[Pkg-javascript-commits] [dojo] 17/18: Imported Upstream version 1.9.1+dfsg

David Prévot taffit at alioth.debian.org
Fri Oct 25 19:59:38 UTC 2013


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository dojo.

commit 0f7733b7ecb6204e947d2da15dbdad2d218ea011
Author: David Prévot <taffit at debian.org>
Date:   Thu Oct 24 18:53:24 2013 -0400

    Imported Upstream version 1.9.1+dfsg
---
 dijit/BackgroundIframe.js                          |   38 +-
 dijit/Calendar.js                                  |  149 +-
 dijit/CalendarLite.js                              |  327 +-
 dijit/CheckedMenuItem.js                           |   22 +-
 dijit/ColorPalette.js                              |  294 +-
 dijit/Declaration.js                               |   49 +-
 dijit/Destroyable.js                               |   58 +
 dijit/Dialog.js                                    |  423 +-
 dijit/DialogUnderlay.js                            |  105 +-
 dijit/DropDownMenu.js                              |   61 +-
 dijit/Editor.js                                    |  357 +-
 dijit/Fieldset.js                                  |   40 +
 dijit/InlineEditBox.js                             | 1184 +-
 dijit/LICENSE                                      |    2 +-
 dijit/Menu.js                                      |  609 +-
 dijit/MenuBar.js                                   |  130 +-
 dijit/MenuBarItem.js                               |    7 -
 dijit/MenuItem.js                                  |  145 +-
 dijit/MenuSeparator.js                             |    8 -
 dijit/PopupMenuBarItem.js                          |    7 -
 dijit/PopupMenuItem.js                             |   45 +-
 dijit/ProgressBar.js                               |  295 +-
 dijit/RadioMenuItem.js                             |   64 +
 dijit/TitlePane.js                                 |  469 +-
 dijit/Toolbar.js                                   |   27 +-
 dijit/ToolbarSeparator.js                          |    7 -
 dijit/Tooltip.js                                   |  301 +-
 dijit/TooltipDialog.js                             |  306 +-
 dijit/Tree.js                                      | 3065 +-
 dijit/Viewport.js                                  |   87 +
 dijit/WidgetSet.js                                 |  104 +-
 dijit/_AttachMixin.js                              |  238 +
 dijit/_BidiMixin.js                                |  159 +
 dijit/_BidiSupport.js                              |   72 +-
 dijit/_Calendar.js                                 |   11 +-
 dijit/_Contained.js                                |   21 +-
 dijit/_Container.js                                |   70 +-
 dijit/_CssStateMixin.js                            |  563 +-
 dijit/_DialogMixin.js                              |   14 +-
 dijit/_FocusMixin.js                               |    9 +-
 dijit/_HasDropDown.js                              |  302 +-
 dijit/_KeyNavContainer.js                          |  244 +-
 dijit/_KeyNavMixin.js                              |  478 +
 dijit/_MenuBase.js                                 |  785 +-
 dijit/_OnDijitClickMixin.js                        |  130 +-
 dijit/_PaletteMixin.js                             |  594 +-
 dijit/_Templated.js                                |   49 +-
 dijit/_TemplatedMixin.js                           |  217 +-
 dijit/_TimePicker.js                               |  420 +-
 dijit/_Widget.js                                   |   88 +-
 dijit/_WidgetBase.js                               | 2023 +-
 dijit/_WidgetsInTemplateMixin.js                   |   73 +-
 dijit/_base.js                                     |   11 +-
 dijit/_base/focus.js                               |  154 +-
 dijit/_base/manager.js                             |   79 +-
 dijit/_base/place.js                               |   72 +-
 dijit/_base/popup.js                               |   18 +-
 dijit/_base/scroll.js                              |   11 +-
 dijit/_base/sniff.js                               |   10 +-
 dijit/_base/typematic.js                           |    9 +-
 dijit/_base/wai.js                                 |   28 +-
 dijit/_base/window.js                              |   11 +-
 dijit/_editor/RichText.js                          | 5153 +--
 dijit/_editor/_Plugin.js                           |  541 +-
 dijit/_editor/html.js                              |  376 +-
 dijit/_editor/nls/FontChoice.js                    |    2 +
 dijit/_editor/nls/LinkDialog.js                    |    2 +
 dijit/_editor/nls/ar/FontChoice.js                 |    5 -
 dijit/_editor/nls/ar/LinkDialog.js                 |    3 -
 dijit/_editor/nls/ar/commands.js                   |   19 +-
 dijit/_editor/nls/az/FontChoice.js                 |    2 -
 dijit/_editor/nls/az/LinkDialog.js                 |    2 -
 dijit/_editor/nls/az/commands.js                   |    2 -
 dijit/_editor/nls/bg/FontChoice.js                 |   25 +
 dijit/_editor/nls/bg/LinkDialog.js                 |   14 +
 dijit/_editor/nls/bg/commands.js                   |   51 +
 dijit/_editor/nls/ca/FontChoice.js                 |    5 -
 dijit/_editor/nls/ca/LinkDialog.js                 |    2 -
 dijit/_editor/nls/ca/commands.js                   |   15 +-
 dijit/_editor/nls/commands.js                      |    2 +
 dijit/_editor/nls/cs/FontChoice.js                 |    5 -
 dijit/_editor/nls/cs/LinkDialog.js                 |    3 -
 dijit/_editor/nls/cs/commands.js                   |   10 +-
 dijit/_editor/nls/da/FontChoice.js                 |    5 -
 dijit/_editor/nls/da/LinkDialog.js                 |    3 -
 dijit/_editor/nls/da/commands.js                   |   10 +-
 dijit/_editor/nls/de/FontChoice.js                 |    5 -
 dijit/_editor/nls/de/LinkDialog.js                 |    3 -
 dijit/_editor/nls/de/commands.js                   |   12 +-
 dijit/_editor/nls/el/FontChoice.js                 |    5 -
 dijit/_editor/nls/el/LinkDialog.js                 |    3 -
 dijit/_editor/nls/el/commands.js                   |   11 +-
 dijit/_editor/nls/es/FontChoice.js                 |    5 -
 dijit/_editor/nls/es/LinkDialog.js                 |    3 -
 dijit/_editor/nls/es/commands.js                   |    6 +-
 dijit/_editor/nls/fi/FontChoice.js                 |    7 +-
 dijit/_editor/nls/fi/LinkDialog.js                 |    3 -
 dijit/_editor/nls/fi/commands.js                   |   13 +-
 dijit/_editor/nls/fr/FontChoice.js                 |   19 +-
 dijit/_editor/nls/fr/LinkDialog.js                 |    2 -
 dijit/_editor/nls/fr/commands.js                   |   10 +-
 dijit/_editor/nls/he/FontChoice.js                 |    5 -
 dijit/_editor/nls/he/LinkDialog.js                 |    3 -
 dijit/_editor/nls/he/commands.js                   |   16 +-
 dijit/_editor/nls/hu/FontChoice.js                 |    5 -
 dijit/_editor/nls/hu/LinkDialog.js                 |    3 -
 dijit/_editor/nls/hu/commands.js                   |    6 +-
 dijit/_editor/nls/it/FontChoice.js                 |   20 +-
 dijit/_editor/nls/it/LinkDialog.js                 |    7 +-
 dijit/_editor/nls/it/commands.js                   |   19 +-
 dijit/_editor/nls/ja/FontChoice.js                 |    5 -
 dijit/_editor/nls/ja/LinkDialog.js                 |    7 +-
 dijit/_editor/nls/ja/commands.js                   |   21 +-
 dijit/_editor/nls/kk/FontChoice.js                 |    9 +-
 dijit/_editor/nls/kk/LinkDialog.js                 |    4 +-
 dijit/_editor/nls/kk/commands.js                   |   14 +-
 dijit/_editor/nls/ko/FontChoice.js                 |    5 -
 dijit/_editor/nls/ko/LinkDialog.js                 |    7 +-
 dijit/_editor/nls/ko/commands.js                   |   14 +-
 dijit/_editor/nls/nb/FontChoice.js                 |    5 -
 dijit/_editor/nls/nb/LinkDialog.js                 |    3 -
 dijit/_editor/nls/nb/commands.js                   |    2 -
 dijit/_editor/nls/nl/FontChoice.js                 |    5 -
 dijit/_editor/nls/nl/LinkDialog.js                 |    3 -
 dijit/_editor/nls/nl/commands.js                   |    6 +-
 dijit/_editor/nls/pl/FontChoice.js                 |    9 +-
 dijit/_editor/nls/pl/LinkDialog.js                 |    5 +-
 dijit/_editor/nls/pl/commands.js                   |    8 +-
 dijit/_editor/nls/pt-pt/FontChoice.js              |    5 -
 dijit/_editor/nls/pt-pt/LinkDialog.js              |    3 -
 dijit/_editor/nls/pt-pt/commands.js                |    9 +-
 dijit/_editor/nls/pt/FontChoice.js                 |    7 +-
 dijit/_editor/nls/pt/LinkDialog.js                 |    5 +-
 dijit/_editor/nls/pt/commands.js                   |   16 +-
 dijit/_editor/nls/ro/FontChoice.js                 |   10 +-
 dijit/_editor/nls/ro/LinkDialog.js                 |    3 -
 dijit/_editor/nls/ro/commands.js                   |    6 +-
 dijit/_editor/nls/ru/FontChoice.js                 |    5 -
 dijit/_editor/nls/ru/LinkDialog.js                 |    3 -
 dijit/_editor/nls/ru/commands.js                   |   13 +-
 dijit/_editor/nls/sk/FontChoice.js                 |    6 -
 dijit/_editor/nls/sk/LinkDialog.js                 |   17 +-
 dijit/_editor/nls/sk/commands.js                   |   41 +-
 dijit/_editor/nls/sl/FontChoice.js                 |    6 -
 dijit/_editor/nls/sl/LinkDialog.js                 |    3 -
 dijit/_editor/nls/sl/commands.js                   |    8 +-
 dijit/_editor/nls/sv/FontChoice.js                 |   33 +-
 dijit/_editor/nls/sv/LinkDialog.js                 |   13 +-
 dijit/_editor/nls/sv/commands.js                   |   17 +-
 dijit/_editor/nls/th/FontChoice.js                 |    6 -
 dijit/_editor/nls/th/LinkDialog.js                 |    9 +-
 dijit/_editor/nls/th/commands.js                   |   13 +-
 dijit/_editor/nls/tr/FontChoice.js                 |    5 -
 dijit/_editor/nls/tr/LinkDialog.js                 |    3 -
 dijit/_editor/nls/tr/commands.js                   |    7 +-
 dijit/_editor/nls/uk/FontChoice.js                 |   25 +
 dijit/_editor/nls/uk/LinkDialog.js                 |   14 +
 dijit/_editor/nls/uk/commands.js                   |   51 +
 dijit/_editor/nls/zh-tw/FontChoice.js              |    5 -
 dijit/_editor/nls/zh-tw/LinkDialog.js              |    3 -
 dijit/_editor/nls/zh-tw/commands.js                |    6 +-
 dijit/_editor/nls/zh/FontChoice.js                 |   21 +-
 dijit/_editor/nls/zh/LinkDialog.js                 |    9 +-
 dijit/_editor/nls/zh/commands.js                   |   11 +-
 dijit/_editor/plugins/AlwaysShowToolbar.js         |  340 +-
 dijit/_editor/plugins/EnterKeyHandling.js          |  965 +-
 dijit/_editor/plugins/FontChoice.js                | 1061 +-
 dijit/_editor/plugins/FullScreen.js                |  797 +-
 dijit/_editor/plugins/LinkDialog.js                | 1111 +-
 dijit/_editor/plugins/NewPage.js                   |  123 +-
 dijit/_editor/plugins/Print.js                     |  204 +-
 dijit/_editor/plugins/TabIndent.js                 |   15 +-
 dijit/_editor/plugins/TextColor.js                 |  192 +-
 dijit/_editor/plugins/ToggleDir.js                 |   15 +-
 dijit/_editor/plugins/ViewSource.js                | 1004 +-
 dijit/_editor/range.js                             | 1024 +-
 dijit/_editor/selection.js                         |  191 +-
 dijit/_tree/dndSource.js                           |   11 +-
 dijit/a11y.js                                      |  303 +-
 dijit/a11yclick.js                                 |  138 +
 dijit/bench/benchReceive.php                       |  129 +
 dijit/bench/benchTool.html                         |  228 +
 dijit/bench/button.html                            |  184 +
 dijit/bench/create_widgets.html                    |   59 +
 dijit/bench/test_button-results.html               |   66 +
 dijit/bench/widget_construction_test.php           |  185 +
 dijit/dijit-all.js                                 |   11 +-
 dijit/dijit.js                                     |   15 +-
 dijit/dijit.profile.js                             |    6 +-
 dijit/focus.js                                     |  248 +-
 dijit/form/Button.js                               |  205 +-
 dijit/form/CheckBox.js                             |   51 +-
 dijit/form/ComboBox.js                             |    7 -
 dijit/form/ComboBoxMixin.js                        |   31 +-
 dijit/form/ComboButton.js                          |  136 +-
 dijit/form/CurrencyTextBox.js                      |   35 +-
 dijit/form/DataList.js                             |   17 +-
 dijit/form/DateTextBox.js                          |   22 +-
 dijit/form/DropDownButton.js                       |  176 +-
 dijit/form/FilteringSelect.js                      |   45 +-
 dijit/form/Form.js                                 |   35 +-
 dijit/form/HorizontalRule.js                       |  103 +-
 dijit/form/HorizontalRuleLabels.js                 |  195 +-
 dijit/form/HorizontalSlider.js                     |  664 +-
 dijit/form/MappedTextBox.js                        |   38 +-
 dijit/form/MultiSelect.js                          |  239 +-
 dijit/form/NumberSpinner.js                        |  118 +-
 dijit/form/NumberTextBox.js                        |  109 +-
 dijit/form/RadioButton.js                          |    9 +-
 dijit/form/RangeBoundTextBox.js                    |   88 +-
 dijit/form/Select.js                               |  701 +-
 dijit/form/SimpleTextarea.js                       |  152 +-
 dijit/form/Slider.js                               |   11 +-
 dijit/form/TextBox.js                              |  125 +-
 dijit/form/Textarea.js                             |   56 +-
 dijit/form/TimeTextBox.js                          |   28 +-
 dijit/form/ToggleButton.js                         |    9 +-
 dijit/form/ValidationTextBox.js                    |  206 +-
 dijit/form/VerticalRule.js                         |    8 +-
 dijit/form/VerticalRuleLabels.js                   |    8 +-
 dijit/form/VerticalSlider.js                       |    7 -
 dijit/form/_AutoCompleterMixin.js                  |  426 +-
 dijit/form/_ButtonMixin.js                         |  167 +-
 dijit/form/_CheckBoxMixin.js                       |   38 +-
 dijit/form/_ComboBoxMenu.js                        |   36 +-
 dijit/form/_ComboBoxMenuMixin.js                   |  342 +-
 dijit/form/_DateTimeTextBox.js                     |  120 +-
 dijit/form/_ExpandingTextAreaMixin.js              |  105 +-
 dijit/form/_FormMixin.js                           |  169 +-
 dijit/form/_FormSelectWidget.js                    | 1180 +-
 dijit/form/_FormValueMixin.js                      |   34 +-
 dijit/form/_FormValueWidget.js                     |   87 +-
 dijit/form/_FormWidget.js                          |  116 +-
 dijit/form/_FormWidgetMixin.js                     |  437 +-
 dijit/form/_ListBase.js                            |  212 +-
 dijit/form/_ListMouseMixin.js                      |  152 +-
 dijit/form/_RadioButtonMixin.js                    |   28 +-
 dijit/form/_SearchMixin.js                         |  288 +
 dijit/form/_Spinner.js                             |   88 +-
 dijit/form/_TextBoxMixin.js                        |  907 +-
 dijit/form/_ToggleButtonMixin.js                   |  100 +-
 dijit/form/nls/ComboBox.js                         |    2 +
 dijit/form/nls/Textarea.js                         |    2 +
 dijit/form/nls/ar/ComboBox.js                      |    2 -
 dijit/form/nls/ar/Textarea.js                      |    3 +-
 dijit/form/nls/ar/validate.js                      |    2 -
 dijit/form/nls/az/ComboBox.js                      |    2 -
 dijit/form/nls/az/Textarea.js                      |    3 +-
 dijit/form/nls/az/validate.js                      |    2 -
 dijit/form/nls/bg/ComboBox.js                      |    6 +
 dijit/form/nls/bg/Textarea.js                      |    9 +
 dijit/form/nls/bg/validate.js                      |    7 +
 dijit/form/nls/ca/ComboBox.js                      |    3 -
 dijit/form/nls/ca/Textarea.js                      |    5 +-
 dijit/form/nls/ca/validate.js                      |    3 -
 dijit/form/nls/cs/ComboBox.js                      |    2 -
 dijit/form/nls/cs/Textarea.js                      |    3 +-
 dijit/form/nls/cs/validate.js                      |    2 -
 dijit/form/nls/da/ComboBox.js                      |    2 -
 dijit/form/nls/da/Textarea.js                      |    3 +-
 dijit/form/nls/da/validate.js                      |    4 +-
 dijit/form/nls/de/ComboBox.js                      |    2 -
 dijit/form/nls/de/Textarea.js                      |    4 +-
 dijit/form/nls/de/validate.js                      |    2 -
 dijit/form/nls/el/ComboBox.js                      |    2 -
 dijit/form/nls/el/Textarea.js                      |    3 +-
 dijit/form/nls/el/validate.js                      |    2 -
 dijit/form/nls/es/ComboBox.js                      |    2 -
 dijit/form/nls/es/Textarea.js                      |    3 +-
 dijit/form/nls/es/validate.js                      |    2 -
 dijit/form/nls/fi/ComboBox.js                      |    2 -
 dijit/form/nls/fi/Textarea.js                      |    3 +-
 dijit/form/nls/fi/validate.js                      |    2 -
 dijit/form/nls/fr/ComboBox.js                      |    2 -
 dijit/form/nls/fr/Textarea.js                      |    7 +-
 dijit/form/nls/fr/validate.js                      |    2 -
 dijit/form/nls/he/ComboBox.js                      |    2 -
 dijit/form/nls/he/Textarea.js                      |    3 +-
 dijit/form/nls/he/validate.js                      |    2 -
 dijit/form/nls/hu/ComboBox.js                      |    2 -
 dijit/form/nls/hu/Textarea.js                      |    3 +-
 dijit/form/nls/hu/validate.js                      |    2 -
 dijit/form/nls/it/ComboBox.js                      |    4 +-
 dijit/form/nls/it/Textarea.js                      |    3 +-
 dijit/form/nls/it/validate.js                      |    4 +-
 dijit/form/nls/ja/ComboBox.js                      |    2 -
 dijit/form/nls/ja/Textarea.js                      |    3 +-
 dijit/form/nls/ja/validate.js                      |    2 -
 dijit/form/nls/kk/ComboBox.js                      |    3 -
 dijit/form/nls/kk/Textarea.js                      |    5 +-
 dijit/form/nls/kk/validate.js                      |    3 -
 dijit/form/nls/ko/ComboBox.js                      |    2 -
 dijit/form/nls/ko/Textarea.js                      |    3 +-
 dijit/form/nls/ko/validate.js                      |    2 -
 dijit/form/nls/nb/ComboBox.js                      |    2 -
 dijit/form/nls/nb/Textarea.js                      |    3 +-
 dijit/form/nls/nb/validate.js                      |    2 -
 dijit/form/nls/nl/ComboBox.js                      |    2 -
 dijit/form/nls/nl/Textarea.js                      |    3 +-
 dijit/form/nls/nl/validate.js                      |    2 -
 dijit/form/nls/pl/ComboBox.js                      |    2 -
 dijit/form/nls/pl/Textarea.js                      |    3 +-
 dijit/form/nls/pl/validate.js                      |    4 +-
 dijit/form/nls/pt-pt/ComboBox.js                   |    2 -
 dijit/form/nls/pt-pt/Textarea.js                   |    3 +-
 dijit/form/nls/pt-pt/validate.js                   |    2 -
 dijit/form/nls/pt/ComboBox.js                      |    2 -
 dijit/form/nls/pt/Textarea.js                      |    3 +-
 dijit/form/nls/pt/validate.js                      |    2 -
 dijit/form/nls/ro/ComboBox.js                      |    3 -
 dijit/form/nls/ro/Textarea.js                      |    5 +-
 dijit/form/nls/ro/validate.js                      |    3 -
 dijit/form/nls/ru/ComboBox.js                      |    2 -
 dijit/form/nls/ru/Textarea.js                      |    3 +-
 dijit/form/nls/ru/validate.js                      |    2 -
 dijit/form/nls/sk/ComboBox.js                      |    7 +-
 dijit/form/nls/sk/Textarea.js                      |    7 +-
 dijit/form/nls/sk/validate.js                      |    5 +-
 dijit/form/nls/sl/ComboBox.js                      |    3 -
 dijit/form/nls/sl/Textarea.js                      |    5 +-
 dijit/form/nls/sl/validate.js                      |    3 -
 dijit/form/nls/sv/ComboBox.js                      |    6 +-
 dijit/form/nls/sv/Textarea.js                      |    3 +-
 dijit/form/nls/sv/validate.js                      |    8 +-
 dijit/form/nls/th/ComboBox.js                      |    3 -
 dijit/form/nls/th/Textarea.js                      |    9 +-
 dijit/form/nls/th/validate.js                      |    3 -
 dijit/form/nls/tr/ComboBox.js                      |    2 -
 dijit/form/nls/tr/Textarea.js                      |    3 +-
 dijit/form/nls/tr/validate.js                      |    2 -
 dijit/form/nls/uk/ComboBox.js                      |    6 +
 dijit/form/nls/uk/Textarea.js                      |    9 +
 dijit/form/nls/uk/validate.js                      |    7 +
 dijit/form/nls/validate.js                         |    2 +
 dijit/form/nls/zh-tw/ComboBox.js                   |    2 -
 dijit/form/nls/zh-tw/Textarea.js                   |    3 +-
 dijit/form/nls/zh-tw/validate.js                   |    2 -
 dijit/form/nls/zh/ComboBox.js                      |    2 -
 dijit/form/nls/zh/Textarea.js                      |    7 +-
 dijit/form/nls/zh/validate.js                      |    4 +-
 dijit/form/templates/Button.html                   |    3 +-
 dijit/form/templates/CheckBox.html                 |    4 +-
 dijit/form/templates/ComboButton.html              |    7 +-
 dijit/form/templates/DropDownBox.html              |    8 +-
 dijit/form/templates/DropDownButton.html           |    9 +-
 dijit/form/templates/HorizontalSlider.html         |    5 +-
 dijit/form/templates/Select.html                   |   22 +-
 dijit/form/templates/Spinner.html                  |    8 +-
 dijit/form/templates/VerticalSlider.html           |    5 +-
 dijit/hccss.js                                     |   59 +-
 dijit/icons/commonIcons.css                        |    2 +-
 .../icons/images/commonIconsObjActDisabled_rtl.png |  Bin 5820 -> 4968 bytes
 dijit/icons/images/commonIconsObjActEnabled.png    |  Bin 12474 -> 7803 bytes
 .../icons/images/commonIconsObjActEnabled8bit.png  |  Bin 4334 -> 4279 bytes
 .../images/commonIconsObjActEnabled8bit_rtl.png    |  Bin 5258 -> 4407 bytes
 .../icons/images/commonIconsObjActEnabled_rtl.png  |  Bin 10481 -> 7776 bytes
 dijit/icons/images/editorIconsDisabled.png         |  Bin 3289 -> 3205 bytes
 dijit/icons/images/editorIconsDisabled_rtl.png     |  Bin 6965 -> 4010 bytes
 dijit/icons/images/editorIconsEnabled.png          |  Bin 3846 -> 3790 bytes
 dijit/icons/images/editorIconsEnabled_rtl.png      |  Bin 7144 -> 4151 bytes
 dijit/icons/images/loadingAnimation_rtl.gif        |  Bin 1513 -> 630 bytes
 dijit/layout/AccordionContainer.js                 |  225 +-
 dijit/layout/AccordionPane.js                      |    8 +-
 dijit/layout/BorderContainer.js                    |  930 +-
 dijit/layout/ContentPane.js                        | 1140 +-
 dijit/layout/LayoutContainer.js                    |  226 +-
 dijit/layout/LinkPane.js                           |    8 -
 dijit/layout/ScrollingTabController.js             |  885 +-
 dijit/layout/SplitContainer.js                     |  222 +-
 dijit/layout/StackContainer.js                     |  682 +-
 dijit/layout/StackController.js                    |  337 +-
 dijit/layout/TabContainer.js                       |   20 +-
 dijit/layout/TabController.js                      |  130 +-
 dijit/layout/_ContentPaneResizeMixin.js            |  440 +-
 dijit/layout/_LayoutWidget.js                      |   64 +-
 dijit/layout/_TabContainerBase.js                  |  237 +-
 dijit/layout/templates/AccordionButton.html        |    8 +-
 dijit/layout/templates/ScrollingTabController.html |   28 +-
 .../templates/_ScrollingTabControllerButton.html   |   10 +-
 dijit/layout/templates/_TabButton.html             |   20 +-
 dijit/layout/utils.js                              |  220 +-
 dijit/main.js                                      |   10 +-
 dijit/nls/ar/common.js                             |    2 -
 dijit/nls/ar/loading.js                            |    2 -
 dijit/nls/az/common.js                             |    2 -
 dijit/nls/az/loading.js                            |    2 -
 dijit/nls/bg/common.js                             |    8 +
 dijit/nls/bg/loading.js                            |    6 +
 dijit/nls/ca/common.js                             |    3 -
 dijit/nls/ca/loading.js                            |    3 -
 dijit/nls/common.js                                |    2 +
 dijit/nls/cs/common.js                             |    2 -
 dijit/nls/cs/loading.js                            |    2 -
 dijit/nls/da/common.js                             |    2 -
 dijit/nls/da/loading.js                            |    2 -
 dijit/nls/de/common.js                             |    2 -
 dijit/nls/de/loading.js                            |    2 -
 dijit/nls/el/common.js                             |    2 -
 dijit/nls/el/loading.js                            |    2 -
 dijit/nls/es/common.js                             |    2 -
 dijit/nls/es/loading.js                            |    2 -
 dijit/nls/fi/common.js                             |    2 -
 dijit/nls/fi/loading.js                            |    2 -
 dijit/nls/fr/common.js                             |    4 +-
 dijit/nls/fr/loading.js                            |    2 -
 dijit/nls/he/common.js                             |    2 -
 dijit/nls/he/loading.js                            |    2 -
 dijit/nls/hr/loading.js                            |    2 +-
 dijit/nls/hu/common.js                             |    2 -
 dijit/nls/hu/loading.js                            |    2 -
 dijit/nls/it/common.js                             |    4 +-
 dijit/nls/it/loading.js                            |    2 -
 dijit/nls/ja/common.js                             |    2 -
 dijit/nls/ja/loading.js                            |    2 -
 dijit/nls/kk/common.js                             |    2 -
 dijit/nls/kk/loading.js                            |    4 +-
 dijit/nls/ko/common.js                             |    2 -
 dijit/nls/ko/loading.js                            |    2 -
 dijit/nls/loading.js                               |    2 +
 dijit/nls/nb/common.js                             |    2 -
 dijit/nls/nb/loading.js                            |    2 -
 dijit/nls/nl/common.js                             |    2 -
 dijit/nls/nl/loading.js                            |    2 -
 dijit/nls/pl/common.js                             |    2 -
 dijit/nls/pl/loading.js                            |    2 -
 dijit/nls/pt-pt/common.js                          |    2 -
 dijit/nls/pt-pt/loading.js                         |    2 -
 dijit/nls/pt/common.js                             |    2 -
 dijit/nls/pt/loading.js                            |    2 -
 dijit/nls/ro/common.js                             |    3 -
 dijit/nls/ro/loading.js                            |    3 -
 dijit/nls/ru/common.js                             |    4 +-
 dijit/nls/ru/loading.js                            |    2 -
 dijit/nls/sk/common.js                             |    3 -
 dijit/nls/sk/loading.js                            |    7 +-
 dijit/nls/sl/common.js                             |    3 -
 dijit/nls/sl/loading.js                            |    2 -
 dijit/nls/sv/common.js                             |    2 -
 dijit/nls/sv/loading.js                            |    4 +-
 dijit/nls/th/common.js                             |    3 -
 dijit/nls/th/loading.js                            |    3 -
 dijit/nls/tr/common.js                             |    2 -
 dijit/nls/tr/loading.js                            |    2 -
 dijit/nls/uk/common.js                             |    8 +
 dijit/nls/uk/loading.js                            |    6 +
 dijit/nls/zh-tw/common.js                          |    2 -
 dijit/nls/zh-tw/loading.js                         |    2 -
 dijit/nls/zh/common.js                             |    2 -
 dijit/nls/zh/loading.js                            |    2 -
 dijit/package.json                                 |    7 +-
 dijit/place.js                                     |  253 +-
 dijit/popup.js                                     |  363 +-
 dijit/registry.js                                  |   54 +-
 dijit/resources/_modules.js                        |   18 -
 dijit/robot.js                                     |    5 +-
 dijit/robotx.js                                    |   39 +-
 dijit/selection.js                                 |  525 +
 dijit/templates/Calendar.html                      |   16 +-
 dijit/templates/CheckedMenuItem.html               |    9 +-
 dijit/templates/ColorPalette.html                  |    4 +-
 dijit/templates/Dialog.html                        |   11 +-
 dijit/templates/Fieldset.html                      |   15 +
 dijit/templates/InlineEditBox.html                 |    7 +-
 dijit/templates/Menu.html                          |    3 +-
 dijit/templates/MenuBar.html                       |    3 +-
 dijit/templates/MenuBarItem.html                   |    6 +-
 dijit/templates/MenuItem.html                      |   13 +-
 dijit/templates/MenuSeparator.html                 |    4 +-
 dijit/templates/ProgressBar.html                   |    5 +-
 dijit/templates/TimePicker.html                    |    9 -
 dijit/templates/TitlePane.html                     |   10 +-
 dijit/templates/Tooltip.html                       |    2 +-
 dijit/templates/TooltipDialog.html                 |    6 +-
 dijit/templates/Tree.html                          |    6 +-
 dijit/templates/TreeNode.html                      |   13 +-
 dijit/tests/Bidi.html                              |  372 +-
 dijit/tests/CalendarLite.html                      |   58 +
 dijit/tests/Destroyable.html                       |   95 +
 dijit/tests/Dialog.html                            |  337 +-
 dijit/tests/Fieldset.html                          |   56 +
 dijit/tests/Menu.html                              |   71 +
 dijit/tests/NodeList-instantiate.html              |   64 +-
 dijit/tests/ProgressBar.html                       |  314 +-
 dijit/tests/Tooltip-placement.html                 |  721 +-
 dijit/tests/TooltipDialog.html                     |   56 +
 dijit/tests/_AttachMixin.html                      |  165 +
 .../BidiSupportModule/BidiSupportTest.js           |  355 +-
 .../tests/_BidiSupport/BidiSupportModule/module.js |   14 +-
 dijit/tests/_BidiSupport/_data/categoriesHeb.json  |   18 +-
 dijit/tests/_BidiSupport/_data/countriesHeb.json   |   90 +-
 .../DynamicChangeTextDir.html                      |   72 +-
 .../dynamicallyChangeTextDir/module.js             |   12 +-
 dijit/tests/_BidiSupport/form/Button.html          |  400 +
 dijit/tests/_BidiSupport/form/module.js            |   32 +-
 dijit/tests/_BidiSupport/form/multiSelect.html     |  381 +
 .../_BidiSupport/form/noTextDirTextWidgets.html    |  442 +-
 .../_BidiSupport/form/robot/InlineEditBox.html     |  240 +-
 .../_BidiSupport/form/robot/SimpleComboBoxes.html  |  207 +-
 .../_BidiSupport/form/robot/SimpleTextarea.html    |  102 +-
 dijit/tests/_BidiSupport/form/robot/TextBoxes.html |  114 +-
 dijit/tests/_BidiSupport/form/robot/Textarea.html  |   42 +-
 .../_BidiSupport/form/test_InlineEditBox.html      |   78 +-
 .../_BidiSupport/form/test_PlaceholderInput.html   |   56 +
 dijit/tests/_BidiSupport/form/test_Select.html     |  299 +
 .../_BidiSupport/form/test_SimpleComboBoxes.html   |   31 +-
 .../_BidiSupport/form/test_SimpleTextarea.html     |   24 +-
 dijit/tests/_BidiSupport/form/test_Slider.html     |  173 +
 dijit/tests/_BidiSupport/form/test_TextBoxes.html  |   26 +-
 dijit/tests/_BidiSupport/form/test_Textarea.html   |   29 +-
 .../tests/_BidiSupport/form/test_TimeTextBox.html  |  320 +
 .../inheritance/Inher-ComplexMarkupContainers.html |   99 +-
 .../inheritance/Inher-MarkupContainers.html        |  103 +-
 .../_BidiSupport/inheritance/Inher-Simple.html     |   43 +-
 dijit/tests/_BidiSupport/inheritance/module.js     |   16 +-
 .../_BidiSupport/layout/AccordionContainer.html    |   82 +
 .../tests/_BidiSupport/layout/StackContainer.html  |   70 +
 dijit/tests/_BidiSupport/layout/TabContainer.html  |  122 +
 dijit/tests/_BidiSupport/layout/module.js          |    5 +
 dijit/tests/_BidiSupport/layout/runTests.html      |   10 +
 dijit/tests/_BidiSupport/misc/Dialog.html          |   58 +
 dijit/tests/_BidiSupport/misc/MenuItem.html        |  311 +
 dijit/tests/_BidiSupport/misc/TitlePane.html       |   75 +
 dijit/tests/_BidiSupport/misc/Tooltip.html         |  300 +
 dijit/tests/_BidiSupport/misc/TooltipDialog.html   |   68 +
 dijit/tests/_BidiSupport/misc/module.js            |    9 +
 dijit/tests/_BidiSupport/misc/runTests.html        |   11 +
 dijit/tests/_BidiSupport/module.js                 |   30 +-
 .../tests/_BidiSupport/tree/ProgrammaticTree.html  |  154 +-
 dijit/tests/_BidiSupport/tree/SimpleTree.html      |  270 -
 .../_BidiSupport/tree/TreeRootlessCustomIcons.html |  267 -
 dijit/tests/_BidiSupport/tree/module.js            |   16 +-
 dijit/tests/_BidiSupport/widgets/Tooltip.html      |  305 -
 dijit/tests/_BidiSupport/widgets/module.js         |   11 -
 dijit/tests/_BidiSupport/widgets/runTests.html     |   11 -
 dijit/tests/_Container.html                        |  244 +-
 dijit/tests/_HasDropDown.html                      |  149 +
 dijit/tests/_KeyNavContainer.html                  |  165 +
 dijit/tests/_Templated-widgetsInTemplate1.x.html   |    9 +-
 dijit/tests/_TemplatedMixin.html                   |  474 +-
 dijit/tests/_TimePicker.html                       |   35 +
 dijit/tests/_Widget-attr.html                      |  457 +-
 dijit/tests/_Widget-connect-performance.html       |    4 +-
 dijit/tests/_Widget-deferredConnect.html           |    6 +-
 dijit/tests/_Widget-lifecycle.html                 |  140 +-
 dijit/tests/_Widget-on.html                        |   68 +-
 dijit/tests/_Widget-ondijitclick.html              |   59 +-
 dijit/tests/_Widget-placeAt.html                   |  332 +-
 dijit/tests/_Widget-subscribe.html                 |   18 +-
 dijit/tests/_WidgetsInTemplateMixin.html           |  694 +-
 dijit/tests/_altCalendar.html                      |   37 -
 dijit/tests/_base/manager.html                     |    5 +
 dijit/tests/_base/module.js                        |   26 +-
 dijit/tests/_base/place.html                       |   56 +-
 dijit/tests/_base/popup.html                       |  472 +
 dijit/tests/_base/robot/CrossWindow.html           |    3 +-
 dijit/tests/_base/robot/FocusManager.html          |    3 +
 dijit/tests/_base/robot/focus_mouse.html           |   40 +-
 dijit/tests/_base/robot/popup.html                 |  207 -
 dijit/tests/_base/robot/typematic.html             |   79 -
 dijit/tests/_base/tabindex.html                    |  296 -
 dijit/tests/_base/test_CrossWindow.html            |    4 +-
 dijit/tests/_base/test_FocusManager.html           |    5 +-
 dijit/tests/_base/test_focusWidget.html            |   33 +-
 dijit/tests/_base/test_popup.html                  |  283 -
 dijit/tests/_base/test_typematic.html              |   65 -
 dijit/tests/_base/wai.html                         |    2 +-
 dijit/tests/_data/SlowStore.js                     |  151 +-
 dijit/tests/_data/categories.json                  |   18 +-
 dijit/tests/_data/categoriesNested.json            |   16 +-
 dijit/tests/_data/countries.json                   |   88 +-
 dijit/tests/_data/geography.js                     |   37 +
 dijit/tests/_data/states.json                      |  128 +-
 dijit/tests/_loadTest.js                           |   15 +-
 dijit/tests/_testCommon.js                         |   18 +-
 dijit/tests/a11y.html                              |  303 +
 dijit/tests/boilerplate.js                         |  137 +
 dijit/tests/boilerplateOnload.js                   |    3 +
 dijit/tests/css/dijitTests.css                     |    8 +-
 dijit/tests/delay.js                               |    3 +
 dijit/tests/editor/BackForwardState.html           |   33 +-
 dijit/tests/editor/BackForwardStateHelper.html     |    8 +-
 dijit/tests/editor/Editor_IE8Compat.html           |   21 +
 dijit/tests/editor/Editor_stylesheet.html          |  104 +
 dijit/tests/editor/EnterKeyHandling.html           |   64 +-
 dijit/tests/editor/html.html                       |  131 +
 dijit/tests/editor/module.js                       |   57 +-
 dijit/tests/editor/nls_8859-2.html                 |   51 +-
 dijit/tests/editor/nls_sjis.html                   |   51 +-
 dijit/tests/editor/nls_utf8.html                   |   51 +-
 dijit/tests/editor/robot/BackForwardState.html     |   40 +-
 dijit/tests/editor/robot/CustomPlugin.html         |   31 +-
 dijit/tests/editor/robot/Editor_FontChoice.html    |  151 +-
 dijit/tests/editor/robot/Editor_FullScreen.html    |   69 +-
 dijit/tests/editor/robot/Editor_IE8Compat.html     |   69 +
 dijit/tests/editor/robot/Editor_LinkDialog.html    |  245 +-
 dijit/tests/editor/robot/Editor_NewPage.html       |   26 +-
 dijit/tests/editor/robot/Editor_ViewSource.html    |   99 +-
 dijit/tests/editor/robot/Editor_a11y.html          |   21 +-
 dijit/tests/editor/robot/Editor_misc.html          |  177 +-
 dijit/tests/editor/robot/Editor_mouse.html         |  127 +-
 dijit/tests/editor/robot/EnterKeyHandling.html     |  177 +-
 dijit/tests/editor/robot/TabIndent.html            |   41 +-
 dijit/tests/editor/robot/ToggleDir.html            |   68 +-
 dijit/tests/editor/robot/ToggleDir_rtl.html        |   66 +-
 dijit/tests/editor/runTests.html                   |    2 +-
 dijit/tests/editor/test_CustomPlugin.html          |  140 +-
 dijit/tests/editor/test_Editor.html                |  145 +-
 dijit/tests/editor/test_FontChoice.html            |   45 +-
 dijit/tests/editor/test_FullScreen.html            |   93 +-
 dijit/tests/editor/test_LinkDialog.html            |   49 +-
 dijit/tests/editor/test_NewPage.html               |   35 +-
 dijit/tests/editor/test_Print.html                 |   31 +-
 dijit/tests/editor/test_TabIndent.html             |   30 +-
 dijit/tests/editor/test_ToggleDir.html             |   31 +-
 dijit/tests/editor/test_ToggleDir_rtl.html         |   31 +-
 dijit/tests/editor/test_ViewSource.html            |   44 +-
 dijit/tests/editor/test_performance.html           |  169 +
 dijit/tests/focus.html                             |  392 +
 dijit/tests/form/AutoCompleterMixin.html           |   18 +-
 dijit/tests/form/ButtonMixin.html                  |  194 +-
 dijit/tests/form/CheckBox.html                     |  262 +
 dijit/tests/form/CheckBoxMixin.html                |  195 +-
 dijit/tests/form/DateTextBox.html                  |   69 -
 dijit/tests/form/ExpandingTextAreaMixin.html       |   32 +-
 dijit/tests/form/Form.html                         |  118 +-
 dijit/tests/form/RadioButtonMixin.html             |   28 +-
 dijit/tests/form/TextBoxMixin.html                 |   20 +-
 dijit/tests/form/TextBox_sizes.html                |  328 +-
 dijit/tests/form/TextBox_sizes.js                  |  443 +-
 dijit/tests/form/TextBox_types.html                |   36 +-
 dijit/tests/form/ToggleButtonMixin.html            |   24 +-
 dijit/tests/form/_autoComplete.html                |  290 +-
 dijit/tests/form/mobile.html                       |   74 +-
 dijit/tests/form/module.js                         |  127 +-
 dijit/tests/form/robot/Button_a11y.html            |  145 +-
 dijit/tests/form/robot/Button_mouse.html           |   31 +-
 dijit/tests/form/robot/CheckBox_a11y.html          |   83 +-
 dijit/tests/form/robot/CheckBox_mouse.html         |   94 +-
 dijit/tests/form/robot/DateTextBox.html            |  567 +-
 dijit/tests/form/robot/Form_onsubmit.html          |    3 +-
 dijit/tests/form/robot/Form_state.html             |    3 +-
 dijit/tests/form/robot/MultiSelect.html            |   17 +-
 dijit/tests/form/robot/Select.html                 |  271 +-
 dijit/tests/form/robot/SimpleTextarea.html         |    3 +-
 dijit/tests/form/robot/Slider_mouse.html           |    5 +-
 dijit/tests/form/robot/Spinner_a11y.html           |   38 +-
 dijit/tests/form/robot/Spinner_mouse.html          |    4 +-
 dijit/tests/form/robot/TextBox_onInput.html        |  137 +
 dijit/tests/form/robot/Textarea.html               |  276 +-
 dijit/tests/form/robot/TimeTextBox.html            |  278 +-
 dijit/tests/form/robot/ValidationTextBox.html      |  267 +-
 dijit/tests/form/robot/_autoComplete_a11y.html     |  190 +-
 dijit/tests/form/robot/_autoComplete_mouse.html    |   73 +-
 dijit/tests/form/robot/validationMessages.html     |  309 +-
 dijit/tests/form/test_Button.html                  |  293 +-
 dijit/tests/form/test_CheckBox.html                |   50 +-
 dijit/tests/form/test_DateTextBox.html             |  326 +-
 dijit/tests/form/test_DateTextBox_iframe.html      |    7 +-
 dijit/tests/form/test_Form_onsubmit.html           |   22 +-
 dijit/tests/form/test_Form_state.html              |   20 +-
 dijit/tests/form/test_MultiSelect.html             |  122 +-
 dijit/tests/form/test_Select.html                  |  779 +-
 dijit/tests/form/test_SimpleTextarea.html          |   28 +-
 dijit/tests/form/test_Slider.html                  |  118 +-
 dijit/tests/form/test_Spinner.html                 |   17 +-
 dijit/tests/form/test_Textarea.html                |  106 +-
 dijit/tests/form/test_TimeTextBox.html             |   40 +-
 dijit/tests/form/test_validStatePerformance.html   |   88 +-
 dijit/tests/form/test_validate.html                |  452 +-
 dijit/tests/form/test_verticalAlign.html           |   88 +-
 dijit/tests/formAction.html                        |    4 +-
 dijit/tests/general-module.js                      |   59 +-
 dijit/tests/helpers.js                             |  119 +-
 dijit/tests/i18n/calendar.html                     |    8 +-
 dijit/tests/i18n/currency.html                     |    9 +-
 dijit/tests/i18n/date.html                         |    9 +-
 dijit/tests/i18n/digit.html                        |   19 +-
 dijit/tests/i18n/module.js                         |   22 +-
 dijit/tests/i18n/number.html                       |    9 +-
 dijit/tests/i18n/test_i18n.js                      |   37 +-
 dijit/tests/i18n/textbox.html                      |    9 +-
 dijit/tests/i18n/time.html                         |   20 +-
 dijit/tests/infrastructure-module.js               |   53 +-
 dijit/tests/layout/AccordionContainer.html         |  265 +-
 dijit/tests/layout/BorderContainer.html            |  615 +-
 dijit/tests/layout/ContentPane-auto-require.html   |  117 +
 dijit/tests/layout/ContentPane-remote.html         |  285 +-
 dijit/tests/layout/ContentPane.html                |  832 +-
 dijit/tests/layout/ContentPaneLayout.html          | 1155 +-
 dijit/tests/layout/LayoutContainer.html            |  307 +-
 dijit/tests/layout/LayoutContainer_v1.html         |  290 +
 dijit/tests/layout/StackContainer.html             |  373 +-
 dijit/tests/layout/TabContainer.html               |  366 +-
 dijit/tests/layout/TabContainerTitlePane.html      |   82 +-
 dijit/tests/layout/borderContainer.php             |   20 +-
 dijit/tests/layout/combotab.html                   |    6 +-
 dijit/tests/layout/doc0.html                       |    6 +-
 dijit/tests/layout/doc3.html                       |    2 +
 dijit/tests/layout/getResponse.php                 |    6 +-
 dijit/tests/layout/mobile.html                     |   40 +-
 dijit/tests/layout/module.js                       |   56 +-
 dijit/tests/layout/multipleLayoutWidgets.php       |   10 +-
 dijit/tests/layout/nestedStack.html                |  278 +-
 .../layout/robot/AccordionContainer_a11y.html      |   65 +-
 .../layout/robot/AccordionContainer_mouse.html     |   42 +-
 dijit/tests/layout/robot/BorderContainer.html      |  158 +-
 .../layout/robot/BorderContainer_complex.html      |  216 +-
 dijit/tests/layout/robot/BorderContainer_full.html |  117 +-
 .../tests/layout/robot/BorderContainer_nested.html |  145 +-
 dijit/tests/layout/robot/GUI.html                  |  222 +-
 dijit/tests/layout/robot/TabContainer_a11y.html    |  386 +-
 dijit/tests/layout/robot/TabContainer_mouse.html   |  286 +-
 .../tests/layout/robot/TabContainer_noLayout.html  |  558 +-
 .../layout/robot/borderContainerTestFunctions.js   |  197 +-
 dijit/tests/layout/runTests.html                   |    2 +-
 dijit/tests/layout/tab3.html                       |    6 +-
 dijit/tests/layout/tab3_noLayout.html              |    6 +-
 dijit/tests/layout/tab4.html                       |    6 +-
 dijit/tests/layout/test_AccordionContainer.html    |  124 +-
 dijit/tests/layout/test_BorderContainer.html       |  230 +-
 .../tests/layout/test_BorderContainer_complex.html |  100 +-
 .../layout/test_BorderContainer_experimental.html  |  131 +-
 dijit/tests/layout/test_BorderContainer_full.html  |   43 +-
 .../tests/layout/test_BorderContainer_nested.html  |  110 +-
 dijit/tests/layout/test_ContentPane.html           |  259 +-
 dijit/tests/layout/test_Gui.html                   |  147 +-
 dijit/tests/layout/test_SplitContainer.html        |   24 +-
 dijit/tests/layout/test_TabContainer.html          |  433 +-
 dijit/tests/layout/test_TabContainer_CSS.html      |  107 +
 dijit/tests/layout/test_TabContainer_noLayout.html |  118 +-
 dijit/tests/loremIpsum.html                        |   99 +
 dijit/tests/mobile.html                            |  163 +-
 dijit/tests/module.js                              |   28 +-
 dijit/tests/place-clip.html                        |  267 +
 dijit/tests/place-margin.html                      |  104 +
 dijit/tests/place.html                             |  251 +
 dijit/tests/popup.html                             |  615 +
 dijit/tests/registry.html                          |   93 +
 dijit/tests/resources/TestContextRequireWidget.js  |   17 +
 dijit/tests/resources/TestWidget.js                |   10 +
 dijit/tests/robot/BgIframe.html                    |  135 +-
 dijit/tests/robot/Calendar_a11y.html               |  276 +-
 dijit/tests/robot/ColorPalette.html                |  173 +-
 dijit/tests/robot/Dialog_a11y.html                 |  447 +-
 dijit/tests/robot/Dialog_focusDestroy.html         |   51 +-
 dijit/tests/robot/Dialog_mouse.html                |  628 +-
 dijit/tests/robot/InlineEditBox.html               |  273 +-
 dijit/tests/robot/Menu_a11y.html                   |  835 +-
 dijit/tests/robot/Menu_iframe.html                 |  198 +-
 dijit/tests/robot/Menu_mouse.html                  |  482 +-
 dijit/tests/robot/TitlePane.html                   |  117 +-
 dijit/tests/robot/Toolbar.html                     |  215 +-
 dijit/tests/robot/TooltipDialog_a11y.html          |  306 +-
 dijit/tests/robot/TooltipDialog_mouse.html         |  277 +-
 dijit/tests/robot/Tooltip_a11y.html                |  197 +-
 dijit/tests/robot/Tooltip_mouse.html               |  210 +-
 dijit/tests/robot/Tooltip_mouse_quirks.html        |   35 +-
 dijit/tests/robot/_Widget-deferredConnect.html     |   39 +-
 dijit/tests/robot/_Widget-ondijitclick_a11y.html   |  127 +-
 dijit/tests/robot/_Widget-ondijitclick_mouse.html  |   75 +-
 dijit/tests/robot/typematic.html                   |  103 +
 dijit/tests/test_Calendar.html                     |   76 +-
 dijit/tests/test_CalendarLite.html                 |   43 -
 dijit/tests/test_ColorPalette.html                 |   66 +-
 dijit/tests/test_Declaration.html                  |   68 +-
 dijit/tests/test_Dialog.html                       |  348 +-
 dijit/tests/test_Dialog_focusDestroy.html          |   67 +-
 dijit/tests/test_InlineEditBox.html                |  130 +-
 dijit/tests/test_Menu.html                         |  459 +-
 dijit/tests/test_Menu_iframe.html                  |   10 +-
 dijit/tests/test_TitlePane.html                    |  111 +-
 dijit/tests/test_Toolbar.html                      |  123 +-
 dijit/tests/test_Tooltip.html                      |  210 +-
 dijit/tests/test_TooltipDialog.html                |  211 +-
 dijit/tests/test_UIWindowIssue_main.html           |   74 +-
 dijit/tests/test_bgIframe.html                     |   70 +-
 dijit/tests/test_typematic.html                    |   68 +
 dijit/tests/tree/CustomLabel.html                  |  104 +-
 dijit/tests/tree/Tree.html                         |  396 -
 dijit/tests/tree/Tree_ForestStoreModel.html        |  386 +
 dijit/tests/tree/Tree_ObjectStoreModel.html        |  972 +
 dijit/tests/tree/Tree_with_JRS.html                |    9 +-
 dijit/tests/tree/module.js                         |   35 +-
 dijit/tests/tree/places.json                       |   50 +-
 dijit/tests/tree/robot/Tree_Custom_TreeNode.html   |   64 +
 dijit/tests/tree/robot/Tree_a11y.html              | 1020 +-
 dijit/tests/tree/robot/Tree_dnd.html               |  425 +-
 dijit/tests/tree/robot/Tree_dnd.js                 |  241 +-
 dijit/tests/tree/robot/Tree_dnd_multiParent.html   |  207 +-
 dijit/tests/tree/robot/Tree_mouse.html             |  103 +
 dijit/tests/tree/robot/Tree_selector.html          |  350 +-
 dijit/tests/tree/robot/Tree_v1.html                |  124 +-
 dijit/tests/tree/test_Custom_TreeNode.html         |   95 +
 dijit/tests/tree/test_Tree.html                    |  166 +-
 dijit/tests/tree/test_Tree_DnD.html                |  304 +-
 dijit/tests/tree/test_Tree_v1.html                 |   60 +-
 dijit/themes/claro/Calendar.css                    |   75 +-
 dijit/themes/claro/Calendar.less                   |   34 +-
 dijit/themes/claro/ColorPalette.css                |    5 +-
 dijit/themes/claro/Common.css                      |   45 +-
 dijit/themes/claro/Common.less                     |   34 +-
 dijit/themes/claro/Dialog.css                      |   46 +-
 dijit/themes/claro/Dialog.less                     |   33 +-
 dijit/themes/claro/Editor.css                      |   23 +-
 dijit/themes/claro/Editor.less                     |   10 +-
 dijit/themes/claro/Editor_rtl.css                  |    7 +
 dijit/themes/claro/Editor_rtl.less                 |   13 +-
 dijit/themes/claro/Menu.css                        |  136 +-
 dijit/themes/claro/Menu.less                       |  139 +-
 dijit/themes/claro/ProgressBar.css                 |   14 +-
 dijit/themes/claro/ProgressBar.less                |   13 +-
 dijit/themes/claro/ProgressBar_rtl.css             |    8 +
 dijit/themes/claro/ProgressBar_rtl.less            |   11 +
 dijit/themes/claro/README                          |   34 +-
 dijit/themes/claro/TimePicker.css                  |   50 +-
 dijit/themes/claro/TimePicker.less                 |   44 +-
 dijit/themes/claro/TitlePane.css                   |   46 +-
 dijit/themes/claro/TitlePane.less                  |   34 +-
 dijit/themes/claro/TitlePane_rtl.css               |    3 +-
 dijit/themes/claro/TitlePane_rtl.less              |    2 +-
 dijit/themes/claro/Toolbar.css                     |   80 +-
 dijit/themes/claro/Toolbar.less                    |   30 +-
 dijit/themes/claro/Toolbar_rtl.css                 |    6 +-
 dijit/themes/claro/Tree.css                        |   56 +-
 dijit/themes/claro/Tree.less                       |   39 +-
 dijit/themes/claro/claro_rtl.css                   |    3 +-
 dijit/themes/claro/compile.js                      |    2 +-
 dijit/themes/claro/document.css                    |    6 +-
 dijit/themes/claro/form/Button.css                 |   34 +-
 dijit/themes/claro/form/Button.less                |   38 +-
 dijit/themes/claro/form/Checkbox.css               |   12 +-
 dijit/themes/claro/form/Common.css                 |  112 +-
 dijit/themes/claro/form/Common.less                |   76 +-
 dijit/themes/claro/form/Common_rtl.css             |    5 -
 dijit/themes/claro/form/Common_rtl.less            |    5 -
 dijit/themes/claro/form/NumberSpinner.css          |   34 +-
 dijit/themes/claro/form/NumberSpinner.less         |   10 +-
 dijit/themes/claro/form/RadioButton.css            |   12 +-
 dijit/themes/claro/form/Select.css                 |   71 +-
 dijit/themes/claro/form/Select.less                |   65 +-
 dijit/themes/claro/form/Select_rtl.css             |    4 -
 dijit/themes/claro/form/Select_rtl.less            |    6 -
 dijit/themes/claro/form/Slider.css                 |  139 +-
 dijit/themes/claro/form/Slider.less                |   43 +-
 dijit/themes/claro/form/Slider_rtl.css             |    4 +-
 dijit/themes/claro/form/images/button.png          |  Bin 680 -> 0 bytes
 dijit/themes/claro/form/images/buttonDisabled.png  |  Bin 0 -> 105 bytes
 dijit/themes/claro/form/images/buttonDisabled.svg  |   23 +
 dijit/themes/claro/form/images/buttonEnabled.png   |  Bin 0 -> 122 bytes
 dijit/themes/claro/form/images/buttonEnabled.svg   |   24 +
 dijit/themes/claro/form/images/button_grad_d.png   |  Bin 3897 -> 0 bytes
 dijit/themes/claro/form/images/formHighlight.png   |  Bin 339 -> 0 bytes
 dijit/themes/claro/form/images/shadow.png          |  Bin 4624 -> 0 bytes
 .../themes/claro/form/images/sliderHorizontal.png  |  Bin 180 -> 0 bytes
 dijit/themes/claro/form/images/sliderVertical.png  |  Bin 177 -> 0 bytes
 dijit/themes/claro/form/images/textBox_back.png    |  Bin 2837 -> 0 bytes
 dijit/themes/claro/images/activeGradient.png       |  Bin 0 -> 94 bytes
 dijit/themes/claro/images/activeGradient.svg       |   19 +
 dijit/themes/claro/images/calendar.png             |  Bin 0 -> 142 bytes
 dijit/themes/claro/images/calendarArrows.png       |  Bin 1425 -> 1238 bytes
 dijit/themes/claro/images/calendarArrows8bit.png   |  Bin 1053 -> 998 bytes
 .../claro/images/calendarContainerImages.png       |  Bin 3347 -> 0 bytes
 dijit/themes/claro/images/checkmarkNoBorder.png    |  Bin 4401 -> 1394 bytes
 dijit/themes/claro/images/commonHighlight.png      |  Bin 339 -> 0 bytes
 dijit/themes/claro/images/dialogCloseIcon.png      |  Bin 1660 -> 1423 bytes
 dijit/themes/claro/images/dialogCloseIcon8bit.png  |  Bin 705 -> 649 bytes
 dijit/themes/claro/images/dnd.png                  |  Bin 2996 -> 1910 bytes
 dijit/themes/claro/images/loadingAnimation.gif     |  Bin 718 -> 631 bytes
 dijit/themes/claro/images/menuHighlight.png        |  Bin 339 -> 0 bytes
 dijit/themes/claro/images/progressBarEmpty.png     |  Bin 2849 -> 0 bytes
 dijit/themes/claro/images/progressBarFull.png      |  Bin 177 -> 127 bytes
 dijit/themes/claro/images/spriteArrows.png         |  Bin 233 -> 175 bytes
 dijit/themes/claro/images/standardGradient.png     |  Bin 0 -> 101 bytes
 dijit/themes/claro/images/standardGradient.svg     |   18 +
 dijit/themes/claro/images/tooltip.png              |  Bin 1818 -> 713 bytes
 dijit/themes/claro/images/tooltip8bit.png          |  Bin 589 -> 534 bytes
 dijit/themes/claro/images/tooltipGradient.png      |  Bin 1030 -> 0 bytes
 dijit/themes/claro/images/treeExpandImages.png     |  Bin 676 -> 465 bytes
 dijit/themes/claro/images/treeExpandImages8bit.png |  Bin 799 -> 744 bytes
 dijit/themes/claro/images/treeExpand_loading.gif   |  Bin 1944 -> 0 bytes
 dijit/themes/claro/layout/AccordionContainer.css   |   60 +-
 dijit/themes/claro/layout/AccordionContainer.less  |   45 +-
 dijit/themes/claro/layout/BorderContainer.css      |   52 +-
 dijit/themes/claro/layout/BorderContainer.less     |   33 +-
 dijit/themes/claro/layout/ContentPane.css          |    3 +-
 dijit/themes/claro/layout/TabContainer.css         |  266 +-
 dijit/themes/claro/layout/TabContainer.less        |  270 +-
 dijit/themes/claro/layout/TabContainer_rtl.css     |   66 +-
 dijit/themes/claro/layout/TabContainer_rtl.less    |   74 -
 dijit/themes/claro/layout/images/accordion.png     |  Bin 640 -> 0 bytes
 .../layout/images/splitterHorizontalHover.png      |  Bin 3711 -> 0 bytes
 .../claro/layout/images/splitterVerticalHover.png  |  Bin 3869 -> 0 bytes
 dijit/themes/claro/layout/images/tabBottom.png     |  Bin 718 -> 0 bytes
 .../claro/layout/images/tabBottomSelected.png      |  Bin 0 -> 118 bytes
 .../claro/layout/images/tabBottomSelected.svg      |   18 +
 .../claro/layout/images/tabBottomUnselected.png    |  Bin 0 -> 110 bytes
 .../claro/layout/images/tabBottomUnselected.svg    |   19 +
 dijit/themes/claro/layout/images/tabLeft.png       |  Bin 1692 -> 0 bytes
 .../themes/claro/layout/images/tabLeftSelected.png |  Bin 0 -> 213 bytes
 .../themes/claro/layout/images/tabLeftSelected.svg |   17 +
 .../claro/layout/images/tabLeftUnselected.png      |  Bin 0 -> 106 bytes
 .../claro/layout/images/tabLeftUnselected.svg      |   16 +
 dijit/themes/claro/layout/images/tabRight.png      |  Bin 1759 -> 0 bytes
 .../claro/layout/images/tabRightSelected.png       |  Bin 0 -> 210 bytes
 .../claro/layout/images/tabRightSelected.svg       |   17 +
 .../claro/layout/images/tabRightUnselected.png     |  Bin 0 -> 105 bytes
 .../claro/layout/images/tabRightUnselected.svg     |   16 +
 dijit/themes/claro/layout/images/tabTop.png        |  Bin 721 -> 0 bytes
 .../themes/claro/layout/images/tabTopSelected.png  |  Bin 0 -> 120 bytes
 .../themes/claro/layout/images/tabTopSelected.svg  |   18 +
 .../claro/layout/images/tabTopUnselected.png       |  Bin 0 -> 121 bytes
 .../claro/layout/images/tabTopUnselected.svg       |   19 +
 dijit/themes/claro/variables.less                  |  186 +-
 dijit/themes/dijit.css                             |  533 +-
 dijit/themes/dijit_rtl.css                         |   57 +-
 dijit/themes/nihilo/Common.css                     |   14 +-
 dijit/themes/nihilo/Dialog.css                     |   10 +-
 dijit/themes/nihilo/Menu.css                       |   17 +-
 dijit/themes/nihilo/ProgressBar.css                |    3 +-
 dijit/themes/nihilo/ProgressBar_rtl.css            |   12 +
 dijit/themes/nihilo/TimePicker.css                 |   24 +-
 dijit/themes/nihilo/TitlePane.css                  |   14 +-
 dijit/themes/nihilo/TitlePane_rtl.css              |    5 +-
 dijit/themes/nihilo/form/Button.css                |    7 +-
 dijit/themes/nihilo/form/Button_rtl.css            |    6 +-
 dijit/themes/nihilo/form/Common.css                |   19 +-
 dijit/themes/nihilo/form/Select.css                |   46 +-
 dijit/themes/nihilo/form/TimeTextBox.css           |    2 +-
 dijit/themes/nihilo/images/accordionItemActive.png |  Bin 148 -> 106 bytes
 dijit/themes/nihilo/images/buttonActive.png        |  Bin 139 -> 105 bytes
 dijit/themes/nihilo/images/buttonDisabled.png      |  Bin 139 -> 89 bytes
 dijit/themes/nihilo/images/buttonEnabled.png       |  Bin 135 -> 100 bytes
 dijit/themes/nihilo/images/buttonHover.png         |  Bin 134 -> 100 bytes
 dijit/themes/nihilo/images/dndCopy.png             |  Bin 777 -> 727 bytes
 dijit/themes/nihilo/images/dndMove.png             |  Bin 726 -> 676 bytes
 dijit/themes/nihilo/images/dndNoCopy.png           |  Bin 699 -> 1259 bytes
 dijit/themes/nihilo/images/dndNoMove.png           |  Bin 677 -> 951 bytes
 dijit/themes/nihilo/images/preciseSliderThumb.png  |  Bin 413 -> 334 bytes
 .../nihilo/images/preciseSliderThumbFocus.png      |  Bin 434 -> 338 bytes
 dijit/themes/nihilo/images/progressBarEmpty.png    |  Bin 314 -> 272 bytes
 dijit/themes/nihilo/images/progressBarFull.png     |  Bin 746 -> 702 bytes
 dijit/themes/nihilo/images/sliderEmpty.png         |  Bin 114 -> 71 bytes
 dijit/themes/nihilo/images/sliderEmptyVertical.png |  Bin 114 -> 71 bytes
 dijit/themes/nihilo/images/sliderFull.png          |  Bin 130 -> 91 bytes
 dijit/themes/nihilo/images/sliderFullFocus.png     |  Bin 132 -> 86 bytes
 dijit/themes/nihilo/images/sliderFullVertical.png  |  Bin 126 -> 84 bytes
 .../nihilo/images/sliderFullVerticalFocus.png      |  Bin 126 -> 83 bytes
 dijit/themes/nihilo/images/sliderThumb.png         |  Bin 413 -> 300 bytes
 dijit/themes/nihilo/images/sliderThumbFocus.png    |  Bin 421 -> 306 bytes
 .../nihilo/images/splitContainerSizerH-thumb.png   |  Bin 127 -> 77 bytes
 .../themes/nihilo/images/splitContainerSizerH.png  |  Bin 121 -> 81 bytes
 .../nihilo/images/splitContainerSizerV-thumb.png   |  Bin 129 -> 79 bytes
 .../themes/nihilo/images/splitContainerSizerV.png  |  Bin 116 -> 77 bytes
 dijit/themes/nihilo/images/spriteArrows.png        |  Bin 720 -> 476 bytes
 dijit/themes/nihilo/images/spriteCheckbox.png      |  Bin 707 -> 681 bytes
 dijit/themes/nihilo/images/spriteDivIcons.png      |  Bin 1062 -> 995 bytes
 dijit/themes/nihilo/images/spriteRadio.png         |  Bin 1073 -> 958 bytes
 .../nihilo/images/spriteRoundedIconsSmall.png      |  Bin 2195 -> 1870 bytes
 dijit/themes/nihilo/images/spriteTree.png          |  Bin 337 -> 237 bytes
 dijit/themes/nihilo/images/spriteTree_rtl.png      |  Bin 335 -> 236 bytes
 .../nihilo/images/tabBottomActiveSpriteLR.gif      |  Bin 291 -> 0 bytes
 .../nihilo/images/tabBottomEnabledSpriteLR.gif     |  Bin 266 -> 0 bytes
 .../nihilo/images/tabBottomHoverSpriteLR.gif       |  Bin 388 -> 0 bytes
 dijit/themes/nihilo/images/tabLeftChecked.gif      |  Bin 303 -> 0 bytes
 dijit/themes/nihilo/images/tabRightChecked.gif     |  Bin 300 -> 0 bytes
 dijit/themes/nihilo/images/tabStripe.gif           |  Bin 54 -> 0 bytes
 dijit/themes/nihilo/images/tabStripeBottom.gif     |  Bin 432 -> 0 bytes
 dijit/themes/nihilo/images/tabStripeLeft.gif       |  Bin 432 -> 0 bytes
 dijit/themes/nihilo/images/tabStripeRight.gif      |  Bin 432 -> 0 bytes
 dijit/themes/nihilo/images/titleBar.png            |  Bin 148 -> 99 bytes
 dijit/themes/nihilo/images/titleBarActive.png      |  Bin 155 -> 113 bytes
 .../themes/nihilo/images/tooltipConnectorDown.png  |  Bin 342 -> 265 bytes
 .../themes/nihilo/images/tooltipConnectorLeft.png  |  Bin 361 -> 246 bytes
 .../themes/nihilo/images/tooltipConnectorRight.png |  Bin 363 -> 252 bytes
 dijit/themes/nihilo/images/tooltipConnectorUp.png  |  Bin 319 -> 253 bytes
 dijit/themes/nihilo/images/treeHover.png           |  Bin 112 -> 78 bytes
 dijit/themes/nihilo/images/validationInputBg.png   |  Bin 126 -> 89 bytes
 dijit/themes/nihilo/images/warning.png             |  Bin 1275 -> 1197 bytes
 dijit/themes/nihilo/layout/TabContainer.css        |  226 +-
 dijit/themes/nihilo/nihilo_rtl.css                 |    1 +
 dijit/themes/soria/Common.css                      |   19 +-
 dijit/themes/soria/Dialog.css                      |   10 +-
 dijit/themes/soria/Menu.css                        |   17 +-
 dijit/themes/soria/ProgressBar.css                 |    3 +-
 dijit/themes/soria/ProgressBar_rtl.css             |    9 +
 dijit/themes/soria/TimePicker.css                  |   26 +-
 dijit/themes/soria/TitlePane.css                   |   14 +-
 dijit/themes/soria/TitlePane_rtl.css               |    5 +-
 dijit/themes/soria/form/Button.css                 |    6 +-
 dijit/themes/soria/form/Button_rtl.css             |    6 +-
 dijit/themes/soria/form/Common.css                 |   18 +-
 dijit/themes/soria/form/Select.css                 |   55 +-
 dijit/themes/soria/form/TimeTextBox.css            |    2 +-
 dijit/themes/soria/images/accordionItemActive.png  |  Bin 171 -> 138 bytes
 dijit/themes/soria/images/buttonActive.png         |  Bin 187 -> 147 bytes
 dijit/themes/soria/images/buttonDisabled.png       |  Bin 187 -> 138 bytes
 dijit/themes/soria/images/buttonEnabled.png        |  Bin 174 -> 122 bytes
 dijit/themes/soria/images/buttonHover.png          |  Bin 160 -> 116 bytes
 dijit/themes/soria/images/dndCopy.png              |  Bin 777 -> 727 bytes
 dijit/themes/soria/images/dndMove.png              |  Bin 726 -> 676 bytes
 dijit/themes/soria/images/dndNoCopy.png            |  Bin 699 -> 1259 bytes
 dijit/themes/soria/images/dndNoMove.png            |  Bin 677 -> 951 bytes
 dijit/themes/soria/images/preciseSliderThumb.png   |  Bin 413 -> 334 bytes
 .../soria/images/preciseSliderThumbFocus.png       |  Bin 434 -> 338 bytes
 dijit/themes/soria/images/progressBarEmpty.png     |  Bin 232 -> 192 bytes
 dijit/themes/soria/images/progressBarFull.png      |  Bin 251 -> 210 bytes
 dijit/themes/soria/images/sliderEmpty.png          |  Bin 114 -> 71 bytes
 dijit/themes/soria/images/sliderEmptyVertical.png  |  Bin 114 -> 71 bytes
 dijit/themes/soria/images/sliderFull.png           |  Bin 131 -> 88 bytes
 dijit/themes/soria/images/sliderFullFocus.png      |  Bin 146 -> 105 bytes
 dijit/themes/soria/images/sliderFullVertical.png   |  Bin 127 -> 84 bytes
 .../soria/images/sliderFullVerticalFocus.png       |  Bin 143 -> 103 bytes
 dijit/themes/soria/images/sliderThumb.png          |  Bin 413 -> 300 bytes
 dijit/themes/soria/images/sliderThumbFocus.png     |  Bin 421 -> 306 bytes
 .../soria/images/splitContainerSizerH-thumb.png    |  Bin 125 -> 83 bytes
 dijit/themes/soria/images/splitContainerSizerH.png |  Bin 127 -> 84 bytes
 .../soria/images/splitContainerSizerV-thumb.png    |  Bin 121 -> 79 bytes
 dijit/themes/soria/images/splitContainerSizerV.png |  Bin 124 -> 84 bytes
 dijit/themes/soria/images/spriteArrows.png         |  Bin 720 -> 476 bytes
 dijit/themes/soria/images/spriteCheckbox.png       |  Bin 707 -> 681 bytes
 dijit/themes/soria/images/spriteDivIcons.png       |  Bin 1114 -> 1055 bytes
 dijit/themes/soria/images/spriteRadio.png          |  Bin 1073 -> 958 bytes
 .../soria/images/spriteRoundedIconsSmall.png       |  Bin 3187 -> 2360 bytes
 .../soria/images/spriteRoundedIconsSmallBl.png     |  Bin 3010 -> 2319 bytes
 dijit/themes/soria/images/spriteTree.png           |  Bin 337 -> 237 bytes
 dijit/themes/soria/images/spriteTree_rtl.png       |  Bin 335 -> 236 bytes
 .../soria/images/tabBottomActiveSpriteLR.gif       |  Bin 741 -> 0 bytes
 .../themes/soria/images/tabBottomHoverSpriteLR.gif |  Bin 569 -> 0 bytes
 dijit/themes/soria/images/tabLeftChecked.gif       |  Bin 795 -> 2005 bytes
 dijit/themes/soria/images/tabRightChecked.gif      |  Bin 793 -> 2003 bytes
 dijit/themes/soria/images/tabStripe.gif            |  Bin 54 -> 0 bytes
 dijit/themes/soria/images/tabStripeBottom.gif      |  Bin 54 -> 0 bytes
 dijit/themes/soria/images/tabStripeLeft.gif        |  Bin 54 -> 0 bytes
 dijit/themes/soria/images/tabStripeRight.gif       |  Bin 54 -> 0 bytes
 dijit/themes/soria/images/titleBar.png             |  Bin 183 -> 142 bytes
 dijit/themes/soria/images/titleBarActive.png       |  Bin 183 -> 147 bytes
 dijit/themes/soria/images/tooltipConnectorDown.png |  Bin 342 -> 265 bytes
 dijit/themes/soria/images/tooltipConnectorLeft.png |  Bin 361 -> 246 bytes
 .../themes/soria/images/tooltipConnectorRight.png  |  Bin 363 -> 252 bytes
 dijit/themes/soria/images/tooltipConnectorUp.png   |  Bin 319 -> 253 bytes
 dijit/themes/soria/images/treeHover.png            |  Bin 112 -> 78 bytes
 dijit/themes/soria/images/validationInputBg.png    |  Bin 126 -> 89 bytes
 dijit/themes/soria/images/warning.png              |  Bin 1275 -> 1197 bytes
 dijit/themes/soria/layout/TabContainer.css         |  233 +-
 dijit/themes/soria/soria_rtl.css                   |    1 +
 dijit/themes/themeTester-orig.html                 |    1 +
 dijit/themes/themeTester.html                      | 2093 +-
 dijit/themes/tundra/Common.css                     |   18 +-
 dijit/themes/tundra/Menu.css                       |   20 +-
 dijit/themes/tundra/ProgressBar.css                |    3 +-
 dijit/themes/tundra/ProgressBar_rtl.css            |    5 +
 dijit/themes/tundra/TimePicker.css                 |   30 +-
 dijit/themes/tundra/TimePicker_rtl.css             |    2 +-
 dijit/themes/tundra/TitlePane.css                  |    8 +-
 dijit/themes/tundra/TitlePane_rtl.css              |    2 +-
 dijit/themes/tundra/form/Button.css                |    8 +-
 dijit/themes/tundra/form/Common.css                |   15 +-
 dijit/themes/tundra/form/Select.css                |   52 +-
 dijit/themes/tundra/images/buttonActive.png        |  Bin 129 -> 92 bytes
 dijit/themes/tundra/images/buttonDisabled.png      |  Bin 135 -> 99 bytes
 dijit/themes/tundra/images/buttonEnabled.png       |  Bin 120 -> 99 bytes
 dijit/themes/tundra/images/buttonHover.png         |  Bin 144 -> 107 bytes
 dijit/themes/tundra/images/calendarDayLabel.png    |  Bin 161 -> 124 bytes
 dijit/themes/tundra/images/calendarMonthLabel.png  |  Bin 162 -> 125 bytes
 dijit/themes/tundra/images/calendarYearLabel.png   |  Bin 172 -> 135 bytes
 dijit/themes/tundra/images/checkmark.png           |  Bin 5529 -> 1743 bytes
 dijit/themes/tundra/images/checkmarkNoBorder.png   |  Bin 4401 -> 1394 bytes
 dijit/themes/tundra/images/circleIcon.png          |  Bin 2975 -> 283 bytes
 dijit/themes/tundra/images/dndCopy.png             |  Bin 777 -> 727 bytes
 dijit/themes/tundra/images/dndMove.png             |  Bin 726 -> 676 bytes
 dijit/themes/tundra/images/dndNoCopy.png           |  Bin 699 -> 1259 bytes
 dijit/themes/tundra/images/dndNoMove.png           |  Bin 677 -> 951 bytes
 .../themes/tundra/images/dojoTundraGradientBg.png  |  Bin 135 -> 98 bytes
 dijit/themes/tundra/images/doubleArrowDown.png     |  Bin 152 -> 102 bytes
 dijit/themes/tundra/images/doubleArrowUp.png       |  Bin 158 -> 108 bytes
 dijit/themes/tundra/images/loading.gif             |  Bin 751 -> 687 bytes
 dijit/themes/tundra/images/menu.png                |  Bin 140 -> 90 bytes
 dijit/themes/tundra/images/preciseSliderThumb.png  |  Bin 248 -> 198 bytes
 .../tundra/images/preciseSliderThumbFocus.png      |  Bin 281 -> 203 bytes
 dijit/themes/tundra/images/progressBarAnim-1.png   |  Bin 288 -> 238 bytes
 dijit/themes/tundra/images/progressBarAnim-2.png   |  Bin 289 -> 239 bytes
 dijit/themes/tundra/images/progressBarAnim-3.png   |  Bin 288 -> 238 bytes
 dijit/themes/tundra/images/progressBarAnim-4.png   |  Bin 287 -> 237 bytes
 dijit/themes/tundra/images/progressBarAnim-5.png   |  Bin 283 -> 233 bytes
 dijit/themes/tundra/images/progressBarAnim-6.png   |  Bin 283 -> 233 bytes
 dijit/themes/tundra/images/progressBarAnim-7.png   |  Bin 284 -> 234 bytes
 dijit/themes/tundra/images/progressBarAnim-8.png   |  Bin 286 -> 236 bytes
 dijit/themes/tundra/images/progressBarAnim-9.png   |  Bin 289 -> 239 bytes
 dijit/themes/tundra/images/progressBarEmpty.png    |  Bin 164 -> 106 bytes
 dijit/themes/tundra/images/progressBarFull.png     |  Bin 160 -> 125 bytes
 dijit/themes/tundra/images/radioButtonActive.png   |  Bin 550 -> 500 bytes
 .../tundra/images/radioButtonActiveDisabled.png    |  Bin 517 -> 467 bytes
 .../tundra/images/radioButtonActiveHover.png       |  Bin 646 -> 596 bytes
 dijit/themes/tundra/images/radioButtonDisabled.png |  Bin 403 -> 353 bytes
 dijit/themes/tundra/images/radioButtonEnabled.png  |  Bin 487 -> 437 bytes
 dijit/themes/tundra/images/radioButtonHover.png    |  Bin 497 -> 447 bytes
 dijit/themes/tundra/images/sliderEmpty.png         |  Bin 124 -> 74 bytes
 dijit/themes/tundra/images/sliderEmptyVertical.png |  Bin 88 -> 75 bytes
 dijit/themes/tundra/images/sliderFull.png          |  Bin 135 -> 85 bytes
 dijit/themes/tundra/images/sliderFullFocus.png     |  Bin 163 -> 85 bytes
 dijit/themes/tundra/images/sliderFullVertical.png  |  Bin 99 -> 86 bytes
 .../tundra/images/sliderFullVerticalFocus.png      |  Bin 164 -> 86 bytes
 dijit/themes/tundra/images/sliderThumb.png         |  Bin 241 -> 191 bytes
 dijit/themes/tundra/images/sliderThumbFocus.png    |  Bin 288 -> 210 bytes
 dijit/themes/tundra/images/smallArrowDown.png      |  Bin 134 -> 84 bytes
 dijit/themes/tundra/images/smallArrowUp.png        |  Bin 134 -> 84 bytes
 .../tundra/images/splitContainerSizerH-thumb.png   |  Bin 127 -> 77 bytes
 .../themes/tundra/images/splitContainerSizerH.png  |  Bin 140 -> 90 bytes
 .../tundra/images/splitContainerSizerV-thumb.png   |  Bin 129 -> 79 bytes
 .../themes/tundra/images/splitContainerSizerV.png  |  Bin 135 -> 85 bytes
 dijit/themes/tundra/images/spriteArrows.png        |  Bin 338 -> 216 bytes
 .../tundra/images/spriteRoundedIconsSmall.png      |  Bin 2195 -> 1870 bytes
 dijit/themes/tundra/images/tabActive.png           |  Bin 155 -> 105 bytes
 dijit/themes/tundra/images/tabClose.png            |  Bin 220 -> 170 bytes
 dijit/themes/tundra/images/tabCloseHover.png       |  Bin 220 -> 170 bytes
 dijit/themes/tundra/images/tabDisabled.png         |  Bin 139 -> 101 bytes
 dijit/themes/tundra/images/tabEnabled.png          |  Bin 142 -> 106 bytes
 dijit/themes/tundra/images/tabHover.png            |  Bin 154 -> 112 bytes
 dijit/themes/tundra/images/titleBar.png            |  Bin 151 -> 114 bytes
 .../themes/tundra/images/tooltipConnectorDown.png  |  Bin 410 -> 292 bytes
 .../themes/tundra/images/tooltipConnectorLeft.png  |  Bin 3106 -> 300 bytes
 .../themes/tundra/images/tooltipConnectorRight.png |  Bin 3121 -> 329 bytes
 dijit/themes/tundra/images/tooltipConnectorUp.png  |  Bin 3092 -> 289 bytes
 dijit/themes/tundra/images/treeExpand_loading.gif  |  Bin 1944 -> 1894 bytes
 dijit/themes/tundra/images/treeHover.png           |  Bin 112 -> 78 bytes
 dijit/themes/tundra/images/validationInputBg.png   |  Bin 165 -> 115 bytes
 dijit/themes/tundra/images/warning.png             |  Bin 1275 -> 1197 bytes
 dijit/themes/tundra/layout/TabContainer.css        |   42 +-
 dijit/themes/tundra/layout/TabContainer_rtl.css    |   48 -
 dijit/themes/tundra/tundra_rtl.css                 |    1 +
 dijit/tree/ForestStoreModel.js                     |   46 +-
 dijit/tree/ObjectStoreModel.js                     |  253 +
 dijit/tree/TreeStoreModel.js                       |   60 +-
 dijit/tree/_dndContainer.js                        |   65 +-
 dijit/tree/_dndSelector.js                         |  127 +-
 dijit/tree/dndSource.js                            | 1020 +-
 dijit/tree/model.js                                |  273 +-
 dijit/typematic.js                                 |  385 +-
 dojo/AdapterRegistry.js                            |   29 +-
 dojo/Deferred.js                                   |  320 +
 dojo/DeferredList.js                               |   10 +-
 dojo/Evented.js                                    |   27 +-
 dojo/LICENSE                                       |    2 +-
 dojo/NodeList-data.js                              |  161 +-
 dojo/NodeList-dom.js                               |  194 +-
 dojo/NodeList-fx.js                                |   97 +-
 dojo/NodeList-html.js                              |   40 +-
 dojo/NodeList-manipulate.js                        |  350 +-
 dojo/NodeList-traverse.js                          |  255 +-
 dojo/NodeList.js                                   |    6 +
 dojo/OpenAjax.js                                   |   28 +-
 dojo/Stateful.js                                   |  146 +-
 dojo/_base/Color.js                                |   74 +-
 dojo/_base/Deferred.js                             |  171 +-
 dojo/_base/NodeList.js                             |  106 +-
 dojo/_base/array.js                                |  523 +-
 dojo/_base/browser.js                              |   13 +-
 dojo/_base/config.js                               |  163 +-
 dojo/_base/configFirefoxExtension.js               |   28 +-
 dojo/_base/configNode.js                           |   10 +-
 dojo/_base/configRhino.js                          |    2 +-
 dojo/_base/configSpidermonkey.js                   |   14 +-
 dojo/_base/connect.js                              |  380 +-
 dojo/_base/declare.js                              |  843 +-
 dojo/_base/event.js                                |   74 +-
 dojo/_base/fx.js                                   |  274 +-
 dojo/_base/html.js                                 |   25 +-
 dojo/_base/json.js                                 |   18 +-
 dojo/_base/kernel.js                               |  101 +-
 dojo/_base/lang.js                                 |  972 +-
 dojo/_base/loader.js                               |  405 +-
 dojo/_base/query.js                                |   14 +-
 dojo/_base/sniff.js                                |  212 +-
 dojo/_base/unload.js                               |   87 +-
 dojo/_base/url.js                                  |    4 +-
 dojo/_base/window.js                               |  226 +-
 dojo/_base/xhr.js                                  |  644 +-
 dojo/_firebug/firebug.js                           |   70 +-
 dojo/aspect.js                                     |  254 +-
 dojo/back.js                                       |  118 +-
 dojo/behavior.js                                   |   53 +-
 dojo/cache.js                                      |    6 +-
 dojo/cldr/monetary.js                              |   27 +-
 dojo/cldr/nls/ar/buddhist.js                       |  251 +-
 dojo/cldr/nls/ar/coptic.js                         |   76 +
 dojo/cldr/nls/ar/currency.js                       |    7 +
 dojo/cldr/nls/ar/ethiopic.js                       |   46 +
 dojo/cldr/nls/ar/generic.js                        |   69 +
 dojo/cldr/nls/ar/gregorian.js                      |  316 +-
 dojo/cldr/nls/ar/hebrew.js                         |  187 +-
 dojo/cldr/nls/ar/islamic.js                        |  236 +-
 dojo/cldr/nls/ar/japanese.js                       |  269 +
 dojo/cldr/nls/ar/number.js                         |   20 +-
 dojo/cldr/nls/ar/persian.js                        |  220 +
 dojo/cldr/nls/ar/roc.js                            |   35 +
 dojo/cldr/nls/buddhist.js                          |  258 +-
 dojo/cldr/nls/ca/buddhist.js                       |  254 +
 dojo/cldr/nls/ca/chinese.js                        |  119 +
 dojo/cldr/nls/ca/currency.js                       |    8 +
 dojo/cldr/nls/ca/generic.js                        |   68 +
 dojo/cldr/nls/ca/gregorian.js                      |  157 +-
 dojo/cldr/nls/ca/number.js                         |    8 +-
 dojo/cldr/nls/ca/roc.js                            |   31 +
 dojo/cldr/nls/chinese.js                           |  414 +
 dojo/cldr/nls/coptic.js                            |  439 +
 dojo/cldr/nls/cs/buddhist.js                       |  223 +
 dojo/cldr/nls/cs/chinese.js                        |   35 +
 dojo/cldr/nls/cs/currency.js                       |   26 +-
 dojo/cldr/nls/cs/generic.js                        |   69 +
 dojo/cldr/nls/cs/gregorian.js                      |  355 +-
 dojo/cldr/nls/cs/hebrew.js                         |  153 +
 dojo/cldr/nls/cs/islamic.js                        |  153 +
 dojo/cldr/nls/cs/japanese.js                       |   35 +
 dojo/cldr/nls/cs/number.js                         |    6 +-
 dojo/cldr/nls/cs/roc.js                            |   34 +
 dojo/cldr/nls/currency.js                          |    5 +-
 dojo/cldr/nls/da/buddhist.js                       |  270 +-
 dojo/cldr/nls/da/currency.js                       |    7 +
 dojo/cldr/nls/da/generic.js                        |   69 +
 dojo/cldr/nls/da/gregorian.js                      |  100 +-
 dojo/cldr/nls/da/hebrew.js                         |  165 +
 dojo/cldr/nls/da/islamic.js                        |  186 +-
 dojo/cldr/nls/da/japanese.js                       |   35 +
 dojo/cldr/nls/da/number.js                         |    6 +-
 dojo/cldr/nls/da/roc.js                            |   35 +
 dojo/cldr/nls/dangi.js                             |  420 +
 dojo/cldr/nls/de/buddhist.js                       |  170 +-
 dojo/cldr/nls/de/chinese.js                        |   65 +
 dojo/cldr/nls/de/currency.js                       |   10 +-
 dojo/cldr/nls/de/generic.js                        |   69 +
 dojo/cldr/nls/de/gregorian.js                      |  127 +-
 dojo/cldr/nls/de/hebrew.js                         |  144 +
 dojo/cldr/nls/de/islamic.js                        |  204 +-
 dojo/cldr/nls/de/japanese.js                       |   35 +
 dojo/cldr/nls/de/number.js                         |    6 +-
 dojo/cldr/nls/de/roc.js                            |   35 +
 dojo/cldr/nls/el/buddhist.js                       |  225 +-
 dojo/cldr/nls/el/currency.js                       |    1 +
 dojo/cldr/nls/el/generic.js                        |   72 +
 dojo/cldr/nls/el/gregorian.js                      |   99 +-
 dojo/cldr/nls/el/hebrew.js                         |  157 +-
 dojo/cldr/nls/el/japanese.js                       |   50 +
 dojo/cldr/nls/el/number.js                         |    7 +-
 dojo/cldr/nls/el/roc.js                            |   55 +
 dojo/cldr/nls/en-au/chinese.js                     |   10 +
 dojo/cldr/nls/en-au/generic.js                     |   18 +
 dojo/cldr/nls/en-au/gregorian.js                   |   13 +-
 dojo/cldr/nls/en-au/japanese.js                    |   10 +
 dojo/cldr/nls/en-au/number.js                      |    7 -
 dojo/cldr/nls/en-ca/gregorian.js                   |   20 -
 dojo/cldr/nls/en-gb/buddhist.js                    |  101 -
 dojo/cldr/nls/en-gb/chinese.js                     |  131 +
 dojo/cldr/nls/en-gb/currency.js                    |   14 +
 dojo/cldr/nls/en-gb/generic.js                     |   46 +
 dojo/cldr/nls/en-gb/gregorian.js                   |   51 +-
 dojo/cldr/nls/en-gb/indian.js                      |   94 +
 dojo/cldr/nls/en-gb/islamic.js                     |  153 -
 dojo/cldr/nls/en-gb/japanese.js                    |   11 +
 dojo/cldr/nls/en/buddhist.js                       |  147 +-
 dojo/cldr/nls/en/chinese.js                        |   99 +
 dojo/cldr/nls/en/generic.js                        |   81 +
 dojo/cldr/nls/en/gregorian.js                      |  315 +-
 dojo/cldr/nls/en/hebrew.js                         |   90 +
 dojo/cldr/nls/en/islamic.js                        |  180 +-
 dojo/cldr/nls/en/japanese.js                       |   33 +
 dojo/cldr/nls/en/number.js                         |    3 +-
 dojo/cldr/nls/en/roc.js                            |   33 +
 dojo/cldr/nls/es/buddhist.js                       |  122 +-
 dojo/cldr/nls/es/chinese.js                        |   65 +
 dojo/cldr/nls/es/currency.js                       |    3 +-
 dojo/cldr/nls/es/generic.js                        |   71 +
 dojo/cldr/nls/es/gregorian.js                      |   87 +-
 dojo/cldr/nls/es/hebrew.js                         |  137 +
 dojo/cldr/nls/es/islamic.js                        |  188 +-
 dojo/cldr/nls/es/japanese.js                       |   35 +
 dojo/cldr/nls/es/number.js                         |    7 +-
 dojo/cldr/nls/es/roc.js                            |   34 +
 dojo/cldr/nls/ethiopic-amete-alem.js               |  450 +
 dojo/cldr/nls/ethiopic.js                          |  439 +
 dojo/cldr/nls/fi/buddhist.js                       |  269 +-
 dojo/cldr/nls/fi/chinese.js                        |   51 +
 dojo/cldr/nls/fi/currency.js                       |    3 +-
 dojo/cldr/nls/fi/generic.js                        |   71 +
 dojo/cldr/nls/fi/gregorian.js                      |   91 +-
 dojo/cldr/nls/fi/hebrew.js                         |  256 +-
 dojo/cldr/nls/fi/islamic.js                        |  225 +-
 dojo/cldr/nls/fi/japanese.js                       |   35 +
 dojo/cldr/nls/fi/number.js                         |    6 +-
 dojo/cldr/nls/fi/roc.js                            |   35 +
 dojo/cldr/nls/fr-ch/currency.js                    |    7 +
 dojo/cldr/nls/fr-ch/generic.js                     |    8 +
 dojo/cldr/nls/fr/buddhist.js                       |  242 +
 dojo/cldr/nls/fr/chinese.js                        |   85 +
 dojo/cldr/nls/fr/coptic.js                         |   31 +
 dojo/cldr/nls/fr/currency.js                       |    4 +-
 dojo/cldr/nls/fr/ethiopic.js                       |   31 +
 dojo/cldr/nls/fr/generic.js                        |   69 +
 dojo/cldr/nls/fr/gregorian.js                      |   91 +-
 dojo/cldr/nls/fr/hebrew.js                         |  212 +
 dojo/cldr/nls/fr/indian.js                         |   31 +
 dojo/cldr/nls/fr/islamic.js                        |  238 +
 dojo/cldr/nls/fr/japanese.js                       |   35 +
 dojo/cldr/nls/fr/number.js                         |    8 +-
 dojo/cldr/nls/fr/roc.js                            |   35 +
 dojo/cldr/nls/generic.js                           |  444 +
 dojo/cldr/nls/gregorian.js                         |  231 +-
 dojo/cldr/nls/he/generic.js                        |   67 +
 dojo/cldr/nls/he/gregorian.js                      |  134 +-
 dojo/cldr/nls/he/hebrew.js                         |  191 +-
 dojo/cldr/nls/he/islamic.js                        |  232 +-
 dojo/cldr/nls/he/japanese.js                       |  107 +
 dojo/cldr/nls/he/number.js                         |    6 +-
 dojo/cldr/nls/hebrew.js                            |  226 +-
 dojo/cldr/nls/hu/buddhist.js                       |  251 +
 dojo/cldr/nls/hu/chinese.js                        |   87 +
 dojo/cldr/nls/hu/coptic.js                         |   91 +
 dojo/cldr/nls/hu/currency.js                       |    6 +
 dojo/cldr/nls/hu/ethiopic.js                       |   91 +
 dojo/cldr/nls/hu/generic.js                        |   66 +
 dojo/cldr/nls/hu/gregorian.js                      |  306 +-
 dojo/cldr/nls/hu/hebrew.js                         |  231 +
 dojo/cldr/nls/hu/indian.js                         |   87 +
 dojo/cldr/nls/hu/islamic.js                        |  237 +
 dojo/cldr/nls/hu/japanese.js                       |   35 +
 dojo/cldr/nls/hu/number.js                         |    7 +-
 dojo/cldr/nls/hu/persian.js                        |  242 +
 dojo/cldr/nls/hu/roc.js                            |   34 +
 dojo/cldr/nls/indian.js                            |  428 +
 dojo/cldr/nls/islamic-civil.js                     |  280 +
 dojo/cldr/nls/islamic.js                           |  164 +-
 dojo/cldr/nls/it/buddhist.js                       |  230 +
 dojo/cldr/nls/it/chinese.js                        |   35 +
 dojo/cldr/nls/it/currency.js                       |    2 +
 dojo/cldr/nls/it/generic.js                        |   69 +
 dojo/cldr/nls/it/gregorian.js                      |   85 +-
 dojo/cldr/nls/it/hebrew.js                         |  140 +
 dojo/cldr/nls/it/islamic.js                        |  140 +
 dojo/cldr/nls/it/japanese.js                       |   35 +
 dojo/cldr/nls/it/number.js                         |   14 +-
 dojo/cldr/nls/it/roc.js                            |   35 +
 dojo/cldr/nls/ja/buddhist.js                       |  155 +
 dojo/cldr/nls/ja/chinese.js                        |  111 +
 dojo/cldr/nls/ja/coptic.js                         |  121 +
 dojo/cldr/nls/ja/currency.js                       |    5 +
 dojo/cldr/nls/ja/ethiopic.js                       |  121 +
 dojo/cldr/nls/ja/generic.js                        |   74 +
 dojo/cldr/nls/ja/gregorian.js                      |  103 +-
 dojo/cldr/nls/ja/hebrew.js                         |  225 +
 dojo/cldr/nls/ja/indian.js                         |  118 +
 dojo/cldr/nls/ja/islamic.js                        |  213 +
 dojo/cldr/nls/ja/japanese.js                       |  550 +
 dojo/cldr/nls/ja/number.js                         |   14 +-
 dojo/cldr/nls/ja/persian.js                        |  213 +
 dojo/cldr/nls/ja/roc.js                            |   35 +
 dojo/cldr/nls/japanese.js                          | 1149 +
 dojo/cldr/nls/ko/buddhist.js                       |  161 +
 dojo/cldr/nls/ko/chinese.js                        |   69 +
 dojo/cldr/nls/ko/currency.js                       |    1 +
 dojo/cldr/nls/ko/generic.js                        |   75 +
 dojo/cldr/nls/ko/gregorian.js                      |   71 +-
 dojo/cldr/nls/ko/hebrew.js                         |  127 +
 dojo/cldr/nls/ko/islamic.js                        |  127 +
 dojo/cldr/nls/ko/japanese.js                       |  269 +
 dojo/cldr/nls/ko/number.js                         |    8 +-
 dojo/cldr/nls/ko/roc.js                            |   35 +
 dojo/cldr/nls/nb/buddhist.js                       |  247 +
 dojo/cldr/nls/nb/currency.js                       |   12 +-
 dojo/cldr/nls/nb/generic.js                        |   71 +
 dojo/cldr/nls/nb/gregorian.js                      |  120 +-
 dojo/cldr/nls/nb/hebrew.js                         |  163 +
 dojo/cldr/nls/nb/islamic.js                        |  163 +
 dojo/cldr/nls/nb/japanese.js                       |   35 +
 dojo/cldr/nls/nb/number.js                         |    6 +-
 dojo/cldr/nls/nb/roc.js                            |   35 +
 dojo/cldr/nls/nl/buddhist.js                       |  237 +
 dojo/cldr/nls/nl/chinese.js                        |   66 +
 dojo/cldr/nls/nl/currency.js                       |    9 +-
 dojo/cldr/nls/nl/generic.js                        |   70 +
 dojo/cldr/nls/nl/gregorian.js                      |  121 +-
 dojo/cldr/nls/nl/hebrew.js                         |  211 +
 dojo/cldr/nls/nl/islamic.js                        |  229 +
 dojo/cldr/nls/nl/japanese.js                       |   35 +
 dojo/cldr/nls/nl/number.js                         |    6 +-
 dojo/cldr/nls/nl/roc.js                            |   35 +
 dojo/cldr/nls/number.js                            |   11 +-
 dojo/cldr/nls/persian.js                           |  292 +
 dojo/cldr/nls/pl/buddhist.js                       |  248 +
 dojo/cldr/nls/pl/chinese.js                        |   91 +
 dojo/cldr/nls/pl/coptic.js                         |   91 +
 dojo/cldr/nls/pl/currency.js                       |    3 +-
 dojo/cldr/nls/pl/ethiopic.js                       |   91 +
 dojo/cldr/nls/pl/generic.js                        |   72 +
 dojo/cldr/nls/pl/gregorian.js                      |   70 +-
 dojo/cldr/nls/pl/hebrew.js                         |  224 +
 dojo/cldr/nls/pl/indian.js                         |   87 +
 dojo/cldr/nls/pl/islamic.js                        |  231 +
 dojo/cldr/nls/pl/japanese.js                       |   35 +
 dojo/cldr/nls/pl/number.js                         |    8 +-
 dojo/cldr/nls/pl/persian.js                        |  245 +
 dojo/cldr/nls/pl/roc.js                            |   35 +
 dojo/cldr/nls/pt-pt/buddhist.js                    |  218 +
 dojo/cldr/nls/pt-pt/currency.js                    |    8 +
 dojo/cldr/nls/pt-pt/generic.js                     |   25 +
 dojo/cldr/nls/pt-pt/gregorian.js                   |  141 +-
 dojo/cldr/nls/pt-pt/hebrew.js                      |  134 +
 dojo/cldr/nls/pt-pt/islamic.js                     |  134 +
 dojo/cldr/nls/pt-pt/japanese.js                    |    8 +
 dojo/cldr/nls/pt-pt/number.js                      |    5 +-
 dojo/cldr/nls/pt-pt/roc.js                         |    8 +
 dojo/cldr/nls/pt/buddhist.js                       |  237 +
 dojo/cldr/nls/pt/chinese.js                        |   91 +
 dojo/cldr/nls/pt/coptic.js                         |   91 +
 dojo/cldr/nls/pt/currency.js                       |   10 +-
 dojo/cldr/nls/pt/ethiopic.js                       |   91 +
 dojo/cldr/nls/pt/generic.js                        |   68 +
 dojo/cldr/nls/pt/gregorian.js                      |  100 +-
 dojo/cldr/nls/pt/hebrew.js                         |  214 +
 dojo/cldr/nls/pt/indian.js                         |   87 +
 dojo/cldr/nls/pt/islamic.js                        |  153 +
 dojo/cldr/nls/pt/japanese.js                       |   35 +
 dojo/cldr/nls/pt/number.js                         |    6 +-
 dojo/cldr/nls/pt/persian.js                        |  234 +
 dojo/cldr/nls/pt/roc.js                            |   35 +
 dojo/cldr/nls/ro/buddhist.js                       |  213 +-
 dojo/cldr/nls/ro/chinese.js                        |   87 +
 dojo/cldr/nls/ro/coptic.js                         |   31 +
 dojo/cldr/nls/ro/currency.js                       |    1 +
 dojo/cldr/nls/ro/ethiopic.js                       |   31 +
 dojo/cldr/nls/ro/generic.js                        |   67 +
 dojo/cldr/nls/ro/gregorian.js                      |   74 +-
 dojo/cldr/nls/ro/hebrew.js                         |  217 +
 dojo/cldr/nls/ro/islamic.js                        |  154 +
 dojo/cldr/nls/ro/number.js                         |    8 +-
 dojo/cldr/nls/roc.js                               |  449 +
 dojo/cldr/nls/ru/buddhist.js                       |  254 +
 dojo/cldr/nls/ru/chinese.js                        |  122 +
 dojo/cldr/nls/ru/coptic.js                         |  106 +
 dojo/cldr/nls/ru/currency.js                       |    1 +
 dojo/cldr/nls/ru/ethiopic.js                       |  106 +
 dojo/cldr/nls/ru/generic.js                        |   70 +
 dojo/cldr/nls/ru/gregorian.js                      |  340 +-
 dojo/cldr/nls/ru/hebrew.js                         |  231 +
 dojo/cldr/nls/ru/indian.js                         |  101 +
 dojo/cldr/nls/ru/islamic.js                        |  237 +
 dojo/cldr/nls/ru/japanese.js                       |  269 +
 dojo/cldr/nls/ru/number.js                         |    7 +-
 dojo/cldr/nls/ru/persian.js                        |  251 +
 dojo/cldr/nls/ru/roc.js                            |   35 +
 dojo/cldr/nls/sk/currency.js                       |   15 +-
 dojo/cldr/nls/sk/generic.js                        |   67 +
 dojo/cldr/nls/sk/gregorian.js                      |  310 +-
 dojo/cldr/nls/sk/number.js                         |   17 +-
 dojo/cldr/nls/sl/generic.js                        |   65 +
 dojo/cldr/nls/sl/gregorian.js                      |  311 +-
 dojo/cldr/nls/sl/number.js                         |    8 +-
 dojo/cldr/nls/sv/buddhist.js                       |  242 +
 dojo/cldr/nls/sv/coptic.js                         |   91 +
 dojo/cldr/nls/sv/currency.js                       |   11 +-
 dojo/cldr/nls/sv/ethiopic.js                       |   91 +
 dojo/cldr/nls/sv/generic.js                        |   73 +
 dojo/cldr/nls/sv/gregorian.js                      |  155 +-
 dojo/cldr/nls/sv/hebrew.js                         |  221 +
 dojo/cldr/nls/sv/indian.js                         |   90 +
 dojo/cldr/nls/sv/islamic.js                        |  214 +
 dojo/cldr/nls/sv/japanese.js                       |  269 +
 dojo/cldr/nls/sv/number.js                         |    7 +-
 dojo/cldr/nls/sv/persian.js                        |  242 +
 dojo/cldr/nls/sv/roc.js                            |   35 +
 dojo/cldr/nls/th/buddhist.js                       |  267 +-
 dojo/cldr/nls/th/chinese.js                        |  119 +
 dojo/cldr/nls/th/coptic.js                         |  121 +
 dojo/cldr/nls/th/currency.js                       |    9 +-
 dojo/cldr/nls/th/ethiopic.js                       |  121 +
 dojo/cldr/nls/th/generic.js                        |   68 +
 dojo/cldr/nls/th/gregorian.js                      |  129 +-
 dojo/cldr/nls/th/hebrew.js                         |  230 +
 dojo/cldr/nls/th/indian.js                         |  118 +
 dojo/cldr/nls/th/islamic.js                        |  250 +
 dojo/cldr/nls/th/japanese.js                       |  306 +
 dojo/cldr/nls/th/number.js                         |    8 +-
 dojo/cldr/nls/th/persian.js                        |  250 +
 dojo/cldr/nls/th/roc.js                            |   67 +
 dojo/cldr/nls/tr/buddhist.js                       |  251 +
 dojo/cldr/nls/tr/coptic.js                         |   46 +
 dojo/cldr/nls/tr/currency.js                       |    8 +-
 dojo/cldr/nls/tr/ethiopic.js                       |   46 +
 dojo/cldr/nls/tr/generic.js                        |   73 +
 dojo/cldr/nls/tr/gregorian.js                      |   91 +-
 dojo/cldr/nls/tr/hebrew.js                         |  225 +
 dojo/cldr/nls/tr/islamic.js                        |  234 +
 dojo/cldr/nls/tr/japanese.js                       |   35 +
 dojo/cldr/nls/tr/number.js                         |   10 +-
 dojo/cldr/nls/tr/persian.js                        |  248 +
 dojo/cldr/nls/tr/roc.js                            |   35 +
 dojo/cldr/nls/zh-hant/buddhist.js                  |  241 +-
 dojo/cldr/nls/zh-hant/chinese.js                   |   85 +
 dojo/cldr/nls/zh-hant/coptic.js                    |  121 +
 dojo/cldr/nls/zh-hant/currency.js                  |    7 +
 dojo/cldr/nls/zh-hant/ethiopic.js                  |  121 +
 dojo/cldr/nls/zh-hant/generic.js                   |   68 +
 dojo/cldr/nls/zh-hant/gregorian.js                 |  137 +-
 dojo/cldr/nls/zh-hant/hebrew.js                    |  241 +
 dojo/cldr/nls/zh-hant/indian.js                    |  118 +
 dojo/cldr/nls/zh-hant/islamic.js                   |  276 +-
 dojo/cldr/nls/zh-hant/japanese.js                  |  302 +
 dojo/cldr/nls/zh-hant/number.js                    |   17 +-
 dojo/cldr/nls/zh-hant/persian.js                   |  261 +
 dojo/cldr/nls/zh-hant/roc.js                       |   35 +
 dojo/cldr/nls/zh-hk/currency.js                    |    4 +-
 dojo/cldr/nls/zh-hk/gregorian.js                   |  113 +-
 dojo/cldr/nls/zh-hk/number.js                      |    6 +-
 dojo/cldr/nls/zh-tw/currency.js                    |   11 +-
 dojo/cldr/nls/zh-tw/gregorian.js                   |   68 +-
 dojo/cldr/nls/zh-tw/number.js                      |   11 +
 dojo/cldr/nls/zh/buddhist.js                       |  231 +
 dojo/cldr/nls/zh/chinese.js                        |  141 +
 dojo/cldr/nls/zh/coptic.js                         |  121 +
 dojo/cldr/nls/zh/currency.js                       |    7 +
 dojo/cldr/nls/zh/ethiopic.js                       |  121 +
 dojo/cldr/nls/zh/generic.js                        |   69 +
 dojo/cldr/nls/zh/gregorian.js                      |  234 +-
 dojo/cldr/nls/zh/hebrew.js                         |  239 +
 dojo/cldr/nls/zh/indian.js                         |  118 +
 dojo/cldr/nls/zh/islamic.js                        |  259 +
 dojo/cldr/nls/zh/japanese.js                       |  306 +
 dojo/cldr/nls/zh/number.js                         |   16 +-
 dojo/cldr/nls/zh/persian.js                        |  259 +
 dojo/cldr/nls/zh/roc.js                            |   35 +
 dojo/cldr/supplemental.js                          |  132 +-
 dojo/colors.js                                     |   44 +-
 dojo/cookie.js                                     |   60 +-
 dojo/currency.js                                   |  130 +-
 dojo/data/ItemFileReadStore.js                     |  496 +-
 dojo/data/ItemFileWriteStore.js                    |  149 +-
 dojo/data/ObjectStore.js                           |  205 +-
 dojo/data/api/Identity.js                          |   68 +-
 dojo/data/api/Item.js                              |   13 +
 dojo/data/api/Notification.js                      |   90 +-
 dojo/data/api/Read.js                              |  169 +-
 dojo/data/api/Request.js                           |   23 +-
 dojo/data/api/Write.js                             |   71 +-
 dojo/data/util/filter.js                           |   35 +-
 dojo/data/util/simpleFetch.js                      |  259 +-
 dojo/data/util/sorter.js                           |   32 +-
 dojo/date.js                                       |   93 +-
 dojo/date/locale.js                                |  190 +-
 dojo/date/stamp.js                                 |   82 +-
 dojo/dnd/AutoSource.js                             |    7 +-
 dojo/dnd/Avatar.js                                 |   79 +-
 dojo/dnd/Container.js                              |  221 +-
 dojo/dnd/Manager.js                                |  103 +-
 dojo/dnd/Moveable.js                               |  136 +-
 dojo/dnd/Mover.js                                  |   77 +-
 dojo/dnd/Selector.js                               |  105 +-
 dojo/dnd/Source.js                                 |  127 +-
 dojo/dnd/Target.js                                 |   14 +-
 dojo/dnd/TimedMoveable.js                          |   23 +-
 dojo/dnd/autoscroll.js                             |  123 +-
 dojo/dnd/common.js                                 |   35 +-
 dojo/dnd/move.js                                   |   58 +-
 dojo/dojo.js                                       |  657 +-
 dojo/dojo.profile.js                               |   12 +-
 dojo/dom-attr.js                                   |  160 +-
 dojo/dom-class.js                                  |  316 +-
 dojo/dom-construct.js                              |  444 +-
 dojo/dom-form.js                                   |  137 +-
 dojo/dom-geometry.js                               |  656 +-
 dojo/dom-prop.js                                   |   74 +-
 dojo/dom-style.js                                  |  301 +-
 dojo/dom.js                                        |  215 +-
 dojo/domReady.js                                   |   63 +-
 dojo/errors/CancelError.js                         |   13 +
 dojo/errors/RequestError.js                        |   15 +
 dojo/errors/RequestTimeoutError.js                 |   15 +
 dojo/errors/create.js                              |   41 +
 dojo/fx.js                                         |  143 +-
 dojo/fx/Toggler.js                                 |   26 +-
 dojo/fx/easing.js                                  |   22 +-
 dojo/gears.js                                      |   32 +-
 dojo/has.js                                        |  105 +-
 dojo/hash.js                                       |  117 +-
 dojo/hccss.js                                      |   52 +
 dojo/html.js                                       |  188 +-
 dojo/i18n.js                                       |  638 +-
 dojo/io-query.js                                   |   29 +-
 dojo/io/iframe.js                                  |  440 +-
 dojo/io/script.js                                  |  280 +-
 dojo/jaxer.js                                      |   19 -
 dojo/json.js                                       |  123 +-
 dojo/keys.js                                       |  149 +-
 dojo/main.js                                       |   20 +-
 dojo/mouse.js                                      |  114 +-
 dojo/nls/ar/colors.js                              |  302 +-
 dojo/nls/az/colors.js                              |    4 +-
 dojo/nls/bg/colors.js                              |  156 +
 dojo/nls/ca/colors.js                              |  304 +-
 dojo/nls/colors.js                                 |    4 +-
 dojo/nls/cs/colors.js                              |  303 +-
 dojo/nls/da/colors.js                              |  303 +-
 dojo/nls/de/colors.js                              |  303 +-
 dojo/nls/el/colors.js                              |  303 +-
 dojo/nls/es/colors.js                              |  303 +-
 dojo/nls/fi/colors.js                              |  303 +-
 dojo/nls/fr/colors.js                              |  303 +-
 dojo/nls/he/colors.js                              |    6 +-
 dojo/nls/hr/colors.js                              |  298 +-
 dojo/nls/hu/colors.js                              |  303 +-
 dojo/nls/it/colors.js                              |  303 +-
 dojo/nls/ja/colors.js                              |  303 +-
 dojo/nls/kk/colors.js                              |  303 +-
 dojo/nls/ko/colors.js                              |  303 +-
 dojo/nls/nb/colors.js                              |  303 +-
 dojo/nls/nl/colors.js                              |  303 +-
 dojo/nls/pl/colors.js                              |  303 +-
 dojo/nls/pt-pt/colors.js                           |  302 +-
 dojo/nls/pt/colors.js                              |  303 +-
 dojo/nls/ro/colors.js                              |  304 +-
 dojo/nls/ru/colors.js                              |  303 +-
 dojo/nls/sk/colors.js                              |  304 +-
 dojo/nls/sl/colors.js                              |  301 +-
 dojo/nls/sv/colors.js                              |  303 +-
 dojo/nls/th/colors.js                              |  185 +-
 dojo/nls/tr/colors.js                              |  303 +-
 dojo/nls/uk/colors.js                              |  156 +
 dojo/nls/zh-tw/colors.js                           |  303 +-
 dojo/nls/zh/colors.js                              |  303 +-
 dojo/node.js                                       |   67 +
 dojo/number.js                                     |  223 +-
 dojo/on.js                                         |  287 +-
 dojo/package.json                                  |    2 +-
 dojo/parser.js                                     | 1160 +-
 dojo/promise/Promise.js                            |  133 +
 dojo/promise/all.js                                |   76 +
 dojo/promise/first.js                              |   49 +
 dojo/promise/instrumentation.js                    |  105 +
 dojo/promise/tracer.js                             |   85 +
 dojo/query.js                                      |  420 +-
 dojo/ready.js                                      |  115 +-
 dojo/regexp.js                                     |   33 +-
 dojo/request.js                                    |   81 +
 dojo/request/default.js                            |   32 +
 dojo/request/handlers.js                           |   74 +
 dojo/request/iframe.js                             |  431 +
 dojo/request/node.js                               |  195 +
 dojo/request/notify.js                             |   74 +
 dojo/request/registry.js                           |   85 +
 dojo/request/script.js                             |  219 +
 dojo/request/util.js                               |  158 +
 dojo/request/watch.js                              |  109 +
 dojo/request/xhr.js                                |  316 +
 dojo/resources/_modules.js                         |   36 -
 dojo/resources/dnd.css                             |    6 +-
 dojo/robot.js                                      |  202 +-
 dojo/robotx.js                                     |  256 +-
 dojo/router.js                                     |   28 +
 dojo/router/RouterBase.js                          |  376 +
 dojo/rpc/JsonService.js                            |   56 +-
 dojo/rpc/JsonpService.js                           |   57 +-
 dojo/rpc/RpcService.js                             |   77 +-
 dojo/selector/_loader.js                           |    6 +-
 dojo/selector/acme.js                              |  332 +-
 dojo/selector/lite.js                              |  105 +-
 dojo/sniff.js                                      |   80 +
 dojo/store/Cache.js                                |  108 +-
 dojo/store/DataStore.js                            |   64 +-
 dojo/store/JsonRest.js                             |  125 +-
 dojo/store/Memory.js                               |   77 +-
 dojo/store/Observable.js                           |   62 +-
 dojo/store/README                                  |   14 +-
 dojo/store/api/Store.js                            |   72 +-
 dojo/store/util/QueryResults.js                    |   33 +-
 dojo/store/util/SimpleQueryEngine.js               |   34 +-
 dojo/string.js                                     |   76 +-
 dojo/tests.js                                      |    3 +-
 dojo/tests/AdapterRegistry.js                      |   14 +-
 dojo/tests/Deferred.js                             |  477 +
 dojo/tests/DeferredList.js                         |    2 +-
 dojo/tests/NodeList-data.html                      |   59 +-
 dojo/tests/NodeList-data.js                        |    2 +-
 dojo/tests/NodeList-fx.html                        |   79 +-
 dojo/tests/NodeList-manipulate.html                |  148 +-
 dojo/tests/NodeList-manipulate.js                  |    2 +-
 dojo/tests/NodeList-traverse.html                  |   35 +-
 dojo/tests/NodeList-traverse.js                    |    2 +-
 dojo/tests/Stateful.js                             |  184 +-
 dojo/tests/_base.js                                |    7 +-
 dojo/tests/_base/Color.js                          |   17 +-
 dojo/tests/_base/Deferred.js                       |   24 +-
 dojo/tests/_base/NodeList.html                     |    5 +-
 dojo/tests/_base/abs.html                          |    2 +-
 dojo/tests/_base/absQuirk.html                     |    2 +-
 dojo/tests/_base/array.js                          |  113 +-
 dojo/tests/_base/connect.js                        |   14 +-
 dojo/tests/_base/connectKey.html                   |   27 +
 dojo/tests/_base/declare.js                        |  143 +-
 dojo/tests/_base/fx.html                           |  123 +-
 dojo/tests/_base/fx.js                             |    2 +-
 dojo/tests/_base/fx_delay.html                     |   12 +-
 dojo/tests/_base/html.html                         |  123 +-
 dojo/tests/_base/html.js                           |    7 +-
 dojo/tests/_base/html_quirks.html                  |   67 +-
 dojo/tests/_base/html_rtl.html                     |   58 +-
 dojo/tests/_base/i18nExhaustive.js                 |  107 +
 dojo/tests/_base/json.js                           |    2 +-
 dojo/tests/_base/lang.js                           |  114 +-
 dojo/tests/_base/loader.js                         |   47 +-
 dojo/tests/_base/loader/14808.html                 |   24 +
 dojo/tests/_base/loader/14808/App.js               |   10 +
 dojo/tests/_base/loader/14808/Module.js            |    9 +
 dojo/tests/_base/loader/boot-sniffConfig.html      |   33 +
 dojo/tests/_base/loader/boot-userConfig.html       |   23 +
 dojo/tests/_base/loader/bootstrap.js               |    4 +-
 dojo/tests/_base/loader/config/pkg/m1.js           |   20 +
 dojo/tests/_base/loader/config/pkg/m2.js           |    4 +
 dojo/tests/_base/loader/config/someModule.js       |   11 +
 .../config/someModuleConfiggedPriorToBoot.js       |    5 +
 dojo/tests/_base/loader/config/test.html           |  122 +
 dojo/tests/_base/loader/configApi.html             |    3 +-
 dojo/tests/_base/loader/coolio/coolio-built.html   |   16 +-
 ....html => coolio-dev-async-with-packageMap.html} |    0
 .../_base/loader/coolio/coolio-dev-async.html      |   15 +-
 .../coolio-dev-legacy-async-with-packageMap.html   |   83 +
 .../loader/coolio/coolio-dev-legacy-async.html     |   15 +-
 dojo/tests/_base/loader/coolio/coolio.js           |   17 -
 dojo/tests/_base/loader/coolio/coolio.profile.js   |   84 +-
 dojo/tests/_base/loader/coolio/test.html           |   15 +-
 dojo/tests/_base/loader/getText.txt                |    2 +-
 .../legacyModule.js                                |   60 +
 .../nls/ab-cd-ef/legacyBundle.js                   |    1 +
 .../nls/ab/legacyBundle.js                         |    1 +
 .../nls/legacyBundle.js                            |    1 +
 .../nls/legacyModule_ROOT.js                       |    1 +
 .../nls/legacyModule_ab-cd-ef.js                   |    1 +
 .../nls/legacyModule_ab-cd.js                      |    1 +
 .../nls/legacyModule_ab.js                         |    1 +
 .../nls/legacyModule_xx.js                         |    1 +
 .../152-build-with-layers/legacyModule.js          |   60 +
 .../nls/ab-cd-ef/legacyBundle.js                   |    1 +
 .../152-build-with-layers/nls/ab/legacyBundle.js   |    1 +
 .../152-build-with-layers/nls/legacyBundle.js      |    1 +
 .../152-build-with-layers/nls/legacyModule_ROOT.js |    1 +
 .../nls/legacyModule_en-us.js                      |    1 +
 .../152-build-with-layers/nls/legacyModule_en.js   |    1 +
 .../built-i18n-test/152-build/legacyModule.js      |   50 +
 .../152-build/nls/ab-cd-ef/legacyBundle.js         |    1 +
 .../152-build/nls/ab/legacyBundle.js               |    1 +
 .../built-i18n-test/152-build/nls/legacyBundle.js  |    1 +
 .../loader/i18n-exhaustive/i18n-test/amdModule.js  |   41 +
 .../i18n-test/build-test-targets.sh                |    7 +
 .../i18n-test-with-layers-and-preloads.profile.js  |   37 +
 .../i18n-test/i18n-test-with-layers.profile.js     |   35 +
 .../i18n-exhaustive/i18n-test/i18n-test.profile.js |   30 +
 .../i18n-exhaustive/i18n-test/legacyModule.js      |   75 +
 .../i18n-test/nls/ab-cd-ef/amdBundle.js            |    4 +
 .../i18n-test/nls/ab-cd-ef/legacyBundle.js         |    4 +
 .../i18n-exhaustive/i18n-test/nls/ab/amdBundle.js  |    4 +
 .../i18n-test/nls/ab/legacyBundle.js               |    4 +
 .../i18n-exhaustive/i18n-test/nls/amdBundle.js     |    8 +
 .../i18n-exhaustive/i18n-test/nls/legacyBundle.js  |    4 +
 .../loader/i18n-exhaustive/i18n-test/unit.html     |   94 +
 .../loader/i18n-exhaustive/test-instructions.md    |   64 +
 dojo/tests/_base/loader/moduleIds.js               |    6 +-
 dojo/tests/_base/loader/modules.js                 |   23 +-
 dojo/tests/_base/loader/modules/anon.js            |    2 +-
 dojo/tests/_base/loader/modules/factoryArity.js    |   10 +-
 .../_base/loader/modules/factoryArityExports.js    |    8 +
 dojo/tests/_base/loader/modules/full.js            |    2 +-
 dojo/tests/_base/loader/modules/idFactoryArity.js  |    8 +
 .../_base/loader/modules/idFactoryArityExports.js  |    8 +
 dojo/tests/_base/loader/modules/impliedDep1.js     |    3 +
 dojo/tests/_base/loader/modules/impliedDep2.js     |    3 +
 dojo/tests/_base/loader/modules/impliedDep3.js     |    3 +
 dojo/tests/_base/loader/modules/impliedDep4.js     |    3 +
 dojo/tests/_base/loader/modules/wrapped.js         |    4 +-
 dojo/tests/_base/loader/onerror.html               |  151 +
 dojo/tests/_base/loader/require/m1.js              |   13 +
 dojo/tests/_base/loader/require/m2.js              |    5 +
 .../_base/loader/require/test-require-plugin.html  |   33 +
 dojo/tests/_base/loader/requirejs/bar              |    2 +-
 .../tests/_base/loader/requirejs/circular-tests.js |    6 +-
 dojo/tests/_base/loader/requirejs/dataMain.js      |    2 +-
 dojo/tests/_base/loader/requirejs/depoverlap.js    |   13 +-
 dojo/tests/_base/loader/requirejs/dos.js           |    4 +-
 .../tests/_base/loader/requirejs/exports/assign.js |    2 +-
 .../_base/loader/requirejs/exports/assign2.js      |    2 +-
 .../loader/requirejs/exports/exports-tests.js      |    2 +-
 .../_base/loader/requirejs/exports/funcSet.js      |    2 +-
 .../loader/requirejs/exports/implicitModule.js     |    6 +-
 .../_base/loader/requirejs/exports/simpleReturn.js |    4 +-
 .../_base/loader/requirejs/exports/usethis.js      |    2 +-
 .../_base/loader/requirejs/exports/vanilla.js      |    2 +-
 dojo/tests/_base/loader/requirejs/foo              |    2 +-
 dojo/tests/_base/loader/requirejs/func.js          |    6 +-
 dojo/tests/_base/loader/requirejs/funcFour.js      |    6 +-
 dojo/tests/_base/loader/requirejs/funcOne.js       |    6 +-
 dojo/tests/_base/loader/requirejs/funcThree.js     |    6 +-
 dojo/tests/_base/loader/requirejs/funcTwo.js       |    6 +-
 dojo/tests/_base/loader/requirejs/i18n/commonA.js  |    2 +-
 dojo/tests/_base/loader/requirejs/i18n/commonB.js  |    2 +-
 .../_base/loader/requirejs/i18n/testModule.js      |    2 +-
 .../_base/loader/requirejs/layers/helloWorld.txt   |    2 +-
 dojo/tests/_base/loader/requirejs/layers/layer1.js |    6 +-
 dojo/tests/_base/loader/requirejs/map.js           |    2 +-
 dojo/tests/_base/loader/requirejs/one.js           |    4 +-
 .../_base/loader/requirejs/paths/first.js/first.js |    2 +-
 .../loader/requirejs/paths/first.js/second.js      |    4 +-
 .../loader/requirejs/relative/foo/bar/message.txt  |    2 +-
 .../_base/loader/requirejs/relative/foo/bar/one.js |    2 +-
 .../loader/requirejs/relative/relative-tests.js    |   40 +-
 dojo/tests/_base/loader/requirejs/simple-tests.js  |    4 +-
 dojo/tests/_base/loader/requirejs/simple.js        |    2 +-
 dojo/tests/_base/loader/requirejs/text/local.js    |    4 +-
 .../loader/requirejs/text/resources/local.html     |    2 +-
 .../tests/_base/loader/requirejs/text/subwidget.js |    2 +-
 .../_base/loader/requirejs/text/subwidget2.html    |    2 +-
 dojo/tests/_base/loader/requirejs/text/text.html   |    2 +-
 dojo/tests/_base/loader/requirejs/text/widget.html |    2 +-
 dojo/tests/_base/loader/requirejs/text/widget.js   |    2 +-
 dojo/tests/_base/loader/requirejs/tres.js          |    2 +-
 dojo/tests/_base/loader/requirejs/two.js           |    4 +-
 dojo/tests/_base/loader/requirejs/uniques/one.js   |    2 +-
 dojo/tests/_base/loader/requirejs/uniques/two.js   |    2 +-
 dojo/tests/_base/loader/requirejs/uno.js           |    4 +-
 .../tests/_base/loader/requirejs/urlfetch/three.js |    2 +-
 dojo/tests/_base/loader/requirejs/urlfetch/two.js  |    2 +-
 dojo/tests/_base/loader/stripStrict.html           |   23 +
 dojo/tests/_base/loader/xdomain/xdomain.html       |    4 +-
 dojo/tests/_base/object.js                         |   22 +-
 dojo/tests/_base/query.html                        |  145 +-
 dojo/tests/_base/query.js                          |    4 +-
 dojo/tests/_base/scrollingIframe.js                |    2 +-
 dojo/tests/_base/sniff.html                        |   36 +
 dojo/tests/_base/window.html                       |   52 +-
 dojo/tests/_base/window.js                         |    2 +-
 dojo/tests/_base/xhr.html                          |   24 +
 dojo/tests/_base/xhr.js                            |    2 +-
 dojo/tests/aspect.js                               |  112 +-
 dojo/tests/back-hash.js                            |   11 +-
 dojo/tests/back.html                               |   92 +-
 dojo/tests/back.js                                 |    2 +-
 dojo/tests/behavior.js                             |    2 +-
 dojo/tests/cache.js                                |    2 +-
 dojo/tests/cldr.js                                 |   10 +-
 dojo/tests/colors.js                               |   12 +-
 dojo/tests/cookie.html                             |   33 +-
 dojo/tests/cookie.js                               |    2 +-
 dojo/tests/currency.js                             |   63 +-
 dojo/tests/data.js                                 |    4 +-
 dojo/tests/data/ItemFileReadStore.js               |    2 +-
 dojo/tests/data/ItemFileWriteStore.js              |  214 +-
 dojo/tests/data/ObjectStore.js                     |   18 +
 dojo/tests/data/readOnlyItemFileTestTemplates.js   |  364 +-
 dojo/tests/data/runTests.html                      |    2 +-
 dojo/tests/data/utils.js                           |    2 +-
 dojo/tests/date.js                                 |  390 +-
 dojo/tests/date/locale.js                          |  262 +-
 dojo/tests/date/stamp.js                           |   44 +-
 dojo/tests/dnd/dndDefault.css                      |    4 +
 dojo/tests/dnd/flickr_viewer.html                  |  165 +-
 dojo/tests/dnd/robot/test_dnd.html                 |   73 +-
 dojo/tests/dnd/test_autoscroll.html                |  195 +
 dojo/tests/dnd/test_box_constraints.html           |   38 +-
 dojo/tests/dnd/test_container.html                 |   24 +-
 dojo/tests/dnd/test_container_markup.html          |   21 +-
 dojo/tests/dnd/test_custom_constraints.html        |   25 +-
 dojo/tests/dnd/test_dnd.html                       |  189 +-
 dojo/tests/dnd/test_dnd_handles.html               |   19 +-
 dojo/tests/dnd/test_form.html                      |   21 +-
 dojo/tests/dnd/test_moveable.html                  |   35 +-
 dojo/tests/dnd/test_moveable_markup.html           |   19 +-
 dojo/tests/dnd/test_params.html                    |   18 +-
 dojo/tests/dnd/test_parent_constraints.html        |   22 +-
 .../tests/dnd/test_parent_constraints_margins.html |   18 +-
 dojo/tests/dnd/test_selector.html                  |   26 +-
 dojo/tests/dnd/test_selector_markup.html           |   21 +-
 dojo/tests/dnd/test_timed_moveable.html            |   36 +-
 dojo/tests/dom-style.html                          |   43 +
 dojo/tests/dom-style.js                            |    5 +
 dojo/tests/errors.js                               |   47 +
 dojo/tests/fx.html                                 |  217 +-
 dojo/tests/fx.js                                   |    2 +-
 dojo/tests/hash.js                                 |   59 +-
 dojo/tests/html.js                                 |    2 +-
 dojo/tests/html/test_set.html                      |  260 +-
 dojo/tests/i18n.html                               |   19 +-
 dojo/tests/i18n.js                                 |   14 +-
 dojo/tests/io/iframe.html                          |  139 +-
 dojo/tests/io/iframe.js                            |    2 +-
 dojo/tests/io/script.js                            |    2 +-
 dojo/tests/io/scriptJsonp.js                       |    2 +-
 dojo/tests/json.js                                 |   93 +-
 dojo/tests/module.js                               |    9 +
 dojo/tests/mouse.js                                |   53 +
 dojo/tests/node.js                                 |   55 +
 dojo/tests/number.js                               |  433 +-
 dojo/tests/on.js                                   |  232 +-
 dojo/tests/on/bench.html                           |   98 +
 dojo/tests/on/connectKey.html                      |   33 +
 dojo/tests/on/on.js                                |  289 +
 dojo/tests/parser.html                             |  789 -
 dojo/tests/parser.js                               |    8 +-
 dojo/tests/parser/bench.html                       |  311 +
 dojo/tests/parser/parseOnLoadAutoRequire.html      |   43 +
 .../parser/parseOnLoadDeclarativeRequire.html      |   62 +
 dojo/tests/parser/parser-args.html                 |   58 +
 dojo/tests/parser/parser.html                      | 1164 +
 dojo/tests/parser/parserAsync.html                 |   85 +
 dojo/tests/parser/runTests.html                    |   10 +
 dojo/tests/promise.js                              |    8 +
 dojo/tests/promise/Promise.js                      |   60 +
 dojo/tests/promise/all.js                          |  104 +
 dojo/tests/promise/first.js                        |  100 +
 dojo/tests/promise/tracer.js                       |  106 +
 dojo/tests/query.js                                |   27 +
 dojo/tests/query/query.html                        |  474 +
 dojo/tests/query/queryQuirks.html                  |  456 +
 dojo/tests/query/runTests.html                     |    9 +
 dojo/tests/query/xml.xhtml                         |   19 +
 dojo/tests/regexp.js                               |    6 +-
 dojo/tests/request.js                              |   14 +
 dojo/tests/request/handlers.js                     |   87 +
 dojo/tests/request/iframe.html                     |  205 +
 dojo/tests/request/iframeDummyMethod.php           |  109 +
 dojo/tests/request/node.js                         |   78 +
 dojo/tests/request/notify.html                     |  191 +
 dojo/tests/request/registry.html                   |  101 +
 dojo/tests/request/script.html                     |   92 +
 dojo/tests/request/scriptDummyMethod.php           |   21 +
 dojo/tests/request/xhr.html                        |  320 +
 dojo/tests/request/xhrDummyMethod.php              |   72 +
 dojo/tests/request/xhrEchoContentTypeHeader.php    |   12 +
 dojo/tests/request/xhrXml.php                      |    9 +
 dojo/tests/resources/AMDMixin.js                   |   10 +
 dojo/tests/resources/AMDWidget.js                  |    9 +
 dojo/tests/resources/AMDWidget2.js                 |   14 +
 dojo/tests/resources/AMDWidget3.js                 |    9 +
 dojo/tests/resources/amdmodule.js                  |    8 +
 dojo/tests/resources/nodeamd.js                    |   26 +
 dojo/tests/resources/nodemod/m.js                  |    7 +
 dojo/tests/resources/nodemod/package.json          |    4 +
 dojo/tests/resources/nodemodule.js                 |    7 +
 dojo/tests/resources/noderequire.js                |    5 +
 dojo/tests/resources/noderequireamd.js             |    7 +
 dojo/tests/router.js                               |  379 +
 dojo/tests/rpc.js                                  |   25 +-
 dojo/tests/smoke-dojo-sie.html                     |   11 -
 dojo/tests/sniff.html                              |   35 +
 dojo/tests/store/Cache.js                          |   29 +-
 dojo/tests/store/DataStore.js                      |   23 +-
 dojo/tests/store/JsonRest.js                       |   68 +-
 dojo/tests/store/Memory.js                         |   37 +-
 dojo/tests/store/Observable.js                     |   71 +-
 dojo/tests/store/index.php                         |   23 +
 dojo/tests/string.js                               |   38 +-
 dojo/tests/test_dom_setSelectable.html             |   74 +
 dojo/tests/test_fx.html                            |   26 +-
 dojo/tests/test_touch.html                         |  158 +-
 dojo/tests/touch.js                                |    2 +-
 dojo/tests/uacss.js                                |    5 +-
 dojo/tests/uacss/sniffQuirks.html                  |   22 +-
 dojo/tests/uacss/sniffStandards.html               |   22 +-
 dojo/tests/when.js                                 |  101 +
 dojo/tests/window.js                               |    5 +-
 dojo/tests/window/test_scroll.html                 | 1006 +-
 dojo/tests/window/test_scrollNoDTD.html            |   18 +-
 dojo/tests/window/test_scrollStrictDTD.html        |   18 +-
 dojo/tests/window/viewport.html                    |   20 +-
 dojo/text.js                                       |  259 +-
 dojo/topic.js                                      |   29 +-
 dojo/touch.js                                      |  358 +-
 dojo/uacss.js                                      |   53 +-
 dojo/when.js                                       |   55 +
 dojo/window.js                                     |  382 +-
 dojox/.gitmodules                                  |    9 +
 dojox/LICENSE                                      |    2 +-
 dojox/NodeList/delegate.js                         |   23 +-
 dojox/NodeList/tests/delegate.html                 |    2 +-
 dojox/analytics.js                                 |    7 +
 dojox/analytics/README                             |   74 +-
 dojox/analytics/Urchin.js                          |   37 +-
 dojox/analytics/_base.js                           |   87 +-
 dojox/analytics/logger/dojoxAnalytics.php          |    2 +-
 dojox/analytics/plugins/consoleMessages.js         |   20 +-
 dojox/analytics/plugins/dojo.js                    |   14 +-
 dojox/analytics/plugins/gestureEvents.js           |   95 +
 dojox/analytics/plugins/idle.js                    |   27 +-
 dojox/analytics/plugins/mouseClick.js              |   39 +-
 dojox/analytics/plugins/mouseOver.js               |   56 +-
 dojox/analytics/plugins/touchMove.js               |  109 +
 dojox/analytics/plugins/touchPress.js              |   91 +
 dojox/analytics/plugins/window.js                  |   15 +-
 dojox/analytics/profiles/analytics.profile.js      |   32 +-
 .../analytics/profiles/analyticsInBase.profile.js  |   18 +-
 dojox/analytics/tests/test_GoogleAnalytics.html    |  113 +-
 .../tests/test_GoogleAnalyticsMarkup.html          |   86 +-
 dojox/analytics/tests/test_analytics-async.html    |  189 +-
 .../tests/test_analytics-gestureEvents.html        |  161 +
 .../test_analytics-touchAndGestureEvents.html      |  167 +
 .../tests/test_analytics-touchEvents.html          |  165 +
 dojox/analytics/tests/test_analytics.html          |  159 +-
 dojox/app/CONTRIBUTING.md                          |    3 +
 dojox/app/Controller.js                            |   75 +
 dojox/app/LICENSE                                  |  195 +
 dojox/app/README.txt                               |  219 +-
 dojox/app/View.js                                  |  149 +
 dojox/app/ViewBase.js                              |  258 +
 dojox/app/animation.js                             |  346 -
 dojox/app/bind.js                                  |   39 -
 dojox/app/build/buildControlApp.js                 |    9 +
 dojox/app/build/discoverAppConfig.js               |  120 +
 dojox/app/controllers/BorderLayout.js              |   88 +
 dojox/app/controllers/History.js                   |  127 +
 dojox/app/controllers/HistoryHash.js               |  291 +
 dojox/app/controllers/Layout.js                    |  192 +
 dojox/app/controllers/LayoutBase.js                |  130 +
 dojox/app/controllers/Load.js                      |  278 +
 dojox/app/controllers/Transition.js                |  430 +
 dojox/app/main.js                                  |  441 +-
 dojox/app/model.js                                 |   26 -
 dojox/app/module/history.js                        |   90 -
 dojox/app/module/lifecycle.js                      |   50 +-
 dojox/app/scene.js                                 |  588 -
 dojox/app/schema/application.json                  |    6 +-
 dojox/app/schema/model.json                        |    2 +-
 dojox/app/schema/scene.json                        |    3 +-
 dojox/app/schema/store.json                        |    2 +-
 dojox/app/tests/borderLayoutApp/borderlayoutApp.js |   45 +
 dojox/app/tests/borderLayoutApp/config.json        |  148 +
 dojox/app/tests/borderLayoutApp/css/layoutApp.css  |  117 +
 dojox/app/tests/borderLayoutApp/index.html         |   24 +
 dojox/app/tests/borderLayoutApp/index2.html        |   24 +
 dojox/app/tests/borderLayoutApp/layoutApp.js       |   47 +
 .../borderLayoutApp/templates/itemDetails.html     |   37 +
 .../app/tests/borderLayoutApp/templates/list.html  |   11 +
 .../app/tests/borderLayoutApp/templates/view1.html |    3 +
 .../tests/borderLayoutApp/templates/view10.html    |    3 +
 .../app/tests/borderLayoutApp/templates/view2.html |    3 +
 .../app/tests/borderLayoutApp/templates/view3.html |   20 +
 .../app/tests/borderLayoutApp/templates/view4.html |   47 +
 .../app/tests/borderLayoutApp/templates/view5.html |   15 +
 .../app/tests/borderLayoutApp/templates/view6.html |   14 +
 .../app/tests/borderLayoutApp/templates/view7.html |    5 +
 .../app/tests/borderLayoutApp/templates/view8.html |    5 +
 .../app/tests/borderLayoutApp/templates/view9.html |    3 +
 .../borderLayoutApp/test_BorderContainer_full.html |   65 +
 .../test_BorderContainer_full2.html                |  121 +
 .../app/tests/borderLayoutApp/views/itemDetails.js |   48 +
 dojox/app/tests/borderLayoutApp/views/list.js      |   76 +
 dojox/app/tests/borderLayoutApp/views/view1.js     |   24 +
 dojox/app/tests/borderLayoutApp/views/view5.js     |   24 +
 dojox/app/tests/customApp/DtlView.js               |    7 +
 dojox/app/tests/customApp/WidgetView.js            |   13 +
 dojox/app/tests/customApp/WidgetView2.js           |   14 +
 dojox/app/tests/customApp/config.json              |   61 +
 dojox/app/tests/customApp/customApp.js             |    7 +
 dojox/app/tests/customApp/dtl.html                 |    1 +
 dojox/app/tests/customApp/dtl.js                   |    6 +
 dojox/app/tests/customApp/home.html                |    7 +
 dojox/app/tests/customApp/index.html               |   34 +
 dojox/app/tests/customApp/widget.js                |    5 +
 dojox/app/tests/doh/borderLayoutApp/config.json    |  148 +
 dojox/app/tests/doh/borderLayoutApp/index.html     |  164 +
 dojox/app/tests/doh/config.html                    |    3 +
 dojox/app/tests/doh/error.js                       |  163 +
 dojox/app/tests/doh/error1.json                    |   29 +
 dojox/app/tests/doh/error2.json                    |   29 +
 dojox/app/tests/doh/error3.html                    |    4 +
 dojox/app/tests/doh/error3.json                    |   28 +
 dojox/app/tests/doh/error4.json                    |   28 +
 dojox/app/tests/doh/error5.json                    |   29 +
 dojox/app/tests/doh/errorDef1.js                   |    7 +
 dojox/app/tests/doh/errorDef2.js                   |    7 +
 dojox/app/tests/doh/errorDojoDef.js                |    5 +
 dojox/app/tests/doh/errorLast.json                 |   29 +
 dojox/app/tests/doh/globalizedApp/config.json      |   56 +
 dojox/app/tests/doh/globalizedApp/index.html       |  161 +
 dojox/app/tests/doh/hasConfigTest/config.json      |   72 +
 dojox/app/tests/doh/hasConfigTest/index.html       |  101 +
 dojox/app/tests/doh/hasConfigTest/modelApp.js      |   15 +
 dojox/app/tests/doh/helpers.js                     |   73 +
 dojox/app/tests/doh/layoutApp/config.json          |  135 +
 dojox/app/tests/doh/layoutApp/index.html           |  146 +
 dojox/app/tests/doh/lifecycleTest/config.json      |   31 +
 dojox/app/tests/doh/lifecycleTest/index.html       |   78 +
 dojox/app/tests/doh/lifecycleTest/modelApp.js      |    4 +
 .../app/tests/doh/mediaQuery3ColumnApp/config.json |  124 +
 .../app/tests/doh/mediaQuery3ColumnApp/index.html  |  127 +
 dojox/app/tests/doh/module.js                      |   18 +
 dojox/app/tests/doh/runErrorsTests.html            |   10 +
 dojox/app/tests/doh/runTests.html                  |    9 +
 dojox/app/tests/doh/simpleModelApp/config.json     |  233 +
 dojox/app/tests/doh/simpleModelApp/index.html      |  273 +
 .../resources/data/jsonRestRepeatData.json         |  102 +
 .../doh/simpleModelApp/resources/data/names2.json  |   11 +
 .../doh/simpleModelApp/resources/data/repeat.json  |  105 +
 dojox/app/tests/globalizedApp/build.profile.js     |   31 +
 dojox/app/tests/globalizedApp/config.json          |   56 +
 dojox/app/tests/globalizedApp/detail.html          |    3 +
 dojox/app/tests/globalizedApp/detail.js            |    8 +
 dojox/app/tests/globalizedApp/globalizedApp.js     |    6 +
 .../tests/globalizedApp/globalizedApp.profile.js   |   13 +
 dojox/app/tests/globalizedApp/home.html            |   11 +
 dojox/app/tests/globalizedApp/index.html           |   27 +
 dojox/app/tests/globalizedApp/nls/app.js           |    7 +
 dojox/app/tests/globalizedApp/nls/fr/app.js        |    4 +
 dojox/app/tests/globalizedApp/nls/fr/home.js       |    4 +
 dojox/app/tests/globalizedApp/nls/home.js          |    7 +
 dojox/app/tests/globalizedApp/package.json         |    4 +
 dojox/app/tests/layoutApp/build.profile.js         |   32 +
 dojox/app/tests/layoutApp/config.json              |  135 +
 dojox/app/tests/layoutApp/css/layoutApp.css        |  118 +
 dojox/app/tests/layoutApp/index.html               |   23 +
 dojox/app/tests/layoutApp/layoutApp.js             |   68 +
 dojox/app/tests/layoutApp/layoutApp.profile.js     |   13 +
 dojox/app/tests/layoutApp/package.json             |    4 +
 dojox/app/tests/layoutApp/views/date.html          |   24 +
 dojox/app/tests/layoutApp/views/date.js            |   43 +
 dojox/app/tests/layoutApp/views/itemDetails.html   |   37 +
 dojox/app/tests/layoutApp/views/itemDetails.js     |   48 +
 dojox/app/tests/layoutApp/views/list.html          |   11 +
 dojox/app/tests/layoutApp/views/list.js            |   76 +
 dojox/app/tests/layoutApp/views/navigation.html    |   14 +
 dojox/app/tests/layoutApp/views/simple.html        |  101 +
 dojox/app/tests/layoutApp/views/simple.js          |   62 +
 dojox/app/tests/layoutApp2/config.json             |  134 +
 .../layoutApp2/controllers/UnloadViewController.js |   94 +
 dojox/app/tests/layoutApp2/css/layoutApp.css       |  118 +
 dojox/app/tests/layoutApp2/index.html              |   23 +
 dojox/app/tests/layoutApp2/layoutApp.js            |   68 +
 dojox/app/tests/layoutApp2/views/date.html         |   26 +
 dojox/app/tests/layoutApp2/views/date.js           |   65 +
 dojox/app/tests/layoutApp2/views/itemDetails.html  |   37 +
 dojox/app/tests/layoutApp2/views/itemDetails.js    |   48 +
 dojox/app/tests/layoutApp2/views/list.html         |   32 +
 dojox/app/tests/layoutApp2/views/list.js           |   79 +
 dojox/app/tests/layoutApp2/views/navigation.html   |   17 +
 dojox/app/tests/layoutApp2/views/simple.html       |  101 +
 dojox/app/tests/layoutApp2/views/simple.js         |   62 +
 dojox/app/tests/longListTestApp/config.json        |  127 +
 dojox/app/tests/longListTestApp/css/demo.css       |   12 +
 dojox/app/tests/longListTestApp/css/tablet.css     |   81 +
 dojox/app/tests/longListTestApp/index.html         |   43 +
 dojox/app/tests/longListTestApp/longListTestApp.js |   30 +
 .../longListTestApp/resources/data/repeat.json     |  105 +
 dojox/app/tests/longListTestApp/src.js             |   21 +
 .../tests/longListTestApp/themes/android/todo.css  |   25 +
 .../longListTestApp/themes/blackberry/todo.css     |   21 +
 .../tests/longListTestApp/themes/iphone/todo.css   |   31 +
 dojox/app/tests/longListTestApp/views/Footer1.html |    9 +
 dojox/app/tests/longListTestApp/views/Footer1.js   |   18 +
 dojox/app/tests/longListTestApp/views/Header1.html |    7 +
 dojox/app/tests/longListTestApp/views/Header1.js   |   67 +
 .../app/tests/longListTestApp/views/LongList1.html |   11 +
 dojox/app/tests/longListTestApp/views/LongList1.js |   40 +
 .../app/tests/longListTestApp/views/LongList2.html |   21 +
 dojox/app/tests/longListTestApp/views/LongList2.js |   68 +
 .../app/tests/longListTestApp/views/LongList3.html |   15 +
 dojox/app/tests/longListTestApp/views/LongList3.js |   42 +
 .../app/tests/longListTestApp/views/LongList4.html |   22 +
 dojox/app/tests/longListTestApp/views/LongList4.js |   68 +
 .../app/tests/longListTestApp/views/TestInfo.html  |   25 +
 dojox/app/tests/longListTestApp/views/TestInfo.js  |   37 +
 .../configuration/ScrollableListSelection.html     |   49 +
 .../views/configuration/ScrollableListSelection.js |   23 +
 .../views/tablet/ViewScrollableLists.html          |   57 +
 .../views/tablet/ViewScrollableLists.js            |   26 +
 dojox/app/tests/mediaQuery3ColumnApp/config.json   |  124 +
 .../mediaQuery3ColumnApp/controllers/CssLayout.js  |   61 +
 .../controllers/NavigationController.js            |  213 +
 .../css/mediaQuery3ColumnApp.css                   |  267 +
 dojox/app/tests/mediaQuery3ColumnApp/index.html    |   23 +
 .../mediaQuery3ColumnApp/mediaQuery3ColumnApp.js   |   19 +
 dojox/app/tests/mediaQuery3ColumnApp/nls/app.js    |    7 +
 dojox/app/tests/mediaQuery3ColumnApp/nls/fr/app.js |    4 +
 .../app/tests/mediaQuery3ColumnApp/nls/fr/home.js  |    4 +
 dojox/app/tests/mediaQuery3ColumnApp/nls/home.js   |    7 +
 .../tests/mediaQuery3ColumnApp/views/header.html   |    9 +
 .../mediaQuery3ColumnApp/views/last/last.html      |   25 +
 .../tests/mediaQuery3ColumnApp/views/last/last.js  |   70 +
 .../mediaQuery3ColumnApp/views/main/TestInfo.html  |   28 +
 .../mediaQuery3ColumnApp/views/main/TestInfo.js    |   30 +
 .../mediaQuery3ColumnApp/views/main/main.html      |   25 +
 .../tests/mediaQuery3ColumnApp/views/main/main.js  |   74 +
 .../mediaQuery3ColumnApp/views/nav/navigation.html |   29 +
 .../mediaQuery3ColumnApp/views/nav/navigation.js   |   54 +
 dojox/app/tests/mediaQueryLayoutApp/config.json    |  137 +
 .../mediaQueryLayoutApp/controllers/CssLayout.js   |   79 +
 .../css/mediaQueryLayoutApp.css                    |  187 +
 dojox/app/tests/mediaQueryLayoutApp/index.html     |   23 +
 .../mediaQueryLayoutApp/mediaQueryLayoutApp.js     |   68 +
 .../tests/mediaQueryLayoutApp/views/TestInfo.html  |   24 +
 .../tests/mediaQueryLayoutApp/views/TestInfo.js    |   52 +
 .../views/centerNavigation.html                    |   15 +
 .../mediaQueryLayoutApp/views/centerNavigation.js  |   30 +
 .../tests/mediaQueryLayoutApp/views/date/date.html |   21 +
 .../tests/mediaQueryLayoutApp/views/date/date.js   |   58 +
 .../tests/mediaQueryLayoutApp/views/header.html    |   20 +
 .../app/tests/mediaQueryLayoutApp/views/header.js  |   45 +
 .../views/list/itemDetails.html                    |   38 +
 .../mediaQueryLayoutApp/views/list/itemDetails.js  |   48 +
 .../tests/mediaQueryLayoutApp/views/list/list.html |    6 +
 .../tests/mediaQueryLayoutApp/views/list/list.js   |  113 +
 .../mediaQueryLayoutApp/views/navigation.html      |   16 +
 .../mediaQueryLayoutApp/views/simple/simple.html   |  101 +
 .../mediaQueryLayoutApp/views/simple/simple.js     |   62 +
 dojox/app/tests/modelApp/config.json               |  127 +-
 dojox/app/tests/modelApp/date/date.html            |   24 +
 dojox/app/tests/modelApp/date/date.js              |   44 +
 dojox/app/tests/modelApp/index.html                |   19 +-
 dojox/app/tests/modelApp/list/itemDetails.html     |   37 +
 dojox/app/tests/modelApp/list/itemDetails.js       |   48 +
 dojox/app/tests/modelApp/list/list.html            |   11 +
 dojox/app/tests/modelApp/list/list.js              |   66 +
 dojox/app/tests/modelApp/main/main.html            |    9 +
 dojox/app/tests/modelApp/modelApp.js               |  162 +-
 dojox/app/tests/modelApp/simple/simple.html        |  101 +
 dojox/app/tests/modelApp/simple/simple.js          |   62 +
 dojox/app/tests/modelApp/views/generate.html       |   68 -
 dojox/app/tests/modelApp/views/main.html           |   15 -
 dojox/app/tests/modelApp/views/repeat.html         |   89 -
 dojox/app/tests/modelApp/views/simple.html         |   59 -
 dojox/app/tests/multiSceneApp/application.html     |    2 +-
 dojox/app/tests/multiSceneApp/config.json          |  111 +-
 dojox/app/tests/multiSceneApp/gallery.html         |    3 -
 dojox/app/tests/multiSceneApp/index.html           |   35 +-
 dojox/app/tests/multiSceneApp/multiSceneApp.js     |   17 +-
 dojox/app/tests/multiSceneApp/simple.html          |    2 +-
 dojox/app/tests/multiSceneApp/tabScene.html        |    4 +-
 .../{views => templates}/simple/home.html          |    0
 .../tests/multiSceneApp/templates/simple/main.html |   27 +
 .../multiSceneApp/templates/simple/second.html     |   12 +
 .../multiSceneApp/templates/simple/third.html      |   38 +
 .../{views => templates}/tabs/tab1.html            |    0
 .../{views => templates}/tabs/tab2.html            |    0
 .../{views => templates}/tabs/tab3.html            |    0
 .../tests/multiSceneApp/views/gallery/ajax.html    |   10 -
 .../multiSceneApp/views/gallery/ajaxLoad.html      |    7 -
 .../multiSceneApp/views/gallery/animations.html    |   24 -
 .../multiSceneApp/views/gallery/buttonScene.html   |    8 -
 .../multiSceneApp/views/gallery/buttons/tab1.html  |    9 -
 .../multiSceneApp/views/gallery/buttons/tab2.html  |    8 -
 .../multiSceneApp/views/gallery/buttons/tab3.html  |    6 -
 .../views/gallery/flippableViews.html              |   19 -
 .../tests/multiSceneApp/views/gallery/forms.html   |  110 -
 .../multiSceneApp/views/gallery/headings.html      |   23 -
 .../tests/multiSceneApp/views/gallery/icons.html   |   18 -
 .../tests/multiSceneApp/views/gallery/jsonp.html   |   10 -
 .../tests/multiSceneApp/views/gallery/list.html    |  143 -
 .../app/tests/multiSceneApp/views/gallery/map.html |    5 -
 .../multiSceneApp/views/gallery/navigation.html    |   51 -
 .../multiSceneApp/views/gallery/rowTemplate.html   |    1 -
 .../tests/multiSceneApp/views/gallery/tabbar.html  |   27 -
 .../tests/multiSceneApp/views/gallery/welcome.html |    5 -
 .../app/tests/multiSceneApp/views/simple/main.html |   92 -
 .../tests/multiSceneApp/views/simple/second.html   |   13 -
 .../tests/multiSceneApp/views/simple/third.html    |   38 -
 dojox/app/tests/scrollableTestApp/config.json      |  194 +
 dojox/app/tests/scrollableTestApp/css/demo.css     |   12 +
 dojox/app/tests/scrollableTestApp/css/tablet.css   |   81 +
 dojox/app/tests/scrollableTestApp/index.html       |   44 +
 .../scrollableTestApp/resources/data/repeat.json   |  105 +
 .../tests/scrollableTestApp/scrollableTestApp.js   |   67 +
 dojox/app/tests/scrollableTestApp/src.js           |   15 +
 .../scrollableTestApp/themes/android/todo.css      |   25 +
 .../scrollableTestApp/themes/blackberry/todo.css   |   21 +
 .../tests/scrollableTestApp/themes/iphone/todo.css |   31 +
 .../views/ListItem-domButtons.html                 |  106 +
 .../scrollableTestApp/views/ListItem-domButtons.js |   18 +
 .../views/ListItem-domButtons2.html                |   42 +
 .../views/RoundRectWidListTemplate.html            |    8 +
 .../tests/scrollableTestApp/views/Scrollable1.html |   41 +
 .../tests/scrollableTestApp/views/Scrollable1.js   |   86 +
 .../scrollableTestApp/views/Scrollable1P.html      |   23 +
 .../tests/scrollableTestApp/views/Scrollable1P.js  |  151 +
 .../tests/scrollableTestApp/views/Scrollable2.html |   41 +
 .../tests/scrollableTestApp/views/Scrollable2.js   |   81 +
 .../tests/scrollableTestApp/views/Scrollable3.html |   42 +
 .../tests/scrollableTestApp/views/Scrollable3.js   |   81 +
 .../tests/scrollableTestApp/views/Scrollable4.html |   43 +
 .../tests/scrollableTestApp/views/Scrollable4.js   |   81 +
 .../tests/scrollableTestApp/views/Scrollable5.html |   42 +
 .../tests/scrollableTestApp/views/Scrollable5.js   |   81 +
 .../tests/scrollableTestApp/views/TestInfo.html    |   27 +
 .../app/tests/scrollableTestApp/views/TestInfo.js  |   46 +
 .../configuration/ScrollableListSelection.html     |   70 +
 .../views/configuration/ScrollableListSelection.js |   31 +
 dojox/app/tests/scrollableTestApp/views/items.js   |   24 +
 .../scrollableTestApp/views/repeatDetails.html     |   46 +
 .../tests/scrollableTestApp/views/repeatDetails.js |   34 +
 .../views/tablet/ViewScrollableLists.html          |   78 +
 .../views/tablet/ViewScrollableLists.js            |   26 +
 dojox/app/tests/scrollableTestApp2/config.json     |  200 +
 dojox/app/tests/scrollableTestApp2/css/demo.css    |   12 +
 dojox/app/tests/scrollableTestApp2/css/tablet.css  |   81 +
 dojox/app/tests/scrollableTestApp2/index.html      |   44 +
 .../scrollableTestApp2/resources/data/repeat.json  |  105 +
 .../tests/scrollableTestApp2/scrollableTestApp.js  |   67 +
 dojox/app/tests/scrollableTestApp2/src.js          |   15 +
 .../scrollableTestApp2/themes/android/todo.css     |   25 +
 .../scrollableTestApp2/themes/blackberry/todo.css  |   21 +
 .../scrollableTestApp2/themes/iphone/todo.css      |   31 +
 .../views/ListItem-domButtons.html                 |  106 +
 .../views/ListItem-domButtons.js                   |   35 +
 .../views/ListItem-domButtons2.html                |   42 +
 .../views/RoundRectWidListTemplate.html            |    8 +
 .../scrollableTestApp2/views/Scrollable1.html      |   43 +
 .../tests/scrollableTestApp2/views/Scrollable1.js  |   86 +
 .../scrollableTestApp2/views/Scrollable1P.html     |   23 +
 .../tests/scrollableTestApp2/views/Scrollable1P.js |  151 +
 .../scrollableTestApp2/views/Scrollable2.html      |   41 +
 .../tests/scrollableTestApp2/views/Scrollable2.js  |   81 +
 .../scrollableTestApp2/views/Scrollable3.html      |   42 +
 .../tests/scrollableTestApp2/views/Scrollable3.js  |   81 +
 .../scrollableTestApp2/views/Scrollable4.html      |   43 +
 .../tests/scrollableTestApp2/views/Scrollable4.js  |   81 +
 .../scrollableTestApp2/views/Scrollable5.html      |   42 +
 .../tests/scrollableTestApp2/views/Scrollable5.js  |   81 +
 .../tests/scrollableTestApp2/views/TestInfo.html   |   27 +
 .../app/tests/scrollableTestApp2/views/TestInfo.js |   46 +
 .../configuration/ScrollableListSelection.html     |   70 +
 .../views/configuration/ScrollableListSelection.js |   38 +
 dojox/app/tests/scrollableTestApp2/views/items.js  |   24 +
 .../scrollableTestApp2/views/repeatDetails.html    |   46 +
 .../scrollableTestApp2/views/repeatDetails.js      |   34 +
 .../views/tablet/ViewScrollableLists.html          |   78 +
 .../views/tablet/ViewScrollableLists.js            |   27 +
 dojox/app/tests/simpleModelApp/config.json         |  260 +
 .../tests/simpleModelApp/generate/generate.html    |   49 +
 .../app/tests/simpleModelApp/generate/generate.js  |   53 +
 dojox/app/tests/simpleModelApp/index.html          |   61 +
 dojox/app/tests/simpleModelApp/main/main.html      |   30 +
 dojox/app/tests/simpleModelApp/modelApp.js         |   77 +
 dojox/app/tests/simpleModelApp/repeat/repeat.html  |   67 +
 dojox/app/tests/simpleModelApp/repeat/repeat.js    |   76 +
 dojox/app/tests/simpleModelApp/repeat/repeat2.html |   64 +
 dojox/app/tests/simpleModelApp/repeat/repeat2.js   |   77 +
 dojox/app/tests/simpleModelApp/repeat/repeat3.html |   64 +
 dojox/app/tests/simpleModelApp/repeat/repeat3.js   |   77 +
 .../resources/data/jsonRestNamesData.json          |    9 +
 .../resources/data/jsonRestRepeatData.json         |  102 +
 .../simpleModelApp/resources/data/names2.json      |   11 +
 .../simpleModelApp/resources/data/repeat.json      |  105 +
 dojox/app/tests/simpleModelApp/simple/simple.html  |   80 +
 dojox/app/tests/simpleModelApp/simple/simple.js    |   44 +
 dojox/app/tests/simpleModelApp/simple/simple2.html |   80 +
 dojox/app/tests/simpleModelApp/simple/simple2.js   |   44 +
 dojox/app/tests/simpleModelApp/simple/simple3.html |  102 +
 dojox/app/tests/simpleModelApp/simple/simple3.js   |   62 +
 dojox/app/tests/swapViewTestApp/config.json        |  151 +
 .../controllers/DivIdBasedLayout.js                |   70 +
 dojox/app/tests/swapViewTestApp/css/layoutApp.css  |  271 +
 dojox/app/tests/swapViewTestApp/index.html         |   27 +
 dojox/app/tests/swapViewTestApp/layoutApp.js       |   55 +
 .../app/tests/swapViewTestApp/views/TestInfo.html  |   23 +
 dojox/app/tests/swapViewTestApp/views/TestInfo.js  |   53 +
 dojox/app/tests/swapViewTestApp/views/header.html  |    4 +
 dojox/app/tests/swapViewTestApp/views/main.html    |   35 +
 dojox/app/tests/swapViewTestApp/views/main.js      |   76 +
 .../tests/swapViewTestApp/views/navigation.html    |   21 +
 .../app/tests/swapViewTestApp/views/navigation.js  |   34 +
 dojox/app/tests/swapViewTestApp/views/repeat.html  |   24 +
 dojox/app/tests/swapViewTestApp/views/repeat.js    |  122 +
 .../tests/swapViewTestApp/views/repeatDetails.html |   48 +
 .../tests/swapViewTestApp/views/repeatDetails.js   |   29 +
 dojox/app/tests/swapViewTestApp/views/simple.html  |   90 +
 dojox/app/tests/swapViewTestApp/views/simple.js    |   76 +
 dojox/app/transition.js                            |   60 -
 dojox/app/utils/config.js                          |   85 +
 dojox/app/utils/constraints.js                     |   99 +
 dojox/app/utils/hash.js                            |  176 +
 dojox/app/utils/layout.js                          |  141 +
 dojox/app/utils/model.js                           |   62 +
 dojox/app/utils/mvcModel.js                        |   99 +
 dojox/app/utils/nls.js                             |   49 +
 dojox/app/utils/simpleModel.js                     |  110 +
 dojox/app/view.js                                  |   15 -
 dojox/app/widgets/Container.js                     |  150 +
 dojox/app/widgets/_ScrollableMixin.js              |  162 +
 dojox/atom/io/Connection.js                        |  125 +-
 dojox/atom/io/model.js                             |  470 +-
 dojox/atom/widget/FeedEntryEditor.js               |  343 +-
 dojox/atom/widget/FeedEntryViewer.js               |  302 +-
 dojox/atom/widget/FeedViewer.js                    |  294 +-
 dojox/atom/widget/nls/FeedEntryEditor.js           |    4 +-
 dojox/atom/widget/nls/FeedEntryViewer.js           |    2 +
 dojox/atom/widget/nls/FeedViewerEntry.js           |    2 +
 dojox/atom/widget/nls/PeopleEditor.js              |    2 +
 dojox/atom/widget/nls/ar/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/ar/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/ar/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/ar/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/az/FeedEntryEditor.js        |    4 +-
 dojox/atom/widget/nls/az/FeedEntryViewer.js        |    4 +-
 dojox/atom/widget/nls/az/FeedViewerEntry.js        |    4 +-
 dojox/atom/widget/nls/az/PeopleEditor.js           |    4 +-
 dojox/atom/widget/nls/bg/FeedEntryEditor.js        |    8 +
 dojox/atom/widget/nls/bg/FeedEntryViewer.js        |   13 +
 dojox/atom/widget/nls/bg/FeedViewerEntry.js        |    5 +
 dojox/atom/widget/nls/bg/PeopleEditor.js           |    7 +
 dojox/atom/widget/nls/ca/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/ca/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/ca/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/ca/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/cs/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/cs/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/cs/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/cs/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/da/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/da/FeedEntryViewer.js        |    4 +-
 dojox/atom/widget/nls/da/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/da/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/de/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/de/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/de/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/de/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/el/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/el/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/el/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/el/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/es/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/es/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/es/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/es/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/fi/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/fi/FeedEntryViewer.js        |    4 +-
 dojox/atom/widget/nls/fi/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/fi/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/fr/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/fr/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/fr/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/fr/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/he/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/he/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/he/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/he/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/hu/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/hu/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/hu/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/hu/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/it/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/it/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/it/FeedViewerEntry.js        |    4 +-
 dojox/atom/widget/nls/it/PeopleEditor.js           |    4 +-
 dojox/atom/widget/nls/ja/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/ja/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/ja/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/ja/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/kk/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/kk/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/kk/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/kk/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/ko/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/ko/FeedEntryViewer.js        |    4 +-
 dojox/atom/widget/nls/ko/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/ko/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/nb/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/nb/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/nb/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/nb/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/nl/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/nl/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/nl/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/nl/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/pl/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/pl/FeedEntryViewer.js        |    4 +-
 dojox/atom/widget/nls/pl/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/pl/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js     |    2 -
 dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js     |    2 -
 dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js     |    2 -
 dojox/atom/widget/nls/pt-pt/PeopleEditor.js        |    2 -
 dojox/atom/widget/nls/pt/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/pt/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/pt/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/pt/PeopleEditor.js           |    4 +-
 dojox/atom/widget/nls/ro/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/ro/FeedEntryViewer.js        |    4 +-
 dojox/atom/widget/nls/ro/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/ro/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/ru/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/ru/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/ru/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/ru/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/sk/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/sk/FeedEntryViewer.js        |    8 +-
 dojox/atom/widget/nls/sk/FeedViewerEntry.js        |    4 +-
 dojox/atom/widget/nls/sk/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/sl/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/sl/FeedEntryViewer.js        |    4 +-
 dojox/atom/widget/nls/sl/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/sl/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/sv/FeedEntryEditor.js        |   10 +-
 dojox/atom/widget/nls/sv/FeedEntryViewer.js        |   10 +-
 dojox/atom/widget/nls/sv/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/sv/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/th/FeedEntryEditor.js        |    4 +-
 dojox/atom/widget/nls/th/FeedEntryViewer.js        |   10 +-
 dojox/atom/widget/nls/th/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/th/PeopleEditor.js           |    4 +-
 dojox/atom/widget/nls/tr/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/tr/FeedEntryViewer.js        |    2 -
 dojox/atom/widget/nls/tr/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/tr/PeopleEditor.js           |    2 -
 dojox/atom/widget/nls/uk/FeedEntryEditor.js        |    8 +
 dojox/atom/widget/nls/uk/FeedEntryViewer.js        |   13 +
 dojox/atom/widget/nls/uk/FeedViewerEntry.js        |    5 +
 dojox/atom/widget/nls/uk/PeopleEditor.js           |    7 +
 dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js     |    2 -
 dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js     |    2 -
 dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js     |    2 -
 dojox/atom/widget/nls/zh-tw/PeopleEditor.js        |    2 -
 dojox/atom/widget/nls/zh/FeedEntryEditor.js        |    2 -
 dojox/atom/widget/nls/zh/FeedEntryViewer.js        |   10 +-
 dojox/atom/widget/nls/zh/FeedViewerEntry.js        |    2 -
 dojox/atom/widget/nls/zh/PeopleEditor.js           |    4 +-
 dojox/calc/FuncGen.js                              |   48 +-
 dojox/calc/GraphPro.js                             |   18 +-
 dojox/calc/Grapher.js                              |  103 +-
 dojox/calc/Standard.js                             |   78 +-
 dojox/calc/_Executor.js                            |   37 +-
 dojox/calc/_ExecutorIframe.html                    |   98 +-
 dojox/calc/tests/test_GraphPro.html                |    2 +-
 dojox/calc/tests/test_Standard.html                |    2 +-
 dojox/calc/toFrac.js                               |    3 +-
 dojox/calendar/CONTRIBUTING.md                     |    3 +
 dojox/calendar/Calendar.js                         |   59 +
 dojox/calendar/CalendarBase.js                     | 1464 +
 dojox/calendar/ColumnView.js                       |  257 +
 dojox/calendar/ColumnViewSecondarySheet.js         |  105 +
 dojox/calendar/ExpandRenderer.js                   |  144 +
 dojox/calendar/HorizontalRenderer.js               |   92 +
 dojox/calendar/Keyboard.js                         |  349 +
 dojox/calendar/LICENSE                             |  195 +
 dojox/calendar/LabelRenderer.js                    |   44 +
 dojox/calendar/MatrixView.js                       | 2307 ++
 dojox/calendar/MobileCalendar.js                   |   58 +
 dojox/calendar/MobileHorizontalRenderer.js         |   81 +
 dojox/calendar/MobileVerticalRenderer.js           |   47 +
 dojox/calendar/MonthColumnView.js                  | 1512 +
 dojox/calendar/Mouse.js                            |  313 +
 dojox/calendar/README                              |   18 +
 dojox/calendar/SimpleColumnView.js                 | 1750 +
 dojox/calendar/StoreMixin.js                       |  329 +
 dojox/calendar/Touch.js                            |  448 +
 dojox/calendar/VerticalRenderer.js                 |   39 +
 dojox/calendar/ViewBase.js                         | 2843 ++
 dojox/calendar/_RendererMixin.js                   |  307 +
 dojox/calendar/_VerticalScrollBarBase.js           |   79 +
 dojox/calendar/nls/ar/buttons.js                   |   10 +
 dojox/calendar/nls/bg/buttons.js                   |   10 +
 dojox/calendar/nls/buttons.js                      |   45 +
 dojox/calendar/nls/ca/buttons.js                   |   10 +
 dojox/calendar/nls/cs/buttons.js                   |   10 +
 dojox/calendar/nls/da/buttons.js                   |   10 +
 dojox/calendar/nls/de/buttons.js                   |   10 +
 dojox/calendar/nls/el/buttons.js                   |   10 +
 dojox/calendar/nls/es/buttons.js                   |   10 +
 dojox/calendar/nls/fi/buttons.js                   |   10 +
 dojox/calendar/nls/fr/buttons.js                   |   10 +
 dojox/calendar/nls/he/buttons.js                   |   10 +
 dojox/calendar/nls/hr/buttons.js                   |   10 +
 dojox/calendar/nls/hu/buttons.js                   |   10 +
 dojox/calendar/nls/it/buttons.js                   |   10 +
 dojox/calendar/nls/ja/buttons.js                   |   10 +
 dojox/calendar/nls/kk/buttons.js                   |   10 +
 dojox/calendar/nls/ko/buttons.js                   |   10 +
 dojox/calendar/nls/nb/buttons.js                   |   10 +
 dojox/calendar/nls/nl/buttons.js                   |   10 +
 dojox/calendar/nls/pl/buttons.js                   |   10 +
 dojox/calendar/nls/pt-pt/buttons.js                |   10 +
 dojox/calendar/nls/pt/buttons.js                   |   10 +
 dojox/calendar/nls/ro/buttons.js                   |   10 +
 dojox/calendar/nls/ru/buttons.js                   |   10 +
 dojox/calendar/nls/sk/buttons.js                   |   10 +
 dojox/calendar/nls/sl/buttons.js                   |   10 +
 dojox/calendar/nls/sv/buttons.js                   |   10 +
 dojox/calendar/nls/th/buttons.js                   |   10 +
 dojox/calendar/nls/tr/buttons.js                   |   10 +
 dojox/calendar/nls/uk/buttons.js                   |   10 +
 dojox/calendar/nls/zh-tw/buttons.js                |   10 +
 dojox/calendar/nls/zh/buttons.js                   |   10 +
 dojox/calendar/templates/Calendar.html             |   16 +
 dojox/calendar/templates/ColumnView.html           |   32 +
 .../templates/ColumnViewSecondarySheet.html        |   11 +
 dojox/calendar/templates/ExpandRenderer.html       |    3 +
 dojox/calendar/templates/HorizontalRenderer.html   |   13 +
 dojox/calendar/templates/LabelRenderer.html        |    8 +
 dojox/calendar/templates/MatrixView.html           |   17 +
 dojox/calendar/templates/MobileCalendar.html       |   11 +
 .../templates/MobileHorizontalRenderer.html        |   13 +
 .../calendar/templates/MobileVerticalRenderer.html |   12 +
 dojox/calendar/templates/MonthColumnView.html      |   18 +
 dojox/calendar/templates/SimpleColumnView.html     |   27 +
 dojox/calendar/templates/SimpleMatrixView.html     |   17 +
 dojox/calendar/templates/VerticalRenderer.html     |   13 +
 dojox/calendar/tests/CalendarMonthColumn.html      |   17 +
 dojox/calendar/tests/DatePicker.js                 |   27 +
 dojox/calendar/tests/ExtendedCalendar.js           |   91 +
 dojox/calendar/tests/SimpleMatrixView.html         |   11 +
 dojox/calendar/tests/asyncStore.css                |   41 +
 dojox/calendar/tests/asyncStore.html               |  183 +
 dojox/calendar/tests/calendar.css                  |   89 +
 dojox/calendar/tests/calendar.html                 |  396 +
 dojox/calendar/tests/calendarItemEvents.html       |  183 +
 dojox/calendar/tests/calendarMonthView.html        |  454 +
 dojox/calendar/tests/calendarStyleGridCell.html    |   84 +
 dojox/calendar/tests/calendarStyleGridCellCSS.html |   67 +
 dojox/calendar/tests/columntablet.css              |   12 +
 dojox/calendar/tests/columntablet.html             |  164 +
 dojox/calendar/tests/columnview.css                |  175 +
 dojox/calendar/tests/columnview.html               |  732 +
 dojox/calendar/tests/columnview_rtl.css            |    5 +
 dojox/calendar/tests/columnview_rtl.html           |  746 +
 dojox/calendar/tests/contextmenu.html              |  342 +
 dojox/calendar/tests/editing.html                  |  135 +
 dojox/calendar/tests/hcalendar.html                |  325 +
 dojox/calendar/tests/isItemEditable.html           |  163 +
 dojox/calendar/tests/matrixtablet.css              |   14 +
 dojox/calendar/tests/matrixtablet.html             |  190 +
 dojox/calendar/tests/matrixview.css                |  120 +
 dojox/calendar/tests/matrixview.html               |  766 +
 dojox/calendar/tests/matrixview_rtl.css            |    6 +
 dojox/calendar/tests/matrixview_rtl.html           |  844 +
 dojox/calendar/tests/module.js                     |    6 +
 dojox/calendar/tests/monthcolumnview.css           |  132 +
 dojox/calendar/tests/monthcolumnview.html          |  610 +
 dojox/calendar/tests/monthcolumnview_rtl.html      |  611 +
 dojox/calendar/tests/monthtablet.css               |   14 +
 dojox/calendar/tests/monthtablet.html              |  138 +
 dojox/calendar/tests/runTests.html                 |    9 +
 dojox/calendar/tests/unitTest_Store.js             |   14 +
 dojox/calendar/tests/unitTest_Time.js              |   22 +
 dojox/calendar/tests/unitTest_TimeRanges.js        |  151 +
 dojox/calendar/tests/unitTest_editing.js           |  736 +
 dojox/calendar/themes/claro/Calendar.css           |   28 +
 dojox/calendar/themes/claro/Calendar.less          |   36 +
 dojox/calendar/themes/claro/Calendar_rtl.css       |    3 +
 dojox/calendar/themes/claro/Calendar_rtl.less      |    3 +
 dojox/calendar/themes/claro/ColumnView.css         |  521 +
 dojox/calendar/themes/claro/ColumnView.less        |  522 +
 dojox/calendar/themes/claro/ColumnViewCommon.less  |   10 +
 dojox/calendar/themes/claro/ColumnView_rtl.css     |  117 +
 dojox/calendar/themes/claro/ColumnView_rtl.less    |  134 +
 dojox/calendar/themes/claro/Common.less            |  111 +
 dojox/calendar/themes/claro/MatrixView.css         |  376 +
 dojox/calendar/themes/claro/MatrixView.less        |  374 +
 dojox/calendar/themes/claro/MatrixViewCommon.less  |   12 +
 dojox/calendar/themes/claro/MatrixView_rtl.css     |   71 +
 dojox/calendar/themes/claro/MatrixView_rtl.less    |   75 +
 dojox/calendar/themes/claro/MonthColumnView.css    |  283 +
 dojox/calendar/themes/claro/MonthColumnView.less   |  282 +
 .../themes/claro/MonthColumnViewCommon.less        |    7 +
 .../calendar/themes/claro/MonthColumnView_rtl.css  |   58 +
 .../calendar/themes/claro/MonthColumnView_rtl.less |   60 +
 dojox/calendar/themes/claro/SimpleColumnView.css   |  390 +
 dojox/calendar/themes/claro/SimpleColumnView.less  |  391 +
 .../calendar}/themes/claro/images/titlebar.png     |  Bin 640 -> 640 bytes
 dojox/calendar/themes/iphone/Calendar.css          |   25 +
 dojox/calendar/themes/iphone/Calendar.less         |   30 +
 dojox/calendar/themes/iphone/Calendar_rtl.css      |    3 +
 dojox/calendar/themes/iphone/Calendar_rtl.less     |    3 +
 dojox/calendar/themes/iphone/ColumnView.css        |  504 +
 dojox/calendar/themes/iphone/ColumnView.less       |  537 +
 dojox/calendar/themes/iphone/ColumnViewCommon.less |   10 +
 dojox/calendar/themes/iphone/ColumnView_rtl.css    |  102 +
 dojox/calendar/themes/iphone/ColumnView_rtl.less   |  129 +
 .../themes/iphone/Common.css}                      |    0
 dojox/calendar/themes/iphone/Common.less           |   78 +
 dojox/calendar/themes/iphone/MatrixView.css        |  407 +
 dojox/calendar/themes/iphone/MatrixView.less       |  429 +
 dojox/calendar/themes/iphone/MatrixViewCommon.less |   11 +
 dojox/calendar/themes/iphone/MatrixView_rtl.css    |  463 +
 dojox/calendar/themes/iphone/MatrixView_rtl.less   |   71 +
 dojox/calendar/themes/iphone/MonthColumnView.css   |  264 +
 dojox/calendar/themes/iphone/MonthColumnView.less  |  303 +
 .../themes/iphone/MonthColumnViewCommon.less       |    7 +
 .../calendar/themes/iphone/MonthColumnView_rtl.css |   42 +
 .../themes/iphone/MonthColumnView_rtl.less         |   57 +
 dojox/calendar/themes/nihilo/Calendar.css          |   27 +
 dojox/calendar/themes/nihilo/Calendar.less         |   33 +
 dojox/calendar/themes/nihilo/Calendar_rtl.css      |    3 +
 dojox/calendar/themes/nihilo/Calendar_rtl.less     |    3 +
 dojox/calendar/themes/nihilo/ColumnView.css        |  484 +
 dojox/calendar/themes/nihilo/ColumnView.less       |  518 +
 dojox/calendar/themes/nihilo/ColumnViewCommon.less |   10 +
 dojox/calendar/themes/nihilo/ColumnView_rtl.css    |  102 +
 dojox/calendar/themes/nihilo/ColumnView_rtl.less   |  129 +
 dojox/calendar/themes/nihilo/Common.less           |   72 +
 dojox/calendar/themes/nihilo/MatrixView.css        |  364 +
 dojox/calendar/themes/nihilo/MatrixView.less       |  373 +
 dojox/calendar/themes/nihilo/MatrixViewCommon.less |   12 +
 dojox/calendar/themes/nihilo/MatrixView_rtl.css    |   56 +
 dojox/calendar/themes/nihilo/MatrixView_rtl.less   |   71 +
 dojox/calendar/themes/nihilo/MonthColumnView.css   |  261 +
 dojox/calendar/themes/nihilo/MonthColumnView.less  |  281 +
 .../themes/nihilo/MonthColumnViewCommon.less       |    7 +
 .../calendar/themes/nihilo/MonthColumnView_rtl.css |   42 +
 .../themes/nihilo/MonthColumnView_rtl.less         |   56 +
 dojox/calendar/themes/nihilo/SimpleColumnView.css  |  356 +
 dojox/calendar/themes/nihilo/SimpleColumnView.less |  382 +
 .../themes/nihilo/images/accordionItemActive.png   |  Bin 148 -> 148 bytes
 .../calendar}/themes/nihilo/images/titleBar.png    |  Bin 148 -> 148 bytes
 dojox/calendar/themes/soria/Calendar.css           |   27 +
 dojox/calendar/themes/soria/Calendar.less          |   33 +
 dojox/calendar/themes/soria/Calendar_rtl.css       |    3 +
 dojox/calendar/themes/soria/Calendar_rtl.less      |    3 +
 dojox/calendar/themes/soria/ColumnView.css         |  481 +
 dojox/calendar/themes/soria/ColumnView.less        |  511 +
 dojox/calendar/themes/soria/ColumnViewCommon.less  |   10 +
 dojox/calendar/themes/soria/ColumnView_rtl.css     |  102 +
 dojox/calendar/themes/soria/ColumnView_rtl.less    |  129 +
 dojox/calendar/themes/soria/Common.less            |   72 +
 dojox/calendar/themes/soria/MatrixView.css         |  364 +
 dojox/calendar/themes/soria/MatrixView.less        |  373 +
 dojox/calendar/themes/soria/MatrixViewCommon.less  |   12 +
 dojox/calendar/themes/soria/MatrixView_rtl.css     |   56 +
 dojox/calendar/themes/soria/MatrixView_rtl.less    |   71 +
 dojox/calendar/themes/soria/MonthColumnView.css    |  261 +
 dojox/calendar/themes/soria/MonthColumnView.less   |  282 +
 .../themes/soria/MonthColumnViewCommon.less        |    7 +
 .../calendar/themes/soria/MonthColumnView_rtl.css  |   42 +
 .../calendar/themes/soria/MonthColumnView_rtl.less |   56 +
 dojox/calendar/themes/soria/SimpleColumnView.css   |  356 +
 dojox/calendar/themes/soria/SimpleColumnView.less  |  382 +
 .../themes/soria/images/accordionItemActive.png    |  Bin 171 -> 171 bytes
 .../calendar}/themes/soria/images/titleBar.png     |  Bin 183 -> 183 bytes
 dojox/calendar/themes/tundra/Calendar.css          |   27 +
 dojox/calendar/themes/tundra/Calendar.less         |   33 +
 dojox/calendar/themes/tundra/Calendar_rtl.css      |    3 +
 dojox/calendar/themes/tundra/Calendar_rtl.less     |    3 +
 dojox/calendar/themes/tundra/ColumnView.css        |  483 +
 dojox/calendar/themes/tundra/ColumnView.less       |  520 +
 dojox/calendar/themes/tundra/ColumnViewCommon.less |   10 +
 dojox/calendar/themes/tundra/ColumnView_rtl.css    |  102 +
 dojox/calendar/themes/tundra/ColumnView_rtl.less   |  129 +
 dojox/calendar/themes/tundra/Common.less           |   69 +
 dojox/calendar/themes/tundra/MatrixView.css        |  358 +
 dojox/calendar/themes/tundra/MatrixView.less       |  373 +
 dojox/calendar/themes/tundra/MatrixViewCommon.less |   12 +
 dojox/calendar/themes/tundra/MatrixView_rtl.css    |   56 +
 dojox/calendar/themes/tundra/MatrixView_rtl.less   |   71 +
 dojox/calendar/themes/tundra/MonthColumnView.css   |  258 +
 dojox/calendar/themes/tundra/MonthColumnView.less  |  281 +
 .../themes/tundra/MonthColumnViewCommon.less       |    7 +
 .../calendar/themes/tundra/MonthColumnView_rtl.css |   42 +
 .../themes/tundra/MonthColumnView_rtl.less         |   56 +
 dojox/calendar/themes/tundra/SimpleColumnView.css  |  346 +
 dojox/calendar/themes/tundra/SimpleColumnView.less |  378 +
 .../themes/tundra/images/accordionItemHover.gif    |  Bin 0 -> 171 bytes
 .../calendar}/themes/tundra/images/titleBar.png    |  Bin 151 -> 151 bytes
 dojox/calendar/time.js                             |  176 +
 dojox/charting/BidiSupport.js                      |  266 +-
 dojox/charting/BidiSupport3D.js                    |    4 +
 dojox/charting/Chart.js                            |  771 +-
 dojox/charting/Chart2D.js                          |    8 +-
 dojox/charting/Chart3D.js                          |   27 +-
 dojox/charting/DataChart.js                        |  169 +-
 dojox/charting/DataSeries.js                       |   40 +-
 dojox/charting/Element.js                          |  170 +-
 dojox/charting/Series.js                           |   28 +-
 dojox/charting/SimpleTheme.js                      |  577 +
 dojox/charting/StoreSeries.js                      |   27 +-
 dojox/charting/Theme.js                            |  749 +-
 dojox/charting/action2d/Base.js                    |   20 +-
 dojox/charting/action2d/ChartAction.js             |   16 +-
 dojox/charting/action2d/Highlight.js               |   62 +-
 dojox/charting/action2d/Magnify.js                 |   39 +-
 dojox/charting/action2d/MouseIndicator.js          |  158 +-
 dojox/charting/action2d/MouseZoomAndPan.js         |   78 +-
 dojox/charting/action2d/MoveSlice.js               |   53 +-
 dojox/charting/action2d/PlotAction.js              |   36 +-
 dojox/charting/action2d/Shake.js                   |   38 +-
 dojox/charting/action2d/Tooltip.js                 |  123 +-
 dojox/charting/action2d/TouchIndicator.js          |  233 +-
 dojox/charting/action2d/TouchZoomAndPan.js         |  226 +-
 dojox/charting/action2d/_IndicatorElement.js       |  362 +-
 dojox/charting/axis2d/Base.js                      |  150 +-
 dojox/charting/axis2d/Default.js                   |  841 +-
 dojox/charting/axis2d/Invisible.js                 |  231 +-
 dojox/charting/axis2d/common.js                    |   53 +-
 dojox/charting/bidi/Chart.js                       |  260 +
 dojox/charting/bidi/Chart3D.js                     |   78 +
 dojox/charting/bidi/_bidiutils.js                  |   27 +
 dojox/charting/bidi/action2d/Tooltip.js            |   45 +
 dojox/charting/bidi/action2d/ZoomAndPan.js         |   11 +
 dojox/charting/bidi/axis2d/Default.js              |   27 +
 dojox/charting/bidi/widget/Chart.js                |   29 +
 dojox/charting/bidi/widget/Legend.js               |   63 +
 dojox/charting/plot2d/Areas.js                     |   10 +-
 dojox/charting/plot2d/Bars.js                      |  202 +-
 dojox/charting/plot2d/Base.js                      |  381 +-
 dojox/charting/plot2d/Bubble.js                    |   85 +-
 dojox/charting/plot2d/Candlesticks.js              |   70 +-
 dojox/charting/plot2d/CartesianBase.js             |  289 +
 dojox/charting/plot2d/ClusteredBars.js             |   99 +-
 dojox/charting/plot2d/ClusteredColumns.js          |  101 +-
 dojox/charting/plot2d/Columns.js                   |  155 +-
 dojox/charting/plot2d/Default.js                   |  287 +-
 dojox/charting/plot2d/Grid.js                      |  459 +-
 dojox/charting/plot2d/Indicator.js                 |  493 +
 dojox/charting/plot2d/Lines.js                     |    8 +-
 dojox/charting/plot2d/Markers.js                   |    8 +-
 dojox/charting/plot2d/MarkersOnly.js               |    8 +-
 dojox/charting/plot2d/OHLC.js                      |   57 +-
 dojox/charting/plot2d/Pie.js                       |  300 +-
 dojox/charting/plot2d/Scatter.js                   |   77 +-
 dojox/charting/plot2d/Spider.js                    |  370 +-
 dojox/charting/plot2d/Stacked.js                   |  210 +-
 dojox/charting/plot2d/StackedAreas.js              |    8 +-
 dojox/charting/plot2d/StackedBars.js               |  137 +-
 dojox/charting/plot2d/StackedColumns.js            |  137 +-
 dojox/charting/plot2d/StackedLines.js              |    8 +-
 dojox/charting/plot2d/_PlotEvents.js               |   34 +-
 dojox/charting/plot2d/common.js                    |    6 +-
 dojox/charting/plot2d/commonStacked.js             |   71 +
 dojox/charting/plot3d/Bars.js                      |   18 +-
 dojox/charting/plot3d/Base.js                      |   16 +-
 dojox/charting/plot3d/Cylinders.js                 |   18 +-
 dojox/charting/scaler/common.js                    |   11 +-
 dojox/charting/scaler/linear.js                    |   26 +-
 .../tests/BidiSupport/bidi_ChartAxisTitle.html     |    4 +-
 .../tests/BidiSupport/bidi_DataSeries.html         |    5 +-
 .../tests/BidiSupport/bidi_DeclerativeChart.html   |    6 +-
 dojox/charting/tests/BidiSupport/bidi_Event2d.html |    5 +-
 .../tests/BidiSupport/bidi_Label_shortening.html   |    7 +-
 .../tests/BidiSupport/bidi_Pie_smart_label.html    |    5 +-
 dojox/charting/tests/BidiSupport/bidi_Pies.html    |    5 +-
 .../tests/BidiSupport/bidi_RotatedLabels.html      |    4 +-
 .../tests/BidiSupport/bidi_SelectableLegend.html   |    5 +-
 .../tests/BidiSupport/bidi_SetTextDir.html         |    8 +-
 .../charting/tests/BidiSupport/bidi_Spider2d.html  |    7 +-
 dojox/charting/tests/BidiSupport/charting.js       |    3 +
 .../tests/BidiSupport/data/goog_prices.csv         |  796 +
 .../tests/BidiSupport/data/msft_prices.csv         |  796 +
 .../tests/BidiSupport/data/yahoo_prices.csv        |  796 +
 .../tests/BidiSupport/mirror_ChartAxisTitle.html   |  192 +
 .../tests/BidiSupport/mirror_DataSeries.html       |  237 +
 .../tests/BidiSupport/mirror_DeclerativeChart.html |  105 +
 .../charting/tests/BidiSupport/mirror_Event2d.html |  251 +
 .../tests/BidiSupport/mirror_Label_shortening.html |  234 +
 .../tests/BidiSupport/mirror_Pie_smart_label.html  |  169 +
 dojox/charting/tests/BidiSupport/mirror_Pies.html  |  124 +
 .../tests/BidiSupport/mirror_RotatedLabels.html    |  121 +
 .../tests/BidiSupport/mirror_SelectableLegend.html |  209 +
 .../tests/BidiSupport/mirror_SetTextDir.html       |  353 +
 .../tests/BidiSupport/mirror_Spider2d.html         |  272 +
 .../tests/BidiSupport/mirror_StoreSeries.html      |  202 +
 .../charting/tests/BidiSupport/mirror_anim2d.html  |  133 +
 dojox/charting/tests/BidiSupport/mirror_axes.html  |  100 +
 .../tests/BidiSupport/mirror_axisZoomControl.html  |  131 +
 .../tests/BidiSupport/mirror_axisoffsets.html      |   45 +
 dojox/charting/tests/BidiSupport/mirror_bars.html  |   72 +
 .../tests/BidiSupport/mirror_chart2d-amd.html      |  863 +
 .../tests/BidiSupport/mirror_chart2d_dynamics.html |  261 +
 .../tests/BidiSupport/mirror_chart2d_updating.html |  107 +
 .../tests/BidiSupport/mirror_chartTitle.html       |  108 +
 .../tests/BidiSupport/mirror_chartingsize.html     |   44 +
 .../tests/BidiSupport/mirror_cylinders.html        |   72 +
 .../tests/BidiSupport/mirror_dropLabels.html       |  122 +
 .../tests/BidiSupport/mirror_fillstroke.html       |  138 +
 .../tests/BidiSupport/mirror_fireEvent.html        |  227 +
 dojox/charting/tests/BidiSupport/mirror_grid.html  |   48 +
 .../tests/BidiSupport/mirror_itemcolor.html        |  150 +
 .../tests/BidiSupport/mirror_labels2d.html         |  197 +
 .../charting/tests/BidiSupport/mirror_legend.html  |   73 +
 .../tests/BidiSupport/mirror_missingPoints.html    |  221 +
 .../tests/BidiSupport/mirror_mouseIndicator.html   |   65 +
 .../tests/BidiSupport/mirror_mouseIndicator2.html  |   69 +
 .../tests/BidiSupport/mirror_mouseZoomAndPan.html  |   81 +
 dojox/charting/tests/BidiSupport/mirror_nulls.html |  115 +
 dojox/charting/tests/BidiSupport/mirror_pie2d.html |  166 +
 .../tests/BidiSupport/mirror_pie2d_5050.html       |   67 +
 .../tests/BidiSupport/mirror_pie2d_zeroslice.html  |   65 +
 .../tests/BidiSupport/mirror_pie_omitLabels.html   |   77 +
 .../tests/BidiSupport/mirror_plot_order.html       |  113 +
 .../tests/BidiSupport/mirror_series_order.html     |  102 +
 .../charting/tests/BidiSupport/mirror_shadow.html  |   95 +
 .../tests/BidiSupport/mirror_spidersingle.html     |   62 +
 .../charting/tests/BidiSupport/mirror_stacked.html |  177 +
 .../charting/tests/BidiSupport/mirror_tension.html |   71 +
 dojox/charting/tests/BidiSupport/stock.json        |    8 +
 dojox/charting/tests/Theme.js                      |   13 +-
 dojox/charting/tests/charting.js                   |   10 +-
 .../charting/tests/gradients/test_grad_bars1.html  |    3 +-
 .../charting/tests/gradients/test_grad_bars2.html  |    5 +-
 .../charting/tests/gradients/test_grad_bars3.html  |    5 +-
 .../charting/tests/gradients/test_grad_bars4.html  |    5 +-
 .../charting/tests/gradients/test_grad_bars5.html  |    5 +-
 .../tests/gradients/test_grad_bubble1.html         |    5 +-
 .../tests/gradients/test_grad_bubble2.html         |    5 +-
 .../tests/gradients/test_grad_bubble3.html         |    5 +-
 .../tests/gradients/test_grad_bubble4.html         |    5 +-
 .../tests/gradients/test_grad_bubble6.html         |    5 +-
 .../tests/gradients/test_grad_columns1.html        |    3 +-
 .../tests/gradients/test_grad_columns2.html        |    5 +-
 .../tests/gradients/test_grad_columns3.html        |    5 +-
 .../tests/gradients/test_grad_columns4.html        |    5 +-
 .../tests/gradients/test_grad_columns5.html        |    5 +-
 dojox/charting/tests/gradients/test_grad_pie1.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie2.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie3.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie4.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie7.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie8.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie9.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pieA.html |    3 +-
 .../tests/gradients/test_grad_scatter1.html        |    3 +-
 .../tests/gradients/test_grad_scatter2.html        |    5 +-
 .../tests/gradients/test_grad_scatterB.html        |    5 +-
 dojox/charting/tests/runTests.html                 |    2 +-
 dojox/charting/tests/test_DataChart.html           |    2 +-
 dojox/charting/tests/test_DataSeries.html          |    2 +-
 dojox/charting/tests/test_StoreSeries-amd.html     |   38 +-
 dojox/charting/tests/test_StoreSeries.html         |    2 +-
 dojox/charting/tests/test_anim2d.html              |   40 +-
 dojox/charting/tests/test_axes.html                |    8 +-
 dojox/charting/tests/test_axes_dates.html          |   58 +
 dojox/charting/tests/test_axisZoomControl.html     |  126 +-
 dojox/charting/tests/test_axisoffsets.html         |   43 +
 dojox/charting/tests/test_bars.html                |    2 +-
 dojox/charting/tests/test_chart2d-amd.html         |   52 +-
 dojox/charting/tests/test_chart2d.html             |    2 +-
 dojox/charting/tests/test_chart2d_dynamics.html    |    2 +-
 dojox/charting/tests/test_chart2d_updating.html    |    2 +-
 dojox/charting/tests/test_chartAxisTitle.html      |    2 +-
 dojox/charting/tests/test_chartTitle.html          |    2 +-
 dojox/charting/tests/test_chartingsize.html        |    9 +-
 dojox/charting/tests/test_cylinders.html           |    2 +-
 dojox/charting/tests/test_dropLabels.html          |  122 +
 dojox/charting/tests/test_event2d.html             |    2 +-
 dojox/charting/tests/test_fillstroke.html          |    2 +-
 dojox/charting/tests/test_filter.html              |   99 +
 dojox/charting/tests/test_fireEvent.html           |    2 +-
 dojox/charting/tests/test_grid.html                |   78 +
 dojox/charting/tests/test_itemcolor.html           |  149 +
 dojox/charting/tests/test_label_shortening.html    |    2 +-
 dojox/charting/tests/test_labels2d.html            |    2 +-
 dojox/charting/tests/test_legend.html              |   73 +
 dojox/charting/tests/test_missingPoints.html       |  221 +
 dojox/charting/tests/test_mouseIndicator.html      |   10 +-
 dojox/charting/tests/test_mouseIndicator2.html     |   78 +-
 dojox/charting/tests/test_mouseZoomAndPan.html     |    8 +-
 dojox/charting/tests/test_nulls.html               |    2 +-
 dojox/charting/tests/test_pie2d.html               |    2 +-
 dojox/charting/tests/test_pie2d_5050.html          |   67 +
 dojox/charting/tests/test_pie2d_zeroslice.html     |    2 +-
 dojox/charting/tests/test_pie_omitLabels.html      |   74 +
 dojox/charting/tests/test_pie_smart_label.html     |    5 +-
 dojox/charting/tests/test_plot_order.html          |    2 +-
 dojox/charting/tests/test_rotatedLabels.html       |    2 +-
 dojox/charting/tests/test_scaler.html              |    2 +-
 dojox/charting/tests/test_selectableLegend.html    |    2 +-
 dojox/charting/tests/test_series_order.html        |    2 +-
 dojox/charting/tests/test_shadow.html              |   95 +
 dojox/charting/tests/test_sparklines.html          |   10 +-
 dojox/charting/tests/test_spider2d.html            |  132 +-
 dojox/charting/tests/test_spidersingle.html        |   62 +
 dojox/charting/tests/test_stacked.html             |  170 +
 dojox/charting/tests/test_tension.html             |    3 +-
 dojox/charting/tests/test_themes-amd.html          |    7 +-
 dojox/charting/tests/test_themes.html              |    2 +-
 dojox/charting/tests/test_threshold.html           |  144 +
 dojox/charting/tests/test_touchIndicator.html      |    8 +-
 dojox/charting/tests/test_touchZoomAndPan.html     |    7 +-
 dojox/charting/tests/test_widget2d-amd.html        |    6 +-
 dojox/charting/tests/test_widget2d.html            |    4 +-
 dojox/charting/tests/test_widget2d_deprecated.html |    4 +-
 dojox/charting/tests/test_win2d.html               |    2 +-
 dojox/charting/tests/theme_preview.html            |    2 +-
 dojox/charting/themes/Adobebricks.js               |    6 +-
 dojox/charting/themes/Algae.js                     |    4 +-
 dojox/charting/themes/Bahamation.js                |    4 +-
 dojox/charting/themes/BlueDusk.js                  |    5 +-
 dojox/charting/themes/Claro.js                     |   16 +-
 dojox/charting/themes/CubanShirts.js               |    8 +-
 dojox/charting/themes/Desert.js                    |    8 +-
 dojox/charting/themes/Distinctive.js               |    6 +-
 dojox/charting/themes/Dollar.js                    |    6 +-
 dojox/charting/themes/Grasshopper.js               |    4 +-
 dojox/charting/themes/Grasslands.js                |    8 +-
 dojox/charting/themes/GreySkies.js                 |    6 +-
 dojox/charting/themes/Harmony.js                   |    6 +-
 dojox/charting/themes/IndigoNation.js              |    8 +-
 dojox/charting/themes/Ireland.js                   |    6 +-
 dojox/charting/themes/Julie.js                     |    4 +-
 dojox/charting/themes/MiamiNice.js                 |    6 +-
 dojox/charting/themes/Midwest.js                   |    6 +-
 dojox/charting/themes/Minty.js                     |    6 +-
 dojox/charting/themes/PlotKit/base.js              |   10 +-
 dojox/charting/themes/PurpleRain.js                |    8 +-
 dojox/charting/themes/RoyalPurples.js              |    6 +-
 dojox/charting/themes/SageToLime.js                |    6 +-
 dojox/charting/themes/Shrooms.js                   |    7 +-
 dojox/charting/themes/ThreeD.js                    |    6 +-
 dojox/charting/themes/Tufte.js                     |    4 +-
 dojox/charting/themes/WatersEdge.js                |    6 +-
 dojox/charting/themes/Wetland.js                   |    6 +-
 dojox/charting/themes/gradientGenerator.js         |   42 +-
 dojox/charting/widget/BidiSupport.js               |   94 +-
 dojox/charting/widget/Chart.js                     |  286 +-
 dojox/charting/widget/Chart2D.js                   |    8 +-
 dojox/charting/widget/Legend.js                    |  128 +-
 dojox/charting/widget/SelectableLegend.js          |   46 +-
 dojox/charting/widget/Sparkline.js                 |  100 +-
 dojox/collections.js                               |    8 +-
 dojox/collections/ArrayList.js                     |  104 +-
 dojox/collections/BinaryTree.js                    |    4 +-
 dojox/collections/Dictionary.js                    |   72 +-
 dojox/collections/Queue.js                         |   58 +-
 dojox/collections/Set.js                           |   34 +-
 dojox/collections/SortedList.js                    |  124 +-
 dojox/collections/Stack.js                         |   58 +-
 dojox/collections/_base.js                         |   58 +-
 dojox/color.js                                     |    7 +
 dojox/color/Colorspace.js                          |  162 +-
 dojox/color/MeanColorModel.js                      |   40 +
 dojox/color/NeutralColorModel.js                   |   79 +
 dojox/color/Palette.js                             |  200 +-
 dojox/color/SimpleColorModel.js                    |   69 +
 dojox/color/_base.js                               |   46 +-
 dojox/color/api/ColorModel.js                      |   30 +
 dojox/color/tests/ColorModel.js                    |   22 +
 dojox/color/tests/color.js                         |    2 +-
 dojox/cometd.js                                    |    5 +-
 dojox/cometd/HttpChannels.js                       |   32 -
 dojox/cometd/README                                |    6 +-
 dojox/cometd/RestChannels.js                       |  483 -
 dojox/cometd/_base.js                              |  754 -
 dojox/cometd/ack.js                                |   50 -
 dojox/cometd/callbackPollTransport.js              |  102 -
 dojox/cometd/longPollTransport.js                  |    2 -
 dojox/cometd/longPollTransportFormEncoded.js       |  157 -
 dojox/cometd/longPollTransportJsonEncoded.js       |  159 -
 dojox/cometd/tests/_base.js                        |   31 -
 dojox/cometd/tests/all.js                          |    8 -
 dojox/cometd/tests/runTests.html                   |   10 -
 dojox/cometd/timestamp.js                          |    8 -
 dojox/cometd/timesync.js                           |  141 -
 dojox/css3/README                                  |    6 +-
 dojox/css3/fx.js                                   |   53 +-
 dojox/css3/transit.js                              |   91 +-
 dojox/css3/transition.js                           |  211 +-
 dojox/data/AndOrReadStore.js                       | 1204 +-
 dojox/data/AndOrWriteStore.js                      |  814 +-
 dojox/data/AppStore.js                             |   92 +-
 dojox/data/AtomReadStore.js                        |  133 +-
 dojox/data/CdfStore.js                             |  204 +-
 dojox/data/ClientFilter.js                         |   65 +-
 dojox/data/CouchDBRestStore.js                     |   22 +-
 dojox/data/CssClassStore.js                        |   50 +-
 dojox/data/CssRuleStore.js                         |  115 +-
 dojox/data/CsvStore.js                             |  109 +-
 dojox/data/FileStore.js                            |  147 +-
 dojox/data/FlickrRestStore.js                      |   22 +-
 dojox/data/FlickrStore.js                          |   96 +-
 dojox/data/GoogleFeedStore.js                      |   29 +-
 dojox/data/GoogleSearchStore.js                    |  351 +-
 dojox/data/HtmlStore.js                            |  167 +-
 dojox/data/HtmlTableStore.js                       |  183 +-
 dojox/data/ItemExplorer.js                         |    9 +-
 dojox/data/JsonQueryRestStore.js                   |   20 +-
 dojox/data/JsonRestStore.js                        |  225 +-
 dojox/data/KeyValueStore.js                        |  140 +-
 dojox/data/OpenSearchStore.js                      |   80 +-
 dojox/data/OpmlStore.js                            |  168 +-
 dojox/data/PersevereStore.js                       |   26 +-
 dojox/data/PicasaStore.js                          |  108 +-
 dojox/data/QueryReadStore.js                       |   98 +-
 dojox/data/RailsStore.js                           |    5 +-
 dojox/data/S3Store.js                              |    7 +-
 dojox/data/ServiceStore.js                         |  204 +-
 dojox/data/SnapLogicStore.js                       |  112 +-
 dojox/data/StoreExplorer.js                        |    4 +-
 dojox/data/WikipediaStore.js                       |   16 +-
 dojox/data/XmlItem.js                              |   18 +-
 dojox/data/XmlStore.js                             |  313 +-
 .../demos/demo_GoogleImageSearchStore_Grid.html    |   75 +
 dojox/data/demos/demo_GoogleSearchStore_Grid.html  |    1 +
 .../demos/demo_QueryReadStore_FilteringSelect.html |    8 +-
 dojox/data/demos/stores/LazyLoadJSIStore.js        |   12 +-
 dojox/data/demos/stores/filestore_funcs.php        |    8 +-
 dojox/data/demos/widgets/PicasaViewList.js         |    6 +-
 dojox/data/dom.js                                  |   33 +-
 dojox/data/restListener.js                         |   21 +-
 dojox/data/tests/ClientFilter.js                   |    2 +-
 dojox/data/tests/QueryReadStore.html               |  224 +-
 dojox/data/tests/performance/CsvStore.js           |    4 +-
 dojox/data/tests/stores/AndOrReadStore.js          |  346 +-
 dojox/data/tests/stores/AndOrWriteStore.js         |  484 +-
 dojox/data/tests/stores/AppStore.js                |  144 +-
 dojox/data/tests/stores/AtomReadStore.js           |   75 +-
 dojox/data/tests/stores/CssClassStore.js           |  143 +-
 dojox/data/tests/stores/CssRuleStore.js            |  119 +-
 dojox/data/tests/stores/CsvStore.js                |  214 +-
 dojox/data/tests/stores/FileStore.js               |  100 +-
 dojox/data/tests/stores/FlickrRestStore.js         |   56 +-
 dojox/data/tests/stores/FlickrStore.js             |   56 +-
 dojox/data/tests/stores/GoogleFeedStore.js         |   67 +-
 dojox/data/tests/stores/GoogleSearchStore.js       |   71 +-
 dojox/data/tests/stores/HtmlStore.js               |  148 +-
 dojox/data/tests/stores/HtmlTableStore.js          |  112 +-
 dojox/data/tests/stores/JsonQueryRestStore.js      |   22 +-
 dojox/data/tests/stores/JsonRestStore.js           |   28 +-
 dojox/data/tests/stores/KeyValueStore.js           |  162 +-
 dojox/data/tests/stores/OpenSearchStore.js         |  152 +-
 dojox/data/tests/stores/OpmlStore.js               |  150 +-
 dojox/data/tests/stores/PicasaStore.js             |   54 +-
 dojox/data/tests/stores/QueryReadStore.js          |  221 +-
 dojox/data/tests/stores/QueryReadStore.php         |   54 +-
 dojox/data/tests/stores/ServiceStore.js            |   16 +-
 dojox/data/tests/stores/SnapLogicStore.js          |   60 +-
 dojox/data/tests/stores/WikipediaStore.js          |   38 +-
 dojox/data/tests/stores/XmlStore.js                |  230 +-
 dojox/data/tests/stores/filestore_funcs.php        |    4 +-
 .../tests/stores/test_Tree_on_JsonRestStore.html   |   11 +-
 dojox/data/util/JsonQuery.js                       |    5 +-
 dojox/date/buddhist.js                             |   66 +-
 dojox/date/buddhist/Date.js                        |  116 +-
 dojox/date/buddhist/locale.js                      |   75 +-
 dojox/date/hebrew.js                               |   81 +-
 dojox/date/hebrew/Date.js                          |  278 +-
 dojox/date/hebrew/locale.js                        |  138 +-
 dojox/date/hebrew/numerals.js                      |   86 +-
 dojox/date/islamic.js                              |   79 +-
 dojox/date/islamic/Date.js                         |  179 +-
 dojox/date/islamic/locale.js                       |   84 +-
 dojox/date/persian.js                              |  252 +
 dojox/date/persian/Date.js                         |  458 +
 dojox/date/persian/locale.js                       |  414 +
 dojox/date/php.js                                  |  140 +-
 dojox/date/posix.js                                |   79 +-
 dojox/date/relative.js                             |   27 +-
 dojox/date/tests/HebrewDateTest1.html              |    2 +-
 dojox/date/tests/hebrew/Date.js                    |    2 +
 dojox/date/tests/islamic/Date.js                   | 1852 +-
 dojox/date/tests/module.js                         |    1 +
 dojox/date/tests/relative.js                       |    2 +-
 dojox/date/tests/test_DateTextBoxBuddhist.html     |    2 +-
 dojox/date/tests/test_DateTextBoxIslamic.html      |    2 +-
 .../date/tests/test_DateTextBoxNewHebrewGreg.html  |    2 +-
 .../date/tests/test_DateTextBoxNewPersianGreg.html |  184 +
 dojox/date/tests/test_DateTextBoxPersianGreg.html  |  148 +
 dojox/date/tests/test_DateTextBoxUmalqura.html     |  148 +
 dojox/date/tests/timezoneFormatting.js             |   30 +-
 dojox/date/tests/umalqura/Date.js                  | 2719 ++
 dojox/date/timezone.js                             |   47 +-
 dojox/date/umalqura.js                             |  253 +
 dojox/date/umalqura/Date.js                        |  706 +
 dojox/date/umalqura/locale.js                      |  415 +
 dojox/dgauges/CONTRIBUTING.md                      |    3 +
 dojox/dgauges/CircularGauge.js                     |   58 +
 dojox/dgauges/CircularRangeIndicator.js            |  247 +
 dojox/dgauges/CircularScale.js                     |  276 +
 dojox/dgauges/CircularValueIndicator.js            |   62 +
 dojox/dgauges/GaugeBase.js                         |  295 +
 dojox/dgauges/IndicatorBase.js                     |   10 +
 dojox/dgauges/LICENSE                              |  195 +
 dojox/dgauges/LinearScaler.js                      |  161 +
 dojox/dgauges/LogScaler.js                         |  120 +
 dojox/dgauges/MultiLinearScaler.js                 |  149 +
 dojox/dgauges/README                               |   22 +
 dojox/dgauges/RectangularGauge.js                  |  208 +
 dojox/dgauges/RectangularRangeIndicator.js         |  146 +
 dojox/dgauges/RectangularScale.js                  |  176 +
 .../dgauges/RectangularSegmentedRangeIndicator.js  |  268 +
 dojox/dgauges/RectangularValueIndicator.js         |   92 +
 dojox/dgauges/ScaleBase.js                         |  239 +
 dojox/dgauges/ScaleIndicatorBase.js                |  319 +
 dojox/dgauges/TextIndicator.js                     |  144 +
 dojox/dgauges/_circularUtils.js                    |   91 +
 dojox/dgauges/components/DefaultPropertiesMixin.js |   89 +
 .../components/black/CircularLinearGauge.js        |  154 +
 .../components/black/HorizontalLinearGauge.js      |  125 +
 .../components/black/SemiCircularLinearGauge.js    |  162 +
 .../components/black/VerticalLinearGauge.js        |  126 +
 .../components/classic/CircularLinearGauge.js      |  173 +
 .../components/classic/HorizontalLinearGauge.js    |  147 +
 .../components/classic/SemiCircularLinearGauge.js  |  159 +
 .../components/classic/VerticalLinearGauge.js      |  148 +
 .../components/default/CircularLinearGauge.js      |  176 +
 .../components/default/HorizontalLinearGauge.js    |  190 +
 .../components/default/SemiCircularLinearGauge.js  |  208 +
 .../components/default/VerticalLinearGauge.js      |  194 +
 .../components/green/CircularLinearGauge.js        |  162 +
 .../components/green/HorizontalLinearGauge.js      |  122 +
 .../components/green/SemiCircularLinearGauge.js    |  155 +
 .../components/green/VerticalLinearGauge.js        |  124 +
 .../dgauges/components/grey/CircularLinearGauge.js |  139 +
 .../components/grey/HorizontalLinearGauge.js       |  119 +
 .../components/grey/SemiCircularLinearGauge.js     |  136 +
 .../dgauges/components/grey/VerticalLinearGauge.js |  116 +
 dojox/dgauges/components/utils.js                  |  133 +
 dojox/dgauges/tests/gauges/AircraftGauge.js        |  221 +
 dojox/dgauges/tests/gauges/BulletGraph.js          |  107 +
 dojox/dgauges/tests/gauges/SimpleCircularGauge.js  |   87 +
 .../dgauges/tests/gauges/SimpleRectangularGauge.js |  120 +
 .../tests/gauges/SimpleSemiCircularGauge.js        |  108 +
 dojox/dgauges/tests/style.css                      |    2 +
 dojox/dgauges/tests/test_AircraftGauge.html        |   24 +
 .../tests/test_Black_CircularLinearGauge.html      |   35 +
 .../tests/test_Black_HorizontalLinearGauge.html    |   36 +
 .../tests/test_Black_SemiCircularLinearGauge.html  |   36 +
 .../tests/test_Black_VerticalLinearGauge.html      |   36 +
 dojox/dgauges/tests/test_BulletGraph.html          |   25 +
 .../tests/test_Classic_CircularLinearGauge.html    |   36 +
 .../tests/test_Classic_HorizontalLinearGauge.html  |   36 +
 .../test_Classic_SemiCircularLinearGauge.html      |   36 +
 .../tests/test_Classic_VerticalLinearGauge.html    |   36 +
 .../tests/test_Default_CircularLinearGauge.html    |   36 +
 .../test_Default_SemiCircularLinearGauge.html      |   36 +
 .../tests/test_Green_CircularLinearGauge.html      |   35 +
 .../tests/test_Green_HorizontalLinearGauge.html    |   36 +
 .../tests/test_Green_SemiCircularLinearGauge.html  |   35 +
 .../tests/test_Green_VerticalLinearGauge.html      |   36 +
 .../tests/test_Grey_CircularLinearGauge.html       |   35 +
 .../tests/test_Grey_HorizontalLinearGauge.html     |   36 +
 .../tests/test_Grey_SemiCircularLinearGauge.html   |   35 +
 .../tests/test_Grey_VerticalLinearGauge.html       |   36 +
 dojox/dgauges/tests/test_SimpleCircularGauge.html  |   37 +
 .../dgauges/tests/test_SimpleRectangularGauge.html |   36 +
 .../tests/test_SimpleSemiCircularGauge.html        |   35 +
 dojox/dgauges/tests/test_all.html                  |  150 +
 dojox/dgauges/tests/test_circular_gauge.html       |  199 +
 dojox/dgauges/tests/test_horizontal_gauge.html     |   40 +
 dojox/dgauges/tests/test_mobile.html               |  112 +
 dojox/dgauges/tests/test_programmatic.html         |   39 +
 dojox/dnd/BoundingBoxController.js                 |   75 +-
 dojox/dnd/Selector.js                              |   54 +-
 dojox/dnd/tests/test_boundingBoxController.html    |    2 +-
 dojox/dnd/tests/test_selector.html                 |    2 +-
 dojox/dojox.profile.js                             |   29 +-
 dojox/drawing.js                                   |   11 +-
 dojox/drawing/Drawing.js                           |  309 +-
 dojox/drawing/_base.js                             |   38 +-
 dojox/drawing/annotations/Angle.js                 |   48 +-
 dojox/drawing/annotations/Arrow.js                 |   30 +-
 dojox/drawing/annotations/BoxShadow.js             |   81 +-
 dojox/drawing/annotations/Label.js                 |   46 +-
 dojox/drawing/defaults.js                          |   86 +-
 dojox/drawing/library/greek.js                     |  113 +-
 dojox/drawing/library/icons.js                     |  405 +-
 dojox/drawing/manager/Anchors.js                   |  415 +-
 dojox/drawing/manager/Canvas.js                    |   48 +-
 dojox/drawing/manager/Mouse.js                     |  251 +-
 dojox/drawing/manager/Stencil.js                   |   92 +-
 dojox/drawing/manager/StencilUI.js                 |   38 +-
 dojox/drawing/manager/Undo.js                      |   21 +-
 dojox/drawing/manager/_registry.js                 |   40 +-
 dojox/drawing/manager/keys.js                      |   59 +-
 dojox/drawing/plugins/_Plugin.js                   |   22 +-
 dojox/drawing/plugins/drawing/GreekPalette.js      |  103 +-
 dojox/drawing/plugins/drawing/Grid.js              |   50 +-
 dojox/drawing/plugins/drawing/Silverlight.js       |   32 +-
 dojox/drawing/plugins/tools/Iconize.js             |   26 +-
 dojox/drawing/plugins/tools/Pan.js                 |   54 +-
 dojox/drawing/plugins/tools/Zoom.js                |   68 +-
 dojox/drawing/stencil/Ellipse.js                   |   46 +-
 dojox/drawing/stencil/Image.js                     |   82 +-
 dojox/drawing/stencil/Line.js                      |   53 +-
 dojox/drawing/stencil/Path.js                      |   44 +-
 dojox/drawing/stencil/Rect.js                      |   28 +-
 dojox/drawing/stencil/Text.js                      |  159 +-
 dojox/drawing/stencil/_Base.js                     |  283 +-
 dojox/drawing/tests/drawing.html                   |   59 +-
 dojox/drawing/tests/test_drawing.html              |  163 +-
 dojox/drawing/tests/test_drawing_toolbar.html      |    2 +-
 dojox/drawing/tests/test_paths.html                |    2 +-
 dojox/drawing/tests/test_shadows.html              |    2 +-
 dojox/drawing/tools/Arrow.js                       |   41 +-
 dojox/drawing/tools/Ellipse.js                     |   31 +-
 dojox/drawing/tools/Line.js                        |   33 +-
 dojox/drawing/tools/Path.js                        |   27 +-
 dojox/drawing/tools/Pencil.js                      |   28 +-
 dojox/drawing/tools/Rect.js                        |   31 +-
 dojox/drawing/tools/TextBlock.js                   |  135 +-
 dojox/drawing/tools/custom/Axes.js                 |  134 +-
 dojox/drawing/tools/custom/Equation.js             |   23 +-
 dojox/drawing/tools/custom/Vector.js               |   73 +-
 dojox/drawing/ui/Button.js                         |   36 +-
 dojox/drawing/ui/Toolbar.js                        |   64 +-
 dojox/drawing/ui/Tooltip.js                        |   31 +-
 dojox/drawing/ui/dom/Pan.js                        |   45 +-
 dojox/drawing/ui/dom/Toolbar.js                    |  111 +-
 dojox/drawing/ui/dom/Zoom.js                       |   64 +-
 dojox/drawing/util/common.js                       |   85 +-
 dojox/drawing/util/oo.js                           |   57 +-
 dojox/drawing/util/positioning.js                  |   28 +-
 dojox/drawing/util/typeset.js                      |   16 +-
 dojox/dtl.js                                       |    7 +
 dojox/dtl/Context.js                               |   59 +-
 dojox/dtl/DomInline.js                             |   64 +-
 dojox/dtl/Inline.js                                |   57 +-
 dojox/dtl/_DomTemplated.js                         |   30 +-
 dojox/dtl/_Templated.js                            |   63 +-
 dojox/dtl/_base.js                                 |  159 +-
 dojox/dtl/contrib/data.js                          |   33 +-
 dojox/dtl/contrib/dijit.js                         |   35 +-
 dojox/dtl/contrib/dom.js                           |   24 +-
 dojox/dtl/contrib/objects.js                       |   16 +-
 dojox/dtl/demos/json/blog/get_blog_1.json          |    2 +-
 dojox/dtl/demos/json/blog/get_blog_3.json          |    2 +-
 dojox/dtl/demos/json/blog/get_blog_list.json       |    2 +-
 dojox/dtl/demos/json/blog/get_page_about.json      |    2 +-
 dojox/dtl/demos/json/fruit.json                    |    2 +-
 dojox/dtl/demos/json/morefruit.json                |    2 +-
 dojox/dtl/dom.js                                   |   89 +-
 dojox/dtl/ext-dojo/NodeList.js                     |   24 +-
 dojox/dtl/filter/dates.js                          |   27 +-
 dojox/dtl/filter/htmlstrings.js                    |   34 +-
 dojox/dtl/filter/integers.js                       |   14 +-
 dojox/dtl/filter/lists.js                          |   46 +-
 dojox/dtl/filter/logic.js                          |   23 +-
 dojox/dtl/filter/misc.js                           |   25 +-
 dojox/dtl/filter/strings.js                        |   89 +-
 dojox/dtl/render/dom.js                            |   26 +-
 dojox/dtl/render/html.js                           |   14 +-
 dojox/dtl/tag/date.js                              |   22 +-
 dojox/dtl/tag/loader.js                            |   14 +-
 dojox/dtl/tag/logic.js                             |   26 +-
 dojox/dtl/tag/loop.js                              |   18 +-
 dojox/dtl/tag/misc.js                              |   23 +-
 dojox/dtl/tests/module.js                          |    3 +-
 dojox/dtl/tests/templated.js                       |   25 +
 dojox/dtl/tests/templates/base.html                |    2 +-
 dojox/dtl/tests/templates/hello.html               |    2 +-
 dojox/dtl/tests/templates/pocket.html              |    2 +-
 dojox/dtl/tests/templates/pocket2.html             |    2 +-
 dojox/dtl/tests/text/filter.js                     |   14 +-
 dojox/dtl/tests/text/tag.js                        |    7 +
 dojox/dtl/utils/date.js                            |   22 +-
 dojox/editor/plugins/AutoSave.js                   |   35 +-
 dojox/editor/plugins/AutoUrlLink.js                |   22 +-
 dojox/editor/plugins/Blockquote.js                 |   40 +-
 dojox/editor/plugins/Breadcrumb.js                 |   57 +-
 dojox/editor/plugins/CollapsibleToolbar.js         |   20 +-
 dojox/editor/plugins/EntityPalette.js              |   30 +-
 dojox/editor/plugins/FindReplace.js                |   80 +-
 dojox/editor/plugins/InsertAnchor.js               |   67 +-
 dojox/editor/plugins/InsertEntity.js               |   13 +-
 dojox/editor/plugins/LocalImage.js                 |   47 +-
 dojox/editor/plugins/NormalizeIndentOutdent.js     |   37 +-
 dojox/editor/plugins/NormalizeStyle.js             |  108 +-
 dojox/editor/plugins/PageBreak.js                  |   21 +-
 dojox/editor/plugins/PasteFromWord.js              |   32 +-
 dojox/editor/plugins/PrettyPrint.js                |   17 +-
 dojox/editor/plugins/Preview.js                    |   17 +-
 dojox/editor/plugins/ResizeTableColumn.js          |   65 +-
 dojox/editor/plugins/SafePaste.js                  |   12 +-
 dojox/editor/plugins/Save.js                       |   18 +-
 dojox/editor/plugins/ShowBlockNodes.js             |   17 +-
 dojox/editor/plugins/Smiley.js                     |   38 +-
 dojox/editor/plugins/SpellCheck.js                 |  417 +-
 dojox/editor/plugins/StatusBar.js                  |   18 +-
 dojox/editor/plugins/TablePlugins.js               |  854 +-
 dojox/editor/plugins/TextColor.js                  |   28 +-
 dojox/editor/plugins/ToolbarLineBreak.js           |   17 +-
 dojox/editor/plugins/UploadImage.js                |   46 +-
 dojox/editor/plugins/_SmileyPalette.js             |  244 +-
 dojox/editor/plugins/_SpellCheckParser.js          |    8 +-
 dojox/editor/plugins/nls/AutoSave.js               |    4 +-
 dojox/editor/plugins/nls/Blockquote.js             |    4 +-
 dojox/editor/plugins/nls/Breadcrumb.js             |    4 +-
 dojox/editor/plugins/nls/CollapsibleToolbar.js     |    4 +-
 dojox/editor/plugins/nls/FindReplace.js            |    4 +-
 dojox/editor/plugins/nls/InsertAnchor.js           |    4 +-
 dojox/editor/plugins/nls/InsertEntity.js           |    4 +-
 dojox/editor/plugins/nls/LocalImage.js             |    4 +-
 dojox/editor/plugins/nls/PageBreak.js              |    4 +-
 dojox/editor/plugins/nls/PasteFromWord.js          |    7 +-
 dojox/editor/plugins/nls/Preview.js                |    4 +-
 dojox/editor/plugins/nls/SafePaste.js              |    5 +-
 dojox/editor/plugins/nls/Save.js                   |    4 +-
 dojox/editor/plugins/nls/ShowBlockNodes.js         |    4 +-
 dojox/editor/plugins/nls/Smiley.js                 |    4 +-
 dojox/editor/plugins/nls/SpellCheck.js             |    4 +-
 dojox/editor/plugins/nls/TableDialog.js            |   10 +-
 dojox/editor/plugins/nls/TextColor.js              |    4 +-
 dojox/editor/plugins/nls/ar/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/ar/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/ar/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/ar/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/ar/FindReplace.js         |    3 -
 dojox/editor/plugins/nls/ar/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/ar/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/ar/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/ar/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/ar/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/ar/Preview.js             |    3 -
 dojox/editor/plugins/nls/ar/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/ar/Save.js                |    3 -
 dojox/editor/plugins/nls/ar/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/ar/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/ar/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/ar/TableDialog.js         |   11 +-
 dojox/editor/plugins/nls/ar/TextColor.js           |    3 -
 dojox/editor/plugins/nls/ar/latinEntities.js       |  126 +-
 dojox/editor/plugins/nls/bg/AutoSave.js            |   15 +
 dojox/editor/plugins/nls/bg/Blockquote.js          |    5 +
 dojox/editor/plugins/nls/bg/Breadcrumb.js          |   11 +
 dojox/editor/plugins/nls/bg/CollapsibleToolbar.js  |    6 +
 dojox/editor/plugins/nls/bg/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/bg/InsertAnchor.js        |   10 +
 dojox/editor/plugins/nls/bg/InsertEntity.js        |    5 +
 dojox/editor/plugins/nls/bg/LocalImage.js          |   12 +
 dojox/editor/plugins/nls/bg/PageBreak.js           |    5 +
 dojox/editor/plugins/nls/bg/PasteFromWord.js       |    6 +
 dojox/editor/plugins/nls/bg/Preview.js             |    5 +
 dojox/editor/plugins/nls/bg/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/bg/Save.js                |    5 +
 dojox/editor/plugins/nls/bg/ShowBlockNodes.js      |    5 +
 dojox/editor/plugins/nls/bg/Smiley.js              |   24 +
 dojox/editor/plugins/nls/bg/SpellCheck.js          |   18 +
 dojox/editor/plugins/nls/bg/TableDialog.js         |   33 +
 dojox/editor/plugins/nls/bg/TextColor.js           |    6 +
 dojox/editor/plugins/nls/bg/latinEntities.js       |  257 +
 dojox/editor/plugins/nls/ca/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/ca/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/ca/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/ca/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/ca/FindReplace.js         |    3 -
 dojox/editor/plugins/nls/ca/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/ca/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/ca/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/ca/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/ca/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/ca/Preview.js             |    3 -
 dojox/editor/plugins/nls/ca/Save.js                |    3 -
 dojox/editor/plugins/nls/ca/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/ca/Smiley.js              |    3 -
 dojox/editor/plugins/nls/ca/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/ca/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/ca/TextColor.js           |    3 -
 dojox/editor/plugins/nls/ca/latinEntities.js       |   72 +-
 dojox/editor/plugins/nls/cs/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/cs/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/cs/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/cs/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/cs/FindReplace.js         |    2 -
 dojox/editor/plugins/nls/cs/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/cs/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/cs/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/cs/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/cs/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/cs/Preview.js             |    3 -
 dojox/editor/plugins/nls/cs/Save.js                |    3 -
 dojox/editor/plugins/nls/cs/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/cs/Smiley.js              |    3 -
 dojox/editor/plugins/nls/cs/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/cs/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/cs/TextColor.js           |    3 -
 dojox/editor/plugins/nls/cs/latinEntities.js       |   60 +-
 dojox/editor/plugins/nls/da/AutoSave.js            |   11 +-
 dojox/editor/plugins/nls/da/Blockquote.js          |    5 +-
 dojox/editor/plugins/nls/da/Breadcrumb.js          |    5 +-
 dojox/editor/plugins/nls/da/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/da/FindReplace.js         |   21 +-
 dojox/editor/plugins/nls/da/InsertAnchor.js        |    5 +-
 dojox/editor/plugins/nls/da/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/da/LocalImage.js          |    5 +-
 dojox/editor/plugins/nls/da/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/da/PasteFromWord.js       |    9 +-
 dojox/editor/plugins/nls/da/Preview.js             |    3 -
 dojox/editor/plugins/nls/da/Save.js                |    3 -
 dojox/editor/plugins/nls/da/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/da/Smiley.js              |    3 -
 dojox/editor/plugins/nls/da/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/da/TableDialog.js         |   11 +-
 dojox/editor/plugins/nls/da/TextColor.js           |    3 -
 dojox/editor/plugins/nls/da/latinEntities.js       |  504 +-
 dojox/editor/plugins/nls/de/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/de/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/de/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/de/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/de/FindReplace.js         |    9 +-
 dojox/editor/plugins/nls/de/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/de/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/de/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/de/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/de/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/de/Preview.js             |    3 -
 dojox/editor/plugins/nls/de/SafePaste.js           |    2 +-
 dojox/editor/plugins/nls/de/Save.js                |    3 -
 dojox/editor/plugins/nls/de/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/de/Smiley.js              |   13 +-
 dojox/editor/plugins/nls/de/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/de/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/de/TextColor.js           |    3 -
 dojox/editor/plugins/nls/de/latinEntities.js       |   70 +-
 dojox/editor/plugins/nls/el/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/el/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/el/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/el/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/el/FindReplace.js         |    3 -
 dojox/editor/plugins/nls/el/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/el/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/el/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/el/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/el/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/el/Preview.js             |    3 -
 dojox/editor/plugins/nls/el/Save.js                |    3 -
 dojox/editor/plugins/nls/el/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/el/Smiley.js              |    3 -
 dojox/editor/plugins/nls/el/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/el/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/el/TextColor.js           |    3 -
 dojox/editor/plugins/nls/el/latinEntities.js       |   26 +-
 dojox/editor/plugins/nls/es/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/es/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/es/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/es/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/es/FindReplace.js         |    2 -
 dojox/editor/plugins/nls/es/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/es/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/es/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/es/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/es/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/es/Preview.js             |    3 -
 dojox/editor/plugins/nls/es/Save.js                |    3 -
 dojox/editor/plugins/nls/es/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/es/Smiley.js              |    3 -
 dojox/editor/plugins/nls/es/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/es/TableDialog.js         |   11 +-
 dojox/editor/plugins/nls/es/TextColor.js           |    3 -
 dojox/editor/plugins/nls/es/latinEntities.js       |   60 +-
 dojox/editor/plugins/nls/fi/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/fi/Blockquote.js          |    5 +-
 dojox/editor/plugins/nls/fi/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/fi/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/fi/FindReplace.js         |    5 +-
 dojox/editor/plugins/nls/fi/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/fi/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/fi/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/fi/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/fi/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/fi/Preview.js             |    3 -
 dojox/editor/plugins/nls/fi/Save.js                |    3 -
 dojox/editor/plugins/nls/fi/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/fi/Smiley.js              |    3 -
 dojox/editor/plugins/nls/fi/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/fi/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/fi/TextColor.js           |    3 -
 dojox/editor/plugins/nls/fi/latinEntities.js       |    4 -
 dojox/editor/plugins/nls/fr/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/fr/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/fr/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/fr/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/fr/FindReplace.js         |    2 -
 dojox/editor/plugins/nls/fr/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/fr/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/fr/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/fr/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/fr/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/fr/Preview.js             |    3 -
 dojox/editor/plugins/nls/fr/Save.js                |    5 +-
 dojox/editor/plugins/nls/fr/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/fr/Smiley.js              |    3 -
 dojox/editor/plugins/nls/fr/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/fr/TableDialog.js         |   32 +-
 dojox/editor/plugins/nls/fr/TextColor.js           |    3 -
 dojox/editor/plugins/nls/fr/latinEntities.js       |   16 +-
 dojox/editor/plugins/nls/he/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/he/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/he/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/he/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/he/FindReplace.js         |    3 -
 dojox/editor/plugins/nls/he/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/he/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/he/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/he/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/he/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/he/Preview.js             |    3 -
 dojox/editor/plugins/nls/he/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/he/Save.js                |    3 -
 dojox/editor/plugins/nls/he/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/he/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/he/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/he/TableDialog.js         |   13 +-
 dojox/editor/plugins/nls/he/TextColor.js           |    3 -
 dojox/editor/plugins/nls/he/latinEntities.js       |    3 -
 dojox/editor/plugins/nls/hr/PasteFromWord.js       |    4 +-
 dojox/editor/plugins/nls/hr/SafePaste.js           |    2 +-
 dojox/editor/plugins/nls/hr/ShowBlockNodes.js      |    2 +-
 dojox/editor/plugins/nls/hr/Smiley.js              |    2 +-
 dojox/editor/plugins/nls/hr/SpellCheck.js          |    2 +-
 dojox/editor/plugins/nls/hr/TableDialog.js         |   10 +-
 dojox/editor/plugins/nls/hr/latinEntities.js       |  148 +-
 dojox/editor/plugins/nls/hu/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/hu/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/hu/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/hu/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/hu/FindReplace.js         |    3 -
 dojox/editor/plugins/nls/hu/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/hu/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/hu/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/hu/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/hu/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/hu/Preview.js             |    3 -
 dojox/editor/plugins/nls/hu/Save.js                |    3 -
 dojox/editor/plugins/nls/hu/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/hu/Smiley.js              |    3 -
 dojox/editor/plugins/nls/hu/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/hu/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/hu/TextColor.js           |    3 -
 dojox/editor/plugins/nls/hu/latinEntities.js       |   74 +-
 dojox/editor/plugins/nls/it/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/it/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/it/Breadcrumb.js          |   11 +-
 dojox/editor/plugins/nls/it/CollapsibleToolbar.js  |    7 +-
 dojox/editor/plugins/nls/it/FindReplace.js         |   19 +-
 dojox/editor/plugins/nls/it/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/it/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/it/LocalImage.js          |    7 +-
 dojox/editor/plugins/nls/it/PageBreak.js           |    5 +-
 dojox/editor/plugins/nls/it/PasteFromWord.js       |    7 +-
 dojox/editor/plugins/nls/it/Preview.js             |    3 -
 dojox/editor/plugins/nls/it/Save.js                |    3 -
 dojox/editor/plugins/nls/it/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/it/Smiley.js              |    5 +-
 dojox/editor/plugins/nls/it/SpellCheck.js          |   13 +-
 dojox/editor/plugins/nls/it/TableDialog.js         |   25 +-
 dojox/editor/plugins/nls/it/TextColor.js           |    3 -
 dojox/editor/plugins/nls/it/latinEntities.js       |   18 +-
 dojox/editor/plugins/nls/ja/AutoSave.js            |    2 -
 dojox/editor/plugins/nls/ja/Blockquote.js          |    2 -
 dojox/editor/plugins/nls/ja/Breadcrumb.js          |   15 +-
 dojox/editor/plugins/nls/ja/CollapsibleToolbar.js  |    6 +-
 dojox/editor/plugins/nls/ja/FindReplace.js         |   10 +-
 dojox/editor/plugins/nls/ja/InsertAnchor.js        |    4 +-
 dojox/editor/plugins/nls/ja/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/ja/LocalImage.js          |    6 +-
 dojox/editor/plugins/nls/ja/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/ja/PasteFromWord.js       |    8 +-
 dojox/editor/plugins/nls/ja/Preview.js             |    3 -
 dojox/editor/plugins/nls/ja/Save.js                |    3 -
 dojox/editor/plugins/nls/ja/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/ja/Smiley.js              |   29 +-
 dojox/editor/plugins/nls/ja/SpellCheck.js          |    4 +-
 dojox/editor/plugins/nls/ja/TableDialog.js         |   12 +-
 dojox/editor/plugins/nls/ja/TextColor.js           |    2 -
 dojox/editor/plugins/nls/ja/latinEntities.js       |  152 +-
 dojox/editor/plugins/nls/kk/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/kk/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/kk/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/kk/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/kk/FindReplace.js         |    3 -
 dojox/editor/plugins/nls/kk/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/kk/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/kk/LocalImage.js          |    7 +-
 dojox/editor/plugins/nls/kk/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/kk/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/kk/Preview.js             |    3 -
 dojox/editor/plugins/nls/kk/Save.js                |    3 -
 dojox/editor/plugins/nls/kk/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/kk/Smiley.js              |   13 +-
 dojox/editor/plugins/nls/kk/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/kk/TableDialog.js         |   15 +-
 dojox/editor/plugins/nls/kk/TextColor.js           |    3 -
 dojox/editor/plugins/nls/kk/latinEntities.js       |  132 +-
 dojox/editor/plugins/nls/ko/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/ko/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/ko/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/ko/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/ko/FindReplace.js         |    8 +-
 dojox/editor/plugins/nls/ko/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/ko/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/ko/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/ko/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/ko/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/ko/Preview.js             |    3 -
 dojox/editor/plugins/nls/ko/Save.js                |    3 -
 dojox/editor/plugins/nls/ko/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/ko/Smiley.js              |    2 -
 dojox/editor/plugins/nls/ko/SpellCheck.js          |    9 +-
 dojox/editor/plugins/nls/ko/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/ko/TextColor.js           |    3 -
 dojox/editor/plugins/nls/ko/latinEntities.js       |  402 +-
 dojox/editor/plugins/nls/latinEntities.js          |    4 +-
 dojox/editor/plugins/nls/nb/AutoSave.js            |    2 -
 dojox/editor/plugins/nls/nb/Blockquote.js          |    2 -
 dojox/editor/plugins/nls/nb/Breadcrumb.js          |    2 -
 dojox/editor/plugins/nls/nb/CollapsibleToolbar.js  |    2 -
 dojox/editor/plugins/nls/nb/FindReplace.js         |    2 -
 dojox/editor/plugins/nls/nb/InsertAnchor.js        |    2 -
 dojox/editor/plugins/nls/nb/InsertEntity.js        |    2 -
 dojox/editor/plugins/nls/nb/LocalImage.js          |    2 -
 dojox/editor/plugins/nls/nb/PageBreak.js           |    2 -
 dojox/editor/plugins/nls/nb/PasteFromWord.js       |    4 -
 dojox/editor/plugins/nls/nb/Preview.js             |    2 -
 dojox/editor/plugins/nls/nb/Save.js                |    2 -
 dojox/editor/plugins/nls/nb/ShowBlockNodes.js      |    2 -
 dojox/editor/plugins/nls/nb/Smiley.js              |    4 +-
 dojox/editor/plugins/nls/nb/SpellCheck.js          |    2 -
 dojox/editor/plugins/nls/nb/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/nb/TextColor.js           |    2 -
 dojox/editor/plugins/nls/nb/latinEntities.js       |    5 +-
 dojox/editor/plugins/nls/nl/AutoSave.js            |    7 +-
 dojox/editor/plugins/nls/nl/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/nl/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/nl/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/nl/FindReplace.js         |    3 -
 dojox/editor/plugins/nls/nl/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/nl/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/nl/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/nl/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/nl/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/nl/Preview.js             |    3 -
 dojox/editor/plugins/nls/nl/SafePaste.js           |    2 +-
 dojox/editor/plugins/nls/nl/Save.js                |    3 -
 dojox/editor/plugins/nls/nl/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/nl/Smiley.js              |    5 +-
 dojox/editor/plugins/nls/nl/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/nl/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/nl/TextColor.js           |    3 -
 dojox/editor/plugins/nls/nl/latinEntities.js       |    4 -
 dojox/editor/plugins/nls/pl/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/pl/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/pl/Breadcrumb.js          |    5 +-
 dojox/editor/plugins/nls/pl/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/pl/FindReplace.js         |    7 +-
 dojox/editor/plugins/nls/pl/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/pl/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/pl/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/pl/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/pl/PasteFromWord.js       |    7 +-
 dojox/editor/plugins/nls/pl/Preview.js             |    3 -
 dojox/editor/plugins/nls/pl/Save.js                |    3 -
 dojox/editor/plugins/nls/pl/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/pl/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/pl/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/pl/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/pl/TextColor.js           |    3 -
 dojox/editor/plugins/nls/pl/latinEntities.js       |  114 +-
 dojox/editor/plugins/nls/pt-pt/AutoSave.js         |    3 -
 dojox/editor/plugins/nls/pt-pt/Blockquote.js       |    3 -
 dojox/editor/plugins/nls/pt-pt/Breadcrumb.js       |    3 -
 .../editor/plugins/nls/pt-pt/CollapsibleToolbar.js |    3 -
 dojox/editor/plugins/nls/pt-pt/FindReplace.js      |    3 -
 dojox/editor/plugins/nls/pt-pt/InsertAnchor.js     |    3 -
 dojox/editor/plugins/nls/pt-pt/InsertEntity.js     |    3 -
 dojox/editor/plugins/nls/pt-pt/LocalImage.js       |    3 -
 dojox/editor/plugins/nls/pt-pt/PageBreak.js        |    3 -
 dojox/editor/plugins/nls/pt-pt/PasteFromWord.js    |    5 -
 dojox/editor/plugins/nls/pt-pt/Preview.js          |    3 -
 dojox/editor/plugins/nls/pt-pt/SafePaste.js        |    5 +
 dojox/editor/plugins/nls/pt-pt/Save.js             |    3 -
 dojox/editor/plugins/nls/pt-pt/ShowBlockNodes.js   |    3 -
 dojox/editor/plugins/nls/pt-pt/Smiley.js           |    6 +-
 dojox/editor/plugins/nls/pt-pt/SpellCheck.js       |    3 -
 dojox/editor/plugins/nls/pt-pt/TableDialog.js      |    9 +-
 dojox/editor/plugins/nls/pt-pt/TextColor.js        |    3 -
 dojox/editor/plugins/nls/pt-pt/latinEntities.js    |   56 +-
 dojox/editor/plugins/nls/pt/AutoSave.js            |    2 -
 dojox/editor/plugins/nls/pt/Blockquote.js          |    2 -
 dojox/editor/plugins/nls/pt/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/pt/CollapsibleToolbar.js  |    2 -
 dojox/editor/plugins/nls/pt/FindReplace.js         |    6 +-
 dojox/editor/plugins/nls/pt/InsertAnchor.js        |    4 +-
 dojox/editor/plugins/nls/pt/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/pt/LocalImage.js          |    2 -
 dojox/editor/plugins/nls/pt/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/pt/PasteFromWord.js       |    4 -
 dojox/editor/plugins/nls/pt/Preview.js             |    5 +-
 dojox/editor/plugins/nls/pt/Save.js                |    3 -
 dojox/editor/plugins/nls/pt/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/pt/Smiley.js              |    2 -
 dojox/editor/plugins/nls/pt/SpellCheck.js          |    2 -
 dojox/editor/plugins/nls/pt/TableDialog.js         |   10 +-
 dojox/editor/plugins/nls/pt/TextColor.js           |    4 +-
 dojox/editor/plugins/nls/pt/latinEntities.js       |   71 +-
 dojox/editor/plugins/nls/ro/AutoSave.js            |   15 +-
 dojox/editor/plugins/nls/ro/Blockquote.js          |    5 +-
 dojox/editor/plugins/nls/ro/Breadcrumb.js          |    9 +-
 dojox/editor/plugins/nls/ro/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/ro/FindReplace.js         |   17 +-
 dojox/editor/plugins/nls/ro/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/ro/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/ro/LocalImage.js          |    9 +-
 dojox/editor/plugins/nls/ro/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/ro/PasteFromWord.js       |    7 +-
 dojox/editor/plugins/nls/ro/Preview.js             |    3 -
 dojox/editor/plugins/nls/ro/SafePaste.js           |    2 +-
 dojox/editor/plugins/nls/ro/Save.js                |    3 -
 dojox/editor/plugins/nls/ro/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/ro/Smiley.js              |    3 -
 dojox/editor/plugins/nls/ro/SpellCheck.js          |   17 +-
 dojox/editor/plugins/nls/ro/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/ro/TextColor.js           |    3 -
 dojox/editor/plugins/nls/ro/latinEntities.js       |  338 +-
 dojox/editor/plugins/nls/ru/AutoSave.js            |    5 +-
 dojox/editor/plugins/nls/ru/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/ru/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/ru/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/ru/FindReplace.js         |    3 -
 dojox/editor/plugins/nls/ru/InsertAnchor.js        |    5 +-
 dojox/editor/plugins/nls/ru/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/ru/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/ru/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/ru/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/ru/Preview.js             |    3 -
 dojox/editor/plugins/nls/ru/SafePaste.js           |    2 +-
 dojox/editor/plugins/nls/ru/Save.js                |    3 -
 dojox/editor/plugins/nls/ru/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/ru/Smiley.js              |    5 +-
 dojox/editor/plugins/nls/ru/SpellCheck.js          |    7 +-
 dojox/editor/plugins/nls/ru/TableDialog.js         |   15 +-
 dojox/editor/plugins/nls/ru/TextColor.js           |    5 +-
 dojox/editor/plugins/nls/ru/latinEntities.js       |   18 +-
 dojox/editor/plugins/nls/sk/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/sk/Blockquote.js          |    5 +-
 dojox/editor/plugins/nls/sk/Breadcrumb.js          |    7 +-
 dojox/editor/plugins/nls/sk/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/sk/FindReplace.js         |    3 -
 dojox/editor/plugins/nls/sk/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/sk/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/sk/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/sk/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/sk/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/sk/Preview.js             |    3 -
 dojox/editor/plugins/nls/sk/Save.js                |    3 -
 dojox/editor/plugins/nls/sk/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/sk/Smiley.js              |    3 -
 dojox/editor/plugins/nls/sk/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/sk/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/sk/TextColor.js           |    3 -
 dojox/editor/plugins/nls/sk/latinEntities.js       |   14 +-
 dojox/editor/plugins/nls/sl/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/sl/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/sl/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/sl/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/sl/FindReplace.js         |   23 +-
 dojox/editor/plugins/nls/sl/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/sl/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/sl/LocalImage.js          |   17 +-
 dojox/editor/plugins/nls/sl/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/sl/PasteFromWord.js       |    7 +-
 dojox/editor/plugins/nls/sl/Preview.js             |    3 -
 dojox/editor/plugins/nls/sl/SafePaste.js           |    2 +-
 dojox/editor/plugins/nls/sl/Save.js                |    3 -
 dojox/editor/plugins/nls/sl/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/sl/Smiley.js              |    3 -
 dojox/editor/plugins/nls/sl/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/sl/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/sl/TextColor.js           |    3 -
 dojox/editor/plugins/nls/sl/latinEntities.js       |  498 +-
 dojox/editor/plugins/nls/sv/AutoSave.js            |   19 +-
 dojox/editor/plugins/nls/sv/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/sv/Breadcrumb.js          |    5 +-
 dojox/editor/plugins/nls/sv/CollapsibleToolbar.js  |    7 +-
 dojox/editor/plugins/nls/sv/FindReplace.js         |   19 +-
 dojox/editor/plugins/nls/sv/InsertAnchor.js        |    7 +-
 dojox/editor/plugins/nls/sv/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/sv/LocalImage.js          |   11 +-
 dojox/editor/plugins/nls/sv/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/sv/PasteFromWord.js       |    7 +-
 dojox/editor/plugins/nls/sv/Preview.js             |    5 +-
 dojox/editor/plugins/nls/sv/Save.js                |    3 -
 dojox/editor/plugins/nls/sv/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/sv/Smiley.js              |   25 +-
 dojox/editor/plugins/nls/sv/SpellCheck.js          |   15 +-
 dojox/editor/plugins/nls/sv/TableDialog.js         |   11 +-
 dojox/editor/plugins/nls/sv/TextColor.js           |    5 +-
 dojox/editor/plugins/nls/sv/latinEntities.js       |  446 +-
 dojox/editor/plugins/nls/th/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/th/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/th/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/th/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/th/FindReplace.js         |    3 -
 dojox/editor/plugins/nls/th/InsertAnchor.js        |    7 +-
 dojox/editor/plugins/nls/th/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/th/LocalImage.js          |    5 +-
 dojox/editor/plugins/nls/th/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/th/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/th/Preview.js             |    3 -
 dojox/editor/plugins/nls/th/SafePaste.js           |    2 +-
 dojox/editor/plugins/nls/th/Save.js                |    3 -
 dojox/editor/plugins/nls/th/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/th/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/th/SpellCheck.js          |    5 +-
 dojox/editor/plugins/nls/th/TableDialog.js         |   23 +-
 dojox/editor/plugins/nls/th/TextColor.js           |    3 -
 dojox/editor/plugins/nls/th/latinEntities.js       |  146 +-
 dojox/editor/plugins/nls/tr/AutoSave.js            |    3 -
 dojox/editor/plugins/nls/tr/Blockquote.js          |    3 -
 dojox/editor/plugins/nls/tr/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/tr/CollapsibleToolbar.js  |    3 -
 dojox/editor/plugins/nls/tr/FindReplace.js         |    3 -
 dojox/editor/plugins/nls/tr/InsertAnchor.js        |    3 -
 dojox/editor/plugins/nls/tr/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/tr/LocalImage.js          |    3 -
 dojox/editor/plugins/nls/tr/PageBreak.js           |    3 -
 dojox/editor/plugins/nls/tr/PasteFromWord.js       |    5 -
 dojox/editor/plugins/nls/tr/Preview.js             |    3 -
 dojox/editor/plugins/nls/tr/Save.js                |    3 -
 dojox/editor/plugins/nls/tr/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/tr/Smiley.js              |    3 -
 dojox/editor/plugins/nls/tr/SpellCheck.js          |    3 -
 dojox/editor/plugins/nls/tr/TableDialog.js         |    9 +-
 dojox/editor/plugins/nls/tr/TextColor.js           |    3 -
 dojox/editor/plugins/nls/tr/latinEntities.js       |   30 +-
 dojox/editor/plugins/nls/uk/AutoSave.js            |   15 +
 dojox/editor/plugins/nls/uk/Blockquote.js          |    5 +
 dojox/editor/plugins/nls/uk/Breadcrumb.js          |   11 +
 dojox/editor/plugins/nls/uk/CollapsibleToolbar.js  |    6 +
 dojox/editor/plugins/nls/uk/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/uk/InsertAnchor.js        |   10 +
 dojox/editor/plugins/nls/uk/InsertEntity.js        |    5 +
 dojox/editor/plugins/nls/uk/LocalImage.js          |   12 +
 dojox/editor/plugins/nls/uk/PageBreak.js           |    5 +
 dojox/editor/plugins/nls/uk/PasteFromWord.js       |    6 +
 dojox/editor/plugins/nls/uk/Preview.js             |    5 +
 dojox/editor/plugins/nls/uk/SafePaste.js           |    5 +
 dojox/editor/plugins/nls/uk/Save.js                |    5 +
 dojox/editor/plugins/nls/uk/ShowBlockNodes.js      |    5 +
 dojox/editor/plugins/nls/uk/Smiley.js              |   24 +
 dojox/editor/plugins/nls/uk/SpellCheck.js          |   18 +
 dojox/editor/plugins/nls/uk/TableDialog.js         |   33 +
 dojox/editor/plugins/nls/uk/TextColor.js           |    6 +
 dojox/editor/plugins/nls/uk/latinEntities.js       |  257 +
 dojox/editor/plugins/nls/zh-tw/AutoSave.js         |    2 -
 dojox/editor/plugins/nls/zh-tw/Blockquote.js       |    2 -
 dojox/editor/plugins/nls/zh-tw/Breadcrumb.js       |    3 -
 .../editor/plugins/nls/zh-tw/CollapsibleToolbar.js |    2 -
 dojox/editor/plugins/nls/zh-tw/FindReplace.js      |    2 -
 dojox/editor/plugins/nls/zh-tw/InsertAnchor.js     |    2 -
 dojox/editor/plugins/nls/zh-tw/InsertEntity.js     |    3 -
 dojox/editor/plugins/nls/zh-tw/LocalImage.js       |    2 -
 dojox/editor/plugins/nls/zh-tw/PageBreak.js        |    3 -
 dojox/editor/plugins/nls/zh-tw/PasteFromWord.js    |    4 -
 dojox/editor/plugins/nls/zh-tw/Preview.js          |    3 -
 dojox/editor/plugins/nls/zh-tw/SafePaste.js        |    2 +-
 dojox/editor/plugins/nls/zh-tw/Save.js             |    3 -
 dojox/editor/plugins/nls/zh-tw/ShowBlockNodes.js   |    3 -
 dojox/editor/plugins/nls/zh-tw/Smiley.js           |    5 +-
 dojox/editor/plugins/nls/zh-tw/SpellCheck.js       |    2 -
 dojox/editor/plugins/nls/zh-tw/TableDialog.js      |   10 +-
 dojox/editor/plugins/nls/zh-tw/TextColor.js        |    2 -
 dojox/editor/plugins/nls/zh-tw/latinEntities.js    |    4 -
 dojox/editor/plugins/nls/zh/AutoSave.js            |    4 +-
 dojox/editor/plugins/nls/zh/Blockquote.js          |    2 -
 dojox/editor/plugins/nls/zh/Breadcrumb.js          |    3 -
 dojox/editor/plugins/nls/zh/CollapsibleToolbar.js  |    2 -
 dojox/editor/plugins/nls/zh/FindReplace.js         |   16 +-
 dojox/editor/plugins/nls/zh/InsertAnchor.js        |    6 +-
 dojox/editor/plugins/nls/zh/InsertEntity.js        |    3 -
 dojox/editor/plugins/nls/zh/LocalImage.js          |    4 +-
 dojox/editor/plugins/nls/zh/PageBreak.js           |    5 +-
 dojox/editor/plugins/nls/zh/PasteFromWord.js       |    6 +-
 dojox/editor/plugins/nls/zh/Preview.js             |    3 -
 dojox/editor/plugins/nls/zh/Save.js                |    3 -
 dojox/editor/plugins/nls/zh/ShowBlockNodes.js      |    3 -
 dojox/editor/plugins/nls/zh/Smiley.js              |    5 +-
 dojox/editor/plugins/nls/zh/SpellCheck.js          |    6 +-
 dojox/editor/plugins/nls/zh/TableDialog.js         |   10 +-
 dojox/editor/plugins/nls/zh/TextColor.js           |    4 +-
 dojox/editor/plugins/nls/zh/latinEntities.js       |  141 +-
 dojox/editor/plugins/resources/css/SpellCheck.css  |    3 -
 dojox/editor/plugins/resources/editorPlugins.css   |   11 +-
 dojox/editor/plugins/resources/images/checking.gif |  Bin 0 -> 348 bytes
 dojox/editor/plugins/resources/insertTable.html    |    4 +-
 dojox/editor/plugins/resources/modifyTable.html    |    4 +-
 dojox/editor/tests/editorAutoSave.html             |    2 +-
 dojox/editor/tests/editorAutoUrlLink.html          |    2 +-
 dojox/editor/tests/editorBlockquote.html           |    2 +-
 dojox/editor/tests/editorBreadcrumb.html           |    2 +-
 dojox/editor/tests/editorCollapsibleToolbar.html   |    2 +-
 dojox/editor/tests/editorFindReplace.html          |    2 +-
 dojox/editor/tests/editorInsertAnchor.html         |    2 +-
 dojox/editor/tests/editorInsertEntity.html         |    2 +-
 dojox/editor/tests/editorLocalImage.html           |    2 +-
 .../editor/tests/editorNormalizeIndentOutdent.html |    2 +-
 dojox/editor/tests/editorNormalizeStyle.html       |    2 +-
 dojox/editor/tests/editorPageBreak.html            |    2 +-
 dojox/editor/tests/editorPasteFromWord.html        |    2 +-
 dojox/editor/tests/editorPrettyPrint.html          |    2 +-
 dojox/editor/tests/editorPreview.html              |    2 +-
 dojox/editor/tests/editorResizeTableColumn.html    |    1 -
 dojox/editor/tests/editorSafePaste.html            |    2 +-
 dojox/editor/tests/editorSave.html                 |    2 +-
 dojox/editor/tests/editorShowBlockNodes.html       |    2 +-
 dojox/editor/tests/editorSmileyPlugin.html         |    2 +-
 dojox/editor/tests/editorSpellCheck.html           |    2 +-
 dojox/editor/tests/editorStatusBar.html            |    2 +-
 dojox/editor/tests/editorTablePlugs.html           |   95 +-
 dojox/editor/tests/editorTextColor.html            |    2 +-
 dojox/editor/tests/editorToolbarLineBreak.html     |    2 +-
 dojox/editor/tests/editorUploadPlug.html           |    1 -
 dojox/editor/tests/robot/Editor_Smiley.html        |    6 +-
 dojox/editor/tests/testPluginsAll.html             |    2 +-
 dojox/embed/Flash.js                               |  155 +-
 dojox/embed/Object.js                              |   55 +-
 dojox/embed/Quicktime.js                           |   96 +-
 dojox/embed/flashVars.js                           |   22 +-
 dojox/embed/tests/object.html                      |    2 +-
 dojox/embed/tests/quicktime.html                   |   22 +-
 dojox/embed/tests/resources/sample.3gp             |  Bin 0 -> 28561 bytes
 dojox/encoding/ascii85.js                          |   15 +-
 dojox/encoding/base64.js                           |   11 +-
 dojox/encoding/bits.js                             |    3 -
 dojox/encoding/compression/lzw.js                  |    3 -
 dojox/encoding/compression/splay.js                |    3 -
 dojox/encoding/crypto/Blowfish.js                  |   23 +-
 dojox/encoding/crypto/RSAKey-ext.js                |   15 +-
 dojox/encoding/crypto/RSAKey.js                    |   10 +-
 dojox/encoding/crypto/SimpleAES.js                 |   66 +-
 dojox/encoding/crypto/_base.js                     |    7 +-
 dojox/encoding/digests/MD5.js                      |   64 +-
 dojox/encoding/digests/SHA1.js                     |   47 +-
 dojox/encoding/digests/SHA224.js                   |   68 +
 dojox/encoding/digests/SHA256.js                   |   68 +
 dojox/encoding/digests/SHA384.js                   |   71 +
 dojox/encoding/digests/SHA512.js                   |   70 +
 dojox/encoding/digests/_base.js                    |   67 +-
 dojox/encoding/digests/_sha-32.js                  |  138 +
 dojox/encoding/digests/_sha-64.js                  |  221 +
 dojox/encoding/easy64.js                           |   16 +-
 dojox/encoding/tests/compression/colors2.html      |    2 +-
 dojox/encoding/tests/compression/colors3.html      |    2 +-
 dojox/encoding/tests/compression/test.html         |    2 +-
 dojox/encoding/tests/compression/vq.html           |    2 +-
 dojox/encoding/tests/digests/SHA224.js             |   18 +
 dojox/encoding/tests/digests/SHA256.js             |   14 +
 dojox/encoding/tests/digests/SHA384.js             |   36 +
 dojox/encoding/tests/digests/SHA512.js             |   22 +
 dojox/encoding/tests/digests/_base.js              |    2 +-
 dojox/flash.js                                     |   11 +-
 dojox/flash/_base.js                               |  259 +-
 dojox/flash/tests/test_flash.html                  |    2 +-
 dojox/form/BusyButton.js                           |   34 +-
 dojox/form/CheckedMultiSelect.js                   |   67 +-
 dojox/form/DateTextBox.js                          |  199 +-
 dojox/form/DayTextBox.js                           |   52 +
 dojox/form/DropDownStack.js                        |   15 +-
 dojox/form/FileInput.js                            |   42 +-
 dojox/form/FileInputAuto.js                        |   95 +-
 dojox/form/FileInputBlind.js                       |    2 +-
 dojox/form/FilePickerTextBox.js                    |   46 +-
 dojox/form/FileUploader.js                         |  333 +-
 dojox/form/ListInput.js                            |  121 +-
 dojox/form/Manager.js                              |   39 +-
 dojox/form/MonthTextBox.js                         |   69 +
 dojox/form/MultiComboBox.js                        |   12 +-
 dojox/form/PasswordValidator.js                    |   41 +-
 dojox/form/README                                  |   14 +-
 dojox/form/RadioStack.js                           |   14 +-
 dojox/form/RangeSlider.js                          |   43 +-
 dojox/form/Rating.js                               |  191 +-
 dojox/form/TimeSpinner.js                          |   39 +-
 dojox/form/TriStateCheckBox.js                     |  209 +-
 dojox/form/Uploader.js                             |  711 +-
 dojox/form/YearTextBox.js                          |   63 +
 dojox/form/_SelectStackMixin.js                    |   34 +-
 dojox/form/manager/_ClassMixin.js                  |   12 +-
 dojox/form/manager/_DisplayMixin.js                |    8 +-
 dojox/form/manager/_EnableMixin.js                 |    8 +-
 dojox/form/manager/_FormMixin.js                   |   11 +-
 dojox/form/manager/_Mixin.js                       |   96 +-
 dojox/form/manager/_NodeMixin.js                   |   66 +-
 dojox/form/manager/_ValueMixin.js                  |    8 +-
 dojox/form/nls/CheckedMultiSelect.js               |    5 +-
 dojox/form/nls/PasswordValidator.js                |    2 +
 dojox/form/nls/Uploader.js                         |    5 +-
 dojox/form/nls/ar/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/ar/PasswordValidator.js             |    4 +-
 dojox/form/nls/ar/Uploader.js                      |    5 +
 dojox/form/nls/az/PasswordValidator.js             |    4 +-
 dojox/form/nls/bg/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/bg/PasswordValidator.js             |    6 +
 dojox/form/nls/bg/Uploader.js                      |    5 +
 dojox/form/nls/ca/PasswordValidator.js             |    6 +-
 dojox/form/nls/cs/PasswordValidator.js             |    6 +-
 dojox/form/nls/da/PasswordValidator.js             |    8 +-
 dojox/form/nls/de/CheckedMultiSelect.js            |    4 +-
 dojox/form/nls/de/PasswordValidator.js             |    6 +-
 dojox/form/nls/el/PasswordValidator.js             |    6 +-
 dojox/form/nls/es/PasswordValidator.js             |    7 +-
 dojox/form/nls/fi/PasswordValidator.js             |    7 +-
 dojox/form/nls/fr/PasswordValidator.js             |    7 +-
 dojox/form/nls/he/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/he/PasswordValidator.js             |    7 +-
 dojox/form/nls/he/Uploader.js                      |    5 +
 dojox/form/nls/hu/PasswordValidator.js             |    7 +-
 dojox/form/nls/it/PasswordValidator.js             |    7 +-
 dojox/form/nls/ja/PasswordValidator.js             |    7 +-
 dojox/form/nls/kk/PasswordValidator.js             |    5 +-
 dojox/form/nls/ko/PasswordValidator.js             |    7 +-
 dojox/form/nls/nb/PasswordValidator.js             |    7 +-
 dojox/form/nls/nl/CheckedMultiSelect.js            |    2 +-
 dojox/form/nls/nl/PasswordValidator.js             |    7 +-
 dojox/form/nls/pl/PasswordValidator.js             |    7 +-
 dojox/form/nls/pt-pt/CheckedMultiSelect.js         |    6 +
 dojox/form/nls/pt-pt/PasswordValidator.js          |    7 +-
 dojox/form/nls/pt-pt/Uploader.js                   |    5 +
 dojox/form/nls/pt/PasswordValidator.js             |    7 +-
 dojox/form/nls/ro/PasswordValidator.js             |    9 +-
 dojox/form/nls/ru/CheckedMultiSelect.js            |    4 +-
 dojox/form/nls/ru/PasswordValidator.js             |    7 +-
 dojox/form/nls/sk/PasswordValidator.js             |    7 +-
 dojox/form/nls/sl/PasswordValidator.js             |    7 +-
 dojox/form/nls/sl/Uploader.js                      |    2 +-
 dojox/form/nls/sv/PasswordValidator.js             |    9 +-
 dojox/form/nls/th/PasswordValidator.js             |    7 +-
 dojox/form/nls/tr/PasswordValidator.js             |    7 +-
 dojox/form/nls/uk/CheckedMultiSelect.js            |    6 +
 dojox/form/nls/uk/PasswordValidator.js             |    6 +
 dojox/form/nls/uk/Uploader.js                      |    5 +
 dojox/form/nls/zh-tw/CheckedMultiSelect.js         |    4 +-
 dojox/form/nls/zh-tw/PasswordValidator.js          |    7 +-
 dojox/form/nls/zh/PasswordValidator.js             |    7 +-
 dojox/form/resources/CheckedMultiSelect.css        |    8 +-
 dojox/form/resources/FileInput.css                 |   11 +-
 dojox/form/resources/HorizontalRangeSlider.html    |    6 +-
 dojox/form/resources/ListInput.css                 |    2 +-
 dojox/form/resources/TriStateCheckBox.css          |    6 -
 dojox/form/resources/TriStateCheckBox.html         |    4 +-
 dojox/form/resources/Uploader.html                 |   15 +-
 dojox/form/resources/UploaderFileList.html         |   17 +
 dojox/form/resources/VerticalRangeSlider.html      |    5 +-
 .../resources/_CheckedMultiSelectMenuItem.html     |    2 +-
 dojox/form/tests/UploadFile.php.disabled           |   19 +-
 dojox/form/tests/images/attach.png                 |  Bin 19459 -> 0 bytes
 dojox/form/tests/images/grad.jpg                   |  Bin 361 -> 0 bytes
 dojox/form/tests/images/grad_down.jpg              |  Bin 352 -> 0 bytes
 dojox/form/tests/images/grad_over.jpg              |  Bin 381 -> 0 bytes
 dojox/form/tests/images/rndBtnSprite.png           |  Bin 9402 -> 0 bytes
 dojox/form/tests/images/rndBtn_down.png            |  Bin 4035 -> 0 bytes
 dojox/form/tests/images/rndBtn_norm.png            |  Bin 3977 -> 0 bytes
 dojox/form/tests/images/rndBtn_over.png            |  Bin 3945 -> 0 bytes
 dojox/form/tests/test_BusyButton.html              |    2 +-
 dojox/form/tests/test_CheckedMultiSelect.html      |  446 +-
 .../tests/test_CheckedMultiSelectDropDown.html     |   30 +-
 .../tests/test_CheckedMultiSelectNonDropDown.html  |   30 +-
 dojox/form/tests/test_DateTextBox.html             |   70 +-
 dojox/form/tests/test_FileInput.html               |    2 +-
 dojox/form/tests/test_FilePickerTextBox.html       |    4 +-
 dojox/form/tests/test_FileUploader.html            |    2 +-
 dojox/form/tests/test_ListInput.html               |   28 +-
 dojox/form/tests/test_Manager1.html                |   19 +-
 dojox/form/tests/test_Manager_amd.html             |  236 +
 dojox/form/tests/test_MultiComboBox.html           |    6 +-
 dojox/form/tests/test_PasswordValidator.html       |   44 +-
 dojox/form/tests/test_RangeSlider.html             |   25 +-
 dojox/form/tests/test_Rating.html                  |    6 +-
 dojox/form/tests/test_SelectStack.html             |    6 +-
 dojox/form/tests/test_TimeSpinner.html             |    2 +-
 dojox/form/tests/test_TriStateCheckbox.html        |  176 +-
 dojox/form/tests/test_Uploader.html                |  109 +-
 dojox/form/tests/test_UploaderAll.html             |    7 +-
 dojox/form/tests/test_Uploader_programmatic.html   |  211 +
 dojox/form/uploader/Base.js                        |  125 -
 dojox/form/uploader/FileList.js                    |   76 +-
 dojox/form/uploader/_Base.js                       |  116 +
 dojox/form/uploader/_Flash.js                      |  306 +
 dojox/form/uploader/_HTML5.js                      |  165 +
 dojox/form/uploader/_IFrame.js                     |   85 +
 dojox/form/uploader/plugins/Flash.js               |  308 +-
 dojox/form/uploader/plugins/HTML5.js               |  244 +-
 dojox/form/uploader/plugins/IFrame.js              |   82 +-
 dojox/fx.js                                        |    7 +
 dojox/fx/Shadow.js                                 |   42 +-
 dojox/fx/Timeline.js                               |   81 +-
 dojox/fx/_base.js                                  |   62 +-
 dojox/fx/_core.js                                  |   44 +-
 dojox/fx/easing.js                                 |    2 +-
 dojox/fx/ext-dojo/NodeList-style.js                |   44 +-
 dojox/fx/ext-dojo/NodeList.js                      |   31 +-
 dojox/fx/ext-dojo/complex.js                       |   63 +-
 dojox/fx/ext-dojo/reverse.js                       |   38 +-
 dojox/fx/flip.js                                   |   73 +-
 dojox/fx/scroll.js                                 |   15 +-
 dojox/fx/split.js                                  |  130 +-
 dojox/fx/style.js                                  |   93 +-
 dojox/fx/tests/example_Line.html                   |    2 +-
 dojox/fx/tests/example_backgroundPosition.html     |    2 +-
 dojox/fx/tests/example_dojoAnimations.html         |   30 +-
 dojox/fx/tests/example_easingChart2D.html          |    2 +-
 dojox/fx/tests/test_Nodelist-fx.html               |    6 +-
 dojox/fx/tests/test_Shadow.html                    |    2 +-
 dojox/fx/tests/test_Timeline.html                  |    2 +-
 dojox/fx/tests/test_animateClass.html              |   34 +-
 dojox/fx/tests/test_complex.html                   |    2 +-
 dojox/fx/tests/test_crossFade.html                 |    2 +-
 dojox/fx/tests/test_easing.html                    |    2 +-
 dojox/fx/tests/test_flip.html                      |    2 +-
 dojox/fx/tests/test_highlight.html                 |    2 +-
 dojox/fx/tests/test_reverse.html                   |    2 +-
 dojox/fx/tests/test_scroll.html                    |    2 +-
 dojox/fx/tests/test_sizeTo.html                    |    2 +-
 dojox/fx/tests/test_slideBy.html                   |    2 +-
 dojox/fx/tests/test_split.html                     |    2 +-
 dojox/fx/tests/test_text.html                      |    2 +-
 dojox/fx/tests/test_wipeTo.html                    |   12 +-
 dojox/fx/text.js                                   |  120 +-
 dojox/gantt/GanttChart.js                          |  505 +-
 dojox/gantt/GanttProjectControl.js                 |  886 +
 dojox/gantt/GanttProjectItem.js                    | 1027 +-
 dojox/gantt/GanttResourceItem.js                   |  875 +-
 dojox/gantt/GanttTaskControl.js                    | 1334 +
 dojox/gantt/GanttTaskItem.js                       | 1393 +-
 dojox/gantt/README                                 |   45 +
 dojox/gantt/TabMenu.js                             |  458 +-
 dojox/gantt/contextMenuTab.js                      |  362 +
 dojox/gantt/resources/gantt.css                    |  100 +-
 dojox/gantt/tests/test_Gantt.html                  |   88 +-
 dojox/gauges/AnalogArcIndicator.js                 |    6 +-
 dojox/gauges/AnalogArrowIndicator.js               |    8 +-
 dojox/gauges/AnalogCircleIndicator.js              |    8 +-
 dojox/gauges/AnalogGauge.js                        |   28 +-
 dojox/gauges/AnalogIndicatorBase.js                |   12 +-
 dojox/gauges/AnalogLineIndicator.js                |    8 +-
 dojox/gauges/AnalogNeedleIndicator.js              |    6 +-
 dojox/gauges/BarCircleIndicator.js                 |   10 +-
 dojox/gauges/BarGauge.js                           |   58 +-
 dojox/gauges/BarIndicator.js                       |    6 +-
 dojox/gauges/BarLineIndicator.js                   |   10 +-
 dojox/gauges/GlossyCircularGauge.js                |    4 -
 dojox/gauges/GlossyCircularGaugeBase.js            |  101 +-
 dojox/gauges/GlossyCircularGaugeNeedle.js          |    5 +-
 dojox/gauges/GlossyHorizontalGauge.js              |   78 +-
 dojox/gauges/GlossyHorizontalGaugeMarker.js        |   14 +-
 dojox/gauges/GlossySemiCircularGauge.js            |   10 +-
 dojox/gauges/Range.js                              |   24 +-
 dojox/gauges/TextIndicator.js                      |   16 +-
 dojox/gauges/_Gauge.js                             |  141 +-
 dojox/gauges/_Indicator.js                         |   58 +-
 dojox/geo/charting/Feature.js                      |  383 +-
 dojox/geo/charting/KeyboardInteractionSupport.js   |  289 +-
 dojox/geo/charting/Map.js                          | 1196 +-
 dojox/geo/charting/MouseInteractionSupport.js      |  680 +-
 dojox/geo/charting/TouchInteractionSupport.js      |  584 +-
 dojox/geo/charting/_Marker.js                      |  125 +-
 dojox/geo/charting/_base.js                        |   36 +-
 dojox/geo/charting/resources/data/Americas.json    |  157 +
 dojox/geo/charting/resources/data/AsiaPacific.json |  117 +
 .../charting/resources/data/ContinentalEurope.json |  217 +
 .../resources/data/EuropeMiddleEastAfrica.json     |  562 +
 dojox/geo/charting/resources/data/NOTICES          |   69 +-
 .../charting/resources/data/WorldCountries.json    |  827 +
 .../resources/data/WorldCountriesMercator.json     |  827 +
 .../charting/{resources/data => tests}/series.json |    0
 dojox/geo/charting/tests/test_europemaps.html      |   50 +
 dojox/geo/charting/tests/test_mapWithCharting.html |    3 +-
 dojox/geo/charting/tests/test_mapWithLegend.html   |    3 +-
 dojox/geo/charting/tests/test_maps.html            |   10 +-
 dojox/geo/charting/tests/test_widget.html          |  117 +-
 dojox/geo/charting/widget/Legend.js                |  175 +-
 dojox/geo/charting/widget/Map.js                   |  345 +-
 dojox/geo/openlayers/Collection.js                 |   53 +-
 dojox/geo/openlayers/Feature.js                    |   60 +-
 dojox/geo/openlayers/Geometry.js                   |   42 +-
 dojox/geo/openlayers/GeometryFeature.js            |  284 +-
 dojox/geo/openlayers/GfxLayer.js                   |  122 +-
 dojox/geo/openlayers/GreatCircle.js                |   90 +-
 dojox/geo/openlayers/JsonImport.js                 |  112 +-
 dojox/geo/openlayers/Layer.js                      |  130 +-
 dojox/geo/openlayers/LineString.js                 |   25 +-
 dojox/geo/openlayers/Map.js                        |  518 +-
 dojox/geo/openlayers/Patch.js                      |   47 +-
 dojox/geo/openlayers/Point.js                      |   28 +-
 dojox/geo/openlayers/TouchInteractionSupport.js    |  159 +-
 dojox/geo/openlayers/WidgetFeature.js              |  218 +-
 dojox/geo/openlayers/_base.js                      |   79 +
 .../tests/baseLayers/test_baseLayers.html          |  223 -
 dojox/geo/openlayers/tests/ecr/Ecr.js              |  209 -
 dojox/geo/openlayers/tests/ecr/EcrRenderer.js      |  163 -
 dojox/geo/openlayers/tests/ecr/LegsRenderer.js     |   66 -
 dojox/geo/openlayers/tests/ecr/PortRenderer.js     |   27 -
 dojox/geo/openlayers/tests/ecr/data/ecr.json       |   41 -
 dojox/geo/openlayers/tests/ecr/data/ecr2.json      |  277 -
 dojox/geo/openlayers/tests/ecr/data/ecr3.json      | 3352 --
 .../openlayers/tests/ecr/data/mapDataFixed.json    |41467 --------------------
 dojox/geo/openlayers/tests/ecr/test_ecr.html       |   88 -
 .../openlayers/tests/nonWidget/test_nonWidget.html |   17 +-
 dojox/geo/openlayers/tests/sun/Cities.js           |  310 -
 dojox/geo/openlayers/tests/sun/Sun.js              |  226 -
 dojox/geo/openlayers/tests/sun/SunDemo.js          |  298 -
 dojox/geo/openlayers/tests/sun/c.csv               |  340 -
 dojox/geo/openlayers/tests/sun/test_sun.html       |  135 -
 dojox/geo/openlayers/tests/test_bench.html         |    2 +-
 dojox/geo/openlayers/tests/test_gfx.html           |    2 +-
 dojox/geo/openlayers/tests/test_gfx2.html          |    2 +-
 dojox/geo/openlayers/tests/test_gfx_amd.html       |  169 +
 dojox/geo/openlayers/tests/test_widget.html        |    2 +-
 .../tests/widgetFeature/test_widgetFeature.html    |    2 +-
 .../widgetFeature/test_widgetFeature_amd.html      |  328 +
 dojox/geo/openlayers/widget/Map.js                 |  159 +-
 dojox/gesture/Base.js                              |   10 +-
 dojox/gesture/swipe.js                             |   15 +-
 dojox/gesture/tap.js                               |    1 +
 dojox/gesture/tests/doh/bubble.html                |    2 +-
 dojox/gesture/tests/doh/swipe.html                 |    2 +-
 dojox/gesture/tests/doh/tap.html                   |    2 +-
 dojox/gesture/tests/test_gesture.html              |   14 +-
 dojox/gfx/Moveable.js                              |  146 +-
 dojox/gfx/Mover.js                                 |   54 +-
 dojox/gfx/VectorText.js                            |  331 +-
 dojox/gfx/_base.js                                 |  808 +-
 dojox/gfx/_gfxBidiSupport.js                       |  222 +-
 dojox/gfx/arc.js                                   |   36 +-
 dojox/gfx/bezierutils.js                           |  171 +
 dojox/gfx/canvas.js                                |  832 +-
 dojox/gfx/canvasWithEvents.js                      |  999 +-
 dojox/gfx/canvasext.js                             |   39 +
 dojox/gfx/decompose.js                             |   44 +-
 dojox/gfx/demos/PI.html                            |    2 +-
 dojox/gfx/demos/beautify.html                      |    2 +-
 dojox/gfx/demos/butterfly.html                     |    2 +-
 dojox/gfx/demos/clipping.html                      |  880 +
 dojox/gfx/demos/clockWidget.html                   |    4 +-
 dojox/gfx/demos/filters.html                       |  221 +
 dojox/gfx/demos/lion.html                          |    2 +-
 dojox/gfx/demos/roundedPane.html                   |    2 +-
 dojox/gfx/demos/tiger.html                         |    2 +-
 dojox/gfx/demos/tooltip.html                       |    4 +-
 dojox/gfx/filters.js                               |  742 +
 dojox/gfx/fx.js                                    |   81 +-
 dojox/gfx/gradient.js                              |   15 +-
 dojox/gfx/gradutils.js                             |   12 +-
 dojox/gfx/matrix.js                                |  538 +-
 dojox/gfx/path.js                                  |  123 +-
 dojox/gfx/registry.js                              |   53 +
 dojox/gfx/renderer.js                              |   21 +-
 dojox/gfx/resources/gfxSvgProxyFrame.html          |    2 +-
 dojox/gfx/shape.js                                 |  854 +-
 dojox/gfx/silverlight.js                           |  465 +-
 dojox/gfx/silverlight_attach.js                    |   14 +-
 dojox/gfx/svg.js                                   |  458 +-
 dojox/gfx/svg_attach.js                            |   69 +-
 dojox/gfx/svgext.js                                |  225 +
 .../canvas/dynamicallyChangeTextCanvas.html        |    2 +-
 .../canvas/inheritFromSurfaceCanvas.html           |    2 +-
 .../canvas/test_SurfaceGroupCanvas.html            |    2 +-
 .../_gfxBidiSupport/canvas/textBidiCanvas.html     |    2 +-
 .../_gfxBidiSupport/dynamicallyChangeText.html     |    2 +-
 .../tests/_gfxBidiSupport/inheritFromSurface.html  |    2 +-
 .../dynamicallyChangeTextSilverlight.html          |    2 +-
 .../silverlight/inheritFromSurfaceSilverlight.html |    2 +-
 .../silverlight/test_SurfaceGroupSilverlight.html  |   10 +-
 .../silverlight/textBidiSilverlight.html           |    2 +-
 .../svgWeb/dynamicallyChangeTextSvgWeb.html        |    2 +-
 .../svgWeb/inheritFromSurfaceSvgWeb.html           |    2 +-
 .../svgWeb/test_SurfaceGroupSvgWeb.html            |    2 +-
 .../_gfxBidiSupport/svgWeb/textBidiSvgWeb.html     |    2 +-
 .../_gfxBidiSupport/svgWeb/textpathBidiSvgWeb.html |    2 +-
 .../tests/_gfxBidiSupport/test_SurfaceGroup.html   |    2 +-
 dojox/gfx/tests/_gfxBidiSupport/textBidi.html      |    2 +-
 dojox/gfx/tests/_gfxBidiSupport/textpathBidi.html  |    2 +-
 dojox/gfx/tests/events-canvas.html                 |    2 +-
 dojox/gfx/tests/images/maps.png                    |  Bin 0 -> 40920 bytes
 dojox/gfx/tests/matrix.js                          |   37 +
 dojox/gfx/tests/module.js                          |    6 +
 dojox/gfx/tests/performance/gfx_fill.html          |    2 +-
 dojox/gfx/tests/performance/gfx_primitives.html    |    2 +-
 dojox/gfx/tests/performance/gfx_scenes.html        |    2 +-
 dojox/gfx/tests/svgweb/README                      |    5 +-
 dojox/gfx/tests/svgweb/sample.html                 |    6 +-
 dojox/gfx/tests/svgweb/test.roundrect.html         |    2 +-
 dojox/gfx/tests/svgweb/test_arc.html               |    2 +-
 dojox/gfx/tests/svgweb/test_bezier.html            |    2 +-
 dojox/gfx/tests/svgweb/test_destroy.html           |    2 +-
 dojox/gfx/tests/svgweb/test_fill.html              |    2 +-
 dojox/gfx/tests/svgweb/test_fx.html                |    2 +-
 dojox/gfx/tests/svgweb/test_fx_shapes.html         |    2 +-
 dojox/gfx/tests/svgweb/test_gfx.html               |   12 +-
 dojox/gfx/tests/svgweb/test_gradient.html          |    2 +-
 dojox/gfx/tests/svgweb/test_group1.html            |    2 +-
 dojox/gfx/tests/svgweb/test_group2.html            |    2 +-
 dojox/gfx/tests/svgweb/test_image1.html            |    3 +-
 dojox/gfx/tests/svgweb/test_image2.html            |    2 +-
 dojox/gfx/tests/svgweb/test_image3.html            |    2 +-
 dojox/gfx/tests/svgweb/test_image4.html            |    2 +-
 dojox/gfx/tests/svgweb/test_image5.html            |    2 +-
 dojox/gfx/tests/svgweb/test_linearGradient.html    |    2 +-
 dojox/gfx/tests/svgweb/test_linestyle.html         |    2 +-
 dojox/gfx/tests/svgweb/test_pattern.html           |    2 +-
 dojox/gfx/tests/svgweb/test_poly.html              |    2 +-
 dojox/gfx/tests/svgweb/test_resize.html            |    2 +-
 dojox/gfx/tests/svgweb/test_setPath.html           |    2 +-
 dojox/gfx/tests/svgweb/test_tbbox.html             |    2 +-
 dojox/gfx/tests/svgweb/test_text.html              |    2 +-
 dojox/gfx/tests/svgweb/test_textpath.html          |    2 +-
 dojox/gfx/tests/svgweb/test_transform.html         |    2 +-
 dojox/gfx/tests/svgweb/test_utils.html             |    2 +-
 dojox/gfx/tests/svgweb/test_vectortext_draw.html   |    6 +-
 dojox/gfx/tests/svgweb/test_vectortext_load.html   |   12 +-
 dojox/gfx/tests/test_arc.html                      |    2 +-
 dojox/gfx/tests/test_base.html                     |  117 +
 dojox/gfx/tests/test_batch.html                    |  311 +
 dojox/gfx/tests/test_bezier.html                   |    2 +-
 dojox/gfx/tests/test_bubbling.html                 |  195 +-
 dojox/gfx/tests/test_canvaspolyline.html           |    4 +-
 dojox/gfx/tests/test_clip.html                     |  138 +
 dojox/gfx/tests/test_containerBBox.html            |  143 +
 dojox/gfx/tests/test_dashedstroke.html             |   79 +
 dojox/gfx/tests/test_decompose.html                |    2 +-
 dojox/gfx/tests/test_destroy.html                  |   13 +-
 dojox/gfx/tests/test_fill.html                     |    2 +-
 dojox/gfx/tests/test_filter.html                   |  105 +
 dojox/gfx/tests/test_fx.html                       |   20 +-
 dojox/gfx/tests/test_fx_shapes.html                |    2 +-
 dojox/gfx/tests/test_gfx.html                      |   16 +-
 dojox/gfx/tests/test_gfx_amd.html                  |   16 +-
 dojox/gfx/tests/test_gradient.html                 |    2 +-
 dojox/gfx/tests/test_group1.html                   |    2 +-
 dojox/gfx/tests/test_group2.html                   |    2 +-
 dojox/gfx/tests/test_image1.html                   |    2 +-
 dojox/gfx/tests/test_image2.html                   |    2 +-
 dojox/gfx/tests/test_image3.html                   |    2 +-
 dojox/gfx/tests/test_image4.html                   |    2 +-
 dojox/gfx/tests/test_image5.html                   |   74 +-
 dojox/gfx/tests/test_imagedata.html                |  583 +
 dojox/gfx/tests/test_lifecycle.html                |  176 +
 dojox/gfx/tests/test_linearGradient.html           |    2 +-
 dojox/gfx/tests/test_linestyle.html                |    2 +-
 dojox/gfx/tests/test_loadCanvas.html               |    2 +-
 dojox/gfx/tests/test_pattern.html                  |    2 +-
 dojox/gfx/tests/test_poly.html                     |    2 +-
 dojox/gfx/tests/test_rect_setShape_vml.html        |    2 +-
 dojox/gfx/tests/test_refproj.html                  |    2 +-
 dojox/gfx/tests/test_registry.html                 |   34 +-
 dojox/gfx/tests/test_renderingOptions.html         |   61 +
 dojox/gfx/tests/test_resize.html                   |    2 +-
 dojox/gfx/tests/test_roundrect.html                |    2 +-
 dojox/gfx/tests/test_setPath.html                  |   14 +-
 dojox/gfx/tests/test_surfaceClip.html              |    2 +-
 dojox/gfx/tests/test_switchTo.html                 |   62 +
 dojox/gfx/tests/test_tbbox.html                    |    2 +-
 dojox/gfx/tests/test_text.html                     |  149 +-
 dojox/gfx/tests/test_textbbox.html                 |  101 +
 dojox/gfx/tests/test_textpath.html                 |    2 +-
 dojox/gfx/tests/test_transform.html                |    2 +-
 dojox/gfx/tests/test_utils.html                    |    3 +-
 dojox/gfx/tests/test_vectortext_draw.html          |    6 +-
 dojox/gfx/tests/test_vectortext_load.html          |   12 +-
 dojox/gfx/utils.js                                 |   65 +-
 dojox/gfx/vml.js                                   |  469 +-
 dojox/gfx/vml_attach.js                            |  110 +-
 dojox/gfx3d.js                                     |   12 +-
 dojox/gfx3d/_base.js                               |    3 +-
 dojox/gfx3d/gradient.js                            |   27 +-
 dojox/gfx3d/lighting.js                            |    2 +-
 dojox/gfx3d/matrix.js                              |  278 +-
 dojox/gfx3d/object.js                              |  408 +-
 dojox/gfx3d/scheduler.js                           |   28 +-
 dojox/gfx3d/tests/test_camerarotate.html           |    2 +-
 dojox/gfx3d/tests/test_camerarotate_shaded.html    |    2 +-
 dojox/gfx3d/tests/test_cube.html                   |    2 +-
 dojox/gfx3d/tests/test_cylinder.html               |    2 +-
 dojox/gfx3d/tests/test_drawer.html                 |    2 +-
 dojox/gfx3d/tests/test_edges.html                  |    2 +-
 dojox/gfx3d/tests/test_matrix.html                 |    2 +-
 dojox/gfx3d/tests/test_orbit.html                  |    2 +-
 dojox/gfx3d/tests/test_overlap.html                |    2 +-
 dojox/gfx3d/tests/test_polygon.html                |    2 +-
 dojox/gfx3d/tests/test_quads.html                  |    2 +-
 dojox/gfx3d/tests/test_rotate.html                 |    2 +-
 dojox/gfx3d/tests/test_scene.html                  |    2 +-
 dojox/gfx3d/tests/test_triangles.html              |    2 +-
 dojox/gfx3d/tests/test_vector.html                 |    2 +-
 dojox/gfx3d/vector.js                              |  125 +-
 dojox/grid/BidiSupport.js                          |    4 +
 dojox/grid/DataGrid.js                             |   26 +-
 dojox/grid/EnhancedGrid.js                         |   22 +-
 dojox/grid/LazyTreeGrid.js                         |   40 +-
 dojox/grid/README                                  |    2 +-
 dojox/grid/Selection.js                            |    7 +-
 dojox/grid/TreeGrid.js                             |   57 +-
 dojox/grid/_Builder.js                             |   71 +-
 dojox/grid/_EditManager.js                         |   15 +-
 dojox/grid/_Events.js                              |   47 +-
 dojox/grid/_FocusManager.js                        |   50 +-
 dojox/grid/_Grid.js                                |  223 +-
 dojox/grid/_RowSelector.js                         |    2 +-
 dojox/grid/_Scroller.js                            |    5 +-
 dojox/grid/_SelectionPreserver.js                  |    4 +-
 dojox/grid/_View.js                                |   35 +-
 dojox/grid/_ViewManager.js                         |   11 +-
 dojox/grid/bidi/_BidiMixin.js                      |  177 +
 dojox/grid/cells/_base.js                          |  107 +-
 dojox/grid/cells/dijit.js                          |   37 +-
 dojox/grid/cells/tree.js                           |   14 +-
 dojox/grid/compatGrid.tar.gz                       |  Bin 216813 -> 101260 bytes
 dojox/grid/enhanced/_Events.js                     |    3 +-
 dojox/grid/enhanced/_FocusManager.js               |  114 +-
 dojox/grid/enhanced/_Plugin.js                     |   27 +-
 dojox/grid/enhanced/_PluginManager.js              |   33 +-
 dojox/grid/enhanced/nls/EnhancedGrid.js            |    2 +
 dojox/grid/enhanced/nls/Filter.js                  |    2 +
 dojox/grid/enhanced/nls/Pagination.js              |    2 +
 dojox/grid/enhanced/nls/ar/EnhancedGrid.js         |    9 +-
 dojox/grid/enhanced/nls/ar/Filter.js               |   80 +-
 dojox/grid/enhanced/nls/ar/Pagination.js           |   18 +-
 dojox/grid/enhanced/nls/bg/EnhancedGrid.js         |   13 +
 dojox/grid/enhanced/nls/bg/Filter.js               |   75 +
 dojox/grid/enhanced/nls/bg/Pagination.js           |   21 +
 dojox/grid/enhanced/nls/ca/EnhancedGrid.js         |   11 +-
 dojox/grid/enhanced/nls/ca/Filter.js               |   17 +-
 dojox/grid/enhanced/nls/ca/Pagination.js           |    4 +-
 dojox/grid/enhanced/nls/cs/EnhancedGrid.js         |   11 +-
 dojox/grid/enhanced/nls/cs/Filter.js               |   73 +-
 dojox/grid/enhanced/nls/cs/Pagination.js           |   15 +-
 dojox/grid/enhanced/nls/da/EnhancedGrid.js         |    9 +-
 dojox/grid/enhanced/nls/da/Filter.js               |   33 +-
 dojox/grid/enhanced/nls/da/Pagination.js           |   10 +-
 dojox/grid/enhanced/nls/de/EnhancedGrid.js         |   11 +-
 dojox/grid/enhanced/nls/de/Filter.js               |   61 +-
 dojox/grid/enhanced/nls/de/Pagination.js           |   19 +-
 dojox/grid/enhanced/nls/el/EnhancedGrid.js         |    9 +-
 dojox/grid/enhanced/nls/el/Filter.js               |   15 +-
 dojox/grid/enhanced/nls/el/Pagination.js           |    4 +-
 dojox/grid/enhanced/nls/es/EnhancedGrid.js         |    7 +-
 dojox/grid/enhanced/nls/es/Filter.js               |   29 +-
 dojox/grid/enhanced/nls/es/Pagination.js           |    7 +-
 dojox/grid/enhanced/nls/fi/EnhancedGrid.js         |   11 +-
 dojox/grid/enhanced/nls/fi/Filter.js               |   63 +-
 dojox/grid/enhanced/nls/fi/Pagination.js           |   12 +-
 dojox/grid/enhanced/nls/fr/EnhancedGrid.js         |    9 +-
 dojox/grid/enhanced/nls/fr/Filter.js               |   25 +-
 dojox/grid/enhanced/nls/fr/Pagination.js           |   13 +-
 dojox/grid/enhanced/nls/he/EnhancedGrid.js         |    7 +-
 dojox/grid/enhanced/nls/he/Filter.js               |    7 +-
 dojox/grid/enhanced/nls/he/Pagination.js           |    4 +-
 dojox/grid/enhanced/nls/hr/EnhancedGrid.js         |    7 +-
 dojox/grid/enhanced/nls/hr/Filter.js               |    8 +-
 dojox/grid/enhanced/nls/hr/Pagination.js           |    5 +-
 dojox/grid/enhanced/nls/hu/EnhancedGrid.js         |    7 +-
 dojox/grid/enhanced/nls/hu/Filter.js               |   15 +-
 dojox/grid/enhanced/nls/hu/Pagination.js           |    7 +-
 dojox/grid/enhanced/nls/it/EnhancedGrid.js         |   15 +-
 dojox/grid/enhanced/nls/it/Filter.js               |   45 +-
 dojox/grid/enhanced/nls/it/Pagination.js           |   19 +-
 dojox/grid/enhanced/nls/ja/EnhancedGrid.js         |   10 +-
 dojox/grid/enhanced/nls/ja/Filter.js               |   59 +-
 dojox/grid/enhanced/nls/ja/Pagination.js           |    8 +-
 dojox/grid/enhanced/nls/kk/EnhancedGrid.js         |   11 +-
 dojox/grid/enhanced/nls/kk/Filter.js               |   23 +-
 dojox/grid/enhanced/nls/kk/Pagination.js           |    4 +-
 dojox/grid/enhanced/nls/ko/EnhancedGrid.js         |   11 +-
 dojox/grid/enhanced/nls/ko/Filter.js               |   19 +-
 dojox/grid/enhanced/nls/ko/Pagination.js           |   15 +-
 dojox/grid/enhanced/nls/nb/EnhancedGrid.js         |    9 +-
 dojox/grid/enhanced/nls/nb/Filter.js               |   33 +-
 dojox/grid/enhanced/nls/nb/Pagination.js           |    8 +-
 dojox/grid/enhanced/nls/nl/EnhancedGrid.js         |    7 +-
 dojox/grid/enhanced/nls/nl/Filter.js               |   23 +-
 dojox/grid/enhanced/nls/nl/Pagination.js           |   11 +-
 dojox/grid/enhanced/nls/pl/EnhancedGrid.js         |   11 +-
 dojox/grid/enhanced/nls/pl/Filter.js               |   47 +-
 dojox/grid/enhanced/nls/pl/Pagination.js           |   25 +-
 dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js      |   12 -
 dojox/grid/enhanced/nls/pt-br/Filter.js            |   85 -
 dojox/grid/enhanced/nls/pt-br/Pagination.js        |   32 -
 dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js      |    9 +-
 dojox/grid/enhanced/nls/pt-pt/Filter.js            |   22 +-
 dojox/grid/enhanced/nls/pt-pt/Pagination.js        |   12 +-
 dojox/grid/enhanced/nls/pt/EnhancedGrid.js         |    7 +-
 dojox/grid/enhanced/nls/pt/Filter.js               |   34 +-
 dojox/grid/enhanced/nls/pt/Pagination.js           |    4 +-
 dojox/grid/enhanced/nls/ro/EnhancedGrid.js         |   11 +-
 dojox/grid/enhanced/nls/ro/Filter.js               |   33 +-
 dojox/grid/enhanced/nls/ro/Pagination.js           |   16 +-
 dojox/grid/enhanced/nls/ru/EnhancedGrid.js         |   13 +-
 dojox/grid/enhanced/nls/ru/Filter.js               |   85 +-
 dojox/grid/enhanced/nls/ru/Pagination.js           |    9 +-
 dojox/grid/enhanced/nls/sk/EnhancedGrid.js         |    7 +-
 dojox/grid/enhanced/nls/sk/Filter.js               |   17 +-
 dojox/grid/enhanced/nls/sk/Pagination.js           |    6 +-
 dojox/grid/enhanced/nls/sl/EnhancedGrid.js         |   11 +-
 dojox/grid/enhanced/nls/sl/Filter.js               |   31 +-
 dojox/grid/enhanced/nls/sl/Pagination.js           |    7 +-
 dojox/grid/enhanced/nls/sv/EnhancedGrid.js         |    7 +-
 dojox/grid/enhanced/nls/sv/Filter.js               |   27 +-
 dojox/grid/enhanced/nls/sv/Pagination.js           |    4 +-
 dojox/grid/enhanced/nls/th/EnhancedGrid.js         |    7 +-
 dojox/grid/enhanced/nls/th/Filter.js               |   15 +-
 dojox/grid/enhanced/nls/th/Pagination.js           |    4 +-
 dojox/grid/enhanced/nls/tr/EnhancedGrid.js         |    7 +-
 dojox/grid/enhanced/nls/tr/Filter.js               |   21 +-
 dojox/grid/enhanced/nls/tr/Pagination.js           |    4 +-
 dojox/grid/enhanced/nls/uk/EnhancedGrid.js         |   13 +
 dojox/grid/enhanced/nls/uk/Filter.js               |   75 +
 dojox/grid/enhanced/nls/uk/Pagination.js           |   21 +
 dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js      |    9 +-
 dojox/grid/enhanced/nls/zh-tw/Filter.js            |   49 +-
 dojox/grid/enhanced/nls/zh-tw/Pagination.js        |    9 +-
 dojox/grid/enhanced/nls/zh/EnhancedGrid.js         |   13 +-
 dojox/grid/enhanced/nls/zh/Filter.js               |   69 +-
 dojox/grid/enhanced/nls/zh/Pagination.js           |   23 +-
 dojox/grid/enhanced/plugins/CellMerge.js           |   55 +-
 dojox/grid/enhanced/plugins/Cookie.js              |    2 +-
 dojox/grid/enhanced/plugins/DnD.js                 |   27 +-
 dojox/grid/enhanced/plugins/Exporter.js            |   27 +-
 dojox/grid/enhanced/plugins/Filter.js              |   44 +-
 dojox/grid/enhanced/plugins/GridSource.js          |   72 +-
 dojox/grid/enhanced/plugins/IndirectSelection.js   |   62 +-
 dojox/grid/enhanced/plugins/Menu.js                |   18 +-
 dojox/grid/enhanced/plugins/NestedSorting.js       |   80 +-
 dojox/grid/enhanced/plugins/Pagination.js          |   41 +-
 dojox/grid/enhanced/plugins/Printer.js             |   41 +-
 dojox/grid/enhanced/plugins/Rearrange.js           |   19 +-
 dojox/grid/enhanced/plugins/Selector.js            |   83 +-
 dojox/grid/enhanced/plugins/_RowMapLayer.js        |    7 +-
 dojox/grid/enhanced/plugins/_SelectionPreserver.js |    1 +
 dojox/grid/enhanced/plugins/_StoreLayer.js         |   80 +-
 .../enhanced/plugins/exporter/_ExportWriter.js     |  136 +-
 .../enhanced/plugins/filter/ClearFilterConfirm.js  |    8 +-
 dojox/grid/enhanced/plugins/filter/FilterBar.js    |   13 +-
 .../enhanced/plugins/filter/FilterDefDialog.js     |   44 +-
 dojox/grid/enhanced/plugins/filter/FilterLayer.js  |   24 +-
 .../enhanced/plugins/filter/FilterStatusTip.js     |   13 +-
 .../grid/enhanced/plugins/filter/_ConditionExpr.js |   10 +-
 dojox/grid/enhanced/resources/EnhancedGrid.css     |    1 -
 dojox/grid/enhanced/templates/FilterBar.html       |    2 +-
 dojox/grid/resources/Grid.css                      |   17 +-
 dojox/grid/resources/Grid_rtl.css                  |    4 +
 dojox/grid/resources/claroGrid.css                 |   18 +-
 dojox/grid/resources/nihiloGrid.css                |    6 +
 dojox/grid/resources/soriaGrid.css                 |    5 +
 dojox/grid/resources/tundraGrid.css                |    4 +
 dojox/grid/tests/bidi/test_edit_dijit.html         |  127 +
 dojox/grid/tests/bidi/test_styling.html            |  164 +
 .../grid/tests/bidi/test_treegrid_lazyloading.html |  134 +
 dojox/grid/tests/bidi/test_treegrid_model.html     |  101 +
 .../tests/enhanced/support/test_layout_music.js    |    3 +-
 dojox/grid/tests/enhanced/support/test_repeat.js   |   11 +-
 .../enhanced/support/test_write_store_music.js     |    1 -
 .../enhanced/test_enhanced_grid_cellmerge.html     |    6 +-
 .../tests/enhanced/test_enhanced_grid_cookie.html  |    5 +-
 .../tests/enhanced/test_enhanced_grid_dnd.html     |    2 +-
 .../tests/enhanced/test_enhanced_grid_filter.html  |    5 +-
 .../test_enhanced_grid_indirectSelection.html      |    3 +-
 .../test_enhanced_grid_leak_programmatic.html      |    2 +-
 .../enhanced/test_enhanced_grid_leak_scroll.html   |    2 +-
 .../test_enhanced_grid_leak_with_plugin.html       |    4 +-
 .../tests/enhanced/test_enhanced_grid_menus.html   |    4 +-
 .../enhanced/test_enhanced_grid_nestedsorting.html |    2 +-
 .../enhanced/test_enhanced_grid_pagination.html    |    7 +-
 .../tests/enhanced/test_enhanced_grid_plugins.html |    4 +-
 .../enhanced/test_enhanced_grid_print_export.html  |    5 +-
 .../tests/enhanced/test_enhanced_grid_search.html  |    5 +-
 .../enhanced/test_enhanced_grid_selector.html      |    5 +-
 dojox/grid/tests/robot/7815.html                   |    2 +-
 dojox/grid/tests/robot/DataGrid_a11y.html          |    4 +-
 dojox/grid/tests/robot/DataGrid_mouse.html         |    2 +-
 dojox/grid/tests/robot/_DataGrid.html              |    4 +-
 dojox/grid/tests/test_backwards_compatibility.html |    8 +-
 dojox/grid/tests/test_change_structure.html        |    4 +-
 dojox/grid/tests/test_custom_sort.html             |    4 +-
 dojox/grid/tests/test_data_grid.html               |    8 +-
 dojox/grid/tests/test_data_grid_autoheight.html    |    4 +-
 dojox/grid/tests/test_data_grid_autowidth.html     |   10 +-
 dojox/grid/tests/test_data_grid_edit.html          |    6 +-
 dojox/grid/tests/test_data_grid_edit_dijit.html    |    6 +-
 .../tests/test_data_grid_edit_large_resultset.html |    8 +-
 dojox/grid/tests/test_data_grid_empty.html         |    4 +-
 dojox/grid/tests/test_data_grid_hideHdr.html       |    6 +-
 dojox/grid/tests/test_data_grid_large.html         |    4 +-
 .../tests/test_data_grid_large_flex_cells.html     |    4 +-
 dojox/grid/tests/test_data_grid_multiStores.html   |   14 +-
 dojox/grid/tests/test_data_grid_notification.html  |    6 +-
 dojox/grid/tests/test_data_grid_page_cache.html    |    4 +-
 dojox/grid/tests/test_data_grid_pctWidth.html      |    6 +-
 dojox/grid/tests/test_data_grid_processError.html  |    8 +-
 dojox/grid/tests/test_data_grid_relWidth.html      |   14 +-
 dojox/grid/tests/test_data_grid_setStore.html      |    6 +-
 dojox/grid/tests/test_edit.html                    |    4 +-
 dojox/grid/tests/test_edit_canEdit.html            |    4 +-
 dojox/grid/tests/test_edit_dijit.html              |    4 +-
 dojox/grid/tests/test_edit_keyNav.html             |    4 +-
 dojox/grid/tests/test_events.html                  |    6 +-
 dojox/grid/tests/test_expand.html                  |    4 +-
 dojox/grid/tests/test_grid.html                    |    4 +-
 dojox/grid/tests/test_grid_autorender.html         |    4 +-
 dojox/grid/tests/test_grid_colspan_resize.html     |    4 +-
 dojox/grid/tests/test_grid_column_display.html     |   14 +-
 dojox/grid/tests/test_grid_column_reorder.html     |    4 +-
 dojox/grid/tests/test_grid_csv_export.html         |    4 +-
 dojox/grid/tests/test_grid_dlg.html                |    4 +-
 dojox/grid/tests/test_grid_formatters.html         |    8 +-
 dojox/grid/tests/test_grid_headerHeight.html       |    6 +-
 dojox/grid/tests/test_grid_hidden_rows.html        |    2 +-
 dojox/grid/tests/test_grid_layout.html             |    2 +-
 .../tests/test_grid_layout_LayoutContainer.html    |    2 +-
 .../tests/test_grid_layout_borderContainer.html    |    6 +-
 dojox/grid/tests/test_grid_messages.html           |   16 +-
 .../grid/tests/test_grid_messages_autoheight.html  |   16 +-
 dojox/grid/tests/test_grid_performance.html        |    2 +-
 dojox/grid/tests/test_grid_programmatic.html       |    2 +-
 .../grid/tests/test_grid_programmatic_layout.html  |    2 +-
 .../tests/test_grid_programmatic_leak_test.html    |    2 +-
 dojox/grid/tests/test_grid_rtl.html                |    2 +-
 dojox/grid/tests/test_grid_selectors.html          |    8 +-
 dojox/grid/tests/test_grid_simple_structure.html   |    4 +-
 dojox/grid/tests/test_grid_simple_structure2.html  |    4 +-
 dojox/grid/tests/test_grid_tab_container.html      |    8 +-
 dojox/grid/tests/test_grid_themes.html             |    6 +-
 dojox/grid/tests/test_grid_tooltip_menu.html       |    4 +-
 dojox/grid/tests/test_keyboard.html                |    6 +-
 dojox/grid/tests/test_markup.html                  |    6 +-
 dojox/grid/tests/test_mysql_edit.html              |    4 +-
 dojox/grid/tests/test_selection.html               |   10 +-
 dojox/grid/tests/test_sizing.html                  |    6 +-
 dojox/grid/tests/test_sizing_100rows.html          |    6 +-
 dojox/grid/tests/test_sizing_ResizeHandle.html     |    6 +-
 dojox/grid/tests/test_styling.html                 |    4 +-
 dojox/grid/tests/test_subgrid.html                 |    2 +-
 dojox/grid/tests/test_treegrid.html                |    8 +-
 dojox/grid/tests/test_treegrid_lazyloading.html    |    6 +-
 dojox/grid/tests/test_treegrid_loading.html        |    4 +-
 dojox/grid/tests/test_treegrid_model.html          |   26 +-
 dojox/grid/tests/test_treegrid_model_lazy.html     |    6 +-
 dojox/grid/tests/test_treegrid_performance.html    |    4 +-
 dojox/grid/tests/test_tundra_edit.html             |    4 +-
 dojox/grid/tests/test_yahoo_images.html            |    4 +-
 dojox/grid/tests/test_yahoo_search.html            |    4 +-
 dojox/grid/util.js                                 |   10 +-
 dojox/help/_base.js                                |    4 +-
 dojox/help/demos/demo_Console.html                 |    2 +-
 dojox/highlight.js                                 |    7 +
 dojox/highlight/_base.js                           |  121 +-
 dojox/highlight/languages/cpp.js                   |    7 +-
 dojox/highlight/languages/css.js                   |    5 +-
 dojox/highlight/languages/delphi.js                |    7 +-
 dojox/highlight/languages/django.js                |    4 +-
 dojox/highlight/languages/groovy.js                |    7 +-
 dojox/highlight/languages/html.js                  |    4 +-
 dojox/highlight/languages/java.js                  |    7 +-
 dojox/highlight/languages/javascript.js            |    4 +-
 dojox/highlight/languages/pygments/_html.js        |    4 +-
 dojox/highlight/languages/pygments/_www.js         |    2 +-
 dojox/highlight/languages/pygments/css.js          |    4 +-
 dojox/highlight/languages/pygments/html.js         |    4 +-
 dojox/highlight/languages/pygments/javascript.js   |    4 +-
 dojox/highlight/languages/pygments/xml.js          |    4 +-
 dojox/highlight/languages/python.js                |    7 +-
 dojox/highlight/languages/sql.js                   |    7 +-
 dojox/highlight/languages/xml.js                   |    4 +-
 dojox/highlight/languages/xquery.js                |    4 +-
 dojox/highlight/tests/example-xml-resultdata.xml   |    2 +-
 dojox/highlight/tests/example-xquery-source.xquery |    2 +-
 dojox/highlight/tests/highlight.js                 |    8 +-
 dojox/highlight/tests/test_highlight.html          |    2 +-
 dojox/highlight/tests/test_highlightWidget.html    |   10 +-
 dojox/highlight/tests/test_pygments.html           |    2 +-
 dojox/highlight/widget/Code.js                     |   50 +-
 dojox/html.js                                      |    7 +
 dojox/html/_base.js                                |  110 +-
 dojox/html/ellipsis.js                             |   28 +-
 dojox/html/entities.js                             |    2 +-
 dojox/html/ext-dojo/style.js                       |   13 +-
 dojox/html/format.js                               |    2 +-
 dojox/html/metrics.js                              |    7 +-
 dojox/html/styles.js                               |  129 +-
 dojox/html/tests/entities.js                       |   24 +-
 dojox/html/tests/remote/commentedStyles.html       |   30 +
 dojox/html/tests/remote/remoteCss1.css             |    3 +
 dojox/html/tests/remote/remoteCss2.css             |    3 +
 dojox/html/tests/test_ellipsis.html                |    2 +-
 dojox/html/tests/test_metrics.html                 |    2 +-
 dojox/html/tests/test_metrics_getTextBox.html      |    2 +-
 dojox/html/tests/test_set.html                     | 1187 +-
 dojox/html/tests/test_style-html.html              |    2 +-
 dojox/html/tests/test_themes.html                  |    2 +-
 dojox/image.js                                     |   10 +-
 dojox/image/Badge.js                               |   36 +-
 dojox/image/FlickrBadge.js                         |   15 +-
 dojox/image/Gallery.js                             |    4 +-
 dojox/image/Lightbox.js                            |  139 +-
 dojox/image/LightboxNano.js                        |   69 +-
 dojox/image/Magnifier.js                           |   11 +-
 dojox/image/MagnifierLite.js                       |   33 +-
 dojox/image/SlideShow.js                           |   19 +-
 dojox/image/ThumbnailPicker.js                     |  120 +-
 dojox/image/_base.js                               |   36 +-
 dojox/image/resources/Lightbox.html                |    2 +-
 dojox/image/resources/ThumbnailPicker.css          |    8 +
 dojox/image/tests/test_Badge.html                  |    4 +-
 dojox/image/tests/test_FlickrBadge.html            |    2 +-
 dojox/image/tests/test_Gallery.html                |    4 +-
 dojox/image/tests/test_Gallery_GoogleData.html     |    2 +-
 .../image/tests/test_Gallery_in_TabContainer.html  |    6 +-
 dojox/image/tests/test_Lightbox.html               |    6 +-
 dojox/image/tests/test_LightboxNano.html           |    4 +-
 dojox/image/tests/test_Magnifier.html              |    6 +-
 dojox/image/tests/test_MagnifierLite.html          |    6 +-
 dojox/image/tests/test_SlideShow.html              |    4 +-
 dojox/image/tests/test_SlideShow_GoogleData.html   |    2 +-
 dojox/image/tests/test_ThumbnailPicker.html        |    4 +-
 .../image/tests/test_ThumbnailPickerLightbox.html  |    2 +-
 dojox/io/OAuth.js                                  |   38 +-
 dojox/io/httpParse.js                              |    8 +-
 dojox/io/proxy/tests/xip.html                      |    2 +-
 dojox/io/proxy/xip.js                              |   37 +-
 dojox/io/scriptFrame.js                            |   17 +-
 dojox/io/tests/scriptFrame.html                    |    2 +-
 dojox/io/tests/scriptFrameRepeat.html              |    2 +-
 dojox/io/tests/windowName.html                     |    2 +-
 dojox/io/tests/xhrMultiPart.html                   |    2 +-
 dojox/io/windowName.js                             |   70 +-
 dojox/io/xhrMultiPart.js                           |   64 +-
 dojox/io/xhrPlugins.js                             |   46 +-
 dojox/io/xhrScriptPlugin.js                        |    7 +-
 dojox/io/xhrWindowNamePlugin.js                    |    9 +-
 dojox/jq.js                                        |   54 +-
 dojox/json/query.js                                |  128 +-
 dojox/json/ref.js                                  |  114 +-
 dojox/json/schema.js                               |   45 +-
 dojox/json/tests/query.js                          |    2 +-
 dojox/json/tests/ref.js                            |   11 +
 dojox/jsonPath.js                                  |   11 +-
 dojox/jsonPath/query.js                            |   29 +-
 dojox/jsonPath/tests/jsonPath.js                   |    4 +-
 dojox/lang/docs.js                                 |    5 +-
 dojox/lang/functional/array.js                     |   40 +-
 dojox/lang/functional/binrec.js                    |    2 +-
 dojox/lang/functional/curry.js                     |   33 +-
 dojox/lang/functional/fold.js                      |   54 +-
 dojox/lang/functional/lambda.js                    |   18 +-
 dojox/lang/functional/linrec.js                    |    2 +-
 dojox/lang/functional/listcomp.js                  |   29 +-
 dojox/lang/functional/multirec.js                  |    2 +-
 dojox/lang/functional/numrec.js                    |    2 +-
 dojox/lang/functional/object.js                    |   30 +-
 dojox/lang/functional/reversed.js                  |   40 +-
 dojox/lang/functional/scan.js                      |   44 +-
 dojox/lang/functional/sequence.js                  |   20 +-
 dojox/lang/functional/tailrec.js                   |    2 +-
 dojox/lang/functional/zip.js                       |   28 +-
 dojox/lang/observable.js                           |   82 +-
 dojox/lang/oo/Decorator.js                         |   14 +-
 dojox/lang/oo/Filter.js                            |   18 +-
 dojox/lang/oo/aop.js                               |   34 +-
 dojox/lang/oo/general.js                           |   19 +-
 dojox/lang/oo/mixin.js                             |   41 +-
 dojox/lang/oo/rearrange.js                         |   12 +-
 dojox/lang/tests/bench_decl.html                   |    2 +-
 dojox/lang/tests/declare-old.js                    |   18 +-
 dojox/lang/tests/fun_perf.html                     |    2 +-
 dojox/lang/tests/observable.js                     |    6 +-
 dojox/lang/tests/rec_perf.html                     |    2 +-
 dojox/lang/tests/test_aspect.html                  |    2 +-
 dojox/lang/tests/test_oo_decl.html                 |    2 +-
 dojox/lang/tests/test_oo_mixin.html                |    2 +-
 dojox/lang/typed.js                                |    5 +-
 dojox/lang/utils.js                                |   45 +-
 dojox/layout/ContentPane.js                        |   33 +-
 dojox/layout/Dock.js                               |  111 +
 dojox/layout/DragPane.js                           |   24 +-
 dojox/layout/ExpandoPane.js                        |   98 +-
 dojox/layout/FloatingPane.js                       |  136 +-
 dojox/layout/GridContainer.js                      |  121 +-
 dojox/layout/GridContainerLite.js                  |  261 +-
 dojox/layout/RadioGroup.js                         |   99 +-
 dojox/layout/ResizeHandle.js                       |  111 +-
 dojox/layout/RotatorContainer.js                   |  134 +-
 dojox/layout/ScrollPane.js                         |   42 +-
 dojox/layout/TableContainer.js                     |   20 +-
 dojox/layout/ToggleSplitter.js                     |   23 +-
 dojox/layout/dnd/Avatar.js                         |    5 +-
 dojox/layout/dnd/PlottedDnd.js                     |   63 +-
 dojox/layout/resources/ExpandoPane.css             |    4 +-
 dojox/layout/resources/ExpandoPane.html            |    2 +-
 dojox/layout/resources/RadioGroup.css              |    4 +
 .../layout/resources/icons/gridcontainer_grip.gif  |  Bin 80 -> 80 bytes
 dojox/layout/tests/ContentPane.html                |  223 +-
 dojox/layout/tests/_bottomPane.html                |    4 +-
 dojox/layout/tests/_floating.html                  |    4 +-
 dojox/layout/tests/test_DragPane.html              |    3 -
 dojox/layout/tests/test_ExpandoPane.html           |   22 +-
 dojox/layout/tests/test_ExpandoPane_code.html      |   14 +-
 dojox/layout/tests/test_ExpandoPane_more.html      |    6 +-
 dojox/layout/tests/test_ExpandoPane_prog.html      |    6 +-
 dojox/layout/tests/test_ExpandoPane_splitters.html |    6 +-
 dojox/layout/tests/test_FloatingPane.html          |    2 +-
 dojox/layout/tests/test_GridContainer.html         |    2 +-
 .../layout/tests/test_GridContainerColWidths.html  |    2 +-
 dojox/layout/tests/test_GridContainerLite.html     |   92 +-
 .../tests/test_GridContainerLite_doLayout.html     |    2 +-
 .../test_GridContainerLite_dragRestriction.html    |    2 +-
 .../tests/test_GridContainer_ResizableCol.html     |    2 +-
 .../tests/test_GridContainer_TitlePanes.html       |    2 +-
 .../test_GridContainer_complete_solution.html      |    8 +-
 .../tests/test_GridContainer_dragHandle.html       |    4 +-
 .../test_GridContainer_in_BorderContainer.html     |    2 +-
 ...test_GridContainer_in_BorderContainer_prog.html |    2 +-
 dojox/layout/tests/test_RadioGroup.html            |    9 +-
 dojox/layout/tests/test_ResizeHandle.html          |    4 +-
 dojox/layout/tests/test_RotatorContainer.html      |    2 +-
 dojox/layout/tests/test_ScrollPane.html            |    2 +-
 dojox/layout/tests/test_ScrollPaneSingle.html      |    2 +-
 dojox/layout/tests/test_TableContainer.html        |   16 +-
 dojox/layout/tests/test_ToggleSplitter.html        |    2 +-
 dojox/layout/tests/test_TouchStackContainer.html   |    2 +-
 dojox/main.js                                      |   10 +-
 dojox/math.js                                      |   12 +-
 dojox/math/BigInteger.js                           |    8 +-
 dojox/math/_base.js                                |   54 +-
 dojox/math/matrix.js                               |   90 +-
 dojox/math/random/Secure.js                        |   34 +-
 dojox/math/random/Simple.js                        |   14 +-
 dojox/math/random/prng4.js                         |    6 +-
 dojox/math/round.js                                |   55 +-
 dojox/math/stats.js                                |   70 +-
 dojox/mdnd/AreaManager.js                          |  121 +-
 dojox/mdnd/AutoScroll.js                           |   28 +-
 dojox/mdnd/DropIndicator.js                        |   13 +-
 dojox/mdnd/LazyManager.js                          |   26 +-
 dojox/mdnd/Moveable.js                             |   54 +-
 dojox/mdnd/PureSource.js                           |   44 +-
 dojox/mdnd/adapter/DndFromDojo.js                  |   61 +-
 dojox/mdnd/adapter/DndToDojo.js                    |  139 +-
 dojox/mdnd/dropMode/DefaultDropMode.js             |   37 +-
 dojox/mdnd/dropMode/OverDropMode.js                |   38 +-
 dojox/mdnd/dropMode/VerticalDropMode.js            |   35 +-
 dojox/mdnd/resources/dnd.css                       |    3 +
 .../tests/functionalTests/test_dnd_acceptance.html |    3 +-
 .../tests/functionalTests/test_dnd_autoScroll.html |    2 +-
 .../functionalTests/test_dnd_defaultDropMode.html  |    2 +-
 .../functionalTests/test_dnd_dndFromDojo.html      |    2 +-
 .../tests/functionalTests/test_dnd_dndToDojo.html  |    3 +-
 .../test_dnd_dndToDojo_dndFromDojo.html            |    2 +-
 .../functionalTests/test_dnd_overDropMode.html     |    2 +-
 .../tests/functionalTests/test_dnd_stress.html     |    2 +-
 .../functionalTests/test_dnd_verticalDropMode.html |    2 +-
 dojox/mdnd/tests/robot/test_dnd_acceptance.html    |    2 +-
 .../mdnd/tests/robot/test_dnd_defaultDropMode.html |    2 +-
 dojox/mdnd/tests/robot/test_dnd_dndFromDojo.html   |    2 +-
 dojox/mdnd/tests/robot/test_dnd_dndToDojo.html     |    2 +-
 dojox/mdnd/tests/robot/test_dnd_overDropMode.html  |    4 +-
 .../tests/robot/test_dnd_verticalDropMode.html     |    2 +-
 .../areaManager/AreaManagerCoverPresence.html      |    2 +-
 .../areaManager/AreaManagerManagingDragItems.html  |    2 +-
 .../areaManager/AreaManagerRegistering.html        |    2 +-
 .../unitTests/dropIndicator/DropIndicatorTest.html |    2 +-
 .../unitTests/dropMode/DefaultDropModeTest.html    |    2 +-
 .../tests/unitTests/dropMode/OverDropModeTest.html |    2 +-
 .../unitTests/dropMode/VerticalDropModeTest.html   |    2 +-
 dojox/mobile.js                                    |    7 +
 dojox/mobile/Accordion.js                          |  507 +
 dojox/mobile/Audio.js                              |  109 +
 dojox/mobile/Badge.js                              |   75 +
 dojox/mobile/Button.js                             |   55 +-
 dojox/mobile/Carousel.js                           |  513 +-
 dojox/mobile/CarouselItem.js                       |  104 +
 dojox/mobile/CheckBox.js                           |   33 +-
 dojox/mobile/ComboBox.js                           |  198 +-
 dojox/mobile/Container.js                          |   21 +
 dojox/mobile/ContentPane.js                        |  123 +-
 dojox/mobile/DataCarousel.js                       |   19 +
 dojox/mobile/DatePicker.js                         |   22 +
 dojox/mobile/EdgeToEdgeCategory.js                 |   10 +-
 dojox/mobile/EdgeToEdgeDataList.js                 |   19 +-
 dojox/mobile/EdgeToEdgeList.js                     |   16 +-
 dojox/mobile/EdgeToEdgeStoreList.js                |   17 +
 dojox/mobile/ExpandingTextArea.js                  |   15 +-
 dojox/mobile/FilteredListMixin.js                  |  422 +
 dojox/mobile/FixedSplitter.js                      |  175 +-
 dojox/mobile/FixedSplitterPane.js                  |   36 +-
 dojox/mobile/FlippableView.js                      |    8 -
 dojox/mobile/FormLayout.js                         |   81 +
 dojox/mobile/GridLayout.js                         |   32 +
 dojox/mobile/Heading.js                            |  276 +-
 dojox/mobile/Icon.js                               |   72 +
 dojox/mobile/IconContainer.js                      |  212 +-
 dojox/mobile/IconItem.js                           |  509 +-
 dojox/mobile/IconMenu.js                           |  126 +
 dojox/mobile/IconMenuItem.js                       |  122 +
 dojox/mobile/ListItem.js                           |  631 +-
 dojox/mobile/LongListMixin.js                      |  304 +
 dojox/mobile/Opener.js                             |   77 +-
 dojox/mobile/Overlay.js                            |  107 +-
 dojox/mobile/PageIndicator.js                      |   51 +-
 dojox/mobile/Pane.js                               |   38 +
 dojox/mobile/ProgressBar.js                        |   79 +
 dojox/mobile/ProgressIndicator.js                  |  131 +-
 dojox/mobile/README                                |   55 +-
 dojox/mobile/RadioButton.js                        |   15 +-
 dojox/mobile/Rating.js                             |   77 +
 dojox/mobile/RoundRect.js                          |   46 +-
 dojox/mobile/RoundRectCategory.js                  |   43 +-
 dojox/mobile/RoundRectDataList.js                  |   19 +-
 dojox/mobile/RoundRectList.js                      |  102 +-
 dojox/mobile/RoundRectStoreList.js                 |   17 +
 dojox/mobile/ScreenSizeAware.js                    |  268 +
 dojox/mobile/ScrollablePane.js                     |  122 +
 dojox/mobile/ScrollableView.js                     |  115 +-
 dojox/mobile/SearchBox.js                          |  124 +
 dojox/mobile/SimpleDialog.js                       |  221 +
 dojox/mobile/Slider.js                             |  104 +-
 dojox/mobile/SpinWheel.js                          |   87 +-
 dojox/mobile/SpinWheelDatePicker.js                |  103 +-
 dojox/mobile/SpinWheelSlot.js                      |  411 +-
 dojox/mobile/SpinWheelTimePicker.js                |   37 +-
 dojox/mobile/StoreCarousel.js                      |   17 +
 dojox/mobile/SwapView.js                           |  229 +-
 dojox/mobile/Switch.js                             |  241 +-
 dojox/mobile/TabBar.js                             |  221 +-
 dojox/mobile/TabBarButton.js                       |  323 +-
 dojox/mobile/TextArea.js                           |    5 -
 dojox/mobile/TextBox.js                            |   27 +-
 dojox/mobile/TimePicker.js                         |   21 +
 dojox/mobile/ToggleButton.js                       |    4 -
 dojox/mobile/ToolBarButton.js                      |  217 +-
 dojox/mobile/Tooltip.js                            |   45 +-
 dojox/mobile/TransitionEvent.js                    |   41 +-
 dojox/mobile/TreeView.js                           |  120 +
 dojox/mobile/ValuePicker.js                        |   31 +
 dojox/mobile/ValuePickerDatePicker.js              |  130 +
 dojox/mobile/ValuePickerSlot.js                    |  389 +
 dojox/mobile/ValuePickerTimePicker.js              |  218 +
 dojox/mobile/Video.js                              |   41 +
 dojox/mobile/View.js                               |  609 +-
 dojox/mobile/ViewController.js                     |  398 +-
 dojox/mobile/_ComboBoxMenu.js                      |   42 +-
 dojox/mobile/_ContentPaneMixin.js                  |  130 +
 dojox/mobile/_DataListMixin.js                     |  109 +-
 dojox/mobile/_DataMixin.js                         |  125 +
 dojox/mobile/_DatePickerMixin.js                   |  275 +
 dojox/mobile/_EditableIconMixin.js                 |  417 +
 dojox/mobile/_EditableListMixin.js                 |  263 +
 dojox/mobile/_ExecScriptMixin.js                   |   40 +
 dojox/mobile/_IconItemPane.js                      |   99 +
 dojox/mobile/_ItemBase.js                          |  396 +-
 dojox/mobile/_ListTouchMixin.js                    |   56 +-
 dojox/mobile/_PickerBase.js                        |  116 +
 dojox/mobile/_PickerChooser.js                     |   22 +
 dojox/mobile/_ScrollableMixin.js                   |   56 +-
 dojox/mobile/_StoreListMixin.js                    |  124 +
 dojox/mobile/_StoreMixin.js                        |  150 +
 dojox/mobile/_TimePickerMixin.js                   |   48 +
 dojox/mobile/_base.js                              |   13 +-
 dojox/mobile/_compat.js                            |  213 +-
 dojox/mobile/_css3.js                              |  129 +
 dojox/mobile/_maskUtils.js                         |  116 +
 dojox/mobile/app.js                                |    9 +
 dojox/mobile/app/AlertDialog.js                    |    2 +-
 dojox/mobile/app/List.js                           |   27 +-
 dojox/mobile/app/ListSelector.js                   |   12 +-
 dojox/mobile/app/SceneAssistant.js                 |   20 +-
 dojox/mobile/app/SceneController.js                |   18 +-
 dojox/mobile/app/StageController.js                |    2 +-
 dojox/mobile/app/_FormWidget.js                    |   15 +-
 dojox/mobile/app/_base.js                          |    2 +-
 dojox/mobile/app/_event.js                         |   13 +-
 dojox/mobile/bidi/Accordion.js                     |   23 +
 dojox/mobile/bidi/Badge.js                         |   32 +
 dojox/mobile/bidi/Button.js                        |   25 +
 dojox/mobile/bidi/Carousel.js                      |   53 +
 dojox/mobile/bidi/CarouselItem.js                  |   36 +
 dojox/mobile/bidi/Heading.js                       |   38 +
 dojox/mobile/bidi/IconItem.js                      |   42 +
 dojox/mobile/bidi/IconMenu.js                      |   23 +
 dojox/mobile/bidi/ListItem.js                      |   98 +
 dojox/mobile/bidi/RoundRectCategory.js             |   30 +
 dojox/mobile/bidi/SpinWheelSlot.js                 |   42 +
 dojox/mobile/bidi/SwapView.js                      |   38 +
 dojox/mobile/bidi/Switch.js                        |   59 +
 dojox/mobile/bidi/TabBar.js                        |   23 +
 dojox/mobile/bidi/TabBarButton.js                  |   29 +
 dojox/mobile/bidi/TextBox.js                       |   48 +
 dojox/mobile/bidi/ToolBarButton.js                 |   35 +
 dojox/mobile/bidi/Tooltip.js                       |   54 +
 dojox/mobile/bidi/TreeView.js                      |   20 +
 dojox/mobile/bidi/ValuePickerSlot.js               |   43 +
 dojox/mobile/bidi/_ComboBoxMenu.js                 |   27 +
 dojox/mobile/bidi/_ItemBase.js                     |   40 +
 dojox/mobile/bidi/_StoreListMixin.js               |   21 +
 dojox/mobile/bidi/common.js                        |   61 +
 dojox/mobile/bookmarkable.js                       |  154 +
 dojox/mobile/build/build.bat                       |   10 +-
 dojox/mobile/build/build.sh                        |   10 +-
 dojox/mobile/common.js                             |  578 +-
 dojox/mobile/compat.js                             |   50 +-
 dojox/mobile/deviceTheme.js                        |  444 +-
 dojox/mobile/dh/ContentTypeMap.js                  |   33 +
 dojox/mobile/dh/DataHandler.js                     |   57 +
 dojox/mobile/dh/HtmlContentHandler.js              |   61 +
 dojox/mobile/dh/HtmlScriptContentHandler.js        |   14 +
 dojox/mobile/dh/JsonContentHandler.js              |  239 +
 dojox/mobile/dh/PatternFileTypeMap.js              |   38 +
 dojox/mobile/dh/StringDataSource.js                |   26 +
 dojox/mobile/dh/SuffixFileTypeMap.js               |   34 +
 dojox/mobile/dh/UrlDataSource.js                   |   40 +
 dojox/mobile/i18n.js                               |   36 +-
 dojox/mobile/iconUtils.js                          |  240 +
 dojox/mobile/lazyLoadUtils.js                      |   96 +
 dojox/mobile/migrationAssist.js                    |  429 +
 dojox/mobile/mobile-all.js                         |   55 +-
 dojox/mobile/pageTurningUtils.js                   |  600 +
 dojox/mobile/parser.js                             |  112 +-
 dojox/mobile/scrollable.js                         | 2535 +-
 dojox/mobile/sniff.js                              |   42 +-
 dojox/mobile/tests/audio/sample.mp3                |  Bin 0 -> 61916 bytes
 dojox/mobile/tests/audio/sample.ogg                |  Bin 0 -> 59023 bytes
 dojox/mobile/tests/audio/sample.wav                |  Bin 0 -> 623326 bytes
 dojox/mobile/tests/auto.html                       |   99 +
 dojox/mobile/tests/bidi/Bidi_Accordion.html        |  279 +
 dojox/mobile/tests/bidi/Bidi_Button.html           |  179 +
 dojox/mobile/tests/bidi/Bidi_ComboBox.html         |  165 +
 dojox/mobile/tests/bidi/Bidi_Dialog.html           |  426 +
 .../tests/bidi/Bidi_EdgeToEdgeCategoryList.html    |  439 +
 .../mobile/tests/bidi/Bidi_EdgeToEdgeDataList.html |  213 +
 dojox/mobile/tests/bidi/Bidi_EdgeToEdgeList.html   |  294 +
 .../tests/bidi/Bidi_EdgeToEdgeStoreList.html       |  213 +
 dojox/mobile/tests/bidi/Bidi_Heading.html          |  218 +
 dojox/mobile/tests/bidi/Bidi_IconContainer.html    |  176 +
 dojox/mobile/tests/bidi/Bidi_IconMenu.html         |  196 +
 dojox/mobile/tests/bidi/Bidi_Index.html            |  152 +
 .../tests/bidi/Bidi_RoundRectCategoryList.html     |  441 +
 dojox/mobile/tests/bidi/Bidi_SearchBox.html        |  195 +
 dojox/mobile/tests/bidi/Bidi_SpinWheel.html        |  266 +
 dojox/mobile/tests/bidi/Bidi_StoreCarousel.html    |  212 +
 dojox/mobile/tests/bidi/Bidi_Switch.html           |  172 +
 dojox/mobile/tests/bidi/Bidi_TabBar.html           |  194 +
 dojox/mobile/tests/bidi/Bidi_TextArea.html         |  225 +
 dojox/mobile/tests/bidi/Bidi_TextBox.html          |  191 +
 dojox/mobile/tests/bidi/Bidi_ToggleButton.html     |  170 +
 dojox/mobile/tests/bidi/Bidi_Tooltip.html          |  294 +
 dojox/mobile/tests/bidi/Bidi_TreeView.html         |  186 +
 dojox/mobile/tests/bidi/Bidi_ValuePicker.html      |  281 +
 dojox/mobile/tests/bidi/Bidi_carousel-categ.json   |    8 +
 dojox/mobile/tests/bidi/Bidi_index.js              |   51 +
 dojox/mobile/tests/bidi/doh/ButtonTests.html       |  113 +
 dojox/mobile/tests/bidi/doh/HeadingTests.html      |  144 +
 dojox/mobile/tests/bidi/doh/IconMenuTests.html     |   98 +
 dojox/mobile/tests/bidi/doh/TabBarTests.html       |  170 +
 dojox/mobile/tests/bidi/doh/module.js              |   23 +
 dojox/mobile/tests/bidi/doh/runTests.html          |    9 +
 .../mobile/tests/bidi/doh/test_Accordion-demo.html |   94 +
 .../mobile/tests/bidi/doh/test_EdgeToEdgeList.html |  108 +
 .../mobile/tests/bidi/doh/test_IconContainer.html  |   90 +
 .../doh/test_RoundRect-EdgeToEdgeDataList.html     |  107 +
 .../doh/test_RoundRect-EdgeToEdgeStoreList.html    |  103 +
 .../tests/bidi/doh/test_SpinWheel-custom.html      |  103 +
 .../tests/bidi/doh/test_StoreCarousel-demo.html    |   92 +
 dojox/mobile/tests/bidi/doh/test_Switch.html       |  104 +
 dojox/mobile/tests/bidi/doh/test_Tooltip.html      |  116 +
 dojox/mobile/tests/bidi/doh/test_TreeView.html     |   91 +
 .../tests/bidi/doh/test_ValuePicker-custom.html    |   71 +
 dojox/mobile/tests/{doh => bidi}/settings.json     |    0
 .../tests/bidi/test_Carousel_rtl-compat.html       |   55 +
 dojox/mobile/tests/bidi/test_Carousel_rtl.html     |   52 +
 dojox/mobile/tests/bidi/test_ComboBox_rtl.html     |  213 +
 .../tests/bidi/test_EdgeToEdgeDataList_rtl.html    |   80 +
 .../mobile/tests/bidi/test_EdgeToEdgeList_rtl.html |   49 +
 .../tests/bidi/test_EdgeToEdgeStoreList_rtl.html   |   90 +
 .../tests/bidi/test_FixedSplitter-H2_rtl.html      |   39 +
 .../bidi/test_FixedSplitter-V2H2-change_rtl.html   |   67 +
 dojox/mobile/tests/bidi/test_Heading_rtl.html      |  191 +
 .../mobile/tests/bidi/test_IconContainer_rtl.html  |   63 +
 .../tests/bidi/test_IconMenu-standalone_rtl.html   |   35 +
 .../tests/bidi/test_RoundRectDataList_rtl.html     |   80 +
 .../tests/bidi/test_RoundRectList-check_rtl.html   |   77 +
 .../mobile/tests/bidi/test_RoundRectList_rtl.html  |   84 +
 .../tests/bidi/test_RoundRectStoreList_rtl.html    |   88 +
 .../tests/bidi/test_SpinWheel-custom_rtl.html      |   74 +
 dojox/mobile/tests/bidi/test_SwapView_rtl.html     |   96 +
 dojox/mobile/tests/bidi/test_Switch_rtl.html       |   86 +
 dojox/mobile/tests/bidi/test_TabBar_rtl.html       |  175 +
 dojox/mobile/tests/bidi/test_ToggleButton_rtl.html |   37 +
 .../app/assistants/main-assistant.js               |   12 +-
 dojox/mobile/tests/complexListApp/index.html       |    2 +-
 .../mobile/tests/data/FixedSplitterfragment1.html  |    4 +
 .../mobile/tests/data/FixedSplitterfragment2.html  |    4 +
 .../mobile/tests/data/FixedSplitterfragment3.html  |    4 +
 dojox/mobile/tests/{ => data}/carousel-categ.json  |    0
 dojox/mobile/tests/{ => data}/carousel-dish.json   |    0
 dojox/mobile/tests/{ => data}/carousel-glass.json  |    0
 dojox/mobile/tests/{ => data}/carousel-shell.json  |    0
 dojox/mobile/tests/{ => data}/carousel-stone.json  |    0
 dojox/mobile/tests/data/carousel-widget.json       |    8 +
 dojox/mobile/tests/data/cvfragment1.html           |   12 +
 dojox/mobile/tests/data/cvfragment2.html           |    7 +
 dojox/mobile/tests/data/cvfragment3.html           |   14 +
 dojox/mobile/tests/data/dialog1.html               |    3 +
 dojox/mobile/tests/data/dialog2.html               |    4 +
 dojox/mobile/tests/data/dialog3.html               |    6 +
 dojox/mobile/tests/data/dialog4.html               |    3 +
 dojox/mobile/tests/data/dialog5.html               |    9 +
 dojox/mobile/tests/data/dialog6.html               |   13 +
 dojox/mobile/tests/data/dojotoolkitblog_rss2.xml   |  298 +
 dojox/mobile/tests/data/fake_service.php           |   14 +
 dojox/mobile/tests/{ => data}/fragment1.html       |    0
 dojox/mobile/tests/data/fragment2.html             |    4 +
 dojox/mobile/tests/data/fragment3.html             |    6 +
 dojox/mobile/tests/data/fragment4.html             |    4 +
 dojox/mobile/tests/data/fruits.json                |   13 +
 .../tests/{ => data}/insurance-car-coverage.html   |    0
 .../tests/{ => data}/insurance-car-safe.html       |    0
 dojox/mobile/tests/data/insurance-car.json         |    6 +
 .../tests/{ => data}/insurance-life-child.html     |    0
 .../tests/{ => data}/insurance-life-long.html      |    0
 dojox/mobile/tests/data/insurance-life.json        |    6 +
 .../tests/{ => data}/insurance-sports-boat.html    |    0
 .../tests/{ => data}/insurance-sports-moto.html    |    0
 .../tests/{ => data}/insurance-sports-snow.html    |    0
 dojox/mobile/tests/data/insurance-sports.json      |    7 +
 dojox/mobile/tests/data/insurance.json             |    7 +
 dojox/mobile/tests/data/settings-itemMap.json      |   14 +
 dojox/mobile/tests/{ => data}/settings.json        |    0
 dojox/mobile/tests/data/simple1.html               |   23 +
 dojox/mobile/tests/data/view-sample.html           |   38 +
 dojox/mobile/tests/data/view1.html                 |   14 +
 dojox/mobile/tests/data/view1.json                 |   19 +
 dojox/mobile/tests/data/view2.html                 |    9 +
 dojox/mobile/tests/data/view2.json                 |   32 +
 dojox/mobile/tests/data/view3.html                 |   17 +
 dojox/mobile/tests/data/view3.json                 |   41 +
 dojox/mobile/tests/data/view4.html                 |   17 +
 dojox/mobile/tests/data/view4.json                 |   78 +
 dojox/mobile/tests/data/view5.html                 |    7 +
 dojox/mobile/tests/data/view5.json                 |   26 +
 dojox/mobile/tests/dialogApp/index.html            |    2 +-
 dojox/mobile/tests/doh/Button.html                 |   50 -
 dojox/mobile/tests/doh/Button_Programmatic.html    |   55 -
 .../tests/doh/CreateListItem2_Programmatic.js      |   21 -
 .../tests/doh/CreateListItem_Programmatic.js       |   50 -
 dojox/mobile/tests/doh/CustomListItem.js           |    5 +
 dojox/mobile/tests/doh/DataListTests.js            |  106 +
 dojox/mobile/tests/doh/EdgeToEdgeCatagory.js       |   71 -
 dojox/mobile/tests/doh/EdgeToEdgeCategory.html     |   41 -
 dojox/mobile/tests/doh/EdgeToEdgeDataList.html     |  155 -
 .../tests/doh/EdgeToEdgeDataList_Programmatic.html |  157 -
 .../tests/doh/HTML5-attribute-compliance.html      |  197 +
 dojox/mobile/tests/doh/Heading.html                |   65 -
 dojox/mobile/tests/doh/Heading2.html               |  166 -
 dojox/mobile/tests/doh/Heading2_Programmatic.html  |  164 -
 dojox/mobile/tests/doh/HeadingFixedBarsTests.html  |  116 +
 dojox/mobile/tests/doh/Heading_Programmatic.html   |   70 -
 dojox/mobile/tests/doh/IconContainer.html          |  151 -
 dojox/mobile/tests/doh/IconContainer2.html         |  120 -
 dojox/mobile/tests/doh/IconContainer3.html         |  125 -
 .../mobile/tests/doh/IconContainerBadgeTests.html  |  182 +
 .../tests/doh/IconContainer_Programmatic.html      |  148 -
 .../doh/ItemBase_subclasses_Programmatic.html      |  312 +
 dojox/mobile/tests/doh/ListItem.html               |   61 -
 dojox/mobile/tests/doh/ListItem.js                 |  113 -
 dojox/mobile/tests/doh/ListItem2.html              |   33 -
 dojox/mobile/tests/doh/ListItem2.js                |   44 -
 dojox/mobile/tests/doh/ListItem2_Programmatic.html |   26 -
 dojox/mobile/tests/doh/ListItem_Programmatic.html  |   36 -
 dojox/mobile/tests/doh/ListTests.js                |   91 +
 dojox/mobile/tests/doh/MblCSS3TransitionTests.html |   62 +
 dojox/mobile/tests/doh/MyDataHandler.js            |   18 +
 dojox/mobile/tests/doh/MyDataSource.js             |   13 +
 dojox/mobile/tests/doh/MyFileTypeMap.js            |   27 +
 dojox/mobile/tests/doh/README                      |   16 +
 dojox/mobile/tests/doh/RoundRect.html              |   69 -
 dojox/mobile/tests/doh/RoundRectDataList.html      |   71 -
 .../tests/doh/RoundRectDataList_Programmatic.html  |   77 -
 dojox/mobile/tests/doh/RoundRectList.html          |   42 -
 dojox/mobile/tests/doh/RoundRectList.js            |   71 -
 .../tests/doh/RoundRectList_Programmatic.html      |   61 -
 dojox/mobile/tests/doh/RoundRect_Programmatic.html |   70 -
 dojox/mobile/tests/doh/Switch.html                 |  143 -
 dojox/mobile/tests/doh/Switch_Programmatic.html    |  126 -
 dojox/mobile/tests/doh/TabBar.html                 |  143 -
 dojox/mobile/tests/doh/TabBar_Programmatic.html    |  161 -
 dojox/mobile/tests/doh/TestHelper.js               |   52 +
 dojox/mobile/tests/doh/TestURLProp.html            |  214 +
 dojox/mobile/tests/doh/TestURLProp2.html           |  259 +
 dojox/mobile/tests/doh/TestUtil.js                 |  212 +-
 dojox/mobile/tests/doh/ToggleButtonTests.html      |   95 +
 dojox/mobile/tests/doh/ToolBarButton.html          |   89 -
 dojox/mobile/tests/doh/ToolBarButton.js            |   93 -
 .../tests/doh/ToolBarButton_Programmatic.html      |  195 -
 dojox/mobile/tests/doh/View-demo.html              |  821 -
 dojox/mobile/tests/doh/View.html                   |  122 -
 dojox/mobile/tests/doh/View2_Programmatic.html     |  199 -
 dojox/mobile/tests/doh/View3_Programmatic.html     |  139 -
 dojox/mobile/tests/doh/View_Programmatic.html      |  139 -
 .../mobile/tests/doh/accordion/AccordionTests.html |  201 +
 dojox/mobile/tests/doh/accordion/dojo.html         |    7 +
 dojox/mobile/tests/doh/accordion/module.js         |    7 +
 dojox/mobile/tests/doh/accordion/runTests.html     |    9 +
 dojox/mobile/tests/doh/badge/BadgeTests.html       |  163 +
 dojox/mobile/tests/doh/badge/module.js             |    7 +
 dojox/mobile/tests/doh/badge/runTests.html         |    9 +
 dojox/mobile/tests/doh/bidi/ComboBoxTests_Rtl.html |  142 +
 .../tests/doh/bidi/EdgeToEdgeCatagory_Rtl.js       |   72 +
 .../tests/doh/bidi/EdgeToEdgeCategory_Rtl.html     |   44 +
 .../tests/doh/bidi/EdgeToEdgeDataList_Rtl.html     |   72 +
 .../tests/doh/bidi/EdgeToEdgeStoreList_Rtl.html    |   28 +
 .../tests/doh/bidi/FixedSplitterTests1_Rtl.html    |   32 +
 .../tests/doh/bidi/FixedSplitterTests2_Rtl.html    |   19 +
 .../tests/doh/bidi/FixedSplitterTests3_Rtl.html    |   32 +
 .../tests/doh/bidi/FixedSplitterTests_rtl.js       |  136 +
 dojox/mobile/tests/doh/bidi/Heading2_Rtl.html      |   66 +
 dojox/mobile/tests/doh/bidi/Heading2_rtl.js        |   87 +
 dojox/mobile/tests/doh/bidi/HeadingTests_Rtl.html  |  151 +
 dojox/mobile/tests/doh/bidi/Heading_Rtl.html       |   66 +
 .../mobile/tests/doh/bidi/IconContainer2_Rtl.html  |  107 +
 .../mobile/tests/doh/bidi/IconContainer3_Rtl.html  |  112 +
 .../tests/doh/bidi/IconContainerTests_Rtl.html     |  216 +
 dojox/mobile/tests/doh/bidi/IconContainer_Rtl.html |   63 +
 dojox/mobile/tests/doh/bidi/IconContainer_Rtl.js   |   64 +
 dojox/mobile/tests/doh/bidi/IconMenuTests_Rtl.html |  201 +
 dojox/mobile/tests/doh/bidi/ListItem2_Rtl.html     |   35 +
 dojox/mobile/tests/doh/bidi/ListItem_Rtl.html      |   62 +
 .../tests/doh/bidi/RoundRectDataList_Rtl.html      |   71 +
 .../mobile/tests/doh/bidi/RoundRectDataList_Rtl.js |   55 +
 dojox/mobile/tests/doh/bidi/RoundRectList_Rtl.html |   44 +
 dojox/mobile/tests/doh/bidi/RoundRectList_Rtl.js   |   73 +
 .../tests/doh/bidi/RoundRectStoreList_Rtl.html     |   28 +
 .../tests/doh/bidi/SpinWheel_Programmatic_Rtl.html |  153 +
 dojox/mobile/tests/doh/bidi/StoreList_Rtl.js       |  152 +
 .../mobile/tests/doh/bidi/SwapViewTests1_Rtl.html  |   25 +
 dojox/mobile/tests/doh/bidi/SwapViewTests_rtl.js   |  101 +
 dojox/mobile/tests/doh/bidi/SwitchTests_Rtl.html   |   94 +
 dojox/mobile/tests/doh/bidi/Switch_Rtl.html        |   82 +
 dojox/mobile/tests/doh/bidi/Switch_rtl.js          |   64 +
 dojox/mobile/tests/doh/bidi/TabBarTests_Rtl.html   |  117 +
 dojox/mobile/tests/doh/bidi/TabBar_Rtl.html        |   69 +
 dojox/mobile/tests/doh/bidi/TabBar_rtl.js          |   66 +
 dojox/mobile/tests/doh/bidi/TestUtil_Rtl.js        |  174 +
 .../tests/doh/bidi/ToggleButtonTests_Rtl.html      |   92 +
 .../tests/doh/bidi/ToolBarButtonSetter_rtl.html    |  171 +
 dojox/mobile/tests/doh/bidi/ToolBarButton_Rtl.js   |  117 +
 dojox/mobile/tests/doh/bidi/ToolBarButton_rtl.html |   91 +
 dojox/mobile/tests/doh/bidi/module.js              |   55 +
 dojox/mobile/tests/doh/bidi/runTests.html          |    9 +
 dojox/mobile/tests/doh/bidi/settings.json          |   14 +
 dojox/mobile/tests/doh/bidi/settings2.json         |   12 +
 dojox/mobile/tests/doh/button/Button.html          |   50 +
 dojox/mobile/tests/doh/button/ButtonTests.html     |  103 +
 .../tests/doh/button/Button_Programmatic.html      |   55 +
 dojox/mobile/tests/doh/button/module.js            |    9 +
 dojox/mobile/tests/doh/button/runTests.html        |    9 +
 dojox/mobile/tests/doh/checkbox/CheckBoxTests.html |   87 +
 dojox/mobile/tests/doh/checkbox/module.js          |    7 +
 dojox/mobile/tests/doh/checkbox/runTests.html      |    9 +
 dojox/mobile/tests/doh/combobox/ComboBoxTests.html |  230 +
 dojox/mobile/tests/doh/combobox/module.js          |    9 +
 dojox/mobile/tests/doh/combobox/runTests.html      |    9 +
 .../tests/doh/contentpane/ContentPaneTests.html    |  235 +
 dojox/mobile/tests/doh/contentpane/fragment1.html  |    3 +
 dojox/mobile/tests/doh/contentpane/fragment2.html  |    3 +
 dojox/mobile/tests/doh/contentpane/module.js       |    9 +
 dojox/mobile/tests/doh/contentpane/runTests.html   |    9 +
 dojox/mobile/tests/doh/data/view1.html             |   14 +
 dojox/mobile/tests/doh/data/view1.myjson           |   41 +
 dojox/mobile/tests/doh/data/view2.html             |    9 +
 dojox/mobile/tests/doh/data/view3.html             |   16 +
 dojox/mobile/tests/doh/data/view3.mydata           |   27 +
 dojox/mobile/tests/doh/data/view4.html             |   17 +
 dojox/mobile/tests/doh/data/view5.html             |    7 +
 dojox/mobile/tests/doh/data/view5.mydata2          |   39 +
 dojox/mobile/tests/doh/data/view6.myhtml           |    8 +
 .../doh/edgetoedgecategory/EdgeToEdgeCatagory.js   |   72 +
 .../doh/edgetoedgecategory/EdgeToEdgeCategory.html |   41 +
 .../EdgeToEdgeCategoryTests.html                   |   96 +
 .../mobile/tests/doh/edgetoedgecategory/module.js  |    8 +
 .../tests/doh/edgetoedgecategory/runTests.html     |    9 +
 .../doh/edgetoedgedatalist/EdgeToEdgeDataList.html |   71 +
 .../EdgeToEdgeDataListTests.html                   |   29 +
 .../EdgeToEdgeDataList_Programmatic.html           |   79 +
 .../mobile/tests/doh/edgetoedgedatalist/module.js  |   11 +
 .../tests/doh/edgetoedgedatalist/runTests.html     |    9 +
 .../tests/doh/edgetoedgedatalist/settings.json     |   14 +
 .../tests/doh/edgetoedgelist/EdgeToEdgeList.js     |   77 +
 .../doh/edgetoedgelist/EdgeToEdgeListTests.html    |   35 +
 dojox/mobile/tests/doh/edgetoedgelist/module.js    |    7 +
 .../mobile/tests/doh/edgetoedgelist/runTests.html  |    9 +
 .../EdgeToEdgeStoreList-itemMap-updates.html       |  152 +
 .../edgetoedgestorelist/EdgeToEdgeStoreList.html   |   32 +
 .../EdgeToEdgeStoreList_Programmatic.html          |   46 +
 .../tests/doh/edgetoedgestorelist/StoreList.js     |  217 +
 .../mobile/tests/doh/edgetoedgestorelist/module.js |    9 +
 .../tests/doh/edgetoedgestorelist/runTests.html    |    9 +
 .../tests/doh/edgetoedgestorelist/settings2.json   |   12 +
 .../expandingtextarea/ExpandingTextAreaTests.html  |  158 +
 dojox/mobile/tests/doh/expandingtextarea/module.js |    7 +
 .../tests/doh/expandingtextarea/runTests.html      |    9 +
 .../doh/filteredlistmixin/FilteredListTests.html   |  374 +
 dojox/mobile/tests/doh/filteredlistmixin/module.js |    7 +
 .../tests/doh/filteredlistmixin/runTests.html      |    9 +
 .../tests/doh/fixedbars/CustomFixedBarsTests.html  |   50 +
 .../doh/fixedbars/DeclaredFixedFooterTests.html    |  125 +
 dojox/mobile/tests/doh/fixedbars/module.js         |    8 +
 dojox/mobile/tests/doh/fixedbars/runTests.html     |    9 +
 .../tests/doh/fixedsplitter/FixedSplitterTests.js  |  164 +
 .../doh/fixedsplitter/FixedSplitterTests1.html     |   31 +
 .../doh/fixedsplitter/FixedSplitterTests2.html     |   18 +
 .../doh/fixedsplitter/FixedSplitterTests3.html     |   31 +
 dojox/mobile/tests/doh/fixedsplitter/module.js     |   11 +
 dojox/mobile/tests/doh/fixedsplitter/runTests.html |    9 +
 dojox/mobile/tests/doh/heading/Heading.html        |   65 +
 dojox/mobile/tests/doh/heading/Heading2.html       |   65 +
 dojox/mobile/tests/doh/heading/Heading2.js         |  102 +
 .../tests/doh/heading/Heading2_Programmatic.html   |   86 +
 dojox/mobile/tests/doh/heading/HeadingTests.html   |  151 +
 .../tests/doh/heading/Heading_Programmatic.html    |  172 +
 dojox/mobile/tests/doh/heading/module.js           |   11 +
 dojox/mobile/tests/doh/heading/runTests.html       |    9 +
 .../tests/doh/iconcontainer/IconContainer.html     |   62 +
 .../tests/doh/iconcontainer/IconContainer.js       |   89 +
 .../tests/doh/iconcontainer/IconContainer2.html    |  106 +
 .../tests/doh/iconcontainer/IconContainer3.html    |  110 +
 .../doh/iconcontainer/IconContainerTests.html      |  215 +
 .../doh/iconcontainer/IconContainerTests2.html     |  180 +
 .../iconcontainer/IconContainer_Programmatic.html  |   91 +
 dojox/mobile/tests/doh/iconcontainer/module.js     |   12 +
 dojox/mobile/tests/doh/iconcontainer/runTests.html |    9 +
 dojox/mobile/tests/doh/iconmenu/IconMenuTests.html |  195 +
 dojox/mobile/tests/doh/iconmenu/module.js          |    7 +
 dojox/mobile/tests/doh/iconmenu/runTests.html      |    9 +
 dojox/mobile/tests/doh/index.html                  |   85 +-
 .../doh/listitem/CreateListItem2_Programmatic.js   |   21 +
 .../doh/listitem/CreateListItem_Programmatic.js    |   52 +
 dojox/mobile/tests/doh/listitem/ListItem.html      |   61 +
 dojox/mobile/tests/doh/listitem/ListItem.js        |  134 +
 dojox/mobile/tests/doh/listitem/ListItem2.html     |   33 +
 dojox/mobile/tests/doh/listitem/ListItem2.js       |   46 +
 .../tests/doh/listitem/ListItem2_Programmatic.html |   26 +
 .../tests/doh/listitem/ListItem3_Programmatic.html |  218 +
 dojox/mobile/tests/doh/listitem/ListItemTests.js   |  150 +
 .../mobile/tests/doh/listitem/ListItemTests1.html  |  108 +
 .../mobile/tests/doh/listitem/ListItemTests2.html  |  108 +
 .../tests/doh/listitem/ListItem_Programmatic.html  |   36 +
 dojox/mobile/tests/doh/listitem/module.js          |   15 +
 dojox/mobile/tests/doh/listitem/runTests.html      |    9 +
 .../tests/doh/longlistmixin/LongListMixin.html     |  270 +
 dojox/mobile/tests/doh/longlistmixin/module.js     |    7 +
 dojox/mobile/tests/doh/longlistmixin/runTests.html |    9 +
 dojox/mobile/tests/doh/module.js                   |   97 +-
 dojox/mobile/tests/doh/opener/OpenerTests1.html    |  103 +
 dojox/mobile/tests/doh/opener/module.js            |    6 +
 dojox/mobile/tests/doh/opener/runTests.html        |    9 +
 .../tests/doh/pageindicator/PageIndicatorTests.js  |  190 +
 .../doh/pageindicator/PageIndicatorTests1.html     |   38 +
 .../doh/pageindicator/PageIndicatorTests2.html     |   38 +
 .../doh/pageindicator/PageIndicatorTests3.html     |   39 +
 dojox/mobile/tests/doh/pageindicator/module.js     |   11 +
 dojox/mobile/tests/doh/pageindicator/runTests.html |    9 +
 dojox/mobile/tests/doh/progress-indicator.html     |   45 -
 dojox/mobile/tests/doh/progressindicator/module.js |    7 +
 .../doh/progressindicator/progress-indicator.html  |   45 +
 .../tests/doh/progressindicator/runTests.html      |    9 +
 .../tests/doh/radiobutton/RadioButtonTests.html    |  139 +
 dojox/mobile/tests/doh/radiobutton/module.js       |    7 +
 dojox/mobile/tests/doh/radiobutton/runTests.html   |    9 +
 dojox/mobile/tests/doh/roundrect/RoundRect.html    |   69 +
 .../doh/roundrect/RoundRect_Programmatic.html      |   74 +
 dojox/mobile/tests/doh/roundrect/module.js         |    8 +
 dojox/mobile/tests/doh/roundrect/runTests.html     |    9 +
 .../doh/roundrectdatalist/RoundRectDataList.html   |   70 +
 .../doh/roundrectdatalist/RoundRectDataList.js     |   55 +
 .../roundrectdatalist/RoundRectDataListTests.html  |   29 +
 .../RoundRectDataList_Programmatic.html            |   79 +
 dojox/mobile/tests/doh/roundrectdatalist/module.js |   11 +
 .../tests/doh/roundrectdatalist/runTests.html      |    9 +
 .../tests/doh/roundrectdatalist/settings.json      |   14 +
 .../tests/doh/roundrectlist/RoundRectList.html     |   42 +
 .../tests/doh/roundrectlist/RoundRectList.js       |   73 +
 .../doh/roundrectlist/RoundRectListTests.html      |   35 +
 .../roundrectlist/RoundRectList_Programmatic.html  |   66 +
 dojox/mobile/tests/doh/roundrectlist/module.js     |    9 +
 dojox/mobile/tests/doh/roundrectlist/runTests.html |    9 +
 .../doh/roundrectstorelist/RoundRectStoreList.html |   31 +
 .../RoundRectStoreList_Programmatic.html           |   46 +
 .../tests/doh/roundrectstorelist/StoreList.js      |  217 +
 .../mobile/tests/doh/roundrectstorelist/module.js  |    8 +
 .../tests/doh/roundrectstorelist/runTests.html     |    9 +
 .../tests/doh/roundrectstorelist/settings2.json    |   12 +
 .../doh/scrollablepane/ScrollablePaneTests.html    |   62 +
 dojox/mobile/tests/doh/scrollablepane/module.js    |    7 +
 .../mobile/tests/doh/scrollablepane/runTests.html  |    9 +
 dojox/mobile/tests/doh/slider/SliderTests.html     |  157 +
 dojox/mobile/tests/doh/slider/module.js            |    7 +
 dojox/mobile/tests/doh/slider/runTests.html        |    9 +
 .../doh/spinwheel/SpinWheel_Programmatic.html      |  195 +
 dojox/mobile/tests/doh/spinwheel/module.js         |    7 +
 dojox/mobile/tests/doh/spinwheel/runTests.html     |    9 +
 .../spinwheeldatepicker/SpinWheelDatePicker.html   |  267 +
 .../mobile/tests/doh/spinwheeldatepicker/module.js |    7 +
 .../tests/doh/spinwheeldatepicker/runTests.html    |    9 +
 dojox/mobile/tests/doh/swapview/SwapViewTests.js   |  101 +
 .../mobile/tests/doh/swapview/SwapViewTests1.html  |   36 +
 .../mobile/tests/doh/swapview/SwapViewTests2.html  |   19 +
 .../mobile/tests/doh/swapview/SwapViewTests3.html  |   24 +
 dojox/mobile/tests/doh/swapview/module.js          |   11 +
 dojox/mobile/tests/doh/swapview/runTests.html      |    9 +
 dojox/mobile/tests/doh/switch/Switch.html          |   81 +
 dojox/mobile/tests/doh/switch/Switch.js            |   64 +
 dojox/mobile/tests/doh/switch/SwitchTests.html     |   94 +
 .../tests/doh/switch/Switch_Programmatic.html      |   66 +
 dojox/mobile/tests/doh/switch/module.js            |    9 +
 dojox/mobile/tests/doh/switch/runTests.html        |    9 +
 dojox/mobile/tests/doh/tabbar/TabBar.html          |  159 +
 dojox/mobile/tests/doh/tabbar/TabBar.js            |  161 +
 dojox/mobile/tests/doh/tabbar/TabBarTests.html     |  116 +
 .../tests/doh/tabbar/TabBar_Programmatic.html      |  158 +
 dojox/mobile/tests/doh/tabbar/module.js            |   11 +
 dojox/mobile/tests/doh/tabbar/runTests.html        |    9 +
 .../doh/templating/TemplatedWidgetsTests.html      |  608 +
 dojox/mobile/tests/doh/templating/module.js        |    7 +
 dojox/mobile/tests/doh/templating/runTests.html    |    9 +
 dojox/mobile/tests/doh/textarea/TextAreaTests.html |  170 +
 dojox/mobile/tests/doh/textarea/module.js          |    7 +
 dojox/mobile/tests/doh/textarea/runTests.html      |    9 +
 dojox/mobile/tests/doh/textbox/TextBoxTests.html   |  159 +
 dojox/mobile/tests/doh/textbox/module.js           |    7 +
 dojox/mobile/tests/doh/textbox/runTests.html       |    9 +
 .../tests/doh/toolbarbutton/ToolBarButton.html     |  113 +
 .../tests/doh/toolbarbutton/ToolBarButton.js       |  144 +
 .../doh/toolbarbutton/ToolBarButtonSetter.html     |  171 +
 .../doh/toolbarbutton/ToolBarButtonTests.html      |  100 +
 .../toolbarbutton/ToolBarButton_Programmatic.html  |  181 +
 dojox/mobile/tests/doh/toolbarbutton/module.js     |   10 +
 dojox/mobile/tests/doh/toolbarbutton/runTests.html |    9 +
 dojox/mobile/tests/doh/topHeading_defect.html      |    6 +-
 .../doh/transition/MblCSS3TransitionTests.html     |   62 +
 dojox/mobile/tests/doh/transition/module.js        |    7 +
 dojox/mobile/tests/doh/transition/runTests.html    |    9 +
 .../doh/valuepickerdatepicker/DatePickerIso.html   |  130 +
 .../ValuePickerDatePicker.html                     |  224 +
 .../tests/doh/valuepickerdatepicker/module.js      |    8 +
 .../tests/doh/valuepickerdatepicker/runTests.html  |    9 +
 .../ValuePickerTimePickerTests.html                |   68 +
 .../tests/doh/valuepickertimepicker/module.js      |    7 +
 .../tests/doh/valuepickertimepicker/runTests.html  |    9 +
 dojox/mobile/tests/doh/view/View-demo.html         |  838 +
 dojox/mobile/tests/doh/view/View.html              |  122 +
 .../mobile/tests/doh/view/View2_Programmatic.html  |  199 +
 .../mobile/tests/doh/view/View3_Programmatic.html  |  144 +
 dojox/mobile/tests/doh/view/View_Programmatic.html |  145 +
 dojox/mobile/tests/doh/view/module.js              |   11 +
 dojox/mobile/tests/doh/view/runTests.html          |    9 +
 .../app/assistants/flickr-image-view-assistant.js  |   10 +-
 dojox/mobile/tests/imageControlsApp/index.html     |    2 +-
 dojox/mobile/tests/images/LTR.png                  |  Bin 0 -> 469 bytes
 dojox/mobile/tests/images/Mountain.jpg             |  Bin 0 -> 27639 bytes
 dojox/mobile/tests/images/RTL.png                  |  Bin 0 -> 478 bytes
 dojox/mobile/tests/images/auto.png                 |  Bin 0 -> 934 bytes
 dojox/mobile/tests/images/chart.png                |  Bin 17937 -> 12607 bytes
 dojox/mobile/tests/images/contacts16.png           |  Bin 0 -> 3142 bytes
 dojox/mobile/tests/images/dojo-logo1.png           |  Bin 0 -> 12510 bytes
 dojox/mobile/tests/images/icons16.png              |  Bin 0 -> 5291 bytes
 dojox/mobile/tests/images/menu1.jpg                |  Bin 0 -> 4878 bytes
 dojox/mobile/tests/images/menu2.jpg                |  Bin 0 -> 5630 bytes
 dojox/mobile/tests/images/menu3.jpg                |  Bin 0 -> 3352 bytes
 dojox/mobile/tests/images/menu4.jpg                |  Bin 0 -> 5115 bytes
 dojox/mobile/tests/images/menu5.jpg                |  Bin 0 -> 4337 bytes
 dojox/mobile/tests/images/menu6.jpg                |  Bin 0 -> 7914 bytes
 dojox/mobile/tests/images/pic1.jpg                 |  Bin 267196 -> 170445 bytes
 dojox/mobile/tests/images/pic10.jpg                |  Bin 270933 -> 258728 bytes
 dojox/mobile/tests/images/pic2.jpg                 |  Bin 255957 -> 181835 bytes
 dojox/mobile/tests/images/pic3.jpg                 |  Bin 260893 -> 222766 bytes
 dojox/mobile/tests/images/pic4.jpg                 |  Bin 262508 -> 127812 bytes
 dojox/mobile/tests/images/pic5.jpg                 |  Bin 307923 -> 222410 bytes
 dojox/mobile/tests/images/pic6.jpg                 |  Bin 254583 -> 131224 bytes
 dojox/mobile/tests/images/pic7.jpg                 |  Bin 323165 -> 249500 bytes
 dojox/mobile/tests/images/pic8.jpg                 |  Bin 296657 -> 121302 bytes
 dojox/mobile/tests/images/pic9.jpg                 |  Bin 277204 -> 165931 bytes
 .../mobile/tests/{ => images}/progressBarAnim.gif  |  Bin 4458 -> 4458 bytes
 dojox/mobile/tests/images/pull-arrow.png           |  Bin 0 -> 365 bytes
 dojox/mobile/tests/images/release-arrow.png        |  Bin 0 -> 400 bytes
 dojox/mobile/tests/{ => images}/sliderHthumb.png   |  Bin 346 -> 346 bytes
 dojox/mobile/tests/{ => images}/sliderVthumb.png   |  Bin 338 -> 338 bytes
 dojox/mobile/tests/images/star-2.png               |  Bin 0 -> 1679 bytes
 dojox/mobile/tests/images/star-3.png               |  Bin 0 -> 3615 bytes
 dojox/mobile/tests/images/star-4.png               |  Bin 0 -> 3807 bytes
 dojox/mobile/tests/images/star-5.png               |  Bin 0 -> 3976 bytes
 dojox/mobile/tests/images/star-6.png               |  Bin 0 -> 3328 bytes
 dojox/mobile/tests/images/star-blue.png            |  Bin 0 -> 492 bytes
 dojox/mobile/tests/images/star-green.png           |  Bin 0 -> 502 bytes
 dojox/mobile/tests/images/star-orange.png          |  Bin 0 -> 494 bytes
 dojox/mobile/tests/images/star-yellow.png          |  Bin 0 -> 490 bytes
 dojox/mobile/tests/index.html                      |  339 +-
 dojox/mobile/tests/index.js                        |  314 +
 dojox/mobile/tests/inputApp/index.html             |    2 +-
 dojox/mobile/tests/insurance-car.json              |    6 -
 dojox/mobile/tests/insurance-life.json             |    6 -
 dojox/mobile/tests/insurance-sports.json           |    7 -
 dojox/mobile/tests/insurance.json                  |    7 -
 dojox/mobile/tests/items.json                      |    7 -
 dojox/mobile/tests/multiSceneApp/index.html        |    2 +-
 dojox/mobile/tests/nls/it/sample.js                |    3 +-
 dojox/mobile/tests/nls/ja/sample.js                |    3 +-
 dojox/mobile/tests/robot/Animation.html            |  147 +-
 dojox/mobile/tests/robot/Animation2.html           |  145 +-
 dojox/mobile/tests/robot/ButtonList.html           |   75 +-
 dojox/mobile/tests/robot/ButtonList2.html          |   77 +-
 dojox/mobile/tests/robot/Flippable.html            |   75 +-
 dojox/mobile/tests/robot/Icon.html                 |   64 +-
 dojox/mobile/tests/robot/Icon2.html                |   64 +-
 dojox/mobile/tests/robot/ListItem.html             |   15 +-
 dojox/mobile/tests/robot/RoundRectListConnect.html |   96 +
 dojox/mobile/tests/robot/ScrollableView.html       |   11 +-
 dojox/mobile/tests/robot/ScrollableView2.html      |   11 +-
 dojox/mobile/tests/robot/ScrollableView3.html      |   11 +-
 dojox/mobile/tests/robot/Settings.html             |   65 +-
 dojox/mobile/tests/robot/Switch.html               |   95 +-
 dojox/mobile/tests/robot/Switch2.html              |   95 +-
 dojox/mobile/tests/robot/TabBar.html               |  105 +-
 dojox/mobile/tests/robot/TabBar2.html              |  105 +-
 dojox/mobile/tests/robot/Transitions.html          |  170 +
 dojox/mobile/tests/robot/index.html                |   28 +
 dojox/mobile/tests/robot/module.js                 |    9 +-
 dojox/mobile/tests/simpleApp/index.html            |    2 +-
 dojox/mobile/tests/simpleListApp/index.html        |    2 +-
 dojox/mobile/tests/templates/Button1.html          |    1 +
 dojox/mobile/tests/templates/CheckBox1.html        |    3 +
 dojox/mobile/tests/templates/Heading1.html         |   17 +
 dojox/mobile/tests/templates/Heading2.html         |   20 +
 dojox/mobile/tests/templates/ListItem1.html        |    5 +
 dojox/mobile/tests/templates/ListItem2.html        |   16 +
 dojox/mobile/tests/templates/ListItem3.html        |   10 +
 dojox/mobile/tests/templates/RadioButton1.html     |    2 +
 dojox/mobile/tests/templates/Slider1.html          |   20 +
 dojox/mobile/tests/templates/Switch1.html          |   14 +
 dojox/mobile/tests/templates/ToggleButton1.html    |    6 +
 dojox/mobile/tests/templates/View1.html            |   43 +
 dojox/mobile/tests/test_Accessibility_Support.html |  116 -
 dojox/mobile/tests/test_Accordion-demo.html        |  171 +
 dojox/mobile/tests/test_Android-ButtonList.html    |   65 -
 dojox/mobile/tests/test_Android-EdgeToEdge.html    |   48 -
 .../tests/test_Android-EdgeToEdgeCategory.html     |   45 -
 dojox/mobile/tests/test_Android-Heading.html       |  123 -
 dojox/mobile/tests/test_Android-Icon.html          |   58 -
 dojox/mobile/tests/test_Android-RoundRectList.html |   53 -
 dojox/mobile/tests/test_Android-Settings.html      |  108 -
 dojox/mobile/tests/test_Android-Switch.html        |   76 -
 dojox/mobile/tests/test_Android-TabBar.html        |   65 -
 .../tests/test_Android-VariableHeightList.html     |   98 -
 dojox/mobile/tests/test_Animation.html             |   79 -
 dojox/mobile/tests/test_Audio-single-source.html   |   27 +
 dojox/mobile/tests/test_Audio.html                 |   29 +
 dojox/mobile/tests/test_Badge.html                 |   58 +
 .../tests/test_BlackBerry-EdgeToEdgeList.html      |   59 -
 dojox/mobile/tests/test_BlackBerry-Heading.html    |  123 -
 .../tests/test_BlackBerry-IconContainer.html       |   57 -
 .../tests/test_BlackBerry-RoundRectList.html       |   59 -
 .../tests/test_BlackBerry-ScrollableView.html      |  396 -
 dojox/mobile/tests/test_BlackBerry-Settings.html   |  111 -
 dojox/mobile/tests/test_BlackBerry-SwapView.html   |   92 -
 dojox/mobile/tests/test_BlackBerry-Switch.html     |   76 -
 dojox/mobile/tests/test_BlackBerry-TabBar.html     |   65 -
 .../tests/test_BlackBerry-VariableHeightList.html  |   99 -
 dojox/mobile/tests/test_Button.html                |   95 +
 dojox/mobile/tests/test_Calendar.html              |   27 +
 dojox/mobile/tests/test_Carousel-async.html        |   58 -
 dojox/mobile/tests/test_Carousel-prog.html         |   57 +
 dojox/mobile/tests/test_Carousel-slideshow.html    |   40 -
 dojox/mobile/tests/test_Carousel.html              |   91 +-
 dojox/mobile/tests/test_CarouselItem.html          |   47 +
 dojox/mobile/tests/test_ComboBox-sv.html           |  178 +
 dojox/mobile/tests/test_ComboBox-widepage.html     |  105 +
 dojox/mobile/tests/test_ComboBox.html              |    2 +-
 dojox/mobile/tests/test_ContentPane.html           |   85 +-
 dojox/mobile/tests/test_Custom-EdgeToEdgeList.html |   59 -
 dojox/mobile/tests/test_Custom-FormControls.html   |  173 -
 dojox/mobile/tests/test_Custom-Heading.html        |  121 -
 dojox/mobile/tests/test_Custom-Icon.html           |   58 -
 dojox/mobile/tests/test_Custom-Opener.html         |  156 -
 dojox/mobile/tests/test_Custom-RoundRectList.html  |   59 -
 dojox/mobile/tests/test_Custom-Settings.html       |  167 -
 dojox/mobile/tests/test_Custom-TabBar.html         |   65 -
 dojox/mobile/tests/test_Custom-Tooltip.html        |  117 -
 dojox/mobile/tests/test_Custom-css-sprite.html     |  170 -
 .../mobile/tests/test_Custom-list-domButtons.html  |  227 -
 dojox/mobile/tests/test_DataCarousel-demo.html     |   58 +
 dojox/mobile/tests/test_DataCarousel.html          |   31 +
 dojox/mobile/tests/test_DatePicker.html            |   50 +
 dojox/mobile/tests/test_DatePicker2.html           |   90 +
 dojox/mobile/tests/test_EdgeToEdgeCategory.html    |   49 +
 .../tests/test_EdgeToEdgeDataList-auto-sv.html     |   86 +
 .../tests/test_EdgeToEdgeDataList-auto-v.html      |   58 +
 .../tests/test_EdgeToEdgeDataList-itemMap.html     |   80 +
 .../tests/test_EdgeToEdgeDataList-more-sv.html     |   77 +
 .../tests/test_EdgeToEdgeDataList-more-v.html      |   76 +
 dojox/mobile/tests/test_EdgeToEdgeDataList.html    |   94 +-
 dojox/mobile/tests/test_EdgeToEdgeList-check.html  |  124 +-
 .../tests/test_EdgeToEdgeList-editable-a11y.html   |  173 +
 .../tests/test_EdgeToEdgeList-editable-sv.html     |  147 +
 .../mobile/tests/test_EdgeToEdgeList-editable.html |  141 +
 .../tests/test_EdgeToEdgeList-syncWithViews.html   |  118 +
 .../mobile/tests/test_EdgeToEdgeList-variable.html |  100 +
 dojox/mobile/tests/test_EdgeToEdgeList.html        |   49 +
 .../tests/test_EdgeToEdgeStoreList-auto-sv.html    |   91 +
 .../tests/test_EdgeToEdgeStoreList-auto-v.html     |   63 +
 .../tests/test_EdgeToEdgeStoreList-categ.html      |   79 +
 .../test_EdgeToEdgeStoreList-itemMap-updates.html  |  133 +
 .../tests/test_EdgeToEdgeStoreList-itemMap.html    |   90 +
 .../tests/test_EdgeToEdgeStoreList-lazy.html       |   97 +
 .../tests/test_EdgeToEdgeStoreList-more-sv.html    |   82 +
 .../tests/test_EdgeToEdgeStoreList-more-v.html     |   81 +
 dojox/mobile/tests/test_EdgeToEdgeStoreList.html   |  101 +
 .../test_FilteredList-EdgeToEdgeDataList-demo.html |  221 +
 ...FilteredList-EdgeToEdgeStoreList-auto-prog.html |  114 +
 ...test_FilteredList-EdgeToEdgeStoreList-auto.html |  109 +
 ...test_FilteredList-EdgeToEdgeStoreList-demo.html |  221 +
 ...test_FilteredList-EdgeToEdgeStoreList-prog.html |  122 +
 ...st_FilteredList-EdgeToEdgeStoreList-simple.html |  116 +
 .../test_FilteredList-RoundRectList-auto.html      |  103 +
 .../test_FilteredList-RoundRectList-demo.html      |  228 +
 dojox/mobile/tests/test_FixedSplitter-H2-prog.html |   84 +-
 dojox/mobile/tests/test_FixedSplitter-H2.html      |   63 +-
 .../tests/test_FixedSplitter-V2H2-ContentPane.html |   41 +
 .../tests/test_FixedSplitter-V2H2-change.html      |   67 +
 dojox/mobile/tests/test_FixedSplitter-V2H2.html    |   71 +-
 dojox/mobile/tests/test_FixedSplitter-V3-var0.html |   62 +
 dojox/mobile/tests/test_FixedSplitter-V3-var1.html |   62 +
 dojox/mobile/tests/test_FixedSplitter-V3-var2.html |   62 +
 dojox/mobile/tests/test_FixedSplitter-V3.html      |   69 +-
 .../tests/test_FixedSplitter-orientation.html      |   77 +
 dojox/mobile/tests/test_FormControls.html          |  360 +-
 dojox/mobile/tests/test_FormLayout.html            |  253 +
 dojox/mobile/tests/test_GridLayout-2cols.html      |   43 +
 dojox/mobile/tests/test_GridLayout-3cols.html      |   43 +
 dojox/mobile/tests/test_GridLayout-change.html     |   43 +
 dojox/mobile/tests/test_GridLayout-demo.html       |  220 +
 dojox/mobile/tests/test_Heading.html               |  219 +
 dojox/mobile/tests/test_Icon.html                  |   49 +
 dojox/mobile/tests/test_IconContainer-badge.html   |   90 +
 dojox/mobile/tests/test_IconContainer-connect.html |  114 +
 .../tests/test_IconContainer-editable-a11y.html    |  120 +
 .../mobile/tests/test_IconContainer-editable.html  |   94 +
 .../mobile/tests/test_IconContainer-highlight.html |   80 +
 dojox/mobile/tests/test_IconContainer-multi.html   |   38 +
 dojox/mobile/tests/test_IconContainer-prog.html    |   83 +
 dojox/mobile/tests/test_IconContainer-pubsub.html  |  114 +
 .../test_IconContainer-removeConfirmation.html     |  124 +
 .../tests/test_IconContainer-single-below.html     |   38 +
 dojox/mobile/tests/test_IconContainer-single.html  |   38 +
 dojox/mobile/tests/test_IconContainer-sprite.html  |   65 +
 .../tests/test_IconContainer-transition-below.html |   54 +
 .../tests/test_IconContainer-transition-zoom.html  |   71 +
 dojox/mobile/tests/test_IconContainer.html         |   63 +
 dojox/mobile/tests/test_IconMenu-6up.html          |   87 +
 dojox/mobile/tests/test_IconMenu-programmatic.html |   71 +
 dojox/mobile/tests/test_IconMenu-standalone.html   |   31 +
 dojox/mobile/tests/test_ListItem-actions.html      |  238 +
 dojox/mobile/tests/test_ListItem-button.html       |   58 +
 dojox/mobile/tests/test_ListItem-domButtons.html   |  244 +
 dojox/mobile/tests/test_ListItem-layout.html       |  134 +
 dojox/mobile/tests/test_ListItem-sprite.html       |  170 +
 dojox/mobile/tests/test_ListItem-transOpt.html     |   87 +
 dojox/mobile/tests/test_LongListMixin.html         |   65 +
 .../tests/test_Opener-ActionSheet-async.html       |    8 +-
 dojox/mobile/tests/test_Opener-Calendar-async.html |   65 -
 .../tests/test_Opener-Calendar-lazy-prog.html      |   77 +
 dojox/mobile/tests/test_Opener-Calendar-lazy.html  |   74 +
 dojox/mobile/tests/test_Opener-Calendar.html       |   72 +
 .../tests/test_Opener-ColorPalette-async.html      |   59 -
 .../tests/test_Opener-ColorPalette-lazy.html       |   65 +
 dojox/mobile/tests/test_Opener-ColorPalette.html   |   66 +
 dojox/mobile/tests/test_Opener-ColorPicker.html    |   58 -
 .../tests/test_Opener-DateSpinWheel-async.html     |   63 -
 .../tests/test_Opener-DateSpinWheel-lazy.html      |   65 +
 dojox/mobile/tests/test_Opener-DateSpinWheel.html  |   69 +
 .../tests/test_Opener-RoundSelectList-async.html   |   10 +-
 .../mobile/tests/test_Opener-SearchList-async.html |   13 +-
 dojox/mobile/tests/test_Overlay.html               |  164 +-
 dojox/mobile/tests/test_ProgressBar.html           |   67 +
 .../mobile/tests/test_ProgressIndicator-color.html |   65 +
 .../tests/test_ProgressIndicator-heading.html      |   58 +
 .../mobile/tests/test_ProgressIndicator-list.html  |  100 +
 .../mobile/tests/test_ProgressIndicator-size.html  |   41 +
 dojox/mobile/tests/test_ProgressIndicator.html     |   76 +
 dojox/mobile/tests/test_Rating-prog.html           |   33 +
 dojox/mobile/tests/test_Rating-setter.html         |   47 +
 dojox/mobile/tests/test_Rating.html                |   79 +
 dojox/mobile/tests/test_RoundRect.html             |   29 +
 dojox/mobile/tests/test_RoundRectCategory.html     |   49 +
 dojox/mobile/tests/test_RoundRectDataList.html     |   93 +-
 dojox/mobile/tests/test_RoundRectList-check.html   |  125 +-
 dojox/mobile/tests/test_RoundRectList-connect.html |  136 +
 .../tests/test_RoundRectList-editable-sv.html      |  144 +
 .../mobile/tests/test_RoundRectList-editable.html  |  141 +
 dojox/mobile/tests/test_RoundRectList-icons.html   |   95 +
 dojox/mobile/tests/test_RoundRectList-inherit.html |  126 +
 .../mobile/tests/test_RoundRectList-variable.html  |  100 +
 .../mobile/tests/test_RoundRectList-vh-icons.html  |  106 +
 dojox/mobile/tests/test_RoundRectList.html         |   84 +
 dojox/mobile/tests/test_RoundRectStoreList.html    |   99 +
 .../tests/test_ScreenSizeAware-demo-prop.html      |  109 +
 .../tests/test_ScreenSizeAware-demo-tag.html       |  108 +
 dojox/mobile/tests/test_ScreenSizeAware-icon.html  |  196 +
 dojox/mobile/tests/test_ScreenSizeAware-prop.html  |  239 +
 dojox/mobile/tests/test_ScreenSizeAware-tag.html   |  241 +
 .../mobile/tests/test_ScrollableMixin-custom.html  |  227 +-
 dojox/mobile/tests/test_ScrollablePane-demo.html   |  251 +
 dojox/mobile/tests/test_ScrollablePane-h.html      |   47 +
 dojox/mobile/tests/test_ScrollablePane-mask.html   |  138 +
 dojox/mobile/tests/test_ScrollablePane.html        |   52 +
 .../tests/test_ScrollableView-HTML-inputs.html     |  100 +
 .../tests/test_ScrollableView-demo-long.html       |  395 +
 dojox/mobile/tests/test_ScrollableView-demo.html   |  399 +
 .../tests/test_ScrollableView-fixedFooters.html    |   60 +
 dojox/mobile/tests/test_ScrollableView-h.html      |   55 +
 .../mobile/tests/test_ScrollableView-hv-ah-af.html |  126 +
 .../mobile/tests/test_ScrollableView-hv-vh-vf.html |  126 +
 dojox/mobile/tests/test_ScrollableView-hv.html     |  125 +
 .../tests/test_ScrollableView-pullToRefresh.html   |  186 +
 .../tests/test_ScrollableView-scrollEvents.html    |   94 +
 .../tests/test_ScrollableView-short-inp.html       |   92 +
 dojox/mobile/tests/test_ScrollableView-short.html  |   89 +
 .../tests/test_ScrollableView-v-ah-af-inp.html     |  180 +
 .../mobile/tests/test_ScrollableView-v-ah-af.html  |  168 +
 .../mobile/tests/test_ScrollableView-v-ah-inp.html |  179 +
 dojox/mobile/tests/test_ScrollableView-v-inp.html  |  179 +
 .../tests/test_ScrollableView-v-vh-af-inp.html     |  181 +
 .../mobile/tests/test_ScrollableView-v-vh-af.html  |  169 +
 .../mobile/tests/test_ScrollableView-v-vh-inp.html |  180 +
 .../tests/test_ScrollableView-v-vh-vf-inp.html     |  182 +
 .../mobile/tests/test_ScrollableView-v-vh-vf.html  |  170 +
 dojox/mobile/tests/test_ScrollableView-v-vh.html   |  168 +
 dojox/mobile/tests/test_ScrollableView-v.html      |  167 +
 dojox/mobile/tests/test_SimpleDialog-large.html    |  132 +
 dojox/mobile/tests/test_SimpleDialog-load.html     |  160 +
 .../mobile/tests/test_SimpleDialog-spinWheel.html  |   40 +
 dojox/mobile/tests/test_SimpleDialog.html          |  185 +
 dojox/mobile/tests/test_Slider.html                |  246 +-
 dojox/mobile/tests/test_SpinWheel-1slot.html       |   42 +-
 dojox/mobile/tests/test_SpinWheel-custom.html      |  136 +-
 dojox/mobile/tests/test_SpinWheel-icons.html       |   77 +-
 .../tests/test_SpinWheelDatePicker-setter.html     |   45 +
 .../mobile/tests/test_SpinWheelDatePicker-sv.html  |  199 +-
 dojox/mobile/tests/test_SpinWheelDatePicker.html   |  171 +-
 .../tests/test_SpinWheelTimePicker-setter.html     |   38 +
 dojox/mobile/tests/test_SpinWheelTimePicker.html   |   76 +-
 dojox/mobile/tests/test_StoreCarousel-demo.html    |   58 +
 dojox/mobile/tests/test_StoreCarousel-prog.html    |   37 +
 dojox/mobile/tests/test_StoreCarousel-resize.html  |   31 +
 .../mobile/tests/test_StoreCarousel-slideshow.html |   46 +
 dojox/mobile/tests/test_StoreCarousel-widgets.html |   47 +
 dojox/mobile/tests/test_StoreCarousel.html         |   31 +
 dojox/mobile/tests/test_SwapView-demo.html         |  241 +
 dojox/mobile/tests/test_SwapView-show.html         |   68 +
 dojox/mobile/tests/test_SwapView-slideshow.html    |   99 +
 dojox/mobile/tests/test_SwapView.html              |   96 +
 dojox/mobile/tests/test_Switch-setter.html         |  130 +-
 dojox/mobile/tests/test_Switch.html                |   84 +
 dojox/mobile/tests/test_TabBar-badge.html          |   66 +
 .../tests/test_TabBar-seg-grouped-scroll.html      |  184 +
 dojox/mobile/tests/test_TabBar-seg-grouped.html    |  179 +
 dojox/mobile/tests/test_TabBar-seg.html            |  163 +
 dojox/mobile/tests/test_TabBar-syncWithViews.html  |   98 +
 dojox/mobile/tests/test_TabBar.html                |  288 +
 dojox/mobile/tests/test_Templated-widgets.html     |  375 +
 .../tests/test_TextBox-in-ScrollableView.html      |  193 +
 dojox/mobile/tests/test_TimePicker.html            |   47 +
 dojox/mobile/tests/test_ToolBarButton-setter.html  |   77 +
 dojox/mobile/tests/test_Tooltip.html               |  225 +-
 dojox/mobile/tests/test_TreeView.html              |   40 +
 dojox/mobile/tests/test_ValuePicker-1slot.html     |   38 +
 dojox/mobile/tests/test_ValuePicker-custom.html    |   40 +
 dojox/mobile/tests/test_ValuePicker-dialog.html    |  186 +
 .../tests/test_ValuePickerDatePicker-setter.html   |   45 +
 dojox/mobile/tests/test_ValuePickerDatePicker.html |  137 +
 dojox/mobile/tests/test_ValuePickerSlot.html       |   42 +
 .../tests/test_ValuePickerTimePicker-setter.html   |   42 +
 dojox/mobile/tests/test_ValuePickerTimePicker.html |   48 +
 dojox/mobile/tests/test_Video-single-source.html   |   27 +
 dojox/mobile/tests/test_Video.html                 |   29 +
 dojox/mobile/tests/test_a11y.html                  |  122 +
 .../tests/test_add-to-home-screen-sample.html      |  218 +
 dojox/mobile/tests/test_ajax-html-sync.html        |   43 +
 dojox/mobile/tests/test_ajax-html.html             |   70 +-
 dojox/mobile/tests/test_ajax-json-sync.html        |   43 +
 dojox/mobile/tests/test_ajax-json.html             |   70 +-
 dojox/mobile/tests/test_anchor-label.html          |  115 +-
 dojox/mobile/tests/test_bg-view.html               |   66 +
 dojox/mobile/tests/test_bg.html                    |   65 +
 .../mobile/tests/test_bk-ScrollableView-demo.html  |  429 +
 dojox/mobile/tests/test_bk-content-view.html       |   42 +
 dojox/mobile/tests/test_bk-grouped-views.html      |   66 +
 dojox/mobile/tests/test_bk-list.html               |  115 +
 dojox/mobile/tests/test_bk-split-views.html        |  144 +
 dojox/mobile/tests/test_bk-tablet-settings.html    |  240 +
 .../tests/test_bk_force-ScrollableView-demo.html   |  429 +
 dojox/mobile/tests/test_bk_force-content-view.html |   42 +
 .../mobile/tests/test_bk_force-grouped-views.html  |   66 +
 dojox/mobile/tests/test_bk_force-list.html         |  115 +
 dojox/mobile/tests/test_bk_force-split-views.html  |  144 +
 .../tests/test_bk_force-tablet-settings.html       |  240 +
 dojox/mobile/tests/test_bookmarkable.html          |  111 -
 dojox/mobile/tests/test_css-sprite.html            |  170 -
 dojox/mobile/tests/test_data-handlers.html         |   77 +
 dojox/mobile/tests/test_domButtons.html            |  145 +-
 dojox/mobile/tests/test_domButtons16.html          |   54 +
 dojox/mobile/tests/test_domButtonsBadge.html       |   52 +
 .../tests/test_dynamic-ScrollableView-ah-af.html   |   96 +-
 .../tests/test_dynamic-ScrollableView-vh-vf.html   |   88 +-
 dojox/mobile/tests/test_dynamic-icons.html         |   92 +-
 dojox/mobile/tests/test_dynamic-items.html         |  104 +-
 dojox/mobile/tests/test_dynamic-view.html          |   57 -
 .../tests/test_grouped-scrollable-views.html       |  100 +-
 dojox/mobile/tests/test_grouped-views.html         |   98 +-
 dojox/mobile/tests/test_hash-parameter.html        |   98 +-
 dojox/mobile/tests/test_html-form-controls.html    |  140 +-
 dojox/mobile/tests/test_html-inputs.html           |  106 +-
 dojox/mobile/tests/test_i18n-sync.html             |   90 +
 dojox/mobile/tests/test_i18n.html                  |  160 +-
 dojox/mobile/tests/test_iPad-Heading.html          |  124 -
 dojox/mobile/tests/test_iPad-Settings-async.html   |  241 -
 dojox/mobile/tests/test_iPad-Settings.html         |  235 -
 dojox/mobile/tests/test_iPad-TabBar.html           |   66 -
 .../mobile/tests/test_iPhone-Animation-async.html  |   81 -
 dojox/mobile/tests/test_iPhone-Animation.html      |   79 -
 dojox/mobile/tests/test_iPhone-Button.html         |   42 -
 dojox/mobile/tests/test_iPhone-ButtonList.html     |   48 -
 dojox/mobile/tests/test_iPhone-EdgeToEdge.html     |   49 -
 .../tests/test_iPhone-EdgeToEdgeCategory.html      |   45 -
 dojox/mobile/tests/test_iPhone-Heading.html        |  123 -
 dojox/mobile/tests/test_iPhone-Icon-sprite.html    |   62 -
 dojox/mobile/tests/test_iPhone-Icon.html           |   63 -
 dojox/mobile/tests/test_iPhone-IconMulti.html      |   44 -
 dojox/mobile/tests/test_iPhone-IconSingle.html     |   36 -
 .../mobile/tests/test_iPhone-IconSingleBelow.html  |   36 -
 dojox/mobile/tests/test_iPhone-ResultList.html     |   64 -
 dojox/mobile/tests/test_iPhone-RoundRect.html      |   26 -
 dojox/mobile/tests/test_iPhone-RoundRectList.html  |   53 -
 .../test_iPhone-ScrollableView-demo-async.html     |  393 -
 .../test_iPhone-ScrollableView-demo-long.html      |  389 -
 .../tests/test_iPhone-ScrollableView-demo.html     |  395 -
 .../mobile/tests/test_iPhone-ScrollableView-h.html |   50 -
 .../tests/test_iPhone-ScrollableView-hv-ah-af.html |  121 -
 .../tests/test_iPhone-ScrollableView-hv-vh-vf.html |  121 -
 .../tests/test_iPhone-ScrollableView-hv.html       |  120 -
 .../test_iPhone-ScrollableView-short-inp.html      |   84 -
 .../tests/test_iPhone-ScrollableView-short.html    |   84 -
 .../test_iPhone-ScrollableView-v-ah-af-inp.html    |  172 -
 .../tests/test_iPhone-ScrollableView-v-ah-af.html  |  163 -
 .../tests/test_iPhone-ScrollableView-v-inp.html    |  171 -
 .../test_iPhone-ScrollableView-v-vh-af-inp.html    |  173 -
 .../tests/test_iPhone-ScrollableView-v-vh-af.html  |  164 -
 .../tests/test_iPhone-ScrollableView-v-vh-inp.html |  172 -
 .../test_iPhone-ScrollableView-v-vh-vf-inp.html    |  174 -
 .../tests/test_iPhone-ScrollableView-v-vh-vf.html  |  165 -
 .../tests/test_iPhone-ScrollableView-v-vh.html     |  163 -
 .../mobile/tests/test_iPhone-ScrollableView-v.html |  162 -
 dojox/mobile/tests/test_iPhone-Settings.html       |  167 -
 .../tests/test_iPhone-SwapView-demo-async.html     |  219 -
 dojox/mobile/tests/test_iPhone-SwapView-demo.html  |  217 -
 .../test_iPhone-SwapView-slideshow-async.html      |   98 -
 .../tests/test_iPhone-SwapView-slideshow.html      |   95 -
 dojox/mobile/tests/test_iPhone-SwapView.html       |   83 -
 dojox/mobile/tests/test_iPhone-Switch.html         |   76 -
 .../test_iPhone-TabBar-seg-grouped-scroll.html     |  182 -
 .../tests/test_iPhone-TabBar-seg-grouped.html      |  177 -
 dojox/mobile/tests/test_iPhone-TabBar-seg.html     |  161 -
 dojox/mobile/tests/test_iPhone-TabBar.html         |   65 -
 .../tests/test_iPhone-VariableHeightList.html      |   98 -
 dojox/mobile/tests/test_ios6.html                  |  102 +
 dojox/mobile/tests/test_list-actions.html          |  225 -
 dojox/mobile/tests/test_list-domButtons.html       |  227 -
 dojox/mobile/tests/test_migrationAssist.html       |  123 +
 .../test_new_transition-animations-standard.html   |  163 +-
 .../tests/test_new_transition-animations.html      |  129 +-
 .../tests/test_new_transition-animations2.html     |  339 +-
 .../mobile/tests/test_orientation-transition.html  |   84 +-
 .../tests/test_pageTurningUtils-add-remove.html    |  146 +
 .../tests/test_pageTurningUtils-callback.html      |  100 +
 .../tests/test_pageTurningUtils-pageType.html      |  147 +
 dojox/mobile/tests/test_pageTurningUtils.html      |  118 +
 dojox/mobile/tests/test_phone-settings.html        |  170 +
 dojox/mobile/tests/test_progress-indicator.html    |   67 -
 .../mobile/tests/test_screen-size-aware-async.html |  315 -
 .../mobile/tests/test_screen-size-aware-demo.html  |  175 -
 dojox/mobile/tests/test_screen-size-aware.html     |  308 -
 dojox/mobile/tests/test_scrollable-no-dojo-af.html |  147 -
 .../tests/test_scrollable-no-dojo-ah-af.html       |  153 -
 dojox/mobile/tests/test_scrollable-no-dojo-ah.html |  145 -
 dojox/mobile/tests/test_scrollable-no-dojo.html    |  122 -
 dojox/mobile/tests/test_tablet-settings.html       |  239 +
 dojox/mobile/tests/test_theme-iOS6.html            |  102 +
 dojox/mobile/tests/test_theme-switch.html          |  118 +
 .../test_transition-animations-extended1.html      |  126 +-
 .../test_transition-animations-extended2.html      |  164 +-
 .../test_transition-animations-extended3.html      |  164 +-
 .../test_transition-animations-extended4.html      |  140 +-
 .../test_transition-animations-extended5.html      |  146 +-
 .../tests/test_transition-animations-standard.html |  140 +-
 dojox/mobile/tests/test_transition-animations.html |  129 +-
 .../mobile/tests/test_transition-animations2.html  |  506 +-
 dojox/mobile/tests/test_transition-connect.html    |   95 +-
 dojox/mobile/tests/test_transition-pubsub.html     |   85 +-
 .../tests/test_transition-to-dynamic-view.html     |   71 -
 dojox/mobile/tests/video/sample.mp4                |  Bin 0 -> 488267 bytes
 dojox/mobile/tests/video/sample.ogv                |  Bin 0 -> 485325 bytes
 dojox/mobile/tests/video/sample.webm               |  Bin 0 -> 306270 bytes
 dojox/mobile/tests/view-sample.html                |   38 -
 dojox/mobile/tests/view1.html                      |   14 -
 dojox/mobile/tests/view1.json                      |   18 -
 dojox/mobile/tests/view2.html                      |    9 -
 dojox/mobile/tests/view2.json                      |   31 -
 dojox/mobile/tests/view3.html                      |   16 -
 dojox/mobile/tests/view3.json                      |   42 -
 dojox/mobile/themes/android/Accordion-compat.css   |   25 +
 dojox/mobile/themes/android/Accordion.css          |   73 +
 dojox/mobile/themes/android/Button-compat.css      |   48 +-
 dojox/mobile/themes/android/Button.css             |   60 +-
 dojox/mobile/themes/android/Button.less            |    2 -
 dojox/mobile/themes/android/Carousel.css           |   57 +-
 dojox/mobile/themes/android/Carousel.less          |    2 -
 dojox/mobile/themes/android/Carousel_rtl.css       |   13 +
 dojox/mobile/themes/android/CheckBox-compat.css    |   61 +-
 dojox/mobile/themes/android/CheckBox.css           |   43 +-
 dojox/mobile/themes/android/CheckBox.less          |    2 -
 dojox/mobile/themes/android/ComboBox-compat.css    |   10 +-
 dojox/mobile/themes/android/ComboBox.css           |   20 +-
 dojox/mobile/themes/android/ComboBox.less          |    2 -
 dojox/mobile/themes/android/ComboBox_rtl.css       |    4 +
 dojox/mobile/themes/android/DatePicker.css         |    2 +
 dojox/mobile/themes/android/EdgeToEdgeCategory.css |   14 +-
 .../mobile/themes/android/EdgeToEdgeCategory.less  |    2 -
 dojox/mobile/themes/android/EdgeToEdgeList.css     |    7 +-
 dojox/mobile/themes/android/FixedSplitter.css      |   19 +
 dojox/mobile/themes/android/FormLayout.css         |  190 +
 dojox/mobile/themes/android/GridLayout.css         |   24 +
 dojox/mobile/themes/android/Heading-compat.css     |   22 +-
 dojox/mobile/themes/android/Heading.css            |   66 +-
 dojox/mobile/themes/android/Heading.less           |    2 -
 .../mobile/themes/android/IconContainer-compat.css |   16 +-
 .../themes/android/IconContainer-compat.less       |    5 +
 dojox/mobile/themes/android/IconContainer.css      |  204 +-
 dojox/mobile/themes/android/IconContainer.less     |    2 +-
 dojox/mobile/themes/android/IconContainer_rtl.css  |   14 +
 dojox/mobile/themes/android/IconMenu-compat.css    |   34 +
 dojox/mobile/themes/android/IconMenu.css           |   64 +
 .../mobile/themes/android/IconMenu_rtl-compat.css  |   17 +
 dojox/mobile/themes/android/IconMenu_rtl.css       |   23 +
 dojox/mobile/themes/android/ListItem-compat.css    |   29 +-
 dojox/mobile/themes/android/ListItem-compat.less   |    5 +
 dojox/mobile/themes/android/ListItem.css           |  109 +-
 .../mobile/themes/android/ListItem_rtl-compat.css  |    1 +
 dojox/mobile/themes/android/ListItem_rtl.css       |   29 +
 dojox/mobile/themes/android/ListItem_rtl.less      |    4 +
 dojox/mobile/themes/android/Overlay-compat.css     |   13 +-
 dojox/mobile/themes/android/Overlay.css            |    3 +-
 .../mobile/themes/android/PageIndicator-compat.css |    4 +
 dojox/mobile/themes/android/PageIndicator.css      |    3 +-
 dojox/mobile/themes/android/PageIndicator.less     |    2 -
 dojox/mobile/themes/android/ProgressBar-compat.css |   15 +
 dojox/mobile/themes/android/ProgressBar.css        |   35 +
 .../themes/android/ProgressIndicator-compat.css    |  101 +-
 dojox/mobile/themes/android/ProgressIndicator.css  |  111 +-
 dojox/mobile/themes/android/ProgressIndicator.less |    2 -
 dojox/mobile/themes/android/RadioButton-compat.css |   53 +-
 dojox/mobile/themes/android/RadioButton.css        |   40 +-
 dojox/mobile/themes/android/RadioButton.less       |    2 -
 dojox/mobile/themes/android/RoundRect-compat.css   |  133 +-
 dojox/mobile/themes/android/RoundRect.css          |    8 +-
 dojox/mobile/themes/android/RoundRect.less         |    2 -
 dojox/mobile/themes/android/RoundRectCategory.css  |    7 +-
 dojox/mobile/themes/android/RoundRectCategory.less |    2 -
 .../themes/android/RoundRectCategory_rtl.css       |    4 +
 .../mobile/themes/android/RoundRectList-compat.css |  138 +-
 dojox/mobile/themes/android/RoundRectList.css      |   32 +-
 dojox/mobile/themes/android/RoundRectList.less     |    2 -
 dojox/mobile/themes/android/ScrollablePane.css     |   12 +
 dojox/mobile/themes/android/SearchBox-compat.css   |   26 +
 dojox/mobile/themes/android/SearchBox.css          |   61 +
 .../mobile/themes/android/SimpleDialog-compat.css  |   10 +
 dojox/mobile/themes/android/SimpleDialog.css       |   48 +
 dojox/mobile/themes/android/Slider-compat.css      |   67 +-
 dojox/mobile/themes/android/Slider.css             |   31 +-
 dojox/mobile/themes/android/Slider.less            |    2 -
 dojox/mobile/themes/android/SpinWheel-compat.css   |   36 +
 dojox/mobile/themes/android/SpinWheel.css          |   77 +
 .../mobile/themes/android/SpinWheel_rtl-compat.css |    4 +
 dojox/mobile/themes/android/SpinWheel_rtl.css      |    5 +
 dojox/mobile/themes/android/Switch-compat.css      |  136 +-
 dojox/mobile/themes/android/Switch-compat.less     |    7 +
 dojox/mobile/themes/android/Switch.css             |  220 +-
 dojox/mobile/themes/android/Switch.less            |    7 +-
 dojox/mobile/themes/android/Switch_rtl-compat.css  |   43 +
 dojox/mobile/themes/android/Switch_rtl.css         |  117 +
 dojox/mobile/themes/android/TabBar-compat.css      |   76 +-
 dojox/mobile/themes/android/TabBar-compat.less     |    3 +
 dojox/mobile/themes/android/TabBar.css             |  308 +-
 dojox/mobile/themes/android/TabBar.less            |    1 +
 dojox/mobile/themes/android/TabBar_rtl-compat.css  |   19 +
 dojox/mobile/themes/android/TabBar_rtl.css         |   89 +
 dojox/mobile/themes/android/TextArea-compat.css    |    8 +-
 dojox/mobile/themes/android/TextArea.css           |    4 +-
 dojox/mobile/themes/android/TextArea.less          |    2 -
 dojox/mobile/themes/android/TextBox-compat.css     |    7 +-
 dojox/mobile/themes/android/TextBox.css            |    6 +-
 dojox/mobile/themes/android/TextBox.less           |    2 -
 dojox/mobile/themes/android/TimePicker.css         |    2 +
 .../mobile/themes/android/ToggleButton-compat.css  |   52 +-
 dojox/mobile/themes/android/ToggleButton.css       |   48 +-
 dojox/mobile/themes/android/ToggleButton.less      |    2 -
 dojox/mobile/themes/android/ToggleButton_rtl.css   |    7 +
 .../mobile/themes/android/ToolBarButton-compat.css |   63 +
 dojox/mobile/themes/android/ToolBarButton.css      |   93 +-
 dojox/mobile/themes/android/ToolBarButton.less     |    2 -
 dojox/mobile/themes/android/ToolBarButton_rtl.css  |   18 +
 dojox/mobile/themes/android/Tooltip-compat.css     |   75 +-
 dojox/mobile/themes/android/Tooltip.css            |   40 +-
 dojox/mobile/themes/android/Tooltip.less           |    2 -
 dojox/mobile/themes/android/ValuePicker-compat.css |   19 +
 dojox/mobile/themes/android/ValuePicker.css        |   57 +
 dojox/mobile/themes/android/ValuePicker.less       |    5 +
 dojox/mobile/themes/android/android-app-compat.css |    4 +
 dojox/mobile/themes/android/android-app.css        |   24 +-
 dojox/mobile/themes/android/android-compat.css     |    8 +-
 dojox/mobile/themes/android/android.css            |   14 +-
 dojox/mobile/themes/android/android_rtl-compat.css |    7 +
 dojox/mobile/themes/android/android_rtl.css        |   15 +
 dojox/mobile/themes/android/base-compat.css        |    3 +-
 dojox/mobile/themes/android/base_rtl-compat.css    |    3 +
 dojox/mobile/themes/android/base_rtl.css           |    7 +
 dojox/mobile/themes/android/common-compat.css      |   18 +
 dojox/mobile/themes/android/common.css             |   49 +-
 dojox/mobile/themes/android/common.less            |    2 -
 .../themes/android/compat/arrow-button-bg-sel.png  |  Bin 0 -> 189 bytes
 .../themes/android/compat/arrow-button-bg.png      |  Bin 182 -> 157 bytes
 .../android/compat/arrow-button-head-sel.png       |  Bin 0 -> 1134 bytes
 .../themes/android/compat/arrow-button-head.png    |  Bin 566 -> 1068 bytes
 .../android/compat/arrow-button-right-head-sel.png |  Bin 0 -> 1129 bytes
 .../android/compat/arrow-button-right-head.png     |  Bin 0 -> 1073 bytes
 .../themes/android/compat/blue-button-sel-bg.png   |  Bin 0 -> 207 bytes
 .../themes/android/compat/button-arrow-head-bg.gif |  Bin 0 -> 316 bytes
 .../mobile/themes/android/compat/button-chk-bg.png |  Bin 0 -> 154 bytes
 .../mobile/themes/android/compat/button-sel-bg.png |  Bin 156 -> 207 bytes
 .../themes/android/compat/button-unsel-bg.png      |  Bin 0 -> 207 bytes
 .../themes/android/compat/red-button-sel-bg.png    |  Bin 0 -> 207 bytes
 .../mobile/themes/android/compat/switch-arc-l.gif  |  Bin 958 -> 0 bytes
 .../mobile/themes/android/compat/switch-arc-r.gif  |  Bin 1047 -> 0 bytes
 .../mobile/themes/android/compat/switch-arc1-k.gif |  Bin 500 -> 492 bytes
 .../mobile/themes/android/compat/switch-arc1-l.gif |  Bin 0 -> 803 bytes
 .../mobile/themes/android/compat/switch-arc1-r.gif |  Bin 0 -> 691 bytes
 .../mobile/themes/android/compat/switch-arc2-k.gif |  Bin 554 -> 536 bytes
 .../mobile/themes/android/compat/switch-arc2-l.gif |  Bin 0 -> 827 bytes
 .../mobile/themes/android/compat/switch-arc2-r.gif |  Bin 0 -> 728 bytes
 .../themes/android/compat/switch-default-k.gif     |  Bin 313 -> 0 bytes
 .../themes/android/compat/switch-default-l.gif     |  Bin 550 -> 0 bytes
 .../themes/android/compat/switch-default-r.gif     |  Bin 557 -> 0 bytes
 .../themes/android/compat/switch-round-l.gif       |  Bin 978 -> 0 bytes
 .../themes/android/compat/switch-round-r.gif       |  Bin 1106 -> 0 bytes
 .../themes/android/compat/switch-round1-k.gif      |  Bin 720 -> 511 bytes
 .../themes/android/compat/switch-round1-l.gif      |  Bin 0 -> 851 bytes
 .../themes/android/compat/switch-round1-r.gif      |  Bin 0 -> 936 bytes
 .../themes/android/compat/switch-round2-k.gif      |  Bin 785 -> 566 bytes
 .../themes/android/compat/switch-round2-l.gif      |  Bin 0 -> 883 bytes
 .../themes/android/compat/switch-round2-r.gif      |  Bin 0 -> 974 bytes
 .../themes/android/compat/switch-square-k.gif      |  Bin 0 -> 388 bytes
 .../themes/android/compat/switch-square-l.gif      |  Bin 0 -> 578 bytes
 .../themes/android/compat/switch-square-r.gif      |  Bin 0 -> 686 bytes
 .../themes/android/compat/tab-seg-button-bg.png    |  Bin 0 -> 157 bytes
 .../android/compat/tab-seg-sel-button-bg.png       |  Bin 0 -> 178 bytes
 .../themes/android/compat/tab-slim-bar-bg.png      |  Bin 0 -> 107 bytes
 .../themes/android/compat/tab-tall-bar-bg.png      |  Bin 0 -> 161 bytes
 .../android/compat/togglebutton-chk-mark-bg.png    |  Bin 0 -> 150 bytes
 .../android/compat/valuepicker-button-bg.png       |  Bin 0 -> 246 bytes
 .../themes/android/dijit/Calendar-compat.css       |   35 +
 .../themes/android/dijit/Calendar-compat.less      |    2 +
 dojox/mobile/themes/android/dijit/Calendar.css     |  119 +
 dojox/mobile/themes/android/dijit/Calendar.less    |    2 +
 .../dijit/compat/calendar-datelabel-act-bg.png     |  Bin 0 -> 209 bytes
 .../dijit/compat/calendar-datelabel-sel-bg.png     |  Bin 0 -> 144 bytes
 .../android/dijit/compat/calendar-month-bg.png     |  Bin 0 -> 186 bytes
 .../android/dijit/compat/calendar-year-bg.png      |  Bin 0 -> 177 bytes
 dojox/mobile/themes/android/variables.less         |  984 +-
 dojox/mobile/themes/android/variables_rtl.less     |   32 +
 .../mobile/themes/blackberry/Accordion-compat.css  |   19 +
 dojox/mobile/themes/blackberry/Accordion.css       |   72 +
 dojox/mobile/themes/blackberry/Button-compat.css   |   48 +-
 dojox/mobile/themes/blackberry/Button.css          |   56 +-
 dojox/mobile/themes/blackberry/Button.less         |    2 -
 dojox/mobile/themes/blackberry/Carousel.css        |   57 +-
 dojox/mobile/themes/blackberry/Carousel.less       |    2 -
 dojox/mobile/themes/blackberry/Carousel_rtl.css    |   13 +
 dojox/mobile/themes/blackberry/CheckBox-compat.css |   60 +-
 dojox/mobile/themes/blackberry/CheckBox.css        |   39 +-
 dojox/mobile/themes/blackberry/CheckBox.less       |    2 -
 dojox/mobile/themes/blackberry/ComboBox-compat.css |   18 +-
 .../mobile/themes/blackberry/ComboBox-compat.less  |    2 +
 dojox/mobile/themes/blackberry/ComboBox.css        |   18 +-
 dojox/mobile/themes/blackberry/ComboBox.less       |    2 -
 dojox/mobile/themes/blackberry/ComboBox_rtl.css    |    4 +
 dojox/mobile/themes/blackberry/DatePicker.css      |    2 +
 .../themes/blackberry/EdgeToEdgeCategory.css       |   16 +-
 .../themes/blackberry/EdgeToEdgeCategory.less      |    2 -
 dojox/mobile/themes/blackberry/EdgeToEdgeList.css  |    9 +-
 dojox/mobile/themes/blackberry/EdgeToEdgeList.less |    2 -
 dojox/mobile/themes/blackberry/FixedSplitter.css   |   19 +
 dojox/mobile/themes/blackberry/FormLayout.css      |  190 +
 dojox/mobile/themes/blackberry/GridLayout.css      |   24 +
 dojox/mobile/themes/blackberry/Heading-compat.css  |   25 +-
 dojox/mobile/themes/blackberry/Heading.css         |   69 +-
 dojox/mobile/themes/blackberry/Heading.less        |    2 -
 .../themes/blackberry/IconContainer-compat.css     |   16 +-
 .../themes/blackberry/IconContainer-compat.less    |    5 +
 dojox/mobile/themes/blackberry/IconContainer.css   |  205 +-
 dojox/mobile/themes/blackberry/IconContainer.less  |    2 +-
 .../mobile/themes/blackberry/IconContainer_rtl.css |   14 +
 dojox/mobile/themes/blackberry/IconMenu-compat.css |   28 +
 dojox/mobile/themes/blackberry/IconMenu.css        |   64 +
 .../themes/blackberry/IconMenu_rtl-compat.css      |   17 +
 dojox/mobile/themes/blackberry/IconMenu_rtl.css    |    7 +
 dojox/mobile/themes/blackberry/ListItem-compat.css |   29 +-
 .../mobile/themes/blackberry/ListItem-compat.less  |    5 +
 dojox/mobile/themes/blackberry/ListItem.css        |  114 +-
 .../themes/blackberry/ListItem_rtl-compat.css      |    1 +
 dojox/mobile/themes/blackberry/ListItem_rtl.css    |   29 +
 dojox/mobile/themes/blackberry/ListItem_rtl.less   |    4 +
 dojox/mobile/themes/blackberry/Overlay-compat.css  |   13 +-
 dojox/mobile/themes/blackberry/Overlay.css         |    3 +-
 .../themes/blackberry/PageIndicator-compat.css     |    4 +
 dojox/mobile/themes/blackberry/PageIndicator.css   |    3 +-
 dojox/mobile/themes/blackberry/PageIndicator.less  |    2 -
 .../themes/blackberry/ProgressBar-compat.css       |    5 +
 dojox/mobile/themes/blackberry/ProgressBar.css     |   29 +
 .../themes/blackberry/ProgressIndicator-compat.css |  101 +-
 .../mobile/themes/blackberry/ProgressIndicator.css |  111 +-
 .../themes/blackberry/ProgressIndicator.less       |    2 -
 .../themes/blackberry/RadioButton-compat.css       |   53 +-
 dojox/mobile/themes/blackberry/RadioButton.css     |   38 +-
 dojox/mobile/themes/blackberry/RadioButton.less    |    2 -
 .../mobile/themes/blackberry/RoundRect-compat.css  |  133 +-
 dojox/mobile/themes/blackberry/RoundRect.css       |   10 +-
 dojox/mobile/themes/blackberry/RoundRect.less      |    2 -
 .../themes/blackberry/RoundRectCategory-compat.css |    5 +
 .../mobile/themes/blackberry/RoundRectCategory.css |   20 +-
 .../themes/blackberry/RoundRectCategory.less       |    2 -
 .../themes/blackberry/RoundRectCategory_rtl.css    |    4 +
 .../themes/blackberry/RoundRectList-compat.css     |  138 +-
 dojox/mobile/themes/blackberry/RoundRectList.css   |   48 +-
 dojox/mobile/themes/blackberry/RoundRectList.less  |    2 -
 dojox/mobile/themes/blackberry/ScrollablePane.css  |   12 +
 .../mobile/themes/blackberry/SearchBox-compat.css  |   26 +
 dojox/mobile/themes/blackberry/SearchBox.css       |   61 +
 .../themes/blackberry/SimpleDialog-compat.css      |    4 +
 dojox/mobile/themes/blackberry/SimpleDialog.css    |   42 +
 dojox/mobile/themes/blackberry/Slider-compat.css   |   67 +-
 dojox/mobile/themes/blackberry/Slider.css          |   31 +-
 dojox/mobile/themes/blackberry/Slider.less         |    2 -
 .../mobile/themes/blackberry/SpinWheel-compat.css  |   36 +
 dojox/mobile/themes/blackberry/SpinWheel.css       |   77 +
 .../themes/blackberry/SpinWheel_rtl-compat.css     |    4 +
 dojox/mobile/themes/blackberry/SpinWheel_rtl.css   |    5 +
 dojox/mobile/themes/blackberry/Switch-compat.css   |  136 +-
 dojox/mobile/themes/blackberry/Switch-compat.less  |    7 +
 dojox/mobile/themes/blackberry/Switch.css          |  220 +-
 dojox/mobile/themes/blackberry/Switch.less         |    7 +-
 .../mobile/themes/blackberry/Switch_rtl-compat.css |   43 +
 dojox/mobile/themes/blackberry/Switch_rtl.css      |  117 +
 dojox/mobile/themes/blackberry/TabBar-compat.css   |  104 +-
 dojox/mobile/themes/blackberry/TabBar-compat.less  |    3 +
 dojox/mobile/themes/blackberry/TabBar.css          |  314 +-
 dojox/mobile/themes/blackberry/TabBar.less         |    1 +
 .../mobile/themes/blackberry/TabBar_rtl-compat.css |   19 +
 dojox/mobile/themes/blackberry/TabBar_rtl.css      |   89 +
 dojox/mobile/themes/blackberry/TextArea-compat.css |    8 +-
 dojox/mobile/themes/blackberry/TextArea.css        |    4 +-
 dojox/mobile/themes/blackberry/TextArea.less       |    2 -
 dojox/mobile/themes/blackberry/TextBox-compat.css  |    7 +-
 dojox/mobile/themes/blackberry/TextBox.css         |    6 +-
 dojox/mobile/themes/blackberry/TextBox.less        |    2 -
 dojox/mobile/themes/blackberry/TimePicker.css      |    2 +
 .../themes/blackberry/ToggleButton-compat.css      |   53 +-
 dojox/mobile/themes/blackberry/ToggleButton.css    |   43 +-
 dojox/mobile/themes/blackberry/ToggleButton.less   |    2 -
 .../mobile/themes/blackberry/ToggleButton_rtl.css  |    7 +
 .../themes/blackberry/ToolBarButton-compat.css     |   63 +
 dojox/mobile/themes/blackberry/ToolBarButton.css   |   91 +-
 dojox/mobile/themes/blackberry/ToolBarButton.less  |    2 -
 .../mobile/themes/blackberry/ToolBarButton_rtl.css |   18 +
 dojox/mobile/themes/blackberry/Tooltip-compat.css  |   75 +-
 dojox/mobile/themes/blackberry/Tooltip.css         |   32 +-
 dojox/mobile/themes/blackberry/Tooltip.less        |    2 -
 .../themes/blackberry/ValuePicker-compat.css       |   19 +
 dojox/mobile/themes/blackberry/ValuePicker.css     |   57 +
 dojox/mobile/themes/blackberry/ValuePicker.less    |    5 +
 dojox/mobile/themes/blackberry/base-compat.css     |    4 +-
 dojox/mobile/themes/blackberry/base_rtl-compat.css |    3 +
 dojox/mobile/themes/blackberry/base_rtl.css        |    7 +
 .../mobile/themes/blackberry/blackberry-compat.css |    8 +-
 dojox/mobile/themes/blackberry/blackberry.css      |   14 +-
 .../themes/blackberry/blackberry_rtl-compat.css    |    7 +
 dojox/mobile/themes/blackberry/blackberry_rtl.css  |   15 +
 dojox/mobile/themes/blackberry/common-compat.css   |   18 +
 dojox/mobile/themes/blackberry/common.css          |   48 +-
 dojox/mobile/themes/blackberry/common.less         |    2 -
 .../blackberry/compat/arrow-button-bg-sel.png      |  Bin 0 -> 189 bytes
 .../themes/blackberry/compat/arrow-button-bg.png   |  Bin 129 -> 157 bytes
 .../blackberry/compat/arrow-button-head-sel.png    |  Bin 0 -> 1134 bytes
 .../themes/blackberry/compat/arrow-button-head.png |  Bin 0 -> 1068 bytes
 .../compat/arrow-button-right-head-sel.png         |  Bin 0 -> 1129 bytes
 .../blackberry/compat/arrow-button-right-head.png  |  Bin 0 -> 1073 bytes
 .../blackberry/compat/blue-button-sel-bg.png       |  Bin 0 -> 201 bytes
 .../blackberry/compat/button-arrow-head-bg.gif     |  Bin 0 -> 316 bytes
 .../themes/blackberry/compat/button-chk-bg.png     |  Bin 0 -> 177 bytes
 .../themes/blackberry/compat/button-unsel-bg.png   |  Bin 0 -> 201 bytes
 .../mobile/themes/blackberry/compat/heading-bg.png |  Bin 109 -> 204 bytes
 .../themes/blackberry/compat/red-button-sel-bg.png |  Bin 0 -> 201 bytes
 .../themes/blackberry/compat/switch-arc-l.gif      |  Bin 1024 -> 0 bytes
 .../themes/blackberry/compat/switch-arc-r.gif      |  Bin 820 -> 0 bytes
 .../themes/blackberry/compat/switch-arc1-k.gif     |  Bin 497 -> 721 bytes
 .../themes/blackberry/compat/switch-arc1-l.gif     |  Bin 0 -> 867 bytes
 .../themes/blackberry/compat/switch-arc1-r.gif     |  Bin 0 -> 644 bytes
 .../themes/blackberry/compat/switch-arc2-k.gif     |  Bin 550 -> 785 bytes
 .../themes/blackberry/compat/switch-arc2-l.gif     |  Bin 0 -> 905 bytes
 .../themes/blackberry/compat/switch-arc2-r.gif     |  Bin 0 -> 683 bytes
 .../themes/blackberry/compat/switch-default-k.gif  |  Bin 533 -> 0 bytes
 .../themes/blackberry/compat/switch-default-l.gif  |  Bin 742 -> 0 bytes
 .../themes/blackberry/compat/switch-default-r.gif  |  Bin 699 -> 0 bytes
 .../themes/blackberry/compat/switch-round-l.gif    |  Bin 1014 -> 0 bytes
 .../themes/blackberry/compat/switch-round-r.gif    |  Bin 865 -> 0 bytes
 .../themes/blackberry/compat/switch-round1-k.gif   |  Bin 710 -> 730 bytes
 .../themes/blackberry/compat/switch-round1-l.gif   |  Bin 0 -> 901 bytes
 .../themes/blackberry/compat/switch-round1-r.gif   |  Bin 0 -> 679 bytes
 .../themes/blackberry/compat/switch-round2-k.gif   |  Bin 782 -> 800 bytes
 .../themes/blackberry/compat/switch-round2-l.gif   |  Bin 0 -> 946 bytes
 .../themes/blackberry/compat/switch-round2-r.gif   |  Bin 0 -> 716 bytes
 .../themes/blackberry/compat/switch-square-k.gif   |  Bin 0 -> 768 bytes
 .../themes/blackberry/compat/switch-square-l.gif   |  Bin 0 -> 918 bytes
 .../themes/blackberry/compat/switch-square-r.gif   |  Bin 0 -> 690 bytes
 .../themes/blackberry/compat/tab-seg-button-bg.png |  Bin 0 -> 178 bytes
 .../blackberry/compat/tab-seg-sel-button-bg.png    |  Bin 0 -> 197 bytes
 .../themes/blackberry/compat/tab-slim-bar-bg.png   |  Bin 0 -> 107 bytes
 .../themes/blackberry/compat/tab-tall-bar-bg.png   |  Bin 0 -> 161 bytes
 .../blackberry/compat/togglebutton-chk-mark-bg.png |  Bin 0 -> 170 bytes
 .../blackberry/compat/valuepicker-button-bg.png    |  Bin 0 -> 272 bytes
 .../themes/blackberry/dijit/Calendar-compat.css    |   38 +
 .../themes/blackberry/dijit/Calendar-compat.less   |    2 +
 dojox/mobile/themes/blackberry/dijit/Calendar.css  |  125 +
 dojox/mobile/themes/blackberry/dijit/Calendar.less |    2 +
 .../dijit/compat/calendar-datelabel-sel-bg.png     |  Bin 0 -> 193 bytes
 .../blackberry/dijit/compat/calendar-month-bg.png  |  Bin 0 -> 195 bytes
 .../blackberry/dijit/compat/calendar-year-bg.png   |  Bin 0 -> 180 bytes
 dojox/mobile/themes/blackberry/variables.less      | 1003 +-
 dojox/mobile/themes/blackberry/variables_rtl.less  |   32 +
 dojox/mobile/themes/common/Accordion-compat.less   |   30 +
 dojox/mobile/themes/common/Accordion.less          |   67 +
 dojox/mobile/themes/common/Button-compat.less      |   46 +
 dojox/mobile/themes/common/Button.less             |   43 +-
 dojox/mobile/themes/common/Carousel.less           |   56 +-
 dojox/mobile/themes/common/Carousel_rtl.less       |   13 +
 dojox/mobile/themes/common/CheckBox-compat.less    |   40 +
 dojox/mobile/themes/common/CheckBox.less           |   29 +-
 dojox/mobile/themes/common/ComboBox-compat.less    |    9 +
 dojox/mobile/themes/common/ComboBox.less           |   11 +-
 dojox/mobile/themes/common/ComboBox_rtl.less       |    4 +
 dojox/mobile/themes/common/EdgeToEdgeCategory.less |    7 +-
 dojox/mobile/themes/common/EdgeToEdgeList.less     |    4 +-
 dojox/mobile/themes/common/FixedSplitter.css       |   22 -
 dojox/mobile/themes/common/FixedSplitter.less      |   22 +
 dojox/mobile/themes/common/FormLayout.less         |  218 +
 dojox/mobile/themes/common/GridLayout.less         |   28 +
 dojox/mobile/themes/common/Heading-compat.less     |   13 +
 dojox/mobile/themes/common/Heading.less            |   42 +-
 .../mobile/themes/common/IconContainer-compat.less |   16 +
 dojox/mobile/themes/common/IconContainer.less      |   95 +-
 dojox/mobile/themes/common/IconContainer_rtl.less  |   14 +
 dojox/mobile/themes/common/IconMenu-compat.less    |   44 +
 dojox/mobile/themes/common/IconMenu.less           |   62 +
 .../mobile/themes/common/IconMenu_rtl-compat.less  |   19 +
 dojox/mobile/themes/common/IconMenu_rtl.less       |   87 +
 dojox/mobile/themes/common/ListItem-compat.less    |   16 +
 dojox/mobile/themes/common/ListItem.less           |  111 +-
 dojox/mobile/themes/common/ListItem_rtl.less       |   27 +
 dojox/mobile/themes/common/Overlay-compat.less     |   22 +
 dojox/mobile/themes/common/PageIndicator.less      |    5 +-
 dojox/mobile/themes/common/PageTurning.css         |   38 +
 dojox/mobile/themes/common/ProgressBar-compat.less |   17 +
 dojox/mobile/themes/common/ProgressBar.less        |   27 +
 .../themes/common/ProgressIndicator-compat.less    |   89 +
 dojox/mobile/themes/common/ProgressIndicator.less  |  126 +-
 dojox/mobile/themes/common/RadioButton-compat.less |   34 +
 dojox/mobile/themes/common/RadioButton.less        |   27 +-
 dojox/mobile/themes/common/RoundRect-compat.less   |   80 +
 dojox/mobile/themes/common/RoundRect.less          |    7 +-
 dojox/mobile/themes/common/RoundRectCategory.less  |    4 +
 .../themes/common/RoundRectCategory_rtl.less       |    4 +
 .../mobile/themes/common/RoundRectList-compat.less |   84 +
 dojox/mobile/themes/common/RoundRectList.less      |   26 +-
 dojox/mobile/themes/common/ScrollablePane.less     |   12 +
 dojox/mobile/themes/common/SearchBox-compat.less   |   31 +
 dojox/mobile/themes/common/SearchBox.less          |  110 +
 .../mobile/themes/common/SimpleDialog-compat.less  |   16 +
 dojox/mobile/themes/common/SimpleDialog.less       |   37 +
 dojox/mobile/themes/common/Slider-compat.less      |   45 +
 dojox/mobile/themes/common/Slider.less             |   24 +-
 dojox/mobile/themes/common/SpinWheel-compat.css    |   36 -
 dojox/mobile/themes/common/SpinWheel-compat.less   |   48 +
 dojox/mobile/themes/common/SpinWheel.css           |   77 -
 dojox/mobile/themes/common/SpinWheel.less          |   92 +
 .../mobile/themes/common/SpinWheel_rtl-compat.less |    4 +
 dojox/mobile/themes/common/SpinWheel_rtl.less      |    5 +
 dojox/mobile/themes/common/Switch-compat.less      |  139 +
 dojox/mobile/themes/common/Switch.css              |  224 -
 dojox/mobile/themes/common/Switch.less             |  211 +-
 dojox/mobile/themes/common/Switch_rtl-compat.less  |   43 +
 dojox/mobile/themes/common/Switch_rtl.less         |  117 +
 dojox/mobile/themes/common/TabBar-compat.less      |   81 +
 dojox/mobile/themes/common/TabBar.less             |  324 +-
 dojox/mobile/themes/common/TabBar_rtl-compat.less  |   20 +
 dojox/mobile/themes/common/TabBar_rtl.less         |   89 +
 dojox/mobile/themes/common/TextArea-compat.less    |   10 +
 dojox/mobile/themes/common/TextArea.less           |    7 +-
 dojox/mobile/themes/common/TextBox-compat.less     |    6 +
 dojox/mobile/themes/common/TextBox.less            |    5 +
 .../mobile/themes/common/ToggleButton-compat.less  |   50 +
 dojox/mobile/themes/common/ToggleButton.less       |   58 +-
 dojox/mobile/themes/common/ToggleButton_rtl.less   |    7 +
 .../mobile/themes/common/ToolBarButton-compat.less |   84 +
 dojox/mobile/themes/common/ToolBarButton.less      |  100 +-
 dojox/mobile/themes/common/ToolBarButton_rtl.less  |   18 +
 dojox/mobile/themes/common/Tooltip-compat.less     |   51 +
 dojox/mobile/themes/common/Tooltip.less            |   10 +-
 dojox/mobile/themes/common/ValuePicker-compat.less |   23 +
 dojox/mobile/themes/common/ValuePicker.less        |   54 +
 dojox/mobile/themes/common/common-compat.less      |   20 +
 dojox/mobile/themes/common/common.less             |   33 +-
 dojox/mobile/themes/common/compile.js              |   42 -
 dojox/mobile/themes/common/css3.less               |  308 +
 .../mobile/themes/common/dijit/Calendar-compat.css |    9 -
 .../themes/common/dijit/Calendar-compat.less       |   44 +
 dojox/mobile/themes/common/dijit/Calendar.css      |  135 -
 dojox/mobile/themes/common/dijit/Calendar.less     |  106 +
 dojox/mobile/themes/common/dijit/ColorPalette.css  |    3 +-
 dojox/mobile/themes/common/dijit/ColorPicker.css   |    2 +-
 dojox/mobile/themes/common/dijit/base.css          |    1 -
 dojox/mobile/themes/common/dijit/dijit-compat.css  |    1 -
 dojox/mobile/themes/common/dijit/dijit.css         |    1 -
 dojox/mobile/themes/common/domButtons-compat.css   |   10 +
 dojox/mobile/themes/common/domButtons.css          |   18 +
 .../domButtons/DomButtonBlackCircleCross.css       |   78 +-
 .../domButtons/DomButtonBlackCircleCross.less      |   50 +
 .../DomButtonBlackDownArrow16-compat.css           |    8 +
 .../domButtons/DomButtonBlackDownArrow16.css       |   23 +
 .../domButtons/DomButtonBlackDownArrow16.less      |   23 +
 .../DomButtonBlackLeftArrow16-compat.css           |    8 +
 .../domButtons/DomButtonBlackLeftArrow16.css       |   23 +
 .../domButtons/DomButtonBlackLeftArrow16.less      |   23 +
 .../DomButtonBlackRightArrow16-compat.css          |    8 +
 .../domButtons/DomButtonBlackRightArrow16.css      |   23 +
 .../domButtons/DomButtonBlackRightArrow16.less     |   23 +
 .../domButtons/DomButtonBlackUpArrow16-compat.css  |    8 +
 .../common/domButtons/DomButtonBlackUpArrow16.css  |   23 +
 .../common/domButtons/DomButtonBlackUpArrow16.less |   23 +
 .../domButtons/DomButtonBlueBadge-compat.css       |    6 +
 .../common/domButtons/DomButtonBlueBadge.css       |   29 +
 .../common/domButtons/DomButtonBlueBadge.less      |   28 +
 .../themes/common/domButtons/DomButtonBlueBall.css |   21 +-
 .../common/domButtons/DomButtonBlueBall.less       |   16 +
 .../common/domButtons/DomButtonBlueCircleArrow.css |   76 +-
 .../domButtons/DomButtonBlueCircleArrow.less       |   49 +
 .../common/domButtons/DomButtonBlueCircleMinus.css |   57 +-
 .../domButtons/DomButtonBlueCircleMinus.less       |   38 +
 .../common/domButtons/DomButtonBlueCirclePlus.css  |   73 +-
 .../common/domButtons/DomButtonBlueCirclePlus.less |   48 +
 .../common/domButtons/DomButtonCheckboxOff.css     |   69 +-
 .../common/domButtons/DomButtonCheckboxOff.less    |   41 +
 .../common/domButtons/DomButtonCheckboxOn.css      |   69 +-
 .../common/domButtons/DomButtonCheckboxOn.less     |   41 +
 .../common/domButtons/DomButtonColorButtons.css    |  116 +-
 .../common/domButtons/DomButtonColorButtons.less   |   56 +
 .../common/domButtons/DomButtonDarkBlueCheck.css   |   33 +-
 .../common/domButtons/DomButtonDarkBlueCheck.less  |   19 +
 .../domButtons/DomButtonDarkBlueCheck_rtl.css      |    8 +
 .../domButtons/DomButtonDarkBlueCheck_rtl.less     |    8 +
 .../common/domButtons/DomButtonGrayArrow.css       |   33 +-
 .../common/domButtons/DomButtonGrayArrow.less      |   19 +
 .../domButtons/DomButtonGrayArrow_rtl-compat.css   |    6 +
 .../common/domButtons/DomButtonGrayArrow_rtl.css   |    8 +
 .../common/domButtons/DomButtonGrayArrow_rtl.less  |    8 +
 .../domButtons/DomButtonGrayCross-compat.css       |    8 +
 .../common/domButtons/DomButtonGrayCross.css       |   33 +
 .../common/domButtons/DomButtonGrayCross.less      |   33 +
 .../common/domButtons/DomButtonGrayKnob-compat.css |    9 +
 .../themes/common/domButtons/DomButtonGrayKnob.css |   45 +
 .../common/domButtons/DomButtonGrayKnob.less       |   40 +
 .../domButtons/DomButtonGrayMinus-compat.css       |    8 +
 .../common/domButtons/DomButtonGrayMinus.css       |   20 +
 .../common/domButtons/DomButtonGrayMinus.less      |   19 +
 .../common/domButtons/DomButtonGrayPlus-compat.css |    8 +
 .../themes/common/domButtons/DomButtonGrayPlus.css |   35 +
 .../common/domButtons/DomButtonGrayPlus.less       |   32 +
 .../common/domButtons/DomButtonGrayRoundRect.css   |   32 +-
 .../common/domButtons/DomButtonGrayRoundRect.less  |   24 +
 .../themes/common/domButtons/DomButtonGrayStar.css |   79 +-
 .../common/domButtons/DomButtonGrayStar.less       |   50 +
 .../domButtons/DomButtonGreenBadge-compat.css      |    6 +
 .../common/domButtons/DomButtonGreenBadge.css      |   29 +
 .../common/domButtons/DomButtonGreenBadge.less     |   28 +
 .../common/domButtons/DomButtonGreenBall.css       |   21 +-
 .../common/domButtons/DomButtonGreenBall.less      |   16 +
 .../domButtons/DomButtonGreenCircleArrow.css       |   76 +-
 .../domButtons/DomButtonGreenCircleArrow.less      |   49 +
 .../domButtons/DomButtonGreenCircleMinus.css       |   57 +-
 .../domButtons/DomButtonGreenCircleMinus.less      |   38 +
 .../common/domButtons/DomButtonGreenCirclePlus.css |   73 +-
 .../domButtons/DomButtonGreenCirclePlus.less       |   48 +
 .../common/domButtons/DomButtonOrangeBall.css      |   21 +-
 .../common/domButtons/DomButtonOrangeBall.less     |   16 +
 .../common/domButtons/DomButtonRedBadge-compat.css |    6 +
 .../themes/common/domButtons/DomButtonRedBadge.css |   29 +
 .../common/domButtons/DomButtonRedBadge.less       |   28 +
 .../themes/common/domButtons/DomButtonRedBall.css  |   21 +-
 .../themes/common/domButtons/DomButtonRedBall.less |   16 +
 .../common/domButtons/DomButtonRedCircleArrow.css  |   76 +-
 .../common/domButtons/DomButtonRedCircleArrow.less |   49 +
 .../common/domButtons/DomButtonRedCircleMinus.css  |   57 +-
 .../common/domButtons/DomButtonRedCircleMinus.less |   38 +
 .../common/domButtons/DomButtonRedCirclePlus.css   |   73 +-
 .../common/domButtons/DomButtonRedCirclePlus.less  |   48 +
 .../common/domButtons/DomButtonRedCross-compat.css |    8 +
 .../themes/common/domButtons/DomButtonRedCross.css |   33 +
 .../common/domButtons/DomButtonRedCross.less       |   33 +
 .../domButtons/DomButtonSilverCircleDownArrow.css  |   68 +-
 .../domButtons/DomButtonSilverCircleDownArrow.less |   44 +
 .../domButtons/DomButtonSilverCircleGrayButton.css |   43 +-
 .../DomButtonSilverCircleGrayButton.less           |   28 +
 .../DomButtonSilverCircleGreenButton.css           |   43 +-
 .../DomButtonSilverCircleGreenButton.less          |   28 +
 .../domButtons/DomButtonSilverCircleGreenPlus.css  |   58 +-
 .../domButtons/DomButtonSilverCircleGreenPlus.less |   38 +
 .../DomButtonSilverCircleOrangeButton.css          |   43 +-
 .../DomButtonSilverCircleOrangeButton.less         |   28 +
 .../domButtons/DomButtonSilverCircleRedCross.css   |   61 +-
 .../domButtons/DomButtonSilverCircleRedCross.less  |   39 +
 .../common/domButtons/DomButtonTransparent19.css   |    6 +-
 .../common/domButtons/DomButtonTransparent19.less  |    7 +
 .../common/domButtons/DomButtonTransparent29.css   |    6 +-
 .../common/domButtons/DomButtonTransparent29.less  |    7 +
 .../common/domButtons/DomButtonTransparent30.css   |    6 +-
 .../common/domButtons/DomButtonTransparent30.less  |    7 +
 .../common/domButtons/DomButtonWhiteArrow.css      |   33 +-
 .../common/domButtons/DomButtonWhiteArrow.less     |   19 +
 .../common/domButtons/DomButtonWhiteCheck.css      |   33 +-
 .../common/domButtons/DomButtonWhiteCheck.less     |   19 +
 .../common/domButtons/DomButtonWhiteCheck_rtl.css  |    8 +
 .../common/domButtons/DomButtonWhiteCheck_rtl.less |    8 +
 .../domButtons/DomButtonWhiteCross-compat.css      |    8 +
 .../common/domButtons/DomButtonWhiteCross.css      |   33 +
 .../common/domButtons/DomButtonWhiteCross.less     |   33 +
 .../common/domButtons/DomButtonWhiteDownArrow.css  |   31 +-
 .../common/domButtons/DomButtonWhiteDownArrow.less |   23 +
 .../DomButtonWhiteDownArrow16-compat.css           |    8 +
 .../domButtons/DomButtonWhiteDownArrow16.css       |   23 +
 .../domButtons/DomButtonWhiteDownArrow16.less      |   23 +
 .../DomButtonWhiteLeftArrow16-compat.css           |    8 +
 .../domButtons/DomButtonWhiteLeftArrow16.css       |   23 +
 .../domButtons/DomButtonWhiteLeftArrow16.less      |   23 +
 .../domButtons/DomButtonWhiteMinus-compat.css      |    8 +
 .../common/domButtons/DomButtonWhiteMinus.css      |   19 +
 .../common/domButtons/DomButtonWhiteMinus.less     |   18 +
 .../common/domButtons/DomButtonWhitePlus.css       |   50 +-
 .../common/domButtons/DomButtonWhitePlus.less      |   29 +
 .../DomButtonWhiteRightArrow16-compat.css          |    8 +
 .../domButtons/DomButtonWhiteRightArrow16.css      |   23 +
 .../domButtons/DomButtonWhiteRightArrow16.less     |   23 +
 .../common/domButtons/DomButtonWhiteSearch.css     |   47 +-
 .../common/domButtons/DomButtonWhiteSearch.less    |   31 +
 .../common/domButtons/DomButtonWhiteUpArrow.css    |   31 +-
 .../common/domButtons/DomButtonWhiteUpArrow.less   |   23 +
 .../domButtons/DomButtonWhiteUpArrow16-compat.css  |    8 +
 .../common/domButtons/DomButtonWhiteUpArrow16.css  |   23 +
 .../common/domButtons/DomButtonWhiteUpArrow16.less |   23 +
 .../common/domButtons/DomButtonYellowStar.css      |   79 +-
 .../common/domButtons/DomButtonYellowStar.less     |   50 +
 .../compat/mblDomButtonBlackDownArrow16.png        |  Bin 0 -> 216 bytes
 .../compat/mblDomButtonBlackLeftArrow16.png        |  Bin 0 -> 191 bytes
 .../compat/mblDomButtonBlackRightArrow16.png       |  Bin 0 -> 194 bytes
 .../compat/mblDomButtonBlackUpArrow16.png          |  Bin 0 -> 202 bytes
 .../compat/mblDomButtonGrayArrow_rtl.png           |  Bin 0 -> 110 bytes
 .../domButtons/compat/mblDomButtonGrayCross.png    |  Bin 0 -> 284 bytes
 .../domButtons/compat/mblDomButtonGrayKnob.png     |  Bin 0 -> 924 bytes
 .../domButtons/compat/mblDomButtonGrayMinus.png    |  Bin 0 -> 939 bytes
 .../domButtons/compat/mblDomButtonGrayPlus.png     |  Bin 0 -> 964 bytes
 .../domButtons/compat/mblDomButtonRedCross.png     |  Bin 0 -> 293 bytes
 .../domButtons/compat/mblDomButtonWhiteCross.png   |  Bin 0 -> 224 bytes
 .../compat/mblDomButtonWhiteDownArrow16.png        |  Bin 0 -> 229 bytes
 .../compat/mblDomButtonWhiteLeftArrow16.png        |  Bin 0 -> 205 bytes
 .../domButtons/compat/mblDomButtonWhiteMinus.png   |  Bin 0 -> 158 bytes
 .../domButtons/compat/mblDomButtonWhitePlus.png    |  Bin 918 -> 939 bytes
 .../compat/mblDomButtonWhiteRightArrow16.png       |  Bin 0 -> 214 bytes
 .../compat/mblDomButtonWhiteUpArrow16.png          |  Bin 0 -> 212 bytes
 dojox/mobile/themes/common/transitions.css         |    2 +
 dojox/mobile/themes/common/transitions/cover.css   |   54 +-
 dojox/mobile/themes/common/transitions/cover.less  |   27 +
 dojox/mobile/themes/common/transitions/coverv.css  |   55 +-
 dojox/mobile/themes/common/transitions/coverv.less |   27 +
 dojox/mobile/themes/common/transitions/cube.css    |  473 +
 dojox/mobile/themes/common/transitions/cube.less   |  130 +
 .../mobile/themes/common/transitions/dissolve.css  |   52 +-
 .../mobile/themes/common/transitions/dissolve.less |   15 +
 dojox/mobile/themes/common/transitions/fade.css    |   36 +-
 dojox/mobile/themes/common/transitions/fade.less   |   23 +
 dojox/mobile/themes/common/transitions/flip.css    |   57 +-
 dojox/mobile/themes/common/transitions/flip.less   |   33 +
 dojox/mobile/themes/common/transitions/reveal.css  |   56 +-
 dojox/mobile/themes/common/transitions/reveal.less |   29 +
 dojox/mobile/themes/common/transitions/revealv.css |   52 +-
 .../mobile/themes/common/transitions/revealv.less  |   29 +
 dojox/mobile/themes/common/transitions/scaleIn.css |   82 +-
 .../mobile/themes/common/transitions/scaleIn.less  |   21 +
 .../mobile/themes/common/transitions/scaleOut.css  |   82 +-
 .../mobile/themes/common/transitions/scaleOut.less |   21 +
 dojox/mobile/themes/common/transitions/slide.css   |   64 +-
 dojox/mobile/themes/common/transitions/slide.less  |   25 +
 dojox/mobile/themes/common/transitions/slidev.css  |   63 +-
 dojox/mobile/themes/common/transitions/slidev.less |   26 +
 dojox/mobile/themes/common/transitions/swap.css    |  158 +
 dojox/mobile/themes/common/transitions/swap.less   |   25 +
 dojox/mobile/themes/common/transitions/swirl.css   |   72 +-
 dojox/mobile/themes/common/transitions/swirl.less  |   21 +
 dojox/mobile/themes/common/transitions/zoomIn.css  |   82 +-
 dojox/mobile/themes/common/transitions/zoomIn.less |   21 +
 dojox/mobile/themes/common/transitions/zoomOut.css |   82 +-
 .../mobile/themes/common/transitions/zoomOut.less  |   21 +
 dojox/mobile/themes/custom/Accordion-compat.css    |   19 +
 dojox/mobile/themes/custom/Accordion.css           |   71 +
 dojox/mobile/themes/custom/Button-compat.css       |   43 +-
 dojox/mobile/themes/custom/Button.css              |   74 +-
 dojox/mobile/themes/custom/Button.less             |    2 -
 dojox/mobile/themes/custom/Carousel.css            |   57 +-
 dojox/mobile/themes/custom/Carousel.less           |    2 -
 dojox/mobile/themes/custom/Carousel_rtl.css        |   13 +
 dojox/mobile/themes/custom/CheckBox-compat.css     |   58 +-
 dojox/mobile/themes/custom/CheckBox.css            |   55 +-
 dojox/mobile/themes/custom/CheckBox.less           |    2 -
 dojox/mobile/themes/custom/ComboBox-compat.css     |   12 +-
 dojox/mobile/themes/custom/ComboBox.css            |   30 +-
 dojox/mobile/themes/custom/ComboBox.less           |    2 -
 dojox/mobile/themes/custom/ComboBox_rtl.css        |    4 +
 dojox/mobile/themes/custom/DatePicker.css          |    2 +
 .../themes/custom/EdgeToEdgeCategory-compat.css    |    4 -
 dojox/mobile/themes/custom/EdgeToEdgeCategory.css  |   25 +-
 dojox/mobile/themes/custom/EdgeToEdgeCategory.less |    2 -
 dojox/mobile/themes/custom/EdgeToEdgeList.css      |    7 +-
 dojox/mobile/themes/custom/EdgeToEdgeList.less     |    2 -
 dojox/mobile/themes/custom/FixedSplitter.css       |   19 +
 dojox/mobile/themes/custom/FormLayout.css          |  190 +
 dojox/mobile/themes/custom/GridLayout.css          |   24 +
 dojox/mobile/themes/custom/Heading-compat.css      |   47 +-
 dojox/mobile/themes/custom/Heading.css             |   70 +-
 dojox/mobile/themes/custom/Heading.less            |    2 -
 .../mobile/themes/custom/IconContainer-compat.css  |   16 +-
 .../mobile/themes/custom/IconContainer-compat.less |    5 +
 dojox/mobile/themes/custom/IconContainer.css       |  228 +-
 dojox/mobile/themes/custom/IconContainer.less      |    2 +-
 dojox/mobile/themes/custom/IconContainer_rtl.css   |   14 +
 dojox/mobile/themes/custom/IconMenu-compat.css     |   34 +
 dojox/mobile/themes/custom/IconMenu.css            |   63 +
 dojox/mobile/themes/custom/IconMenu_rtl-compat.css |   17 +
 dojox/mobile/themes/custom/IconMenu_rtl.css        |   23 +
 dojox/mobile/themes/custom/ListItem-compat.css     |   19 +-
 dojox/mobile/themes/custom/ListItem-compat.less    |    5 +
 dojox/mobile/themes/custom/ListItem.css            |  128 +-
 dojox/mobile/themes/custom/ListItem_rtl-compat.css |    1 +
 dojox/mobile/themes/custom/ListItem_rtl.css        |   29 +
 dojox/mobile/themes/custom/ListItem_rtl.less       |    4 +
 dojox/mobile/themes/custom/Opener.css              |    4 +
 dojox/mobile/themes/custom/Overlay-compat.css      |   13 +-
 dojox/mobile/themes/custom/Overlay.css             |    7 +-
 .../mobile/themes/custom/PageIndicator-compat.css  |    4 +
 dojox/mobile/themes/custom/PageIndicator.css       |    3 +-
 dojox/mobile/themes/custom/PageIndicator.less      |    2 -
 dojox/mobile/themes/custom/ProgressBar-compat.css  |    9 +
 dojox/mobile/themes/custom/ProgressBar.css         |   30 +
 .../themes/custom/ProgressIndicator-compat.css     |  101 +-
 dojox/mobile/themes/custom/ProgressIndicator.css   |  111 +-
 dojox/mobile/themes/custom/ProgressIndicator.less  |    2 -
 dojox/mobile/themes/custom/RadioButton-compat.css  |   52 +-
 dojox/mobile/themes/custom/RadioButton.css         |   49 +-
 dojox/mobile/themes/custom/RadioButton.less        |    2 -
 dojox/mobile/themes/custom/RoundRect-compat.css    |  136 +-
 dojox/mobile/themes/custom/RoundRect.css           |   14 +-
 dojox/mobile/themes/custom/RoundRect.less          |    2 -
 dojox/mobile/themes/custom/RoundRectCategory.css   |   11 +-
 dojox/mobile/themes/custom/RoundRectCategory.less  |    2 -
 .../mobile/themes/custom/RoundRectCategory_rtl.css |    4 +
 .../mobile/themes/custom/RoundRectList-compat.css  |  161 +-
 dojox/mobile/themes/custom/RoundRectList.css       |   26 +-
 dojox/mobile/themes/custom/RoundRectList.less      |    2 -
 dojox/mobile/themes/custom/ScrollablePane.css      |   12 +
 dojox/mobile/themes/custom/SearchBox-compat.css    |   26 +
 dojox/mobile/themes/custom/SearchBox.css           |   61 +
 dojox/mobile/themes/custom/SimpleDialog-compat.css |    4 +
 dojox/mobile/themes/custom/SimpleDialog.css        |   48 +
 dojox/mobile/themes/custom/Slider-compat.css       |   66 +-
 dojox/mobile/themes/custom/Slider.css              |   40 +-
 dojox/mobile/themes/custom/Slider.less             |    2 -
 dojox/mobile/themes/custom/SpinWheel-compat.css    |   36 +
 dojox/mobile/themes/custom/SpinWheel.css           |   77 +
 .../mobile/themes/custom/SpinWheel_rtl-compat.css  |    4 +
 dojox/mobile/themes/custom/SpinWheel_rtl.css       |    5 +
 dojox/mobile/themes/custom/Switch-compat.css       |  159 +-
 dojox/mobile/themes/custom/Switch-compat.less      |    7 +
 dojox/mobile/themes/custom/Switch.css              |  233 +-
 dojox/mobile/themes/custom/Switch.less             |    7 +-
 dojox/mobile/themes/custom/Switch_rtl-compat.css   |   43 +
 dojox/mobile/themes/custom/Switch_rtl.css          |  117 +
 dojox/mobile/themes/custom/TabBar-compat.css       |  110 +-
 dojox/mobile/themes/custom/TabBar-compat.less      |    3 +
 dojox/mobile/themes/custom/TabBar.css              |  317 +-
 dojox/mobile/themes/custom/TabBar.less             |    1 +
 dojox/mobile/themes/custom/TabBar_rtl-compat.css   |   19 +
 dojox/mobile/themes/custom/TabBar_rtl.css          |   89 +
 dojox/mobile/themes/custom/TextArea-compat.css     |    8 +-
 dojox/mobile/themes/custom/TextArea.css            |    9 +-
 dojox/mobile/themes/custom/TextArea.less           |    2 -
 dojox/mobile/themes/custom/TextBox-compat.css      |    7 +-
 dojox/mobile/themes/custom/TextBox.css             |   11 +-
 dojox/mobile/themes/custom/TextBox.less            |    2 -
 dojox/mobile/themes/custom/TimePicker.css          |    2 +
 dojox/mobile/themes/custom/ToggleButton-compat.css |   53 +-
 dojox/mobile/themes/custom/ToggleButton.css        |   72 +-
 dojox/mobile/themes/custom/ToggleButton.less       |    2 -
 dojox/mobile/themes/custom/ToggleButton_rtl.css    |    7 +
 .../mobile/themes/custom/ToolBarButton-compat.css  |   63 +
 dojox/mobile/themes/custom/ToolBarButton.css       |  100 +-
 dojox/mobile/themes/custom/ToolBarButton.less      |    2 -
 dojox/mobile/themes/custom/ToolBarButton_rtl.css   |   18 +
 dojox/mobile/themes/custom/Tooltip-compat.css      |   75 +-
 dojox/mobile/themes/custom/Tooltip.css             |   47 +-
 dojox/mobile/themes/custom/Tooltip.less            |    2 -
 dojox/mobile/themes/custom/ValuePicker-compat.css  |   19 +
 dojox/mobile/themes/custom/ValuePicker.css         |   57 +
 dojox/mobile/themes/custom/ValuePicker.less        |    5 +
 dojox/mobile/themes/custom/View.css                |    2 +-
 dojox/mobile/themes/custom/base-compat.css         |    2 +-
 dojox/mobile/themes/custom/base_rtl-compat.css     |    3 +
 dojox/mobile/themes/custom/base_rtl.css            |    7 +
 dojox/mobile/themes/custom/common-compat.css       |   22 +-
 dojox/mobile/themes/custom/common.css              |   55 +-
 .../themes/custom/compat/arrow-button-bg-sel.png   |  Bin 0 -> 193 bytes
 .../themes/custom/compat/arrow-button-bg.png       |  Bin 0 -> 191 bytes
 .../themes/custom/compat/arrow-button-head-sel.png |  Bin 0 -> 482 bytes
 .../themes/custom/compat/arrow-button-head.png     |  Bin 503 -> 452 bytes
 .../custom/compat/arrow-button-right-head-sel.png  |  Bin 0 -> 528 bytes
 .../custom/compat/arrow-button-right-head.png      |  Bin 0 -> 484 bytes
 .../mobile/themes/custom/compat/blue-button-bg.png |  Bin 0 -> 209 bytes
 .../themes/custom/compat/blue-button-sel-bg.png    |  Bin 0 -> 191 bytes
 .../themes/custom/compat/button-arrow-head-bg.gif  |  Bin 0 -> 340 bytes
 dojox/mobile/themes/custom/compat/button-bg.png    |  Bin 0 -> 141 bytes
 .../mobile/themes/custom/compat/button-chk-bg.png  |  Bin 0 -> 141 bytes
 .../mobile/themes/custom/compat/button-sel-bg.png  |  Bin 0 -> 191 bytes
 .../themes/custom/compat/button-unsel-bg.png       |  Bin 0 -> 191 bytes
 dojox/mobile/themes/custom/compat/heading-bg.png   |  Bin 339 -> 173 bytes
 .../custom/compat/icon-content-heading-bg.png      |  Bin 0 -> 193 bytes
 .../mobile/themes/custom/compat/red-button-bg.png  |  Bin 0 -> 213 bytes
 .../themes/custom/compat/red-button-sel-bg.png     |  Bin 0 -> 191 bytes
 .../themes/custom/compat/slider-h-bar-bg.png       |  Bin 135 -> 162 bytes
 dojox/mobile/themes/custom/compat/slider-h-bg.png  |  Bin 0 -> 141 bytes
 .../themes/custom/compat/slider-handle-bg.png      |  Bin 0 -> 171 bytes
 .../mobile/themes/custom/compat/switch-arc1-k.gif  |  Bin 0 -> 304 bytes
 .../mobile/themes/custom/compat/switch-arc1-l.gif  |  Bin 0 -> 489 bytes
 .../mobile/themes/custom/compat/switch-arc1-r.gif  |  Bin 0 -> 351 bytes
 .../mobile/themes/custom/compat/switch-arc2-k.gif  |  Bin 0 -> 339 bytes
 .../mobile/themes/custom/compat/switch-arc2-l.gif  |  Bin 0 -> 512 bytes
 .../mobile/themes/custom/compat/switch-arc2-r.gif  |  Bin 0 -> 367 bytes
 .../themes/custom/compat/switch-round1-k.gif       |  Bin 0 -> 334 bytes
 .../themes/custom/compat/switch-round1-l.gif       |  Bin 0 -> 500 bytes
 .../themes/custom/compat/switch-round1-r.gif       |  Bin 0 -> 374 bytes
 .../themes/custom/compat/switch-round2-k.gif       |  Bin 0 -> 380 bytes
 .../themes/custom/compat/switch-round2-l.gif       |  Bin 0 -> 476 bytes
 .../themes/custom/compat/switch-round2-r.gif       |  Bin 0 -> 397 bytes
 .../themes/custom/compat/switch-square-k.gif       |  Bin 0 -> 297 bytes
 .../themes/custom/compat/switch-square-l.gif       |  Bin 0 -> 411 bytes
 .../themes/custom/compat/switch-square-r.gif       |  Bin 0 -> 321 bytes
 .../themes/custom/compat/tab-seg-button-bg.png     |  Bin 0 -> 169 bytes
 .../themes/custom/compat/tab-seg-sel-button-bg.png |  Bin 0 -> 200 bytes
 .../themes/custom/compat/tab-slim-bar-bg.png       |  Bin 0 -> 107 bytes
 .../themes/custom/compat/tab-tall-bar-bg.png       |  Bin 0 -> 161 bytes
 .../custom/compat/togglebutton-chk-mark-bg.png     |  Bin 0 -> 157 bytes
 dojox/mobile/themes/custom/compat/ui-widget-bg.png |  Bin 680 -> 0 bytes
 .../themes/custom/compat/valuepicker-button-bg.png |  Bin 0 -> 265 bytes
 dojox/mobile/themes/custom/custom-compat.css       |    7 +-
 dojox/mobile/themes/custom/custom.css              |   14 +-
 dojox/mobile/themes/custom/custom_rtl-compat.css   |    7 +
 dojox/mobile/themes/custom/custom_rtl.css          |   15 +
 .../mobile/themes/custom/dijit/Calendar-compat.css |   35 +
 .../themes/custom/dijit/Calendar-compat.less       |    2 +
 dojox/mobile/themes/custom/dijit/Calendar.css      |  119 +
 dojox/mobile/themes/custom/dijit/Calendar.less     |    2 +
 .../dijit/compat/calendar-datelabel-act-bg.png     |  Bin 0 -> 203 bytes
 .../dijit/compat/calendar-datelabel-sel-bg.png     |  Bin 0 -> 201 bytes
 .../custom/dijit/compat/calendar-month-bg.png      |  Bin 0 -> 180 bytes
 .../custom/dijit/compat/calendar-year-bg.png       |  Bin 0 -> 180 bytes
 dojox/mobile/themes/custom/variables.less          | 1392 +-
 dojox/mobile/themes/custom/variables_rtl.less      |   32 +
 dojox/mobile/themes/holodark/Accordion-compat.css  |   28 +
 dojox/mobile/themes/holodark/Accordion.css         |   74 +
 dojox/mobile/themes/holodark/Button-compat.css     |   59 +
 dojox/mobile/themes/holodark/Button-compat.less    |   21 +
 dojox/mobile/themes/holodark/Button.css            |   86 +
 dojox/mobile/themes/holodark/Button.less           |   20 +
 dojox/mobile/themes/holodark/Carousel.css          |   79 +
 dojox/mobile/themes/holodark/Carousel_rtl.css      |   13 +
 dojox/mobile/themes/holodark/CheckBox-compat.css   |   38 +
 dojox/mobile/themes/holodark/CheckBox.css          |   85 +
 dojox/mobile/themes/holodark/CheckBox.less         |   32 +
 dojox/mobile/themes/holodark/ComboBox-compat.css   |    7 +
 dojox/mobile/themes/holodark/ComboBox.css          |   48 +
 dojox/mobile/themes/holodark/ComboBox_rtl.css      |    4 +
 dojox/mobile/themes/holodark/DatePicker.css        |    2 +
 .../mobile/themes/holodark/EdgeToEdgeCategory.css  |   21 +
 dojox/mobile/themes/holodark/EdgeToEdgeList.css    |   10 +
 dojox/mobile/themes/holodark/FixedSplitter.css     |   19 +
 dojox/mobile/themes/holodark/FormLayout.css        |  190 +
 dojox/mobile/themes/holodark/GridLayout.css        |   24 +
 dojox/mobile/themes/holodark/Heading-compat.css    |   13 +
 dojox/mobile/themes/holodark/Heading-compat.less   |    6 +
 dojox/mobile/themes/holodark/Heading.css           |   40 +
 .../themes/holodark/IconContainer-compat.css       |   13 +
 .../themes/holodark/IconContainer-compat.less      |    5 +
 dojox/mobile/themes/holodark/IconContainer.css     |  261 +
 dojox/mobile/themes/holodark/IconContainer.less    |    5 +
 dojox/mobile/themes/holodark/IconContainer_rtl.css |   14 +
 dojox/mobile/themes/holodark/IconMenu-compat.css   |   34 +
 dojox/mobile/themes/holodark/IconMenu.css          |   63 +
 .../mobile/themes/holodark/IconMenu_rtl-compat.css |   17 +
 dojox/mobile/themes/holodark/IconMenu_rtl.css      |   23 +
 dojox/mobile/themes/holodark/ListItem-compat.css   |   13 +
 dojox/mobile/themes/holodark/ListItem-compat.less  |    5 +
 dojox/mobile/themes/holodark/ListItem.css          |  119 +
 dojox/mobile/themes/holodark/ListItem.less         |    5 +
 .../mobile/themes/holodark/ListItem_rtl-compat.css |    1 +
 dojox/mobile/themes/holodark/ListItem_rtl.css      |   29 +
 dojox/mobile/themes/holodark/ListItem_rtl.less     |    4 +
 dojox/mobile/themes/holodark/Opener-compat.css     |    3 +
 dojox/mobile/themes/holodark/Opener.css            |    7 +
 dojox/mobile/themes/holodark/Overlay-compat.css    |   14 +
 dojox/mobile/themes/holodark/Overlay.css           |   19 +
 dojox/mobile/themes/holodark/Overlay.less          |    5 +
 .../themes/holodark/PageIndicator-compat.css       |    4 +
 dojox/mobile/themes/holodark/PageIndicator.css     |   23 +
 .../mobile/themes/holodark/ProgressBar-compat.css  |   17 +
 dojox/mobile/themes/holodark/ProgressBar.css       |   35 +
 dojox/mobile/themes/holodark/ProgressBar.less      |    6 +
 .../themes/holodark/ProgressIndicator-compat.css   |   83 +
 dojox/mobile/themes/holodark/ProgressIndicator.css |  157 +
 .../mobile/themes/holodark/RadioButton-compat.css  |   32 +
 dojox/mobile/themes/holodark/RadioButton.css       |   87 +
 dojox/mobile/themes/holodark/RadioButton.less      |   37 +
 dojox/mobile/themes/holodark/RoundRect-compat.css  |   73 +
 dojox/mobile/themes/holodark/RoundRect.css         |   13 +
 dojox/mobile/themes/holodark/RoundRectCategory.css |   10 +
 .../themes/holodark/RoundRectCategory_rtl.css      |    4 +
 .../themes/holodark/RoundRectList-compat.css       |   78 +
 dojox/mobile/themes/holodark/RoundRectList.css     |   19 +
 dojox/mobile/themes/holodark/ScrollablePane.css    |   12 +
 dojox/mobile/themes/holodark/SearchBox-compat.css  |   26 +
 dojox/mobile/themes/holodark/SearchBox.css         |   61 +
 .../mobile/themes/holodark/SimpleDialog-compat.css |   10 +
 dojox/mobile/themes/holodark/SimpleDialog.css      |   54 +
 dojox/mobile/themes/holodark/Slider-compat.css     |   40 +
 dojox/mobile/themes/holodark/Slider.css            |   98 +
 dojox/mobile/themes/holodark/Slider.less           |   45 +
 dojox/mobile/themes/holodark/SpinWheel-compat.css  |   36 +
 dojox/mobile/themes/holodark/SpinWheel.css         |   77 +
 .../themes/holodark/SpinWheel_rtl-compat.css       |    4 +
 dojox/mobile/themes/holodark/SpinWheel_rtl.css     |    5 +
 dojox/mobile/themes/holodark/Switch-compat.css     |  116 +
 dojox/mobile/themes/holodark/Switch-compat.less    |    7 +
 dojox/mobile/themes/holodark/Switch.css            |  240 +
 dojox/mobile/themes/holodark/Switch.less           |   23 +
 dojox/mobile/themes/holodark/Switch_rtl-compat.css |   43 +
 dojox/mobile/themes/holodark/Switch_rtl.css        |  117 +
 dojox/mobile/themes/holodark/TabBar-compat.css     |   80 +
 dojox/mobile/themes/holodark/TabBar-compat.less    |   22 +
 dojox/mobile/themes/holodark/TabBar.css            |  318 +
 dojox/mobile/themes/holodark/TabBar.less           |   37 +
 dojox/mobile/themes/holodark/TabBar_rtl-compat.css |   19 +
 dojox/mobile/themes/holodark/TabBar_rtl.css        |   89 +
 dojox/mobile/themes/holodark/TextArea-compat.css   |    7 +
 dojox/mobile/themes/holodark/TextArea.css          |   23 +
 dojox/mobile/themes/holodark/TextBox-compat.css    |    4 +
 dojox/mobile/themes/holodark/TextBox.css           |   27 +
 dojox/mobile/themes/holodark/TextBox.less          |   13 +
 dojox/mobile/themes/holodark/TimePicker.css        |    2 +
 .../mobile/themes/holodark/ToggleButton-compat.css |   42 +
 dojox/mobile/themes/holodark/ToggleButton.css      |   54 +
 dojox/mobile/themes/holodark/ToggleButton_rtl.css  |    7 +
 .../themes/holodark/ToolBarButton-compat.css       |   63 +
 dojox/mobile/themes/holodark/ToolBarButton.css     |   90 +
 dojox/mobile/themes/holodark/ToolBarButton_rtl.css |   18 +
 dojox/mobile/themes/holodark/Tooltip-compat.css    |   40 +
 dojox/mobile/themes/holodark/Tooltip.css           |  152 +
 .../mobile/themes/holodark/ValuePicker-compat.css  |   22 +
 .../mobile/themes/holodark/ValuePicker-compat.less |    6 +
 dojox/mobile/themes/holodark/ValuePicker.css       |   60 +
 dojox/mobile/themes/holodark/ValuePicker.less      |   11 +
 dojox/mobile/themes/holodark/View.css              |   24 +
 dojox/mobile/themes/holodark/View.less             |    6 +
 dojox/mobile/themes/holodark/android-compat.css    |   23 +
 .../mobile/themes/holodark/android_rtl-compat.css  |    7 +
 dojox/mobile/themes/holodark/base-compat.css       |    8 +
 dojox/mobile/themes/holodark/base.css              |   12 +
 dojox/mobile/themes/holodark/base_rtl-compat.css   |    3 +
 dojox/mobile/themes/holodark/base_rtl.css          |    7 +
 dojox/mobile/themes/holodark/common-compat.css     |   18 +
 dojox/mobile/themes/holodark/common.css            |   52 +
 .../themes/holodark/compat/arrow-button-bg-sel.png |  Bin 0 -> 189 bytes
 .../themes/holodark/compat/arrow-button-bg.png     |  Bin 0 -> 157 bytes
 .../holodark/compat/arrow-button-head-sel.png      |  Bin 0 -> 1134 bytes
 .../themes/holodark/compat/arrow-button-head.png   |  Bin 0 -> 1068 bytes
 .../compat/arrow-button-right-head-sel.png         |  Bin 0 -> 1129 bytes
 .../holodark/compat/arrow-button-right-head.png    |  Bin 0 -> 1073 bytes
 .../themes/holodark/compat/blue-button-bg.png      |  Bin 0 -> 199 bytes
 .../themes/holodark/compat/blue-button-sel-bg.png  |  Bin 0 -> 207 bytes
 .../holodark/compat/button-arrow-head-bg.gif       |  Bin 0 -> 316 bytes
 dojox/mobile/themes/holodark/compat/button-bg.png  |  Bin 0 -> 169 bytes
 .../themes/holodark/compat/button-chk-bg.png       |  Bin 0 -> 154 bytes
 .../themes/holodark/compat/button-sel-bg.png       |  Bin 0 -> 207 bytes
 .../themes/holodark/compat/button-unsel-bg.png     |  Bin 0 -> 207 bytes
 dojox/mobile/themes/holodark/compat/gray-arrow.png |  Bin 0 -> 920 bytes
 dojox/mobile/themes/holodark/compat/heading-bg.png |  Bin 0 -> 181 bytes
 .../holodark/compat/icon-content-heading-bg.png    |  Bin 0 -> 193 bytes
 .../themes/holodark/compat/red-button-bg.png       |  Bin 0 -> 248 bytes
 .../themes/holodark/compat/red-button-sel-bg.png   |  Bin 0 -> 207 bytes
 .../themes/holodark/compat/slider-h-bar-bg.png     |  Bin 0 -> 124 bytes
 .../mobile/themes/holodark/compat/slider-h-bg.png  |  Bin 0 -> 135 bytes
 .../themes/holodark/compat/slider-handle-bg.png    |  Bin 0 -> 156 bytes
 .../themes/holodark/compat/switch-arc1-k.gif       |  Bin 0 -> 492 bytes
 .../themes/holodark/compat/switch-arc1-l.gif       |  Bin 0 -> 803 bytes
 .../themes/holodark/compat/switch-arc1-r.gif       |  Bin 0 -> 691 bytes
 .../themes/holodark/compat/switch-arc2-k.gif       |  Bin 0 -> 536 bytes
 .../themes/holodark/compat/switch-arc2-l.gif       |  Bin 0 -> 827 bytes
 .../themes/holodark/compat/switch-arc2-r.gif       |  Bin 0 -> 728 bytes
 .../themes/holodark/compat/switch-round1-k.gif     |  Bin 0 -> 511 bytes
 .../themes/holodark/compat/switch-round1-l.gif     |  Bin 0 -> 851 bytes
 .../themes/holodark/compat/switch-round1-r.gif     |  Bin 0 -> 936 bytes
 .../themes/holodark/compat/switch-round2-k.gif     |  Bin 0 -> 566 bytes
 .../themes/holodark/compat/switch-round2-l.gif     |  Bin 0 -> 883 bytes
 .../themes/holodark/compat/switch-round2-r.gif     |  Bin 0 -> 974 bytes
 .../themes/holodark/compat/switch-square-k.gif     |  Bin 0 -> 388 bytes
 .../themes/holodark/compat/switch-square-l.gif     |  Bin 0 -> 578 bytes
 .../themes/holodark/compat/switch-square-r.gif     |  Bin 0 -> 686 bytes
 .../themes/holodark/compat/tab-button-bg.png       |  Bin 0 -> 277 bytes
 .../holodark/compat/tab-orange-button-bg.png       |  Bin 0 -> 197 bytes
 .../themes/holodark/compat/tab-seg-button-bg.png   |  Bin 0 -> 157 bytes
 .../holodark/compat/tab-seg-sel-button-bg.png      |  Bin 0 -> 178 bytes
 .../themes/holodark/compat/tab-sel-button-bg.png   |  Bin 0 -> 286 bytes
 .../themes/holodark/compat/tab-slim-bar-bg.png     |  Bin 0 -> 107 bytes
 .../themes/holodark/compat/tab-tall-bar-bg.png     |  Bin 0 -> 161 bytes
 .../themes/holodark/compat/togglebutton-chk-bg.png |  Bin 0 -> 154 bytes
 .../holodark/compat/togglebutton-chk-mark-bg.png   |  Bin 0 -> 150 bytes
 .../holodark/compat/valuepicker-button-bg.png      |  Bin 0 -> 246 bytes
 .../themes/holodark/dijit/Calendar-compat.css      |   31 +
 .../themes/holodark/dijit/Calendar-compat.less     |    2 +
 dojox/mobile/themes/holodark/dijit/Calendar.css    |  113 +
 dojox/mobile/themes/holodark/dijit/Calendar.less   |    9 +
 .../dijit/compat/calendar-datelabel-act-bg.png     |  Bin 0 -> 209 bytes
 .../dijit/compat/calendar-datelabel-sel-bg.png     |  Bin 0 -> 144 bytes
 .../holodark/dijit/compat/calendar-month-bg.png    |  Bin 0 -> 186 bytes
 .../holodark/dijit/compat/calendar-year-bg.png     |  Bin 0 -> 177 bytes
 dojox/mobile/themes/holodark/holodark.css          |   31 +
 dojox/mobile/themes/holodark/holodark_rtl.css      |   15 +
 .../themes/holodark/images/thumb-overlay-large.png |  Bin 0 -> 3697 bytes
 .../themes/holodark/images/thumb-overlay-small.png |  Bin 0 -> 1549 bytes
 .../themes/holodark/images/thumb-overlay.png       |  Bin 0 -> 2010 bytes
 dojox/mobile/themes/holodark/images/vseparator.png |  Bin 0 -> 160 bytes
 dojox/mobile/themes/holodark/variables.less        |  914 +
 dojox/mobile/themes/holodark/variables_rtl.less    |   32 +
 dojox/mobile/themes/iphone/Accordion-compat.css    |   25 +
 dojox/mobile/themes/iphone/Accordion.css           |   73 +
 dojox/mobile/themes/iphone/Button-compat.css       |   48 +-
 dojox/mobile/themes/iphone/Button.css              |   58 +-
 dojox/mobile/themes/iphone/Button.less             |    2 -
 dojox/mobile/themes/iphone/Carousel.css            |   57 +-
 dojox/mobile/themes/iphone/Carousel.less           |    2 -
 dojox/mobile/themes/iphone/Carousel_rtl.css        |   13 +
 dojox/mobile/themes/iphone/CheckBox-compat.css     |   58 +-
 dojox/mobile/themes/iphone/CheckBox.css            |   39 +-
 dojox/mobile/themes/iphone/CheckBox.less           |    2 -
 dojox/mobile/themes/iphone/ComboBox-compat.css     |   12 +-
 dojox/mobile/themes/iphone/ComboBox.css            |   18 +-
 dojox/mobile/themes/iphone/ComboBox.less           |    2 -
 dojox/mobile/themes/iphone/ComboBox_rtl.css        |    4 +
 dojox/mobile/themes/iphone/DatePicker.css          |    2 +
 .../themes/iphone/EdgeToEdgeCategory-compat.css    |    4 +
 dojox/mobile/themes/iphone/EdgeToEdgeCategory.css  |   19 +-
 dojox/mobile/themes/iphone/EdgeToEdgeCategory.less |    2 -
 dojox/mobile/themes/iphone/EdgeToEdgeList.css      |    9 +-
 dojox/mobile/themes/iphone/EdgeToEdgeList.less     |    2 -
 dojox/mobile/themes/iphone/FixedSplitter.css       |   19 +
 dojox/mobile/themes/iphone/FormLayout.css          |  190 +
 dojox/mobile/themes/iphone/GridLayout.css          |   24 +
 dojox/mobile/themes/iphone/Heading-compat.css      |   24 +-
 dojox/mobile/themes/iphone/Heading.css             |   74 +-
 dojox/mobile/themes/iphone/Heading.less            |   13 +
 .../mobile/themes/iphone/IconContainer-compat.css  |   16 +-
 .../mobile/themes/iphone/IconContainer-compat.less |    5 +
 dojox/mobile/themes/iphone/IconContainer.css       |  202 +-
 dojox/mobile/themes/iphone/IconContainer.less      |    2 +-
 dojox/mobile/themes/iphone/IconContainer_rtl.css   |   14 +
 dojox/mobile/themes/iphone/IconMenu-compat.css     |   37 +
 dojox/mobile/themes/iphone/IconMenu.css            |   67 +
 dojox/mobile/themes/iphone/IconMenu_rtl-compat.css |   17 +
 dojox/mobile/themes/iphone/IconMenu_rtl.css        |   23 +
 dojox/mobile/themes/iphone/ListItem-compat.css     |   14 +-
 dojox/mobile/themes/iphone/ListItem-compat.less    |    5 +
 dojox/mobile/themes/iphone/ListItem.css            |  117 +-
 dojox/mobile/themes/iphone/ListItem.less           |   12 +
 dojox/mobile/themes/iphone/ListItem_rtl-compat.css |    1 +
 dojox/mobile/themes/iphone/ListItem_rtl.css        |   29 +
 dojox/mobile/themes/iphone/ListItem_rtl.less       |    4 +
 dojox/mobile/themes/iphone/Overlay-compat.css      |   18 +-
 dojox/mobile/themes/iphone/Overlay.css             |    4 +-
 .../mobile/themes/iphone/PageIndicator-compat.css  |    4 +
 dojox/mobile/themes/iphone/PageIndicator.css       |    3 +-
 dojox/mobile/themes/iphone/PageIndicator.less      |    2 -
 dojox/mobile/themes/iphone/ProgressBar-compat.css  |   15 +
 dojox/mobile/themes/iphone/ProgressBar.css         |   33 +
 .../themes/iphone/ProgressIndicator-compat.css     |  101 +-
 dojox/mobile/themes/iphone/ProgressIndicator.css   |  111 +-
 dojox/mobile/themes/iphone/ProgressIndicator.less  |    2 -
 dojox/mobile/themes/iphone/RadioButton-compat.css  |   53 +-
 dojox/mobile/themes/iphone/RadioButton.css         |   38 +-
 dojox/mobile/themes/iphone/RadioButton.less        |    2 -
 dojox/mobile/themes/iphone/RoundRect-compat.css    |  133 +-
 dojox/mobile/themes/iphone/RoundRect.css           |   10 +-
 dojox/mobile/themes/iphone/RoundRect.less          |    2 -
 dojox/mobile/themes/iphone/RoundRectCategory.css   |   12 +-
 dojox/mobile/themes/iphone/RoundRectCategory.less  |    2 -
 .../mobile/themes/iphone/RoundRectCategory_rtl.css |    4 +
 .../mobile/themes/iphone/RoundRectList-compat.css  |  138 +-
 dojox/mobile/themes/iphone/RoundRectList.css       |   34 +-
 dojox/mobile/themes/iphone/RoundRectList.less      |    2 -
 dojox/mobile/themes/iphone/ScrollablePane.css      |   12 +
 dojox/mobile/themes/iphone/SearchBox-compat.css    |   26 +
 dojox/mobile/themes/iphone/SearchBox.css           |   61 +
 dojox/mobile/themes/iphone/SimpleDialog-compat.css |   12 +
 dojox/mobile/themes/iphone/SimpleDialog.css        |   70 +
 dojox/mobile/themes/iphone/SimpleDialog.less       |   23 +
 dojox/mobile/themes/iphone/Slider-compat.css       |   67 +-
 dojox/mobile/themes/iphone/Slider.css              |   35 +-
 dojox/mobile/themes/iphone/Slider.less             |    2 -
 dojox/mobile/themes/iphone/SpinWheel-compat.css    |   36 +
 dojox/mobile/themes/iphone/SpinWheel.css           |   81 +
 dojox/mobile/themes/iphone/SpinWheel.less          |    8 +
 .../mobile/themes/iphone/SpinWheel_rtl-compat.css  |    4 +
 dojox/mobile/themes/iphone/SpinWheel_rtl.css       |    5 +
 dojox/mobile/themes/iphone/Switch-compat.css       |  136 +-
 dojox/mobile/themes/iphone/Switch-compat.less      |    7 +
 dojox/mobile/themes/iphone/Switch.css              |  229 +-
 dojox/mobile/themes/iphone/Switch.less             |   15 +-
 dojox/mobile/themes/iphone/Switch_rtl-compat.css   |   43 +
 dojox/mobile/themes/iphone/Switch_rtl.css          |  117 +
 dojox/mobile/themes/iphone/TabBar-compat.css       |   72 +-
 dojox/mobile/themes/iphone/TabBar-compat.less      |    3 +
 dojox/mobile/themes/iphone/TabBar.css              |  320 +-
 dojox/mobile/themes/iphone/TabBar.less             |   22 +
 dojox/mobile/themes/iphone/TabBar_rtl-compat.css   |   19 +
 dojox/mobile/themes/iphone/TabBar_rtl.css          |   89 +
 dojox/mobile/themes/iphone/TextArea-compat.css     |    8 +-
 dojox/mobile/themes/iphone/TextArea.css            |    4 +-
 dojox/mobile/themes/iphone/TextArea.less           |    2 -
 dojox/mobile/themes/iphone/TextBox-compat.css      |    7 +-
 dojox/mobile/themes/iphone/TextBox.css             |    6 +-
 dojox/mobile/themes/iphone/TextBox.less            |    2 -
 dojox/mobile/themes/iphone/TimePicker.css          |    2 +
 dojox/mobile/themes/iphone/ToggleButton-compat.css |   52 +-
 dojox/mobile/themes/iphone/ToggleButton.css        |   46 +-
 dojox/mobile/themes/iphone/ToggleButton.less       |    2 -
 dojox/mobile/themes/iphone/ToggleButton_rtl.css    |    7 +
 .../mobile/themes/iphone/ToolBarButton-compat.css  |   72 +
 dojox/mobile/themes/iphone/ToolBarButton.css       |  108 +-
 dojox/mobile/themes/iphone/ToolBarButton.less      |    8 +
 dojox/mobile/themes/iphone/ToolBarButton_rtl.css   |   18 +
 dojox/mobile/themes/iphone/Tooltip-compat.css      |   72 +-
 dojox/mobile/themes/iphone/Tooltip.css             |   38 +-
 dojox/mobile/themes/iphone/Tooltip.less            |    2 -
 dojox/mobile/themes/iphone/ValuePicker-compat.css  |   19 +
 dojox/mobile/themes/iphone/ValuePicker.css         |   60 +
 dojox/mobile/themes/iphone/ValuePicker.less        |    5 +
 dojox/mobile/themes/iphone/base-compat.css         |    2 +
 dojox/mobile/themes/iphone/base_rtl-compat.css     |    3 +
 dojox/mobile/themes/iphone/base_rtl.css            |    7 +
 dojox/mobile/themes/iphone/common-compat.css       |   18 +
 dojox/mobile/themes/iphone/common.css              |   93 +-
 dojox/mobile/themes/iphone/common.less             |   40 +
 .../themes/iphone/compat/arrow-button-bg-sel.png   |  Bin 0 -> 183 bytes
 .../themes/iphone/compat/arrow-button-bg.png       |  Bin 195 -> 202 bytes
 .../themes/iphone/compat/arrow-button-head-sel.png |  Bin 0 -> 418 bytes
 .../themes/iphone/compat/arrow-button-head.png     |  Bin 878 -> 453 bytes
 .../iphone/compat/arrow-button-right-head-sel.png  |  Bin 0 -> 373 bytes
 .../iphone/compat/arrow-button-right-head.png      |  Bin 0 -> 406 bytes
 .../themes/iphone/compat/button-arrow-head-bg.gif  |  Bin 0 -> 316 bytes
 .../mobile/themes/iphone/compat/button-chk-bg.png  |  Bin 0 -> 199 bytes
 .../themes/iphone/compat/button-unsel-bg.png       |  Bin 0 -> 182 bytes
 .../themes/iphone/compat/ipad-arrow-button-bg.png  |  Bin 181 -> 220 bytes
 .../iphone/compat/ipad-arrow-button-head-sel.png   |  Bin 0 -> 382 bytes
 .../iphone/compat/ipad-arrow-button-head.png       |  Bin 1212 -> 393 bytes
 .../compat/ipad-arrow-button-right-head-sel.png    |  Bin 0 -> 370 bytes
 .../iphone/compat/ipad-arrow-button-right-head.png |  Bin 0 -> 371 bytes
 .../iphone/compat/ipad-arrow-button-sel-bg.png     |  Bin 0 -> 229 bytes
 .../mobile/themes/iphone/compat/switch-arc1-k.gif  |  Bin 524 -> 392 bytes
 .../mobile/themes/iphone/compat/switch-arc1-l.gif  |  Bin 0 -> 903 bytes
 .../mobile/themes/iphone/compat/switch-arc1-r.gif  |  Bin 0 -> 474 bytes
 .../mobile/themes/iphone/compat/switch-arc2-k.gif  |  Bin 604 -> 435 bytes
 .../mobile/themes/iphone/compat/switch-arc2-l.gif  |  Bin 0 -> 946 bytes
 .../mobile/themes/iphone/compat/switch-arc2-r.gif  |  Bin 0 -> 492 bytes
 .../themes/iphone/compat/switch-round1-k.gif       |  Bin 548 -> 500 bytes
 .../themes/iphone/compat/switch-round1-l.gif       |  Bin 0 -> 925 bytes
 .../themes/iphone/compat/switch-round1-r.gif       |  Bin 0 -> 508 bytes
 .../themes/iphone/compat/switch-round2-k.gif       |  Bin 636 -> 554 bytes
 .../themes/iphone/compat/switch-round2-l.gif       |  Bin 0 -> 968 bytes
 .../themes/iphone/compat/switch-round2-r.gif       |  Bin 0 -> 527 bytes
 .../themes/iphone/compat/switch-square-k.gif       |  Bin 0 -> 405 bytes
 .../themes/iphone/compat/switch-square-l.gif       |  Bin 0 -> 733 bytes
 .../themes/iphone/compat/switch-square-r.gif       |  Bin 0 -> 484 bytes
 .../themes/iphone/compat/tab-seg-button-bg.png     |  Bin 0 -> 205 bytes
 .../themes/iphone/compat/tab-seg-sel-button-bg.png |  Bin 0 -> 169 bytes
 .../themes/iphone/compat/tab-slim-bar-bg.png       |  Bin 0 -> 107 bytes
 .../themes/iphone/compat/tab-tall-bar-bg.png       |  Bin 0 -> 126 bytes
 .../iphone/compat/togglebutton-chk-mark-bg.png     |  Bin 0 -> 150 bytes
 .../themes/iphone/compat/valuepicker-button-bg.png |  Bin 0 -> 265 bytes
 .../mobile/themes/iphone/dijit/Calendar-compat.css |   27 +
 .../themes/iphone/dijit/Calendar-compat.less       |    2 +
 dojox/mobile/themes/iphone/dijit/Calendar.css      |  123 +
 dojox/mobile/themes/iphone/dijit/Calendar.less     |    2 +
 .../dijit/compat/calendar-daylabel-bg.png          |  Bin 130 -> 130 bytes
 .../dijit/compat/calendar-month-bg.png             |  Bin 185 -> 185 bytes
 .../dijit/compat/calendar-year-bg.png              |  Bin 177 -> 177 bytes
 dojox/mobile/themes/iphone/ipad-compat.css         |   71 +-
 dojox/mobile/themes/iphone/ipad.css                |  162 +-
 dojox/mobile/themes/iphone/iphone-app-compat.css   |    4 +
 dojox/mobile/themes/iphone/iphone-app.css          |   18 +-
 dojox/mobile/themes/iphone/iphone-compat.css       |    8 +-
 dojox/mobile/themes/iphone/iphone.css              |   14 +-
 dojox/mobile/themes/iphone/iphone_rtl-compat.css   |    7 +
 dojox/mobile/themes/iphone/iphone_rtl.css          |   15 +
 dojox/mobile/themes/iphone/variables.less          | 1025 +-
 dojox/mobile/themes/iphone/variables_rtl.less      |   32 +
 dojox/mobile/themes/utils/README                   |   26 +
 dojox/mobile/themes/utils/cleanup.bat              |    2 +
 dojox/mobile/themes/utils/cleanup.js               |   46 +
 dojox/mobile/themes/utils/cleanup.sh               |    1 +
 dojox/mobile/themes/utils/compile.bat              |    3 +
 dojox/mobile/themes/utils/compile.js               |  118 +
 dojox/mobile/themes/utils/compile.sh               |    2 +
 dojox/mobile/themes/windows/Accordion-compat.css   |   30 +
 dojox/mobile/themes/windows/Accordion.css          |  111 +
 dojox/mobile/themes/windows/Accordion.less         |   31 +
 dojox/mobile/themes/windows/Button-compat.css      |   55 +
 dojox/mobile/themes/windows/Button.css             |   64 +
 dojox/mobile/themes/windows/Button.less            |    6 +
 dojox/mobile/themes/windows/Carousel.css           |   93 +
 dojox/mobile/themes/windows/Carousel_rtl.css       |   13 +
 dojox/mobile/themes/windows/CheckBox-compat.css    |   52 +
 dojox/mobile/themes/windows/CheckBox.css           |   97 +
 dojox/mobile/themes/windows/CheckBox.less          |   37 +
 dojox/mobile/themes/windows/ComboBox-compat.css    |   21 +
 dojox/mobile/themes/windows/ComboBox.css           |   90 +
 dojox/mobile/themes/windows/ComboBox.less          |   28 +
 dojox/mobile/themes/windows/ComboBox_rtl.css       |    4 +
 dojox/mobile/themes/windows/DatePicker.css         |    2 +
 dojox/mobile/themes/windows/EdgeToEdgeCategory.css |   45 +
 .../mobile/themes/windows/EdgeToEdgeCategory.less  |   10 +
 dojox/mobile/themes/windows/EdgeToEdgeList.css     |   24 +
 .../{android => windows}/EdgeToEdgeList.less       |    0
 dojox/mobile/themes/windows/FixedSplitter.css      |   33 +
 dojox/mobile/themes/windows/FormLayout.css         |  204 +
 dojox/mobile/themes/windows/GridLayout.css         |   38 +
 dojox/mobile/themes/windows/Heading-compat.css     |   24 +
 dojox/mobile/themes/windows/Heading.css            |   88 +
 dojox/mobile/themes/windows/Heading.less           |   42 +
 .../mobile/themes/windows/IconContainer-compat.css |   27 +
 .../themes/windows/IconContainer-compat.less       |    5 +
 dojox/mobile/themes/windows/IconContainer.css      |  317 +
 dojox/mobile/themes/windows/IconContainer.less     |   51 +
 dojox/mobile/themes/windows/IconContainer_rtl.css  |   14 +
 dojox/mobile/themes/windows/IconMenu-compat.css    |   45 +
 dojox/mobile/themes/windows/IconMenu.css           |   77 +
 .../mobile/themes/windows/IconMenu_rtl-compat.css  |   17 +
 dojox/mobile/themes/windows/IconMenu_rtl.css       |   23 +
 dojox/mobile/themes/windows/ListItem-compat.css    |   27 +
 dojox/mobile/themes/windows/ListItem-compat.less   |    5 +
 dojox/mobile/themes/windows/ListItem.css           |  163 +
 dojox/mobile/themes/windows/ListItem.less          |   40 +
 dojox/mobile/themes/windows/ListItem_rtl.css       |   26 +
 dojox/mobile/themes/windows/Opener-compat.css      |    3 +
 dojox/mobile/themes/windows/Opener.css             |    7 +
 dojox/mobile/themes/windows/Overlay-compat.css     |   28 +
 dojox/mobile/themes/windows/Overlay.css            |   37 +
 dojox/mobile/themes/windows/Overlay.less           |    5 +
 .../mobile/themes/windows/PageIndicator-compat.css |    4 +
 dojox/mobile/themes/windows/PageIndicator.css      |   37 +
 dojox/mobile/themes/windows/ProgressBar-compat.css |   23 +
 dojox/mobile/themes/windows/ProgressBar.css        |   62 +
 dojox/mobile/themes/windows/ProgressBar.less       |   27 +
 .../themes/windows/ProgressIndicator-compat.css    |   97 +
 dojox/mobile/themes/windows/ProgressIndicator.css  |  174 +
 dojox/mobile/themes/windows/ProgressIndicator.less |    6 +
 dojox/mobile/themes/windows/RadioButton-compat.css |   46 +
 dojox/mobile/themes/windows/RadioButton.css        |   88 +
 dojox/mobile/themes/windows/RadioButton.less       |   33 +
 dojox/mobile/themes/windows/RoundRect-compat.css   |   87 +
 dojox/mobile/themes/windows/RoundRect.css          |   31 +
 dojox/mobile/themes/windows/RoundRectCategory.css  |   26 +
 .../themes/windows/RoundRectCategory_rtl.css       |    4 +
 .../mobile/themes/windows/RoundRectList-compat.css |   92 +
 dojox/mobile/themes/windows/RoundRectList.css      |   42 +
 dojox/mobile/themes/windows/RoundRectList.less     |   13 +
 dojox/mobile/themes/windows/ScrollablePane.css     |   33 +
 dojox/mobile/themes/windows/ScrollablePane.less    |   11 +
 dojox/mobile/themes/windows/SearchBox-compat.css   |   40 +
 dojox/mobile/themes/windows/SearchBox.css          |   82 +
 dojox/mobile/themes/windows/SearchBox.less         |   11 +
 .../mobile/themes/windows/SimpleDialog-compat.css  |   18 +
 dojox/mobile/themes/windows/SimpleDialog.css       |   83 +
 dojox/mobile/themes/windows/SimpleDialog.less      |   27 +
 dojox/mobile/themes/windows/Slider-compat.css      |   54 +
 dojox/mobile/themes/windows/Slider.css             |  123 +
 dojox/mobile/themes/windows/Slider.less            |   52 +
 dojox/mobile/themes/windows/SpinWheel-compat.css   |   50 +
 dojox/mobile/themes/windows/SpinWheel.css          |  180 +
 dojox/mobile/themes/windows/SpinWheel.less         |  112 +
 .../mobile/themes/windows/SpinWheel_rtl-compat.css |    4 +
 dojox/mobile/themes/windows/SpinWheel_rtl.css      |    5 +
 dojox/mobile/themes/windows/Switch-compat.css      |  130 +
 dojox/mobile/themes/windows/Switch-compat.less     |    7 +
 dojox/mobile/themes/windows/Switch.css             |  296 +
 dojox/mobile/themes/windows/Switch.less            |   73 +
 dojox/mobile/themes/windows/Switch_rtl-compat.css  |   43 +
 dojox/mobile/themes/windows/Switch_rtl.css         |  117 +
 dojox/mobile/themes/windows/TabBar-compat.css      |   73 +
 dojox/mobile/themes/windows/TabBar-compat.less     |    3 +
 dojox/mobile/themes/windows/TabBar.css             |  277 +
 dojox/mobile/themes/windows/TabBar.less            |   37 +
 dojox/mobile/themes/windows/TabBar_rtl-compat.css  |   19 +
 dojox/mobile/themes/windows/TabBar_rtl.css         |   89 +
 dojox/mobile/themes/windows/TextArea-compat.css    |   21 +
 dojox/mobile/themes/windows/TextArea.css           |   48 +
 dojox/mobile/themes/windows/TextArea.less          |   12 +
 dojox/mobile/themes/windows/TextBox-compat.css     |   18 +
 dojox/mobile/themes/windows/TextBox.css            |   48 +
 dojox/mobile/themes/windows/TextBox.less           |   16 +
 dojox/mobile/themes/windows/TimePicker.css         |    2 +
 .../mobile/themes/windows/ToggleButton-compat.css  |   56 +
 dojox/mobile/themes/windows/ToggleButton.css       |  117 +
 dojox/mobile/themes/windows/ToggleButton.less      |   49 +
 dojox/mobile/themes/windows/ToggleButton_rtl.css   |    7 +
 .../mobile/themes/windows/ToolBarButton-compat.css |   77 +
 dojox/mobile/themes/windows/ToolBarButton.css      |  135 +
 dojox/mobile/themes/windows/ToolBarButton.less     |   22 +
 dojox/mobile/themes/windows/ToolBarButton_rtl.css  |   18 +
 dojox/mobile/themes/windows/Tooltip-compat.css     |   54 +
 dojox/mobile/themes/windows/Tooltip.css            |  275 +
 dojox/mobile/themes/windows/Tooltip.less           |  146 +
 dojox/mobile/themes/windows/ValuePicker-compat.css |   33 +
 dojox/mobile/themes/windows/ValuePicker.css        |  104 +
 dojox/mobile/themes/windows/ValuePicker.less       |   55 +
 dojox/mobile/themes/windows/View.css               |   40 +
 dojox/mobile/themes/windows/View.less              |    6 +
 dojox/mobile/themes/windows/base-compat.css        |    8 +
 dojox/mobile/themes/windows/base.css               |   13 +
 dojox/mobile/themes/windows/common-compat.css      |   32 +
 dojox/mobile/themes/windows/common.css             |   93 +
 dojox/mobile/themes/windows/common.less            |   29 +
 .../themes/windows/compat/arrow-button-bg-sel.png  |  Bin 0 -> 189 bytes
 .../themes/windows/compat/arrow-button-bg.png      |  Bin 0 -> 157 bytes
 .../windows/compat/arrow-button-head-sel.png       |  Bin 0 -> 1134 bytes
 .../themes/windows/compat/arrow-button-head.png    |  Bin 0 -> 1068 bytes
 .../windows/compat/arrow-button-right-head-sel.png |  Bin 0 -> 1129 bytes
 .../windows/compat/arrow-button-right-head.png     |  Bin 0 -> 1073 bytes
 .../themes/windows/compat/blue-button-bg.png       |  Bin 0 -> 199 bytes
 .../themes/windows/compat/blue-button-sel-bg.png   |  Bin 0 -> 207 bytes
 .../themes/windows/compat/button-arrow-head-bg.gif |  Bin 0 -> 316 bytes
 dojox/mobile/themes/windows/compat/button-bg.png   |  Bin 0 -> 169 bytes
 .../mobile/themes/windows/compat/button-chk-bg.png |  Bin 0 -> 154 bytes
 .../mobile/themes/windows/compat/button-sel-bg.png |  Bin 0 -> 207 bytes
 .../themes/windows/compat/button-unsel-bg.png      |  Bin 0 -> 207 bytes
 dojox/mobile/themes/windows/compat/gray-arrow.png  |  Bin 0 -> 920 bytes
 dojox/mobile/themes/windows/compat/heading-bg.png  |  Bin 0 -> 181 bytes
 .../windows/compat/icon-content-heading-bg.png     |  Bin 0 -> 193 bytes
 .../mobile/themes/windows/compat/red-button-bg.png |  Bin 0 -> 248 bytes
 .../themes/windows/compat/red-button-sel-bg.png    |  Bin 0 -> 207 bytes
 .../themes/windows/compat/slider-h-bar-bg.png      |  Bin 0 -> 124 bytes
 dojox/mobile/themes/windows/compat/slider-h-bg.png |  Bin 0 -> 135 bytes
 .../themes/windows/compat/slider-handle-bg.png     |  Bin 0 -> 156 bytes
 .../mobile/themes/windows/compat/switch-arc1-k.gif |  Bin 0 -> 492 bytes
 .../mobile/themes/windows/compat/switch-arc1-l.gif |  Bin 0 -> 803 bytes
 .../mobile/themes/windows/compat/switch-arc1-r.gif |  Bin 0 -> 691 bytes
 .../mobile/themes/windows/compat/switch-arc2-k.gif |  Bin 0 -> 536 bytes
 .../mobile/themes/windows/compat/switch-arc2-l.gif |  Bin 0 -> 827 bytes
 .../mobile/themes/windows/compat/switch-arc2-r.gif |  Bin 0 -> 728 bytes
 .../themes/windows/compat/switch-round1-k.gif      |  Bin 0 -> 511 bytes
 .../themes/windows/compat/switch-round1-l.gif      |  Bin 0 -> 851 bytes
 .../themes/windows/compat/switch-round1-r.gif      |  Bin 0 -> 936 bytes
 .../themes/windows/compat/switch-round2-k.gif      |  Bin 0 -> 566 bytes
 .../themes/windows/compat/switch-round2-l.gif      |  Bin 0 -> 883 bytes
 .../themes/windows/compat/switch-round2-r.gif      |  Bin 0 -> 974 bytes
 .../themes/windows/compat/switch-square-k.gif      |  Bin 0 -> 388 bytes
 .../themes/windows/compat/switch-square-l.gif      |  Bin 0 -> 578 bytes
 .../themes/windows/compat/switch-square-r.gif      |  Bin 0 -> 686 bytes
 .../mobile/themes/windows/compat/tab-button-bg.png |  Bin 0 -> 277 bytes
 .../themes/windows/compat/tab-orange-button-bg.png |  Bin 0 -> 197 bytes
 .../themes/windows/compat/tab-seg-button-bg.png    |  Bin 0 -> 157 bytes
 .../windows/compat/tab-seg-sel-button-bg.png       |  Bin 0 -> 178 bytes
 .../themes/windows/compat/tab-sel-button-bg.png    |  Bin 0 -> 286 bytes
 .../themes/windows/compat/tab-slim-bar-bg.png      |  Bin 0 -> 107 bytes
 .../themes/windows/compat/tab-tall-bar-bg.png      |  Bin 0 -> 161 bytes
 .../themes/windows/compat/togglebutton-chk-bg.png  |  Bin 0 -> 154 bytes
 .../windows/compat/togglebutton-chk-mark-bg.png    |  Bin 0 -> 150 bytes
 .../windows/compat/valuepicker-button-bg.png       |  Bin 0 -> 246 bytes
 .../themes/windows/dijit/Calendar-compat.css       |   37 +
 .../themes/windows/dijit/Calendar-compat.less      |    2 +
 dojox/mobile/themes/windows/dijit/Calendar.css     |  123 +
 dojox/mobile/themes/windows/dijit/Calendar.less    |    2 +
 .../themes/windows/images/check-disabled.png       |  Bin 0 -> 3829 bytes
 dojox/mobile/themes/windows/images/dark/back.png   |  Bin 0 -> 3470 bytes
 dojox/mobile/themes/windows/images/dark/check.png  |  Bin 0 -> 3685 bytes
 .../mobile/themes/windows/images/dark/radiobtn.png |  Bin 0 -> 3807 bytes
 dojox/mobile/themes/windows/images/light/back.png  |  Bin 0 -> 3292 bytes
 dojox/mobile/themes/windows/images/light/check.png |  Bin 0 -> 3995 bytes
 .../themes/windows/images/light/radiobtn.png       |  Bin 0 -> 3736 bytes
 .../themes/windows/images/radiobtn-disabled.png    |  Bin 0 -> 3811 bytes
 dojox/mobile/themes/windows/variables.less         |  995 +
 dojox/mobile/themes/windows/variables_rtl.less     |   33 +
 dojox/mobile/themes/windows/windows-compat.css     |   23 +
 dojox/mobile/themes/windows/windows.css            |   31 +
 dojox/mobile/transition.js                         |   14 +-
 dojox/mobile/uacss.js                              |   26 +-
 dojox/mobile/viewRegistry.js                       |   94 +
 dojox/mvc.js                                       |   10 +-
 dojox/mvc/Bind.js                                  |   31 +-
 dojox/mvc/EditModelRefController.js                |  204 +
 dojox/mvc/EditStoreRefController.js                |  153 +
 dojox/mvc/EditStoreRefListController.js            |   64 +
 dojox/mvc/Element.js                               |   31 +
 dojox/mvc/Generate.js                              |  148 +-
 dojox/mvc/Group.js                                 |   41 +-
 dojox/mvc/ListController.js                        |  229 +
 dojox/mvc/ModelRefController.js                    |  198 +
 dojox/mvc/Output.js                                |   37 +-
 dojox/mvc/README                                   |   13 +-
 dojox/mvc/Repeat.js                                |  182 +-
 dojox/mvc/StatefulArray.js                         |  203 +
 dojox/mvc/StatefulModel.js                         |  364 +-
 dojox/mvc/StatefulSeries.js                        |   79 +
 dojox/mvc/StoreRefController.js                    |  156 +
 dojox/mvc/Templated.js                             |   34 +
 dojox/mvc/WidgetList.js                            |  286 +
 dojox/mvc/_Container.js                            |   23 +-
 dojox/mvc/_Controller.js                           |  131 +
 dojox/mvc/_DataBindingExtension.js                 |   26 +
 dojox/mvc/_DataBindingMixin.js                     |   99 +-
 dojox/mvc/_InlineTemplateMixin.js                  |   30 +
 dojox/mvc/_TextBoxExtensions.js                    |   33 +
 dojox/mvc/_atBindingExtension.js                   |   11 +
 dojox/mvc/_atBindingMixin.js                       |  268 +
 dojox/mvc/_base.js                                 |   25 +-
 dojox/mvc/_patches.js                              |   52 +-
 dojox/mvc/at.js                                    |  134 +
 dojox/mvc/atBindingExtension.js                    |   54 +
 dojox/mvc/equals.js                                |   81 +
 dojox/mvc/getPlainValue.js                         |   72 +
 dojox/mvc/getStateful.js                           |   67 +
 dojox/mvc/parserExtension.js                       |   75 +
 dojox/mvc/resolve.js                               |   36 +
 dojox/mvc/sync.js                                  |  260 +
 dojox/mvc/tests/{ => 1.7}/css/android-format.css   |    0
 dojox/mvc/tests/{ => 1.7}/css/app-format.css       |    0
 dojox/mvc/tests/{ => 1.7}/css/index-format.css     |    0
 dojox/mvc/tests/{ => 1.7}/css/iphone-format.css    |    0
 .../1.7/doh/doh_async_mvc_14491-input-output.html  |  161 +
 .../1.7/doh/doh_async_mvc_input-output-simple.html |  158 +
 .../tests/1.7/doh/doh_async_mvc_mobile-demo.html   |  342 +
 .../1.7/doh/doh_async_mvc_zero-value-test.html     |  139 +
 .../mvc/tests/1.7/doh/doh_mvc_binding-simple.html  |  429 +
 dojox/mvc/tests/1.7/doh/doh_mvc_date_test.html     |  697 +
 .../tests/1.7/doh/doh_mvc_form-kitchensink.html    | 1408 +
 .../1.7/doh/doh_mvc_programmatic-repeat-store.html |  348 +
 .../mvc/tests/1.7/doh/doh_mvc_ref-set-repeat.html  |  247 +
 .../doh/doh_mvc_search-results-repeat-store.html   |  278 +
 .../1.7/doh/doh_mvc_search-results-repeat.html     |  301 +
 .../doh/doh_mvc_shipto-billto-hierarchical.html    |  377 +
 .../1.7/doh/doh_mvc_shipto-billto-simple.html      |  215 +
 .../1.7/doh/doh_mvc_template_repeat_exprchar.html  |  237 +
 .../1.7/doh/doh_mvc_validation-test-simple.html    |  134 +
 dojox/mvc/tests/{ => 1.7}/helpers.js               |    0
 .../mvc/tests/1.7/images/MVC_patterns_in_Dojo.png  |  Bin 0 -> 4264 bytes
 dojox/mvc/tests/1.7/images/background.jpg          |  Bin 0 -> 70265 bytes
 dojox/mvc/tests/1.7/images/master_detail.png       |  Bin 0 -> 3054 bytes
 .../tests/1.7/images/validating_form_pattern.png   |  Bin 0 -> 3524 bytes
 .../tests/1.7/mobile/demo/demo-async-store.html    |  186 +
 dojox/mvc/tests/1.7/mobile/demo/demo-async.html    |  203 +
 dojox/mvc/tests/1.7/mobile/demo/demo-sync.html     |  201 +
 dojox/mvc/tests/{ => 1.7}/mobile/demo/demo.css     |    0
 dojox/mvc/tests/1.7/mobile/demo/demo.html          |  203 +
 .../tests/{ => 1.7}/mobile/demo/demo.profile.js    |    0
 .../tests/{ => 1.7}/mobile/demo/generateView.html  |    0
 dojox/mvc/tests/1.7/mobile/demo/iPad-Demo.html     |  213 +
 .../{ => 1.7}/mobile/demo/images/i-icon-1.png      |  Bin 486 -> 486 bytes
 .../{ => 1.7}/mobile/demo/images/i-icon-2.png      |  Bin 459 -> 459 bytes
 .../{ => 1.7}/mobile/demo/images/i-icon-3.png      |  Bin 306 -> 306 bytes
 .../mvc/tests/{ => 1.7}/mobile/demo/images/mvc.png |  Bin 3457 -> 3457 bytes
 .../{ => 1.7}/mobile/demo/repeatDataBinding.html   |    0
 .../tests/{ => 1.7}/mobile/demo/shipToBillTo.html  |    0
 .../tests/{ => 1.7}/mobile/demo/src-async-store.js |    0
 dojox/mvc/tests/{ => 1.7}/mobile/demo/src-async.js |    0
 dojox/mvc/tests/{ => 1.7}/mobile/demo/src-sync.js  |    0
 dojox/mvc/tests/{ => 1.7}/mobile/demo/src.js       |    0
 .../1.7/mobile/test_Android-repeat-data-store.html |  104 +
 .../1.7/mobile/test_iPhone-shipto-billto.html      |  121 +
 .../mobile/test_mobile-list-multiple-sel-mvc.html  |  210 +
 .../mobile/test_mobile-list-single-sel-mvc.html    |  212 +
 dojox/mvc/tests/1.7/models/LoanWizardModel.js      |  105 +
 dojox/mvc/tests/1.7/module.js                      |   33 +
 dojox/mvc/tests/{ => 1.7}/mvc_index.html           |    0
 dojox/mvc/tests/1.7/robot/android_repeat-ins.html  |  171 +
 .../mvc/tests/1.7/robot/iphone_shipto-billto.html  |  102 +
 dojox/mvc/tests/1.7/robot/mobile-demo-test.html    |  404 +
 dojox/mvc/tests/1.7/robot/moduleFullSet.js         |   27 +
 dojox/mvc/tests/1.7/robot/mvc_generate-view.html   |  179 +
 dojox/mvc/tests/1.7/robot/mvc_loan-stateful.html   |  160 +
 dojox/mvc/tests/1.7/robot/mvc_ref-set-repeat.html  |  156 +
 .../1.7/robot/mvc_search-results-ins-del.html      |  276 +
 .../tests/1.7/robot/mvc_search-results-repeat.html |  123 +
 .../1.7/robot/mvc_shipto-billto-hierarchical.html  |  103 +
 .../tests/1.7/robot/mvc_shipto-billto-simple.html  |  101 +
 dojox/mvc/tests/1.7/robot/runTestsFullSet.html     |    9 +
 .../mvc/tests/1.7/test_async-mvc_group-simple.html |   81 +
 .../1.7/test_async-mvc_input-output-simple.html    |   82 +
 .../tests/1.7/test_async-mvc_repeat-simple.html    |  193 +
 dojox/mvc/tests/1.7/test_mvc_bindings-simple.html  |  182 +
 dojox/mvc/tests/1.7/test_mvc_dates.html            |  407 +
 dojox/mvc/tests/1.7/test_mvc_form-kitchensink.html |  651 +
 .../tests/1.7/test_mvc_generate-view-store.html    |   71 +
 dojox/mvc/tests/1.7/test_mvc_generate-view.html    |   75 +
 .../tests/1.7/test_mvc_input-output-simple.html    |   84 +
 dojox/mvc/tests/1.7/test_mvc_loan-stateful.html    |  187 +
 dojox/mvc/tests/1.7/test_mvc_prog_repeat.html      |  219 +
 .../1.7/test_mvc_programmatic-repeat-store.html    |  147 +
 dojox/mvc/tests/1.7/test_mvc_ref-kitchensink.html  |  160 +
 .../tests/1.7/test_mvc_ref-set-repeat-simple.html  |  140 +
 .../mvc/tests/1.7/test_mvc_ref-template-13263.html |   63 +
 .../1.7/test_mvc_repeat-declarative-sync.html      |  205 +
 .../test_mvc_repeat-store-declarative-async.html   |  128 +
 .../tests/1.7/test_mvc_search-results-ins-del.html |  244 +
 .../1.7/test_mvc_search-results-repeat-store.html  |  116 +
 .../tests/1.7/test_mvc_search-results-repeat.html  |  222 +
 .../1.7/test_mvc_shipto-billto-hierarchical.html   |  198 +
 .../test_mvc_shipto-billto-simple-declarative.html |  132 +
 .../test_mvc_shipto-billto-simple-oldparser.html   |  131 +
 .../tests/1.7/test_mvc_shipto-billto-simple.html   |  130 +
 .../tests/1.7/test_mvc_simple-programmatic.html    |   64 +
 .../1.7/test_mvc_updateData-hack-support.html      |  221 +
 .../test_templatedWidget/myMvcTemplated.js         |    0
 .../{ => 1.7}/test_templatedWidget/readme.txt      |    0
 .../test_templatedWidget/test_mvc_widget.html      |    0
 .../test_mvc_widget_template.html                  |    0
 dojox/mvc/tests/{ => 1.7}/zips/10024.json          |    0
 dojox/mvc/tests/{ => 1.7}/zips/10706.json          |    0
 dojox/mvc/tests/WidgetList_tests/module.js         |   18 +
 dojox/mvc/tests/WidgetList_tests/runTests.html     |    9 +
 .../test_mobile-checkbox-list-mvc.html             |  474 +
 .../test_mobile-list-single-sel-mvc.html           |  171 +
 ...t_mobile-listItem-with-icon-and-sub-lables.html |  188 +
 .../mvc/tests/WidgetList_tests/test_mvc_Menu.html  |  466 +
 ...test_mvc_observable-search-results-ins-del.html |  370 +
 .../test_mvc_search-results-ins-del.html           |  299 +
 .../test_mvc_search-results-repeat.html            |  270 +
 .../test_nested_widgetLists-jsonRest-ins-del.html  |  213 +
 dojox/mvc/tests/_data/jsonRestRepeatData.json      |   29 +
 dojox/mvc/tests/controllers/readme.txt             |  113 +
 dojox/mvc/tests/controllers/step1_test_mvc.html    |  128 +
 dojox/mvc/tests/controllers/step2_test_mvc.html    |  131 +
 dojox/mvc/tests/controllers/step3_test_mvc.html    |  142 +
 dojox/mvc/tests/controllers/step4_test_mvc.html    |  148 +
 dojox/mvc/tests/controllers/step5_test_mvc.html    |  158 +
 dojox/mvc/tests/controllers/step6_test_mvc.html    |  236 +
 dojox/mvc/tests/controllers/step7_test_mvc.html    |  245 +
 dojox/mvc/tests/controllers/step8_test_mvc.html    |  247 +
 dojox/mvc/tests/controllers/step9_test_mvc.html    |  257 +
 dojox/mvc/tests/css/app-format.css                 |   10 +
 dojox/mvc/tests/css/dijitTests.css                 |  116 -
 .../docExamples/generateDeclarativeExample1.html   |   84 +
 .../docExamples/groupDeclarativeExample1.html      |  108 +
 .../docExamples/repeatDeclarativeExample1.html     |  107 +
 .../docExamples/widgetListDeclarativeExample1.html |  108 +
 .../widgetListProgrammaticExample1.html            |  121 +
 dojox/mvc/tests/doh/ModelRefController.js          |   28 +
 dojox/mvc/tests/doh/StatefulArray.js               |   51 +
 dojox/mvc/tests/doh/StatefulModelOptions.js        |   23 +
 dojox/mvc/tests/doh/StoreRefControllerTest.js      |  221 +
 dojox/mvc/tests/doh/WidgetList.js                  |  199 +
 .../doh_mvc_DOMNode-search-results-repeat.html     |  280 +
 .../doh/WidgetList_tests/doh_mvc_mobile-demo.html  |  348 +
 .../doh_mvc_new_ref-set-repeat.html                |  234 +
 .../doh_mvc_performance_search-results-repeat.html |  324 +
 .../doh_mvc_programmatic-repeat-store.html         |  191 +
 .../doh_mvc_repeat_select_cancel.html              |  379 +
 .../doh_mvc_repeat_select_manualsave.html          |  398 +
 .../doh_mvc_search-results-repeat-store.html       |  179 +
 .../doh_mvc_search-results-repeat.html             |  281 +
 .../doh_new-mvc_label_and_totals.html              |  306 +
 dojox/mvc/tests/doh/_Controller.js                 |   24 +
 dojox/mvc/tests/doh/atEquals.js                    |   34 +
 .../doh/doh_async_mvc_14491-input-output.html      |  170 +
 .../doh/doh_mvc_DOMNode-search-results-repeat.html |  274 +
 .../doh/doh_mvc_DOMNode_shipto-billto-simple.html  |  129 +
 dojox/mvc/tests/doh/doh_mvc_binding-simple.html    |  265 +
 dojox/mvc/tests/doh/doh_mvc_date_test.html         |  596 +
 .../tests/doh/doh_mvc_extension-per-widget.html    |   64 +
 dojox/mvc/tests/doh/doh_mvc_form-kitchensink.html  | 1176 +
 dojox/mvc/tests/doh/doh_mvc_loan-stateful.html     |  436 +
 dojox/mvc/tests/doh/doh_mvc_mobile-demo.html       |  344 +
 .../mvc/tests/doh/doh_mvc_new_ref-set-repeat.html  |  229 +
 .../doh/doh_mvc_new_shipto-billto-simple.html      |  173 +
 .../doh_mvc_performance_search-results-repeat.html |  317 +
 .../doh/doh_mvc_programmatic-repeat-store.html     |  191 +
 .../mvc/tests/doh/doh_mvc_ref-template-13263.html  |  116 +
 .../tests/doh/doh_mvc_repeat_select_cancel.html    |  370 +
 .../doh/doh_mvc_repeat_select_manualsave.html      |  394 +
 .../doh/doh_mvc_search-results-repeat-store.html   |  174 +
 .../tests/doh/doh_mvc_search-results-repeat.html   |  277 +
 .../doh/doh_mvc_shipto-billto-hierarchical.html    |  218 +
 dojox/mvc/tests/doh/doh_mvc_sync-test.html         |  218 +
 .../doh/doh_mvc_template_repeat_exprchar.html      |  108 +
 .../tests/doh/doh_mvc_validation-test-simple.html  |  123 +
 dojox/mvc/tests/doh/doh_mvc_zero-value-test.html   |  103 +
 .../tests/doh/doh_new-mvc_input-output-simple.html |  118 +
 .../tests/doh/doh_new-mvc_label_and_totals.html    |  304 +
 dojox/mvc/tests/doh/equals.js                      |   54 +
 dojox/mvc/tests/{ => doh}/helpers.js               |    0
 dojox/mvc/tests/doh/wildcard.js                    |   21 +
 .../tests/doh_async_mvc_14491-input-output.html    |  162 -
 .../tests/doh_async_mvc_input-output-simple.html   |  158 -
 dojox/mvc/tests/doh_async_mvc_mobile-demo.html     |  342 -
 dojox/mvc/tests/doh_mvc_binding-simple.html        |  429 -
 dojox/mvc/tests/doh_mvc_date_test.html             |  711 -
 dojox/mvc/tests/doh_mvc_form-kitchensink.html      | 1417 -
 .../tests/doh_mvc_programmatic-repeat-store.html   |  348 -
 dojox/mvc/tests/doh_mvc_ref-set-repeat.html        |  247 -
 .../tests/doh_mvc_search-results-repeat-store.html |  278 -
 dojox/mvc/tests/doh_mvc_search-results-repeat.html |  301 -
 .../tests/doh_mvc_shipto-billto-hierarchical.html  |  377 -
 dojox/mvc/tests/doh_mvc_shipto-billto-simple.html  |  215 -
 .../tests/doh_mvc_template_repeat_exprchar.html    |  236 -
 .../mvc/tests/doh_mvc_validation-test-simple.html  |  133 -
 dojox/mvc/tests/images/directory_45.png            |  Bin 0 -> 1509 bytes
 dojox/mvc/tests/images/settings.png                |  Bin 0 -> 5005 bytes
 .../mobile/demo/MobileDemoContactController.js     |   12 +
 .../mobile/demo/MobileDemoContactListController.js |   71 +
 .../mobile/demo/MobileDemoContactListModel.js      |   39 +
 .../tests/mobile/demo/MobileDemoContactModel.js    |   25 +
 .../tests/mobile/demo/MobileDemoGenerateActions.js |   35 +
 dojox/mvc/tests/mobile/demo/demo-async-store.html  |  186 -
 dojox/mvc/tests/mobile/demo/demo-async.html        |  203 -
 dojox/mvc/tests/mobile/demo/demo-sync.html         |  201 -
 dojox/mvc/tests/mobile/demo/demo.css               |    6 +-
 dojox/mvc/tests/mobile/demo/demo.html              |  387 +-
 dojox/mvc/tests/mobile/demo/iPad-Demo.html         |  213 -
 dojox/mvc/tests/mobile/demo/src.js                 |  197 +-
 .../mobile/test_Android-repeat-data-store.html     |  104 -
 .../tests/mobile/test_iPhone-shipto-billto.html    |  121 -
 .../mobile/test_mobile-checkbox-list-mvc.html      |  514 +
 .../mobile/test_mobile-list-multiple-sel-mvc.html  |  180 +
 .../mobile/test_mobile-list-single-sel-mvc.html    |  179 +
 dojox/mvc/tests/models/LoanWizardModel.js          |  113 -
 dojox/mvc/tests/module.js                          |  106 +-
 dojox/mvc/tests/moduleFullSet.js                   |   31 -
 .../tests/multiattrib/doh_mvc_test_Toolbar.html    |  176 +
 .../multiattrib/doh_mvc_test_Toolbar_withCtrl.html |  170 +
 dojox/mvc/tests/multiattrib/test_Toolbar.html      |  123 +
 .../test_mvc_ref-set-repeat-multiattrib.html       |  212 +
 dojox/mvc/tests/mvc_index.html                     |   15 +-
 dojox/mvc/tests/robot/android_repeat-ins.html      |  171 -
 dojox/mvc/tests/robot/iphone_shipto-billto.html    |  102 -
 dojox/mvc/tests/robot/mobile-demo-test.html        |  404 -
 dojox/mvc/tests/robot/mvc_generate-view.html       |  179 -
 dojox/mvc/tests/robot/mvc_loan-stateful.html       |  160 -
 dojox/mvc/tests/robot/mvc_ref-set-repeat.html      |  156 -
 .../tests/robot/mvc_search-results-ins-del.html    |  276 -
 .../mvc/tests/robot/mvc_search-results-repeat.html |  123 -
 .../robot/mvc_shipto-billto-hierarchical.html      |  103 -
 .../mvc/tests/robot/mvc_shipto-billto-simple.html  |  101 -
 dojox/mvc/tests/runTestsFullSet.html               |    9 -
 .../templates/ModelRefControllerInTemplate.html    |    3 +
 .../mvc/tests/templates/_ControllerInTemplate.html |    3 +
 dojox/mvc/tests/test_WidgetList.html               |  171 +
 .../test_WidgetList_WidgetListInTemplate.html      |   20 +
 dojox/mvc/tests/test_WidgetList_childBindings.json |    4 +
 dojox/mvc/tests/test_WidgetList_childTemplate.html |    7 +
 dojox/mvc/tests/test_async-mvc_group-simple.html   |  106 +-
 .../tests/test_async-mvc_input-output-simple.html  |   88 +-
 dojox/mvc/tests/test_async-mvc_repeat-simple.html  |  282 +-
 dojox/mvc/tests/test_mvc_Element.html              |   92 +
 dojox/mvc/tests/test_mvc_HTML5Element.html         |  148 +
 dojox/mvc/tests/test_mvc_bindings-simple.html      |  182 -
 dojox/mvc/tests/test_mvc_dates.html                |  407 -
 dojox/mvc/tests/test_mvc_form-kitchensink.html     |  651 -
 dojox/mvc/tests/test_mvc_generate-view-store.html  |   77 +-
 dojox/mvc/tests/test_mvc_generate-view.html        |   89 +-
 dojox/mvc/tests/test_mvc_input-output-simple.html  |   71 +-
 dojox/mvc/tests/test_mvc_loan-stateful.html        |  187 -
 .../tests/test_mvc_new-data-replace-simple.html    |  151 +
 .../test_mvc_new-ref-set-repeat-nostateful.html    |  119 +
 .../tests/test_mvc_new-ref-set-repeat-simple.html  |  150 +
 .../tests/test_mvc_new-ref-set-replace-repeat.html |  198 +
 dojox/mvc/tests/test_mvc_new_bindings-simple.html  |  187 +
 dojox/mvc/tests/test_mvc_new_form-kitchensink.html |  658 +
 dojox/mvc/tests/test_mvc_new_label_and_totals.html |  247 +
 dojox/mvc/tests/test_mvc_new_loan-stateful.html    |  290 +
 .../tests/test_mvc_new_shipto-billto-simple.html   |  141 +
 ...test_mvc_observable-search-results-ins-del.html |  347 +
 .../tests/test_mvc_programmatic-repeat-store.html  |  236 +-
 dojox/mvc/tests/test_mvc_radiobutton.html          |   84 +
 dojox/mvc/tests/test_mvc_ref-kitchensink.html      |  160 -
 .../mvc/tests/test_mvc_ref-set-repeat-simple.html  |  140 -
 .../tests/test_mvc_repeat-declarative-sync.html    |  205 -
 .../test_mvc_repeat-store-declarative-async.html   |  128 -
 dojox/mvc/tests/test_mvc_repeat_select.html        |  287 +
 dojox/mvc/tests/test_mvc_repeat_select_cancel.html |  311 +
 .../tests/test_mvc_repeat_select_manualsave.html   |  317 +
 .../mvc/tests/test_mvc_search-results-ins-del.html |  455 +-
 .../test_mvc_search-results-repeat-store.html      |  277 +-
 .../mvc/tests/test_mvc_search-results-repeat.html  |  388 +-
 .../tests/test_mvc_shipto-billto-hierarchical.html |  331 +-
 .../test_mvc_shipto-billto-simple-declarative.html |  132 -
 .../test_mvc_shipto-billto-simple-oldparser.html   |  131 -
 dojox/mvc/tests/test_mvc_shipto-billto-simple.html |  130 -
 dojox/mvc/tests/test_mvc_simple-programmatic.html  |   89 +-
 .../tests/test_new-mvc_input-output-simple.html    |   84 +
 .../test_templatedWidget/{readme.txt => README}    |    0
 .../tests/test_templatedWidget/myMvcTemplated.js   |   52 +-
 .../test_templatedWidget/test_mvc_widget.html      |  116 +-
 .../test_mvc_widget_template.html                  |   75 +-
 dojox/mvc/tests/test_templatedWidgetList/README    |    5 +
 .../test_templatedWidgetList/myMvcTemplated.js     |   45 +
 .../test_templatedWidgetList/myMvcTemplated2.js    |   54 +
 .../test_templatedWidgetList/myMvcTemplated3.js    |   54 +
 .../myMvcTemplated3bDetails.js                     |   49 +
 .../test_templatedWidgetList/test_mvc_widget.html  |   99 +
 .../test_templatedWidgetList/test_mvc_widget2.html |  127 +
 .../test_templatedWidgetList/test_mvc_widget3.html |   94 +
 .../test_mvc_widget_template.html                  |   16 +
 .../test_mvc_widget_template2.html                 |   19 +
 .../test_mvc_widget_template3.html                 |   19 +
 .../test_mvc_widget_template3bDetails.html         |   26 +
 dojox/mvc/tests/zips/10024.json                    |    2 +-
 dojox/mvc/tests/zips/10706.json                    |    2 +-
 dojox/package.json                                 |    6 +-
 dojox/rails/tests/test_rails.html                  |    4 +-
 dojox/resources/_modules.js                        |  252 -
 dojox/robot/tests/test_recorder.html               |    2 +-
 dojox/rpc/JsonRPC.js                               |   10 +-
 dojox/rpc/JsonRest.js                              |   29 +-
 dojox/rpc/OfflineRest.js                           |   14 +-
 dojox/rpc/Rest.js                                  |   42 +-
 dojox/rpc/SMDLibrary/twitter.smd                   |   70 +-
 dojox/rpc/Service.js                               |   15 +-
 dojox/rpc/demos/demo_GoogleAjax.html               |    2 +-
 dojox/rpc/demos/demo_GoogleAjaxTranslate.html      |    2 +-
 dojox/rpc/demos/demo_GoogleFeed.html               |    2 +-
 dojox/rpc/demos/demo_jabsorb.html                  |    2 +-
 dojox/rpc/demos/documentation.html                 |    2 +-
 dojox/rpc/demos/wikipedia.html                     |    2 +-
 dojox/rpc/demos/yahoo.html                         |    2 +-
 dojox/rpc/tests/resources/bigQuery                 |    2 +-
 dojox/rpc/tests/resources/bigQuery5                |    2 +-
 dojox/rpc/tests/resources/obj1                     |    2 +-
 dojox/rpc/tests/resources/obj1lazyValue            |    2 +-
 dojox/rpc/tests/resources/obj1testArray            |    2 +-
 dojox/rpc/tests/resources/obj3                     |    2 +-
 dojox/rpc/tests/resources/obj4                     |    2 +-
 dojox/rpc/tests/resources/res                      |    2 +-
 dojox/rpc/tests/stores/JsonRestStore.js            |   22 +-
 dojox/secure/capability.js                         |   20 +-
 dojox/secure/fromJson.js                           |   50 +-
 dojox/secure/sandbox.js                            |   58 +-
 dojox/sketch.js                                    |    8 +
 dojox/sketch/Figure.js                             |   21 +-
 dojox/sketch/_Plugin.js                            |    6 +-
 dojox/socket.js                                    |   47 +-
 dojox/socket/Reconnect.js                          |    4 +-
 dojox/sql.js                                       |   11 +-
 dojox/sql/_base.js                                 |   61 +-
 dojox/sql/_crypto.js                               |   27 +-
 dojox/sql/demos/customers/customers.html           |    2 +-
 dojox/storage.js                                   |   11 +-
 dojox/store/LightstreamerStore.js                  |  204 -
 dojox/store/README                                 |    9 +-
 dojox/store/tests/test_LightstreamerStore.html     |   74 -
 dojox/string/BidiComplex.js                        |    2 +-
 dojox/string/BidiEngine.js                         |  237 +-
 dojox/string/Builder.js                            |   29 +-
 dojox/string/sprintf.js                            |    4 +-
 dojox/string/tests/BuilderArguments.html           |    2 +-
 dojox/string/tests/PerfFun.html                    |    2 +-
 dojox/string/tests/test_BidiComplex.html           |    2 +-
 dojox/testing/DocTest.js                           |   26 +-
 dojox/timing.js                                    |    7 +
 dojox/timing/Sequence.js                           |   18 +-
 dojox/timing/Streamer.js                           |   26 +-
 dojox/timing/ThreadPool.js                         |    4 +-
 dojox/timing/_base.js                              |   33 +-
 dojox/timing/doLater.js                            |   35 +-
 dojox/timing/tests/test_Sequence.html              |    2 +-
 dojox/timing/tests/test_ThreadPool.html            |    2 +-
 dojox/timing/tests/test_doLater.html               |    2 +-
 dojox/treemap/DrillDownUp.js                       |  125 +
 dojox/treemap/GroupLabel.js                        |   42 +
 dojox/treemap/Keyboard.js                          |   98 +
 dojox/treemap/README                               |   18 +
 dojox/treemap/ScaledLabel.js                       |   56 +
 dojox/treemap/TreeMap.js                           |  803 +
 dojox/treemap/_utils.js                            |  253 +
 dojox/treemap/tests/Store.js                       |   14 +
 dojox/treemap/tests/freight.csv                    |   51 +
 dojox/treemap/tests/module.js                      |    3 +
 dojox/treemap/tests/runTests.html                  |    9 +
 dojox/treemap/tests/test.html                      |  200 +
 dojox/treemap/tests/test_attr.html                 |   43 +
 dojox/treemap/tests/test_drilldown.html            |   44 +
 dojox/treemap/tests/test_evt.html                  |   49 +
 dojox/treemap/tests/test_func.html                 |   51 +
 dojox/treemap/tests/test_grouplabel.html           |   44 +
 dojox/treemap/tests/test_key.html                  |   43 +
 dojox/treemap/tests/test_props.html                |   43 +
 dojox/treemap/tests/test_scaledlabel.html          |   43 +
 dojox/treemap/tests/test_style.html                |   65 +
 dojox/treemap/themes/DrillDownUp.css               |    3 +
 dojox/treemap/themes/GroupLabel.css                |    7 +
 dojox/treemap/themes/MobileTreeMap.css             |   35 +
 dojox/treemap/themes/TreeMap.css                   |   81 +
 dojox/uuid.js                                      |    8 +
 dojox/uuid/Uuid.js                                 |    8 +-
 dojox/uuid/_base.js                                |   17 +-
 dojox/uuid/generateTimeBasedUuid.js                |    4 +-
 dojox/validate.js                                  |   14 +-
 dojox/validate/_base.js                            |   81 +-
 dojox/validate/br.js                               |   10 +-
 dojox/validate/ca.js                               |   28 +-
 dojox/validate/check.js                            |   57 +-
 dojox/validate/creditCard.js                       |   53 +-
 dojox/validate/isbn.js                             |   11 +-
 dojox/validate/regexp.js                           |  154 +-
 dojox/validate/tests/creditcard.js                 |    1 +
 dojox/validate/us.js                               |   27 +-
 dojox/validate/web.js                              |  109 +-
 dojox/widget/AutoRotator.js                        |  161 +-
 dojox/widget/Calendar.js                           |  954 +-
 dojox/widget/Calendar/Calendar.css                 |    1 +
 dojox/widget/Calendar2Pane.js                      |   11 +
 dojox/widget/Calendar3Pane.js                      |   12 +
 dojox/widget/CalendarFisheye.js                    |   11 +
 dojox/widget/CalendarFx.js                         |   35 +-
 dojox/widget/CalendarViews.js                      |  152 +-
 dojox/widget/ColorPicker.js                        |  105 +-
 dojox/widget/ColorPicker/ColorPicker.html          |   16 +-
 dojox/widget/DailyCalendar.js                      |   15 +
 dojox/widget/DataPresentation.js                   |  440 +-
 dojox/widget/Dialog.js                             |   27 +-
 dojox/widget/DialogSimple.js                       |   11 +-
 dojox/widget/DocTester.js                          |   17 +-
 dojox/widget/DynamicTooltip.js                     |    8 +-
 dojox/widget/FeedPortlet.js                        |   18 +-
 dojox/widget/FilePicker.js                         |   76 +-
 dojox/widget/FisheyeList.js                        | 1302 +-
 dojox/widget/FisheyeListItem.js                    |  104 +
 dojox/widget/FisheyeLite.js                        |   96 +-
 dojox/widget/Loader.js                             |   38 +-
 dojox/widget/MonthAndYearlyCalendar.js             |   10 +
 dojox/widget/MonthlyCalendar.js                    |   15 +
 dojox/widget/MultiSelectCalendar.js                |   87 +-
 .../MultiSelectCalendar/MultiSelectCalendar.html   |    2 +-
 dojox/widget/Pager.js                              |  524 +-
 dojox/widget/PagerItem.js                          |   23 +
 dojox/widget/PlaceholderMenuItem.js                |   31 +-
 dojox/widget/Portlet.js                            |  713 +-
 dojox/widget/PortletDialogSettings.js              |   48 +
 dojox/widget/PortletSettings.js                    |   72 +
 dojox/widget/README                                |    4 +-
 dojox/widget/Roller.js                             |   64 +-
 dojox/widget/RollingList.js                        |  269 +-
 dojox/widget/Rotator.js                            |  236 +-
 dojox/widget/Selection.js                          |  220 +
 dojox/widget/SortList.js                           |   39 +-
 dojox/widget/Standby.js                            |  115 +-
 dojox/widget/TitleGroup.js                         |   24 +-
 dojox/widget/Toaster.js                            |   15 +-
 dojox/widget/Toaster/Toaster.css                   |    2 +-
 dojox/widget/UpgradeBar.js                         |  184 +-
 dojox/widget/Wizard.js                             |   84 +-
 dojox/widget/WizardPane.js                         |   76 +
 dojox/widget/YearlyCalendar.js                     |   15 +
 dojox/widget/_CalendarBase.js                      |  385 +
 dojox/widget/_CalendarDay.js                       |   15 +
 dojox/widget/_CalendarDayView.js                   |  188 +
 dojox/widget/_CalendarMonth.js                     |   16 +
 dojox/widget/_CalendarMonthView.js                 |   69 +
 dojox/widget/_CalendarMonthYear.js                 |   16 +
 dojox/widget/_CalendarMonthYearView.js             |  277 +
 dojox/widget/_CalendarView.js                      |   80 +
 dojox/widget/_CalendarYear.js                      |   19 +
 dojox/widget/_CalendarYearView.js                  |   52 +
 dojox/widget/_FisheyeFX.js                         |   23 +
 dojox/widget/_Invalidating.js                      |   62 +
 dojox/widget/nls/ColorPicker.js                    |    2 +
 dojox/widget/nls/FilePicker.js                     |    2 +
 dojox/widget/nls/Wizard.js                         |    2 +
 dojox/widget/nls/ar/ColorPicker.js                 |    2 -
 dojox/widget/nls/ar/FilePicker.js                  |    9 +-
 dojox/widget/nls/ar/Wizard.js                      |    2 -
 dojox/widget/nls/az/ColorPicker.js                 |    2 -
 dojox/widget/nls/az/FilePicker.js                  |    2 -
 dojox/widget/nls/az/Wizard.js                      |    2 -
 dojox/widget/nls/bg/ColorPicker.js                 |   14 +
 dojox/widget/nls/bg/FilePicker.js                  |    7 +
 dojox/widget/nls/bg/Wizard.js                      |    7 +
 dojox/widget/nls/ca/ColorPicker.js                 |    8 +-
 dojox/widget/nls/ca/FilePicker.js                  |    9 +-
 dojox/widget/nls/ca/Wizard.js                      |    2 -
 dojox/widget/nls/cs/ColorPicker.js                 |    3 +-
 dojox/widget/nls/cs/FilePicker.js                  |    8 +-
 dojox/widget/nls/cs/Wizard.js                      |    2 -
 dojox/widget/nls/da/ColorPicker.js                 |    9 +-
 dojox/widget/nls/da/FilePicker.js                  |    8 +-
 dojox/widget/nls/da/Wizard.js                      |    2 -
 dojox/widget/nls/de/ColorPicker.js                 |    9 +-
 dojox/widget/nls/de/FilePicker.js                  |    8 +-
 dojox/widget/nls/de/Wizard.js                      |    2 -
 dojox/widget/nls/el/ColorPicker.js                 |    2 +-
 dojox/widget/nls/el/FilePicker.js                  |    8 +-
 dojox/widget/nls/el/Wizard.js                      |    2 -
 dojox/widget/nls/es/ColorPicker.js                 |    6 +-
 dojox/widget/nls/es/FilePicker.js                  |    8 +-
 dojox/widget/nls/es/Wizard.js                      |    2 -
 dojox/widget/nls/fi/ColorPicker.js                 |    9 +-
 dojox/widget/nls/fi/FilePicker.js                  |    8 +-
 dojox/widget/nls/fi/Wizard.js                      |    2 -
 dojox/widget/nls/fr/ColorPicker.js                 |    7 +-
 dojox/widget/nls/fr/FilePicker.js                  |    8 +-
 dojox/widget/nls/fr/Wizard.js                      |    2 -
 dojox/widget/nls/he/ColorPicker.js                 |    1 -
 dojox/widget/nls/he/FilePicker.js                  |    8 +-
 dojox/widget/nls/he/Wizard.js                      |    2 -
 dojox/widget/nls/hu/ColorPicker.js                 |    9 +-
 dojox/widget/nls/hu/FilePicker.js                  |    8 +-
 dojox/widget/nls/hu/Wizard.js                      |    4 +-
 dojox/widget/nls/it/ColorPicker.js                 |    9 +-
 dojox/widget/nls/it/FilePicker.js                  |    8 +-
 dojox/widget/nls/it/Wizard.js                      |    6 +-
 dojox/widget/nls/ja/ColorPicker.js                 |   12 +-
 dojox/widget/nls/ja/FilePicker.js                  |    8 +-
 dojox/widget/nls/ja/Wizard.js                      |    2 -
 dojox/widget/nls/kk/ColorPicker.js                 |    2 +-
 dojox/widget/nls/kk/FilePicker.js                  |    9 +-
 dojox/widget/nls/kk/Wizard.js                      |    4 +-
 dojox/widget/nls/ko/ColorPicker.js                 |    4 +-
 dojox/widget/nls/ko/FilePicker.js                  |    8 +-
 dojox/widget/nls/ko/Wizard.js                      |    2 -
 dojox/widget/nls/nb/ColorPicker.js                 |   11 +-
 dojox/widget/nls/nb/FilePicker.js                  |    8 +-
 dojox/widget/nls/nb/Wizard.js                      |    2 -
 dojox/widget/nls/nl/ColorPicker.js                 |    6 +-
 dojox/widget/nls/nl/FilePicker.js                  |    9 +-
 dojox/widget/nls/nl/Wizard.js                      |    2 -
 dojox/widget/nls/pl/ColorPicker.js                 |   12 +-
 dojox/widget/nls/pl/FilePicker.js                  |    8 +-
 dojox/widget/nls/pl/Wizard.js                      |    2 -
 dojox/widget/nls/pt-pt/ColorPicker.js              |    1 -
 dojox/widget/nls/pt-pt/FilePicker.js               |    8 +-
 dojox/widget/nls/pt-pt/Wizard.js                   |    2 -
 dojox/widget/nls/pt/ColorPicker.js                 |   11 +-
 dojox/widget/nls/pt/FilePicker.js                  |    8 +-
 dojox/widget/nls/pt/Wizard.js                      |    2 -
 dojox/widget/nls/ro/ColorPicker.js                 |    9 +-
 dojox/widget/nls/ro/FilePicker.js                  |    9 +-
 dojox/widget/nls/ro/Wizard.js                      |    2 -
 dojox/widget/nls/ru/ColorPicker.js                 |    2 +-
 dojox/widget/nls/ru/FilePicker.js                  |    8 +-
 dojox/widget/nls/ru/Wizard.js                      |    2 -
 dojox/widget/nls/sk/ColorPicker.js                 |   11 +-
 dojox/widget/nls/sk/FilePicker.js                  |    9 +-
 dojox/widget/nls/sk/Wizard.js                      |    6 +-
 dojox/widget/nls/sl/ColorPicker.js                 |   11 +-
 dojox/widget/nls/sl/FilePicker.js                  |    9 +-
 dojox/widget/nls/sl/Wizard.js                      |    4 +-
 dojox/widget/nls/sv/ColorPicker.js                 |   12 +-
 dojox/widget/nls/sv/FilePicker.js                  |    8 +-
 dojox/widget/nls/sv/Wizard.js                      |    4 +-
 dojox/widget/nls/th/ColorPicker.js                 |   15 +-
 dojox/widget/nls/th/FilePicker.js                  |    9 +-
 dojox/widget/nls/th/Wizard.js                      |    6 +-
 dojox/widget/nls/tr/ColorPicker.js                 |    2 +-
 dojox/widget/nls/tr/FilePicker.js                  |    8 +-
 dojox/widget/nls/tr/Wizard.js                      |    2 -
 dojox/widget/nls/uk/ColorPicker.js                 |   14 +
 dojox/widget/nls/uk/FilePicker.js                  |    7 +
 dojox/widget/nls/uk/Wizard.js                      |    7 +
 dojox/widget/nls/zh-tw/ColorPicker.js              |   10 +-
 dojox/widget/nls/zh-tw/FilePicker.js               |    8 +-
 dojox/widget/nls/zh-tw/Wizard.js                   |    2 -
 dojox/widget/nls/zh/ColorPicker.js                 |   10 +-
 dojox/widget/nls/zh/FilePicker.js                  |    8 +-
 dojox/widget/nls/zh/Wizard.js                      |    6 +-
 dojox/widget/rotator/Controller.js                 |   89 +-
 dojox/widget/rotator/Fade.js                       |   34 +-
 dojox/widget/rotator/Pan.js                        |   58 +-
 dojox/widget/rotator/PanFade.js                    |   78 +-
 dojox/widget/rotator/Slide.js                      |   34 +-
 dojox/widget/rotator/ThumbnailController.js        |   57 +-
 dojox/widget/rotator/Wipe.js                       |   40 +-
 dojox/widget/tests/Selection.js                    |   21 +
 dojox/widget/tests/_Invalidating.js                |   16 +
 dojox/widget/tests/demo_FisheyeList.html           |    2 +-
 dojox/widget/tests/module.js                       |    4 +
 dojox/widget/tests/runTests.html                   |    9 +
 dojox/widget/tests/test_AutoRotator.html           |   47 +-
 dojox/widget/tests/test_Calendar.html              |  131 +-
 dojox/widget/tests/test_CalendarViews.html         |   52 +-
 dojox/widget/tests/test_ColorPicker-async.html     |    2 +-
 dojox/widget/tests/test_ColorPicker.html           |   14 +-
 dojox/widget/tests/test_DataPresentation.html      |    2 +-
 dojox/widget/tests/test_Dialog.html                |    2 +-
 dojox/widget/tests/test_DocTester.html             |    2 +-
 dojox/widget/tests/test_DynamicTooltip.html        |    2 +-
 dojox/widget/tests/test_FilePicker.html            |    6 +-
 dojox/widget/tests/test_FisheyeList.html           |   37 +-
 dojox/widget/tests/test_FisheyeLite.html           |  184 +-
 dojox/widget/tests/test_Iterator.html              |    4 +-
 dojox/widget/tests/test_Loader.html                |    2 +-
 .../tests/test_MultiSelectCalendar-async.html      |    2 +-
 dojox/widget/tests/test_MultiSelectCalendar.html   |    2 +-
 dojox/widget/tests/test_Pager.html                 |   19 +-
 dojox/widget/tests/test_PlaceholderMenuItem.html   |    2 +-
 dojox/widget/tests/test_Portlet.html               |    6 +-
 .../widget/tests/test_PortletInGridContainer.html  |   26 +-
 dojox/widget/tests/test_PortletInGridContainer.js  |    1 +
 .../tests/test_PortletInGridContainerColumns.html  |    2 +-
 dojox/widget/tests/test_Roller.html                |    2 +-
 dojox/widget/tests/test_RollingList.html           |   12 +-
 dojox/widget/tests/test_Rotator.html               |  215 +-
 dojox/widget/tests/test_RotatorController.html     |   66 +-
 .../tests/test_Rotator_ThumbnailController.html    |   24 +-
 dojox/widget/tests/test_SortList.html              |    4 +-
 dojox/widget/tests/test_Standby.html               |    8 +-
 dojox/widget/tests/test_Standby_quirks.html        |    8 +-
 dojox/widget/tests/test_Standby_rtl.html           |    8 +-
 dojox/widget/tests/test_TitleGroup.html            |    2 +-
 dojox/widget/tests/test_Toaster.html               |    2 +-
 dojox/widget/tests/test_UpgradeBar.html            |   73 +-
 dojox/widget/tests/test_UpgradeBar_markup.html     |   44 +-
 dojox/widget/tests/test_Wizard.html                |    3 +-
 dojox/wire.js                                      |   12 +-
 dojox/wire/CompositeWire.js                        |   40 +-
 dojox/wire/DataWire.js                             |   59 +-
 dojox/wire/TableAdapter.js                         |   34 +-
 dojox/wire/TextAdapter.js                          |   41 +-
 dojox/wire/TreeAdapter.js                          |   68 +-
 dojox/wire/Wire.js                                 |   97 +-
 dojox/wire/XmlWire.js                              |   68 +-
 dojox/wire/_base.js                                |   65 +-
 dojox/wire/demos/TableContainer.js                 |   10 +-
 dojox/wire/demos/WidgetRepeater.js                 |    6 +-
 dojox/wire/demos/markup/demo_ActionChaining.html   |    2 +-
 dojox/wire/demos/markup/demo_ActionWiring.html     |   10 +-
 dojox/wire/demos/markup/demo_BasicChildWire.html   |    6 +-
 .../wire/demos/markup/demo_BasicColumnWiring.html  |    6 +-
 .../wire/demos/markup/demo_ConditionalActions.html |    4 +-
 dojox/wire/demos/markup/demo_FlickrStoreWire.html  |   20 +-
 dojox/wire/demos/markup/demo_TopicWiring.html      |    6 +-
 dojox/wire/ml/Action.js                            |   52 +-
 dojox/wire/ml/Data.js                              |   46 +-
 dojox/wire/ml/DataStore.js                         |   68 +-
 dojox/wire/ml/Invocation.js                        |   54 +-
 dojox/wire/ml/JsonHandler.js                       |   14 +-
 dojox/wire/ml/RestHandler.js                       |   46 +-
 dojox/wire/ml/Service.js                           |   40 +-
 dojox/wire/ml/Transfer.js                          |  159 +-
 dojox/wire/ml/XmlHandler.js                        |   21 +-
 dojox/wire/ml/util.js                              |   60 +-
 dojox/wire/tests/markup/Action.html                |    2 +-
 dojox/wire/tests/markup/Data.html                  |    2 +-
 dojox/wire/tests/markup/DataStore.html             |    2 +-
 dojox/wire/tests/markup/Invocation.html            |    2 +-
 dojox/wire/tests/markup/Service.html               |    2 +-
 dojox/wire/tests/markup/Transfer.html              |    2 +-
 dojox/xml/parser.js                                |   32 +-
 dojox/xml/tests/mail.html                          |    8 +-
 dojox/xml/tests/widgetParser.html                  |    2 +-
 dojox/xml/widgetParser.js                          |    2 +-
 dojox/xmpp/ChatService.js                          |    2 +-
 dojox/xmpp/PresenceService.js                      |    2 +-
 dojox/xmpp/RosterService.js                        |    2 +-
 dojox/xmpp/TransportSession.js                     |   22 +-
 dojox/xmpp/bosh.js                                 |   40 +-
 dojox/xmpp/tests/test_xmppService.html             |    2 +-
 dojox/xmpp/util.js                                 |   93 +-
 dojox/xmpp/xmppSession.js                          |   76 +-
 util/.gitmodules                                   |    3 +
 util/LICENSE                                       |    2 +-
 util/build/argv.js                                 |   27 +-
 util/build/buildControl.js                         |  400 +-
 util/build/buildControlBase.js                     |   12 +-
 util/build/buildControlDefault.js                  |  131 +-
 util/build/discover.js                             |   78 +-
 util/build/examples/require.js                     |    2 +-
 util/build/fileHandleThrottle.js                   |   10 +-
 util/build/fileUtils.js                            |  128 +-
 util/build/help.txt                                |   22 +-
 util/build/main.js                                 |  166 +-
 util/build/messages.js                             |   20 +-
 util/build/node/fs.js                              |    8 +-
 util/build/node/process.js                         |   53 +-
 util/build/optimizeRunner.js                       |  113 +-
 util/build/plugins/domReady.js                     |    8 +-
 util/build/plugins/has.js                          |   16 +-
 util/build/plugins/i18n.js                         |   80 +-
 util/build/plugins/loadInit.js                     |   10 +-
 util/build/plugins/require.js                      |   11 +-
 util/build/plugins/text.js                         |   82 +-
 util/build/replace.js                              |   54 +-
 util/build/rhino/fs.js                             |   34 +-
 util/build/rhino/process.js                        |   10 +-
 util/build/stringify.js                            |  126 +-
 util/build/transforms/copy.js                      |   13 +-
 util/build/transforms/depsDeclarative.js           |   93 +
 util/build/transforms/depsDump.js                  |    4 +-
 util/build/transforms/depsScan.js                  |  332 +-
 util/build/transforms/dojoReport.js                |    6 +-
 util/build/transforms/hasFindAll.js                |   18 +-
 util/build/transforms/hasFixup.js                  |  155 +-
 util/build/transforms/hasReport.js                 |   19 +-
 util/build/transforms/insertSymbols.js             |   15 +-
 util/build/transforms/optimizeCss.js               |  234 +-
 util/build/transforms/optimizer/closure.js         |  105 +
 util/build/transforms/optimizer/sendJob.js         |  153 +
 util/build/transforms/optimizer/shrinksafe.js      |   94 +
 util/build/transforms/optimizer/stripConsole.js    |   18 +
 util/build/transforms/optimizer/uglify.js          |   46 +
 util/build/transforms/read.js                      |   32 +-
 util/build/transforms/report.js                    |   12 +-
 util/build/transforms/write.js                     |    7 +-
 util/build/transforms/writeAmd.js                  |  447 +-
 util/build/transforms/writeCss.js                  |   50 +-
 util/build/transforms/writeDojo.js                 |  116 +-
 util/build/transforms/writeOptimized.js            |  304 +-
 util/build/v1xProfiles.js                          |   17 +-
 util/buildscripts/LICENSE                          |    2 +-
 util/buildscripts/build.bat                        |    4 +-
 util/buildscripts/build.js                         |   10 +-
 util/buildscripts/build.sh                         |    4 +-
 util/buildscripts/build_release.sh                 |   61 +-
 util/buildscripts/cdnBuild.sh                      |    3 +-
 util/buildscripts/changeVersion.js                 |   20 +-
 util/buildscripts/cldr/alias.js                    |   16 +-
 util/buildscripts/cldr/arrayInherit.js             |   12 +-
 util/buildscripts/cldr/build.xml                   |   11 +-
 util/buildscripts/cldr/calendar.xsl                |   57 +-
 util/buildscripts/cldr/cldrUtil.js                 |   15 +-
 util/buildscripts/cldr/ldml/core.zip               |  Bin 4098553 -> 9368196 bytes
 util/buildscripts/cldr/number.xsl                  |    2 +-
 util/buildscripts/cldr/specialLocale.js            |    6 +-
 util/buildscripts/cldr/wrap.js                     |    2 +-
 util/buildscripts/cldr/xhr.js                      |   12 +
 util/buildscripts/copyright.txt                    |    2 +-
 util/buildscripts/jslib/buildUtilXd.js             |   16 +-
 util/buildscripts/jslib/fileUtil.js                |   36 +-
 util/buildscripts/jslib/i18nUtil.js                |   33 +-
 util/buildscripts/profiles/amd.profile.js          |  141 +
 util/buildscripts/profiles/demos-all.profile.js    |   64 +-
 util/buildscripts/profiles/nano.profile.js         |   51 +
 util/buildscripts/profiles/node.profile.js         |  128 +
 util/buildscripts/profiles/webkitMobile.profile.js |  185 +
 util/buildscripts/tests/webkitHasTest.html         |  182 +
 .../webbuild/makeWebBuildModuleList.js             |    3 +-
 util/buildscripts/webbuild/server/js/build.js      |    9 +-
 util/checkstyle/checkstyleReport.html              |    4 +-
 util/checkstyle/runCheckstyle.js                   |   20 +-
 util/closureCompiler/README                        |   36 +-
 util/closureCompiler/compiler.jar                  |  Bin 4332498 -> 6243182 bytes
 util/docscripts/LICENSE                            |    2 +-
 util/docscripts/modules/dojox.module.properties    |    2 +-
 util/docscripts/preview.php                        |    2 +-
 util/doh/LICENSE                                   |    2 +-
 util/doh/Robot.html                                |   58 +-
 util/doh/_browserRunner.js                         |  309 +-
 util/doh/_nodeRunner.js                            |   12 +-
 util/doh/_parseURLargs.js                          |  128 +-
 util/doh/_rhinoRunner.js                           |   12 +-
 util/doh/doh.profile.js                            |   16 +-
 util/doh/mobileRunner.html                         |   27 +-
 util/doh/package.json                              |    2 +-
 util/doh/plugins/README.txt                        |    9 +
 util/doh/plugins/android-webdriver-robot.html      |   85 +
 util/doh/plugins/android-webdriver-robot.js        |  338 +
 util/doh/plugins/hello.js                          |    6 +-
 util/doh/plugins/remoteRobot.js                    |   46 +
 util/doh/robot.js                                  |  539 +-
 util/doh/robot/DOHRobot.jar                        |  Bin 46761 -> 48805 bytes
 util/doh/robot/DOHRobot.java                       |   89 +-
 util/doh/runner.html                               |   35 +-
 util/doh/runner.js                                 |  881 +-
 util/doh/tests/robot.html                          |  132 +-
 util/doh/tests/selfTest.js                         |   38 +-
 util/doh/tests/tearDownTest.js                     |   65 +
 util/jsdoc/LICENSE                                 |    2 +-
 util/less/.npmignore                               |    1 +
 util/less/CHANGELOG.md                             |  118 +
 util/less/CONTRIBUTING.md                          |   50 +
 util/less/Makefile                                 |   87 +
 util/less/README                                   |    7 -
 util/less/README.md                                |   20 +
 util/less/benchmark/benchmark.less                 | 3979 ++
 util/less/benchmark/less-benchmark.js              |   47 +
 util/less/bin/lessc                                |  190 +
 util/less/browser.js                               |  369 -
 util/less/build/amd.js                             |    6 +
 util/less/build/ecma-5.js                          |  120 +
 util/less/build/header.js                          |    7 +
 util/less/build/require-rhino.js                   |    7 +
 util/less/build/require.js                         |    7 +
 util/less/dist/less-1.1.0.js                       | 2695 ++
 util/less/dist/less-1.1.0.min.js                   |   16 +
 util/less/dist/less-1.1.1.js                       | 2710 ++
 util/less/dist/less-1.1.1.min.js                   |   16 +
 util/less/dist/less-1.1.2.js                       | 2712 ++
 util/less/dist/less-1.1.2.min.js                   |   16 +
 util/less/dist/less-1.1.3.js                       | 2721 ++
 util/less/dist/less-1.1.3.min.js                   |   16 +
 util/less/dist/less-1.1.4.js                       | 2769 ++
 util/less/dist/less-1.1.4.min.js                   |   16 +
 util/less/dist/less-1.1.5.js                       | 2805 ++
 util/less/dist/less-1.1.5.min.js                   |    9 +
 util/less/dist/less-1.1.6.js                       | 3004 ++
 util/less/dist/less-1.1.6.min.js                   |    9 +
 util/less/dist/less-1.2.0.js                       | 3293 ++
 util/less/dist/less-1.2.0.min.js                   |    9 +
 util/less/dist/less-1.2.1.js                       | 3318 ++
 util/less/dist/less-1.2.1.min.js                   |    9 +
 util/less/dist/less-1.2.2.js                       | 3337 ++
 util/less/dist/less-1.2.2.min.js                   |    9 +
 util/less/dist/less-1.3.0.js                       | 3478 ++
 util/less/dist/less-1.3.0.min.js                   |    9 +
 util/less/dist/less-1.3.1.js                       | 4011 ++
 util/less/dist/less-1.3.1.min.js                   |    9 +
 util/less/dist/less-1.3.2.js                       | 4401 +++
 util/less/dist/less-1.3.2.min.js                   |    9 +
 util/less/dist/less-1.3.3.js                       | 4413 +++
 util/less/dist/less-1.3.3.min.js                   |    9 +
 util/less/dist/less-rhino-1.1.3.js                 | 2460 ++
 util/less/dist/less-rhino-1.1.5.js                 | 2481 ++
 util/less/dist/less-rhino-1.3.1.js                 | 3725 ++
 util/less/dist/less-rhino-1.3.2.js                 | 3990 ++
 util/less/dist/less-rhino-1.3.3.js                 | 4002 ++
 util/less/functions.js                             |  174 -
 util/less/index.js                                 |  137 -
 util/less/lib/less/browser.js                      |  519 +
 util/less/lib/less/colors.js                       |  152 +
 util/less/lib/less/functions.js                    |  377 +
 util/less/lib/less/index.js                        |  216 +
 util/less/lib/less/lessc_helper.js                 |   62 +
 util/less/lib/less/parser.js                       | 1522 +
 util/less/lib/less/rhino.js                        |  123 +
 util/less/lib/less/tree.js                         |   45 +
 util/less/lib/less/tree/alpha.js                   |   17 +
 util/less/lib/less/tree/anonymous.js               |   27 +
 util/less/lib/less/tree/assignment.js              |   19 +
 util/less/lib/less/tree/call.js                    |   54 +
 util/less/lib/less/tree/color.js                   |  111 +
 util/less/lib/less/tree/comment.js                 |   14 +
 util/less/lib/less/tree/condition.js               |   42 +
 util/less/lib/less/tree/dimension.js               |   51 +
 util/less/lib/less/tree/directive.js               |   39 +
 util/less/lib/less/tree/element.js                 |   49 +
 util/less/lib/less/tree/expression.js              |   23 +
 util/less/lib/less/tree/import.js                  |   82 +
 util/less/lib/less/tree/javascript.js              |   51 +
 util/less/lib/less/tree/keyword.js                 |   19 +
 util/less/lib/less/tree/media.js                   |  121 +
 util/less/lib/less/tree/mixin.js                   |  212 +
 util/less/lib/less/tree/operation.js               |   37 +
 util/less/lib/less/tree/paren.js                   |   16 +
 util/less/lib/less/tree/quoted.js                  |   43 +
 util/less/lib/less/tree/ratio.js                   |   13 +
 util/less/lib/less/tree/rule.js                    |   49 +
 util/less/lib/less/tree/ruleset.js                 |  414 +
 util/less/lib/less/tree/selector.js                |   52 +
 util/less/lib/less/tree/unicode-descriptor.js      |   13 +
 util/less/lib/less/tree/url.js                     |   27 +
 util/less/lib/less/tree/value.js                   |   24 +
 util/less/lib/less/tree/variable.js                |   38 +
 util/less/package.json                             |   23 +
 util/less/parser.js                                | 1110 -
 util/less/test/browser-test-prepare.js             |   29 +
 util/less/test/browser/common.js                   |   74 +
 util/less/test/browser/css/relative-urls/urls.css  |   36 +
 .../test/browser/css/rootpath-relative/urls.css    |   36 +
 util/less/test/browser/css/rootpath/urls.css       |   36 +
 util/less/test/browser/css/urls.css                |   36 +
 util/less/test/browser/jasmine-html.js             |  681 +
 util/less/test/browser/jasmine.css                 |   82 +
 util/less/test/browser/jasmine.js                  | 2600 ++
 util/less/test/browser/less/imports/urls.less      |    4 +
 util/less/test/browser/less/imports/urls2.less     |    4 +
 .../less/test/browser/less/relative-urls/urls.less |   33 +
 .../test/browser/less/rootpath-relative/urls.less  |   33 +
 util/less/test/browser/less/rootpath/urls.less     |   33 +
 util/less/test/browser/less/urls.less              |   33 +
 util/less/test/browser/phantom-runner.js           |  139 +
 util/less/test/browser/runner-browser.js           |    3 +
 util/less/test/browser/runner-main.js              |   15 +
 util/less/test/browser/runner-relative-urls.js     |    4 +
 util/less/test/browser/runner-rootpath-relative.js |    5 +
 util/less/test/browser/runner-rootpath.js          |    4 +
 util/less/test/browser/template.htm                |   10 +
 util/less/test/css/charsets.css                    |    1 +
 util/less/test/css/colors.css                      |   80 +
 util/less/test/css/comments.css                    |   63 +
 util/less/test/css/css-3.css                       |  113 +
 util/less/test/css/css-escapes.css                 |   24 +
 util/less/test/css/css.css                         |   89 +
 util/less/test/css/debug/linenumbers-all.css       |   43 +
 util/less/test/css/debug/linenumbers-comments.css  |   35 +
 .../less/test/css/debug/linenumbers-mediaquery.css |   35 +
 util/less/test/css/functions.css                   |  100 +
 util/less/test/css/ie-filters.css                  |    9 +
 util/less/test/css/import-once.css                 |    3 +
 util/less/test/css/import.css                      |   21 +
 util/less/test/css/javascript.css                  |   23 +
 util/less/test/css/lazy-eval.css                   |    3 +
 util/less/test/css/media.css                       |  195 +
 util/less/test/css/mixins-args.css                 |   95 +
 util/less/test/css/mixins-closure.css              |    9 +
 util/less/test/css/mixins-guards.css               |   71 +
 util/less/test/css/mixins-important.css            |   38 +
 util/less/test/css/mixins-named-args.css           |   27 +
 util/less/test/css/mixins-nested.css               |   14 +
 util/less/test/css/mixins-pattern.css              |   47 +
 util/less/test/css/mixins.css                      |  121 +
 util/less/test/css/operations.css                  |   49 +
 util/less/test/css/parens.css                      |   20 +
 util/less/test/css/rulesets.css                    |   33 +
 util/less/test/css/scope.css                       |   35 +
 util/less/test/css/selectors.css                   |  133 +
 util/less/test/css/static-urls/urls.css            |   42 +
 util/less/test/css/strings.css                     |   40 +
 util/less/test/css/urls.css                        |   42 +
 util/less/test/css/variables.css                   |   26 +
 util/less/test/css/whitespace.css                  |   42 +
 util/less/test/less-test.js                        |  182 +
 util/less/test/less/charsets.less                  |    3 +
 util/less/test/less/colors.less                    |   92 +
 util/less/test/less/comments.less                  |   77 +
 util/less/test/less/css-3.less                     |  113 +
 util/less/test/less/css-escapes.less               |   33 +
 util/less/test/less/css.less                       |  102 +
 util/less/test/less/debug/import/test.less         |   25 +
 util/less/test/less/debug/linenumbers.less         |   23 +
 .../less/errors/bad-variable-declaration1.less     |    1 +
 .../test/less/errors/bad-variable-declaration1.txt |    2 +
 .../less/test/less/errors/comment-in-selector.less |    1 +
 util/less/test/less/errors/comment-in-selector.txt |    2 +
 util/less/test/less/errors/import-missing.less     |    1 +
 util/less/test/less/errors/import-missing.txt      |    3 +
 util/less/test/less/errors/import-no-semi.less     |    1 +
 util/less/test/less/errors/import-no-semi.txt      |    2 +
 util/less/test/less/errors/import-subfolder1.less  |    1 +
 util/less/test/less/errors/import-subfolder1.txt   |    3 +
 util/less/test/less/errors/import-subfolder2.less  |    1 +
 util/less/test/less/errors/import-subfolder2.txt   |    2 +
 .../less/errors/imports/import-subfolder1.less     |    1 +
 .../less/errors/imports/import-subfolder2.less     |    1 +
 .../less/test/less/errors/imports/import-test.less |    4 +
 .../imports/subfolder/mixin-not-defined.less       |    1 +
 .../subfolder/parse-error-curly-bracket.less       |    1 +
 util/less/test/less/errors/javascript-error.less   |    3 +
 util/less/test/less/errors/javascript-error.txt    |    4 +
 .../less/errors/mixed-mixin-definition-args-1.less |    6 +
 .../less/errors/mixed-mixin-definition-args-1.txt  |    4 +
 .../less/errors/mixed-mixin-definition-args-2.less |    6 +
 .../less/errors/mixed-mixin-definition-args-2.txt  |    4 +
 util/less/test/less/errors/mixin-not-defined.less  |   11 +
 util/less/test/less/errors/mixin-not-defined.txt   |    3 +
 util/less/test/less/errors/mixin-not-matched.less  |    6 +
 util/less/test/less/errors/mixin-not-matched.txt   |    3 +
 util/less/test/less/errors/mixin-not-matched2.less |    6 +
 util/less/test/less/errors/mixin-not-matched2.txt  |    3 +
 .../less/errors/parse-error-curly-bracket.less     |    1 +
 .../test/less/errors/parse-error-curly-bracket.txt |    2 +
 .../less/errors/parse-error-missing-bracket.less   |    2 +
 .../less/errors/parse-error-missing-bracket.txt    |    2 +
 .../test/less/errors/parse-error-with-import.less  |   13 +
 .../test/less/errors/parse-error-with-import.txt   |    4 +
 util/less/test/less/errors/property-ie5-hack.less  |    3 +
 util/less/test/less/errors/property-ie5-hack.txt   |    4 +
 util/less/test/less/errors/recursive-variable.less |    1 +
 util/less/test/less/errors/recursive-variable.txt  |    2 +
 util/less/test/less/functions.less                 |  111 +
 util/less/test/less/ie-filters.less                |   15 +
 util/less/test/less/import-once.less               |    4 +
 util/less/test/less/import.less                    |   12 +
 .../less/import/deeper/import-once-test-a.less     |    1 +
 .../import/import-and-relative-paths-test.less     |    6 +
 .../less/test/less/import/import-charset-test.less |    1 +
 util/less/test/less/import/import-once-test-c.less |    6 +
 util/less/test/less/import/import-test-a.less      |    3 +
 util/less/test/less/import/import-test-b.less      |    8 +
 util/less/test/less/import/import-test-c.less      |    6 +
 util/less/test/less/import/import-test-d.css       |    1 +
 util/less/test/less/import/import-test-e.less      |    2 +
 util/less/test/less/import/imports/font.less       |    8 +
 util/less/test/less/import/imports/logo.less       |    5 +
 util/less/test/less/import/urls.less               |    1 +
 util/less/test/less/javascript.less                |   29 +
 util/less/test/less/lazy-eval.less                 |    6 +
 util/less/test/less/media.less                     |  199 +
 util/less/test/less/mixins-args.less               |  167 +
 util/less/test/less/mixins-closure.less            |   26 +
 util/less/test/less/mixins-guards.less             |  124 +
 util/less/test/less/mixins-important.less          |   22 +
 util/less/test/less/mixins-named-args.less         |   36 +
 util/less/test/less/mixins-nested.less             |   22 +
 util/less/test/less/mixins-pattern.less            |   99 +
 util/less/test/less/mixins.less                    |  114 +
 util/less/test/less/operations.less                |   62 +
 util/less/test/less/parens.less                    |   26 +
 util/less/test/less/rulesets.less                  |   30 +
 util/less/test/less/scope.less                     |   79 +
 util/less/test/less/selectors.less                 |  136 +
 util/less/test/less/static-urls/urls.less          |   33 +
 util/less/test/less/strings.less                   |   51 +
 util/less/test/less/urls.less                      |   33 +
 util/less/test/less/variables.less                 |   53 +
 util/less/test/less/whitespace.less                |   44 +
 util/less/tree.js                                  |   13 -
 util/less/tree/alpha.js                            |   17 -
 util/less/tree/anonymous.js                        |   13 -
 util/less/tree/call.js                             |   45 -
 util/less/tree/color.js                            |   98 -
 util/less/tree/comment.js                          |   14 -
 util/less/tree/dimension.js                        |   34 -
 util/less/tree/directive.js                        |   33 -
 util/less/tree/element.js                          |   35 -
 util/less/tree/expression.js                       |   23 -
 util/less/tree/import.js                           |   77 -
 util/less/tree/javascript.js                       |   51 -
 util/less/tree/keyword.js                          |    9 -
 util/less/tree/mixin.js                            |  106 -
 util/less/tree/operation.js                        |   32 -
 util/less/tree/quoted.js                           |   29 -
 util/less/tree/rule.js                             |   38 -
 util/less/tree/ruleset.js                          |  212 -
 util/less/tree/selector.js                         |   28 -
 util/less/tree/url.js                              |   25 -
 util/less/tree/value.js                            |   24 -
 util/less/tree/variable.js                         |   24 -
 util/shrinksafe/shrinksafe.jar                     |  Bin 19066 -> 19090 bytes
 util/shrinksafe/src/manifest                       |    6 +-
 .../src/org/dojotoolkit/shrinksafe/Compressor.java |    2 +-
 .../shrinksafe/resources/Messages.properties       |    2 +-
 util/shrinksafe/tests/escapeunicode.js             |    3 +-
 util/shrinksafe/tests/module.js                    |   25 +-
 util/shrinksafe/tests/runner.sh                    |    2 +-
 8349 files changed, 517266 insertions(+), 220092 deletions(-)

diff --git a/dijit/BackgroundIframe.js b/dijit/BackgroundIframe.js
index 6d37e8d..07f815c 100644
--- a/dijit/BackgroundIframe.js
+++ b/dijit/BackgroundIframe.js
@@ -1,21 +1,23 @@
 define([
 	"require",			// require.toUrl
-	".",	// to export dijit.BackgroundIframe
+	"./main",	// to export dijit.BackgroundIframe
 	"dojo/_base/config",
 	"dojo/dom-construct", // domConstruct.create
 	"dojo/dom-style", // domStyle.set
 	"dojo/_base/lang", // lang.extend lang.hitch
 	"dojo/on",
-	"dojo/_base/sniff", // has("ie"), has("mozilla"), has("quirks")
-	"dojo/_base/window" // win.doc.createElement
-], function(require, dijit, config, domConstruct, domStyle, lang, on, has, win){
+	"dojo/sniff" // has("ie"), has("mozilla"), has("quirks")
+], function(require, dijit, config, domConstruct, domStyle, lang, on, has){
 
 	// module:
 	//		dijit/BackgroundIFrame
-	// summary:
-	//		new dijit.BackgroundIframe(node)
-	//		Makes a background iframe as a child of node, that fills
-	//		area (and position) of node
+
+	// Flag for whether to create background iframe behind popups like Menus and Dialog.
+	// A background iframe is useful to prevent problems with popups appearing behind applets/pdf files,
+	// and is also useful on older versions of IE (IE6 and IE7) to prevent the "bleed through select" problem.
+	// TODO: For 2.0, make this false by default.  Also, possibly move definition to has.js so that this module can be
+	// conditionally required via  dojo/has!bgIfame?dijit/BackgroundIframe
+	has.add("config-bgIframe", !has("touch"));
 
 	// TODO: remove _frames, it isn't being used much, since popups never release their
 	// iframes (see [22236])
@@ -31,12 +33,13 @@ define([
 				iframe = queue.pop();
 				iframe.style.display="";
 			}else{
+				// transparency needed for DialogUnderlay and for tooltips on IE (to see screen near connector)
 				if(has("ie") < 9){
 					var burl = config["dojoBlankHtmlUrl"] || require.toUrl("dojo/resources/blank.html") || "javascript:\"\"";
 					var html="<iframe src='" + burl + "' role='presentation'"
 						+ " style='position: absolute; left: 0px; top: 0px;"
 						+ "z-index: -1; filter:Alpha(Opacity=\"0\");'>";
-					iframe = win.doc.createElement(html);
+					iframe = document.createElement(html);
 				}else{
 					iframe = domConstruct.create("iframe");
 					iframe.src = 'javascript:""';
@@ -58,22 +61,21 @@ define([
 
 	dijit.BackgroundIframe = function(/*DomNode*/ node){
 		// summary:
-		//		For IE/FF z-index schenanigans. id attribute is required.
+		//		For IE/FF z-index shenanigans. id attribute is required.
 		//
 		// description:
-		//		new dijit.BackgroundIframe(node)
-		//			Makes a background iframe as a child of node, that fills
-		//			area (and position) of node
+		//		new dijit.BackgroundIframe(node).
+		//
+		//		Makes a background iframe as a child of node, that fills
+		//		area (and position) of node
 
 		if(!node.id){ throw new Error("no id"); }
-		if(has("ie") || has("mozilla")){
+		if(has("config-bgIframe")){
 			var iframe = (this.iframe = _frames.pop());
 			node.appendChild(iframe);
 			if(has("ie")<7 || has("quirks")){
 				this.resize(node);
-				this._conn = on(node, 'resize', lang.hitch(this, function(){
-					this.resize(node);
-				}));
+				this._conn = on(node, 'resize', lang.hitch(this, "resize", node));
 			}else{
 				domStyle.set(iframe, {
 					width: '100%',
@@ -86,7 +88,7 @@ define([
 	lang.extend(dijit.BackgroundIframe, {
 		resize: function(node){
 			// summary:
-			// 		Resize the iframe so it's the same size as node.
+			//		Resize the iframe so it's the same size as node.
 			//		Needed on IE6 and IE/quirks because height:100% doesn't work right.
 			if(this.iframe){
 				domStyle.set(this.iframe, {
diff --git a/dijit/Calendar.js b/dijit/Calendar.js
index a0e9846..e20edbe 100644
--- a/dijit/Calendar.js
+++ b/dijit/Calendar.js
@@ -5,45 +5,33 @@ define([
 	"dojo/_base/declare", // declare
 	"dojo/dom-attr", // domAttr.get
 	"dojo/dom-class", // domClass.add domClass.contains domClass.remove domClass.toggle
-	"dojo/_base/event", // event.stop
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/keys", // keys
 	"dojo/_base/lang", // lang.hitch
-	"dojo/_base/sniff", // has("ie")
+	"dojo/on",
+	"dojo/sniff", // has("ie")
 	"./CalendarLite",
 	"./_Widget",
 	"./_CssStateMixin",
 	"./_TemplatedMixin",
-	"./form/DropDownButton",
-	"./hccss"	// not used directly, but sets CSS class on <body>
-], function(array, date, local, declare, domAttr, domClass, event, kernel, keys, lang, has,
-			CalendarLite, _Widget, _CssStateMixin, _TemplatedMixin, DropDownButton){
-
-/*=====
-	var CalendarLite = dijit.CalendarLite;
-	var _CssStateMixin = dijit._CssStateMixin;
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var DropDownButton = dijit.form.DropDownButton;
-=====*/
+	"./form/DropDownButton"
+], function(array, date, local, declare, domAttr, domClass, kernel, keys, lang, on, has, CalendarLite, _Widget, _CssStateMixin, _TemplatedMixin, DropDownButton){
 
 	// module:
 	//		dijit/Calendar
-	// summary:
-	//		A simple GUI for choosing a date in the context of a monthly calendar.
 
-	var Calendar = declare("dijit.Calendar",
-		[CalendarLite, _Widget, _CssStateMixin], // _Widget for deprecated methods like setAttribute()
-		{
+	// _Widget for deprecated methods like setAttribute()
+	var Calendar = declare("dijit.Calendar", [CalendarLite, _Widget, _CssStateMixin], {
 		// summary:
 		//		A simple GUI for choosing a date in the context of a monthly calendar.
 		//
 		// description:
 		//		See CalendarLite for general description.   Calendar extends CalendarLite, adding:
-		//			- month drop down list
-		//			- keyboard navigation
-		//			- CSS classes for hover/mousepress on date, month, and year nodes
-		//			- support of deprecated methods (will be removed in 2.0)
+		//
+		//		- month drop down list
+		//		- keyboard navigation
+		//		- CSS classes for hover/mousepress on date, month, and year nodes
+		//		- support of deprecated methods (will be removed in 2.0)
 
 		// Set node classes for various mouse events, see dijit._CssStateMixin for more details
 		cssStateNodes: {
@@ -55,9 +43,9 @@ define([
 
 		setValue: function(/*Date*/ value){
 			// summary:
-			//      Deprecated.   Use set('value', ...) instead.
+			//		Deprecated.   Use set('value', ...) instead.
 			// tags:
-			//      deprecated
+			//		deprecated
 			kernel.deprecated("dijit.Calendar:setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
 			this.set('value', value);
 		},
@@ -75,41 +63,48 @@ define([
 			}, this.monthNode);
 		},
 
-		buildRendering: function(){
+		postCreate: function(){
 			this.inherited(arguments);
 
 			// Events specific to Calendar, not used in CalendarLite
-			this.connect(this.domNode, "onkeypress", "_onKeyPress");
-			this.connect(this.dateRowsNode, "onmouseover", "_onDayMouseOver");
-			this.connect(this.dateRowsNode, "onmouseout", "_onDayMouseOut");
-			this.connect(this.dateRowsNode, "onmousedown", "_onDayMouseDown");
-			this.connect(this.dateRowsNode, "onmouseup", "_onDayMouseUp");
+			this.own(
+				on(this.domNode, "keydown", lang.hitch(this, "_onKeyDown")),
+				on(this.dateRowsNode, "mouseover", lang.hitch(this, "_onDayMouseOver")),
+				on(this.dateRowsNode, "mouseout", lang.hitch(this, "_onDayMouseOut")),
+				on(this.dateRowsNode, "mousedown", lang.hitch(this, "_onDayMouseDown")),
+				on(this.dateRowsNode, "mouseup", lang.hitch(this, "_onDayMouseUp"))
+			);
 		},
 
 		_onMonthSelect: function(/*Number*/ newMonth){
 			// summary:
-			//      Handler for when user selects a month from the drop down list
+			//		Handler for when user selects a month from the drop down list
 			// tags:
-			//      protected
+			//		protected
 
 			// move to selected month, bounding by the number of days in the month
-			// (ex: dec 31 --> jan 28, not jan 31)
-			this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus, "month",
-				newMonth - this.currentFocus.getMonth()));
+			// (ex: jan 31 --> feb 28, not feb 31)
+			var date = new this.dateClassObj(this.currentFocus);
+			date.setDate(1);
+			date.setMonth(newMonth);
+			var daysInMonth = this.dateModule.getDaysInMonth(date);
+			var currentDate = this.currentFocus.getDate();
+			date.setDate(Math.min(currentDate, daysInMonth));
+			this._setCurrentFocusAttr(date);
 		},
 
 		_onDayMouseOver: function(/*Event*/ evt){
 			// summary:
-			//      Handler for mouse over events on days, sets hovered style
+			//		Handler for mouse over events on days, sets hovered style
 			// tags:
-			//      protected
+			//		protected
 
 			// event can occur on <td> or the <span> inside the td,
 			// set node to the <td>.
 			var node =
 				domClass.contains(evt.target, "dijitCalendarDateLabel") ?
-				evt.target.parentNode :
-				evt.target;
+					evt.target.parentNode :
+					evt.target;
 
 			if(node && (
 				(node.dijitDateValue && !domClass.contains(node, "dijitCalendarDisabledDate"))
@@ -122,14 +117,18 @@ define([
 
 		_onDayMouseOut: function(/*Event*/ evt){
 			// summary:
-			//      Handler for mouse out events on days, clears hovered style
+			//		Handler for mouse out events on days, clears hovered style
 			// tags:
-			//      protected
+			//		protected
 
-			if(!this._currentNode){ return; }
+			if(!this._currentNode){
+				return;
+			}
 
 			// if mouse out occurs moving from <td> to <span> inside <td>, ignore it
-			if(evt.relatedTarget && evt.relatedTarget.parentNode == this._currentNode){ return; }
+			if(evt.relatedTarget && evt.relatedTarget.parentNode == this._currentNode){
+				return;
+			}
 			var cls = "dijitCalendarHoveredDate";
 			if(domClass.contains(this._currentNode, "dijitCalendarActiveDate")){
 				cls += " dijitCalendarActiveDate";
@@ -157,57 +156,55 @@ define([
 			// summary:
 			//		Provides keyboard navigation of calendar.
 			// description:
-			//		Called from _onKeyPress() to handle keypress on a stand alone Calendar,
-			//		and also from `dijit.form._DateTimeTextBox` to pass a keypress event
-			//		from the `dijit.form.DateTextBox` to be handled in this widget
+			//		Called from _onKeyDown() to handle keydown on a stand alone Calendar,
+			//		and also from `dijit/form/_DateTimeTextBox` to pass a keydown event
+			//		from the `dijit/form/DateTextBox` to be handled in this widget
 			// returns:
 			//		False if the key was recognized as a navigation key,
-			//		to indicate that the event was handled by Calendar and shouldn't be propogated
+			//		to indicate that the event was handled by Calendar and shouldn't be propagated
 			// tags:
 			//		protected
 			var increment = -1,
 				interval,
 				newValue = this.currentFocus;
-			switch(evt.charOrCode){
+			switch(evt.keyCode){
 				case keys.RIGHT_ARROW:
 					increment = 1;
-					//fallthrough...
+				//fallthrough...
 				case keys.LEFT_ARROW:
 					interval = "day";
-					if(!this.isLeftToRight()){ increment *= -1; }
+					if(!this.isLeftToRight()){
+						increment *= -1;
+					}
 					break;
 				case keys.DOWN_ARROW:
 					increment = 1;
-					//fallthrough...
+				//fallthrough...
 				case keys.UP_ARROW:
 					interval = "week";
 					break;
 				case keys.PAGE_DOWN:
 					increment = 1;
-					//fallthrough...
+				//fallthrough...
 				case keys.PAGE_UP:
 					interval = evt.ctrlKey || evt.altKey ? "year" : "month";
 					break;
 				case keys.END:
 					// go to the next month
-					newValue = this.dateFuncObj.add(newValue, "month", 1);
+					newValue = this.dateModule.add(newValue, "month", 1);
 					// subtract a day from the result when we're done
 					interval = "day";
-					//fallthrough...
+				//fallthrough...
 				case keys.HOME:
 					newValue = new this.dateClassObj(newValue);
 					newValue.setDate(1);
 					break;
-				case keys.ENTER:
-				case " ":
-					this.set("value", this.currentFocus);
-					break;
 				default:
 					return true;
 			}
 
 			if(interval){
-				newValue = this.dateFuncObj.add(newValue, interval, increment);
+				newValue = this.dateModule.add(newValue, interval, increment);
 			}
 
 			this._setCurrentFocusAttr(newValue);
@@ -215,11 +212,12 @@ define([
 			return false;
 		},
 
-		_onKeyPress: function(/*Event*/ evt){
+		_onKeyDown: function(/*Event*/ evt){
 			// summary:
-			//		For handling keypress events on a stand alone calendar
+			//		For handling keydown events on a stand alone calendar
 			if(!this.handleKey(evt)){
-				event.stop(evt);
+				evt.stopPropagation();
+				evt.preventDefault();
 			}
 		},
 
@@ -227,10 +225,10 @@ define([
 			// summary:
 			//		Deprecated.   Notification that a date cell was selected.  It may be the same as the previous value.
 			// description:
-			//      Formerly used by `dijit.form._DateTimeTextBox` (and thus `dijit.form.DateTextBox`)
-			//      to get notification when the user has clicked a date.  Now onExecute() (above) is used.
+			//		Formerly used by `dijit/form/_DateTimeTextBox` (and thus `dijit/form/DateTextBox`)
+			//		to get notification when the user has clicked a date.  Now onExecute() (above) is used.
 			// tags:
-			//      protected
+			//		protected
 		},
 
 		onChange: function(value){
@@ -244,11 +242,11 @@ define([
 			// dateObject: Date
 			// locale: String?
 			// tags:
-			//      extension
+			//		extension
 
-/*=====
-			return ""; // String
-=====*/
+			/*=====
+			 return ""; // String
+			 =====*/
 		}
 	});
 
@@ -257,7 +255,8 @@ define([
 		//		DropDownButton for the current month.    Displays name of current month
 		//		and a list of month names in the drop down
 
-		onMonthSelect: function(){ },
+		onMonthSelect: function(){
+		},
 
 		postCreate: function(){
 			this.inherited(arguments);
@@ -277,7 +276,7 @@ define([
 			// the center <TH> overlaps the right <TH> (due to a browser bug).
 			this.containerNode.innerHTML =
 				(has("ie") == 6 ? "" : "<div class='dijitSpacer'>" + this.dropDown.domNode.innerHTML + "</div>") +
-				"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>" +  monthNames[month.getMonth()] + "</div>";
+					"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>" + monthNames[month.getMonth()] + "</div>";
 		}
 	});
 
@@ -294,9 +293,9 @@ define([
 			"data-dojo-attach-event='onclick:_onClick,onmouseover:_onMenuHover,onmouseout:_onMenuHover'></div>",
 
 		_setMonthsAttr: function(/*String[]*/ months){
-			this.domNode.innerHTML = array.map(months, function(month, idx){
-					return month ? "<div class='dijitCalendarMonthLabel' month='" + idx +"'>" + month + "</div>" : "";
-				}).join("");
+			this.domNode.innerHTML = array.map(months,function(month, idx){
+				return month ? "<div class='dijitCalendarMonthLabel' month='" + idx + "'>" + month + "</div>" : "";
+			}).join("");
 		},
 
 		_onClick: function(/*Event*/ evt){
diff --git a/dijit/CalendarLite.js b/dijit/CalendarLite.js
index 66da5c6..f2cbd78 100644
--- a/dijit/CalendarLite.js
+++ b/dijit/CalendarLite.js
@@ -4,28 +4,23 @@ define([
 	"dojo/cldr/supplemental", // cldrSupplemental.getFirstDayOfWeek
 	"dojo/date", // date
 	"dojo/date/locale",
+	"dojo/date/stamp", // stamp.fromISOString
 	"dojo/dom", // dom.setSelectable
 	"dojo/dom-class", // domClass.contains
-	"dojo/_base/event", // event.stop
 	"dojo/_base/lang", // lang.getObject, lang.hitch
-	"dojo/_base/sniff", // has("ie") has("webkit")
+	"dojo/on",
+	"dojo/sniff", // has("ie") has("webkit")
 	"dojo/string", // string.substitute
-	"dojo/_base/window", // win.doc.createTextNode
 	"./_WidgetBase",
 	"./_TemplatedMixin",
-	"dojo/text!./templates/Calendar.html"
-], function(array, declare, cldrSupplemental, date, local, dom, domClass, event, lang, has, string, win,
-			_WidgetBase, _TemplatedMixin, template){
+	"dojo/text!./templates/Calendar.html",
+	"./a11yclick",	// not used directly, but template has ondijitclick in it
+	"./hccss"    // not used directly, but sets CSS class on <body>
+], function(array, declare, cldrSupplemental, date, locale, stamp, dom, domClass, lang, on, has, string, _WidgetBase, _TemplatedMixin, template){
 
-/*=====
-	var _WidgetBase = dijit._WidgetBase;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-=====*/
 
 	// module:
 	//		dijit/CalendarLite
-	// summary:
-	//		Lightweight version of Calendar widget aimed towards mobile use
 
 	var CalendarLite = declare("dijit.CalendarLite", [_WidgetBase, _TemplatedMixin], {
 		// summary:
@@ -34,7 +29,7 @@ define([
 		// description:
 		//		A simple GUI for choosing a date in the context of a monthly calendar.
 		//		This widget can't be used in a form because it doesn't serialize the date to an
-		//		`<input>` field.  For a form element, use dijit.form.DateTextBox instead.
+		//		`<input>` field.  For a form element, use dijit/form/DateTextBox instead.
 		//
 		//		Note that the parser takes all dates attributes passed in the
 		//		[RFC 3339 format](http://www.faqs.org/rfcs/rfc3339.html), e.g. `2005-06-30T08:05:00-07:00`
@@ -45,13 +40,13 @@ define([
 		//	|	var calendar = new dijit.CalendarLite({}, dojo.byId("calendarNode"));
 		//
 		// example:
-		//	|	<div data-dojo-type="dijit.CalendarLite"></div>
+		//	|	<div data-dojo-type="dijit/CalendarLite"></div>
 
 		// Template for main calendar
 		templateString: template,
 
 		// Template for cell for a day of the week (ex: M)
-		dowTemplateString: '<th class="dijitReset dijitCalendarDayLabelTemplate" role="columnheader"><span class="dijitCalendarDayLabel">${d}</span></th>',
+		dowTemplateString: '<th class="dijitReset dijitCalendarDayLabelTemplate" role="columnheader" scope="col"><span class="dijitCalendarDayLabel">${d}</span></th>',
 
 		// Templates for a single date (ex: 13), and for a row for a week (ex: 20 21 22 23 24 25 26)
 		dateTemplateString: '<td class="dijitReset" role="gridcell" data-dojo-attach-point="dateCells"><span class="dijitCalendarDateLabel" data-dojo-attach-point="dateLabels"></span></td>',
@@ -63,15 +58,18 @@ define([
 		// TODO: for 2.0 make this a string (ISO format) rather than a Date
 
 		// datePackage: String
-		//		JavaScript object containing Calendar functions.  Uses Gregorian Calendar routines
-		//		from dojo.date by default.
-		datePackage: date,
+		//		JavaScript namespace to find calendar routines.	 If unspecified, uses Gregorian calendar routines
+		//		at dojo/date and dojo/date/locale.
+		datePackage: "",
+		//		TODO: for 2.0, replace datePackage with dateModule and dateLocalModule attributes specifying MIDs,
+		//		or alternately just get rid of this completely and tell user to use module ID remapping
+		//		via require
 
 		// dayWidth: String
 		//		How to represent the days of the week in the calendar header. See locale
 		dayWidth: "narrow",
 
-		// tabIndex: Integer
+		// tabIndex: String
 		//		Order fields are traversed when user hits the tab key
 		tabIndex: "0",
 
@@ -81,7 +79,10 @@ define([
 		//		i.e. the current "page" the calendar is on.
 		currentFocus: new Date(),
 
-		baseClass:"dijitCalendar",
+		// Put the summary to the node with role=grid
+		_setSummaryAttr: "gridNode",
+
+		baseClass: "dijitCalendar",
 
 		_isValidDate: function(/*Date*/ value){
 			// summary:
@@ -98,14 +99,15 @@ define([
 			//		Support get('value')
 
 			// this.value is set to 1AM, but return midnight, local time for back-compat
-			if(this.value && !isNaN(this.value)){
-				var value = new this.dateClassObj(this.value);
+			var storedVal = this._get("value");
+			if(storedVal && !isNaN(storedVal)){
+				var value = new this.dateClassObj(storedVal);
 				value.setHours(0, 0, 0, 0);
 
 				// If daylight savings pushes midnight to the previous date, fix the Date
 				// object to point at 1am so it will represent the correct day. See #9366
-				if(value.getDate() < this.value.getDate()){
-					value = this.dateFuncObj.add(value, "hour", 1);
+				if(value.getDate() < storedVal.getDate()){
+					value = this.dateModule.add(value, "hour", 1);
 				}
 				return value;
 			}else{
@@ -117,68 +119,84 @@ define([
 			// summary:
 			//		Support set("value", ...)
 			// description:
-			// 		Set the current date and update the UI.  If the date is disabled, the value will
+			//		Set the current date and update the UI.  If the date is disabled, the value will
 			//		not change, but the display will change to the corresponding month.
 			// value:
 			//		Either a Date or the number of seconds since 1970.
 			// tags:
-			//      protected
-			if(value){
-				// convert from Number to Date, or make copy of Date object so that setHours() call below
-				// doesn't affect original value
-				value = new this.dateClassObj(value);
+			//		protected
+			if(typeof value == "string"){
+				value = stamp.fromISOString(value);
 			}
-			if(this._isValidDate(value)){
-				if(!this._isValidDate(this.value) || this.dateFuncObj.compare(value, this.value)){
-					value.setHours(1, 0, 0, 0); // round to nearest day (1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)
-
-					if(!this.isDisabledDate(value, this.lang)){
-						this._set("value", value);
-
-						// Set focus cell to the new value.   Arguably this should only happen when there isn't a current
-						// focus point.   This will also repopulate the grid, showing the new selected value (and possibly
-						// new month/year).
-						this.set("currentFocus", value);
-
-						if(priorityChange || typeof priorityChange == "undefined"){
-							this.onChange(this.get('value'));
-						}
-					}
+			value = this._patchDate(value);
+
+			if(this._isValidDate(value) && !this.isDisabledDate(value, this.lang)){
+				this._set("value", value);
+
+				// Set focus cell to the new value.   Arguably this should only happen when there isn't a current
+				// focus point.   This will also repopulate the grid to new month/year if necessary.
+				this.set("currentFocus", value);
+
+				// Mark the selected date
+				this._markSelectedDates([value]);
+
+				if(this._created && (priorityChange || typeof priorityChange == "undefined")){
+					this.onChange(this.get('value'));
 				}
 			}else{
-				// clear value, and repopulate grid (to deselect the previously selected day) without changing currentFocus
+				// clear value, and mark all dates as unselected
 				this._set("value", null);
-				this.set("currentFocus", this.currentFocus);
+				this._markSelectedDates([]);
 			}
 		},
 
+		_patchDate: function(/*Date|Number*/ value){
+			// summary:
+			//		Convert Number into Date, or copy Date object.   Then, round to nearest day,
+			//		setting to 1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)
+			if(value){
+				value = new this.dateClassObj(value);
+				value.setHours(1, 0, 0, 0);
+			}
+			return value;
+		},
+
 		_setText: function(node, text){
 			// summary:
 			//		This just sets the content of node to the specified text.
 			//		Can't do "node.innerHTML=text" because of an IE bug w/tables, see #3434.
 			// tags:
-			//      private
+			//		private
 			while(node.firstChild){
 				node.removeChild(node.firstChild);
 			}
-			node.appendChild(win.doc.createTextNode(text));
+			node.appendChild(node.ownerDocument.createTextNode(text));
 		},
 
 		_populateGrid: function(){
 			// summary:
-			//      Fills in the calendar grid with each day (1-31)
+			//		Fills in the calendar grid with each day (1-31).
+			//		Call this on creation, when moving to a new month.
 			// tags:
-			//      private
+			//		private
 
 			var month = new this.dateClassObj(this.currentFocus);
 			month.setDate(1);
 
 			var firstDay = month.getDay(),
-				daysInMonth = this.dateFuncObj.getDaysInMonth(month),
-				daysInPreviousMonth = this.dateFuncObj.getDaysInMonth(this.dateFuncObj.add(month, "month", -1)),
+				daysInMonth = this.dateModule.getDaysInMonth(month),
+				daysInPreviousMonth = this.dateModule.getDaysInMonth(this.dateModule.add(month, "month", -1)),
 				today = new this.dateClassObj(),
 				dayOffset = cldrSupplemental.getFirstDayOfWeek(this.lang);
-			if(dayOffset > firstDay){ dayOffset -= 7; }
+			if(dayOffset > firstDay){
+				dayOffset -= 7;
+			}
+
+			// If they didn't provide a summary, change the default summary to match with the new month
+			if(!this.summary){
+				var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month)
+				this.gridNode.setAttribute("summary", monthNames[month.getMonth()]);
+			}
 
 			// Mapping from date (as specified by number returned from Date.valueOf()) to corresponding <td>
 			this._date2cell = {};
@@ -203,27 +221,21 @@ define([
 				}
 
 				if(adj){
-					date = this.dateFuncObj.add(date, "month", adj);
+					date = this.dateModule.add(date, "month", adj);
 				}
 				date.setDate(number);
 
-				if(!this.dateFuncObj.compare(date, today, "date")){
+				if(!this.dateModule.compare(date, today, "date")){
 					clazz = "dijitCalendarCurrentDate " + clazz;
 				}
 
-				if(this._isSelectedDate(date, this.lang)){
-					clazz = "dijitCalendarSelectedDate " + clazz;
-					template.setAttribute("aria-selected", true);
-				}else{
-					template.setAttribute("aria-selected", false);
-				}
-
 				if(this.isDisabledDate(date, this.lang)){
 					clazz = "dijitCalendarDisabledDate " + clazz;
-					template.setAttribute("aria-disabled", true);
+					template.setAttribute("aria-disabled", "true");
 				}else{
 					clazz = "dijitCalendarEnabledDate " + clazz;
 					template.removeAttribute("aria-disabled");
+					template.setAttribute("aria-selected", "false");
 				}
 
 				var clazz2 = this.getClassForDate(date, this.lang);
@@ -241,33 +253,48 @@ define([
 				// Set Date string (ex: "13").
 				this._setText(this.dateLabels[idx], date.getDateLocalized ? date.getDateLocalized(this.lang) : date.getDate());
 			}, this);
+		},
+
+		_populateControls: function(){
+			// summary:
+			//		Fill in localized month, and prev/current/next years
+			// tags:
+			//		protected
+
+			var month = new this.dateClassObj(this.currentFocus);
+			month.setDate(1);
 
 			// set name of this month
 			this.monthWidget.set("month", month);
 
-			// Fill in localized prev/current/next years
 			var y = month.getFullYear() - 1;
 			var d = new this.dateClassObj();
 			array.forEach(["previous", "current", "next"], function(name){
 				d.setFullYear(y++);
-				this._setText(this[name+"YearLabelNode"],
-					this.dateLocaleModule.format(d, {selector:'year', locale:this.lang}));
+				this._setText(this[name + "YearLabelNode"],
+					this.dateLocaleModule.format(d, {selector: 'year', locale: this.lang}));
 			}, this);
 		},
 
 		goToToday: function(){
 			// summary:
-			//      Sets calendar's value to today's date
+			//		Sets calendar's value to today's date
 			this.set('value', new this.dateClassObj());
 		},
 
-		constructor: function(/*Object*/args){
-			this.datePackage = args.datePackage || this.datePackage;
-			this.dateFuncObj = typeof this.datePackage == "string" ?
-				lang.getObject(this.datePackage, false) :// "string" part for back-compat, remove for 2.0
-				this.datePackage;
-			this.dateClassObj = this.dateFuncObj.Date || Date;
-			this.dateLocaleModule = lang.getObject("locale", false, this.dateFuncObj);
+		constructor: function(params /*===== , srcNodeRef =====*/){
+			// summary:
+			//		Create the widget.
+			// params: Object|null
+			//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+			//		and functions, typically callbacks like onClick.
+			//		The hash can contain any of the widget's properties, excluding read-only properties.
+			// srcNodeRef: DOMNode|String?
+			//		If a srcNodeRef (DOM node) is specified, replace srcNodeRef with my generated DOM tree
+
+			this.dateModule = params.datePackage ? lang.getObject(params.datePackage, false) : date;
+			this.dateClassObj = this.dateModule.Date || Date;
+			this.dateLocaleModule = params.datePackage ? lang.getObject(params.datePackage + ".locale", false) : locale;
 		},
 
 		_createMonthWidget: function(){
@@ -275,7 +302,7 @@ define([
 			//		Creates the drop down button that displays the current month and lets user pick a new one
 
 			return CalendarLite._MonthWidget({
-				id: this.id + "_mw",
+				id: this.id + "_mddb",
 				lang: this.lang,
 				dateLocaleModule: this.dateLocaleModule
 			}, this.monthNode);
@@ -286,13 +313,13 @@ define([
 			var d = this.dowTemplateString,
 				dayNames = this.dateLocaleModule.getNames('days', this.dayWidth, 'standAlone', this.lang),
 				dayOffset = cldrSupplemental.getFirstDayOfWeek(this.lang);
-			this.dayCellsHtml = string.substitute([d,d,d,d,d,d,d].join(""), {d: ""}, function(){
-				return dayNames[dayOffset++ % 7]
+			this.dayCellsHtml = string.substitute([d, d, d, d, d, d, d].join(""), {d: ""}, function(){
+				return dayNames[dayOffset++ % 7];
 			});
 
 			// Markup for dates of the month (referenced from template), but without numbers filled in
 			var r = string.substitute(this.weekTemplateString, {d: this.dateTemplateString});
-			this.dateRowsHtml = [r,r,r,r,r,r].join("");
+			this.dateRowsHtml = [r, r, r, r, r, r].join("");
 
 			// Instantiate from template.
 			// dateCells and dateLabels arrays filled when _Templated parses my template.
@@ -304,20 +331,34 @@ define([
 
 			var dateObj = new this.dateClassObj(this.currentFocus);
 
-			this._supportingWidgets.push(this.monthWidget = this._createMonthWidget());
+			this.monthWidget = this._createMonthWidget();
 
 			this.set('currentFocus', dateObj, false);	// draw the grid to the month specified by currentFocus
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this._connectControls();
+		},
+
+		_connectControls: function(){
+			// summary:
+			//		Set up connects for increment/decrement of months/years
+			// tags:
+			//		protected
 
-			// Set up connects for increment/decrement of months/years
 			var connect = lang.hitch(this, function(nodeProp, part, amount){
-				this.connect(this[nodeProp], "onclick", function(){
-					this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus, part, amount));
-				});
+				return on(this[nodeProp], "click", lang.hitch(this, function(){
+					this._setCurrentFocusAttr(this.dateModule.add(this.currentFocus, part, amount));
+				}));
 			});
-			connect("incrementMonth", "month", 1);
-			connect("decrementMonth", "month", -1);
-			connect("nextYearLabelNode", "year", 1);
-			connect("previousYearLabelNode", "year", -1);
+
+			this.own(
+				connect("incrementMonth", "month", 1),
+				connect("decrementMonth", "month", -1),
+				connect("nextYearLabelNode", "year", 1),
+				connect("previousYearLabelNode", "year", -1)
+			);
 		},
 
 		_setCurrentFocusAttr: function(/*Date*/ date, /*Boolean*/ forceFocus){
@@ -325,24 +366,27 @@ define([
 			//		If the calendar currently has focus, then focuses specified date,
 			//		changing the currently displayed month/year if necessary.
 			//		If the calendar doesn't have focus, updates currently
-			//		displayed month/year, and sets the cell that will get focus.
+			//		displayed month/year, and sets the cell that will get focus
+			//		when Calendar is focused.
 			// forceFocus:
 			//		If true, will focus() the cell even if calendar itself doesn't have focus
 
 			var oldFocus = this.currentFocus,
-				oldCell = oldFocus && this._date2cell ? this._date2cell[oldFocus.valueOf()] : null;
-
-			// round specified value to nearest day (1am to avoid issues when DST shift occurs at midnight, see #8521, #9366)
-			date = new this.dateClassObj(date);
-			date.setHours(1, 0, 0, 0);
+				oldCell = this._getNodeByDate(oldFocus);
+			date = this._patchDate(date);
 
 			this._set("currentFocus", date);
 
-			// TODO: only re-populate grid when month/year has changed
-			this._populateGrid();
+			// If the focus is on a different month than the current calendar month, switch the displayed month.
+			// Also will populate the grid initially, on Calendar creation.
+			if(!this._date2cell || this.dateModule.difference(oldFocus, date, "month") != 0){
+				this._populateGrid();
+				this._populateControls();
+				this._markSelectedDates([this.value]);
+			}
 
 			// set tabIndex=0 on new cell, and focus it (but only if Calendar itself is focused)
-			var newCell = this._date2cell[date.valueOf()];
+			var newCell = this._getNodeByDate(date);
 			newCell.setAttribute("tabIndex", this.tabIndex);
 			if(this.focused || forceFocus){
 				newCell.focus();
@@ -350,7 +394,7 @@ define([
 
 			// set tabIndex=-1 on old focusable cell
 			if(oldCell && oldCell != newCell){
-				if(has("webkit")){	// see #11064 about webkit bug
+				if(has("webkit")){    // see #11064 about webkit bug
 					oldCell.setAttribute("tabIndex", "-1");
 				}else{
 					oldCell.removeAttribute("tabIndex");
@@ -366,30 +410,52 @@ define([
 
 		_onDayClick: function(/*Event*/ evt){
 			// summary:
-			//      Handler for day clicks, selects the date if appropriate
+			//		Handler for day clicks, selects the date if appropriate
 			// tags:
-			//      protected
-			event.stop(evt);
-			for(var node = evt.target; node && !node.dijitDateValue; node = node.parentNode);
+			//		protected
+			evt.stopPropagation();
+			evt.preventDefault();
+			for(var node = evt.target; node && !node.dijitDateValue; node = node.parentNode){
+				;
+			}
 			if(node && !domClass.contains(node, "dijitCalendarDisabledDate")){
 				this.set('value', node.dijitDateValue);
 			}
 		},
 
-		onChange: function(/*Date*/ /*===== date =====*/){
+		_getNodeByDate: function(/*Date*/ value){
 			// summary:
-			//		Called only when the selected date has changed
+			//		Returns the cell corresponding to the date, or null if the date is not within the currently
+			//		displayed month.
+			value = this._patchDate(value);
+			return value && this._date2cell ? this._date2cell[value.valueOf()] : null;
 		},
 
-		_isSelectedDate: function(dateObject /*===== , locale =====*/){
+		_markSelectedDates: function(/*Date[]*/ dates){
 			// summary:
-			//		Extension point so developers can subclass Calendar to
-			//		support multiple (concurrently) selected dates
-			// dateObject: Date
-			// locale: String?
-			// tags:
-			//		protected extension
-			return this._isValidDate(this.value) && !this.dateFuncObj.compare(dateObject, this.value, "date")
+			//		Marks the specified cells as selected, and clears cells previously marked as selected.
+			//		For CalendarLite at most one cell is selected at any point, but this allows an array
+			//		for easy subclassing.
+
+			// Function to mark a cell as selected or unselected
+			function mark(/*Boolean*/ selected, /*DomNode*/ cell){
+				domClass.toggle(cell, "dijitCalendarSelectedDate", selected);
+				cell.setAttribute("aria-selected", selected ? "true" : "false");
+			}
+
+			// Clear previously selected cells.
+			array.forEach(this._selectedCells || [], lang.partial(mark, false));
+
+			// Mark newly selected cells.  Ignore dates outside the currently displayed month.
+			this._selectedCells = array.filter(array.map(dates, this._getNodeByDate, this), function(n){
+				return n;
+			});
+			array.forEach(this._selectedCells, lang.partial(mark, true));
+		},
+
+		onChange: function(/*Date*/ /*===== date =====*/){
+			// summary:
+			//		Called only when the selected date has changed
 		},
 
 		isDisabledDate: function(/*===== dateObject, locale =====*/){
@@ -398,10 +464,10 @@ define([
 			// dateObject: Date
 			// locale: String?
 			// tags:
-			//      extension
-/*=====
-			return false; // Boolean
-=====*/
+			//		extension
+			/*=====
+			 return false; // Boolean
+			 =====*/
 		},
 
 		getClassForDate: function(/*===== dateObject, locale =====*/){
@@ -411,11 +477,11 @@ define([
 			// dateObject: Date
 			// locale: String?
 			// tags:
-			//      extension
+			//		extension
 
-/*=====
-			return ""; // String
-=====*/
+			/*=====
+			 return ""; // String
+			 =====*/
 		}
 	});
 
@@ -424,26 +490,29 @@ define([
 		//		Displays name of current month padded to the width of the month
 		//		w/the longest name, so that changing months doesn't change width.
 		//
-		//		Create as new dijit.Calendar._MonthWidget({
-		//			lang: ...,
-		//			dateLocaleModule: ...
-		//		})
+		//		Create as:
+		// |	new Calendar._MonthWidget({
+		// |			lang: ...,
+		// |			dateLocaleModule: ...
+		// |		})
 
 		_setMonthAttr: function(month){
 			// summary:
 			//		Set the current month to display as a label
 			var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, month),
 				spacer =
-					(has("ie") == 6 ? "" :	"<div class='dijitSpacer'>" +
-						array.map(monthNames, function(s){ return "<div>" + s + "</div>"; }).join("") + "</div>");
+					(has("ie") == 6 ? "" : "<div class='dijitSpacer'>" +
+						array.map(monthNames,function(s){
+							return "<div>" + s + "</div>";
+						}).join("") + "</div>");
 
 			// Set name of current month and also fill in spacer element with all the month names
 			// (invisible) so that the maximum width will affect layout.   But not on IE6 because then
 			// the center <TH> overlaps the right <TH> (due to a browser bug).
 			this.domNode.innerHTML =
 				spacer +
-				"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>" +
-				monthNames[month.getMonth()] + "</div>";
+					"<div class='dijitCalendarMonthLabel dijitCalendarCurrentMonthLabel'>" +
+					monthNames[month.getMonth()] + "</div>";
 		}
 	});
 
diff --git a/dijit/CheckedMenuItem.js b/dijit/CheckedMenuItem.js
index 8627f87..5cf5622 100644
--- a/dijit/CheckedMenuItem.js
+++ b/dijit/CheckedMenuItem.js
@@ -6,19 +6,15 @@ define([
 	"./hccss"
 ], function(declare, domClass, MenuItem, template){
 
-/*=====
-	var MenuItem = dijit.MenuItem;
-=====*/
-
 	// module:
 	//		dijit/CheckedMenuItem
-	// summary:
-	//		A checkbox-like menu item for toggling on and off
 
 	return declare("dijit.CheckedMenuItem", MenuItem, {
 		// summary:
 		//		A checkbox-like menu item for toggling on and off
 
+		baseClass: "dijitCheckedMenuItem",
+
 		templateString: template,
 
 		// checked: Boolean
@@ -28,13 +24,19 @@ define([
 			// summary:
 			//		Hook so attr('checked', bool) works.
 			//		Sets the class and state for the check box.
-			domClass.toggle(this.domNode, "dijitCheckedMenuItemChecked", checked);
-			this.domNode.setAttribute("aria-checked", checked);
+			domClass.toggle(this.domNode, this.baseClass + "Checked", checked);
+			this.domNode.setAttribute("aria-checked", checked ? "true" : "false");
 			this._set("checked", checked);
 		},
 
 		iconClass: "",	// override dijitNoIcon
 
+		role: "menuitemcheckbox",
+
+		// checkedChar: String
+		//		Character (or string) used in place of checkbox icon when display in high contrast mode
+		checkedChar: "✓",
+
 		onChange: function(/*Boolean*/ /*===== checked =====*/){
 			// summary:
 			//		User defined function to handle check/uncheck events
@@ -42,7 +44,7 @@ define([
 			//		callback
 		},
 
-		_onClick: function(/*Event*/ e){
+		_onClick: function(evt){
 			// summary:
 			//		Clicking this item just toggles its state
 			// tags:
@@ -51,7 +53,7 @@ define([
 				this.set("checked", !this.checked);
 				this.onChange(this.checked);
 			}
-			this.inherited(arguments);
+			this.onClick(evt);
 		}
 	});
 });
diff --git a/dijit/ColorPalette.js b/dijit/ColorPalette.js
index ef41250..bae0681 100644
--- a/dijit/ColorPalette.js
+++ b/dijit/ColorPalette.js
@@ -1,158 +1,160 @@
 define([
-	"require",		// require.toUrl
+	"require", // require.toUrl
 	"dojo/text!./templates/ColorPalette.html",
-	"./_Widget",
+	"./_Widget", // used also to load dijit/hccss for setting has("highcontrast")
 	"./_TemplatedMixin",
 	"./_PaletteMixin",
+	"./hccss", // has("highcontrast")
 	"dojo/i18n", // i18n.getLocalization
 	"dojo/_base/Color", // dojo.Color dojo.Color.named
 	"dojo/_base/declare", // declare
-	"dojo/dom-class", // domClass.contains
 	"dojo/dom-construct", // domConstruct.place
-	"dojo/_base/window", // win.body
 	"dojo/string", // string.substitute
-	"dojo/i18n!dojo/nls/colors",	// translations
-	"dojo/colors"	// extend dojo.Color w/names of other colors
-], function(require, template, _Widget, _TemplatedMixin, _PaletteMixin, i18n, Color,
-	declare, domClass, domConstruct, win, string){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _PaletteMixin = dijit._PaletteMixin;
-=====*/
-
-// module:
-//		dijit/ColorPalette
-// summary:
-//		A keyboard accessible color-picking widget
-
-var ColorPalette = declare("dijit.ColorPalette", [_Widget, _TemplatedMixin, _PaletteMixin], {
-	// summary:
-	//		A keyboard accessible color-picking widget
-	// description:
-	//		Grid showing various colors, so the user can pick a certain color.
-	//		Can be used standalone, or as a popup.
-	//
-	// example:
-	// |	<div data-dojo-type="dijit.ColorPalette"></div>
-	//
-	// example:
-	// |	var picker = new dijit.ColorPalette({ },srcNode);
-	// |	picker.startup();
-
-
-	// palette: [const] String
-	//		Size of grid, either "7x10" or "3x4".
-	palette: "7x10",
-
-	// _palettes: [protected] Map
-	// 		This represents the value of the colors.
-	//		The first level is a hashmap of the different palettes available.
-	//		The next two dimensions represent the columns and rows of colors.
-	_palettes: {
-		"7x10":	[["white", "seashell", "cornsilk", "lemonchiffon","lightyellow", "palegreen", "paleturquoise", "lightcyan",	"lavender", "plum"],
-				["lightgray", "pink", "bisque", "moccasin", "khaki", "lightgreen", "lightseagreen", "lightskyblue", "cornflowerblue", "violet"],
-				["silver", "lightcoral", "sandybrown", "orange", "palegoldenrod", "chartreuse", "mediumturquoise", 	"skyblue", "mediumslateblue","orchid"],
-				["gray", "red", "orangered", "darkorange", "yellow", "limegreen", 	"darkseagreen", "royalblue", "slateblue", "mediumorchid"],
-				["dimgray", "crimson", 	"chocolate", "coral", "gold", "forestgreen", "seagreen", "blue", "blueviolet", "darkorchid"],
-				["darkslategray","firebrick","saddlebrown", "sienna", "olive", "green", "darkcyan", "mediumblue","darkslateblue", "darkmagenta" ],
-				["black", "darkred", "maroon", "brown", "darkolivegreen", "darkgreen", "midnightblue", "navy", "indigo", 	"purple"]],
-
-		"3x4": [["white", "lime", "green", "blue"],
-			["silver", "yellow", "fuchsia", "navy"],
-			["gray", "red", "purple", "black"]]
-	},
-
-	// templateString: String
-	//		The template of this widget.
-	templateString: template,
-
-	baseClass: "dijitColorPalette",
-
-	_dyeFactory: function(value, row, col){
-		// Overrides _PaletteMixin._dyeFactory().
-		return new this._dyeClass(value, row, col);
-	},
-
-	buildRendering: function(){
-		// Instantiate the template, which makes a skeleton into which we'll insert a bunch of
-		// <img> nodes
-		this.inherited(arguments);
-
-		//	Creates customized constructor for dye class (color of a single cell) for
-		//	specified palette and high-contrast vs. normal mode.   Used in _getDye().
-		this._dyeClass = declare(ColorPalette._Color, {
-			hc: domClass.contains(win.body(), "dijit_a11y"),
-			palette: this.palette
-		});
-
-		// Creates <img> nodes in each cell of the template.
-		this._preparePalette(
-			this._palettes[this.palette],
-			i18n.getLocalization("dojo", "colors", this.lang));
-	}
-});
-
-ColorPalette._Color = declare("dijit._Color", Color, {
-	// summary:
-	//		Object associated with each cell in a ColorPalette palette.
-	//		Implements dijit.Dye.
-
-	// Template for each cell in normal (non-high-contrast mode).  Each cell contains a wrapper
-	// node for showing the border (called dijitPaletteImg for back-compat), and dijitColorPaletteSwatch
-	// for showing the color.
-	template:
-		"<span class='dijitInline dijitPaletteImg'>" +
-			"<img src='${blankGif}' alt='${alt}' class='dijitColorPaletteSwatch' style='background-color: ${color}'/>" +
-		"</span>",
-
-	// Template for each cell in high contrast mode.  Each cell contains an image with the whole palette,
-	// but scrolled and clipped to show the correct color only
-	hcTemplate:
-		"<span class='dijitInline dijitPaletteImg' style='position: relative; overflow: hidden; height: 12px; width: 14px;'>" +
-			"<img src='${image}' alt='${alt}' style='position: absolute; left: ${left}px; top: ${top}px; ${size}'/>" +
-		"</span>",
-
-	// _imagePaths: [protected] Map
-	//		This is stores the path to the palette images used for high-contrast mode display
-	_imagePaths: {
-		"7x10": require.toUrl("./themes/a11y/colors7x10.png"),
-		"3x4": require.toUrl("./themes/a11y/colors3x4.png")
-	},
-
-	constructor: function(/*String*/alias, /*Number*/ row, /*Number*/ col){
-		this._alias = alias;
-		this._row = row;
-		this._col = col;
-		this.setColor(Color.named[alias]);
-	},
-
-	getValue: function(){
-		// summary:
-		//		Note that although dijit._Color is initialized with a value like "white" getValue() always
-		//		returns a hex value
-		return this.toHex();
-	},
-
-	fillCell: function(/*DOMNode*/ cell, /*String*/ blankGif){
-		var html = string.substitute(this.hc ? this.hcTemplate : this.template, {
-			// substitution variables for normal mode
-			color: this.toHex(),
-			blankGif: blankGif,
-			alt: this._alias,
-
-			// variables used for high contrast mode
-			image: this._imagePaths[this.palette].toString(),
-			left: this._col * -20 - 5,
-			top: this._row * -20 - 5,
-			size: this.palette == "7x10" ? "height: 145px; width: 206px" : "height: 64px; width: 86px"
-		});
-
-		domConstruct.place(html, cell);
-	}
-});
+	"dojo/i18n!dojo/nls/colors", // translations
+	"dojo/colors"    // extend dojo.Color w/names of other colors
+], function(require, template, _Widget, _TemplatedMixin, _PaletteMixin, has, i18n, Color,
+	declare, domConstruct, string){
 
+	// module:
+	//		dijit/ColorPalette
 
-return ColorPalette;
+	var ColorPalette = declare("dijit.ColorPalette", [_Widget, _TemplatedMixin, _PaletteMixin], {
+		// summary:
+		//		A keyboard accessible color-picking widget
+		// description:
+		//		Grid showing various colors, so the user can pick a certain color.
+		//		Can be used standalone, or as a popup.
+		//
+		// example:
+		// |	<div data-dojo-type="dijit/ColorPalette"></div>
+		//
+		// example:
+		// |	var picker = new dijit.ColorPalette({ },srcNode);
+		// |	picker.startup();
+
+
+		// palette: [const] String
+		//		Size of grid, either "7x10" or "3x4".
+		palette: "7x10",
+
+		// _palettes: [protected] Map
+		//		This represents the value of the colors.
+		//		The first level is a hashmap of the different palettes available.
+		//		The next two dimensions represent the columns and rows of colors.
+		_palettes: {
+			"7x10": [
+				["white", "seashell", "cornsilk", "lemonchiffon", "lightyellow", "palegreen", "paleturquoise", "lightcyan", "lavender", "plum"],
+				["lightgray", "pink", "bisque", "moccasin", "khaki", "lightgreen", "lightseagreen", "lightskyblue", "cornflowerblue", "violet"],
+				["silver", "lightcoral", "sandybrown", "orange", "palegoldenrod", "chartreuse", "mediumturquoise", "skyblue", "mediumslateblue", "orchid"],
+				["gray", "red", "orangered", "darkorange", "yellow", "limegreen", "darkseagreen", "royalblue", "slateblue", "mediumorchid"],
+				["dimgray", "crimson", "chocolate", "coral", "gold", "forestgreen", "seagreen", "blue", "blueviolet", "darkorchid"],
+				["darkslategray", "firebrick", "saddlebrown", "sienna", "olive", "green", "darkcyan", "mediumblue", "darkslateblue", "darkmagenta" ],
+				["black", "darkred", "maroon", "brown", "darkolivegreen", "darkgreen", "midnightblue", "navy", "indigo", "purple"]
+			],
+
+			"3x4": [
+				["white", "lime", "green", "blue"],
+				["silver", "yellow", "fuchsia", "navy"],
+				["gray", "red", "purple", "black"]
+			]
+		},
+
+		// templateString: String
+		//		The template of this widget.
+		templateString: template,
+
+		baseClass: "dijitColorPalette",
+
+		_dyeFactory: function(value, row, col, title){
+			// Overrides _PaletteMixin._dyeFactory().
+			return new this._dyeClass(value, row, col, title);
+		},
+
+		buildRendering: function(){
+			// Instantiate the template, which makes a skeleton into which we'll insert a bunch of
+			// <img> nodes
+			this.inherited(arguments);
+
+			//	Creates customized constructor for dye class (color of a single cell) for
+			//	specified palette and high-contrast vs. normal mode.   Used in _getDye().
+			this._dyeClass = declare(ColorPalette._Color, {
+				palette: this.palette
+			});
+
+			// Creates <img> nodes in each cell of the template.
+			this._preparePalette(
+				this._palettes[this.palette],
+				i18n.getLocalization("dojo", "colors", this.lang));
+		}
+	});
+
+	ColorPalette._Color = declare("dijit._Color", Color, {
+		// summary:
+		//		Object associated with each cell in a ColorPalette palette.
+		//		Implements dijit/Dye.
+
+		// Template for each cell in normal (non-high-contrast mode).  Each cell contains a wrapper
+		// node for showing the border (called dijitPaletteImg for back-compat), and dijitColorPaletteSwatch
+		// for showing the color.
+		template: "<span class='dijitInline dijitPaletteImg'>" +
+			"<img src='${blankGif}' alt='${alt}' title='${title}' class='dijitColorPaletteSwatch' style='background-color: ${color}'/>" +
+			"</span>",
+
+		// Template for each cell in high contrast mode.  Each cell contains an image with the whole palette,
+		// but scrolled and clipped to show the correct color only
+		hcTemplate: "<span class='dijitInline dijitPaletteImg' style='position: relative; overflow: hidden; height: 12px; width: 14px;'>" +
+			"<img src='${image}' alt='${alt}' title='${title}' style='position: absolute; left: ${left}px; top: ${top}px; ${size}'/>" +
+			"</span>",
+
+		// _imagePaths: [protected] Map
+		//		This is stores the path to the palette images used for high-contrast mode display
+		_imagePaths: {
+			"7x10": require.toUrl("./themes/a11y/colors7x10.png"),
+			"3x4": require.toUrl("./themes/a11y/colors3x4.png")
+		},
+
+		constructor: function(alias, row, col, title){
+			// summary:
+			//		Constructor for ColorPalette._Color
+			// alias: String
+			//		English name of the color.
+			// row: Number
+			//		Vertical position in grid.
+			// column: Number
+			//		Horizontal position in grid.
+			// title: String
+			//		Localized name of the color.
+			this._title = title;
+			this._row = row;
+			this._col = col;
+			this.setColor(Color.named[alias]);
+		},
+
+		getValue: function(){
+			// summary:
+			//		Note that although dijit._Color is initialized with a value like "white" getValue() always
+			//		returns a hex value
+			return this.toHex();
+		},
+
+		fillCell: function(/*DOMNode*/ cell, /*String*/ blankGif){
+			var html = string.substitute(has("highcontrast") ? this.hcTemplate : this.template, {
+				// substitution variables for normal mode
+				color: this.toHex(),
+				blankGif: blankGif,
+				alt: this._title,
+				title: this._title,
+
+				// variables used for high contrast mode
+				image: this._imagePaths[this.palette].toString(),
+				left: this._col * -20 - 5,
+				top: this._row * -20 - 5,
+				size: this.palette == "7x10" ? "height: 145px; width: 206px" : "height: 64px; width: 86px"
+			});
+
+			domConstruct.place(html, cell);
+		}
+	});
+
+	return ColorPalette;
 });
diff --git a/dijit/Declaration.js b/dijit/Declaration.js
index e885277..3c86148 100644
--- a/dijit/Declaration.js
+++ b/dijit/Declaration.js
@@ -1,6 +1,6 @@
 define([
 	"dojo/_base/array", // array.forEach array.map
-	"dojo/_base/connect", // connect.connect
+	"dojo/aspect",	// aspect.after
 	"dojo/_base/declare", // declare
 	"dojo/_base/lang", // lang.getObject
 	"dojo/parser", // parser._functionFromScript
@@ -9,19 +9,10 @@ define([
 	"./_TemplatedMixin",
 	"./_WidgetsInTemplateMixin",
 	"dojo/NodeList-dom"
-], function(array, connect, declare, lang, parser, query, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
-=====*/
+], function(array, aspect, declare, lang, parser, query, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin){
 
 	// module:
 	//		dijit/Declaration
-	// summary:
-	//		The Declaration widget allows a developer to declare new widget
-	//		classes directly from a snippet of markup.
 
 	return declare("dijit.Declaration", _Widget, {
 		// summary:
@@ -52,8 +43,9 @@ define([
 
 		buildRendering: function(){
 			var src = this.srcNodeRef.parentNode.removeChild(this.srcNodeRef),
-				methods = query("> script[type^='dojo/method']", src).orphan(),
-				connects = query("> script[type^='dojo/connect']", src).orphan(),
+				methods = query("> script[type='dojo/method']", src).orphan(),
+				connects = query("> script[type='dojo/connect']", src).orphan(), // remove for 2.0
+				aspects = query("> script[type='dojo/aspect']", src).orphan(),
 				srcType = src.nodeName;
 
 			var propList = this.defaults || {};
@@ -63,21 +55,23 @@ define([
 			// If there's no "event" specified then it's code to run on instantiation,
 			// so it becomes a connection to "postscript" (handled below).
 			array.forEach(methods, function(s){
-				var evt = s.getAttribute("event") || s.getAttribute("data-dojo-event"),
-					func = parser._functionFromScript(s);
+				var evt = s.getAttribute("event") || s.getAttribute("data-dojo-event"), // remove "event" for 2.0
+					func = parser._functionFromScript(s, "data-dojo-");
 				if(evt){
 					propList[evt] = func;
 				}else{
-					connects.push(s);
+					aspects.push(s);
 				}
 			});
 
 			// map array of strings like [ "dijit.form.Button" ] to array of mixin objects
 			// (note that array.map(this.mixins, lang.getObject) doesn't work because it passes
 			// a bogus third argument to getObject(), confusing it)
-			this.mixins = this.mixins.length ?
-				array.map(this.mixins, function(name){ return lang.getObject(name); } ) :
-				[ _Widget, _TemplatedMixin, _WidgetsInTemplateMixin ];
+			if(this.mixins.length){
+				this.mixins = array.map(this.mixins, function(name){ return lang.getObject(name); } );
+			}else{
+				this.mixins = [ _Widget, _TemplatedMixin, _WidgetsInTemplateMixin ];
+			}
 
 			propList._skipNodeCache = true;
 			propList.templateString =
@@ -96,16 +90,25 @@ define([
 			);
 
 			// Handle <script> blocks of form:
-			//		<script type="dojo/connect" data-dojo-event="foo">
+			//		<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="foo">
 			// and
 			//		<script type="dojo/method">
-			// (Note that the second one is just shorthand for a dojo/connect to postscript)
+			// (Note that the second one is just shorthand for a dojo/aspect to postscript)
 			// Since this is a connect in the declaration, we are actually connection to the method
 			// in the _prototype_.
+			array.forEach(aspects, function(s){
+				var advice = s.getAttribute("data-dojo-advice") || "after",
+					method = s.getAttribute("data-dojo-method") || "postscript",
+					func = parser._functionFromScript(s);
+				aspect.after(wc.prototype, method, func, true);
+			});
+
+			// Handle legacy <script type="dojo/connect" data-dojo-event="foo">.
+			// Remove for 2.0.
 			array.forEach(connects, function(s){
-				var evt = s.getAttribute("event") || s.getAttribute("data-dojo-event") || "postscript",
+				var evt = s.getAttribute("event") || s.getAttribute("data-dojo-event"),
 					func = parser._functionFromScript(s);
-				connect.connect(wc.prototype, evt, func);
+				aspect.after(wc.prototype, evt, func, true);
 			});
 		}
 	});
diff --git a/dijit/Destroyable.js b/dijit/Destroyable.js
new file mode 100644
index 0000000..6256f87
--- /dev/null
+++ b/dijit/Destroyable.js
@@ -0,0 +1,58 @@
+define([
+	"dojo/_base/array", // array.forEach array.map
+	"dojo/aspect",
+	"dojo/_base/declare"
+], function(array, aspect, declare){
+
+	// module:
+	//		dijit/Destroyable
+
+	return declare("dijit.Destroyable", null, {
+		// summary:
+		//		Mixin to track handles and release them when instance is destroyed.
+		// description:
+		//		Call this.own(...) on list of handles (returned from dojo/aspect, dojo/on,
+		//		dojo/Stateful::watch, or any class (including widgets) with a destroyRecursive() or destroy() method.
+		//		Then call destroy() later to destroy this instance and release the resources.
+
+		destroy: function(/*Boolean*/ preserveDom){
+			// summary:
+			//		Destroy this class, releasing any resources registered via own().
+			this._destroyed = true;
+		},
+
+		own: function(){
+			// summary:
+			//		Track specified handles and remove/destroy them when this instance is destroyed, unless they were
+			//		already removed/destroyed manually.
+			// tags:
+			//		protected
+			// returns:
+			//		The array of specified handles, so you can do for example:
+			//	|		var handle = this.own(on(...))[0];
+
+			array.forEach(arguments, function(handle){
+				var destroyMethodName =
+					"destroyRecursive" in handle ? "destroyRecursive" : // remove "destroyRecursive" for 2.0
+						"destroy" in handle ? "destroy" :
+							"remove";
+
+				// When this.destroy() is called, destroy handle.  Since I'm using aspect.before(),
+				// the handle will be destroyed before a subclass's destroy() method starts running, before it calls
+				// this.inherited() or even if it doesn't call this.inherited() at all.  If that's an issue, make an
+				// onDestroy() method and connect to that instead.
+				var odh = aspect.before(this, "destroy", function(preserveDom){
+					handle[destroyMethodName](preserveDom);
+				});
+
+				// If handle is destroyed manually before this.destroy() is called, remove the listener set directly above.
+				var hdh = aspect.after(handle, destroyMethodName, function(){
+					odh.remove();
+					hdh.remove();
+				}, true);
+			}, this);
+
+			return arguments;		// handle
+		}
+	});
+});
diff --git a/dijit/Dialog.js b/dijit/Dialog.js
index 387ee2d..efa0949 100644
--- a/dijit/Dialog.js
+++ b/dijit/Dialog.js
@@ -1,28 +1,25 @@
 define([
 	"require",
 	"dojo/_base/array", // array.forEach array.indexOf array.map
-	"dojo/_base/connect", // connect._keypress
+	"dojo/aspect",
 	"dojo/_base/declare", // declare
-	"dojo/_base/Deferred", // Deferred
+	"dojo/Deferred", // Deferred
 	"dojo/dom", // dom.isDescendant
 	"dojo/dom-class", // domClass.add domClass.contains
 	"dojo/dom-geometry", // domGeometry.position
 	"dojo/dom-style", // domStyle.set
-	"dojo/_base/event", // event.stop
 	"dojo/_base/fx", // fx.fadeIn fx.fadeOut
 	"dojo/i18n", // i18n.getLocalization
-	"dojo/_base/kernel", // kernel.isAsync
 	"dojo/keys",
 	"dojo/_base/lang", // lang.mixin lang.hitch
 	"dojo/on",
 	"dojo/ready",
-	"dojo/_base/sniff", // has("ie") has("opera")
-	"dojo/_base/window", // win.body
-	"dojo/window", // winUtils.getBox
+	"dojo/sniff", // has("ie") has("opera") has("dijit-legacy-requires")
+	"dojo/window", // winUtils.getBox, winUtils.get
 	"dojo/dnd/Moveable", // Moveable
 	"dojo/dnd/TimedMoveable", // TimedMoveable
 	"./focus",
-	"./_base/manager",	// manager.defaultDuration
+	"./_base/manager", // manager.defaultDuration
 	"./_Widget",
 	"./_TemplatedMixin",
 	"./_CssStateMixin",
@@ -31,27 +28,14 @@ define([
 	"./DialogUnderlay",
 	"./layout/ContentPane",
 	"dojo/text!./templates/Dialog.html",
-	".",			// for back-compat, exporting dijit._underlay (remove in 2.0)
 	"dojo/i18n!./nls/common"
-], function(require, array, connect, declare, Deferred,
-			dom, domClass, domGeometry, domStyle, event, fx, i18n, kernel, keys, lang, on, ready, has, win, winUtils,
+], function(require, array, aspect, declare, Deferred,
+			dom, domClass, domGeometry, domStyle, fx, i18n, keys, lang, on, ready, has, winUtils,
 			Moveable, TimedMoveable, focus, manager, _Widget, _TemplatedMixin, _CssStateMixin, _FormMixin, _DialogMixin,
-			DialogUnderlay, ContentPane, template, dijit){
-	
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _CssStateMixin = dijit._CssStateMixin;
-	var _FormMixin = dijit.form._FormMixin;
-	var _DialogMixin = dijit._DialogMixin;
-=====*/	
-
+			DialogUnderlay, ContentPane, template){
 
 	// module:
 	//		dijit/Dialog
-	// summary:
-	//		A modal dialog Widget
-
 
 	/*=====
 	dijit._underlay = function(kwArgs){
@@ -65,23 +49,7 @@ define([
 	};
 	=====*/
 
-	var _DialogBase = declare("dijit._DialogBase", [_TemplatedMixin, _FormMixin, _DialogMixin, _CssStateMixin], {
-		// summary:
-		//		A modal dialog Widget
-		//
-		// description:
-		//		Pops up a modal dialog window, blocking access to the screen
-		//		and also graying out the screen Dialog is extended from
-		//		ContentPane so it supports all the same parameters (href, etc.)
-		//
-		// example:
-		// |	<div data-dojo-type="dijit.Dialog" data-dojo-props="href: 'test.html'"></div>
-		//
-		// example:
-		// |	var foo = new dijit.Dialog({ title: "test dialog", content: "test content" };
-		// |	dojo.body().appendChild(foo.domNode);
-		// |	foo.startup();
-
+	var _DialogBase = declare("dijit._DialogBase" + (has("dojo-bidi") ? "_NoBidi" : ""), [_TemplatedMixin, _FormMixin, _DialogMixin, _CssStateMixin], {
 		templateString: template,
 
 		baseClass: "dijitDialog",
@@ -91,10 +59,7 @@ define([
 		},
 
 		// Map widget attributes to DOMNode attributes.
-		_setTitleAttr: [
-			{ node: "titleNode", type: "innerHTML" },
-			{ node: "titleBar", type: "attribute" }
-		],
+		_setTitleAttr: { node: "titleNode", type: "innerHTML" },
 
 		// open: [readonly] Boolean
 		//		True if Dialog is currently displayed on screen.
@@ -105,25 +70,25 @@ define([
 		duration: manager.defaultDuration,
 
 		// refocus: Boolean
-		// 		A Toggle to modify the default focus behavior of a Dialog, which
-		// 		is to re-focus the element which had focus before being opened.
+		//		A Toggle to modify the default focus behavior of a Dialog, which
+		//		is to re-focus the element which had focus before being opened.
 		//		False will disable refocusing. Default: true
 		refocus: true,
 
 		// autofocus: Boolean
-		// 		A Toggle to modify the default focus behavior of a Dialog, which
-		// 		is to focus on the first dialog element after opening the dialog.
+		//		A Toggle to modify the default focus behavior of a Dialog, which
+		//		is to focus on the first dialog element after opening the dialog.
 		//		False will disable autofocusing. Default: true
 		autofocus: true,
 
 		// _firstFocusItem: [private readonly] DomNode
 		//		The pointer to the first focusable node in the dialog.
-		//		Set by `dijit._DialogMixin._getFocusItems`.
+		//		Set by `dijit/_DialogMixin._getFocusItems()`.
 		_firstFocusItem: null,
 
 		// _lastFocusItem: [private readonly] DomNode
 		//		The pointer to which node has focus prior to our dialog.
-		//		Set by `dijit._DialogMixin._getFocusItems`.
+		//		Set by `dijit/_DialogMixin._getFocusItems()`.
 		_lastFocusItem: null,
 
 		// doLayout: [protected] Boolean
@@ -134,20 +99,27 @@ define([
 		doLayout: false,
 
 		// draggable: Boolean
-		//		Toggles the moveable aspect of the Dialog. If true, Dialog
+		//		Toggles the movable aspect of the Dialog. If true, Dialog
 		//		can be dragged by it's title. If false it will remain centered
 		//		in the viewport.
 		draggable: true,
+		_setDraggableAttr: function(/*Boolean*/ val){
+			// Avoid _WidgetBase behavior of copying draggable attribute to this.domNode,
+			// as that prevents text select on modern browsers (#14452)
+			this._set("draggable", val);
+		},
 
-		//aria-describedby: String
-		//		Allows the user to add an aria-describedby attribute onto the dialog.   The value should
-		//		be the id of the container element of text that describes the dialog purpose (usually
-		//		the first text in the dialog).
-		//		<div data-dojo-type="dijit.Dialog" aria-describedby="intro" .....>
-		//			<div id="intro">Introductory text</div>
-		//			<div>rest of dialog contents</div>
-		//		</div>
-		"aria-describedby":"",
+		// maxRatio: Number
+		//		Maximum size to allow the dialog to expand to, relative to viewport size
+		maxRatio: 0.9,
+
+		// closable: Boolean
+		//		Dialog show [x] icon to close itself, and ESC key will close the dialog.
+		closable: true,
+		_setClosableAttr: function(val){
+			this.closeButtonNode.style.display = val ? "" : "none";
+			this._set("closable", val);
+		},
 
 		postMixInProperties: function(){
 			var _nlsResources = i18n.getLocalization("dijit", "common");
@@ -158,14 +130,15 @@ define([
 		postCreate: function(){
 			domStyle.set(this.domNode, {
 				display: "none",
-				position:"absolute"
+				position: "absolute"
 			});
-			win.body().appendChild(this.domNode);
+			this.ownerDocumentBody.appendChild(this.domNode);
 
 			this.inherited(arguments);
 
-			this.connect(this, "onExecute", "hide");
-			this.connect(this, "onCancel", "hide");
+			aspect.after(this, "onExecute", lang.hitch(this, "hide"), true);
+			aspect.after(this, "onCancel", lang.hitch(this, "hide"), true);
+
 			this._modalconnects = [];
 		},
 
@@ -179,20 +152,28 @@ define([
 
 			// when href is specified we need to reposition the dialog after the data is loaded
 			// and find the focusable elements
+			this._size();
 			this._position();
+
 			if(this.autofocus && DialogLevelManager.isTop(this)){
 				this._getFocusItems(this.domNode);
 				focus.focus(this._firstFocusItem);
 			}
+
 			this.inherited(arguments);
 		},
 
+		focus: function(){
+			this._getFocusItems(this.domNode);
+			focus.focus(this._firstFocusItem);
+		},
+
 		_endDrag: function(){
 			// summary:
 			//		Called after dragging the Dialog. Saves the position of the dialog in the viewport,
 			//		and also adjust position to be fully within the viewport, so user doesn't lose access to handle
 			var nodePosition = domGeometry.position(this.domNode),
-				viewport = winUtils.getBox();
+				viewport = winUtils.getBox(this.ownerDocument);
 			nodePosition.y = Math.min(Math.max(nodePosition.y, 0), (viewport.h - nodePosition.h));
 			nodePosition.x = Math.min(Math.max(nodePosition.x, 0), (viewport.w - nodePosition.w));
 			this._relativePosition = nodePosition;
@@ -212,20 +193,24 @@ define([
 			if(this.titleBar && this.draggable){
 				this._moveable = new ((has("ie") == 6) ? TimedMoveable // prevent overload, see #5285
 					: Moveable)(node, { handle: this.titleBar });
-				this.connect(this._moveable, "onMoveStop", "_endDrag");
+				aspect.after(this._moveable, "onMoveStop", lang.hitch(this, "_endDrag"), true);
 			}else{
-				domClass.add(node,"dijitDialogFixed");
+				domClass.add(node, "dijitDialogFixed");
 			}
 
 			this.underlayAttrs = {
 				dialogId: this.id,
-				"class": array.map(this["class"].split(/\s/), function(s){ return s+"_underlay"; }).join(" ")
+				"class": array.map(this["class"].split(/\s/),function(s){
+					return s + "_underlay";
+				}).join(" "),
+				_onKeyDown: lang.hitch(this, "_onKey"),
+				ownerDocument: this.ownerDocument
 			};
 		},
 
 		_size: function(){
 			// summary:
-			// 		If necessary, shrink dialog contents so dialog fits in viewport
+			//		If necessary, shrink dialog contents so dialog fits in viewport.
 			// tags:
 			//		private
 
@@ -235,34 +220,43 @@ define([
 			// that if the user later increases the viewport size, the dialog can display w/out a scrollbar.
 			// Need to do this before the domGeometry.position(this.domNode) call below.
 			if(this._singleChild){
-				if(this._singleChildOriginalStyle){
+				if(typeof this._singleChildOriginalStyle != "undefined"){
 					this._singleChild.domNode.style.cssText = this._singleChildOriginalStyle;
+					delete this._singleChildOriginalStyle;
 				}
-				delete this._singleChildOriginalStyle;
 			}else{
 				domStyle.set(this.containerNode, {
-					width:"auto",
-					height:"auto"
+					width: "auto",
+					height: "auto"
 				});
 			}
 
 			var bb = domGeometry.position(this.domNode);
-			var viewport = winUtils.getBox();
+
+			// Get viewport size but then reduce it by a bit; Dialog should always have some space around it
+			// to indicate that it's a popup.  This will also compensate for possible scrollbars on viewport.
+			var viewport = winUtils.getBox(this.ownerDocument);
+			viewport.w *= this.maxRatio;
+			viewport.h *= this.maxRatio;
+
 			if(bb.w >= viewport.w || bb.h >= viewport.h){
 				// Reduce size of dialog contents so that dialog fits in viewport
 
-				var w = Math.min(bb.w, Math.floor(viewport.w * 0.75)),
-					h = Math.min(bb.h, Math.floor(viewport.h * 0.75));
+				var containerSize = domGeometry.position(this.containerNode),
+					w = Math.min(bb.w, viewport.w) - (bb.w - containerSize.w),
+					h = Math.min(bb.h, viewport.h) - (bb.h - containerSize.h);
 
 				if(this._singleChild && this._singleChild.resize){
-					this._singleChildOriginalStyle = this._singleChild.domNode.style.cssText;
+					if(typeof this._singleChildOriginalStyle == "undefined"){
+						this._singleChildOriginalStyle = this._singleChild.domNode.style.cssText;
+					}
 					this._singleChild.resize({w: w, h: h});
 				}else{
 					domStyle.set(this.containerNode, {
 						width: w + "px",
 						height: h + "px",
 						overflow: "auto",
-						position: "relative"	// workaround IE bug moving scrollbar or dragging dialog
+						position: "relative"    // workaround IE bug moving scrollbar or dragging dialog
 					});
 				}
 			}else{
@@ -274,19 +268,19 @@ define([
 
 		_position: function(){
 			// summary:
-			//		Position modal dialog in the viewport. If no relative offset
+			//		Position the dialog in the viewport.  If no relative offset
 			//		in the viewport has been determined (by dragging, for instance),
-			//		center the node. Otherwise, use the Dialog's stored relative offset,
-			//		and position the node to top: left: values based on the viewport.
-			if(!domClass.contains(win.body(), "dojoMove")){	// don't do anything if called during auto-scroll
+			//		center the dialog.  Otherwise, use the Dialog's stored relative offset,
+			//		adjusted by the viewport's scroll.
+			if(!domClass.contains(this.ownerDocumentBody, "dojoMove")){    // don't do anything if called during auto-scroll
 				var node = this.domNode,
-					viewport = winUtils.getBox(),
+					viewport = winUtils.getBox(this.ownerDocument),
 					p = this._relativePosition,
 					bb = p ? null : domGeometry.position(node),
 					l = Math.floor(viewport.l + (p ? p.x : (viewport.w - bb.w) / 2)),
 					t = Math.floor(viewport.t + (p ? p.y : (viewport.h - bb.h) / 2))
-				;
-				domStyle.set(node,{
+					;
+				domStyle.set(node, {
 					left: l + "px",
 					top: t + "px"
 				});
@@ -299,55 +293,40 @@ define([
 			// tags:
 			//		private
 
-			if(evt.charOrCode){
+			if(evt.keyCode == keys.TAB){
+				this._getFocusItems(this.domNode);
 				var node = evt.target;
-				if(evt.charOrCode === keys.TAB){
-					this._getFocusItems(this.domNode);
-				}
-				var singleFocusItem = (this._firstFocusItem == this._lastFocusItem);
-				// see if we are shift-tabbing from first focusable item on dialog
-				if(node == this._firstFocusItem && evt.shiftKey && evt.charOrCode === keys.TAB){
-					if(!singleFocusItem){
-						focus.focus(this._lastFocusItem); // send focus to last item in dialog
-					}
-					event.stop(evt);
-				}else if(node == this._lastFocusItem && evt.charOrCode === keys.TAB && !evt.shiftKey){
-					if(!singleFocusItem){
-						focus.focus(this._firstFocusItem); // send focus to first item in dialog
-					}
-					event.stop(evt);
-				}else{
-					// see if the key is for the dialog
-					while(node){
-						if(node == this.domNode || domClass.contains(node, "dijitPopup")){
-							if(evt.charOrCode == keys.ESCAPE){
-								this.onCancel();
-							}else{
-								return; // just let it go
-							}
-						}
-						node = node.parentNode;
-					}
-					// this key is for the disabled document window
-					if(evt.charOrCode !== keys.TAB){ // allow tabbing into the dialog for a11y
-						event.stop(evt);
-					// opera won't tab to a div
-					}else if(!has("opera")){
-						try{
-							this._firstFocusItem.focus();
-						}catch(e){ /*squelch*/ }
-					}
+				if(this._firstFocusItem == this._lastFocusItem){
+					// don't move focus anywhere, but don't allow browser to move focus off of dialog either
+					evt.stopPropagation();
+					evt.preventDefault();
+				}else if(node == this._firstFocusItem && evt.shiftKey){
+					// if we are shift-tabbing from first focusable item in dialog, send focus to last item
+					focus.focus(this._lastFocusItem);
+					evt.stopPropagation();
+					evt.preventDefault();
+				}else if(node == this._lastFocusItem && !evt.shiftKey){
+					// if we are tabbing from last focusable item in dialog, send focus to first item
+					focus.focus(this._firstFocusItem);
+					evt.stopPropagation();
+					evt.preventDefault();
 				}
+			}else if(this.closable && evt.keyCode == keys.ESCAPE){
+				this.onCancel();
+				evt.stopPropagation();
+				evt.preventDefault();
 			}
 		},
 
 		show: function(){
 			// summary:
 			//		Display the dialog
-			// returns: dojo.Deferred
-			//		Deferred object that resolves when the display animation is complete
+			// returns: dojo/promise/Promise
+			//		Promise object that resolves when the display animation is complete
 
-			if(this.open){ return; }
+			if(this.open){
+				return;
+			}
 
 			if(!this._started){
 				this.startup();
@@ -356,30 +335,25 @@ define([
 			// first time we show the dialog, there's some initialization stuff to do
 			if(!this._alreadyInitialized){
 				this._setup();
-				this._alreadyInitialized=true;
+				this._alreadyInitialized = true;
 			}
 
 			if(this._fadeOutDeferred){
+				// There's a hide() operation in progress, so cancel it, but still call DialogLevelManager.hide()
+				// as though the hide() completed, in preparation for the DialogLevelManager.show() call below.
 				this._fadeOutDeferred.cancel();
+				DialogLevelManager.hide(this);
 			}
 
-			this._modalconnects.push(on(window, "scroll", lang.hitch(this, "layout")));
-			this._modalconnects.push(on(window, "resize", lang.hitch(this, function(){
-				// IE gives spurious resize events and can actually get stuck
-				// in an infinite loop if we don't ignore them
-				var viewport = winUtils.getBox();
-				if(!this._oldViewport ||
-						viewport.h != this._oldViewport.h ||
-						viewport.w != this._oldViewport.w){
-					this.layout();
-					this._oldViewport = viewport;
-				}
-			})));
-			this._modalconnects.push(on(this.domNode, connect._keypress, lang.hitch(this, "_onKey")));
+			// Recenter Dialog if user scrolls browser.  Connecting to document doesn't work on IE, need to use window.
+			var win = winUtils.get(this.ownerDocument);
+			this._modalconnects.push(on(win, "scroll", lang.hitch(this, "resize")));
+
+			this._modalconnects.push(on(this.domNode, "keydown", lang.hitch(this, "_onKey")));
 
 			domStyle.set(this.domNode, {
-				opacity:0,
-				display:""
+				opacity: 0,
+				display: ""
 			});
 
 			this._set("open", true);
@@ -396,6 +370,9 @@ define([
 				delete this._fadeInDeferred;
 			}));
 
+			// If delay is 0, code below will delete this._fadeInDeferred instantly, so grab promise while we can.
+			var promise = this._fadeInDeferred.promise;
+
 			fadeIn = fx.fadeIn({
 				node: this.domNode,
 				duration: this.duration,
@@ -409,22 +386,23 @@ define([
 						this._getFocusItems(this.domNode);
 						focus.focus(this._firstFocusItem);
 					}
-					this._fadeInDeferred.callback(true);
+					this._fadeInDeferred.resolve(true);
 					delete this._fadeInDeferred;
 				})
 			}).play();
 
-			return this._fadeInDeferred;
+			return promise;
 		},
 
 		hide: function(){
 			// summary:
 			//		Hide the dialog
-			// returns: dojo.Deferred
-			//		Deferred object that resolves when the hide animation is complete
+			// returns: dojo/promise/Promise
+			//		Promise object that resolves when the display animation is complete
 
-			// if we haven't been initialized yet then we aren't showing and we can just return
-			if(!this._alreadyInitialized){
+			// If we haven't been initialized yet then we aren't showing and we can just return.
+			// Likewise if we are already hidden, or are currently fading out.
+			if(!this._alreadyInitialized || !this.open){
 				return;
 			}
 			if(this._fadeInDeferred){
@@ -438,19 +416,23 @@ define([
 				fadeOut.stop();
 				delete this._fadeOutDeferred;
 			}));
+
 			// fire onHide when the promise resolves.
 			this._fadeOutDeferred.then(lang.hitch(this, 'onHide'));
 
+			// If delay is 0, code below will delete this._fadeOutDeferred instantly, so grab promise while we can.
+			var promise = this._fadeOutDeferred.promise;
+
 			fadeOut = fx.fadeOut({
 				node: this.domNode,
 				duration: this.duration,
 				onEnd: lang.hitch(this, function(){
 					this.domNode.style.display = "none";
 					DialogLevelManager.hide(this);
-					this._fadeOutDeferred.callback(true);
+					this._fadeOutDeferred.resolve(true);
 					delete this._fadeOutDeferred;
 				})
-			 }).play();
+			}).play();
 
 			if(this._scrollConnected){
 				this._scrollConnected = false;
@@ -465,19 +447,22 @@ define([
 			}
 			this._set("open", false);
 
-			return this._fadeOutDeferred;
+			return promise;
 		},
 
-		layout: function(){
+		resize: function(){
 			// summary:
-			//		Position the Dialog and the underlay
+			//		Called when viewport scrolled or size changed.  Adjust Dialog as necessary to keep it visible.
 			// tags:
 			//		private
 			if(this.domNode.style.display != "none"){
-				if(dijit._underlay){	// avoid race condition during show()
-					dijit._underlay.layout();
+				this._size();
+				if(!has("touch")){
+					// If the user has scrolled the display then reposition the Dialog.  But don't do it for touch
+					// devices, because it will counteract when a keyboard pops up and then the browser auto-scrolls
+					// the focused node into view.
+					this._position();
 				}
-				this._position();
 			}
 		},
 
@@ -502,8 +487,38 @@ define([
 		}
 	});
 
-	var Dialog = declare("dijit.Dialog", [ContentPane, _DialogBase], {});
-	Dialog._DialogBase = _DialogBase;	// for monkey patching
+	if(has("dojo-bidi")){
+		_DialogBase = declare("dijit._DialogBase", _DialogBase, {
+			_setTitleAttr: function(/*String*/ title){
+				this._set("title", title);
+				this.titleNode.innerHTML = title;
+				this.applyTextDir(this.titleNode);
+			},
+
+			_setTextDirAttr: function(textDir){
+				if(this._created && this.textDir != textDir){
+					this._set("textDir", textDir);
+					this.set("title", this.title);
+				}
+			}
+		});
+	}
+
+	var Dialog = declare("dijit.Dialog", [ContentPane, _DialogBase], {
+		// summary:
+		//		A modal dialog Widget.
+		// description:
+		//		Pops up a modal dialog window, blocking access to the screen
+		//		and also graying out the screen Dialog is extended from
+		//		ContentPane so it supports all the same parameters (href, etc.).
+		// example:
+		// |	<div data-dojo-type="dijit/Dialog" data-dojo-props="href: 'test.html'"></div>
+		// example:
+		// |	var foo = new Dialog({ title: "test dialog", content: "test content" });
+		// |	foo.placeAt(win.body());
+		// |	foo.startup();
+	});
+	Dialog._DialogBase = _DialogBase;	// for monkey patching and dojox/widget/DialogSimple
 
 	var DialogLevelManager = Dialog._DialogLevelManager = {
 		// summary:
@@ -513,7 +528,7 @@ define([
 
 		_beginZIndex: 950,
 
-		show: function(/*dijit._Widget*/ dialog, /*Object*/ underlayAttrs){
+		show: function(/*dijit/_WidgetBase*/ dialog, /*Object*/ underlayAttrs){
 			// summary:
 			//		Call right before fade-in animation for new dialog.
 			//		Saves current focus, displays/adjusts underlay for new dialog,
@@ -525,61 +540,48 @@ define([
 			//		animation completes.
 
 			// Save current focus
-			ds[ds.length-1].focus = focus.curNode;
-
-			// Display the underlay, or if already displayed then adjust for this new dialog
-			var underlay = dijit._underlay;
-			if(!underlay || underlay._destroyed){
-				underlay = dijit._underlay = new DialogUnderlay(underlayAttrs);
-			}else{
-				underlay.set(dialog.underlayAttrs);
-			}
+			ds[ds.length - 1].focus = focus.curNode;
 
 			// Set z-index a bit above previous dialog
-			var zIndex = ds[ds.length-1].dialog ? ds[ds.length-1].zIndex + 2 : Dialog._DialogLevelManager._beginZIndex;
-			if(ds.length == 1){	// first dialog
-				underlay.show();
-			}
-			domStyle.set(dijit._underlay.domNode, 'zIndex', zIndex - 1);
-
-			// Dialog
+			var zIndex = ds[ds.length - 1].dialog ? ds[ds.length - 1].zIndex + 2 : Dialog._DialogLevelManager._beginZIndex;
 			domStyle.set(dialog.domNode, 'zIndex', zIndex);
 
+			// Display the underlay, or if already displayed then adjust for this new dialog
+			DialogUnderlay.show(underlayAttrs, zIndex - 1);
+
 			ds.push({dialog: dialog, underlayAttrs: underlayAttrs, zIndex: zIndex});
 		},
 
-		hide: function(/*dijit._Widget*/ dialog){
+		hide: function(/*dijit/_WidgetBase*/ dialog){
 			// summary:
 			//		Called when the specified dialog is hidden/destroyed, after the fade-out
 			//		animation ends, in order to reset page focus, fix the underlay, etc.
 			//		If the specified dialog isn't open then does nothing.
 			//
 			//		Caller is responsible for either setting display:none on the dialog domNode,
-			//		or calling dijit.popup.hide(), or removing it from the page DOM.
+			//		or calling dijit/popup.hide(), or removing it from the page DOM.
 
-			if(ds[ds.length-1].dialog == dialog){
+			if(ds[ds.length - 1].dialog == dialog){
 				// Removing the top (or only) dialog in the stack, return focus
 				// to previous dialog
 
 				ds.pop();
 
-				var pd = ds[ds.length-1];	// the new active dialog (or the base page itself)
+				var pd = ds[ds.length - 1];	// the new active dialog (or the base page itself)
 
 				// Adjust underlay
 				if(ds.length == 1){
-					// Returning to original page.
-					// Hide the underlay, unless the underlay widget has already been destroyed
-					// because we are being called during page unload (when all widgets are destroyed)
-					if(!dijit._underlay._destroyed){
-						dijit._underlay.hide();
-					}
+					// Returning to original page.  Hide the underlay.
+					DialogUnderlay.hide();
 				}else{
-					// Popping back to previous dialog, adjust underlay
-					domStyle.set(dijit._underlay.domNode, 'zIndex', pd.zIndex - 1);
-					dijit._underlay.set(pd.underlayAttrs);
+					// Popping back to previous dialog, adjust underlay.
+					DialogUnderlay.show(pd.underlayAttrs, pd.zIndex - 1);
 				}
 
-				// Adjust focus
+				// Adjust focus.
+				// TODO: regardless of setting of dialog.refocus, if the exeucte() method set focus somewhere,
+				// don't shift focus back to button.  Note that execute() runs at the start of the fade-out but
+				// this code runs later, at the end of the fade-out.  Menu has code like this.
 				if(dialog.refocus){
 					// If we are returning control to a previous dialog but for some reason
 					// that dialog didn't have a focused field, set focus to first focusable item.
@@ -592,23 +594,31 @@ define([
 					}
 
 					if(focus){
-						focus.focus();
+						// Refocus the button that spawned the Dialog.   This will fail in corner cases including
+						// page unload on IE, because the dijit/form/Button that launched the Dialog may get destroyed
+						// before this code runs.  (#15058)
+						try{
+							focus.focus();
+						}catch(e){
+						}
 					}
 				}
 			}else{
 				// Removing a dialog out of order (#9944, #10705).
 				// Don't need to mess with underlay or z-index or anything.
-				var idx = array.indexOf(array.map(ds, function(elem){return elem.dialog}), dialog);
+				var idx = array.indexOf(array.map(ds, function(elem){
+					return elem.dialog;
+				}), dialog);
 				if(idx != -1){
 					ds.splice(idx, 1);
 				}
 			}
 		},
 
-		isTop: function(/*dijit._Widget*/ dialog){
+		isTop: function(/*dijit/_WidgetBase*/ dialog){
 			// summary:
 			//		Returns true if specified Dialog is the top in the task
-			return ds[ds.length-1].dialog == dialog;
+			return ds[ds.length - 1].dialog == dialog;
 		}
 	};
 
@@ -621,11 +631,34 @@ define([
 	//		underlayAttrs: attributes to set on underlay (when this widget is active)
 	// }
 	var ds = Dialog._dialogStack = [
-		{dialog: null, focus: null, underlayAttrs: null}	// entry for stuff at z-index: 0
+		{dialog: null, focus: null, underlayAttrs: null}    // entry for stuff at z-index: 0
 	];
 
+	// If focus was accidentally removed from the dialog, such as if the user clicked a blank
+	// area of the screen, or clicked the browser's address bar and then tabbed into the page,
+	// then refocus.   Won't do anything if focus was removed because the Dialog was closed, or
+	// because a new Dialog popped up on top of the old one, or when focus moves to popups
+	focus.watch("curNode", function(attr, oldNode, node){
+ 		// Note: if no dialogs, ds.length==1 but ds[ds.length-1].dialog is null
+		var topDialog = ds[ds.length - 1].dialog;
+
+		// If a node was focused, and there's a Dialog currently showing, and not in the process of fading out...
+		// Ignore focus events on other document though because it's likely an Editor inside of the Dialog.
+		if(node && topDialog && !topDialog._fadeOutDeferred && node.ownerDocument == topDialog.ownerDocument){
+			// If the node that was focused is inside the dialog or in a popup, even a context menu that isn't
+			// technically a descendant of the the dialog, don't do anything.
+			do{
+				if(node == topDialog.domNode || domClass.contains(node, "dijitPopup")){ return; }
+			}while(node = node.parentNode);
+
+			// Otherwise, return focus to the dialog.  Use a delay to avoid confusing dijit/focus code's
+			// own tracking of focus.
+			topDialog.focus();
+		}
+	});
+
 	// Back compat w/1.6, remove for 2.0
-	if(!kernel.isAsync){
+	if(has("dijit-legacy-requires")){
 		ready(0, function(){
 			var requires = ["dijit/TooltipDialog"];
 			require(requires);	// use indirection so modules not rolled into a build
diff --git a/dijit/DialogUnderlay.js b/dijit/DialogUnderlay.js
index 0dcb216..8a823cc 100644
--- a/dijit/DialogUnderlay.js
+++ b/dijit/DialogUnderlay.js
@@ -1,31 +1,29 @@
 define([
 	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.hitch
+	"dojo/aspect", // aspect.after
 	"dojo/dom-attr", // domAttr.set
-	"dojo/_base/window", // win.body
-	"dojo/window", // winUtils.getBox
+	"dojo/dom-style", // domStyle.getComputedStyle
+	"dojo/on",
+	"dojo/window", // winUtils.getBox, winUtils.get
 	"./_Widget",
 	"./_TemplatedMixin",
-	"./BackgroundIframe"
-], function(declare, domAttr, win, winUtils, _Widget, _TemplatedMixin, BackgroundIframe){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-=====*/
+	"./BackgroundIframe",
+	"./Viewport",
+	"./main" // for back-compat, exporting dijit._underlay (remove in 2.0)
+], function(declare, lang, aspect, domAttr, domStyle, on,
+			winUtils, _Widget, _TemplatedMixin, BackgroundIframe, Viewport, dijit){
 
 	// module:
 	//		dijit/DialogUnderlay
-	// summary:
-	//		The component that blocks the screen behind a `dijit.Dialog`
 
-	return declare("dijit.DialogUnderlay", [_Widget, _TemplatedMixin], {
+	var DialogUnderlay = declare("dijit.DialogUnderlay", [_Widget, _TemplatedMixin], {
 		// summary:
-		//		The component that blocks the screen behind a `dijit.Dialog`
+		//		A component used to block input behind a `dijit/Dialog`.
 		//
-		// description:
-		// 		A component used to block input behind a `dijit.Dialog`. Only a single
-		//		instance of this widget is created by `dijit.Dialog`, and saved as
-		//		a reference to be shared between all Dialogs as `dijit._underlay`
+		//		Normally this class should not be instantiated directly, but rather shown and hidden via
+		//		DialogUnderlay.show() and DialogUnderlay.hide().  And usually the module is not accessed directly
+		//		at all, since the underlay is shown and hidden by Dialog.DialogLevelManager.
 		//
 		//		The underlay itself can be styled based on and id:
 		//	|	#myDialog_underlay { background-color:red; }
@@ -35,7 +33,7 @@ define([
 
 		// Template has two divs; outer div is used for fade-in/fade-out, and also to hold background iframe.
 		// Inner div has opacity specified in CSS file.
-		templateString: "<div class='dijitDialogUnderlayWrapper'><div class='dijitDialogUnderlay' data-dojo-attach-point='node'></div></div>",
+		templateString: "<div class='dijitDialogUnderlayWrapper'><div class='dijitDialogUnderlay' tabIndex='-1' data-dojo-attach-point='node'></div></div>",
 
 		// Parameters on creation or updatable later
 
@@ -47,6 +45,10 @@ define([
 		//		This class name is used on the DialogUnderlay node, in addition to dijitDialogUnderlay
 		"class": "",
 
+		// This will get overwritten as soon as show() is call, but leave an empty array in case hide() or destroy()
+		// is called first.   The array is shared between instances but that's OK because we never write into it.
+		_modalConnects: [],
+
 		_setDialogIdAttr: function(id){
 			domAttr.set(this.node, "id", id + "_underlay");
 			this._set("dialogId", id);
@@ -58,9 +60,12 @@ define([
 		},
 
 		postCreate: function(){
-			// summary:
-			//		Append the underlay to the body
-			win.body().appendChild(this.domNode);
+			// Append the underlay to the body
+			this.ownerDocumentBody.appendChild(this.domNode);
+
+			this.own(on(this.domNode, "keydown", lang.hitch(this, "_onKeyDown")));
+
+			this.inherited(arguments);
 		},
 
 		layout: function(){
@@ -83,7 +88,7 @@ define([
 			os.display = "none";
 
 			// then resize and show
-			var viewport = winUtils.getBox();
+			var viewport = winUtils.getBox(this.ownerDocument);
 			os.top = viewport.t + "px";
 			os.left = viewport.l + "px";
 			is.width = viewport.w + "px";
@@ -95,16 +100,72 @@ define([
 			// summary:
 			//		Show the dialog underlay
 			this.domNode.style.display = "block";
+			this.open = true;
 			this.layout();
 			this.bgIframe = new BackgroundIframe(this.domNode);
+
+			var win = winUtils.get(this.ownerDocument);
+			this._modalConnects = [
+				Viewport.on("resize", lang.hitch(this, "layout")),
+				on(win, "scroll", lang.hitch(this, "layout"))
+			];
+
 		},
 
 		hide: function(){
 			// summary:
 			//		Hides the dialog underlay
+
 			this.bgIframe.destroy();
 			delete this.bgIframe;
 			this.domNode.style.display = "none";
+			while(this._modalConnects.length){ (this._modalConnects.pop()).remove(); }
+			this.open = false;
+		},
+
+		destroy: function(){
+			while(this._modalConnects.length){ (this._modalConnects.pop()).remove(); }
+			this.inherited(arguments);
+		},
+
+		_onKeyDown: function(){
+			// summary:
+			//		Extension point so Dialog can monitor keyboard events on the underlay.
 		}
 	});
+
+	DialogUnderlay.show = function(/*Object*/ attrs, /*Number*/ zIndex){
+		// summary:
+		//		Display the underlay with the given attributes set.  If the underlay is already displayed,
+		//		then adjust it's attributes as specified.
+		// attrs:
+		//		The parameters to create DialogUnderlay with.
+		// zIndex:
+		//		zIndex of the underlay
+
+		var underlay = DialogUnderlay._singleton;
+		if(!underlay || underlay._destroyed){
+			underlay = dijit._underlay = DialogUnderlay._singleton = new DialogUnderlay(attrs);
+		}else{
+			if(attrs){ underlay.set(attrs); }
+		}
+		domStyle.set(underlay.domNode, 'zIndex', zIndex);
+		if(!underlay.open){
+			underlay.show();
+		}
+	};
+
+	DialogUnderlay.hide = function(){
+		// summary:
+		//		Hide the underlay.
+
+		// Guard code in case the underlay widget has already been destroyed
+		// because we are being called during page unload (when all widgets are destroyed)
+		var underlay = DialogUnderlay._singleton;
+		if(underlay && !underlay._destroyed){
+			underlay.hide();
+		}
+	};
+
+	return DialogUnderlay;
 });
diff --git a/dijit/DropDownMenu.js b/dijit/DropDownMenu.js
index a5314a3..326f505 100644
--- a/dijit/DropDownMenu.js
+++ b/dijit/DropDownMenu.js
@@ -1,21 +1,13 @@
 define([
 	"dojo/_base/declare", // declare
-	"dojo/_base/event", // event.stop
 	"dojo/keys", // keys
 	"dojo/text!./templates/Menu.html",
 	"./_OnDijitClickMixin",
 	"./_MenuBase"
-], function(declare, event, keys, template, _OnDijitClickMixin, _MenuBase){
-
-/*=====
-	var _MenuBase = dijit._MenuBase;
-	var _OnDijitClickMixin = dijit._OnDijitClickMixin;
-=====*/
+], function(declare, keys, template, _OnDijitClickMixin, _MenuBase){
 
 	// module:
 	//		dijit/DropDownMenu
-	// summary:
-	//		dijit.DropDownMenu widget
 
 	return declare("dijit.DropDownMenu", [_MenuBase, _OnDijitClickMixin], {
 		// summary:
@@ -25,37 +17,28 @@ define([
 
 		baseClass: "dijitMenu",
 
-		postCreate: function(){
-			var l = this.isLeftToRight();
-			this._openSubMenuKey = l ? keys.RIGHT_ARROW : keys.LEFT_ARROW;
-			this._closeSubMenuKey = l ? keys.LEFT_ARROW : keys.RIGHT_ARROW;
-			this.connectKeyNavHandlers([keys.UP_ARROW], [keys.DOWN_ARROW]);
+		// Arrow key navigation
+		_onUpArrow: function(){
+			this.focusPrev();
 		},
-
-		_onKeyPress: function(/*Event*/ evt){
-			// summary:
-			//		Handle keyboard based menu navigation.
-			// tags:
-			//		protected
-
-			if(evt.ctrlKey || evt.altKey){ return; }
-
-			switch(evt.charOrCode){
-				case this._openSubMenuKey:
-					this._moveToPopup(evt);
-					event.stop(evt);
-					break;
-				case this._closeSubMenuKey:
-					if(this.parentMenu){
-						if(this.parentMenu._isMenuBar){
-							this.parentMenu.focusPrev();
-						}else{
-							this.onCancel(false);
-						}
-					}else{
-						event.stop(evt);
-					}
-					break;
+		_onDownArrow: function(){
+			this.focusNext();
+		},
+		_onRightArrow: function(/*Event*/ evt){
+			this._moveToPopup(evt);
+			evt.stopPropagation();
+			evt.preventDefault();
+		},
+		_onLeftArrow: function(){
+			if(this.parentMenu){
+				if(this.parentMenu._isMenuBar){
+					this.parentMenu.focusPrev();
+				}else{
+					this.onCancel(false);
+				}
+			}else{
+				evt.stopPropagation();
+				evt.preventDefault();
 			}
 		}
 	});
diff --git a/dijit/Editor.js b/dijit/Editor.js
index 3ba1f7a..7a3134e 100644
--- a/dijit/Editor.js
+++ b/dijit/Editor.js
@@ -1,20 +1,18 @@
 define([
+	"require",
 	"dojo/_base/array", // array.forEach
 	"dojo/_base/declare", // declare
-	"dojo/_base/Deferred", // Deferred
+	"dojo/Deferred", // Deferred
 	"dojo/i18n", // i18n.getLocalization
 	"dojo/dom-attr", // domAttr.set
 	"dojo/dom-class", // domClass.add
 	"dojo/dom-geometry",
 	"dojo/dom-style", // domStyle.set, get
-	"dojo/_base/event", // event.stop
 	"dojo/keys", // keys.F1 keys.F15 keys.TAB
 	"dojo/_base/lang", // lang.getObject lang.hitch
-	"dojo/_base/sniff", // has("ie") has("mac") has("webkit")
+	"dojo/sniff", // has("ie") has("mac") has("webkit")
 	"dojo/string", // string.substitute
 	"dojo/topic", // topic.publish()
-	"dojo/_base/window", // win.withGlobal
-	"./_base/focus",	// dijit.getBookmark()
 	"./_Container",
 	"./Toolbar",
 	"./ToolbarSeparator",
@@ -25,17 +23,15 @@ define([
 	"./_editor/html",
 	"./_editor/range",
 	"./_editor/RichText",
-	".",	// dijit._scopeName
+	"./main", // dijit._scopeName
 	"dojo/i18n!./_editor/nls/commands"
-], function(array, declare, Deferred, i18n, domAttr, domClass, domGeometry, domStyle,
-			event, keys, lang, has, string, topic, win,
-			focusBase, _Container, Toolbar, ToolbarSeparator, _LayoutWidget, ToggleButton,
+], function(require, array, declare, Deferred, i18n, domAttr, domClass, domGeometry, domStyle,
+			keys, lang, has, string, topic,
+			_Container, Toolbar, ToolbarSeparator, _LayoutWidget, ToggleButton,
 			_Plugin, EnterKeyHandling, html, rangeapi, RichText, dijit){
 
 	// module:
 	//		dijit/Editor
-	// summary:
-	//		A rich text Editing widget
 
 	var Editor = declare("dijit.Editor", RichText, {
 		// summary:
@@ -48,7 +44,7 @@ define([
 		//		the options available in the toolbar.  Content generation may vary across
 		//		browsers, and clipboard operations may have different results, to name
 		//		a few limitations.  Note: this widget should not be used with the HTML
-		//		<TEXTAREA> tag -- see dijit._editor.RichText for details.
+		//		<TEXTAREA> tag -- see dijit/_editor/RichText for details.
 
 		// plugins: [const] Object[]
 		//		A list of plugin names (as strings) or instances (as objects)
@@ -62,19 +58,21 @@ define([
 		//		A list of extra plugin names which will be appended to plugins array
 		extraPlugins: null,
 
-		constructor: function(){
+		constructor: function(/*===== params, srcNodeRef =====*/){
 			// summary:
-			//		Runs on widget initialization to setup arrays etc.
-			// tags:
-			//		private
+			//		Create the widget.
+			// params: Object|null
+			//		Initial settings for any of the attributes, except readonly attributes.
+			// srcNodeRef: DOMNode
+			//		The editor replaces the specified DOMNode.
 
 			if(!lang.isArray(this.plugins)){
-				this.plugins=["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|",
-				"insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull",
-				EnterKeyHandling /*, "createLink"*/];
+				this.plugins = ["undo", "redo", "|", "cut", "copy", "paste", "|", "bold", "italic", "underline", "strikethrough", "|",
+					"insertOrderedList", "insertUnorderedList", "indent", "outdent", "|", "justifyLeft", "justifyRight", "justifyCenter", "justifyFull",
+					EnterKeyHandling /*, "createLink"*/];
 			}
 
-			this._plugins=[];
+			this._plugins = [];
 			this._editInterval = this.editActionInterval * 1000;
 
 			//IE will always lose focus when other element gets focus, while for FF and safari,
@@ -106,23 +104,37 @@ define([
 		},
 
 		postCreate: function(){
+			this.inherited(arguments);
+
 			//for custom undo/redo, if enabled.
-			this._steps=this._steps.slice(0);
-			this._undoedSteps=this._undoedSteps.slice(0);
+			this._steps = this._steps.slice(0);
+			this._undoedSteps = this._undoedSteps.slice(0);
 
 			if(lang.isArray(this.extraPlugins)){
-				this.plugins=this.plugins.concat(this.extraPlugins);
+				this.plugins = this.plugins.concat(this.extraPlugins);
 			}
 
-			this.inherited(arguments);
-
 			this.commands = i18n.getLocalization("dijit._editor", "commands", this.lang);
 
+			if(has("webkit")){
+				// Disable selecting the entire editor by inadvertent double-clicks.
+				// on buttons, title bar, etc.  Otherwise clicking too fast on
+				// a button such as undo/redo selects the entire editor.
+				domStyle.set(this.domNode, "KhtmlUserSelect", "none");
+			}
+		},
+
+		startup: function(){
+
+			this.inherited(arguments);
+
 			if(!this.toolbar){
 				// if we haven't been assigned a toolbar, create one
 				this.toolbar = new Toolbar({
+					ownerDocument: this.ownerDocument,
 					dir: this.dir,
-					lang: this.lang
+					lang: this.lang,
+					"aria-label": this.id
 				});
 				this.header.appendChild(this.toolbar.domNode);
 			}
@@ -130,33 +142,28 @@ define([
 			array.forEach(this.plugins, this.addPlugin, this);
 
 			// Okay, denote the value can now be set.
-			this.setValueDeferred.callback(true);
+			this.setValueDeferred.resolve(true);
 
 			domClass.add(this.iframe.parentNode, "dijitEditorIFrameContainer");
 			domClass.add(this.iframe, "dijitEditorIFrame");
 			domAttr.set(this.iframe, "allowTransparency", true);
 
-			if(has("webkit")){
-				// Disable selecting the entire editor by inadvertent double-clicks.
-				// on buttons, title bar, etc.  Otherwise clicking too fast on
-				// a button such as undo/redo selects the entire editor.
-				domStyle.set(this.domNode, "KhtmlUserSelect", "none");
-			}
 			this.toolbar.startup();
 			this.onNormalizedDisplayChanged(); //update toolbar button status
 		},
+
 		destroy: function(){
 			array.forEach(this._plugins, function(p){
 				if(p && p.destroy){
 					p.destroy();
 				}
 			});
-			this._plugins=[];
+			this._plugins = [];
 			this.toolbar.destroyRecursive();
 			delete this.toolbar;
 			this.inherited(arguments);
 		},
-		addPlugin: function(/*String||Object||Function*/plugin, /*Integer?*/index){
+		addPlugin: function(/*String||Object||Function*/ plugin, /*Integer?*/ index){
 			// summary:
 			//		takes a plugin name as a string or a plugin instance and
 			//		adds it to the toolbar and associates it with this editor
@@ -164,19 +171,17 @@ define([
 			//		plugins array. If index is passed, it's placed in the plugins
 			//		array at that index. No big magic, but a nice helper for
 			//		passing in plugin names via markup.
-			//
-			// plugin: String, args object, plugin instance, or plugin constructor
-			//
+			// plugin:
+			//		String, args object, plugin instance, or plugin constructor
 			// args:
 			//		This object will be passed to the plugin constructor
-			//
-			// index: Integer
+			// index:
 			//		Used when creating an instance from
 			//		something already in this.plugins. Ensures that the new
 			//		instance is assigned to this.plugins at that index.
-			var args=lang.isString(plugin)?{name:plugin}:lang.isFunction(plugin)?{ctor:plugin}:plugin;
+			var args = lang.isString(plugin) ? {name: plugin} : lang.isFunction(plugin) ? {ctor: plugin} : plugin;
 			if(!args.setEditor){
-				var o={"args":args,"plugin":null,"editor":this};
+				var o = {"args": args, "plugin": null, "editor": this};
 				if(args.name){
 					// search registry for a plugin factory matching args.name, if it's not there then
 					// fallback to 1.0 API:
@@ -189,16 +194,20 @@ define([
 					}
 				}
 				if(!o.plugin){
-					var pc = args.ctor || lang.getObject(args.name);
-					if(pc){
-						o.plugin=new pc(args);
+					try{
+						// TODO: remove lang.getObject() call in 2.0
+						var pc = args.ctor || lang.getObject(args.name) || require(args.name);
+						if(pc){
+							o.plugin = new pc(args);
+						}
+					}catch(e){
+						throw new Error(this.id + ": cannot find plugin [" + args.name + "]");
 					}
 				}
 				if(!o.plugin){
-					console.warn('Cannot find plugin',plugin);
-					return;
+					throw new Error(this.id + ": cannot find plugin [" + args.name + "]");
 				}
-				plugin=o.plugin;
+				plugin = o.plugin;
 			}
 			if(arguments.length > 1){
 				this._plugins[index] = plugin;
@@ -215,22 +224,22 @@ define([
 
 		resize: function(size){
 			// summary:
-			//		Resize the editor to the specified size, see `dijit.layout._LayoutWidget.resize`
+			//		Resize the editor to the specified size, see `dijit/layout/_LayoutWidget.resize()`
 			if(size){
 				// we've been given a height/width for the entire editor (toolbar + contents), calls layout()
 				// to split the allocated size between the toolbar and the contents
 				_LayoutWidget.prototype.resize.apply(this, arguments);
 			}
 			/*
-			else{
-				// do nothing, the editor is already laid out correctly.   The user has probably specified
-				// the height parameter, which was used to set a size on the iframe
-			}
-			*/
+			 else{
+			 // do nothing, the editor is already laid out correctly.   The user has probably specified
+			 // the height parameter, which was used to set a size on the iframe
+			 }
+			 */
 		},
 		layout: function(){
 			// summary:
-			//		Called from `dijit.layout._LayoutWidget.resize`.  This shouldn't be called directly
+			//		Called from `dijit/layout/_LayoutWidget.resize()`.  This shouldn't be called directly
 			// tags:
 			//		protected
 
@@ -240,11 +249,11 @@ define([
 			// calc off the added margins and padding too. See tracker: #10662
 			var areaHeight = (this._contentBox.h -
 				(this.getHeaderHeight() + this.getFooterHeight() +
-				 domGeometry.getPadBorderExtents(this.iframe.parentNode).h +
-				 domGeometry.getMarginExtents(this.iframe.parentNode).h));
+					domGeometry.getPadBorderExtents(this.iframe.parentNode).h +
+					domGeometry.getMarginExtents(this.iframe.parentNode).h));
 			this.editingArea.style.height = areaHeight + "px";
 			if(this.iframe){
-				this.iframe.style.height="100%";
+				this.iframe.style.height = "100%";
 			}
 			this._layoutMode = true;
 		},
@@ -290,7 +299,7 @@ define([
 				delete this._cursorToStart; // Remove the force to cursor to start position.
 				delete this._savedSelection; // new mouse position overrides old selection
 				if(e.target.tagName == "BODY"){
-					setTimeout(lang.hitch(this, "placeCursorAtEnd"), 0);
+					this.defer("placeCursorAtEnd");
 				}
 				this.inherited(arguments);
 			}
@@ -340,25 +349,25 @@ define([
 			// tags:
 			//		private
 			if(!this._inEditing){
-				this._inEditing=true;
+				this._inEditing = true;
 				this._beginEditing(cmd);
 			}
-			if(this.editActionInterval>0){
+			if(this.editActionInterval > 0){
 				if(this._editTimer){
-					clearTimeout(this._editTimer);
+					this._editTimer.remove();
 				}
-				this._editTimer = setTimeout(lang.hitch(this, this.endEditing), this._editInterval);
+				this._editTimer = this.defer("endEditing", this._editInterval);
 			}
 		},
 
 		// TODO: declaring these in the prototype is meaningless, just create in the constructor/postCreate
-		_steps:[],
-		_undoedSteps:[],
+		_steps: [],
+		_undoedSteps: [],
 
 		execCommand: function(cmd){
 			// summary:
 			//		Main handler for executing any commands to the editor, like paste, bold, etc.
-			//      Called by plugins, but not meant to be called by end users.
+			//		Called by plugins, but not meant to be called by end users.
 			// tags:
 			//		protected
 			if(this.customUndo && (cmd == 'undo' || cmd == 'redo')){
@@ -414,10 +423,11 @@ define([
 				}
 			}catch(e){
 				//TODO: when else might we get an exception?  Do we need the Mozilla test below?
-				if(e.code == 1011 /* Mozilla: service denied */){
+				if(e.code == 1011 /* Mozilla: service denied */ ||
+					(e.code == 9 && has("opera") /* Opera not supported */)){
 					// Warn user of platform limitation.  Cannot programmatically access clipboard. See ticket #4136
 					var sub = string.substitute,
-						accel = {cut:'X', copy:'C', paste:'V'};
+						accel = {cut: 'X', copy: 'C', paste: 'V'};
 					alert(sub(this.commands.systemShortcut,
 						[this.commands[cmd], sub(this.commands[has("mac") ? 'appleKey' : 'ctrlKey'], [accel[cmd]])]));
 				}
@@ -429,7 +439,7 @@ define([
 		queryCommandEnabled: function(cmd){
 			// summary:
 			//		Returns true if specified editor command is enabled.
-			//      Used by the plugins to know when to highlight/not highlight buttons.
+			//		Used by the plugins to know when to highlight/not highlight buttons.
 			// tags:
 			//		protected
 			if(this.customUndo && (cmd == 'undo' || cmd == 'redo')){
@@ -448,14 +458,14 @@ define([
 			var col = b.isCollapsed;
 			var r, sNode, eNode, sel;
 			if(mark){
-				if(has("ie") < 9){
+				if(has("ie") < 9 || (has("ie") === 9 && has("quirks"))){
 					if(lang.isArray(mark)){
-						//IE CONTROL, have to use the native bookmark.
+						// IE CONTROL, have to use the native bookmark.
 						bookmark = [];
-						array.forEach(mark,function(n){
-							bookmark.push(rangeapi.getNode(n,this.editNode));
-						},this);
-						win.withGlobal(this.window,'moveToBookmark',dijit,[{mark: bookmark, isCollapsed: col}]);
+						array.forEach(mark, function(n){
+							bookmark.push(rangeapi.getNode(n, this.editNode));
+						}, this);
+						this.selection.moveToBookmark({mark: bookmark, isCollapsed: col});
 					}else{
 						if(mark.startContainer && mark.endContainer){
 							// Use the pseudo WC3 range API.  This works better for positions
@@ -464,15 +474,15 @@ define([
 							if(sel && sel.removeAllRanges){
 								sel.removeAllRanges();
 								r = rangeapi.create(this.window);
-								sNode = rangeapi.getNode(mark.startContainer,this.editNode);
-								eNode = rangeapi.getNode(mark.endContainer,this.editNode);
+								sNode = rangeapi.getNode(mark.startContainer, this.editNode);
+								eNode = rangeapi.getNode(mark.endContainer, this.editNode);
 								if(sNode && eNode){
 									// Okay, we believe we found the position, so add it into the selection
 									// There are cases where it may not be found, particularly in undo/redo, when
 									// IE changes the underlying DOM on us (wraps text in a <p> tag or similar.
 									// So, in those cases, don't bother restoring selection.
-									r.setStart(sNode,mark.startOffset);
-									r.setEnd(eNode,mark.endOffset);
+									r.setStart(sNode, mark.startOffset);
+									r.setEnd(eNode, mark.endOffset);
 									sel.addRange(r);
 								}
 							}
@@ -483,14 +493,14 @@ define([
 					if(sel && sel.removeAllRanges){
 						sel.removeAllRanges();
 						r = rangeapi.create(this.window);
-						sNode = rangeapi.getNode(mark.startContainer,this.editNode);
-						eNode = rangeapi.getNode(mark.endContainer,this.editNode);
+						sNode = rangeapi.getNode(mark.startContainer, this.editNode);
+						eNode = rangeapi.getNode(mark.endContainer, this.editNode);
 						if(sNode && eNode){
 							// Okay, we believe we found the position, so add it into the selection
 							// There are cases where it may not be found, particularly in undo/redo, when
 							// formatting as been done and so on, so don't restore selection then.
-							r.setStart(sNode,mark.startOffset);
-							r.setEnd(eNode,mark.endOffset);
+							r.setStart(sNode, mark.startOffset);
+							r.setEnd(eNode, mark.endOffset);
 							sel.addRange(r);
 						}
 					}
@@ -503,8 +513,10 @@ define([
 			// tags:
 			//		private
 			this.setValue(to.text);
-			var b=to.bookmark;
-			if(!b){ return; }
+			var b = to.bookmark;
+			if(!b){
+				return;
+			}
 			this._moveToBookmark(b);
 		},
 		undo: function(){
@@ -512,15 +524,14 @@ define([
 			//		Handler for editor undo (ex: ctrl-z) operation
 			// tags:
 			//		private
-			//console.log('undo');
 			var ret = false;
 			if(!this._undoRedoActive){
 				this._undoRedoActive = true;
 				this.endEditing(true);
-				var s=this._steps.pop();
-				if(s && this._steps.length>0){
+				var s = this._steps.pop();
+				if(s && this._steps.length > 0){
 					this.focus();
-					this._changeToStep(s,this._steps[this._steps.length-1]);
+					this._changeToStep(s, this._steps[this._steps.length - 1]);
 					this._undoedSteps.push(s);
 					this.onDisplayChanged();
 					delete this._undoRedoActive;
@@ -535,15 +546,14 @@ define([
 			//		Handler for editor redo (ex: ctrl-y) operation
 			// tags:
 			//		private
-			//console.log('redo');
 			var ret = false;
 			if(!this._undoRedoActive){
 				this._undoRedoActive = true;
 				this.endEditing(true);
-				var s=this._undoedSteps.pop();
-				if(s && this._steps.length>0){
+				var s = this._undoedSteps.pop();
+				if(s && this._steps.length > 0){
 					this.focus();
-					this._changeToStep(this._steps[this._steps.length-1],s);
+					this._changeToStep(this._steps[this._steps.length - 1], s);
 					this._steps.push(s);
 					this.onDisplayChanged();
 					ret = true;
@@ -559,11 +569,11 @@ define([
 			// tags:
 			//		private
 			if(this._editTimer){
-				clearTimeout(this._editTimer);
+				this._editTimer = this._editTimer.remove();
 			}
 			if(this._inEditing){
 				this._endEditing(ignore_caret);
-				this._inEditing=false;
+				this._inEditing = false;
 			}
 		},
 
@@ -572,11 +582,11 @@ define([
 			//		Get the currently selected text
 			// tags:
 			//		protected
-			var b=win.withGlobal(this.window,focusBase.getBookmark);
-			var tmp=[];
+			var b = this.selection.getBookmark();
+			var tmp = [];
 			if(b && b.mark){
 				var mark = b.mark;
-				if(has("ie") < 9){
+				if(has("ie") < 9 || (has("ie") === 9 && has("quirks"))){
 					// Try to use the pseudo range API on IE for better accuracy.
 					var sel = rangeapi.getSelection(this.window);
 					if(!lang.isArray(mark)){
@@ -588,24 +598,24 @@ define([
 							if(range){
 								b.mark = range.cloneRange();
 							}else{
-								b.mark = win.withGlobal(this.window,focusBase.getBookmark);
+								b.mark = this.selection.getBookmark();
 							}
 						}
 					}else{
 						// Control ranges (img, table, etc), handle differently.
-						array.forEach(b.mark,function(n){
-							tmp.push(rangeapi.getIndex(n,this.editNode).o);
-						},this);
+						array.forEach(b.mark, function(n){
+							tmp.push(rangeapi.getIndex(n, this.editNode).o);
+						}, this);
 						b.mark = tmp;
 					}
 				}
 				try{
 					if(b.mark && b.mark.startContainer){
-						tmp=rangeapi.getIndex(b.mark.startContainer,this.editNode).o;
-						b.mark={startContainer:tmp,
-							startOffset:b.mark.startOffset,
-							endContainer:b.mark.endContainer===b.mark.startContainer?tmp:rangeapi.getIndex(b.mark.endContainer,this.editNode).o,
-							endOffset:b.mark.endOffset};
+						tmp = rangeapi.getIndex(b.mark.startContainer, this.editNode).o;
+						b.mark = {startContainer: tmp,
+							startOffset: b.mark.startOffset,
+							endContainer: b.mark.endContainer === b.mark.startContainer ? tmp : rangeapi.getIndex(b.mark.endContainer, this.editNode).o,
+							endOffset: b.mark.endOffset};
 					}
 				}catch(e){
 					b.mark = null;
@@ -624,7 +634,7 @@ define([
 				// to make sure selection restores right for the 'initial' state.
 				// and undo is called.  So not using this.value, as it was 'processed'
 				// and the line-up for selections may have been altered.
-				this._steps.push({'text':html.getChildrenHtml(this.editNode),'bookmark':this._getBookmark()});
+				this._steps.push({'text': html.getChildrenHtml(this.editNode), 'bookmark': this._getBookmark()});
 			}
 		},
 		_endEditing: function(){
@@ -633,10 +643,11 @@ define([
 			//		Deals with saving undo; see editActionInterval parameter.
 			// tags:
 			//		private
+
 			// Avoid filtering to make sure selections restore.
 			var v = html.getChildrenHtml(this.editNode);
 
-			this._undoedSteps=[];//clear undoed steps
+			this._undoedSteps = [];//clear undoed steps
 			this._steps.push({text: v, bookmark: this._getBookmark()});
 		},
 		onKeyDown: function(e){
@@ -655,13 +666,15 @@ define([
 				return;
 			}
 			var k = e.keyCode;
-			if(e.ctrlKey && !e.altKey){//undo and redo only if the special right Alt + z/y are not pressed #5892
-				if(k == 90 || k == 122){ //z
-					event.stop(e);
+			if(e.ctrlKey && !e.shiftKey && !e.altKey){//undo and redo only if the special right Alt + z/y are not pressed #5892
+				if(k == 90 || k == 122){ //z, but also F11 key
+					e.stopPropagation();
+					e.preventDefault();
 					this.undo();
 					return;
 				}else if(k == 89 || k == 121){ //y
-					event.stop(e);
+					e.stopPropagation();
+					e.preventDefault();
 					this.redo();
 					return;
 				}
@@ -669,52 +682,50 @@ define([
 			this.inherited(arguments);
 
 			switch(k){
-					case keys.ENTER:
-					case keys.BACKSPACE:
-					case keys.DELETE:
-						this.beginEditing();
-						break;
-					case 88: //x
-					case 86: //v
-						if(e.ctrlKey && !e.altKey && !e.metaKey){
-							this.endEditing();//end current typing step if any
-							if(e.keyCode == 88){
-								this.beginEditing('cut');
-								//use timeout to trigger after the cut is complete
-								setTimeout(lang.hitch(this, this.endEditing), 1);
-							}else{
-								this.beginEditing('paste');
-								//use timeout to trigger after the paste is complete
-								setTimeout(lang.hitch(this, this.endEditing), 1);
-							}
-							break;
-						}
-						//pass through
-					default:
-						if(!e.ctrlKey && !e.altKey && !e.metaKey && (e.keyCode<keys.F1 || e.keyCode>keys.F15)){
-							this.beginEditing();
-							break;
+				case keys.ENTER:
+				case keys.BACKSPACE:
+				case keys.DELETE:
+					this.beginEditing();
+					break;
+				case 88: //x
+				case 86: //v
+					if(e.ctrlKey && !e.altKey && !e.metaKey){
+						this.endEditing();//end current typing step if any
+						if(e.keyCode == 88){
+							this.beginEditing('cut');
+						}else{
+							this.beginEditing('paste');
 						}
-						//pass through
-					case keys.ALT:
-						this.endEditing();
+						//use timeout to trigger after the paste is complete
+						this.defer("endEditing", 1);
 						break;
-					case keys.UP_ARROW:
-					case keys.DOWN_ARROW:
-					case keys.LEFT_ARROW:
-					case keys.RIGHT_ARROW:
-					case keys.HOME:
-					case keys.END:
-					case keys.PAGE_UP:
-					case keys.PAGE_DOWN:
-						this.endEditing(true);
-						break;
-					//maybe ctrl+backspace/delete, so don't endEditing when ctrl is pressed
-					case keys.CTRL:
-					case keys.SHIFT:
-					case keys.TAB:
+					}
+				//pass through
+				default:
+					if(!e.ctrlKey && !e.altKey && !e.metaKey && (e.keyCode < keys.F1 || e.keyCode > keys.F15)){
+						this.beginEditing();
 						break;
-				}
+					}
+				//pass through
+				case keys.ALT:
+					this.endEditing();
+					break;
+				case keys.UP_ARROW:
+				case keys.DOWN_ARROW:
+				case keys.LEFT_ARROW:
+				case keys.RIGHT_ARROW:
+				case keys.HOME:
+				case keys.END:
+				case keys.PAGE_UP:
+				case keys.PAGE_DOWN:
+					this.endEditing(true);
+					break;
+				//maybe ctrl+backspace/delete, so don't endEditing when ctrl is pressed
+				case keys.CTRL:
+				case keys.SHIFT:
+				case keys.TAB:
+					break;
+			}
 		},
 		_onBlur: function(){
 			// summary:
@@ -732,8 +743,9 @@ define([
 			// tags:
 			//		private
 			try{
-				this._savedSelection=this._getBookmark();
-			}catch(e){ /* Squelch any errors that occur if selection save occurs due to being hidden simultaneously. */}
+				this._savedSelection = this._getBookmark();
+			}catch(e){ /* Squelch any errors that occur if selection save occurs due to being hidden simultaneously. */
+			}
 		},
 		_restoreSelection: function(){
 			// summary:
@@ -747,7 +759,7 @@ define([
 				// only restore the selection if the current range is collapsed
 				// if not collapsed, then it means the editor does not lose
 				// selection and there is no need to restore it
-				if(win.withGlobal(this.window,'isCollapsed',dijit)){
+				if(this.selection.isCollapsed()){
 					this._moveToBookmark(this._savedSelection);
 				}
 				delete this._savedSelection;
@@ -785,20 +797,19 @@ define([
 		},
 
 		_setDisabledAttr: function(/*Boolean*/ value){
-			var disableFunc = lang.hitch(this, function(){
+			this.setValueDeferred.then(lang.hitch(this, function(){
 				if((!this.disabled && value) || (!this._buttonEnabledPlugins && value)){
-				// Disable editor: disable all enabled buttons and remember that list
+					// Disable editor: disable all enabled buttons and remember that list
 					array.forEach(this._plugins, function(p){
 						p.set("disabled", true);
-				});
-			}else if(this.disabled && !value){
+					});
+				}else if(this.disabled && !value){
 					// Restore plugins to being active.
 					array.forEach(this._plugins, function(p){
 						p.set("disabled", false);
-				});
-			}
-			});
-			this.setValueDeferred.addCallback(disableFunc);
+					});
+				}
+			}));
 			this.inherited(arguments);
 		},
 
@@ -812,7 +823,8 @@ define([
 				if(this.document && this.document.body){
 					domStyle.set(this.document.body, "color", domStyle.get(this.iframe, "color"));
 				}
-			}catch(e){ /* Squelch any errors caused by focus change if hidden during a state change */}
+			}catch(e){ /* Squelch any errors caused by focus change if hidden during a state change */
+			}
 		}
 	});
 
@@ -820,9 +832,11 @@ define([
 	function simplePluginFactory(args){
 		return new _Plugin({ command: args.name });
 	}
+
 	function togglePluginFactory(args){
 		return new _Plugin({ buttonClass: ToggleButton, command: args.name });
 	}
+
 	lang.mixin(_Plugin.registry, {
 		"undo": simplePluginFactory,
 		"redo": simplePluginFactory,
@@ -851,7 +865,12 @@ define([
 		"superscript": togglePluginFactory,
 
 		"|": function(){
-			return new _Plugin({ button: new ToolbarSeparator(), setEditor: function(editor){this.editor = editor;}});
+			return new _Plugin({
+				setEditor: function(editor){
+					this.editor = editor;
+					this.button = new ToolbarSeparator({ownerDocument: editor.ownerDocument});
+				}
+			});
 		}
 	});
 
diff --git a/dijit/Fieldset.js b/dijit/Fieldset.js
new file mode 100644
index 0000000..31b6d08
--- /dev/null
+++ b/dijit/Fieldset.js
@@ -0,0 +1,40 @@
+define([
+	"dojo/_base/declare",
+	"dojo/query!css2",
+	"dijit/TitlePane",
+	"dojo/text!./templates/Fieldset.html"
+], function(declare, query, TitlePane, template){
+
+
+	return declare("dijit.Fieldset", TitlePane, {
+		// summary:
+		//		An accessible fieldset that can be expanded or collapsed via
+		//		its legend.  Fieldset extends `dijit.TitlePane`.
+
+		// baseClass: [protected] String
+		//		The root className to use for the various states of this widget
+		baseClass: 'dijitFieldset',
+
+		// title: String
+		//		Content of the legend tag. Overrides <legend> tag if not empty.
+		title: '',
+
+		// open: Boolean
+		//		Whether fieldset is opened or closed.
+		open: true,
+
+		templateString: template,
+
+		postCreate: function() {
+			if(!this.title){
+				var legends = query('legend', this.containerNode);
+				if(legends.length) { // oops, no legend?
+					this.set('title', legends[0].innerHTML);
+					legends[0].parentNode.removeChild(legends[0]);
+				}
+			}
+
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dijit/InlineEditBox.js b/dijit/InlineEditBox.js
index 36ad710..ab78ce5 100644
--- a/dijit/InlineEditBox.js
+++ b/dijit/InlineEditBox.js
@@ -1,16 +1,20 @@
 define([
+	"require",
 	"dojo/_base/array", // array.forEach
+	"dojo/aspect",
 	"dojo/_base/declare", // declare
 	"dojo/dom-attr", // domAttr.set domAttr.get
 	"dojo/dom-class", // domClass.add domClass.remove domClass.toggle
 	"dojo/dom-construct", // domConstruct.create domConstruct.destroy
 	"dojo/dom-style", // domStyle.getComputedStyle domStyle.set domStyle.get
-	"dojo/_base/event", // event.stop
 	"dojo/i18n", // i18n.getLocalization
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/keys", // keys.ENTER keys.ESCAPE
 	"dojo/_base/lang", // lang.getObject
-	"dojo/_base/sniff", // has("ie")
+	"dojo/on",
+	"dojo/sniff", // has("ie")
+	"dojo/when",
+	"./a11yclick",
 	"./focus",
 	"./_Widget",
 	"./_TemplatedMixin",
@@ -21,605 +25,629 @@ define([
 	"./form/TextBox",
 	"dojo/text!./templates/InlineEditBox.html",
 	"dojo/i18n!./nls/common"
-], function(array, declare, domAttr, domClass, domConstruct, domStyle, event, i18n, kernel, keys, lang, has,
-			fm, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _Container, Button, _TextBoxMixin, TextBox, template){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
-	var _Container = dijit._Container;
-	var Button = dijit.form.Button;
-	var TextBox = dijit.form.TextBox;
-=====*/
-
-// module:
-//		dijit/InlineEditBox
-// summary:
-//		An element with in-line edit capabilities
-
-var InlineEditor = declare("dijit._InlineEditor", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
-	// summary:
-	// 		Internal widget used by InlineEditBox, displayed when in editing mode
-	//		to display the editor and maybe save/cancel buttons.  Calling code should
-	//		connect to save/cancel methods to detect when editing is finished
-	//
-	//		Has mainly the same parameters as InlineEditBox, plus these values:
-	//
-	// style: Object
-	//		Set of CSS attributes of display node, to replicate in editor
-	//
-	// value: String
-	//		Value as an HTML string or plain text string, depending on renderAsHTML flag
-
-	templateString: template,
-
-	postMixInProperties: function(){
-		this.inherited(arguments);
-		this.messages = i18n.getLocalization("dijit", "common", this.lang);
-		array.forEach(["buttonSave", "buttonCancel"], function(prop){
-			if(!this[prop]){ this[prop] = this.messages[prop]; }
-		}, this);
-	},
-
-	buildRendering: function(){
-		this.inherited(arguments);
-
-		// Create edit widget in place in the template
-		var cls = typeof this.editor == "string" ? lang.getObject(this.editor) : this.editor;
-
-		// Copy the style from the source
-		// Don't copy ALL properties though, just the necessary/applicable ones.
-		// wrapperStyle/destStyle code is to workaround IE bug where getComputedStyle().fontSize
-		// is a relative value like 200%, rather than an absolute value like 24px, and
-		// the 200% can refer *either* to a setting on the node or it's ancestor (see #11175)
-		var srcStyle = this.sourceStyle,
-			editStyle = "line-height:" + srcStyle.lineHeight + ";",
-			destStyle = domStyle.getComputedStyle(this.domNode);
-		array.forEach(["Weight","Family","Size","Style"], function(prop){
-			var textStyle = srcStyle["font"+prop],
-				wrapperStyle = destStyle["font"+prop];
-			if(wrapperStyle != textStyle){
-				editStyle += "font-"+prop+":"+srcStyle["font"+prop]+";";
-			}
-		}, this);
-		array.forEach(["marginTop","marginBottom","marginLeft", "marginRight"], function(prop){
-			this.domNode.style[prop] = srcStyle[prop];
-		}, this);
-		var width = this.inlineEditBox.width;
-		if(width == "100%"){
-			// block mode
-			editStyle += "width:100%;";
-			this.domNode.style.display = "block";
-		}else{
-			// inline-block mode
-			editStyle += "width:" + (width + (Number(width) == width ? "px" : "")) + ";";
-		}
-		var editorParams = lang.delegate(this.inlineEditBox.editorParams, {
-			style: editStyle,
-			dir: this.dir,
-			lang: this.lang,
-			textDir: this.textDir
-		});
-		editorParams[ "displayedValue" in cls.prototype ? "displayedValue" : "value"] = this.value;
-		this.editWidget = new cls(editorParams, this.editorPlaceholder);
+], function(require, array, aspect, declare, domAttr, domClass, domConstruct, domStyle, i18n, kernel, keys, lang, on, has, when, a11yclick, fm, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _Container, Button, _TextBoxMixin, TextBox, template){
 
-		if(this.inlineEditBox.autoSave){
-			// Remove the save/cancel buttons since saving is done by simply tabbing away or
-			// selecting a value from the drop down list
-			domConstruct.destroy(this.buttonContainer);
-		}
-	},
-
-	postCreate: function(){
-		this.inherited(arguments);
-
-		var ew = this.editWidget;
-
-		if(this.inlineEditBox.autoSave){
-			// Selecting a value from a drop down list causes an onChange event and then we save
-			this.connect(ew, "onChange", "_onChange");
-
-			// ESC and TAB should cancel and save.  Note that edit widgets do a stopEvent() on ESC key (to
-			// prevent Dialog from closing when the user just wants to revert the value in the edit widget),
-			// so this is the only way we can see the key press event.
-			this.connect(ew, "onKeyPress", "_onKeyPress");
-		}else{
-			// If possible, enable/disable save button based on whether the user has changed the value
-			if("intermediateChanges" in ew){
-				ew.set("intermediateChanges", true);
-				this.connect(ew, "onChange", "_onIntermediateChange");
-				this.saveButton.set("disabled", true);
-			}
-		}
-	},
+	// module:
+	//		dijit/InlineEditBox
 
-	_onIntermediateChange: function(/*===== val =====*/){
+	var InlineEditor = declare("dijit._InlineEditor", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
 		// summary:
-		//		Called for editor widgets that support the intermediateChanges=true flag as a way
-		//		to detect when to enable/disabled the save button
-		this.saveButton.set("disabled", (this.getValue() == this._resetValue) || !this.enableSave());
-	},
-
-	destroy: function(){
-		this.editWidget.destroy(true); // let the parent wrapper widget clean up the DOM
-		this.inherited(arguments);
-	},
-
-	getValue: function(){
-		// summary:
-		//		Return the [display] value of the edit widget
-		var ew = this.editWidget;
-		return String(ew.get("displayedValue" in ew ? "displayedValue" : "value"));
-	},
-
-	_onKeyPress: function(e){
-		// summary:
-		//		Handler for keypress in the edit box in autoSave mode.
-		// description:
-		//		For autoSave widgets, if Esc/Enter, call cancel/save.
-		// tags:
-		//		private
-
-		if(this.inlineEditBox.autoSave && this.inlineEditBox.editing){
-			if(e.altKey || e.ctrlKey){ return; }
-			// If Enter/Esc pressed, treat as save/cancel.
-			if(e.charOrCode == keys.ESCAPE){
-				event.stop(e);
-				this.cancel(true); // sets editing=false which short-circuits _onBlur processing
-			}else if(e.charOrCode == keys.ENTER && e.target.tagName == "INPUT"){
-				event.stop(e);
-				this._onChange(); // fire _onBlur and then save
+		//		Internal widget used by InlineEditBox, displayed when in editing mode
+		//		to display the editor and maybe save/cancel buttons.  Calling code should
+		//		connect to save/cancel methods to detect when editing is finished
+		//
+		//		Has mainly the same parameters as InlineEditBox, plus these values:
+		//
+		// style: Object
+		//		Set of CSS attributes of display node, to replicate in editor
+		//
+		// value: String
+		//		Value as an HTML string or plain text string, depending on renderAsHTML flag
+
+		templateString: template,
+
+		contextRequire: require,
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			this.messages = i18n.getLocalization("dijit", "common", this.lang);
+			array.forEach(["buttonSave", "buttonCancel"], function(prop){
+				if(!this[prop]){
+					this[prop] = this.messages[prop];
+				}
+			}, this);
+		},
+
+		buildRendering: function(){
+			this.inherited(arguments);
+
+			// Create edit widget in place in the template
+			// TODO: remove getObject() for 2.0
+			var Cls = typeof this.editor == "string" ? (lang.getObject(this.editor) || require(this.editor)) : this.editor;
+
+			// Copy the style from the source
+			// Don't copy ALL properties though, just the necessary/applicable ones.
+			// wrapperStyle/destStyle code is to workaround IE bug where getComputedStyle().fontSize
+			// is a relative value like 200%, rather than an absolute value like 24px, and
+			// the 200% can refer *either* to a setting on the node or it's ancestor (see #11175)
+			var srcStyle = this.sourceStyle,
+				editStyle = "line-height:" + srcStyle.lineHeight + ";",
+				destStyle = domStyle.getComputedStyle(this.domNode);
+			array.forEach(["Weight", "Family", "Size", "Style"], function(prop){
+				var textStyle = srcStyle["font" + prop],
+					wrapperStyle = destStyle["font" + prop];
+				if(wrapperStyle != textStyle){
+					editStyle += "font-" + prop + ":" + srcStyle["font" + prop] + ";";
+				}
+			}, this);
+			array.forEach(["marginTop", "marginBottom", "marginLeft", "marginRight", "position", "left", "top", "right", "bottom", "float", "clear", "display"], function(prop){
+				this.domNode.style[prop] = srcStyle[prop];
+			}, this);
+			var width = this.inlineEditBox.width;
+			if(width == "100%"){
+				// block mode
+				editStyle += "width:100%;";
+				this.domNode.style.display = "block";
+			}else{
+				// inline-block mode
+				editStyle += "width:" + (width + (Number(width) == width ? "px" : "")) + ";";
 			}
+			var editorParams = lang.delegate(this.inlineEditBox.editorParams, {
+				style: editStyle,
+				dir: this.dir,
+				lang: this.lang,
+				textDir: this.textDir
+			});
+			// set the value in onLoadDeferred instead so the widget has time to finish initializing
+			//editorParams[("displayedValue" in Cls.prototype || "_setDisplayedValueAttr" in Cls.prototype) ? "displayedValue" : "value"] = this.value;
+			this.editWidget = new Cls(editorParams, this.editorPlaceholder);
+
+			if(this.inlineEditBox.autoSave){
+				// Remove the save/cancel buttons since saving is done by simply tabbing away or
+				// selecting a value from the drop down list
+				domConstruct.destroy(this.buttonContainer);
+			}
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+
+			var ew = this.editWidget;
+
+			if(this.inlineEditBox.autoSave){
+				this.own(
+					// Selecting a value from a drop down list causes an onChange event and then we save
+					aspect.after(ew, "onChange", lang.hitch(this, "_onChange"), true),
+
+					// ESC and TAB should cancel and save.
+					on(ew, "keydown", lang.hitch(this, "_onKeyDown"))
+				);
+			}else{
+				// If possible, enable/disable save button based on whether the user has changed the value
+				if("intermediateChanges" in ew){
+					ew.set("intermediateChanges", true);
+					this.own(aspect.after(ew, "onChange", lang.hitch(this, "_onIntermediateChange"), true));
+					this.saveButton.set("disabled", true);
+				}
+			}
+		},
+
+		startup: function(){
+			this.editWidget.startup();
+			this.inherited(arguments);
+		},
+
+		_onIntermediateChange: function(/*===== val =====*/){
+			// summary:
+			//		Called for editor widgets that support the intermediateChanges=true flag as a way
+			//		to detect when to enable/disabled the save button
+			this.saveButton.set("disabled", (this.getValue() == this._resetValue) || !this.enableSave());
+		},
+
+		destroy: function(){
+			this.editWidget.destroy(true); // let the parent wrapper widget clean up the DOM
+			this.inherited(arguments);
+		},
+
+		getValue: function(){
+			// summary:
+			//		Return the [display] value of the edit widget
+			var ew = this.editWidget;
+			return String(ew.get(("displayedValue" in ew || "_getDisplayedValueAttr" in ew) ? "displayedValue" : "value"));
+		},
+
+		_onKeyDown: function(e){
+			// summary:
+			//		Handler for keydown in the edit box in autoSave mode.
+			// description:
+			//		For autoSave widgets, if Esc/Enter, call cancel/save.
+			// tags:
+			//		private
+
+			if(this.inlineEditBox.autoSave && this.inlineEditBox.editing){
+				if(e.altKey || e.ctrlKey){
+					return;
+				}
+				// If Enter/Esc pressed, treat as save/cancel.
+				if(e.keyCode == keys.ESCAPE){
+					e.stopPropagation();
+					e.preventDefault();
+					this.cancel(true); // sets editing=false which short-circuits _onBlur processing
+				}else if(e.keyCode == keys.ENTER && e.target.tagName == "INPUT"){
+					e.stopPropagation();
+					e.preventDefault();
+					this._onChange(); // fire _onBlur and then save
+				}
 
-			// _onBlur will handle TAB automatically by allowing
-			// the TAB to change focus before we mess with the DOM: #6227
-			// Expounding by request:
-			// 	The current focus is on the edit widget input field.
-			//	save() will hide and destroy this widget.
-			//	We want the focus to jump from the currently hidden
-			//	displayNode, but since it's hidden, it's impossible to
-			//	unhide it, focus it, and then have the browser focus
-			//	away from it to the next focusable element since each
-			//	of these events is asynchronous and the focus-to-next-element
-			//	is already queued.
-			//	So we allow the browser time to unqueue the move-focus event
-			//	before we do all the hide/show stuff.
-		}
-	},
-
-	_onBlur: function(){
-		// summary:
-		//		Called when focus moves outside the editor
-		// tags:
-		//		private
-
-		this.inherited(arguments);
-		if(this.inlineEditBox.autoSave && this.inlineEditBox.editing){
-			if(this.getValue() == this._resetValue){
-				this.cancel(false);
-			}else if(this.enableSave()){
-				this.save(false);
+				// _onBlur will handle TAB automatically by allowing
+				// the TAB to change focus before we mess with the DOM: #6227
+				// Expounding by request:
+				//	The current focus is on the edit widget input field.
+				//	save() will hide and destroy this widget.
+				//	We want the focus to jump from the currently hidden
+				//	displayNode, but since it's hidden, it's impossible to
+				//	unhide it, focus it, and then have the browser focus
+				//	away from it to the next focusable element since each
+				//	of these events is asynchronous and the focus-to-next-element
+				//	is already queued.
+				//	So we allow the browser time to unqueue the move-focus event
+				//	before we do all the hide/show stuff.
+			}
+		},
+
+		_onBlur: function(){
+			// summary:
+			//		Called when focus moves outside the editor
+			// tags:
+			//		private
+
+			this.inherited(arguments);
+			if(this.inlineEditBox.autoSave && this.inlineEditBox.editing){
+				if(this.getValue() == this._resetValue){
+					this.cancel(false);
+				}else if(this.enableSave()){
+					this.save(false);
+				}
+			}
+		},
+
+		_onChange: function(){
+			// summary:
+			//		Called when the underlying widget fires an onChange event,
+			//		such as when the user selects a value from the drop down list of a ComboBox,
+			//		which means that the user has finished entering the value and we should save.
+			// tags:
+			//		private
+
+			if(this.inlineEditBox.autoSave && this.inlineEditBox.editing && this.enableSave()){
+				fm.focus(this.inlineEditBox.displayNode); // fires _onBlur which will save the formatted value
+			}
+		},
+
+		enableSave: function(){
+			// summary:
+			//		User overridable function returning a Boolean to indicate
+			//		if the Save button should be enabled or not - usually due to invalid conditions
+			// tags:
+			//		extension
+			return this.editWidget.isValid ? this.editWidget.isValid() : true;
+		},
+
+		focus: function(){
+			// summary:
+			//		Focus the edit widget.
+			// tags:
+			//		protected
+
+			this.editWidget.focus();
+
+			if(this.editWidget.focusNode){
+				// IE can take 30ms to report the focus event, but focus manager needs to know before a 0ms timeout.
+				fm._onFocusNode(this.editWidget.focusNode);
+
+				if(this.editWidget.focusNode.tagName == "INPUT"){
+					this.defer(function(){
+						_TextBoxMixin.selectInputText(this.editWidget.focusNode);
+					});
+				}
 			}
 		}
-	},
+	});
 
-	_onChange: function(){
-		// summary:
-		//		Called when the underlying widget fires an onChange event,
-		//		such as when the user selects a value from the drop down list of a ComboBox,
-		//		which means that the user has finished entering the value and we should save.
-		// tags:
-		//		private
-
-		if(this.inlineEditBox.autoSave && this.inlineEditBox.editing && this.enableSave()){
-			fm.focus(this.inlineEditBox.displayNode); // fires _onBlur which will save the formatted value
-		}
-	},
 
-	enableSave: function(){
+	var InlineEditBox = declare("dijit.InlineEditBox" + (has("dojo-bidi") ? "_NoBidi" : ""), _Widget, {
 		// summary:
-		//		User overridable function returning a Boolean to indicate
-		// 		if the Save button should be enabled or not - usually due to invalid conditions
-		// tags:
-		//		extension
-		return (
-			this.editWidget.isValid
-			? this.editWidget.isValid()
-			: true
-		);
-	},
-
-	focus: function(){
-		// summary:
-		//		Focus the edit widget.
-		// tags:
-		//		protected
-
-		this.editWidget.focus();
-		setTimeout(lang.hitch(this, function(){
-			if(this.editWidget.focusNode && this.editWidget.focusNode.tagName == "INPUT"){
-				_TextBoxMixin.selectInputText(this.editWidget.focusNode);
+		//		An element with in-line edit capabilities
+		//
+		// description:
+		//		Behavior for an existing node (`<p>`, `<div>`, `<span>`, etc.) so that
+		//		when you click it, an editor shows up in place of the original
+		//		text.  Optionally, Save and Cancel button are displayed below the edit widget.
+		//		When Save is clicked, the text is pulled from the edit
+		//		widget and redisplayed and the edit widget is again hidden.
+		//		By default a plain Textarea widget is used as the editor (or for
+		//		inline values a TextBox), but you can specify an editor such as
+		//		dijit.Editor (for editing HTML) or a Slider (for adjusting a number).
+		//		An edit widget must support the following API to be used:
+		//
+		//		- displayedValue or value as initialization parameter,
+		//			and available through set('displayedValue') / set('value')
+		//		- void focus()
+		//		- DOM-node focusNode = node containing editable text
+
+		// editing: [readonly] Boolean
+		//		Is the node currently in edit mode?
+		editing: false,
+
+		// autoSave: Boolean
+		//		Changing the value automatically saves it; don't have to push save button
+		//		(and save button isn't even displayed)
+		autoSave: true,
+
+		// buttonSave: String
+		//		Save button label
+		buttonSave: "",
+
+		// buttonCancel: String
+		//		Cancel button label
+		buttonCancel: "",
+
+		// renderAsHtml: Boolean
+		//		Set this to true if the specified Editor's value should be interpreted as HTML
+		//		rather than plain text (ex: `dijit.Editor`)
+		renderAsHtml: false,
+
+		// editor: String|Function
+		//		MID (ex: "dijit/form/TextBox") or constructor for editor widget
+		editor: TextBox,
+
+		// editorWrapper: String|Function
+		//		Class name (or reference to the Class) for widget that wraps the editor widget, displaying save/cancel
+		//		buttons.
+		editorWrapper: InlineEditor,
+
+		// editorParams: Object
+		//		Set of parameters for editor, like {required: true}
+		editorParams: {},
+
+		// disabled: Boolean
+		//		If true, clicking the InlineEditBox to edit it will have no effect.
+		disabled: false,
+
+		onChange: function(/*===== value =====*/){
+			// summary:
+			//		Set this handler to be notified of changes to value.
+			// tags:
+			//		callback
+		},
+
+		onCancel: function(){
+			// summary:
+			//		Set this handler to be notified when editing is cancelled.
+			// tags:
+			//		callback
+		},
+
+		// width: String
+		//		Width of editor.  By default it's width=100% (ie, block mode).
+		width: "100%",
+
+		// value: String
+		//		The display value of the widget in read-only mode
+		value: "",
+
+		// noValueIndicator: [const] String
+		//		The text that gets displayed when there is no value (so that the user has a place to click to edit)
+		noValueIndicator: has("ie") <= 6 ? // font-family needed on IE6 but it messes up IE8
+			"<span style='font-family: wingdings; text-decoration: underline;'>    &#x270d;    </span>" :
+			"<span style='text-decoration: underline;'>    &#x270d;    </span>", //   ==  
+
+		constructor: function(/*===== params, srcNodeRef =====*/){
+			// summary:
+			//		Create the widget.
+			// params: Object|null
+			//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+			//		and functions, typically callbacks like onClick.
+			//		The hash can contain any of the widget's properties, excluding read-only properties.
+			// srcNodeRef: DOMNode|String?
+			//		If a srcNodeRef (DOM node) is specified:
+			//
+			//		- use srcNodeRef.innerHTML as my value
+			//		- replace srcNodeRef with my generated DOM tree
+
+			this.editorParams = {};
+		},
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+
+			// save pointer to original source node, since Widget nulls-out srcNodeRef
+			this.displayNode = this.srcNodeRef;
+
+			// connect handlers to the display node
+			this.own(
+				on(this.displayNode, a11yclick, lang.hitch(this, "_onClick")),
+				on(this.displayNode, "mouseover, focus", lang.hitch(this, "_onMouseOver")),
+				on(this.displayNode, "mouseout, blur", lang.hitch(this, "_onMouseOut"))
+			);
+
+			this.displayNode.setAttribute("role", "button");
+			if(!this.displayNode.getAttribute("tabIndex")){
+				this.displayNode.setAttribute("tabIndex", 0);
 			}
-		}), 0);
-	}
-});
-
 
-var InlineEditBox = declare("dijit.InlineEditBox", _Widget, {
-	// summary:
-	//		An element with in-line edit capabilities
-	//
-	// description:
-	//		Behavior for an existing node (`<p>`, `<div>`, `<span>`, etc.) so that
-	// 		when you click it, an editor shows up in place of the original
-	//		text.  Optionally, Save and Cancel button are displayed below the edit widget.
-	//		When Save is clicked, the text is pulled from the edit
-	//		widget and redisplayed and the edit widget is again hidden.
-	//		By default a plain Textarea widget is used as the editor (or for
-	//		inline values a TextBox), but you can specify an editor such as
-	//		dijit.Editor (for editing HTML) or a Slider (for adjusting a number).
-	//		An edit widget must support the following API to be used:
-	//			- displayedValue or value as initialization parameter,
-	//			and available through set('displayedValue') / set('value')
-	//			- void focus()
-	//			- DOM-node focusNode = node containing editable text
-
-	// editing: [readonly] Boolean
-	//		Is the node currently in edit mode?
-	editing: false,
-
-	// autoSave: Boolean
-	//		Changing the value automatically saves it; don't have to push save button
-	//		(and save button isn't even displayed)
-	autoSave: true,
-
-	// buttonSave: String
-	//		Save button label
-	buttonSave: "",
-
-	// buttonCancel: String
-	//		Cancel button label
-	buttonCancel: "",
-
-	// renderAsHtml: Boolean
-	//		Set this to true if the specified Editor's value should be interpreted as HTML
-	//		rather than plain text (ex: `dijit.Editor`)
-	renderAsHtml: false,
-
-	// editor: String|Function
-	//		Class name (or reference to the Class) for Editor widget
-	editor: TextBox,
-
-	// editorWrapper: String|Function
-	//		Class name (or reference to the Class) for widget that wraps the editor widget, displaying save/cancel
-	//		buttons.
-	editorWrapper: InlineEditor,
-
-	// editorParams: Object
-	//		Set of parameters for editor, like {required: true}
-	editorParams: {},
-
-	// disabled: Boolean
-	//		If true, clicking the InlineEditBox to edit it will have no effect.
-	disabled: false,
-
-	onChange: function(/*===== value =====*/){
-		// summary:
-		//		Set this handler to be notified of changes to value.
-		// tags:
-		//		callback
-	},
-
-	onCancel: function(){
-		// summary:
-		//		Set this handler to be notified when editing is cancelled.
-		// tags:
-		//		callback
-	},
-
-	// width: String
-	//		Width of editor.  By default it's width=100% (ie, block mode).
-	width: "100%",
-
-	// value: String
-	//		The display value of the widget in read-only mode
-	value: "",
-
-	// noValueIndicator: [const] String
-	//		The text that gets displayed when there is no value (so that the user has a place to click to edit)
-	noValueIndicator: has("ie") <= 6 ?	// font-family needed on IE6 but it messes up IE8
-		"<span style='font-family: wingdings; text-decoration: underline;'>    &#x270d;    </span>" :
-		"<span style='text-decoration: underline;'>    &#x270d;    </span>",	// 	//   ==  
-
-	constructor: function(){
-		// summary:
-		//		Sets up private arrays etc.
-		// tags:
-		//		private
-		this.editorParams = {};
-	},
-
-	postMixInProperties: function(){
-		this.inherited(arguments);
-
-		// save pointer to original source node, since Widget nulls-out srcNodeRef
-		this.displayNode = this.srcNodeRef;
-
-		// connect handlers to the display node
-		var events = {
-			ondijitclick: "_onClick",
-			onmouseover: "_onMouseOver",
-			onmouseout: "_onMouseOut",
-			onfocus: "_onMouseOver",
-			onblur: "_onMouseOut"
-		};
-		for(var name in events){
-			this.connect(this.displayNode, name, events[name]);
-		}
-		this.displayNode.setAttribute("role", "button");
-		if(!this.displayNode.getAttribute("tabIndex")){
-			this.displayNode.setAttribute("tabIndex", 0);
-		}
-
-		if(!this.value && !("value" in this.params)){ // "" is a good value if specified directly so check params){
-			this.value = lang.trim(this.renderAsHtml ? this.displayNode.innerHTML :
-				(this.displayNode.innerText||this.displayNode.textContent||""));
-		}
-		if(!this.value){
-			this.displayNode.innerHTML = this.noValueIndicator;
-		}
-
-		domClass.add(this.displayNode, 'dijitInlineEditBoxDisplayMode');
-	},
+			if(!this.value && !("value" in this.params)){ // "" is a good value if specified directly so check params){
+				this.value = lang.trim(this.renderAsHtml ? this.displayNode.innerHTML :
+					(this.displayNode.innerText || this.displayNode.textContent || ""));
+			}
+			if(!this.value){
+				this.displayNode.innerHTML = this.noValueIndicator;
+			}
 
-	setDisabled: function(/*Boolean*/ disabled){
-		// summary:
-		//		Deprecated.   Use set('disabled', ...) instead.
-		// tags:
-		//		deprecated
-		kernel.deprecated("dijit.InlineEditBox.setDisabled() is deprecated.  Use set('disabled', bool) instead.", "", "2.0");
-		this.set('disabled', disabled);
-	},
-
-	_setDisabledAttr: function(/*Boolean*/ disabled){
-		// summary:
-		//		Hook to make set("disabled", ...) work.
-		//		Set disabled state of widget.
-		this.domNode.setAttribute("aria-disabled", disabled);
-		if(disabled){
-			this.displayNode.removeAttribute("tabIndex");
-		}else{
-			this.displayNode.setAttribute("tabIndex", 0);
-		}
-		domClass.toggle(this.displayNode, "dijitInlineEditBoxDisplayModeDisabled", disabled);
-		this._set("disabled", disabled);
-	},
+			domClass.add(this.displayNode, 'dijitInlineEditBoxDisplayMode');
+		},
+
+		setDisabled: function(/*Boolean*/ disabled){
+			// summary:
+			//		Deprecated.   Use set('disabled', ...) instead.
+			// tags:
+			//		deprecated
+			kernel.deprecated("dijit.InlineEditBox.setDisabled() is deprecated.  Use set('disabled', bool) instead.", "", "2.0");
+			this.set('disabled', disabled);
+		},
+
+		_setDisabledAttr: function(/*Boolean*/ disabled){
+			// summary:
+			//		Hook to make set("disabled", ...) work.
+			//		Set disabled state of widget.
+			this.domNode.setAttribute("aria-disabled", disabled ? "true" : "false");
+			if(disabled){
+				this.displayNode.removeAttribute("tabIndex");
+			}else{
+				this.displayNode.setAttribute("tabIndex", 0);
+			}
+			domClass.toggle(this.displayNode, "dijitInlineEditBoxDisplayModeDisabled", disabled);
+			this._set("disabled", disabled);
+		},
+
+		_onMouseOver: function(){
+			// summary:
+			//		Handler for onmouseover and onfocus event.
+			// tags:
+			//		private
+			if(!this.disabled){
+				domClass.add(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
+			}
+		},
+
+		_onMouseOut: function(){
+			// summary:
+			//		Handler for onmouseout and onblur event.
+			// tags:
+			//		private
+			domClass.remove(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
+		},
+
+		_onClick: function(/*Event*/ e){
+			// summary:
+			//		Handler for onclick event.
+			// tags:
+			//		private
+			if(this.disabled){
+				return;
+			}
+			if(e){
+				e.stopPropagation();
+				e.preventDefault();
+			}
+			this._onMouseOut();
 
-	_onMouseOver: function(){
-		// summary:
-		//		Handler for onmouseover and onfocus event.
-		// tags:
-		//		private
-		if(!this.disabled){
-			domClass.add(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
-		}
-	},
+			// Since FF gets upset if you move a node while in an event handler for that node...
+			this.defer("edit");
+		},
 
-	_onMouseOut: function(){
-		// summary:
-		//		Handler for onmouseout and onblur event.
-		// tags:
-		//		private
-		domClass.remove(this.displayNode, "dijitInlineEditBoxDisplayModeHover");
-	},
+		edit: function(){
+			// summary:
+			//		Display the editor widget in place of the original (read only) markup.
+			// tags:
+			//		private
 
-	_onClick: function(/*Event*/ e){
-		// summary:
-		//		Handler for onclick event.
-		// tags:
-		//		private
-		if(this.disabled){ return; }
-		if(e){ event.stop(e); }
-		this._onMouseOut();
-
-		// Since FF gets upset if you move a node while in an event handler for that node...
-		setTimeout(lang.hitch(this, "edit"), 0);
-	},
-
-	edit: function(){
-		// summary:
-		//		Display the editor widget in place of the original (read only) markup.
-		// tags:
-		//		private
-
-		if(this.disabled || this.editing){ return; }
-		this._set('editing', true);
-
-		// save some display node values that can be restored later
-		this._savedPosition = domStyle.get(this.displayNode, "position") || "static";
-		this._savedOpacity = domStyle.get(this.displayNode, "opacity") || "1";
-		this._savedTabIndex = domAttr.get(this.displayNode, "tabIndex") || "0";
-
-		if(this.wrapperWidget){
-			var ew = this.wrapperWidget.editWidget;
-			ew.set("displayedValue" in ew ? "displayedValue" : "value", this.value);
-		}else{
-			// Placeholder for edit widget
-			// Put place holder (and eventually editWidget) before the display node so that it's positioned correctly
-			// when Calendar dropdown appears, which happens automatically on focus.
-			var placeholder = domConstruct.create("span", null, this.domNode, "before");
-
-			// Create the editor wrapper (the thing that holds the editor widget and the save/cancel buttons)
-			var ewc = typeof this.editorWrapper == "string" ? lang.getObject(this.editorWrapper) : this.editorWrapper;
-			this.wrapperWidget = new ewc({
-				value: this.value,
-				buttonSave: this.buttonSave,
-				buttonCancel: this.buttonCancel,
-				dir: this.dir,
-				lang: this.lang,
-				tabIndex: this._savedTabIndex,
-				editor: this.editor,
-				inlineEditBox: this,
-				sourceStyle: domStyle.getComputedStyle(this.displayNode),
-				save: lang.hitch(this, "save"),
-				cancel: lang.hitch(this, "cancel"),
-				textDir: this.textDir
-			}, placeholder);
-			if(!this._started){
-				this.startup();
+			if(this.disabled || this.editing){
+				return;
 			}
-		}
-		var ww = this.wrapperWidget;
-
-		// to avoid screen jitter, we first create the editor with position:absolute, visibility:hidden,
-		// and then when it's finished rendering, we switch from display mode to editor
-		// position:absolute releases screen space allocated to the display node
-		// opacity:0 is the same as visibility:hidden but is still focusable
-		// visiblity:hidden removes focus outline
-
-		domStyle.set(this.displayNode, { position: "absolute", opacity: "0" }); // makes display node invisible, display style used for focus-ability
-		domStyle.set(ww.domNode, { position: this._savedPosition, visibility: "visible", opacity: "1" });
-		domAttr.set(this.displayNode, "tabIndex", "-1"); // needed by WebKit for TAB from editor to skip displayNode
-
-		// Replace the display widget with edit widget, leaving them both displayed for a brief time so that
-		// focus can be shifted without incident.  (browser may needs some time to render the editor.)
-		setTimeout(lang.hitch(ww, function(){
-			this.focus(); // both nodes are showing, so we can switch focus safely
-			this._resetValue = this.getValue();
-		}), 0);
-	},
-
-	_onBlur: function(){
-		// summary:
-		//		Called when focus moves outside the InlineEditBox.
-		//		Performs garbage collection.
-		// tags:
-		//		private
-
-		this.inherited(arguments);
-		if(!this.editing){
-			/* causes IE focus problems, see TooltipDialog_a11y.html...
-			setTimeout(lang.hitch(this, function(){
-				if(this.wrapperWidget){
-					this.wrapperWidget.destroy();
-					delete this.wrapperWidget;
+			this._set('editing', true);
+
+			// save some display node values that can be restored later
+			this._savedTabIndex = domAttr.get(this.displayNode, "tabIndex") || "0";
+
+			if(!this.wrapperWidget){
+				// Placeholder for edit widget
+				// Put place holder (and eventually editWidget) before the display node so that it's positioned correctly
+				// when Calendar dropdown appears, which happens automatically on focus.
+				var placeholder = domConstruct.create("span", null, this.domNode, "before");
+
+				// Create the editor wrapper (the thing that holds the editor widget and the save/cancel buttons)
+				var Ewc = typeof this.editorWrapper == "string" ? lang.getObject(this.editorWrapper) : this.editorWrapper;
+				this.wrapperWidget = new Ewc({
+					value: this.value,
+					buttonSave: this.buttonSave,
+					buttonCancel: this.buttonCancel,
+					dir: this.dir,
+					lang: this.lang,
+					tabIndex: this._savedTabIndex,
+					editor: this.editor,
+					inlineEditBox: this,
+					sourceStyle: domStyle.getComputedStyle(this.displayNode),
+					save: lang.hitch(this, "save"),
+					cancel: lang.hitch(this, "cancel"),
+					textDir: this.textDir
+				}, placeholder);
+				if(!this.wrapperWidget._started){
+					this.wrapperWidget.startup();
 				}
-			}), 0);
-			*/
-		}
-	},
-
-	destroy: function(){
-		if(this.wrapperWidget && !this.wrapperWidget._destroyed){
-			this.wrapperWidget.destroy();
-			delete this.wrapperWidget;
-		}
-		this.inherited(arguments);
-	},
-
-	_showText: function(/*Boolean*/ focus){
-		// summary:
-		//		Revert to display mode, and optionally focus on display node
-		// tags:
-		//		private
-
-		var ww = this.wrapperWidget;
-		domStyle.set(ww.domNode, { position: "absolute", visibility: "hidden", opacity: "0" }); // hide the editor from mouse/keyboard events
-		domStyle.set(this.displayNode, { position: this._savedPosition, opacity: this._savedOpacity }); // make the original text visible
-		domAttr.set(this.displayNode, "tabIndex", this._savedTabIndex);
-		if(focus){
-			fm.focus(this.displayNode);
-		}
-	},
-
-	save: function(/*Boolean*/ focus){
-		// summary:
-		//		Save the contents of the editor and revert to display mode.
-		// focus: Boolean
-		//		Focus on the display mode text
-		// tags:
-		//		private
-
-		if(this.disabled || !this.editing){ return; }
-		this._set('editing', false);
-
-		var ww = this.wrapperWidget;
-		var value = ww.getValue();
-		this.set('value', value); // display changed, formatted value
-
-		this._showText(focus); // set focus as needed
-	},
+				if(!this._started){
+					this.startup();
+				}
+			}
+			var ww = this.wrapperWidget;
+
+			// to avoid screen jitter, we first create the editor with position: absolute, visibility: hidden,
+			// and then when it's finished rendering, we switch from display mode to editor
+			// position: absolute releases screen space allocated to the display node
+			// opacity:0 is the same as visibility: hidden but is still focusable
+			// visibility: hidden removes focus outline
+
+			domClass.add(this.displayNode, "dijitOffScreen");
+			domClass.remove(ww.domNode, "dijitOffScreen");
+			domStyle.set(ww.domNode, { visibility: "visible" });
+			domAttr.set(this.displayNode, "tabIndex", "-1"); // needed by WebKit for TAB from editor to skip displayNode
+
+			// After edit widget has finished initializing (in particular need to wait for dijit.Editor),
+			// or immediately if there is no onLoadDeferred Deferred,
+			// replace the display widget with edit widget, leaving them both displayed for a brief time so that
+			// focus can be shifted without incident.
+			var ew = ww.editWidget;
+			var self = this;
+			when(ew.onLoadDeferred, lang.hitch(ww, function(){
+				// set value again in case the edit widget's value is just now valid
+				ew.set(("displayedValue" in ew || "_setDisplayedValueAttr" in ew) ? "displayedValue" : "value", self.value);
+				this.defer(function(){ // defer needed so that the change of focus doesn't happen on mousedown which also sets focus
+					// the saveButton should start out disabled in most cases but the above set could have fired onChange
+					ww.saveButton.set("disabled", "intermediateChanges" in ew);
+					this.focus(); // both nodes are showing, so we can switch focus safely
+					this._resetValue = this.getValue();
+				});
+			}));
+		},
+
+		_onBlur: function(){
+			// summary:
+			//		Called when focus moves outside the InlineEditBox.
+			//		Performs garbage collection.
+			// tags:
+			//		private
+
+			this.inherited(arguments);
+			if(!this.editing){
+				/* causes IE focus problems, see TooltipDialog_a11y.html...
+				 this.defer(function(){
+				 if(this.wrapperWidget){
+				 this.wrapperWidget.destroy();
+				 delete this.wrapperWidget;
+				 }
+				 });
+				 */
+			}
+		},
 
-	setValue: function(/*String*/ val){
-		// summary:
-		//		Deprecated.   Use set('value', ...) instead.
-		// tags:
-		//		deprecated
-		kernel.deprecated("dijit.InlineEditBox.setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
-		return this.set("value", val);
-	},
-
-	_setValueAttr: function(/*String*/ val){
-		// summary:
-		// 		Hook to make set("value", ...) work.
-		//		Inserts specified HTML value into this node, or an "input needed" character if node is blank.
+		destroy: function(){
+			if(this.wrapperWidget && !this.wrapperWidget._destroyed){
+				this.wrapperWidget.destroy();
+				delete this.wrapperWidget;
+			}
+			this.inherited(arguments);
+		},
+
+		_showText: function(/*Boolean*/ focus){
+			// summary:
+			//		Revert to display mode, and optionally focus on display node
+			// tags:
+			//		private
+
+			var ww = this.wrapperWidget;
+			domStyle.set(ww.domNode, { visibility: "hidden" }); // hide the editor from mouse/keyboard events
+			domClass.add(ww.domNode, "dijitOffScreen");
+			domClass.remove(this.displayNode, "dijitOffScreen");
+			domAttr.set(this.displayNode, "tabIndex", this._savedTabIndex);
+			if(focus){
+				fm.focus(this.displayNode);
+			}
+		},
+
+		save: function(/*Boolean*/ focus){
+			// summary:
+			//		Save the contents of the editor and revert to display mode.
+			// focus: Boolean
+			//		Focus on the display mode text
+			// tags:
+			//		private
+
+			if(this.disabled || !this.editing){
+				return;
+			}
+			this._set('editing', false);
+
+			var ww = this.wrapperWidget;
+			var value = ww.getValue();
+			this.set('value', value); // display changed, formatted value
+
+			this._showText(focus); // set focus as needed
+		},
+
+		setValue: function(/*String*/ val){
+			// summary:
+			//		Deprecated.   Use set('value', ...) instead.
+			// tags:
+			//		deprecated
+			kernel.deprecated("dijit.InlineEditBox.setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
+			return this.set("value", val);
+		},
+
+		_setValueAttr: function(/*String*/ val){
+			// summary:
+			//		Hook to make set("value", ...) work.
+			//		Inserts specified HTML value into this node, or an "input needed" character if node is blank.
+
+			val = lang.trim(val);
+			var renderVal = this.renderAsHtml ? val : val.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """).replace(/\n/g, "<br>");
+			this.displayNode.innerHTML = renderVal || this.noValueIndicator;
+			this._set("value", val);
+
+			if(this._started){
+				// tell the world that we have changed
+				this.defer(function(){
+					this.onChange(val);
+				}); // defer prevents browser freeze for long-running event handlers
+			}
+		},
+
+		getValue: function(){
+			// summary:
+			//		Deprecated.   Use get('value') instead.
+			// tags:
+			//		deprecated
+			kernel.deprecated("dijit.InlineEditBox.getValue() is deprecated.  Use get('value') instead.", "", "2.0");
+			return this.get("value");
+		},
+
+		cancel: function(/*Boolean*/ focus){
+			// summary:
+			//		Revert to display mode, discarding any changes made in the editor
+			// tags:
+			//		private
+
+			if(this.disabled || !this.editing){
+				return;
+			}
+			this._set('editing', false);
 
-		val = lang.trim(val);
-		var renderVal = this.renderAsHtml ? val : val.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """).replace(/\n/g, "<br>");
-		this.displayNode.innerHTML = renderVal || this.noValueIndicator;
-		this._set("value", val);
+			// tell the world that we have no changes
+			this.defer("onCancel"); // defer prevents browser freeze for long-running event handlers
 
-		if(this._started){
-			// tell the world that we have changed
-			setTimeout(lang.hitch(this, "onChange", val), 0); // setTimeout prevents browser freeze for long-running event handlers
+			this._showText(focus);
 		}
-		// contextual (auto) text direction depends on the text value
-		if(this.textDir == "auto"){
-			this.applyTextDir(this.displayNode, this.displayNode.innerText);
-		}
-	},
-
-	getValue: function(){
-		// summary:
-		//		Deprecated.   Use get('value') instead.
-		// tags:
-		//		deprecated
-		kernel.deprecated("dijit.InlineEditBox.getValue() is deprecated.  Use get('value') instead.", "", "2.0");
-		return this.get("value");
-	},
-
-	cancel: function(/*Boolean*/ focus){
-		// summary:
-		//		Revert to display mode, discarding any changes made in the editor
-		// tags:
-		//		private
+	});
 
-		if(this.disabled || !this.editing){ return; }
-		this._set('editing', false);
+	if(has("dojo-bidi")){
+		InlineEditBox = declare("dijit.InlineEditBox", InlineEditBox, {
+			_setValueAttr: function(){
+				this.inherited(arguments);
+				this.applyTextDir(this.displayNode);
+			}
+		});
+	}
 
-		// tell the world that we have no changes
-		setTimeout(lang.hitch(this, "onCancel"), 0); // setTimeout prevents browser freeze for long-running event handlers
+	InlineEditBox._InlineEditor = InlineEditor;	// for monkey patching
 
-		this._showText(focus);
-	},
-	_setTextDirAttr: function(/*String*/ textDir){
-		// summary:
-		//		Setter for textDir.
-		// description:
-		//		Users shouldn't call this function; they should be calling
-		//		set('textDir', value)
-		// tags:
-		//		private
-		if(!this._created || this.textDir != textDir){
-			this._set("textDir", textDir);
-			this.applyTextDir(this.displayNode, this.displayNode.innerText);
-			this.displayNode.align = this.dir == "rtl" ? "right" : "left"; //fix the text alignment
-		}
-   }
+	return InlineEditBox;
 });
-
-InlineEditBox._InlineEditor = InlineEditor;	// for monkey patching
-
-return InlineEditBox;
-});
\ No newline at end of file
diff --git a/dijit/LICENSE b/dijit/LICENSE
index aa6b39f..b1ddd34 100644
--- a/dijit/LICENSE
+++ b/dijit/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2011, The Dojo Foundation
+Copyright (c) 2005-2013, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/dijit/Menu.js b/dijit/Menu.js
index 1cbd6c8..7fd2258 100644
--- a/dijit/Menu.js
+++ b/dijit/Menu.js
@@ -2,320 +2,363 @@ define([
 	"require",
 	"dojo/_base/array", // array.forEach
 	"dojo/_base/declare", // declare
-	"dojo/_base/event", // event.stop
 	"dojo/dom", // dom.byId dom.isDescendant
 	"dojo/dom-attr", // domAttr.get domAttr.set domAttr.has domAttr.remove
 	"dojo/dom-geometry", // domStyle.getComputedStyle domGeometry.position
 	"dojo/dom-style", // domStyle.getComputedStyle
-	"dojo/_base/kernel",
-	"dojo/keys",	// keys.F10
+	"dojo/keys", // keys.F10
 	"dojo/_base/lang", // lang.hitch
 	"dojo/on",
-	"dojo/_base/sniff", // has("ie"), has("quirks")
-	"dojo/_base/window", // win.body win.doc.documentElement win.doc.frames win.withGlobal
+	"dojo/sniff", // has("ie"), has("quirks")
+	"dojo/_base/window", // win.body
 	"dojo/window", // winUtils.get
 	"./popup",
 	"./DropDownMenu",
 	"dojo/ready"
-], function(require, array, declare, event, dom, domAttr, domGeometry, domStyle, kernel, keys, lang, on,
-			has, win, winUtils, pm, DropDownMenu, ready){
-
-/*=====
-	var DropDownMenu = dijit.DropDownMenu;
-=====*/
-
-// module:
-//		dijit/Menu
-// summary:
-//		Includes dijit.Menu widget and base class dijit._MenuBase
-
-// Back compat w/1.6, remove for 2.0
-if(!kernel.isAsync){
-	ready(0, function(){
-		var requires = ["dijit/MenuItem", "dijit/PopupMenuItem", "dijit/CheckedMenuItem", "dijit/MenuSeparator"];
-		require(requires);	// use indirection so modules not rolled into a build
-	});
-}
-
-return declare("dijit.Menu", DropDownMenu, {
-	// summary:
-	//		A context menu you can assign to multiple elements
-
-	constructor: function(){
-		this._bindings = [];
-	},
-
-	// targetNodeIds: [const] String[]
-	//		Array of dom node ids of nodes to attach to.
-	//		Fill this with nodeIds upon widget creation and it becomes context menu for those nodes.
-	targetNodeIds: [],
-
-	// contextMenuForWindow: [const] Boolean
-	//		If true, right clicking anywhere on the window will cause this context menu to open.
-	//		If false, must specify targetNodeIds.
-	contextMenuForWindow: false,
-
-	// leftClickToOpen: [const] Boolean
-	//		If true, menu will open on left click instead of right click, similar to a file menu.
-	leftClickToOpen: false,
-
-	// refocus: Boolean
-	// 		When this menu closes, re-focus the element which had focus before it was opened.
-	refocus: true,
-
-	postCreate: function(){
-		if(this.contextMenuForWindow){
-			this.bindDomNode(win.body());
-		}else{
-			// TODO: should have _setTargetNodeIds() method to handle initialization and a possible
-			// later set('targetNodeIds', ...) call.  There's also a problem that targetNodeIds[]
-			// gets stale after calls to bindDomNode()/unBindDomNode() as it still is just the original list (see #9610)
-			array.forEach(this.targetNodeIds, this.bindDomNode, this);
-		}
-		this.inherited(arguments);
-	},
-
-	// thanks burstlib!
-	_iframeContentWindow: function(/* HTMLIFrameElement */iframe_el){
-		// summary:
-		//		Returns the window reference of the passed iframe
-		// tags:
-		//		private
-		return winUtils.get(this._iframeContentDocument(iframe_el)) ||
-			// Moz. TODO: is this available when defaultView isn't?
-			this._iframeContentDocument(iframe_el)['__parent__'] ||
-			(iframe_el.name && win.doc.frames[iframe_el.name]) || null;	//	Window
-	},
-
-	_iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
-		// summary:
-		//		Returns a reference to the document object inside iframe_el
-		// tags:
-		//		protected
-		return iframe_el.contentDocument // W3
-			|| (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
-			|| (iframe_el.name && win.doc.frames[iframe_el.name] && win.doc.frames[iframe_el.name].document)
-			|| null;	//	HTMLDocument
-	},
-
-	bindDomNode: function(/*String|DomNode*/ node){
-		// summary:
-		//		Attach menu to given node
-		node = dom.byId(node);
-
-		var cn;	// Connect node
-
-		// Support context menus on iframes.  Rather than binding to the iframe itself we need
-		// to bind to the <body> node inside the iframe.
-		if(node.tagName.toLowerCase() == "iframe"){
-			var iframe = node,
-				window = this._iframeContentWindow(iframe);
-			cn = win.withGlobal(window, win.body);
-		}else{
-
-			// To capture these events at the top level, attach to <html>, not <body>.
-			// Otherwise right-click context menu just doesn't work.
-			cn = (node == win.body() ? win.doc.documentElement : node);
-		}
+], function(require, array, declare, dom, domAttr, domGeometry, domStyle, keys, lang, on, has, win, winUtils, pm, DropDownMenu, ready){
 
+	// module:
+	//		dijit/Menu
 
-		// "binding" is the object to track our connection to the node (ie, the parameter to bindDomNode())
-		var binding = {
-			node: node,
-			iframe: iframe
-		};
-
-		// Save info about binding in _bindings[], and make node itself record index(+1) into
-		// _bindings[] array.  Prefix w/_dijitMenu to avoid setting an attribute that may
-		// start with a number, which fails on FF/safari.
-		domAttr.set(node, "_dijitMenu" + this.id, this._bindings.push(binding));
-
-		// Setup the connections to monitor click etc., unless we are connecting to an iframe which hasn't finished
-		// loading yet, in which case we need to wait for the onload event first, and then connect
-		// On linux Shift-F10 produces the oncontextmenu event, but on Windows it doesn't, so
-		// we need to monitor keyboard events in addition to the oncontextmenu event.
-		var doConnects = lang.hitch(this, function(cn){
-			return [
-				// TODO: when leftClickToOpen is true then shouldn't space/enter key trigger the menu,
-				// rather than shift-F10?
-				on(cn, this.leftClickToOpen ? "click" : "contextmenu", lang.hitch(this, function(evt){
-					// Schedule context menu to be opened unless it's already been scheduled from onkeydown handler
-					event.stop(evt);
-					this._scheduleOpen(evt.target, iframe, {x: evt.pageX, y: evt.pageY});
-				})),
-				on(cn, "keydown", lang.hitch(this, function(evt){
-					if(evt.shiftKey && evt.keyCode == keys.F10){
-						event.stop(evt);
-						this._scheduleOpen(evt.target, iframe);	// no coords - open near target node
-					}
-				}))
-			];
+	// Back compat w/1.6, remove for 2.0
+	if(has("dijit-legacy-requires")){
+		ready(0, function(){
+			var requires = ["dijit/MenuItem", "dijit/PopupMenuItem", "dijit/CheckedMenuItem", "dijit/MenuSeparator"];
+			require(requires);	// use indirection so modules not rolled into a build
 		});
-		binding.connects = cn ? doConnects(cn) : [];
-
-		if(iframe){
-			// Setup handler to [re]bind to the iframe when the contents are initially loaded,
-			// and every time the contents change.
-			// Need to do this b/c we are actually binding to the iframe's <body> node.
-			// Note: can't use connect.connect(), see #9609.
-
-			binding.onloadHandler = lang.hitch(this, function(){
-				// want to remove old connections, but IE throws exceptions when trying to
-				// access the <body> node because it's already gone, or at least in a state of limbo
+	}
 
-				var window = this._iframeContentWindow(iframe);
-					cn = win.withGlobal(window, win.body);
-				binding.connects = doConnects(cn);
-			});
-			if(iframe.addEventListener){
-				iframe.addEventListener("load", binding.onloadHandler, false);
+	return declare("dijit.Menu", DropDownMenu, {
+		// summary:
+		//		A context menu you can assign to multiple elements
+
+		constructor: function(/*===== params, srcNodeRef =====*/){
+			// summary:
+			//		Create the widget.
+			// params: Object|null
+			//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+			//		and functions, typically callbacks like onClick.
+			//		The hash can contain any of the widget's properties, excluding read-only properties.
+			// srcNodeRef: DOMNode|String?
+			//		If a srcNodeRef (DOM node) is specified:
+			//
+			//		- use srcNodeRef.innerHTML as my contents
+			//		- replace srcNodeRef with my generated DOM tree
+
+			this._bindings = [];
+		},
+
+		// targetNodeIds: [const] String[]
+		//		Array of dom node ids of nodes to attach to.
+		//		Fill this with nodeIds upon widget creation and it becomes context menu for those nodes.
+		targetNodeIds: [],
+
+		// selector: String?
+		//		CSS expression to apply this Menu to descendants of targetNodeIds, rather than to
+		//		the nodes specified by targetNodeIds themselves.    Useful for applying a Menu to
+		//		a range of rows in a table, tree, etc.
+		//
+		//		The application must require() an appropriate level of dojo/query to handle the selector.
+		selector: "",
+
+		// TODO: in 2.0 remove support for multiple targetNodeIds.   selector gives the same effect.
+		// So, change targetNodeIds to a targetNodeId: "", remove bindDomNode()/unBindDomNode(), etc.
+
+		/*=====
+		// currentTarget: [readonly] DOMNode
+		//		For context menus, set to the current node that the Menu is being displayed for.
+		//		Useful so that the menu actions can be tailored according to the node
+		currentTarget: null,
+		=====*/
+
+		// contextMenuForWindow: [const] Boolean
+		//		If true, right clicking anywhere on the window will cause this context menu to open.
+		//		If false, must specify targetNodeIds.
+		contextMenuForWindow: false,
+
+		// leftClickToOpen: [const] Boolean
+		//		If true, menu will open on left click instead of right click, similar to a file menu.
+		leftClickToOpen: false,
+
+		// refocus: Boolean
+		//		When this menu closes, re-focus the element which had focus before it was opened.
+		refocus: true,
+
+		postCreate: function(){
+			if(this.contextMenuForWindow){
+				this.bindDomNode(this.ownerDocumentBody);
 			}else{
-				iframe.attachEvent("onload", binding.onloadHandler);
+				array.forEach(this.targetNodeIds, this.bindDomNode, this);
+			}
+			this.inherited(arguments);
+		},
+
+		// thanks burstlib!
+		_iframeContentWindow: function(/* HTMLIFrameElement */iframe_el){
+			// summary:
+			//		Returns the window reference of the passed iframe
+			// tags:
+			//		private
+			return winUtils.get(this._iframeContentDocument(iframe_el)) ||
+				// Moz. TODO: is this available when defaultView isn't?
+				this._iframeContentDocument(iframe_el)['__parent__'] ||
+				(iframe_el.name && document.frames[iframe_el.name]) || null;	//	Window
+		},
+
+		_iframeContentDocument: function(/* HTMLIFrameElement */iframe_el){
+			// summary:
+			//		Returns a reference to the document object inside iframe_el
+			// tags:
+			//		protected
+			return iframe_el.contentDocument // W3
+				|| (iframe_el.contentWindow && iframe_el.contentWindow.document) // IE
+				|| (iframe_el.name && document.frames[iframe_el.name] && document.frames[iframe_el.name].document)
+				|| null;	//	HTMLDocument
+		},
+
+		bindDomNode: function(/*String|DomNode*/ node){
+			// summary:
+			//		Attach menu to given node
+			node = dom.byId(node, this.ownerDocument);
+
+			var cn;	// Connect node
+
+			// Support context menus on iframes.  Rather than binding to the iframe itself we need
+			// to bind to the <body> node inside the iframe.
+			if(node.tagName.toLowerCase() == "iframe"){
+				var iframe = node,
+					window = this._iframeContentWindow(iframe);
+				cn = win.body(window.document);
+			}else{
+				// To capture these events at the top level, attach to <html>, not <body>.
+				// Otherwise right-click context menu just doesn't work.
+				cn = (node == win.body(this.ownerDocument) ? this.ownerDocument.documentElement : node);
 			}
-		}
-	},
 
-	unBindDomNode: function(/*String|DomNode*/ nodeName){
-		// summary:
-		//		Detach menu from given node
-
-		var node;
-		try{
-			node = dom.byId(nodeName);
-		}catch(e){
-			// On IE the dom.byId() call will get an exception if the attach point was
-			// the <body> node of an <iframe> that has since been reloaded (and thus the
-			// <body> node is in a limbo state of destruction.
-			return;
-		}
 
-		// node["_dijitMenu" + this.id] contains index(+1) into my _bindings[] array
-		var attrName = "_dijitMenu" + this.id;
-		if(node && domAttr.has(node, attrName)){
-			var bid = domAttr.get(node, attrName)-1, b = this._bindings[bid], h;
-			while(h = b.connects.pop()){
-				h.remove();
-			}
+			// "binding" is the object to track our connection to the node (ie, the parameter to bindDomNode())
+			var binding = {
+				node: node,
+				iframe: iframe
+			};
+
+			// Save info about binding in _bindings[], and make node itself record index(+1) into
+			// _bindings[] array.  Prefix w/_dijitMenu to avoid setting an attribute that may
+			// start with a number, which fails on FF/safari.
+			domAttr.set(node, "_dijitMenu" + this.id, this._bindings.push(binding));
+
+			// Setup the connections to monitor click etc., unless we are connecting to an iframe which hasn't finished
+			// loading yet, in which case we need to wait for the onload event first, and then connect
+			// On linux Shift-F10 produces the oncontextmenu event, but on Windows it doesn't, so
+			// we need to monitor keyboard events in addition to the oncontextmenu event.
+			var doConnects = lang.hitch(this, function(cn){
+				var selector = this.selector,
+					delegatedEvent = selector ?
+						function(eventType){
+							return on.selector(selector, eventType);
+						} :
+						function(eventType){
+							return eventType;
+						},
+					self = this;
+				return [
+					// TODO: when leftClickToOpen is true then shouldn't space/enter key trigger the menu,
+					// rather than shift-F10?
+					on(cn, delegatedEvent(this.leftClickToOpen ? "click" : "contextmenu"), function(evt){
+						// Schedule context menu to be opened unless it's already been scheduled from onkeydown handler
+						evt.stopPropagation();
+						evt.preventDefault();
+						self._scheduleOpen(this, iframe, {x: evt.pageX, y: evt.pageY});
+					}),
+					on(cn, delegatedEvent("keydown"), function(evt){
+						if(evt.shiftKey && evt.keyCode == keys.F10){
+							evt.stopPropagation();
+							evt.preventDefault();
+							self._scheduleOpen(this, iframe);	// no coords - open near target node
+						}
+					})
+				];
+			});
+			binding.connects = cn ? doConnects(cn) : [];
 
-			// Remove listener for iframe onload events
-			var iframe = b.iframe;
 			if(iframe){
-				if(iframe.removeEventListener){
-					iframe.removeEventListener("load", b.onloadHandler, false);
+				// Setup handler to [re]bind to the iframe when the contents are initially loaded,
+				// and every time the contents change.
+				// Need to do this b/c we are actually binding to the iframe's <body> node.
+				// Note: can't use connect.connect(), see #9609.
+
+				binding.onloadHandler = lang.hitch(this, function(){
+					// want to remove old connections, but IE throws exceptions when trying to
+					// access the <body> node because it's already gone, or at least in a state of limbo
+
+					var window = this._iframeContentWindow(iframe),
+						cn = win.body(window.document);
+					binding.connects = doConnects(cn);
+				});
+				if(iframe.addEventListener){
+					iframe.addEventListener("load", binding.onloadHandler, false);
 				}else{
-					iframe.detachEvent("onload", b.onloadHandler);
+					iframe.attachEvent("onload", binding.onloadHandler);
 				}
 			}
+		},
+
+		unBindDomNode: function(/*String|DomNode*/ nodeName){
+			// summary:
+			//		Detach menu from given node
+
+			var node;
+			try{
+				node = dom.byId(nodeName, this.ownerDocument);
+			}catch(e){
+				// On IE the dom.byId() call will get an exception if the attach point was
+				// the <body> node of an <iframe> that has since been reloaded (and thus the
+				// <body> node is in a limbo state of destruction.
+				return;
+			}
 
-			domAttr.remove(node, attrName);
-			delete this._bindings[bid];
-		}
-	},
+			// node["_dijitMenu" + this.id] contains index(+1) into my _bindings[] array
+			var attrName = "_dijitMenu" + this.id;
+			if(node && domAttr.has(node, attrName)){
+				var bid = domAttr.get(node, attrName) - 1, b = this._bindings[bid], h;
+				while((h = b.connects.pop())){
+					h.remove();
+				}
 
-	_scheduleOpen: function(/*DomNode?*/ target, /*DomNode?*/ iframe, /*Object?*/ coords){
-		// summary:
-		//		Set timer to display myself.  Using a timer rather than displaying immediately solves
-		//		two problems:
-		//
-		//		1. IE: without the delay, focus work in "open" causes the system
-		//		context menu to appear in spite of stopEvent.
-		//
-		//		2. Avoid double-shows on linux, where shift-F10 generates an oncontextmenu event
-		//		even after a event.stop(e).  (Shift-F10 on windows doesn't generate the
-		//		oncontextmenu event.)
-
-		if(!this._openTimer){
-			this._openTimer = setTimeout(lang.hitch(this, function(){
-				delete this._openTimer;
-				this._openMyself({
-					target: target,
-					iframe: iframe,
-					coords: coords
-				});
-			}), 1);
-		}
-	},
+				// Remove listener for iframe onload events
+				var iframe = b.iframe;
+				if(iframe){
+					if(iframe.removeEventListener){
+						iframe.removeEventListener("load", b.onloadHandler, false);
+					}else{
+						iframe.detachEvent("onload", b.onloadHandler);
+					}
+				}
 
-	_openMyself: function(args){
-		// summary:
-		//		Internal function for opening myself when the user does a right-click or something similar.
-		// args:
-		//		This is an Object containing:
-		//		* target:
-		//			The node that is being clicked
-		//		* iframe:
-		//			If an <iframe> is being clicked, iframe points to that iframe
-		//		* coords:
-		//			Put menu at specified x/y position in viewport, or if iframe is
-		//			specified, then relative to iframe.
-		//
-		//		_openMyself() formerly took the event object, and since various code references
-		//		evt.target (after connecting to _openMyself()), using an Object for parameters
-		//		(so that old code still works).
+				domAttr.remove(node, attrName);
+				delete this._bindings[bid];
+			}
+		},
+
+		_scheduleOpen: function(/*DomNode?*/ target, /*DomNode?*/ iframe, /*Object?*/ coords){
+			// summary:
+			//		Set timer to display myself.  Using a timer rather than displaying immediately solves
+			//		two problems:
+			//
+			//		1. IE: without the delay, focus work in "open" causes the system
+			//		context menu to appear in spite of stopEvent.
+			//
+			//		2. Avoid double-shows on linux, where shift-F10 generates an oncontextmenu event
+			//		even after a evt.preventDefault().  (Shift-F10 on windows doesn't generate the
+			//		oncontextmenu event.)
+
+			if(!this._openTimer){
+				this._openTimer = this.defer(function(){
+					delete this._openTimer;
+					this._openMyself({
+						target: target,
+						iframe: iframe,
+						coords: coords
+					});
+				}, 1);
+			}
+		},
+
+		_openMyself: function(args){
+			// summary:
+			//		Internal function for opening myself when the user does a right-click or something similar.
+			// args:
+			//		This is an Object containing:
+			//
+			//		- target: The node that is being clicked
+			//		- iframe: If an `<iframe>` is being clicked, iframe points to that iframe
+			//		- coords: Put menu at specified x/y position in viewport, or if iframe is
+			//		  specified, then relative to iframe.
+			//
+			//		_openMyself() formerly took the event object, and since various code references
+			//		evt.target (after connecting to _openMyself()), using an Object for parameters
+			//		(so that old code still works).
+
+			var target = args.target,
+				iframe = args.iframe,
+				coords = args.coords,
+				byKeyboard = !coords;
+
+			// To be used by MenuItem event handlers to tell which node the menu was opened on
+			this.currentTarget = target;
+
+			// Get coordinates to open menu, either at specified (mouse) position or (if triggered via keyboard)
+			// then near the node the menu is assigned to.
+			if(coords){
+				if(iframe){
+					// Specified coordinates are on <body> node of an <iframe>, convert to match main document
+					var ifc = domGeometry.position(iframe, true),
+						window = this._iframeContentWindow(iframe),
+						scroll = domGeometry.docScroll(window.document);
+
+					var cs = domStyle.getComputedStyle(iframe),
+						tp = domStyle.toPixelValue,
+						left = (has("ie") && has("quirks") ? 0 : tp(iframe, cs.paddingLeft)) + (has("ie") && has("quirks") ? tp(iframe, cs.borderLeftWidth) : 0),
+						top = (has("ie") && has("quirks") ? 0 : tp(iframe, cs.paddingTop)) + (has("ie") && has("quirks") ? tp(iframe, cs.borderTopWidth) : 0);
+
+					coords.x += ifc.x + left - scroll.x;
+					coords.y += ifc.y + top - scroll.y;
+				}
+			}else{
+				coords = domGeometry.position(target, true);
+				coords.x += 10;
+				coords.y += 10;
+			}
 
-		var target = args.target,
-			iframe = args.iframe,
-			coords = args.coords;
+			var self = this;
+			var prevFocusNode = this._focusManager.get("prevNode");
+			var curFocusNode = this._focusManager.get("curNode");
+			var savedFocusNode = !curFocusNode || (dom.isDescendant(curFocusNode, this.domNode)) ? prevFocusNode : curFocusNode;
 
-		// Get coordinates to open menu, either at specified (mouse) position or (if triggered via keyboard)
-		// then near the node the menu is assigned to.
-		if(coords){
-			if(iframe){
-				// Specified coordinates are on <body> node of an <iframe>, convert to match main document
-				var ifc = domGeometry.position(iframe, true),
-					window = this._iframeContentWindow(iframe),
-					scroll = win.withGlobal(window, "_docScroll", dojo);
-
-				var cs = domStyle.getComputedStyle(iframe),
-					tp = domStyle.toPixelValue,
-					left = (has("ie") && has("quirks") ? 0 : tp(iframe, cs.paddingLeft)) + (has("ie") && has("quirks") ? tp(iframe, cs.borderLeftWidth) : 0),
-					top = (has("ie") && has("quirks") ? 0 : tp(iframe, cs.paddingTop)) + (has("ie") && has("quirks") ? tp(iframe, cs.borderTopWidth) : 0);
-
-				coords.x += ifc.x + left - scroll.x;
-				coords.y += ifc.y + top - scroll.y;
+			function closeAndRestoreFocus(){
+				// user has clicked on a menu or popup
+				if(self.refocus && savedFocusNode){
+					savedFocusNode.focus();
+				}
+				pm.close(self);
 			}
-		}else{
-			coords = domGeometry.position(target, true);
-			coords.x += 10;
-			coords.y += 10;
-		}
 
-		var self=this;
-		var prevFocusNode = this._focusManager.get("prevNode");
-		var curFocusNode = this._focusManager.get("curNode");
-		var savedFocusNode = !curFocusNode || (dom.isDescendant(curFocusNode, this.domNode)) ? prevFocusNode : curFocusNode;
+			pm.open({
+				popup: this,
+				x: coords.x,
+				y: coords.y,
+				onExecute: closeAndRestoreFocus,
+				onCancel: closeAndRestoreFocus,
+				orient: this.isLeftToRight() ? 'L' : 'R'
+			});
 
-		function closeAndRestoreFocus(){
-			// user has clicked on a menu or popup
-			if(self.refocus && savedFocusNode){
-				savedFocusNode.focus();
+			// Focus the menu even when opened by mouse, so that a click on blank area of screen will close it
+			this.focus();
+			if(!byKeyboard){
+				// But then (when opened by mouse), mark Menu as passive, so that the first item isn't highlighted.
+				// On IE9+ this needs to be on a delay because the focus is asynchronous.
+				this.defer(function(){
+					this._cleanUp(true);
+				});
 			}
-			pm.close(self);
-		}
-		pm.open({
-			popup: this,
-			x: coords.x,
-			y: coords.y,
-			onExecute: closeAndRestoreFocus,
-			onCancel: closeAndRestoreFocus,
-			orient: this.isLeftToRight() ? 'L' : 'R'
-		});
-		this.focus();
-
-		this._onBlur = function(){
-			this.inherited('_onBlur', arguments);
-			// Usually the parent closes the child widget but if this is a context
-			// menu then there is no parent
-			pm.close(this);
-			// don't try to restore focus; user has clicked another part of the screen
-			// and set focus there
-		};
-	},
-
-	uninitialize: function(){
- 		array.forEach(this._bindings, function(b){ if(b){ this.unBindDomNode(b.node); } }, this);
- 		this.inherited(arguments);
-	}
-});
 
+			this._onBlur = function(){
+				this.inherited('_onBlur', arguments);
+				// Usually the parent closes the child widget but if this is a context
+				// menu then there is no parent
+				pm.close(this);
+				// don't try to restore focus; user has clicked another part of the screen
+				// and set focus there
+			};
+		},
+
+		destroy: function(){
+			array.forEach(this._bindings, function(b){
+				if(b){
+					this.unBindDomNode(b.node);
+				}
+			}, this);
+			this.inherited(arguments);
+		}
+	});
 });
diff --git a/dijit/MenuBar.js b/dijit/MenuBar.js
index ef8e651..31a7865 100644
--- a/dijit/MenuBar.js
+++ b/dijit/MenuBar.js
@@ -1,81 +1,89 @@
 define([
 	"dojo/_base/declare", // declare
-	"dojo/_base/event", // event.stop
 	"dojo/keys", // keys.DOWN_ARROW
 	"./_MenuBase",
 	"dojo/text!./templates/MenuBar.html"
-], function(declare, event, keys, _MenuBase, template){
+], function(declare, keys, _MenuBase, template){
 
-/*=====
-	var _MenuBase = dijit._MenuBase;
-=====*/
+	// module:
+	//		dijit/MenuBar
 
-// module:
-//		dijit/MenuBar
-// summary:
-//		A menu bar, listing menu choices horizontally, like the "File" menu in most desktop applications
-
-return declare("dijit.MenuBar", _MenuBase, {
-	// summary:
-	//		A menu bar, listing menu choices horizontally, like the "File" menu in most desktop applications
+	return declare("dijit.MenuBar", _MenuBase, {
+		// summary:
+		//		A menu bar, listing menu choices horizontally, like the "File" menu in most desktop applications
 
-	templateString: template,
+		templateString: template,
 
-	baseClass: "dijitMenuBar",
+		baseClass: "dijitMenuBar",
 
-	// _isMenuBar: [protected] Boolean
-	//		This is a MenuBar widget, not a (vertical) Menu widget.
-	_isMenuBar: true,
+		// By default open popups for MenuBar instantly
+		popupDelay: 0,
 
-	postCreate: function(){
-		var l = this.isLeftToRight();
-		this.connectKeyNavHandlers(
-			l ? [keys.LEFT_ARROW] : [keys.RIGHT_ARROW],
-			l ? [keys.RIGHT_ARROW] : [keys.LEFT_ARROW]
-		);
+		// _isMenuBar: [protected] Boolean
+		//		This is a MenuBar widget, not a (vertical) Menu widget.
+		_isMenuBar: true,
 
 		// parameter to dijit.popup.open() about where to put popup (relative to this.domNode)
-		this._orient = ["below"];
-	},
-
-	focusChild: function(item){
-		// overload focusChild so that whenever the focus is moved to a new item,
-		// check the previous focused whether it has its popup open, if so, after
-		// focusing the new item, open its submenu immediately
-		var prev_item = this.focusedChild,
-			showpopup = prev_item && prev_item.popup && prev_item.popup.isShowingNow;
-		this.inherited(arguments);
-		if(showpopup && item.popup && !item.disabled){
-			this._openPopup();		// TODO: on down arrow, _openPopup() is called here and in onItemClick()
-		}
-	},
+		_orient: ["below"],
 
-	_onKeyPress: function(/*Event*/ evt){
-		// summary:
-		//		Handle keyboard based menu navigation.
-		// tags:
-		//		protected
+		_moveToPopup: function(/*Event*/ evt){
+			// summary:
+			//		This handles the down arrow key, opening a submenu if one exists.
+			//		Unlike _MenuBase._moveToPopup(), will never move to the next item in the MenuBar.
+			// tags:
+			//		private
 
-		if(evt.ctrlKey || evt.altKey){ return; }
+			if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
+				this.onItemClick(this.focusedChild, evt);
+			}
+		},
 
-		switch(evt.charOrCode){
-			case keys.DOWN_ARROW:
-				this._moveToPopup(evt);
-				event.stop(evt);
-		}
-	},
+		focusChild: function(item){
+			// Overload focusChild so that whenever a new item is focused and the menu is active, open its submenu immediately.
 
-	onItemClick: function(/*dijit._Widget*/ item, /*Event*/ evt){
-		// summary:
-		//		Handle clicks on an item. Cancels a dropdown if already open.
-		// tags:
-		//		private
-		if(item.popup && item.popup.isShowingNow){
-			item.popup.onCancel();
-		}else{
 			this.inherited(arguments);
-		}
-	}
-});
+			if(this.activated && item.popup && !item.disabled){
+				this._openItemPopup(item, true);
+			}
+		},
+
+		_onChildDeselect: function(item){
+			// override _MenuBase._onChildDeselect() to close submenu immediately
 
+			if(this.currentPopupItem == item){
+				this.currentPopupItem = null;
+				item._closePopup(); // this calls onClose
+			}
+
+			this.inherited(arguments);
+		},
+
+		// Arrow key navigation
+		_onLeftArrow: function(){
+			this.focusPrev();
+		},
+		_onRightArrow: function(){
+			this.focusNext();
+		},
+		_onDownArrow: function(/*Event*/ evt){
+			this._moveToPopup(evt);
+		},
+		_onUpArrow: function(){
+		},
+
+		onItemClick: function(/*dijit/_WidgetBase*/ item, /*Event*/ evt){
+			// summary:
+			//		Handle clicks on an item.   Also called by _moveToPopup() due to a down-arrow key on the item.
+			//		Cancels a dropdown if already open and click is either mouse or space/enter.
+			//		Don't close dropdown due to down arrow.
+			// tags:
+			//		private
+			if(item.popup && item.popup.isShowingNow && (!/^key/.test(evt.type) || evt.keyCode !== keys.DOWN_ARROW)){
+				item.focusNode.focus();
+				this._cleanUp(true);
+			}else{
+				this.inherited(arguments);
+			}
+		}
+	});
 });
diff --git a/dijit/MenuBarItem.js b/dijit/MenuBarItem.js
index 5a0dd6a..1675a98 100644
--- a/dijit/MenuBarItem.js
+++ b/dijit/MenuBarItem.js
@@ -4,15 +4,8 @@ define([
 	"dojo/text!./templates/MenuBarItem.html"
 ], function(declare, MenuItem, template){
 
-/*=====
-	var MenuItem = dijit.MenuItem;
-=====*/
-
 	// module:
 	//		dijit/MenuBarItem
-	// summary:
-	//		Item in a MenuBar that's clickable, and doesn't spawn a submenu when pressed (or hovered)
-
 
 	var _MenuBarItemMixin = declare("dijit._MenuBarItemMixin", null, {
 		templateString: template,
diff --git a/dijit/MenuItem.js b/dijit/MenuItem.js
index 85c2a5b..1c63237 100644
--- a/dijit/MenuItem.js
+++ b/dijit/MenuItem.js
@@ -3,33 +3,22 @@ define([
 	"dojo/dom", // dom.setSelectable
 	"dojo/dom-attr", // domAttr.set
 	"dojo/dom-class", // domClass.toggle
-	"dojo/_base/event", // event.stop
 	"dojo/_base/kernel", // kernel.deprecated
-	"dojo/_base/sniff", // has("ie")
+	"dojo/sniff", // has("ie")
+	"dojo/_base/lang", // lang.hitch
 	"./_Widget",
 	"./_TemplatedMixin",
 	"./_Contained",
 	"./_CssStateMixin",
 	"dojo/text!./templates/MenuItem.html"
-], function(declare, dom, domAttr, domClass, event, kernel, has,
+], function(declare, dom, domAttr, domClass, kernel, has, lang,
 			_Widget, _TemplatedMixin, _Contained, _CssStateMixin, template){
 
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _Contained = dijit._Contained;
-	var _CssStateMixin = dijit._CssStateMixin;
-=====*/
-
 	// module:
 	//		dijit/MenuItem
-	// summary:
-	//		A line item in a Menu Widget
-
 
-	return declare("dijit.MenuItem",
-		[_Widget, _TemplatedMixin, _Contained, _CssStateMixin],
-		{
+	var MenuItem = declare("dijit.MenuItem" + (has("dojo-bidi") ? "_NoBidi" : ""),
+		[_Widget, _TemplatedMixin, _Contained, _CssStateMixin], {
 		// summary:
 		//		A line item in a Menu Widget
 
@@ -40,9 +29,35 @@ define([
 		baseClass: "dijitMenuItem",
 
 		// label: String
-		//		Menu text
-		label: '',
-		_setLabelAttr: { node: "containerNode", type: "innerHTML" },
+		//		Menu text as HTML
+		label: "",
+		_setLabelAttr: function(val){
+			this._set("label", val);
+			var shortcutKey = "";
+			var text;
+			var ndx = val.search(/{\S}/);
+			if(ndx >= 0){
+				shortcutKey = val.charAt(ndx + 1);
+				var prefix = val.substr(0, ndx);
+				var suffix = val.substr(ndx + 3);
+				text = prefix + shortcutKey + suffix;
+				val = prefix + '<span class="dijitMenuItemShortcutKey">' + shortcutKey + '</span>' + suffix;
+			}else{
+				text = val;
+			}
+			this.domNode.setAttribute("aria-label", text + " " + this.accelKey);
+			this.containerNode.innerHTML = val;
+			this._set('shortcutKey', shortcutKey);
+		},
+
+		/*=====
+		// shortcutKey: [readonly] String
+		//		Single character (underlined when the parent Menu is focused) used to navigate directly to this widget,
+		//		also known as [a mnemonic](http://en.wikipedia.org/wiki/Mnemonics_(keyboard%29).
+		//		This is denoted in the label by surrounding the single character with {}.
+		//		For example, if label="{F}ile", then shortcutKey="F".
+		shortcutKey: "",
+		=====*/
 
 		// iconClass: String
 		//		Class to apply to DOMNode to make it display an icon.
@@ -50,10 +65,11 @@ define([
 		_setIconClassAttr: { node: "iconNode", type: "class" },
 
 		// accelKey: String
-		//		Text for the accelerator (shortcut) key combination.
-		//		Note that although Menu can display accelerator keys there
-		//		is no infrastructure to actually catch and execute these
-		//		accelerators.
+		//		Text for the accelerator (shortcut) key combination, a control, alt, etc. modified keystroke meant to
+		//		execute the menu item regardless of where the focus is on the page.
+		//
+		//		Note that although Menu can display accelerator keys, there is no infrastructure to actually catch and
+		//		execute those accelerators.
 		accelKey: "",
 
 		// disabled: Boolean
@@ -65,57 +81,20 @@ define([
 			// If button label is specified as srcNodeRef.innerHTML rather than
 			// this.params.label, handle it here.
 			if(source && !("label" in this.params)){
-				this.set('label', source.innerHTML);
+				this._set('label', source.innerHTML);
 			}
 		},
 
 		buildRendering: function(){
 			this.inherited(arguments);
-			var label = this.id+"_text";
-			domAttr.set(this.containerNode, "id", label);
+			var label = this.id + "_text";
+			domAttr.set(this.containerNode, "id", label); // only needed for backward compat
 			if(this.accelKeyNode){
-				domAttr.set(this.accelKeyNode, "id", this.id + "_accel");
-				label += " " + this.id + "_accel";
+				domAttr.set(this.accelKeyNode, "id", this.id + "_accel"); // only needed for backward compat
 			}
-			this.domNode.setAttribute("aria-labelledby", label);
 			dom.setSelectable(this.domNode, false);
 		},
 
-		_onHover: function(){
-			// summary:
-			//		Handler when mouse is moved onto menu item
-			// tags:
-			//		protected
-			this.getParent().onItemHover(this);
-		},
-
-		_onUnhover: function(){
-			// summary:
-			//		Handler when mouse is moved off of menu item,
-			//		possibly to a child menu, or maybe to a sibling
-			//		menuitem or somewhere else entirely.
-			// tags:
-			//		protected
-
-			// if we are unhovering the currently selected item
-			// then unselect it
-			this.getParent().onItemUnhover(this);
-
-			// When menu is hidden (collapsed) due to clicking a MenuItem and having it execute,
-			// FF and IE don't generate an onmouseout event for the MenuItem.
-			// So, help out _CssStateMixin in this case.
-			this._set("hovering", false);
-		},
-
-		_onClick: function(evt){
-			// summary:
-			//		Internal handler for click events on MenuItem.
-			// tags:
-			//		private
-			this.getParent().onItemClick(this, evt);
-			event.stop(evt);
-		},
-
 		onClick: function(/*Event*/){
 			// summary:
 			//		User defined function to handle clicks
@@ -143,7 +122,7 @@ define([
 			//		goes to this MenuItem or a child menu.
 			// tags:
 			//		protected
-			this._setSelected(true);
+
 			this.getParent()._onItemFocus(this);
 
 			this.inherited(arguments);
@@ -155,16 +134,6 @@ define([
 			// tags:
 			//		private
 
-			/***
-			 * TODO: remove this method and calls to it, when _onBlur() is working for MenuItem.
-			 * Currently _onBlur() gets called when focus is moved from the MenuItem to a child menu.
-			 * That's not supposed to happen, but the problem is:
-			 * In order to allow dijit.popup's getTopPopup() to work,a sub menu's popupParent
-			 * points to the parent Menu, bypassing the parent MenuItem... thus the
-			 * MenuItem is not in the chain of active widgets and gets a premature call to
-			 * _onBlur()
-			 */
-
 			domClass.toggle(this.domNode, "dijitMenuItemSelected", selected);
 		},
 
@@ -185,6 +154,7 @@ define([
 			kernel.deprecated("dijit.Menu.setDisabled() is deprecated.  Use set('disabled', bool) instead.", "", "2.0");
 			this.set('disabled', disabled);
 		},
+
 		_setDisabledAttr: function(/*Boolean*/ value){
 			// summary:
 			//		Hook for attr('disabled', ...) to work.
@@ -193,17 +163,32 @@ define([
 			this.focusNode.setAttribute('aria-disabled', value ? 'true' : 'false');
 			this._set("disabled", value);
 		},
+
 		_setAccelKeyAttr: function(/*String*/ value){
 			// summary:
 			//		Hook for attr('accelKey', ...) to work.
 			//		Set accelKey on this menu item.
 
-			this.accelKeyNode.style.display=value?"":"none";
-			this.accelKeyNode.innerHTML=value;
-			//have to use colSpan to make it work in IE
-			domAttr.set(this.containerNode,'colSpan',value?"1":"2");
-
+			if(this.accelKeyNode){
+				this.accelKeyNode.style.display = value ? "" : "none";
+				this.accelKeyNode.innerHTML = value;
+				//have to use colSpan to make it work in IE
+				domAttr.set(this.containerNode, 'colSpan', value ? "1" : "2");
+			}
 			this._set("accelKey", value);
 		}
 	});
+
+	if(has("dojo-bidi")){
+		MenuItem = declare("dijit.MenuItem", MenuItem, {
+			_setLabelAttr: function(val){
+				this.inherited(arguments);
+				if(this.textDir === "auto"){
+					this.applyTextDir(this.textDirNode);
+				}
+			}
+		});
+	}
+
+	return MenuItem;
 });
diff --git a/dijit/MenuSeparator.js b/dijit/MenuSeparator.js
index 44c209a..3c4313b 100644
--- a/dijit/MenuSeparator.js
+++ b/dijit/MenuSeparator.js
@@ -7,16 +7,8 @@ define([
 	"dojo/text!./templates/MenuSeparator.html"
 ], function(declare, dom, _WidgetBase, _TemplatedMixin, _Contained, template){
 
-/*=====
-	var _WidgetBase = dijit._WidgetBase;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _Contained = dijit._Contained;
-=====*/
-
 	// module:
 	//		dijit/MenuSeparator
-	// summary:
-	//		A line between two menu items
 
 	return declare("dijit.MenuSeparator", [_WidgetBase, _TemplatedMixin, _Contained], {
 		// summary:
diff --git a/dijit/PopupMenuBarItem.js b/dijit/PopupMenuBarItem.js
index 04e8d20..4192df3 100644
--- a/dijit/PopupMenuBarItem.js
+++ b/dijit/PopupMenuBarItem.js
@@ -6,16 +6,9 @@ define([
 
 	// module:
 	//		dijit/PopupMenuBarItem
-	// summary:
-	//		Item in a MenuBar like "File" or "Edit", that spawns a submenu when pressed (or hovered)
 
 	var _MenuBarItemMixin = MenuBarItem._MenuBarItemMixin;
 
-/*=====
-	var PopupMenuItem = dijit.PopupMenuItem;
-	var _MenuBarItemMixin = dijit._MenuBarItemMixin;
-=====*/
-
 	return declare("dijit.PopupMenuBarItem", [PopupMenuItem, _MenuBarItemMixin], {
 		// summary:
 		//		Item in a MenuBar like "File" or "Edit", that spawns a submenu when pressed (or hovered)
diff --git a/dijit/PopupMenuItem.js b/dijit/PopupMenuItem.js
index 54eb730..ed48524 100644
--- a/dijit/PopupMenuItem.js
+++ b/dijit/PopupMenuItem.js
@@ -1,21 +1,16 @@
 define([
 	"dojo/_base/declare", // declare
 	"dojo/dom-style", // domStyle.set
+	"dojo/_base/lang",
 	"dojo/query", // query
-	"dojo/_base/window", // win.body
+	"./popup",
 	"./registry",	// registry.byNode
 	"./MenuItem",
 	"./hccss"
-], function(declare, domStyle, query, win, registry, MenuItem){
-
-/*=====
-	var MenuItem = dijit.MenuItem;
-=====*/
+], function(declare, domStyle, lang, query, pm, registry, MenuItem){
 
 	// module:
 	//		dijit/PopupMenuItem
-	// summary:
-	//		An item in a Menu that spawn a drop down (usually a drop down menu)
 
 	return declare("dijit.PopupMenuItem", MenuItem, {
 		// summary:
@@ -26,10 +21,10 @@ define([
 			//		When Menu is declared in markup, this code gets the menu label and
 			//		the popup widget from the srcNodeRef.
 			// description:
-			//		srcNodeRefinnerHTML contains both the menu item text and a popup widget
+			//		srcNodeRef.innerHTML contains both the menu item text and a popup widget
 			//		The first part holds the menu item text and the second part is the popup
 			// example:
-			// |	<div data-dojo-type="dijit.PopupMenuItem">
+			// |	<div data-dojo-type="dijit/PopupMenuItem">
 			// |		<span>pick me</span>
 			// |		<popup> ... </popup>
 			// |	</div>
@@ -45,17 +40,41 @@ define([
 			}
 		},
 
+		_openPopup: function(/*Object*/ params, /*Boolean*/ focus){
+			// summary:
+			//		Open the popup to the side of/underneath this MenuItem, and optionally focus first item
+			// tags:
+			//		protected
+
+			var popup = this.popup;
+
+			pm.open(lang.delegate(params, {
+				popup: this.popup,
+				around: this.domNode
+			}));
+
+			if(focus && popup.focus){
+				popup.focus();
+			}
+		},
+
+		_closePopup: function(){
+			pm.close(this.popup);
+			this.popup.parentMenu = null;
+		},
+
 		startup: function(){
 			if(this._started){ return; }
 			this.inherited(arguments);
 
-			// we didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's
-			// land now.  move it to win.doc.body.
+			// We didn't copy the dropdown widget from the this.srcNodeRef, so it's in no-man's
+			// land now.  Move it to <body>.
 			if(!this.popup){
 				var node = query("[widgetId]", this.dropDownContainer)[0];
 				this.popup = registry.byNode(node);
 			}
-			win.body().appendChild(this.popup.domNode);
+			this.ownerDocumentBody.appendChild(this.popup.domNode);
+			this.popup.domNode.setAttribute("aria-labelledby", this.containerNode.id);
 			this.popup.startup();
 
 			this.popup.domNode.style.display="none";
diff --git a/dijit/ProgressBar.js b/dijit/ProgressBar.js
index 5c7a3d6..b3328d1 100644
--- a/dijit/ProgressBar.js
+++ b/dijit/ProgressBar.js
@@ -1,5 +1,5 @@
 define([
-	"require",			// require.toUrl
+	"require", // require.toUrl
 	"dojo/_base/declare", // declare
 	"dojo/dom-class", // domClass.toggle
 	"dojo/_base/lang", // lang.mixin
@@ -9,167 +9,158 @@ define([
 	"dojo/text!./templates/ProgressBar.html"
 ], function(require, declare, domClass, lang, number, _Widget, _TemplatedMixin, template){
 
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-=====*/
-
-// module:
-//		dijit/ProgressBar
-// summary:
-//		A progress indication widget, showing the amount completed
-//		(often the percentage completed) of a task.
-
-
-return declare("dijit.ProgressBar", [_Widget, _TemplatedMixin], {
-	// summary:
-	//		A progress indication widget, showing the amount completed
-	//		(often the percentage completed) of a task.
-	//
-	// example:
-	// |	<div data-dojo-type="ProgressBar"
-	// |		 places="0"
-	// |		 value="..." maximum="...">
-	// |	</div>
-
-	// progress: [const] String (Percentage or Number)
-	//		Number or percentage indicating amount of task completed.
-	// 		Deprecated.   Use "value" instead.
-	progress: "0",
-
-	// value: String (Percentage or Number)
-	//		Number or percentage indicating amount of task completed.
-	// 		With "%": percentage value, 0% <= progress <= 100%, or
-	// 		without "%": absolute value, 0 <= progress <= maximum.
-	//		Infinity means that the progress bar is indeterminate.
-	value: "",
-
-	// maximum: [const] Float
-	//		Max sample number
-	maximum: 100,
-
-	// places: [const] Number
-	//		Number of places to show in values; 0 by default
-	places: 0,
-
-	// indeterminate: [const] Boolean
-	// 		If false: show progress value (number or percentage).
-	// 		If true: show that a process is underway but that the amount completed is unknown.
-	// 		Deprecated.   Use "value" instead.
-	indeterminate: false,
-
-	// label: String?
-	//		Label on progress bar.   Defaults to percentage for determinate progress bar and
-	//		blank for indeterminate progress bar.
-	label:"",
-
-	// name: String
-	//		this is the field name (for a form) if set. This needs to be set if you want to use
-	//		this widget in a dijit.form.Form widget (such as dijit.Dialog)
-	name: '',
-
-	templateString: template,
-
-	// _indeterminateHighContrastImagePath: [private] URL
-	//		URL to image to use for indeterminate progress bar when display is in high contrast mode
-	_indeterminateHighContrastImagePath:
-		require.toUrl("./themes/a11y/indeterminate_progress.gif"),
-
-	postMixInProperties: function(){
-		this.inherited(arguments);
-		if(!("value" in this.params)){
-			this.value = this.indeterminate ? Infinity : this.progress;
-		}
-	},
-
-	buildRendering: function(){
-		this.inherited(arguments);
-		this.indeterminateHighContrastImage.setAttribute("src",
-			this._indeterminateHighContrastImagePath.toString());
-		this.update();
-	},
+	// module:
+	//		dijit/ProgressBar
 
-	update: function(/*Object?*/attributes){
+	return declare("dijit.ProgressBar", [_Widget, _TemplatedMixin], {
 		// summary:
-		//		Internal method to change attributes of ProgressBar, similar to set(hash).  Users should call
-		//		set("value", ...) rather than calling this method directly.
-		// attributes:
-		//		May provide progress and/or maximum properties on this parameter;
-		//		see attribute specs for details.
-		// example:
-		//	|	myProgressBar.update({'indeterminate': true});
-		//	|	myProgressBar.update({'progress': 80});
-		//	|	myProgressBar.update({'indeterminate': true, label:"Loading ..." })
-		// tags:
-		//		private
-
-		// TODO: deprecate this method and use set() instead
-
-		lang.mixin(this, attributes || {});
-		var tip = this.internalProgress, ap = this.domNode;
-		var percent = 1;
-		if(this.indeterminate){
-			ap.removeAttribute("aria-valuenow");
-			ap.removeAttribute("aria-valuemin");
-			ap.removeAttribute("aria-valuemax");
-		}else{
-			if(String(this.progress).indexOf("%") != -1){
-				percent = Math.min(parseFloat(this.progress)/100, 1);
-				this.progress = percent * this.maximum;
+		//		A progress indication widget, showing the amount completed
+		//		(often the percentage completed) of a task.
+
+		// progress: [const] String (Percentage or Number)
+		//		Number or percentage indicating amount of task completed.
+		//		Deprecated.   Use "value" instead.
+		progress: "0",
+
+		// value: String (Percentage or Number)
+		//		Number or percentage indicating amount of task completed.
+		//		With "%": percentage value, 0% <= progress <= 100%, or
+		//		without "%": absolute value, 0 <= progress <= maximum.
+		//		Infinity means that the progress bar is indeterminate.
+		value: "",
+
+		// maximum: [const] Float
+		//		Max sample number
+		maximum: 100,
+
+		// places: [const] Number
+		//		Number of places to show in values; 0 by default
+		places: 0,
+
+		// indeterminate: [const] Boolean
+		//		If false: show progress value (number or percentage).
+		//		If true: show that a process is underway but that the amount completed is unknown.
+		//		Deprecated.   Use "value" instead.
+		indeterminate: false,
+
+		// label: String?
+		//		HTML label on progress bar.   Defaults to percentage for determinate progress bar and
+		//		blank for indeterminate progress bar.
+		label: "",
+
+		// name: String
+		//		this is the field name (for a form) if set. This needs to be set if you want to use
+		//		this widget in a dijit/form/Form widget (such as dijit/Dialog)
+		name: '',
+
+		templateString: template,
+
+		// _indeterminateHighContrastImagePath: [private] URL
+		//		URL to image to use for indeterminate progress bar when display is in high contrast mode
+		_indeterminateHighContrastImagePath: require.toUrl("./themes/a11y/indeterminate_progress.gif"),
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+
+			// Back-compat for when constructor specifies indeterminate or progress, rather than value.   Remove for 2.0.
+			if(!(this.params && "value" in this.params)){
+				this.value = this.indeterminate ? Infinity : this.progress;
+			}
+		},
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.indeterminateHighContrastImage.setAttribute("src",
+				this._indeterminateHighContrastImagePath.toString());
+			this.update();
+		},
+
+		_setDirAttr: function(val){
+			// Normally _CssStateMixin takes care of this, but we aren't extending it
+			domClass.toggle(this.domNode, "dijitProgressBarRtl", val == "rtl");
+			this.inherited(arguments);
+		},
+
+		update: function(/*Object?*/attributes){
+			// summary:
+			//		Internal method to change attributes of ProgressBar, similar to set(hash).  Users should call
+			//		set("value", ...) rather than calling this method directly.
+			// attributes:
+			//		May provide progress and/or maximum properties on this parameter;
+			//		see attribute specs for details.
+			// example:
+			//	|	myProgressBar.update({'indeterminate': true});
+			//	|	myProgressBar.update({'progress': 80});
+			//	|	myProgressBar.update({'indeterminate': true, label:"Loading ..." })
+			// tags:
+			//		private
+
+			// TODO: deprecate this method and use set() instead
+
+			lang.mixin(this, attributes || {});
+			var tip = this.internalProgress, ap = this.domNode;
+			var percent = 1;
+			if(this.indeterminate){
+				ap.removeAttribute("aria-valuenow");
 			}else{
-				this.progress = Math.min(this.progress, this.maximum);
-				percent = this.maximum ? this.progress / this.maximum : 0;
+				if(String(this.progress).indexOf("%") != -1){
+					percent = Math.min(parseFloat(this.progress) / 100, 1);
+					this.progress = percent * this.maximum;
+				}else{
+					this.progress = Math.min(this.progress, this.maximum);
+					percent = this.maximum ? this.progress / this.maximum : 0;
+				}
+				ap.setAttribute("aria-valuenow", this.progress);
 			}
 
-			ap.setAttribute("aria-describedby", this.labelNode.id);
-			ap.setAttribute("aria-valuenow", this.progress);
+			// Even indeterminate ProgressBars should have these attributes
+			ap.setAttribute("aria-labelledby", this.labelNode.id);
 			ap.setAttribute("aria-valuemin", 0);
 			ap.setAttribute("aria-valuemax", this.maximum);
-		}
-		this.labelNode.innerHTML = this.report(percent);
-
-		domClass.toggle(this.domNode, "dijitProgressBarIndeterminate", this.indeterminate);
-		tip.style.width = (percent * 100) + "%";
-		this.onChange();
-	},
-
-	_setValueAttr: function(v){
-		this._set("value", v);
-		if(v == Infinity){
-			this.update({indeterminate:true});
-		}else{
-			this.update({indeterminate:false, progress:v});
-		}
-	},
-
-	_setLabelAttr: function(label){
-		this._set("label", label);
-		this.update();
-	},
 
-	_setIndeterminateAttr: function(indeterminate){
-		// Deprecated, use set("value", ...) instead
-		this.indeterminate = indeterminate;
-		this.update();
-	},
+			this.labelNode.innerHTML = this.report(percent);
 
-	report: function(/*float*/percent){
-		// summary:
-		//		Generates message to show inside progress bar (normally indicating amount of task completed).
-		//		May be overridden.
-		// tags:
-		//		extension
+			domClass.toggle(this.domNode, "dijitProgressBarIndeterminate", this.indeterminate);
+			tip.style.width = (percent * 100) + "%";
+			this.onChange();
+		},
 
-		return this.label ? this.label :
+		_setValueAttr: function(v){
+			this._set("value", v);
+			if(v == Infinity){
+				this.update({indeterminate: true});
+			}else{
+				this.update({indeterminate: false, progress: v});
+			}
+		},
+
+		_setLabelAttr: function(label){
+			this._set("label", label);
+			this.update();
+		},
+
+		_setIndeterminateAttr: function(indeterminate){
+			// Deprecated, use set("value", ...) instead
+			this._set("indeterminate", indeterminate);
+			this.update();
+		},
+
+		report: function(/*float*/percent){
+			// summary:
+			//		Generates HTML message to show inside progress bar (normally indicating amount of task completed).
+			//		May be overridden.
+			// tags:
+			//		extension
+
+			return this.label ? this.label :
 				(this.indeterminate ? " " : number.format(percent, { type: "percent", places: this.places, locale: this.lang }));
-	},
-
-	onChange: function(){
-		// summary:
-		//		Callback fired when progress updates.
-		// tags:
-		//		extension
-	}
-});
+		},
 
+		onChange: function(){
+			// summary:
+			//		Callback fired when progress updates.
+			// tags:
+			//		extension
+		}
+	});
 });
diff --git a/dijit/RadioMenuItem.js b/dijit/RadioMenuItem.js
new file mode 100644
index 0000000..c36a276
--- /dev/null
+++ b/dijit/RadioMenuItem.js
@@ -0,0 +1,64 @@
+define([
+	"dojo/_base/declare", // declare
+	"dojo/dom-class", // domClass.toggle
+	"./CheckedMenuItem"
+], function(declare, domClass, CheckedMenuItem){
+
+	// module:
+	//		dijit/RadioButtonMenuItem
+
+	return declare("dijit.RadioButtonMenuItem", CheckedMenuItem, {
+		// summary:
+		//		A radio-button-like menu item for toggling on and off
+
+		baseClass: "dijitRadioMenuItem",
+
+		role: "menuitemradio",
+
+		// checkedChar: String
+		//		Character (or string) used in place of radio button icon when display in high contrast mode
+		checkedChar: "*",
+
+		// group: String
+		//		Toggling on a RadioMenuItem in a given group toggles off the other RadioMenuItems in that group.
+		group: "",
+
+		// mapping from group name to checked widget within that group (or null if no widget is checked)
+		_currentlyChecked: {},
+
+		_setCheckedAttr: function(/*Boolean*/ checked){
+			// summary:
+			//		Hook so attr('checked', bool) works.
+			//		Sets the class and state for the check box.
+
+			if(checked && this.group && this._currentlyChecked[this.group] && this._currentlyChecked[this.group] != this){
+				// if another RadioMenuItem in my group is checked, uncheck it
+				this._currentlyChecked[this.group].set("checked", false);
+			}
+
+			this.inherited(arguments);
+
+			// set the currently checked widget to this, or null if we are clearing the currently checked widget
+			if(this.group){
+				if(checked){
+					this._currentlyChecked[this.group] = this;
+				}else if(this._currentlyChecked[this.group] == this){
+					this._currentlyChecked[this.group] = null;
+				}
+			}
+		},
+
+		_onClick: function(evt){
+			// summary:
+			//		Clicking this item toggles it on.   If it's already on, then clicking does nothing.
+			// tags:
+			//		private
+
+			if(!this.disabled && !this.checked){
+				this.set("checked", true);
+				this.onChange(true);
+			}
+			this.onClick(evt);
+		}
+	});
+});
diff --git a/dijit/TitlePane.js b/dijit/TitlePane.js
index f30c065..de83854 100644
--- a/dijit/TitlePane.js
+++ b/dijit/TitlePane.js
@@ -5,271 +5,288 @@ define([
 	"dojo/dom-attr", // domAttr.set or get domAttr.remove
 	"dojo/dom-class", // domClass.replace
 	"dojo/dom-geometry", // domGeometry.setMarginBox domGeometry.getMarginBox
-	"dojo/_base/event", // event.stop
 	"dojo/fx", // fxUtils.wipeIn fxUtils.wipeOut
+	"dojo/has",
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/keys", // keys.DOWN_ARROW keys.ENTER
 	"./_CssStateMixin",
 	"./_TemplatedMixin",
 	"./layout/ContentPane",
 	"dojo/text!./templates/TitlePane.html",
-	"./_base/manager"	// defaultDuration
-], function(array, declare, dom, domAttr, domClass, domGeometry, event, fxUtils, kernel, keys,
+	"./_base/manager",    // defaultDuration
+	"./a11yclick"	// template uses ondijitclick
+], function(array, declare, dom, domAttr, domClass, domGeometry, fxUtils, has, kernel, keys,
 			_CssStateMixin, _TemplatedMixin, ContentPane, template, manager){
 
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _CssStateMixin = dijit._CssStateMixin;
-	var ContentPane = dijit.layout.ContentPane;
-=====*/
-
-// module:
-//		dijit/TitlePane
-// summary:
-//		A pane with a title on top, that can be expanded or collapsed.
-
-
-return declare("dijit.TitlePane", [ContentPane, _TemplatedMixin, _CssStateMixin], {
-	// summary:
-	//		A pane with a title on top, that can be expanded or collapsed.
-	//
-	// description:
-	//		An accessible container with a title Heading, and a content
-	//		section that slides open and closed. TitlePane is an extension to
-	//		`dijit.layout.ContentPane`, providing all the useful content-control aspects from it.
-	//
-	// example:
-	// | 	// load a TitlePane from remote file:
-	// |	var foo = new dijit.TitlePane({ href: "foobar.html", title:"Title" });
-	// |	foo.startup();
-	//
-	// example:
-	// |	<!-- markup href example: -->
-	// |	<div data-dojo-type="dijit.TitlePane" data-dojo-props="href: 'foobar.html', title: 'Title'"></div>
-	//
-	// example:
-	// |	<!-- markup with inline data -->
-	// | 	<div data-dojo-type="dijit.TitlePane" title="Title">
-	// |		<p>I am content</p>
-	// |	</div>
-
-	// title: String
-	//		Title of the pane
-	title: "",
-	_setTitleAttr: { node: "titleNode", type: "innerHTML" },	// override default where title becomes a hover tooltip
-
-	// open: Boolean
-	//		Whether pane is opened or closed.
-	open: true,
-
-	// toggleable: Boolean
-	//		Whether pane can be opened or closed by clicking the title bar.
-	toggleable: true,
-
-	// tabIndex: String
-	//		Tabindex setting for the title (so users can tab to the title then
-	//		use space/enter to open/close the title pane)
-	tabIndex: "0",
-
-	// duration: Integer
-	//		Time in milliseconds to fade in/fade out
-	duration: manager.defaultDuration,
-
-	// baseClass: [protected] String
-	//		The root className to be placed on this widget's domNode.
-	baseClass: "dijitTitlePane",
-
-	templateString: template,
-
-	// doLayout: [protected] Boolean
-	//		Don't change this parameter from the default value.
-	//		This ContentPane parameter doesn't make sense for TitlePane, since TitlePane
-	//		is never a child of a layout container, nor should TitlePane try to control
-	//		the size of an inner widget.
-	doLayout: false,
-
-	// Tooltip is defined in _WidgetBase but we need to handle the mapping to DOM here
-	_setTooltipAttr: {node: "focusNode", type: "attribute", attribute: "title"},	// focusNode spans the entire width, titleNode doesn't
-
-	buildRendering: function(){
-		this.inherited(arguments);
-		dom.setSelectable(this.titleNode, false);
-	},
-
-	postCreate: function(){
-		this.inherited(arguments);
-
-		// Hover and focus effect on title bar, except for non-toggleable TitlePanes
-		// This should really be controlled from _setToggleableAttr() but _CssStateMixin
-		// doesn't provide a way to disconnect a previous _trackMouseState() call
-		if(this.toggleable){
-			this._trackMouseState(this.titleBarNode, "dijitTitlePaneTitle");
-		}
-
-		// setup open/close animations
-		var hideNode = this.hideNode, wipeNode = this.wipeNode;
-		this._wipeIn = fxUtils.wipeIn({
-			node: wipeNode,
-			duration: this.duration,
-			beforeBegin: function(){
-				hideNode.style.display="";
-			}
-		});
-		this._wipeOut = fxUtils.wipeOut({
-			node: wipeNode,
-			duration: this.duration,
-			onEnd: function(){
-				hideNode.style.display="none";
-			}
-		});
-	},
+	// module:
+	//		dijit/TitlePane
 
-	_setOpenAttr: function(/*Boolean*/ open, /*Boolean*/ animate){
+	var TitlePane = declare("dijit.TitlePane", [ContentPane, _TemplatedMixin, _CssStateMixin], {
 		// summary:
-		//		Hook to make set("open", boolean) control the open/closed state of the pane.
+		//		A pane with a title on top, that can be expanded or collapsed.
+		//
+		// description:
+		//		An accessible container with a title Heading, and a content
+		//		section that slides open and closed. TitlePane is an extension to
+		//		`dijit/layout/ContentPane`, providing all the useful content-control aspects from it.
+		//
+		// example:
+		//	|	// load a TitlePane from remote file:
+		//	|	var foo = new dijit.TitlePane({ href: "foobar.html", title:"Title" });
+		//	|	foo.startup();
+		//
+		// example:
+		//	|	<!-- markup href example: -->
+		//	|	<div data-dojo-type="dijit/TitlePane" data-dojo-props="href: 'foobar.html', title: 'Title'"></div>
+		//
+		// example:
+		//	|	<!-- markup with inline data -->
+		//	|	<div data-dojo-type="dijit/TitlePane" title="Title">
+		//	|		<p>I am content</p>
+		//	|	</div>
+
+		// title: String
+		//		Title of the pane
+		title: "",
+		_setTitleAttr: { node: "titleNode", type: "innerHTML" }, // override default where title becomes a hover tooltip
+
 		// open: Boolean
-		//		True if you want to open the pane, false if you want to close it.
+		//		Whether pane is opened or closed.
+		open: true,
 
-		array.forEach([this._wipeIn, this._wipeOut], function(animation){
-			if(animation && animation.status() == "playing"){
-				animation.stop();
-			}
-		});
+		// toggleable: Boolean
+		//		Whether pane can be opened or closed by clicking the title bar.
+		toggleable: true,
 
-		if(animate){
-			var anim = this[open ? "_wipeIn" : "_wipeOut"];
-			anim.play();
-		}else{
-			this.hideNode.style.display = this.wipeNode.style.display = open ? "" : "none";
-		}
+		// tabIndex: String
+		//		Tabindex setting for the title (so users can tab to the title then
+		//		use space/enter to open/close the title pane)
+		tabIndex: "0",
 
-		// load content (if this is the first time we are opening the TitlePane
-		// and content is specified as an href, or href was set when hidden)
-		if(this._started){
-			if(open){
-				this._onShow();
-			}else{
-				this.onHide();
-			}
-		}
+		// duration: Integer
+		//		Time in milliseconds to fade in/fade out
+		duration: manager.defaultDuration,
 
-		this.arrowNodeInner.innerHTML = open ? "-" : "+";
+		// baseClass: [protected] String
+		//		The root className to be placed on this widget's domNode.
+		baseClass: "dijitTitlePane",
 
-		this.containerNode.setAttribute("aria-hidden", open ? "false" : "true");
-		this.focusNode.setAttribute("aria-pressed", open ? "true" : "false");
+		templateString: template,
 
-		this._set("open", open);
+		// doLayout: [protected] Boolean
+		//		Don't change this parameter from the default value.
+		//		This ContentPane parameter doesn't make sense for TitlePane, since TitlePane
+		//		is never a child of a layout container, nor should TitlePane try to control
+		//		the size of an inner widget.
+		doLayout: false,
 
-		this._setCss();
-	},
+		// Tooltip is defined in _WidgetBase but we need to handle the mapping to DOM here
+		_setTooltipAttr: {node: "focusNode", type: "attribute", attribute: "title"}, // focusNode spans the entire width, titleNode doesn't
 
-	_setToggleableAttr: function(/*Boolean*/ canToggle){
-		// summary:
-		//		Hook to make set("toggleable", boolean) work.
-		// canToggle: Boolean
-		//		True to allow user to open/close pane by clicking title bar.
-
-		this.focusNode.setAttribute("role", canToggle ? "button" : "heading");
-		if(canToggle){
-			// TODO: if canToggle is switched from true to false shouldn't we remove this setting?
-			this.focusNode.setAttribute("aria-controls", this.id+"_pane");
-			domAttr.set(this.focusNode, "tabIndex", this.tabIndex);
-		}else{
-			domAttr.remove(this.focusNode, "tabIndex");
-		}
+		buildRendering: function(){
+			this.inherited(arguments);
+			dom.setSelectable(this.titleNode, false);
+		},
 
-		this._set("toggleable", canToggle);
+		postCreate: function(){
+			this.inherited(arguments);
 
-		this._setCss();
-	},
+			// Hover and focus effect on title bar, except for non-toggleable TitlePanes
+			// This should really be controlled from _setToggleableAttr() but _CssStateMixin
+			// doesn't provide a way to disconnect a previous _trackMouseState() call
+			if(this.toggleable){
+				this._trackMouseState(this.titleBarNode, this.baseClass + "Title");
+			}
 
-	_setContentAttr: function(/*String|DomNode|Nodelist*/ content){
-		// summary:
-		//		Hook to make set("content", ...) work.
-		// 		Typically called when an href is loaded.  Our job is to make the animation smooth.
+			// setup open/close animations
+			var hideNode = this.hideNode, wipeNode = this.wipeNode;
+			this._wipeIn = fxUtils.wipeIn({
+				node: wipeNode,
+				duration: this.duration,
+				beforeBegin: function(){
+					hideNode.style.display = "";
+				}
+			});
+			this._wipeOut = fxUtils.wipeOut({
+				node: wipeNode,
+				duration: this.duration,
+				onEnd: function(){
+					hideNode.style.display = "none";
+				}
+			});
+		},
+
+		_setOpenAttr: function(/*Boolean*/ open, /*Boolean*/ animate){
+			// summary:
+			//		Hook to make set("open", boolean) control the open/closed state of the pane.
+			// open: Boolean
+			//		True if you want to open the pane, false if you want to close it.
+
+			array.forEach([this._wipeIn, this._wipeOut], function(animation){
+				if(animation && animation.status() == "playing"){
+					animation.stop();
+				}
+			});
+
+			if(animate){
+				var anim = this[open ? "_wipeIn" : "_wipeOut"];
+				anim.play();
+			}else{
+				this.hideNode.style.display = this.wipeNode.style.display = open ? "" : "none";
+			}
 
-		if(!this.open || !this._wipeOut || this._wipeOut.status() == "playing"){
-			// we are currently *closing* the pane (or the pane is closed), so just let that continue
-			this.inherited(arguments);
-		}else{
-			if(this._wipeIn && this._wipeIn.status() == "playing"){
-				this._wipeIn.stop();
+			// load content (if this is the first time we are opening the TitlePane
+			// and content is specified as an href, or href was set when hidden)
+			if(this._started){
+				if(open){
+					this._onShow();
+				}else{
+					this.onHide();
+				}
 			}
 
-			// freeze container at current height so that adding new content doesn't make it jump
-			domGeometry.setMarginBox(this.wipeNode, { h: domGeometry.getMarginBox(this.wipeNode).h });
+			this.containerNode.setAttribute("aria-hidden", open ? "false" : "true");
+			this.focusNode.setAttribute("aria-pressed", open ? "true" : "false");
 
-			// add the new content (erasing the old content, if any)
-			this.inherited(arguments);
+			this._set("open", open);
 
-			// call _wipeIn.play() to animate from current height to new height
-			if(this._wipeIn){
-				this._wipeIn.play();
-			}else{
-				this.hideNode.style.display = "";
-			}
-		}
-	},
+			this._setCss();
+		},
 
-	toggle: function(){
-		// summary:
-		//		Switches between opened and closed state
-		// tags:
-		//		private
+		_setToggleableAttr: function(/*Boolean*/ canToggle){
+			// summary:
+			//		Hook to make set("toggleable", boolean) work.
+			// canToggle: Boolean
+			//		True to allow user to open/close pane by clicking title bar.
 
-		this._setOpenAttr(!this.open, true);
-	},
+			this.focusNode.setAttribute("role", canToggle ? "button" : "heading");
+			if(canToggle){
+				this.focusNode.setAttribute("aria-controls", this.id + "_pane");
+				this.focusNode.setAttribute("tabIndex", this.tabIndex);
+				this.focusNode.setAttribute("aria-pressed", this.open);
+			}else{
+				domAttr.remove(this.focusNode, "aria-controls");
+				domAttr.remove(this.focusNode, "tabIndex");
+				domAttr.remove(this.focusNode, "aria-pressed");
+			}
 
-	_setCss: function(){
-		// summary:
-		//		Set the open/close css state for the TitlePane
-		// tags:
-		//		private
+			this._set("toggleable", canToggle);
 
-		var node = this.titleBarNode || this.focusNode;
-		var oldCls = this._titleBarClass;
-		this._titleBarClass = "dijit" + (this.toggleable ? "" : "Fixed") + (this.open ? "Open" : "Closed");
-		domClass.replace(node, this._titleBarClass, oldCls || "");
+			this._setCss();
+		},
 
-		this.arrowNodeInner.innerHTML = this.open ? "-" : "+";
-	},
+		_setContentAttr: function(/*String|DomNode|Nodelist*/ content){
+			// summary:
+			//		Hook to make set("content", ...) work.
+			//		Typically called when an href is loaded.  Our job is to make the animation smooth.
 
-	_onTitleKey: function(/*Event*/ e){
-		// summary:
-		//		Handler for when user hits a key
-		// tags:
-		//		private
+			if(!this.open || !this._wipeOut || this._wipeOut.status() == "playing"){
+				// we are currently *closing* the pane (or the pane is closed), so just let that continue
+				this.inherited(arguments);
+			}else{
+				if(this._wipeIn && this._wipeIn.status() == "playing"){
+					this._wipeIn.stop();
+				}
+
+				// freeze container at current height so that adding new content doesn't make it jump
+				domGeometry.setMarginBox(this.wipeNode, { h: domGeometry.getMarginBox(this.wipeNode).h });
+
+				// add the new content (erasing the old content, if any)
+				this.inherited(arguments);
+
+				// call _wipeIn.play() to animate from current height to new height
+				if(this._wipeIn){
+					this._wipeIn.play();
+				}else{
+					this.hideNode.style.display = "";
+				}
+			}
+		},
+
+		toggle: function(){
+			// summary:
+			//		Switches between opened and closed state
+			// tags:
+			//		private
+
+			this._setOpenAttr(!this.open, true);
+		},
+
+		_setCss: function(){
+			// summary:
+			//		Set the open/close css state for the TitlePane
+			// tags:
+			//		private
+
+			var node = this.titleBarNode || this.focusNode;
+			var oldCls = this._titleBarClass;
+			this._titleBarClass = this.baseClass + "Title" + (this.toggleable ? "" : "Fixed") + (this.open ? "Open" : "Closed");
+			domClass.replace(node, this._titleBarClass, oldCls || "");
+
+			// Back compat, remove for 2.0
+			domClass.replace(node, this._titleBarClass.replace("TitlePaneTitle", ""), (oldCls || "").replace("TitlePaneTitle", ""));
+
+			this.arrowNodeInner.innerHTML = this.open ? "-" : "+";
+		},
+
+		_onTitleKey: function(/*Event*/ e){
+			// summary:
+			//		Handler for when user hits a key
+			// tags:
+			//		private
+
+			if(e.keyCode == keys.DOWN_ARROW && this.open){
+				this.containerNode.focus();
+				e.preventDefault();
+			}
+		},
 
-		if(e.charOrCode == keys.ENTER || e.charOrCode == ' '){
+		_onTitleClick: function(){
+			// summary:
+			//		Handler when user clicks the title bar
+			// tags:
+			//		private
 			if(this.toggleable){
 				this.toggle();
 			}
-			event.stop(e);
-		}else if(e.charOrCode == keys.DOWN_ARROW && this.open){
-			this.containerNode.focus();
-			e.preventDefault();
-	 	}
-	},
-
-	_onTitleClick: function(){
-		// summary:
-		//		Handler when user clicks the title bar
-		// tags:
-		//		private
-		if(this.toggleable){
-			this.toggle();
+		},
+
+		setTitle: function(/*String*/ title){
+			// summary:
+			//		Deprecated.  Use set('title', ...) instead.
+			// tags:
+			//		deprecated
+			kernel.deprecated("dijit.TitlePane.setTitle() is deprecated.  Use set('title', ...) instead.", "", "2.0");
+			this.set("title", title);
 		}
-	},
-
-	setTitle: function(/*String*/ title){
-		// summary:
-		//		Deprecated.  Use set('title', ...) instead.
-		// tags:
-		//		deprecated
-		kernel.deprecated("dijit.TitlePane.setTitle() is deprecated.  Use set('title', ...) instead.", "", "2.0");
-		this.set("title", title);
+	});
+
+	if(has("dojo-bidi")){
+		TitlePane.extend({
+			_setTitleAttr: function(/*String*/ title){
+				// Override default where title becomes a hover tooltip
+				this._set("title", title);
+				this.titleNode.innerHTML = title;
+				this.applyTextDir(this.titleNode);
+			},
+
+			_setTooltipAttr: function(/*String*/ tooltip){
+				this._set("tooltip", tooltip);
+				if(this.textDir){
+					tooltip = this.enforceTextDirWithUcc(null, tooltip);
+				}
+				domAttr.set(this.focusNode, "title", tooltip);			// focusNode spans the entire width, titleNode doesn't
+			},
+
+			_setTextDirAttr: function(textDir){
+				if(this._created && this.textDir != textDir){
+					this._set("textDir", textDir);
+					this.set("title", this.title);
+					this.set("tooltip", this.tooltip);
+				}
+			}
+		});
 	}
-});
 
+	return TitlePane;
 });
diff --git a/dijit/Toolbar.js b/dijit/Toolbar.js
index df0201d..6f96466 100644
--- a/dijit/Toolbar.js
+++ b/dijit/Toolbar.js
@@ -1,28 +1,20 @@
 define([
 	"require",
 	"dojo/_base/declare", // declare
-	"dojo/_base/kernel",
+	"dojo/has",
 	"dojo/keys", // keys.LEFT_ARROW keys.RIGHT_ARROW
 	"dojo/ready",
 	"./_Widget",
 	"./_KeyNavContainer",
 	"./_TemplatedMixin"
-], function(require, declare, kernel, keys, ready, _Widget, _KeyNavContainer, _TemplatedMixin){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _KeyNavContainer = dijit._KeyNavContainer;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-=====*/
+], function(require, declare, has, keys, ready, _Widget, _KeyNavContainer, _TemplatedMixin){
 
 	// module:
 	//		dijit/Toolbar
-	// summary:
-	//		A Toolbar widget, used to hold things like `dijit.Editor` buttons
 
 
 	// Back compat w/1.6, remove for 2.0
-	if(!kernel.isAsync){
+	if(has("dijit-legacy-requires")){
 		ready(0, function(){
 			var requires = ["dijit/ToolbarSeparator"];
 			require(requires);	// use indirection so modules not rolled into a build
@@ -31,7 +23,7 @@ define([
 
 	return declare("dijit.Toolbar", [_Widget, _TemplatedMixin, _KeyNavContainer], {
 		// summary:
-		//		A Toolbar widget, used to hold things like `dijit.Editor` buttons
+		//		A Toolbar widget, used to hold things like `dijit/Editor` buttons
 
 		templateString:
 			'<div class="dijit" role="toolbar" tabIndex="${tabIndex}" data-dojo-attach-point="containerNode">' +
@@ -39,13 +31,12 @@ define([
 
 		baseClass: "dijitToolbar",
 
-		postCreate: function(){
-			this.inherited(arguments);
+		_onLeftArrow: function(){
+			this.focusPrev();
+		},
 
-			this.connectKeyNavHandlers(
-				this.isLeftToRight() ? [keys.LEFT_ARROW] : [keys.RIGHT_ARROW],
-				this.isLeftToRight() ? [keys.RIGHT_ARROW] : [keys.LEFT_ARROW]
-			);
+		_onRightArrow: function(){
+			this.focusNext();
 		}
 	});
 });
diff --git a/dijit/ToolbarSeparator.js b/dijit/ToolbarSeparator.js
index 33a7ca9..2ec6420 100644
--- a/dijit/ToolbarSeparator.js
+++ b/dijit/ToolbarSeparator.js
@@ -5,15 +5,8 @@ define([
 	"./_TemplatedMixin"
 ], function(declare, dom, _Widget, _TemplatedMixin){
 
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-=====*/
-
 	// module:
 	//		dijit/ToolbarSeparator
-	// summary:
-	//		A spacer between two `dijit.Toolbar` items
 
 
 	return declare("dijit.ToolbarSeparator", [_Widget, _TemplatedMixin], {
diff --git a/dijit/Tooltip.js b/dijit/Tooltip.js
index 7029689..4411e15 100644
--- a/dijit/Tooltip.js
+++ b/dijit/Tooltip.js
@@ -4,33 +4,34 @@ define([
 	"dojo/_base/fx", // fx.fadeIn fx.fadeOut
 	"dojo/dom", // dom.byId
 	"dojo/dom-class", // domClass.add
-	"dojo/dom-geometry", // domGeometry.getMarginBox domGeometry.position
+	"dojo/dom-geometry", // domGeometry.position
 	"dojo/dom-style", // domStyle.set, domStyle.get
 	"dojo/_base/lang", // lang.hitch lang.isArrayLike
-	"dojo/_base/sniff", // has("ie")
-	"dojo/_base/window", // win.body
+	"dojo/mouse",
+	"dojo/on",
+	"dojo/sniff", // has("ie")
 	"./_base/manager",	// manager.defaultDuration
 	"./place",
 	"./_Widget",
 	"./_TemplatedMixin",
 	"./BackgroundIframe",
 	"dojo/text!./templates/Tooltip.html",
-	"."		// sets dijit.showTooltip etc. for back-compat
-], function(array, declare, fx, dom, domClass, domGeometry, domStyle, lang, has, win,
+	"./main"		// sets dijit.showTooltip etc. for back-compat
+], function(array, declare, fx, dom, domClass, domGeometry, domStyle, lang, mouse, on, has,
 			manager, place, _Widget, _TemplatedMixin, BackgroundIframe, template, dijit){
 
-/*=====
-	var _Widget = dijit._Widget;
-	var BackgroundIframe = dijit.BackgroundIframe;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-=====*/
-
 	// module:
 	//		dijit/Tooltip
-	// summary:
-	//		Defines dijit.Tooltip widget (to display a tooltip), showTooltip()/hideTooltip(), and _MasterTooltip
 
 
+	// TODO: Tooltip should really share more positioning code with TooltipDialog, like:
+	//		- the orient() method
+	//		- the connector positioning code in show()
+	//		- the dijitTooltip[Dialog] class
+	//
+	// The problem is that Tooltip's implementation supplies it's own <iframe> and interacts directly
+	// with dijit/place, rather than going through dijit/popup like TooltipDialog and other popups (ex: Menu).
+
 	var MasterTooltip = declare("dijit._MasterTooltip", [_Widget, _TemplatedMixin], {
 		// summary:
 		//		Internal widget that holds the actual tooltip markup,
@@ -47,7 +48,7 @@ define([
 		templateString: template,
 
 		postCreate: function(){
-			win.body().appendChild(this.domNode);
+			this.ownerDocumentBody.appendChild(this.domNode);
 
 			this.bgIframe = new BackgroundIframe(this.domNode);
 
@@ -62,7 +63,7 @@ define([
 			//		(To left if there's no space on the right, or if rtl == true)
 			// innerHTML: String
 			//		Contents of the tooltip
-			// aroundNode: DomNode || dijit.__Rectangle
+			// aroundNode: DomNode|dijit/place.__Rectangle
 			//		Specifies that tooltip should be next to this node / area
 			// position: String[]?
 			//		List of positions to try to position tooltip (ex: ["right", "above"])
@@ -77,17 +78,17 @@ define([
 				return;
 			}
 
-			// reset width; it may have been set by orient() on a previous tooltip show()
-			this.domNode.width = "auto";
-
 			if(this.fadeOut.status() == "playing"){
 				// previous tooltip is being hidden; wait until the hide completes then show new one
 				this._onDeck=arguments;
 				return;
 			}
 			this.containerNode.innerHTML=innerHTML;
-			
-			this.set("textDir", textDir);
+
+			if(textDir){
+				this.set("textDir", textDir);
+			}
+
 			this.containerNode.align = rtl? "right" : "left"; //fix the text alignment
 
 			var pos = place.around(this.domNode, aroundNode,
@@ -101,6 +102,10 @@ define([
 				this.connectorNode.style.left = "";
 			}else if(pos.corner.charAt(1) == 'M' && pos.aroundCorner.charAt(1) == 'M'){
 				this.connectorNode.style.left = aroundNodeCoords.x + ((aroundNodeCoords.w - this.connectorNode.offsetWidth) >> 1) - pos.x + "px";
+			}else{
+				// Not *-centered, but just above/below/after/before
+				this.connectorNode.style.left = "";
+				this.connectorNode.style.top = "";
 			}
 
 			// show it
@@ -117,10 +122,11 @@ define([
 			//		width to whatever width is available
 			// tags:
 			//		protected
+
 			this.connectorNode.style.top = ""; //reset to default
 
-			//Adjust the spaceAvailable width, without changing the spaceAvailable object
-			var tooltipSpaceAvaliableWidth = spaceAvailable.w - this.connectorNode.offsetWidth;
+			var heightAvailable = spaceAvailable.h,
+				widthAvailable = spaceAvailable.w;
 
 			node.className = "dijitTooltip " +
 				{
@@ -136,33 +142,29 @@ define([
 					"BL-BR": "dijitTooltipLeft"
 				}[aroundCorner + "-" + tooltipCorner];
 
-			// reduce tooltip's width to the amount of width available, so that it doesn't overflow screen
+			// reset width; it may have been set by orient() on a previous tooltip show()
 			this.domNode.style.width = "auto";
-			var size = domGeometry.getContentBox(this.domNode);
 
-			var width = Math.min((Math.max(tooltipSpaceAvaliableWidth,1)), size.w);
-			var widthWasReduced = width < size.w;
+			// Reduce tooltip's width to the amount of width available, so that it doesn't overflow screen.
+			// Note that sometimes widthAvailable is negative, but we guard against setting style.width to a
+			// negative number since that causes an exception on IE.
+			var size = domGeometry.position(this.domNode);
+			if(has("ie") == 9){
+				// workaround strange IE9 bug where setting width to offsetWidth causes words to wrap
+				size.w += 2;
+			}
 
-			this.domNode.style.width = width+"px";
+			var width = Math.min((Math.max(widthAvailable,1)), size.w);
 
-			//Adjust width for tooltips that have a really long word or a nowrap setting
-			if(widthWasReduced){
-				this.containerNode.style.overflow = "auto"; //temp change to overflow to detect if our tooltip needs to be wider to support the content
-				var scrollWidth = this.containerNode.scrollWidth;
-				this.containerNode.style.overflow = "visible"; //change it back
-				if(scrollWidth > width){
-					scrollWidth = scrollWidth + domStyle.get(this.domNode,"paddingLeft") + domStyle.get(this.domNode,"paddingRight");
-					this.domNode.style.width = scrollWidth + "px";
-				}
-			}
+			domGeometry.setMarginBox(this.domNode, {w: width});
 
 			// Reposition the tooltip connector.
 			if(tooltipCorner.charAt(0) == 'B' && aroundCorner.charAt(0) == 'B'){
-				var mb = domGeometry.getMarginBox(node);
+				var bb = domGeometry.position(node);
 				var tooltipConnectorHeight = this.connectorNode.offsetHeight;
-				if(mb.h > spaceAvailable.h){
+				if(bb.h > heightAvailable){
 					// The tooltip starts at the top of the page and will extend past the aroundNode
-					var aroundNodePlacement = spaceAvailable.h - ((aroundNodeCoords.h + tooltipConnectorHeight) >> 1);
+					var aroundNodePlacement = heightAvailable - ((aroundNodeCoords.h + tooltipConnectorHeight) >> 1);
 					this.connectorNode.style.top = aroundNodePlacement + "px";
 					this.connectorNode.style.bottom = "";
 				}else{
@@ -171,7 +173,7 @@ define([
 					// extend past top of tooltip content
 					this.connectorNode.style.bottom = Math.min(
 						Math.max(aroundNodeCoords.h/2 - tooltipConnectorHeight/2, 0),
-						mb.h - tooltipConnectorHeight) + "px";
+						bb.h - tooltipConnectorHeight) + "px";
 					this.connectorNode.style.top = "";
 				}
 			}else{
@@ -180,7 +182,7 @@ define([
 				this.connectorNode.style.bottom = "";
 			}
 
-			return Math.max(0, size.w - tooltipSpaceAvaliableWidth);
+			return Math.max(0, size.w - widthAvailable);
 		},
 
 		_onShow: function(){
@@ -226,44 +228,49 @@ define([
 				this.show.apply(this, this._onDeck);
 				this._onDeck=null;
 			}
-		},
-		
-		_setAutoTextDir: function(/*Object*/node){
-		    // summary:
-		    //	    Resolve "auto" text direction for children nodes
-		    // tags:
-		    //		private
-
-            this.applyTextDir(node, has("ie") ? node.outerText : node.textContent);
-            array.forEach(node.children, function(child){this._setAutoTextDir(child); }, this);
-		},
-		
-		_setTextDirAttr: function(/*String*/ textDir){
-		    // summary:
-		    //		Setter for textDir.
-		    // description:
-		    //		Users shouldn't call this function; they should be calling
-		    //		set('textDir', value)
-		    // tags:
-		    //		private
-	
-            this._set("textDir", typeof textDir != 'undefined'? textDir : "");
-    	    if (textDir == "auto"){
-    	        this._setAutoTextDir(this.containerNode);
-    	    }else{
-    	        this.containerNode.dir = this.textDir;
-    	    }  		             		        
-        }
+		}
 	});
 
+	if(has("dojo-bidi")){
+		MasterTooltip.extend({
+			_setAutoTextDir: function(/*Object*/node){
+				// summary:
+				//		Resolve "auto" text direction for children nodes
+				// tags:
+				//		private
+
+				this.applyTextDir(node);
+				array.forEach(node.children, function(child){ this._setAutoTextDir(child); }, this);
+			},
+
+			_setTextDirAttr: function(/*String*/ textDir){
+				// summary:
+				//		Setter for textDir.
+				// description:
+				//		Users shouldn't call this function; they should be calling
+				//		set('textDir', value)
+				// tags:
+				//		private
+
+				this._set("textDir", textDir);
+
+				if (textDir == "auto"){
+					this._setAutoTextDir(this.containerNode);
+				}else{
+					this.containerNode.dir = this.textDir;
+				}
+			}
+		});
+	}
+
 	dijit.showTooltip = function(innerHTML, aroundNode, position, rtl, textDir){
 		// summary:
 		//		Static method to display tooltip w/specified contents in specified position.
-		//		See description of dijit.Tooltip.defaultPosition for details on position parameter.
-		//		If position is not specified then dijit.Tooltip.defaultPosition is used.
+		//		See description of dijit/Tooltip.defaultPosition for details on position parameter.
+		//		If position is not specified then dijit/Tooltip.defaultPosition is used.
 		// innerHTML: String
 		//		Contents of the tooltip
-		// aroundNode: dijit.__Rectangle
+		// aroundNode: place.__Rectangle
 		//		Specifies that tooltip should be next to this node / area
 		// position: String[]?
 		//		List of positions to try to position tooltip (ex: ["right", "above"])
@@ -272,6 +279,15 @@ define([
 		//		means "rtl"; specifies GUI direction, not text direction.
 		// textDir: String?
 		//		Corresponds to `WidgetBase.textdir` attribute; specifies direction of text.
+
+		// After/before don't work, but for back-compat convert them to the working after-centered, before-centered.
+		// Possibly remove this in 2.0.   Alternately, get before/after to work.
+		if(position){
+			position = array.map(position, function(val){
+				return {after: "after-centered", before: "before-centered"}[val] || val;
+			});
+		}
+
 		if(!Tooltip._masterTT){ dijit._masterTT = Tooltip._masterTT = new MasterTooltip(); }
 		return Tooltip._masterTT.show(innerHTML, aroundNode, position, rtl, textDir);
 	};
@@ -285,9 +301,10 @@ define([
 	var Tooltip = declare("dijit.Tooltip", _Widget, {
 		// summary:
 		//		Pops up a tooltip (a help message) when you hover over a node.
+		//		Also provides static show() and hide() methods that can be used without instantiating a dijit/Tooltip.
 
 		// label: String
-		//		Text to display in the tooltip.
+		//		HTML to display in the tooltip.
 		//		Specified as innerHTML when creating the widget from markup.
 		label: "",
 
@@ -296,43 +313,64 @@ define([
 		//		the tooltip is displayed.
 		showDelay: 400,
 
-		// connectId: String|String[]
+		// connectId: String|String[]|DomNode|DomNode[]
 		//		Id of domNode(s) to attach the tooltip to.
-		//		When user hovers over specified dom node, the tooltip will appear.
+		//		When user hovers over specified dom node(s), the tooltip will appear.
 		connectId: [],
 
 		// position: String[]
-		//		See description of `dijit.Tooltip.defaultPosition` for details on position parameter.
+		//		See description of `dijit/Tooltip.defaultPosition` for details on position parameter.
 		position: [],
 
-		_setConnectIdAttr: function(/*String|String[]*/ newId){
+		// selector: String?
+		//		CSS expression to apply this Tooltip to descendants of connectIds, rather than to
+		//		the nodes specified by connectIds themselves.    Useful for applying a Tooltip to
+		//		a range of rows in a table, tree, etc.   Use in conjunction with getContent() parameter.
+		//		Ex: connectId: myTable, selector: "tr", getContent: function(node){ return ...; }
+		//
+		//		The application must require() an appropriate level of dojo/query to handle the selector.
+		selector: "",
+
+		// TODO: in 2.0 remove support for multiple connectIds.   selector gives the same effect.
+		// So, change connectId to a "", remove addTarget()/removeTarget(), etc.
+
+		_setConnectIdAttr: function(/*String|String[]|DomNode|DomNode[]*/ newId){
 			// summary:
 			//		Connect to specified node(s)
 
 			// Remove connections to old nodes (if there are any)
 			array.forEach(this._connections || [], function(nested){
-				array.forEach(nested, lang.hitch(this, "disconnect"));
+				array.forEach(nested, function(handle){ handle.remove(); });
 			}, this);
 
 			// Make array of id's to connect to, excluding entries for nodes that don't exist yet, see startup()
 			this._connectIds = array.filter(lang.isArrayLike(newId) ? newId : (newId ? [newId] : []),
-					function(id){ return dom.byId(id); });
+					function(id){ return dom.byId(id, this.ownerDocument); }, this);
 
 			// Make connections
 			this._connections = array.map(this._connectIds, function(id){
-				var node = dom.byId(id);
+				var node = dom.byId(id, this.ownerDocument),
+					selector = this.selector,
+					delegatedEvent = selector ?
+						function(eventType){ return on.selector(selector, eventType); } :
+						function(eventType){ return eventType; },
+					self = this;
 				return [
-					this.connect(node, "onmouseenter", "_onHover"),
-					this.connect(node, "onmouseleave", "_onUnHover"),
-					this.connect(node, "onfocus", "_onHover"),
-					this.connect(node, "onblur", "_onUnHover")
+					on(node, delegatedEvent(mouse.enter), function(){
+						self._onHover(this);
+					}),
+					on(node, delegatedEvent("focusin"), function(){
+						self._onHover(this);
+					}),
+					on(node, delegatedEvent(mouse.leave), lang.hitch(self, "_onUnHover")),
+					on(node, delegatedEvent("focusout"), lang.hitch(self, "_onUnHover"))
 				];
 			}, this);
 
 			this._set("connectId", newId);
 		},
 
-		addTarget: function(/*DOMNODE || String*/ node){
+		addTarget: function(/*OomNode|String*/ node){
 			// summary:
 			//		Attach tooltip to specified node if it's not already connected
 
@@ -344,7 +382,7 @@ define([
 			}
 		},
 
-		removeTarget: function(/*DomNode || String*/ node){
+		removeTarget: function(/*DomNode|String*/ node){
 			// summary:
 			//		Detach tooltip from specified node
 
@@ -373,49 +411,57 @@ define([
 			array.forEach(lang.isArrayLike(ids) ? ids : [ids], this.addTarget, this);
 		},
 
-		_onHover: function(/*Event*/ e){
+		getContent: function(/*DomNode*/ node){
+			// summary:
+			//		User overridable function that return the text to display in the tooltip.
+			// tags:
+			//		extension
+			return this.label || this.domNode.innerHTML;
+		},
+
+		_onHover: function(/*DomNode*/ target){
 			// summary:
 			//		Despite the name of this method, it actually handles both hover and focus
 			//		events on the target node, setting a timer to show the tooltip.
 			// tags:
 			//		private
 			if(!this._showTimer){
-				var target = e.target;
-				this._showTimer = setTimeout(lang.hitch(this, function(){this.open(target)}), this.showDelay);
+				this._showTimer = this.defer(function(){ this.open(target); }, this.showDelay);
 			}
 		},
 
-		_onUnHover: function(/*Event*/ /*===== e =====*/){
+		_onUnHover: function(){
 			// summary:
 			//		Despite the name of this method, it actually handles both mouseleave and blur
 			//		events on the target node, hiding the tooltip.
 			// tags:
 			//		private
 
-			// keep a tooltip open if the associated element still has focus (even though the
-			// mouse moved away)
-			if(this._focus){ return; }
-
 			if(this._showTimer){
-				clearTimeout(this._showTimer);
+				this._showTimer.remove();
 				delete this._showTimer;
 			}
 			this.close();
 		},
 
 		open: function(/*DomNode*/ target){
- 			// summary:
+			// summary:
 			//		Display the tooltip; usually not called directly.
 			// tags:
 			//		private
 
 			if(this._showTimer){
-				clearTimeout(this._showTimer);
+				this._showTimer.remove();
 				delete this._showTimer;
 			}
-			Tooltip.show(this.label || this.domNode.innerHTML, target, this.position, !this.isLeftToRight(), this.textDir);
 
-			this._connectNode = target;
+			var content = this.getContent(target);
+			if(!content){
+				return;
+			}
+			Tooltip.show(content, target, this.position, !this.isLeftToRight(), this.textDir);
+
+			this._connectNode = target;		// _connectNode means "tooltip currently displayed for this node"
 			this.onShow(target, this.position);
 		},
 
@@ -433,7 +479,7 @@ define([
 			}
 			if(this._showTimer){
 				// if tooltip is scheduled to be shown (after a brief delay)
-				clearTimeout(this._showTimer);
+				this._showTimer.remove();
 				delete this._showTimer;
 			}
 		},
@@ -452,8 +498,14 @@ define([
 			//		callback
 		},
 
-		uninitialize: function(){
+		destroy: function(){
 			this.close();
+
+			// Remove connections manually since they aren't registered to be removed by _WidgetBase
+			array.forEach(this._connections || [], function(nested){
+				array.forEach(nested, function(handle){ handle.remove(); });
+			}, this);
+
 			this.inherited(arguments);
 		}
 	});
@@ -462,28 +514,31 @@ define([
 	Tooltip.show = dijit.showTooltip;		// export function through module return value
 	Tooltip.hide = dijit.hideTooltip;		// export function through module return value
 
-	// dijit.Tooltip.defaultPosition: String[]
-	//		This variable controls the position of tooltips, if the position is not specified to
-	//		the Tooltip widget or *TextBox widget itself.  It's an array of strings with the values
-	//		possible for `dijit/place::around()`.   The recommended values are:
-	//
-	//			* before-centered: centers tooltip to the left of the anchor node/widget, or to the right
-	//				 in the case of RTL scripts like Hebrew and Arabic
-	//			* after-centered: centers tooltip to the right of the anchor node/widget, or to the left
-	//				 in the case of RTL scripts like Hebrew and Arabic
-	//			* above-centered: tooltip is centered above anchor node
-	//			* below-centered: tooltip is centered above anchor node
-	//
-	//		The list is positions is tried, in order, until a position is found where the tooltip fits
-	//		within the viewport.
-	//
-	//		Be careful setting this parameter.  A value of "above-centered" may work fine until the user scrolls
-	//		the screen so that there's no room above the target node.   Nodes with drop downs, like
-	//		DropDownButton or FilteringSelect, are especially problematic, in that you need to be sure
-	//		that the drop down and tooltip don't overlap, even when the viewport is scrolled so that there
-	//		is only room below (or above) the target node, but not both.
 	Tooltip.defaultPosition = ["after-centered", "before-centered"];
 
-
+	/*=====
+	lang.mixin(Tooltip, {
+		 // defaultPosition: String[]
+		 //		This variable controls the position of tooltips, if the position is not specified to
+		 //		the Tooltip widget or *TextBox widget itself.  It's an array of strings with the values
+		 //		possible for `dijit/place.around()`.   The recommended values are:
+		 //
+		 //		- before-centered: centers tooltip to the left of the anchor node/widget, or to the right
+		 //		  in the case of RTL scripts like Hebrew and Arabic
+		 //		- after-centered: centers tooltip to the right of the anchor node/widget, or to the left
+		 //		  in the case of RTL scripts like Hebrew and Arabic
+		 //		- above-centered: tooltip is centered above anchor node
+		 //		- below-centered: tooltip is centered above anchor node
+		 //
+		 //		The list is positions is tried, in order, until a position is found where the tooltip fits
+		 //		within the viewport.
+		 //
+		 //		Be careful setting this parameter.  A value of "above-centered" may work fine until the user scrolls
+		 //		the screen so that there's no room above the target node.   Nodes with drop downs, like
+		 //		DropDownButton or FilteringSelect, are especially problematic, in that you need to be sure
+		 //		that the drop down and tooltip don't overlap, even when the viewport is scrolled so that there
+		 //		is only room below (or above) the target node, but not both.
+	 });
+	=====*/
 	return Tooltip;
 });
diff --git a/dijit/TooltipDialog.js b/dijit/TooltipDialog.js
index 78b58d2..84feba4 100644
--- a/dijit/TooltipDialog.js
+++ b/dijit/TooltipDialog.js
@@ -1,154 +1,198 @@
 define([
 	"dojo/_base/declare", // declare
 	"dojo/dom-class", // domClass.replace
-	"dojo/_base/event", // event.stop
+	"dojo/has",
 	"dojo/keys", // keys
 	"dojo/_base/lang", // lang.hitch
+	"dojo/on",
 	"./focus",
 	"./layout/ContentPane",
 	"./_DialogMixin",
 	"./form/_FormMixin",
 	"./_TemplatedMixin",
 	"dojo/text!./templates/TooltipDialog.html",
-	"."		// exports methods to dijit global
-], function(declare, domClass, event, keys, lang,
-			focus, ContentPane, _DialogMixin, _FormMixin, _TemplatedMixin, template, dijit){
-
-/*=====
-	var ContentPane = dijit.layout.ContentPane;
-	var _DialogMixin = dijit._DialogMixin;
-	var _FormMixin = dijit.form._FormMixin;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-=====*/
+	"./main"        // exports methods to dijit global
+], function(declare, domClass, has, keys, lang, on, focus, ContentPane, _DialogMixin, _FormMixin, _TemplatedMixin, template, dijit){
 
 	// module:
 	//		dijit/TooltipDialog
-	// summary:
-	//		Pops up a dialog that appears like a Tooltip
 
 
-	return declare("dijit.TooltipDialog",
+	var TooltipDialog = declare("dijit.TooltipDialog",
 		[ContentPane, _TemplatedMixin, _FormMixin, _DialogMixin], {
-		// summary:
-		//		Pops up a dialog that appears like a Tooltip
-
-		// title: String
-		// 		Description of tooltip dialog (required for a11y)
-		title: "",
-
-		// doLayout: [protected] Boolean
-		//		Don't change this parameter from the default value.
-		//		This ContentPane parameter doesn't make sense for TooltipDialog, since TooltipDialog
-		//		is never a child of a layout container, nor can you specify the size of
-		//		TooltipDialog in order to control the size of an inner widget.
-		doLayout: false,
-
-		// autofocus: Boolean
-		// 		A Toggle to modify the default focus behavior of a Dialog, which
-		// 		is to focus on the first dialog element after opening the dialog.
-		//		False will disable autofocusing. Default: true
-		autofocus: true,
-
-		// baseClass: [protected] String
-		//		The root className to use for the various states of this widget
-		baseClass: "dijitTooltipDialog",
-
-		// _firstFocusItem: [private] [readonly] DomNode
-		//		The pointer to the first focusable node in the dialog.
-		//		Set by `dijit._DialogMixin._getFocusItems`.
-		_firstFocusItem: null,
-
-		// _lastFocusItem: [private] [readonly] DomNode
-		//		The pointer to which node has focus prior to our dialog.
-		//		Set by `dijit._DialogMixin._getFocusItems`.
-		_lastFocusItem: null,
-
-		templateString: template,
-
-		_setTitleAttr: function(/*String*/ title){
-			this.containerNode.title = title;
-			this._set("title", title)
-		},
-
-		postCreate: function(){
-			this.inherited(arguments);
-			this.connect(this.containerNode, "onkeypress", "_onKey");
-		},
-
-		orient: function(/*DomNode*/ node, /*String*/ aroundCorner, /*String*/ corner){
-			// summary:
-			//		Configure widget to be displayed in given position relative to the button.
-			//		This is called from the dijit.popup code, and should not be called
-			//		directly.
-			// tags:
-			//		protected
-			var newC = "dijitTooltipAB" + (corner.charAt(1) == 'L' ? "Left" : "Right")
-					+ " dijitTooltip"
-					+ (corner.charAt(0) == 'T' ? "Below" : "Above");
-
-			domClass.replace(this.domNode, newC, this._currentOrientClass || "");
-			this._currentOrientClass = newC;
-		},
-
-		focus: function(){
-			// summary:
-			//		Focus on first field
-			this._getFocusItems(this.containerNode);
-			focus.focus(this._firstFocusItem);
-		},
-
-		onOpen: function(/*Object*/ pos){
-			// summary:
-			//		Called when dialog is displayed.
-			//		This is called from the dijit.popup code, and should not be called directly.
-			// tags:
-			//		protected
-
-			this.orient(this.domNode,pos.aroundCorner, pos.corner);
-			this._onShow(); // lazy load trigger
-		},
-
-		onClose: function(){
 			// summary:
-			//		Called when dialog is hidden.
-			//		This is called from the dijit.popup code, and should not be called directly.
-			// tags:
-			//		protected
-			this.onHide();
-		},
-
-		_onKey: function(/*Event*/ evt){
-			// summary:
-			//		Handler for keyboard events
-			// description:
-			//		Keep keyboard focus in dialog; close dialog on escape key
-			// tags:
-			//		private
-
-			var node = evt.target;
-			if(evt.charOrCode === keys.TAB){
+			//		Pops up a dialog that appears like a Tooltip
+
+			// title: String
+			//		Description of tooltip dialog (required for a11y)
+			title: "",
+
+			// doLayout: [protected] Boolean
+			//		Don't change this parameter from the default value.
+			//		This ContentPane parameter doesn't make sense for TooltipDialog, since TooltipDialog
+			//		is never a child of a layout container, nor can you specify the size of
+			//		TooltipDialog in order to control the size of an inner widget.
+			doLayout: false,
+
+			// autofocus: Boolean
+			//		A Toggle to modify the default focus behavior of a Dialog, which
+			//		is to focus on the first dialog element after opening the dialog.
+			//		False will disable autofocusing.  Default: true.
+			autofocus: true,
+
+			// baseClass: [protected] String
+			//		The root className to use for the various states of this widget
+			baseClass: "dijitTooltipDialog",
+
+			// _firstFocusItem: [private readonly] DomNode
+			//		The pointer to the first focusable node in the dialog.
+			//		Set by `dijit/_DialogMixin._getFocusItems()`.
+			_firstFocusItem: null,
+
+			// _lastFocusItem: [private readonly] DomNode
+			//		The pointer to which node has focus prior to our dialog.
+			//		Set by `dijit/_DialogMixin._getFocusItems()`.
+			_lastFocusItem: null,
+
+			templateString: template,
+
+			_setTitleAttr: "containerNode",
+
+			postCreate: function(){
+				this.inherited(arguments);
+				this.own(on(this.containerNode, "keydown", lang.hitch(this, "_onKey")));
+			},
+
+			orient: function(/*DomNode*/ node, /*String*/ aroundCorner, /*String*/ tooltipCorner){
+				// summary:
+				//		Configure widget to be displayed in given position relative to the button.
+				//		This is called from the dijit.popup code, and should not be called
+				//		directly.
+				// tags:
+				//		protected
+
+				// Note: intentionally not using dijitTooltip class since that sets position:absolute, which
+				// confuses dijit/popup trying to get the size of the tooltip.
+				var newC = {
+					// Real around node
+					"MR-ML": "dijitTooltipRight",
+					"ML-MR": "dijitTooltipLeft",
+					"TM-BM": "dijitTooltipAbove",
+					"BM-TM": "dijitTooltipBelow",
+					"BL-TL": "dijitTooltipBelow dijitTooltipABLeft",
+					"TL-BL": "dijitTooltipAbove dijitTooltipABLeft",
+					"BR-TR": "dijitTooltipBelow dijitTooltipABRight",
+					"TR-BR": "dijitTooltipAbove dijitTooltipABRight",
+					"BR-BL": "dijitTooltipRight",
+					"BL-BR": "dijitTooltipLeft",
+
+					// Positioning "around" a point, ex: mouse position
+					"BR-TL": "dijitTooltipBelow dijitTooltipABLeft",
+					"BL-TR": "dijitTooltipBelow dijitTooltipABRight",
+					"TL-BR": "dijitTooltipAbove dijitTooltipABRight",
+					"TR-BL": "dijitTooltipAbove dijitTooltipABLeft"
+				}[aroundCorner + "-" + tooltipCorner];
+
+				domClass.replace(this.domNode, newC, this._currentOrientClass || "");
+				this._currentOrientClass = newC;
+
+				// Tooltip.orient() has code to reposition connector for when Tooltip is before/after anchor.
+				// Not putting here to avoid code bloat, and since TooltipDialogs are generally above/below.
+				// Should combine code from Tooltip and TooltipDialog.
+			},
+
+			focus: function(){
+				// summary:
+				//		Focus on first field
 				this._getFocusItems(this.containerNode);
-			}
-			var singleFocusItem = (this._firstFocusItem == this._lastFocusItem);
-			if(evt.charOrCode == keys.ESCAPE){
-				// Use setTimeout to avoid crash on IE, see #10396.
-				setTimeout(lang.hitch(this, "onCancel"), 0);
-				event.stop(evt);
-			}else if(node == this._firstFocusItem && evt.shiftKey && evt.charOrCode === keys.TAB){
-				if(!singleFocusItem){
-					focus.focus(this._lastFocusItem); // send focus to last item in dialog
+				focus.focus(this._firstFocusItem);
+			},
+
+			onOpen: function(/*Object*/ pos){
+				// summary:
+				//		Called when dialog is displayed.
+				//		This is called from the dijit.popup code, and should not be called directly.
+				// tags:
+				//		protected
+
+				this.orient(this.domNode, pos.aroundCorner, pos.corner);
+
+				// Position the tooltip connector for middle alignment.
+				// This could not have been done in orient() since the tooltip wasn't positioned at that time.
+				var aroundNodeCoords = pos.aroundNodePos;
+				if(pos.corner.charAt(0) == 'M' && pos.aroundCorner.charAt(0) == 'M'){
+					this.connectorNode.style.top = aroundNodeCoords.y + ((aroundNodeCoords.h - this.connectorNode.offsetHeight) >> 1) - pos.y + "px";
+					this.connectorNode.style.left = "";
+				}else if(pos.corner.charAt(1) == 'M' && pos.aroundCorner.charAt(1) == 'M'){
+					this.connectorNode.style.left = aroundNodeCoords.x + ((aroundNodeCoords.w - this.connectorNode.offsetWidth) >> 1) - pos.x + "px";
+				}
+
+				this._onShow(); // lazy load trigger  (TODO: shouldn't we load before positioning?)
+			},
+
+			onClose: function(){
+				// summary:
+				//		Called when dialog is hidden.
+				//		This is called from the dijit.popup code, and should not be called directly.
+				// tags:
+				//		protected
+				this.onHide();
+			},
+
+			_onKey: function(/*Event*/ evt){
+				// summary:
+				//		Handler for keydown events
+				// description:
+				//		Keep keyboard focus in dialog; close dialog on escape key
+				// tags:
+				//		private
+
+				if(evt.keyCode == keys.ESCAPE){
+					// Use defer to avoid crash on IE, see #10396.  Not sure if this is still needed or not.
+					// If this if() wasn't here, presumably dijit/popup would catch the ESCAPE key and close the popup.
+					this.defer("onCancel");
+					evt.stopPropagation();
+					evt.preventDefault();
+				}else if(evt.keyCode == keys.TAB){
+					var node = evt.target;
+					this._getFocusItems(this.containerNode);
+					if(this._firstFocusItem == this._lastFocusItem){
+						evt.stopPropagation();
+						evt.preventDefault();
+					}else if(node == this._firstFocusItem && evt.shiftKey){
+						focus.focus(this._lastFocusItem); // send focus to last item in dialog
+						evt.stopPropagation();
+						evt.preventDefault();
+					}else if(node == this._lastFocusItem && !evt.shiftKey){
+						focus.focus(this._firstFocusItem); // send focus to first item in dialog
+						evt.stopPropagation();
+						evt.preventDefault();
+					}else{
+						// we want the browser's default tab handling to move focus
+						// but we don't want the tab to propagate upwards
+						evt.stopPropagation();
+					}
 				}
-				event.stop(evt);
-			}else if(node == this._lastFocusItem && evt.charOrCode === keys.TAB && !evt.shiftKey){
-				if(!singleFocusItem){
-					focus.focus(this._firstFocusItem); // send focus to first item in dialog
+			}
+		});
+
+	if(has("dojo-bidi")){
+		TooltipDialog.extend({
+			_setTitleAttr: function(/*String*/ title){
+				this.containerNode.title = (this.textDir && this.enforceTextDirWithUcc) ? this.enforceTextDirWithUcc(null, title) : title;
+				this._set("title", title);
+			},
+
+			_setTextDirAttr: function(/*String*/ textDir){
+				if(!this._created || this.textDir != textDir){
+					this._set("textDir", textDir);
+					if(this.textDir && this.title){
+						this.containerNode.title = this.enforceTextDirWithUcc(null, this.title);
+					}
 				}
-				event.stop(evt);
-			}else if(evt.charOrCode === keys.TAB){
-				// we want the browser's default tab handling to move focus
-				// but we don't want the tab to propagate upwards
-				evt.stopPropagation();
 			}
-		}
-	});
+		});
+	}
+
+	return TooltipDialog;
 });
diff --git a/dijit/Tree.js b/dijit/Tree.js
index faf398d..0f83dbf 100644
--- a/dijit/Tree.js
+++ b/dijit/Tree.js
@@ -1,1446 +1,1510 @@
 define([
 	"dojo/_base/array", // array.filter array.forEach array.map
-	"dojo/_base/connect",	// connect.isCopyKey()
+	"dojo/aspect",
+	"dojo/_base/connect", // connect.isCopyKey()
 	"dojo/cookie", // cookie
 	"dojo/_base/declare", // declare
-	"dojo/_base/Deferred", // Deferred
-	"dojo/DeferredList", // DeferredList
+	"dojo/Deferred", // Deferred
+	"dojo/promise/all",
 	"dojo/dom", // dom.isDescendant
 	"dojo/dom-class", // domClass.add domClass.remove domClass.replace domClass.toggle
 	"dojo/dom-geometry", // domGeometry.setMarginBox domGeometry.position
-	"dojo/dom-style",// domStyle.set
-	"dojo/_base/event", // event.stop
+	"dojo/dom-style", // domStyle.set
+	"dojo/errors/create", // createError
 	"dojo/fx", // fxUtils.wipeIn fxUtils.wipeOut
+	"dojo/has",
 	"dojo/_base/kernel", // kernel.deprecated
-	"dojo/keys",	// arrows etc.
+	"dojo/keys", // arrows etc.
 	"dojo/_base/lang", // lang.getObject lang.mixin lang.hitch
+	"dojo/on", // on(), on.selector()
 	"dojo/topic",
+	"dojo/touch",
+	"dojo/when",
+	"./a11yclick",
 	"./focus",
-	"./registry",	// registry.getEnclosingWidget(), manager.defaultDuration
-	"./_base/manager",	// manager.getEnclosingWidget(), manager.defaultDuration
+	"./registry", // registry.byNode(), registry.getEnclosingWidget()
+	"./_base/manager", // manager.defaultDuration
 	"./_Widget",
 	"./_TemplatedMixin",
 	"./_Container",
 	"./_Contained",
 	"./_CssStateMixin",
+	"./_KeyNavMixin",
 	"dojo/text!./templates/TreeNode.html",
 	"dojo/text!./templates/Tree.html",
 	"./tree/TreeStoreModel",
 	"./tree/ForestStoreModel",
-	"./tree/_dndSelector"
-], function(array, connect, cookie, declare, Deferred, DeferredList,
-			dom, domClass, domGeometry, domStyle, event, fxUtils, kernel, keys, lang, topic,
-			focus, registry, manager, _Widget, _TemplatedMixin, _Container, _Contained, _CssStateMixin,
+	"./tree/_dndSelector",
+	"dojo/query!css2"	// needed when on.selector() used with a string for the selector
+], function(array, aspect, connect, cookie, declare, Deferred, all,
+			dom, domClass, domGeometry, domStyle, createError, fxUtils, has, kernel, keys, lang, on, topic, touch, when,
+			a11yclick, focus, registry, manager, _Widget, _TemplatedMixin, _Container, _Contained, _CssStateMixin, _KeyNavMixin,
 			treeNodeTemplate, treeTemplate, TreeStoreModel, ForestStoreModel, _dndSelector){
 
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _CssStateMixin = dijit._CssStateMixin;
-	var _Container = dijit._Container;
-	var _Contained = dijit._Contained;
-=====*/
-
-// module:
-//		dijit/Tree
-// summary:
-//		dijit.Tree widget, and internal dijit._TreeNode widget
-
-
-var TreeNode = declare(
-	"dijit._TreeNode",
-	[_Widget, _TemplatedMixin, _Container, _Contained, _CssStateMixin],
-{
-	// summary:
-	//		Single node within a tree.   This class is used internally
-	//		by Tree and should not be accessed directly.
-	// tags:
-	//		private
-
-	// item: [const] Item
-	//		the dojo.data entry this tree represents
-	item: null,
-
-	// isTreeNode: [protected] Boolean
-	//		Indicates that this is a TreeNode.   Used by `dijit.Tree` only,
-	//		should not be accessed directly.
-	isTreeNode: true,
-
-	// label: String
-	//		Text of this tree node
-	label: "",
-	_setLabelAttr: {node: "labelNode", type: "innerText"},
-
-	// isExpandable: [private] Boolean
-	//		This node has children, so show the expando node (+ sign)
-	isExpandable: null,
-
-	// isExpanded: [readonly] Boolean
-	//		This node is currently expanded (ie, opened)
-	isExpanded: false,
-
-	// state: [private] String
-	//		Dynamic loading-related stuff.
-	//		When an empty folder node appears, it is "UNCHECKED" first,
-	//		then after dojo.data query it becomes "LOADING" and, finally "LOADED"
-	state: "UNCHECKED",
-
-	templateString: treeNodeTemplate,
-
-	baseClass: "dijitTreeNode",
-
-	// For hover effect for tree node, and focus effect for label
-	cssStateNodes: {
-		rowNode: "dijitTreeRow",
-		labelNode: "dijitTreeLabel"
-	},
-
-	// Tooltip is defined in _WidgetBase but we need to handle the mapping to DOM here
-	_setTooltipAttr: {node: "rowNode", type: "attribute", attribute: "title"},
-
-	buildRendering: function(){
-		this.inherited(arguments);
-
-		// set expand icon for leaf
-		this._setExpando();
-
-		// set icon and label class based on item
-		this._updateItemClasses(this.item);
-
-		if(this.isExpandable){
-			this.labelNode.setAttribute("aria-expanded", this.isExpanded);
-		}
-
-		//aria-selected should be false on all selectable elements.
-		this.setSelected(false);
-	},
+	// module:
+	//		dijit/Tree
 
-	_setIndentAttr: function(indent){
+	function shimmedPromise(/*Deferred|Promise*/ d){
 		// summary:
-		//		Tell this node how many levels it should be indented
-		// description:
-		//		0 for top level nodes, 1 for their children, 2 for their
-		//		grandchildren, etc.
-
-		// Math.max() is to prevent negative padding on hidden root node (when indent == -1)
-		var pixels = (Math.max(indent, 0) * this.tree._nodePixelIndent) + "px";
-
-		domStyle.set(this.domNode, "backgroundPosition",	pixels + " 0px");
-		domStyle.set(this.rowNode, this.isLeftToRight() ? "paddingLeft" : "paddingRight", pixels);
+		//		Return a Promise based on given Deferred or Promise, with back-compat addCallback() and addErrback() shims
+		//		added (TODO: remove those back-compat shims, and this method, for 2.0)
 
-		array.forEach(this.getChildren(), function(child){
-			child.set("indent", indent+1);
+		return lang.delegate(d.promise || d, {
+			addCallback: function(callback){
+				this.then(callback);
+			},
+			addErrback: function(errback){
+				this.otherwise(errback);
+			}
 		});
+	}
 
-		this._set("indent", indent);
-	},
-
-	markProcessing: function(){
+	var TreeNode = declare("dijit._TreeNode", [_Widget, _TemplatedMixin, _Container, _Contained, _CssStateMixin], {
 		// summary:
-		//		Visually denote that tree is loading data, etc.
+		//		Single node within a tree.   This class is used internally
+		//		by Tree and should not be accessed directly.
 		// tags:
 		//		private
-		this.state = "LOADING";
-		this._setExpando(true);
-	},
 
-	unmarkProcessing: function(){
-		// summary:
-		//		Clear markup from markProcessing() call
-		// tags:
-		//		private
-		this._setExpando(false);
-	},
+		// item: [const] Item
+		//		the dojo.data entry this tree represents
+		item: null,
 
-	_updateItemClasses: function(item){
-		// summary:
-		//		Set appropriate CSS classes for icon and label dom node
-		//		(used to allow for item updates to change respective CSS)
-		// tags:
-		//		private
-		var tree = this.tree, model = tree.model;
-		if(tree._v10Compat && item === model.root){
-			// For back-compat with 1.0, need to use null to specify root item (TODO: remove in 2.0)
-			item = null;
-		}
-		this._applyClassAndStyle(item, "icon", "Icon");
-		this._applyClassAndStyle(item, "label", "Label");
-		this._applyClassAndStyle(item, "row", "Row");
-	},
+		// isTreeNode: [protected] Boolean
+		//		Indicates that this is a TreeNode.   Used by `dijit.Tree` only,
+		//		should not be accessed directly.
+		isTreeNode: true,
 
-	_applyClassAndStyle: function(item, lower, upper){
-		// summary:
-		//		Set the appropriate CSS classes and styles for labels, icons and rows.
-		//
-		// item:
-		//		The data item.
-		//
-		// lower:
-		//		The lower case attribute to use, e.g. 'icon', 'label' or 'row'.
-		//
-		// upper:
-		//		The upper case attribute to use, e.g. 'Icon', 'Label' or 'Row'.
-		//
-		// tags:
-		//		private
+		// label: String
+		//		Text of this tree node
+		label: "",
+		_setLabelAttr: function(val){
+			this.labelNode[this.labelType == "html" ? "innerHTML" : "innerText" in this.labelNode ?
+				"innerText" : "textContent"] = val;
+			this._set("label", val);
+		},
 
-		var clsName = "_" + lower + "Class";
-		var nodeName = lower + "Node";
-		var oldCls = this[clsName];
+		// labelType: [const] String
+		//		Specifies how to interpret the label.  Can be "html" or "text".
+		labelType: "text",
 
-		this[clsName] = this.tree["get" + upper + "Class"](item, this.isExpanded);
-		domClass.replace(this[nodeName], this[clsName] || "", oldCls || "");
+		// isExpandable: [private] Boolean
+		//		This node has children, so show the expando node (+ sign)
+		isExpandable: null,
 
-		domStyle.set(this[nodeName], this.tree["get" + upper + "Style"](item, this.isExpanded) || {});
- 	},
+		// isExpanded: [readonly] Boolean
+		//		This node is currently expanded (ie, opened)
+		isExpanded: false,
 
-	_updateLayout: function(){
-		// summary:
-		//		Set appropriate CSS classes for this.domNode
-		// tags:
-		//		private
-		var parent = this.getParent();
-		if(!parent || !parent.rowNode || parent.rowNode.style.display == "none"){
-			/* if we are hiding the root node then make every first level child look like a root node */
-			domClass.add(this.domNode, "dijitTreeIsRoot");
-		}else{
-			domClass.toggle(this.domNode, "dijitTreeIsLast", !this.getNextSibling());
-		}
-	},
+		// state: [private] String
+		//		Dynamic loading-related stuff.
+		//		When an empty folder node appears, it is "NotLoaded" first,
+		//		then after dojo.data query it becomes "Loading" and, finally "Loaded"
+		state: "NotLoaded",
 
-	_setExpando: function(/*Boolean*/ processing){
-		// summary:
-		//		Set the right image for the expando node
-		// tags:
-		//		private
+		templateString: treeNodeTemplate,
 
-		var styles = ["dijitTreeExpandoLoading", "dijitTreeExpandoOpened",
-						"dijitTreeExpandoClosed", "dijitTreeExpandoLeaf"],
-			_a11yStates = ["*","-","+","*"],
-			idx = processing ? 0 : (this.isExpandable ?	(this.isExpanded ? 1 : 2) : 3);
+		baseClass: "dijitTreeNode",
 
-		// apply the appropriate class to the expando node
-		domClass.replace(this.expandoNode, styles[idx], styles);
+		// For hover effect for tree node, and focus effect for label
+		cssStateNodes: {
+			rowNode: "dijitTreeRow"
+		},
 
-		// provide a non-image based indicator for images-off mode
-		this.expandoNodeText.innerHTML = _a11yStates[idx];
+		// Tooltip is defined in _WidgetBase but we need to handle the mapping to DOM here
+		_setTooltipAttr: {node: "rowNode", type: "attribute", attribute: "title"},
 
-	},
+		buildRendering: function(){
+			this.inherited(arguments);
 
-	expand: function(){
-		// summary:
-		//		Show my children
-		// returns:
-		//		Deferred that fires when expansion is complete
+			// set expand icon for leaf
+			this._setExpando();
 
-		// If there's already an expand in progress or we are already expanded, just return
-		if(this._expandDeferred){
-			return this._expandDeferred;		// dojo.Deferred
-		}
+			// set icon and label class based on item
+			this._updateItemClasses(this.item);
 
-		// cancel in progress collapse operation
-		this._wipeOut && this._wipeOut.stop();
+			if(this.isExpandable){
+				this.labelNode.setAttribute("aria-expanded", this.isExpanded);
+			}
 
-		// All the state information for when a node is expanded, maybe this should be
-		// set when the animation completes instead
-		this.isExpanded = true;
-		this.labelNode.setAttribute("aria-expanded", "true");
-		if(this.tree.showRoot || this !== this.tree.rootNode){
-			this.containerNode.setAttribute("role", "group");
-		}
-		domClass.add(this.contentNode,'dijitTreeContentExpanded');
-		this._setExpando();
-		this._updateItemClasses(this.item);
-		if(this == this.tree.rootNode){
-			this.tree.domNode.setAttribute("aria-expanded", "true");
-		}
+			//aria-selected should be false on all selectable elements.
+			this.setSelected(false);
+		},
 
-		var def,
-			wipeIn = fxUtils.wipeIn({
-				node: this.containerNode, duration: manager.defaultDuration,
-				onEnd: function(){
-					def.callback(true);
-				}
+		_setIndentAttr: function(indent){
+			// summary:
+			//		Tell this node how many levels it should be indented
+			// description:
+			//		0 for top level nodes, 1 for their children, 2 for their
+			//		grandchildren, etc.
+
+			// Math.max() is to prevent negative padding on hidden root node (when indent == -1)
+			var pixels = (Math.max(indent, 0) * this.tree._nodePixelIndent) + "px";
+
+			domStyle.set(this.domNode, "backgroundPosition", pixels + " 0px");	// TODOC: what is this for???
+			domStyle.set(this.rowNode, this.isLeftToRight() ? "paddingLeft" : "paddingRight", pixels);
+
+			array.forEach(this.getChildren(), function(child){
+				child.set("indent", indent + 1);
 			});
 
-		// Deferred that fires when expand is complete
-		def = (this._expandDeferred = new Deferred(function(){
-			// Canceller
-			wipeIn.stop();
-		}));
+			this._set("indent", indent);
+		},
+
+		markProcessing: function(){
+			// summary:
+			//		Visually denote that tree is loading data, etc.
+			// tags:
+			//		private
+			this.state = "Loading";
+			this._setExpando(true);
+		},
+
+		unmarkProcessing: function(){
+			// summary:
+			//		Clear markup from markProcessing() call
+			// tags:
+			//		private
+			this._setExpando(false);
+		},
+
+		_updateItemClasses: function(item){
+			// summary:
+			//		Set appropriate CSS classes for icon and label dom node
+			//		(used to allow for item updates to change respective CSS)
+			// tags:
+			//		private
+			var tree = this.tree, model = tree.model;
+			if(tree._v10Compat && item === model.root){
+				// For back-compat with 1.0, need to use null to specify root item (TODO: remove in 2.0)
+				item = null;
+			}
+			this._applyClassAndStyle(item, "icon", "Icon");
+			this._applyClassAndStyle(item, "label", "Label");
+			this._applyClassAndStyle(item, "row", "Row");
+
+			this.tree._startPaint(true);		// signifies paint started and finished (synchronously)
+		},
+
+		_applyClassAndStyle: function(item, lower, upper){
+			// summary:
+			//		Set the appropriate CSS classes and styles for labels, icons and rows.
+			//
+			// item:
+			//		The data item.
+			//
+			// lower:
+			//		The lower case attribute to use, e.g. 'icon', 'label' or 'row'.
+			//
+			// upper:
+			//		The upper case attribute to use, e.g. 'Icon', 'Label' or 'Row'.
+			//
+			// tags:
+			//		private
+
+			var clsName = "_" + lower + "Class";
+			var nodeName = lower + "Node";
+			var oldCls = this[clsName];
+
+			this[clsName] = this.tree["get" + upper + "Class"](item, this.isExpanded);
+			domClass.replace(this[nodeName], this[clsName] || "", oldCls || "");
+
+			domStyle.set(this[nodeName], this.tree["get" + upper + "Style"](item, this.isExpanded) || {});
+		},
+
+		_updateLayout: function(){
+			// summary:
+			//		Set appropriate CSS classes for this.domNode
+			// tags:
+			//		private
+			var parent = this.getParent();
+			if(!parent || !parent.rowNode || parent.rowNode.style.display == "none"){
+				/* if we are hiding the root node then make every first level child look like a root node */
+				domClass.add(this.domNode, "dijitTreeIsRoot");
+			}else{
+				domClass.toggle(this.domNode, "dijitTreeIsLast", !this.getNextSibling());
+			}
+		},
 
-		wipeIn.play();
+		_setExpando: function(/*Boolean*/ processing){
+			// summary:
+			//		Set the right image for the expando node
+			// tags:
+			//		private
 
-		return def;		// dojo.Deferred
-	},
+			var styles = ["dijitTreeExpandoLoading", "dijitTreeExpandoOpened",
+					"dijitTreeExpandoClosed", "dijitTreeExpandoLeaf"],
+				_a11yStates = ["*", "-", "+", "*"],
+				idx = processing ? 0 : (this.isExpandable ? (this.isExpanded ? 1 : 2) : 3);
 
-	collapse: function(){
-		// summary:
-		//		Collapse this node (if it's expanded)
+			// apply the appropriate class to the expando node
+			domClass.replace(this.expandoNode, styles[idx], styles);
 
-		if(!this.isExpanded){ return; }
+			// provide a non-image based indicator for images-off mode
+			this.expandoNodeText.innerHTML = _a11yStates[idx];
 
-		// cancel in progress expand operation
-		if(this._expandDeferred){
-			this._expandDeferred.cancel();
-			delete this._expandDeferred;
-		}
+		},
 
-		this.isExpanded = false;
-		this.labelNode.setAttribute("aria-expanded", "false");
-		if(this == this.tree.rootNode){
-			this.tree.domNode.setAttribute("aria-expanded", "false");
-		}
-		domClass.remove(this.contentNode,'dijitTreeContentExpanded');
-		this._setExpando();
-		this._updateItemClasses(this.item);
+		expand: function(){
+			// summary:
+			//		Show my children
+			// returns:
+			//		Promise that resolves when expansion is complete
+
+			// If there's already an expand in progress or we are already expanded, just return
+			if(this._expandDeferred){
+				return shimmedPromise(this._expandDeferred);		// dojo/promise/Promise
+			}
+
+			// cancel in progress collapse operation
+			if(this._collapseDeferred){
+				this._collapseDeferred.cancel();
+				delete this._collapseDeferred;
+			}
+
+			// All the state information for when a node is expanded, maybe this should be
+			// set when the animation completes instead
+			this.isExpanded = true;
+			this.labelNode.setAttribute("aria-expanded", "true");
+			if(this.tree.showRoot || this !== this.tree.rootNode){
+				this.containerNode.setAttribute("role", "group");
+			}
+			domClass.add(this.contentNode, 'dijitTreeContentExpanded');
+			this._setExpando();
+			this._updateItemClasses(this.item);
+
+			if(this == this.tree.rootNode && this.tree.showRoot){
+				this.tree.domNode.setAttribute("aria-expanded", "true");
+			}
 
-		if(!this._wipeOut){
-			this._wipeOut = fxUtils.wipeOut({
-				node: this.containerNode, duration: manager.defaultDuration
+			var wipeIn = fxUtils.wipeIn({
+				node: this.containerNode,
+				duration: manager.defaultDuration
 			});
-		}
-		this._wipeOut.play();
-	},
 
-	// indent: Integer
-	//		Levels from this node to the root node
-	indent: 0,
+			// Deferred that fires when expand is complete
+			var def = (this._expandDeferred = new Deferred(function(){
+				// Canceller
+				wipeIn.stop();
+			}));
 
-	setChildItems: function(/* Object[] */ items){
-		// summary:
-		//		Sets the child items of this node, removing/adding nodes
-		//		from current children to match specified items[] array.
-		//		Also, if this.persist == true, expands any children that were previously
-		// 		opened.
-		// returns:
-		//		Deferred object that fires after all previously opened children
-		//		have been expanded again (or fires instantly if there are no such children).
+			aspect.after(wipeIn, "onEnd", function(){
+				def.resolve(true);
+			}, true);
 
-		var tree = this.tree,
-			model = tree.model,
-			defs = [];	// list of deferreds that need to fire before I am complete
+			wipeIn.play();
 
+			return shimmedPromise(def);		// dojo/promise/Promise
+		},
 
-		// Orphan all my existing children.
-		// If items contains some of the same items as before then we will reattach them.
-		// Don't call this.removeChild() because that will collapse the tree etc.
-		array.forEach(this.getChildren(), function(child){
-			_Container.prototype.removeChild.call(this, child);
-		}, this);
+		collapse: function(){
+			// summary:
+			//		Collapse this node (if it's expanded)
+			// returns:
+			//		Promise that resolves when collapse is complete
 
-		this.state = "LOADED";
+			if(this._collapseDeferred){
+				// Node is already collapsed, or there's a collapse in progress, just return that Deferred
+				return shimmedPromise(this._collapseDeferred);
+			}
 
-		if(items && items.length > 0){
-			this.isExpandable = true;
+			// cancel in progress expand operation
+			if(this._expandDeferred){
+				this._expandDeferred.cancel();
+				delete this._expandDeferred;
+			}
+
+			this.isExpanded = false;
+			this.labelNode.setAttribute("aria-expanded", "false");
+			if(this == this.tree.rootNode && this.tree.showRoot){
+				this.tree.domNode.setAttribute("aria-expanded", "false");
+			}
+			domClass.remove(this.contentNode, 'dijitTreeContentExpanded');
+			this._setExpando();
+			this._updateItemClasses(this.item);
 
-			// Create _TreeNode widget for each specified tree node, unless one already
-			// exists and isn't being used (presumably it's from a DnD move and was recently
-			// released
-			array.forEach(items, function(item){
-				var id = model.getIdentity(item),
-					existingNodes = tree._itemNodesMap[id],
-					node;
-				if(existingNodes){
-					for(var i=0;i<existingNodes.length;i++){
-						if(existingNodes[i] && !existingNodes[i].getParent()){
-							node = existingNodes[i];
-							node.set('indent', this.indent+1);
-							break;
+			var wipeOut = fxUtils.wipeOut({
+				node: this.containerNode,
+				duration: manager.defaultDuration
+			});
+
+			// Deferred that fires when expand is complete
+			var def = (this._collapseDeferred = new Deferred(function(){
+				// Canceller
+				wipeOut.stop();
+			}));
+
+			aspect.after(wipeOut, "onEnd", function(){
+				def.resolve(true);
+			}, true);
+
+			wipeOut.play();
+
+			return shimmedPromise(def);		// dojo/promise/Promise
+		},
+
+		// indent: Integer
+		//		Levels from this node to the root node
+		indent: 0,
+
+		setChildItems: function(/* Object[] */ items){
+			// summary:
+			//		Sets the child items of this node, removing/adding nodes
+			//		from current children to match specified items[] array.
+			//		Also, if this.persist == true, expands any children that were previously
+			//		opened.
+			// returns:
+			//		Promise that resolves after all previously opened children
+			//		have been expanded again (or fires instantly if there are no such children).
+
+			var tree = this.tree,
+				model = tree.model,
+				defs = [];	// list of deferreds that need to fire before I am complete
+
+
+			// Orphan all my existing children.
+			// If items contains some of the same items as before then we will reattach them.
+			// Don't call this.removeChild() because that will collapse the tree etc.
+			var oldChildren = this.getChildren();
+			array.forEach(oldChildren, function(child){
+				_Container.prototype.removeChild.call(this, child);
+			}, this);
+
+			// All the old children of this TreeNode are subject for destruction if
+			//		1) they aren't listed in the new children array (items)
+			//		2) they aren't immediately adopted by another node (DnD)
+			this.defer(function(){
+				array.forEach(oldChildren, function(node){
+					if(!node._destroyed && !node.getParent()){
+						// If node is in selection then remove it.
+						tree.dndController.removeTreeNode(node);
+
+						// Deregister mapping from item id --> this node and its descendants
+						function remove(node){
+							var id = model.getIdentity(node.item),
+								ary = tree._itemNodesMap[id];
+							if(ary.length == 1){
+								delete tree._itemNodesMap[id];
+							}else{
+								var index = array.indexOf(ary, node);
+								if(index != -1){
+									ary.splice(index, 1);
+								}
+							}
+							array.forEach(node.getChildren(), remove);
+						}
+
+						remove(node);
+
+						// Remove any entries involving this node from cookie tracking expanded nodes
+						if(tree.persist){
+							var destroyedPath = array.map(node.getTreePath(),function(item){
+								return tree.model.getIdentity(item);
+							}).join("/");
+							for(var path in tree._openedNodes){
+								if(path.substr(0, destroyedPath.length) == destroyedPath){
+									delete tree._openedNodes[path];
+								}
+							}
+							tree._saveExpandedNodes();
 						}
+
+						// And finally we can destroy the node
+						node.destroyRecursive();
 					}
-				}
-				if(!node){
-					node = this.tree._createTreeNode({
+				});
+			});
+
+			this.state = "Loaded";
+
+			if(items && items.length > 0){
+				this.isExpandable = true;
+
+				// Create _TreeNode widget for each specified tree node, unless one already
+				// exists and isn't being used (presumably it's from a DnD move and was recently
+				// released
+				array.forEach(items, function(item){    // MARKER: REUSE NODE
+					var id = model.getIdentity(item),
+						existingNodes = tree._itemNodesMap[id],
+						node;
+					if(existingNodes){
+						for(var i = 0; i < existingNodes.length; i++){
+							if(existingNodes[i] && !existingNodes[i].getParent()){
+								node = existingNodes[i];
+								node.set('indent', this.indent + 1);
+								break;
+							}
+						}
+					}
+					if(!node){
+						node = this.tree._createTreeNode({
 							item: item,
 							tree: tree,
 							isExpandable: model.mayHaveChildren(item),
 							label: tree.getLabel(item),
+							labelType: (tree.model && tree.model.labelType) || "text",
 							tooltip: tree.getTooltip(item),
+							ownerDocument: tree.ownerDocument,
 							dir: tree.dir,
 							lang: tree.lang,
 							textDir: tree.textDir,
 							indent: this.indent + 1
 						});
-					if(existingNodes){
-						existingNodes.push(node);
-					}else{
-						tree._itemNodesMap[id] = [node];
+						if(existingNodes){
+							existingNodes.push(node);
+						}else{
+							tree._itemNodesMap[id] = [node];
+						}
 					}
-				}
-				this.addChild(node);
-
-				// If node was previously opened then open it again now (this may trigger
-				// more data store accesses, recursively)
-				if(this.tree.autoExpand || this.tree._state(node)){
-					defs.push(tree._expandNode(node));
-				}
-			}, this);
-
-			// note that updateLayout() needs to be called on each child after
-			// _all_ the children exist
-			array.forEach(this.getChildren(), function(child){
-				child._updateLayout();
-			});
-		}else{
-			this.isExpandable=false;
-		}
+					this.addChild(node);
 
-		if(this._setExpando){
-			// change expando to/from dot or + icon, as appropriate
-			this._setExpando(false);
-		}
-
-		// Set leaf icon or folder icon, as appropriate
-		this._updateItemClasses(this.item);
+					// If node was previously opened then open it again now (this may trigger
+					// more data store accesses, recursively)
+					if(this.tree.autoExpand || this.tree._state(node)){
+						defs.push(tree._expandNode(node));
+					}
+				}, this);
 
-		// On initial tree show, make the selected TreeNode as either the root node of the tree,
-		// or the first child, if the root node is hidden
-		if(this == tree.rootNode){
-			var fc = this.tree.showRoot ? this : this.getChildren()[0];
-			if(fc){
-				fc.setFocusable(true);
-				tree.lastFocused = fc;
+				// note that updateLayout() needs to be called on each child after
+				// _all_ the children exist
+				array.forEach(this.getChildren(), function(child){
+					child._updateLayout();
+				});
 			}else{
-				// fallback: no nodes in tree so focus on Tree <div> itself
-				tree.domNode.setAttribute("tabIndex", "0");
+				this.isExpandable = false;
+			}
+
+			if(this._setExpando){
+				// change expando to/from dot or + icon, as appropriate
+				this._setExpando(false);
 			}
-		}
 
-		return new DeferredList(defs);	// dojo.Deferred
-	},
+			// Set leaf icon or folder icon, as appropriate
+			this._updateItemClasses(this.item);
 
-	getTreePath: function(){
-		var node = this;
-		var path = [];
-		while(node && node !== this.tree.rootNode){
+			var def = all(defs);
+			this.tree._startPaint(def);		// to reset TreeNode widths after an item is added/removed from the Tree
+			return shimmedPromise(def);		// dojo/promise/Promise
+		},
+
+		getTreePath: function(){
+			var node = this;
+			var path = [];
+			while(node && node !== this.tree.rootNode){
 				path.unshift(node.item);
 				node = node.getParent();
-		}
-		path.unshift(this.tree.rootNode.item);
+			}
+			path.unshift(this.tree.rootNode.item);
 
-		return path;
-	},
+			return path;
+		},
 
-	getIdentity: function(){
-		return this.tree.model.getIdentity(this.item);
-	},
+		getIdentity: function(){
+			return this.tree.model.getIdentity(this.item);
+		},
 
-	removeChild: function(/* treeNode */ node){
-		this.inherited(arguments);
+		removeChild: function(/* treeNode */ node){
+			this.inherited(arguments);
 
-		var children = this.getChildren();
-		if(children.length == 0){
-			this.isExpandable = false;
-			this.collapse();
-		}
+			var children = this.getChildren();
+			if(children.length == 0){
+				this.isExpandable = false;
+				this.collapse();
+			}
 
-		array.forEach(children, function(child){
+			array.forEach(children, function(child){
 				child._updateLayout();
-		});
-	},
-
-	makeExpandable: function(){
-		// summary:
-		//		if this node wasn't already showing the expando node,
-		//		turn it into one and call _setExpando()
-
-		// TODO: hmm this isn't called from anywhere, maybe should remove it for 2.0
-
-		this.isExpandable = true;
-		this._setExpando(false);
-	},
-
-	_onLabelFocus: function(){
-		// summary:
-		//		Called when this row is focused (possibly programatically)
-		//		Note that we aren't using _onFocus() builtin to dijit
-		//		because it's called when focus is moved to a descendant TreeNode.
-		// tags:
-		//		private
-		this.tree._onNodeFocus(this);
-	},
-
-	setSelected: function(/*Boolean*/ selected){
-		// summary:
-		//		A Tree has a (single) currently selected node.
-		//		Mark that this node is/isn't that currently selected node.
-		// description:
-		//		In particular, setting a node as selected involves setting tabIndex
-		//		so that when user tabs to the tree, focus will go to that node (only).
-		this.labelNode.setAttribute("aria-selected", selected);
-		domClass.toggle(this.rowNode, "dijitTreeRowSelected", selected);
-	},
-
-	setFocusable: function(/*Boolean*/ selected){
-		// summary:
-		//		A Tree has a (single) node that's focusable.
-		//		Mark that this node is/isn't that currently focsuable node.
-		// description:
-		//		In particular, setting a node as selected involves setting tabIndex
-		//		so that when user tabs to the tree, focus will go to that node (only).
-
-		this.labelNode.setAttribute("tabIndex", selected ? "0" : "-1");
-	},
+			});
+		},
 
-	_onClick: function(evt){
-		// summary:
-		//		Handler for onclick event on a node
-		// tags:
-		//		private
-		this.tree._onClick(this, evt);
-	},
-	_onDblClick: function(evt){
-		// summary:
-		//		Handler for ondblclick event on a node
-		// tags:
-		//		private
-		this.tree._onDblClick(this, evt);
-	},
+		makeExpandable: function(){
+			// summary:
+			//		if this node wasn't already showing the expando node,
+			//		turn it into one and call _setExpando()
 
-	_onMouseEnter: function(evt){
-		// summary:
-		//		Handler for onmouseenter event on a node
-		// tags:
-		//		private
-		this.tree._onNodeMouseEnter(this, evt);
-	},
+			// TODO: hmm this isn't called from anywhere, maybe should remove it for 2.0
 
-	_onMouseLeave: function(evt){
-		// summary:
-		//		Handler for onmouseenter event on a node
-		// tags:
-		//		private
-		this.tree._onNodeMouseLeave(this, evt);
-	},
-
-	_setTextDirAttr: function(textDir){
-		if(textDir &&((this.textDir != textDir) || !this._created)){
-			this._set("textDir", textDir);
-			this.applyTextDir(this.labelNode, this.labelNode.innerText || this.labelNode.textContent || "");
-			array.forEach(this.getChildren(), function(childNode){
-				childNode.set("textDir", textDir);
-			}, this);
+			this.isExpandable = true;
+			this._setExpando(false);
+		},
+
+		setSelected: function(/*Boolean*/ selected){
+			// summary:
+			//		A Tree has a (single) currently selected node.
+			//		Mark that this node is/isn't that currently selected node.
+			// description:
+			//		In particular, setting a node as selected involves setting tabIndex
+			//		so that when user tabs to the tree, focus will go to that node (only).
+			this.labelNode.setAttribute("aria-selected", selected ? "true" : "false");
+			domClass.toggle(this.rowNode, "dijitTreeRowSelected", selected);
+		},
+
+		focus: function(){
+			focus.focus(this.focusNode);
 		}
+	});
+
+	if(has("dojo-bidi")){
+		TreeNode.extend({
+			_setTextDirAttr: function(textDir){
+				if(textDir && ((this.textDir != textDir) || !this._created)){
+					this._set("textDir", textDir);
+					this.applyTextDir(this.labelNode);
+					array.forEach(this.getChildren(), function(childNode){
+						childNode.set("textDir", textDir);
+					}, this);
+				}
+			}
+		});
 	}
-});
-
-var Tree = declare("dijit.Tree", [_Widget, _TemplatedMixin], {
-	// summary:
-	//		This widget displays hierarchical data from a store.
-
-	// store: [deprecated] String||dojo.data.Store
-	//		Deprecated.  Use "model" parameter instead.
-	//		The store to get data to display in the tree.
-	store: null,
-
-	// model: dijit.Tree.model
-	//		Interface to read tree data, get notifications of changes to tree data,
-	//		and for handling drop operations (i.e drag and drop onto the tree)
-	model: null,
-
-	// query: [deprecated] anything
-	//		Deprecated.  User should specify query to the model directly instead.
-	//		Specifies datastore query to return the root item or top items for the tree.
-	query: null,
-
-	// label: [deprecated] String
-	//		Deprecated.  Use dijit.tree.ForestStoreModel directly instead.
-	//		Used in conjunction with query parameter.
-	//		If a query is specified (rather than a root node id), and a label is also specified,
-	//		then a fake root node is created and displayed, with this label.
-	label: "",
-
-	// showRoot: [const] Boolean
-	//		Should the root node be displayed, or hidden?
-	showRoot: true,
-
-	// childrenAttr: [deprecated] String[]
-	//		Deprecated.   This information should be specified in the model.
-	//		One ore more attributes that holds children of a tree node
-	childrenAttr: ["children"],
-
-	// paths: String[][] or Item[][]
-	//		Full paths from rootNode to selected nodes expressed as array of items or array of ids.
-	//		Since setting the paths may be asynchronous (because ofwaiting on dojo.data), set("paths", ...)
-	//		returns a Deferred to indicate when the set is complete.
-	paths: [],
-
-	// path: String[] or Item[]
-	//      Backward compatible singular variant of paths.
-	path: [],
-
-	// selectedItems: [readonly] Item[]
-	//		The currently selected items in this tree.
-	//		This property can only be set (via set('selectedItems', ...)) when that item is already
-	//		visible in the tree.   (I.e. the tree has already been expanded to show that node.)
-	//		Should generally use `paths` attribute to set the selected items instead.
-	selectedItems: null,
-
-	// selectedItem: [readonly] Item
-	//      Backward compatible singular variant of selectedItems.
-	selectedItem: null,
-
-	// openOnClick: Boolean
-	//		If true, clicking a folder node's label will open it, rather than calling onClick()
-	openOnClick: false,
-
-	// openOnDblClick: Boolean
-	//		If true, double-clicking a folder node's label will open it, rather than calling onDblClick()
-	openOnDblClick: false,
-
-	templateString: treeTemplate,
-
-	// persist: Boolean
-	//		Enables/disables use of cookies for state saving.
-	persist: true,
-
-	// autoExpand: Boolean
-	//		Fully expand the tree on load.   Overrides `persist`.
-	autoExpand: false,
-
-	// dndController: [protected] Function|String
-	//		Class to use as as the dnd controller.  Specifying this class enables DnD.
-	//		Generally you should specify this as dijit.tree.dndSource.
-	//      Setting of dijit.tree._dndSelector handles selection only (no actual DnD).
-	dndController: _dndSelector,
-
-	// parameters to pull off of the tree and pass on to the dndController as its params
-	dndParams: ["onDndDrop","itemCreator","onDndCancel","checkAcceptance", "checkItemAcceptance", "dragThreshold", "betweenThreshold"],
-
-	//declare the above items so they can be pulled from the tree's markup
-
-	// onDndDrop: [protected] Function
-	//		Parameter to dndController, see `dijit.tree.dndSource.onDndDrop`.
-	//		Generally this doesn't need to be set.
-	onDndDrop: null,
-
-	/*=====
-	itemCreator: function(nodes, target, source){
-		// summary:
-		//		Returns objects passed to `Tree.model.newItem()` based on DnD nodes
-		//		dropped onto the tree.   Developer must override this method to enable
-		// 		dropping from external sources onto this Tree, unless the Tree.model's items
-		//		happen to look like {id: 123, name: "Apple" } with no other attributes.
-		// description:
-		//		For each node in nodes[], which came from source, create a hash of name/value
-		//		pairs to be passed to Tree.model.newItem().  Returns array of those hashes.
-		// nodes: DomNode[]
-		//		The DOMNodes dragged from the source container
-		// target: DomNode
-		//		The target TreeNode.rowNode
-		// source: dojo.dnd.Source
-		//		The source container the nodes were dragged from, perhaps another Tree or a plain dojo.dnd.Source
-		// returns: Object[]
-		//		Array of name/value hashes for each new item to be added to the Tree, like:
-		// |	[
-		// |		{ id: 123, label: "apple", foo: "bar" },
-		// |		{ id: 456, label: "pear", zaz: "bam" }
-		// |	]
-		// tags:
-		//		extension
-		return [{}];
-	},
-	=====*/
-	itemCreator: null,
-
-	// onDndCancel: [protected] Function
-	//		Parameter to dndController, see `dijit.tree.dndSource.onDndCancel`.
-	//		Generally this doesn't need to be set.
-	onDndCancel: null,
-
-/*=====
-	checkAcceptance: function(source, nodes){
-		// summary:
-		//		Checks if the Tree itself can accept nodes from this source
-		// source: dijit.tree._dndSource
-		//		The source which provides items
-		// nodes: DOMNode[]
-		//		Array of DOM nodes corresponding to nodes being dropped, dijitTreeRow nodes if
-		//		source is a dijit.Tree.
-		// tags:
-		//		extension
-		return true;	// Boolean
-	},
-=====*/
-	checkAcceptance: null,
-
-/*=====
-	checkItemAcceptance: function(target, source, position){
-		// summary:
-		//		Stub function to be overridden if one wants to check for the ability to drop at the node/item level
-		// description:
-		//		In the base case, this is called to check if target can become a child of source.
-		//		When betweenThreshold is set, position="before" or "after" means that we
-		//		are asking if the source node can be dropped before/after the target node.
-		// target: DOMNode
-		//		The dijitTreeRoot DOM node inside of the TreeNode that we are dropping on to
-		//		Use dijit.getEnclosingWidget(target) to get the TreeNode.
-		// source: dijit.tree.dndSource
-		//		The (set of) nodes we are dropping
-		// position: String
-		//		"over", "before", or "after"
-		// tags:
-		//		extension
-		return true;	// Boolean
-	},
-=====*/
-	checkItemAcceptance: null,
-
-	// dragThreshold: Integer
-	//		Number of pixels mouse moves before it's considered the start of a drag operation
-	dragThreshold: 5,
-
-	// betweenThreshold: Integer
-	//		Set to a positive value to allow drag and drop "between" nodes.
-	//
-	//		If during DnD mouse is over a (target) node but less than betweenThreshold
-	//		pixels from the bottom edge, dropping the the dragged node will make it
-	//		the next sibling of the target node, rather than the child.
-	//
-	//		Similarly, if mouse is over a target node but less that betweenThreshold
-	//		pixels from the top edge, dropping the dragged node will make it
-	//		the target node's previous sibling rather than the target node's child.
-	betweenThreshold: 0,
-
-	// _nodePixelIndent: Integer
-	//		Number of pixels to indent tree nodes (relative to parent node).
-	//		Default is 19 but can be overridden by setting CSS class dijitTreeIndent
-	//		and calling resize() or startup() on tree after it's in the DOM.
-	_nodePixelIndent: 19,
-
-	_publish: function(/*String*/ topicName, /*Object*/ message){
-		// summary:
-		//		Publish a message for this widget/topic
-		topic.publish(this.id, lang.mixin({tree: this, event: topicName}, message || {}));	// publish
-	},
-
-	postMixInProperties: function(){
-		this.tree = this;
-
-		if(this.autoExpand){
-			// There's little point in saving opened/closed state of nodes for a Tree
-			// that initially opens all it's nodes.
-			this.persist = false;
-		}
-
-		this._itemNodesMap={};
-
-		if(!this.cookieName && this.id){
-			this.cookieName = this.id + "SaveStateCookie";
-		}
-
-		this._loadDeferred = new Deferred();
 
-		this.inherited(arguments);
-	},
+	var Tree = declare("dijit.Tree", [_Widget, _KeyNavMixin, _TemplatedMixin, _CssStateMixin], {
+		// summary:
+		//		This widget displays hierarchical data from a store.
+
+		baseClass: "dijitTree",
+
+		// store: [deprecated] String|dojo/data/Store
+		//		Deprecated.  Use "model" parameter instead.
+		//		The store to get data to display in the tree.
+		store: null,
+
+		// model: [const] dijit/tree/model
+		//		Interface to read tree data, get notifications of changes to tree data,
+		//		and for handling drop operations (i.e drag and drop onto the tree)
+		model: null,
+
+		// query: [deprecated] anything
+		//		Deprecated.  User should specify query to the model directly instead.
+		//		Specifies datastore query to return the root item or top items for the tree.
+		query: null,
+
+		// label: [deprecated] String
+		//		Deprecated.  Use dijit/tree/ForestStoreModel directly instead.
+		//		Used in conjunction with query parameter.
+		//		If a query is specified (rather than a root node id), and a label is also specified,
+		//		then a fake root node is created and displayed, with this label.
+		label: "",
+
+		// showRoot: [const] Boolean
+		//		Should the root node be displayed, or hidden?
+		showRoot: true,
+
+		// childrenAttr: [deprecated] String[]
+		//		Deprecated.   This information should be specified in the model.
+		//		One ore more attributes that holds children of a tree node
+		childrenAttr: ["children"],
+
+		// paths: String[][] or Item[][]
+		//		Full paths from rootNode to selected nodes expressed as array of items or array of ids.
+		//		Since setting the paths may be asynchronous (because of waiting on dojo.data), set("paths", ...)
+		//		returns a Promise to indicate when the set is complete.
+		paths: [],
+
+		// path: String[] or Item[]
+		//		Backward compatible singular variant of paths.
+		path: [],
+
+		// selectedItems: [readonly] Item[]
+		//		The currently selected items in this tree.
+		//		This property can only be set (via set('selectedItems', ...)) when that item is already
+		//		visible in the tree.   (I.e. the tree has already been expanded to show that node.)
+		//		Should generally use `paths` attribute to set the selected items instead.
+		selectedItems: null,
+
+		// selectedItem: [readonly] Item
+		//		Backward compatible singular variant of selectedItems.
+		selectedItem: null,
+
+		// openOnClick: Boolean
+		//		If true, clicking a folder node's label will open it, rather than calling onClick()
+		openOnClick: false,
+
+		// openOnDblClick: Boolean
+		//		If true, double-clicking a folder node's label will open it, rather than calling onDblClick()
+		openOnDblClick: false,
+
+		templateString: treeTemplate,
+
+		// persist: Boolean
+		//		Enables/disables use of cookies for state saving.
+		persist: false,
+
+		// autoExpand: Boolean
+		//		Fully expand the tree on load.   Overrides `persist`.
+		autoExpand: false,
+
+		// dndController: [protected] Function|String
+		//		Class to use as as the dnd controller.  Specifying this class enables DnD.
+		//		Generally you should specify this as dijit/tree/dndSource.
+		//		Setting of dijit/tree/_dndSelector handles selection only (no actual DnD).
+		dndController: _dndSelector,
+
+		// parameters to pull off of the tree and pass on to the dndController as its params
+		dndParams: ["onDndDrop", "itemCreator", "onDndCancel", "checkAcceptance", "checkItemAcceptance", "dragThreshold", "betweenThreshold"],
+
+		//declare the above items so they can be pulled from the tree's markup
+
+		// onDndDrop: [protected] Function
+		//		Parameter to dndController, see `dijit/tree/dndSource.onDndDrop()`.
+		//		Generally this doesn't need to be set.
+		onDndDrop: null,
+
+		itemCreator: null,
+		/*=====
+		itemCreator: function(nodes, target, source){
+			// summary:
+			//		Returns objects passed to `Tree.model.newItem()` based on DnD nodes
+			//		dropped onto the tree.   Developer must override this method to enable
+			//		dropping from external sources onto this Tree, unless the Tree.model's items
+			//		happen to look like {id: 123, name: "Apple" } with no other attributes.
+			//
+			//		For each node in nodes[], which came from source, create a hash of name/value
+			//		pairs to be passed to Tree.model.newItem().  Returns array of those hashes.
+			// nodes: DomNode[]
+			//		The DOMNodes dragged from the source container
+			// target: DomNode
+			//		The target TreeNode.rowNode
+			// source: dojo/dnd/Source
+			//		The source container the nodes were dragged from, perhaps another Tree or a plain dojo/dnd/Source
+			// returns: Object[]
+			//		Array of name/value hashes for each new item to be added to the Tree, like:
+			// |	[
+			// |		{ id: 123, label: "apple", foo: "bar" },
+			// |		{ id: 456, label: "pear", zaz: "bam" }
+			// |	]
+			// tags:
+			//		extension
+			return [{}];
+		},
+		=====*/
+
+		// onDndCancel: [protected] Function
+		//		Parameter to dndController, see `dijit/tree/dndSource.onDndCancel()`.
+		//		Generally this doesn't need to be set.
+		onDndCancel: null,
+
+		/*=====
+		checkAcceptance: function(source, nodes){
+			// summary:
+			//		Checks if the Tree itself can accept nodes from this source
+			// source: dijit/tree/dndSource
+			//		The source which provides items
+			// nodes: DOMNode[]
+			//		Array of DOM nodes corresponding to nodes being dropped, dijitTreeRow nodes if
+			//		source is a dijit/Tree.
+			// tags:
+			//		extension
+			return true;	// Boolean
+		},
+		=====*/
+		checkAcceptance: null,
+
+		/*=====
+		checkItemAcceptance: function(target, source, position){
+			// summary:
+			//		Stub function to be overridden if one wants to check for the ability to drop at the node/item level
+			// description:
+			//		In the base case, this is called to check if target can become a child of source.
+			//		When betweenThreshold is set, position="before" or "after" means that we
+			//		are asking if the source node can be dropped before/after the target node.
+			// target: DOMNode
+			//		The dijitTreeRoot DOM node inside of the TreeNode that we are dropping on to
+			//		Use registry.getEnclosingWidget(target) to get the TreeNode.
+			// source: dijit/tree/dndSource
+			//		The (set of) nodes we are dropping
+			// position: String
+			//		"over", "before", or "after"
+			// tags:
+			//		extension
+			return true;	// Boolean
+		},
+		=====*/
+		checkItemAcceptance: null,
+
+		// dragThreshold: Integer
+		//		Number of pixels mouse moves before it's considered the start of a drag operation
+		dragThreshold: 5,
+
+		// betweenThreshold: Integer
+		//		Set to a positive value to allow drag and drop "between" nodes.
+		//
+		//		If during DnD mouse is over a (target) node but less than betweenThreshold
+		//		pixels from the bottom edge, dropping the the dragged node will make it
+		//		the next sibling of the target node, rather than the child.
+		//
+		//		Similarly, if mouse is over a target node but less that betweenThreshold
+		//		pixels from the top edge, dropping the dragged node will make it
+		//		the target node's previous sibling rather than the target node's child.
+		betweenThreshold: 0,
+
+		// _nodePixelIndent: Integer
+		//		Number of pixels to indent tree nodes (relative to parent node).
+		//		Default is 19 but can be overridden by setting CSS class dijitTreeIndent
+		//		and calling resize() or startup() on tree after it's in the DOM.
+		_nodePixelIndent: 19,
+
+		_publish: function(/*String*/ topicName, /*Object*/ message){
+			// summary:
+			//		Publish a message for this widget/topic
+			topic.publish(this.id, lang.mixin({tree: this, event: topicName}, message || {}));	// publish
+		},
+
+		postMixInProperties: function(){
+			this.tree = this;
+
+			if(this.autoExpand){
+				// There's little point in saving opened/closed state of nodes for a Tree
+				// that initially opens all it's nodes.
+				this.persist = false;
+			}
 
-	postCreate: function(){
-		this._initState();
+			this._itemNodesMap = {};
 
-		// Create glue between store and Tree, if not specified directly by user
-		if(!this.model){
-			this._store2model();
-		}
+			if(!this.cookieName && this.id){
+				this.cookieName = this.id + "SaveStateCookie";
+			}
 
-		// monitor changes to items
-		this.connect(this.model, "onChange", "_onItemChange");
-		this.connect(this.model, "onChildrenChange", "_onItemChildrenChange");
-		this.connect(this.model, "onDelete", "_onItemDelete");
+			// Deferred that resolves when all the children have loaded.
+			this.expandChildrenDeferred = new Deferred();
+
+			// Promise that resolves when all pending operations complete.
+			this.pendingCommandsPromise = this.expandChildrenDeferred.promise;
+
+			this.inherited(arguments);
+		},
+
+		postCreate: function(){
+			this._initState();
+
+			// Catch events on TreeNodes
+			var self = this;
+			this.own(
+				on(this.containerNode, on.selector(".dijitTreeNode", touch.enter), function(evt){
+					self._onNodeMouseEnter(registry.byNode(this), evt);
+				}),
+				on(this.containerNode, on.selector(".dijitTreeNode", touch.leave), function(evt){
+					self._onNodeMouseLeave(registry.byNode(this), evt);
+				}),
+				on(this.containerNode, a11yclick, function(evt){
+					var node = registry.getEnclosingWidget(evt.target);
+					if(node.isInstanceOf(TreeNode)){
+						self._onClick(node, evt);
+					}
+				}),
+				on(this.containerNode, on.selector(".dijitTreeNode", "dblclick"), function(evt){
+					self._onDblClick(registry.byNode(this), evt);
+				})
+			);
+
+			// Create glue between store and Tree, if not specified directly by user
+			if(!this.model){
+				this._store2model();
+			}
 
-		this._load();
+			// monitor changes to items
+			this.own(
+				aspect.after(this.model, "onChange", lang.hitch(this, "_onItemChange"), true),
+				aspect.after(this.model, "onChildrenChange", lang.hitch(this, "_onItemChildrenChange"), true),
+				aspect.after(this.model, "onDelete", lang.hitch(this, "_onItemDelete"), true)
+			);
 
-		this.inherited(arguments);
+			this.inherited(arguments);
 
-		if(this.dndController){
-			if(lang.isString(this.dndController)){
-				this.dndController = lang.getObject(this.dndController);
-			}
-			var params={};
-			for(var i=0; i<this.dndParams.length;i++){
-				if(this[this.dndParams[i]]){
-					params[this.dndParams[i]] = this[this.dndParams[i]];
+			if(this.dndController){
+				// TODO: remove string support in 2.0.
+				if(lang.isString(this.dndController)){
+					this.dndController = lang.getObject(this.dndController);
+				}
+				var params = {};
+				for(var i = 0; i < this.dndParams.length; i++){
+					if(this[this.dndParams[i]]){
+						params[this.dndParams[i]] = this[this.dndParams[i]];
+					}
 				}
+				this.dndController = new this.dndController(this, params);
 			}
-			this.dndController = new this.dndController(this, params);
-		}
-	},
 
-	_store2model: function(){
-		// summary:
-		//		User specified a store&query rather than model, so create model from store/query
-		this._v10Compat = true;
-		kernel.deprecated("Tree: from version 2.0, should specify a model object rather than a store/query");
-
-		var modelParams = {
-			id: this.id + "_ForestStoreModel",
-			store: this.store,
-			query: this.query,
-			childrenAttrs: this.childrenAttr
-		};
-
-		// Only override the model's mayHaveChildren() method if the user has specified an override
-		if(this.params.mayHaveChildren){
-			modelParams.mayHaveChildren = lang.hitch(this, "mayHaveChildren");
-		}
+			this._load();
 
-		if(this.params.getItemChildren){
-			modelParams.getChildren = lang.hitch(this, function(item, onComplete, onError){
-				this.getItemChildren((this._v10Compat && item === this.model.root) ? null : item, onComplete, onError);
-			});
-		}
-		this.model = new ForestStoreModel(modelParams);
-
-		// For backwards compatibility, the visibility of the root node is controlled by
-		// whether or not the user has specified a label
-		this.showRoot = Boolean(this.label);
-	},
+			// onLoadDeferred should fire when all commands that are part of initialization have completed.
+			// It will include all the set("paths", ...) commands that happen during initialization.
+			this.onLoadDeferred = shimmedPromise(this.pendingCommandsPromise);
 
-	onLoad: function(){
-		// summary:
-		//		Called when tree finishes loading and expanding.
-		// description:
-		//		If persist == true the loading may encompass many levels of fetches
-		//		from the data store, each asynchronous.   Waits for all to finish.
-		// tags:
-		//		callback
-	},
+			this.onLoadDeferred.then(lang.hitch(this, "onLoad"));
+		},
 
-	_load: function(){
-		// summary:
-		//		Initial load of the tree.
-		//		Load root node (possibly hidden) and it's children.
-		this.model.getRoot(
-			lang.hitch(this, function(item){
-				var rn = (this.rootNode = this.tree._createTreeNode({
-					item: item,
-					tree: this,
-					isExpandable: true,
-					label: this.label || this.getLabel(item),
-					textDir: this.textDir,
-					indent: this.showRoot ? 0 : -1
-				}));
-				if(!this.showRoot){
-					rn.rowNode.style.display="none";
-					// if root is not visible, move tree role to the invisible
-					// root node's containerNode, see #12135
-					this.domNode.setAttribute("role", "presentation");
-
-					rn.labelNode.setAttribute("role", "presentation");
-					rn.containerNode.setAttribute("role", "tree");
-				}
-				this.domNode.appendChild(rn.domNode);
-				var identity = this.model.getIdentity(item);
-				if(this._itemNodesMap[identity]){
-					this._itemNodesMap[identity].push(rn);
-				}else{
-					this._itemNodesMap[identity] = [rn];
-				}
+		_store2model: function(){
+			// summary:
+			//		User specified a store&query rather than model, so create model from store/query
+			this._v10Compat = true;
+			kernel.deprecated("Tree: from version 2.0, should specify a model object rather than a store/query");
 
-				rn._updateLayout();		// sets "dijitTreeIsRoot" CSS classname
+			var modelParams = {
+				id: this.id + "_ForestStoreModel",
+				store: this.store,
+				query: this.query,
+				childrenAttrs: this.childrenAttr
+			};
 
-				// load top level children and then fire onLoad() event
-				this._expandNode(rn).addCallback(lang.hitch(this, function(){
-					this._loadDeferred.callback(true);
-					this.onLoad();
-				}));
-			}),
-			function(err){
-				console.error(this, ": error loading root: ", err);
+			// Only override the model's mayHaveChildren() method if the user has specified an override
+			if(this.params.mayHaveChildren){
+				modelParams.mayHaveChildren = lang.hitch(this, "mayHaveChildren");
 			}
-		);
-	},
 
-	getNodesByItem: function(/*Item or id*/ item){
-		// summary:
-		//		Returns all tree nodes that refer to an item
-		// returns:
-		//		Array of tree nodes that refer to passed item
-
-		if(!item){ return []; }
-		var identity = lang.isString(item) ? item : this.model.getIdentity(item);
-		// return a copy so widget don't get messed up by changes to returned array
-		return [].concat(this._itemNodesMap[identity]);
-	},
-
-	_setSelectedItemAttr: function(/*Item or id*/ item){
-		this.set('selectedItems', [item]);
-	},
-
-	_setSelectedItemsAttr: function(/*Items or ids*/ items){
-		// summary:
-		//		Select tree nodes related to passed items.
-		//		WARNING: if model use multi-parented items or desired tree node isn't already loaded
-		//		behavior is undefined. Use set('paths', ...) instead.
-		var tree = this;
-		this._loadDeferred.addCallback( lang.hitch(this, function(){
-			var identities = array.map(items, function(item){
-				return (!item || lang.isString(item)) ? item : tree.model.getIdentity(item);
-			});
-			var nodes = [];
-			array.forEach(identities, function(id){
-				nodes = nodes.concat(tree._itemNodesMap[id] || []);
-			});
-			this.set('selectedNodes', nodes);
-		}));
-	},
+			if(this.params.getItemChildren){
+				modelParams.getChildren = lang.hitch(this, function(item, onComplete, onError){
+					this.getItemChildren((this._v10Compat && item === this.model.root) ? null : item, onComplete, onError);
+				});
+			}
+			this.model = new ForestStoreModel(modelParams);
+
+			// For backwards compatibility, the visibility of the root node is controlled by
+			// whether or not the user has specified a label
+			this.showRoot = Boolean(this.label);
+		},
+
+		onLoad: function(){
+			// summary:
+			//		Called when tree finishes loading and expanding.
+			// description:
+			//		If persist == true the loading may encompass many levels of fetches
+			//		from the data store, each asynchronous.   Waits for all to finish.
+			// tags:
+			//		callback
+		},
+
+		_load: function(){
+			// summary:
+			//		Initial load of the tree.
+			//		Load root node (possibly hidden) and it's children.
+			this.model.getRoot(
+				lang.hitch(this, function(item){
+					var rn = (this.rootNode = this.tree._createTreeNode({
+						item: item,
+						tree: this,
+						isExpandable: true,
+						label: this.label || this.getLabel(item),
+						labelType: this.model.labelType || "text",
+						textDir: this.textDir,
+						indent: this.showRoot ? 0 : -1
+					}));
+
+					if(!this.showRoot){
+						rn.rowNode.style.display = "none";
+						// if root is not visible, move tree role to the invisible
+						// root node's containerNode, see #12135
+						this.domNode.setAttribute("role", "presentation");
+						this.domNode.removeAttribute("aria-expanded");
+						this.domNode.removeAttribute("aria-multiselectable");
+
+						// move the aria-label or aria-labelledby to the element with the role
+						if(this["aria-label"]){
+							rn.containerNode.setAttribute("aria-label", this["aria-label"]);
+							this.domNode.removeAttribute("aria-label");
+						}else if(this["aria-labelledby"]){
+							rn.containerNode.setAttribute("aria-labelledby", this["aria-labelledby"]);
+							this.domNode.removeAttribute("aria-labelledby");
+						}
+						rn.labelNode.setAttribute("role", "presentation");
+						rn.containerNode.setAttribute("role", "tree");
+						rn.containerNode.setAttribute("aria-expanded", "true");
+						rn.containerNode.setAttribute("aria-multiselectable", !this.dndController.singular);
+					}else{
+						this.domNode.setAttribute("aria-multiselectable", !this.dndController.singular);
+						this.rootLoadingIndicator.style.display = "none";
+					}
 
-	_setPathAttr: function(/*Item[] || String[]*/ path){
-		// summary:
-		//      Singular variant of _setPathsAttr
-		if(path.length){
-			return this.set("paths", [path]);
-		}else{
-			// Empty list is interpreted as "select nothing"
-			return this.set("paths", []);
-		}
-	},
+					this.containerNode.appendChild(rn.domNode);
+					var identity = this.model.getIdentity(item);
+					if(this._itemNodesMap[identity]){
+						this._itemNodesMap[identity].push(rn);
+					}else{
+						this._itemNodesMap[identity] = [rn];
+					}
 
-	_setPathsAttr: function(/*Item[][] || String[][]*/ paths){
-		// summary:
-		//		Select the tree nodes identified by passed paths.
-		// paths:
-		//		Array of arrays of items or item id's
-		// returns:
-		//		Deferred to indicate when the set is complete
-		var tree = this;
-
-		// We may need to wait for some nodes to expand, so setting
-		// each path will involve a Deferred. We bring those deferreds
-		// together witha DeferredList.
-		return new DeferredList(array.map(paths, function(path){
-			var d = new Deferred();
-
-			// normalize path to use identity
-			path = array.map(path, function(item){
-				return lang.isString(item) ? item : tree.model.getIdentity(item);
-			});
+					rn._updateLayout();		// sets "dijitTreeIsRoot" CSS classname
+
+					// Load top level children, and if persist==true, all nodes that were previously opened
+					this._expandNode(rn).then(lang.hitch(this, function(){
+						// Then, select the nodes specified by params.paths[].
+
+						this.rootLoadingIndicator.style.display = "none";
+						this.expandChildrenDeferred.resolve(true);
+					}));
+				}),
+				lang.hitch(this, function(err){
+					console.error(this, ": error loading root: ", err);
+				})
+			);
+		},
+
+		getNodesByItem: function(/*Item or id*/ item){
+			// summary:
+			//		Returns all tree nodes that refer to an item
+			// returns:
+			//		Array of tree nodes that refer to passed item
+
+			if(!item){
+				return [];
+			}
+			var identity = lang.isString(item) ? item : this.model.getIdentity(item);
+			// return a copy so widget don't get messed up by changes to returned array
+			return [].concat(this._itemNodesMap[identity]);
+		},
+
+		_setSelectedItemAttr: function(/*Item or id*/ item){
+			this.set('selectedItems', [item]);
+		},
+
+		_setSelectedItemsAttr: function(/*Items or ids*/ items){
+			// summary:
+			//		Select tree nodes related to passed items.
+			//		WARNING: if model use multi-parented items or desired tree node isn't already loaded
+			//		behavior is undefined. Use set('paths', ...) instead.
+			var tree = this;
+			return this.pendingCommandsPromise = this.pendingCommandsPromise.always(lang.hitch(this, function(){
+				var identities = array.map(items, function(item){
+					return (!item || lang.isString(item)) ? item : tree.model.getIdentity(item);
+				});
+				var nodes = [];
+				array.forEach(identities, function(id){
+					nodes = nodes.concat(tree._itemNodesMap[id] || []);
+				});
+				this.set('selectedNodes', nodes);
+			}));
+		},
 
+		_setPathAttr: function(/*Item[]|String[]*/ path){
+			// summary:
+			//		Singular variant of _setPathsAttr
 			if(path.length){
-				// Wait for the tree to load, if it hasn't already.
-				tree._loadDeferred.addCallback(function(){ selectPath(path, [tree.rootNode], d); });
+				return shimmedPromise(this.set("paths", [path]).then(function(paths){ return paths[0]; }));
 			}else{
-				d.errback("Empty path");
+				// Empty list is interpreted as "select nothing"
+				return shimmedPromise(this.set("paths", []).then(function(paths){ return paths[0]; }));
 			}
-			return d;
-		})).addCallback(setNodes);
-
-		function selectPath(path, nodes, def){
-			// Traverse path; the next path component should be among "nodes".
-			var nextPath = path.shift();
-			var nextNode = array.filter(nodes, function(node){
-				return node.getIdentity() == nextPath;
-			})[0];
-			if(!!nextNode){
-				if(path.length){
-					tree._expandNode(nextNode).addCallback(function(){ selectPath(path, nextNode.getChildren(), def); });
+		},
+
+		_setPathsAttr: function(/*Item[][]|String[][]*/ paths){
+			// summary:
+			//		Select the tree nodes identified by passed paths.
+			// paths:
+			//		Array of arrays of items or item id's
+			// returns:
+			//		Promise to indicate when the set is complete
+
+			var tree = this;
+
+			function selectPath(path, nodes){
+				// Traverse path, returning Promise for node at the end of the path.
+				// The next path component should be among "nodes".
+				var nextPath = path.shift();
+				var nextNode = array.filter(nodes, function(node){
+					return node.getIdentity() == nextPath;
+				})[0];
+				if(!!nextNode){
+					if(path.length){
+						return tree._expandNode(nextNode).then(function(){
+							return selectPath(path, nextNode.getChildren());
+						});
+					}else{
+						// Successfully reached the end of this path
+						return nextNode;
+					}
 				}else{
-					//Successfully reached the end of this path
-					def.callback(nextNode);
+					throw new Tree.PathError("Could not expand path at " + nextPath);
 				}
-			}else{
-				def.errback("Could not expand path at " + nextPath);
 			}
-		}
-
-		function setNodes(newNodes){
-			//After all expansion is finished, set the selection to
-			//the set of nodes successfully found.
-			tree.set("selectedNodes", array.map(
-				array.filter(newNodes,function(x){return x[0];}),
-				function(x){return x[1];}));
-		}
-	},
 
-	_setSelectedNodeAttr: function(node){
-		this.set('selectedNodes', [node]);
-	},
-	_setSelectedNodesAttr: function(nodes){
-		this._loadDeferred.addCallback( lang.hitch(this, function(){
+			// Let any previous set("path", ...) commands complete before this one starts.
+			// TODO for 2.0: make the user do this wait themselves?
+			return shimmedPromise(this.pendingCommandsPromise = this.pendingCommandsPromise.always(function(){
+				// We may need to wait for some nodes to expand, so setting
+				// each path will involve a Deferred. We bring those deferreds
+				// together with a dojo/promise/all.
+				return all(array.map(paths, function(path){
+					// normalize path to use identity
+					path = array.map(path, function(item){
+						return lang.isString(item) ? item : tree.model.getIdentity(item);
+					});
+
+					if(path.length){
+						return selectPath(path, [tree.rootNode]);
+					}else{
+						throw new Tree.PathError("Empty path");
+					}
+				}));
+			}).then(function setNodes(newNodes){
+				// After all expansion is finished, set the selection to last element from each path
+				tree.set("selectedNodes", newNodes);
+				return tree.paths;
+			}));
+		},
+
+		_setSelectedNodeAttr: function(node){
+			this.set('selectedNodes', [node]);
+		},
+		_setSelectedNodesAttr: function(nodes){
+			// summary:
+			//		Marks the specified TreeNodes as selected.
+			// nodes: TreeNode[]
+			//		TreeNodes to mark.
 			this.dndController.setSelection(nodes);
-		}));
-	},
+		},
 
 
-	////////////// Data store related functions //////////////////////
-	// These just get passed to the model; they are here for back-compat
+		expandAll: function(){
+			// summary:
+			//		Expand all nodes in the tree
+			// returns:
+			//		Promise that resolves when all nodes have expanded
 
-	mayHaveChildren: function(/*dojo.data.Item*/ /*===== item =====*/){
-		// summary:
-		//		Deprecated.   This should be specified on the model itself.
-		//
-		//		Overridable function to tell if an item has or may have children.
-		//		Controls whether or not +/- expando icon is shown.
-		//		(For efficiency reasons we may not want to check if an element actually
-		//		has children until user clicks the expando node)
-		// tags:
-		//		deprecated
-	},
+			var _this = this;
 
-	getItemChildren: function(/*===== parentItem, onComplete =====*/){
-		// summary:
-		//		Deprecated.   This should be specified on the model itself.
-		//
-		// 		Overridable function that return array of child items of given parent item,
-		//		or if parentItem==null then return top items in tree
-		// tags:
-		//		deprecated
-	},
+			function expand(node){
+				// Expand the node
+				return _this._expandNode(node).then(function(){
+					// When node has expanded, call expand() recursively on each non-leaf child
+					var childBranches = array.filter(node.getChildren() || [], function(node){
+						return node.isExpandable;
+					});
 
-	///////////////////////////////////////////////////////
-	// Functions for converting an item to a TreeNode
-	getLabel: function(/*dojo.data.Item*/ item){
-		// summary:
-		//		Overridable function to get the label for a tree node (given the item)
-		// tags:
-		//		extension
-		return this.model.getLabel(item);	// String
-	},
-
-	getIconClass: function(/*dojo.data.Item*/ item, /*Boolean*/ opened){
-		// summary:
-		//		Overridable function to return CSS class name to display icon
-		// tags:
-		//		extension
-		return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf"
-	},
-
-	getLabelClass: function(/*===== item, opened =====*/){
-		// summary:
-		//		Overridable function to return CSS class name to display label
-		// item: dojo.data.Item
-		// opened: Boolean
-		// returns: String
-		//		CSS class name
-		// tags:
-		//		extension
-	},
-
-	getRowClass: function(/*===== item, opened =====*/){
-		// summary:
-		//		Overridable function to return CSS class name to display row
-		// item: dojo.data.Item
-		// opened: Boolean
-		// returns: String
-		//		CSS class name
-		// tags:
-		//		extension
-	},
+					// And when all those recursive calls finish, signal that I'm finished
+					return all(array.map(childBranches, expand));
+				});
+			}
 
-	getIconStyle: function(/*===== item, opened =====*/){
-		// summary:
-		//		Overridable function to return CSS styles to display icon
-		// item: dojo.data.Item
-		// opened: Boolean
-		// returns: Object
-		//		Object suitable for input to dojo.style() like {backgroundImage: "url(...)"}
-		// tags:
-		//		extension
-	},
+			return shimmedPromise(expand(this.rootNode));
+		},
 
-	getLabelStyle: function(/*===== item, opened =====*/){
-		// summary:
-		//		Overridable function to return CSS styles to display label
-		// item: dojo.data.Item
-		// opened: Boolean
-		// returns:
-		//		Object suitable for input to dojo.style() like {color: "red", background: "green"}
-		// tags:
-		//		extension
-	},
+		collapseAll: function(){
+			// summary:
+			//		Collapse all nodes in the tree
+			// returns:
+			//		Promise that resolves when all nodes have collapsed
 
-	getRowStyle: function(/*===== item, opened =====*/){
-		// summary:
-		//		Overridable function to return CSS styles to display row
-		// item: dojo.data.Item
-		// opened: Boolean
-		// returns:
-		//		Object suitable for input to dojo.style() like {background-color: "#bbb"}
-		// tags:
-		//		extension
-	},
+			var _this = this;
 
-	getTooltip: function(/*dojo.data.Item*/ /*===== item =====*/){
-		// summary:
-		//		Overridable function to get the tooltip for a tree node (given the item)
-		// tags:
-		//		extension
-		return "";	// String
-	},
+			function collapse(node){
+				// Collapse children first
+				var childBranches = array.filter(node.getChildren() || [], function(node){
+						return node.isExpandable;
+					}),
+					defs = all(array.map(childBranches, collapse));
 
-	/////////// Keyboard and Mouse handlers ////////////////////
+				// And when all those recursive calls finish, collapse myself, unless I'm the invisible root node,
+				// in which case collapseAll() is finished
+				if(!node.isExpanded || (node == _this.rootNode && !_this.showRoot)){
+					return defs;
+				}else{
+					// When node has collapsed, signal that call is finished
+					return defs.then(function(){
+						return _this._collapseNode(node);
+					});
+				}
+			}
 
-	_onKeyPress: function(/*Event*/ e){
-		// summary:
-		//		Translates keypress events into commands for the controller
-		if(e.altKey){ return; }
-		var treeNode = registry.getEnclosingWidget(e.target);
-		if(!treeNode){ return; }
-
-		var key = e.charOrCode;
-		if(typeof key == "string" && key != " "){	// handle printables (letter navigation)
-			// Check for key navigation.
-			if(!e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey){
-				this._onLetterKeyNav( { node: treeNode, key: key.toLowerCase() } );
-				event.stop(e);
+			return shimmedPromise(collapse(this.rootNode));
+		},
+
+		////////////// Data store related functions //////////////////////
+		// These just get passed to the model; they are here for back-compat
+
+		mayHaveChildren: function(/*dojo/data/Item*/ /*===== item =====*/){
+			// summary:
+			//		Deprecated.   This should be specified on the model itself.
+			//
+			//		Overridable function to tell if an item has or may have children.
+			//		Controls whether or not +/- expando icon is shown.
+			//		(For efficiency reasons we may not want to check if an element actually
+			//		has children until user clicks the expando node)
+			// tags:
+			//		deprecated
+		},
+
+		getItemChildren: function(/*===== parentItem, onComplete =====*/){
+			// summary:
+			//		Deprecated.   This should be specified on the model itself.
+			//
+			//		Overridable function that return array of child items of given parent item,
+			//		or if parentItem==null then return top items in tree
+			// tags:
+			//		deprecated
+		},
+
+		///////////////////////////////////////////////////////
+		// Functions for converting an item to a TreeNode
+		getLabel: function(/*dojo/data/Item*/ item){
+			// summary:
+			//		Overridable function to get the label for a tree node (given the item)
+			// tags:
+			//		extension
+			return this.model.getLabel(item);	// String
+		},
+
+		getIconClass: function(/*dojo/data/Item*/ item, /*Boolean*/ opened){
+			// summary:
+			//		Overridable function to return CSS class name to display icon
+			// tags:
+			//		extension
+			return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf"
+		},
+
+		getLabelClass: function(/*===== item, opened =====*/){
+			// summary:
+			//		Overridable function to return CSS class name to display label
+			// item: dojo/data/Item
+			// opened: Boolean
+			// returns: String
+			//		CSS class name
+			// tags:
+			//		extension
+		},
+
+		getRowClass: function(/*===== item, opened =====*/){
+			// summary:
+			//		Overridable function to return CSS class name to display row
+			// item: dojo/data/Item
+			// opened: Boolean
+			// returns: String
+			//		CSS class name
+			// tags:
+			//		extension
+		},
+
+		getIconStyle: function(/*===== item, opened =====*/){
+			// summary:
+			//		Overridable function to return CSS styles to display icon
+			// item: dojo/data/Item
+			// opened: Boolean
+			// returns: Object
+			//		Object suitable for input to dojo.style() like {backgroundImage: "url(...)"}
+			// tags:
+			//		extension
+		},
+
+		getLabelStyle: function(/*===== item, opened =====*/){
+			// summary:
+			//		Overridable function to return CSS styles to display label
+			// item: dojo/data/Item
+			// opened: Boolean
+			// returns:
+			//		Object suitable for input to dojo.style() like {color: "red", background: "green"}
+			// tags:
+			//		extension
+		},
+
+		getRowStyle: function(/*===== item, opened =====*/){
+			// summary:
+			//		Overridable function to return CSS styles to display row
+			// item: dojo/data/Item
+			// opened: Boolean
+			// returns:
+			//		Object suitable for input to dojo.style() like {background-color: "#bbb"}
+			// tags:
+			//		extension
+		},
+
+		getTooltip: function(/*dojo/data/Item*/ /*===== item =====*/){
+			// summary:
+			//		Overridable function to get the tooltip for a tree node (given the item)
+			// tags:
+			//		extension
+			return "";	// String
+		},
+
+		/////////// Keyboard and Mouse handlers ////////////////////
+
+
+		_onDownArrow: function(/*Event*/ evt, /*TreeNode*/ node){
+			// summary:
+			//		down arrow pressed; get next visible node, set focus there
+
+			var nextNode = this._getNext(node);
+			if(nextNode && nextNode.isTreeNode){
+				this.focusNode(nextNode);
 			}
-		}else{	// handle non-printables (arrow keys)
-			// clear record of recent printables (being saved for multi-char letter navigation),
-			// because "a", down-arrow, "b" shouldn't search for "ab"
-			if(this._curSearch){
-				clearTimeout(this._curSearch.timer);
-				delete this._curSearch;
+		},
+
+		_onUpArrow: function(/*Event*/ evt, /*TreeNode*/ node){
+			// summary:
+			//		Up arrow pressed; move to previous visible node
+
+			// if younger siblings
+			var previousSibling = node.getPreviousSibling();
+			if(previousSibling){
+				node = previousSibling;
+				// if the previous node is expanded, dive in deep
+				while(node.isExpandable && node.isExpanded && node.hasChildren()){
+					// move to the last child
+					var children = node.getChildren();
+					node = children[children.length - 1];
+				}
+			}else{
+				// if this is the first child, return the parent
+				// unless the parent is the root of a tree with a hidden root
+				var parent = node.getParent();
+				if(!(!this.showRoot && parent === this.rootNode)){
+					node = parent;
+				}
 			}
 
-			var map = this._keyHandlerMap;
-			if(!map){
-				// setup table mapping keys to events
-				map = {};
-				map[keys.ENTER]="_onEnterKey";
-				//On WebKit based browsers, the combination ctrl-enter
-				//does not get passed through. To allow accessible
-				//multi-select on those browsers, the space key is
-				//also used for selection.
-				map[keys.SPACE]= map[" "] = "_onEnterKey";
-				map[this.isLeftToRight() ? keys.LEFT_ARROW : keys.RIGHT_ARROW]="_onLeftArrow";
-				map[this.isLeftToRight() ? keys.RIGHT_ARROW : keys.LEFT_ARROW]="_onRightArrow";
-				map[keys.UP_ARROW]="_onUpArrow";
-				map[keys.DOWN_ARROW]="_onDownArrow";
-				map[keys.HOME]="_onHomeKey";
-				map[keys.END]="_onEndKey";
-				this._keyHandlerMap = map;
+			if(node && node.isTreeNode){
+				this.focusNode(node);
 			}
-			if(this._keyHandlerMap[key]){
-				this[this._keyHandlerMap[key]]( { node: treeNode, item: treeNode.item, evt: e } );
-				event.stop(e);
+		},
+
+		_onRightArrow: function(/*Event*/ evt, /*TreeNode*/ node){
+			// summary:
+			//		Right arrow pressed; go to child node
+
+			// if not expanded, expand, else move to 1st child
+			if(node.isExpandable && !node.isExpanded){
+				this._expandNode(node);
+			}else if(node.hasChildren()){
+				node = node.getChildren()[0];
+				if(node && node.isTreeNode){
+					this.focusNode(node);
+				}
 			}
-		}
-	},
+		},
 
-	_onEnterKey: function(/*Object*/ message){
-		this._publish("execute", { item: message.item, node: message.node } );
-		this.dndController.userSelect(message.node, connect.isCopyKey( message.evt ), message.evt.shiftKey);
-		this.onClick(message.item, message.node, message.evt);
-	},
-
-	_onDownArrow: function(/*Object*/ message){
-		// summary:
-		//		down arrow pressed; get next visible node, set focus there
-		var node = this._getNextNode(message.node);
-		if(node && node.isTreeNode){
-			this.focusNode(node);
-		}
-	},
+		_onLeftArrow: function(/*Event*/ evt, /*TreeNode*/ node){
+			// summary:
+			//		Left arrow pressed.
+			//		If not collapsed, collapse, else move to parent.
 
-	_onUpArrow: function(/*Object*/ message){
-		// summary:
-		//		Up arrow pressed; move to previous visible node
-
-		var node = message.node;
-
-		// if younger siblings
-		var previousSibling = node.getPreviousSibling();
-		if(previousSibling){
-			node = previousSibling;
-			// if the previous node is expanded, dive in deep
-			while(node.isExpandable && node.isExpanded && node.hasChildren()){
-				// move to the last child
-				var children = node.getChildren();
-				node = children[children.length-1];
-			}
-		}else{
-			// if this is the first child, return the parent
-			// unless the parent is the root of a tree with a hidden root
-			var parent = node.getParent();
-			if(!(!this.showRoot && parent === this.rootNode)){
-				node = parent;
+			if(node.isExpandable && node.isExpanded){
+				this._collapseNode(node);
+			}else{
+				var parent = node.getParent();
+				if(parent && parent.isTreeNode && !(!this.showRoot && parent === this.rootNode)){
+					this.focusNode(parent);
+				}
 			}
-		}
+		},
 
-		if(node && node.isTreeNode){
-			this.focusNode(node);
-		}
-	},
+		focusLastChild: function(){
+			// summary:
+			//		End key pressed; go to last visible node.
 
-	_onRightArrow: function(/*Object*/ message){
-		// summary:
-		//		Right arrow pressed; go to child node
-		var node = message.node;
-
-		// if not expanded, expand, else move to 1st child
-		if(node.isExpandable && !node.isExpanded){
-			this._expandNode(node);
-		}else if(node.hasChildren()){
-			node = node.getChildren()[0];
+			var node = this._getLast();
 			if(node && node.isTreeNode){
 				this.focusNode(node);
 			}
-		}
-	},
-
-	_onLeftArrow: function(/*Object*/ message){
-		// summary:
-		//		Left arrow pressed.
-		//		If not collapsed, collapse, else move to parent.
-
-		var node = message.node;
-
-		if(node.isExpandable && node.isExpanded){
-			this._collapseNode(node);
-		}else{
-			var parent = node.getParent();
-			if(parent && parent.isTreeNode && !(!this.showRoot && parent === this.rootNode)){
-				this.focusNode(parent);
+		},
+
+		_getFirst: function(){
+			// summary:
+			//		Returns the first child.
+			// tags:
+			//		abstract extension
+			return this.showRoot ? this.rootNode : this.rootNode.getChildren()[0];
+		},
+
+		_getLast: function(){
+			// summary:
+			//		Returns the last descendant.
+			// tags:
+			//		abstract extension
+			var node = this.rootNode;
+			while(node.isExpanded){
+				var c = node.getChildren();
+				if(!c.length){
+					break;
+				}
+				node = c[c.length - 1];
 			}
-		}
-	},
+			return node;
+		},
+
+		// Tree only searches forward so dir parameter is unused
+		_getNext: function(node){
+			// summary:
+			//		Returns the next descendant, compared to "child".
+			// node: Widget
+			//		The current widget
+			// tags:
+			//		abstract extension
+
+			if(node.isExpandable && node.isExpanded && node.hasChildren()){
+				// if this is an expanded node, get the first child
+				return node.getChildren()[0];		// TreeNode
+			}else{
+				// find a parent node with a sibling
+				while(node && node.isTreeNode){
+					var returnNode = node.getNextSibling();
+					if(returnNode){
+						return returnNode;		// TreeNode
+					}
+					node = node.getParent();
+				}
+				return null;
+			}
+		},
 
-	_onHomeKey: function(){
-		// summary:
-		//		Home key pressed; get first visible node, and set focus there
-		var node = this._getRootOrFirstNode();
-		if(node){
-			this.focusNode(node);
-		}
-	},
+		// Implement _KeyNavContainer.childSelector, to identify which nodes are navigable
+		childSelector: ".dijitTreeRow",
 
-	_onEndKey: function(){
-		// summary:
-		//		End key pressed; go to last visible node.
+		isExpandoNode: function(node, widget){
+			// summary:
+			//		check whether a dom node is the expandoNode for a particular TreeNode widget
+			return dom.isDescendant(node, widget.expandoNode) || dom.isDescendant(node, widget.expandoNodeText);
+		},
 
-		var node = this.rootNode;
-		while(node.isExpanded){
-			var c = node.getChildren();
-			node = c[c.length - 1];
-		}
+		__click: function(/*TreeNode*/ nodeWidget, /*Event*/ e, /*Boolean*/doOpen, /*String*/func){
+			var domElement = e.target,
+				isExpandoClick = this.isExpandoNode(domElement, nodeWidget);
 
-		if(node && node.isTreeNode){
+			if(nodeWidget.isExpandable && (doOpen || isExpandoClick)){
+				// expando node was clicked, or label of a folder node was clicked; open it
+				this._onExpandoClick({node: nodeWidget});
+			}else{
+				this._publish("execute", { item: nodeWidget.item, node: nodeWidget, evt: e });
+				this[func](nodeWidget.item, nodeWidget, e);
+				this.focusNode(nodeWidget);
+			}
+			e.stopPropagation();
+			e.preventDefault();
+		},
+		_onClick: function(/*TreeNode*/ nodeWidget, /*Event*/ e){
+			// summary:
+			//		Translates click events into commands for the controller to process
+			this.__click(nodeWidget, e, this.openOnClick, 'onClick');
+		},
+		_onDblClick: function(/*TreeNode*/ nodeWidget, /*Event*/ e){
+			// summary:
+			//		Translates double-click events into commands for the controller to process
+			this.__click(nodeWidget, e, this.openOnDblClick, 'onDblClick');
+		},
+
+		_onExpandoClick: function(/*Object*/ message){
+			// summary:
+			//		User clicked the +/- icon; expand or collapse my children.
+			var node = message.node;
+
+			// If we are collapsing, we might be hiding the currently focused node.
+			// Also, clicking the expando node might have erased focus from the current node.
+			// For simplicity's sake just focus on the node with the expando.
 			this.focusNode(node);
-		}
-	},
-
-	// multiCharSearchDuration: Number
-	//		If multiple characters are typed where each keystroke happens within
-	//		multiCharSearchDuration of the previous keystroke,
-	//		search for nodes matching all the keystrokes.
-	//
-	//		For example, typing "ab" will search for entries starting with
-	//		"ab" unless the delay between "a" and "b" is greater than multiCharSearchDuration.
-	multiCharSearchDuration: 250,
-
-	_onLetterKeyNav: function(message){
-		// summary:
-		//		Called when user presses a prinatable key; search for node starting with recently typed letters.
-		// message: Object
-		//		Like { node: TreeNode, key: 'a' } where key is the key the user pressed.
-
-		// Branch depending on whether this key starts a new search, or modifies an existing search
-		var cs = this._curSearch;
-		if(cs){
-			// We are continuing a search.  Ex: user has pressed 'a', and now has pressed
-			// 'b', so we want to search for nodes starting w/"ab".
-			cs.pattern = cs.pattern + message.key;
-			clearTimeout(cs.timer);
-		}else{
-			// We are starting a new search
-			cs = this._curSearch = {
-					pattern: message.key,
-					startNode: message.node
-			};
-		}
 
-		// set/reset timer to forget recent keystrokes
-		var self = this;
-		cs.timer = setTimeout(function(){
-			delete self._curSearch;
-		}, this.multiCharSearchDuration);
-
-		// Navigate to TreeNode matching keystrokes [entered so far].
-		var node = cs.startNode;
-		do{
-			node = this._getNextNode(node);
-			//check for last node, jump to first node if necessary
-			if(!node){
-				node = this._getRootOrFirstNode();
+			if(node.isExpanded){
+				this._collapseNode(node);
+			}else{
+				this._expandNode(node);
 			}
-		}while(node !== cs.startNode && (node.label.toLowerCase().substr(0, cs.pattern.length) != cs.pattern));
-		if(node && node.isTreeNode){
-			// no need to set focus if back where we started
-			if(node !== cs.startNode){
-				this.focusNode(node);
+		},
+
+		onClick: function(/*===== item, node, evt =====*/){
+			// summary:
+			//		Callback when a tree node is clicked
+			// item: Object
+			//		Object from the dojo/store corresponding to this TreeNode
+			// node: TreeNode
+			//		The TreeNode itself
+			// evt: Event
+			//		The event
+			// tags:
+			//		callback
+		},
+		onDblClick: function(/*===== item, node, evt =====*/){
+			// summary:
+			//		Callback when a tree node is double-clicked
+			// item: Object
+			//		Object from the dojo/store corresponding to this TreeNode
+			// node: TreeNode
+			//		The TreeNode itself
+			// evt: Event
+			//		The event
+			// tags:
+			//		callback
+		},
+		onOpen: function(/*===== item, node =====*/){
+			// summary:
+			//		Callback when a node is opened
+			// item: dojo/data/Item
+			// node: TreeNode
+			// tags:
+			//		callback
+		},
+		onClose: function(/*===== item, node =====*/){
+			// summary:
+			//		Callback when a node is closed
+			// item: Object
+			//		Object from the dojo/store corresponding to this TreeNode
+			// node: TreeNode
+			//		The TreeNode itself
+			// tags:
+			//		callback
+		},
+
+		_getNextNode: function(node){
+			// summary:
+			//		Get next visible node
+
+			kernel.deprecated(this.declaredClass + "::_getNextNode(node) is deprecated. Use _getNext(node) instead.", "", "2.0");
+			return this._getNext(node);
+		},
+
+		_getRootOrFirstNode: function(){
+			// summary:
+			//		Get first visible node
+			kernel.deprecated(this.declaredClass + "::_getRootOrFirstNode() is deprecated. Use _getFirst() instead.", "", "2.0");
+			return this._getFirst();
+		},
+
+		_collapseNode: function(/*TreeNode*/ node){
+			// summary:
+			//		Called when the user has requested to collapse the node
+			// returns:
+			//		Promise that resolves when the node has finished closing
+
+			if(node._expandNodeDeferred){
+				delete node._expandNodeDeferred;
 			}
-		}
-	},
-
-	isExpandoNode: function(node, widget){
-		// summary:
-		//		check whether a dom node is the expandoNode for a particular TreeNode widget
-		return dom.isDescendant(node, widget.expandoNode);
-	},
-	_onClick: function(/*TreeNode*/ nodeWidget, /*Event*/ e){
-		// summary:
-		//		Translates click events into commands for the controller to process
 
-		var domElement = e.target,
-			isExpandoClick = this.isExpandoNode(domElement, nodeWidget);
-
-		if( (this.openOnClick && nodeWidget.isExpandable) || isExpandoClick ){
-			// expando node was clicked, or label of a folder node was clicked; open it
-			if(nodeWidget.isExpandable){
-				this._onExpandoClick({node:nodeWidget});
+			if(node.state == "Loading"){
+				// ignore clicks while we are in the process of loading data
+				return;
 			}
-		}else{
-			this._publish("execute", { item: nodeWidget.item, node: nodeWidget, evt: e } );
-			this.onClick(nodeWidget.item, nodeWidget, e);
-			this.focusNode(nodeWidget);
-		}
-		event.stop(e);
-	},
-	_onDblClick: function(/*TreeNode*/ nodeWidget, /*Event*/ e){
-		// summary:
-		//		Translates double-click events into commands for the controller to process
 
-		var domElement = e.target,
-			isExpandoClick = (domElement == nodeWidget.expandoNode || domElement == nodeWidget.expandoNodeText);
+			if(node.isExpanded){
+				var ret = node.collapse();
 
-		if( (this.openOnDblClick && nodeWidget.isExpandable) ||isExpandoClick ){
-			// expando node was clicked, or label of a folder node was clicked; open it
-			if(nodeWidget.isExpandable){
-				this._onExpandoClick({node:nodeWidget});
-			}
-		}else{
-			this._publish("execute", { item: nodeWidget.item, node: nodeWidget, evt: e } );
-			this.onDblClick(nodeWidget.item, nodeWidget, e);
-			this.focusNode(nodeWidget);
-		}
-		event.stop(e);
-	},
+				this.onClose(node.item, node);
+				this._state(node, false);
 
-	_onExpandoClick: function(/*Object*/ message){
-		// summary:
-		//		User clicked the +/- icon; expand or collapse my children.
-		var node = message.node;
-
-		// If we are collapsing, we might be hiding the currently focused node.
-		// Also, clicking the expando node might have erased focus from the current node.
-		// For simplicity's sake just focus on the node with the expando.
-		this.focusNode(node);
-
-		if(node.isExpanded){
-			this._collapseNode(node);
-		}else{
-			this._expandNode(node);
-		}
-	},
+				this._startPaint(ret);	// after this finishes, need to reset widths of TreeNodes
 
-	onClick: function(/*===== item, node, evt =====*/){
-		// summary:
-		//		Callback when a tree node is clicked
-		// item: dojo.data.Item
-		// node: TreeNode
-		// evt: Event
-		// tags:
-		//		callback
-	},
-	onDblClick: function(/*===== item, node, evt =====*/){
-		// summary:
-		//		Callback when a tree node is double-clicked
-		// item: dojo.data.Item
-		// node: TreeNode
-		// evt: Event
-		// tags:
-		//		callback
-	},
-	onOpen: function(/*===== item, node =====*/){
-		// summary:
-		//		Callback when a node is opened
-		// item: dojo.data.Item
-		// node: TreeNode
-		// tags:
-		//		callback
-	},
-	onClose: function(/*===== item, node =====*/){
-		// summary:
-		//		Callback when a node is closed
-		// item: dojo.data.Item
-		// node: TreeNode
-		// tags:
-		//		callback
-	},
-
-	_getNextNode: function(node){
-		// summary:
-		//		Get next visible node
-
-		if(node.isExpandable && node.isExpanded && node.hasChildren()){
-			// if this is an expanded node, get the first child
-			return node.getChildren()[0];		// _TreeNode
-		}else{
-			// find a parent node with a sibling
-			while(node && node.isTreeNode){
-				var returnNode = node.getNextSibling();
-				if(returnNode){
-					return returnNode;		// _TreeNode
-				}
-				node = node.getParent();
+				return ret;
 			}
-			return null;
-		}
-	},
-
-	_getRootOrFirstNode: function(){
-		// summary:
-		//		Get first visible node
-		return this.showRoot ? this.rootNode : this.rootNode.getChildren()[0];
-	},
-
-	_collapseNode: function(/*_TreeNode*/ node){
-		// summary:
-		//		Called when the user has requested to collapse the node
-
-		if(node._expandNodeDeferred){
-			delete node._expandNodeDeferred;
-		}
-
-		if(node.isExpandable){
-			if(node.state == "LOADING"){
-				// ignore clicks while we are in the process of loading data
-				return;
+		},
+
+		_expandNode: function(/*TreeNode*/ node){
+			// summary:
+			//		Called when the user has requested to expand the node
+			// returns:
+			//		Promise that resolves when the node is loaded and opened and (if persist=true) all it's descendants
+			//		that were previously opened too
+
+			if(node._expandNodeDeferred){
+				// there's already an expand in progress, or completed, so just return
+				return node._expandNodeDeferred;	// dojo/Deferred
 			}
 
-			node.collapse();
-			this.onClose(node.item, node);
-
-			this._state(node, false);
-		}
-	},
-
-	_expandNode: function(/*_TreeNode*/ node, /*Boolean?*/ recursive){
-		// summary:
-		//		Called when the user has requested to expand the node
-		// recursive:
-		//		Internal flag used when _expandNode() calls itself, don't set.
-		// returns:
-		//		Deferred that fires when the node is loaded and opened and (if persist=true) all it's descendants
-		//		that were previously opened too
-
-		if(node._expandNodeDeferred && !recursive){
-			// there's already an expand in progress (or completed), so just return
-			return node._expandNodeDeferred;	// dojo.Deferred
-		}
-
-		var model = this.model,
-			item = node.item,
-			_this = this;
+			var model = this.model,
+				item = node.item,
+				_this = this;
 
-		switch(node.state){
-			case "UNCHECKED":
-				// need to load all the children, and then expand
+			// Load data if it's not already loaded
+			if(!node._loadDeferred){
+				// need to load all the children before expanding
 				node.markProcessing();
 
 				// Setup deferred to signal when the load and expand are finished.
 				// Save that deferred in this._expandDeferred as a flag that operation is in progress.
-				var def = (node._expandNodeDeferred = new Deferred());
+				node._loadDeferred = new Deferred();
 
 				// Get the children
 				model.getChildren(
@@ -1450,240 +1514,285 @@ var Tree = declare("dijit.Tree", [_Widget, _TemplatedMixin], {
 
 						// Display the children and also start expanding any children that were previously expanded
 						// (if this.persist == true).   The returned Deferred will fire when those expansions finish.
-						var scid = node.setChildItems(items);
-
-						// Call _expandNode() again but this time it will just to do the animation (default branch).
-						// The returned Deferred will fire when the animation completes.
-						// TODO: seems like I can avoid recursion and just use a deferred to sequence the events?
-						var ed = _this._expandNode(node, true);
-
-						// After the above two tasks (setChildItems() and recursive _expandNode()) finish,
-						// signal that I am done.
-						scid.addCallback(function(){
-							ed.addCallback(function(){
-								def.callback();
-							})
+						node.setChildItems(items).then(function(){
+							node._loadDeferred.resolve(items);
 						});
 					},
 					function(err){
-						console.error(_this, ": error loading root children: ", err);
+						console.error(_this, ": error loading " + node.label + " children: ", err);
+						node._loadDeferred.reject(err);
 					}
 				);
-				break;
+			}
 
-			default:	// "LOADED"
-				// data is already loaded; just expand node
-				def = (node._expandNodeDeferred = node.expand());
+			// Expand the node after data has loaded
+			var def = node._loadDeferred.then(lang.hitch(this, function(){
+				var def2 = node.expand();
 
+				// seems like these should delayed until node.expand() completes, but left here for back-compat about
+				// when this.isOpen flag gets set (ie, at the beginning of the animation)
 				this.onOpen(node.item, node);
-
 				this._state(node, true);
-		}
-
-		return def;	// dojo.Deferred
-	},
 
-	////////////////// Miscellaneous functions ////////////////
-
-	focusNode: function(/* _tree.Node */ node){
-		// summary:
-		//		Focus on the specified node (which must be visible)
-		// tags:
-		//		protected
-
-		// set focus so that the label will be voiced using screen readers
-		focus.focus(node.labelNode);
-	},
-
-	_onNodeFocus: function(/*dijit._Widget*/ node){
-		// summary:
-		//		Called when a TreeNode gets focus, either by user clicking
-		//		it, or programatically by arrow key handling code.
-		// description:
-		//		It marks that the current node is the selected one, and the previously
-		//		selected node no longer is.
-
-		if(node && node != this.lastFocused){
-			if(this.lastFocused && !this.lastFocused._destroyed){
-				// mark that the previously focsable node is no longer focusable
-				this.lastFocused.setFocusable(false);
+				return def2;
+			}));
+
+			this._startPaint(def);	// after this finishes, need to reset widths of TreeNodes
+
+			return def;	// dojo/promise/Promise
+		},
+
+		////////////////// Miscellaneous functions ////////////////
+
+		focusNode: function(/* _tree.Node */ node){
+			// summary:
+			//		Focus on the specified node (which must be visible)
+			// tags:
+			//		protected
+
+			this.focusChild(node);
+		},
+
+		_onNodeMouseEnter: function(/*dijit/_WidgetBase*/ /*===== node =====*/){
+			// summary:
+			//		Called when mouse is over a node (onmouseenter event),
+			//		this is monitored by the DND code
+		},
+
+		_onNodeMouseLeave: function(/*dijit/_WidgetBase*/ /*===== node =====*/){
+			// summary:
+			//		Called when mouse leaves a node (onmouseleave event),
+			//		this is monitored by the DND code
+		},
+
+		//////////////// Events from the model //////////////////////////
+
+		_onItemChange: function(/*Item*/ item){
+			// summary:
+			//		Processes notification of a change to an item's scalar values like label
+			var model = this.model,
+				identity = model.getIdentity(item),
+				nodes = this._itemNodesMap[identity];
+
+			if(nodes){
+				var label = this.getLabel(item),
+					tooltip = this.getTooltip(item);
+				array.forEach(nodes, function(node){
+					node.set({
+						item: item, // theoretically could be new JS Object representing same item
+						label: label,
+						tooltip: tooltip
+					});
+					node._updateItemClasses(item);
+				});
 			}
-
-			// mark that the new node is the currently selected one
-			node.setFocusable(true);
-			this.lastFocused = node;
-		}
-	},
-
-	_onNodeMouseEnter: function(/*dijit._Widget*/ /*===== node =====*/){
-		// summary:
-		//		Called when mouse is over a node (onmouseenter event),
-		//		this is monitored by the DND code
-	},
-
-	_onNodeMouseLeave: function(/*dijit._Widget*/ /*===== node =====*/){
-		// summary:
-		//		Called when mouse leaves a node (onmouseleave event),
-		//		this is monitored by the DND code
-	},
-
-	//////////////// Events from the model //////////////////////////
-
-	_onItemChange: function(/*Item*/ item){
-		// summary:
-		//		Processes notification of a change to an item's scalar values like label
-		var model = this.model,
-			identity = model.getIdentity(item),
-			nodes = this._itemNodesMap[identity];
-
-		if(nodes){
-			var label = this.getLabel(item),
-				tooltip = this.getTooltip(item);
-			array.forEach(nodes, function(node){
-				node.set({
-					item: item,		// theoretically could be new JS Object representing same item
-					label: label,
-					tooltip: tooltip
+		},
+
+		_onItemChildrenChange: function(/*dojo/data/Item*/ parent, /*dojo/data/Item[]*/ newChildrenList){
+			// summary:
+			//		Processes notification of a change to an item's children
+			var model = this.model,
+				identity = model.getIdentity(parent),
+				parentNodes = this._itemNodesMap[identity];
+
+			if(parentNodes){
+				array.forEach(parentNodes, function(parentNode){
+					parentNode.setChildItems(newChildrenList);
 				});
-				node._updateItemClasses(item);
-			});
-		}
-	},
-
-	_onItemChildrenChange: function(/*dojo.data.Item*/ parent, /*dojo.data.Item[]*/ newChildrenList){
-		// summary:
-		//		Processes notification of a change to an item's children
-		var model = this.model,
-			identity = model.getIdentity(parent),
-			parentNodes = this._itemNodesMap[identity];
-
-		if(parentNodes){
-			array.forEach(parentNodes,function(parentNode){
-				parentNode.setChildItems(newChildrenList);
-			});
-		}
-	},
-
-	_onItemDelete: function(/*Item*/ item){
-		// summary:
-		//		Processes notification of a deletion of an item
-		var model = this.model,
-			identity = model.getIdentity(item),
-			nodes = this._itemNodesMap[identity];
-
-		if(nodes){
-			array.forEach(nodes,function(node){
-				// Remove node from set of selected nodes (if it's selected)
-				this.dndController.removeTreeNode(node);
-
-				var parent = node.getParent();
-				if(parent){
-					// if node has not already been orphaned from a _onSetItem(parent, "children", ..) call...
-					parent.removeChild(node);
+			}
+		},
+
+		_onItemDelete: function(/*Item*/ item){
+			// summary:
+			//		Processes notification of a deletion of an item.
+			//		Not called from new dojo.store interface but there's cleanup code in setChildItems() instead.
+
+			var model = this.model,
+				identity = model.getIdentity(item),
+				nodes = this._itemNodesMap[identity];
+
+			if(nodes){
+				array.forEach(nodes, function(node){
+					// Remove node from set of selected nodes (if it's selected)
+					this.dndController.removeTreeNode(node);
+
+					var parent = node.getParent();
+					if(parent){
+						// if node has not already been orphaned from a _onSetItem(parent, "children", ..) call...
+						parent.removeChild(node);
+					}
+					node.destroyRecursive();
+				}, this);
+				delete this._itemNodesMap[identity];
+			}
+		},
+
+		/////////////// Miscellaneous funcs
+
+		_initState: function(){
+			// summary:
+			//		Load in which nodes should be opened automatically
+			this._openedNodes = {};
+			if(this.persist && this.cookieName){
+				var oreo = cookie(this.cookieName);
+				if(oreo){
+					array.forEach(oreo.split(','), function(item){
+						this._openedNodes[item] = true;
+					}, this);
 				}
-				node.destroyRecursive();
-			}, this);
-			delete this._itemNodesMap[identity];
-		}
-	},
-
-	/////////////// Miscellaneous funcs
+			}
+		},
 
-	_initState: function(){
-		// summary:
-		//		Load in which nodes should be opened automatically
-		this._openedNodes = {};
-		if(this.persist && this.cookieName){
-			var oreo = cookie(this.cookieName);
-			if(oreo){
-				array.forEach(oreo.split(','), function(item){
-					this._openedNodes[item] = true;
-				}, this);
+		_state: function(node, expanded){
+			// summary:
+			//		Query or set expanded state for an node
+			if(!this.persist){
+				return false;
 			}
-		}
-	},
-	_state: function(node, expanded){
-		// summary:
-		//		Query or set expanded state for an node
-		if(!this.persist){
-			return false;
-		}
-		var path = array.map(node.getTreePath(), function(item){
+			var path = array.map(node.getTreePath(),function(item){
 				return this.model.getIdentity(item);
 			}, this).join("/");
-		if(arguments.length === 1){
-			return this._openedNodes[path];
-		}else{
-			if(expanded){
-				this._openedNodes[path] = true;
+			if(arguments.length === 1){
+				return this._openedNodes[path];
 			}else{
-				delete this._openedNodes[path];
+				if(expanded){
+					this._openedNodes[path] = true;
+				}else{
+					delete this._openedNodes[path];
+				}
+				this._saveExpandedNodes();
 			}
-			var ary = [];
-			for(var id in this._openedNodes){
-				ary.push(id);
+		},
+
+		_saveExpandedNodes: function(){
+			if(this.persist && this.cookieName){
+				var ary = [];
+				for(var id in this._openedNodes){
+					ary.push(id);
+				}
+				cookie(this.cookieName, ary.join(","), {expires: 365});
 			}
-			cookie(this.cookieName, ary.join(","), {expires:365});
-		}
-	},
+		},
 
-	destroy: function(){
-		if(this._curSearch){
-			clearTimeout(this._curSearch.timer);
-			delete this._curSearch;
-		}
-		if(this.rootNode){
-			this.rootNode.destroyRecursive();
-		}
-		if(this.dndController && !lang.isString(this.dndController)){
-			this.dndController.destroy();
-		}
-		this.rootNode = null;
-		this.inherited(arguments);
-	},
-
-	destroyRecursive: function(){
-		// A tree is treated as a leaf, not as a node with children (like a grid),
-		// but defining destroyRecursive for back-compat.
-		this.destroy();
-	},
-
-	resize: function(changeSize){
-		if(changeSize){
-			domGeometry.setMarginBox(this.domNode, changeSize);
-		}
+		destroy: function(){
+			if(this._curSearch){
+				this._curSearch.timer.remove();
+				delete this._curSearch;
+			}
+			if(this.rootNode){
+				this.rootNode.destroyRecursive();
+			}
+			if(this.dndController && !lang.isString(this.dndController)){
+				this.dndController.destroy();
+			}
+			this.rootNode = null;
+			this.inherited(arguments);
+		},
+
+		destroyRecursive: function(){
+			// A tree is treated as a leaf, not as a node with children (like a grid),
+			// but defining destroyRecursive for back-compat.
+			this.destroy();
+		},
+
+		resize: function(changeSize){
+			if(changeSize){
+				domGeometry.setMarginBox(this.domNode, changeSize);
+			}
 
-		// The only JS sizing involved w/tree is the indentation, which is specified
-		// in CSS and read in through this dummy indentDetector node (tree must be
-		// visible and attached to the DOM to read this)
-		this._nodePixelIndent = domGeometry.position(this.tree.indentDetector).w;
+			// The main JS sizing involved w/tree is the indentation, which is specified
+			// in CSS and read in through this dummy indentDetector node (tree must be
+			// visible and attached to the DOM to read this).
+			// If the Tree is hidden domGeometry.position(this.tree.indentDetector).w will return 0, in which case just
+			// keep the default value.
+			this._nodePixelIndent = domGeometry.position(this.tree.indentDetector).w || this._nodePixelIndent;
+
+			// resize() may be called before this.rootNode is created, so wait until it's available
+			this.expandChildrenDeferred.then(lang.hitch(this, function(){
+				// If tree has already loaded, then reset indent for all the nodes
+				this.rootNode.set('indent', this.showRoot ? 0 : -1);
+
+				// Also, adjust widths of all rows to match width of Tree
+				this._adjustWidths();
+			}));
+		},
+
+		_outstandingPaintOperations: 0,
+		_startPaint: function(/*Promise|Boolean*/ p){
+			// summary:
+			//		Called at the start of an operation that will change what's displayed.
+			// p:
+			//		Promise that tells when the operation will complete.  Alternately, if it's just a Boolean, it signifies
+			//		that the operation was synchronous, and already completed.
+
+			this._outstandingPaintOperations++;
+			if(this._adjustWidthsTimer){
+				this._adjustWidthsTimer.remove();
+				delete this._adjustWidthsTimer;
+			}
 
-		if(this.tree.rootNode){
-			// If tree has already loaded, then reset indent for all the nodes
-			this.tree.rootNode.set('indent', this.showRoot ? 0 : -1);
-		}
-	},
+			var oc = lang.hitch(this, function(){
+				this._outstandingPaintOperations--;
 
-	_createTreeNode: function(/*Object*/ args){
-		// summary:
-		//		creates a TreeNode
-		// description:
-		//		Developers can override this method to define their own TreeNode class;
-		//		However it will probably be removed in a future release in favor of a way
-		//		of just specifying a widget for the label, rather than one that contains
-		//		the children too.
-		return new TreeNode(args);
-	},
-
-	_setTextDirAttr: function(textDir){
-		if(textDir && this.textDir!= textDir){
-			this._set("textDir",textDir);
-			this.rootNode.set("textDir", textDir);
+				if(this._outstandingPaintOperations <= 0 && !this._adjustWidthsTimer && this._started){
+					// Use defer() to avoid a width adjustment when another operation will immediately follow,
+					// such as a sequence of opening a node, then it's children, then it's grandchildren, etc.
+					this._adjustWidthsTimer = this.defer("_adjustWidths");
+				}
+			});
+			when(p, oc, oc);
+		},
+
+		_adjustWidths: function(){
+			// summary:
+			//		Size container to match widest TreeNode, so that highlighting with scrolling works (#13141, #16132)
+
+			if(this._adjustWidthsTimer){
+				this._adjustWidthsTimer.remove();
+				delete this._adjustWidthsTimer;
+			}
+
+			this.containerNode.style.width = "auto";
+			this.containerNode.style.width = this.domNode.scrollWidth > this.domNode.offsetWidth ? "auto" : "100%";
+		},
+
+		_createTreeNode: function(/*Object*/ args){
+			// summary:
+			//		creates a TreeNode
+			// description:
+			//		Developers can override this method to define their own TreeNode class;
+			//		However it will probably be removed in a future release in favor of a way
+			//		of just specifying a widget for the label, rather than one that contains
+			//		the children too.
+			return new TreeNode(args);
+		},
+
+		focus: function(){
+			// summary:
+			//		Default focus() implementation: focus the previously focused child, or first child.
+			//		Some applications may want to change this method to focus the [first] selected child.
+
+			if(this.lastFocusedChild){
+				this.focusNode(this.lastFocusedChild);
+			}else{
+				this.focusFirstChild();
+			}
 		}
+	});
+
+	if(has("dojo-bidi")){
+		Tree.extend({
+			_setTextDirAttr: function(textDir){
+				if(textDir && this.textDir != textDir){
+					this._set("textDir", textDir);
+					this.rootNode.set("textDir", textDir);
+				}
+			}
+		});
 	}
-});
 
-Tree._TreeNode = TreeNode;	// for monkey patching
+	Tree.PathError = createError("TreePathError");
+	Tree._TreeNode = TreeNode;	// for monkey patching or creating subclasses of TreeNode
 
-return Tree;
+	return Tree;
 });
diff --git a/dijit/Viewport.js b/dijit/Viewport.js
new file mode 100644
index 0000000..bf9a811
--- /dev/null
+++ b/dijit/Viewport.js
@@ -0,0 +1,87 @@
+define([
+	"dojo/Evented",
+	"dojo/on",
+	"dojo/domReady",
+	"dojo/sniff",	// has("ie"), has("ios")
+	"dojo/window" // getBox()
+], function(Evented, on, domReady, has, winUtils){
+
+	// module:
+	//		dijit/Viewport
+
+	/*=====
+	return {
+		// summary:
+		//		Utility singleton to watch for viewport resizes, avoiding duplicate notifications
+		//		which can lead to infinite loops.
+		// description:
+		//		Usage: Viewport.on("resize", myCallback).
+		//
+		//		myCallback() is called without arguments in case it's _WidgetBase.resize(),
+		//		which would interpret the argument as the size to make the widget.
+	};
+	=====*/
+
+	var Viewport = new Evented();
+
+	var focusedNode;
+
+	domReady(function(){
+		var oldBox = winUtils.getBox();
+		Viewport._rlh = on(window, "resize", function(){
+			var newBox = winUtils.getBox();
+			if(oldBox.h == newBox.h && oldBox.w == newBox.w){ return; }
+			oldBox = newBox;
+			Viewport.emit("resize");
+		});
+
+		// Also catch zoom changes on IE8, since they don't naturally generate resize events
+		if(has("ie") == 8){
+			var deviceXDPI = screen.deviceXDPI;
+			setInterval(function(){
+				if(screen.deviceXDPI != deviceXDPI){
+					deviceXDPI = screen.deviceXDPI;
+					Viewport.emit("resize");
+				}
+			}, 500);
+		}
+
+		// On iOS, keep track of the focused node so we can guess when the keyboard is/isn't being displayed.
+		if(has("ios")){
+			on(document, "focusin", function(evt){
+				focusedNode = evt.target;
+			});
+			on(document, "focusout", function(evt){
+				focusedNode = null;
+			});
+		}
+	});
+
+	Viewport.getEffectiveBox = function(/*Document*/ doc){
+		// summary:
+		//		Get the size of the viewport, or on mobile devices, the part of the viewport not obscured by the
+		//		virtual keyboard.
+
+		var box = winUtils.getBox(doc);
+
+		// Account for iOS virtual keyboard, if it's being shown.  Unfortunately no direct way to check or measure.
+		var tag = focusedNode && focusedNode.tagName && focusedNode.tagName.toLowerCase();
+		if(has("ios") && focusedNode && !focusedNode.readOnly && (tag == "textarea" || (tag == "input" &&
+			/^(color|email|number|password|search|tel|text|url)$/.test(focusedNode.type)))){
+
+			// Box represents the size of the viewport.  Some of the viewport is likely covered by the keyboard.
+			// Estimate height of visible viewport assuming viewport goes to bottom of screen, but is covered by keyboard.
+			box.h *= (orientation == 0 || orientation == 180 ? 0.66 : 0.40);
+
+			// Above measurement will be inaccurate if viewport was scrolled up so far that it ends before the bottom
+			// of the screen.   In this case, keyboard isn't covering as much of the viewport as we thought.
+			// We know the visible size is at least the distance from the top of the viewport to the focused node.
+			var rect = focusedNode.getBoundingClientRect();
+			box.h = Math.max(box.h, rect.top + rect.height);
+		}
+
+		return box;
+	};
+
+	return Viewport;
+});
diff --git a/dijit/WidgetSet.js b/dijit/WidgetSet.js
index f5a2b6a..ea25044 100644
--- a/dijit/WidgetSet.js
+++ b/dijit/WidgetSet.js
@@ -1,44 +1,40 @@
 define([
 	"dojo/_base/array", // array.forEach array.map
 	"dojo/_base/declare", // declare
-	"dojo/_base/window", // win.global
+	"dojo/_base/kernel", // kernel.global
 	"./registry"	// to add functions to dijit.registry
-], function(array, declare, win, registry){
+], function(array, declare, kernel, registry){
 
 	// module:
 	//		dijit/WidgetSet
-	// summary:
-	//		Legacy registry code.   New modules should just use registry.
-	//		Will be removed in 2.0.
 
 	var WidgetSet = declare("dijit.WidgetSet", null, {
 		// summary:
-		//		A set of widgets indexed by id. A default instance of this class is
-		//		available as `dijit.registry`
+		//		A set of widgets indexed by id.
+		//		Deprecated, will be removed in 2.0.
 		//
 		// example:
 		//		Create a small list of widgets:
-		//		|	var ws = new dijit.WidgetSet();
-		//		|	ws.add(dijit.byId("one"));
-		//		| 	ws.add(dijit.byId("two"));
-		//		|	// destroy both:
-		//		|	ws.forEach(function(w){ w.destroy(); });
-		//
-		// example:
-		//		Using dijit.registry:
-		//		|	dijit.registry.forEach(function(w){ /* do something */ });
+		//		|	require(["dijit/WidgetSet", "dijit/registry"],
+		//		|		function(WidgetSet, registry){
+		//		|		var ws = new WidgetSet();
+		//		|		ws.add(registry.byId("one"));
+		//		|		ws.add(registry.byId("two"));
+		//		|		// destroy both:
+		//		|		ws.forEach(function(w){ w.destroy(); });
+		//		|	});
 
 		constructor: function(){
 			this._hash = {};
 			this.length = 0;
 		},
 
-		add: function(/*dijit._Widget*/ widget){
+		add: function(/*dijit/_WidgetBase*/ widget){
 			// summary:
 			//		Add a widget to this list. If a duplicate ID is detected, a error is thrown.
 			//
-			// widget: dijit._Widget
-			//		Any dijit._Widget subclass.
+			// widget: dijit/_WidgetBase
+			//		Any dijit/_WidgetBase subclass.
 			if(this._hash[widget.id]){
 				throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
 			}
@@ -69,19 +65,22 @@ define([
 			//
 			// example:
 			//		Using the default `dijit.registry` instance:
-			//		|	dijit.registry.forEach(function(widget){
-			//		|		console.log(widget.declaredClass);
+			//		|	require(["dijit/WidgetSet", "dijit/registry"],
+			//		|		function(WidgetSet, registry){
+			//		|		registry.forEach(function(widget){
+			//		|			console.log(widget.declaredClass);
+			//		|		});
 			//		|	});
 			//
 			// returns:
 			//		Returns self, in order to allow for further chaining.
 
-			thisObj = thisObj || win.global;
+			thisObj = thisObj || kernel.global;
 			var i = 0, id;
 			for(id in this._hash){
 				func.call(thisObj, this._hash[id], i++, this._hash);
 			}
-			return this;	// dijit.WidgetSet
+			return this;	// dijit/WidgetSet
 		},
 
 		filter: function(/*Function*/ filter, /* Object? */thisObj){
@@ -98,11 +97,17 @@ define([
 			//
 			// example:
 			//		Arbitrary: select the odd widgets in this list
-			//		|	dijit.registry.filter(function(w, i){
-			//		|		return i % 2 == 0;
-			//		|	}).forEach(function(w){ /* odd ones */ });
+			//		|	
+			//		|		
+			//		|	
+			//		|	require(["dijit/WidgetSet", "dijit/registry"],
+			//		|		function(WidgetSet, registry){
+			//		|		registry.filter(function(w, i){
+			//		|			return i % 2 == 0;
+			//		|		}).forEach(function(w){ /* odd ones */ });
+			//		|	});
 
-			thisObj = thisObj || win.global;
+			thisObj = thisObj || kernel.global;
 			var res = new WidgetSet(), i = 0, id;
 			for(id in this._hash){
 				var w = this._hash[id];
@@ -110,7 +115,7 @@ define([
 					res.add(w);
 				}
 			}
-			return res; // dijit.WidgetSet
+			return res; // dijit/WidgetSet
 		},
 
 		byId: function(/*String*/ id){
@@ -118,12 +123,15 @@ define([
 			//		Find a widget in this list by it's id.
 			// example:
 			//		Test if an id is in a particular WidgetSet
-			//		| var ws = new dijit.WidgetSet();
-			//		| ws.add(dijit.byId("bar"));
-			//		| var t = ws.byId("bar") // returns a widget
-			//		| var x = ws.byId("foo"); // returns undefined
+			//		|	require(["dijit/WidgetSet", "dijit/registry"],
+			//		|		function(WidgetSet, registry){
+			//		|		var ws = new WidgetSet();
+			//		|		ws.add(registry.byId("bar"));
+			//		|		var t = ws.byId("bar") // returns a widget
+			//		|		var x = ws.byId("foo"); // returns undefined
+			//		|	});
 
-			return this._hash[id];	// dijit._Widget
+			return this._hash[id];	// dijit/_WidgetBase
 		},
 
 		byClass: function(/*String*/ cls){
@@ -135,7 +143,10 @@ define([
 			//
 			// example:
 			//		Find all `dijit.TitlePane`s in a page:
-			//		|	dijit.registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); });
+			//		|	require(["dijit/WidgetSet", "dijit/registry"],
+			//		|		function(WidgetSet, registry){
+			//		|		registry.byClass("dijit.TitlePane").forEach(function(tp){ tp.close(); });
+			//		|	});
 
 			var res = new WidgetSet(), id, widget;
 			for(id in this._hash){
@@ -144,7 +155,7 @@ define([
 					res.add(widget);
 				}
 			 }
-			 return res; // dijit.WidgetSet
+			 return res; // dijit/WidgetSet
 		},
 
 		toArray: function(){
@@ -153,20 +164,27 @@ define([
 			//
 			// example:
 			//		Work with the widget .domNodes in a real Array
-			//		|	array.map(dijit.registry.toArray(), function(w){ return w.domNode; });
+			//		|	require(["dijit/WidgetSet", "dijit/registry"],
+			//		|		function(WidgetSet, registry){
+			//		|		array.map(registry.toArray(), function(w){ return w.domNode; });
+			//		|	});
+
 
 			var ar = [];
 			for(var id in this._hash){
 				ar.push(this._hash[id]);
 			}
-			return ar;	// dijit._Widget[]
+			return ar;	// dijit/_WidgetBase[]
 		},
 
 		map: function(/* Function */func, /* Object? */thisObj){
 			// summary:
 			//		Create a new Array from this WidgetSet, following the same rules as `array.map`
 			// example:
-			//		|	var nodes = dijit.registry.map(function(w){ return w.domNode; });
+			//		|	require(["dijit/WidgetSet", "dijit/registry"],
+			//		|		function(WidgetSet, registry){
+			//		|		var nodes = registry.map(function(w){ return w.domNode; });
+			//		|	});
 			//
 			// returns:
 			//		A new array of the returned values.
@@ -175,7 +193,7 @@ define([
 
 		every: function(func, thisObj){
 			// summary:
-			// 		A synthetic clone of `array.every` acting explicitly on this WidgetSet
+			//		A synthetic clone of `array.every` acting explicitly on this WidgetSet
 			//
 			// func: Function
 			//		A callback function run for every widget in this list. Exits loop
@@ -184,7 +202,7 @@ define([
 			// thisObj: Object?
 			//		Optional scope parameter to use for the callback
 
-			thisObj = thisObj || win.global;
+			thisObj = thisObj || kernel.global;
 			var x = 0, i;
 			for(i in this._hash){
 				if(!func.call(thisObj, this._hash[i], x++, this._hash)){
@@ -196,7 +214,7 @@ define([
 
 		some: function(func, thisObj){
 			// summary:
-			// 		A synthetic clone of `array.some` acting explicitly on this WidgetSet
+			//		A synthetic clone of `array.some` acting explicitly on this WidgetSet
 			//
 			// func: Function
 			//		A callback function run for every widget in this list. Exits loop
@@ -205,7 +223,7 @@ define([
 			// thisObj: Object?
 			//		Optional scope parameter to use for the callback
 
-			thisObj = thisObj || win.global;
+			thisObj = thisObj || kernel.global;
 			var x = 0, i;
 			for(i in this._hash){
 				if(func.call(thisObj, this._hash[i], x++, this._hash)){
@@ -217,7 +235,7 @@ define([
 
 	});
 
-	// Add in 1.x compatibility methods to dijit.registry.
+	// Add in 1.x compatibility methods to dijit/registry.
 	// These functions won't show up in the API doc but since they are deprecated anyway,
 	// that's probably for the best.
 	array.forEach(["forEach", "filter", "byClass", "map", "every", "some"], function(func){
diff --git a/dijit/_AttachMixin.js b/dijit/_AttachMixin.js
new file mode 100644
index 0000000..4fb30f7
--- /dev/null
+++ b/dijit/_AttachMixin.js
@@ -0,0 +1,238 @@
+define([
+	"require",
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/connect",	// remove for 2.0
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.getObject
+	"dojo/mouse",
+	"dojo/on",
+	"dojo/touch",
+	"./_WidgetBase"
+], function(require, array, connect, declare, lang, mouse, on, touch, _WidgetBase){
+
+	// module:
+	//		dijit/_AttachMixin
+
+	// Map from string name like "mouseenter" to synthetic event like mouse.enter
+	var synthEvents = lang.delegate(touch, {
+		"mouseenter": mouse.enter,
+		"mouseleave": mouse.leave,
+		"keypress": connect._keypress	// remove for 2.0
+	});
+
+	// To be lightweight, _AttachMixin doesn't require() dijit/a11yclick.
+	// If the subclass has a template using "ondijitclick", it must load dijit/a11yclick itself.
+	// In that case, the a11yclick variable below will get set to point to that synthetic event.
+	var a11yclick;
+
+	var _AttachMixin = declare("dijit._AttachMixin", null, {
+		// summary:
+		//		Mixin for widgets to attach to dom nodes and setup events via
+		//		convenient data-dojo-attach-point and data-dojo-attach-event DOM attributes.
+		//
+		//		Superclass of _TemplatedMixin, and can also be used standalone when templates are pre-rendered on the
+		//		server.
+		//
+		//		Does not [yet] handle widgets like ContentPane with this.containerNode set.   It should skip
+		//		scanning for data-dojo-attach-point and data-dojo-attach-event inside this.containerNode, but it
+		//		doesn't.
+
+/*=====
+		// _attachPoints: [private] String[]
+		//		List of widget attribute names associated with data-dojo-attach-point=... in the
+		//		template, ex: ["containerNode", "labelNode"]
+		_attachPoints: [],
+
+		// _attachEvents: [private] Handle[]
+		//		List of connections associated with data-dojo-attach-event=... in the
+		//		template
+		_attachEvents: [],
+
+		// attachScope: [public] Object
+		//		Object to which attach points and events will be scoped.  Defaults
+		//		to 'this'.
+		attachScope: undefined,
+
+		// searchContainerNode: [protected] Boolean
+		//		Search descendants of this.containerNode for data-dojo-attach-point and data-dojo-attach-event.
+		//		Should generally be left false (the default value) both for performance and to avoid failures when
+		//		this.containerNode holds other _AttachMixin instances with their own attach points and events.
+ 		searchContainerNode: false,
+ =====*/
+
+		constructor: function(/*===== params, srcNodeRef =====*/){
+			// summary:
+			//		Create the widget.
+			// params: Object|null
+			//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+			//		and functions, typically callbacks like onClick.
+			//		The hash can contain any of the widget's properties, excluding read-only properties.
+			// srcNodeRef: DOMNode|String?
+			//		If a srcNodeRef (DOM node) is specified, replace srcNodeRef with my generated DOM tree.
+
+			this._attachPoints = [];
+			this._attachEvents = [];
+		},
+
+
+		buildRendering: function(){
+			// summary:
+			//		Attach to DOM nodes marked with special attributes.
+			// tags:
+			//		protected
+
+			this.inherited(arguments);
+
+			// recurse through the node, looking for, and attaching to, our
+			// attachment points and events, which should be defined on the template node.
+			this._attachTemplateNodes(this.domNode);
+
+			this._beforeFillContent();		// hook for _WidgetsInTemplateMixin
+		},
+
+		_beforeFillContent: function(){
+		},
+
+		_attachTemplateNodes: function(rootNode){
+			// summary:
+			//		Iterate through the dom nodes and attach functions and nodes accordingly.
+			// description:
+			//		Map widget properties and functions to the handlers specified in
+			//		the dom node and it's descendants. This function iterates over all
+			//		nodes and looks for these properties:
+			//
+			//		- dojoAttachPoint/data-dojo-attach-point
+			//		- dojoAttachEvent/data-dojo-attach-event
+			// rootNode: DomNode
+			//		The node to search for properties. All descendants will be searched.
+			// tags:
+			//		private
+
+			// DFS to process all nodes except those inside of this.containerNode
+			var node = rootNode;
+			while(true){
+				if(node.nodeType == 1 && (this._processTemplateNode(node, function(n,p){ return n.getAttribute(p); },
+						this._attach) || this.searchContainerNode) && node.firstChild){
+					node = node.firstChild;
+				}else{
+					if(node == rootNode){ return; }
+					while(!node.nextSibling){
+						node = node.parentNode;
+						if(node == rootNode){ return; }
+					}
+					node = node.nextSibling;
+				}
+			}
+		},
+
+		_processTemplateNode: function(/*DOMNode|Widget*/ baseNode, getAttrFunc, attachFunc){
+			// summary:
+			//		Process data-dojo-attach-point and data-dojo-attach-event for given node or widget.
+			//		Returns true if caller should process baseNode's children too.
+
+			var ret = true;
+
+			// Process data-dojo-attach-point
+			var _attachScope = this.attachScope || this,
+				attachPoint = getAttrFunc(baseNode, "dojoAttachPoint") || getAttrFunc(baseNode, "data-dojo-attach-point");
+			if(attachPoint){
+				var point, points = attachPoint.split(/\s*,\s*/);
+				while((point = points.shift())){
+					if(lang.isArray(_attachScope[point])){
+						_attachScope[point].push(baseNode);
+					}else{
+						_attachScope[point] = baseNode;
+					}
+					ret = (point != "containerNode");
+					this._attachPoints.push(point);
+				}
+			}
+
+			// Process data-dojo-attach-event
+			var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent") || getAttrFunc(baseNode, "data-dojo-attach-event");
+			if(attachEvent){
+				// NOTE: we want to support attributes that have the form
+				// "domEvent: nativeEvent; ..."
+				var event, events = attachEvent.split(/\s*,\s*/);
+				var trim = lang.trim;
+				while((event = events.shift())){
+					if(event){
+						var thisFunc = null;
+						if(event.indexOf(":") != -1){
+							// oh, if only JS had tuple assignment
+							var funcNameArr = event.split(":");
+							event = trim(funcNameArr[0]);
+							thisFunc = trim(funcNameArr[1]);
+						}else{
+							event = trim(event);
+						}
+						if(!thisFunc){
+							thisFunc = event;
+						}
+
+						this._attachEvents.push(attachFunc(baseNode, event, lang.hitch(_attachScope, thisFunc)));
+					}
+				}
+			}
+
+			return ret;
+		},
+
+		_attach: function(node, type, func){
+			// summary:
+			//		Roughly corresponding to dojo/on, this is the default function for processing a
+			//		data-dojo-attach-event.  Meant to attach to DOMNodes, not to widgets.
+			// node: DOMNode
+			//		The node to setup a listener on.
+			// type: String
+			//		Event name like "click".
+			// getAttrFunc: Function
+			//		Function to get the specified property for a given DomNode/Widget.
+			// attachFunc: Function?
+			//		Attaches an event handler from the specified node/widget to specified function.
+
+			// Map special type names like "mouseenter" to synthetic events.
+			// Subclasses are responsible to require() dijit/a11yclick if they want to use it.
+			type = type.replace(/^on/, "").toLowerCase();
+			if(type == "dijitclick"){
+				type = a11yclick || (a11yclick = require("./a11yclick"));
+			}else{
+				type = synthEvents[type] || type;
+			}
+
+			return on(node, type, func);
+		},
+
+		_detachTemplateNodes: function() {
+			// summary:
+			//		Detach and clean up the attachments made in _attachtempalteNodes.
+
+			// Delete all attach points to prevent IE6 memory leaks.
+			var _attachScope = this.attachScope || this;
+			array.forEach(this._attachPoints, function(point){
+				delete _attachScope[point];
+			});
+			this._attachPoints = [];
+
+			// And same for event handlers
+			array.forEach(this._attachEvents, function(handle){ handle.remove(); });
+			this._attachEvents = [];
+		},
+
+		destroyRendering: function(){
+			this._detachTemplateNodes();
+			this.inherited(arguments);
+		}
+	});
+
+	// These arguments can be specified for widgets which are used in templates.
+	// Since any widget can be specified as sub widgets in template, mix it
+	// into the base widget class.  (This is a hack, but it's effective.).
+	// Remove for 2.0.   Also, hide from API doc parser.
+	lang.extend(_WidgetBase, /*===== {} || =====*/ {
+		dojoAttachEvent: "",
+		dojoAttachPoint: ""
+	});
+	
+	return _AttachMixin;
+});
diff --git a/dijit/_BidiMixin.js b/dijit/_BidiMixin.js
new file mode 100644
index 0000000..c3d0c26
--- /dev/null
+++ b/dijit/_BidiMixin.js
@@ -0,0 +1,159 @@
+define([], function(){
+
+	// module:
+	//		dijit/_BidiMixin
+
+	// UCC - constants that will be used by bidi support.
+	var bidi_const = {
+		LRM : '\u200E',
+		LRE : '\u202A',
+		PDF : '\u202C',
+		RLM : '\u200f',
+		RLE : '\u202B'
+	};
+
+	return {
+		// summary:
+		//		When has("dojo-bidi") is true, _WidgetBase will mixin this class.   It enables support for the textdir
+		//		property to control text direction independently from the GUI direction.
+		// description:
+		//		There's a special need for displaying BIDI text in rtl direction
+		//		in ltr GUI, sometimes needed auto support.
+		//		In creation of widget, if it's want to activate this class,
+		//		the widget should define the "textDir".
+
+		// textDir: String
+		//		Bi-directional support,	the main variable which is responsible for the direction of the text.
+		//		The text direction can be different than the GUI direction by using this parameter in creation
+		//		of a widget.
+		//
+		//		Allowed values:
+		//
+		//		1. "ltr"
+		//		2. "rtl"
+		//		3. "auto" - contextual the direction of a text defined by first strong letter.
+		//
+		//		By default is as the page direction.
+		textDir: "",
+
+		getTextDir: function(/*String*/ text){
+			// summary:
+			//		Gets the right direction of text.
+			// description:
+			//		If textDir is ltr or rtl returns the value.
+			//		If it's auto, calls to another function that responsible
+			//		for checking the value, and defining the direction.
+			// tags:
+			//		protected.
+			return this.textDir == "auto" ? this._checkContextual(text) : this.textDir;
+		},
+
+		_checkContextual: function(text){
+			// summary:
+			//		Finds the first strong (directional) character, return ltr if isLatin
+			//		or rtl if isBidiChar.
+			// tags:
+			//		private.
+
+			// look for strong (directional) characters
+			var fdc = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(text);
+			// if found return the direction that defined by the character, else return widgets dir as defult.
+			return fdc ? ( fdc[0] <= 'z' ? "ltr" : "rtl" ) : this.dir ? this.dir : this.isLeftToRight() ? "ltr" : "rtl";
+		},
+
+		applyTextDir: function(/*DOMNode*/ element, /*String?*/ text){
+			// summary:
+			//		Set element.dir according to this.textDir, assuming this.textDir has a value.
+			// element:
+			//		The text element to be set. Should have dir property.
+			// text:
+			//		If specified, and this.textDir is "auto", for calculating the right transformation
+			//		Otherwise text read from element.
+			// description:
+			//		If textDir is ltr or rtl returns the value.
+			//		If it's auto, calls to another function that responsible
+			//		for checking the value, and defining the direction.
+			// tags:
+			//		protected.
+
+			if(this.textDir){
+				var textDir = this.textDir;
+				if(textDir == "auto"){
+					// convert "auto" to either "ltr" or "rtl"
+					if(typeof text === "undefined"){
+						// text not specified, get text from element
+						var tagName = element.tagName.toLowerCase();
+						text = (tagName == "input" || tagName == "textarea") ? element.value :
+							element.innerText || element.textContent || "";
+					}
+					textDir = this._checkContextual(text);
+				}
+
+				if(element.dir != textDir){
+					// set element's dir to match textDir, but not when textDir is null and not when it already matches
+					element.dir = textDir;
+				}
+			}
+		},
+
+		enforceTextDirWithUcc: function(option, text){
+			// summary:
+			//		Wraps by UCC (Unicode control characters) option's text according to this.textDir
+			// option:
+			//		The element (`<option>`) we wrapping the text for.
+			// text:
+			//		The text to be wrapped.
+			// description:
+			//		There's a dir problem with some HTML elements. For some elements (e.g. `<option>`, `<select>`)
+			//		defining the dir in different direction then the GUI orientation, won't display correctly.
+			//		FF 3.6 will change the alignment of the text in option - this doesn't follow the bidi standards (static text
+			//		should be aligned following GUI direction). IE8 and Opera11.10 completely ignore dir setting for `<option>`.
+			//		Therefore the only solution is to use UCC (Unicode  control characters) to display the text in correct orientation.
+			//		This function saves the original text value for later restoration if needed, for example if the textDir will change etc.
+			if(this.textDir){
+				if(option){
+					option.originalText = text;
+				}
+				var dir = this.textDir == "auto" ? this._checkContextual(text) : this.textDir;
+				return (dir == "ltr" ? bidi_const.LRE : bidi_const.RLE ) + text + bidi_const.PDF;
+			}
+			return text;
+		},
+
+		restoreOriginalText: function(origObj){
+			// summary:
+			//		Restores the text of origObj, if needed, after enforceTextDirWithUcc, e.g. set("textDir", textDir).
+			// origObj:
+			//		The element (`<option>`) to restore.
+			// description:
+			//		Sets the text of origObj to origObj.originalText, which is the original text, without the UCCs.
+			//		The function than removes the originalText from origObj!
+			if(origObj.originalText){
+				origObj.text = origObj.originalText;
+				delete origObj.originalText;
+			}
+			return origObj;
+		},
+
+		_setTextDirAttr: function(/*String*/ textDir){
+			// summary:
+			//		Setter for textDir.
+			// description:
+			//		Users shouldn't call this function; they should be calling
+			//		set('textDir', value)
+			if(!this._created || this.textDir != textDir){
+				this._set("textDir", textDir);
+				var node = null;
+				if(this.displayNode){
+					node = this.displayNode;
+					this.displayNode.align = this.dir == "rtl" ? "right" : "left";
+				}else{
+					node = this.textDirNode || this.focusNode || this.textbox;
+				}
+				if(node){
+					this.applyTextDir(node);
+				}
+			}
+		}
+	};
+});
diff --git a/dijit/_BidiSupport.js b/dijit/_BidiSupport.js
index a533f73..de1177d 100644
--- a/dijit/_BidiSupport.js
+++ b/dijit/_BidiSupport.js
@@ -1,69 +1,21 @@
-define(["./_WidgetBase"], function(_WidgetBase){
-
-/*=====
-	var _WidgetBase = dijit._WidgetBase;
-====*/
+define(["dojo/has", "./_WidgetBase", "./_BidiMixin"], function(has, _WidgetBase, _BidiMixin){
 
 	// module:
 	//		dijit/_BidiSupport
-	// summary:
-	//		Module that deals with BIDI, special with the auto
-	//		direction if needed without changing the GUI direction.
-	//		Including this module will extend _WidgetBase with BIDI related methods.
-	// description:
-	//		There's a special need for displaying BIDI text in rtl direction
-	//		in ltr GUI, sometimes needed auto support.
-	//		In creation of widget, if it's want to activate this class,
-	//		the widget should define the "textDir".
-
-	_WidgetBase.extend({
-
-		getTextDir: function(/*String*/ text){
-			// summary:
-			//		Gets the right direction of text.
-			// description:
-			// 		If textDir is ltr or rtl returns the value.
-			//		If it's auto, calls to another function that responsible
-			//		for checking the value, and defining the direction.
-			//	tags:
-			//		protected.
-			return this.textDir == "auto" ? this._checkContextual(text) : this.textDir;
-		},
-
-		_checkContextual: function(text){
-			// summary:
-			//		Finds the first strong (directional) character, return ltr if isLatin
-			//		or rtl if isBidiChar.
-			//	tags:
-			//		private.
 
-			// look for strong (directional) characters
-			var fdc = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(text);
-			// if found return the direction that defined by the character, else return widgets dir as defult.
-			return fdc ? ( fdc[0] <= 'z' ? "ltr" : "rtl" ) : this.dir ? this.dir : this.isLeftToRight() ? "ltr" : "rtl";
-		},
+	/*=====
+	return function(){
+		// summary:
+		//		Deprecated module for enabling textdir support in the dijit widgets.   New code should just define
+		//		has("dojo-bidi") to return true, rather than manually requiring this module.
+	};
+	=====*/
 
-		applyTextDir: function(/*Object*/ element, /*String*/ text){
-			// summary:
-			//		Set element.dir according to this.textDir
-			// element:
-			//		The text element to be set. Should have dir property.
-			// text:
-			//		Used in case this.textDir is "auto", for calculating the right transformation
-			// description:
-			// 		If textDir is ltr or rtl returns the value.
-			//		If it's auto, calls to another function that responsible
-			//		for checking the value, and defining the direction.
-			//	tags:
-			//		protected.
+	_WidgetBase.extend(_BidiMixin);
 
-			var textDir = this.textDir == "auto" ? this._checkContextual(text) : this.textDir;
-			// update only when there's a difference
-			if(element.dir != textDir){
-				element.dir = textDir;
-			}
-		}
-	});
+	// Back-compat with version 1.8: just including _BidiSupport should trigger bidi support in all the widgets.
+	// Although this statement doesn't do much because the other widgets have likely already been loaded.
+	has.add("dojo-bidi", true);
 
 	return _WidgetBase;
 });
diff --git a/dijit/_Calendar.js b/dijit/_Calendar.js
index 96e52fa..488e6b1 100644
--- a/dijit/_Calendar.js
+++ b/dijit/_Calendar.js
@@ -1,13 +1,18 @@
 define([
 	"dojo/_base/kernel", // kernel.deprecated
 	"./Calendar",
-	"."	// for exporting dijit.Calendar
+	"./main"	// for exporting dijit.Calendar
 ], function(kernel, Calendar, dijit){
 
 	// module:
 	//		dijit/_Calendar
-	// summary:
-	//		Deprecated widget, used dijit/Calendar instead.   Will be removed in 2.0.
+
+	/*=====
+	return {
+		// summary:
+		//		Deprecated widget, used dijit/Calendar instead.   Will be removed in 2.0.
+	};
+	=====*/
 
 	kernel.deprecated("dijit._Calendar is deprecated", "dijit._Calendar moved to dijit.Calendar", 2.0);
 
diff --git a/dijit/_Contained.js b/dijit/_Contained.js
index 21c286d..2f54ac4 100644
--- a/dijit/_Contained.js
+++ b/dijit/_Contained.js
@@ -5,29 +5,26 @@ define([
 
 	// module:
 	//		dijit/_Contained
-	// summary:
-	//		Mixin for widgets that are children of a container widget
 
 	return declare("dijit._Contained", null, {
 		// summary:
 		//		Mixin for widgets that are children of a container widget
-		//
 		// example:
-		// | 	// make a basic custom widget that knows about it's parents
-		// |	declare("my.customClass",[dijit._Widget,dijit._Contained],{});
+		//	|	// make a basic custom widget that knows about its parents
+		//	|	declare("my.customClass",[dijit._WidgetBase, dijit._Contained],{});
 
 		_getSibling: function(/*String*/ which){
 			// summary:
-			//      Returns next or previous sibling
+			//		Returns next or previous sibling
 			// which:
-			//      Either "next" or "previous"
+			//		Either "next" or "previous"
 			// tags:
-			//      private
+			//		private
 			var node = this.domNode;
 			do{
 				node = node[which+"Sibling"];
 			}while(node && node.nodeType != 1);
-			return node && registry.byNode(node);	// dijit._Widget
+			return node && registry.byNode(node);	// dijit/_WidgetBase
 		},
 
 		getPreviousSibling: function(){
@@ -35,7 +32,7 @@ define([
 			//		Returns null if this is the first child of the parent,
 			//		otherwise returns the next element sibling to the "left".
 
-			return this._getSibling("previous"); // dijit._Widget
+			return this._getSibling("previous"); // dijit/_WidgetBase
 		},
 
 		getNextSibling: function(){
@@ -43,14 +40,14 @@ define([
 			//		Returns null if this is the last child of the parent,
 			//		otherwise returns the next element sibling to the "right".
 
-			return this._getSibling("next"); // dijit._Widget
+			return this._getSibling("next"); // dijit/_WidgetBase
 		},
 
 		getIndexInParent: function(){
 			// summary:
 			//		Returns the index of this widget within its container parent.
 			//		It returns -1 if the parent does not exist, or if the parent
-			//		is not a dijit._Container
+			//		is not a dijit/_Container
 
 			var p = this.getParent();
 			if(!p || !p.getIndexOfChild){
diff --git a/dijit/_Container.js b/dijit/_Container.js
index a8bd92b..497da30 100644
--- a/dijit/_Container.js
+++ b/dijit/_Container.js
@@ -2,51 +2,55 @@ define([
 	"dojo/_base/array", // array.forEach array.indexOf
 	"dojo/_base/declare", // declare
 	"dojo/dom-construct", // domConstruct.place
-	"./registry"	// registry.byNode()
-], function(array, declare, domConstruct, registry){
+	"dojo/_base/kernel" // kernel.deprecated
+], function(array, declare, domConstruct, kernel){
 
 	// module:
 	//		dijit/_Container
-	// summary:
-	//		Mixin for widgets that contain a set of widget children.
 
 	return declare("dijit._Container", null, {
 		// summary:
-		//		Mixin for widgets that contain a set of widget children.
-		// description:
-		//		Use this mixin for widgets that needs to know about and
-		//		keep track of their widget children. Suitable for widgets like BorderContainer
-		//		and TabContainer which contain (only) a set of child widgets.
-		//
-		//		It's not suitable for widgets like ContentPane
-		//		which contains mixed HTML (plain DOM nodes in addition to widgets),
-		//		and where contained widgets are not necessarily directly below
-		//		this.containerNode.   In that case calls like addChild(node, position)
-		//		wouldn't make sense.
+		//		Mixin for widgets that contain HTML and/or a set of widget children.
 
 		buildRendering: function(){
 			this.inherited(arguments);
 			if(!this.containerNode){
-				// all widgets with descendants must set containerNode
-	 			this.containerNode = this.domNode;
+				// All widgets with descendants must set containerNode.
+				// NB: this code doesn't quite work right because for TabContainer it runs before
+				// _TemplatedMixin::buildRendering(), and thus
+				// sets this.containerNode to this.domNode, later to be overridden by the assignment in the template.
+				this.containerNode = this.domNode;
 			}
 		},
 
-		addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
+		addChild: function(/*dijit/_WidgetBase*/ widget, /*int?*/ insertIndex){
 			// summary:
 			//		Makes the given widget a child of this widget.
 			// description:
 			//		Inserts specified child widget's dom node as a child of this widget's
 			//		container node, and possibly does other processing (such as layout).
 
+			// I want to just call domConstruct.place(widget.domNode, this.containerNode, insertIndex), but the counting
+			// is thrown off by text nodes and comment nodes that show up when constructed by markup.
+			// In the future consider stripping those nodes on construction, either in the parser or this widget code.
 			var refNode = this.containerNode;
-			if(insertIndex && typeof insertIndex == "number"){
-				var children = this.getChildren();
-				if(children && children.length >= insertIndex){
-					refNode = children[insertIndex-1].domNode;
-					insertIndex = "after";
+			if(insertIndex > 0){
+				// Old-school way to get nth child; dojo.query would be easier but _Container was weened from dojo.query
+				// in #10087 to minimize download size.   Not sure if that's still and issue with new smaller dojo/query.
+				refNode = refNode.firstChild;
+				while(insertIndex > 0){
+					if(refNode.nodeType == 1){ insertIndex--; }
+					refNode = refNode.nextSibling;
+				}
+				if(refNode){
+					insertIndex = "before";
+				}else{
+					// to support addChild(child, n-1) where there are n children (should add child at end)
+					refNode = this.containerNode;
+					insertIndex = "last";
 				}
 			}
+
 			domConstruct.place(widget.domNode, refNode, insertIndex);
 
 			// If I've been started but the child widget hasn't been started,
@@ -62,7 +66,7 @@ define([
 			// summary:
 			//		Removes the passed widget instance from this widget but does
 			//		not destroy it.  You can also pass in an integer indicating
-			//		the index within the container to remove
+			//		the index within the container to remove (ie, removeChild(5) removes the sixth widget).
 
 			if(typeof widget == "number"){
 				widget = this.getChildren()[widget];
@@ -78,27 +82,25 @@ define([
 
 		hasChildren: function(){
 			// summary:
-			//		Returns true if widget has children, i.e. if this.containerNode contains something.
+			//		Returns true if widget has child widgets, i.e. if this.containerNode contains widgets.
 			return this.getChildren().length > 0;	// Boolean
 		},
 
-		_getSiblingOfChild: function(/*dijit._Widget*/ child, /*int*/ dir){
+		_getSiblingOfChild: function(/*dijit/_WidgetBase*/ child, /*int*/ dir){
 			// summary:
 			//		Get the next or previous widget sibling of child
 			// dir:
 			//		if 1, get the next sibling
 			//		if -1, get the previous sibling
 			// tags:
-			//      private
-			var node = child.domNode,
-				which = (dir>0 ? "nextSibling" : "previousSibling");
-			do{
-				node = node[which];
-			}while(node && (node.nodeType != 1 || !registry.byNode(node)));
-			return node && registry.byNode(node);	// dijit._Widget
+			//		private
+			kernel.deprecated(this.declaredClass+"::_getSiblingOfChild() is deprecated. Use _KeyNavMixin::_getNext() instead.", "", "2.0");
+			var children = this.getChildren(),
+				idx = array.indexOf(children, child);	// int
+			return children[idx + dir];
 		},
 
-		getIndexOfChild: function(/*dijit._Widget*/ child){
+		getIndexOfChild: function(/*dijit/_WidgetBase*/ child){
 			// summary:
 			//		Gets the index of the child in this container or -1 if not found
 			return array.indexOf(this.getChildren(), child);	// int
diff --git a/dijit/_CssStateMixin.js b/dijit/_CssStateMixin.js
index 820b2dd..db8470c 100644
--- a/dijit/_CssStateMixin.js
+++ b/dijit/_CssStateMixin.js
@@ -1,268 +1,363 @@
 define([
-	"dojo/touch",
 	"dojo/_base/array", // array.forEach array.map
-	"dojo/_base/declare",	// declare
+	"dojo/_base/declare", // declare
+	"dojo/dom", // dom.isDescendant()
 	"dojo/dom-class", // domClass.toggle
+	"dojo/has",
 	"dojo/_base/lang", // lang.hitch
-	"dojo/_base/window" // win.body
-], function(touch, array, declare, domClass, lang, win){
-
-// module:
-//		dijit/_CssStateMixin
-// summary:
-//		Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus
-//		state changes, and also higher-level state changes such becoming disabled or selected.
-
-return declare("dijit._CssStateMixin", [], {
-	// summary:
-	//		Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus
-	//		state changes, and also higher-level state changes such becoming disabled or selected.
-	//
-	// description:
-	//		By mixing this class into your widget, and setting the this.baseClass attribute, it will automatically
-	//		maintain CSS classes on the widget root node (this.domNode) depending on hover,
-	//		active, focus, etc. state.   Ex: with a baseClass of dijitButton, it will apply the classes
-	//		dijitButtonHovered and dijitButtonActive, as the user moves the mouse over the widget and clicks it.
-	//
-	//		It also sets CSS like dijitButtonDisabled based on widget semantic state.
-	//
-	//		By setting the cssStateNodes attribute, a widget can also track events on subnodes (like buttons
-	//		within the widget).
-
-	// cssStateNodes: [protected] Object
-	//		List of sub-nodes within the widget that need CSS classes applied on mouse hover/press and focus
-	//.
-	//		Each entry in the hash is a an attachpoint names (like "upArrowButton") mapped to a CSS class names
-	//		(like "dijitUpArrowButton"). Example:
-	//	|		{
-	//	|			"upArrowButton": "dijitUpArrowButton",
-	//	|			"downArrowButton": "dijitDownArrowButton"
-	//	|		}
-	//		The above will set the CSS class dijitUpArrowButton to the this.upArrowButton DOMNode when it
-	//		is hovered, etc.
-	cssStateNodes: {},
-
-	// hovering: [readonly] Boolean
-	//		True if cursor is over this widget
-	hovering: false,
-
-	// active: [readonly] Boolean
-	//		True if mouse was pressed while over this widget, and hasn't been released yet
-	active: false,
-
-	_applyAttributes: function(){
-		// This code would typically be in postCreate(), but putting in _applyAttributes() for
-		// performance: so the class changes happen before DOM is inserted into the document.
-		// Change back to postCreate() in 2.0.  See #11635.
-
-		this.inherited(arguments);
-
-		// Automatically monitor mouse events (essentially :hover and :active) on this.domNode
-		array.forEach(["onmouseenter", "onmouseleave", touch.press], function(e){
-			this.connect(this.domNode, e, "_cssMouseEvent");
-		}, this);
-
-		// Monitoring changes to disabled, readonly, etc. state, and update CSS class of root node
-		array.forEach(["disabled", "readOnly", "checked", "selected", "focused", "state", "hovering", "active"], function(attr){
-			this.watch(attr, lang.hitch(this, "_setStateClass"));
-		}, this);
-
-		// Events on sub nodes within the widget
-		for(var ap in this.cssStateNodes){
-			this._trackMouseState(this[ap], this.cssStateNodes[ap]);
-		}
-		// Set state initially; there's probably no hover/active/focus state but widget might be
-		// disabled/readonly/checked/selected so we want to set CSS classes for those conditions.
-		this._setStateClass();
-	},
-
-	_cssMouseEvent: function(/*Event*/ event){
-		// summary:
-		//	Sets hovering and active properties depending on mouse state,
-		//	which triggers _setStateClass() to set appropriate CSS classes for this.domNode.
-
-		if(!this.disabled){
-			switch(event.type){
-				case "mouseenter":
-				case "mouseover":	// generated on non-IE browsers even though we connected to mouseenter
-					this._set("hovering", true);
-					this._set("active", this._mouseDown);
-					break;
-
-				case "mouseleave":
-				case "mouseout":	// generated on non-IE browsers even though we connected to mouseleave
-					this._set("hovering", false);
-					this._set("active", false);
-					break;
+	"dojo/on",
+	"dojo/domReady",
+	"dojo/touch",
+	"dojo/_base/window", // win.body
+	"./a11yclick",
+	"./registry"
+], function(array, declare, dom, domClass, has, lang, on, domReady, touch, win, a11yclick, registry){
 
-				case "mousedown":
-				case "touchpress":
-					this._set("active", true);
-					this._mouseDown = true;
-					// Set a global event to handle mouseup, so it fires properly
-					// even if the cursor leaves this.domNode before the mouse up event.
-					// Alternately could set active=false on mouseout.
-					var mouseUpConnector = this.connect(win.body(), touch.release, function(){
-						this._mouseDown = false;
-						this._set("active", false);
-						this.disconnect(mouseUpConnector);
-					});
-					break;
-			}
-		}
-	},
+	// module:
+	//		dijit/_CssStateMixin
 
-	_setStateClass: function(){
+	var CssStateMixin = declare("dijit._CssStateMixin", [], {
 		// summary:
-		//		Update the visual state of the widget by setting the css classes on this.domNode
-		//		(or this.stateNode if defined) by combining this.baseClass with
-		//		various suffixes that represent the current widget state(s).
+		//		Mixin for widgets to set CSS classes on the widget DOM nodes depending on hover/mouse press/focus
+		//		state changes, and also higher-level state changes such becoming disabled or selected.
 		//
 		// description:
-		//		In the case where a widget has multiple
-		//		states, it sets the class based on all possible
-		//	 	combinations.  For example, an invalid form widget that is being hovered
-		//		will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
+		//		By mixing this class into your widget, and setting the this.baseClass attribute, it will automatically
+		//		maintain CSS classes on the widget root node (this.domNode) depending on hover,
+		//		active, focus, etc. state.   Ex: with a baseClass of dijitButton, it will apply the classes
+		//		dijitButtonHovered and dijitButtonActive, as the user moves the mouse over the widget and clicks it.
 		//
-		//		The widget may have one or more of the following states, determined
-		//		by this.state, this.checked, this.valid, and this.selected:
-		//			- Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
-		//			- Incomplete - ValidationTextBox sets this.state to "Incomplete" if the current input value is not finished yet
-		//			- Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
-		//			- Selected - ex: currently selected tab will have this.selected==true
+		//		It also sets CSS like dijitButtonDisabled based on widget semantic state.
 		//
-		//		In addition, it may have one or more of the following states,
-		//		based on this.disabled and flags set in _onMouse (this.active, this.hovering) and from focus manager (this.focused):
-		//			- Disabled	- if the widget is disabled
-		//			- Active		- if the mouse (or space/enter key?) is being pressed down
-		//			- Focused		- if the widget has focus
-		//			- Hover		- if the mouse is over the widget
-
-		// Compute new set of classes
-		var newStateClasses = this.baseClass.split(" ");
-
-		function multiply(modifier){
-			newStateClasses = newStateClasses.concat(array.map(newStateClasses, function(c){ return c+modifier; }), "dijit"+modifier);
-		}
+		//		By setting the cssStateNodes attribute, a widget can also track events on subnodes (like buttons
+		//		within the widget).
+
+		/*=====
+		 // cssStateNodes: [protected] Object
+		 //		Subclasses may define a cssStateNodes property that lists sub-nodes within the widget that
+		 //		need CSS classes applied on mouse hover/press and focus.
+		 //
+		 //		Each entry in this optional hash is a an attach-point name (like "upArrowButton") mapped to a CSS class name
+		 //		(like "dijitUpArrowButton"). Example:
+		 //	|		{
+		 //	|			"upArrowButton": "dijitUpArrowButton",
+		 //	|			"downArrowButton": "dijitDownArrowButton"
+		 //	|		}
+		 //		The above will set the CSS class dijitUpArrowButton to the this.upArrowButton DOMNode when it
+		 //		is hovered, etc.
+		 cssStateNodes: {},
+		 =====*/
+
+		// hovering: [readonly] Boolean
+		//		True if cursor is over this widget
+		hovering: false,
+
+		// active: [readonly] Boolean
+		//		True if mouse was pressed while over this widget, and hasn't been released yet
+		active: false,
+
+		_applyAttributes: function(){
+			// This code would typically be in postCreate(), but putting in _applyAttributes() for
+			// performance: so the class changes happen before DOM is inserted into the document.
+			// Change back to postCreate() in 2.0.  See #11635.
+
+			this.inherited(arguments);
+
+			// Monitoring changes to disabled, readonly, etc. state, and update CSS class of root node
+			array.forEach(["disabled", "readOnly", "checked", "selected", "focused", "state", "hovering", "active", "_opened"], function(attr){
+				this.watch(attr, lang.hitch(this, "_setStateClass"));
+			}, this);
+
+			// Track hover and active mouse events on widget root node, plus possibly on subnodes
+			for(var ap in this.cssStateNodes || {}){
+				this._trackMouseState(this[ap], this.cssStateNodes[ap]);
+			}
+			this._trackMouseState(this.domNode, this.baseClass);
+
+			// Set state initially; there's probably no hover/active/focus state but widget might be
+			// disabled/readonly/checked/selected so we want to set CSS classes for those conditions.
+			this._setStateClass();
+		},
+
+		_cssMouseEvent: function(/*Event*/ event){
+			// summary:
+			//		Handler for CSS event on this.domNode. Sets hovering and active properties depending on mouse state,
+			//		which triggers _setStateClass() to set appropriate CSS classes for this.domNode.
+
+			if(!this.disabled){
+				switch(event.type){
+					case "mouseover":
+					case "MSPointerOver":
+						this._set("hovering", true);
+						this._set("active", this._mouseDown);
+						break;
+					case "mouseout":
+					case "MSPointerOut":
+						this._set("hovering", false);
+						this._set("active", false);
+						break;
+					case "mousedown":
+					case "touchstart":
+					case "MSPointerDown":
+					case "keydown":
+						this._set("active", true);
+						break;
+					case "mouseup":
+					case "dojotouchend":
+					case "keyup":
+						this._set("active", false);
+						break;
+				}
+			}
+		},
+
+		_setStateClass: function(){
+			// summary:
+			//		Update the visual state of the widget by setting the css classes on this.domNode
+			//		(or this.stateNode if defined) by combining this.baseClass with
+			//		various suffixes that represent the current widget state(s).
+			//
+			// description:
+			//		In the case where a widget has multiple
+			//		states, it sets the class based on all possible
+			//		combinations.  For example, an invalid form widget that is being hovered
+			//		will be "dijitInput dijitInputInvalid dijitInputHover dijitInputInvalidHover".
+			//
+			//		The widget may have one or more of the following states, determined
+			//		by this.state, this.checked, this.valid, and this.selected:
+			//
+			//		- Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
+			//		- Incomplete - ValidationTextBox sets this.state to "Incomplete" if the current input value is not finished yet
+			//		- Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
+			//		- Selected - ex: currently selected tab will have this.selected==true
+			//
+			//		In addition, it may have one or more of the following states,
+			//		based on this.disabled and flags set in _onMouse (this.active, this.hovering) and from focus manager (this.focused):
+			//
+			//		- Disabled	- if the widget is disabled
+			//		- Active		- if the mouse (or space/enter key?) is being pressed down
+			//		- Focused		- if the widget has focus
+			//		- Hover		- if the mouse is over the widget
+
+			// Compute new set of classes
+			var newStateClasses = this.baseClass.split(" ");
+
+			function multiply(modifier){
+				newStateClasses = newStateClasses.concat(array.map(newStateClasses, function(c){
+					return c + modifier;
+				}), "dijit" + modifier);
+			}
 
-		if(!this.isLeftToRight()){
-			// For RTL mode we need to set an addition class like dijitTextBoxRtl.
-			multiply("Rtl");
-		}
+			if(!this.isLeftToRight()){
+				// For RTL mode we need to set an addition class like dijitTextBoxRtl.
+				multiply("Rtl");
+			}
 
-		var checkedState = this.checked == "mixed" ? "Mixed" : (this.checked ? "Checked" : "");
-		if(this.checked){
-			multiply(checkedState);
-		}
-		if(this.state){
-			multiply(this.state);
-		}
-		if(this.selected){
-			multiply("Selected");
-		}
+			var checkedState = this.checked == "mixed" ? "Mixed" : (this.checked ? "Checked" : "");
+			if(this.checked){
+				multiply(checkedState);
+			}
+			if(this.state){
+				multiply(this.state);
+			}
+			if(this.selected){
+				multiply("Selected");
+			}
+			if(this._opened){
+				multiply("Opened");
+			}
 
-		if(this.disabled){
-			multiply("Disabled");
-		}else if(this.readOnly){
-			multiply("ReadOnly");
-		}else{
-			if(this.active){
-				multiply("Active");
-			}else if(this.hovering){
-				multiply("Hover");
+			if(this.disabled){
+				multiply("Disabled");
+			}else if(this.readOnly){
+				multiply("ReadOnly");
+			}else{
+				if(this.active){
+					multiply("Active");
+				}else if(this.hovering){
+					multiply("Hover");
+				}
 			}
-		}
 
-		if(this.focused){
-			multiply("Focused");
-		}
+			if(this.focused){
+				multiply("Focused");
+			}
 
-		// Remove old state classes and add new ones.
-		// For performance concerns we only write into domNode.className once.
-		var tn = this.stateNode || this.domNode,
-			classHash = {};	// set of all classes (state and otherwise) for node
+			// Remove old state classes and add new ones.
+			// For performance concerns we only write into domNode.className once.
+			var tn = this.stateNode || this.domNode,
+				classHash = {};	// set of all classes (state and otherwise) for node
 
-		array.forEach(tn.className.split(" "), function(c){ classHash[c] = true; });
+			array.forEach(tn.className.split(" "), function(c){
+				classHash[c] = true;
+			});
 
-		if("_stateClasses" in this){
-			array.forEach(this._stateClasses, function(c){ delete classHash[c]; });
-		}
+			if("_stateClasses" in this){
+				array.forEach(this._stateClasses, function(c){
+					delete classHash[c];
+				});
+			}
+
+			array.forEach(newStateClasses, function(c){
+				classHash[c] = true;
+			});
+
+			var newClasses = [];
+			for(var c in classHash){
+				newClasses.push(c);
+			}
+			tn.className = newClasses.join(" ");
+
+			this._stateClasses = newStateClasses;
+		},
+
+		_subnodeCssMouseEvent: function(node, clazz, evt){
+			// summary:
+			//		Handler for hover/active mouse event on widget's subnode
+			if(this.disabled || this.readOnly){
+				return;
+			}
+
+			function hover(isHovering){
+				domClass.toggle(node, clazz + "Hover", isHovering);
+			}
+
+			function active(isActive){
+				domClass.toggle(node, clazz + "Active", isActive);
+			}
 
-		array.forEach(newStateClasses, function(c){ classHash[c] = true; });
+			function focused(isFocused){
+				domClass.toggle(node, clazz + "Focused", isFocused);
+			}
 
-		var newClasses = [];
-		for(var c in classHash){
-			newClasses.push(c);
+			switch(evt.type){
+				case "mouseover":
+				case "MSPointerOver":
+					hover(true);
+					break;
+				case "mouseout":
+				case "MSPointerOut":
+					hover(false);
+					active(false);
+					break;
+				case "mousedown":
+				case "touchstart":
+				case "MSPointerDown":
+				case "keydown":
+					active(true);
+					break;
+				case "mouseup":
+				case "MSPointerUp":
+				case "dojotouchend":
+				case "keyup":
+					active(false);
+					break;
+				case "focus":
+				case "focusin":
+					focused(true);
+					break;
+				case "blur":
+				case "focusout":
+					focused(false);
+					break;
+			}
+		},
+
+		_trackMouseState: function(/*DomNode*/ node, /*String*/ clazz){
+			// summary:
+			//		Track mouse/focus events on specified node and set CSS class on that node to indicate
+			//		current state.   Usually not called directly, but via cssStateNodes attribute.
+			// description:
+			//		Given class=foo, will set the following CSS class on the node
+			//
+			//		- fooActive: if the user is currently pressing down the mouse button while over the node
+			//		- fooHover: if the user is hovering the mouse over the node, but not pressing down a button
+			//		- fooFocus: if the node is focused
+			//
+			//		Note that it won't set any classes if the widget is disabled.
+			// node: DomNode
+			//		Should be a sub-node of the widget, not the top node (this.domNode), since the top node
+			//		is handled specially and automatically just by mixing in this class.
+			// clazz: String
+			//		CSS class name (ex: dijitSliderUpArrow)
+
+			// Flag for listener code below to call this._cssMouseEvent() or this._subnodeCssMouseEvent()
+			// when node is hovered/active
+			node._cssState = clazz;
 		}
-		tn.className = newClasses.join(" ");
+	});
 
-		this._stateClasses = newStateClasses;
-	},
+	domReady(function(){
+		// Document level listener to catch hover etc. events on widget root nodes and subnodes.
+		// Note that when the mouse is moved quickly, a single onmouseenter event could signal that multiple widgets
+		// have been hovered or unhovered (try test_Accordion.html)
 
-	_trackMouseState: function(/*DomNode*/ node, /*String*/ clazz){
-		// summary:
-		//		Track mouse/focus events on specified node and set CSS class on that node to indicate
-		//		current state.   Usually not called directly, but via cssStateNodes attribute.
-		// description:
-		//		Given class=foo, will set the following CSS class on the node
-		//			- fooActive: if the user is currently pressing down the mouse button while over the node
-		//			- fooHover: if the user is hovering the mouse over the node, but not pressing down a button
-		//			- fooFocus: if the node is focused
-		//
-		//		Note that it won't set any classes if the widget is disabled.
-		// node: DomNode
-		//		Should be a sub-node of the widget, not the top node (this.domNode), since the top node
-		//		is handled specially and automatically just by mixing in this class.
-		// clazz: String
-		//		CSS class name (ex: dijitSliderUpArrow).
-
-		// Current state of node (initially false)
-		// NB: setting specifically to false because domClass.toggle() needs true boolean as third arg
-		var hovering=false, active=false, focused=false;
-
-		var self = this,
-			cn = lang.hitch(this, "connect", node);
-
-		function setClass(){
-			var disabled = ("disabled" in self && self.disabled) || ("readonly" in self && self.readonly);
-			domClass.toggle(node, clazz+"Hover", hovering && !active && !disabled);
-			domClass.toggle(node, clazz+"Active", active && !disabled);
-			domClass.toggle(node, clazz+"Focused", focused && !disabled);
+		function pointerHandler(evt, target, relatedTarget){
+			// Handler for mouseover, mouseout, a11yclick.press and a11click.release events
+
+			// Poor man's event propagation.  Don't propagate event to ancestors of evt.relatedTarget,
+			// to avoid processing mouseout events moving from a widget's domNode to a descendant node;
+			// such events shouldn't be interpreted as a mouseleave on the widget.
+			if(relatedTarget && dom.isDescendant(relatedTarget, target)){
+				return;
+			}
+
+			for(var node = target; node && node != relatedTarget; node = node.parentNode){
+				// Process any nodes with _cssState property.   They are generally widget root nodes,
+				// but could also be sub-nodes within a widget
+				if(node._cssState){
+					var widget = registry.getEnclosingWidget(node);
+					if(widget){
+						if(node == widget.domNode){
+							// event on the widget's root node
+							widget._cssMouseEvent(evt);
+						}else{
+							// event on widget's sub-node
+							widget._subnodeCssMouseEvent(node, node._cssState, evt);
+						}
+					}
+				}
+			}
 		}
 
-		// Mouse
-		cn("onmouseenter", function(){
-			hovering = true;
-			setClass();
+		var body = win.body(), activeNode;
+
+		// Handle pointer related events (i.e. mouse or touch)
+		on(body, touch.over, function(evt){
+			// Using touch.over rather than mouseover mainly to ignore phantom mouse events on iOS.
+			pointerHandler(evt, evt.target, evt.relatedTarget);
 		});
-		cn("onmouseleave", function(){
-			hovering = false;
-			active = false;
-			setClass();
+		on(body, touch.out, function(evt){
+			// Using touch.out rather than mouseout mainly to ignore phantom mouse events on iOS.
+			pointerHandler(evt, evt.target, evt.relatedTarget);
 		});
-		cn(touch.press, function(){
-			active = true;
-			setClass();
+		on(body, a11yclick.press, function(evt){
+			// Save the a11yclick.press target to reference when the a11yclick.release comes.
+			activeNode = evt.target;
+			pointerHandler(evt, activeNode)
 		});
-		cn(touch.release, function(){
-			active = false;
-			setClass();
+		on(body, a11yclick.release, function(evt){
+			// The release event could come on a separate node than the press event, if for example user slid finger.
+			// Reference activeNode to reset the state of the node that got state set in the a11yclick.press handler.
+			pointerHandler(evt, activeNode);
+			activeNode = null;
 		});
 
-		// Focus
-		cn("onfocus", function(){
-			focused = true;
-			setClass();
-		});
-		cn("onblur", function(){
-			focused = false;
-			setClass();
+		// Track focus events on widget sub-nodes that have been registered via _trackMouseState().
+		// However, don't track focus events on the widget root nodes, because focus is tracked via the
+		// focus manager (and it's not really tracking focus, but rather tracking that focus is on one of the widget's
+		// nodes or a subwidget's node or a popup node, etc.)
+		// Remove for 2.0 (if focus CSS needed, just use :focus pseudo-selector).
+		on(body, "focusin, focusout", function(evt){
+			var node = evt.target;
+			if(node._cssState && !node.getAttribute("widgetId")){
+				var widget = registry.getEnclosingWidget(node);
+				if(widget){
+					widget._subnodeCssMouseEvent(node, node._cssState, evt);
+				}
+			}
 		});
+	});
 
-		// Just in case widget is enabled/disabled while it has focus/hover/active state.
-		// Maybe this is overkill.
-		this.watch("disabled", setClass);
-		this.watch("readOnly", setClass);
-	}
-});
+	return CssStateMixin;
 });
diff --git a/dijit/_DialogMixin.js b/dijit/_DialogMixin.js
index 94433cb..8d8388c 100644
--- a/dijit/_DialogMixin.js
+++ b/dijit/_DialogMixin.js
@@ -5,8 +5,6 @@ define([
 
 	// module:
 	//		dijit/_DialogMixin
-	// summary:
-	//		_DialogMixin provides functions useful to Dialog and TooltipDialog
 
 	return declare("dijit._DialogMixin", null, {
 		// summary:
@@ -28,22 +26,22 @@ define([
 
 		onCancel: function(){
 			// summary:
-			//	    Called when user has pressed the Dialog's cancel button, to notify container.
+			//		Called when user has pressed the Dialog's cancel button, to notify container.
 			// description:
-			//	    Developer shouldn't override or connect to this method;
+			//		Developer shouldn't override or connect to this method;
 			//		it's a private communication device between the TooltipDialog
-			//		and the thing that opened it (ex: `dijit.form.DropDownButton`)
+			//		and the thing that opened it (ex: `dijit/form/DropDownButton`)
 			// type:
 			//		protected
 		},
 
 		onExecute: function(){
 			// summary:
-			//	    Called when user has pressed the dialog's OK button, to notify container.
+			//		Called when user has pressed the dialog's OK button, to notify container.
 			// description:
-			//	    Developer shouldn't override or connect to this method;
+			//		Developer shouldn't override or connect to this method;
 			//		it's a private communication device between the TooltipDialog
-			//		and the thing that opened it (ex: `dijit.form.DropDownButton`)
+			//		and the thing that opened it (ex: `dijit/form/DropDownButton`)
 			// type:
 			//		protected
 		},
diff --git a/dijit/_FocusMixin.js b/dijit/_FocusMixin.js
index e327a44..473ebe7 100644
--- a/dijit/_FocusMixin.js
+++ b/dijit/_FocusMixin.js
@@ -5,15 +5,8 @@ define([
 	"dojo/_base/lang" // lang.extend
 ], function(focus, _WidgetBase, declare, lang){
 
-/*=====
-	var _WidgetBase = dijit._WidgetBase;
-=====*/
-
 	// module:
 	//		dijit/_FocusMixin
-	// summary:
-	//		Mixin to widget to provide _onFocus() and _onBlur() methods that
-	//		fire when a widget or it's descendants get/lose focus
 
 	// We don't know where _FocusMixin will occur in the inheritance chain, but we need the _onFocus()/_onBlur() below
 	// to be last in the inheritance chain, so mixin to _WidgetBase.
@@ -64,7 +57,7 @@ define([
 	return declare("dijit._FocusMixin", null, {
 		// summary:
 		//		Mixin to widget to provide _onFocus() and _onBlur() methods that
-		//		fire when a widget or it's descendants get/lose focus
+		//		fire when a widget or its descendants get/lose focus
 
 		// flag that I want _onFocus()/_onBlur() notifications from focus manager
 		_focusManager: focus
diff --git a/dijit/_HasDropDown.js b/dijit/_HasDropDown.js
index 7f59760..b1ee84c 100644
--- a/dijit/_HasDropDown.js
+++ b/dijit/_HasDropDown.js
@@ -1,33 +1,26 @@
 define([
 	"dojo/_base/declare", // declare
 	"dojo/_base/Deferred",
-	"dojo/_base/event", // event.stop
 	"dojo/dom", // dom.isDescendant
 	"dojo/dom-attr", // domAttr.set
 	"dojo/dom-class", // domClass.add domClass.contains domClass.remove
 	"dojo/dom-geometry", // domGeometry.marginBox domGeometry.position
 	"dojo/dom-style", // domStyle.set
-	"dojo/has",
+	"dojo/has", // has("touch")
 	"dojo/keys", // keys.DOWN_ARROW keys.ENTER keys.ESCAPE
 	"dojo/_base/lang", // lang.hitch lang.isFunction
+	"dojo/on",
 	"dojo/touch",
-	"dojo/_base/window", // win.doc
-	"dojo/window", // winUtils.getBox
-	"./registry",	// registry.byNode()
+	"./registry", // registry.byNode()
 	"./focus",
 	"./popup",
 	"./_FocusMixin"
-], function(declare, Deferred, event,dom, domAttr, domClass, domGeometry, domStyle, has, keys, lang, touch,
-			win, winUtils, registry, focus, popup, _FocusMixin){
+], function(declare, Deferred, dom, domAttr, domClass, domGeometry, domStyle, has, keys, lang, on, touch,
+			registry, focus, popup, _FocusMixin){
 
-/*=====
-	var _FocusMixin = dijit._FocusMixin;
-=====*/
 
 	// module:
 	//		dijit/_HasDropDown
-	// summary:
-	//		Mixin for widgets that need drop down ability.
 
 	return declare("dijit._HasDropDown", _FocusMixin, {
 		// summary:
@@ -47,7 +40,8 @@ define([
 		_arrowWrapperNode: null,
 
 		// _popupStateNode: [protected] DomNode
-		//		The node to set the popupActive class on.
+		//		The node to set the aria-expanded class on.
+		//		Also sets popupActive class but that will be removed in 2.0.
 		//		Can be set via a data-dojo-attach-point assignment.
 		//		If missing, then focusNode or _buttonNode (if focusNode is missing) will be used.
 		_popupStateNode: null,
@@ -66,7 +60,7 @@ define([
 		// autoWidth: [protected] Boolean
 		//		Set to true to make the drop down at least as wide as this
 		//		widget.  Set to false if the drop down should just be its
-		//		default width
+		//		default width.
 		autoWidth: true,
 
 		// forceWidth: [protected] Boolean
@@ -78,59 +72,66 @@ define([
 		//		The max height for our dropdown.
 		//		Any dropdown taller than this will have scrollbars.
 		//		Set to 0 for no max height, or -1 to limit height to available space in viewport
-		maxHeight: 0,
+		maxHeight: -1,
 
 		// dropDownPosition: [const] String[]
 		//		This variable controls the position of the drop down.
 		//		It's an array of strings with the following values:
 		//
-		//			* before: places drop down to the left of the target node/widget, or to the right in
-		//			  the case of RTL scripts like Hebrew and Arabic
-		//			* after: places drop down to the right of the target node/widget, or to the left in
-		//			  the case of RTL scripts like Hebrew and Arabic
-		//			* above: drop down goes above target node
-		//			* below: drop down goes below target node
+		//		- before: places drop down to the left of the target node/widget, or to the right in
+		//		  the case of RTL scripts like Hebrew and Arabic
+		//		- after: places drop down to the right of the target node/widget, or to the left in
+		//		  the case of RTL scripts like Hebrew and Arabic
+		//		- above: drop down goes above target node
+		//		- below: drop down goes below target node
 		//
 		//		The list is positions is tried, in order, until a position is found where the drop down fits
 		//		within the viewport.
 		//
-		dropDownPosition: ["below","above"],
+		dropDownPosition: ["below", "above"],
 
 		// _stopClickEvents: Boolean
 		//		When set to false, the click events will not be stopped, in
-		//		case you want to use them in your subwidget
+		//		case you want to use them in your subclass
 		_stopClickEvents: true,
 
 		_onDropDownMouseDown: function(/*Event*/ e){
 			// summary:
-			//		Callback when the user mousedown's on the arrow icon
-			if(this.disabled || this.readOnly){ return; }
+			//		Callback when the user mousedown/touchstart on the arrow icon.
+			if(this.disabled || this.readOnly){
+				return;
+			}
 
-			// Prevent default to stop things like text selection, but don't stop propogation, so that:
-			//		1. TimeTextBox etc. can focusthe <input> on mousedown
+			// Prevent default to stop things like text selection, but don't stop propagation, so that:
+			//		1. TimeTextBox etc. can focus the <input> on mousedown
 			//		2. dropDownButtonActive class applied by _CssStateMixin (on button depress)
 			//		3. user defined onMouseDown handler fires
 			e.preventDefault();
 
-			this._docHandler = this.connect(win.doc, touch.release, "_onDropDownMouseUp");
+			this._docHandler = this.own(on(this.ownerDocument, touch.release, lang.hitch(this, "_onDropDownMouseUp")))[0];
 
 			this.toggleDropDown();
 		},
 
 		_onDropDownMouseUp: function(/*Event?*/ e){
 			// summary:
-			//		Callback when the user lifts their mouse after mouse down on the arrow icon.
-			//		If the drop down is a simple menu and the mouse is over the menu, we execute it, otherwise, we focus our
+			//		Callback on mouseup/touchend after mousedown/touchstart on the arrow icon.
+			//		Note that this function is called regardless of what node the event occurred on (but only after
+			//		a mousedown/touchstart on the arrow).
+			//
+			//		If the drop down is a simple menu and the cursor is over the menu, we execute it, otherwise, we focus our
 			//		drop down widget.  If the event is missing, then we are not
 			//		a mouseup event.
 			//
 			//		This is useful for the common mouse movement pattern
-			//		with native browser <select> nodes:
-			//			1. mouse down on the select node (probably on the arrow)
-			//			2. move mouse to a menu item while holding down the mouse button
-			//			3. mouse up.  this selects the menu item as though the user had clicked it.
+			//		with native browser `<select>` nodes:
+			//
+			//		1. mouse down on the select node (probably on the arrow)
+			//		2. move mouse to a menu item while holding down the mouse button
+			//		3. mouse up.  this selects the menu item as though the user had clicked it.
 			if(e && this._docHandler){
-				this.disconnect(this._docHandler);
+				this._docHandler.remove();
+				this._docHandler = null;
 			}
 			var dropDown = this.dropDown, overMenu = false;
 
@@ -140,8 +141,7 @@ define([
 				// Find out if our target is somewhere in our dropdown widget,
 				// but not over our _buttonNode (the clickable node)
 				var c = domGeometry.position(this._buttonNode, true);
-				if(!(e.pageX >= c.x && e.pageX <= c.x + c.w) ||
-					!(e.pageY >= c.y && e.pageY <= c.y + c.h)){
+				if(!(e.pageX >= c.x && e.pageX <= c.x + c.w) || !(e.pageY >= c.y && e.pageY <= c.y + c.h)){
 					var t = e.target;
 					while(t && !overMenu){
 						if(domClass.contains(t, "dijitPopup")){
@@ -168,37 +168,26 @@ define([
 			if(this._opened){
 				if(dropDown.focus && dropDown.autoFocus !== false){
 					// Focus the dropdown widget - do it on a delay so that we
-					// don't steal our own focus.
-					window.setTimeout(lang.hitch(dropDown, "focus"), 1);
+					// don't steal back focus from the dropdown.
+					this._focusDropDownTimer = this.defer(function(){
+						dropDown.focus();
+						delete this._focusDropDownTimer;
+					});
 				}
 			}else{
 				// The drop down arrow icon probably can't receive focus, but widget itself should get focus.
-				// setTimeout() needed to make it work on IE (test DateTextBox)
-				setTimeout(lang.hitch(this, "focus"), 0);
-			}
-
-			if(has("ios")){
-				this._justGotMouseUp = true;
-				setTimeout(lang.hitch(this, function(){
-					this._justGotMouseUp = false;
-				}), 0);
+				// defer() needed to make it work on IE (test DateTextBox)
+				if(this.focus){
+					this.defer("focus");
+				}
 			}
 		},
 
 		_onDropDownClick: function(/*Event*/ e){
-			if(has("ios") && !this._justGotMouseUp){
-				// This branch fires on iPhone for ComboBox, because the button node is an <input> and doesn't
-				// generate touchstart/touchend events.   Pretend we just got a mouse down / mouse up.
-				// The if(has("ios") is necessary since IE and desktop safari get spurious onclick events
-				// when there are nested tables (specifically, clicking on a table that holds a dijit.form.Select,
-				// but not on the Select itself, causes an onclick event on the Select)
-				this._onDropDownMouseDown(e);
-				this._onDropDownMouseUp(e);
-			}
-
-			// The drop down was already opened on mousedown/keydown; just need to call stopEvent().
+			// The drop down was already opened on mousedown/keydown; just need to stop the event
 			if(this._stopClickEvents){
-				event.stop(e);
+				e.stopPropagation();
+				e.preventDefault();
 			}
 		},
 
@@ -211,26 +200,29 @@ define([
 			// Add a class to the "dijitDownArrowButton" type class to _buttonNode so theme can set direction of arrow
 			// based on where drop down will normally appear
 			var defaultPos = {
-					"after" : this.isLeftToRight() ? "Right" : "Left",
-					"before" : this.isLeftToRight() ? "Left" : "Right",
-					"above" : "Up",
-					"below" : "Down",
-					"left" : "Left",
-					"right" : "Right"
+				"after": this.isLeftToRight() ? "Right" : "Left",
+				"before": this.isLeftToRight() ? "Left" : "Right",
+				"above": "Up",
+				"below": "Down",
+				"left": "Left",
+				"right": "Right"
 			}[this.dropDownPosition[0]] || this.dropDownPosition[0] || "Down";
 			domClass.add(this._arrowWrapperNode || this._buttonNode, "dijit" + defaultPos + "ArrowButton");
 		},
 
 		postCreate: function(){
 			// summary:
-			//		set up nodes and connect our mouse and keypress events
+			//		set up nodes and connect our mouse and keyboard events
 
 			this.inherited(arguments);
 
-			this.connect(this._buttonNode, touch.press, "_onDropDownMouseDown");
-			this.connect(this._buttonNode, "onclick", "_onDropDownClick");
-			this.connect(this.focusNode, "onkeypress", "_onKey");
-			this.connect(this.focusNode, "onkeyup", "_onKeyUp");
+			var keyboardEventNode = this.focusNode || this.domNode;
+			this.own(
+				on(this._buttonNode, touch.press, lang.hitch(this, "_onDropDownMouseDown")),
+				on(this._buttonNode, "click", lang.hitch(this, "_onDropDownClick")),
+				on(keyboardEventNode, "keydown", lang.hitch(this, "_onKey")),
+				on(keyboardEventNode, "keyup", lang.hitch(this, "_onKeyUp"))
+			);
 		},
 
 		destroy: function(){
@@ -249,30 +241,35 @@ define([
 			// summary:
 			//		Callback when the user presses a key while focused on the button node
 
-			if(this.disabled || this.readOnly){ return; }
-
+			if(this.disabled || this.readOnly){
+				return;
+			}
 			var d = this.dropDown, target = e.target;
 			if(d && this._opened && d.handleKey){
 				if(d.handleKey(e) === false){
 					/* false return code means that the drop down handled the key */
-					event.stop(e);
+					e.stopPropagation();
+					e.preventDefault();
 					return;
 				}
 			}
-			if(d && this._opened && e.charOrCode == keys.ESCAPE){
+			if(d && this._opened && e.keyCode == keys.ESCAPE){
 				this.closeDropDown();
-				event.stop(e);
+				e.stopPropagation();
+				e.preventDefault();
 			}else if(!this._opened &&
-					(e.charOrCode == keys.DOWN_ARROW ||
-						( (e.charOrCode == keys.ENTER || e.charOrCode == " ") &&
-						  //ignore enter and space if the event is for a text input
-						  ((target.tagName || "").toLowerCase() !== 'input' ||
-						     (target.type && target.type.toLowerCase() !== 'text'))))){
+				(e.keyCode == keys.DOWN_ARROW ||
+					// ignore unmodified SPACE if _KeyNavMixin has active searching in progress
+					( (e.keyCode == keys.ENTER || (e.keyCode == keys.SPACE && (!this._searchTimer || (e.ctrlKey || e.altKey || e.metaKey)))) &&
+						//ignore enter and space if the event is for a text input
+						((target.tagName || "").toLowerCase() !== 'input' ||
+							(target.type && target.type.toLowerCase() !== 'text'))))){
 				// Toggle the drop down, but wait until keyup so that the drop down doesn't
 				// get a stray keyup event, or in the case of key-repeat (because user held
 				// down key for too long), stray keydown events
 				this._toggleOnKeyUp = true;
-				event.stop(e);
+				e.stopPropagation();
+				e.preventDefault();
 			}
 		},
 
@@ -282,7 +279,7 @@ define([
 				this.toggleDropDown();
 				var d = this.dropDown;	// drop down may not exist until toggleDropDown() call
 				if(d && d.focus){
-					setTimeout(lang.hitch(d, "focus"), 1);
+					this.defer(lang.hitch(d, "focus"), 1);
 				}
 			}
 		},
@@ -291,13 +288,10 @@ define([
 			// summary:
 			//		Called magically when focus has shifted away from this widget and it's dropdown
 
-			// Don't focus on button if the user has explicitly focused on something else (happens
-			// when user clicks another control causing the current popup to close)..
-			// But if focus is inside of the drop down then reset focus to me, because IE doesn't like
-			// it when you display:none a node with focus.
-			var focusMe = focus.curNode && this.dropDown && dom.isDescendant(focus.curNode, this.dropDown.domNode);
-
-			this.closeDropDown(focusMe);
+			// Close dropdown but don't focus my <input>.  User may have focused somewhere else (ex: clicked another
+			// input), and even if they just clicked a blank area of the screen, focusing my <input> will unwantedly
+			// popup the keyboard on mobile.
+			this.closeDropDown(false);
 
 			this.inherited(arguments);
 		},
@@ -356,11 +350,13 @@ define([
 			// tags:
 			//		protected
 
-			if(this.disabled || this.readOnly){ return; }
+			if(this.disabled || this.readOnly){
+				return;
+			}
 			if(!this._opened){
 				this.loadAndOpenDropDown();
 			}else{
-				this.closeDropDown();
+				this.closeDropDown(true);	// refocus button to avoid hiding node w/focus
 			}
 		},
 
@@ -369,7 +365,7 @@ define([
 			//		Opens the dropdown for this widget.   To be called only when this.dropDown
 			//		has been created and is ready to display (ie, it's data is loaded).
 			// returns:
-			//		return value of dijit.popup.open()
+			//		return value of dijit/popup.open()
 			// tags:
 			//		protected
 
@@ -378,91 +374,12 @@ define([
 				aroundNode = this._aroundNode || this.domNode,
 				self = this;
 
-			// Prepare our popup's height and honor maxHeight if it exists.
-
-			// TODO: isn't maxHeight dependent on the return value from dijit.popup.open(),
-			// ie, dependent on how much space is available (BK)
-
-			if(!this._preparedNode){
-				this._preparedNode = true;
-				// Check if we have explicitly set width and height on the dropdown widget dom node
-				if(ddNode.style.width){
-					this._explicitDDWidth = true;
-				}
-				if(ddNode.style.height){
-					this._explicitDDHeight = true;
-				}
-			}
-
-			// Code for resizing dropdown (height limitation, or increasing width to match my width)
-			if(this.maxHeight || this.forceWidth || this.autoWidth){
-				var myStyle = {
-					display: "",
-					visibility: "hidden"
-				};
-				if(!this._explicitDDWidth){
-					myStyle.width = "";
-				}
-				if(!this._explicitDDHeight){
-					myStyle.height = "";
-				}
-				domStyle.set(ddNode, myStyle);
-
-				// Figure out maximum height allowed (if there is a height restriction)
-				var maxHeight = this.maxHeight;
-				if(maxHeight == -1){
-					// limit height to space available in viewport either above or below my domNode
-					// (whichever side has more room)
-					var viewport = winUtils.getBox(),
-						position = domGeometry.position(aroundNode, false);
-					maxHeight = Math.floor(Math.max(position.y, viewport.h - (position.y + position.h)));
-				}
-
-				// Attach dropDown to DOM and make make visibility:hidden rather than display:none
-				// so we call startup() and also get the size
-				popup.moveOffScreen(dropDown);
-
-				if(dropDown.startup && !dropDown._started){
-					dropDown.startup(); // this has to be done after being added to the DOM
-				}
-				// Get size of drop down, and determine if vertical scroll bar needed
-				var mb = domGeometry.getMarginSize(ddNode);
-				var overHeight = (maxHeight && mb.h > maxHeight);
-				domStyle.set(ddNode, {
-					overflowX: "hidden",
-					overflowY: overHeight ? "auto" : "hidden"
-				});
-				if(overHeight){
-					mb.h = maxHeight;
-					if("w" in mb){
-						mb.w += 16;	// room for vertical scrollbar
-					}
-				}else{
-					delete mb.h;
-				}
-
-				// Adjust dropdown width to match or be larger than my width
-				if(this.forceWidth){
-					mb.w = aroundNode.offsetWidth;
-				}else if(this.autoWidth){
-					mb.w = Math.max(mb.w, aroundNode.offsetWidth);
-				}else{
-					delete mb.w;
-				}
-
-				// And finally, resize the dropdown to calculated height and width
-				if(lang.isFunction(dropDown.resize)){
-					dropDown.resize(mb);
-				}else{
-					domGeometry.setMarginBox(ddNode, mb);
-				}
-			}
-
 			var retVal = popup.open({
 				parent: this,
 				popup: dropDown,
 				around: aroundNode,
 				orient: this.dropDownPosition,
+				maxHeight: this.maxHeight,
 				onExecute: function(){
 					self.closeDropDown(true);
 				},
@@ -472,14 +389,35 @@ define([
 				onClose: function(){
 					domAttr.set(self._popupStateNode, "popupActive", false);
 					domClass.remove(self._popupStateNode, "dijitHasDropDownOpen");
-					self._opened = false;
+					self._set("_opened", false);	// use set() because _CssStateMixin is watching
 				}
 			});
+
+			// Set width of drop down if necessary, so that dropdown width + width of scrollbar (from popup wrapper)
+			// matches width of aroundNode
+			if(this.forceWidth || (this.autoWidth && aroundNode.offsetWidth > dropDown._popupWrapper.offsetWidth)){
+				var resizeArgs = {
+					w: aroundNode.offsetWidth - (dropDown._popupWrapper.offsetWidth - dropDown.domNode.offsetWidth)
+				};
+				if(lang.isFunction(dropDown.resize)){
+					dropDown.resize(resizeArgs);
+				}else{
+					domGeometry.setMarginBox(ddNode, resizeArgs);
+				}
+			}
+
 			domAttr.set(this._popupStateNode, "popupActive", "true");
-			domClass.add(self._popupStateNode, "dijitHasDropDownOpen");
-			this._opened=true;
+			domClass.add(this._popupStateNode, "dijitHasDropDownOpen");
+			this._set("_opened", true);	// use set() because _CssStateMixin is watching
+
+			this._popupStateNode.setAttribute("aria-expanded", "true");
+			this._popupStateNode.setAttribute("aria-owns", dropDown.id);
+
+			// Set aria-labelledby on dropdown if it's not already set to something more meaningful
+			if(ddNode.getAttribute("role") !== "presentation" && !ddNode.getAttribute("aria-labelledby")){
+				ddNode.setAttribute("aria-labelledby", this.id);
+			}
 
-			// TODO: set this.checked and call setStateClass(), to affect button look while drop down is shown
 			return retVal;
 		},
 
@@ -491,8 +429,16 @@ define([
 			// tags:
 			//		protected
 
+			if(this._focusDropDownTimer){
+				this._focusDropDownTimer.remove();
+				delete this._focusDropDownTimer;
+			}
+
 			if(this._opened){
-				if(focus){ this.focus(); }
+				this._popupStateNode.setAttribute("aria-expanded", "false");
+				if(focus){
+					this.focus();
+				}
 				popup.close(this.dropDown);
 				this._opened = false;
 			}
diff --git a/dijit/_KeyNavContainer.js b/dijit/_KeyNavContainer.js
index 647653c..e354e7f 100644
--- a/dijit/_KeyNavContainer.js
+++ b/dijit/_KeyNavContainer.js
@@ -1,69 +1,53 @@
 define([
-	"dojo/_base/kernel", // kernel.deprecated
-	"./_Container",
-	"./_FocusMixin",
 	"dojo/_base/array", // array.forEach
-	"dojo/keys", // keys.END keys.HOME
 	"dojo/_base/declare", // declare
-	"dojo/_base/event", // event.stop
 	"dojo/dom-attr", // domAttr.set
-	"dojo/_base/lang" // lang.hitch
-], function(kernel, _Container, _FocusMixin, array, keys, declare, event, domAttr, lang){
+	"dojo/_base/kernel", // kernel.deprecated
+	"dojo/keys", // keys.END keys.HOME
+	"dojo/_base/lang", // lang.hitch
+	"./registry",
+	"./_Container",
+	"./_FocusMixin",
+	"./_KeyNavMixin"
+], function(array, declare, domAttr, kernel, keys, lang, registry, _Container, _FocusMixin, _KeyNavMixin){
 
-/*=====
-	var _FocusMixin = dijit._FocusMixin;
-	var _Container = dijit._Container;
-=====*/
 
 	// module:
 	//		dijit/_KeyNavContainer
-	// summary:
-	//		A _Container with keyboard navigation of its children.
-
-	return declare("dijit._KeyNavContainer", [_FocusMixin, _Container], {
 
+	return declare("dijit._KeyNavContainer", [_FocusMixin, _KeyNavMixin, _Container], {
 		// summary:
 		//		A _Container with keyboard navigation of its children.
 		// description:
-		//		To use this mixin, call connectKeyNavHandlers() in
-		//		postCreate().
-		//		It provides normalized keyboard and focusing code for Container
-		//		widgets.
-
-/*=====
-		// focusedChild: [protected] Widget
-		//		The currently focused child widget, or null if there isn't one
-		focusedChild: null,
-=====*/
-
-		// tabIndex: Integer
-		//		Tab index of the container; same as HTML tabIndex attribute.
-		//		Note then when user tabs into the container, focus is immediately
-		//		moved to the first item in the container.
-		tabIndex: "0",
+		//		Provides normalized keyboard and focusing code for Container widgets.
+		//		To use this mixin, call connectKeyNavHandlers() in postCreate().
+		//		Also, child widgets must implement a focus() method.
 
 		connectKeyNavHandlers: function(/*keys[]*/ prevKeyCodes, /*keys[]*/ nextKeyCodes){
 			// summary:
-			//		Call in postCreate() to attach the keyboard handlers
-			//		to the container.
-			// preKeyCodes: keys[]
+			//		Deprecated.  You can call this in postCreate() to attach the keyboard handlers to the container,
+			//		but the preferred method is to override _onLeftArrow() and _onRightArrow(), or
+			//		_onUpArrow() and _onDownArrow(), to call focusPrev() and focusNext().
+			// prevKeyCodes: keys[]
 			//		Key codes for navigating to the previous child.
 			// nextKeyCodes: keys[]
 			//		Key codes for navigating to the next child.
 			// tags:
 			//		protected
 
-			// TODO: call this automatically from my own postCreate()
+			// TODO: remove for 2.0, and make subclasses override _onLeftArrow, _onRightArrow etc. instead.
 
 			var keyCodes = (this._keyNavCodes = {});
 			var prev = lang.hitch(this, "focusPrev");
 			var next = lang.hitch(this, "focusNext");
-			array.forEach(prevKeyCodes, function(code){ keyCodes[code] = prev; });
-			array.forEach(nextKeyCodes, function(code){ keyCodes[code] = next; });
+			array.forEach(prevKeyCodes, function(code){
+				keyCodes[code] = prev;
+			});
+			array.forEach(nextKeyCodes, function(code){
+				keyCodes[code] = next;
+			});
 			keyCodes[keys.HOME] = lang.hitch(this, "focusFirstChild");
 			keyCodes[keys.END] = lang.hitch(this, "focusLastChild");
-			this.connect(this.domNode, "onkeypress", "_onContainerKeypress");
-			this.connect(this.domNode, "onfocus", "_onContainerFocus");
 		},
 
 		startupKeyNavChildren: function(){
@@ -75,31 +59,44 @@ define([
 			array.forEach(this.getChildren(), lang.hitch(this, "_startupChild"));
 		},
 
-		addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
+		addChild: function(/*dijit/_WidgetBase*/ widget, /*int?*/ insertIndex){
 			this.inherited(arguments);
 			this._startupChild(widget);
 		},
 
-		focus: function(){
+		_startupChild: function(/*dijit/_WidgetBase*/ widget){
 			// summary:
-			//		Default focus() implementation: focus the first child.
-			this.focusFirstChild();
+			//		Setup for each child widget.
+			// description:
+			//		Sets tabIndex=-1 on each child, so that the tab key will
+			//		leave the container rather than visiting each child.
+			//
+			//		Note: if you add children by a different method than addChild(), then need to call this manually
+			//		or at least make sure the child's tabIndex is -1.
+			//
+			//		Note: see also _LayoutWidget.setupChild(), which is also called for each child widget.
+			// tags:
+			//		private
+
+			widget.set("tabIndex", "-1");
 		},
 
-		focusFirstChild: function(){
+		_getFirst: function(){
 			// summary:
-			//		Focus the first focusable child in the container.
+			//		Returns the first child.
 			// tags:
-			//		protected
-			this.focusChild(this._getFirstFocusableChild());
+			//		abstract extension
+			var children = this.getChildren();
+			return children.length ? children[0] : null;
 		},
 
-		focusLastChild: function(){
+		_getLast: function(){
 			// summary:
-			//		Focus the last focusable child in the container.
+			//		Returns the last descendant.
 			// tags:
-			//		protected
-			this.focusChild(this._getLastFocusableChild());
+			//		abstract extension
+			var children = this.getChildren();
+			return children.length ? children[children.length - 1] : null;
 		},
 
 		focusNext: function(){
@@ -119,146 +116,13 @@ define([
 			this.focusChild(this._getNextFocusableChild(this.focusedChild, -1), true);
 		},
 
-		focusChild: function(/*dijit._Widget*/ widget, /*Boolean*/ last){
-			// summary:
-			//		Focus specified child widget.
-			// widget:
-			//		Reference to container's child widget
-			// last:
-			//		If true and if widget has multiple focusable nodes, focus the
-			//		last one instead of the first one
-			// tags:
-			//		protected
-
-			if(!widget){ return; }
-
-			if(this.focusedChild && widget !== this.focusedChild){
-				this._onChildBlur(this.focusedChild);	// used by _MenuBase
-			}
-			widget.set("tabIndex", this.tabIndex);	// for IE focus outline to appear, must set tabIndex before focs
-			widget.focus(last ? "end" : "start");
-			this._set("focusedChild", widget);
-		},
-
-		_startupChild: function(/*dijit._Widget*/ widget){
-			// summary:
-			//		Setup for each child widget
-			// description:
-			//		Sets tabIndex=-1 on each child, so that the tab key will
-			//		leave the container rather than visiting each child.
-			// tags:
-			//		private
-
-			widget.set("tabIndex", "-1");
-
-			this.connect(widget, "_onFocus", function(){
-				// Set valid tabIndex so tabbing away from widget goes to right place, see #10272
-				widget.set("tabIndex", this.tabIndex);
-			});
-			this.connect(widget, "_onBlur", function(){
-				widget.set("tabIndex", "-1");
-			});
-		},
-
-		_onContainerFocus: function(evt){
-			// summary:
-			//		Handler for when the container gets focus
-			// description:
-			//		Initially the container itself has a tabIndex, but when it gets
-			//		focus, switch focus to first child...
-			// tags:
-			//		private
-
-			// Note that we can't use _onFocus() because switching focus from the
-			// _onFocus() handler confuses the focus.js code
-			// (because it causes _onFocusNode() to be called recursively)
-			// Also, _onFocus() would fire when focus went directly to a child widget due to mouse click.
-
-			// Ignore spurious focus events:
-			//	1. focus on a child widget bubbles on FF
-			//	2. on IE, clicking the scrollbar of a select dropdown moves focus from the focused child item to me
-			if(evt.target !== this.domNode || this.focusedChild){ return; }
-
-			this.focusFirstChild();
-
-			// and then set the container's tabIndex to -1,
-			// (don't remove as that breaks Safari 4)
-			// so that tab or shift-tab will go to the fields after/before
-			// the container, rather than the container itself
-			domAttr.set(this.domNode, "tabIndex", "-1");
-		},
-
-		_onBlur: function(evt){
-			// When focus is moved away the container, and its descendant (popup) widgets,
-			// then restore the container's tabIndex so that user can tab to it again.
-			// Note that using _onBlur() so that this doesn't happen when focus is shifted
-			// to one of my child widgets (typically a popup)
-			if(this.tabIndex){
-				domAttr.set(this.domNode, "tabIndex", this.tabIndex);
-			}
-			this.focusedChild = null;
-			this.inherited(arguments);
-		},
+		childSelector: function(/*DOMNode*/ node){
+			// Implement _KeyNavMixin.childSelector, to identify focusable child nodes.
+			// If we allowed a dojo/query dependency from this module this could more simply be a string "> *"
+			// instead of this function.
 
-		_onContainerKeypress: function(evt){
-			// summary:
-			//		When a key is pressed, if it's an arrow key etc. then
-			//		it's handled here.
-			// tags:
-			//		private
-			if(evt.ctrlKey || evt.altKey){ return; }
-			var func = this._keyNavCodes[evt.charOrCode];
-			if(func){
-				func();
-				event.stop(evt);
-			}
-		},
-
-		_onChildBlur: function(/*dijit._Widget*/ /*===== widget =====*/){
-			// summary:
-			//		Called when focus leaves a child widget to go
-			//		to a sibling widget.
-			//		Used by MenuBase.js (TODO: move code there)
-			// tags:
-			//		protected
-		},
-
-		_getFirstFocusableChild: function(){
-			// summary:
-			//		Returns first child that can be focused
-			return this._getNextFocusableChild(null, 1);	// dijit._Widget
-		},
-
-		_getLastFocusableChild: function(){
-			// summary:
-			//		Returns last child that can be focused
-			return this._getNextFocusableChild(null, -1);	// dijit._Widget
-		},
-
-		_getNextFocusableChild: function(child, dir){
-			// summary:
-			//		Returns the next or previous focusable child, compared
-			//		to "child"
-			// child: Widget
-			//		The current widget
-			// dir: Integer
-			//		* 1 = after
-			//		* -1 = before
-			if(child){
-				child = this._getSiblingOfChild(child, dir);
-			}
-			var children = this.getChildren();
-			for(var i=0; i < children.length; i++){
-				if(!child){
-					child = children[(dir>0) ? 0 : (children.length-1)];
-				}
-				if(child.isFocusable()){
-					return child;	// dijit._Widget
-				}
-				child = this._getSiblingOfChild(child, dir);
-			}
-			// no focusable child found
-			return null;	// dijit._Widget
+			var node = registry.byNode(node);
+			return node && node.getParent() == this;
 		}
 	});
 });
diff --git a/dijit/_KeyNavMixin.js b/dijit/_KeyNavMixin.js
new file mode 100644
index 0000000..d692898
--- /dev/null
+++ b/dijit/_KeyNavMixin.js
@@ -0,0 +1,478 @@
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/declare", // declare
+	"dojo/dom-attr", // domAttr.set
+	"dojo/keys", // keys.END keys.HOME, keys.LEFT_ARROW etc.
+	"dojo/_base/lang", // lang.hitch
+	"dojo/on",
+	"dijit/registry",
+	"dijit/_FocusMixin"        // to make _onBlur() work
+], function(array, declare, domAttr, keys, lang, on, registry, _FocusMixin){
+
+	// module:
+	//		dijit/_KeyNavMixin
+
+	return declare("dijit._KeyNavMixin", _FocusMixin, {
+		// summary:
+		//		A mixin to allow arrow key and letter key navigation of child or descendant widgets.
+		//		It can be used by dijit/_Container based widgets with a flat list of children,
+		//		or more complex widgets like dijit/Tree.
+		//
+		//		To use this mixin, the subclass must:
+		//
+		//			- Implement  _getNext(), _getFirst(), _getLast(), _onLeftArrow(), _onRightArrow()
+		//			  _onDownArrow(), _onUpArrow() methods to handle home/end/left/right/up/down keystrokes.
+		//			  Next and previous in this context refer to a linear ordering of the descendants used
+		//			  by letter key search.
+		//			- Set all descendants' initial tabIndex to "-1"; both initial descendants and any
+		//			  descendants added later, by for example addChild()
+		//			- Define childSelector to a function or string that identifies focusable descendant widgets
+		//
+		//		Also, child widgets must implement a focus() method.
+
+		/*=====
+		 // focusedChild: [protected readonly] Widget
+		 //		The currently focused child widget, or null if there isn't one
+		 focusedChild: null,
+
+		 // _keyNavCodes: Object
+		 //		Hash mapping key code (arrow keys and home/end key) to functions to handle those keys.
+		 //		Usually not used directly, as subclasses can instead override _onLeftArrow() etc.
+		 _keyNavCodes: {},
+		 =====*/
+
+		// tabIndex: String
+		//		Tab index of the container; same as HTML tabIndex attribute.
+		//		Note then when user tabs into the container, focus is immediately
+		//		moved to the first item in the container.
+		tabIndex: "0",
+
+		// childSelector: [protected abstract] Function||String
+		//		Selector (passed to on.selector()) used to identify what to treat as a child widget.   Used to monitor
+		//		focus events and set this.focusedChild.   Must be set by implementing class.   If this is a string
+		//		(ex: "> *") then the implementing class must require dojo/query.
+		childSelector: null,
+
+		postCreate: function(){
+			this.inherited(arguments);
+
+			// Set tabIndex on this.domNode.  Will be automatic after #7381 is fixed.
+			domAttr.set(this.domNode, "tabIndex", this.tabIndex);
+
+			if(!this._keyNavCodes){
+				var keyCodes = this._keyNavCodes = {};
+				keyCodes[keys.HOME] = lang.hitch(this, "focusFirstChild");
+				keyCodes[keys.END] = lang.hitch(this, "focusLastChild");
+				keyCodes[this.isLeftToRight() ? keys.LEFT_ARROW : keys.RIGHT_ARROW] = lang.hitch(this, "_onLeftArrow");
+				keyCodes[this.isLeftToRight() ? keys.RIGHT_ARROW : keys.LEFT_ARROW] = lang.hitch(this, "_onRightArrow");
+				keyCodes[keys.UP_ARROW] = lang.hitch(this, "_onUpArrow");
+				keyCodes[keys.DOWN_ARROW] = lang.hitch(this, "_onDownArrow");
+			}
+
+			var self = this,
+				childSelector = typeof this.childSelector == "string"
+					? this.childSelector
+					: lang.hitch(this, "childSelector");
+			this.own(
+				on(this.domNode, "keypress", lang.hitch(this, "_onContainerKeypress")),
+				on(this.domNode, "keydown", lang.hitch(this, "_onContainerKeydown")),
+				on(this.domNode, "focus", lang.hitch(this, "_onContainerFocus")),
+				on(this.containerNode, on.selector(childSelector, "focusin"), function(evt){
+					self._onChildFocus(registry.getEnclosingWidget(this), evt);
+				})
+			);
+		},
+
+		_onLeftArrow: function(){
+			// summary:
+			//		Called on left arrow key, or right arrow key if widget is in RTL mode.
+			//		Should go back to the previous child in horizontal container widgets like Toolbar.
+			// tags:
+			//		extension
+		},
+
+		_onRightArrow: function(){
+			// summary:
+			//		Called on right arrow key, or left arrow key if widget is in RTL mode.
+			//		Should go to the next child in horizontal container widgets like Toolbar.
+			// tags:
+			//		extension
+		},
+
+		_onUpArrow: function(){
+			// summary:
+			//		Called on up arrow key. Should go to the previous child in vertical container widgets like Menu.
+			// tags:
+			//		extension
+		},
+
+		_onDownArrow: function(){
+			// summary:
+			//		Called on down arrow key. Should go to the next child in vertical container widgets like Menu.
+			// tags:
+			//		extension
+		},
+
+		focus: function(){
+			// summary:
+			//		Default focus() implementation: focus the first child.
+			this.focusFirstChild();
+		},
+
+		_getFirstFocusableChild: function(){
+			// summary:
+			//		Returns first child that can be focused.
+
+			// Leverage _getNextFocusableChild() to skip disabled children
+			return this._getNextFocusableChild(null, 1);	// dijit/_WidgetBase
+		},
+
+		_getLastFocusableChild: function(){
+			// summary:
+			//		Returns last child that can be focused.
+
+			// Leverage _getNextFocusableChild() to skip disabled children
+			return this._getNextFocusableChild(null, -1);	// dijit/_WidgetBase
+		},
+
+		focusFirstChild: function(){
+			// summary:
+			//		Focus the first focusable child in the container.
+			// tags:
+			//		protected
+
+			this.focusChild(this._getFirstFocusableChild());
+		},
+
+		focusLastChild: function(){
+			// summary:
+			//		Focus the last focusable child in the container.
+			// tags:
+			//		protected
+
+			this.focusChild(this._getLastFocusableChild());
+		},
+
+		focusChild: function(/*dijit/_WidgetBase*/ widget, /*Boolean*/ last){
+			// summary:
+			//		Focus specified child widget.
+			// widget:
+			//		Reference to container's child widget
+			// last:
+			//		If true and if widget has multiple focusable nodes, focus the
+			//		last one instead of the first one
+			// tags:
+			//		protected
+
+			if(!widget){
+				return;
+			}
+
+			if(this.focusedChild && widget !== this.focusedChild){
+				this._onChildBlur(this.focusedChild);	// used to be used by _MenuBase
+			}
+			widget.set("tabIndex", this.tabIndex);	// for IE focus outline to appear, must set tabIndex before focus
+			widget.focus(last ? "end" : "start");
+
+			// Don't set focusedChild here, because the focus event should trigger a call to _onChildFocus(), which will
+			// set it.   More importantly, _onChildFocus(), which may be executed asynchronously (after this function
+			// returns) needs to know the old focusedChild to set its tabIndex to -1.
+		},
+
+		_onContainerFocus: function(evt){
+			// summary:
+			//		Handler for when the container itself gets focus.
+			// description:
+			//		Initially the container itself has a tabIndex, but when it gets
+			//		focus, switch focus to first child...
+			// tags:
+			//		private
+
+			// Note that we can't use _onFocus() because switching focus from the
+			// _onFocus() handler confuses the focus.js code
+			// (because it causes _onFocusNode() to be called recursively).
+			// Also, _onFocus() would fire when focus went directly to a child widget due to mouse click.
+
+			// Ignore spurious focus events:
+			//	1. focus on a child widget bubbles on FF
+			//	2. on IE, clicking the scrollbar of a select dropdown moves focus from the focused child item to me
+			if(evt.target !== this.domNode || this.focusedChild){
+				return;
+			}
+
+			this.focus();
+		},
+
+		_onFocus: function(){
+			// When the container gets focus by being tabbed into, or a descendant gets focus by being clicked,
+			// set the container's tabIndex to -1 (don't remove as that breaks Safari 4) so that tab or shift-tab
+			// will go to the fields after/before the container, rather than the container itself
+			domAttr.set(this.domNode, "tabIndex", "-1");
+
+			this.inherited(arguments);
+		},
+
+		_onBlur: function(evt){
+			// When focus is moved away the container, and its descendant (popup) widgets,
+			// then restore the container's tabIndex so that user can tab to it again.
+			// Note that using _onBlur() so that this doesn't happen when focus is shifted
+			// to one of my child widgets (typically a popup)
+
+			// TODO: for 2.0 consider changing this to blur whenever the container blurs, to be truthful that there is
+			// no focused child at that time.
+
+			domAttr.set(this.domNode, "tabIndex", this.tabIndex);
+			if(this.focusedChild){
+				this.focusedChild.set("tabIndex", "-1");
+				this.lastFocusedChild = this.focusedChild;
+				this._set("focusedChild", null);
+			}
+			this.inherited(arguments);
+		},
+
+		_onChildFocus: function(/*dijit/_WidgetBase*/ child){
+			// summary:
+			//		Called when a child widget gets focus, either by user clicking
+			//		it, or programatically by arrow key handling code.
+			// description:
+			//		It marks that the current node is the selected one, and the previously
+			//		selected node no longer is.
+
+			if(child && child != this.focusedChild){
+				if(this.focusedChild && !this.focusedChild._destroyed){
+					// mark that the previously focusable node is no longer focusable
+					this.focusedChild.set("tabIndex", "-1");
+				}
+
+				// mark that the new node is the currently selected one
+				child.set("tabIndex", this.tabIndex);
+				this.lastFocused = child;		// back-compat for Tree, remove for 2.0
+				this._set("focusedChild", child);
+			}
+		},
+
+		_searchString: "",
+		// multiCharSearchDuration: Number
+		//		If multiple characters are typed where each keystroke happens within
+		//		multiCharSearchDuration of the previous keystroke,
+		//		search for nodes matching all the keystrokes.
+		//
+		//		For example, typing "ab" will search for entries starting with
+		//		"ab" unless the delay between "a" and "b" is greater than multiCharSearchDuration.
+		multiCharSearchDuration: 1000,
+
+		onKeyboardSearch: function(/*dijit/_WidgetBase*/ item, /*Event*/ evt, /*String*/ searchString, /*Number*/ numMatches){
+			// summary:
+			//		When a key is pressed that matches a child item,
+			//		this method is called so that a widget can take appropriate action is necessary.
+			// tags:
+			//		protected
+			if(item){
+				this.focusChild(item);
+			}
+		},
+
+		_keyboardSearchCompare: function(/*dijit/_WidgetBase*/ item, /*String*/ searchString){
+			// summary:
+			//		Compares the searchString to the widget's text label, returning:
+			//
+			//			* -1: a high priority match  and stop searching
+			//		 	* 0: not a match
+			//		 	* 1: a match but keep looking for a higher priority match
+			// tags:
+			//		private
+
+			var element = item.domNode,
+				text = item.label || (element.focusNode ? element.focusNode.label : '') || element.innerText || element.textContent || "",
+				currentString = text.replace(/^\s+/, '').substr(0, searchString.length).toLowerCase();
+
+			return (!!searchString.length && currentString == searchString) ? -1 : 0; // stop searching after first match by default
+		},
+
+		_onContainerKeydown: function(evt){
+			// summary:
+			//		When a key is pressed, if it's an arrow key etc. then it's handled here.
+			// tags:
+			//		private
+
+			var func = this._keyNavCodes[evt.keyCode];
+			if(func){
+				func(evt, this.focusedChild);
+				evt.stopPropagation();
+				evt.preventDefault();
+				this._searchString = ''; // so a DOWN_ARROW b doesn't search for ab
+			}else if(evt.keyCode == keys.SPACE && this._searchTimer && !(evt.ctrlKey || evt.altKey || evt.metaKey)){
+				evt.stopImmediatePropagation(); // stop a11yclick and _HasDropdown from seeing SPACE if we're doing keyboard searching
+				evt.preventDefault(); // stop IE from scrolling, and most browsers (except FF) from sending keypress
+				this._keyboardSearch(evt, ' ');
+			}
+		},
+
+		_onContainerKeypress: function(evt){
+			// summary:
+			//		When a printable key is pressed, it's handled here, searching by letter.
+			// tags:
+			//		private
+
+			if(evt.charCode < keys.SPACE || evt.ctrlKey || evt.altKey || evt.metaKey ||
+					(evt.charCode == keys.SPACE && this._searchTimer)){
+				// Avoid duplicate events on firefox (ex: arrow key that will be handled by keydown handler),
+				// and also control sequences like CMD-Q
+				return;
+			}
+			evt.preventDefault();
+			evt.stopPropagation();
+
+			this._keyboardSearch(evt, String.fromCharCode(evt.charCode).toLowerCase());
+		},
+
+		_keyboardSearch: function(/*Event*/ evt, /*String*/ keyChar){
+			// summary:
+			//		Perform a search of the widget's options based on the user's keyboard activity
+			// description:
+			//		Called on keypress (and sometimes keydown), searches through this widget's children
+			//		looking for items that match the user's typed search string.  Multiple characters
+			//		typed within 1 sec of each other are combined for multicharacter searching.
+			// tags:
+			//		private
+			var
+				matchedItem = null,
+				searchString,
+				numMatches = 0,
+				search = lang.hitch(this, function(){
+					if(this._searchTimer){
+						this._searchTimer.remove();
+					}
+					this._searchString += keyChar;
+					var allSameLetter = /^(.)\1*$/.test(this._searchString);
+					var searchLen = allSameLetter ? 1 : this._searchString.length;
+					searchString = this._searchString.substr(0, searchLen);
+					// commented out code block to search again if the multichar search fails after a smaller timeout
+					//this._searchTimer = this.defer(function(){ // this is the "failure" timeout
+					//	this._typingSlowly = true; // if the search fails, then treat as a full timeout
+					//	this._searchTimer = this.defer(function(){ // this is the "success" timeout
+					//		this._searchTimer = null;
+					//		this._searchString = '';
+					//	}, this.multiCharSearchDuration >> 1);
+					//}, this.multiCharSearchDuration >> 1);
+					this._searchTimer = this.defer(function(){ // this is the "success" timeout
+						this._searchTimer = null;
+						this._searchString = '';
+					}, this.multiCharSearchDuration);
+					var currentItem = this.focusedChild || null;
+					if(searchLen == 1 || !currentItem){
+						currentItem = this._getNextFocusableChild(currentItem, 1); // skip current
+						if(!currentItem){
+							return;
+						} // no items
+					}
+					var stop = currentItem;
+					do{
+						var rc = this._keyboardSearchCompare(currentItem, searchString);
+						if(!!rc && numMatches++ == 0){
+							matchedItem = currentItem;
+						}
+						if(rc == -1){ // priority match
+							numMatches = -1;
+							break;
+						}
+						currentItem = this._getNextFocusableChild(currentItem, 1);
+					}while(currentItem != stop);
+					// commented out code block to search again if the multichar search fails after a smaller timeout
+					//if(!numMatches && (this._typingSlowly || searchLen == 1)){
+					//	this._searchString = '';
+					//	if(searchLen > 1){
+					//		// if no matches and they're typing slowly, then go back to first letter searching
+					//		search();
+					//	}
+					//}
+				});
+
+			search();
+			// commented out code block to search again if the multichar search fails after a smaller timeout
+			//this._typingSlowly = false;
+			this.onKeyboardSearch(matchedItem, evt, searchString, numMatches);
+		},
+
+		_onChildBlur: function(/*dijit/_WidgetBase*/ /*===== widget =====*/){
+			// summary:
+			//		Called when focus leaves a child widget to go
+			//		to a sibling widget.
+			//		Used to be used by MenuBase.js (remove for 2.0)
+			// tags:
+			//		protected
+		},
+
+		_getNextFocusableChild: function(child, dir){
+			// summary:
+			//		Returns the next or previous focusable descendant, compared to "child".
+			//		Implements and extends _KeyNavMixin._getNextFocusableChild() for a _Container.
+			// child: Widget
+			//		The current widget
+			// dir: Integer
+			//		- 1 = after
+			//		- -1 = before
+			// tags:
+			//		abstract extension
+
+			var wrappedValue = child;
+			do{
+				if(!child){
+					child = this[dir > 0 ? "_getFirst" : "_getLast"]();
+					if(!child){ break; }
+				}else{
+					child = this._getNext(child, dir);
+				}
+				if(child != null && child != wrappedValue && child.isFocusable()){
+					return child;	// dijit/_WidgetBase
+				}
+			}while(child != wrappedValue);
+			// no focusable child found
+			return null;	// dijit/_WidgetBase
+		},
+
+		_getFirst: function(){
+			// summary:
+			//		Returns the first child.
+			// tags:
+			//		abstract extension
+
+			return null;	// dijit/_WidgetBase
+		},
+
+		_getLast: function(){
+			// summary:
+			//		Returns the last descendant.
+			// tags:
+			//		abstract extension
+
+			return null;	// dijit/_WidgetBase
+		},
+
+		_getNext: function(child, dir){
+			// summary:
+			//		Returns the next descendant, compared to "child".
+			// child: Widget
+			//		The current widget
+			// dir: Integer
+			//		- 1 = after
+			//		- -1 = before
+			// tags:
+			//		abstract extension
+
+			if(child){
+				child = child.domNode;
+				while(child){
+					child = child[dir < 0 ? "previousSibling" : "nextSibling"];
+					if(child  && "getAttribute" in child){
+						var w = registry.byNode(child);
+						if(w){
+							return w; // dijit/_WidgetBase
+						}
+					}
+				}
+			}
+			return null;	// dijit/_WidgetBase
+		}
+	});
+});
diff --git a/dijit/_MenuBase.js b/dijit/_MenuBase.js
index d1b3876..65ad3b0 100644
--- a/dijit/_MenuBase.js
+++ b/dijit/_MenuBase.js
@@ -1,391 +1,464 @@
 define([
-	"./popup",
-	"dojo/window",
-	"./_Widget",
-	"./_KeyNavContainer",
-	"./_TemplatedMixin",
+	"dojo/_base/array", // array.indexOf
 	"dojo/_base/declare", // declare
 	"dojo/dom", // dom.isDescendant domClass.replace
 	"dojo/dom-attr",
 	"dojo/dom-class", // domClass.replace
 	"dojo/_base/lang", // lang.hitch
-	"dojo/_base/array"	// array.indexOf
-], function(pm, winUtils, _Widget, _KeyNavContainer, _TemplatedMixin,
-	declare, dom, domAttr, domClass, lang, array){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _KeyNavContainer = dijit._KeyNavContainer;
-=====*/
-
-// module:
-//		dijit/_MenuBase
-// summary:
-//		Base class for Menu and MenuBar
-
-return declare("dijit._MenuBase",
-	[_Widget, _TemplatedMixin, _KeyNavContainer],
-{
-	// summary:
-	//		Base class for Menu and MenuBar
-
-	// parentMenu: [readonly] Widget
-	//		pointer to menu that displayed me
-	parentMenu: null,
-
-	// popupDelay: Integer
-	//		number of milliseconds before hovering (without clicking) causes the popup to automatically open.
-	popupDelay: 500,
-
-	onExecute: function(){
-		// summary:
-		//		Attach point for notification about when a menu item has been executed.
-		//		This is an internal mechanism used for Menus to signal to their parent to
-		//		close them, because they are about to execute the onClick handler.  In
-		//		general developers should not attach to or override this method.
-		// tags:
-		//		protected
-	},
-
-	onCancel: function(/*Boolean*/ /*===== closeAll =====*/){
-		// summary:
-		//		Attach point for notification about when the user cancels the current menu
-		//		This is an internal mechanism used for Menus to signal to their parent to
-		//		close them.  In general developers should not attach to or override this method.
-		// tags:
-		//		protected
-	},
-
-	_moveToPopup: function(/*Event*/ evt){
-		// summary:
-		//		This handles the right arrow key (left arrow key on RTL systems),
-		//		which will either open a submenu, or move to the next item in the
-		//		ancestor MenuBar
-		// tags:
-		//		private
-
-		if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
-			this.focusedChild._onClick(evt);
-		}else{
-			var topMenu = this._getTopMenu();
-			if(topMenu && topMenu._isMenuBar){
-				topMenu.focusNext();
-			}
-		}
-	},
+	"dojo/mouse", // mouse.enter, mouse.leave
+	"dojo/on",
+	"dojo/window",
+	"./a11yclick",
+	"./registry",
+	"./_Widget",
+	"./_CssStateMixin",
+	"./_KeyNavContainer",
+	"./_TemplatedMixin"
+], function(array, declare, dom, domAttr, domClass, lang, mouse, on, winUtils, a11yclick,
+			registry, _Widget, _CssStateMixin, _KeyNavContainer, _TemplatedMixin){
 
-	_onPopupHover: function(/*Event*/ /*===== evt =====*/){
-		// summary:
-		//		This handler is called when the mouse moves over the popup.
-		// tags:
-		//		private
-
-		// if the mouse hovers over a menu popup that is in pending-close state,
-		// then stop the close operation.
-		// This can't be done in onItemHover since some popup targets don't have MenuItems (e.g. ColorPicker)
-		if(this.currentPopup && this.currentPopup._pendingClose_timer){
-			var parentMenu = this.currentPopup.parentMenu;
-			// highlight the parent menu item pointing to this popup
-			if(parentMenu.focusedChild){
-				parentMenu.focusedChild._setSelected(false);
-			}
-			parentMenu.focusedChild = this.currentPopup.from_item;
-			parentMenu.focusedChild._setSelected(true);
-			// cancel the pending close
-			this._stopPendingCloseTimer(this.currentPopup);
-		}
-	},
+	// module:
+	//		dijit/_MenuBase
 
-	onItemHover: function(/*MenuItem*/ item){
+	return declare("dijit._MenuBase", [_Widget, _TemplatedMixin, _KeyNavContainer, _CssStateMixin], {
 		// summary:
-		//		Called when cursor is over a MenuItem.
-		// tags:
-		//		protected
-
-		// Don't do anything unless user has "activated" the menu by:
-		//		1) clicking it
-		//		2) opening it from a parent menu (which automatically focuses it)
-		if(this.isActive){
-			this.focusChild(item);
-			if(this.focusedChild.popup && !this.focusedChild.disabled && !this.hover_timer){
-				this.hover_timer = setTimeout(lang.hitch(this, "_openPopup"), this.popupDelay);
+		//		Abstract base class for Menu and MenuBar.
+		//		Subclass should implement _onUpArrow(), _onDownArrow(), _onLeftArrow(), and _onRightArrow().
+
+		// selected: dijit/MenuItem
+		//		Currently selected (a.k.a. highlighted) MenuItem, or null if no MenuItem is selected.
+		//		If a submenu is open, will be set to MenuItem that displayed the submenu.   OTOH, if
+		//		this Menu is in passive mode (i.e. hasn't been clicked yet), will be null, because
+		//		"selected" is not merely "hovered".
+		selected: null,
+		_setSelectedAttr: function(item){
+			if(this.selected != item){
+				if(this.selected){
+					this.selected._setSelected(false);
+					this._onChildDeselect(this.selected);
+				}
+				if(item){
+					item._setSelected(true);
+				}
+				this._set("selected", item);
 			}
-		}
-		// if the user is mixing mouse and keyboard navigation,
-		// then the menu may not be active but a menu item has focus,
-		// but it's not the item that the mouse just hovered over.
-		// To avoid both keyboard and mouse selections, use the latest.
-		if(this.focusedChild){
-			this.focusChild(item);
-		}
-		this._hoveredChild = item;
-	},
+		},
 
-	_onChildBlur: function(item){
-		// summary:
-		//		Called when a child MenuItem becomes inactive because focus
-		//		has been removed from the MenuItem *and* it's descendant menus.
-		// tags:
-		//		private
-		this._stopPopupTimer();
-		item._setSelected(false);
-		// Close all popups that are open and descendants of this menu
-		var itemPopup = item.popup;
-		if(itemPopup){
-			this._stopPendingCloseTimer(itemPopup);
-			itemPopup._pendingClose_timer = setTimeout(function(){
-				itemPopup._pendingClose_timer = null;
-				if(itemPopup.parentMenu){
-					itemPopup.parentMenu.currentPopup = null;
+		// activated: [readonly] Boolean
+		//		This Menu has been clicked (mouse or via space/arrow key) or opened as a submenu,
+		//		so mere mouseover will open submenus.  Focusing a menu via TAB does NOT automatically make it active
+		//		since TAB is a navigation operation and not a selection one.
+		//		For Windows apps, pressing the ALT key focuses the menubar menus (similar to TAB navigation) but the
+		//		menu is not active (ie no dropdown) until an item is clicked.
+		activated: false,
+		_setActivatedAttr: function(val){
+			domClass.toggle(this.domNode, "dijitMenuActive", val);
+			domClass.toggle(this.domNode, "dijitMenuPassive", !val);
+			this._set("activated", val);
+		},
+
+		// parentMenu: [readonly] Widget
+		//		pointer to menu that displayed me
+		parentMenu: null,
+
+		// popupDelay: Integer
+		//		After a menu has been activated (by clicking on it etc.), number of milliseconds before hovering
+		//		(without clicking) another MenuItem causes that MenuItem's popup to automatically open.
+		popupDelay: 500,
+
+		// passivePopupDelay: Integer
+		//		For a passive (unclicked) Menu, number of milliseconds before hovering (without clicking) will cause
+		//		the popup to open.  Default is Infinity, meaning you need to click the menu to open it.
+		passivePopupDelay: Infinity,
+
+		// autoFocus: Boolean
+		//		A toggle to control whether or not a Menu gets focused when opened as a drop down from a MenuBar
+		//		or DropDownButton/ComboButton.   Note though that it always get focused when opened via the keyboard.
+		autoFocus: false,
+
+		childSelector: function(/*DOMNode*/ node){
+			// summary:
+			//		Selector (passed to on.selector()) used to identify MenuItem child widgets, but exclude inert children
+			//		like MenuSeparator.  If subclass overrides to a string (ex: "> *"), the subclass must require dojo/query.
+			// tags:
+			//		protected
+
+			var widget = registry.byNode(node);
+			return node.parentNode == this.containerNode && widget && widget.focus;
+		},
+
+		postCreate: function(){
+			var self = this,
+				matches = typeof this.childSelector == "string" ? this.childSelector : lang.hitch(this, "childSelector");
+			this.own(
+				on(this.containerNode, on.selector(matches, mouse.enter), function(){
+					self.onItemHover(registry.byNode(this));
+				}),
+				on(this.containerNode, on.selector(matches, mouse.leave), function(){
+					self.onItemUnhover(registry.byNode(this));
+				}),
+				on(this.containerNode, on.selector(matches, a11yclick), function(evt){
+					self.onItemClick(registry.byNode(this), evt);
+					evt.stopPropagation();
+					evt.preventDefault();
+				})
+			);
+			this.inherited(arguments);
+		},
+
+		onKeyboardSearch: function(/*MenuItem*/ item, /*Event*/ evt, /*String*/ searchString, /*Number*/ numMatches){
+			// summary:
+			//		Attach point for notification about when a menu item has been searched for
+			//		via the keyboard search mechanism.
+			// tags:
+			//		protected
+			this.inherited(arguments);
+			if(!!item && (numMatches == -1 || (!!item.popup && numMatches == 1))){
+				this.onItemClick(item, evt);
+			}
+		},
+
+		_keyboardSearchCompare: function(/*dijit/_WidgetBase*/ item, /*String*/ searchString){
+			// summary:
+			//		Compares the searchString to the widget's text label, returning:
+			//		-1: a high priority match and stop searching
+			//		 0: no match
+			//		 1: a match but keep looking for a higher priority match
+			// tags:
+			//		private
+			if(!!item.shortcutKey){
+				// accessKey matches have priority
+				return searchString == item.shortcutKey.toLowerCase() ? -1 : 0;
+			}
+			return this.inherited(arguments) ? 1 : 0; // change return value of -1 to 1 so that searching continues
+		},
+
+		onExecute: function(){
+			// summary:
+			//		Attach point for notification about when a menu item has been executed.
+			//		This is an internal mechanism used for Menus to signal to their parent to
+			//		close them, because they are about to execute the onClick handler.  In
+			//		general developers should not attach to or override this method.
+			// tags:
+			//		protected
+		},
+
+		onCancel: function(/*Boolean*/ /*===== closeAll =====*/){
+			// summary:
+			//		Attach point for notification about when the user cancels the current menu
+			//		This is an internal mechanism used for Menus to signal to their parent to
+			//		close them.  In general developers should not attach to or override this method.
+			// tags:
+			//		protected
+		},
+
+		_moveToPopup: function(/*Event*/ evt){
+			// summary:
+			//		This handles the right arrow key (left arrow key on RTL systems),
+			//		which will either open a submenu, or move to the next item in the
+			//		ancestor MenuBar
+			// tags:
+			//		private
+
+			if(this.focusedChild && this.focusedChild.popup && !this.focusedChild.disabled){
+				this.onItemClick(this.focusedChild, evt);
+			}else{
+				var topMenu = this._getTopMenu();
+				if(topMenu && topMenu._isMenuBar){
+					topMenu.focusNext();
 				}
-				pm.close(itemPopup); // this calls onClose
-			}, this.popupDelay);
-		}
-	},
+			}
+		},
+
+		_onPopupHover: function(/*Event*/ /*===== evt =====*/){
+			// summary:
+			//		This handler is called when the mouse moves over the popup.
+			// tags:
+			//		private
+
+			// if the mouse hovers over a menu popup that is in pending-close state,
+			// then stop the close operation.
+			// This can't be done in onItemHover since some popup targets don't have MenuItems (e.g. ColorPicker)
+
+			// highlight the parent menu item pointing to this popup (in case user temporarily moused over another MenuItem)
+			this.set("selected", this.currentPopupItem);
+
+			// cancel the pending close (if there is one) (in case user temporarily moused over another MenuItem)
+			this._stopPendingCloseTimer();
+		},
+
+		onItemHover: function(/*MenuItem*/ item){
+			// summary:
+			//		Called when cursor is over a MenuItem.
+			// tags:
+			//		protected
+
+			// Don't do anything unless user has "activated" the menu by:
+			//		1) clicking it
+			//		2) opening it from a parent menu (which automatically activates it)
+
+			if(this.activated){
+				this.set("selected", item);
+				if(item.popup && !item.disabled && !this.hover_timer){
+					this.hover_timer = this.defer(function(){
+						this._openItemPopup(item);
+					}, this.popupDelay);
+				}
+			}else if(this.passivePopupDelay < Infinity){
+				if(this.passive_hover_timer){
+					this.passive_hover_timer.remove();
+				}
+				this.passive_hover_timer = this.defer(function(){
+					this.onItemClick(item, {type: "click"});
+				}, this.passivePopupDelay);
+			}
 
-	onItemUnhover: function(/*MenuItem*/ item){
-		// summary:
-		//		Callback fires when mouse exits a MenuItem
-		// tags:
-		//		protected
+			this._hoveredChild = item;
 
-		if(this.isActive){
-			this._stopPopupTimer();
-		}
-		if(this._hoveredChild == item){ this._hoveredChild = null; }
-	},
+			item._set("hovering", true);
+		},
 
-	_stopPopupTimer: function(){
-		// summary:
-		//		Cancels the popup timer because the user has stop hovering
-		//		on the MenuItem, etc.
-		// tags:
-		//		private
-		if(this.hover_timer){
-			clearTimeout(this.hover_timer);
-			this.hover_timer = null;
-		}
-	},
+		_onChildDeselect: function(item){
+			// summary:
+			//		Called when a child MenuItem becomes deselected.   Setup timer to close its popup.
 
-	_stopPendingCloseTimer: function(/*dijit._Widget*/ popup){
-		// summary:
-		//		Cancels the pending-close timer because the close has been preempted
-		// tags:
-		//		private
-		if(popup._pendingClose_timer){
-			clearTimeout(popup._pendingClose_timer);
-			popup._pendingClose_timer = null;
-		}
-	},
+			this._stopPopupTimer();
 
-	_stopFocusTimer: function(){
-		// summary:
-		//		Cancels the pending-focus timer because the menu was closed before focus occured
-		// tags:
-		//		private
-		if(this._focus_timer){
-			clearTimeout(this._focus_timer);
-			this._focus_timer = null;
-		}
-	},
+			// Setup timer to close all popups that are open and descendants of this menu.
+			// Will be canceled if user quickly moves the mouse over the popup.
+			if(this.currentPopupItem == item){
+				this._stopPendingCloseTimer();
+				this._pendingClose_timer = this.defer(function(){
+					this._pendingClose_timer = null;
+					this.currentPopupItem = null;
+					item._closePopup(); // this calls onClose
+				}, this.popupDelay);
+			}
+		},
 
-	_getTopMenu: function(){
-		// summary:
-		//		Returns the top menu in this chain of Menus
-		// tags:
-		//		private
-		for(var top=this; top.parentMenu; top=top.parentMenu);
-		return top;
-	},
-
-	onItemClick: function(/*dijit._Widget*/ item, /*Event*/ evt){
-		// summary:
-		//		Handle clicks on an item.
-		// tags:
-		//		private
+		onItemUnhover: function(/*MenuItem*/ item){
+			// summary:
+			//		Callback fires when mouse exits a MenuItem
+			// tags:
+			//		protected
 
-		// this can't be done in _onFocus since the _onFocus events occurs asynchronously
-		if(typeof this.isShowingNow == 'undefined'){ // non-popup menu
-			this._markActive();
-		}
+			if(this._hoveredChild == item){
+				this._hoveredChild = null;
+			}
 
-		this.focusChild(item);
+			if(this.passive_hover_timer){
+				this.passive_hover_timer.remove();
+				this.passive_hover_timer = null;
+			}
 
-		if(item.disabled){ return false; }
+			item._set("hovering", false);
+		},
 
-		if(item.popup){
-			this._openPopup();
-		}else{
-			// before calling user defined handler, close hierarchy of menus
-			// and restore focus to place it was when menu was opened
-			this.onExecute();
+		_stopPopupTimer: function(){
+			// summary:
+			//		Cancels the popup timer because the user has stop hovering
+			//		on the MenuItem, etc.
+			// tags:
+			//		private
 
-			// user defined handler for click
-			item.onClick(evt);
-		}
-	},
+			if(this.hover_timer){
+				this.hover_timer = this.hover_timer.remove();
+			}
+		},
+
+		_stopPendingCloseTimer: function(){
+			// summary:
+			//		Cancels the pending-close timer because the close has been preempted
+			// tags:
+			//		private
+			if(this._pendingClose_timer){
+				this._pendingClose_timer = this._pendingClose_timer.remove();
+			}
+		},
+
+		_getTopMenu: function(){
+			// summary:
+			//		Returns the top menu in this chain of Menus
+			// tags:
+			//		private
+			for(var top = this; top.parentMenu; top = top.parentMenu){}
+			return top;
+		},
+
+		onItemClick: function(/*dijit/_WidgetBase*/ item, /*Event*/ evt){
+			// summary:
+			//		Handle clicks on an item.
+			// tags:
+			//		private
+
+			if(this.passive_hover_timer){
+				this.passive_hover_timer.remove();
+			}
 
-	_openPopup: function(){
-		// summary:
-		//		Open the popup to the side of/underneath the current menu item
-		// tags:
-		//		protected
-
-		this._stopPopupTimer();
-		var from_item = this.focusedChild;
-		if(!from_item){ return; } // the focused child lost focus since the timer was started
-		var popup = from_item.popup;
-		if(popup.isShowingNow){ return; }
-		if(this.currentPopup){
-			this._stopPendingCloseTimer(this.currentPopup);
-			pm.close(this.currentPopup);
-		}
-		popup.parentMenu = this;
-		popup.from_item = from_item; // helps finding the parent item that should be focused for this popup
-		var self = this;
-		pm.open({
-			parent: this,
-			popup: popup,
-			around: from_item.domNode,
-			orient: this._orient || ["after", "before"],
-			onCancel: function(){ // called when the child menu is canceled
-				// set isActive=false (_closeChild vs _cleanUp) so that subsequent hovering will NOT open child menus
-				// which seems aligned with the UX of most applications (e.g. notepad, wordpad, paint shop pro)
-				self.focusChild(from_item);	// put focus back on my node
-				self._cleanUp();			// close the submenu (be sure this is done _after_ focus is moved)
-				from_item._setSelected(true); // oops, _cleanUp() deselected the item
-				self.focusedChild = from_item;	// and unset focusedChild
-			},
-			onExecute: lang.hitch(this, "_cleanUp")
-		});
-
-		this.currentPopup = popup;
-		// detect mouseovers to handle lazy mouse movements that temporarily focus other menu items
-		popup.connect(popup.domNode, "onmouseenter", lang.hitch(self, "_onPopupHover")); // cleaned up when the popped-up widget is destroyed on close
-
-		if(popup.focus){
-			// If user is opening the popup via keyboard (right arrow, or down arrow for MenuBar),
-			// if the cursor happens to collide with the popup, it will generate an onmouseover event
-			// even though the mouse wasn't moved.  Use a setTimeout() to call popup.focus so that
-			// our focus() call overrides the onmouseover event, rather than vice-versa.  (#8742)
-			popup._focus_timer = setTimeout(lang.hitch(popup, function(){
-				this._focus_timer = null;
-				this.focus();
-			}), 0);
-		}
-	},
+			this.focusChild(item);
 
-	_markActive: function(){
-		// summary:
-		//		Mark this menu's state as active.
-		//		Called when this Menu gets focus from:
-		//			1) clicking it (mouse or via space/arrow key)
-		//			2) being opened by a parent menu.
-		//		This is not called just from mouse hover.
-		//		Focusing a menu via TAB does NOT automatically set isActive
-		//		since TAB is a navigation operation and not a selection one.
-		//		For Windows apps, pressing the ALT key focuses the menubar
-		//		menus (similar to TAB navigation) but the menu is not active
-		//		(ie no dropdown) until an item is clicked.
-		this.isActive = true;
-		domClass.replace(this.domNode, "dijitMenuActive", "dijitMenuPassive");
-	},
-
-	onOpen: function(/*Event*/ /*===== e =====*/){
-		// summary:
-		//		Callback when this menu is opened.
-		//		This is called by the popup manager as notification that the menu
-		//		was opened.
-		// tags:
-		//		private
+			if(item.disabled){
+				return false;
+			}
 
-		this.isShowingNow = true;
-		this._markActive();
-	},
+			if(item.popup){
+				this.set("selected", item);
+				this.set("activated", true);
+				var byKeyboard = /^key/.test(evt._origType || evt.type) ||
+					(evt.clientX == 0 && evt.clientY == 0);	// detects accessKey like ALT+SHIFT+F, where type is "click"
+				this._openItemPopup(item, byKeyboard);
+			}else{
+				// before calling user defined handler, close hierarchy of menus
+				// and restore focus to place it was when menu was opened
+				this.onExecute();
+
+				// user defined handler for click
+				item._onClick ? item._onClick(evt) : item.onClick(evt);
+			}
+		},
 
-	_markInactive: function(){
-		// summary:
-		//		Mark this menu's state as inactive.
-		this.isActive = false; // don't do this in _onBlur since the state is pending-close until we get here
-		domClass.replace(this.domNode, "dijitMenuPassive", "dijitMenuActive");
-	},
+		_openItemPopup: function(/*dijit/MenuItem*/ from_item, /*Boolean*/ focus){
+			// summary:
+			//		Open the popup to the side of/underneath the current menu item, and optionally focus first item
+			// tags:
+			//		protected
 
-	onClose: function(){
-		// summary:
-		//		Callback when this menu is closed.
-		//		This is called by the popup manager as notification that the menu
-		//		was closed.
-		// tags:
-		//		private
-
-		this._stopFocusTimer();
-		this._markInactive();
-		this.isShowingNow = false;
-		this.parentMenu = null;
-	},
-
-	_closeChild: function(){
-		// summary:
-		//		Called when submenu is clicked or focus is lost.  Close hierarchy of menus.
-		// tags:
-		//		private
-		this._stopPopupTimer();
-
-		if(this.currentPopup){
-			// If focus is on a descendant MenuItem then move focus to me,
-			// because IE doesn't like it when you display:none a node with focus,
-			// and also so keyboard users don't lose control.
-			// Likely, immediately after a user defined onClick handler will move focus somewhere
-			// else, like a Dialog.
-			if(array.indexOf(this._focusManager.activeStack, this.id) >= 0){
-				domAttr.set(this.focusedChild.focusNode, "tabIndex", this.tabIndex);
-				this.focusedChild.focusNode.focus();
+			if(from_item == this.currentPopupItem){
+				// Specified popup is already being shown, so just return
+				return;
 			}
-			// Close all popups that are open and descendants of this menu
-			pm.close(this.currentPopup);
-			this.currentPopup = null;
-		}
+			if(this.currentPopupItem){
+				// If another popup is currently shown, then close it
+				this._stopPendingCloseTimer();
+				this.currentPopupItem._closePopup();
+			}
+			this._stopPopupTimer();
 
-		if(this.focusedChild){ // unhighlight the focused item
-			this.focusedChild._setSelected(false);
-			this.focusedChild._onUnhover();
-			this.focusedChild = null;
-		}
-	},
+			var popup = from_item.popup;
+			popup.parentMenu = this;
+
+			// detect mouseover of the popup to handle lazy mouse movements that temporarily focus other menu items\c
+			this.own(this._mouseoverHandle = on.once(popup.domNode, "mouseover", lang.hitch(this, "_onPopupHover")));
+
+			var self = this;
+			from_item._openPopup({
+				parent: this,
+				orient: this._orient || ["after", "before"],
+				onCancel: function(){ // called when the child menu is canceled
+					if(focus){
+						// put focus back on my node before focused node is hidden
+						self.focusChild(from_item);
+					}
+
+					// close the submenu (be sure this is done _after_ focus is moved)
+					self._cleanUp();
+				},
+				onExecute: lang.hitch(this, "_cleanUp", true),
+				onClose: function(){
+					// Remove handler created by onItemHover
+					if(self._mouseoverHandle){
+						self._mouseoverHandle.remove();
+						delete self._mouseoverHandle;
+					}
+				}
+			}, focus);
+
+			this.currentPopupItem = from_item;
+
+			// TODO: focusing a popup should clear tabIndex on Menu (and it's child MenuItems), so that neither
+			// TAB nor SHIFT-TAB returns to the menu.  Only ESC or ENTER should return to the menu.
+		},
+
+		onOpen: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		Callback when this menu is opened.
+			//		This is called by the popup manager as notification that the menu
+			//		was opened.
+			// tags:
+			//		private
+
+			this.isShowingNow = true;
+			this.set("activated", true);
+		},
+
+		onClose: function(){
+			// summary:
+			//		Callback when this menu is closed.
+			//		This is called by the popup manager as notification that the menu
+			//		was closed.
+			// tags:
+			//		private
+
+			this.set("activated", false);
+			this.set("selected", null);
+			this.isShowingNow = false;
+			this.parentMenu = null;
+		},
+
+		_closeChild: function(){
+			// summary:
+			//		Called when submenu is clicked or focus is lost.  Close hierarchy of menus.
+			// tags:
+			//		private
+			this._stopPopupTimer();
 
-	_onItemFocus: function(/*MenuItem*/ item){
-		// summary:
-		//		Called when child of this Menu gets focus from:
-		//			1) clicking it
-		//			2) tabbing into it
-		//			3) being opened by a parent menu.
-		//		This is not called just from mouse hover.
-		if(this._hoveredChild && this._hoveredChild != item){
-			this._hoveredChild._onUnhover(); // any previous mouse movement is trumped by focus selection
-		}
-	},
+			if(this.currentPopupItem){
+				// If focus is on a descendant MenuItem then move focus to me,
+				// because IE doesn't like it when you display:none a node with focus,
+				// and also so keyboard users don't lose control.
+				// Likely, immediately after a user defined onClick handler will move focus somewhere
+				// else, like a Dialog.
+				if(this.focused){
+					domAttr.set(this.selected.focusNode, "tabIndex", this.tabIndex);
+					this.selected.focusNode.focus();
+				}
 
-	_onBlur: function(){
-		// summary:
-		//		Called when focus is moved away from this Menu and it's submenus.
-		// tags:
-		//		protected
-		this._cleanUp();
-		this.inherited(arguments);
-	},
-
-	_cleanUp: function(){
-		// summary:
-		//		Called when the user is done with this menu.  Closes hierarchy of menus.
-		// tags:
-		//		private
+				// Close all popups that are open and descendants of this menu
+				this.currentPopupItem._closePopup();
+				this.currentPopupItem = null;
+			}
+		},
+
+		_onItemFocus: function(/*MenuItem*/ item){
+			// summary:
+			//		Called when child of this Menu gets focus from:
+			//
+			//		1. clicking it
+			//		2. tabbing into it
+			//		3. being opened by a parent menu.
+			//
+			//		This is not called just from mouse hover.
+
+			if(this._hoveredChild && this._hoveredChild != item){
+				this.onItemUnhover(this._hoveredChild);	// any previous mouse movement is trumped by focus selection
+			}
+			this.set("selected", item);
+		},
+
+		_onBlur: function(){
+			// summary:
+			//		Called when focus is moved away from this Menu and it's submenus.
+			// tags:
+			//		protected
+
+			this._cleanUp(true);
+			this.inherited(arguments);
+		},
+
+		_cleanUp: function(/*Boolean*/ clearSelectedItem){
+			// summary:
+			//		Called when the user is done with this menu.  Closes hierarchy of menus.
+			// tags:
+			//		private
+
+			this._closeChild(); // don't call this.onClose since that's incorrect for MenuBar's that never close
+			if(typeof this.isShowingNow == 'undefined'){ // non-popup menu doesn't call onClose
+				this.set("activated", false);
+			}
 
-		this._closeChild(); // don't call this.onClose since that's incorrect for MenuBar's that never close
-		if(typeof this.isShowingNow == 'undefined'){ // non-popup menu doesn't call onClose
-			this._markInactive();
+			if(clearSelectedItem){
+				this.set("selected", null);
+			}
 		}
-	}
-});
-
+	});
 });
diff --git a/dijit/_OnDijitClickMixin.js b/dijit/_OnDijitClickMixin.js
index 081ee86..0009202 100644
--- a/dijit/_OnDijitClickMixin.js
+++ b/dijit/_OnDijitClickMixin.js
@@ -3,123 +3,29 @@ define([
 	"dojo/_base/array", // array.forEach
 	"dojo/keys", // keys.ENTER keys.SPACE
 	"dojo/_base/declare", // declare
-	"dojo/_base/sniff", // has("ie")
-	"dojo/_base/unload", // unload.addOnWindowUnload
-	"dojo/_base/window" // win.doc.addEventListener win.doc.attachEvent win.doc.detachEvent
-], function(on, array, keys, declare, has, unload, win){
+	"dojo/has", // has("dom-addeventlistener")
+	"./a11yclick"
+], function(on, array, keys, declare, has, a11yclick){
 
 	// module:
 	//		dijit/_OnDijitClickMixin
-	// summary:
-	//		Mixin so you can pass "ondijitclick" to this.connect() method,
-	//		as a way to handle clicks by mouse, or by keyboard (SPACE/ENTER key)
-
-
-	// Keep track of where the last keydown event was, to help avoid generating
-	// spurious ondijitclick events when:
-	// 1. focus is on a <button> or <a>
-	// 2. user presses then releases the ENTER key
-	// 3. onclick handler fires and shifts focus to another node, with an ondijitclick handler
-	// 4. onkeyup event fires, causing the ondijitclick handler to fire
-	var lastKeyDownNode = null;
-	if(has("ie")){
-		(function(){
-			var keydownCallback = function(evt){
-				lastKeyDownNode = evt.srcElement;
-			};
-			win.doc.attachEvent('onkeydown', keydownCallback);
-			unload.addOnWindowUnload(function(){
-				win.doc.detachEvent('onkeydown', keydownCallback);
-			});
-		})();
-	}else{
-		win.doc.addEventListener('keydown', function(evt){
-			lastKeyDownNode = evt.target;
-		}, true);
-	}
-
-	// Custom a11yclick (a.k.a. ondijitclick) event
-	var a11yclick = function(node, listener){
-		if(/input|button/i.test(node.nodeName)){
-			// pass through, the browser already generates click event on SPACE/ENTER key
-			return on(node, "click", listener);
-		}else{
-			// Don't fire the click event unless both the keydown and keyup occur on this node.
-			// Avoids problems where focus shifted to this node or away from the node on keydown,
-			// either causing this node to process a stray keyup event, or causing another node
-			// to get a stray keyup event.
-
-			function clickKey(/*Event*/ e){
-				return (e.keyCode == keys.ENTER || e.keyCode == keys.SPACE) &&
-						!e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey;
-			}
-			var handles = [
-				on(node, "keypress", function(e){
-					//console.log(this.id + ": onkeydown, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode));
-					if(clickKey(e)){
-						// needed on IE for when focus changes between keydown and keyup - otherwise dropdown menus do not work
-						lastKeyDownNode = e.target;
-
-						// Prevent viewport scrolling on space key in IE<9.
-						// (Reproducible on test_Button.html on any of the first dijit.form.Button examples)
-						// Do this onkeypress rather than onkeydown because onkeydown.preventDefault() will
-						// suppress the onkeypress event, breaking _HasDropDown
-						e.preventDefault();
-					}
-				}),
-
-				on(node, "keyup", function(e){
-					//console.log(this.id + ": onkeyup, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode));
-					if(clickKey(e) && e.target == lastKeyDownNode){	// === breaks greasemonkey
-						//need reset here or have problems in FF when focus returns to trigger element after closing popup/alert
-						lastKeyDownNode = null;
-						listener.call(this, e);
-					}
-				}),
-
-				on(node, "click", function(e){
-					// and connect for mouse clicks too (or touch-clicks on mobile)
-					listener.call(this, e);
-				})
-			];
-
-			return {
-				remove: function(){
-					array.forEach(handles, function(h){ h.remove(); });
-				}
-			};
-		}
-	};
-
-	return declare("dijit._OnDijitClickMixin", null, {
-		connect: function(
-				/*Object|null*/ obj,
-				/*String|Function*/ event,
-				/*String|Function*/ method){
-			// summary:
-			//		Connects specified obj/event to specified method of this object
-			//		and registers for disconnect() on widget destroy.
-			// description:
-			//		Provide widget-specific analog to connect.connect, except with the
-			//		implicit use of this widget as the target object.
-			//		This version of connect also provides a special "ondijitclick"
-			//		event which triggers on a click or space or enter keyup.
-			//		Events connected with `this.connect` are disconnected upon
-			//		destruction.
-			// returns:
-			//		A handle that can be passed to `disconnect` in order to disconnect before
-			//		the widget is destroyed.
-			// example:
-			//	|	var btn = new dijit.form.Button();
-			//	|	// when foo.bar() is called, call the listener we're going to
-			//	|	// provide in the scope of btn
-			//	|	btn.connect(foo, "bar", function(){
-			//	|		console.debug(this.toString());
-			//	|	});
-			// tags:
-			//		protected
 
+	var ret = declare("dijit._OnDijitClickMixin", null, {
+		// summary:
+		//		Deprecated.   New code should access the dijit/a11yclick event directly, ex:
+		//		|	this.own(on(node, a11yclick, function(){ ... }));
+		//
+		//		Mixing in this class will make _WidgetBase.connect(node, "ondijitclick", ...) work.
+		//		It also used to be necessary to make templates with ondijitclick work, but now you can just require
+		//		dijit/a11yclick.
+
+		connect: function(obj, event, method){
+			// override _WidgetBase.connect() to make this.connect(node, "ondijitclick", ...) work
 			return this.inherited(arguments, [obj, event == "ondijitclick" ? a11yclick : event, method]);
 		}
 	});
+
+	ret.a11yclick = a11yclick;	// back compat
+
+	return ret;
 });
diff --git a/dijit/_PaletteMixin.js b/dijit/_PaletteMixin.js
index cb9cbfb..33b1931 100644
--- a/dijit/_PaletteMixin.js
+++ b/dijit/_PaletteMixin.js
@@ -3,343 +3,337 @@ define([
 	"dojo/dom-attr", // domAttr.set
 	"dojo/dom-class", // domClass.add domClass.remove
 	"dojo/dom-construct", // domConstruct.create domConstruct.place
-	"dojo/_base/event", // event.stop
 	"dojo/keys", // keys
 	"dojo/_base/lang", // lang.getObject
+	"dojo/on",
 	"./_CssStateMixin",
+	"./a11yclick",
 	"./focus",
 	"./typematic"
-], function(declare, domAttr, domClass, domConstruct, event, keys, lang, _CssStateMixin, focus, typematic){
-
-/*=====
-	var _CssStateMixin = dijit._CssStateMixin;
-=====*/
-
-// module:
-//		dijit/_PaletteMixin
-// summary:
-//		A keyboard accessible palette, for picking a color/emoticon/etc.
-
-return declare("dijit._PaletteMixin", [_CssStateMixin], {
-	// summary:
-	//		A keyboard accessible palette, for picking a color/emoticon/etc.
-	// description:
-	//		A mixin for a grid showing various entities, so the user can pick a certain entity.
-
-	// defaultTimeout: Number
-	//		Number of milliseconds before a held key or button becomes typematic
-	defaultTimeout: 500,
-
-	// timeoutChangeRate: Number
-	//		Fraction of time used to change the typematic timer between events
-	//		1.0 means that each typematic event fires at defaultTimeout intervals
-	//		< 1.0 means that each typematic event fires at an increasing faster rate
-	timeoutChangeRate: 0.90,
-
-	// value: String
-	//		Currently selected color/emoticon/etc.
-	value: "",
-
-	// _selectedCell: [private] Integer
-	//		Index of the currently selected cell. Initially, none selected
-	_selectedCell: -1,
-
-/*=====
-	// _currentFocus: [private] DomNode
-	//		The currently focused cell (if the palette itself has focus), or otherwise
-	//		the cell to be focused when the palette itself gets focus.
-	//		Different from value, which represents the selected (i.e. clicked) cell.
-	_currentFocus: null,
-=====*/
-
-/*=====
-	// _xDim: [protected] Integer
-	//		This is the number of cells horizontally across.
-	_xDim: null,
-=====*/
-
-/*=====
-	// _yDim: [protected] Integer
-	//		This is the number of cells vertically down.
-	_yDim: null,
-=====*/
-
-	// tabIndex: String
-	//		Widget tab index.
-	tabIndex: "0",
-
-	// cellClass: [protected] String
-	//		CSS class applied to each cell in the palette
-	cellClass: "dijitPaletteCell",
-
-	// dyeClass: [protected] String
-	//	 Name of javascript class for Object created for each cell of the palette.
-	//	 dyeClass should implements dijit.Dye interface
-	dyeClass: '',
-	
-	// summary: String
-	//		Localized summary for the palette table
-	summary: '',
-	_setSummaryAttr: "paletteTableNode",
-
-	_dyeFactory: function(value /*===== , row, col =====*/){
-		// summary:
-		//		Return instance of dijit.Dye for specified cell of palette
-		// tags:
-		//		extension
-		var dyeClassObj = lang.getObject(this.dyeClass);
-		return new dyeClassObj(value);
-	},
-
-	_preparePalette: function(choices, titles) {
-		// summary:
-		//		Subclass must call _preparePalette() from postCreate(), passing in the tooltip
-		//		for each cell
-		// choices: String[][]
-		//		id's for each cell of the palette, used to create Dye JS object for each cell
-		// titles: String[]
-		//		Localized tooltip for each cell
+], function(declare, domAttr, domClass, domConstruct, keys, lang, on, _CssStateMixin, a11yclick, focus, typematic){
 
-		this._cells = [];
-		var url = this._blankGif;
+	// module:
+	//		dijit/_PaletteMixin
 
-		this.connect(this.gridNode, "ondijitclick", "_onCellClick");
-
-		for(var row=0; row < choices.length; row++){
-			var rowNode = domConstruct.create("tr", {tabIndex: "-1"}, this.gridNode);
-			for(var col=0; col < choices[row].length; col++){
-				var value = choices[row][col];
-				if(value){
-					var cellObject = this._dyeFactory(value, row, col);
+	var PaletteMixin = declare("dijit._PaletteMixin", _CssStateMixin, {
+		// summary:
+		//		A keyboard accessible palette, for picking a color/emoticon/etc.
+		// description:
+		//		A mixin for a grid showing various entities, so the user can pick a certain entity.
 
-					var cellNode = domConstruct.create("td", {
-						"class": this.cellClass,
-						tabIndex: "-1",
-						title: titles[value],
-						role: "gridcell"
-					});
+		// defaultTimeout: Number
+		//		Number of milliseconds before a held key or button becomes typematic
+		defaultTimeout: 500,
 
-					// prepare cell inner structure
-					cellObject.fillCell(cellNode, url);
+		// timeoutChangeRate: Number
+		//		Fraction of time used to change the typematic timer between events
+		//		1.0 means that each typematic event fires at defaultTimeout intervals
+		//		Less than 1.0 means that each typematic event fires at an increasing faster rate
+		timeoutChangeRate: 0.90,
 
-					domConstruct.place(cellNode, rowNode);
+		// value: String
+		//		Currently selected color/emoticon/etc.
+		value: "",
+
+		// _selectedCell: [private] Integer
+		//		Index of the currently selected cell. Initially, none selected
+		_selectedCell: -1,
+
+		/*=====
+		 // _currentFocus: [private] DomNode
+		 //		The currently focused cell (if the palette itself has focus), or otherwise
+		 //		the cell to be focused when the palette itself gets focus.
+		 //		Different from value, which represents the selected (i.e. clicked) cell.
+		 _currentFocus: null,
+		 =====*/
+
+		/*=====
+		 // _xDim: [protected] Integer
+		 //		This is the number of cells horizontally across.
+		 _xDim: null,
+		 =====*/
+
+		/*=====
+		 // _yDim: [protected] Integer
+		 //		This is the number of cells vertically down.
+		 _yDim: null,
+		 =====*/
+
+		// tabIndex: String
+		//		Widget tab index.
+		tabIndex: "0",
+
+		// cellClass: [protected] String
+		//		CSS class applied to each cell in the palette
+		cellClass: "dijitPaletteCell",
+
+		// dyeClass: [protected] Constructor
+		//		Constructor for Object created for each cell of the palette.
+		//		dyeClass should implement the dijit/_PaletteMixin.__Dye interface.
+		dyeClass: null,
+
+		_dyeFactory: function(value /*===== , row, col, title =====*/){
+			// summary:
+			//		Return instance of dijit.Dye for specified cell of palette
+			// tags:
+			//		extension
 
-					cellNode.index = this._cells.length;
+			// Remove string support for 2.0
+			var dyeClassObj = typeof this.dyeClass == "string" ? lang.getObject(this.dyeClass) : this.dyeClass;
+			return new dyeClassObj(value);
+		},
 
-					// save cell info into _cells
-					this._cells.push({node:cellNode, dye:cellObject});
+		_preparePalette: function(choices, titles){
+			// summary:
+			//		Subclass must call _preparePalette() from postCreate(), passing in the tooltip
+			//		for each cell
+			// choices: String[][]
+			//		id's for each cell of the palette, used to create Dye JS object for each cell
+			// titles: String[]
+			//		Localized tooltip for each cell
+
+			this._cells = [];
+			var url = this._blankGif;
+
+			this.own(on(this.gridNode, a11yclick, lang.hitch(this, "_onCellClick")));
+
+			for(var row = 0; row < choices.length; row++){
+				var rowNode = domConstruct.create("tr", {tabIndex: "-1", role: "row"}, this.gridNode);
+				for(var col = 0; col < choices[row].length; col++){
+					var value = choices[row][col];
+					if(value){
+						var cellObject = this._dyeFactory(value, row, col, titles[value]);
+
+						var cellNode = domConstruct.create("td", {
+							"class": this.cellClass,
+							tabIndex: "-1",
+							title: titles[value],
+							role: "gridcell"
+						}, rowNode);
+
+						// prepare cell inner structure
+						cellObject.fillCell(cellNode, url);
+
+						cellNode.idx = this._cells.length;
+
+						// save cell info into _cells
+						this._cells.push({node: cellNode, dye: cellObject});
+					}
 				}
 			}
-		}
-		this._xDim = choices[0].length;
-		this._yDim = choices.length;
-
-		// Now set all events
-		// The palette itself is navigated to with the tab key on the keyboard
-		// Keyboard navigation within the Palette is with the arrow keys
-		// Spacebar selects the cell.
-		// For the up key the index is changed by negative the x dimension.
-
-		var keyIncrementMap = {
-			UP_ARROW: -this._xDim,
-			// The down key the index is increase by the x dimension.
-			DOWN_ARROW: this._xDim,
-			// Right and left move the index by 1.
-			RIGHT_ARROW: this.isLeftToRight() ? 1 : -1,
-			LEFT_ARROW: this.isLeftToRight() ? -1 : 1
-		};
-		for(var key in keyIncrementMap){
-			this._connects.push(
-				typematic.addKeyListener(
-					this.domNode,
-					{charOrCode:keys[key], ctrlKey:false, altKey:false, shiftKey:false},
-					this,
-					function(){
-						var increment = keyIncrementMap[key];
-						return function(count){ this._navigateByKey(increment, count); };
-					}(),
-					this.timeoutChangeRate,
-					this.defaultTimeout
-				)
-			);
-		}
-	},
-
-	postCreate: function(){
-		this.inherited(arguments);
-
-		// Set initial navigable node.
-		this._setCurrent(this._cells[0].node);
-	},
+			this._xDim = choices[0].length;
+			this._yDim = choices.length;
+
+			// Now set all events
+			// The palette itself is navigated to with the tab key on the keyboard
+			// Keyboard navigation within the Palette is with the arrow keys
+			// Spacebar selects the cell.
+			// For the up key the index is changed by negative the x dimension.
+
+			var keyIncrementMap = {
+				UP_ARROW: -this._xDim,
+				// The down key the index is increase by the x dimension.
+				DOWN_ARROW: this._xDim,
+				// Right and left move the index by 1.
+				RIGHT_ARROW: this.isLeftToRight() ? 1 : -1,
+				LEFT_ARROW: this.isLeftToRight() ? -1 : 1
+			};
+			for(var key in keyIncrementMap){
+				this.own(
+					typematic.addKeyListener(
+						this.domNode,
+						{keyCode: keys[key], ctrlKey: false, altKey: false, shiftKey: false},
+						this,
+						function(){
+							var increment = keyIncrementMap[key];
+							return function(count){
+								this._navigateByKey(increment, count);
+							};
+						}(),
+						this.timeoutChangeRate,
+						this.defaultTimeout
+					)
+				);
+			}
+		},
 
-	focus: function(){
-		// summary:
-		//		Focus this widget.  Puts focus on the most recently focused cell.
+		postCreate: function(){
+			this.inherited(arguments);
 
-		// The cell already has tabIndex set, just need to set CSS and focus it
-		focus.focus(this._currentFocus);
-	},
+			// Set initial navigable node.
+			this._setCurrent(this._cells[0].node);
+		},
 
-	_onCellClick: function(/*Event*/ evt){
-		// summary:
-		//		Handler for click, enter key & space key. Selects the cell.
-		// evt:
-		//		The event.
-		// tags:
-		//		private
+		focus: function(){
+			// summary:
+			//		Focus this widget.  Puts focus on the most recently focused cell.
 
-		var target = evt.target;
+			// The cell already has tabIndex set, just need to set CSS and focus it
+			focus.focus(this._currentFocus);
+		},
 
-		// Find TD associated with click event.   For ColorPalette user likely clicked IMG inside of TD
-		while(target.tagName != "TD"){
-			if(!target.parentNode || target == this.gridNode){	// probably can never happen, but just in case
-				return;
+		_onCellClick: function(/*Event*/ evt){
+			// summary:
+			//		Handler for click, enter key & space key. Selects the cell.
+			// evt:
+			//		The event.
+			// tags:
+			//		private
+
+			var target = evt.target;
+
+			// Find TD associated with click event.   For ColorPalette user likely clicked IMG inside of TD
+			while(target.tagName != "TD"){
+				if(!target.parentNode || target == this.gridNode){    // probably can never happen, but just in case
+					return;
+				}
+				target = target.parentNode;
 			}
-			target = target.parentNode;
-		}
 
-		var value = this._getDye(target).getValue();
+			var value = this._getDye(target).getValue();
 
-		// First focus the clicked cell, and then send onChange() notification.
-		// onChange() (via _setValueAttr) must be after the focus call, because
-		// it may trigger a refocus to somewhere else (like the Editor content area), and that
-		// second focus should win.
-		this._setCurrent(target);
-		focus.focus(target);
-		this._setValueAttr(value, true);
+			// First focus the clicked cell, and then send onChange() notification.
+			// onChange() (via _setValueAttr) must be after the focus call, because
+			// it may trigger a refocus to somewhere else (like the Editor content area), and that
+			// second focus should win.
+			this._setCurrent(target);
+			focus.focus(target);
+			this._setValueAttr(value, true);
 
-		event.stop(evt);
-	},
+			evt.stopPropagation();
+			evt.preventDefault();
+		},
 
-	_setCurrent: function(/*DomNode*/ node){
-		// summary:
-		//		Sets which node is the focused cell.
-		// description:
-   		//		At any point in time there's exactly one
-		//		cell with tabIndex != -1.   If focus is inside the palette then
-		// 		focus is on that cell.
-		//
-		//		After calling this method, arrow key handlers and mouse click handlers
-		//		should focus the cell in a setTimeout().
-		// tags:
-		//		protected
-		if("_currentFocus" in this){
-			// Remove tabIndex on old cell
-			domAttr.set(this._currentFocus, "tabIndex", "-1");
-		}
+		_setCurrent: function(/*DomNode*/ node){
+			// summary:
+			//		Sets which node is the focused cell.
+			// description:
+			//		At any point in time there's exactly one
+			//		cell with tabIndex != -1.   If focus is inside the palette then
+			//		focus is on that cell.
+			//
+			//		After calling this method, arrow key handlers and mouse click handlers
+			//		should focus the cell in a setTimeout().
+			// tags:
+			//		protected
+			if("_currentFocus" in this){
+				// Remove tabIndex on old cell
+				domAttr.set(this._currentFocus, "tabIndex", "-1");
+			}
 
-		// Set tabIndex of new cell
-		this._currentFocus = node;
-		if(node){
-			domAttr.set(node, "tabIndex", this.tabIndex);
-		}
-	},
+			// Set tabIndex of new cell
+			this._currentFocus = node;
+			if(node){
+				domAttr.set(node, "tabIndex", this.tabIndex);
+			}
+		},
 
-	_setValueAttr: function(value, priorityChange){
-		// summary:
-		// 		This selects a cell. It triggers the onChange event.
-		// value: String value of the cell to select
-		// tags:
-		//		protected
-		// priorityChange:
-		//		Optional parameter used to tell the select whether or not to fire
-		//		onChange event.
-
-		// clear old selected cell
-		if(this._selectedCell >= 0){
-			domClass.remove(this._cells[this._selectedCell].node, this.cellClass + "Selected");
-		}
-		this._selectedCell = -1;
-
-		// search for cell matching specified value
-		if(value){
-			for(var i = 0; i < this._cells.length; i++){
-				if(value == this._cells[i].dye.getValue()){
-					this._selectedCell = i;
-					domClass.add(this._cells[i].node, this.cellClass + "Selected");
-					break;
+		_setValueAttr: function(value, priorityChange){
+			// summary:
+			//		This selects a cell. It triggers the onChange event.
+			// value: String
+			//		Value of the cell to select
+			// tags:
+			//		protected
+			// priorityChange: Boolean?
+			//		Optional parameter used to tell the select whether or not to fire
+			//		onChange event.
+
+			// clear old selected cell
+			if(this._selectedCell >= 0){
+				domClass.remove(this._cells[this._selectedCell].node, this.cellClass + "Selected");
+			}
+			this._selectedCell = -1;
+
+			// search for cell matching specified value
+			if(value){
+				for(var i = 0; i < this._cells.length; i++){
+					if(value == this._cells[i].dye.getValue()){
+						this._selectedCell = i;
+						domClass.add(this._cells[i].node, this.cellClass + "Selected");
+						break;
+					}
 				}
 			}
-		}
 
-		// record new value, or null if no matching cell
-		this._set("value", this._selectedCell >= 0 ? value : null);
-
-		if(priorityChange || priorityChange === undefined){
-			this.onChange(value);
-		}
-	},
-
-	onChange: function(/*===== value =====*/){
-		// summary:
-		//		Callback when a cell is selected.
-		// value: String
-		//		Value corresponding to cell.
-	},
-
-	_navigateByKey: function(increment, typeCount){
-		// summary:
-		// 	  	This is the callback for typematic.
-		// 		It changes the focus and the highlighed cell.
-		// increment:
-		// 		How much the key is navigated.
-		// typeCount:
-		//		How many times typematic has fired.
-		// tags:
-		//		private
-
-		// typecount == -1 means the key is released.
-		if(typeCount == -1){ return; }
-
-		var newFocusIndex = this._currentFocus.index + increment;
-		if(newFocusIndex < this._cells.length && newFocusIndex > -1){
-			var focusNode = this._cells[newFocusIndex].node;
-			this._setCurrent(focusNode);
-
-			// Actually focus the node, for the benefit of screen readers.
-			// Use setTimeout because IE doesn't like changing focus inside of an event handler
-			setTimeout(lang.hitch(dijit, "focus", focusNode), 0);
-		}
-	},
+			// record new value, or null if no matching cell
+			this._set("value", this._selectedCell >= 0 ? value : null);
 
-	_getDye: function(/*DomNode*/ cell){
-		// summary:
-		//		Get JS object for given cell DOMNode
-
-		return this._cells[cell.index].dye;
-	}
-});
-
-/*=====
-declare("dijit.Dye",
-	null,
-	{
-		// summary:
-		//		Interface for the JS Object associated with a palette cell (i.e. DOMNode)
+			if(priorityChange || priorityChange === undefined){
+				this.onChange(value);
+			}
+		},
 
-		constructor: function(alias, row, col){
+		onChange: function(/*===== value =====*/){
 			// summary:
-			//		Initialize according to value or alias like "white"
-			// alias: String
+			//		Callback when a cell is selected.
+			// value: String
+			//		Value corresponding to cell.
 		},
 
-		getValue: function(){
+		_navigateByKey: function(increment, typeCount){
 			// summary:
-			//		Return "value" of cell; meaning of "value" varies by subclass.
-			// description:
-			//		For example color hex value, emoticon ascii value etc, entity hex value.
+			//		This is the callback for typematic.
+			//		It changes the focus and the highlighed cell.
+			// increment:
+			//		How much the key is navigated.
+			// typeCount:
+			//		How many times typematic has fired.
+			// tags:
+			//		private
+
+			// typecount == -1 means the key is released.
+			if(typeCount == -1){
+				return;
+			}
+
+			var newFocusIndex = this._currentFocus.idx + increment;
+			if(newFocusIndex < this._cells.length && newFocusIndex > -1){
+				var focusNode = this._cells[newFocusIndex].node;
+				this._setCurrent(focusNode);
+
+				// Actually focus the node, for the benefit of screen readers.
+				// Use defer because IE doesn't like changing focus inside of an event handler
+				this.defer(lang.hitch(focus, "focus", focusNode));
+			}
 		},
 
-		fillCell: function(cell, blankGif){
+		_getDye: function(/*DomNode*/ cell){
 			// summary:
-			//		Add cell DOMNode inner structure
-			//	cell: DomNode
-			//		The surrounding cell
-			//	blankGif: String
-			//		URL for blank cell image
-		}
-	}
-);
-=====*/
+			//		Get JS object for given cell DOMNode
 
+			return this._cells[cell.idx].dye;
+		}
+	});
+
+	/*=====
+	 PaletteMixin.__Dye = declare("dijit.Dye", null, {
+		 // summary:
+		 //		Interface for the JS Object associated with a palette cell (i.e. DOMNode)
+
+		 constructor: function(alias, row, col){
+			 // summary:
+			 //		Initialize according to value or alias like "white"
+			 // alias: String
+		 },
+
+		 getValue: function(){
+			 // summary:
+			 //		Return "value" of cell; meaning of "value" varies by subclass.
+			 // description:
+			 //		For example color hex value, emoticon ascii value etc, entity hex value.
+		 },
+
+		 fillCell: function(cell, blankGif){
+			 // summary:
+			 //		Add cell DOMNode inner structure
+			 // cell: DomNode
+			 //		The surrounding cell
+			 // blankGif: String
+			 //		URL for blank cell image
+		 }
+	 });
+	 =====*/
+
+	return PaletteMixin;
 });
diff --git a/dijit/_Templated.js b/dijit/_Templated.js
index 22e1277..6ff132a 100644
--- a/dijit/_Templated.js
+++ b/dijit/_Templated.js
@@ -8,21 +8,14 @@ define([
 	"dojo/_base/kernel" // kernel.deprecated
 ], function(_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, array, declare, lang, kernel){
 
-/*=====
-	var _WidgetBase = dijit._WidgetBase;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
-=====*/
-
 	// module:
 	//		dijit/_Templated
-	// summary:
-	//		Deprecated mixin for widgets that are instantiated from a template.
 
 	// These arguments can be specified for widgets which are used in templates.
 	// Since any widget can be specified as sub widgets in template, mix it
 	// into the base widget class.  (This is a hack, but it's effective.)
-	lang.extend(_WidgetBase, {
+	// Remove for 2.0.   Also, hide from API doc parser.
+	lang.extend(_WidgetBase, /*===== {} || =====*/ {
 		waiRole: "",
 		waiState:""
 	});
@@ -41,31 +34,25 @@ define([
 			kernel.deprecated(this.declaredClass + ": dijit._Templated deprecated, use dijit._TemplatedMixin and if necessary dijit._WidgetsInTemplateMixin", "", "2.0");
 		},
 
-		_attachTemplateNodes: function(rootNode, getAttrFunc){
-
-			this.inherited(arguments);
+		_processNode: function(baseNode, getAttrFunc){
+			var ret = this.inherited(arguments);
 
 			// Do deprecated waiRole and waiState
-			var nodes = lang.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
-			var x = lang.isArray(rootNode) ? 0 : -1;
-			for(; x<nodes.length; x++){
-				var baseNode = (x == -1) ? rootNode : nodes[x];
-
-				// waiRole, waiState
-				var role = getAttrFunc(baseNode, "waiRole");
-				if(role){
-					baseNode.setAttribute("role", role);
-				}
-				var values = getAttrFunc(baseNode, "waiState");
-				if(values){
-					array.forEach(values.split(/\s*,\s*/), function(stateValue){
-						if(stateValue.indexOf('-') != -1){
-							var pair = stateValue.split('-');
-							baseNode.setAttribute("aria-"+pair[0], pair[1]);
-						}
-					});
-				}
+			var role = getAttrFunc(baseNode, "waiRole");
+			if(role){
+				baseNode.setAttribute("role", role);
 			}
+			var values = getAttrFunc(baseNode, "waiState");
+			if(values){
+				array.forEach(values.split(/\s*,\s*/), function(stateValue){
+					if(stateValue.indexOf('-') != -1){
+						var pair = stateValue.split('-');
+						baseNode.setAttribute("aria-"+pair[0], pair[1]);
+					}
+				});
+			}
+
+			return ret;
 		}
 	});
 });
diff --git a/dijit/_TemplatedMixin.js b/dijit/_TemplatedMixin.js
index 3171d9f..f5802f0 100644
--- a/dijit/_TemplatedMixin.js
+++ b/dijit/_TemplatedMixin.js
@@ -1,27 +1,18 @@
 define([
-	"dojo/_base/lang", // lang.getObject
-	"dojo/touch",
-	"./_WidgetBase",
-	"dojo/string", // string.substitute string.trim
 	"dojo/cache",	// dojo.cache
-	"dojo/_base/array", // array.forEach
 	"dojo/_base/declare", // declare
 	"dojo/dom-construct", // domConstruct.destroy, domConstruct.toDom
-	"dojo/_base/sniff", // has("ie")
-	"dojo/_base/unload", // unload.addOnWindowUnload
-	"dojo/_base/window" // win.doc
-], function(lang, touch, _WidgetBase, string, cache, array, declare, domConstruct, has, unload, win) {
-
-/*=====
-	var _WidgetBase = dijit._WidgetBase;
-=====*/
+	"dojo/_base/lang", // lang.getObject
+	"dojo/on",
+	"dojo/sniff", // has("ie")
+	"dojo/string", // string.substitute string.trim
+	"./_AttachMixin"
+], function(cache, declare, domConstruct, lang, on, has, string, _AttachMixin){
 
 	// module:
 	//		dijit/_TemplatedMixin
-	// summary:
-	//		Mixin for widgets that are instantiated from a template
 
-	var _TemplatedMixin = declare("dijit._TemplatedMixin", null, {
+	var _TemplatedMixin = declare("dijit._TemplatedMixin", _AttachMixin, {
 		// summary:
 		//		Mixin for widgets that are instantiated from a template
 
@@ -41,33 +32,17 @@ define([
 		//		that its template is always re-built from a string
 		_skipNodeCache: false,
 
-		// _earlyTemplatedStartup: Boolean
-		//		A fallback to preserve the 1.0 - 1.3 behavior of children in
-		//		templates having their startup called before the parent widget
-		//		fires postCreate. Defaults to 'false', causing child widgets to
-		//		have their .startup() called immediately before a parent widget
-		//		.startup(), but always after the parent .postCreate(). Set to
-		//		'true' to re-enable to previous, arguably broken, behavior.
-		_earlyTemplatedStartup: false,
-
 /*=====
-		// _attachPoints: [private] String[]
-		//		List of widget attribute names associated with data-dojo-attach-point=... in the
-		//		template, ex: ["containerNode", "labelNode"]
- 		_attachPoints: [],
- =====*/
-
-/*=====
-		// _attachEvents: [private] Handle[]
-		//		List of connections associated with data-dojo-attach-event=... in the
-		//		template
- 		_attachEvents: [],
- =====*/
+		// _rendered: Boolean
+		//		Not normally use, but this flag can be set by the app if the server has already rendered the template,
+		//		i.e. already inlining the template for the widget into the main page.   Reduces _TemplatedMixin to
+		//		just function like _AttachMixin.
+		_rendered: false,
+=====*/
 
-		constructor: function(){
-			this._attachPoints = [];
-			this._attachEvents = [];
-		},
+		// Set _AttachMixin.searchContainerNode to true for back-compat for widgets that have data-dojo-attach-point's
+		// and events inside this.containerNode.   Remove for 2.0.
+		searchContainerNode: true,
 
 		_stringRepl: function(tmpl){
 			// summary:
@@ -97,43 +72,40 @@ define([
 			// tags:
 			//		protected
 
-			if(!this.templateString){
-				this.templateString = cache(this.templatePath, {sanitize: true});
-			}
-
-			// Lookup cached version of template, and download to cache if it
-			// isn't there already.  Returns either a DomNode or a string, depending on
-			// whether or not the template contains ${foo} replacement parameters.
-			var cached = _TemplatedMixin.getCachedTemplate(this.templateString, this._skipNodeCache);
+			if(!this._rendered){
+				if(!this.templateString){
+					this.templateString = cache(this.templatePath, {sanitize: true});
+				}
 
-			var node;
-			if(lang.isString(cached)){
-				node = domConstruct.toDom(this._stringRepl(cached));
-				if(node.nodeType != 1){
-					// Flag common problems such as templates with multiple top level nodes (nodeType == 11)
-					throw new Error("Invalid template: " + cached);
+				// Lookup cached version of template, and download to cache if it
+				// isn't there already.  Returns either a DomNode or a string, depending on
+				// whether or not the template contains ${foo} replacement parameters.
+				var cached = _TemplatedMixin.getCachedTemplate(this.templateString, this._skipNodeCache, this.ownerDocument);
+
+				var node;
+				if(lang.isString(cached)){
+					node = domConstruct.toDom(this._stringRepl(cached), this.ownerDocument);
+					if(node.nodeType != 1){
+						// Flag common problems such as templates with multiple top level nodes (nodeType == 11)
+						throw new Error("Invalid template: " + cached);
+					}
+				}else{
+					// if it's a node, all we have to do is clone it
+					node = cached.cloneNode(true);
 				}
-			}else{
-				// if it's a node, all we have to do is clone it
-				node = cached.cloneNode(true);
-			}
 
-			this.domNode = node;
+				this.domNode = node;
+			}
 
-			// Call down to _Widget.buildRendering() to get base classes assigned
+			// Call down to _WidgetBase.buildRendering() to get base classes assigned
 			// TODO: change the baseClass assignment to _setBaseClassAttr
 			this.inherited(arguments);
 
-			// recurse through the node, looking for, and attaching to, our
-			// attachment points and events, which should be defined on the template node.
-			this._attachTemplateNodes(node, function(n,p){ return n.getAttribute(p); });
-
-			this._beforeFillContent();		// hook for _WidgetsInTemplateMixin
-
-			this._fillContent(this.srcNodeRef);
-		},
+			if(!this._rendered){
+				this._fillContent(this.srcNodeRef);
+			}
 
-		_beforeFillContent: function(){
+			this._rendered = true;
 		},
 
 		_fillContent: function(/*DomNode*/ source){
@@ -148,96 +120,14 @@ define([
 					dest.appendChild(source.firstChild);
 				}
 			}
-		},
-
-		_attachTemplateNodes: function(rootNode, getAttrFunc){
-			// summary:
-			//		Iterate through the template and attach functions and nodes accordingly.
-			//		Alternately, if rootNode is an array of widgets, then will process data-dojo-attach-point
-			//		etc. for those widgets.
-			// description:
-			//		Map widget properties and functions to the handlers specified in
-			//		the dom node and it's descendants. This function iterates over all
-			//		nodes and looks for these properties:
-			//			* dojoAttachPoint/data-dojo-attach-point
-			//			* dojoAttachEvent/data-dojo-attach-event
-			// rootNode: DomNode|Widget[]
-			//		the node to search for properties. All children will be searched.
-			// getAttrFunc: Function
-			//		a function which will be used to obtain property for a given
-			//		DomNode/Widget
-			// tags:
-			//		private
-
-			var nodes = lang.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*"));
-			var x = lang.isArray(rootNode) ? 0 : -1;
-			for(; x<nodes.length; x++){
-				var baseNode = (x == -1) ? rootNode : nodes[x];
-				if(this.widgetsInTemplate && (getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type"))){
-					continue;
-				}
-				// Process data-dojo-attach-point
-				var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint") || getAttrFunc(baseNode, "data-dojo-attach-point");
-				if(attachPoint){
-					var point, points = attachPoint.split(/\s*,\s*/);
-					while((point = points.shift())){
-						if(lang.isArray(this[point])){
-							this[point].push(baseNode);
-						}else{
-							this[point]=baseNode;
-						}
-						this._attachPoints.push(point);
-					}
-				}
-
-				// Process data-dojo-attach-event
-				var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent") || getAttrFunc(baseNode, "data-dojo-attach-event");
-				if(attachEvent){
-					// NOTE: we want to support attributes that have the form
-					// "domEvent: nativeEvent; ..."
-					var event, events = attachEvent.split(/\s*,\s*/);
-					var trim = lang.trim;
-					while((event = events.shift())){
-						if(event){
-							var thisFunc = null;
-							if(event.indexOf(":") != -1){
-								// oh, if only JS had tuple assignment
-								var funcNameArr = event.split(":");
-								event = trim(funcNameArr[0]);
-								thisFunc = trim(funcNameArr[1]);
-							}else{
-								event = trim(event);
-							}
-							if(!thisFunc){
-								thisFunc = event;
-							}
-							// Map "press", "move" and "release" to keys.touch, keys.move, keys.release
-							this._attachEvents.push(this.connect(baseNode, touch[event] || event, thisFunc));
-						}
-					}
-				}
-			}
-		},
-
-		destroyRendering: function(){
-			// Delete all attach points to prevent IE6 memory leaks.
-			array.forEach(this._attachPoints, function(point){
-				delete this[point];
-			}, this);
-			this._attachPoints = [];
-
-			// And same for event handlers
-			array.forEach(this._attachEvents, this.disconnect, this);
-			this._attachEvents = [];
-
-			this.inherited(arguments);
 		}
+
 	});
 
 	// key is templateString; object is either string or DOM tree
 	_TemplatedMixin._templateCache = {};
 
-	_TemplatedMixin.getCachedTemplate = function(templateString, alwaysUseString){
+	_TemplatedMixin.getCachedTemplate = function(templateString, alwaysUseString, doc){
 		// summary:
 		//		Static method to get a template based on the templatePath or
 		//		templateString key
@@ -245,6 +135,8 @@ define([
 		//		The template
 		// alwaysUseString: Boolean
 		//		Don't cache the DOM tree for this template, even if it doesn't have any variables
+		// doc: Document?
+		//		The target document.   Defaults to document global if unspecified.
 		// returns: Mixed
 		//		Either string (if there are ${} variables that need to be replaced) or just
 		//		a DOM tree (if the node can be cloned directly)
@@ -255,8 +147,9 @@ define([
 		var cached = tmplts[key];
 		if(cached){
 			try{
-				// if the cached value is an innerHTML string (no ownerDocument) or a DOM tree created within the current document, then use the current cached value
-				if(!cached.ownerDocument || cached.ownerDocument == win.doc){
+				// if the cached value is an innerHTML string (no ownerDocument) or a DOM tree created within the
+				// current document, then use the current cached value
+				if(!cached.ownerDocument || cached.ownerDocument == (doc || document)){
 					// string or node of the same document
 					return cached;
 				}
@@ -271,7 +164,7 @@ define([
 			return (tmplts[key] = templateString); //String
 		}else{
 			// there are no variables in the template so we can cache the DOM tree
-			var node = domConstruct.toDom(templateString);
+			var node = domConstruct.toDom(templateString, doc);
 			if(node.nodeType != 1){
 				throw new Error("Invalid template: " + templateString);
 			}
@@ -280,7 +173,7 @@ define([
 	};
 
 	if(has("ie")){
-		unload.addOnWindowUnload(function(){
+		on(window, "unload", function(){
 			var cache = _TemplatedMixin._templateCache;
 			for(var key in cache){
 				var value = cache[key];
@@ -292,13 +185,5 @@ define([
 		});
 	}
 
-	// These arguments can be specified for widgets which are used in templates.
-	// Since any widget can be specified as sub widgets in template, mix it
-	// into the base widget class.  (This is a hack, but it's effective.)
-	lang.extend(_WidgetBase,{
-		dojoAttachEvent: "",
-		dojoAttachPoint: ""
-	});
-
 	return _TemplatedMixin;
 });
diff --git a/dijit/_TimePicker.js b/dijit/_TimePicker.js
index 2ccdfe8..fde8d47 100644
--- a/dijit/_TimePicker.js
+++ b/dijit/_TimePicker.js
@@ -6,59 +6,26 @@ define([
 	"dojo/_base/declare", // declare
 	"dojo/dom-class", // domClass.add domClass.contains domClass.toggle
 	"dojo/dom-construct", // domConstruct.create
-	"dojo/_base/event", // event.stop
 	"dojo/_base/kernel", // deprecated
 	"dojo/keys", // keys
 	"dojo/_base/lang", // lang.mixin
-	"dojo/_base/sniff", // has("ie")
+	"dojo/sniff", // has(...)
 	"dojo/query", // query
-	"dijit/typematic",
-	"./_Widget",
-	"./_TemplatedMixin",
-	"./form/_FormValueWidget",
-	"dojo/text!./templates/TimePicker.html"
-], function(array, ddate, locale, stamp, declare, domClass, domConstruct, event, kernel, keys, lang, has, query,
-			typematic, _Widget, _TemplatedMixin, _FormValueWidget, template){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _FormValueWidget = dijit.form._FormValueWidget;
-=====*/
+	"dojo/mouse", // mouse.wheel
+	"dojo/on",
+	"./_WidgetBase",
+	"./form/_ListMouseMixin"
+], function(array, ddate, locale, stamp, declare, domClass, domConstruct, kernel, keys, lang, has, query, mouse, on,
+			_WidgetBase, _ListMouseMixin){
 
 	// module:
 	//		dijit/_TimePicker
-	// summary:
-	//		A graphical time picker.
 
 
-	/*=====
-	declare(
-		"dijit._TimePicker.__Constraints",
-		locale.__FormatOptions,
-		{
-			// clickableIncrement: String
-			//		See `dijit._TimePicker.clickableIncrement`
-			clickableIncrement: "T00:15:00",
-
-			// visibleIncrement: String
-			//		See `dijit._TimePicker.visibleIncrement`
-			visibleIncrement: "T01:00:00",
-
-			// visibleRange: String
-			//		See `dijit._TimePicker.visibleRange`
-			visibleRange: "T05:00:00"
-		}
-	);
-	=====*/
-
-	return declare("dijit._TimePicker", [_Widget, _TemplatedMixin], {
+	var TimePicker = declare("dijit._TimePicker", [_WidgetBase, _ListMouseMixin], {
 		// summary:
-		//		A graphical time picker.
-		//		This widget is used internally by other widgets and is not available
-		//		as a standalone widget due to lack of accessibility support.
-
-		templateString: template,
+		//		A time picker dropdown, used by dijit/form/TimeTextBox.
+		//		This widget is not available as a standalone widget due to lack of accessibility support.
 
 		// baseClass: [protected] String
 		//		The root className to use for the various states of this widget
@@ -69,7 +36,7 @@ define([
 		//		every clickable element in the time picker increases.
 		//		Set in local time, without a time zone.
 		//		Example: `T00:15:00` creates 15 minute increments
-		//		Must divide dijit._TimePicker.visibleIncrement evenly
+		//		Must divide dijit/_TimePicker.visibleIncrement evenly
 		clickableIncrement: "T00:15:00",
 
 		// visibleIncrement: String
@@ -79,12 +46,6 @@ define([
 		//		Example: `T01:00:00` creates text in every 1 hour increment
 		visibleIncrement: "T01:00:00",
 
-		// visibleRange: String
-		//		ISO-8601 string representing the range of this TimePicker.
-		//		The TimePicker will only display times in this range.
-		//		Example: `T05:00:00` displays 5 hours of options
-		visibleRange: "T05:00:00",
-
 		// value: String
 		//		Date to display.
 		//		Defaults to current time and date.
@@ -101,32 +62,38 @@ define([
 		//		Example: `2007-06-01T09:00:00`
 		value: new Date(),
 
-		_visibleIncrement:2,
-		_clickableIncrement:1,
-		_totalIncrements:10,
+		_visibleIncrement: 2,
+		_clickableIncrement: 1,
+		_totalIncrements: 10,
 
-		// constraints: dijit._TimePicker.__Constraints
+		// constraints: TimePicker.__Constraints
 		//		Specifies valid range of times (start time, end time)
-		constraints:{},
-
-/*=====
-		serialize: function(val, options){
-			// summary:
-			//		User overridable function used to convert the attr('value') result to a String
-			// val: Date
-			//		The current value
-			// options: Object?
-			// tags:
-			//		protected
-		},
-=====*/
+		constraints: {},
+
+		/*=====
+		 serialize: function(val, options){
+			 // summary:
+			 //		User overridable function used to convert the attr('value') result to a String
+			 // val: Date
+			 //		The current value
+			 // options: Object?
+			 // tags:
+			 //		protected
+		 },
+		 =====*/
 		serialize: stamp.toISOString,
 
-/*=====
-		// filterString: string
-		//		The string to filter by
-		filterString: "",
-=====*/
+		/*=====
+		 // filterString: string
+		 //		The string to filter by
+		 filterString: "",
+		 =====*/
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.containerNode = this.domNode;	// expected by _ListBase
+			this.timeMenu = this.domNode;	// for back-compat
+		},
 
 		setValue: function(/*Date*/ value){
 			// summary:
@@ -166,7 +133,7 @@ define([
 			return false; // Boolean
 		},
 
-		_getFilteredNodes: function(/*number*/ start, /*number*/ maxNum, /*Boolean*/ before, /*DOMnode*/ lastNode){
+		_getFilteredNodes: function(/*number*/ start, /*number*/ maxNum, /*Boolean*/ before, /*DOMNode*/ lastNode){
 			// summary:
 			//		Returns an array of nodes with the filter applied.  At most maxNum nodes
 			//		will be returned - but fewer may be returned as well.  If the
@@ -174,27 +141,15 @@ define([
 			//		before the given index
 			// tags:
 			//		private
-			var
-				nodes = [],
-				lastValue = lastNode ? lastNode.date : this._refDate,
-				n,
-				i = start,
-				max = this._maxIncrement + Math.abs(i),
-				chk = before ? -1 : 1,
-				dec = before ? 1 : 0,
-				inc = 1 - dec;
-			do{
-				i -= dec;
-				n = this._createOption(i);
+
+			var nodes = [];
+
+			for(var i = 0 ; i < this._maxIncrement; i++){
+				var n = this._createOption(i);
 				if(n){
-					if((before && n.date > lastValue) || (!before && n.date < lastValue)){
-						break; // don't wrap
-					}
-					nodes[before ? "unshift" : "push"](n);
-					lastValue = n.date;
+					nodes.push(n);
 				}
-				i += inc;
-			}while(nodes.length < maxNum && (i*chk) < max);
+			}
 			return nodes;
 		},
 
@@ -204,29 +159,26 @@ define([
 			// tags:
 			//		private
 			var fromIso = stamp.fromISOString;
-			this.timeMenu.innerHTML = "";
-			this._clickableIncrementDate=fromIso(this.clickableIncrement);
-			this._visibleIncrementDate=fromIso(this.visibleIncrement);
-			this._visibleRangeDate=fromIso(this.visibleRange);
-			// get the value of the increments and the range in seconds (since 00:00:00) to find out how many divs to create
+			this.domNode.innerHTML = "";
+			this._clickableIncrementDate = fromIso(this.clickableIncrement);
+			this._visibleIncrementDate = fromIso(this.visibleIncrement);
+			// get the value of the increments to find out how many divs to create
 			var
 				sinceMidnight = function(/*Date*/ date){
 					return date.getHours() * 60 * 60 + date.getMinutes() * 60 + date.getSeconds();
 				},
 				clickableIncrementSeconds = sinceMidnight(this._clickableIncrementDate),
 				visibleIncrementSeconds = sinceMidnight(this._visibleIncrementDate),
-				visibleRangeSeconds = sinceMidnight(this._visibleRangeDate),
 				// round reference date to previous visible increment
 				time = (this.value || this.currentFocus).getTime();
 
-			this._refDate = new Date(time - time % (clickableIncrementSeconds*1000));
-			this._refDate.setFullYear(1970,0,1); // match parse defaults
+			this._refDate = fromIso("T00:00:00");
+			this._refDate.setFullYear(1970, 0, 1); // match parse defaults
 
 			// assume clickable increment is the smallest unit
 			this._clickableIncrement = 1;
 			// divide the visible range by the clickable increment to get the number of divs to create
 			// example: 10:00:00/00:15:00 -> display 40 divs
-			this._totalIncrements = visibleRangeSeconds / clickableIncrementSeconds;
 			// divide the visible increments by the clickable increments to get how often to display the time inline
 			// example: 01:00:00/00:15:00 -> display the time every 4 divs
 			this._visibleIncrement = visibleIncrementSeconds / clickableIncrementSeconds;
@@ -234,22 +186,29 @@ define([
 			// absolute max number of increments.
 			this._maxIncrement = (60 * 60 * 24) / clickableIncrementSeconds;
 
-			var
-				// Find the nodes we should display based on our filter.
-				// Limit to 10 nodes displayed as a half-hearted attempt to stop drop down from overlapping <input>.
-				count = Math.min(this._totalIncrements, 10),
-				after = this._getFilteredNodes(0, (count >> 1) + 1, false),
-				moreAfter = [],
-				estBeforeLength = count - after.length,
-				before = this._getFilteredNodes(0, estBeforeLength, true, after[0]);
-				if(before.length < estBeforeLength && after.length > 0){
-					moreAfter = this._getFilteredNodes(after.length, estBeforeLength - before.length, false, after[after.length-1]);
-				}
-			array.forEach(before.concat(after, moreAfter), function(n){ this.timeMenu.appendChild(n); }, this);
+			var nodes  = this._getFilteredNodes();
+			array.forEach(nodes, function(n){
+				this.domNode.appendChild(n);
+			}, this);
+
+			// never show empty due to a bad filter
+			if(!nodes.length && this.filterString){
+				this.filterString = '';
+				this._showText();
+			}
 		},
 
-		constructor: function(){
-			this.constraints = {}; // create instance object
+		constructor: function(/*===== params, srcNodeRef =====*/){
+			// summary:
+			//		Create the widget.
+			// params: Object|null
+			//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+			//		and functions, typically callbacks like onClick.
+			//		The hash can contain any of the widget's properties, excluding read-only properties.
+			// srcNodeRef: DOMNode|String?
+			//		If a srcNodeRef (DOM node) is specified, replace srcNodeRef with my generated DOM tree
+
+			this.constraints = {};
 		},
 
 		postMixInProperties: function(){
@@ -258,8 +217,10 @@ define([
 		},
 
 		_setConstraintsAttr: function(/* Object */ constraints){
-			// brings in visibleRange, increments, etc.
-			lang.mixin(this, constraints);
+			// brings in increments, etc.
+			for(var key in constraints){
+				this._set(key, constraints[key]);
+			}
 
 			// locale needs the lang in the constraints as locale
 			if(!constraints.locale){
@@ -267,39 +228,19 @@ define([
 			}
 		},
 
-		postCreate: function(){
-			// assign typematic mouse listeners to the arrow buttons
-			this.connect(this.timeMenu, has("ie") ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
-			this._connects.push(typematic.addMouseListener(this.upArrow, this, "_onArrowUp", 33, 250));
-			this._connects.push(typematic.addMouseListener(this.downArrow, this, "_onArrowDown", 33, 250));
-
-			this.inherited(arguments);
-		},
-
-		_buttonMouse: function(/*Event*/ e){
-			// summary:
-			//		Handler for hover (and unhover) on up/down arrows
-			// tags:
-			//		private
-
-			// in non-IE browser the "mouseenter" event will become "mouseover",
-			// but in IE it's still "mouseenter"
-			domClass.toggle(e.currentTarget, e.currentTarget == this.upArrow ? "dijitUpArrowHover" : "dijitDownArrowHover",
-				e.type == "mouseenter" || e.type == "mouseover");
-		},
-
 		_createOption: function(/*Number*/ index){
 			// summary:
-			//		Creates a clickable time option
+			//		Creates a clickable time option, or returns null if the specified index doesn't match the filter
 			// tags:
 			//		private
 			var date = new Date(this._refDate);
 			var incrementDate = this._clickableIncrementDate;
-			date.setHours(date.getHours() + incrementDate.getHours() * index,
-				date.getMinutes() + incrementDate.getMinutes() * index,
-				date.getSeconds() + incrementDate.getSeconds() * index);
+			date.setTime(date.getTime()
+				+ incrementDate.getHours() * index * 3600000
+				+ incrementDate.getMinutes() * index * 60000
+				+ incrementDate.getSeconds() * index * 1000);
 			if(this.constraints.selector == "time"){
-				date.setFullYear(1970,0,1); // make sure each time is for the same date
+				date.setFullYear(1970, 0, 1); // make sure each time is for the same date
 			}
 			var dateString = locale.format(date, this.constraints);
 			if(this.filterString && dateString.toLowerCase().indexOf(this.filterString) !== 0){
@@ -307,31 +248,33 @@ define([
 				return null;
 			}
 
-			var div = domConstruct.create("div", {"class": this.baseClass+"Item"});
+			var div = this.ownerDocument.createElement("div");
+			div.className = this.baseClass + "Item";
 			div.date = date;
-			div.index = index;
-			domConstruct.create('div',{
+			div.idx = index;
+			domConstruct.create('div', {
 				"class": this.baseClass + "ItemInner",
 				innerHTML: dateString
 			}, div);
 
-			if(index%this._visibleIncrement<1 && index%this._visibleIncrement>-1){
-				domClass.add(div, this.baseClass+"Marker");
-			}else if(!(index%this._clickableIncrement)){
-				domClass.add(div, this.baseClass+"Tick");
+			if(index % this._visibleIncrement < 1 && index % this._visibleIncrement > -1){
+				domClass.add(div, this.baseClass + "Marker");
+			}else if(!(index % this._clickableIncrement)){
+				domClass.add(div, this.baseClass + "Tick");
 			}
 
 			if(this.isDisabledDate(date)){
 				// set disabled
-				domClass.add(div, this.baseClass+"ItemDisabled");
+				domClass.add(div, this.baseClass + "ItemDisabled");
 			}
 			if(this.value && !ddate.compare(this.value, date, this.constraints.selector)){
 				div.selected = true;
-				domClass.add(div, this.baseClass+"ItemSelected");
-				if(domClass.contains(div, this.baseClass+"Marker")){
-					domClass.add(div, this.baseClass+"MarkerSelected");
+				domClass.add(div, this.baseClass + "ItemSelected");
+				this._selectedDiv = div;
+				if(domClass.contains(div, this.baseClass + "Marker")){
+					domClass.add(div, this.baseClass + "MarkerSelected");
 				}else{
-					domClass.add(div, this.baseClass+"TickSelected");
+					domClass.add(div, this.baseClass + "TickSelected");
 				}
 
 				// Initially highlight the current value.   User can change highlight by up/down arrow keys
@@ -341,13 +284,22 @@ define([
 			return div;
 		},
 
+		onOpen: function(){
+			this.inherited(arguments);
+
+			// Since _ListBase::_setSelectedAttr() calls scrollIntoView(), shouldn't call it until list is visible.
+			this.set("selected", this._selectedDiv);
+		},
+
 		_onOptionSelected: function(/*Object*/ tgt){
 			// summary:
 			//		Called when user clicks an option in the drop down list
 			// tags:
 			//		private
 			var tdate = tgt.target.date || tgt.target.parentNode.date;
-			if(!tdate || this.isDisabledDate(tdate)){ return; }
+			if(!tdate || this.isDisabledDate(tdate)){
+				return;
+			}
 			this._highlighted_option = null;
 			this.set('value', tdate);
 			this.onChange(tdate);
@@ -357,7 +309,7 @@ define([
 			// summary:
 			//		Notification that a time was selected.  It may be the same as the previous value.
 			// tags:
-			//      public
+			//		public
 		},
 
 		_highlightOption: function(/*node*/ node, /*Boolean*/ highlight){
@@ -365,7 +317,9 @@ define([
 			//		Turns on/off highlight effect on a node based on mouse out/over event
 			// tags:
 			//		private
-			if(!node){return;}
+			if(!node){
+				return;
+			}
 			if(highlight){
 				if(this._highlighted_option){
 					this._highlightOption(this._highlighted_option, false);
@@ -376,116 +330,33 @@ define([
 			}else{
 				this._highlighted_option = null;
 			}
-			domClass.toggle(node, this.baseClass+"ItemHover", highlight);
-			if(domClass.contains(node, this.baseClass+"Marker")){
-				domClass.toggle(node, this.baseClass+"MarkerHover", highlight);
+			domClass.toggle(node, this.baseClass + "ItemHover", highlight);
+			if(domClass.contains(node, this.baseClass + "Marker")){
+				domClass.toggle(node, this.baseClass + "MarkerHover", highlight);
 			}else{
-				domClass.toggle(node, this.baseClass+"TickHover", highlight);
-			}
-		},
-
-		onmouseover: function(/*Event*/ e){
-			// summary:
-			//		Handler for onmouseover event
-			// tags:
-			//		private
-			this._keyboardSelected = null;
-			var tgr = (e.target.parentNode === this.timeMenu) ? e.target : e.target.parentNode;
-			// if we aren't targeting an item, then we return
-			if(!domClass.contains(tgr, this.baseClass+"Item")){return;}
-			this._highlightOption(tgr, true);
-		},
-
-		onmouseout: function(/*Event*/ e){
-			// summary:
-			//		Handler for onmouseout event
-			// tags:
-			//		private
-			this._keyboardSelected = null;
-			var tgr = (e.target.parentNode === this.timeMenu) ? e.target : e.target.parentNode;
-			this._highlightOption(tgr, false);
-		},
-
-		_mouseWheeled: function(/*Event*/ e){
-			// summary:
-			//		Handle the mouse wheel events
-			// tags:
-			//		private
-			this._keyboardSelected = null;
-			event.stop(e);
-			// we're not _measuring_ the scroll amount, just direction
-			var scrollAmount = (has("ie") ? e.wheelDelta : -e.detail);
-			this[(scrollAmount>0 ? "_onArrowUp" : "_onArrowDown")](); // yes, we're making a new dom node every time you mousewheel, or click
-		},
-
-		_onArrowUp: function(count){
-			// summary:
-			//		Handler for up arrow key.
-			// description:
-			//		Removes the bottom time and add one to the top
-			// tags:
-			//		private
-			if(typeof count == "number" && count == -1){ return; } // typematic end
-			if(!this.timeMenu.childNodes.length){ return; }
-			var index = this.timeMenu.childNodes[0].index;
-			var divs = this._getFilteredNodes(index, 1, true, this.timeMenu.childNodes[0]);
-			if(divs.length){
-				this.timeMenu.removeChild(this.timeMenu.childNodes[this.timeMenu.childNodes.length - 1]);
-				this.timeMenu.insertBefore(divs[0], this.timeMenu.childNodes[0]);
-			}
-		},
-
-		_onArrowDown: function(count){
-			// summary:
-			//		Handler for up arrow key.
-			// description:
-			//		Remove the top time and add one to the bottom
-			// tags:
-			//		private
-			if(typeof count == "number" && count == -1){ return; } // typematic end
-			if(!this.timeMenu.childNodes.length){ return; }
-			var index = this.timeMenu.childNodes[this.timeMenu.childNodes.length - 1].index + 1;
-			var divs = this._getFilteredNodes(index, 1, false, this.timeMenu.childNodes[this.timeMenu.childNodes.length - 1]);
-			if(divs.length){
-				this.timeMenu.removeChild(this.timeMenu.childNodes[0]);
-				this.timeMenu.appendChild(divs[0]);
+				domClass.toggle(node, this.baseClass + "TickHover", highlight);
 			}
 		},
 
 		handleKey: function(/*Event*/ e){
 			// summary:
-			//		Called from `dijit.form._DateTimeTextBox` to pass a keypress event
-			//		from the `dijit.form.TimeTextBox` to be handled in this widget
+			//		Called from `dijit/form/_DateTimeTextBox` to pass a keypress event
+			//		from the `dijit/form/TimeTextBox` to be handled in this widget
 			// tags:
 			//		protected
-			if(e.charOrCode == keys.DOWN_ARROW || e.charOrCode == keys.UP_ARROW){
-				event.stop(e);
-				// Figure out which option to highlight now and then highlight it
-				if(this._highlighted_option && !this._highlighted_option.parentNode){
-					this._highlighted_option = null;
-				}
-				var timeMenu = this.timeMenu,
-					tgt = this._highlighted_option || query("." + this.baseClass + "ItemSelected", timeMenu)[0];
-				if(!tgt){
-					tgt = timeMenu.childNodes[0];
-				}else if(timeMenu.childNodes.length){
-					if(e.charOrCode == keys.DOWN_ARROW && !tgt.nextSibling){
-						this._onArrowDown();
-					}else if(e.charOrCode == keys.UP_ARROW && !tgt.previousSibling){
-						this._onArrowUp();
-					}
-					if(e.charOrCode == keys.DOWN_ARROW){
-						tgt = tgt.nextSibling;
-					}else{
-						tgt = tgt.previousSibling;
-					}
-				}
-				this._highlightOption(tgt, true);
-				this._keyboardSelected = tgt;
+			if(e.keyCode == keys.DOWN_ARROW){
+				this.selectNextNode();
+				e.stopPropagation();
+				e.preventDefault();
+				return false;
+			}else if(e.keyCode == keys.UP_ARROW){
+				this.selectPreviousNode();
+				e.stopPropagation();
+				e.preventDefault();
 				return false;
-			}else if(e.charOrCode == keys.ENTER || e.charOrCode === keys.TAB){
+			}else if(e.keyCode == keys.ENTER || e.keyCode === keys.TAB){
 				// mouse hover followed by TAB is NO selection
-				if(!this._keyboardSelected && e.charOrCode === keys.TAB){
+				if(!this._keyboardSelected && e.keyCode === keys.TAB){
 					return true;	// true means don't call stopEvent()
 				}
 
@@ -496,9 +367,40 @@ define([
 
 				// Call stopEvent() for ENTER key so that form doesn't submit,
 				// but not for TAB, so that TAB does switch focus
-				return e.charOrCode === keys.TAB;
+				return e.keyCode === keys.TAB;
 			}
 			return undefined;
+		},
+
+		// Implement abstract methods for _ListBase
+		onHover: function(/*DomNode*/ node){
+			this._highlightOption(node, true);
+		},
+
+		onUnhover: function(/*DomNode*/ node){
+			this._highlightOption(node, false);
+		},
+
+		onSelect: function(/*DomNode*/ node){
+			this._highlightOption(node, true);
+		},
+
+		onDeselect: function(/*DomNode*/ node){
+			this._highlightOption(node, false);
+		},
+
+		onClick: function(/*DomNode*/ node){
+			this._onOptionSelected({target: node});
 		}
 	});
+
+	/*=====
+	 TimePicker.__Constraints = declare(locale.__FormatOptions, {
+		 // clickableIncrement: String
+		 //		See `dijit/_TimePicker.clickableIncrement`
+		 clickableIncrement: "T00:15:00"
+	 });
+	 =====*/
+
+	return TimePicker;
 });
diff --git a/dijit/_Widget.js b/dijit/_Widget.js
index 1b5f64d..75d9c3d 100644
--- a/dijit/_Widget.js
+++ b/dijit/_Widget.js
@@ -3,6 +3,7 @@ define([
 	"dojo/_base/config",	// config.isDebug
 	"dojo/_base/connect",	// connect.connect
 	"dojo/_base/declare", // declare
+	"dojo/has",
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/_base/lang", // lang.hitch
 	"dojo/query",
@@ -13,20 +14,12 @@ define([
 	"./_FocusMixin",
 	"dojo/uacss",		// browser sniffing (included for back-compat; subclasses may be using)
 	"./hccss"		// high contrast mode sniffing (included to set CSS classes on <body>, module ret value unused)
-], function(aspect, config, connect, declare, kernel, lang, query, ready,
+], function(aspect, config, connect, declare, has, kernel, lang, query, ready,
 			registry, _WidgetBase, _OnDijitClickMixin, _FocusMixin){
 
-/*=====
-	var _WidgetBase = dijit._WidgetBase;
-	var _OnDijitClickMixin = dijit._OnDijitClickMixin;
-	var _FocusMixin = dijit._FocusMixin;
-=====*/
-
 
 // module:
 //		dijit/_Widget
-// summary:
-//		Old base for widgets.   New widgets should extend _WidgetBase instead
 
 
 function connectToDomNode(){
@@ -51,22 +44,26 @@ if(kernel.connect){
 
 var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusMixin], {
 	// summary:
-	//		Base class for all Dijit widgets.
+	//		Old base class for widgets.   New widgets should extend `dijit/_WidgetBase` instead
+	// description:
+	//		Old Base class for Dijit widgets.
 	//
 	//		Extends _WidgetBase, adding support for:
-	//			- declaratively/programatically specifying widget initialization parameters like
-	//				onMouseMove="foo" that call foo when this.domNode gets a mousemove event
-	//			- ondijitclick
-	//				Support new data-dojo-attach-event="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress
-	//			- focus related functions
-	//				In particular, the onFocus()/onBlur() callbacks.   Driven internally by
-	//				dijit/_base/focus.js.
-	//			- deprecated methods
-	//			- onShow(), onHide(), onClose()
+	//
+	//		- declaratively/programatically specifying widget initialization parameters like
+	//			onMouseMove="foo" that call foo when this.domNode gets a mousemove event
+	//		- ondijitclick:
+	//			Support new data-dojo-attach-event="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress
+	//		- focus related functions:
+	//			In particular, the onFocus()/onBlur() callbacks.   Driven internally by
+	//			dijit/_base/focus.js.
+	//		- deprecated methods
+	//		- onShow(), onHide(), onClose()
 	//
 	//		Also, by loading code in dijit/_base, turns on:
-	//			- browser sniffing (putting browser id like .dj_ie on <html> node)
-	//			- high contrast mode sniffing (add .dijit_a11y class to <body> if machine is in high contrast mode)
+	//
+	//		- browser sniffing (putting browser class like `dj_ie` on `<html>` node)
+	//		- high contrast mode sniffing (add `dijit_a11y` class to `<body>` if machine is in high contrast mode)
 
 
 	////////////////// DEFERRED CONNECTS ///////////////////
@@ -204,7 +201,20 @@ var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusM
 	},
 	=====*/
 
-	constructor: function(params){
+	constructor: function(params /*===== ,srcNodeRef =====*/){
+		// summary:
+		//		Create the widget.
+		// params: Object|null
+		//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+		//		and functions, typically callbacks like onClick.
+		//		The hash can contain any of the widget's properties, excluding read-only properties.
+		// srcNodeRef: DOMNode|String?
+		//		If a srcNodeRef (DOM node) is specified:
+		//
+		//		- use srcNodeRef.innerHTML as my contents
+		//		- if this is a behavioral widget then apply behavior to that srcNodeRef
+		//		- otherwise, replace srcNodeRef with my generated DOM tree
+
 		// extract parameters like onMouseMove that should connect directly to this.domNode
 		this._toConnect = {};
 		for(var name in params){
@@ -225,10 +235,12 @@ var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusM
 		delete this._toConnect;
 	},
 
-	on: function(/*String*/ type, /*Function*/ func){
+	on: function(/*String|Function*/ type, /*Function*/ func){
 		if(this[this._onMap(type)] === connectToDomNode){
-			// Use connect.connect() rather than on() to get handling for "onmouseenter" on non-IE, etc.
+			// Use connect.connect() rather than on() to get handling for "onmouseenter" on non-IE,
+			// normalization of onkeypress/onkeydown to behave like firefox, etc.
 			// Also, need to specify context as "this" rather than the default context of the DOMNode
+			// Remove in 2.0.
 			return connect.connect(this.domNode, type.toLowerCase(), this, func);
 		}
 		return this.inherited(arguments);
@@ -255,11 +267,11 @@ var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusM
 	attr: function(/*String|Object*/name, /*Object?*/value){
 		// summary:
 		//		Set or get properties on a widget instance.
-		//	name:
+		// name:
 		//		The property to get or set. If an object is passed here and not
 		//		a string, its keys are used as names of attributes to be set
 		//		and the value of the object as values to set in the widget.
-		//	value:
+		// value:
 		//		Optional. If provided, attr() operates as a setter. If omitted,
 		//		the current value of the named property is returned.
 		// description:
@@ -291,7 +303,7 @@ var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusM
 		//		supposed to be internal/hidden, but it's left here for back-compat reasons.
 
 		kernel.deprecated(this.declaredClass+"::getDescendants() is deprecated. Use getChildren() instead.", "", "2.0");
-		return this.containerNode ? query('[widgetId]', this.containerNode).map(registry.byNode) : []; // dijit._Widget[]
+		return this.containerNode ? query('[widgetId]', this.containerNode).map(registry.byNode) : []; // dijit/_WidgetBase[]
 	},
 
 	////////////////// MISCELLANEOUS METHODS ///////////////////
@@ -306,8 +318,8 @@ var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusM
 	onShow: function(){
 		// summary:
 		//		Called when this widget becomes the selected pane in a
-		//		`dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
-		//		`dijit.layout.AccordionContainer`, etc.
+		//		`dijit/layout/TabContainer`, `dijit/layout/StackContainer`,
+		//		`dijit/layout/AccordionContainer`, etc.
 		//
 		//		Also called to indicate display of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
 		// tags:
@@ -316,13 +328,13 @@ var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusM
 
 	onHide: function(){
 		// summary:
-			//		Called when another widget becomes the selected pane in a
-			//		`dijit.layout.TabContainer`, `dijit.layout.StackContainer`,
-			//		`dijit.layout.AccordionContainer`, etc.
-			//
-			//		Also called to indicate hide of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
-			// tags:
-			//		callback
+		//		Called when another widget becomes the selected pane in a
+		//		`dijit/layout/TabContainer`, `dijit/layout/StackContainer`,
+		//		`dijit/layout/AccordionContainer`, etc.
+		//
+		//		Also called to indicate hide of a `dijit.Dialog`, `dijit.TooltipDialog`, or `dijit.TitlePane`.
+		// tags:
+		//		callback
 	},
 
 	onClose: function(){
@@ -331,7 +343,7 @@ var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusM
 		//		up from a DateTextBox), and it is hidden.
 		//		This is called from the dijit.popup code, and should not be called directly.
 		//
-		//		Also used as a parameter for children of `dijit.layout.StackContainer` or subclasses.
+		//		Also used as a parameter for children of `dijit/layout/StackContainer` or subclasses.
 		//		Callback if a user tries to close the child.   Child will be closed if this function returns true.
 		// tags:
 		//		extension
@@ -341,7 +353,7 @@ var _Widget = declare("dijit._Widget", [_WidgetBase, _OnDijitClickMixin, _FocusM
 });
 
 // For back-compat, remove in 2.0.
-if(!kernel.isAsync){
+if(has("dijit-legacy-requires")){
 	ready(0, function(){
 		var requires = ["dijit/_base"];
 		require(requires);	// use indirection so modules not rolled into a build
diff --git a/dijit/_WidgetBase.js b/dijit/_WidgetBase.js
index fa269bb..557cba3 100644
--- a/dijit/_WidgetBase.js
+++ b/dijit/_WidgetBase.js
@@ -1,5 +1,5 @@
 define([
-	"require",			// require.toUrl
+	"require", // require.toUrl
 	"dojo/_base/array", // array.forEach array.map
 	"dojo/aspect",
 	"dojo/_base/config", // config.blankGif
@@ -8,984 +8,1177 @@ define([
 	"dojo/dom", // dom.byId
 	"dojo/dom-attr", // domAttr.set domAttr.remove
 	"dojo/dom-class", // domClass.add domClass.replace
-	"dojo/dom-construct", // domConstruct.create domConstruct.destroy domConstruct.place
-	"dojo/dom-geometry",	// isBodyLtr
+	"dojo/dom-construct", // domConstruct.destroy domConstruct.place
+	"dojo/dom-geometry", // isBodyLtr
 	"dojo/dom-style", // domStyle.set, domStyle.get
+	"dojo/has",
 	"dojo/_base/kernel",
 	"dojo/_base/lang", // mixin(), isArray(), etc.
 	"dojo/on",
 	"dojo/ready",
 	"dojo/Stateful", // Stateful
 	"dojo/topic",
-	"dojo/_base/window", // win.doc.createTextNode
-	"./registry"	// registry.getUniqueId(), registry.findWidgets()
+	"dojo/_base/window", // win.body()
+	"./Destroyable",
+	"dojo/has!dojo-bidi?./_BidiMixin",
+	"./registry"    // registry.getUniqueId(), registry.findWidgets()
 ], function(require, array, aspect, config, connect, declare,
-			dom, domAttr, domClass, domConstruct, domGeometry, domStyle, kernel,
-			lang, on, ready, Stateful, topic, win, registry){
-
-/*=====
-var Stateful = dojo.Stateful;
-=====*/
-
-// module:
-//		dijit/_WidgetBase
-// summary:
-//		Future base class for all Dijit widgets.
-
-// For back-compat, remove in 2.0.
-if(!kernel.isAsync){
-	ready(0, function(){
-		var requires = ["dijit/_base/manager"];
-		require(requires);	// use indirection so modules not rolled into a build
-	});
-}
-
-// Nested hash listing attributes for each tag, all strings in lowercase.
-// ex: {"div": {"style": true, "tabindex" true}, "form": { ...
-var tagAttrs = {};
-function getAttrs(obj){
-	var ret = {};
-	for(var attr in obj){
-		ret[attr.toLowerCase()] = true;
-	}
-	return ret;
-}
-
-function nonEmptyAttrToDom(attr){
-	// summary:
-	//		Returns a setter function that copies the attribute to this.domNode,
-	//		or removes the attribute from this.domNode, depending on whether the
-	//		value is defined or not.
-	return function(val){
-		domAttr[val ? "set" : "remove"](this.domNode, attr, val);
-		this._set(attr, val);
-	};
-}
-
-return declare("dijit._WidgetBase", Stateful, {
-	// summary:
-	//		Future base class for all Dijit widgets.
-	// description:
-	//		Future base class for all Dijit widgets.
-	//		_Widget extends this class adding support for various features needed by desktop.
-	//
-	//		Provides stubs for widget lifecycle methods for subclasses to extend, like postMixInProperties(), buildRendering(),
-	//		postCreate(), startup(), and destroy(), and also public API methods like set(), get(), and watch().
-	//
-	//		Widgets can provide custom setters/getters for widget attributes, which are called automatically by set(name, value).
-	//		For an attribute XXX, define methods _setXXXAttr() and/or _getXXXAttr().
-	//
-	//		_setXXXAttr can also be a string/hash/array mapping from a widget attribute XXX to the widget's DOMNodes:
-	//
-	//		- DOM node attribute
-	// |		_setFocusAttr: {node: "focusNode", type: "attribute"}
-	// |		_setFocusAttr: "focusNode"	(shorthand)
-	// |		_setFocusAttr: ""		(shorthand, maps to this.domNode)
-	// 		Maps this.focus to this.focusNode.focus, or (last example) this.domNode.focus
-	//
-	//		- DOM node innerHTML
-	//	|		_setTitleAttr: { node: "titleNode", type: "innerHTML" }
-	//		Maps this.title to this.titleNode.innerHTML
-	//
-	//		- DOM node innerText
-	//	|		_setTitleAttr: { node: "titleNode", type: "innerText" }
-	//		Maps this.title to this.titleNode.innerText
-	//
-	//		- DOM node CSS class
-	// |		_setMyClassAttr: { node: "domNode", type: "class" }
-	//		Maps this.myClass to this.domNode.className
-	//
-	//		If the value of _setXXXAttr is an array, then each element in the array matches one of the
-	//		formats of the above list.
-	//
-	//		If the custom setter is null, no action is performed other than saving the new value
-	//		in the widget (in this).
-	//
-	//		If no custom setter is defined for an attribute, then it will be copied
-	//		to this.focusNode (if the widget defines a focusNode), or this.domNode otherwise.
-	//		That's only done though for attributes that match DOMNode attributes (title,
-	//		alt, aria-labelledby, etc.)
-
-	// id: [const] String
-	//		A unique, opaque ID string that can be assigned by users or by the
-	//		system. If the developer passes an ID which is known not to be
-	//		unique, the specified ID is ignored and the system-generated ID is
-	//		used instead.
-	id: "",
-	_setIdAttr: "domNode",	// to copy to this.domNode even for auto-generated id's
-
-	// lang: [const] String
-	//		Rarely used.  Overrides the default Dojo locale used to render this widget,
-	//		as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
-	//		Value must be among the list of locales specified during by the Dojo bootstrap,
-	//		formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
-	lang: "",
-	// set on domNode even when there's a focus node.   but don't set lang="", since that's invalid.
-	_setLangAttr: nonEmptyAttrToDom("lang"),
-
-	// dir: [const] String
-	//		Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
-	//		attribute. Either left-to-right "ltr" or right-to-left "rtl".  If undefined, widgets renders in page's
-	//		default direction.
-	dir: "",
-	// set on domNode even when there's a focus node.   but don't set dir="", since that's invalid.
-	_setDirAttr: nonEmptyAttrToDom("dir"),	// to set on domNode even when there's a focus node
-
-	// textDir: String
-	//		Bi-directional support,	the main variable which is responsible for the direction of the text.
-	//		The text direction can be different than the GUI direction by using this parameter in creation
-	//		of a widget.
-	// 		Allowed values:
-	//			1. "ltr"
-	//			2. "rtl"
-	//			3. "auto" - contextual the direction of a text defined by first strong letter.
-	//		By default is as the page direction.
-	textDir: "",
-
-	// class: String
-	//		HTML class attribute
-	"class": "",
-	_setClassAttr: { node: "domNode", type: "class" },
-
-	// style: String||Object
-	//		HTML style attributes as cssText string or name/value hash
-	style: "",
-
-	// title: String
-	//		HTML title attribute.
-	//
-	//		For form widgets this specifies a tooltip to display when hovering over
-	//		the widget (just like the native HTML title attribute).
-	//
-	//		For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer,
-	//		etc., it's used to specify the tab label, accordion pane title, etc.
-	title: "",
-
-	// tooltip: String
-	//		When this widget's title attribute is used to for a tab label, accordion pane title, etc.,
-	//		this specifies the tooltip to appear when the mouse is hovered over that text.
-	tooltip: "",
-
-	// baseClass: [protected] String
-	//		Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate
-	//		widget state.
-	baseClass: "",
-
-	// srcNodeRef: [readonly] DomNode
-	//		pointer to original DOM node
-	srcNodeRef: null,
-
-	// domNode: [readonly] DomNode
-	//		This is our visible representation of the widget! Other DOM
-	//		Nodes may by assigned to other properties, usually through the
-	//		template system's data-dojo-attach-point syntax, but the domNode
-	//		property is the canonical "top level" node in widget UI.
-	domNode: null,
-
-	// containerNode: [readonly] DomNode
-	//		Designates where children of the source DOM node will be placed.
-	//		"Children" in this case refers to both DOM nodes and widgets.
-	//		For example, for myWidget:
-	//
-	//		|	<div data-dojo-type=myWidget>
-	//		|		<b> here's a plain DOM node
-	//		|		<span data-dojo-type=subWidget>and a widget</span>
-	//		|		<i> and another plain DOM node </i>
-	//		|	</div>
-	//
-	//		containerNode would point to:
-	//
-	//		|		<b> here's a plain DOM node
-	//		|		<span data-dojo-type=subWidget>and a widget</span>
-	//		|		<i> and another plain DOM node </i>
-	//
-	//		In templated widgets, "containerNode" is set via a
-	//		data-dojo-attach-point assignment.
-	//
-	//		containerNode must be defined for any widget that accepts innerHTML
-	//		(like ContentPane or BorderContainer or even Button), and conversely
-	//		is null for widgets that don't, like TextBox.
-	containerNode: null,
-
-/*=====
-	// _started: Boolean
-	//		startup() has completed.
-	_started: false,
-=====*/
-
-	// attributeMap: [protected] Object
-	//		Deprecated.   Instead of attributeMap, widget should have a _setXXXAttr attribute
-	//		for each XXX attribute to be mapped to the DOM.
-	//
-	//		attributeMap sets up a "binding" between attributes (aka properties)
-	//		of the widget and the widget's DOM.
-	//		Changes to widget attributes listed in attributeMap will be
-	//		reflected into the DOM.
-	//
-	//		For example, calling set('title', 'hello')
-	//		on a TitlePane will automatically cause the TitlePane's DOM to update
-	//		with the new title.
-	//
-	//		attributeMap is a hash where the key is an attribute of the widget,
-	//		and the value reflects a binding to a:
-	//
-	//		- DOM node attribute
-	// |		focus: {node: "focusNode", type: "attribute"}
-	// 		Maps this.focus to this.focusNode.focus
-	//
-	//		- DOM node innerHTML
-	//	|		title: { node: "titleNode", type: "innerHTML" }
-	//		Maps this.title to this.titleNode.innerHTML
-	//
-	//		- DOM node innerText
-	//	|		title: { node: "titleNode", type: "innerText" }
-	//		Maps this.title to this.titleNode.innerText
-	//
-	//		- DOM node CSS class
-	// |		myClass: { node: "domNode", type: "class" }
-	//		Maps this.myClass to this.domNode.className
-	//
-	//		If the value is an array, then each element in the array matches one of the
-	//		formats of the above list.
-	//
-	//		There are also some shorthands for backwards compatibility:
-	//		- string --> { node: string, type: "attribute" }, for example:
-	//	|	"focusNode" ---> { node: "focusNode", type: "attribute" }
-	//		- "" --> { node: "domNode", type: "attribute" }
-	attributeMap: {},
-
-	// _blankGif: [protected] String
-	//		Path to a blank 1x1 image.
-	//		Used by <img> nodes in templates that really get their image via CSS background-image.
-	_blankGif: config.blankGif || require.toUrl("dojo/resources/blank.gif"),
-
-	//////////// INITIALIZATION METHODS ///////////////////////////////////////
-
-	postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
-		// summary:
-		//		Kicks off widget instantiation.  See create() for details.
-		// tags:
-		//		private
-		this.create(params, srcNodeRef);
-	},
-
-	create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
-		// summary:
-		//		Kick off the life-cycle of a widget
-		// params:
-		//		Hash of initialization parameters for widget, including
-		//		scalar values (like title, duration etc.) and functions,
-		//		typically callbacks like onClick.
-		// srcNodeRef:
-		//		If a srcNodeRef (DOM node) is specified:
-		//			- use srcNodeRef.innerHTML as my contents
-		//			- if this is a behavioral widget then apply behavior
-		//			  to that srcNodeRef
-		//			- otherwise, replace srcNodeRef with my generated DOM
-		//			  tree
-		// description:
-		//		Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate,
-		//		etc.), some of which of you'll want to override. See http://dojotoolkit.org/reference-guide/dijit/_WidgetBase.html
-		//		for a discussion of the widget creation lifecycle.
-		//
-		//		Of course, adventurous developers could override create entirely, but this should
-		//		only be done as a last resort.
-		// tags:
-		//		private
-
-		// store pointer to original DOM tree
-		this.srcNodeRef = dom.byId(srcNodeRef);
+			dom, domAttr, domClass, domConstruct, domGeometry, domStyle, has, kernel,
+			lang, on, ready, Stateful, topic, win, Destroyable, _BidiMixin, registry){
 
-		// For garbage collection.  An array of listener handles returned by this.connect() / this.subscribe()
-		this._connects = [];
+	// module:
+	//		dijit/_WidgetBase
 
-		// For widgets internal to this widget, invisible to calling code
-		this._supportingWidgets = [];
+	// Flag to make dijit load modules the app didn't explicitly request, for backwards compatibility
+	has.add("dijit-legacy-requires", !kernel.isAsync);
 
-		// this is here for back-compat, remove in 2.0 (but check NodeList-instantiate.html test)
-		if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
+	// Flag to enable support for textdir attribute
+	has.add("dojo-bidi", false);
 
-		// mix in our passed parameters
-		if(params){
-			this.params = params;
-			lang.mixin(this, params);
-		}
-		this.postMixInProperties();
 
-		// generate an id for the widget if one wasn't specified
-		// (be sure to do this before buildRendering() because that function might
-		// expect the id to be there.)
-		if(!this.id){
-			this.id = registry.getUniqueId(this.declaredClass.replace(/\./g,"_"));
-		}
-		registry.add(this);
-
-		this.buildRendering();
-
-		if(this.domNode){
-			// Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
-			// Also calls custom setters for all attributes with custom setters.
-			this._applyAttributes();
-
-			// If srcNodeRef was specified, then swap out original srcNode for this widget's DOM tree.
-			// For 2.0, move this after postCreate().  postCreate() shouldn't depend on the
-			// widget being attached to the DOM since it isn't when a widget is created programmatically like
-			// new MyWidget({}).   See #11635.
-			var source = this.srcNodeRef;
-			if(source && source.parentNode && this.domNode !== source){
-				source.parentNode.replaceChild(this.domNode, source);
-			}
-		}
+	// For back-compat, remove in 2.0.
+	if(has("dijit-legacy-requires")){
+		ready(0, function(){
+			var requires = ["dijit/_base/manager"];
+			require(requires);	// use indirection so modules not rolled into a build
+		});
+	}
 
-		if(this.domNode){
-			// Note: for 2.0 may want to rename widgetId to dojo._scopeName + "_widgetId",
-			// assuming that dojo._scopeName even exists in 2.0
-			this.domNode.setAttribute("widgetId", this.id);
-		}
-		this.postCreate();
+	// Nested hash listing attributes for each tag, all strings in lowercase.
+	// ex: {"div": {"style": true, "tabindex" true}, "form": { ...
+	var tagAttrs = {};
 
-		// If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
-		if(this.srcNodeRef && !this.srcNodeRef.parentNode){
-			delete this.srcNodeRef;
+	function getAttrs(obj){
+		var ret = {};
+		for(var attr in obj){
+			ret[attr.toLowerCase()] = true;
 		}
+		return ret;
+	}
 
-		this._created = true;
-	},
+	function nonEmptyAttrToDom(attr){
+		// summary:
+		//		Returns a setter function that copies the attribute to this.domNode,
+		//		or removes the attribute from this.domNode, depending on whether the
+		//		value is defined or not.
+		return function(val){
+			domAttr[val ? "set" : "remove"](this.domNode, attr, val);
+			this._set(attr, val);
+		};
+	}
 
-	_applyAttributes: function(){
+	var _WidgetBase = declare("dijit._WidgetBase", [Stateful, Destroyable], {
 		// summary:
-		//		Step during widget creation to copy  widget attributes to the
-		//		DOM according to attributeMap and _setXXXAttr objects, and also to call
-		//		custom _setXXXAttr() methods.
+		//		Future base class for all Dijit widgets.
+		// description:
+		//		Future base class for all Dijit widgets.
+		//		_Widget extends this class adding support for various features needed by desktop.
 		//
-		//		Skips over blank/false attribute values, unless they were explicitly specified
-		//		as parameters to the widget, since those are the default anyway,
-		//		and setting tabIndex="" is different than not setting tabIndex at all.
+		//		Provides stubs for widget lifecycle methods for subclasses to extend, like postMixInProperties(), buildRendering(),
+		//		postCreate(), startup(), and destroy(), and also public API methods like set(), get(), and watch().
 		//
-		//		For backwards-compatibility reasons attributeMap overrides _setXXXAttr when
-		//		_setXXXAttr is a hash/string/array, but _setXXXAttr as a functions override attributeMap.
-		// tags:
-		//		private
-
-		// Get list of attributes where this.set(name, value) will do something beyond
-		// setting this[name] = value.  Specifically, attributes that have:
-		//		- associated _setXXXAttr() method/hash/string/array
-		//		- entries in attributeMap.
-		var ctor = this.constructor,
-			list = ctor._setterAttrs;
-		if(!list){
-			list = (ctor._setterAttrs = []);
-			for(var attr in this.attributeMap){
-				list.push(attr);
-			}
-
-			var proto = ctor.prototype;
-			for(var fxName in proto){
-				if(fxName in this.attributeMap){ continue; }
-				var setterName = "_set" + fxName.replace(/^[a-z]|-[a-zA-Z]/g, function(c){ return c.charAt(c.length-1).toUpperCase(); }) + "Attr";
-				if(setterName in proto){
-					list.push(fxName);
+		//		Widgets can provide custom setters/getters for widget attributes, which are called automatically by set(name, value).
+		//		For an attribute XXX, define methods _setXXXAttr() and/or _getXXXAttr().
+		//
+		//		_setXXXAttr can also be a string/hash/array mapping from a widget attribute XXX to the widget's DOMNodes:
+		//
+		//		- DOM node attribute
+		// |		_setFocusAttr: {node: "focusNode", type: "attribute"}
+		// |		_setFocusAttr: "focusNode"	(shorthand)
+		// |		_setFocusAttr: ""		(shorthand, maps to this.domNode)
+		//		Maps this.focus to this.focusNode.focus, or (last example) this.domNode.focus
+		//
+		//		- DOM node innerHTML
+		//	|		_setTitleAttr: { node: "titleNode", type: "innerHTML" }
+		//		Maps this.title to this.titleNode.innerHTML
+		//
+		//		- DOM node innerText
+		//	|		_setTitleAttr: { node: "titleNode", type: "innerText" }
+		//		Maps this.title to this.titleNode.innerText
+		//
+		//		- DOM node CSS class
+		// |		_setMyClassAttr: { node: "domNode", type: "class" }
+		//		Maps this.myClass to this.domNode.className
+		//
+		//		If the value of _setXXXAttr is an array, then each element in the array matches one of the
+		//		formats of the above list.
+		//
+		//		If the custom setter is null, no action is performed other than saving the new value
+		//		in the widget (in this).
+		//
+		//		If no custom setter is defined for an attribute, then it will be copied
+		//		to this.focusNode (if the widget defines a focusNode), or this.domNode otherwise.
+		//		That's only done though for attributes that match DOMNode attributes (title,
+		//		alt, aria-labelledby, etc.)
+
+		// id: [const] String
+		//		A unique, opaque ID string that can be assigned by users or by the
+		//		system. If the developer passes an ID which is known not to be
+		//		unique, the specified ID is ignored and the system-generated ID is
+		//		used instead.
+		id: "",
+		_setIdAttr: "domNode", // to copy to this.domNode even for auto-generated id's
+
+		// lang: [const] String
+		//		Rarely used.  Overrides the default Dojo locale used to render this widget,
+		//		as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
+		//		Value must be among the list of locales specified during by the Dojo bootstrap,
+		//		formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
+		lang: "",
+		// set on domNode even when there's a focus node.	but don't set lang="", since that's invalid.
+		_setLangAttr: nonEmptyAttrToDom("lang"),
+
+		// dir: [const] String
+		//		Bi-directional support, as defined by the [HTML DIR](http://www.w3.org/TR/html401/struct/dirlang.html#adef-dir)
+		//		attribute. Either left-to-right "ltr" or right-to-left "rtl".  If undefined, widgets renders in page's
+		//		default direction.
+		dir: "",
+		// set on domNode even when there's a focus node.	but don't set dir="", since that's invalid.
+		_setDirAttr: nonEmptyAttrToDom("dir"), // to set on domNode even when there's a focus node
+
+		// class: String
+		//		HTML class attribute
+		"class": "",
+		_setClassAttr: { node: "domNode", type: "class" },
+
+		// style: String||Object
+		//		HTML style attributes as cssText string or name/value hash
+		style: "",
+
+		// title: String
+		//		HTML title attribute.
+		//
+		//		For form widgets this specifies a tooltip to display when hovering over
+		//		the widget (just like the native HTML title attribute).
+		//
+		//		For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer,
+		//		etc., it's used to specify the tab label, accordion pane title, etc.  In this case it's
+		//		interpreted as HTML.
+		title: "",
+
+		// tooltip: String
+		//		When this widget's title attribute is used to for a tab label, accordion pane title, etc.,
+		//		this specifies the tooltip to appear when the mouse is hovered over that text.
+		tooltip: "",
+
+		// baseClass: [protected] String
+		//		Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate
+		//		widget state.
+		baseClass: "",
+
+		// srcNodeRef: [readonly] DomNode
+		//		pointer to original DOM node
+		srcNodeRef: null,
+
+		// domNode: [readonly] DomNode
+		//		This is our visible representation of the widget! Other DOM
+		//		Nodes may by assigned to other properties, usually through the
+		//		template system's data-dojo-attach-point syntax, but the domNode
+		//		property is the canonical "top level" node in widget UI.
+		domNode: null,
+
+		// containerNode: [readonly] DomNode
+		//		Designates where children of the source DOM node will be placed.
+		//		"Children" in this case refers to both DOM nodes and widgets.
+		//		For example, for myWidget:
+		//
+		//		|	<div data-dojo-type=myWidget>
+		//		|		<b> here's a plain DOM node
+		//		|		<span data-dojo-type=subWidget>and a widget</span>
+		//		|		<i> and another plain DOM node </i>
+		//		|	</div>
+		//
+		//		containerNode would point to:
+		//
+		//		|		<b> here's a plain DOM node
+		//		|		<span data-dojo-type=subWidget>and a widget</span>
+		//		|		<i> and another plain DOM node </i>
+		//
+		//		In templated widgets, "containerNode" is set via a
+		//		data-dojo-attach-point assignment.
+		//
+		//		containerNode must be defined for any widget that accepts innerHTML
+		//		(like ContentPane or BorderContainer or even Button), and conversely
+		//		is null for widgets that don't, like TextBox.
+		containerNode: null,
+
+		// ownerDocument: [const] Document?
+		//		The document this widget belongs to.  If not specified to constructor, will default to
+		//		srcNodeRef.ownerDocument, or if no sourceRef specified, then to the document global
+		ownerDocument: null,
+		_setOwnerDocumentAttr: function(val){
+			// this setter is merely to avoid automatically trying to set this.domNode.ownerDocument
+			this._set("ownerDocument", val);
+		},
+
+		/*=====
+		// _started: [readonly] Boolean
+		//		startup() has completed.
+		_started: false,
+		=====*/
+
+		// attributeMap: [protected] Object
+		//		Deprecated.	Instead of attributeMap, widget should have a _setXXXAttr attribute
+		//		for each XXX attribute to be mapped to the DOM.
+		//
+		//		attributeMap sets up a "binding" between attributes (aka properties)
+		//		of the widget and the widget's DOM.
+		//		Changes to widget attributes listed in attributeMap will be
+		//		reflected into the DOM.
+		//
+		//		For example, calling set('title', 'hello')
+		//		on a TitlePane will automatically cause the TitlePane's DOM to update
+		//		with the new title.
+		//
+		//		attributeMap is a hash where the key is an attribute of the widget,
+		//		and the value reflects a binding to a:
+		//
+		//		- DOM node attribute
+		// |		focus: {node: "focusNode", type: "attribute"}
+		//		Maps this.focus to this.focusNode.focus
+		//
+		//		- DOM node innerHTML
+		//	|		title: { node: "titleNode", type: "innerHTML" }
+		//		Maps this.title to this.titleNode.innerHTML
+		//
+		//		- DOM node innerText
+		//	|		title: { node: "titleNode", type: "innerText" }
+		//		Maps this.title to this.titleNode.innerText
+		//
+		//		- DOM node CSS class
+		// |		myClass: { node: "domNode", type: "class" }
+		//		Maps this.myClass to this.domNode.className
+		//
+		//		If the value is an array, then each element in the array matches one of the
+		//		formats of the above list.
+		//
+		//		There are also some shorthands for backwards compatibility:
+		//
+		//		- string --> { node: string, type: "attribute" }, for example:
+		//
+		//	|	"focusNode" ---> { node: "focusNode", type: "attribute" }
+		//
+		//		- "" --> { node: "domNode", type: "attribute" }
+		attributeMap: {},
+
+		// _blankGif: [protected] String
+		//		Path to a blank 1x1 image.
+		//		Used by `<img>` nodes in templates that really get their image via CSS background-image.
+		_blankGif: config.blankGif || require.toUrl("dojo/resources/blank.gif"),
+
+		//////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+		/*=====
+		constructor: function(params, srcNodeRef){
+			// summary:
+			//		Create the widget.
+			// params: Object|null
+			//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+			//		and functions, typically callbacks like onClick.
+			//		The hash can contain any of the widget's properties, excluding read-only properties.
+			// srcNodeRef: DOMNode|String?
+			//		If a srcNodeRef (DOM node) is specified:
+			//
+			//		- use srcNodeRef.innerHTML as my contents
+			//		- if this is a behavioral widget then apply behavior to that srcNodeRef
+			//		- otherwise, replace srcNodeRef with my generated DOM tree
+		},
+		=====*/
+
+		_introspect: function(){
+			// summary:
+			//		Collect metadata about this widget (only once per class, not once per instance):
+			//
+			//			- list of attributes with custom setters, storing in this.constructor._setterAttrs
+			//			- generate this.constructor._onMap, mapping names like "mousedown" to functions like onMouseDown
+
+			var ctor = this.constructor;
+			if(!ctor._setterAttrs){
+				var proto = ctor.prototype,
+					attrs = ctor._setterAttrs = [], // attributes with custom setters
+					onMap = (ctor._onMap = {});
+
+				// Items in this.attributeMap are like custom setters.  For back-compat, remove for 2.0.
+				for(var name in proto.attributeMap){
+					attrs.push(name);
 				}
-			}
-		}
 
-		// Call this.set() for each attribute that was either specified as parameter to constructor,
-		// or was found above and has a default non-null value.   For correlated attributes like value and displayedValue, the one
-		// specified as a parameter should take precedence, so apply attributes in this.params last.
-		// Particularly important for new DateTextBox({displayedValue: ...}) since DateTextBox's default value is
-		// NaN and thus is not ignored like a default value of "".
-		array.forEach(list, function(attr){
-			if(this.params && attr in this.params){
-				// skip this one, do it below
-			}else if(this[attr]){
-				this.set(attr, this[attr]);
-			}
-		}, this);
-		for(var param in this.params){
-			this.set(param, this[param]);
-		}
-	},
+				// Loop over widget properties, collecting properties with custom setters and filling in ctor._onMap.
+				for(name in proto){
+					if(/^on/.test(name)){
+						onMap[name.substring(2).toLowerCase()] = name;
+					}
 
-	postMixInProperties: function(){
-		// summary:
-		//		Called after the parameters to the widget have been read-in,
-		//		but before the widget template is instantiated. Especially
-		//		useful to set properties that are referenced in the widget
-		//		template.
-		// tags:
-		//		protected
-	},
-
-	buildRendering: function(){
-		// summary:
-		//		Construct the UI for this widget, setting this.domNode.
-		//		Most widgets will mixin `dijit._TemplatedMixin`, which implements this method.
-		// tags:
-		//		protected
-
-		if(!this.domNode){
-			// Create root node if it wasn't created by _Templated
-			this.domNode = this.srcNodeRef || domConstruct.create('div');
-		}
+					if(/^_set[A-Z](.*)Attr$/.test(name)){
+						name = name.charAt(4).toLowerCase() + name.substr(5, name.length - 9);
+						if(!proto.attributeMap || !(name in proto.attributeMap)){
+							attrs.push(name);
+						}
+					}
+				}
 
-		// baseClass is a single class name or occasionally a space-separated list of names.
-		// Add those classes to the DOMNode.  If RTL mode then also add with Rtl suffix.
-		// TODO: make baseClass custom setter
-		if(this.baseClass){
-			var classes = this.baseClass.split(" ");
-			if(!this.isLeftToRight()){
-				classes = classes.concat( array.map(classes, function(name){ return name+"Rtl"; }));
+				// Note: this isn't picking up info on properties like aria-label and role, that don't have custom setters
+				// but that set() maps to attributes on this.domNode or this.focusNode
+			}
+		},
+
+		postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
+			// summary:
+			//		Kicks off widget instantiation.  See create() for details.
+			// tags:
+			//		private
+
+			// Note that we skip calling this.inherited(), i.e. dojo/Stateful::postscript(), because 1.x widgets don't
+			// expect their custom setters to get called until after buildRendering().  Consider changing for 2.0.
+
+			this.create(params, srcNodeRef);
+		},
+
+		create: function(params, srcNodeRef){
+			// summary:
+			//		Kick off the life-cycle of a widget
+			// description:
+			//		Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate,
+			//		etc.), some of which of you'll want to override. See http://dojotoolkit.org/reference-guide/dijit/_WidgetBase.html
+			//		for a discussion of the widget creation lifecycle.
+			//
+			//		Of course, adventurous developers could override create entirely, but this should
+			//		only be done as a last resort.
+			// params: Object|null
+			//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+			//		and functions, typically callbacks like onClick.
+			//		The hash can contain any of the widget's properties, excluding read-only properties.
+			// srcNodeRef: DOMNode|String?
+			//		If a srcNodeRef (DOM node) is specified:
+			//
+			//		- use srcNodeRef.innerHTML as my contents
+			//		- if this is a behavioral widget then apply behavior to that srcNodeRef
+			//		- otherwise, replace srcNodeRef with my generated DOM tree
+			// tags:
+			//		private
+
+			// First time widget is instantiated, scan prototype to figure out info about custom setters etc.
+			this._introspect();
+
+			// store pointer to original DOM tree
+			this.srcNodeRef = dom.byId(srcNodeRef);
+
+			// No longer used, remove for 2.0.
+			this._connects = [];
+			this._supportingWidgets = [];
+
+			// this is here for back-compat, remove in 2.0 (but check NodeList-instantiate.html test)
+			if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){
+				this.id = this.srcNodeRef.id;
 			}
-			domClass.add(this.domNode, classes);
-		}
-	},
 
-	postCreate: function(){
-		// summary:
-		//		Processing after the DOM fragment is created
-		// description:
-		//		Called after the DOM fragment has been created, but not necessarily
-		//		added to the document.  Do not include any operations which rely on
-		//		node dimensions or placement.
-		// tags:
-		//		protected
-	},
-
-	startup: function(){
-		// summary:
-		//		Processing after the DOM fragment is added to the document
-		// description:
-		//		Called after a widget and its children have been created and added to the page,
-		//		and all related widgets have finished their create() cycle, up through postCreate().
-		//		This is useful for composite widgets that need to control or layout sub-widgets.
-		//		Many layout widgets can use this as a wiring phase.
-		if(this._started){ return; }
-		this._started = true;
-		array.forEach(this.getChildren(), function(obj){
-			if(!obj._started && !obj._destroyed && lang.isFunction(obj.startup)){
-				obj.startup();
-				obj._started = true;
+			// mix in our passed parameters
+			if(params){
+				this.params = params;
+				lang.mixin(this, params);
+			}
+			this.postMixInProperties();
+
+			// Generate an id for the widget if one wasn't specified, or it was specified as id: undefined.
+			// Do this before buildRendering() because it might expect the id to be there.
+			if(!this.id){
+				this.id = registry.getUniqueId(this.declaredClass.replace(/\./g, "_"));
+				if(this.params){
+					// if params contains {id: undefined}, prevent _applyAttributes() from processing it
+					delete this.params.id;
+				}
 			}
-		});
-	},
 
-	//////////// DESTROY FUNCTIONS ////////////////////////////////
+			// The document and <body> node this widget is associated with
+			this.ownerDocument = this.ownerDocument || (this.srcNodeRef ? this.srcNodeRef.ownerDocument : document);
+			this.ownerDocumentBody = win.body(this.ownerDocument);
 
-	destroyRecursive: function(/*Boolean?*/ preserveDom){
-		// summary:
-		// 		Destroy this widget and its descendants
-		// description:
-		//		This is the generic "destructor" function that all widget users
-		// 		should call to cleanly discard with a widget. Once a widget is
-		// 		destroyed, it is removed from the manager object.
-		// preserveDom:
-		//		If true, this method will leave the original DOM structure
-		//		alone of descendant Widgets. Note: This will NOT work with
-		//		dijit._Templated widgets.
-
-		this._beingDestroyed = true;
-		this.destroyDescendants(preserveDom);
-		this.destroy(preserveDom);
-	},
-
-	destroy: function(/*Boolean*/ preserveDom){
-		// summary:
-		// 		Destroy this widget, but not its descendants.
-		//		This method will, however, destroy internal widgets such as those used within a template.
-		// preserveDom: Boolean
-		//		If true, this method will leave the original DOM structure alone.
-		//		Note: This will not yet work with _Templated widgets
-
-		this._beingDestroyed = true;
-		this.uninitialize();
-
-		// remove this.connect() and this.subscribe() listeners
-		var c;
-		while(c = this._connects.pop()){
-			c.remove();
-		}
+			registry.add(this);
 
-		// destroy widgets created as part of template, etc.
-		var w;
-		while(w = this._supportingWidgets.pop()){
-			if(w.destroyRecursive){
-				w.destroyRecursive();
-			}else if(w.destroy){
-				w.destroy();
-			}
-		}
+			this.buildRendering();
 
-		this.destroyRendering(preserveDom);
-		registry.remove(this.id);
-		this._destroyed = true;
-	},
+			var deleteSrcNodeRef;
 
-	destroyRendering: function(/*Boolean?*/ preserveDom){
-		// summary:
-		//		Destroys the DOM nodes associated with this widget
-		// preserveDom:
-		//		If true, this method will leave the original DOM structure alone
-		//		during tear-down. Note: this will not work with _Templated
-		//		widgets yet.
-		// tags:
-		//		protected
-
-		if(this.bgIframe){
-			this.bgIframe.destroy(preserveDom);
-			delete this.bgIframe;
-		}
+			if(this.domNode){
+				// Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
+				// Also calls custom setters for all attributes with custom setters.
+				this._applyAttributes();
 
-		if(this.domNode){
-			if(preserveDom){
-				domAttr.remove(this.domNode, "widgetId");
-			}else{
-				domConstruct.destroy(this.domNode);
-			}
-			delete this.domNode;
-		}
+				// If srcNodeRef was specified, then swap out original srcNode for this widget's DOM tree.
+				// For 2.0, move this after postCreate().  postCreate() shouldn't depend on the
+				// widget being attached to the DOM since it isn't when a widget is created programmatically like
+				// new MyWidget({}).	See #11635.
+				var source = this.srcNodeRef;
+				if(source && source.parentNode && this.domNode !== source){
+					source.parentNode.replaceChild(this.domNode, source);
+					deleteSrcNodeRef = true;
+				}
 
-		if(this.srcNodeRef){
-			if(!preserveDom){
-				domConstruct.destroy(this.srcNodeRef);
+				// Note: for 2.0 may want to rename widgetId to dojo._scopeName + "_widgetId",
+				// assuming that dojo._scopeName even exists in 2.0
+				this.domNode.setAttribute("widgetId", this.id);
 			}
-			delete this.srcNodeRef;
-		}
-	},
+			this.postCreate();
 
-	destroyDescendants: function(/*Boolean?*/ preserveDom){
-		// summary:
-		//		Recursively destroy the children of this widget and their
-		//		descendants.
-		// preserveDom:
-		//		If true, the preserveDom attribute is passed to all descendant
-		//		widget's .destroy() method. Not for use with _Templated
-		//		widgets.
-
-		// get all direct descendants and destroy them recursively
-		array.forEach(this.getChildren(), function(widget){
-			if(widget.destroyRecursive){
-				widget.destroyRecursive(preserveDom);
+			// If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
+			// I think for back-compatibility it isn't deleting srcNodeRef until after postCreate() has run.
+			if(deleteSrcNodeRef){
+				delete this.srcNodeRef;
 			}
-		});
-	},
-
-	uninitialize: function(){
-		// summary:
-		//		Stub function. Override to implement custom widget tear-down
-		//		behavior.
-		// tags:
-		//		protected
-		return false;
-	},
 
-	////////////////// GET/SET, CUSTOM SETTERS, ETC. ///////////////////
-
-	_setStyleAttr: function(/*String||Object*/ value){
-		// summary:
-		//		Sets the style attribute of the widget according to value,
-		//		which is either a hash like {height: "5px", width: "3px"}
-		//		or a plain string
-		// description:
-		//		Determines which node to set the style on based on style setting
-		//		in attributeMap.
-		// tags:
-		//		protected
-
-		var mapNode = this.domNode;
-
-		// Note: technically we should revert any style setting made in a previous call
-		// to his method, but that's difficult to keep track of.
-
-		if(lang.isObject(value)){
-			domStyle.set(mapNode, value);
-		}else{
-			if(mapNode.style.cssText){
-				mapNode.style.cssText += "; " + value;
-			}else{
-				mapNode.style.cssText = value;
+			this._created = true;
+		},
+
+		_applyAttributes: function(){
+			// summary:
+			//		Step during widget creation to copy  widget attributes to the
+			//		DOM according to attributeMap and _setXXXAttr objects, and also to call
+			//		custom _setXXXAttr() methods.
+			//
+			//		Skips over blank/false attribute values, unless they were explicitly specified
+			//		as parameters to the widget, since those are the default anyway,
+			//		and setting tabIndex="" is different than not setting tabIndex at all.
+			//
+			//		For backwards-compatibility reasons attributeMap overrides _setXXXAttr when
+			//		_setXXXAttr is a hash/string/array, but _setXXXAttr as a functions override attributeMap.
+			// tags:
+			//		private
+
+			// Call this.set() for each property that was either specified as parameter to constructor,
+			// or is in the list found above.	For correlated properties like value and displayedValue, the one
+			// specified as a parameter should take precedence.
+			// Particularly important for new DateTextBox({displayedValue: ...}) since DateTextBox's default value is
+			// NaN and thus is not ignored like a default value of "".
+
+			// Step 1: Save the current values of the widget properties that were specified as parameters to the constructor.
+			// Generally this.foo == this.params.foo, except if postMixInProperties() changed the value of this.foo.
+			var params = {};
+			for(var key in this.params || {}){
+				params[key] = this._get(key);
 			}
-		}
 
-		this._set("style", value);
-	},
+			// Step 2: Call set() for each property with a non-falsy value that wasn't passed as a parameter to the constructor
+			array.forEach(this.constructor._setterAttrs, function(key){
+				if(!(key in params)){
+					var val = this._get(key);
+					if(val){
+						this.set(key, val);
+					}
+				}
+			}, this);
 
-	_attrToDom: function(/*String*/ attr, /*String*/ value, /*Object?*/ commands){
-		// summary:
-		//		Reflect a widget attribute (title, tabIndex, duration etc.) to
-		//		the widget DOM, as specified by commands parameter.
-		//		If commands isn't specified then it's looked up from attributeMap.
-		//		Note some attributes like "type"
-		//		cannot be processed this way as they are not mutable.
-		//
-		// tags:
-		//		private
+			// Step 3: Call set() for each property that was specified as parameter to constructor.
+			// Use params hash created above to ignore side effects from step #2 above.
+			for(key in params){
+				this.set(key, params[key]);
+			}
+		},
+
+		postMixInProperties: function(){
+			// summary:
+			//		Called after the parameters to the widget have been read-in,
+			//		but before the widget template is instantiated. Especially
+			//		useful to set properties that are referenced in the widget
+			//		template.
+			// tags:
+			//		protected
+		},
+
+		buildRendering: function(){
+			// summary:
+			//		Construct the UI for this widget, setting this.domNode.
+			//		Most widgets will mixin `dijit._TemplatedMixin`, which implements this method.
+			// tags:
+			//		protected
+
+			if(!this.domNode){
+				// Create root node if it wasn't created by _TemplatedMixin
+				this.domNode = this.srcNodeRef || this.ownerDocument.createElement("div");
+			}
 
-		commands = arguments.length >= 3 ? commands : this.attributeMap[attr];
+			// baseClass is a single class name or occasionally a space-separated list of names.
+			// Add those classes to the DOMNode.  If RTL mode then also add with Rtl suffix.
+			// TODO: make baseClass custom setter
+			if(this.baseClass){
+				var classes = this.baseClass.split(" ");
+				if(!this.isLeftToRight()){
+					classes = classes.concat(array.map(classes, function(name){
+						return name + "Rtl";
+					}));
+				}
+				domClass.add(this.domNode, classes);
+			}
+		},
+
+		postCreate: function(){
+			// summary:
+			//		Processing after the DOM fragment is created
+			// description:
+			//		Called after the DOM fragment has been created, but not necessarily
+			//		added to the document.  Do not include any operations which rely on
+			//		node dimensions or placement.
+			// tags:
+			//		protected
+		},
+
+		startup: function(){
+			// summary:
+			//		Processing after the DOM fragment is added to the document
+			// description:
+			//		Called after a widget and its children have been created and added to the page,
+			//		and all related widgets have finished their create() cycle, up through postCreate().
+			//
+			//		Note that startup() may be called while the widget is still hidden, for example if the widget is
+			//		inside a hidden dijit/Dialog or an unselected tab of a dijit/layout/TabContainer.
+			//		For widgets that need to do layout, it's best to put that layout code inside resize(), and then
+			//		extend dijit/layout/_LayoutWidget so that resize() is called when the widget is visible.
+			if(this._started){
+				return;
+			}
+			this._started = true;
+			array.forEach(this.getChildren(), function(obj){
+				if(!obj._started && !obj._destroyed && lang.isFunction(obj.startup)){
+					obj.startup();
+					obj._started = true;
+				}
+			});
+		},
+
+		//////////// DESTROY FUNCTIONS ////////////////////////////////
+
+		destroyRecursive: function(/*Boolean?*/ preserveDom){
+			// summary:
+			//		Destroy this widget and its descendants
+			// description:
+			//		This is the generic "destructor" function that all widget users
+			//		should call to cleanly discard with a widget. Once a widget is
+			//		destroyed, it is removed from the manager object.
+			// preserveDom:
+			//		If true, this method will leave the original DOM structure
+			//		alone of descendant Widgets. Note: This will NOT work with
+			//		dijit._TemplatedMixin widgets.
+
+			this._beingDestroyed = true;
+			this.destroyDescendants(preserveDom);
+			this.destroy(preserveDom);
+		},
+
+		destroy: function(/*Boolean*/ preserveDom){
+			// summary:
+			//		Destroy this widget, but not its descendants.  Descendants means widgets inside of
+			//		this.containerNode.   Will also destroy any resources (including widgets) registered via this.own().
+			//
+			//		This method will also destroy internal widgets such as those created from a template,
+			//		assuming those widgets exist inside of this.domNode but outside of this.containerNode.
+			//
+			//		For 2.0 it's planned that this method will also destroy descendant widgets, so apps should not
+			//		depend on the current ability to destroy a widget without destroying its descendants.   Generally
+			//		they should use destroyRecursive() for widgets with children.
+			// preserveDom: Boolean
+			//		If true, this method will leave the original DOM structure alone.
+			//		Note: This will not yet work with _TemplatedMixin widgets
+
+			this._beingDestroyed = true;
+			this.uninitialize();
+
+			function destroy(w){
+				if(w.destroyRecursive){
+					w.destroyRecursive(preserveDom);
+				}else if(w.destroy){
+					w.destroy(preserveDom);
+				}
+			}
 
-		array.forEach(lang.isArray(commands) ? commands : [commands], function(command){
+			// Back-compat, remove for 2.0
+			array.forEach(this._connects, lang.hitch(this, "disconnect"));
+			array.forEach(this._supportingWidgets, destroy);
 
-			// Get target node and what we are doing to that node
-			var mapNode = this[command.node || command || "domNode"];	// DOM node
-			var type = command.type || "attribute";	// class, innerHTML, innerText, or attribute
+			// Destroy supporting widgets, but not child widgets under this.containerNode (for 2.0, destroy child widgets
+			// here too).   if() statement is to guard against exception if destroy() called multiple times (see #15815).
+			if(this.domNode){
+				array.forEach(registry.findWidgets(this.domNode, this.containerNode), destroy);
+			}
 
-			switch(type){
-				case "attribute":
-					if(lang.isFunction(value)){ // functions execute in the context of the widget
-						value = lang.hitch(this, value);
-					}
+			this.destroyRendering(preserveDom);
+			registry.remove(this.id);
+			this._destroyed = true;
+		},
+
+		destroyRendering: function(/*Boolean?*/ preserveDom){
+			// summary:
+			//		Destroys the DOM nodes associated with this widget.
+			// preserveDom:
+			//		If true, this method will leave the original DOM structure alone
+			//		during tear-down. Note: this will not work with _Templated
+			//		widgets yet.
+			// tags:
+			//		protected
+
+			if(this.bgIframe){
+				this.bgIframe.destroy(preserveDom);
+				delete this.bgIframe;
+			}
 
-					// Get the name of the DOM node attribute; usually it's the same
-					// as the name of the attribute in the widget (attr), but can be overridden.
-					// Also maps handler names to lowercase, like onSubmit --> onsubmit
-					var attrName = command.attribute ? command.attribute :
-						(/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr);
-
-					domAttr.set(mapNode, attrName, value);
-					break;
-				case "innerText":
-					mapNode.innerHTML = "";
-					mapNode.appendChild(win.doc.createTextNode(value));
-					break;
-				case "innerHTML":
-					mapNode.innerHTML = value;
-					break;
-				case "class":
-					domClass.replace(mapNode, value, this[attr]);
-					break;
+			if(this.domNode){
+				if(preserveDom){
+					domAttr.remove(this.domNode, "widgetId");
+				}else{
+					domConstruct.destroy(this.domNode);
+				}
+				delete this.domNode;
 			}
-		}, this);
-	},
 
-	get: function(name){
-		// summary:
-		//		Get a property from a widget.
-		//	name:
-		//		The property to get.
-		// description:
-		//		Get a named property from a widget. The property may
-		//		potentially be retrieved via a getter method. If no getter is defined, this
-		// 		just retrieves the object's property.
-		//
-		// 		For example, if the widget has properties `foo` and `bar`
-		//		and a method named `_getFooAttr()`, calling:
-		//		`myWidget.get("foo")` would be equivalent to calling
-		//		`widget._getFooAttr()` and `myWidget.get("bar")`
-		//		would be equivalent to the expression
-		//		`widget.bar2`
-		var names = this._getAttrNames(name);
-		return this[names.g] ? this[names.g]() : this[name];
-	},
-
-	set: function(name, value){
-		// summary:
-		//		Set a property on a widget
-		//	name:
-		//		The property to set.
-		//	value:
-		//		The value to set in the property.
-		// description:
-		//		Sets named properties on a widget which may potentially be handled by a
-		// 		setter in the widget.
-		//
-		// 		For example, if the widget has properties `foo` and `bar`
-		//		and a method named `_setFooAttr()`, calling
-		//		`myWidget.set("foo", "Howdy!")` would be equivalent to calling
-		//		`widget._setFooAttr("Howdy!")` and `myWidget.set("bar", 3)`
-		//		would be equivalent to the statement `widget.bar = 3;`
-		//
-		//		set() may also be called with a hash of name/value pairs, ex:
-		//
-		//	|	myWidget.set({
-		//	|		foo: "Howdy",
-		//	|		bar: 3
-		//	|	});
-		//
-		//	This is equivalent to calling `set(foo, "Howdy")` and `set(bar, 3)`
+			if(this.srcNodeRef){
+				if(!preserveDom){
+					domConstruct.destroy(this.srcNodeRef);
+				}
+				delete this.srcNodeRef;
+			}
+		},
+
+		destroyDescendants: function(/*Boolean?*/ preserveDom){
+			// summary:
+			//		Recursively destroy the children of this widget and their
+			//		descendants.
+			// preserveDom:
+			//		If true, the preserveDom attribute is passed to all descendant
+			//		widget's .destroy() method. Not for use with _Templated
+			//		widgets.
+
+			// get all direct descendants and destroy them recursively
+			array.forEach(this.getChildren(), function(widget){
+				if(widget.destroyRecursive){
+					widget.destroyRecursive(preserveDom);
+				}
+			});
+		},
+
+		uninitialize: function(){
+			// summary:
+			//		Deprecated. Override destroy() instead to implement custom widget tear-down
+			//		behavior.
+			// tags:
+			//		protected
+			return false;
+		},
+
+		////////////////// GET/SET, CUSTOM SETTERS, ETC. ///////////////////
+
+		_setStyleAttr: function(/*String||Object*/ value){
+			// summary:
+			//		Sets the style attribute of the widget according to value,
+			//		which is either a hash like {height: "5px", width: "3px"}
+			//		or a plain string
+			// description:
+			//		Determines which node to set the style on based on style setting
+			//		in attributeMap.
+			// tags:
+			//		protected
+
+			var mapNode = this.domNode;
+
+			// Note: technically we should revert any style setting made in a previous call
+			// to his method, but that's difficult to keep track of.
+
+			if(lang.isObject(value)){
+				domStyle.set(mapNode, value);
+			}else{
+				if(mapNode.style.cssText){
+					mapNode.style.cssText += "; " + value;
+				}else{
+					mapNode.style.cssText = value;
+				}
+			}
 
-		if(typeof name === "object"){
-			for(var x in name){
-				this.set(x, name[x]);
+			this._set("style", value);
+		},
+
+		_attrToDom: function(/*String*/ attr, /*String*/ value, /*Object?*/ commands){
+			// summary:
+			//		Reflect a widget attribute (title, tabIndex, duration etc.) to
+			//		the widget DOM, as specified by commands parameter.
+			//		If commands isn't specified then it's looked up from attributeMap.
+			//		Note some attributes like "type"
+			//		cannot be processed this way as they are not mutable.
+			// attr:
+			//		Name of member variable (ex: "focusNode" maps to this.focusNode) pointing
+			//		to DOMNode inside the widget, or alternately pointing to a subwidget
+			// tags:
+			//		private
+
+			commands = arguments.length >= 3 ? commands : this.attributeMap[attr];
+
+			array.forEach(lang.isArray(commands) ? commands : [commands], function(command){
+
+				// Get target node and what we are doing to that node
+				var mapNode = this[command.node || command || "domNode"];	// DOM node
+				var type = command.type || "attribute";	// class, innerHTML, innerText, or attribute
+
+				switch(type){
+					case "attribute":
+						if(lang.isFunction(value)){ // functions execute in the context of the widget
+							value = lang.hitch(this, value);
+						}
+
+						// Get the name of the DOM node attribute; usually it's the same
+						// as the name of the attribute in the widget (attr), but can be overridden.
+						// Also maps handler names to lowercase, like onSubmit --> onsubmit
+						var attrName = command.attribute ? command.attribute :
+							(/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr);
+
+						if(mapNode.tagName){
+							// Normal case, mapping to a DOMNode.  Note that modern browsers will have a mapNode.set()
+							// method, but for consistency we still call domAttr
+							domAttr.set(mapNode, attrName, value);
+						}else{
+							// mapping to a sub-widget
+							mapNode.set(attrName, value);
+						}
+						break;
+					case "innerText":
+						mapNode.innerHTML = "";
+						mapNode.appendChild(this.ownerDocument.createTextNode(value));
+						break;
+					case "innerHTML":
+						mapNode.innerHTML = value;
+						break;
+					case "class":
+						domClass.replace(mapNode, value, this[attr]);
+						break;
+				}
+			}, this);
+		},
+
+		get: function(name){
+			// summary:
+			//		Get a property from a widget.
+			// name:
+			//		The property to get.
+			// description:
+			//		Get a named property from a widget. The property may
+			//		potentially be retrieved via a getter method. If no getter is defined, this
+			//		just retrieves the object's property.
+			//
+			//		For example, if the widget has properties `foo` and `bar`
+			//		and a method named `_getFooAttr()`, calling:
+			//		`myWidget.get("foo")` would be equivalent to calling
+			//		`widget._getFooAttr()` and `myWidget.get("bar")`
+			//		would be equivalent to the expression
+			//		`widget.bar2`
+			var names = this._getAttrNames(name);
+			return this[names.g] ? this[names.g]() : this._get(name);
+		},
+
+		set: function(name, value){
+			// summary:
+			//		Set a property on a widget
+			// name:
+			//		The property to set.
+			// value:
+			//		The value to set in the property.
+			// description:
+			//		Sets named properties on a widget which may potentially be handled by a
+			//		setter in the widget.
+			//
+			//		For example, if the widget has properties `foo` and `bar`
+			//		and a method named `_setFooAttr()`, calling
+			//		`myWidget.set("foo", "Howdy!")` would be equivalent to calling
+			//		`widget._setFooAttr("Howdy!")` and `myWidget.set("bar", 3)`
+			//		would be equivalent to the statement `widget.bar = 3;`
+			//
+			//		set() may also be called with a hash of name/value pairs, ex:
+			//
+			//	|	myWidget.set({
+			//	|		foo: "Howdy",
+			//	|		bar: 3
+			//	|	});
+			//
+			//	This is equivalent to calling `set(foo, "Howdy")` and `set(bar, 3)`
+
+			if(typeof name === "object"){
+				for(var x in name){
+					this.set(x, name[x]);
+				}
+				return this;
 			}
-			return this;
-		}
-		var names = this._getAttrNames(name),
-			setter = this[names.s];
-		if(lang.isFunction(setter)){
-			// use the explicit setter
-			var result = setter.apply(this, Array.prototype.slice.call(arguments, 1));
-		}else{
-			// Mapping from widget attribute to DOMNode attribute/value/etc.
-			// Map according to:
-			//		1. attributeMap setting, if one exists (TODO: attributeMap deprecated, remove in 2.0)
-			//		2. _setFooAttr: {...} type attribute in the widget (if one exists)
-			//		3. apply to focusNode or domNode if standard attribute name, excluding funcs like onClick.
-			// Checks if an attribute is a "standard attribute" by whether the DOMNode JS object has a similar
-			// attribute name (ex: accept-charset attribute matches jsObject.acceptCharset).
-			// Note also that Tree.focusNode() is a function not a DOMNode, so test for that.
-			var defaultNode = this.focusNode && !lang.isFunction(this.focusNode) ? "focusNode" : "domNode",
-				tag = this[defaultNode].tagName,
-				attrsForTag = tagAttrs[tag] || (tagAttrs[tag] = getAttrs(this[defaultNode])),
-				map =	name in this.attributeMap ? this.attributeMap[name] :
+			var names = this._getAttrNames(name),
+				setter = this[names.s];
+			if(lang.isFunction(setter)){
+				// use the explicit setter
+				var result = setter.apply(this, Array.prototype.slice.call(arguments, 1));
+			}else{
+				// Mapping from widget attribute to DOMNode/subwidget attribute/value/etc.
+				// Map according to:
+				//		1. attributeMap setting, if one exists (TODO: attributeMap deprecated, remove in 2.0)
+				//		2. _setFooAttr: {...} type attribute in the widget (if one exists)
+				//		3. apply to focusNode or domNode if standard attribute name, excluding funcs like onClick.
+				// Checks if an attribute is a "standard attribute" by whether the DOMNode JS object has a similar
+				// attribute name (ex: accept-charset attribute matches jsObject.acceptCharset).
+				// Note also that Tree.focusNode() is a function not a DOMNode, so test for that.
+				var defaultNode = this.focusNode && !lang.isFunction(this.focusNode) ? "focusNode" : "domNode",
+					tag = this[defaultNode] && this[defaultNode].tagName,
+					attrsForTag = tag && (tagAttrs[tag] || (tagAttrs[tag] = getAttrs(this[defaultNode]))),
+					map = name in this.attributeMap ? this.attributeMap[name] :
 						names.s in this ? this[names.s] :
-						((names.l in attrsForTag && typeof value != "function") ||
-							/^aria-|^data-|^role$/.test(name)) ? defaultNode : null;
-			if(map != null){
-				this._attrToDom(name, value, map);
+							((attrsForTag && names.l in attrsForTag && typeof value != "function") ||
+								/^aria-|^data-|^role$/.test(name)) ? defaultNode : null;
+				if(map != null){
+					this._attrToDom(name, value, map);
+				}
+				this._set(name, value);
 			}
-			this._set(name, value);
-		}
-		return result || this;
-	},
-
-	_attrPairNames: {},		// shared between all widgets
-	_getAttrNames: function(name){
-		// summary:
-		//		Helper function for get() and set().
-		//		Caches attribute name values so we don't do the string ops every time.
-		// tags:
-		//		private
-
-		var apn = this._attrPairNames;
-		if(apn[name]){ return apn[name]; }
-		var uc = name.replace(/^[a-z]|-[a-zA-Z]/g, function(c){ return c.charAt(c.length-1).toUpperCase(); });
-		return (apn[name] = {
-			n: name+"Node",
-			s: "_set"+uc+"Attr",	// converts dashes to camel case, ex: accept-charset --> _setAcceptCharsetAttr
-			g: "_get"+uc+"Attr",
-			l: uc.toLowerCase()		// lowercase name w/out dashes, ex: acceptcharset
-		});
-	},
+			return result || this;
+		},
+
+		_attrPairNames: {}, // shared between all widgets
+		_getAttrNames: function(name){
+			// summary:
+			//		Helper function for get() and set().
+			//		Caches attribute name values so we don't do the string ops every time.
+			// tags:
+			//		private
+
+			var apn = this._attrPairNames;
+			if(apn[name]){
+				return apn[name];
+			}
+			var uc = name.replace(/^[a-z]|-[a-zA-Z]/g, function(c){
+				return c.charAt(c.length - 1).toUpperCase();
+			});
+			return (apn[name] = {
+				n: name + "Node",
+				s: "_set" + uc + "Attr", // converts dashes to camel case, ex: accept-charset --> _setAcceptCharsetAttr
+				g: "_get" + uc + "Attr",
+				l: uc.toLowerCase()        // lowercase name w/out dashes, ex: acceptcharset
+			});
+		},
+
+		_set: function(/*String*/ name, /*anything*/ value){
+			// summary:
+			//		Helper function to set new value for specified property, and call handlers
+			//		registered with watch() if the value has changed.
+			var oldValue = this[name];
+			this[name] = value;
+			if(this._created && value !== oldValue){
+				if(this._watchCallbacks){
+					this._watchCallbacks(name, oldValue, value);
+				}
+				this.emit("attrmodified-" + name, {
+					detail: {
+						prevValue: oldValue,
+						newValue: value
+					}
+				});
+			}
+		},
+
+		_get: function(/*String*/ name){
+			// summary:
+			//		Helper function to get value for specified property stored by this._set(),
+			//		i.e. for properties with custom setters.  Used mainly by custom getters.
+			//
+			//		For example, CheckBox._getValueAttr() calls this._get("value").
+
+			// future: return name in this.props ? this.props[name] : this[name];
+			return this[name];
+		},
+
+		emit: function(/*String*/ type, /*Object?*/ eventObj, /*Array?*/ callbackArgs){
+			// summary:
+			//		Used by widgets to signal that a synthetic event occurred, ex:
+			//	|	myWidget.emit("attrmodified-selectedChildWidget", {}).
+			//
+			//		Emits an event on this.domNode named type.toLowerCase(), based on eventObj.
+			//		Also calls onType() method, if present, and returns value from that method.
+			//		By default passes eventObj to callback, but will pass callbackArgs instead, if specified.
+			//		Modifies eventObj by adding missing parameters (bubbles, cancelable, widget).
+			// tags:
+			//		protected
+
+			// Specify fallback values for bubbles, cancelable in case they are not set in eventObj.
+			// Also set pointer to widget, although since we can't add a pointer to the widget for native events
+			// (see #14729), maybe we shouldn't do it here?
+			eventObj = eventObj || {};
+			if(eventObj.bubbles === undefined){
+				eventObj.bubbles = true;
+			}
+			if(eventObj.cancelable === undefined){
+				eventObj.cancelable = true;
+			}
+			if(!eventObj.detail){
+				eventObj.detail = {};
+			}
+			eventObj.detail.widget = this;
 
-	_set: function(/*String*/ name, /*anything*/ value){
-		// summary:
-		//		Helper function to set new value for specified attribute, and call handlers
-		//		registered with watch() if the value has changed.
-		var oldValue = this[name];
-		this[name] = value;
-		if(this._watchCallbacks && this._created && value !== oldValue){
-			this._watchCallbacks(name, oldValue, value);
-		}
-	},
+			var ret, callback = this["on" + type];
+			if(callback){
+				ret = callback.apply(this, callbackArgs ? callbackArgs : [eventObj]);
+			}
 
-	on: function(/*String*/ type, /*Function*/ func){
-		// summary:
-		//		Call specified function when event occurs, ex: myWidget.on("click", function(){ ... }).
-		// description:
-		//		Call specified function when event `type` occurs, ex: `myWidget.on("click", function(){ ... })`.
-		//		Note that the function is not run in any particular scope, so if (for example) you want it to run in the
-		//		widget's scope you must do `myWidget.on("click", lang.hitch(myWidget, func))`.
+			// Emit event, but avoid spurious emit()'s as parent sets properties on child during startup/destroy
+			if(this._started && !this._beingDestroyed){
+				on.emit(this.domNode, type.toLowerCase(), eventObj);
+			}
 
-		return aspect.after(this, this._onMap(type), func, true);
-	},
+			return ret;
+		},
+
+		on: function(/*String|Function*/ type, /*Function*/ func){
+			// summary:
+			//		Call specified function when event occurs, ex: myWidget.on("click", function(){ ... }).
+			// type:
+			//		Name of event (ex: "click") or extension event like touch.press.
+			// description:
+			//		Call specified function when event `type` occurs, ex: `myWidget.on("click", function(){ ... })`.
+			//		Note that the function is not run in any particular scope, so if (for example) you want it to run in the
+			//		widget's scope you must do `myWidget.on("click", lang.hitch(myWidget, func))`.
+
+			// For backwards compatibility, if there's an onType() method in the widget then connect to that.
+			// Remove in 2.0.
+			var widgetMethod = this._onMap(type);
+			if(widgetMethod){
+				return aspect.after(this, widgetMethod, func, true);
+			}
 
-	_onMap: function(/*String*/ type){
-		// summary:
-		//		Maps on() type parameter (ex: "mousemove") to method name (ex: "onMouseMove")
-		var ctor = this.constructor, map = ctor._onMap;
-		if(!map){
-			map = (ctor._onMap = {});
-			for(var attr in ctor.prototype){
-				if(/^on/.test(attr)){
-					map[attr.replace(/^on/, "").toLowerCase()] = attr;
+			// Otherwise, just listen for the event on this.domNode.
+			return this.own(on(this.domNode, type, func))[0];
+		},
+
+		_onMap: function(/*String|Function*/ type){
+			// summary:
+			//		Maps on() type parameter (ex: "mousemove") to method name (ex: "onMouseMove").
+			//		If type is a synthetic event like touch.press then returns undefined.
+			var ctor = this.constructor, map = ctor._onMap;
+			if(!map){
+				map = (ctor._onMap = {});
+				for(var attr in ctor.prototype){
+					if(/^on/.test(attr)){
+						map[attr.replace(/^on/, "").toLowerCase()] = attr;
+					}
 				}
 			}
-		}
-		return map[type.toLowerCase()];	// String
-	},
+			return map[typeof type == "string" && type.toLowerCase()];	// String
+		},
+
+		toString: function(){
+			// summary:
+			//		Returns a string that represents the widget.
+			// description:
+			//		When a widget is cast to a string, this method will be used to generate the
+			//		output. Currently, it does not implement any sort of reversible
+			//		serialization.
+			return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
+		},
+
+		getChildren: function(){
+			// summary:
+			//		Returns all direct children of this widget, i.e. all widgets underneath this.containerNode whose parent
+			//		is this widget.   Note that it does not return all descendants, but rather just direct children.
+			//		Analogous to [Node.childNodes](https://developer.mozilla.org/en-US/docs/DOM/Node.childNodes),
+			//		except containing widgets rather than DOMNodes.
+			//
+			//		The result intentionally excludes internally created widgets (a.k.a. supporting widgets)
+			//		outside of this.containerNode.
+			//
+			//		Note that the array returned is a simple array.  Application code should not assume
+			//		existence of methods like forEach().
+
+			return this.containerNode ? registry.findWidgets(this.containerNode) : []; // dijit/_WidgetBase[]
+		},
+
+		getParent: function(){
+			// summary:
+			//		Returns the parent widget of this widget.
+
+			return registry.getEnclosingWidget(this.domNode.parentNode);
+		},
+
+		connect: function(/*Object|null*/ obj, /*String|Function*/ event, /*String|Function*/ method){
+			// summary:
+			//		Deprecated, will be removed in 2.0, use this.own(on(...)) or this.own(aspect.after(...)) instead.
+			//
+			//		Connects specified obj/event to specified method of this object
+			//		and registers for disconnect() on widget destroy.
+			//
+			//		Provide widget-specific analog to dojo.connect, except with the
+			//		implicit use of this widget as the target object.
+			//		Events connected with `this.connect` are disconnected upon
+			//		destruction.
+			// returns:
+			//		A handle that can be passed to `disconnect` in order to disconnect before
+			//		the widget is destroyed.
+			// example:
+			//	|	var btn = new Button();
+			//	|	// when foo.bar() is called, call the listener we're going to
+			//	|	// provide in the scope of btn
+			//	|	btn.connect(foo, "bar", function(){
+			//	|		console.debug(this.toString());
+			//	|	});
+			// tags:
+			//		protected
+
+			return this.own(connect.connect(obj, event, this, method))[0];	// handle
+		},
+
+		disconnect: function(handle){
+			// summary:
+			//		Deprecated, will be removed in 2.0, use handle.remove() instead.
+			//
+			//		Disconnects handle created by `connect`.
+			// tags:
+			//		protected
 
-	toString: function(){
-		// summary:
-		//		Returns a string that represents the widget
-		// description:
-		//		When a widget is cast to a string, this method will be used to generate the
-		//		output. Currently, it does not implement any sort of reversible
-		//		serialization.
-		return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
-	},
-
-	getChildren: function(){
-		// summary:
-		//		Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
-		//		Does not return nested widgets, nor widgets that are part of this widget's template.
-		return this.containerNode ? registry.findWidgets(this.containerNode) : []; // dijit._Widget[]
-	},
-
-	getParent: function(){
-		// summary:
-		//		Returns the parent widget of this widget
-		return registry.getEnclosingWidget(this.domNode.parentNode);
-	},
-
-	connect: function(
-			/*Object|null*/ obj,
-			/*String|Function*/ event,
-			/*String|Function*/ method){
-		// summary:
-		//		Connects specified obj/event to specified method of this object
-		//		and registers for disconnect() on widget destroy.
-		// description:
-		//		Provide widget-specific analog to dojo.connect, except with the
-		//		implicit use of this widget as the target object.
-		//		Events connected with `this.connect` are disconnected upon
-		//		destruction.
-		// returns:
-		//		A handle that can be passed to `disconnect` in order to disconnect before
-		//		the widget is destroyed.
-		// example:
-		//	|	var btn = new dijit.form.Button();
-		//	|	// when foo.bar() is called, call the listener we're going to
-		//	|	// provide in the scope of btn
-		//	|	btn.connect(foo, "bar", function(){
-		//	|		console.debug(this.toString());
-		//	|	});
-		// tags:
-		//		protected
-
-		var handle = connect.connect(obj, event, this, method);
-		this._connects.push(handle);
-		return handle;		// _Widget.Handle
-	},
-
-	disconnect: function(handle){
-		// summary:
-		//		Disconnects handle created by `connect`.
-		//		Also removes handle from this widget's list of connects.
-		// tags:
-		//		protected
-		var i = array.indexOf(this._connects, handle);
-		if(i != -1){
 			handle.remove();
-			this._connects.splice(i, 1);
-		}
-	},
-
-	subscribe: function(t, method){
-		// summary:
-		//		Subscribes to the specified topic and calls the specified method
-		//		of this object and registers for unsubscribe() on widget destroy.
-		// description:
-		//		Provide widget-specific analog to dojo.subscribe, except with the
-		//		implicit use of this widget as the target object.
-		// t: String
-		//		The topic
-		// method: Function
-		//		The callback
-		// example:
-		//	|	var btn = new dijit.form.Button();
-		//	|	// when /my/topic is published, this button changes its label to
-		//	|   // be the parameter of the topic.
-		//	|	btn.subscribe("/my/topic", function(v){
-		//	|		this.set("label", v);
-		//	|	});
-		// tags:
-		//		protected
-		var handle = topic.subscribe(t, lang.hitch(this, method));
-		this._connects.push(handle);
-		return handle;		// _Widget.Handle
-	},
-
-	unsubscribe: function(/*Object*/ handle){
-		// summary:
-		//		Unsubscribes handle created by this.subscribe.
-		//		Also removes handle from this widget's list of subscriptions
-		// tags:
-		//		protected
-		this.disconnect(handle);
-	},
-
-	isLeftToRight: function(){
-		// summary:
-		//		Return this widget's explicit or implicit orientation (true for LTR, false for RTL)
-		// tags:
-		//		protected
-		return this.dir ? (this.dir == "ltr") : domGeometry.isBodyLtr(); //Boolean
-	},
+		},
+
+		subscribe: function(t, method){
+			// summary:
+			//		Deprecated, will be removed in 2.0, use this.own(topic.subscribe()) instead.
+			//
+			//		Subscribes to the specified topic and calls the specified method
+			//		of this object and registers for unsubscribe() on widget destroy.
+			//
+			//		Provide widget-specific analog to dojo.subscribe, except with the
+			//		implicit use of this widget as the target object.
+			// t: String
+			//		The topic
+			// method: Function
+			//		The callback
+			// example:
+			//	|	var btn = new Button();
+			//	|	// when /my/topic is published, this button changes its label to
+			//	|	// be the parameter of the topic.
+			//	|	btn.subscribe("/my/topic", function(v){
+			//	|		this.set("label", v);
+			//	|	});
+			// tags:
+			//		protected
+			return this.own(topic.subscribe(t, lang.hitch(this, method)))[0];	// handle
+		},
+
+		unsubscribe: function(/*Object*/ handle){
+			// summary:
+			//		Deprecated, will be removed in 2.0, use handle.remove() instead.
+			//
+			//		Unsubscribes handle created by this.subscribe.
+			//		Also removes handle from this widget's list of subscriptions
+			// tags:
+			//		protected
 
-	isFocusable: function(){
-		// summary:
-		//		Return true if this widget can currently be focused
-		//		and false if not
-		return this.focus && (domStyle.get(this.domNode, "display") != "none");
-	},
-
-	placeAt: function(/* String|DomNode|_Widget */reference, /* String?|Int? */position){
-		// summary:
-		//		Place this widget's domNode reference somewhere in the DOM based
-		//		on standard domConstruct.place conventions, or passing a Widget reference that
-		//		contains and addChild member.
-		//
-		// description:
-		//		A convenience function provided in all _Widgets, providing a simple
-		//		shorthand mechanism to put an existing (or newly created) Widget
-		//		somewhere in the dom, and allow chaining.
-		//
-		// reference:
-		//		The String id of a domNode, a domNode reference, or a reference to a Widget possessing
-		//		an addChild method.
-		//
-		// position:
-		//		If passed a string or domNode reference, the position argument
-		//		accepts a string just as domConstruct.place does, one of: "first", "last",
-		//		"before", or "after".
-		//
-		//		If passed a _Widget reference, and that widget reference has an ".addChild" method,
-		//		it will be called passing this widget instance into that method, supplying the optional
-		//		position index passed.
-		//
-		// returns:
-		//		dijit._Widget
-		//		Provides a useful return of the newly created dijit._Widget instance so you
-		//		can "chain" this function by instantiating, placing, then saving the return value
-		//		to a variable.
-		//
-		// example:
-		// | 	// create a Button with no srcNodeRef, and place it in the body:
-		// | 	var button = new dijit.form.Button({ label:"click" }).placeAt(win.body());
-		// | 	// now, 'button' is still the widget reference to the newly created button
-		// | 	button.on("click", function(e){ console.log('click'); }));
-		//
-		// example:
-		// |	// create a button out of a node with id="src" and append it to id="wrapper":
-		// | 	var button = new dijit.form.Button({},"src").placeAt("wrapper");
-		//
-		// example:
-		// |	// place a new button as the first element of some div
-		// |	var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
-		//
-		// example:
-		// |	// create a contentpane and add it to a TabContainer
-		// |	var tc = dijit.byId("myTabs");
-		// |	new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
-
-		if(reference.declaredClass && reference.addChild){
-			reference.addChild(this, position);
-		}else{
-			domConstruct.place(this.domNode, reference, position);
+			handle.remove();
+		},
+
+		isLeftToRight: function(){
+			// summary:
+			//		Return this widget's explicit or implicit orientation (true for LTR, false for RTL)
+			// tags:
+			//		protected
+			return this.dir ? (this.dir == "ltr") : domGeometry.isBodyLtr(this.ownerDocument); //Boolean
+		},
+
+		isFocusable: function(){
+			// summary:
+			//		Return true if this widget can currently be focused
+			//		and false if not
+			return this.focus && (domStyle.get(this.domNode, "display") != "none");
+		},
+
+		placeAt: function(/* String|DomNode|_Widget */ reference, /* String|Int? */ position){
+			// summary:
+			//		Place this widget somewhere in the DOM based
+			//		on standard domConstruct.place() conventions.
+			// description:
+			//		A convenience function provided in all _Widgets, providing a simple
+			//		shorthand mechanism to put an existing (or newly created) Widget
+			//		somewhere in the dom, and allow chaining.
+			// reference:
+			//		Widget, DOMNode, or id of widget or DOMNode
+			// position:
+			//		If reference is a widget (or id of widget), and that widget has an ".addChild" method,
+			//		it will be called passing this widget instance into that method, supplying the optional
+			//		position index passed.  In this case position (if specified) should be an integer.
+			//
+			//		If reference is a DOMNode (or id matching a DOMNode but not a widget),
+			//		the position argument can be a numeric index or a string
+			//		"first", "last", "before", or "after", same as dojo/dom-construct::place().
+			// returns: dijit/_WidgetBase
+			//		Provides a useful return of the newly created dijit._Widget instance so you
+			//		can "chain" this function by instantiating, placing, then saving the return value
+			//		to a variable.
+			// example:
+			//	|	// create a Button with no srcNodeRef, and place it in the body:
+			//	|	var button = new Button({ label:"click" }).placeAt(win.body());
+			//	|	// now, 'button' is still the widget reference to the newly created button
+			//	|	button.on("click", function(e){ console.log('click'); }));
+			// example:
+			//	|	// create a button out of a node with id="src" and append it to id="wrapper":
+			//	|	var button = new Button({},"src").placeAt("wrapper");
+			// example:
+			//	|	// place a new button as the first element of some div
+			//	|	var button = new Button({ label:"click" }).placeAt("wrapper","first");
+			// example:
+			//	|	// create a contentpane and add it to a TabContainer
+			//	|	var tc = dijit.byId("myTabs");
+			//	|	new ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
+
+			var refWidget = !reference.tagName && registry.byId(reference);
+			if(refWidget && refWidget.addChild && (!position || typeof position === "number")){
+				// Adding this to refWidget and can use refWidget.addChild() to handle everything.
+				refWidget.addChild(this, position);
+			}else{
+				// "reference" is a plain DOMNode, or we can't use refWidget.addChild().   Use domConstruct.place() and
+				// target refWidget.containerNode for nested placement (position==number, "first", "last", "only"), and
+				// refWidget.domNode otherwise ("after"/"before"/"replace").  (But not supported officially, see #14946.)
+				var ref = refWidget ?
+					(refWidget.containerNode && !/after|before|replace/.test(position || "") ?
+						refWidget.containerNode : refWidget.domNode) : dom.byId(reference, this.ownerDocument);
+				domConstruct.place(this.domNode, ref, position);
+
+				// Start this iff it has a parent widget that's already started.
+				// TODO: for 2.0 maybe it should also start the widget when this.getParent() returns null??
+				if(!this._started && (this.getParent() || {})._started){
+					this.startup();
+				}
+			}
+			return this;
+		},
+
+		defer: function(fcn, delay){
+			// summary:
+			//		Wrapper to setTimeout to avoid deferred functions executing
+			//		after the originating widget has been destroyed.
+			//		Returns an object handle with a remove method (that returns null) (replaces clearTimeout).
+			// fcn: function reference
+			// delay: Optional number (defaults to 0)
+			// tags:
+			//		protected.
+			var timer = setTimeout(lang.hitch(this,
+				function(){
+					if(!timer){
+						return;
+					}
+					timer = null;
+					if(!this._destroyed){
+						lang.hitch(this, fcn)();
+					}
+				}),
+				delay || 0
+			);
+			return {
+				remove: function(){
+					if(timer){
+						clearTimeout(timer);
+						timer = null;
+					}
+					return null; // so this works well: handle = handle.remove();
+				}
+			};
 		}
-		return this;
-	},
+	});
 
-	getTextDir: function(/*String*/ text,/*String*/ originalDir){
-		// summary:
-		//		Return direction of the text.
-		//		The function overridden in the _BidiSupport module,
-		//		its main purpose is to calculate the direction of the
-		//		text, if was defined by the programmer through textDir.
-		//	tags:
-		//		protected.
-		return originalDir;
-	},
-
-	applyTextDir: function(/*===== element, text =====*/){
-		// summary:
-		//		The function overridden in the _BidiSupport module,
-		//		originally used for setting element.dir according to this.textDir.
-		//		In this case does nothing.
-		// element: DOMNode
-		// text: String
-		// tags:
-		//		protected.
+	if(has("dojo-bidi")){
+		_WidgetBase.extend(_BidiMixin);
 	}
-});
 
+	return _WidgetBase;
 });
diff --git a/dijit/_WidgetsInTemplateMixin.js b/dijit/_WidgetsInTemplateMixin.js
index a4e7c92..553ea25 100644
--- a/dijit/_WidgetsInTemplateMixin.js
+++ b/dijit/_WidgetsInTemplateMixin.js
@@ -1,14 +1,13 @@
 define([
-	"dojo/_base/array", // array.forEach
-	"dojo/_base/declare", // declare
-	"dojo/parser", // parser.parse
-	"dijit/registry"	// registry.findWidgets
-], function(array, declare, parser, registry){
+	"dojo/_base/array", // forEach()
+	"dojo/aspect", // after()
+	"dojo/_base/declare", // declare()
+	"dojo/_base/lang",	// hitch()
+	"dojo/parser" // parse()
+], function(array, aspect, declare, lang, parser){
 
 	// module:
 	//		dijit/_WidgetsInTemplateMixin
-	// summary:
-	//		Mixin to supplement _TemplatedMixin when template contains widgets
 
 	return declare("dijit._WidgetsInTemplateMixin", null, {
 		// summary:
@@ -28,25 +27,74 @@ define([
 		//		declared in markup inside it?  (Remove for 2.0 and assume true)
 		widgetsInTemplate: true,
 
+		// contextRequire: Function
+		//		Used to provide a context require to the dojo/parser in order to be
+		//		able to use relative MIDs (e.g. `./Widget`) in the widget's template.
+		contextRequire: null,
+
 		_beforeFillContent: function(){
 			if(this.widgetsInTemplate){
 				// Before copying over content, instantiate widgets in template
 				var node = this.domNode;
 
-				var cw = (this._startupWidgets = parser.parse(node, {
+				if(this.containerNode && !this.searchContainerNode){
+					// Tell parse call below not to look for widgets inside of this.containerNode
+					this.containerNode.stopParser = true;
+				}
+
+				parser.parse(node, {
 					noStart: !this._earlyTemplatedStartup,
 					template: true,
 					inherited: {dir: this.dir, lang: this.lang, textDir: this.textDir},
 					propsThis: this,	// so data-dojo-props of widgets in the template can reference "this" to refer to me
+					contextRequire: this.contextRequire,
 					scope: "dojo"	// even in multi-version mode templates use dojoType/data-dojo-type
+				}).then(lang.hitch(this, function(widgets){
+					this._startupWidgets = widgets;
+
+					// _WidgetBase::destroy() will destroy any supporting widgets under this.domNode.
+					// If we wanted to, we could call this.own() on anything in this._startupWidgets that was moved outside
+					// of this.domNode (like Dialog, which is moved to <body>).
+
+					// Hook up attach points and events for nodes that were converted to widgets
+					for(var i = 0; i < widgets.length; i++){
+						this._processTemplateNode(widgets[i], function(n,p){
+							// callback to get a property of a widget
+							return n[p];
+						}, function(widget, type, callback){
+							// callback to do data-dojo-attach-event to a widget
+							if(type in widget){
+								// back-compat, remove for 2.0
+								return widget.connect(widget, type, callback);
+							}else{
+								// 1.x may never hit this branch, but it's the default for 2.0
+								return widget.on(type, callback, true);
+							}
+						});
+					}
+
+					// Cleanup flag set above, just in case
+					if(this.containerNode && this.containerNode.stopParser){
+						delete this.containerNode.stopParser;
+					}
 				}));
 
-				this._supportingWidgets = registry.findWidgets(node);
+				if(!this._startupWidgets){
+					throw new Error(this.declaredClass + ": parser returned unfilled promise (probably waiting for module auto-load), " +
+						"unsupported by _WidgetsInTemplateMixin.   Must pre-load all supporting widgets before instantiation.");
+				}
+			}
+		},
 
-				this._attachTemplateNodes(cw, function(n,p){
-					return n[p];
-				});
+		_processTemplateNode: function(/*DOMNode|Widget*/ baseNode, getAttrFunc, attachFunc){
+			// Override _AttachMixin._processNode to skip DOMNodes with data-dojo-type set.   They are handled separately
+			// in the _beforeFillContent() code above.
+
+			if(getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type")){
+				return true;
 			}
+
+			return this.inherited(arguments);
 		},
 
 		startup: function(){
@@ -55,6 +103,7 @@ define([
 					w.startup();
 				}
 			});
+			this._startupWidgets = null;
 			this.inherited(arguments);
 		}
 	});
diff --git a/dijit/_base.js b/dijit/_base.js
index 1fc06fa..671f99f 100644
--- a/dijit/_base.js
+++ b/dijit/_base.js
@@ -1,5 +1,5 @@
 define([
-	".",
+	"./main",
 	"./a11y",	// used to be in dijit/_base/manager
 	"./WidgetSet",	// used to be in dijit/_base/manager
 	"./_base/focus",
@@ -15,8 +15,13 @@ define([
 
 	// module:
 	//		dijit/_base
-	// summary:
-	//		Includes all the modules in dijit/_base
+
+	/*=====
+	return {
+		// summary:
+		//		Includes all the modules in dijit/_base
+	};
+	=====*/
 
 	return dijit._base;
 });
diff --git a/dijit/_base/focus.js b/dijit/_base/focus.js
index aa85d00..94f3071 100644
--- a/dijit/_base/focus.js
+++ b/dijit/_base/focus.js
@@ -5,16 +5,18 @@ define([
 	"dojo/topic", // publish
 	"dojo/_base/window", // win.doc win.doc.selection win.global win.global.getSelection win.withGlobal
 	"../focus",
-	".."	// for exporting symbols to dijit
-], function(array, dom, lang, topic, win, focus, dijit){
+	"../selection",
+	"../main"	// for exporting symbols to dijit
+], function(array, dom, lang, topic, win, focus, selection, dijit){
 
 	// module:
 	//		dijit/_base/focus
-	// summary:
-	//		Deprecated module to monitor currently focused node and stack of currently focused widgets.
-	//		New code should access dijit/focus directly.
 
-	lang.mixin(dijit, {
+	var exports = {
+		// summary:
+		//		Deprecated module to monitor currently focused node and stack of currently focused widgets.
+		//		New code should access dijit/focus directly.
+
 		// _curFocus: DomNode
 		//		Currently focused item on screen
 		_curFocus: null,
@@ -32,90 +34,8 @@ define([
 		getBookmark: function(){
 			// summary:
 			//		Retrieves a bookmark that can be used with moveToBookmark to return to the same range
-			var bm, rg, tg, sel = win.doc.selection, cf = focus.curNode;
-
-			if(win.global.getSelection){
-				//W3C Range API for selections.
-				sel = win.global.getSelection();
-				if(sel){
-					if(sel.isCollapsed){
-						tg = cf? cf.tagName : "";
-						if(tg){
-							//Create a fake rangelike item to restore selections.
-							tg = tg.toLowerCase();
-							if(tg == "textarea" ||
-									(tg == "input" && (!cf.type || cf.type.toLowerCase() == "text"))){
-								sel = {
-									start: cf.selectionStart,
-									end: cf.selectionEnd,
-									node: cf,
-									pRange: true
-								};
-								return {isCollapsed: (sel.end <= sel.start), mark: sel}; //Object.
-							}
-						}
-						bm = {isCollapsed:true};
-						if(sel.rangeCount){
-							bm.mark = sel.getRangeAt(0).cloneRange();
-						}
-					}else{
-						rg = sel.getRangeAt(0);
-						bm = {isCollapsed: false, mark: rg.cloneRange()};
-					}
-				}
-			}else if(sel){
-				// If the current focus was a input of some sort and no selection, don't bother saving
-				// a native bookmark.  This is because it causes issues with dialog/page selection restore.
-				// So, we need to create psuedo bookmarks to work with.
-				tg = cf ? cf.tagName : "";
-				tg = tg.toLowerCase();
-				if(cf && tg && (tg == "button" || tg == "textarea" || tg == "input")){
-					if(sel.type && sel.type.toLowerCase() == "none"){
-						return {
-							isCollapsed: true,
-							mark: null
-						}
-					}else{
-						rg = sel.createRange();
-						return {
-							isCollapsed: rg.text && rg.text.length?false:true,
-							mark: {
-								range: rg,
-								pRange: true
-							}
-						};
-					}
-				}
-				bm = {};
-
-				//'IE' way for selections.
-				try{
-					// createRange() throws exception when dojo in iframe
-					//and nothing selected, see #9632
-					rg = sel.createRange();
-					bm.isCollapsed = !(sel.type == 'Text' ? rg.htmlText.length : rg.length);
-				}catch(e){
-					bm.isCollapsed = true;
-					return bm;
-				}
-				if(sel.type.toUpperCase() == 'CONTROL'){
-					if(rg.length){
-						bm.mark=[];
-						var i=0,len=rg.length;
-						while(i<len){
-							bm.mark.push(rg.item(i++));
-						}
-					}else{
-						bm.isCollapsed = true;
-						bm.mark = null;
-					}
-				}else{
-					bm.mark = rg.getBookmark();
-				}
-			}else{
-				console.warn("No idea how to store the current selection for this browser!");
-			}
-			return bm; // Object
+			var sel = win.global == window ? selection : new selection.SelectionManager(win.global);
+			return sel.getBookmark();
 		},
 
 		moveToBookmark: function(/*Object*/ bookmark){
@@ -124,43 +44,8 @@ define([
 			// bookmark:
 			//		This should be a returned object from dijit.getBookmark()
 
-			var _doc = win.doc,
-				mark = bookmark.mark;
-			if(mark){
-				if(win.global.getSelection){
-					//W3C Rangi API (FF, WebKit, Opera, etc)
-					var sel = win.global.getSelection();
-					if(sel && sel.removeAllRanges){
-						if(mark.pRange){
-							var n = mark.node;
-							n.selectionStart = mark.start;
-							n.selectionEnd = mark.end;
-						}else{
-							sel.removeAllRanges();
-							sel.addRange(mark);
-						}
-					}else{
-						console.warn("No idea how to restore selection for this browser!");
-					}
-				}else if(_doc.selection && mark){
-					//'IE' way.
-					var rg;
-					if(mark.pRange){
-						rg = mark.range;
-					}else if(lang.isArray(mark)){
-						rg = _doc.body.createControlRange();
-						//rg.addElement does not have call/apply method, so can not call it directly
-						//rg is not available in "range.addElement(item)", so can't use that either
-						array.forEach(mark, function(n){
-							rg.addElement(n);
-						});
-					}else{
-						rg = _doc.body.createTextRange();
-						rg.moveToBookmark(mark);
-					}
-					rg.select();
-				}
-			}
+			var sel = win.global == window ? selection : new selection.SelectionManager(win.global);
+			return sel.moveToBookmark(bookmark);
 		},
 
 		getFocus: function(/*Widget?*/ menu, /*Window?*/ openedForWindow){
@@ -174,7 +59,7 @@ define([
 			//		or removed focus altogether.)   In this case the selected text is not returned,
 			//		since it can't be accurately determined.
 			//
-			// menu: dijit._Widget or {domNode: DomNode} structure
+			// menu: dijit/_WidgetBase|{domNode: DomNode} structure
 			//		The button that was just pressed.  If focus has disappeared or moved
 			//		to this button, returns the previous focus.  In this case the bookmark
 			//		information is already lost, and null is returned.
@@ -192,7 +77,7 @@ define([
 			}; // Object
 		},
 
-		// _activeStack: dijit._Widget[]
+		// _activeStack: dijit/_WidgetBase[]
 		//		List of currently active widgets (focused widget and it's ancestors)
 		_activeStack: [],
 
@@ -200,7 +85,7 @@ define([
 			// summary:
 			//		Registers listeners on the specified iframe so that any click
 			//		or focus event on that iframe (or anything in it) is reported
-			//		as a focus/click event on the <iframe> itself.
+			//		as a focus/click event on the `<iframe>` itself.
 			// description:
 			//		Currently only used by editor.
 			// returns:
@@ -245,12 +130,12 @@ define([
 
 			handle && handle.remove();
 		}
-	});
+	};
 
 	// Override focus singleton's focus function so that dijit.focus()
 	// has backwards compatible behavior of restoring selection (although
 	// probably no one is using that).
-	focus.focus = function(/*Object || DomNode */ handle){
+	focus.focus = function(/*Object|DomNode */ handle){
 		// summary:
 		//		Sets the focused node and the selection according to argument.
 		//		To set focus to an iframe's content, pass in the iframe itself.
@@ -315,5 +200,8 @@ define([
 		topic.publish("widgetFocus", widget, by);	// publish
 	});
 
-	return dijit;
+	lang.mixin(dijit, exports);
+
+	/*===== return exports; =====*/
+	return dijit;	// for back compat :-(
 });
diff --git a/dijit/_base/manager.js b/dijit/_base/manager.js
index 783c533..7f4f7ed 100644
--- a/dijit/_base/manager.js
+++ b/dijit/_base/manager.js
@@ -1,76 +1,35 @@
 define([
 	"dojo/_base/array",
 	"dojo/_base/config", // defaultDuration
+	"dojo/_base/lang",
 	"../registry",
-	".."	// for setting exports to dijit namespace
-], function(array, config, registry, dijit){
+	"../main"	// for setting exports to dijit namespace
+], function(array, config, lang, registry, dijit){
 
 	// module:
 	//		dijit/_base/manager
-	// summary:
-	//		Shim to methods on registry, plus a few other declarations.
-	//		New code should access dijit/registry directly when possible.
 
-	/*=====
-	dijit.byId = function(id){
+	var exports = {
 		// summary:
-		//		Returns a widget by it's id, or if passed a widget, no-op (like dom.byId())
-		// id: String|dijit._Widget
-		return registry.byId(id); // dijit._Widget
+		//		Deprecated.  Shim to methods on registry, plus a few other declarations.
+		//		New code should access dijit/registry directly when possible.
 	};
 
-	dijit.getUniqueId = function(widgetType){
-		// summary:
-		//		Generates a unique id for a given widgetType
-		// widgetType: String
-		return registry.getUniqueId(widgetType); // String
-	};
-
-	dijit.findWidgets = function(root){
-		// summary:
-		//		Search subtree under root returning widgets found.
-		//		Doesn't search for nested widgets (ie, widgets inside other widgets).
-		// root: DOMNode
-		return registry.findWidgets(root);
-	};
-
-	dijit._destroyAll = function(){
-		// summary:
-		//		Code to destroy all widgets and do other cleanup on page unload
-
-		return registry._destroyAll();
-	};
-
-	dijit.byNode = function(node){
-		// summary:
-		//		Returns the widget corresponding to the given DOMNode
-		// node: DOMNode
-		return registry.byNode(node); // dijit._Widget
-	};
-
-	dijit.getEnclosingWidget = function(node){
-		// summary:
-		//		Returns the widget whose DOM tree contains the specified DOMNode, or null if
-		//		the node is not contained within the DOM tree of any widget
-		// node: DOMNode
-		return registry.getEnclosingWidget(node);
-	};
-	=====*/
 	array.forEach(["byId", "getUniqueId", "findWidgets", "_destroyAll", "byNode", "getEnclosingWidget"], function(name){
-		dijit[name] = registry[name];
+		exports[name] = registry[name];
 	});
 
-	/*=====
-	dojo.mixin(dijit, {
-		// defaultDuration: Integer
-		//		The default fx.animation speed (in ms) to use for all Dijit
-		//		transitional fx.animations, unless otherwise specified
-		//		on a per-instance basis. Defaults to 200, overrided by
-		//		`djConfig.defaultDuration`
-		defaultDuration: 200
-	});
-	=====*/
-	dijit.defaultDuration = config["defaultDuration"] || 200;
+	 lang.mixin(exports, {
+		 // defaultDuration: Integer
+		 //		The default fx.animation speed (in ms) to use for all Dijit
+		 //		transitional fx.animations, unless otherwise specified
+		 //		on a per-instance basis. Defaults to 200, overrided by
+		 //		`djConfig.defaultDuration`
+		 defaultDuration: config["defaultDuration"] || 200
+	 });
+
+	lang.mixin(dijit, exports);
 
-	return dijit;
+	/*===== return exports; =====*/
+	return dijit;	// for back compat :-(
 });
diff --git a/dijit/_base/place.js b/dijit/_base/place.js
index 713bde9..dbfd2a6 100644
--- a/dijit/_base/place.js
+++ b/dijit/_base/place.js
@@ -1,17 +1,21 @@
 define([
 	"dojo/_base/array", // array.forEach
-	"dojo/_base/lang", // lang.isArray
+	"dojo/_base/lang", // lang.isArray, lang.mixin
 	"dojo/window", // windowUtils.getBox
 	"../place",
-	".."	// export to dijit namespace
+	"../main"	// export to dijit namespace
 ], function(array, lang, windowUtils, place, dijit){
 
 	// module:
 	//		dijit/_base/place
-	// summary:
-	//		Back compatibility module, new code should use dijit/place directly instead of using this module.
 
-	dijit.getViewport = function(){
+
+	var exports = {
+		// summary:
+		//		Deprecated back compatibility module, new code should use dijit/place directly instead of using this module.
+	};
+
+	exports.getViewport = function(){
 		// summary:
 		//		Deprecated method to return the dimensions and scroll position of the viewable area of a browser window.
 		//		New code should use windowUtils.getBox()
@@ -19,29 +23,18 @@ define([
 		return windowUtils.getBox();
 	};
 
-	/*=====
-	dijit.placeOnScreen = function(node, pos, corners, padding){
-		// summary:
-		//		Positions one of the node's corners at specified position
-		//		such that node is fully visible in viewport.
-		//		Deprecated, new code should use dijit.place.at() instead.
-	};
-	=====*/
-	dijit.placeOnScreen = place.at;
+	exports.placeOnScreen = place.at;
 
-	/*=====
-	dijit.placeOnScreenAroundElement = function(node, aroundElement, aroundCorners, layoutNode){
+	exports.placeOnScreenAroundElement = function(node, aroundNode, aroundCorners, layoutNode){
 		// summary:
 		//		Like dijit.placeOnScreenAroundNode(), except it accepts an arbitrary object
 		//		for the "around" argument and finds a proper processor to place a node.
-		//		Deprecated, new code should use dijit.place.around() instead.
-	};
-	====*/
-	dijit.placeOnScreenAroundElement = function(node, aroundNode, aroundCorners, layoutNode){
+		//		Deprecated, new code should use dijit/place.around() instead.
+
 		// Convert old style {"BL": "TL", "BR": "TR"} type argument
 		// to style needed by dijit.place code:
 		//		[
-		// 			{aroundCorner: "BL", corner: "TL" },
+		//			{aroundCorner: "BL", corner: "TL" },
 		//			{aroundCorner: "BR", corner: "TR" }
 		//		]
 		var positions;
@@ -57,50 +50,48 @@ define([
 		return place.around(node, aroundNode, positions, true, layoutNode);
 	};
 
+	exports.placeOnScreenAroundNode = exports.placeOnScreenAroundElement;
 	/*=====
-	dijit.placeOnScreenAroundNode = function(node, aroundNode, aroundCorners, layoutNode){
+	exports.placeOnScreenAroundNode = function(node, aroundNode, aroundCorners, layoutNode){
 		// summary:
 		//		Position node adjacent or kitty-corner to aroundNode
 		//		such that it's fully visible in viewport.
-		//		Deprecated, new code should use dijit.place.around() instead.
+		//		Deprecated, new code should use dijit/place.around() instead.
 	};
 	=====*/
-	dijit.placeOnScreenAroundNode = dijit.placeOnScreenAroundElement;
 
+	exports.placeOnScreenAroundRectangle = exports.placeOnScreenAroundElement;
 	/*=====
-	dijit.placeOnScreenAroundRectangle = function(node, aroundRect, aroundCorners, layoutNode){
+	exports.placeOnScreenAroundRectangle = function(node, aroundRect, aroundCorners, layoutNode){
 		// summary:
 		//		Like dijit.placeOnScreenAroundNode(), except that the "around"
 		//		parameter is an arbitrary rectangle on the screen (x, y, width, height)
 		//		instead of a dom node.
-		//		Deprecated, new code should use dijit.place.around() instead.
+		//		Deprecated, new code should use dijit/place.around() instead.
 	};
 	=====*/
-	dijit.placeOnScreenAroundRectangle = dijit.placeOnScreenAroundElement;
 
-	dijit.getPopupAroundAlignment = function(/*Array*/ position, /*Boolean*/ leftToRight){
+	exports.getPopupAroundAlignment = function(/*Array*/ position, /*Boolean*/ leftToRight){
 		// summary:
 		//		Deprecated method, unneeded when using dijit/place directly.
 		//		Transforms the passed array of preferred positions into a format suitable for
-		//		passing as the aroundCorners argument to dijit.placeOnScreenAroundElement.
-		//
+		//		passing as the aroundCorners argument to dijit/place.placeOnScreenAroundElement.
 		// position: String[]
 		//		This variable controls the position of the drop down.
 		//		It's an array of strings with the following values:
 		//
-		//			* before: places drop down to the left of the target node/widget, or to the right in
-		//			  the case of RTL scripts like Hebrew and Arabic
-		//			* after: places drop down to the right of the target node/widget, or to the left in
-		//			  the case of RTL scripts like Hebrew and Arabic
-		//			* above: drop down goes above target node
-		//			* below: drop down goes below target node
+		//		- before: places drop down to the left of the target node/widget, or to the right in
+		//		  the case of RTL scripts like Hebrew and Arabic
+		//		- after: places drop down to the right of the target node/widget, or to the left in
+		//		  the case of RTL scripts like Hebrew and Arabic
+		//		- above: drop down goes above target node
+		//		- below: drop down goes below target node
 		//
 		//		The list is positions is tried, in order, until a position is found where the drop down fits
 		//		within the viewport.
-		//
 		// leftToRight: Boolean
 		//		Whether the popup will be displaying in leftToRight mode.
-		//
+
 		var align = {};
 		array.forEach(position, function(pos){
 			var ltr = leftToRight;
@@ -133,5 +124,8 @@ define([
 		return align;
 	};
 
-	return dijit;
+	lang.mixin(dijit, exports);
+
+	/*===== return exports; =====*/
+	return dijit;	// for back compat :-(
 });
diff --git a/dijit/_base/popup.js b/dijit/_base/popup.js
index eedc453..2b0aa20 100644
--- a/dijit/_base/popup.js
+++ b/dijit/_base/popup.js
@@ -1,13 +1,19 @@
 define([
 	"dojo/dom-class", // domClass.contains
+	"dojo/_base/window",
 	"../popup",
 	"../BackgroundIframe"	// just loading for back-compat, in case client code is referencing it
-], function(domClass, popup){
+], function(domClass, win, popup){
 
 // module:
 //		dijit/_base/popup
-// summary:
-//		Old module for popups, new code should use dijit/popup directly
+
+/*=====
+return {
+	// summary:
+	//		Deprecated.   Old module for popups, new code should use dijit/popup directly.
+};
+=====*/
 
 
 // Hack support for old API passing in node instead of a widget (to various methods)
@@ -19,7 +25,9 @@ popup._createWrapper = function(widget){
 			_popupWrapper: (widget.parentNode && domClass.contains(widget.parentNode, "dijitPopup")) ?
 				widget.parentNode : null,
 			domNode: widget,
-			destroy: function(){}
+			destroy: function(){},
+			ownerDocument: widget.ownerDocument,
+			ownerDocumentBody: win.body(widget.ownerDocument)
 		};
 	}
 	return origCreateWrapper.call(this, widget);
@@ -27,7 +35,7 @@ popup._createWrapper = function(widget){
 
 // Support old format of orient parameter
 var origOpen = popup.open;
-popup.open = function(/*dijit.popup.__OpenArgs*/ args){
+popup.open = function(/*__OpenArgs*/ args){
 	// Convert old hash structure (ex: {"BL": "TL", ...}) of orient to format compatible w/new popup.open() API.
 	// Don't do conversion for:
 	//		- null parameter (that means to use the default positioning)
diff --git a/dijit/_base/scroll.js b/dijit/_base/scroll.js
index a341a4b..4d9468c 100644
--- a/dijit/_base/scroll.js
+++ b/dijit/_base/scroll.js
@@ -1,11 +1,16 @@
 define([
 	"dojo/window", // windowUtils.scrollIntoView
-	".."	// export symbol to dijit
+	"../main"	// export symbol to dijit
 ], function(windowUtils, dijit){
 	// module:
 	//		dijit/_base/scroll
-	// summary:
-	//		Back compatibility module, new code should use windowUtils directly instead of using this module.
+
+	/*=====
+	return {
+		// summary:
+		//		Back compatibility module, new code should use windowUtils directly instead of using this module.
+	};
+	=====*/
 
 	dijit.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
 		// summary:
diff --git a/dijit/_base/sniff.js b/dijit/_base/sniff.js
index 450be52..2f4e547 100644
--- a/dijit/_base/sniff.js
+++ b/dijit/_base/sniff.js
@@ -1,6 +1,12 @@
 define([ "dojo/uacss" ], function(){
+
 	// module:
 	//		dijit/_base/sniff
-	// summary:
-	//		Back compatibility module, new code should require dojo/uacss directly instead of this module.
+
+	/*=====
+	return {
+		// summary:
+		//		Deprecated, back compatibility module, new code should require dojo/uacss directly instead of this module.
+	};
+	=====*/
 });
diff --git a/dijit/_base/typematic.js b/dijit/_base/typematic.js
index 62017b4..3ac8602 100644
--- a/dijit/_base/typematic.js
+++ b/dijit/_base/typematic.js
@@ -1,3 +1,10 @@
 define(["../typematic"], function(){
-	// for back-compat, just loads top level module
+
+	/*=====
+	return {
+		// summary:
+		//		Deprecated, for back-compat, just loads top level module
+	};
+	=====*/
+
 });
diff --git a/dijit/_base/wai.js b/dijit/_base/wai.js
index 1f93945..f139913 100644
--- a/dijit/_base/wai.js
+++ b/dijit/_base/wai.js
@@ -1,26 +1,27 @@
 define([
 	"dojo/dom-attr", // domAttr.attr
 	"dojo/_base/lang", // lang.mixin
-	"..",	// export symbols to dijit
+	"../main",	// export symbols to dijit
 	"../hccss"			// not using this module directly, but loading it sets CSS flag on <html>
 ], function(domAttr, lang, dijit){
 
 	// module:
 	//		dijit/_base/wai
-	// summary:
-	//		Deprecated methods for setting/getting wai roles and states.
-	//		New code should call setAttribute()/getAttribute() directly.
-	//
-	//		Also loads hccss to apply dijit_a11y class to root node if machine is in high-contrast mode.
 
-	lang.mixin(dijit, {
+	var exports = {
+		// summary:
+		//		Deprecated methods for setting/getting wai roles and states.
+		//		New code should call setAttribute()/getAttribute() directly.
+		//
+		//		Also loads hccss to apply dj_a11y class to root node if machine is in high-contrast mode.
+
 		hasWaiRole: function(/*Element*/ elem, /*String?*/ role){
 			// summary:
 			//		Determines if an element has a particular role.
 			// returns:
 			//		True if elem has the specific role attribute and false if not.
-			// 		For backwards compatibility if role parameter not provided,
-			// 		returns true if has a role
+			//		For backwards compatibility if role parameter not provided,
+			//		returns true if has a role
 			var waiRole = this.getWaiRole(elem);
 			return role ? (waiRole.indexOf(role) > -1) : (waiRole.length > 0);
 		},
@@ -46,7 +47,7 @@ define([
 		removeWaiRole: function(/*Element*/ elem, /*String*/ role){
 			// summary:
 			//		Removes the specified role from an element.
-			// 		Removes role attribute if no specific role provided (for backwards compat.)
+			//		Removes role attribute if no specific role provided (for backwards compat.)
 
 			var roleValue = domAttr.get(elem, "role");
 			if(!roleValue){ return; }
@@ -99,7 +100,10 @@ define([
 
 			elem.removeAttribute("aria-"+state);
 		}
-	});
+	};
+
+	lang.mixin(dijit, exports);
 
-	return dijit;
+	/*===== return exports; =====*/
+	return dijit;	// for back compat :-(
 });
diff --git a/dijit/_base/window.js b/dijit/_base/window.js
index 4015ea3..ba3f802 100644
--- a/dijit/_base/window.js
+++ b/dijit/_base/window.js
@@ -1,11 +1,16 @@
 define([
 	"dojo/window", // windowUtils.get
-	".."	// export symbol to dijit
+	"../main"	// export symbol to dijit
 ], function(windowUtils, dijit){
 	// module:
 	//		dijit/_base/window
-	// summary:
-	//		Back compatibility module, new code should use windowUtils directly instead of using this module.
+
+	/*=====
+	return {
+		// summary:
+		//		Back compatibility module, new code should use windowUtils directly instead of using this module.
+	};
+	=====*/
 
 	dijit.getDocumentWindow = function(doc){
 		return windowUtils.get(doc);
diff --git a/dijit/_editor/RichText.js b/dijit/_editor/RichText.js
index a2e1ebf..0921d84 100644
--- a/dijit/_editor/RichText.js
+++ b/dijit/_editor/RichText.js
@@ -7,2621 +7,2706 @@ define([
 	"dojo/dom-attr", // domAttr.set or get
 	"dojo/dom-class", // domClass.add domClass.remove
 	"dojo/dom-construct", // domConstruct.create domConstruct.destroy domConstruct.place
-	"dojo/dom-geometry", // domGeometry.getMarginBox domGeometry.position
+	"dojo/dom-geometry", // domGeometry.position
 	"dojo/dom-style", // domStyle.getComputedStyle domStyle.set
-	"dojo/_base/event", // event.stop
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/keys", // keys.BACKSPACE keys.TAB
 	"dojo/_base/lang", // lang.clone lang.hitch lang.isArray lang.isFunction lang.isString lang.trim
 	"dojo/on", // on()
 	"dojo/query", // query
-	"dojo/ready", // ready
-	"dojo/_base/sniff", // has("ie") has("mozilla") has("opera") has("safari") has("webkit")
-	"dojo/topic",	// topic.publish() (publish)
+	"dojo/domReady",
+	"dojo/sniff", // has("ie") has("mozilla") has("opera") has("safari") has("webkit")
+	"dojo/topic", // topic.publish() (publish)
 	"dojo/_base/unload", // unload
 	"dojo/_base/url", // url
-	"dojo/_base/window", // win.body win.doc.body.focus win.doc.createElement win.global.location win.withGlobal
+	"dojo/window", // winUtils.get()
 	"../_Widget",
 	"../_CssStateMixin",
-	"./selection",
+	"../selection",
 	"./range",
 	"./html",
 	"../focus",
-	".."	// dijit._scopeName
+	"../main"    // dijit._scopeName
 ], function(array, config, declare, Deferred, dom, domAttr, domClass, domConstruct, domGeometry, domStyle,
-	event, kernel, keys, lang, on, query, ready, has, topic, unload, _Url, win,
-	_Widget, _CssStateMixin, selectionapi, rangeapi, htmlapi, focus, dijit){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _CssStateMixin = dijit._CssStateMixin;
-=====*/
-
-// module:
-//		dijit/_editor/RichText
-// summary:
-//		dijit._editor.RichText is the core of dijit.Editor, which provides basic
-//		WYSIWYG editing features.
-
-// if you want to allow for rich text saving with back/forward actions, you must add a text area to your page with
-// the id==dijit._scopeName + "._editor.RichText.value" (typically "dijit._editor.RichText.value). For example,
-// something like this will work:
-//
-//	<textarea id="dijit._editor.RichText.value" style="display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;"></textarea>
-//
-
-var RichText = declare("dijit._editor.RichText", [_Widget, _CssStateMixin], {
-	// summary:
-	//		dijit._editor.RichText is the core of dijit.Editor, which provides basic
-	//		WYSIWYG editing features.
-	//
-	// description:
-	//		dijit._editor.RichText is the core of dijit.Editor, which provides basic
-	//		WYSIWYG editing features. It also encapsulates the differences
-	//		of different js engines for various browsers.  Do not use this widget
-	//		with an HTML <TEXTAREA> tag, since the browser unescapes XML escape characters,
-	//		like <.  This can have unexpected behavior and lead to security issues
-	//		such as scripting attacks.
-	//
-	// tags:
-	//		private
-
-	constructor: function(params){
-		// contentPreFilters: Function(String)[]
-		//		Pre content filter function register array.
-		//		these filters will be executed before the actual
-		//		editing area gets the html content.
-		this.contentPreFilters = [];
-
-		// contentPostFilters: Function(String)[]
-		//		post content filter function register array.
-		//		These will be used on the resulting html
-		//		from contentDomPostFilters. The resulting
-		//		content is the final html (returned by getValue()).
-		this.contentPostFilters = [];
-
-		// contentDomPreFilters: Function(DomNode)[]
-		//		Pre content dom filter function register array.
-		//		These filters are applied after the result from
-		//		contentPreFilters are set to the editing area.
-		this.contentDomPreFilters = [];
-
-		// contentDomPostFilters: Function(DomNode)[]
-		//		Post content dom filter function register array.
-		//		These filters are executed on the editing area dom.
-		//		The result from these will be passed to contentPostFilters.
-		this.contentDomPostFilters = [];
-
-		// editingAreaStyleSheets: dojo._URL[]
-		//		array to store all the stylesheets applied to the editing area
-		this.editingAreaStyleSheets = [];
-
-		// Make a copy of this.events before we start writing into it, otherwise we
-		// will modify the prototype which leads to bad things on pages w/multiple editors
-		this.events = [].concat(this.events);
-
-		this._keyHandlers = {};
-
-		if(params && lang.isString(params.value)){
-			this.value = params.value;
-		}
-
-		this.onLoadDeferred = new Deferred();
-	},
-
-	baseClass: "dijitEditor",
-
-	// inheritWidth: Boolean
-	//		whether to inherit the parent's width or simply use 100%
-	inheritWidth: false,
-
-	// focusOnLoad: [deprecated] Boolean
-	//		Focus into this widget when the page is loaded
-	focusOnLoad: false,
-
-	// name: String?
-	//		Specifies the name of a (hidden) <textarea> node on the page that's used to save
-	//		the editor content on page leave.   Used to restore editor contents after navigating
-	//		to a new page and then hitting the back button.
-	name: "",
-
-	// styleSheets: [const] String
-	//		semicolon (";") separated list of css files for the editing area
-	styleSheets: "",
-
-	// height: String
-	//		Set height to fix the editor at a specific height, with scrolling.
-	//		By default, this is 300px.  If you want to have the editor always
-	//		resizes to accommodate the content, use AlwaysShowToolbar plugin
-	//		and set height="".  If this editor is used within a layout widget,
-	//		set height="100%".
-	height: "300px",
-
-	// minHeight: String
-	//		The minimum height that the editor should have.
-	minHeight: "1em",
-
-	// isClosed: [private] Boolean
-	isClosed: true,
-
-	// isLoaded: [private] Boolean
-	isLoaded: false,
-
-	// _SEPARATOR: [private] String
-	//		Used to concat contents from multiple editors into a single string,
-	//		so they can be saved into a single <textarea> node.  See "name" attribute.
-	_SEPARATOR: "@@**%%__RICHTEXTBOUNDRY__%%**@@",
-
-	// _NAME_CONTENT_SEP: [private] String
-	//		USed to separate name from content.  Just a colon isn't safe.
-	_NAME_CONTENT_SEP: "@@**%%:%%**@@",
-
-	// onLoadDeferred: [readonly] dojo.Deferred
-	//		Deferred which is fired when the editor finishes loading.
-	//		Call myEditor.onLoadDeferred.then(callback) it to be informed
-	//		when the rich-text area initialization is finalized.
-	onLoadDeferred: null,
-
-	// isTabIndent: Boolean
-	//		Make tab key and shift-tab indent and outdent rather than navigating.
-	//		Caution: sing this makes web pages inaccessible to users unable to use a mouse.
-	isTabIndent: false,
-
-	// disableSpellCheck: [const] Boolean
-	//		When true, disables the browser's native spell checking, if supported.
-	//		Works only in Firefox.
-	disableSpellCheck: false,
-
-	postCreate: function(){
-		if("textarea" === this.domNode.tagName.toLowerCase()){
-			console.warn("RichText should not be used with the TEXTAREA tag.  See dijit._editor.RichText docs.");
-		}
+			kernel, keys, lang, on, query, domReady, has, topic, unload, _Url, winUtils,
+			_Widget, _CssStateMixin, selectionapi, rangeapi, htmlapi, focus, dijit){
 
-		// Push in the builtin filters now, making them the first executed, but not over-riding anything
-		// users passed in.  See: #6062
-		this.contentPreFilters = [lang.hitch(this, "_preFixUrlAttributes")].concat(this.contentPreFilters);
-		if(has("mozilla")){
-			this.contentPreFilters = [this._normalizeFontStyle].concat(this.contentPreFilters);
-			this.contentPostFilters = [this._removeMozBogus].concat(this.contentPostFilters);
-		}
-		if(has("webkit")){
-			// Try to clean up WebKit bogus artifacts.  The inserted classes
-			// made by WebKit sometimes messes things up.
-			this.contentPreFilters = [this._removeWebkitBogus].concat(this.contentPreFilters);
-			this.contentPostFilters = [this._removeWebkitBogus].concat(this.contentPostFilters);
-		}
-		if(has("ie")){
-			// IE generates <strong> and <em> but we want to normalize to <b> and <i>
-			this.contentPostFilters = [this._normalizeFontStyle].concat(this.contentPostFilters);
-			this.contentDomPostFilters = [lang.hitch(this, this._stripBreakerNodes)].concat(this.contentDomPostFilters);
-		}
-		this.inherited(arguments);
+	// module:
+	//		dijit/_editor/RichText
 
-		topic.publish(dijit._scopeName + "._editor.RichText::init", this);
-		this.open();
-		this.setupDefaultShortcuts();
-	},
+	// If you want to allow for rich text saving with back/forward actions, you must add a text area to your page with
+	// the id==dijit._scopeName + "._editor.RichText.value" (typically "dijit/_editor/RichText.value). For example,
+	// something like this will work:
+	//
+	//	<textarea id="dijit._editor.RichText.value" style="display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;"></textarea>
 
-	setupDefaultShortcuts: function(){
+	var RichText = declare("dijit._editor.RichText", [_Widget, _CssStateMixin], {
 		// summary:
-		//		Add some default key handlers
+		//		dijit/_editor/RichText is the core of dijit.Editor, which provides basic
+		//		WYSIWYG editing features.
+		//
 		// description:
-		//		Overwrite this to setup your own handlers. The default
-		//		implementation does not use Editor commands, but directly
-		//		executes the builtin commands within the underlying browser
-		//		support.
-		// tags:
-		//		protected
-		var exec = lang.hitch(this, function(cmd, arg){
-			return function(){
-				return !this.execCommand(cmd,arg);
-			};
-		});
-
-		var ctrlKeyHandlers = {
-			b: exec("bold"),
-			i: exec("italic"),
-			u: exec("underline"),
-			a: exec("selectall"),
-			s: function(){ this.save(true); },
-			m: function(){ this.isTabIndent = !this.isTabIndent; },
-
-			"1": exec("formatblock", "h1"),
-			"2": exec("formatblock", "h2"),
-			"3": exec("formatblock", "h3"),
-			"4": exec("formatblock", "h4"),
-
-			"\\": exec("insertunorderedlist")
-		};
-
-		if(!has("ie")){
-			ctrlKeyHandlers.Z = exec("redo"); //FIXME: undo?
-		}
-
-		var key;
-		for(key in ctrlKeyHandlers){
-			this.addKeyHandler(key, true, false, ctrlKeyHandlers[key]);
-		}
-	},
-
-	// events: [private] String[]
-	//		 events which should be connected to the underlying editing area
-	events: ["onKeyPress", "onKeyDown", "onKeyUp"], // onClick handled specially
-
-	// captureEvents: [deprecated] String[]
-	//		 Events which should be connected to the underlying editing
-	//		 area, events in this array will be addListener with
-	//		 capture=true.
-	// TODO: looking at the code I don't see any distinction between events and captureEvents,
-	// so get rid of this for 2.0 if not sooner
-	captureEvents: [],
-
-	_editorCommandsLocalized: false,
-	_localizeEditorCommands: function(){
-		// summary:
-		//		When IE is running in a non-English locale, the API actually changes,
-		//		so that we have to say (for example) danraku instead of p (for paragraph).
-		//		Handle that here.
+		//		dijit/_editor/RichText is the core of dijit.Editor, which provides basic
+		//		WYSIWYG editing features. It also encapsulates the differences
+		//		of different js engines for various browsers.  Do not use this widget
+		//		with an HTML <TEXTAREA> tag, since the browser unescapes XML escape characters,
+		//		like <.  This can have unexpected behavior and lead to security issues
+		//		such as scripting attacks.
+		//
 		// tags:
 		//		private
-		if(RichText._editorCommandsLocalized){
-			// Use the already generate cache of mappings.
-			this._local2NativeFormatNames = RichText._local2NativeFormatNames;
-			this._native2LocalFormatNames = RichText._native2LocalFormatNames;
-			return;
-		}
-		RichText._editorCommandsLocalized = true;
-		RichText._local2NativeFormatNames = {};
-		RichText._native2LocalFormatNames = {};
-		this._local2NativeFormatNames = RichText._local2NativeFormatNames;
-		this._native2LocalFormatNames = RichText._native2LocalFormatNames;
-		//in IE, names for blockformat is locale dependent, so we cache the values here
-
-		//put p after div, so if IE returns Normal, we show it as paragraph
-		//We can distinguish p and div if IE returns Normal, however, in order to detect that,
-		//we have to call this.document.selection.createRange().parentElement() or such, which
-		//could slow things down. Leave it as it is for now
-		var formats = ['div', 'p', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', 'address'];
-		var localhtml = "", format, i=0;
-		while((format=formats[i++])){
-			//append a <br> after each element to separate the elements more reliably
-			if(format.charAt(1) !== 'l'){
-				localhtml += "<"+format+"><span>content</span></"+format+"><br/>";
-			}else{
-				localhtml += "<"+format+"><li>content</li></"+format+"><br/>";
+
+		constructor: function(params /*===== , srcNodeRef =====*/){
+			// summary:
+			//		Create the widget.
+			// params: Object|null
+			//		Initial settings for any of the widget attributes, except readonly attributes.
+			// srcNodeRef: DOMNode
+			//		The widget replaces the specified DOMNode.
+
+			// contentPreFilters: Function(String)[]
+			//		Pre content filter function register array.
+			//		these filters will be executed before the actual
+			//		editing area gets the html content.
+			this.contentPreFilters = [];
+
+			// contentPostFilters: Function(String)[]
+			//		post content filter function register array.
+			//		These will be used on the resulting html
+			//		from contentDomPostFilters. The resulting
+			//		content is the final html (returned by getValue()).
+			this.contentPostFilters = [];
+
+			// contentDomPreFilters: Function(DomNode)[]
+			//		Pre content dom filter function register array.
+			//		These filters are applied after the result from
+			//		contentPreFilters are set to the editing area.
+			this.contentDomPreFilters = [];
+
+			// contentDomPostFilters: Function(DomNode)[]
+			//		Post content dom filter function register array.
+			//		These filters are executed on the editing area dom.
+			//		The result from these will be passed to contentPostFilters.
+			this.contentDomPostFilters = [];
+
+			// editingAreaStyleSheets: dojo._URL[]
+			//		array to store all the stylesheets applied to the editing area
+			this.editingAreaStyleSheets = [];
+
+			// Make a copy of this.events before we start writing into it, otherwise we
+			// will modify the prototype which leads to bad things on pages w/multiple editors
+			this.events = [].concat(this.events);
+
+			this._keyHandlers = {};
+
+			if(params && lang.isString(params.value)){
+				this.value = params.value;
 			}
-		}
-		// queryCommandValue returns empty if we hide editNode, so move it out of screen temporary
-		// Also, IE9 does weird stuff unless we do it inside the editor iframe.
-		var style = { position: "absolute", top: "0px", zIndex: 10, opacity: 0.01 };
-		var div = domConstruct.create('div', {style: style, innerHTML: localhtml});
-		win.body().appendChild(div);
-
-		// IE9 has a timing issue with doing this right after setting
-		// the inner HTML, so put a delay in.
-		var inject = lang.hitch(this, function(){
-			var node = div.firstChild;
-			while(node){
-				try{
-					selectionapi.selectElement(node.firstChild);
-					var nativename = node.tagName.toLowerCase();
-					this._local2NativeFormatNames[nativename] = document.queryCommandValue("formatblock");
-					this._native2LocalFormatNames[this._local2NativeFormatNames[nativename]] = nativename;
-					node = node.nextSibling.nextSibling;
-					//console.log("Mapped: ", nativename, " to: ", this._local2NativeFormatNames[nativename]);
-				}catch(e){ /*Sqelch the occasional IE9 error */ }
-			}
-			div.parentNode.removeChild(div);
-			div.innerHTML = "";
-		});
-		setTimeout(inject, 0);
-	},
-
-	open: function(/*DomNode?*/ element){
-		// summary:
-		//		Transforms the node referenced in this.domNode into a rich text editing
-		//		node.
-		// description:
-		//		Sets up the editing area asynchronously. This will result in
-		//		the creation and replacement with an iframe.
-		// tags:
-		//		private
 
-		if(!this.onLoadDeferred || this.onLoadDeferred.fired >= 0){
 			this.onLoadDeferred = new Deferred();
-		}
+		},
+
+		baseClass: "dijitEditor",
+
+		// inheritWidth: Boolean
+		//		whether to inherit the parent's width or simply use 100%
+		inheritWidth: false,
+
+		// focusOnLoad: [deprecated] Boolean
+		//		Focus into this widget when the page is loaded
+		focusOnLoad: false,
+
+		// name: String?
+		//		Specifies the name of a (hidden) `<textarea>` node on the page that's used to save
+		//		the editor content on page leave.   Used to restore editor contents after navigating
+		//		to a new page and then hitting the back button.
+		name: "",
+
+		// styleSheets: [const] String
+		//		semicolon (";") separated list of css files for the editing area
+		styleSheets: "",
+
+		// height: String
+		//		Set height to fix the editor at a specific height, with scrolling.
+		//		By default, this is 300px.  If you want to have the editor always
+		//		resizes to accommodate the content, use AlwaysShowToolbar plugin
+		//		and set height="".  If this editor is used within a layout widget,
+		//		set height="100%".
+		height: "300px",
+
+		// minHeight: String
+		//		The minimum height that the editor should have.
+		minHeight: "1em",
+
+		// isClosed: [private] Boolean
+		isClosed: true,
+
+		// isLoaded: [private] Boolean
+		isLoaded: false,
+
+		// _SEPARATOR: [private] String
+		//		Used to concat contents from multiple editors into a single string,
+		//		so they can be saved into a single `<textarea>` node.  See "name" attribute.
+		_SEPARATOR: "@@**%%__RICHTEXTBOUNDRY__%%**@@",
+
+		// _NAME_CONTENT_SEP: [private] String
+		//		USed to separate name from content.  Just a colon isn't safe.
+		_NAME_CONTENT_SEP: "@@**%%:%%**@@",
+
+		// onLoadDeferred: [readonly] dojo/promise/Promise
+		//		Deferred which is fired when the editor finishes loading.
+		//		Call myEditor.onLoadDeferred.then(callback) it to be informed
+		//		when the rich-text area initialization is finalized.
+		onLoadDeferred: null,
+
+		// isTabIndent: Boolean
+		//		Make tab key and shift-tab indent and outdent rather than navigating.
+		//		Caution: sing this makes web pages inaccessible to users unable to use a mouse.
+		isTabIndent: false,
+
+		// disableSpellCheck: [const] Boolean
+		//		When true, disables the browser's native spell checking, if supported.
+		//		Works only in Firefox.
+		disableSpellCheck: false,
+
+		postCreate: function(){
+			if("textarea" === this.domNode.tagName.toLowerCase()){
+				console.warn("RichText should not be used with the TEXTAREA tag.  See dijit._editor.RichText docs.");
+			}
+
+			// Push in the builtin filters now, making them the first executed, but not over-riding anything
+			// users passed in.  See: #6062
+			this.contentPreFilters = [lang.hitch(this, "_preFixUrlAttributes")].concat(this.contentPreFilters);
+			if(has("mozilla")){
+				this.contentPreFilters = [this._normalizeFontStyle].concat(this.contentPreFilters);
+				this.contentPostFilters = [this._removeMozBogus].concat(this.contentPostFilters);
+			}
+			if(has("webkit")){
+				// Try to clean up WebKit bogus artifacts.  The inserted classes
+				// made by WebKit sometimes messes things up.
+				this.contentPreFilters = [this._removeWebkitBogus].concat(this.contentPreFilters);
+				this.contentPostFilters = [this._removeWebkitBogus].concat(this.contentPostFilters);
+			}
+			if(has("ie")){
+				// IE generates <strong> and <em> but we want to normalize to <b> and <i>
+				this.contentPostFilters = [this._normalizeFontStyle].concat(this.contentPostFilters);
+				this.contentDomPostFilters = [lang.hitch(this, this._stripBreakerNodes)].concat(this.contentDomPostFilters);
+			}
+			this.inherited(arguments);
 
-		if(!this.isClosed){ this.close(); }
-		topic.publish(dijit._scopeName + "._editor.RichText::open", this);
+			topic.publish(dijit._scopeName + "._editor.RichText::init", this);
+		},
 
-		if(arguments.length === 1 && element.nodeName){ // else unchanged
-			this.domNode = element;
-		}
+		startup: function(){
+			this.inherited(arguments);
 
-		var dn = this.domNode;
-
-		// "html" will hold the innerHTML of the srcNodeRef and will be used to
-		// initialize the editor.
-		var html;
-
-		if(lang.isString(this.value)){
-			// Allow setting the editor content programmatically instead of
-			// relying on the initial content being contained within the target
-			// domNode.
-			html = this.value;
-			delete this.value;
-			dn.innerHTML = "";
-		}else if(dn.nodeName && dn.nodeName.toLowerCase() == "textarea"){
-			// if we were created from a textarea, then we need to create a
-			// new editing harness node.
-			var ta = (this.textarea = dn);
-			this.name = ta.name;
-			html = ta.value;
-			dn = this.domNode = win.doc.createElement("div");
-			dn.setAttribute('widgetId', this.id);
-			ta.removeAttribute('widgetId');
-			dn.cssText = ta.cssText;
-			dn.className += " " + ta.className;
-			domConstruct.place(dn, ta, "before");
-			var tmpFunc = lang.hitch(this, function(){
-				//some browsers refuse to submit display=none textarea, so
-				//move the textarea off screen instead
-				domStyle.set(ta, {
-					display: "block",
-					position: "absolute",
-					top: "-1000px"
-				});
+			// Don't call open() until startup() because we need to be attached to the DOM, and also if we are the
+			// child of a StackContainer, let StackContainer._setupChild() do DOM manipulations before iframe is
+			// created, to avoid duplicate onload call.
+			this.open();
+			this.setupDefaultShortcuts();
+		},
+
+		setupDefaultShortcuts: function(){
+			// summary:
+			//		Add some default key handlers
+			// description:
+			//		Overwrite this to setup your own handlers. The default
+			//		implementation does not use Editor commands, but directly
+			//		executes the builtin commands within the underlying browser
+			//		support.
+			// tags:
+			//		protected
+			var exec = lang.hitch(this, function(cmd, arg){
+				return function(){
+					return !this.execCommand(cmd, arg);
+				};
+			});
+
+			var ctrlKeyHandlers = {
+				b: exec("bold"),
+				i: exec("italic"),
+				u: exec("underline"),
+				a: exec("selectall"),
+				s: function(){
+					this.save(true);
+				},
+				m: function(){
+					this.isTabIndent = !this.isTabIndent;
+				},
+
+				"1": exec("formatblock", "h1"),
+				"2": exec("formatblock", "h2"),
+				"3": exec("formatblock", "h3"),
+				"4": exec("formatblock", "h4"),
+
+				"\\": exec("insertunorderedlist")
+			};
 
-				if(has("ie")){ //nasty IE bug: abnormal formatting if overflow is not hidden
-					var s = ta.style;
-					this.__overflow = s.overflow;
-					s.overflow = "hidden";
+			if(!has("ie")){
+				ctrlKeyHandlers.Z = exec("redo"); //FIXME: undo?
+			}
+
+			var key;
+			for(key in ctrlKeyHandlers){
+				this.addKeyHandler(key, true, false, ctrlKeyHandlers[key]);
+			}
+		},
+
+		// events: [private] String[]
+		//		 events which should be connected to the underlying editing area
+		events: ["onKeyDown", "onKeyUp"], // onClick handled specially
+
+		// captureEvents: [deprecated] String[]
+		//		 Events which should be connected to the underlying editing
+		//		 area, events in this array will be addListener with
+		//		 capture=true.
+		// TODO: looking at the code I don't see any distinction between events and captureEvents,
+		// so get rid of this for 2.0 if not sooner
+		captureEvents: [],
+
+		_editorCommandsLocalized: false,
+		_localizeEditorCommands: function(){
+			// summary:
+			//		When IE is running in a non-English locale, the API actually changes,
+			//		so that we have to say (for example) danraku instead of p (for paragraph).
+			//		Handle that here.
+			// tags:
+			//		private
+			if(RichText._editorCommandsLocalized){
+				// Use the already generate cache of mappings.
+				this._local2NativeFormatNames = RichText._local2NativeFormatNames;
+				this._native2LocalFormatNames = RichText._native2LocalFormatNames;
+				return;
+			}
+			RichText._editorCommandsLocalized = true;
+			RichText._local2NativeFormatNames = {};
+			RichText._native2LocalFormatNames = {};
+			this._local2NativeFormatNames = RichText._local2NativeFormatNames;
+			this._native2LocalFormatNames = RichText._native2LocalFormatNames;
+			//in IE, names for blockformat is locale dependent, so we cache the values here
+
+			//put p after div, so if IE returns Normal, we show it as paragraph
+			//We can distinguish p and div if IE returns Normal, however, in order to detect that,
+			//we have to call this.document.selection.createRange().parentElement() or such, which
+			//could slow things down. Leave it as it is for now
+			var formats = ['div', 'p', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', 'address'];
+			var localhtml = "", format, i = 0;
+			while((format = formats[i++])){
+				//append a <br> after each element to separate the elements more reliably
+				if(format.charAt(1) !== 'l'){
+					localhtml += "<" + format + "><span>content</span></" + format + "><br/>";
+				}else{
+					localhtml += "<" + format + "><li>content</li></" + format + "><br/>";
+				}
+			}
+			// queryCommandValue returns empty if we hide editNode, so move it out of screen temporary
+			// Also, IE9 does weird stuff unless we do it inside the editor iframe.
+			var style = { position: "absolute", top: "0px", zIndex: 10, opacity: 0.01 };
+			var div = domConstruct.create('div', {style: style, innerHTML: localhtml});
+			this.ownerDocumentBody.appendChild(div);
+
+			// IE9 has a timing issue with doing this right after setting
+			// the inner HTML, so put a delay in.
+			var inject = lang.hitch(this, function(){
+				var node = div.firstChild;
+				while(node){
+					try{
+						this.selection.selectElement(node.firstChild);
+						var nativename = node.tagName.toLowerCase();
+						this._local2NativeFormatNames[nativename] = document.queryCommandValue("formatblock");
+						this._native2LocalFormatNames[this._local2NativeFormatNames[nativename]] = nativename;
+						node = node.nextSibling.nextSibling;
+						//console.log("Mapped: ", nativename, " to: ", this._local2NativeFormatNames[nativename]);
+					}catch(e){ /*Sqelch the occasional IE9 error */
+					}
 				}
+				domConstruct.destroy(div);
 			});
-			if(has("ie")){
-				setTimeout(tmpFunc, 10);
-			}else{
-				tmpFunc();
+			this.defer(inject);
+		},
+
+		open: function(/*DomNode?*/ element){
+			// summary:
+			//		Transforms the node referenced in this.domNode into a rich text editing
+			//		node.
+			// description:
+			//		Sets up the editing area asynchronously. This will result in
+			//		the creation and replacement with an iframe.
+			// tags:
+			//		private
+
+			if(!this.onLoadDeferred || this.onLoadDeferred.fired >= 0){
+				this.onLoadDeferred = new Deferred();
 			}
 
-			if(ta.form){
-				var resetValue = ta.value;
-				this.reset = function(){
-					var current = this.getValue();
-					if(current !== resetValue){
-						this.replaceValue(resetValue);
+			if(!this.isClosed){
+				this.close();
+			}
+			topic.publish(dijit._scopeName + "._editor.RichText::open", this);
+
+			if(arguments.length === 1 && element.nodeName){ // else unchanged
+				this.domNode = element;
+			}
+
+			var dn = this.domNode;
+
+			// "html" will hold the innerHTML of the srcNodeRef and will be used to
+			// initialize the editor.
+			var html;
+
+			if(lang.isString(this.value)){
+				// Allow setting the editor content programmatically instead of
+				// relying on the initial content being contained within the target
+				// domNode.
+				html = this.value;
+				delete this.value;
+				dn.innerHTML = "";
+			}else if(dn.nodeName && dn.nodeName.toLowerCase() == "textarea"){
+				// if we were created from a textarea, then we need to create a
+				// new editing harness node.
+				var ta = (this.textarea = dn);
+				this.name = ta.name;
+				html = ta.value;
+				dn = this.domNode = this.ownerDocument.createElement("div");
+				dn.setAttribute('widgetId', this.id);
+				ta.removeAttribute('widgetId');
+				dn.cssText = ta.cssText;
+				dn.className += " " + ta.className;
+				domConstruct.place(dn, ta, "before");
+				var tmpFunc = lang.hitch(this, function(){
+					//some browsers refuse to submit display=none textarea, so
+					//move the textarea off screen instead
+					domStyle.set(ta, {
+						display: "block",
+						position: "absolute",
+						top: "-1000px"
+					});
+
+					if(has("ie")){ //nasty IE bug: abnormal formatting if overflow is not hidden
+						var s = ta.style;
+						this.__overflow = s.overflow;
+						s.overflow = "hidden";
 					}
-				};
-				on(ta.form, "submit", lang.hitch(this, function(){
-					// Copy value to the <textarea> so it gets submitted along with form.
-					// FIXME: should we be calling close() here instead?
-					domAttr.set(ta, 'disabled', this.disabled); // don't submit the value if disabled
-					ta.value = this.getValue();
-				}));
+				});
+				if(has("ie")){
+					this.defer(tmpFunc, 10);
+				}else{
+					tmpFunc();
+				}
+
+				if(ta.form){
+					var resetValue = ta.value;
+					this.reset = function(){
+						var current = this.getValue();
+						if(current !== resetValue){
+							this.replaceValue(resetValue);
+						}
+					};
+					on(ta.form, "submit", lang.hitch(this, function(){
+						// Copy value to the <textarea> so it gets submitted along with form.
+						// FIXME: should we be calling close() here instead?
+						domAttr.set(ta, 'disabled', this.disabled); // don't submit the value if disabled
+						ta.value = this.getValue();
+					}));
+				}
+			}else{
+				html = htmlapi.getChildrenHtml(dn);
+				dn.innerHTML = "";
 			}
-		}else{
-			html = htmlapi.getChildrenHtml(dn);
-			dn.innerHTML = "";
-		}
 
-		this.value = html;
+			this.value = html;
 
-		// If we're a list item we have to put in a blank line to force the
-		// bullet to nicely align at the top of text
-		if(dn.nodeName && dn.nodeName === "LI"){
-			dn.innerHTML = " <br>";
-		}
+			// If we're a list item we have to put in a blank line to force the
+			// bullet to nicely align at the top of text
+			if(dn.nodeName && dn.nodeName === "LI"){
+				dn.innerHTML = " <br>";
+			}
 
-		// Construct the editor div structure.
-		this.header = dn.ownerDocument.createElement("div");
-		dn.appendChild(this.header);
-		this.editingArea = dn.ownerDocument.createElement("div");
-		dn.appendChild(this.editingArea);
-		this.footer = dn.ownerDocument.createElement("div");
-		dn.appendChild(this.footer);
+			// Construct the editor div structure.
+			this.header = dn.ownerDocument.createElement("div");
+			dn.appendChild(this.header);
+			this.editingArea = dn.ownerDocument.createElement("div");
+			dn.appendChild(this.editingArea);
+			this.footer = dn.ownerDocument.createElement("div");
+			dn.appendChild(this.footer);
 
-		if(!this.name){
-			this.name = this.id + "_AUTOGEN";
-		}
+			if(!this.name){
+				this.name = this.id + "_AUTOGEN";
+			}
 
-		// User has pressed back/forward button so we lost the text in the editor, but it's saved
-		// in a hidden <textarea> (which contains the data for all the editors on this page),
-		// so get editor value from there
-		if(this.name !== "" && (!config["useXDomain"] || config["allowXdRichTextSave"])){
-			var saveTextarea = dom.byId(dijit._scopeName + "._editor.RichText.value");
-			if(saveTextarea && saveTextarea.value !== ""){
-				var datas = saveTextarea.value.split(this._SEPARATOR), i=0, dat;
-				while((dat=datas[i++])){
-					var data = dat.split(this._NAME_CONTENT_SEP);
-					if(data[0] === this.name){
-						html = data[1];
-						datas = datas.splice(i, 1);
-						saveTextarea.value = datas.join(this._SEPARATOR);
-						break;
+			// User has pressed back/forward button so we lost the text in the editor, but it's saved
+			// in a hidden <textarea> (which contains the data for all the editors on this page),
+			// so get editor value from there
+			if(this.name !== "" && (!config["useXDomain"] || config["allowXdRichTextSave"])){
+				var saveTextarea = dom.byId(dijit._scopeName + "._editor.RichText.value");
+				if(saveTextarea && saveTextarea.value !== ""){
+					var datas = saveTextarea.value.split(this._SEPARATOR), i = 0, dat;
+					while((dat = datas[i++])){
+						var data = dat.split(this._NAME_CONTENT_SEP);
+						if(data[0] === this.name){
+							html = data[1];
+							datas = datas.splice(i, 1);
+							saveTextarea.value = datas.join(this._SEPARATOR);
+							break;
+						}
 					}
 				}
-			}
 
-			if(!RichText._globalSaveHandler){
-				RichText._globalSaveHandler = {};
-				unload.addOnUnload(function(){
-					var id;
-					for(id in RichText._globalSaveHandler){
-						var f = RichText._globalSaveHandler[id];
-						if(lang.isFunction(f)){
-							f();
+				if(!RichText._globalSaveHandler){
+					RichText._globalSaveHandler = {};
+					unload.addOnUnload(function(){
+						var id;
+						for(id in RichText._globalSaveHandler){
+							var f = RichText._globalSaveHandler[id];
+							if(lang.isFunction(f)){
+								f();
+							}
 						}
-					}
-				});
+					});
+				}
+				RichText._globalSaveHandler[this.id] = lang.hitch(this, "_saveContent");
 			}
-			RichText._globalSaveHandler[this.id] = lang.hitch(this, "_saveContent");
-		}
 
-		this.isClosed = false;
-
-		var ifr = (this.editorObject = this.iframe = win.doc.createElement('iframe'));
-		ifr.id = this.id+"_iframe";
-		this._iframeSrc = this._getIframeDocTxt();
-		ifr.style.border = "none";
-		ifr.style.width = "100%";
-		if(this._layoutMode){
-			// iframe should be 100% height, thus getting it's height from surrounding
-			// <div> (which has the correct height set by Editor)
-			ifr.style.height = "100%";
-		}else{
-			if(has("ie") >= 7){
-				if(this.height){
-					ifr.style.height = this.height;
-				}
-				if(this.minHeight){
-					ifr.style.minHeight = this.minHeight;
-				}
+			this.isClosed = false;
+
+			var ifr = (this.editorObject = this.iframe = this.ownerDocument.createElement('iframe'));
+			ifr.id = this.id + "_iframe";
+			ifr.style.border = "none";
+			ifr.style.width = "100%";
+			if(this._layoutMode){
+				// iframe should be 100% height, thus getting it's height from surrounding
+				// <div> (which has the correct height set by Editor)
+				ifr.style.height = "100%";
 			}else{
-				ifr.style.height = this.height ? this.height : this.minHeight;
+				if(has("ie") >= 7){
+					if(this.height){
+						ifr.style.height = this.height;
+					}
+					if(this.minHeight){
+						ifr.style.minHeight = this.minHeight;
+					}
+				}else{
+					ifr.style.height = this.height ? this.height : this.minHeight;
+				}
 			}
-		}
-		ifr.frameBorder = 0;
-		ifr._loadFunc = lang.hitch( this, function(w){
-			this.window = w;
-			this.document = this.window.document;
+			ifr.frameBorder = 0;
+			ifr._loadFunc = lang.hitch(this, function(w){
+				this.window = w;
+				this.document = this.window.document;
 
-			if(has("ie")){
-				this._localizeEditorCommands();
-			}
+				// instantiate class to access selected text in editor's iframe
+				this.selection = new selectionapi.SelectionManager(w);
 
-			// Do final setup and set initial contents of editor
-			this.onLoad(html);
-		});
+				if(has("ie")){
+					this._localizeEditorCommands();
+				}
 
-		// Set the iframe's initial (blank) content.
-		var iframeSrcRef = 'parent.' + dijit._scopeName + '.byId("'+this.id+'")._iframeSrc';
-		var s = 'javascript:(function(){try{return ' + iframeSrcRef + '}catch(e){document.open();document.domain="' +
-				document.domain + '";document.write(' + iframeSrcRef + ');document.close();}})()';
-		ifr.setAttribute('src', s);
-		this.editingArea.appendChild(ifr);
+				// Do final setup and set initial contents of editor
+				this.onLoad(html);
+			});
 
-		if(has("safari") <= 4){
-			var src = ifr.getAttribute("src");
-			if(!src || src.indexOf("javascript") === -1){
-				// Safari 4 and earlier sometimes act oddly
-				// So we have to set it again.
-				setTimeout(function(){ifr.setAttribute('src', s);},0);
-			}
-		}
+			// Attach iframe to document, and set the initial (blank) content.
+			var src = this._getIframeDocTxt(),
+				s = "javascript: '" + src.replace(/\\/g, "\\\\").replace(/'/g, "\\'") + "'";
 
-		// TODO: this is a guess at the default line-height, kinda works
-		if(dn.nodeName === "LI"){
-			dn.lastChild.style.marginTop = "-1.2em";
-		}
+			if(has("ie") >= 9){
+				// On IE9+, attach to document before setting the content, to avoid problem w/iframe running in
+				// wrong security context, see #16633.
+				this.editingArea.appendChild(ifr);
+				ifr.src = s;
+			}else{
+				// For other browsers, set src first, especially for IE6/7 where attaching first gives a warning on
+				// https:// about "this page contains secure and insecure items, do you want to view both?"
+				ifr.setAttribute('src', s);
+				this.editingArea.appendChild(ifr);
+			}
 
-		domClass.add(this.domNode, this.baseClass);
-	},
+			// TODO: this is a guess at the default line-height, kinda works
+			if(dn.nodeName === "LI"){
+				dn.lastChild.style.marginTop = "-1.2em";
+			}
 
-	//static cache variables shared among all instance of this class
-	_local2NativeFormatNames: {},
-	_native2LocalFormatNames: {},
+			domClass.add(this.domNode, this.baseClass);
+		},
+
+		//static cache variables shared among all instance of this class
+		_local2NativeFormatNames: {},
+		_native2LocalFormatNames: {},
+
+		_getIframeDocTxt: function(){
+			// summary:
+			//		Generates the boilerplate text of the document inside the iframe (ie, `<html><head>...</head><body/></html>`).
+			//		Editor content (if not blank) should be added afterwards.
+			// tags:
+			//		private
+			var _cs = domStyle.getComputedStyle(this.domNode);
+
+			// The contents inside of <body>.  The real contents are set later via a call to setValue().
+			var html = "";
+			var setBodyId = true;
+			if(has("ie") || has("webkit") || (!this.height && !has("mozilla"))){
+				// In auto-expand mode, need a wrapper div for AlwaysShowToolbar plugin to correctly
+				// expand/contract the editor as the content changes.
+				html = "<div id='dijitEditorBody'></div>";
+				setBodyId = false;
+			}else if(has("mozilla")){
+				// workaround bug where can't select then delete text (until user types something
+				// into the editor)... and/or issue where typing doesn't erase selected text
+				this._cursorToStart = true;
+				html = " ";	//  
+			}
 
-	_getIframeDocTxt: function(){
-		// summary:
-		//		Generates the boilerplate text of the document inside the iframe (ie, <html><head>...</head><body/></html>).
-		//		Editor content (if not blank) should be added afterwards.
-		// tags:
-		//		private
-		var _cs = domStyle.getComputedStyle(this.domNode);
-
-		// The contents inside of <body>.  The real contents are set later via a call to setValue().
-		var html = "";
-		var setBodyId = true;
-		if(has("ie") || has("webkit") || (!this.height && !has("mozilla"))){
-			// In auto-expand mode, need a wrapper div for AlwaysShowToolbar plugin to correctly
-			// expand/contract the editor as the content changes.
-			html = "<div id='dijitEditorBody'></div>";
-			setBodyId = false;
-		}else if(has("mozilla")){
-			// workaround bug where can't select then delete text (until user types something
-			// into the editor)... and/or issue where typing doesn't erase selected text
-			this._cursorToStart = true;
-			html = " ";	//  
-		}
+			var font = [ _cs.fontWeight, _cs.fontSize, _cs.fontFamily ].join(" ");
 
-		var font = [ _cs.fontWeight, _cs.fontSize, _cs.fontFamily ].join(" ");
-
-		// line height is tricky - applying a units value will mess things up.
-		// if we can't get a non-units value, bail out.
-		var lineHeight = _cs.lineHeight;
-		if(lineHeight.indexOf("px") >= 0){
-			lineHeight = parseFloat(lineHeight)/parseFloat(_cs.fontSize);
-			// console.debug(lineHeight);
-		}else if(lineHeight.indexOf("em")>=0){
-			lineHeight = parseFloat(lineHeight);
-		}else{
-			// If we can't get a non-units value, just default
-			// it to the CSS spec default of 'normal'.  Seems to
-			// work better, esp on IE, than '1.0'
-			lineHeight = "normal";
-		}
-		var userStyle = "";
-		var self = this;
-		this.style.replace(/(^|;)\s*(line-|font-?)[^;]+/ig, function(match){
-			match = match.replace(/^;/ig,"") + ';';
-			var s = match.split(":")[0];
-			if(s){
-				s = lang.trim(s);
-				s = s.toLowerCase();
-				var i;
-				var sC = "";
-				for(i = 0; i < s.length; i++){
-					var c = s.charAt(i);
-					switch(c){
-						case "-":
-							i++;
-							c = s.charAt(i).toUpperCase();
-						default:
-							sC += c;
+			// line height is tricky - applying a units value will mess things up.
+			// if we can't get a non-units value, bail out.
+			var lineHeight = _cs.lineHeight;
+			if(lineHeight.indexOf("px") >= 0){
+				lineHeight = parseFloat(lineHeight) / parseFloat(_cs.fontSize);
+				// console.debug(lineHeight);
+			}else if(lineHeight.indexOf("em") >= 0){
+				lineHeight = parseFloat(lineHeight);
+			}else{
+				// If we can't get a non-units value, just default
+				// it to the CSS spec default of 'normal'.  Seems to
+				// work better, esp on IE, than '1.0'
+				lineHeight = "normal";
+			}
+			var userStyle = "";
+			var self = this;
+			this.style.replace(/(^|;)\s*(line-|font-?)[^;]+/ig, function(match){
+				match = match.replace(/^;/ig, "") + ';';
+				var s = match.split(":")[0];
+				if(s){
+					s = lang.trim(s);
+					s = s.toLowerCase();
+					var i;
+					var sC = "";
+					for(i = 0; i < s.length; i++){
+						var c = s.charAt(i);
+						switch(c){
+							case "-":
+								i++;
+								c = s.charAt(i).toUpperCase();
+							default:
+								sC += c;
+						}
 					}
+					domStyle.set(self.domNode, sC, "");
 				}
-				domStyle.set(self.domNode, sC, "");
-			}
-			userStyle += match + ';';
-		});
-
-
-		// need to find any associated label element and update iframe document title
-		var label=query('label[for="'+this.id+'"]');
-
-		return [
-			this.isLeftToRight() ? "<html>\n<head>\n" : "<html dir='rtl'>\n<head>\n",
-			(has("mozilla") && label.length ? "<title>" + label[0].innerHTML + "</title>\n" : ""),
-			"<meta http-equiv='Content-Type' content='text/html'>\n",
-			"<style>\n",
-			"\tbody,html {\n",
-			"\t\tbackground:transparent;\n",
-			"\t\tpadding: 1px 0 0 0;\n",
-			"\t\tmargin: -1px 0 0 0;\n", // remove extraneous vertical scrollbar on safari and firefox
-
-			// Set the html/body sizing.  Webkit always needs this, other browsers
-			// only set it when height is defined (not auto-expanding), otherwise
-			// scrollers do not appear.
-			((has("webkit"))?"\t\twidth: 100%;\n":""),
-			((has("webkit"))?"\t\theight: 100%;\n":""),
-			"\t}\n",
-
-			// TODO: left positioning will cause contents to disappear out of view
-			//	   if it gets too wide for the visible area
-			"\tbody{\n",
-			"\t\ttop:0px;\n",
-			"\t\tleft:0px;\n",
-			"\t\tright:0px;\n",
-			"\t\tfont:", font, ";\n",
-				((this.height||has("opera")) ? "" : "\t\tposition: fixed;\n"),
-			// FIXME: IE 6 won't understand min-height?
-			"\t\tmin-height:", this.minHeight, ";\n",
-			"\t\tline-height:", lineHeight,";\n",
-			"\t}\n",
-			"\tp{ margin: 1em 0; }\n",
-
-			// Determine how scrollers should be applied.  In autoexpand mode (height = "") no scrollers on y at all.
-			// But in fixed height mode we want both x/y scrollers.  Also, if it's using wrapping div and in auto-expand
-			// (Mainly IE) we need to kill the y scroller on body and html.
-			(!setBodyId && !this.height ? "\tbody,html {overflow-y: hidden;}\n" : ""),
-			"\t#dijitEditorBody{overflow-x: auto; overflow-y:" + (this.height ? "auto;" : "hidden;") + " outline: 0px;}\n",
-			"\tli > ul:-moz-first-node, li > ol:-moz-first-node{ padding-top: 1.2em; }\n",
-			// Can't set min-height in IE9, it puts layout on li, which puts move/resize handles.
-			(!has("ie") ? "\tli{ min-height:1.2em; }\n" : ""),
-			"</style>\n",
-			this._applyEditingAreaStyleSheets(),"\n",
-			"</head>\n<body ",
-			(setBodyId?"id='dijitEditorBody' ":""),
-			"onload='frameElement._loadFunc(window,document)' style='"+userStyle+"'>", html, "</body>\n</html>"
-		].join(""); // String
-	},
-
-	_applyEditingAreaStyleSheets: function(){
-		// summary:
-		//		apply the specified css files in styleSheets
-		// tags:
-		//		private
-		var files = [];
-		if(this.styleSheets){
-			files = this.styleSheets.split(';');
-			this.styleSheets = '';
-		}
+				userStyle += match + ';';
+			});
 
-		//empty this.editingAreaStyleSheets here, as it will be filled in addStyleSheet
-		files = files.concat(this.editingAreaStyleSheets);
-		this.editingAreaStyleSheets = [];
 
-		var text='', i=0, url;
-		while((url=files[i++])){
-			var abstring = (new _Url(win.global.location, url)).toString();
-			this.editingAreaStyleSheets.push(abstring);
-			text += '<link rel="stylesheet" type="text/css" href="'+abstring+'"/>';
-		}
-		return text;
-	},
+			// need to find any associated label element, aria-label, or aria-labelledby and update iframe document title
+			var label = query('label[for="' + this.id + '"]');
+			var title = "";
+			if(label.length){
+				title = label[0].innerHTML;
+			}else if(this["aria-label"]){
+				title = this["aria-label"];
+			}else if(this["aria-labelledby"]){
+				title = dom.byId(this["aria-labelledby"]).innerHTML;
+			}
 
-	addStyleSheet: function(/*dojo._Url*/ uri){
-		// summary:
-		//		add an external stylesheet for the editing area
-		// uri:
-		//		A dojo.uri.Uri pointing to the url of the external css file
-		var url=uri.toString();
-
-		//if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe
-		if(url.charAt(0) === '.' || (url.charAt(0) !== '/' && !uri.host)){
-			url = (new _Url(win.global.location, url)).toString();
-		}
+			// Now that we have the title, also set it as the title attribute on the iframe
+			this.iframe.setAttribute("title", title);
+
+			return [
+				"<!DOCTYPE html>",
+				this.isLeftToRight() ? "<html lang='" + this.lang + "'>\n<head>\n" : "<html dir='rtl' lang='" + this.lang + "'>\n<head>\n",
+				//(has("mozilla") && label.length ? "<title>" + label[0].innerHTML + "</title>\n" : ""),
+				title ? "<title>" + title + "</title>" : "",
+				"<meta http-equiv='Content-Type' content='text/html'>\n",
+				"<style>\n",
+				"\tbody,html {\n",
+				"\t\tbackground:transparent;\n",
+				"\t\tpadding: 1px 0 0 0;\n",
+				"\t\tmargin: -1px 0 0 0;\n", // remove extraneous vertical scrollbar on safari and firefox
+				"\t}\n",
+				"\tbody,html, #dijitEditorBody{ outline: none; }",
+
+				// Set <body> to expand to full size of editor, so clicking anywhere will work.
+				// Except in auto-expand mode, in which case the editor expands to the size of <body>.
+				// Also determine how scrollers should be applied.  In autoexpand mode (height = "") no scrollers on y at all.
+				// But in fixed height mode we want both x/y scrollers.
+				// Scrollers go on <body> since it's been set to height: 100%.
+				"html { height: 100%; width: 100%; overflow: hidden; }\n",	// scroll bar is on <body>, shouldn't be on <html>
+				this.height ? "\tbody { height: 100%; width: 100%; overflow: auto; }\n" :
+					"\tbody { min-height: " + this.minHeight + "; width: 100%; overflow-x: auto; overflow-y: hidden; }\n",
+
+				// TODO: left positioning will cause contents to disappear out of view
+				//	   if it gets too wide for the visible area
+				"\tbody{\n",
+				"\t\ttop:0px;\n",
+				"\t\tleft:0px;\n",
+				"\t\tright:0px;\n",
+				"\t\tfont:", font, ";\n",
+				((this.height || has("opera")) ? "" : "\t\tposition: fixed;\n"),
+				"\t\tline-height:", lineHeight, ";\n",
+				"\t}\n",
+				"\tp{ margin: 1em 0; }\n",
+
+				"\tli > ul:-moz-first-node, li > ol:-moz-first-node{ padding-top: 1.2em; }\n",
+				// Can't set min-height in IE9, it puts layout on li, which puts move/resize handles.
+				(!has("ie") ? "\tli{ min-height:1.2em; }\n" : ""),
+				"</style>\n",
+				this._applyEditingAreaStyleSheets(), "\n",
+				"</head>\n<body role='main' ",
+				(setBodyId ? "id='dijitEditorBody' " : ""),
+
+				// Onload handler fills in real editor content.
+				// On IE9, sometimes onload is called twice, and the first time frameElement is null (test_FullScreen.html)
+				"onload='frameElement && frameElement._loadFunc(window,document)' ",
+				"style='" + userStyle + "'>", html, "</body>\n</html>"
+			].join(""); // String
+		},
+
+		_applyEditingAreaStyleSheets: function(){
+			// summary:
+			//		apply the specified css files in styleSheets
+			// tags:
+			//		private
+			var files = [];
+			if(this.styleSheets){
+				files = this.styleSheets.split(';');
+				this.styleSheets = '';
+			}
 
-		if(array.indexOf(this.editingAreaStyleSheets, url) > -1){
-//			console.debug("dijit._editor.RichText.addStyleSheet: Style sheet "+url+" is already applied");
-			return;
-		}
+			//empty this.editingAreaStyleSheets here, as it will be filled in addStyleSheet
+			files = files.concat(this.editingAreaStyleSheets);
+			this.editingAreaStyleSheets = [];
 
-		this.editingAreaStyleSheets.push(url);
-		this.onLoadDeferred.addCallback(lang.hitch(this, function(){
-			if(this.document.createStyleSheet){ //IE
-				this.document.createStyleSheet(url);
-			}else{ //other browser
-				var head = this.document.getElementsByTagName("head")[0];
-				var stylesheet = this.document.createElement("link");
-				stylesheet.rel="stylesheet";
-				stylesheet.type="text/css";
-				stylesheet.href=url;
-				head.appendChild(stylesheet);
-			}
-		}));
-	},
-
-	removeStyleSheet: function(/*dojo._Url*/ uri){
-		// summary:
-		//		remove an external stylesheet for the editing area
-		var url=uri.toString();
-		//if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe
-		if(url.charAt(0) === '.' || (url.charAt(0) !== '/' && !uri.host)){
-			url = (new _Url(win.global.location, url)).toString();
-		}
-		var index = array.indexOf(this.editingAreaStyleSheets, url);
-		if(index === -1){
-//			console.debug("dijit._editor.RichText.removeStyleSheet: Style sheet "+url+" has not been applied");
-			return;
-		}
-		delete this.editingAreaStyleSheets[index];
-		win.withGlobal(this.window,'query', dojo, ['link:[href="'+url+'"]']).orphan();
-	},
-
-	// disabled: Boolean
-	//		The editor is disabled; the text cannot be changed.
-	disabled: false,
-
-	_mozSettingProps: {'styleWithCSS':false},
-	_setDisabledAttr: function(/*Boolean*/ value){
-		value = !!value;
-		this._set("disabled", value);
-		if(!this.isLoaded){ return; } // this method requires init to be complete
-		if(has("ie") || has("webkit") || has("opera")){
-			var preventIEfocus = has("ie") && (this.isLoaded || !this.focusOnLoad);
-			if(preventIEfocus){ this.editNode.unselectable = "on"; }
-			this.editNode.contentEditable = !value;
-			if(preventIEfocus){
-				var _this = this;
-				setTimeout(function(){
-					if(_this.editNode){		// guard in case widget destroyed before timeout
-						_this.editNode.unselectable = "off";
-					}
-				}, 0);
+			var text = '', i = 0, url, ownerWindow = winUtils.get(this.ownerDocument);
+			while((url = files[i++])){
+				var abstring = (new _Url(ownerWindow.location, url)).toString();
+				this.editingAreaStyleSheets.push(abstring);
+				text += '<link rel="stylesheet" type="text/css" href="' + abstring + '"/>';
 			}
-		}else{ //moz
-			try{
-				this.document.designMode=(value?'off':'on');
-			}catch(e){ return; } // ! _disabledOK
-			if(!value && this._mozSettingProps){
-				var ps = this._mozSettingProps;
-				var n;
-				for(n in ps){
-					if(ps.hasOwnProperty(n)){
-						try{
-							this.document.execCommand(n,false,ps[n]);
-						}catch(e2){}
-					}
+			return text;
+		},
+
+		addStyleSheet: function(/*dojo/_base/url*/ uri){
+			// summary:
+			//		add an external stylesheet for the editing area
+			// uri:
+			//		Url of the external css file
+			var url = uri.toString(), ownerWindow = winUtils.get(this.ownerDocument);
+
+			//if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe
+			if(url.charAt(0) === '.' || (url.charAt(0) !== '/' && !uri.host)){
+				url = (new _Url(ownerWindow.location, url)).toString();
+			}
+
+			if(array.indexOf(this.editingAreaStyleSheets, url) > -1){
+//			console.debug("dijit/_editor/RichText.addStyleSheet(): Style sheet "+url+" is already applied");
+				return;
+			}
+
+			this.editingAreaStyleSheets.push(url);
+			this.onLoadDeferred.then(lang.hitch(this, function(){
+				if(this.document.createStyleSheet){ //IE
+					this.document.createStyleSheet(url);
+				}else{ //other browser
+					var head = this.document.getElementsByTagName("head")[0];
+					var stylesheet = this.document.createElement("link");
+					stylesheet.rel = "stylesheet";
+					stylesheet.type = "text/css";
+					stylesheet.href = url;
+					head.appendChild(stylesheet);
 				}
+			}));
+		},
+
+		removeStyleSheet: function(/*dojo/_base/url*/ uri){
+			// summary:
+			//		remove an external stylesheet for the editing area
+			var url = uri.toString(), ownerWindow = winUtils.get(this.ownerDocument);
+			//if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe
+			if(url.charAt(0) === '.' || (url.charAt(0) !== '/' && !uri.host)){
+				url = (new _Url(ownerWindow.location, url)).toString();
+			}
+			var index = array.indexOf(this.editingAreaStyleSheets, url);
+			if(index === -1){
+//			console.debug("dijit/_editor/RichText.removeStyleSheet(): Style sheet "+url+" has not been applied");
+				return;
 			}
+			delete this.editingAreaStyleSheets[index];
+			query('link[href="' + url + '"]', this.window.document).orphan();
+		},
+
+		// disabled: Boolean
+		//		The editor is disabled; the text cannot be changed.
+		disabled: false,
+
+		_mozSettingProps: {'styleWithCSS': false},
+		_setDisabledAttr: function(/*Boolean*/ value){
+			value = !!value;
+			this._set("disabled", value);
+			if(!this.isLoaded){
+				return;
+			} // this method requires init to be complete
+			if(has("ie") || has("webkit") || has("opera")){
+				var preventIEfocus = has("ie") && (this.isLoaded || !this.focusOnLoad);
+				if(preventIEfocus){
+					this.editNode.unselectable = "on";
+				}
+				this.editNode.contentEditable = !value;
+				if(preventIEfocus){
+					this.defer(function(){
+						if(this.editNode){        // guard in case widget destroyed before timeout
+							this.editNode.unselectable = "off";
+						}
+					});
+				}
+			}else{ //moz
+				try{
+					this.document.designMode = (value ? 'off' : 'on');
+				}catch(e){
+					return;
+				} // ! _disabledOK
+				if(!value && this._mozSettingProps){
+					var ps = this._mozSettingProps;
+					var n;
+					for(n in ps){
+						if(ps.hasOwnProperty(n)){
+							try{
+								this.document.execCommand(n, false, ps[n]);
+							}catch(e2){
+							}
+						}
+					}
+				}
 //			this.document.execCommand('contentReadOnly', false, value);
 //				if(value){
 //					this.blur(); //to remove the blinking caret
 //				}
-		}
-		this._disabledOK = true;
-	},
+			}
+			this._disabledOK = true;
+		},
 
-/* Event handlers
- *****************/
+		/* Event handlers
+		 *****************/
 
-	onLoad: function(/*String*/ html){
-		// summary:
-		//		Handler after the iframe finishes loading.
-		// html: String
-		//		Editor contents should be set to this value
-		// tags:
-		//		protected
+		onLoad: function(/*String*/ html){
+			// summary:
+			//		Handler after the iframe finishes loading.
+			// html: String
+			//		Editor contents should be set to this value
+			// tags:
+			//		protected
 
-		// TODO: rename this to _onLoad, make empty public onLoad() method, deprecate/make protected onLoadDeferred handler?
+			// TODO: rename this to _onLoad, make empty public onLoad() method, deprecate/make protected onLoadDeferred handler?
 
-		if(!this.window.__registeredWindow){
-			this.window.__registeredWindow = true;
-			this._iframeRegHandle = focus.registerIframe(this.iframe);
-		}
-		if(!has("ie") && !has("webkit") && (this.height || has("mozilla"))){
-			this.editNode=this.document.body;
-		}else{
-			// there's a wrapper div around the content, see _getIframeDocTxt().
-			this.editNode=this.document.body.firstChild;
-			var _this = this;
-			if(has("ie")){ // #4996 IE wants to focus the BODY tag
-				this.tabStop = domConstruct.create('div', { tabIndex: -1 }, this.editingArea);
-				this.iframe.onfocus = function(){ _this.editNode.setActive(); };
+			if(!this.window.__registeredWindow){
+				this.window.__registeredWindow = true;
+				this._iframeRegHandle = focus.registerIframe(this.iframe);
 			}
-		}
-		this.focusNode = this.editNode; // for InlineEditBox
-
-
-		var events = this.events.concat(this.captureEvents);
-		var ap = this.iframe ? this.document : this.editNode;
-		array.forEach(events, function(item){
-			this.connect(ap, item.toLowerCase(), item);
-		}, this);
-
-		this.connect(ap, "onmouseup", "onClick"); // mouseup in the margin does not generate an onclick event
-
-		if(has("ie")){ // IE contentEditable
-			this.connect(this.document, "onmousedown", "_onIEMouseDown"); // #4996 fix focus
-
-			// give the node Layout on IE
-			// TODO: this may no longer be needed, since we've reverted IE to using an iframe,
-			// not contentEditable.   Removing it would also probably remove the need for creating
-			// the extra <div> in _getIframeDocTxt()
-			this.editNode.style.zoom = 1.0;
-		}else{
-			this.connect(this.document, "onmousedown", function(){
-				// Clear the moveToStart focus, as mouse
-				// down will set cursor point.  Required to properly
-				// work with selection/position driven plugins and clicks in
-				// the window. refs: #10678
-				delete this._cursorToStart;
-			});
-		}
-
-		if(has("webkit")){
-			//WebKit sometimes doesn't fire right on selections, so the toolbar
-			//doesn't update right.  Therefore, help it out a bit with an additional
-			//listener.  A mouse up will typically indicate a display change, so fire this
-			//and get the toolbar to adapt.  Reference: #9532
-			this._webkitListener = this.connect(this.document, "onmouseup", "onDisplayChanged");
-			this.connect(this.document, "onmousedown", function(e){
-				var t = e.target;
-				if(t && (t === this.document.body || t === this.document)){
-					// Since WebKit uses the inner DIV, we need to check and set position.
-					// See: #12024 as to why the change was made.
-					setTimeout(lang.hitch(this, "placeCursorAtEnd"), 0);
+			if(!has("ie") && !has("webkit") && (this.height || has("mozilla"))){
+				this.editNode = this.document.body;
+			}else{
+				// there's a wrapper div around the content, see _getIframeDocTxt().
+				this.editNode = this.document.body.firstChild;
+				var _this = this;
+				if(has("ie")){ // #4996 IE wants to focus the BODY tag
+					this.tabStop = domConstruct.create('div', { tabIndex: -1 }, this.editingArea);
+					this.iframe.onfocus = function(){
+						_this.editNode.setActive();
+					};
 				}
-			});
-		}
+			}
+			this.focusNode = this.editNode; // for InlineEditBox
 
-		if(has("ie")){
-			// Try to make sure 'hidden' elements aren't visible in edit mode (like browsers other than IE
-			// do).  See #9103
-			try{
-				this.document.execCommand('RespectVisibilityInDesign', true, null);
-			}catch(e){/* squelch */}
-		}
 
-		this.isLoaded = true;
+			var events = this.events.concat(this.captureEvents);
+			var ap = this.iframe ? this.document : this.editNode;
+			this.own(
+				array.map(events, function(item){
+					var type = item.toLowerCase().replace(/^on/, "");
+					on(ap, type, lang.hitch(this, item));
+				}, this)
+			);
 
-		this.set('disabled', this.disabled); // initialize content to editable (or not)
+			this.own(on(ap, "mouseup", lang.hitch(this, "onClick"))); // mouseup in the margin does not generate an onclick event
 
-		// Note that setValue() call will only work after isLoaded is set to true (above)
+			if(has("ie")){ // IE contentEditable
+				this.own(on(this.document, "mousedown", lang.hitch(this, "_onIEMouseDown"))); // #4996 fix focus
 
-		// Set up a function to allow delaying the setValue until a callback is fired
-		// This ensures extensions like dijit.Editor have a way to hold the value set
-		// until plugins load (and do things like register filters).
-		var setContent = lang.hitch(this, function(){
-			this.setValue(html);
-			if(this.onLoadDeferred){
-				this.onLoadDeferred.callback(true);
+				// give the node Layout on IE
+				// TODO: this may no longer be needed, since we've reverted IE to using an iframe,
+				// not contentEditable.   Removing it would also probably remove the need for creating
+				// the extra <div> in _getIframeDocTxt()
+				this.editNode.style.zoom = 1.0;
+			}else{
+				this.own(on(this.document, "mousedown", lang.hitch(this, function(){
+					// Clear the moveToStart focus, as mouse
+					// down will set cursor point.  Required to properly
+					// work with selection/position driven plugins and clicks in
+					// the window. refs: #10678
+					delete this._cursorToStart;
+				})));
 			}
-			this.onDisplayChanged();
-			if(this.focusOnLoad){
-				// after the document loads, then set focus after updateInterval expires so that
-				// onNormalizedDisplayChanged has run to avoid input caret issues
-				ready(lang.hitch(this, function(){ setTimeout(lang.hitch(this, "focus"), this.updateInterval); }));
-			}
-			// Save off the initial content now
-			this.value = this.getValue(true);
-		});
-		if(this.setValueDeferred){
-			this.setValueDeferred.addCallback(setContent);
-		}else{
-			setContent();
-		}
-	},
 
-	onKeyDown: function(/* Event */ e){
-		// summary:
-		//		Handler for onkeydown event
-		// tags:
-		//		protected
+			if(has("webkit")){
+				//WebKit sometimes doesn't fire right on selections, so the toolbar
+				//doesn't update right.  Therefore, help it out a bit with an additional
+				//listener.  A mouse up will typically indicate a display change, so fire this
+				//and get the toolbar to adapt.  Reference: #9532
+				this._webkitListener = this.own(on(this.document, "mouseup", lang.hitch(this, "onDisplayChanged")))[0];
+				this.own(on(this.document, "mousedown", lang.hitch(this, function(e){
+					var t = e.target;
+					if(t && (t === this.document.body || t === this.document)){
+						// Since WebKit uses the inner DIV, we need to check and set position.
+						// See: #12024 as to why the change was made.
+						this.defer("placeCursorAtEnd");
+					}
+				})));
+			}
+
+			if(has("ie")){
+				// Try to make sure 'hidden' elements aren't visible in edit mode (like browsers other than IE
+				// do).  See #9103
+				try{
+					this.document.execCommand('RespectVisibilityInDesign', true, null);
+				}catch(e){/* squelch */
+				}
+			}
+
+			this.isLoaded = true;
 
-		// we need this event at the moment to get the events from control keys
-		// such as the backspace. It might be possible to add this to Dojo, so that
-		// keyPress events can be emulated by the keyDown and keyUp detection.
+			this.set('disabled', this.disabled); // initialize content to editable (or not)
 
-		if(e.keyCode === keys.TAB && this.isTabIndent ){
-			event.stop(e); //prevent tab from moving focus out of editor
+			// Note that setValue() call will only work after isLoaded is set to true (above)
 
-			// FIXME: this is a poor-man's indent/outdent. It would be
-			// better if it added 4 " " chars in an undoable way.
-			// Unfortunately pasteHTML does not prove to be undoable
-			if(this.queryCommandEnabled((e.shiftKey ? "outdent" : "indent"))){
-				this.execCommand((e.shiftKey ? "outdent" : "indent"));
+			// Set up a function to allow delaying the setValue until a callback is fired
+			// This ensures extensions like dijit.Editor have a way to hold the value set
+			// until plugins load (and do things like register filters).
+			var setContent = lang.hitch(this, function(){
+				this.setValue(html);
+				if(this.onLoadDeferred){
+					this.onLoadDeferred.resolve(true);
+				}
+				this.onDisplayChanged();
+				if(this.focusOnLoad){
+					// after the document loads, then set focus after updateInterval expires so that
+					// onNormalizedDisplayChanged has run to avoid input caret issues
+					domReady(lang.hitch(this, "defer", "focus", this.updateInterval));
+				}
+				// Save off the initial content now
+				this.value = this.getValue(true);
+			});
+			if(this.setValueDeferred){
+				this.setValueDeferred.then(setContent);
+			}else{
+				setContent();
 			}
-		}
-		if(has("ie")){
-			if(e.keyCode == keys.TAB && !this.isTabIndent){
-				if(e.shiftKey && !e.ctrlKey && !e.altKey){
-					// focus the BODY so the browser will tab away from it instead
-					this.iframe.focus();
-				}else if(!e.shiftKey && !e.ctrlKey && !e.altKey){
-					// focus the BODY so the browser will tab away from it instead
-					this.tabStop.focus();
+		},
+
+		onKeyDown: function(/* Event */ e){
+			// summary:
+			//		Handler for keydown event
+			// tags:
+			//		protected
+
+			if(e.keyCode === keys.TAB && this.isTabIndent){
+				//prevent tab from moving focus out of editor
+				e.stopPropagation();
+				e.preventDefault();
+
+				// FIXME: this is a poor-man's indent/outdent. It would be
+				// better if it added 4 " " chars in an undoable way.
+				// Unfortunately pasteHTML does not prove to be undoable
+				if(this.queryCommandEnabled((e.shiftKey ? "outdent" : "indent"))){
+					this.execCommand((e.shiftKey ? "outdent" : "indent"));
 				}
-			}else if(e.keyCode === keys.BACKSPACE && this.document.selection.type === "Control"){
-				// IE has a bug where if a non-text object is selected in the editor,
-				// hitting backspace would act as if the browser's back button was
-				// clicked instead of deleting the object. see #1069
-				event.stop(e);
-				this.execCommand("delete");
-			}else if((65 <= e.keyCode && e.keyCode <= 90) ||
-				(e.keyCode>=37 && e.keyCode<=40) // FIXME: get this from connect() instead!
-			){ //arrow keys
-				e.charCode = e.keyCode;
-				this.onKeyPress(e);
 			}
-		}
-		if(has("ff")){
-			if(e.keyCode === keys.PAGE_UP || e.keyCode === keys.PAGE_DOWN ){
-				if(this.editNode.clientHeight >= this.editNode.scrollHeight){
-					// Stop the event to prevent firefox from trapping the cursor when there is no scroll bar.
+			if(has("ie")){
+				if(e.keyCode == keys.TAB && !this.isTabIndent){
+					if(e.shiftKey && !e.ctrlKey && !e.altKey){
+						// focus the BODY so the browser will tab away from it instead
+						this.iframe.focus();
+					}else if(!e.shiftKey && !e.ctrlKey && !e.altKey){
+						// focus the BODY so the browser will tab away from it instead
+						this.tabStop.focus();
+					}
+				}else if(e.keyCode === keys.BACKSPACE && this.document.selection.type === "Control"){
+					// IE has a bug where if a non-text object is selected in the editor,
+					// hitting backspace would act as if the browser's back button was
+					// clicked instead of deleting the object. see #1069
+					e.stopPropagation();
 					e.preventDefault();
+					this.execCommand("delete");
 				}
 			}
-		}
-		return true;
-	},
-
-	onKeyUp: function(/*===== e =====*/){
-		// summary:
-		//		Handler for onkeyup event
-		// tags:
-		//      callback
-	},
-
-	setDisabled: function(/*Boolean*/ disabled){
-		// summary:
-		//		Deprecated, use set('disabled', ...) instead.
-		// tags:
-		//		deprecated
-		kernel.deprecated('dijit.Editor::setDisabled is deprecated','use dijit.Editor::attr("disabled",boolean) instead', 2.0);
-		this.set('disabled',disabled);
-	},
-	_setValueAttr: function(/*String*/ value){
-		// summary:
-		//      Registers that attr("value", foo) should call setValue(foo)
-		this.setValue(value);
-	},
-	_setDisableSpellCheckAttr: function(/*Boolean*/ disabled){
-		if(this.document){
-			domAttr.set(this.document.body, "spellcheck", !disabled);
-		}else{
-			// try again after the editor is finished loading
-			this.onLoadDeferred.addCallback(lang.hitch(this, function(){
-				domAttr.set(this.document.body, "spellcheck", !disabled);
-			}));
-		}
-		this._set("disableSpellCheck", disabled);
-	},
-
-	onKeyPress: function(e){
-		// summary:
-		//		Handle the various key events
-		// tags:
-		//		protected
-
-		var c = (e.keyChar && e.keyChar.toLowerCase()) || e.keyCode,
-			handlers = this._keyHandlers[c],
-			args = arguments;
-			
-		if(handlers && !e.altKey){
-			array.some(handlers, function(h){
-				// treat meta- same as ctrl-, for benefit of mac users
-				if(!(h.shift ^ e.shiftKey) && !(h.ctrl ^ (e.ctrlKey||e.metaKey))){ 
-					if(!h.handler.apply(this, args)){
+			if(has("ff")){
+				if(e.keyCode === keys.PAGE_UP || e.keyCode === keys.PAGE_DOWN){
+					if(this.editNode.clientHeight >= this.editNode.scrollHeight){
+						// Stop the event to prevent firefox from trapping the cursor when there is no scroll bar.
 						e.preventDefault();
 					}
-					return true;
 				}
-			}, this);
-		}
-
-		// function call after the character has been inserted
-		if(!this._onKeyHitch){
-			this._onKeyHitch = lang.hitch(this, "onKeyPressed");
-		}
-		setTimeout(this._onKeyHitch, 1);
-		return true;
-	},
-
-	addKeyHandler: function(/*String*/ key, /*Boolean*/ ctrl, /*Boolean*/ shift, /*Function*/ handler){
-		// summary:
-		//		Add a handler for a keyboard shortcut
-		// description:
-		//		The key argument should be in lowercase if it is a letter character
-		// tags:
-		//		protected
-		if(!lang.isArray(this._keyHandlers[key])){
-			this._keyHandlers[key] = [];
-		}
-		//TODO: would be nice to make this a hash instead of an array for quick lookups
-		this._keyHandlers[key].push({
-			shift: shift || false,
-			ctrl: ctrl || false,
-			handler: handler
-		});
-	},
-
-	onKeyPressed: function(){
-		// summary:
-		//		Handler for after the user has pressed a key, and the display has been updated.
-		//		(Runs on a timer so that it runs after the display is updated)
-		// tags:
-		//		private
-		this.onDisplayChanged(/*e*/); // can't pass in e
-	},
-
-	onClick: function(/*Event*/ e){
-		// summary:
-		//		Handler for when the user clicks.
-		// tags:
-		//		private
-
-		// console.info('onClick',this._tryDesignModeOn);
-		this.onDisplayChanged(e);
-	},
-
-	_onIEMouseDown: function(){
-		// summary:
-		//		IE only to prevent 2 clicks to focus
-		// tags:
-		//		protected
-
-		if(!this.focused && !this.disabled){
-			this.focus();
-		}
-	},
+			}
 
-	_onBlur: function(e){
-		// summary:
-		//		Called from focus manager when focus has moved away from this editor
-		// tags:
-		//		protected
+			var handlers = this._keyHandlers[e.keyCode],
+				args = arguments;
 
-		// console.info('_onBlur')
+			if(handlers && !e.altKey){
+				array.some(handlers, function(h){
+					// treat meta- same as ctrl-, for benefit of mac users
+					if(!(h.shift ^ e.shiftKey) && !(h.ctrl ^ (e.ctrlKey || e.metaKey))){
+						if(!h.handler.apply(this, args)){
+							e.preventDefault();
+						}
+						return true;
+					}
+				}, this);
+			}
 
-		this.inherited(arguments);
+			// function call after the character has been inserted
+			this.defer("onKeyPressed", 1);
 
-		var newValue = this.getValue(true);
-		if(newValue !== this.value){
-			this.onChange(newValue);
-		}
-		this._set("value", newValue);
-	},
+			return true;
+		},
+
+		onKeyUp: function(/*===== e =====*/){
+			// summary:
+			//		Handler for onkeyup event
+			// tags:
+			//		callback
+		},
+
+		setDisabled: function(/*Boolean*/ disabled){
+			// summary:
+			//		Deprecated, use set('disabled', ...) instead.
+			// tags:
+			//		deprecated
+			kernel.deprecated('dijit.Editor::setDisabled is deprecated', 'use dijit.Editor::attr("disabled",boolean) instead', 2.0);
+			this.set('disabled', disabled);
+		},
+		_setValueAttr: function(/*String*/ value){
+			// summary:
+			//		Registers that attr("value", foo) should call setValue(foo)
+			this.setValue(value);
+		},
+		_setDisableSpellCheckAttr: function(/*Boolean*/ disabled){
+			if(this.document){
+				domAttr.set(this.document.body, "spellcheck", !disabled);
+			}else{
+				// try again after the editor is finished loading
+				this.onLoadDeferred.then(lang.hitch(this, function(){
+					domAttr.set(this.document.body, "spellcheck", !disabled);
+				}));
+			}
+			this._set("disableSpellCheck", disabled);
+		},
+
+		addKeyHandler: function(/*String|Number*/ key, /*Boolean*/ ctrl, /*Boolean*/ shift, /*Function*/ handler){
+			// summary:
+			//		Add a handler for a keyboard shortcut
+			// tags:
+			//		protected
+
+			if(typeof key == "string"){
+				// Something like Ctrl-B.  Since using keydown event, we need to convert string to a number.
+				key = key.toUpperCase().charCodeAt(0);
+			}
 
-	_onFocus: function(/*Event*/ e){
-		// summary:
-		//		Called from focus manager when focus has moved into this editor
-		// tags:
-		//		protected
+			if(!lang.isArray(this._keyHandlers[key])){
+				this._keyHandlers[key] = [];
+			}
 
-		// console.info('_onFocus')
-		if(!this.disabled){
-			if(!this._disabledOK){
-				this.set('disabled', false);
+			this._keyHandlers[key].push({
+				shift: shift || false,
+				ctrl: ctrl || false,
+				handler: handler
+			});
+		},
+
+		onKeyPressed: function(){
+			// summary:
+			//		Handler for after the user has pressed a key, and the display has been updated.
+			//		(Runs on a timer so that it runs after the display is updated)
+			// tags:
+			//		private
+			this.onDisplayChanged(/*e*/); // can't pass in e
+		},
+
+		onClick: function(/*Event*/ e){
+			// summary:
+			//		Handler for when the user clicks.
+			// tags:
+			//		private
+
+			// console.info('onClick',this._tryDesignModeOn);
+			this.onDisplayChanged(e);
+		},
+
+		_onIEMouseDown: function(){
+			// summary:
+			//		IE only to prevent 2 clicks to focus
+			// tags:
+			//		protected
+
+			if(!this.focused && !this.disabled){
+				this.focus();
+			}
+		},
+
+		_onBlur: function(e){
+			// summary:
+			//		Called from focus manager when focus has moved away from this editor
+			// tags:
+			//		protected
+
+			// Workaround IE9+ problems when you blur the browser windows while an editor is focused: IE hangs
+			// when you focus editor #1, blur the browser window, and then click editor #0.  See #16939.
+			if(has("ie") >= 9){
+				this.defer(function(){
+					if(!focus.curNode){
+						this.ownerDocumentBody.focus();
+					}
+				});
 			}
+
 			this.inherited(arguments);
-		}
-	},
 
-	// TODO: remove in 2.0
-	blur: function(){
-		// summary:
-		//		Remove focus from this instance.
-		// tags:
-		//		deprecated
-		if(!has("ie") && this.window.document.documentElement && this.window.document.documentElement.focus){
-			this.window.document.documentElement.focus();
-		}else if(win.doc.body.focus){
-			win.doc.body.focus();
-		}
-	},
+			var newValue = this.getValue(true);
+			if(newValue !== this.value){
+				this.onChange(newValue);
+			}
+			this._set("value", newValue);
+		},
+
+		_onFocus: function(/*Event*/ e){
+			// summary:
+			//		Called from focus manager when focus has moved into this editor
+			// tags:
+			//		protected
+
+			// console.info('_onFocus')
+			if(!this.disabled){
+				if(!this._disabledOK){
+					this.set('disabled', false);
+				}
+				this.inherited(arguments);
+			}
+		},
+
+		// TODO: remove in 2.0
+		blur: function(){
+			// summary:
+			//		Remove focus from this instance.
+			// tags:
+			//		deprecated
+			if(!has("ie") && this.window.document.documentElement && this.window.document.documentElement.focus){
+				this.window.document.documentElement.focus();
+			}else if(this.ownerDocumentBody.focus){
+				this.ownerDocumentBody.focus();
+			}
+		},
 
-	focus: function(){
-		// summary:
-		//		Move focus to this editor
-		if(!this.isLoaded){
-			this.focusOnLoad = true;
-			return;
-		}
-		if(this._cursorToStart){
-			delete this._cursorToStart;
-			if(this.editNode.childNodes){
-				this.placeCursorAtStart(); // this calls focus() so return
+		focus: function(){
+			// summary:
+			//		Move focus to this editor
+			if(!this.isLoaded){
+				this.focusOnLoad = true;
 				return;
 			}
-		}
-		if(!has("ie")){
-			focus.focus(this.iframe);
-		}else if(this.editNode && this.editNode.focus){
-			// editNode may be hidden in display:none div, lets just punt in this case
-			//this.editNode.focus(); -> causes IE to scroll always (strict and quirks mode) to the top the Iframe
-			// if we fire the event manually and let the browser handle the focusing, the latest
-			// cursor position is focused like in FF
-			this.iframe.fireEvent('onfocus', document.createEventObject()); // createEventObject only in IE
-		//	}else{
-		// TODO: should we throw here?
-		// console.debug("Have no idea how to focus into the editor!");
-		}
-	},
-
-	// _lastUpdate: 0,
-	updateInterval: 200,
-	_updateTimer: null,
-	onDisplayChanged: function(/*Event*/ /*===== e =====*/){
-		// summary:
-		//		This event will be fired every time the display context
-		//		changes and the result needs to be reflected in the UI.
-		// description:
-		//		If you don't want to have update too often,
-		//		onNormalizedDisplayChanged should be used instead
-		// tags:
-		//		private
-
-		// var _t=new Date();
-		if(this._updateTimer){
-			clearTimeout(this._updateTimer);
-		}
-		if(!this._updateHandler){
-			this._updateHandler = lang.hitch(this,"onNormalizedDisplayChanged");
-		}
-		this._updateTimer = setTimeout(this._updateHandler, this.updateInterval);
+			if(this._cursorToStart){
+				delete this._cursorToStart;
+				if(this.editNode.childNodes){
+					this.placeCursorAtStart(); // this calls focus() so return
+					return;
+				}
+			}
+			if(!has("ie")){
+				focus.focus(this.iframe);
+			}else if(this.editNode && this.editNode.focus){
+				// editNode may be hidden in display:none div, lets just punt in this case
+				//this.editNode.focus(); -> causes IE to scroll always (strict and quirks mode) to the top the Iframe
+				// if we fire the event manually and let the browser handle the focusing, the latest
+				// cursor position is focused like in FF
+				this.iframe.fireEvent('onfocus', document.createEventObject()); // createEventObject only in IE
+				//	}else{
+				// TODO: should we throw here?
+				// console.debug("Have no idea how to focus into the editor!");
+			}
+		},
+
+		// _lastUpdate: 0,
+		updateInterval: 200,
+		_updateTimer: null,
+		onDisplayChanged: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		This event will be fired every time the display context
+			//		changes and the result needs to be reflected in the UI.
+			// description:
+			//		If you don't want to have update too often,
+			//		onNormalizedDisplayChanged should be used instead
+			// tags:
+			//		private
+
+			// var _t=new Date();
+			if(this._updateTimer){
+				this._updateTimer.remove();
+			}
+			this._updateTimer = this.defer("onNormalizedDisplayChanged", this.updateInterval);
+
+			// Technically this should trigger a call to watch("value", ...) registered handlers,
+			// but getValue() is too slow to call on every keystroke so we don't.
+		},
+		onNormalizedDisplayChanged: function(){
+			// summary:
+			//		This event is fired every updateInterval ms or more
+			// description:
+			//		If something needs to happen immediately after a
+			//		user change, please use onDisplayChanged instead.
+			// tags:
+			//		private
+			delete this._updateTimer;
+		},
+		onChange: function(/*===== newContent =====*/){
+			// summary:
+			//		This is fired if and only if the editor loses focus and
+			//		the content is changed.
+		},
+		_normalizeCommand: function(/*String*/ cmd, /*Anything?*/argument){
+			// summary:
+			//		Used as the advice function to map our
+			//		normalized set of commands to those supported by the target
+			//		browser.
+			// tags:
+			//		private
+
+			var command = cmd.toLowerCase();
+			if(command === "formatblock"){
+				if(has("safari") && argument === undefined){
+					command = "heading";
+				}
+			}else if(command === "hilitecolor" && !has("mozilla")){
+				command = "backcolor";
+			}
 
-		// Technically this should trigger a call to watch("value", ...) registered handlers,
-		// but getValue() is too slow to call on every keystroke so we don't.
-	},
-	onNormalizedDisplayChanged: function(){
-		// summary:
-		//		This event is fired every updateInterval ms or more
-		// description:
-		//		If something needs to happen immediately after a
-		//		user change, please use onDisplayChanged instead.
-		// tags:
-		//		private
-		delete this._updateTimer;
-	},
-	onChange: function(/*===== newContent =====*/){
-		// summary:
-		//		This is fired if and only if the editor loses focus and
-		//		the content is changed.
-	},
-	_normalizeCommand: function(/*String*/ cmd, /*Anything?*/argument){
-		// summary:
-		//		Used as the advice function to map our
-		//		normalized set of commands to those supported by the target
-		//		browser.
-		// tags:
-		//		private
+			return command;
+		},
+
+		_qcaCache: {},
+		queryCommandAvailable: function(/*String*/ command){
+			// summary:
+			//		Tests whether a command is supported by the host. Clients
+			//		SHOULD check whether a command is supported before attempting
+			//		to use it, behaviour for unsupported commands is undefined.
+			// command:
+			//		The command to test for
+			// tags:
+			//		private
+
+			// memoizing version. See _queryCommandAvailable for computing version
+			var ca = this._qcaCache[command];
+			if(ca !== undefined){
+				return ca;
+			}
+			return (this._qcaCache[command] = this._queryCommandAvailable(command));
+		},
+
+		_queryCommandAvailable: function(/*String*/ command){
+			// summary:
+			//		See queryCommandAvailable().
+			// tags:
+			//		private
+
+			var ie = 1;
+			var mozilla = 1 << 1;
+			var webkit = 1 << 2;
+			var opera = 1 << 3;
+
+			function isSupportedBy(browsers){
+				return {
+					ie: Boolean(browsers & ie),
+					mozilla: Boolean(browsers & mozilla),
+					webkit: Boolean(browsers & webkit),
+					opera: Boolean(browsers & opera)
+				};
+			}
 
-		var command = cmd.toLowerCase();
-		if(command === "formatblock"){
-			if(has("safari") && argument === undefined){ command = "heading"; }
-		}else if(command === "hilitecolor" && !has("mozilla")){
-			command = "backcolor";
-		}
+			var supportedBy = null;
+
+			switch(command.toLowerCase()){
+				case "bold":
+				case "italic":
+				case "underline":
+				case "subscript":
+				case "superscript":
+				case "fontname":
+				case "fontsize":
+				case "forecolor":
+				case "hilitecolor":
+				case "justifycenter":
+				case "justifyfull":
+				case "justifyleft":
+				case "justifyright":
+				case "delete":
+				case "selectall":
+				case "toggledir":
+					supportedBy = isSupportedBy(mozilla | ie | webkit | opera);
+					break;
 
-		return command;
-	},
+				case "createlink":
+				case "unlink":
+				case "removeformat":
+				case "inserthorizontalrule":
+				case "insertimage":
+				case "insertorderedlist":
+				case "insertunorderedlist":
+				case "indent":
+				case "outdent":
+				case "formatblock":
+				case "inserthtml":
+				case "undo":
+				case "redo":
+				case "strikethrough":
+				case "tabindent":
+					supportedBy = isSupportedBy(mozilla | ie | opera | webkit);
+					break;
 
-	_qcaCache: {},
-	queryCommandAvailable: function(/*String*/ command){
-		// summary:
-		//		Tests whether a command is supported by the host. Clients
-		//		SHOULD check whether a command is supported before attempting
-		//		to use it, behaviour for unsupported commands is undefined.
-		// command:
-		//		The command to test for
-		// tags:
-		//		private
+				case "blockdirltr":
+				case "blockdirrtl":
+				case "dirltr":
+				case "dirrtl":
+				case "inlinedirltr":
+				case "inlinedirrtl":
+					supportedBy = isSupportedBy(ie);
+					break;
+				case "cut":
+				case "copy":
+				case "paste":
+					supportedBy = isSupportedBy(ie | mozilla | webkit | opera);
+					break;
 
-		// memoizing version. See _queryCommandAvailable for computing version
-		var ca = this._qcaCache[command];
-		if(ca !== undefined){ return ca; }
-		return (this._qcaCache[command] = this._queryCommandAvailable(command));
-	},
+				case "inserttable":
+					supportedBy = isSupportedBy(mozilla | ie);
+					break;
 
-	_queryCommandAvailable: function(/*String*/ command){
-		// summary:
-		//		See queryCommandAvailable().
-		// tags:
-		//		private
+				case "insertcell":
+				case "insertcol":
+				case "insertrow":
+				case "deletecells":
+				case "deletecols":
+				case "deleterows":
+				case "mergecells":
+				case "splitcell":
+					supportedBy = isSupportedBy(ie | mozilla);
+					break;
 
-		var ie = 1;
-		var mozilla = 1 << 1;
-		var webkit = 1 << 2;
-		var opera = 1 << 3;
-
-		function isSupportedBy(browsers){
-			return {
-				ie: Boolean(browsers & ie),
-				mozilla: Boolean(browsers & mozilla),
-				webkit: Boolean(browsers & webkit),
-				opera: Boolean(browsers & opera)
-			};
-		}
+				default:
+					return false;
+			}
 
-		var supportedBy = null;
-
-		switch(command.toLowerCase()){
-			case "bold": case "italic": case "underline":
-			case "subscript": case "superscript":
-			case "fontname": case "fontsize":
-			case "forecolor": case "hilitecolor":
-			case "justifycenter": case "justifyfull": case "justifyleft":
-			case "justifyright": case "delete": case "selectall": case "toggledir":
-				supportedBy = isSupportedBy(mozilla | ie | webkit | opera);
-				break;
-
-			case "createlink": case "unlink": case "removeformat":
-			case "inserthorizontalrule": case "insertimage":
-			case "insertorderedlist": case "insertunorderedlist":
-			case "indent": case "outdent": case "formatblock":
-			case "inserthtml": case "undo": case "redo": case "strikethrough": case "tabindent":
-				supportedBy = isSupportedBy(mozilla | ie | opera | webkit);
-				break;
-
-			case "blockdirltr": case "blockdirrtl":
-			case "dirltr": case "dirrtl":
-			case "inlinedirltr": case "inlinedirrtl":
-				supportedBy = isSupportedBy(ie);
-				break;
-			case "cut": case "copy": case "paste":
-				supportedBy = isSupportedBy( ie | mozilla | webkit);
-				break;
-
-			case "inserttable":
-				supportedBy = isSupportedBy(mozilla | ie);
-				break;
-
-			case "insertcell": case "insertcol": case "insertrow":
-			case "deletecells": case "deletecols": case "deleterows":
-			case "mergecells": case "splitcell":
-				supportedBy = isSupportedBy(ie | mozilla);
-				break;
-
-			default: return false;
-		}
+			return (has("ie") && supportedBy.ie) ||
+				(has("mozilla") && supportedBy.mozilla) ||
+				(has("webkit") && supportedBy.webkit) ||
+				(has("opera") && supportedBy.opera);	// Boolean return true if the command is supported, false otherwise
+		},
+
+		execCommand: function(/*String*/ command, argument){
+			// summary:
+			//		Executes a command in the Rich Text area
+			// command:
+			//		The command to execute
+			// argument:
+			//		An optional argument to the command
+			// tags:
+			//		protected
+			var returnValue;
+
+			//focus() is required for IE to work
+			//In addition, focus() makes sure after the execution of
+			//the command, the editor receives the focus as expected
+			if(this.focused){
+				// put focus back in the iframe, unless focus has somehow been shifted out of the editor completely
+				this.focus();
+			}
 
-		return (has("ie") && supportedBy.ie) ||
-			(has("mozilla") && supportedBy.mozilla) ||
-			(has("webkit") && supportedBy.webkit) ||
-			(has("opera") && supportedBy.opera);	// Boolean return true if the command is supported, false otherwise
-	},
+			command = this._normalizeCommand(command, argument);
 
-	execCommand: function(/*String*/ command, argument){
-		// summary:
-		//		Executes a command in the Rich Text area
-		// command:
-		//		The command to execute
-		// argument:
-		//		An optional argument to the command
-		// tags:
-		//		protected
-		var returnValue;
-
-		//focus() is required for IE to work
-		//In addition, focus() makes sure after the execution of
-		//the command, the editor receives the focus as expected
-		this.focus();
-
-		command = this._normalizeCommand(command, argument);
-		
-		if(argument !== undefined){
-			if(command === "heading"){
-				throw new Error("unimplemented");
-			}else if((command === "formatblock") && has("ie")){
-				argument = '<'+argument+'>';
+			if(argument !== undefined){
+				if(command === "heading"){
+					throw new Error("unimplemented");
+				}else if((command === "formatblock") && has("ie")){
+					argument = '<' + argument + '>';
+				}
 			}
-		}
 
-		//Check to see if we have any over-rides for commands, they will be functions on this
-		//widget of the form _commandImpl.  If we don't, fall through to the basic native
-		//exec command of the browser.
-		var implFunc = "_" + command + "Impl";
-		if(this[implFunc]){
-			returnValue = this[implFunc](argument);
-		}else{
-			argument = arguments.length > 1 ? argument : null;
-			if(argument || command !== "createlink"){
-				returnValue = this.document.execCommand(command, false, argument);
+			//Check to see if we have any over-rides for commands, they will be functions on this
+			//widget of the form _commandImpl.  If we don't, fall through to the basic native
+			//exec command of the browser.
+			var implFunc = "_" + command + "Impl";
+			if(this[implFunc]){
+				returnValue = this[implFunc](argument);
+			}else{
+				argument = arguments.length > 1 ? argument : null;
+				if(argument || command !== "createlink"){
+					returnValue = this.document.execCommand(command, false, argument);
+				}
 			}
-		}
-
-		this.onDisplayChanged();
-		return returnValue;
-	},
 
-	queryCommandEnabled: function(/*String*/ command){
-		// summary:
-		//		Check whether a command is enabled or not.
-		// command:
-		//		The command to execute
-		// tags:
-		//		protected
-		if(this.disabled || !this._disabledOK){ return false; }
+			this.onDisplayChanged();
+			return returnValue;
+		},
+
+		queryCommandEnabled: function(/*String*/ command){
+			// summary:
+			//		Check whether a command is enabled or not.
+			// command:
+			//		The command to execute
+			// tags:
+			//		protected
+			if(this.disabled || !this._disabledOK){
+				return false;
+			}
 
-		command = this._normalizeCommand(command);
+			command = this._normalizeCommand(command);
 
-		//Check to see if we have any over-rides for commands, they will be functions on this
-		//widget of the form _commandEnabledImpl.  If we don't, fall through to the basic native
-		//command of the browser.
-		var implFunc = "_" + command + "EnabledImpl";
+			//Check to see if we have any over-rides for commands, they will be functions on this
+			//widget of the form _commandEnabledImpl.  If we don't, fall through to the basic native
+			//command of the browser.
+			var implFunc = "_" + command + "EnabledImpl";
 
-		if(this[implFunc]){
-			return  this[implFunc](command);
-		}else{
-			return this._browserQueryCommandEnabled(command);
-		}
-	},
+			if(this[implFunc]){
+				return  this[implFunc](command);
+			}else{
+				return this._browserQueryCommandEnabled(command);
+			}
+		},
 
-	queryCommandState: function(command){
-		// summary:
-		//		Check the state of a given command and returns true or false.
-		// tags:
-		//		protected
-
-		if(this.disabled || !this._disabledOK){ return false; }
-		command = this._normalizeCommand(command);
-		try{
-			return this.document.queryCommandState(command);
-		}catch(e){
-			//Squelch, occurs if editor is hidden on FF 3 (and maybe others.)
-			return false;
-		}
-	},
+		queryCommandState: function(command){
+			// summary:
+			//		Check the state of a given command and returns true or false.
+			// tags:
+			//		protected
 
-	queryCommandValue: function(command){
-		// summary:
-		//		Check the value of a given command. This matters most for
-		//		custom selections and complex values like font value setting.
-		// tags:
-		//		protected
-
-		if(this.disabled || !this._disabledOK){ return false; }
-		var r;
-		command = this._normalizeCommand(command);
-		if(has("ie") && command === "formatblock"){
-			r = this._native2LocalFormatNames[this.document.queryCommandValue(command)];
-		}else if(has("mozilla") && command === "hilitecolor"){
-			var oldValue;
+			if(this.disabled || !this._disabledOK){
+				return false;
+			}
+			command = this._normalizeCommand(command);
 			try{
-				oldValue = this.document.queryCommandValue("styleWithCSS");
+				return this.document.queryCommandState(command);
 			}catch(e){
-				oldValue = false;
+				//Squelch, occurs if editor is hidden on FF 3 (and maybe others.)
+				return false;
 			}
-			this.document.execCommand("styleWithCSS", false, true);
-			r = this.document.queryCommandValue(command);
-			this.document.execCommand("styleWithCSS", false, oldValue);
-		}else{
-			r = this.document.queryCommandValue(command);
-		}
-		return r;
-	},
+		},
 
-	// Misc.
+		queryCommandValue: function(command){
+			// summary:
+			//		Check the value of a given command. This matters most for
+			//		custom selections and complex values like font value setting.
+			// tags:
+			//		protected
 
-	_sCall: function(name, args){
-		// summary:
-		//		Run the named method of dijit._editor.selection over the
-		//		current editor instance's window, with the passed args.
-		// tags:
-		//		private
-		return win.withGlobal(this.window, name, selectionapi, args);
-	},
+			if(this.disabled || !this._disabledOK){
+				return false;
+			}
+			var r;
+			command = this._normalizeCommand(command);
+			if(has("ie") && command === "formatblock"){
+				r = this._native2LocalFormatNames[this.document.queryCommandValue(command)];
+			}else if(has("mozilla") && command === "hilitecolor"){
+				var oldValue;
+				try{
+					oldValue = this.document.queryCommandValue("styleWithCSS");
+				}catch(e){
+					oldValue = false;
+				}
+				this.document.execCommand("styleWithCSS", false, true);
+				r = this.document.queryCommandValue(command);
+				this.document.execCommand("styleWithCSS", false, oldValue);
+			}else{
+				r = this.document.queryCommandValue(command);
+			}
+			return r;
+		},
 
-	// FIXME: this is a TON of code duplication. Why?
+		// Misc.
 
-	placeCursorAtStart: function(){
-		// summary:
-		//		Place the cursor at the start of the editing area.
-		// tags:
-		//		private
+		_sCall: function(name, args){
+			// summary:
+			//		Deprecated, remove for 2.0.   New code should access this.selection directly.
+			//		Run the named method of dijit/selection over the
+			//		current editor instance's window, with the passed args.
+			// tags:
+			//		private deprecated
 
-		this.focus();
-
-		//see comments in placeCursorAtEnd
-		var isvalid=false;
-		if(has("mozilla")){
-			// TODO:  Is this branch even necessary?
-			var first=this.editNode.firstChild;
-			while(first){
-				if(first.nodeType === 3){
-					if(first.nodeValue.replace(/^\s+|\s+$/g, "").length>0){
-						isvalid=true;
-						this._sCall("selectElement", [ first ]);
-						break;
-					}
-				}else if(first.nodeType === 1){
-					isvalid=true;
-					var tg = first.tagName ? first.tagName.toLowerCase() : "";
-					// Collapse before childless tags.
-					if(/br|input|img|base|meta|area|basefont|hr|link/.test(tg)){
-						this._sCall("selectElement", [ first ]);
-					}else{
-						// Collapse inside tags with children.
-						this._sCall("selectElementChildren", [ first ]);
-					}
-					break;
-				}
-				first = first.nextSibling;
-			}
-		}else{
-			isvalid=true;
-			this._sCall("selectElementChildren", [ this.editNode ]);
-		}
-		if(isvalid){
-			this._sCall("collapse", [ true ]);
-		}
-	},
+			return this.selection[name].apply(this.selection, args);
+		},
 
-	placeCursorAtEnd: function(){
-		// summary:
-		//		Place the cursor at the end of the editing area.
-		// tags:
-		//		private
+		// FIXME: this is a TON of code duplication. Why?
+
+		placeCursorAtStart: function(){
+			// summary:
+			//		Place the cursor at the start of the editing area.
+			// tags:
+			//		private
 
-		this.focus();
-
-		//In mozilla, if last child is not a text node, we have to use
-		// selectElementChildren on this.editNode.lastChild otherwise the
-		// cursor would be placed at the end of the closing tag of
-		//this.editNode.lastChild
-		var isvalid=false;
-		if(has("mozilla")){
-			var last=this.editNode.lastChild;
-			while(last){
-				if(last.nodeType === 3){
-					if(last.nodeValue.replace(/^\s+|\s+$/g, "").length>0){
-						isvalid=true;
-						this._sCall("selectElement", [ last ]);
+			this.focus();
+
+			//see comments in placeCursorAtEnd
+			var isvalid = false;
+			if(has("mozilla")){
+				// TODO:  Is this branch even necessary?
+				var first = this.editNode.firstChild;
+				while(first){
+					if(first.nodeType === 3){
+						if(first.nodeValue.replace(/^\s+|\s+$/g, "").length > 0){
+							isvalid = true;
+							this.selection.selectElement(first);
+							break;
+						}
+					}else if(first.nodeType === 1){
+						isvalid = true;
+						var tg = first.tagName ? first.tagName.toLowerCase() : "";
+						// Collapse before childless tags.
+						if(/br|input|img|base|meta|area|basefont|hr|link/.test(tg)){
+							this.selection.selectElement(first);
+						}else{
+							// Collapse inside tags with children.
+							this.selection.selectElementChildren(first);
+						}
 						break;
 					}
-				}else if(last.nodeType === 1){
-					isvalid=true;
-					if(last.lastChild){
-						this._sCall("selectElement", [ last.lastChild ]);
-					}else{
-						this._sCall("selectElement", [ last ]);
-					}
-					break;
+					first = first.nextSibling;
 				}
-				last = last.previousSibling;
+			}else{
+				isvalid = true;
+				this.selection.selectElementChildren(this.editNode);
 			}
-		}else{
-			isvalid=true;
-			this._sCall("selectElementChildren", [ this.editNode ]);
-		}
-		if(isvalid){
-			this._sCall("collapse", [ false ]);
-		}
-	},
-
-	getValue: function(/*Boolean?*/ nonDestructive){
-		// summary:
-		//		Return the current content of the editing area (post filters
-		//		are applied).  Users should call get('value') instead.
-		//	nonDestructive:
-		//		defaults to false. Should the post-filtering be run over a copy
-		//		of the live DOM? Most users should pass "true" here unless they
-		//		*really* know that none of the installed filters are going to
-		//		mess up the editing session.
-		// tags:
-		//		private
-		if(this.textarea){
-			if(this.isClosed || !this.isLoaded){
-				return this.textarea.value;
+			if(isvalid){
+				this.selection.collapse(true);
 			}
-		}
+		},
 
-		return this._postFilterContent(null, nonDestructive);
-	},
-	_getValueAttr: function(){
-		// summary:
-		//		Hook to make attr("value") work
-		return this.getValue(true);
-	},
+		placeCursorAtEnd: function(){
+			// summary:
+			//		Place the cursor at the end of the editing area.
+			// tags:
+			//		private
 
-	setValue: function(/*String*/ html){
-		// summary:
-		//		This function sets the content. No undo history is preserved.
-		//		Users should use set('value', ...) instead.
-		// tags:
-		//		deprecated
-
-		// TODO: remove this and getValue() for 2.0, and move code to _setValueAttr()
+			this.focus();
 
-		if(!this.isLoaded){
-			// try again after the editor is finished loading
-			this.onLoadDeferred.addCallback(lang.hitch(this, function(){
-				this.setValue(html);
-			}));
-			return;
-		}
-		this._cursorToStart = true;
-		if(this.textarea && (this.isClosed || !this.isLoaded)){
-			this.textarea.value=html;
-		}else{
-			html = this._preFilterContent(html);
-			var node = this.isClosed ? this.domNode : this.editNode;
-			if(html && has("mozilla") && html.toLowerCase() === "<p></p>"){
-				html = "<p> </p>";	//  
-			}
-
-			// Use   to avoid webkit problems where editor is disabled until the user clicks it
-			if(!html && has("webkit")){
-				html = " ";	//  
+			//In mozilla, if last child is not a text node, we have to use
+			// selectElementChildren on this.editNode.lastChild otherwise the
+			// cursor would be placed at the end of the closing tag of
+			//this.editNode.lastChild
+			var isvalid = false;
+			if(has("mozilla")){
+				var last = this.editNode.lastChild;
+				while(last){
+					if(last.nodeType === 3){
+						if(last.nodeValue.replace(/^\s+|\s+$/g, "").length > 0){
+							isvalid = true;
+							this.selection.selectElement(last);
+							break;
+						}
+					}else if(last.nodeType === 1){
+						isvalid = true;
+						this.selection.selectElement(last.lastChild || last);
+						break;
+					}
+					last = last.previousSibling;
+				}
+			}else{
+				isvalid = true;
+				this.selection.selectElementChildren(this.editNode);
 			}
-			node.innerHTML = html;
-			this._preDomFilterContent(node);
-		}
-
-		this.onDisplayChanged();
-		this._set("value", this.getValue(true));
-	},
-
-	replaceValue: function(/*String*/ html){
-		// summary:
-		//		This function set the content while trying to maintain the undo stack
-		//		(now only works fine with Moz, this is identical to setValue in all
-		//		other browsers)
-		// tags:
-		//		protected
-
-		if(this.isClosed){
-			this.setValue(html);
-		}else if(this.window && this.window.getSelection && !has("mozilla")){ // Safari
-			// look ma! it's a totally f'd browser!
-			this.setValue(html);
-		}else if(this.window && this.window.getSelection){ // Moz
-			html = this._preFilterContent(html);
-			this.execCommand("selectall");
-			if(!html){
-				this._cursorToStart = true;
-				html = " ";	//  
+			if(isvalid){
+				this.selection.collapse(false);
 			}
-			this.execCommand("inserthtml", html);
-			this._preDomFilterContent(this.editNode);
-		}else if(this.document && this.document.selection){//IE
-			//In IE, when the first element is not a text node, say
-			//an <a> tag, when replacing the content of the editing
-			//area, the <a> tag will be around all the content
-			//so for now, use setValue for IE too
-			this.setValue(html);
-		}
-
-		this._set("value", this.getValue(true));
-	},
-
-	_preFilterContent: function(/*String*/ html){
-		// summary:
-		//		Filter the input before setting the content of the editing
-		//		area. DOM pre-filtering may happen after this
-		//		string-based filtering takes place but as of 1.2, this is not
-		//		guaranteed for operations such as the inserthtml command.
-		// tags:
-		//		private
-
-		var ec = html;
-		array.forEach(this.contentPreFilters, function(ef){ if(ef){ ec = ef(ec); } });
-		return ec;
-	},
-	_preDomFilterContent: function(/*DomNode*/ dom){
-		// summary:
-		//		filter the input's live DOM. All filter operations should be
-		//		considered to be "live" and operating on the DOM that the user
-		//		will be interacting with in their editing session.
-		// tags:
-		//		private
-		dom = dom || this.editNode;
-		array.forEach(this.contentDomPreFilters, function(ef){
-			if(ef && lang.isFunction(ef)){
-				ef(dom);
+		},
+
+		getValue: function(/*Boolean?*/ nonDestructive){
+			// summary:
+			//		Return the current content of the editing area (post filters
+			//		are applied).  Users should call get('value') instead.
+			// nonDestructive:
+			//		defaults to false. Should the post-filtering be run over a copy
+			//		of the live DOM? Most users should pass "true" here unless they
+			//		*really* know that none of the installed filters are going to
+			//		mess up the editing session.
+			// tags:
+			//		private
+			if(this.textarea){
+				if(this.isClosed || !this.isLoaded){
+					return this.textarea.value;
+				}
 			}
-		}, this);
-	},
 
-	_postFilterContent: function(
-		/*DomNode|DomNode[]|String?*/ dom,
-		/*Boolean?*/ nonDestructive){
-		// summary:
-		//		filter the output after getting the content of the editing area
-		//
-		// description:
-		//		post-filtering allows plug-ins and users to specify any number
-		//		of transforms over the editor's content, enabling many common
-		//		use-cases such as transforming absolute to relative URLs (and
-		//		vice-versa), ensuring conformance with a particular DTD, etc.
-		//		The filters are registered in the contentDomPostFilters and
-		//		contentPostFilters arrays. Each item in the
-		//		contentDomPostFilters array is a function which takes a DOM
-		//		Node or array of nodes as its only argument and returns the
-		//		same. It is then passed down the chain for further filtering.
-		//		The contentPostFilters array behaves the same way, except each
-		//		member operates on strings. Together, the DOM and string-based
-		//		filtering allow the full range of post-processing that should
-		//		be necessaray to enable even the most agressive of post-editing
-		//		conversions to take place.
-		//
-		//		If nonDestructive is set to "true", the nodes are cloned before
-		//		filtering proceeds to avoid potentially destructive transforms
-		//		to the content which may still needed to be edited further.
-		//		Once DOM filtering has taken place, the serialized version of
-		//		the DOM which is passed is run through each of the
-		//		contentPostFilters functions.
-		//
-		//	dom:
-		//		a node, set of nodes, which to filter using each of the current
-		//		members of the contentDomPostFilters and contentPostFilters arrays.
-		//
-		//	nonDestructive:
-		//		defaults to "false". If true, ensures that filtering happens on
-		//		a clone of the passed-in content and not the actual node
-		//		itself.
-		//
-		// tags:
-		//		private
+			return this._postFilterContent(null, nonDestructive);
+		},
+		_getValueAttr: function(){
+			// summary:
+			//		Hook to make attr("value") work
+			return this.getValue(true);
+		},
+
+		setValue: function(/*String*/ html){
+			// summary:
+			//		This function sets the content. No undo history is preserved.
+			//		Users should use set('value', ...) instead.
+			// tags:
+			//		deprecated
+
+			// TODO: remove this and getValue() for 2.0, and move code to _setValueAttr()
+
+			if(!this.isLoaded){
+				// try again after the editor is finished loading
+				this.onLoadDeferred.then(lang.hitch(this, function(){
+					this.setValue(html);
+				}));
+				return;
+			}
+			this._cursorToStart = true;
+			if(this.textarea && (this.isClosed || !this.isLoaded)){
+				this.textarea.value = html;
+			}else{
+				html = this._preFilterContent(html);
+				var node = this.isClosed ? this.domNode : this.editNode;
+				if(html && has("mozilla") && html.toLowerCase() === "<p></p>"){
+					html = "<p> </p>";	//  
+				}
 
-		var ec;
-		if(!lang.isString(dom)){
-			dom = dom || this.editNode;
-			if(this.contentDomPostFilters.length){
-				if(nonDestructive){
-					dom = lang.clone(dom);
+				// Use   to avoid webkit problems where editor is disabled until the user clicks it
+				if(!html && has("webkit")){
+					html = " ";	//  
 				}
-				array.forEach(this.contentDomPostFilters, function(ef){
-					dom = ef(dom);
-				});
+				node.innerHTML = html;
+				this._preDomFilterContent(node);
 			}
-			ec = htmlapi.getChildrenHtml(dom);
-		}else{
-			ec = dom;
-		}
 
-		if(!lang.trim(ec.replace(/^\xA0\xA0*/, '').replace(/\xA0\xA0*$/, '')).length){
-			ec = "";
-		}
-
-		//	if(has("ie")){
-		//		//removing appended <P> </P> for IE
-		//		ec = ec.replace(/(?:<p> </p>[\n\r]*)+$/i,"");
-		//	}
-		array.forEach(this.contentPostFilters, function(ef){
-			ec = ef(ec);
-		});
-
-		return ec;
-	},
+			this.onDisplayChanged();
+			this._set("value", this.getValue(true));
+		},
 
-	_saveContent: function(){
-		// summary:
-		//		Saves the content in an onunload event if the editor has not been closed
-		// tags:
-		//		private
+		replaceValue: function(/*String*/ html){
+			// summary:
+			//		This function set the content while trying to maintain the undo stack
+			//		(now only works fine with Moz, this is identical to setValue in all
+			//		other browsers)
+			// tags:
+			//		protected
 
-		var saveTextarea = dom.byId(dijit._scopeName + "._editor.RichText.value");
-		if(saveTextarea){
-			if(saveTextarea.value){
-				saveTextarea.value += this._SEPARATOR;
+			if(this.isClosed){
+				this.setValue(html);
+			}else if(this.window && this.window.getSelection && !has("mozilla")){ // Safari
+				// look ma! it's a totally f'd browser!
+				this.setValue(html);
+			}else if(this.window && this.window.getSelection){ // Moz
+				html = this._preFilterContent(html);
+				this.execCommand("selectall");
+				if(!html){
+					this._cursorToStart = true;
+					html = " ";	//  
+				}
+				this.execCommand("inserthtml", html);
+				this._preDomFilterContent(this.editNode);
+			}else if(this.document && this.document.selection){//IE
+				//In IE, when the first element is not a text node, say
+				//an <a> tag, when replacing the content of the editing
+				//area, the <a> tag will be around all the content
+				//so for now, use setValue for IE too
+				this.setValue(html);
 			}
-			saveTextarea.value += this.name + this._NAME_CONTENT_SEP + this.getValue(true);
-		}
-	},
-
-
-	escapeXml: function(/*String*/ str, /*Boolean*/ noSingleQuotes){
-		// summary:
-		//		Adds escape sequences for special characters in XML.
-		//		Optionally skips escapes for single quotes
-		// tags:
-		//		private
-
-		str = str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """);
-		if(!noSingleQuotes){
-			str = str.replace(/'/gm, "'");
-		}
-		return str; // string
-	},
 
-	getNodeHtml: function(/* DomNode */ node){
-		// summary:
-		//		Deprecated.   Use dijit/_editor/html::_getNodeHtml() instead.
-		// tags:
-		//		deprecated
-		kernel.deprecated('dijit.Editor::getNodeHtml is deprecated','use dijit/_editor/html::getNodeHtml instead', 2);
-		return htmlapi.getNodeHtml(node); // String
-	},
-
-	getNodeChildrenHtml: function(/* DomNode */ dom){
-		// summary:
-		//		Deprecated.   Use dijit/_editor/html::getChildrenHtml() instead.
-		// tags:
-		//		deprecated
-		kernel.deprecated('dijit.Editor::getNodeChildrenHtml is deprecated','use dijit/_editor/html::getChildrenHtml instead', 2);
-		return htmlapi.getChildrenHtml(dom);
-	},
-
-	close: function(/*Boolean?*/ save){
-		// summary:
-		//		Kills the editor and optionally writes back the modified contents to the
-		//		element from which it originated.
-		// save:
-		//		Whether or not to save the changes. If false, the changes are discarded.
-		// tags:
-		//		private
-
-		if(this.isClosed){ return; }
-
-		if(!arguments.length){ save = true; }
-		if(save){
 			this._set("value", this.getValue(true));
-		}
-
-		// line height is squashed for iframes
-		// FIXME: why was this here? if(this.iframe){ this.domNode.style.lineHeight = null; }
-
-		if(this.interval){ clearInterval(this.interval); }
-
-		if(this._webkitListener){
-			//Cleaup of WebKit fix: #9532
-			this.disconnect(this._webkitListener);
-			delete this._webkitListener;
-		}
-
-		// Guard against memory leaks on IE (see #9268)
-		if(has("ie")){
-			 this.iframe.onfocus = null;
-		}
-		this.iframe._loadFunc = null;
-
-		if(this._iframeRegHandle){
-			this._iframeRegHandle.remove();
-			delete this._iframeRegHandle;
-		}
-
-		if(this.textarea){
-			var s = this.textarea.style;
-			s.position = "";
-			s.left = s.top = "";
-			if(has("ie")){
-				s.overflow = this.__overflow;
-				this.__overflow = null;
-			}
-			this.textarea.value = this.value;
-			domConstruct.destroy(this.domNode);
-			this.domNode = this.textarea;
-		}else{
-			// Note that this destroys the iframe
-			this.domNode.innerHTML = this.value;
-		}
-		delete this.iframe;
-
-		domClass.remove(this.domNode, this.baseClass);
-		this.isClosed = true;
-		this.isLoaded = false;
-
-		delete this.editNode;
-		delete this.focusNode;
-
-		if(this.window && this.window._frameElement){
-			this.window._frameElement = null;
-		}
-
-		this.window = null;
-		this.document = null;
-		this.editingArea = null;
-		this.editorObject = null;
-	},
-
-	destroy: function(){
-		if(!this.isClosed){ this.close(false); }
-		if(this._updateTimer){
-			clearTimeout(this._updateTimer);
-		}
-		this.inherited(arguments);
-		if(RichText._globalSaveHandler){
-			delete RichText._globalSaveHandler[this.id];
-		}
-	},
-
-	_removeMozBogus: function(/* String */ html){
-		// summary:
-		//		Post filter to remove unwanted HTML attributes generated by mozilla
-		// tags:
-		//		private
-		return html.replace(/\stype="_moz"/gi, '').replace(/\s_moz_dirty=""/gi, '').replace(/_moz_resizing="(true|false)"/gi,''); // String
-	},
-	_removeWebkitBogus: function(/* String */ html){
-		// summary:
-		//		Post filter to remove unwanted HTML attributes generated by webkit
-		// tags:
-		//		private
-		html = html.replace(/\sclass="webkit-block-placeholder"/gi, '');
-		html = html.replace(/\sclass="apple-style-span"/gi, '');
-		// For some reason copy/paste sometime adds extra meta tags for charset on
-		// webkit (chrome) on mac.They need to be removed.  See: #12007"
-		html = html.replace(/<meta charset=\"utf-8\" \/>/gi, '');
-		return html; // String
-	},
-	_normalizeFontStyle: function(/* String */ html){
-		// summary:
-		//		Convert 'strong' and 'em' to 'b' and 'i'.
-		// description:
-		//		Moz can not handle strong/em tags correctly, so to help
-		//		mozilla and also to normalize output, convert them to 'b' and 'i'.
-		//
-		//		Note the IE generates 'strong' and 'em' rather than 'b' and 'i'
-		// tags:
-		//		private
-		return html.replace(/<(\/)?strong([ \>])/gi, '<$1b$2')
-			.replace(/<(\/)?em([ \>])/gi, '<$1i$2' ); // String
-	},
-
-	_preFixUrlAttributes: function(/* String */ html){
-		// summary:
-		//		Pre-filter to do fixing to href attributes on <a> and <img> tags
-		// tags:
-		//		private
-		return html.replace(/(?:(<a(?=\s).*?\shref=)("|')(.*?)\2)|(?:(<a\s.*?href=)([^"'][^ >]+))/gi,
-				'$1$4$2$3$5$2 _djrealurl=$2$3$5$2')
-			.replace(/(?:(<img(?=\s).*?\ssrc=)("|')(.*?)\2)|(?:(<img\s.*?src=)([^"'][^ >]+))/gi,
-				'$1$4$2$3$5$2 _djrealurl=$2$3$5$2'); // String
-	},
-
-	/*****************************************************************************
-		The following functions implement HTML manipulation commands for various
-		browser/contentEditable implementations.  The goal of them is to enforce
-		standard behaviors of them.
-	******************************************************************************/
-
-	/*** queryCommandEnabled implementations ***/
-
-	_browserQueryCommandEnabled: function(command){
-		// summary:
-		//		Implementation to call to the native queryCommandEnabled of the browser.
-		// command:
-		//		The command to check.
-		// tags:
-		//		protected
-		if(!command) { return false; }
-		var elem = has("ie") ? this.document.selection.createRange() : this.document;
-		try{
-			return elem.queryCommandEnabled(command);
-		}catch(e){
-			return false;
-		}
-	},
-
-	_createlinkEnabledImpl: function(/*===== argument =====*/){
-		// summary:
-		//		This function implements the test for if the create link
-		//		command should be enabled or not.
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		var enabled = true;
-		if(has("opera")){
-			var sel = this.window.getSelection();
-			if(sel.isCollapsed){
-				enabled = true;
+		},
+
+		_preFilterContent: function(/*String*/ html){
+			// summary:
+			//		Filter the input before setting the content of the editing
+			//		area. DOM pre-filtering may happen after this
+			//		string-based filtering takes place but as of 1.2, this is not
+			//		guaranteed for operations such as the inserthtml command.
+			// tags:
+			//		private
+
+			var ec = html;
+			array.forEach(this.contentPreFilters, function(ef){
+				if(ef){
+					ec = ef(ec);
+				}
+			});
+			return ec;
+		},
+		_preDomFilterContent: function(/*DomNode*/ dom){
+			// summary:
+			//		filter the input's live DOM. All filter operations should be
+			//		considered to be "live" and operating on the DOM that the user
+			//		will be interacting with in their editing session.
+			// tags:
+			//		private
+			dom = dom || this.editNode;
+			array.forEach(this.contentDomPreFilters, function(ef){
+				if(ef && lang.isFunction(ef)){
+					ef(dom);
+				}
+			}, this);
+		},
+
+		_postFilterContent: function(/*DomNode|DomNode[]|String?*/ dom, /*Boolean?*/ nonDestructive){
+			// summary:
+			//		filter the output after getting the content of the editing area
+			//
+			// description:
+			//		post-filtering allows plug-ins and users to specify any number
+			//		of transforms over the editor's content, enabling many common
+			//		use-cases such as transforming absolute to relative URLs (and
+			//		vice-versa), ensuring conformance with a particular DTD, etc.
+			//		The filters are registered in the contentDomPostFilters and
+			//		contentPostFilters arrays. Each item in the
+			//		contentDomPostFilters array is a function which takes a DOM
+			//		Node or array of nodes as its only argument and returns the
+			//		same. It is then passed down the chain for further filtering.
+			//		The contentPostFilters array behaves the same way, except each
+			//		member operates on strings. Together, the DOM and string-based
+			//		filtering allow the full range of post-processing that should
+			//		be necessaray to enable even the most agressive of post-editing
+			//		conversions to take place.
+			//
+			//		If nonDestructive is set to "true", the nodes are cloned before
+			//		filtering proceeds to avoid potentially destructive transforms
+			//		to the content which may still needed to be edited further.
+			//		Once DOM filtering has taken place, the serialized version of
+			//		the DOM which is passed is run through each of the
+			//		contentPostFilters functions.
+			//
+			// dom:
+			//		a node, set of nodes, which to filter using each of the current
+			//		members of the contentDomPostFilters and contentPostFilters arrays.
+			//
+			// nonDestructive:
+			//		defaults to "false". If true, ensures that filtering happens on
+			//		a clone of the passed-in content and not the actual node
+			//		itself.
+			//
+			// tags:
+			//		private
+
+			var ec;
+			if(!lang.isString(dom)){
+				dom = dom || this.editNode;
+				if(this.contentDomPostFilters.length){
+					if(nonDestructive){
+						dom = lang.clone(dom);
+					}
+					array.forEach(this.contentDomPostFilters, function(ef){
+						dom = ef(dom);
+					});
+				}
+				ec = htmlapi.getChildrenHtml(dom);
 			}else{
-				enabled = this.document.queryCommandEnabled("createlink");
+				ec = dom;
 			}
-		}else{
-			enabled = this._browserQueryCommandEnabled("createlink");
-		}
-		return enabled;
-	},
-
-	_unlinkEnabledImpl: function(/*===== argument =====*/){
-		// summary:
-		//		This function implements the test for if the unlink
-		//		command should be enabled or not.
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		var enabled = true;
-		if(has("mozilla") || has("webkit")){
-			enabled = this._sCall("hasAncestorElement", ["a"]);
-		}else{
-			enabled = this._browserQueryCommandEnabled("unlink");
-		}
-		return enabled;
-	},
-
-	_inserttableEnabledImpl: function(/*===== argument =====*/){
-		// summary:
-		//		This function implements the test for if the inserttable
-		//		command should be enabled or not.
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		var enabled = true;
-		if(has("mozilla") || has("webkit")){
-			enabled = true;
-		}else{
-			enabled = this._browserQueryCommandEnabled("inserttable");
-		}
-		return enabled;
-	},
 
-	_cutEnabledImpl: function(/*===== argument =====*/){
-		// summary:
-		//		This function implements the test for if the cut
-		//		command should be enabled or not.
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		var enabled = true;
-		if(has("webkit")){
-			// WebKit deems clipboard activity as a security threat and natively would return false
-			var sel = this.window.getSelection();
-			if(sel){ sel = sel.toString(); }
-			enabled = !!sel;
-		}else{
-			enabled = this._browserQueryCommandEnabled("cut");
-		}
-		return enabled;
-	},
-
-	_copyEnabledImpl: function(/*===== argument =====*/){
-		// summary:
-		//		This function implements the test for if the copy
-		//		command should be enabled or not.
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		var enabled = true;
-		if(has("webkit")){
-			// WebKit deems clipboard activity as a security threat and natively would return false
-			var sel = this.window.getSelection();
-			if(sel){ sel = sel.toString(); }
-			enabled = !!sel;
-		}else{
-			enabled = this._browserQueryCommandEnabled("copy");
-		}
-		return enabled;
-	},
-
-	_pasteEnabledImpl: function(/*===== argument =====*/){
-		// summary:c
-		//		This function implements the test for if the paste
-		//		command should be enabled or not.
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		var enabled = true;
-		if(has("webkit")){
-			return true;
-		}else{
-			enabled = this._browserQueryCommandEnabled("paste");
-		}
-		return enabled;
-	},
+			if(!lang.trim(ec.replace(/^\xA0\xA0*/, '').replace(/\xA0\xA0*$/, '')).length){
+				ec = "";
+			}
 
-	/*** execCommand implementations ***/
+			//	if(has("ie")){
+			//		//removing appended <P> </P> for IE
+			//		ec = ec.replace(/(?:<p> </p>[\n\r]*)+$/i,"");
+			//	}
+			array.forEach(this.contentPostFilters, function(ef){
+				ec = ef(ec);
+			});
 
-	_inserthorizontalruleImpl: function(argument){
-		// summary:
-		//		This function implements the insertion of HTML 'HR' tags.
-		//		into a point on the page.  IE doesn't to it right, so
-		//		we have to use an alternate form
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		if(has("ie")){
-			return this._inserthtmlImpl("<hr>");
-		}
-		return this.document.execCommand("inserthorizontalrule", false, argument);
-	},
+			return ec;
+		},
 
-	_unlinkImpl: function(argument){
-		// summary:
-		//		This function implements the unlink of an 'a' tag.
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		if((this.queryCommandEnabled("unlink")) && (has("mozilla") || has("webkit"))){
-			var a = this._sCall("getAncestorElement", [ "a" ]);
-			this._sCall("selectElement", [ a ]);
-			return this.document.execCommand("unlink", false, null);
-		}
-		return this.document.execCommand("unlink", false, argument);
-	},
+		_saveContent: function(){
+			// summary:
+			//		Saves the content in an onunload event if the editor has not been closed
+			// tags:
+			//		private
 
-	_hilitecolorImpl: function(argument){
-		// summary:
-		//		This function implements the hilitecolor command
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		var returnValue;
-		var isApplied = this._handleTextColorOrProperties("hilitecolor", argument);
-		if(!isApplied){
-			if(has("mozilla")){
-				// mozilla doesn't support hilitecolor properly when useCSS is
-				// set to false (bugzilla #279330)
-				this.document.execCommand("styleWithCSS", false, true);
-				console.log("Executing color command.");
-				returnValue = this.document.execCommand("hilitecolor", false, argument);
-				this.document.execCommand("styleWithCSS", false, false);
-			}else{
-				returnValue = this.document.execCommand("hilitecolor", false, argument);
+			var saveTextarea = dom.byId(dijit._scopeName + "._editor.RichText.value");
+			if(saveTextarea){
+				if(saveTextarea.value){
+					saveTextarea.value += this._SEPARATOR;
+				}
+				saveTextarea.value += this.name + this._NAME_CONTENT_SEP + this.getValue(true);
 			}
-		}
-		return returnValue;
-	},
+		},
 
-	_backcolorImpl: function(argument){
-		// summary:
-		//		This function implements the backcolor command
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		if(has("ie")){
-			// Tested under IE 6 XP2, no problem here, comment out
-			// IE weirdly collapses ranges when we exec these commands, so prevent it
-			//	var tr = this.document.selection.createRange();
-			argument = argument ? argument : null;
-		}
-		var isApplied = this._handleTextColorOrProperties("backcolor", argument);
-		if(!isApplied){
-			isApplied = this.document.execCommand("backcolor", false, argument);
-		}
-		return isApplied;
-	},
 
-	_forecolorImpl: function(argument){
-		// summary:
-		//		This function implements the forecolor command
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		if(has("ie")){
-			// Tested under IE 6 XP2, no problem here, comment out
-			// IE weirdly collapses ranges when we exec these commands, so prevent it
-			//	var tr = this.document.selection.createRange();
-			argument = argument? argument : null;
-		}
-		var isApplied = false;
-		isApplied = this._handleTextColorOrProperties("forecolor", argument);
-		if(!isApplied){
-			isApplied = this.document.execCommand("forecolor", false, argument);
-		}
-		return isApplied;
-	},
+		escapeXml: function(/*String*/ str, /*Boolean*/ noSingleQuotes){
+			// summary:
+			//		Adds escape sequences for special characters in XML.
+			//		Optionally skips escapes for single quotes
+			// tags:
+			//		private
 
-	_inserthtmlImpl: function(argument){
-		// summary:
-		//		This function implements the insertion of HTML content into
-		//		a point on the page.
-		// argument:
-		//		The content to insert, if any.
-		// tags:
-		//		protected
-		argument = this._preFilterContent(argument);
-		var rv = true;
-		if(has("ie")){
-			var insertRange = this.document.selection.createRange();
-			if(this.document.selection.type.toUpperCase() === 'CONTROL'){
-				var n=insertRange.item(0);
-				while(insertRange.length){
-					insertRange.remove(insertRange.item(0));
-				}
-				n.outerHTML=argument;
-			}else{
-				insertRange.pasteHTML(argument);
-			}
-			insertRange.select();
-			//insertRange.collapse(true);
-		}else if(has("mozilla") && !argument.length){
-			//mozilla can not inserthtml an empty html to delete current selection
-			//so we delete the selection instead in this case
-			this._sCall("remove"); // FIXME
-		}else{
-			rv = this.document.execCommand("inserthtml", false, argument);
-		}
-		return rv;
-	},
+			str = str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """);
+			if(!noSingleQuotes){
+				str = str.replace(/'/gm, "'");
+			}
+			return str; // string
+		},
+
+		getNodeHtml: function(/* DomNode */ node){
+			// summary:
+			//		Deprecated.   Use dijit/_editor/html::_getNodeHtml() instead.
+			// tags:
+			//		deprecated
+			kernel.deprecated('dijit.Editor::getNodeHtml is deprecated', 'use dijit/_editor/html::getNodeHtml instead', 2);
+			return htmlapi.getNodeHtml(node); // String
+		},
+
+		getNodeChildrenHtml: function(/* DomNode */ dom){
+			// summary:
+			//		Deprecated.   Use dijit/_editor/html::getChildrenHtml() instead.
+			// tags:
+			//		deprecated
+			kernel.deprecated('dijit.Editor::getNodeChildrenHtml is deprecated', 'use dijit/_editor/html::getChildrenHtml instead', 2);
+			return htmlapi.getChildrenHtml(dom);
+		},
+
+		close: function(/*Boolean?*/ save){
+			// summary:
+			//		Kills the editor and optionally writes back the modified contents to the
+			//		element from which it originated.
+			// save:
+			//		Whether or not to save the changes. If false, the changes are discarded.
+			// tags:
+			//		private
+
+			if(this.isClosed){
+				return;
+			}
 
-	_boldImpl: function(argument){
-		// summary:
-		//		This function implements an over-ride of the bold command.
-		// argument:
-		//		Not used, operates by selection.
-		// tags:
-		//		protected
-		var applied = false;
-		if(has("ie")){
-			this._adaptIESelection();		
-			applied = this._adaptIEFormatAreaAndExec("bold");
-		}
-		if(!applied){
-			applied = this.document.execCommand("bold", false, argument);
-		}
-		return applied;
-	},
+			if(!arguments.length){
+				save = true;
+			}
+			if(save){
+				this._set("value", this.getValue(true));
+			}
 
-	_italicImpl: function(argument){
-		// summary:
-		//		This function implements an over-ride of the italic command.
-		// argument:
-		//		Not used, operates by selection.
-		// tags:
-		//		protected
-		var applied = false;
-		if(has("ie")){
-			this._adaptIESelection();			
-			applied = this._adaptIEFormatAreaAndExec("italic");
-		}
-		if(!applied){
-			applied = this.document.execCommand("italic", false, argument);
-		}
-		return applied;
-	},
+			// line height is squashed for iframes
+			// FIXME: why was this here? if(this.iframe){ this.domNode.style.lineHeight = null; }
 
-	_underlineImpl: function(argument){
-		// summary:
-		//		This function implements an over-ride of the underline command.
-		// argument:
-		//		Not used, operates by selection.
-		// tags:
-		//		protected
-		var applied = false;
-		if(has("ie")){
-			this._adaptIESelection();			
-			applied = this._adaptIEFormatAreaAndExec("underline");
-		}
-		if(!applied){
-			applied = this.document.execCommand("underline", false, argument);
-		}
-		return applied;
-	},
+			if(this.interval){
+				clearInterval(this.interval);
+			}
 
-	_strikethroughImpl: function(argument){
-		// summary:
-		//		This function implements an over-ride of the strikethrough command.
-		// argument:
-		//		Not used, operates by selection.
-		// tags:
-		//		protected
-		var applied = false;
-		if(has("ie")){
-			this._adaptIESelection();			
-			applied = this._adaptIEFormatAreaAndExec("strikethrough");
-		}
-		if(!applied){
-			applied = this.document.execCommand("strikethrough", false, argument);
-		}
-		return applied;
-	},
+			if(this._webkitListener){
+				// Cleanup of WebKit fix: #9532
+				this._webkitListener.remove();
+				delete this._webkitListener;
+			}
 
-	_superscriptImpl: function(argument){
-		// summary:
-		//		This function implements an over-ride of the superscript command.
-		// argument:
-		//		Not used, operates by selection.
-		// tags:
-		//		protected
-		var applied = false;
-		if(has("ie")){
-			this._adaptIESelection();			
-			applied = this._adaptIEFormatAreaAndExec("superscript");
-		}
-		if(!applied){
-			applied = this.document.execCommand("superscript", false, argument);
-		}
-		return applied;
-	},
+			// Guard against memory leaks on IE (see #9268)
+			if(has("ie")){
+				this.iframe.onfocus = null;
+			}
+			this.iframe._loadFunc = null;
 
-	_subscriptImpl: function(argument){
-		// summary:
-		//		This function implements an over-ride of the superscript command.
-		// argument:
-		//		Not used, operates by selection.
-		// tags:
-		//		protected
-		var applied = false;
-		if(has("ie")){
-			this._adaptIESelection();			
-			applied = this._adaptIEFormatAreaAndExec("subscript");
-			
-		}
-		if(!applied){
-			applied = this.document.execCommand("subscript", false, argument);
-		}
-		return applied;
-	},
-	
-	_fontnameImpl: function(argument){
-		// summary:
-		//		This function implements the fontname command
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		var isApplied;
-		if(has("ie")){
-			isApplied = this._handleTextColorOrProperties("fontname", argument);
-		}
-		if(!isApplied){
-			isApplied = this.document.execCommand("fontname", false, argument);
-		}
-		return isApplied;
-	},
+			if(this._iframeRegHandle){
+				this._iframeRegHandle.remove();
+				delete this._iframeRegHandle;
+			}
 
-	_fontsizeImpl: function(argument){
-		// summary:
-		//		This function implements the fontsize command
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		var isApplied;
-		if(has("ie")){
-			isApplied = this._handleTextColorOrProperties("fontsize", argument);
-		}
-		if(!isApplied){
-			isApplied = this.document.execCommand("fontsize", false, argument);
-		}
-		return isApplied;
-	},
-	
-	_insertorderedlistImpl: function(argument){
-		// summary:
-		//		This function implements the insertorderedlist command
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		var applied = false;
-		if(has("ie")){
-			applied = this._adaptIEList("insertorderedlist", argument);
-		}
-		if(!applied){
-			applied = this.document.execCommand("insertorderedlist", false, argument);
-		}
-		return applied;
-	},
-	
-	_insertunorderedlistImpl: function(argument){
-		// summary:
-		//		This function implements the insertunorderedlist command
-		// argument:
-		//		arguments to the exec command, if any.
-		// tags:
-		//		protected
-		var applied = false;
-		if(has("ie")){
-			applied = this._adaptIEList("insertunorderedlist", argument);
-		}
-		if(!applied){
-			applied = this.document.execCommand("insertunorderedlist", false, argument);
-		}
-		return applied;
-	},
-	
-	getHeaderHeight: function(){
-		// summary:
-		//		A function for obtaining the height of the header node
-		return this._getNodeChildrenHeight(this.header); // Number
-	},
+			if(this.textarea){
+				var s = this.textarea.style;
+				s.position = "";
+				s.left = s.top = "";
+				if(has("ie")){
+					s.overflow = this.__overflow;
+					this.__overflow = null;
+				}
+				this.textarea.value = this.value;
+				domConstruct.destroy(this.domNode);
+				this.domNode = this.textarea;
+			}else{
+				// Note that this destroys the iframe
+				this.domNode.innerHTML = this.value;
+			}
+			delete this.iframe;
 
-	getFooterHeight: function(){
-		// summary:
-		//		A function for obtaining the height of the footer node
-		return this._getNodeChildrenHeight(this.footer); // Number
-	},
+			domClass.remove(this.domNode, this.baseClass);
+			this.isClosed = true;
+			this.isLoaded = false;
 
-	_getNodeChildrenHeight: function(node){
-		// summary:
-		//		An internal function for computing the cumulative height of all child nodes of 'node'
-		// node:
-		//		The node to process the children of;
-		var h = 0;
-		if(node && node.childNodes){
-			// IE didn't compute it right when position was obtained on the node directly is some cases,
-			// so we have to walk over all the children manually.
-			var i;
-			for(i = 0; i < node.childNodes.length; i++){
-				var size = domGeometry.position(node.childNodes[i]);
-				h += size.h;
+			delete this.editNode;
+			delete this.focusNode;
+
+			if(this.window && this.window._frameElement){
+				this.window._frameElement = null;
 			}
-		}
-		return h; // Number
-	},
 
-	_isNodeEmpty: function(node, startOffset){
-		// summary:
-		//		Function to test if a node is devoid of real content.
-		// node:
-		//		The node to check.
-		// tags:
-		//		private.
-		if(node.nodeType === 1/*element*/){
-			if(node.childNodes.length > 0){
-				return this._isNodeEmpty(node.childNodes[0], startOffset);
-	}
-			return true;
-		}else if(node.nodeType === 3/*text*/){
-			return (node.nodeValue.substring(startOffset) === "");
-		}
-		return false;
-	},
+			this.window = null;
+			this.document = null;
+			this.editingArea = null;
+			this.editorObject = null;
+		},
 
-	_removeStartingRangeFromRange: function(node, range){
-		// summary:
-		//		Function to adjust selection range by removing the current
-		//		start node.
-		// node:
-		//		The node to remove from the starting range.
-		// range:
-		//		The range to adapt.
-		// tags:
-		//		private
-		if(node.nextSibling){
-			range.setStart(node.nextSibling,0);
-		}else{
-			var parent = node.parentNode;
-			while(parent && parent.nextSibling == null){
-				//move up the tree until we find a parent that has another node, that node will be the next node
-				parent = parent.parentNode;
+		destroy: function(){
+			if(!this.isClosed){
+				this.close(false);
 			}
-			if(parent){
-				range.setStart(parent.nextSibling,0);
+			if(this._updateTimer){
+				this._updateTimer.remove();
 			}
-		}
-		return range;
-	},
-
-	_adaptIESelection: function(){
-		// summary:
-		//		Function to adapt the IE range by removing leading 'newlines'
-		//		Needed to fix issue with bold/italics/underline not working if
-		//		range included leading 'newlines'.
-		//		In IE, if a user starts a selection at the very end of a line,
-		//		then the native browser commands will fail to execute correctly.
-		//		To work around the issue,  we can remove all empty nodes from
-		//		the start of the range selection.
-		var selection = rangeapi.getSelection(this.window);
-		if(selection && selection.rangeCount && !selection.isCollapsed){
-			var range = selection.getRangeAt(0);
-			var firstNode = range.startContainer;
-			var startOffset = range.startOffset;
-
-			while(firstNode.nodeType === 3/*text*/ && startOffset >= firstNode.length && firstNode.nextSibling){
-				//traverse the text nodes until we get to the one that is actually highlighted
-				startOffset = startOffset - firstNode.length;
-				firstNode = firstNode.nextSibling;
-			}
-
-			//Remove the starting ranges until the range does not start with an empty node.
-			var lastNode=null;
-			while(this._isNodeEmpty(firstNode, startOffset) && firstNode !== lastNode){
-				lastNode =firstNode; //this will break the loop in case we can't find the next sibling
-				range = this._removeStartingRangeFromRange(firstNode, range); //move the start container to the next node in the range
-				firstNode = range.startContainer;
-				startOffset = 0; //start at the beginning of the new starting range
-			}
-			selection.removeAllRanges();// this will work as long as users cannot select multiple ranges. I have not been able to do that in the editor.
-			selection.addRange(range);
-		}
-	},
-	
-	_adaptIEFormatAreaAndExec: function(command){
-		// summary:
-		//		Function to handle IE's quirkiness regarding how it handles
-		//		format commands on a word.  This involves a lit of node splitting
-		//		and format cloning.
-		// command:
-		//		The format command, needed to check if the desired
-		//		command is true or not.
-		var selection = rangeapi.getSelection(this.window);
-		var doc = this.document;
-		var rs, ret, range, txt, startNode, endNode, breaker, sNode;
-		if(command && selection && selection.isCollapsed){
-			var isApplied = this.queryCommandValue(command);
-			if(isApplied){
-				
-				// We have to split backwards until we hit the format
-				var nNames = this._tagNamesForCommand(command);
-				range = selection.getRangeAt(0);
-				var fs = range.startContainer;
-				if(fs.nodeType === 3){
-					var offset = range.endOffset;
-					if(fs.length < offset){
-						//We are not looking from the right node, try to locate the correct one
-						ret = this._adjustNodeAndOffset(rs, offset);
-						fs = ret.node;
-						offset = ret.offset;
-					}
-				}									
-				var topNode;
-				while(fs && fs !== this.editNode){
-					// We have to walk back and see if this is still a format or not.
-					// Hm, how do I do this?
-					var tName = fs.tagName? fs.tagName.toLowerCase() : "";
-					if(array.indexOf(nNames, tName) > -1){
-						topNode = fs;
-						break;
+			this.inherited(arguments);
+			if(RichText._globalSaveHandler){
+				delete RichText._globalSaveHandler[this.id];
+			}
+		},
+
+		_removeMozBogus: function(/* String */ html){
+			// summary:
+			//		Post filter to remove unwanted HTML attributes generated by mozilla
+			// tags:
+			//		private
+			return html.replace(/\stype="_moz"/gi, '').replace(/\s_moz_dirty=""/gi, '').replace(/_moz_resizing="(true|false)"/gi, ''); // String
+		},
+		_removeWebkitBogus: function(/* String */ html){
+			// summary:
+			//		Post filter to remove unwanted HTML attributes generated by webkit
+			// tags:
+			//		private
+			html = html.replace(/\sclass="webkit-block-placeholder"/gi, '');
+			html = html.replace(/\sclass="apple-style-span"/gi, '');
+			// For some reason copy/paste sometime adds extra meta tags for charset on
+			// webkit (chrome) on mac.They need to be removed.  See: #12007"
+			html = html.replace(/<meta charset=\"utf-8\" \/>/gi, '');
+			return html; // String
+		},
+		_normalizeFontStyle: function(/* String */ html){
+			// summary:
+			//		Convert 'strong' and 'em' to 'b' and 'i'.
+			// description:
+			//		Moz can not handle strong/em tags correctly, so to help
+			//		mozilla and also to normalize output, convert them to 'b' and 'i'.
+			//
+			//		Note the IE generates 'strong' and 'em' rather than 'b' and 'i'
+			// tags:
+			//		private
+			return html.replace(/<(\/)?strong([ \>])/gi, '<$1b$2')
+				.replace(/<(\/)?em([ \>])/gi, '<$1i$2'); // String
+		},
+
+		_preFixUrlAttributes: function(/* String */ html){
+			// summary:
+			//		Pre-filter to do fixing to href attributes on `<a>` and `<img>` tags
+			// tags:
+			//		private
+			return html.replace(/(?:(<a(?=\s).*?\shref=)("|')(.*?)\2)|(?:(<a\s.*?href=)([^"'][^ >]+))/gi,
+				'$1$4$2$3$5$2 _djrealurl=$2$3$5$2')
+				.replace(/(?:(<img(?=\s).*?\ssrc=)("|')(.*?)\2)|(?:(<img\s.*?src=)([^"'][^ >]+))/gi,
+				'$1$4$2$3$5$2 _djrealurl=$2$3$5$2'); // String
+		},
+
+		/*****************************************************************************
+		 The following functions implement HTML manipulation commands for various
+		 browser/contentEditable implementations.  The goal of them is to enforce
+		 standard behaviors of them.
+		 ******************************************************************************/
+
+		/*** queryCommandEnabled implementations ***/
+
+		_browserQueryCommandEnabled: function(command){
+			// summary:
+			//		Implementation to call to the native queryCommandEnabled of the browser.
+			// command:
+			//		The command to check.
+			// tags:
+			//		protected
+			if(!command){
+				return false;
+			}
+			var elem = has("ie") ? this.document.selection.createRange() : this.document;
+			try{
+				return elem.queryCommandEnabled(command);
+			}catch(e){
+				return false;
+			}
+		},
+
+		_createlinkEnabledImpl: function(/*===== argument =====*/){
+			// summary:
+			//		This function implements the test for if the create link
+			//		command should be enabled or not.
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			var enabled = true;
+			if(has("opera")){
+				var sel = this.window.getSelection();
+				if(sel.isCollapsed){
+					enabled = true;
+				}else{
+					enabled = this.document.queryCommandEnabled("createlink");
+				}
+			}else{
+				enabled = this._browserQueryCommandEnabled("createlink");
+			}
+			return enabled;
+		},
+
+		_unlinkEnabledImpl: function(/*===== argument =====*/){
+			// summary:
+			//		This function implements the test for if the unlink
+			//		command should be enabled or not.
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			var enabled = true;
+			if(has("mozilla") || has("webkit")){
+				enabled = this.selection.hasAncestorElement("a");
+			}else{
+				enabled = this._browserQueryCommandEnabled("unlink");
+			}
+			return enabled;
+		},
+
+		_inserttableEnabledImpl: function(/*===== argument =====*/){
+			// summary:
+			//		This function implements the test for if the inserttable
+			//		command should be enabled or not.
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			var enabled = true;
+			if(has("mozilla") || has("webkit")){
+				enabled = true;
+			}else{
+				enabled = this._browserQueryCommandEnabled("inserttable");
+			}
+			return enabled;
+		},
+
+		_cutEnabledImpl: function(/*===== argument =====*/){
+			// summary:
+			//		This function implements the test for if the cut
+			//		command should be enabled or not.
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			var enabled = true;
+			if(has("webkit")){
+				// WebKit deems clipboard activity as a security threat and natively would return false
+				var sel = this.window.getSelection();
+				if(sel){
+					sel = sel.toString();
+				}
+				enabled = !!sel;
+			}else{
+				enabled = this._browserQueryCommandEnabled("cut");
+			}
+			return enabled;
+		},
+
+		_copyEnabledImpl: function(/*===== argument =====*/){
+			// summary:
+			//		This function implements the test for if the copy
+			//		command should be enabled or not.
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			var enabled = true;
+			if(has("webkit")){
+				// WebKit deems clipboard activity as a security threat and natively would return false
+				var sel = this.window.getSelection();
+				if(sel){
+					sel = sel.toString();
+				}
+				enabled = !!sel;
+			}else{
+				enabled = this._browserQueryCommandEnabled("copy");
+			}
+			return enabled;
+		},
+
+		_pasteEnabledImpl: function(/*===== argument =====*/){
+			// summary:c
+			//		This function implements the test for if the paste
+			//		command should be enabled or not.
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			var enabled = true;
+			if(has("webkit")){
+				return true;
+			}else{
+				enabled = this._browserQueryCommandEnabled("paste");
+			}
+			return enabled;
+		},
+
+		/*** execCommand implementations ***/
+
+		_inserthorizontalruleImpl: function(argument){
+			// summary:
+			//		This function implements the insertion of HTML 'HR' tags.
+			//		into a point on the page.  IE doesn't to it right, so
+			//		we have to use an alternate form
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			if(has("ie")){
+				return this._inserthtmlImpl("<hr>");
+			}
+			return this.document.execCommand("inserthorizontalrule", false, argument);
+		},
+
+		_unlinkImpl: function(argument){
+			// summary:
+			//		This function implements the unlink of an 'a' tag.
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			if((this.queryCommandEnabled("unlink")) && (has("mozilla") || has("webkit"))){
+				var a = this.selection.getAncestorElement("a");
+				this.selection.selectElement(a);
+				return this.document.execCommand("unlink", false, null);
+			}
+			return this.document.execCommand("unlink", false, argument);
+		},
+
+		_hilitecolorImpl: function(argument){
+			// summary:
+			//		This function implements the hilitecolor command
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			var returnValue;
+			var isApplied = this._handleTextColorOrProperties("hilitecolor", argument);
+			if(!isApplied){
+				if(has("mozilla")){
+					// mozilla doesn't support hilitecolor properly when useCSS is
+					// set to false (bugzilla #279330)
+					this.document.execCommand("styleWithCSS", false, true);
+					console.log("Executing color command.");
+					returnValue = this.document.execCommand("hilitecolor", false, argument);
+					this.document.execCommand("styleWithCSS", false, false);
+				}else{
+					returnValue = this.document.execCommand("hilitecolor", false, argument);
+				}
+			}
+			return returnValue;
+		},
+
+		_backcolorImpl: function(argument){
+			// summary:
+			//		This function implements the backcolor command
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			if(has("ie")){
+				// Tested under IE 6 XP2, no problem here, comment out
+				// IE weirdly collapses ranges when we exec these commands, so prevent it
+				//	var tr = this.document.selection.createRange();
+				argument = argument ? argument : null;
+			}
+			var isApplied = this._handleTextColorOrProperties("backcolor", argument);
+			if(!isApplied){
+				isApplied = this.document.execCommand("backcolor", false, argument);
+			}
+			return isApplied;
+		},
+
+		_forecolorImpl: function(argument){
+			// summary:
+			//		This function implements the forecolor command
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			if(has("ie")){
+				// Tested under IE 6 XP2, no problem here, comment out
+				// IE weirdly collapses ranges when we exec these commands, so prevent it
+				//	var tr = this.document.selection.createRange();
+				argument = argument ? argument : null;
+			}
+			var isApplied = false;
+			isApplied = this._handleTextColorOrProperties("forecolor", argument);
+			if(!isApplied){
+				isApplied = this.document.execCommand("forecolor", false, argument);
+			}
+			return isApplied;
+		},
+
+		_inserthtmlImpl: function(argument){
+			// summary:
+			//		This function implements the insertion of HTML content into
+			//		a point on the page.
+			// argument:
+			//		The content to insert, if any.
+			// tags:
+			//		protected
+			argument = this._preFilterContent(argument);
+			var rv = true;
+			if(has("ie")){
+				var insertRange = this.document.selection.createRange();
+				if(this.document.selection.type.toUpperCase() === 'CONTROL'){
+					var n = insertRange.item(0);
+					while(insertRange.length){
+						insertRange.remove(insertRange.item(0));
 					}
-					fs = fs.parentNode;
+					n.outerHTML = argument;
+				}else{
+					insertRange.pasteHTML(argument);
 				}
+				insertRange.select();
+				//insertRange.collapse(true);
+			}else if(has("mozilla") && !argument.length){
+				//mozilla can not inserthtml an empty html to delete current selection
+				//so we delete the selection instead in this case
+				this.selection.remove(); // FIXME
+			}else{
+				rv = this.document.execCommand("inserthtml", false, argument);
+			}
+			return rv;
+		},
+
+		_boldImpl: function(argument){
+			// summary:
+			//		This function implements an over-ride of the bold command.
+			// argument:
+			//		Not used, operates by selection.
+			// tags:
+			//		protected
+			var applied = false;
+			if(has("ie")){
+				this._adaptIESelection();
+				applied = this._adaptIEFormatAreaAndExec("bold");
+			}
+			if(!applied){
+				applied = this.document.execCommand("bold", false, argument);
+			}
+			return applied;
+		},
+
+		_italicImpl: function(argument){
+			// summary:
+			//		This function implements an over-ride of the italic command.
+			// argument:
+			//		Not used, operates by selection.
+			// tags:
+			//		protected
+			var applied = false;
+			if(has("ie")){
+				this._adaptIESelection();
+				applied = this._adaptIEFormatAreaAndExec("italic");
+			}
+			if(!applied){
+				applied = this.document.execCommand("italic", false, argument);
+			}
+			return applied;
+		},
+
+		_underlineImpl: function(argument){
+			// summary:
+			//		This function implements an over-ride of the underline command.
+			// argument:
+			//		Not used, operates by selection.
+			// tags:
+			//		protected
+			var applied = false;
+			if(has("ie")){
+				this._adaptIESelection();
+				applied = this._adaptIEFormatAreaAndExec("underline");
+			}
+			if(!applied){
+				applied = this.document.execCommand("underline", false, argument);
+			}
+			return applied;
+		},
+
+		_strikethroughImpl: function(argument){
+			// summary:
+			//		This function implements an over-ride of the strikethrough command.
+			// argument:
+			//		Not used, operates by selection.
+			// tags:
+			//		protected
+			var applied = false;
+			if(has("ie")){
+				this._adaptIESelection();
+				applied = this._adaptIEFormatAreaAndExec("strikethrough");
+			}
+			if(!applied){
+				applied = this.document.execCommand("strikethrough", false, argument);
+			}
+			return applied;
+		},
+
+		_superscriptImpl: function(argument){
+			// summary:
+			//		This function implements an over-ride of the superscript command.
+			// argument:
+			//		Not used, operates by selection.
+			// tags:
+			//		protected
+			var applied = false;
+			if(has("ie")){
+				this._adaptIESelection();
+				applied = this._adaptIEFormatAreaAndExec("superscript");
+			}
+			if(!applied){
+				applied = this.document.execCommand("superscript", false, argument);
+			}
+			return applied;
+		},
+
+		_subscriptImpl: function(argument){
+			// summary:
+			//		This function implements an over-ride of the superscript command.
+			// argument:
+			//		Not used, operates by selection.
+			// tags:
+			//		protected
+			var applied = false;
+			if(has("ie")){
+				this._adaptIESelection();
+				applied = this._adaptIEFormatAreaAndExec("subscript");
 
-				// Okay, we have a stopping place, time to split things apart.
-				if(topNode){
-					// Okay, we know how far we have to split backwards, so we have to split now.
-					rs = range.startContainer;
-					var newblock = doc.createElement(topNode.tagName);
-					domConstruct.place(newblock, topNode, "after");
-					if(rs && rs.nodeType === 3){
-						// Text node, we have to split it.
-						var nodeToMove, tNode;
-						var endOffset = range.endOffset;
-						if(rs.length < endOffset){
-							//We are not splitting the right node, try to locate the correct one
-							ret = this._adjustNodeAndOffset(rs, endOffset);
-							rs = ret.node;
-							endOffset = ret.offset;
-						}
-		
-						txt = rs.nodeValue;
-						startNode = doc.createTextNode(txt.substring(0, endOffset));
-						var endText = txt.substring(endOffset, txt.length);
-						if(endText){
-							endNode = doc.createTextNode(endText);
+			}
+			if(!applied){
+				applied = this.document.execCommand("subscript", false, argument);
+			}
+			return applied;
+		},
+
+		_fontnameImpl: function(argument){
+			// summary:
+			//		This function implements the fontname command
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			var isApplied;
+			if(has("ie")){
+				isApplied = this._handleTextColorOrProperties("fontname", argument);
+			}
+			if(!isApplied){
+				isApplied = this.document.execCommand("fontname", false, argument);
+			}
+			return isApplied;
+		},
+
+		_fontsizeImpl: function(argument){
+			// summary:
+			//		This function implements the fontsize command
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			var isApplied;
+			if(has("ie")){
+				isApplied = this._handleTextColorOrProperties("fontsize", argument);
+			}
+			if(!isApplied){
+				isApplied = this.document.execCommand("fontsize", false, argument);
+			}
+			return isApplied;
+		},
+
+		_insertorderedlistImpl: function(argument){
+			// summary:
+			//		This function implements the insertorderedlist command
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			var applied = false;
+			if(has("ie")){
+				applied = this._adaptIEList("insertorderedlist", argument);
+			}
+			if(!applied){
+				applied = this.document.execCommand("insertorderedlist", false, argument);
+			}
+			return applied;
+		},
+
+		_insertunorderedlistImpl: function(argument){
+			// summary:
+			//		This function implements the insertunorderedlist command
+			// argument:
+			//		arguments to the exec command, if any.
+			// tags:
+			//		protected
+			var applied = false;
+			if(has("ie")){
+				applied = this._adaptIEList("insertunorderedlist", argument);
+			}
+			if(!applied){
+				applied = this.document.execCommand("insertunorderedlist", false, argument);
+			}
+			return applied;
+		},
+
+		getHeaderHeight: function(){
+			// summary:
+			//		A function for obtaining the height of the header node
+			return this._getNodeChildrenHeight(this.header); // Number
+		},
+
+		getFooterHeight: function(){
+			// summary:
+			//		A function for obtaining the height of the footer node
+			return this._getNodeChildrenHeight(this.footer); // Number
+		},
+
+		_getNodeChildrenHeight: function(node){
+			// summary:
+			//		An internal function for computing the cumulative height of all child nodes of 'node'
+			// node:
+			//		The node to process the children of;
+			var h = 0;
+			if(node && node.childNodes){
+				// IE didn't compute it right when position was obtained on the node directly is some cases,
+				// so we have to walk over all the children manually.
+				var i;
+				for(i = 0; i < node.childNodes.length; i++){
+					var size = domGeometry.position(node.childNodes[i]);
+					h += size.h;
+				}
+			}
+			return h; // Number
+		},
+
+		_isNodeEmpty: function(node, startOffset){
+			// summary:
+			//		Function to test if a node is devoid of real content.
+			// node:
+			//		The node to check.
+			// tags:
+			//		private.
+			if(node.nodeType === 1/*element*/){
+				if(node.childNodes.length > 0){
+					return this._isNodeEmpty(node.childNodes[0], startOffset);
+				}
+				return true;
+			}else if(node.nodeType === 3/*text*/){
+				return (node.nodeValue.substring(startOffset) === "");
+			}
+			return false;
+		},
+
+		_removeStartingRangeFromRange: function(node, range){
+			// summary:
+			//		Function to adjust selection range by removing the current
+			//		start node.
+			// node:
+			//		The node to remove from the starting range.
+			// range:
+			//		The range to adapt.
+			// tags:
+			//		private
+			if(node.nextSibling){
+				range.setStart(node.nextSibling, 0);
+			}else{
+				var parent = node.parentNode;
+				while(parent && parent.nextSibling == null){
+					//move up the tree until we find a parent that has another node, that node will be the next node
+					parent = parent.parentNode;
+				}
+				if(parent){
+					range.setStart(parent.nextSibling, 0);
+				}
+			}
+			return range;
+		},
+
+		_adaptIESelection: function(){
+			// summary:
+			//		Function to adapt the IE range by removing leading 'newlines'
+			//		Needed to fix issue with bold/italics/underline not working if
+			//		range included leading 'newlines'.
+			//		In IE, if a user starts a selection at the very end of a line,
+			//		then the native browser commands will fail to execute correctly.
+			//		To work around the issue,  we can remove all empty nodes from
+			//		the start of the range selection.
+			var selection = rangeapi.getSelection(this.window);
+			if(selection && selection.rangeCount && !selection.isCollapsed){
+				var range = selection.getRangeAt(0);
+				var firstNode = range.startContainer;
+				var startOffset = range.startOffset;
+
+				while(firstNode.nodeType === 3/*text*/ && startOffset >= firstNode.length && firstNode.nextSibling){
+					//traverse the text nodes until we get to the one that is actually highlighted
+					startOffset = startOffset - firstNode.length;
+					firstNode = firstNode.nextSibling;
+				}
+
+				//Remove the starting ranges until the range does not start with an empty node.
+				var lastNode = null;
+				while(this._isNodeEmpty(firstNode, startOffset) && firstNode !== lastNode){
+					lastNode = firstNode; //this will break the loop in case we can't find the next sibling
+					range = this._removeStartingRangeFromRange(firstNode, range); //move the start container to the next node in the range
+					firstNode = range.startContainer;
+					startOffset = 0; //start at the beginning of the new starting range
+				}
+				selection.removeAllRanges();// this will work as long as users cannot select multiple ranges. I have not been able to do that in the editor.
+				selection.addRange(range);
+			}
+		},
+
+		_adaptIEFormatAreaAndExec: function(command){
+			// summary:
+			//		Function to handle IE's quirkiness regarding how it handles
+			//		format commands on a word.  This involves a lit of node splitting
+			//		and format cloning.
+			// command:
+			//		The format command, needed to check if the desired
+			//		command is true or not.
+			var selection = rangeapi.getSelection(this.window);
+			var doc = this.document;
+			var rs, ret, range, txt, startNode, endNode, breaker, sNode;
+			if(command && selection && selection.isCollapsed){
+				var isApplied = this.queryCommandValue(command);
+				if(isApplied){
+
+					// We have to split backwards until we hit the format
+					var nNames = this._tagNamesForCommand(command);
+					range = selection.getRangeAt(0);
+					var fs = range.startContainer;
+					if(fs.nodeType === 3){
+						var offset = range.endOffset;
+						if(fs.length < offset){
+							//We are not looking from the right node, try to locate the correct one
+							ret = this._adjustNodeAndOffset(rs, offset);
+							fs = ret.node;
+							offset = ret.offset;
 						}
-						// Place the split, then remove original nodes.
-						domConstruct.place(startNode, rs, "before");
-						if(endNode){
-							breaker = doc.createElement("span");
-							breaker.className = "ieFormatBreakerSpan";
-							domConstruct.place(breaker, rs, "after");
-							domConstruct.place(endNode, breaker, "after");
-							endNode = breaker;
+					}
+					var topNode;
+					while(fs && fs !== this.editNode){
+						// We have to walk back and see if this is still a format or not.
+						// Hm, how do I do this?
+						var tName = fs.tagName ? fs.tagName.toLowerCase() : "";
+						if(array.indexOf(nNames, tName) > -1){
+							topNode = fs;
+							break;
 						}
-						domConstruct.destroy(rs);
-						
-						// Okay, we split the text.  Now we need to see if we're
-						// parented to the block element we're splitting and if
-						// not, we have to split all the way up.  Ugh.
-						var parentC = startNode.parentNode;
-						var tagList = [];
-						var tagData;
-						while(parentC !== topNode){
-							var tg = parentC.tagName;
-							tagData = {tagName: tg};
-							tagList.push(tagData);
-														
-							var newTg = doc.createElement(tg);
-							// Clone over any 'style' data.
-							if(parentC.style){
-								if(newTg.style){
-									if(parentC.style.cssText){
-										newTg.style.cssText = parentC.style.cssText;
-										tagData.cssText = parentC.style.cssText;
+						fs = fs.parentNode;
+					}
+
+					// Okay, we have a stopping place, time to split things apart.
+					if(topNode){
+						// Okay, we know how far we have to split backwards, so we have to split now.
+						rs = range.startContainer;
+						var newblock = doc.createElement(topNode.tagName);
+						domConstruct.place(newblock, topNode, "after");
+						if(rs && rs.nodeType === 3){
+							// Text node, we have to split it.
+							var nodeToMove, tNode;
+							var endOffset = range.endOffset;
+							if(rs.length < endOffset){
+								//We are not splitting the right node, try to locate the correct one
+								ret = this._adjustNodeAndOffset(rs, endOffset);
+								rs = ret.node;
+								endOffset = ret.offset;
+							}
+
+							txt = rs.nodeValue;
+							startNode = doc.createTextNode(txt.substring(0, endOffset));
+							var endText = txt.substring(endOffset, txt.length);
+							if(endText){
+								endNode = doc.createTextNode(endText);
+							}
+							// Place the split, then remove original nodes.
+							domConstruct.place(startNode, rs, "before");
+							if(endNode){
+								breaker = doc.createElement("span");
+								breaker.className = "ieFormatBreakerSpan";
+								domConstruct.place(breaker, rs, "after");
+								domConstruct.place(endNode, breaker, "after");
+								endNode = breaker;
+							}
+							domConstruct.destroy(rs);
+
+							// Okay, we split the text.  Now we need to see if we're
+							// parented to the block element we're splitting and if
+							// not, we have to split all the way up.  Ugh.
+							var parentC = startNode.parentNode;
+							var tagList = [];
+							var tagData;
+							while(parentC !== topNode){
+								var tg = parentC.tagName;
+								tagData = {tagName: tg};
+								tagList.push(tagData);
+
+								var newTg = doc.createElement(tg);
+								// Clone over any 'style' data.
+								if(parentC.style){
+									if(newTg.style){
+										if(parentC.style.cssText){
+											newTg.style.cssText = parentC.style.cssText;
+											tagData.cssText = parentC.style.cssText;
+										}
 									}
 								}
-							}
-							// If font also need to clone over any font data.
-							if(parentC.tagName === "FONT"){
-								if(parentC.color){
-									newTg.color = parentC.color;
-									tagData.color = parentC.color;
+								// If font also need to clone over any font data.
+								if(parentC.tagName === "FONT"){
+									if(parentC.color){
+										newTg.color = parentC.color;
+										tagData.color = parentC.color;
+									}
+									if(parentC.face){
+										newTg.face = parentC.face;
+										tagData.face = parentC.face;
+									}
+									if(parentC.size){  // this check was necessary on IE
+										newTg.size = parentC.size;
+										tagData.size = parentC.size;
+									}
 								}
-								if(parentC.face){
-									newTg.face = parentC.face;
-									tagData.face = parentC.face;
+								if(parentC.className){
+									newTg.className = parentC.className;
+									tagData.className = parentC.className;
 								}
-								if(parentC.size){  // this check was necessary on IE
-									newTg.size = parentC.size;
-									tagData.size = parentC.size;
+
+								// Now move end node and every sibling
+								// after it over into the new tag.
+								if(endNode){
+									nodeToMove = endNode;
+									while(nodeToMove){
+										tNode = nodeToMove.nextSibling;
+										newTg.appendChild(nodeToMove);
+										nodeToMove = tNode;
+									}
 								}
+								if(newTg.tagName == parentC.tagName){
+									breaker = doc.createElement("span");
+									breaker.className = "ieFormatBreakerSpan";
+									domConstruct.place(breaker, parentC, "after");
+									domConstruct.place(newTg, breaker, "after");
+								}else{
+									domConstruct.place(newTg, parentC, "after");
+								}
+								startNode = parentC;
+								endNode = newTg;
+								parentC = parentC.parentNode;
 							}
-							if(parentC.className){
-								newTg.className = parentC.className;
-								tagData.className = parentC.className;
-							}
-							
-							// Now move end node and every sibling 
-							// after it over into the new tag.
+
+							// Lastly, move the split out all the split tags
+							// to the new block as they should now be split properly.
 							if(endNode){
 								nodeToMove = endNode;
+								if(nodeToMove.nodeType === 1 || (nodeToMove.nodeType === 3 && nodeToMove.nodeValue)){
+									// Non-blank text and non-text nodes need to clear out that blank space
+									// before moving the contents.
+									newblock.innerHTML = "";
+								}
 								while(nodeToMove){
 									tNode = nodeToMove.nextSibling;
-									newTg.appendChild(nodeToMove);
+									newblock.appendChild(nodeToMove);
 									nodeToMove = tNode;
 								}
 							}
-							if(newTg.tagName == parentC.tagName){
-								breaker = doc.createElement("span");
-								breaker.className = "ieFormatBreakerSpan";
-								domConstruct.place(breaker, parentC, "after");
-								domConstruct.place(newTg, breaker, "after");
-							}else{
-								domConstruct.place(newTg, parentC, "after");
-							}
-							startNode = parentC;
-							endNode = newTg;
-							parentC = parentC.parentNode;
-						}
 
-						// Lastly, move the split out all the split tags 
-						// to the new block as they should now be split properly.
-						if(endNode){
-							nodeToMove = endNode;
-							if(nodeToMove.nodeType === 1 || (nodeToMove.nodeType === 3 && nodeToMove.nodeValue)){
-								// Non-blank text and non-text nodes need to clear out that blank space
-								// before moving the contents.
-								newblock.innerHTML = "";
-							}
-							while(nodeToMove){
-								tNode = nodeToMove.nextSibling;
-								newblock.appendChild(nodeToMove);
-								nodeToMove = tNode;
-							}
-						}
-						
-						// We had intermediate tags, we have to now recreate them inbetween the split
-						// and restore what styles, classnames, etc, we can.  
-						if(tagList.length){
-							tagData = tagList.pop();
-							var newContTag = doc.createElement(tagData.tagName);
-							if(tagData.cssText && newContTag.style){
-								newContTag.style.cssText = tagData.cssText;
-							}
-							if(tagData.className){
-								newContTag.className = tagData.className;
-							}
-							if(tagData.tagName === "FONT"){
-								if(tagData.color){
-									newContTag.color = tagData.color;
-								}
-								if(tagData.face){
-									newContTag.face = tagData.face;
-								}
-								if(tagData.size){ 
-									newContTag.size = tagData.size;
-								}
-							}								
-							domConstruct.place(newContTag, newblock, "before");
-							while(tagList.length){
+							// We had intermediate tags, we have to now recreate them inbetween the split
+							// and restore what styles, classnames, etc, we can.
+							var newrange;
+							if(tagList.length){
 								tagData = tagList.pop();
-								var newTgNode = doc.createElement(tagData.tagName);
-								if(tagData.cssText && newTgNode.style){
-									newTgNode.style.cssText = tagData.cssText;
+								var newContTag = doc.createElement(tagData.tagName);
+								if(tagData.cssText && newContTag.style){
+									newContTag.style.cssText = tagData.cssText;
 								}
 								if(tagData.className){
-									newTgNode.className = tagData.className;
+									newContTag.className = tagData.className;
 								}
 								if(tagData.tagName === "FONT"){
 									if(tagData.color){
-										newTgNode.color = tagData.color;
+										newContTag.color = tagData.color;
 									}
 									if(tagData.face){
-										newTgNode.face = tagData.face;
+										newContTag.face = tagData.face;
+									}
+									if(tagData.size){
+										newContTag.size = tagData.size;
+									}
+								}
+								domConstruct.place(newContTag, newblock, "before");
+								while(tagList.length){
+									tagData = tagList.pop();
+									var newTgNode = doc.createElement(tagData.tagName);
+									if(tagData.cssText && newTgNode.style){
+										newTgNode.style.cssText = tagData.cssText;
+									}
+									if(tagData.className){
+										newTgNode.className = tagData.className;
 									}
-									if(tagData.size){ 
-										newTgNode.size = tagData.size;
+									if(tagData.tagName === "FONT"){
+										if(tagData.color){
+											newTgNode.color = tagData.color;
+										}
+										if(tagData.face){
+											newTgNode.face = tagData.face;
+										}
+										if(tagData.size){
+											newTgNode.size = tagData.size;
+										}
 									}
-								}	
-								newContTag.appendChild(newTgNode);
-								newContTag = newTgNode;
-							}							
-							
-							// Okay, everything is theoretically split apart and removed from the content
-							// so insert the dummy text to select, select it, then
-							// clear to position cursor.
-							sNode = doc.createTextNode(".");
-							breaker.appendChild(sNode);
-							newContTag.appendChild(sNode);
-							win.withGlobal(this.window, lang.hitch(this, function(){
-								var newrange = rangeapi.create();
+									newContTag.appendChild(newTgNode);
+									newContTag = newTgNode;
+								}
+
+								// Okay, everything is theoretically split apart and removed from the content
+								// so insert the dummy text to select, select it, then
+								// clear to position cursor.
+								sNode = doc.createTextNode(".");
+								breaker.appendChild(sNode);
+								newContTag.appendChild(sNode);
+								newrange = rangeapi.create(this.window);
 								newrange.setStart(sNode, 0);
 								newrange.setEnd(sNode, sNode.length);
 								selection.removeAllRanges();
 								selection.addRange(newrange);
-								selectionapi.collapse(false);
+								this.selection.collapse(false);
 								sNode.parentNode.innerHTML = "";
-							}));							
-						}else{
-							// No extra tags, so we have to insert a breaker point and rely
-							// on filters to remove it later.
-							breaker = doc.createElement("span");
-							breaker.className="ieFormatBreakerSpan";
-							sNode = doc.createTextNode(".");
-							breaker.appendChild(sNode);
-							domConstruct.place(breaker, newblock, "before");
-							win.withGlobal(this.window, lang.hitch(this, function(){
-								var newrange = rangeapi.create();
+							}else{
+								// No extra tags, so we have to insert a breaker point and rely
+								// on filters to remove it later.
+								breaker = doc.createElement("span");
+								breaker.className = "ieFormatBreakerSpan";
+								sNode = doc.createTextNode(".");
+								breaker.appendChild(sNode);
+								domConstruct.place(breaker, newblock, "before");
+								newrange = rangeapi.create(this.window);
 								newrange.setStart(sNode, 0);
 								newrange.setEnd(sNode, sNode.length);
 								selection.removeAllRanges();
 								selection.addRange(newrange);
-								selectionapi.collapse(false);
+								this.selection.collapse(false);
 								sNode.parentNode.innerHTML = "";
-							}));
+							}
+							if(!newblock.firstChild){
+								// Empty, we don't need it.  Split was at end or similar
+								// So, remove it.
+								domConstruct.destroy(newblock);
+							}
+							return true;
 						}
-						if(!newblock.firstChild){
-							// Empty, we don't need it.  Split was at end or similar
-							// So, remove it.
-							domConstruct.destroy(newblock);
-						}					
-						return true;
 					}
-				}
-				return false;
-			}else{
-				range = selection.getRangeAt(0);
-				rs = range.startContainer;
-				if(rs && rs.nodeType === 3){
-					// Text node, we have to split it.
-					win.withGlobal(this.window, lang.hitch(this, function(){
+					return false;
+				}else{
+					range = selection.getRangeAt(0);
+					rs = range.startContainer;
+					if(rs && rs.nodeType === 3){
+						// Text node, we have to split it.
 						var offset = range.startOffset;
 						if(rs.length < offset){
 							//We are not splitting the right node, try to locate the correct one
@@ -2635,7 +2720,7 @@ var RichText = declare("dijit._editor.RichText", [_Widget, _CssStateMixin], {
 						if(endText !== ""){
 							endNode = doc.createTextNode(txt.substring(offset));
 						}
-						// Create a space, we'll select and bold it, so 
+						// Create a space, we'll select and bold it, so
 						// the whole word doesn't get bolded
 						breaker = doc.createElement("span");
 						sNode = doc.createTextNode(".");
@@ -2650,7 +2735,7 @@ var RichText = declare("dijit._editor.RichText", [_Widget, _CssStateMixin], {
 							domConstruct.place(endNode, breaker, "after");
 						}
 						domConstruct.destroy(rs);
-						var newrange = rangeapi.create();
+						var newrange = rangeapi.create(this.window);
 						newrange.setStart(sNode, 0);
 						newrange.setEnd(sNode, sNode.length);
 						selection.removeAllRanges();
@@ -2662,51 +2747,50 @@ var RichText = declare("dijit._editor.RichText", [_Widget, _CssStateMixin], {
 						newrange.setEnd(sNode, sNode.length);
 						selection.removeAllRanges();
 						selection.addRange(newrange);
-						selectionapi.collapse(false);
+						this.selection.collapse(false);
 						sNode.parentNode.innerHTML = "";
-					}));
-					return true;
+						return true;
+					}
 				}
+			}else{
+				return false;
 			}
-		}else{
-			return false;
-		}
-	},
-	
-	_adaptIEList: function(command /*===== , argument =====*/){
-		// summary:
-		//		This function handles normalizing the IE list behavior as 
-		//		much as possible.
-		// command:
-		//		The list command to execute.
-		// argument:
-		//		Any additional argument.
-		// tags:
-		//		private
-		var selection = rangeapi.getSelection(this.window);
-		if(selection.isCollapsed){
-			// In the case of no selection, lets commonize the behavior and
-			// make sure that it indents if needed.
-			if(selection.rangeCount && !this.queryCommandValue(command)){
-				var range = selection.getRangeAt(0);
-				var sc = range.startContainer;
-				if(sc && sc.nodeType == 3){
-					// text node.  Lets see if there is a node before it that isn't
-					// some sort of breaker.
-					if(!range.startOffset){
-						// We're at the beginning of a text area.  It may have been br split
-						// Who knows?  In any event, we must create the list manually
-						// or IE may shove too much into the list element.  It seems to
-						// grab content before the text node too if it's br split.
-						// Why can't IE work like everyone else?
-						win.withGlobal(this.window, lang.hitch(this, function(){
-							// Create a space, we'll select and bold it, so 
+		},
+
+		_adaptIEList: function(command /*===== , argument =====*/){
+			// summary:
+			//		This function handles normalizing the IE list behavior as
+			//		much as possible.
+			// command:
+			//		The list command to execute.
+			// argument:
+			//		Any additional argument.
+			// tags:
+			//		private
+			var selection = rangeapi.getSelection(this.window);
+			if(selection.isCollapsed){
+				// In the case of no selection, lets commonize the behavior and
+				// make sure that it indents if needed.
+				if(selection.rangeCount && !this.queryCommandValue(command)){
+					var range = selection.getRangeAt(0);
+					var sc = range.startContainer;
+					if(sc && sc.nodeType == 3){
+						// text node.  Lets see if there is a node before it that isn't
+						// some sort of breaker.
+						if(!range.startOffset){
+							// We're at the beginning of a text area.  It may have been br split
+							// Who knows?  In any event, we must create the list manually
+							// or IE may shove too much into the list element.  It seems to
+							// grab content before the text node too if it's br split.
+							// Why can't IE work like everyone else?
+
+							// Create a space, we'll select and bold it, so
 							// the whole word doesn't get bolded
 							var lType = "ul";
 							if(command === "insertorderedlist"){
 								lType = "ol";
 							}
-							var list = domConstruct.create(lType);
+							var list = this.document.createElement(lType);
 							var li = domConstruct.create("li", null, list);
 							domConstruct.place(list, sc, "before");
 							// Move in the text node as part of the li.
@@ -2715,44 +2799,42 @@ var RichText = declare("dijit._editor.RichText", [_Widget, _CssStateMixin], {
 							// sometimes throws errors.
 							domConstruct.create("br", null, list, "after");
 							// Okay, now lets move our cursor to the beginning.
-							var newrange = rangeapi.create();
+							var newrange = rangeapi.create(this.window);
 							newrange.setStart(sc, 0);
 							newrange.setEnd(sc, sc.length);
 							selection.removeAllRanges();
 							selection.addRange(newrange);
-							selectionapi.collapse(true);
-						}));
-						return true;
+							this.selection.collapse(true);
+							return true;
+						}
 					}
 				}
 			}
-		}
-		return false;
-	},
-	
-	_handleTextColorOrProperties: function(command, argument){
-		// summary:
-		//		This function handles appplying text color as best it is 
-		//		able to do so when the selection is collapsed, making the
-		//		behavior cross-browser consistent. It also handles the name
-		//		and size for IE.
-		// command:
-		//		The command.
-		// argument:
-		//		Any additional arguments.
-		// tags:
-		//		private
-		var selection = rangeapi.getSelection(this.window);
-		var doc = this.document;
-		var rs, ret, range, txt, startNode, endNode, breaker, sNode;
-		argument = argument || null;
-		if(command && selection && selection.isCollapsed){
-			if(selection.rangeCount){
-				range = selection.getRangeAt(0);
-				rs = range.startContainer;
-				if(rs && rs.nodeType === 3){
-					// Text node, we have to split it.
-					win.withGlobal(this.window, lang.hitch(this, function(){
+			return false;
+		},
+
+		_handleTextColorOrProperties: function(command, argument){
+			// summary:
+			//		This function handles appplying text color as best it is
+			//		able to do so when the selection is collapsed, making the
+			//		behavior cross-browser consistent. It also handles the name
+			//		and size for IE.
+			// command:
+			//		The command.
+			// argument:
+			//		Any additional arguments.
+			// tags:
+			//		private
+			var selection = rangeapi.getSelection(this.window);
+			var doc = this.document;
+			var rs, ret, range, txt, startNode, endNode, breaker, sNode;
+			argument = argument || null;
+			if(command && selection && selection.isCollapsed){
+				if(selection.rangeCount){
+					range = selection.getRangeAt(0);
+					rs = range.startContainer;
+					if(rs && rs.nodeType === 3){
+						// Text node, we have to split it.
 						var offset = range.startOffset;
 						if(rs.length < offset){
 							//We are not splitting the right node, try to locate the correct one
@@ -2766,14 +2848,14 @@ var RichText = declare("dijit._editor.RichText", [_Widget, _CssStateMixin], {
 						if(endText !== ""){
 							endNode = doc.createTextNode(txt.substring(offset));
 						}
-						// Create a space, we'll select and bold it, so 
+						// Create a space, we'll select and bold it, so
 						// the whole word doesn't get bolded
-						breaker = domConstruct.create("span");
+						breaker = doc.createElement("span");
 						sNode = doc.createTextNode(".");
 						breaker.appendChild(sNode);
-						// Create a junk node to avoid it trying to stlye the breaker.
+						// Create a junk node to avoid it trying to style the breaker.
 						// This will get destroyed later.
-						var extraSpan = domConstruct.create("span");
+						var extraSpan = doc.createElement("span");
 						breaker.appendChild(extraSpan);
 						if(startNode.length){
 							domConstruct.place(startNode, rs, "after");
@@ -2785,13 +2867,13 @@ var RichText = declare("dijit._editor.RichText", [_Widget, _CssStateMixin], {
 							domConstruct.place(endNode, breaker, "after");
 						}
 						domConstruct.destroy(rs);
-						var newrange = rangeapi.create();
+						var newrange = rangeapi.create(this.window);
 						newrange.setStart(sNode, 0);
 						newrange.setEnd(sNode, sNode.length);
 						selection.removeAllRanges();
 						selection.addRange(newrange);
 						if(has("webkit")){
-							// WebKit is frustrating with positioning the cursor. 
+							// WebKit is frustrating with positioning the cursor.
 							// It stinks to have a selected space, but there really
 							// isn't much choice here.
 							var style = "color";
@@ -2799,10 +2881,10 @@ var RichText = declare("dijit._editor.RichText", [_Widget, _CssStateMixin], {
 								style = "backgroundColor";
 							}
 							domStyle.set(breaker, style, argument);
-							selectionapi.remove();
+							this.selection.remove();
 							domConstruct.destroy(extraSpan);
 							breaker.innerHTML = " ";	//  
-							selectionapi.selectElement(breaker);
+							this.selection.selectElement(breaker);
 							this.focus();
 						}else{
 							this.execCommand(command, argument);
@@ -2812,80 +2894,77 @@ var RichText = declare("dijit._editor.RichText", [_Widget, _CssStateMixin], {
 							newrange.setEnd(sNode, sNode.length);
 							selection.removeAllRanges();
 							selection.addRange(newrange);
-							selectionapi.collapse(false);
+							this.selection.collapse(false);
 							sNode.parentNode.removeChild(sNode);
 						}
-					}));
-					return true;
+						return true;
+					}
 				}
-			}				
-		}
-		return false;
-	},
-	
-	_adjustNodeAndOffset: function(/*DomNode*/node, /*Int*/offset){
-		// summary:
-		//		In the case there are multiple text nodes in a row the offset may not be within the node.  
-		//		If the offset is larger than the node length, it will attempt to find
-		//		the next text sibling until it locates the text node in which the offset refers to
-		// node:
-		//		The node to check.
-		// offset:
-		//		The position to find within the text node
-		// tags:
-		//		private.
-		while(node.length < offset && node.nextSibling && node.nextSibling.nodeType === 3){
-			//Adjust the offset and node in the case of multiple text nodes in a row
-			offset = offset - node.length;
-			node = node.nextSibling;
-		}
-		return {"node": node, "offset": offset};
-	},
-	
-	_tagNamesForCommand: function(command){
-		// summary:
-		//		Function to return the tab names that are associated
-		//		with a particular style.
-		// command: String
-		//		The command to return tags for.
-		// tags:
-		//		private
-		if(command === "bold"){
-			return ["b", "strong"];
-		}else if(command === "italic"){
-			return ["i","em"];
-		}else if(command === "strikethrough"){
-			return ["s", "strike"];
-		}else if(command === "superscript"){
-			return ["sup"];
-		}else if(command === "subscript"){
-			return ["sub"];
-		}else if(command === "underline"){
-			return ["u"];
-		}	
-		return [];
-	},
-
-	_stripBreakerNodes: function(node){
-		// summary:
-		//		Function for stripping out the breaker spans inserted by the formatting command.
-		//		Registered as a filter for IE, handles the breaker spans needed to fix up
-		//		How bold/italic/etc, work when selection is collapsed (single cursor).
-		win.withGlobal(this.window, lang.hitch(this, function(){
-			var breakers = query(".ieFormatBreakerSpan", node);
-			var i;
-			for(i = 0; i < breakers.length; i++){
-				var b = breakers[i];
+			}
+			return false;
+		},
+
+		_adjustNodeAndOffset: function(/*DomNode*/node, /*Int*/offset){
+			// summary:
+			//		In the case there are multiple text nodes in a row the offset may not be within the node.
+			//		If the offset is larger than the node length, it will attempt to find
+			//		the next text sibling until it locates the text node in which the offset refers to
+			// node:
+			//		The node to check.
+			// offset:
+			//		The position to find within the text node
+			// tags:
+			//		private.
+			while(node.length < offset && node.nextSibling && node.nextSibling.nodeType === 3){
+				//Adjust the offset and node in the case of multiple text nodes in a row
+				offset = offset - node.length;
+				node = node.nextSibling;
+			}
+			return {"node": node, "offset": offset};
+		},
+
+		_tagNamesForCommand: function(command){
+			// summary:
+			//		Function to return the tab names that are associated
+			//		with a particular style.
+			// command: String
+			//		The command to return tags for.
+			// tags:
+			//		private
+			if(command === "bold"){
+				return ["b", "strong"];
+			}else if(command === "italic"){
+				return ["i", "em"];
+			}else if(command === "strikethrough"){
+				return ["s", "strike"];
+			}else if(command === "superscript"){
+				return ["sup"];
+			}else if(command === "subscript"){
+				return ["sub"];
+			}else if(command === "underline"){
+				return ["u"];
+			}
+			return [];
+		},
+
+		_stripBreakerNodes: function(/*DOMNode*/ node){
+			// summary:
+			//		Function for stripping out the breaker spans inserted by the formatting command.
+			//		Registered as a filter for IE, handles the breaker spans needed to fix up
+			//		How bold/italic/etc, work when selection is collapsed (single cursor).
+			if(!this.isLoaded){
+				return;
+			} // this method requires init to be complete
+			query(".ieFormatBreakerSpan", node).forEach(function(b){
 				while(b.firstChild){
 					domConstruct.place(b.firstChild, b, "before");
 				}
 				domConstruct.destroy(b);
-			}		
-		}));
-		return node;
-	}
-});
+			});
+			return node;
+		}
+	});
 
-return RichText;
+	return RichText;
 
 });
diff --git a/dijit/_editor/_Plugin.js b/dijit/_editor/_Plugin.js
index d1276f8..8d65437 100644
--- a/dijit/_editor/_Plugin.js
+++ b/dijit/_editor/_Plugin.js
@@ -2,293 +2,300 @@ define([
 	"dojo/_base/connect", // connect.connect
 	"dojo/_base/declare", // declare
 	"dojo/_base/lang", // lang.mixin, lang.hitch
+	"../Destroyable",
 	"../form/Button"
-], function(connect, declare, lang, Button){
-
-// module:
-//		dijit/_editor/_Plugin
-// summary:
-//		Base class for a "plugin" to the editor, which is usually
-//		a single button on the Toolbar and some associated code
-
-
-var _Plugin = declare("dijit._editor._Plugin", null, {
-	// summary:
-	//		Base class for a "plugin" to the editor, which is usually
-	//		a single button on the Toolbar and some associated code
-
-	constructor: function(/*Object?*/args){
-		this.params = args || {};
-		lang.mixin(this, this.params);
-		this._connects=[];
-		this._attrPairNames = {};
-	},
-
-	// editor: [const] dijit.Editor
-	//		Points to the parent editor
-	editor: null,
-
-	// iconClassPrefix: [const] String
-	//		The CSS class name for the button node is formed from `iconClassPrefix` and `command`
-	iconClassPrefix: "dijitEditorIcon",
-
-	// button: dijit._Widget?
-	//		Pointer to `dijit.form.Button` or other widget (ex: `dijit.form.FilteringSelect`)
-	//		that is added to the toolbar to control this plugin.
-	//		If not specified, will be created on initialization according to `buttonClass`
-	button: null,
-
-	// command: String
-	//		String like "insertUnorderedList", "outdent", "justifyCenter", etc. that represents an editor command.
-	//		Passed to editor.execCommand() if `useDefaultCommand` is true.
-	command: "",
-
-	// useDefaultCommand: Boolean
-	//		If true, this plugin executes by calling Editor.execCommand() with the argument specified in `command`.
-	useDefaultCommand: true,
-
-	// buttonClass: Widget Class
-	//		Class of widget (ex: dijit.form.Button or dijit.form.FilteringSelect)
-	//		that is added to the toolbar to control this plugin.
-	//		This is used to instantiate the button, unless `button` itself is specified directly.
-	buttonClass: Button,
-
-	// disabled: Boolean
-	//		Flag to indicate if this plugin has been disabled and should do nothing
-	//		helps control button state, among other things.  Set via the setter api.
-	disabled: false,
-
-	getLabel: function(/*String*/key){
-		// summary:
-		//		Returns the label to use for the button
-		// tags:
-		//		private
-		return this.editor.commands[key];		// String
-	},
+], function(connect, declare, lang, Destroyable, Button){
 
-	_initButton: function(){
-		// summary:
-		//		Initialize the button or other widget that will control this plugin.
-		//		This code only works for plugins controlling built-in commands in the editor.
-		// tags:
-		//		protected extension
-		if(this.command.length){
-			var label = this.getLabel(this.command),
-				editor = this.editor,
-				className = this.iconClassPrefix+" "+this.iconClassPrefix + this.command.charAt(0).toUpperCase() + this.command.substr(1);
-			if(!this.button){
-				var props = lang.mixin({
-					label: label,
-					dir: editor.dir,
-					lang: editor.lang,
-					showLabel: false,
-					iconClass: className,
-					dropDown: this.dropDown,
-					tabIndex: "-1"
-				}, this.params || {});
-				this.button = new this.buttonClass(props);
-			}
-		}
-		if(this.get("disabled") && this.button){
-			this.button.set("disabled", this.get("disabled"));
-		}
-	},
+	// module:
+	//		dijit/_editor/_Plugin
 
-	destroy: function(){
+	var _Plugin = declare("dijit._editor._Plugin", Destroyable, {
 		// summary:
-		//		Destroy this plugin
+		//		Base class for a "plugin" to the editor, which is usually
+		//		a single button on the Toolbar and some associated code
+
+		constructor: function(args){
+			// summary:
+			//		Create the plugin.
+			// args: Object?
+			//		Initial settings for any of the attributes.
+
+			this.params = args || {};
+			lang.mixin(this, this.params);
+			this._attrPairNames = {};
+		},
+
+		// editor: [const] dijit.Editor
+		//		Points to the parent editor
+		editor: null,
+
+		// iconClassPrefix: [const] String
+		//		The CSS class name for the button node is formed from `iconClassPrefix` and `command`
+		iconClassPrefix: "dijitEditorIcon",
+
+		// button: dijit/_WidgetBase?
+		//		Pointer to `dijit/form/Button` or other widget (ex: `dijit/form/FilteringSelect`)
+		//		that is added to the toolbar to control this plugin.
+		//		If not specified, will be created on initialization according to `buttonClass`
+		button: null,
+
+		// command: String
+		//		String like "insertUnorderedList", "outdent", "justifyCenter", etc. that represents an editor command.
+		//		Passed to editor.execCommand() if `useDefaultCommand` is true.
+		command: "",
+
+		// useDefaultCommand: Boolean
+		//		If true, this plugin executes by calling Editor.execCommand() with the argument specified in `command`.
+		useDefaultCommand: true,
+
+		// buttonClass: Widget Class
+		//		Class of widget (ex: dijit.form.Button or dijit/form/FilteringSelect)
+		//		that is added to the toolbar to control this plugin.
+		//		This is used to instantiate the button, unless `button` itself is specified directly.
+		buttonClass: Button,
+
+		// disabled: Boolean
+		//		Flag to indicate if this plugin has been disabled and should do nothing
+		//		helps control button state, among other things.  Set via the setter api.
+		disabled: false,
+
+		getLabel: function(/*String*/key){
+			// summary:
+			//		Returns the label to use for the button
+			// tags:
+			//		private
+			return this.editor.commands[key];		// String
+		},
+
+		_initButton: function(){
+			// summary:
+			//		Initialize the button or other widget that will control this plugin.
+			//		This code only works for plugins controlling built-in commands in the editor.
+			// tags:
+			//		protected extension
+			if(this.command.length){
+				var label = this.getLabel(this.command),
+					editor = this.editor,
+					className = this.iconClassPrefix + " " + this.iconClassPrefix + this.command.charAt(0).toUpperCase() + this.command.substr(1);
+				if(!this.button){
+					var props = lang.mixin({
+						label: label,
+						ownerDocument: editor.ownerDocument,
+						dir: editor.dir,
+						lang: editor.lang,
+						showLabel: false,
+						iconClass: className,
+						dropDown: this.dropDown,
+						tabIndex: "-1"
+					}, this.params || {});
+					this.button = new this.buttonClass(props);
+				}
+			}
+			if(this.get("disabled") && this.button){
+				this.button.set("disabled", this.get("disabled"));
+			}
+		},
 
-		var h;
-		while(h = this._connects.pop()){ h.remove(); }
-		if(this.dropDown){
-			this.dropDown.destroyRecursive();
-		}
-	},
+		destroy: function(){
+			if(this.dropDown){
+				this.dropDown.destroyRecursive();
+			}
 
-	connect: function(o, f, tf){
-		// summary:
-		//		Make a connect.connect() that is automatically disconnected when this plugin is destroyed.
-		//		Similar to `dijit._Widget.connect`.
-		// tags:
-		//		protected
-		this._connects.push(connect.connect(o, f, this, tf));
-	},
-
-	updateState: function(){
-		// summary:
-		//		Change state of the plugin to respond to events in the editor.
-		// description:
-		//		This is called on meaningful events in the editor, such as change of selection
-		//		or caret position (but not simple typing of alphanumeric keys).   It gives the
-		//		plugin a chance to update the CSS of its button.
-		//
-		//		For example, the "bold" plugin will highlight/unhighlight the bold button depending on whether the
-		//		characters next to the caret are bold or not.
-		//
-		//		Only makes sense when `useDefaultCommand` is true, as it calls Editor.queryCommandEnabled(`command`).
-		var e = this.editor,
-			c = this.command,
-			checked, enabled;
-		if(!e || !e.isLoaded || !c.length){ return; }
-		var disabled = this.get("disabled");
-		if(this.button){
-			try{
-				enabled = !disabled && e.queryCommandEnabled(c);
-				if(this.enabled !== enabled){
-					this.enabled = enabled;
-					this.button.set('disabled', !enabled);
-				}
-				if(typeof this.button.checked == 'boolean'){
-					checked = e.queryCommandState(c);
-					if(this.checked !== checked){
-						this.checked = checked;
-						this.button.set('checked', e.queryCommandState(c));
+			this.inherited(arguments);
+		},
+
+		connect: function(o, f, tf){
+			// summary:
+			//		Deprecated.  Use this.own() with dojo/on or dojo/aspect.instead.
+			//
+			//		Make a connect.connect() that is automatically disconnected when this plugin is destroyed.
+			//		Similar to `dijit/_Widget.connect()`.
+			// tags:
+			//		protected deprecated
+
+			this.own(connect.connect(o, f, this, tf));
+		},
+
+		updateState: function(){
+			// summary:
+			//		Change state of the plugin to respond to events in the editor.
+			// description:
+			//		This is called on meaningful events in the editor, such as change of selection
+			//		or caret position (but not simple typing of alphanumeric keys).   It gives the
+			//		plugin a chance to update the CSS of its button.
+			//
+			//		For example, the "bold" plugin will highlight/unhighlight the bold button depending on whether the
+			//		characters next to the caret are bold or not.
+			//
+			//		Only makes sense when `useDefaultCommand` is true, as it calls Editor.queryCommandEnabled(`command`).
+			var e = this.editor,
+				c = this.command,
+				checked, enabled;
+			if(!e || !e.isLoaded || !c.length){
+				return;
+			}
+			var disabled = this.get("disabled");
+			if(this.button){
+				try{
+					enabled = !disabled && e.queryCommandEnabled(c);
+					if(this.enabled !== enabled){
+						this.enabled = enabled;
+						this.button.set('disabled', !enabled);
+					}
+					if(enabled){
+						if(typeof this.button.checked == 'boolean'){
+							checked = e.queryCommandState(c);
+							if(this.checked !== checked){
+								this.checked = checked;
+								this.button.set('checked', e.queryCommandState(c));
+							}
+						}
 					}
+				}catch(e){
+					console.log(e); // FIXME: we shouldn't have debug statements in our code.  Log as an error?
 				}
-			}catch(e){
-				console.log(e); // FIXME: we shouldn't have debug statements in our code.  Log as an error?
 			}
-		}
-	},
+		},
 
-	setEditor: function(/*dijit.Editor*/ editor){
-		// summary:
-		//		Tell the plugin which Editor it is associated with.
+		setEditor: function(/*dijit/Editor*/ editor){
+			// summary:
+			//		Tell the plugin which Editor it is associated with.
 
-		// TODO: refactor code to just pass editor to constructor.
+			// TODO: refactor code to just pass editor to constructor.
 
-		// FIXME: detach from previous editor!!
-		this.editor = editor;
+			// FIXME: detach from previous editor!!
+			this.editor = editor;
 
-		// FIXME: prevent creating this if we don't need to (i.e., editor can't handle our command)
-		this._initButton();
+			// FIXME: prevent creating this if we don't need to (i.e., editor can't handle our command)
+			this._initButton();
 
-		// Processing for buttons that execute by calling editor.execCommand()
-		if(this.button && this.useDefaultCommand){
-			if(this.editor.queryCommandAvailable(this.command)){
-				this.connect(this.button, "onClick",
-					lang.hitch(this.editor, "execCommand", this.command, this.commandArg)
-				);
-			}else{
-				// hide button because editor doesn't support command (due to browser limitations)
-				this.button.domNode.style.display = "none";
+			// Processing for buttons that execute by calling editor.execCommand()
+			if(this.button && this.useDefaultCommand){
+				if(this.editor.queryCommandAvailable(this.command)){
+					this.own(this.button.on("click",
+						lang.hitch(this.editor, "execCommand", this.command, this.commandArg)
+					));
+				}else{
+					// hide button because editor doesn't support command (due to browser limitations)
+					this.button.domNode.style.display = "none";
+				}
 			}
-		}
 
-		this.connect(this.editor, "onNormalizedDisplayChanged", "updateState");
-	},
+			this.own(this.editor.on("NormalizedDisplayChanged", lang.hitch(this, "updateState")));
+		},
 
-	setToolbar: function(/*dijit.Toolbar*/ toolbar){
-		// summary:
-		//		Tell the plugin to add it's controller widget (often a button)
-		//		to the toolbar.  Does nothing if there is no controller widget.
-
-		// TODO: refactor code to just pass toolbar to constructor.
+		setToolbar: function(/*dijit/Toolbar*/ toolbar){
+			// summary:
+			//		Tell the plugin to add it's controller widget (often a button)
+			//		to the toolbar.  Does nothing if there is no controller widget.
 
-		if(this.button){
-			toolbar.addChild(this.button);
-		}
-		// console.debug("adding", this.button, "to:", toolbar);
-	},
+			// TODO: refactor code to just pass toolbar to constructor.
 
-	set: function(/* attribute */ name, /* anything */ value){
-		// summary:
-		//		Set a property on a plugin
-		//	name:
-		//		The property to set.
-		//	value:
-		//		The value to set in the property.
-		// description:
-		//		Sets named properties on a plugin which may potentially be handled by a
-		// 		setter in the plugin.
-		// 		For example, if the plugin has a properties "foo"
-		//		and "bar" and a method named "_setFooAttr", calling:
-		//	|	plugin.set("foo", "Howdy!");
-		//		would be equivalent to writing:
-		//	|	plugin._setFooAttr("Howdy!");
-		//		and:
-		//	|	plugin.set("bar", 3);
-		//		would be equivalent to writing:
-		//	|	plugin.bar = 3;
-		//
-		//	set() may also be called with a hash of name/value pairs, ex:
-		//	|	plugin.set({
-		//	|		foo: "Howdy",
-		//	|		bar: 3
-		//	|	})
-		//	This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
-		if(typeof name === "object"){
-			for(var x in name){
-				this.set(x, name[x]);
-	}
-			return this;
-		}
-		var names = this._getAttrNames(name);
-		if(this[names.s]){
-			// use the explicit setter
-			var result = this[names.s].apply(this, Array.prototype.slice.call(arguments, 1));
-		}else{
-			this._set(name, value);
+			if(this.button){
+				toolbar.addChild(this.button);
+			}
+			// console.debug("adding", this.button, "to:", toolbar);
+		},
+
+		set: function(/* attribute */ name, /* anything */ value){
+			// summary:
+			//		Set a property on a plugin
+			// name:
+			//		The property to set.
+			// value:
+			//		The value to set in the property.
+			// description:
+			//		Sets named properties on a plugin which may potentially be handled by a
+			//		setter in the plugin.
+			//		For example, if the plugin has a properties "foo"
+			//		and "bar" and a method named "_setFooAttr", calling:
+			//	|	plugin.set("foo", "Howdy!");
+			//		would be equivalent to writing:
+			//	|	plugin._setFooAttr("Howdy!");
+			//		and:
+			//	|	plugin.set("bar", 3);
+			//		would be equivalent to writing:
+			//	|	plugin.bar = 3;
+			//
+			//		set() may also be called with a hash of name/value pairs, ex:
+			//	|	plugin.set({
+			//	|		foo: "Howdy",
+			//	|		bar: 3
+			//	|	})
+			//		This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
+			if(typeof name === "object"){
+				for(var x in name){
+					this.set(x, name[x]);
+				}
+				return this;
+			}
+			var names = this._getAttrNames(name);
+			if(this[names.s]){
+				// use the explicit setter
+				var result = this[names.s].apply(this, Array.prototype.slice.call(arguments, 1));
+			}else{
+				this._set(name, value);
+			}
+			return result || this;
+		},
+
+		get: function(name){
+			// summary:
+			//		Get a property from a plugin.
+			// name:
+			//		The property to get.
+			// description:
+			//		Get a named property from a plugin. The property may
+			//		potentially be retrieved via a getter method. If no getter is defined, this
+			//		just retrieves the object's property.
+			//		For example, if the plugin has a properties "foo"
+			//		and "bar" and a method named "_getFooAttr", calling:
+			//	|	plugin.get("foo");
+			//		would be equivalent to writing:
+			//	|	plugin._getFooAttr();
+			//		and:
+			//	|	plugin.get("bar");
+			//		would be equivalent to writing:
+			//	|	plugin.bar;
+			var names = this._getAttrNames(name);
+			return this[names.g] ? this[names.g]() : this[name];
+		},
+
+		_setDisabledAttr: function(disabled){
+			// summary:
+			//		Function to set the plugin state and call updateState to make sure the
+			//		button is updated appropriately.
+			this._set("disabled", disabled);
+			this.updateState();
+		},
+
+		_getAttrNames: function(name){
+			// summary:
+			//		Helper function for get() and set().
+			//		Caches attribute name values so we don't do the string ops every time.
+			// tags:
+			//		private
+
+			var apn = this._attrPairNames;
+			if(apn[name]){
+				return apn[name];
+			}
+			var uc = name.charAt(0).toUpperCase() + name.substr(1);
+			return (apn[name] = {
+				s: "_set" + uc + "Attr",
+				g: "_get" + uc + "Attr"
+			});
+		},
+
+		_set: function(/*String*/ name, /*anything*/ value){
+			// summary:
+			//		Helper function to set new value for specified attribute
+			this[name] = value;
 		}
-		return result || this;
-	},
-
-	get: function(name){
-		// summary:
-		//		Get a property from a plugin.
-		//	name:
-		//		The property to get.
-		// description:
-		//		Get a named property from a plugin. The property may
-		//		potentially be retrieved via a getter method. If no getter is defined, this
-		// 		just retrieves the object's property.
-		// 		For example, if the plugin has a properties "foo"
-		//		and "bar" and a method named "_getFooAttr", calling:
-		//	|	plugin.get("foo");
-		//		would be equivalent to writing:
-		//	|	plugin._getFooAttr();
-		//		and:
-		//	|	plugin.get("bar");
-		//		would be equivalent to writing:
-		//	|	plugin.bar;
-		var names = this._getAttrNames(name);
-		return this[names.g] ? this[names.g]() : this[name];
-	},
-
-	_setDisabledAttr: function(disabled){
-		// summary:
-		//		Function to set the plugin state and call updateState to make sure the
-		//		button is updated appropriately.
-		this.disabled = disabled;
-		this.updateState();
-	},
-
-	_getAttrNames: function(name){
-		// summary:
-		//		Helper function for get() and set().
-		//		Caches attribute name values so we don't do the string ops every time.
-		// tags:
-		//		private
-
-		var apn = this._attrPairNames;
-		if(apn[name]){ return apn[name]; }
-		var uc = name.charAt(0).toUpperCase() + name.substr(1);
-		return (apn[name] = {
-			s: "_set"+uc+"Attr",
-			g: "_get"+uc+"Attr"
-		});
-	},
-
-	_set: function(/*String*/ name, /*anything*/ value){
-		// summary:
-		//		Helper function to set new value for specified attribute
-		this[name] = value;
-	}
-});
-
-// Hash mapping plugin name to factory, used for registering plugins
-_Plugin.registry = {};
+	});
 
-return _Plugin;
+	// Hash mapping plugin name to factory, used for registering plugins
+	_Plugin.registry = {};
 
+	return _Plugin;
 });
diff --git a/dijit/_editor/html.js b/dijit/_editor/html.js
index ac35b1d..15fe894 100755
--- a/dijit/_editor/html.js
+++ b/dijit/_editor/html.js
@@ -1,194 +1,224 @@
 define([
-	"dojo/_base/lang", // lang.isString
-	"dojo/_base/sniff", // has("ie")
-	".."		// for exporting symbols to dijit._editor (remove for 2.0)
-], function(lang, has, dijit){
+	"dojo/_base/array",
+	"dojo/_base/lang", // lang.setObject
+	"dojo/sniff" // has("ie")
+], function(array, lang, has){
 
-// module:
-//		dijit/_editor/html
-// summary:
-//		Utility functions used by editor
+	// module:
+	//		dijit/_editor/html
 
-lang.getObject("_editor", true, dijit);
+	var exports = {
+		// summary:
+		//		HTML serialization utility functions used by editor
+	};
+	lang.setObject("dijit._editor.html", exports);
 
-dijit._editor.escapeXml=function(/*String*/str, /*Boolean?*/noSingleQuotes){
-	// summary:
-	//		Adds escape sequences for special characters in XML: &<>"'
-	//		Optionally skips escapes for single quotes
-	str = str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """);
-	if(!noSingleQuotes){
-		str = str.replace(/'/gm, "'");
-	}
-	return str; // string
-};
+	var escape = exports.escapeXml = function(/*String*/ str, /*Boolean?*/ noSingleQuotes){
+		// summary:
+		//		Adds escape sequences for special characters in XML: `&<>"'`.
+		//		Optionally skips escapes for single quotes.
+		str = str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """);
+		if(!noSingleQuotes){
+			str = str.replace(/'/gm, "'");
+		}
+		return str; // string
+	};
 
-dijit._editor.getNodeHtml=function(/* DomNode */node){
-	var output;
-	switch(node.nodeType){
-		case 1: //element node
-			var lName = node.nodeName.toLowerCase();
-			if(!lName || lName.charAt(0) == "/"){
-				// IE does some strange things with malformed HTML input, like
-				// treating a close tag </span> without an open tag <span>, as
-				// a new tag with tagName of /span.  Corrupts output HTML, remove
-				// them.  Other browsers don't prefix tags that way, so will
-				// never show up.
-				return "";
-			}
-			output = '<' + lName;
+	exports.getNodeHtml = function(/*DomNode*/ node){
+		// summary:
+		//		Return string representing HTML for node and it's children
+		var output = [];
+		exports.getNodeHtmlHelper(node, output);
+		return output.join("");
+	};
+
+	exports.getNodeHtmlHelper = function(/*DomNode*/ node, /*String[]*/ output){
+		// summary:
+		//		Pushes array of strings into output[] which represent HTML for node and it's children
+		switch(node.nodeType){
+			case 1: // element node
+				var lName = node.nodeName.toLowerCase();
+				if(!lName || lName.charAt(0) == "/"){
+					// IE does some strange things with malformed HTML input, like
+					// treating a close tag </span> without an open tag <span>, as
+					// a new tag with tagName of /span.  Corrupts output HTML, remove
+					// them.  Other browsers don't prefix tags that way, so will
+					// never show up.
+					return "";
+				}
+				output.push('<', lName);
 
-			//store the list of attributes and sort it to have the
-			//attributes appear in the dictionary order
-			var attrarray = [];
-			var attr;
-			if(has("ie") && node.outerHTML){
-				var s = node.outerHTML;
-				s = s.substr(0, s.indexOf('>'))
-					.replace(/(['"])[^"']*\1/g, ''); //to make the following regexp safe
-				var reg = /(\b\w+)\s?=/g;
-				var m, key;
-				while((m = reg.exec(s))){
-					key = m[1];
-					if(key.substr(0,3) != '_dj'){
-						if(key == 'src' || key == 'href'){
-							if(node.getAttribute('_djrealurl')){
-								attrarray.push([key,node.getAttribute('_djrealurl')]);
-								continue;
+				// store the list of attributes and sort it to have the
+				// attributes appear in the dictionary order
+				var attrarray = [], attrhash = {};
+				var attr;
+				if(has("dom-attributes-explicit") || has("dom-attributes-specified-flag")){
+					// IE8+ and all other browsers.
+					var i = 0;
+					while((attr = node.attributes[i++])){
+						// ignore all attributes starting with _dj which are
+						// internal temporary attributes used by the editor
+						var n = attr.name;
+						if(n.substr(0, 3) !== '_dj' &&
+							(!has("dom-attributes-specified-flag") || attr.specified) && !(n in attrhash)){    // workaround repeated attributes bug in IE8 (LinkDialog test)
+							var v = attr.value;
+							if(n == 'src' || n == 'href'){
+								if(node.getAttribute('_djrealurl')){
+									v = node.getAttribute('_djrealurl');
+								}
+							}
+							if(has("ie") === 8 && n === "style"){
+								v = v.replace("HEIGHT:", "height:").replace("WIDTH:", "width:");
 							}
+							attrarray.push([n, v]);
+							attrhash[n] = v;
 						}
-						var val, match;
-						switch(key){
-							case 'style':
-								val = node.style.cssText.toLowerCase();
-								break;
-							case 'class':
-								val = node.className;
-								break;
-							case 'width':
-								if(lName === "img"){
-									// This somehow gets lost on IE for IMG tags and the like
-									// and we have to find it in outerHTML, known IE oddity.
-									match=/width=(\S+)/i.exec(s);
-									if(match){
-										val = match[1];
+					}
+				}else{
+					// IE6-7 code path
+					var clone = /^input$|^img$/i.test(node.nodeName) ? node : node.cloneNode(false);
+					var s = clone.outerHTML;
+					// Split up and manage the attrs via regexp
+					// similar to prettyPrint attr logic.
+					var rgxp_attrsMatch = /[\w-]+=("[^"]*"|'[^']*'|\S*)/gi
+					var attrSplit = s.match(rgxp_attrsMatch);
+					s = s.substr(0, s.indexOf('>'));
+					array.forEach(attrSplit, function(attr){
+						if(attr){
+							var idx = attr.indexOf("=");
+							if(idx > 0){
+								var key = attr.substring(0, idx);
+								if(key.substr(0, 3) != '_dj'){
+									if(key == 'src' || key == 'href'){
+										if(node.getAttribute('_djrealurl')){
+											attrarray.push([key, node.getAttribute('_djrealurl')]);
+											return;
+										}
 									}
-									break;
-								}
-							case 'height':
-								if(lName === "img"){
-									// This somehow gets lost on IE for IMG tags and the like
-									// and we have to find it in outerHTML, known IE oddity.
-									match=/height=(\S+)/i.exec(s);
-									if(match){
-										val = match[1];
+									var val, match;
+									switch(key){
+										case 'style':
+											val = node.style.cssText.toLowerCase();
+											break;
+										case 'class':
+											val = node.className;
+											break;
+										case 'width':
+											if(lName === "img"){
+												// This somehow gets lost on IE for IMG tags and the like
+												// and we have to find it in outerHTML, known IE oddity.
+												match = /width=(\S+)/i.exec(s);
+												if(match){
+													val = match[1];
+												}
+												break;
+											}
+										case 'height':
+											if(lName === "img"){
+												// This somehow gets lost on IE for IMG tags and the like
+												// and we have to find it in outerHTML, known IE oddity.
+												match = /height=(\S+)/i.exec(s);
+												if(match){
+													val = match[1];
+												}
+												break;
+											}
+										default:
+											val = node.getAttribute(key);
+									}
+									if(val != null){
+										attrarray.push([key, val.toString()]);
 									}
-									break;
 								}
-							default:
-								val = node.getAttribute(key);
-						}
-						if(val != null){
-							attrarray.push([key, val.toString()]);
-						}
-					}
-				}
-			}else{
-				var i = 0;
-				while((attr = node.attributes[i++])){
-					//ignore all attributes starting with _dj which are
-					//internal temporary attributes used by the editor
-					var n = attr.name;
-					if(n.substr(0,3) != '_dj' /*&&
-						(attr.specified == undefined || attr.specified)*/){
-						var v = attr.value;
-						if(n == 'src' || n == 'href'){
-							if(node.getAttribute('_djrealurl')){
-								v = node.getAttribute('_djrealurl');
 							}
 						}
-						attrarray.push([n,v]);
-					}
+					}, this);
 				}
-			}
-			attrarray.sort(function(a,b){
-				return a[0] < b[0] ? -1 : (a[0] == b[0] ? 0 : 1);
-			});
-			var j = 0;
-			while((attr = attrarray[j++])){
-				output += ' ' + attr[0] + '="' +
-					(lang.isString(attr[1]) ? dijit._editor.escapeXml(attr[1], true) : attr[1]) + '"';
-			}
-			if(lName === "script"){
-				// Browsers handle script tags differently in how you get content,
-				// but innerHTML always seems to work, so insert its content that way
-				// Yes, it's bad to allow script tags in the editor code, but some people
-				// seem to want to do it, so we need to at least return them right.
-				// other plugins/filters can strip them.
-				output += '>' + node.innerHTML +'</' + lName + '>';
-			}else{
-				if(node.childNodes.length){
-					output += '>' + dijit._editor.getChildrenHtml(node)+'</' + lName +'>';
-				}else{
-					switch(lName){
-						case 'br':
-						case 'hr':
-						case 'img':
-						case 'input':
-						case 'base':
-						case 'meta':
-						case 'area':
-						case 'basefont':
-							// These should all be singly closed
-							output += ' />';
-							break;
-						default:
-							// Assume XML style separate closure for everything else.
-							output += '></' + lName + '>';
-					}
+				attrarray.sort(function(a, b){
+					return a[0] < b[0] ? -1 : (a[0] == b[0] ? 0 : 1);
+				});
+				var j = 0;
+				while((attr = attrarray[j++])){
+					output.push(' ', attr[0], '="',
+						(typeof attr[1] === "string" ? escape(attr[1], true) : attr[1]), '"');
 				}
-			}
-			break;
-		case 4: // cdata
-		case 3: // text
-			// FIXME:
-			output = dijit._editor.escapeXml(node.nodeValue, true);
-			break;
-		case 8: //comment
-			// FIXME:
-			output = '<!--' + dijit._editor.escapeXml(node.nodeValue, true) + '-->';
-			break;
-		default:
-			output = "<!-- Element not recognized - Type: " + node.nodeType + " Name: " + node.nodeName + "-->";
-	}
-	return output;
-};
+				switch(lName){
+					case 'br':
+					case 'hr':
+					case 'img':
+					case 'input':
+					case 'base':
+					case 'meta':
+					case 'area':
+					case 'basefont':
+						// These should all be singly closed
+						output.push(' />');
+						break;
+					case 'script':
+						// Browsers handle script tags differently in how you get content,
+						// but innerHTML always seems to work, so insert its content that way
+						// Yes, it's bad to allow script tags in the editor code, but some people
+						// seem to want to do it, so we need to at least return them right.
+						// other plugins/filters can strip them.
+						output.push('>', node.innerHTML, '</', lName, '>');
+						break;
+					default:
+						output.push('>');
+						if(node.hasChildNodes()){
+							exports.getChildrenHtmlHelper(node, output);
+						}
+						output.push('</', lName, '>');
+				}
+				break;
+			case 4: // cdata
+			case 3: // text
+				// FIXME:
+				output.push(escape(node.nodeValue, true));
+				break;
+			case 8: // comment
+				// FIXME:
+				output.push('<!--', escape(node.nodeValue, true), '-->');
+				break;
+			default:
+				output.push("<!-- Element not recognized - Type: ", node.nodeType, " Name: ", node.nodeName, "-->");
+		}
+	};
+
+	exports.getChildrenHtml = function(/*DomNode*/ node){
+		// summary:
+		//		Returns the html content of a DomNode's children
+		var output = [];
+		exports.getChildrenHtmlHelper(node, output);
+		return output.join("");
+	};
 
-dijit._editor.getChildrenHtml = function(/* DomNode */dom){
-	// summary:
-	//		Returns the html content of a DomNode and children
-	var out = "";
-	if(!dom){ return out; }
-	var nodes = dom["childNodes"] || dom;
+	exports.getChildrenHtmlHelper = function(/*DomNode*/ dom, /*String[]*/ output){
+		// summary:
+		//		Pushes the html content of a DomNode's children into out[]
 
-	//IE issue.
-	//If we have an actual node we can check parent relationships on for IE,
-	//We should check, as IE sometimes builds invalid DOMS.  If no parent, we can't check
-	//And should just process it and hope for the best.
-	var checkParent = !has("ie") || nodes !== dom;
+		if(!dom){
+			return;
+		}
+		var nodes = dom["childNodes"] || dom;
+
+		// IE issue.
+		// If we have an actual node we can check parent relationships on for IE,
+		// We should check, as IE sometimes builds invalid DOMS.  If no parent, we can't check
+		// And should just process it and hope for the best.
+		var checkParent = !has("ie") || nodes !== dom;
 
-	var node, i = 0;
-	while((node = nodes[i++])){
-		//IE is broken.  DOMs are supposed to be a tree.  But in the case of malformed HTML, IE generates a graph
-		//meaning one node ends up with multiple references (multiple parents).  This is totally wrong and invalid, but
-		//such is what it is.  We have to keep track and check for this because otherise the source output HTML will have dups.
-		//No other browser generates a graph.  Leave it to IE to break a fundamental DOM rule.  So, we check the parent if we can
-		//If we can't, nothing more we can do other than walk it.
-		if(!checkParent || node.parentNode == dom){
-			out += dijit._editor.getNodeHtml(node);
+		var node, i = 0;
+		while((node = nodes[i++])){
+			// IE is broken.  DOMs are supposed to be a tree.  But in the case of malformed HTML, IE generates a graph
+			// meaning one node ends up with multiple references (multiple parents).  This is totally wrong and invalid, but
+			// such is what it is.  We have to keep track and check for this because otherwise the source output HTML will have dups.
+			// No other browser generates a graph.  Leave it to IE to break a fundamental DOM rule.  So, we check the parent if we can
+			// If we can't, nothing more we can do other than walk it.
+			if(!checkParent || node.parentNode == dom){
+				exports.getNodeHtmlHelper(node, output);
+			}
 		}
-	}
-	return out; // String
-};
+	};
 
-return dijit._editor;
+	return exports;
 });
diff --git a/dijit/_editor/nls/FontChoice.js b/dijit/_editor/nls/FontChoice.js
index c920f0f..f2be183 100644
--- a/dijit/_editor/nls/FontChoice.js
+++ b/dijit/_editor/nls/FontChoice.js
@@ -30,6 +30,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -57,6 +58,7 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dijit/_editor/nls/LinkDialog.js b/dijit/_editor/nls/LinkDialog.js
index 00360ea..716d1a0 100644
--- a/dijit/_editor/nls/LinkDialog.js
+++ b/dijit/_editor/nls/LinkDialog.js
@@ -16,6 +16,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -43,6 +44,7 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dijit/_editor/nls/ar/FontChoice.js b/dijit/_editor/nls/ar/FontChoice.js
index a2ee528..e67bb1a 100644
--- a/dijit/_editor/nls/ar/FontChoice.js
+++ b/dijit/_editor/nls/ar/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "الحجم",
 	fontName: "طاقم طباعة",
 	formatBlock: "النسق",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "أحادي المسافة",
 	cursive: "كتابة بحروف متصلة",
 	fantasy: "خيالي",
-
 	noFormat: "‏لا شيء‏",
 	p: "فقرة",
 	h1: "عنوان",
 	h2: "عنوان فرعي",
 	h3: "فرعي-عنوان فرعي",
 	pre: "منسق بصفة مسبقة",
-
 	1: "صغير جدا جدا",
 	2: "صغير جدا",
 	3: "صغير",
@@ -26,5 +22,4 @@ define(
 	6: "كبير جدا",
 	7: "كبير جدا جدا"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ar/LinkDialog.js b/dijit/_editor/nls/ar/LinkDialog.js
index ad64eb3..bc29ecf 100644
--- a/dijit/_editor/nls/ar/LinkDialog.js
+++ b/dijit/_editor/nls/ar/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "خصائص الوصلة",
 	insertImageTitle: "خصائص الصورة",
@@ -12,6 +11,4 @@ define(
 	topWindow: "النافذة العلوية",
 	newWindow: "‏نافذة جديدة‏"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ar/commands.js b/dijit/_editor/nls/ar/commands.js
index 0713041..1c3afaf 100644
--- a/dijit/_editor/nls/ar/commands.js
+++ b/dijit/_editor/nls/ar/commands.js
@@ -1,28 +1,27 @@
 define(
-//begin v1.x content
 ({
-	'bold': 'عري~ض',
+	'bold': 'عريض',
 	'copy': 'نسخ',
 	'cut': 'قص',
 	'delete': 'حذف',
-	'indent': 'ازاحة للداخل',
+	'indent': '‏ازاحة للداخل‏',
 	'insertHorizontalRule': 'مسطرة أفقية',
 	'insertOrderedList': '‏كشف مرقم‏',
 	'insertUnorderedList': 'كشف نقطي',
-	'italic': '~مائل',
+	'italic': 'مائل',
 	'justifyCenter': 'محاذاة في الوسط',
 	'justifyFull': 'ضبط',
 	'justifyLeft': 'محاذاة الى اليسار',
 	'justifyRight': 'محاذاة الى اليمين',
 	'outdent': 'ازاحة للخارج',
 	'paste': 'لصق',
-	'redo': '‏اعادة‏',
+	'redo': 'اعادة',
 	'removeFormat': 'ازالة النسق',
-	'selectAll': '‏اختيار كل‏',
+	'selectAll': 'اختيار كل',
 	'strikethrough': 'تشطيب',
 	'subscript': 'رمز سفلي',
 	'superscript': 'رمز علوي',
-	'underline': '~تسطير',
+	'underline': 'تسطير',
 	'undo': 'تراجع',
 	'unlink': 'ازالة وصلة',
 	'createLink': 'تكوين وصلة',
@@ -41,14 +40,12 @@ define(
 	'fontName': 'اسم طاقم الطباعة',
 	'tabIndent': 'ازاحة علامة الجدولة للداخل',
 	"fullScreen": "تبديل  الشاشة الكاملة",
-	"viewSource": "مشاهدة مصدر HTML",
-	"print": "طباعة",
+	"viewSource": "\u202bمشاهدة مصدر HTML\u202c",
+	"print": "‏طباعة‏",
 	"newPage": "صفحة جديدة",
 	/* Error messages */
 	'systemShortcut': 'يكون التصرف "${0}" متاحا فقط ببرنامج الاستعراض الخاص بك باستخدام المسار المختصر للوحة المفاتيح.  استخدم ${1}.',
 	'ctrlKey':'ctrl+${0}',
 	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/az/FontChoice.js b/dijit/_editor/nls/az/FontChoice.js
index b0538cb..508c925 100644
--- a/dijit/_editor/nls/az/FontChoice.js
+++ b/dijit/_editor/nls/az/FontChoice.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"1" : "xx-kiçik",
 	"2" : "x-kiçik",
@@ -23,5 +22,4 @@ define(
 	"cursive" : "Əl yazısı",
 	"noFormat" : "Heç biri"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/az/LinkDialog.js b/dijit/_editor/nls/az/LinkDialog.js
index 2ddab8d..3ff1be6 100644
--- a/dijit/_editor/nls/az/LinkDialog.js
+++ b/dijit/_editor/nls/az/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"text" : "Yazı:",
 	"insertImageTitle" : "Şəkil başlığı əlavə et",
@@ -12,5 +11,4 @@ define(
 	"currentWindow" : "Hazırki pəncərə",
 	"url" : "URL:"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/az/commands.js b/dijit/_editor/nls/az/commands.js
index 703a8e7..500c526 100644
--- a/dijit/_editor/nls/az/commands.js
+++ b/dijit/_editor/nls/az/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"removeFormat" : "Formatı Sil",
 	"copy" :"Köçür",
@@ -48,5 +47,4 @@ define(
 	"appleKey" : "⌘${0}",
 	"ctrlKey" : "ctrl+${0}"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/bg/FontChoice.js b/dijit/_editor/nls/bg/FontChoice.js
new file mode 100644
index 0000000..29721e7
--- /dev/null
+++ b/dijit/_editor/nls/bg/FontChoice.js
@@ -0,0 +1,25 @@
+define(
+({
+	fontSize: "Размер",
+	fontName: "Шрифт",
+	formatBlock: "Формат",
+	serif: "serif",
+	"sans-serif": "sans-serif",
+	monospace: "monospace",
+	cursive: "cursive",
+	fantasy: "fantasy",
+	noFormat: "Няма",
+	p: "Параграф",
+	h1: "Заглавна част",
+	h2: "Подзаглавие",
+	h3: "Под-подзаглавие",
+	pre: "Предварително форматиран",
+	1: "xx-малък",
+	2: "x-малък",
+	3: "малък",
+	4: "среден",
+	5: "голям",
+	6: "x-голям",
+	7: "xx-голям"
+})
+);
diff --git a/dijit/_editor/nls/bg/LinkDialog.js b/dijit/_editor/nls/bg/LinkDialog.js
new file mode 100644
index 0000000..9d92a01
--- /dev/null
+++ b/dijit/_editor/nls/bg/LinkDialog.js
@@ -0,0 +1,14 @@
+define(
+({
+	createLinkTitle: "Свойства на връзка",
+	insertImageTitle: "Свойства на изображение",
+	url: "URL:",
+	text: "Описание:",
+	target: "Цел:",
+	set: "Задай",
+	currentWindow: "Текущ прозорец",
+	parentWindow: "Родителски прозорец",
+	topWindow: "Най-горен прозорец",
+	newWindow: "Нов прозорец"
+})
+);
diff --git a/dijit/_editor/nls/bg/commands.js b/dijit/_editor/nls/bg/commands.js
new file mode 100644
index 0000000..d85cc08
--- /dev/null
+++ b/dijit/_editor/nls/bg/commands.js
@@ -0,0 +1,51 @@
+define(
+({
+	'bold': 'Получерен',
+	'copy': 'Копирай',
+	'cut': 'Изрежи',
+	'delete': 'Изтрий',
+	'indent': 'Отстъп',
+	'insertHorizontalRule': 'Хоризонтална линия',
+	'insertOrderedList': 'Номериран списък',
+	'insertUnorderedList': 'Списък с водещи символи',
+	'italic': 'Курсив',
+	'justifyCenter': 'Центрирано подравняване',
+	'justifyFull': 'Двустранно подравняване',
+	'justifyLeft': 'Подравняване отляво',
+	'justifyRight': 'Подравняване отдясно',
+	'outdent': 'Обратен отстъп',
+	'paste': 'Постави',
+	'redo': 'Върни',
+	'removeFormat': 'Премахни форматирането',
+	'selectAll': 'Избери всички',
+	'strikethrough': 'Зачеркване',
+	'subscript': 'Долен индекс',
+	'superscript': 'Горен индекс',
+	'underline': 'Подчертаване',
+	'undo': 'Отмени',
+	'unlink': 'Премахване на връзка',
+	'createLink': 'Създаване на връзка',
+	'toggleDir': 'Превключване на посока',
+	'insertImage': 'Вмъкване на изображение',
+	'insertTable': 'Вмъкване/редактиране на таблица',
+	'toggleTableBorder': 'Превключване на граница на таблица',
+	'deleteTable': 'Изтриване на таблица',
+	'tableProp': 'Свойство на таблица',
+	'htmlToggle': 'HTML източник',
+	'foreColor': 'Цвят на предния план',
+	'hiliteColor': 'Цвят на фон',
+	'plainFormatBlock': 'Стил на абзац',
+	'formatBlock': 'Стил на абзац',
+	'fontSize': 'Размер на шрифт',
+	'fontName': 'Име на шрифт',
+	'tabIndent': 'Отстъп на табулация',
+	"fullScreen": "Превключване на цял екран",
+	"viewSource": "Преглед на HTML източник",
+	"print": "Отпечатаване",
+	"newPage": "Нова страница",
+	/* Error messages */
+	'systemShortcut': 'Действие "${0}" е достъпно във Вашия браузър само чрез използване на бърза клавишна комбинация. Използвайте ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
+})
+);
diff --git a/dijit/_editor/nls/ca/FontChoice.js b/dijit/_editor/nls/ca/FontChoice.js
index bf116e7..bc49d81 100644
--- a/dijit/_editor/nls/ca/FontChoice.js
+++ b/dijit/_editor/nls/ca/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Mida",
 	fontName: "Tipus de lletra",
 	formatBlock: "Format",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monoespai",
 	cursive: "Cursiva",
 	fantasy: "Fantasia",
-
 	noFormat: "Cap",
 	p: "Paràgraf",
 	h1: "Títol",
 	h2: "Subtítol",
 	h3: "Subsubtítol",
 	pre: "Format previ",
-
 	1: "xx-petit",
 	2: "x-petit",
 	3: "petit",
@@ -26,5 +22,4 @@ define(
 	6: "x-gran",
 	7: "xx-gran"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ca/LinkDialog.js b/dijit/_editor/nls/ca/LinkDialog.js
index 3c22820..f81cab3 100644
--- a/dijit/_editor/nls/ca/LinkDialog.js
+++ b/dijit/_editor/nls/ca/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Propietats de l\'enllaç",
 	insertImageTitle: "Propietats de la imatge",
@@ -12,5 +11,4 @@ define(
 	topWindow: "Finestra superior",
 	newWindow: "Finestra nova"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ca/commands.js b/dijit/_editor/nls/ca/commands.js
index 7ee2ae1..c1e6d03 100644
--- a/dijit/_editor/nls/ca/commands.js
+++ b/dijit/_editor/nls/ca/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Negreta',
 	'copy': 'Copia',
@@ -10,11 +9,11 @@ define(
 	'insertOrderedList': 'Llista numerada',
 	'insertUnorderedList': 'Llista de vinyetes',
 	'italic': 'Cursiva',
-	'justifyCenter': 'Centra',
+	'justifyCenter': 'Alineació centrada',
 	'justifyFull': 'Justifica',
-	'justifyLeft': 'Alinea a l\'esquerra',
-	'justifyRight': 'Alinea a la dreta',
-	'outdent': 'Sagna a l\'esquerra',
+	'justifyLeft': 'Alineació a l\'esquerra',
+	'justifyRight': 'Alineació a la dreta',
+	'outdent': 'Sagnat a l\'esquerra',
 	'paste': 'Enganxa',
 	'redo': 'Refés',
 	'removeFormat': 'Elimina el format',
@@ -37,7 +36,7 @@ define(
 	'hiliteColor': 'Color de fons',
 	'plainFormatBlock': 'Estil de paràgraf',
 	'formatBlock': 'Estil de paràgraf',
-	'fontSize': 'Cos de la lletra',
+	'fontSize': 'Mida del tipus de lletra',
 	'fontName': 'Nom del tipus de lletra',
 	'tabIndent': 'Sagnat',
 	"fullScreen": "Commuta pantalla completa",
@@ -46,7 +45,7 @@ define(
 	"newPage": "Pàgina nova",
 	/* Error messages */
 	'systemShortcut': 'L\'acció "${0}" és l\'única disponible al navegador utilitzant una drecera del teclat. Utilitzeu ${1}.',
-	'ctrlKey':'control+${0}'
+	'ctrlKey':'control+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/commands.js b/dijit/_editor/nls/commands.js
index bf6a53d..8fa6f43 100644
--- a/dijit/_editor/nls/commands.js
+++ b/dijit/_editor/nls/commands.js
@@ -53,6 +53,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -80,6 +81,7 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dijit/_editor/nls/cs/FontChoice.js b/dijit/_editor/nls/cs/FontChoice.js
index 722f035..5ce5e3b 100644
--- a/dijit/_editor/nls/cs/FontChoice.js
+++ b/dijit/_editor/nls/cs/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Velikost",
 	fontName: "Písmo",
 	formatBlock: "Formát",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "cursive",
 	fantasy: "fantasy",
-
 	noFormat: "Žádný",
 	p: "Odstavec",
 	h1: "Nadpis",
 	h2: "Podnadpis",
 	h3: "Podnadpis 2",
 	pre: "Předformátované",
-
 	1: "extra malé",
 	2: "velmi malé",
 	3: "malé",
@@ -26,5 +22,4 @@ define(
 	6: "velmi velké",
 	7: "extra velké"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/cs/LinkDialog.js b/dijit/_editor/nls/cs/LinkDialog.js
index 7a6acc3..3aea5c8 100644
--- a/dijit/_editor/nls/cs/LinkDialog.js
+++ b/dijit/_editor/nls/cs/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Vlastnosti odkazu",
 	insertImageTitle: "Vlastnosti obrázku",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Okno nejvyšší úrovně",
 	newWindow: "Nové okno"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/cs/commands.js b/dijit/_editor/nls/cs/commands.js
index 5d56608..911f6c6 100644
--- a/dijit/_editor/nls/cs/commands.js
+++ b/dijit/_editor/nls/cs/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Tučné',
 	'copy': 'Kopírovat',
@@ -40,12 +39,13 @@ define(
 	'fontSize': 'Velikost písma',
 	'fontName': 'Název písma',
 	'tabIndent': 'Odsazení tabulátoru',
-	"fullScreen": "Přepnout celou obrazovku",
-	"viewSource": "Zobrazit zdroj HTML",
+	"fullScreen": "Přepnout režim celé obrazovky",
+	"viewSource": "Zobrazit zdroj ve formátu HTML",
 	"print": "Tisk",
 	"newPage": "Nová stránka",
 	/* Error messages */
-	'systemShortcut': 'Akce "${0}" je v prohlížeči dostupná pouze prostřednictvím klávesové zkratky. Použijte klávesovou zkratku ${1}.'
+	'systemShortcut': 'Akce "${0}" je v prohlížeči dostupná pouze prostřednictvím klávesové zkratky. Použijte klávesovou zkratku ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/da/FontChoice.js b/dijit/_editor/nls/da/FontChoice.js
index ab382e4..d287417 100644
--- a/dijit/_editor/nls/da/FontChoice.js
+++ b/dijit/_editor/nls/da/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Størrelse",
 	fontName: "Skrifttype",
 	formatBlock: "Format",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "kursiv",
 	fantasy: "fantasy",
-
 	noFormat: "Ingen",
 	p: "Afsnit",
 	h1: "Overskrift",
 	h2: "Underoverskrift",
 	h3: "Underunderoverskrift",
 	pre: "Forudformateret",
-
 	1: "xx-small",
 	2: "x-small",
 	3: "small",
@@ -26,5 +22,4 @@ define(
 	6: "x-large",
 	7: "xx-large"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/da/LinkDialog.js b/dijit/_editor/nls/da/LinkDialog.js
index 2b405ea..ab136cf 100644
--- a/dijit/_editor/nls/da/LinkDialog.js
+++ b/dijit/_editor/nls/da/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Linkegenskaber",
 	insertImageTitle: "Billedegenskaber",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Øverste vindue",
 	newWindow: "Nyt vindue"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/da/commands.js b/dijit/_editor/nls/da/commands.js
index 0d21af9..06a6042 100644
--- a/dijit/_editor/nls/da/commands.js
+++ b/dijit/_editor/nls/da/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Fed',
 	'copy': 'Kopiér',
@@ -39,13 +38,14 @@ define(
 	'formatBlock': 'Afsnitstypografi',
 	'fontSize': 'Skriftstørrelse',
 	'fontName': 'Skriftnavn',
-	'tabIndent': 'Indrykning med tabulator',
-	"fullScreen": "Aktivér/deaktivér fuldskærm",
+	'tabIndent': 'Tabulatorindrykning',
+	"fullScreen": "Fuld skærm til/fra",
 	"viewSource": "Vis HTML-kilde",
 	"print": "Udskriv",
 	"newPage": "Ny side",
 	/* Error messages */
-	'systemShortcut': 'Funktionen "${0}" kan kun bruges i din browser med en tastaturgenvej. Brug ${1}.'
+	'systemShortcut': 'Funktionen "${0}" kan kun bruges i din browser med en tastaturgenvej. Brug ${1}.',
+	'ctrlKey':'Ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/de/FontChoice.js b/dijit/_editor/nls/de/FontChoice.js
index db1d989..9bdc80c 100644
--- a/dijit/_editor/nls/de/FontChoice.js
+++ b/dijit/_editor/nls/de/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Größe",
 	fontName: "Schriftart",
 	formatBlock: "Format",
-
 	serif: "Serife",
 	"sans-serif": "Serifenlos",
 	monospace: "Monospaceschrift",
 	cursive: "Kursiv",
 	fantasy: "Fantasie",
-
 	noFormat: "Keine Angabe",
 	p: "Absatz",
 	h1: "Überschrift",
 	h2: "Unterüberschrift",
 	h3: "Unterunterüberschrift",
 	pre: "Vorformatiert",
-
 	1: "XXS",
 	2: "XS",
 	3: "S",
@@ -26,5 +22,4 @@ define(
 	6: "XL",
 	7: "XXL"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/de/LinkDialog.js b/dijit/_editor/nls/de/LinkDialog.js
index cf5209d..5d0d963 100644
--- a/dijit/_editor/nls/de/LinkDialog.js
+++ b/dijit/_editor/nls/de/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Linkeigenschaften",
 	insertImageTitle: "Grafikeigenschaften",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Aktives Fenster",
 	newWindow: "Neues Fenster"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/de/commands.js b/dijit/_editor/nls/de/commands.js
index 5f68329..9c44295 100755
--- a/dijit/_editor/nls/de/commands.js
+++ b/dijit/_editor/nls/de/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Fett',
 	'copy': 'Kopieren',
@@ -16,7 +15,7 @@ define(
 	'justifyRight': 'Rechtsbündig',
 	'outdent': 'Ausrücken',
 	'paste': 'Einfügen',
-	'redo': 'Wiederherstellen',
+	'redo': 'Wiederholen',
 	'removeFormat': 'Formatierung entfernen',
 	'selectAll': 'Alles auswählen',
 	'strikethrough': 'Durchgestrichen',
@@ -26,7 +25,7 @@ define(
 	'undo': 'Rückgängig',
 	'unlink': 'Link entfernen',
 	'createLink': 'Link erstellen',
-	'toggleDir': 'Wechselrichtung',
+	'toggleDir': 'Richtung wechseln',
 	'insertImage': 'Grafik einfügen',
 	'insertTable': 'Tabelle einfügen/bearbeiten',
 	'toggleTableBorder': 'Tabellenumrandung ein-/ausschalten',
@@ -39,15 +38,14 @@ define(
 	'formatBlock': 'Absatzstil',
 	'fontSize': 'Schriftgröße',
 	'fontName': 'Schriftartname',
-	'tabIndent': 'Tabulatoreinrückung',
+	'tabIndent': 'Registerkarteneinrückung',
 	"fullScreen": "Gesamtanzeige",
 	"viewSource": "HTML-Quelle",
 	"print": "Drucken",
 	"newPage": "Neue Seite",
 	/* Error messages */
 	'systemShortcut': 'Die Aktion "${0}" ist nur über einen Direktaufruf in Ihrem Browser verfügbar. Verwenden Sie ${1}.',
-	'ctrlKey':'Strg+${0}'
+	'ctrlKey':'Strg+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/el/FontChoice.js b/dijit/_editor/nls/el/FontChoice.js
index c58d50a..1d978cc 100644
--- a/dijit/_editor/nls/el/FontChoice.js
+++ b/dijit/_editor/nls/el/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Μέγεθος",
 	fontName: "Γραμματοσειρά",
 	formatBlock: "Μορφή",
-
 	serif: "με πατούρες (serif)",
 	"sans-serif": "χωρίς πατούρες (sans-serif)",
 	monospace: "σταθερού πλάτους",
 	cursive: "πλάγιοι",
 	fantasy: "φαντασίας",
-
 	noFormat: "Χωρίς",
 	p: "Παράγραφος",
 	h1: "Επικεφαλίδα",
 	h2: "Δευτερεύουσα επικεφαλίδα",
 	h3: "Δευτερεύουσα επικεφαλίδα τρίτου επιπέδου",
 	pre: "Προ-μορφοποιημένο",
-
 	1: "xx-μικρά",
 	2: "x-μικρά",
 	3: "μικρά",
@@ -26,5 +22,4 @@ define(
 	6: "x-μεγάλα",
 	7: "xx-μεγάλα"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/el/LinkDialog.js b/dijit/_editor/nls/el/LinkDialog.js
index 330fb96..d6e72de 100644
--- a/dijit/_editor/nls/el/LinkDialog.js
+++ b/dijit/_editor/nls/el/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Ιδιότητες σύνδεσης",
 	insertImageTitle: "Ιδιότητες εικόνας",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Παράθυρο σε πρώτο πλάνο",
 	newWindow: "Νέο παράθυρο"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/el/commands.js b/dijit/_editor/nls/el/commands.js
index 26574f5..52b2353 100644
--- a/dijit/_editor/nls/el/commands.js
+++ b/dijit/_editor/nls/el/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Έντονα',
 	'copy': 'Αντιγραφή',
@@ -24,8 +23,8 @@ define(
 	'superscript': 'Εκθέτης',
 	'underline': 'Υπογράμμιση',
 	'undo': 'Αναίρεση',
-	'unlink': 'Αφαίρεση σύνδεσης',
-	'createLink': 'Δημιουργία σύνδεσης',
+	'unlink': 'Αφαίρεση διασύνδεσης',
+	'createLink': 'Δημιουργία διασύνδεσης',
 	'toggleDir': 'Εναλλαγή κατεύθυνσης',
 	'insertImage': 'Εισαγωγή εικόνας',
 	'insertTable': 'Εισαγωγή/Τροποποίηση πίνακα',
@@ -45,8 +44,8 @@ define(
 	"print": "Εκτύπωση",
 	"newPage": "Νέα σελίδα",
 	/* Error messages */
-	'systemShortcut': 'Σε αυτό το πρόγραμμα πλοήγησης, η ενέργεια "${0}" είναι διαθέσιμη μόνο με τη χρήση μιας συντόμευσης πληκτρολογίου. Χρησιμοποιήστε τη συντόμευση ${1}.'
+	'systemShortcut': 'Η ενέργεια "${0}" είναι διαθέσιμη στο πρόγραμμα πλοήγησης μόνο μέσω μιας συντόμευσης πληκτρολογίου. Χρησιμοποιήστε τη συντόμευση ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/es/FontChoice.js b/dijit/_editor/nls/es/FontChoice.js
index 8e2f83f..95915aa 100644
--- a/dijit/_editor/nls/es/FontChoice.js
+++ b/dijit/_editor/nls/es/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Tamaño",
 	fontName: "Font",
 	formatBlock: "Formato",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "espacio sencillo",
 	cursive: "cursiva",
 	fantasy: "fantasía",
-
 	noFormat: "Ninguno",
 	p: "Párrafo",
 	h1: "Cabecera",
 	h2: "Subcabecera",
 	h3: "Sub-subcabecera",
 	pre: "Preformateado",
-
 	1: "xx-pequeño",
 	2: "x-pequeño",
 	3: "pequeño",
@@ -26,5 +22,4 @@ define(
 	6: "x-grande",
 	7: "xx-grande"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/es/LinkDialog.js b/dijit/_editor/nls/es/LinkDialog.js
index 986d4f2..d59bba9 100644
--- a/dijit/_editor/nls/es/LinkDialog.js
+++ b/dijit/_editor/nls/es/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Propiedades del enlace",
 	insertImageTitle: "Propiedades de la imagen",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Ventana superior",
 	newWindow: "Nueva ventana"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/es/commands.js b/dijit/_editor/nls/es/commands.js
index e6b16f2..27d4f62 100644
--- a/dijit/_editor/nls/es/commands.js
+++ b/dijit/_editor/nls/es/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Negrita',
 	'copy': 'Copiar',
@@ -46,8 +45,7 @@ define(
 	"newPage": "Nueva página",
 	/* Error messages */
 	'systemShortcut': 'La acción "${0}" sólo está disponible en su navegador mediante un atajo de teclado. Utilice ${1}.',
-	'ctrlKey':'control+${0}'
+	'ctrlKey':'control+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/fi/FontChoice.js b/dijit/_editor/nls/fi/FontChoice.js
index 06e0c64..f274bb1 100644
--- a/dijit/_editor/nls/fi/FontChoice.js
+++ b/dijit/_editor/nls/fi/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Koko",
 	fontName: "Fontti",
-	formatBlock: "Muoto",
-
+	formatBlock: "Muotoile",
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "cursive",
 	fantasy: "fantasy",
-
 	noFormat: "Ei mitään",
 	p: "Kappale",
 	h1: "Otsikko",
 	h2: "Alatason otsikko",
 	h3: "Alimman tason otsikko",
 	pre: "Esimuotoiltu",
-
 	1: "xx-small",
 	2: "x-small",
 	3: "small",
@@ -26,5 +22,4 @@ define(
 	6: "x-large",
 	7: "xx-large"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/fi/LinkDialog.js b/dijit/_editor/nls/fi/LinkDialog.js
index db5626c..62bd3fd 100644
--- a/dijit/_editor/nls/fi/LinkDialog.js
+++ b/dijit/_editor/nls/fi/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Linkin ominaisuudet",
 	insertImageTitle: "Kuvan ominaisuudet",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Päällimmäinen ikkuna",
 	newWindow: "Uusi ikkuna"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/fi/commands.js b/dijit/_editor/nls/fi/commands.js
index 517afd1..c1d08f1 100644
--- a/dijit/_editor/nls/fi/commands.js
+++ b/dijit/_editor/nls/fi/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Lihavointi',
 	'copy': 'Kopioi',
@@ -20,8 +19,8 @@ define(
 	'removeFormat': 'Poista muotoilu',
 	'selectAll': 'Valitse kaikki',
 	'strikethrough': 'Yliviivaus',
-	'subscript': 'Alaindeksi',
-	'superscript': 'Yläindeksi',
+	'subscript': 'Alennettu',
+	'superscript': 'Korotettu',
 	'underline': 'Alleviivaus',
 	'undo': 'Kumoa',
 	'unlink': 'Poista linkki',
@@ -37,7 +36,7 @@ define(
 	'hiliteColor': 'Taustaväri',
 	'plainFormatBlock': 'Kappaletyyli',
 	'formatBlock': 'Kappaletyyli',
-	'fontSize': 'Fontin koko',
+	'fontSize': 'Fonttikoko',
 	'fontName': 'Fontin nimi',
 	'tabIndent': 'Sarkainsisennys',
 	"fullScreen": "Vaihda koko näyttö",
@@ -45,8 +44,8 @@ define(
 	"print": "Tulosta",
 	"newPage": "Uusi sivu",
 	/* Error messages */
-	'systemShortcut': 'Toiminto "${0}" on käytettävissä selaimessa vain näppäimistön pikatoiminnolla. Käytä seuraavaa: ${1}.'
+	'systemShortcut': 'Toiminto "${0}" on käytettävissä selaimessa vain näppäimistön pikatoiminnolla. Käytä seuraavaa: ${1}.',
+	'ctrlKey':'Ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/fr/FontChoice.js b/dijit/_editor/nls/fr/FontChoice.js
index bf77dd7..fb38826 100644
--- a/dijit/_editor/nls/fr/FontChoice.js
+++ b/dijit/_editor/nls/fr/FontChoice.js
@@ -1,30 +1,25 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Taille",
 	fontName: "Police",
 	formatBlock: "Mise en forme",
-
 	serif: "serif",
 	"sans-serif": "sans serif",
 	monospace: "espacement fixe",
 	cursive: "cursive",
 	fantasy: "fantaisie",
-
 	noFormat: "Néant",
 	p: "Paragraphe",
 	h1: "En-tête",
 	h2: "Sous-en-tête",
 	h3: "Sous-sous-en-tête",
 	pre: "Pré-mise en forme",
-
-	1: "xxs",
-	2: "xs",
-	3: "s",
-	4: "m",
-	5: "l",
-	6: "xl",
-	7: "xxl"
+	1: "très très petite",
+	2: "très petite",
+	3: "petite",
+	4: "moyenne",
+	5: "grande",
+	6: "très grande",
+	7: "très très grande"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/fr/LinkDialog.js b/dijit/_editor/nls/fr/LinkDialog.js
index 8ae89c1..5e78969 100644
--- a/dijit/_editor/nls/fr/LinkDialog.js
+++ b/dijit/_editor/nls/fr/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Propriétés du lien",
 	insertImageTitle: "Propriétés de l'image",
@@ -12,5 +11,4 @@ define(
 	topWindow: "Fenêtre supérieure",
 	newWindow: "Nouvelle fenêtre"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/fr/commands.js b/dijit/_editor/nls/fr/commands.js
index 587a727..1c9a5f6 100644
--- a/dijit/_editor/nls/fr/commands.js
+++ b/dijit/_editor/nls/fr/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Gras',
 	'copy': 'Copier',
@@ -33,8 +32,8 @@ define(
 	'deleteTable': 'Supprimer le tableau',
 	'tableProp': 'Propriété du tableau',
 	'htmlToggle': 'Source HTML',
-	'foreColor': 'Couleur d\'avant-plan',
-	'hiliteColor': 'Couleur d\'arrière-plan',
+	'foreColor': 'Couleur avant-plan',
+	'hiliteColor': 'Couleur arrière-plan',
 	'plainFormatBlock': 'Style de paragraphe',
 	'formatBlock': 'Style de paragraphe',
 	'fontSize': 'Taille de police',
@@ -45,7 +44,8 @@ define(
 	"print": "Imprimer",
 	"newPage": "Nouvelle page",
 	/* Error messages */
-	'systemShortcut': 'L\'action "${0}" est disponible dans votre navigateur uniquement, par le biais d\'un raccourci-clavier. Utilisez ${1}.'
+	'systemShortcut': 'Action "${0}" uniquement disponible dans votre navigateur via un raccourci clavier. Utilisez ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/he/FontChoice.js b/dijit/_editor/nls/he/FontChoice.js
index 72363d6..bd678a5 100644
--- a/dijit/_editor/nls/he/FontChoice.js
+++ b/dijit/_editor/nls/he/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "גודל",
 	fontName: "גופן",
 	formatBlock: "עיצוב",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "cursive",
 	fantasy: "fantasy",
-
 	noFormat: "ללא ",
 	p: "פיסקה",
 	h1: "כותרת",
 	h2: "תת-כותרת",
 	h3: "תת-תת-כותרת",
 	pre: "מעוצב מראש",
-
 	1: "קטן ביות",
 	2: "קטן מאוד",
 	3: "קטן",
@@ -26,5 +22,4 @@ define(
 	6: "גדול מאוד",
 	7: "גדול ביותר"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/he/LinkDialog.js b/dijit/_editor/nls/he/LinkDialog.js
index 1a16944..e73470b 100644
--- a/dijit/_editor/nls/he/LinkDialog.js
+++ b/dijit/_editor/nls/he/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "תכונות קישור",
 	insertImageTitle: "תכונות תמונה",
@@ -12,6 +11,4 @@ define(
 	topWindow: "חלון עליון",
 	newWindow: "חלון חדש"
 })
-//end v1.x content
 );
-
diff --git a/dijit/_editor/nls/he/commands.js b/dijit/_editor/nls/he/commands.js
index 69d2a74..d403a19 100644
--- a/dijit/_editor/nls/he/commands.js
+++ b/dijit/_editor/nls/he/commands.js
@@ -1,19 +1,18 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'מודגש',
-	'copy': 'עותק',
+	'copy': 'העתקה',
 	'cut': 'גזירה',
 	'delete': 'מחיקה',
 	'indent': 'הגדלת כניסה',
 	'insertHorizontalRule': 'קו אופקי',
-	'insertOrderedList': 'רשימה ממוספרת',
+	'insertOrderedList': 'רשימה ממסופרת',
 	'insertUnorderedList': 'רשימה עם תבליטים',
 	'italic': 'נטוי',
 	'justifyCenter': 'יישור למרכז',
 	'justifyFull': 'יישור דו-צדדי',
-	'justifyLeft': 'יישור לשמאל',
-	'justifyRight': 'יישור לימין',
+	'justifyLeft': 'יישור לימין',
+	'justifyRight': 'יישור לשמאל',
 	'outdent': 'הקטנת כניסה',
 	'paste': 'הדבקה',
 	'redo': 'שחזור פעולה',
@@ -22,7 +21,7 @@ define(
 	'strikethrough': 'קו חוצה',
 	'subscript': 'כתב תחתי',
 	'superscript': 'כתב עילי',
-	'underline': 'קו תחתי',
+	'underline': 'קו תחתון',
 	'undo': 'ביטול פעולה',
 	'unlink': 'סילוק הקישור',
 	'createLink': 'יצירת קישור',
@@ -37,7 +36,7 @@ define(
 	'hiliteColor': 'צבע רקע',
 	'plainFormatBlock': 'סגנון פיסקה',
 	'formatBlock': 'סגנון פיסקה',
-	'fontSize': 'גופן יחסי',
+	'fontSize': 'גודל גופן',
 	'fontName': 'שם גופן',
 	'tabIndent': 'כניסת טאב',
 	"fullScreen": "מיתוג מסך מלא",
@@ -45,9 +44,8 @@ define(
 	"print": "הדפסה",
 	"newPage": "דף חדש",
 	/* Error messages */
-	'systemShortcut': 'הפעולה "${0}" זמינה בדפדפן רק באמצעות קיצור דרך במקלדת. השתמשו בקיצור ${1}.',
+	'systemShortcut': 'הפעולה "${0}" זמינה בדפדפן רק באמצעות קיצור דרך במקלדת.  השתמשו בקיצור ${1}.',
 	'ctrlKey':'ctrl+${0}‎',
 	'appleKey':'\u2318${0}‎' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/hu/FontChoice.js b/dijit/_editor/nls/hu/FontChoice.js
index e37ab40..c2da9d5 100644
--- a/dijit/_editor/nls/hu/FontChoice.js
+++ b/dijit/_editor/nls/hu/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Méret",
 	fontName: "Betűtípus",
 	formatBlock: "Formátum",
-
 	serif: "talpas",
 	"sans-serif": "talpatlan",
 	monospace: "rögzített szélességű",
 	cursive: "kurzív",
 	fantasy: "fantázia",
-
 	noFormat: "Nincs",
 	p: "Bekezdés",
 	h1: "Címsor",
 	h2: "Alcím",
 	h3: "Al-alcím",
 	pre: "Előformázott",
-
 	1: "xx-kicsi",
 	2: "x-kicsi",
 	3: "kicsi",
@@ -26,5 +22,4 @@ define(
 	6: "x-nagy",
 	7: "xx-nagy"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/hu/LinkDialog.js b/dijit/_editor/nls/hu/LinkDialog.js
index 4e73312..be65c03 100644
--- a/dijit/_editor/nls/hu/LinkDialog.js
+++ b/dijit/_editor/nls/hu/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Hivatkozás tulajdonságai",
 	insertImageTitle: "Kép tulajdonságai",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Legfelső szintű ablak",
 	newWindow: "Új ablak"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/hu/commands.js b/dijit/_editor/nls/hu/commands.js
index 6afb026..894722a 100644
--- a/dijit/_editor/nls/hu/commands.js
+++ b/dijit/_editor/nls/hu/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Félkövér',
 	'copy': 'Másolás',
@@ -45,7 +44,8 @@ define(
 	"print": "Nyomtatás",
 	"newPage": "Új oldal",
 	/* Error messages */
-	'systemShortcut': 'A(z) "${0}" művelet a böngészőben csak billentyűparancs használatával érhető el. Használja a következőt: ${1}.'
+	'systemShortcut': 'A(z) "${0}" művelet a böngészőben csak billentyűparancs használatával érhető el. Használja a következőt: ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/it/FontChoice.js b/dijit/_editor/nls/it/FontChoice.js
index 29c9dfa..e3ab11c 100644
--- a/dijit/_editor/nls/it/FontChoice.js
+++ b/dijit/_editor/nls/it/FontChoice.js
@@ -1,31 +1,25 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Dimensione",
 	fontName: "Carattere",
 	formatBlock: "Formato",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "spaziatura fissa",
 	cursive: "corsivo",
 	fantasy: "fantasy",
-
 	noFormat: "Nessuna",
 	p: "Paragrafo",
 	h1: "Intestazione",
 	h2: "Sottointestazione",
 	h3: "Sottointestazione secondaria",
 	pre: "Preformattato",
-
-	1: "xx-small",
-	2: "x-small",
-	3: "small",
-	4: "medium",
-	5: "large",
-	6: "x-large",
-	7: "xx-large"
+	1: "piccolissimo",
+	2: "molto piccolo",
+	3: "piccolo",
+	4: "medio",
+	5: "grande",
+	6: "molto grande",
+	7: "grandissimo"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/it/LinkDialog.js b/dijit/_editor/nls/it/LinkDialog.js
index b659615..df7c4bb 100644
--- a/dijit/_editor/nls/it/LinkDialog.js
+++ b/dijit/_editor/nls/it/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Proprietà collegamento",
 	insertImageTitle: "Proprietà immagine",
@@ -8,10 +7,8 @@ define(
 	target: "Destinazione:",
 	set: "Imposta",
 	currentWindow: "Finestra corrente",
-	parentWindow: "Finestra parent",
-	topWindow: "Finestra in primo piano",
+	parentWindow: "Finestra padre",
+	topWindow: "Finestra superiore",
 	newWindow: "Nuova finestra"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/it/commands.js b/dijit/_editor/nls/it/commands.js
index 1aa2df5..56cac79 100644
--- a/dijit/_editor/nls/it/commands.js
+++ b/dijit/_editor/nls/it/commands.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Grassetto',
 	'copy': 'Copia',
 	'cut': 'Taglia',
 	'delete': 'Elimina',
-	'indent': 'Rientra',
+	'indent': 'Rientro',
 	'insertHorizontalRule': 'Righello orizzontale',
 	'insertOrderedList': 'Elenco numerato',
 	'insertUnorderedList': 'Elenco puntato',
@@ -14,7 +13,7 @@ define(
 	'justifyFull': 'Giustifica',
 	'justifyLeft': 'Allinea a sinistra',
 	'justifyRight': 'Allinea a destra',
-	'outdent': 'Rimuovi rientro',
+	'outdent': 'Annulla rientro',
 	'paste': 'Incolla',
 	'redo': 'Ripristina',
 	'removeFormat': 'Rimuovi formato',
@@ -22,14 +21,14 @@ define(
 	'strikethrough': 'Barrato',
 	'subscript': 'Pedice',
 	'superscript': 'Apice',
-	'underline': 'Sottolineato',
+	'underline': 'Sottolinea',
 	'undo': 'Annulla',
 	'unlink': 'Rimuovi collegamento',
 	'createLink': 'Crea collegamento',
-	'toggleDir': 'Inverti direzione',
+	'toggleDir': 'Attiva/Disattiva direzione',
 	'insertImage': 'Inserisci immagine',
 	'insertTable': 'Inserisci/Modifica tabella',
-	'toggleTableBorder': 'Mostra/Nascondi margine tabella',
+	'toggleTableBorder': 'Attiva/Disattiva bordo tabella',
 	'deleteTable': 'Elimina tabella',
 	'tableProp': 'Proprietà tabella',
 	'htmlToggle': 'Origine HTML',
@@ -39,14 +38,14 @@ define(
 	'formatBlock': 'Stile paragrafo',
 	'fontSize': 'Dimensione carattere',
 	'fontName': 'Nome carattere',
-	'tabIndent': 'Rientranza tabulazione',
+	'tabIndent': 'Rientro tabulazione',
 	"fullScreen": "Attiva/Disattiva schermo intero",
 	"viewSource": "Visualizza origine HTML",
 	"print": "Stampa",
 	"newPage": "Nuova pagina",
 	/* Error messages */
-	'systemShortcut': 'Azione "${0}" disponibile sul proprio browser solo mediante i tasti di scelta rapida della tastiera. Utilizzare ${1}.'
+	'systemShortcut': 'La azione "${0}" è disponibile solo nel browser tramite un tasto di scelta rapida. Utilizzare ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ja/FontChoice.js b/dijit/_editor/nls/ja/FontChoice.js
index 45d6178..0cd28ac 100644
--- a/dijit/_editor/nls/ja/FontChoice.js
+++ b/dijit/_editor/nls/ja/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "サイズ",
 	fontName: "フォント",
 	formatBlock: "フォーマット",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "cursive",
 	fantasy: "fantasy",
-
 	noFormat: "なし",
 	p: "段落",
 	h1: "見出し",
 	h2: "副見出し",
 	h3: "副見出しの副見出し",
 	pre: "事前フォーマット済み",
-
 	1: "超極小",
 	2: "極小",
 	3: "小",
@@ -26,5 +22,4 @@ define(
 	6: "特大",
 	7: "超特大"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ja/LinkDialog.js b/dijit/_editor/nls/ja/LinkDialog.js
index df9c07d..9a230a9 100644
--- a/dijit/_editor/nls/ja/LinkDialog.js
+++ b/dijit/_editor/nls/ja/LinkDialog.js
@@ -1,17 +1,14 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "リンク・プロパティー",
 	insertImageTitle: "イメージ・プロパティー",
 	url: "URL:",
 	text: "説明:",
-	target: "ターゲット:",
+	target: "ターゲット: ",
 	set: "設定",
-	currentWindow: "現行ウィンドウ",
+	currentWindow: "現在のウィンドウ",
 	parentWindow: "親ウィンドウ",
 	topWindow: "最上位ウィンドウ",
 	newWindow: "新規ウィンドウ"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ja/commands.js b/dijit/_editor/nls/ja/commands.js
index 4e8f1a9..7c28287 100644
--- a/dijit/_editor/nls/ja/commands.js
+++ b/dijit/_editor/nls/ja/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': '太字',
 	'copy': 'コピー',
@@ -17,7 +16,7 @@ define(
 	'outdent': 'アウトデント',
 	'paste': '貼り付け',
 	'redo': 'やり直し',
-	'removeFormat': '書式のクリア',
+	'removeFormat': '形式の削除',
 	'selectAll': 'すべて選択',
 	'strikethrough': '取り消し線',
 	'subscript': '下付き文字',
@@ -29,24 +28,24 @@ define(
 	'toggleDir': '方向の切り替え',
 	'insertImage': 'イメージの挿入',
 	'insertTable': 'テーブルの挿入/編集',
-	'toggleTableBorder': 'テーブル・ボーダーの切り替え',
+	'toggleTableBorder': 'テーブルボーダーの切り替え',
 	'deleteTable': 'テーブルの削除',
-	'tableProp': 'テーブル・プロパティー',
+	'tableProp': 'テーブルプロパティ',
 	'htmlToggle': 'HTML ソース',
 	'foreColor': '前景色',
-	'hiliteColor': 'マーカー',
+	'hiliteColor': '背景色',
 	'plainFormatBlock': '段落スタイル',
 	'formatBlock': '段落スタイル',
-	'fontSize': 'フォント・サイズ',
+	'fontSize': 'フォントサイズ',
 	'fontName': 'フォント名',
-	'tabIndent': 'タブ・インデント',
+	'tabIndent': 'タブインデント',
 	"fullScreen": "全画面表示に切り替え",
 	"viewSource": "HTML ソースの表示",
 	"print": "印刷",
-	"newPage": "新規ページ",
+	"newPage": "新しいページ",
 	/* Error messages */
-	'systemShortcut': '"${0}" アクションを使用できるのは、ブラウザーでキーボード・ショートカットを使用する場合のみです。${1} を使用してください。',
-	'ctrlKey':'Ctrl+${0}'
+	'systemShortcut': '"${0}" アクションを使用できるのは、ブラウザーでキーボードショートカットを使用する場合のみです。 ${1} を使用してください。',
+	'ctrlKey':'Ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/kk/FontChoice.js b/dijit/_editor/nls/kk/FontChoice.js
index 37a1944..976e10d 100644
--- a/dijit/_editor/nls/kk/FontChoice.js
+++ b/dijit/_editor/nls/kk/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Өлшемі",
 	fontName: "Қаріп",
 	formatBlock: "Пішім",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "көлбеу",
-	fantasy: "қиял-ғажайып",
-
+	fantasy: "fantasy",
 	noFormat: "Ешбір",
 	p: "Еже",
-	h1: "Үстіңгі деректеме",
+	h1: "Тақырып",
 	h2: "Ішкі тақырып",
 	h3: "Ішкі-ішкі тақырып",
 	pre: "Алдын ала пішімделген",
-
 	1: "xx-кіші",
 	2: "x-кіші",
 	3: "кіші",
@@ -26,5 +22,4 @@ define(
 	6: "x-үлкен",
 	7: "xx-үлкен"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/kk/LinkDialog.js b/dijit/_editor/nls/kk/LinkDialog.js
index bbf9688..7164e01 100644
--- a/dijit/_editor/nls/kk/LinkDialog.js
+++ b/dijit/_editor/nls/kk/LinkDialog.js
@@ -1,9 +1,8 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Сілтеме сипаттары",
 	insertImageTitle: "Сурет сипаттары",
-	url: "URL мекенжайы:",
+	url: "URL:",
 	text: "Сипаттама:",
 	target: "Мақсат:",
 	set: "Орнату",
@@ -12,5 +11,4 @@ define(
 	topWindow: "Ең жоғарғы терезе",
 	newWindow: "Жаңа терезе"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/kk/commands.js b/dijit/_editor/nls/kk/commands.js
index b03c438..26c4c1f 100644
--- a/dijit/_editor/nls/kk/commands.js
+++ b/dijit/_editor/nls/kk/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Қалың',
 	'copy': 'Көшіру',
@@ -14,7 +13,7 @@ define(
 	'justifyFull': 'Туралау',
 	'justifyLeft': 'Сол жақ бойынша туралау',
 	'justifyRight': 'Оң жақ бойынша туралау',
-	'outdent': 'Шығыңқы',
+	'outdent': 'Солға ығысу',
 	'paste': 'Қою',
 	'redo': 'Қайтару',
 	'removeFormat': 'Пішімді алып тастау',
@@ -23,11 +22,11 @@ define(
 	'subscript': 'Жоласты',
 	'superscript': 'Жолүсті',
 	'underline': 'Асты сызылған',
-	'undo': 'Болдырмау ',
-	'unlink': 'Сілтемені жою',
+	'undo': 'Болдырмау',
+	'unlink': 'Сілтемені алып тастау',
 	'createLink': 'Сілтеме жасау',
 	'toggleDir': 'Бағытты қосу',
-	'insertImage': 'Сурет кірістіру',
+	'insertImage': 'Суретті кірістіру',
 	'insertTable': 'Кестені кірістіру/өңдеу',
 	'toggleTableBorder': 'Кесте жиегін қосу',
 	'deleteTable': 'Кестені жою',
@@ -45,7 +44,8 @@ define(
 	"print": "Басып шығару",
 	"newPage": "Жаңа бет",
 	/* Error messages */
-	'systemShortcut': '"${0}" әрекеті шолғышта тек пернелер тіркесімі арқылы қол жетімді. ${1} пайдаланыңыз.'
+	'systemShortcut': '"${0}" әрекеті шолғышта тек пернелер тіркесімі арқылы қол жетімді. Қолдану ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ko/FontChoice.js b/dijit/_editor/nls/ko/FontChoice.js
index b1ecdfd..566a087 100644
--- a/dijit/_editor/nls/ko/FontChoice.js
+++ b/dijit/_editor/nls/ko/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "크기",
 	fontName: "글꼴",
 	formatBlock: "서식",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "cursive",
 	fantasy: "fantasy",
-
 	noFormat: "없음",
 	p: "단락",
 	h1: "제목",
 	h2: "부제목",
 	h3: "하위 부제목",
 	pre: "서식이 지정됨",
-
 	1: "가장 작게",
 	2: "조금 작게",
 	3: "작게",
@@ -26,5 +22,4 @@ define(
 	6: "조금 크게",
 	7: "가장 크게"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ko/LinkDialog.js b/dijit/_editor/nls/ko/LinkDialog.js
index f9a42da..cb1c4ce 100644
--- a/dijit/_editor/nls/ko/LinkDialog.js
+++ b/dijit/_editor/nls/ko/LinkDialog.js
@@ -1,8 +1,7 @@
 define(
-//begin v1.x content
 ({
-	createLinkTitle: "링크 등록 정보",
-	insertImageTitle: "이미지 등록 정보",
+	createLinkTitle: "링크 특성",
+	insertImageTitle: "이미지 특성",
 	url: "URL:",
 	text: "설명:",
 	target: "대상",
@@ -12,6 +11,4 @@ define(
 	topWindow: "최상위 창",
 	newWindow: "새 창"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ko/commands.js b/dijit/_editor/nls/ko/commands.js
index 062e8c4..0973257 100644
--- a/dijit/_editor/nls/ko/commands.js
+++ b/dijit/_editor/nls/ko/commands.js
@@ -1,7 +1,6 @@
 define(
-//begin v1.x content
 ({
-	'bold': '굵게',
+	'bold': '굵은체',
 	'copy': '복사',
 	'cut': '잘라내기',
 	'delete': '삭제',
@@ -9,7 +8,7 @@ define(
 	'insertHorizontalRule': '수평 자',
 	'insertOrderedList': '번호 목록',
 	'insertUnorderedList': '글머리표 목록',
-	'italic': '기울임꼴',
+	'italic': '기울임체',
 	'justifyCenter': '가운데 맞춤',
 	'justifyFull': '양쪽 맞춤',
 	'justifyLeft': '왼쪽 맞춤',
@@ -35,8 +34,8 @@ define(
 	'htmlToggle': 'HTML 소스',
 	'foreColor': '전경색',
 	'hiliteColor': '배경색',
-	'plainFormatBlock': '단락 양식',
-	'formatBlock': '단락 양식',
+	'plainFormatBlock': '단락 스타일',
+	'formatBlock': '단락 스타일',
 	'fontSize': '글꼴 크기',
 	'fontName': '글꼴 이름',
 	'tabIndent': '탭 들여쓰기',
@@ -45,7 +44,8 @@ define(
 	"print": "인쇄",
 	"newPage": "새 페이지",
 	/* Error messages */
-	'systemShortcut': '"${0}" 조치는 브라우저에서 키보드 단축키를 통해서만 사용 가능합니다. ${1}을(를) 사용하십시오.'
+	'systemShortcut': '"${0}" 조치는 브라우저에서 키보드 단축키를 이용해서만 사용할 수 있습니다. ${1}을(를) 사용하십시오.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/nb/FontChoice.js b/dijit/_editor/nls/nb/FontChoice.js
index 358233f..11458f8 100644
--- a/dijit/_editor/nls/nb/FontChoice.js
+++ b/dijit/_editor/nls/nb/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Størrelse",
 	fontName: "Skrift",
 	formatBlock: "Format",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "kursiv",
 	fantasy: "fantasi",
-
 	noFormat: "Ingen",
 	p: "Avsnitt",
 	h1: "Overskrift",
 	h2: "Undertittel",
 	h3: "Under-undertittel",
 	pre: "Forhåndsformatert",
-
 	1: "xx-liten",
 	2: "x-liten",
 	3: "liten",
@@ -26,5 +22,4 @@ define(
 	6: "x-stor",
 	7: "xx-stor"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/nb/LinkDialog.js b/dijit/_editor/nls/nb/LinkDialog.js
index ad1dd86..c2e4b82 100644
--- a/dijit/_editor/nls/nb/LinkDialog.js
+++ b/dijit/_editor/nls/nb/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Koblingsegenskaper",
 	insertImageTitle: "Bildeegenskaper",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Øverste vindu",
 	newWindow: "Nytt vindu"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/nb/commands.js b/dijit/_editor/nls/nb/commands.js
index 5bad6a5..265759a 100644
--- a/dijit/_editor/nls/nb/commands.js
+++ b/dijit/_editor/nls/nb/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Fet',
 	'copy': 'Kopier',
@@ -49,5 +48,4 @@ define(
 	'ctrlKey':'ctrl+${0}',
 	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/nl/FontChoice.js b/dijit/_editor/nls/nl/FontChoice.js
index a422387..69db6d1 100644
--- a/dijit/_editor/nls/nl/FontChoice.js
+++ b/dijit/_editor/nls/nl/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Grootte",
 	fontName: "Lettertype",
 	formatBlock: "Opmaak",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "cursief",
 	fantasy: "fantasy",
-
 	noFormat: "Geen",
 	p: "Alinea",
 	h1: "Kop",
 	h2: "Subkop",
 	h3: "Sub-subkop",
 	pre: "Vooraf opgemaakt",
-
 	1: "xx-klein",
 	2: "x-klein",
 	3: "klein",
@@ -26,5 +22,4 @@ define(
 	6: "x-groot",
 	7: "xx-groot"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/nl/LinkDialog.js b/dijit/_editor/nls/nl/LinkDialog.js
index 786058b..b81c117 100644
--- a/dijit/_editor/nls/nl/LinkDialog.js
+++ b/dijit/_editor/nls/nl/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Linkeigenschappen",
 	insertImageTitle: "Afbeeldingseigenschappen",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Bovenste venster",
 	newWindow: "Nieuw venster"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/nl/commands.js b/dijit/_editor/nls/nl/commands.js
index d2527d3..432325a 100644
--- a/dijit/_editor/nls/nl/commands.js
+++ b/dijit/_editor/nls/nl/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Vet',
 	'copy': 'Kopiëren',
@@ -45,7 +44,8 @@ define(
 	"print": "Afdrukken",
 	"newPage": "Nieuwe pagina",
 	/* Error messages */
-	'systemShortcut': 'De actie "${0}" is alleen beschikbaar in uw browser via een sneltoetscombinatie. Gebruik ${1}.'
+	'systemShortcut': 'De actie "${0}" is alleen beschikbaar in uw browser via een sneltoetscombinatie. Gebruik ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/pl/FontChoice.js b/dijit/_editor/nls/pl/FontChoice.js
index 49ac3e4..616fb86 100644
--- a/dijit/_editor/nls/pl/FontChoice.js
+++ b/dijit/_editor/nls/pl/FontChoice.js
@@ -1,30 +1,25 @@
 define(
-//begin v1.x content
 ({
-	fontSize: "Wielkość",
+	fontSize: "Rozmiar",
 	fontName: "Czcionka",
 	formatBlock: "Format",
-
 	serif: "szeryfowa",
 	"sans-serif": "bezszeryfowa",
 	monospace: "czcionka o stałej szerokości",
 	cursive: "kursywa",
 	fantasy: "fantazyjna",
-
 	noFormat: "Brak",
 	p: "Akapit",
 	h1: "Nagłówek",
 	h2: "Nagłówek 2-go poziomu",
 	h3: "Nagłówek 3-go poziomu",
 	pre: "Wstępnie sformatowane",
-
 	1: "najmniejsza",
 	2: "mniejsza",
 	3: "mała",
 	4: "średnia",
-	5: "duża",
+	5: "duże",
 	6: "większa",
 	7: "największa"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/pl/LinkDialog.js b/dijit/_editor/nls/pl/LinkDialog.js
index 0cd9bb5..1166dad 100644
--- a/dijit/_editor/nls/pl/LinkDialog.js
+++ b/dijit/_editor/nls/pl/LinkDialog.js
@@ -1,17 +1,14 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Właściwości odsyłacza",
 	insertImageTitle: "Właściwości obrazu",
 	url: "Adres URL:",
 	text: "Opis:",
-	target: "Cel:",
+	target: "Docelowe:",
 	set: "Ustaw",
 	currentWindow: "Bieżące okno",
 	parentWindow: "Okno macierzyste",
 	topWindow: "Okno najwyższego poziomu",
 	newWindow: "Nowe okno"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/pl/commands.js b/dijit/_editor/nls/pl/commands.js
index ab20734..1a6f6c1 100644
--- a/dijit/_editor/nls/pl/commands.js
+++ b/dijit/_editor/nls/pl/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Pogrubienie',
 	'copy': 'Kopiuj',
@@ -32,7 +31,7 @@ define(
 	'toggleTableBorder': 'Przełącz ramkę tabeli',
 	'deleteTable': 'Usuń tabelę',
 	'tableProp': 'Właściwość tabeli',
-	'htmlToggle': 'Kod źródłowy HTML',
+	'htmlToggle': 'Źródło HTML',
 	'foreColor': 'Kolor pierwszego planu',
 	'hiliteColor': 'Kolor tła',
 	'plainFormatBlock': 'Styl akapitu',
@@ -46,8 +45,7 @@ define(
 	"newPage": "Nowa strona",
 	/* Error messages */
 	'systemShortcut': 'Działanie ${0} jest dostępne w tej przeglądarce wyłącznie przy użyciu skrótu klawiaturowego. Należy użyć klawiszy ${1}.',
-	'ctrlKey':'Ctrl+${0}'
+	'ctrlKey':'Ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/pt-pt/FontChoice.js b/dijit/_editor/nls/pt-pt/FontChoice.js
index c867ff6..e2c9352 100644
--- a/dijit/_editor/nls/pt-pt/FontChoice.js
+++ b/dijit/_editor/nls/pt-pt/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Tamanho",
 	fontName: "Tipo de letra",
 	formatBlock: "Formato",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "cursive",
 	fantasy: "fantasy",
-
 	noFormat: "Nenhum",
 	p: "Parágrafo",
 	h1: "Título",
 	h2: "Sub-título",
 	h3: "Sub-subtítulo",
 	pre: "Pré-formatado",
-
 	1: "xxs",
 	2: "xs",
 	3: "small",
@@ -26,5 +22,4 @@ define(
 	6: "xl",
 	7: "xxl"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/pt-pt/LinkDialog.js b/dijit/_editor/nls/pt-pt/LinkDialog.js
index 51d7455..b44215c 100644
--- a/dijit/_editor/nls/pt-pt/LinkDialog.js
+++ b/dijit/_editor/nls/pt-pt/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Propriedades da ligação",
 	insertImageTitle: "Propriedades da imagem",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Janela superior",
 	newWindow: "Nova janela"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/pt-pt/commands.js b/dijit/_editor/nls/pt-pt/commands.js
index 539d96a..8fdddbc 100644
--- a/dijit/_editor/nls/pt-pt/commands.js
+++ b/dijit/_editor/nls/pt-pt/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Negrito',
 	'copy': 'Copiar',
@@ -32,7 +31,7 @@ define(
 	'toggleTableBorder': 'Alternar contorno da tabela',
 	'deleteTable': 'Eliminar tabela',
 	'tableProp': 'Propriedades da tabela',
-	'htmlToggle': 'Código-fonte de HTML',
+	'htmlToggle': 'Origem HTML',
 	'foreColor': 'Cor de primeiro plano',
 	'hiliteColor': 'Cor de segundo plano',
 	'plainFormatBlock': 'Estilo de parágrafo',
@@ -45,8 +44,8 @@ define(
 	"print": "Imprimir",
 	"newPage": "Nova página",
 	/* Error messages */
-	'systemShortcut': 'A acção "${0}" apenas está disponível no navegador utilizando um atalho de teclado. Utilize ${1}.'
+	'systemShortcut': 'A acção "${0}" apenas está disponível no navegador utilizando um atalho de teclado. Utilize ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/pt/FontChoice.js b/dijit/_editor/nls/pt/FontChoice.js
index 94c2ba0..e5aeea5 100644
--- a/dijit/_editor/nls/pt/FontChoice.js
+++ b/dijit/_editor/nls/pt/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Tamanho",
 	fontName: "Fonte",
 	formatBlock: "Formatar",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "espaço simples",
 	cursive: "cursiva",
 	fantasy: "fantasy",
-
-	noFormat: "Nenhuma",
+	noFormat: "Nenhum",
 	p: "Parágrafo",
 	h1: "Título",
 	h2: "Subtítulo",
 	h3: "Sub-subtítulo",
 	pre: "Pré-formatado",
-
 	1: "extra-extra-pequeno",
 	2: "extra-pequeno",
 	3: "pequena",
@@ -26,5 +22,4 @@ define(
 	6: "extra-grande",
 	7: "extra-extra-grande"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/pt/LinkDialog.js b/dijit/_editor/nls/pt/LinkDialog.js
index f303014..00d9a28 100644
--- a/dijit/_editor/nls/pt/LinkDialog.js
+++ b/dijit/_editor/nls/pt/LinkDialog.js
@@ -1,17 +1,14 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Propriedades de Link",
 	insertImageTitle: "Propriedades de Imagem",
 	url: "URL:",
 	text: "Descrição:",
 	target: "Destino:",
-	set: "Definir",
+	set: "Configurar",
 	currentWindow: "Janela Atual",
 	parentWindow: "Janela Pai",
 	topWindow: "Primeira Janela",
 	newWindow: "Nova Janela"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/pt/commands.js b/dijit/_editor/nls/pt/commands.js
index e613736..932b82b 100644
--- a/dijit/_editor/nls/pt/commands.js
+++ b/dijit/_editor/nls/pt/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Negrito',
 	'copy': 'Copiar',
@@ -12,9 +11,9 @@ define(
 	'italic': 'Itálico',
 	'justifyCenter': 'Alinhar pelo Centro',
 	'justifyFull': 'Justificar',
-	'justifyLeft': 'Alinhar à Esquerda',
-	'justifyRight': 'Alinhar à Direita',
-	'outdent': 'Não chanfrado',
+	'justifyLeft': 'Alinhar pela Esquerda',
+	'justifyRight': 'Alinhar pela Direita',
+	'outdent': 'Não-chanfrado',
 	'paste': 'Colar',
 	'redo': 'Refazer',
 	'removeFormat': 'Remover Formato',
@@ -34,7 +33,7 @@ define(
 	'tableProp': 'Propriedade da Tabela',
 	'htmlToggle': 'Origem HTML',
 	'foreColor': 'Cor do Primeiro Plano',
-	'hiliteColor': 'Cor do Segundo Plano',
+	'hiliteColor': 'Cor de segundo plano',
 	'plainFormatBlock': 'Estilo de Parágrafo',
 	'formatBlock': 'Estilo de Parágrafo',
 	'fontSize': 'Tamanho da Fonte',
@@ -42,10 +41,11 @@ define(
 	'tabIndent': 'Recuo de Guia',
 	"fullScreen": "Comutar Tela Cheia",
 	"viewSource": "Visualizar Origem HTML",
-	"print": "Imprimir",
+	"print": "Impressão",
 	"newPage": "Nova Página",
 	/* Error messages */
-	'systemShortcut': 'A ação "${0}" está disponível em seu navegador apenas usando um atalho de teclado. Use ${1}.'
+	'systemShortcut': 'A ação "${0}" está disponível em seu navegador apenas usando um atalho do teclado. Use ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ro/FontChoice.js b/dijit/_editor/nls/ro/FontChoice.js
index 3e9621a..46b5d51 100644
--- a/dijit/_editor/nls/ro/FontChoice.js
+++ b/dijit/_editor/nls/ro/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
-	fontSize: "Dimensiune",
+	fontSize: "Mărime",
 	fontName: "Font",
 	formatBlock: "Format",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "cursive",
 	fantasy: "fantasy",
-
-	noFormat: "Fără",
+	noFormat: "Nimic",
 	p: "Paragraf",
 	h1: "Titlu",
 	h2: "Subtitlu",
 	h3: "Sub-subtitlu",
 	pre: "Preformatat",
-
 	1: "xxs (xx-small)",
 	2: "xs (x-small)",
 	3: "s (small)",
@@ -26,6 +22,4 @@ define(
 	6: "xl (x-large)",
 	7: "xxl (xx-large)"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ro/LinkDialog.js b/dijit/_editor/nls/ro/LinkDialog.js
index 847d296..74cc851 100644
--- a/dijit/_editor/nls/ro/LinkDialog.js
+++ b/dijit/_editor/nls/ro/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Proprietăţi legătură",
 	insertImageTitle: "Proprietăţi imagine",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Fereastra cea mai de sus",
 	newWindow: "Fereastra nouă"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ro/commands.js b/dijit/_editor/nls/ro/commands.js
index 724f340..f1e1043 100644
--- a/dijit/_editor/nls/ro/commands.js
+++ b/dijit/_editor/nls/ro/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Aldin',
 	'copy': 'Copiere',
@@ -45,7 +44,8 @@ define(
 	"print": "Tipărire",
 	"newPage": "Pagină nouă",
 	/* Error messages */
-	'systemShortcut': 'Acţiunea "${0}" este disponibilă în browser doar utilizând o comandă rapidă de la tastatură. Utilizaţi ${1}.'
+	'systemShortcut': 'Acţiunea "${0}" este disponibilă în browser doar utilizând o comandă rapidă de la tastatură. Utilizaţi ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ru/FontChoice.js b/dijit/_editor/nls/ru/FontChoice.js
index 414f995..b5a16d6 100644
--- a/dijit/_editor/nls/ru/FontChoice.js
+++ b/dijit/_editor/nls/ru/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Размер",
 	fontName: "Шрифт",
 	formatBlock: "Формат",
-
 	serif: "с засечками",
 	"sans-serif": "без засечек",
 	monospace: "непропорциональный",
 	cursive: "курсив",
 	fantasy: "артистический",
-
 	noFormat: "Нет",
 	p: "Абзац",
 	h1: "Заголовок",
 	h2: "Подзаголовок",
 	h3: "Вложенный подзаголовок",
 	pre: "Заранее отформатированный",
-
 	1: "самый маленький",
 	2: "очень маленький",
 	3: "маленький",
@@ -26,5 +22,4 @@ define(
 	6: "очень большой",
 	7: "самый большой"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ru/LinkDialog.js b/dijit/_editor/nls/ru/LinkDialog.js
index 5f8eff8..8227862 100644
--- a/dijit/_editor/nls/ru/LinkDialog.js
+++ b/dijit/_editor/nls/ru/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Свойства ссылки",
 	insertImageTitle: "Свойства изображения",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Верхнее окно",
 	newWindow: "Новое окно"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/ru/commands.js b/dijit/_editor/nls/ru/commands.js
index 90f5d15..5323ebd 100644
--- a/dijit/_editor/nls/ru/commands.js
+++ b/dijit/_editor/nls/ru/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Полужирный',
 	'copy': 'Копировать',
@@ -10,10 +9,10 @@ define(
 	'insertOrderedList': 'Нумерованный список',
 	'insertUnorderedList': 'Список с маркерами',
 	'italic': 'Курсив',
-	'justifyCenter': 'По центру',
+	'justifyCenter': 'Выровнять по центру',
 	'justifyFull': 'По ширине',
-	'justifyLeft': 'По левому краю',
-	'justifyRight': 'По правому краю',
+	'justifyLeft': 'Выровнять по левому краю',
+	'justifyRight': 'Выровнять по правому краю',
 	'outdent': 'Втяжка',
 	'paste': 'Вставить',
 	'redo': 'Повторить',
@@ -45,8 +44,8 @@ define(
 	"print": "Печать",
 	"newPage": "Создать страницу",
 	/* Error messages */
-	'systemShortcut': 'Действие "${0}" можно выполнить в браузере только путем нажатия клавиш ${1}.'
+	'systemShortcut': 'Действие "${0}" можно выполнить в браузере только путем нажатия клавиш ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/sk/FontChoice.js b/dijit/_editor/nls/sk/FontChoice.js
index 4734c19..e468ac5 100644
--- a/dijit/_editor/nls/sk/FontChoice.js
+++ b/dijit/_editor/nls/sk/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Veľkosť",
 	fontName: "Písmo",
 	formatBlock: "Formát",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "cursive",
 	fantasy: "fantasy",
-
 	noFormat: "Žiadny",
 	p: "Odsek",
 	h1: "Hlavička",
 	h2: "Podhlavička",
 	h3: "Pod-podhlavička",
 	pre: "Predformátované",
-
 	1: "xx-small",
 	2: "x-small",
 	3: "small",
@@ -26,6 +22,4 @@ define(
 	6: "x-large",
 	7: "xx-large"
 })
-//end v1.x content
 );
-
diff --git a/dijit/_editor/nls/sk/LinkDialog.js b/dijit/_editor/nls/sk/LinkDialog.js
index ca57a1b..1084921 100644
--- a/dijit/_editor/nls/sk/LinkDialog.js
+++ b/dijit/_editor/nls/sk/LinkDialog.js
@@ -1,17 +1,14 @@
 define(
-//begin v1.x content
 ({
-	createLinkTitle: "Pripojiť vlastnosti",
-	insertImageTitle: "Vlastnosti obrázka ",
-	url: "URL:",
+	createLinkTitle: "Vlastnosti prepojenia",
+	insertImageTitle: "Vlastnosti obrázka",
+	url: "Adresa URL:",
 	text: "Opis:",
 	target: "Cieľ:",
 	set: "Nastaviť",
-	currentWindow: "Aktuálne okno ",
-	parentWindow: "Rodičovské okno ",
-	topWindow: "Najvrchnejšie okno ",
-	newWindow: "Nové okno "
+	currentWindow: "Aktuálne okno",
+	parentWindow: "Rodičovské okno",
+	topWindow: "Najvyššie okno",
+	newWindow: "Nové okno"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/sk/commands.js b/dijit/_editor/nls/sk/commands.js
index f4af3b3..bb0bf1d 100644
--- a/dijit/_editor/nls/sk/commands.js
+++ b/dijit/_editor/nls/sk/commands.js
@@ -1,38 +1,37 @@
 define(
-//begin v1.x content
 ({
-	'bold': 'Tučné písmo',
+	'bold': 'Tučné',
 	'copy': 'Kopírovať',
 	'cut': 'Vystrihnúť',
 	'delete': 'Vymazať',
 	'indent': 'Odsadiť',
-	'insertHorizontalRule': 'Horizontálna čiara',
+	'insertHorizontalRule': 'Vodorovná čiara',
 	'insertOrderedList': 'Číslovaný zoznam',
 	'insertUnorderedList': 'Zoznam s odrážkami',
 	'italic': 'Kurzíva',
 	'justifyCenter': 'Zarovnať na stred',
-	'justifyFull': 'Zarovnať podľa okraja',
-	'justifyLeft': 'Zarovnať doľava',
-	'justifyRight': 'Zarovnať doprava',
-	'outdent': 'Predsadiť',
-	'paste': 'Nalepiť',
-	'redo': 'Znova vykonať',
-	'removeFormat': 'Odstrániť formát',
+	'justifyFull': 'Zarovnať k okrajom',
+	'justifyLeft': 'Zarovnať vľavo',
+	'justifyRight': 'Zarovnať vpravo',
+	'outdent': 'Zmenšiť odsadenie',
+	'paste': 'Prilepiť',
+	'redo': 'Znova',
+	'removeFormat': 'Odstrániť formátovanie',
 	'selectAll': 'Vybrať všetko',
 	'strikethrough': 'Prečiarknuť',
 	'subscript': 'Dolný index',
 	'superscript': 'Horný index',
 	'underline': 'Podčiarknuť',
-	'undo': 'Vrátiť späť',
+	'undo': 'Späť',
 	'unlink': 'Odstrániť prepojenie',
 	'createLink': 'Vytvoriť prepojenie',
 	'toggleDir': 'Prepnúť smer',
 	'insertImage': 'Vložiť obrázok',
 	'insertTable': 'Vložiť/upraviť tabuľku',
-	'toggleTableBorder': 'Prepnúť rámček tabuľky',
-	'deleteTable': 'Vymazať tabuľku',
+	'toggleTableBorder': 'Prepnúť ohraničenie tabuľky',
+	'deleteTable': 'Odstrániť tabuľku',
 	'tableProp': 'Vlastnosť tabuľky',
-	'htmlToggle': 'Zdroj HTML',
+	'htmlToggle': 'Zdrojový kód HTML',
 	'foreColor': 'Farba popredia',
 	'hiliteColor': 'Farba pozadia',
 	'plainFormatBlock': 'Štýl odseku',
@@ -40,13 +39,13 @@ define(
 	'fontSize': 'Veľkosť písma',
 	'fontName': 'Názov písma',
 	'tabIndent': 'Odsadenie tabulátora',
-	"fullScreen": "Zobraziť na celú obrazovku",
-	"viewSource": "Zobraziť zdrojový kód HTML ",
-	"print": "Tlačiť",
-	"newPage": "Nová stránka ",
+	"fullScreen": "Prepnúť na celú obrazovku",
+	"viewSource": "Zobraziť zdrojový kód HTML",
+	"print": "Vytlačiť",
+	"newPage": "Nová stránka",
 	/* Error messages */
-	'systemShortcut': 'Akcia "${0}" je vo vašom prehliadači dostupná len s použitím klávesovej skratky. Použite ${1}.'
+	'systemShortcut': 'Akcia "${0}" je vo vašom prehliadači dostupná iba prostredníctvom klávesovej skratky. Stlačte ${1}.',
+	'ctrlKey':'Ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/sl/FontChoice.js b/dijit/_editor/nls/sl/FontChoice.js
index f54975d..db7f76e 100644
--- a/dijit/_editor/nls/sl/FontChoice.js
+++ b/dijit/_editor/nls/sl/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Velikost",
 	fontName: "Pisava",
 	formatBlock: "Oblika",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "cursive",
 	fantasy: "fantasy",
-
 	noFormat: "Brez",
 	p: "Odstavek",
 	h1: "Naslovni slog",
 	h2: "Podnaslovni slog",
 	h3: "Pod-podnaslovni slog",
 	pre: "Vnaprej oblikovan",
-
 	1: "xx-majhno",
 	2: "x-majhno",
 	3: "majhno",
@@ -26,6 +22,4 @@ define(
 	6: "x-veliko",
 	7: "xx-veliko"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/sl/LinkDialog.js b/dijit/_editor/nls/sl/LinkDialog.js
index 7118f40..db74c3a 100644
--- a/dijit/_editor/nls/sl/LinkDialog.js
+++ b/dijit/_editor/nls/sl/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Lastnosti povezave",
 	insertImageTitle: "Lastnosti slike",
@@ -12,6 +11,4 @@ define(
 	topWindow: "Okno na vrhu",
 	newWindow: "Novo okno"
 })
-//end v1.x content
 );
-
diff --git a/dijit/_editor/nls/sl/commands.js b/dijit/_editor/nls/sl/commands.js
index f7e6877..9e742a3 100644
--- a/dijit/_editor/nls/sl/commands.js
+++ b/dijit/_editor/nls/sl/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Krepko',
 	'copy': 'Prekopiraj',
@@ -29,7 +28,7 @@ define(
 	'toggleDir': 'Preklopi smer',
 	'insertImage': 'Vstavi sliko',
 	'insertTable': 'Vstavi/uredi tabelo',
-	'toggleTableBorder': 'Preklopi na rob tabele',
+	'toggleTableBorder': 'Preklopi na obrobo tabele',
 	'deleteTable': 'Izbriši tabelo',
 	'tableProp': 'Lastnost tabele',
 	'htmlToggle': 'Izvorna koda HTML',
@@ -45,7 +44,8 @@ define(
 	"print": "Natisni",
 	"newPage": "Nova stran",
 	/* Error messages */
-	'systemShortcut': 'Dejanje "${0}" lahko v vašem brskalniku uporabite samo z bližnjico na tipkovnici. Uporabite ${1}.'
+	'systemShortcut': 'Dejanje "${0}" lahko v vašem brskalniku uporabite samo z bližnjico na tipkovnici. Uporabite ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/sv/FontChoice.js b/dijit/_editor/nls/sv/FontChoice.js
index 4c92983..e16369d 100644
--- a/dijit/_editor/nls/sv/FontChoice.js
+++ b/dijit/_editor/nls/sv/FontChoice.js
@@ -1,30 +1,25 @@
 define(
-//begin v1.x content
 ({
-	fontSize: "Storlek",
+	fontSize: "Storlek ",
 	fontName: "Teckensnitt",
 	formatBlock: "Format",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
-	cursive: "kursivt",
+	cursive: "cursive",
 	fantasy: "fantasy",
-
-	noFormat: "Ingen",
+	noFormat: "Inget",
 	p: "Stycke",
-	h1: "Rubrik",
-	h2: "Underrubrik",
-	h3: "Underunderrubrik",
-	pre: "Förformaterat",
-
-	1: "mycket, mycket litet",
-	2: "mycket litet",
-	3: "litet",
-	4: "medelstort",
-	5: "stort",
-	6: "extra stort",
-	7: "extra extra stort"
+	h1: "Rubrik 1",
+	h2: "Rubrik 2",
+	h3: "Rubrik 3",
+	pre: "Förformaterad",
+	1: "XXS",
+	2: "XS",
+	3: "S",
+	4: "M",
+	5: "L",
+	6: "XL",
+	7: "XXL"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/sv/LinkDialog.js b/dijit/_editor/nls/sv/LinkDialog.js
index 9475026..776e996 100644
--- a/dijit/_editor/nls/sv/LinkDialog.js
+++ b/dijit/_editor/nls/sv/LinkDialog.js
@@ -1,17 +1,14 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Länkegenskaper",
 	insertImageTitle: "Bildegenskaper",
 	url: "URL-adress:",
 	text: "Beskrivning:",
 	target: "Mål:",
-	set: "Ange",
-	currentWindow: "aktuellt fönster",
-	parentWindow: "överordnat fönster",
-	topWindow: "översta fönstret",
-	newWindow: "nytt fönster"
+	set: "Använd",
+	currentWindow: "Aktuellt fönster",
+	parentWindow: "Överordnat fönster",
+	topWindow: "Översta fönstret",
+	newWindow: "Nytt fönster"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/sv/commands.js b/dijit/_editor/nls/sv/commands.js
index 51a9b80..b583c49 100644
--- a/dijit/_editor/nls/sv/commands.js
+++ b/dijit/_editor/nls/sv/commands.js
@@ -1,12 +1,11 @@
 define(
-//begin v1.x content
 ({
-	'bold': 'Fetstil',
+	'bold': 'Halvfet',
 	'copy': 'Kopiera',
 	'cut': 'Klipp ut',
 	'delete': 'Ta bort',
 	'indent': 'Indrag',
-	'insertHorizontalRule': 'Horisontell linjal',
+	'insertHorizontalRule': 'Horisontell linje',
 	'insertOrderedList': 'Numrerad lista',
 	'insertUnorderedList': 'Punktlista',
 	'italic': 'Kursiv',
@@ -22,14 +21,14 @@ define(
 	'strikethrough': 'Genomstruken',
 	'subscript': 'Nedsänkt',
 	'superscript': 'Upphöjt',
-	'underline': 'Understrykning',
+	'underline': 'Understruken',
 	'undo': 'Ångra',
 	'unlink': 'Ta bort länk',
 	'createLink': 'Skapa länk',
 	'toggleDir': 'Växla riktning',
 	'insertImage': 'Infoga bild',
 	'insertTable': 'Infoga/redigera tabell',
-	'toggleTableBorder': 'Aktivera/avaktivera tabellram',
+	'toggleTableBorder': 'Växla tabellinjer',
 	'deleteTable': 'Ta bort tabell',
 	'tableProp': 'Tabellegenskap',
 	'htmlToggle': 'HTML-källkod',
@@ -38,17 +37,15 @@ define(
 	'plainFormatBlock': 'Styckeformat',
 	'formatBlock': 'Styckeformat',
 	'fontSize': 'Teckenstorlek',
-	'fontName': 'Teckensnittsnamn',
+	'fontName': 'Teckensnitt',
 	'tabIndent': 'Tabbindrag',
 	"fullScreen": "Växla helskärm",
 	"viewSource": "Visa HTML-kod",
 	"print": "Skriv ut",
 	"newPage": "Ny sida",
 	/* Error messages */
-	'systemShortcut': 'Åtgärden "${0}" är endast tillgänglig i webbläsaren med hjälp av ett kortkommando. Använd ${1}.',
+	'systemShortcut': 'Åtgärden ${0} är endast tillgänglig i webbläsaren via ett tangentbordskommando. Använd ${1}.',
 	'ctrlKey':'Ctrl+${0}',
-	'appleKey':'\u2318+${0}' // "command" or open-apple key on Macintosh
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/th/FontChoice.js b/dijit/_editor/nls/th/FontChoice.js
index 9d48a6d..7d2c3a9 100644
--- a/dijit/_editor/nls/th/FontChoice.js
+++ b/dijit/_editor/nls/th/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "ขนาด",
 	fontName: "ฟอนต์",
 	formatBlock: "รูปแบบ",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "monospace",
 	cursive: "cursive",
 	fantasy: "fantasy",
-
 	noFormat: "ไม่มี",
 	p: "ย่อหน้า",
 	h1: "ส่วนหัว",
 	h2: "ส่วนหัวย่อย",
 	h3: "ส่วนย่อยของส่วนหัวย่อย",
 	pre: "การกำหนดรูปแบบล่วงหน้า",
-
 	1: "xx-small",
 	2: "x-small",
 	3: "small",
@@ -26,6 +22,4 @@ define(
 	6: "x-large",
 	7: "xx-large"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/th/LinkDialog.js b/dijit/_editor/nls/th/LinkDialog.js
index 515e441..30f00af 100644
--- a/dijit/_editor/nls/th/LinkDialog.js
+++ b/dijit/_editor/nls/th/LinkDialog.js
@@ -1,17 +1,14 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "คุณสมบัติลิงก์",
-	insertImageTitle: "คุณสมบัติอิมเมจ",
+	insertImageTitle: "คุณสมบัติรูปภาพ",
 	url: "URL:",
-	text: "รายละเอียด:",
+	text: "คำอธิบาย:",
 	target: "เป้าหมาย:",
-	set: "ตั้งค่า",
+	set: "เซ็ต",
 	currentWindow: "หน้าต่างปัจจุบัน",
 	parentWindow: "หน้าต่างหลัก",
 	topWindow: "หน้าต่างบนสุด",
 	newWindow: "หน้าต่างใหม่"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/th/commands.js b/dijit/_editor/nls/th/commands.js
index 290e913..29e7998 100644
--- a/dijit/_editor/nls/th/commands.js
+++ b/dijit/_editor/nls/th/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'ตัวหนา',
 	'copy': 'คัดลอก',
@@ -10,8 +9,8 @@ define(
 	'insertOrderedList': 'ลำดับเลข',
 	'insertUnorderedList': 'หัวข้อย่อย',
 	'italic': 'ตัวเอียง',
-	'justifyCenter': 'จัดกึ่งกลาง',
-	'justifyFull': 'จัดชิดขอบ',
+	'justifyCenter': 'จัดแนวกึ่งกลาง',
+	'justifyFull': 'ชิดขอบ',
 	'justifyLeft': 'จัดชิดซ้าย',
 	'justifyRight': 'จัดชิดขวา',
 	'outdent': 'ลดการเยื้อง',
@@ -27,7 +26,7 @@ define(
 	'unlink': 'ลบลิงก์ออก',
 	'createLink': 'สร้างลิงก์',
 	'toggleDir': 'สลับทิศทาง',
-	'insertImage': 'แทรกอิมเมจ',
+	'insertImage': 'แทรกรูปภาพ',
 	'insertTable': 'แทรก/แก้ไขตาราง',
 	'toggleTableBorder': 'สลับเส้นขอบตาราง',
 	'deleteTable': 'ลบตาราง',
@@ -45,8 +44,8 @@ define(
 	"print": "พิมพ์",
 	"newPage": "หน้าใหม่",
 	/* Error messages */
-	'systemShortcut': 'การดำเนินการ"${0}" ใช้งานได้เฉพาะกับเบราว์เซอร์ของคุณโดยใช้แป้นพิมพ์ลัด ใช้ ${1}'
+	'systemShortcut': 'แอ็กชัน "${0}" ใช้งานได้เฉพาะกับเบราว์เซอร์ของคุณโดยใช้แป้นพิมพ์ลัด ใช้ ${1}',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/tr/FontChoice.js b/dijit/_editor/nls/tr/FontChoice.js
index b97cad3..07cea02 100644
--- a/dijit/_editor/nls/tr/FontChoice.js
+++ b/dijit/_editor/nls/tr/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "Boyut",
 	fontName: "Yazı Tipi",
 	formatBlock: "Biçim",
-
 	serif: "serif",
 	"sans-serif": "sans-serif",
 	monospace: "tek aralıklı",
 	cursive: "el yazısı",
 	fantasy: "fantazi",
-
 	noFormat: "Yok",
 	p: "Paragraf",
 	h1: "Başlık",
 	h2: "Alt Başlık",
 	h3: "Alt Alt Başlık",
 	pre: "Önceden Biçimlendirilmiş",
-
 	1: "xx-küçük",
 	2: "x-küçük",
 	3: "küçük",
@@ -26,5 +22,4 @@ define(
 	6: "x-büyük",
 	7: "xx-büyük"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/tr/LinkDialog.js b/dijit/_editor/nls/tr/LinkDialog.js
index 66b04e4..c30e77c 100644
--- a/dijit/_editor/nls/tr/LinkDialog.js
+++ b/dijit/_editor/nls/tr/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "Bağlantı Özellikleri",
 	insertImageTitle: "Resim Özellikleri",
@@ -12,6 +11,4 @@ define(
 	topWindow: "En Üst Pencere",
 	newWindow: "Yeni Pencere"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/tr/commands.js b/dijit/_editor/nls/tr/commands.js
index 8b26396..4536ccf 100644
--- a/dijit/_editor/nls/tr/commands.js
+++ b/dijit/_editor/nls/tr/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': 'Kalın',
 	'copy': 'Kopyala',
@@ -45,8 +44,8 @@ define(
 	"print": "Yazdır",
 	"newPage": "Yeni Sayfa",
 	/* Error messages */
-	'systemShortcut': '"${0}" işlemi yalnızca tarayıcınızda bir klavye kısayoluyla birlikte kullanılabilir. Şunu kullanın: ${1}.'
+	'systemShortcut': '"${0}" işlemi yalnızca tarayıcınızda bir klavye kısayoluyla birlikte kullanılabilir. Şunu kullanın: ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/uk/FontChoice.js b/dijit/_editor/nls/uk/FontChoice.js
new file mode 100644
index 0000000..938d599
--- /dev/null
+++ b/dijit/_editor/nls/uk/FontChoice.js
@@ -0,0 +1,25 @@
+define(
+({
+	fontSize: "Розмір",
+	fontName: "Шрифт",
+	formatBlock: "Формат",
+	serif: "із засічками",
+	"sans-serif": "без засічок",
+	monospace: "непропорційний",
+	cursive: "курсив",
+	fantasy: "вишуканий",
+	noFormat: "Немає",
+	p: "Абзац",
+	h1: "Заголовок",
+	h2: "Підзаголовок",
+	h3: "Вкладений підзаголовок",
+	pre: "Попередній формат",
+	1: "найменший",
+	2: "дуже малий",
+	3: "малий",
+	4: "середній",
+	5: "великий",
+	6: "дуже великий",
+	7: "найбільший"
+})
+);
diff --git a/dijit/_editor/nls/uk/LinkDialog.js b/dijit/_editor/nls/uk/LinkDialog.js
new file mode 100644
index 0000000..f110690
--- /dev/null
+++ b/dijit/_editor/nls/uk/LinkDialog.js
@@ -0,0 +1,14 @@
+define(
+({
+	createLinkTitle: "Властивості посилання",
+	insertImageTitle: "Властивості зображення",
+	url: "URL:",
+	text: "Опис:",
+	target: "Призначення:",
+	set: "Встановити",
+	currentWindow: "Поточне вікно",
+	parentWindow: "Батьківське вікно",
+	topWindow: "Найвище вікно",
+	newWindow: "Нове вікно"
+})
+);
diff --git a/dijit/_editor/nls/uk/commands.js b/dijit/_editor/nls/uk/commands.js
new file mode 100644
index 0000000..3d58087
--- /dev/null
+++ b/dijit/_editor/nls/uk/commands.js
@@ -0,0 +1,51 @@
+define(
+({
+	'bold': 'Напівжирний',
+	'copy': 'Копіювати',
+	'cut': 'Вирізати',
+	'delete': 'Видалити',
+	'indent': 'Відступ',
+	'insertHorizontalRule': 'Горизонтальне правило',
+	'insertOrderedList': 'Нумерований список',
+	'insertUnorderedList': 'Список з маркерами',
+	'italic': 'Курсив',
+	'justifyCenter': 'По центру',
+	'justifyFull': 'Вирівняти',
+	'justifyLeft': 'По лівому краю',
+	'justifyRight': 'По правому краю',
+	'outdent': 'Зменшити відступ',
+	'paste': 'Вставити',
+	'redo': 'Повторити',
+	'removeFormat': 'Видалити формат',
+	'selectAll': 'Вибрати всі',
+	'strikethrough': 'Закреслений',
+	'subscript': 'Надрядковий знак',
+	'superscript': 'Надрядковий знак',
+	'underline': 'Підкреслений',
+	'undo': 'Скасувати',
+	'unlink': 'Видаліть посилання',
+	'createLink': 'Створити посилання',
+	'toggleDir': 'Перемкнути напрямок',
+	'insertImage': 'Вставити зображення',
+	'insertTable': 'Вставити/змінити таблицю',
+	'toggleTableBorder': 'Перемкнути рамки таблиці',
+	'deleteTable': 'Видалити таблицю',
+	'tableProp': 'Властивість таблиці',
+	'htmlToggle': 'Вихідний текст HTML',
+	'foreColor': 'Колір тексту',
+	'hiliteColor': 'Колір фону',
+	'plainFormatBlock': 'Формат абзацу',
+	'formatBlock': 'Формат абзацу',
+	'fontSize': 'Розмір шрифту',
+	'fontName': 'Назва шрифту',
+	'tabIndent': 'Табуляція',
+	"fullScreen": "Повноекранний режим",
+	"viewSource": "Переглянути вихідний текст HTML",
+	"print": "Друк",
+	"newPage": "Створити сторінку",
+	/* Error messages */
+	'systemShortcut': 'Дія "${0}" доступна у вашому браузері лише за допомогою клавіш швидкого доступу. Використовуйте ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
+})
+);
diff --git a/dijit/_editor/nls/zh-tw/FontChoice.js b/dijit/_editor/nls/zh-tw/FontChoice.js
index f368836..63089f6 100644
--- a/dijit/_editor/nls/zh-tw/FontChoice.js
+++ b/dijit/_editor/nls/zh-tw/FontChoice.js
@@ -1,23 +1,19 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "大小",
 	fontName: "字型",
 	formatBlock: "格式",
-
 	serif: "新細明體",
 	"sans-serif": "新細明體",
 	monospace: "等寬",
 	cursive: "Cursive",
 	fantasy: "Fantasy",
-
 	noFormat: "無",
 	p: "段落",
 	h1: "標題",
 	h2: "子標題",
 	h3: "次子標題",
 	pre: "預先格式化",
-
 	1: "最小",
 	2: "較小",
 	3: "小",
@@ -26,5 +22,4 @@ define(
 	6: "較大",
 	7: "最大"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/zh-tw/LinkDialog.js b/dijit/_editor/nls/zh-tw/LinkDialog.js
index 446327a..efc092e 100644
--- a/dijit/_editor/nls/zh-tw/LinkDialog.js
+++ b/dijit/_editor/nls/zh-tw/LinkDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "鏈結內容",
 	insertImageTitle: "影像內容",
@@ -12,6 +11,4 @@ define(
 	topWindow: "最上面的視窗",
 	newWindow: "新視窗"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/zh-tw/commands.js b/dijit/_editor/nls/zh-tw/commands.js
index 7efdda1..8019339 100644
--- a/dijit/_editor/nls/zh-tw/commands.js
+++ b/dijit/_editor/nls/zh-tw/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': '粗體',
 	'copy': '複製',
@@ -45,7 +44,8 @@ define(
 	"print": "列印",
 	"newPage": "新頁面",
 	/* Error messages */
-	'systemShortcut': '"${0}" 動作在您的瀏覽器中,只能使用鍵盤快速鍵。請使用 ${1}。'
+	'systemShortcut': '"${0}" 動作在您的瀏覽器中,只能使用鍵盤快速鍵。請使用 ${1}。',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/zh/FontChoice.js b/dijit/_editor/nls/zh/FontChoice.js
index fe3f8e9..9ae6934 100644
--- a/dijit/_editor/nls/zh/FontChoice.js
+++ b/dijit/_editor/nls/zh/FontChoice.js
@@ -1,30 +1,25 @@
 define(
-//begin v1.x content
 ({
 	fontSize: "大小",
 	fontName: "字体",
 	formatBlock: "格式",
-
 	serif: "有衬线",
 	"sans-serif": "无衬线",
 	monospace: "等宽字体",
 	cursive: "草书",
 	fantasy: "虚线",
-
 	noFormat: "无",
 	p: "段落",
 	h1: "标题",
-	h2: "子标题",
+	h2: "副标题",
 	h3: "二级子标题",
 	pre: "预设有格式的",
-
-	1: "XXS 号",
-	2: "XS 号",
-	3: "S 号",
-	4: "M 号",
-	5: "L 号",
-	6: "XL 号",
-	7: "XXL 号"
+	1: "XX 小号",
+	2: "X 小号",
+	3: "小号",
+	4: "中号",
+	5: "大号",
+	6: "X 大号",
+	7: "XX 大号"
 })
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/zh/LinkDialog.js b/dijit/_editor/nls/zh/LinkDialog.js
index e408cf0..7afad32 100644
--- a/dijit/_editor/nls/zh/LinkDialog.js
+++ b/dijit/_editor/nls/zh/LinkDialog.js
@@ -1,17 +1,14 @@
 define(
-//begin v1.x content
 ({
 	createLinkTitle: "链接属性",
 	insertImageTitle: "图像属性",
 	url: "URL:",
-	text: "描述:",
+	text: "说明:",
 	target: "目标:",
-	set: "设置",
+	set: "集",
 	currentWindow: "当前窗口",
 	parentWindow: "父窗口",
-	topWindow: "顶层窗口",
+	topWindow: "最顶层窗口",
 	newWindow: "新建窗口"
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/nls/zh/commands.js b/dijit/_editor/nls/zh/commands.js
index 46bee0b..734a744 100644
--- a/dijit/_editor/nls/zh/commands.js
+++ b/dijit/_editor/nls/zh/commands.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	'bold': '粗体',
 	'copy': '复制',
@@ -26,7 +25,7 @@ define(
 	'undo': '撤销',
 	'unlink': '除去链接',
 	'createLink': '创建链接',
-	'toggleDir': '固定方向',
+	'toggleDir': '切换方向',
 	'insertImage': '插入图像',
 	'insertTable': '插入/编辑表',
 	'toggleTableBorder': '切换表边框',
@@ -40,13 +39,13 @@ define(
 	'fontSize': '字体大小',
 	'fontName': '字体名称',
 	'tabIndent': '制表符缩进',
-	"fullScreen": "切换全屏幕",
+	"fullScreen": "切换全屏",
 	"viewSource": "查看 HTML 源代码",
 	"print": "打印",
 	"newPage": "新建页面",
 	/* Error messages */
-	'systemShortcut': '只能在浏览器中通过键盘快捷方式执行“${0}”操作。使用 ${1}。'
+	'systemShortcut': '只能通过使用键盘快捷键在浏览器中执行 "${0}" 操作。请使用 ${1}。',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
-//end v1.x content
 );
diff --git a/dijit/_editor/plugins/AlwaysShowToolbar.js b/dijit/_editor/plugins/AlwaysShowToolbar.js
index 754541a..ee71706 100644
--- a/dijit/_editor/plugins/AlwaysShowToolbar.js
+++ b/dijit/_editor/plugins/AlwaysShowToolbar.js
@@ -4,196 +4,198 @@ define([
 	"dojo/dom-construct", // domConstruct.place
 	"dojo/dom-geometry",
 	"dojo/_base/lang", // lang.hitch
-	"dojo/_base/sniff", // has("ie") has("opera")
+	"dojo/on",
+	"dojo/sniff", // has("ie") has("opera")
 	"dojo/_base/window", // win.body
 	"../_Plugin"
-], function(declare, domClass, domConstruct, domGeometry, lang, has, win, _Plugin){
-
-/*=====
-	var _Plugin = dijit._editor._Plugin;
-=====*/
-
-// module:
-//		dijit/_editor/plugins/AlwaysShowToolbar
-// summary:
-//		This plugin is required for Editors in auto-expand mode.
-//		It handles the auto-expansion as the user adds/deletes text,
-//		and keeps the editor's toolbar visible even when the top of the editor
-//		has scrolled off the top of the viewport (usually when editing a long
-//		document).
-
-
-return declare("dijit._editor.plugins.AlwaysShowToolbar", _Plugin, {
-	// summary:
-	//		This plugin is required for Editors in auto-expand mode.
-	//		It handles the auto-expansion as the user adds/deletes text,
-	//		and keeps the editor's toolbar visible even when the top of the editor
-	//		has scrolled off the top of the viewport (usually when editing a long
-	//		document).
-	// description:
-	//		Specify this in extraPlugins (or plugins) parameter and also set
-	//		height to "".
-	// example:
-	//	|	<div data-dojo-type="dijit.Editor" height=""
-	//	|	data-dojo-props="extraPlugins: [dijit._editor.plugins.AlwaysShowToolbar]">
-
-	// _handleScroll: Boolean
-	//		Enables/disables the handler for scroll events
-	_handleScroll: true,
-
-	setEditor: function(e){
-		// Overrides _Plugin.setEditor().
-		if(!e.iframe){
-			console.log('Port AlwaysShowToolbar plugin to work with Editor without iframe');
-			return;
-		}
-
-		this.editor = e;
+], function(declare, domClass, domConstruct, domGeometry, lang, on, has, win, _Plugin){
 
-		e.onLoadDeferred.addCallback(lang.hitch(this, this.enable));
-	},
+	// module:
+	//		dijit/_editor/plugins/AlwaysShowToolbar
 
-	enable: function(d){
+	return declare("dijit._editor.plugins.AlwaysShowToolbar", _Plugin, {
 		// summary:
-		//		Enable plugin.  Called when Editor has finished initializing.
-		// tags:
-		//		private
+		//		This plugin is required for Editors in auto-expand mode.
+		//		It handles the auto-expansion as the user adds/deletes text,
+		//		and keeps the editor's toolbar visible even when the top of the editor
+		//		has scrolled off the top of the viewport (usually when editing a long
+		//		document).
+		// description:
+		//		Specify this in extraPlugins (or plugins) parameter and also set
+		//		height to "".
+		// example:
+		//	|	<script type="dojo/require">
+		//	|		AlwaysShowToolbar: "dijit/_editor/plugins/AlwaysShowToolbar"
+		//	|	</script>
+		//	|	<div data-dojo-type="dijit/Editor" height=""
+		//	|			data-dojo-props="extraPlugins: [AlwaysShowToolbar]">
+
+		// _handleScroll: Boolean
+		//		Enables/disables the handler for scroll events
+		_handleScroll: true,
+
+		setEditor: function(e){
+			// Overrides _Plugin.setEditor().
+			if(!e.iframe){
+				console.log('Port AlwaysShowToolbar plugin to work with Editor without iframe');
+				return;
+			}
 
-		this._updateHeight();
-		this.connect(window, 'onscroll', "globalOnScrollHandler");
-		this.connect(this.editor, 'onNormalizedDisplayChanged', "_updateHeight");
-		return d;
-	},
+			this.editor = e;
+
+			e.onLoadDeferred.then(lang.hitch(this, this.enable));
+		},
+
+		enable: function(d){
+			// summary:
+			//		Enable plugin.  Called when Editor has finished initializing.
+			// tags:
+			//		private
+
+			this._updateHeight();
+			this.own(
+				on(window, 'scroll', lang.hitch(this, "globalOnScrollHandler")),
+				this.editor.on('NormalizedDisplayChanged', lang.hitch(this, "_updateHeight"))
+			);
+			return d;
+		},
+
+		_updateHeight: function(){
+			// summary:
+			//		Updates the height of the editor area to fit the contents.
+			var e = this.editor;
+			if(!e.isLoaded){
+				return;
+			}
+			if(e.height){
+				return;
+			}
 
-	_updateHeight: function(){
-		// summary:
-		//		Updates the height of the editor area to fit the contents.
-		var e = this.editor;
-		if(!e.isLoaded){ return; }
-		if(e.height){ return; }
-
-		var height = domGeometry.getMarginSize(e.editNode).h;
-		if(has("opera")){
-			height = e.editNode.scrollHeight;
-		}
-		// console.debug('height',height);
-		// alert(this.editNode);
+			var height = domGeometry.getMarginSize(e.editNode).h;
+			if(has("opera")){
+				height = e.editNode.scrollHeight;
+			}
+			// console.debug('height',height);
+			// alert(this.editNode);
 
-		//height maybe zero in some cases even though the content is not empty,
-		//we try the height of body instead
-		if(!height){
-			height = domGeometry.getMarginSize(e.document.body).h;
-		}
+			//height maybe zero in some cases even though the content is not empty,
+			//we try the height of body instead
+			if(!height){
+				height = domGeometry.getMarginSize(e.document.body).h;
+			}
 
-		if(height == 0){
-			console.debug("Can not figure out the height of the editing area!");
-			return; //prevent setting height to 0
-		}
-		if(has("ie") <= 7 && this.editor.minHeight){
-			var min = parseInt(this.editor.minHeight);
-			if(height < min){ height = min; }
-		}
-		if(height != this._lastHeight){
-			this._lastHeight = height;
-			// this.editorObject.style.height = this._lastHeight + "px";
-			domGeometry.setMarginBox(e.iframe, { h: this._lastHeight });
-		}
-	},
+			if(this._fixEnabled){
+				// #16204: add toolbar height when it is fixed aka "stuck to the top of the screen" to prevent content from cutting off during autosizing.
+				// Seems like _updateHeight should be taking the intitial margin height from a more appropriate node that includes the marginTop set in globalOnScrollHandler.
+				height += domGeometry.getMarginSize(this.editor.header).h;
+			}
+
+			if(height == 0){
+				console.debug("Can not figure out the height of the editing area!");
+				return; //prevent setting height to 0
+			}
+			if(has("ie") <= 7 && this.editor.minHeight){
+				var min = parseInt(this.editor.minHeight);
+				if(height < min){
+					height = min;
+				}
+			}
+			if(height != this._lastHeight){
+				this._lastHeight = height;
+				// this.editorObject.style.height = this._lastHeight + "px";
+				domGeometry.setMarginBox(e.iframe, { h: this._lastHeight });
+			}
+		},
 
-	// _lastHeight: Integer
-	//		Height in px of the editor at the last time we did sizing
-	_lastHeight: 0,
+		// _lastHeight: Integer
+		//		Height in px of the editor at the last time we did sizing
+		_lastHeight: 0,
 
-	globalOnScrollHandler: function(){
-		// summary:
-		//		Handler for scroll events that bubbled up to <html>
-		// tags:
-		//		private
-
-		var isIE6 = has("ie") < 7;
-		if(!this._handleScroll){ return; }
-		var tdn = this.editor.header;
-		if(!this._scrollSetUp){
-			this._scrollSetUp = true;
-			this._scrollThreshold = domGeometry.position(tdn, true).y;
-//			var db = win.body;
-//			console.log("threshold:", this._scrollThreshold);
-			//what's this for?? comment out for now
-//			if((isIE6)&&(db)&&(domStyle.set or get TODO(db, "backgroundIimage")=="none")){
-//				db.style.backgroundImage = "url(" + dojo.uri.moduleUri("dijit", "templates/blank.gif") + ")";
-//				db.style.backgroundAttachment = "fixed";
-//			}
-		}
+		globalOnScrollHandler: function(){
+			// summary:
+			//		Handler for scroll events that bubbled up to `<html>`
+			// tags:
+			//		private
 
-		var scrollPos = domGeometry.docScroll().y;
-		var s = tdn.style;
+			var isIE6 = has("ie") < 7;
+			if(!this._handleScroll){
+				return;
+			}
+			var tdn = this.editor.header;
+			if(!this._scrollSetUp){
+				this._scrollSetUp = true;
+				this._scrollThreshold = domGeometry.position(tdn, true).y;
+			}
 
-		if(scrollPos > this._scrollThreshold && scrollPos < this._scrollThreshold+this._lastHeight){
-			// dojo.debug(scrollPos);
-			if(!this._fixEnabled){
-				var tdnbox = domGeometry.getMarginSize(tdn);
-				this.editor.iframe.style.marginTop = tdnbox.h+"px";
+			var scrollPos = domGeometry.docScroll(this.editor.ownerDocument).y;
+			var s = tdn.style;
+
+			if(scrollPos > this._scrollThreshold && scrollPos < this._scrollThreshold + this._lastHeight){
+				// console.debug(scrollPos);
+				if(!this._fixEnabled){
+					var tdnbox = domGeometry.getMarginSize(tdn);
+					this.editor.iframe.style.marginTop = tdnbox.h + "px";
+
+					if(isIE6){
+						s.left = domGeometry.position(tdn).x;
+						if(tdn.previousSibling){
+							this._IEOriginalPos = ['after', tdn.previousSibling];
+						}else if(tdn.nextSibling){
+							this._IEOriginalPos = ['before', tdn.nextSibling];
+						}else{
+							this._IEOriginalPos = ['last', tdn.parentNode];
+						}
+						this.editor.ownerDocumentBody.appendChild(tdn);
+						domClass.add(tdn, 'dijitIEFixedToolbar');
+					}else{
+						s.position = "fixed";
+						s.top = "0px";
+					}
 
+					domGeometry.setMarginBox(tdn, { w: tdnbox.w });
+					s.zIndex = 2000;
+					this._fixEnabled = true;
+				}
+				// if we're showing the floating toolbar, make sure that if
+				// we've scrolled past the bottom of the editor that we hide
+				// the toolbar for this instance of the editor.
+
+				// TODO: when we get multiple editor toolbar support working
+				// correctly, ensure that we check this against the scroll
+				// position of the bottom-most editor instance.
+				var eHeight = (this.height) ? parseInt(this.editor.height) : this.editor._lastHeight;
+				s.display = (scrollPos > this._scrollThreshold + eHeight) ? "none" : "";
+			}else if(this._fixEnabled){
+				this.editor.iframe.style.marginTop = '';
+				s.position = "";
+				s.top = "";
+				s.zIndex = "";
+				s.display = "";
 				if(isIE6){
-					s.left = domGeometry.position(tdn).x;
-					if(tdn.previousSibling){
-						this._IEOriginalPos = ['after',tdn.previousSibling];
-					}else if(tdn.nextSibling){
-						this._IEOriginalPos = ['before',tdn.nextSibling];
+					s.left = "";
+					domClass.remove(tdn, 'dijitIEFixedToolbar');
+					if(this._IEOriginalPos){
+						domConstruct.place(tdn, this._IEOriginalPos[1], this._IEOriginalPos[0]);
+						this._IEOriginalPos = null;
 					}else{
-						this._IEOriginalPos = ['last',tdn.parentNode];
+						domConstruct.place(tdn, this.editor.iframe, 'before');
 					}
-					win.body().appendChild(tdn);
-					domClass.add(tdn,'dijitIEFixedToolbar');
-				}else{
-					s.position = "fixed";
-					s.top = "0px";
-				}
-
-				domGeometry.setMarginBox(tdn, { w: tdnbox.w });
-				s.zIndex = 2000;
-				this._fixEnabled = true;
-			}
-			// if we're showing the floating toolbar, make sure that if
-			// we've scrolled past the bottom of the editor that we hide
-			// the toolbar for this instance of the editor.
-
-			// TODO: when we get multiple editor toolbar support working
-			// correctly, ensure that we check this against the scroll
-			// position of the bottom-most editor instance.
-			var eHeight = (this.height) ? parseInt(this.editor.height) : this.editor._lastHeight;
-			s.display = (scrollPos > this._scrollThreshold+eHeight) ? "none" : "";
-		}else if(this._fixEnabled){
-			this.editor.iframe.style.marginTop = '';
-			s.position = "";
-			s.top = "";
-			s.zIndex = "";
-			s.display = "";
-			if(isIE6){
-				s.left = "";
-				domClass.remove(tdn,'dijitIEFixedToolbar');
-				if(this._IEOriginalPos){
-					domConstruct.place(tdn, this._IEOriginalPos[1], this._IEOriginalPos[0]);
-					this._IEOriginalPos = null;
-				}else{
-					domConstruct.place(tdn, this.editor.iframe, 'before');
 				}
+				s.width = "";
+				this._fixEnabled = false;
 			}
-			s.width = "";
-			this._fixEnabled = false;
-		}
-	},
+		},
 
-	destroy: function(){
-		// Overrides _Plugin.destroy().   TODO: call this.inherited() rather than repeating code.
-		this._IEOriginalPos = null;
-		this._handleScroll = false;
-		this.inherited(arguments);
+		destroy: function(){
+			// Overrides _Plugin.destroy().   TODO: call this.inherited() rather than repeating code.
+			this._IEOriginalPos = null;
+			this._handleScroll = false;
+			this.inherited(arguments);
 
-		if(has("ie") < 7){
-			domClass.remove(this.editor.header, 'dijitIEFixedToolbar');
+			if(has("ie") < 7){
+				domClass.remove(this.editor.header, 'dijitIEFixedToolbar');
+			}
 		}
-	}
-});
+	});
 
 });
diff --git a/dijit/_editor/plugins/EnterKeyHandling.js b/dijit/_editor/plugins/EnterKeyHandling.js
index 6b91105..0f76a25 100644
--- a/dijit/_editor/plugins/EnterKeyHandling.js
+++ b/dijit/_editor/plugins/EnterKeyHandling.js
@@ -1,250 +1,255 @@
 define([
 	"dojo/_base/declare", // declare
 	"dojo/dom-construct", // domConstruct.destroy domConstruct.place
-	"dojo/_base/event", // event.stop
 	"dojo/keys", // keys.ENTER
 	"dojo/_base/lang",
-	"dojo/_base/sniff", // has("ie") has("mozilla") has("webkit")
-	"dojo/_base/window", // win.global win.withGlobal
+	"dojo/on",
+	"dojo/sniff", // has("ie") has("mozilla") has("webkit")
+	"dojo/_base/window", // win.withGlobal
 	"dojo/window", // winUtils.scrollIntoView
 	"../_Plugin",
 	"../RichText",
 	"../range",
-	"../selection"
-], function(declare, domConstruct, event, keys, lang, has, win, winUtils, _Plugin, RichText, rangeapi, selectionapi){
-
-/*=====
-	var _Plugin = dijit._editor._Plugin;
-=====*/
-
-// module:
-//		dijit/_editor/plugins/EnterKeyHandling
-// summary:
-//		This plugin tries to make all browsers behave consistently with regard to
-//		how ENTER behaves in the editor window.  It traps the ENTER key and alters
-//		the way DOM is constructed in certain cases to try to commonize the generated
-//		DOM and behaviors across browsers.
-
-
-return declare("dijit._editor.plugins.EnterKeyHandling", _Plugin, {
-	// summary:
-	//		This plugin tries to make all browsers behave consistently with regard to
-	//		how ENTER behaves in the editor window.  It traps the ENTER key and alters
-	//		the way DOM is constructed in certain cases to try to commonize the generated
-	//		DOM and behaviors across browsers.
-	//
-	// description:
-	//		This plugin has three modes:
-	//
-	//			* blockNodeForEnter=BR
-	//			* blockNodeForEnter=DIV
-	//			* blockNodeForEnter=P
-	//
-	//		In blockNodeForEnter=P, the ENTER key starts a new
-	//		paragraph, and shift-ENTER starts a new line in the current paragraph.
-	//		For example, the input:
-	//
-	//		|	first paragraph <shift-ENTER>
-	//		|	second line of first paragraph <ENTER>
-	//		|	second paragraph
-	//
-	//		will generate:
-	//
-	//		|	<p>
-	//		|		first paragraph
-	//		|		<br/>
-	//		|		second line of first paragraph
-	//		|	</p>
-	//		|	<p>
-	//		|		second paragraph
-	//		|	</p>
-	//
-	//		In BR and DIV mode, the ENTER key conceptually goes to a new line in the
-	//		current paragraph, and users conceptually create a new paragraph by pressing ENTER twice.
-	//		For example, if the user enters text into an editor like this:
-	//
-	//		|		one <ENTER>
-	//		|		two <ENTER>
-	//		|		three <ENTER>
-	//		|		<ENTER>
-	//		|		four <ENTER>
-	//		|		five <ENTER>
-	//		|		six <ENTER>
-	//
-	//		It will appear on the screen as two 'paragraphs' of three lines each.  Markupwise, this generates:
-	//
-	//		BR:
-	//		|		one<br/>
-	//		|		two<br/>
-	//		|		three<br/>
-	//		|		<br/>
-	//		|		four<br/>
-	//		|		five<br/>
-	//		|		six<br/>
-	//
-	//		DIV:
-	//		|		<div>one</div>
-	//		|		<div>two</div>
-	//		|		<div>three</div>
-	//		|		<div> </div>
-	//		|		<div>four</div>
-	//		|		<div>five</div>
-	//		|		<div>six</div>
-
-	// blockNodeForEnter: String
-	//		This property decides the behavior of Enter key. It can be either P,
-	//		DIV, BR, or empty (which means disable this feature). Anything else
-	//		will trigger errors.  The default is 'BR'
-	//
-	//		See class description for more details.
-	blockNodeForEnter: 'BR',
-
-	constructor: function(args){
-		if(args){
-			if("blockNodeForEnter" in args){
-				args.blockNodeForEnter = args.blockNodeForEnter.toUpperCase();
+	"../../_base/focus"
+], function(declare, domConstruct, keys, lang, on, has, win, winUtils, _Plugin, RichText, rangeapi, baseFocus){
+
+	// module:
+	//		dijit/_editor/plugins/EnterKeyHandling
+
+	return declare("dijit._editor.plugins.EnterKeyHandling", _Plugin, {
+		// summary:
+		//		This plugin tries to make all browsers behave consistently with regard to
+		//		how ENTER behaves in the editor window.  It traps the ENTER key and alters
+		//		the way DOM is constructed in certain cases to try to commonize the generated
+		//		DOM and behaviors across browsers.
+		//
+		// description:
+		//		This plugin has three modes:
+		//
+		//		- blockNodeForEnter=BR
+		//		- blockNodeForEnter=DIV
+		//		- blockNodeForEnter=P
+		//
+		//		In blockNodeForEnter=P, the ENTER key starts a new
+		//		paragraph, and shift-ENTER starts a new line in the current paragraph.
+		//		For example, the input:
+		//
+		//	|	first paragraph <shift-ENTER>
+		//	|	second line of first paragraph <ENTER>
+		//	|	second paragraph
+		//
+		//		will generate:
+		//
+		//	|	<p>
+		//	|		first paragraph
+		//	|		<br/>
+		//	|		second line of first paragraph
+		//	|	</p>
+		//	|	<p>
+		//	|		second paragraph
+		//	|	</p>
+		//
+		//		In BR and DIV mode, the ENTER key conceptually goes to a new line in the
+		//		current paragraph, and users conceptually create a new paragraph by pressing ENTER twice.
+		//		For example, if the user enters text into an editor like this:
+		//
+		//	|		one <ENTER>
+		//	|		two <ENTER>
+		//	|		three <ENTER>
+		//	|		<ENTER>
+		//	|		four <ENTER>
+		//	|		five <ENTER>
+		//	|		six <ENTER>
+		//
+		//		It will appear on the screen as two 'paragraphs' of three lines each.  Markupwise, this generates:
+		//
+		//		BR:
+		//	|		one<br/>
+		//	|		two<br/>
+		//	|		three<br/>
+		//	|		<br/>
+		//	|		four<br/>
+		//	|		five<br/>
+		//	|		six<br/>
+		//
+		//		DIV:
+		//	|		<div>one</div>
+		//	|		<div>two</div>
+		//	|		<div>three</div>
+		//	|		<div> </div>
+		//	|		<div>four</div>
+		//	|		<div>five</div>
+		//	|		<div>six</div>
+
+		// blockNodeForEnter: String
+		//		This property decides the behavior of Enter key. It can be either P,
+		//		DIV, BR, or empty (which means disable this feature). Anything else
+		//		will trigger errors.  The default is 'BR'
+		//
+		//		See class description for more details.
+		blockNodeForEnter: 'BR',
+
+		constructor: function(args){
+			if(args){
+				if("blockNodeForEnter" in args){
+					args.blockNodeForEnter = args.blockNodeForEnter.toUpperCase();
+				}
+				lang.mixin(this, args);
 			}
-			lang.mixin(this,args);
-		}
-	},
-
-	setEditor: function(editor){
-		// Overrides _Plugin.setEditor().
-		if(this.editor === editor){ return; }
-		this.editor = editor;
-		if(this.blockNodeForEnter == 'BR'){
-			// While Moz has a mode tht mostly works, it's still a little different,
-			// So, try to just have a common mode and be consistent.  Which means
-			// we need to enable customUndo, if not already enabled.
-			this.editor.customUndo = true;
-				editor.onLoadDeferred.addCallback(lang.hitch(this,function(d){
-				this.connect(editor.document, "onkeypress", function(e){
-					if(e.charOrCode == keys.ENTER){
-						// Just do it manually.  The handleEnterKey has a shift mode that
-						// Always acts like <br>, so just use it.
-						var ne = lang.mixin({},e);
-						ne.shiftKey = true;
-						if(!this.handleEnterKey(ne)){
-							event.stop(e);
+		},
+
+		setEditor: function(editor){
+			// Overrides _Plugin.setEditor().
+			if(this.editor === editor){
+				return;
+			}
+			this.editor = editor;
+			if(this.blockNodeForEnter == 'BR'){
+				// While Moz has a mode tht mostly works, it's still a little different,
+				// So, try to just have a common mode and be consistent.  Which means
+				// we need to enable customUndo, if not already enabled.
+				this.editor.customUndo = true;
+				editor.onLoadDeferred.then(lang.hitch(this, function(d){
+					this.own(on(editor.document, "keydown", lang.hitch(this, function(e){
+						if(e.keyCode == keys.ENTER){
+							// Just do it manually.  The handleEnterKey has a shift mode that
+							// Always acts like <br>, so just use it.
+							var ne = lang.mixin({}, e);
+							ne.shiftKey = true;
+							if(!this.handleEnterKey(ne)){
+								e.stopPropagation();
+								e.preventDefault();
+							}
 						}
+					})));
+					if(has("ie") >= 9){
+						this.own(on(editor.document, "paste", lang.hitch(this, function(e){
+							setTimeout(lang.hitch(this, function(){
+								// Use the old range/selection code to kick IE 9 into updating
+								// its range by moving it back, then forward, one 'character'.
+								var r = this.editor.document.selection.createRange();
+								r.move('character', -1);
+								r.select();
+								r.move('character', 1);
+								r.select();
+							}), 0);
+						})));
 					}
-				});
 					return d;
 				}));
-		}else if(this.blockNodeForEnter){
-			// add enter key handler
-			// FIXME: need to port to the new event code!!
-			var h = lang.hitch(this,this.handleEnterKey);
-			editor.addKeyHandler(13, 0, 0, h); //enter
-			editor.addKeyHandler(13, 0, 1, h); //shift+enter
-			this.connect(this.editor,'onKeyPressed','onKeyPressed');
-		}
-	},
-	onKeyPressed: function(){
-		// summary:
-		//		Handler for keypress events.
-		// tags:
-		//		private
-		if(this._checkListLater){
-			if(win.withGlobal(this.editor.window, 'isCollapsed', dijit)){
-				var liparent=win.withGlobal(this.editor.window, 'getAncestorElement', selection, ['LI']);
-				if(!liparent){
-					// circulate the undo detection code by calling RichText::execCommand directly
-					RichText.prototype.execCommand.call(this.editor, 'formatblock',this.blockNodeForEnter);
-					// set the innerHTML of the new block node
-					var block = win.withGlobal(this.editor.window, 'getAncestorElement', selection, [this.blockNodeForEnter]);
-					if(block){
-						block.innerHTML=this.bogusHtmlContent;
-						if(has("ie")){
-							// move to the start by moving backwards one char
-							var r = this.editor.document.selection.createRange();
-							r.move('character',-1);
-							r.select();
+			}else if(this.blockNodeForEnter){
+				// add enter key handler
+				var h = lang.hitch(this, "handleEnterKey");
+				editor.addKeyHandler(13, 0, 0, h); //enter
+				editor.addKeyHandler(13, 0, 1, h); //shift+enter
+				this.own(this.editor.on('KeyPressed', lang.hitch(this, 'onKeyPressed')));
+			}
+		},
+		onKeyPressed: function(){
+			// summary:
+			//		Handler for after the user has pressed a key, and the display has been updated.
+			//		Connected to RichText's onKeyPressed() method.
+			// tags:
+			//		private
+			if(this._checkListLater){
+				if(win.withGlobal(this.editor.window, 'isCollapsed', baseFocus)){	// TODO: stop using withGlobal(), and baseFocus
+					var liparent = this.editor.selection.getAncestorElement('LI');
+					if(!liparent){
+						// circulate the undo detection code by calling RichText::execCommand directly
+						RichText.prototype.execCommand.call(this.editor, 'formatblock', this.blockNodeForEnter);
+						// set the innerHTML of the new block node
+						var block = this.editor.selection.getAncestorElement(this.blockNodeForEnter);
+						if(block){
+							block.innerHTML = this.bogusHtmlContent;
+							if(has("ie") <= 9){
+								// move to the start by moving backwards one char
+								var r = this.editor.document.selection.createRange();
+								r.move('character', -1);
+								r.select();
+							}
+						}else{
+							console.error('onKeyPressed: Cannot find the new block node'); // FIXME
 						}
 					}else{
-						console.error('onKeyPressed: Cannot find the new block node'); // FIXME
-					}
-				}else{
-					if(has("mozilla")){
-						if(liparent.parentNode.parentNode.nodeName == 'LI'){
-							liparent=liparent.parentNode.parentNode;
+						if(has("mozilla")){
+							if(liparent.parentNode.parentNode.nodeName == 'LI'){
+								liparent = liparent.parentNode.parentNode;
+							}
+						}
+						var fc = liparent.firstChild;
+						if(fc && fc.nodeType == 1 && (fc.nodeName == 'UL' || fc.nodeName == 'OL')){
+							liparent.insertBefore(fc.ownerDocument.createTextNode('\xA0'), fc);
+							var newrange = rangeapi.create(this.editor.window);
+							newrange.setStart(liparent.firstChild, 0);
+							var selection = rangeapi.getSelection(this.editor.window, true);
+							selection.removeAllRanges();
+							selection.addRange(newrange);
 						}
-					}
-					var fc=liparent.firstChild;
-					if(fc && fc.nodeType == 1 && (fc.nodeName == 'UL' || fc.nodeName == 'OL')){
-						liparent.insertBefore(fc.ownerDocument.createTextNode('\xA0'),fc);
-						var newrange = rangeapi.create(this.editor.window);
-						newrange.setStart(liparent.firstChild,0);
-						var selection = rangeapi.getSelection(this.editor.window, true);
-						selection.removeAllRanges();
-						selection.addRange(newrange);
 					}
 				}
+				this._checkListLater = false;
 			}
-			this._checkListLater = false;
-		}
-		if(this._pressedEnterInBlock){
-			// the new created is the original current P, so we have previousSibling below
-			if(this._pressedEnterInBlock.previousSibling){
-				this.removeTrailingBr(this._pressedEnterInBlock.previousSibling);
-			}
-			delete this._pressedEnterInBlock;
-		}
-	},
-
-	// bogusHtmlContent: [private] String
-	//		HTML to stick into a new empty block
-	bogusHtmlContent: ' ',		//  
-
-	// blockNodes: [private] Regex
-	//		Regex for testing if a given tag is a block level (display:block) tag
-	blockNodes: /^(?:P|H1|H2|H3|H4|H5|H6|LI)$/,
-
-	handleEnterKey: function(e){
-		// summary:
-		//		Handler for enter key events when blockNodeForEnter is DIV or P.
-		// description:
-		//		Manually handle enter key event to make the behavior consistent across
-		//		all supported browsers. See class description for details.
-		// tags:
-		//		private
-
-		var selection, range, newrange, startNode, endNode, brNode, doc=this.editor.document,br,rs,txt;
-		if(e.shiftKey){		// shift+enter always generates <br>
-			var parent = win.withGlobal(this.editor.window, "getParentElement", selectionapi);
-			var header = rangeapi.getAncestor(parent,this.blockNodes);
-			if(header){
-				if(header.tagName == 'LI'){
-					return true; // let browser handle
+			if(this._pressedEnterInBlock){
+				// the new created is the original current P, so we have previousSibling below
+				if(this._pressedEnterInBlock.previousSibling){
+					this.removeTrailingBr(this._pressedEnterInBlock.previousSibling);
 				}
-				selection = rangeapi.getSelection(this.editor.window);
-				range = selection.getRangeAt(0);
-				if(!range.collapsed){
-					range.deleteContents();
+				delete this._pressedEnterInBlock;
+			}
+		},
+
+		// bogusHtmlContent: [private] String
+		//		HTML to stick into a new empty block
+		bogusHtmlContent: ' ', //  
+
+		// blockNodes: [private] Regex
+		//		Regex for testing if a given tag is a block level (display:block) tag
+		blockNodes: /^(?:P|H1|H2|H3|H4|H5|H6|LI)$/,
+
+		handleEnterKey: function(e){
+			// summary:
+			//		Handler for enter key events when blockNodeForEnter is DIV or P.
+			// description:
+			//		Manually handle enter key event to make the behavior consistent across
+			//		all supported browsers. See class description for details.
+			// tags:
+			//		private
+
+			var selection, range, newrange, startNode, endNode, brNode, doc = this.editor.document, br, rs, txt;
+			if(e.shiftKey){        // shift+enter always generates <br>
+				var parent = this.editor.selection.getParentElement();
+				var header = rangeapi.getAncestor(parent, this.blockNodes);
+				if(header){
+					if(header.tagName == 'LI'){
+						return true; // let browser handle
+					}
 					selection = rangeapi.getSelection(this.editor.window);
 					range = selection.getRangeAt(0);
-				}
-				if(rangeapi.atBeginningOfContainer(header, range.startContainer, range.startOffset)){
-						br=doc.createElement('br');
+					if(!range.collapsed){
+						range.deleteContents();
+						selection = rangeapi.getSelection(this.editor.window);
+						range = selection.getRangeAt(0);
+					}
+					if(rangeapi.atBeginningOfContainer(header, range.startContainer, range.startOffset)){
+						br = doc.createElement('br');
 						newrange = rangeapi.create(this.editor.window);
-						header.insertBefore(br,header.firstChild);
+						header.insertBefore(br, header.firstChild);
 						newrange.setStartAfter(br);
 						selection.removeAllRanges();
 						selection.addRange(newrange);
-				}else if(rangeapi.atEndOfContainer(header, range.startContainer, range.startOffset)){
-					newrange = rangeapi.create(this.editor.window);
-					br=doc.createElement('br');
+					}else if(rangeapi.atEndOfContainer(header, range.startContainer, range.startOffset)){
+						newrange = rangeapi.create(this.editor.window);
+						br = doc.createElement('br');
 						header.appendChild(br);
 						header.appendChild(doc.createTextNode('\xA0'));
-						newrange.setStart(header.lastChild,0);
-					selection.removeAllRanges();
-					selection.addRange(newrange);
-				}else{
-					rs = range.startContainer;
-					if(rs && rs.nodeType == 3){
-						// Text node, we have to split it.
-						txt = rs.nodeValue;
-						win.withGlobal(this.editor.window, function(){
+						newrange.setStart(header.lastChild, 0);
+						selection.removeAllRanges();
+						selection.addRange(newrange);
+					}else{
+						rs = range.startContainer;
+						if(rs && rs.nodeType == 3){
+							// Text node, we have to split it.
+							txt = rs.nodeValue;
 							startNode = doc.createTextNode(txt.substring(0, range.startOffset));
 							endNode = doc.createTextNode(txt.substring(range.startOffset));
 							brNode = doc.createElement("br");
@@ -256,29 +261,27 @@ return declare("dijit._editor.plugins.EnterKeyHandling", _Plugin, {
 							domConstruct.place(brNode, startNode, "after");
 							domConstruct.place(endNode, brNode, "after");
 							domConstruct.destroy(rs);
-							newrange = rangeapi.create();
-							newrange.setStart(endNode,0);
+							newrange = rangeapi.create(this.editor.window);
+							newrange.setStart(endNode, 0);
 							selection.removeAllRanges();
 							selection.addRange(newrange);
-						});
-						return false;
-					}
-					return true; // let browser handle
-				}
-			}else{
-				selection = rangeapi.getSelection(this.editor.window);
-				if(selection.rangeCount){
-					range = selection.getRangeAt(0);
-					if(range && range.startContainer){
-						if(!range.collapsed){
-							range.deleteContents();
-							selection = rangeapi.getSelection(this.editor.window);
-							range = selection.getRangeAt(0);
+							return false;
 						}
-						rs = range.startContainer;
-						if(rs && rs.nodeType == 3){
-							// Text node, we have to split it.
-							win.withGlobal(this.editor.window, lang.hitch(this, function(){
+						return true; // let browser handle
+					}
+				}else{
+					selection = rangeapi.getSelection(this.editor.window);
+					if(selection.rangeCount){
+						range = selection.getRangeAt(0);
+						if(range && range.startContainer){
+							if(!range.collapsed){
+								range.deleteContents();
+								selection = rangeapi.getSelection(this.editor.window);
+								range = selection.getRangeAt(0);
+							}
+							rs = range.startContainer;
+							if(rs && rs.nodeType == 3){
+								// Text node, we have to split it.
 								var endEmpty = false;
 
 								var offset = range.startOffset;
@@ -307,23 +310,21 @@ return declare("dijit._editor.plugins.EnterKeyHandling", _Plugin, {
 								domConstruct.place(brNode, startNode, "after");
 								domConstruct.place(endNode, brNode, "after");
 								domConstruct.destroy(rs);
-								newrange = rangeapi.create();
-								newrange.setStart(endNode,0);
+								newrange = rangeapi.create(this.editor.window);
+								newrange.setStart(endNode, 0);
 								newrange.setEnd(endNode, endNode.length);
 								selection.removeAllRanges();
 								selection.addRange(newrange);
 								if(endEmpty && !has("webkit")){
-									selectionapi.remove();
+									this.editor.selection.remove();
 								}else{
-									selectionapi.collapse(true);
+									this.editor.selection.collapse(true);
+								}
+							}else{
+								var targetNode;
+								if(range.startOffset >= 0){
+									targetNode = rs.childNodes[range.startOffset];
 								}
-							}));
-						}else{
-							var targetNode;
-							if(range.startOffset >= 0){
-								targetNode = rs.childNodes[range.startOffset];
-							}
-							win.withGlobal(this.editor.window, lang.hitch(this, function(){
 								var brNode = doc.createElement("br");
 								var endNode = doc.createTextNode('\xA0');
 								if(!targetNode){
@@ -333,226 +334,240 @@ return declare("dijit._editor.plugins.EnterKeyHandling", _Plugin, {
 									domConstruct.place(brNode, targetNode, "before");
 									domConstruct.place(endNode, brNode, "after");
 								}
-								newrange = rangeapi.create(win.global);
-								newrange.setStart(endNode,0);
+								newrange = rangeapi.create(this.editor.window);
+								newrange.setStart(endNode, 0);
 								newrange.setEnd(endNode, endNode.length);
 								selection.removeAllRanges();
 								selection.addRange(newrange);
-								selectionapi.collapse(true);
-							}));
+								this.editor.selection.collapse(true);
+							}
 						}
+					}else{
+						// don't change this: do not call this.execCommand, as that may have other logic in subclass
+						RichText.prototype.execCommand.call(this.editor, 'inserthtml', '<br>');
 					}
-				}else{
-					// don't change this: do not call this.execCommand, as that may have other logic in subclass
-					RichText.prototype.execCommand.call(this.editor, 'inserthtml', '<br>');
 				}
+				return false;
 			}
-			return false;
-		}
-		var _letBrowserHandle = true;
+			var _letBrowserHandle = true;
 
-		// first remove selection
-		selection = rangeapi.getSelection(this.editor.window);
-		range = selection.getRangeAt(0);
-		if(!range.collapsed){
-			range.deleteContents();
+			// first remove selection
 			selection = rangeapi.getSelection(this.editor.window);
 			range = selection.getRangeAt(0);
-		}
+			if(!range.collapsed){
+				range.deleteContents();
+				selection = rangeapi.getSelection(this.editor.window);
+				range = selection.getRangeAt(0);
+			}
 
-		var block = rangeapi.getBlockAncestor(range.endContainer, null, this.editor.editNode);
-		var blockNode = block.blockNode;
+			var block = rangeapi.getBlockAncestor(range.endContainer, null, this.editor.editNode);
+			var blockNode = block.blockNode;
 
-		// if this is under a LI or the parent of the blockNode is LI, just let browser to handle it
-		if((this._checkListLater = (blockNode && (blockNode.nodeName == 'LI' || blockNode.parentNode.nodeName == 'LI')))){
-			if(has("mozilla")){
-				// press enter in middle of P may leave a trailing <br/>, let's remove it later
-				this._pressedEnterInBlock = blockNode;
-			}
-			// if this li only contains spaces, set the content to empty so the browser will outdent this item
-			if(/^(\s| | |\xA0|<span\b[^>]*\bclass=['"]Apple-style-span['"][^>]*>(\s| | |\xA0)<\/span>)?(<br>)?$/.test(blockNode.innerHTML)){
-				// empty LI node
-				blockNode.innerHTML = '';
-				if(has("webkit")){ // WebKit tosses the range when innerHTML is reset
-					newrange = rangeapi.create(this.editor.window);
-					newrange.setStart(blockNode, 0);
-					selection.removeAllRanges();
-					selection.addRange(newrange);
+			// if this is under a LI or the parent of the blockNode is LI, just let browser to handle it
+			if((this._checkListLater = (blockNode && (blockNode.nodeName == 'LI' || blockNode.parentNode.nodeName == 'LI')))){
+				if(has("mozilla")){
+					// press enter in middle of P may leave a trailing <br/>, let's remove it later
+					this._pressedEnterInBlock = blockNode;
 				}
-				this._checkListLater = false; // nothing to check since the browser handles outdent
+				// if this li only contains spaces, set the content to empty so the browser will outdent this item
+				if(/^(\s| | |\xA0|<span\b[^>]*\bclass=['"]Apple-style-span['"][^>]*>(\s| | |\xA0)<\/span>)?(<br>)?$/.test(blockNode.innerHTML)){
+					// empty LI node
+					blockNode.innerHTML = '';
+					if(has("webkit")){ // WebKit tosses the range when innerHTML is reset
+						newrange = rangeapi.create(this.editor.window);
+						newrange.setStart(blockNode, 0);
+						selection.removeAllRanges();
+						selection.addRange(newrange);
+					}
+					this._checkListLater = false; // nothing to check since the browser handles outdent
+				}
+				return true;
 			}
-			return true;
-		}
 
-		// text node directly under body, let's wrap them in a node
-		if(!block.blockNode || block.blockNode===this.editor.editNode){
-			try{
-				RichText.prototype.execCommand.call(this.editor, 'formatblock',this.blockNodeForEnter);
-			}catch(e2){ /*squelch FF3 exception bug when editor content is a single BR*/ }
-			// get the newly created block node
-			// FIXME
-			block = {blockNode:win.withGlobal(this.editor.window, "getAncestorElement", selectionapi, [this.blockNodeForEnter]),
+			// text node directly under body, let's wrap them in a node
+			if(!block.blockNode || block.blockNode === this.editor.editNode){
+				try{
+					RichText.prototype.execCommand.call(this.editor, 'formatblock', this.blockNodeForEnter);
+				}catch(e2){ /*squelch FF3 exception bug when editor content is a single BR*/
+				}
+				// get the newly created block node
+				// FIXME
+				block = {blockNode: this.editor.selection.getAncestorElement(this.blockNodeForEnter),
 					blockContainer: this.editor.editNode};
-			if(block.blockNode){
-				if(block.blockNode != this.editor.editNode &&
-					(!(block.blockNode.textContent || block.blockNode.innerHTML).replace(/^\s+|\s+$/g, "").length)){
-					this.removeTrailingBr(block.blockNode);
-					return false;
+				if(block.blockNode){
+					if(block.blockNode != this.editor.editNode &&
+						(!(block.blockNode.textContent || block.blockNode.innerHTML).replace(/^\s+|\s+$/g, "").length)){
+						this.removeTrailingBr(block.blockNode);
+						return false;
+					}
+				}else{    // we shouldn't be here if formatblock worked
+					block.blockNode = this.editor.editNode;
 				}
-			}else{	// we shouldn't be here if formatblock worked
-				block.blockNode = this.editor.editNode;
+				selection = rangeapi.getSelection(this.editor.window);
+				range = selection.getRangeAt(0);
 			}
-			selection = rangeapi.getSelection(this.editor.window);
-			range = selection.getRangeAt(0);
-		}
 
-		var newblock = doc.createElement(this.blockNodeForEnter);
-		newblock.innerHTML=this.bogusHtmlContent;
-		this.removeTrailingBr(block.blockNode);
-		var endOffset = range.endOffset;
-		var node = range.endContainer;
-		if(node.length < endOffset){
-			//We are not checking the right node, try to locate the correct one
-			var ret = this._adjustNodeAndOffset(node, endOffset);
-			node = ret.node;
-			endOffset = ret.offset;
-		}
-		if(rangeapi.atEndOfContainer(block.blockNode, node, endOffset)){
-			if(block.blockNode === block.blockContainer){
-				block.blockNode.appendChild(newblock);
-			}else{
-				domConstruct.place(newblock, block.blockNode, "after");
-			}
-			_letBrowserHandle = false;
-			// lets move caret to the newly created block
-			newrange = rangeapi.create(this.editor.window);
-			newrange.setStart(newblock, 0);
-			selection.removeAllRanges();
-			selection.addRange(newrange);
-			if(this.editor.height){
-				winUtils.scrollIntoView(newblock);
+			var newblock = doc.createElement(this.blockNodeForEnter);
+			newblock.innerHTML = this.bogusHtmlContent;
+			this.removeTrailingBr(block.blockNode);
+			var endOffset = range.endOffset;
+			var node = range.endContainer;
+			if(node.length < endOffset){
+				//We are not checking the right node, try to locate the correct one
+				var ret = this._adjustNodeAndOffset(node, endOffset);
+				node = ret.node;
+				endOffset = ret.offset;
 			}
-		}else if(rangeapi.atBeginningOfContainer(block.blockNode,
-				range.startContainer, range.startOffset)){
-			domConstruct.place(newblock, block.blockNode, block.blockNode === block.blockContainer ? "first" : "before");
-			if(newblock.nextSibling && this.editor.height){
-				// position input caret - mostly WebKit needs this
+			if(rangeapi.atEndOfContainer(block.blockNode, node, endOffset)){
+				if(block.blockNode === block.blockContainer){
+					block.blockNode.appendChild(newblock);
+				}else{
+					domConstruct.place(newblock, block.blockNode, "after");
+				}
+				_letBrowserHandle = false;
+				// lets move caret to the newly created block
 				newrange = rangeapi.create(this.editor.window);
-				newrange.setStart(newblock.nextSibling, 0);
+				newrange.setStart(newblock, 0);
 				selection.removeAllRanges();
 				selection.addRange(newrange);
-				// browser does not scroll the caret position into view, do it manually
-				winUtils.scrollIntoView(newblock.nextSibling);
-			}
-			_letBrowserHandle = false;
-		}else{ //press enter in the middle of P/DIV/Whatever/
-			if(block.blockNode === block.blockContainer){
-				block.blockNode.appendChild(newblock);
-			}else{
-				domConstruct.place(newblock, block.blockNode, "after");
-			}
-			_letBrowserHandle = false;
+				if(this.editor.height){
+					winUtils.scrollIntoView(newblock);
+				}
+			}else if(rangeapi.atBeginningOfContainer(block.blockNode,
+				range.startContainer, range.startOffset)){
+				domConstruct.place(newblock, block.blockNode, block.blockNode === block.blockContainer ? "first" : "before");
+				if(newblock.nextSibling && this.editor.height){
+					// position input caret - mostly WebKit needs this
+					newrange = rangeapi.create(this.editor.window);
+					newrange.setStart(newblock.nextSibling, 0);
+					selection.removeAllRanges();
+					selection.addRange(newrange);
+					// browser does not scroll the caret position into view, do it manually
+					winUtils.scrollIntoView(newblock.nextSibling);
+				}
+				_letBrowserHandle = false;
+			}else{ //press enter in the middle of P/DIV/Whatever/
+				if(block.blockNode === block.blockContainer){
+					block.blockNode.appendChild(newblock);
+				}else{
+					domConstruct.place(newblock, block.blockNode, "after");
+				}
+				_letBrowserHandle = false;
 
-			// Clone any block level styles.
-			if(block.blockNode.style){
-				if(newblock.style){
-					if(block.blockNode.style.cssText){
-						newblock.style.cssText = block.blockNode.style.cssText;
+				// Clone any block level styles.
+				if(block.blockNode.style){
+					if(newblock.style){
+						if(block.blockNode.style.cssText){
+							newblock.style.cssText = block.blockNode.style.cssText;
+						}
 					}
 				}
-			}
 
-			// Okay, we probably have to split.
-			rs = range.startContainer;
-			var firstNodeMoved;
-			if(rs && rs.nodeType == 3){
-				// Text node, we have to split it.
-				var nodeToMove, tNode;
-				endOffset = range.endOffset;
-				if(rs.length < endOffset){
-					//We are not splitting the right node, try to locate the correct one
-					ret = this._adjustNodeAndOffset(rs, endOffset);
-					rs = ret.node;
-					endOffset = ret.offset;
-				}
+				// Okay, we probably have to split.
+				rs = range.startContainer;
+				var firstNodeMoved;
+				if(rs && rs.nodeType == 3){
+					// Text node, we have to split it.
+					var nodeToMove, tNode;
+					endOffset = range.endOffset;
+					if(rs.length < endOffset){
+						//We are not splitting the right node, try to locate the correct one
+						ret = this._adjustNodeAndOffset(rs, endOffset);
+						rs = ret.node;
+						endOffset = ret.offset;
+					}
 
-				txt = rs.nodeValue;
-				startNode = doc.createTextNode(txt.substring(0, endOffset));
-				endNode = doc.createTextNode(txt.substring(endOffset, txt.length));
-
-				// Place the split, then remove original nodes.
-				domConstruct.place(startNode, rs, "before");
-				domConstruct.place(endNode, rs, "after");
-				domConstruct.destroy(rs);
-
-				// Okay, we split the text.  Now we need to see if we're
-				// parented to the block element we're splitting and if
-				// not, we have to split all the way up.  Ugh.
-				var parentC = startNode.parentNode;
-				while(parentC !== block.blockNode){
-					var tg = parentC.tagName;
-					var newTg = doc.createElement(tg);
-					// Clone over any 'style' data.
-					if(parentC.style){
-						if(newTg.style){
-							if(parentC.style.cssText){
-								newTg.style.cssText = parentC.style.cssText;
+					txt = rs.nodeValue;
+					startNode = doc.createTextNode(txt.substring(0, endOffset));
+					endNode = doc.createTextNode(txt.substring(endOffset, txt.length));
+
+					// Place the split, then remove original nodes.
+					domConstruct.place(startNode, rs, "before");
+					domConstruct.place(endNode, rs, "after");
+					domConstruct.destroy(rs);
+
+					// Okay, we split the text.  Now we need to see if we're
+					// parented to the block element we're splitting and if
+					// not, we have to split all the way up.  Ugh.
+					var parentC = startNode.parentNode;
+					while(parentC !== block.blockNode){
+						var tg = parentC.tagName;
+						var newTg = doc.createElement(tg);
+						// Clone over any 'style' data.
+						if(parentC.style){
+							if(newTg.style){
+								if(parentC.style.cssText){
+									newTg.style.cssText = parentC.style.cssText;
+								}
 							}
 						}
-					}
-					// If font also need to clone over any font data.
-					if(parentC.tagName === "FONT"){
-						if(parentC.color){
-							newTg.color = parentC.color;
-						}
-						if(parentC.face){
-							newTg.face = parentC.face;
+						// If font also need to clone over any font data.
+						if(parentC.tagName === "FONT"){
+							if(parentC.color){
+								newTg.color = parentC.color;
+							}
+							if(parentC.face){
+								newTg.face = parentC.face;
+							}
+							if(parentC.size){  // this check was necessary on IE
+								newTg.size = parentC.size;
+							}
 						}
-						if(parentC.size){  // this check was necessary on IE
-							newTg.size = parentC.size;
+
+						nodeToMove = endNode;
+						while(nodeToMove){
+							tNode = nodeToMove.nextSibling;
+							newTg.appendChild(nodeToMove);
+							nodeToMove = tNode;
 						}
+						domConstruct.place(newTg, parentC, "after");
+						startNode = parentC;
+						endNode = newTg;
+						parentC = parentC.parentNode;
 					}
 
+					// Lastly, move the split out tags to the new block.
+					// as they should now be split properly.
 					nodeToMove = endNode;
+					if(nodeToMove.nodeType == 1 || (nodeToMove.nodeType == 3 && nodeToMove.nodeValue)){
+						// Non-blank text and non-text nodes need to clear out that blank space
+						// before moving the contents.
+						newblock.innerHTML = "";
+					}
+					firstNodeMoved = nodeToMove;
 					while(nodeToMove){
 						tNode = nodeToMove.nextSibling;
-						newTg.appendChild(nodeToMove);
+						newblock.appendChild(nodeToMove);
 						nodeToMove = tNode;
 					}
-					domConstruct.place(newTg, parentC, "after");
-					startNode = parentC;
-					endNode = newTg;
-					parentC = parentC.parentNode;
-				}
-
-				// Lastly, move the split out tags to the new block.
-				// as they should now be split properly.
-				nodeToMove = endNode;
-				if(nodeToMove.nodeType == 1 || (nodeToMove.nodeType == 3 && nodeToMove.nodeValue)){
-					// Non-blank text and non-text nodes need to clear out that blank space
-					// before moving the contents.
-					newblock.innerHTML = "";
-				}
-				firstNodeMoved = nodeToMove;
-				while(nodeToMove){
-					tNode = nodeToMove.nextSibling;
-					newblock.appendChild(nodeToMove);
-					nodeToMove = tNode;
 				}
-			}
 
-			//lets move caret to the newly created block
-			newrange = rangeapi.create(this.editor.window);
-			var nodeForCursor;
-			var innerMostFirstNodeMoved = firstNodeMoved;
-			if(this.blockNodeForEnter !== 'BR'){
-				while(innerMostFirstNodeMoved){
-					nodeForCursor = innerMostFirstNodeMoved;
-					tNode = innerMostFirstNodeMoved.firstChild;
-					innerMostFirstNodeMoved = tNode;
-				}
-				if(nodeForCursor && nodeForCursor.parentNode){
-					newblock = nodeForCursor.parentNode;
+				//lets move caret to the newly created block
+				newrange = rangeapi.create(this.editor.window);
+				var nodeForCursor;
+				var innerMostFirstNodeMoved = firstNodeMoved;
+				if(this.blockNodeForEnter !== 'BR'){
+					while(innerMostFirstNodeMoved){
+						nodeForCursor = innerMostFirstNodeMoved;
+						tNode = innerMostFirstNodeMoved.firstChild;
+						innerMostFirstNodeMoved = tNode;
+					}
+					if(nodeForCursor && nodeForCursor.parentNode){
+						newblock = nodeForCursor.parentNode;
+						newrange.setStart(newblock, 0);
+						selection.removeAllRanges();
+						selection.addRange(newrange);
+						if(this.editor.height){
+							winUtils.scrollIntoView(newblock);
+						}
+						if(has("mozilla")){
+							// press enter in middle of P may leave a trailing <br/>, let's remove it later
+							this._pressedEnterInBlock = block.blockNode;
+						}
+					}else{
+						_letBrowserHandle = true;
+					}
+				}else{
 					newrange.setStart(newblock, 0);
 					selection.removeAllRanges();
 					selection.addRange(newrange);
@@ -563,63 +578,51 @@ return declare("dijit._editor.plugins.EnterKeyHandling", _Plugin, {
 						// press enter in middle of P may leave a trailing <br/>, let's remove it later
 						this._pressedEnterInBlock = block.blockNode;
 					}
-				}else{
-					_letBrowserHandle = true;
-				}
-			}else{
-				newrange.setStart(newblock, 0);
-				selection.removeAllRanges();
-				selection.addRange(newrange);
-				if(this.editor.height){
-					winUtils.scrollIntoView(newblock);
-				}
-				if(has("mozilla")){
-					// press enter in middle of P may leave a trailing <br/>, let's remove it later
-					this._pressedEnterInBlock = block.blockNode;
 				}
 			}
-		}
-		return _letBrowserHandle;
-	},
-
-	_adjustNodeAndOffset: function(/*DomNode*/node, /*Int*/offset){
-		// summary:
-		//              In the case there are multiple text nodes in a row the offset may not be within the node.  If the offset is larger than the node length, it will attempt to find
-		//              the next text sibling until it locates the text node in which the offset refers to
-		// node:
-		//              The node to check.
-		// offset:
-		//              The position to find within the text node
-		// tags:
-		//              private.
-		while(node.length < offset && node.nextSibling && node.nextSibling.nodeType==3){
-			//Adjust the offset and node in the case of multiple text nodes in a row
-			offset = offset - node.length;
-			node = node.nextSibling;
-		}
-		return {"node": node, "offset": offset};
-	},
+			return _letBrowserHandle;
+		},
+
+		_adjustNodeAndOffset: function(/*DomNode*/node, /*Int*/offset){
+			// summary:
+			//		In the case there are multiple text nodes in a row the offset may not be within the node.  If the offset is larger than the node length, it will attempt to find
+			//		the next text sibling until it locates the text node in which the offset refers to
+			// node:
+			//		The node to check.
+			// offset:
+			//		The position to find within the text node
+			// tags:
+			//		private.
+			while(node.length < offset && node.nextSibling && node.nextSibling.nodeType == 3){
+				//Adjust the offset and node in the case of multiple text nodes in a row
+				offset = offset - node.length;
+				node = node.nextSibling;
+			}
+			return {"node": node, "offset": offset};
+		},
+
+		removeTrailingBr: function(container){
+			// summary:
+			//		If last child of container is a `<br>`, then remove it.
+			// tags:
+			//		private
+			var para = /P|DIV|LI/i.test(container.tagName) ?
+				container : this.editor.selection.getParentOfType(container, ['P', 'DIV', 'LI']);
+
+			if(!para){
+				return;
+			}
+			if(para.lastChild){
+				if((para.childNodes.length > 1 && para.lastChild.nodeType == 3 && /^[\s\xAD]*$/.test(para.lastChild.nodeValue)) ||
+					para.lastChild.tagName == 'BR'){
 
-	removeTrailingBr: function(container){
-		// summary:
-		//		If last child of container is a <br>, then remove it.
-		// tags:
-		//		private
-		var para = /P|DIV|LI/i.test(container.tagName) ?
-			container : selectionapi.getParentOfType(container,['P','DIV','LI']);
-
-		if(!para){ return; }
-		if(para.lastChild){
-			if((para.childNodes.length > 1 && para.lastChild.nodeType == 3 && /^[\s\xAD]*$/.test(para.lastChild.nodeValue)) ||
-				para.lastChild.tagName=='BR'){
-
-				domConstruct.destroy(para.lastChild);
+					domConstruct.destroy(para.lastChild);
+				}
+			}
+			if(!para.childNodes.length){
+				para.innerHTML = this.bogusHtmlContent;
 			}
 		}
-		if(!para.childNodes.length){
-			para.innerHTML=this.bogusHtmlContent;
-		}
-	}
-});
+	});
 
 });
diff --git a/dijit/_editor/plugins/FontChoice.js b/dijit/_editor/plugins/FontChoice.js
index 042b693..76a3372 100644
--- a/dijit/_editor/plugins/FontChoice.js
+++ b/dijit/_editor/plugins/FontChoice.js
@@ -1,11 +1,11 @@
 define([
+	"require",
 	"dojo/_base/array", // array.indexOf array.map
 	"dojo/_base/declare", // declare
 	"dojo/dom-construct", // domConstruct.place
 	"dojo/i18n", // i18n.getLocalization
 	"dojo/_base/lang", // lang.delegate lang.hitch lang.isString
 	"dojo/store/Memory", // MemoryStore
-	"dojo/_base/window", // win.withGlobal
 	"../../registry", // registry.getUniqueId
 	"../../_Widget",
 	"../../_TemplatedMixin",
@@ -13,579 +13,594 @@ define([
 	"../../form/FilteringSelect",
 	"../_Plugin",
 	"../range",
-	"../selection",
 	"dojo/i18n!../nls/FontChoice"
-], function(array, declare, domConstruct, i18n, lang, MemoryStore, win,
-	registry, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, FilteringSelect, _Plugin, rangeapi, selectionapi){
-
-/*=====
-	var _Plugin = dijit._editor._Plugin;
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
-	var FilteringSelect = dijit.form.FilteringSelect;
-=====*/
-
-
-// module:
-//		dijit/_editor/plugins/FontChoice
-// summary:
-//		fontchoice, fontsize, and formatblock editor plugins
-
-
-var _FontDropDown = declare("dijit._editor.plugins._FontDropDown",
-	[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
-	// summary:
-	//		Base class for widgets that contains a label (like "Font:")
-	//		and a FilteringSelect drop down to pick a value.
-	//		Used as Toolbar entry.
-
-	// label: [public] String
-	//		The label to apply to this particular FontDropDown.
-	label: "",
-
-	// plainText: [public] boolean
-	//		Flag to indicate that the returned label should be plain text
-	//		instead of an example.
-	plainText: false,
-
-	// templateString: [public] String
-	//		The template used to construct the labeled dropdown.
-	templateString:
-		"<span style='white-space: nowrap' class='dijit dijitReset dijitInline'>" +
-			"<label class='dijitLeft dijitInline' for='${selectId}'>${label}</label>" +
-			"<input data-dojo-type='dijit.form.FilteringSelect' required='false' " +
-			        "data-dojo-props='labelType:\"html\", labelAttr:\"label\", searchAttr:\"name\"' " +
-					"tabIndex='-1' id='${selectId}' data-dojo-attach-point='select' value=''/>" +
-		"</span>",
-
-	postMixInProperties: function(){
-		// summary:
-		//		Over-ride to set specific properties.
-		this.inherited(arguments);
-
-		this.strings = i18n.getLocalization("dijit._editor", "FontChoice");
-
-		// Set some substitution variables used in the template
-		this.label = this.strings[this.command];
-		this.id = registry.getUniqueId(this.declaredClass.replace(/\./g,"_"));	// TODO: unneeded??
-		this.selectId = this.id + "_select";	// used in template
-
-		this.inherited(arguments);
-	},
-
-	postCreate: function(){
-		// summary:
-		//		Over-ride for the default postCreate action
-		//		This establishes the filtering selects and the like.
-
-		// Initialize the list of items in the drop down by creating data store with items like:
-		// {value: 1, name: "xx-small", label: "<font size=1>xx-small</font-size>" }
-		this.select.set("store", new MemoryStore({
-			idProperty: "value",
-			data: array.map(this.values, function(value){
-				var name = this.strings[value] || value;
-				return {
-					label: this.getLabel(value, name),
-					name: name,
-					value: value
-				};
-			}, this)
-		}));
-
-		this.select.set("value", "", false);
-		this.disabled = this.select.get("disabled");
-	},
-
-	_setValueAttr: function(value, priorityChange){
-		// summary:
-		//		Over-ride for the default action of setting the
-		//		widget value, maps the input to known values
-		// value: Object|String
-		//		The value to set in the select.
-		// priorityChange:
-		//		Optional parameter used to tell the select whether or not to fire
-		//		onChange event.
-
-		// if the value is not a permitted value, just set empty string to prevent showing the warning icon
-		priorityChange = priorityChange !== false;
-		this.select.set('value', array.indexOf(this.values,value) < 0 ? "" : value, priorityChange);
-		if(!priorityChange){
-			// Clear the last state in case of updateState calls.  Ref: #10466
-			this.select._lastValueReported=null;
-		}
-	},
-
-	_getValueAttr: function(){
-		// summary:
-		//		Allow retrieving the value from the composite select on
-		//		call to button.get("value");
-		return this.select.get('value');
-	},
+], function(require, array, declare, domConstruct, i18n, lang, MemoryStore,
+	registry, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, FilteringSelect, _Plugin, rangeapi){
+
+	// module:
+	//		dijit/_editor/plugins/FontChoice
+
+	var _FontDropDown = declare("dijit._editor.plugins._FontDropDown",
+		[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+			// summary:
+			//		Base class for widgets that contains a label (like "Font:")
+			//		and a FilteringSelect drop down to pick a value.
+			//		Used as Toolbar entry.
+
+			// label: [public] String
+			//		The label to apply to this particular FontDropDown.
+			label: "",
+
+			// plainText: [public] boolean
+			//		Flag to indicate that the returned label should be plain text
+			//		instead of an example.
+			plainText: false,
+
+			// templateString: [public] String
+			//		The template used to construct the labeled dropdown.
+			templateString: "<span style='white-space: nowrap' class='dijit dijitReset dijitInline'>" +
+				"<label class='dijitLeft dijitInline' for='${selectId}'>${label}</label>" +
+				"<input data-dojo-type='../../form/FilteringSelect' required='false' " +
+				"data-dojo-props='labelType:\"html\", labelAttr:\"label\", searchAttr:\"name\"' " +
+				"class='${comboClass}' " +
+				"tabIndex='-1' id='${selectId}' data-dojo-attach-point='select' value=''/>" +
+				"</span>",
+
+			// contextRequire: [public] Function
+			//		The context require that is used to resolve modules in template.
+			contextRequire: require,
+
+			postMixInProperties: function(){
+				// summary:
+				//		Over-ride to set specific properties.
+				this.inherited(arguments);
+
+				this.strings = i18n.getLocalization("dijit._editor", "FontChoice");
+
+				// Set some substitution variables used in the template
+				this.label = this.strings[this.command];
+
+				// _WidgetBase sets the id after postMixInProperties(), but we need it now.
+				// Alternative is to have a buildRendering() method and move this.selectId setting there,
+				// or alternately get rid of selectId variable and just access ${id} in template?
+				this.id = registry.getUniqueId(this.declaredClass.replace(/\./g, "_"));
+
+				this.selectId = this.id + "_select";	// used in template
+
+				this.inherited(arguments);
+			},
+
+			postCreate: function(){
+				// summary:
+				//		Over-ride for the default postCreate action
+				//		This establishes the filtering selects and the like.
+
+				// Initialize the list of items in the drop down by creating data store with items like:
+				// {value: 1, name: "xx-small", label: "<font size=1>xx-small</font-size>" }
+				this.select.set("store", new MemoryStore({
+					idProperty: "value",
+					data: array.map(this.values, function(value){
+						var name = this.strings[value] || value;
+						return {
+							label: this.getLabel(value, name),
+							name: name,
+							value: value
+						};
+					}, this)
+				}));
+
+				this.select.set("value", "", false);
+				this.disabled = this.select.get("disabled");
+			},
+
+			_setValueAttr: function(value, priorityChange){
+				// summary:
+				//		Over-ride for the default action of setting the
+				//		widget value, maps the input to known values
+				// value: Object|String
+				//		The value to set in the select.
+				// priorityChange:
+				//		Optional parameter used to tell the select whether or not to fire
+				//		onChange event.
+
+				// if the value is not a permitted value, just set empty string to prevent showing the warning icon
+				priorityChange = priorityChange !== false;
+				this.select.set('value', array.indexOf(this.values, value) < 0 ? "" : value, priorityChange);
+				if(!priorityChange){
+					// Clear the last state in case of updateState calls.  Ref: #10466
+					this.select._lastValueReported = null;
+				}
+			},
+
+			_getValueAttr: function(){
+				// summary:
+				//		Allow retrieving the value from the composite select on
+				//		call to button.get("value");
+				return this.select.get('value');
+			},
+
+			focus: function(){
+				// summary:
+				//		Over-ride for focus control of this widget.  Delegates focus down to the
+				//		filtering select.
+				this.select.focus();
+			},
+
+			_setDisabledAttr: function(value){
+				// summary:
+				//		Over-ride for the button's 'disabled' attribute so that it can be
+				//		disabled programmatically.
+
+				// Save off ths disabled state so the get retrieves it correctly
+				//without needing to have a function proxy it.
+				this._set("disabled", value);
+				this.select.set("disabled", value);
+			}
+		});
 
-	focus: function(){
-		// summary:
-		//		Over-ride for focus control of this widget.  Delegates focus down to the
-		//		filtering select.
-		this.select.focus();
-	},
 
-	_setDisabledAttr: function(value){
+	var _FontNameDropDown = declare("dijit._editor.plugins._FontNameDropDown", _FontDropDown, {
 		// summary:
-		//		Over-ride for the button's 'disabled' attribute so that it can be
-		//		disabled programmatically.
-
-		// Save off ths disabled state so the get retrieves it correctly
-		//without needing to have a function proxy it.
-		this.disabled = value;
-		this.select.set("disabled", value);
-	}
-});
-
+		//		Dropdown to select a font; goes in editor toolbar.
 
-var _FontNameDropDown = declare("dijit._editor.plugins._FontNameDropDown", _FontDropDown, {
-	// summary:
-	//		Dropdown to select a font; goes in editor toolbar.
+		// generic: [const] Boolean
+		//		Use generic (web standard) font names
+		generic: false,
 
-	// generic: Boolean
-	//		Use generic (web standard) font names
-	generic: false,
+		// command: [public] String
+		//		The editor 'command' implemented by this plugin.
+		command: "fontName",
 
-	// command: [public] String
-	//		The editor 'command' implemented by this plugin.
-	command: "fontName",
+		comboClass: "dijitFontNameCombo",
 
-	postMixInProperties: function(){
-		// summary:
-		//		Over-ride for the default posr mixin control
-		if(!this.values){
-			this.values = this.generic ?
-				["serif", "sans-serif", "monospace", "cursive", "fantasy"] : // CSS font-family generics
+		postMixInProperties: function(){
+			// summary:
+			//		Over-ride for the default posr mixin control
+			if(!this.values){
+				this.values = this.generic ?
+					["serif", "sans-serif", "monospace", "cursive", "fantasy"] : // CSS font-family generics
 					["Arial", "Times New Roman", "Comic Sans MS", "Courier New"];
+			}
+			this.inherited(arguments);
+		},
+
+		getLabel: function(value, name){
+			// summary:
+			//		Function used to generate the labels of the format dropdown
+			//		will return a formatted, or plain label based on the value
+			//		of the plainText option.
+			// value: String
+			//		The 'insert value' associated with a name
+			// name: String
+			//		The text name of the value
+			if(this.plainText){
+				return name;
+			}else{
+				return "<div style='font-family: " + value + "'>" + name + "</div>";
+			}
+		},
+
+		_setValueAttr: function(value, priorityChange){
+			// summary:
+			//		Over-ride for the default action of setting the
+			//		widget value, maps the input to known values
+
+			priorityChange = priorityChange !== false;
+			if(this.generic){
+				var map = {
+					"Arial": "sans-serif",
+					"Helvetica": "sans-serif",
+					"Myriad": "sans-serif",
+					"Times": "serif",
+					"Times New Roman": "serif",
+					"Comic Sans MS": "cursive",
+					"Apple Chancery": "cursive",
+					"Courier": "monospace",
+					"Courier New": "monospace",
+					"Papyrus": "fantasy",
+					"Estrangelo Edessa": "cursive", // Windows 7
+					"Gabriola": "fantasy" // Windows 7
+				};
+				value = map[value] || value;
+			}
+			this.inherited(arguments, [value, priorityChange]);
 		}
-		this.inherited(arguments);
-	},
-
-	getLabel: function(value, name){
-		// summary:
-		//		Function used to generate the labels of the format dropdown
-		//		will return a formatted, or plain label based on the value
-		//		of the plainText option.
-		// value: String
-		//		The 'insert value' associated with a name
-		// name: String
-		//		The text name of the value
-		if(this.plainText){
-			return name;
-		}else{
-			return "<div style='font-family: "+value+"'>" + name + "</div>";
-		}
-	},
-
-	_setValueAttr: function(value, priorityChange){
-		// summary:
-		//		Over-ride for the default action of setting the
-		//		widget value, maps the input to known values
-
-		priorityChange = priorityChange !== false;
-		if(this.generic){
-			var map = {
-				"Arial": "sans-serif",
-				"Helvetica": "sans-serif",
-				"Myriad": "sans-serif",
-				"Times": "serif",
-				"Times New Roman": "serif",
-				"Comic Sans MS": "cursive",
-				"Apple Chancery": "cursive",
-				"Courier": "monospace",
-				"Courier New": "monospace",
-				"Papyrus": "fantasy",
-				"Estrangelo Edessa": "cursive", // Windows 7
-				"Gabriola": "fantasy" // Windows 7
-			};
-			value = map[value] || value;
-		}
-		this.inherited(arguments, [value, priorityChange]);
-	}
-});
-
-var _FontSizeDropDown = declare("dijit._editor.plugins._FontSizeDropDown", _FontDropDown, {
-	// summary:
-	//		Dropdown to select a font size; goes in editor toolbar.
-
-	// command: [public] String
-	//		The editor 'command' implemented by this plugin.
-	command: "fontSize",
+	});
 
-	// values: [public] Number[]
-	//		The HTML font size values supported by this plugin
-	values: [1,2,3,4,5,6,7], // sizes according to the old HTML FONT SIZE
-
-	getLabel: function(value, name){
+	var _FontSizeDropDown = declare("dijit._editor.plugins._FontSizeDropDown", _FontDropDown, {
 		// summary:
-		//		Function used to generate the labels of the format dropdown
-		//		will return a formatted, or plain label based on the value
-		//		of the plainText option.
-		//		We're stuck using the deprecated FONT tag to correspond
-		//		with the size measurements used by the editor
-		// value: String
-		//		The 'insert value' associated with a name
-		// name: String
-		//		The text name of the value
-		if(this.plainText){
-			return name;
-		}else{
-			return "<font size=" + value + "'>" + name + "</font>";
-		}
-	},
+		//		Dropdown to select a font size; goes in editor toolbar.
+
+		// command: [public] String
+		//		The editor 'command' implemented by this plugin.
+		command: "fontSize",
+
+		comboClass: "dijitFontSizeCombo",
+
+		// values: [public] Number[]
+		//		The HTML font size values supported by this plugin
+		values: [1, 2, 3, 4, 5, 6, 7], // sizes according to the old HTML FONT SIZE
+
+		getLabel: function(value, name){
+			// summary:
+			//		Function used to generate the labels of the format dropdown
+			//		will return a formatted, or plain label based on the value
+			//		of the plainText option.
+			//		We're stuck using the deprecated FONT tag to correspond
+			//		with the size measurements used by the editor
+			// value: String
+			//		The 'insert value' associated with a name
+			// name: String
+			//		The text name of the value
+			if(this.plainText){
+				return name;
+			}else{
+				return "<font size=" + value + "'>" + name + "</font>";
+			}
+		},
+
+		_setValueAttr: function(value, priorityChange){
+			// summary:
+			//		Over-ride for the default action of setting the
+			//		widget value, maps the input to known values
+			priorityChange = priorityChange !== false;
+			if(value.indexOf && value.indexOf("px") != -1){
+				var pixels = parseInt(value, 10);
+				value = {10: 1, 13: 2, 16: 3, 18: 4, 24: 5, 32: 6, 48: 7}[pixels] || value;
+			}
 
-	_setValueAttr: function(value, priorityChange){
-		// summary:
-		//		Over-ride for the default action of setting the
-		//		widget value, maps the input to known values
-		priorityChange = priorityChange !== false;
-		if(value.indexOf && value.indexOf("px") != -1){
-			var pixels = parseInt(value, 10);
-			value = {10:1, 13:2, 16:3, 18:4, 24:5, 32:6, 48:7}[pixels] || value;
+			this.inherited(arguments, [value, priorityChange]);
 		}
+	});
 
-		this.inherited(arguments, [value, priorityChange]);
-	}
-});
-
-
-var _FormatBlockDropDown = declare("dijit._editor.plugins._FormatBlockDropDown", _FontDropDown, {
-	// summary:
-	//		Dropdown to select a format (like paragraph or heading); goes in editor toolbar.
-
-	// command: [public] String
-	//		The editor 'command' implemented by this plugin.
-	command: "formatBlock",
-
-	// values: [public] Array
-	//		The HTML format tags supported by this plugin
-	values: ["noFormat", "p", "h1", "h2", "h3", "pre"],
-
-	postCreate: function(){
-		// Init and set the default value to no formatting.  Update state will adjust it
-		// as needed.
-		this.inherited(arguments);
-		this.set("value", "noFormat", false);
-	},
-
-	getLabel: function(value, name){
-		// summary:
-		//		Function used to generate the labels of the format dropdown
-		//		will return a formatted, or plain label based on the value
-		//		of the plainText option.
-		// value: String
-		//		The 'insert value' associated with a name
-		// name: String
-		//		The text name of the value
-		if(this.plainText || value == "noFormat"){
-			return name;
-		}else{
-			return "<" + value + ">" + name + "</" + value + ">";
-		}
-	},
 
-	_execCommand: function(editor, command, choice){
+	var _FormatBlockDropDown = declare("dijit._editor.plugins._FormatBlockDropDown", _FontDropDown, {
 		// summary:
-		//		Over-ride for default exec-command label.
-		// 		Allows us to treat 'none' as special.
-		if(choice === "noFormat"){
-			var start;
-			var end;
-			var sel = rangeapi.getSelection(editor.window);
-			if(sel && sel.rangeCount > 0){
-				var range = sel.getRangeAt(0);
-				var node, tag;
-				if(range){
-					start = range.startContainer;
-					end = range.endContainer;
-
-					// find containing nodes of start/end.
-					while(start && start !== editor.editNode &&
-						  start !== editor.document.body &&
-						  start.nodeType !== 1){
-						start = start.parentNode;
-					}
+		//		Dropdown to select a format (like paragraph or heading); goes in editor toolbar.
+
+		// command: [public] String
+		//		The editor 'command' implemented by this plugin.
+		command: "formatBlock",
+
+		comboClass: "dijitFormatBlockCombo",
+
+		// values: [public] Array
+		//		The HTML format tags supported by this plugin
+		values: ["noFormat", "p", "h1", "h2", "h3", "pre"],
+
+		postCreate: function(){
+			// Init and set the default value to no formatting.  Update state will adjust it
+			// as needed.
+			this.inherited(arguments);
+			this.set("value", "noFormat", false);
+		},
+
+		getLabel: function(value, name){
+			// summary:
+			//		Function used to generate the labels of the format dropdown
+			//		will return a formatted, or plain label based on the value
+			//		of the plainText option.
+			// value: String
+			//		The 'insert value' associated with a name
+			// name: String
+			//		The text name of the value
+			if(this.plainText || value == "noFormat"){
+				return name;
+			}else{
+				return "<" + value + ">" + name + "</" + value + ">";
+			}
+		},
+
+		_execCommand: function(editor, command, choice){
+			// summary:
+			//		Over-ride for default exec-command label.
+			//		Allows us to treat 'none' as special.
+			if(choice === "noFormat"){
+				var start;
+				var end;
+				var sel = rangeapi.getSelection(editor.window);
+				if(sel && sel.rangeCount > 0){
+					var range = sel.getRangeAt(0);
+					var node, tag;
+					if(range){
+						start = range.startContainer;
+						end = range.endContainer;
+
+						// find containing nodes of start/end.
+						while(start && start !== editor.editNode &&
+							start !== editor.document.body &&
+							start.nodeType !== 1){
+							start = start.parentNode;
+						}
 
-					while(end && end !== editor.editNode &&
-						  end !== editor.document.body &&
-						  end.nodeType !== 1){
-						end = end.parentNode;
-					}
+						while(end && end !== editor.editNode &&
+							end !== editor.document.body &&
+							end.nodeType !== 1){
+							end = end.parentNode;
+						}
 
-					var processChildren = lang.hitch(this, function(node, ary){
-						if(node.childNodes && node.childNodes.length){
-							var i;
-							for(i = 0; i < node.childNodes.length; i++){
-								var c = node.childNodes[i];
-								if(c.nodeType == 1){
-									if(win.withGlobal(editor.window, "inSelection", selectionapi, [c])){
-										var tag = c.tagName? c.tagName.toLowerCase(): "";
-										if(array.indexOf(this.values, tag) !== -1){
-											ary.push(c);
+						var processChildren = lang.hitch(this, function(node, ary){
+							if(node.childNodes && node.childNodes.length){
+								var i;
+								for(i = 0; i < node.childNodes.length; i++){
+									var c = node.childNodes[i];
+									if(c.nodeType == 1){
+										if(editor.selection.inSelection(c)){
+											var tag = c.tagName ? c.tagName.toLowerCase() : "";
+											if(array.indexOf(this.values, tag) !== -1){
+												ary.push(c);
+											}
+											processChildren(c, ary);
 										}
-										processChildren(c, ary);
 									}
 								}
 							}
-						}
-					});
-
-					var unformatNodes = lang.hitch(this, function(nodes){
-						// summary:
-						//		Internal function to clear format nodes.
-						// nodes:
-						//		The array of nodes to strip formatting from.
-						if(nodes && nodes.length){
-							editor.beginEditing();
-							while(nodes.length){
-								this._removeFormat(editor, nodes.pop());
+						});
+
+						var unformatNodes = lang.hitch(this, function(nodes){
+							// summary:
+							//		Internal function to clear format nodes.
+							// nodes:
+							//		The array of nodes to strip formatting from.
+							if(nodes && nodes.length){
+								editor.beginEditing();
+								while(nodes.length){
+									this._removeFormat(editor, nodes.pop());
+								}
+								editor.endEditing();
 							}
-							editor.endEditing();
-						}
-					});
-
-					var clearNodes = [];
-					if(start == end){
-						//Contained within the same block, may be collapsed, but who cares, see if we
-						// have a block element to remove.
-						var block;
-						node = start;
-						while(node && node !== editor.editNode && node !== editor.document.body){
-							if(node.nodeType == 1){
-								tag = node.tagName? node.tagName.toLowerCase(): "";
-								if(array.indexOf(this.values, tag) !== -1){
-									block = node;
-									break;
+						});
+
+						var clearNodes = [];
+						if(start == end){
+							//Contained within the same block, may be collapsed, but who cares, see if we
+							// have a block element to remove.
+							var block;
+							node = start;
+							while(node && node !== editor.editNode && node !== editor.document.body){
+								if(node.nodeType == 1){
+									tag = node.tagName ? node.tagName.toLowerCase() : "";
+									if(array.indexOf(this.values, tag) !== -1){
+										block = node;
+										break;
+									}
 								}
+								node = node.parentNode;
 							}
-							node = node.parentNode;
-						}
 
-						//Also look for all child nodes in the selection that may need to be
-						//cleared of formatting
-						processChildren(start, clearNodes);
-						if(block){ clearNodes = [block].concat(clearNodes); }
-						unformatNodes(clearNodes);
-					}else{
-						// Probably a multi select, so we have to process it.  Whee.
-						node = start;
-						while(win.withGlobal(editor.window, "inSelection", selectionapi, [node])){
-							if(node.nodeType == 1){
-								tag = node.tagName? node.tagName.toLowerCase(): "";
-								if(array.indexOf(this.values, tag) !== -1){
-									clearNodes.push(node);
+							//Also look for all child nodes in the selection that may need to be
+							//cleared of formatting
+							processChildren(start, clearNodes);
+							if(block){
+								clearNodes = [block].concat(clearNodes);
+							}
+							unformatNodes(clearNodes);
+						}else{
+							// Probably a multi select, so we have to process it.  Whee.
+							node = start;
+							while(editor.selection.inSelection(node)){
+								if(node.nodeType == 1){
+									tag = node.tagName ? node.tagName.toLowerCase() : "";
+									if(array.indexOf(this.values, tag) !== -1){
+										clearNodes.push(node);
+									}
+									processChildren(node, clearNodes);
 								}
-								processChildren(node,clearNodes);
+								node = node.nextSibling;
 							}
-							node = node.nextSibling;
+							unformatNodes(clearNodes);
 						}
-						unformatNodes(clearNodes);
+						editor.onDisplayChanged();
 					}
-					editor.onDisplayChanged();
 				}
+			}else{
+				editor.execCommand(command, choice);
+			}
+		},
+
+		_removeFormat: function(editor, node){
+			// summary:
+			//		function to remove the block format node.
+			// node:
+			//		The block format node to remove (and leave the contents behind)
+			if(editor.customUndo){
+				// So of course IE doesn't work right with paste-overs.
+				// We have to do this manually, which is okay since IE already uses
+				// customUndo and we turned it on for WebKit.  WebKit pasted funny,
+				// so couldn't use the execCommand approach
+				while(node.firstChild){
+					domConstruct.place(node.firstChild, node, "before");
+				}
+				node.parentNode.removeChild(node);
+			}else{
+				// Everyone else works fine this way, a paste-over and is native
+				// undo friendly.
+				editor.selection.selectElementChildren(node);
+				var html = editor.selection.getSelectedHtml();
+				editor.selection.selectElement(node);
+				editor.execCommand("inserthtml", html || "");
 			}
-		}else{
-			editor.execCommand(command, choice);
 		}
-	},
+	});
 
-	_removeFormat: function(editor, node){
+	// TODO: for 2.0, split into FontChoice plugin into three separate classes,
+	// one for each command (and change registry below)
+	var FontChoice = declare("dijit._editor.plugins.FontChoice", _Plugin, {
 		// summary:
-		//		function to remove the block format node.
-		// node:
-		//		The block format node to remove (and leave the contents behind)
-		if(editor.customUndo){
-			// So of course IE doesn't work right with paste-overs.
-			// We have to do this manually, which is okay since IE already uses
-			// customUndo and we turned it on for WebKit.  WebKit pasted funny,
-			// so couldn't use the execCommand approach
-			while(node.firstChild){
-				domConstruct.place(node.firstChild, node, "before");
+		//		This plugin provides three drop downs for setting style in the editor
+		//		(font, font size, and format block), as controlled by command.
+		//
+		// description:
+		//		The commands provided by this plugin are:
+		//
+		//		- fontName: Provides a drop down to select from a list of font names
+		//		- fontSize: Provides a drop down to select from a list of font sizes
+		//		- formatBlock: Provides a drop down to select from a list of block styles
+		//		  which can easily be added to an editor by including one or more of the above commands
+		//		  in the `plugins` attribute as follows:
+		//
+		//	|	plugins="['fontName','fontSize',...]"
+		//
+		//		It is possible to override the default dropdown list by providing an Array for the `custom` property when
+		//		instantiating this plugin, e.g.
+		//
+		//	|	plugins="[{name:'dijit._editor.plugins.FontChoice', command:'fontName', values:['Verdana','Myriad','Garamond']},...]"
+		//
+		//		Alternatively, for `fontName` only, `generic:true` may be specified to provide a dropdown with
+		//		[CSS generic font families](http://www.w3.org/TR/REC-CSS2/fonts.html#generic-font-families).
+		//
+		//		Note that the editor is often unable to properly handle font styling information defined outside
+		//		the context of the current editor instance, such as pre-populated HTML.
+
+		// useDefaultCommand: [protected] Boolean
+		//		Override _Plugin.useDefaultCommand...
+		//		processing is handled by this plugin, not by dijit/Editor.
+		useDefaultCommand: false,
+
+		_initButton: function(){
+			// summary:
+			//		Overrides _Plugin._initButton(), to initialize the FilteringSelect+label in toolbar,
+			//		rather than a simple button.
+			// tags:
+			//		protected
+
+			// Create the widget to go into the toolbar (the so-called "button")
+			var clazz = {
+					fontName: _FontNameDropDown,
+					fontSize: _FontSizeDropDown,
+					formatBlock: _FormatBlockDropDown
+				}[this.command],
+				params = this.params;
+
+			// For back-compat reasons support setting custom values via "custom" parameter
+			// rather than "values" parameter.   Remove in 2.0.
+			if(this.params.custom){
+				params.values = this.params.custom;
 			}
-			node.parentNode.removeChild(node);
-		}else{
-			// Everyone else works fine this way, a paste-over and is native
-			// undo friendly.
-			win.withGlobal(editor.window,
-				 "selectElementChildren", selectionapi, [node]);
-			var html = 	win.withGlobal(editor.window,
-				 "getSelectedHtml", selectionapi, [null]);
-			win.withGlobal(editor.window,
-				 "selectElement", selectionapi, [node]);
-			editor.execCommand("inserthtml", html||"");
-		}
-	}
-});
 
-// TODO: for 2.0, split into FontChoice plugin into three separate classes,
-// one for each command (and change registry below)
-var FontChoice = declare("dijit._editor.plugins.FontChoice", _Plugin,{
-	// summary:
-	//		This plugin provides three drop downs for setting style in the editor
-	//		(font, font size, and format block), as controlled by command.
-	//
-	// description:
-	//		The commands provided by this plugin are:
-	//
-	//		* fontName
-	//	|		Provides a drop down to select from a list of font names
-	//		* fontSize
-	//	|		Provides a drop down to select from a list of font sizes
-	//		* formatBlock
-	//	|		Provides a drop down to select from a list of block styles
-	//	|
-	//
-	//		which can easily be added to an editor by including one or more of the above commands
-	//		in the `plugins` attribute as follows:
-	//
-	//	|	plugins="['fontName','fontSize',...]"
-	//
-	//		It is possible to override the default dropdown list by providing an Array for the `custom` property when
-	//		instantiating this plugin, e.g.
-	//
-	//	|	plugins="[{name:'dijit._editor.plugins.FontChoice', command:'fontName', custom:['Verdana','Myriad','Garamond']},...]"
-	//
-	//		Alternatively, for `fontName` only, `generic:true` may be specified to provide a dropdown with
-	//		[CSS generic font families](http://www.w3.org/TR/REC-CSS2/fonts.html#generic-font-families)
-	//
-	//		Note that the editor is often unable to properly handle font styling information defined outside
-	//		the context of the current editor instance, such as pre-populated HTML.
-
-	// useDefaultCommand: [protected] Boolean
-	//		Override _Plugin.useDefaultCommand...
-	//		processing is handled by this plugin, not by dijit.Editor.
-	useDefaultCommand: false,
-
-	_initButton: function(){
-		// summary:
-		//		Overrides _Plugin._initButton(), to initialize the FilteringSelect+label in toolbar,
-		//		rather than a simple button.
-		// tags:
-		//		protected
-
-		// Create the widget to go into the toolbar (the so-called "button")
-		var clazz = {
-				fontName: _FontNameDropDown,
-				fontSize: _FontSizeDropDown,
-				formatBlock: _FormatBlockDropDown
-			}[this.command],
-		params = this.params;
-
-		// For back-compat reasons support setting custom values via "custom" parameter
-		// rather than "values" parameter
-		if(this.params.custom){
-			params.values = this.params.custom;
-		}
+			var editor = this.editor;
+			this.button = new clazz(lang.delegate({dir: editor.dir, lang: editor.lang}, params));
 
-		var editor = this.editor;
-		this.button = new clazz(lang.delegate({dir: editor.dir, lang: editor.lang}, params));
+			// Reflect changes to the drop down in the editor
+			this.own(this.button.select.on("change", lang.hitch(this, function(choice){
+				// User invoked change, since all internal updates set priorityChange to false and will
+				// not trigger an onChange event.
 
-		// Reflect changes to the drop down in the editor
-		this.connect(this.button.select, "onChange", function(choice){
-			// User invoked change, since all internal updates set priorityChange to false and will
-			// not trigger an onChange event.
-			this.editor.focus();
+				if(this.editor.focused){
+					// put focus back in the iframe, unless focus has somehow been shifted out of the editor completely
+					this.editor.focus();
+				}
 
-			if(this.command == "fontName" && choice.indexOf(" ") != -1){ choice = "'" + choice + "'"; }
+				if(this.command == "fontName" && choice.indexOf(" ") != -1){
+					choice = "'" + choice + "'";
+				}
 
-			// Invoke, the editor already normalizes commands called through its
-			// execCommand.
-			if(this.button._execCommand){
-				this.button._execCommand(this.editor, this.command, choice);
-			}else{
-				this.editor.execCommand(this.command, choice);
+				// Invoke, the editor already normalizes commands called through its
+				// execCommand.
+				if(this.button._execCommand){
+					this.button._execCommand(this.editor, this.command, choice);
+				}else{
+					this.editor.execCommand(this.command, choice);
+				}
+			})));
+		},
+
+		updateState: function(){
+			// summary:
+			//		Overrides _Plugin.updateState().  This controls updating the menu
+			//		options to the right values on state changes in the document (that trigger a
+			//		test of the actions.)
+			//		It set value of drop down in toolbar to reflect font/font size/format block
+			//		of text at current caret position.
+			// tags:
+			//		protected
+			var _e = this.editor;
+			var _c = this.command;
+			if(!_e || !_e.isLoaded || !_c.length){
+				return;
 			}
-		});
-	},
 
-	updateState: function(){
-		// summary:
-		//		Overrides _Plugin.updateState().  This controls updating the menu
-		//		options to the right values on state changes in the document (that trigger a
-		//		test of the actions.)
-		//		It set value of drop down in toolbar to reflect font/font size/format block
-		//		of text at current caret position.
-		// tags:
-		//		protected
-		var _e = this.editor;
-		var _c = this.command;
-		if(!_e || !_e.isLoaded || !_c.length){ return; }
-
-		if(this.button){
-			var disabled = this.get("disabled");
-			this.button.set("disabled", disabled);
-			if(disabled){ return; }
-			var value;
-			try{
-				value = _e.queryCommandValue(_c) || "";
-			}catch(e){
-				//Firefox may throw error above if the editor is just loaded, ignore it
-				value = "";
-			}
+			if(this.button){
+				var disabled = this.get("disabled");
+				this.button.set("disabled", disabled);
+				if(disabled){
+					return;
+				}
+				var value;
+				try{
+					value = _e.queryCommandValue(_c) || "";
+				}catch(e){
+					//Firefox may throw error above if the editor is just loaded, ignore it
+					value = "";
+				}
+
+				// strip off single quotes, if any
+				var quoted = lang.isString(value) && value.match(/'([^']*)'/);
+				if(quoted){
+					value = quoted[1];
+				}
 
-			// strip off single quotes, if any
-			var quoted = lang.isString(value) && value.match(/'([^']*)'/);
-			if(quoted){ value = quoted[1]; }
-
-			if(_c === "formatBlock"){
-				if(!value || value == "p"){
-					// Some browsers (WebKit) doesn't actually get the tag info right.
-					// and IE returns paragraph when in a DIV!, so incorrect a lot,
-					// so we have double-check it.
-					value = null;
-					var elem;
-					// Try to find the current element where the caret is.
-					var sel = rangeapi.getSelection(this.editor.window);
-					if(sel && sel.rangeCount > 0){
-						var range = sel.getRangeAt(0);
-						if(range){
-							elem = range.endContainer;
+				if(_c === "formatBlock"){
+					if(!value || value == "p"){
+						// Some browsers (WebKit) doesn't actually get the tag info right.
+						// and IE returns paragraph when in a DIV!, so incorrect a lot,
+						// so we have double-check it.
+						value = null;
+						var elem;
+						// Try to find the current element where the caret is.
+						var sel = rangeapi.getSelection(this.editor.window);
+						if(sel && sel.rangeCount > 0){
+							var range = sel.getRangeAt(0);
+							if(range){
+								elem = range.endContainer;
+							}
 						}
-					}
 
-					// Okay, now see if we can find one of the formatting types we're in.
-					while(elem && elem !== _e.editNode && elem !== _e.document){
-						var tg = elem.tagName?elem.tagName.toLowerCase():"";
-						if(tg && array.indexOf(this.button.values, tg) > -1){
-							value = tg;
-							break;
+						// Okay, now see if we can find one of the formatting types we're in.
+						while(elem && elem !== _e.editNode && elem !== _e.document){
+							var tg = elem.tagName ? elem.tagName.toLowerCase() : "";
+							if(tg && array.indexOf(this.button.values, tg) > -1){
+								value = tg;
+								break;
+							}
+							elem = elem.parentNode;
+						}
+						if(!value){
+							// Still no value, so lets select 'none'.
+							value = "noFormat";
+						}
+					}else{
+						// Check that the block format is one allowed, if not,
+						// null it so that it gets set to empty.
+						if(array.indexOf(this.button.values, value) < 0){
+							value = "noFormat";
 						}
-						elem = elem.parentNode;
-					}
-					if(!value){
-						// Still no value, so lets select 'none'.
-						value = "noFormat";
-					}
-				}else{
-					// Check that the block format is one allowed, if not,
-					// null it so that it gets set to empty.
-					if(array.indexOf(this.button.values, value) < 0){
-						value = "noFormat";
 					}
 				}
-			}
-			if(value !== this.button.get("value")){
-				// Set the value, but denote it is not a priority change, so no
-				// onchange fires.
-				this.button.set('value', value, false);
+				if(value !== this.button.get("value")){
+					// Set the value, but denote it is not a priority change, so no
+					// onchange fires.
+					this.button.set('value', value, false);
+				}
 			}
 		}
-	}
-});
-
-// Register these plugins
-array.forEach(["fontName", "fontSize", "formatBlock"], function(name){
-	_Plugin.registry[name] = function(args){
-		return new FontChoice({
-			command: name,
-			plainText: args.plainText
-		});
-	};
-});
+	});
+
+	// Register these plugins
+	array.forEach(["fontName", "fontSize", "formatBlock"], function(name){
+		_Plugin.registry[name] = function(args){
+			return new FontChoice({
+				command: name,
+				plainText: args.plainText
+			});
+		};
+	});
+
+	// Make all classes available through AMD, and return main class
+	FontChoice._FontDropDown = _FontDropDown;
+	FontChoice._FontNameDropDown = _FontNameDropDown;
+	FontChoice._FontSizeDropDown = _FontSizeDropDown;
+	FontChoice._FormatBlockDropDown = _FormatBlockDropDown;
+	return FontChoice;
 
 });
diff --git a/dijit/_editor/plugins/FullScreen.js b/dijit/_editor/plugins/FullScreen.js
index 8cbe9df..6ec4844 100755
--- a/dijit/_editor/plugins/FullScreen.js
+++ b/dijit/_editor/plugins/FullScreen.js
@@ -4,345 +4,426 @@ define([
 	"dojo/dom-class", // domClass.add domClass.remove
 	"dojo/dom-geometry",
 	"dojo/dom-style",
-	"dojo/_base/event", // event.stop
 	"dojo/i18n", // i18n.getLocalization
 	"dojo/keys", // keys.F11 keys.TAB
 	"dojo/_base/lang", // lang.hitch
 	"dojo/on", // on()
-	"dojo/_base/sniff", // has("ie"), has("quirks")
+	"dojo/sniff", // has("ie"), has("quirks")
 	"dojo/_base/window", // win.body
 	"dojo/window", // winUtils.getBox winUtils.scrollIntoView
-	"../../focus",			// focus.focus(), focus.curNode
+	"../../focus", // focus.focus(), focus.curNode
 	"../_Plugin",
 	"../../form/ToggleButton",
 	"../../registry", // registry.getEnclosingWidget()
 	"dojo/i18n!../nls/commands"
-], function(aspect, declare, domClass, domGeometry, domStyle, event, i18n, keys, lang, on, has, win, winUtils,
+], function(aspect, declare, domClass, domGeometry, domStyle, i18n, keys, lang, on, has, win, winUtils,
 			focus, _Plugin, ToggleButton, registry){
 
-/*=====
-	var _Plugin = dijit._editor._Plugin;
-=====*/
+	// module:
+	//		dijit/_editor/plugins/FullScreen
 
-
-// module:
-//		dijit/_editor/plugins/FullScreen
-// summary:
-//		This plugin provides FullScreen capability to the editor.  When
-//		toggled on, it will render the editor into the full window and
-//		overlay everything.  It also binds to the hotkey: CTRL-SHIFT-F11
-//		for toggling fullscreen mode.
-
-
-var FullScreen = declare("dijit._editor.plugins.FullScreen",_Plugin,{
-	// summary:
-	//		This plugin provides FullScreen capability to the editor.  When
-	//		toggled on, it will render the editor into the full window and
-	//		overlay everything.  It also binds to the hotkey: CTRL-SHIFT-F11
-	//		for toggling fullscreen mode.
-
-	// zIndex: [public] Number
-	//		zIndex value used for overlaying the full page.
-	//		default is 500.
-	zIndex: 500,
-
-	// _origState: [private] Object
-	//		The original view state of the editor.
-	_origState: null,
-
-	// _origiFrameState: [private] Object
-	//		The original view state of the iframe of the editor.
-	_origiFrameState: null,
-
-	// _resizeHandle: [private] Object
-	//		Connection point used for handling resize when window resizes.
-	_resizeHandle: null,
-
-	// isFullscreen: [const] boolean
-	//		Read-Only variable used to denote of the editor is in fullscreen mode or not.
-	isFullscreen: false,
-
-	toggle: function(){
-		// summary:
-		//		Function to allow programmatic toggling of the view.
-		this.button.set("checked", !this.button.get("checked"));
-	},
-
-	_initButton: function(){
+	var FullScreen = declare("dijit._editor.plugins.FullScreen", _Plugin, {
 		// summary:
-		//		Over-ride for creation of the resize button.
-		var strings = i18n.getLocalization("dijit._editor", "commands"),
-			editor = this.editor;
-		this.button = new ToggleButton({
-			label: strings["fullScreen"],
-			dir: editor.dir,
-			lang: editor.lang,
-			showLabel: false,
-			iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "FullScreen",
-			tabIndex: "-1",
-			onChange: lang.hitch(this, "_setFullScreen")
-		});
-	},
-
-	setEditor: function(editor){
-		// summary:
-		//		Over-ride for the setting of the editor.
-		// editor: Object
-		//		The editor to configure for this plugin to use.
-		this.editor = editor;
-		this._initButton();
-
-		this.editor.addKeyHandler(keys.F11, true, true, lang.hitch(this, function(e){
-			// Enable the CTRL-SHIFT-F11 hotkey for fullscreen mode.
-			this.toggle();
-			event.stop(e);
-			setTimeout(lang.hitch(this, function(){this.editor.focus();}), 250);
-			return true;
-		}));
-		this.connect(this.editor.domNode, "onkeydown", "_containFocus");
-	},
-
-	_containFocus: function(e){
-		// summary:
-		//		When in Full Screen mode, it's good to try and retain focus in the editor
-		//		so this function is intended to try and constrain the TAB key.
-		// e: Event
-		//		The key event.
-		// tags:
-		//		private
-		if(this.isFullscreen){
-			var ed = this.editor;
-			if(!ed.isTabIndent &&
-				ed._fullscreen_oldOnKeyDown &&
-				e.keyCode === keys.TAB){
-				// If we're in fullscreen mode, we want to take over how tab moves focus a bit.
-				// to keep it within the editor since it's hiding the rest of the page.
-				// IE hates changing focus IN the event handler, so need to put calls
-				// in a timeout.  Gotta love IE.
-				// Also need to check for alternate view nodes if present and active.
-				var f = focus.curNode;
-				var avn = this._getAltViewNode();
-				if(f == ed.iframe ||
-					(avn && f === avn)){
-					setTimeout(lang.hitch(this, function(){
-						ed.toolbar.focus();
-					}), 10);
-				}else{
-					if(avn && domStyle.get(ed.iframe, "display") === "none"){
+		//		This plugin provides FullScreen capability to the editor.  When
+		//		toggled on, it will render the editor into the full window and
+		//		overlay everything.  It also binds to the hotkey: CTRL-SHIFT-F11
+		//		for toggling fullscreen mode.
+
+		// zIndex: [public] Number
+		//		zIndex value used for overlaying the full page.
+		//		default is 500.
+		zIndex: 500,
+
+		// _origState: [private] Object
+		//		The original view state of the editor.
+		_origState: null,
+
+		// _origiFrameState: [private] Object
+		//		The original view state of the iframe of the editor.
+		_origiFrameState: null,
+
+		// _resizeHandle: [private] Object
+		//		Connection point used for handling resize when window resizes.
+		_resizeHandle: null,
+
+		// isFullscreen: [const] boolean
+		//		Read-Only variable used to denote of the editor is in fullscreen mode or not.
+		isFullscreen: false,
+
+		toggle: function(){
+			// summary:
+			//		Function to allow programmatic toggling of the view.
+			this.button.set("checked", !this.button.get("checked"));
+		},
+
+		_initButton: function(){
+			// summary:
+			//		Over-ride for creation of the resize button.
+			var strings = i18n.getLocalization("dijit._editor", "commands"),
+				editor = this.editor;
+			this.button = new ToggleButton({
+				label: strings["fullScreen"],
+				ownerDocument: editor.ownerDocument,
+				dir: editor.dir,
+				lang: editor.lang,
+				showLabel: false,
+				iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "FullScreen",
+				tabIndex: "-1",
+				onChange: lang.hitch(this, "_setFullScreen")
+			});
+		},
+
+		setEditor: function(editor){
+			// summary:
+			//		Over-ride for the setting of the editor.
+			// editor: Object
+			//		The editor to configure for this plugin to use.
+			this.editor = editor;
+			this._initButton();
+
+			this.editor.addKeyHandler(keys.F11, true, true, lang.hitch(this, function(e){
+				// Enable the CTRL-SHIFT-F11 hotkey for fullscreen mode.
+				this.toggle();
+				e.stopPropagation();
+				e.preventDefault();
+				this.editor.defer("focus", 250);
+				return true;
+			}));
+			this.own(on(this.editor.domNode, "keydown", lang.hitch(this, "_containFocus")));
+		},
+
+		_containFocus: function(e){
+			// summary:
+			//		When in Full Screen mode, it's good to try and retain focus in the editor
+			//		so this function is intended to try and constrain the TAB key.
+			// e: Event
+			//		The key event.
+			// tags:
+			//		private
+			if(this.isFullscreen){
+				var ed = this.editor;
+				if(!ed.isTabIndent &&
+					ed._fullscreen_oldOnKeyDown &&
+					e.keyCode === keys.TAB){
+					// If we're in fullscreen mode, we want to take over how tab moves focus a bit.
+					// to keep it within the editor since it's hiding the rest of the page.
+					// IE hates changing focus IN the event handler, so need to put calls
+					// in a timeout.  Gotta love IE.
+					// Also need to check for alternate view nodes if present and active.
+					var f = focus.curNode;
+					var avn = this._getAltViewNode();
+					if(f == ed.iframe ||
+						(avn && f === avn)){
 						setTimeout(lang.hitch(this, function(){
-							focus.focus(avn);
+							ed.toolbar.focus();
 						}), 10);
 					}else{
-						setTimeout(lang.hitch(this, function(){
-							ed.focus();
-						}), 10);
+						if(avn && domStyle.get(ed.iframe, "display") === "none"){
+							setTimeout(lang.hitch(this, function(){
+								focus.focus(avn);
+							}), 10);
+						}else{
+							setTimeout(lang.hitch(this, function(){
+								ed.focus();
+							}), 10);
+						}
 					}
+					event.stopPropagation();
+					event.preventDefault();
+				}else if(ed._fullscreen_oldOnKeyDown){
+					// Only call up when it's a different function.  Traps corner case event issue
+					// on IE which caused stack overflow on handler cleanup.
+					ed._fullscreen_oldOnKeyDown(e);
 				}
-				event.stop(e);
-			}else if(ed._fullscreen_oldOnKeyDown){
-				// Only call up when it's a different function.  Traps corner case event issue
-				// on IE which caused stack overflow on handler cleanup.
-				ed._fullscreen_oldOnKeyDown(e);
 			}
-		}
-	},
+		},
+
+		_resizeEditor: function(){
+			// summary:
+			//		Function to handle resizing the editor as the viewport
+			//		resizes (window scaled)
+			// tags:
+			//		private
+			var vp = winUtils.getBox(this.editor.ownerDocument);
+			domGeometry.setMarginBox(this.editor.domNode, {
+				w: vp.w,
+				h: vp.h
+			});
 
-	_resizeEditor: function(){
-		// summary:
-		//		Function to handle resizing the editor as the viewport
-		//		resizes (window scaled)
-		// tags:
-		//		private
-		var vp = winUtils.getBox();
-		domGeometry.setMarginBox(this.editor.domNode, {
-			w: vp.w,
-			h: vp.h
-		});
+			//Adjust the internal heights too, as they can be a bit off.
+			var hHeight = this.editor.getHeaderHeight();
+			var fHeight = this.editor.getFooterHeight();
+			var extents = domGeometry.getPadBorderExtents(this.editor.domNode);
+			var fcpExtents = domGeometry.getPadBorderExtents(this.editor.iframe.parentNode);
+			var fcmExtents = domGeometry.getMarginExtents(this.editor.iframe.parentNode);
+
+			var cHeight = vp.h - (hHeight + extents.h + fHeight);
+			domGeometry.setMarginBox(this.editor.iframe.parentNode, {
+				h: cHeight,
+				w: vp.w
+			});
+			domGeometry.setMarginBox(this.editor.iframe, {
+				h: cHeight - (fcpExtents.h + fcmExtents.h)
+			});
+		},
+
+		_getAltViewNode: function(){
+			// summary:
+			//		This function is intended as a hook point for setting an
+			//		alternate view node for when in full screen mode and the
+			//		editable iframe is hidden.
+			// tags:
+			//		protected.
+		},
+
+		_setFullScreen: function(full){
+			// summary:
+			//		Function to handle toggling between full screen and
+			//		regular view.
+			// tags:
+			//		private
+
+			//Alias this for shorter code.
+			var ed = this.editor;
+			var body = ed.ownerDocumentBody;
+			var editorParent = ed.domNode.parentNode;
 
-		//Adjust the internal heights too, as they can be a bit off.
-		var hHeight = this.editor.getHeaderHeight();
-		var fHeight = this.editor.getFooterHeight();
-		var extents = domGeometry.getPadBorderExtents(this.editor.domNode);
-		var fcpExtents = domGeometry.getPadBorderExtents(this.editor.iframe.parentNode);
-		var fcmExtents = domGeometry.getMarginExtents(this.editor.iframe.parentNode);
-
-		var cHeight = vp.h - (hHeight + extents.h + fHeight);
-		domGeometry.setMarginBox(this.editor.iframe.parentNode, {
-			h: cHeight,
-			w: vp.w
-		});
-		domGeometry.setMarginBox(this.editor.iframe, {
-			h: cHeight - (fcpExtents.h + fcmExtents.h)
-		});
-	},
+			var vp = winUtils.getBox(ed.ownerDocument);
 
-	_getAltViewNode: function(){
-		// summary:
-		//		This function is intended as a hook point for setting an
-		//		alternate view node for when in full screen mode and the
-		//		editable iframe is hidden.
-		// tags:
-		//		protected.
-	},
-
-	_setFullScreen: function(full){
-		// summary:
-		//		Function to handle toggling between full screen and
-		//		regular view.
-		// tags:
-		//		private
-		var vp = winUtils.getBox();
-
-		//Alias this for shorter code.
-		var ed = this.editor;
-		var body = win.body();
-		var editorParent = ed.domNode.parentNode;
-
-		this.isFullscreen = full;
-
-		if(full){
-			//Parent classes can royally screw up this plugin, so we
-			//have to set everything to position static.
-			while(editorParent && editorParent !== win.body()){
-				domClass.add(editorParent, "dijitForceStatic");
-				editorParent = editorParent.parentNode;
-			}
+			this.isFullscreen = full;
 
-			// Save off the resize function.  We want to kill its behavior.
-			this._editorResizeHolder = this.editor.resize;
-			ed.resize = function(){} ;
-
-			// Try to constrain focus control.
-			ed._fullscreen_oldOnKeyDown = ed.onKeyDown;
-			ed.onKeyDown = lang.hitch(this, this._containFocus);
-
-			this._origState = {};
-			this._origiFrameState = {};
-
-			// Store the basic editor state we have to restore later.
-			// Not using domStyle.get here, had problems, didn't
-			// give me stuff like 100%, gave me pixel calculated values.
-			// Need the exact original values.
-			var domNode = ed.domNode,
-				rawStyle = domNode && domNode.style || {};
-			this._origState = {
-				width: rawStyle.width || "",
-				height: rawStyle.height || "",
-				top: domStyle.get(domNode, "top") || "",
-				left: domStyle.get(domNode, "left") || "",
-				position: domStyle.get(domNode, "position") || "static",
-				marginBox: domGeometry.getMarginBox(ed.domNode)
-			};
-
-			// Store the iframe state we have to restore later.
-			// Not using domStyle.get here, had problems, didn't
-			// give me stuff like 100%, gave me pixel calculated values.
-			// Need the exact original values.
-			var iframe = ed.iframe,
-				iframeStyle = iframe && iframe.style || {};
-
-			var bc = domStyle.get(ed.iframe, "backgroundColor");
-			this._origiFrameState = {
-				backgroundColor: bc || "transparent",
-				width: iframeStyle.width || "auto",
-				height: iframeStyle.height || "auto",
-				zIndex: iframeStyle.zIndex || ""
-			};
-
-			// Okay, size everything.
-			domStyle.set(ed.domNode, {
-				position: "absolute",
-				top: "0px",
-				left: "0px",
-				zIndex: this.zIndex,
-				width: vp.w + "px",
-				height: vp.h + "px"
-			});
+			if(full){
+				//Parent classes can royally screw up this plugin, so we
+				//have to set everything to position static.
+				while(editorParent && editorParent !== body){
+					domClass.add(editorParent, "dijitForceStatic");
+					editorParent = editorParent.parentNode;
+				}
 
-			domStyle.set(ed.iframe, {
-				height: "100%",
-				width: "100%",
-				zIndex: this.zIndex,
-				backgroundColor: bc !== "transparent" &&
-					bc !== "rgba(0, 0, 0, 0)"?bc:"white"
-			});
+				// Save off the resize function.  We want to kill its behavior.
+				this._editorResizeHolder = this.editor.resize;
+				ed.resize = function(){
+				};
+
+				// Try to constrain focus control.
+				ed._fullscreen_oldOnKeyDown = ed.onKeyDown;
+				ed.onKeyDown = lang.hitch(this, this._containFocus);
+
+				this._origState = {};
+				this._origiFrameState = {};
+
+				// Store the basic editor state we have to restore later.
+				// Not using domStyle.get here, had problems, didn't
+				// give me stuff like 100%, gave me pixel calculated values.
+				// Need the exact original values.
+				var domNode = ed.domNode,
+					rawStyle = domNode && domNode.style || {};
+				this._origState = {
+					width: rawStyle.width || "",
+					height: rawStyle.height || "",
+					top: domStyle.get(domNode, "top") || "",
+					left: domStyle.get(domNode, "left") || "",
+					position: domStyle.get(domNode, "position") || "static",
+					marginBox: domGeometry.getMarginBox(ed.domNode)
+				};
+
+				// Store the iframe state we have to restore later.
+				// Not using domStyle.get here, had problems, didn't
+				// give me stuff like 100%, gave me pixel calculated values.
+				// Need the exact original values.
+				var iframe = ed.iframe,
+					iframeStyle = iframe && iframe.style || {};
+
+				var bc = domStyle.get(ed.iframe, "backgroundColor");
+				this._origiFrameState = {
+					backgroundColor: bc || "transparent",
+					width: iframeStyle.width || "auto",
+					height: iframeStyle.height || "auto",
+					zIndex: iframeStyle.zIndex || ""
+				};
+
+				// Okay, size everything.
+				domStyle.set(ed.domNode, {
+					position: "absolute",
+					top: "0px",
+					left: "0px",
+					zIndex: this.zIndex,
+					width: vp.w + "px",
+					height: vp.h + "px"
+				});
 
-			domStyle.set(ed.iframe.parentNode, {
-				height: "95%",
-				width: "100%"
-			});
+				domStyle.set(ed.iframe, {
+					height: "100%",
+					width: "100%",
+					zIndex: this.zIndex,
+					backgroundColor: bc !== "transparent" &&
+						bc !== "rgba(0, 0, 0, 0)" ? bc : "white"
+				});
 
-			// Store the overflow state we have to restore later.
-			// IE had issues, so have to check that it's defined.  Ugh.
-			if(body.style && body.style.overflow){
-				this._oldOverflow = domStyle.get(body, "overflow");
-			}else{
-				this._oldOverflow = "";
-			}
+				domStyle.set(ed.iframe.parentNode, {
+					height: "95%",
+					width: "100%"
+				});
 
-			if(has("ie") && !has("quirks")){
-				// IE will put scrollbars in anyway, html (parent of body)
-				// also controls them in standards mode, so we have to
-				// remove them, argh.
-				if(body.parentNode &&
-					body.parentNode.style &&
-					body.parentNode.style.overflow){
-					this._oldBodyParentOverflow = body.parentNode.style.overflow;
+				// Store the overflow state we have to restore later.
+				// IE had issues, so have to check that it's defined.  Ugh.
+				if(body.style && body.style.overflow){
+					this._oldOverflow = domStyle.get(body, "overflow");
 				}else{
-					try{
-						this._oldBodyParentOverflow = domStyle.get(body.parentNode, "overflow");
-					}catch(e){
-						this._oldBodyParentOverflow = "scroll";
+					this._oldOverflow = "";
+				}
+
+				if(has("ie") && !has("quirks")){
+					// IE will put scrollbars in anyway, html (parent of body)
+					// also controls them in standards mode, so we have to
+					// remove them, argh.
+					if(body.parentNode &&
+						body.parentNode.style &&
+						body.parentNode.style.overflow){
+						this._oldBodyParentOverflow = body.parentNode.style.overflow;
+					}else{
+						try{
+							this._oldBodyParentOverflow = domStyle.get(body.parentNode, "overflow");
+						}catch(e){
+							this._oldBodyParentOverflow = "scroll";
+						}
 					}
+					domStyle.set(body.parentNode, "overflow", "hidden");
 				}
-				domStyle.set(body.parentNode, "overflow", "hidden");
-			}
-			domStyle.set(body, "overflow", "hidden");
-
-			var resizer = function(){
-				// function to handle resize events.
-				// Will check current VP and only resize if
-				// different.
-				var vp = winUtils.getBox();
-				if("_prevW" in this && "_prevH" in this){
-					// No actual size change, ignore.
-					if(vp.w === this._prevW && vp.h === this._prevH){
-						return;
+				domStyle.set(body, "overflow", "hidden");
+
+				var resizer = function(){
+					// function to handle resize events.
+					// Will check current VP and only resize if
+					// different.
+					var vp = winUtils.getBox(ed.ownerDocument);
+					if("_prevW" in this && "_prevH" in this){
+						// No actual size change, ignore.
+						if(vp.w === this._prevW && vp.h === this._prevH){
+							return;
+						}
+					}else{
+						this._prevW = vp.w;
+						this._prevH = vp.h;
 					}
-				}else{
-					this._prevW = vp.w;
-					this._prevH = vp.h;
+					if(this._resizer){
+						clearTimeout(this._resizer);
+						delete this._resizer;
+					}
+					// Timeout it to help avoid spamming resize on IE.
+					// Works for all browsers.
+					this._resizer = setTimeout(lang.hitch(this, function(){
+						delete this._resizer;
+						this._resizeEditor();
+					}), 10);
+				};
+				this._resizeHandle = on(window, "resize", lang.hitch(this, resizer));
+
+				// Also monitor for direct calls to resize and adapt editor.
+				this._resizeHandle2 = aspect.after(ed, "onResize", lang.hitch(this, function(){
+					if(this._resizer){
+						clearTimeout(this._resizer);
+						delete this._resizer;
+					}
+					this._resizer = setTimeout(lang.hitch(this, function(){
+						delete this._resizer;
+						this._resizeEditor();
+					}), 10);
+				}));
+
+				// Call it once to work around IE glitchiness.  Safe for other browsers too.
+				this._resizeEditor();
+				var dn = this.editor.toolbar.domNode;
+				setTimeout(function(){
+					winUtils.scrollIntoView(dn);
+				}, 250);
+			}else{
+				if(this._resizeHandle){
+					// Cleanup resizing listeners
+					this._resizeHandle.remove();
+					this._resizeHandle = null;
 				}
-				if(this._resizer){
-					clearTimeout(this._resizer);
-					delete this._resizer;
+				if(this._resizeHandle2){
+					// Cleanup resizing listeners
+					this._resizeHandle2.remove();
+					this._resizeHandle2 = null;
 				}
-				// Timeout it to help avoid spamming resize on IE.
-				// Works for all browsers.
-				this._resizer = setTimeout(lang.hitch(this, function(){
-					delete this._resizer;
-					this._resizeEditor();
-				}), 10);
-			};
-			this._resizeHandle = on(window, "resize", lang.hitch(this, resizer));
-
-			// Also monitor for direct calls to resize and adapt editor.
-			this._resizeHandle2 = aspect.after(ed, "onResize", lang.hitch(this, function(){
-				if(this._resizer){
-					clearTimeout(this._resizer);
-					delete this._resizer;
+				if(this._rst){
+					clearTimeout(this._rst);
+					this._rst = null;
+				}
+
+				//Remove all position static class assigns.
+				while(editorParent && editorParent !== body){
+					domClass.remove(editorParent, "dijitForceStatic");
+					editorParent = editorParent.parentNode;
+				}
+
+				// Restore resize function
+				if(this._editorResizeHolder){
+					this.editor.resize = this._editorResizeHolder;
 				}
-				this._resizer = setTimeout(lang.hitch(this, function(){
-					delete this._resizer;
-					this._resizeEditor();
-				}), 10);
-			}));
 
-			// Call it once to work around IE glitchiness.  Safe for other browsers too.
-			this._resizeEditor();
-			var dn = this.editor.toolbar.domNode;
-			setTimeout(function(){winUtils.scrollIntoView(dn);}, 250);
-		}else{
+				if(!this._origState && !this._origiFrameState){
+					// If we actually didn't toggle, then don't do anything.
+					return;
+				}
+				if(ed._fullscreen_oldOnKeyDown){
+					ed.onKeyDown = ed._fullscreen_oldOnKeyDown;
+					delete ed._fullscreen_oldOnKeyDown;
+				}
+
+				// Add a timeout to make sure we don't have a resize firing in the
+				// background at the time of minimize.
+				var self = this;
+				setTimeout(function(){
+					// Restore all the editor state.
+					var mb = self._origState.marginBox;
+					var oh = self._origState.height;
+					if(has("ie") && !has("quirks")){
+						body.parentNode.style.overflow = self._oldBodyParentOverflow;
+						delete self._oldBodyParentOverflow;
+					}
+					domStyle.set(body, "overflow", self._oldOverflow);
+					delete self._oldOverflow;
+
+					domStyle.set(ed.domNode, self._origState);
+					domStyle.set(ed.iframe.parentNode, {
+						height: "",
+						width: ""
+					});
+					domStyle.set(ed.iframe, self._origiFrameState);
+					delete self._origState;
+					delete self._origiFrameState;
+					// In case it is contained in a layout and the layout changed size,
+					// go ahead and call resize.
+					var pWidget = registry.getEnclosingWidget(ed.domNode.parentNode);
+					if(pWidget && pWidget.resize){
+						pWidget.resize();
+					}else{
+						if(!oh || oh.indexOf("%") < 0){
+							// Resize if the original size wasn't set
+							// or wasn't in percent.  Timeout is to avoid
+							// an IE crash in unit testing.
+							setTimeout(lang.hitch(this, function(){
+								ed.resize({h: mb.h});
+							}), 0);
+						}
+					}
+					winUtils.scrollIntoView(self.editor.toolbar.domNode);
+				}, 100);
+			}
+		},
+
+		updateState: function(){
+			// summary:
+			//		Over-ride for button state control for disabled to work.
+			this.button.set("disabled", this.get("disabled"));
+		},
+
+		destroy: function(){
+			// summary:
+			//		Over-ride to ensure the resize handle gets cleaned up.
 			if(this._resizeHandle){
 				// Cleanup resizing listeners
 				this._resizeHandle.remove();
@@ -353,105 +434,21 @@ var FullScreen = declare("dijit._editor.plugins.FullScreen",_Plugin,{
 				this._resizeHandle2.remove();
 				this._resizeHandle2 = null;
 			}
-			if(this._rst){
-				clearTimeout(this._rst);
-				this._rst = null;
-			}
-
-			//Remove all position static class assigns.
-			while(editorParent && editorParent !== win.body()){
-				domClass.remove(editorParent, "dijitForceStatic");
-				editorParent = editorParent.parentNode;
-			}
-
-			// Restore resize function
-			if(this._editorResizeHolder){
-				this.editor.resize = this._editorResizeHolder;
-			}
-
-			if(!this._origState && !this._origiFrameState){
-				// If we actually didn't toggle, then don't do anything.
-				return;
+			if(this._resizer){
+				clearTimeout(this._resizer);
+				this._resizer = null;
 			}
-			if(ed._fullscreen_oldOnKeyDown){
-				ed.onKeyDown = ed._fullscreen_oldOnKeyDown;
-				delete ed._fullscreen_oldOnKeyDown;
-			}
-
-			// Add a timeout to make sure we don't have a resize firing in the
-			// background at the time of minimize.
-			var self = this;
-			setTimeout(function(){
-				// Restore all the editor state.
-				var mb = self._origState.marginBox;
-				var oh = self._origState.height;
-				if(has("ie") && !has("quirks")){
-					body.parentNode.style.overflow = self._oldBodyParentOverflow;
-					delete self._oldBodyParentOverflow;
-				}
-				domStyle.set(body, "overflow", self._oldOverflow);
-				delete self._oldOverflow;
-
-				domStyle.set(ed.domNode, self._origState);
-				domStyle.set(ed.iframe.parentNode, {
-					height: "",
-					width: ""
-				});
-				domStyle.set(ed.iframe, self._origiFrameState);
-				delete self._origState;
-				delete self._origiFrameState;
-				// In case it is contained in a layout and the layout changed size,
-				// go ahead and call resize.
-				var pWidget = registry.getEnclosingWidget(ed.domNode.parentNode);
-				if(pWidget && pWidget.resize){
-					pWidget.resize();
-				}else{
-					if(!oh || oh.indexOf("%") < 0){
-						// Resize if the original size wasn't set
-						// or wasn't in percent.  Timeout is to avoid
-						// an IE crash in unit testing.
-						setTimeout(lang.hitch(this, function(){ed.resize({h: mb.h});}), 0);
-					}
-				}
-				winUtils.scrollIntoView(self.editor.toolbar.domNode);
-			}, 100);
-		}
-	},
-
-	updateState: function(){
-		// summary:
-		//		Over-ride for button state control for disabled to work.
-		this.button.set("disabled", this.get("disabled"));
-	},
-
-	destroy: function(){
-		// summary:
-		//		Over-ride to ensure the resize handle gets cleaned up.
-		if(this._resizeHandle){
-			// Cleanup resizing listeners
-			this._resizeHandle.remove();
-			this._resizeHandle = null;
+			this.inherited(arguments);
 		}
-		if(this._resizeHandle2){
-			// Cleanup resizing listeners
-			this._resizeHandle2.remove();
-			this._resizeHandle2 = null;
-		}
-		if(this._resizer){
-			clearTimeout(this._resizer);
-			this._resizer = null;
-		}
-		this.inherited(arguments);
-	}
-});
-
-// Register this plugin.
-// For back-compat accept "fullscreen" (all lowercase) too, remove in 2.0
-_Plugin.registry["fullScreen"] = _Plugin.registry["fullscreen"] = function(args){
-	return new FullScreen({
-		zIndex: ("zIndex" in args)?args.zIndex:500
 	});
-};
 
-return FullScreen;
+	// Register this plugin.
+	// For back-compat accept "fullscreen" (all lowercase) too, remove in 2.0
+	_Plugin.registry["fullScreen"] = _Plugin.registry["fullscreen"] = function(args){
+		return new FullScreen({
+			zIndex: ("zIndex" in args) ? args.zIndex : 500
+		});
+	};
+
+	return FullScreen;
 });
diff --git a/dijit/_editor/plugins/LinkDialog.js b/dijit/_editor/plugins/LinkDialog.js
index a2e1d32..4e001d5 100644
--- a/dijit/_editor/plugins/LinkDialog.js
+++ b/dijit/_editor/plugins/LinkDialog.js
@@ -4,583 +4,604 @@ define([
 	"dojo/dom-attr", // domAttr.get
 	"dojo/keys", // keys.ENTER
 	"dojo/_base/lang", // lang.delegate lang.hitch lang.trim
-	"dojo/_base/sniff", // has("ie")
+	"dojo/on",
+	"dojo/sniff", // has("ie")
+	"dojo/query", // query
 	"dojo/string", // string.substitute
-	"dojo/_base/window", // win.withGlobal
 	"../../_Widget",
 	"../_Plugin",
 	"../../form/DropDownButton",
-	"../range",
-	"../selection"
-], function(require, declare, domAttr, keys, lang, has, string, win,
-	_Widget, _Plugin, DropDownButton, rangeapi, selectionapi){
-
-/*=====
-	var _Plugin = dijit._editor._Plugin;
-=====*/
-
-// module:
-//		dijit/_editor/plugins/LinkDialog
-// summary:
-//		Editor plugins: LinkDialog (for inserting links) and ImgLinkDialog (for inserting images)
-
-
-var LinkDialog = declare("dijit._editor.plugins.LinkDialog", _Plugin, {
-	// summary:
-	//		This plugin provides the basis for an 'anchor' (link) dialog and an extension of it
-	//		provides the image link dialog.
-	//
-	// description:
-	//		The command provided by this plugin is:
-	//		* createLink
-
-	// Override _Plugin.buttonClass.   This plugin is controlled by a DropDownButton
-	// (which triggers a TooltipDialog).
-	buttonClass: DropDownButton,
-
-	// Override _Plugin.useDefaultCommand... processing is handled by this plugin, not by dijit.Editor.
-	useDefaultCommand: false,
-
-	// urlRegExp: [protected] String
-	//		Used for validating input as correct URL.  While file:// urls are not terribly
-	//		useful, they are technically valid.
-	urlRegExp: "((https?|ftps?|file)\\://|\./|/|)(/[a-zA-Z]{1,1}:/|)(((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)*(?:[a-zA-Z](?:[-\\da-zA-Z]{0,80}[\\da-zA-Z])?)\\.?)|(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]|(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]|(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|4294[0-8]\\d{5}|42949[0-5]\\d{4}|429496[0-6] [...]
-
-	// emailRegExp: [protected] String
-	//		Used for validating input as correct email address.  Taken from dojox.validate
-	emailRegExp:  "<?(mailto\\:)([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+" /*username*/ + "@" +
-        "((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)+(?:[a-zA-Z](?:[-\\da-zA-Z]{0,6}[\\da-zA-Z])?)\\.?)|localhost|^[^-][a-zA-Z0-9_-]*>?",	// host.
-
-	// htmlTemplate: [protected] String
-	//		String used for templating the HTML to insert at the desired point.
-	htmlTemplate: "<a href=\"${urlInput}\" _djrealurl=\"${urlInput}\"" +
-		" target=\"${targetSelect}\"" +
-		">${textInput}</a>",
-
-	// tag: [protected] String
-	//		Tag used for the link type.
-	tag: "a",
-
-	// _hostRxp [private] RegExp
-	//		Regular expression used to validate url fragments (ip address, hostname, etc)
-	_hostRxp: /^((([^\[:]+):)?([^@]+)@)?(\[([^\]]+)\]|([^\[:]*))(:([0-9]+))?$/,
-
-	// _userAtRxp [private] RegExp
-	//		Regular expression used to validate e-mail address fragment.
-	_userAtRxp: /^([!#-'*+\-\/-9=?A-Z^-~]+[.])*[!#-'*+\-\/-9=?A-Z^-~]+@/i,
-
-	// linkDialogTemplate: [protected] String
-	//		Template for contents of TooltipDialog to pick URL
-	linkDialogTemplate: [
-		"<table><tr><td>",
-		"<label for='${id}_urlInput'>${url}</label>",
-		"</td><td>",
-		"<input data-dojo-type='dijit.form.ValidationTextBox' required='true' " +
-		"id='${id}_urlInput' name='urlInput' data-dojo-props='intermediateChanges:true'/>",
-		"</td></tr><tr><td>",
-		"<label for='${id}_textInput'>${text}</label>",
-		"</td><td>",
-		"<input data-dojo-type='dijit.form.ValidationTextBox' required='true' id='${id}_textInput' " +
-		"name='textInput' data-dojo-props='intermediateChanges:true'/>",
-		"</td></tr><tr><td>",
-		"<label for='${id}_targetSelect'>${target}</label>",
-		"</td><td>",
-		"<select id='${id}_targetSelect' name='targetSelect' data-dojo-type='dijit.form.Select'>",
-		"<option selected='selected' value='_self'>${currentWindow}</option>",
-		"<option value='_blank'>${newWindow}</option>",
-		"<option value='_top'>${topWindow}</option>",
-		"<option value='_parent'>${parentWindow}</option>",
-		"</select>",
-		"</td></tr><tr><td colspan='2'>",
-		"<button data-dojo-type='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
-		"<button data-dojo-type='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>",
-		"</td></tr></table>"
-	].join(""),
-
-	_initButton: function(){
-		this.inherited(arguments);
-
-		// Setup to lazy create TooltipDialog first time the button is clicked
-		this.button.loadDropDown = lang.hitch(this, "_loadDropDown");
-
-		this._connectTagEvents();
-	},
-	_loadDropDown: function(callback){
-		// Called the first time the button is pressed.  Initialize TooltipDialog.
-		require([
-			"dojo/i18n", // i18n.getLocalization
-			"../../TooltipDialog",
-			"../../registry", // registry.byId, registry.getUniqueId
-			"../../form/Button",	// used by template
-			"../../form/Select",	// used by template
-			"../../form/ValidationTextBox",	// used by template
-			"dojo/i18n!../../nls/common",
-			"dojo/i18n!../nls/LinkDialog"
-		], lang.hitch(this, function(i18n, TooltipDialog, registry){
-			var _this = this;
-			this.tag = this.command == 'insertImage' ? 'img' : 'a';
-			var messages = lang.delegate(i18n.getLocalization("dijit", "common", this.lang),
-				i18n.getLocalization("dijit._editor", "LinkDialog", this.lang));
-			var dropDown = (this.dropDown = this.button.dropDown = new TooltipDialog({
-				title: messages[this.command + "Title"],
-				execute: lang.hitch(this, "setValue"),
-				onOpen: function(){
-					_this._onOpenDialog();
-					TooltipDialog.prototype.onOpen.apply(this, arguments);
-				},
-				onCancel: function(){
-					setTimeout(lang.hitch(_this, "_onCloseDialog"),0);
-				}
-			}));
-			messages.urlRegExp = this.urlRegExp;
-			messages.id = registry.getUniqueId(this.editor.id);
-			this._uniqueId = messages.id;
-			this._setContent(dropDown.title +
-				"<div style='border-bottom: 1px black solid;padding-bottom:2pt;margin-bottom:4pt'></div>" +
-				string.substitute(this.linkDialogTemplate, messages));
-			dropDown.startup();
-			this._urlInput = registry.byId(this._uniqueId + "_urlInput");
-			this._textInput = registry.byId(this._uniqueId + "_textInput");
-			this._setButton = registry.byId(this._uniqueId + "_setButton");
-			this.connect(registry.byId(this._uniqueId + "_cancelButton"), "onClick", function(){
-				this.dropDown.onCancel();
-			});
-			if(this._urlInput){
-				this.connect(this._urlInput, "onChange", "_checkAndFixInput");
-			}
-			if(this._textInput){
-				this.connect(this._textInput, "onChange", "_checkAndFixInput");
-			}
+	"../range"
+], function(require, declare, domAttr, keys, lang, on, has, query, string,
+	_Widget, _Plugin, DropDownButton, rangeapi){
 
-			// Build up the dual check for http/https/file:, and mailto formats.
-			this._urlRegExp = new RegExp("^" + this.urlRegExp + "$", "i");
-			this._emailRegExp = new RegExp("^" + this.emailRegExp + "$", "i");
-			this._urlInput.isValid = lang.hitch(this, function(){
-				// Function over-ride of isValid to test if the input matches a url or a mailto style link.
-				var value = this._urlInput.get("value");
-				return this._urlRegExp.test(value) || this._emailRegExp.test(value);
-			});
+	// module:
+	//		dijit/_editor/plugins/LinkDialog
 
-			// Listen for enter and execute if valid.
-			this.connect(dropDown.domNode, "onkeypress", function(e){
-				if(e && e.charOrCode == keys.ENTER &&
-					!e.shiftKey && !e.metaKey && !e.ctrlKey && !e.altKey){
-					if(!this._setButton.get("disabled")){
-						dropDown.onExecute();
-						dropDown.execute(dropDown.get('value'));
+	var LinkDialog = declare("dijit._editor.plugins.LinkDialog", _Plugin, {
+		// summary:
+		//		This plugin provides the basis for an 'anchor' (link) dialog and an extension of it
+		//		provides the image link dialog.
+		// description:
+		//		The command provided by this plugin is:
+		//
+		//		- createLink
+
+		// Override _Plugin.buttonClass.   This plugin is controlled by a DropDownButton
+		// (which triggers a TooltipDialog).
+		buttonClass: DropDownButton,
+
+		// Override _Plugin.useDefaultCommand... processing is handled by this plugin, not by dijit/Editor.
+		useDefaultCommand: false,
+
+		// urlRegExp: [protected] String
+		//		Used for validating input as correct URL.  While file:// urls are not terribly
+		//		useful, they are technically valid.
+		urlRegExp: "((https?|ftps?|file)\\://|\./|\.\./|/|)(/[a-zA-Z]{1,1}:/|)(((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)*(?:[a-zA-Z](?:[-\\da-zA-Z]{0,80}[\\da-zA-Z])?)\\.?)|(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]|(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]|(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|4294[0-8]\\d{5}|42949[0-5]\\d{4}|4294 [...]
+
+		// emailRegExp: [protected] String
+		//		Used for validating input as correct email address.  Taken from dojox.validate
+		emailRegExp: "<?(mailto\\:)([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+" /*username*/ + "@" +
+			"((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)+(?:[a-zA-Z](?:[-\\da-zA-Z]{0,6}[\\da-zA-Z])?)\\.?)|localhost|^[^-][a-zA-Z0-9_-]*>?", // host.
+
+		// htmlTemplate: [protected] String
+		//		String used for templating the HTML to insert at the desired point.
+		htmlTemplate: "<a href=\"${urlInput}\" _djrealurl=\"${urlInput}\"" +
+			" target=\"${targetSelect}\"" +
+			">${textInput}</a>",
+
+		// tag: [protected] String
+		//		Tag used for the link type.
+		tag: "a",
+
+		// _hostRxp [private] RegExp
+		//		Regular expression used to validate url fragments (ip address, hostname, etc)
+		_hostRxp: /^((([^\[:]+):)?([^@]+)@)?(\[([^\]]+)\]|([^\[:]*))(:([0-9]+))?$/,
+
+		// _userAtRxp [private] RegExp
+		//		Regular expression used to validate e-mail address fragment.
+		_userAtRxp: /^([!#-'*+\-\/-9=?A-Z^-~]+[.])*[!#-'*+\-\/-9=?A-Z^-~]+@/i,
+
+		// linkDialogTemplate: [protected] String
+		//		Template for contents of TooltipDialog to pick URL
+		linkDialogTemplate: [
+			"<table role='presentation'><tr><td>",
+			"<label for='${id}_urlInput'>${url}</label>",
+			"</td><td>",
+			"<input data-dojo-type='dijit.form.ValidationTextBox' required='true' " +
+				"id='${id}_urlInput' name='urlInput' data-dojo-props='intermediateChanges:true'/>",
+			"</td></tr><tr><td>",
+			"<label for='${id}_textInput'>${text}</label>",
+			"</td><td>",
+			"<input data-dojo-type='dijit.form.ValidationTextBox' required='true' id='${id}_textInput' " +
+				"name='textInput' data-dojo-props='intermediateChanges:true'/>",
+			"</td></tr><tr><td>",
+			"<label for='${id}_targetSelect'>${target}</label>",
+			"</td><td>",
+			"<select id='${id}_targetSelect' name='targetSelect' data-dojo-type='dijit.form.Select'>",
+			"<option selected='selected' value='_self'>${currentWindow}</option>",
+			"<option value='_blank'>${newWindow}</option>",
+			"<option value='_top'>${topWindow}</option>",
+			"<option value='_parent'>${parentWindow}</option>",
+			"</select>",
+			"</td></tr><tr><td colspan='2'>",
+			"<button data-dojo-type='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
+			"<button data-dojo-type='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>",
+			"</td></tr></table>"
+		].join(""),
+
+		_initButton: function(){
+			this.inherited(arguments);
+
+			// Setup to lazy create TooltipDialog first time the button is clicked
+			this.button.loadDropDown = lang.hitch(this, "_loadDropDown");
+
+			this._connectTagEvents();
+		},
+		_loadDropDown: function(callback){
+			// Called the first time the button is pressed.  Initialize TooltipDialog.
+			require([
+				"dojo/i18n", // i18n.getLocalization
+				"../../TooltipDialog",
+				"../../registry", // registry.byId, registry.getUniqueId
+				"../../form/Button", // used by template
+				"../../form/Select", // used by template
+				"../../form/ValidationTextBox", // used by template
+				"dojo/i18n!../../nls/common",
+				"dojo/i18n!../nls/LinkDialog"
+			], lang.hitch(this, function(i18n, TooltipDialog, registry){
+				var _this = this;
+				this.tag = this.command == 'insertImage' ? 'img' : 'a';
+				var messages = lang.delegate(i18n.getLocalization("dijit", "common", this.lang),
+					i18n.getLocalization("dijit._editor", "LinkDialog", this.lang));
+				var dropDown = (this.dropDown = this.button.dropDown = new TooltipDialog({
+					title: messages[this.command + "Title"],
+					ownerDocument: this.editor.ownerDocument,
+					dir: this.editor.dir,
+					execute: lang.hitch(this, "setValue"),
+					onOpen: function(){
+						_this._onOpenDialog();
+						TooltipDialog.prototype.onOpen.apply(this, arguments);
+					},
+					onCancel: function(){
+						setTimeout(lang.hitch(_this, "_onCloseDialog"), 0);
 					}
+				}));
+				messages.urlRegExp = this.urlRegExp;
+				messages.id = registry.getUniqueId(this.editor.id);
+				this._uniqueId = messages.id;
+				this._setContent(dropDown.title +
+					"<div style='border-bottom: 1px black solid;padding-bottom:2pt;margin-bottom:4pt'></div>" +
+					string.substitute(this.linkDialogTemplate, messages));
+				dropDown.startup();
+				this._urlInput = registry.byId(this._uniqueId + "_urlInput");
+				this._textInput = registry.byId(this._uniqueId + "_textInput");
+				this._setButton = registry.byId(this._uniqueId + "_setButton");
+				this.own(registry.byId(this._uniqueId + "_cancelButton").on("click", lang.hitch(this.dropDown, "onCancel")));
+				if(this._urlInput){
+					this.own(this._urlInput.on("change", lang.hitch(this, "_checkAndFixInput")));
+				}
+				if(this._textInput){
+					this.own(this._textInput.on("change", lang.hitch(this, "_checkAndFixInput")));
 				}
-			});
 
-			callback();
-		}));
-	},
+				// Build up the dual check for http/https/file:, and mailto formats.
+				this._urlRegExp = new RegExp("^" + this.urlRegExp + "$", "i");
+				this._emailRegExp = new RegExp("^" + this.emailRegExp + "$", "i");
+				this._urlInput.isValid = lang.hitch(this, function(){
+					// Function over-ride of isValid to test if the input matches a url or a mailto style link.
+					var value = this._urlInput.get("value");
+					return this._urlRegExp.test(value) || this._emailRegExp.test(value);
+				});
+
+				// Listen for enter and execute if valid.
+				this.own(on(dropDown.domNode, "keydown", lang.hitch(this, lang.hitch(this, function(e){
+					if(e && e.keyCode == keys.ENTER && !e.shiftKey && !e.metaKey && !e.ctrlKey && !e.altKey){
+						if(!this._setButton.get("disabled")){
+							dropDown.onExecute();
+							dropDown.execute(dropDown.get('value'));
+						}
+					}
+				}))));
 
-	_checkAndFixInput: function(){
-		// summary:
-		//		A function to listen for onChange events and test the input contents
-		//		for valid information, such as valid urls with http/https/ftp and if
-		//		not present, try and guess if the input url is relative or not, and if
-		//		not, append http:// to it.  Also validates other fields as determined by
-		//		the internal _isValid function.
-		var self = this;
-		var url = this._urlInput.get("value");
-		var fixupUrl = function(url){
-			var appendHttp = false;
-			var appendMailto = false;
-			if(url && url.length > 1){
-				url = lang.trim(url);
-				if(url.indexOf("mailto:") !== 0){
-					if(url.indexOf("/") > 0){
-						if(url.indexOf("://") === -1){
-							// Check that it doesn't start with / or ./, which would
-							// imply 'target server relativeness'
-							if(url.charAt(0) !== '/' && url.indexOf("./") !== 0){
-								if(self._hostRxp.test(url)){
-									appendHttp = true;
+				callback();
+			}));
+		},
+
+		_checkAndFixInput: function(){
+			// summary:
+			//		A function to listen for onChange events and test the input contents
+			//		for valid information, such as valid urls with http/https/ftp and if
+			//		not present, try and guess if the input url is relative or not, and if
+			//		not, append http:// to it.  Also validates other fields as determined by
+			//		the internal _isValid function.
+			var self = this;
+			var url = this._urlInput.get("value");
+			var fixupUrl = function(url){
+				var appendHttp = false;
+				var appendMailto = false;
+				if(url && url.length > 1){
+					url = lang.trim(url);
+					if(url.indexOf("mailto:") !== 0){
+						if(url.indexOf("/") > 0){
+							if(url.indexOf("://") === -1){
+								// Check that it doesn't start with /, ./, or ../, which would
+								// imply 'target server relativeness'
+								if(url.charAt(0) !== '/' && url.indexOf("./") && url.indexOf("../") !== 0){
+									if(self._hostRxp.test(url)){
+										appendHttp = true;
+									}
 								}
 							}
+						}else if(self._userAtRxp.test(url)){
+							// If it looks like a foo@, append a mailto.
+							appendMailto = true;
 						}
-					}else if(self._userAtRxp.test(url)){
-						// If it looks like a foo@, append a mailto.
-						appendMailto = true;
 					}
 				}
+				if(appendHttp){
+					self._urlInput.set("value", "http://" + url);
+				}
+				if(appendMailto){
+					self._urlInput.set("value", "mailto:" + url);
+				}
+				self._setButton.set("disabled", !self._isValid());
+			};
+			if(this._delayedCheck){
+				clearTimeout(this._delayedCheck);
+				this._delayedCheck = null;
 			}
-			if(appendHttp){
-				self._urlInput.set("value", "http://" + url);
+			this._delayedCheck = setTimeout(function(){
+				fixupUrl(url);
+			}, 250);
+		},
+
+		_connectTagEvents: function(){
+			// summary:
+			//		Over-ridable function that connects tag specific events.
+			this.editor.onLoadDeferred.then(lang.hitch(this, function(){
+				this.own(on(this.editor.editNode, "dblclick", lang.hitch(this, "_onDblClick")));
+			}));
+		},
+
+		_isValid: function(){
+			// summary:
+			//		Internal function to allow validating of the inputs
+			//		for a link to determine if set should be disabled or not
+			// tags:
+			//		protected
+			return this._urlInput.isValid() && this._textInput.isValid();
+		},
+
+		_setContent: function(staticPanel){
+			// summary:
+			//		Helper for _initButton above.   Not sure why it's a separate method.
+			this.dropDown.set({
+				parserScope: "dojo", // make parser search for dojoType/data-dojo-type even if page is multi-version
+				content: staticPanel
+			});
+		},
+
+		_checkValues: function(args){
+			// summary:
+			//		Function to check the values in args and 'fix' them up as needed.
+			// args: Object
+			//		Content being set.
+			// tags:
+			//		protected
+			if(args && args.urlInput){
+				args.urlInput = args.urlInput.replace(/"/g, """);
 			}
-			if(appendMailto){
-				self._urlInput.set("value", "mailto:" + url);
+			return args;
+		},
+
+		setValue: function(args){
+			// summary:
+			//		Callback from the dialog when user presses "set" button.
+			// tags:
+			//		private
+
+			// TODO: prevent closing popup if the text is empty
+			this._onCloseDialog();
+			if(has("ie") < 9){ //see #4151
+				var sel = rangeapi.getSelection(this.editor.window);
+				var range = sel.getRangeAt(0);
+				var a = range.endContainer;
+				if(a.nodeType === 3){
+					// Text node, may be the link contents, so check parent.
+					// This plugin doesn't really support nested HTML elements
+					// in the link, it assumes all link content is text.
+					a = a.parentNode;
+				}
+				if(a && (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
+					// Still nothing, one last thing to try on IE, as it might be 'img'
+					// and thus considered a control.
+					a = this.editor.selection.getSelectedElement(this.tag);
+				}
+				if(a && (a.nodeName && a.nodeName.toLowerCase() === this.tag)){
+					// Okay, we do have a match.  IE, for some reason, sometimes pastes before
+					// instead of removing the targeted paste-over element, so we unlink the
+					// old one first.  If we do not the <a> tag remains, but it has no content,
+					// so isn't readily visible (but is wrong for the action).
+					if(this.editor.queryCommandEnabled("unlink")){
+						// Select all the link children, then unlink.  The following insert will
+						// then replace the selected text.
+						this.editor.selection.selectElementChildren(a);
+						this.editor.execCommand("unlink");
+					}
+				}
 			}
-			self._setButton.set("disabled", !self._isValid());
-		};
-		if(this._delayedCheck){
-			clearTimeout(this._delayedCheck);
-			this._delayedCheck = null;
-		}
-		this._delayedCheck = setTimeout(function(){
-			fixupUrl(url);
-		}, 250);
-	},
-
-	_connectTagEvents: function(){
-		// summary:
-		//		Over-ridable function that connects tag specific events.
-		this.editor.onLoadDeferred.addCallback(lang.hitch(this, function(){
-			this.connect(this.editor.editNode, "ondblclick", this._onDblClick);
-		}));
-	},
+			// make sure values are properly escaped, etc.
+			args = this._checkValues(args);
+			this.editor.execCommand('inserthtml',
+				string.substitute(this.htmlTemplate, args));
+
+			// IE sometimes leaves a blank link, so we need to fix it up.
+			// Go ahead and do this for everyone just to avoid blank links
+			// in the page.
+			query("a", this.editor.document).forEach(function(a){
+				if(!a.innerHTML && !domAttr.has(a, "name")){
+					// Remove empty anchors that do not have "name" set.
+					// Empty ones with a name set could be a hidden hash
+					// anchor.
+					a.parentNode.removeChild(a);
+				}
+			}, this);
+		},
 
-	_isValid: function(){
-		// summary:
-		//		Internal function to allow validating of the inputs
-		//		for a link to determine if set should be disabled or not
-		// tags:
-		//		protected
-		return this._urlInput.isValid() && this._textInput.isValid();
-	},
-
-	_setContent: function(staticPanel){
-		// summary:
-		//		Helper for _initButton above.   Not sure why it's a separate method.
-		this.dropDown.set({
-			parserScope: "dojo",		// make parser search for dojoType/data-dojo-type even if page is multi-version
-			content: staticPanel
-		});
-	},
-
-	_checkValues: function(args){
-		// summary:
-		//		Function to check the values in args and 'fix' them up as needed.
-		// args: Object
-		//		Content being set.
-		// tags:
-		//		protected
-		if(args && args.urlInput){
-			args.urlInput = args.urlInput.replace(/"/g, """);
-		}
-		return args;
-	},
+		_onCloseDialog: function(){
+			// summary:
+			//		Handler for close event on the dialog
 
-	setValue: function(args){
-		// summary:
-		//		Callback from the dialog when user presses "set" button.
-		// tags:
-		//		private
-		//TODO: prevent closing popup if the text is empty
-		this._onCloseDialog();
-		if(has("ie") < 9){ //see #4151
-			var sel = rangeapi.getSelection(this.editor.window);
-			var range = sel.getRangeAt(0);
-			var a = range.endContainer;
-			if(a.nodeType === 3){
-				// Text node, may be the link contents, so check parent.
-				// This plugin doesn't really support nested HTML elements
-				// in the link, it assumes all link content is text.
-				a = a.parentNode;
+			if(this.editor.focused){
+				// put focus back in the edit area, unless the dialog closed because the user clicked somewhere else
+				this.editor.focus();
 			}
-			if(a && (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
-				// Still nothing, one last thing to try on IE, as it might be 'img'
-				// and thus considered a control.
-				a = win.withGlobal(this.editor.window,
-					"getSelectedElement", selectionapi, [this.tag]);
+		},
+
+		_getCurrentValues: function(a){
+			// summary:
+			//		Over-ride for getting the values to set in the dropdown.
+			// a:
+			//		The anchor/link to process for data for the dropdown.
+			// tags:
+			//		protected
+			var url, text, target;
+			if(a && a.tagName.toLowerCase() === this.tag){
+				url = a.getAttribute('_djrealurl') || a.getAttribute('href');
+				target = a.getAttribute('target') || "_self";
+				text = a.textContent || a.innerText;
+				this.editor.selection.selectElement(a, true);
+			}else{
+				text = this.editor.selection.getSelectedText();
 			}
-			if(a && (a.nodeName && a.nodeName.toLowerCase() === this.tag)){
-				// Okay, we do have a match.  IE, for some reason, sometimes pastes before
-				// instead of removing the targeted paste-over element, so we unlink the
-				// old one first.  If we do not the <a> tag remains, but it has no content,
-				// so isn't readily visible (but is wrong for the action).
-				if(this.editor.queryCommandEnabled("unlink")){
-					// Select all the link children, then unlink.  The following insert will
-					// then replace the selected text.
-					win.withGlobal(this.editor.window,
-						"selectElementChildren", selectionapi, [a]);
-					this.editor.execCommand("unlink");
+			return {urlInput: url || '', textInput: text || '', targetSelect: target || ''}; //Object;
+		},
+
+		_onOpenDialog: function(){
+			// summary:
+			//		Handler for when the dialog is opened.
+			//		If the caret is currently in a URL then populate the URL's info into the dialog.
+			var a, b, fc;
+			if(has("ie")){
+				// IE, even IE10, is difficult to select the element in, using the range unified
+				// API seems to work reasonably well.
+				var sel = rangeapi.getSelection(this.editor.window);
+				if(sel.rangeCount){
+					var range = sel.getRangeAt(0);
+					a = range.endContainer;
+					if(a.nodeType === 3){
+						// Text node, may be the link contents, so check parent.
+						// This plugin doesn't really support nested HTML elements
+						// in the link, it assumes all link content is text.
+						a = a.parentNode;
+					}
+					if(a && (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
+						// Still nothing, one last thing to try on IE, as it might be 'img'
+						// and thus considered a control.
+						a = this.editor.selection.getSelectedElement(this.tag);
+					}
+					if(!a || (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
+						// Try another lookup, IE's selection is just terrible.
+						b = this.editor.selection.getAncestorElement(this.tag);
+						if(b && (b.nodeName && b.nodeName.toLowerCase() == this.tag)){
+							// Looks like we found an A tag, use it and make sure just it is
+							// selected.
+							a = b;
+							this.editor.selection.selectElement(a);
+						}else if(range.startContainer === range.endContainer){
+							// STILL nothing.  Trying one more thing.  Lets look at the first child.
+							// It might be an anchor tag in a div by itself or the like.  If it is,
+							// we'll use it otherwise we give up.  The selection is not easily
+							// determinable to be on an existing anchor tag.
+							fc = range.startContainer.firstChild;
+							if(fc && (fc.nodeName && fc.nodeName.toLowerCase() == this.tag)){
+								a = fc;
+								this.editor.selection.selectElement(a);
+							}
+						}
+					}
 				}
+			}else{
+				a = this.editor.selection.getAncestorElement(this.tag);
 			}
-		}
-		// make sure values are properly escaped, etc.
-		args = this._checkValues(args);
-		this.editor.execCommand('inserthtml',
-			string.substitute(this.htmlTemplate, args));
-	},
-
-	_onCloseDialog: function(){
-		// summary:
-		//		Handler for close event on the dialog
-		this.editor.focus();
-	},
-
-	_getCurrentValues: function(a){
-		// summary:
-		//		Over-ride for getting the values to set in the dropdown.
-		// a:
-		//		The anchor/link to process for data for the dropdown.
-		// tags:
-		//		protected
-		var url, text, target;
-		if(a && a.tagName.toLowerCase() === this.tag){
-			url = a.getAttribute('_djrealurl') || a.getAttribute('href');
-			target = a.getAttribute('target') || "_self";
-			text = a.textContent || a.innerText;
-			win.withGlobal(this.editor.window, "selectElement", selectionapi, [a, true]);
-		}else{
-			text = win.withGlobal(this.editor.window, selectionapi.getSelectedText);
-		}
-		return {urlInput: url || '', textInput: text || '', targetSelect: target || ''}; //Object;
-	},
-
-	_onOpenDialog: function(){
-		// summary:
-		//		Handler for when the dialog is opened.
-		//		If the caret is currently in a URL then populate the URL's info into the dialog.
-		var a;
-		if(has("ie") < 9){
-			// IE is difficult to select the element in, using the range unified
-			// API seems to work reasonably well.
-			var sel = rangeapi.getSelection(this.editor.window);
-			var range = sel.getRangeAt(0);
-			a = range.endContainer;
-			if(a.nodeType === 3){
-				// Text node, may be the link contents, so check parent.
-				// This plugin doesn't really support nested HTML elements
-				// in the link, it assumes all link content is text.
-				a = a.parentNode;
-			}
-			if(a && (a.nodeName && a.nodeName.toLowerCase() !== this.tag)){
-				// Still nothing, one last thing to try on IE, as it might be 'img'
-				// and thus considered a control.
-				a = win.withGlobal(this.editor.window,
-					"getSelectedElement", selectionapi, [this.tag]);
+			this.dropDown.reset();
+			this._setButton.set("disabled", true);
+			this.dropDown.set("value", this._getCurrentValues(a));
+		},
+
+		_onDblClick: function(e){
+			// summary:
+			//		Function to define a behavior on double clicks on the element
+			//		type this dialog edits to select it and pop up the editor
+			//		dialog.
+			// e: Object
+			//		The double-click event.
+			// tags:
+			//		protected.
+			if(e && e.target){
+				var t = e.target;
+				var tg = t.tagName ? t.tagName.toLowerCase() : "";
+				if(tg === this.tag && domAttr.get(t, "href")){
+					var editor = this.editor;
+
+					this.editor.selection.selectElement(t);
+					editor.onDisplayChanged();
+
+					// Call onNormalizedDisplayChange() now, rather than on timer.
+					// On IE, when focus goes to the first <input> in the TooltipDialog, the editor loses it's selection.
+					// Later if onNormalizedDisplayChange() gets called via the timer it will disable the LinkDialog button
+					// (actually, all the toolbar buttons), at which point clicking the <input> will close the dialog,
+					// since (for unknown reasons) focus.js ignores disabled controls.
+					if(editor._updateTimer){
+						editor._updateTimer.remove();
+						delete editor._updateTimer;
+					}
+					editor.onNormalizedDisplayChanged();
+
+					var button = this.button;
+					setTimeout(function(){
+						// Focus shift outside the event handler.
+						// IE doesn't like focus changes in event handles.
+						button.set("disabled", false);
+						button.loadAndOpenDropDown().then(function(){
+							if(button.dropDown.focus){
+								button.dropDown.focus();
+							}
+						});
+					}, 10);
+				}
 			}
-		}else{
-			a = win.withGlobal(this.editor.window,
-				"getAncestorElement", selectionapi, [this.tag]);
 		}
-		this.dropDown.reset();
-		this._setButton.set("disabled", true);
-		this.dropDown.set("value", this._getCurrentValues(a));
-	},
+	});
 
-	_onDblClick: function(e){
+	var ImgLinkDialog = declare("dijit._editor.plugins.ImgLinkDialog", [LinkDialog], {
 		// summary:
-		// 		Function to define a behavior on double clicks on the element
-		//		type this dialog edits to select it and pop up the editor
-		//		dialog.
-		// e: Object
-		//		The double-click event.
-		// tags:
-		//		protected.
-		if(e && e.target){
-			var t = e.target;
-			var tg = t.tagName? t.tagName.toLowerCase() : "";
-			if(tg === this.tag && domAttr.get(t,"href")){
-				var editor = this.editor;
-
-				win.withGlobal(editor.window,
-					 "selectElement",
-					 selectionapi, [t]);
-
-				editor.onDisplayChanged();
-
-				// Call onNormalizedDisplayChange() now, rather than on timer.
-				// On IE, when focus goes to the first <input> in the TooltipDialog, the editor loses it's selection.
-				// Later if onNormalizedDisplayChange() gets called via the timer it will disable the LinkDialog button
-				// (actually, all the toolbar buttons), at which point clicking the <input> will close the dialog,
-				// since (for unknown reasons) focus.js ignores disabled controls.
-				if(editor._updateTimer){
-					clearTimeout(editor._updateTimer);
-					delete editor._updateTimer;
+		//		This plugin extends LinkDialog and adds in a plugin for handling image links.
+		//		provides the image link dialog.
+		// description:
+		//		The command provided by this plugin is:
+		//
+		//		- insertImage
+
+		// linkDialogTemplate: [protected] String
+		//		Over-ride for template since img dialog doesn't need target that anchor tags may.
+		linkDialogTemplate: [
+			"<table role='presentation'><tr><td>",
+			"<label for='${id}_urlInput'>${url}</label>",
+			"</td><td>",
+			"<input dojoType='dijit.form.ValidationTextBox' regExp='${urlRegExp}' " +
+				"required='true' id='${id}_urlInput' name='urlInput' data-dojo-props='intermediateChanges:true'/>",
+			"</td></tr><tr><td>",
+			"<label for='${id}_textInput'>${text}</label>",
+			"</td><td>",
+			"<input data-dojo-type='dijit.form.ValidationTextBox' required='false' id='${id}_textInput' " +
+				"name='textInput' data-dojo-props='intermediateChanges:true'/>",
+			"</td></tr><tr><td>",
+			"</td><td>",
+			"</td></tr><tr><td colspan='2'>",
+			"<button data-dojo-type='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
+			"<button data-dojo-type='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>",
+			"</td></tr></table>"
+		].join(""),
+
+		// htmlTemplate: [protected] String
+		//		String used for templating the `<img>` HTML to insert at the desired point.
+		htmlTemplate: "<img src=\"${urlInput}\" _djrealurl=\"${urlInput}\" alt=\"${textInput}\" />",
+
+		// tag: [protected] String
+		//		Tag used for the link type (img).
+		tag: "img",
+
+		_getCurrentValues: function(img){
+			// summary:
+			//		Over-ride for getting the values to set in the dropdown.
+			// a:
+			//		The anchor/link to process for data for the dropdown.
+			// tags:
+			//		protected
+			var url, text;
+			if(img && img.tagName.toLowerCase() === this.tag){
+				url = img.getAttribute('_djrealurl') || img.getAttribute('src');
+				text = img.getAttribute('alt');
+				this.editor.selection.selectElement(img, true);
+			}else{
+				text = this.editor.selection.getSelectedText();
+			}
+			return {urlInput: url || '', textInput: text || ''}; //Object
+		},
+
+		_isValid: function(){
+			// summary:
+			//		Over-ride for images.  You can have alt text of blank, it is valid.
+			// tags:
+			//		protected
+			return this._urlInput.isValid();
+		},
+
+		_connectTagEvents: function(){
+			// summary:
+			//		Over-ridable function that connects tag specific events.
+			this.inherited(arguments);
+			this.editor.onLoadDeferred.then(lang.hitch(this, function(){
+				// Use onmousedown instead of onclick.  Seems that IE eats the first onclick
+				// to wrap it in a selector box, then the second one acts as onclick.  See #10420
+				this.own(on(this.editor.editNode, "mousedown", lang.hitch(this, "_selectTag")));
+			}));
+		},
+
+		_selectTag: function(e){
+			// summary:
+			//		A simple event handler that lets me select an image if it is clicked on.
+			//		makes it easier to select images in a standard way across browsers.  Otherwise
+			//		selecting an image for edit becomes difficult.
+			// e: Event
+			//		The mousedown event.
+			// tags:
+			//		private
+			if(e && e.target){
+				var t = e.target;
+				var tg = t.tagName ? t.tagName.toLowerCase() : "";
+				if(tg === this.tag){
+					this.editor.selection.selectElement(t);
 				}
-				editor.onNormalizedDisplayChanged();
-
-				var button = this.button;
-				setTimeout(function(){
-					// Focus shift outside the event handler.
-					// IE doesn't like focus changes in event handles.
-					button.set("disabled", false);
-					button.loadAndOpenDropDown().then(function(){
-						if(button.dropDown.focus){
-							button.dropDown.focus();
-						}
-					});
-				}, 10);
 			}
-		}
-	}
-});
-
-var ImgLinkDialog = declare("dijit._editor.plugins.ImgLinkDialog", [LinkDialog], {
-	// summary:
-	//		This plugin extends LinkDialog and adds in a plugin for handling image links.
-	//		provides the image link dialog.
-	//
-	// description:
-	//		The command provided by this plugin is:
-	//		* insertImage
-
-	// linkDialogTemplate: [protected] String
-	//		Over-ride for template since img dialog doesn't need target that anchor tags may.
-	linkDialogTemplate: [
-		"<table><tr><td>",
-		"<label for='${id}_urlInput'>${url}</label>",
-		"</td><td>",
-		"<input dojoType='dijit.form.ValidationTextBox' regExp='${urlRegExp}' " +
-		"required='true' id='${id}_urlInput' name='urlInput' data-dojo-props='intermediateChanges:true'/>",
-		"</td></tr><tr><td>",
-		"<label for='${id}_textInput'>${text}</label>",
-		"</td><td>",
-		"<input data-dojo-type='dijit.form.ValidationTextBox' required='false' id='${id}_textInput' " +
-		"name='textInput' data-dojo-props='intermediateChanges:true'/>",
-		"</td></tr><tr><td>",
-		"</td><td>",
-		"</td></tr><tr><td colspan='2'>",
-		"<button data-dojo-type='dijit.form.Button' type='submit' id='${id}_setButton'>${set}</button>",
-		"<button data-dojo-type='dijit.form.Button' type='button' id='${id}_cancelButton'>${buttonCancel}</button>",
-		"</td></tr></table>"
-	].join(""),
-
-	// htmlTemplate: [protected] String
-	//		String used for templating the <img> HTML to insert at the desired point.
-	htmlTemplate: "<img src=\"${urlInput}\" _djrealurl=\"${urlInput}\" alt=\"${textInput}\" />",
-
-	// tag: [protected] String
-	//		Tag used for the link type (img).
-	tag: "img",
-
-	_getCurrentValues: function(img){
-		// summary:
-		//		Over-ride for getting the values to set in the dropdown.
-		// a:
-		//		The anchor/link to process for data for the dropdown.
-		// tags:
-		//		protected
-		var url, text;
-		if(img && img.tagName.toLowerCase() === this.tag){
-			url = img.getAttribute('_djrealurl') || img.getAttribute('src');
-			text = img.getAttribute('alt');
-			win.withGlobal(this.editor.window,
-				"selectElement", selectionapi, [img, true]);
-		}else{
-			text = win.withGlobal(this.editor.window, selectionapi.getSelectedText);
-		}
-		return {urlInput: url || '', textInput: text || ''}; //Object;
-	},
-
-	_isValid: function(){
-		// summary:
-		//		Over-ride for images.  You can have alt text of blank, it is valid.
-		// tags:
-		//		protected
-		return this._urlInput.isValid();
-	},
-
-	_connectTagEvents: function(){
-		// summary:
-		//		Over-ridable function that connects tag specific events.
-		this.inherited(arguments);
-		this.editor.onLoadDeferred.addCallback(lang.hitch(this, function(){
-			// Use onmousedown instead of onclick.  Seems that IE eats the first onclick
-			// to wrap it in a selector box, then the second one acts as onclick.  See #10420
-			this.connect(this.editor.editNode, "onmousedown", this._selectTag);
-		}));
-	},
-
-	_selectTag: function(e){
-		// summary:
-		//		A simple event handler that lets me select an image if it is clicked on.
-		//		makes it easier to select images in a standard way across browsers.  Otherwise
-		//		selecting an image for edit becomes difficult.
-		// e: Event
-		//		The mousedown event.
-		// tags:
-		//		private
-		if(e && e.target){
-			var t = e.target;
-			var tg = t.tagName? t.tagName.toLowerCase() : "";
-			if(tg === this.tag){
-				win.withGlobal(this.editor.window,
-					"selectElement",
-					selectionapi, [t]);
+		},
+
+		_checkValues: function(args){
+			// summary:
+			//		Function to check the values in args and 'fix' them up as needed
+			//		(special characters in the url or alt text)
+			// args: Object
+			//		Content being set.
+			// tags:
+			//		protected
+			if(args && args.urlInput){
+				args.urlInput = args.urlInput.replace(/"/g, """);
 			}
-		}
-	},
-
-	_checkValues: function(args){
-		// summary:
-		//		Function to check the values in args and 'fix' them up as needed
-		//		(special characters in the url or alt text)
-		// args: Object
-		//		Content being set.
-		// tags:
-		//		protected
-		if(args && args.urlInput){
-			args.urlInput = args.urlInput.replace(/"/g, """);
-		}
-		if(args && args.textInput){
-			args.textInput = args.textInput.replace(/"/g, """);
-		}
-		return args;
-	},
-
-	_onDblClick: function(e){
-		// summary:
-		// 		Function to define a behavior on double clicks on the element
-		//		type this dialog edits to select it and pop up the editor
-		//		dialog.
-		// e: Object
-		//		The double-click event.
-		// tags:
-		//		protected.
-		if(e && e.target){
-			var t = e.target;
-			var tg = t.tagName ? t.tagName.toLowerCase() : "";
-			if(tg === this.tag && domAttr.get(t,"src")){
-				var editor = this.editor;
-
-				win.withGlobal(editor.window,
-					 "selectElement",
-					 selectionapi, [t]);
-				editor.onDisplayChanged();
-
-				// Call onNormalizedDisplayChange() now, rather than on timer.
-				// On IE, when focus goes to the first <input> in the TooltipDialog, the editor loses it's selection.
-				// Later if onNormalizedDisplayChange() gets called via the timer it will disable the LinkDialog button
-				// (actually, all the toolbar buttons), at which point clicking the <input> will close the dialog,
-				// since (for unknown reasons) focus.js ignores disabled controls.
-				if(editor._updateTimer){
-					clearTimeout(editor._updateTimer);
-					delete editor._updateTimer;
+			if(args && args.textInput){
+				args.textInput = args.textInput.replace(/"/g, """);
+			}
+			return args;
+		},
+
+		_onDblClick: function(e){
+			// summary:
+			//		Function to define a behavior on double clicks on the element
+			//		type this dialog edits to select it and pop up the editor
+			//		dialog.
+			// e: Object
+			//		The double-click event.
+			// tags:
+			//		protected.
+			if(e && e.target){
+				var t = e.target;
+				var tg = t.tagName ? t.tagName.toLowerCase() : "";
+				if(tg === this.tag && domAttr.get(t, "src")){
+					var editor = this.editor;
+
+					this.editor.selection.selectElement(t);
+					editor.onDisplayChanged();
+
+					// Call onNormalizedDisplayChange() now, rather than on timer.
+					// On IE, when focus goes to the first <input> in the TooltipDialog, the editor loses it's selection.
+					// Later if onNormalizedDisplayChange() gets called via the timer it will disable the LinkDialog button
+					// (actually, all the toolbar buttons), at which point clicking the <input> will close the dialog,
+					// since (for unknown reasons) focus.js ignores disabled controls.
+					if(editor._updateTimer){
+						editor._updateTimer.remove();
+						delete editor._updateTimer;
+					}
+					editor.onNormalizedDisplayChanged();
+
+					var button = this.button;
+					setTimeout(function(){
+						// Focus shift outside the event handler.
+						// IE doesn't like focus changes in event handles.
+						button.set("disabled", false);
+						button.loadAndOpenDropDown().then(function(){
+							if(button.dropDown.focus){
+								button.dropDown.focus();
+							}
+						});
+					}, 10);
 				}
-				editor.onNormalizedDisplayChanged();
-
-				var button = this.button;
-				setTimeout(function(){
-					// Focus shift outside the event handler.
-					// IE doesn't like focus changes in event handles.
-					button.set("disabled", false);
-					button.loadAndOpenDropDown().then(function(){
-						if(button.dropDown.focus){
-							button.dropDown.focus();
-						}
-					});
-				}, 10);
 			}
 		}
-	}
-});
-
-// Register these plugins
-_Plugin.registry["createLink"] = function(){
-	return new LinkDialog({command: "createLink"});
-};
-_Plugin.registry["insertImage"] = function(){
-	return new ImgLinkDialog({command: "insertImage"});
-};
-
-
-// Export both LinkDialog and ImgLinkDialog
-LinkDialog.ImgLinkDialog = ImgLinkDialog;
-return LinkDialog;
+	});
+
+	// Register these plugins
+	_Plugin.registry["createLink"] = function(){
+		return new LinkDialog({command: "createLink"});
+	};
+	_Plugin.registry["insertImage"] = function(){
+		return new ImgLinkDialog({command: "insertImage"});
+	};
+
+
+	// Export both LinkDialog and ImgLinkDialog
+	// TODO for 2.0: either return both classes in a hash, or split this file into two separate files.
+	// Then the documentation for the module can be applied to the hash, and will show up in the API doc.
+	LinkDialog.ImgLinkDialog = ImgLinkDialog;
+	return LinkDialog;
 });
diff --git a/dijit/_editor/plugins/NewPage.js b/dijit/_editor/plugins/NewPage.js
index 3cd519b..cf8d20f 100644
--- a/dijit/_editor/plugins/NewPage.js
+++ b/dijit/_editor/plugins/NewPage.js
@@ -7,77 +7,70 @@ define([
 	"dojo/i18n!../nls/commands"
 ], function(declare, i18n, lang, _Plugin, Button){
 
-/*=====
-	var _Plugin = dijit._editor._Plugin;
-=====*/
+	// module:
+	//		dijit/_editor/plugins/NewPage
 
-// module:
-//		dijit/_editor/plugins/NewPage
-// summary:
-//		This plugin provides a simple 'new page' capability.  In other
-//		words, set content to some default user defined string.
-
-
-var NewPage = declare("dijit._editor.plugins.NewPage",_Plugin,{
-	// summary:
-	//		This plugin provides a simple 'new page' capability.  In other
-	//		words, set content to some default user defined string.
-
-	// content: [public] String
-	//		The default content to insert into the editor as the new page.
-	//		The default is the <br> tag, a single blank line.
-	content: "<br>",
-
-	_initButton: function(){
+	var NewPage = declare("dijit._editor.plugins.NewPage", _Plugin, {
 		// summary:
-		//		Over-ride for creation of the Print button.
-		var strings = i18n.getLocalization("dijit._editor", "commands"),
-			editor = this.editor;
-		this.button = new Button({
-			label: strings["newPage"],
-			dir: editor.dir,
-			lang: editor.lang,
-			showLabel: false,
-			iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "NewPage",
-			tabIndex: "-1",
-			onClick: lang.hitch(this, "_newPage")
-		});
-	},
+		//		This plugin provides a simple 'new page' capability.  In other
+		//		words, set content to some default user defined string.
 
-	setEditor: function(/*dijit.Editor*/ editor){
-		// summary:
-		//		Tell the plugin which Editor it is associated with.
-		// editor: Object
-		//		The editor object to attach the newPage capability to.
-		this.editor = editor;
-		this._initButton();
-	},
+		// content: [public] String
+		//		The default content to insert into the editor as the new page.
+		//		The default is the `<br>` tag, a single blank line.
+		content: "<br>",
 
-	updateState: function(){
-		// summary:
-		//		Over-ride for button state control for disabled to work.
-		this.button.set("disabled", this.get("disabled"));
-	},
+		_initButton: function(){
+			// summary:
+			//		Over-ride for creation of the Print button.
+			var strings = i18n.getLocalization("dijit._editor", "commands"),
+				editor = this.editor;
+			this.button = new Button({
+				label: strings["newPage"],
+				ownerDocument: editor.ownerDocument,
+				dir: editor.dir,
+				lang: editor.lang,
+				showLabel: false,
+				iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "NewPage",
+				tabIndex: "-1",
+				onClick: lang.hitch(this, "_newPage")
+			});
+		},
 
-	_newPage: function(){
-		// summary:
-		//		Function to set the content to blank.
-		// tags:
-		//		private
-		this.editor.beginEditing();
-		this.editor.set("value", this.content);
-		this.editor.endEditing();
-		this.editor.focus();
-	}
-});
+		setEditor: function(/*dijit/Editor*/ editor){
+			// summary:
+			//		Tell the plugin which Editor it is associated with.
+			// editor: Object
+			//		The editor object to attach the newPage capability to.
+			this.editor = editor;
+			this._initButton();
+		},
 
-// Register this plugin.
-// For back-compat accept "newpage" (all lowercase) too, remove in 2.0
-_Plugin.registry["newPage"] = _Plugin.registry["newpage"] = function(args){
-	return new NewPage({
-		content: ("content" in args)?args.content:"<br>"
+		updateState: function(){
+			// summary:
+			//		Over-ride for button state control for disabled to work.
+			this.button.set("disabled", this.get("disabled"));
+		},
+
+		_newPage: function(){
+			// summary:
+			//		Function to set the content to blank.
+			// tags:
+			//		private
+			this.editor.beginEditing();
+			this.editor.set("value", this.content);
+			this.editor.endEditing();
+			this.editor.focus();
+		}
 	});
-};
 
-return NewPage;
+	// Register this plugin.
+	// For back-compat accept "newpage" (all lowercase) too, remove in 2.0
+	_Plugin.registry["newPage"] = _Plugin.registry["newpage"] = function(args){
+		return new NewPage({
+			content: ("content" in args) ? args.content : "<br>"
+		});
+	};
+
+	return NewPage;
 });
diff --git a/dijit/_editor/plugins/Print.js b/dijit/_editor/plugins/Print.js
index df9aee8..ed7c40e 100755
--- a/dijit/_editor/plugins/Print.js
+++ b/dijit/_editor/plugins/Print.js
@@ -2,128 +2,120 @@ define([
 	"dojo/_base/declare", // declare
 	"dojo/i18n", // i18n.getLocalization
 	"dojo/_base/lang", // lang.hitch
-	"dojo/_base/sniff", // has("chrome") has("opera")
-	"../../focus",		// focus.focus()
+	"dojo/sniff", // has("chrome") has("opera")
+	"../../focus", // focus.focus()
 	"../_Plugin",
 	"../../form/Button",
 	"dojo/i18n!../nls/commands"
 ], function(declare, i18n, lang, has, focus, _Plugin, Button){
 
-/*=====
-	var _Plugin = dijit._editor._Plugin;
-=====*/
+	// module:
+	//		dijit/_editor/plugins/Print
 
-// module:
-//		dijit/_editor/plugins/Print
-// summary:
-//		This plugin provides Print capability to the editor.  When
-//		clicked, the document in the editor frame will be printed.
-
-
-var Print = declare("dijit._editor.plugins.Print",_Plugin,{
-	// summary:
-	//		This plugin provides Print capability to the editor.  When
-	//		clicked, the document in the editor frame will be printed.
-
-	_initButton: function(){
+	var Print = declare("dijit._editor.plugins.Print", _Plugin, {
 		// summary:
-		//		Over-ride for creation of the Print button.
-		var strings = i18n.getLocalization("dijit._editor", "commands"),
-			editor = this.editor;
-		this.button = new Button({
-			label: strings["print"],
-			dir: editor.dir,
-			lang: editor.lang,
-			showLabel: false,
-			iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "Print",
-			tabIndex: "-1",
-			onClick: lang.hitch(this, "_print")
-		});
-	},
+		//		This plugin provides Print capability to the editor.  When
+		//		clicked, the document in the editor frame will be printed.
 
-	setEditor: function(/*dijit.Editor*/ editor){
-		// summary:
-		//		Tell the plugin which Editor it is associated with.
-		// editor: Object
-		//		The editor object to attach the print capability to.
-		this.editor = editor;
-		this._initButton();
+		_initButton: function(){
+			// summary:
+			//		Over-ride for creation of the Print button.
+			var strings = i18n.getLocalization("dijit._editor", "commands"),
+				editor = this.editor;
+			this.button = new Button({
+				label: strings["print"],
+				ownerDocument: editor.ownerDocument,
+				dir: editor.dir,
+				lang: editor.lang,
+				showLabel: false,
+				iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "Print",
+				tabIndex: "-1",
+				onClick: lang.hitch(this, "_print")
+			});
+		},
 
-		// Set up a check that we have a print function
-		// and disable button if we do not.
-		this.editor.onLoadDeferred.addCallback(
-			lang.hitch(this, function(){
-				if(!this.editor.iframe.contentWindow["print"]){
-					this.button.set("disabled", true);
-				}
-			})
-		);
-	},
+		setEditor: function(/*dijit/Editor*/ editor){
+			// summary:
+			//		Tell the plugin which Editor it is associated with.
+			// editor: Object
+			//		The editor object to attach the print capability to.
+			this.editor = editor;
+			this._initButton();
 
-	updateState: function(){
-		// summary:
-		//		Over-ride for button state control for disabled to work.
-		var disabled = this.get("disabled");
-		if(!this.editor.iframe.contentWindow["print"]){
-			disabled = true;
-		}
-		this.button.set("disabled", disabled);
-	},
+			// Set up a check that we have a print function
+			// and disable button if we do not.
+			this.editor.onLoadDeferred.then(
+				lang.hitch(this, function(){
+					if(!this.editor.iframe.contentWindow["print"]){
+						this.button.set("disabled", true);
+					}
+				})
+			);
+		},
 
-	_print: function(){
-		// summary:
-		//		Function to trigger printing of the editor document
-		// tags:
-		//		private
-		var edFrame = this.editor.iframe;
-		if(edFrame.contentWindow["print"]){
-			// IE requires the frame to be focused for
-			// print to work, but since this is okay for all
-			// no special casing.
-			if(!has("opera") && !has("chrome")){
-				focus.focus(edFrame);
-				edFrame.contentWindow.print();
-			}else{
-				// Neither Opera nor Chrome 3 et you print single frames.
-				// So, open a new 'window', print it, and close it.
-				// Also, can't use size 0x0, have to use 1x1
-				var edDoc = this.editor.document;
-				var content = this.editor.get("value");
-				content = "<html><head><meta http-equiv='Content-Type' " +
-					"content='text/html; charset='UTF-8'></head><body>" +
-					content + "</body></html>";
-				var win = window.open("javascript: ''",
-					"",
-					"status=0,menubar=0,location=0,toolbar=0," +
-					"width=1,height=1,resizable=0,scrollbars=0");
-				win.document.open();
-				win.document.write(content);
-				win.document.close();
+		updateState: function(){
+			// summary:
+			//		Over-ride for button state control for disabled to work.
+			var disabled = this.get("disabled");
+			if(!this.editor.iframe.contentWindow["print"]){
+				disabled = true;
+			}
+			this.button.set("disabled", disabled);
+		},
 
-				var styleNodes = edDoc.getElementsByTagName("style");
-				if(styleNodes){
-					// Clone over any editor view styles, since we can't print the iframe
-					// directly.
-					var i;
-					for(i = 0; i < styleNodes.length; i++){
-						var style = styleNodes[i].innerHTML;
-						var sNode = win.document.createElement("style");
-						sNode.appendChild(win.document.createTextNode(style));
-						win.document.getElementsByTagName("head")[0].appendChild(sNode);
+		_print: function(){
+			// summary:
+			//		Function to trigger printing of the editor document
+			// tags:
+			//		private
+			var edFrame = this.editor.iframe;
+			if(edFrame.contentWindow["print"]){
+				// IE requires the frame to be focused for
+				// print to work, but since this is okay for all
+				// no special casing.
+				if(!has("opera") && !has("chrome")){
+					focus.focus(edFrame);
+					edFrame.contentWindow.print();
+				}else{
+					// Neither Opera nor Chrome 3 et you print single frames.
+					// So, open a new 'window', print it, and close it.
+					// Also, can't use size 0x0, have to use 1x1
+					var edDoc = this.editor.document;
+					var content = this.editor.get("value");
+					content = "<html><head><meta http-equiv='Content-Type' " +
+						"content='text/html; charset='UTF-8'></head><body>" +
+						content + "</body></html>";
+					var win = window.open("javascript: ''",
+						"",
+						"status=0,menubar=0,location=0,toolbar=0," +
+							"width=1,height=1,resizable=0,scrollbars=0");
+					win.document.open();
+					win.document.write(content);
+					win.document.close();
+
+					var styleNodes = edDoc.getElementsByTagName("style");
+					if(styleNodes){
+						// Clone over any editor view styles, since we can't print the iframe
+						// directly.
+						var i;
+						for(i = 0; i < styleNodes.length; i++){
+							var style = styleNodes[i].innerHTML;
+							var sNode = win.document.createElement("style");
+							sNode.appendChild(win.document.createTextNode(style));
+							win.document.getElementsByTagName("head")[0].appendChild(sNode);
+						}
 					}
+					win.print();
+					win.close();
 				}
-				win.print();
-				win.close();
 			}
 		}
-	}
-});
-
-// Register this plugin.
-_Plugin.registry["print"] = function(){
-	return new Print({command: "print"});
-};
+	});
 
+	// Register this plugin.
+	_Plugin.registry["print"] = function(){
+		return new Print({command: "print"});
+	};
 
-return Print;
+	return Print;
 });
diff --git a/dijit/_editor/plugins/TabIndent.js b/dijit/_editor/plugins/TabIndent.js
index 66720b9..34cc143 100644
--- a/dijit/_editor/plugins/TabIndent.js
+++ b/dijit/_editor/plugins/TabIndent.js
@@ -5,17 +5,8 @@ define([
 	"../../form/ToggleButton"
 ], function(declare, kernel, _Plugin, ToggleButton){
 
-/*=====
-	var _Plugin = dijit._editor._Plugin;
-=====*/
-
 	// module:
 	//		dijit/_editor/plugins/TabIndent
-	// summary:
-	//		This plugin is used to allow the use of the tab and shift-tab keys
-	//		to indent/outdent list items.  This overrides the default behavior
-	//		of moving focus from/to the toolbar
-
 
 	kernel.experimental("dijit._editor.plugins.TabIndent");
 
@@ -26,7 +17,7 @@ define([
 		//		to indent/outdent list items.  This overrides the default behavior
 		//		of moving focus from/to the toolbar
 
-		// Override _Plugin.useDefaultCommand... processing is handled by this plugin, not by dijit.Editor.
+		// Override _Plugin.useDefaultCommand... processing is handled by this plugin, not by dijit/Editor.
 		useDefaultCommand: false,
 
 		// Override _Plugin.buttonClass to use a ToggleButton for this plugin rather than a vanilla Button
@@ -39,9 +30,9 @@ define([
 			this.inherited(arguments);
 
 			var e = this.editor;
-			this.connect(this.button, "onChange", function(val){
+			this.own(this.button.on("change", function(val){
 				e.set("isTabIndent", val);
-			});
+			}));
 
 			// Set initial checked state of button based on Editor.isTabIndent
 			this.updateState();
diff --git a/dijit/_editor/plugins/TextColor.js b/dijit/_editor/plugins/TextColor.js
index 7c582e5..5ee9122 100644
--- a/dijit/_editor/plugins/TextColor.js
+++ b/dijit/_editor/plugins/TextColor.js
@@ -7,113 +7,109 @@ define([
 	"../../form/DropDownButton"
 ], function(require, colors, declare, lang, _Plugin, DropDownButton){
 
-/*=====
-	var _Plugin = dijit._editor._Plugin;
-=====*/
-
-// module:
-//		dijit/_editor/plugins/TextColor
-// summary:
-//		This plugin provides dropdown color pickers for setting text color and background color
-
-
-var TextColor = declare("dijit._editor.plugins.TextColor", _Plugin, {
-	// summary:
-	//		This plugin provides dropdown color pickers for setting text color and background color
-	//
-	// description:
-	//		The commands provided by this plugin are:
-	//		* foreColor - sets the text color
-	//		* hiliteColor - sets the background color
-
-	// Override _Plugin.buttonClass to use DropDownButton (with ColorPalette) to control this plugin
-	buttonClass: DropDownButton,
-
-	// useDefaultCommand: Boolean
-	//		False as we do not use the default editor command/click behavior.
-	useDefaultCommand: false,
-
-	_initButton: function(){
-		this.inherited(arguments);
-
-		// Setup to lazy load ColorPalette first time the button is clicked
-		var self = this;
-		this.button.loadDropDown = function(callback){
-			require(["../../ColorPalette"], lang.hitch(this, function(ColorPalette){
-				this.dropDown = new ColorPalette({
-					value: self.value,
-					onChange: function(color){
-						self.editor.execCommand(self.command, color);
-					}
-				});
-				callback();
-			}));
-		};
-	},
-
-	updateState: function(){
-		// summary:
-		//		Overrides _Plugin.updateState().  This updates the ColorPalette
-		//		to show the color of the currently selected text.
-		// tags:
-		//		protected
-
-		var _e = this.editor;
-		var _c = this.command;
-		if(!_e || !_e.isLoaded || !_c.length){
-			return;
-		}
+	// module:
+	//		dijit/_editor/plugins/TextColor
 
-		if(this.button){
-			var disabled = this.get("disabled");
-			this.button.set("disabled", disabled);
-			if(disabled){ return; }
-
-			var value;
-			try{
-				value = _e.queryCommandValue(_c)|| "";
-			}catch(e){
-				//Firefox may throw error above if the editor is just loaded, ignore it
-				value = "";
+	var TextColor = declare("dijit._editor.plugins.TextColor", _Plugin, {
+		// summary:
+		//		This plugin provides dropdown color pickers for setting text color and background color
+		// description:
+		//		The commands provided by this plugin are:
+		//
+		//		- foreColor - sets the text color
+		//		- hiliteColor - sets the background color
+
+		// Override _Plugin.buttonClass to use DropDownButton (with ColorPalette) to control this plugin
+		buttonClass: DropDownButton,
+
+		// useDefaultCommand: Boolean
+		//		False as we do not use the default editor command/click behavior.
+		useDefaultCommand: false,
+
+		_initButton: function(){
+			this.inherited(arguments);
+
+			// Setup to lazy load ColorPalette first time the button is clicked
+			var self = this;
+			this.button.loadDropDown = function(callback){
+				require(["../../ColorPalette"], lang.hitch(this, function(ColorPalette){
+					this.dropDown = new ColorPalette({
+						dir: self.editor.dir,
+						ownerDocument: self.editor.ownerDocument,
+						value: self.value,
+						onChange: function(color){
+							self.editor.execCommand(self.command, color);
+						}
+					});
+					callback();
+				}));
+			};
+		},
+
+		updateState: function(){
+			// summary:
+			//		Overrides _Plugin.updateState().  This updates the ColorPalette
+			//		to show the color of the currently selected text.
+			// tags:
+			//		protected
+
+			var _e = this.editor;
+			var _c = this.command;
+			if(!_e || !_e.isLoaded || !_c.length){
+				return;
 			}
-		}
 
-		if(value == ""){
-			value = "#000000";
-		}
-		if(value == "transparent"){
-			value = "#ffffff";
-		}
+			if(this.button){
+				var disabled = this.get("disabled");
+				this.button.set("disabled", disabled);
+				if(disabled){
+					return;
+				}
+
+				var value;
+				try{
+					value = _e.queryCommandValue(_c) || "";
+				}catch(e){
+					//Firefox may throw error above if the editor is just loaded, ignore it
+					value = "";
+				}
+			}
 
-		if(typeof value == "string"){
-			//if RGB value, convert to hex value
-			if(value.indexOf("rgb")> -1){
-				value = colors.fromRgb(value).toHex();
+			if(value == ""){
+				value = "#000000";
+			}
+			if(value == "transparent"){
+				value = "#ffffff";
 			}
-		}else{	//it's an integer(IE returns an MS access #)
-			value =((value & 0x0000ff)<< 16)|(value & 0x00ff00)|((value & 0xff0000)>>> 16);
-			value = value.toString(16);
-			value = "#000000".slice(0, 7 - value.length)+ value;
 
-		}
+			if(typeof value == "string"){
+				//if RGB value, convert to hex value
+				if(value.indexOf("rgb") > -1){
+					value = colors.fromRgb(value).toHex();
+				}
+			}else{    //it's an integer(IE returns an MS access #)
+				value = ((value & 0x0000ff) << 16) | (value & 0x00ff00) | ((value & 0xff0000) >>> 16);
+				value = value.toString(16);
+				value = "#000000".slice(0, 7 - value.length) + value;
 
-		this.value = value;
+			}
 
-		var dropDown = this.button.dropDown;
-		if(dropDown && value !== dropDown.get('value')){
-			dropDown.set('value', value, false);
-		}
-	}
-});
+			this.value = value;
 
-// Register this plugin.
-_Plugin.registry["foreColor"] = function(){
-	return new TextColor({command: "foreColor"});
-};
-_Plugin.registry["hiliteColor"] = function(){
-	return new TextColor({command: "hiliteColor"});
-};
+			var dropDown = this.button.dropDown;
+			if(dropDown && value !== dropDown.get('value')){
+				dropDown.set('value', value, false);
+			}
+		}
+	});
 
+	// Register this plugin.
+	_Plugin.registry["foreColor"] = function(){
+		return new TextColor({command: "foreColor"});
+	};
+	_Plugin.registry["hiliteColor"] = function(){
+		return new TextColor({command: "hiliteColor"});
+	};
 
-return TextColor;
+	return TextColor;
 });
diff --git a/dijit/_editor/plugins/ToggleDir.js b/dijit/_editor/plugins/ToggleDir.js
index 767ee00..d0597e8 100644
--- a/dijit/_editor/plugins/ToggleDir.js
+++ b/dijit/_editor/plugins/ToggleDir.js
@@ -3,20 +3,13 @@ define([
 	"dojo/dom-style", // domStyle.getComputedStyle
 	"dojo/_base/kernel", // kernel.experimental
 	"dojo/_base/lang", // lang.hitch
+	"dojo/on",
 	"../_Plugin",
 	"../../form/ToggleButton"
-], function(declare, domStyle, kernel, lang, _Plugin, ToggleButton){
-
-/*=====
-	var _Plugin = dijit._editor._Plugin;
-=====*/
+], function(declare, domStyle, kernel, lang, on, _Plugin, ToggleButton){
 
 	// module:
 	//		dijit/_editor/plugins/ToggleDir
-	// summary:
-	//		This plugin is used to toggle direction of the edited document,
-	//		independent of what direction the whole page is.
-
 
 	kernel.experimental("dijit._editor.plugins.ToggleDir");
 
@@ -37,7 +30,7 @@ define([
 		_initButton: function(){
 			// Override _Plugin._initButton() to setup handler for button click events.
 			this.inherited(arguments);
-			this.editor.onLoadDeferred.addCallback(lang.hitch(this, function(){
+			this.editor.onLoadDeferred.then(lang.hitch(this, function(){
 				var editDoc = this.editor.editorObject.contentWindow.document.documentElement;
 				//IE direction has to toggle on the body, not document itself.
 				//If you toggle just the document, things get very strange in the
@@ -45,7 +38,7 @@ define([
 				editDoc = editDoc.getElementsByTagName("body")[0];
 				var isLtr = domStyle.getComputedStyle(editDoc).direction == "ltr";
 				this.button.set("checked", !isLtr);
-				this.connect(this.button, "onChange", "_setRtl");
+				this.own(this.button.on("change", lang.hitch(this, "_setRtl")));
 			}));
 		},
 
diff --git a/dijit/_editor/plugins/ViewSource.js b/dijit/_editor/plugins/ViewSource.js
index 3525f4a..33b018f 100755
--- a/dijit/_editor/plugins/ViewSource.js
+++ b/dijit/_editor/plugins/ViewSource.js
@@ -1,517 +1,535 @@
 define([
 	"dojo/_base/array", // array.forEach
+	"dojo/aspect", // Aspect commands for advice
 	"dojo/_base/declare", // declare
 	"dojo/dom-attr", // domAttr.set
 	"dojo/dom-construct", // domConstruct.create domConstruct.place
 	"dojo/dom-geometry", // domGeometry.setMarginBox domGeometry.position
 	"dojo/dom-style", // domStyle.set
-	"dojo/_base/event", // event.stop
 	"dojo/i18n", // i18n.getLocalization
-	"dojo/keys",	//  keys.F12
+	"dojo/keys", // keys.F12
 	"dojo/_base/lang", // lang.hitch
 	"dojo/on", // on()
-	"dojo/_base/sniff", // has("ie") has("webkit")
-	"dojo/_base/window", // win.body win.global
+	"dojo/sniff", // has("ie")
 	"dojo/window", // winUtils.getBox
-	"../../focus",	// focus.focus()
+	"../../focus", // focus.focus()
 	"../_Plugin",
 	"../../form/ToggleButton",
-	"../..",	// dijit._scopeName
+	"../..", // dijit._scopeName
 	"../../registry", // registry.getEnclosingWidget()
 	"dojo/i18n!../nls/commands"
-], function(array, declare, domAttr, domConstruct, domGeometry, domStyle, event, i18n, keys, lang, on, has, win,
-	winUtils, focus, _Plugin, ToggleButton, dijit, registry){
-
-/*=====
-	var _Plugin = dijit._editor._Plugin;
-=====*/
-
-// module:
-//		dijit/_editor/plugins/ViewSource
-// summary:
-//		This plugin provides a simple view source capability.
-
-
-var ViewSource = declare("dijit._editor.plugins.ViewSource",_Plugin, {
-	// summary:
-	//		This plugin provides a simple view source capability.  When view
-	//		source mode is enabled, it disables all other buttons/plugins on the RTE.
-	//		It also binds to the hotkey: CTRL-SHIFT-F11 for toggling ViewSource mode.
-
-	// stripScripts: [public] Boolean
-	//		Boolean flag used to indicate if script tags should be stripped from the document.
-	//		Defaults to true.
-	stripScripts: true,
-
-	// stripComments: [public] Boolean
-	//		Boolean flag used to indicate if comment tags should be stripped from the document.
-	//		Defaults to true.
-	stripComments: true,
-
-	// stripComments: [public] Boolean
-	//		Boolean flag used to indicate if iframe tags should be stripped from the document.
-	//		Defaults to true.
-	stripIFrames: true,
-
-	// readOnly: [const] Boolean
-	//		Boolean flag used to indicate if the source view should be readonly or not.
-	//		Cannot be changed after initialization of the plugin.
-	//		Defaults to false.
-	readOnly: false,
-
-	// _fsPlugin: [private] Object
-	//		Reference to a registered fullscreen plugin so that viewSource knows
-	//		how to scale.
-	_fsPlugin: null,
-
-	toggle: function(){
-		// summary:
-		//		Function to allow programmatic toggling of the view.
-
-		// For Webkit, we have to focus a very particular way.
-		// when swapping views, otherwise focus doesn't shift right
-		// but can't focus this way all the time, only for VS changes.
-		// If we did it all the time, buttons like bold, italic, etc
-		// break.
-		if(has("webkit")){this._vsFocused = true;}
-		this.button.set("checked", !this.button.get("checked"));
+], function(array, aspect, declare, domAttr, domConstruct, domGeometry, domStyle, i18n, keys, lang, on, has, winUtils,
+			focus, _Plugin, ToggleButton, dijit, registry){
 
-	},
+	// module:
+	//		dijit/_editor/plugins/ViewSource
 
-	_initButton: function(){
+	var ViewSource = declare("dijit._editor.plugins.ViewSource", _Plugin, {
 		// summary:
-		//		Over-ride for creation of the resize button.
-		var strings = i18n.getLocalization("dijit._editor", "commands"),
-			editor = this.editor;
-		this.button = new ToggleButton({
-			label: strings["viewSource"],
-			dir: editor.dir,
-			lang: editor.lang,
-			showLabel: false,
-			iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "ViewSource",
-			tabIndex: "-1",
-			onChange: lang.hitch(this, "_showSource")
-		});
-
-		// IE 7 has a horrible bug with zoom, so we have to create this node
-		// to cross-check later.  Sigh.
-		if(has("ie") == 7){
-			this._ieFixNode = domConstruct.create("div", {
-				style: {
-					opacity: "0",
-					zIndex: "-1000",
-					position: "absolute",
-					top: "-1000px"
-				}
-			}, win.body());
-		}
-		// Make sure readonly mode doesn't make the wrong cursor appear over the button.
-		this.button.set("readOnly", false);
-	},
-
+		//		This plugin provides a simple view source capability.  When view
+		//		source mode is enabled, it disables all other buttons/plugins on the RTE.
+		//		It also binds to the hotkey: CTRL-SHIFT-F11 for toggling ViewSource mode.
+
+		// stripScripts: [public] Boolean
+		//		Boolean flag used to indicate if script tags should be stripped from the document.
+		//		Defaults to true.
+		stripScripts: true,
+
+		// stripComments: [public] Boolean
+		//		Boolean flag used to indicate if comment tags should be stripped from the document.
+		//		Defaults to true.
+		stripComments: true,
+
+		// stripComments: [public] Boolean
+		//		Boolean flag used to indicate if iframe tags should be stripped from the document.
+		//		Defaults to true.
+		stripIFrames: true,
+
+		// readOnly: [const] Boolean
+		//		Boolean flag used to indicate if the source view should be readonly or not.
+		//		Cannot be changed after initialization of the plugin.
+		//		Defaults to false.
+		readOnly: false,
+
+		// _fsPlugin: [private] Object
+		//		Reference to a registered fullscreen plugin so that viewSource knows
+		//		how to scale.
+		_fsPlugin: null,
+
+		toggle: function(){
+			// summary:
+			//		Function to allow programmatic toggling of the view.
+
+			// For Webkit, we have to focus a very particular way.
+			// when swapping views, otherwise focus doesn't shift right
+			// but can't focus this way all the time, only for VS changes.
+			// If we did it all the time, buttons like bold, italic, etc
+			// break.
+			if(has("webkit")){
+				this._vsFocused = true;
+			}
+			this.button.set("checked", !this.button.get("checked"));
+
+		},
+
+		_initButton: function(){
+			// summary:
+			//		Over-ride for creation of the resize button.
+			var strings = i18n.getLocalization("dijit._editor", "commands"),
+				editor = this.editor;
+			this.button = new ToggleButton({
+				label: strings["viewSource"],
+				ownerDocument: editor.ownerDocument,
+				dir: editor.dir,
+				lang: editor.lang,
+				showLabel: false,
+				iconClass: this.iconClassPrefix + " " + this.iconClassPrefix + "ViewSource",
+				tabIndex: "-1",
+				onChange: lang.hitch(this, "_showSource")
+			});
 
-	setEditor: function(/*dijit.Editor*/ editor){
-		// summary:
-		//		Tell the plugin which Editor it is associated with.
-		// editor: Object
-		//		The editor object to attach the print capability to.
-		this.editor = editor;
-		this._initButton();
-
-		this.editor.addKeyHandler(keys.F12, true, true, lang.hitch(this, function(e){
-			// Move the focus before switching
-			// It'll focus back.  Hiding a focused
-			// node causes issues.
-			this.button.focus();
-			this.toggle();
-			event.stop(e);
-
-			// Call the focus shift outside of the handler.
-			setTimeout(lang.hitch(this, function(){
-				// We over-ride focus, so we just need to call.
-				this.editor.focus();
-			}), 100);
-		}));
-	},
-
-	_showSource: function(source){
-		// summary:
-		//		Function to toggle between the source and RTE views.
-		// source: boolean
-		//		Boolean value indicating if it should be in source mode or not.
-		// tags:
-		//		private
-		var ed = this.editor;
-		var edPlugins = ed._plugins;
-		var html;
-		this._sourceShown = source;
-		var self = this;
-		try{
-			if(!this.sourceArea){
-				this._createSourceView();
+			// IE 7 has a horrible bug with zoom, so we have to create this node
+			// to cross-check later.  Sigh.
+			if(has("ie") == 7){
+				this._ieFixNode = domConstruct.create("div", {
+					style: {
+						opacity: "0",
+						zIndex: "-1000",
+						position: "absolute",
+						top: "-1000px"
+					}
+				}, editor.ownerDocumentBody);
 			}
-			if(source){
-				// Update the QueryCommandEnabled function to disable everything but
-				// the source view mode.  Have to over-ride a function, then kick all
-				// plugins to check their state.
-				ed._sourceQueryCommandEnabled = ed.queryCommandEnabled;
-				ed.queryCommandEnabled = function(cmd){
-					return cmd.toLowerCase() === "viewsource";
-				};
-				this.editor.onDisplayChanged();
-				html = ed.get("value");
-				html = this._filter(html);
-				ed.set("value", html);
-				array.forEach(edPlugins, function(p){
-					// Turn off any plugins not controlled by queryCommandenabled.
-					if(!(p instanceof ViewSource)){
-						p.set("disabled", true)
+			// Make sure readonly mode doesn't make the wrong cursor appear over the button.
+			this.button.set("readOnly", false);
+		},
+
+
+		setEditor: function(/*dijit/Editor*/ editor){
+			// summary:
+			//		Tell the plugin which Editor it is associated with.
+			// editor: Object
+			//		The editor object to attach the print capability to.
+			this.editor = editor;
+			this._initButton();
+
+			this.editor.addKeyHandler(keys.F12, true, true, lang.hitch(this, function(e){
+				// Move the focus before switching
+				// It'll focus back.  Hiding a focused
+				// node causes issues.
+				this.button.focus();
+				this.toggle();
+				e.stopPropagation();
+				e.preventDefault();
+
+				// Call the focus shift outside of the handler.
+				setTimeout(lang.hitch(this, function(){
+					// Focus the textarea... unless focus has moved outside of the editor completely during the timeout.
+					// Since we override focus, so we just need to call it.
+					if(this.editor.focused){
+						this.editor.focus();
 					}
-				});
-
-				// We actually do need to trap this plugin and adjust how we
-				// display the textarea.
-				if(this._fsPlugin){
-					this._fsPlugin._getAltViewNode = function(){
-						return self.sourceArea;
-					};
+				}), 100);
+			}));
+		},
+
+		_showSource: function(source){
+			// summary:
+			//		Function to toggle between the source and RTE views.
+			// source: boolean
+			//		Boolean value indicating if it should be in source mode or not.
+			// tags:
+			//		private
+			var ed = this.editor;
+			var edPlugins = ed._plugins;
+			var html;
+			this._sourceShown = source;
+			var self = this;
+			try{
+				if(!this.sourceArea){
+					this._createSourceView();
 				}
+				if(source){
+					// Update the QueryCommandEnabled function to disable everything but
+					// the source view mode.  Have to over-ride a function, then kick all
+					// plugins to check their state.
+					ed._sourceQueryCommandEnabled = ed.queryCommandEnabled;
+					ed.queryCommandEnabled = function(cmd){
+						return cmd.toLowerCase() === "viewsource";
+					};
+					this.editor.onDisplayChanged();
+					html = ed.get("value");
+					html = this._filter(html);
+					ed.set("value", html);
+					array.forEach(edPlugins, function(p){
+						// Turn off any plugins not controlled by queryCommandenabled.
+						if(p && !(p instanceof ViewSource) && p.isInstanceOf(_Plugin)){
+							p.set("disabled", true)
+						}
+					});
+
+					// We actually do need to trap this plugin and adjust how we
+					// display the textarea.
+					if(this._fsPlugin){
+						this._fsPlugin._getAltViewNode = function(){
+							return self.sourceArea;
+						};
+					}
 
-				this.sourceArea.value = html;
-
-				// Since neither iframe nor textarea have margin, border, or padding,
-				// just set sizes equal
-				this.sourceArea.style.height = ed.iframe.style.height;
-				this.sourceArea.style.width = ed.iframe.style.width;
-				domStyle.set(ed.iframe, "display", "none");
-				domStyle.set(this.sourceArea, {
-					display: "block"
-				});
-
-				var resizer = function(){
-					// function to handle resize events.
-					// Will check current VP and only resize if
-					// different.
-					var vp = winUtils.getBox();
-
-					if("_prevW" in this && "_prevH" in this){
-						// No actual size change, ignore.
-						if(vp.w === this._prevW && vp.h === this._prevH){
-							return;
+					this.sourceArea.value = html;
+
+					// Since neither iframe nor textarea have margin, border, or padding,
+					// just set sizes equal
+					this.sourceArea.style.height = ed.iframe.style.height;
+					this.sourceArea.style.width = ed.iframe.style.width;
+					domStyle.set(ed.iframe, "display", "none");
+					domStyle.set(this.sourceArea, {
+						display: "block"
+					});
+
+					var resizer = function(){
+						// function to handle resize events.
+						// Will check current VP and only resize if
+						// different.
+						var vp = winUtils.getBox(ed.ownerDocument);
+
+						if("_prevW" in this && "_prevH" in this){
+							// No actual size change, ignore.
+							if(vp.w === this._prevW && vp.h === this._prevH){
+								return;
+							}else{
+								this._prevW = vp.w;
+								this._prevH = vp.h;
+							}
 						}else{
 							this._prevW = vp.w;
 							this._prevH = vp.h;
 						}
-					}else{
-						this._prevW = vp.w;
-						this._prevH = vp.h;
-					}
-					if(this._resizer){
-						clearTimeout(this._resizer);
-						delete this._resizer;
+						if(this._resizer){
+							clearTimeout(this._resizer);
+							delete this._resizer;
+						}
+						// Timeout it to help avoid spamming resize on IE.
+						// Works for all browsers.
+						this._resizer = setTimeout(lang.hitch(this, function(){
+							delete this._resizer;
+							this._resize();
+						}), 10);
+					};
+					this._resizeHandle = on(window, "resize", lang.hitch(this, resizer));
+
+					//Call this on a delay once to deal with IE glitchiness on initial size.
+					setTimeout(lang.hitch(this, this._resize), 100);
+
+					//Trigger a check for command enablement/disablement.
+					this.editor.onNormalizedDisplayChanged();
+
+					this.editor.__oldGetValue = this.editor.getValue;
+					this.editor.getValue = lang.hitch(this, function(){
+						var txt = this.sourceArea.value;
+						txt = this._filter(txt);
+						return txt;
+					});
+
+					this._setListener = aspect.after(this.editor, "setValue", lang.hitch(this, function(htmlTxt){
+						htmlTxt = htmlTxt || "";
+						htmlTxt = this._filter(htmlTxt);
+						this.sourceArea.value = htmlTxt;
+					}), true);
+				}else{
+					// First check that we were in source view before doing anything.
+					// corner case for being called with a value of false and we hadn't
+					// actually been in source display mode.
+					if(!ed._sourceQueryCommandEnabled){
+						return;
 					}
-					// Timeout it to help avoid spamming resize on IE.
-					// Works for all browsers.
-					this._resizer = setTimeout(lang.hitch(this, function(){
-						delete this._resizer;
-						this._resize();
-					}), 10);
-				};
-				this._resizeHandle = on(window, "resize", lang.hitch(this, resizer));
 
-				//Call this on a delay once to deal with IE glitchiness on initial size.
-				setTimeout(lang.hitch(this, this._resize), 100);
+					// Remove the set listener.
+					this._setListener.remove();
+					delete this._setListener;
 
-				//Trigger a check for command enablement/disablement.
-				this.editor.onNormalizedDisplayChanged();
+					this._resizeHandle.remove();
+					delete this._resizeHandle;
 
-				this.editor.__oldGetValue = this.editor.getValue;
-				this.editor.getValue = lang.hitch(this, function(){
-					var txt = this.sourceArea.value;
-					txt = this._filter(txt);
-					return txt;
-				});
-			}else{
-				// First check that we were in source view before doing anything.
-				// corner case for being called with a value of false and we hadn't
-				// actually been in source display mode.
-				if(!ed._sourceQueryCommandEnabled){
-					return;
-				}
-				this._resizeHandle.remove();
-				delete this._resizeHandle;
-
-				if(this.editor.__oldGetValue){
-					this.editor.getValue = this.editor.__oldGetValue;
-					delete this.editor.__oldGetValue;
-				}
+					if(this.editor.__oldGetValue){
+						this.editor.getValue = this.editor.__oldGetValue;
+						delete this.editor.__oldGetValue;
+					}
 
-				// Restore all the plugin buttons state.
-				ed.queryCommandEnabled = ed._sourceQueryCommandEnabled;
-				if(!this._readOnly){
-					html = this.sourceArea.value;
-					html = this._filter(html);
-					ed.beginEditing();
-					ed.set("value", html);
-					ed.endEditing();
-				}
+					// Restore all the plugin buttons state.
+					ed.queryCommandEnabled = ed._sourceQueryCommandEnabled;
+					if(!this._readOnly){
+						html = this.sourceArea.value;
+						html = this._filter(html);
+						ed.beginEditing();
+						ed.set("value", html);
+						ed.endEditing();
+					}
 
-				array.forEach(edPlugins, function(p){
-					// Turn back on any plugins we turned off.
-					p.set("disabled", false);
-				});
+					array.forEach(edPlugins, function(p){
+						// Turn back on any plugins we turned off.
+						if(p && p.isInstanceOf(_Plugin)){
+							p.set("disabled", false);
+						}
+					});
 
-				domStyle.set(this.sourceArea, "display", "none");
-				domStyle.set(ed.iframe, "display", "block");
-				delete ed._sourceQueryCommandEnabled;
+					domStyle.set(this.sourceArea, "display", "none");
+					domStyle.set(ed.iframe, "display", "block");
+					delete ed._sourceQueryCommandEnabled;
 
-				//Trigger a check for command enablement/disablement.
-				this.editor.onDisplayChanged();
-			}
-			// Call a delayed resize to wait for some things to display in header/footer.
-			setTimeout(lang.hitch(this, function(){
-				// Make resize calls.
-				var parent = ed.domNode.parentNode;
-				if(parent){
-					var container = registry.getEnclosingWidget(parent);
-					if(container && container.resize){
-						container.resize();
-					}
+					//Trigger a check for command enablement/disablement.
+					this.editor.onDisplayChanged();
 				}
-                ed.resize();
-			}), 300);
-		}catch(e){
-			console.log(e);
-		}
-	},
-
-	updateState: function(){
-		// summary:
-		//		Over-ride for button state control for disabled to work.
-		this.button.set("disabled", this.get("disabled"));
-	},
-
-	_resize: function(){
-		// summary:
-		//		Internal function to resize the source view
-		// tags:
-		//		private
-		var ed = this.editor;
-		var tbH = ed.getHeaderHeight();
-		var fH = ed.getFooterHeight();
-		var eb = domGeometry.position(ed.domNode);
-
-		// Styles are now applied to the internal source container, so we have
-		// to subtract them off.
-		var containerPadding = domGeometry.getPadBorderExtents(ed.iframe.parentNode);
-		var containerMargin = domGeometry.getMarginExtents(ed.iframe.parentNode);
-
-		var extents = domGeometry.getPadBorderExtents(ed.domNode);
-		var edb = {
-			w: eb.w - extents.w,
-			h: eb.h - (tbH + extents.h + + fH)
-		};
-
-		// Fullscreen gets odd, so we need to check for the FS plugin and
-		// adapt.
-		if(this._fsPlugin && this._fsPlugin.isFullscreen){
-			//Okay, probably in FS, adjust.
-			var vp = winUtils.getBox();
-			edb.w = (vp.w - extents.w);
-			edb.h = (vp.h - (tbH + extents.h + fH));
-		}
+				// Call a delayed resize to wait for some things to display in header/footer.
+				setTimeout(lang.hitch(this, function(){
+					// Make resize calls.
+					var parent = ed.domNode.parentNode;
+					if(parent){
+						var container = registry.getEnclosingWidget(parent);
+						if(container && container.resize){
+							container.resize();
+						}
+					}
+					ed.resize();
+				}), 300);
+			}catch(e){
+				console.log(e);
+			}
+		},
+
+		updateState: function(){
+			// summary:
+			//		Over-ride for button state control for disabled to work.
+			this.button.set("disabled", this.get("disabled"));
+		},
+
+		_resize: function(){
+			// summary:
+			//		Internal function to resize the source view
+			// tags:
+			//		private
+			var ed = this.editor;
+			var tbH = ed.getHeaderHeight();
+			var fH = ed.getFooterHeight();
+			var eb = domGeometry.position(ed.domNode);
+
+			// Styles are now applied to the internal source container, so we have
+			// to subtract them off.
+			var containerPadding = domGeometry.getPadBorderExtents(ed.iframe.parentNode);
+			var containerMargin = domGeometry.getMarginExtents(ed.iframe.parentNode);
+
+			var extents = domGeometry.getPadBorderExtents(ed.domNode);
+			var edb = {
+				w: eb.w - extents.w,
+				h: eb.h - (tbH + extents.h + fH)
+			};
 
-		if(has("ie")){
-			// IE is always off by 2px, so we have to adjust here
-			// Note that IE ZOOM is broken here.  I can't get
-			//it to scale right.
-			edb.h -= 2;
-		}
+			// Fullscreen gets odd, so we need to check for the FS plugin and
+			// adapt.
+			if(this._fsPlugin && this._fsPlugin.isFullscreen){
+				//Okay, probably in FS, adjust.
+				var vp = winUtils.getBox(ed.ownerDocument);
+				edb.w = (vp.w - extents.w);
+				edb.h = (vp.h - (tbH + extents.h + fH));
+			}
 
-		// IE has a horrible zoom bug.  So, we have to try and account for
-		// it and fix up the scaling.
-		if(this._ieFixNode){
-			var _ie7zoom = -this._ieFixNode.offsetTop / 1000;
-			edb.w = Math.floor((edb.w + 0.9) / _ie7zoom);
-			edb.h = Math.floor((edb.h + 0.9) / _ie7zoom);
-		}
+			if(has("ie")){
+				// IE is always off by 2px, so we have to adjust here
+				// Note that IE ZOOM is broken here.  I can't get
+				//it to scale right.
+				edb.h -= 2;
+			}
 
-		domGeometry.setMarginBox(this.sourceArea, {
-			w: edb.w - (containerPadding.w + containerMargin.w),
-			h: edb.h - (containerPadding.h + containerMargin.h)
-		});
+			// IE has a horrible zoom bug.  So, we have to try and account for
+			// it and fix up the scaling.
+			if(this._ieFixNode){
+				var _ie7zoom = -this._ieFixNode.offsetTop / 1000;
+				edb.w = Math.floor((edb.w + 0.9) / _ie7zoom);
+				edb.h = Math.floor((edb.h + 0.9) / _ie7zoom);
+			}
 
-		// Scale the parent container too in this case.
-		domGeometry.setMarginBox(ed.iframe.parentNode, {
-			h: edb.h
-		});
-	},
+			domGeometry.setMarginBox(this.sourceArea, {
+				w: edb.w - (containerPadding.w + containerMargin.w),
+				h: edb.h - (containerPadding.h + containerMargin.h)
+			});
 
-	_createSourceView: function(){
-		// summary:
-		//		Internal function for creating the source view area.
-		// tags:
-		//		private
-		var ed = this.editor;
-		var edPlugins = ed._plugins;
-		this.sourceArea = domConstruct.create("textarea");
-		if(this.readOnly){
-			domAttr.set(this.sourceArea, "readOnly", true);
-			this._readOnly = true;
-		}
-		domStyle.set(this.sourceArea, {
-			padding: "0px",
-			margin: "0px",
-			borderWidth: "0px",
-			borderStyle: "none"
-		});
-		domConstruct.place(this.sourceArea, ed.iframe, "before");
-
-		if(has("ie") && ed.iframe.parentNode.lastChild !== ed.iframe){
-			// There's some weirdo div in IE used for focus control
-			// But is messed up scaling the textarea if we don't config
-			// it some so it doesn't have a varying height.
-			domStyle.set(ed.iframe.parentNode.lastChild,{
-				width: "0px",
-				height: "0px",
+			// Scale the parent container too in this case.
+			domGeometry.setMarginBox(ed.iframe.parentNode, {
+				h: edb.h
+			});
+		},
+
+		_createSourceView: function(){
+			// summary:
+			//		Internal function for creating the source view area.
+			// tags:
+			//		private
+			var ed = this.editor;
+			var edPlugins = ed._plugins;
+			this.sourceArea = domConstruct.create("textarea");
+			if(this.readOnly){
+				domAttr.set(this.sourceArea, "readOnly", true);
+				this._readOnly = true;
+			}
+			domStyle.set(this.sourceArea, {
 				padding: "0px",
 				margin: "0px",
 				borderWidth: "0px",
 				borderStyle: "none"
 			});
-		}
+			domAttr.set(this.sourceArea, "aria-label", this.editor.id);
+
+			domConstruct.place(this.sourceArea, ed.iframe, "before");
+
+			if(has("ie") && ed.iframe.parentNode.lastChild !== ed.iframe){
+				// There's some weirdo div in IE used for focus control
+				// But is messed up scaling the textarea if we don't config
+				// it some so it doesn't have a varying height.
+				domStyle.set(ed.iframe.parentNode.lastChild, {
+					width: "0px",
+					height: "0px",
+					padding: "0px",
+					margin: "0px",
+					borderWidth: "0px",
+					borderStyle: "none"
+				});
+			}
 
-		// We also need to take over editor focus a bit here, so that focus calls to
-		// focus the editor will focus to the right node when VS is active.
-		ed._viewsource_oldFocus = ed.focus;
-		var self = this;
-		ed.focus = function(){
-			if(self._sourceShown){
-				self.setSourceAreaCaret();
-			}else{
-				try{
-					if(this._vsFocused){
-						delete this._vsFocused;
-						// Must focus edit node in this case (webkit only) or
-						// focus doesn't shift right, but in normal
-						// cases we focus with the regular function.
-						focus.focus(ed.editNode);
-					}else{
-						ed._viewsource_oldFocus();
+			// We also need to take over editor focus a bit here, so that focus calls to
+			// focus the editor will focus to the right node when VS is active.
+			ed._viewsource_oldFocus = ed.focus;
+			var self = this;
+			ed.focus = function(){
+				if(self._sourceShown){
+					self.setSourceAreaCaret();
+				}else{
+					try{
+						if(this._vsFocused){
+							delete this._vsFocused;
+							// Must focus edit node in this case (webkit only) or
+							// focus doesn't shift right, but in normal
+							// cases we focus with the regular function.
+							focus.focus(ed.editNode);
+						}else{
+							ed._viewsource_oldFocus();
+						}
+					}catch(e){
+						console.log(e);
 					}
-				}catch(e){
-					console.log(e);
 				}
-			}
-		};
-
-		var i, p;
-		for(i = 0; i < edPlugins.length; i++){
-			// We actually do need to trap this plugin and adjust how we
-			// display the textarea.
-			p = edPlugins[i];
-			if(p && (p.declaredClass === "dijit._editor.plugins.FullScreen" ||
-					p.declaredClass === (dijit._scopeName +
-					"._editor.plugins.FullScreen"))){
-				this._fsPlugin = p;
-				break;
-			}
-		}
-		if(this._fsPlugin){
-			// Found, we need to over-ride the alt-view node function
-			// on FullScreen with our own, chain up to parent call when appropriate.
-			this._fsPlugin._viewsource_getAltViewNode = this._fsPlugin._getAltViewNode;
-			this._fsPlugin._getAltViewNode = function(){
-				return self._sourceShown?self.sourceArea:this._viewsource_getAltViewNode();
 			};
-		}
 
-		// Listen to the source area for key events as well, as we need to be able to hotkey toggle
-		// it from there too.
-		this.connect(this.sourceArea, "onkeydown", lang.hitch(this, function(e){
-			if(this._sourceShown && e.keyCode == keys.F12 && e.ctrlKey && e.shiftKey){
-				this.button.focus();
-				this.button.set("checked", false);
-				setTimeout(lang.hitch(this, function(){ed.focus();}), 100);
-				event.stop(e);
+			var i, p;
+			for(i = 0; i < edPlugins.length; i++){
+				// We actually do need to trap this plugin and adjust how we
+				// display the textarea.
+				p = edPlugins[i];
+				if(p && (p.declaredClass === "dijit._editor.plugins.FullScreen" ||
+					p.declaredClass === (dijit._scopeName +
+						"._editor.plugins.FullScreen"))){
+					this._fsPlugin = p;
+					break;
+				}
+			}
+			if(this._fsPlugin){
+				// Found, we need to over-ride the alt-view node function
+				// on FullScreen with our own, chain up to parent call when appropriate.
+				this._fsPlugin._viewsource_getAltViewNode = this._fsPlugin._getAltViewNode;
+				this._fsPlugin._getAltViewNode = function(){
+					return self._sourceShown ? self.sourceArea : this._viewsource_getAltViewNode();
+				};
 			}
-		}));
-	},
-
-	_stripScripts: function(html){
-		// summary:
-		//		Strips out script tags from the HTML used in editor.
-		// html: String
-		//		The HTML to filter
-		// tags:
-		//		private
-		if(html){
-			// Look for closed and unclosed (malformed) script attacks.
-			html = html.replace(/<\s*script[^>]*>((.|\s)*?)<\\?\/\s*script\s*>/ig, "");
-			html = html.replace(/<\s*script\b([^<>]|\s)*>?/ig, "");
-			html = html.replace(/<[^>]*=(\s|)*[("|')]javascript:[^$1][(\s|.)]*[$1][^>]*>/ig, "");
-		}
-		return html;
-	},
-
-	_stripComments: function(html){
-		// summary:
-		//		Strips out comments from the HTML used in editor.
-		// html: String
-		//		The HTML to filter
-		// tags:
-		//		private
-		if(html){
-			html = html.replace(/<!--(.|\s){1,}?-->/g, "");
-		}
-		return html;
-	},
-
-	_stripIFrames: function(html){
-		// summary:
-		//		Strips out iframe tags from the content, to avoid iframe script
-		//		style injection attacks.
-		// html: String
-		//		The HTML to filter
-		// tags:
-		//		private
-		if(html){
-			html = html.replace(/<\s*iframe[^>]*>((.|\s)*?)<\\?\/\s*iframe\s*>/ig, "");
-		}
-		return html;
-	},
 
-	_filter: function(html){
-		// summary:
-		//		Internal function to perform some filtering on the HTML.
-		// html: String
-		//		The HTML to filter
-		// tags:
-		//		private
-		if(html){
-			if(this.stripScripts){
-				html = this._stripScripts(html);
+			// Listen to the source area for key events as well, as we need to be able to hotkey toggle
+			// it from there too.
+			this.own(on(this.sourceArea, "keydown", lang.hitch(this, function(e){
+				if(this._sourceShown && e.keyCode == keys.F12 && e.ctrlKey && e.shiftKey){
+					this.button.focus();
+					this.button.set("checked", false);
+					setTimeout(lang.hitch(this, function(){
+						ed.focus();
+					}), 100);
+					e.stopPropagation();
+					e.preventDefault();
+				}
+			})));
+		},
+
+		_stripScripts: function(html){
+			// summary:
+			//		Strips out script tags from the HTML used in editor.
+			// html: String
+			//		The HTML to filter
+			// tags:
+			//		private
+			if(html){
+				// Look for closed and unclosed (malformed) script attacks.
+				html = html.replace(/<\s*script[^>]*>((.|\s)*?)<\\?\/\s*script\s*>/ig, "");
+				html = html.replace(/<\s*script\b([^<>]|\s)*>?/ig, "");
+				html = html.replace(/<[^>]*=(\s|)*[("|')]javascript:[^$1][(\s|.)]*[$1][^>]*>/ig, "");
 			}
-			if(this.stripComments){
-				html = this._stripComments(html);
+			return html;
+		},
+
+		_stripComments: function(html){
+			// summary:
+			//		Strips out comments from the HTML used in editor.
+			// html: String
+			//		The HTML to filter
+			// tags:
+			//		private
+			if(html){
+				html = html.replace(/<!--(.|\s){1,}?-->/g, "");
 			}
-			if(this.stripIFrames){
-				html = this._stripIFrames(html);
+			return html;
+		},
+
+		_stripIFrames: function(html){
+			// summary:
+			//		Strips out iframe tags from the content, to avoid iframe script
+			//		style injection attacks.
+			// html: String
+			//		The HTML to filter
+			// tags:
+			//		private
+			if(html){
+				html = html.replace(/<\s*iframe[^>]*>((.|\s)*?)<\\?\/\s*iframe\s*>/ig, "");
 			}
-		}
-		return html;
-	},
-
-	setSourceAreaCaret: function(){
-		// summary:
-		//		Internal function to set the caret in the sourceArea
-		//		to 0x0
-		var global = win.global;
-		var elem = this.sourceArea;
-		focus.focus(elem);
-		if(this._sourceShown && !this.readOnly){
-			if(has("ie")){
-				if(this.sourceArea.createTextRange){
+			return html;
+		},
+
+		_filter: function(html){
+			// summary:
+			//		Internal function to perform some filtering on the HTML.
+			// html: String
+			//		The HTML to filter
+			// tags:
+			//		private
+			if(html){
+				if(this.stripScripts){
+					html = this._stripScripts(html);
+				}
+				if(this.stripComments){
+					html = this._stripComments(html);
+				}
+				if(this.stripIFrames){
+					html = this._stripIFrames(html);
+				}
+			}
+			return html;
+		},
+
+		setSourceAreaCaret: function(){
+			// summary:
+			//		Internal function to set the caret in the sourceArea
+			//		to 0x0
+			var elem = this.sourceArea;
+			focus.focus(elem);
+			if(this._sourceShown && !this.readOnly){
+				if(elem.setSelectionRange){
+					elem.setSelectionRange(0, 0);
+				}else if(this.sourceArea.createTextRange){
+					// IE
 					var range = elem.createTextRange();
 					range.collapse(true);
 					range.moveStart("character", -99999); // move to 0
@@ -519,46 +537,42 @@ var ViewSource = declare("dijit._editor.plugins.ViewSource",_Plugin, {
 					range.moveEnd("character", 0);
 					range.select();
 				}
-			}else if(global.getSelection){
-				if(elem.setSelectionRange){
-					elem.setSelectionRange(0,0);
-				}
 			}
+		},
+
+		destroy: function(){
+			// summary:
+			//		Over-ride to remove the node used to correct for IE's
+			//		zoom bug.
+			if(this._ieFixNode){
+				domConstruct.destroy(this._ieFixNode);
+			}
+			if(this._resizer){
+				clearTimeout(this._resizer);
+				delete this._resizer;
+			}
+			if(this._resizeHandle){
+				this._resizeHandle.remove();
+				delete this._resizeHandle;
+			}
+			if(this._setListener){
+				this._setListener.remove();
+				delete this._setListener;
+			}
+			this.inherited(arguments);
 		}
-	},
-
-	destroy: function(){
-		// summary:
-		//		Over-ride to remove the node used to correct for IE's
-		//		zoom bug.
-		if(this._ieFixNode){
-			win.body().removeChild(this._ieFixNode);
-		}
-		if(this._resizer){
-			clearTimeout(this._resizer);
-			delete this._resizer;
-		}
-		if(this._resizeHandle){
-			this._resizeHandle.remove();
-			delete this._resizeHandle;
-		}
-		this.inherited(arguments);
-	}
-});
-
-// Register this plugin.
-// For back-compat accept "viewsource" (all lowercase) too, remove in 2.0
-_Plugin.registry["viewSource"] = _Plugin.registry["viewsource"] = function(args){
-	return new ViewSource({
-		readOnly: ("readOnly" in args)?args.readOnly:false,
-		stripComments: ("stripComments" in args)?args.stripComments:true,
-		stripScripts: ("stripScripts" in args)?args.stripScripts:true,
-		stripIFrames: ("stripIFrames" in args)?args.stripIFrames:true
 	});
-};
-
-
 
+	// Register this plugin.
+	// For back-compat accept "viewsource" (all lowercase) too, remove in 2.0
+	_Plugin.registry["viewSource"] = _Plugin.registry["viewsource"] = function(args){
+		return new ViewSource({
+			readOnly: ("readOnly" in args) ? args.readOnly : false,
+			stripComments: ("stripComments" in args) ? args.stripComments : true,
+			stripScripts: ("stripScripts" in args) ? args.stripScripts : true,
+			stripIFrames: ("stripIFrames" in args) ? args.stripIFrames : true
+		});
+	};
 
-return ViewSource;
+	return ViewSource;
 });
diff --git a/dijit/_editor/range.js b/dijit/_editor/range.js
index 58a5d0a..f2d5868 100644
--- a/dijit/_editor/range.js
+++ b/dijit/_editor/range.js
@@ -1,553 +1,559 @@
 define([
 	"dojo/_base/array", // array.every
 	"dojo/_base/declare", // declare
-	"dojo/_base/lang", // lang.isArray
-	"dojo/_base/window", // win.global
-	".."	// for exporting symbols to dijit, TODO: remove in 2.0
-], function(array, declare, lang, win, dijit){
-
-// module:
-//		dijit/_editor/range
-// summary:
-//		W3C range API
-
-
-dijit.range={};
-
-dijit.range.getIndex = function(/*DomNode*/node, /*DomNode*/parent){
-//	dojo.profile.start("dijit.range.getIndex");
-	var ret = [], retR = [];
-	var onode = node;
-
-	var pnode, n;
-	while(node != parent){
-		var i = 0;
-		pnode = node.parentNode;
-		while((n = pnode.childNodes[i++])){
-			if(n === node){
-				--i;
-				break;
+	"dojo/_base/lang" // lang.isArray
+], function(array, declare, lang){
+
+	// module:
+	//		dijit/_editor/range
+
+	var rangeapi = {
+		// summary:
+		//		W3C range API
+
+		getIndex: function(/*DomNode*/ node, /*DomNode*/ parent){
+			var ret = [], retR = [];
+			var onode = node;
+
+			var pnode, n;
+			while(node != parent){
+				var i = 0;
+				pnode = node.parentNode;
+				while((n = pnode.childNodes[i++])){
+					if(n === node){
+						--i;
+						break;
+					}
+				}
+				//if(i>=pnode.childNodes.length){
+				//console.debug("Error finding index of a node in dijit/range.getIndex()");
+				//}
+				ret.unshift(i);
+				retR.unshift(i - pnode.childNodes.length);
+				node = pnode;
 			}
-		}
-		//if(i>=pnode.childNodes.length){
-			//dojo.debug("Error finding index of a node in dijit.range.getIndex");
-		//}
-		ret.unshift(i);
-		retR.unshift(i - pnode.childNodes.length);
-		node = pnode;
-	}
-
-	//normalized() can not be called so often to prevent
-	//invalidating selection/range, so we have to detect
-	//here that any text nodes in a row
-	if(ret.length > 0 && onode.nodeType == 3){
-		n = onode.previousSibling;
-		while(n && n.nodeType == 3){
-			ret[ret.length - 1]--;
-			n = n.previousSibling;
-		}
-		n = onode.nextSibling;
-		while(n && n.nodeType == 3){
-			retR[retR.length - 1]++;
-			n = n.nextSibling;
-		}
-	}
-//	dojo.profile.end("dijit.range.getIndex");
-	return {o: ret, r:retR};
-};
-
-dijit.range.getNode = function(/*Array*/index, /*DomNode*/parent){
-	if(!lang.isArray(index) || index.length == 0){
-		return parent;
-	}
-	var node = parent;
-//	if(!node)debugger
-	array.every(index, function(i){
-		if(i >= 0 && i < node.childNodes.length){
-			node = node.childNodes[i];
-		}else{
-			node = null;
-			//console.debug('Error: can not find node with index',index,'under parent node',parent );
-			return false; //terminate array.every
-		}
-		return true; //carry on the every loop
-	});
-
-	return node;
-};
-
-dijit.range.getCommonAncestor = function(n1, n2, root){
-	root = root || n1.ownerDocument.body;
-	var getAncestors = function(n){
-		var as = [];
-		while(n){
-			as.unshift(n);
-			if(n !== root){
-				n = n.parentNode;
-			}else{
-				break;
+
+			//normalized() can not be called so often to prevent
+			//invalidating selection/range, so we have to detect
+			//here that any text nodes in a row
+			if(ret.length > 0 && onode.nodeType == 3){
+				n = onode.previousSibling;
+				while(n && n.nodeType == 3){
+					ret[ret.length - 1]--;
+					n = n.previousSibling;
+				}
+				n = onode.nextSibling;
+				while(n && n.nodeType == 3){
+					retR[retR.length - 1]++;
+					n = n.nextSibling;
+				}
 			}
-		}
-		return as;
-	};
-	var n1as = getAncestors(n1);
-	var n2as = getAncestors(n2);
-
-	var m = Math.min(n1as.length, n2as.length);
-	var com = n1as[0]; //at least, one element should be in the array: the root (BODY by default)
-	for(var i = 1; i < m; i++){
-		if(n1as[i] === n2as[i]){
-			com = n1as[i]
-		}else{
-			break;
-		}
-	}
-	return com;
-};
-
-dijit.range.getAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){
-	root = root || node.ownerDocument.body;
-	while(node && node !== root){
-		var name = node.nodeName.toUpperCase();
-		if(regex.test(name)){
-			return node;
-		}
 
-		node = node.parentNode;
-	}
-	return null;
-};
-
-dijit.range.BlockTagNames = /^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/;
-dijit.range.getBlockAncestor = function(/*DomNode*/node, /*RegEx?*/regex, /*DomNode?*/root){
-	root = root || node.ownerDocument.body;
-	regex = regex || dijit.range.BlockTagNames;
-	var block = null, blockContainer;
-	while(node && node !== root){
-		var name = node.nodeName.toUpperCase();
-		if(!block && regex.test(name)){
-			block = node;
-		}
-		if(!blockContainer && (/^(?:BODY|TD|TH|CAPTION)$/).test(name)){
-			blockContainer = node;
-		}
+			return {o: ret, r:retR};
+		},
 
-		node = node.parentNode;
-	}
-	return {blockNode:block, blockContainer:blockContainer || node.ownerDocument.body};
-};
-
-dijit.range.atBeginningOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){
-	var atBeginning = false;
-	var offsetAtBeginning = (offset == 0);
-	if(!offsetAtBeginning && node.nodeType == 3){ //if this is a text node, check whether the left part is all space
-		if(/^[\s\xA0]+$/.test(node.nodeValue.substr(0, offset))){
-			offsetAtBeginning = true;
-		}
-	}
-	if(offsetAtBeginning){
-		var cnode = node;
-		atBeginning = true;
-		while(cnode && cnode !== container){
-			if(cnode.previousSibling){
-				atBeginning = false;
-				break;
+		getNode: function(/*Array*/ index, /*DomNode*/ parent){
+			if(!lang.isArray(index) || index.length == 0){
+				return parent;
 			}
-			cnode = cnode.parentNode;
-		}
-	}
-	return atBeginning;
-};
-
-dijit.range.atEndOfContainer = function(/*DomNode*/container, /*DomNode*/node, /*Int*/offset){
-	var atEnd = false;
-	var offsetAtEnd = (offset == (node.length || node.childNodes.length));
-	if(!offsetAtEnd && node.nodeType == 3){ //if this is a text node, check whether the right part is all space
-		if(/^[\s\xA0]+$/.test(node.nodeValue.substr(offset))){
-			offsetAtEnd = true;
-		}
-	}
-	if(offsetAtEnd){
-		var cnode = node;
-		atEnd = true;
-		while(cnode && cnode !== container){
-			if(cnode.nextSibling){
-				atEnd = false;
-				break;
-			}
-			cnode = cnode.parentNode;
-		}
-	}
-	return atEnd;
-};
-
-dijit.range.adjacentNoneTextNode = function(startnode, next){
-	var node = startnode;
-	var len = (0 - startnode.length) || 0;
-	var prop = next ? 'nextSibling' : 'previousSibling';
-	while(node){
-		if(node.nodeType != 3){
-			break;
-		}
-		len += node.length;
-		node = node[prop];
-	}
-	return [node,len];
-};
-
-dijit.range._w3c = Boolean(window['getSelection']);
-dijit.range.create = function(/*Window?*/window){
-	if(dijit.range._w3c){
-		return (window || win.global).document.createRange();
-	}else{//IE
-		return new dijit.range.W3CRange;
-	}
-};
-
-dijit.range.getSelection = function(/*Window*/win, /*Boolean?*/ignoreUpdate){
-	if(dijit.range._w3c){
-		return win.getSelection();
-	}else{//IE
-		var s = new dijit.range.ie.selection(win);
-		if(!ignoreUpdate){
-			s._getCurrentSelection();
-		}
-		return s;
-	}
-};
-
-if(!dijit.range._w3c){
-	dijit.range.ie = {
-		cachedSelection: {},
-		selection: function(win){
-			this._ranges = [];
-			this.addRange = function(r, /*boolean*/internal){
-				this._ranges.push(r);
-				if(!internal){
-					r._select();
-				}
-				this.rangeCount = this._ranges.length;
-			};
-			this.removeAllRanges = function(){
-				//don't detach, the range may be used later
-//				for(var i=0;i<this._ranges.length;i++){
-//					this._ranges[i].detach();
-//				}
-				this._ranges = [];
-				this.rangeCount = 0;
-			};
-			var _initCurrentRange = function(){
-				var r = win.document.selection.createRange();
-				var type = win.document.selection.type.toUpperCase();
-				if(type == "CONTROL"){
-					//TODO: multiple range selection(?)
-					return new dijit.range.W3CRange(dijit.range.ie.decomposeControlRange(r));
+			var node = parent;
+			//	if(!node)debugger
+			array.every(index, function(i){
+				if(i >= 0 && i < node.childNodes.length){
+					node = node.childNodes[i];
 				}else{
-					return new dijit.range.W3CRange(dijit.range.ie.decomposeTextRange(r));
+					node = null;
+					//console.debug('Error: can not find node with index',index,'under parent node',parent );
+					return false; //terminate array.every
 				}
+				return true; //carry on the every loop
+			});
+
+			return node;
+		},
+
+		getCommonAncestor: function(n1, n2, root){
+			root = root || n1.ownerDocument.body;
+			var getAncestors = function(n){
+				var as = [];
+				while(n){
+					as.unshift(n);
+					if(n !== root){
+						n = n.parentNode;
+					}else{
+						break;
+					}
+				}
+				return as;
 			};
-			this.getRangeAt = function(i){
-				return this._ranges[i];
-			};
-			this._getCurrentSelection = function(){
-				this.removeAllRanges();
-				var r = _initCurrentRange();
-				if(r){
-					this.addRange(r, true);
-					this.isCollapsed = r.collapsed;
+			var n1as = getAncestors(n1);
+			var n2as = getAncestors(n2);
+
+			var m = Math.min(n1as.length, n2as.length);
+			var com = n1as[0]; //at least, one element should be in the array: the root (BODY by default)
+			for(var i = 1; i < m; i++){
+				if(n1as[i] === n2as[i]){
+					com = n1as[i]
 				}else{
-					this.isCollapsed = true;
+					break;
 				}
-			};
+			}
+			return com;
 		},
-		decomposeControlRange: function(range){
-			var firstnode = range.item(0), lastnode = range.item(range.length - 1);
-			var startContainer = firstnode.parentNode, endContainer = lastnode.parentNode;
-			var startOffset = dijit.range.getIndex(firstnode, startContainer).o[0];
-			var endOffset = dijit.range.getIndex(lastnode, endContainer).o[0] + 1;
-			return [startContainer, startOffset,endContainer, endOffset];
+
+		getAncestor: function(/*DomNode*/ node, /*RegEx?*/ regex, /*DomNode?*/ root){
+			root = root || node.ownerDocument.body;
+			while(node && node !== root){
+				var name = node.nodeName.toUpperCase();
+				if(regex.test(name)){
+					return node;
+				}
+
+				node = node.parentNode;
+			}
+			return null;
 		},
-		getEndPoint: function(range, end){
-			var atmrange = range.duplicate();
-			atmrange.collapse(!end);
-			var cmpstr = 'EndTo' + (end ? 'End' : 'Start');
-			var parentNode = atmrange.parentElement();
-
-			var startnode, startOffset, lastNode;
-			if(parentNode.childNodes.length > 0){
-				array.every(parentNode.childNodes, function(node, i){
-					var calOffset;
-					if(node.nodeType != 3){
-						atmrange.moveToElementText(node);
-
-						if(atmrange.compareEndPoints(cmpstr, range) > 0){
-							//startnode = node.previousSibling;
-							if(lastNode && lastNode.nodeType == 3){
-								//where shall we put the start? in the text node or after?
-								startnode = lastNode;
-								calOffset = true;
-							}else{
-								startnode = parentNode;
-								startOffset = i;
-								return false;
-							}
-						}else{
-							if(i == parentNode.childNodes.length - 1){
-								startnode = parentNode;
-								startOffset = parentNode.childNodes.length;
-								return false;
-							}
-						}
-					}else{
-						if(i == parentNode.childNodes.length - 1){//at the end of this node
-							startnode = node;
-							calOffset = true;
-						}
+
+		BlockTagNames: /^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/,
+
+		getBlockAncestor: function(/*DomNode*/ node, /*RegEx?*/ regex, /*DomNode?*/ root){
+			root = root || node.ownerDocument.body;
+			regex = regex || rangeapi.BlockTagNames;
+			var block = null, blockContainer;
+			while(node && node !== root){
+				var name = node.nodeName.toUpperCase();
+				if(!block && regex.test(name)){
+					block = node;
+				}
+				if(!blockContainer && (/^(?:BODY|TD|TH|CAPTION)$/).test(name)){
+					blockContainer = node;
+				}
+
+				node = node.parentNode;
+			}
+			return {blockNode:block, blockContainer:blockContainer || node.ownerDocument.body};
+		},
+
+		atBeginningOfContainer: function(/*DomNode*/ container, /*DomNode*/ node, /*Int*/ offset){
+			var atBeginning = false;
+			var offsetAtBeginning = (offset == 0);
+			if(!offsetAtBeginning && node.nodeType == 3){ //if this is a text node, check whether the left part is all space
+				if(/^[\s\xA0]+$/.test(node.nodeValue.substr(0, offset))){
+					offsetAtBeginning = true;
+				}
+			}
+			if(offsetAtBeginning){
+				var cnode = node;
+				atBeginning = true;
+				while(cnode && cnode !== container){
+					if(cnode.previousSibling){
+						atBeginning = false;
+						break;
 					}
-					//			try{
-					if(calOffset && startnode){
-						var prevnode = dijit.range.adjacentNoneTextNode(startnode)[0];
-						if(prevnode){
-							startnode = prevnode.nextSibling;
-						}else{
-							startnode = parentNode.firstChild; //firstChild must be a text node
-						}
-						var prevnodeobj = dijit.range.adjacentNoneTextNode(startnode);
-						prevnode = prevnodeobj[0];
-						var lenoffset = prevnodeobj[1];
-						if(prevnode){
-							atmrange.moveToElementText(prevnode);
-							atmrange.collapse(false);
-						}else{
-							atmrange.moveToElementText(parentNode);
-						}
-						atmrange.setEndPoint(cmpstr, range);
-						startOffset = atmrange.text.length - lenoffset;
+					cnode = cnode.parentNode;
+				}
+			}
+			return atBeginning;
+		},
 
-						return false;
+		atEndOfContainer: function(/*DomNode*/ container, /*DomNode*/ node, /*Int*/ offset){
+			var atEnd = false;
+			var offsetAtEnd = (offset == (node.length || node.childNodes.length));
+			if(!offsetAtEnd && node.nodeType == 3){ //if this is a text node, check whether the right part is all space
+				if(/^[\s\xA0]+$/.test(node.nodeValue.substr(offset))){
+					offsetAtEnd = true;
+				}
+			}
+			if(offsetAtEnd){
+				var cnode = node;
+				atEnd = true;
+				while(cnode && cnode !== container){
+					if(cnode.nextSibling){
+						atEnd = false;
+						break;
 					}
-					//			}catch(e){ debugger }
-					lastNode = node;
-					return true;
-				});
-			}else{
-				startnode = parentNode;
-				startOffset = 0;
+					cnode = cnode.parentNode;
+				}
 			}
+			return atEnd;
+		},
 
-			//if at the end of startnode and we are dealing with start container, then
-			//move the startnode to nextSibling if it is a text node
-			//TODO: do this for end container?
-			if(!end && startnode.nodeType == 1 && startOffset == startnode.childNodes.length){
-				var nextnode = startnode.nextSibling;
-				if(nextnode && nextnode.nodeType == 3){
-					startnode = nextnode;
-					startOffset = 0;
+		adjacentNoneTextNode: function(startnode, next){
+			var node = startnode;
+			var len = (0 - startnode.length) || 0;
+			var prop = next ? 'nextSibling' : 'previousSibling';
+			while(node){
+				if(node.nodeType != 3){
+					break;
 				}
+				len += node.length;
+				node = node[prop];
 			}
-			return [startnode, startOffset];
+			return [node,len];
 		},
-		setEndPoint: function(range, container, offset){
-			//text node
-			var atmrange = range.duplicate(), node, len;
-			if(container.nodeType != 3){ //normal node
-				if(offset > 0){
-					node = container.childNodes[offset - 1];
-					if(node){
-						if(node.nodeType == 3){
-							container = node;
-							offset = node.length;
-							//pass through
+
+		create: function(/*Window?*/ win){	// TODO: for 2.0, replace optional window param w/mandatory window or document param
+			win = win || window;
+			if(win.getSelection){
+				return win.document.createRange();
+			}else{//IE
+				return new W3CRange();
+			}
+		},
+
+		getSelection: function(/*Window*/ window, /*Boolean?*/ ignoreUpdate){
+			if(window.getSelection){
+				return window.getSelection();
+			}else{//IE
+				var s = new ie.selection(window);
+				if(!ignoreUpdate){
+					s._getCurrentSelection();
+				}
+				return s;
+			}
+		}
+	};
+
+	// TODO: convert to has() test?   But remember IE9 issues with quirks vs. standards in main frame vs. iframe.
+	if(!window.getSelection){
+		var ie = rangeapi.ie = {
+			cachedSelection: {},
+			selection: function(window){
+				this._ranges = [];
+				this.addRange = function(r, /*boolean*/ internal){
+					this._ranges.push(r);
+					if(!internal){
+						r._select();
+					}
+					this.rangeCount = this._ranges.length;
+				};
+				this.removeAllRanges = function(){
+					//don't detach, the range may be used later
+					//				for(var i=0;i<this._ranges.length;i++){
+					//					this._ranges[i].detach();
+					//				}
+					this._ranges = [];
+					this.rangeCount = 0;
+				};
+				var _initCurrentRange = function(){
+					var r = window.document.selection.createRange();
+					var type = window.document.selection.type.toUpperCase();
+					if(type == "CONTROL"){
+						//TODO: multiple range selection(?)
+						return new W3CRange(ie.decomposeControlRange(r));
+					}else{
+						return new W3CRange(ie.decomposeTextRange(r));
+					}
+				};
+				this.getRangeAt = function(i){
+					return this._ranges[i];
+				};
+				this._getCurrentSelection = function(){
+					this.removeAllRanges();
+					var r = _initCurrentRange();
+					if(r){
+						this.addRange(r, true);
+						this.isCollapsed = r.collapsed;
+					}else{
+						this.isCollapsed = true;
+					}
+				};
+			},
+			decomposeControlRange: function(range){
+				var firstnode = range.item(0), lastnode = range.item(range.length - 1);
+				var startContainer = firstnode.parentNode, endContainer = lastnode.parentNode;
+				var startOffset = rangeapi.getIndex(firstnode, startContainer).o[0];
+				var endOffset = rangeapi.getIndex(lastnode, endContainer).o[0] + 1;
+				return [startContainer, startOffset,endContainer, endOffset];
+			},
+			getEndPoint: function(range, end){
+				var atmrange = range.duplicate();
+				atmrange.collapse(!end);
+				var cmpstr = 'EndTo' + (end ? 'End' : 'Start');
+				var parentNode = atmrange.parentElement();
+
+				var startnode, startOffset, lastNode;
+				if(parentNode.childNodes.length > 0){
+					array.every(parentNode.childNodes, function(node, i){
+						var calOffset;
+						if(node.nodeType != 3){
+							atmrange.moveToElementText(node);
+
+							if(atmrange.compareEndPoints(cmpstr, range) > 0){
+								//startnode = node.previousSibling;
+								if(lastNode && lastNode.nodeType == 3){
+									//where shall we put the start? in the text node or after?
+									startnode = lastNode;
+									calOffset = true;
+								}else{
+									startnode = parentNode;
+									startOffset = i;
+									return false;
+								}
+							}else{
+								if(i == parentNode.childNodes.length - 1){
+									startnode = parentNode;
+									startOffset = parentNode.childNodes.length;
+									return false;
+								}
+							}
 						}else{
-							if(node.nextSibling && node.nextSibling.nodeType == 3){
-								container = node.nextSibling;
-								offset = 0;
-								//pass through
+							if(i == parentNode.childNodes.length - 1){//at the end of this node
+								startnode = node;
+								calOffset = true;
+							}
+						}
+						//			try{
+						if(calOffset && startnode){
+							var prevnode = rangeapi.adjacentNoneTextNode(startnode)[0];
+							if(prevnode){
+								startnode = prevnode.nextSibling;
 							}else{
-								atmrange.moveToElementText(node.nextSibling ? node : container);
-								var parent = node.parentNode;
-								var tempNode = parent.insertBefore(node.ownerDocument.createTextNode(' '), node.nextSibling);
+								startnode = parentNode.firstChild; //firstChild must be a text node
+							}
+							var prevnodeobj = rangeapi.adjacentNoneTextNode(startnode);
+							prevnode = prevnodeobj[0];
+							var lenoffset = prevnodeobj[1];
+							if(prevnode){
+								atmrange.moveToElementText(prevnode);
 								atmrange.collapse(false);
-								parent.removeChild(tempNode);
+							}else{
+								atmrange.moveToElementText(parentNode);
 							}
+							atmrange.setEndPoint(cmpstr, range);
+							startOffset = atmrange.text.length - lenoffset;
+
+							return false;
 						}
-					}
+						//			}catch(e){ debugger }
+						lastNode = node;
+						return true;
+					});
 				}else{
-					atmrange.moveToElementText(container);
-					atmrange.collapse(true);
+					startnode = parentNode;
+					startOffset = 0;
 				}
-			}
-			if(container.nodeType == 3){
-				var prevnodeobj = dijit.range.adjacentNoneTextNode(container);
-				var prevnode = prevnodeobj[0];
-				len = prevnodeobj[1];
-				if(prevnode){
-					atmrange.moveToElementText(prevnode);
-					atmrange.collapse(false);
-					//if contentEditable is not inherit, the above collapse won't make the end point
-					//in the correctly position: it always has a -1 offset, so compensate it
-					if(prevnode.contentEditable != 'inherit'){
-						len++;
+
+				//if at the end of startnode and we are dealing with start container, then
+				//move the startnode to nextSibling if it is a text node
+				//TODO: do this for end container?
+				if(!end && startnode.nodeType == 1 && startOffset == startnode.childNodes.length){
+					var nextnode = startnode.nextSibling;
+					if(nextnode && nextnode.nodeType == 3){
+						startnode = nextnode;
+						startOffset = 0;
+					}
+				}
+				return [startnode, startOffset];
+			},
+			setEndPoint: function(range, container, offset){
+				//text node
+				var atmrange = range.duplicate(), node, len;
+				if(container.nodeType != 3){ //normal node
+					if(offset > 0){
+						node = container.childNodes[offset - 1];
+						if(node){
+							if(node.nodeType == 3){
+								container = node;
+								offset = node.length;
+								//pass through
+							}else{
+								if(node.nextSibling && node.nextSibling.nodeType == 3){
+									container = node.nextSibling;
+									offset = 0;
+									//pass through
+								}else{
+									atmrange.moveToElementText(node.nextSibling ? node : container);
+									var parent = node.parentNode;
+									var tempNode = parent.insertBefore(node.ownerDocument.createTextNode(' '), node.nextSibling);
+									atmrange.collapse(false);
+									parent.removeChild(tempNode);
+								}
+							}
+						}
+					}else{
+						atmrange.moveToElementText(container);
+						atmrange.collapse(true);
+					}
+				}
+				if(container.nodeType == 3){
+					var prevnodeobj = rangeapi.adjacentNoneTextNode(container);
+					var prevnode = prevnodeobj[0];
+					len = prevnodeobj[1];
+					if(prevnode){
+						atmrange.moveToElementText(prevnode);
+						atmrange.collapse(false);
+						//if contentEditable is not inherit, the above collapse won't make the end point
+						//in the correctly position: it always has a -1 offset, so compensate it
+						if(prevnode.contentEditable != 'inherit'){
+							len++;
+						}
+					}else{
+						atmrange.moveToElementText(container.parentNode);
+						atmrange.collapse(true);
+
+						// Correct internal cursor position
+						// http://bugs.dojotoolkit.org/ticket/15578
+						atmrange.move('character', 1);
+						atmrange.move('character', -1);
+					}
+
+					offset += len;
+					if(offset > 0){
+						if(atmrange.move('character', offset) != offset){
+							console.error('Error when moving!');
+						}
 					}
-				}else{
-					atmrange.moveToElementText(container.parentNode);
-					atmrange.collapse(true);
 				}
 
-				offset += len;
-				if(offset > 0){
-					if(atmrange.move('character', offset) != offset){
-						console.error('Error when moving!');
+				return atmrange;
+			},
+			decomposeTextRange: function(range){
+				var tmpary = ie.getEndPoint(range);
+				var startContainer = tmpary[0], startOffset = tmpary[1];
+				var endContainer = tmpary[0], endOffset = tmpary[1];
+
+				if(range.htmlText.length){
+					if(range.htmlText == range.text){ //in the same text node
+						endOffset = startOffset + range.text.length;
+					}else{
+						tmpary = ie.getEndPoint(range, true);
+						endContainer = tmpary[0],endOffset = tmpary[1];
+						//					if(startContainer.tagName == "BODY"){
+						//						startContainer = startContainer.firstChild;
+						//					}
 					}
 				}
+				return [startContainer, startOffset, endContainer, endOffset];
+			},
+			setRange: function(range, startContainer, startOffset, endContainer, endOffset, collapsed){
+				var start = ie.setEndPoint(range, startContainer, startOffset);
+
+				range.setEndPoint('StartToStart', start);
+				if(!collapsed){
+					var end = ie.setEndPoint(range, endContainer, endOffset);
+				}
+				range.setEndPoint('EndToEnd', end || start);
+
+				return range;
 			}
+		};
 
-			return atmrange;
-		},
-		decomposeTextRange: function(range){
-			var tmpary = dijit.range.ie.getEndPoint(range);
-			var startContainer = tmpary[0], startOffset = tmpary[1];
-			var endContainer = tmpary[0], endOffset = tmpary[1];
-
-			if(range.htmlText.length){
-				if(range.htmlText == range.text){ //in the same text node
-					endOffset = startOffset + range.text.length;
+		var W3CRange = rangeapi.W3CRange = declare(null, {
+			constructor: function(){
+				if(arguments.length>0){
+					this.setStart(arguments[0][0],arguments[0][1]);
+					this.setEnd(arguments[0][2],arguments[0][3]);
 				}else{
-					tmpary = dijit.range.ie.getEndPoint(range, true);
-					endContainer = tmpary[0],endOffset = tmpary[1];
-//					if(startContainer.tagName == "BODY"){
-//						startContainer = startContainer.firstChild;
-//					}
+					this.commonAncestorContainer = null;
+					this.startContainer = null;
+					this.startOffset = 0;
+					this.endContainer = null;
+					this.endOffset = 0;
+					this.collapsed = true;
 				}
-			}
-			return [startContainer, startOffset, endContainer, endOffset];
-		},
-		setRange: function(range, startContainer, startOffset, endContainer, endOffset, collapsed){
-			var start = dijit.range.ie.setEndPoint(range, startContainer, startOffset);
-
-			range.setEndPoint('StartToStart', start);
-			if(!collapsed){
-				var end = dijit.range.ie.setEndPoint(range, endContainer, endOffset);
-			}
-			range.setEndPoint('EndToEnd', end || start);
+			},
+			_updateInternal: function(){
+				if(this.startContainer !== this.endContainer){
+					this.commonAncestorContainer = rangeapi.getCommonAncestor(this.startContainer, this.endContainer);
+				}else{
+					this.commonAncestorContainer = this.startContainer;
+				}
+				this.collapsed = (this.startContainer === this.endContainer) && (this.startOffset == this.endOffset);
+			},
+			setStart: function(node, offset){
+				offset=parseInt(offset);
+				if(this.startContainer === node && this.startOffset == offset){
+					return;
+				}
+				delete this._cachedBookmark;
 
-			return range;
-		}
-	};
+				this.startContainer = node;
+				this.startOffset = offset;
+				if(!this.endContainer){
+					this.setEnd(node, offset);
+				}else{
+					this._updateInternal();
+				}
+			},
+			setEnd: function(node, offset){
+				offset=parseInt(offset);
+				if(this.endContainer === node && this.endOffset == offset){
+					return;
+				}
+				delete this._cachedBookmark;
 
-declare("dijit.range.W3CRange",null, {
-	constructor: function(){
-		if(arguments.length>0){
-			this.setStart(arguments[0][0],arguments[0][1]);
-			this.setEnd(arguments[0][2],arguments[0][3]);
-		}else{
-			this.commonAncestorContainer = null;
-			this.startContainer = null;
-			this.startOffset = 0;
-			this.endContainer = null;
-			this.endOffset = 0;
-			this.collapsed = true;
-		}
-	},
-	_updateInternal: function(){
-		if(this.startContainer !== this.endContainer){
-			this.commonAncestorContainer = dijit.range.getCommonAncestor(this.startContainer, this.endContainer);
-		}else{
-			this.commonAncestorContainer = this.startContainer;
-		}
-		this.collapsed = (this.startContainer === this.endContainer) && (this.startOffset == this.endOffset);
-	},
-	setStart: function(node, offset){
-		offset=parseInt(offset);
-		if(this.startContainer === node && this.startOffset == offset){
-			return;
-		}
-		delete this._cachedBookmark;
-
-		this.startContainer = node;
-		this.startOffset = offset;
-		if(!this.endContainer){
-			this.setEnd(node, offset);
-		}else{
-			this._updateInternal();
-		}
-	},
-	setEnd: function(node, offset){
-		offset=parseInt(offset);
-		if(this.endContainer === node && this.endOffset == offset){
-			return;
-		}
-		delete this._cachedBookmark;
-
-		this.endContainer = node;
-		this.endOffset = offset;
-		if(!this.startContainer){
-			this.setStart(node, offset);
-		}else{
-			this._updateInternal();
-		}
-	},
-	setStartAfter: function(node, offset){
-		this._setPoint('setStart', node, offset, 1);
-	},
-	setStartBefore: function(node, offset){
-		this._setPoint('setStart', node, offset, 0);
-	},
-	setEndAfter: function(node, offset){
-		this._setPoint('setEnd', node, offset, 1);
-	},
-	setEndBefore: function(node, offset){
-		this._setPoint('setEnd', node, offset, 0);
-	},
-	_setPoint: function(what, node, offset, ext){
-		var index = dijit.range.getIndex(node, node.parentNode).o;
-		this[what](node.parentNode, index.pop()+ext);
-	},
-	_getIERange: function(){
-		var r = (this._body || this.endContainer.ownerDocument.body).createTextRange();
-		dijit.range.ie.setRange(r, this.startContainer, this.startOffset, this.endContainer, this.endOffset, this.collapsed);
-		return r;
-	},
-	getBookmark: function(){
-		this._getIERange();
-		return this._cachedBookmark;
-	},
-	_select: function(){
-		var r = this._getIERange();
-		r.select();
-	},
-	deleteContents: function(){
-		var s = this.startContainer, r = this._getIERange();
-		if(s.nodeType === 3 && !this.startOffset){
-			//if the range starts at the beginning of a
-			//text node, move it to before the textnode
-			//to make sure the range is still valid
-			//after deleteContents() finishes
-			this.setStartBefore(s);
-		}
-		r.pasteHTML('');
-		this.endContainer = this.startContainer;
-		this.endOffset = this.startOffset;
-		this.collapsed = true;
-	},
-	cloneRange: function(){
-		var r = new dijit.range.W3CRange([this.startContainer,this.startOffset,
-			this.endContainer,this.endOffset]);
-		r._body = this._body;
-		return r;
-	},
-	detach: function(){
-		this._body = null;
-		this.commonAncestorContainer = null;
-		this.startContainer = null;
-		this.startOffset = 0;
-		this.endContainer = null;
-		this.endOffset = 0;
-		this.collapsed = true;
-}
-});
-} //if(!dijit.range._w3c)
+				this.endContainer = node;
+				this.endOffset = offset;
+				if(!this.startContainer){
+					this.setStart(node, offset);
+				}else{
+					this._updateInternal();
+				}
+			},
+			setStartAfter: function(node, offset){
+				this._setPoint('setStart', node, offset, 1);
+			},
+			setStartBefore: function(node, offset){
+				this._setPoint('setStart', node, offset, 0);
+			},
+			setEndAfter: function(node, offset){
+				this._setPoint('setEnd', node, offset, 1);
+			},
+			setEndBefore: function(node, offset){
+				this._setPoint('setEnd', node, offset, 0);
+			},
+			_setPoint: function(what, node, offset, ext){
+				var index = rangeapi.getIndex(node, node.parentNode).o;
+				this[what](node.parentNode, index.pop()+ext);
+			},
+			_getIERange: function(){
+				var r = (this._body || this.endContainer.ownerDocument.body).createTextRange();
+				ie.setRange(r, this.startContainer, this.startOffset, this.endContainer, this.endOffset, this.collapsed);
+				return r;
+			},
+			getBookmark: function(){
+				this._getIERange();
+				return this._cachedBookmark;
+			},
+			_select: function(){
+				var r = this._getIERange();
+				r.select();
+			},
+			deleteContents: function(){
+				var s = this.startContainer, r = this._getIERange();
+				if(s.nodeType === 3 && !this.startOffset){
+					//if the range starts at the beginning of a
+					//text node, move it to before the textnode
+					//to make sure the range is still valid
+					//after deleteContents() finishes
+					this.setStartBefore(s);
+				}
+				r.pasteHTML('');
+				this.endContainer = this.startContainer;
+				this.endOffset = this.startOffset;
+				this.collapsed = true;
+			},
+			cloneRange: function(){
+				var r = new W3CRange([this.startContainer,this.startOffset,
+					this.endContainer,this.endOffset]);
+				r._body = this._body;
+				return r;
+			},
+			detach: function(){
+				this._body = null;
+				this.commonAncestorContainer = null;
+				this.startContainer = null;
+				this.startOffset = 0;
+				this.endContainer = null;
+				this.endOffset = 0;
+				this.collapsed = true;
+			}
+		});
+	} //if(!window.getSelection)
 
+	// remove for 2.0
+	lang.setObject("dijit.range", rangeapi);
 
-return dijit.range;
+	return rangeapi;
 });
diff --git a/dijit/_editor/selection.js b/dijit/_editor/selection.js
index 822aa87..982e455 100644
--- a/dijit/_editor/selection.js
+++ b/dijit/_editor/selection.js
@@ -1,31 +1,23 @@
 define([
 	"dojo/dom", // dom.byId
 	"dojo/_base/lang",
-	"dojo/_base/sniff", // has("ie") has("opera")
+	"dojo/sniff", // has("ie") has("opera")
 	"dojo/_base/window", // win.body win.doc win.doc.createElement win.doc.selection win.doc.selection.createRange win.doc.selection.type.toLowerCase win.global win.global.getSelection
-	".."		// for exporting symbols to dijit._editor.selection (TODO: remove in 2.0)
+	"../main"		// for exporting symbols to dijit._editor.selection
 ], function(dom, lang, has, win, dijit){
 
 // module:
 //		dijit/_editor/selection
-// summary:
-//		Text selection API
 
+var selection = {
+	// summary:
+	//		Deprecated text selection API.  Will be removed in 2.0.  New code should use dijit/selection.
 
-lang.getObject("_editor.selection", true, dijit);
-
-// FIXME:
-//		all of these methods branch internally for IE. This is probably
-//		sub-optimal in terms of runtime performance. We should investigate the
-//		size difference for differentiating at definition time.
-
-lang.mixin(dijit._editor.selection, {
 	getType: function(){
 		// summary:
 		//		Get the selection type (like win.doc.select.type in IE).
-		if(has("ie") < 9){
-			return win.doc.selection.type.toLowerCase();
-		}else{
+		if(win.doc.getSelection){
+			// W3C path
 			var stype = "text";
 
 			// Check if the actual selection is a CONTROL (IMG, TABLE, HR, etc...).
@@ -44,35 +36,33 @@ lang.mixin(dijit._editor.selection, {
 				}
 			}
 			return stype; //String
+		}else{
+			// IE6-8
+			return win.doc.selection.type.toLowerCase();
 		}
 	},
 
 	getSelectedText: function(){
 		// summary:
 		//		Return the text (no html tags) included in the current selection or null if no text is selected
-		if(has("ie") < 9){
+		if(win.doc.getSelection){
+			// W3C path
+			var selection = win.global.getSelection();
+			return selection ? selection.toString() : ""; //String
+		}else{
+			// IE6-8
 			if(dijit._editor.selection.getType() == 'control'){
 				return null;
 			}
 			return win.doc.selection.createRange().text;
-		}else{
-			var selection = win.global.getSelection();
-			if(selection){
-				return selection.toString(); //String
-			}
 		}
-		return '';
 	},
 
 	getSelectedHtml: function(){
 		// summary:
 		//		Return the html text of the current selection or null if unavailable
-		if(has("ie") < 9){
-			if(dijit._editor.selection.getType() == 'control'){
-				return null;
-			}
-			return win.doc.selection.createRange().htmlText;
-		}else{
+		if(win.doc.getSelection){
+			// W3C path
 			var selection = win.global.getSelection();
 			if(selection && selection.rangeCount){
 				var i;
@@ -87,6 +77,12 @@ lang.mixin(dijit._editor.selection, {
 				return html; //String
 			}
 			return null;
+		}else{
+			// IE6-8
+			if(dijit._editor.selection.getType() == 'control'){
+				return null;
+			}
+			return win.doc.selection.createRange().htmlText;
 		}
 	},
 
@@ -96,14 +92,16 @@ lang.mixin(dijit._editor.selection, {
 		//		a single element (object like and image or a table) is
 		//		selected.
 		if(dijit._editor.selection.getType() == "control"){
-			if(has("ie") < 9){
+			if(win.doc.getSelection){
+				// W3C path
+				var selection = win.global.getSelection();
+				return selection.anchorNode.childNodes[ selection.anchorOffset ];
+			}else{
+				// IE6-8
 				var range = win.doc.selection.createRange();
 				if(range && range.item){
 					return win.doc.selection.createRange().item(0);
 				}
-			}else{
-				var selection = win.global.getSelection();
-				return selection.anchorNode.childNodes[ selection.anchorOffset ];
 			}
 		}
 		return null;
@@ -116,11 +114,7 @@ lang.mixin(dijit._editor.selection, {
 			var p = this.getSelectedElement();
 			if(p){ return p.parentNode; }
 		}else{
-			if(has("ie") < 9){
-				var r = win.doc.selection.createRange();
-				r.collapse(true);
-				return r.parentElement();
-			}else{
+			if(win.doc.getSelection){
 				var selection = win.global.getSelection();
 				if(selection){
 					var node = selection.anchorNode;
@@ -129,21 +123,25 @@ lang.mixin(dijit._editor.selection, {
 					}
 					return node;
 				}
+			}else{
+				var r = win.doc.selection.createRange();
+				r.collapse(true);
+				return r.parentElement();
 			}
 		}
 		return null;
 	},
 
-	hasAncestorElement: function(/*String*/tagName /* ... */){
+	hasAncestorElement: function(/*String*/ tagName /* ... */){
 		// summary:
-		// 		Check whether current selection has a  parent element which is
-		// 		of type tagName (or one of the other specified tagName)
+		//		Check whether current selection has a  parent element which is
+		//		of type tagName (or one of the other specified tagName)
 		// tagName: String
 		//		The tag name to determine if it has an ancestor of.
 		return this.getAncestorElement.apply(this, arguments) != null; //Boolean
 	},
 
-	getAncestorElement: function(/*String*/tagName /* ... */){
+	getAncestorElement: function(/*String*/ tagName /* ... */){
 		// summary:
 		//		Return the parent element of the current selection which is of
 		//		type tagName (or one of the other specified tagName)
@@ -188,12 +186,13 @@ lang.mixin(dijit._editor.selection, {
 		return null;
 	},
 
-	collapse: function(/*Boolean*/beginning){
+	collapse: function(/*Boolean*/ beginning){
 		// summary:
 		//		Function to collapse (clear), the current selection
 		// beginning: Boolean
-		//		Boolean to indicate whether to collapse the cursor to the beginning of the selection or end.
-		if(window.getSelection){
+		//		Indicates whether to collapse the cursor to the beginning of the selection or end.
+		if(win.doc.getSelection){
+			// W3C path
 			var selection = win.global.getSelection();
 			if(selection.removeAllRanges){ // Mozilla
 				if(beginning){
@@ -205,7 +204,8 @@ lang.mixin(dijit._editor.selection, {
 				// pulled from WebCore/ecma/kjs_window.cpp, line 2536
 				selection.collapse(beginning);
 			}
-		}else if(has("ie")){ // IE
+		}else{
+			// IE6-8
 			var range = win.doc.selection.createRange();
 			range.collapse(beginning);
 			range.select();
@@ -216,39 +216,33 @@ lang.mixin(dijit._editor.selection, {
 		// summary:
 		//		Function to delete the currently selected content from the document.
 		var sel = win.doc.selection;
-		if(has("ie") < 9){
+		if(win.doc.getSelection){
+			// W3C path
+			sel = win.global.getSelection();
+			sel.deleteFromDocument();
+			return sel; //Selection
+		}else{
+			// IE6-8
 			if(sel.type.toLowerCase() != "none"){
 				sel.clear();
 			}
 			return sel; //Selection
-		}else{
-			sel = win.global.getSelection();
-			sel.deleteFromDocument();
-			return sel; //Selection
 		}
 	},
 
-	selectElementChildren: function(/*DomNode*/element,/*Boolean?*/nochangefocus){
+	selectElementChildren: function(/*DomNode*/ element, /*Boolean?*/ nochangefocus){
 		// summary:
 		//		clear previous selection and select the content of the node
 		//		(excluding the node itself)
 		// element: DOMNode
 		//		The element you wish to select the children content of.
 		// nochangefocus: Boolean
-		//		Boolean to indicate if the foxus should change or not.
-		var global = win.global;
+		//		Indicates if the focus should change or not.
 		var doc = win.doc;
 		var range;
 		element = dom.byId(element);
-		if(doc.selection && has("ie") < 9 && win.body().createTextRange){ // IE
-			range = element.ownerDocument.body.createTextRange();
-			range.moveToElementText(element);
-			if(!nochangefocus){
-				try{
-					range.select(); // IE throws an exception here if the widget is hidden.  See #5439
-				}catch(e){ /* squelch */}
-			}
-		}else if(global.getSelection){
+		if(win.doc.getSelection){
+			// W3C
 			var selection = win.global.getSelection();
 			if(has("opera")){
 				//Opera's selectAllChildren doesn't seem to work right
@@ -260,41 +254,36 @@ lang.mixin(dijit._editor.selection, {
 					range = doc.createRange();
 				}
 				range.setStart(element, 0);
-				range.setEnd(element,(element.nodeType == 3)?element.length:element.childNodes.length);
+				range.setEnd(element,(element.nodeType == 3) ? element.length : element.childNodes.length);
 				selection.addRange(range);
 			}else{
 				selection.selectAllChildren(element);
 			}
+		}else{
+			// IE6-8
+			range = element.ownerDocument.body.createTextRange();
+			range.moveToElementText(element);
+			if(!nochangefocus){
+				try{
+					range.select(); // IE throws an exception here if the widget is hidden.  See #5439
+				}catch(e){ /* squelch */}
+			}
 		}
 	},
 
-	selectElement: function(/*DomNode*/element,/*Boolean?*/nochangefocus){
+	selectElement: function(/*DomNode*/ element, /*Boolean?*/ nochangefocus){
 		// summary:
 		//		clear previous selection and select element (including all its children)
-		// element:  DOMNode
+		// element: DOMNode
 		//		The element to select.
 		// nochangefocus: Boolean
 		//		Boolean indicating if the focus should be changed.  IE only.
 		var range;
-		var doc = win.doc;
-		var global = win.global;
-		element = dom.byId(element);
-		if(has("ie") < 9 && win.body().createTextRange){
-			try{
-				var tg = element.tagName ? element.tagName.toLowerCase() : "";
-				if(tg === "img" || tg === "table"){
-					range = win.body().createControlRange();
-				}else{
-					range = win.body().createRange();
-				}
-				range.addElement(element);
-				if(!nochangefocus){
-					range.select();
-				}
-			}catch(e){
-				this.selectElementChildren(element,nochangefocus);
-			}
-		}else if(global.getSelection){
+		element = dom.byId(element);	// TODO: remove for 2.0 or sooner, spec listed above doesn't allow for string
+		var doc = element.ownerDocument;
+		var global = win.global;	// TODO: use winUtils.get(doc)?
+		if(doc.getSelection){
+			// W3C path
 			var selection = global.getSelection();
 			range = doc.createRange();
 			if(selection.removeAllRanges){ // Mozilla
@@ -310,6 +299,22 @@ lang.mixin(dijit._editor.selection, {
 				selection.removeAllRanges();
 				selection.addRange(range);
 			}
+		}else{
+			// IE6-8
+			try{
+				var tg = element.tagName ? element.tagName.toLowerCase() : "";
+				if(tg === "img" || tg === "table"){
+					range = win.body(doc).createControlRange();
+				}else{
+					range = win.body(doc).createRange();
+				}
+				range.addElement(element);
+				if(!nochangefocus){
+					range.select();
+				}
+			}catch(e){
+				this.selectElementChildren(element, nochangefocus);
+			}
 		}
 	},
 
@@ -324,8 +329,8 @@ lang.mixin(dijit._editor.selection, {
 			var doc = win.doc;
 			var range;
 
-			if(win.global.getSelection){
-				//WC3
+			if(win.doc.getSelection){
+				// WC3
 				var sel = win.global.getSelection();
 				if(sel && sel.rangeCount > 0){
 					range = sel.getRangeAt(0);
@@ -339,9 +344,9 @@ lang.mixin(dijit._editor.selection, {
 						}
 					}catch(e){ /* squelch */}
 				}
-			}else if(doc.selection){
-				// Probably IE, so we can't use the range object as the pseudo
-				// range doesn't implement the boundry checking, we have to
+			}else{
+				// IE6-8, so we can't use the range object as the pseudo
+				// range doesn't implement the boundary checking, we have to
 				// use IE specific crud.
 				range = doc.selection.createRange();
 				try{
@@ -363,10 +368,12 @@ lang.mixin(dijit._editor.selection, {
 				}
 			}
 		}
-		return false; // boolean
+		return false; // Boolean
 	}
+};
 
-});
 
-return dijit._editor.selection;
+lang.setObject("dijit._editor.selection", selection);
+
+return selection;
 });
diff --git a/dijit/_tree/dndSource.js b/dijit/_tree/dndSource.js
index 28db300..e4db351 100644
--- a/dijit/_tree/dndSource.js
+++ b/dijit/_tree/dndSource.js
@@ -1,12 +1,17 @@
 define([
 	"dojo/_base/kernel", // kernel.deprecated
-	"dojo/_base/lang", // lang.getObject
+	"dojo/_base/lang", // lang.setObject
 	"../tree/dndSource"
 ], function(kernel, lang, dndSource){
 	// module:
 	//		dijit/_tree/dndSource
-	// summary:
-	//		Deprecated module, use dijit.tree.dndSource instead
+
+	/*=====
+	return {
+		// summary:
+		//		Deprecated module, use dijit/tree/dndSource instead.
+	};
+	=====*/
 
 	// TODO: remove this file in 2.0
 	kernel.deprecated("dijit._tree.dndSource has been moved to dijit.tree.dndSource, use that instead", "", "2.0");
diff --git a/dijit/a11y.js b/dijit/a11y.js
index d616335..a54308a 100644
--- a/dijit/a11y.js
+++ b/dijit/a11y.js
@@ -1,177 +1,176 @@
 define([
 	"dojo/_base/array", // array.forEach array.map
-	"dojo/_base/config", // defaultDuration
-	"dojo/_base/declare", // declare
 	"dojo/dom",			// dom.byId
 	"dojo/dom-attr", // domAttr.attr domAttr.has
-	"dojo/dom-style", // style.style
-	"dojo/_base/sniff", // has("ie")
-	"./_base/manager",	// manager._isElementShown
-	"."	// for exporting methods to dijit namespace
-], function(array, config, declare, dom, domAttr, domStyle, has, manager, dijit){
+	"dojo/dom-style", // domStyle.style
+	"dojo/_base/lang", // lang.mixin()
+	"dojo/sniff", // has("ie") has("extend-dojo")
+	"./main"	// for exporting methods to dijit namespace
+], function(array, dom, domAttr, domStyle, lang, has, dijit){
 
 	// module:
 	//		dijit/a11y
-	// summary:
-	//		Accessibility utility functions (keyboard, tab stops, etc.)
-
-	var shown = (dijit._isElementShown = function(/*Element*/ elem){
-		var s = domStyle.get(elem);
-		return (s.visibility != "hidden")
-			&& (s.visibility != "collapsed")
-			&& (s.display != "none")
-			&& (domAttr.get(elem, "type") != "hidden");
-	});
-
-	dijit.hasDefaultTabStop = function(/*Element*/ elem){
+
+	var a11y = {
 		// summary:
-		//		Tests if element is tab-navigable even without an explicit tabIndex setting
-
-		// No explicit tabIndex setting, need to investigate node type
-		switch(elem.nodeName.toLowerCase()){
-			case "a":
-				// An <a> w/out a tabindex is only navigable if it has an href
-				return domAttr.has(elem, "href");
-			case "area":
-			case "button":
-			case "input":
-			case "object":
-			case "select":
-			case "textarea":
-				// These are navigable by default
-				return true;
-			case "iframe":
-				// If it's an editor <iframe> then it's tab navigable.
-				var body;
-				try{
-					// non-IE
-					var contentDocument = elem.contentDocument;
-					if("designMode" in contentDocument && contentDocument.designMode == "on"){
-						return true;
-					}
-					body = contentDocument.body;
-				}catch(e1){
-					// contentWindow.document isn't accessible within IE7/8
-					// if the iframe.src points to a foreign url and this
-					// page contains an element, that could get focus
+		//		Accessibility utility functions (keyboard, tab stops, etc.)
+
+		_isElementShown: function(/*Element*/ elem){
+			var s = domStyle.get(elem);
+			return (s.visibility != "hidden")
+				&& (s.visibility != "collapsed")
+				&& (s.display != "none")
+				&& (domAttr.get(elem, "type") != "hidden");
+		},
+
+		hasDefaultTabStop: function(/*Element*/ elem){
+			// summary:
+			//		Tests if element is tab-navigable even without an explicit tabIndex setting
+
+			// No explicit tabIndex setting, need to investigate node type
+			switch(elem.nodeName.toLowerCase()){
+				case "a":
+					// An <a> w/out a tabindex is only navigable if it has an href
+					return domAttr.has(elem, "href");
+				case "area":
+				case "button":
+				case "input":
+				case "object":
+				case "select":
+				case "textarea":
+					// These are navigable by default
+					return true;
+				case "iframe":
+					// If it's an editor <iframe> then it's tab navigable.
+					var body;
 					try{
-						body = elem.contentWindow.document.body;
-					}catch(e2){
-						return false;
+						// non-IE
+						var contentDocument = elem.contentDocument;
+						if("designMode" in contentDocument && contentDocument.designMode == "on"){
+							return true;
+						}
+						body = contentDocument.body;
+					}catch(e1){
+						// contentWindow.document isn't accessible within IE7/8
+						// if the iframe.src points to a foreign url and this
+						// page contains an element, that could get focus
+						try{
+							body = elem.contentWindow.document.body;
+						}catch(e2){
+							return false;
+						}
 					}
-				}
-				return body && (body.contentEditable == 'true' ||
-					(body.firstChild && body.firstChild.contentEditable == 'true'));
-			default:
-				return elem.contentEditable == 'true';
-		}
-	};
+					return body && (body.contentEditable == 'true' ||
+						(body.firstChild && body.firstChild.contentEditable == 'true'));
+				default:
+					return elem.contentEditable == 'true';
+			}
+		},
 
-	var isTabNavigable = (dijit.isTabNavigable = function(/*Element*/ elem){
-		// summary:
-		//		Tests if an element is tab-navigable
-
-		// TODO: convert (and rename method) to return effective tabIndex; will save time in _getTabNavigable()
-		if(domAttr.get(elem, "disabled")){
-			return false;
-		}else if(domAttr.has(elem, "tabIndex")){
-			// Explicit tab index setting
-			return domAttr.get(elem, "tabIndex") >= 0; // boolean
-		}else{
-			// No explicit tabIndex setting, so depends on node type
-			return dijit.hasDefaultTabStop(elem);
-		}
-	});
+		isTabNavigable: function(/*Element*/ elem){
+			// summary:
+			//		Tests if an element is tab-navigable
 
-	dijit._getTabNavigable = function(/*DOMNode*/ root){
-		// summary:
-		//		Finds descendants of the specified root node.
-		//
-		// description:
-		//		Finds the following descendants of the specified root node:
-		//		* the first tab-navigable element in document order
-		//		  without a tabIndex or with tabIndex="0"
-		//		* the last tab-navigable element in document order
-		//		  without a tabIndex or with tabIndex="0"
-		//		* the first element in document order with the lowest
-		//		  positive tabIndex value
-		//		* the last element in document order with the highest
-		//		  positive tabIndex value
-		var first, last, lowest, lowestTabindex, highest, highestTabindex, radioSelected = {};
-
-		function radioName(node){
-			// If this element is part of a radio button group, return the name for that group.
-			return node && node.tagName.toLowerCase() == "input" &&
-				node.type && node.type.toLowerCase() == "radio" &&
-				node.name && node.name.toLowerCase();
-		}
+			// TODO: convert (and rename method) to return effective tabIndex; will save time in _getTabNavigable()
+			if(domAttr.get(elem, "disabled")){
+				return false;
+			}else if(domAttr.has(elem, "tabIndex")){
+				// Explicit tab index setting
+				return domAttr.get(elem, "tabIndex") >= 0; // boolean
+			}else{
+				// No explicit tabIndex setting, so depends on node type
+				return a11y.hasDefaultTabStop(elem);
+			}
+		},
 
-		var walkTree = function(/*DOMNode*/parent){
-			for(var child = parent.firstChild; child; child = child.nextSibling){
-				// Skip text elements, hidden elements, and also non-HTML elements (those in custom namespaces) in IE,
-				// since show() invokes getAttribute("type"), which crash on VML nodes in IE.
-				if(child.nodeType != 1 || (has("ie") && child.scopeName !== "HTML") || !shown(child)){
-					continue;
-				}
+		_getTabNavigable: function(/*DOMNode*/ root){
+			// summary:
+			//		Finds descendants of the specified root node.
+			// description:
+			//		Finds the following descendants of the specified root node:
+			//
+			//		- the first tab-navigable element in document order
+			//		  without a tabIndex or with tabIndex="0"
+			//		- the last tab-navigable element in document order
+			//		  without a tabIndex or with tabIndex="0"
+			//		- the first element in document order with the lowest
+			//		  positive tabIndex value
+			//		- the last element in document order with the highest
+			//		  positive tabIndex value
+			var first, last, lowest, lowestTabindex, highest, highestTabindex, radioSelected = {};
 
-				if(isTabNavigable(child)){
-					var tabindex = domAttr.get(child, "tabIndex");
-					if(!domAttr.has(child, "tabIndex") || tabindex == 0){
-						if(!first){
-							first = child;
-						}
-						last = child;
-					}else if(tabindex > 0){
-						if(!lowest || tabindex < lowestTabindex){
-							lowestTabindex = tabindex;
-							lowest = child;
+			function radioName(node){
+				// If this element is part of a radio button group, return the name for that group.
+				return node && node.tagName.toLowerCase() == "input" &&
+					node.type && node.type.toLowerCase() == "radio" &&
+					node.name && node.name.toLowerCase();
+			}
+
+			var shown = a11y._isElementShown, isTabNavigable = a11y.isTabNavigable;
+			var walkTree = function(/*DOMNode*/ parent){
+				for(var child = parent.firstChild; child; child = child.nextSibling){
+					// Skip text elements, hidden elements, and also non-HTML elements (those in custom namespaces) in IE,
+					// since show() invokes getAttribute("type"), which crash on VML nodes in IE.
+					if(child.nodeType != 1 || (has("ie") <= 9 && child.scopeName !== "HTML") || !shown(child)){
+						continue;
+					}
+
+					if(isTabNavigable(child)){
+						var tabindex = +domAttr.get(child, "tabIndex");	// + to convert string --> number
+						if(!domAttr.has(child, "tabIndex") || tabindex == 0){
+							if(!first){
+								first = child;
+							}
+							last = child;
+						}else if(tabindex > 0){
+							if(!lowest || tabindex < lowestTabindex){
+								lowestTabindex = tabindex;
+								lowest = child;
+							}
+							if(!highest || tabindex >= highestTabindex){
+								highestTabindex = tabindex;
+								highest = child;
+							}
 						}
-						if(!highest || tabindex >= highestTabindex){
-							highestTabindex = tabindex;
-							highest = child;
+						var rn = radioName(child);
+						if(domAttr.get(child, "checked") && rn){
+							radioSelected[rn] = child;
 						}
 					}
-					var rn = radioName(child);
-					if(domAttr.get(child, "checked") && rn){
-						radioSelected[rn] = child;
+					if(child.nodeName.toUpperCase() != 'SELECT'){
+						walkTree(child);
 					}
 				}
-				if(child.nodeName.toUpperCase() != 'SELECT'){
-					walkTree(child);
-				}
+			};
+			if(shown(root)){
+				walkTree(root);
+			}
+			function rs(node){
+				// substitute checked radio button for unchecked one, if there is a checked one with the same name.
+				return radioSelected[radioName(node)] || node;
 			}
-		};
-		if(shown(root)){
-			walkTree(root);
-		}
-		function rs(node){
-			// substitute checked radio button for unchecked one, if there is a checked one with the same name.
-			return radioSelected[radioName(node)] || node;
-		}
 
-		return { first: rs(first), last: rs(last), lowest: rs(lowest), highest: rs(highest) };
-	};
-	dijit.getFirstInTabbingOrder = function(/*String|DOMNode*/ root){
-		// summary:
-		//		Finds the descendant of the specified root node
-		//		that is first in the tabbing order
-		var elems = dijit._getTabNavigable(dom.byId(root));
-		return elems.lowest ? elems.lowest : elems.first; // DomNode
-	};
+			return { first: rs(first), last: rs(last), lowest: rs(lowest), highest: rs(highest) };
+		},
 
-	dijit.getLastInTabbingOrder = function(/*String|DOMNode*/ root){
-		// summary:
-		//		Finds the descendant of the specified root node
-		//		that is last in the tabbing order
-		var elems = dijit._getTabNavigable(dom.byId(root));
-		return elems.last ? elems.last : elems.highest; // DomNode
-	};
+		getFirstInTabbingOrder: function(/*String|DOMNode*/ root, /*Document?*/ doc){
+			// summary:
+			//		Finds the descendant of the specified root node
+			//		that is first in the tabbing order
+			var elems = a11y._getTabNavigable(dom.byId(root, doc));
+			return elems.lowest ? elems.lowest : elems.first; // DomNode
+		},
 
-	return {
-		hasDefaultTabStop: dijit.hasDefaultTabStop,
-		isTabNavigable: dijit.isTabNavigable,
-		_getTabNavigable: dijit._getTabNavigable,
-		getFirstInTabbingOrder: dijit.getFirstInTabbingOrder,
-		getLastInTabbingOrder: dijit.getLastInTabbingOrder
+		getLastInTabbingOrder: function(/*String|DOMNode*/ root, /*Document?*/ doc){
+			// summary:
+			//		Finds the descendant of the specified root node
+			//		that is last in the tabbing order
+			var elems = a11y._getTabNavigable(dom.byId(root, doc));
+			return elems.last ? elems.last : elems.highest; // DomNode
+		}
 	};
+
+	has("extend-dojo") && lang.mixin(dijit, a11y);
+
+	return a11y;
 });
diff --git a/dijit/a11yclick.js b/dijit/a11yclick.js
new file mode 100644
index 0000000..f4da56e
--- /dev/null
+++ b/dijit/a11yclick.js
@@ -0,0 +1,138 @@
+define([
+	"dojo/keys", // keys.ENTER keys.SPACE
+	"dojo/mouse",
+	"dojo/on",
+	"dojo/touch" // touch support for click is now there
+], function(keys, mouse, on, touch){
+
+	// module:
+	//		dijit/a11yclick
+
+	/*=====
+	return {
+		// summary:
+		//		Custom press, release, and click synthetic events
+		//		which trigger on a left mouse click, touch, or space/enter keyup.
+
+		click: function(node, listener){
+			// summary:
+			//		Logical click operation for mouse, touch, or keyboard (space/enter key)
+		},
+		press: function(node, listener){
+			// summary:
+			//		Mousedown (left button), touchstart, or keydown (space or enter) corresponding to logical click operation.
+		},
+		release: function(node, listener){
+			// summary:
+			//		Mouseup (left button), touchend, or keyup (space or enter) corresponding to logical click operation.
+		},
+		move: function(node, listener){
+			// summary:
+			//		Mouse cursor or a finger is dragged over the given node.
+		}
+	};
+	=====*/
+
+	function clickKey(/*Event*/ e){
+		// Test if this keyboard event should be tracked as the start (if keydown) or end (if keyup) of a click event.
+		// Only track for nodes marked to be tracked, and not for buttons or inputs,
+		// since buttons handle keyboard click natively, and text inputs should not
+		// prevent typing spaces or newlines.
+		if((e.keyCode === keys.ENTER || e.keyCode === keys.SPACE) && !/input|button|textarea/i.test(e.target.nodeName)){
+
+			// Test if a node or its ancestor has been marked with the dojoClick property to indicate special processing
+			for(var node = e.target; node; node = node.parentNode){
+				if(node.dojoClick){ return true; }
+			}
+		}
+	}
+
+	var lastKeyDownNode;
+
+	on(document, "keydown", function(e){
+		//console.log("a11yclick: onkeydown, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode));
+		if(clickKey(e)){
+			// needed on IE for when focus changes between keydown and keyup - otherwise dropdown menus do not work
+			lastKeyDownNode = e.target;
+
+			// Prevent viewport scrolling on space key in IE<9.
+			// (Reproducible on test_Button.html on any of the first dijit/form/Button examples)
+			e.preventDefault();
+		}else{
+			lastKeyDownNode = null;
+		}
+	});
+
+	on(document, "keyup", function(e){
+		//console.log("a11yclick: onkeyup, e.target = ", e.target, ", lastKeyDownNode was ", lastKeyDownNode, ", equality is ", (e.target === lastKeyDownNode));
+		if(clickKey(e) && e.target == lastKeyDownNode){	// === breaks greasemonkey
+			//need reset here or have problems in FF when focus returns to trigger element after closing popup/alert
+			lastKeyDownNode = null;
+
+			on.emit(e.target, "click", {
+				cancelable: true,
+				bubbles: true,
+				ctrlKey: e.ctrlKey,
+				shiftKey: e.shiftKey,
+				metaKey: e.metaKey,
+				altKey: e.altKey,
+				_origType: e.type
+			});
+		}
+	});
+
+	// I want to return a hash of the synthetic events, but for backwards compatibility the main return value
+	// needs to be the click event.   Change for 2.0.
+
+	var click = function(node, listener){
+		// Set flag on node so that keydown/keyup above emits click event
+		node.dojoClick = true;
+
+		return on(node, "click", listener);
+	};
+	click.click = click;	// forward compatibility with 2.0
+
+	click.press =  function(node, listener){
+		var touchListener = on(node, touch.press, function(evt){
+			if(evt.type == "mousedown" && !mouse.isLeft(evt)){
+				// Ignore right click
+				return;
+			}
+			listener(evt);
+		}), keyListener = on(node, "keydown", function(evt){
+			if(evt.keyCode === keys.ENTER || evt.keyCode === keys.SPACE){
+				listener(evt);
+			}
+		});
+		return {
+			remove: function(){
+				touchListener.remove();
+				keyListener.remove();
+			}
+		};
+	};
+
+	click.release =  function(node, listener){
+		var touchListener = on(node, touch.release, function(evt){
+			if(evt.type == "mouseup" && !mouse.isLeft(evt)){
+				// Ignore right click
+				return;
+			}
+			listener(evt);
+		}), keyListener = on(node, "keyup", function(evt){
+			if(evt.keyCode === keys.ENTER || evt.keyCode === keys.SPACE){
+				listener(evt);
+			}
+		});
+		return {
+			remove: function(){
+				touchListener.remove();
+				keyListener.remove();
+			}
+		};
+	};
+
+	click.move = touch.move;	// just for convenience
+
+	return click;
+});
diff --git a/dijit/bench/benchReceive.php b/dijit/bench/benchReceive.php
new file mode 100644
index 0000000..50539c5
--- /dev/null
+++ b/dijit/bench/benchReceive.php
@@ -0,0 +1,129 @@
+<?php
+/*
+
+	benchReceive.php - example way to handle incoming benchmark data,
+	or how to use JSON php class to mangle data.  No benchmark data
+	is stored currently.
+
+--
+-- Table structure for table `benchmarks`
+--
+
+CREATE TABLE `benchmarks` (
+  `id` int(11) NOT NULL auto_increment,
+  `useragent` varchar(242) NOT NULL default '',
+  `dojover` varchar(96) NOT NULL default '',
+  `testNum` int(11) NOT NULL default '0',
+  `dijit` varchar(64) NOT NULL default '',
+  `testCount` int(11) NOT NULL default '0',
+  `testAverage` float NOT NULL default '0',
+  `testMethod` varchar(10) NOT NULL default '',
+  `testTime` bigint(20) NOT NULL default '0',
+  `dataSet` varchar(64) NOT NULL default '',
+  PRIMARY KEY  (`id`),
+  KEY `dijit` (`dijit`,`testAverage`),
+  KEY `dataSet` (`dataSet`)
+) TYPE=MyISAM;
+
+--
+-- [end table struct] --
+
+*/
+
+if(is_array($_POST)){
+
+	$username = '';
+	$password = '';
+	$dataBase = '';
+	$table    = '';
+
+	mysql_connect("localhost",$username,$password);
+	mysql_select_db($dataBase);
+
+	require("../../dojo/tests/resources/JSON.php");
+	$json = new Services_JSON();
+
+	// see "escape()" call in benchTest.html
+	$string = $json->decode(urldecode($_POST['key']));
+	// $string = $json->decode($_POST['key']);
+
+	print "<h1>Thank YOU!</h1>";
+	print "
+		<p>Your results have been added to our database. No
+		personal information outside of what you see here
+		has been stored.
+		</p>
+
+		<p>You can <a href= \"javascript:history.back()\">go back</a>
+		and run more tests, or even better, load up another browser
+		and the submit your tests again!
+		</p>
+
+		<p>again ... thanks for your time.</p>
+
+		";
+
+	print "<h3>Results Submitted:</h3>";
+	print "<pre style=\"font:6pt Terminal,sans-serif; border:1px solid #cecece; background-color:#ededed; padding:20px; \">";
+
+		$ua = $string->clientNavigator;
+		$dojov = $string->dojoVersion;
+
+		print "Client: ".$ua."\n";
+		print "Dojo v".$dojov."\n";
+
+		if(is_array($string->dataSet)){
+			print "\nTest Results:";
+			// should client serialize a key, or is this safer?
+			$dataSet = md5(serialize($string));
+			foreach ($string->dataSet as $test){
+				$data = array(
+					'dataSet' => $dataSet,
+					'useragent' => $ua,
+					'dojover' => $dojov,
+					'testNum' => $test->testNum,
+					'testMethod' => $test->testMethod,
+					'testTime' => $test->testTime,
+					'testAverage' => $test->testAverage,
+					'testCount' => $test->testCount,
+					'dijit' => $test->dijit
+				);
+				print_r($data);
+				add_rec($table,$data);
+			}
+		}
+
+		if(is_array($string->errors)){
+			// not saving errors at this point
+			print "\nErrors:";
+			foreach ($string->errors as $error){
+				print_r($error);
+			}
+		}
+	print "</pre>";
+}
+
+function add_rec($table, $data){
+
+	if(!is_array($data)){ return FALSE; }
+
+	$keys = array_keys($data);
+	$values = array_values($data);
+	$field=0;
+
+	for($field;$field<sizeof($data);$field++){
+		if(!ereg("^[0-9].*$",$keys[$field])){
+			$sqlfields = $sqlfields.$keys[$field]."=\"".$values[$field]."\", ";
+       		}
+	}
+	$sqlfields = (substr($sqlfields,0,(strlen($sqlfields)-2)));
+
+	if($query = mysql_query("insert into $table set $sqlfields")){
+		$id = mysql_insert_id();
+		return ($id);
+	}else{
+		return FALSE;
+	}
+}
+
+?>
diff --git a/dijit/bench/benchTool.html b/dijit/bench/benchTool.html
new file mode 100644
index 0000000..2ba8861
--- /dev/null
+++ b/dijit/bench/benchTool.html
@@ -0,0 +1,228 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>Dojo interactive benchmark tool</title>
+
+	<!-- make display better on mobile, so that results appear under the controls rather than to the right of them -->
+	<meta name="viewport" content="width=device-width, initial-scale=1.0"/> 
+
+	<style>
+		@import "../../dijit/themes/claro/claro.css";
+		@import "../themes/claro/document.css";
+		@import "../../dijit/tests/css/dijitTests.css";
+
+		#resultsContainer, #testControl, #submitControl {
+			margin: 20px;
+			padding:12px;
+			background-color:#fff;
+			-moz-border-radius:8pt 8pt;
+			-webkit-border-radius:7pt;
+			border:2px solid #ededed;
+		}
+
+		#resultsContainer {
+			padding-top: 0;
+		}
+
+		#results {  overflow:auto; min-height:100px; border:1px solid #ccc; color:darkred; padding:8px;  }
+
+		.runHolder, .submitButton {
+			border:1px solid #ccc; padding:3px;
+			-moz-border-radius:8pt 8pt;
+			-webkit-border-radius:7pt;
+			text-align:center;
+			cursor:pointer; background-color:#ededed; display:block; width:125px;
+		}
+
+	</style>
+
+
+	<script type="text/javascript" src="../../dojo/dojo.js"></script>
+	<script type="text/javascript">
+		// basic stats are located at http://dante.dojotoolkit.org/benchmarks/
+
+		dojo.require("dojo.fx");
+		dojo.require("dijit.dijit");
+		dojo.require("dijit.form.ComboBox");
+		dojo.require("dojo.parser");
+
+		// setup global variables
+		var masterResults = { clientNavigator: navigator.userAgent, dataSet: [], errors: [] };
+		var isRunning = false;
+		var theCount, theClass, runner = null;
+		var testCount = 0;
+
+		dojo.ready(function(){
+			theCount = dojo.byId('countNode');
+			runner = dojo.byId('runner');
+			masterResults.dojoVersion = dojo.version.toString();
+			
+			dojo.parser.parse();	// instantiate the ComboBox
+			theClass = dijit.byId('classNode');
+		});
+
+
+		function _toggleRunMsg(){
+			var newMsg = (isRunning) ? " Run Test " : " Running ...";
+			dojo.fx.chain([
+				dojo.fadeOut({
+					node:runner,
+					duration:200,
+					onEnd: function(){
+						runner.innerHTML = newMsg;
+						isRunning=!isRunning;
+					}
+				}),
+				dojo.fadeIn({ node:runner, duration: 200 })
+			]).play();
+		}
+
+		function runTest(){
+			if(isRunning){ return; }
+			_toggleRunMsg();
+			setTimeout(function(){ _runRealTest(); },1000);
+		}
+
+		function _runRealTest(){
+
+			// Remove widgets from previous run
+			dojo.forEach(dijit.findWidgets(dojo.byId("widgetsContainer")), function(widget){
+				widget.destroyRecursive();
+			});
+
+			var count = theCount.value,
+				aclass = theClass.get("value"),
+				theMethod = dojo.query("input[name=theMethod]").filter(function(node){ return node.checked; }).attr("value")[0],
+				tmpNode = document.createElement('div'),
+				startTimer;
+			try{
+				dojo.require(/dojox\.mobile\.[A-Z]/.test(aclass) ? "dojox.mobile._base" : aclass);
+				dojo.ready(function(){
+					var i;
+					switch(theMethod){
+						case "parse" :
+						case "fastparse" :
+							var tmpString = [];
+							var tag = /Button/.test(aclass) ? "button" : (/Text/.test(aclass) ? "input" : "div");
+							for(i=0; i<count; i++){
+								tmpString.push(
+								'<', tag, ' ',
+								 (theMethod == 'fastparse' ? 'data-dojo-type="' : 'dojoType="'),
+								aclass, '"></', tag, '>');
+							}
+							tmpNode.innerHTML = tmpString.join("");
+							startTimer = new Date().getTime();
+							dojo.parser.parse(tmpNode);
+							break;
+						case "create" :
+							var construction = dojo.getObject(aclass);
+							startTimer = new Date().getTime();
+							for(i=0; i<count; i++){
+								var tmp = new construction({});
+								tmpNode.appendChild(tmp.domNode);
+							}
+							break;
+					}
+
+					// Render the widgets in a visible <div> as part of benchmark
+					dojo.byId("widgetsContainer").appendChild(tmpNode);
+					
+					// [Some] browsers defer rendering until after JS finishes running
+					// so use a setTimeout(, 0) to make sure widgets render.
+					setTimeout(function(){
+						var endTime = new Date().getTime() - startTimer;
+	
+						var average = (endTime / count);
+						var msg = "It took: "+endTime+"ms to "+theMethod+" "+count+" "+aclass+" widgets"+
+							"<br>(average: "+average+" ms/widget)<br><br>";
+	
+						masterResults.dataSet.push({
+							testNum: ++testCount,
+							dijit: aclass,
+							testCount: count,
+							testAverage: average,
+							testMethod: theMethod,
+							testTime: endTime
+						});
+
+						dojo.byId("results").innerHTML += msg;
+						
+						dojo.byId("mailto").href = "mailto:?subject=test results&body=" +
+							encodeURIComponent(dojo.byId("results").innerText || dojo.byId("results").textContent);
+
+						setTimeout(function(){ _toggleRunMsg(); },250);
+					}, 0);
+
+				});
+			}catch(e){
+
+				setTimeout(function(){ _toggleRunMsg(); },250);
+				console.error("Ooops:", e);
+			}
+
+		}
+
+		function doDebug(){
+			dojo.byId('hiddenHolder').value = dojo.toJson(masterResults);
+			return true;
+		}
+
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">Dojo Benchmark Tool</h1>
+
+	<div id="testControl">
+
+		Class:
+			<select data-dojo-type="dijit/form/ComboBox"
+					data-dojo-props='name:"dijit", id:"classNode", value:"dijit.form.Button", style:{width:"200px"}'>
+				<option>dijit.form.Button</option>
+				<option>dojox.mobile.Button</option>
+				<option>dijit.form.TextBox</option>
+				<option>dojox.mobile.app.TextBox</option>
+			</select>
+		<br><br>
+		Count: <input type="text" name="count" id="countNode" value="100" size="4" ><br><br>
+
+		Method:
+			<br>
+			<label for="parse">
+				<input type="radio" name="theMethod" value="parse" id="parse" checked="on"> Parse with 1.x dojoType syntax
+			</label>
+			<br>
+			<label for="fastparse">
+				<input type="radio" name="theMethod" value="fastparse" id="fastparse"> Parse with 2.0 data-dojo-type syntax
+			</label>
+			<br>
+			<label for="create">
+				<input type="radio" name="theMethod" value="create" id="create"> Create programatically
+			</label>
+
+		<br><br>
+		<span onclick="runTest()" class="runHolder"><span id="runner"> Run Test </span></span>
+
+	</div>
+
+	<div id="resultsContainer"><h3>Results:</h3><div id="results"></div></div>
+
+	<div id="submitControl">
+		<p>
+		* The results of these tests are important to us.  Please feel free to submit your dataSet
+		to Dojotoolkit.org. Your privacy will be respected.
+		</p>
+		<div id="hiddenResults">
+			<form id="resultForm" action="http://dante.dojotoolkit.org/benchmarks/submit.php"
+				method="POST" onsubmit="doDebug()">
+				<input type="hidden" id="hiddenHolder" value="" name="key">
+				<input type="submit" value=" Submit Data " class="submitButton">
+			</form>
+		</div>
+		
+		<p>Alternately, <a id="mailto">mail results</a> to any email address.</p>
+	</div>
+
+	<div id="widgetsContainer" style="clear: both;"></div>
+</body>
+</html>
diff --git a/dijit/bench/button.html b/dijit/bench/button.html
new file mode 100644
index 0000000..a28f902
--- /dev/null
+++ b/dijit/bench/button.html
@@ -0,0 +1,184 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+
+<html>
+	<head>
+		<title>button test</title>
+
+		<style type="text/css">
+			@import "../themes/tundra/tundra.css";
+			th { background: #ccccff; }
+			td { align: left; }
+		</style>
+
+		<script type="text/javascript"> djConfig = { isDebug: true, parseOnLoad: true }; </script>
+		<script type="text/javascript" src="../../dojo/dojo.js"></script>
+		<script>
+			dojo.require("dojo.parser");
+			dojo.require("dijit.form.Button");
+		</script>
+
+		<script type="text/javascript">
+				oldTime = new Date();
+				dojo.ready(function(){
+					var time = new Date().getTime() - oldTime;
+					var p = document.createElement("p");
+					p.appendChild(document.createTextNode("Widgets loaded in " + time + "ms"));
+					document.getElementById("results").appendChild(p);
+				});
+
+		</script>
+	</head>
+
+	<body class="tundra">
+
+		<h1>Test of instantiating many buttons</h1>
+
+		<p>
+		<strong style="color:red">Warning:</strong> these benchmarks will take a number of seconds to run. Other system activity will cause these benchmarks to skew.
+		</p>
+
+		<p>
+		The results should not be compared between browsers for they are run on different systems,
+		however results for the same browser are relative to each other.
+		</p>
+
+		<button data-dojo-type="dijit/form/Button">hello world 0</button>
+		<button data-dojo-type="dijit/form/Button">hello world 1</button>
+		<button data-dojo-type="dijit/form/Button">hello world 2</button>
+		<button data-dojo-type="dijit/form/Button">hello world 3</button>
+		<button data-dojo-type="dijit/form/Button">hello world 4</button>
+		<button data-dojo-type="dijit/form/Button">hello world 5</button>
+		<button data-dojo-type="dijit/form/Button">hello world 6</button>
+		<button data-dojo-type="dijit/form/Button">hello world 7</button>
+		<button data-dojo-type="dijit/form/Button">hello world 8</button>
+		<button data-dojo-type="dijit/form/Button">hello world 9</button>
+
+		<button data-dojo-type="dijit/form/Button">hello world 10</button>
+		<button data-dojo-type="dijit/form/Button">hello world 11</button>
+		<button data-dojo-type="dijit/form/Button">hello world 12</button>
+		<button data-dojo-type="dijit/form/Button">hello world 13</button>
+		<button data-dojo-type="dijit/form/Button">hello world 14</button>
+		<button data-dojo-type="dijit/form/Button">hello world 15</button>
+		<button data-dojo-type="dijit/form/Button">hello world 16</button>
+		<button data-dojo-type="dijit/form/Button">hello world 17</button>
+		<button data-dojo-type="dijit/form/Button">hello world 18</button>
+		<button data-dojo-type="dijit/form/Button">hello world 19</button>
+
+		<button data-dojo-type="dijit/form/Button">hello world 20</button>
+		<button data-dojo-type="dijit/form/Button">hello world 21</button>
+		<button data-dojo-type="dijit/form/Button">hello world 22</button>
+		<button data-dojo-type="dijit/form/Button">hello world 23</button>
+		<button data-dojo-type="dijit/form/Button">hello world 24</button>
+		<button data-dojo-type="dijit/form/Button">hello world 25</button>
+		<button data-dojo-type="dijit/form/Button">hello world 26</button>
+		<button data-dojo-type="dijit/form/Button">hello world 27</button>
+		<button data-dojo-type="dijit/form/Button">hello world 28</button>
+		<button data-dojo-type="dijit/form/Button">hello world 29</button>
+
+		<button data-dojo-type="dijit/form/Button">hello world 30</button>
+		<button data-dojo-type="dijit/form/Button">hello world 31</button>
+		<button data-dojo-type="dijit/form/Button">hello world 32</button>
+		<button data-dojo-type="dijit/form/Button">hello world 33</button>
+		<button data-dojo-type="dijit/form/Button">hello world 34</button>
+		<button data-dojo-type="dijit/form/Button">hello world 35</button>
+		<button data-dojo-type="dijit/form/Button">hello world 36</button>
+		<button data-dojo-type="dijit/form/Button">hello world 37</button>
+		<button data-dojo-type="dijit/form/Button">hello world 38</button>
+		<button data-dojo-type="dijit/form/Button">hello world 39</button>
+
+		<button data-dojo-type="dijit/form/Button">hello world 40</button>
+		<button data-dojo-type="dijit/form/Button">hello world 41</button>
+		<button data-dojo-type="dijit/form/Button">hello world 42</button>
+		<button data-dojo-type="dijit/form/Button">hello world 43</button>
+		<button data-dojo-type="dijit/form/Button">hello world 44</button>
+		<button data-dojo-type="dijit/form/Button">hello world 45</button>
+		<button data-dojo-type="dijit/form/Button">hello world 46</button>
+		<button data-dojo-type="dijit/form/Button">hello world 47</button>
+		<button data-dojo-type="dijit/form/Button">hello world 48</button>
+		<button data-dojo-type="dijit/form/Button">hello world 49</button>
+
+		<button data-dojo-type="dijit/form/Button">hello world 50</button>
+		<button data-dojo-type="dijit/form/Button">hello world 51</button>
+		<button data-dojo-type="dijit/form/Button">hello world 52</button>
+		<button data-dojo-type="dijit/form/Button">hello world 53</button>
+		<button data-dojo-type="dijit/form/Button">hello world 54</button>
+		<button data-dojo-type="dijit/form/Button">hello world 55</button>
+		<button data-dojo-type="dijit/form/Button">hello world 56</button>
+		<button data-dojo-type="dijit/form/Button">hello world 57</button>
+		<button data-dojo-type="dijit/form/Button">hello world 58</button>
+		<button data-dojo-type="dijit/form/Button">hello world 59</button>
+
+		<button data-dojo-type="dijit/form/Button">hello world 60</button>
+		<button data-dojo-type="dijit/form/Button">hello world 61</button>
+		<button data-dojo-type="dijit/form/Button">hello world 62</button>
+		<button data-dojo-type="dijit/form/Button">hello world 63</button>
+		<button data-dojo-type="dijit/form/Button">hello world 64</button>
+		<button data-dojo-type="dijit/form/Button">hello world 65</button>
+		<button data-dojo-type="dijit/form/Button">hello world 66</button>
+		<button data-dojo-type="dijit/form/Button">hello world 67</button>
+		<button data-dojo-type="dijit/form/Button">hello world 68</button>
+		<button data-dojo-type="dijit/form/Button">hello world 69</button>
+
+		<button data-dojo-type="dijit/form/Button">hello world 70</button>
+		<button data-dojo-type="dijit/form/Button">hello world 71</button>
+		<button data-dojo-type="dijit/form/Button">hello world 72</button>
+		<button data-dojo-type="dijit/form/Button">hello world 73</button>
+		<button data-dojo-type="dijit/form/Button">hello world 74</button>
+		<button data-dojo-type="dijit/form/Button">hello world 75</button>
+		<button data-dojo-type="dijit/form/Button">hello world 76</button>
+		<button data-dojo-type="dijit/form/Button">hello world 77</button>
+		<button data-dojo-type="dijit/form/Button">hello world 78</button>
+		<button data-dojo-type="dijit/form/Button">hello world 79</button>
+
+		<button data-dojo-type="dijit/form/Button">hello world 80</button>
+		<button data-dojo-type="dijit/form/Button">hello world 81</button>
+		<button data-dojo-type="dijit/form/Button">hello world 82</button>
+		<button data-dojo-type="dijit/form/Button">hello world 83</button>
+		<button data-dojo-type="dijit/form/Button">hello world 84</button>
+		<button data-dojo-type="dijit/form/Button">hello world 85</button>
+		<button data-dojo-type="dijit/form/Button">hello world 86</button>
+		<button data-dojo-type="dijit/form/Button">hello world 87</button>
+		<button data-dojo-type="dijit/form/Button">hello world 88</button>
+		<button data-dojo-type="dijit/form/Button">hello world 89</button>
+
+		<button data-dojo-type="dijit/form/Button">hello world 90</button>
+		<button data-dojo-type="dijit/form/Button">hello world 91</button>
+		<button data-dojo-type="dijit/form/Button">hello world 92</button>
+		<button data-dojo-type="dijit/form/Button">hello world 93</button>
+		<button data-dojo-type="dijit/form/Button">hello world 94</button>
+		<button data-dojo-type="dijit/form/Button">hello world 95</button>
+		<button data-dojo-type="dijit/form/Button">hello world 96</button>
+		<button data-dojo-type="dijit/form/Button">hello world 97</button>
+		<button data-dojo-type="dijit/form/Button">hello world 98</button>
+		<button data-dojo-type="dijit/form/Button">hello world 99</button>
+
+
+		<h2>Result</h2>
+		(divide by 100 to get time per widget)
+		<div id="results"></div>
+
+		<h2>Typical results</h2>
+
+		<table border=1>
+		<thead>
+			<tr>
+				<th>IE6
+				<th>IE7
+				<th>Safari
+				<th>Gecko (on PC)
+				<th>Gecko (on intel mac)
+			</tr>
+		</thead>
+		<tbody>
+			<tr>
+				<td>25812 (258ms/widget)
+				<td>10391 (103ms/widget)
+				<td>1934 (19ms/widget)
+				<td>1344 (13ms/widget)
+				<td>2937 (29ms/widget)
+			</tr>
+		</tbody>
+		</table>
+	</body>
+</html>
diff --git a/dijit/bench/create_widgets.html b/dijit/bench/create_widgets.html
new file mode 100644
index 0000000..27aed53
--- /dev/null
+++ b/dijit/bench/create_widgets.html
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>PROGRAMMATIC - Dojo Widget Creation Test</title>
+		<script type="text/javascript" src="../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			var queryCount = location.search.match(/count=(\d*)/);
+			var count = (queryCount ? parseInt(queryCount[1]) : 100);
+			var queryClass = location.search.match(/class=([a-zA-z.]*)/);
+			var className = (queryClass ? queryClass[1] : "form.Button");
+
+			dojo.require("dijit." + className);
+			dojo.require("dojo.parser");
+			logMessage = window.alert;
+
+			var constructor = dojo.getObject("dijit."+className);
+			function makeEm(){
+				var container = dojo.byId("buttonContainer");
+				var t0 = new Date().getTime();
+				for(var i = 1; i <= count; i++){
+					var it =
+						new constructor(
+								{label:"Button "+i, onclick:'logMessage("clicked simple")'}
+							);
+					container.appendChild(it.domNode);
+					it.domNode.style.display = '';
+				}
+				var t1 = new Date().getTime();
+				dojo.byId("results").innerHTML = "It took " + (t1 - t0) + " msec to create " + count + " "+className+" instances programmatically.";
+			}
+			dojo.ready(makeEm);
+		</script>
+
+		<style type="text/css">
+			@import "../themes/tundra/tundra.css";
+
+			#buttonContainer {
+				border: 1px solid black;
+				width: 100%;
+			}
+
+			#results {
+				color: darkred;
+			}
+		</style>
+	</head>
+	<body class=tundra>
+		<script language='javascript'>
+			document.write("<h2>Currently Creating "+count+" "+className+" instances</h2>");
+		</script>
+		Pass <code>?count=<i><b>100</b></i></code> in the query string to change the number of widgets.<br>
+		Pass <code>?class=<i><b>form.Button</b></i></code> in the query string to change the widget class.
+		<h3 id="results"></h3>
+
+		<div id="buttonContainer" class='box'></div>
+		<br>
+	</body>
+</html>
diff --git a/dijit/bench/test_button-results.html b/dijit/bench/test_button-results.html
new file mode 100644
index 0000000..c9fa520
--- /dev/null
+++ b/dijit/bench/test_button-results.html
@@ -0,0 +1,66 @@
+<html>
+<style>
+	th	{	vertical-align:bottom;	}
+	td {
+		padding:10px;
+		text-align:right;
+	}
+	.computer	{	vertical-align:top;	}
+</style>
+<body>
+<h3>Widget instantiation timing test results</h3>
+
+<table>
+
+<tr><th rowspan=2>Computer/OS</th><th rowspan=2>Browser</th><th colspan=3>Parsing</th><th colspan=3>Programmatic</th></tr>
+<tr>														<th>100</th><th>500</th><th>1000</th><th>100</th><th>500</th><th>1000</th></tr>
+<tr><td class='computer' rowspan=3>MacBook Pro 2.16<br> OS 10.4 2GB RAM</td>
+	<td>FF (2.0.0.3)</td>
+	<td>303</td><td>1724</td><td>3505</td>
+	<td>195</td><td>1006</td><td>2266</td>
+</tr>
+<tr><td>Safari (2.04)</td>
+	<td>192</td><td>1460</td><td>4463</td>
+	<td>142</td><td>895</td><td>2403</td>
+</tr>
+<tr><td>WebKit Nightly (21223)</td>
+	<td>110</td><td>540</td><td>1096</td>
+	<td>85</td><td>458</td><td>940</td>
+</tr>
+
+
+<tr><td class='computer' rowspan=2>Dell Precision 2.13 PPro<br> XP SP 2 - 2GB RAM</td>
+	<td>FF (2.0.0.3)</td>
+	<td>282</td><td>1266</td><td>2484</td>
+	<td>250</td><td>890</td><td>1766</td>
+</tr>
+
+<tr>
+	<td>IE7 (7.0.5730.11)</td>
+	<td>303</td><td>2079</td><td>5172</td>
+	<td>203</td><td>1140</td><td>2422</td>
+</tr>
+
+<tr><td><!--browser--></td>
+	<td><!--100 parse--></td><td><!--500 parse--></td><td><!--1000 parse--></td>
+	<td><!--100 code--></td><td><!--500 code--></td><td><!--1000 code--></td>
+</tr>
+</table>
+
+
+<H3>If you want to play:</H3>
+<p></p>
+<ol>
+	<li> Run the following tests:
+		<ul>
+			<li><a href='http://dojotoolkit.org/~owen/bench/dojo/dijit/bench/test_Button-parse.php?count=100'>http://dojotoolkit.org/~owen/bench/dojo/dijit/bench/test_Button-parse.php?count=100</a></li>
+			<li><a href='http://dojotoolkit.org/~owen/bench/dojo/dijit/bench/test_Button-programmatic.html?count=100'>http://dojotoolkit.org/~owen/bench/dojo/dijit/bench/test_Button-programmatic.html?count=100</a></li>
+		</ul>
+		<br>
+		Change the "count=" to 100, 500, 1000 for each.
+		<br><br>
+		Restart the browser between each test/count.  Run each test 3 times and record the smallest number.
+	</li>
+	<li>Record your tests in the copy of this file in SVN:  <code>dijit/bench/test_Button-results.html</code>  and check it in.  Reference ticket #2968.</li>
+</ol>
+</body>
diff --git a/dijit/bench/widget_construction_test.php b/dijit/bench/widget_construction_test.php
new file mode 100644
index 0000000..74a5ca4
--- /dev/null
+++ b/dijit/bench/widget_construction_test.php
@@ -0,0 +1,185 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+
+<html>
+	<head>
+		<title>test of various synchronous page searching methods</title>
+		<style type="text/css">
+			@import "../themes/claro/document.css";
+			@import "../themes/tundra/tundra.css";
+		</style>
+		<script type="text/javascript" src="../../dojo/dojo.js"
+			data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+		<script type="text/javascript">
+			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+			dojo.require("dijit._WidgetBase");
+			dojo.require("dijit._TemplatedMixin");
+
+			/* dummy widget for benchmarking purposes */
+			dojo.declare(
+				"SimpleButton",
+				[ dijit._WidgetBase, dijit._TemplatedMixin ],
+				{
+					label: "",
+
+					templateString: "<button data-dojo-attach-event='onclick:onClick'>${label}</button>",
+
+					onClick: function(){
+						this.domNode.style.backgroundColor="green";
+					},
+					postCreate: function(){
+					}
+				}
+			);
+		</script>
+	</head>
+	<body>
+		<h1 style="font-size: 40px; line-height: 50px;">This page contains a huge number of nodes, most of which are "chaff".</h1>
+		<h3>Here's the relative timings for this page</h3>
+		<div id="profileOutputTable"></div>
+		<!--
+		<h3>And some comparison data</h3>
+		<table border=1>
+		<thead>
+			<tr>
+				<th>IE
+				<th>Safari
+				<th>Gecko (on PC)
+				<th>Gecko (on intel mac)
+			</tr>
+		</thead>
+		<tbody>
+			<tr>
+				<td>4890
+				<td>3242
+				<td>3094
+				<td>3782
+			</tr>
+		</tbody>
+		</table>
+		-->
+
+
+<?
+	$containerDepth = 30;
+	$leadingChaff = 100;
+	$trailingChaff = 100;
+	$items = 100;
+?>
+<?
+	function generateChaff($iters){
+		for($i=0;$i<$iters;$i++){ ?>
+			<pre class="highlighted"><code><span class="hl-reserved">var </span><span class="hl-identifier">dlg</span><span class="hl-default"> = </span><span class="hl-reserved">new </span><span class="hl-identifier">blah</span><span class="hl-default">.</span><span class="hl-identifier">ext</span><span class="hl-default">.</span><span class="hl-identifier">LayoutDialog</span><span class="hl-brackets">(</span><span class="hl-identifier">config</span><span class="hl-code">.</span><span class="hl- [...]
+				</span><span title="autoCreate" class="hl-identifier">autoCreate</span><span class="hl-code"> : </span><span class="hl-reserved">true</span><span class="hl-code">,
+				</span><span title="minWidth" class="hl-identifier">minWidth</span><span class="hl-code">:</span><span class="hl-number">400</span><span class="hl-code">,
+				</span><span title="minHeight" class="hl-identifier">minHeight</span><span class="hl-code">:</span><span class="hl-number">300</span><span class="hl-code">,
+				</span>
+				<span title="syncHeightBeforeShow" class="hl-identifier">syncHeightBeforeShow</span><span class="hl-code">: </span><span class="hl-reserved">true</span><span class="hl-code">,
+				</span><span title="shadow" class="hl-identifier">shadow</span><span class="hl-code">:</span><span class="hl-reserved">true</span><span class="hl-code">,
+				</span><span title="fixedcenter" class="hl-identifier">fixedcenter</span><span class="hl-code">: </span><span class="hl-reserved">true</span><span class="hl-code">,
+				</span><span title="center" class="hl-identifier">center</span><span class="hl-code">:</span><span class="hl-brackets">{</span><span class="hl-identifier">autoScroll</span><span class="hl-code">:</span><span class="hl-reserved">false</span><span class="hl-brackets">}</span><span class="hl-code">,
+				</span><span title="east"  class="hl-identifier">east</span><span class="hl-code">:</span><span class="hl-brackets">{</span><span class="hl-identifier">split</span><span class="hl-code">:</span><span class="hl-reserved">true</span><span class="hl-code">,</span><span class="hl-identifier">initialSize</span><span class="hl-code">:</span><span class="hl-number">150</span><span class="hl-code">,</span><span class="hl-identifier">minSize</span><span class="hl-code">:</span><span class="hl [...]
+			})</span><span class="hl-default">;
+			</span><span class="hl-identifier">dlg</span><span class="hl-default">.</span><span class="hl-identifier">setTitle</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">Choose an Image</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-default">;
+			</span><span class="hl-identifier">dlg</span><span class="hl-default">.</span><span class="hl-identifier">getEl</span><span class="hl-brackets">()</span><span class="hl-default">.</span><span class="hl-identifier">addClass</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">ychooser-dlg</span><span class="hl-quotes">'</span><span class="hl-brackets">)</span><span class="hl-default">;</span></code></pre><br />
+			<pre class="highlighted"><code><span class="hl-reserved">var </span><span class="hl-identifier">animated</span><span class="hl-default"> = </span><span class="hl-reserved">new </span><span class="hl-identifier">blah</span><span class="hl-default">.</span><span class="hl-identifier">ext</span><span class="hl-default">.</span><span class="hl-identifier">Resizable</span><span class="hl-brackets">(</span><span class="hl-quotes">'</span><span class="hl-string">animated</span><span class="h [...]
+			    </span><span title="east" class="hl-identifier">width</span><span class="hl-code">: </span><span class="hl-number">200</span><span class="hl-code">,
+			    </span><span title="east" class="hl-identifier">height</span><span class="hl-code">: </span><span class="hl-number">100</span><span class="hl-code">,
+			    </span><span title="east" class="hl-identifier">minWidth</span><span class="hl-code">:</span><span class="hl-number">100</span><span class="hl-code">,
+			    </span><span class="hl-identifier">minHeight</span><span class="hl-code">:</span><span class="hl-number">50</span><span class="hl-code">,
+			    </span><span class="hl-identifier">animate</span><span class="hl-code">:</span><span class="hl-reserved">true</span><span class="hl-code">,
+			    </span><span class="hl-identifier">easing</span><span class="hl-code">: </span><span class="hl-identifier">YAHOO</span><span class="hl-code">.</span><span class="hl-identifier">util</span><span class="hl-code">.</span><span class="hl-identifier">Easing</span><span class="hl-code">.</span><span class="hl-identifier">backIn</span><span class="hl-code">,
+			    </span><span class="hl-identifier">duration</span><span class="hl-code">:</span><span class="hl-number">.6
+			</span><span class="hl-brackets">})</span><span class="hl-default">;</span></code></pre>
+			<h4>The standard Lorem Ipsum passage, used since the 1500s</h4>
+			<p>
+			"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
+			eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
+			ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
+			aliquip ex ea commodo consequat. Duis aute irure dolor in
+			reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
+			pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
+			culpa qui officia deserunt mollit anim id est laborum."
+			</p>
+
+			<h4>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC</h4>
+
+			<p>
+			"Sed ut perspiciatis unde omnis iste natus error sit voluptatem
+			accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
+			quae ab illo inventore veritatis et quasi architecto beatae vitae
+			dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit
+			aspernatur aut odit aut fugit, sed quia consequuntur magni dolores
+			eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam
+			est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci
+			velit, sed quia non numquam eius modi tempora incidunt ut labore et
+			dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam,
+			quis nostrum exercitationem ullam corporis suscipit laboriosam,
+			nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure
+			reprehenderit qui in ea voluptate velit esse quam nihil molestiae
+			consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla
+			pariatur?"
+			</p>
+
+			<h4>1914 translation by H. Rackham</h4>
+
+			<p>
+			"But I must explain to you how all this mistaken idea of denouncing
+			pleasure and praising pain was born and I will give you a complete
+			account of the system, and expound the actual teachings of the
+			great explorer of the truth, the master-builder of human happiness.
+			No one rejects, dislikes, or avoids pleasure itself, because it is
+			pleasure, but because those who do not know how to pursue pleasure
+			rationally encounter consequences that are extremely painful. Nor
+			again is there anyone who loves or pursues or desires to obtain
+			pain of itself, because it is pain, but because occasionally
+			circumstances occur in which toil and pain can procure him some
+			great pleasure. To take a trivial example, which of us ever
+			undertakes laborious physical exercise, except to obtain some
+			advantage from it? But who has any right to find fault with a man
+			who chooses to enjoy a pleasure that has no annoying consequences,
+			or one who avoids a pain that produces no resultant pleasure?"
+			</p>
+		<? }
+	} // end generateChaff
+	$widgetName = "SimpleButton";
+?>
+<? generateChaff($leadingChaff); ?>
+<hr>
+<? for($i=0;$i<$containerDepth;$i++){ ?>
+	<table border="1" cellpadding="0" cellspacing="0" width="100%">
+	<!--
+	<table>
+	-->
+		<tr>
+			<td>
+			<br>
+			chaff!
+			<br>
+<? } ?>
+<? for($i=0;$i<$items;$i++){ ?>
+			<div data-dojo-type="<?= $widgetName ?>" label="item2 <?= $i ?>">item2 <?= $i ?></div>
+<? } ?>
+<? for($i=0;$i<$containerDepth;$i++){ ?>
+			</td>
+		</tr>
+	</table>
+<? } ?>
+<? generateChaff($trailingChaff);  ?>
+<? for($i=0;$i<$items;$i++){ ?>
+	<div data-dojo-type="<?= $widgetName ?>" label="item2 <?= $i ?>"><span>item <?= $i ?></span></div>
+<? } ?>
+
+<script type="text/javascript">
+
+		oldTime = new Date();
+		dojo.ready(function(){
+			var time = new Date().getTime() - oldTime;
+			var p = document.createElement("p");
+			alert("Widgets loaded in " + time + "ms");
+		});
+
+</script>
+
+	</body>
+</html>
diff --git a/dijit/dijit-all.js b/dijit/dijit-all.js
index db78661..d576c2c 100644
--- a/dijit/dijit-all.js
+++ b/dijit/dijit-all.js
@@ -1,5 +1,5 @@
 define([
-	".",
+	"./main",
 	"./dijit",
 	"./ColorPalette",
 	"./Declaration",
@@ -61,8 +61,13 @@ define([
 
 	// module:
 	//		dijit/dijit-all
-	// summary:
-	//		A rollup that includes every dijit. You probably don't need this.
+
+	/*=====
+	return {
+		// summary:
+		//		A rollup that includes every dijit. You probably don't need this.
+	};
+	=====*/
 
 	console.warn("dijit-all may include much more code than your application actually requires. We strongly recommend that you investigate a custom build or the web build tool");
 
diff --git a/dijit/dijit.js b/dijit/dijit.js
index de1de1c..2df446b 100644
--- a/dijit/dijit.js
+++ b/dijit/dijit.js
@@ -1,5 +1,5 @@
 define([
-	".",
+	"./main",
 	"./_base",
 	"dojo/parser",
 	"./_Widget",
@@ -12,10 +12,15 @@ define([
 
 	// module:
 	//		dijit/dijit
-	// summary:
-	//		A roll-up for common dijit methods
-	//		All the stuff in _base (these are the function that are guaranteed available without an explicit dojo.require)
-	//		And some other stuff that we tend to pull in all the time anyway
+
+	/*=====
+	return {
+		// summary:
+		//		A roll-up for common dijit methods
+		//		All the stuff in _base (these are the function that are guaranteed available without an explicit dojo.require)
+		//		And some other stuff that we tend to pull in all the time anyway
+	};
+	=====*/
 
 	return dijit;
 });
diff --git a/dijit/dijit.profile.js b/dijit/dijit.profile.js
index dffbfa0..5a75a6a 100644
--- a/dijit/dijit.profile.js
+++ b/dijit/dijit.profile.js
@@ -27,11 +27,7 @@ var profile = (function(){
 			miniExclude: function(filename, mid){
 				return /^dijit\/bench\//.test(mid) || /^dijit\/themes\/themeTest/.test(mid);
 			}
-		},
-
-		trees:[
-			[".", ".", /(\/\.)|(~$)/]
-		]
+		}
 	};
 })();
 
diff --git a/dijit/focus.js b/dijit/focus.js
index 4a3b335..016c860 100644
--- a/dijit/focus.js
+++ b/dijit/focus.js
@@ -7,25 +7,23 @@ define([
 	"dojo/Evented",
 	"dojo/_base/lang", // lang.hitch
 	"dojo/on",
-	"dojo/ready",
-	"dojo/_base/sniff", // has("ie")
+	"dojo/domReady",
+	"dojo/sniff", // has("ie")
 	"dojo/Stateful",
-	"dojo/_base/unload", // unload.addOnWindowUnload
 	"dojo/_base/window", // win.body
 	"dojo/window", // winUtils.get
 	"./a11y",	// a11y.isTabNavigable
 	"./registry",	// registry.byId
-	"."		// to set dijit.focus
-], function(aspect, declare, dom, domAttr, domConstruct, Evented, lang, on, ready, has, Stateful, unload, win, winUtils,
+	"./main"		// to set dijit.focus
+], function(aspect, declare, dom, domAttr, domConstruct, Evented, lang, on, domReady, has, Stateful, win, winUtils,
 			a11y, registry, dijit){
 
 	// module:
 	//		dijit/focus
-	// summary:
-	//		Returns a singleton that tracks the currently focused node, and which widgets are currently "active".
 
-/*=====
-	dijit.focus = {
+	var lastFocusin;
+
+	var FocusManager = declare([Stateful, Evented], {
 		// summary:
 		//		Tracks the currently focused node, and which widgets are currently "active".
 		//		Access via require(["dijit/focus"], function(focus){ ... }).
@@ -45,46 +43,7 @@ define([
 		//		Currently focused item on screen
 		curNode: null,
 
-		// activeStack: dijit._Widget[]
-		//		List of currently active widgets (focused widget and it's ancestors)
-		activeStack: [],
-
-		registerIframe: function(iframe){
-			// summary:
-			//		Registers listeners on the specified iframe so that any click
-			//		or focus event on that iframe (or anything in it) is reported
-			//		as a focus/click event on the <iframe> itself.
-			// description:
-			//		Currently only used by editor.
-			// returns:
-			//		Handle with remove() method to deregister.
-		},
-
-		registerWin: function(targetWindow, effectiveNode){
-			// summary:
-			//		Registers listeners on the specified window (either the main
-			//		window or an iframe's window) to detect when the user has clicked somewhere
-			//		or focused somewhere.
-			// description:
-			//		Users should call registerIframe() instead of this method.
-			// targetWindow: Window?
-			//		If specified this is the window associated with the iframe,
-			//		i.e. iframe.contentWindow.
-			// effectiveNode: DOMNode?
-			//		If specified, report any focus events inside targetWindow as
-			//		an event on effectiveNode, rather than on evt.target.
-			// returns:
-			//		Handle with remove() method to deregister.
-		}
-	};
-=====*/
-
-	var FocusManager = declare([Stateful, Evented], {
-		// curNode: DomNode
-		//		Currently focused item on screen
-		curNode: null,
-
-		// activeStack: dijit._Widget[]
+		// activeStack: dijit/_WidgetBase[]
 		//		List of currently active widgets (focused widget and it's ancestors)
 		activeStack: [],
 
@@ -106,7 +65,7 @@ define([
 			// summary:
 			//		Registers listeners on the specified iframe so that any click
 			//		or focus event on that iframe (or anything in it) is reported
-			//		as a focus/click event on the <iframe> itself.
+			//		as a focus/click event on the `<iframe>` itself.
 			// description:
 			//		Currently only used by editor.
 			// returns:
@@ -132,92 +91,88 @@ define([
 
 			// TODO: make this function private in 2.0; Editor/users should call registerIframe(),
 
-			var _this = this;
-			var mousedownListener = function(evt){
-				_this._justMouseDowned = true;
-				setTimeout(function(){ _this._justMouseDowned = false; }, 0);
+			// Listen for blur and focus events on targetWindow's document.
+			var _this = this,
+				body = targetWindow.document && targetWindow.document.body;
+
+			if(body){
+				var mdh = on(targetWindow.document, 'mousedown, touchstart', function(evt){
+					_this._justMouseDowned = true;
+					setTimeout(function(){ _this._justMouseDowned = false; }, 0);
+
+					// workaround weird IE bug where the click is on an orphaned node
+					// (first time clicking a Select/DropDownButton inside a TooltipDialog).
+					// actually, strangely this is happening on latest chrome too.
+					if(evt && evt.target && evt.target.parentNode == null){
+						return;
+					}
 
-				// workaround weird IE bug where the click is on an orphaned node
-				// (first time clicking a Select/DropDownButton inside a TooltipDialog)
-				if(has("ie") && evt && evt.srcElement && evt.srcElement.parentNode == null){
-					return;
-				}
+					_this._onTouchNode(effectiveNode || evt.target, "mouse");
+				});
 
-				_this._onTouchNode(effectiveNode || evt.target || evt.srcElement, "mouse");
-			};
+				var fih = on(body, 'focusin', function(evt){
 
-			// Listen for blur and focus events on targetWindow's document.
-			// IIRC, I'm using attachEvent() rather than dojo.connect() because focus/blur events don't bubble
-			// through dojo.connect(), and also maybe to catch the focus events early, before onfocus handlers
-			// fire.
-			// Connect to <html> (rather than document) on IE to avoid memory leaks, but document on other browsers because
-			// (at least for FF) the focus event doesn't fire on <html> or <body>.
-			var doc = has("ie") ? targetWindow.document.documentElement : targetWindow.document;
-			if(doc){
-				if(has("ie")){
-					targetWindow.document.body.attachEvent('onmousedown', mousedownListener);
-					var activateListener = function(evt){
-						// IE reports that nodes like <body> have gotten focus, even though they have tabIndex=-1,
-						// ignore those events
-						var tag = evt.srcElement.tagName.toLowerCase();
-						if(tag == "#document" || tag == "body"){ return; }
+					lastFocusin = (new Date()).getTime();
+
+					// When you refocus the browser window, IE gives an event with an empty srcElement
+					if(!evt.target.tagName) { return; }
 
+					// IE reports that nodes like <body> have gotten focus, even though they have tabIndex=-1,
+					// ignore those events
+					var tag = evt.target.tagName.toLowerCase();
+					if(tag == "#document" || tag == "body"){ return; }
+
+					if(a11y.isTabNavigable(evt.target)){
+						// If condition doesn't seem quite right, but it is correctly preventing focus events for
+						// clicks on disabled buttons.  (TODO: it doesn't register clicks on TabContainer tabs because
+						// they are tabIndex="-1")
+						_this._onFocusNode(effectiveNode || evt.target);
+					}else{
 						// Previous code called _onTouchNode() for any activate event on a non-focusable node.   Can
 						// probably just ignore such an event as it will be handled by onmousedown handler above, but
 						// leaving the code for now.
-						if(a11y.isTabNavigable(evt.srcElement)){
-							_this._onFocusNode(effectiveNode || evt.srcElement);
-						}else{
-							_this._onTouchNode(effectiveNode || evt.srcElement);
-						}
-					};
-					doc.attachEvent('onactivate', activateListener);
-					var deactivateListener =  function(evt){
-						_this._onBlurNode(effectiveNode || evt.srcElement);
-					};
-					doc.attachEvent('ondeactivate', deactivateListener);
-
-					return {
-						remove: function(){
-							targetWindow.document.detachEvent('onmousedown', mousedownListener);
-							doc.detachEvent('onactivate', activateListener);
-							doc.detachEvent('ondeactivate', deactivateListener);
-							doc = null;	// prevent memory leak (apparent circular reference via closure)
-						}
-					};
-				}else{
-					doc.body.addEventListener('mousedown', mousedownListener, true);
-					doc.body.addEventListener('touchstart', mousedownListener, true);
-					var focusListener = function(evt){
-						_this._onFocusNode(effectiveNode || evt.target);
-					};
-					doc.addEventListener('focus', focusListener, true);
-					var blurListener = function(evt){
-						_this._onBlurNode(effectiveNode || evt.target);
-					};
-					doc.addEventListener('blur', blurListener, true);
-
-					return {
-						remove: function(){
-							doc.body.removeEventListener('mousedown', mousedownListener, true);
-							doc.body.removeEventListener('touchstart', mousedownListener, true);
-							doc.removeEventListener('focus', focusListener, true);
-							doc.removeEventListener('blur', blurListener, true);
-							doc = null;	// prevent memory leak (apparent circular reference via closure)
-						}
-					};
-				}
+						_this._onTouchNode(effectiveNode || evt.target);
+					}
+				});
+
+				var foh = on(body, 'focusout', function(evt){
+					// IE9+ has a problem where focusout events come after the corresponding focusin event.  At least
+					// when moving focus from the Editor's <iframe> to a normal DOMNode.
+					if((new Date()).getTime() < lastFocusin + 100){
+						return;
+					}
+
+					_this._onBlurNode(effectiveNode || evt.target);
+				});
+
+				return {
+					remove: function(){
+						mdh.remove();
+						fih.remove();
+						foh.remove();
+						mdh = fih = foh = null;
+						body = null;	// prevent memory leak (apparent circular reference via closure)
+					}
+				};
 			}
 		},
 
-		_onBlurNode: function(/*DomNode*/ /*===== node =====*/){
+		_onBlurNode: function(/*DomNode*/ node){
 			// summary:
-			// 		Called when focus leaves a node.
+			//		Called when focus leaves a node.
 			//		Usually ignored, _unless_ it *isn't* followed by touching another node,
 			//		which indicates that we tabbed off the last field on the page,
 			//		in which case every widget is marked inactive
-			this.set("prevNode", this.curNode);
-			this.set("curNode", null);
+
+			// If the blur event isn't followed by a focus event, it means the user clicked on something unfocusable,
+			// so clear focus.
+			if(this._clearFocusTimer){
+				clearTimeout(this._clearFocusTimer);
+			}
+			this._clearFocusTimer = setTimeout(lang.hitch(this, function(){
+				this.set("prevNode", this.curNode);
+				this.set("curNode", null);
+			}), 0);
 
 			if(this._justMouseDowned){
 				// the mouse down caused a new widget to be marked as active; this blur event
@@ -225,15 +180,14 @@ define([
 				return;
 			}
 
-			// if the blur event isn't followed by a focus event then mark all widgets as inactive.
+			// If the blur event isn't followed by a focus or touch event then mark all widgets as inactive.
 			if(this._clearActiveWidgetsTimer){
 				clearTimeout(this._clearActiveWidgetsTimer);
 			}
 			this._clearActiveWidgetsTimer = setTimeout(lang.hitch(this, function(){
 				delete this._clearActiveWidgetsTimer;
 				this._setStack([]);
-				this.prevNode = null;
-			}), 100);
+			}), 0);
 		},
 
 		_onTouchNode: function(/*DomNode*/ node, /*String*/ by){
@@ -298,9 +252,17 @@ define([
 				return;
 			}
 
+			// There was probably a blur event right before this event, but since we have a new focus, don't
+			// do anything with the blur
+			if(this._clearFocusTimer){
+				clearTimeout(this._clearFocusTimer);
+				delete this._clearFocusTimer;
+			}
+
 			this._onTouchNode(node);
 
 			if(node == this.curNode){ return; }
+			this.set("prevNode", this.curNode);
 			this.set("curNode", node);
 		},
 
@@ -312,19 +274,19 @@ define([
 			// by:
 			//		"mouse" if the focus/touch was caused by a mouse down event
 
-			var oldStack = this.activeStack;
-			this.set("activeStack", newStack);
+			var oldStack = this.activeStack, lastOldIdx = oldStack.length - 1, lastNewIdx = newStack.length - 1;
 
-			// compare old stack to new stack to see how many elements they have in common
-			for(var nCommon=0; nCommon<Math.min(oldStack.length, newStack.length); nCommon++){
-				if(oldStack[nCommon] != newStack[nCommon]){
-					break;
-				}
+			if(newStack[lastNewIdx] == oldStack[lastOldIdx]){
+				// no changes, return now to avoid spurious notifications about changes to activeStack
+				return;
 			}
 
-			var widget;
+			this.set("activeStack", newStack);
+
+			var widget, i;
+
 			// for all elements that have gone out of focus, set focused=false
-			for(var i=oldStack.length-1; i>=nCommon; i--){
+			for(i = lastOldIdx; i >= 0 && oldStack[i] != newStack[i]; i--){
 				widget = registry.byId(oldStack[i]);
 				if(widget){
 					widget._hasBeenBlurred = true;		// TODO: used by form widgets, should be moved there
@@ -337,7 +299,7 @@ define([
 			}
 
 			// for all element that have come into focus, set focused=true
-			for(i=nCommon; i<newStack.length; i++){
+			for(i++; i <= lastNewIdx; i++){
 				widget = registry.byId(newStack[i]);
 				if(widget){
 					widget.set("focused", true);
@@ -361,18 +323,20 @@ define([
 	var singleton = new FocusManager();
 
 	// register top window and all the iframes it contains
-	ready(function(){
-		var handle = singleton.registerWin(win.doc.parentWindow || win.doc.defaultView);
+	domReady(function(){
+		var handle = singleton.registerWin(winUtils.get(document));
 		if(has("ie")){
-			unload.addOnWindowUnload(function(){
-				handle.remove();
-				handle = null;
-			})
+			on(window, "unload", function(){
+				if(handle){	// because this gets called twice when doh.robot is running
+					handle.remove();
+					handle = null;
+				}
+			});
 		}
 	});
 
 	// Setup dijit.focus as a pointer to the singleton but also (for backwards compatibility)
-	// as a function to set focus.
+	// as a function to set focus.   Remove for 2.0.
 	dijit.focus = function(node){
 		singleton.focus(node);	// indirection here allows dijit/_base/focus.js to override behavior
 	};
diff --git a/dijit/form/Button.js b/dijit/form/Button.js
index a9ccbc2..a64c556 100644
--- a/dijit/form/Button.js
+++ b/dijit/form/Button.js
@@ -2,123 +2,126 @@ define([
 	"require",
 	"dojo/_base/declare", // declare
 	"dojo/dom-class", // domClass.toggle
+	"dojo/has", // has("dijit-legacy-requires")
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/_base/lang", // lang.trim
 	"dojo/ready",
 	"./_FormWidget",
 	"./_ButtonMixin",
 	"dojo/text!./templates/Button.html"
-], function(require, declare, domClass, kernel, lang, ready, _FormWidget, _ButtonMixin, template){
+], function(require, declare, domClass, has, kernel, lang, ready, _FormWidget, _ButtonMixin, template){
 
-/*=====
-	var _FormWidget = dijit.form._FormWidget;
-	var _ButtonMixin = dijit.form._ButtonMixin;
-=====*/
+	// module:
+	//		dijit/form/Button
 
-// module:
-//		dijit/form/Button
-// summary:
-//		Button widget
-
-// Back compat w/1.6, remove for 2.0
-if(!kernel.isAsync){
-	ready(0, function(){
-		var requires = ["dijit/form/DropDownButton", "dijit/form/ComboButton", "dijit/form/ToggleButton"];
-		require(requires);	// use indirection so modules not rolled into a build
-	});
-}
-
-return declare("dijit.form.Button", [_FormWidget, _ButtonMixin], {
-	// summary:
-	//		Basically the same thing as a normal HTML button, but with special styling.
-	// description:
-	//		Buttons can display a label, an icon, or both.
-	//		A label should always be specified (through innerHTML) or the label
-	//		attribute.  It can be hidden via showLabel=false.
-	// example:
-	// |	<button data-dojo-type="dijit.form.Button" onClick="...">Hello world</button>
-	//
-	// example:
-	// |	var button1 = new dijit.form.Button({label: "hello world", onClick: foo});
-	// |	dojo.body().appendChild(button1.domNode);
-
-	// showLabel: Boolean
-	//		Set this to true to hide the label text and display only the icon.
-	//		(If showLabel=false then iconClass must be specified.)
-	//		Especially useful for toolbars.
-	//		If showLabel=true, the label will become the title (a.k.a. tooltip/hint) of the icon.
-	//
-	//		The exception case is for computers in high-contrast mode, where the label
-	//		will still be displayed, since the icon doesn't appear.
-	showLabel: true,
-
-	// iconClass: String
-	//		Class to apply to DOMNode in button to make it display an icon
-	iconClass: "dijitNoIcon",
-	_setIconClassAttr: { node: "iconNode", type: "class" },
-
-	baseClass: "dijitButton",
-
-	templateString: template,
-
-	// Map widget attributes to DOMNode attributes.
-	_setValueAttr: "valueNode",
+	// Back compat w/1.6, remove for 2.0
+	if(has("dijit-legacy-requires")){
+		ready(0, function(){
+			var requires = ["dijit/form/DropDownButton", "dijit/form/ComboButton", "dijit/form/ToggleButton"];
+			require(requires);	// use indirection so modules not rolled into a build
+		});
+	}
 
-	_onClick: function(/*Event*/ e){
+	var Button = declare("dijit.form.Button" + (has("dojo-bidi") ? "_NoBidi" : ""), [_FormWidget, _ButtonMixin], {
 		// summary:
-		//		Internal function to handle click actions
-		var ok = this.inherited(arguments);
-		if(ok){
+		//		Basically the same thing as a normal HTML button, but with special styling.
+		// description:
+		//		Buttons can display a label, an icon, or both.
+		//		A label should always be specified (through innerHTML) or the label
+		//		attribute.  It can be hidden via showLabel=false.
+		// example:
+		// |	<button data-dojo-type="dijit/form/Button" onClick="...">Hello world</button>
+		//
+		// example:
+		// |	var button1 = new Button({label: "hello world", onClick: foo});
+		// |	dojo.body().appendChild(button1.domNode);
+
+		// showLabel: Boolean
+		//		Set this to true to hide the label text and display only the icon.
+		//		(If showLabel=false then iconClass must be specified.)
+		//		Especially useful for toolbars.
+		//		If showLabel=true, the label will become the title (a.k.a. tooltip/hint) of the icon.
+		//
+		//		The exception case is for computers in high-contrast mode, where the label
+		//		will still be displayed, since the icon doesn't appear.
+		showLabel: true,
+
+		// iconClass: String
+		//		Class to apply to DOMNode in button to make it display an icon
+		iconClass: "dijitNoIcon",
+		_setIconClassAttr: { node: "iconNode", type: "class" },
+
+		baseClass: "dijitButton",
+
+		templateString: template,
+
+		// Map widget attributes to DOMNode attributes.
+		_setValueAttr: "valueNode",
+		_setNameAttr: function(name){
+			// avoid breaking existing subclasses where valueNode undefined.  Perhaps in 2.0 require it to be defined?
 			if(this.valueNode){
-				this.valueNode.click();
-				e.preventDefault(); // cancel BUTTON click and continue with hidden INPUT click
-				// leave ok = true so that subclasses can do what they need to do
+				this.valueNode.setAttribute("name", name);
 			}
-		}
-		return ok;
-	},
-
-	_fillContent: function(/*DomNode*/ source){
-		// Overrides _Templated._fillContent().
-		// If button label is specified as srcNodeRef.innerHTML rather than
-		// this.params.label, handle it here.
-		// TODO: remove the method in 2.0, parser will do it all for me
-		if(source && (!this.params || !("label" in this.params))){
-			var sourceLabel = lang.trim(source.innerHTML);
-			if(sourceLabel){
-				this.label = sourceLabel; // _applyAttributes will be called after buildRendering completes to update the DOM
+		},
+
+		_fillContent: function(/*DomNode*/ source){
+			// Overrides _Templated._fillContent().
+			// If button label is specified as srcNodeRef.innerHTML rather than
+			// this.params.label, handle it here.
+			// TODO: remove the method in 2.0, parser will do it all for me
+			if(source && (!this.params || !("label" in this.params))){
+				var sourceLabel = lang.trim(source.innerHTML);
+				if(sourceLabel){
+					this.label = sourceLabel; // _applyAttributes will be called after buildRendering completes to update the DOM
+				}
 			}
-		}
-	},
+		},
 
-	_setShowLabelAttr: function(val){
-		if(this.containerNode){
-			domClass.toggle(this.containerNode, "dijitDisplayNone", !val);
+		_setShowLabelAttr: function(val){
+			if(this.containerNode){
+				domClass.toggle(this.containerNode, "dijitDisplayNone", !val);
+			}
+			this._set("showLabel", val);
+		},
+
+		setLabel: function(/*String*/ content){
+			// summary:
+			//		Deprecated.  Use set('label', ...) instead.
+			kernel.deprecated("dijit.form.Button.setLabel() is deprecated.  Use set('label', ...) instead.", "", "2.0");
+			this.set("label", content);
+		},
+
+		_setLabelAttr: function(/*String*/ content){
+			// summary:
+			//		Hook for set('label', ...) to work.
+			// description:
+			//		Set the label (text) of the button; takes an HTML string.
+			//		If the label is hidden (showLabel=false) then and no title has
+			//		been specified, then label is also set as title attribute of icon.
+			this.inherited(arguments);
+			if(!this.showLabel && !("title" in this.params)){
+				this.titleNode.title = lang.trim(this.containerNode.innerText || this.containerNode.textContent || '');
+			}
 		}
-		this._set("showLabel", val);
-	},
-
-	setLabel: function(/*String*/ content){
-		// summary:
-		//		Deprecated.  Use set('label', ...) instead.
-		kernel.deprecated("dijit.form.Button.setLabel() is deprecated.  Use set('label', ...) instead.", "", "2.0");
-		this.set("label", content);
-	},
+	});
 
-	_setLabelAttr: function(/*String*/ content){
-		// summary:
-		//		Hook for set('label', ...) to work.
-		// description:
-		//		Set the label (text) of the button; takes an HTML string.
-		//		If the label is hidden (showLabel=false) then and no title has
-		//		been specified, then label is also set as title attribute of icon.
-		this.inherited(arguments);
-		if(!this.showLabel && !("title" in this.params)){
-			this.titleNode.title = lang.trim(this.containerNode.innerText || this.containerNode.textContent || '');
-		}
+	if(has("dojo-bidi")){
+		Button = declare("dijit.form.Button", Button, {
+			_setLabelAttr: function(/*String*/ content){
+				this.inherited(arguments);
+				if(this.titleNode.title){
+					this.applyTextDir(this.titleNode, this.titleNode.title);
+				}
+			},
+
+			_setTextDirAttr: function(/*String*/ textDir){
+				if(this._created && this.textDir != textDir){
+					this._set("textDir", textDir);
+					this._setLabelAttr(this.label); // call applyTextDir on both focusNode and titleNode
+				}
+			}
+		});
 	}
-});
-
 
+	return Button;
 });
-
diff --git a/dijit/form/CheckBox.js b/dijit/form/CheckBox.js
index 53d9e63..0fc69a6 100644
--- a/dijit/form/CheckBox.js
+++ b/dijit/form/CheckBox.js
@@ -2,27 +2,21 @@ define([
 	"require",
 	"dojo/_base/declare", // declare
 	"dojo/dom-attr", // domAttr.set
-	"dojo/_base/kernel",
+	"dojo/has",		// has("dijit-legacy-requires")
 	"dojo/query", // query
 	"dojo/ready",
 	"./ToggleButton",
 	"./_CheckBoxMixin",
 	"dojo/text!./templates/CheckBox.html",
-	"dojo/NodeList-dom" // NodeList.addClass/removeClass
-], function(require, declare, domAttr, kernel, query, ready, ToggleButton, _CheckBoxMixin, template){
-
-/*=====
-	var ToggleButton = dijit.form.ToggleButton;
-	var _CheckBoxMixin = dijit.form._CheckBoxMixin;
-=====*/
+	"dojo/NodeList-dom", // NodeList.addClass/removeClass
+	"../a11yclick"	// template uses ondijitclick
+], function(require, declare, domAttr, has, query, ready, ToggleButton, _CheckBoxMixin, template){
 
 	// module:
 	//		dijit/form/CheckBox
-	// summary:
-	//		Checkbox widget
 
 	// Back compat w/1.6, remove for 2.0
-	if(!kernel.isAsync){
+	if(has("dijit-legacy-requires")){
 		ready(0, function(){
 			var requires = ["dijit/form/RadioButton"];
 			require(requires);	// use indirection so modules not rolled into a build
@@ -31,7 +25,7 @@ define([
 
 	return declare("dijit.form.CheckBox", [ToggleButton, _CheckBoxMixin], {
 		// summary:
-		// 		Same as an HTML checkbox, but with fancy styling.
+		//		Same as an HTML checkbox, but with fancy styling.
 		//
 		// description:
 		//		User interacts with real html inputs.
@@ -40,8 +34,9 @@ define([
 		//		we update the state of the checkbox/radio.
 		//
 		//		There are two modes:
-		//			1. High contrast mode
-		//			2. Normal mode
+		//
+		//		1. High contrast mode
+		//		2. Normal mode
 		//
 		//		In case 1, the regular html inputs are shown and used by the user.
 		//		In case 2, the regular html inputs are invisible but still used by
@@ -56,19 +51,21 @@ define([
 			//		Handler for value= attribute to constructor, and also calls to
 			//		set('value', val).
 			// description:
-			//		During initialization, just saves as attribute to the <input type=checkbox>.
+			//		During initialization, just saves as attribute to the `<input type=checkbox>`.
 			//
 			//		After initialization,
 			//		when passed a boolean, controls whether or not the CheckBox is checked.
 			//		If passed a string, changes the value attribute of the CheckBox (the one
-			//		specified as "value" when the CheckBox was constructed (ex: <input
-			//		data-dojo-type="dijit.CheckBox" value="chicken">)
-			//		widget.set('value', string) will check the checkbox and change the value to the
-			//		specified string
-			//		widget.set('value', boolean) will change the checked state.
+			//		specified as "value" when the CheckBox was constructed
+			//		(ex: `<input data-dojo-type="dijit/CheckBox" value="chicken">`).
+			//
+			//		`widget.set('value', string)` will check the checkbox and change the value to the
+			//		specified string.
+			//
+			//		`widget.set('value', boolean)` will change the checked state.
+
 			if(typeof newValue == "string"){
-				this._set("value", newValue);
-				domAttr.set(this.focusNode, 'value', newValue);
+				this.inherited(arguments);
 				newValue = true;
 			}
 			if(this._created){
@@ -81,19 +78,21 @@ define([
 			// description:
 			//		If the CheckBox is checked, returns the value attribute.
 			//		Otherwise returns false.
-			return (this.checked ? this.value : false);
+			return this.checked && this._get("value");
 		},
 
-		// Override behavior from Button, since we don't have an iconNode
+		// Override behavior from Button, since we don't have an iconNode or valueNode
 		_setIconClassAttr: null,
+		_setNameAttr: "focusNode",
 
 		postMixInProperties: function(){
 			this.inherited(arguments);
 
-			// Need to set initial checked state as part of template, so that form submit works.
+			// Need to set initial checked state via node.setAttribute so that form submit works
+			// and IE8 radio button tab order is preserved.
 			// domAttr.set(node, "checked", bool) doesn't work on IE until node has been attached
 			// to <body>, see #8666
-			this.checkedAttrSetting = this.checked ? "checked" : "";
+			this.checkedAttrSetting = "";
 		},
 
 		 _fillContent: function(){
diff --git a/dijit/form/ComboBox.js b/dijit/form/ComboBox.js
index d585120..00f74e5 100644
--- a/dijit/form/ComboBox.js
+++ b/dijit/form/ComboBox.js
@@ -4,15 +4,8 @@ define([
 	"./ComboBoxMixin"
 ], function(declare, ValidationTextBox, ComboBoxMixin){
 
-/*=====
-	var ValidationTextBox = dijit.form.ValidationTextBox;
-	var ComboBoxMixin = dijit.form.ComboBoxMixin;
-=====*/
-
 	// module:
 	//		dijit/form/ComboBox
-	// summary:
-	//		Auto-completing text box
 
 	return declare("dijit.form.ComboBox", [ValidationTextBox, ComboBoxMixin], {
 		// summary:
diff --git a/dijit/form/ComboBoxMixin.js b/dijit/form/ComboBoxMixin.js
index ee4a9b8..8a3b808 100644
--- a/dijit/form/ComboBoxMixin.js
+++ b/dijit/form/ComboBoxMixin.js
@@ -1,25 +1,18 @@
 define([
 	"dojo/_base/declare", // declare
-	"dojo/_base/Deferred",
+	"dojo/Deferred",
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/_base/lang", // lang.mixin
-	"dojo/store/util/QueryResults",	// dojo.store.util.QueryResults
+	"dojo/store/util/QueryResults",
 	"./_AutoCompleterMixin",
 	"./_ComboBoxMenu",
 	"../_HasDropDown",
 	"dojo/text!./templates/DropDownBox.html"
 ], function(declare, Deferred, kernel, lang, QueryResults, _AutoCompleterMixin, _ComboBoxMenu, _HasDropDown, template){
 
-/*=====
-	var _AutoCompleterMixin = dijit.form._AutoCompleterMixin;
-	var _ComboBoxMenu = dijit.form._ComboBoxMenu;
-	var _HasDropDown = dijit._HasDropDown;
-=====*/
 
 	// module:
 	//		dijit/form/ComboBoxMixin
-	// summary:
-	//		Provides main functionality of ComboBox widget
 
 	return declare("dijit.form.ComboBoxMixin", [_HasDropDown, _AutoCompleterMixin], {
 		// summary:
@@ -40,10 +33,10 @@ define([
 		baseClass: "dijitTextBox dijitComboBox",
 
 		/*=====
-		// store: [const] dojo.store.api.Store || dojo.data.api.Read
+		// store: [const] dojo/store/api/Store|dojo/data/api/Read
 		//		Reference to data provider object used by this ComboBox.
 		//
-		//		Should be dojo.store.api.Store, but dojo.data.api.Read supported
+		//		Should be dojo/store/api/Store, but dojo/data/api/Read supported
 		//		for backwards compatibility.
 		store: null,
 		=====*/
@@ -66,14 +59,14 @@ define([
 		},
 
 		_setStoreAttr: function(store){
-			// For backwards-compatibility, accept dojo.data store in addition to dojo.store.store.  Remove in 2.0.
+			// For backwards-compatibility, accept dojo.data store in addition to dojo/store/api/Store.  Remove in 2.0.
 			if(!store.get){
 				lang.mixin(store, {
 					_oldAPI: true,
 					get: function(id){
 						// summary:
 						//		Retrieves an object by it's identity. This will trigger a fetchItemByIdentity.
-						//		Like dojo.store.DataStore.get() except returns native item.
+						//		Like dojo/store/DataStore.get() except returns native item.
 						var deferred = new Deferred();
 						this.fetchItemByIdentity({
 							identity: id,
@@ -88,13 +81,14 @@ define([
 					},
 					query: function(query, options){
 						// summary:
-						//		Queries the store for objects.   Like dojo.store.DataStore.query()
+						//		Queries the store for objects.   Like dojo/store/DataStore.query()
 						//		except returned Deferred contains array of native items.
 						var deferred = new Deferred(function(){ fetchHandle.abort && fetchHandle.abort(); });
+						deferred.total = new Deferred();
 						var fetchHandle = this.fetch(lang.mixin({
 							query: query,
 							onBegin: function(count){
-								deferred.total = count;
+								deferred.total.resolve(count);
 							},
 							onComplete: function(results){
 								deferred.resolve(results);
@@ -113,15 +107,16 @@ define([
 		postMixInProperties: function(){
 			// Since _setValueAttr() depends on this.store, _setStoreAttr() needs to execute first.
 			// Unfortunately, without special code, it ends up executing second.
-			if(this.params.store){
-				this._setStoreAttr(this.params.store);
+			var store = this.params.store || this.store;
+			if(store){
+				this._setStoreAttr(store);
 			}
 
 			this.inherited(arguments);
 
 			// User may try to access this.store.getValue() etc.  in a custom labelFunc() function.
 			// It's not available with the new data store for handling inline <option> tags, so add it.
-			if(!this.params.store){
+			if(!this.params.store && !this.store._oldAPI){
 				var clazz = this.declaredClass;
 				lang.mixin(this.store, {
 					getValue: function(item, attr){
diff --git a/dijit/form/ComboButton.js b/dijit/form/ComboButton.js
index 3d7dfc7..45316a0 100644
--- a/dijit/form/ComboButton.js
+++ b/dijit/form/ComboButton.js
@@ -1,89 +1,83 @@
 define([
 	"dojo/_base/declare", // declare
-	"dojo/_base/event", // event.stop
 	"dojo/keys", // keys
-	"../focus",		// focus.focus()
+	"../focus", // focus.focus()
 	"./DropDownButton",
 	"dojo/text!./templates/ComboButton.html"
-], function(declare, event, keys, focus, DropDownButton, template){
+], function(declare, keys, focus, DropDownButton, template){
 
-/*=====
-	var DropDownButton = dijit.form.DropDownButton;
-=====*/
+	// module:
+	//		dijit/form/ComboButton
 
-// module:
-//		dijit/form/ComboButton
-// summary:
-//		A combination button and drop-down button.
+	return declare("dijit.form.ComboButton", DropDownButton, {
+		// summary:
+		//		A combination button and drop-down button.
+		//		Users can click one side to "press" the button, or click an arrow
+		//		icon to display the drop down.
+		//
+		// example:
+		// |	<button data-dojo-type="dijit/form/ComboButton" onClick="...">
+		// |		<span>Hello world</span>
+		// |		<div data-dojo-type="dijit/Menu">...</div>
+		// |	</button>
+		//
+		// example:
+		// |	var button1 = new ComboButton({label: "hello world", onClick: foo, dropDown: "myMenu"});
+		// |	dojo.body().appendChild(button1.domNode);
+		//
 
-return declare("dijit.form.ComboButton", DropDownButton, {
-	// summary:
-	//		A combination button and drop-down button.
-	//		Users can click one side to "press" the button, or click an arrow
-	//		icon to display the drop down.
-	//
-	// example:
-	// |	<button data-dojo-type="dijit.form.ComboButton" onClick="...">
-	// |		<span>Hello world</span>
-	// |		<div data-dojo-type="dijit.Menu">...</div>
-	// |	</button>
-	//
-	// example:
-	// |	var button1 = new dijit.form.ComboButton({label: "hello world", onClick: foo, dropDown: "myMenu"});
-	// |	dojo.body().appendChild(button1.domNode);
-	//
+		templateString: template,
 
-	templateString: template,
+		// Map widget attributes to DOMNode attributes.
+		_setIdAttr: "", // override _FormWidgetMixin which puts id on the focusNode
+		_setTabIndexAttr: ["focusNode", "titleNode"],
+		_setTitleAttr: "titleNode",
 
-	// Map widget attributes to DOMNode attributes.
-	_setIdAttr: "",	// override _FormWidgetMixin which puts id on the focusNode
-	_setTabIndexAttr: ["focusNode", "titleNode"],
-	_setTitleAttr: "titleNode",
+		// optionsTitle: String
+		//		Text that describes the options menu (accessibility)
+		optionsTitle: "",
 
-	// optionsTitle: String
-	//		Text that describes the options menu (accessibility)
-	optionsTitle: "",
+		baseClass: "dijitComboButton",
 
-	baseClass: "dijitComboButton",
+		// Set classes like dijitButtonContentsHover or dijitArrowButtonActive depending on
+		// mouse action over specified node
+		cssStateNodes: {
+			"buttonNode": "dijitButtonNode",
+			"titleNode": "dijitButtonContents",
+			"_popupStateNode": "dijitDownArrowButton"
+		},
 
-	// Set classes like dijitButtonContentsHover or dijitArrowButtonActive depending on
-	// mouse action over specified node
-	cssStateNodes: {
-		"buttonNode": "dijitButtonNode",
-		"titleNode": "dijitButtonContents",
-		"_popupStateNode": "dijitDownArrowButton"
-	},
+		_focusedNode: null,
 
-	_focusedNode: null,
+		_onButtonKeyDown: function(/*Event*/ evt){
+			// summary:
+			//		Handler for right arrow key when focus is on left part of button
+			if(evt.keyCode == keys[this.isLeftToRight() ? "RIGHT_ARROW" : "LEFT_ARROW"]){
+				focus.focus(this._popupStateNode);
+				evt.stopPropagation();
+				evt.preventDefault();
+			}
+		},
 
-	_onButtonKeyPress: function(/*Event*/ evt){
-		// summary:
-		//		Handler for right arrow key when focus is on left part of button
-		if(evt.charOrCode == keys[this.isLeftToRight() ? "RIGHT_ARROW" : "LEFT_ARROW"]){
-			focus.focus(this._popupStateNode);
-			event.stop(evt);
-		}
-	},
+		_onArrowKeyDown: function(/*Event*/ evt){
+			// summary:
+			//		Handler for left arrow key when focus is on right part of button
+			if(evt.keyCode == keys[this.isLeftToRight() ? "LEFT_ARROW" : "RIGHT_ARROW"]){
+				focus.focus(this.titleNode);
+				evt.stopPropagation();
+				evt.preventDefault();
+			}
+		},
 
-	_onArrowKeyPress: function(/*Event*/ evt){
-		// summary:
-		//		Handler for left arrow key when focus is on right part of button
-		if(evt.charOrCode == keys[this.isLeftToRight() ? "LEFT_ARROW" : "RIGHT_ARROW"]){
-			focus.focus(this.titleNode);
-			event.stop(evt);
+		focus: function(/*String*/ position){
+			// summary:
+			//		Focuses this widget to according to position, if specified,
+			//		otherwise on arrow node
+			// position:
+			//		"start" or "end"
+			if(!this.disabled){
+				focus.focus(position == "start" ? this.titleNode : this._popupStateNode);
+			}
 		}
-	},
-
-	focus: function(/*String*/ position){
-		// summary:
-		//		Focuses this widget to according to position, if specified,
-		//		otherwise on arrow node
-		// position:
-		//		"start" or "end"
-		if(!this.disabled){
-			focus.focus(position == "start" ? this.titleNode : this._popupStateNode);
-		}
-	}
-});
-
+	});
 });
diff --git a/dijit/form/CurrencyTextBox.js b/dijit/form/CurrencyTextBox.js
index 191ac7d..7294b12 100644
--- a/dijit/form/CurrencyTextBox.js
+++ b/dijit/form/CurrencyTextBox.js
@@ -5,27 +5,18 @@ define([
 	"./NumberTextBox"
 ], function(currency, declare, lang, NumberTextBox){
 
-/*=====
-	var NumberTextBox = dijit.form.NumberTextBox;
-=====*/
-
 	// module:
 	//		dijit/form/CurrencyTextBox
-	// summary:
-	//		A validating currency textbox
-
 
 	/*=====
-	declare(
-		"dijit.form.CurrencyTextBox.__Constraints",
-		[dijit.form.NumberTextBox.__Constraints, currency.__FormatOptions, currency.__ParseOptions], {
+	var __Constraints = declare([NumberTextBox.__Constraints, currency.__FormatOptions, currency.__ParseOptions], {
 		// summary:
 		//		Specifies both the rules on valid/invalid values (minimum, maximum,
 		//		number of required decimal places), and also formatting options for
 		//		displaying the value when the field is not focused (currency symbol,
 		//		etc.)
 		// description:
-		//		Follows the pattern of `dijit.form.NumberTextBox.constraints`.
+		//		Follows the pattern of `dijit/form/NumberTextBox.__Constraints`.
 		//		In general developers won't need to set this parameter
 		// example:
 		//		To ensure that the user types in the cents (for example, 1.00 instead of just 1):
@@ -37,7 +28,7 @@ define([
 		// summary:
 		//		A validating currency textbox
 		// description:
-		//		CurrencyTextBox is similar to `dijit.form.NumberTextBox` but has a few
+		//		CurrencyTextBox is similar to `dijit/form/NumberTextBox` but has a few
 		//		extra features related to currency:
 		//
 		//		1. After specifying the currency type (american dollars, euros, etc.) it automatically
@@ -50,36 +41,30 @@ define([
 		currency: "",
 
 		/*=====
-		// constraints: dijit.form.CurrencyTextBox.__Constraints
+		// constraints: __Constraints
 		//		Despite the name, this parameter specifies both constraints on the input
 		//		(including minimum/maximum allowed values) as well as
-		//		formatting options.  See `dijit.form.CurrencyTextBox.__Constraints` for details.
+		//		formatting options.
 		constraints: {},
 		======*/
 
 		baseClass: "dijitTextBox dijitCurrencyTextBox",
 
-		// Override regExpGen ValidationTextBox.regExpGen().... we use a reg-ex generating function rather
-		// than a straight regexp to deal with locale  (plus formatting options too?)
-		regExpGen: function(constraints){
-			// if focused, accept either currency data or NumberTextBox format
-			return '(' + (this.focused ? this.inherited(arguments, [ lang.mixin({}, constraints, this.editOptions) ]) + '|' : '')
-				+ currency.regexp(constraints) + ')';
-		},
-
 		// Override NumberTextBox._formatter to deal with currencies, ex: converts "123.45" to "$123.45"
 		_formatter: currency.format,
 
 		_parser: currency.parse,
 
+		_regExpGenerator: currency.regexp,
+
 		parse: function(/*String*/ value, /*Object*/ constraints){
 			// summary:
-			// 		Parses string value as a Currency, according to the constraints object
+			//		Parses string value as a Currency, according to the constraints object
 			// tags:
-			// 		protected extension
+			//		protected extension
 			var v = this.inherited(arguments);
 			if(isNaN(v) && /\d+/.test(value)){ // currency parse failed, but it could be because they are using NumberTextBox format so try its parse
-				v = lang.hitch(lang.mixin({}, this, { _parser: NumberTextBox.prototype._parser }), "inherited")(arguments);
+				v = lang.hitch(lang.delegate(this, { _parser: NumberTextBox.prototype._parser }), "inherited")(arguments);
 			}
 			return v;
 		},
diff --git a/dijit/form/DataList.js b/dijit/form/DataList.js
index 4d6a9f2..407f6b0 100644
--- a/dijit/form/DataList.js
+++ b/dijit/form/DataList.js
@@ -3,18 +3,16 @@ define([
 	"dojo/dom", // dom.byId
 	"dojo/_base/lang", // lang.trim
 	"dojo/query", // query
-	"dojo/store/Memory", // dojo.store.Memory
+	"dojo/store/Memory",
 	"../registry"	// registry.add registry.remove
 ], function(declare, dom, lang, query, MemoryStore, registry){
 
 	// module:
 	//		dijit/form/DataList
-	// summary:
-	//		Inefficient but small data store specialized for inlined data via OPTION tags
 
 	function toItem(/*DOMNode*/ option){
 		// summary:
-		//		Convert <option> node to hash
+		//		Convert `<option>` node to hash
 		return {
 			id: option.value,
 			value: option.value,
@@ -33,7 +31,16 @@ define([
 		//	|		<option value="AL">Alabama</option>
 		//	|		...
 
-		constructor: function(/*Object?*/ params, /*DomNode|String*/ srcNodeRef){
+		constructor: function(params, srcNodeRef){
+			// summary:
+			//		Create the widget.
+			// params: Object|null
+			//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+			//		and functions, typically callbacks like onClick.
+			//		The hash can contain any of the widget's properties, excluding read-only properties.
+			// srcNodeRef: DOMNode|String
+			//		Attach widget to this DOM node.
+
 			// store pointer to original DOM tree
 			this.domNode = dom.byId(srcNodeRef);
 
diff --git a/dijit/form/DateTextBox.js b/dijit/form/DateTextBox.js
index cd30a67..4defb62 100644
--- a/dijit/form/DateTextBox.js
+++ b/dijit/form/DateTextBox.js
@@ -4,31 +4,25 @@ define([
 	"./_DateTimeTextBox"
 ], function(declare, Calendar, _DateTimeTextBox){
 
-/*=====
-	var Calendar = dijit.Calendar;
-	var _DateTimeTextBox = dijit.form._DateTimeTextBox;
-=====*/
-
 	// module:
 	//		dijit/form/DateTextBox
-	// summary:
-	//		A validating, serializable, range-bound date text box with a drop down calendar
-
 
 	return declare("dijit.form.DateTextBox", _DateTimeTextBox, {
 		// summary:
 		//		A validating, serializable, range-bound date text box with a drop down calendar
-		//
-		//		Example:
-		// |	new dijit.form.DateTextBox({value: new Date(2009, 0, 20)})
-		//
-		//		Example:
-		// |	<input data-dojo-type='dijit.form.DateTextBox' value='2009-01-20'>
+		// example:
+		// |	new DateTextBox({value: new Date(2009, 0, 20)})
+		// example:
+		// |	<input data-dojo-type='dijit/form/DateTextBox' value='2009-01-20'>
 
 		baseClass: "dijitTextBox dijitComboBox dijitDateTextBox",
 		popupClass: Calendar,
 		_selector: "date",
 
+		// Prevent scrollbar on Calendar dropdown.  On iPad it often gets a scrollbar unnecessarily because Viewport
+		// thinks the keyboard is showing.  Even if the keyboard is showing, it disappears when the calendar gets focus.
+		maxHeight: Infinity,
+
 		// value: Date
 		//		The value of this widget as a JavaScript Date object, with only year/month/day specified.
 		//		If specified in markup, use the format specified in `stamp.fromISOString`.
diff --git a/dijit/form/DropDownButton.js b/dijit/form/DropDownButton.js
index 4561874..e2202b8 100644
--- a/dijit/form/DropDownButton.js
+++ b/dijit/form/DropDownButton.js
@@ -1,105 +1,99 @@
 define([
 	"dojo/_base/declare", // declare
-	"dojo/_base/lang",	// hitch
+	"dojo/_base/lang", // hitch
 	"dojo/query", // query
-	"../registry",	// registry.byNode
-	"../popup",		// dijit.popup2.hide
+	"../registry", // registry.byNode
+	"../popup", // dijit.popup2.hide
 	"./Button",
 	"../_Container",
 	"../_HasDropDown",
 	"dojo/text!./templates/DropDownButton.html"
 ], function(declare, lang, query, registry, popup, Button, _Container, _HasDropDown, template){
 
-/*=====
-	Button = dijit.form.Button;
-	_Container = dijit._Container;
-	_HasDropDown = dijit._HasDropDown;
-=====*/
+	// module:
+	//		dijit/form/DropDownButton
 
-// module:
-//		dijit/form/DropDownButton
-// summary:
-//		A button with a drop down
-
-
-return declare("dijit.form.DropDownButton", [Button, _Container, _HasDropDown], {
-	// summary:
-	//		A button with a drop down
-	//
-	// example:
-	// |	<button data-dojo-type="dijit.form.DropDownButton">
-	// |		Hello world
-	// |		<div data-dojo-type="dijit.Menu">...</div>
-	// |	</button>
-	//
-	// example:
-	// |	var button1 = new dijit.form.DropDownButton({ label: "hi", dropDown: new dijit.Menu(...) });
-	// |	win.body().appendChild(button1);
-	//
-
-	baseClass : "dijitDropDownButton",
-
-	templateString: template,
-
-	_fillContent: function(){
-		// Overrides Button._fillContent().
+	return declare("dijit.form.DropDownButton", [Button, _Container, _HasDropDown], {
+		// summary:
+		//		A button with a drop down
+		//
+		// example:
+		// |	<button data-dojo-type="dijit/form/DropDownButton">
+		// |		Hello world
+		// |		<div data-dojo-type="dijit/Menu">...</div>
+		// |	</button>
+		//
+		// example:
+		// |	var button1 = new DropDownButton({ label: "hi", dropDown: new dijit.Menu(...) });
+		// |	win.body().appendChild(button1);
 		//
-		// My inner HTML contains both the button contents and a drop down widget, like
-		// <DropDownButton>  <span>push me</span>  <Menu> ... </Menu> </DropDownButton>
-		// The first node is assumed to be the button content. The widget is the popup.
-
-		if(this.srcNodeRef){ // programatically created buttons might not define srcNodeRef
-			//FIXME: figure out how to filter out the widget and use all remaining nodes as button
-			//	content, not just nodes[0]
-			var nodes = query("*", this.srcNodeRef);
-			this.inherited(arguments, [nodes[0]]);
-
-			// save pointer to srcNode so we can grab the drop down widget after it's instantiated
-			this.dropDownContainer = this.srcNodeRef;
-		}
-	},
-
-	startup: function(){
-		if(this._started){ return; }
 
-		// the child widget from srcNodeRef is the dropdown widget.  Insert it in the page DOM,
-		// make it invisible, and store a reference to pass to the popup code.
-		if(!this.dropDown && this.dropDownContainer){
-			var dropDownNode = query("[widgetId]", this.dropDownContainer)[0];
-			this.dropDown = registry.byNode(dropDownNode);
-			delete this.dropDownContainer;
-		}
-		if(this.dropDown){
-			popup.hide(this.dropDown);
+		baseClass: "dijitDropDownButton",
+
+		templateString: template,
+
+		_fillContent: function(){
+			// Overrides Button._fillContent().
+			//
+			// My inner HTML contains both the button contents and a drop down widget, like
+			// <DropDownButton>  <span>push me</span>  <Menu> ... </Menu> </DropDownButton>
+			// The first node is assumed to be the button content. The widget is the popup.
+
+			if(this.srcNodeRef){ // programatically created buttons might not define srcNodeRef
+				//FIXME: figure out how to filter out the widget and use all remaining nodes as button
+				//	content, not just nodes[0]
+				var nodes = query("*", this.srcNodeRef);
+				this.inherited(arguments, [nodes[0]]);
+
+				// save pointer to srcNode so we can grab the drop down widget after it's instantiated
+				this.dropDownContainer = this.srcNodeRef;
+			}
+		},
+
+		startup: function(){
+			if(this._started){
+				return;
+			}
+
+			// the child widget from srcNodeRef is the dropdown widget.  Insert it in the page DOM,
+			// make it invisible, and store a reference to pass to the popup code.
+			if(!this.dropDown && this.dropDownContainer){
+				var dropDownNode = query("[widgetId]", this.dropDownContainer)[0];
+				if(dropDownNode){
+					this.dropDown = registry.byNode(dropDownNode);
+				}
+				delete this.dropDownContainer;
+			}
+			if(this.dropDown){
+				popup.hide(this.dropDown);
+			}
+
+			this.inherited(arguments);
+		},
+
+		isLoaded: function(){
+			// Returns whether or not we are loaded - if our dropdown has an href,
+			// then we want to check that.
+			var dropDown = this.dropDown;
+			return (!!dropDown && (!dropDown.href || dropDown.isLoaded));
+		},
+
+		loadDropDown: function(/*Function*/ callback){
+			// Default implementation assumes that drop down already exists,
+			// but hasn't loaded it's data (ex: ContentPane w/href).
+			// App must override if the drop down is lazy-created.
+			var dropDown = this.dropDown;
+			var handler = dropDown.on("load", lang.hitch(this, function(){
+				handler.remove();
+				callback();
+			}));
+			dropDown.refresh();		// tell it to load
+		},
+
+		isFocusable: function(){
+			// Overridden so that focus is handled by the _HasDropDown mixin, not by
+			// the _FormWidget mixin.
+			return this.inherited(arguments) && !this._mouseDown;
 		}
-
-		this.inherited(arguments);
-	},
-
-	isLoaded: function(){
-		// Returns whether or not we are loaded - if our dropdown has an href,
-		// then we want to check that.
-		var dropDown = this.dropDown;
-		return (!!dropDown && (!dropDown.href || dropDown.isLoaded));
-	},
-
-	loadDropDown: function(/*Function*/ callback){
-		// Default implementation assumes that drop down already exists,
-		// but hasn't loaded it's data (ex: ContentPane w/href).
-		// App must override if the drop down is lazy-created.
-		var dropDown = this.dropDown;
-		var handler = dropDown.on("load", lang.hitch(this, function(){
-			handler.remove();
-			callback();
-		}));
-		dropDown.refresh();		// tell it to load
-	},
-
-	isFocusable: function(){
-		// Overridden so that focus is handled by the _HasDropDown mixin, not by
-		// the _FormWidget mixin.
-		return this.inherited(arguments) && !this._mouseDown;
-	}
-});
-
+	});
 });
diff --git a/dijit/form/FilteringSelect.js b/dijit/form/FilteringSelect.js
index 2a687b6..b59ff8c 100644
--- a/dijit/form/FilteringSelect.js
+++ b/dijit/form/FilteringSelect.js
@@ -1,22 +1,13 @@
 define([
-	"dojo/data/util/filter", // filter.patternToRegExp
 	"dojo/_base/declare", // declare
-	"dojo/_base/Deferred", // Deferred.when
 	"dojo/_base/lang", // lang.mixin
+	"dojo/when",
 	"./MappedTextBox",
 	"./ComboBoxMixin"
-], function(filter, declare, Deferred, lang, MappedTextBox, ComboBoxMixin){
-
-/*=====
-	var MappedTextBox = dijit.form.MappedTextBox;
-	var ComboBoxMixin = dijit.form.ComboBoxMixin;
-=====*/
+], function(declare, lang, when, MappedTextBox, ComboBoxMixin){
 
 	// module:
 	//		dijit/form/FilteringSelect
-	// summary:
-	//		An enhanced version of the HTML SELECT tag, populated dynamically
-
 
 	return declare("dijit.form.FilteringSelect", [MappedTextBox, ComboBoxMixin], {
 		// summary:
@@ -33,17 +24,19 @@ define([
 		//		attribute on 1 of the child OPTION tags.
 		//
 		//		Similar features:
-		//			- There is a drop down list of possible values.
-		//			- You can only enter a value from the drop down list.  (You can't
-		//				enter an arbitrary value.)
-		//			- The value submitted with the form is the hidden value (ex: CA),
-		//				not the displayed value a.k.a. label (ex: California)
+		//
+		//		- There is a drop down list of possible values.
+		//		- You can only enter a value from the drop down list.  (You can't
+		//			enter an arbitrary value.)
+		//		- The value submitted with the form is the hidden value (ex: CA),
+		//			not the displayed value a.k.a. label (ex: California)
 		//
 		//		Enhancements over plain HTML version:
-		//			- If you type in some text then it will filter down the list of
-		//				possible values in the drop down list.
-		//			- List can be specified either as a static list or via a javascript
-		//				function (that can get the list from a server)
+		//
+		//		- If you type in some text then it will filter down the list of
+		//			possible values in the drop down list.
+		//		- List can be specified either as a static list or via a javascript
+		//			function (that can get the list from a server)
 
 		// required: Boolean
 		//		True (default) if user is required to enter a value into this field.
@@ -57,7 +50,7 @@ define([
 
 		isValid: function(){
 			// Overrides ValidationTextBox.isValid()
-			return this.item || (!this.required && this.get('displayedValue') == ""); // #5974
+			return !!this.item || (!this.required && this.get('displayedValue') == ""); // #5974
 		},
 
 		_refreshState: function(){
@@ -141,7 +134,7 @@ define([
 
 				var self = this;
 				this._lastQuery = value;
-				Deferred.when(this.store.get(value), function(item){
+				when(this.store.get(value), function(item){
 					self._callbackSetLabel(item? [item] : [], undefined, undefined, priorityChange);
 				});
 			}else{
@@ -199,10 +192,10 @@ define([
 					// remove this branch for 2.0
 					q = qs;
 				}else{
-					// Query on searchAttr is a regex for benefit of dojo.store.Memory,
-					// but with a toString() method to help dojo.store.JsonRest.
+					// Query on searchAttr is a regex for benefit of dojo/store/Memory,
+					// but with a toString() method to help dojo/store/JsonRest.
 					// Search string like "Co*" converted to regex like /^Co.*$/i.
-					q = filter.patternToRegExp(qs, this.ignoreCase);
+					q = this._patternToRegExp(qs);
 					q.toString = function(){ return qs; };
 				}
 				this._lastQuery = query[this.searchAttr] = q;
@@ -221,7 +214,7 @@ define([
 				};
 				lang.mixin(options, this.fetchProperties);
 				this._fetchHandle = this.store.query(query, options);
-				Deferred.when(this._fetchHandle, function(result){
+				when(this._fetchHandle, function(result){
 					_this._fetchHandle = null;
 					_this._callbackSetLabel(result || [], query, options, priorityChange);
 				}, function(err){
diff --git a/dijit/form/Form.js b/dijit/form/Form.js
index ca9266b..a53b9cf 100644
--- a/dijit/form/Form.js
+++ b/dijit/form/Form.js
@@ -1,26 +1,16 @@
 define([
 	"dojo/_base/declare", // declare
 	"dojo/dom-attr", // domAttr.set
-	"dojo/_base/event", // event.stop
 	"dojo/_base/kernel", // kernel.deprecated
-	"dojo/_base/sniff", // has("ie")
+	"dojo/sniff", // has("ie")
 	"../_Widget",
 	"../_TemplatedMixin",
 	"./_FormMixin",
 	"../layout/_ContentPaneResizeMixin"
-], function(declare, domAttr, event, kernel, has, _Widget, _TemplatedMixin, _FormMixin, _ContentPaneResizeMixin){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _FormMixin = dijit.form._FormMixin;
-	var _ContentPaneResizeMixin = dijit.layout._ContentPaneResizeMixin;
-=====*/
+], function(declare, domAttr, kernel, has, _Widget, _TemplatedMixin, _FormMixin, _ContentPaneResizeMixin){
 
 	// module:
 	//		dijit/form/Form
-	// summary:
-	//		Widget corresponding to HTML form tag, for validation and serialization
 
 
 	return declare("dijit.form.Form", [_Widget, _TemplatedMixin, _FormMixin, _ContentPaneResizeMixin], {
@@ -28,7 +18,7 @@ define([
 		//		Widget corresponding to HTML form tag, for validation and serialization
 		//
 		// example:
-		//	|	<form data-dojo-type="dijit.form.Form" id="myForm">
+		//	|	<form data-dojo-type="dijit/form/Form" id="myForm">
 		//	|		Name: <input type="text" name="name" />
 		//	|	</form>
 		//	|	myObj = {name: "John Doe"};
@@ -90,9 +80,11 @@ define([
 		},
 
 		_setEncTypeAttr: function(/*String*/ value){
-			this.encType = value;
 			domAttr.set(this.domNode, "encType", value);
-			if(has("ie")){ this.domNode.encoding = value; }
+			if(has("ie")){
+				this.domNode.encoding = value;
+			}
+			this._set("encType", value);
 		},
 
 		reset: function(/*Event?*/ e){
@@ -104,9 +96,10 @@ define([
 			var faux = {
 				returnValue: true, // the IE way
 				preventDefault: function(){ // not IE
-							this.returnValue = false;
-						},
-				stopPropagation: function(){},
+					this.returnValue = false;
+				},
+				stopPropagation: function(){
+				},
 				currentTarget: e ? e.target : this.domNode,
 				target: e ? e.target : this.domNode
 			};
@@ -129,7 +122,8 @@ define([
 
 		_onReset: function(e){
 			this.reset(e);
-			event.stop(e);
+			e.stopPropagation();
+			e.preventDefault();
 			return false;
 		},
 
@@ -142,7 +136,8 @@ define([
 				this.execute(this.getValues());
 			}
 			if(this.onSubmit(e) === false){ // only exactly false stops submit
-				event.stop(e);
+				e.stopPropagation();
+				e.preventDefault();
 			}
 		},
 
diff --git a/dijit/form/HorizontalRule.js b/dijit/form/HorizontalRule.js
index 6a1a391..715223b 100644
--- a/dijit/form/HorizontalRule.js
+++ b/dijit/form/HorizontalRule.js
@@ -1,76 +1,67 @@
 define([
-	"dojo/_base/declare",	// declare
+	"dojo/_base/declare", // declare
 	"../_Widget",
 	"../_TemplatedMixin"
 ], function(declare, _Widget, _TemplatedMixin){
 
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-=====*/
+	// module:
+	//		dijit/form/HorizontalRule
 
-// module:
-//		dijit/form/HorizontalRule
-// summary:
-//		Hash marks for `dijit.form.HorizontalSlider`
+	return declare("dijit.form.HorizontalRule", [_Widget, _TemplatedMixin], {
+		// summary:
+		//		Hash marks for `dijit/form/HorizontalSlider`
 
+		templateString: '<div class="dijitRuleContainer dijitRuleContainerH"></div>',
 
-return declare("dijit.form.HorizontalRule", [_Widget, _TemplatedMixin], {
-	// summary:
-	//		Hash marks for `dijit.form.HorizontalSlider`
+		// count: Integer
+		//		Number of hash marks to generate
+		count: 3,
 
-	templateString: '<div class="dijitRuleContainer dijitRuleContainerH"></div>',
+		// container: String
+		//		For HorizontalSlider, this is either "topDecoration" or "bottomDecoration",
+		//		and indicates whether this rule goes above or below the slider.
+		container: "containerNode",
 
-	// count: Integer
-	//		Number of hash marks to generate
-	count: 3,
+		// ruleStyle: String
+		//		CSS style to apply to individual hash marks
+		ruleStyle: "",
 
-	// container: String
-	//		For HorizontalSlider, this is either "topDecoration" or "bottomDecoration",
-	//		and indicates whether this rule goes above or below the slider.
-	container: "containerNode",
+		_positionPrefix: '<div class="dijitRuleMark dijitRuleMarkH" style="left:',
+		_positionSuffix: '%;',
+		_suffix: '"></div>',
 
-	// ruleStyle: String
-	//		CSS style to apply to individual hash marks
-	ruleStyle: "",
+		_genHTML: function(pos){
+			return this._positionPrefix + pos + this._positionSuffix + this.ruleStyle + this._suffix;
+		},
 
-	_positionPrefix: '<div class="dijitRuleMark dijitRuleMarkH" style="left:',
-	_positionSuffix: '%;',
-	_suffix: '"></div>',
+		// _isHorizontal: [protected extension] Boolean
+		//		VerticalRule will override this...
+		_isHorizontal: true,
 
-	_genHTML: function(pos){
-		return this._positionPrefix + pos + this._positionSuffix + this.ruleStyle + this._suffix;
-	},
+		buildRendering: function(){
+			this.inherited(arguments);
 
-	// _isHorizontal: [protected extension] Boolean
-	//		VerticalRule will override this...
-	_isHorizontal: true,
-
-	buildRendering: function(){
-		this.inherited(arguments);
-
-		var innerHTML;
-		if(this.count == 1){
-			innerHTML = this._genHTML(50, 0);
-		}else{
-			var i;
-			var interval = 100 / (this.count-1);
-			if(!this._isHorizontal || this.isLeftToRight()){
-				innerHTML = this._genHTML(0, 0);
-				for(i=1; i < this.count-1; i++){
-					innerHTML += this._genHTML(interval*i, i);
-				}
-				innerHTML += this._genHTML(100, this.count-1);
+			var innerHTML;
+			if(this.count == 1){
+				innerHTML = this._genHTML(50, 0);
 			}else{
-				innerHTML = this._genHTML(100, 0);
-				for(i=1; i < this.count-1; i++){
-					innerHTML += this._genHTML(100-interval*i, i);
+				var i;
+				var interval = 100 / (this.count - 1);
+				if(!this._isHorizontal || this.isLeftToRight()){
+					innerHTML = this._genHTML(0, 0);
+					for(i = 1; i < this.count - 1; i++){
+						innerHTML += this._genHTML(interval * i, i);
+					}
+					innerHTML += this._genHTML(100, this.count - 1);
+				}else{
+					innerHTML = this._genHTML(100, 0);
+					for(i = 1; i < this.count - 1; i++){
+						innerHTML += this._genHTML(100 - interval * i, i);
+					}
+					innerHTML += this._genHTML(0, this.count - 1);
 				}
-				innerHTML += this._genHTML(0, this.count-1);
 			}
+			this.domNode.innerHTML = innerHTML;
 		}
-		this.domNode.innerHTML = innerHTML;
-	}
-});
-
+	});
 });
diff --git a/dijit/form/HorizontalRuleLabels.js b/dijit/form/HorizontalRuleLabels.js
index dc3da11..e499150 100644
--- a/dijit/form/HorizontalRuleLabels.js
+++ b/dijit/form/HorizontalRuleLabels.js
@@ -1,99 +1,122 @@
 define([
-	"dojo/_base/declare",	// declare
+	"dojo/_base/declare", // declare
+	"dojo/has",
 	"dojo/number", // number.format
 	"dojo/query", // query
+	"dojo/_base/lang", // lang
 	"./HorizontalRule"
-], function(declare, number, query, HorizontalRule){
+], function(declare, has, number, query, lang, HorizontalRule){
 
-/*=====
-	var HorizontalRule = dijit.form.HorizontalRule;
-=====*/
+	// module:
+	//		dijit/form/HorizontalRuleLabels
 
-// module:
-//		dijit/form/HorizontalRuleLabels
-// summary:
-//		Labels for `dijit.form.HorizontalSlider`
-
-return declare("dijit.form.HorizontalRuleLabels", HorizontalRule, {
-	// summary:
-	//		Labels for `dijit.form.HorizontalSlider`
-
-	templateString: '<div class="dijitRuleContainer dijitRuleContainerH dijitRuleLabelsContainer dijitRuleLabelsContainerH"></div>',
-
-	// labelStyle: String
-	//		CSS style to apply to individual text labels
-	labelStyle: "",
-
-	// labels: String[]?
-	//		Array of text labels to render - evenly spaced from left-to-right or bottom-to-top.
-	//		Alternately, minimum and maximum can be specified, to get numeric labels.
-	labels: [],
-
-	// numericMargin: Integer
-	//		Number of generated numeric labels that should be rendered as '' on the ends when labels[] are not specified
-	numericMargin: 0,
-
-	// numericMinimum: Integer
-	//		Leftmost label value for generated numeric labels when labels[] are not specified
-	minimum: 0,
-
-	// numericMaximum: Integer
-	//		Rightmost label value for generated numeric labels when labels[] are not specified
-	maximum: 1,
-
-	// constraints: Object
-	//		pattern, places, lang, et al (see dojo.number) for generated numeric labels when labels[] are not specified
-	constraints: {pattern:"#%"},
-
-	_positionPrefix: '<div class="dijitRuleLabelContainer dijitRuleLabelContainerH" style="left:',
-	_labelPrefix: '"><div class="dijitRuleLabel dijitRuleLabelH">',
-	_suffix: '</div></div>',
-
-	_calcPosition: function(pos){
+	var HorizontalRuleLabels = declare("dijit.form.HorizontalRuleLabels", HorizontalRule, {
 		// summary:
-		//		Returns the value to be used in HTML for the label as part of the left: attribute
-		// tags:
-		//		protected extension
-		return pos;
-	},
-
-	_genHTML: function(pos, ndx){
-		return this._positionPrefix + this._calcPosition(pos) + this._positionSuffix + this.labelStyle + this._labelPrefix + this.labels[ndx] + this._suffix;
-	},
+		//		Labels for `dijit/form/HorizontalSlider`
+
+		templateString: '<div class="dijitRuleContainer dijitRuleContainerH dijitRuleLabelsContainer dijitRuleLabelsContainerH"></div>',
+
+		// labelStyle: String
+		//		CSS style to apply to individual text labels
+		labelStyle: "",
+
+		// labels: String[]?
+		//		Array of text labels to render - evenly spaced from left-to-right or bottom-to-top.
+		//		Alternately, minimum and maximum can be specified, to get numeric labels.
+		labels: [],
+
+		// numericMargin: Integer
+		//		Number of generated numeric labels that should be rendered as '' on the ends when labels[] are not specified
+		numericMargin: 0,
+
+		// numericMinimum: Integer
+		//		Leftmost label value for generated numeric labels when labels[] are not specified
+		minimum: 0,
+
+		// numericMaximum: Integer
+		//		Rightmost label value for generated numeric labels when labels[] are not specified
+		maximum: 1,
+
+		// constraints: Object
+		//		pattern, places, lang, et al (see dojo.number) for generated numeric labels when labels[] are not specified
+		constraints: {pattern: "#%"},
+
+		_positionPrefix: '<div class="dijitRuleLabelContainer dijitRuleLabelContainerH" style="left:',
+		_labelPrefix: '"><div class="dijitRuleLabel dijitRuleLabelH">',
+		_suffix: '</div></div>',
+
+		_calcPosition: function(pos){
+			// summary:
+			//		Returns the value to be used in HTML for the label as part of the left: attribute
+			// tags:
+			//		protected extension
+			return pos;
+		},
+
+		_genHTML: function(pos, ndx){
+			var label = this.labels[ndx];
+			return this._positionPrefix + this._calcPosition(pos) + this._positionSuffix + this.labelStyle +
+				this._genDirectionHTML(label) +
+				this._labelPrefix + label + this._suffix;
+		},
+
+		_genDirectionHTML: function(label){
+			// extension point for bidi code
+			return "";
+		},
+
+		getLabels: function(){
+			// summary:
+			//		Overridable function to return array of labels to use for this slider.
+			//		Can specify a getLabels() method instead of a labels[] array, or min/max attributes.
+			// tags:
+			//		protected extension
+
+			// if the labels array was not specified directly, then see if <li> children were
+			var labels = this.labels;
+			if(!labels.length && this.srcNodeRef){
+				// for markup creation, labels are specified as child elements
+				labels = query("> li", this.srcNodeRef).map(function(node){
+					return String(node.innerHTML);
+				});
+			}
+			// if the labels were not specified directly and not as <li> children, then calculate numeric labels
+			if(!labels.length && this.count > 1){
+				var start = this.minimum;
+				var inc = (this.maximum - start) / (this.count - 1);
+				for(var i = 0; i < this.count; i++){
+					labels.push((i < this.numericMargin || i >= (this.count - this.numericMargin)) ? '' : number.format(start, this.constraints));
+					start += inc;
+				}
+			}
+			return labels;
+		},
 
-	getLabels: function(){
-		// summary:
-		//		Overridable function to return array of labels to use for this slider.
-		//		Can specify a getLabels() method instead of a labels[] array, or min/max attributes.
-		// tags:
-		//		protected extension
-
-		// if the labels array was not specified directly, then see if <li> children were
-		var labels = this.labels;
-		if(!labels.length){
-			// for markup creation, labels are specified as child elements
-			labels = query("> li", this.srcNodeRef).map(function(node){
-				return String(node.innerHTML);
-			});
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			this.labels = this.getLabels();
+			this.count = this.labels.length;
 		}
-		this.srcNodeRef.innerHTML = '';
-		// if the labels were not specified directly and not as <li> children, then calculate numeric labels
-		if(!labels.length && this.count > 1){
-			var start = this.minimum;
-			var inc = (this.maximum - start) / (this.count-1);
-			for(var i=0; i < this.count; i++){
-				labels.push((i < this.numericMargin || i >= (this.count-this.numericMargin)) ? '' : number.format(start, this.constraints));
-				start += inc;
+	});
+
+	if(has("dojo-bidi")){
+		HorizontalRuleLabels.extend({
+			_setTextDirAttr: function(textDir){
+				if(this.textDir != textDir){
+					this._set("textDir", textDir);
+					query(".dijitRuleLabelContainer", this.domNode).forEach(
+						lang.hitch(this, function(labelNode){
+							labelNode.style.direction = this.getTextDir(labelNode.innerText || labelNode.textContent || "");
+						})
+					);
+				}
+			},
+
+			_genDirectionHTML: function(label){
+				return (this.textDir ? ("direction:" + this.getTextDir(label) + ";") : "")
 			}
-		}
-		return labels;
-	},
-
-	postMixInProperties: function(){
-		this.inherited(arguments);
-		this.labels = this.getLabels();
-		this.count = this.labels.length;
+		});
 	}
-});
 
+	return HorizontalRuleLabels;
 });
diff --git a/dijit/form/HorizontalSlider.js b/dijit/form/HorizontalSlider.js
index 72fd776..76b0868 100644
--- a/dijit/form/HorizontalSlider.js
+++ b/dijit/form/HorizontalSlider.js
@@ -2,356 +2,382 @@ define([
 	"dojo/_base/array", // array.forEach
 	"dojo/_base/declare", // declare
 	"dojo/dnd/move",
-	"dojo/_base/event", // event.stop
 	"dojo/_base/fx", // fx.animateProperty
 	"dojo/dom-geometry", // domGeometry.position
 	"dojo/dom-style", // domStyle.getComputedStyle
 	"dojo/keys", // keys.DOWN_ARROW keys.END keys.HOME keys.LEFT_ARROW keys.PAGE_DOWN keys.PAGE_UP keys.RIGHT_ARROW keys.UP_ARROW
 	"dojo/_base/lang", // lang.hitch
-	"dojo/_base/sniff", // has("ie") has("mozilla")
+	"dojo/sniff", // has("ie") has("mozilla")
 	"dojo/dnd/Moveable", // Moveable
 	"dojo/dnd/Mover", // Mover Mover.prototype.destroy.apply
 	"dojo/query", // query
-	"../registry", // registry.findWidgets
-	"../focus",		// focus.focus()
+	"dojo/mouse", // mouse.wheel
+	"dojo/on",
+	"../_base/manager", // defaultDuration
+	"../focus", // focus.focus()
 	"../typematic",
 	"./Button",
 	"./_FormValueWidget",
 	"../_Container",
 	"dojo/text!./templates/HorizontalSlider.html"
-], function(array, declare, move, event, fx, domGeometry, domStyle, keys, lang, has, Moveable, Mover, query,
-			registry, focus, typematic, Button, _FormValueWidget, _Container, template){
-
-/*=====
-	var Button = dijit.form.Button;
-	var _FormValueWidget = dijit.form._FormValueWidget;
-	var _Container = dijit._Container;
-=====*/
-
-// module:
-//		dijit/form/HorizontalSlider
-// summary:
-//		A form widget that allows one to select a value with a horizontally draggable handle
-
-
-var _SliderMover = declare("dijit.form._SliderMover", Mover, {
-	onMouseMove: function(e){
-		var widget = this.widget;
-		var abspos = widget._abspos;
-		if(!abspos){
-			abspos = widget._abspos = domGeometry.position(widget.sliderBarContainer, true);
-			widget._setPixelValue_ = lang.hitch(widget, "_setPixelValue");
-			widget._isReversed_ = widget._isReversed();
+], function(array, declare, move, fx, domGeometry, domStyle, keys, lang, has, Moveable, Mover, query, mouse, on,
+			manager, focus, typematic, Button, _FormValueWidget, _Container, template){
+
+	// module:
+	//		dijit/form/HorizontalSlider
+
+	var _SliderMover = declare("dijit.form._SliderMover", Mover, {
+		onMouseMove: function(e){
+			var widget = this.widget;
+			var abspos = widget._abspos;
+			if(!abspos){
+				abspos = widget._abspos = domGeometry.position(widget.sliderBarContainer, true);
+				widget._setPixelValue_ = lang.hitch(widget, "_setPixelValue");
+				widget._isReversed_ = widget._isReversed();
+			}
+			var pixelValue = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord];
+			widget._setPixelValue_(widget._isReversed_ ? (abspos[widget._pixelCount] - pixelValue) : pixelValue, abspos[widget._pixelCount], false);
+		},
+
+		destroy: function(e){
+			Mover.prototype.destroy.apply(this, arguments);
+			var widget = this.widget;
+			widget._abspos = null;
+			widget._setValueAttr(widget.value, true);
 		}
-		var pixelValue = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord];
-		widget._setPixelValue_(widget._isReversed_ ? (abspos[widget._pixelCount]-pixelValue) : pixelValue, abspos[widget._pixelCount], false);
-	},
-
-	destroy: function(e){
-		Mover.prototype.destroy.apply(this, arguments);
-		var widget = this.widget;
-		widget._abspos = null;
-		widget._setValueAttr(widget.value, true);
-	}
-});
+	});
 
-var HorizontalSlider = declare("dijit.form.HorizontalSlider", [_FormValueWidget, _Container], {
-	// summary:
-	//		A form widget that allows one to select a value with a horizontally draggable handle
-
-	templateString: template,
-
-	// Overrides FormValueWidget.value to indicate numeric value
-	value: 0,
-
-	// showButtons: [const] Boolean
-	//		Show increment/decrement buttons at the ends of the slider?
-	showButtons: true,
-
-	// minimum:: [const] Integer
-	//		The minimum value the slider can be set to.
-	minimum: 0,
-
-	// maximum: [const] Integer
-	//		The maximum value the slider can be set to.
-	maximum: 100,
-
-	// discreteValues: Integer
-	//		If specified, indicates that the slider handle has only 'discreteValues' possible positions,
-	//		and that after dragging the handle, it will snap to the nearest possible position.
-	//		Thus, the slider has only 'discreteValues' possible values.
-	//
-	//		For example, if minimum=10, maxiumum=30, and discreteValues=3, then the slider handle has
-	//		three possible positions, representing values 10, 20, or 30.
-	//
-	//		If discreteValues is not specified or if it's value is higher than the number of pixels
-	//		in the slider bar, then the slider handle can be moved freely, and the slider's value will be
-	//		computed/reported based on pixel position (in this case it will likely be fractional,
-	//		such as 123.456789).
-	discreteValues: Infinity,
-
-	// pageIncrement: Integer
-	//		If discreteValues is also specified, this indicates the amount of clicks (ie, snap positions)
-	//		that the slider handle is moved via pageup/pagedown keys.
-	//		If discreteValues is not specified, it indicates the number of pixels.
-	pageIncrement: 2,
-
-	// clickSelect: Boolean
-	//		If clicking the slider bar changes the value or not
-	clickSelect: true,
-
-	// slideDuration: Number
-	//		The time in ms to take to animate the slider handle from 0% to 100%,
-	//		when clicking the slider bar to make the handle move.
-	slideDuration: registry.defaultDuration,
-
-	// Map widget attributes to DOMNode attributes.
-	_setIdAttr: "",		// Override _FormWidget which sends id to focusNode
-
-	baseClass: "dijitSlider",
-
-	// Apply CSS classes to up/down arrows and handle per mouse state
-	cssStateNodes: {
-		incrementButton: "dijitSliderIncrementButton",
-		decrementButton: "dijitSliderDecrementButton",
-		focusNode: "dijitSliderThumb"
-	},
-
-	_mousePixelCoord: "pageX",
-	_pixelCount: "w",
-	_startingPixelCoord: "x",
-	_handleOffsetCoord: "left",
-	_progressPixelSize: "width",
-
-	_onKeyUp: function(/*Event*/ e){
-		if(this.disabled || this.readOnly || e.altKey || e.ctrlKey || e.metaKey){ return; }
-		this._setValueAttr(this.value, true);
-	},
-
-	_onKeyPress: function(/*Event*/ e){
-		if(this.disabled || this.readOnly || e.altKey || e.ctrlKey || e.metaKey){ return; }
-		switch(e.charOrCode){
-			case keys.HOME:
-				this._setValueAttr(this.minimum, false);
-				break;
-			case keys.END:
-				this._setValueAttr(this.maximum, false);
-				break;
-			// this._descending === false: if ascending vertical (min on top)
-			// (this._descending || this.isLeftToRight()): if left-to-right horizontal or descending vertical
-			case ((this._descending || this.isLeftToRight()) ? keys.RIGHT_ARROW : keys.LEFT_ARROW):
-			case (this._descending === false ? keys.DOWN_ARROW : keys.UP_ARROW):
-			case (this._descending === false ? keys.PAGE_DOWN : keys.PAGE_UP):
-				this.increment(e);
-				break;
-			case ((this._descending || this.isLeftToRight()) ? keys.LEFT_ARROW : keys.RIGHT_ARROW):
-			case (this._descending === false ? keys.UP_ARROW : keys.DOWN_ARROW):
-			case (this._descending === false ? keys.PAGE_UP : keys.PAGE_DOWN):
-				this.decrement(e);
-				break;
-			default:
+	var HorizontalSlider = declare("dijit.form.HorizontalSlider", [_FormValueWidget, _Container], {
+		// summary:
+		//		A form widget that allows one to select a value with a horizontally draggable handle
+
+		templateString: template,
+
+		// Overrides FormValueWidget.value to indicate numeric value
+		value: 0,
+
+		// showButtons: [const] Boolean
+		//		Show increment/decrement buttons at the ends of the slider?
+		showButtons: true,
+
+		// minimum: [const] Integer
+		//		The minimum value the slider can be set to.
+		minimum: 0,
+
+		// maximum: [const] Integer
+		//		The maximum value the slider can be set to.
+		maximum: 100,
+
+		// discreteValues: Integer
+		//		If specified, indicates that the slider handle has only 'discreteValues' possible positions,
+		//		and that after dragging the handle, it will snap to the nearest possible position.
+		//		Thus, the slider has only 'discreteValues' possible values.
+		//
+		//		For example, if minimum=10, maxiumum=30, and discreteValues=3, then the slider handle has
+		//		three possible positions, representing values 10, 20, or 30.
+		//
+		//		If discreteValues is not specified or if it's value is higher than the number of pixels
+		//		in the slider bar, then the slider handle can be moved freely, and the slider's value will be
+		//		computed/reported based on pixel position (in this case it will likely be fractional,
+		//		such as 123.456789).
+		discreteValues: Infinity,
+
+		// pageIncrement: Integer
+		//		If discreteValues is also specified, this indicates the amount of clicks (ie, snap positions)
+		//		that the slider handle is moved via pageup/pagedown keys.
+		//		If discreteValues is not specified, it indicates the number of pixels.
+		pageIncrement: 2,
+
+		// clickSelect: Boolean
+		//		If clicking the slider bar changes the value or not
+		clickSelect: true,
+
+		// slideDuration: Number
+		//		The time in ms to take to animate the slider handle from 0% to 100%,
+		//		when clicking the slider bar to make the handle move.
+		slideDuration: manager.defaultDuration,
+
+		// Map widget attributes to DOMNode attributes.
+		_setIdAttr: "", // Override _FormWidget which sends id to focusNode
+		_setNameAttr: "valueNode", // Override default behavior to send to focusNode
+
+		baseClass: "dijitSlider",
+
+		// Apply CSS classes to up/down arrows and handle per mouse state
+		cssStateNodes: {
+			incrementButton: "dijitSliderIncrementButton",
+			decrementButton: "dijitSliderDecrementButton",
+			focusNode: "dijitSliderThumb"
+		},
+
+		_mousePixelCoord: "pageX",
+		_pixelCount: "w",
+		_startingPixelCoord: "x",
+		_handleOffsetCoord: "left",
+		_progressPixelSize: "width",
+
+		_onKeyUp: function(/*Event*/ e){
+			if(this.disabled || this.readOnly || e.altKey || e.ctrlKey || e.metaKey){
 				return;
-		}
-		event.stop(e);
-	},
-
-	_onHandleClick: function(e){
-		if(this.disabled || this.readOnly){ return; }
-		if(!has("ie")){
-			// make sure you get focus when dragging the handle
-			// (but don't do on IE because it causes a flicker on mouse up (due to blur then focus)
-			focus.focus(this.sliderHandle);
-		}
-		event.stop(e);
-	},
+			}
+			this._setValueAttr(this.value, true);
+		},
 
-	_isReversed: function(){
-		// summary:
-		//		Returns true if direction is from right to left
-		// tags:
-		//		protected extension
-		return !this.isLeftToRight();
-	},
-
-	_onBarClick: function(e){
-		if(this.disabled || this.readOnly || !this.clickSelect){ return; }
-		focus.focus(this.sliderHandle);
-		event.stop(e);
-		var abspos = domGeometry.position(this.sliderBarContainer, true);
-		var pixelValue = e[this._mousePixelCoord] - abspos[this._startingPixelCoord];
-		this._setPixelValue(this._isReversed() ? (abspos[this._pixelCount] - pixelValue) : pixelValue, abspos[this._pixelCount], true);
-		this._movable.onMouseDown(e);
-	},
-
-	_setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean?*/ priorityChange){
-		if(this.disabled || this.readOnly){ return; }
-		var count = this.discreteValues;
-		if(count <= 1 || count == Infinity){ count = maxPixels; }
-		count--;
-		var pixelsPerValue = maxPixels / count;
-		var wholeIncrements = Math.round(pixelValue / pixelsPerValue);
-		this._setValueAttr(Math.max(Math.min((this.maximum-this.minimum)*wholeIncrements/count + this.minimum, this.maximum), this.minimum), priorityChange);
-	},
-
-	_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange){
-		// summary:
-		//		Hook so set('value', value) works.
-		this._set("value", value);
-		this.valueNode.value = value;
-		this.focusNode.setAttribute("aria-valuenow", value);
-		this.inherited(arguments);
-		var percent = (value - this.minimum) / (this.maximum - this.minimum);
-		var progressBar = (this._descending === false) ? this.remainingBar : this.progressBar;
-		var remainingBar = (this._descending === false) ? this.progressBar : this.remainingBar;
-		if(this._inProgressAnim && this._inProgressAnim.status != "stopped"){
-			this._inProgressAnim.stop(true);
-		}
-		if(priorityChange && this.slideDuration > 0 && progressBar.style[this._progressPixelSize]){
-			// animate the slider
-			var _this = this;
-			var props = {};
-			var start = parseFloat(progressBar.style[this._progressPixelSize]);
-			var duration = this.slideDuration * (percent-start/100);
-			if(duration == 0){ return; }
-			if(duration < 0){ duration = 0 - duration; }
-			props[this._progressPixelSize] = { start: start, end: percent*100, units:"%" };
-			this._inProgressAnim = fx.animateProperty({ node: progressBar, duration: duration,
-				onAnimate: function(v){
-					remainingBar.style[_this._progressPixelSize] = (100 - parseFloat(v[_this._progressPixelSize])) + "%";
-				},
-				onEnd: function(){
-					delete _this._inProgressAnim;
-				},
-				properties: props
-			});
-			this._inProgressAnim.play();
-		}else{
-			progressBar.style[this._progressPixelSize] = (percent*100) + "%";
-			remainingBar.style[this._progressPixelSize] = ((1-percent)*100) + "%";
-		}
-	},
-
-	_bumpValue: function(signedChange, /*Boolean?*/ priorityChange){
-		if(this.disabled || this.readOnly){ return; }
-		var s = domStyle.getComputedStyle(this.sliderBarContainer);
-		var c = domGeometry.getContentBox(this.sliderBarContainer, s);
-		var count = this.discreteValues;
-		if(count <= 1 || count == Infinity){ count = c[this._pixelCount]; }
-		count--;
-		var value = (this.value - this.minimum) * count / (this.maximum - this.minimum) + signedChange;
-		if(value < 0){ value = 0; }
-		if(value > count){ value = count; }
-		value = value * (this.maximum - this.minimum) / count + this.minimum;
-		this._setValueAttr(value, priorityChange);
-	},
-
-	_onClkBumper: function(val){
-		if(this.disabled || this.readOnly || !this.clickSelect){ return; }
-		this._setValueAttr(val, true);
-	},
-
-	_onClkIncBumper: function(){
-		this._onClkBumper(this._descending === false ? this.minimum : this.maximum);
-	},
-
-	_onClkDecBumper: function(){
-		this._onClkBumper(this._descending === false ? this.maximum : this.minimum);
-	},
-
-	decrement: function(/*Event*/ e){
-		// summary:
-		//		Decrement slider
-		// tags:
-		//		private
-		this._bumpValue(e.charOrCode == keys.PAGE_DOWN ? -this.pageIncrement : -1);
-	},
+		_onKeyDown: function(/*Event*/ e){
+			if(this.disabled || this.readOnly || e.altKey || e.ctrlKey || e.metaKey){
+				return;
+			}
+			switch(e.keyCode){
+				case keys.HOME:
+					this._setValueAttr(this.minimum, false);
+					break;
+				case keys.END:
+					this._setValueAttr(this.maximum, false);
+					break;
+				// this._descending === false: if ascending vertical (min on top)
+				// (this._descending || this.isLeftToRight()): if left-to-right horizontal or descending vertical
+				case ((this._descending || this.isLeftToRight()) ? keys.RIGHT_ARROW : keys.LEFT_ARROW):
+				case (this._descending === false ? keys.DOWN_ARROW : keys.UP_ARROW):
+				case (this._descending === false ? keys.PAGE_DOWN : keys.PAGE_UP):
+					this.increment(e);
+					break;
+				case ((this._descending || this.isLeftToRight()) ? keys.LEFT_ARROW : keys.RIGHT_ARROW):
+				case (this._descending === false ? keys.UP_ARROW : keys.DOWN_ARROW):
+				case (this._descending === false ? keys.PAGE_UP : keys.PAGE_DOWN):
+					this.decrement(e);
+					break;
+				default:
+					return;
+			}
+			e.stopPropagation();
+			e.preventDefault();
+		},
 
-	increment: function(/*Event*/ e){
-		// summary:
-		//		Increment slider
-		// tags:
-		//		private
-		this._bumpValue(e.charOrCode == keys.PAGE_UP ? this.pageIncrement : 1);
-	},
+		_onHandleClick: function(e){
+			if(this.disabled || this.readOnly){
+				return;
+			}
+			if(!has("ie")){
+				// make sure you get focus when dragging the handle
+				// (but don't do on IE because it causes a flicker on mouse up (due to blur then focus)
+				focus.focus(this.sliderHandle);
+			}
+			e.stopPropagation();
+			e.preventDefault();
+		},
+
+		_isReversed: function(){
+			// summary:
+			//		Returns true if direction is from right to left
+			// tags:
+			//		protected extension
+			return !this.isLeftToRight();
+		},
+
+		_onBarClick: function(e){
+			if(this.disabled || this.readOnly || !this.clickSelect){
+				return;
+			}
+			focus.focus(this.sliderHandle);
+			e.stopPropagation();
+			e.preventDefault();
+			var abspos = domGeometry.position(this.sliderBarContainer, true);
+			var pixelValue = e[this._mousePixelCoord] - abspos[this._startingPixelCoord];
+			this._setPixelValue(this._isReversed() ? (abspos[this._pixelCount] - pixelValue) : pixelValue, abspos[this._pixelCount], true);
+			this._movable.onMouseDown(e);
+		},
+
+		_setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean?*/ priorityChange){
+			if(this.disabled || this.readOnly){
+				return;
+			}
+			var count = this.discreteValues;
+			if(count <= 1 || count == Infinity){
+				count = maxPixels;
+			}
+			count--;
+			var pixelsPerValue = maxPixels / count;
+			var wholeIncrements = Math.round(pixelValue / pixelsPerValue);
+			this._setValueAttr(Math.max(Math.min((this.maximum - this.minimum) * wholeIncrements / count + this.minimum, this.maximum), this.minimum), priorityChange);
+		},
+
+		_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange){
+			// summary:
+			//		Hook so set('value', value) works.
+			this._set("value", value);
+			this.valueNode.value = value;
+			this.focusNode.setAttribute("aria-valuenow", value);
+			this.inherited(arguments);
+			var percent = (value - this.minimum) / (this.maximum - this.minimum);
+			var progressBar = (this._descending === false) ? this.remainingBar : this.progressBar;
+			var remainingBar = (this._descending === false) ? this.progressBar : this.remainingBar;
+			if(this._inProgressAnim && this._inProgressAnim.status != "stopped"){
+				this._inProgressAnim.stop(true);
+			}
+			if(priorityChange && this.slideDuration > 0 && progressBar.style[this._progressPixelSize]){
+				// animate the slider
+				var _this = this;
+				var props = {};
+				var start = parseFloat(progressBar.style[this._progressPixelSize]);
+				var duration = this.slideDuration * (percent - start / 100);
+				if(duration == 0){
+					return;
+				}
+				if(duration < 0){
+					duration = 0 - duration;
+				}
+				props[this._progressPixelSize] = { start: start, end: percent * 100, units: "%" };
+				this._inProgressAnim = fx.animateProperty({ node: progressBar, duration: duration,
+					onAnimate: function(v){
+						remainingBar.style[_this._progressPixelSize] = (100 - parseFloat(v[_this._progressPixelSize])) + "%";
+					},
+					onEnd: function(){
+						delete _this._inProgressAnim;
+					},
+					properties: props
+				});
+				this._inProgressAnim.play();
+			}else{
+				progressBar.style[this._progressPixelSize] = (percent * 100) + "%";
+				remainingBar.style[this._progressPixelSize] = ((1 - percent) * 100) + "%";
+			}
+		},
 
-	_mouseWheeled: function(/*Event*/ evt){
-		// summary:
-		//		Event handler for mousewheel where supported
-		event.stop(evt);
-		var janky = !has("mozilla");
-		var scroll = evt[(janky ? "wheelDelta" : "detail")] * (janky ? 1 : -1);
-		this._bumpValue(scroll < 0 ? -1 : 1, true); // negative scroll acts like a decrement
-	},
-
-	startup: function(){
-		if(this._started){ return; }
-
-		array.forEach(this.getChildren(), function(child){
-			if(this[child.container] != this.containerNode){
-				this[child.container].appendChild(child.domNode);
+		_bumpValue: function(signedChange, /*Boolean?*/ priorityChange){
+			if(this.disabled || this.readOnly){
+				return;
+			}
+			var s = domStyle.getComputedStyle(this.sliderBarContainer);
+			var c = domGeometry.getContentBox(this.sliderBarContainer, s);
+			var count = this.discreteValues;
+			if(count <= 1 || count == Infinity){
+				count = c[this._pixelCount];
+			}
+			count--;
+			var value = (this.value - this.minimum) * count / (this.maximum - this.minimum) + signedChange;
+			if(value < 0){
+				value = 0;
 			}
-		}, this);
+			if(value > count){
+				value = count;
+			}
+			value = value * (this.maximum - this.minimum) / count + this.minimum;
+			this._setValueAttr(value, priorityChange);
+		},
 
-		this.inherited(arguments);
-	},
+		_onClkBumper: function(val){
+			if(this.disabled || this.readOnly || !this.clickSelect){
+				return;
+			}
+			this._setValueAttr(val, true);
+		},
+
+		_onClkIncBumper: function(){
+			this._onClkBumper(this._descending === false ? this.minimum : this.maximum);
+		},
+
+		_onClkDecBumper: function(){
+			this._onClkBumper(this._descending === false ? this.maximum : this.minimum);
+		},
+
+		decrement: function(/*Event*/ e){
+			// summary:
+			//		Decrement slider
+			// tags:
+			//		private
+			this._bumpValue(e.keyCode == keys.PAGE_DOWN ? -this.pageIncrement : -1);
+		},
+
+		increment: function(/*Event*/ e){
+			// summary:
+			//		Increment slider
+			// tags:
+			//		private
+			this._bumpValue(e.keyCode == keys.PAGE_UP ? this.pageIncrement : 1);
+		},
+
+		_mouseWheeled: function(/*Event*/ evt){
+			// summary:
+			//		Event handler for mousewheel where supported
+			evt.stopPropagation();
+			evt.preventDefault();
+			this._bumpValue(evt.wheelDelta < 0 ? -1 : 1, true); // negative scroll acts like a decrement
+		},
+
+		startup: function(){
+			if(this._started){
+				return;
+			}
 
-	_typematicCallback: function(/*Number*/ count, /*Object*/ button, /*Event*/ e){
-		if(count == -1){
-			this._setValueAttr(this.value, true);
-		}else{
-			this[(button == (this._descending? this.incrementButton : this.decrementButton)) ? "decrement" : "increment"](e);
-		}
-	},
+			array.forEach(this.getChildren(), function(child){
+				if(this[child.container] != this.containerNode){
+					this[child.container].appendChild(child.domNode);
+				}
+			}, this);
 
-	buildRendering: function(){
-		this.inherited(arguments);
-		if(this.showButtons){
-			this.incrementButton.style.display="";
-			this.decrementButton.style.display="";
-		}
+			this.inherited(arguments);
+		},
 
-		// find any associated label element and add to slider focusnode.
-		var label = query('label[for="'+this.id+'"]');
-		if(label.length){
-			label[0].id = (this.id+"_label");
-			this.focusNode.setAttribute("aria-labelledby", label[0].id);
-		}
+		_typematicCallback: function(/*Number*/ count, /*Object*/ button, /*Event*/ e){
+			if(count == -1){
+				this._setValueAttr(this.value, true);
+			}else{
+				this[(button == (this._descending ? this.incrementButton : this.decrementButton)) ? "decrement" : "increment"](e);
+			}
+		},
 
-		this.focusNode.setAttribute("aria-valuemin", this.minimum);
-		this.focusNode.setAttribute("aria-valuemax", this.maximum);
-	},
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(this.showButtons){
+				this.incrementButton.style.display = "";
+				this.decrementButton.style.display = "";
+			}
 
-	postCreate: function(){
-		this.inherited(arguments);
+			// find any associated label element and add to slider focusnode.
+			var label = query('label[for="' + this.id + '"]');
+			if(label.length){
+				if(!label[0].id){
+					label[0].id = this.id + "_label";
+				}
+				this.focusNode.setAttribute("aria-labelledby", label[0].id);
+			}
 
-		if(this.showButtons){
-			this._connects.push(typematic.addMouseListener(
-				this.decrementButton, this, "_typematicCallback", 25, 500));
-			this._connects.push(typematic.addMouseListener(
-				this.incrementButton, this, "_typematicCallback", 25, 500));
-		}
-		this.connect(this.domNode, !has("mozilla") ? "onmousewheel" : "DOMMouseScroll", "_mouseWheeled");
+			this.focusNode.setAttribute("aria-valuemin", this.minimum);
+			this.focusNode.setAttribute("aria-valuemax", this.maximum);
+		},
 
-		// define a custom constructor for a SliderMover that points back to me
-		var mover = declare(_SliderMover, {
-			widget: this
-		});
-		this._movable = new Moveable(this.sliderHandle, {mover: mover});
+		postCreate: function(){
+			this.inherited(arguments);
 
-		this._layoutHackIE7();
-	},
+			if(this.showButtons){
+				this.own(
+					typematic.addMouseListener(this.decrementButton, this, "_typematicCallback", 25, 500),
+					typematic.addMouseListener(this.incrementButton, this, "_typematicCallback", 25, 500)
+				);
+			}
+			this.own(
+				on(this.domNode, mouse.wheel, lang.hitch(this, "_mouseWheeled"))
+			);
+
+			// define a custom constructor for a SliderMover that points back to me
+			var mover = declare(_SliderMover, {
+				widget: this
+			});
+			this._movable = new Moveable(this.sliderHandle, {mover: mover});
 
-	destroy: function(){
-		this._movable.destroy();
-		if(this._inProgressAnim && this._inProgressAnim.status != "stopped"){
-			this._inProgressAnim.stop(true);
+			this._layoutHackIE7();
+		},
+
+		destroy: function(){
+			this._movable.destroy();
+			if(this._inProgressAnim && this._inProgressAnim.status != "stopped"){
+				this._inProgressAnim.stop(true);
+			}
+			this.inherited(arguments);
 		}
-		this._supportingWidgets = registry.findWidgets(this.domNode); // tells destroy about pseudo-child widgets (ruler/labels)
-		this.inherited(arguments);
-	}
-});
+	});
 
-HorizontalSlider._Mover = _SliderMover;	// for monkey patching
+	HorizontalSlider._Mover = _SliderMover;	// for monkey patching
 
-return HorizontalSlider;
+	return HorizontalSlider;
 });
diff --git a/dijit/form/MappedTextBox.js b/dijit/form/MappedTextBox.js
index e528d87..955fa29 100644
--- a/dijit/form/MappedTextBox.js
+++ b/dijit/form/MappedTextBox.js
@@ -1,30 +1,23 @@
 define([
 	"dojo/_base/declare", // declare
+	"dojo/sniff", // has("msapp")
 	"dojo/dom-construct", // domConstruct.place
 	"./ValidationTextBox"
-], function(declare, domConstruct, ValidationTextBox){
-
-/*=====
-	var ValidationTextBox = dijit.form.ValidationTextBox;
-=====*/
+], function(declare, has, domConstruct, ValidationTextBox){
 
 	// module:
 	//		dijit/form/MappedTextBox
-	// summary:
-	//		A dijit.form.ValidationTextBox subclass which provides a base class for widgets that have
-	//		a visible formatted display value, and a serializable
-	//		value in a hidden input field which is actually sent to the server.
 
 	return declare("dijit.form.MappedTextBox", ValidationTextBox, {
 		// summary:
-		//		A dijit.form.ValidationTextBox subclass which provides a base class for widgets that have
+		//		A dijit/form/ValidationTextBox subclass which provides a base class for widgets that have
 		//		a visible formatted display value, and a serializable
 		//		value in a hidden input field which is actually sent to the server.
 		// description:
 		//		The visible display may
 		//		be locale-dependent and interactive.  The value sent to the server is stored in a hidden
 		//		input field which uses the `name` attribute declared by the original widget.  That value sent
-		//		to the server is defined by the dijit.form.MappedTextBox.serialize method and is typically
+		//		to the server is defined by the dijit/form/MappedTextBox.serialize() method and is typically
 		//		locale-neutral.
 		// tags:
 		//		protected
@@ -32,13 +25,13 @@ define([
 		postMixInProperties: function(){
 			this.inherited(arguments);
 
-			// we want the name attribute to go to the hidden <input>, not the displayed <input>,
-			// so override _FormWidget.postMixInProperties() setting of nameAttrSetting
+			// We want the name attribute to go to the hidden <input>, not the displayed <input>,
+			// so override _FormWidget.postMixInProperties() setting of nameAttrSetting for IE.
 			this.nameAttrSetting = "";
 		},
 
-		// Override default behavior to assign name to focusNode
-		_setNameAttr: null,
+		// Remap name attribute to be mapped to hidden node created in buildRendering(), rather than this.focusNode
+		_setNameAttr: "valueNode",
 
 		serialize: function(val /*=====, options =====*/){
 			// summary:
@@ -62,25 +55,28 @@ define([
 		},
 
 		validate: function(){
-			// Overrides `dijit.form.TextBox.validate`
+			// Overrides `dijit/form/TextBox.validate`
 			this.valueNode.value = this.toString();
 			return this.inherited(arguments);
 		},
 
 		buildRendering: function(){
-			// Overrides `dijit._TemplatedMixin.buildRendering`
+			// Overrides `dijit/_TemplatedMixin/buildRendering`
 
 			this.inherited(arguments);
 
 			// Create a hidden <input> node with the serialized value used for submit
 			// (as opposed to the displayed value).
-			// Passing in name as markup rather than calling domConstruct.create() with an attrs argument
-			// to make query(input[name=...]) work on IE. (see #8660)
-			this.valueNode = domConstruct.place("<input type='hidden'" + (this.name ? " name='" + this.name.replace(/'/g, """) + "'" : "") + "/>", this.textbox, "after");
+			// Passing in name as markup rather than relying on _setNameAttr custom setter above
+			// to make query(input[name=...]) work on IE. (see #8660).
+			// But not doing that for Windows 8 Store apps because it causes a security exception (see #16452).
+			this.valueNode = domConstruct.place("<input type='hidden'" +
+				((this.name && !has("msapp")) ? ' name="' + this.name.replace(/"/g, """) + '"' : "") + "/>",
+				this.textbox, "after");
 		},
 
 		reset: function(){
-			// Overrides `dijit.form.ValidationTextBox.reset` to
+			// Overrides `dijit/form/ValidationTextBox.reset` to
 			// reset the hidden textbox value to ''
 			this.valueNode.value = '';
 			this.inherited(arguments);
diff --git a/dijit/form/MultiSelect.js b/dijit/form/MultiSelect.js
index 89072bf..1e54c9e 100644
--- a/dijit/form/MultiSelect.js
+++ b/dijit/form/MultiSelect.js
@@ -2,117 +2,146 @@ define([
 	"dojo/_base/array", // array.indexOf, array.map
 	"dojo/_base/declare", // declare
 	"dojo/dom-geometry", // domGeometry.setMarginBox
+	"dojo/has",
 	"dojo/query", // query
 	"./_FormValueWidget"
-], function(array, declare, domGeometry, query, _FormValueWidget){
+], function(array, declare, domGeometry, has, query, _FormValueWidget){
 
-/*=====
-	var _FormValueWidget = dijit.form._FormValueWidget;
-=====*/
+	// module:
+	//		dijit/form/MultiSelect
 
-// module:
-//		dijit/form/MultiSelect
-// summary:
-//		Widget version of a <select multiple=true> element,
-//		for selecting multiple options.
-
-return declare("dijit.form.MultiSelect", _FormValueWidget, {
-	// summary:
-	//		Widget version of a <select multiple=true> element,
-	//		for selecting multiple options.
-
-	// size: Number
-	//		Number of elements to display on a page
-	//		NOTE: may be removed in version 2.0, since elements may have variable height;
-	//		set the size via style="..." or CSS class names instead.
-	size: 7,
-
-	templateString: "<select multiple='true' ${!nameAttrSetting} data-dojo-attach-point='containerNode,focusNode' data-dojo-attach-event='onchange: _onChange'></select>",
-
-	addSelected: function(/*dijit.form.MultiSelect*/ select){
-		// summary:
-		//		Move the selected nodes of a passed Select widget
-		//		instance to this Select widget.
-		//
-		// example:
-		// |	// move all the selected values from "bar" to "foo"
-		// | 	dijit.byId("foo").addSelected(dijit.byId("bar"));
-
-		select.getSelected().forEach(function(n){
-			this.containerNode.appendChild(n);
-			// scroll to bottom to see item
-			// cannot use scrollIntoView since <option> tags don't support all attributes
-			// does not work on IE due to a bug where <select> always shows scrollTop = 0
-			this.domNode.scrollTop = this.domNode.offsetHeight; // overshoot will be ignored
-			// scrolling the source select is trickier esp. on safari who forgets to change the scrollbar size
-			var oldscroll = select.domNode.scrollTop;
-			select.domNode.scrollTop = 0;
-			select.domNode.scrollTop = oldscroll;
-		},this);
-		this._set('value', this.get('value'));
-	},
-
-	getSelected: function(){
-		// summary:
-		//		Access the NodeList of the selected options directly
-		return query("option",this.containerNode).filter(function(n){
-			return n.selected; // Boolean
-		}); // dojo.NodeList
-	},
-
-	_getValueAttr: function(){
-		// summary:
-		//		Hook so get('value') works.
-		// description:
-		//		Returns an array of the selected options' values.
-
-		// Don't call getSelect.map() because it doesn't return a real array,
-		// and that messes up dojo.toJson() calls like in the Form.html test
-		return array.map(this.getSelected(), function(n){
-			return n.value;
-		});
-	},
-
-	multiple: true, // for Form
-
-	_setValueAttr: function(/*Array*/ values, /*Boolean?*/ priorityChange){
+	var MultiSelect = declare("dijit.form.MultiSelect" + (has("dojo-bidi") ? "_NoBidi" : ""), _FormValueWidget, {
 		// summary:
-		//		Hook so set('value', values) works.
-		// description:
-		//		Set the value(s) of this Select based on passed values
-		query("option",this.containerNode).forEach(function(n){
-			n.selected = (array.indexOf(values,n.value) != -1);
-		});
-		this.inherited(arguments);
-	},
-
-	invertSelection: function(/*Boolean?*/ onChange){
-		// summary:
-		//		Invert the selection
-		// onChange: Boolean
-		//		If false, onChange is not fired.
-		var val = [];
-		query("option",this.containerNode).forEach(function(n){
-			if(!n.selected){ val.push(n.value); }
-		});
-		this._setValueAttr(val, !(onChange === false || onChange == null));
-	},
-
-	_onChange: function(/*Event*/){
-		this._handleOnChange(this.get('value'), true);
-	},
-
-	// for layout widgets:
-	resize: function(/*Object*/ size){
-		if(size){
-			domGeometry.setMarginBox(this.domNode, size);
+		//		Widget version of a `<select multiple=true>` element,
+		//		for selecting multiple options.
+
+		// size: Number
+		//		Number of elements to display on a page
+		//		NOTE: may be removed in version 2.0, since elements may have variable height;
+		//		set the size via style="..." or CSS class names instead.
+		size: 7,
+
+		baseClass: "dijitMultiSelect",
+
+		templateString: "<select multiple='true' ${!nameAttrSetting} data-dojo-attach-point='containerNode,focusNode' data-dojo-attach-event='onchange: _onChange'></select>",
+
+		addSelected: function(/*dijit/form/MultiSelect*/ select){
+			// summary:
+			//		Move the selected nodes of a passed Select widget
+			//		instance to this Select widget.
+			//
+			// example:
+			// |	// move all the selected values from "bar" to "foo"
+			// |	dijit.byId("foo").addSelected(dijit.byId("bar"));
+
+			select.getSelected().forEach(function(n){
+				this.containerNode.appendChild(n);
+				// scroll to bottom to see item
+				// cannot use scrollIntoView since <option> tags don't support all attributes
+				// does not work on IE due to a bug where <select> always shows scrollTop = 0
+				this.domNode.scrollTop = this.domNode.offsetHeight; // overshoot will be ignored
+				// scrolling the source select is trickier esp. on safari who forgets to change the scrollbar size
+				var oldscroll = select.domNode.scrollTop;
+				select.domNode.scrollTop = 0;
+				select.domNode.scrollTop = oldscroll;
+			}, this);
+			this._set('value', this.get('value'));
+		},
+
+		getSelected: function(){
+			// summary:
+			//		Access the NodeList of the selected options directly
+			return query("option", this.containerNode).filter(function(n){
+				return n.selected; // Boolean
+			}); // dojo/NodeList
+		},
+
+		_getValueAttr: function(){
+			// summary:
+			//		Hook so get('value') works.
+			// description:
+			//		Returns an array of the selected options' values.
+
+			// Don't call getSelect.map() because it doesn't return a real array,
+			// and that messes up dojo.toJson() calls like in the Form.html test
+			return array.map(this.getSelected(), function(n){
+				return n.value;
+			});
+		},
+
+		multiple: true, // for Form
+
+		_setValueAttr: function(/*Array*/ values, /*Boolean?*/ priorityChange){
+			// summary:
+			//		Hook so set('value', values) works.
+			// description:
+			//		Set the value(s) of this Select based on passed values
+			query("option", this.containerNode).forEach(function(n){
+				n.selected = (array.indexOf(values, n.value) != -1);
+			});
+			this.inherited(arguments);
+		},
+
+		invertSelection: function(/*Boolean?*/ onChange){
+			// summary:
+			//		Invert the selection
+			// onChange: Boolean
+			//		If false, onChange is not fired.
+			var val = [];
+			query("option", this.containerNode).forEach(function(n){
+				if(!n.selected){
+					val.push(n.value);
+				}
+			});
+			this._setValueAttr(val, !(onChange === false || onChange == null));
+		},
+
+		_onChange: function(/*Event*/){
+			this._handleOnChange(this.get('value'), true);
+		},
+
+		// for layout widgets:
+		resize: function(/*Object*/ size){
+			if(size){
+				domGeometry.setMarginBox(this.domNode, size);
+			}
+		},
+
+		postCreate: function(){
+			this._set('value', this.get('value'));
+			this.inherited(arguments);
 		}
-	},
-
-	postCreate: function(){
-		this._set('value', this.get('value'));
-		this.inherited(arguments);
+	});
+
+	if(has("dojo-bidi")){
+		MultiSelect = declare("dijit.form.MultiSelect", MultiSelect, {
+			addSelected: function(/*dijit/form/MultiSelect*/ select){
+				select.getSelected().forEach(function(n){
+					n.text = this.enforceTextDirWithUcc(this.restoreOriginalText(n), n.text);
+				}, this);
+				this.inherited(arguments);
+			},
+
+			_setTextDirAttr: function(textDir){
+				// to insure the code executed only when _BidiSupport loaded, and only
+				// when there was a change in textDir
+				if((this.textDir != textDir || !this._created) && this.enforceTextDirWithUcc){
+					this._set("textDir", textDir);
+
+					query("option", this.containerNode).forEach(function(option){
+						// If the value wasn't defined explicitly, it the same object as
+						// option.text. Since the option.text will be modified (by wrapping of UCC)
+						// we want to save the original option.value for form submission.
+						if(!this._created && option.value === option.text){
+							option.value = option.text;
+						}
+						// apply the bidi support
+						option.text = this.enforceTextDirWithUcc(option, option.originalText || option.text);
+					}, this);
+				}
+			}
+		});
 	}
-});
 
+	return MultiSelect;
 });
diff --git a/dijit/form/NumberSpinner.js b/dijit/form/NumberSpinner.js
index 9cbf770..9251db9 100644
--- a/dijit/form/NumberSpinner.js
+++ b/dijit/form/NumberSpinner.js
@@ -1,74 +1,72 @@
 define([
 	"dojo/_base/declare", // declare
-	"dojo/_base/event", // event.stop
 	"dojo/keys", // keys.END keys.HOME
 	"./_Spinner",
 	"./NumberTextBox"
-], function(declare, event, keys, _Spinner, NumberTextBox){
+], function(declare, keys, _Spinner, NumberTextBox){
 
-/*=====
-	var _Spinner = dijit.form._Spinner;
-	var NumberTextBox = dijit.form.NumberTextBox;
-=====*/
-
-// module:
-//		dijit/form/NumberSpinner
-// summary:
-//		Extends NumberTextBox to add up/down arrows and pageup/pagedown for incremental change to the value
+	// module:
+	//		dijit/form/NumberSpinner
 
+	return declare("dijit.form.NumberSpinner", [_Spinner, NumberTextBox.Mixin], {
+		// summary:
+		//		Extends NumberTextBox to add up/down arrows and pageup/pagedown for incremental change to the value
+		//
+		// description:
+		//		A `dijit/form/NumberTextBox` extension to provide keyboard accessible value selection
+		//		as well as icons for spinning direction. When using the keyboard, the typematic rules
+		//		apply, meaning holding the key will gradually increase or decrease the value and
+		//		accelerate.
+		//
+		// example:
+		//	| new NumberSpinner({ constraints:{ max:300, min:100 }}, "someInput");
 
-return declare("dijit.form.NumberSpinner", [_Spinner, NumberTextBox.Mixin], {
-	// summary:
-	//		Extends NumberTextBox to add up/down arrows and pageup/pagedown for incremental change to the value
-	//
-	// description:
-	//		A `dijit.form.NumberTextBox` extension to provide keyboard accessible value selection
-	//		as well as icons for spinning direction. When using the keyboard, the typematic rules
-	//		apply, meaning holding the key will gradually increase or decrease the value and
-	// 		accelerate.
-	//
-	// example:
-	//	| new dijit.form.NumberSpinner({ constraints:{ max:300, min:100 }}, "someInput");
+		baseClass: "dijitTextBox dijitSpinner dijitNumberTextBox",
 
-	adjust: function(/*Object*/ val, /*Number*/ delta){
-		// summary:
-		//		Change Number val by the given amount
-		// tags:
-		//		protected
+		adjust: function(/*Object*/ val, /*Number*/ delta){
+			// summary:
+			//		Change Number val by the given amount
+			// tags:
+			//		protected
 
-		var tc = this.constraints,
-			v = isNaN(val),
-			gotMax = !isNaN(tc.max),
-			gotMin = !isNaN(tc.min)
-		;
-		if(v && delta != 0){ // blank or invalid value and they want to spin, so create defaults
-			val = (delta > 0) ?
-				gotMin ? tc.min : gotMax ? tc.max : 0 :
-				gotMax ? this.constraints.max : gotMin ? tc.min : 0
-			;
-		}
-		var newval = val + delta;
-		if(v || isNaN(newval)){ return val; }
-		if(gotMax && (newval > tc.max)){
-			newval = tc.max;
-		}
-		if(gotMin && (newval < tc.min)){
-			newval = tc.min;
-		}
-		return newval;
-	},
+			var tc = this.constraints,
+				v = isNaN(val),
+				gotMax = !isNaN(tc.max),
+				gotMin = !isNaN(tc.min)
+				;
+			if(v && delta != 0){ // blank or invalid value and they want to spin, so create defaults
+				val = (delta > 0) ?
+					gotMin ? tc.min : gotMax ? tc.max : 0 :
+					gotMax ? this.constraints.max : gotMin ? tc.min : 0
+				;
+			}
+			var newval = val + delta;
+			if(v || isNaN(newval)){
+				return val;
+			}
+			if(gotMax && (newval > tc.max)){
+				newval = tc.max;
+			}
+			if(gotMin && (newval < tc.min)){
+				newval = tc.min;
+			}
+			return newval;
+		},
 
-	_onKeyPress: function(e){
-		if((e.charOrCode == keys.HOME || e.charOrCode == keys.END) && !(e.ctrlKey || e.altKey || e.metaKey)
-		&& typeof this.get('value') != 'undefined' /* gibberish, so HOME and END are default editing keys*/){
-			var value = this.constraints[(e.charOrCode == keys.HOME ? "min" : "max")];
-			if(typeof value == "number"){
-				this._setValueAttr(value, false);
+		_onKeyDown: function(e){
+			if(this.disabled || this.readOnly){
+				return;
+			}
+			if((e.keyCode == keys.HOME || e.keyCode == keys.END) && !(e.ctrlKey || e.altKey || e.metaKey)
+				&& typeof this.get('value') != 'undefined' /* gibberish, so HOME and END are default editing keys*/){
+				var value = this.constraints[(e.keyCode == keys.HOME ? "min" : "max")];
+				if(typeof value == "number"){
+					this._setValueAttr(value, false);
+				}
+				// eat home or end key whether we change the value or not
+				e.stopPropagation();
+				e.preventDefault();
 			}
-			// eat home or end key whether we change the value or not
-			event.stop(e);
 		}
-	}
-});
-
+	});
 });
diff --git a/dijit/form/NumberTextBox.js b/dijit/form/NumberTextBox.js
index f0c4a6b..cf99a2f 100644
--- a/dijit/form/NumberTextBox.js
+++ b/dijit/form/NumberTextBox.js
@@ -5,34 +5,9 @@ define([
 	"./RangeBoundTextBox"
 ], function(declare, lang, number, RangeBoundTextBox){
 
-/*=====
-	var RangeBoundTextBox = dijit.form.RangeBoundTextBox;
-=====*/
-
 	// module:
 	//		dijit/form/NumberTextBox
-	// summary:
-	//		A TextBox for entering numbers, with formatting and range checking
-
 
-	/*=====
-	declare(
-		"dijit.form.NumberTextBox.__Constraints",
-		[dijit.form.RangeBoundTextBox.__Constraints, number.__FormatOptions, number.__ParseOptions], {
-		// summary:
-		//		Specifies both the rules on valid/invalid values (minimum, maximum,
-		//		number of required decimal places), and also formatting options for
-		//		displaying the value when the field is not focused.
-		// example:
-		//		Minimum/maximum:
-		//		To specify a field between 0 and 120:
-		//	|		{min:0,max:120}
-		//		To specify a field that must be an integer:
-		//	|		{fractional:false}
-		//		To specify a field where 0 to 3 decimal places are allowed on input:
-		//	|		{places:'0,3'}
-	});
-	=====*/
 
 	var NumberTextBoxMixin = declare("dijit.form.NumberTextBoxMixin", null, {
 		// summary:
@@ -40,16 +15,20 @@ define([
 		// tags:
 		//		protected
 
-		// Override ValidationTextBox.regExpGen().... we use a reg-ex generating function rather
+		// Override ValidationTextBox.pattern.... we use a reg-ex generating function rather
 		// than a straight regexp to deal with locale (plus formatting options too?)
-		regExpGen: number.regexp,
+		pattern: function(constraints){
+			// if focused, accept either currency data or NumberTextBox format
+			return '(' + (this.focused && this.editOptions ? this._regExpGenerator(lang.delegate(constraints, this.editOptions)) + '|' : '')
+				+ this._regExpGenerator(constraints) + ')';
+		},
 
 		/*=====
-		// constraints: dijit.form.NumberTextBox.__Constraints
+		// constraints: NumberTextBox.__Constraints
 		//		Despite the name, this parameter specifies both constraints on the input
 		//		(including minimum/maximum allowed values) as well as
 		//		formatting options like places (the number of digits to display after
-		//		the decimal point).  See `dijit.form.NumberTextBox.__Constraints` for details.
+		//		the decimal point).
 		constraints: {},
 		======*/
 
@@ -76,7 +55,7 @@ define([
 			//		as a string, for example converting 12345 into "12,345".
 			// value: Number
 			//		The number to be converted into a string.
-			// options: dojo.number.__FormatOptions?
+			// options: number.__FormatOptions?
 			//		Formatting options
 			// tags:
 			//		protected extension
@@ -86,6 +65,20 @@ define([
 		 =====*/
 		_formatter: number.format,
 
+		/*=====
+		_regExpGenerator: function(constraints){
+			// summary:
+			//		Generate a localized regular expression as a string, according to constraints.
+			// constraints: number.__ParseOptions
+			//		Formatting options
+			// tags:
+			//		protected
+
+			return "(\d*).(\d*)";	// string
+		},
+		=====*/
+		_regExpGenerator: number.regexp,
+
 		postMixInProperties: function(){
 			this.inherited(arguments);
 			this._set("type", "text"); // in case type="number" was specified which messes up parse/format
@@ -118,7 +111,7 @@ define([
 			this.inherited(arguments);
 		},
 
-		format: function(/*Number*/ value, /*dojo.number.__FormatOptions*/ constraints){
+		format: function(/*Number*/ value, /*number.__FormatOptions*/ constraints){
 			// summary:
 			//		Formats the value as a Number, according to constraints.
 			// tags:
@@ -127,7 +120,7 @@ define([
 			var formattedValue = String(value);
 			if(typeof value != "number"){ return formattedValue; }
 			if(isNaN(value)){ return ""; }
-			// check for exponential notation that dojo.number.format chokes on
+			// check for exponential notation that dojo/number.format() chokes on
 			if(!("rangeCheck" in this && this.rangeCheck(value, constraints)) && constraints.exponent !== false && /\de[-+]?\d/i.test(formattedValue)){
 				return formattedValue;
 			}
@@ -143,7 +136,7 @@ define([
 			//		Parses the string value as a Number, according to constraints.
 			// value: String
 			//		String representing a number
-			// constraints: dojo.number.__ParseOptions
+			// constraints: number.__ParseOptions
 			//		Formatting options
 			// tags:
 			//		protected
@@ -177,8 +170,8 @@ define([
 			//		When called with the actual value it does corrections so that '' etc. are represented as NaN.
 			//		Otherwise it dispatches to the superclass's filter() method.
 			//
-			//		See `dijit.form.TextBox.filter` for more details.
-			return (value === null || value === '' || value === undefined) ? NaN : this.inherited(arguments); // set('value', null||''||undefined) should fire onChange(NaN)
+			//		See `dijit/form/TextBox.filter()` for more details.
+			return (value == null /* or undefined */ || value === '') ? NaN : this.inherited(arguments); // set('value', null||''||undefined) should fire onChange(NaN)
 		},
 
 		serialize: function(/*Number*/ value, /*Object?*/ options){
@@ -190,7 +183,7 @@ define([
 		},
 
 		_setBlurValue: function(){
-			var val = lang.hitch(lang.mixin({}, this, { focused: true }), "get")('value'); // parse with editOptions
+			var val = lang.hitch(lang.delegate(this, { focused: true }), "get")('value'); // parse with editOptions
 			this._setValueAttr(val, true);
 		},
 
@@ -226,7 +219,7 @@ define([
 			// Returning undefined prevents user text from being overwritten when doing _setValueAttr(_getValueAttr()).
 			// A blank displayed value is still returned as NaN.
 			if(isNaN(v) && this.textbox.value !== ''){
-				if(this.constraints.exponent !== false && /\de[-+]?\d/i.test(this.textbox.value) && (new RegExp("^"+number._realNumberRegexp(lang.mixin({}, this.constraints))+"$").test(this.textbox.value))){	// check for exponential notation that parse() rejected (erroneously?)
+				if(this.constraints.exponent !== false && /\de[-+]?\d/i.test(this.textbox.value) && (new RegExp("^"+number._realNumberRegexp(lang.delegate(this.constraints))+"$").test(this.textbox.value))){	// check for exponential notation that parse() rejected (erroneously?)
 					var n = Number(this.textbox.value);
 					return isNaN(n) ? undefined : n; // return exponential Number or undefined for random text (may not be possible to do with the above RegExp check)
 				}else{
@@ -238,7 +231,7 @@ define([
 		},
 
 		isValid: function(/*Boolean*/ isFocused){
-			// Overrides dijit.form.RangeBoundTextBox.isValid to check that the editing-mode value is valid since
+			// Overrides dijit/form/RangeBoundTextBox.isValid() to check that the editing-mode value is valid since
 			// it may not be formatted according to the regExp validation rules
 			if(!this.focused || this._isEmpty(this.textbox.value)){
 				return this.inherited(arguments);
@@ -256,31 +249,45 @@ define([
 			}
 		}
 	});
-/*=====
-	NumberTextBoxMixin = dijit.form.NumberTextBoxMixin;
-=====*/
 
-	var NumberTextBox = declare("dijit.form.NumberTextBox", [RangeBoundTextBox,NumberTextBoxMixin], {
+	var NumberTextBox = declare("dijit.form.NumberTextBox", [RangeBoundTextBox, NumberTextBoxMixin], {
 		// summary:
 		//		A TextBox for entering numbers, with formatting and range checking
 		// description:
 		//		NumberTextBox is a textbox for entering and displaying numbers, supporting
 		//		the following main features:
 		//
-		//			1. Enforce minimum/maximum allowed values (as well as enforcing that the user types
-		//				a number rather than a random string)
-		//			2. NLS support (altering roles of comma and dot as "thousands-separator" and "decimal-point"
-		//				depending on locale).
-		//			3. Separate modes for editing the value and displaying it, specifically that
-		//				the thousands separator character (typically comma) disappears when editing
-		//				but reappears after the field is blurred.
-		//			4. Formatting and constraints regarding the number of places (digits after the decimal point)
-		//				allowed on input, and number of places displayed when blurred (see `constraints` parameter).
+		//		1. Enforce minimum/maximum allowed values (as well as enforcing that the user types
+		//			a number rather than a random string)
+		//		2. NLS support (altering roles of comma and dot as "thousands-separator" and "decimal-point"
+		//			depending on locale).
+		//		3. Separate modes for editing the value and displaying it, specifically that
+		//			the thousands separator character (typically comma) disappears when editing
+		//			but reappears after the field is blurred.
+		//		4. Formatting and constraints regarding the number of places (digits after the decimal point)
+		//			allowed on input, and number of places displayed when blurred (see `constraints` parameter).
 
 		baseClass: "dijitTextBox dijitNumberTextBox"
 	});
 
 	NumberTextBox.Mixin = NumberTextBoxMixin;	// for monkey patching
 
+	/*=====
+	 NumberTextBox.__Constraints = declare([RangeBoundTextBox.__Constraints, number.__FormatOptions, number.__ParseOptions], {
+		 // summary:
+		 //		Specifies both the rules on valid/invalid values (minimum, maximum,
+		 //		number of required decimal places), and also formatting options for
+		 //		displaying the value when the field is not focused.
+		 // example:
+		 //		Minimum/maximum:
+		 //		To specify a field between 0 and 120:
+		 //	|		{min:0,max:120}
+		 //		To specify a field that must be an integer:
+		 //	|		{fractional:false}
+		 //		To specify a field where 0 to 3 decimal places are allowed on input:
+		 //	|		{places:'0,3'}
+	 });
+	 =====*/
+
 	return NumberTextBox;
 });
diff --git a/dijit/form/RadioButton.js b/dijit/form/RadioButton.js
index ca7e499..105c04d 100644
--- a/dijit/form/RadioButton.js
+++ b/dijit/form/RadioButton.js
@@ -4,19 +4,12 @@ define([
 	"./_RadioButtonMixin"
 ], function(declare, CheckBox, _RadioButtonMixin){
 
-/*=====
-	var CheckBox = dijit.form.CheckBox;
-	var _RadioButtonMixin = dijit.form._RadioButtonMixin;
-=====*/
-
 	// module:
 	//		dijit/form/RadioButton
-	// summary:
-	//		Radio button widget
 
 	return declare("dijit.form.RadioButton", [CheckBox, _RadioButtonMixin], {
 		// summary:
-		// 		Same as an HTML radio, but with fancy styling.
+		//		Same as an HTML radio, but with fancy styling.
 
 		baseClass: "dijitRadio"
 	});
diff --git a/dijit/form/RangeBoundTextBox.js b/dijit/form/RangeBoundTextBox.js
index 274d608..25b76e0 100644
--- a/dijit/form/RangeBoundTextBox.js
+++ b/dijit/form/RangeBoundTextBox.js
@@ -4,27 +4,11 @@ define([
 	"./MappedTextBox"
 ], function(declare, i18n, MappedTextBox){
 
-/*=====
-	var MappedTextBox = dijit.form.MappedTextBox;
-=====*/
-
 	// module:
 	//		dijit/form/RangeBoundTextBox
-	// summary:
-	//		Base class for textbox form widgets which defines a range of valid values.
 
-	/*=====
-		dijit.form.RangeBoundTextBox.__Constraints = function(){
-			// min: Number
-			//		Minimum signed value.  Default is -Infinity
-			// max: Number
-			//		Maximum signed value.  Default is +Infinity
-			this.min = min;
-			this.max = max;
-		}
-	=====*/
 
-	return declare("dijit.form.RangeBoundTextBox", MappedTextBox, {
+	var RangeBoundTextBox = declare("dijit.form.RangeBoundTextBox", MappedTextBox, {
 		// summary:
 		//		Base class for textbox form widgets which defines a range of valid values.
 
@@ -33,11 +17,11 @@ define([
 		rangeMessage: "",
 
 		/*=====
-		// constraints: dijit.form.RangeBoundTextBox.__Constraints
+		// constraints: RangeBoundTextBox.__Constraints
 		constraints: {},
 		======*/
 
-		rangeCheck: function(/*Number*/ primitive, /*dijit.form.RangeBoundTextBox.__Constraints*/ constraints){
+		rangeCheck: function(/*Number*/ primitive, /*dijit/form/RangeBoundTextBox.__Constraints*/ constraints){
 			// summary:
 			//		Overridable function used to validate the range of the numeric input value.
 			// tags:
@@ -59,39 +43,37 @@ define([
 			//		Returns true if the value is out of range and will remain
 			//		out of range even if the user types more characters
 			var val = this.get('value');
-			var isTooLittle = false;
-			var isTooMuch = false;
+			if(val == null){ return false; } // not yet valid enough to compare to
+			var outOfRange = false;
 			if("min" in this.constraints){
 				var min = this.constraints.min;
-				min = this.compare(val, ((typeof min == "number") && min >= 0 && val !=0) ? 0 : min);
-				isTooLittle = (typeof min == "number") && min < 0;
+				outOfRange = this.compare(val, ((typeof min == "number") && min >= 0 && val != 0) ? 0 : min) < 0;
 			}
-			if("max" in this.constraints){
+			if(!outOfRange && ("max" in this.constraints)){
 				var max = this.constraints.max;
-				max = this.compare(val, ((typeof max != "number") || max > 0) ? max : 0);
-				isTooMuch = (typeof max == "number") && max > 0;
+				outOfRange = this.compare(val, ((typeof max != "number") || max > 0) ? max : 0) > 0;
 			}
-			return isTooLittle || isTooMuch;
+			return outOfRange;
 		},
 
 		_isValidSubset: function(){
 			// summary:
-			//		Overrides `dijit.form.ValidationTextBox._isValidSubset`.
+			//		Overrides `dijit/form/ValidationTextBox._isValidSubset()`.
 			//		Returns true if the input is syntactically valid, and either within
 			//		range or could be made in range by more typing.
 			return this.inherited(arguments) && !this._isDefinitelyOutOfRange();
 		},
 
 		isValid: function(/*Boolean*/ isFocused){
-			// Overrides dijit.form.ValidationTextBox.isValid to check that the value is also in range.
+			// Overrides dijit/form/ValidationTextBox.isValid() to check that the value is also in range.
 			return this.inherited(arguments) &&
 				((this._isEmpty(this.textbox.value) && !this.required) || this.isInRange(isFocused)); // Boolean
 		},
 
 		getErrorMessage: function(/*Boolean*/ isFocused){
-			// Overrides dijit.form.ValidationTextBox.getErrorMessage to print "out of range" message if appropriate
+			// Overrides dijit/form/ValidationTextBox.getErrorMessage() to print "out of range" message if appropriate
 			var v = this.get('value');
-			if(v !== null && v !== '' && v !== undefined && (typeof v != "number" || !isNaN(v)) && !this.isInRange(isFocused)){ // don't check isInRange w/o a real value
+			if(v != null /* and !undefined */ && v !== '' && (typeof v != "number" || !isNaN(v)) && !this.isInRange(isFocused)){ // don't check isInRange w/o a real value
 				return this.rangeMessage; // String
 			}
 			return this.inherited(arguments);
@@ -103,41 +85,15 @@ define([
 				this.messages = i18n.getLocalization("dijit.form", "validate", this.lang);
 				this.rangeMessage = this.messages.rangeMessage;
 			}
-		},
-
-		_setConstraintsAttr: function(/*Object*/ constraints){
-			this.inherited(arguments);
-			if(this.focusNode){ // not set when called from postMixInProperties
-				if(this.constraints.min !== undefined){
-					this.focusNode.setAttribute("aria-valuemin", this.constraints.min);
-				}else{
-					this.focusNode.removeAttribute("aria-valuemin");
-				}
-				if(this.constraints.max !== undefined){
-					this.focusNode.setAttribute("aria-valuemax", this.constraints.max);
-				}else{
-					this.focusNode.removeAttribute("aria-valuemax");
-				}
-			}
-		},
-
-		_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange){
-			// summary:
-			//		Hook so set('value', ...) works.
-
-			this.focusNode.setAttribute("aria-valuenow", value);
-			this.inherited(arguments);
-		},
-
-		applyTextDir: function(/*===== element, text =====*/){
-			// summary:
-			//		The function overridden in the _BidiSupport module,
-			//		originally used for setting element.dir according to this.textDir.
-			//		In this case does nothing.
-			// element: Object
-			// text: String
-			// tags:
-			//		protected.
 		}
 	});
+	/*=====
+	RangeBoundTextBox.__Constraints = declare(null, {
+		// min: Number
+		//		Minimum signed value.  Default is -Infinity
+		// max: Number
+		//		Maximum signed value.  Default is +Infinity
+	});
+	=====*/
+	return RangeBoundTextBox;
 });
diff --git a/dijit/form/Select.js b/dijit/form/Select.js
index e285a23..e723e77 100644
--- a/dijit/form/Select.js
+++ b/dijit/form/Select.js
@@ -3,343 +3,456 @@ define([
 	"dojo/_base/declare", // declare
 	"dojo/dom-attr", // domAttr.set
 	"dojo/dom-class", // domClass.add domClass.remove domClass.toggle
-	"dojo/dom-construct", // domConstruct.create
 	"dojo/dom-geometry", // domGeometry.setMarginBox
-	"dojo/_base/event", // event.stop
 	"dojo/i18n", // i18n.getLocalization
 	"dojo/_base/lang", // lang.hitch
+	"dojo/on",
+	"dojo/sniff", // has("ie")
 	"./_FormSelectWidget",
 	"../_HasDropDown",
-	"../Menu",
+	"../DropDownMenu",
 	"../MenuItem",
 	"../MenuSeparator",
 	"../Tooltip",
+	"../_KeyNavMixin",
+	"../registry", // registry.byNode
 	"dojo/text!./templates/Select.html",
 	"dojo/i18n!./nls/validate"
-], function(array, declare, domAttr, domClass, domConstruct, domGeometry, event, i18n, lang,
-			_FormSelectWidget, _HasDropDown, Menu, MenuItem, MenuSeparator, Tooltip, template){
-
-/*=====
-	var _FormSelectWidget = dijit.form._FormSelectWidget;
-	var _HasDropDown = dijit._HasDropDown;
-	var _FormSelectWidget = dijit._FormSelectWidget;
-	var Menu = dijit.Menu;
-	var MenuItem = dijit.MenuItem;
-	var MenuSeparator = dijit.MenuSeparator;
-	var Tooltip = dijit.Tooltip;
-=====*/
-
-// module:
-//		dijit/form/Select
-// summary:
-//		This is a "styleable" select box - it is basically a DropDownButton which
-//		can take a <select> as its input.
-
-
-var _SelectMenu = declare("dijit.form._SelectMenu", Menu, {
-	// summary:
-	//		An internally-used menu for dropdown that allows us a vertical scrollbar
-	buildRendering: function(){
-		// summary:
-		//		Stub in our own changes, so that our domNode is not a table
-		//		otherwise, we won't respond correctly to heights/overflows
-		this.inherited(arguments);
-		var o = (this.menuTableNode = this.domNode);
-		var n = (this.domNode = domConstruct.create("div", {style: {overflowX: "hidden", overflowY: "scroll"}}));
-		if(o.parentNode){
-			o.parentNode.replaceChild(n, o);
-		}
-		domClass.remove(o, "dijitMenuTable");
-		n.className = o.className + " dijitSelectMenu";
-		o.className = "dijitReset dijitMenuTable";
-		o.setAttribute("role", "listbox");
-		n.setAttribute("role", "presentation");
-		n.appendChild(o);
-	},
-
-	postCreate: function(){
-		// summary:
-		//		stop mousemove from selecting text on IE to be consistent with other browsers
+], function(array, declare, domAttr, domClass, domGeometry, i18n, lang, on, has,
+			_FormSelectWidget, _HasDropDown, DropDownMenu, MenuItem, MenuSeparator, Tooltip, _KeyNavMixin, registry, template){
 
-		this.inherited(arguments);
+	// module:
+	//		dijit/form/Select
 
-		this.connect(this.domNode, "onmousemove", event.stop);
-	},
-
-	resize: function(/*Object*/ mb){
+	var _SelectMenu = declare("dijit.form._SelectMenu", DropDownMenu, {
 		// summary:
-		//		Overridden so that we are able to handle resizing our
-		//		internal widget.  Note that this is not a "full" resize
-		//		implementation - it only works correctly if you pass it a
-		//		marginBox.
-		//
-		// mb: Object
-		//		The margin box to set this dropdown to.
-		if(mb){
-			domGeometry.setMarginBox(this.domNode, mb);
-			if("w" in mb){
-				// We've explicitly set the wrapper <div>'s width, so set <table> width to match.
-				// 100% is safer than a pixel value because there may be a scroll bar with
-				// browser/OS specific width.
-				this.menuTableNode.style.width = "100%";
-			}
-		}
-	}
-});
+		//		An internally-used menu for dropdown that allows us a vertical scrollbar
 
-var Select = declare("dijit.form.Select", [_FormSelectWidget, _HasDropDown], {
-	// summary:
-	//		This is a "styleable" select box - it is basically a DropDownButton which
-	//		can take a <select> as its input.
+		// Override Menu.autoFocus setting so that opening a Select highlights the current value.
+		autoFocus: true,
 
-	baseClass: "dijitSelect",
+		buildRendering: function(){
+			this.inherited(arguments);
 
-	templateString: template,
+			this.domNode.setAttribute("role", "listbox");
+		},
 
-	// required: Boolean
-	//		Can be true or false, default is false.
-	required: false,
+		postCreate: function(){
+			// summary:
+			//		stop mousemove from selecting text on IE to be consistent with other browsers
 
-	// state: [readonly] String
-	//		"Incomplete" if this select is required but unset (i.e. blank value), "" otherwise
-	state: "",
+			this.inherited(arguments);
 
-	// message: String
-	//		Currently displayed error/prompt message
-	message: "",
+			this.own(on(this.domNode, "selectstart", function(evt){
+				evt.preventDefault();
+				evt.stopPropagation();
+			}));
+		},
 
-	//	tooltipPosition: String[]
-	//		See description of dijit.Tooltip.defaultPosition for details on this parameter.
-	tooltipPosition: [],
+		focus: function(){
+			// summary:
+			//		Overridden so that the previously selected value will be focused instead of only the first item
+			var found = false,
+				val = this.parentWidget.value;
+			if(lang.isArray(val)){
+				val = val[val.length - 1];
+			}
+			if(val){ // if focus selected
+				array.forEach(this.parentWidget._getChildren(), function(child){
+					if(child.option && (val === child.option.value)){ // find menu item widget with this value
+						found = true;
+						this.focusChild(child, false); // focus previous selection
+					}
+				}, this);
+			}
+			if(!found){
+				this.inherited(arguments); // focus first item by default
+			}
+		}
+	});
 
-	// emptyLabel: string
-	//		What to display in an "empty" dropdown
-	emptyLabel: " ",	//  
+	var Select = declare("dijit.form.Select" + (has("dojo-bidi") ? "_NoBidi" : ""), [_FormSelectWidget, _HasDropDown, _KeyNavMixin], {
+		// summary:
+		//		This is a "styleable" select box - it is basically a DropDownButton which
+		//		can take a `<select>` as its input.
 
-	// _isLoaded: Boolean
-	//		Whether or not we have been loaded
-	_isLoaded: false,
+		baseClass: "dijitSelect dijitValidationTextBox",
 
-	// _childrenLoaded: Boolean
-	//		Whether or not our children have been loaded
-	_childrenLoaded: false,
+		templateString: template,
 
-	_fillContent: function(){
-		// summary:
-		//		Set the value to be the first, or the selected index
-		this.inherited(arguments);
-		// set value from selected option
-		if(this.options.length && !this.value && this.srcNodeRef){
-			var si = this.srcNodeRef.selectedIndex || 0; // || 0 needed for when srcNodeRef is not a SELECT
-			this.value = this.options[si >= 0 ? si : 0].value;
-		}
-		// Create the dropDown widget
-		this.dropDown = new _SelectMenu({id: this.id + "_menu"});
-		domClass.add(this.dropDown.domNode, this.baseClass + "Menu");
-	},
+		_buttonInputDisabled: has("ie") ? "disabled" : "", // allows IE to disallow focus, but Firefox cannot be disabled for mousedown events
 
-	_getMenuItemForOption: function(/*dijit.form.__SelectOption*/ option){
-		// summary:
-		//		For the given option, return the menu item that should be
-		//		used to display it.  This can be overridden as needed
-		if(!option.value && !option.label){
-			// We are a separator (no label set for it)
-			return new MenuSeparator();
-		}else{
-			// Just a regular menu option
-			var click = lang.hitch(this, "_setValueAttr", option);
-			var item = new MenuItem({
-				option: option,
-				label: option.label || this.emptyLabel,
-				onClick: click,
-				disabled: option.disabled || false
-			});
-			item.focusNode.setAttribute("role", "listitem");
-			return item;
-		}
-	},
+		// required: Boolean
+		//		Can be true or false, default is false.
+		required: false,
 
-	_addOptionItem: function(/*dijit.form.__SelectOption*/ option){
-		// summary:
-		//		For the given option, add an option to our dropdown.
-		//		If the option doesn't have a value, then a separator is added
-		//		in that place.
-		if(this.dropDown){
-			this.dropDown.addChild(this._getMenuItemForOption(option));
-		}
-	},
+		// state: [readonly] String
+		//		"Incomplete" if this select is required but unset (i.e. blank value), "" otherwise
+		state: "",
 
-	_getChildren: function(){
-		if(!this.dropDown){
-			return [];
-		}
-		return this.dropDown.getChildren();
-	},
+		// message: String
+		//		Currently displayed error/prompt message
+		message: "",
 
-	_loadChildren: function(/*Boolean*/ loadMenuItems){
-		// summary:
-		//		Resets the menu and the length attribute of the button - and
-		//		ensures that the label is appropriately set.
-		//	loadMenuItems: Boolean
-		//		actually loads the child menu items - we only do this when we are
-		//		populating for showing the dropdown.
-
-		if(loadMenuItems === true){
-			// this.inherited destroys this.dropDown's child widgets (MenuItems).
-			// Avoid this.dropDown (Menu widget) having a pointer to a destroyed widget (which will cause
-			// issues later in _setSelected). (see #10296)
-			if(this.dropDown){
-				delete this.dropDown.focusedChild;
-			}
-			if(this.options.length){
-				this.inherited(arguments);
-			}else{
-				// Drop down menu is blank but add one blank entry just so something appears on the screen
-				// to let users know that they are no choices (mimicing native select behavior)
-				array.forEach(this._getChildren(), function(child){ child.destroyRecursive(); });
-				var item = new MenuItem({label: " "});
-				this.dropDown.addChild(item);
-			}
-		}else{
-			this._updateSelection();
-		}
+		// tooltipPosition: String[]
+		//		See description of `dijit/Tooltip.defaultPosition` for details on this parameter.
+		tooltipPosition: [],
 
-		this._isLoaded = false;
-		this._childrenLoaded = true;
+		// emptyLabel: string
+		//		What to display in an "empty" dropdown
+		emptyLabel: " ", //  
 
-		if(!this._loadingStore){
-			// Don't call this if we are loading - since we will handle it later
-			this._setValueAttr(this.value);
-		}
-	},
-
-	_setValueAttr: function(value){
-		this.inherited(arguments);
-		domAttr.set(this.valueNode, "value", this.get("value"));
-		this.validate(this.focused);	// to update this.state
-	},
-
-	_setDisabledAttr: function(/*Boolean*/ value){
-		this.inherited(arguments);
-		this.validate(this.focused);	// to update this.state
-	},
-
-	_setRequiredAttr: function(/*Boolean*/ value){
-		this._set("required", value);
-		this.focusNode.setAttribute("aria-required", value);
-		this.validate(this.focused);	// to update this.state
-	},
-
-	_setDisplay: function(/*String*/ newDisplay){
-		// summary:
-		//		sets the display for the given value (or values)
-		var lbl = newDisplay || this.emptyLabel;
-		this.containerNode.innerHTML = '<span class="dijitReset dijitInline ' + this.baseClass + 'Label">' + lbl + '</span>';
-		this.focusNode.setAttribute("aria-valuetext", lbl);
-	},
+		// _isLoaded: Boolean
+		//		Whether or not we have been loaded
+		_isLoaded: false,
 
-	validate: function(/*Boolean*/ isFocused){
-		// summary:
-		//		Called by oninit, onblur, and onkeypress, and whenever required/disabled state changes
-		// description:
-		//		Show missing or invalid messages if appropriate, and highlight textbox field.
-		//		Used when a select is initially set to no value and the user is required to
-		//		set the value.
-
-		var isValid = this.disabled || this.isValid(isFocused);
-		this._set("state", isValid ? "" : "Incomplete");
-		this.focusNode.setAttribute("aria-invalid", isValid ? "false" : "true");
-		var message = isValid ? "" : this._missingMsg;
-		if(message && this.focused && this._hasBeenBlurred){
-			Tooltip.show(message, this.domNode, this.tooltipPosition, !this.isLeftToRight());
-		}else{
-			Tooltip.hide(this.domNode);
-		}
-		this._set("message", message);
-		return isValid;
-	},
+		// _childrenLoaded: Boolean
+		//		Whether or not our children have been loaded
+		_childrenLoaded: false,
 
-	isValid: function(/*Boolean*/ /*===== isFocused =====*/){
-		// summary:
-		//		Whether or not this is a valid value.  The only way a Select
-		//		can be invalid is when it's required but nothing is selected.
-		return (!this.required || this.value === 0 || !(/^\s*$/.test(this.value || ""))); // handle value is null or undefined
-	},
-
-	reset: function(){
-		// summary:
-		//		Overridden so that the state will be cleared.
-		this.inherited(arguments);
-		Tooltip.hide(this.domNode);
-		this.validate(this.focused);	// to update this.state
-	},
+		_fillContent: function(){
+			// summary:
+			//		Set the value to be the first, or the selected index
+			this.inherited(arguments);
+			// set value from selected option
+			if(this.options.length && !this.value && this.srcNodeRef){
+				var si = this.srcNodeRef.selectedIndex || 0; // || 0 needed for when srcNodeRef is not a SELECT
+				this._set("value", this.options[si >= 0 ? si : 0].value);
+			}
+			// Create the dropDown widget
+			this.dropDown = new _SelectMenu({ id: this.id + "_menu", parentWidget: this });
+			domClass.add(this.dropDown.domNode, this.baseClass.replace(/\s+|$/g, "Menu "));
+		},
+
+		_getMenuItemForOption: function(/*_FormSelectWidget.__SelectOption*/ option){
+			// summary:
+			//		For the given option, return the menu item that should be
+			//		used to display it.  This can be overridden as needed
+			if(!option.value && !option.label){
+				// We are a separator (no label set for it)
+				return new MenuSeparator({ownerDocument: this.ownerDocument});
+			}else{
+				// Just a regular menu option
+				var click = lang.hitch(this, "_setValueAttr", option);
+				var item = new MenuItem({
+					option: option,
+					label: option.label || this.emptyLabel,
+					onClick: click,
+					ownerDocument: this.ownerDocument,
+					dir: this.dir,
+					textDir: this.textDir,
+					disabled: option.disabled || false
+				});
+				item.focusNode.setAttribute("role", "option");
+				return item;
+			}
+		},
 
-	postMixInProperties: function(){
-		// summary:
-		//		set the missing message
-		this.inherited(arguments);
-		this._missingMsg = i18n.getLocalization("dijit.form", "validate",
-									this.lang).missingMessage;
-	},
+		_addOptionItem: function(/*_FormSelectWidget.__SelectOption*/ option){
+			// summary:
+			//		For the given option, add an option to our dropdown.
+			//		If the option doesn't have a value, then a separator is added
+			//		in that place.
+			if(this.dropDown){
+				this.dropDown.addChild(this._getMenuItemForOption(option));
+			}
+		},
 
-	postCreate: function(){
-		// summary:
-		//		stop mousemove from selecting text on IE to be consistent with other browsers
+		_getChildren: function(){
+			if(!this.dropDown){
+				return [];
+			}
+			return this.dropDown.getChildren();
+		},
+
+		focus: function(){
+			// Override _KeyNavMixin::focus(), which calls focusFirstChild().
+			// We just want the standard form widget behavior.
+			if(!this.disabled && this.focusNode.focus){
+				try{
+					this.focusNode.focus();
+				}catch(e){
+					/*squelch errors from hidden nodes*/
+				}
+			}
+		},
+
+		focusChild: function(/*dijit/_WidgetBase*/ widget){
+			// summary:
+			//		Sets the value to the given option, used during search by letter.
+			// widget:
+			//		Reference to option's widget
+			// tags:
+			//		protected
+			if(widget){
+				this.set('value', widget.option);
+			}
+		},
+
+		_getFirst: function(){
+			// summary:
+			//		Returns the first child widget.
+			// tags:
+			//		abstract extension
+			var children = this._getChildren();
+			return children.length ? children[0] : null;
+		},
+
+		_getLast: function(){
+			// summary:
+			//		Returns the last child widget.
+			// tags:
+			//		abstract extension
+			var children = this._getChildren();
+			return children.length ? children[children.length-1] : null;
+		},
+
+		childSelector: function(/*DOMNode*/ node){
+			// Implement _KeyNavMixin.childSelector, to identify focusable child nodes.
+			// If we allowed a dojo/query dependency from this module this could more simply be a string "> *"
+			// instead of this function.
+
+			var node = registry.byNode(node);
+			return node && node.getParent() == this.dropDown;
+		},
+
+		onKeyboardSearch: function(/*dijit/_WidgetBase*/ item, /*Event*/ evt, /*String*/ searchString, /*Number*/ numMatches){
+			// summary:
+			//		When a key is pressed that matches a child item,
+			//		this method is called so that a widget can take appropriate action is necessary.
+			// tags:
+			//		protected
+			if(item){
+				this.focusChild(item);
+			}
+		},
+
+		_loadChildren: function(/*Boolean*/ loadMenuItems){
+			// summary:
+			//		Resets the menu and the length attribute of the button - and
+			//		ensures that the label is appropriately set.
+			// loadMenuItems: Boolean
+			//		actually loads the child menu items - we only do this when we are
+			//		populating for showing the dropdown.
+
+			if(loadMenuItems === true){
+				// this.inherited destroys this.dropDown's child widgets (MenuItems).
+				// Avoid this.dropDown (Menu widget) having a pointer to a destroyed widget (which will cause
+				// issues later in _setSelected). (see #10296)
+				if(this.dropDown){
+					delete this.dropDown.focusedChild;
+					this.focusedChild = null;
+				}
+				if(this.options.length){
+					this.inherited(arguments);
+				}else{
+					// Drop down menu is blank but add one blank entry just so something appears on the screen
+					// to let users know that they are no choices (mimicing native select behavior)
+					array.forEach(this._getChildren(), function(child){
+						child.destroyRecursive();
+					});
+					var item = new MenuItem({
+						ownerDocument: this.ownerDocument,
+						label: this.emptyLabel
+					});
+					this.dropDown.addChild(item);
+				}
+			}else{
+				this._updateSelection();
+			}
 
-		this.inherited(arguments);
+			this._isLoaded = false;
+			this._childrenLoaded = true;
 
-		this.connect(this.domNode, "onmousemove", event.stop);
-	},
+			if(!this._loadingStore){
+				// Don't call this if we are loading - since we will handle it later
+				this._setValueAttr(this.value, false);
+			}
+		},
 
-	_setStyleAttr: function(/*String||Object*/ value){
-		this.inherited(arguments);
-		domClass.toggle(this.domNode, this.baseClass + "FixedWidth", !!this.domNode.style.width);
-	},
+		_refreshState: function(){
+			if(this._started){
+				this.validate(this.focused);
+			}
+		},
+
+		startup: function(){
+			this.inherited(arguments);
+			this._refreshState(); // after all _set* methods have run
+		},
+
+		_setValueAttr: function(value){
+			this.inherited(arguments);
+			domAttr.set(this.valueNode, "value", this.get("value"));
+			this._refreshState();	// to update this.state
+		},
+
+		_setNameAttr: "valueNode",
+
+		_setDisabledAttr: function(/*Boolean*/ value){
+			this.inherited(arguments);
+			this._refreshState();	// to update this.state
+		},
+
+		_setRequiredAttr: function(/*Boolean*/ value){
+			this._set("required", value);
+			this.focusNode.setAttribute("aria-required", value);
+			this._refreshState();	// to update this.state
+		},
+
+		_setOptionsAttr: function(/*Array*/ options){
+			this._isLoaded = false;
+			this._set('options', options);
+		},
+
+		_setDisplay: function(/*String*/ newDisplay){
+			// summary:
+			//		sets the display for the given value (or values)
+			var lbl = newDisplay || this.emptyLabel;
+			this.containerNode.innerHTML = '<span role="option" class="dijitReset dijitInline ' + this.baseClass.replace(/\s+|$/g, "Label ") + '">' + lbl + '</span>';
+		},
+
+		validate: function(/*Boolean*/ isFocused){
+			// summary:
+			//		Called by oninit, onblur, and onkeypress, and whenever required/disabled state changes
+			// description:
+			//		Show missing or invalid messages if appropriate, and highlight textbox field.
+			//		Used when a select is initially set to no value and the user is required to
+			//		set the value.
+
+			var isValid = this.disabled || this.isValid(isFocused);
+			this._set("state", isValid ? "" : (this._hasBeenBlurred ? "Error" : "Incomplete"));
+			this.focusNode.setAttribute("aria-invalid", isValid ? "false" : "true");
+			var message = isValid ? "" : this._missingMsg;
+			if(message && this.focused && this._hasBeenBlurred){
+				Tooltip.show(message, this.domNode, this.tooltipPosition, !this.isLeftToRight());
+			}else{
+				Tooltip.hide(this.domNode);
+			}
+			this._set("message", message);
+			return isValid;
+		},
+
+		isValid: function(/*Boolean*/ /*===== isFocused =====*/){
+			// summary:
+			//		Whether or not this is a valid value.  The only way a Select
+			//		can be invalid is when it's required but nothing is selected.
+			return (!this.required || this.value === 0 || !(/^\s*$/.test(this.value || ""))); // handle value is null or undefined
+		},
+
+		reset: function(){
+			// summary:
+			//		Overridden so that the state will be cleared.
+			this.inherited(arguments);
+			Tooltip.hide(this.domNode);
+			this._refreshState();	// to update this.state
+		},
+
+		postMixInProperties: function(){
+			// summary:
+			//		set the missing message
+			this.inherited(arguments);
+			this._missingMsg = i18n.getLocalization("dijit.form", "validate", this.lang).missingMessage;
+		},
+
+		postCreate: function(){
+			// summary:
+			//		stop mousemove from selecting text on IE to be consistent with other browsers
+
+			this.inherited(arguments);
+
+			this.own(on(this.domNode, "selectstart", function(evt){
+				evt.preventDefault();
+				evt.stopPropagation();
+			}));
+
+			this.domNode.setAttribute("aria-expanded", "false");
+
+			if(has("ie") < 9){
+				// IE INPUT tag fontFamily has to be set directly using STYLE
+				// the defer gives IE a chance to render the TextBox and to deal with font inheritance
+				this.defer(function(){
+					try{
+						var s = domStyle.getComputedStyle(this.domNode); // can throw an exception if widget is immediately destroyed
+						if(s){
+							var ff = s.fontFamily;
+							if(ff){
+								var inputs = this.domNode.getElementsByTagName("INPUT");
+								if(inputs){
+									for(var i = 0; i < inputs.length; i++){
+										inputs[i].style.fontFamily = ff;
+									}
+								}
+							}
+						}
+					}catch(e){
+						// when used in a Dialog, and this is called before the dialog is
+						// shown, s.fontFamily would trigger "Invalid Argument" error.
+					}
+				});
+			}
+		},
+
+		_setStyleAttr: function(/*String||Object*/ value){
+			this.inherited(arguments);
+			domClass.toggle(this.domNode, this.baseClass.replace(/\s+|$/g, "FixedWidth "), !!this.domNode.style.width);
+		},
+
+		isLoaded: function(){
+			return this._isLoaded;
+		},
+
+		loadDropDown: function(/*Function*/ loadCallback){
+			// summary:
+			//		populates the menu
+			this._loadChildren(true);
+			this._isLoaded = true;
+			loadCallback();
+		},
+
+		destroy: function(preserveDom){
+			if(this.dropDown && !this.dropDown._destroyed){
+				this.dropDown.destroyRecursive(preserveDom);
+				delete this.dropDown;
+			}
+			this.inherited(arguments);
+		},
 
-	isLoaded: function(){
-		return this._isLoaded;
-	},
+		_onFocus: function(){
+			this.validate(true);	// show tooltip if second focus of required tooltip, but no selection
+			this.inherited(arguments);
+		},
 
-	loadDropDown: function(/*Function*/ loadCallback){
-		// summary:
-		//		populates the menu
-		this._loadChildren(true);
-		this._isLoaded = true;
-		loadCallback();
-	},
-
-	closeDropDown: function(){
-		// overriding _HasDropDown.closeDropDown()
-		this.inherited(arguments);
-
-		if(this.dropDown && this.dropDown.menuTableNode){
-			// Erase possible width: 100% setting from _SelectMenu.resize().
-			// Leaving it would interfere with the next openDropDown() call, which
-			// queries the natural size of the drop down.
-			this.dropDown.menuTableNode.style.width = "";
+		_onBlur: function(){
+			Tooltip.hide(this.domNode);
+			this.inherited(arguments);
+			this.validate(false);
 		}
-	},
+	});
 
-	uninitialize: function(preserveDom){
-		if(this.dropDown && !this.dropDown._destroyed){
-			this.dropDown.destroyRecursive(preserveDom);
-			delete this.dropDown;
-		}
-		this.inherited(arguments);
-	},
+	if(has("dojo-bidi")){
+		Select = declare("dijit.form.Select", Select, {
+			_setDisplay: function(/*String*/ newDisplay){
+				this.inherited(arguments);
+				this.applyTextDir(this.containerNode);
+			}
+		});
+	}
 
-	_onFocus: function(){
-		this.validate(true);	// show tooltip if second focus of required tooltip, but no selection
-		this.inherited(arguments);
-	},
+	Select._Menu = _SelectMenu;	// for monkey patching
 
-	_onBlur: function(){
-		Tooltip.hide(this.domNode);
-		this.inherited(arguments);
+	// generic event helper to ensure the dropdown items are loaded before the real event handler is called
+	function _onEventAfterLoad(method){
+		return function(evt){
+			if(!this._isLoaded){
+				this.loadDropDown(lang.hitch(this, method, evt));
+			}else{
+				this.inherited(method, arguments);
+			}
+		};
 	}
-});
-
-Select._Menu = _SelectMenu;	// for monkey patching
+	Select.prototype._onContainerKeydown = _onEventAfterLoad("_onContainerKeydown");
+	Select.prototype._onContainerKeypress = _onEventAfterLoad("_onContainerKeypress");
 
-return Select;
+	return Select;
 });
diff --git a/dijit/form/SimpleTextarea.js b/dijit/form/SimpleTextarea.js
index e82109a..5017b08 100644
--- a/dijit/form/SimpleTextarea.js
+++ b/dijit/form/SimpleTextarea.js
@@ -1,100 +1,90 @@
 define([
 	"dojo/_base/declare", // declare
 	"dojo/dom-class", // domClass.add
-	"dojo/_base/sniff", // has("ie") has("opera")
-	"dojo/_base/window", // win.doc.selection win.doc.selection.createRange
+	"dojo/sniff", // has("ie") has("opera")
 	"./TextBox"
-], function(declare, domClass, has, win, TextBox){
+], function(declare, domClass, has, TextBox){
 
-/*=====
-	var TextBox = dijit.form.TextBox;
-=====*/
+	// module:
+	//		dijit/form/SimpleTextarea
 
-// module:
-//		dijit/form/SimpleTextarea
-// summary:
-//		A simple textarea that degrades, and responds to
-// 		minimal LayoutContainer usage, and works with dijit.form.Form.
-//		Doesn't automatically size according to input, like Textarea.
+	return declare("dijit.form.SimpleTextarea", TextBox, {
+		// summary:
+		//		A simple textarea that degrades, and responds to
+		//		minimal LayoutContainer usage, and works with dijit/form/Form.
+		//		Doesn't automatically size according to input, like Textarea.
+		//
+		// example:
+		//	|	<textarea data-dojo-type="dijit/form/SimpleTextarea" name="foo" value="bar" rows=30 cols=40></textarea>
+		//
+		// example:
+		//	|	new SimpleTextarea({ rows:20, cols:30 }, "foo");
 
-return declare("dijit.form.SimpleTextarea", TextBox, {
-	// summary:
-	//		A simple textarea that degrades, and responds to
-	// 		minimal LayoutContainer usage, and works with dijit.form.Form.
-	//		Doesn't automatically size according to input, like Textarea.
-	//
-	// example:
-	//	|	<textarea data-dojo-type="dijit.form.SimpleTextarea" name="foo" value="bar" rows=30 cols=40></textarea>
-	//
-	// example:
-	//	|	new dijit.form.SimpleTextarea({ rows:20, cols:30 }, "foo");
+		baseClass: "dijitTextBox dijitTextArea",
 
-	baseClass: "dijitTextBox dijitTextArea",
+		// rows: Number
+		//		The number of rows of text.
+		rows: "3",
 
-	// rows: Number
-	//		The number of rows of text.
-	rows: "3",
+		// rows: Number
+		//		The number of characters per line.
+		cols: "20",
 
-	// rows: Number
-	//		The number of characters per line.
-	cols: "20",
+		templateString: "<textarea ${!nameAttrSetting} data-dojo-attach-point='focusNode,containerNode,textbox' autocomplete='off'></textarea>",
 
-	templateString: "<textarea ${!nameAttrSetting} data-dojo-attach-point='focusNode,containerNode,textbox' autocomplete='off'></textarea>",
-
-	postMixInProperties: function(){
-		// Copy value from srcNodeRef, unless user specified a value explicitly (or there is no srcNodeRef)
-		// TODO: parser will handle this in 2.0
-		if(!this.value && this.srcNodeRef){
-			this.value = this.srcNodeRef.value;
-		}
-		this.inherited(arguments);
-	},
+		postMixInProperties: function(){
+			// Copy value from srcNodeRef, unless user specified a value explicitly (or there is no srcNodeRef)
+			// TODO: parser will handle this in 2.0
+			if(!this.value && this.srcNodeRef){
+				this.value = this.srcNodeRef.value;
+			}
+			this.inherited(arguments);
+		},
 
-	buildRendering: function(){
-		this.inherited(arguments);
-		if(has("ie") && this.cols){ // attribute selectors is not supported in IE6
-			domClass.add(this.textbox, "dijitTextAreaCols");
-		}
-	},
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(has("ie") && this.cols){ // attribute selectors is not supported in IE6
+				domClass.add(this.textbox, "dijitTextAreaCols");
+			}
+		},
 
-	filter: function(/*String*/ value){
-		// Override TextBox.filter to deal with newlines... specifically (IIRC) this is for IE which writes newlines
-		// as \r\n instead of just \n
-		if(value){
-			value = value.replace(/\r/g,"");
-		}
-		return this.inherited(arguments);
-	},
+		filter: function(/*String*/ value){
+			// Override TextBox.filter to deal with newlines... specifically (IIRC) this is for IE which writes newlines
+			// as \r\n instead of just \n
+			if(value){
+				value = value.replace(/\r/g, "");
+			}
+			return this.inherited(arguments);
+		},
 
-	_onInput: function(/*Event?*/ e){
-		// Override TextBox._onInput() to enforce maxLength restriction
-		if(this.maxLength){
-			var maxLength = parseInt(this.maxLength);
-			var value = this.textbox.value.replace(/\r/g,'');
-			var overflow = value.length - maxLength;
-			if(overflow > 0){
-				var textarea = this.textbox;
-				if(textarea.selectionStart){
-					var pos = textarea.selectionStart;
-					var cr = 0;
-					if(has("opera")){
-						cr = (this.textbox.value.substring(0,pos).match(/\r/g) || []).length;
+		_onInput: function(/*Event?*/ e){
+			// Override TextBox._onInput() to enforce maxLength restriction
+			if(this.maxLength){
+				var maxLength = parseInt(this.maxLength);
+				var value = this.textbox.value.replace(/\r/g, '');
+				var overflow = value.length - maxLength;
+				if(overflow > 0){
+					var textarea = this.textbox;
+					if(textarea.selectionStart){
+						var pos = textarea.selectionStart;
+						var cr = 0;
+						if(has("opera")){
+							cr = (this.textbox.value.substring(0, pos).match(/\r/g) || []).length;
+						}
+						this.textbox.value = value.substring(0, pos - overflow - cr) + value.substring(pos - cr);
+						textarea.setSelectionRange(pos - overflow, pos - overflow);
+					}else if(this.ownerDocument.selection){ //IE
+						textarea.focus();
+						var range = this.ownerDocument.selection.createRange();
+						// delete overflow characters
+						range.moveStart("character", -overflow);
+						range.text = '';
+						// show cursor
+						range.select();
 					}
-					this.textbox.value = value.substring(0,pos-overflow-cr)+value.substring(pos-cr);
-					textarea.setSelectionRange(pos-overflow, pos-overflow);
-				}else if(win.doc.selection){ //IE
-					textarea.focus();
-					var range = win.doc.selection.createRange();
-					// delete overflow characters
-					range.moveStart("character", -overflow);
-					range.text = '';
-					// show cursor
-					range.select();
 				}
 			}
+			this.inherited(arguments);
 		}
-		this.inherited(arguments);
-	}
-});
-
+	});
 });
diff --git a/dijit/form/Slider.js b/dijit/form/Slider.js
index 3a3df38..128741f 100644
--- a/dijit/form/Slider.js
+++ b/dijit/form/Slider.js
@@ -10,9 +10,14 @@ define([
 
 	// module:
 	//		dijit/form/Slider
-	// summary:
-	//		Rollup of all the the Slider related widgets
-	//		For back-compat, remove for 2.0
 
 	kernel.deprecated("Call require() for HorizontalSlider / VerticalRule, explicitly rather than 'dijit.form.Slider' itself", "", "2.0");
+
+	/*=====
+	 return {
+		 // summary:
+		 //		Rollup of all the the Slider related widgets
+		 //		For back-compat, remove for 2.0
+	 };
+	 =====*/
 });
diff --git a/dijit/form/TextBox.js b/dijit/form/TextBox.js
index 89138f6..511566e 100644
--- a/dijit/form/TextBox.js
+++ b/dijit/form/TextBox.js
@@ -4,26 +4,19 @@ define([
 	"dojo/dom-style", // domStyle.getComputedStyle
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/_base/lang", // lang.hitch
-	"dojo/_base/sniff", // has("ie") has("mozilla")
-	"dojo/_base/window", // win.doc.selection.createRange
+	"dojo/on",
+	"dojo/sniff", // has("ie") has("mozilla")
 	"./_FormValueWidget",
 	"./_TextBoxMixin",
 	"dojo/text!./templates/TextBox.html",
-	".."	// to export dijit._setSelectionRange, remove in 2.0
-], function(declare, domConstruct, domStyle, kernel, lang, has, win,
+	"../main"	// to export dijit._setSelectionRange, remove in 2.0
+], function(declare, domConstruct, domStyle, kernel, lang, on, has,
 			_FormValueWidget, _TextBoxMixin, template, dijit){
 
-/*=====
-	var _FormValueWidget = dijit.form._FormValueWidget;
-	var _TextBoxMixin = dijit.form._TextBoxMixin;
-=====*/
-
 	// module:
 	//		dijit/form/TextBox
-	// summary:
-	//		A base class for textbox form inputs
 
-	var TextBox = declare(/*====="dijit.form.TextBox", =====*/ [_FormValueWidget, _TextBoxMixin], {
+	var TextBox = declare("dijit.form.TextBox" + (has("dojo-bidi") ? "_NoBidi" : ""), [_FormValueWidget, _TextBoxMixin], {
 		// summary:
 		//		A base class for textbox form inputs
 
@@ -42,12 +35,29 @@ define([
 			this.inherited(arguments);
 		},
 
-		_onInput: function(e){
+		postCreate: function(){
 			this.inherited(arguments);
-			if(this.intermediateChanges){ // _TextBoxMixin uses onInput
-				var _this = this;
-				// the setTimeout allows the key to post to the widget input box
-				setTimeout(function(){ _this._handleOnChange(_this.get('value'), false); }, 0);
+
+			if(has("ie") < 9){
+				// IE INPUT tag fontFamily has to be set directly using STYLE
+				// the defer gives IE a chance to render the TextBox and to deal with font inheritance
+				this.defer(function(){
+					try{
+						var s = domStyle.getComputedStyle(this.domNode); // can throw an exception if widget is immediately destroyed
+						if(s){
+							var ff = s.fontFamily;
+							if(ff){
+								var inputs = this.domNode.getElementsByTagName("INPUT");
+								if(inputs){
+									for(var i=0; i < inputs.length; i++){
+										inputs[i].style.fontFamily = ff;
+									}
+								}
+							}
+						}
+					}catch(e){/*when used in a Dialog, and this is called before the dialog is
+					 shown, s.fontFamily would trigger "Invalid Argument" error.*/}
+				});
 			}
 		},
 
@@ -58,16 +68,29 @@ define([
 				// dijitInputField class gives placeHolder same padding as the input field
 				// parent node already has dijitInputField class but it doesn't affect this <span>
 				// since it's position: absolute.
-				this._phspan = domConstruct.create('span',{className:'dijitPlaceHolder dijitInputField'},this.textbox,'after');
+				this._phspan = domConstruct.create('span',{ onmousedown:function(e){ e.preventDefault(); }, className:'dijitPlaceHolder dijitInputField'},this.textbox,'after');
+				this.own(on(this._phspan, "touchend, MSPointerUp", lang.hitch(this, function(){
+					// If the user clicks placeholder rather than the <input>, need programmatic focus.  Normally this
+					// is done in _FormWidgetMixin._onFocus() but after [30663] it's done on a delay, which is ineffective.
+					this.focus();
+				})));
 			}
 			this._phspan.innerHTML="";
-			this._phspan.appendChild(document.createTextNode(v));
+			this._phspan.appendChild(this._phspan.ownerDocument.createTextNode(v));
+			this._updatePlaceHolder();
+		},
+
+		_onInput: function(/*Event*/ evt){
+			// summary:
+			//		Called AFTER the input event has happened
+			//		See if the placeHolder text should be removed or added while editing.
+			this.inherited(arguments);
 			this._updatePlaceHolder();
 		},
 
 		_updatePlaceHolder: function(){
 			if(this._phspan){
-				this._phspan.style.display=(this.placeHolder&&!this.focused&&!this.textbox.value)?"":"none";
+				this._phspan.style.display = (this.placeHolder && !this.textbox.value) ? "" : "none";
 			}
 		},
 
@@ -81,7 +104,7 @@ define([
 			//		Deprecated.  Use get('displayedValue') instead.
 			// tags:
 			//		deprecated
-			kernel.deprecated(this.declaredClass+"::getDisplayedValue() is deprecated. Use set('displayedValue') instead.", "", "2.0");
+			kernel.deprecated(this.declaredClass+"::getDisplayedValue() is deprecated. Use get('displayedValue') instead.", "", "2.0");
 			return this.get('displayedValue');
 		},
 
@@ -98,6 +121,13 @@ define([
 			if(this.disabled){ return; }
 			this.inherited(arguments);
 			this._updatePlaceHolder();
+
+			if(has("mozilla")){
+				if(this.selectOnClick){
+					// clear selection so that the next mouse click doesn't reselect
+					this.textbox.selectionStart = this.textbox.selectionEnd = undefined;
+				}
+			}
 		},
 
 		_onFocus: function(/*String*/ by){
@@ -108,38 +138,11 @@ define([
 	});
 
 	if(has("ie")){
-		TextBox = declare(/*===== "dijit.form.TextBox.IEMixin", =====*/ TextBox, {
-			declaredClass: "dijit.form.TextBox",	// for user code referencing declaredClass
-
-			_isTextSelected: function(){
-				var range = win.doc.selection.createRange();
-				var parent = range.parentElement();
-				return parent == this.textbox && range.text.length == 0;
-			},
-
-			postCreate: function(){
-				this.inherited(arguments);
-				// IE INPUT tag fontFamily has to be set directly using STYLE
-				// the setTimeout gives IE a chance to render the TextBox and to deal with font inheritance
-				setTimeout(lang.hitch(this, function(){
-					try{
-						var s = domStyle.getComputedStyle(this.domNode); // can throw an exception if widget is immediately destroyed
-						if(s){
-							var ff = s.fontFamily;
-							if(ff){
-								var inputs = this.domNode.getElementsByTagName("INPUT");
-								if(inputs){
-									for(var i=0; i < inputs.length; i++){
-										inputs[i].style.fontFamily = ff;
-									}
-								}
-							}
-						}
-					}catch(e){/*when used in a Dialog, and this is called before the dialog is
-						shown, s.fontFamily would trigger "Invalid Argument" error.*/}
-				}), 0);
-			}
-		});
+		TextBox.prototype._isTextSelected = function(){
+			var range = this.ownerDocument.selection.createRange();
+			var parent = range.parentElement();
+			return parent == this.textbox && range.text.length > 0;
+		};
 
 		// Overrides definition of _setSelectionRange from _TextBoxMixin (TODO: move to _TextBoxMixin.js?)
 		dijit._setSelectionRange = _TextBoxMixin._setSelectionRange = function(/*DomNode*/ element, /*Number?*/ start, /*Number?*/ stop){
@@ -152,22 +155,16 @@ define([
 				r.select();
 			}
 		}
-	}else if(has("mozilla")){
-		TextBox = declare(/*===== "dijit.form.TextBox.MozMixin", =====*/TextBox, {
-			declaredClass: "dijit.form.TextBox",	// for user code referencing declaredClass
+	}
 
-			_onBlur: function(e){
+	if(has("dojo-bidi")){
+		TextBox = declare("dijit.form.TextBox", TextBox, {
+			_setPlaceHolderAttr: function(v){
 				this.inherited(arguments);
-				if(this.selectOnClick){
-						// clear selection so that the next mouse click doesn't reselect
-					this.textbox.selectionStart = this.textbox.selectionEnd = undefined;
-				}
+				this.applyTextDir(this._phspan);
 			}
 		});
-	}else{
-		TextBox.prototype.declaredClass = "dijit.form.TextBox";
 	}
-	lang.setObject("dijit.form.TextBox", TextBox);	// don't do direct assignment, it confuses API doc parser
 
 	return TextBox;
 });
diff --git a/dijit/form/Textarea.js b/dijit/form/Textarea.js
index 325c305..3550e5e 100644
--- a/dijit/form/Textarea.js
+++ b/dijit/form/Textarea.js
@@ -5,45 +5,33 @@ define([
 	"./SimpleTextarea"
 ], function(declare, domStyle, _ExpandingTextAreaMixin, SimpleTextarea){
 
-/*=====
-	var _ExpandingTextAreaMixin = dijit.form._ExpandingTextAreaMixin;
-	var SimpleTextarea = dijit.form.SimpleTextarea;
-=====*/
+	// module:
+	//		dijit/form/Textarea
 
-// module:
-//		dijit/form/Textarea
-// summary:
-//		A textarea widget that adjusts it's height according to the amount of data.
+	return declare("dijit.form.Textarea", [SimpleTextarea, _ExpandingTextAreaMixin], {
+		// summary:
+		//		A textarea widget that adjusts it's height according to the amount of data.
+		//
+		// description:
+		//		A textarea that dynamically expands/contracts (changing it's height) as
+		//		the user types, to display all the text without requiring a scroll bar.
+		//
+		//		Takes nearly all the parameters (name, value, etc.) that a vanilla textarea takes.
+		//		Rows is not supported since this widget adjusts the height.
 
 
-return declare("dijit.form.Textarea", [SimpleTextarea, _ExpandingTextAreaMixin], {
-	// summary:
-	//		A textarea widget that adjusts it's height according to the amount of data.
-	//
-	// description:
-	//		A textarea that dynamically expands/contracts (changing it's height) as
-	//		the user types, to display all the text without requiring a scroll bar.
-	//
-	//		Takes nearly all the parameters (name, value, etc.) that a vanilla textarea takes.
-	//		Rows is not supported since this widget adjusts the height.
-	//
-	// example:
-	// |	<textarea data-dojo-type="dijit.form.TextArea">...</textarea>
+		// TODO: for 2.0, rename this to ExpandingTextArea, and rename SimpleTextarea to TextArea
 
+		baseClass: "dijitTextBox dijitTextArea dijitExpandingTextArea",
 
-	// TODO: for 2.0, rename this to ExpandingTextArea, and rename SimpleTextarea to TextArea
+		// Override SimpleTextArea.cols to default to width:100%, for backward compatibility
+		cols: "",
 
-	baseClass: "dijitTextBox dijitTextArea dijitExpandingTextArea",
-
-	// Override SimpleTextArea.cols to default to width:100%, for backward compatibility
-	cols: "",
-
-	buildRendering: function(){
-		this.inherited(arguments);
-
-		// tweak textarea style to reduce browser differences
-		domStyle.set(this.textbox, { overflowY: 'hidden', overflowX: 'auto', boxSizing: 'border-box', MsBoxSizing: 'border-box', WebkitBoxSizing: 'border-box', MozBoxSizing: 'border-box' });
-	}
-});
+		buildRendering: function(){
+			this.inherited(arguments);
 
+			// tweak textarea style to reduce browser differences
+			domStyle.set(this.textbox, { overflowY: 'hidden', overflowX: 'auto', boxSizing: 'border-box', MsBoxSizing: 'border-box', WebkitBoxSizing: 'border-box', MozBoxSizing: 'border-box' });
+		}
+	});
 });
diff --git a/dijit/form/TimeTextBox.js b/dijit/form/TimeTextBox.js
index 5320f1f..f40a3b2 100644
--- a/dijit/form/TimeTextBox.js
+++ b/dijit/form/TimeTextBox.js
@@ -6,22 +6,13 @@ define([
 	"./_DateTimeTextBox"
 ], function(declare, keys, lang, _TimePicker, _DateTimeTextBox){
 
-/*=====
-	var _TimePicker = dijit._TimePicker;
-	var _DateTimeTextBox = dijit.form._DateTimeTextBox;
-=====*/
-
 	// module:
 	//		dijit/form/TimeTextBox
-	// summary:
-	//		A validating, serializable, range-bound time text box with a drop down time picker
 
 
 	/*=====
-	declare(
-		"dijit.form.TimeTextBox.__Constraints",
-		[dijit.form._DateTimeTextBox.__Constraints, dijit._TimePicker.__Constraints]
-	);
+	var __Constraints = declare([_DateTimeTextBox.__Constraints, _TimePicker.__Constraints], {
+	});
 	=====*/
 
 	return declare("dijit.form.TimeTextBox", _DateTimeTextBox, {
@@ -33,7 +24,7 @@ define([
 		_selector: "time",
 
 /*=====
-		// constraints: dijit.form.TimeTextBox.__Constraints
+		// constraints: __Constraints
 		constraints:{},
 =====*/
 
@@ -41,16 +32,19 @@ define([
 		//		The value of this widget as a JavaScript Date object.  Note that the date portion implies time zone and daylight savings rules.
 		//
 		//		Example:
-		// |	new dijit.form.TimeTextBox({value: stamp.fromISOString("T12:59:59", new Date())})
+		// |	new dijit/form/TimeTextBox({value: stamp.fromISOString("T12:59:59", new Date())})
 		//
 		//		When passed to the parser in markup, must be specified according to locale-independent
 		//		`stamp.fromISOString` format.
 		//
 		//		Example:
-		// |	<input data-dojo-type='dijit.form.TimeTextBox' value='T12:34:00'>
+		// |	<input data-dojo-type='dijit/form/TimeTextBox' value='T12:34:00'>
 		value: new Date(""),		// value.toString()="NaN"
 		//FIXME: in markup, you have no control over daylight savings
 
+		// Add scrollbars if necessary so that dropdown doesn't cover the <input>
+		maxHeight: -1,
+
 		_onKey: function(evt){
 			if(this.disabled || this.readOnly){ return; }
 			this.inherited(arguments);
@@ -66,9 +60,9 @@ define([
 					// these keys have special meaning
 					break;
 				default:
-					// setTimeout() because the keystroke hasn't yet appeared in the <input>,
+					// defer() because the keystroke hasn't yet appeared in the <input>,
 					// so the get('displayedValue') call below won't give the result we want.
-					setTimeout(lang.hitch(this, function(){
+					this.defer(function(){
 						// set this.filterString to the filter to apply to the drop down list;
 						// it will be used in openDropDown()
 						var val = this.get('displayedValue');
@@ -81,7 +75,7 @@ define([
 							this.closeDropDown();
 						}
 						this.openDropDown();
-					}), 0);
+					});
 			}
 		}
 	});
diff --git a/dijit/form/ToggleButton.js b/dijit/form/ToggleButton.js
index 6cc481d..f61390c 100644
--- a/dijit/form/ToggleButton.js
+++ b/dijit/form/ToggleButton.js
@@ -5,21 +5,14 @@ define([
 	"./_ToggleButtonMixin"
 ], function(declare, kernel, Button, _ToggleButtonMixin){
 
-/*=====
-	var Button = dijit.form.Button;
-	var _ToggleButtonMixin = dijit.form._ToggleButtonMixin;
-=====*/
-
 	// module:
 	//		dijit/form/ToggleButton
-	// summary:
-	//		A templated button widget that can be in two states (checked or not).
 
 
 	return declare("dijit.form.ToggleButton", [Button, _ToggleButtonMixin], {
 		// summary:
 		//		A templated button widget that can be in two states (checked or not).
-		//		Can be base class for things like tabs or checkbox or radio buttons
+		//		Can be base class for things like tabs or checkbox or radio buttons.
 
 		baseClass: "dijitToggleButton",
 
diff --git a/dijit/form/ValidationTextBox.js b/dijit/form/ValidationTextBox.js
index 670d0f1..fd88b01 100644
--- a/dijit/form/ValidationTextBox.js
+++ b/dijit/form/ValidationTextBox.js
@@ -1,42 +1,32 @@
 define([
 	"dojo/_base/declare", // declare
+	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/i18n", // i18n.getLocalization
 	"./TextBox",
 	"../Tooltip",
 	"dojo/text!./templates/ValidationTextBox.html",
 	"dojo/i18n!./nls/validate"
-], function(declare, i18n, TextBox, Tooltip, template){
-
-/*=====
-	var Tooltip = dijit.Tooltip;
-	var TextBox = dijit.form.TextBox;
-=====*/
+], function(declare, kernel, i18n, TextBox, Tooltip, template){
 
 	// module:
 	//		dijit/form/ValidationTextBox
-	// summary:
-	//		Base class for textbox widgets with the ability to validate content of various types and provide user feedback.
 
 
 	/*=====
-		dijit.form.ValidationTextBox.__Constraints = function(){
-			// locale: String
-			//		locale used for validation, picks up value from this widget's lang attribute
-			// _flags_: anything
-			//		various flags passed to regExpGen function
-			this.locale = "";
-			this._flags_ = "";
-		}
+	var __Constraints = {
+		// locale: String
+		//		locale used for validation, picks up value from this widget's lang attribute
+		// _flags_: anything
+		//		various flags passed to pattern function
+	};
 	=====*/
 
-	return declare("dijit.form.ValidationTextBox", TextBox, {
+	var ValidationTextBox;
+	return ValidationTextBox = declare("dijit.form.ValidationTextBox", TextBox, {
 		// summary:
 		//		Base class for textbox widgets with the ability to validate content of various types and provide user feedback.
-		// tags:
-		//		protected
 
 		templateString: template,
-		baseClass: "dijitTextBox dijitValidationTextBox",
 
 		// required: Boolean
 		//		User is required to enter data into this field.
@@ -52,15 +42,15 @@ define([
 		promptMessage: "",
 
 		// invalidMessage: String
-		// 		The message to display if value is invalid.
+		//		The message to display if value is invalid.
 		//		The translated string value is read from the message file by default.
-		// 		Set to "" to use the promptMessage instead.
+		//		Set to "" to use the promptMessage instead.
 		invalidMessage: "$_unset_$",
 
 		// missingMessage: String
-		// 		The message to display if value is empty and the field is required.
+		//		The message to display if value is empty and the field is required.
 		//		The translated string value is read from the message file by default.
-		// 		Set to "" to use the invalidMessage instead.
+		//		Set to "" to use the invalidMessage instead.
 		missingMessage: "$_unset_$",
 
 		// message: String
@@ -69,22 +59,23 @@ define([
 		//		displayed when the field is focused.
 		message: "",
 
-		// constraints: dijit.form.ValidationTextBox.__Constraints
+		// constraints: __Constraints
 		//		user-defined object needed to pass parameters to the validator functions
 		constraints: {},
 
-		// regExp: [extension protected] String
-		//		regular expression string used to validate the input
-		//		Do not specify both regExp and regExpGen
-		regExp: ".*",
+		// pattern: [extension protected] String|Function(constraints) returning a string.
+		//		This defines the regular expression used to validate the input.
+		//		Do not add leading ^ or $ characters since the widget adds these.
+		//		A function may be used to generate a valid pattern when dependent on constraints or other runtime factors.
+		//		set('pattern', String|Function).
+		pattern: ".*",
+
+		// regExp: Deprecated [extension protected] String.  Use "pattern" instead.
+		regExp: "",
 
-		regExpGen: function(/*dijit.form.ValidationTextBox.__Constraints*/ /*===== constraints =====*/){
+		regExpGen: function(/*__Constraints*/ /*===== constraints =====*/){
 			// summary:
-			//		Overridable function used to generate regExp when dependent on constraints.
-			//		Do not specify both regExp and regExpGen.
-			// tags:
-			//		extension protected
-			return this.regExp; // String
+			//		Deprecated.  Use set('pattern', Function) instead.
 		},
 
 		// state: [readonly] String
@@ -92,22 +83,36 @@ define([
 		state: "",
 
 		// tooltipPosition: String[]
-		//		See description of `dijit.Tooltip.defaultPosition` for details on this parameter.
+		//		See description of `dijit/Tooltip.defaultPosition` for details on this parameter.
 		tooltipPosition: [],
 
+		_deprecateRegExp: function(attr, value){
+			if(value != ValidationTextBox.prototype[attr]){
+				kernel.deprecated("ValidationTextBox id="+this.id+", set('" + attr + "', ...) is deprecated.  Use set('pattern', ...) instead.", "", "2.0");
+				this.set('pattern', value);
+			}
+		},
+		_setRegExpGenAttr: function(/*Function*/ newFcn){
+			this._deprecateRegExp("regExpGen", newFcn);
+			this._set("regExpGen", this._computeRegexp); // backward compat with this.regExpGen(this.constraints)
+		},
+		_setRegExpAttr: function(/*String*/ value){
+			this._deprecateRegExp("regExp", value);
+		},
+
 		_setValueAttr: function(){
 			// summary:
 			//		Hook so set('value', ...) works.
 			this.inherited(arguments);
-			this.validate(this.focused);
+			this._refreshState();
 		},
 
-		validator: function(/*anything*/ value, /*dijit.form.ValidationTextBox.__Constraints*/ constraints){
+		validator: function(/*anything*/ value, /*__Constraints*/ constraints){
 			// summary:
 			//		Overridable function used to validate the text input against the regular expression.
 			// tags:
 			//		protected
-			return (new RegExp("^(?:" + this.regExpGen(constraints) + ")"+(this.required?"":"?")+"$")).test(value) &&
+			return (new RegExp("^(?:" + this._computeRegexp(constraints) + ")"+(this.required?"":"?")+"$")).test(value) &&
 				(!this.required || !this._isEmpty(value)) &&
 				(this._isEmpty(value) || this.parse(value, constraints) !== undefined); // Boolean
 		},
@@ -125,7 +130,7 @@ define([
 			//		Can override with your own routine in a subclass.
 			// tags:
 			//		protected
-			return this.validator(this.textbox.value, this.constraints);
+			return this.validator(this.textbox.value, this.get('constraints'));
 		},
 
 		_isEmpty: function(value){
@@ -139,7 +144,11 @@ define([
 			//		Return an error message to show if appropriate
 			// tags:
 			//		protected
-			return (this.required && this._isEmpty(this.textbox.value)) ? this.missingMessage : this.invalidMessage; // String
+			var invalid = this.invalidMessage == "$_unset_$" ? this.messages.invalidMessage :
+				!this.invalidMessage ? this.promptMessage : this.invalidMessage;
+			var missing = this.missingMessage == "$_unset_$" ? this.messages.missingMessage :
+				!this.missingMessage ? invalid : this.missingMessage;
+			return (this.required && this._isEmpty(this.textbox.value)) ? missing : invalid; // String
 		},
 
 		getPromptMessage: function(/*Boolean*/ /*===== isFocused =====*/){
@@ -163,7 +172,7 @@ define([
 			if(isValid){ this._maskValidSubsetError = true; }
 			var isEmpty = this._isEmpty(this.textbox.value);
 			var isValidSubset = !isValid && isFocused && this._isValidSubset();
-			this._set("state", isValid ? "" : (((((!this._hasBeenBlurred || isFocused) && isEmpty) || isValidSubset) && this._maskValidSubsetError) ? "Incomplete" : "Error"));
+			this._set("state", isValid ? "" : (((((!this._hasBeenBlurred || isFocused) && isEmpty) || isValidSubset) && (this._maskValidSubsetError || (isValidSubset && !this._hasBeenBlurred && isFocused))) ? "Incomplete" : "Error"));
 			this.focusNode.setAttribute("aria-invalid", isValid ? "false" : "true");
 
 			if(this.state == "Error"){
@@ -195,68 +204,95 @@ define([
 
 		_refreshState: function(){
 			// Overrides TextBox._refreshState()
-			this.validate(this.focused);
+			if(this._created){ // should instead be this._started but that would require all programmatic ValidationTextBox instantiations to call startup()
+				this.validate(this.focused);
+			}
 			this.inherited(arguments);
 		},
 
 		//////////// INITIALIZATION METHODS ///////////////////////////////////////
 
-		constructor: function(){
+		constructor: function(params /*===== , srcNodeRef =====*/){
+			// summary:
+			//		Create the widget.
+			// params: Object|null
+			//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+			//		and functions, typically callbacks like onClick.
+			//		The hash can contain any of the widget's properties, excluding read-only properties.
+			// srcNodeRef: DOMNode|String?
+			//		If a srcNodeRef (DOM node) is specified, replace srcNodeRef with my generated DOM tree.
+
 			this.constraints = {};
+			this.baseClass += ' dijitValidationTextBox';
+		},
+
+		startup: function(){
+			this.inherited(arguments);
+			this._refreshState(); // after all _set* methods have run
 		},
 
-		_setConstraintsAttr: function(/*Object*/ constraints){
+		_setConstraintsAttr: function(/*__Constraints*/ constraints){
 			if(!constraints.locale && this.lang){
 				constraints.locale = this.lang;
 			}
 			this._set("constraints", constraints);
-			this._computePartialRE();
+			this._refreshState();
 		},
 
-		_computePartialRE: function(){
-			var p = this.regExpGen(this.constraints);
-			this.regExp = p;
-			var partialre = "";
-			// parse the regexp and produce a new regexp that matches valid subsets
-			// if the regexp is .* then there's no use in matching subsets since everything is valid
-			if(p != ".*"){ this.regExp.replace(/\\.|\[\]|\[.*?[^\\]{1}\]|\{.*?\}|\(\?[=:!]|./g,
-				function(re){
-					switch(re.charAt(0)){
-						case '{':
-						case '+':
-						case '?':
-						case '*':
-						case '^':
-						case '$':
-						case '|':
-						case '(':
-							partialre += re;
-							break;
-						case ")":
-							partialre += "|$)";
-							break;
-						 default:
-							partialre += "(?:"+re+"|$)";
-							break;
-					}
+		_setPatternAttr: function(/*String|Function*/ pattern){
+			this._set("pattern", pattern); // don't set on INPUT to avoid native HTML5 validation
+		},
+
+		_computeRegexp: function(/*__Constraints*/ constraints){
+			// summary:
+			//		Hook to get the current regExp and to compute the partial validation RE.
+
+			var p = this.pattern;
+			if(typeof p == "function"){
+				p = p.call(this, constraints);
+			}
+			if(p != this._lastRegExp){
+				var partialre = "";
+				this._lastRegExp = p;
+				// parse the regexp and produce a new regexp that matches valid subsets
+				// if the regexp is .* then there's no use in matching subsets since everything is valid
+				if(p != ".*"){
+					p.replace(/\\.|\[\]|\[.*?[^\\]{1}\]|\{.*?\}|\(\?[=:!]|./g,
+					function(re){
+						switch(re.charAt(0)){
+							case '{':
+							case '+':
+							case '?':
+							case '*':
+							case '^':
+							case '$':
+							case '|':
+							case '(':
+								partialre += re;
+								break;
+							case ")":
+								partialre += "|$)";
+								break;
+							 default:
+								partialre += "(?:"+re+"|$)";
+								break;
+						}
+					});
 				}
-			);}
-			try{ // this is needed for now since the above regexp parsing needs more test verification
-				"".search(partialre);
-			}catch(e){ // should never be here unless the original RE is bad or the parsing is bad
-				partialre = this.regExp;
-				console.warn('RegExp error in ' + this.declaredClass + ': ' + this.regExp);
-			} // should never be here unless the original RE is bad or the parsing is bad
-			this._partialre = "^(?:" + partialre + ")$";
+				try{ // this is needed for now since the above regexp parsing needs more test verification
+					"".search(partialre);
+				}catch(e){ // should never be here unless the original RE is bad or the parsing is bad
+					partialre = this.pattern;
+					console.warn('RegExp error in ' + this.declaredClass + ': ' + this.pattern);
+				} // should never be here unless the original RE is bad or the parsing is bad
+				this._partialre = "^(?:" + partialre + ")$";
+			}
+			return p;
 		},
 
 		postMixInProperties: function(){
 			this.inherited(arguments);
 			this.messages = i18n.getLocalization("dijit.form", "validate", this.lang);
-			if(this.invalidMessage == "$_unset_$"){ this.invalidMessage = this.messages.invalidMessage; }
-			if(!this.invalidMessage){ this.invalidMessage = this.promptMessage; }
-			if(this.missingMessage == "$_unset_$"){ this.missingMessage = this.messages.missingMessage; }
-			if(!this.missingMessage){ this.missingMessage = this.invalidMessage; }
 			this._setConstraintsAttr(this.constraints); // this needs to happen now (and later) due to codependency on _set*Attr calls attachPoints
 		},
 
@@ -277,7 +313,7 @@ define([
 		},
 
 		reset:function(){
-			// Overrides dijit.form.TextBox.reset() by also
+			// Overrides dijit/form/TextBox.reset() by also
 			// hiding errors about partial matches
 			this._maskValidSubsetError = true;
 			this.inherited(arguments);
diff --git a/dijit/form/VerticalRule.js b/dijit/form/VerticalRule.js
index 389dcbd..4f0397e 100644
--- a/dijit/form/VerticalRule.js
+++ b/dijit/form/VerticalRule.js
@@ -3,18 +3,12 @@ define([
 	"./HorizontalRule"
 ], function(declare, HorizontalRule){
 
-/*=====
-	var HorizontalRule = dijit.form.HorizontalRule;
-=====*/
-
 	// module:
 	//		dijit/form/VerticalRule
-	// summary:
-	//		Hash marks for the `dijit.form.VerticalSlider`
 
 	return declare("dijit.form.VerticalRule", HorizontalRule, {
 		// summary:
-		//		Hash marks for the `dijit.form.VerticalSlider`
+		//		Hash marks for the `dijit/form/VerticalSlider`
 
 		templateString: '<div class="dijitRuleContainer dijitRuleContainerV"></div>',
 		_positionPrefix: '<div class="dijitRuleMark dijitRuleMarkV" style="top:',
diff --git a/dijit/form/VerticalRuleLabels.js b/dijit/form/VerticalRuleLabels.js
index bcef05b..d9b121f 100644
--- a/dijit/form/VerticalRuleLabels.js
+++ b/dijit/form/VerticalRuleLabels.js
@@ -3,18 +3,12 @@ define([
 	"./HorizontalRuleLabels"
 ], function(declare, HorizontalRuleLabels){
 
-/*=====
-	var HorizontalRuleLabels = dijit.form.HorizontalRuleLabels;
-=====*/
-
 	// module:
 	//		dijit/form/VerticalRuleLabels
-	// summary:
-	//		Labels for the `dijit.form.VerticalSlider`
 
 	return declare("dijit.form.VerticalRuleLabels", HorizontalRuleLabels, {
 		// summary:
-		//		Labels for the `dijit.form.VerticalSlider`
+		//		Labels for the `dijit/form/VerticalSlider`
 
 		templateString: '<div class="dijitRuleContainer dijitRuleContainerV dijitRuleLabelsContainer dijitRuleLabelsContainerV"></div>',
 
diff --git a/dijit/form/VerticalSlider.js b/dijit/form/VerticalSlider.js
index f786ee9..dbdae85 100644
--- a/dijit/form/VerticalSlider.js
+++ b/dijit/form/VerticalSlider.js
@@ -4,15 +4,8 @@ define([
 	"dojo/text!./templates/VerticalSlider.html"
 ], function(declare, HorizontalSlider, template){
 
-/*=====
-	var HorizontalSlider = dijit.form.HorizontalSlider;
-=====*/
-
 	// module:
 	//		dijit/form/VerticalSlider
-	// summary:
-	//		A form widget that allows one to select a value with a vertically draggable handle
-
 
 	return declare("dijit.form.VerticalSlider", HorizontalSlider, {
 		// summary:
diff --git a/dijit/form/_AutoCompleterMixin.js b/dijit/form/_AutoCompleterMixin.js
index ca32797..e0f262b 100644
--- a/dijit/form/_AutoCompleterMixin.js
+++ b/dijit/form/_AutoCompleterMixin.js
@@ -1,65 +1,33 @@
 define([
-	"dojo/_base/connect", // keys keys.SHIFT
-	"dojo/data/util/filter", // patternToRegExp
+	"dojo/aspect",
 	"dojo/_base/declare", // declare
-	"dojo/_base/Deferred", // Deferred.when
 	"dojo/dom-attr", // domAttr.get
-	"dojo/_base/event", // event.stop
 	"dojo/keys",
 	"dojo/_base/lang", // lang.clone lang.hitch
 	"dojo/query", // query
 	"dojo/regexp", // regexp.escapeString
-	"dojo/_base/sniff", // has("ie")
-	"dojo/string", // string.substitute
-	"dojo/_base/window", // win.doc.selection.createRange
+	"dojo/sniff", // has("ie")
 	"./DataList",
-	"../registry",	// registry.byId
-	"./_TextBoxMixin"	// defines _TextBoxMixin.selectInputText
-], function(connect, filter, declare, Deferred, domAttr, event, keys, lang, query, regexp, has, string, win,
-			DataList, registry, _TextBoxMixin){
+	"./_TextBoxMixin", // defines _TextBoxMixin.selectInputText
+	"./_SearchMixin"
+], function(aspect, declare, domAttr, keys, lang, query, regexp, has, DataList, _TextBoxMixin, SearchMixin){
 
 	// module:
 	//		dijit/form/_AutoCompleterMixin
-	// summary:
-	//		A mixin that implements the base functionality for `dijit.form.ComboBox`/`dijit.form.FilteringSelect`
 
-
-	return declare("dijit.form._AutoCompleterMixin", null, {
+	var AutoCompleterMixin = declare("dijit.form._AutoCompleterMixin", SearchMixin, {
 		// summary:
-		//		A mixin that implements the base functionality for `dijit.form.ComboBox`/`dijit.form.FilteringSelect`
+		//		A mixin that implements the base functionality for `dijit/form/ComboBox`/`dijit/form/FilteringSelect`
 		// description:
-		//		All widgets that mix in dijit.form._AutoCompleterMixin must extend `dijit.form._FormValueWidget`.
+		//		All widgets that mix in dijit/form/_AutoCompleterMixin must extend `dijit/form/_FormValueWidget`.
 		// tags:
 		//		protected
 
 		// item: Object
-		//		This is the item returned by the dojo.data.store implementation that
+		//		This is the item returned by the dojo/store/api/Store implementation that
 		//		provides the data for this ComboBox, it's the currently selected item.
 		item: null,
 
-		// pageSize: Integer
-		//		Argument to data provider.
-		//		Specifies number of search results per page (before hitting "next" button)
-		pageSize: Infinity,
-
-		// store: [const] dojo.store.api.Store
-		//		Reference to data provider object used by this ComboBox
-		store: null,
-
-		// fetchProperties: Object
-		//		Mixin to the store's fetch.
-		//		For example, to set the sort order of the ComboBox menu, pass:
-		//	|	{ sort: [{attribute:"name",descending: true}] }
-		//		To override the default queryOptions so that deep=false, do:
-		//	|	{ queryOptions: {ignoreCase: true, deep: false} }
-		fetchProperties:{},
-
-		// query: Object
-		//		A query that can be passed to 'store' to initially filter the items,
-		//		before doing further filtering based on `searchAttr` and the key.
-		//		Any reference to the `searchAttr` is ignored.
-		query: {},
-
 		// autoComplete: Boolean
 		//		If user types in a partial string, and then tab out of the `<input>` box,
 		//		automatically copy the first entry displayed in the drop down list to
@@ -67,7 +35,7 @@ define([
 		autoComplete: true,
 
 		// highlightMatch: String
-		// 		One of: "first", "all" or "none".
+		//		One of: "first", "all" or "none".
 		//
 		//		If the ComboBox/FilteringSelect opens with the search results and the searched
 		//		string can be found, it will be highlighted.  If set to "all"
@@ -77,16 +45,6 @@ define([
 		//		interfere with any HTML markup an HTML label might contain.
 		highlightMatch: "first",
 
-		// searchDelay: Integer
-		//		Delay in milliseconds between when user types something and we start
-		//		searching based on that value
-		searchDelay: 100,
-
-		// searchAttr: String
-		//		Search for items in the data store where this attribute (in the item)
-		//		matches what the user typed
-		searchAttr: "name",
-
 		// labelAttr: String?
 		//		The entries in the drop down list come from this attribute in the
 		//		dojo.data items.
@@ -98,21 +56,6 @@ define([
 		//		Can be "html" or "text".
 		labelType: "text",
 
-		// queryExpr: String
-		//		This specifies what query ComboBox/FilteringSelect sends to the data store,
-		//		based on what the user has typed.  Changing this expression will modify
-		//		whether the drop down shows only exact matches, a "starting with" match,
-		//		etc.  Use it in conjunction with highlightMatch.
-		//		dojo.data query expression pattern.
-		//		`${0}` will be substituted for the user text.
-		//		`*` is used for wildcards.
-		//		`${0}*` means "starts with", `*${0}*` means "contains", `${0}` means "is"
-		queryExpr: "${0}*",
-
-		// ignoreCase: Boolean
-		//		Set true if the ComboBox/FilteringSelect should ignore case when matching possible items
-		ignoreCase: true,
-
 		// Flags to _HasDropDown to limit height of drop down to make it fit in viewport
 		maxHeight: -1,
 
@@ -127,19 +70,19 @@ define([
 				pos = element.selectionStart;
 			}else if(has("ie")){
 				// in the case of a mouse click in a popup being handled,
-				// then the win.doc.selection is not the textarea, but the popup
-				// var r = win.doc.selection.createRange();
+				// then the document.selection is not the textarea, but the popup
+				// var r = document.selection.createRange();
 				// hack to get IE 6 to play nice. What a POS browser.
-				var tr = win.doc.selection.createRange().duplicate();
+				var tr = element.ownerDocument.selection.createRange().duplicate();
 				var ntr = element.createTextRange();
-				tr.move("character",0);
-				ntr.move("character",0);
+				tr.move("character", 0);
+				ntr.move("character", 0);
 				try{
 					// If control doesn't have focus, you get an exception.
 					// Seems to happen on reverse-tab, but can also happen on tab (seems to be a race condition - only happens sometimes).
 					// There appears to be no workaround for this - googled for quite a while.
 					ntr.setEndPoint("EndToEnd", tr);
-					pos = String(ntr.text).replace(/\r/g,"").length;
+					pos = String(ntr.text).replace(/\r/g, "").length;
 				}catch(e){
 					// If focus has shifted, 0 is fine for caret pos.
 				}
@@ -156,59 +99,41 @@ define([
 			// Additional code to set disabled state of ComboBox node.
 			// Overrides _FormValueWidget._setDisabledAttr() or ValidationTextBox._setDisabledAttr().
 			this.inherited(arguments);
-			this.domNode.setAttribute("aria-disabled", value);
-		},
-
-		_abortQuery: function(){
-			// stop in-progress query
-			if(this.searchTimer){
-				clearTimeout(this.searchTimer);
-				this.searchTimer = null;
-			}
-			if(this._fetchHandle){
-				if(this._fetchHandle.cancel){
-					this._cancelingQuery = true;
-					this._fetchHandle.cancel();
-					this._cancelingQuery = false;
-				}
-				this._fetchHandle = null;
-			}
-		},
-
-		_onInput: function(/*Event*/ evt){
-			// summary:
-			//		Handles paste events
-			this.inherited(arguments);
-			if(evt.charOrCode == 229){ // IME or cut/paste event
-				this._onKey(evt);
-			}
+			this.domNode.setAttribute("aria-disabled", value ? "true" : "false");
 		},
 
 		_onKey: function(/*Event*/ evt){
 			// summary:
 			//		Handles keyboard events
 
-			var key = evt.charOrCode;
+			if(evt.charCode >= 32){
+				return;
+			} // alphanumeric reserved for searching
+
+			var key = evt.charCode || evt.keyCode;
 
 			// except for cutting/pasting case - ctrl + x/v
-			if(evt.altKey || ((evt.ctrlKey || evt.metaKey) && (key != 'x' && key != 'v')) || key == keys.SHIFT){
-				return; // throw out weird key combinations and spurious events
+			if(key == keys.ALT || key == keys.CTRL || key == keys.META || key == keys.SHIFT){
+				return; // throw out spurious events
 			}
 
-			var doSearch = false;
 			var pw = this.dropDown;
 			var highlighted = null;
-			this._prev_key_backspace = false;
 			this._abortQuery();
 
 			// _HasDropDown will do some of the work:
-			//		1. when drop down is not yet shown:
-			//			- if user presses the down arrow key, call loadDropDown()
-			//		2. when drop down is already displayed:
-			//			- on ESC key, call closeDropDown()
-			//			- otherwise, call dropDown.handleKey() to process the keystroke
+			//
+			//	1. when drop down is not yet shown:
+			//		- if user presses the down arrow key, call loadDropDown()
+			//	2. when drop down is already displayed:
+			//		- on ESC key, call closeDropDown()
+			//		- otherwise, call dropDown.handleKey() to process the keystroke
 			this.inherited(arguments);
 
+			if(evt.altKey || evt.ctrlKey || evt.metaKey){
+				return;
+			} // don't process keys with modifiers  - but we want shift+TAB
+
 			if(this._opened){
 				highlighted = pw.getHighlightedOption();
 			}
@@ -222,7 +147,8 @@ define([
 					if(this._opened){
 						this._announceOption(highlighted);
 					}
-					event.stop(evt);
+					evt.stopPropagation();
+					evt.preventDefault();
 					break;
 
 				case keys.ENTER:
@@ -233,41 +159,38 @@ define([
 						// only stop event on prev/next
 						if(highlighted == pw.nextButton){
 							this._nextSearch(1);
-							event.stop(evt);
+							// prevent submit
+							evt.stopPropagation();
+							evt.preventDefault();
 							break;
 						}else if(highlighted == pw.previousButton){
 							this._nextSearch(-1);
-							event.stop(evt);
+							// prevent submit
+							evt.stopPropagation();
+							evt.preventDefault();
 							break;
 						}
+						// prevent submit if ENTER was to choose an item
+						evt.stopPropagation();
+						evt.preventDefault();
 					}else{
 						// Update 'value' (ex: KY) according to currently displayed text
 						this._setBlurValue(); // set value if needed
 						this._setCaretPos(this.focusNode, this.focusNode.value.length); // move cursor to end and cancel highlighting
 					}
-					// default case:
-					// if enter pressed while drop down is open, or for FilteringSelect,
-					// if we are in the middle of a query to convert a directly typed in value to an item,
-					// prevent submit
-					if(this._opened || this._fetchHandle){
-						event.stop(evt);
-					}
-					// fall through
+				// fall through
 
 				case keys.TAB:
 					var newvalue = this.get('displayedValue');
 					//	if the user had More Choices selected fall into the
 					//	_onBlur handler
-					if(pw && (
-						newvalue == pw._messages["previousMessage"] ||
-						newvalue == pw._messages["nextMessage"])
-					){
+					if(pw && (newvalue == pw._messages["previousMessage"] || newvalue == pw._messages["nextMessage"])){
 						break;
 					}
 					if(highlighted){
 						this._selectOption(highlighted);
 					}
-					// fall through
+				// fall through
 
 				case keys.ESCAPE:
 					if(this._opened){
@@ -275,57 +198,27 @@ define([
 						this.closeDropDown();
 					}
 					break;
-
-				case ' ':
-					if(highlighted){
-						// user is effectively clicking a choice in the drop down menu
-						event.stop(evt);
-						this._selectOption(highlighted);
-						this.closeDropDown();
-					}else{
-						// user typed a space into the input box, treat as normal character
-						doSearch = true;
-					}
-					break;
-
-				case keys.DELETE:
-				case keys.BACKSPACE:
-					this._prev_key_backspace = true;
-					doSearch = true;
-					break;
-
-				default:
-					// Non char keys (F1-F12 etc..)  shouldn't open list.
-					// Ascii characters and IME input (Chinese, Japanese etc.) should.
-					//IME input produces keycode == 229.
-					doSearch = typeof key == 'string' || key == 229;
-			}
-			if(doSearch){
-				// need to wait a tad before start search so that the event
-				// bubbles through DOM and we have value visible
-				this.item = undefined; // undefined means item needs to be set
-				this.searchTimer = setTimeout(lang.hitch(this, "_startSearchFromInput"),1);
 			}
 		},
 
 		_autoCompleteText: function(/*String*/ text){
 			// summary:
-			// 		Fill in the textbox with the first item from the drop down
-			// 		list, and highlight the characters that were
-			// 		auto-completed. For example, if user typed "CA" and the
-			// 		drop down list appeared, the textbox would be changed to
-			// 		"California" and "ifornia" would be highlighted.
+			//		Fill in the textbox with the first item from the drop down
+			//		list, and highlight the characters that were
+			//		auto-completed. For example, if user typed "CA" and the
+			//		drop down list appeared, the textbox would be changed to
+			//		"California" and "ifornia" would be highlighted.
 
 			var fn = this.focusNode;
 
 			// IE7: clear selection so next highlight works all the time
 			_TextBoxMixin.selectInputText(fn, fn.value.length);
 			// does text autoComplete the value in the textbox?
-			var caseFilter = this.ignoreCase? 'toLowerCase' : 'substr';
+			var caseFilter = this.ignoreCase ? 'toLowerCase' : 'substr';
 			if(text[caseFilter](0).indexOf(this.focusNode.value[caseFilter](0)) == 0){
 				var cpos = this.autoComplete ? this._getCaretPos(fn) : fn.value.length;
 				// only try to extend if we added the last character at the end of the input
-				if((cpos+1) > fn.value.length){
+				if((cpos + 1) > fn.value.length){
 					// only add to input node as we would overwrite Capitalisation of chars
 					// actually, that is ok
 					fn.value = text;//.substr(cpos);
@@ -346,19 +239,16 @@ define([
 			//		1. generates drop-down list and calls _showResultList() to display it
 			//		2. if this result list is from user pressing "more choices"/"previous choices"
 			//			then tell screen reader to announce new option
-			this._fetchHandle = null;
-			if(	this.disabled ||
-				this.readOnly ||
-				(query[this.searchAttr] !== this._lastQuery)	// TODO: better way to avoid getting unwanted notify
-			){
-				return;
-			}
 			var wasSelected = this.dropDown.getHighlightedOption();
 			this.dropDown.clearResultList();
 			if(!results.length && options.start == 0){ // if no results and not just the previous choices button
 				this.closeDropDown();
 				return;
 			}
+			this._nextSearch = this.dropDown.onPage = lang.hitch(this, function(direction){
+				results.nextPage(direction !== -1);
+				this.focus();
+			});
 
 			// Fill in the textbox with the first item from the drop down list,
 			// and highlight the characters that were auto-completed. For
@@ -366,7 +256,7 @@ define([
 			// textbox would be changed to "California" and "ifornia" would be
 			// highlighted.
 
-			var nodes = this.dropDown.createOptions(
+			this.dropDown.createOptions(
 				results,
 				options,
 				lang.hitch(this, "_getMenuLabelFromItem")
@@ -378,10 +268,10 @@ define([
 			// #4091:
 			//		tell the screen reader that the paging callback finished by
 			//		shouting the next choice
-			if(options.direction){
-				if(1 == options.direction){
+			if("direction" in options){
+				if(options.direction){
 					this.dropDown.highlightFirstOption();
-				}else if(-1 == options.direction){
+				}else if(!options.direction){
 					this.dropDown.highlightLastOption();
 				}
 				if(wasSelected){
@@ -393,7 +283,7 @@ define([
 				// it does not make sense to autocomplete
 				// if they are just previewing the options available.
 				&& !/^[*]+$/.test(query[this.searchAttr].toString())){
-					this._announceOption(nodes[1]); // 1st real item
+				this._announceOption(this.dropDown.containerNode.firstChild.nextSibling); // 1st real item
 			}
 		},
 
@@ -410,7 +300,6 @@ define([
 			// Overrides _HasDropDown.loadDropDown().
 			// This is called when user has pressed button icon or pressed the down arrow key
 			// to open the drop down.
-
 			this._startSearchAll();
 		},
 
@@ -428,7 +317,6 @@ define([
 			if(this._opened){
 				this.inherited(arguments);
 				this.domNode.setAttribute("aria-expanded", "false");
-				this.focusNode.removeAttribute("aria-activedescendant");
 			}
 		},
 
@@ -440,11 +328,7 @@ define([
 			//		the value
 			var newvalue = this.get('displayedValue');
 			var pw = this.dropDown;
-			if(pw && (
-				newvalue == pw._messages["previousMessage"] ||
-				newvalue == pw._messages["nextMessage"]
-				)
-			){
+			if(pw && (newvalue == pw._messages["previousMessage"] || newvalue == pw._messages["nextMessage"])){
 				this._setValueAttr(this._lastValueReported, true);
 			}else if(typeof this.item == "undefined"){
 				// Update 'value' (ex: KY) according to currently displayed text
@@ -456,6 +340,8 @@ define([
 				}
 				this._refreshState();
 			}
+			// Remove aria-activedescendant since it may not be removed if they select with arrows then blur with mouse
+			this.focusNode.removeAttribute("aria-activedescendant");
 		},
 
 		_setItemAttr: function(/*item*/ item, /*Boolean?*/ priorityChange, /*String?*/ displayedValue){
@@ -470,7 +356,7 @@ define([
 			var value = '';
 			if(item){
 				if(!displayedValue){
-					displayedValue = this.store._oldAPI ?	// remove getValue() for 2.0 (old dojo.data API)
+					displayedValue = this.store._oldAPI ? // remove getValue() for 2.0 (old dojo.data API)
 						this.store.getValue(item, this.searchAttr) : item[this.searchAttr];
 				}
 				value = this._getValueField() != this.searchAttr ? this.store.getIdentity(item) : displayedValue;
@@ -495,9 +381,10 @@ define([
 				this.item = undefined;
 				this.value = '';
 			}else{
-				newValue = (this.store._oldAPI ? 	// remove getValue() for 2.0 (old dojo.data API)
-					this.store.getValue(node.item, this.searchAttr) : node.item[this.searchAttr]).toString();
-				this.set('item', node.item, false, newValue);
+				var item = this.dropDown.items[node.getAttribute("item")];
+				newValue = (this.store._oldAPI ? // remove getValue() for 2.0 (old dojo.data API)
+					this.store.getValue(item, this.searchAttr) : item[this.searchAttr]).toString();
+				this.set('item', item, false, newValue);
 			}
 			// get the text that the user manually entered (cut off autocompleted text)
 			this.focusNode.value = this.focusNode.value.substring(0, this._lastInput.length);
@@ -516,6 +403,9 @@ define([
 			}
 			this._setCaretPos(this.focusNode, this.focusNode.value.length);
 			this._handleOnChange(this.value, true);
+			// Remove aria-activedescendant since the drop down is no loner visible
+			// after closeDropDown() but _announceOption() adds it back in
+			this.focusNode.removeAttribute("aria-activedescendant");
 		},
 
 		_startSearchAll: function(){
@@ -523,11 +413,8 @@ define([
 		},
 
 		_startSearchFromInput: function(){
-			this._startSearch(this.focusNode.value.replace(/([\\\*\?])/g, "\\$1"));
-		},
-
-		_getQueryString: function(/*String*/ text){
-			return string.substitute(this.queryExpr, [text]);
+			this.item = undefined; // undefined means item needs to be set
+			this.inherited(arguments);
 		},
 
 		_startSearch: function(/*String*/ key){
@@ -544,101 +431,26 @@ define([
 					dir: this.dir,
 					textDir: this.textDir
 				});
-				this.focusNode.removeAttribute("aria-activedescendant");
-				this.textbox.setAttribute("aria-owns",popupId); // associate popup with textbox
 			}
 			this._lastInput = key; // Store exactly what was entered by the user.
-
-			// Setup parameters to be passed to store.query().
-			// Create a new query to prevent accidentally querying for a hidden
-			// value from FilteringSelect's keyField
-			var query = lang.clone(this.query); // #5970
-			var options = {
-				start: 0,
-				count: this.pageSize,
-				queryOptions: {		// remove for 2.0
-					ignoreCase: this.ignoreCase,
-					deep: true
-				}
-			};
-			lang.mixin(options, this.fetchProperties);
-
-			// Generate query
-			var qs = this._getQueryString(key), q;
-			if(this.store._oldAPI){
-				// remove this branch for 2.0
-				q = qs;
-			}else{
-				// Query on searchAttr is a regex for benefit of dojo.store.Memory,
-				// but with a toString() method to help dojo.store.JsonRest.
-				// Search string like "Co*" converted to regex like /^Co.*$/i.
-				q = filter.patternToRegExp(qs, this.ignoreCase);
-				q.toString = function(){ return qs; };
-			}
-			this._lastQuery = query[this.searchAttr] = q;
-
-			// Function to run the query, wait for the results, and then call _openResultList()
-			var _this = this,
-				startQuery = function(){
-					var resPromise = _this._fetchHandle = _this.store.query(query, options);
-					Deferred.when(resPromise, function(res){
-						_this._fetchHandle = null;
-						res.total = resPromise.total;
-						_this._openResultList(res, query, options);
-					}, function(err){
-						_this._fetchHandle = null;
-						if(!_this._cancelingQuery){	// don't treat canceled query as an error
-							console.error(_this.declaredClass + ' ' + err.toString());
-							_this.closeDropDown();
-						}
-					});
-				};
-
-			// #5970: set _lastQuery, *then* start the timeout
-			// otherwise, if the user types and the last query returns before the timeout,
-			// _lastQuery won't be set and their input gets rewritten
-
-			this.searchTimer = setTimeout(lang.hitch(this, function(query, _this){
-				this.searchTimer = null;
-
-				startQuery();
-
-				// Setup method to handle clicking next/previous buttons to page through results
-				this._nextSearch = this.dropDown.onPage = function(direction){
-					options.start += options.count * direction;
-					//	tell callback the direction of the paging so the screen
-					//	reader knows which menu option to shout
-					options.direction = direction;
-					startQuery();
-					_this.focus();
-				};
-			}, query, this), this.searchDelay);
+			this.inherited(arguments);
 		},
 
 		_getValueField: function(){
 			// summary:
 			//		Helper for postMixInProperties() to set this.value based on data inlined into the markup.
-			//		Returns the attribute name in the item (in dijit.form._ComboBoxDataStore) to use as the value.
+			//		Returns the attribute name in the item (in dijit/form/_ComboBoxDataStore) to use as the value.
 			return this.searchAttr;
 		},
 
 		//////////// INITIALIZATION METHODS ///////////////////////////////////////
 
-		constructor: function(){
-			this.query={};
-			this.fetchProperties={};
-		},
-
 		postMixInProperties: function(){
+			this.inherited(arguments);
 			if(!this.store){
 				var srcNodeRef = this.srcNodeRef;
-				var list = this.list;
-				if(list){
-					this.store = registry.byId(list);
-				}else{
-					// if user didn't specify store, then assume there are option tags
-					this.store = new DataList({}, srcNodeRef);
-				}
+				// if user didn't specify store, then assume there are option tags
+				this.store = new DataList({}, srcNodeRef);
 
 				// if there is no value set and there is an option list, set
 				// the value to the first value to be consistent with native Select
@@ -655,8 +467,6 @@ define([
 					}
 				}
 			}
-
-			this.inherited(arguments);
 		},
 
 		postCreate: function(){
@@ -666,13 +476,16 @@ define([
 			//		protected
 
 			// find any associated label element and add to ComboBox node.
-			var label=query('label[for="'+this.id+'"]');
+			var label = query('label[for="' + this.id + '"]');
 			if(label.length){
-				label[0].id = (this.id+"_label");
+				if(!label[0].id){
+					label[0].id = this.id + "_label";
+				}
 				this.domNode.setAttribute("aria-labelledby", label[0].id);
 
 			}
 			this.inherited(arguments);
+			aspect.after(this, "onSearch", lang.hitch(this, "_openResultList"), true);
 		},
 
 		_getMenuLabelFromItem: function(/*Item*/ item){
@@ -680,7 +493,7 @@ define([
 				labelType = this.labelType;
 			// If labelType is not "text" we don't want to screw any markup ot whatever.
 			if(this.highlightMatch != "none" && this.labelType == "text" && this._lastInput){
-				label = this.doHighlight(label, this._escapeHtml(this._lastInput));
+				label = this.doHighlight(label, this._lastInput);
 				labelType = "html";
 			}
 			return {html: labelType == "html", label: label};
@@ -695,21 +508,25 @@ define([
 			//		protected
 
 			var
-				// Add (g)lobal modifier when this.highlightMatch == "all" and (i)gnorecase when this.ignoreCase == true
+			// Add (g)lobal modifier when this.highlightMatch == "all" and (i)gnorecase when this.ignoreCase == true
 				modifiers = (this.ignoreCase ? "i" : "") + (this.highlightMatch == "all" ? "g" : ""),
 				i = this.queryExpr.indexOf("${0}");
 			find = regexp.escapeString(find); // escape regexp special chars
-			return this._escapeHtml(label).replace(
-				// prepend ^ when this.queryExpr == "${0}*" and append $ when this.queryExpr == "*${0}"
-				new RegExp((i == 0 ? "^" : "") + "("+ find +")" + (i == (this.queryExpr.length - 4) ? "$" : ""), modifiers),
-				'<span class="dijitComboBoxHighlightMatch">$1</span>'
+			//If < appears in label, and user presses t, we don't want to highlight the t in the escaped "<"
+			//first find out every occurences of "find", wrap each occurence in a pair of "\uFFFF" characters (which
+			//should not appear in any string). then html escape the whole string, and replace '\uFFFF" with the
+			//HTML highlight markup. 
+			return this._escapeHtml(label.replace(
+				new RegExp((i == 0 ? "^" : "") + "(" + find + ")" + (i == (this.queryExpr.length - 4) ? "$" : ""), modifiers),
+				'\uFFFF$1\uFFFF')).replace(
+				/\uFFFF([^\uFFFF]+)\uFFFF/g, '<span class="dijitComboBoxHighlightMatch">$1</span>'
 			); // returns String, (almost) valid HTML (entities encoded)
 		},
 
 		_escapeHtml: function(/*String*/ str){
 			// TODO Should become dojo.html.entities(), when exists use instead
 			// summary:
-			//		Adds escape sequences for special characters in XML: &<>"'
+			//		Adds escape sequences for special characters in XML: `&<>"'`
 			str = String(str).replace(/&/gm, "&").replace(/</gm, "<")
 				.replace(/>/gm, ">").replace(/"/gm, """); //balance"
 			return str; // string
@@ -722,9 +539,13 @@ define([
 			this.inherited(arguments);
 		},
 
-		labelFunc: function(/*item*/ item, /*dojo.store.api.Store*/ store){
+		labelFunc: function(item, store){
 			// summary:
 			//		Computes the label to display based on the dojo.data store item.
+			// item: Object
+			//		The item from the store
+			// store: dojo/store/api/Store
+			//		The store.
 			// returns:
 			//		The label that the ComboBox should display
 			// tags:
@@ -742,23 +563,32 @@ define([
 			//		Hook so set('value', value) works.
 			// description:
 			//		Sets the value of the select.
-			this._set("item", item||null); // value not looked up in store
-			if(!value){ value = ''; } // null translates to blank
+			this._set("item", item || null); // value not looked up in store
+			if(value == null /* or undefined */){
+				value = '';
+			} // null translates to blank
 			this.inherited(arguments);
-		},
-		_setTextDirAttr: function(/*String*/ textDir){
-			// summary:
-			//		Setter for textDir, needed for the dropDown's textDir update.
-			// description:
-			//		Users shouldn't call this function; they should be calling
-			//		set('textDir', value)
-			// tags:
-			//		private
-			this.inherited(arguments);
-			// update the drop down also (_ComboBoxMenuMixin)
-			if(this.dropDown){
-				this.dropDown._set("textDir", textDir);
-			}
 		}
 	});
+
+	if(has("dojo-bidi")){
+		AutoCompleterMixin.extend({
+			_setTextDirAttr: function(/*String*/ textDir){
+				// summary:
+				//		Setter for textDir, needed for the dropDown's textDir update.
+				// description:
+				//		Users shouldn't call this function; they should be calling
+				//		set('textDir', value)
+				// tags:
+				//		private
+				this.inherited(arguments);
+				// update the drop down also (_ComboBoxMenuMixin)
+				if(this.dropDown){
+					this.dropDown._set("textDir", textDir);
+				}
+			}
+		});
+	}
+
+	return AutoCompleterMixin;
 });
diff --git a/dijit/form/_ButtonMixin.js b/dijit/form/_ButtonMixin.js
index f345d88..eadefbf 100644
--- a/dijit/form/_ButtonMixin.js
+++ b/dijit/form/_ButtonMixin.js
@@ -1,85 +1,116 @@
 define([
 	"dojo/_base/declare", // declare
 	"dojo/dom", // dom.setSelectable
-	"dojo/_base/event", // event.stop
-	"../registry"		// registry.byNode
-], function(declare, dom, event, registry){
+	"dojo/has",
+	"../registry"        // registry.byNode
+], function(declare, dom, has, registry){
 
-// module:
-//		dijit/form/_ButtonMixin
-// summary:
-//		A mixin to add a thin standard API wrapper to a normal HTML button
+	// module:
+	//		dijit/form/_ButtonMixin
 
-return declare("dijit.form._ButtonMixin", null, {
-	// summary:
-	//		A mixin to add a thin standard API wrapper to a normal HTML button
-	// description:
-	//		A label should always be specified (through innerHTML) or the label attribute.
-	//		Attach points:
-	//			focusNode (required): this node receives focus
-	//			valueNode (optional): this node's value gets submitted with FORM elements
-	//			containerNode (optional): this node gets the innerHTML assignment for label
-	// example:
-	// |	<button data-dojo-type="dijit.form.Button" onClick="...">Hello world</button>
-	//
-	// example:
-	// |	var button1 = new dijit.form.Button({label: "hello world", onClick: foo});
-	// |	dojo.body().appendChild(button1.domNode);
+	var ButtonMixin = declare("dijit.form._ButtonMixin" + (has("dojo-bidi") ? "_NoBidi" : ""), null, {
+		// summary:
+		//		A mixin to add a thin standard API wrapper to a normal HTML button
+		// description:
+		//		A label should always be specified (through innerHTML) or the label attribute.
+		//
+		//		Attach points:
+		//
+		//		- focusNode (required): this node receives focus
+		//		- valueNode (optional): this node's value gets submitted with FORM elements
+		//		- containerNode (optional): this node gets the innerHTML assignment for label
+		// example:
+		// |	<button data-dojo-type="dijit/form/Button" onClick="...">Hello world</button>
+		// example:
+		// |	var button1 = new Button({label: "hello world", onClick: foo});
+		// |	dojo.body().appendChild(button1.domNode);
 
-	// label: HTML String
-	//		Content to display in button.
-	label: "",
+		// label: HTML String
+		//		Content to display in button.
+		label: "",
 
-	// type: [const] String
-	//		Type of button (submit, reset, button, checkbox, radio)
-	type: "button",
+		// type: [const] String
+		//		Type of button (submit, reset, button, checkbox, radio)
+		type: "button",
 
-	_onClick: function(/*Event*/ e){
-		// summary:
-		//		Internal function to handle click actions
-		if(this.disabled){
-			event.stop(e);
+		__onClick: function(/*Event*/ e){
+			// summary:
+			//		Internal function to divert the real click onto the hidden INPUT that has a native default action associated with it
+			// type:
+			//		private
+			e.stopPropagation();
+			e.preventDefault();
+			if(!this.disabled){
+				// cannot use on.emit since button default actions won't occur
+				this.valueNode.click(e);
+			}
 			return false;
-		}
-		var preventDefault = this.onClick(e) === false; // user click actions
-		if(!preventDefault && this.type == "submit" && !(this.valueNode||this.focusNode).form){ // see if a non-form widget needs to be signalled
-			for(var node=this.domNode; node.parentNode; node=node.parentNode){
-				var widget=registry.byNode(node);
-				if(widget && typeof widget._onSubmit == "function"){
-					widget._onSubmit(e);
-					preventDefault = true;
-					break;
+		},
+
+		_onClick: function(/*Event*/ e){
+			// summary:
+			//		Internal function to handle click actions
+			if(this.disabled){
+				e.stopPropagation();
+				e.preventDefault();
+				return false;
+			}
+			if(this.onClick(e) === false){
+				e.preventDefault();
+			}
+			cancelled = e.defaultPrevented;
+
+			// Signal Form/Dialog to submit/close.  For 2.0, consider removing this code and instead making the Form/Dialog
+			// listen for bubbled click events where evt.target.type == "submit" && !evt.defaultPrevented.
+			if(!cancelled && this.type == "submit" && !(this.valueNode || this.focusNode).form){
+				for(var node = this.domNode; node.parentNode; node = node.parentNode){
+					var widget = registry.byNode(node);
+					if(widget && typeof widget._onSubmit == "function"){
+						widget._onSubmit(e);
+						e.preventDefault(); // action has already occurred
+						cancelled = true;
+						break;
+					}
 				}
 			}
-		}
-		if(preventDefault){
-			e.preventDefault();
-		}
-		return !preventDefault;
-	},
 
-	postCreate: function(){
-		this.inherited(arguments);
-		dom.setSelectable(this.focusNode, false);
-	},
+			return !cancelled;
+		},
 
-	onClick: function(/*Event*/ /*===== e =====*/){
-		// summary:
-		//		Callback for when button is clicked.
-		//		If type="submit", return true to perform submit, or false to cancel it.
-		// type:
-		//		callback
-		return true;		// Boolean
-	},
+		postCreate: function(){
+			this.inherited(arguments);
+			dom.setSelectable(this.focusNode, false);
+		},
 
-	_setLabelAttr: function(/*String*/ content){
-		// summary:
-		//		Hook for set('label', ...) to work.
-		// description:
-		//		Set the label (text) of the button; takes an HTML string.
-		this._set("label", content);
-		(this.containerNode||this.focusNode).innerHTML = content;
+		onClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		Callback for when button is clicked.
+			//		If type="submit", return true to perform submit, or false to cancel it.
+			// type:
+			//		callback
+			return true;		// Boolean
+		},
+
+		_setLabelAttr: function(/*String*/ content){
+			// summary:
+			//		Hook for set('label', ...) to work.
+			// description:
+			//		Set the label (text) of the button; takes an HTML string.
+			this._set("label", content);
+			var labelNode = this.containerNode || this.focusNode;
+			labelNode.innerHTML = content;
+		}
+	});
+
+	if(has("dojo-bidi")){
+		ButtonMixin = declare("dijit.form._ButtonMixin", ButtonMixin, {
+			_setLabelAttr: function(){
+				this.inherited(arguments);
+				var labelNode = this.containerNode || this.focusNode;
+				this.applyTextDir(labelNode);
+			}
+		});
 	}
-});
 
+	return ButtonMixin;
 });
diff --git a/dijit/form/_CheckBoxMixin.js b/dijit/form/_CheckBoxMixin.js
index 76b0147..a9e8563 100644
--- a/dijit/form/_CheckBoxMixin.js
+++ b/dijit/form/_CheckBoxMixin.js
@@ -1,17 +1,14 @@
 define([
 	"dojo/_base/declare", // declare
-	"dojo/dom-attr", // domAttr.set
-	"dojo/_base/event" // event.stop
-], function(declare, domAttr, event){
+	"dojo/dom-attr" // domAttr.set
+], function(declare, domAttr){
 
 	// module:
 	//		dijit/form/_CheckBoxMixin
-	// summary:
-	// 		Mixin to provide widget functionality corresponding to an HTML checkbox
 
 	return declare("dijit.form._CheckBoxMixin", null, {
 		// summary:
-		// 		Mixin to provide widget functionality corresponding to an HTML checkbox
+		//		Mixin to provide widget functionality corresponding to an HTML checkbox
 		//
 		// description:
 		//		User interacts with real html inputs.
@@ -21,8 +18,8 @@ define([
 		//
 
 		// type: [private] String
-		//		type attribute on <input> node.
-		//		Overrides `dijit.form.Button.type`.  Users should not change this value.
+		//		type attribute on `<input>` node.
+		//		Overrides `dijit/form/Button.type`.  Users should not change this value.
 		type: "checkbox",
 
 		// value: String
@@ -35,31 +32,33 @@ define([
 		//		In markup, this is specified as "readOnly".
 		//		Similar to disabled except readOnly form values are submitted.
 		readOnly: false,
-		
+
 		// aria-pressed for toggle buttons, and aria-checked for checkboxes
 		_aria_attr: "aria-checked",
 
 		_setReadOnlyAttr: function(/*Boolean*/ value){
 			this._set("readOnly", value);
 			domAttr.set(this.focusNode, 'readOnly', value);
-			this.focusNode.setAttribute("aria-readonly", value);
 		},
 
-		// Override dijit.form.Button._setLabelAttr() since we don't even have a containerNode.
-		// Normally users won't try to set label, except when CheckBox or RadioButton is the child of a dojox.layout.TabContainer
+		// Override dijit/form/Button._setLabelAttr() since we don't even have a containerNode.
+		// Normally users won't try to set label, except when CheckBox or RadioButton is the child of a dojox/layout/TabContainer
 		_setLabelAttr: undefined,
 
-		postMixInProperties: function(){
-			if(this.value == ""){
-				this.value = "on";
-			}
-			this.inherited(arguments);
+		_getSubmitValue: function(/*String*/ value){
+			return (value == null || value === "") ? "on" : value;
+		},
+
+		_setValueAttr: function(newValue){
+			newValue = this._getSubmitValue(newValue);	// "on" to match browser native behavior when value unspecified
+			this._set("value", newValue);
+			domAttr.set(this.focusNode, "value", newValue);
 		},
 
 		reset: function(){
 			this.inherited(arguments);
 			// Handle unlikely event that the <input type=checkbox> value attribute has changed
-			this._set("value", this.params.value || "on");
+			this._set("value", this._getSubmitValue(this.params.value));
 			domAttr.set(this.focusNode, 'value', this.value);
 		},
 
@@ -68,7 +67,8 @@ define([
 			//		Internal function to handle click actions - need to check
 			//		readOnly, since button no longer does that check.
 			if(this.readOnly){
-				event.stop(e);
+				e.stopPropagation();
+				e.preventDefault();
 				return false;
 			}
 			return this.inherited(arguments);
diff --git a/dijit/form/_ComboBoxMenu.js b/dijit/form/_ComboBoxMenu.js
index 8704385..2da48b2 100644
--- a/dijit/form/_ComboBoxMenu.js
+++ b/dijit/form/_ComboBoxMenu.js
@@ -1,38 +1,32 @@
 define([
 	"dojo/_base/declare", // declare
 	"dojo/dom-class", // domClass.add domClass.remove
-	"dojo/dom-construct", // domConstruct.create
 	"dojo/dom-style", // domStyle.get
 	"dojo/keys", // keys.DOWN_ARROW keys.PAGE_DOWN keys.PAGE_UP keys.UP_ARROW
 	"../_WidgetBase",
 	"../_TemplatedMixin",
 	"./_ComboBoxMenuMixin",
 	"./_ListMouseMixin"
-], function(declare, domClass, domConstruct, domStyle, keys,
+], function(declare, domClass, domStyle, keys,
 			_WidgetBase, _TemplatedMixin, _ComboBoxMenuMixin, _ListMouseMixin){
 
-/*=====
-	var _WidgetBase = dijit._WidgetBase;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _ComboBoxMenuMixin = dijit.form._ComboBoxMenuMixin;
-	var _ListMouseMixin = dijit.form._ListMouseMixin;
-=====*/
 
 	// module:
 	//		dijit/form/_ComboBoxMenu
-	// summary:
-	//		Focus-less menu for internal use in `dijit.form.ComboBox`
 
 	return declare("dijit.form._ComboBoxMenu",[_WidgetBase, _TemplatedMixin, _ListMouseMixin, _ComboBoxMenuMixin], {
 		// summary:
-		//		Focus-less menu for internal use in `dijit.form.ComboBox`
-		//              Abstract methods that must be defined externally:
-		//                      onChange: item was explicitly chosen (mousedown somewhere on the menu and mouseup somewhere on the menu)
-		//                      onPage: next(1) or previous(-1) button pressed
+		//		Focus-less menu for internal use in `dijit/form/ComboBox`
+		//		Abstract methods that must be defined externally:
+		//
+		//		- onChange: item was explicitly chosen (mousedown somewhere on the menu and mouseup somewhere on the menu)
+		//		- onPage: next(1) or previous(-1) button pressed
 		// tags:
 		//		private
 
-		templateString: "<div class='dijitReset dijitMenu' data-dojo-attach-point='containerNode' style='overflow: auto; overflow-x: hidden;'>"
+		// TODO for 2.0 or earlier: stop putting stuff inside this.containerNode.   Switch to using this.domNode
+		// or a different attach point.    See _TemplatedMixin::searchContainerNode.
+		templateString: "<div class='dijitReset dijitMenu' data-dojo-attach-point='containerNode' style='overflow: auto; overflow-x: hidden;' role='listbox'>"
 				+"<div class='dijitMenuItem dijitMenuPreviousButton' data-dojo-attach-point='previousButton' role='option'></div>"
 				+"<div class='dijitMenuItem dijitMenuNextButton' data-dojo-attach-point='nextButton' role='option'></div>"
 				+"</div>",
@@ -45,13 +39,15 @@ define([
 				domClass.add(this.previousButton, "dijitMenuItemRtl");
 				domClass.add(this.nextButton, "dijitMenuItemRtl");
 			}
+			this.containerNode.setAttribute("role","listbox");
 		},
 
 		_createMenuItem: function(){
-			return domConstruct.create("div", {
-				"class": "dijitReset dijitMenuItem" +(this.isLeftToRight() ? "" : " dijitMenuItemRtl"),
-				role: "option"
-			});
+			// note: not using domConstruct.create() because need to specify document
+			var item = this.ownerDocument.createElement("div");
+			item.className = "dijitReset dijitMenuItem" +(this.isLeftToRight() ? "" : " dijitMenuItemRtl");
+			item.setAttribute("role", "option");
+			return item;
 		},
 
 		onHover: function(/*DomNode*/ node){
@@ -117,7 +113,7 @@ define([
 			// summary:
 			//		Handle keystroke event forwarded from ComboBox, returning false if it's
 			//		a keystroke I recognize and process, true otherwise.
-			switch(evt.charOrCode){
+			switch(evt.keyCode){
 				case keys.DOWN_ARROW:
 					this.selectNextNode();
 					return false;
diff --git a/dijit/form/_ComboBoxMenuMixin.js b/dijit/form/_ComboBoxMenuMixin.js
index 90ccd7d..4fd8367 100644
--- a/dijit/form/_ComboBoxMenuMixin.js
+++ b/dijit/form/_ComboBoxMenuMixin.js
@@ -2,190 +2,200 @@ define([
 	"dojo/_base/array", // array.forEach
 	"dojo/_base/declare", // declare
 	"dojo/dom-attr", // domAttr.set
+	"dojo/has",
 	"dojo/i18n", // i18n.getLocalization
-	"dojo/_base/window", // win.doc.createTextNode
 	"dojo/i18n!./nls/ComboBox"
-], function(array, declare, domAttr, i18n, win){
-
-// module:
-//		dijit/form/_ComboBoxMenuMixin
-// summary:
-//		Focus-less menu for internal use in `dijit.form.ComboBox`
-
-return declare( "dijit.form._ComboBoxMenuMixin", null, {
-	// summary:
-	//		Focus-less menu for internal use in `dijit.form.ComboBox`
-	// tags:
-	//		private
-
-	// _messages: Object
-	//		Holds "next" and "previous" text for paging buttons on drop down
-	_messages: null,
-
-	postMixInProperties: function(){
-		this.inherited(arguments);
-		this._messages = i18n.getLocalization("dijit.form", "ComboBox", this.lang);
-	},
-
-	buildRendering: function(){
-		this.inherited(arguments);
-
-		// fill in template with i18n messages
-		this.previousButton.innerHTML = this._messages["previousMessage"];
-		this.nextButton.innerHTML = this._messages["nextMessage"];
-	},
-
-	_setValueAttr: function(/*Object*/ value){
-		this.value = value;
-		this.onChange(value);
-	},
-
-	onClick: function(/*DomNode*/ node){
-		if(node == this.previousButton){
-			this._setSelectedAttr(null);
-			this.onPage(-1);
-		}else if(node == this.nextButton){
-			this._setSelectedAttr(null);
-			this.onPage(1);
-		}else{
-			this.onChange(node);
-		}
-	},
-
-	// stubs
-	onChange: function(/*Number*/ /*===== direction =====*/){
-		// summary:
-		//		Notifies ComboBox/FilteringSelect that user selected an option.
-		// tags:
-		//		callback
-	},
+], function(array, declare, domAttr, has, i18n){
 
-	onPage: function(/*Number*/ /*===== direction =====*/){
-		// summary:
-		//		Notifies ComboBox/FilteringSelect that user clicked to advance to next/previous page.
-		// tags:
-		//		callback
-	},
+	// module:
+	//		dijit/form/_ComboBoxMenuMixin
 
-	onClose: function(){
+	var ComboBoxMenuMixin = declare("dijit.form._ComboBoxMenuMixin" + (has("dojo-bidi") ? "_NoBidi" : ""), null, {
 		// summary:
-		//		Callback from dijit.popup code to this widget, notifying it that it closed
+		//		Focus-less menu for internal use in `dijit/form/ComboBox`
 		// tags:
 		//		private
-		this._setSelectedAttr(null);
-	},
 
-	_createOption: function(/*Object*/ item, labelFunc){
-		// summary:
-		//		Creates an option to appear on the popup menu subclassed by
-		//		`dijit.form.FilteringSelect`.
-
-		var menuitem = this._createMenuItem();
-		var labelObject = labelFunc(item);
-		if(labelObject.html){
-			menuitem.innerHTML = labelObject.label;
-		}else{
-			menuitem.appendChild(
-				win.doc.createTextNode(labelObject.label)
-			);
-		}
-		// #3250: in blank options, assign a normal height
-		if(menuitem.innerHTML == ""){
-			menuitem.innerHTML = " ";	//  
-		}
-
-		// update menuitem.dir if BidiSupport was required
-		this.applyTextDir(menuitem, (menuitem.innerText || menuitem.textContent || ""));
-
-		menuitem.item=item;
-		return menuitem;
-	},
+		// _messages: Object
+		//		Holds "next" and "previous" text for paging buttons on drop down
+		_messages: null,
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			this._messages = i18n.getLocalization("dijit.form", "ComboBox", this.lang);
+		},
+
+		buildRendering: function(){
+			this.inherited(arguments);
+
+			// fill in template with i18n messages
+			this.previousButton.innerHTML = this._messages["previousMessage"];
+			this.nextButton.innerHTML = this._messages["nextMessage"];
+		},
+
+		_setValueAttr: function(/*Object*/ value){
+			this._set("value", value);
+			this.onChange(value);
+		},
+
+		onClick: function(/*DomNode*/ node){
+			if(node == this.previousButton){
+				this._setSelectedAttr(null);
+				this.onPage(-1);
+			}else if(node == this.nextButton){
+				this._setSelectedAttr(null);
+				this.onPage(1);
+			}else{
+				this.onChange(node);
+			}
+		},
+
+		// stubs
+		onChange: function(/*Number*/ /*===== direction =====*/){
+			// summary:
+			//		Notifies ComboBox/FilteringSelect that user selected an option.
+			// tags:
+			//		callback
+		},
+
+		onPage: function(/*Number*/ /*===== direction =====*/){
+			// summary:
+			//		Notifies ComboBox/FilteringSelect that user clicked to advance to next/previous page.
+			// tags:
+			//		callback
+		},
+
+		onClose: function(){
+			// summary:
+			//		Callback from dijit.popup code to this widget, notifying it that it closed
+			// tags:
+			//		private
+			this._setSelectedAttr(null);
+		},
+
+		_createOption: function(/*Object*/ item, labelFunc){
+			// summary:
+			//		Creates an option to appear on the popup menu subclassed by
+			//		`dijit/form/FilteringSelect`.
+
+			var menuitem = this._createMenuItem();
+			var labelObject = labelFunc(item);
+			if(labelObject.html){
+				menuitem.innerHTML = labelObject.label;
+			}else{
+				menuitem.appendChild(
+					menuitem.ownerDocument.createTextNode(labelObject.label)
+				);
+			}
+			// #3250: in blank options, assign a normal height
+			if(menuitem.innerHTML == ""){
+				menuitem.innerHTML = " ";	//  
+			}
 
-	createOptions: function(results, options, labelFunc){
-		// summary:
-		//		Fills in the items in the drop down list
-		// results:
-		//		Array of items
-		// options:
-		//		The options to the query function of the store
-		//
-		// labelFunc:
-		//		Function to produce a label in the drop down list from a dojo.data item
-
-		// display "Previous . . ." button
-		this.previousButton.style.display = (options.start == 0) ? "none" : "";
-		domAttr.set(this.previousButton, "id", this.id + "_prev");
-		// create options using _createOption function defined by parent
-		// ComboBox (or FilteringSelect) class
-		// #2309:
-		//		iterate over cache nondestructively
-		array.forEach(results, function(item, i){
-			var menuitem = this._createOption(item, labelFunc);
-			domAttr.set(menuitem, "id", this.id + i);
-			this.nextButton.parentNode.insertBefore(menuitem, this.nextButton);
-		}, this);
-		// display "Next . . ." button
-		var displayMore = false;
-		// Try to determine if we should show 'more'...
-		if(results.total && !results.total.then && results.total != -1){
-			if((options.start + options.count) < results.total){
-				displayMore = true;
-			}else if((options.start + options.count) > results.total && options.count == results.length){
-				// Weird return from a data store, where a start + count > maxOptions
-				// implies maxOptions isn't really valid and we have to go into faking it.
-				// And more or less assume more if count == results.length
+			return menuitem;
+		},
+
+		createOptions: function(results, options, labelFunc){
+			// summary:
+			//		Fills in the items in the drop down list
+			// results:
+			//		Array of items
+			// options:
+			//		The options to the query function of the store
+			//
+			// labelFunc:
+			//		Function to produce a label in the drop down list from a dojo.data item
+
+			this.items = results;
+
+			// display "Previous . . ." button
+			this.previousButton.style.display = (options.start == 0) ? "none" : "";
+			domAttr.set(this.previousButton, "id", this.id + "_prev");
+			// create options using _createOption function defined by parent
+			// ComboBox (or FilteringSelect) class
+			// #2309:
+			//		iterate over cache nondestructively
+			array.forEach(results, function(item, i){
+				var menuitem = this._createOption(item, labelFunc);
+				menuitem.setAttribute("item", i);	// index to this.items; use indirection to avoid mem leak
+				domAttr.set(menuitem, "id", this.id + i);
+				this.nextButton.parentNode.insertBefore(menuitem, this.nextButton);
+			}, this);
+			// display "Next . . ." button
+			var displayMore = false;
+			// Try to determine if we should show 'more'...
+			if(results.total && !results.total.then && results.total != -1){
+				if((options.start + options.count) < results.total){
+					displayMore = true;
+				}else if((options.start + options.count) > results.total && options.count == results.length){
+					// Weird return from a data store, where a start + count > maxOptions
+					// implies maxOptions isn't really valid and we have to go into faking it.
+					// And more or less assume more if count == results.length
+					displayMore = true;
+				}
+			}else if(options.count == results.length){
+				//Don't know the size, so we do the best we can based off count alone.
+				//So, if we have an exact match to count, assume more.
 				displayMore = true;
 			}
-		}else if(options.count == results.length){
-			//Don't know the size, so we do the best we can based off count alone.
-			//So, if we have an exact match to count, assume more.
-			displayMore = true;
-		}
 
-		this.nextButton.style.display = displayMore ? "" : "none";
-		domAttr.set(this.nextButton,"id", this.id + "_next");
-		return this.containerNode.childNodes;
-	},
+			this.nextButton.style.display = displayMore ? "" : "none";
+			domAttr.set(this.nextButton, "id", this.id + "_next");
+		},
 
-	clearResultList: function(){
-		// summary:
-		//		Clears the entries in the drop down list, but of course keeps the previous and next buttons.
-		var container = this.containerNode;
-		while(container.childNodes.length > 2){
-			container.removeChild(container.childNodes[container.childNodes.length-2]);
-		}
-		this._setSelectedAttr(null);
-	},
+		clearResultList: function(){
+			// summary:
+			//		Clears the entries in the drop down list, but of course keeps the previous and next buttons.
+			var container = this.containerNode;
+			while(container.childNodes.length > 2){
+				container.removeChild(container.childNodes[container.childNodes.length - 2]);
+			}
+			this._setSelectedAttr(null);
+		},
+
+		highlightFirstOption: function(){
+			// summary:
+			//		Highlight the first real item in the list (not Previous Choices).
+			this.selectFirstNode();
+		},
+
+		highlightLastOption: function(){
+			// summary:
+			//		Highlight the last real item in the list (not More Choices).
+			this.selectLastNode();
+		},
+
+		selectFirstNode: function(){
+			this.inherited(arguments);
+			if(this.getHighlightedOption() == this.previousButton){
+				this.selectNextNode();
+			}
+		},
 
-	highlightFirstOption: function(){
-		// summary:
-		//		Highlight the first real item in the list (not Previous Choices).
-		this.selectFirstNode();
-	},
+		selectLastNode: function(){
+			this.inherited(arguments);
+			if(this.getHighlightedOption() == this.nextButton){
+				this.selectPreviousNode();
+			}
+		},
 
-	highlightLastOption: function(){
-		// summary:
-		//		Highlight the last real item in the list (not More Choices).
-		this.selectLastNode();
-	},
-
-	selectFirstNode: function(){
-		this.inherited(arguments);
-		if(this.getHighlightedOption() == this.previousButton){
-			this.selectNextNode();
+		getHighlightedOption: function(){
+			return this.selected;
 		}
-	},
+	});
 
-	selectLastNode: function(){
-		this.inherited(arguments);
-		if(this.getHighlightedOption() == this.nextButton){
-			this.selectPreviousNode();
-		}
-	},
+	if(has("dojo-bidi")){
+		ComboBoxMenuMixin = declare("dijit.form._ComboBoxMenuMixin", ComboBoxMenuMixin, {
+			_createOption: function(){
+				var menuitem = this.inherited(arguments);
+
+				// update menuitem.dir if BidiSupport was required
+				this.applyTextDir(menuitem);
 
-	getHighlightedOption: function(){
-		return this._getSelectedAttr();
+				return menuitem;
+			}
+		});
 	}
-});
 
+	return ComboBoxMenuMixin;
 });
diff --git a/dijit/form/_DateTimeTextBox.js b/dijit/form/_DateTimeTextBox.js
index 29ecf18..6d482f5 100644
--- a/dijit/form/_DateTimeTextBox.js
+++ b/dijit/form/_DateTimeTextBox.js
@@ -9,32 +9,11 @@ define([
 	"dojo/text!./templates/DropDownBox.html"
 ], function(date, locale, stamp, declare, lang, RangeBoundTextBox, _HasDropDown, template){
 
-/*=====
-	var _HasDropDown = dijit._HasDropDown;
-	var RangeBoundTextBox = dijit.form.RangeBoundTextBox;
-=====*/
-
 	// module:
 	//		dijit/form/_DateTimeTextBox
-	// summary:
-	//		Base class for validating, serializable, range-bound date or time text box.
-
 
 	new Date("X"); // workaround for #11279, new Date("") == NaN
 
-	/*=====
-	declare(
-		"dijit.form._DateTimeTextBox.__Constraints",
-		[RangeBoundTextBox.__Constraints, locale.__FormatOptions], {
-		// summary:
-		//		Specifies both the rules on valid/invalid values (first/last date/time allowed),
-		//		and also formatting options for how the date/time is displayed.
-		// example:
-		//		To restrict to dates within 2004, displayed in a long format like "December 25, 2005":
-		//	|		{min:'2004-01-01',max:'2004-12-31', formatLength:'long'}
-	});
-	=====*/
-
 	var _DateTimeTextBox = declare("dijit.form._DateTimeTextBox", [RangeBoundTextBox, _HasDropDown], {
 		// summary:
 		//		Base class for validating, serializable, range-bound date or time text box.
@@ -45,27 +24,31 @@ define([
 		//		Set this textbox to display a down arrow button, to open the drop down list.
 		hasDownArrow: true,
 
-		// openOnClick: [const] Boolean
-		//		Set to true to open drop down upon clicking anywhere on the textbox.
-		openOnClick: true,
+		// Set classes like dijitDownArrowButtonHover depending on mouse action over button node
+		cssStateNodes: {
+			"_buttonNode": "dijitDownArrowButton"
+		},
 
 		/*=====
-		// constraints: dijit.form._DateTimeTextBox.__Constraints
+		// constraints: _DateTimeTextBox.__Constraints
 		//		Despite the name, this parameter specifies both constraints on the input
 		//		(including starting/ending dates/times allowed) as well as
 		//		formatting options like whether the date is displayed in long (ex: December 25, 2005)
-		//		or short (ex: 12/25/2005) format.  See `dijit.form._DateTimeTextBox.__Constraints` for details.
+		//		or short (ex: 12/25/2005) format.  See `dijit/form/_DateTimeTextBox.__Constraints` for details.
 		constraints: {},
 		======*/
 
-		// Override ValidationTextBox.regExpGen().... we use a reg-ex generating function rather
+		// Override ValidationTextBox.pattern.... we use a reg-ex generating function rather
 		// than a straight regexp to deal with locale  (plus formatting options too?)
-		regExpGen: locale.regexp,
+		pattern: locale.regexp,
 
 		// datePackage: String
-		//		JavaScript namespace to find calendar routines.	 Uses Gregorian calendar routines
-		//		at dojo.date, by default.
-		datePackage: date,
+		//		JavaScript namespace to find calendar routines.	 If unspecified, uses Gregorian calendar routines
+		//		at dojo/date and dojo/date/locale.
+		datePackage: "",
+		//		TODO: for 2.0, replace datePackage with dateModule and dateLocalModule attributes specifying MIDs,
+		//		or alternately just get rid of this completely and tell user to use module ID remapping
+		//		via require
 
 		postMixInProperties: function(){
 			this.inherited(arguments);
@@ -80,9 +63,9 @@ define([
 		},
 
 		// flag to _HasDropDown to make drop down Calendar width == <input> width
-		forceWidth: true,
+		autoWidth: true,
 
-		format: function(/*Date*/ value, /*dojo.date.locale.__FormatOptions*/ constraints){
+		format: function(/*Date*/ value, /*locale.__FormatOptions*/ constraints){
 			// summary:
 			//		Formats the value as a Date, according to specified locale (second argument)
 			// tags:
@@ -91,7 +74,7 @@ define([
 			return this.dateLocaleModule.format(value, constraints);
 		},
 
-		"parse": function(/*String*/ value, /*dojo.date.locale.__FormatOptions*/ constraints){
+		"parse": function(/*String*/ value, /*locale.__FormatOptions*/ constraints){
 			// summary:
 			//		Parses as string as a Date, according to constraints
 			// tags:
@@ -114,7 +97,7 @@ define([
 
 		// value: Date
 		//		The value of this widget as a JavaScript Date object.  Use get("value") / set("value", val) to manipulate.
-		//		When passed to the parser in markup, must be specified according to `dojo.date.stamp.fromISOString`
+		//		When passed to the parser in markup, must be specified according to `dojo/date/stamp.fromISOString()`
 		value: new Date(""),	// value.toString()="NaN"
 
 		_blankValue: null,	// used by filter() when the textbox is blank
@@ -131,14 +114,20 @@ define([
 		//		Subclass must specify this.
 		_selector: "",
 
-		constructor: function(/*Object*/ args){
-			this.datePackage = args.datePackage || this.datePackage;
-			this.dateFuncObj = typeof this.datePackage == "string" ?
-				lang.getObject(this.datePackage, false) :// "string" part for back-compat, remove for 2.0
-				this.datePackage;
-			this.dateClassObj = this.dateFuncObj.Date || Date;
-			this.dateLocaleModule = lang.getObject("locale", false, this.dateFuncObj);
-			this.regExpGen = this.dateLocaleModule.regexp;
+		constructor: function(params /*===== , srcNodeRef =====*/){
+			// summary:
+			//		Create the widget.
+			// params: Object|null
+			//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+			//		and functions, typically callbacks like onClick.
+			//		The hash can contain any of the widget's properties, excluding read-only properties.
+			// srcNodeRef: DOMNode|String?
+			//		If a srcNodeRef (DOM node) is specified, replace srcNodeRef with my generated DOM tree
+
+			this.dateModule = params.datePackage ? lang.getObject(params.datePackage, false) : date;
+			this.dateClassObj = this.dateModule.Date || Date;
+			this.dateLocaleModule = params.datePackage ? lang.getObject(params.datePackage+".locale", false) : locale;
+			this._set('pattern', this.dateLocaleModule.regexp);
 			this._invalidDate = this.constructor.prototype.value.toString();
 		},
 
@@ -149,10 +138,9 @@ define([
 				this._buttonNode.style.display = "none";
 			}
 
-			// If openOnClick is true, we basically just want to treat the whole widget as the
-			// button.  We need to do that also if the actual drop down button will be hidden,
-			// so that there's a mouse method for opening the drop down.
-			if(this.openOnClick || !this.hasDownArrow){
+			// If hasDownArrow is false, we basically just want to treat the whole widget as the
+			// button.
+			if(!this.hasDownArrow){
 				this._buttonNode = this.domNode;
 				this.baseClass += " dijitComboBoxOpenOnClick";
 			}
@@ -163,7 +151,7 @@ define([
 			constraints.fullYear = true; // see #5465 - always format with 4-digit years
 			var fromISO = stamp.fromISOString;
 			if(typeof constraints.min == "string"){ constraints.min = fromISO(constraints.min); }
- 			if(typeof constraints.max == "string"){ constraints.max = fromISO(constraints.max); }
+			if(typeof constraints.max == "string"){ constraints.max = fromISO(constraints.max); }
 			this.inherited(arguments);
 		},
 
@@ -200,7 +188,8 @@ define([
 
 		_set: function(attr, value){
 			// Avoid spurious watch() notifications when value is changed to new Date object w/the same value
-			if(attr == "value" && this.value instanceof Date && this.compare(value, this.value) == 0){
+			var oldValue = this._get("value");
+			if(attr == "value" && oldValue instanceof Date && this.compare(value, oldValue) == 0){
 				return;
 			}
 			this.inherited(arguments);
@@ -211,7 +200,7 @@ define([
 				// convert null setting into today's date, since there needs to be *some* default at all times.
 				 val = new this.dateClassObj();
 			}
-			this.dropDownDefaultValue = val;
+			this._set("dropDownDefaultValue", val);
 		},
 
 		openDropDown: function(/*Function*/ callback){
@@ -231,18 +220,17 @@ define([
 				dir: textBox.dir,
 				lang: textBox.lang,
 				value: value,
+				textDir: textBox.textDir,
 				currentFocus: !this._isInvalidDate(value) ? value : this.dropDownDefaultValue,
-					constraints: textBox.constraints,
+				constraints: textBox.constraints,
 				filterString: textBox.filterString, // for TimeTextBox, to filter times shown
-
-					datePackage: textBox.datePackage,
-
-					isDisabledDate: function(/*Date*/ date){
-						// summary:
-						// 	disables dates outside of the min/max of the _DateTimeTextBox
-						return !textBox.rangeCheck(date, textBox.constraints);
-					}
-				});
+				datePackage: textBox.params.datePackage,
+				isDisabledDate: function(/*Date*/ date){
+					// summary:
+					//		disables dates outside of the min/max of the _DateTimeTextBox
+					return !textBox.rangeCheck(date, textBox.constraints);
+				}
+			});
 
 			this.inherited(arguments);
 		},
@@ -256,5 +244,17 @@ define([
 		}
 	});
 
+
+	/*=====
+	 _DateTimeTextBox.__Constraints = declare([RangeBoundTextBox.__Constraints, locale.__FormatOptions], {
+		 // summary:
+		 //		Specifies both the rules on valid/invalid values (first/last date/time allowed),
+		 //		and also formatting options for how the date/time is displayed.
+		 // example:
+		 //		To restrict to dates within 2004, displayed in a long format like "December 25, 2005":
+		 //	|		{min:'2004-01-01',max:'2004-12-31', formatLength:'long'}
+	 });
+	 =====*/
+
 	return _DateTimeTextBox;
 });
diff --git a/dijit/form/_ExpandingTextAreaMixin.js b/dijit/form/_ExpandingTextAreaMixin.js
index 74a65ee..652fe72 100644
--- a/dijit/form/_ExpandingTextAreaMixin.js
+++ b/dijit/form/_ExpandingTextAreaMixin.js
@@ -1,17 +1,29 @@
 define([
 	"dojo/_base/declare", // declare
 	"dojo/dom-construct", // domConstruct.create
+	"dojo/has",
 	"dojo/_base/lang", // lang.hitch
-	"dojo/_base/window" // win.body
-], function(declare, domConstruct, lang, win){
+	"dojo/on",
+	"dojo/_base/window", // win.body
+	"../Viewport"
+], function(declare, domConstruct, has, lang, on, win, Viewport){
 
 	// module:
 	//		dijit/form/_ExpandingTextAreaMixin
-	// summary:
-	//		Mixin for textarea widgets to add auto-expanding capability
 
-	// feature detection
-	var needsHelpShrinking;
+	// feature detection, true for mozilla and webkit
+	has.add("textarea-needs-help-shrinking", function(){
+		var body = win.body(),	// note: if multiple documents exist, doesn't matter which one we use
+			te = domConstruct.create('textarea', {
+			rows:"5",
+			cols:"20",
+			value: ' ',
+			style: {zoom:1, fontSize:"12px", height:"96px", overflow:'hidden', visibility:'hidden', position:'absolute', border:"5px solid white", margin:"0", padding:"0", boxSizing: 'border-box', MsBoxSizing: 'border-box', WebkitBoxSizing: 'border-box', MozBoxSizing: 'border-box' }
+		}, body, "last");
+		var needsHelpShrinking = te.scrollHeight >= te.clientHeight;
+		body.removeChild(te);
+		return needsHelpShrinking;
+	});
 
 	return declare("dijit.form._ExpandingTextAreaMixin", null, {
 		// summary:
@@ -25,17 +37,13 @@ define([
 		postCreate: function(){
 			this.inherited(arguments);
 			var textarea = this.textbox;
-
-			if(needsHelpShrinking == undefined){
-				var te = domConstruct.create('textarea', {rows:"5", cols:"20", value: ' ', style: {zoom:1, overflow:'hidden', visibility:'hidden', position:'absolute', border:"0px solid black", padding:"0px"}}, win.body(), "last");
-				needsHelpShrinking = te.scrollHeight >= te.clientHeight;
-				win.body().removeChild(te);
-			}
-			this.connect(textarea, "onscroll", "_resizeLater");
-			this.connect(textarea, "onresize", "_resizeLater");
-			this.connect(textarea, "onfocus", "_resizeLater");
 			textarea.style.overflowY = "hidden";
-			this._estimateHeight();
+			this.own(on(textarea, "focus, resize", lang.hitch(this, "_resizeLater")));
+		},
+
+		startup: function(){ 
+			this.inherited(arguments);
+			this.own(Viewport.on("resize", lang.hitch(this, "_resizeLater")));
 			this._resizeLater();
 		},
 
@@ -46,26 +54,25 @@ define([
 
 		_estimateHeight: function(){
 			// summary:
-			// 		Approximate the height when the textarea is invisible with the number of lines in the text.
-			// 		Fails when someone calls setValue with a long wrapping line, but the layout fixes itself when the user clicks inside so . . .
-			// 		In IE, the resize event is supposed to fire when the textarea becomes visible again and that will correct the size automatically.
+			//		Approximate the height when the textarea is invisible with the number of lines in the text.
+			//		Fails when someone calls setValue with a long wrapping line, but the layout fixes itself when the user clicks inside so . . .
+			//		In IE, the resize event is supposed to fire when the textarea becomes visible again and that will correct the size automatically.
 			//
 			var textarea = this.textbox;
-			textarea.style.height = "auto";
 			// #rows = #newlines+1
-			// Note: on Moz, the following #rows appears to be 1 too many.
-			// Actually, Moz is reserving room for the scrollbar.
-			// If you increase the font size, this behavior becomes readily apparent as the last line gets cut off without the +1.
-			textarea.rows = (textarea.value.match(/\n/g) || []).length + 2;
+			textarea.rows = (textarea.value.match(/\n/g) || []).length + 1;
 		},
 
 		_resizeLater: function(){
-			setTimeout(lang.hitch(this, "resize"), 0);
+			this.defer("resize");
 		},
 
 		resize: function(){
 			// summary:
 			//		Resizes the textarea vertically (should be called after a style/value change)
+
+			var textarea = this.textbox;
+
 			function textareaScrollHeight(){
 				var empty = false;
 				if(textarea.value === ''){
@@ -77,45 +84,47 @@ define([
 				return sh;
 			}
 
-			var textarea = this.textbox;
 			if(textarea.style.overflowY == "hidden"){ textarea.scrollTop = 0; }
-			if(this.resizeTimer){ clearTimeout(this.resizeTimer); }
-			this.resizeTimer = null;
 			if(this.busyResizing){ return; }
 			this.busyResizing = true;
 			if(textareaScrollHeight() || textarea.offsetHeight){
-				var currentHeight = textarea.style.height;
-				if(!(/px/.test(currentHeight))){
-					currentHeight = textareaScrollHeight();
-					textarea.rows = 1;
-					textarea.style.height = currentHeight + "px";
-				}
-				var newH = Math.max(parseInt(currentHeight) - textarea.clientHeight, 0) + textareaScrollHeight();
+				var newH = textareaScrollHeight() + Math.max(textarea.offsetHeight - textarea.clientHeight, 0);
 				var newHpx = newH + "px";
 				if(newHpx != textarea.style.height){
-					textarea.rows = 1;
 					textarea.style.height = newHpx;
+					textarea.rows = 1; // rows can act like a minHeight if not cleared
 				}
-				if(needsHelpShrinking){
-					var scrollHeight = textareaScrollHeight();
-					textarea.style.height = "auto";
-					if(textareaScrollHeight() < scrollHeight){ // scrollHeight can shrink so now try a larger value
-						newHpx = newH - scrollHeight + textareaScrollHeight() + "px";
+				if(has("textarea-needs-help-shrinking")){
+					var	origScrollHeight = textareaScrollHeight(),
+						newScrollHeight = origScrollHeight,
+						origMinHeight = textarea.style.minHeight,
+						decrement = 4, // not too fast, not too slow
+						thisScrollHeight,
+						origScrollTop = textarea.scrollTop;
+					textarea.style.minHeight = newHpx; // maintain current height
+					textarea.style.height = "auto"; // allow scrollHeight to change
+					while(newH > 0){
+						textarea.style.minHeight = Math.max(newH - decrement, 4) + "px";
+						thisScrollHeight = textareaScrollHeight();
+						var change = newScrollHeight - thisScrollHeight;
+						newH -= change;
+						if(change < decrement){
+							break; // scrollHeight didn't shrink
+						}
+						newScrollHeight = thisScrollHeight;
+						decrement <<= 1;
 					}
-					textarea.style.height = newHpx;
+					textarea.style.height = newH + "px";
+					textarea.style.minHeight = origMinHeight;
+					textarea.scrollTop = origScrollTop;
 				}
 				textarea.style.overflowY = textareaScrollHeight() > textarea.clientHeight ? "auto" : "hidden";
+				if(textarea.style.overflowY == "hidden"){ textarea.scrollTop = 0; }
 			}else{
 				// hidden content of unknown size
 				this._estimateHeight();
 			}
 			this.busyResizing = false;
-		},
-
-		destroy: function(){
-			if(this.resizeTimer){ clearTimeout(this.resizeTimer); }
-			if(this.shrinkTimer){ clearTimeout(this.shrinkTimer); }
-			this.inherited(arguments);
 		}
 	});
 });
diff --git a/dijit/form/_FormMixin.js b/dijit/form/_FormMixin.js
index f578cf7..029d362 100644
--- a/dijit/form/_FormMixin.js
+++ b/dijit/form/_FormMixin.js
@@ -3,19 +3,17 @@ define([
 	"dojo/_base/declare", // declare
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/_base/lang", // lang.hitch lang.isArray
+	"dojo/on",
 	"dojo/window" // winUtils.scrollIntoView
-], function(array, declare, kernel, lang, winUtils){
+], function(array, declare, kernel, lang, on, winUtils){
 
 	// module:
 	//		dijit/form/_FormMixin
-	// summary:
-	//		Mixin for containers of form widgets (i.e. widgets that represent a single value
-	//		and can be children of a <form> node or dijit.form.Form widget)
 
 	return declare("dijit.form._FormMixin", null, {
 		// summary:
 		//		Mixin for containers of form widgets (i.e. widgets that represent a single value
-		//		and can be children of a <form> node or dijit.form.Form widget)
+		//		and can be children of a `<form>` node or `dijit/form/Form` widget)
 		// description:
 		//		Can extract all the form widgets
 		//		values and combine them into a single javascript object, or alternately
@@ -43,14 +41,13 @@ define([
 		//		which indicates that the form is ready to be submitted.
 		state: "",
 
-		//	TODO:
+		// TODO:
 		//	* Repeater
 		//	* better handling for arrays.  Often form elements have names with [] like
 		//	* people[3].sex (for a list of people [{name: Bill, sex: M}, ...])
-		//
-		//
 
-		_getDescendantFormWidgets: function(/*dijit._WidgetBase[]?*/ children){
+
+		_getDescendantFormWidgets: function(/*dijit/_WidgetBase[]?*/ children){
 			// summary:
 			//		Returns all form widget descendants, searching through non-form child widgets like BorderContainer
 			var res = [];
@@ -75,11 +72,10 @@ define([
 		validate: function(){
 			// summary:
 			//		returns if the form is valid - same as isValid - but
-			//		provides a few additional (ui-specific) features.
-			//		1 - it will highlight any sub-widgets that are not
-			//			valid
-			//		2 - it will call focus() on the first invalid
-			//			sub-widget
+			//		provides a few additional (ui-specific) features:
+			//
+			//		1. it will highlight any sub-widgets that are not valid
+			//		2. it will call focus() on the first invalid sub-widget
 			var didFocus = false;
 			return array.every(array.map(this._getDescendantFormWidgets(), function(widget){
 				// Need to set this so that "required" widgets get their
@@ -92,8 +88,8 @@ define([
 					widget.focus();
 					didFocus = true;
 				}
-	 			return valid;
-	 		}), function(item){ return item; });
+				return valid;
+			}), function(item){ return item; });
 		},
 
 		setValues: function(val){
@@ -122,13 +118,11 @@ define([
 				if(values === undefined){
 					continue;
 				}
-				if(!lang.isArray(values)){
-					values = [ values ];
-				}
+				values = [].concat(values);
 				if(typeof widgets[0].checked == 'boolean'){
 					// for checkbox/radio, values is a list of which widgets should be checked
 					array.forEach(widgets, function(w){
-						w.set('value', array.indexOf(values, w.value) != -1);
+						w.set('value', array.indexOf(values, w._get('value')) != -1);
 					});
 				}else if(widgets[0].multiple){
 					// it takes an array (e.g. multi-select)
@@ -142,7 +136,7 @@ define([
 			}
 
 			/***
-			 * 	TODO: code for plain input boxes (this shouldn't run for inputs that are part of widgets)
+			 *	TODO: code for plain input boxes (this shouldn't run for inputs that are part of widgets)
 
 			array.forEach(this.containerNode.elements, function(element){
 				if(element.name == ''){return};	// like "continue"
@@ -210,8 +204,8 @@ define([
 						element.value = myObj[name] || "";
 						break;
 				}
-	  		});
-	  		*/
+			});
+			*/
 
 			// Note: no need to call this._set("value", ...) as the child updates will trigger onChange events
 			// which I am monitoring.
@@ -223,7 +217,7 @@ define([
 		},
 		_getValueAttr: function(){
 			// summary:
-			// 		Returns Object representing form values.   See description of `value` for details.
+			//		Returns Object representing form values.   See description of `value` for details.
 			// description:
 
 			// The value is updated into this.value every time a child has an onChange event,
@@ -231,7 +225,7 @@ define([
 			// that wouldn't work when:
 			//
 			// 1. User presses return key to submit a form.  That doesn't fire an onchange event,
-			// and even if it did it would come too late due to the setTimeout(..., 0) in _handleOnChange()
+			// and even if it did it would come too late due to the defer(...) in _handleOnChange()
 			//
 			// 2. app for some reason calls this.get("value") while the user is typing into a
 			// form field.   Not sure if that case needs to be supported or not.
@@ -345,9 +339,9 @@ define([
 			return obj;
 		},
 
-	 	isValid: function(){
-	 		// summary:
-	 		//		Returns true if all of the widgets are valid.
+		isValid: function(){
+			// summary:
+			//		Returns true if all of the widgets are valid.
 			//		Deprecated, will be removed in 2.0.  Use get("state") instead.
 
 			return this.state == "";
@@ -375,99 +369,84 @@ define([
 
 		disconnectChildren: function(){
 			// summary:
-			//		Remove connections to monitor changes to children's value, error state, and disabled state,
-			//		in order to update Form.value and Form.state.
-			array.forEach(this._childConnections || [], lang.hitch(this, "disconnect"));
-			array.forEach(this._childWatches || [], function(w){ w.unwatch(); });
+			//		Deprecated method.   Applications no longer need to call this.   Remove for 2.0.
 		},
 
 		connectChildren: function(/*Boolean*/ inStartup){
 			// summary:
-			//		Setup connections to monitor changes to children's value, error state, and disabled state,
-			//		in order to update Form.value and Form.state.
-			//
 			//		You can call this function directly, ex. in the event that you
 			//		programmatically add a widget to the form *after* the form has been
 			//		initialized.
 
-			var _this = this;
-
-			// Remove old connections, if any
-			this.disconnectChildren();
+			// TODO: rename for 2.0
 
 			this._descendants = this._getDescendantFormWidgets();
 
-			// (Re)set this.value and this.state.   Send watch() notifications but not on startup.
-			var set = inStartup ? function(name, val){ _this[name] = val; } : lang.hitch(this, "_set");
-			set("value", this.get("value"));
-			set("state", this._getState());
-
-			// Monitor changes to error state and disabled state in order to update
-			// Form.state
-			var conns = (this._childConnections = []),
-				watches = (this._childWatches = []);
-			array.forEach(array.filter(this._descendants,
-				function(item){ return item.validate; }
-			),
-			function(widget){
-				// We are interested in whenever the widget changes validity state - or
-				// whenever the disabled attribute on that widget is changed.
-				array.forEach(["state", "disabled"], function(attr){
-					watches.push(widget.watch(attr, function(){
-						_this.set("state", _this._getState());
-					}));
-				});
+			// To get notifications from children they need to be started.   Children didn't used to need to be started,
+			// so for back-compat, start them here
+			array.forEach(this._descendants, function(child){
+				if(!child._started){ child.startup(); }
 			});
 
-			// And monitor calls to child.onChange so we can update this.value
-			var onChange = function(){
-				// summary:
-				//		Called when child's value or disabled state changes
-
-				// Use setTimeout() to collapse value changes in multiple children into a single
-				// update to my value.   Multiple updates will occur on:
-				//	1. Form.set()
-				//	2. Form.reset()
-				//	3. user selecting a radio button (which will de-select another radio button,
-				//		 causing two onChange events)
-				if(_this._onChangeDelayTimer){
-					clearTimeout(_this._onChangeDelayTimer);
+			if(!inStartup){
+				this._onChildChange();
+			}
+		},
+
+		_onChildChange: function(/*String*/ attr){
+			// summary:
+			//		Called when child's value or disabled state changes
+
+			// The unit tests expect state update to be synchronous, so update it immediately.
+			if(!attr || attr == "state" || attr == "disabled"){
+				this._set("state", this._getState());
+			}
+
+			// Use defer() to collapse value changes in multiple children into a single
+			// update to my value.   Multiple updates will occur on:
+			//	1. Form.set()
+			//	2. Form.reset()
+			//	3. user selecting a radio button (which will de-select another radio button,
+			//		 causing two onChange events)
+			if(!attr || attr == "value" || attr == "disabled" || attr == "checked"){
+				if(this._onChangeDelayTimer){
+					this._onChangeDelayTimer.remove();
 				}
-				_this._onChangeDelayTimer = setTimeout(function(){
-					delete _this._onChangeDelayTimer;
-					_this._set("value", _this.get("value"));
+				this._onChangeDelayTimer = this.defer(function(){
+					delete this._onChangeDelayTimer;
+					this._set("value", this.get("value"));
 				}, 10);
-			};
-			array.forEach(
-				array.filter(this._descendants, function(item){ return item.onChange; } ),
-				function(widget){
-					// When a child widget's value changes,
-					// the efficient thing to do is to just update that one attribute in this.value,
-					// but that gets a little complicated when a checkbox is checked/unchecked
-					// since this.value["checkboxName"] contains an array of all the checkboxes w/the same name.
-					// Doing simple thing for now.
-					conns.push(_this.connect(widget, "onChange", onChange));
-
-					// Disabling/enabling a child widget should remove it's value from this.value.
-					// Again, this code could be more efficient, doing simple thing for now.
-					watches.push(widget.watch("disabled", onChange));
-				}
-			);
+			}
 		},
 
 		startup: function(){
 			this.inherited(arguments);
 
-			// Initialize value and valid/invalid state tracking.  Needs to be done in startup()
-			// so that children are initialized.
-			this.connectChildren(true);
+			// Set initial this.value and this.state.   Don't emit watch() notifications.
+			this._descendants = this._getDescendantFormWidgets();
+			this.value = this.get("value");
+			this.state = this._getState();
+
+			// Initialize value and valid/invalid state tracking.
+			var self = this;
+			this.own(
+				on(
+					this.containerNode,
+					"attrmodified-state, attrmodified-disabled, attrmodified-value, attrmodified-checked",
+					function(evt){
+						if(evt.target == self.domNode){
+							return;	// ignore events that I fire on myself because my children changed
+						}
+						self._onChildChange(evt.type.replace("attrmodified-", ""));
+					}
+				)
+			);
 
 			// Make state change call onValidStateChange(), will be removed in 2.0
 			this.watch("state", function(attr, oldVal, newVal){ this.onValidStateChange(newVal == ""); });
 		},
 
 		destroy: function(){
-			this.disconnectChildren();
 			this.inherited(arguments);
 		}
 
diff --git a/dijit/form/_FormSelectWidget.js b/dijit/form/_FormSelectWidget.js
index c156475..34b3d99 100644
--- a/dijit/form/_FormSelectWidget.js
+++ b/dijit/form/_FormSelectWidget.js
@@ -1,5 +1,6 @@
 define([
 	"dojo/_base/array", // array.filter array.forEach array.map array.some
+	"dojo/_base/Deferred",
 	"dojo/aspect", // aspect.after
 	"dojo/data/util/sorter", // util.sorter.createSortFunction
 	"dojo/_base/declare", // declare
@@ -8,270 +9,367 @@ define([
 	"dojo/_base/kernel",	// _scopeName
 	"dojo/_base/lang", // lang.delegate lang.isArray lang.isObject lang.hitch
 	"dojo/query", // query
+	"dojo/when",
+	"dojo/store/util/QueryResults",
 	"./_FormValueWidget"
-], function(array, aspect, sorter, declare, dom, domClass, kernel, lang, query, _FormValueWidget){
-
-/*=====
-	var _FormValueWidget = dijit.form._FormValueWidget;
-=====*/
-
-// module:
-//		dijit/form/_FormSelectWidget
-// summary:
-//		Extends _FormValueWidget in order to provide "select-specific"
-//		values - i.e., those values that are unique to <select> elements.
-
-
-/*=====
-dijit.form.__SelectOption = function(){
-	// value: String
-	//		The value of the option.  Setting to empty (or missing) will
-	//		place a separator at that location
-	// label: String
-	//		The label for our option.  It can contain html tags.
-	// selected: Boolean
-	//		Whether or not we are a selected option
-	// disabled: Boolean
-	//		Whether or not this specific option is disabled
-	this.value = value;
-	this.label = label;
-	this.selected = selected;
-	this.disabled = disabled;
-}
-=====*/
-
-return declare("dijit.form._FormSelectWidget", _FormValueWidget, {
-	// summary:
-	//		Extends _FormValueWidget in order to provide "select-specific"
-	//		values - i.e., those values that are unique to <select> elements.
-	//		This also provides the mechanism for reading the elements from
-	//		a store, if desired.
-
-	// multiple: [const] Boolean
-	//		Whether or not we are multi-valued
-	multiple: false,
-
-	// options: dijit.form.__SelectOption[]
-	//		The set of options for our select item.  Roughly corresponds to
-	//		the html <option> tag.
-	options: null,
-
-	// store: dojo.data.api.Identity
-	//		A store which, at the very least implements dojo.data.api.Identity
-	//		to use for getting our list of options - rather than reading them
-	//		from the <option> html tags.
-	store: null,
-
-	// query: object
-	//		A query to use when fetching items from our store
-	query: null,
-
-	// queryOptions: object
-	//		Query options to use when fetching from the store
-	queryOptions: null,
-
-	// onFetch: Function
-	//		A callback to do with an onFetch - but before any items are actually
-	//		iterated over (i.e. to filter even further what you want to add)
-	onFetch: null,
-
-	// sortByLabel: Boolean
-	//		Flag to sort the options returned from a store by the label of
-	//		the store.
-	sortByLabel: true,
-
-
-	// loadChildrenOnOpen: Boolean
-	//		By default loadChildren is called when the items are fetched from the
-	//		store.  This property allows delaying loadChildren (and the creation
-	//		of the options/menuitems) until the user clicks the button to open the
-	//		dropdown.
-	loadChildrenOnOpen: false,
-
-	getOptions: function(/*anything*/ valueOrIdx){
+], function(array, Deferred, aspect, sorter, declare, dom, domClass, kernel, lang, query, when,
+			QueryResults, _FormValueWidget){
+
+	// module:
+	//		dijit/form/_FormSelectWidget
+
+	/*=====
+	var __SelectOption = {
+		// value: String
+		//		The value of the option.  Setting to empty (or missing) will
+		//		place a separator at that location
+		// label: String
+		//		The label for our option.  It can contain html tags.
+		// selected: Boolean
+		//		Whether or not we are a selected option
+		// disabled: Boolean
+		//		Whether or not this specific option is disabled
+	};
+	=====*/
+
+	var _FormSelectWidget = declare("dijit.form._FormSelectWidget", _FormValueWidget, {
 		// summary:
-		//		Returns a given option (or options).
-		// valueOrIdx:
-		//		If passed in as a string, that string is used to look up the option
-		//		in the array of options - based on the value property.
-		//		(See dijit.form.__SelectOption).
-		//
-		//		If passed in a number, then the option with the given index (0-based)
-		//		within this select will be returned.
-		//
-		//		If passed in a dijit.form.__SelectOption, the same option will be
-		//		returned if and only if it exists within this select.
-		//
-		//		If passed an array, then an array will be returned with each element
-		//		in the array being looked up.
-		//
-		//		If not passed a value, then all options will be returned
-		//
-		// returns:
-		//		The option corresponding with the given value or index.  null
-		//		is returned if any of the following are true:
-		//			- A string value is passed in which doesn't exist
-		//			- An index is passed in which is outside the bounds of the array of options
-		//			- A dijit.form.__SelectOption is passed in which is not a part of the select
-
-		// NOTE: the compare for passing in a dijit.form.__SelectOption checks
-		//		if the value property matches - NOT if the exact option exists
-		// NOTE: if passing in an array, null elements will be placed in the returned
-		//		array when a value is not found.
-		var lookupValue = valueOrIdx, opts = this.options || [], l = opts.length;
-
-		if(lookupValue === undefined){
-			return opts; // dijit.form.__SelectOption[]
-		}
-		if(lang.isArray(lookupValue)){
-			return array.map(lookupValue, "return this.getOptions(item);", this); // dijit.form.__SelectOption[]
-		}
-		if(lang.isObject(valueOrIdx)){
-			// We were passed an option - so see if it's in our array (directly),
-			// and if it's not, try and find it by value.
-			if(!array.some(this.options, function(o, idx){
-				if(o === lookupValue ||
-					(o.value && o.value === lookupValue.value)){
-					lookupValue = idx;
-					return true;
-				}
-				return false;
-			})){
-				lookupValue = -1;
+		//		Extends _FormValueWidget in order to provide "select-specific"
+		//		values - i.e., those values that are unique to `<select>` elements.
+		//		This also provides the mechanism for reading the elements from
+		//		a store, if desired.
+
+		// multiple: [const] Boolean
+		//		Whether or not we are multi-valued
+		multiple: false,
+
+		// options: __SelectOption[]
+		//		The set of options for our select item.  Roughly corresponds to
+		//		the html `<option>` tag.
+		options: null,
+
+		// store: dojo/store/api/Store
+		//		A store to use for getting our list of options - rather than reading them
+		//		from the `<option>` html tags.   Should support getIdentity().
+		//		For back-compat store can also be a dojo/data/api/Identity.
+		store: null,
+
+		// query: object
+		//		A query to use when fetching items from our store
+		query: null,
+
+		// queryOptions: object
+		//		Query options to use when fetching from the store
+		queryOptions: null,
+
+		// labelAttr: String?
+		//		The entries in the drop down list come from this attribute in the dojo.store items.
+		//		If ``store`` is set, labelAttr must be set too, unless store is an old-style
+		//		dojo.data store rather than a new dojo/store.
+		labelAttr: "",
+
+		// onFetch: Function
+		//		A callback to do with an onFetch - but before any items are actually
+		//		iterated over (i.e. to filter even further what you want to add)
+		onFetch: null,
+
+		// sortByLabel: Boolean
+		//		Flag to sort the options returned from a store by the label of
+		//		the store.
+		sortByLabel: true,
+
+
+		// loadChildrenOnOpen: Boolean
+		//		By default loadChildren is called when the items are fetched from the
+		//		store.  This property allows delaying loadChildren (and the creation
+		//		of the options/menuitems) until the user clicks the button to open the
+		//		dropdown.
+		loadChildrenOnOpen: false,
+
+		// onLoadDeferred: [readonly] dojo.Deferred
+		//		This is the `dojo.Deferred` returned by setStore().
+		//		Calling onLoadDeferred.then() registers your
+		//		callback to be called only once, when the prior setStore completes.
+		onLoadDeferred: null,
+
+		getOptions: function(/*anything*/ valueOrIdx){
+			// summary:
+			//		Returns a given option (or options).
+			// valueOrIdx:
+			//		If passed in as a string, that string is used to look up the option
+			//		in the array of options - based on the value property.
+			//		(See dijit/form/_FormSelectWidget.__SelectOption).
+			//
+			//		If passed in a number, then the option with the given index (0-based)
+			//		within this select will be returned.
+			//
+			//		If passed in a dijit/form/_FormSelectWidget.__SelectOption, the same option will be
+			//		returned if and only if it exists within this select.
+			//
+			//		If passed an array, then an array will be returned with each element
+			//		in the array being looked up.
+			//
+			//		If not passed a value, then all options will be returned
+			//
+			// returns:
+			//		The option corresponding with the given value or index.
+			//		null is returned if any of the following are true:
+			//
+			//		- A string value is passed in which doesn't exist
+			//		- An index is passed in which is outside the bounds of the array of options
+			//		- A dijit/form/_FormSelectWidget.__SelectOption is passed in which is not a part of the select
+
+			// NOTE: the compare for passing in a dijit/form/_FormSelectWidget.__SelectOption checks
+			//		if the value property matches - NOT if the exact option exists
+			// NOTE: if passing in an array, null elements will be placed in the returned
+			//		array when a value is not found.
+			var opts = this.options || [];
+
+			if(valueOrIdx == null){
+				return opts; // __SelectOption[]
 			}
-		}
-		if(typeof lookupValue == "string"){
-			for(var i=0; i<l; i++){
-				if(opts[i].value === lookupValue){
-					lookupValue = i;
-					break;
+			if(lang.isArray(valueOrIdx)){
+				return array.map(valueOrIdx, "return this.getOptions(item);", this); // __SelectOption[]
+			}
+			if(lang.isString(valueOrIdx)){
+				valueOrIdx = { value: valueOrIdx };
+			}
+			if(lang.isObject(valueOrIdx)){
+				// We were passed an option - so see if it's in our array (directly),
+				// and if it's not, try and find it by value.
+
+				if(!array.some(opts, function(option, idx){
+					for(var a in valueOrIdx){
+						if(!(a in option) || option[a] != valueOrIdx[a]){ // == and not === so that 100 matches '100'
+							return false;
+						}
+					}
+					valueOrIdx = idx;
+					return true; // stops iteration through opts
+				})){
+					valueOrIdx = -1;
 				}
 			}
-		}
-		if(typeof lookupValue == "number" && lookupValue >= 0 && lookupValue < l){
-			return this.options[lookupValue]; // dijit.form.__SelectOption
-		}
-		return null; // null
-	},
-
-	addOption: function(/*dijit.form.__SelectOption|dijit.form.__SelectOption[]*/ option){
-		// summary:
-		//		Adds an option or options to the end of the select.  If value
-		//		of the option is empty or missing, a separator is created instead.
-		//		Passing in an array of options will yield slightly better performance
-		//		since the children are only loaded once.
-		if(!lang.isArray(option)){ option = [option]; }
-		array.forEach(option, function(i){
-			if(i && lang.isObject(i)){
-				this.options.push(i);
+			if(valueOrIdx >= 0 && valueOrIdx < opts.length){
+				return opts[valueOrIdx]; // __SelectOption
 			}
-		}, this);
-		this._loadChildren();
-	},
+			return null; // null
+		},
+
+		addOption: function(/*__SelectOption|__SelectOption[]*/ option){
+			// summary:
+			//		Adds an option or options to the end of the select.  If value
+			//		of the option is empty or missing, a separator is created instead.
+			//		Passing in an array of options will yield slightly better performance
+			//		since the children are only loaded once.
+			array.forEach(lang.isArray(option) ? option : [option], function(i){
+				if(i && lang.isObject(i)){
+					this.options.push(i);
+				}
+			}, this);
+			this._loadChildren();
+		},
+
+		removeOption: function(/*String|__SelectOption|Number|Array*/ valueOrIdx){
+			// summary:
+			//		Removes the given option or options.  You can remove by string
+			//		(in which case the value is removed), number (in which case the
+			//		index in the options array is removed), or select option (in
+			//		which case, the select option with a matching value is removed).
+			//		You can also pass in an array of those values for a slightly
+			//		better performance since the children are only loaded once.
+			//		For numeric option values, specify {value: number} as the argument.
+			var oldOpts = this.getOptions(lang.isArray(valueOrIdx) ? valueOrIdx : [valueOrIdx]);
+			array.forEach(oldOpts, function(option){
+				// We can get null back in our array - if our option was not found.  In
+				// that case, we don't want to blow up...
+				if(option){
+					this.options = array.filter(this.options, function(node){
+						return (node.value !== option.value || node.label !== option.label);
+					});
+					this._removeOptionItem(option);
+				}
+			}, this);
+			this._loadChildren();
+		},
+
+		updateOption: function(/*__SelectOption|__SelectOption[]*/ newOption){
+			// summary:
+			//		Updates the values of the given option.  The option to update
+			//		is matched based on the value of the entered option.  Passing
+			//		in an array of new options will yield better performance since
+			//		the children will only be loaded once.
+			array.forEach(lang.isArray(newOption) ? newOption : [newOption], function(i){
+				var oldOpt = this.getOptions({ value: i.value }), k;
+				if(oldOpt){
+					for(k in i){
+						oldOpt[k] = i[k];
+					}
+				}
+			}, this);
+			this._loadChildren();
+		},
+
+		setStore: function(store, selectedValue, fetchArgs){
+			// summary:
+			//		Sets the store you would like to use with this select widget.
+			//		The selected value is the value of the new store to set.  This
+			//		function returns the original store, in case you want to reuse
+			//		it or something.
+			// store: dojo/store/api/Store
+			//		The dojo.store you would like to use - it MUST implement getIdentity()
+			//		and MAY implement observe().
+			//		For backwards-compatibility this can also be a data.data store, in which case
+			//		it MUST implement dojo/data/api/Identity,
+			//		and MAY implement dojo/data/api/Notification.
+			// selectedValue: anything?
+			//		The value that this widget should set itself to *after* the store
+			//		has been loaded
+			// fetchArgs: Object?
+			//		Hash of parameters to set filter on store, etc.
+			//
+			//		- query: new value for Select.query,
+			//		- queryOptions: new value for Select.queryOptions,
+			//		- onFetch: callback function for each item in data (Deprecated)
+			var oStore = this.store;
+			fetchArgs = fetchArgs || {};
+
+			if(oStore !== store){
+				// Our store has changed, so cancel any listeners on old store (remove for 2.0)
+				var h;
+				while((h = this._notifyConnections.pop())){
+					h.remove();
+				}
 
-	removeOption: function(/*String|dijit.form.__SelectOption|Number|Array*/ valueOrIdx){
-		// summary:
-		//		Removes the given option or options.  You can remove by string
-		//		(in which case the value is removed), number (in which case the
-		//		index in the options array is removed), or select option (in
-		//		which case, the select option with a matching value is removed).
-		//		You can also pass in an array of those values for a slightly
-		//		better performance since the children are only loaded once.
-		if(!lang.isArray(valueOrIdx)){ valueOrIdx = [valueOrIdx]; }
-		var oldOpts = this.getOptions(valueOrIdx);
-		array.forEach(oldOpts, function(i){
-			// We can get null back in our array - if our option was not found.  In
-			// that case, we don't want to blow up...
-			if(i){
-				this.options = array.filter(this.options, function(node){
-					return (node.value !== i.value || node.label !== i.label);
-				});
-				this._removeOptionItem(i);
+				// For backwards-compatibility, accept dojo.data store in addition to dojo.store.store.  Remove in 2.0.
+				if(!store.get){
+					lang.mixin(store, {
+						_oldAPI: true,
+						get: function(id){
+							// summary:
+							//		Retrieves an object by it's identity. This will trigger a fetchItemByIdentity.
+							//		Like dojo.store.DataStore.get() except returns native item.
+							var deferred = new Deferred();
+							this.fetchItemByIdentity({
+								identity: id,
+								onItem: function(object){
+									deferred.resolve(object);
+								},
+								onError: function(error){
+									deferred.reject(error);
+								}
+							});
+							return deferred.promise;
+						},
+						query: function(query, options){
+							// summary:
+							//		Queries the store for objects.   Like dojo/store/DataStore.query()
+							//		except returned Deferred contains array of native items.
+							var deferred = new Deferred(function(){
+								if(fetchHandle.abort){
+									fetchHandle.abort();
+								}
+							});
+							deferred.total = new Deferred();
+							var fetchHandle = this.fetch(lang.mixin({
+								query: query,
+								onBegin: function(count){
+									deferred.total.resolve(count);
+								},
+								onComplete: function(results){
+									deferred.resolve(results);
+								},
+								onError: function(error){
+									deferred.reject(error);
+								}
+							}, options));
+							return new QueryResults(deferred);
+						}
+					});
+
+					if(store.getFeatures()["dojo.data.api.Notification"]){
+						this._notifyConnections = [
+							aspect.after(store, "onNew", lang.hitch(this, "_onNewItem"), true),
+							aspect.after(store, "onDelete", lang.hitch(this, "_onDeleteItem"), true),
+							aspect.after(store, "onSet", lang.hitch(this, "_onSetItem"), true)
+						];
+					}
+				}
+				this._set("store", store);			// Our store has changed, so update our notifications
 			}
-		}, this);
-		this._loadChildren();
-	},
 
-	updateOption: function(/*dijit.form.__SelectOption|dijit.form.__SelectOption[]*/ newOption){
-		// summary:
-		//		Updates the values of the given option.  The option to update
-		//		is matched based on the value of the entered option.  Passing
-		//		in an array of new options will yield better performance since
-		//		the children will only be loaded once.
-		if(!lang.isArray(newOption)){ newOption = [newOption]; }
-		array.forEach(newOption, function(i){
-			var oldOpt = this.getOptions(i), k;
-			if(oldOpt){
-				for(k in i){ oldOpt[k] = i[k]; }
+			// Remove existing options (if there are any)
+			if(this.options && this.options.length){
+				this.removeOption(this.options);
 			}
-		}, this);
-		this._loadChildren();
-	},
 
-	setStore: function(/*dojo.data.api.Identity*/ store,
-						/*anything?*/ selectedValue,
-						/*Object?*/ fetchArgs){
-		// summary:
-		//		Sets the store you would like to use with this select widget.
-		//		The selected value is the value of the new store to set.  This
-		//		function returns the original store, in case you want to reuse
-		//		it or something.
-		// store: dojo.data.api.Identity
-		//		The store you would like to use - it MUST implement dojo.data.api.Identity,
-		//		and MAY implement dojo.data.api.Notification.
-		// selectedValue: anything?
-		//		The value that this widget should set itself to *after* the store
-		//		has been loaded
-		// fetchArgs: Object?
-		//		The arguments that will be passed to the store's fetch() function
-		var oStore = this.store;
-		fetchArgs = fetchArgs || {};
-		if(oStore !== store){
-			// Our store has changed, so update our notifications
-			var h;
-			while(h = this._notifyConnections.pop()){ h.remove(); }
+			// Cancel listener for updates to old store
+			if(this._queryRes && this._queryRes.close){
+				this._queryRes.close();
+			}
 
-			if(store && store.getFeatures()["dojo.data.api.Notification"]){
-				this._notifyConnections = [
-					aspect.after(store, "onNew", lang.hitch(this, "_onNewItem"), true),
-					aspect.after(store, "onDelete", lang.hitch(this, "_onDeleteItem"), true),
-					aspect.after(store, "onSet", lang.hitch(this, "_onSetItem"), true)
-				];
+			// If user has specified new query and query options along with this new store, then use them.
+			if(fetchArgs.query){
+				this._set("query", fetchArgs.query);
+				this._set("queryOptions", fetchArgs.queryOptions);
 			}
-			this._set("store", store);
-		}
 
-		// Turn off change notifications while we make all these changes
-		this._onChangeActive = false;
+			// Add our new options
+			if(store){
+				this._loadingStore = true;
+				this.onLoadDeferred = new Deferred();
 
-		// Remove existing options (if there are any)
-		if(this.options && this.options.length){
-			this.removeOption(this.options);
-		}
+				// Run query
+				// Save result in this._queryRes so we can cancel the listeners we register below
+				this._queryRes = store.query(this.query, this.queryOptions);
+				when(this._queryRes, lang.hitch(this, function(items){
 
-		// Add our new options
-		if(store){
-			this._loadingStore = true;
-			store.fetch(lang.delegate(fetchArgs, {
-				onComplete: function(items, opts){
 					if(this.sortByLabel && !fetchArgs.sort && items.length){
-						items.sort(sorter.createSortFunction([{
-							attribute: store.getLabelAttributes(items[0])[0]
-						}], store));
+						if(store.getValue){
+							// Old dojo.data API to access items, remove for 2.0
+							items.sort(sorter.createSortFunction([
+								{
+									attribute: store.getLabelAttributes(items[0])[0]
+								}
+							], store));
+						}else{
+							// TODO: remove sortByLabel completely for 2.0?  It can be handled by queryOptions: {sort: ... }.
+							var labelAttr = this.labelAttr;
+							items.sort(function(a, b){
+								return a[labelAttr] > b[labelAttr] ? 1 : b[labelAttr] > a[labelAttr] ? -1 : 0;
+							});
+						}
 					}
 
 					if(fetchArgs.onFetch){
-							items = fetchArgs.onFetch.call(this, items, opts);
+						items = fetchArgs.onFetch.call(this, items, fetchArgs);
 					}
+
 					// TODO: Add these guys as a batch, instead of separately
 					array.forEach(items, function(i){
 						this._addOptionForItem(i);
 					}, this);
 
+					// Register listener for store updates
+					if(this._queryRes.observe){
+						this._queryRes.observe(lang.hitch(this, function(object, deletedFrom, insertedInto){
+							if(deletedFrom == insertedInto){
+								this._onSetItem(object);
+							}else{
+								if(deletedFrom != -1){
+									this._onDeleteItem(object);
+								}
+								if(insertedInto != -1){
+									this._onNewItem(object);
+								}
+							}
+						}), true);
+					}
+
 					// Set our value (which might be undefined), and then tweak
 					// it to send a change event with the real value
 					this._loadingStore = false;
-						this.set("value", "_pendingValue" in this ? this._pendingValue : selectedValue);
+					this.set("value", "_pendingValue" in this ? this._pendingValue : selectedValue);
 					delete this._pendingValue;
 
 					if(!this.loadChildrenOnOpen){
@@ -279,317 +377,353 @@ return declare("dijit.form._FormSelectWidget", _FormValueWidget, {
 					}else{
 						this._pseudoLoadChildren(items);
 					}
-					this._fetchedWith = opts;
-					this._lastValueReported = this.multiple ? [] : null;
-					this._onChangeActive = true;
+					this.onLoadDeferred.resolve(true);
 					this.onSetStore();
-					this._handleOnChange(this.value);
-				},
-				scope: this
-			}));
-		}else{
-			delete this._fetchedWith;
-		}
-		return oStore;	// dojo.data.api.Identity
-	},
-
-	// TODO: implement set() and watch() for store and query, although not sure how to handle
-	// setting them individually rather than together (as in setStore() above)
-
-	_setValueAttr: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
-		// summary:
-		//		set the value of the widget.
-		//		If a string is passed, then we set our value from looking it up.
-		if(this._loadingStore){
-			// Our store is loading - so save our value, and we'll set it when
-			// we're done
-			this._pendingValue = newValue;
-			return;
-		}
-		var opts = this.getOptions() || [];
-		if(!lang.isArray(newValue)){
-			newValue = [newValue];
-		}
-		array.forEach(newValue, function(i, idx){
-			if(!lang.isObject(i)){
-				i = i + "";
+				}), function(err){
+					console.error('dijit.form.Select: ' + err.toString());
+					this.onLoadDeferred.reject(err);
+				});
 			}
-			if(typeof i === "string"){
-				newValue[idx] = array.filter(opts, function(node){
-					return node.value === i;
-				})[0] || {value: "", label: ""};
+			return oStore;	// dojo/data/api/Identity
+		},
+
+		// TODO: implement set() and watch() for store and query, although not sure how to handle
+		// setting them individually rather than together (as in setStore() above)
+
+		_setValueAttr: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
+			// summary:
+			//		set the value of the widget.
+			//		If a string is passed, then we set our value from looking it up.
+			if(!this._onChangeActive){
+				priorityChange = null;
 			}
-		}, this);
-
-		// Make sure some sane default is set
-		newValue = array.filter(newValue, function(i){ return i && i.value; });
-		if(!this.multiple && (!newValue[0] || !newValue[0].value) && opts.length){
-			newValue[0] = opts[0];
-		}
-		array.forEach(opts, function(i){
-			i.selected = array.some(newValue, function(v){ return v.value === i.value; });
-		});
-		var val = array.map(newValue, function(i){ return i.value; }),
-			disp = array.map(newValue, function(i){ return i.label; });
-
-		this._set("value", this.multiple ? val : val[0]);
-		this._setDisplay(this.multiple ? disp : disp[0]);
-		this._updateSelection();
-		this._handleOnChange(this.value, priorityChange);
-	},
-
-	_getDisplayedValueAttr: function(){
-		// summary:
-		//		returns the displayed value of the widget
-		var val = this.get("value");
-		if(!lang.isArray(val)){
-			val = [val];
-		}
-		var ret = array.map(this.getOptions(val), function(v){
-			if(v && "label" in v){
-				return v.label;
-			}else if(v){
-				return v.value;
+			if(this._loadingStore){
+				// Our store is loading - so save our value, and we'll set it when
+				// we're done
+				this._pendingValue = newValue;
+				return;
 			}
-			return null;
-		}, this);
-		return this.multiple ? ret : ret[0];
-	},
-
-	_loadChildren: function(){
-		// summary:
-		//		Loads the children represented by this widget's options.
-		//		reset the menu to make it populatable on the next click
-		if(this._loadingStore){ return; }
-		array.forEach(this._getChildren(), function(child){
-			child.destroyRecursive();
-		});
-		// Add each menu item
-		array.forEach(this.options, this._addOptionItem, this);
-
-		// Update states
-		this._updateSelection();
-	},
-
-	_updateSelection: function(){
-		// summary:
-		//		Sets the "selected" class on the item for styling purposes
-		this._set("value", this._getValueFromOpts());
-		var val = this.value;
-		if(!lang.isArray(val)){
-			val = [val];
-		}
-		if(val && val[0]){
-			array.forEach(this._getChildren(), function(child){
-				var isSelected = array.some(val, function(v){
-					return child.option && (v === child.option.value);
+			if(newValue == null){
+				return;
+			}
+			if(lang.isArray(newValue)){
+				newValue = array.map(newValue, function(value){
+					return lang.isObject(value) ? value : { value: value };
+				}); // __SelectOption[]
+			}else if(lang.isObject(newValue)){
+				newValue = [newValue];
+			}else{
+				newValue = [
+					{ value: newValue }
+				];
+			}
+			newValue = array.filter(this.getOptions(newValue), function(i){
+				return i && i.value;
+			});
+			var opts = this.getOptions() || [];
+			if(!this.multiple && (!newValue[0] || !newValue[0].value) && !!opts.length){
+				newValue[0] = opts[0];
+			}
+			array.forEach(opts, function(opt){
+				opt.selected = array.some(newValue, function(v){
+					return v.value === opt.value;
 				});
-				domClass.toggle(child.domNode, this.baseClass + "SelectedOption", isSelected);
-				child.domNode.setAttribute("aria-selected", isSelected);
+			});
+			var val = array.map(newValue, function(opt){
+				return opt.value;
+			});
+
+			if(typeof val == "undefined" || typeof val[0] == "undefined"){
+				return;
+			} // not fully initialized yet or a failed value lookup
+			var disp = array.map(newValue, function(opt){
+				return opt.label;
+			});
+			this._setDisplay(this.multiple ? disp : disp[0]);
+			this.inherited(arguments, [ this.multiple ? val : val[0], priorityChange ]);
+			this._updateSelection();
+		},
+
+		_getDisplayedValueAttr: function(){
+			// summary:
+			//		returns the displayed value of the widget
+			var ret = array.map([].concat(this.get('selectedOptions')), function(v){
+				if(v && "label" in v){
+					return v.label;
+				}else if(v){
+					return v.value;
+				}
+				return null;
 			}, this);
-		}
-	},
-
-	_getValueFromOpts: function(){
-		// summary:
-		//		Returns the value of the widget by reading the options for
-		//		the selected flag
-		var opts = this.getOptions() || [];
-		if(!this.multiple && opts.length){
-			// Mirror what a select does - choose the first one
-			var opt = array.filter(opts, function(i){
-				return i.selected;
-			})[0];
-			if(opt && opt.value){
-				return opt.value
-			}else{
-				opts[0].selected = true;
-				return opts[0].value;
+			return this.multiple ? ret : ret[0];
+		},
+
+		_setDisplayedValueAttr: function(label){
+			// summary:
+			//		Sets the displayed value of the widget
+			this.set('value', this.getOptions(typeof label == "string" ? { label: label } : label));
+		},
+
+		_loadChildren: function(){
+			// summary:
+			//		Loads the children represented by this widget's options.
+			//		reset the menu to make it populatable on the next click
+			if(this._loadingStore){
+				return;
 			}
-		}else if(this.multiple){
-			// Set value to be the sum of all selected
-			return array.map(array.filter(opts, function(i){
-				return i.selected;
-			}), function(i){
-				return i.value;
-			}) || [];
-		}
-		return "";
-	},
-
-	// Internal functions to call when we have store notifications come in
-	_onNewItem: function(/*item*/ item, /*Object?*/ parentInfo){
-		if(!parentInfo || !parentInfo.parent){
-			// Only add it if we are top-level
-			this._addOptionForItem(item);
-		}
-	},
-	_onDeleteItem: function(/*item*/ item){
-		var store = this.store;
-		this.removeOption(store.getIdentity(item));
-	},
-	_onSetItem: function(/*item*/ item){
-		this.updateOption(this._getOptionObjForItem(item));
-	},
-
-	_getOptionObjForItem: function(item){
-		// summary:
-		//		Returns an option object based off the given item.  The "value"
-		//		of the option item will be the identity of the item, the "label"
-		//		of the option will be the label of the item.  If the item contains
-		//		children, the children value of the item will be set
-		var store = this.store, label = store.getLabel(item),
-			value = (label ? store.getIdentity(item) : null);
-		return {value: value, label: label, item:item}; // dijit.form.__SelectOption
-	},
-
-	_addOptionForItem: function(/*item*/ item){
-		// summary:
-		//		Creates (and adds) the option for the given item
-		var store = this.store;
-		if(!store.isItemLoaded(item)){
-			// We are not loaded - so let's load it and add later
-			store.loadItem({item: item, onItem: function(i){
-				this._addOptionForItem(i);
-			},
-			scope: this});
-			return;
-		}
-		var newOpt = this._getOptionObjForItem(item);
-		this.addOption(newOpt);
-	},
-
-	constructor: function(/*Object*/ keywordArgs){
-		// summary:
-		//		Saves off our value, if we have an initial one set so we
-		//		can use it if we have a store as well (see startup())
-		this._oValue = (keywordArgs || {}).value || null;
-		this._notifyConnections = [];
-	},
-
-	buildRendering: function(){
-		this.inherited(arguments);
-		dom.setSelectable(this.focusNode, false);
-	},
-
-	_fillContent: function(){
-		// summary:
-		//		Loads our options and sets up our dropdown correctly.  We
-		//		don't want any content, so we don't call any inherit chain
-		//		function.
-		var opts = this.options;
-		if(!opts){
-			opts = this.options = this.srcNodeRef ? query("> *",
-						this.srcNodeRef).map(function(node){
+			array.forEach(this._getChildren(), function(child){
+				child.destroyRecursive();
+			});
+			// Add each menu item
+			array.forEach(this.options, this._addOptionItem, this);
+
+			// Update states
+			this._updateSelection();
+		},
+
+		_updateSelection: function(){
+			// summary:
+			//		Sets the "selected" class on the item for styling purposes
+			this.focusedChild = null;
+			this._set("value", this._getValueFromOpts());
+			var val = [].concat(this.value);
+			if(val && val[0]){
+				var self = this;
+				array.forEach(this._getChildren(), function(child){
+					var isSelected = array.some(val, function(v){
+						return child.option && (v === child.option.value);
+					});
+					if(isSelected && !self.multiple){
+						self.focusedChild = child;
+					}
+					domClass.toggle(child.domNode, this.baseClass.replace(/\s+|$/g, "SelectedOption "), isSelected);
+					child.domNode.setAttribute("aria-selected", isSelected ? "true" : "false");
+				}, this);
+			}
+		},
+
+		_getValueFromOpts: function(){
+			// summary:
+			//		Returns the value of the widget by reading the options for
+			//		the selected flag
+			var opts = this.getOptions() || [];
+			if(!this.multiple && opts.length){
+				// Mirror what a select does - choose the first one
+				var opt = array.filter(opts, function(i){
+					return i.selected;
+				})[0];
+				if(opt && opt.value){
+					return opt.value;
+				}else{
+					opts[0].selected = true;
+					return opts[0].value;
+				}
+			}else if(this.multiple){
+				// Set value to be the sum of all selected
+				return array.map(array.filter(opts, function(i){
+					return i.selected;
+				}), function(i){
+					return i.value;
+				}) || [];
+			}
+			return "";
+		},
+
+		// Internal functions to call when we have store notifications come in
+		_onNewItem: function(/*item*/ item, /*Object?*/ parentInfo){
+			if(!parentInfo || !parentInfo.parent){
+				// Only add it if we are top-level
+				this._addOptionForItem(item);
+			}
+		},
+		_onDeleteItem: function(/*item*/ item){
+			var store = this.store;
+			this.removeOption({value: store.getIdentity(item) });
+		},
+		_onSetItem: function(/*item*/ item){
+			this.updateOption(this._getOptionObjForItem(item));
+		},
+
+		_getOptionObjForItem: function(item){
+			// summary:
+			//		Returns an option object based off the given item.  The "value"
+			//		of the option item will be the identity of the item, the "label"
+			//		of the option will be the label of the item.
+
+			// remove getLabel() call for 2.0 (it's to support the old dojo.data API)
+			var store = this.store,
+				label = (this.labelAttr && this.labelAttr in item) ? item[this.labelAttr] : store.getLabel(item),
+				value = (label ? store.getIdentity(item) : null);
+			return {value: value, label: label, item: item}; // __SelectOption
+		},
+
+		_addOptionForItem: function(/*item*/ item){
+			// summary:
+			//		Creates (and adds) the option for the given item
+			var store = this.store;
+			if(store.isItemLoaded && !store.isItemLoaded(item)){
+				// We are not loaded - so let's load it and add later.
+				// Remove for 2.0 (it's the old dojo.data API)
+				store.loadItem({item: item, onItem: function(i){
+					this._addOptionForItem(i);
+				},
+					scope: this});
+				return;
+			}
+			var newOpt = this._getOptionObjForItem(item);
+			this.addOption(newOpt);
+		},
+
+		constructor: function(params /*===== , srcNodeRef =====*/){
+			// summary:
+			//		Create the widget.
+			// params: Object|null
+			//		Hash of initialization parameters for widget, including scalar values (like title, duration etc.)
+			//		and functions, typically callbacks like onClick.
+			//		The hash can contain any of the widget's properties, excluding read-only properties.
+			// srcNodeRef: DOMNode|String?
+			//		If a srcNodeRef (DOM node) is specified, replace srcNodeRef with my generated DOM tree
+
+			//		Saves off our value, if we have an initial one set so we
+			//		can use it if we have a store as well (see startup())
+			this._oValue = (params || {}).value || null;
+			this._notifyConnections = [];	// remove for 2.0
+		},
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			dom.setSelectable(this.focusNode, false);
+		},
+
+		_fillContent: function(){
+			// summary:
+			//		Loads our options and sets up our dropdown correctly.  We
+			//		don't want any content, so we don't call any inherit chain
+			//		function.
+			if(!this.options){
+				this.options =
+					this.srcNodeRef
+						? query("> *", this.srcNodeRef).map(
+						function(node){
 							if(node.getAttribute("type") === "separator"){
 								return { value: "", label: "", selected: false, disabled: false };
 							}
 							return {
 								value: (node.getAttribute("data-" + kernel._scopeName + "-value") || node.getAttribute("value")),
-										label: String(node.innerHTML),
+								label: String(node.innerHTML),
 								// FIXME: disabled and selected are not valid on complex markup children (which is why we're
 								// looking for data-dojo-value above.  perhaps we should data-dojo-props="" this whole thing?)
 								// decide before 1.6
-										selected: node.getAttribute("selected") || false,
+								selected: node.getAttribute("selected") || false,
 								disabled: node.getAttribute("disabled") || false
 							};
-						}, this) : [];
-		}
-		if(!this.value){
-			this._set("value", this._getValueFromOpts());
-		}else if(this.multiple && typeof this.value == "string"){
-			this._set("value", this.value.split(","));
-		}
-	},
-
-	postCreate: function(){
-		// summary:
-		//		sets up our event handling that we need for functioning
-		//		as a select
-		this.inherited(arguments);
-
-		// Make our event connections for updating state
-		this.connect(this, "onChange", "_updateSelection");
-		this.connect(this, "startup", "_loadChildren");
-
-		this._setValueAttr(this.value, null);
-	},
-
-	startup: function(){
-		// summary:
-		//		Connects in our store, if we have one defined
-		this.inherited(arguments);
-		var store = this.store, fetchArgs = {};
-		array.forEach(["query", "queryOptions", "onFetch"], function(i){
-			if(this[i]){
-				fetchArgs[i] = this[i];
+						},
+						this)
+						: [];
 			}
-			delete this[i];
-		}, this);
-		if(store && store.getFeatures()["dojo.data.api.Identity"]){
-			// Temporarily set our store to null so that it will get set
-			// and connected appropriately
-			this.store = null;
-			this.setStore(store, this._oValue, fetchArgs);
-		}
-	},
-
-	destroy: function(){
-		// summary:
-		//		Clean up our connections
-		var h;
-		while(h = this._notifyConnections.pop()){ h.remove(); }
-		this.inherited(arguments);
-	},
-
-	_addOptionItem: function(/*dijit.form.__SelectOption*/ /*===== option =====*/){
-		// summary:
-		//		User-overridable function which, for the given option, adds an
-		//		item to the select.  If the option doesn't have a value, then a
-		//		separator is added in that place.  Make sure to store the option
-		//		in the created option widget.
-	},
+			if(!this.value){
+				this._set("value", this._getValueFromOpts());
+			}else if(this.multiple && typeof this.value == "string"){
+				this._set("value", this.value.split(","));
+			}
+		},
+
+		postCreate: function(){
+			// summary:
+			//		sets up our event handling that we need for functioning
+			//		as a select
+			this.inherited(arguments);
+
+			// Make our event connections for updating state
+			aspect.after(this, "onChange", lang.hitch(this, "_updateSelection"));
+
+			// moved from startup
+			//		Connects in our store, if we have one defined
+			var store = this.store;
+			if(store && (store.getIdentity || store.getFeatures()["dojo.data.api.Identity"])){
+				// Temporarily set our store to null so that it will get set
+				// and connected appropriately
+				this.store = null;
+				this.setStore(store, this._oValue);
+			}
+		},
 
-	_removeOptionItem: function(/*dijit.form.__SelectOption*/ /*===== option =====*/){
-		// summary:
-		//		User-overridable function which, for the given option, removes
-		//		its item from the select.
-	},
+		startup: function(){
+			// summary:
+			this._loadChildren();
+			this.inherited(arguments);
+		},
 
-	_setDisplay: function(/*String or String[]*/ /*===== newDisplay =====*/){
-		// summary:
-		//		Overridable function which will set the display for the
-		//		widget.  newDisplay is either a string (in the case of
-		//		single selects) or array of strings (in the case of multi-selects)
-	},
+		destroy: function(){
+			// summary:
+			//		Clean up our connections
 
-	_getChildren: function(){
-		// summary:
-		//		Overridable function to return the children that this widget contains.
-		return [];
-	},
+			var h;
+			while((h = this._notifyConnections.pop())){
+				h.remove();
+			}
 
-	_getSelectedOptionsAttr: function(){
-		// summary:
-		//		hooks into this.attr to provide a mechanism for getting the
-		//		option items for the current value of the widget.
-		return this.getOptions(this.get("value"));
-	},
+			// Cancel listener for store updates
+			if(this._queryRes && this._queryRes.close){
+				this._queryRes.close();
+			}
 
-	_pseudoLoadChildren: function(/*item[]*/ /*===== items =====*/){
-		// summary:
-		//		a function that will "fake" loading children, if needed, and
-		//		if we have set to not load children until the widget opens.
-		// items:
-		//		An array of items that will be loaded, when needed
-	},
+			this.inherited(arguments);
+		},
+
+		_addOptionItem: function(/*__SelectOption*/ /*===== option =====*/){
+			// summary:
+			//		User-overridable function which, for the given option, adds an
+			//		item to the select.  If the option doesn't have a value, then a
+			//		separator is added in that place.  Make sure to store the option
+			//		in the created option widget.
+		},
+
+		_removeOptionItem: function(/*__SelectOption*/ /*===== option =====*/){
+			// summary:
+			//		User-overridable function which, for the given option, removes
+			//		its item from the select.
+		},
+
+		_setDisplay: function(/*String or String[]*/ /*===== newDisplay =====*/){
+			// summary:
+			//		Overridable function which will set the display for the
+			//		widget.  newDisplay is either a string (in the case of
+			//		single selects) or array of strings (in the case of multi-selects)
+		},
+
+		_getChildren: function(){
+			// summary:
+			//		Overridable function to return the children that this widget contains.
+			return [];
+		},
+
+		_getSelectedOptionsAttr: function(){
+			// summary:
+			//		hooks into this.attr to provide a mechanism for getting the
+			//		option items for the current value of the widget.
+			return this.getOptions({ selected: true });
+		},
+
+		_pseudoLoadChildren: function(/*item[]*/ /*===== items =====*/){
+			// summary:
+			//		a function that will "fake" loading children, if needed, and
+			//		if we have set to not load children until the widget opens.
+			// items:
+			//		An array of items that will be loaded, when needed
+		},
+
+		onSetStore: function(){
+			// summary:
+			//		a function that can be connected to in order to receive a
+			//		notification that the store has finished loading and all options
+			//		from that store are available
+		}
+	});
 
-	onSetStore: function(){
-		// summary:
-		//		a function that can be connected to in order to receive a
-		//		notification that the store has finished loading and all options
-		//		from that store are available
-	}
-});
+	/*=====
+	_FormSelectWidget.__SelectOption = __SelectOption;
+	=====*/
 
+	return _FormSelectWidget;
 });
diff --git a/dijit/form/_FormValueMixin.js b/dijit/form/_FormValueMixin.js
index f04ea90..c2fc650 100644
--- a/dijit/form/_FormValueMixin.js
+++ b/dijit/form/_FormValueMixin.js
@@ -2,24 +2,21 @@ define([
 	"dojo/_base/declare", // declare
 	"dojo/dom-attr", // domAttr.set
 	"dojo/keys", // keys.ESCAPE
-	"dojo/_base/sniff", // has("ie"), has("quirks")
+	"dojo/_base/lang",
+	"dojo/on",
+	"dojo/sniff", // has("ie"), has("quirks")
 	"./_FormWidgetMixin"
-], function(declare, domAttr, keys, has, _FormWidgetMixin){
-
-/*=====
-	var _FormWidgetMixin = dijit.form._FormWidgetMixin;
-=====*/
+], function(declare, domAttr, keys, lang, on, has, _FormWidgetMixin){
 
 	// module:
 	//		dijit/form/_FormValueMixin
-	// summary:
-	//		Mixin for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.
 
 	return declare("dijit.form._FormValueMixin", _FormWidgetMixin, {
 		// summary:
-		//		Mixin for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.
+		//		Mixin for widgets corresponding to native HTML elements such as `<input>` or `<select>`
+		//		that have user changeable values.
 		// description:
-		//		Each _FormValueMixin represents a single input value, and has a (possibly hidden) <input> element,
+		//		Each _FormValueMixin represents a single input value, and has a (possibly hidden) `<input>` element,
 		//		to which it serializes it's input value, so that form submission (either normal submission or via FormBind?)
 		//		works as expected.
 
@@ -31,16 +28,12 @@ define([
 
 		_setReadOnlyAttr: function(/*Boolean*/ value){
 			domAttr.set(this.focusNode, 'readOnly', value);
-			this.focusNode.setAttribute("aria-readonly", value);
 			this._set("readOnly", value);
 		},
 
 		postCreate: function(){
 			this.inherited(arguments);
 
-			if(has("ie")){ // IE won't stop the event with keypress
-				this.connect(this.focusNode || this.domNode, "onkeydown", this._onKeyDown);
-			}
 			// Update our reset value if it hasn't yet been set (because this.set()
 			// is only called when there *is* a value)
 			if(this._resetValue === undefined){
@@ -77,19 +70,6 @@ define([
 			//		Reset the widget's value to what it was at initialization time
 			this._hasBeenBlurred = false;
 			this._setValueAttr(this._resetValue, true);
-		},
-
-		_onKeyDown: function(e){
-			if(e.keyCode == keys.ESCAPE && !(e.ctrlKey || e.altKey || e.metaKey)){
-				var te;
-				if(has("ie") < 9 || (has("ie") && has("quirks"))){
-					e.preventDefault(); // default behavior needs to be stopped here since keypress is too late
-					te = document.createEventObject();
-					te.keyCode = keys.ESCAPE;
-					te.shiftKey = e.shiftKey;
-					e.srcElement.fireEvent('onkeypress', te);
-				}
-			}
 		}
 	});
 });
diff --git a/dijit/form/_FormValueWidget.js b/dijit/form/_FormValueWidget.js
index 02b2810..55df51d 100644
--- a/dijit/form/_FormValueWidget.js
+++ b/dijit/form/_FormValueWidget.js
@@ -1,58 +1,51 @@
 define([
 	"dojo/_base/declare", // declare
-	"dojo/_base/sniff", // has("ie")
+	"dojo/sniff", // has("ie")
 	"./_FormWidget",
 	"./_FormValueMixin"
 ], function(declare, has, _FormWidget, _FormValueMixin){
 
-/*=====
-var _FormWidget = dijit.form._FormWidget;
-var _FormValueMixin = dijit.form._FormValueMixin;
-=====*/
+	// module:
+	//		dijit/form/_FormValueWidget
 
-// module:
-//		dijit/form/_FormValueWidget
-// summary:
-//		FormValueWidget
-
-
-return declare("dijit.form._FormValueWidget", [_FormWidget, _FormValueMixin],
-{
-	// summary:
-	//		Base class for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.
-	// description:
-	//		Each _FormValueWidget represents a single input value, and has a (possibly hidden) <input> element,
-	//		to which it serializes it's input value, so that form submission (either normal submission or via FormBind?)
-	//		works as expected.
-
-	// Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared
-	// directly in the template as read by the parser in order to function. IE is known to specifically
-	// require the 'name' attribute at element creation time.  See #8484, #8660.
-
-	_layoutHackIE7: function(){
+	return declare("dijit.form._FormValueWidget", [_FormWidget, _FormValueMixin], {
 		// summary:
-		//		Work around table sizing bugs on IE7 by forcing redraw
-
-		if(has("ie") == 7){ // fix IE7 layout bug when the widget is scrolled out of sight
-			var domNode = this.domNode;
-			var parent = domNode.parentNode;
-			var pingNode = domNode.firstChild || domNode; // target node most unlikely to have a custom filter
-			var origFilter = pingNode.style.filter; // save custom filter, most likely nothing
-			var _this = this;
-			while(parent && parent.clientHeight == 0){ // search for parents that haven't rendered yet
-				(function ping(){
-					var disconnectHandle = _this.connect(parent, "onscroll",
-						function(){
-							_this.disconnect(disconnectHandle); // only call once
-							pingNode.style.filter = (new Date()).getMilliseconds(); // set to anything that's unique
-							setTimeout(function(){ pingNode.style.filter = origFilter }, 0); // restore custom filter, if any
-						}
-					);
-				})();
-				parent = parent.parentNode;
+		//		Base class for widgets corresponding to native HTML elements such as `<input>` or `<select>`
+		//		that have user changeable values.
+		// description:
+		//		Each _FormValueWidget represents a single input value, and has a (possibly hidden) `<input>` element,
+		//		to which it serializes it's input value, so that form submission (either normal submission or via FormBind?)
+		//		works as expected.
+
+		// Don't attempt to mixin the 'type', 'name' attributes here programatically -- they must be declared
+		// directly in the template as read by the parser in order to function. IE is known to specifically
+		// require the 'name' attribute at element creation time.  See #8484, #8660.
+
+		_layoutHackIE7: function(){
+			// summary:
+			//		Work around table sizing bugs on IE7 by forcing redraw
+
+			if(has("ie") == 7){ // fix IE7 layout bug when the widget is scrolled out of sight
+				var domNode = this.domNode;
+				var parent = domNode.parentNode;
+				var pingNode = domNode.firstChild || domNode; // target node most unlikely to have a custom filter
+				var origFilter = pingNode.style.filter; // save custom filter, most likely nothing
+				var _this = this;
+				while(parent && parent.clientHeight == 0){ // search for parents that haven't rendered yet
+					(function ping(){
+						var disconnectHandle = _this.connect(parent, "onscroll",
+							function(){
+								_this.disconnect(disconnectHandle); // only call once
+								pingNode.style.filter = (new Date()).getMilliseconds(); // set to anything that's unique
+								_this.defer(function(){
+									pingNode.style.filter = origFilter;
+								}); // restore custom filter, if any
+							}
+						);
+					})();
+					parent = parent.parentNode;
+				}
 			}
 		}
-	}
-});
-
+	});
 });
diff --git a/dijit/form/_FormWidget.js b/dijit/form/_FormWidget.js
index bdb3118..a9f8e3d 100644
--- a/dijit/form/_FormWidget.js
+++ b/dijit/form/_FormWidget.js
@@ -1,79 +1,71 @@
 define([
-	"dojo/_base/declare",	// declare
+	"dojo/_base/declare", // declare
+	"dojo/sniff", // has("dijit-legacy-requires"), has("msapp")
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/ready",
 	"../_Widget",
 	"../_CssStateMixin",
 	"../_TemplatedMixin",
 	"./_FormWidgetMixin"
-], function(declare, kernel, ready, _Widget, _CssStateMixin, _TemplatedMixin, _FormWidgetMixin){
+], function(declare, has, kernel, ready, _Widget, _CssStateMixin, _TemplatedMixin, _FormWidgetMixin){
 
-/*=====
-var _Widget = dijit._Widget;
-var _TemplatedMixin = dijit._TemplatedMixin;
-var _CssStateMixin = dijit._CssStateMixin;
-var _FormWidgetMixin = dijit.form._FormWidgetMixin;
-=====*/
+	// module:
+	//		dijit/form/_FormWidget
 
-// module:
-//		dijit/form/_FormWidget
-// summary:
-//		FormWidget
+	// Back compat w/1.6, remove for 2.0
+	if(has("dijit-legacy-requires")){
+		ready(0, function(){
+			var requires = ["dijit/form/_FormValueWidget"];
+			require(requires);	// use indirection so modules not rolled into a build
+		});
+	}
 
-
-// Back compat w/1.6, remove for 2.0
-if(!kernel.isAsync){
-	ready(0, function(){
-		var requires = ["dijit/form/_FormValueWidget"];
-		require(requires);	// use indirection so modules not rolled into a build
-	});
-}
-
-return declare("dijit.form._FormWidget", [_Widget, _TemplatedMixin, _CssStateMixin, _FormWidgetMixin], {
-	// summary:
-	//		Base class for widgets corresponding to native HTML elements such as <checkbox> or <button>,
-	//		which can be children of a <form> node or a `dijit.form.Form` widget.
-	//
-	// description:
-	//		Represents a single HTML element.
-	//		All these widgets should have these attributes just like native HTML input elements.
-	//		You can set them during widget construction or afterwards, via `dijit._Widget.attr`.
-	//
-	//		They also share some common methods.
-
-	setDisabled: function(/*Boolean*/ disabled){
+	return declare("dijit.form._FormWidget", [_Widget, _TemplatedMixin, _CssStateMixin, _FormWidgetMixin], {
 		// summary:
-		//		Deprecated.  Use set('disabled', ...) instead.
-		kernel.deprecated("setDisabled("+disabled+") is deprecated. Use set('disabled',"+disabled+") instead.", "", "2.0");
-		this.set('disabled', disabled);
-	},
+		//		Base class for widgets corresponding to native HTML elements such as `<checkbox>` or `<button>`,
+		//		which can be children of a `<form>` node or a `dijit/form/Form` widget.
+		//
+		// description:
+		//		Represents a single HTML element.
+		//		All these widgets should have these attributes just like native HTML input elements.
+		//		You can set them during widget construction or afterwards, via `dijit/_WidgetBase.set()`.
+		//
+		//		They also share some common methods.
 
-	setValue: function(/*String*/ value){
-		// summary:
-		//		Deprecated.  Use set('value', ...) instead.
-		kernel.deprecated("dijit.form._FormWidget:setValue("+value+") is deprecated.  Use set('value',"+value+") instead.", "", "2.0");
-		this.set('value', value);
-	},
+		setDisabled: function(/*Boolean*/ disabled){
+			// summary:
+			//		Deprecated.  Use set('disabled', ...) instead.
+			kernel.deprecated("setDisabled(" + disabled + ") is deprecated. Use set('disabled'," + disabled + ") instead.", "", "2.0");
+			this.set('disabled', disabled);
+		},
 
-	getValue: function(){
-		// summary:
-		//		Deprecated.  Use get('value') instead.
-		kernel.deprecated(this.declaredClass+"::getValue() is deprecated. Use get('value') instead.", "", "2.0");
-		return this.get('value');
-	},
+		setValue: function(/*String*/ value){
+			// summary:
+			//		Deprecated.  Use set('value', ...) instead.
+			kernel.deprecated("dijit.form._FormWidget:setValue(" + value + ") is deprecated.  Use set('value'," + value + ") instead.", "", "2.0");
+			this.set('value', value);
+		},
 
-	postMixInProperties: function(){
-		// Setup name=foo string to be referenced from the template (but only if a name has been specified)
-		// Unfortunately we can't use _setNameAttr to set the name due to IE limitations, see #8484, #8660.
-		// Regarding escaping, see heading "Attribute values" in
-		// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
-		this.nameAttrSetting = this.name ? ('name="' + this.name.replace(/'/g, """) + '"') : '';
-		this.inherited(arguments);
-	},
+		getValue: function(){
+			// summary:
+			//		Deprecated.  Use get('value') instead.
+			kernel.deprecated(this.declaredClass + "::getValue() is deprecated. Use get('value') instead.", "", "2.0");
+			return this.get('value');
+		},
 
-	// Override automatic assigning type --> focusNode, it causes exception on IE.
-	// Instead, type must be specified as ${type} in the template, as part of the original DOM
-	_setTypeAttr: null
-});
+		postMixInProperties: function(){
+			// Setup name=foo string to be referenced from the template (but only if a name has been specified).
+			// Unfortunately we can't use _setNameAttr to set the name in IE due to IE limitations, see #8484, #8660.
+			// But when IE6 and IE7 are desupported, then we probably don't need this anymore, so should remove it in 2.0.
+			// Also, don't do this for Windows 8 Store Apps because it causes a security exception (see #16452).
+			// Regarding escaping, see heading "Attribute values" in
+			// http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2
+			this.nameAttrSetting = (this.name && !has("msapp")) ? ('name="' + this.name.replace(/"/g, """) + '"') : '';
+			this.inherited(arguments);
+		},
 
+		// Override automatic assigning type --> focusNode, it causes exception on IE.
+		// Instead, type must be specified as ${type} in the template, as part of the original DOM
+		_setTypeAttr: null
+	});
 });
diff --git a/dijit/form/_FormWidgetMixin.js b/dijit/form/_FormWidgetMixin.js
index 8d8198d..ff284fb 100644
--- a/dijit/form/_FormWidgetMixin.js
+++ b/dijit/form/_FormWidgetMixin.js
@@ -5,227 +5,234 @@ define([
 	"dojo/dom-style", // domStyle.get
 	"dojo/_base/lang", // lang.hitch lang.isArray
 	"dojo/mouse", // mouse.isLeft
-	"dojo/_base/sniff", // has("webkit")
-	"dojo/_base/window", // win.body
+	"dojo/on",
+	"dojo/sniff", // has("webkit")
 	"dojo/window", // winUtils.scrollIntoView
-	"../a11y"	// a11y.hasDefaultTabStop
-], function(array, declare, domAttr, domStyle, lang, mouse, has, win, winUtils, a11y){
-
-// module:
-//		dijit/form/_FormWidgetMixin
-// summary:
-//		Mixin for widgets corresponding to native HTML elements such as <checkbox> or <button>,
-//		which can be children of a <form> node or a `dijit.form.Form` widget.
-
-return declare("dijit.form._FormWidgetMixin", null, {
-	// summary:
-	//		Mixin for widgets corresponding to native HTML elements such as <checkbox> or <button>,
-	//		which can be children of a <form> node or a `dijit.form.Form` widget.
-	//
-	// description:
-	//		Represents a single HTML element.
-	//		All these widgets should have these attributes just like native HTML input elements.
-	//		You can set them during widget construction or afterwards, via `dijit._Widget.attr`.
-	//
-	//		They also share some common methods.
-
-	// name: [const] String
-	//		Name used when submitting form; same as "name" attribute or plain HTML elements
-	name: "",
-
-	// alt: String
-	//		Corresponds to the native HTML <input> element's attribute.
-	alt: "",
-
-	// value: String
-	//		Corresponds to the native HTML <input> element's attribute.
-	value: "",
-
-	// type: [const] String
-	//		Corresponds to the native HTML <input> element's attribute.
-	type: "text",
-
-	// tabIndex: Integer
-	//		Order fields are traversed when user hits the tab key
-	tabIndex: "0",
-	_setTabIndexAttr: "focusNode",	// force copy even when tabIndex default value, needed since Button is <span>
-
-	// disabled: Boolean
-	//		Should this widget respond to user input?
-	//		In markup, this is specified as "disabled='disabled'", or just "disabled".
-	disabled: false,
-
-	// intermediateChanges: Boolean
-	//		Fires onChange for each value change or only on demand
-	intermediateChanges: false,
-
-	// scrollOnFocus: Boolean
-	//		On focus, should this widget scroll into view?
-	scrollOnFocus: true,
-
-	// Override _WidgetBase mapping id to this.domNode, needs to be on focusNode so <label> etc.
-	// works with screen reader
-	_setIdAttr: "focusNode",
-
-	postCreate: function(){
-		this.inherited(arguments);
-		this.connect(this.domNode, "onmousedown", "_onMouseDown");
-	},
-
-	_setDisabledAttr: function(/*Boolean*/ value){
-		this._set("disabled", value);
-		domAttr.set(this.focusNode, 'disabled', value);
-		if(this.valueNode){
-			domAttr.set(this.valueNode, 'disabled', value);
-		}
-		this.focusNode.setAttribute("aria-disabled", value);
-
-		if(value){
-			// reset these, because after the domNode is disabled, we can no longer receive
-			// mouse related events, see #4200
-			this._set("hovering", false);
-			this._set("active", false);
-
-			// clear tab stop(s) on this widget's focusable node(s)  (ComboBox has two focusable nodes)
-			var attachPointNames = "tabIndex" in this.attributeMap ? this.attributeMap.tabIndex :
-				("_setTabIndexAttr" in this) ? this._setTabIndexAttr : "focusNode";
-			array.forEach(lang.isArray(attachPointNames) ? attachPointNames : [attachPointNames], function(attachPointName){
-				var node = this[attachPointName];
-				// complex code because tabIndex=-1 on a <div> doesn't work on FF
-				if(has("webkit") || a11y.hasDefaultTabStop(node)){	// see #11064 about webkit bug
-					node.setAttribute('tabIndex', "-1");
-				}else{
-					node.removeAttribute('tabIndex');
-				}
-			}, this);
-		}else{
-			if(this.tabIndex != ""){
-				this.set('tabIndex', this.tabIndex);
-			}
-		}
-	},
-
-	_onFocus: function(e){
-		if(this.scrollOnFocus){
-			winUtils.scrollIntoView(this.domNode);
-		}
-		this.inherited(arguments);
-	},
-
-	isFocusable: function(){
-		// summary:
-		//		Tells if this widget is focusable or not.  Used internally by dijit.
-		// tags:
-		//		protected
-		return !this.disabled && this.focusNode && (domStyle.get(this.domNode, "display") != "none");
-	},
+	"../a11y"    // a11y.hasDefaultTabStop
+], function(array, declare, domAttr, domStyle, lang, mouse, on, has, winUtils, a11y){
 
-	focus: function(){
-		// summary:
-		//		Put focus on this widget
-		if(!this.disabled && this.focusNode.focus){
-			try{ this.focusNode.focus(); }catch(e){}/*squelch errors from hidden nodes*/
-		}
-	},
+	// module:
+	//		dijit/form/_FormWidgetMixin
 
-	compare: function(/*anything*/ val1, /*anything*/ val2){
-		// summary:
-		//		Compare 2 values (as returned by get('value') for this widget).
-		// tags:
-		//		protected
-		if(typeof val1 == "number" && typeof val2 == "number"){
-			return (isNaN(val1) && isNaN(val2)) ? 0 : val1 - val2;
-		}else if(val1 > val2){
-			return 1;
-		}else if(val1 < val2){
-			return -1;
-		}else{
-			return 0;
-		}
-	},
-
-	onChange: function(/*===== newValue =====*/){
-		// summary:
-		//		Callback when this widget's value is changed.
-		// tags:
-		//		callback
-	},
-
-	// _onChangeActive: [private] Boolean
-	//		Indicates that changes to the value should call onChange() callback.
-	//		This is false during widget initialization, to avoid calling onChange()
-	//		when the initial value is set.
-	_onChangeActive: false,
-
-	_handleOnChange: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
+	return declare("dijit.form._FormWidgetMixin", null, {
 		// summary:
-		//		Called when the value of the widget is set.  Calls onChange() if appropriate
-		// newValue:
-		//		the new value
-		// priorityChange:
-		//		For a slider, for example, dragging the slider is priorityChange==false,
-		//		but on mouse up, it's priorityChange==true.  If intermediateChanges==false,
-		//		onChange is only called form priorityChange=true events.
-		// tags:
-		//		private
-		if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){
-			// this block executes not for a change, but during initialization,
-			// and is used to store away the original value (or for ToggleButton, the original checked state)
-			this._resetValue = this._lastValueReported = newValue;
-		}
-		this._pendingOnChange = this._pendingOnChange
-			|| (typeof newValue != typeof this._lastValueReported)
-			|| (this.compare(newValue, this._lastValueReported) != 0);
-		if((this.intermediateChanges || priorityChange || priorityChange === undefined) && this._pendingOnChange){
-			this._lastValueReported = newValue;
-			this._pendingOnChange = false;
-			if(this._onChangeActive){
-				if(this._onChangeHandle){
-					clearTimeout(this._onChangeHandle);
+		//		Mixin for widgets corresponding to native HTML elements such as `<checkbox>` or `<button>`,
+		//		which can be children of a `<form>` node or a `dijit/form/Form` widget.
+		//
+		// description:
+		//		Represents a single HTML element.
+		//		All these widgets should have these attributes just like native HTML input elements.
+		//		You can set them during widget construction or afterwards, via `dijit/_WidgetBase.set()`.
+		//
+		//		They also share some common methods.
+
+		// name: [const] String
+		//		Name used when submitting form; same as "name" attribute or plain HTML elements
+		name: "",
+
+		// alt: String
+		//		Corresponds to the native HTML `<input>` element's attribute.
+		alt: "",
+
+		// value: String
+		//		Corresponds to the native HTML `<input>` element's attribute.
+		value: "",
+
+		// type: [const] String
+		//		Corresponds to the native HTML `<input>` element's attribute.
+		type: "text",
+
+		// type: String
+		//		Apply aria-label in markup to the widget's focusNode
+		"aria-label": "focusNode",
+
+		// tabIndex: String
+		//		Order fields are traversed when user hits the tab key
+		tabIndex: "0",
+		_setTabIndexAttr: "focusNode", // force copy even when tabIndex default value, needed since Button is <span>
+
+		// disabled: Boolean
+		//		Should this widget respond to user input?
+		//		In markup, this is specified as "disabled='disabled'", or just "disabled".
+		disabled: false,
+
+		// intermediateChanges: Boolean
+		//		Fires onChange for each value change or only on demand
+		intermediateChanges: false,
+
+		// scrollOnFocus: Boolean
+		//		On focus, should this widget scroll into view?
+		scrollOnFocus: true,
+
+		// Override _WidgetBase mapping id to this.domNode, needs to be on focusNode so <label> etc.
+		// works with screen reader
+		_setIdAttr: "focusNode",
+
+		_setDisabledAttr: function(/*Boolean*/ value){
+			this._set("disabled", value);
+			domAttr.set(this.focusNode, 'disabled', value);
+			if(this.valueNode){
+				domAttr.set(this.valueNode, 'disabled', value);
+			}
+			this.focusNode.setAttribute("aria-disabled", value ? "true" : "false");
+
+			if(value){
+				// reset these, because after the domNode is disabled, we can no longer receive
+				// mouse related events, see #4200
+				this._set("hovering", false);
+				this._set("active", false);
+
+				// clear tab stop(s) on this widget's focusable node(s)  (ComboBox has two focusable nodes)
+				var attachPointNames = "tabIndex" in this.attributeMap ? this.attributeMap.tabIndex :
+					("_setTabIndexAttr" in this) ? this._setTabIndexAttr : "focusNode";
+				array.forEach(lang.isArray(attachPointNames) ? attachPointNames : [attachPointNames], function(attachPointName){
+					var node = this[attachPointName];
+					// complex code because tabIndex=-1 on a <div> doesn't work on FF
+					if(has("webkit") || a11y.hasDefaultTabStop(node)){    // see #11064 about webkit bug
+						node.setAttribute('tabIndex', "-1");
+					}else{
+						node.removeAttribute('tabIndex');
+					}
+				}, this);
+			}else{
+				if(this.tabIndex != ""){
+					this.set('tabIndex', this.tabIndex);
 				}
-				// setTimeout allows hidden value processing to run and
-				// also the onChange handler can safely adjust focus, etc
-				this._onChangeHandle = setTimeout(lang.hitch(this,
-					function(){
-						this._onChangeHandle = null;
-						this.onChange(newValue);
-					}), 0); // try to collapse multiple onChange's fired faster than can be processed
 			}
-		}
-	},
-
-	create: function(){
-		// Overrides _Widget.create()
-		this.inherited(arguments);
-		this._onChangeActive = true;
-	},
-
-	destroy: function(){
-		if(this._onChangeHandle){ // destroy called before last onChange has fired
-			clearTimeout(this._onChangeHandle);
-			this.onChange(this._lastValueReported);
-		}
-		this.inherited(arguments);
-	},
-
-	_onMouseDown: function(e){
-		// If user clicks on the button, even if the mouse is released outside of it,
-		// this button should get focus (to mimics native browser buttons).
-		// This is also needed on chrome because otherwise buttons won't get focus at all,
-		// which leads to bizarre focus restore on Dialog close etc.
-		// IE exhibits strange scrolling behavior when focusing a node so only do it when !focused.
-		// FF needs the extra help to make sure the mousedown actually gets to the focusNode
-		if((!this.focused || !has('ie')) && !e.ctrlKey && mouse.isLeft(e) && this.isFocusable()){ // !e.ctrlKey to ignore right-click on mac
-			// Set a global event to handle mouseup, so it fires properly
-			// even if the cursor leaves this.domNode before the mouse up event.
-			var mouseUpConnector = this.connect(win.body(), "onmouseup", function(){
-				if(this.isFocusable()){
-					this.focus();
+		},
+
+		_onFocus: function(/*String*/ by){
+			// If user clicks on the widget, even if the mouse is released outside of it,
+			// this widget's focusNode should get focus (to mimic native browser behavior).
+			// Browsers often need help to make sure the focus via mouse actually gets to the focusNode.
+			// TODO: consider removing all of this for 2.0 or sooner, see #16622 etc.
+			if(by == "mouse" && this.isFocusable()){
+				// IE exhibits strange scrolling behavior when refocusing a node so only do it when !focused.
+				var focusHandle = this.own(on(this.focusNode, "focus", function(){
+					mouseUpHandle.remove();
+					focusHandle.remove();
+				}))[0];
+				// Set a global event to handle mouseup, so it fires properly
+				// even if the cursor leaves this.domNode before the mouse up event.
+				var mouseUpHandle = this.own(on(this.ownerDocumentBody, "mouseup, touchend", lang.hitch(this, function(evt){
+					mouseUpHandle.remove();
+					focusHandle.remove();
+					// if here, then the mousedown did not focus the focusNode as the default action
+					if(this.focused){
+						if(evt.type == "touchend"){
+							this.defer("focus"); // native focus hasn't occurred yet
+						}else{
+							this.focus(); // native focus already occurred on mousedown
+						}
+					}
+				})))[0];
+			}
+			if(this.scrollOnFocus){
+				this.defer(function(){
+					winUtils.scrollIntoView(this.domNode);
+				}); // without defer, the input caret position can change on mouse click
+			}
+			this.inherited(arguments);
+		},
+
+		isFocusable: function(){
+			// summary:
+			//		Tells if this widget is focusable or not.  Used internally by dijit.
+			// tags:
+			//		protected
+			return !this.disabled && this.focusNode && (domStyle.get(this.domNode, "display") != "none");
+		},
+
+		focus: function(){
+			// summary:
+			//		Put focus on this widget
+			if(!this.disabled && this.focusNode.focus){
+				try{
+					this.focusNode.focus();
+				}catch(e){
+				}
+				/*squelch errors from hidden nodes*/
+			}
+		},
+
+		compare: function(/*anything*/ val1, /*anything*/ val2){
+			// summary:
+			//		Compare 2 values (as returned by get('value') for this widget).
+			// tags:
+			//		protected
+			if(typeof val1 == "number" && typeof val2 == "number"){
+				return (isNaN(val1) && isNaN(val2)) ? 0 : val1 - val2;
+			}else if(val1 > val2){
+				return 1;
+			}else if(val1 < val2){
+				return -1;
+			}else{
+				return 0;
+			}
+		},
+
+		onChange: function(/*===== newValue =====*/){
+			// summary:
+			//		Callback when this widget's value is changed.
+			// tags:
+			//		callback
+		},
+
+		// _onChangeActive: [private] Boolean
+		//		Indicates that changes to the value should call onChange() callback.
+		//		This is false during widget initialization, to avoid calling onChange()
+		//		when the initial value is set.
+		_onChangeActive: false,
+
+		_handleOnChange: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
+			// summary:
+			//		Called when the value of the widget is set.  Calls onChange() if appropriate
+			// newValue:
+			//		the new value
+			// priorityChange:
+			//		For a slider, for example, dragging the slider is priorityChange==false,
+			//		but on mouse up, it's priorityChange==true.  If intermediateChanges==false,
+			//		onChange is only called form priorityChange=true events.
+			// tags:
+			//		private
+			if(this._lastValueReported == undefined && (priorityChange === null || !this._onChangeActive)){
+				// this block executes not for a change, but during initialization,
+				// and is used to store away the original value (or for ToggleButton, the original checked state)
+				this._resetValue = this._lastValueReported = newValue;
+			}
+			this._pendingOnChange = this._pendingOnChange
+				|| (typeof newValue != typeof this._lastValueReported)
+				|| (this.compare(newValue, this._lastValueReported) != 0);
+			if((this.intermediateChanges || priorityChange || priorityChange === undefined) && this._pendingOnChange){
+				this._lastValueReported = newValue;
+				this._pendingOnChange = false;
+				if(this._onChangeActive){
+					if(this._onChangeHandle){
+						this._onChangeHandle.remove();
+					}
+					// defer allows hidden value processing to run and
+					// also the onChange handler can safely adjust focus, etc
+					this._onChangeHandle = this.defer(
+						function(){
+							this._onChangeHandle = null;
+							this.onChange(newValue);
+						}); // try to collapse multiple onChange's fired faster than can be processed
 				}
-				this.disconnect(mouseUpConnector);
-			});
+			}
+		},
+
+		create: function(){
+			// Overrides _Widget.create()
+			this.inherited(arguments);
+			this._onChangeActive = true;
+		},
+
+		destroy: function(){
+			if(this._onChangeHandle){ // destroy called before last onChange has fired
+				this._onChangeHandle.remove();
+				this.onChange(this._lastValueReported);
+			}
+			this.inherited(arguments);
 		}
-	}
-});
-
+	});
 });
diff --git a/dijit/form/_ListBase.js b/dijit/form/_ListBase.js
index 7e832d4..c06fdc1 100644
--- a/dijit/form/_ListBase.js
+++ b/dijit/form/_ListBase.js
@@ -1,123 +1,133 @@
 define([
-	"dojo/_base/declare",	// declare
+	"dojo/_base/declare", // declare
+	"dojo/on",
 	"dojo/window" // winUtils.scrollIntoView
-], function(declare, winUtils){
+], function(declare, on, winUtils){
 
-// module:
-//		dijit/form/_ListBase
-// summary:
-//		Focus-less menu to handle UI events consistently
+	// module:
+	//		dijit/form/_ListBase
 
-return declare( "dijit.form._ListBase", null, {
-	// summary:
-	//		Focus-less menu to handle UI events consistently
-	//		Abstract methods that must be defined externally:
-	//			onSelect: item is active (mousedown but not yet mouseup, or keyboard arrow selected but no Enter)
-	//			onDeselect:  cancels onSelect
-	// tags:
-	//		private
+	return declare("dijit.form._ListBase", null, {
+		// summary:
+		//		Focus-less menu to handle UI events consistently.
+		//		Abstract methods that must be defined externally:
+		//
+		//		- onSelect: item is active (mousedown but not yet mouseup, or keyboard arrow selected but no Enter)
+		//		- onDeselect:  cancels onSelect
+		// tags:
+		//		private
 
-	// selected: DOMnode
-	//		currently selected node
-	selected: null,
+		// selected: DOMNode
+		//		currently selected node
+		selected: null,
 
-	_getTarget: function(/*Event*/ evt){
-		var tgt = evt.target;
-		var container = this.containerNode;
-		if(tgt == container || tgt == this.domNode){ return null; }
-		while(tgt && tgt.parentNode != container){
-			// recurse to the top
-			tgt = tgt.parentNode;
-		}
-		return tgt;
-	},
+		_listConnect: function(/*String|Function*/ eventType, /*String*/ callbackFuncName){
+			// summary:
+			//		Connects 'containerNode' to specified method of this object
+			//		and automatically registers for 'disconnect' on widget destroy.
+			// description:
+			//		Provide widget-specific analog to 'connect'.
+			//		The callback function is called with the normal event object,
+			//		but also a second parameter is passed that indicates which list item
+			//		actually received the event.
+			// returns:
+			//		A handle that can be passed to `disconnect` in order to disconnect
+			//		before the widget is destroyed.
+			// tags:
+			//		private
 
-	selectFirstNode: function(){
-		// summary:
-		// 		Select the first displayed item in the list.
-		var first = this.containerNode.firstChild;
-		while(first && first.style.display == "none"){
-			first = first.nextSibling;
-		}
-		this._setSelectedAttr(first);
-	},
+			var self = this;
+			return self.own(on(self.containerNode,
+				on.selector(
+					function(eventTarget, selector, target){
+						return eventTarget.parentNode == target;
+					},
+					eventType
+				),
+				function(evt){
+					evt.preventDefault();
+					self[callbackFuncName](evt, this);
+				}
+			));
+		},
 
-	selectLastNode: function(){
-		// summary:
-		// 		Select the last displayed item in the list
-		var last = this.containerNode.lastChild;
-		while(last && last.style.display == "none"){
-			last = last.previousSibling;
-		}
-		this._setSelectedAttr(last);
-	},
+		selectFirstNode: function(){
+			// summary:
+			//		Select the first displayed item in the list.
+			var first = this.containerNode.firstChild;
+			while(first && first.style.display == "none"){
+				first = first.nextSibling;
+			}
+			this._setSelectedAttr(first);
+		},
 
-	selectNextNode: function(){
-		// summary:
-		// 		Select the item just below the current selection.
-		// 		If nothing selected, select first node.
-		var selectedNode = this._getSelectedAttr();
-		if(!selectedNode){
-			this.selectFirstNode();
-		}else{
-			var next = selectedNode.nextSibling;
-			while(next && next.style.display == "none"){
-				next = next.nextSibling;
+		selectLastNode: function(){
+			// summary:
+			//		Select the last displayed item in the list
+			var last = this.containerNode.lastChild;
+			while(last && last.style.display == "none"){
+				last = last.previousSibling;
 			}
-			if(!next){
+			this._setSelectedAttr(last);
+		},
+
+		selectNextNode: function(){
+			// summary:
+			//		Select the item just below the current selection.
+			//		If nothing selected, select first node.
+			var selectedNode = this.selected;
+			if(!selectedNode){
 				this.selectFirstNode();
 			}else{
-				this._setSelectedAttr(next);
+				var next = selectedNode.nextSibling;
+				while(next && next.style.display == "none"){
+					next = next.nextSibling;
+				}
+				if(!next){
+					this.selectFirstNode();
+				}else{
+					this._setSelectedAttr(next);
+				}
 			}
-		}
-	},
+		},
 
-	selectPreviousNode: function(){
-		// summary:
-		// 		Select the item just above the current selection.
-		// 		If nothing selected, select last node (if
-		// 		you select Previous and try to keep scrolling up the list).
-		var selectedNode = this._getSelectedAttr();
-		if(!selectedNode){
-			this.selectLastNode();
-		}else{
-			var prev = selectedNode.previousSibling;
-			while(prev && prev.style.display == "none"){
-				prev = prev.previousSibling;
-			}
-			if(!prev){
+		selectPreviousNode: function(){
+			// summary:
+			//		Select the item just above the current selection.
+			//		If nothing selected, select last node (if
+			//		you select Previous and try to keep scrolling up the list).
+			var selectedNode = this.selected;
+			if(!selectedNode){
 				this.selectLastNode();
 			}else{
-				this._setSelectedAttr(prev);
+				var prev = selectedNode.previousSibling;
+				while(prev && prev.style.display == "none"){
+					prev = prev.previousSibling;
+				}
+				if(!prev){
+					this.selectLastNode();
+				}else{
+					this._setSelectedAttr(prev);
+				}
 			}
-		}
-	},
+		},
 
-	_setSelectedAttr: function(/*DomNode*/ node){
-		// summary:
-		//		Does the actual select.
-		if(this.selected != node){
-			var selectedNode = this._getSelectedAttr();
-			if(selectedNode){
-				this.onDeselect(selectedNode);
-				this.selected = null;
-			}
-			if(node && node.parentNode == this.containerNode){
-				this.selected = node;
-				winUtils.scrollIntoView(node);
+		_setSelectedAttr: function(/*DomNode*/ node){
+			// summary:
+			//		Does the actual select.
+			if(this.selected != node){
+				var selectedNode = this.selected;
+				if(selectedNode){
+					this.onDeselect(selectedNode);
+				}
+				if(node){
+					winUtils.scrollIntoView(node);
+					this.onSelect(node);
+				}
+				this._set("selected", node);
+			}else if(node){
 				this.onSelect(node);
 			}
-		}else if(node){
-			this.onSelect(node);
 		}
-	},
-
-	_getSelectedAttr: function(){
-		// summary:
-		//		Returns the selected node.
-		var v = this.selected;
-		return (v && v.parentNode == this.containerNode) ? v : (this.selected = null);
-	}
-});
-
+	});
 });
diff --git a/dijit/form/_ListMouseMixin.js b/dijit/form/_ListMouseMixin.js
index 896f866..b22200f 100644
--- a/dijit/form/_ListMouseMixin.js
+++ b/dijit/form/_ListMouseMixin.js
@@ -1,96 +1,96 @@
 define([
 	"dojo/_base/declare", // declare
-	"dojo/_base/event", // event.stop
+	"dojo/on",
 	"dojo/touch",
 	"./_ListBase"
-], function(declare, event, touch, _ListBase){
+], function(declare, on, touch, _ListBase){
 
-/*=====
-var _ListBase = dijit.form._ListBase;
-=====*/
+	// module:
+	//		dijit/form/_ListMouseMixin
 
-// module:
-//		dijit/form/_ListMouseMixin
-// summary:
-//		a mixin to handle mouse or touch events for a focus-less menu
+	return declare("dijit.form._ListMouseMixin", _ListBase, {
+		// summary:
+		//		A mixin to handle mouse or touch events for a focus-less menu
+		//		Abstract methods that must be defined externally:
+		//
+		//		- onClick: item was chosen (mousedown somewhere on the menu and mouseup somewhere on the menu)
+		// tags:
+		//		private
 
-return declare( "dijit.form._ListMouseMixin", _ListBase, {
-	// summary:
-	//		a Mixin to handle mouse or touch events for a focus-less menu
-	//		Abstract methods that must be defined externally:
-	//			onClick: item was chosen (mousedown somewhere on the menu and mouseup somewhere on the menu)
-	// tags:
-	//		private
+		postCreate: function(){
+			this.inherited(arguments);
 
-	postCreate: function(){
-		this.inherited(arguments);
-		this.connect(this.domNode, touch.press, "_onMouseDown");
-		this.connect(this.domNode, touch.release, "_onMouseUp");
-		this.connect(this.domNode, "onmouseover", "_onMouseOver");
-		this.connect(this.domNode, "onmouseout", "_onMouseOut");
-	},
+			// Add flag to use normalized click handling from dojo/touch
+			this.domNode.dojoClick = true;
 
-	_onMouseDown: function(/*Event*/ evt){
-		event.stop(evt);
-		if(this._hoveredNode){
-			this.onUnhover(this._hoveredNode);
-			this._hoveredNode = null;
-		}
-		this._isDragging = true;
-		this._setSelectedAttr(this._getTarget(evt));
-	},
+			this.own(on(this.domNode, "mousedown", function(evt){
+				evt.preventDefault();
+			})); // prevent focus shift on list scrollbar press
+			this._listConnect("click", "_onClick");
+			this._listConnect(touch.press, "_onMouseDown");
+			this._listConnect(touch.release, "_onMouseUp");
+			this._listConnect(touch.over, "_onMouseOver");
+			this._listConnect(touch.out, "_onMouseOut");
+		},
 
-	_onMouseUp: function(/*Event*/ evt){
-		event.stop(evt);
-		this._isDragging = false;
-		var selectedNode = this._getSelectedAttr();
-		var target = this._getTarget(evt);
-		var hoveredNode = this._hoveredNode;
-		if(selectedNode && target == selectedNode){
-			this.onClick(selectedNode);
-		}else if(hoveredNode && target == hoveredNode){ // drag to select
-			this._setSelectedAttr(hoveredNode);
-			this.onClick(hoveredNode);
-		}
-	},
+		_onClick: function(/*Event*/ evt, /*DomNode*/ target){
+			this._setSelectedAttr(target);
+			if(this._deferredClick){
+				this._deferredClick.remove();
+			}
+			this._deferredClick = this.defer(function(){
+				this._deferredClick = null;
+				this.onClick(target);
+			});
+		},
 
-	_onMouseOut: function(/*Event*/ /*===== evt ====*/){
-		if(this._hoveredNode){
-			this.onUnhover(this._hoveredNode);
-			if(this._getSelectedAttr() == this._hoveredNode){
-				this.onSelect(this._hoveredNode);
+		_onMouseDown: function(/*Event*/ evt, /*DomNode*/ target){
+			if(this._hoveredNode){
+				this.onUnhover(this._hoveredNode);
+				this._hoveredNode = null;
 			}
-			this._hoveredNode = null;
-		}
-		if(this._isDragging){
-			this._cancelDrag = (new Date()).getTime() + 1000; // cancel in 1 second if no _onMouseOver fires
-		}
-	},
+			this._isDragging = true;
+			this._setSelectedAttr(target);
+		},
 
-	_onMouseOver: function(/*Event*/ evt){
-		if(this._cancelDrag){
-			var time = (new Date()).getTime();
-			if(time > this._cancelDrag){
-				this._isDragging = false;
+		_onMouseUp: function(/*Event*/ evt, /*DomNode*/ target){
+			this._isDragging = false;
+			var selectedNode = this.selected;
+			var hoveredNode = this._hoveredNode;
+			if(selectedNode && target == selectedNode){
+				this.defer(function(){
+					this._onClick(evt, selectedNode);
+				});
+			}else if(hoveredNode){ // drag to select
+				this.defer(function(){
+					this._onClick(evt, hoveredNode);
+				});
 			}
-			this._cancelDrag = null;
-		}
-		var node = this._getTarget(evt);
-		if(!node){ return; }
-		if(this._hoveredNode != node){
+		},
+
+		_onMouseOut: function(/*Event*/ evt, /*DomNode*/ target){
 			if(this._hoveredNode){
-				this._onMouseOut({ target: this._hoveredNode });
+				this.onUnhover(this._hoveredNode);
+				this._hoveredNode = null;
+			}
+			if(this._isDragging){
+				this._cancelDrag = (new Date()).getTime() + 1000; // cancel in 1 second if no _onMouseOver fires
 			}
-			if(node && node.parentNode == this.containerNode){
-				if(this._isDragging){
-					this._setSelectedAttr(node);
-				}else{
-					this._hoveredNode = node;
-					this.onHover(node);
+		},
+
+		_onMouseOver: function(/*Event*/ evt, /*DomNode*/ target){
+			if(this._cancelDrag){
+				var time = (new Date()).getTime();
+				if(time > this._cancelDrag){
+					this._isDragging = false;
 				}
+				this._cancelDrag = null;
+			}
+			this._hoveredNode = target;
+			this.onHover(target);
+			if(this._isDragging){
+				this._setSelectedAttr(target);
 			}
 		}
-	}
-});
-
+	});
 });
diff --git a/dijit/form/_RadioButtonMixin.js b/dijit/form/_RadioButtonMixin.js
index f30bbad..3326173 100644
--- a/dijit/form/_RadioButtonMixin.js
+++ b/dijit/form/_RadioButtonMixin.js
@@ -2,31 +2,27 @@ define([
 	"dojo/_base/array", // array.forEach
 	"dojo/_base/declare", // declare
 	"dojo/dom-attr", // domAttr.set
-	"dojo/_base/event", // event.stop
 	"dojo/_base/lang", // lang.hitch
 	"dojo/query", // query
-	"dojo/_base/window", // win.doc
-	"../registry"	// registry.getEnclosingWidget
-], function(array, declare, domAttr, event, lang, query, win, registry){
+	"../registry"    // registry.getEnclosingWidget
+], function(array, declare, domAttr, lang, query, registry){
 
 	// module:
 	//		dijit/form/_RadioButtonMixin
-	// summary:
-	// 		Mixin to provide widget functionality for an HTML radio button
 
 	return declare("dijit.form._RadioButtonMixin", null, {
 		// summary:
-		// 		Mixin to provide widget functionality for an HTML radio button
+		//		Mixin to provide widget functionality for an HTML radio button
 
 		// type: [private] String
-		//		type attribute on <input> node.
+		//		type attribute on `<input>` node.
 		//		Users should not change this value.
 		type: "radio",
 
 		_getRelatedWidgets: function(){
 			// Private function needed to help iterate over all radio buttons in a group.
 			var ary = [];
-			query("input[type=radio]", this.focusNode.form || win.doc).forEach( // can't use name= since query doesn't support [] in the name
+			query("input[type=radio]", this.focusNode.form || this.ownerDocument).forEach(// can't use name= since query doesn't support [] in the name
 				lang.hitch(this, function(inputNode){
 					if(inputNode.name == this.name && inputNode.form == this.focusNode.form){
 						var widget = registry.getEnclosingWidget(inputNode);
@@ -42,7 +38,9 @@ define([
 		_setCheckedAttr: function(/*Boolean*/ value){
 			// If I am being checked then have to deselect currently checked radio button
 			this.inherited(arguments);
-			if(!this._created){ return; }
+			if(!this._created){
+				return;
+			}
 			if(value){
 				array.forEach(this._getRelatedWidgets(), lang.hitch(this, function(widget){
 					if(widget != this && widget.checked){
@@ -52,13 +50,19 @@ define([
 			}
 		},
 
+		_getSubmitValue: function(/*String*/ value){
+			return value == null ? "on" : value;
+		},
+
 		_onClick: function(/*Event*/ e){
 			if(this.checked || this.disabled){ // nothing to do
-				event.stop(e);
+				e.stopPropagation();
+				e.preventDefault();
 				return false;
 			}
 			if(this.readOnly){ // ignored by some browsers so we have to resync the DOM elements with widget values
-				event.stop(e);
+				e.stopPropagation();
+				e.preventDefault();
 				array.forEach(this._getRelatedWidgets(), lang.hitch(this, function(widget){
 					domAttr.set(this.focusNode || this.domNode, 'checked', widget.checked);
 				}));
diff --git a/dijit/form/_SearchMixin.js b/dijit/form/_SearchMixin.js
new file mode 100644
index 0000000..31f8e3f
--- /dev/null
+++ b/dijit/form/_SearchMixin.js
@@ -0,0 +1,288 @@
+define([
+	"dojo/_base/declare", // declare
+	"dojo/keys", // keys
+	"dojo/_base/lang", // lang.clone lang.hitch
+	"dojo/query", // query
+	"dojo/string", // string.substitute
+	"dojo/when",
+	"../registry"	// registry.byId
+], function(declare, keys, lang, query, string, when, registry){
+
+	// module:
+	//		dijit/form/_SearchMixin
+
+
+	return declare("dijit.form._SearchMixin", null, {
+		// summary:
+		//		A mixin that implements the base functionality to search a store based upon user-entered text such as
+		//		with `dijit/form/ComboBox` or `dijit/form/FilteringSelect`
+		// tags:
+		//		protected
+
+		// pageSize: Integer
+		//		Argument to data provider.
+		//		Specifies maximum number of search results to return per query
+		pageSize: Infinity,
+
+		// store: [const] dojo/store/api/Store
+		//		Reference to data provider object used by this ComboBox.
+		//		The store must accept an object hash of properties for its query. See `query` and `queryExpr` for details.
+		store: null,
+
+		// fetchProperties: Object
+		//		Mixin to the store's fetch.
+		//		For example, to set the sort order of the ComboBox menu, pass:
+		//	|	{ sort: [{attribute:"name",descending: true}] }
+		//		To override the default queryOptions so that deep=false, do:
+		//	|	{ queryOptions: {ignoreCase: true, deep: false} }
+		fetchProperties:{},
+
+		// query: Object
+		//		A query that can be passed to `store` to initially filter the items.
+		//		ComboBox overwrites any reference to the `searchAttr` and sets it to the `queryExpr` with the user's input substituted.
+		query: {},
+
+		// searchDelay: Integer
+		//		Delay in milliseconds between when user types something and we start
+		//		searching based on that value
+		searchDelay: 200,
+
+		// searchAttr: String
+		//		Search for items in the data store where this attribute (in the item)
+		//		matches what the user typed
+		searchAttr: "name",
+
+		// queryExpr: String
+		//		This specifies what query is sent to the data store,
+		//		based on what the user has typed.  Changing this expression will modify
+		//		whether the results are only exact matches, a "starting with" match,
+		//		etc.
+		//		`${0}` will be substituted for the user text.
+		//		`*` is used for wildcards.
+		//		`${0}*` means "starts with", `*${0}*` means "contains", `${0}` means "is"
+		queryExpr: "${0}*",
+
+		// ignoreCase: Boolean
+		//		Set true if the query should ignore case when matching possible items
+		ignoreCase: true,
+
+		_patternToRegExp: function(pattern){
+			// summary:
+			//		Helper function to convert a simple pattern to a regular expression for matching.
+			// description:
+			//		Returns a regular expression object that conforms to the defined conversion rules.
+			//		For example:
+			//
+			//		- ca*   -> /^ca.*$/
+			//		- *ca*  -> /^.*ca.*$/
+			//		- *c\*a*  -> /^.*c\*a.*$/
+			//		- *c\*a?*  -> /^.*c\*a..*$/
+			//
+			//		and so on.
+			// pattern: string
+			//		A simple matching pattern to convert that follows basic rules:
+			//
+			//		- * Means match anything, so ca* means match anything starting with ca
+			//		- ? Means match single character.  So, b?b will match to bob and bab, and so on.
+			//		- \ is an escape character.  So for example, \* means do not treat * as a match, but literal character *.
+			//
+			//		To use a \ as a character in the string, it must be escaped.  So in the pattern it should be
+			//		represented by \\ to be treated as an ordinary \ character instead of an escape.
+
+			return new RegExp("^" + pattern.replace(/(\\.)|(\*)|(\?)|\W/g, function(str, literal, star, question){
+				return star ? ".*" : question ? "." : literal ? literal : "\\" + str;
+			}) + "$", this.ignoreCase ? "mi" : "m");
+		},
+
+		_abortQuery: function(){
+			// stop in-progress query
+			if(this.searchTimer){
+				this.searchTimer = this.searchTimer.remove();
+			}
+			if(this._queryDeferHandle){
+				this._queryDeferHandle = this._queryDeferHandle.remove();
+			}
+			if(this._fetchHandle){
+				if(this._fetchHandle.abort){
+					this._cancelingQuery = true;
+					this._fetchHandle.abort();
+					this._cancelingQuery = false;
+				}
+				if(this._fetchHandle.cancel){
+					this._cancelingQuery = true;
+					this._fetchHandle.cancel();
+					this._cancelingQuery = false;
+				}
+				this._fetchHandle = null;
+			}
+		},
+
+		_processInput: function(/*Event*/ evt){
+			// summary:
+			//		Handles input (keyboard/paste) events
+			if(this.disabled || this.readOnly){ return; }
+			var key = evt.charOrCode;
+
+			// except for cutting/pasting case - ctrl + x/v
+			if("type" in evt && evt.type.substring(0,3) == "key" && (evt.altKey || ((evt.ctrlKey || evt.metaKey) && (key != 'x' && key != 'v')) || key == keys.SHIFT)){
+				return; // throw out weird key combinations and spurious events
+			}
+
+			var doSearch = false;
+			this._prev_key_backspace = false;
+
+			switch(key){
+				case keys.DELETE:
+				case keys.BACKSPACE:
+					this._prev_key_backspace = true;
+					this._maskValidSubsetError = true;
+					doSearch = true;
+					break;
+
+				default:
+					// Non char keys (F1-F12 etc..) shouldn't start a search..
+					// Ascii characters and IME input (Chinese, Japanese etc.) should.
+					//IME input produces keycode == 229.
+					doSearch = typeof key == 'string' || key == 229;
+			}
+			if(doSearch){
+				// need to wait a tad before start search so that the event
+				// bubbles through DOM and we have value visible
+				if(!this.store){
+					this.onSearch();
+				}else{
+					this.searchTimer = this.defer("_startSearchFromInput", 1);
+				}
+			}
+		},
+
+		onSearch: function(/*===== results, query, options =====*/){
+			// summary:
+			//		Callback when a search completes.
+			//
+			// results: Object
+			//		An array of items from the originating _SearchMixin's store.
+			//
+			// query: Object
+			//		A copy of the originating _SearchMixin's query property.
+			//
+			// options: Object
+			//		The additional parameters sent to the originating _SearchMixin's store, including: start, count, queryOptions.
+			//
+			// tags:
+			//		callback
+		},
+
+		_startSearchFromInput: function(){
+			this._startSearch(this.focusNode.value);
+		},
+
+		_startSearch: function(/*String*/ text){
+			// summary:
+			//		Starts a search for elements matching text (text=="" means to return all items),
+			//		and calls onSearch(...) when the search completes, to display the results.
+
+			this._abortQuery();
+			var
+				_this = this,
+				// Setup parameters to be passed to store.query().
+				// Create a new query to prevent accidentally querying for a hidden
+				// value from FilteringSelect's keyField
+				query = lang.clone(this.query), // #5970
+				options = {
+					start: 0,
+					count: this.pageSize,
+					queryOptions: {		// remove for 2.0
+						ignoreCase: this.ignoreCase,
+						deep: true
+					}
+				},
+				qs = string.substitute(this.queryExpr, [text.replace(/([\\\*\?])/g, "\\$1")]),
+				q,
+				startQuery = function(){
+					var resPromise = _this._fetchHandle = _this.store.query(query, options);
+					if(_this.disabled || _this.readOnly || (q !== _this._lastQuery)){
+						return;
+					} // avoid getting unwanted notify
+					when(resPromise, function(res){
+						_this._fetchHandle = null;
+						if(!_this.disabled && !_this.readOnly && (q === _this._lastQuery)){ // avoid getting unwanted notify
+							when(resPromise.total, function(total){
+								res.total = total;
+								var pageSize = _this.pageSize;
+								if(isNaN(pageSize) || pageSize > res.total){ pageSize = res.total; }
+								// Setup method to fetching the next page of results
+								res.nextPage = function(direction){
+									//	tell callback the direction of the paging so the screen
+									//	reader knows which menu option to shout
+									options.direction = direction = direction !== false;
+									options.count = pageSize;
+									if(direction){
+										options.start += res.length;
+										if(options.start >= res.total){
+											options.count = 0;
+										}
+									}else{
+										options.start -= pageSize;
+										if(options.start < 0){
+											options.count = Math.max(pageSize + options.start, 0);
+											options.start = 0;
+										}
+									}
+									if(options.count <= 0){
+										res.length = 0;
+										_this.onSearch(res, query, options);
+									}else{
+										startQuery();
+									}
+								};
+								_this.onSearch(res, query, options);
+							});
+						}
+					}, function(err){
+						_this._fetchHandle = null;
+						if(!_this._cancelingQuery){	// don't treat canceled query as an error
+							console.error(_this.declaredClass + ' ' + err.toString());
+						}
+					});
+				};
+
+			lang.mixin(options, this.fetchProperties);
+
+			// Generate query
+			if(this.store._oldAPI){
+				// remove this branch for 2.0
+				q = qs;
+			}else{
+				// Query on searchAttr is a regex for benefit of dojo/store/Memory,
+				// but with a toString() method to help dojo/store/JsonRest.
+				// Search string like "Co*" converted to regex like /^Co.*$/i.
+				q = this._patternToRegExp(qs);
+				q.toString = function(){ return qs; };
+			}
+
+			// set _lastQuery, *then* start the timeout
+			// otherwise, if the user types and the last query returns before the timeout,
+			// _lastQuery won't be set and their input gets rewritten
+			this._lastQuery = query[this.searchAttr] = q;
+			this._queryDeferHandle = this.defer(startQuery, this.searchDelay);
+		},
+
+		//////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+		constructor: function(){
+			this.query={};
+			this.fetchProperties={};
+		},
+
+		postMixInProperties: function(){
+			if(!this.store){
+				var list = this.list;
+				if(list){
+					this.store = registry.byId(list);
+				}
+			}
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dijit/form/_Spinner.js b/dijit/form/_Spinner.js
index 66250fc..dc25a38 100644
--- a/dijit/form/_Spinner.js
+++ b/dijit/form/_Spinner.js
@@ -1,30 +1,24 @@
 define([
 	"dojo/_base/declare", // declare
-	"dojo/_base/event", // event.stop
 	"dojo/keys", // keys keys.DOWN_ARROW keys.PAGE_DOWN keys.PAGE_UP keys.UP_ARROW
 	"dojo/_base/lang", // lang.hitch
-	"dojo/_base/sniff", // has("mozilla")
-	"dijit/typematic",
+	"dojo/sniff", // has("mozilla")
+	"dojo/mouse", // mouse.wheel
+	"dojo/on",
+	"../typematic",
 	"./RangeBoundTextBox",
 	"dojo/text!./templates/Spinner.html",
-	"./_TextBoxMixin"	// selectInputText
-], function(declare, event, keys, lang, has, typematic, RangeBoundTextBox, template, _TextBoxMixin){
-
-/*=====
-	var RangeBoundTextBox = dijit.form.RangeBoundTextBox;
-=====*/
+	"./_TextBoxMixin"    // selectInputText
+], function(declare, keys, lang, has, mouse, on, typematic, RangeBoundTextBox, template, _TextBoxMixin){
 
 	// module:
 	//		dijit/form/_Spinner
-	// summary:
-	//		Mixin for validation widgets with a spinner.
-
 
 	return declare("dijit.form._Spinner", RangeBoundTextBox, {
 		// summary:
 		//		Mixin for validation widgets with a spinner.
 		// description:
-		//		This class basically (conceptually) extends `dijit.form.ValidationTextBox`.
+		//		This class basically (conceptually) extends `dijit/form/ValidationTextBox`.
 		//		It modifies the template to have up/down arrows, and provides related handling code.
 
 		// defaultTimeout: Number
@@ -38,7 +32,7 @@ define([
 		// timeoutChangeRate: Number
 		//		Fraction of time used to change the typematic timer between events.
 		//		1.0 means that each typematic event fires at defaultTimeout intervals.
-		//		< 1.0 means that each typematic event fires at an increasing faster rate.
+		//		Less than 1.0 means that each typematic event fires at an increasing faster rate.
 		timeoutChangeRate: 0.90,
 
 		// smallDelta: Number
@@ -63,7 +57,7 @@ define([
 		adjust: function(val /*=====, delta =====*/){
 			// summary:
 			//		Overridable function used to adjust a primitive value(Number/Date/...) by the delta amount specified.
-			// 		The val is adjusted in a way that makes sense to the object type.
+			//		The val is adjusted in a way that makes sense to the object type.
 			// val: Object
 			// delta: Number
 			// tags:
@@ -74,8 +68,10 @@ define([
 		_arrowPressed: function(/*Node*/ nodePressed, /*Number*/ direction, /*Number*/ increment){
 			// summary:
 			//		Handler for arrow button or arrow key being pressed
-			if(this.disabled || this.readOnly){ return; }
-			this._setValueAttr(this.adjust(this.get('value'), direction*increment), false);
+			if(this.disabled || this.readOnly){
+				return;
+			}
+			this._setValueAttr(this.adjust(this.get('value'), direction * increment), false);
 			_TextBoxMixin.selectInputText(this.textbox, this.textbox.value.length);
 		},
 
@@ -86,14 +82,18 @@ define([
 		},
 
 		_typematicCallback: function(/*Number*/ count, /*DOMNode*/ node, /*Event*/ evt){
-			var inc=this.smallDelta;
+			var inc = this.smallDelta;
 			if(node == this.textbox){
-				var key = evt.charOrCode;
+				var key = evt.keyCode;
 				inc = (key == keys.PAGE_UP || key == keys.PAGE_DOWN) ? this.largeDelta : this.smallDelta;
 				node = (key == keys.UP_ARROW || key == keys.PAGE_UP) ? this.upArrowNode : this.downArrowNode;
 			}
-			if(count == -1){ this._arrowReleased(node); }
-			else{ this._arrowPressed(node, (node == this.upArrowNode) ? 1 : -1, inc); }
+			if(count == -1){
+				this._arrowReleased(node);
+			}
+			else{
+				this._arrowPressed(node, (node == this.upArrowNode) ? 1 : -1, inc);
+			}
 		},
 
 		_wheelTimer: null,
@@ -101,7 +101,8 @@ define([
 			// summary:
 			//		Mouse wheel listener where supported
 
-			event.stop(evt);
+			evt.stopPropagation();
+			evt.preventDefault();
 			// FIXME: Safari bubbles
 
 			// be nice to DOH and scroll as much as the event says to
@@ -117,23 +118,50 @@ define([
 
 				this._arrowPressed(node, scrollAmount, this.smallDelta);
 
-				if(!this._wheelTimer){
-					clearTimeout(this._wheelTimer);
+				if(this._wheelTimer){
+					this._wheelTimer.remove();
 				}
-				this._wheelTimer = setTimeout(lang.hitch(this,"_arrowReleased",node), 50);
+				this._wheelTimer = this.defer(function(){
+					this._arrowReleased(node);
+				}, 50);
 			}
+		},
 
+		_setConstraintsAttr: function(/*Object*/ constraints){
+			this.inherited(arguments);
+			if(this.focusNode){ // not set when called from postMixInProperties
+				if(this.constraints.min !== undefined){
+					this.focusNode.setAttribute("aria-valuemin", this.constraints.min);
+				}else{
+					this.focusNode.removeAttribute("aria-valuemin");
+				}
+				if(this.constraints.max !== undefined){
+					this.focusNode.setAttribute("aria-valuemax", this.constraints.max);
+				}else{
+					this.focusNode.removeAttribute("aria-valuemax");
+				}
+			}
+		},
+
+		_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange){
+			// summary:
+			//		Hook so set('value', ...) works.
+
+			this.focusNode.setAttribute("aria-valuenow", value);
+			this.inherited(arguments);
 		},
 
 		postCreate: function(){
 			this.inherited(arguments);
 
 			// extra listeners
-			this.connect(this.domNode, !has("mozilla") ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
-			this._connects.push(typematic.addListener(this.upArrowNode, this.textbox, {charOrCode:keys.UP_ARROW,ctrlKey:false,altKey:false,shiftKey:false,metaKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout));
-			this._connects.push(typematic.addListener(this.downArrowNode, this.textbox, {charOrCode:keys.DOWN_ARROW,ctrlKey:false,altKey:false,shiftKey:false,metaKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout));
-			this._connects.push(typematic.addListener(this.upArrowNode, this.textbox, {charOrCode:keys.PAGE_UP,ctrlKey:false,altKey:false,shiftKey:false,metaKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout));
-			this._connects.push(typematic.addListener(this.downArrowNode, this.textbox, {charOrCode:keys.PAGE_DOWN,ctrlKey:false,altKey:false,shiftKey:false,metaKey:false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout));
+			this.own(
+				on(this.domNode, mouse.wheel, lang.hitch(this, "_mouseWheeled")),
+				typematic.addListener(this.upArrowNode, this.textbox, {keyCode: keys.UP_ARROW, ctrlKey: false, altKey: false, shiftKey: false, metaKey: false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout),
+				typematic.addListener(this.downArrowNode, this.textbox, {keyCode: keys.DOWN_ARROW, ctrlKey: false, altKey: false, shiftKey: false, metaKey: false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout),
+				typematic.addListener(this.upArrowNode, this.textbox, {keyCode: keys.PAGE_UP, ctrlKey: false, altKey: false, shiftKey: false, metaKey: false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout),
+				typematic.addListener(this.downArrowNode, this.textbox, {keyCode: keys.PAGE_DOWN, ctrlKey: false, altKey: false, shiftKey: false, metaKey: false}, this, "_typematicCallback", this.timeoutChangeRate, this.defaultTimeout, this.minimumTimeout)
+			);
 		}
 	});
 });
diff --git a/dijit/form/_TextBoxMixin.js b/dijit/form/_TextBoxMixin.js
index ad08b08..db64622 100644
--- a/dijit/form/_TextBoxMixin.js
+++ b/dijit/form/_TextBoxMixin.js
@@ -1,408 +1,499 @@
-define([
-	"dojo/_base/array", // array.forEach
-	"dojo/_base/declare", // declare
-	"dojo/dom", // dom.byId
-	"dojo/_base/event", // event.stop
-	"dojo/keys", // keys.ALT keys.CAPS_LOCK keys.CTRL keys.META keys.SHIFT
-	"dojo/_base/lang", // lang.mixin
-	".."	// for exporting dijit._setSelectionRange, dijit.selectInputText
-], function(array, declare, dom, event, keys, lang, dijit){
-
-// module:
-//		dijit/form/_TextBoxMixin
-// summary:
-//		A mixin for textbox form input widgets
-
-var _TextBoxMixin = declare("dijit.form._TextBoxMixin", null, {
-	// summary:
-	//		A mixin for textbox form input widgets
-
-	// trim: Boolean
-	//		Removes leading and trailing whitespace if true.  Default is false.
-	trim: false,
-
-	// uppercase: Boolean
-	//		Converts all characters to uppercase if true.  Default is false.
-	uppercase: false,
-
-	// lowercase: Boolean
-	//		Converts all characters to lowercase if true.  Default is false.
-	lowercase: false,
-
-	// propercase: Boolean
-	//		Converts the first character of each word to uppercase if true.
-	propercase: false,
-
-	// maxLength: String
-	//		HTML INPUT tag maxLength declaration.
-	maxLength: "",
-
-	// selectOnClick: [const] Boolean
-	//		If true, all text will be selected when focused with mouse
-	selectOnClick: false,
-
-	// placeHolder: String
-	//		Defines a hint to help users fill out the input field (as defined in HTML 5).
-	//		This should only contain plain text (no html markup).
-	placeHolder: "",
-
-	_getValueAttr: function(){
-		// summary:
-		//		Hook so get('value') works as we like.
-		// description:
-		//		For `dijit.form.TextBox` this basically returns the value of the <input>.
-		//
-		//		For `dijit.form.MappedTextBox` subclasses, which have both
-		//		a "displayed value" and a separate "submit value",
-		//		This treats the "displayed value" as the master value, computing the
-		//		submit value from it via this.parse().
-		return this.parse(this.get('displayedValue'), this.constraints);
-	},
-
-	_setValueAttr: function(value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
-		// summary:
-		//		Hook so set('value', ...) works.
-		//
-		// description:
-		//		Sets the value of the widget to "value" which can be of
-		//		any type as determined by the widget.
-		//
-		// value:
-		//		The visual element value is also set to a corresponding,
-		//		but not necessarily the same, value.
-		//
-		// formattedValue:
-		//		If specified, used to set the visual element value,
-		//		otherwise a computed visual value is used.
-		//
-		// priorityChange:
-		//		If true, an onChange event is fired immediately instead of
-		//		waiting for the next blur event.
-
-		var filteredValue;
-		if(value !== undefined){
-			// TODO: this is calling filter() on both the display value and the actual value.
-			// I added a comment to the filter() definition about this, but it should be changed.
-			filteredValue = this.filter(value);
-			if(typeof formattedValue != "string"){
-				if(filteredValue !== null && ((typeof filteredValue != "number") || !isNaN(filteredValue))){
-					formattedValue = this.filter(this.format(filteredValue, this.constraints));
-				}else{ formattedValue = ''; }
-			}
-		}
-		if(formattedValue != null && formattedValue != undefined && ((typeof formattedValue) != "number" || !isNaN(formattedValue)) && this.textbox.value != formattedValue){
-			this.textbox.value = formattedValue;
-			this._set("displayedValue", this.get("displayedValue"));
-		}
-
-		if(this.textDir == "auto"){
-			this.applyTextDir(this.focusNode, formattedValue);
-		}
-
-		this.inherited(arguments, [filteredValue, priorityChange]);
-	},
-
-	// displayedValue: String
-	//		For subclasses like ComboBox where the displayed value
-	//		(ex: Kentucky) and the serialized value (ex: KY) are different,
-	//		this represents the displayed value.
-	//
-	//		Setting 'displayedValue' through set('displayedValue', ...)
-	//		updates 'value', and vice-versa.  Otherwise 'value' is updated
-	//		from 'displayedValue' periodically, like onBlur etc.
-	//
-	//		TODO: move declaration to MappedTextBox?
-	//		Problem is that ComboBox references displayedValue,
-	//		for benefit of FilteringSelect.
-	displayedValue: "",
-
-	_getDisplayedValueAttr: function(){
-		// summary:
-		//		Hook so get('displayedValue') works.
-		// description:
-		//		Returns the displayed value (what the user sees on the screen),
-		// 		after filtering (ie, trimming spaces etc.).
-		//
-		//		For some subclasses of TextBox (like ComboBox), the displayed value
-		//		is different from the serialized value that's actually
-		//		sent to the server (see dijit.form.ValidationTextBox.serialize)
-
-		// TODO: maybe we should update this.displayedValue on every keystroke so that we don't need
-		// this method
-		// TODO: this isn't really the displayed value when the user is typing
-		return this.filter(this.textbox.value);
-	},
-
-	_setDisplayedValueAttr: function(/*String*/ value){
-		// summary:
-		//		Hook so set('displayedValue', ...) works.
-		// description:
-		//		Sets the value of the visual element to the string "value".
-		//		The widget value is also set to a corresponding,
-		//		but not necessarily the same, value.
-
-		if(value === null || value === undefined){ value = '' }
-		else if(typeof value != "string"){ value = String(value) }
-
-		this.textbox.value = value;
-
-		// sets the serialized value to something corresponding to specified displayedValue
-		// (if possible), and also updates the textbox.value, for example converting "123"
-		// to "123.00"
-		this._setValueAttr(this.get('value'), undefined);
-
-		this._set("displayedValue", this.get('displayedValue'));
-
-		// textDir support
-		if(this.textDir == "auto"){
-			this.applyTextDir(this.focusNode, value);
-		}
-	},
-
-	format: function(value /*=====, constraints =====*/){
-		// summary:
-		//		Replaceable function to convert a value to a properly formatted string.
-		// value: String
-		// constraints: Object
-		// tags:
-		//		protected extension
-		return ((value == null || value == undefined) ? "" : (value.toString ? value.toString() : value));
-	},
-
-	parse: function(value /*=====, constraints =====*/){
-		// summary:
-		//		Replaceable function to convert a formatted string to a value
-		// value: String
-		// constraints: Object
-		// tags:
-		//		protected extension
-
-		return value;	// String
-	},
-
-	_refreshState: function(){
-		// summary:
-		//		After the user types some characters, etc., this method is
-		//		called to check the field for validity etc.  The base method
-		//		in `dijit.form.TextBox` does nothing, but subclasses override.
-		// tags:
-		//		protected
-	},
-
-	/*=====
-	onInput: function(event){
-		// summary:
-		//		Connect to this function to receive notifications of various user data-input events.
-		//		Return false to cancel the event and prevent it from being processed.
-		// event:
-		//		keydown | keypress | cut | paste | input
-		// tags:
-		//		callback
-	},
-	=====*/
-	onInput: function(){},
-
-	__skipInputEvent: false,
-	_onInput: function(){
-		// summary:
-		//		Called AFTER the input event has happened
-		// set text direction according to textDir that was defined in creation
-		if(this.textDir == "auto"){
-			this.applyTextDir(this.focusNode, this.focusNode.value);
-		}
-
-		this._refreshState();
-
-		// In case someone is watch()'ing for changes to displayedValue
-		this._set("displayedValue", this.get("displayedValue"));
-	},
-
-	postCreate: function(){
-		// setting the value here is needed since value="" in the template causes "undefined"
-		// and setting in the DOM (instead of the JS object) helps with form reset actions
-		this.textbox.setAttribute("value", this.textbox.value); // DOM and JS values should be the same
-
-		this.inherited(arguments);
-
-		// normalize input events to reduce spurious event processing
-		//	onkeydown: do not forward modifier keys
-		//	           set charOrCode to numeric keycode
-		//	onkeypress: do not forward numeric charOrCode keys (already sent through onkeydown)
-		//	onpaste & oncut: set charOrCode to 229 (IME)
-		//	oninput: if primary event not already processed, set charOrCode to 229 (IME), else do not forward
-		var handleEvent = function(e){
-			var charCode = e.charOrCode || e.keyCode || 229;
-			if(e.type == "keydown"){
-				switch(charCode){ // ignore "state" keys
-					case keys.SHIFT:
-					case keys.ALT:
-					case keys.CTRL:
-					case keys.META:
-					case keys.CAPS_LOCK:
-						return;
-					default:
-						if(charCode >= 65 && charCode <= 90){ return; } // keydown for A-Z can be processed with keypress
-				}
-			}
-			if(e.type == "keypress" && typeof charCode != "string"){ return; }
-			if(e.type == "input"){
-				if(this.__skipInputEvent){ // duplicate event
-					this.__skipInputEvent = false;
-					return;
-				}
-			}else{
-				this.__skipInputEvent = true;
-			}
-			// create fake event to set charOrCode and to know if preventDefault() was called
-			var faux = lang.mixin({}, e, {
-				charOrCode: charCode,
-				wasConsumed: false,
-				preventDefault: function(){
-					faux.wasConsumed = true;
-					e.preventDefault();
-				},
-				stopPropagation: function(){ e.stopPropagation(); }
-			});
-			// give web page author a chance to consume the event
-			if(this.onInput(faux) === false){
-				event.stop(faux); // return false means stop
-			}
-			if(faux.wasConsumed){ return; } // if preventDefault was called
-			setTimeout(lang.hitch(this, "_onInput", faux), 0); // widget notification after key has posted
-		};
-		array.forEach([ "onkeydown", "onkeypress", "onpaste", "oncut", "oninput" ], function(event){
-			this.connect(this.textbox, event, handleEvent);
-		}, this);
-	},
-
-	_blankValue: '', // if the textbox is blank, what value should be reported
-	filter: function(val){
-		// summary:
-		//		Auto-corrections (such as trimming) that are applied to textbox
-		//		value on blur or form submit.
-		// description:
-		//		For MappedTextBox subclasses, this is called twice
-		// 			- once with the display value
-		//			- once the value as set/returned by set('value', ...)
-		//		and get('value'), ex: a Number for NumberTextBox.
-		//
-		//		In the latter case it does corrections like converting null to NaN.  In
-		//		the former case the NumberTextBox.filter() method calls this.inherited()
-		//		to execute standard trimming code in TextBox.filter().
-		//
-		//		TODO: break this into two methods in 2.0
-		//
-		// tags:
-		//		protected extension
-		if(val === null){ return this._blankValue; }
-		if(typeof val != "string"){ return val; }
-		if(this.trim){
-			val = lang.trim(val);
-		}
-		if(this.uppercase){
-			val = val.toUpperCase();
-		}
-		if(this.lowercase){
-			val = val.toLowerCase();
-		}
-		if(this.propercase){
-			val = val.replace(/[^\s]+/g, function(word){
-				return word.substring(0,1).toUpperCase() + word.substring(1);
-			});
-		}
-		return val;
-	},
-
-	_setBlurValue: function(){
-		this._setValueAttr(this.get('value'), true);
-	},
-
-	_onBlur: function(e){
-		if(this.disabled){ return; }
-		this._setBlurValue();
-		this.inherited(arguments);
-
-		if(this._selectOnClickHandle){
-			this.disconnect(this._selectOnClickHandle);
-		}
-	},
-
-	_isTextSelected: function(){
-		return this.textbox.selectionStart == this.textbox.selectionEnd;
-	},
-
-	_onFocus: function(/*String*/ by){
-		if(this.disabled || this.readOnly){ return; }
-
-		// Select all text on focus via click if nothing already selected.
-		// Since mouse-up will clear the selection need to defer selection until after mouse-up.
-		// Don't do anything on focus by tabbing into the widget since there's no associated mouse-up event.
-		if(this.selectOnClick && by == "mouse"){
-			this._selectOnClickHandle = this.connect(this.domNode, "onmouseup", function(){
-				// Only select all text on first click; otherwise users would have no way to clear
-				// the selection.
-				this.disconnect(this._selectOnClickHandle);
-
-				// Check if the user selected some text manually (mouse-down, mouse-move, mouse-up)
-				// and if not, then select all the text
-				if(this._isTextSelected()){
-					_TextBoxMixin.selectInputText(this.textbox);
-				}
-			});
-		}
-		// call this.inherited() before refreshState(), since this.inherited() will possibly scroll the viewport
-		// (to scroll the TextBox into view), which will affect how _refreshState() positions the tooltip
-		this.inherited(arguments);
-
-		this._refreshState();
-	},
-
-	reset: function(){
-		// Overrides dijit._FormWidget.reset().
-		// Additionally resets the displayed textbox value to ''
-		this.textbox.value = '';
-		this.inherited(arguments);
-	},
-	_setTextDirAttr: function(/*String*/ textDir){
-		// summary:
-		//		Setter for textDir.
-		// description:
-		//		Users shouldn't call this function; they should be calling
-		//		set('textDir', value)
-		// tags:
-		//		private
-
-		// only if new textDir is different from the old one
-		// and on widgets creation.
-		if(!this._created
-			|| this.textDir != textDir){
-				this._set("textDir", textDir);
-				// so the change of the textDir will take place immediately.
-				this.applyTextDir(this.focusNode, this.focusNode.value);
-		}
-	}
-});
-
-
-_TextBoxMixin._setSelectionRange = dijit._setSelectionRange = function(/*DomNode*/ element, /*Number?*/ start, /*Number?*/ stop){
-	if(element.setSelectionRange){
-		element.setSelectionRange(start, stop);
-	}
-};
-
-_TextBoxMixin.selectInputText = dijit.selectInputText = function(/*DomNode*/ element, /*Number?*/ start, /*Number?*/ stop){
-	// summary:
-	//		Select text in the input element argument, from start (default 0), to stop (default end).
-
-	// TODO: use functions in _editor/selection.js?
-	element = dom.byId(element);
-	if(isNaN(start)){ start = 0; }
-	if(isNaN(stop)){ stop = element.value ? element.value.length : 0; }
-	try{
-		element.focus();
-		_TextBoxMixin._setSelectionRange(element, start, stop);
-	}catch(e){ /* squelch random errors (esp. on IE) from unexpected focus changes or DOM nodes being hidden */ }
-};
-
-return _TextBoxMixin;
-});
+define([
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/declare", // declare
+	"dojo/dom", // dom.byId
+	"dojo/has",
+	"dojo/keys", // keys.ALT keys.CAPS_LOCK keys.CTRL keys.META keys.SHIFT
+	"dojo/_base/lang", // lang.mixin
+	"dojo/on", // on
+	"../main"    // for exporting dijit._setSelectionRange, dijit.selectInputText
+], function(array, declare, dom, has, keys, lang, on, dijit){
+
+	// module:
+	//		dijit/form/_TextBoxMixin
+
+	var _TextBoxMixin = declare("dijit.form._TextBoxMixin" + (has("dojo-bidi") ? "_NoBidi" : ""), null, {
+		// summary:
+		//		A mixin for textbox form input widgets
+
+		// trim: Boolean
+		//		Removes leading and trailing whitespace if true.  Default is false.
+		trim: false,
+
+		// uppercase: Boolean
+		//		Converts all characters to uppercase if true.  Default is false.
+		uppercase: false,
+
+		// lowercase: Boolean
+		//		Converts all characters to lowercase if true.  Default is false.
+		lowercase: false,
+
+		// propercase: Boolean
+		//		Converts the first character of each word to uppercase if true.
+		propercase: false,
+
+		// maxLength: String
+		//		HTML INPUT tag maxLength declaration.
+		maxLength: "",
+
+		// selectOnClick: [const] Boolean
+		//		If true, all text will be selected when focused with mouse
+		selectOnClick: false,
+
+		// placeHolder: String
+		//		Defines a hint to help users fill out the input field (as defined in HTML 5).
+		//		This should only contain plain text (no html markup).
+		placeHolder: "",
+
+		_getValueAttr: function(){
+			// summary:
+			//		Hook so get('value') works as we like.
+			// description:
+			//		For `dijit/form/TextBox` this basically returns the value of the `<input>`.
+			//
+			//		For `dijit/form/MappedTextBox` subclasses, which have both
+			//		a "displayed value" and a separate "submit value",
+			//		This treats the "displayed value" as the master value, computing the
+			//		submit value from it via this.parse().
+			return this.parse(this.get('displayedValue'), this.constraints);
+		},
+
+		_setValueAttr: function(value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
+			// summary:
+			//		Hook so set('value', ...) works.
+			//
+			// description:
+			//		Sets the value of the widget to "value" which can be of
+			//		any type as determined by the widget.
+			//
+			// value:
+			//		The visual element value is also set to a corresponding,
+			//		but not necessarily the same, value.
+			//
+			// formattedValue:
+			//		If specified, used to set the visual element value,
+			//		otherwise a computed visual value is used.
+			//
+			// priorityChange:
+			//		If true, an onChange event is fired immediately instead of
+			//		waiting for the next blur event.
+
+			var filteredValue;
+			if(value !== undefined){
+				// TODO: this is calling filter() on both the display value and the actual value.
+				// I added a comment to the filter() definition about this, but it should be changed.
+				filteredValue = this.filter(value);
+				if(typeof formattedValue != "string"){
+					if(filteredValue !== null && ((typeof filteredValue != "number") || !isNaN(filteredValue))){
+						formattedValue = this.filter(this.format(filteredValue, this.constraints));
+					}else{
+						formattedValue = '';
+					}
+				}
+			}
+			if(formattedValue != null /* and !undefined */ && ((typeof formattedValue) != "number" || !isNaN(formattedValue)) && this.textbox.value != formattedValue){
+				this.textbox.value = formattedValue;
+				this._set("displayedValue", this.get("displayedValue"));
+			}
+
+			this.inherited(arguments, [filteredValue, priorityChange]);
+		},
+
+		// displayedValue: String
+		//		For subclasses like ComboBox where the displayed value
+		//		(ex: Kentucky) and the serialized value (ex: KY) are different,
+		//		this represents the displayed value.
+		//
+		//		Setting 'displayedValue' through set('displayedValue', ...)
+		//		updates 'value', and vice-versa.  Otherwise 'value' is updated
+		//		from 'displayedValue' periodically, like onBlur etc.
+		//
+		//		TODO: move declaration to MappedTextBox?
+		//		Problem is that ComboBox references displayedValue,
+		//		for benefit of FilteringSelect.
+		displayedValue: "",
+
+		_getDisplayedValueAttr: function(){
+			// summary:
+			//		Hook so get('displayedValue') works.
+			// description:
+			//		Returns the displayed value (what the user sees on the screen),
+			//		after filtering (ie, trimming spaces etc.).
+			//
+			//		For some subclasses of TextBox (like ComboBox), the displayed value
+			//		is different from the serialized value that's actually
+			//		sent to the server (see `dijit/form/ValidationTextBox.serialize()`)
+
+			// TODO: maybe we should update this.displayedValue on every keystroke so that we don't need
+			// this method
+			// TODO: this isn't really the displayed value when the user is typing
+			return this.filter(this.textbox.value);
+		},
+
+		_setDisplayedValueAttr: function(/*String*/ value){
+			// summary:
+			//		Hook so set('displayedValue', ...) works.
+			// description:
+			//		Sets the value of the visual element to the string "value".
+			//		The widget value is also set to a corresponding,
+			//		but not necessarily the same, value.
+
+			if(value == null /* or undefined */){
+				value = ''
+			}
+			else if(typeof value != "string"){
+				value = String(value)
+			}
+
+			this.textbox.value = value;
+
+			// sets the serialized value to something corresponding to specified displayedValue
+			// (if possible), and also updates the textbox.value, for example converting "123"
+			// to "123.00"
+			this._setValueAttr(this.get('value'), undefined);
+
+			this._set("displayedValue", this.get('displayedValue'));
+		},
+
+		format: function(value /*=====, constraints =====*/){
+			// summary:
+			//		Replaceable function to convert a value to a properly formatted string.
+			// value: String
+			// constraints: Object
+			// tags:
+			//		protected extension
+			return value == null /* or undefined */ ? "" : (value.toString ? value.toString() : value);
+		},
+
+		parse: function(value /*=====, constraints =====*/){
+			// summary:
+			//		Replaceable function to convert a formatted string to a value
+			// value: String
+			// constraints: Object
+			// tags:
+			//		protected extension
+
+			return value;	// String
+		},
+
+		_refreshState: function(){
+			// summary:
+			//		After the user types some characters, etc., this method is
+			//		called to check the field for validity etc.  The base method
+			//		in `dijit/form/TextBox` does nothing, but subclasses override.
+			// tags:
+			//		protected
+		},
+
+		 onInput: function(/*===== event =====*/){
+			 // summary:
+			 //		Connect to this function to receive notifications of various user data-input events.
+			 //		Return false to cancel the event and prevent it from being processed.
+			 // event:
+			 //		keydown | keypress | cut | paste | input
+			 // tags:
+			 //		callback
+		 },
+
+		__skipInputEvent: false,
+		_onInput: function(/*Event*/ evt){
+			// summary:
+			//		Called AFTER the input event has happened
+
+			this._processInput(evt);
+
+			if(this.intermediateChanges){
+				// allow the key to post to the widget input box
+				this.defer(function(){
+					this._handleOnChange(this.get('value'), false);
+				});
+			}
+		},
+
+		_processInput: function(/*Event*/ evt){
+			// summary:
+			//		Default action handler for user input events
+
+			this._refreshState();
+
+			// In case someone is watch()'ing for changes to displayedValue
+			this._set("displayedValue", this.get("displayedValue"));
+		},
+
+		postCreate: function(){
+			// setting the value here is needed since value="" in the template causes "undefined"
+			// and setting in the DOM (instead of the JS object) helps with form reset actions
+			this.textbox.setAttribute("value", this.textbox.value); // DOM and JS values should be the same
+
+			this.inherited(arguments);
+
+			// normalize input events to reduce spurious event processing
+			//	onkeydown: do not forward modifier keys
+			//		       set charOrCode to numeric keycode
+			//	onkeypress: do not forward numeric charOrCode keys (already sent through onkeydown)
+			//	onpaste & oncut: set charOrCode to 229 (IME)
+			//	oninput: if primary event not already processed, set charOrCode to 229 (IME), else do not forward
+			var handleEvent = function(e){
+				var charOrCode;
+				if(e.type == "keydown"){
+					charOrCode = e.keyCode;
+					switch(charOrCode){ // ignore state keys
+						case keys.SHIFT:
+						case keys.ALT:
+						case keys.CTRL:
+						case keys.META:
+						case keys.CAPS_LOCK:
+						case keys.NUM_LOCK:
+						case keys.SCROLL_LOCK:
+							return;
+					}
+					if(!e.ctrlKey && !e.metaKey && !e.altKey){ // no modifiers
+						switch(charOrCode){ // ignore location keys
+							case keys.NUMPAD_0:
+							case keys.NUMPAD_1:
+							case keys.NUMPAD_2:
+							case keys.NUMPAD_3:
+							case keys.NUMPAD_4:
+							case keys.NUMPAD_5:
+							case keys.NUMPAD_6:
+							case keys.NUMPAD_7:
+							case keys.NUMPAD_8:
+							case keys.NUMPAD_9:
+							case keys.NUMPAD_MULTIPLY:
+							case keys.NUMPAD_PLUS:
+							case keys.NUMPAD_ENTER:
+							case keys.NUMPAD_MINUS:
+							case keys.NUMPAD_PERIOD:
+							case keys.NUMPAD_DIVIDE:
+								return;
+						}
+						if((charOrCode >= 65 && charOrCode <= 90) || (charOrCode >= 48 && charOrCode <= 57) || charOrCode == keys.SPACE){
+							return; // keypress will handle simple non-modified printable keys
+						}
+						var named = false;
+						for(var i in keys){
+							if(keys[i] === e.keyCode){
+								named = true;
+								break;
+							}
+						}
+						if(!named){
+							return;
+						} // only allow named ones through
+					}
+				}
+				charOrCode = e.charCode >= 32 ? String.fromCharCode(e.charCode) : e.charCode;
+				if(!charOrCode){
+					charOrCode = (e.keyCode >= 65 && e.keyCode <= 90) || (e.keyCode >= 48 && e.keyCode <= 57) || e.keyCode == keys.SPACE ? String.fromCharCode(e.keyCode) : e.keyCode;
+				}
+				if(!charOrCode){
+					charOrCode = 229; // IME
+				}
+				if(e.type == "keypress"){
+					if(typeof charOrCode != "string"){
+						return;
+					}
+					if((charOrCode >= 'a' && charOrCode <= 'z') || (charOrCode >= 'A' && charOrCode <= 'Z') || (charOrCode >= '0' && charOrCode <= '9') || (charOrCode === ' ')){
+						if(e.ctrlKey || e.metaKey || e.altKey){
+							return;
+						} // can only be stopped reliably in keydown
+					}
+				}
+				if(e.type == "input"){
+					if(this.__skipInputEvent){ // duplicate event
+						this.__skipInputEvent = false;
+						return;
+					}
+				}else{
+					this.__skipInputEvent = true;
+				}
+				// create fake event to set charOrCode and to know if preventDefault() was called
+				var faux = { faux: true }, attr;
+				for(attr in e){
+					if(attr != "layerX" && attr != "layerY"){ // prevent WebKit warnings
+						var v = e[attr];
+						if(typeof v != "function" && typeof v != "undefined"){
+							faux[attr] = v;
+						}
+					}
+				}
+				lang.mixin(faux, {
+					charOrCode: charOrCode,
+					_wasConsumed: false,
+					preventDefault: function(){
+						faux._wasConsumed = true;
+						e.preventDefault();
+					},
+					stopPropagation: function(){
+						e.stopPropagation();
+					}
+				});
+				// give web page author a chance to consume the event
+				//console.log(faux.type + ', charOrCode = (' + (typeof charOrCode) + ') ' + charOrCode + ', ctrl ' + !!faux.ctrlKey + ', alt ' + !!faux.altKey + ', meta ' + !!faux.metaKey + ', shift ' + !!faux.shiftKey);
+				if(this.onInput(faux) === false){ // return false means stop
+					faux.preventDefault();
+					faux.stopPropagation();
+				}
+				if(faux._wasConsumed){
+					return;
+				} // if preventDefault was called
+				this.defer(function(){
+					this._onInput(faux);
+				}); // widget notification after key has posted
+				if(e.type == "keypress"){
+					e.stopPropagation(); // don't allow parents to stop printables from being typed
+				}
+			};
+			this.own(on(this.textbox, "keydown, keypress, paste, cut, input, compositionend", lang.hitch(this, handleEvent)));
+		},
+
+		_blankValue: '', // if the textbox is blank, what value should be reported
+		filter: function(val){
+			// summary:
+			//		Auto-corrections (such as trimming) that are applied to textbox
+			//		value on blur or form submit.
+			// description:
+			//		For MappedTextBox subclasses, this is called twice
+			//
+			//		- once with the display value
+			//		- once the value as set/returned by set('value', ...)
+			//
+			//		and get('value'), ex: a Number for NumberTextBox.
+			//
+			//		In the latter case it does corrections like converting null to NaN.  In
+			//		the former case the NumberTextBox.filter() method calls this.inherited()
+			//		to execute standard trimming code in TextBox.filter().
+			//
+			//		TODO: break this into two methods in 2.0
+			//
+			// tags:
+			//		protected extension
+			if(val === null){
+				return this._blankValue;
+			}
+			if(typeof val != "string"){
+				return val;
+			}
+			if(this.trim){
+				val = lang.trim(val);
+			}
+			if(this.uppercase){
+				val = val.toUpperCase();
+			}
+			if(this.lowercase){
+				val = val.toLowerCase();
+			}
+			if(this.propercase){
+				val = val.replace(/[^\s]+/g, function(word){
+					return word.substring(0, 1).toUpperCase() + word.substring(1);
+				});
+			}
+			return val;
+		},
+
+		_setBlurValue: function(){
+			// Format the displayed value, for example (for NumberTextBox) convert 1.4 to 1.400,
+			// or (for CurrencyTextBox) 2.50 to $2.50
+
+			this._setValueAttr(this.get('value'), true);
+		},
+
+		_onBlur: function(e){
+			if(this.disabled){
+				return;
+			}
+			this._setBlurValue();
+			this.inherited(arguments);
+		},
+
+		_isTextSelected: function(){
+			return this.textbox.selectionStart != this.textbox.selectionEnd;
+		},
+
+		_onFocus: function(/*String*/ by){
+			if(this.disabled || this.readOnly){
+				return;
+			}
+
+			// Select all text on focus via click if nothing already selected.
+			// Since mouse-up will clear the selection, need to defer selection until after mouse-up.
+			// Don't do anything on focus by tabbing into the widget since there's no associated mouse-up event.
+			if(this.selectOnClick && by == "mouse"){
+				// Use on.once() to only select all text on first click only; otherwise users would have no way to clear
+				// the selection.
+				this._selectOnClickHandle = on.once(this.domNode, "mouseup, touchend", lang.hitch(this, function(evt){
+					// Check if the user selected some text manually (mouse-down, mouse-move, mouse-up)
+					// and if not, then select all the text
+					if(!this._isTextSelected()){
+						_TextBoxMixin.selectInputText(this.textbox);
+					}
+				}));
+				this.own(this._selectOnClickHandle);
+
+				// in case the mouseup never comes
+				this.defer(function(){
+					if(this._selectOnClickHandle){
+						this._selectOnClickHandle.remove();
+						this._selectOnClickHandle = null;
+					}
+				}, 500); // if mouseup not received soon, then treat it as some gesture
+			}
+			// call this.inherited() before refreshState(), since this.inherited() will possibly scroll the viewport
+			// (to scroll the TextBox into view), which will affect how _refreshState() positions the tooltip
+			this.inherited(arguments);
+
+			this._refreshState();
+		},
+
+		reset: function(){
+			// Overrides `dijit/_FormWidget/reset()`.
+			// Additionally resets the displayed textbox value to ''
+			this.textbox.value = '';
+			this.inherited(arguments);
+		}
+	});
+
+	if(has("dojo-bidi")){
+		_TextBoxMixin = declare("dijit.form._TextBoxMixin", _TextBoxMixin, {
+			_setValueAttr: function(){
+				this.inherited(arguments);
+				this.applyTextDir(this.focusNode);
+			},
+			_setDisplayedValueAttr: function(){
+				this.inherited(arguments);
+				this.applyTextDir(this.focusNode);
+			},
+			_onInput: function(){
+				this.applyTextDir(this.focusNode);
+				this.inherited(arguments);
+			}
+		});
+	}
+
+	_TextBoxMixin._setSelectionRange = dijit._setSelectionRange = function(/*DomNode*/ element, /*Number?*/ start, /*Number?*/ stop){
+		if(element.setSelectionRange){
+			element.setSelectionRange(start, stop);
+		}
+	};
+
+	_TextBoxMixin.selectInputText = dijit.selectInputText = function(/*DomNode*/ element, /*Number?*/ start, /*Number?*/ stop){
+		// summary:
+		//		Select text in the input element argument, from start (default 0), to stop (default end).
+
+		// TODO: use functions in _editor/selection.js?
+		element = dom.byId(element);
+		if(isNaN(start)){
+			start = 0;
+		}
+		if(isNaN(stop)){
+			stop = element.value ? element.value.length : 0;
+		}
+		try{
+			element.focus();
+			_TextBoxMixin._setSelectionRange(element, start, stop);
+		}catch(e){ /* squelch random errors (esp. on IE) from unexpected focus changes or DOM nodes being hidden */
+		}
+	};
+
+	return _TextBoxMixin;
+});
diff --git a/dijit/form/_ToggleButtonMixin.js b/dijit/form/_ToggleButtonMixin.js
index 4440984..f7fcf23 100644
--- a/dijit/form/_ToggleButtonMixin.js
+++ b/dijit/form/_ToggleButtonMixin.js
@@ -3,49 +3,61 @@ define([
 	"dojo/dom-attr" // domAttr.set
 ], function(declare, domAttr){
 
-// module:
-//		dijit/form/_ToggleButtonMixin
-// summary:
-//		A mixin to provide functionality to allow a button that can be in two states (checked or not).
-
-return declare("dijit.form._ToggleButtonMixin", null, {
-	// summary:
-	//		A mixin to provide functionality to allow a button that can be in two states (checked or not).
-
-	// checked: Boolean
-	//		Corresponds to the native HTML <input> element's attribute.
-	//		In markup, specified as "checked='checked'" or just "checked".
-	//		True if the button is depressed, or the checkbox is checked,
-	//		or the radio button is selected, etc.
-	checked: false,
-
-	// aria-pressed for toggle buttons, and aria-checked for checkboxes
-	_aria_attr: "aria-pressed",
-
-	_onClick: function(/*Event*/ evt){
-		var original = this.checked;
-		this._set('checked', !original); // partially set the toggled value, assuming the toggle will work, so it can be overridden in the onclick handler
-		var ret = this.inherited(arguments); // the user could reset the value here
-		this.set('checked', ret ? this.checked : original); // officially set the toggled or user value, or reset it back
-		return ret;
-	},
-
-	_setCheckedAttr: function(/*Boolean*/ value, /*Boolean?*/ priorityChange){
-		this._set("checked", value);
-		domAttr.set(this.focusNode || this.domNode, "checked", value);
-		(this.focusNode || this.domNode).setAttribute(this._aria_attr, value ? "true" : "false"); // aria values should be strings
-		this._handleOnChange(value, priorityChange);
-	},
-
-	reset: function(){
-		// summary:
-		//		Reset the widget's value to what it was at initialization time
-
-		this._hasBeenBlurred = false;
-
-		// set checked state to original setting
-		this.set('checked', this.params.checked || false);
-	}
-});
+	// module:
+	//		dijit/form/_ToggleButtonMixin
 
+	return declare("dijit.form._ToggleButtonMixin", null, {
+		// summary:
+		//		A mixin to provide functionality to allow a button that can be in two states (checked or not).
+
+		// checked: Boolean
+		//		Corresponds to the native HTML `<input>` element's attribute.
+		//		In markup, specified as "checked='checked'" or just "checked".
+		//		True if the button is depressed, or the checkbox is checked,
+		//		or the radio button is selected, etc.
+		checked: false,
+
+		// aria-pressed for toggle buttons, and aria-checked for checkboxes
+		_aria_attr: "aria-pressed",
+
+		_onClick: function(/*Event*/ evt){
+			var original = this.checked;
+			this._set('checked', !original); // partially set the toggled value, assuming the toggle will work, so it can be overridden in the onclick handler
+			var ret = this.inherited(arguments); // the user could reset the value here
+			this.set('checked', ret ? this.checked : original); // officially set the toggled or user value, or reset it back
+			return ret;
+		},
+
+		_setCheckedAttr: function(/*Boolean*/ value, /*Boolean?*/ priorityChange){
+			this._set("checked", value);
+			var node = this.focusNode || this.domNode;
+			if(this._created){ // IE is not ready to handle checked attribute (affects tab order)
+				// needlessly setting "checked" upsets IE's tab order
+				if(domAttr.get(node, "checked") != !!value){
+					domAttr.set(node, "checked", !!value); // "mixed" -> true
+				}
+			}
+			node.setAttribute(this._aria_attr, String(value)); // aria values should be strings
+			this._handleOnChange(value, priorityChange);
+		},
+
+		postCreate: function(){ // use postCreate instead of startup so users forgetting to call startup are OK
+			this.inherited(arguments);
+			var node = this.focusNode || this.domNode;
+			if(this.checked){
+				// need this here instead of on the template so IE8 tab order works
+				node.setAttribute('checked', 'checked');
+			}
+		},
+
+		reset: function(){
+			// summary:
+			//		Reset the widget's value to what it was at initialization time
+
+			this._hasBeenBlurred = false;
+
+			// set checked state to original setting
+			this.set('checked', this.params.checked || false);
+		}
+	});
 });
diff --git a/dijit/form/nls/ComboBox.js b/dijit/form/nls/ComboBox.js
index 90ce9d3..47d0f82 100644
--- a/dijit/form/nls/ComboBox.js
+++ b/dijit/form/nls/ComboBox.js
@@ -8,6 +8,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -35,6 +36,7 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dijit/form/nls/Textarea.js b/dijit/form/nls/Textarea.js
index 20d4253..3eb3781 100644
--- a/dijit/form/nls/Textarea.js
+++ b/dijit/form/nls/Textarea.js
@@ -11,6 +11,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -38,6 +39,7 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dijit/form/nls/ar/ComboBox.js b/dijit/form/nls/ar/ComboBox.js
index 1be1bd9..b386667 100644
--- a/dijit/form/nls/ar/ComboBox.js
+++ b/dijit/form/nls/ar/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "الاختيارات السابقة",
 		nextMessage: "مزيد من الاختيارات"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/ar/Textarea.js b/dijit/form/nls/ar/Textarea.js
index 3987f40..cf1cb7f 100644
--- a/dijit/form/nls/ar/Textarea.js
+++ b/dijit/form/nls/ar/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'مساحة التحرير',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'اطار مساحة التحرير'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/ar/validate.js b/dijit/form/nls/ar/validate.js
index 4c88bdb..0ed6df1 100644
--- a/dijit/form/nls/ar/validate.js
+++ b/dijit/form/nls/ar/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "القيمة التي تم ادخالها غير صحيحة.",
 	missingMessage: "يجب ادخال هذه القيمة.",
 	rangeMessage: "هذه القيمة ليس بالمدى الصحيح."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/az/ComboBox.js b/dijit/form/nls/az/ComboBox.js
index ab67dfe..fb3526c 100644
--- a/dijit/form/nls/az/ComboBox.js
+++ b/dijit/form/nls/az/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"previousMessage" : "Əvvəlki variantlar",
 	"nextMessage" : "Başqa variantlar"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/az/Textarea.js b/dijit/form/nls/az/Textarea.js
index f99b83a..563a245 100644
--- a/dijit/form/nls/az/Textarea.js
+++ b/dijit/form/nls/az/Textarea.js
@@ -1,8 +1,7 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	"iframeEditTitle" : "Redaktə sahəsi",
 	"iframeFocusTitle" : "Redaktə sahəsi çərçivəsi"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/az/validate.js b/dijit/form/nls/az/validate.js
index 9040e5f..f2478f6 100644
--- a/dijit/form/nls/az/validate.js
+++ b/dijit/form/nls/az/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	"rangeMessage" : "Bu dəyər aralıq xaricində.",
 	"invalidMessage" : "Girilən dəyər keçərli deyil.",
 	"missingMessage" : "Bu deyər lazımlı."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/bg/ComboBox.js b/dijit/form/nls/bg/ComboBox.js
new file mode 100644
index 0000000..b0bf13f
--- /dev/null
+++ b/dijit/form/nls/bg/ComboBox.js
@@ -0,0 +1,6 @@
+define(
+({
+	previousMessage: "Предишни избори",
+	nextMessage: "Повече избори"
+})
+);
diff --git a/dijit/form/nls/bg/Textarea.js b/dijit/form/nls/bg/Textarea.js
new file mode 100644
index 0000000..d571dc5
--- /dev/null
+++ b/dijit/form/nls/bg/Textarea.js
@@ -0,0 +1,9 @@
+define(
+// used by both the editor and textarea widgets to provide information to screen reader users
+({
+	iframeEditTitle: 'зона за редактиране',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
+	iframeFocusTitle: 'рамка на зоната за редактиране'  // secondary title for editable IFRAME when focus is on outer container
+	//  to let user know that focus has moved out of editing area and to the
+	//  parent element of the editing area
+})
+);
diff --git a/dijit/form/nls/bg/validate.js b/dijit/form/nls/bg/validate.js
new file mode 100644
index 0000000..c25e121
--- /dev/null
+++ b/dijit/form/nls/bg/validate.js
@@ -0,0 +1,7 @@
+define(
+({
+	invalidMessage: "Въведената стойност е невалидна.",
+	missingMessage: "Тази стойност се изисква.",
+	rangeMessage: "Тази стойност е извън обхват."
+})
+);
diff --git a/dijit/form/nls/ca/ComboBox.js b/dijit/form/nls/ca/ComboBox.js
index 24b685e..837fb01 100644
--- a/dijit/form/nls/ca/ComboBox.js
+++ b/dijit/form/nls/ca/ComboBox.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Opcions anteriors",
 		nextMessage: "Més opcions"
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/ca/Textarea.js b/dijit/form/nls/ca/Textarea.js
index 7b4f9d6..e7ccfaa 100644
--- a/dijit/form/nls/ca/Textarea.js
+++ b/dijit/form/nls/ca/Textarea.js
@@ -1,12 +1,9 @@
 define(
-//begin v1.x content
-/* used by both the editor and textarea widgets to provide information to screen reader users */
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'àrea d\'edició',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'Marc de l\'àrea d\'edició'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/ca/validate.js b/dijit/form/nls/ca/validate.js
index 7629f97..a4c43f1 100644
--- a/dijit/form/nls/ca/validate.js
+++ b/dijit/form/nls/ca/validate.js
@@ -1,10 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "El valor introduït no és vàlid",
 	missingMessage: "Aquest valor és necessari",
 	rangeMessage: "Aquest valor és fora de l'interval"
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/cs/ComboBox.js b/dijit/form/nls/cs/ComboBox.js
index e86b1b0..901f9d6 100644
--- a/dijit/form/nls/cs/ComboBox.js
+++ b/dijit/form/nls/cs/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Předchozí volby",
 		nextMessage: "Další volby"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/cs/Textarea.js b/dijit/form/nls/cs/Textarea.js
index 5896983..185a195 100644
--- a/dijit/form/nls/cs/Textarea.js
+++ b/dijit/form/nls/cs/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'oblast úprav',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'rámec oblasti úprav'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/cs/validate.js b/dijit/form/nls/cs/validate.js
index 6dd8c95..725186b 100644
--- a/dijit/form/nls/cs/validate.js
+++ b/dijit/form/nls/cs/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Zadaná hodnota není platná.",
 	missingMessage: "Tato hodnota je vyžadována.",
 	rangeMessage: "Tato hodnota je mimo rozsah."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/da/ComboBox.js b/dijit/form/nls/da/ComboBox.js
index 9bbacaf..91c1a0f 100644
--- a/dijit/form/nls/da/ComboBox.js
+++ b/dijit/form/nls/da/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Forrige valg",
 		nextMessage: "Flere valg"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/da/Textarea.js b/dijit/form/nls/da/Textarea.js
index 6faa493..c7be129 100644
--- a/dijit/form/nls/da/Textarea.js
+++ b/dijit/form/nls/da/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'redigeringsområde',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'ramme om redigeringsområde'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/da/validate.js b/dijit/form/nls/da/validate.js
index 9307b48..d18f8d8 100644
--- a/dijit/form/nls/da/validate.js
+++ b/dijit/form/nls/da/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
-	invalidMessage: "Den angivne værdi er ikke gyldig.",
+	invalidMessage: "Den angivne værdi er ugyldig.",
 	missingMessage: "Værdien er påkrævet.",
 	rangeMessage: "Værdien er uden for intervallet."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/de/ComboBox.js b/dijit/form/nls/de/ComboBox.js
index 0e2dd48..fccc2d6 100644
--- a/dijit/form/nls/de/ComboBox.js
+++ b/dijit/form/nls/de/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Vorherige Auswahl",
 		nextMessage: "Weitere Auswahlmöglichkeiten"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/de/Textarea.js b/dijit/form/nls/de/Textarea.js
index ed22a38..3494200 100644
--- a/dijit/form/nls/de/Textarea.js
+++ b/dijit/form/nls/de/Textarea.js
@@ -1,11 +1,9 @@
 define(
-//begin v1.x content
-/* used by both the editor and textarea widgets to provide information to screen reader users */
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'Editierbereich',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'Rahmen für Editierbereich'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/de/validate.js b/dijit/form/nls/de/validate.js
index 79346f8..947fcdf 100755
--- a/dijit/form/nls/de/validate.js
+++ b/dijit/form/nls/de/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Der eingegebene Wert ist ungültig. ",
 	missingMessage: "Dieser Wert ist erforderlich.",
 	rangeMessage: "Dieser Wert liegt außerhalb des gültigen Bereichs. "
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/el/ComboBox.js b/dijit/form/nls/el/ComboBox.js
index 06871ad..18535f6 100644
--- a/dijit/form/nls/el/ComboBox.js
+++ b/dijit/form/nls/el/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Προηγούμενες επιλογές",
 		nextMessage: "Περισσότερες επιλογές"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/el/Textarea.js b/dijit/form/nls/el/Textarea.js
index 11814ae..493dd29 100644
--- a/dijit/form/nls/el/Textarea.js
+++ b/dijit/form/nls/el/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'περιοχή επεξεργασίας',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'πλαίσιο περιοχής επεξεργασίας'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/el/validate.js b/dijit/form/nls/el/validate.js
index 8b61b80..cdee696 100644
--- a/dijit/form/nls/el/validate.js
+++ b/dijit/form/nls/el/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Η τιμή που καταχωρήσατε δεν είναι έγκυρη.",
 	missingMessage: "Η τιμή αυτή πρέπει απαραίτητα να καθοριστεί.",
 	rangeMessage: "Η τιμή αυτή δεν ανήκει στο εύρος έγκυρων τιμών."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/es/ComboBox.js b/dijit/form/nls/es/ComboBox.js
index 2d7705a..5c8198b 100644
--- a/dijit/form/nls/es/ComboBox.js
+++ b/dijit/form/nls/es/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Opciones anteriores",
 		nextMessage: "Más opciones"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/es/Textarea.js b/dijit/form/nls/es/Textarea.js
index b4f8e92..6bf2c77 100644
--- a/dijit/form/nls/es/Textarea.js
+++ b/dijit/form/nls/es/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'área de edición',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'marco del área de edición'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/es/validate.js b/dijit/form/nls/es/validate.js
index e880327..d23a1a7 100644
--- a/dijit/form/nls/es/validate.js
+++ b/dijit/form/nls/es/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "El valor especificado no es válido.",
 	missingMessage: "Este valor es necesario.",
 	rangeMessage: "Este valor está fuera del intervalo."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/fi/ComboBox.js b/dijit/form/nls/fi/ComboBox.js
index 4ad1f81..80ad09d 100644
--- a/dijit/form/nls/fi/ComboBox.js
+++ b/dijit/form/nls/fi/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Edelliset valinnat",
 		nextMessage: "Lisää valintoja"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/fi/Textarea.js b/dijit/form/nls/fi/Textarea.js
index d43eb74..78486fe 100644
--- a/dijit/form/nls/fi/Textarea.js
+++ b/dijit/form/nls/fi/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'muokkausalue',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'muokkausalueen kehys'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/fi/validate.js b/dijit/form/nls/fi/validate.js
index 2bf7676..cc8f2b9 100644
--- a/dijit/form/nls/fi/validate.js
+++ b/dijit/form/nls/fi/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Annettu arvo ei kelpaa.",
 	missingMessage: "Tämä arvo on pakollinen.",
 	rangeMessage: "Tämä arvo on sallitun alueen ulkopuolella."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/fr/ComboBox.js b/dijit/form/nls/fr/ComboBox.js
index 04f4184..9b6aa1c 100644
--- a/dijit/form/nls/fr/ComboBox.js
+++ b/dijit/form/nls/fr/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Choix précédents",
 		nextMessage: "Plus de choix"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/fr/Textarea.js b/dijit/form/nls/fr/Textarea.js
index 3d8c993..aea2e02 100644
--- a/dijit/form/nls/fr/Textarea.js
+++ b/dijit/form/nls/fr/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
-	iframeEditTitle: "zone d'édition",  // primary title for editable IFRAME, for screen readers when focus is in the editing area
-	iframeFocusTitle: "cadre de la zone d'édition"  // secondary title for editable IFRAME when focus is on outer container
+	iframeEditTitle: 'zone d\'édition',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
+	iframeFocusTitle: 'cadre de la zone d\'édition'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/fr/validate.js b/dijit/form/nls/fr/validate.js
index 20981aa..dbc07fd 100644
--- a/dijit/form/nls/fr/validate.js
+++ b/dijit/form/nls/fr/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "La valeur indiquée n'est pas correcte.",
 	missingMessage: "Cette valeur est requise.",
 	rangeMessage: "Cette valeur n'est pas comprise dans la plage autorisée."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/he/ComboBox.js b/dijit/form/nls/he/ComboBox.js
index 754b0f6..2341def 100644
--- a/dijit/form/nls/he/ComboBox.js
+++ b/dijit/form/nls/he/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "האפשרויות הקודמות",
 		nextMessage: "אפשרויות נוספות"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/he/Textarea.js b/dijit/form/nls/he/Textarea.js
index 35ac734..9ab626e 100644
--- a/dijit/form/nls/he/Textarea.js
+++ b/dijit/form/nls/he/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'אזור עריכה',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'מסגרת אזור עריכה'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/he/validate.js b/dijit/form/nls/he/validate.js
index 1be970a..96d1d50 100644
--- a/dijit/form/nls/he/validate.js
+++ b/dijit/form/nls/he/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "הערך שצוין אינו חוקי.",
 	missingMessage: "זהו ערך דרוש.",
 	rangeMessage: "הערך מחוץ לטווח."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/hu/ComboBox.js b/dijit/form/nls/hu/ComboBox.js
index 05f5149..5e28de9 100644
--- a/dijit/form/nls/hu/ComboBox.js
+++ b/dijit/form/nls/hu/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Előző menüpontok",
 		nextMessage: "További menüpontok"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/hu/Textarea.js b/dijit/form/nls/hu/Textarea.js
index e8f3b8e..ba2c065 100644
--- a/dijit/form/nls/hu/Textarea.js
+++ b/dijit/form/nls/hu/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'szerkesztési terület',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'szerkesztési terület keret'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/hu/validate.js b/dijit/form/nls/hu/validate.js
index a2a9e15..e1449e9 100644
--- a/dijit/form/nls/hu/validate.js
+++ b/dijit/form/nls/hu/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "A megadott érték érvénytelen.",
 	missingMessage: "Meg kell adni egy értéket.",
 	rangeMessage: "Az érték kívül van a megengedett tartományon."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/it/ComboBox.js b/dijit/form/nls/it/ComboBox.js
index 4d0a32e..2aa200f 100644
--- a/dijit/form/nls/it/ComboBox.js
+++ b/dijit/form/nls/it/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Scelte precedenti",
-		nextMessage: "Altre scelte"
+		nextMessage: "Scelte successive"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/it/Textarea.js b/dijit/form/nls/it/Textarea.js
index 5b05d18..5da4f6b 100644
--- a/dijit/form/nls/it/Textarea.js
+++ b/dijit/form/nls/it/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'modifica area',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'modifica frame area'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/it/validate.js b/dijit/form/nls/it/validate.js
index d299f4b..659da63 100644
--- a/dijit/form/nls/it/validate.js
+++ b/dijit/form/nls/it/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Il valore immesso non è valido.",
 	missingMessage: "Questo valore è obbligatorio.",
-	rangeMessage: "Questo valore non è compreso nell'intervallo."
+	rangeMessage: "Questo valore è fuori dall'intervallo consentito."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/ja/ComboBox.js b/dijit/form/nls/ja/ComboBox.js
index 9ffe040..c173831 100644
--- a/dijit/form/nls/ja/ComboBox.js
+++ b/dijit/form/nls/ja/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "以前の選択項目",
 		nextMessage: "追加の選択項目"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/ja/Textarea.js b/dijit/form/nls/ja/Textarea.js
index 08a93a0..8a71482 100644
--- a/dijit/form/nls/ja/Textarea.js
+++ b/dijit/form/nls/ja/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: '編集域',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: '編集域フレーム'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/ja/validate.js b/dijit/form/nls/ja/validate.js
index 21b323c..cafeb18 100644
--- a/dijit/form/nls/ja/validate.js
+++ b/dijit/form/nls/ja/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "入力した値は無効です。",
 	missingMessage: "この値は必須です。",
 	rangeMessage: "この値は範囲外です。"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/kk/ComboBox.js b/dijit/form/nls/kk/ComboBox.js
index e287206..3a91db7 100644
--- a/dijit/form/nls/kk/ComboBox.js
+++ b/dijit/form/nls/kk/ComboBox.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Алдыңғы нұсқалар",
 		nextMessage: "Басқа нұсқалар"
 })
-//end v1.x content
 );
-
diff --git a/dijit/form/nls/kk/Textarea.js b/dijit/form/nls/kk/Textarea.js
index 2f28cd5..ec43490 100644
--- a/dijit/form/nls/kk/Textarea.js
+++ b/dijit/form/nls/kk/Textarea.js
@@ -1,12 +1,9 @@
 define(
-//begin v1.x content
-/* used by both the editor and textarea widgets to provide information to screen reader users */
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'өңдеу аумағы',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'өңдеу аумағының жақтауы'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
-
diff --git a/dijit/form/nls/kk/validate.js b/dijit/form/nls/kk/validate.js
index 16973a8..97b1240 100644
--- a/dijit/form/nls/kk/validate.js
+++ b/dijit/form/nls/kk/validate.js
@@ -1,10 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Енгізілген мән жарамды емес.",
 	missingMessage: "Бұл мән міндетті.",
 	rangeMessage: "Бұл мән ауқымнан тыс."
 })
-//end v1.x content
 );
-
diff --git a/dijit/form/nls/ko/ComboBox.js b/dijit/form/nls/ko/ComboBox.js
index f2ee413..7ea1188 100644
--- a/dijit/form/nls/ko/ComboBox.js
+++ b/dijit/form/nls/ko/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "이전 선택사항",
 		nextMessage: "기타 선택사항"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/ko/Textarea.js b/dijit/form/nls/ko/Textarea.js
index de203c1..3cbe451 100644
--- a/dijit/form/nls/ko/Textarea.js
+++ b/dijit/form/nls/ko/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: '편집 영역',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: '편집 영역 프레임'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/ko/validate.js b/dijit/form/nls/ko/validate.js
index eaa460f..062171e 100644
--- a/dijit/form/nls/ko/validate.js
+++ b/dijit/form/nls/ko/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "입력된 값이 올바르지 않습니다.",
 	missingMessage: "이 값은 필수입니다.",
 	rangeMessage: "이 값은 범위를 벗어납니다."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/nb/ComboBox.js b/dijit/form/nls/nb/ComboBox.js
index a9c25d8..ab88075 100644
--- a/dijit/form/nls/nb/ComboBox.js
+++ b/dijit/form/nls/nb/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Tidligere valg",
 		nextMessage: "Flere valg"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/nb/Textarea.js b/dijit/form/nls/nb/Textarea.js
index 3026a3d..54042b3 100644
--- a/dijit/form/nls/nb/Textarea.js
+++ b/dijit/form/nls/nb/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'redigeringsområde',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'ramme for redigeringsområde'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/nb/validate.js b/dijit/form/nls/nb/validate.js
index db548a8..d13d55e 100644
--- a/dijit/form/nls/nb/validate.js
+++ b/dijit/form/nls/nb/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Den angitte verdien er ikke gyldig.",
 	missingMessage: "Denne verdien er obligatorisk.",
 	rangeMessage: "Denne verdien er utenfor gyldig område."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/nl/ComboBox.js b/dijit/form/nls/nl/ComboBox.js
index 2c1d351..301c44a 100644
--- a/dijit/form/nls/nl/ComboBox.js
+++ b/dijit/form/nls/nl/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Eerdere opties",
 		nextMessage: "Meer opties"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/nl/Textarea.js b/dijit/form/nls/nl/Textarea.js
index b24553f..83573fb 100644
--- a/dijit/form/nls/nl/Textarea.js
+++ b/dijit/form/nls/nl/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'veld bewerken',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'veldkader bewerken'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/nl/validate.js b/dijit/form/nls/nl/validate.js
index 513b7a3..ab86fe9 100644
--- a/dijit/form/nls/nl/validate.js
+++ b/dijit/form/nls/nl/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "De opgegeven waarde is ongeldig.",
 	missingMessage: "Deze waarde is verplicht.",
 	rangeMessage: "Deze waarde is niet toegestaan."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/pl/ComboBox.js b/dijit/form/nls/pl/ComboBox.js
index 842b14d..1c02bf0 100644
--- a/dijit/form/nls/pl/ComboBox.js
+++ b/dijit/form/nls/pl/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Poprzednie wybory",
 		nextMessage: "Więcej wyborów"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/pl/Textarea.js b/dijit/form/nls/pl/Textarea.js
index d1d4b94..d231bba 100644
--- a/dijit/form/nls/pl/Textarea.js
+++ b/dijit/form/nls/pl/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'edycja obszaru',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'edycja ramki obszaru'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/pl/validate.js b/dijit/form/nls/pl/validate.js
index fcf3f09..3646632 100644
--- a/dijit/form/nls/pl/validate.js
+++ b/dijit/form/nls/pl/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
-	invalidMessage: "Wprowadzona wartość jest niepoprawna.",
+	invalidMessage: "Wprowadzona wartość jest nieprawidłowa.",
 	missingMessage: "Ta wartość jest wymagana.",
 	rangeMessage: "Ta wartość jest spoza zakresu."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/pt-pt/ComboBox.js b/dijit/form/nls/pt-pt/ComboBox.js
index dbd0c4c..e051cee 100644
--- a/dijit/form/nls/pt-pt/ComboBox.js
+++ b/dijit/form/nls/pt-pt/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Opções anteriores",
 		nextMessage: "Mais opções"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/pt-pt/Textarea.js b/dijit/form/nls/pt-pt/Textarea.js
index 3686878..faeb156 100644
--- a/dijit/form/nls/pt-pt/Textarea.js
+++ b/dijit/form/nls/pt-pt/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'área de edição',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'painel da área de edição'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/pt-pt/validate.js b/dijit/form/nls/pt-pt/validate.js
index cd99891..cd20691 100644
--- a/dijit/form/nls/pt-pt/validate.js
+++ b/dijit/form/nls/pt-pt/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "O valor introduzido não é válido.",
 	missingMessage: "Este valor é requerido.",
 	rangeMessage: "Este valor encontra-se fora do intervalo."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/pt/ComboBox.js b/dijit/form/nls/pt/ComboBox.js
index dbd0c4c..e051cee 100644
--- a/dijit/form/nls/pt/ComboBox.js
+++ b/dijit/form/nls/pt/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Opções anteriores",
 		nextMessage: "Mais opções"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/pt/Textarea.js b/dijit/form/nls/pt/Textarea.js
index 7eb9f8b..f73ee86 100644
--- a/dijit/form/nls/pt/Textarea.js
+++ b/dijit/form/nls/pt/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'editar área',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'editar quadro da área'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/pt/validate.js b/dijit/form/nls/pt/validate.js
index beb20fa..ec91267 100644
--- a/dijit/form/nls/pt/validate.js
+++ b/dijit/form/nls/pt/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "O valor inserido não é válido.",
 	missingMessage: "Este valor é necessário.",
 	rangeMessage: "Este valor está fora do intervalo. "
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/ro/ComboBox.js b/dijit/form/nls/ro/ComboBox.js
index 2783f4d..4824dee 100644
--- a/dijit/form/nls/ro/ComboBox.js
+++ b/dijit/form/nls/ro/ComboBox.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Alegeri anterioare",
 		nextMessage: "Mai multe alegeri"
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/ro/Textarea.js b/dijit/form/nls/ro/Textarea.js
index 1f29ba1..69f8f1d 100644
--- a/dijit/form/nls/ro/Textarea.js
+++ b/dijit/form/nls/ro/Textarea.js
@@ -1,12 +1,9 @@
 define(
-//begin v1.x content
-/* used by both the editor and textarea widgets to provide information to screen reader users */
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'zonă de editare',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'cadru zonă de editare'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/ro/validate.js b/dijit/form/nls/ro/validate.js
index 83c7997..9f7183f 100644
--- a/dijit/form/nls/ro/validate.js
+++ b/dijit/form/nls/ro/validate.js
@@ -1,10 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Valoarea introdusă nu este validă.",
 	missingMessage: "Această valoare este necesară.",
 	rangeMessage: "Această valoare este în afara intervalului. "
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/ru/ComboBox.js b/dijit/form/nls/ru/ComboBox.js
index f042314..d474ac7 100644
--- a/dijit/form/nls/ru/ComboBox.js
+++ b/dijit/form/nls/ru/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Предыдущие варианты",
 		nextMessage: "Следующие варианты"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/ru/Textarea.js b/dijit/form/nls/ru/Textarea.js
index 8e7f05a..8eda38e 100644
--- a/dijit/form/nls/ru/Textarea.js
+++ b/dijit/form/nls/ru/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'область редактирования',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'фрейм области редактирования'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/ru/validate.js b/dijit/form/nls/ru/validate.js
index 0ac668d..6b8e579 100644
--- a/dijit/form/nls/ru/validate.js
+++ b/dijit/form/nls/ru/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Указано недопустимое значение.",
 	missingMessage: "Это обязательное значение.",
 	rangeMessage: "Это значение вне диапазона."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/sk/ComboBox.js b/dijit/form/nls/sk/ComboBox.js
index f6bfe11..ccead72 100644
--- a/dijit/form/nls/sk/ComboBox.js
+++ b/dijit/form/nls/sk/ComboBox.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
-		previousMessage: "Predchádzajúce voľby",
-		nextMessage: "Ďalšie voľby"
+		previousMessage: "Predchádzajúce možnosti",
+		nextMessage: "Viac možností"
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/sk/Textarea.js b/dijit/form/nls/sk/Textarea.js
index 4a3e584..43408b2 100644
--- a/dijit/form/nls/sk/Textarea.js
+++ b/dijit/form/nls/sk/Textarea.js
@@ -1,12 +1,9 @@
 define(
-//begin v1.x content
-/* used by both the editor and textarea widgets to provide information to screen reader users */
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'upraviť oblasť',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
-	iframeFocusTitle: 'upraviť rám oblasti'  // secondary title for editable IFRAME when focus is on outer container
+	iframeFocusTitle: 'upraviť rámec oblasti'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/sk/validate.js b/dijit/form/nls/sk/validate.js
index 47fa3a4..f45138b 100644
--- a/dijit/form/nls/sk/validate.js
+++ b/dijit/form/nls/sk/validate.js
@@ -1,10 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Zadaná hodnota nie je platná.",
-	missingMessage: "Táto hodnota je vyžadovaná.",
+	missingMessage: "Táto hodnota je povinná.",
 	rangeMessage: "Táto hodnota je mimo rozsah."
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/sl/ComboBox.js b/dijit/form/nls/sl/ComboBox.js
index 187ba78..fcf38c6 100644
--- a/dijit/form/nls/sl/ComboBox.js
+++ b/dijit/form/nls/sl/ComboBox.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Prejšnje izbire",
 		nextMessage: "Dodatne izbire"
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/sl/Textarea.js b/dijit/form/nls/sl/Textarea.js
index 1e023cb..54fc8eb 100644
--- a/dijit/form/nls/sl/Textarea.js
+++ b/dijit/form/nls/sl/Textarea.js
@@ -1,12 +1,9 @@
 define(
-//begin v1.x content
-/* used by both the editor and textarea widgets to provide information to screen reader users */
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'urejevalno področje',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'okvir urejevalnega področja'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/sl/validate.js b/dijit/form/nls/sl/validate.js
index 88b79ae..74c3c52 100644
--- a/dijit/form/nls/sl/validate.js
+++ b/dijit/form/nls/sl/validate.js
@@ -1,10 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Vnesena vrednost ni veljavna.",
 	missingMessage: "Ta vrednost je zahtevana.",
 	rangeMessage: "Ta vrednost je izven območja."
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/sv/ComboBox.js b/dijit/form/nls/sv/ComboBox.js
index 6abcf1f..a12c29a 100644
--- a/dijit/form/nls/sv/ComboBox.js
+++ b/dijit/form/nls/sv/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
-		previousMessage: "Föregående alternativ",
-		nextMessage: "Fler alternativ"
+		previousMessage: "Tidigare val",
+		nextMessage: "Fler val"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/sv/Textarea.js b/dijit/form/nls/sv/Textarea.js
index 8ad63d6..74fcb6b 100644
--- a/dijit/form/nls/sv/Textarea.js
+++ b/dijit/form/nls/sv/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'redigeringsområde',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'redigeringsområdesram'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/sv/validate.js b/dijit/form/nls/sv/validate.js
index 0ebf0ef..cdf0816 100644
--- a/dijit/form/nls/sv/validate.js
+++ b/dijit/form/nls/sv/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
-	invalidMessage: "Det angivna värdet är ogiltigt.",
-	missingMessage: "Värdet är obligatoriskt.",
-	rangeMessage: "Värdet är utanför intervallet."
+	invalidMessage: "Angivet värde är inte giltigt.",
+	missingMessage: "Värdet krävs.",
+	rangeMessage: "Värdet ligger utanför intervallet."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/th/ComboBox.js b/dijit/form/nls/th/ComboBox.js
index 48b5daa..f130a80 100644
--- a/dijit/form/nls/th/ComboBox.js
+++ b/dijit/form/nls/th/ComboBox.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "การเลือกก่อนหน้า",
 		nextMessage: "การเลือกเพิ่มเติม"
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/th/Textarea.js b/dijit/form/nls/th/Textarea.js
index 4907e45..24f2df1 100644
--- a/dijit/form/nls/th/Textarea.js
+++ b/dijit/form/nls/th/Textarea.js
@@ -1,12 +1,9 @@
 define(
-//begin v1.x content
-/* used by both the editor and textarea widgets to provide information to screen reader users */
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
-	iframeEditTitle: 'แก้ไขพื้นที่',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
-	iframeFocusTitle: 'แก้ไขกรอบพื้นที่'  // secondary title for editable IFRAME when focus is on outer container
+	iframeEditTitle: 'พื้นที่แก้ไข',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
+	iframeFocusTitle: 'กรอบพื้นที่แก้ไข'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/th/validate.js b/dijit/form/nls/th/validate.js
index 8cc7e32..2dceb9f 100644
--- a/dijit/form/nls/th/validate.js
+++ b/dijit/form/nls/th/validate.js
@@ -1,10 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "ค่าที่ป้อนไม่ถูกต้อง",
 	missingMessage: "จำเป็นต้องมีค่านี้",
 	rangeMessage: "ค่านี้เกินช่วง"
 })
-
-//end v1.x content
 );
diff --git a/dijit/form/nls/tr/ComboBox.js b/dijit/form/nls/tr/ComboBox.js
index 85a78d2..7481b63 100644
--- a/dijit/form/nls/tr/ComboBox.js
+++ b/dijit/form/nls/tr/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "Önceki seçenekler",
 		nextMessage: "Diğer seçenekler"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/tr/Textarea.js b/dijit/form/nls/tr/Textarea.js
index 21b70fa..f8c2648 100644
--- a/dijit/form/nls/tr/Textarea.js
+++ b/dijit/form/nls/tr/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: 'düzenleme alanı',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'düzenleme alanı çerçevesi'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/tr/validate.js b/dijit/form/nls/tr/validate.js
index e51e2aa..9b54854 100644
--- a/dijit/form/nls/tr/validate.js
+++ b/dijit/form/nls/tr/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "Girilen değer geçersiz.",
 	missingMessage: "Bu değer gerekli.",
 	rangeMessage: "Bu değer aralık dışında."
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/uk/ComboBox.js b/dijit/form/nls/uk/ComboBox.js
new file mode 100644
index 0000000..8c93285
--- /dev/null
+++ b/dijit/form/nls/uk/ComboBox.js
@@ -0,0 +1,6 @@
+define(
+({
+	previousMessage: "Попередні варіанти",
+	nextMessage: "Додаткові варіанти"
+})
+);
diff --git a/dijit/form/nls/uk/Textarea.js b/dijit/form/nls/uk/Textarea.js
new file mode 100644
index 0000000..ff40953
--- /dev/null
+++ b/dijit/form/nls/uk/Textarea.js
@@ -0,0 +1,9 @@
+define(
+// used by both the editor and textarea widgets to provide information to screen reader users
+({
+	iframeEditTitle: 'область редагування',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
+	iframeFocusTitle: 'фрейм області редагування'  // secondary title for editable IFRAME when focus is on outer container
+	//  to let user know that focus has moved out of editing area and to the
+	//  parent element of the editing area
+})
+);
diff --git a/dijit/form/nls/uk/validate.js b/dijit/form/nls/uk/validate.js
new file mode 100644
index 0000000..f1863ab
--- /dev/null
+++ b/dijit/form/nls/uk/validate.js
@@ -0,0 +1,7 @@
+define(
+({
+	invalidMessage: "Введено невірне значення.",
+	missingMessage: "Це значення є обов'язковим.",
+	rangeMessage: "Це значення за межами діапазону."
+})
+);
diff --git a/dijit/form/nls/validate.js b/dijit/form/nls/validate.js
index 83d5a4b..17bc8c5 100644
--- a/dijit/form/nls/validate.js
+++ b/dijit/form/nls/validate.js
@@ -9,6 +9,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -36,6 +37,7 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dijit/form/nls/zh-tw/ComboBox.js b/dijit/form/nls/zh-tw/ComboBox.js
index c918f01..e7ec1d2 100644
--- a/dijit/form/nls/zh-tw/ComboBox.js
+++ b/dijit/form/nls/zh-tw/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "前一個選擇項",
 		nextMessage: "其他選擇項"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/zh-tw/Textarea.js b/dijit/form/nls/zh-tw/Textarea.js
index 5a034c7..3df55f3 100644
--- a/dijit/form/nls/zh-tw/Textarea.js
+++ b/dijit/form/nls/zh-tw/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
 	iframeEditTitle: '編輯區',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: '編輯區框'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/zh-tw/validate.js b/dijit/form/nls/zh-tw/validate.js
index 05f004e..42d5049 100644
--- a/dijit/form/nls/zh-tw/validate.js
+++ b/dijit/form/nls/zh-tw/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "輸入的值無效。",
 	missingMessage: "必須提供此值。",
 	rangeMessage: "此值超出範圍。"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/zh/ComboBox.js b/dijit/form/nls/zh/ComboBox.js
index a16792a..0baa746 100644
--- a/dijit/form/nls/zh/ComboBox.js
+++ b/dijit/form/nls/zh/ComboBox.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 		previousMessage: "先前选项",
 		nextMessage: "更多选项"
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/zh/Textarea.js b/dijit/form/nls/zh/Textarea.js
index 39bda72..838ea72 100644
--- a/dijit/form/nls/zh/Textarea.js
+++ b/dijit/form/nls/zh/Textarea.js
@@ -1,10 +1,9 @@
 define(
-//begin v1.x content
+// used by both the editor and textarea widgets to provide information to screen reader users
 ({
-	iframeEditTitle: '编辑区',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
-	iframeFocusTitle: '编辑区框架'  // secondary title for editable IFRAME when focus is on outer container
+	iframeEditTitle: '编辑区域',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
+	iframeFocusTitle: '编辑区域框'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
-//end v1.x content
 );
diff --git a/dijit/form/nls/zh/validate.js b/dijit/form/nls/zh/validate.js
index 075ce0c..05538e2 100644
--- a/dijit/form/nls/zh/validate.js
+++ b/dijit/form/nls/zh/validate.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	invalidMessage: "输入的值无效。",
-	missingMessage: "此值是必需值。",
+	missingMessage: "该值是必需的。",
 	rangeMessage: "此值超出范围。"
 })
-//end v1.x content
 );
diff --git a/dijit/form/templates/Button.html b/dijit/form/templates/Button.html
index d167ac0..8c71c29 100644
--- a/dijit/form/templates/Button.html
+++ b/dijit/form/templates/Button.html
@@ -1,6 +1,6 @@
 <span class="dijit dijitReset dijitInline" role="presentation"
 	><span class="dijitReset dijitInline dijitButtonNode"
-		data-dojo-attach-event="ondijitclick:_onClick" role="presentation"
+		data-dojo-attach-event="ondijitclick:__onClick" role="presentation"
 		><span class="dijitReset dijitStretch dijitButtonContents"
 			data-dojo-attach-point="titleNode,focusNode"
 			role="button" aria-labelledby="${id}_label"
@@ -13,5 +13,6 @@
 		></span
 	></span
 	><input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen"
+		data-dojo-attach-event="onclick:_onClick"
 		tabIndex="-1" role="presentation" data-dojo-attach-point="valueNode"
 /></span>
diff --git a/dijit/form/templates/CheckBox.html b/dijit/form/templates/CheckBox.html
index fd81fc2..5122fe2 100644
--- a/dijit/form/templates/CheckBox.html
+++ b/dijit/form/templates/CheckBox.html
@@ -1,7 +1,7 @@
 <div class="dijit dijitReset dijitInline" role="presentation"
 	><input
-	 	${!nameAttrSetting} type="${type}" ${checkedAttrSetting}
+	 	${!nameAttrSetting} type="${type}" role="${type}" aria-checked="false" ${checkedAttrSetting}
 		class="dijitReset dijitCheckBoxInput"
 		data-dojo-attach-point="focusNode"
-	 	data-dojo-attach-event="onclick:_onClick"
+	 	data-dojo-attach-event="ondijitclick:_onClick"
 /></div>
diff --git a/dijit/form/templates/ComboButton.html b/dijit/form/templates/ComboButton.html
index 49eed10..a37f01e 100644
--- a/dijit/form/templates/ComboButton.html
+++ b/dijit/form/templates/ComboButton.html
@@ -1,7 +1,7 @@
 <table class="dijit dijitReset dijitInline dijitLeft"
 	cellspacing='0' cellpadding='0' role="presentation"
 	><tbody role="presentation"><tr role="presentation"
-		><td class="dijitReset dijitStretch dijitButtonNode" data-dojo-attach-point="buttonNode" data-dojo-attach-event="ondijitclick:_onClick,onkeypress:_onButtonKeyPress"
+		><td class="dijitReset dijitStretch dijitButtonNode" data-dojo-attach-point="buttonNode" data-dojo-attach-event="ondijitclick:__onClick,onkeydown:_onButtonKeyDown"
 		><div id="${id}_button" class="dijitReset dijitButtonContents"
 			data-dojo-attach-point="titleNode"
 			role="button" aria-labelledby="${id}_label"
@@ -11,13 +11,14 @@
 		></td
 		><td id="${id}_arrow" class='dijitReset dijitRight dijitButtonNode dijitArrowButton'
 			data-dojo-attach-point="_popupStateNode,focusNode,_buttonNode"
-			data-dojo-attach-event="onkeypress:_onArrowKeyPress"
+			data-dojo-attach-event="onkeydown:_onArrowKeyDown"
 			title="${optionsTitle}"
 			role="button" aria-haspopup="true"
 			><div class="dijitReset dijitArrowButtonInner" role="presentation"></div
 			><div class="dijitReset dijitArrowButtonChar" role="presentation">▼</div
 		></td
 		><td style="display:none !important;"
-			><input ${!nameAttrSetting} type="${type}" value="${value}" data-dojo-attach-point="valueNode"
+			><input ${!nameAttrSetting} type="${type}" value="${value}" data-dojo-attach-point="valueNode" role="presentation"
+				data-dojo-attach-event="onclick:_onClick"
 		/></td></tr></tbody
 ></table>
diff --git a/dijit/form/templates/DropDownBox.html b/dijit/form/templates/DropDownBox.html
index 0314ad9..7c6881c 100644
--- a/dijit/form/templates/DropDownBox.html
+++ b/dijit/form/templates/DropDownBox.html
@@ -1,9 +1,11 @@
 <div class="dijit dijitReset dijitInline dijitLeft"
 	id="widget_${id}"
 	role="combobox"
+	aria-haspopup="true"
+	data-dojo-attach-point="_popupStateNode"
 	><div class='dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton dijitArrowButtonContainer'
-		data-dojo-attach-point="_buttonNode, _popupStateNode" role="presentation"
-		><input class="dijitReset dijitInputField dijitArrowButtonInner" value="▼ " type="text" tabIndex="-1" readonly="readonly" role="presentation"
+		data-dojo-attach-point="_buttonNode" role="presentation"
+		><input class="dijitReset dijitInputField dijitArrowButtonInner" value="▼ " type="text" tabIndex="-1" readonly="readonly" role="button presentation" aria-hidden="true"
 			${_buttonInputDisabled}
 	/></div
 	><div class='dijitReset dijitValidationContainer'
@@ -11,6 +13,6 @@
 	/></div
 	><div class="dijitReset dijitInputField dijitInputContainer"
 		><input class='dijitReset dijitInputInner' ${!nameAttrSetting} type="text" autocomplete="off"
-			data-dojo-attach-point="textbox,focusNode" role="textbox" aria-haspopup="true"
+			data-dojo-attach-point="textbox,focusNode" role="textbox"
 	/></div
 ></div>
diff --git a/dijit/form/templates/DropDownButton.html b/dijit/form/templates/DropDownButton.html
index 56d2618..0fac4be 100644
--- a/dijit/form/templates/DropDownButton.html
+++ b/dijit/form/templates/DropDownButton.html
@@ -1,14 +1,14 @@
 <span class="dijit dijitReset dijitInline"
 	><span class='dijitReset dijitInline dijitButtonNode'
-		data-dojo-attach-event="ondijitclick:_onClick" data-dojo-attach-point="_buttonNode"
+		data-dojo-attach-event="ondijitclick:__onClick" data-dojo-attach-point="_buttonNode"
 		><span class="dijitReset dijitStretch dijitButtonContents"
-			data-dojo-attach-point="focusNode,titleNode,_arrowWrapperNode"
+			data-dojo-attach-point="focusNode,titleNode,_arrowWrapperNode,_popupStateNode"
 			role="button" aria-haspopup="true" aria-labelledby="${id}_label"
 			><span class="dijitReset dijitInline dijitIcon"
 				data-dojo-attach-point="iconNode"
 			></span
 			><span class="dijitReset dijitInline dijitButtonText"
-				data-dojo-attach-point="containerNode,_popupStateNode"
+				data-dojo-attach-point="containerNode"
 				id="${id}_label"
 			></span
 			><span class="dijitReset dijitInline dijitArrowButtonInner"></span
@@ -16,5 +16,6 @@
 		></span
 	></span
 	><input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen" tabIndex="-1"
-		data-dojo-attach-point="valueNode"
+		data-dojo-attach-event="onclick:_onClick"
+		data-dojo-attach-point="valueNode" role="presentation"
 /></span>
diff --git a/dijit/form/templates/HorizontalSlider.html b/dijit/form/templates/HorizontalSlider.html
index 9fd16d4..b926c7d 100644
--- a/dijit/form/templates/HorizontalSlider.html
+++ b/dijit/form/templates/HorizontalSlider.html
@@ -1,4 +1,5 @@
-<table class="dijit dijitReset dijitSlider dijitSliderH" cellspacing="0" cellpadding="0" border="0" rules="none" data-dojo-attach-event="onkeypress:_onKeyPress,onkeyup:_onKeyUp"
+<table class="dijit dijitReset dijitSlider dijitSliderH" cellspacing="0" cellpadding="0" border="0" rules="none" data-dojo-attach-event="onkeydown:_onKeyDown, onkeyup:_onKeyUp"
+	role="presentation"
 	><tr class="dijitReset"
 		><td class="dijitReset" colspan="2"></td
 		><td data-dojo-attach-point="topDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationT dijitSliderDecorationH"></td
@@ -16,7 +17,7 @@
 			/><div class="dijitReset dijitSliderBarContainerH" role="presentation" data-dojo-attach-point="sliderBarContainer"
 				><div role="presentation" data-dojo-attach-point="progressBar" class="dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH" data-dojo-attach-event="press:_onBarClick"
 					><div class="dijitSliderMoveable dijitSliderMoveableH"
-						><div data-dojo-attach-point="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleH" data-dojo-attach-event="press:_onHandleClick" role="slider" valuemin="${minimum}" valuemax="${maximum}"></div
+						><div data-dojo-attach-point="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleH" data-dojo-attach-event="press:_onHandleClick" role="slider"></div
 					></div
 				></div
 				><div role="presentation" data-dojo-attach-point="remainingBar" class="dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH" data-dojo-attach-event="press:_onBarClick"></div
diff --git a/dijit/form/templates/Select.html b/dijit/form/templates/Select.html
index 9e917ab..4901aa8 100644
--- a/dijit/form/templates/Select.html
+++ b/dijit/form/templates/Select.html
@@ -1,14 +1,18 @@
 <table class="dijit dijitReset dijitInline dijitLeft"
-	data-dojo-attach-point="_buttonNode,tableNode,focusNode" cellspacing='0' cellpadding='0'
-	role="combobox" aria-haspopup="true"
+	data-dojo-attach-point="_buttonNode,tableNode,focusNode,_popupStateNode" cellspacing='0' cellpadding='0'
+	role="listbox" aria-haspopup="true"
 	><tbody role="presentation"><tr role="presentation"
-		><td class="dijitReset dijitStretch dijitButtonContents dijitButtonNode" role="presentation"
-			><span class="dijitReset dijitInline dijitButtonText"  data-dojo-attach-point="containerNode,_popupStateNode"></span
+		><td class="dijitReset dijitStretch dijitButtonContents" role="presentation"
+			><div class="dijitReset dijitInputField dijitButtonText"  data-dojo-attach-point="containerNode,textDirNode" role="presentation"></div
+			><div class="dijitReset dijitValidationContainer"
+				><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="Χ " type="text" tabIndex="-1" readonly="readonly" role="presentation"
+			/></div
 			><input type="hidden" ${!nameAttrSetting} data-dojo-attach-point="valueNode" value="${value}" aria-hidden="true"
-		/></td><td class="dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton"
-				data-dojo-attach-point="titleNode" role="presentation"
-			><div class="dijitReset dijitArrowButtonInner" role="presentation"></div
-			><div class="dijitReset dijitArrowButtonChar" role="presentation">▼</div
-		></td
+		/></td
+		><td class="dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton dijitArrowButtonContainer"
+			data-dojo-attach-point="titleNode" role="presentation"
+			><input class="dijitReset dijitInputField dijitArrowButtonInner" value="▼ " type="text" tabIndex="-1" readonly="readonly" role="presentation"
+				${_buttonInputDisabled}
+		/></td
 	></tr></tbody
 ></table>
diff --git a/dijit/form/templates/Spinner.html b/dijit/form/templates/Spinner.html
index 468613d..3f2186a 100644
--- a/dijit/form/templates/Spinner.html
+++ b/dijit/form/templates/Spinner.html
@@ -5,23 +5,23 @@
 		/><div class="dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitUpArrowButton"
 			data-dojo-attach-point="upArrowNode"
 			><div class="dijitArrowButtonInner"
-				><input class="dijitReset dijitInputField" value="▲" type="text" tabIndex="-1" readonly="readonly" role="presentation"
+				><input class="dijitReset dijitInputField" value="▲ " type="text" tabIndex="-1" readonly="readonly" role="presentation"
 					${_buttonInputDisabled}
 			/></div
 		></div
 		><div class="dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitDownArrowButton"
 			data-dojo-attach-point="downArrowNode"
 			><div class="dijitArrowButtonInner"
-				><input class="dijitReset dijitInputField" value="▼" type="text" tabIndex="-1" readonly="readonly" role="presentation"
+				><input class="dijitReset dijitInputField" value="▼ " type="text" tabIndex="-1" readonly="readonly" role="presentation"
 					${_buttonInputDisabled}
 			/></div
 		></div
 	></div
 	><div class='dijitReset dijitValidationContainer'
-		><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="Χ" type="text" tabIndex="-1" readonly="readonly" role="presentation"
+		><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="Χ " type="text" tabIndex="-1" readonly="readonly" role="presentation"
 	/></div
 	><div class="dijitReset dijitInputField dijitInputContainer"
-		><input class='dijitReset dijitInputInner' data-dojo-attach-point="textbox,focusNode" type="${type}" data-dojo-attach-event="onkeypress:_onKeyPress"
+		><input class='dijitReset dijitInputInner' data-dojo-attach-point="textbox,focusNode" type="${type}" data-dojo-attach-event="onkeydown:_onKeyDown"
 			role="spinbutton" autocomplete="off" ${!nameAttrSetting}
 	/></div
 ></div>
diff --git a/dijit/form/templates/VerticalSlider.html b/dijit/form/templates/VerticalSlider.html
index 0c72ed9..574ed3d 100644
--- a/dijit/form/templates/VerticalSlider.html
+++ b/dijit/form/templates/VerticalSlider.html
@@ -1,4 +1,5 @@
-<table class="dijit dijitReset dijitSlider dijitSliderV" cellspacing="0" cellpadding="0" border="0" rules="none" data-dojo-attach-event="onkeypress:_onKeyPress,onkeyup:_onKeyUp"
+<table class="dijit dijitReset dijitSlider dijitSliderV" cellspacing="0" cellpadding="0" border="0" rules="none" data-dojo-attach-event="onkeydown:_onKeyDown,onkeyup:_onKeyUp"
+	role="presentation"
 	><tr class="dijitReset"
 		><td class="dijitReset"></td
 		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV"
@@ -21,7 +22,7 @@
 				><div role="presentation" data-dojo-attach-point="remainingBar" class="dijitSliderBar dijitSliderBarV dijitSliderRemainingBar dijitSliderRemainingBarV" data-dojo-attach-event="press:_onBarClick"><!--#5629--></div
 				><div role="presentation" data-dojo-attach-point="progressBar" class="dijitSliderBar dijitSliderBarV dijitSliderProgressBar dijitSliderProgressBarV" data-dojo-attach-event="press:_onBarClick"
 					><div class="dijitSliderMoveable dijitSliderMoveableV" style="vertical-align:top;"
-						><div data-dojo-attach-point="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleV" data-dojo-attach-event="press:_onHandleClick" role="slider" valuemin="${minimum}" valuemax="${maximum}"></div
+						><div data-dojo-attach-point="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleV" data-dojo-attach-event="press:_onHandleClick" role="slider"></div
 					></div
 				></div
 			></center
diff --git a/dijit/hccss.js b/dijit/hccss.js
index 58db4e9..4925e6b 100644
--- a/dijit/hccss.js
+++ b/dijit/hccss.js
@@ -1,52 +1,21 @@
-define([
-	"require",			// require.toUrl
-	"dojo/_base/config", // config.blankGif
-	"dojo/dom-class", // domClass.add domConstruct.create domStyle.getComputedStyle
-	"dojo/dom-construct", // domClass.add domConstruct.create domStyle.getComputedStyle
-	"dojo/dom-style", // domClass.add domConstruct.create domStyle.getComputedStyle
-	"dojo/ready", // ready
-	"dojo/_base/sniff", // has("ie") has("mozilla")
-	"dojo/_base/window" // win.body
-], function(require, config, domClass, domConstruct, domStyle, ready, has, win){
+define(["dojo/dom-class", "dojo/hccss", "dojo/domReady", "dojo/_base/window"], function(domClass, has, domReady, win){
 
 	// module:
 	//		dijit/hccss
-	// summary:
-	//		Test if computer is in high contrast mode, and sets dijit_a11y flag on <body> if it is.
 
-	if(has("ie") || has("mozilla")){	// NOTE: checking in Safari messes things up
-		// priority is 90 to run ahead of parser priority of 100
-		ready(90, function(){
-			// summary:
-			//		Detects if we are in high-contrast mode or not
+	/*=====
+	return function(){
+		// summary:
+		//		Test if computer is in high contrast mode, and sets `dijit_a11y` flag on `<body>` if it is.
+		//		Deprecated, use ``dojo/hccss`` instead.
+	};
+	=====*/
 
-			// create div for testing if high contrast mode is on or images are turned off
-			var div = domConstruct.create("div",{
-				id: "a11yTestNode",
-				style:{
-					cssText:'border: 1px solid;'
-						+ 'border-color:red green;'
-						+ 'position: absolute;'
-						+ 'height: 5px;'
-						+ 'top: -999px;'
-						+ 'background-image: url("' + (config.blankGif || require.toUrl("dojo/resources/blank.gif")) + '");'
-				}
-			}, win.body());
+	domReady(function(){
+		if(has("highcontrast")){
+			domClass.add(win.body(), "dijit_a11y");
+		}
+	});
 
-			// test it
-			var cs = domStyle.getComputedStyle(div);
-			if(cs){
-				var bkImg = cs.backgroundImage;
-				var needsA11y = (cs.borderTopColor == cs.borderRightColor) || (bkImg != null && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
-				if(needsA11y){
-					domClass.add(win.body(), "dijit_a11y");
-				}
-				if(has("ie")){
-					div.outerHTML = "";		// prevent mixed-content warning, see http://support.microsoft.com/kb/925014
-				}else{
-					win.body().removeChild(div);
-				}
-			}
-		});
-	}
+	return has;
 });
diff --git a/dijit/icons/commonIcons.css b/dijit/icons/commonIcons.css
index 8d0060e..3fde8c2 100644
--- a/dijit/icons/commonIcons.css
+++ b/dijit/icons/commonIcons.css
@@ -133,7 +133,7 @@ The 16 x 16px icons in these sprites are action and object type images which can
 .dijitIconEdit { background-position: -112px; }
 .dijitIconNewTask { background-position: -128px; }
 .dijitIconEditTask { background-position: -144px; }
-.dijitIconEditProperty { background-position: -166px; }
+.dijitIconEditProperty { background-position: -160px; }
 .dijitIconTask { background-position: -176px; }
 .dijitIconFilter { background-position: -192px; }
 .dijitIconConfigure { background-position: -208px; }
diff --git a/dijit/icons/images/commonIconsObjActDisabled_rtl.png b/dijit/icons/images/commonIconsObjActDisabled_rtl.png
index ea070eb..d5e9ac8 100644
Binary files a/dijit/icons/images/commonIconsObjActDisabled_rtl.png and b/dijit/icons/images/commonIconsObjActDisabled_rtl.png differ
diff --git a/dijit/icons/images/commonIconsObjActEnabled.png b/dijit/icons/images/commonIconsObjActEnabled.png
index bd32452..be14bf0 100644
Binary files a/dijit/icons/images/commonIconsObjActEnabled.png and b/dijit/icons/images/commonIconsObjActEnabled.png differ
diff --git a/dijit/icons/images/commonIconsObjActEnabled8bit.png b/dijit/icons/images/commonIconsObjActEnabled8bit.png
index d453ea1..20092f2 100644
Binary files a/dijit/icons/images/commonIconsObjActEnabled8bit.png and b/dijit/icons/images/commonIconsObjActEnabled8bit.png differ
diff --git a/dijit/icons/images/commonIconsObjActEnabled8bit_rtl.png b/dijit/icons/images/commonIconsObjActEnabled8bit_rtl.png
index fe5afd2..7e504ff 100644
Binary files a/dijit/icons/images/commonIconsObjActEnabled8bit_rtl.png and b/dijit/icons/images/commonIconsObjActEnabled8bit_rtl.png differ
diff --git a/dijit/icons/images/commonIconsObjActEnabled_rtl.png b/dijit/icons/images/commonIconsObjActEnabled_rtl.png
index fbe891a..23ff1a3 100644
Binary files a/dijit/icons/images/commonIconsObjActEnabled_rtl.png and b/dijit/icons/images/commonIconsObjActEnabled_rtl.png differ
diff --git a/dijit/icons/images/editorIconsDisabled.png b/dijit/icons/images/editorIconsDisabled.png
index 3a68d7a..98160f4 100644
Binary files a/dijit/icons/images/editorIconsDisabled.png and b/dijit/icons/images/editorIconsDisabled.png differ
diff --git a/dijit/icons/images/editorIconsDisabled_rtl.png b/dijit/icons/images/editorIconsDisabled_rtl.png
index 9f16646..a657ef9 100644
Binary files a/dijit/icons/images/editorIconsDisabled_rtl.png and b/dijit/icons/images/editorIconsDisabled_rtl.png differ
diff --git a/dijit/icons/images/editorIconsEnabled.png b/dijit/icons/images/editorIconsEnabled.png
index ca9989a..bfc03b5 100644
Binary files a/dijit/icons/images/editorIconsEnabled.png and b/dijit/icons/images/editorIconsEnabled.png differ
diff --git a/dijit/icons/images/editorIconsEnabled_rtl.png b/dijit/icons/images/editorIconsEnabled_rtl.png
index 064def3..ed1768a 100644
Binary files a/dijit/icons/images/editorIconsEnabled_rtl.png and b/dijit/icons/images/editorIconsEnabled_rtl.png differ
diff --git a/dijit/icons/images/loadingAnimation_rtl.gif b/dijit/icons/images/loadingAnimation_rtl.gif
index 35b472c..a1aaf62 100644
Binary files a/dijit/icons/images/loadingAnimation_rtl.gif and b/dijit/icons/images/loadingAnimation_rtl.gif differ
diff --git a/dijit/layout/AccordionContainer.js b/dijit/layout/AccordionContainer.js
index 67cf66b..a691bc4 100644
--- a/dijit/layout/AccordionContainer.js
+++ b/dijit/layout/AccordionContainer.js
@@ -2,20 +2,18 @@ define([
 	"require",
 	"dojo/_base/array", // array.forEach array.map
 	"dojo/_base/declare", // declare
-	"dojo/_base/event", // event.stop
 	"dojo/_base/fx", // fx.Animation
 	"dojo/dom", // dom.setSelectable
 	"dojo/dom-attr", // domAttr.attr
 	"dojo/dom-class", // domClass.remove
 	"dojo/dom-construct", // domConstruct.place
 	"dojo/dom-geometry",
-	"dojo/_base/kernel",
 	"dojo/keys", // keys
 	"dojo/_base/lang", // lang.getObject lang.hitch
-	"dojo/_base/sniff", // has("ie")
+	"dojo/sniff", // has("ie") has("dijit-legacy-requires")
 	"dojo/topic", // publish
-	"../focus",			// focus.focus()
-	"../_base/manager",	// manager.defaultDuration
+	"../focus", // focus.focus()
+	"../_base/manager", // manager.defaultDuration
 	"dojo/ready",
 	"../_Widget",
 	"../_Container",
@@ -23,25 +21,13 @@ define([
 	"../_CssStateMixin",
 	"./StackContainer",
 	"./ContentPane",
-	"dojo/text!./templates/AccordionButton.html"
-], function(require, array, declare, event, fx, dom, domAttr, domClass, domConstruct, domGeometry,
-			kernel, keys, lang, has, topic, focus, manager, ready,
-			_Widget, _Container, _TemplatedMixin, _CssStateMixin, StackContainer, ContentPane, template){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _Container = dijit._Container;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _CssStateMixin = dijit._CssStateMixin;
-	var StackContainer = dijit.layout.StackContainer;
-	var ContentPane = dijit.layout.ContentPane;
-=====*/
+	"dojo/text!./templates/AccordionButton.html",
+	"../a11yclick" // AccordionButton template uses ondijitclick; not for keyboard, but for responsive touch.
+], function(require, array, declare, fx, dom, domAttr, domClass, domConstruct, domGeometry, keys, lang, has, topic,
+			focus, manager, ready, _Widget, _Container, _TemplatedMixin, _CssStateMixin, StackContainer, ContentPane, template){
 
 	// module:
 	//		dijit/layout/AccordionContainer
-	// summary:
-	//		Holds a set of panes where every pane's title is visible, but only one pane's content is visible at a time,
-	//		and switching between panes is visualized by sliding the other panes up/down.
 
 
 	// Design notes:
@@ -65,7 +51,6 @@ define([
 	// During animation there are two dijtAccordionChildWrapper's shown, so we need
 	// to compensate for that.
 
-
 	var AccordionButton = declare("dijit.layout._AccordionButton", [_Widget, _TemplatedMixin, _CssStateMixin], {
 		// summary:
 		//		The title bar to click to open up an accordion pane.
@@ -102,8 +87,8 @@ define([
 
 		buildRendering: function(){
 			this.inherited(arguments);
-			var titleTextNodeId = this.id.replace(' ','_');
-			domAttr.set(this.titleTextNode, "id", titleTextNodeId+"_title");
+			var titleTextNodeId = this.id.replace(' ', '_');
+			domAttr.set(this.titleTextNode, "id", titleTextNodeId + "_title");
 			this.focusNode.setAttribute("aria-labelledby", domAttr.get(this.titleTextNode, "id"));
 			dom.setSelectable(this.domNode, false);
 		},
@@ -120,41 +105,57 @@ define([
 			// summary:
 			//		Callback when someone clicks my title.
 			var parent = this.getParent();
-				parent.selectChild(this.contentWidget, true);
-				focus.focus(this.focusNode);
+			parent.selectChild(this.contentWidget, true);
+			focus.focus(this.focusNode);
 		},
 
-		_onTitleKeyPress: function(/*Event*/ evt){
-			return this.getParent()._onKeyPress(evt, this.contentWidget);
+		_onTitleKeyDown: function(/*Event*/ evt){
+			return this.getParent()._onKeyDown(evt, this.contentWidget);
 		},
 
 		_setSelectedAttr: function(/*Boolean*/ isSelected){
 			this._set("selected", isSelected);
-			this.focusNode.setAttribute("aria-expanded", isSelected);
-			this.focusNode.setAttribute("aria-selected", isSelected);
+			this.focusNode.setAttribute("aria-expanded", isSelected ? "true" : "false");
+			this.focusNode.setAttribute("aria-selected", isSelected ? "true" : "false");
 			this.focusNode.setAttribute("tabIndex", isSelected ? "0" : "-1");
 		}
 	});
 
-	var AccordionInnerContainer = declare("dijit.layout._AccordionInnerContainer", [_Widget, _CssStateMixin], {
+	if(has("dojo-bidi")){
+		AccordionButton.extend({
+			_setLabelAttr: function(label){
+				this._set("label", label);
+				domAttr.set(this.titleTextNode, "innerHTML", label);
+				this.applyTextDir(this.titleTextNode);
+			},
+
+			_setTitleAttr: function(title){
+				this._set("title", title);
+				domAttr.set(this.titleTextNode, "title", title);
+				this.applyTextDir(this.titleTextNode);
+			}
+		});
+	}
+
+	var AccordionInnerContainer = declare("dijit.layout._AccordionInnerContainer" + (has("dojo-bidi") ? "_NoBidi" : ""), [_Widget, _CssStateMixin], {
 		// summary:
 		//		Internal widget placed as direct child of AccordionContainer.containerNode.
 		//		When other widgets are added as children to an AccordionContainer they are wrapped in
 		//		this widget.
 
-/*=====
-		// buttonWidget: Function || String
-		//		Class to use to instantiate title
-		//		(Wish we didn't have a separate widget for just the title but maintaining it
-		//		for backwards compatibility, is it worth it?)
+		/*=====
+		 // buttonWidget: Function|String
+		 //		Class to use to instantiate title
+		 //		(Wish we didn't have a separate widget for just the title but maintaining it
+		 //		for backwards compatibility, is it worth it?)
 		 buttonWidget: null,
-=====*/
+		 =====*/
 
-/*=====
-		// contentWidget: dijit._Widget
-		//		Pointer to the real child widget
-	 	contentWidget: null,
-=====*/
+		/*=====
+		 // contentWidget: dijit/_WidgetBase
+		 //		Pointer to the real child widget
+		 contentWidget: null,
+		 =====*/
 
 		baseClass: "dijitAccordionInnerContainer",
 
@@ -183,7 +184,7 @@ define([
 				title: child.tooltip,
 				dir: child.dir,
 				lang: child.lang,
-				textDir: child.textDir,
+				textDir: child.textDir || this.textDir,
 				iconClass: child.iconClass,
 				id: child.id + "_button",
 				parent: this.parent
@@ -191,7 +192,9 @@ define([
 
 			// and then the actual content widget (changing it from prior-sibling to last-child),
 			// wrapped by a <div class=dijitAccordionChildWrapper>
-			this.containerNode = domConstruct.place("<div class='dijitAccordionChildWrapper' style='display:none'>", this.domNode);
+			this.containerNode = domConstruct.place("<div class='dijitAccordionChildWrapper' role='tabpanel' style='display:none'>", this.domNode);
+			this.containerNode.setAttribute("aria-labelledby", this.button.id);
+
 			domConstruct.place(this.contentWidget.domNode, this.containerNode);
 		},
 
@@ -199,15 +202,16 @@ define([
 			this.inherited(arguments);
 
 			// Map changes in content widget's title etc. to changes in the button
-			var button = this.button;
+			var button = this.button,
+				cw = this.contentWidget;
 			this._contentWidgetWatches = [
-				this.contentWidget.watch('title', lang.hitch(this, function(name, oldValue, newValue){
+				cw.watch('title', lang.hitch(this, function(name, oldValue, newValue){
 					button.set("label", newValue);
 				})),
-				this.contentWidget.watch('tooltip', lang.hitch(this, function(name, oldValue, newValue){
+				cw.watch('tooltip', lang.hitch(this, function(name, oldValue, newValue){
 					button.set("title", newValue);
 				})),
-				this.contentWidget.watch('iconClass', lang.hitch(this, function(name, oldValue, newValue){
+				cw.watch('iconClass', lang.hitch(this, function(name, oldValue, newValue){
 					button.set("iconClass", newValue);
 				}))
 			];
@@ -218,7 +222,9 @@ define([
 			this.button.set("selected", isSelected);
 			if(isSelected){
 				var cw = this.contentWidget;
-				if(cw.onSelected){ cw.onSelected(); }
+				if(cw.onSelected){
+					cw.onSelected();
+				}
 			}
 		},
 
@@ -230,7 +236,9 @@ define([
 		destroy: function(){
 			this.button.destroyRecursive();
 
-			array.forEach(this._contentWidgetWatches || [], function(w){ w.unwatch(); });
+			array.forEach(this._contentWidgetWatches || [], function(w){
+				w.unwatch();
+			});
 
 			delete this.contentWidget._buttonWidget;
 			delete this.contentWidget._wrapperWidget;
@@ -244,15 +252,31 @@ define([
 		}
 	});
 
+	if(has("dojo-bidi")){
+		AccordionInnerContainer = declare("dijit.layout._AccordionInnerContainer", AccordionInnerContainer, {
+			postCreate: function(){
+				this.inherited(arguments);
+
+				// Map changes in content widget's textdir to changes in the button
+				var button = this.button;
+				this._contentWidgetWatches.push(
+					this.contentWidget.watch("textDir", function(name, oldValue, newValue){
+						button.set("textDir", newValue);
+					})
+				);
+			}
+		});
+	}
+
 	var AccordionContainer = declare("dijit.layout.AccordionContainer", StackContainer, {
 		// summary:
 		//		Holds a set of panes where every pane's title is visible, but only one pane's content is visible at a time,
 		//		and switching between panes is visualized by sliding the other panes up/down.
 		// example:
-		//	| 	<div data-dojo-type="dijit.layout.AccordionContainer">
-		//	|		<div data-dojo-type="dijit.layout.ContentPane" title="pane 1">
+		//	|	<div data-dojo-type="dijit/layout/AccordionContainer">
+		//	|		<div data-dojo-type="dijit/layout/ContentPane" title="pane 1">
 		//	|		</div>
-		//	|		<div data-dojo-type="dijit.layout.ContentPane" title="pane 2">
+		//	|		<div data-dojo-type="dijit/layout/ContentPane" title="pane 2">
 		//	|			<p>This is some text</p>
 		//	|		</div>
 		//	|	</div>
@@ -265,27 +289,26 @@ define([
 		//		The name of the widget used to display the title of each pane
 		buttonWidget: AccordionButton,
 
-/*=====
-		// _verticalSpace: Number
-		//		Pixels of space available for the open pane
-		//		(my content box size minus the cumulative size of all the title bars)
-		_verticalSpace: 0,
-=====*/
+		/*=====
+		 // _verticalSpace: Number
+		 //		Pixels of space available for the open pane
+		 //		(my content box size minus the cumulative size of all the title bars)
+		 _verticalSpace: 0,
+		 =====*/
 		baseClass: "dijitAccordionContainer",
 
 		buildRendering: function(){
 			this.inherited(arguments);
 			this.domNode.style.overflow = "hidden";		// TODO: put this in dijit.css
-			this.domNode.setAttribute("role", "tablist");	// TODO: put this in template
+			this.domNode.setAttribute("role", "tablist");
 		},
 
 		startup: function(){
-			if(this._started){ return; }
+			if(this._started){
+				return;
+			}
 			this.inherited(arguments);
 			if(this.selectedChildWidget){
-				var style = this.selectedChildWidget.containerNode.style;
-				style.display = "";
-				style.overflow = "auto";
 				this.selectedChildWidget._wrapperWidget.set("selected", true);
 			}
 		},
@@ -296,7 +319,9 @@ define([
 
 			var openPane = this.selectedChildWidget;
 
-			if(!openPane){ return;}
+			if(!openPane){
+				return;
+			}
 
 			// space taken up by title, plus wrapper div (with border/margin) for open pane
 			var wrapperDomNode = openPane._wrapperWidget.domNode,
@@ -310,7 +335,7 @@ define([
 			// get cumulative height of all the unselected title bars
 			var totalCollapsedHeight = 0;
 			array.forEach(this.getChildren(), function(child){
-	            if(child != openPane){
+				if(child != openPane){
 					// Using domGeometry.getMarginSize() rather than domGeometry.position() since claro has 1px bottom margin
 					// to separate accordion panes.  Not sure that works perfectly, it's probably putting a 1px
 					// margin below the bottom pane (even though we don't want one).
@@ -318,7 +343,7 @@ define([
 				}
 			});
 			this._verticalSpace = mySize.h - totalCollapsedHeight - wrapperDomNodeMargin.h
-			 	- wrapperDomNodePadBorder.h - wrapperContainerNodeMargin.h - wrapperContainerNodePadBorder.h
+				- wrapperDomNodePadBorder.h - wrapperContainerNodeMargin.h - wrapperContainerNodePadBorder.h
 				- openPane._buttonWidget.getTitleHeight();
 
 			// Memo size to make displayed child
@@ -343,48 +368,15 @@ define([
 				id: child.id + "_wrapper",
 				dir: child.dir,
 				lang: child.lang,
-				textDir: child.textDir,
+				textDir: child.textDir || this.textDir,
 				parent: this
 			});
 
 			this.inherited(arguments);
-		},
 
-		addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
-			if(this._started){
-				// Adding a child to a started Accordion is complicated because children have
-				// wrapper widgets.  Default code path (calling this.inherited()) would add
-				// the new child inside another child's wrapper.
-
-				// First add in child as a direct child of this AccordionContainer
-				var refNode = this.containerNode;
-				if(insertIndex && typeof insertIndex == "number"){
-					var children = _Widget.prototype.getChildren.call(this);	// get wrapper panes
-					if(children && children.length >= insertIndex){
-						refNode = children[insertIndex-1].domNode;
-						insertIndex = "after";
-					}
-				}
-				domConstruct.place(child.domNode, refNode, insertIndex);
-
-				if(!child._started){
-					child.startup();
-				}
-
-				// Then stick the wrapper widget around the child widget
-				this._setupChild(child);
-
-				// Code below copied from StackContainer
-				topic.publish(this.id+"-addChild", child, insertIndex);	// publish
-				this.layout();
-				if(!this.selectedChildWidget){
-					this.selectChild(child);
-				}
-			}else{
-				// We haven't been started yet so just add in the child widget directly,
-				// and the wrapper will be created on startup()
-				this.inherited(arguments);
-			}
+			// Since we are wrapping children in AccordionInnerContainer, replace the default
+			// wrapper that we created in StackContainer.
+			domConstruct.place(child.domNode, child._wrapper, "replace");
 		},
 
 		removeChild: function(child){
@@ -393,6 +385,7 @@ define([
 			// Destroy wrapper widget first, before StackContainer.getChildren() call.
 			// Replace wrapper widget with true child widget (ContentPane etc.).
 			// This step only happens if the AccordionContainer has been started; otherwise there's no wrapper.
+			// (TODO: since StackContainer destroys child._wrapper, maybe it can do this step too?)
 			if(child._wrapperWidget){
 				domConstruct.place(child.domNode, child._wrapperWidget.domNode, "after");
 				child._wrapperWidget.destroy();
@@ -429,17 +422,17 @@ define([
 
 		_showChild: function(child){
 			// Override StackContainer._showChild() to set visibility of _wrapperWidget.containerNode
-			child._wrapperWidget.containerNode.style.display="block";
+			child._wrapperWidget.containerNode.style.display = "block";
 			return this.inherited(arguments);
 		},
 
 		_hideChild: function(child){
 			// Override StackContainer._showChild() to set visibility of _wrapperWidget.containerNode
-			child._wrapperWidget.containerNode.style.display="none";
+			child._wrapperWidget.containerNode.style.display = "none";
 			this.inherited(arguments);
 		},
 
-		_transition: function(/*dijit._Widget?*/ newWidget, /*dijit._Widget?*/ oldWidget, /*Boolean*/ animate){
+		_transition: function(/*dijit/_WidgetBase?*/ newWidget, /*dijit/_WidgetBase?*/ oldWidget, /*Boolean*/ animate){
 			// Overrides StackContainer._transition() to provide sliding of title bars etc.
 
 			if(has("ie") < 8){
@@ -514,9 +507,9 @@ define([
 		},
 
 		// note: we are treating the container as controller here
-		_onKeyPress: function(/*Event*/ e, /*dijit._Widget*/ fromTitle){
+		_onKeyDown: function(/*Event*/ e, /*dijit/_WidgetBase*/ fromTitle){
 			// summary:
-			//		Handle keypress events
+			//		Handle keydown events
 			// description:
 			//		This is called from a handler on AccordionContainer.domNode
 			//		(setup in StackContainer), and is also called directly from
@@ -524,21 +517,23 @@ define([
 			if(this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
 				return;
 			}
-			var c = e.charOrCode;
+			var c = e.keyCode;
 			if((fromTitle && (c == keys.LEFT_ARROW || c == keys.UP_ARROW)) ||
-					(e.ctrlKey && c == keys.PAGE_UP)){
+				(e.ctrlKey && c == keys.PAGE_UP)){
 				this._adjacent(false)._buttonWidget._onTitleClick();
-				event.stop(e);
+				e.stopPropagation();
+				e.preventDefault();
 			}else if((fromTitle && (c == keys.RIGHT_ARROW || c == keys.DOWN_ARROW)) ||
-					(e.ctrlKey && (c == keys.PAGE_DOWN || c == keys.TAB))){
+				(e.ctrlKey && (c == keys.PAGE_DOWN || c == keys.TAB))){
 				this._adjacent(true)._buttonWidget._onTitleClick();
-				event.stop(e);
+				e.stopPropagation();
+				e.preventDefault();
 			}
 		}
 	});
 
 	// Back compat w/1.6, remove for 2.0
-	if(!kernel.isAsync){
+	if(has("dijit-legacy-requires")){
 		ready(0, function(){
 			var requires = ["dijit/layout/AccordionPane"];
 			require(requires);	// use indirection so modules not rolled into a build
diff --git a/dijit/layout/AccordionPane.js b/dijit/layout/AccordionPane.js
index 9068242..51ce921 100644
--- a/dijit/layout/AccordionPane.js
+++ b/dijit/layout/AccordionPane.js
@@ -4,18 +4,12 @@ define([
 	"./ContentPane"
 ], function(declare, kernel, ContentPane){
 
-/*=====
-	var ContentPane = dijit.layout.ContentPane;
-=====*/
-
 	// module:
 	//		dijit/layout/AccordionPane
-	// summary:
-	//		Deprecated widget.   Use `dijit.layout.ContentPane` instead.
 
 	return declare("dijit.layout.AccordionPane", ContentPane, {
 		// summary:
-		//		Deprecated widget.   Use `dijit.layout.ContentPane` instead.
+		//		Deprecated widget.   Use `dijit/layout/ContentPane` instead.
 		// tags:
 		//		deprecated
 
diff --git a/dijit/layout/BorderContainer.js b/dijit/layout/BorderContainer.js
index 5e0e3a4..2ec9fc3 100644
--- a/dijit/layout/BorderContainer.js
+++ b/dijit/layout/BorderContainer.js
@@ -6,551 +6,475 @@ define([
 	"dojo/dom-construct", // domConstruct.destroy domConstruct.place
 	"dojo/dom-geometry", // domGeometry.marginBox
 	"dojo/dom-style", // domStyle.style
-	"dojo/_base/event", // event.stop
 	"dojo/keys",
-	"dojo/_base/lang", // lang.getObject lang.hitch
+	"dojo/_base/lang", // getObject() hitch() delegate()
 	"dojo/on",
 	"dojo/touch",
-	"dojo/_base/window", // win.body win.doc win.doc.createElement
 	"../_WidgetBase",
 	"../_Widget",
 	"../_TemplatedMixin",
-	"./_LayoutWidget",
-	"./utils"		// layoutUtils.layoutChildren
-], function(array, cookie, declare, domClass, domConstruct, domGeometry, domStyle, event, keys, lang, on, touch, win,
-			_WidgetBase, _Widget, _TemplatedMixin, _LayoutWidget, layoutUtils){
-
-/*=====
-	var _WidgetBase = dijit._WidgetBase;
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _LayoutWidget = dijit.layout._LayoutWidget;
-=====*/
-
-// module:
-//		dijit/layout/BorderContainer
-// summary:
-//		Provides layout in up to 5 regions, a mandatory center with optional borders along its 4 sides.
-
-var _Splitter = declare("dijit.layout._Splitter", [_Widget, _TemplatedMixin ],
-{
-	// summary:
-	//		A draggable spacer between two items in a `dijit.layout.BorderContainer`.
-	// description:
-	//		This is instantiated by `dijit.layout.BorderContainer`.  Users should not
-	//		create it directly.
-	// tags:
-	//		private
-
-/*=====
- 	// container: [const] dijit.layout.BorderContainer
- 	//		Pointer to the parent BorderContainer
-	container: null,
-
-	// child: [const] dijit.layout._LayoutWidget
-	//		Pointer to the pane associated with this splitter
-	child: null,
-
-	// region: [const] String
-	//		Region of pane associated with this splitter.
-	//		"top", "bottom", "left", "right".
-	region: null,
-=====*/
-
-	// live: [const] Boolean
-	//		If true, the child's size changes and the child widget is redrawn as you drag the splitter;
-	//		otherwise, the size doesn't change until you drop the splitter (by mouse-up)
-	live: true,
-
-	templateString: '<div class="dijitSplitter" data-dojo-attach-event="onkeypress:_onKeyPress,press:_startDrag,onmouseenter:_onMouse,onmouseleave:_onMouse" tabIndex="0" role="separator"><div class="dijitSplitterThumb"></div></div>',
-
-	constructor: function(){
-		this._handlers = [];
-	},
-
-	postMixInProperties: function(){
-		this.inherited(arguments);
-
-		this.horizontal = /top|bottom/.test(this.region);
-		this._factor = /top|left/.test(this.region) ? 1 : -1;
-		this._cookieName = this.container.id + "_" + this.region;
-	},
-
-	buildRendering: function(){
-		this.inherited(arguments);
-
-		domClass.add(this.domNode, "dijitSplitter" + (this.horizontal ? "H" : "V"));
-
-		if(this.container.persist){
-			// restore old size
-			var persistSize = cookie(this._cookieName);
-			if(persistSize){
-				this.child.domNode.style[this.horizontal ? "height" : "width"] = persistSize;
-			}
-		}
-	},
+	"./LayoutContainer",
+	"./utils"        // layoutUtils.layoutChildren
+], function(array, cookie, declare, domClass, domConstruct, domGeometry, domStyle, keys, lang, on, touch,
+			_WidgetBase, _Widget, _TemplatedMixin, LayoutContainer, layoutUtils){
+
+	// module:
+	//		dijit/layout/BorderContainer
 
-	_computeMaxSize: function(){
+	var _Splitter = declare("dijit.layout._Splitter", [_Widget, _TemplatedMixin ], {
 		// summary:
-		//		Return the maximum size that my corresponding pane can be set to
+		//		A draggable spacer between two items in a `dijit/layout/BorderContainer`.
+		// description:
+		//		This is instantiated by `dijit/layout/BorderContainer`.  Users should not
+		//		create it directly.
+		// tags:
+		//		private
 
-		var dim = this.horizontal ? 'h' : 'w',
-			childSize = domGeometry.getMarginBox(this.child.domNode)[dim],
-			center = array.filter(this.container.getChildren(), function(child){ return child.region == "center";})[0],
-			spaceAvailable = domGeometry.getMarginBox(center.domNode)[dim];	// can expand until center is crushed to 0
+		/*=====
+		 // container: [const] dijit/layout/BorderContainer
+		 //		Pointer to the parent BorderContainer
+		 container: null,
 
-		return Math.min(this.child.maxSize, childSize + spaceAvailable);
-	},
+		 // child: [const] dijit/layout/_LayoutWidget
+		 //		Pointer to the pane associated with this splitter
+		 child: null,
 
-	_startDrag: function(e){
-		if(!this.cover){
-			this.cover = win.doc.createElement('div');
-			domClass.add(this.cover, "dijitSplitterCover");
-			domConstruct.place(this.cover, this.child.domNode, "after");
-		}
-		domClass.add(this.cover, "dijitSplitterCoverActive");
-
-		// Safeguard in case the stop event was missed.  Shouldn't be necessary if we always get the mouse up.
-		if(this.fake){ domConstruct.destroy(this.fake); }
-		if(!(this._resize = this.live)){ //TODO: disable live for IE6?
-			// create fake splitter to display at old position while we drag
-			(this.fake = this.domNode.cloneNode(true)).removeAttribute("id");
-			domClass.add(this.domNode, "dijitSplitterShadow");
-			domConstruct.place(this.fake, this.domNode, "after");
-		}
-		domClass.add(this.domNode, "dijitSplitterActive dijitSplitter" + (this.horizontal ? "H" : "V") + "Active");
-		if(this.fake){
-			domClass.remove(this.fake, "dijitSplitterHover dijitSplitter" + (this.horizontal ? "H" : "V") + "Hover");
-		}
-
-		//Performance: load data info local vars for onmousevent function closure
-		var factor = this._factor,
-			isHorizontal = this.horizontal,
-			axis = isHorizontal ? "pageY" : "pageX",
-			pageStart = e[axis],
-			splitterStyle = this.domNode.style,
-			dim = isHorizontal ? 'h' : 'w',
-			childStart = domGeometry.getMarginBox(this.child.domNode)[dim],
-			max = this._computeMaxSize(),
-			min = this.child.minSize || 20,
-			region = this.region,
-			splitterAttr = region == "top" || region == "bottom" ? "top" : "left",	// style attribute of splitter to adjust
-			splitterStart = parseInt(splitterStyle[splitterAttr], 10),
-			resize = this._resize,
-			layoutFunc = lang.hitch(this.container, "_layoutChildren", this.child.id),
-			de = win.doc;
-
-		this._handlers = this._handlers.concat([
-			on(de, touch.move, this._drag = function(e, forceResize){
-				var delta = e[axis] - pageStart,
-					childSize = factor * delta + childStart,
-					boundChildSize = Math.max(Math.min(childSize, max), min);
-
-				if(resize || forceResize){
-					layoutFunc(boundChildSize);
-				}
-				// TODO: setting style directly (usually) sets content box size, need to set margin box size
-				splitterStyle[splitterAttr] = delta + splitterStart + factor*(boundChildSize - childSize) + "px";
-			}),
-			on(de, "dragstart", event.stop),
-			on(win.body(), "selectstart", event.stop),
-			on(de, touch.release, lang.hitch(this, "_stopDrag"))
-		]);
-		event.stop(e);
-	},
-
-	_onMouse: function(e){
-		// summary:
-		//		Handler for onmouseenter / onmouseleave events
-		var o = (e.type == "mouseover" || e.type == "mouseenter");
-		domClass.toggle(this.domNode, "dijitSplitterHover", o);
-		domClass.toggle(this.domNode, "dijitSplitter" + (this.horizontal ? "H" : "V") + "Hover", o);
-	},
-
-	_stopDrag: function(e){
-		try{
-			if(this.cover){
-				domClass.remove(this.cover, "dijitSplitterCoverActive");
-			}
-			if(this.fake){ domConstruct.destroy(this.fake); }
-			domClass.remove(this.domNode, "dijitSplitterActive dijitSplitter"
-				+ (this.horizontal ? "H" : "V") + "Active dijitSplitterShadow");
-			this._drag(e); //TODO: redundant with onmousemove?
-			this._drag(e, true);
-		}finally{
-			this._cleanupHandlers();
-			delete this._drag;
-		}
+		 // region: [const] String
+		 //		Region of pane associated with this splitter.
+		 //		"top", "bottom", "left", "right".
+		 region: null,
+		 =====*/
 
-		if(this.container.persist){
-			cookie(this._cookieName, this.child.domNode.style[this.horizontal ? "height" : "width"], {expires:365});
-		}
-	},
-
-	_cleanupHandlers: function(){
-		var h;
-		while(h = this._handlers.pop()){ h.remove(); }
-	},
-
-	_onKeyPress: function(/*Event*/ e){
-		// should we apply typematic to this?
-		this._resize = true;
-		var horizontal = this.horizontal;
-		var tick = 1;
-		switch(e.charOrCode){
-			case horizontal ? keys.UP_ARROW : keys.LEFT_ARROW:
-				tick *= -1;
-//				break;
-			case horizontal ? keys.DOWN_ARROW : keys.RIGHT_ARROW:
-				break;
-			default:
-//				this.inherited(arguments);
-				return;
-		}
-		var childSize = domGeometry.getMarginSize(this.child.domNode)[ horizontal ? 'h' : 'w' ] + this._factor * tick;
-		this.container._layoutChildren(this.child.id, Math.max(Math.min(childSize, this._computeMaxSize()), this.child.minSize));
-		event.stop(e);
-	},
-
-	destroy: function(){
-		this._cleanupHandlers();
-		delete this.child;
-		delete this.container;
-		delete this.cover;
-		delete this.fake;
-		this.inherited(arguments);
-	}
-});
+		// live: [const] Boolean
+		//		If true, the child's size changes and the child widget is redrawn as you drag the splitter;
+		//		otherwise, the size doesn't change until you drop the splitter (by mouse-up)
+		live: true,
 
-var _Gutter = declare("dijit.layout._Gutter", [_Widget, _TemplatedMixin],
-{
-	// summary:
-	// 		Just a spacer div to separate side pane from center pane.
-	//		Basically a trick to lookup the gutter/splitter width from the theme.
-	// description:
-	//		Instantiated by `dijit.layout.BorderContainer`.  Users should not
-	//		create directly.
-	// tags:
-	//		private
-
-	templateString: '<div class="dijitGutter" role="presentation"></div>',
-
-	postMixInProperties: function(){
-		this.inherited(arguments);
-		this.horizontal = /top|bottom/.test(this.region);
-	},
-
-	buildRendering: function(){
-		this.inherited(arguments);
-		domClass.add(this.domNode, "dijitGutter" + (this.horizontal ? "H" : "V"));
-	}
-});
+		templateString: '<div class="dijitSplitter" data-dojo-attach-event="onkeydown:_onKeyDown,press:_startDrag,onmouseenter:_onMouse,onmouseleave:_onMouse" tabIndex="0" role="separator"><div class="dijitSplitterThumb"></div></div>',
 
-var BorderContainer = declare("dijit.layout.BorderContainer", _LayoutWidget, {
-	// summary:
-	//		Provides layout in up to 5 regions, a mandatory center with optional borders along its 4 sides.
-	//
-	// description:
-	//		A BorderContainer is a box with a specified size, such as style="width: 500px; height: 500px;",
-	//		that contains a child widget marked region="center" and optionally children widgets marked
-	//		region equal to "top", "bottom", "leading", "trailing", "left" or "right".
-	//		Children along the edges will be laid out according to width or height dimensions and may
-	//		include optional splitters (splitter="true") to make them resizable by the user.  The remaining
-	//		space is designated for the center region.
-	//
-	//		The outer size must be specified on the BorderContainer node.  Width must be specified for the sides
-	//		and height for the top and bottom, respectively.  No dimensions should be specified on the center;
-	//		it will fill the remaining space.  Regions named "leading" and "trailing" may be used just like
-	//		"left" and "right" except that they will be reversed in right-to-left environments.
-	//
-	//		For complex layouts, multiple children can be specified for a single region.   In this case, the
-	//		layoutPriority flag on the children determines which child is closer to the edge (low layoutPriority)
-	//		and which child is closer to the center (high layoutPriority).   layoutPriority can also be used
-	//		instead of the design attribute to control layout precedence of horizontal vs. vertical panes.
-	// example:
-	// |	<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="design: 'sidebar', gutters: false"
-	// |            style="width: 400px; height: 300px;">
-	// |		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">header text</div>
-	// |		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'right', splitter: true" style="width: 200px;">table of contents</div>
-	// |		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center'">client area</div>
-	// |	</div>
-
-	// design: String
-	//		Which design is used for the layout:
-	//			- "headline" (default) where the top and bottom extend
-	//				the full width of the container
-	//			- "sidebar" where the left and right sides extend from top to bottom.
-	design: "headline",
-
-	// gutters: [const] Boolean
-	//		Give each pane a border and margin.
-	//		Margin determined by domNode.paddingLeft.
-	//		When false, only resizable panes have a gutter (i.e. draggable splitter) for resizing.
-	gutters: true,
-
-	// liveSplitters: [const] Boolean
-	//		Specifies whether splitters resize as you drag (true) or only upon mouseup (false)
-	liveSplitters: true,
-
-	// persist: Boolean
-	//		Save splitter positions in a cookie.
-	persist: false,
-
-	baseClass: "dijitBorderContainer",
-
-	// _splitterClass: Function||String
-	// 		Optional hook to override the default Splitter widget used by BorderContainer
-	_splitterClass: _Splitter,
-
-	postMixInProperties: function(){
-		// change class name to indicate that BorderContainer is being used purely for
-		// layout (like LayoutContainer) rather than for pretty formatting.
-		if(!this.gutters){
-			this.baseClass += "NoGutter";
-		}
-		this.inherited(arguments);
-	},
+		constructor: function(){
+			this._handlers = [];
+		},
 
-	startup: function(){
-		if(this._started){ return; }
-		array.forEach(this.getChildren(), this._setupChild, this);
-		this.inherited(arguments);
-	},
+		postMixInProperties: function(){
+			this.inherited(arguments);
 
-	_setupChild: function(/*dijit._Widget*/ child){
-		// Override _LayoutWidget._setupChild().
+			this.horizontal = /top|bottom/.test(this.region);
+			this._factor = /top|left/.test(this.region) ? 1 : -1;
+			this._cookieName = this.container.id + "_" + this.region;
+		},
 
-		var region = child.region;
-		if(region){
+		buildRendering: function(){
 			this.inherited(arguments);
 
-			domClass.add(child.domNode, this.baseClass+"Pane");
+			domClass.add(this.domNode, "dijitSplitter" + (this.horizontal ? "H" : "V"));
+
+			if(this.container.persist){
+				// restore old size
+				var persistSize = cookie(this._cookieName);
+				if(persistSize){
+					this.child.domNode.style[this.horizontal ? "height" : "width"] = persistSize;
+				}
+			}
+		},
+
+		_computeMaxSize: function(){
+			// summary:
+			//		Return the maximum size that my corresponding pane can be set to
+
+			var dim = this.horizontal ? 'h' : 'w',
+				childSize = domGeometry.getMarginBox(this.child.domNode)[dim],
+				center = array.filter(this.container.getChildren(), function(child){
+					return child.region == "center";
+				})[0];
 
-			var ltr = this.isLeftToRight();
-			if(region == "leading"){ region = ltr ? "left" : "right"; }
-			if(region == "trailing"){ region = ltr ? "right" : "left"; }
+			// Can expand until center is crushed.  But always leave room for center's padding + border,
+			//  otherwise on the next call domGeometry methods start to lie about size.
+			var spaceAvailable = domGeometry.getContentBox(center.domNode)[dim] - 10;
+
+			return Math.min(this.child.maxSize, childSize + spaceAvailable);
+		},
+
+		_startDrag: function(e){
+			if(!this.cover){
+				this.cover = domConstruct.place("<div class=dijitSplitterCover></div>", this.child.domNode, "after");
+			}
+			domClass.add(this.cover, "dijitSplitterCoverActive");
+
+			// Safeguard in case the stop event was missed.  Shouldn't be necessary if we always get the mouse up.
+			if(this.fake){
+				domConstruct.destroy(this.fake);
+			}
+			if(!(this._resize = this.live)){ //TODO: disable live for IE6?
+				// create fake splitter to display at old position while we drag
+				(this.fake = this.domNode.cloneNode(true)).removeAttribute("id");
+				domClass.add(this.domNode, "dijitSplitterShadow");
+				domConstruct.place(this.fake, this.domNode, "after");
+			}
+			domClass.add(this.domNode, "dijitSplitterActive dijitSplitter" + (this.horizontal ? "H" : "V") + "Active");
+			if(this.fake){
+				domClass.remove(this.fake, "dijitSplitterHover dijitSplitter" + (this.horizontal ? "H" : "V") + "Hover");
+			}
 
-			// Create draggable splitter for resizing pane,
-			// or alternately if splitter=false but BorderContainer.gutters=true then
-			// insert dummy div just for spacing
-			if(region != "center" && (child.splitter || this.gutters) && !child._splitterWidget){
-				var _Splitter = child.splitter ? this._splitterClass : _Gutter;
-				if(lang.isString(_Splitter)){
-					_Splitter = lang.getObject(_Splitter);	// for back-compat, remove in 2.0
+			//Performance: load data info local vars for onmousevent function closure
+			var factor = this._factor,
+				isHorizontal = this.horizontal,
+				axis = isHorizontal ? "pageY" : "pageX",
+				pageStart = e[axis],
+				splitterStyle = this.domNode.style,
+				dim = isHorizontal ? 'h' : 'w',
+				childCS = domStyle.getComputedStyle(this.child.domNode),
+				childStart = domGeometry.getMarginBox(this.child.domNode, childCS)[dim],
+				max = this._computeMaxSize(),
+				min = Math.max(this.child.minSize, domGeometry.getPadBorderExtents(this.child.domNode, childCS)[dim] + 10),
+				region = this.region,
+				splitterAttr = region == "top" || region == "bottom" ? "top" : "left", // style attribute of splitter to adjust
+				splitterStart = parseInt(splitterStyle[splitterAttr], 10),
+				resize = this._resize,
+				layoutFunc = lang.hitch(this.container, "_layoutChildren", this.child.id),
+				de = this.ownerDocument;
+
+			this._handlers = this._handlers.concat([
+				on(de, touch.move, this._drag = function(e, forceResize){
+					var delta = e[axis] - pageStart,
+						childSize = factor * delta + childStart,
+						boundChildSize = Math.max(Math.min(childSize, max), min);
+
+					if(resize || forceResize){
+						layoutFunc(boundChildSize);
+					}
+					// TODO: setting style directly (usually) sets content box size, need to set margin box size
+					splitterStyle[splitterAttr] = delta + splitterStart + factor * (boundChildSize - childSize) + "px";
+				}),
+				on(de, "dragstart", function(e){
+					e.stopPropagation();
+					e.preventDefault();
+				}),
+				on(this.ownerDocumentBody, "selectstart", function(e){
+					e.stopPropagation();
+					e.preventDefault();
+				}),
+				on(de, touch.release, lang.hitch(this, "_stopDrag"))
+			]);
+			e.stopPropagation();
+			e.preventDefault();
+		},
+
+		_onMouse: function(e){
+			// summary:
+			//		Handler for onmouseenter / onmouseleave events
+			var o = (e.type == "mouseover" || e.type == "mouseenter");
+			domClass.toggle(this.domNode, "dijitSplitterHover", o);
+			domClass.toggle(this.domNode, "dijitSplitter" + (this.horizontal ? "H" : "V") + "Hover", o);
+		},
+
+		_stopDrag: function(e){
+			try{
+				if(this.cover){
+					domClass.remove(this.cover, "dijitSplitterCoverActive");
+				}
+				if(this.fake){
+					domConstruct.destroy(this.fake);
 				}
-				var splitter = new _Splitter({
-					id: child.id + "_splitter",
-					container: this,
-					child: child,
-					region: region,
-					live: this.liveSplitters
-				});
-				splitter.isSplitter = true;
-				child._splitterWidget = splitter;
-
-				domConstruct.place(splitter.domNode, child.domNode, "after");
-
-				// Splitters aren't added as Contained children, so we need to call startup explicitly
-				splitter.startup();
+				domClass.remove(this.domNode, "dijitSplitterActive dijitSplitter"
+					+ (this.horizontal ? "H" : "V") + "Active dijitSplitterShadow");
+				this._drag(e); //TODO: redundant with onmousemove?
+				this._drag(e, true);
+			}finally{
+				this._cleanupHandlers();
+				delete this._drag;
 			}
-			child.region = region;	// TODO: technically wrong since it overwrites "trailing" with "left" etc.
-		}
-	},
-
-	layout: function(){
-		// Implement _LayoutWidget.layout() virtual method.
-		this._layoutChildren();
-	},
-
-	addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
-		// Override _LayoutWidget.addChild().
-		this.inherited(arguments);
-		if(this._started){
-			this.layout(); //OPT
-		}
-	},
 
-	removeChild: function(/*dijit._Widget*/ child){
-		// Override _LayoutWidget.removeChild().
+			if(this.container.persist){
+				cookie(this._cookieName, this.child.domNode.style[this.horizontal ? "height" : "width"], {expires: 365});
+			}
+		},
 
-		var region = child.region;
-		var splitter = child._splitterWidget;
-		if(splitter){
-			splitter.destroy();
-			delete child._splitterWidget;
-		}
-		this.inherited(arguments);
+		_cleanupHandlers: function(){
+			var h;
+			while(h = this._handlers.pop()){
+				h.remove();
+			}
+		},
+
+		_onKeyDown: function(/*Event*/ e){
+			// should we apply typematic to this?
+			this._resize = true;
+			var horizontal = this.horizontal;
+			var tick = 1;
+			switch(e.keyCode){
+				case horizontal ? keys.UP_ARROW : keys.LEFT_ARROW:
+					tick *= -1;
+//				break;
+				case horizontal ? keys.DOWN_ARROW : keys.RIGHT_ARROW:
+					break;
+				default:
+//				this.inherited(arguments);
+					return;
+			}
+			var childSize = domGeometry.getMarginSize(this.child.domNode)[ horizontal ? 'h' : 'w' ] + this._factor * tick;
+			this.container._layoutChildren(this.child.id, Math.max(Math.min(childSize, this._computeMaxSize()), this.child.minSize));
+			e.stopPropagation();
+			e.preventDefault();
+		},
 
-		if(this._started){
-			this._layoutChildren();
+		destroy: function(){
+			this._cleanupHandlers();
+			delete this.child;
+			delete this.container;
+			delete this.cover;
+			delete this.fake;
+			this.inherited(arguments);
 		}
-		// Clean up whatever style changes we made to the child pane.
-		// Unclear how height and width should be handled.
-		domClass.remove(child.domNode, this.baseClass+"Pane");
-		domStyle.set(child.domNode, {
-			top: "auto",
-			bottom: "auto",
-			left: "auto",
-			right: "auto",
-			position: "static"
-		});
-		domStyle.set(child.domNode, region == "top" || region == "bottom" ? "width" : "height", "auto");
-	},
-
-	getChildren: function(){
-		// Override _LayoutWidget.getChildren() to only return real children, not the splitters.
-		return array.filter(this.inherited(arguments), function(widget){
-			return !widget.isSplitter;
-		});
-	},
-
-	// TODO: remove in 2.0
-	getSplitter: function(/*String*/region){
+	});
+
+	var _Gutter = declare("dijit.layout._Gutter", [_Widget, _TemplatedMixin], {
 		// summary:
-		//		Returns the widget responsible for rendering the splitter associated with region
+		//		Just a spacer div to separate side pane from center pane.
+		//		Basically a trick to lookup the gutter/splitter width from the theme.
+		// description:
+		//		Instantiated by `dijit/layout/BorderContainer`.  Users should not
+		//		create directly.
 		// tags:
-		//		deprecated
-		return array.filter(this.getChildren(), function(child){
-			return child.region == region;
-		})[0]._splitterWidget;
-	},
-
-	resize: function(newSize, currentSize){
-		// Overrides _LayoutWidget.resize().
-
-		// resetting potential padding to 0px to provide support for 100% width/height + padding
-		// TODO: this hack doesn't respect the box model and is a temporary fix
-		if(!this.cs || !this.pe){
-			var node = this.domNode;
-			this.cs = domStyle.getComputedStyle(node);
-			this.pe = domGeometry.getPadExtents(node, this.cs);
-			this.pe.r = domStyle.toPixelValue(node, this.cs.paddingRight);
-			this.pe.b = domStyle.toPixelValue(node, this.cs.paddingBottom);
-
-			domStyle.set(node, "padding", "0px");
-		}
+		//		private
 
-		this.inherited(arguments);
-	},
+		templateString: '<div class="dijitGutter" role="presentation"></div>',
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			this.horizontal = /top|bottom/.test(this.region);
+		},
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			domClass.add(this.domNode, "dijitGutter" + (this.horizontal ? "H" : "V"));
+		}
+	});
 
-	_layoutChildren: function(/*String?*/ changedChildId, /*Number?*/ changedChildSize){
+	var BorderContainer = declare("dijit.layout.BorderContainer", LayoutContainer, {
 		// summary:
-		//		This is the main routine for setting size/position of each child.
-		// description:
-		//		With no arguments, measures the height of top/bottom panes, the width
-		//		of left/right panes, and then sizes all panes accordingly.
+		//		A BorderContainer is a `dijit/LayoutContainer` that can have draggable splitters between the children,
+		//		in order to adjust their sizes.
 		//
-		//		With changedRegion specified (as "left", "top", "bottom", or "right"),
-		//		it changes that region's width/height to changedRegionSize and
-		//		then resizes other regions that were affected.
-		// changedChildId:
-		//		Id of the child which should be resized because splitter was dragged.
-		// changedChildSize:
-		//		The new width/height (in pixels) to make specified child
-
-		if(!this._borderBox || !this._borderBox.h){
-			// We are currently hidden, or we haven't been sized by our parent yet.
-			// Abort.   Someone will resize us later.
-			return;
-		}
+		//		In addition, it automatically adds some space between the children even
+		//		if they don't have a draggable splitter between them, and space between the edge of the BorderContainer
+		//		and the children that are adjacent to the edge.  Note that the intended style is that all the children
+		//		have borders, but (despite the name) the BorderContainer itself does not.
+		//
+		//		See `BorderContainer.ChildWidgetProperties` for details on the properties that can be set on
+		//		children of a `BorderContainer`.
+
+		// gutters: [const] Boolean
+		//		Give each pane a border and margin.
+		//		Margin determined by domNode.paddingLeft.
+		//		When false, only resizable panes have a gutter (i.e. draggable splitter) for resizing.
+		gutters: true,
+
+		// liveSplitters: [const] Boolean
+		//		Specifies whether splitters resize as you drag (true) or only upon mouseup (false)
+		liveSplitters: true,
+
+		// persist: Boolean
+		//		Save splitter positions in a cookie.
+		persist: false,
+
+		baseClass: "dijitBorderContainer",
+
+		// _splitterClass: Function||String
+		//		Optional hook to override the default Splitter widget used by BorderContainer
+		_splitterClass: _Splitter,
+
+		postMixInProperties: function(){
+			// change class name to indicate that BorderContainer is being used purely for
+			// layout (like LayoutContainer) rather than for pretty formatting.
+			if(!this.gutters){
+				this.baseClass += "NoGutter";
+			}
+			this.inherited(arguments);
+		},
 
-		// Generate list of wrappers of my children in the order that I want layoutChildren()
-		// to process them (i.e. from the outside to the inside)
-		var wrappers = array.map(this.getChildren(), function(child, idx){
-			return {
-				pane: child,
-				weight: [
-					child.region == "center" ? Infinity : 0,
-					child.layoutPriority,
-					(this.design == "sidebar" ? 1 : -1) * (/top|bottom/.test(child.region) ? 1 : -1),
-					idx
-				]
-			};
-		}, this);
-		wrappers.sort(function(a, b){
-			var aw = a.weight, bw = b.weight;
-			for(var i=0; i<aw.length; i++){
-				if(aw[i] != bw[i]){
-					return aw[i] - bw[i];
-				}
+		_setupChild: function(/*dijit/_WidgetBase*/ child){
+			// Override LayoutContainer._setupChild().
+
+			this.inherited(arguments);
+
+			var region = child.region, ltr = child.isLeftToRight();
+			if(region == "leading"){
+				region = ltr ? "left" : "right";
 			}
-			return 0;
-		});
-
-		// Make new list, combining the externally specified children with splitters and gutters
-		var childrenAndSplitters = [];
-		array.forEach(wrappers, function(wrapper){
-			var pane = wrapper.pane;
-			childrenAndSplitters.push(pane);
-			if(pane._splitterWidget){
-				childrenAndSplitters.push(pane._splitterWidget);
+			if(region == "trailing"){
+				region = ltr ? "right" : "left";
 			}
-		});
-
-		// Compute the box in which to lay out my children
-		var dim = {
-			l: this.pe.l,
-			t: this.pe.t,
-			w: this._borderBox.w - this.pe.w,
-			h: this._borderBox.h - this.pe.h
-		};
-
-		// Layout the children, possibly changing size due to a splitter drag
-		layoutUtils.layoutChildren(this.domNode, dim, childrenAndSplitters,
-			changedChildId, changedChildSize);
-	},
-
-	destroyRecursive: function(){
-		// Destroy splitters first, while getChildren() still works
-		array.forEach(this.getChildren(), function(child){
+
+			if(region){
+				// Create draggable splitter for resizing pane,
+				// or alternately if splitter=false but BorderContainer.gutters=true then
+				// insert dummy div just for spacing
+				if(region != "center" && (child.splitter || this.gutters) && !child._splitterWidget){
+					var _Splitter = child.splitter ? this._splitterClass : _Gutter;
+					if(lang.isString(_Splitter)){
+						_Splitter = lang.getObject(_Splitter);	// for back-compat, remove in 2.0
+					}
+					var splitter = new _Splitter({
+						id: child.id + "_splitter",
+						container: this,
+						child: child,
+						region: region,
+						live: this.liveSplitters
+					});
+					splitter.isSplitter = true;
+					child._splitterWidget = splitter;
+
+					// Make the tab order match the visual layout by placing the splitter before or after the pane,
+					// depending on where the splitter is visually compared to the pane.
+					var before = region == "bottom" || region == (this.isLeftToRight() ? "right" : "left");
+					domConstruct.place(splitter.domNode, child.domNode, before ? "before" : "after");
+
+					// Splitters aren't added as Contained children, so we need to call startup explicitly
+					splitter.startup();
+				}
+			}
+		},
+
+		layout: function(){
+			// Implement _LayoutWidget.layout() virtual method.
+			this._layoutChildren();
+		},
+
+		removeChild: function(/*dijit/_WidgetBase*/ child){
+			// Override _LayoutWidget.removeChild().
+
 			var splitter = child._splitterWidget;
 			if(splitter){
 				splitter.destroy();
+				delete child._splitterWidget;
 			}
-			delete child._splitterWidget;
-		});
 
-		// Then destroy the real children, and myself
-		this.inherited(arguments);
-	}
-});
+			this.inherited(arguments);
+		},
+
+		getChildren: function(){
+			// Override _LayoutWidget.getChildren() to only return real children, not the splitters.
+			return array.filter(this.inherited(arguments), function(widget){
+				return !widget.isSplitter;
+			});
+		},
+
+		// TODO: remove in 2.0
+		getSplitter: function(/*String*/region){
+			// summary:
+			//		Returns the widget responsible for rendering the splitter associated with region
+			// tags:
+			//		deprecated
+			return array.filter(this.getChildren(), function(child){
+				return child.region == region;
+			})[0]._splitterWidget;
+		},
+
+		resize: function(newSize, currentSize){
+			// Overrides _LayoutWidget.resize().
+
+			// resetting potential padding to 0px to provide support for 100% width/height + padding
+			// TODO: this hack doesn't respect the box model and is a temporary fix
+			if(!this.cs || !this.pe){
+				var node = this.domNode;
+				this.cs = domStyle.getComputedStyle(node);
+				this.pe = domGeometry.getPadExtents(node, this.cs);
+				this.pe.r = domStyle.toPixelValue(node, this.cs.paddingRight);
+				this.pe.b = domStyle.toPixelValue(node, this.cs.paddingBottom);
+
+				domStyle.set(node, "padding", "0px");
+			}
 
-// This argument can be specified for the children of a BorderContainer.
-// Since any widget can be specified as a LayoutContainer child, mix it
-// into the base widget class.  (This is a hack, but it's effective.)
-lang.extend(_WidgetBase, {
-	// region: [const] String
-	//		Parameter for children of `dijit.layout.BorderContainer`.
-	//		Values: "top", "bottom", "leading", "trailing", "left", "right", "center".
-	//		See the `dijit.layout.BorderContainer` description for details.
-	region: '',
-
-	// layoutPriority: [const] Number
-	//		Parameter for children of `dijit.layout.BorderContainer`.
-	//		Children with a higher layoutPriority will be placed closer to the BorderContainer center,
-	//		between children with a lower layoutPriority.
-	layoutPriority: 0,
-
-	// splitter: [const] Boolean
-	//		Parameter for child of `dijit.layout.BorderContainer` where region != "center".
-	//		If true, enables user to resize the widget by putting a draggable splitter between
-	//		this widget and the region=center widget.
-	splitter: false,
-
-	// minSize: [const] Number
-	//		Parameter for children of `dijit.layout.BorderContainer`.
-	//		Specifies a minimum size (in pixels) for this widget when resized by a splitter.
-	minSize: 0,
-
-	// maxSize: [const] Number
-	//		Parameter for children of `dijit.layout.BorderContainer`.
-	//		Specifies a maximum size (in pixels) for this widget when resized by a splitter.
-	maxSize: Infinity
-});
+			this.inherited(arguments);
+		},
+
+		_layoutChildren: function(/*String?*/ changedChildId, /*Number?*/ changedChildSize){
+			// summary:
+			//		This is the main routine for setting size/position of each child.
+			// description:
+			//		With no arguments, measures the height of top/bottom panes, the width
+			//		of left/right panes, and then sizes all panes accordingly.
+			//
+			//		With changedRegion specified (as "left", "top", "bottom", or "right"),
+			//		it changes that region's width/height to changedRegionSize and
+			//		then resizes other regions that were affected.
+			// changedChildId:
+			//		Id of the child which should be resized because splitter was dragged.
+			// changedChildSize:
+			//		The new width/height (in pixels) to make specified child
+
+			if(!this._borderBox || !this._borderBox.h){
+				// We are currently hidden, or we haven't been sized by our parent yet.
+				// Abort.   Someone will resize us later.
+				return;
+			}
+
+			// Combining the externally specified children with splitters and gutters
+			var childrenAndSplitters = [];
+			array.forEach(this._getOrderedChildren(), function(pane){
+				childrenAndSplitters.push(pane);
+				if(pane._splitterWidget){
+					childrenAndSplitters.push(pane._splitterWidget);
+				}
+			});
+
+			// Compute the box in which to lay out my children
+			var dim = {
+				l: this.pe.l,
+				t: this.pe.t,
+				w: this._borderBox.w - this.pe.w,
+				h: this._borderBox.h - this.pe.h
+			};
 
-// For monkey patching
-BorderContainer._Splitter = _Splitter;
-BorderContainer._Gutter = _Gutter;
+			// Layout the children, possibly changing size due to a splitter drag
+			layoutUtils.layoutChildren(this.domNode, dim, childrenAndSplitters,
+				changedChildId, changedChildSize);
+		},
+
+		destroyRecursive: function(){
+			// Destroy splitters first, while getChildren() still works
+			array.forEach(this.getChildren(), function(child){
+				var splitter = child._splitterWidget;
+				if(splitter){
+					splitter.destroy();
+				}
+				delete child._splitterWidget;
+			});
 
-return BorderContainer;
+			// Then destroy the real children, and myself
+			this.inherited(arguments);
+		}
+	});
+
+	BorderContainer.ChildWidgetProperties = {
+		// summary:
+		//		These properties can be specified for the children of a BorderContainer.
+
+		// splitter: [const] Boolean
+		//		Parameter for children where region != "center".
+		//		If true, enables user to resize the widget by putting a draggable splitter between
+		//		this widget and the region=center widget.
+		splitter: false,
+
+		// minSize: [const] Number
+		//		Specifies a minimum size (in pixels) for this widget when resized by a splitter.
+		minSize: 0,
+
+		// maxSize: [const] Number
+		//		Specifies a maximum size (in pixels) for this widget when resized by a splitter.
+		maxSize: Infinity
+	};
+	lang.mixin(BorderContainer.ChildWidgetProperties, LayoutContainer.ChildWidgetProperties);
+
+	// Since any widget can be specified as a BorderContainer child, mix it
+	// into the base widget class.  (This is a hack, but it's effective.)
+	// This is for the benefit of the parser.   Remove for 2.0.  Also, hide from doc viewer.
+	lang.extend(_WidgetBase, /*===== {} || =====*/ BorderContainer.ChildWidgetProperties);
+
+	// For monkey patching
+	BorderContainer._Splitter = _Splitter;
+	BorderContainer._Gutter = _Gutter;
+
+	return BorderContainer;
 });
diff --git a/dijit/layout/ContentPane.js b/dijit/layout/ContentPane.js
index 319ef60..c8b647e 100644
--- a/dijit/layout/ContentPane.js
+++ b/dijit/layout/ContentPane.js
@@ -2,610 +2,652 @@ define([
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/_base/lang", // lang.mixin lang.delegate lang.hitch lang.isFunction lang.isObject
 	"../_Widget",
+	"../_Container",
 	"./_ContentPaneResizeMixin",
 	"dojo/string", // string.substitute
-	"dojo/html", // html._ContentSetter html._emptyNode
+	"dojo/html", // html._ContentSetter
 	"dojo/i18n!../nls/loading",
 	"dojo/_base/array", // array.forEach
 	"dojo/_base/declare", // declare
 	"dojo/_base/Deferred", // Deferred
 	"dojo/dom", // dom.byId
 	"dojo/dom-attr", // domAttr.attr
-	"dojo/_base/window", // win.body win.doc.createDocumentFragment
+	"dojo/dom-construct", // empty()
 	"dojo/_base/xhr", // xhr.get
-	"dojo/i18n" // i18n.getLocalization
-], function(kernel, lang, _Widget, _ContentPaneResizeMixin, string, html, nlsLoading,
-	array, declare, Deferred, dom, domAttr, win, xhr, i18n){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _ContentPaneResizeMixin = dijit.layout._ContentPaneResizeMixin;
-=====*/
-
-// module:
-//		dijit/layout/ContentPane
-// summary:
-//		A widget containing an HTML fragment, specified inline
-//		or by uri.  Fragment may include widgets.
-
-
-return declare("dijit.layout.ContentPane", [_Widget, _ContentPaneResizeMixin], {
-	// summary:
-	//		A widget containing an HTML fragment, specified inline
-	//		or by uri.  Fragment may include widgets.
-	//
-	// description:
-	//		This widget embeds a document fragment in the page, specified
-	//		either by uri, javascript generated markup or DOM reference.
-	//		Any widgets within this content are instantiated and managed,
-	//		but laid out according to the HTML structure.  Unlike IFRAME,
-	//		ContentPane embeds a document fragment as would be found
-	//		inside the BODY tag of a full HTML document.  It should not
-	//		contain the HTML, HEAD, or BODY tags.
-	//		For more advanced functionality with scripts and
-	//		stylesheets, see dojox.layout.ContentPane.  This widget may be
-	//		used stand alone or as a base class for other widgets.
-	//		ContentPane is useful as a child of other layout containers
-	//		such as BorderContainer or TabContainer, but note that those
-	//		widgets can contain any widget as a child.
-	//
-	// example:
-	//		Some quick samples:
-	//		To change the innerHTML: cp.set('content', '<b>new content</b>')
-	//
-	//		Or you can send it a NodeList: cp.set('content', dojo.query('div [class=selected]', userSelection))
-	//
-	//		To do an ajax update: cp.set('href', url)
-
-	// href: String
-	//		The href of the content that displays now.
-	//		Set this at construction if you want to load data externally when the
-	//		pane is shown.  (Set preload=true to load it immediately.)
-	//		Changing href after creation doesn't have any effect; Use set('href', ...);
-	href: "",
-
-	// content: String || DomNode || NodeList || dijit._Widget
-	//		The innerHTML of the ContentPane.
-	//		Note that the initialization parameter / argument to set("content", ...)
-	//		can be a String, DomNode, Nodelist, or _Widget.
-	content: "",
-
-	// extractContent: Boolean
-	//		Extract visible content from inside of <body> .... </body>.
-	//		I.e., strip <html> and <head> (and it's contents) from the href
-	extractContent: false,
-
-	// parseOnLoad: Boolean
-	//		Parse content and create the widgets, if any.
-	parseOnLoad: true,
-
-	// parserScope: String
-	//		Flag passed to parser.  Root for attribute names to search for.   If scopeName is dojo,
-	//		will search for data-dojo-type (or dojoType).  For backwards compatibility
-	//		reasons defaults to dojo._scopeName (which is "dojo" except when
-	//		multi-version support is used, when it will be something like dojo16, dojo20, etc.)
-	parserScope: kernel._scopeName,
-
-	// preventCache: Boolean
-	//		Prevent caching of data from href's by appending a timestamp to the href.
-	preventCache: false,
-
-	// preload: Boolean
-	//		Force load of data on initialization even if pane is hidden.
-	preload: false,
-
-	// refreshOnShow: Boolean
-	//		Refresh (re-download) content when pane goes from hidden to shown
-	refreshOnShow: false,
-
-	// loadingMessage: String
-	//		Message that shows while downloading
-	loadingMessage: "<span class='dijitContentPaneLoading'><span class='dijitInline dijitIconLoading'></span>${loadingState}</span>",
-
-	// errorMessage: String
-	//		Message that shows if an error occurs
-	errorMessage: "<span class='dijitContentPaneError'><span class='dijitInline dijitIconError'></span>${errorState}</span>",
-
-	// isLoaded: [readonly] Boolean
-	//		True if the ContentPane has data in it, either specified
-	//		during initialization (via href or inline content), or set
-	//		via set('content', ...) / set('href', ...)
-	//
-	//		False if it doesn't have any content, or if ContentPane is
-	//		still in the process of downloading href.
-	isLoaded: false,
-
-	baseClass: "dijitContentPane",
-
-	/*======
-	// ioMethod: dojo.xhrGet|dojo.xhrPost
-	//		Function that should grab the content specified via href.
-	ioMethod: dojo.xhrGet,
-	======*/
-
-	// ioArgs: Object
-	//		Parameters to pass to xhrGet() request, for example:
-	// |	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="href: './bar', ioArgs: {timeout: 500}">
-	ioArgs: {},
-
-	// onLoadDeferred: [readonly] dojo.Deferred
-	//		This is the `dojo.Deferred` returned by set('href', ...) and refresh().
-	//		Calling onLoadDeferred.addCallback() or addErrback() registers your
-	//		callback to be called only once, when the prior set('href', ...) call or
-	//		the initial href parameter to the constructor finishes loading.
-	//
-	//		This is different than an onLoad() handler which gets called any time any href
-	//		or content is loaded.
-	onLoadDeferred: null,
-
-	// Cancel _WidgetBase's _setTitleAttr because we don't want the title attribute (used to specify
-	// tab labels) to be copied to ContentPane.domNode... otherwise a tooltip shows up over the
-	// entire pane.
-	_setTitleAttr: null,
-
-	// Flag to parser that I'll parse my contents, so it shouldn't.
-	stopParser: true,
-
-	// template: [private] Boolean
-	//		Flag from the parser that this ContentPane is inside a template
-	//		so the contents are pre-parsed.
-	// (TODO: this declaration can be commented out in 2.0)
-	template: false,
-
-	create: function(params, srcNodeRef){
-		// Convert a srcNodeRef argument into a content parameter, so that the original contents are
-		// processed in the same way as contents set via set("content", ...), calling the parser etc.
-		// Avoid modifying original params object since that breaks NodeList instantiation, see #11906.
-		if((!params || !params.template) && srcNodeRef && !("href" in params) && !("content" in params)){
-			var df = win.doc.createDocumentFragment();
-			srcNodeRef = dom.byId(srcNodeRef);
-			while(srcNodeRef.firstChild){
-				df.appendChild(srcNodeRef.firstChild);
+	"dojo/i18n", // i18n.getLocalization
+	"dojo/when"
+], function(kernel, lang, _Widget, _Container, _ContentPaneResizeMixin, string, html, nlsLoading, array, declare,
+			Deferred, dom, domAttr, domConstruct, xhr, i18n, when){
+
+	// module:
+	//		dijit/layout/ContentPane
+
+	return declare("dijit.layout.ContentPane", [_Widget, _Container, _ContentPaneResizeMixin], {
+		// summary:
+		//		A widget containing an HTML fragment, specified inline
+		//		or by uri.  Fragment may include widgets.
+		//
+		// description:
+		//		This widget embeds a document fragment in the page, specified
+		//		either by uri, javascript generated markup or DOM reference.
+		//		Any widgets within this content are instantiated and managed,
+		//		but laid out according to the HTML structure.  Unlike IFRAME,
+		//		ContentPane embeds a document fragment as would be found
+		//		inside the BODY tag of a full HTML document.  It should not
+		//		contain the HTML, HEAD, or BODY tags.
+		//		For more advanced functionality with scripts and
+		//		stylesheets, see dojox/layout/ContentPane.  This widget may be
+		//		used stand alone or as a base class for other widgets.
+		//		ContentPane is useful as a child of other layout containers
+		//		such as BorderContainer or TabContainer, but note that those
+		//		widgets can contain any widget as a child.
+		//
+		// example:
+		//		Some quick samples:
+		//		To change the innerHTML:
+		// |		cp.set('content', '<b>new content</b>')`
+		//		Or you can send it a NodeList:
+		// |		cp.set('content', dojo.query('div [class=selected]', userSelection))
+		//		To do an ajax update:
+		// |		cp.set('href', url)
+
+		// href: String
+		//		The href of the content that displays now.
+		//		Set this at construction if you want to load data externally when the
+		//		pane is shown.  (Set preload=true to load it immediately.)
+		//		Changing href after creation doesn't have any effect; Use set('href', ...);
+		href: "",
+
+		// content: String|DomNode|NodeList|dijit/_Widget
+		//		The innerHTML of the ContentPane.
+		//		Note that the initialization parameter / argument to set("content", ...)
+		//		can be a String, DomNode, Nodelist, or _Widget.
+		content: "",
+
+		// extractContent: Boolean
+		//		Extract visible content from inside of `<body> .... </body>`.
+		//		I.e., strip `<html>` and `<head>` (and it's contents) from the href
+		extractContent: false,
+
+		// parseOnLoad: Boolean
+		//		Parse content and create the widgets, if any.
+		parseOnLoad: true,
+
+		// parserScope: String
+		//		Flag passed to parser.  Root for attribute names to search for.   If scopeName is dojo,
+		//		will search for data-dojo-type (or dojoType).  For backwards compatibility
+		//		reasons defaults to dojo._scopeName (which is "dojo" except when
+		//		multi-version support is used, when it will be something like dojo16, dojo20, etc.)
+		parserScope: kernel._scopeName,
+
+		// preventCache: Boolean
+		//		Prevent caching of data from href's by appending a timestamp to the href.
+		preventCache: false,
+
+		// preload: Boolean
+		//		Force load of data on initialization even if pane is hidden.
+		preload: false,
+
+		// refreshOnShow: Boolean
+		//		Refresh (re-download) content when pane goes from hidden to shown
+		refreshOnShow: false,
+
+		// loadingMessage: String
+		//		Message that shows while downloading
+		loadingMessage: "<span class='dijitContentPaneLoading'><span class='dijitInline dijitIconLoading'></span>${loadingState}</span>",
+
+		// errorMessage: String
+		//		Message that shows if an error occurs
+		errorMessage: "<span class='dijitContentPaneError'><span class='dijitInline dijitIconError'></span>${errorState}</span>",
+
+		// isLoaded: [readonly] Boolean
+		//		True if the ContentPane has data in it, either specified
+		//		during initialization (via href or inline content), or set
+		//		via set('content', ...) / set('href', ...)
+		//
+		//		False if it doesn't have any content, or if ContentPane is
+		//		still in the process of downloading href.
+		isLoaded: false,
+
+		baseClass: "dijitContentPane",
+
+		/*======
+		 // ioMethod: dojo/_base/xhr.get|dojo._base/xhr.post
+		 //		Function that should grab the content specified via href.
+		 ioMethod: dojo.xhrGet,
+		 ======*/
+
+		// ioArgs: Object
+		//		Parameters to pass to xhrGet() request, for example:
+		// |	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="href: './bar', ioArgs: {timeout: 500}">
+		ioArgs: {},
+
+		// onLoadDeferred: [readonly] dojo.Deferred
+		//		This is the `dojo.Deferred` returned by set('href', ...) and refresh().
+		//		Calling onLoadDeferred.then() registers your
+		//		callback to be called only once, when the prior set('href', ...) call or
+		//		the initial href parameter to the constructor finishes loading.
+		//
+		//		This is different than an onLoad() handler which gets called any time any href
+		//		or content is loaded.
+		onLoadDeferred: null,
+
+		// Cancel _WidgetBase's _setTitleAttr because we don't want the title attribute (used to specify
+		// tab labels) to be copied to ContentPane.domNode... otherwise a tooltip shows up over the
+		// entire pane.
+		_setTitleAttr: null,
+
+		// Flag to parser that I'll parse my contents, so it shouldn't.
+		stopParser: true,
+
+		// template: [private] Boolean
+		//		Flag from the parser that this ContentPane is inside a template
+		//		so the contents are pre-parsed.
+		// TODO: this declaration can be commented out in 2.0
+		template: false,
+
+		markupFactory: function(params, node, ctor){
+			var self = new ctor(params, node);
+
+			// If a parse has started but is waiting for modules to load, then return a Promise for when the parser
+			// finishes.  Don't return a promise though for the case when content hasn't started loading because the
+			// ContentPane is hidden and it has an href (ex: hidden pane of a TabContainer).   In that case we consider
+			// that initialization has already finished.
+			return !self.href && self._contentSetter && self._contentSetter.parseDeferred && !self._contentSetter.parseDeferred.isFulfilled() ?
+				self._contentSetter.parseDeferred.then(function(){
+					return self;
+				}) : self;
+		},
+
+		create: function(params, srcNodeRef){
+			// Convert a srcNodeRef argument into a content parameter, so that the original contents are
+			// processed in the same way as contents set via set("content", ...), calling the parser etc.
+			// Avoid modifying original params object since that breaks NodeList instantiation, see #11906.
+			if((!params || !params.template) && srcNodeRef && !("href" in params) && !("content" in params)){
+				srcNodeRef = dom.byId(srcNodeRef);
+				var df = srcNodeRef.ownerDocument.createDocumentFragment();
+				while(srcNodeRef.firstChild){
+					df.appendChild(srcNodeRef.firstChild);
+				}
+				params = lang.delegate(params, {content: df});
+			}
+			this.inherited(arguments, [params, srcNodeRef]);
+		},
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			var messages = i18n.getLocalization("dijit", "loading", this.lang);
+			this.loadingMessage = string.substitute(this.loadingMessage, messages);
+			this.errorMessage = string.substitute(this.errorMessage, messages);
+		},
+
+		buildRendering: function(){
+			this.inherited(arguments);
+
+			// Since we have no template we need to set this.containerNode ourselves, to make getChildren() work.
+			// For subclasses of ContentPane that do have a template, does nothing.
+			if(!this.containerNode){
+				this.containerNode = this.domNode;
 			}
-			params = lang.delegate(params, {content: df});
-		}
-		this.inherited(arguments, [params, srcNodeRef]);
-	},
-
-	postMixInProperties: function(){
-		this.inherited(arguments);
-		var messages = i18n.getLocalization("dijit", "loading", this.lang);
-		this.loadingMessage = string.substitute(this.loadingMessage, messages);
-		this.errorMessage = string.substitute(this.errorMessage, messages);
-	},
-
-	buildRendering: function(){
-		this.inherited(arguments);
-
-		// Since we have no template we need to set this.containerNode ourselves, to make getChildren() work.
-		// For subclasses of ContentPane that do have a template, does nothing.
-		if(!this.containerNode){
-			this.containerNode = this.domNode;
-		}
 
-		// remove the title attribute so it doesn't show up when hovering
-		// over a node  (TODO: remove in 2.0, no longer needed after #11490)
-		this.domNode.title = "";
+			// remove the title attribute so it doesn't show up when hovering
+			// over a node  (TODO: remove in 2.0, no longer needed after #11490)
+			this.domNode.removeAttribute("title");
+		},
 
-		if(!domAttr.get(this.domNode,"role")){
-			this.domNode.setAttribute("role", "group");
-		}
-	},
+		startup: function(){
+			// summary:
+			//		Call startup() on all children including non _Widget ones like dojo/dnd/Source objects
 
-	startup: function(){
-		// summary:
-		//		Call startup() on all children including non _Widget ones like dojo.dnd.Source objects
+			// This starts all the widgets
+			this.inherited(arguments);
 
-		// This starts all the widgets
-		this.inherited(arguments);
+			// And this catches stuff like dojo/dnd/Source
+			if(this._contentSetter){
+				array.forEach(this._contentSetter.parseResults, function(obj){
+					if(!obj._started && !obj._destroyed && lang.isFunction(obj.startup)){
+						obj.startup();
+						obj._started = true;
+					}
+				}, this);
+			}
+		},
 
-		// And this catches stuff like dojo.dnd.Source
-		if(this._contentSetter){
-			array.forEach(this._contentSetter.parseResults, function(obj){
+		_startChildren: function(){
+			// summary:
+			//		Called when content is loaded.   Calls startup on each child widget.   Similar to ContentPane.startup()
+			//		itself, but avoids marking the ContentPane itself as "restarted" (see #15581).
+
+			// This starts all the widgets
+			array.forEach(this.getChildren(), function(obj){
 				if(!obj._started && !obj._destroyed && lang.isFunction(obj.startup)){
 					obj.startup();
 					obj._started = true;
 				}
-			}, this);
-		}
-	},
-
-	setHref: function(/*String|Uri*/ href){
-		// summary:
-		//		Deprecated.   Use set('href', ...) instead.
-		kernel.deprecated("dijit.layout.ContentPane.setHref() is deprecated. Use set('href', ...) instead.", "", "2.0");
-		return this.set("href", href);
-	},
-	_setHrefAttr: function(/*String|Uri*/ href){
-		// summary:
-		//		Hook so set("href", ...) works.
-		// description:
-		//		Reset the (external defined) content of this pane and replace with new url
-		//		Note: It delays the download until widget is shown if preload is false.
-		//	href:
-		//		url to the page you want to get, must be within the same domain as your mainpage
+			});
 
-		// Cancel any in-flight requests (a set('href', ...) will cancel any in-flight set('href', ...))
-		this.cancel();
+			// And this catches stuff like dojo/dnd/Source
+			if(this._contentSetter){
+				array.forEach(this._contentSetter.parseResults, function(obj){
+					if(!obj._started && !obj._destroyed && lang.isFunction(obj.startup)){
+						obj.startup();
+						obj._started = true;
+					}
+				}, this);
+			}
+		},
+
+		setHref: function(/*String|Uri*/ href){
+			// summary:
+			//		Deprecated.   Use set('href', ...) instead.
+			kernel.deprecated("dijit.layout.ContentPane.setHref() is deprecated. Use set('href', ...) instead.", "", "2.0");
+			return this.set("href", href);
+		},
+		_setHrefAttr: function(/*String|Uri*/ href){
+			// summary:
+			//		Hook so set("href", ...) works.
+			// description:
+			//		Reset the (external defined) content of this pane and replace with new url
+			//		Note: It delays the download until widget is shown if preload is false.
+			// href:
+			//		url to the page you want to get, must be within the same domain as your mainpage
+
+			// Cancel any in-flight requests (a set('href', ...) will cancel any in-flight set('href', ...))
+			this.cancel();
 
-		this.onLoadDeferred = new Deferred(lang.hitch(this, "cancel"));
-		this.onLoadDeferred.addCallback(lang.hitch(this, "onLoad"));
+			this.onLoadDeferred = new Deferred(lang.hitch(this, "cancel"));
+			this.onLoadDeferred.then(lang.hitch(this, "onLoad"));
 
-		this._set("href", href);
+			this._set("href", href);
 
-		// _setHrefAttr() is called during creation and by the user, after creation.
-		// Assuming preload == false, only in the second case do we actually load the URL;
-		// otherwise it's done in startup(), and only if this widget is shown.
-		if(this.preload || (this._created && this._isShown())){
-			this._load();
-		}else{
-			// Set flag to indicate that href needs to be loaded the next time the
-			// ContentPane is made visible
-			this._hrefChanged = true;
-		}
+			// _setHrefAttr() is called during creation and by the user, after creation.
+			// Assuming preload == false, only in the second case do we actually load the URL;
+			// otherwise it's done in startup(), and only if this widget is shown.
+			if(this.preload || (this._created && this._isShown())){
+				this._load();
+			}else{
+				// Set flag to indicate that href needs to be loaded the next time the
+				// ContentPane is made visible
+				this._hrefChanged = true;
+			}
 
-		return this.onLoadDeferred;		// Deferred
-	},
+			return this.onLoadDeferred;		// Deferred
+		},
+
+		setContent: function(/*String|DomNode|Nodelist*/data){
+			// summary:
+			//		Deprecated.   Use set('content', ...) instead.
+			kernel.deprecated("dijit.layout.ContentPane.setContent() is deprecated.  Use set('content', ...) instead.", "", "2.0");
+			this.set("content", data);
+		},
+		_setContentAttr: function(/*String|DomNode|Nodelist*/data){
+			// summary:
+			//		Hook to make set("content", ...) work.
+			//		Replaces old content with data content, include style classes from old content
+			// data:
+			//		the new Content may be String, DomNode or NodeList
+			//
+			//		if data is a NodeList (or an array of nodes) nodes are copied
+			//		so you can import nodes from another document implicitly
+
+			// clear href so we can't run refresh and clear content
+			// refresh should only work if we downloaded the content
+			this._set("href", "");
+
+			// Cancel any in-flight requests (a set('content', ...) will cancel any in-flight set('href', ...))
+			this.cancel();
 
-	setContent: function(/*String|DomNode|Nodelist*/data){
-		// summary:
-		//		Deprecated.   Use set('content', ...) instead.
-		kernel.deprecated("dijit.layout.ContentPane.setContent() is deprecated.  Use set('content', ...) instead.", "", "2.0");
-		this.set("content", data);
-	},
-	_setContentAttr: function(/*String|DomNode|Nodelist*/data){
-		// summary:
-		//		Hook to make set("content", ...) work.
-		//		Replaces old content with data content, include style classes from old content
-		//	data:
-		//		the new Content may be String, DomNode or NodeList
-		//
-		//		if data is a NodeList (or an array of nodes) nodes are copied
-		//		so you can import nodes from another document implicitly
-
-		// clear href so we can't run refresh and clear content
-		// refresh should only work if we downloaded the content
-		this._set("href", "");
-
-		// Cancel any in-flight requests (a set('content', ...) will cancel any in-flight set('href', ...))
-		this.cancel();
-
-		// Even though user is just setting content directly, still need to define an onLoadDeferred
-		// because the _onLoadHandler() handler is still getting called from setContent()
-		this.onLoadDeferred = new Deferred(lang.hitch(this, "cancel"));
-		if(this._created){
-			// For back-compat reasons, call onLoad() for set('content', ...)
-			// calls but not for content specified in srcNodeRef (ie: <div data-dojo-type=ContentPane>...</div>)
-			// or as initialization parameter (ie: new ContentPane({content: ...})
-			this.onLoadDeferred.addCallback(lang.hitch(this, "onLoad"));
-		}
+			// Even though user is just setting content directly, still need to define an onLoadDeferred
+			// because the _onLoadHandler() handler is still getting called from setContent()
+			this.onLoadDeferred = new Deferred(lang.hitch(this, "cancel"));
+			if(this._created){
+				// For back-compat reasons, call onLoad() for set('content', ...)
+				// calls but not for content specified in srcNodeRef (ie: <div data-dojo-type=ContentPane>...</div>)
+				// or as initialization parameter (ie: new ContentPane({content: ...})
+				this.onLoadDeferred.then(lang.hitch(this, "onLoad"));
+			}
 
-		this._setContent(data || "");
+			this._setContent(data || "");
 
-		this._isDownloaded = false; // mark that content is from a set('content') not a set('href')
+			this._isDownloaded = false; // mark that content is from a set('content') not a set('href')
 
-		return this.onLoadDeferred; 	// Deferred
-	},
-	_getContentAttr: function(){
-		// summary:
-		//		Hook to make get("content") work
-		return this.containerNode.innerHTML;
-	},
+			return this.onLoadDeferred;	// Deferred
+		},
+		_getContentAttr: function(){
+			// summary:
+			//		Hook to make get("content") work
+			return this.containerNode.innerHTML;
+		},
 
-	cancel: function(){
-		// summary:
-		//		Cancels an in-flight download of content
-		if(this._xhrDfd && (this._xhrDfd.fired == -1)){
-			this._xhrDfd.cancel();
-		}
-		delete this._xhrDfd; // garbage collect
+		cancel: function(){
+			// summary:
+			//		Cancels an in-flight download of content
+			if(this._xhrDfd && (this._xhrDfd.fired == -1)){
+				this._xhrDfd.cancel();
+			}
+			delete this._xhrDfd; // garbage collect
 
-		this.onLoadDeferred = null;
-	},
+			this.onLoadDeferred = null;
+		},
 
-	uninitialize: function(){
-		if(this._beingDestroyed){
+		destroy: function(){
 			this.cancel();
-		}
-		this.inherited(arguments);
-	},
-
-	destroyRecursive: function(/*Boolean*/ preserveDom){
-		// summary:
-		//		Destroy the ContentPane and its contents
+			this.inherited(arguments);
+		},
 
-		// if we have multiple controllers destroying us, bail after the first
-		if(this._beingDestroyed){
-			return;
-		}
-		this.inherited(arguments);
-	},
+		destroyRecursive: function(/*Boolean*/ preserveDom){
+			// summary:
+			//		Destroy the ContentPane and its contents
 
-	_onShow: function(){
-		// summary:
-		//		Called when the ContentPane is made visible
-		// description:
-		//		For a plain ContentPane, this is called on initialization, from startup().
-		//		If the ContentPane is a hidden pane of a TabContainer etc., then it's
-		//		called whenever the pane is made visible.
-		//
-		//		Does necessary processing, including href download and layout/resize of
-		//		child widget(s)
-
-		this.inherited(arguments);
-
-		if(this.href){
-			if(!this._xhrDfd && // if there's an href that isn't already being loaded
-				(!this.isLoaded || this._hrefChanged || this.refreshOnShow)
-			){
-				return this.refresh();	// If child has an href, promise that fires when the load is complete
+			// if we have multiple controllers destroying us, bail after the first
+			if(this._beingDestroyed){
+				return;
 			}
-		}
-	},
-
-	refresh: function(){
-		// summary:
-		//		[Re]download contents of href and display
-		// description:
-		//		1. cancels any currently in-flight requests
-		//		2. posts "loading..." message
-		//		3. sends XHR to download new data
+			this.inherited(arguments);
+		},
+
+		_onShow: function(){
+			// summary:
+			//		Called when the ContentPane is made visible
+			// description:
+			//		For a plain ContentPane, this is called on initialization, from startup().
+			//		If the ContentPane is a hidden pane of a TabContainer etc., then it's
+			//		called whenever the pane is made visible.
+			//
+			//		Does necessary processing, including href download and layout/resize of
+			//		child widget(s)
+
+			this.inherited(arguments);
+
+			if(this.href){
+				if(!this._xhrDfd && // if there's an href that isn't already being loaded
+					(!this.isLoaded || this._hrefChanged || this.refreshOnShow)
+					){
+					return this.refresh();	// If child has an href, promise that fires when the load is complete
+				}
+			}
+		},
 
-		// Cancel possible prior in-flight request
-		this.cancel();
+		refresh: function(){
+			// summary:
+			//		[Re]download contents of href and display
+			// description:
+			//		1. cancels any currently in-flight requests
+			//		2. posts "loading..." message
+			//		3. sends XHR to download new data
 
-		this.onLoadDeferred = new Deferred(lang.hitch(this, "cancel"));
-		this.onLoadDeferred.addCallback(lang.hitch(this, "onLoad"));
-		this._load();
-		return this.onLoadDeferred;		// If child has an href, promise that fires when refresh is complete
-	},
+			// Cancel possible prior in-flight request
+			this.cancel();
 
-	_load: function(){
-		// summary:
-		//		Load/reload the href specified in this.href
-
-		// display loading message
-		this._setContent(this.onDownloadStart(), true);
-
-		var self = this;
-		var getArgs = {
-			preventCache: (this.preventCache || this.refreshOnShow),
-			url: this.href,
-			handleAs: "text"
-		};
-		if(lang.isObject(this.ioArgs)){
-			lang.mixin(getArgs, this.ioArgs);
-		}
+			this.onLoadDeferred = new Deferred(lang.hitch(this, "cancel"));
+			this.onLoadDeferred.then(lang.hitch(this, "onLoad"));
+			this._load();
+			return this.onLoadDeferred;		// If child has an href, promise that fires when refresh is complete
+		},
+
+		_load: function(){
+			// summary:
+			//		Load/reload the href specified in this.href
+
+			// display loading message
+			this._setContent(this.onDownloadStart(), true);
+
+			var self = this;
+			var getArgs = {
+				preventCache: (this.preventCache || this.refreshOnShow),
+				url: this.href,
+				handleAs: "text"
+			};
+			if(lang.isObject(this.ioArgs)){
+				lang.mixin(getArgs, this.ioArgs);
+			}
 
-		var hand = (this._xhrDfd = (this.ioMethod || xhr.get)(getArgs));
+			var hand = (this._xhrDfd = (this.ioMethod || xhr.get)(getArgs)),
+				returnedHtml;
 
-		hand.addCallback(function(html){
+			hand.then(
+				function(html){
+					returnedHtml = html;
+					try{
+						self._isDownloaded = true;
+						return self._setContent(html, false);
+					}catch(err){
+						self._onError('Content', err); // onContentError
+					}
+				},
+				function(err){
+					if(!hand.canceled){
+						// show error message in the pane
+						self._onError('Download', err); // onDownloadError
+					}
+					delete self._xhrDfd;
+					return err;
+				}
+			).then(function(){
+					self.onDownloadEnd();
+					delete self._xhrDfd;
+					return returnedHtml;
+				});
+
+			// Remove flag saying that a load is needed
+			delete this._hrefChanged;
+		},
+
+		_onLoadHandler: function(data){
+			// summary:
+			//		This is called whenever new content is being loaded
+			this._set("isLoaded", true);
 			try{
-				self._isDownloaded = true;
-				self._setContent(html, false);
-				self.onDownloadEnd();
-			}catch(err){
-				self._onError('Content', err); // onContentError
+				this.onLoadDeferred.resolve(data);
+			}catch(e){
+				console.error('Error ' + this.widgetId + ' running custom onLoad code: ' + e.message);
 			}
-			delete self._xhrDfd;
-			return html;
-		});
-
-		hand.addErrback(function(err){
-			if(!hand.canceled){
-				// show error message in the pane
-				self._onError('Download', err); // onDownloadError
-			}
-			delete self._xhrDfd;
-			return err;
-		});
-
-		// Remove flag saying that a load is needed
-		delete this._hrefChanged;
-	},
+		},
 
-	_onLoadHandler: function(data){
-		// summary:
-		//		This is called whenever new content is being loaded
-		this._set("isLoaded", true);
-		try{
-			this.onLoadDeferred.callback(data);
-		}catch(e){
-			console.error('Error '+this.widgetId+' running custom onLoad code: ' + e.message);
-		}
-	},
-
-	_onUnloadHandler: function(){
-		// summary:
-		//		This is called whenever the content is being unloaded
-		this._set("isLoaded", false);
-		try{
-			this.onUnload();
-		}catch(e){
-			console.error('Error '+this.widgetId+' running custom onUnload code: ' + e.message);
-		}
-	},
+		_onUnloadHandler: function(){
+			// summary:
+			//		This is called whenever the content is being unloaded
+			this._set("isLoaded", false);
+			try{
+				this.onUnload();
+			}catch(e){
+				console.error('Error ' + this.widgetId + ' running custom onUnload code: ' + e.message);
+			}
+		},
 
-	destroyDescendants: function(/*Boolean*/ preserveDom){
-		// summary:
-		//		Destroy all the widgets inside the ContentPane and empty containerNode
+		destroyDescendants: function(/*Boolean*/ preserveDom){
+			// summary:
+			//		Destroy all the widgets inside the ContentPane and empty containerNode
 
-		// Make sure we call onUnload (but only when the ContentPane has real content)
-		if(this.isLoaded){
-			this._onUnloadHandler();
-		}
+			// Make sure we call onUnload (but only when the ContentPane has real content)
+			if(this.isLoaded){
+				this._onUnloadHandler();
+			}
 
-		// Even if this.isLoaded == false there might still be a "Loading..." message
-		// to erase, so continue...
+			// Even if this.isLoaded == false there might still be a "Loading..." message
+			// to erase, so continue...
 
-		// For historical reasons we need to delete all widgets under this.containerNode,
-		// even ones that the user has created manually.
-		var setter = this._contentSetter;
-		array.forEach(this.getChildren(), function(widget){
-			if(widget.destroyRecursive){
-				widget.destroyRecursive(preserveDom);
-			}
-		});
-		if(setter){
-			// Most of the widgets in setter.parseResults have already been destroyed, but
-			// things like Menu that have been moved to <body> haven't yet
-			array.forEach(setter.parseResults, function(widget){
-				if(widget.destroyRecursive && widget.domNode && widget.domNode.parentNode == win.body()){
+			// For historical reasons we need to delete all widgets under this.containerNode,
+			// even ones that the user has created manually.
+			var setter = this._contentSetter;
+			array.forEach(this.getChildren(), function(widget){
+				if(widget.destroyRecursive){
+					// All widgets will hit this branch
 					widget.destroyRecursive(preserveDom);
+				}else if(widget.destroy){
+					// Things like dojo/dnd/Source have destroy(), not destroyRecursive()
+					widget.destroy(preserveDom);
 				}
+				widget._destroyed = true;
 			});
-			delete setter.parseResults;
-		}
+			if(setter){
+				// Most of the widgets in setter.parseResults have already been destroyed, but
+				// things like Menu that have been moved to <body> haven't yet
+				array.forEach(setter.parseResults, function(widget){
+					if(!widget._destroyed){
+						if(widget.destroyRecursive){
+							// All widgets will hit this branch
+							widget.destroyRecursive(preserveDom);
+						}else if(widget.destroy){
+							// Things like dojo/dnd/Source have destroy(), not destroyRecursive()
+							widget.destroy(preserveDom);
+						}
+						widget._destroyed = true;
+					}
+				});
+				delete setter.parseResults;
+			}
 
-		// And then clear away all the DOM nodes
-		if(!preserveDom){
-			html._emptyNode(this.containerNode);
-		}
+			// And then clear away all the DOM nodes
+			if(!preserveDom){
+				domConstruct.empty(this.containerNode);
+			}
 
-		// Delete any state information we have about current contents
-		delete this._singleChild;
-	},
+			// Delete any state information we have about current contents
+			delete this._singleChild;
+		},
+
+		_setContent: function(/*String|DocumentFragment*/ cont, /*Boolean*/ isFakeContent){
+			// summary:
+			//		Insert the content into the container node
+			// returns:
+			//		Returns a Deferred promise that is resolved when the content is parsed.
+
+			// first get rid of child widgets
+			this.destroyDescendants();
+
+			// html.set will take care of the rest of the details
+			// we provide an override for the error handling to ensure the widget gets the errors
+			// configure the setter instance with only the relevant widget instance properties
+			// NOTE: unless we hook into attr, or provide property setters for each property,
+			// we need to re-configure the ContentSetter with each use
+			var setter = this._contentSetter;
+			if(!(setter && setter instanceof html._ContentSetter)){
+				setter = this._contentSetter = new html._ContentSetter({
+					node: this.containerNode,
+					_onError: lang.hitch(this, this._onError),
+					onContentError: lang.hitch(this, function(e){
+						// fires if a domfault occurs when we are appending this.errorMessage
+						// like for instance if domNode is a UL and we try append a DIV
+						var errMess = this.onContentError(e);
+						try{
+							this.containerNode.innerHTML = errMess;
+						}catch(e){
+							console.error('Fatal ' + this.id + ' could not change content due to ' + e.message, e);
+						}
+					})/*,
+					 _onError */
+				});
+			}
 
-	_setContent: function(/*String|DocumentFragment*/ cont, /*Boolean*/ isFakeContent){
-		// summary:
-		//		Insert the content into the container node
-
-		// first get rid of child widgets
-		this.destroyDescendants();
-
-		// html.set will take care of the rest of the details
-		// we provide an override for the error handling to ensure the widget gets the errors
-		// configure the setter instance with only the relevant widget instance properties
-		// NOTE: unless we hook into attr, or provide property setters for each property,
-		// we need to re-configure the ContentSetter with each use
-		var setter = this._contentSetter;
-		if(! (setter && setter instanceof html._ContentSetter)){
-			setter = this._contentSetter = new html._ContentSetter({
-				node: this.containerNode,
-				_onError: lang.hitch(this, this._onError),
-				onContentError: lang.hitch(this, function(e){
-					// fires if a domfault occurs when we are appending this.errorMessage
-					// like for instance if domNode is a UL and we try append a DIV
-					var errMess = this.onContentError(e);
-					try{
-						this.containerNode.innerHTML = errMess;
-					}catch(e){
-						console.error('Fatal '+this.id+' could not change content due to '+e.message, e);
+			var setterParams = lang.mixin({
+				cleanContent: this.cleanContent,
+				extractContent: this.extractContent,
+				parseContent: !cont.domNode && this.parseOnLoad,
+				parserScope: this.parserScope,
+				startup: false,
+				dir: this.dir,
+				lang: this.lang,
+				textDir: this.textDir
+			}, this._contentSetterParams || {});
+
+			var p = setter.set((lang.isObject(cont) && cont.domNode) ? cont.domNode : cont, setterParams);
+
+			// dojox/layout/html/_base::_ContentSetter.set() returns a Promise that indicates when everything is completed.
+			// dojo/html::_ContentSetter.set() currently returns the DOMNode, but that will be changed for 2.0.
+			// So, if set() returns a promise then use it, otherwise fallback to waiting on setter.parseDeferred
+			var self = this;
+			return when(p && p.then ? p : setter.parseDeferred, function(){
+				// setter params must be pulled afresh from the ContentPane each time
+				delete self._contentSetterParams;
+
+				if(!isFakeContent){
+					if(self._started){
+						// Startup each top level child widget (and they will start their children, recursively)
+						self._startChildren();
+
+						// Call resize() on each of my child layout widgets,
+						// or resize() on my single child layout widget...
+						// either now (if I'm currently visible) or when I become visible
+						self._scheduleLayout();
 					}
-				})/*,
-				_onError */
+					self._onLoadHandler(cont);
+				}
 			});
-		}
-
-		var setterParams = lang.mixin({
-			cleanContent: this.cleanContent,
-			extractContent: this.extractContent,
-			parseContent: !cont.domNode && this.parseOnLoad,
-			parserScope: this.parserScope,
-			startup: false,
-			dir: this.dir,
-			lang: this.lang,
-			textDir: this.textDir
-		}, this._contentSetterParams || {});
-
-		setter.set( (lang.isObject(cont) && cont.domNode) ? cont.domNode : cont, setterParams );
-
-		// setter params must be pulled afresh from the ContentPane each time
-		delete this._contentSetterParams;
-
-		if(this.doLayout){
-			this._checkIfSingleChild();
-		}
-
-		if(!isFakeContent){
-			if(this._started){
-				// Startup each top level child widget (and they will start their children, recursively)
-				delete this._started;
-				this.startup();
-
-				// Call resize() on each of my child layout widgets,
-				// or resize() on my single child layout widget...
-				// either now (if I'm currently visible) or when I become visible
-				this._scheduleLayout();
+		},
+
+		_onError: function(type, err, consoleText){
+			this.onLoadDeferred.reject(err);
+
+			// shows user the string that is returned by on[type]Error
+			// override on[type]Error and return your own string to customize
+			var errText = this['on' + type + 'Error'].call(this, err);
+			if(consoleText){
+				console.error(consoleText, err);
+			}else if(errText){// a empty string won't change current content
+				this._setContent(errText, true);
 			}
-
-			this._onLoadHandler(cont);
-		}
-	},
-
-	_onError: function(type, err, consoleText){
-		this.onLoadDeferred.errback(err);
-
-		// shows user the string that is returned by on[type]Error
-		// override on[type]Error and return your own string to customize
-		var errText = this['on' + type + 'Error'].call(this, err);
-		if(consoleText){
-			console.error(consoleText, err);
-		}else if(errText){// a empty string won't change current content
-			this._setContent(errText, true);
+		},
+
+		// EVENT's, should be overide-able
+		onLoad: function(/*===== data =====*/){
+			// summary:
+			//		Event hook, is called after everything is loaded and widgetified
+			// tags:
+			//		callback
+		},
+
+		onUnload: function(){
+			// summary:
+			//		Event hook, is called before old content is cleared
+			// tags:
+			//		callback
+		},
+
+		onDownloadStart: function(){
+			// summary:
+			//		Called before download starts.
+			// description:
+			//		The string returned by this function will be the html
+			//		that tells the user we are loading something.
+			//		Override with your own function if you want to change text.
+			// tags:
+			//		extension
+			return this.loadingMessage;
+		},
+
+		onContentError: function(/*Error*/ /*===== error =====*/){
+			// summary:
+			//		Called on DOM faults, require faults etc. in content.
+			//
+			//		In order to display an error message in the pane, return
+			//		the error message from this method, as an HTML string.
+			//
+			//		By default (if this method is not overriden), it returns
+			//		nothing, so the error message is just printed to the console.
+			// tags:
+			//		extension
+		},
+
+		onDownloadError: function(/*Error*/ /*===== error =====*/){
+			// summary:
+			//		Called when download error occurs.
+			//
+			//		In order to display an error message in the pane, return
+			//		the error message from this method, as an HTML string.
+			//
+			//		Default behavior (if this method is not overriden) is to display
+			//		the error message inside the pane.
+			// tags:
+			//		extension
+			return this.errorMessage;
+		},
+
+		onDownloadEnd: function(){
+			// summary:
+			//		Called when download is finished.
+			// tags:
+			//		callback
 		}
-	},
-
-	// EVENT's, should be overide-able
-	onLoad: function(/*===== data =====*/){
-		// summary:
-		//		Event hook, is called after everything is loaded and widgetified
-		// tags:
-		//		callback
-	},
-
-	onUnload: function(){
-		// summary:
-		//		Event hook, is called before old content is cleared
-		// tags:
-		//		callback
-	},
-
-	onDownloadStart: function(){
-		// summary:
-		//		Called before download starts.
-		// description:
-		//		The string returned by this function will be the html
-		//		that tells the user we are loading something.
-		//		Override with your own function if you want to change text.
-		// tags:
-		//		extension
-		return this.loadingMessage;
-	},
-
-	onContentError: function(/*Error*/ /*===== error =====*/){
-		// summary:
-		//		Called on DOM faults, require faults etc. in content.
-		//
-		//		In order to display an error message in the pane, return
-		//		the error message from this method, as an HTML string.
-		//
-		//		By default (if this method is not overriden), it returns
-		//		nothing, so the error message is just printed to the console.
-		// tags:
-		//		extension
-	},
-
-	onDownloadError: function(/*Error*/ /*===== error =====*/){
-		// summary:
-		//		Called when download error occurs.
-		//
-		//		In order to display an error message in the pane, return
-		//		the error message from this method, as an HTML string.
-		//
-		//		Default behavior (if this method is not overriden) is to display
-		//		the error message inside the pane.
-		// tags:
-		//		extension
-		return this.errorMessage;
-	},
-
-	onDownloadEnd: function(){
-		// summary:
-		//		Called when download is finished.
-		// tags:
-		//		callback
-	}
-});
-
+	});
 });
diff --git a/dijit/layout/LayoutContainer.js b/dijit/layout/LayoutContainer.js
index 96e8df5..8ac6829 100644
--- a/dijit/layout/LayoutContainer.js
+++ b/dijit/layout/LayoutContainer.js
@@ -1,91 +1,153 @@
 define([
-	"dojo/_base/kernel", // kernel.deprecated
-	"dojo/_base/lang",
+	"dojo/_base/array",
 	"dojo/_base/declare", // declare
+	"dojo/dom-class",
+	"dojo/dom-style",
+	"dojo/_base/lang",
 	"../_WidgetBase",
 	"./_LayoutWidget",
-	"./utils"		// layoutUtils.layoutChildren
-], function(kernel, lang, declare, _WidgetBase, _LayoutWidget, layoutUtils){
-
-/*=====
-	var _WidgetBase = dijit._WidgetBase;
-	var _LayoutWidget = dijit.layout._LayoutWidget;
-=====*/
-
-// module:
-//		dijit/layout/LayoutContainer
-// summary:
-//		Deprecated.  Use `dijit.layout.BorderContainer` instead.
-
-
-// This argument can be specified for the children of a LayoutContainer.
-// Since any widget can be specified as a LayoutContainer child, mix it
-// into the base widget class.  (This is a hack, but it's effective.)
-lang.extend(_WidgetBase, {
-	// layoutAlign: String
-	//		"none", "left", "right", "bottom", "top", and "client".
-	//		See the LayoutContainer description for details on this parameter.
-	layoutAlign: 'none'
-});
+	"./utils" // layoutUtils.layoutChildren
+], function(array, declare, domClass, domStyle, lang, _WidgetBase, _LayoutWidget, layoutUtils){
 
-return declare("dijit.layout.LayoutContainer", _LayoutWidget, {
-	// summary:
-	//		Deprecated.  Use `dijit.layout.BorderContainer` instead.
-	//
-	// description:
-	//		Provides Delphi-style panel layout semantics.
-	//
-	//		A LayoutContainer is a box with a specified size (like style="width: 500px; height: 500px;"),
-	//		that contains children widgets marked with "layoutAlign" of "left", "right", "bottom", "top", and "client".
-	//		It takes it's children marked as left/top/bottom/right, and lays them out along the edges of the box,
-	//		and then it takes the child marked "client" and puts it into the remaining space in the middle.
-	//
-	//		Left/right positioning is similar to CSS's "float: left" and "float: right",
-	//		and top/bottom positioning would be similar to "float: top" and "float: bottom", if there were such
-	//		CSS.
-	//
-	//		Note that there can only be one client element, but there can be multiple left, right, top,
-	//		or bottom elements.
-	//
-	// example:
-	// |	<style>
-	// |		html, body{ height: 100%; width: 100%; }
-	// |	</style>
-	// |	<div data-dojo-type="dijit.layout.LayoutContainer" style="width: 100%; height: 100%">
-	// |		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="layoutAlign: 'top'">header text</div>
-	// |		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="layoutAlign: 'left'" style="width: 200px;">table of contents</div>
-	// |		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="layoutAlign: 'client'">client area</div>
-	// |	</div>
-	//
-	//		Lays out each child in the natural order the children occur in.
-	//		Basically each child is laid out into the "remaining space", where "remaining space" is initially
-	//		the content area of this widget, but is reduced to a smaller rectangle each time a child is added.
-	// tags:
-	//		deprecated
-
-	baseClass: "dijitLayoutContainer",
-
-	constructor: function(){
-		kernel.deprecated("dijit.layout.LayoutContainer is deprecated", "use BorderContainer instead", 2.0);
-	},
-
-	layout: function(){
-		layoutUtils.layoutChildren(this.domNode, this._contentBox, this.getChildren());
-	},
-
-	addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
-		this.inherited(arguments);
-		if(this._started){
-			layoutUtils.layoutChildren(this.domNode, this._contentBox, this.getChildren());
-		}
-	},
+	// module:
+	//		dijit/layout/LayoutContainer
+
+	var LayoutContainer = declare("dijit.layout.LayoutContainer", _LayoutWidget, {
+		// summary:
+		//		A LayoutContainer is a box with a specified size, such as style="width: 500px; height: 500px;",
+		//		that contains a child widget marked region="center" and optionally children widgets marked
+		//		region equal to "top", "bottom", "leading", "trailing", "left" or "right".
+		//		Children along the edges will be laid out according to width or height dimensions. The remaining
+		//		space is designated for the center region.
+		//
+		//		The outer size must be specified on the LayoutContainer node.  Width must be specified for the sides
+		//		and height for the top and bottom, respectively.  No dimensions should be specified on the center;
+		//		it will fill the remaining space.  Regions named "leading" and "trailing" may be used just like
+		//		"left" and "right" except that they will be reversed in right-to-left environments.
+		//
+		//		For complex layouts, multiple children can be specified for a single region.   In this case, the
+		//		layoutPriority flag on the children determines which child is closer to the edge (low layoutPriority)
+		//		and which child is closer to the center (high layoutPriority).   layoutPriority can also be used
+		//		instead of the design attribute to control layout precedence of horizontal vs. vertical panes.
+		//
+		//		See `LayoutContainer.ChildWidgetProperties` for details on the properties that can be set on
+		//		children of a `LayoutContainer`.
+		//
+		//		If layoutPriority is not set, lays out each child in the natural order the children occur in.
+		//		Basically each child is laid out into the "remaining space", where "remaining space" is initially
+		//		the content area of this widget, but is reduced to a smaller rectangle each time a child is added.
+
+		// design: String
+		//		Which design is used for the layout:
+		//
+		//		- "headline" (default) where the top and bottom extend the full width of the container
+		//		- "sidebar" where the left and right sides extend from top to bottom.
+		design: "headline",
+
+		baseClass: "dijitLayoutContainer",
+
+		startup: function(){
+			if(this._started){
+				return;
+			}
+			array.forEach(this.getChildren(), this._setupChild, this);
+			this.inherited(arguments);
+		},
+
+		_setupChild: function(/*dijit/_WidgetBase*/ child){
+			// Override _LayoutWidget._setupChild().
+
+			this.inherited(arguments);
+
+			var region = child.region;
+			if(region){
+				domClass.add(child.domNode, this.baseClass + "Pane");
+			}
+		},
+
+		_getOrderedChildren: function(){
+			// summary:
+			//		Return list of my children in the order that I want layoutChildren()
+			//		to process them (i.e. from the outside to the inside)
 
-	removeChild: function(/*dijit._Widget*/ widget){
-		this.inherited(arguments);
-		if(this._started){
-			layoutUtils.layoutChildren(this.domNode, this._contentBox, this.getChildren());
+			var wrappers = array.map(this.getChildren(), function(child, idx){
+				return {
+					pane: child,
+					weight: [
+						child.region == "center" ? Infinity : 0,
+						child.layoutPriority,
+						(this.design == "sidebar" ? 1 : -1) * (/top|bottom/.test(child.region) ? 1 : -1),
+						idx
+					]
+				};
+			}, this);
+			wrappers.sort(function(a, b){
+				var aw = a.weight, bw = b.weight;
+				for(var i = 0; i < aw.length; i++){
+					if(aw[i] != bw[i]){
+						return aw[i] - bw[i];
+					}
+				}
+				return 0;
+			});
+
+			return array.map(wrappers, function(w){ return w.pane; });
+		},
+
+		layout: function(){
+			layoutUtils.layoutChildren(this.domNode, this._contentBox, this._getOrderedChildren());
+		},
+
+		addChild: function(/*dijit/_WidgetBase*/ child, /*Integer?*/ insertIndex){
+			this.inherited(arguments);
+			if(this._started){
+				this.layout();
+			}
+		},
+
+		removeChild: function(/*dijit/_WidgetBase*/ child){
+			this.inherited(arguments);
+			if(this._started){
+				this.layout();
+			}
+
+			// Clean up whatever style changes we made to the child pane.
+			// Unclear how height and width should be handled.
+			domClass.remove(child.domNode, this.baseClass + "Pane");
+			domStyle.set(child.domNode, {
+				top: "auto",
+				bottom: "auto",
+				left: "auto",
+				right: "auto",
+				position: "static"
+			});
+			domStyle.set(child.domNode, /top|bottom/.test(child.region) ? "width" : "height", "auto");
 		}
-	}
-});
+	});
+
+	LayoutContainer.ChildWidgetProperties = {
+		// summary:
+		//		These properties can be specified for the children of a LayoutContainer.
+
+		// region: [const] String
+		//		Values: "top", "bottom", "leading", "trailing", "left", "right", "center".
+		//		See the `dijit/layout/LayoutContainer` description for details.
+		region: '',
+
+		// layoutAlign: [const deprecated] String
+		//		Synonym for region, except using "client" instead of "center".  Deprecated; use region instead.
+		layoutAlign: '',
+
+		// layoutPriority: [const] Number
+		//		Children with a higher layoutPriority will be placed closer to the LayoutContainer center,
+		//		between children with a lower layoutPriority.
+		layoutPriority: 0
+	};
+
+	// Since any widget can be specified as a LayoutContainer child, mix it
+	// into the base widget class.  (This is a hack, but it's effective.)
+	// This is for the benefit of the parser.   Remove for 2.0.  Also, hide from doc viewer.
+	lang.extend(_WidgetBase, /*===== {} || =====*/ LayoutContainer.ChildWidgetProperties);
 
+	return LayoutContainer;
 });
diff --git a/dijit/layout/LinkPane.js b/dijit/layout/LinkPane.js
index 5010de6..cf624c0 100644
--- a/dijit/layout/LinkPane.js
+++ b/dijit/layout/LinkPane.js
@@ -4,16 +4,8 @@ define([
 	"dojo/_base/declare" // declare
 ], function(ContentPane, _TemplatedMixin, declare){
 
-/*=====
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var ContentPane = dijit.layout.ContentPane;
-=====*/
-
 	// module:
 	//		dijit/layout/LinkPane
-	// summary:
-	//		A ContentPane with an href where (when declared in markup)
-	//		the title is specified as innerHTML rather than as a title attribute.
 
 
 	return declare("dijit.layout.LinkPane", [ContentPane, _TemplatedMixin], {
diff --git a/dijit/layout/ScrollingTabController.js b/dijit/layout/ScrollingTabController.js
index d8fda3c..2a2c692 100644
--- a/dijit/layout/ScrollingTabController.js
+++ b/dijit/layout/ScrollingTabController.js
@@ -6,506 +6,495 @@ define([
 	"dojo/dom-style", // domStyle.style
 	"dojo/_base/fx", // Animation
 	"dojo/_base/lang", // lang.hitch
+	"dojo/on",
 	"dojo/query", // query
-	"dojo/_base/sniff", // has("ie"), has("webkit"), has("quirks")
-	"../registry",	// registry.byId()
+	"dojo/sniff", // has("ie"), has("webkit"), has("quirks")
+	"../registry", // registry.byId()
 	"dojo/text!./templates/ScrollingTabController.html",
 	"dojo/text!./templates/_ScrollingTabControllerButton.html",
 	"./TabController",
-	"./utils",	// marginBox2contextBox, layoutChildren
+	"./utils", // marginBox2contextBox, layoutChildren
 	"../_WidgetsInTemplateMixin",
 	"../Menu",
 	"../MenuItem",
 	"../form/Button",
 	"../_HasDropDown",
-	"dojo/NodeList-dom" // NodeList.style
-], function(array, declare, domClass, domGeometry, domStyle, fx, lang, query, has,
+	"dojo/NodeList-dom", // NodeList.style
+	"../a11yclick"	// template uses ondijitclick (not for keyboard support, but for responsive touch support)
+], function(array, declare, domClass, domGeometry, domStyle, fx, lang, on, query, has,
 	registry, tabControllerTemplate, buttonTemplate, TabController, layoutUtils, _WidgetsInTemplateMixin,
 	Menu, MenuItem, Button, _HasDropDown){
 
-/*=====
-var _WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
-var Menu = dijit.Menu;
-var _HasDropDown = dijit._HasDropDown;
-var TabController = dijit.layout.TabController;
-=====*/
+	// module:
+	//		dijit/layout/ScrollingTabController
 
+	var ScrollingTabController = declare("dijit.layout.ScrollingTabController", [TabController, _WidgetsInTemplateMixin], {
+		// summary:
+		//		Set of tabs with left/right arrow keys and a menu to switch between tabs not
+		//		all fitting on a single row.
+		//		Works only for horizontal tabs (either above or below the content, not to the left
+		//		or right).
+		// tags:
+		//		private
+
+		baseClass: "dijitTabController dijitScrollingTabController",
+
+		templateString: tabControllerTemplate,
+
+		// useMenu: [const] Boolean
+		//		True if a menu should be used to select tabs when they are too
+		//		wide to fit the TabContainer, false otherwise.
+		useMenu: true,
+
+		// useSlider: [const] Boolean
+		//		True if a slider should be used to select tabs when they are too
+		//		wide to fit the TabContainer, false otherwise.
+		useSlider: true,
+
+		// tabStripClass: [const] String
+		//		The css class to apply to the tab strip, if it is visible.
+		tabStripClass: "",
+
+		// _minScroll: Number
+		//		The distance in pixels from the edge of the tab strip which,
+		//		if a scroll animation is less than, forces the scroll to
+		//		go all the way to the left/right.
+		_minScroll: 5,
+
+		// Override default behavior mapping class to DOMNode
+		_setClassAttr: { node: "containerNode", type: "class" },
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			var n = this.domNode;
+
+			this.scrollNode = this.tablistWrapper;
+			this._initButtons();
+
+			if(!this.tabStripClass){
+				this.tabStripClass = "dijitTabContainer" +
+					this.tabPosition.charAt(0).toUpperCase() +
+					this.tabPosition.substr(1).replace(/-.*/, "") +
+					"None";
+				domClass.add(n, "tabStrip-disabled")
+			}
 
-// module:
-//		dijit/layout/ScrollingTabController
-// summary:
-//		Set of tabs with left/right arrow keys and a menu to switch between tabs not
-//		all fitting on a single row.
+			domClass.add(this.tablistWrapper, this.tabStripClass);
+		},
 
+		onStartup: function(){
+			this.inherited(arguments);
 
-var ScrollingTabController = declare("dijit.layout.ScrollingTabController", [TabController, _WidgetsInTemplateMixin], {
-	// summary:
-	//		Set of tabs with left/right arrow keys and a menu to switch between tabs not
-	//		all fitting on a single row.
-	//		Works only for horizontal tabs (either above or below the content, not to the left
-	//		or right).
-	// tags:
-	//		private
+			// TabController is hidden until it finishes drawing, to give
+			// a less visually jumpy instantiation.   When it's finished, set visibility to ""
+			// to that the tabs are hidden/shown depending on the container's visibility setting.
+			domStyle.set(this.domNode, "visibility", "");
+			this._postStartup = true;
 
-	baseClass: "dijitTabController dijitScrollingTabController",
+			// changes to the tab button label or iconClass will have changed the width of the
+			// buttons, so do a resize
+			this.own(on(this.containerNode, "attrmodified-label, attrmodified-iconclass", lang.hitch(this, function(evt){
+				if(this._dim){
+					this.resize(this._dim);
+				}
+			})));
+		},
+
+		onAddChild: function(page, insertIndex){
+			this.inherited(arguments);
+
+			// Increment the width of the wrapper when a tab is added
+			// This makes sure that the buttons never wrap.
+			// The value 200 is chosen as it should be bigger than most
+			// Tab button widths.
+			domStyle.set(this.containerNode, "width",
+				(domStyle.get(this.containerNode, "width") + 200) + "px");
+		},
+
+		onRemoveChild: function(page, insertIndex){
+			// null out _selectedTab because we are about to delete that dom node
+			var button = this.pane2button(page.id);
+			if(this._selectedTab === button.domNode){
+				this._selectedTab = null;
+			}
 
-	templateString: tabControllerTemplate,
+			this.inherited(arguments);
+		},
+
+		_initButtons: function(){
+			// summary:
+			//		Creates the buttons used to scroll to view tabs that
+			//		may not be visible if the TabContainer is too narrow.
+
+			// Make a list of the buttons to display when the tab labels become
+			// wider than the TabContainer, and hide the other buttons.
+			// Also gets the total width of the displayed buttons.
+			this._btnWidth = 0;
+			this._buttons = query("> .tabStripButton", this.domNode).filter(function(btn){
+				if((this.useMenu && btn == this._menuBtn.domNode) ||
+					(this.useSlider && (btn == this._rightBtn.domNode || btn == this._leftBtn.domNode))){
+					this._btnWidth += domGeometry.getMarginSize(btn).w;
+					return true;
+				}else{
+					domStyle.set(btn, "display", "none");
+					return false;
+				}
+			}, this);
+		},
+
+		_getTabsWidth: function(){
+			var children = this.getChildren();
+			if(children.length){
+				var leftTab = children[this.isLeftToRight() ? 0 : children.length - 1].domNode,
+					rightTab = children[this.isLeftToRight() ? children.length - 1 : 0].domNode;
+				return rightTab.offsetLeft + rightTab.offsetWidth - leftTab.offsetLeft;
+			}else{
+				return 0;
+			}
+		},
+
+		_enableBtn: function(width){
+			// summary:
+			//		Determines if the tabs are wider than the width of the TabContainer, and
+			//		thus that we need to display left/right/menu navigation buttons.
+			var tabsWidth = this._getTabsWidth();
+			width = width || domStyle.get(this.scrollNode, "width");
+			return tabsWidth > 0 && width < tabsWidth;
+		},
+
+		resize: function(dim){
+			// summary:
+			//		Hides or displays the buttons used to scroll the tab list and launch the menu
+			//		that selects tabs.
+
+			// Save the dimensions to be used when a child is renamed.
+			this._dim = dim;
+
+			// Set my height to be my natural height (tall enough for one row of tab labels),
+			// and my content-box width based on margin-box width specified in dim parameter.
+			// But first reset scrollNode.height in case it was set by layoutChildren() call
+			// in a previous run of this method.
+			this.scrollNode.style.height = "auto";
+			var cb = this._contentBox = layoutUtils.marginBox2contentBox(this.domNode, {h: 0, w: dim.w});
+			cb.h = this.scrollNode.offsetHeight;
+			domGeometry.setContentSize(this.domNode, cb);
+
+			// Show/hide the left/right/menu navigation buttons depending on whether or not they
+			// are needed.
+			var enable = this._enableBtn(this._contentBox.w);
+			this._buttons.style("display", enable ? "" : "none");
+
+			// Position and size the navigation buttons and the tablist
+			this._leftBtn.region = "left";
+			this._rightBtn.region = "right";
+			this._menuBtn.region = this.isLeftToRight() ? "right" : "left";
+			layoutUtils.layoutChildren(this.domNode, this._contentBox,
+				[this._menuBtn, this._leftBtn, this._rightBtn, {domNode: this.scrollNode, region: "center"}]);
+
+			// set proper scroll so that selected tab is visible
+			if(this._selectedTab){
+				if(this._anim && this._anim.status() == "playing"){
+					this._anim.stop();
+				}
+				this.scrollNode.scrollLeft = this._convertToScrollLeft(this._getScrollForSelectedTab());
+			}
 
-	// useMenu: [const] Boolean
-	//		True if a menu should be used to select tabs when they are too
-	//		wide to fit the TabContainer, false otherwise.
-	useMenu: true,
+			// Enable/disabled left right buttons depending on whether or not user can scroll to left or right
+			this._setButtonClass(this._getScroll());
 
-	// useSlider: [const] Boolean
-	//		True if a slider should be used to select tabs when they are too
-	//		wide to fit the TabContainer, false otherwise.
-	useSlider: true,
+			this._postResize = true;
 
-	// tabStripClass: [const] String
-	//		The css class to apply to the tab strip, if it is visible.
-	tabStripClass: "",
+			// Return my size so layoutChildren() can use it.
+			// Also avoids IE9 layout glitch on browser resize when scroll buttons present
+			return {h: this._contentBox.h, w: dim.w};
+		},
 
-	widgetsInTemplate: true,
+		_getScroll: function(){
+			// summary:
+			//		Returns the current scroll of the tabs where 0 means
+			//		"scrolled all the way to the left" and some positive number, based on #
+			//		of pixels of possible scroll (ex: 1000) means "scrolled all the way to the right"
+			return (this.isLeftToRight() || has("ie") < 8 || (has("ie") && has("quirks")) || has("webkit")) ? this.scrollNode.scrollLeft :
+				domStyle.get(this.containerNode, "width") - domStyle.get(this.scrollNode, "width")
+					+ (has("ie") >= 8 ? -1 : 1) * this.scrollNode.scrollLeft;
+		},
+
+		_convertToScrollLeft: function(val){
+			// summary:
+			//		Given a scroll value where 0 means "scrolled all the way to the left"
+			//		and some positive number, based on # of pixels of possible scroll (ex: 1000)
+			//		means "scrolled all the way to the right", return value to set this.scrollNode.scrollLeft
+			//		to achieve that scroll.
+			//
+			//		This method is to adjust for RTL funniness in various browsers and versions.
+			if(this.isLeftToRight() || has("ie") < 8 || (has("ie") && has("quirks")) || has("webkit")){
+				return val;
+			}else{
+				var maxScroll = domStyle.get(this.containerNode, "width") - domStyle.get(this.scrollNode, "width");
+				return (has("ie") >= 8 ? -1 : 1) * (val - maxScroll);
+			}
+		},
 
-	// _minScroll: Number
-	//		The distance in pixels from the edge of the tab strip which,
-	//		if a scroll animation is less than, forces the scroll to
-	//		go all the way to the left/right.
-	_minScroll: 5,
+		onSelectChild: function(/*dijit/_WidgetBase*/ page){
+			// summary:
+			//		Smoothly scrolls to a tab when it is selected.
 
-	// Override default behavior mapping class to DOMNode
-	_setClassAttr: { node: "containerNode", type: "class" },
+			var tab = this.pane2button(page.id);
+			if(!tab){
+				return;
+			}
 
-	buildRendering: function(){
-		this.inherited(arguments);
-		var n = this.domNode;
+			var node = tab.domNode;
 
-		this.scrollNode = this.tablistWrapper;
-		this._initButtons();
+			// Save the selection
+			if(node != this._selectedTab){
+				this._selectedTab = node;
 
-		if(!this.tabStripClass){
-			this.tabStripClass = "dijitTabContainer" +
-				this.tabPosition.charAt(0).toUpperCase() +
-				this.tabPosition.substr(1).replace(/-.*/, "") +
-				"None";
-			domClass.add(n, "tabStrip-disabled")
-		}
+				// Scroll to the selected tab, except on startup, when scrolling is handled in resize()
+				if(this._postResize){
+					var sl = this._getScroll();
 
-		domClass.add(this.tablistWrapper, this.tabStripClass);
-	},
-
-	onStartup: function(){
-		this.inherited(arguments);
-
-		// TabController is hidden until it finishes drawing, to give
-		// a less visually jumpy instantiation.   When it's finished, set visibility to ""
-		// to that the tabs are hidden/shown depending on the container's visibility setting.
-		domStyle.set(this.domNode, "visibility", "");
-		this._postStartup = true;
-	},
-
-	onAddChild: function(page, insertIndex){
-		this.inherited(arguments);
-
-		// changes to the tab button label or iconClass will have changed the width of the
-		// buttons, so do a resize
-		array.forEach(["label", "iconClass"], function(attr){
-			this.pane2watches[page.id].push(
-				this.pane2button[page.id].watch(attr, lang.hitch(this, function(){
-					if(this._postStartup && this._dim){
-						this.resize(this._dim);
+					if(sl > node.offsetLeft ||
+						sl + domStyle.get(this.scrollNode, "width") <
+							node.offsetLeft + domStyle.get(node, "width")){
+						this.createSmoothScroll().play();
 					}
-				}))
-			);
-		}, this);
-
-		// Increment the width of the wrapper when a tab is added
-		// This makes sure that the buttons never wrap.
-		// The value 200 is chosen as it should be bigger than most
-		// Tab button widths.
-		domStyle.set(this.containerNode, "width",
-			(domStyle.get(this.containerNode, "width") + 200) + "px");
-	},
-
-	onRemoveChild: function(page, insertIndex){
-		// null out _selectedTab because we are about to delete that dom node
-		var button = this.pane2button[page.id];
-		if(this._selectedTab === button.domNode){
-			this._selectedTab = null;
-		}
-
-		this.inherited(arguments);
-	},
+				}
+			}
 
-	_initButtons: function(){
-		// summary:
-		//		Creates the buttons used to scroll to view tabs that
-		//		may not be visible if the TabContainer is too narrow.
-
-		// Make a list of the buttons to display when the tab labels become
-		// wider than the TabContainer, and hide the other buttons.
-		// Also gets the total width of the displayed buttons.
-		this._btnWidth = 0;
-		this._buttons = query("> .tabStripButton", this.domNode).filter(function(btn){
-			if((this.useMenu && btn == this._menuBtn.domNode) ||
-				(this.useSlider && (btn == this._rightBtn.domNode || btn == this._leftBtn.domNode))){
-				this._btnWidth += domGeometry.getMarginSize(btn).w;
-				return true;
+			this.inherited(arguments);
+		},
+
+		_getScrollBounds: function(){
+			// summary:
+			//		Returns the minimum and maximum scroll setting to show the leftmost and rightmost
+			//		tabs (respectively)
+			var children = this.getChildren(),
+				scrollNodeWidth = domStyle.get(this.scrollNode, "width"), // about 500px
+				containerWidth = domStyle.get(this.containerNode, "width"), // 50,000px
+				maxPossibleScroll = containerWidth - scrollNodeWidth, // scrolling until right edge of containerNode visible
+				tabsWidth = this._getTabsWidth();
+
+			if(children.length && tabsWidth > scrollNodeWidth){
+				// Scrolling should happen
+				return {
+					min: this.isLeftToRight() ? 0 : children[children.length - 1].domNode.offsetLeft,
+					max: this.isLeftToRight() ?
+						(children[children.length - 1].domNode.offsetLeft + children[children.length - 1].domNode.offsetWidth) - scrollNodeWidth :
+						maxPossibleScroll
+				};
 			}else{
-				domStyle.set(btn, "display", "none");
-				return false;
+				// No scrolling needed, all tabs visible, we stay either scrolled to far left or far right (depending on dir)
+				var onlyScrollPosition = this.isLeftToRight() ? 0 : maxPossibleScroll;
+				return {
+					min: onlyScrollPosition,
+					max: onlyScrollPosition
+				};
+			}
+		},
+
+		_getScrollForSelectedTab: function(){
+			// summary:
+			//		Returns the scroll value setting so that the selected tab
+			//		will appear in the center
+			var w = this.scrollNode,
+				n = this._selectedTab,
+				scrollNodeWidth = domStyle.get(this.scrollNode, "width"),
+				scrollBounds = this._getScrollBounds();
+
+			// TODO: scroll minimal amount (to either right or left) so that
+			// selected tab is fully visible, and just return if it's already visible?
+			var pos = (n.offsetLeft + domStyle.get(n, "width") / 2) - scrollNodeWidth / 2;
+			pos = Math.min(Math.max(pos, scrollBounds.min), scrollBounds.max);
+
+			// TODO:
+			// If scrolling close to the left side or right side, scroll
+			// all the way to the left or right.  See this._minScroll.
+			// (But need to make sure that doesn't scroll the tab out of view...)
+			return pos;
+		},
+
+		createSmoothScroll: function(x){
+			// summary:
+			//		Creates a dojo._Animation object that smoothly scrolls the tab list
+			//		either to a fixed horizontal pixel value, or to the selected tab.
+			// description:
+			//		If an number argument is passed to the function, that horizontal
+			//		pixel position is scrolled to.  Otherwise the currently selected
+			//		tab is scrolled to.
+			// x: Integer?
+			//		An optional pixel value to scroll to, indicating distance from left.
+
+			// Calculate position to scroll to
+			if(arguments.length > 0){
+				// position specified by caller, just make sure it's within bounds
+				var scrollBounds = this._getScrollBounds();
+				x = Math.min(Math.max(x, scrollBounds.min), scrollBounds.max);
+			}else{
+				// scroll to center the current tab
+				x = this._getScrollForSelectedTab();
 			}
-		}, this);
-	},
-
-	_getTabsWidth: function(){
-		var children = this.getChildren();
-		if(children.length){
-			var leftTab = children[this.isLeftToRight() ? 0 : children.length - 1].domNode,
-				rightTab = children[this.isLeftToRight() ? children.length - 1 : 0].domNode;
-			return rightTab.offsetLeft + domStyle.get(rightTab, "width") - leftTab.offsetLeft;
-		}else{
-			return 0;
-		}
-	},
 
-	_enableBtn: function(width){
-		// summary:
-		//		Determines if the tabs are wider than the width of the TabContainer, and
-		//		thus that we need to display left/right/menu navigation buttons.
-		var tabsWidth = this._getTabsWidth();
-		width = width || domStyle.get(this.scrollNode, "width");
-		return tabsWidth > 0 && width < tabsWidth;
-	},
-
-	resize: function(dim){
-		// summary:
-		//		Hides or displays the buttons used to scroll the tab list and launch the menu
-		//		that selects tabs.
-
-		// Save the dimensions to be used when a child is renamed.
-		this._dim = dim;
-
-		// Set my height to be my natural height (tall enough for one row of tab labels),
-		// and my content-box width based on margin-box width specified in dim parameter.
-		// But first reset scrollNode.height in case it was set by layoutChildren() call
-		// in a previous run of this method.
-		this.scrollNode.style.height = "auto";
-		var cb = this._contentBox = layoutUtils.marginBox2contentBox(this.domNode, {h: 0, w: dim.w});
-		cb.h = this.scrollNode.offsetHeight;
-		domGeometry.setContentSize(this.domNode, cb);
-
-		// Show/hide the left/right/menu navigation buttons depending on whether or not they
-		// are needed.
-		var enable = this._enableBtn(this._contentBox.w);
-		this._buttons.style("display", enable ? "" : "none");
-
-		// Position and size the navigation buttons and the tablist
-		this._leftBtn.layoutAlign = "left";
-		this._rightBtn.layoutAlign = "right";
-		this._menuBtn.layoutAlign = this.isLeftToRight() ? "right" : "left";
-		layoutUtils.layoutChildren(this.domNode, this._contentBox,
-			[this._menuBtn, this._leftBtn, this._rightBtn, {domNode: this.scrollNode, layoutAlign: "client"}]);
-
-		// set proper scroll so that selected tab is visible
-		if(this._selectedTab){
 			if(this._anim && this._anim.status() == "playing"){
 				this._anim.stop();
 			}
-			this.scrollNode.scrollLeft = this._convertToScrollLeft(this._getScrollForSelectedTab());
-		}
-
-		// Enable/disabled left right buttons depending on whether or not user can scroll to left or right
-		this._setButtonClass(this._getScroll());
-
-		this._postResize = true;
-
-		// Return my size so layoutChildren() can use it.
-		// Also avoids IE9 layout glitch on browser resize when scroll buttons present
-		return {h: this._contentBox.h, w: dim.w};
-	},
-
-	_getScroll: function(){
-		// summary:
-		//		Returns the current scroll of the tabs where 0 means
-		//		"scrolled all the way to the left" and some positive number, based on #
-		//		of pixels of possible scroll (ex: 1000) means "scrolled all the way to the right"
-		return (this.isLeftToRight() || has("ie") < 8 || (has("ie") && has("quirks")) || has("webkit")) ? this.scrollNode.scrollLeft :
-				domStyle.get(this.containerNode, "width") - domStyle.get(this.scrollNode, "width")
-					 + (has("ie") == 8 ? -1 : 1) * this.scrollNode.scrollLeft;
-	},
-
-	_convertToScrollLeft: function(val){
-		// summary:
-		//		Given a scroll value where 0 means "scrolled all the way to the left"
-		//		and some positive number, based on # of pixels of possible scroll (ex: 1000)
-		//		means "scrolled all the way to the right", return value to set this.scrollNode.scrollLeft
-		//		to achieve that scroll.
-		//
-		//		This method is to adjust for RTL funniness in various browsers and versions.
-		if(this.isLeftToRight() || has("ie") < 8 || (has("ie") && has("quirks")) || has("webkit")){
-			return val;
-		}else{
-			var maxScroll = domStyle.get(this.containerNode, "width") - domStyle.get(this.scrollNode, "width");
-			return (has("ie") == 8 ? -1 : 1) * (val - maxScroll);
-		}
-	},
-
-	onSelectChild: function(/*dijit._Widget*/ page){
-		// summary:
-		//		Smoothly scrolls to a tab when it is selected.
-
-		var tab = this.pane2button[page.id];
-		if(!tab || !page){return;}
-
-		var node = tab.domNode;
-
-		// Save the selection
-		if(node != this._selectedTab){
-			this._selectedTab = node;
 
-			// Scroll to the selected tab, except on startup, when scrolling is handled in resize()
-			if(this._postResize){
-				var sl = this._getScroll();
-
-				if(sl > node.offsetLeft ||
-						sl + domStyle.get(this.scrollNode, "width") <
-						node.offsetLeft + domStyle.get(node, "width")){
-					this.createSmoothScroll().play();
-				}
+			var self = this,
+				w = this.scrollNode,
+				anim = new fx.Animation({
+					beforeBegin: function(){
+						if(this.curve){
+							delete this.curve;
+						}
+						var oldS = w.scrollLeft,
+							newS = self._convertToScrollLeft(x);
+						anim.curve = new fx._Line(oldS, newS);
+					},
+					onAnimate: function(val){
+						w.scrollLeft = val;
+					}
+				});
+			this._anim = anim;
+
+			// Disable/enable left/right buttons according to new scroll position
+			this._setButtonClass(x);
+
+			return anim; // dojo/_base/fx/Animation
+		},
+
+		_getBtnNode: function(/*Event*/ e){
+			// summary:
+			//		Gets a button DOM node from a mouse click event.
+			// e:
+			//		The mouse click event.
+			var n = e.target;
+			while(n && !domClass.contains(n, "tabStripButton")){
+				n = n.parentNode;
+			}
+			return n;
+		},
+
+		doSlideRight: function(/*Event*/ e){
+			// summary:
+			//		Scrolls the menu to the right.
+			// e:
+			//		The mouse click event.
+			this.doSlide(1, this._getBtnNode(e));
+		},
+
+		doSlideLeft: function(/*Event*/ e){
+			// summary:
+			//		Scrolls the menu to the left.
+			// e:
+			//		The mouse click event.
+			this.doSlide(-1, this._getBtnNode(e));
+		},
+
+		doSlide: function(/*Number*/ direction, /*DomNode*/ node){
+			// summary:
+			//		Scrolls the tab list to the left or right by 75% of the widget width.
+			// direction:
+			//		If the direction is 1, the widget scrolls to the right, if it is -1,
+			//		it scrolls to the left.
+
+			if(node && domClass.contains(node, "dijitTabDisabled")){
+				return;
 			}
-		}
-
-		this.inherited(arguments);
-	},
-
-	_getScrollBounds: function(){
-		// summary:
-		//		Returns the minimum and maximum scroll setting to show the leftmost and rightmost
-		//		tabs (respectively)
-		var children = this.getChildren(),
-			scrollNodeWidth = domStyle.get(this.scrollNode, "width"),		// about 500px
-			containerWidth = domStyle.get(this.containerNode, "width"),	// 50,000px
-			maxPossibleScroll = containerWidth - scrollNodeWidth,	// scrolling until right edge of containerNode visible
-			tabsWidth = this._getTabsWidth();
-
-		if(children.length && tabsWidth > scrollNodeWidth){
-			// Scrolling should happen
-			return {
-				min: this.isLeftToRight() ? 0 : children[children.length-1].domNode.offsetLeft,
-				max: this.isLeftToRight() ?
-					(children[children.length-1].domNode.offsetLeft + domStyle.get(children[children.length-1].domNode, "width")) - scrollNodeWidth :
-					maxPossibleScroll
-			};
-		}else{
-			// No scrolling needed, all tabs visible, we stay either scrolled to far left or far right (depending on dir)
-			var onlyScrollPosition = this.isLeftToRight() ? 0 : maxPossibleScroll;
-			return {
-				min: onlyScrollPosition,
-				max: onlyScrollPosition
-			};
-		}
-	},
 
-	_getScrollForSelectedTab: function(){
-		// summary:
-		//		Returns the scroll value setting so that the selected tab
-		//		will appear in the center
-		var w = this.scrollNode,
-			n = this._selectedTab,
-			scrollNodeWidth = domStyle.get(this.scrollNode, "width"),
-			scrollBounds = this._getScrollBounds();
-
-		// TODO: scroll minimal amount (to either right or left) so that
-		// selected tab is fully visible, and just return if it's already visible?
-		var pos = (n.offsetLeft + domStyle.get(n, "width")/2) - scrollNodeWidth/2;
-		pos = Math.min(Math.max(pos, scrollBounds.min), scrollBounds.max);
-
-		// TODO:
-		// If scrolling close to the left side or right side, scroll
-		// all the way to the left or right.  See this._minScroll.
-		// (But need to make sure that doesn't scroll the tab out of view...)
-		return pos;
-	},
-
-	createSmoothScroll: function(x){
-		// summary:
-		//		Creates a dojo._Animation object that smoothly scrolls the tab list
-		//		either to a fixed horizontal pixel value, or to the selected tab.
-		// description:
-		//		If an number argument is passed to the function, that horizontal
-		//		pixel position is scrolled to.  Otherwise the currently selected
-		//		tab is scrolled to.
-		// x: Integer?
-		//		An optional pixel value to scroll to, indicating distance from left.
-
-		// Calculate position to scroll to
-		if(arguments.length > 0){
-			// position specified by caller, just make sure it's within bounds
-			var scrollBounds = this._getScrollBounds();
-			x = Math.min(Math.max(x, scrollBounds.min), scrollBounds.max);
-		}else{
-			// scroll to center the current tab
-			x = this._getScrollForSelectedTab();
-		}
+			var sWidth = domStyle.get(this.scrollNode, "width");
+			var d = (sWidth * 0.75) * direction;
 
-		if(this._anim && this._anim.status() == "playing"){
-			this._anim.stop();
-		}
+			var to = this._getScroll() + d;
 
-		var self = this,
-			w = this.scrollNode,
-			anim = new fx.Animation({
-				beforeBegin: function(){
-					if(this.curve){ delete this.curve; }
-					var oldS = w.scrollLeft,
-						newS = self._convertToScrollLeft(x);
-					anim.curve = new fx._Line(oldS, newS);
-				},
-				onAnimate: function(val){
-					w.scrollLeft = val;
-				}
-			});
-		this._anim = anim;
+			this._setButtonClass(to);
 
-		// Disable/enable left/right buttons according to new scroll position
-		this._setButtonClass(x);
+			this.createSmoothScroll(to).play();
+		},
 
-		return anim; // dojo._Animation
-	},
+		_setButtonClass: function(/*Number*/ scroll){
+			// summary:
+			//		Disables the left scroll button if the tabs are scrolled all the way to the left,
+			//		or the right scroll button in the opposite case.
+			// scroll: Integer
+			//		amount of horizontal scroll
 
-	_getBtnNode: function(/*Event*/ e){
-		// summary:
-		//		Gets a button DOM node from a mouse click event.
-		// e:
-		//		The mouse click event.
-		var n = e.target;
-		while(n && !domClass.contains(n, "tabStripButton")){
-			n = n.parentNode;
+			var scrollBounds = this._getScrollBounds();
+			this._leftBtn.set("disabled", scroll <= scrollBounds.min);
+			this._rightBtn.set("disabled", scroll >= scrollBounds.max);
 		}
-		return n;
-	},
+	});
 
-	doSlideRight: function(/*Event*/ e){
-		// summary:
-		//		Scrolls the menu to the right.
-		// e:
-		//		The mouse click event.
-		this.doSlide(1, this._getBtnNode(e));
-	},
 
-	doSlideLeft: function(/*Event*/ e){
-		// summary:
-		//		Scrolls the menu to the left.
-		// e:
-		//		The mouse click event.
-		this.doSlide(-1,this._getBtnNode(e));
-	},
-
-	doSlide: function(/*Number*/ direction, /*DomNode*/ node){
-		// summary:
-		//		Scrolls the tab list to the left or right by 75% of the widget width.
-		// direction:
-		//		If the direction is 1, the widget scrolls to the right, if it is
-		//		-1, it scrolls to the left.
-
-		if(node && domClass.contains(node, "dijitTabDisabled")){return;}
-
-		var sWidth = domStyle.get(this.scrollNode, "width");
-		var d = (sWidth * 0.75) * direction;
+	var ScrollingTabControllerButtonMixin = declare("dijit.layout._ScrollingTabControllerButtonMixin", null, {
+		baseClass: "dijitTab tabStripButton",
 
-		var to = this._getScroll() + d;
-
-		this._setButtonClass(to);
-
-		this.createSmoothScroll(to).play();
-	},
-
-	_setButtonClass: function(/*Number*/ scroll){
-		// summary:
-		//		Disables the left scroll button if the tabs are scrolled all the way to the left,
-		//		or the right scroll button in the opposite case.
-		// scroll: Integer
-		//		amount of horizontal scroll
-
-		var scrollBounds = this._getScrollBounds();
-		this._leftBtn.set("disabled", scroll <= scrollBounds.min);
-		this._rightBtn.set("disabled", scroll >= scrollBounds.max);
-	}
-});
+		templateString: buttonTemplate,
 
-
-var ScrollingTabControllerButtonMixin = declare("dijit.layout._ScrollingTabControllerButtonMixin", null, {
-	baseClass: "dijitTab tabStripButton",
-
-	templateString: buttonTemplate,
-
-		// Override inherited tabIndex: 0 from dijit.form.Button, because user shouldn't be
+		// Override inherited tabIndex: 0 from dijit/form/Button, because user shouldn't be
 		// able to tab to the left/right/menu buttons
-	tabIndex: "",
+		tabIndex: "",
 
-	// Similarly, override FormWidget.isFocusable() because clicking a button shouldn't focus it
-	// either (this override avoids focus() call in FormWidget.js)
-	isFocusable: function(){ return false; }
-});
-/*=====
-ScrollingTabControllerButtonMixin = dijit.layout._ScrollingTabControllerButtonMixin;
-=====*/
-
-// Class used in template
-declare("dijit.layout._ScrollingTabControllerButton",
-	[Button, ScrollingTabControllerButtonMixin]);
-
-// Class used in template
-declare(
-	"dijit.layout._ScrollingTabControllerMenuButton",
-	[Button, _HasDropDown, ScrollingTabControllerButtonMixin],
-{
-	// id of the TabContainer itself
-	containerId: "",
-
-	// -1 so user can't tab into the button, but so that button can still be focused programatically.
-	// Because need to move focus to the button (or somewhere) before the menu is hidden or IE6 will crash.
-	tabIndex: "-1",
-
-	isLoaded: function(){
-		// recreate menu every time, in case the TabContainer's list of children (or their icons/labels) have changed
-		return false;
-	},
-
-	loadDropDown: function(callback){
-		this.dropDown = new Menu({
-			id: this.containerId + "_menu",
-			dir: this.dir,
-			lang: this.lang,
-			textDir: this.textDir
-		});
-		var container = registry.byId(this.containerId);
-		array.forEach(container.getChildren(), function(page){
-			var menuItem = new MenuItem({
-				id: page.id + "_stcMi",
-				label: page.title,
-				iconClass: page.iconClass,
-				dir: page.dir,
-				lang: page.lang,
-				textDir: page.textDir,
-				onClick: function(){
-					container.selectChild(page);
-				}
+		// Similarly, override FormWidget.isFocusable() because clicking a button shouldn't focus it
+		// either (this override avoids focus() call in FormWidget.js)
+		isFocusable: function(){
+			return false;
+		}
+	});
+
+	// Class used in template
+	declare("dijit.layout._ScrollingTabControllerButton", [Button, ScrollingTabControllerButtonMixin]);
+
+	// Class used in template
+	declare("dijit.layout._ScrollingTabControllerMenuButton", [Button, _HasDropDown, ScrollingTabControllerButtonMixin], {
+		// id of the TabContainer itself
+		containerId: "",
+
+		// -1 so user can't tab into the button, but so that button can still be focused programatically.
+		// Because need to move focus to the button (or somewhere) before the menu is hidden or IE6 will crash.
+		tabIndex: "-1",
+
+		isLoaded: function(){
+			// recreate menu every time, in case the TabContainer's list of children (or their icons/labels) have changed
+			return false;
+		},
+
+		loadDropDown: function(callback){
+			this.dropDown = new Menu({
+				id: this.containerId + "_menu",
+				ownerDocument: this.ownerDocument,
+				dir: this.dir,
+				lang: this.lang,
+				textDir: this.textDir
 			});
-			this.dropDown.addChild(menuItem);
-		}, this);
-		callback();
-	},
-
-	closeDropDown: function(/*Boolean*/ focus){
-		this.inherited(arguments);
-		if(this.dropDown){
-			this.dropDown.destroyRecursive();
-			delete this.dropDown;
+			var container = registry.byId(this.containerId);
+			array.forEach(container.getChildren(), function(page){
+				var menuItem = new MenuItem({
+					id: page.id + "_stcMi",
+					label: page.title,
+					iconClass: page.iconClass,
+					disabled: page.disabled,
+					ownerDocument: this.ownerDocument,
+					dir: page.dir,
+					lang: page.lang,
+					textDir: page.textDir || container.textDir,
+					onClick: function(){
+						container.selectChild(page);
+					}
+				});
+				this.dropDown.addChild(menuItem);
+			}, this);
+			callback();
+		},
+
+		closeDropDown: function(/*Boolean*/ focus){
+			this.inherited(arguments);
+			if(this.dropDown){
+				this._popupStateNode.removeAttribute("aria-owns");	// remove ref to node that we are about to delete
+				this.dropDown.destroyRecursive();
+				delete this.dropDown;
+			}
 		}
-	}
-});
+	});
 
-return ScrollingTabController;
+	return ScrollingTabController;
 });
diff --git a/dijit/layout/SplitContainer.js b/dijit/layout/SplitContainer.js
index e16ece9..452fb81 100644
--- a/dijit/layout/SplitContainer.js
+++ b/dijit/layout/SplitContainer.js
@@ -11,23 +11,15 @@ define([
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/_base/lang", // lang.extend lang.hitch
 	"dojo/on",
-	"dojo/_base/sniff", // has("mozilla")
-	"dojo/_base/window", // win.doc.createElement win.doc.documentElement
+	"dojo/sniff", // has("mozilla")
 	"../registry",	// registry.getUniqueId()
 	"../_WidgetBase",
 	"./_LayoutWidget"
 ], function(array, cookie, declare, dom, domClass, domConstruct, domGeometry, domStyle,
-			event, kernel, lang, on, has, win, registry, _WidgetBase, _LayoutWidget){
-
-/*=====
-var _WidgetBase = dijit._WidgetBase;
-var _LayoutWidget = dijit.layout._LayoutWidget;
-=====*/
+			event, kernel, lang, on, has, registry, _WidgetBase, _LayoutWidget){
 
 // module:
 //		dijit/layout/SplitContainer
-// summary:
-//		Deprecated.  Use `dijit.layout.BorderContainer` instead.
 
 //
 // FIXME: make it prettier
@@ -35,28 +27,9 @@ var _LayoutWidget = dijit.layout._LayoutWidget;
 // FIXME: sizeWidth should be a CSS attribute (at 7 because css wants it to be 7 until we fix to css)
 //
 
-// These arguments can be specified for the children of a SplitContainer.
-// Since any widget can be specified as a SplitContainer child, mix them
-// into the base widget class.  (This is a hack, but it's effective.)
-lang.extend(_WidgetBase, {
-	// sizeMin: [deprecated] Integer
-	//		Deprecated.  Parameter for children of `dijit.layout.SplitContainer`.
-	//		Minimum size (width or height) of a child of a SplitContainer.
-	//		The value is relative to other children's sizeShare properties.
-	sizeMin: 10,
-
-	// sizeShare: [deprecated] Integer
-	//		Deprecated.  Parameter for children of `dijit.layout.SplitContainer`.
-	//		Size (width or height) of a child of a SplitContainer.
-	//		The value is relative to other children's sizeShare properties.
-	//		For example, if there are two children and each has sizeShare=10, then
-	//		each takes up 50% of the available space.
-	sizeShare: 10
-});
-
-return declare("dijit.layout.SplitContainer", _LayoutWidget, {
+var SplitContainer = declare("dijit.layout.SplitContainer", _LayoutWidget, {
 	// summary:
-	//		Deprecated.  Use `dijit.layout.BorderContainer` instead.
+	//		Deprecated.  Use `dijit/layout/BorderContainer` instead.
 	// description:
 	//		A Container widget with sizing handles in-between each child.
 	//		Contains multiple children widgets, all of which are displayed side by side
@@ -64,6 +37,9 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 	//		and you can adjust the relative size of each child by dragging the bars.
 	//
 	//		You must specify a size (width and height) for the SplitContainer.
+	//
+	//		See `SplitContainer.ChildWidgetProperties` for details on the properties that can be set on
+	//		children of a `SplitContainer`.
 	// tags:
 	//		deprecated
 
@@ -112,7 +88,7 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 				this.sizerWidth = parseInt(this.sizerWidth.toString());
 			}catch(e){ this.sizerWidth = 7; }
 		}
-		var sizer = win.doc.createElement('div');
+		var sizer = this.ownerDocument.createElement('div');
 		this.virtualSizer = sizer;
 		sizer.style.position = 'relative';
 
@@ -157,7 +133,7 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 		this.inherited(arguments);
 	},
 
-	_setupChild: function(/*dijit._Widget*/ child){
+	_setupChild: function(/*dijit/_WidgetBase*/ child){
 		this.inherited(arguments);
 		child.domNode.style.position = "absolute";
 		domClass.add(child.domNode, "dijitSplitPane");
@@ -179,7 +155,7 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 		index = index === undefined ? this.sizers.length : index;
 
 		// TODO: use a template for this!!!
-		var sizer = win.doc.createElement('div');
+		var sizer = this.ownerDocument.createElement('div');
 		sizer.id=registry.getUniqueId('dijit_layout_SplitterContainer_Splitter');
 		this.sizers.splice(index,0,sizer);
 		this.domNode.appendChild(sizer);
@@ -187,7 +163,7 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 		sizer.className = this.isHorizontal ? 'dijitSplitContainerSizerH' : 'dijitSplitContainerSizerV';
 
 		// add the thumb div
-		var thumb = win.doc.createElement('div');
+		var thumb = this.ownerDocument.createElement('div');
 		thumb.className = 'thumb';
 		sizer.appendChild(thumb);
 
@@ -200,7 +176,7 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 	removeChild: function(widget){
 		// summary:
 		//		Remove sizer, but only if widget is really our child and
-		// we have at least one sizer to throw away
+		//		we have at least one sizer to throw away
 		if(this.sizers.length){
 			var i = array.indexOf(this.getChildren(), widget);
 			if(i != -1){
@@ -219,15 +195,22 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 		}
 	},
 
-	addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
+	addChild: function(/*dijit/_WidgetBase*/ child, /*Integer?*/ insertIndex){
 		// summary:
 		//		Add a child widget to the container
 		// child:
 		//		a widget to add
 		// insertIndex:
-		//		postion in the "stack" to add the child widget
+		//		position in the "stack" to add the child widget
 
-		this.inherited(arguments);
+		// SplitContainer puts all the child widgets first, and all the splitters at the end.
+		// (This is not ideal for accessibility but not going to fix because the widget is deprecated.)
+		// So, just need to maintain that order so that _Container.addChild() puts the widgets where expected.
+		if(typeof insertIndex == "undefined" || insertIndex == "last"){
+			insertIndex = this.getChildren().length;
+		}
+
+		this.inherited(arguments, [child, insertIndex]);
 
 		if(this._started){
 			// Do the stuff that startup() does for each widget
@@ -417,68 +400,73 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 	},
 
 	beginSizing: function(e, i){
+		// summary:
+		//		Begin dragging the splitter between child[i] and child[i+1]
+
 		var children = this.getChildren();
+
 		this.paneBefore = children[i];
 		this.paneAfter = children[i+1];
 
+		this.paneBefore.sizeBeforeDrag = this.paneBefore.sizeActual;
+		this.paneAfter.sizeBeforeDrag = this.paneAfter.sizeActual;
+		this.paneAfter.positionBeforeDrag = this.paneAfter.position;
+
 		this.isSizing = true;
 		this.sizingSplitter = this.sizers[i];
+		this.sizingSplitter.positionBeforeDrag = domStyle.get(this.sizingSplitter,(this.isHorizontal ? "left" : "top"));
 
 		if(!this.cover){
 			this.cover = domConstruct.create('div', {
-					style: {
-						position:'absolute',
-						zIndex:5,
-						top: 0,
-						left: 0,
-						width: "100%",
-						height: "100%"
-					}
-				}, this.domNode);
+				style: {
+					position:'absolute',
+					zIndex:5,
+					top: 0,
+					left: 0,
+					width: "100%",
+					height: "100%"
+				}
+			}, this.domNode);
 		}else{
 			this.cover.style.zIndex = 5;
 		}
 		this.sizingSplitter.style.zIndex = 6;
 
-		// TODO: REVISIT - we want MARGIN_BOX and core hasn't exposed that yet (but can't we use it anyway if we pay attention? we do elsewhere.)
-		this.originPos = domGeometry.position(children[0].domNode, true);
-		var client, screen;
-		if(this.isHorizontal){
-			client = e.layerX || e.offsetX || 0;
-			screen = e.pageX;
-			this.originPos = this.originPos.x;
-		}else{
-			client = e.layerY || e.offsetY || 0;
-			screen = e.pageY;
-			this.originPos = this.originPos.y;
-		}
-		this.startPoint = this.lastPoint = screen;
-		this.screenToClientOffset = screen - client;
-		this.dragOffset = this.lastPoint - this.paneBefore.sizeActual - this.originPos - this.paneBefore.position;
+		// startPoint is the e.pageX or e.pageY at start of drag
+		this.startPoint = this.lastPoint = (this.isHorizontal ? e.pageX : e.pageY);
+
+		// Calculate maximum to the left or right that splitter is allowed to be dragged
+		// minDelta is negative to indicate left/upward drag where end.pageX < start.pageX.
+		this.maxDelta = this.paneAfter.sizeActual - this.paneAfter.sizeMin;
+		this.minDelta = -1 * (this.paneBefore.sizeActual - this.paneBefore.sizeMin);
 
 		if(!this.activeSizing){
 			this._showSizingLine();
 		}
 
-		//
 		// attach mouse events
-		//
 		this._ownconnects = [
-			on(win.doc.documentElement, "mousemove", lang.hitch(this, "changeSizing")),
-			on(win.doc.documentElement, "mouseup", lang.hitch(this, "endSizing"))
+			on(this.ownerDocument.documentElement, "mousemove", lang.hitch(this, "changeSizing")),
+			on(this.ownerDocument.documentElement, "mouseup", lang.hitch(this, "endSizing"))
 		];
 
 		event.stop(e);
 	},
 
 	changeSizing: function(e){
+		// summary:
+		//		Called on mousemove while dragging the splitter
+
 		if(!this.isSizing){ return; }
+
+		// lastPoint is the most recent e.pageX or e.pageY during the drag
 		this.lastPoint = this.isHorizontal ? e.pageX : e.pageY;
-		this.movePoint();
+		var delta = Math.max(Math.min(this.lastPoint - this.startPoint, this.maxDelta), this.minDelta);
+
 		if(this.activeSizing){
-			this._updateSize();
+			this._updateSize(delta);
 		}else{
-			this._moveSizingLine();
+			this._moveSizingLine(delta);
 		}
 		event.stop(e);
 	},
@@ -492,7 +480,8 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 			this._hideSizingLine();
 		}
 
-		this._updateSize();
+		var delta = Math.max(Math.min(this.lastPoint - this.startPoint, this.maxDelta), this.minDelta);
+		this._updateSize(delta);
 
 		this.isSizing = false;
 
@@ -504,53 +493,17 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 		while(h = this._ownconnects.pop()){ h.remove(); }
 	},
 
-	movePoint: function(){
-
-		// make sure lastPoint is a legal point to drag to
-		var p = this.lastPoint - this.screenToClientOffset;
-
-		var a = p - this.dragOffset;
-		a = this.legaliseSplitPoint(a);
-		p = a + this.dragOffset;
-
-		this.lastPoint = p + this.screenToClientOffset;
-	},
-
-	legaliseSplitPoint: function(a){
-
-		a += this.sizingSplitter.position;
-
-		this.isDraggingLeft = !!(a > 0);
-
-		if(!this.activeSizing){
-			var min = this.paneBefore.position + this.paneBefore.sizeMin;
-			if(a < min){
-				a = min;
-			}
-
-			var max = this.paneAfter.position + (this.paneAfter.sizeActual - (this.sizerWidth + this.paneAfter.sizeMin));
-			if(a > max){
-				a = max;
-			}
-		}
-
-		a -= this.sizingSplitter.position;
-
-		this._checkSizes();
-
-		return a;
-	},
-
-	_updateSize: function(){
-	//FIXME: sometimes this.lastPoint is NaN
-		var pos = this.lastPoint - this.dragOffset - this.originPos;
-
-		var start_region = this.paneBefore.position;
-		var end_region = this.paneAfter.position + this.paneAfter.sizeActual;
+	_updateSize: function(/*Number*/ delta){
+		// summary:
+		//		Resets sizes of panes before and after splitter being dragged.
+		//		Called during a drag, for active sizing, or at the end of a drag otherwise.
+		// delta: Number
+		//		Change in slider position compared to start of drag.   But note that
+		//		this function may be called multiple times during drag.
 
-		this.paneBefore.sizeActual = pos - start_region;
-		this.paneAfter.position	= pos + this.sizerWidth;
-		this.paneAfter.sizeActual = end_region - this.paneAfter.position;
+		this.paneBefore.sizeActual = this.paneBefore.sizeBeforeDrag + delta;
+		this.paneAfter.position	= this.paneAfter.positionBeforeDrag + delta;
+		this.paneAfter.sizeActual = this.paneAfter.sizeBeforeDrag - delta;
 
 		array.forEach(this.getChildren(), function(child){
 			child.sizeShare = child.sizeActual;
@@ -562,8 +515,10 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 	},
 
 	_showSizingLine: function(){
+		// summary:
+		//		Show virtual splitter, for non-active resizing
 
-		this._moveSizingLine();
+		this._moveSizingLine(0);
 
 		domGeometry.setMarginBox(this.virtualSizer,
 			this.isHorizontal ? { w: this.sizerWidth, h: this.paneHeight } : { w: this.paneWidth, h: this.sizerWidth });
@@ -575,10 +530,11 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 		this.virtualSizer.style.display = 'none';
 	},
 
-	_moveSizingLine: function(){
-		var pos = (this.lastPoint - this.startPoint) + this.sizingSplitter.position;
+	_moveSizingLine: function(/*Number*/ delta){
+		// summary:
+		//		Called for non-active resizing, to move the virtual splitter without adjusting the size of the panes
+		var pos = delta + this.sizingSplitter.positionBeforeDrag;
 		domStyle.set(this.virtualSizer,(this.isHorizontal ? "left" : "top"),pos+"px");
-		// this.virtualSizer.style[ this.isHorizontal ? "left" : "top" ] = pos + 'px'; // FIXME: remove this line if the previous is better
 	},
 
 	_getCookieName: function(i){
@@ -608,4 +564,28 @@ return declare("dijit.layout.SplitContainer", _LayoutWidget, {
 	}
 });
 
+SplitContainer.ChildWidgetProperties = {
+	// summary:
+	//		These properties can be specified for the children of a SplitContainer.
+
+	// sizeMin: [deprecated] Integer
+	//		Minimum size (width or height) of a child of a SplitContainer.
+	//		The value is relative to other children's sizeShare properties.
+	sizeMin: 10,
+
+	// sizeShare: [deprecated] Integer
+	//		Size (width or height) of a child of a SplitContainer.
+	//		The value is relative to other children's sizeShare properties.
+	//		For example, if there are two children and each has sizeShare=10, then
+	//		each takes up 50% of the available space.
+	sizeShare: 10
+};
+
+// Since any widget can be specified as a SplitContainer child, mix them
+// into the base widget class.  (This is a hack, but it's effective.)
+// This is for the benefit of the parser.   Remove for 2.0.  Also, hide from doc viewer.
+lang.extend(_WidgetBase, /*===== {} || =====*/ SplitContainer.ChildWidgetProperties);
+
+return SplitContainer;
+
 });
diff --git a/dijit/layout/StackContainer.js b/dijit/layout/StackContainer.js
index 4f81a3e..bdfb781 100644
--- a/dijit/layout/StackContainer.js
+++ b/dijit/layout/StackContainer.js
@@ -3,366 +3,410 @@ define([
 	"dojo/cookie", // cookie
 	"dojo/_base/declare", // declare
 	"dojo/dom-class", // domClass.add domClass.replace
-	"dojo/_base/kernel",	// kernel.isAsync
-	"dojo/_base/lang",	// lang.extend
+	"dojo/dom-construct",
+	"dojo/has", // has("dijit-legacy-requires")
+	"dojo/_base/lang", // lang.extend
+	"dojo/on",
 	"dojo/ready",
 	"dojo/topic", // publish
-	"../registry",	// registry.byId
+	"dojo/when",
+	"../registry", // registry.byId
 	"../_WidgetBase",
 	"./_LayoutWidget",
 	"dojo/i18n!../nls/common"
-], function(array, cookie, declare, domClass, kernel, lang, ready, topic,
-			registry, _WidgetBase, _LayoutWidget){
-
-/*=====
-var _WidgetBase = dijit._WidgetBase;
-var _LayoutWidget = dijit.layout._LayoutWidget;
-var StackController = dijit.layout.StackController;
-=====*/
-
-// module:
-//		dijit/layout/StackContainer
-// summary:
-//		A container that has multiple children, but shows only one child at a time.
-
-// Back compat w/1.6, remove for 2.0
-if(!kernel.isAsync){
-	ready(0, function(){
-		var requires = ["dijit/layout/StackController"];
-		require(requires);	// use indirection so modules not rolled into a build
-	});
-}
-
-// These arguments can be specified for the children of a StackContainer.
-// Since any widget can be specified as a StackContainer child, mix them
-// into the base widget class.  (This is a hack, but it's effective.)
-lang.extend(_WidgetBase, {
-	// selected: Boolean
-	//		Parameter for children of `dijit.layout.StackContainer` or subclasses.
-	//		Specifies that this widget should be the initially displayed pane.
-	//		Note: to change the selected child use `dijit.layout.StackContainer.selectChild`
-	selected: false,
-
-	// closable: Boolean
-	//		Parameter for children of `dijit.layout.StackContainer` or subclasses.
-	//		True if user can close (destroy) this child, such as (for example) clicking the X on the tab.
-	closable: false,
-
-	// iconClass: String
-	//		Parameter for children of `dijit.layout.StackContainer` or subclasses.
-	//		CSS Class specifying icon to use in label associated with this pane.
-	iconClass: "dijitNoIcon",
-
-	// showTitle: Boolean
-	//		Parameter for children of `dijit.layout.StackContainer` or subclasses.
-	//		When true, display title of this widget as tab label etc., rather than just using
-	//		icon specified in iconClass
-	showTitle: true
-});
-
-return declare("dijit.layout.StackContainer", _LayoutWidget, {
-	// summary:
-	//		A container that has multiple children, but shows only
-	//		one child at a time
-	//
-	// description:
-	//		A container for widgets (ContentPanes, for example) That displays
-	//		only one Widget at a time.
-	//
-	//		Publishes topics [widgetId]-addChild, [widgetId]-removeChild, and [widgetId]-selectChild
-	//
-	//		Can be base class for container, Wizard, Show, etc.
-
-	// doLayout: Boolean
-	//		If true, change the size of my currently displayed child to match my size
-	doLayout: true,
-
-	// persist: Boolean
-	//		Remembers the selected child across sessions
-	persist: false,
-
-	baseClass: "dijitStackContainer",
-
-/*=====
-	// selectedChildWidget: [readonly] dijit._Widget
-	//		References the currently selected child widget, if any.
-	//		Adjust selected child with selectChild() method.
-	selectedChildWidget: null,
-=====*/
-
-	buildRendering: function(){
-		this.inherited(arguments);
-		domClass.add(this.domNode, "dijitLayoutContainer");
-		this.containerNode.setAttribute("role", "tabpanel");
-	},
-
-	postCreate: function(){
-		this.inherited(arguments);
-		this.connect(this.domNode, "onkeypress", this._onKeyPress);
-	},
-
-	startup: function(){
-		if(this._started){ return; }
-
-		var children = this.getChildren();
-
-		// Setup each page panel to be initially hidden
-		array.forEach(children, this._setupChild, this);
-
-		// Figure out which child to initially display, defaulting to first one
-		if(this.persist){
-			this.selectedChildWidget = registry.byId(cookie(this.id + "_selectedChild"));
-		}else{
-			array.some(children, function(child){
-				if(child.selected){
-					this.selectedChildWidget = child;
-				}
-				return child.selected;
-			}, this);
-		}
-		var selected = this.selectedChildWidget;
-		if(!selected && children[0]){
-			selected = this.selectedChildWidget = children[0];
-			selected.selected = true;
-		}
-
-		// Publish information about myself so any StackControllers can initialize.
-		// This needs to happen before this.inherited(arguments) so that for
-		// TabContainer, this._contentBox doesn't include the space for the tab labels.
-		topic.publish(this.id+"-startup", {children: children, selected: selected});
-
-		// Startup each child widget, and do initial layout like setting this._contentBox,
-		// then calls this.resize() which does the initial sizing on the selected child.
-		this.inherited(arguments);
-	},
-
-	resize: function(){
-		// Resize is called when we are first made visible (it's called from startup()
-		// if we are initially visible). If this is the first time we've been made
-		// visible then show our first child.
-		if(!this._hasBeenShown){
-			this._hasBeenShown = true;
-			var selected = this.selectedChildWidget;
-			if(selected){
-				this._showChild(selected);
-			}
-		}
-		this.inherited(arguments);
-	},
+], function(array, cookie, declare, domClass, domConstruct, has, lang, on, ready, topic, when, registry, _WidgetBase, _LayoutWidget){
 
-	_setupChild: function(/*dijit._Widget*/ child){
-		// Overrides _LayoutWidget._setupChild()
+	// module:
+	//		dijit/layout/StackContainer
 
-		this.inherited(arguments);
+	// Back compat w/1.6, remove for 2.0
+	if(has("dijit-legacy-requires")){
+		ready(0, function(){
+			var requires = ["dijit/layout/StackController"];
+			require(requires);	// use indirection so modules not rolled into a build
+		});
+	}
 
-		domClass.replace(child.domNode, "dijitHidden", "dijitVisible");
+	var StackContainer = declare("dijit.layout.StackContainer", _LayoutWidget, {
+		// summary:
+		//		A container that has multiple children, but shows only
+		//		one child at a time
+		//
+		// description:
+		//		A container for widgets (ContentPanes, for example) That displays
+		//		only one Widget at a time.
+		//
+		//		Publishes topics [widgetId]-addChild, [widgetId]-removeChild, and [widgetId]-selectChild
+		//
+		//		Can be base class for container, Wizard, Show, etc.
+		//
+		//		See `StackContainer.ChildWidgetProperties` for details on the properties that can be set on
+		//		children of a `StackContainer`.
+
+		// doLayout: Boolean
+		//		If true, change the size of my currently displayed child to match my size
+		doLayout: true,
+
+		// persist: Boolean
+		//		Remembers the selected child across sessions
+		persist: false,
+
+		baseClass: "dijitStackContainer",
+
+		/*=====
+		// selectedChildWidget: [readonly] dijit._Widget
+		//		References the currently selected child widget, if any.
+		//		Adjust selected child with selectChild() method.
+		selectedChildWidget: null,
+		=====*/
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			domClass.add(this.domNode, "dijitLayoutContainer");
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this.own(
+				on(this.domNode, "keydown", lang.hitch(this, "_onKeyDown"))
+			);
+		},
+
+		startup: function(){
+			if(this._started){
+				return;
+			}
 
-		// remove the title attribute so it doesn't show up when i hover
-		// over a node
-		child.domNode.title = "";
-	},
+			var children = this.getChildren();
 
-	addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
-		// Overrides _Container.addChild() to do layout and publish events
+			// Setup each page panel to be initially hidden
+			array.forEach(children, this._setupChild, this);
 
-		this.inherited(arguments);
+			// Figure out which child to initially display, defaulting to first one
+			if(this.persist){
+				this.selectedChildWidget = registry.byId(cookie(this.id + "_selectedChild"));
+			}else{
+				array.some(children, function(child){
+					if(child.selected){
+						this.selectedChildWidget = child;
+					}
+					return child.selected;
+				}, this);
+			}
+			var selected = this.selectedChildWidget;
+			if(!selected && children[0]){
+				selected = this.selectedChildWidget = children[0];
+				selected.selected = true;
+			}
 
-		if(this._started){
-			topic.publish(this.id+"-addChild", child, insertIndex);	// publish
+			// Publish information about myself so any StackControllers can initialize.
+			// This needs to happen before this.inherited(arguments) so that for
+			// TabContainer, this._contentBox doesn't include the space for the tab labels.
+			topic.publish(this.id + "-startup", {children: children, selected: selected, textDir: this.textDir});
+
+			// Startup each child widget, and do initial layout like setting this._contentBox,
+			// then calls this.resize() which does the initial sizing on the selected child.
+			this.inherited(arguments);
+		},
+
+		resize: function(){
+			// Overrides _LayoutWidget.resize()
+			// Resize is called when we are first made visible (it's called from startup()
+			// if we are initially visible). If this is the first time we've been made
+			// visible then show our first child.
+			if(!this._hasBeenShown){
+				this._hasBeenShown = true;
+				var selected = this.selectedChildWidget;
+				if(selected){
+					this._showChild(selected);
+				}
+			}
+			this.inherited(arguments);
+		},
+
+		_setupChild: function(/*dijit/_WidgetBase*/ child){
+			// Overrides _LayoutWidget._setupChild()
+
+			// For aria support, wrap child widget in a <div role="tabpanel">
+			var childNode = child.domNode,
+				wrapper = domConstruct.place(
+					"<div role='tabpanel' class='" + this.baseClass + "ChildWrapper dijitHidden'>",
+					child.domNode,
+					"replace"),
+				label = child["aria-label"] || child.title || child.label;
+			if(label){
+				// setAttribute() escapes special chars, and if() statement avoids setting aria-label="undefined"
+				wrapper.setAttribute("aria-label", label);
+			}
+			domConstruct.place(childNode, wrapper);
+			child._wrapper = wrapper;	// to set the aria-labelledby in StackController
 
-			// in case the tab titles have overflowed from one line to two lines
-			// (or, if this if first child, from zero lines to one line)
-			// TODO: w/ScrollingTabController this is no longer necessary, although
-			// ScrollTabController.resize() does need to get called to show/hide
-			// the navigation buttons as appropriate, but that's handled in ScrollingTabController.onAddChild().
-			// If this is updated to not layout [except for initial child added / last child removed], update
-			// "childless startup" test in StackContainer.html to check for no resize event after second addChild()
-			this.layout();
+			this.inherited(arguments);
 
-			// if this is the first child, then select it
-			if(!this.selectedChildWidget){
-				this.selectChild(child);
+			// child may have style="display: none" (at least our test cases do), so remove that
+			if(childNode.style.display == "none"){
+				childNode.style.display = "block";
 			}
-		}
-	},
-
-	removeChild: function(/*dijit._Widget*/ page){
-		// Overrides _Container.removeChild() to do layout and publish events
 
-		this.inherited(arguments);
+			// remove the title attribute so it doesn't show up when i hover over a node
+			child.domNode.title = "";
+		},
 
-		if(this._started){
-			// this will notify any tablists to remove a button; do this first because it may affect sizing
-			topic.publish(this.id + "-removeChild", page);	// publish
-		}
+		addChild: function(/*dijit/_WidgetBase*/ child, /*Integer?*/ insertIndex){
+			// Overrides _Container.addChild() to do layout and publish events
 
-		// If all our children are being destroyed than don't run the code below (to select another page),
-		//  because we are deleting every page one by one
-		if(this._descendantsBeingDestroyed){ return; }
+			this.inherited(arguments);
 
-		// Select new page to display, also updating TabController to show the respective tab.
-		// Do this before layout call because it can affect the height of the TabController.
-		if(this.selectedChildWidget === page){
-			this.selectedChildWidget = undefined;
 			if(this._started){
-				var children = this.getChildren();
-				if(children.length){
-					this.selectChild(children[0]);
+				topic.publish(this.id + "-addChild", child, insertIndex);	// publish
+
+				// in case the tab titles have overflowed from one line to two lines
+				// (or, if this if first child, from zero lines to one line)
+				// TODO: w/ScrollingTabController this is no longer necessary, although
+				// ScrollTabController.resize() does need to get called to show/hide
+				// the navigation buttons as appropriate, but that's handled in ScrollingTabController.onAddChild().
+				// If this is updated to not layout [except for initial child added / last child removed], update
+				// "childless startup" test in StackContainer.html to check for no resize event after second addChild()
+				this.layout();
+
+				// if this is the first child, then select it
+				if(!this.selectedChildWidget){
+					this.selectChild(child);
 				}
 			}
-		}
+		},
 
-		if(this._started){
-			// In case the tab titles now take up one line instead of two lines
-			// (note though that ScrollingTabController never overflows to multiple lines),
-			// or the height has changed slightly because of addition/removal of tab which close icon
-			this.layout();
-		}
-	},
+		removeChild: function(/*dijit/_WidgetBase*/ page){
+			// Overrides _Container.removeChild() to do layout and publish events
 
-	selectChild: function(/*dijit._Widget|String*/ page, /*Boolean*/ animate){
-		// summary:
-		//		Show the given widget (which must be one of my children)
-		// page:
-		//		Reference to child widget or id of child widget
+			var idx = array.indexOf(this.getChildren(), page);
 
-		page = registry.byId(page);
+			this.inherited(arguments);
 
-		if(this.selectedChildWidget != page){
-			// Deselect old page and select new one
-			var d = this._transition(page, this.selectedChildWidget, animate);
-			this._set("selectedChildWidget", page);
-			topic.publish(this.id+"-selectChild", page);	// publish
+			// Remove the child widget wrapper we use to set aria roles.  This won't affect the page itself since it's
+			// already been detached from page._wrapper via the this.inherited(arguments) call above.
+			domConstruct.destroy(page._wrapper);
+			delete page._wrapper;
 
-			if(this.persist){
-				cookie(this.id + "_selectedChild", this.selectedChildWidget.id);
+			if(this._started){
+				// This will notify any tablists to remove a button; do this first because it may affect sizing.
+				topic.publish(this.id + "-removeChild", page);
 			}
-		}
 
-		return d;		// If child has an href, promise that fires when the child's href finishes loading
-	},
+			// If all our children are being destroyed than don't run the code below (to select another page),
+			// because we are deleting every page one by one
+			if(this._descendantsBeingDestroyed){
+				return;
+			}
 
-	_transition: function(newWidget, oldWidget /*===== ,  animate =====*/){
-		// summary:
-		//		Hide the old widget and display the new widget.
-		//		Subclasses should override this.
-		// newWidget: dijit._Widget
-		//		The newly selected widget.
-		// oldWidget: dijit._Widget
-		//		The previously selected widget.
-		// animate: Boolean
-		//		Used by AccordionContainer to turn on/off slide effect.
-		// tags:
-		//		protected extension
-		if(oldWidget){
-			this._hideChild(oldWidget);
-		}
-		var d = this._showChild(newWidget);
-
-		// Size the new widget, in case this is the first time it's being shown,
-		// or I have been resized since the last time it was shown.
-		// Note that page must be visible for resizing to work.
-		if(newWidget.resize){
-			if(this.doLayout){
-				newWidget.resize(this._containerContentBox || this._contentBox);
-			}else{
-				// the child should pick it's own size but we still need to call resize()
-				// (with no arguments) to let the widget lay itself out
-				newWidget.resize();
+			// Select new page to display, also updating TabController to show the respective tab.
+			// Do this before layout call because it can affect the height of the TabController.
+			if(this.selectedChildWidget === page){
+				this.selectedChildWidget = undefined;
+				if(this._started){
+					var children = this.getChildren();
+					if(children.length){
+						this.selectChild(children[Math.max(idx - 1, 0)]);
+					}
+				}
 			}
-		}
 
-		return d;	// If child has an href, promise that fires when the child's href finishes loading
-	},
+			if(this._started){
+				// In case the tab titles now take up one line instead of two lines
+				// (note though that ScrollingTabController never overflows to multiple lines),
+				// or the height has changed slightly because of addition/removal of tab which close icon
+				this.layout();
+			}
+		},
 
-	_adjacent: function(/*Boolean*/ forward){
-		// summary:
-		//		Gets the next/previous child widget in this container from the current selection.
-		var children = this.getChildren();
-		var index = array.indexOf(children, this.selectedChildWidget);
-		index += forward ? 1 : children.length - 1;
-		return children[ index % children.length ]; // dijit._Widget
-	},
-
-	forward: function(){
-		// summary:
-		//		Advance to next page.
-		return this.selectChild(this._adjacent(true), true);
-	},
+		selectChild: function(/*dijit/_WidgetBase|String*/ page, /*Boolean*/ animate){
+			// summary:
+			//		Show the given widget (which must be one of my children)
+			// page:
+			//		Reference to child widget or id of child widget
 
-	back: function(){
-		// summary:
-		//		Go back to previous page.
-		return this.selectChild(this._adjacent(false), true);
-	},
-
-	_onKeyPress: function(e){
-		topic.publish(this.id+"-containerKeyPress", { e: e, page: this});	// publish
-	},
-
-	layout: function(){
-		// Implement _LayoutWidget.layout() virtual method.
-		var child = this.selectedChildWidget;
-		if(child && child.resize){
-			if(this.doLayout){
-				child.resize(this._containerContentBox || this._contentBox);
-			}else{
-				child.resize();
+			var d;
+
+			page = registry.byId(page);
+
+			if(this.selectedChildWidget != page){
+				// Deselect old page and select new one
+				d = this._transition(page, this.selectedChildWidget, animate);
+				this._set("selectedChildWidget", page);
+				topic.publish(this.id + "-selectChild", page);	// publish
+
+				if(this.persist){
+					cookie(this.id + "_selectedChild", this.selectedChildWidget.id);
+				}
 			}
-		}
-	},
 
-	_showChild: function(/*dijit._Widget*/ page){
-		// summary:
-		//		Show the specified child by changing it's CSS, and call _onShow()/onShow() so
-		//		it can do any updates it needs regarding loading href's etc.
-		// returns:
-		//		Promise that fires when page has finished showing, or true if there's no href
-		var children = this.getChildren();
-		page.isFirstChild = (page == children[0]);
-		page.isLastChild = (page == children[children.length-1]);
-		page._set("selected", true);
+			// d may be null, or a scalar like true.  Return a promise in all cases
+			return when(d || true);		// Promise
+		},
+
+		_transition: function(newWidget, oldWidget /*===== ,  animate =====*/){
+			// summary:
+			//		Hide the old widget and display the new widget.
+			//		Subclasses should override this.
+			// newWidget: dijit/_WidgetBase
+			//		The newly selected widget.
+			// oldWidget: dijit/_WidgetBase
+			//		The previously selected widget.
+			// animate: Boolean
+			//		Used by AccordionContainer to turn on/off slide effect.
+			// tags:
+			//		protected extension
+			if(oldWidget){
+				this._hideChild(oldWidget);
+			}
+			var d = this._showChild(newWidget);
+
+			// Size the new widget, in case this is the first time it's being shown,
+			// or I have been resized since the last time it was shown.
+			// Note that page must be visible for resizing to work.
+			if(newWidget.resize){
+				if(this.doLayout){
+					newWidget.resize(this._containerContentBox || this._contentBox);
+				}else{
+					// the child should pick it's own size but we still need to call resize()
+					// (with no arguments) to let the widget lay itself out
+					newWidget.resize();
+				}
+			}
 
-		domClass.replace(page.domNode, "dijitVisible", "dijitHidden");
+			return d;	// If child has an href, promise that fires when the child's href finishes loading
+		},
+
+		_adjacent: function(/*Boolean*/ forward){
+			// summary:
+			//		Gets the next/previous child widget in this container from the current selection.
+
+			// TODO: remove for 2.0 if this isn't being used.   Otherwise, fix to skip disabled tabs.
+
+			var children = this.getChildren();
+			var index = array.indexOf(children, this.selectedChildWidget);
+			index += forward ? 1 : children.length - 1;
+			return children[ index % children.length ]; // dijit/_WidgetBase
+		},
+
+		forward: function(){
+			// summary:
+			//		Advance to next page.
+			return this.selectChild(this._adjacent(true), true);
+		},
+
+		back: function(){
+			// summary:
+			//		Go back to previous page.
+			return this.selectChild(this._adjacent(false), true);
+		},
+
+		_onKeyDown: function(e){
+			topic.publish(this.id + "-containerKeyDown", { e: e, page: this});	// publish
+		},
+
+		layout: function(){
+			// Implement _LayoutWidget.layout() virtual method.
+			var child = this.selectedChildWidget;
+			if(child && child.resize){
+				if(this.doLayout){
+					child.resize(this._containerContentBox || this._contentBox);
+				}else{
+					child.resize();
+				}
+			}
+		},
+
+		_showChild: function(/*dijit/_WidgetBase*/ page){
+			// summary:
+			//		Show the specified child by changing it's CSS, and call _onShow()/onShow() so
+			//		it can do any updates it needs regarding loading href's etc.
+			// returns:
+			//		Promise that fires when page has finished showing, or true if there's no href
+			var children = this.getChildren();
+			page.isFirstChild = (page == children[0]);
+			page.isLastChild = (page == children[children.length - 1]);
+			page._set("selected", true);
+
+			if(page._wrapper){	// false if not started yet
+				domClass.replace(page._wrapper, "dijitVisible", "dijitHidden");
+			}
 
-		return (page._onShow && page._onShow()) || true;
-	},
+			return (page._onShow && page._onShow()) || true;
+		},
 
-	_hideChild: function(/*dijit._Widget*/ page){
-		// summary:
-		//		Hide the specified child by changing it's CSS, and call _onHide() so
-		//		it's notified.
-		page._set("selected", false);
-		domClass.replace(page.domNode, "dijitHidden", "dijitVisible");
+		_hideChild: function(/*dijit/_WidgetBase*/ page){
+			// summary:
+			//		Hide the specified child by changing it's CSS, and call _onHide() so
+			//		it's notified.
+			page._set("selected", false);
 
-		page.onHide && page.onHide();
-	},
+			if(page._wrapper){	// false if not started yet
+				domClass.replace(page._wrapper, "dijitHidden", "dijitVisible");
+			}
 
-	closeChild: function(/*dijit._Widget*/ page){
-		// summary:
-		//		Callback when user clicks the [X] to remove a page.
-		//		If onClose() returns true then remove and destroy the child.
-		// tags:
-		//		private
-		var remove = page.onClose(this, page);
-		if(remove){
-			this.removeChild(page);
-			// makes sure we can clean up executeScripts in ContentPane onUnLoad
-			page.destroyRecursive();
-		}
-	},
-
-	destroyDescendants: function(/*Boolean*/ preserveDom){
-		this._descendantsBeingDestroyed = true;
-		this.selectedChildWidget = undefined;
-		array.forEach(this.getChildren(), function(child){
-			if(!preserveDom){
-				this.removeChild(child);
+			page.onHide && page.onHide();
+		},
+
+		closeChild: function(/*dijit/_WidgetBase*/ page){
+			// summary:
+			//		Callback when user clicks the [X] to remove a page.
+			//		If onClose() returns true then remove and destroy the child.
+			// tags:
+			//		private
+			var remove = page.onClose && page.onClose(this, page);
+			if(remove){
+				this.removeChild(page);
+				// makes sure we can clean up executeScripts in ContentPane onUnLoad
+				page.destroyRecursive();
 			}
-			child.destroyRecursive(preserveDom);
-		}, this);
-		this._descendantsBeingDestroyed = false;
-	}
-});
+		},
+
+		destroyDescendants: function(/*Boolean*/ preserveDom){
+			this._descendantsBeingDestroyed = true;
+			this.selectedChildWidget = undefined;
+			array.forEach(this.getChildren(), function(child){
+				if(!preserveDom){
+					this.removeChild(child);
+				}
+				child.destroyRecursive(preserveDom);
+			}, this);
+			this._descendantsBeingDestroyed = false;
+		}
+	});
 
+	StackContainer.ChildWidgetProperties = {
+		// summary:
+		//		These properties can be specified for the children of a StackContainer.
+
+		// selected: Boolean
+		//		Specifies that this widget should be the initially displayed pane.
+		//		Note: to change the selected child use `dijit/layout/StackContainer.selectChild`
+		selected: false,
+
+		// disabled: Boolean
+		//		Specifies that the button to select this pane should be disabled.
+		//		Doesn't affect programmatic selection of the pane, nor does it deselect the pane if it is currently selected.
+		disabled: false,
+
+		// closable: Boolean
+		//		True if user can close (destroy) this child, such as (for example) clicking the X on the tab.
+		closable: false,
+
+		// iconClass: String
+		//		CSS Class specifying icon to use in label associated with this pane.
+		iconClass: "dijitNoIcon",
+
+		// showTitle: Boolean
+		//		When true, display title of this widget as tab label etc., rather than just using
+		//		icon specified in iconClass
+		showTitle: true
+	};
+
+	// Since any widget can be specified as a StackContainer child, mix them
+	// into the base widget class.  (This is a hack, but it's effective.)
+	// This is for the benefit of the parser.   Remove for 2.0.  Also, hide from doc viewer.
+	lang.extend(_WidgetBase, /*===== {} || =====*/ StackContainer.ChildWidgetProperties);
+
+	return StackContainer;
 });
diff --git a/dijit/layout/StackController.js b/dijit/layout/StackController.js
index 6f0cf81..d535407 100644
--- a/dijit/layout/StackController.js
+++ b/dijit/layout/StackController.js
@@ -1,31 +1,24 @@
 define([
 	"dojo/_base/array", // array.forEach array.indexOf array.map
 	"dojo/_base/declare", // declare
-	"dojo/_base/event", // event.stop
+	"dojo/dom-class",
+	"dojo/dom-construct",
 	"dojo/keys", // keys
 	"dojo/_base/lang", // lang.getObject
-	"dojo/_base/sniff", // has("ie")
-	"../focus",		// focus.focus()
-	"../registry",	// registry.byId
+	"dojo/on",
+	"dojo/topic",
+	"../focus", // focus.focus()
+	"../registry", // registry.byId
 	"../_Widget",
 	"../_TemplatedMixin",
 	"../_Container",
 	"../form/ToggleButton",
+	"dojo/touch",	// for normalized click handling, see dojoClick property setting in postCreate()
 	"dojo/i18n!../nls/common"
-], function(array, declare, event, keys, lang, has,
-			focus, registry, _Widget, _TemplatedMixin, _Container, ToggleButton){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-	var _Container = dijit._Container;
-	var ToggleButton = dijit.form.ToggleButton;
-=====*/
+], function(array, declare, domClass, domConstruct, keys, lang, on, topic, focus, registry, _Widget, _TemplatedMixin, _Container, ToggleButton){
 
 	// module:
 	//		dijit/layout/StackController
-	// summary:
-	//		Set of buttons to select a page in a `dijit.layout.StackContainer`
 
 	var StackButton = declare("dijit.layout._StackButton", ToggleButton, {
 		// summary:
@@ -43,47 +36,26 @@ define([
 		// closeButton: Boolean
 		//		When true, display close button for this tab
 		closeButton: false,
-		
-		_setCheckedAttr: function(/*Boolean*/ value, /*Boolean?*/ priorityChange){
-			this.inherited(arguments);
-			this.focusNode.removeAttribute("aria-pressed");
-		},
+
+		_aria_attr: "aria-selected",
 
 		buildRendering: function(/*Event*/ evt){
 			this.inherited(arguments);
 			(this.focusNode || this.domNode).setAttribute("role", "tab");
-		},
-
-		onClick: function(/*Event*/ /*===== evt =====*/){
-			// summary:
-			//		This is for TabContainer where the tabs are <span> rather than button,
-			//		so need to set focus explicitly (on some browsers)
-			//		Note that you shouldn't override this method, but you can connect to it.
-			focus.focus(this.focusNode);
-
-			// ... now let StackController catch the event and tell me what to do
-		},
-
-		onClickCloseButton: function(/*Event*/ evt){
-			// summary:
-			//		StackContainer connects to this function; if your widget contains a close button
-			//		then clicking it should call this function.
-			//		Note that you shouldn't override this method, but you can connect to it.
-			evt.stopPropagation();
 		}
 	});
 
 
 	var StackController = declare("dijit.layout.StackController", [_Widget, _TemplatedMixin, _Container], {
 		// summary:
-		//		Set of buttons to select a page in a `dijit.layout.StackContainer`
+		//		Set of buttons to select a page in a `dijit/layout/StackContainer`
 		// description:
 		//		Monitors the specified StackContainer, and whenever a page is
 		//		added, deleted, or selected, updates itself accordingly.
 
 		baseClass: "dijitStackController",
 
-		templateString: "<span role='tablist' data-dojo-attach-event='onkeypress'></span>",
+		templateString: "<span role='tablist' data-dojo-attach-event='onkeydown'></span>",
 
 		// containerId: [const] String
 		//		The id of the page container that I point to
@@ -93,21 +65,52 @@ define([
 		//		The button widget to create to correspond to each page
 		buttonWidget: StackButton,
 
-		constructor: function(){
-			this.pane2button = {};		// mapping from pane id to buttons
-			this.pane2connects = {};	// mapping from pane id to this.connect() handles
-			this.pane2watches = {};		// mapping from pane id to watch() handles
+		// buttonWidgetCloseClass: String
+		//		CSS class of [x] close icon, used by event delegation code to tell when close button was clicked
+		buttonWidgetCloseClass: "dijitStackCloseButton",
+
+		pane2button: function(/*String*/ id){
+			// summary:
+			//		Returns the button corresponding to the pane w/the given id.
+			// tags:
+			//		protected
+			return registry.byId(this.id + "_" + id);
 		},
 
 		postCreate: function(){
 			this.inherited(arguments);
 
-			// Listen to notifications from StackContainer
-			this.subscribe(this.containerId+"-startup", "onStartup");
-			this.subscribe(this.containerId+"-addChild", "onAddChild");
-			this.subscribe(this.containerId+"-removeChild", "onRemoveChild");
-			this.subscribe(this.containerId+"-selectChild", "onSelectChild");
-			this.subscribe(this.containerId+"-containerKeyPress", "onContainerKeyPress");
+			// Listen to notifications from StackContainer.  This is tricky because the StackContainer may not have
+			// been created yet, so abstracting it through topics.
+			// Note: for TabContainer we can do this through bubbled events instead of topics; maybe that's
+			// all we support for 2.0?
+			this.own(
+				topic.subscribe(this.containerId + "-startup", lang.hitch(this, "onStartup")),
+				topic.subscribe(this.containerId + "-addChild", lang.hitch(this, "onAddChild")),
+				topic.subscribe(this.containerId + "-removeChild", lang.hitch(this, "onRemoveChild")),
+				topic.subscribe(this.containerId + "-selectChild", lang.hitch(this, "onSelectChild")),
+				topic.subscribe(this.containerId + "-containerKeyDown", lang.hitch(this, "onContainerKeyDown"))
+			);
+
+			// Listen for click events to select or close tabs.
+			// No need to worry about ENTER/SPACE key handling: tabs are selected via left/right arrow keys,
+			// and closed via shift-F10 (to show the close menu).
+			// Also, add flag to use normalized click handling from dojo/touch
+			this.containerNode.dojoClick = true;
+			this.own(on(this.containerNode, 'click', lang.hitch(this, function(evt){
+				var button = registry.getEnclosingWidget(evt.target);
+				if(button != this.containerNode && !button.disabled && button.page){
+					for(var target = evt.target; target !== this.containerNode; target = target.parentNode){
+						if(domClass.contains(target, this.buttonWidgetCloseClass)){
+							this.onCloseButtonClick(button.page);
+							break;
+						}else if(target == button.domNode){
+							this.onButtonClick(button.page);
+							break;
+						}
+					}
+				}
+			})));
 		},
 
 		onStartup: function(/*Object*/ info){
@@ -115,22 +118,47 @@ define([
 			//		Called after StackContainer has finished initializing
 			// tags:
 			//		private
+			this.textDir = info.textDir;
 			array.forEach(info.children, this.onAddChild, this);
 			if(info.selected){
 				// Show button corresponding to selected pane (unless selected
 				// is null because there are no panes)
 				this.onSelectChild(info.selected);
 			}
-		},
 
-		destroy: function(){
-			for(var pane in this.pane2button){
-				this.onRemoveChild(registry.byId(pane));
+			// Reflect events like page title changes to tab buttons
+			var containerNode = registry.byId(this.containerId).containerNode,
+				pane2button = lang.hitch(this, "pane2button"),
+				paneToButtonAttr = {
+					"title": "label",
+					"showtitle": "showLabel",
+					"iconclass": "iconClass",
+					"closable": "closeButton",
+					"tooltip": "title",
+					"disabled": "disabled",
+					"textdir": "textdir"
+				},
+				connectFunc = function(attr, buttonAttr){
+					return on(containerNode, "attrmodified-" + attr, function(evt){
+						var button = pane2button(evt.detail && evt.detail.widget && evt.detail.widget.id);
+						if(button){
+							button.set(buttonAttr, evt.detail.newValue);
+						}
+					});
+				};
+			for(var attr in paneToButtonAttr){
+				this.own(connectFunc(attr, paneToButtonAttr[attr]));
 			}
+		},
+
+		destroy: function(preserveDom){
+			// Since the buttons are internal to the StackController widget, destroy() should remove them.
+			// When #5796 is fixed for 2.0 can get rid of this function completely.
+			this.destroyDescendants(preserveDom);
 			this.inherited(arguments);
 		},
 
-		onAddChild: function(/*dijit._Widget*/ page, /*Integer?*/ insertIndex){
+		onAddChild: function(/*dijit/_WidgetBase*/ page, /*Integer?*/ insertIndex){
 			// summary:
 			//		Called whenever a page is added to the container.
 			//		Create button corresponding to the page.
@@ -139,116 +167,103 @@ define([
 
 			// create an instance of the button widget
 			// (remove typeof buttonWidget == string support in 2.0)
-			var cls = lang.isString(this.buttonWidget) ? lang.getObject(this.buttonWidget) : this.buttonWidget;
-			var button = new cls({
+			var Cls = lang.isString(this.buttonWidget) ? lang.getObject(this.buttonWidget) : this.buttonWidget;
+			var button = new Cls({
 				id: this.id + "_" + page.id,
+				name: this.id + "_" + page.id, // note: must match id used in pane2button()
 				label: page.title,
+				disabled: page.disabled,
+				ownerDocument: this.ownerDocument,
 				dir: page.dir,
 				lang: page.lang,
-				textDir: page.textDir,
+				textDir: page.textDir || this.textDir,
 				showLabel: page.showTitle,
 				iconClass: page.iconClass,
 				closeButton: page.closable,
-				title: page.tooltip
-			});
-			button.focusNode.setAttribute("aria-selected", "false");
-
-
-			// map from page attribute to corresponding tab button attribute
-			var pageAttrList = ["title", "showTitle", "iconClass", "closable", "tooltip"],
-				buttonAttrList = ["label", "showLabel", "iconClass", "closeButton", "title"];
-
-			// watch() so events like page title changes are reflected in tab button
-			this.pane2watches[page.id] = array.map(pageAttrList, function(pageAttr, idx){
-				return page.watch(pageAttr, function(name, oldVal, newVal){
-					button.set(buttonAttrList[idx], newVal);
-				});
+				title: page.tooltip,
+				page: page
 			});
 
-			// connections so that clicking a tab button selects the corresponding page
-			this.pane2connects[page.id] = [
-				this.connect(button, 'onClick', lang.hitch(this,"onButtonClick", page)),
-				this.connect(button, 'onClickCloseButton', lang.hitch(this,"onCloseButtonClick", page))
-			];
-
 			this.addChild(button, insertIndex);
-			this.pane2button[page.id] = button;
 			page.controlButton = button;	// this value might be overwritten if two tabs point to same container
-			if(!this._currentChild){ // put the first child into the tab order
-				button.focusNode.setAttribute("tabIndex", "0");
-				button.focusNode.setAttribute("aria-selected", "true");
-				this._currentChild = page;
-			}
-			// make sure all tabs have the same length
-			if(!this.isLeftToRight() && has("ie") && this._rectifyRtlTabList){
-				this._rectifyRtlTabList();
+			if(!this._currentChild){
+				// If this is the first child then StackContainer will soon publish that it's selected,
+				// but before that StackContainer calls layout(), and before layout() is called the
+				// StackController needs to have the proper height... which means that the button needs
+				// to be marked as selected now.   See test_TabContainer_CSS.html for test.
+				this.onSelectChild(page);
 			}
+
+			// Add this StackController button to the list of things that labels that StackContainer pane.
+			// Also, if there's an aria-labelledby parameter for the pane, then the aria-label parameter is unneeded.
+			var labelledby = page._wrapper.getAttribute("aria-labelledby") ?
+				page._wrapper.getAttribute("aria-labelledby") + " " + button.id : button.id;
+			page._wrapper.removeAttribute("aria-label");
+			page._wrapper.setAttribute("aria-labelledby", labelledby);
 		},
 
-		onRemoveChild: function(/*dijit._Widget*/ page){
+		onRemoveChild: function(/*dijit/_WidgetBase*/ page){
 			// summary:
 			//		Called whenever a page is removed from the container.
 			//		Remove the button corresponding to the page.
 			// tags:
 			//		private
 
-			if(this._currentChild === page){ this._currentChild = null; }
-
-			// disconnect/unwatch connections/watches related to page being removed
-			array.forEach(this.pane2connects[page.id], lang.hitch(this, "disconnect"));
-			delete this.pane2connects[page.id];
-			array.forEach(this.pane2watches[page.id], function(w){ w.unwatch(); });
-			delete this.pane2watches[page.id];
+			if(this._currentChild === page){
+				this._currentChild = null;
+			}
 
-			var button = this.pane2button[page.id];
+			var button = this.pane2button(page.id);
 			if(button){
 				this.removeChild(button);
-				delete this.pane2button[page.id];
 				button.destroy();
 			}
 			delete page.controlButton;
 		},
 
-		onSelectChild: function(/*dijit._Widget*/ page){
+		onSelectChild: function(/*dijit/_WidgetBase*/ page){
 			// summary:
 			//		Called when a page has been selected in the StackContainer, either by me or by another StackController
 			// tags:
 			//		private
 
-			if(!page){ return; }
+			if(!page){
+				return;
+			}
 
 			if(this._currentChild){
-				var oldButton=this.pane2button[this._currentChild.id];
+				var oldButton = this.pane2button(this._currentChild.id);
 				oldButton.set('checked', false);
-				oldButton.focusNode.setAttribute("aria-selected", "false");
 				oldButton.focusNode.setAttribute("tabIndex", "-1");
 			}
 
-			var newButton=this.pane2button[page.id];
+			var newButton = this.pane2button(page.id);
 			newButton.set('checked', true);
-			newButton.focusNode.setAttribute("aria-selected", "true");
 			this._currentChild = page;
 			newButton.focusNode.setAttribute("tabIndex", "0");
 			var container = registry.byId(this.containerId);
-			container.containerNode.setAttribute("aria-labelledby", newButton.id);
 		},
 
-		onButtonClick: function(/*dijit._Widget*/ page){
+		onButtonClick: function(/*dijit/_WidgetBase*/ page){
 			// summary:
 			//		Called whenever one of my child buttons is pressed in an attempt to select a page
 			// tags:
 			//		private
 
-			if(this._currentChild.id === page.id) {
+			var button = this.pane2button(page.id);
+
+			// For TabContainer where the tabs are <span>, need to set focus explicitly when left/right arrow
+			focus.focus(button.focusNode);
+
+			if(this._currentChild && this._currentChild.id === page.id){
 				//In case the user clicked the checked button, keep it in the checked state because it remains to be the selected stack page.
-				var button=this.pane2button[page.id];
 				button.set('checked', true);
 			}
 			var container = registry.byId(this.containerId);
 			container.selectChild(page);
 		},
 
-		onCloseButtonClick: function(/*dijit._Widget*/ page){
+		onCloseButtonClick: function(/*dijit/_WidgetBase*/ page){
 			// summary:
 			//		Called whenever one of my child buttons [X] is pressed in an attempt to close a page
 			// tags:
@@ -257,7 +272,7 @@ define([
 			var container = registry.byId(this.containerId);
 			container.closeChild(page);
 			if(this._currentChild){
-				var b = this.pane2button[this._currentChild.id];
+				var b = this.pane2button(this._currentChild.id);
 				if(b){
 					focus.focus(b.focusNode || b.domNode);
 				}
@@ -267,86 +282,124 @@ define([
 		// TODO: this is a bit redundant with forward, back api in StackContainer
 		adjacent: function(/*Boolean*/ forward){
 			// summary:
-			//		Helper for onkeypress to find next/previous button
+			//		Helper for onkeydown to find next/previous button
 			// tags:
 			//		private
 
-			if(!this.isLeftToRight() && (!this.tabPosition || /top|bottom/.test(this.tabPosition))){ forward = !forward; }
+			if(!this.isLeftToRight() && (!this.tabPosition || /top|bottom/.test(this.tabPosition))){
+				forward = !forward;
+			}
 			// find currently focused button in children array
 			var children = this.getChildren();
-			var current = array.indexOf(children, this.pane2button[this._currentChild.id]);
-			// pick next button to focus on
-			var offset = forward ? 1 : children.length - 1;
-			return children[ (current + offset) % children.length ]; // dijit._Widget
+			var idx = array.indexOf(children, this.pane2button(this._currentChild.id)),
+				current = children[idx];
+
+			// Pick next/previous non-disabled button to focus on.   If we get back to the original button it means
+			// that all buttons must be disabled, so return current child to avoid an infinite loop.
+			var child;
+			do{
+				idx = (idx + (forward ? 1 : children.length - 1)) % children.length;
+				child = children[idx];
+			}while(child.disabled && child != current);
+
+			return child; // dijit/_WidgetBase
 		},
 
-		onkeypress: function(/*Event*/ e){
+		onkeydown: function(/*Event*/ e, /*Boolean?*/ fromContainer){
 			// summary:
 			//		Handle keystrokes on the page list, for advancing to next/previous button
 			//		and closing the current page if the page is closable.
 			// tags:
 			//		private
 
-			if(this.disabled || e.altKey ){ return; }
+			if(this.disabled || e.altKey){
+				return;
+			}
 			var forward = null;
 			if(e.ctrlKey || !e._djpage){
-				switch(e.charOrCode){
+				switch(e.keyCode){
 					case keys.LEFT_ARROW:
 					case keys.UP_ARROW:
-						if(!e._djpage){ forward = false; }
+						if(!e._djpage){
+							forward = false;
+						}
 						break;
 					case keys.PAGE_UP:
-						if(e.ctrlKey){ forward = false; }
+						if(e.ctrlKey){
+							forward = false;
+						}
 						break;
 					case keys.RIGHT_ARROW:
 					case keys.DOWN_ARROW:
-						if(!e._djpage){ forward = true; }
+						if(!e._djpage){
+							forward = true;
+						}
 						break;
 					case keys.PAGE_DOWN:
-						if(e.ctrlKey){ forward = true; }
+						if(e.ctrlKey){
+							forward = true;
+						}
 						break;
 					case keys.HOME:
+						// Navigate to first non-disabled child
+						var children = this.getChildren();
+						for(var idx = 0; idx < children.length; idx++){
+							var child = children[idx];
+							if(!child.disabled){
+								this.onButtonClick(child.page);
+								break;
+							}
+						}
+						e.stopPropagation();
+						e.preventDefault();
+						break;
 					case keys.END:
+						// Navigate to last non-disabled child
 						var children = this.getChildren();
-						if(children && children.length){
-							children[e.charOrCode == keys.HOME ? 0 : children.length-1].onClick();
+						for(var idx = children.length - 1; idx >= 0; idx--){
+							var child = children[idx];
+							if(!child.disabled){
+								this.onButtonClick(child.page);
+								break;
+							}
 						}
-						event.stop(e);
+						e.stopPropagation();
+						e.preventDefault();
 						break;
 					case keys.DELETE:
-						if(this._currentChild.closable){
+					case "W".charCodeAt(0):    // ctrl-W
+						if(this._currentChild.closable &&
+							(e.keyCode == keys.DELETE || e.ctrlKey)){
 							this.onCloseButtonClick(this._currentChild);
 						}
-						event.stop(e);
+						// avoid browser tab closing
+						e.stopPropagation();
+						e.preventDefault();
 						break;
-					default:
+					case keys.TAB:
 						if(e.ctrlKey){
-							if(e.charOrCode === keys.TAB){
-								this.adjacent(!e.shiftKey).onClick();
-								event.stop(e);
-							}else if(e.charOrCode == "w"){
-								if(this._currentChild.closable){
-									this.onCloseButtonClick(this._currentChild);
-								}
-								event.stop(e); // avoid browser tab closing.
-							}
+							this.onButtonClick(this.adjacent(!e.shiftKey).page);
+							e.stopPropagation();
+							e.preventDefault();
 						}
+						break;
 				}
 				// handle next/previous page navigation (left/right arrow, etc.)
 				if(forward !== null){
-					this.adjacent(forward).onClick();
-					event.stop(e);
+					this.onButtonClick(this.adjacent(forward).page);
+					e.stopPropagation();
+					e.preventDefault();
 				}
 			}
 		},
 
-		onContainerKeyPress: function(/*Object*/ info){
+		onContainerKeyDown: function(/*Object*/ info){
 			// summary:
-			//		Called when there was a keypress on the container
+			//		Called when there was a keydown on the container
 			// tags:
 			//		private
 			info.e._djpage = info.page;
-			this.onkeypress(info.e);
+			this.onkeydown(info.e);
 		}
 	});
 
diff --git a/dijit/layout/TabContainer.js b/dijit/layout/TabContainer.js
index a04b59b..ca1017a 100644
--- a/dijit/layout/TabContainer.js
+++ b/dijit/layout/TabContainer.js
@@ -6,16 +6,8 @@ define([
 	"./ScrollingTabController"
 ], function(lang, declare, _TabContainerBase, TabController, ScrollingTabController){
 
-/*=====
-	var _TabContainerBase = dijit.layout._TabContainerBase;
-	var TabController = dijit.layout.TabController;
-	var ScrollingTabController = dijit.layout.ScrollingTabController;
-=====*/
-
 	// module:
 	//		dijit/layout/TabContainer
-	// summary:
-	//		A Container with tabs to select each child (only one of which is displayed at a time).
 
 
 	return declare("dijit.layout.TabContainer", _TabContainerBase, {
@@ -25,6 +17,9 @@ define([
 		//		A TabContainer is a container that has multiple panes, but shows only
 		//		one pane at a time.  There are a set of tabs corresponding to each pane,
 		//		where each tab has the name (aka title) of the pane, and optionally a close button.
+		//
+		//		See `StackContainer.ChildWidgetProperties` for details on the properties that can be set on
+		//		children of a `TabContainer`.
 
 		// useMenu: [const] Boolean
 		//		True if a menu should be used to select tabs when they are too
@@ -36,7 +31,7 @@ define([
 		//		wide to fit the TabContainer, false otherwise.
 		useSlider: true,
 
-		// controllerWidget: String
+		// controllerWidget: Class
 		//		An optional parameter to override the widget used to display the tab labels
 		controllerWidget: "",
 
@@ -47,11 +42,14 @@ define([
 			// tags:
 			//		protected extension
 
+			// "string" branch for back-compat, remove for 2.0
 			var cls = this.baseClass + "-tabs" + (this.doLayout ? "" : " dijitTabNoLayout"),
-				TabController = lang.getObject(this.controllerWidget);
+				TabController = typeof this.controllerWidget == "string" ? lang.getObject(this.controllerWidget) :
+						this.controllerWidget;
 
 			return new TabController({
 				id: this.id + "_tablist",
+				ownerDocument: this.ownerDocument,
 				dir: this.dir,
 				lang: this.lang,
 				textDir: this.textDir,
@@ -72,7 +70,7 @@ define([
 			// Scrolling controller only works for horizontal non-nested tabs
 			if(!this.controllerWidget){
 				this.controllerWidget = (this.tabPosition == "top" || this.tabPosition == "bottom") && !this.nested ?
-							"dijit.layout.ScrollingTabController" : "dijit.layout.TabController";
+							ScrollingTabController : TabController;
 			}
 		}
 	});
diff --git a/dijit/layout/TabController.js b/dijit/layout/TabController.js
index 6ec46d9..721b73e 100644
--- a/dijit/layout/TabController.js
+++ b/dijit/layout/TabController.js
@@ -3,28 +3,21 @@ define([
 	"dojo/dom", // dom.setSelectable
 	"dojo/dom-attr", // domAttr.attr
 	"dojo/dom-class", // domClass.toggle
+	"dojo/has",
 	"dojo/i18n", // i18n.getLocalization
 	"dojo/_base/lang", // lang.hitch lang.trim
 	"./StackController",
+	"../registry",
 	"../Menu",
 	"../MenuItem",
 	"dojo/text!./templates/_TabButton.html",
 	"dojo/i18n!../nls/common"
-], function(declare, dom, domAttr, domClass, i18n, lang, StackController, Menu, MenuItem, template){
-
-/*=====
-	var StackController = dijit.layout.StackController;
-	var Menu = dijit.Menu;
-	var MenuItem = dijit.MenuItem;
-=====*/
+], function(declare, dom, domAttr, domClass, has, i18n, lang, StackController, registry, Menu, MenuItem, template){
 
 	// module:
 	//		dijit/layout/TabController
-	// summary:
-	// 		Set of tabs (the things with titles and a close button, that you click to show a tab panel).
-	//		Used internally by `dijit.layout.TabContainer`.
 
-	var TabButton = declare("dijit.layout._TabButton", StackController.StackButton, {
+	var TabButton = declare("dijit.layout._TabButton" + (has("dojo-bidi") ? "_NoBidi" : ""), StackController.StackButton, {
 		// summary:
 		//		A tab (the thing you click to select a pane).
 		// description:
@@ -44,6 +37,9 @@ define([
 
 		templateString: template,
 
+		// Button superclass maps name to a this.valueNode, but we don't have a this.valueNode attach point
+		_setNameAttr: "focusNode",
+
 		// Override _FormWidget.scrollOnFocus.
 		// Don't scroll the whole tab container into view when the button is focused.
 		scrollOnFocus: false,
@@ -60,7 +56,7 @@ define([
 
 			// Required to give IE6 a kick, as it initially hides the
 			// tabs until they are focused on.
-			setTimeout(function(){
+			this.defer(function(){
 				n.className = n.className;
 			}, 1);
 		},
@@ -69,36 +65,33 @@ define([
 			// summary:
 			//		Hide/show close button
 			this._set("closeButton", disp);
-			domClass.toggle(this.innerDiv, "dijitClosable", disp);
+			domClass.toggle(this.domNode, "dijitClosable", disp);
 			this.closeNode.style.display = disp ? "" : "none";
 			if(disp){
 				var _nlsResources = i18n.getLocalization("dijit", "common");
 				if(this.closeNode){
-					domAttr.set(this.closeNode,"title", _nlsResources.itemClose);
+					domAttr.set(this.closeNode, "title", _nlsResources.itemClose);
 				}
-				// add context menu onto title button
-				this._closeMenu = new Menu({
-					id: this.id+"_Menu",
-					dir: this.dir,
-					lang: this.lang,
-					textDir: this.textDir,
-					targetNodeIds: [this.domNode]
-				});
-
-				this._closeMenu.addChild(new MenuItem({
-					label: _nlsResources.itemClose,
-					dir: this.dir,
-					lang: this.lang,
-					textDir: this.textDir,
-					onClick: lang.hitch(this, "onClickCloseButton")
-				}));
-			}else{
-				if(this._closeMenu){
-					this._closeMenu.destroyRecursive();
-					delete this._closeMenu;
+			}
+		},
+
+		_setDisabledAttr: function(/*Boolean*/ disabled){
+			// summary:
+			//		Make tab selected/unselectable
+
+			this.inherited(arguments);
+
+			// Don't show tooltip for close button when tab is disabled
+			if(this.closeNode){
+				if(disabled){
+					domAttr.remove(this.closeNode, "title");
+				}else{
+					var _nlsResources = i18n.getLocalization("dijit", "common");
+					domAttr.set(this.closeNode, "title", _nlsResources.itemClose);
 				}
 			}
 		},
+
 		_setLabelAttr: function(/*String*/ content){
 			// summary:
 			//		Hook for set('label', ...) to work.
@@ -110,21 +103,22 @@ define([
 			if(!this.showLabel && !this.params.title){
 				this.iconNode.alt = lang.trim(this.containerNode.innerText || this.containerNode.textContent || '');
 			}
-		},
-
-		destroy: function(){
-			if(this._closeMenu){
-				this._closeMenu.destroyRecursive();
-				delete this._closeMenu;
-			}
-			this.inherited(arguments);
 		}
 	});
 
+	if(has("dojo-bidi")){
+		TabButton = declare("dijit.layout._TabButton", TabButton, {
+			_setLabelAttr: function(/*String*/ content){
+				this.inherited(arguments);
+				this.applyTextDir(this.iconNode, this.iconNode.alt);
+			}
+		});
+	}
+
 	var TabController = declare("dijit.layout.TabController", StackController, {
 		// summary:
-		// 		Set of tabs (the things with titles and a close button, that you click to show a tab panel).
-		//		Used internally by `dijit.layout.TabContainer`.
+		//		Set of tabs (the things with titles and a close button, that you click to show a tab panel).
+		//		Used internally by `dijit/layout/TabContainer`.
 		// description:
 		//		Lets the user select the currently shown pane in a TabContainer or StackContainer.
 		//		TabController also monitors the TabContainer, and whenever a pane is
@@ -134,7 +128,7 @@ define([
 
 		baseClass: "dijitTabController",
 
-		templateString: "<div role='tablist' data-dojo-attach-event='onkeypress:onkeypress'></div>",
+		templateString: "<div role='tablist' data-dojo-attach-event='onkeydown:onkeydown'></div>",
 
 		// tabPosition: String
 		//		Defines where tabs go relative to the content.
@@ -145,22 +139,40 @@ define([
 		//		The tab widget to create to correspond to each page
 		buttonWidget: TabButton,
 
-		_rectifyRtlTabList: function(){
-			// summary:
-			//		For left/right TabContainer when page is RTL mode, rectify the width of all tabs to be equal, otherwise the tab widths are different in IE
+		// buttonWidgetCloseClass: String
+		//		Class of [x] close icon, used by event delegation code to tell when close button was clicked
+		buttonWidgetCloseClass: "dijitTabCloseButton",
 
-			if(0 >= this.tabPosition.indexOf('-h')){ return; }
-			if(!this.pane2button){ return; }
+		postCreate: function(){
+			this.inherited(arguments);
 
-			var maxWidth = 0;
-			for(var pane in this.pane2button){
-				var ow = this.pane2button[pane].innerDiv.scrollWidth;
-				maxWidth = Math.max(maxWidth, ow);
-			}
-			//unify the length of all the tabs
-			for(pane in this.pane2button){
-				this.pane2button[pane].innerDiv.style.width = maxWidth + 'px';
-			}
+			// Setup a close menu to be shared between all the closable tabs (excluding disabled tabs)
+			var closeMenu = new Menu({
+				id: this.id + "_Menu",
+				ownerDocument: this.ownerDocument,
+				dir: this.dir,
+				lang: this.lang,
+				textDir: this.textDir,
+				targetNodeIds: [this.domNode],
+				selector: function(node){
+					return domClass.contains(node, "dijitClosable") && !domClass.contains(node, "dijitTabDisabled");
+				}
+			});
+			this.own(closeMenu);
+
+			var _nlsResources = i18n.getLocalization("dijit", "common"),
+				controller = this;
+			closeMenu.addChild(new MenuItem({
+				label: _nlsResources.itemClose,
+				ownerDocument: this.ownerDocument,
+				dir: this.dir,
+				lang: this.lang,
+				textDir: this.textDir,
+				onClick: function(evt){
+					var button = registry.byNode(this.getParent().currentTarget);
+					controller.onCloseButtonClick(button.page);
+				}
+			}));
 		}
 	});
 
diff --git a/dijit/layout/_ContentPaneResizeMixin.js b/dijit/layout/_ContentPaneResizeMixin.js
index aa348cb..4dea6de 100644
--- a/dijit/layout/_ContentPaneResizeMixin.js
+++ b/dijit/layout/_ContentPaneResizeMixin.js
@@ -1,255 +1,237 @@
 define([
 	"dojo/_base/array", // array.filter array.forEach
 	"dojo/_base/declare", // declare
-	"dojo/dom-attr",	// domAttr.has
-	"dojo/dom-class",	// domClass.contains domClass.toggle
-	"dojo/dom-geometry",// domGeometry.contentBox domGeometry.marginBox
+	"dojo/dom-class", // domClass.contains domClass.toggle
+	"dojo/dom-geometry", // domGeometry.contentBox domGeometry.marginBox
+	"dojo/dom-style",
 	"dojo/_base/lang", // lang.mixin
 	"dojo/query", // query
-	"dojo/_base/sniff", // has("ie")
-	"dojo/_base/window", // win.global
-	"../registry",	// registry.byId
-	"./utils",	// marginBox2contextBox
-	"../_Contained"
-], function(array, declare, domAttr, domClass, domGeometry, lang, query, has, win,
-			registry, layoutUtils, _Contained){
-
-/*=====
-var _Contained = dijit._Contained;
-=====*/
-
-// module:
-//		dijit/layout/_ContentPaneResizeMixin
-// summary:
-//		Resize() functionality of ContentPane.   If there's a single layout widget
-//		child then it will call resize() with the same dimensions as the ContentPane.
-//		Otherwise just calls resize on each child.
-
-
-return declare("dijit.layout._ContentPaneResizeMixin", null, {
-	// summary:
-	//		Resize() functionality of ContentPane.   If there's a single layout widget
-	//		child then it will call resize() with the same dimensions as the ContentPane.
-	//		Otherwise just calls resize on each child.
-	//
-	//		Also implements basic startup() functionality, where starting the parent
-	//		will start the children
-
-	// doLayout: Boolean
-	//		- false - don't adjust size of children
-	//		- true - if there is a single visible child widget, set it's size to
-	//				however big the ContentPane is
-	doLayout: true,
-
-	// isLayoutContainer: [protected] Boolean
-	//		Indicates that this widget will call resize() on it's child widgets
-	//		when they become visible.
-	isLayoutContainer: true,
-
-	startup: function(){
-		// summary:
-		//		See `dijit.layout._LayoutWidget.startup` for description.
-		//		Although ContentPane doesn't extend _LayoutWidget, it does implement
-		//		the same API.
-
-		if(this._started){ return; }
-
-		var parent = this.getParent();
-		this._childOfLayoutWidget = parent && parent.isLayoutContainer;
-
-		// I need to call resize() on my child/children (when I become visible), unless
-		// I'm the child of a layout widget in which case my parent will call resize() on me and I'll do it then.
-		this._needLayout = !this._childOfLayoutWidget;
+	"dojo/sniff", // has("ie")
+	"../registry", // registry.byId
+	"../Viewport",
+	"./utils" // marginBox2contextBox
+], function(array, declare, domClass, domGeometry, domStyle, lang, query, has,
+			registry, Viewport, layoutUtils){
 
-		this.inherited(arguments);
+	// module:
+	//		dijit/layout/_ContentPaneResizeMixin
 
-		if(this._isShown()){
-			this._onShow();
-		}
-
-		if(!this._childOfLayoutWidget){
-			// If my parent isn't a layout container, since my style *may be* width=height=100%
-			// or something similar (either set directly or via a CSS class),
-			// monitor when my size changes so that I can re-layout.
-			// For browsers where I can't directly monitor when my size changes,
-			// monitor when the viewport changes size, which *may* indicate a size change for me.
-			this.connect(has("ie") ? this.domNode : win.global, 'onresize', function(){
-				// Using function(){} closure to ensure no arguments to resize.
-				this._needLayout = !this._childOfLayoutWidget;
-				this.resize();
-			});
-		}
-	},
-
-	_checkIfSingleChild: function(){
+	return declare("dijit.layout._ContentPaneResizeMixin", null, {
 		// summary:
-		//		Test if we have exactly one visible widget as a child,
-		//		and if so assume that we are a container for that widget,
-		//		and should propagate startup() and resize() calls to it.
-		//		Skips over things like data stores since they aren't visible.
-
-		var childNodes = query("> *", this.containerNode).filter(function(node){
-				return node.tagName !== "SCRIPT"; // or a regexp for hidden elements like script|area|map|etc..
-			}),
-			childWidgetNodes = childNodes.filter(function(node){
-				return domAttr.has(node, "data-dojo-type") || domAttr.has(node, "dojoType") || domAttr.has(node, "widgetId");
-			}),
-			candidateWidgets = array.filter(childWidgetNodes.map(registry.byNode), function(widget){
-				return widget && widget.domNode && widget.resize;
-			});
-
-		if(
-			// all child nodes are widgets
-			childNodes.length == childWidgetNodes.length &&
-
-			// all but one are invisible (like dojo.data)
-			candidateWidgets.length == 1
-		){
-			this._singleChild = candidateWidgets[0];
-		}else{
-			delete this._singleChild;
-		}
-
-		// So we can set overflow: hidden to avoid a safari bug w/scrollbars showing up (#9449)
-		domClass.toggle(this.containerNode, this.baseClass + "SingleChild", !!this._singleChild);
-	},
+		//		Resize() functionality of ContentPane.   If there's a single layout widget
+		//		child then it will call resize() with the same dimensions as the ContentPane.
+		//		Otherwise just calls resize on each child.
+		//
+		//		Also implements basic startup() functionality, where starting the parent
+		//		will start the children
+
+		// doLayout: Boolean
+		//		- false - don't adjust size of children
+		//		- true - if there is a single visible child widget, set it's size to however big the ContentPane is
+		doLayout: true,
+
+		// isLayoutContainer: [protected] Boolean
+		//		Indicates that this widget will call resize() on it's child widgets
+		//		when they become visible.
+		isLayoutContainer: true,
+
+		startup: function(){
+			// summary:
+			//		See `dijit/layout/_LayoutWidget.startup()` for description.
+			//		Although ContentPane doesn't extend _LayoutWidget, it does implement
+			//		the same API.
+
+			if(this._started){
+				return;
+			}
 
-	resize: function(changeSize, resultSize){
-		// summary:
-		//		See `dijit.layout._LayoutWidget.resize` for description.
-		//		Although ContentPane doesn't extend _LayoutWidget, it does implement
-		//		the same API.
-
-		// For the TabContainer --> BorderContainer --> ContentPane case, _onShow() is
-		// never called, so resize() is our trigger to do the initial href download (see [20099]).
-		// However, don't load href for closed TitlePanes.
-		if(!this._wasShown && this.open !== false){
-			this._onShow();
-		}
+			var parent = this.getParent();
+			this._childOfLayoutWidget = parent && parent.isLayoutContainer;
 
-		this._resizeCalled = true;
+			// I need to call resize() on my child/children (when I become visible), unless
+			// I'm the child of a layout widget in which case my parent will call resize() on me and I'll do it then.
+			this._needLayout = !this._childOfLayoutWidget;
 
-		this._scheduleLayout(changeSize, resultSize);
-	},
+			this.inherited(arguments);
 
-	_scheduleLayout: function(changeSize, resultSize){
-		// summary:
-		//		Resize myself, and call resize() on each of my child layout widgets, either now
-		//		(if I'm currently visible) or when I become visible
-		if(this._isShown()){
-			this._layout(changeSize, resultSize);
-		}else{
-			this._needLayout = true;
-			this._changeSize = changeSize;
-			this._resultSize = resultSize;
-		}
-	},
+			if(this._isShown()){
+				this._onShow();
+			}
 
-	_layout: function(changeSize, resultSize){
-		// summary:
-		//		Resize myself according to optional changeSize/resultSize parameters, like a layout widget.
-		//		Also, since I am a Container widget, each of my children expects me to
-		//		call resize() or layout() on them.
-		//
-		//		Should be called on initialization and also whenever we get new content
-		//		(from an href, or from set('content', ...))... but deferred until
-		//		the ContentPane is visible
+			if(!this._childOfLayoutWidget){
+				// Since my parent isn't a layout container, and my style *may be* width=height=100%
+				// or something similar (either set directly or via a CSS class),
+				// monitor when viewport size changes so that I can re-layout.
+				// This is more for subclasses of ContentPane than ContentPane itself, although it
+				// could be useful for a ContentPane if it has a single child widget inheriting ContentPane's size.
+				this.own(Viewport.on("resize", lang.hitch(this, "resize")));
+			}
+		},
+
+		_checkIfSingleChild: function(){
+			// summary:
+			//		Test if we have exactly one visible widget as a child,
+			//		and if so assume that we are a container for that widget,
+			//		and should propagate startup() and resize() calls to it.
+			//		Skips over things like data stores since they aren't visible.
+
+			var candidateWidgets = [],
+				otherVisibleNodes = false;
+
+			query("> *", this.containerNode).some(function(node){
+				var widget = registry.byNode(node);
+				if(widget && widget.resize){
+					candidateWidgets.push(widget);
+				}else if(!/script|link|style/i.test(node.nodeName) && node.offsetHeight){
+					otherVisibleNodes = true;
+				}
+			});
 
-		// Set margin box size, unless it wasn't specified, in which case use current size.
-		if(changeSize){
-			domGeometry.setMarginBox(this.domNode, changeSize);
-		}
+			this._singleChild = candidateWidgets.length == 1 && !otherVisibleNodes ?
+				candidateWidgets[0] : null;
+
+			// So we can set overflow: hidden to avoid a safari bug w/scrollbars showing up (#9449)
+			domClass.toggle(this.containerNode, this.baseClass + "SingleChild", !!this._singleChild);
+		},
+
+		resize: function(changeSize, resultSize){
+			// summary:
+			//		See `dijit/layout/_LayoutWidget.resize()` for description.
+			//		Although ContentPane doesn't extend _LayoutWidget, it does implement
+			//		the same API.
+
+			this._resizeCalled = true;
+
+			this._scheduleLayout(changeSize, resultSize);
+		},
+
+		_scheduleLayout: function(changeSize, resultSize){
+			// summary:
+			//		Resize myself, and call resize() on each of my child layout widgets, either now
+			//		(if I'm currently visible) or when I become visible
+			if(this._isShown()){
+				this._layout(changeSize, resultSize);
+			}else{
+				this._needLayout = true;
+				this._changeSize = changeSize;
+				this._resultSize = resultSize;
+			}
+		},
+
+		_layout: function(changeSize, resultSize){
+			// summary:
+			//		Resize myself according to optional changeSize/resultSize parameters, like a layout widget.
+			//		Also, since I am an isLayoutContainer widget, each of my children expects me to
+			//		call resize() or layout() on it.
+			//
+			//		Should be called on initialization and also whenever we get new content
+			//		(from an href, or from set('content', ...))... but deferred until
+			//		the ContentPane is visible
+
+			delete this._needLayout;
+
+			// For the TabContainer --> BorderContainer --> ContentPane case, _onShow() is
+			// never called directly, so resize() is our trigger to do the initial href download (see [20099]).
+			// However, don't load href for closed TitlePanes.
+			if(!this._wasShown && this.open !== false){
+				this._onShow();
+			}
 
-		// Compute content box size of containerNode in case we [later] need to size our single child.
-		var cn = this.containerNode;
-		if(cn === this.domNode){
-			// If changeSize or resultSize was passed to this method and this.containerNode ==
-			// this.domNode then we can compute the content-box size without querying the node,
-			// which is more reliable (similar to LayoutWidget.resize) (see for example #9449).
-			var mb = resultSize || {};
-			lang.mixin(mb, changeSize || {}); // changeSize overrides resultSize
-			if(!("h" in mb) || !("w" in mb)){
-				mb = lang.mixin(domGeometry.getMarginBox(cn), mb); // just use domGeometry.setMarginBox() to fill in missing values
+			// Set margin box size, unless it wasn't specified, in which case use current size.
+			if(changeSize){
+				domGeometry.setMarginBox(this.domNode, changeSize);
 			}
-			this._contentBox = layoutUtils.marginBox2contentBox(cn, mb);
-		}else{
-			this._contentBox = domGeometry.getContentBox(cn);
-		}
 
-		this._layoutChildren();
+			// Compute content box size of containerNode in case we [later] need to size our single child.
+			var cn = this.containerNode;
+			if(cn === this.domNode){
+				// If changeSize or resultSize was passed to this method and this.containerNode ==
+				// this.domNode then we can compute the content-box size without querying the node,
+				// which is more reliable (similar to LayoutWidget.resize) (see for example #9449).
+				var mb = resultSize || {};
+				lang.mixin(mb, changeSize || {}); // changeSize overrides resultSize
+				if(!("h" in mb) || !("w" in mb)){
+					mb = lang.mixin(domGeometry.getMarginBox(cn), mb); // just use domGeometry.setMarginBox() to fill in missing values
+				}
+				this._contentBox = layoutUtils.marginBox2contentBox(cn, mb);
+			}else{
+				this._contentBox = domGeometry.getContentBox(cn);
+			}
 
-		delete this._needLayout;
-	},
+			this._layoutChildren();
+		},
 
-	_layoutChildren: function(){
-		// Call _checkIfSingleChild() again in case app has manually mucked w/the content
-		// of the ContentPane (rather than changing it through the set("content", ...) API.
-		if(this.doLayout){
-			this._checkIfSingleChild();
-		}
+		_layoutChildren: function(){
+			// Call _checkIfSingleChild() again in case app has manually mucked w/the content
+			// of the ContentPane (rather than changing it through the set("content", ...) API.
+			if(this.doLayout){
+				this._checkIfSingleChild();
+			}
 
-		if(this._singleChild && this._singleChild.resize){
-			var cb = this._contentBox || domGeometry.getContentBox(this.containerNode);
-
-			// note: if widget has padding this._contentBox will have l and t set,
-			// but don't pass them to resize() or it will doubly-offset the child
-			this._singleChild.resize({w: cb.w, h: cb.h});
-		}else{
-			// All my child widgets are independently sized (rather than matching my size),
-			// but I still need to call resize() on each child to make it layout.
-			array.forEach(this.getChildren(), function(widget){
-				if(widget.resize){
-					widget.resize();
+			if(this._singleChild && this._singleChild.resize){
+				var cb = this._contentBox || domGeometry.getContentBox(this.containerNode);
+
+				// note: if widget has padding this._contentBox will have l and t set,
+				// but don't pass them to resize() or it will doubly-offset the child
+				this._singleChild.resize({w: cb.w, h: cb.h});
+			}else{
+				// All my child widgets are independently sized (rather than matching my size),
+				// but I still need to call resize() on each child to make it layout.
+				var children = this.getChildren(),
+					widget,
+					i = 0;
+				while(widget = children[i++]){
+					if(widget.resize){
+						widget.resize();
+					}
 				}
-			});
-		}
-	},
-
-	_isShown: function(){
-		// summary:
-		//		Returns true if the content is currently shown.
-		// description:
-		//		If I am a child of a layout widget then it actually returns true if I've ever been visible,
-		//		not whether I'm currently visible, since that's much faster than tracing up the DOM/widget
-		//		tree every call, and at least solves the performance problem on page load by deferring loading
-		//		hidden ContentPanes until they are first shown
-
-		if(this._childOfLayoutWidget){
-			// If we are TitlePane, etc - we return that only *IF* we've been resized
-			if(this._resizeCalled && "open" in this){
-				return this.open;
 			}
-			return this._resizeCalled;
-		}else if("open" in this){
-			return this.open;		// for TitlePane, etc.
-		}else{
-			var node = this.domNode, parent = this.domNode.parentNode;
-			return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !domClass.contains(node, "dijitHidden") &&
+		},
+
+		_isShown: function(){
+			// summary:
+			//		Returns true if the content is currently shown.
+			// description:
+			//		If I am a child of a layout widget then it actually returns true if I've ever been visible,
+			//		not whether I'm currently visible, since that's much faster than tracing up the DOM/widget
+			//		tree every call, and at least solves the performance problem on page load by deferring loading
+			//		hidden ContentPanes until they are first shown
+
+			if(this._childOfLayoutWidget){
+				// If we are TitlePane, etc - we return that only *IF* we've been resized
+				if(this._resizeCalled && "open" in this){
+					return this.open;
+				}
+				return this._resizeCalled;
+			}else if("open" in this){
+				return this.open;		// for TitlePane, etc.
+			}else{
+				var node = this.domNode, parent = this.domNode.parentNode;
+				return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !domClass.contains(node, "dijitHidden") &&
 					parent && parent.style && (parent.style.display != 'none');
-		}
-	},
-
-	_onShow: function(){
-		// summary:
-		//		Called when the ContentPane is made visible
-		// description:
-		//		For a plain ContentPane, this is called on initialization, from startup().
-		//		If the ContentPane is a hidden pane of a TabContainer etc., then it's
-		//		called whenever the pane is made visible.
-		//
-		//		Does layout/resize of child widget(s)
+			}
+		},
+
+		_onShow: function(){
+			// summary:
+			//		Called when the ContentPane is made visible
+			// description:
+			//		For a plain ContentPane, this is called on initialization, from startup().
+			//		If the ContentPane is a hidden pane of a TabContainer etc., then it's
+			//		called whenever the pane is made visible.
+			//
+			//		Does layout/resize of child widget(s)
+
+			// Need to keep track of whether ContentPane has been shown (which is different than
+			// whether or not it's currently visible).
+			this._wasShown = true;
+
+			if(this._needLayout){
+				// If a layout has been scheduled for when we become visible, do it now
+				this._layout(this._changeSize, this._resultSize);
+			}
 
-		if(this._needLayout){
-			// If a layout has been scheduled for when we become visible, do it now
-			this._layout(this._changeSize, this._resultSize);
+			this.inherited(arguments);
 		}
-
-		this.inherited(arguments);
-
-		// Need to keep track of whether ContentPane has been shown (which is different than
-		// whether or not it's currently visible).
-		this._wasShown = true;
-	}
-});
-
+	});
 });
diff --git a/dijit/layout/_LayoutWidget.js b/dijit/layout/_LayoutWidget.js
index 76324b4..62017db 100644
--- a/dijit/layout/_LayoutWidget.js
+++ b/dijit/layout/_LayoutWidget.js
@@ -3,26 +3,16 @@ define([
 	"../_Widget",
 	"../_Container",
 	"../_Contained",
+	"../Viewport",
 	"dojo/_base/declare", // declare
 	"dojo/dom-class", // domClass.add domClass.remove
 	"dojo/dom-geometry", // domGeometry.marginBox
-	"dojo/dom-style", // domStyle.getComputedStyle
-	"dojo/_base/sniff", // has("ie")
-	"dojo/_base/window" // win.global
-], function(lang, _Widget, _Container, _Contained,
-	declare, domClass, domGeometry, domStyle, has, win){
-
-/*=====
-	var _Widget = dijit._Widget;
-	var _Container = dijit._Container;
-	var _Contained = dijit._Contained;
-=====*/
+	"dojo/dom-style" // domStyle.getComputedStyle
+], function(lang, _Widget, _Container, _Contained, Viewport,
+	declare, domClass, domGeometry, domStyle){
 
 	// module:
 	//		dijit/layout/_LayoutWidget
-	// summary:
-	//		_LayoutWidget Base class for a _Container widget which is responsible for laying out its children.
-	//		Widgets which mixin this code must define layout() to manage placement and sizing of the children.
 
 
 	return declare("dijit.layout._LayoutWidget", [_Widget, _Container, _Contained], {
@@ -49,7 +39,7 @@ define([
 		startup: function(){
 			// summary:
 			//		Called after all the widgets have been instantiated and their
-			//		dom nodes have been inserted somewhere under win.doc.body.
+			//		dom nodes have been inserted somewhere under <body>.
 			//
 			//		Widgets should override this method to do any initialization
 			//		dependent on other widgets existing, and then call
@@ -74,10 +64,7 @@ define([
 				// Since my parent isn't a layout container, and my style *may be* width=height=100%
 				// or something similar (either set directly or via a CSS class),
 				// monitor when viewport size changes so that I can re-layout.
-				this.connect(win.global, 'onresize', function(){
-					// Using function(){} closure to ensure no arguments passed to resize().
-					this.resize();
-				});
+				this.own(Viewport.on("resize", lang.hitch(this, "resize")));
 			}
 		},
 
@@ -85,32 +72,33 @@ define([
 			// summary:
 			//		Call this to resize a widget, or after its size has changed.
 			// description:
-			//		Change size mode:
-			//			When changeSize is specified, changes the marginBox of this widget
-			//			and forces it to relayout its contents accordingly.
-			//			changeSize may specify height, width, or both.
+			//		####Change size mode:
 			//
-			//			If resultSize is specified it indicates the size the widget will
-			//			become after changeSize has been applied.
+			//		When changeSize is specified, changes the marginBox of this widget
+			//		and forces it to re-layout its contents accordingly.
+			//		changeSize may specify height, width, or both.
 			//
-			//		Notification mode:
-			//			When changeSize is null, indicates that the caller has already changed
-			//			the size of the widget, or perhaps it changed because the browser
-			//			window was resized.  Tells widget to relayout its contents accordingly.
+			//		If resultSize is specified it indicates the size the widget will
+			//		become after changeSize has been applied.
 			//
-			//			If resultSize is also specified it indicates the size the widget has
-			//			become.
+			//		####Notification mode:
+			//
+			//		When changeSize is null, indicates that the caller has already changed
+			//		the size of the widget, or perhaps it changed because the browser
+			//		window was resized.  Tells widget to re-layout its contents accordingly.
+			//
+			//		If resultSize is also specified it indicates the size the widget has
+			//		become.
 			//
 			//		In either mode, this method also:
-			//			1. Sets this._borderBox and this._contentBox to the new size of
-			//				the widget.  Queries the current domNode size if necessary.
-			//			2. Calls layout() to resize contents (and maybe adjust child widgets).
 			//
+			//		1. Sets this._borderBox and this._contentBox to the new size of
+			//			the widget.  Queries the current domNode size if necessary.
+			//		2. Calls layout() to resize contents (and maybe adjust child widgets).
 			// changeSize: Object?
 			//		Sets the widget to this margin-box size and position.
 			//		May include any/all of the following properties:
 			//	|	{w: int, h: int, l: int, t: int}
-			//
 			// resultSize: Object?
 			//		The margin-box size of this widget after applying changeSize (if
 			//		changeSize is specified).  If caller knows this size and
@@ -165,7 +153,7 @@ define([
 			//		protected extension
 		},
 
-		_setupChild: function(/*dijit._Widget*/child){
+		_setupChild: function(/*dijit/_WidgetBase*/child){
 			// summary:
 			//		Common setup for initial children and children which are added after startup
 			// tags:
@@ -176,7 +164,7 @@ define([
 			domClass.add(child.domNode, cls);
 		},
 
-		addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
+		addChild: function(/*dijit/_WidgetBase*/ child, /*Integer?*/ insertIndex){
 			// Overrides _Container.addChild() to call _setupChild()
 			this.inherited(arguments);
 			if(this._started){
@@ -184,7 +172,7 @@ define([
 			}
 		},
 
-		removeChild: function(/*dijit._Widget*/ child){
+		removeChild: function(/*dijit/_WidgetBase*/ child){
 			// Overrides _Container.removeChild() to remove class added by _setupChild()
 			var cls = this.baseClass + "-child"
 					+ (child.baseClass ?
diff --git a/dijit/layout/_TabContainerBase.js b/dijit/layout/_TabContainerBase.js
index 5796d74..8cb0c8a 100644
--- a/dijit/layout/_TabContainerBase.js
+++ b/dijit/layout/_TabContainerBase.js
@@ -1,7 +1,7 @@
 define([
 	"dojo/text!./templates/TabContainer.html",
 	"./StackContainer",
-	"./utils",	// marginBox2contextBox, layoutChildren
+	"./utils", // marginBox2contextBox, layoutChildren
 	"../_TemplatedMixin",
 	"dojo/_base/declare", // declare
 	"dojo/dom-class", // domClass.add
@@ -9,145 +9,140 @@ define([
 	"dojo/dom-style" // domStyle.style
 ], function(template, StackContainer, layoutUtils, _TemplatedMixin, declare, domClass, domGeometry, domStyle){
 
+	// module:
+	//		dijit/layout/_TabContainerBase
 
-/*=====
-	var StackContainer = dijit.layout.StackContainer;
-	var _TemplatedMixin = dijit._TemplatedMixin;
-=====*/
+	return declare("dijit.layout._TabContainerBase", [StackContainer, _TemplatedMixin], {
+		// summary:
+		//		Abstract base class for TabContainer.   Must define _makeController() to instantiate
+		//		and return the widget that displays the tab labels
+		// description:
+		//		A TabContainer is a container that has multiple panes, but shows only
+		//		one pane at a time.  There are a set of tabs corresponding to each pane,
+		//		where each tab has the name (aka title) of the pane, and optionally a close button.
 
-// module:
-//		dijit/layout/_TabContainerBase
-// summary:
-//		Abstract base class for TabContainer.   Must define _makeController() to instantiate
-//		and return the widget that displays the tab labels
+		// tabPosition: String
+		//		Defines where tabs go relative to tab content.
+		//		"top", "bottom", "left-h", "right-h"
+		tabPosition: "top",
 
+		baseClass: "dijitTabContainer",
 
-return declare("dijit.layout._TabContainerBase", [StackContainer, _TemplatedMixin], {
-	// summary:
-	//		Abstract base class for TabContainer.   Must define _makeController() to instantiate
-	//		and return the widget that displays the tab labels
-	// description:
-	//		A TabContainer is a container that has multiple panes, but shows only
-	//		one pane at a time.  There are a set of tabs corresponding to each pane,
-	//		where each tab has the name (aka title) of the pane, and optionally a close button.
+		// tabStrip: [const] Boolean
+		//		Defines whether the tablist gets an extra class for layouting, putting a border/shading
+		//		around the set of tabs.   Not supported by claro theme.
+		tabStrip: false,
 
-	// tabPosition: String
-	//		Defines where tabs go relative to tab content.
-	//		"top", "bottom", "left-h", "right-h"
-	tabPosition: "top",
+		// nested: [const] Boolean
+		//		If true, use styling for a TabContainer nested inside another TabContainer.
+		//		For tundra etc., makes tabs look like links, and hides the outer
+		//		border since the outer TabContainer already has a border.
+		nested: false,
 
-	baseClass: "dijitTabContainer",
+		templateString: template,
 
-	// tabStrip: [const] Boolean
-	//		Defines whether the tablist gets an extra class for layouting, putting a border/shading
-	//		around the set of tabs.   Not supported by claro theme.
-	tabStrip: false,
+		postMixInProperties: function(){
+			// set class name according to tab position, ex: dijitTabContainerTop
+			this.baseClass += this.tabPosition.charAt(0).toUpperCase() + this.tabPosition.substr(1).replace(/-.*/, "");
 
-	// nested: [const] Boolean
-	//		If true, use styling for a TabContainer nested inside another TabContainer.
-	//		For tundra etc., makes tabs look like links, and hides the outer
-	//		border since the outer TabContainer already has a border.
-	nested: false,
+			this.srcNodeRef && domStyle.set(this.srcNodeRef, "visibility", "hidden");
 
-	templateString: template,
+			this.inherited(arguments);
+		},
 
-	postMixInProperties: function(){
-		// set class name according to tab position, ex: dijitTabContainerTop
-		this.baseClass += this.tabPosition.charAt(0).toUpperCase() + this.tabPosition.substr(1).replace(/-.*/, "");
+		buildRendering: function(){
+			this.inherited(arguments);
 
-		this.srcNodeRef && domStyle.set(this.srcNodeRef, "visibility", "hidden");
+			// Create the tab list that will have a tab (a.k.a. tab button) for each tab panel
+			this.tablist = this._makeController(this.tablistNode);
 
-		this.inherited(arguments);
-	},
-
-	buildRendering: function(){
-		this.inherited(arguments);
+			if(!this.doLayout){
+				domClass.add(this.domNode, "dijitTabContainerNoLayout");
+			}
 
-		// Create the tab list that will have a tab (a.k.a. tab button) for each tab panel
-		this.tablist = this._makeController(this.tablistNode);
+			if(this.nested){
+				/* workaround IE's lack of support for "a > b" selectors by
+				 * tagging each node in the template.
+				 */
+				domClass.add(this.domNode, "dijitTabContainerNested");
+				domClass.add(this.tablist.containerNode, "dijitTabContainerTabListNested");
+				domClass.add(this.tablistSpacer, "dijitTabContainerSpacerNested");
+				domClass.add(this.containerNode, "dijitTabPaneWrapperNested");
+			}else{
+				domClass.add(this.domNode, "tabStrip-" + (this.tabStrip ? "enabled" : "disabled"));
+			}
+		},
 
-		if(!this.doLayout){ domClass.add(this.domNode, "dijitTabContainerNoLayout"); }
+		_setupChild: function(/*dijit/_WidgetBase*/ tab){
+			// Overrides StackContainer._setupChild().
+			domClass.add(tab.domNode, "dijitTabPane");
+			this.inherited(arguments);
+		},
 
-		if(this.nested){
-			/* workaround IE's lack of support for "a > b" selectors by
-			 * tagging each node in the template.
-			 */
-			domClass.add(this.domNode, "dijitTabContainerNested");
-			domClass.add(this.tablist.containerNode, "dijitTabContainerTabListNested");
-			domClass.add(this.tablistSpacer, "dijitTabContainerSpacerNested");
-			domClass.add(this.containerNode, "dijitTabPaneWrapperNested");
-		}else{
-			domClass.add(this.domNode, "tabStrip-" + (this.tabStrip ? "enabled" : "disabled"));
-		}
-	},
-
-	_setupChild: function(/*dijit._Widget*/ tab){
-		// Overrides StackContainer._setupChild().
-		domClass.add(tab.domNode, "dijitTabPane");
-		this.inherited(arguments);
-	},
-
-	startup: function(){
-		if(this._started){ return; }
-
-		// wire up the tablist and its tabs
-		this.tablist.startup();
-
-		this.inherited(arguments);
-	},
-
-	layout: function(){
-		// Overrides StackContainer.layout().
-		// Configure the content pane to take up all the space except for where the tabs are
-
-		if(!this._contentBox || typeof(this._contentBox.l) == "undefined"){return;}
-
-		var sc = this.selectedChildWidget;
-
-		if(this.doLayout){
-			// position and size the titles and the container node
-			var titleAlign = this.tabPosition.replace(/-h/, "");
-			this.tablist.layoutAlign = titleAlign;
-			var children = [this.tablist, {
-				domNode: this.tablistSpacer,
-				layoutAlign: titleAlign
-			}, {
-				domNode: this.containerNode,
-				layoutAlign: "client"
-			}];
-			layoutUtils.layoutChildren(this.domNode, this._contentBox, children);
-
-			// Compute size to make each of my children.
-			// children[2] is the margin-box size of this.containerNode, set by layoutChildren() call above
-			this._containerContentBox = layoutUtils.marginBox2contentBox(this.containerNode, children[2]);
-
-			if(sc && sc.resize){
-				sc.resize(this._containerContentBox);
+		startup: function(){
+			if(this._started){
+				return;
 			}
-		}else{
-			// just layout the tab controller, so it can position left/right buttons etc.
-			if(this.tablist.resize){
-				//make the tabs zero width so that they don't interfere with width calc, then reset
-				var s = this.tablist.domNode.style;
-				s.width="0";
-				var width = domGeometry.getContentBox(this.domNode).w;
-				s.width="";
-				this.tablist.resize({w: width});
+
+			// wire up the tablist and its tabs
+			this.tablist.startup();
+
+			this.inherited(arguments);
+		},
+
+		layout: function(){
+			// Overrides StackContainer.layout().
+			// Configure the content pane to take up all the space except for where the tabs are
+
+			if(!this._contentBox || typeof(this._contentBox.l) == "undefined"){
+				return;
 			}
 
-			// and call resize() on the selected pane just to tell it that it's been made visible
-			if(sc && sc.resize){
-				sc.resize();
+			var sc = this.selectedChildWidget;
+
+			if(this.doLayout){
+				// position and size the titles and the container node
+				var titleAlign = this.tabPosition.replace(/-h/, "");
+				this.tablist.region = titleAlign;
+				var children = [this.tablist, {
+					domNode: this.tablistSpacer,
+					region: titleAlign
+				}, {
+					domNode: this.containerNode,
+					region: "center"
+				}];
+				layoutUtils.layoutChildren(this.domNode, this._contentBox, children);
+
+				// Compute size to make each of my children.
+				// children[2] is the margin-box size of this.containerNode, set by layoutChildren() call above
+				this._containerContentBox = layoutUtils.marginBox2contentBox(this.containerNode, children[2]);
+
+				if(sc && sc.resize){
+					sc.resize(this._containerContentBox);
+				}
+			}else{
+				// just layout the tab controller, so it can position left/right buttons etc.
+				if(this.tablist.resize){
+					//make the tabs zero width so that they don't interfere with width calc, then reset
+					var s = this.tablist.domNode.style;
+					s.width = "0";
+					var width = domGeometry.getContentBox(this.domNode).w;
+					s.width = "";
+					this.tablist.resize({w: width});
+				}
+
+				// and call resize() on the selected pane just to tell it that it's been made visible
+				if(sc && sc.resize){
+					sc.resize();
+				}
 			}
-		}
-	},
+		},
 
-	destroy: function(){
-		if(this.tablist){
-			this.tablist.destroy();
+		destroy: function(preserveDom){
+			if(this.tablist){
+				this.tablist.destroy(preserveDom);
+			}
+			this.inherited(arguments);
 		}
-		this.inherited(arguments);
-	}
-});
-
+	});
 });
diff --git a/dijit/layout/templates/AccordionButton.html b/dijit/layout/templates/AccordionButton.html
index d2a9eee..1c110e1 100644
--- a/dijit/layout/templates/AccordionButton.html
+++ b/dijit/layout/templates/AccordionButton.html
@@ -1,10 +1,10 @@
-<div data-dojo-attach-event='onclick:_onTitleClick' class='dijitAccordionTitle' role="presentation">
-	<div data-dojo-attach-point='titleNode,focusNode' data-dojo-attach-event='onkeypress:_onTitleKeyPress'
+<div data-dojo-attach-event='ondijitclick:_onTitleClick' class='dijitAccordionTitle' role="presentation">
+	<div data-dojo-attach-point='titleNode,focusNode' data-dojo-attach-event='onkeydown:_onTitleKeyDown'
 			class='dijitAccordionTitleFocus' role="tab" aria-expanded="false"
 		><span class='dijitInline dijitAccordionArrow' role="presentation"></span
 		><span class='arrowTextUp' role="presentation">+</span
 		><span class='arrowTextDown' role="presentation">-</span
-		><img src="${_blankGif}" alt="" class="dijitIcon" data-dojo-attach-point='iconNode' style="vertical-align: middle" role="presentation"/>
-		<span role="presentation" data-dojo-attach-point='titleTextNode' class='dijitAccordionText'></span>
+		><span role="presentation" class="dijitInline dijitIcon" data-dojo-attach-point="iconNode"></span>
+		<span role="presentation" data-dojo-attach-point='titleTextNode, textDirNode' class='dijitAccordionText'></span>
 	</div>
 </div>
diff --git a/dijit/layout/templates/ScrollingTabController.html b/dijit/layout/templates/ScrollingTabController.html
index 505b92f..f72817d 100644
--- a/dijit/layout/templates/ScrollingTabController.html
+++ b/dijit/layout/templates/ScrollingTabController.html
@@ -1,22 +1,22 @@
 <div class="dijitTabListContainer-${tabPosition}" style="visibility:hidden">
 	<div data-dojo-type="dijit.layout._ScrollingTabControllerMenuButton"
-			class="tabStripButton-${tabPosition}"
-			id="${id}_menuBtn"
-			data-dojo-props="containerId: '${containerId}', iconClass: 'dijitTabStripMenuIcon',
+		 class="tabStripButton-${tabPosition}"
+		 id="${id}_menuBtn"
+		 data-dojo-props="containerId: '${containerId}', iconClass: 'dijitTabStripMenuIcon',
 					dropDownPosition: ['below-alt', 'above-alt']"
-			data-dojo-attach-point="_menuBtn" showLabel="false" title="">▼</div>
+		 data-dojo-attach-point="_menuBtn" showLabel="false" title="">▼</div>
 	<div data-dojo-type="dijit.layout._ScrollingTabControllerButton"
-			class="tabStripButton-${tabPosition}"
-			id="${id}_leftBtn"
-			data-dojo-props="iconClass:'dijitTabStripSlideLeftIcon', showLabel:false, title:''"
-			data-dojo-attach-point="_leftBtn" data-dojo-attach-event="onClick: doSlideLeft">◀</div>
+		 class="tabStripButton-${tabPosition}"
+		 id="${id}_leftBtn"
+		 data-dojo-props="iconClass:'dijitTabStripSlideLeftIcon', showLabel:false, title:''"
+		 data-dojo-attach-point="_leftBtn" data-dojo-attach-event="onClick: doSlideLeft">◀</div>
 	<div data-dojo-type="dijit.layout._ScrollingTabControllerButton"
-			class="tabStripButton-${tabPosition}"
-			id="${id}_rightBtn"
-			data-dojo-props="iconClass:'dijitTabStripSlideRightIcon', showLabel:false, title:''"
-			data-dojo-attach-point="_rightBtn" data-dojo-attach-event="onClick: doSlideRight">▶</div>
+		 class="tabStripButton-${tabPosition}"
+		 id="${id}_rightBtn"
+		 data-dojo-props="iconClass:'dijitTabStripSlideRightIcon', showLabel:false, title:''"
+		 data-dojo-attach-point="_rightBtn" data-dojo-attach-event="onClick: doSlideRight">▶</div>
 	<div class='dijitTabListWrapper' data-dojo-attach-point='tablistWrapper'>
-		<div role='tablist' data-dojo-attach-event='onkeypress:onkeypress'
-				data-dojo-attach-point='containerNode' class='nowrapTabStrip'></div>
+		<div role='tablist' data-dojo-attach-event='onkeydown:onkeydown'
+			 data-dojo-attach-point='containerNode' class='nowrapTabStrip'></div>
 	</div>
 </div>
\ No newline at end of file
diff --git a/dijit/layout/templates/_ScrollingTabControllerButton.html b/dijit/layout/templates/_ScrollingTabControllerButton.html
index c7ef933..e80fa43 100644
--- a/dijit/layout/templates/_ScrollingTabControllerButton.html
+++ b/dijit/layout/templates/_ScrollingTabControllerButton.html
@@ -1,8 +1,4 @@
-<div data-dojo-attach-event="onclick:_onClick">
-	<div role="presentation" class="dijitTabInnerDiv" data-dojo-attach-point="innerDiv,focusNode">
-		<div role="presentation" class="dijitTabContent dijitButtonContents" data-dojo-attach-point="tabContent">
-			<img role="presentation" alt="" src="${_blankGif}" class="dijitTabStripIcon" data-dojo-attach-point="iconNode"/>
-			<span data-dojo-attach-point="containerNode,titleNode" class="dijitButtonText"></span>
-		</div>
-	</div>
+<div data-dojo-attach-event="ondijitclick:_onClick" class="dijitTabInnerDiv dijitTabContent dijitButtonContents"  data-dojo-attach-point="focusNode" role="button">
+	<span role="presentation" class="dijitInline dijitTabStripIcon" data-dojo-attach-point="iconNode"></span>
+	<span data-dojo-attach-point="containerNode,titleNode" class="dijitButtonText"></span>
 </div>
\ No newline at end of file
diff --git a/dijit/layout/templates/_TabButton.html b/dijit/layout/templates/_TabButton.html
index 7d6570e..507b571 100644
--- a/dijit/layout/templates/_TabButton.html
+++ b/dijit/layout/templates/_TabButton.html
@@ -1,14 +1,8 @@
-<div role="presentation" data-dojo-attach-point="titleNode" data-dojo-attach-event='onclick:onClick'>
-    <div role="presentation" class='dijitTabInnerDiv' data-dojo-attach-point='innerDiv'>
-        <div role="presentation" class='dijitTabContent' data-dojo-attach-point='tabContent'>
-        	<div role="presentation" data-dojo-attach-point='focusNode'>
-		        <img src="${_blankGif}" alt="" class="dijitIcon dijitTabButtonIcon" data-dojo-attach-point='iconNode' />
-		        <span data-dojo-attach-point='containerNode' class='tabLabel'></span>
-		        <span class="dijitInline dijitTabCloseButton dijitTabCloseIcon" data-dojo-attach-point='closeNode'
-		        		data-dojo-attach-event='onclick: onClickCloseButton' role="presentation">
-		            <span data-dojo-attach-point='closeText' class='dijitTabCloseText'>[x]</span
-		        ></span>
-			</div>
-        </div>
-    </div>
+<div role="presentation" data-dojo-attach-point="titleNode,innerDiv,tabContent" class="dijitTabInner dijitTabContent">
+	<span role="presentation" class="dijitInline dijitIcon dijitTabButtonIcon" data-dojo-attach-point="iconNode"></span>
+	<span data-dojo-attach-point='containerNode,focusNode' class='tabLabel'></span>
+	<span class="dijitInline dijitTabCloseButton dijitTabCloseIcon" data-dojo-attach-point='closeNode'
+		  role="presentation">
+		<span data-dojo-attach-point='closeText' class='dijitTabCloseText'>[x]</span
+				></span>
 </div>
diff --git a/dijit/layout/utils.js b/dijit/layout/utils.js
index 6d8b4d4..a36caed 100644
--- a/dijit/layout/utils.js
+++ b/dijit/layout/utils.js
@@ -3,33 +3,11 @@ define([
 	"dojo/dom-class", // domClass.add domClass.remove
 	"dojo/dom-geometry", // domGeometry.marginBox
 	"dojo/dom-style", // domStyle.getComputedStyle
-	"dojo/_base/lang", // lang.mixin
-	".."	// for exporting symbols to dijit, remove in 2.0
-], function(array, domClass, domGeometry, domStyle, lang, dijit){
+	"dojo/_base/lang" // lang.mixin, lang.setObject
+], function(array, domClass, domGeometry, domStyle, lang){
 
 	// module:
 	//		dijit/layout/utils
-	// summary:
-	//		marginBox2contentBox() and layoutChildren()
-
-	var layout = lang.getObject("layout", true, dijit);
-	/*===== layout = dijit.layout =====*/
-
-	layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
-		// summary:
-		//		Given the margin-box size of a node, return its content box size.
-		//		Functions like domGeometry.contentBox() but is more reliable since it doesn't have
-		//		to wait for the browser to compute sizes.
-		var cs = domStyle.getComputedStyle(node);
-		var me = domGeometry.getMarginExtents(node, cs);
-		var pb = domGeometry.getPadBorderExtents(node, cs);
-		return {
-			l: domStyle.toPixelValue(node, cs.paddingLeft),
-			t: domStyle.toPixelValue(node, cs.paddingTop),
-			w: mb.w - (me.w + pb.w),
-			h: mb.h - (me.h + pb.h)
-		};
-	};
 
 	function capitalize(word){
 		return word.substring(0,1).toUpperCase() + word.substring(1);
@@ -51,91 +29,123 @@ define([
 		}
 	}
 
-	layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Widget[]*/ children,
-			/*String?*/ changedRegionId, /*Number?*/ changedRegionSize){
+	var utils = {
 		// summary:
-		//		Layout a bunch of child dom nodes within a parent dom node
-		// container:
-		//		parent node
-		// dim:
-		//		{l, t, w, h} object specifying dimensions of container into which to place children
-		// children:
-		//		an array of Widgets or at least objects containing:
-		//			* domNode: pointer to DOM node to position
-		//			* region or layoutAlign: position to place DOM node
-		//			* resize(): (optional) method to set size of node
-		//			* id: (optional) Id of widgets, referenced from resize object, below.
-		// changedRegionId:
-		//		If specified, the slider for the region with the specified id has been dragged, and thus
-		//		the region's height or width should be adjusted according to changedRegionSize
-		// changedRegionSize:
-		//		See changedRegionId.
-
-		// copy dim because we are going to modify it
-		dim = lang.mixin({}, dim);
-
-		domClass.add(container, "dijitLayoutContainer");
-
-		// Move "client" elements to the end of the array for layout.  a11y dictates that the author
-		// needs to be able to put them in the document in tab-order, but this algorithm requires that
-		// client be last.    TODO: move these lines to LayoutContainer?   Unneeded other places I think.
-		children = array.filter(children, function(item){ return item.region != "center" && item.layoutAlign != "client"; })
-			.concat(array.filter(children, function(item){ return item.region == "center" || item.layoutAlign == "client"; }));
-
-		// set positions/sizes
-		array.forEach(children, function(child){
-			var elm = child.domNode,
-				pos = (child.region || child.layoutAlign);
-			if(!pos){
-				throw new Error("No region setting for " + child.id)
-			}
-
-			// set elem to upper left corner of unused space; may move it later
-			var elmStyle = elm.style;
-			elmStyle.left = dim.l+"px";
-			elmStyle.top = dim.t+"px";
-			elmStyle.position = "absolute";
-
-			domClass.add(elm, "dijitAlign" + capitalize(pos));
-
-			// Size adjustments to make to this child widget
-			var sizeSetting = {};
-
-			// Check for optional size adjustment due to splitter drag (height adjustment for top/bottom align
-			// panes and width adjustment for left/right align panes.
-			if(changedRegionId && changedRegionId == child.id){
-				sizeSetting[child.region == "top" || child.region == "bottom" ? "h" : "w"] = changedRegionSize;
-			}
-
-			// set size && adjust record of remaining space.
-			// note that setting the width of a <div> may affect its height.
-			if(pos == "top" || pos == "bottom"){
-				sizeSetting.w = dim.w;
-				size(child, sizeSetting);
-				dim.h -= child.h;
-				if(pos == "top"){
-					dim.t += child.h;
-				}else{
-					elmStyle.top = dim.t + dim.h + "px";
+		//		Utility functions for doing layout
+
+		marginBox2contentBox: function(/*DomNode*/ node, /*Object*/ mb){
+			// summary:
+			//		Given the margin-box size of a node, return its content box size.
+			//		Functions like domGeometry.contentBox() but is more reliable since it doesn't have
+			//		to wait for the browser to compute sizes.
+			var cs = domStyle.getComputedStyle(node);
+			var me = domGeometry.getMarginExtents(node, cs);
+			var pb = domGeometry.getPadBorderExtents(node, cs);
+			return {
+				l: domStyle.toPixelValue(node, cs.paddingLeft),
+				t: domStyle.toPixelValue(node, cs.paddingTop),
+				w: mb.w - (me.w + pb.w),
+				h: mb.h - (me.h + pb.h)
+			};
+		},
+
+
+		layoutChildren: function(/*DomNode*/ container, /*Object*/ dim, /*Widget[]*/ children,
+				/*String?*/ changedRegionId, /*Number?*/ changedRegionSize){
+			// summary:
+			//		Layout a bunch of child dom nodes within a parent dom node
+			// container:
+			//		parent node
+			// dim:
+			//		{l, t, w, h} object specifying dimensions of container into which to place children
+			// children:
+			//		An array of Widgets or at least objects containing:
+			//
+			//		- domNode: pointer to DOM node to position
+			//		- region or layoutAlign: position to place DOM node
+			//		- resize(): (optional) method to set size of node
+			//		- id: (optional) Id of widgets, referenced from resize object, below.
+			//
+			//		The widgets in this array should be ordered according to how they should be laid out
+			//		(each element will be processed in order, and take up as much remaining space as needed),
+			//		with the center widget last.
+			// changedRegionId:
+			//		If specified, the slider for the region with the specified id has been dragged, and thus
+			//		the region's height or width should be adjusted according to changedRegionSize
+			// changedRegionSize:
+			//		See changedRegionId.
+
+			// copy dim because we are going to modify it
+			dim = lang.mixin({}, dim);
+
+			domClass.add(container, "dijitLayoutContainer");
+
+			// Move "client" elements to the end of the array for layout.  a11y dictates that the author
+			// needs to be able to put them in the document in tab-order, but this algorithm requires that
+			// client be last.    TODO: remove for 2.0, all dijit client code already sends children as last item.
+			children = array.filter(children, function(item){ return item.region != "center" && item.layoutAlign != "client"; })
+				.concat(array.filter(children, function(item){ return item.region == "center" || item.layoutAlign == "client"; }));
+
+			// set positions/sizes
+			array.forEach(children, function(child){
+				var elm = child.domNode,
+					pos = (child.region || child.layoutAlign);
+				if(!pos){
+					throw new Error("No region setting for " + child.id)
 				}
-			}else if(pos == "left" || pos == "right"){
-				sizeSetting.h = dim.h;
-				size(child, sizeSetting);
-				dim.w -= child.w;
-				if(pos == "left"){
-					dim.l += child.w;
-				}else{
-					elmStyle.left = dim.l + dim.w + "px";
+
+				// set elem to upper left corner of unused space; may move it later
+				var elmStyle = elm.style;
+				elmStyle.left = dim.l+"px";
+				elmStyle.top = dim.t+"px";
+				elmStyle.position = "absolute";
+
+				domClass.add(elm, "dijitAlign" + capitalize(pos));
+
+				// Size adjustments to make to this child widget
+				var sizeSetting = {};
+
+				// Check for optional size adjustment due to splitter drag (height adjustment for top/bottom align
+				// panes and width adjustment for left/right align panes.
+				if(changedRegionId && changedRegionId == child.id){
+					sizeSetting[child.region == "top" || child.region == "bottom" ? "h" : "w"] = changedRegionSize;
 				}
-			}else if(pos == "client" || pos == "center"){
-				size(child, dim);
-			}
-		});
-	};
 
+				if(pos == "leading"){
+					pos = child.isLeftToRight() ? "left" : "right";
+				}
+				if(pos == "trailing"){
+					pos = child.isLeftToRight() ? "right" : "left";
+				}
 
-	return {
-		marginBox2contentBox: layout.marginBox2contentBox,
-		layoutChildren: layout.layoutChildren
+				// set size && adjust record of remaining space.
+				// note that setting the width of a <div> may affect its height.
+				if(pos == "top" || pos == "bottom"){
+					sizeSetting.w = dim.w;
+					size(child, sizeSetting);
+					dim.h -= child.h;
+					if(pos == "top"){
+						dim.t += child.h;
+					}else{
+						elmStyle.top = dim.t + dim.h + "px";
+					}
+				}else if(pos == "left" || pos == "right"){
+					sizeSetting.h = dim.h;
+					size(child, sizeSetting);
+					dim.w -= child.w;
+					if(pos == "left"){
+						dim.l += child.w;
+					}else{
+						elmStyle.left = dim.l + dim.w + "px";
+					}
+				}else if(pos == "client" || pos == "center"){
+					size(child, dim);
+				}
+			});
+		}
 	};
+
+	lang.setObject("dijit.layout.utils", utils);	// remove for 2.0
+
+	return utils;
 });
diff --git a/dijit/main.js b/dijit/main.js
index 1b91ebb..43cc44c 100644
--- a/dijit/main.js
+++ b/dijit/main.js
@@ -2,9 +2,15 @@ define([
 	"dojo/_base/kernel"
 ], function(dojo){
 	// module:
-	//		dijit
+	//		dijit/main
+
+/*=====
+return {
 	// summary:
-	//		The dijit package main module
+	//		The dijit package main module.
+	//		Deprecated.   Users should access individual modules (ex: dijit/registry) directly.
+};
+=====*/
 
 	return dojo.dijit;
 });
diff --git a/dijit/nls/ar/common.js b/dijit/nls/ar/common.js
index 16d3947..eefe10f 100644
--- a/dijit/nls/ar/common.js
+++ b/dijit/nls/ar/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "حسنا",
 	buttonCancel: "الغاء",
 	buttonSave: "حفظ",
 	itemClose: "اغلاق"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/ar/loading.js b/dijit/nls/ar/loading.js
index 2d87a15..564c19b 100644
--- a/dijit/nls/ar/loading.js
+++ b/dijit/nls/ar/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "جاري التحميل...",
 	errorState: "عفوا، حدث خطأ"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/az/common.js b/dijit/nls/az/common.js
index 49ef3dd..44bea58 100644
--- a/dijit/nls/az/common.js
+++ b/dijit/nls/az/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"buttonOk" : "Ok",
 	"buttonCancel" : "Ləğv et",
 	"buttonSave" : "Saxla",
 	"itemClose" : "Bağla"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/az/loading.js b/dijit/nls/az/loading.js
index 4e868eb..26818e2 100644
--- a/dijit/nls/az/loading.js
+++ b/dijit/nls/az/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"loadingState" : "Yüklənir...",
 	"errorState" : "Problem yarandı"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/bg/common.js b/dijit/nls/bg/common.js
new file mode 100644
index 0000000..1561677
--- /dev/null
+++ b/dijit/nls/bg/common.js
@@ -0,0 +1,8 @@
+define(
+({
+	buttonOk: "ОК",
+	buttonCancel: "Отмени",
+	buttonSave: "Запази",
+	itemClose: "Затвори"
+})
+);
diff --git a/dijit/nls/bg/loading.js b/dijit/nls/bg/loading.js
new file mode 100644
index 0000000..3fe6f8a
--- /dev/null
+++ b/dijit/nls/bg/loading.js
@@ -0,0 +1,6 @@
+define(
+({
+	loadingState: "Зареждане...",
+	errorState: "Съжаляваме, възникна грешка"
+})
+);
diff --git a/dijit/nls/ca/common.js b/dijit/nls/ca/common.js
index 08ab8bb..60041a8 100644
--- a/dijit/nls/ca/common.js
+++ b/dijit/nls/ca/common.js
@@ -1,11 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "D'acord",
 	buttonCancel: "Cancel·la",
 	buttonSave: "Desa",
 	itemClose: "Tanca"
 })
-
-//end v1.x content
 );
diff --git a/dijit/nls/ca/loading.js b/dijit/nls/ca/loading.js
index 470a995..6efcf91 100644
--- a/dijit/nls/ca/loading.js
+++ b/dijit/nls/ca/loading.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "S'està carregant...",
 	errorState: "Ens sap greu. S'ha produït un error."
 })
-
-//end v1.x content
 );
diff --git a/dijit/nls/common.js b/dijit/nls/common.js
index e5151c2..25d031d 100644
--- a/dijit/nls/common.js
+++ b/dijit/nls/common.js
@@ -10,6 +10,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -37,6 +38,7 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dijit/nls/cs/common.js b/dijit/nls/cs/common.js
index 415a6a3..82ec2a5 100644
--- a/dijit/nls/cs/common.js
+++ b/dijit/nls/cs/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Storno",
 	buttonSave: "Uložit",
 	itemClose: "Zavřít"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/cs/loading.js b/dijit/nls/cs/loading.js
index 47c5253..f332492 100644
--- a/dijit/nls/cs/loading.js
+++ b/dijit/nls/cs/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Probíhá načítání...",
 	errorState: "Omlouváme se, došlo k chybě"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/da/common.js b/dijit/nls/da/common.js
index ec2795c..2ede916 100644
--- a/dijit/nls/da/common.js
+++ b/dijit/nls/da/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Annullér",
 	buttonSave: "Gem",
 	itemClose: "Luk"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/da/loading.js b/dijit/nls/da/loading.js
index 306023d..103ce8c 100644
--- a/dijit/nls/da/loading.js
+++ b/dijit/nls/da/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Indlæser...",
 	errorState: "Der er opstået en fejl"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/de/common.js b/dijit/nls/de/common.js
index 7a374dd..df36d76 100755
--- a/dijit/nls/de/common.js
+++ b/dijit/nls/de/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Abbrechen",
 	buttonSave: "Speichern",
 	itemClose: "Schließen"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/de/loading.js b/dijit/nls/de/loading.js
index 435a9fc..dc5926f 100644
--- a/dijit/nls/de/loading.js
+++ b/dijit/nls/de/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Wird geladen...",
 	errorState: "Es ist ein Fehler aufgetreten."
 })
-//end v1.x content
 );
diff --git a/dijit/nls/el/common.js b/dijit/nls/el/common.js
index a5b3bde..e0097ca 100644
--- a/dijit/nls/el/common.js
+++ b/dijit/nls/el/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "ΟΚ",
 	buttonCancel: "Ακύρωση",
 	buttonSave: "Αποθήκευση",
 	itemClose: "Κλείσιμο"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/el/loading.js b/dijit/nls/el/loading.js
index 14efe3a..3bb46ad 100644
--- a/dijit/nls/el/loading.js
+++ b/dijit/nls/el/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Φόρτωση...",
 	errorState: "Σας ζητούμε συγνώμη, παρουσιάστηκε σφάλμα"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/es/common.js b/dijit/nls/es/common.js
index 55e30eb..b2602d1 100644
--- a/dijit/nls/es/common.js
+++ b/dijit/nls/es/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "Aceptar",
 	buttonCancel: "Cancelar",
 	buttonSave: "Guardar",
 	itemClose: "Cerrar"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/es/loading.js b/dijit/nls/es/loading.js
index d5e51af..42b4949 100644
--- a/dijit/nls/es/loading.js
+++ b/dijit/nls/es/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Cargando...",
 	errorState: "Lo siento, se ha producido un error"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/fi/common.js b/dijit/nls/fi/common.js
index 23450a5..405729e 100644
--- a/dijit/nls/fi/common.js
+++ b/dijit/nls/fi/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Peruuta",
 	buttonSave: "Tallenna",
 	itemClose: "Sulje"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/fi/loading.js b/dijit/nls/fi/loading.js
index 786cfb8..2306af7 100644
--- a/dijit/nls/fi/loading.js
+++ b/dijit/nls/fi/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Lataus on meneillään...",
 	errorState: "On ilmennyt virhe."
 })
-//end v1.x content
 );
diff --git a/dijit/nls/fr/common.js b/dijit/nls/fr/common.js
index 0d54bc8..edf4192 100644
--- a/dijit/nls/fr/common.js
+++ b/dijit/nls/fr/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Annuler",
-	buttonSave: "Sauvegarder",
+	buttonSave: "Enregistrer",
 	itemClose: "Fermer"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/fr/loading.js b/dijit/nls/fr/loading.js
index 9f263c7..fa5cbde 100644
--- a/dijit/nls/fr/loading.js
+++ b/dijit/nls/fr/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Chargement...",
 	errorState: "Une erreur est survenue"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/he/common.js b/dijit/nls/he/common.js
index 387db73..94b04d0 100644
--- a/dijit/nls/he/common.js
+++ b/dijit/nls/he/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "אישור",
 	buttonCancel: "ביטול",
 	buttonSave: "שמירה",
 	itemClose: "סגירה"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/he/loading.js b/dijit/nls/he/loading.js
index c4e13a0..e5cc1f6 100644
--- a/dijit/nls/he/loading.js
+++ b/dijit/nls/he/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "טעינה...‏",
 	errorState: "אירעה שגיאה"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/hr/loading.js b/dijit/nls/hr/loading.js
index f14e8ee..3ea326c 100644
--- a/dijit/nls/hr/loading.js
+++ b/dijit/nls/hr/loading.js
@@ -1,6 +1,6 @@
 define(
 ({
 	loadingState: "Učitavanje...",
-	errorState: "Žao nam je, došlo je do pogreške"
+	errorState: "Žao nam je, došlo je do greške"
 })
 );
diff --git a/dijit/nls/hu/common.js b/dijit/nls/hu/common.js
index 82f7ecd..0b98e77 100644
--- a/dijit/nls/hu/common.js
+++ b/dijit/nls/hu/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Mégse",
 	buttonSave: "Mentés",
 	itemClose: "Bezárás"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/hu/loading.js b/dijit/nls/hu/loading.js
index 63d758b..7116733 100644
--- a/dijit/nls/hu/loading.js
+++ b/dijit/nls/hu/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Betöltés...",
 	errorState: "Sajnálom, hiba történt"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/it/common.js b/dijit/nls/it/common.js
index 5d62045..30943b5 100644
--- a/dijit/nls/it/common.js
+++ b/dijit/nls/it/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
-	buttonOk: "OK",
+	buttonOk: "Ok",
 	buttonCancel: "Annulla",
 	buttonSave: "Salva",
 	itemClose: "Chiudi"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/it/loading.js b/dijit/nls/it/loading.js
index a41d6fb..4acf89e 100644
--- a/dijit/nls/it/loading.js
+++ b/dijit/nls/it/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Caricamento in corso...",
 	errorState: "Si è verificato un errore"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/ja/common.js b/dijit/nls/ja/common.js
index b364461..5fc5156 100644
--- a/dijit/nls/ja/common.js
+++ b/dijit/nls/ja/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "キャンセル",
 	buttonSave: "保存",
 	itemClose: "閉じる"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/ja/loading.js b/dijit/nls/ja/loading.js
index 741c58e..700b287 100644
--- a/dijit/nls/ja/loading.js
+++ b/dijit/nls/ja/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "ロード中...",
 	errorState: "エラーが発生しました。"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/kk/common.js b/dijit/nls/kk/common.js
index 5675fd7..9cf8cf5 100644
--- a/dijit/nls/kk/common.js
+++ b/dijit/nls/kk/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Болдырмау",
 	buttonSave: "Сақтау",
 	itemClose: "Жабу"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/kk/loading.js b/dijit/nls/kk/loading.js
index 038534c..00bb857 100644
--- a/dijit/nls/kk/loading.js
+++ b/dijit/nls/kk/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
-	loadingState: "Жүктелуде...",
+	loadingState: "Қотарылуда...",
 	errorState: "Кешіріңіз, қате орын алды"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/ko/common.js b/dijit/nls/ko/common.js
index 172e23a..847f14e 100644
--- a/dijit/nls/ko/common.js
+++ b/dijit/nls/ko/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "확인",
 	buttonCancel: "취소",
 	buttonSave: "저장",
 	itemClose: "닫기"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/ko/loading.js b/dijit/nls/ko/loading.js
index 905249c..c9c1c04 100644
--- a/dijit/nls/ko/loading.js
+++ b/dijit/nls/ko/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "로드 중...",
 	errorState: "죄송합니다. 오류가 발생했습니다."
 })
-//end v1.x content
 );
diff --git a/dijit/nls/loading.js b/dijit/nls/loading.js
index 51ab92f..09750d5 100644
--- a/dijit/nls/loading.js
+++ b/dijit/nls/loading.js
@@ -8,6 +8,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -35,6 +36,7 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dijit/nls/nb/common.js b/dijit/nls/nb/common.js
index 4b87fb8..096cfe5 100644
--- a/dijit/nls/nb/common.js
+++ b/dijit/nls/nb/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Avbryt",
 	buttonSave: "Lagre",
 	itemClose: "Lukk"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/nb/loading.js b/dijit/nls/nb/loading.js
index 90b399b..e2f8f77 100644
--- a/dijit/nls/nb/loading.js
+++ b/dijit/nls/nb/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Laster inn...",
 	errorState: "Det oppsto en feil"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/nl/common.js b/dijit/nls/nl/common.js
index bbd4080..25ead10 100644
--- a/dijit/nls/nl/common.js
+++ b/dijit/nls/nl/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Annuleren",
 	buttonSave: "Opslaan",
 	itemClose: "Sluiten"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/nl/loading.js b/dijit/nls/nl/loading.js
index 4fdcedb..d91cfbe 100644
--- a/dijit/nls/nl/loading.js
+++ b/dijit/nls/nl/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Bezig met laden...",
 	errorState: "Er is een fout opgetreden"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/pl/common.js b/dijit/nls/pl/common.js
index c7a6f35..8021eda 100644
--- a/dijit/nls/pl/common.js
+++ b/dijit/nls/pl/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Anuluj",
 	buttonSave: "Zapisz",
 	itemClose: "Zamknij"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/pl/loading.js b/dijit/nls/pl/loading.js
index 5c3e45b..fff2dc1 100644
--- a/dijit/nls/pl/loading.js
+++ b/dijit/nls/pl/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Ładowanie...",
 	errorState: "Niestety, wystąpił błąd"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/pt-pt/common.js b/dijit/nls/pt-pt/common.js
index a7fa342..7780946 100644
--- a/dijit/nls/pt-pt/common.js
+++ b/dijit/nls/pt-pt/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Cancelar",
 	buttonSave: "Guardar",
 	itemClose: "Fechar"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/pt-pt/loading.js b/dijit/nls/pt-pt/loading.js
index 45ad394..0c6f465 100644
--- a/dijit/nls/pt-pt/loading.js
+++ b/dijit/nls/pt-pt/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "A carregar...",
 	errorState: "Lamentamos, mas ocorreu um erro"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/pt/common.js b/dijit/nls/pt/common.js
index 301e314..a5fd2e3 100644
--- a/dijit/nls/pt/common.js
+++ b/dijit/nls/pt/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Cancelar",
 	buttonSave: "Salvar",
 	itemClose: "Fechar"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/pt/loading.js b/dijit/nls/pt/loading.js
index 3f61ef8..a7fe7c8 100644
--- a/dijit/nls/pt/loading.js
+++ b/dijit/nls/pt/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Carregando...",
 	errorState: "Desculpe, ocorreu um erro"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/ro/common.js b/dijit/nls/ro/common.js
index 4763ce0..d81cd41 100644
--- a/dijit/nls/ro/common.js
+++ b/dijit/nls/ro/common.js
@@ -1,11 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Anulare",
 	buttonSave: "Salvare",
 	itemClose: "Închidere"
 })
-
-//end v1.x content
 );
diff --git a/dijit/nls/ro/loading.js b/dijit/nls/ro/loading.js
index 7dd766b..c88838e 100644
--- a/dijit/nls/ro/loading.js
+++ b/dijit/nls/ro/loading.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Încărcare...",
 	errorState: "Ne pare rău, a apărut o eroare "
 })
-
-//end v1.x content
 );
diff --git a/dijit/nls/ru/common.js b/dijit/nls/ru/common.js
index 870e21c..8c69199 100644
--- a/dijit/nls/ru/common.js
+++ b/dijit/nls/ru/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
-	buttonOk: "ОК",
+	buttonOk: "OK",
 	buttonCancel: "Отмена",
 	buttonSave: "Сохранить",
 	itemClose: "Закрыть"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/ru/loading.js b/dijit/nls/ru/loading.js
index 20465d2..e1bc1fa 100644
--- a/dijit/nls/ru/loading.js
+++ b/dijit/nls/ru/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Загрузка...",
 	errorState: "Извините, возникла ошибка"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/sk/common.js b/dijit/nls/sk/common.js
index 76748df..4bf3bd6 100644
--- a/dijit/nls/sk/common.js
+++ b/dijit/nls/sk/common.js
@@ -1,11 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Zrušiť",
 	buttonSave: "Uložiť",
 	itemClose: "Zatvoriť"
 })
-
-//end v1.x content
 );
diff --git a/dijit/nls/sk/loading.js b/dijit/nls/sk/loading.js
index 8630175..044f580 100644
--- a/dijit/nls/sk/loading.js
+++ b/dijit/nls/sk/loading.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
-	loadingState: "Zavádzanie...",
-	errorState: "Nastala chyba"
+	loadingState: "Zavádza sa...",
+	errorState: "Ľutujeme, ale vyskytla sa chyba"
 })
-
-//end v1.x content
 );
diff --git a/dijit/nls/sl/common.js b/dijit/nls/sl/common.js
index 751e4fe..31df38b 100644
--- a/dijit/nls/sl/common.js
+++ b/dijit/nls/sl/common.js
@@ -1,11 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "V redu",
 	buttonCancel: "Prekliči",
 	buttonSave: "Shrani",
 	itemClose: "Zapri"
 })
-
-//end v1.x content
 );
diff --git a/dijit/nls/sl/loading.js b/dijit/nls/sl/loading.js
index 0ba8233..d1f5ee6 100644
--- a/dijit/nls/sl/loading.js
+++ b/dijit/nls/sl/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Nalaganje ...",
 	errorState: "Oprostite, prišlo je do napake."
 })
-//end v1.x content
 );
diff --git a/dijit/nls/sv/common.js b/dijit/nls/sv/common.js
index 57b368f..0a372f4 100644
--- a/dijit/nls/sv/common.js
+++ b/dijit/nls/sv/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Avbryt",
 	buttonSave: "Spara",
 	itemClose: "Stäng"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/sv/loading.js b/dijit/nls/sv/loading.js
index baa5d5a..e9f9bf7 100644
--- a/dijit/nls/sv/loading.js
+++ b/dijit/nls/sv/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Läser in...",
-	errorState: "Det uppstod ett fel."
+	errorState: "Det har inträffat ett fel."
 })
-//end v1.x content
 );
diff --git a/dijit/nls/th/common.js b/dijit/nls/th/common.js
index 4fa0ef6..d364693 100644
--- a/dijit/nls/th/common.js
+++ b/dijit/nls/th/common.js
@@ -1,11 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "ตกลง",
 	buttonCancel: "ยกเลิก",
 	buttonSave: "บันทึก",
 	itemClose: "ปิด"
 })
-
-//end v1.x content
 );
diff --git a/dijit/nls/th/loading.js b/dijit/nls/th/loading.js
index 6b99a61..d9b4723 100644
--- a/dijit/nls/th/loading.js
+++ b/dijit/nls/th/loading.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "กำลังโหลด...",
 	errorState: "ขออภัย เกิดข้อผิดพลาด"
 })
-
-//end v1.x content
 );
diff --git a/dijit/nls/tr/common.js b/dijit/nls/tr/common.js
index 8a1d058..0c203cc 100644
--- a/dijit/nls/tr/common.js
+++ b/dijit/nls/tr/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "Tamam",
 	buttonCancel: "İptal",
 	buttonSave: "Kaydet",
 	itemClose: "Kapat"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/tr/loading.js b/dijit/nls/tr/loading.js
index 53685e3..9bccb3e 100644
--- a/dijit/nls/tr/loading.js
+++ b/dijit/nls/tr/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "Yükleniyor...",
 	errorState: "Üzgünüz, bir hata oluştu"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/uk/common.js b/dijit/nls/uk/common.js
new file mode 100644
index 0000000..1239aa1
--- /dev/null
+++ b/dijit/nls/uk/common.js
@@ -0,0 +1,8 @@
+define(
+({
+	buttonOk: "OK",
+	buttonCancel: "Скасувати",
+	buttonSave: "Зберегти",
+	itemClose: "Закрити"
+})
+);
diff --git a/dijit/nls/uk/loading.js b/dijit/nls/uk/loading.js
new file mode 100644
index 0000000..6f74f74
--- /dev/null
+++ b/dijit/nls/uk/loading.js
@@ -0,0 +1,6 @@
+define(
+({
+	loadingState: "Завантаження...",
+	errorState: "Сталася помилка"
+})
+);
diff --git a/dijit/nls/zh-tw/common.js b/dijit/nls/zh-tw/common.js
index 46eca0d..802ff99 100644
--- a/dijit/nls/zh-tw/common.js
+++ b/dijit/nls/zh-tw/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "確定",
 	buttonCancel: "取消",
 	buttonSave: "儲存",
 	itemClose: "關閉"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/zh-tw/loading.js b/dijit/nls/zh-tw/loading.js
index e581a01..6a2573e 100644
--- a/dijit/nls/zh-tw/loading.js
+++ b/dijit/nls/zh-tw/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "載入中...",
 	errorState: "抱歉,發生錯誤"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/zh/common.js b/dijit/nls/zh/common.js
index b70ed72..ba0b13c 100644
--- a/dijit/nls/zh/common.js
+++ b/dijit/nls/zh/common.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	buttonOk: "确定",
 	buttonCancel: "取消",
 	buttonSave: "保存",
 	itemClose: "关闭"
 })
-//end v1.x content
 );
diff --git a/dijit/nls/zh/loading.js b/dijit/nls/zh/loading.js
index a8ae8e6..0202c21 100644
--- a/dijit/nls/zh/loading.js
+++ b/dijit/nls/zh/loading.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	loadingState: "正在加载...",
 	errorState: "对不起,发生了错误"
 })
-//end v1.x content
 );
diff --git a/dijit/package.json b/dijit/package.json
index b48f94c..5c79afe 100644
--- a/dijit/package.json
+++ b/dijit/package.json
@@ -1,9 +1,12 @@
 {
 	"name": "dijit",
-	"version":"1.7.2",
+	"version":"1.9.1",
+	"directories": {
+		"lib": "."
+	},
 	"main":"main",
 	"dependencies": {
-		"dojo": "current"
+		"dojo":"1.9.1"
 	},
 	"description": "Dijit provides a complete collection of user interface controls based on Dojo, giving you the power to create web applications that are highly optimized for usability, performance, internationalization, accessibility, but above all deliver an incredible user experience.",
 	"licenses": [
diff --git a/dijit/place.js b/dijit/place.js
index 47201d9..a855418 100644
--- a/dijit/place.js
+++ b/dijit/place.js
@@ -1,17 +1,15 @@
 define([
 	"dojo/_base/array", // array.forEach array.map array.some
-	"dojo/dom-geometry", // domGeometry.getMarginBox domGeometry.position
+	"dojo/dom-geometry", // domGeometry.position
 	"dojo/dom-style", // domStyle.getComputedStyle
 	"dojo/_base/kernel", // kernel.deprecated
 	"dojo/_base/window", // win.body
-	"dojo/window", // winUtils.getBox
-	"."	// dijit (defining dijit.place to match API doc)
-], function(array, domGeometry, domStyle, kernel, win, winUtils, dijit){
+	"./Viewport", // getEffectiveBox
+	"./main"	// dijit (defining dijit.place to match API doc)
+], function(array, domGeometry, domStyle, kernel, win, Viewport, dijit){
 
 	// module:
 	//		dijit/place
-	// summary:
-	//		Code to place a popup relative to another node
 
 
 	function _place(/*DomNode*/ node, choices, layoutNode, aroundNodeCoords){
@@ -33,13 +31,13 @@ define([
 
 		// get {x: 10, y: 10, w: 100, h:100} type obj representing position of
 		// viewport over document
-		var view = winUtils.getBox();
+		var view = Viewport.getEffectiveBox(node.ownerDocument);
 
 		// This won't work if the node is inside a <div style="position: relative">,
-		// so reattach it to win.doc.body.	 (Otherwise, the positioning will be wrong
-		// and also it might get cutoff)
+		// so reattach it to <body>.	 (Otherwise, the positioning will be wrong
+		// and also it might get cutoff.)
 		if(!node.parentNode || String(node.parentNode.tagName).toLowerCase() != "body"){
-			win.body().appendChild(node);
+			win.body(node.ownerDocument).appendChild(node);
 		}
 
 		var best = null;
@@ -54,14 +52,19 @@ define([
 					'L': view.l + view.w - pos.x,
 					'R': pos.x - view.l,
 					'M': view.w
-				   }[corner.charAt(1)],
+				}[corner.charAt(1)],
 				h: {
 					'T': view.t + view.h - pos.y,
 					'B': pos.y - view.t,
 					'M': view.h
-				   }[corner.charAt(0)]
+				}[corner.charAt(0)]
 			};
 
+			// Clear left/right position settings set earlier so they don't interfere with calculations,
+			// specifically when layoutNode() (a.k.a. Tooltip.orient()) measures natural width of Tooltip
+			var s = node.style;
+			s.left = s.right = "auto";
+
 			// configure node to be displayed in given position relative to button
 			// (need to do this in order to get an accurate size for the node, because
 			// a tooltip's size changes based on position, due to triangle)
@@ -78,7 +81,7 @@ define([
 				style.visibility = "hidden";
 				style.display = "";
 			}
-			var mb = domGeometry. getMarginBox(node);
+			var bb = domGeometry.position(node);
 			style.display = oldDisplay;
 			style.visibility = oldVis;
 
@@ -87,22 +90,22 @@ define([
 			var
 				startXpos = {
 					'L': pos.x,
-					'R': pos.x - mb.w,
-					'M': Math.max(view.l, Math.min(view.l + view.w, pos.x + (mb.w >> 1)) - mb.w) // M orientation is more flexible
+					'R': pos.x - bb.w,
+					'M': Math.max(view.l, Math.min(view.l + view.w, pos.x + (bb.w >> 1)) - bb.w) // M orientation is more flexible
 				}[corner.charAt(1)],
 				startYpos = {
 					'T': pos.y,
-					'B': pos.y - mb.h,
-					'M': Math.max(view.t, Math.min(view.t + view.h, pos.y + (mb.h >> 1)) - mb.h)
+					'B': pos.y - bb.h,
+					'M': Math.max(view.t, Math.min(view.t + view.h, pos.y + (bb.h >> 1)) - bb.h)
 				}[corner.charAt(0)],
 				startX = Math.max(view.l, startXpos),
 				startY = Math.max(view.t, startYpos),
-				endX = Math.min(view.l + view.w, startXpos + mb.w),
-				endY = Math.min(view.t + view.h, startYpos + mb.h),
+				endX = Math.min(view.l + view.w, startXpos + bb.w),
+				endY = Math.min(view.t + view.h, startYpos + bb.h),
 				width = endX - startX,
 				height = endY - startY;
 
-			overflow += (mb.w - width) + (mb.h - height);
+			overflow += (bb.w - width) + (bb.h - height);
 
 			if(best == null || overflow < best.overflow){
 				best = {
@@ -133,76 +136,74 @@ define([
 		//
 		// In RTL mode, set style.right rather than style.left so in the common case,
 		// window resizes move the popup along with the aroundNode.
-		var l = domGeometry.isBodyLtr(),
-			s = node.style;
-		s.top = best.y + "px";
-		s[l ? "left" : "right"] = (l ? best.x : view.w - best.x - best.w) + "px";
-		s[l ? "right" : "left"] = "auto";	// needed for FF or else tooltip goes to far left
 
-		return best;
-	}
+		var l = domGeometry.isBodyLtr(node.ownerDocument),
+			top = best.y,
+			side = l ? best.x : view.w - best.x - best.w;
 
-	/*=====
-	dijit.place.__Position = function(){
-		// x: Integer
-		//		horizontal coordinate in pixels, relative to document body
-		// y: Integer
-		//		vertical coordinate in pixels, relative to document body
+		if(/relative|absolute/.test(domStyle.get(win.body(node.ownerDocument), "position"))){
+			// compensate for margin on <body>, see #16148
+			top -= domStyle.get(win.body(node.ownerDocument), "marginTop");
+			side -= (l ? 1 : -1) * domStyle.get(win.body(node.ownerDocument), l ? "marginLeft" : "marginRight");
+		}
 
-		this.x = x;
-		this.y = y;
-	};
-	=====*/
+		var s = node.style;
+		s.top = top + "px";
+		s[l ? "left" : "right"] = side + "px";
+		s[l ? "right" : "left"] = "auto";	// needed for FF or else tooltip goes to far left
 
-	/*=====
-	dijit.place.__Rectangle = function(){
-		// x: Integer
-		//		horizontal offset in pixels, relative to document body
-		// y: Integer
-		//		vertical offset in pixels, relative to document body
-		// w: Integer
-		//		width in pixels.   Can also be specified as "width" for backwards-compatibility.
-		// h: Integer
-		//		height in pixels.   Can also be specified as "height" from backwards-compatibility.
+		return best;
+	}
 
-		this.x = x;
-		this.y = y;
-		this.w = w;
-		this.h = h;
+	var reverse = {
+		// Map from corner to kitty-corner
+		"TL": "BR",
+		"TR": "BL",
+		"BL": "TR",
+		"BR": "TL"
 	};
-	=====*/
 
-	return (dijit.place = {
+	var place = {
 		// summary:
 		//		Code to place a DOMNode relative to another DOMNode.
 		//		Load using require(["dijit/place"], function(place){ ... }).
 
-		at: function(node, pos, corners, padding){
+		at: function(node, pos, corners, padding, layoutNode){
 			// summary:
-			//		Positions one of the node's corners at specified position
-			//		such that node is fully visible in viewport.
-			// description:
-			//		NOTE: node is assumed to be absolutely or relatively positioned.
+			//		Positions node kitty-corner to the rectangle centered at (pos.x, pos.y) with width and height of
+			//		padding.x * 2 and padding.y * 2, or zero if padding not specified.  Picks first corner in corners[]
+			//		where node is fully visible, or the corner where it's most visible.
+			//
+			//		Node is assumed to be absolutely or relatively positioned.
 			// node: DOMNode
 			//		The node to position
-			// pos: dijit.place.__Position
+			// pos: dijit/place.__Position
 			//		Object like {x: 10, y: 20}
 			// corners: String[]
-			//		Array of Strings representing order to try corners in, like ["TR", "BL"].
+			//		Array of Strings representing order to try corners of the node in, like ["TR", "BL"].
 			//		Possible values are:
-			//			* "BL" - bottom left
-			//			* "BR" - bottom right
-			//			* "TL" - top left
-			//			* "TR" - top right
-			// padding: dijit.place.__Position?
-			//		optional param to set padding, to put some buffer around the element you want to position.
+			//
+			//		- "BL" - bottom left
+			//		- "BR" - bottom right
+			//		- "TL" - top left
+			//		- "TR" - top right
+			// padding: dijit/place.__Position?
+			//		Optional param to set padding, to put some buffer around the element you want to position.
+			//		Defaults to zero.
+			// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
+			//		For things like tooltip, they are displayed differently (and have different dimensions)
+			//		based on their orientation relative to the parent.  This adjusts the popup based on orientation.
 			// example:
 			//		Try to place node's top right corner at (10,20).
 			//		If that makes node go (partially) off screen, then try placing
 			//		bottom left corner at (10,20).
 			//	|	place(node, {x: 10, y: 20}, ["TR", "BL"])
 			var choices = array.map(corners, function(corner){
-				var c = { corner: corner, pos: {x:pos.x,y:pos.y} };
+				var c = {
+					corner: corner,
+					aroundCorner: reverse[corner],	// so TooltipDialog.orient() gets aroundCorner argument set
+					pos: {x: pos.x,y: pos.y}
+				};
 				if(padding){
 					c.pos.x += corner.charAt(1) == 'L' ? padding.x : -padding.x;
 					c.pos.y += corner.charAt(0) == 'T' ? padding.y : -padding.y;
@@ -210,12 +211,12 @@ define([
 				return c;
 			});
 
-			return _place(node, choices);
+			return _place(node, choices, layoutNode);
 		},
 
 		around: function(
 			/*DomNode*/		node,
-			/*DomNode || dijit.place.__Rectangle*/ anchor,
+			/*DomNode|dijit/place.__Rectangle*/ anchor,
 			/*String[]*/	positions,
 			/*Boolean*/		leftToRight,
 			/*Function?*/	layoutNode){
@@ -223,69 +224,88 @@ define([
 			// summary:
 			//		Position node adjacent or kitty-corner to anchor
 			//		such that it's fully visible in viewport.
-			//
 			// description:
 			//		Place node such that corner of node touches a corner of
 			//		aroundNode, and that node is fully visible.
-			//
 			// anchor:
-			//		Either a DOMNode or a __Rectangle (object with x, y, width, height).
-			//
+			//		Either a DOMNode or a rectangle (object with x, y, width, height).
 			// positions:
 			//		Ordered list of positions to try matching up.
-			//			* before: places drop down to the left of the anchor node/widget, or to the right in the case
-			//				of RTL scripts like Hebrew and Arabic; aligns either the top of the drop down
-			//				with the top of the anchor, or the bottom of the drop down with bottom of the anchor.
-			//			* after: places drop down to the right of the anchor node/widget, or to the left in the case
-			//				of RTL scripts like Hebrew and Arabic; aligns either the top of the drop down
-			//				with the top of the anchor, or the bottom of the drop down with bottom of the anchor.
-			//			* before-centered: centers drop down to the left of the anchor node/widget, or to the right
-			//				 in the case of RTL scripts like Hebrew and Arabic
-			//			* after-centered: centers drop down to the right of the anchor node/widget, or to the left
-			//				 in the case of RTL scripts like Hebrew and Arabic
-			//			* above-centered: drop down is centered above anchor node
-			//			* above: drop down goes above anchor node, left sides aligned
-			//			* above-alt: drop down goes above anchor node, right sides aligned
-			//			* below-centered: drop down is centered above anchor node
-			//			* below: drop down goes below anchor node
-			//			* below-alt: drop down goes below anchor node, right sides aligned
 			//
+			//		- before: places drop down to the left of the anchor node/widget, or to the right in the case
+			//			of RTL scripts like Hebrew and Arabic; aligns either the top of the drop down
+			//			with the top of the anchor, or the bottom of the drop down with bottom of the anchor.
+			//		- after: places drop down to the right of the anchor node/widget, or to the left in the case
+			//			of RTL scripts like Hebrew and Arabic; aligns either the top of the drop down
+			//			with the top of the anchor, or the bottom of the drop down with bottom of the anchor.
+			//		- before-centered: centers drop down to the left of the anchor node/widget, or to the right
+			//			in the case of RTL scripts like Hebrew and Arabic
+			//		- after-centered: centers drop down to the right of the anchor node/widget, or to the left
+			//			in the case of RTL scripts like Hebrew and Arabic
+			//		- above-centered: drop down is centered above anchor node
+			//		- above: drop down goes above anchor node, left sides aligned
+			//		- above-alt: drop down goes above anchor node, right sides aligned
+			//		- below-centered: drop down is centered above anchor node
+			//		- below: drop down goes below anchor node
+			//		- below-alt: drop down goes below anchor node, right sides aligned
 			// layoutNode: Function(node, aroundNodeCorner, nodeCorner)
 			//		For things like tooltip, they are displayed differently (and have different dimensions)
 			//		based on their orientation relative to the parent.	 This adjusts the popup based on orientation.
-			//
 			// leftToRight:
 			//		True if widget is LTR, false if widget is RTL.   Affects the behavior of "above" and "below"
 			//		positions slightly.
-			//
 			// example:
 			//	|	placeAroundNode(node, aroundNode, {'BL':'TL', 'TR':'BR'});
 			//		This will try to position node such that node's top-left corner is at the same position
 			//		as the bottom left corner of the aroundNode (ie, put node below
 			//		aroundNode, with left edges aligned).	If that fails it will try to put
-			// 		the bottom-right corner of node where the top right corner of aroundNode is
+			//		the bottom-right corner of node where the top right corner of aroundNode is
 			//		(ie, put node above aroundNode, with right edges aligned)
 			//
 
-			// if around is a DOMNode (or DOMNode id), convert to coordinates
-			var aroundNodePos = (typeof anchor == "string" || "offsetWidth" in anchor)
-				? domGeometry.position(anchor, true)
-				: anchor;
+			// If around is a DOMNode (or DOMNode id), convert to coordinates.
+			var aroundNodePos;
+			if(typeof anchor == "string" || "offsetWidth" in anchor){
+				aroundNodePos = domGeometry.position(anchor, true);
 
-			// Adjust anchor positioning for the case that a parent node has overflw hidden, therefore cuasing the anchor not to be completely visible
+				// For above and below dropdowns, subtract width of border so that popup and aroundNode borders
+				// overlap, preventing a double-border effect.  Unfortunately, difficult to measure the border
+				// width of either anchor or popup because in both cases the border may be on an inner node.
+				if(/^(above|below)/.test(positions[0])){
+					var anchorBorder = domGeometry.getBorderExtents(anchor),
+						anchorChildBorder = anchor.firstChild ? domGeometry.getBorderExtents(anchor.firstChild) : {t:0,l:0,b:0,r:0},
+						nodeBorder =  domGeometry.getBorderExtents(node),
+						nodeChildBorder = node.firstChild ? domGeometry.getBorderExtents(node.firstChild) : {t:0,l:0,b:0,r:0};
+					aroundNodePos.y += Math.min(anchorBorder.t + anchorChildBorder.t, nodeBorder.t + nodeChildBorder.t);
+					aroundNodePos.h -=  Math.min(anchorBorder.t + anchorChildBorder.t, nodeBorder.t+ nodeChildBorder.t) +
+						Math.min(anchorBorder.b + anchorChildBorder.b, nodeBorder.b + nodeChildBorder.b);
+				}
+			}else{
+				aroundNodePos = anchor;
+			}
+
+			// Compute position and size of visible part of anchor (it may be partially hidden by ancestor nodes w/scrollbars)
 			if(anchor.parentNode){
+				// ignore nodes between position:relative and position:absolute
+				var sawPosAbsolute = domStyle.getComputedStyle(anchor).position == "absolute";
 				var parent = anchor.parentNode;
 				while(parent && parent.nodeType == 1 && parent.nodeName != "BODY"){  //ignoring the body will help performance
-					var parentPos = domGeometry.position(parent, true);
-					var parentStyleOverflow = domStyle.getComputedStyle(parent).overflow;
-					if(parentStyleOverflow == "hidden" || parentStyleOverflow == "auto" || parentStyleOverflow == "scroll"){
+					var parentPos = domGeometry.position(parent, true),
+						pcs = domStyle.getComputedStyle(parent);
+					if(/relative|absolute/.test(pcs.position)){
+						sawPosAbsolute = false;
+					}
+					if(!sawPosAbsolute && /hidden|auto|scroll/.test(pcs.overflow)){
 						var bottomYCoord = Math.min(aroundNodePos.y + aroundNodePos.h, parentPos.y + parentPos.h);
 						var rightXCoord = Math.min(aroundNodePos.x + aroundNodePos.w, parentPos.x + parentPos.w);
 						aroundNodePos.x = Math.max(aroundNodePos.x, parentPos.x);
 						aroundNodePos.y = Math.max(aroundNodePos.y, parentPos.y);
 						aroundNodePos.h = bottomYCoord - aroundNodePos.y;
 						aroundNodePos.w = rightXCoord - aroundNodePos.x;
-					}	
+					}
+					if(pcs.position == "absolute"){
+						sawPosAbsolute = true;
+					}
 					parent = parent.parentNode;
 				}
 			}			
@@ -293,7 +313,7 @@ define([
 			var x = aroundNodePos.x,
 				y = aroundNodePos.y,
 				width = "w" in aroundNodePos ? aroundNodePos.w : (aroundNodePos.w = aroundNodePos.width),
-				height = "h" in aroundNodePos ? aroundNodePos.h : (kernel.deprecated("place.around: dijit.place.__Rectangle: { x:"+x+", y:"+y+", height:"+aroundNodePos.height+", width:"+width+" } has been deprecated.  Please use { x:"+x+", y:"+y+", h:"+aroundNodePos.height+", w:"+width+" }", "", "2.0"), aroundNodePos.h = aroundNodePos.height);
+				height = "h" in aroundNodePos ? aroundNodePos.h : (kernel.deprecated("place.around: dijit/place.__Rectangle: { x:"+x+", y:"+y+", height:"+aroundNodePos.height+", width:"+width+" } has been deprecated.  Please use { x:"+x+", y:"+y+", h:"+aroundNodePos.height+", w:"+width+" }", "", "2.0"), aroundNodePos.h = aroundNodePos.height);
 
 			// Convert positions arguments into choices argument for _place()
 			var choices = [];
@@ -306,12 +326,12 @@ define([
 							'L': x,
 							'R': x + width,
 							'M': x + (width >> 1)
-						   }[aroundCorner.charAt(1)],
+						}[aroundCorner.charAt(1)],
 						y: {
 							'T': y,
 							'B': y + height,
 							'M': y + (height >> 1)
-						   }[aroundCorner.charAt(0)]
+						}[aroundCorner.charAt(0)]
 					}
 				})
 			}
@@ -355,7 +375,7 @@ define([
 						break;
 					default:
 						// To assist dijit/_base/place, accept arguments of type {aroundCorner: "BL", corner: "TL"}.
-						// Not meant to be used directly.
+						// Not meant to be used directly.  Remove for 2.0.
 						push(pos.aroundCorner, pos.corner);
 				}
 			});
@@ -365,5 +385,26 @@ define([
 
 			return position;
 		}
-	});
+	};
+
+	/*=====
+	place.__Position = {
+		// x: Integer
+		//		horizontal coordinate in pixels, relative to document body
+		// y: Integer
+		//		vertical coordinate in pixels, relative to document body
+	};
+	place.__Rectangle = {
+		// x: Integer
+		//		horizontal offset in pixels, relative to document body
+		// y: Integer
+		//		vertical offset in pixels, relative to document body
+		// w: Integer
+		//		width in pixels.   Can also be specified as "width" for backwards-compatibility.
+		// h: Integer
+		//		height in pixels.   Can also be specified as "height" for backwards-compatibility.
+	};
+	=====*/
+
+	return dijit.place = place;	// setting dijit.place for back-compat, remove for 2.0
 });
diff --git a/dijit/popup.js b/dijit/popup.js
index 0e4387f..714aca5 100644
--- a/dijit/popup.js
+++ b/dijit/popup.js
@@ -1,146 +1,91 @@
 define([
 	"dojo/_base/array", // array.forEach array.some
 	"dojo/aspect",
-	"dojo/_base/connect",	// connect._keypress
 	"dojo/_base/declare", // declare
 	"dojo/dom", // dom.isDescendant
 	"dojo/dom-attr", // domAttr.set
 	"dojo/dom-construct", // domConstruct.create domConstruct.destroy
 	"dojo/dom-geometry", // domGeometry.isBodyLtr
 	"dojo/dom-style", // domStyle.set
-	"dojo/_base/event", // event.stop
+	"dojo/has", // has("config-bgIframe")
 	"dojo/keys",
 	"dojo/_base/lang", // lang.hitch
 	"dojo/on",
-	"dojo/_base/sniff", // has("ie") has("mozilla")
-	"dojo/_base/window", // win.body
 	"./place",
 	"./BackgroundIframe",
-	"."	// dijit (defining dijit.popup to match API doc)
-], function(array, aspect, connect, declare, dom, domAttr, domConstruct, domGeometry, domStyle, event, keys, lang, on, has, win,
-			place, BackgroundIframe, dijit){
+	"./Viewport",
+	"./main"    // dijit (defining dijit.popup to match API doc)
+], function(array, aspect, declare, dom, domAttr, domConstruct, domGeometry, domStyle, has, keys, lang, on,
+			place, BackgroundIframe, Viewport, dijit){
 
 	// module:
 	//		dijit/popup
-	// summary:
-	//		Used to show drop downs (ex: the select list of a ComboBox)
-	//		or popups (ex: right-click context menus)
-
 
 	/*=====
-	dijit.popup.__OpenArgs = function(){
-		// popup: Widget
-		//		widget to display
-		// parent: Widget
-		//		the button etc. that is displaying this popup
-		// around: DomNode
-		//		DOM node (typically a button); place popup relative to this node.  (Specify this *or* "x" and "y" parameters.)
-		// x: Integer
-		//		Absolute horizontal position (in pixels) to place node at.  (Specify this *or* "around" parameter.)
-		// y: Integer
-		//		Absolute vertical position (in pixels) to place node at.  (Specify this *or* "around" parameter.)
-		// orient: Object|String
-		//		When the around parameter is specified, orient should be a list of positions to try, ex:
-		//	|	[ "below", "above" ]
-		//		For backwards compatibility it can also be an (ordered) hash of tuples of the form
-		//		(around-node-corner, popup-node-corner), ex:
-		//	|	{ "BL": "TL", "TL": "BL" }
-		//		where BL means "bottom left" and "TL" means "top left", etc.
-		//
-		//		dijit.popup.open() tries to position the popup according to each specified position, in order,
-		//		until the popup appears fully within the viewport.
-		//
-		//		The default value is ["below", "above"]
-		//
-		//		When an (x,y) position is specified rather than an around node, orient is either
-		//		"R" or "L".  R (for right) means that it tries to put the popup to the right of the mouse,
-		//		specifically positioning the popup's top-right corner at the mouse position, and if that doesn't
-		//		fit in the viewport, then it tries, in order, the bottom-right corner, the top left corner,
-		//		and the top-right corner.
-		// onCancel: Function
-		//		callback when user has canceled the popup by
-		//			1. hitting ESC or
-		//			2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog);
-		//			   i.e. whenever popupWidget.onCancel() is called, args.onCancel is called
-		// onClose: Function
-		//		callback whenever this popup is closed
-		// onExecute: Function
-		//		callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only)
-		// padding: dijit.__Position
-		//		adding a buffer around the opening position. This is only useful when around is not set.
-		this.popup = popup;
-		this.parent = parent;
-		this.around = around;
-		this.x = x;
-		this.y = y;
-		this.orient = orient;
-		this.onCancel = onCancel;
-		this.onClose = onClose;
-		this.onExecute = onExecute;
-		this.padding = padding;
+	 var __OpenArgs = {
+		 // popup: Widget
+		 //		widget to display
+		 // parent: Widget
+		 //		the button etc. that is displaying this popup
+		 // around: DomNode
+		 //		DOM node (typically a button); place popup relative to this node.  (Specify this *or* "x" and "y" parameters.)
+		 // x: Integer
+		 //		Absolute horizontal position (in pixels) to place node at.  (Specify this *or* "around" parameter.)
+		 // y: Integer
+		 //		Absolute vertical position (in pixels) to place node at.  (Specify this *or* "around" parameter.)
+		 // orient: Object|String
+		 //		When the around parameter is specified, orient should be a list of positions to try, ex:
+		 //	|	[ "below", "above" ]
+		 //		For backwards compatibility it can also be an (ordered) hash of tuples of the form
+		 //		(around-node-corner, popup-node-corner), ex:
+		 //	|	{ "BL": "TL", "TL": "BL" }
+		 //		where BL means "bottom left" and "TL" means "top left", etc.
+		 //
+		 //		dijit/popup.open() tries to position the popup according to each specified position, in order,
+		 //		until the popup appears fully within the viewport.
+		 //
+		 //		The default value is ["below", "above"]
+		 //
+		 //		When an (x,y) position is specified rather than an around node, orient is either
+		 //		"R" or "L".  R (for right) means that it tries to put the popup to the right of the mouse,
+		 //		specifically positioning the popup's top-right corner at the mouse position, and if that doesn't
+		 //		fit in the viewport, then it tries, in order, the bottom-right corner, the top left corner,
+		 //		and the top-right corner.
+		 // onCancel: Function
+		 //		callback when user has canceled the popup by:
+		 //
+		 //		1. hitting ESC or
+		 //		2. by using the popup widget's proprietary cancel mechanism (like a cancel button in a dialog);
+		 //		   i.e. whenever popupWidget.onCancel() is called, args.onCancel is called
+		 // onClose: Function
+		 //		callback whenever this popup is closed
+		 // onExecute: Function
+		 //		callback when user "executed" on the popup/sub-popup by selecting a menu choice, etc. (top menu only)
+		 // padding: place.__Position
+		 //		adding a buffer around the opening position. This is only useful when around is not set.
+		 // maxHeight: Integer
+		 //		The max height for the popup.  Any popup taller than this will have scrollbars.
+		 //		Set to Infinity for no max height.  Default is to limit height to available space in viewport,
+		 //		above or below the aroundNode or specified x/y position.
+	 };
+	 =====*/
+
+	function destroyWrapper(){
+		// summary:
+		//		Function to destroy wrapper when popup widget is destroyed.
+		//		Left in this scope to avoid memory leak on IE8 on refresh page, see #15206.
+		if(this._popupWrapper){
+			domConstruct.destroy(this._popupWrapper);
+			delete this._popupWrapper;
+		}
 	}
-	=====*/
 
-	/*=====
-	dijit.popup = {
+	var PopupManager = declare(null, {
 		// summary:
 		//		Used to show drop downs (ex: the select list of a ComboBox)
 		//		or popups (ex: right-click context menus).
-		//
-		//		Access via require(["dijit/popup"], function(popup){ ... }).
-
-		moveOffScreen: function(widget){
-			// summary:
-			//		Moves the popup widget off-screen.
-			//		Do not use this method to hide popups when not in use, because
-			//		that will create an accessibility issue: the offscreen popup is
-			//		still in the tabbing order.
-			// widget: dijit._WidgetBase
-			//		The widget
-		},
-
-		hide: function(widget){
-			// summary:
-			//		Hide this popup widget (until it is ready to be shown).
-			//		Initialization for widgets that will be used as popups
-			//
-			// 		Also puts widget inside a wrapper DIV (if not already in one)
-			//
-			//		If popup widget needs to layout it should
-			//		do so when it is made visible, and popup._onShow() is called.
-			// widget: dijit._WidgetBase
-			//		The widget
-		},
 
-		open: function(args){
-			// summary:
-			//		Popup the widget at the specified position
-			// example:
-			//		opening at the mouse position
-			//		|		popup.open({popup: menuWidget, x: evt.pageX, y: evt.pageY});
-			// example:
-			//		opening the widget as a dropdown
-			//		|		popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...}});
-			//
-			//		Note that whatever widget called dijit.popup.open() should also listen to its own _onBlur callback
-			//		(fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
-			// args: dijit.popup.__OpenArgs
-			//		Parameters
-			return {};	// Object specifying which position was chosen
-		},
-
-		close: function(popup){
-			// summary:
-			//		Close specified popup and any popups that it parented.
-			//		If no popup is specified, closes all popups.
-			// widget: dijit._WidgetBase?
-			//		The widget, optional
-		}
-	};
-	=====*/
-
-	var PopupManager = declare(null, {
-		// _stack: dijit._Widget[]
+		// _stack: dijit/_WidgetBase[]
 		//		Stack of currently popped up widgets.
 		//		(someone opened _stack[0], and then it opened _stack[1], etc.)
 		_stack: [],
@@ -152,6 +97,34 @@ define([
 
 		_idGen: 1,
 
+		_repositionAll: function(){
+			// summary:
+			//		If screen has been scrolled, reposition all the popups in the stack.
+			//		Then set timer to check again later.
+
+			if(this._firstAroundNode){	// guard for when clearTimeout() on IE doesn't work
+				var oldPos = this._firstAroundPosition,
+					newPos = domGeometry.position(this._firstAroundNode, true),
+					dx = newPos.x - oldPos.x,
+					dy = newPos.y - oldPos.y;
+
+				if(dx || dy){
+					this._firstAroundPosition = newPos;
+					for(var i = 0; i < this._stack.length; i++){
+						var style = this._stack[i].wrapper.style;
+						style.top = (parseInt(style.top, 10) + dy) + "px";
+						if(style.right == "auto"){
+							style.left = (parseInt(style.left, 10) + dx) + "px";
+						}else{
+							style.right = (parseInt(style.right, 10) - dx) + "px";
+						}
+					}
+				}
+
+				this._aroundMoveListener = setTimeout(lang.hitch(this, "_repositionAll"), dx || dy ? 10 : 50);
+			}
+		},
+
 		_createWrapper: function(/*Widget*/ widget){
 			// summary:
 			//		Initialization for widgets that will be used as popups.
@@ -165,11 +138,12 @@ define([
 				// Create wrapper <div> for when this widget [in the future] will be used as a popup.
 				// This is done early because of IE bugs where creating/moving DOM nodes causes focus
 				// to go wonky, see tests/robot/Toolbar.html to reproduce
-				wrapper = domConstruct.create("div",{
-					"class":"dijitPopup",
-					style:{ display: "none"},
-					role: "presentation"
-				}, win.body());
+				wrapper = domConstruct.create("div", {
+					"class": "dijitPopup",
+					style: { display: "none"},
+					role: "region",
+					"aria-label": widget["aria-label"] || widget.label || widget.name || widget.id
+				}, widget.ownerDocumentBody);
 				wrapper.appendChild(node);
 
 				var s = node.style;
@@ -179,10 +153,7 @@ define([
 				s.top = "0px";
 
 				widget._popupWrapper = wrapper;
-				aspect.after(widget, "destroy", function(){
-					domConstruct.destroy(wrapper);
-					delete widget._popupWrapper;
-				});
+				aspect.after(widget, "destroy", destroyWrapper, true);
 			}
 
 			return wrapper;
@@ -198,11 +169,18 @@ define([
 			// Create wrapper if not already there
 			var wrapper = this._createWrapper(widget);
 
-			domStyle.set(wrapper, {
-				visibility: "hidden",
-				top: "-9999px",		// prevent transient scrollbar causing misalign (#5776), and initial flash in upper left (#10111)
-				display: ""
-			});
+			// Besides setting visibility:hidden, move it out of the viewport, see #5776, #10111, #13604
+			var ltr = domGeometry.isBodyLtr(widget.ownerDocument),
+				style = {
+					visibility: "hidden",
+					top: "-9999px",
+					display: ""
+				};
+			style[ltr ? "left" : "right"] = "-9999px";
+			style[ltr ? "right" : "left"] = "auto";
+			domStyle.set(wrapper, style);
+
+			return wrapper;
 		},
 
 		hide: function(/*Widget*/ widget){
@@ -210,7 +188,7 @@ define([
 			//		Hide this popup widget (until it is ready to be shown).
 			//		Initialization for widgets that will be used as popups
 			//
-			// 		Also puts widget inside a wrapper DIV (if not already in one)
+			//		Also puts widget inside a wrapper DIV (if not already in one)
 			//
 			//		If popup widget needs to layout it should
 			//		do so when it is made visible, and popup._onShow() is called.
@@ -218,7 +196,18 @@ define([
 			// Create wrapper if not already there
 			var wrapper = this._createWrapper(widget);
 
-			domStyle.set(wrapper, "display", "none");
+			domStyle.set(wrapper, {
+				display: "none",
+				height: "auto",		// Open may have limited the height to fit in the viewport
+				overflow: "visible",
+				border: ""			// Open() may have moved border from popup to wrapper.
+			});
+
+			// Open() may have moved border from popup to wrapper.  Move it back.
+			var node = widget.domNode;
+			if("_originalStyle" in node){
+				node.style.cssText = node._originalStyle;
+			}
 		},
 
 		getTopPopup: function(){
@@ -226,13 +215,13 @@ define([
 			//		Compute the closest ancestor popup that's *not* a child of another popup.
 			//		Ex: For a TooltipDialog with a button that spawns a tree of menus, find the popup of the button.
 			var stack = this._stack;
-			for(var pi=stack.length-1; pi > 0 && stack[pi].parent === stack[pi-1].widget; pi--){
+			for(var pi = stack.length - 1; pi > 0 && stack[pi].parent === stack[pi - 1].widget; pi--){
 				/* do nothing, just trying to get right value for pi */
 			}
 			return stack[pi];
 		},
 
-		open: function(/*dijit.popup.__OpenArgs*/ args){
+		open: function(/*__OpenArgs*/ args){
 			// summary:
 			//		Popup the widget at the specified position
 			//
@@ -244,62 +233,100 @@ define([
 			//		opening the widget as a dropdown
 			//		|		popup.open({parent: this, popup: menuWidget, around: this.domNode, onClose: function(){...}});
 			//
-			//		Note that whatever widget called dijit.popup.open() should also listen to its own _onBlur callback
+			//		Note that whatever widget called dijit/popup.open() should also listen to its own _onBlur callback
 			//		(fired from _base/focus.js) to know that focus has moved somewhere else and thus the popup should be closed.
 
 			var stack = this._stack,
 				widget = args.popup,
+				node = widget.domNode,
 				orient = args.orient || ["below", "below-alt", "above", "above-alt"],
-				ltr = args.parent ? args.parent.isLeftToRight() : domGeometry.isBodyLtr(),
+				ltr = args.parent ? args.parent.isLeftToRight() : domGeometry.isBodyLtr(widget.ownerDocument),
 				around = args.around,
-				id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+this._idGen++);
+				id = (args.around && args.around.id) ? (args.around.id + "_dropdown") : ("popup_" + this._idGen++);
 
 			// If we are opening a new popup that isn't a child of a currently opened popup, then
 			// close currently opened popup(s).   This should happen automatically when the old popups
 			// gets the _onBlur() event, except that the _onBlur() event isn't reliable on IE, see [22198].
-			while(stack.length && (!args.parent || !dom.isDescendant(args.parent.domNode, stack[stack.length-1].widget.domNode))){
-				this.close(stack[stack.length-1].widget);
+			while(stack.length && (!args.parent || !dom.isDescendant(args.parent.domNode, stack[stack.length - 1].widget.domNode))){
+				this.close(stack[stack.length - 1].widget);
 			}
 
-			// Get pointer to popup wrapper, and create wrapper if it doesn't exist
-			var wrapper = this._createWrapper(widget);
+			// Get pointer to popup wrapper, and create wrapper if it doesn't exist.  Remove display:none (but keep
+			// off screen) so we can do sizing calculations.
+			var wrapper = this.moveOffScreen(widget);
+
+			if(widget.startup && !widget._started){
+				widget.startup(); // this has to be done after being added to the DOM
+			}
 
+			// Limit height to space available in viewport either above or below aroundNode (whichever side has more
+			// room), adding scrollbar if necessary. Can't add scrollbar to widget because it may be a <table> (ex:
+			// dijit/Menu), so add to wrapper, and then move popup's border to wrapper so scroll bar inside border.
+			var maxHeight, popupSize = domGeometry.position(node);
+			if("maxHeight" in args && args.maxHeight != -1){
+				maxHeight = args.maxHeight || Infinity;	// map 0 --> infinity for back-compat of _HasDropDown.maxHeight
+			}else{
+				var viewport = Viewport.getEffectiveBox(this.ownerDocument),
+					aroundPos = around ? domGeometry.position(around, false) : {y: args.y - (args.padding||0), h: (args.padding||0) * 2};
+				maxHeight = Math.floor(Math.max(aroundPos.y, viewport.h - (aroundPos.y + aroundPos.h)));
+			}
+			if(popupSize.h > maxHeight){
+				// Get style of popup's border.  Unfortunately domStyle.get(node, "border") doesn't work on FF or IE,
+				// and domStyle.get(node, "borderColor") etc. doesn't work on FF, so need to use fully qualified names.
+				var cs = domStyle.getComputedStyle(node),
+					borderStyle = cs.borderLeftWidth + " " + cs.borderLeftStyle + " " + cs.borderLeftColor;
+				domStyle.set(wrapper, {
+					overflowY: "scroll",
+					height: maxHeight + "px",
+					border: borderStyle	// so scrollbar is inside border
+				});
+				node._originalStyle = node.style.cssText;
+				node.style.border = "none";
+			}
 
 			domAttr.set(wrapper, {
 				id: id,
 				style: {
 					zIndex: this._beginZIndex + stack.length
 				},
-				"class": "dijitPopup " + (widget.baseClass || widget["class"] || "").split(" ")[0] +"Popup",
+				"class": "dijitPopup " + (widget.baseClass || widget["class"] || "").split(" ")[0] + "Popup",
 				dijitPopupParent: args.parent ? args.parent.id : ""
 			});
 
-			if(has("ie") || has("mozilla")){
-				if(!widget.bgIframe){
-					// setting widget.bgIframe triggers cleanup in _Widget.destroy()
-					widget.bgIframe = new BackgroundIframe(wrapper);
-				}
+			if(stack.length == 0 && around){
+				// First element on stack. Save position of aroundNode and setup listener for changes to that position.
+				this._firstAroundNode = around;
+				this._firstAroundPosition = domGeometry.position(around, true);
+				this._aroundMoveListener = setTimeout(lang.hitch(this, "_repositionAll"), 50);
+			}
+
+			if(has("config-bgIframe") && !widget.bgIframe){
+				// setting widget.bgIframe triggers cleanup in _WidgetBase.destroyRendering()
+				widget.bgIframe = new BackgroundIframe(wrapper);
 			}
 
 			// position the wrapper node and make it visible
-			var best = around ?
-				place.around(wrapper, around, orient, ltr, widget.orient ? lang.hitch(widget, "orient") : null) :
-				place.at(wrapper, args, orient == 'R' ? ['TR','BR','TL','BL'] : ['TL','BL','TR','BR'], args.padding);
+			var layoutFunc = widget.orient ? lang.hitch(widget, "orient") : null,
+				best = around ?
+					place.around(wrapper, around, orient, ltr, layoutFunc) :
+					place.at(wrapper, args, orient == 'R' ? ['TR', 'BR', 'TL', 'BL'] : ['TL', 'BL', 'TR', 'BR'], args.padding,
+						layoutFunc);
 
-			wrapper.style.display = "";
 			wrapper.style.visibility = "visible";
-			widget.domNode.style.visibility = "visible";	// counteract effects from _HasDropDown
+			node.style.visibility = "visible";	// counteract effects from _HasDropDown
 
 			var handlers = [];
 
 			// provide default escape and tab key handling
 			// (this will work for any widget, not just menu)
-			handlers.push(on(wrapper, connect._keypress, lang.hitch(this, function(evt){
-				if(evt.charOrCode == keys.ESCAPE && args.onCancel){
-					event.stop(evt);
+			handlers.push(on(wrapper, "keydown", lang.hitch(this, function(evt){
+				if(evt.keyCode == keys.ESCAPE && args.onCancel){
+					evt.stopPropagation();
+					evt.preventDefault();
 					args.onCancel();
-				}else if(evt.charOrCode === keys.TAB){
-					event.stop(evt);
+				}else if(evt.keyCode == keys.TAB){
+					evt.stopPropagation();
+					evt.preventDefault();
 					var topPopup = this.getTopPopup();
 					if(topPopup && topPopup.onCancel){
 						topPopup.onCancel();
@@ -322,6 +349,7 @@ define([
 
 			stack.push({
 				widget: widget,
+				wrapper: wrapper,
 				parent: args.parent,
 				onExecute: args.onExecute,
 				onCancel: args.onCancel,
@@ -349,19 +377,25 @@ define([
 			// a popup would cause others to close too.  Thus if we are trying to close B in [A,B,C]
 			// closing C might close B indirectly and then the while() condition will run where stack==[A]...
 			// so the while condition is constructed defensively.
-			while((popup && array.some(stack, function(elem){return elem.widget == popup;})) ||
+			while((popup && array.some(stack, function(elem){
+				return elem.widget == popup;
+			})) ||
 				(!popup && stack.length)){
 				var top = stack.pop(),
 					widget = top.widget,
 					onClose = top.onClose;
 
 				if(widget.onClose){
-					// TODO: in 2.0 standardize onHide() (used by StackContainer) and onClose() (used here)
+					// TODO: in 2.0 standardize onHide() (used by StackContainer) and onClose() (used here).
+					// Actually, StackContainer also calls onClose(), but to mean that the pane is being deleted
+					// (i.e. that the TabContainer's tab's [x] icon was clicked)
 					widget.onClose();
 				}
 
 				var h;
-				while(h = top.handlers.pop()){ h.remove(); }
+				while(h = top.handlers.pop()){
+					h.remove();
+				}
 
 				// Hide the widget and it's wrapper unless it has already been destroyed in above onClose() etc.
 				if(widget && widget.domNode){
@@ -372,6 +406,11 @@ define([
 					onClose();
 				}
 			}
+
+			if(stack.length == 0 && this._aroundMoveListener){
+				clearTimeout(this._aroundMoveListener);
+				this._firstAroundNode = this._firstAroundPosition = this._aroundMoveListener = null;
+			}
 		}
 	});
 
diff --git a/dijit/registry.js b/dijit/registry.js
index cce4ef5..55f2c11 100644
--- a/dijit/registry.js
+++ b/dijit/registry.js
@@ -1,32 +1,28 @@
 define([
 	"dojo/_base/array", // array.forEach array.map
-	"dojo/_base/sniff", // has("ie")
-	"dojo/_base/unload", // unload.addOnWindowUnload
+	"dojo/sniff", // has("ie")
 	"dojo/_base/window", // win.body
-	"."	// dijit._scopeName
-], function(array, has, unload, win, dijit){
+	"./main"	// dijit._scopeName
+], function(array, has, win, dijit){
 
 	// module:
 	//		dijit/registry
-	// summary:
-	//		Registry of existing widget on page, plus some utility methods.
-	//		Must be accessed through AMD api, ex:
-	//		require(["dijit/registry"], function(registry){ registry.byId("foo"); })
 
 	var _widgetTypeCtr = {}, hash = {};
 
 	var registry =  {
 		// summary:
-		//		A set of widgets indexed by id
+		//		Registry of existing widget on page, plus some utility methods.
 
+		// length: Number
+		//		Number of registered widgets
 		length: 0,
 
-		add: function(/*dijit._Widget*/ widget){
+		add: function(widget){
 			// summary:
 			//		Add a widget to the registry. If a duplicate ID is detected, a error is thrown.
-			//
-			// widget: dijit._Widget
-			//		Any dijit._Widget subclass.
+			// widget: dijit/_WidgetBase
+			//		Any dijit/_WidgetBase subclass.
 			if(hash[widget.id]){
 				throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
 			}
@@ -48,13 +44,13 @@ define([
 			// summary:
 			//		Find a widget by it's id.
 			//		If passed a widget then just returns the widget.
-			return typeof id == "string" ? hash[id] : id;	// dijit._Widget
+			return typeof id == "string" ? hash[id] : id;	// dijit/_WidgetBase
 		},
 
 		byNode: function(/*DOMNode*/ node){
 			// summary:
 			//		Returns the widget corresponding to the given DOMNode
-			return hash[node.getAttribute("widgetId")]; // dijit._Widget
+			return hash[node.getAttribute("widgetId")]; // dijit/_WidgetBase
 		},
 
 		toArray: function(){
@@ -63,13 +59,13 @@ define([
 			//
 			// example:
 			//		Work with the widget .domNodes in a real Array
-			//		|	array.map(dijit.registry.toArray(), function(w){ return w.domNode; });
+			//		|	array.map(registry.toArray(), function(w){ return w.domNode; });
 
 			var ar = [];
 			for(var id in hash){
 				ar.push(hash[id]);
 			}
-			return ar;	// dijit._Widget[]
+			return ar;	// dijit/_WidgetBase[]
 		},
 
 		getUniqueId: function(/*String*/widgetType){
@@ -85,10 +81,14 @@ define([
 			return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String
 		},
 
-		findWidgets: function(/*DomNode*/ root){
+		findWidgets: function(root, skipNode){
 			// summary:
 			//		Search subtree under root returning widgets found.
 			//		Doesn't search for nested widgets (ie, widgets inside other widgets).
+			// root: DOMNode
+			//		Node to search under.
+			// skipNode: DOMNode
+			//		If specified, don't search beneath this node (usually containerNode).
 
 			var outAry = [];
 
@@ -101,7 +101,7 @@ define([
 							if(widget){	// may be null on page w/multiple dojo's loaded
 								outAry.push(widget);
 							}
-						}else{
+						}else if(node !== skipNode){
 							getChildrenHelper(node);
 						}
 					}
@@ -140,7 +140,7 @@ define([
 			//		Returns the widget whose DOM tree contains the specified DOMNode, or null if
 			//		the node is not contained within the DOM tree of any widget
 			while(node){
-				var id = node.getAttribute && node.getAttribute("widgetId");
+				var id = node.nodeType == 1 && node.getAttribute("widgetId");
 				if(id){
 					return hash[id];
 				}
@@ -154,20 +154,6 @@ define([
 		_hash: hash
 	};
 
-	if(has("ie")){
-		// Only run _destroyAll() for IE because we think it's only necessary in that case,
-		// and because it causes problems on FF.  See bug #3531 for details.
-		unload.addOnWindowUnload(function(){
-			registry._destroyAll();
-		});
-	}
-
-	/*=====
-	dijit.registry = {
-		// summary:
-		//		A list of widgets on a page.
-	};
-	=====*/
 	dijit.registry = registry;
 
 	return registry;
diff --git a/dijit/resources/_modules.js b/dijit/resources/_modules.js
deleted file mode 100644
index e75636f..0000000
--- a/dijit/resources/_modules.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/*=====
-// dijit fallback for key summaries otherwise not covered by the doc parser
-
-dijit.demos = {
-	// summary:
-	//		Home of the official dijit demo code
-};
-
-dijit.form = {
-	// summary:
-	//		Form and input related widgets
-};
-
-dijit.layout = {
-	// summary:
-	//		Layout related widgets
-};
-=====*/
diff --git a/dijit/robot.js b/dijit/robot.js
index a1d43b5..b6ce901 100644
--- a/dijit/robot.js
+++ b/dijit/robot.js
@@ -1,11 +1,8 @@
 define([
-	".",
 	"dojo/robot"
-], function(dijit){
+], function(){
 	// module:
 	//		dijit/robot
 	// summary:
 	//		Used to have code needed by robot test harness, but no longer
-
-	return dijit;
 });
diff --git a/dijit/robotx.js b/dijit/robotx.js
index d42fff7..5ee25a4 100644
--- a/dijit/robotx.js
+++ b/dijit/robotx.js
@@ -1,34 +1,25 @@
 define([
-	"dojo/_base/kernel", // dojo.experimental lang.mixin
-	".",
-	"dojo/_base/lang", // dojo.experimental lang.mixin
-	"./robot",
-	"dojo/robotx",
-	"dojo/_base/window" // dojo.global
-], function(dojo, dijit_, lang){
+	"dojo/_base/kernel", // kernel.experimental
+	"dojo/robotx"		// includes doh/robot, dojo/robot, and dojo/robotx, all of which affect and return doh/robot module
+], function(kernel, robot){
 
 	// module:
 	//		dijit/robotx
 	// summary:
-	//		Code needed by robot test harness
+	//		Loads doh/robot, dojo/robot, dojo/robotx, and
+	//		sets dijit global in main window to point to the dijit loaded in the iframe.
+	//		TODO: Remove for 2.0.    Tests shouldn't reference a dijit global at all, and should load dojo/robotx
+	//		in preference to this file.
 
+	kernel.experimental("dijit.robotx");
 
-	//WARNING: This module depends on GLOBAL dijit being set for v1.5 code; therefore the lexical variable that
-	//references "dijit" has been renamed to "dijit_"
+	var __updateDocument = robot._updateDocument;
 
-	dojo.experimental("dijit.robotx");
-
-	var __updateDocument = doh.robot._updateDocument;
-
-	lang.mixin(doh.robot,{
-		_updateDocument: function(){
-			__updateDocument();
-			var win = dojo.global;
-			if(win["dijit"]){
-				window.dijit = win.dijit; // window reference needed for IE
-			}
+	robot._updateDocument = function(){
+		__updateDocument();
+		var win = kernel.global;
+		if(win.dijit){
+			window.dijit = win.dijit; // window reference needed for IE
 		}
-	});
-
-	return dijit_;
+	};
 });
diff --git a/dijit/selection.js b/dijit/selection.js
new file mode 100644
index 0000000..3cea725
--- /dev/null
+++ b/dijit/selection.js
@@ -0,0 +1,525 @@
+define([
+	"dojo/_base/array",
+	"dojo/dom", // dom.byId
+	"dojo/_base/lang",
+	"dojo/sniff", // has("ie") has("opera")
+	"dojo/_base/window",
+	"dijit/focus"
+], function(array, dom, lang, has, baseWindow, focus){
+
+	// module:
+	//		dijit/selection
+
+	// Note that this class is using feature detection, but doesn't use has() because sometimes on IE the outer window
+	// may be running in standards mode (ie, IE9 mode) but an iframe may be in compatibility mode.   So the code path
+	// used will vary based on the window.
+
+	var SelectionManager = function(win){
+		// summary:
+		//		Class for monitoring / changing the selection (typically highlighted text) in a given window
+		// win: Window
+		//		The window to monitor/adjust the selection on.
+
+		var doc = win.document;
+
+		this.getType = function(){
+			// summary:
+			//		Get the selection type (like doc.select.type in IE).
+			if(doc.getSelection){
+				// W3C path
+				var stype = "text";
+
+				// Check if the actual selection is a CONTROL (IMG, TABLE, HR, etc...).
+				var oSel;
+				try{
+					oSel = win.getSelection();
+				}catch(e){ /*squelch*/ }
+
+				if(oSel && oSel.rangeCount == 1){
+					var oRange = oSel.getRangeAt(0);
+					if(	(oRange.startContainer == oRange.endContainer) &&
+						((oRange.endOffset - oRange.startOffset) == 1) &&
+						(oRange.startContainer.nodeType != 3 /* text node*/)
+						){
+						stype = "control";
+					}
+				}
+				return stype; //String
+			}else{
+				// IE6-8
+				return doc.selection.type.toLowerCase();
+			}
+		};
+
+		this.getSelectedText = function(){
+			// summary:
+			//		Return the text (no html tags) included in the current selection or null if no text is selected
+			if(doc.getSelection){
+				// W3C path
+				var selection = win.getSelection();
+				return selection ? selection.toString() : ""; //String
+			}else{
+				// IE6-8
+				if(this.getType() == 'control'){
+					return null;
+				}
+				return doc.selection.createRange().text;
+			}
+		};
+
+		this.getSelectedHtml = function(){
+			// summary:
+			//		Return the html text of the current selection or null if unavailable
+			if(doc.getSelection){
+				// W3C path
+				var selection = win.getSelection();
+				if(selection && selection.rangeCount){
+					var i;
+					var html = "";
+					for(i = 0; i < selection.rangeCount; i++){
+						//Handle selections spanning ranges, such as Opera
+						var frag = selection.getRangeAt(i).cloneContents();
+						var div = doc.createElement("div");
+						div.appendChild(frag);
+						html += div.innerHTML;
+					}
+					return html; //String
+				}
+				return null;
+			}else{
+				// IE6-8
+				if(this.getType() == 'control'){
+					return null;
+				}
+				return doc.selection.createRange().htmlText;
+			}
+		};
+
+		this.getSelectedElement = function(){
+			// summary:
+			//		Retrieves the selected element (if any), just in the case that
+			//		a single element (object like and image or a table) is
+			//		selected.
+			if(this.getType() == "control"){
+				if(doc.getSelection){
+					// W3C path
+					var selection = win.getSelection();
+					return selection.anchorNode.childNodes[ selection.anchorOffset ];
+				}else{
+					// IE6-8
+					var range = doc.selection.createRange();
+					if(range && range.item){
+						return doc.selection.createRange().item(0);
+					}
+				}
+			}
+			return null;
+		};
+
+		this.getParentElement = function(){
+			// summary:
+			//		Get the parent element of the current selection
+			if(this.getType() == "control"){
+				var p = this.getSelectedElement();
+				if(p){ return p.parentNode; }
+			}else{
+				if(doc.getSelection){
+					var selection = doc.getSelection();
+					if(selection){
+						var node = selection.anchorNode;
+						while(node && (node.nodeType != 1)){ // not an element
+							node = node.parentNode;
+						}
+						return node;
+					}
+				}else{
+					var r = doc.selection.createRange();
+					r.collapse(true);
+					return r.parentElement();
+				}
+			}
+			return null;
+		};
+
+		this.hasAncestorElement = function(/*String*/ tagName /* ... */){
+			// summary:
+			//		Check whether current selection has a  parent element which is
+			//		of type tagName (or one of the other specified tagName)
+			// tagName: String
+			//		The tag name to determine if it has an ancestor of.
+			return this.getAncestorElement.apply(this, arguments) != null; //Boolean
+		};
+
+		this.getAncestorElement = function(/*String*/ tagName /* ... */){
+			// summary:
+			//		Return the parent element of the current selection which is of
+			//		type tagName (or one of the other specified tagName)
+			// tagName: String
+			//		The tag name to determine if it has an ancestor of.
+			var node = this.getSelectedElement() || this.getParentElement();
+			return this.getParentOfType(node, arguments); //DOMNode
+		};
+
+		this.isTag = function(/*DomNode*/ node, /*String[]*/ tags){
+			// summary:
+			//		Function to determine if a node is one of an array of tags.
+			// node:
+			//		The node to inspect.
+			// tags:
+			//		An array of tag name strings to check to see if the node matches.
+			if(node && node.tagName){
+				var _nlc = node.tagName.toLowerCase();
+				for(var i=0; i<tags.length; i++){
+					var _tlc = String(tags[i]).toLowerCase();
+					if(_nlc == _tlc){
+						return _tlc; // String
+					}
+				}
+			}
+			return "";
+		};
+
+		this.getParentOfType = function(/*DomNode*/ node, /*String[]*/ tags){
+			// summary:
+			//		Function to locate a parent node that matches one of a set of tags
+			// node:
+			//		The node to inspect.
+			// tags:
+			//		An array of tag name strings to check to see if the node matches.
+			while(node){
+				if(this.isTag(node, tags).length){
+					return node; // DOMNode
+				}
+				node = node.parentNode;
+			}
+			return null;
+		};
+
+		this.collapse = function(/*Boolean*/ beginning){
+			// summary:
+			//		Function to collapse (clear), the current selection
+			// beginning: Boolean
+			//		Indicates whether to collapse the cursor to the beginning of the selection or end.
+			if(doc.getSelection){
+				// W3C path
+				var selection = win.getSelection();
+				if(selection.removeAllRanges){ // Mozilla
+					if(beginning){
+						selection.collapseToStart();
+					}else{
+						selection.collapseToEnd();
+					}
+				}else{ // Safari
+					// pulled from WebCore/ecma/kjs_window.cpp, line 2536
+					selection.collapse(beginning);
+				}
+			}else{
+				// IE6-8
+				var range = doc.selection.createRange();
+				range.collapse(beginning);
+				range.select();
+			}
+		};
+
+		this.remove = function(){
+			// summary:
+			//		Function to delete the currently selected content from the document.
+			var sel = doc.selection;
+			if(doc.getSelection){
+				// W3C path
+				sel = win.getSelection();
+				sel.deleteFromDocument();
+				return sel; //Selection
+			}else{
+				// IE6-8
+				if(sel.type.toLowerCase() != "none"){
+					sel.clear();
+				}
+				return sel; //Selection
+			}
+		};
+
+		this.selectElementChildren = function(/*DomNode*/ element, /*Boolean?*/ nochangefocus){
+			// summary:
+			//		clear previous selection and select the content of the node
+			//		(excluding the node itself)
+			// element: DOMNode
+			//		The element you wish to select the children content of.
+			// nochangefocus: Boolean
+			//		Indicates if the focus should change or not.
+
+			var range;
+			element = dom.byId(element);
+			if(doc.getSelection){
+				// W3C
+				var selection = win.getSelection();
+				if(has("opera")){
+					//Opera's selectAllChildren doesn't seem to work right
+					//against <body> nodes and possibly others ... so
+					//we use the W3C range API
+					if(selection.rangeCount){
+						range = selection.getRangeAt(0);
+					}else{
+						range = doc.createRange();
+					}
+					range.setStart(element, 0);
+					range.setEnd(element,(element.nodeType == 3) ? element.length : element.childNodes.length);
+					selection.addRange(range);
+				}else{
+					selection.selectAllChildren(element);
+				}
+			}else{
+				// IE6-8
+				range = element.ownerDocument.body.createTextRange();
+				range.moveToElementText(element);
+				if(!nochangefocus){
+					try{
+						range.select(); // IE throws an exception here if the widget is hidden.  See #5439
+					}catch(e){ /* squelch */}
+				}
+			}
+		};
+
+		this.selectElement = function(/*DomNode*/ element, /*Boolean?*/ nochangefocus){
+			// summary:
+			//		clear previous selection and select element (including all its children)
+			// element: DOMNode
+			//		The element to select.
+			// nochangefocus: Boolean
+			//		Boolean indicating if the focus should be changed.  IE only.
+			var range;
+			element = dom.byId(element);	// TODO: remove for 2.0 or sooner, spec listed above doesn't allow for string
+			if(doc.getSelection){
+				// W3C path
+				var selection = doc.getSelection();
+				range = doc.createRange();
+				if(selection.removeAllRanges){ // Mozilla
+					// FIXME: does this work on Safari?
+					if(has("opera")){
+						//Opera works if you use the current range on
+						//the selection if present.
+						if(selection.getRangeAt(0)){
+							range = selection.getRangeAt(0);
+						}
+					}
+					range.selectNode(element);
+					selection.removeAllRanges();
+					selection.addRange(range);
+				}
+			}else{
+				// IE6-8
+				try{
+					var tg = element.tagName ? element.tagName.toLowerCase() : "";
+					if(tg === "img" || tg === "table"){
+						range = baseWindow.body(doc).createControlRange();
+					}else{
+						range = baseWindow.body(doc).createRange();
+					}
+					range.addElement(element);
+					if(!nochangefocus){
+						range.select();
+					}
+				}catch(e){
+					this.selectElementChildren(element, nochangefocus);
+				}
+			}
+		};
+
+		this.inSelection = function(node){
+			// summary:
+			//		This function determines if 'node' is
+			//		in the current selection.
+			// tags:
+			//		public
+			if(node){
+				var newRange;
+				var range;
+
+				if(doc.getSelection){
+					// WC3
+					var sel = win.getSelection();
+					if(sel && sel.rangeCount > 0){
+						range = sel.getRangeAt(0);
+					}
+					if(range && range.compareBoundaryPoints && doc.createRange){
+						try{
+							newRange = doc.createRange();
+							newRange.setStart(node, 0);
+							if(range.compareBoundaryPoints(range.START_TO_END, newRange) === 1){
+								return true;
+							}
+						}catch(e){ /* squelch */}
+					}
+				}else{
+					// IE6-8, so we can't use the range object as the pseudo
+					// range doesn't implement the boundary checking, we have to
+					// use IE specific crud.
+					range = doc.selection.createRange();
+					try{
+						newRange = node.ownerDocument.body.createTextRange();
+						newRange.moveToElementText(node);
+					}catch(e2){/* squelch */}
+					if(range && newRange){
+						// We can finally compare similar to W3C
+						if(range.compareEndPoints("EndToStart", newRange) === 1){
+							return true;
+						}
+					}
+				}
+			}
+			return false; // Boolean
+		},
+
+		this.getBookmark = function(){
+			// summary:
+			//		Retrieves a bookmark that can be used with moveToBookmark to reselect the currently selected range.
+
+			// TODO: merge additional code from Editor._getBookmark into this method
+
+			var bm, rg, tg, sel = doc.selection, cf = focus.curNode;
+
+			if(doc.getSelection){
+				// W3C Range API for selections.
+				sel = win.getSelection();
+				if(sel){
+					if(sel.isCollapsed){
+						tg = cf? cf.tagName : "";
+						if(tg){
+							// Create a fake rangelike item to restore selections.
+							tg = tg.toLowerCase();
+							if(tg == "textarea" ||
+								(tg == "input" && (!cf.type || cf.type.toLowerCase() == "text"))){
+								sel = {
+									start: cf.selectionStart,
+									end: cf.selectionEnd,
+									node: cf,
+									pRange: true
+								};
+								return {isCollapsed: (sel.end <= sel.start), mark: sel}; //Object.
+							}
+						}
+						bm = {isCollapsed:true};
+						if(sel.rangeCount){
+							bm.mark = sel.getRangeAt(0).cloneRange();
+						}
+					}else{
+						rg = sel.getRangeAt(0);
+						bm = {isCollapsed: false, mark: rg.cloneRange()};
+					}
+				}
+			}else if(sel){
+				// If the current focus was a input of some sort and no selection, don't bother saving
+				// a native bookmark.  This is because it causes issues with dialog/page selection restore.
+				// So, we need to create pseudo bookmarks to work with.
+				tg = cf ? cf.tagName : "";
+				tg = tg.toLowerCase();
+				if(cf && tg && (tg == "button" || tg == "textarea" || tg == "input")){
+					if(sel.type && sel.type.toLowerCase() == "none"){
+						return {
+							isCollapsed: true,
+							mark: null
+						}
+					}else{
+						rg = sel.createRange();
+						return {
+							isCollapsed: rg.text && rg.text.length?false:true,
+							mark: {
+								range: rg,
+								pRange: true
+							}
+						};
+					}
+				}
+				bm = {};
+
+				//'IE' way for selections.
+				try{
+					// createRange() throws exception when dojo in iframe
+					// and nothing selected, see #9632
+					rg = sel.createRange();
+					bm.isCollapsed = !(sel.type == 'Text' ? rg.htmlText.length : rg.length);
+				}catch(e){
+					bm.isCollapsed = true;
+					return bm;
+				}
+				if(sel.type.toUpperCase() == 'CONTROL'){
+					if(rg.length){
+						bm.mark=[];
+						var i=0,len=rg.length;
+						while(i<len){
+							bm.mark.push(rg.item(i++));
+						}
+					}else{
+						bm.isCollapsed = true;
+						bm.mark = null;
+					}
+				}else{
+					bm.mark = rg.getBookmark();
+				}
+			}else{
+				console.warn("No idea how to store the current selection for this browser!");
+			}
+			return bm; // Object
+		};
+
+		this.moveToBookmark = function(/*Object*/ bookmark){
+			// summary:
+			//		Moves current selection to a bookmark.
+			// bookmark:
+			//		This should be a returned object from getBookmark().
+
+			// TODO: merge additional code from Editor._moveToBookmark into this method
+
+			var mark = bookmark.mark;
+			if(mark){
+				if(doc.getSelection){
+					// W3C Range API (FF, WebKit, Opera, etc)
+					var sel = win.getSelection();
+					if(sel && sel.removeAllRanges){
+						if(mark.pRange){
+							var n = mark.node;
+							n.selectionStart = mark.start;
+							n.selectionEnd = mark.end;
+						}else{
+							sel.removeAllRanges();
+							sel.addRange(mark);
+						}
+					}else{
+						console.warn("No idea how to restore selection for this browser!");
+					}
+				}else if(doc.selection && mark){
+					//'IE' way.
+					var rg;
+					if(mark.pRange){
+						rg = mark.range;
+					}else if(lang.isArray(mark)){
+						rg = doc.body.createControlRange();
+						//rg.addElement does not have call/apply method, so can not call it directly
+						//rg is not available in "range.addElement(item)", so can't use that either
+						array.forEach(mark, function(n){
+							rg.addElement(n);
+						});
+					}else{
+						rg = doc.body.createTextRange();
+						rg.moveToBookmark(mark);
+					}
+					rg.select();
+				}
+			}
+		};
+
+		this.isCollapsed = function(){
+			// summary:
+			//		Returns true if there is no text selected
+			return this.getBookmark().isCollapsed;
+		};
+	};
+
+	// singleton on the main window
+	var selection = new SelectionManager(window);
+
+	// hook for editor to use class
+	selection.SelectionManager = SelectionManager;
+
+	return selection;
+});
diff --git a/dijit/templates/Calendar.html b/dijit/templates/Calendar.html
index a3428f5..50cef37 100644
--- a/dijit/templates/Calendar.html
+++ b/dijit/templates/Calendar.html
@@ -1,24 +1,24 @@
-<table cellspacing="0" cellpadding="0" class="dijitCalendarContainer" role="grid" aria-labelledby="${id}_mddb ${id}_year">
+<table cellspacing="0" cellpadding="0" class="dijitCalendarContainer" role="grid" aria-labelledby="${id}_mddb ${id}_year" data-dojo-attach-point="gridNode">
 	<thead>
 		<tr class="dijitReset dijitCalendarMonthContainer" valign="top">
-			<th class='dijitReset dijitCalendarArrow' data-dojo-attach-point="decrementMonth">
-				<img src="${_blankGif}" alt="" class="dijitCalendarIncrementControl dijitCalendarDecrease" role="presentation"/>
+			<th class='dijitReset dijitCalendarArrow' data-dojo-attach-point="decrementMonth" scope="col">
+				<span class="dijitInline dijitCalendarIncrementControl dijitCalendarDecrease" role="presentation"></span>
 				<span data-dojo-attach-point="decreaseArrowNode" class="dijitA11ySideArrow">-</span>
 			</th>
-			<th class='dijitReset' colspan="5">
+			<th class='dijitReset' colspan="5" scope="col">
 				<div data-dojo-attach-point="monthNode">
 				</div>
 			</th>
-			<th class='dijitReset dijitCalendarArrow' data-dojo-attach-point="incrementMonth">
-				<img src="${_blankGif}" alt="" class="dijitCalendarIncrementControl dijitCalendarIncrease" role="presentation"/>
+			<th class='dijitReset dijitCalendarArrow' scope="col" data-dojo-attach-point="incrementMonth">
+				<span class="dijitInline dijitCalendarIncrementControl dijitCalendarIncrease" role="presentation"></span>
 				<span data-dojo-attach-point="increaseArrowNode" class="dijitA11ySideArrow">+</span>
 			</th>
 		</tr>
-		<tr>
+		<tr role="row">
 			${!dayCellsHtml}
 		</tr>
 	</thead>
-	<tbody data-dojo-attach-point="dateRowsNode" data-dojo-attach-event="onclick: _onDayClick" class="dijitReset dijitCalendarBodyContainer">
+	<tbody data-dojo-attach-point="dateRowsNode" data-dojo-attach-event="ondijitclick: _onDayClick" class="dijitReset dijitCalendarBodyContainer">
 			${!dateRowsHtml}
 	</tbody>
 	<tfoot class="dijitReset dijitCalendarYearContainer">
diff --git a/dijit/templates/CheckedMenuItem.html b/dijit/templates/CheckedMenuItem.html
index 8e1bf57..131c4f7 100644
--- a/dijit/templates/CheckedMenuItem.html
+++ b/dijit/templates/CheckedMenuItem.html
@@ -1,10 +1,9 @@
-<tr class="dijitReset dijitMenuItem" data-dojo-attach-point="focusNode" role="menuitemcheckbox" tabIndex="-1"
-		data-dojo-attach-event="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
+<tr class="dijitReset dijitMenuItem" data-dojo-attach-point="focusNode" role="${role}" tabIndex="-1" aria-checked="${checked}">
 	<td class="dijitReset dijitMenuItemIconCell" role="presentation">
-		<img src="${_blankGif}" alt="" class="dijitMenuItemIcon dijitCheckedMenuItemIcon" data-dojo-attach-point="iconNode"/>
-		<span class="dijitCheckedMenuItemIconChar">✓</span>
+		<span class="dijitInline dijitIcon dijitMenuItemIcon dijitCheckedMenuItemIcon" data-dojo-attach-point="iconNode"></span>
+		<span class="dijitMenuItemIconChar dijitCheckedMenuItemIconChar">${checkedChar}</span>
 	</td>
-	<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode,labelNode"></td>
+	<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode,labelNode,textDirNode"></td>
 	<td class="dijitReset dijitMenuItemAccelKey" style="display: none" data-dojo-attach-point="accelKeyNode"></td>
 	<td class="dijitReset dijitMenuArrowCell" role="presentation"> </td>
 </tr>
diff --git a/dijit/templates/ColorPalette.html b/dijit/templates/ColorPalette.html
index 3f7f960..33539b8 100644
--- a/dijit/templates/ColorPalette.html
+++ b/dijit/templates/ColorPalette.html
@@ -1,5 +1,5 @@
-<div class="dijitInline dijitColorPalette">
-	<table dojoAttachPoint="paletteTableNode" class="dijitPaletteTable" cellSpacing="0" cellPadding="0" role="grid">
+<div class="dijitInline dijitColorPalette" role="grid">
+	<table dojoAttachPoint="paletteTableNode" class="dijitPaletteTable" cellSpacing="0" cellPadding="0" role="presentation">
 		<tbody data-dojo-attach-point="gridNode"></tbody>
 	</table>
 </div>
diff --git a/dijit/templates/Dialog.html b/dijit/templates/Dialog.html
index 1e4a223..d6c2952 100644
--- a/dijit/templates/Dialog.html
+++ b/dijit/templates/Dialog.html
@@ -1,9 +1,10 @@
 <div class="dijitDialog" role="dialog" aria-labelledby="${id}_title">
 	<div data-dojo-attach-point="titleBar" class="dijitDialogTitleBar">
-	<span data-dojo-attach-point="titleNode" class="dijitDialogTitle" id="${id}_title"></span>
-	<span data-dojo-attach-point="closeButtonNode" class="dijitDialogCloseIcon" data-dojo-attach-event="ondijitclick: onCancel" title="${buttonCancel}" role="button" tabIndex="-1">
-		<span data-dojo-attach-point="closeText" class="closeText" title="${buttonCancel}">x</span>
-	</span>
+		<span data-dojo-attach-point="titleNode" class="dijitDialogTitle" id="${id}_title"
+				role="heading" level="1"></span>
+		<span data-dojo-attach-point="closeButtonNode" class="dijitDialogCloseIcon" data-dojo-attach-event="ondijitclick: onCancel" title="${buttonCancel}" role="button" tabindex="0">
+			<span data-dojo-attach-point="closeText" class="closeText" title="${buttonCancel}">x</span>
+		</span>
 	</div>
-		<div data-dojo-attach-point="containerNode" class="dijitDialogPaneContent"></div>
+	<div data-dojo-attach-point="containerNode" class="dijitDialogPaneContent"></div>
 </div>
diff --git a/dijit/templates/Fieldset.html b/dijit/templates/Fieldset.html
new file mode 100644
index 0000000..17d56a2
--- /dev/null
+++ b/dijit/templates/Fieldset.html
@@ -0,0 +1,15 @@
+<fieldset>
+	<legend data-dojo-attach-event="ondijitclick:_onTitleClick, onkeydown:_onTitleKey"
+			dojoAttachPoint="titleBarNode, titleNode, focusNode">
+		<span data-dojo-attach-point="arrowNode" class="dijitInline dijitArrowNode" role="presentation"></span
+		><span data-dojo-attach-point="arrowNodeInner" class="dijitArrowNodeInner"></span
+		><span dojoAttachPoint="titleNode" class="dijitFieldsetLegendNode"></span>
+	</legend>
+	<div class="dijitFieldsetContentOuter" data-dojo-attach-point="hideNode" role="presentation">
+		<div class="dijitReset" data-dojo-attach-point="wipeNode" role="presentation">
+			<div class="dijitFieldsetContentInner" data-dojo-attach-point="containerNode" role="region" id="${id}_pane" aria-labelledby="${id}_titleBarNode">
+				<!-- nested divs because wipeIn()/wipeOut() doesn't work right on node w/padding etc.  Put padding on inner div. -->
+			</div>
+		</div>
+	</div>
+</fieldset>
diff --git a/dijit/templates/InlineEditBox.html b/dijit/templates/InlineEditBox.html
index 75451e3..6aac77e 100644
--- a/dijit/templates/InlineEditBox.html
+++ b/dijit/templates/InlineEditBox.html
@@ -1,10 +1,9 @@
-<span data-dojo-attach-point="editNode" role="presentation" style="position: absolute; visibility:hidden" class="dijitReset dijitInline"
-	data-dojo-attach-event="onkeypress: _onKeyPress"
+<span data-dojo-attach-point="editNode" role="presentation" class="dijitReset dijitInline dijitOffScreen"
 	><span data-dojo-attach-point="editorPlaceholder"></span
 	><span data-dojo-attach-point="buttonContainer"
-		><button data-dojo-type="dijit.form.Button" data-dojo-props="label: '${buttonSave}', 'class': 'saveButton'"
+		><button data-dojo-type="./form/Button" data-dojo-props="label: '${buttonSave}', 'class': 'saveButton'"
 			data-dojo-attach-point="saveButton" data-dojo-attach-event="onClick:save"></button
-		><button data-dojo-type="dijit.form.Button"  data-dojo-props="label: '${buttonCancel}', 'class': 'cancelButton'"
+		><button data-dojo-type="./form/Button"  data-dojo-props="label: '${buttonCancel}', 'class': 'cancelButton'"
 			data-dojo-attach-point="cancelButton" data-dojo-attach-event="onClick:cancel"></button
 	></span
 ></span>
diff --git a/dijit/templates/Menu.html b/dijit/templates/Menu.html
index 45e12a0..a9f635b 100644
--- a/dijit/templates/Menu.html
+++ b/dijit/templates/Menu.html
@@ -1,3 +1,4 @@
-<table class="dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable" role="menu" tabIndex="${tabIndex}" data-dojo-attach-event="onkeypress:_onKeyPress" cellspacing="0">
+<table class="dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable" role="menu" tabIndex="${tabIndex}"
+	   cellspacing="0">
 	<tbody class="dijitReset" data-dojo-attach-point="containerNode"></tbody>
 </table>
diff --git a/dijit/templates/MenuBar.html b/dijit/templates/MenuBar.html
index 3ba1ea2..ed54429 100644
--- a/dijit/templates/MenuBar.html
+++ b/dijit/templates/MenuBar.html
@@ -1 +1,2 @@
-<div class="dijitMenuBar dijitMenuPassive" data-dojo-attach-point="containerNode"  role="menubar" tabIndex="${tabIndex}" data-dojo-attach-event="onkeypress: _onKeyPress"></div>
+<div class="dijitMenuBar dijitMenuPassive" data-dojo-attach-point="containerNode" role="menubar" tabIndex="${tabIndex}"
+	 ></div>
diff --git a/dijit/templates/MenuBarItem.html b/dijit/templates/MenuBarItem.html
index f5e2629..0195329 100644
--- a/dijit/templates/MenuBarItem.html
+++ b/dijit/templates/MenuBarItem.html
@@ -1,4 +1,4 @@
-<div class="dijitReset dijitInline dijitMenuItem dijitMenuItemLabel" data-dojo-attach-point="focusNode" role="menuitem" tabIndex="-1"
-		data-dojo-attach-event="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
-	<span data-dojo-attach-point="containerNode"></span>
+<div class="dijitReset dijitInline dijitMenuItem dijitMenuItemLabel" data-dojo-attach-point="focusNode"
+	 	role="menuitem" tabIndex="-1">
+	<span data-dojo-attach-point="containerNode,textDirNode"></span>
 </div>
diff --git a/dijit/templates/MenuItem.html b/dijit/templates/MenuItem.html
index b4fe7d6..93dca6f 100644
--- a/dijit/templates/MenuItem.html
+++ b/dijit/templates/MenuItem.html
@@ -1,14 +1,13 @@
-<tr class="dijitReset dijitMenuItem" data-dojo-attach-point="focusNode" role="menuitem" tabIndex="-1"
-		data-dojo-attach-event="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
+<tr class="dijitReset dijitMenuItem" data-dojo-attach-point="focusNode" role="menuitem" tabIndex="-1">
 	<td class="dijitReset dijitMenuItemIconCell" role="presentation">
-		<img src="${_blankGif}" alt="" class="dijitIcon dijitMenuItemIcon" data-dojo-attach-point="iconNode"/>
+		<span role="presentation" class="dijitInline dijitIcon dijitMenuItemIcon" data-dojo-attach-point="iconNode"></span>
 	</td>
-	<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode"></td>
+	<td class="dijitReset dijitMenuItemLabel" colspan="2" data-dojo-attach-point="containerNode,textDirNode"></td>
 	<td class="dijitReset dijitMenuItemAccelKey" style="display: none" data-dojo-attach-point="accelKeyNode"></td>
 	<td class="dijitReset dijitMenuArrowCell" role="presentation">
-		<div data-dojo-attach-point="arrowWrapper" style="visibility: hidden">
-			<img src="${_blankGif}" alt="" class="dijitMenuExpand"/>
+		<span data-dojo-attach-point="arrowWrapper" style="visibility: hidden">
+			<span class="dijitInline dijitIcon dijitMenuExpand"></span>
 			<span class="dijitMenuExpandA11y">+</span>
-		</div>
+		</span>
 	</td>
 </tr>
diff --git a/dijit/templates/MenuSeparator.html b/dijit/templates/MenuSeparator.html
index 77d1d05..3d4155b 100644
--- a/dijit/templates/MenuSeparator.html
+++ b/dijit/templates/MenuSeparator.html
@@ -1,4 +1,4 @@
-<tr class="dijitMenuSeparator">
+<tr class="dijitMenuSeparator" role="separator">
 	<td class="dijitMenuSeparatorIconCell">
 		<div class="dijitMenuSeparatorTop"></div>
 		<div class="dijitMenuSeparatorBottom"></div>
@@ -7,4 +7,4 @@
 		<div class="dijitMenuSeparatorTop dijitMenuSeparatorLabel"></div>
 		<div class="dijitMenuSeparatorBottom"></div>
 	</td>
-</tr>
\ No newline at end of file
+</tr>
diff --git a/dijit/templates/ProgressBar.html b/dijit/templates/ProgressBar.html
index 9ed12af..bac261a 100644
--- a/dijit/templates/ProgressBar.html
+++ b/dijit/templates/ProgressBar.html
@@ -4,5 +4,6 @@
 		><span style="visibility:hidden"> </span
 	></div
 	><div data-dojo-attach-point="labelNode" class="dijitProgressBarLabel" id="${id}_label"></div
-	><img data-dojo-attach-point="indeterminateHighContrastImage" class="dijitProgressBarIndeterminateHighContrastImage" alt=""
-/></div>
+	><span data-dojo-attach-point="indeterminateHighContrastImage"
+		   class="dijitInline dijitProgressBarIndeterminateHighContrastImage"></span
+></div>
diff --git a/dijit/templates/TimePicker.html b/dijit/templates/TimePicker.html
deleted file mode 100644
index 919fbb0..0000000
--- a/dijit/templates/TimePicker.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<div id="widget_${id}" class="dijitMenu"
-    ><div data-dojo-attach-point="upArrow" class="dijitButtonNode dijitUpArrowButton" data-dojo-attach-event="onmouseenter:_buttonMouse,onmouseleave:_buttonMouse"
-		><div class="dijitReset dijitInline dijitArrowButtonInner" role="presentation"> </div
-		><div class="dijitArrowButtonChar">▲</div></div
-    ><div data-dojo-attach-point="timeMenu,focusNode" data-dojo-attach-event="onclick:_onOptionSelected,onmouseover,onmouseout"></div
-    ><div data-dojo-attach-point="downArrow" class="dijitButtonNode dijitDownArrowButton" data-dojo-attach-event="onmouseenter:_buttonMouse,onmouseleave:_buttonMouse"
-		><div class="dijitReset dijitInline dijitArrowButtonInner" role="presentation"> </div
-		><div class="dijitArrowButtonChar">▼</div></div
-></div>
diff --git a/dijit/templates/TitlePane.html b/dijit/templates/TitlePane.html
index 4e7aece..d482514 100644
--- a/dijit/templates/TitlePane.html
+++ b/dijit/templates/TitlePane.html
@@ -1,15 +1,15 @@
 <div>
-	<div data-dojo-attach-event="onclick:_onTitleClick, onkeypress:_onTitleKey"
-			class="dijitTitlePaneTitle" data-dojo-attach-point="titleBarNode">
+	<div data-dojo-attach-event="ondijitclick:_onTitleClick, onkeydown:_onTitleKey"
+			class="dijitTitlePaneTitle" data-dojo-attach-point="titleBarNode" id="${id}_titleBarNode">
 		<div class="dijitTitlePaneTitleFocus" data-dojo-attach-point="focusNode">
-			<img src="${_blankGif}" alt="" data-dojo-attach-point="arrowNode" class="dijitArrowNode" role="presentation"
-			/><span data-dojo-attach-point="arrowNodeInner" class="dijitArrowNodeInner"></span
+			<span data-dojo-attach-point="arrowNode" class="dijitInline dijitArrowNode" role="presentation"></span
+			><span data-dojo-attach-point="arrowNodeInner" class="dijitArrowNodeInner"></span
 			><span data-dojo-attach-point="titleNode" class="dijitTitlePaneTextNode"></span>
 		</div>
 	</div>
 	<div class="dijitTitlePaneContentOuter" data-dojo-attach-point="hideNode" role="presentation">
 		<div class="dijitReset" data-dojo-attach-point="wipeNode" role="presentation">
-			<div class="dijitTitlePaneContentInner" data-dojo-attach-point="containerNode" role="region" id="${id}_pane">
+			<div class="dijitTitlePaneContentInner" data-dojo-attach-point="containerNode" role="region" id="${id}_pane" aria-labelledby="${id}_titleBarNode">
 				<!-- nested divs because wipeIn()/wipeOut() doesn't work right on node w/padding etc.  Put padding on inner div. -->
 			</div>
 		</div>
diff --git a/dijit/templates/Tooltip.html b/dijit/templates/Tooltip.html
index fdb1a82..648cf6e 100644
--- a/dijit/templates/Tooltip.html
+++ b/dijit/templates/Tooltip.html
@@ -1,4 +1,4 @@
 <div class="dijitTooltip dijitTooltipLeft" id="dojoTooltip"
-	><div class="dijitTooltipContainer dijitTooltipContents" data-dojo-attach-point="containerNode" role='alert'></div
 	><div class="dijitTooltipConnector" data-dojo-attach-point="connectorNode"></div
+	><div class="dijitTooltipContainer dijitTooltipContents" data-dojo-attach-point="containerNode" role='alert'></div
 ></div>
diff --git a/dijit/templates/TooltipDialog.html b/dijit/templates/TooltipDialog.html
index 00a6022..ba6b454 100644
--- a/dijit/templates/TooltipDialog.html
+++ b/dijit/templates/TooltipDialog.html
@@ -1,6 +1,6 @@
-<div role="presentation" tabIndex="-1">
+<div role="alertdialog" tabIndex="-1">
 	<div class="dijitTooltipContainer" role="presentation">
-		<div class ="dijitTooltipContents dijitTooltipFocusNode" data-dojo-attach-point="containerNode" role="dialog"></div>
+		<div class="dijitTooltipContents dijitTooltipFocusNode" data-dojo-attach-point="containerNode"></div>
 	</div>
-	<div class="dijitTooltipConnector" role="presentation"></div>
+	<div class="dijitTooltipConnector" role="presentation" data-dojo-attach-point="connectorNode"></div>
 </div>
diff --git a/dijit/templates/Tree.html b/dijit/templates/Tree.html
index 4e1b943..778f5d7 100644
--- a/dijit/templates/Tree.html
+++ b/dijit/templates/Tree.html
@@ -1,4 +1,6 @@
-<div class="dijitTree dijitTreeContainer" role="tree"
-	data-dojo-attach-event="onkeypress:_onKeyPress">
+<div role="tree">
 	<div class="dijitInline dijitTreeIndent" style="position: absolute; top: -9999px" data-dojo-attach-point="indentDetector"></div>
+	<div class="dijitTreeExpando dijitTreeExpandoLoading" data-dojo-attach-point="rootLoadingIndicator"></div>
+	<div data-dojo-attach-point="containerNode" class="dijitTreeContainer" role="presentation">
+	</div>
 </div>
diff --git a/dijit/templates/TreeNode.html b/dijit/templates/TreeNode.html
index f55450c..8f9c14f 100644
--- a/dijit/templates/TreeNode.html
+++ b/dijit/templates/TreeNode.html
@@ -1,13 +1,12 @@
 <div class="dijitTreeNode" role="presentation"
-	><div data-dojo-attach-point="rowNode" class="dijitTreeRow" role="presentation" data-dojo-attach-event="onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave, onclick:_onClick, ondblclick:_onDblClick"
-		><img src="${_blankGif}" alt="" data-dojo-attach-point="expandoNode" class="dijitTreeExpando" role="presentation"
-		/><span data-dojo-attach-point="expandoNodeText" class="dijitExpandoText" role="presentation"
-		></span
+	><div data-dojo-attach-point="rowNode" class="dijitTreeRow" role="presentation"
+		><span data-dojo-attach-point="expandoNode" class="dijitInline dijitTreeExpando" role="presentation"></span
+		><span data-dojo-attach-point="expandoNodeText" class="dijitExpandoText" role="presentation"></span
 		><span data-dojo-attach-point="contentNode"
 			class="dijitTreeContent" role="presentation">
-			<img src="${_blankGif}" alt="" data-dojo-attach-point="iconNode" class="dijitIcon dijitTreeIcon" role="presentation"
-			/><span data-dojo-attach-point="labelNode" class="dijitTreeLabel" role="treeitem" tabindex="-1" aria-selected="false" data-dojo-attach-event="onfocus:_onLabelFocus"></span>
+			<span role="presentation" class="dijitInline dijitIcon dijitTreeIcon" data-dojo-attach-point="iconNode"></span
+			><span data-dojo-attach-point="labelNode,focusNode" class="dijitTreeLabel" role="treeitem" tabindex="-1" aria-selected="false"></span>
 		</span
 	></div>
-	<div data-dojo-attach-point="containerNode" class="dijitTreeContainer" role="presentation" style="display: none;"></div>
+	<div data-dojo-attach-point="containerNode" class="dijitTreeNodeContainer" role="presentation" style="display: none;"></div>
 </div>
diff --git a/dijit/tests/Bidi.html b/dijit/tests/Bidi.html
index b5843cc..e50f796 100755
--- a/dijit/tests/Bidi.html
+++ b/dijit/tests/Bidi.html
@@ -4,170 +4,170 @@
 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 	<title>Multi-directional document test</title>
 
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="extraLocale: ['en','ar','he'], isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
+	<script type="text/javascript" src="boilerplate.js" data-dojo-config="extraLocale: ['en','ar','he'], isDebug: true"></script>
 
 	<script type="text/javascript">
-		dojo.require("dojo.data.ItemFileReadStore");
-
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.ForestStoreModel");
-
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.MenuItem");
-		dojo.require("dijit.PopupMenuItem");
-
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.form.DropDownButton");
-		dojo.require("dijit.form.ComboButton");
-		dojo.require("dijit.form.ToggleButton");
-
-		dojo.require("dijit.ColorPalette");
-		dojo.require("dijit.Toolbar");
-		dojo.require("dijit.TooltipDialog");
-
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dijit.form.DateTextBox");
-		dojo.require("dijit.form.NumberSpinner");
-		dojo.require("dijit.form.ComboBox");
-
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.ContentPane");
-
-		dojo.require("dojo.parser");
-
-		dojo.require("doh.runner");
-
-		function checkLeft(/*Widget*/ left, /*Widget*/ right){
-			if(left.domNode) left = left.domNode;
-			if(right.domNode) right = right.domNode;
-
-			var lp = dojo.position(left, true),
-				rp = dojo.position(right, true);
-
-			doh.t(lp.x+lp.w-0.1 <= rp.x,
-				left.id + " to left of " + right.id + dojo.toJson(lp) + dojo.toJson(rp)
-			);
-		}
-
-		dojo.ready(function(){
-			doh.register("parse", function(){
-				dojo.parser.parse();
-			});
+		require([
+			"doh/runner",
+
+			"dojo/_base/array",
+			"dojo/dom",
+			"dojo/dom-geometry",
+			"dojo/json",
+			"dojo/on",
+			"dojo/parser",
+			"dojo/query",
+			"dojo/data/ItemFileReadStore",
+
+			"dijit/registry",
+
+			"dijit/Tree",
+			"dijit/tree/ForestStoreModel",
+
+			"dijit/Menu",
+			"dijit/MenuItem",
+			"dijit/PopupMenuItem",
+
+			"dijit/form/Button",
+			"dijit/form/DropDownButton",
+			"dijit/form/ComboButton",
+			"dijit/form/ToggleButton",
+	
+			"dijit/ColorPalette",
+			"dijit/Toolbar",
+			"dijit/TooltipDialog",
+	
+			"dijit/form/TextBox",
+			"dijit/form/DateTextBox",
+			"dijit/form/NumberSpinner",
+			"dijit/form/ComboBox",
+	
+			"dijit/layout/TabContainer",
+			"dijit/layout/ContentPane",
+				
+			"dojo/domReady!"
+		], function(doh, array, dom, domGeom, json, on, parser, query, ItemFileReadStore, registry){
+		
+
+			function checkLeft(/*Widget*/ left, /*Widget*/ right){
+				if(left.domNode) left = left.domNode;
+				if(right.domNode) right = right.domNode;
+	
+				var lp = domGeom.position(left, true),
+					rp = domGeom.position(right, true);
+	
+				doh.t(lp.x+lp.w-0.1 <= rp.x,
+					left.id + " to left of " + right.id + json.stringify(lp) + json.stringify(rp)
+				);
+			}
+
+			doh.register("setup", [
+				function parse(){
+					parser.parse();
+				},
+				{
+					name: "wait for tab container load",
+					timeout: 5000,
+					runTest: function(){
+						return registry.byId("ltr_tc_cp").onLoadDeferred;
+					}
+				},
+				{
+					name: "wait for tree load",
+					timeout: 5000,
+					runTest: function(){
+						return registry.byId("ltr_tc_tree").onLoadDeferred;
+					}
+				}
+			]);
 
 			doh.register("Test bidi toolbar", [
 				{
 					name: "toolbar checkLeft",
 					runTest: function(){
 						//Check that the order of the menu buttons is correct
-						checkLeft(dijit.byId("ltr_ToolbarCutButton"), dijit.byId("ltr_ToolbarDropDown"));
-						checkLeft(dijit.byId("ltr_ToolbarDropDown"), dijit.byId("ltr_ToolbarColorDropDown"));
-						checkLeft(dijit.byId("ltr_ToolbarColorDropDown"), dijit.byId("ltr_ToolbarComboButton"));
-						checkLeft(dijit.byId("rtl_ToolbarComboButton"), dijit.byId("rtl_ToolbarColorDropDown"));
-						checkLeft(dijit.byId("rtl_ToolbarColorDropDown"), dijit.byId("rtl_ToolbarDropDown"));
-						checkLeft(dijit.byId("rtl_ToolbarDropDown"), dijit.byId("rtl_ToolbarCutButton"));
+						checkLeft(registry.byId("ltr_ToolbarCutButton"), registry.byId("ltr_ToolbarDropDown"));
+						checkLeft(registry.byId("ltr_ToolbarDropDown"), registry.byId("ltr_ToolbarColorDropDown"));
+						checkLeft(registry.byId("ltr_ToolbarColorDropDown"), registry.byId("ltr_ToolbarComboButton"));
+						checkLeft(registry.byId("rtl_ToolbarComboButton"), registry.byId("rtl_ToolbarColorDropDown"));
+						checkLeft(registry.byId("rtl_ToolbarColorDropDown"), registry.byId("rtl_ToolbarDropDown"));
+						checkLeft(registry.byId("rtl_ToolbarDropDown"), registry.byId("rtl_ToolbarCutButton"));
 					}
 				},
 				{
 					name: "ltr_ToolbarDropDown",
 					runTest: function(){
-						dijit.byId("ltr_ToolbarDropDown").openDropDown();
+						registry.byId("ltr_ToolbarDropDown").openDropDown();
 
-						checkLeft(dojo.byId("ltr_l1"), dijit.byId("ltr_i1"));
-						checkLeft(dojo.byId("ltr_l2"), dijit.byId("ltr_i2"));
-						checkLeft(dojo.byId("ltr_l3"), dijit.byId("ltr_i3"));
+						checkLeft(dom.byId("ltr_l1"), registry.byId("ltr_i1"));
+						checkLeft(dom.byId("ltr_l2"), registry.byId("ltr_i2"));
+						checkLeft(dom.byId("ltr_l3"), registry.byId("ltr_i3"));
 
-						doh.is("ltr", dojo.byId("widget_ltr_i1").dir);
-						doh.is("ltr", dojo.byId("widget_ltr_i2").dir);
-						doh.is("ltr", dojo.byId("widget_ltr_i3").dir);
-						doh.is("ltr", dijit.byId("ltr_button").dir);
+						doh.is("ltr", dom.byId("widget_ltr_i1").dir);
+						doh.is("ltr", dom.byId("widget_ltr_i2").dir);
+						doh.is("ltr", dom.byId("widget_ltr_i3").dir);
+						doh.is("ltr", registry.byId("ltr_button").dir);
 					}
 				},
 				{
 					name: "rtl_ToolbarDropDown",
 					runTest: function(){
-						dijit.byId("rtl_ToolbarDropDown").openDropDown();
+						registry.byId("rtl_ToolbarDropDown").openDropDown();
 
-						checkLeft(dijit.byId("rtl_i1"), dojo.byId("rtl_l1"));
-						checkLeft(dijit.byId("rtl_i2"), dojo.byId("rtl_l2"));
-						checkLeft(dijit.byId("rtl_i3"), dojo.byId("rtl_l3"));
+						checkLeft(registry.byId("rtl_i1"), dom.byId("rtl_l1"));
+						checkLeft(registry.byId("rtl_i2"), dom.byId("rtl_l2"));
+						checkLeft(registry.byId("rtl_i3"), dom.byId("rtl_l3"));
 
-						doh.is("rtl", dojo.byId("widget_rtl_i1").dir);
-						doh.is("rtl", dojo.byId("widget_rtl_i2").dir);
-						doh.is("rtl", dojo.byId("widget_rtl_i3").dir);
-						doh.is("rtl", dijit.byId("rtl_button").dir);
-					}
-				},
-				{
-					name: "ltr_ToolbarColorDropDown",
-					runTest: function(){
-						dijit.byId("ltr_ToolbarColorDropDown").openDropDown();
-
-						var white = dojo.query("img[alt='white']", dojo.byId("ltr_colorPalette"))[0];
-						var plum = dojo.query("img[alt='plum']", dojo.byId("ltr_colorPalette"))[0];
-						checkLeft(white, plum);
-					}
-				},
-				{
-					name: "rtl_ToolbarColorDropDown",
-					runTest: function(){
-						dijit.byId("rtl_ToolbarColorDropDown").openDropDown();
-
-						var white = dojo.query("img[alt='white']", dojo.byId("rtl_colorPalette"))[0];
-						var plum = dojo.query("img[alt='plum']", dojo.byId("rtl_colorPalette"))[0];
-						checkLeft(plum, white);
+						doh.is("rtl", dom.byId("widget_rtl_i1").dir);
+						doh.is("rtl", dom.byId("widget_rtl_i2").dir);
+						doh.is("rtl", dom.byId("widget_rtl_i3").dir);
+						doh.is("rtl", registry.byId("rtl_button").dir);
 					}
 				},
 				{
 					name: "ltr_ToolbarMenuDropDown",
 					runTest: function(){
-						dijit.byId("ltr_ToolbarComboButton").openDropDown();
+						registry.byId("ltr_ToolbarComboButton").openDropDown();
 
-						var icon = dijit.byId("ltr_mi1").iconNode;
-						var label = dijit.byId("ltr_mi1").containerNode;
+						var icon = registry.byId("ltr_mi1").iconNode;
+						var label = registry.byId("ltr_mi1").containerNode;
 						checkLeft(icon, label);
 					}
 				},
 				{
 					name: "ltr_Toolbar_nested_menu",
 					runTest: function(){
-						dijit.byId("ltr_popup_mi1")._onClick({preventDefault: function(){}, stopPropagation: function(){}});
-
-						var icon = dijit.byId("ltr_popup_mi1").iconNode;
-						var label = dijit.byId("ltr_popup_mi1").containerNode;
+						on.emit(registry.byId("ltr_popup_mi1").domNode, "click",  {
+							bubbles: true,
+							cancelable: true,
+							which: 1
+						});
+						var icon = registry.byId("ltr_popup_mi1").iconNode;
+						var label = registry.byId("ltr_popup_mi1").containerNode;
 						checkLeft(icon, label);
 					}
 				},
 				{
 					name: "rtl_ToolbarMenuDropDown",
 					runTest: function(){
-						dijit.byId("rtl_ToolbarComboButton").openDropDown();
+						registry.byId("rtl_ToolbarComboButton").openDropDown();
 
-						var icon = dijit.byId("rtl_mi1").iconNode;
-						var label = dijit.byId("rtl_mi1").containerNode;
+						var icon = registry.byId("rtl_mi1").iconNode;
+						var label = registry.byId("rtl_mi1").containerNode;
 						checkLeft(label, icon);
 					}
 				},
 				{
 					name: "rtl_Toolbar_nested_menu",
 					runTest: function(){
-						dijit.byId("rtl_popup_mi1")._onClick({preventDefault: function(){}, stopPropagation: function(){}});
+						on.emit(registry.byId("rtl_popup_mi1").domNode, "click",  {
+							bubbles: true,
+							cancelable: true,
+							which: 1
+						});
 
-						var icon = dijit.byId("rtl_popup_mi1").iconNode;
-						var label = dijit.byId("rtl_popup_mi1").containerNode;
+						var icon = registry.byId("rtl_popup_mi1").iconNode;
+						var label = registry.byId("rtl_popup_mi1").containerNode;
 						checkLeft(label, icon);
 					}
 				}
@@ -178,13 +178,13 @@
 					name: "ltr TabContainer",
 					runTest: function(){
 						// Check that the order of the tabs is correct
-						checkLeft(dijit.byId("ltr_tc_tablist_ltr_tc_cp"), dijit.byId("ltr_tc_tablist_ltr_tc_tree"));
+						checkLeft(registry.byId("ltr_tc_tablist_ltr_tc_cp"), registry.byId("ltr_tc_tablist_ltr_tc_tree"));
 
 						// Check the fields on each of the first tabs
-						doh.is("ltr", dijit.byId("ltr_tc_cp").dir);
+						doh.is("ltr", registry.byId("ltr_tc_cp").dir);
 
-						var combo = dojo.query("input[value='dijit']", dojo.byId("ltr_tc_cp"))[0];
-						var arrow = dojo.query(".dijitButtonNode", dojo.byId("ltr_tc_cp"))[0];
+						var combo = query("input[value='dijit']", dom.byId("ltr_tc_cp"))[0];
+						var arrow = query(".dijitButtonNode", dom.byId("ltr_tc_cp"))[0];
 						checkLeft(combo, arrow);
 					}
 				},
@@ -192,13 +192,13 @@
 					name: "rtl TabContainer",
 					runTest: function(){
 						// Check that the order of the tabs is correct
-						checkLeft(dijit.byId("rtl_tc_tablist_rtl_tc_tree"), dijit.byId("rtl_tc_tablist_rtl_tc_cp"));
+						checkLeft(registry.byId("rtl_tc_tablist_rtl_tc_tree"), registry.byId("rtl_tc_tablist_rtl_tc_cp"));
 
 						// Check the fields on each of the first tabs
-						doh.is("rtl", dijit.byId("rtl_tc_cp").dir);
+						doh.is("rtl", registry.byId("rtl_tc_cp").dir);
 
-						combo = dojo.query("input[value='dijit']", dojo.byId("rtl_tc_cp"))[0];
-						arrow = dojo.query(".dijitButtonNode", dojo.byId("rtl_tc_cp"))[0];
+						combo = query("input[value='dijit']", dom.byId("rtl_tc_cp"))[0];
+						arrow = query(".dijitButtonNode", dom.byId("rtl_tc_cp"))[0];
 						checkLeft(arrow, combo);
 					}
 				}
@@ -208,13 +208,13 @@
 				{
 					name: "ltr_tree",
 					runTest: function(){
-						dijit.byId("ltr_tc").selectChild("ltr_tc_tree");
+						registry.byId("ltr_tc").selectChild("ltr_tc_tree");
 
-						var rowNodes = dojo.query(".dijitTreeRow", dojo.byId("ltr_tc_tree"));
+						var rowNodes = query(".dijitTreeRow", dom.byId("ltr_tc_tree"));
 
-						dojo.forEach(rowNodes, function(rowNode){
-							var expando = dojo.query(".dijitTreeExpando", rowNode)[0];
-							var label = dojo.query(".dijitTreeContent", rowNode)[0];
+						array.forEach(rowNodes, function(rowNode){
+							var expando = query(".dijitTreeExpando", rowNode)[0];
+							var label = query(".dijitTreeContent", rowNode)[0];
 							checkLeft(expando, label);
 						});
 					}
@@ -222,13 +222,13 @@
 				{
 					name: "rtl_tree",
 					runTest: function(){
-						dijit.byId("rtl_tc").selectChild("rtl_tc_tree");
+						registry.byId("rtl_tc").selectChild("rtl_tc_tree");
 
-						var rowNodes = dojo.query(".dijitTreeRow", dojo.byId("rtl_tc_tree"));
+						var rowNodes = query(".dijitTreeRow", dom.byId("rtl_tc_tree"));
 
-						dojo.forEach(rowNodes, function(rowNode){
-							var expando = dojo.query(".dijitTreeExpando", rowNode)[0];
-							var label = dojo.query(".dijitTreeContent", rowNode)[0];
+						array.forEach(rowNodes, function(rowNode){
+							var expando = query(".dijitTreeExpando", rowNode)[0];
+							var label = query(".dijitTreeContent", rowNode)[0];
 							checkLeft(label, expando);
 						});
 					}
@@ -243,58 +243,58 @@
 
 	<h1 class="testTitle">Multi-directional document test</h1>
 
-	<div data-dojo-id="continentStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"_data/countries.json"'></div>
-	<div data-dojo-id="continentModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
+	<div data-dojo-id="continentStore" data-dojo-type="dojo/data/ItemFileReadStore" data-dojo-props='url:"_data/countries.json"'></div>
+	<div data-dojo-id="continentModel" data-dojo-type="dijit/tree/ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
 		rootId:"continentRoot", rootLabel:"Continents", childrenAttrs:["children"]'></div>
 
 	<div id="right" dir="rtl" lang="ar-eg" style="float: right; width: 500px;">
 		<h2>RTL</h2>
 
-		<div data-dojo-type="dijit.Toolbar"
-				><div id="rtl_ToolbarCutButton" data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</div
-				><div id="rtl_ToolbarDropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"plusIcon", showLabel:true'>
+		<div data-dojo-type="dijit/Toolbar"
+				><div id="rtl_ToolbarCutButton" data-dojo-type="dijit/form/Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</div
+				><div id="rtl_ToolbarDropDown" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"plusIcon", showLabel:true'>
 					<span>שיח</span>
-					<div data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information"'>
+					<div data-dojo-type="dijit/TooltipDialog" data-dojo-props='title:"Enter Login information"'>
 						<table>
 							<tr>
 								<td><label id="rtl_l1">שם:</label></td>
-								<td><input id="rtl_i1" data-dojo-type="dijit.form.TextBox"/></td>
+								<td><input id="rtl_i1" data-dojo-type="dijit/form/TextBox"/></td>
 							</tr>
 							<tr>
 								<td><label id="rtl_l2">תאריך:</label></td>
-								<td><input id="rtl_i2" data-dojo-type="dijit.form.DateTextBox"/></td>
+								<td><input id="rtl_i2" data-dojo-type="dijit/form/DateTextBox"/></td>
 							</tr>
 							<tr>
 								<td><label id="rtl_l3">גיל:</label></td>
-								<td><input id="rtl_i3" data-dojo-type="dijit.form.NumberSpinner"/></td>
+								<td><input id="rtl_i3" data-dojo-type="dijit/form/NumberSpinner"/></td>
 							</tr>
 							<tr>
 								<td colspan="2" style="text-align:center;">
-									<button id="rtl_button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", name:"submit"'>כניסה</button>
+									<button id="rtl_button" data-dojo-type="dijit/form/Button" data-dojo-props='type:"submit", name:"submit"'>כניסה</button>
 								</td>
 							</tr>
 						</table>
 					</div
 				></div
-				><div id="rtl_ToolbarColorDropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBackColor", showLabel:true'>
+				><div id="rtl_ToolbarColorDropDown" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBackColor", showLabel:true'>
 					<span>لوحة الألوان</span>
-					<div id="rtl_colorPalette" data-dojo-type="dijit.ColorPalette" data-dojo-props='style:"display:none;", palette:"7x10", onChange:function(){ console.log(this.value); }'></div>
+					<div id="rtl_colorPalette" data-dojo-type="dijit/ColorPalette" data-dojo-props='style:"display:none;", palette:"7x10", onChange:function(){ console.log(this.value); }'></div>
 				</div
-				><div id="rtl_ToolbarComboButton" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", iconClass:"plusIcon", showLabel:true'>
+				><div id="rtl_ToolbarComboButton" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"save options", iconClass:"plusIcon", showLabel:true'>
 					<span>القائمة</span>
-					<div data-dojo-type="dijit.Menu" data-dojo-props='style:"display:none;"'>
-						<div id="rtl_mi1" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave"'>حفظ</div>
-						<div data-dojo-type="dijit.MenuItem">حفظ ك</div>
-						<div id="rtl_popup_mi1" data-dojo-type="dijit.PopupMenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconForeColor"'>
+					<div data-dojo-type="dijit/Menu" data-dojo-props='style:"display:none;"'>
+						<div id="rtl_mi1" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave"'>حفظ</div>
+						<div data-dojo-type="dijit/MenuItem">حفظ ك</div>
+						<div id="rtl_popup_mi1" data-dojo-type="dijit/PopupMenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconForeColor"'>
 							<span>فرعية</span>
-							<div data-dojo-type="dijit.Menu">
-								<div data-dojo-type="dijit.MenuItem">Submenu Item One</div>
-								<div data-dojo-type="dijit.MenuItem">Submenu Item Two</div>
-								<div data-dojo-type="dijit.PopupMenuItem">
+							<div data-dojo-type="dijit/Menu">
+								<div data-dojo-type="dijit/MenuItem">Submenu Item One</div>
+								<div data-dojo-type="dijit/MenuItem">Submenu Item Two</div>
+								<div data-dojo-type="dijit/PopupMenuItem">
 									<span>Deeper Submenu</span>
-									<div data-dojo-type="dijit.Menu">
-										<div data-dojo-type="dijit.MenuItem">Sub-sub-menu Item One</div>
-										<div data-dojo-type="dijit.MenuItem">Sub-sub-menu Item Two</div>
+									<div data-dojo-type="dijit/Menu">
+										<div data-dojo-type="dijit/MenuItem">Sub-sub-menu Item One</div>
+										<div data-dojo-type="dijit/MenuItem">Sub-sub-menu Item Two</div>
 									</div>
 								</div>
 							</div>
@@ -302,59 +302,59 @@
 					</div>
 				</div
 		></div>
-		<div id="rtl_tc" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 450px; height: 300px; margin-top: 1em;"'>
-			<div id="rtl_tc_cp" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"رابط", closable:true, href:"layout/doc0.html"'></div>
-			<div id="rtl_tc_tree" data-dojo-type="dijit.Tree" data-dojo-props='model:continentModel, openOnClick:true, title:"עץ", closable:true'></div>
+		<div id="rtl_tc" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 450px; height: 300px; margin-top: 1em;"'>
+			<div id="rtl_tc_cp" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"رابط", closable:true, href:"layout/doc0.html"'></div>
+			<div id="rtl_tc_tree" data-dojo-type="dijit/Tree" data-dojo-props='model:continentModel, openOnClick:true, title:"עץ", closable:true'></div>
 		</div>
 	</div>
 
 	<div id="left" dir="ltr" lang="en-us" style="width: 500px; float: left;">
 		<h2>LTR</h2>
 
-		<div data-dojo-type="dijit.Toolbar"
-				><div id="ltr_ToolbarCutButton" data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</div
-				><div id="ltr_ToolbarDropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"plusIcon", showLabel:true'>
+		<div data-dojo-type="dijit/Toolbar"
+				><div id="ltr_ToolbarCutButton" data-dojo-type="dijit/form/Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</div
+				><div id="ltr_ToolbarDropDown" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"plusIcon", showLabel:true'>
 					<span>TooltipDialog</span>
-					<div data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information"'>
+					<div data-dojo-type="dijit/TooltipDialog" data-dojo-props='title:"Enter Login information"'>
 						<table>
 							<tr>
 								<td><label id="ltr_l1">Name:</label></td>
-								<td><input id="ltr_i1" data-dojo-type="dijit.form.TextBox"/></td>
+								<td><input id="ltr_i1" data-dojo-type="dijit/form/TextBox"/></td>
 							</tr>
 							<tr>
 								<td><label id="ltr_l2">Date:</label></td>
-								<td><input id="ltr_i2" data-dojo-type="dijit.form.DateTextBox"/></td>
+								<td><input id="ltr_i2" data-dojo-type="dijit/form/DateTextBox"/></td>
 							</tr>
 							<tr>
 								<td><label id="ltr_l3">Age:</label></td>
-								<td><input id="ltr_i3" data-dojo-type="dijit.form.NumberSpinner"/></td>
+								<td><input id="ltr_i3" data-dojo-type="dijit/form/NumberSpinner"/></td>
 							</tr>
 							<tr>
 								<td colspan="2" style="text-align:center;">
-									<button id="ltr_button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", name:"submit"'>Login</button></td>
+									<button id="ltr_button" data-dojo-type="dijit/form/Button" data-dojo-props='type:"submit", name:"submit"'>Login</button></td>
 							</tr>
 						</table>
 					</div
 				></div
-				><div id="ltr_ToolbarColorDropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBackColor", showLabel:true'>
+				><div id="ltr_ToolbarColorDropDown" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBackColor", showLabel:true'>
 					<span>ColorPalette</span>
-					<div id="ltr_colorPalette" data-dojo-type="dijit.ColorPalette" data-dojo-props='style:"display:none;", palette:"7x10", onChange:function(){ console.log(this.value); }'></div>
+					<div id="ltr_colorPalette" data-dojo-type="dijit/ColorPalette" data-dojo-props='style:"display:none;", palette:"7x10", onChange:function(){ console.log(this.value); }'></div>
 				</div
-				><div id="ltr_ToolbarComboButton" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", iconClass:"plusIcon", showLabel:true'>
+				><div id="ltr_ToolbarComboButton" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"save options", iconClass:"plusIcon", showLabel:true'>
 					<span>Menu</span>
-					<div data-dojo-type="dijit.Menu" data-dojo-props='style:"display none;"'>
-						<div id="ltr_mi1" data-dojo-type="dijit.MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave"'>Save</div>
-						<div data-dojo-type="dijit.MenuItem">Save As</div>
-						<div id="ltr_popup_mi1" data-dojo-type="dijit.PopupMenuItem">
+					<div data-dojo-type="dijit/Menu" data-dojo-props='style:"display none;"'>
+						<div id="ltr_mi1" data-dojo-type="dijit/MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave"'>Save</div>
+						<div data-dojo-type="dijit/MenuItem">Save As</div>
+						<div id="ltr_popup_mi1" data-dojo-type="dijit/PopupMenuItem">
 							<span>Enabled Submenu</span>
-							<div data-dojo-type="dijit.Menu">
-								<div data-dojo-type="dijit.MenuItem">Submenu Item One</div>
-								<div data-dojo-type="dijit.MenuItem">Submenu Item Two</div>
-								<div data-dojo-type="dijit.PopupMenuItem">
+							<div data-dojo-type="dijit/Menu">
+								<div data-dojo-type="dijit/MenuItem">Submenu Item One</div>
+								<div data-dojo-type="dijit/MenuItem">Submenu Item Two</div>
+								<div data-dojo-type="dijit/PopupMenuItem">
 									<span>Deeper Submenu</span>
-									<div data-dojo-type="dijit.Menu">
-										<div data-dojo-type="dijit.MenuItem">Sub-sub-menu Item One</div>
-										<div data-dojo-type="dijit.MenuItem">Sub-sub-menu Item Two</div>
+									<div data-dojo-type="dijit/Menu">
+										<div data-dojo-type="dijit/MenuItem">Sub-sub-menu Item One</div>
+										<div data-dojo-type="dijit/MenuItem">Sub-sub-menu Item Two</div>
 									</div>
 								</div>
 							</div>
@@ -363,9 +363,9 @@
 				</div
 		></div>
 
-		<div id="ltr_tc" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 450px; height: 300px; margin-top: 1em;"'>
-			<div id="ltr_tc_cp" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Href", closable:true, href:"layout/doc0.html"'></div>
-			<div id="ltr_tc_tree" data-dojo-type="dijit.Tree" data-dojo-props='model:continentModel, openOnClick:true, title:"Tree", closable:true'></div>
+		<div id="ltr_tc" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 450px; height: 300px; margin-top: 1em;"'>
+			<div id="ltr_tc_cp" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Href", closable:true, href:"layout/doc0.html"'></div>
+			<div id="ltr_tc_tree" data-dojo-type="dijit/Tree" data-dojo-props='model:continentModel, openOnClick:true, title:"Tree", closable:true'></div>
 		</div>
 
 	</div>
diff --git a/dijit/tests/CalendarLite.html b/dijit/tests/CalendarLite.html
new file mode 100644
index 0000000..cc1790d
--- /dev/null
+++ b/dijit/tests/CalendarLite.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>CalendarLite Widget Test</title>
+
+		<script src="boilerplate.js"></script>
+
+		<script type="text/javascript">
+			require(["doh/runner", "dojo/date/stamp", "dojo/dom", "dijit/CalendarLite", "dojo/domReady!"],
+					function(doh, stamp, dom, CalendarLite){
+
+				doh.register("CalendarLite", [
+					function create(){
+						cal = new CalendarLite({
+							id: "cal",
+							value: "1999-12-31",
+							onChange: function myHandler(id,newValue){
+								console.debug("onChange for id = " + id + ", value: " + newValue);
+							}
+						}, dom.byId("calendar1"));
+
+						doh.is("1999-12-31", stamp.toISOString(cal.get("value"), {selector: "date"}), "value");
+						doh.is("December", cal.gridNode.getAttribute("summary"));
+					},
+
+					function change(){
+						cal.set("value", "2000-11-30");
+						doh.is("2000-11-30", stamp.toISOString(cal.get("value"), {selector: "date"}), "value");
+						doh.is("November", cal.gridNode.getAttribute("summary"));
+					},
+
+					function createWithSummary(){
+						cal2 = new CalendarLite({
+							id: "cal2",
+							value: "1999-12-31",
+							summary: "explicit summary"
+						}, dom.byId("calendar2"));
+
+						doh.is("explicit summary", cal2.gridNode.getAttribute("summary"));
+					}
+
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body class="claro" role="main">
+
+		<h1 class="testTitle">Dijit CalendarLite Test</h1>
+
+		<label for="before">before:</label><input value="input" id="before"/>
+		<input id="calendar1"/>
+		<label for="after">between:</label><input value="input" id="between"/>
+		<input id="calendar2"/>
+		<label for="after">after:</label><input value="input" id="after"/>
+	</body>
+</html>
diff --git a/dijit/tests/Destroyable.html b/dijit/tests/Destroyable.html
new file mode 100644
index 0000000..d19e466
--- /dev/null
+++ b/dijit/tests/Destroyable.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>widget attribute unit test (in constructor and get()/set())</title>
+<style type="text/css">
+	@import "../themes/claro/document.css";
+	@import "css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true"></script>
+
+<script type="text/javascript">
+require([
+	"doh/runner", "dojo/aspect", "dojo/_base/declare", "dojo/dom", "dojo/dom-construct", "dojo/on", "dojo/Stateful",
+	"dijit/Destroyable", "dojo/domReady!"
+], function(doh, aspect, declare, dom, domConstruct, on, Stateful, Destroyable){
+	doh.register("Deferred", [
+		function general(){
+			var SupportingWidget = declare([], {
+				destroyCalls: 0,
+				constructor: function(name){
+					this.name = name;
+				},
+				destroy: function(){
+					this.destroyCalls++;
+				}
+			});
+			var watchMe = new Stateful({
+				name: "watchMe",
+				x: 0
+			});
+			var DestroyableSubClass = declare(Destroyable, {
+				// number of times my button was clicked
+				clicks: 0,
+
+				// number of times watchMe changed value of x
+				watches: 0,
+
+				constructor: function(){
+					var self = this;
+					this.domNode = domConstruct.create("button");
+					this.own(
+						// setup an event handler (to be destroyed when I'm destroyed)
+						on(this.domNode, "click", function(){ self.clicks++; }),
+
+						// watch external watchMe class (to be unwatch()'d when I'm destroyed)
+						watchMe.watch("x", function(name, oVal, nVal){ self.watches++; })
+					);
+
+					// Setup two supporting widgets, to be destroyed when I'm destroyed
+					this.own(this.sw1 = new SupportingWidget("sw1"));
+					this.own(this.sw2 = new SupportingWidget("sw2"));
+				}
+			});
+
+			var destroyable1 = new DestroyableSubClass();
+			dom.byId("container").appendChild(destroyable1.domNode);
+
+			// make sure event handler was setup
+			destroyable1.domNode.click();
+			doh.is(1, destroyable1.clicks, "one click");
+
+			// make sure watch handler was setup
+			watchMe.set("x", 1);
+			doh.is(1, destroyable1.watches, "one watch notification");
+
+			// manually destroy one of the supporting widgets
+			destroyable1.sw1.destroy();
+			doh.is(1, destroyable1.sw1.destroyCalls);
+
+			// Destroy the Destroyable instance itself.   destroyable1 should:
+			// 		- destroy the sw2 supporting widget, but not try to re-destroy sw1
+			//		- disconnect the watch() listener on watchMe
+			//		- disconnect the click event handler on destroyable1.domNode
+			destroyable1.destroy();
+			doh.is(1, destroyable1.sw1.destroyCalls, "sw1 wasn't redestroyed");
+			doh.is(1, destroyable1.sw2.destroyCalls, "sw2 was destroyed");
+			destroyable1.domNode.click();
+			doh.is(1, destroyable1.clicks, "no new click notification");
+			watchMe.set("x", 2);
+			doh.is(1, destroyable1.watches, "no new watch notification");
+		}
+	]);	// doh.register()
+
+	doh.run();
+});	// require()
+
+</script>
+</head>
+<body>
+<h1>dijit/Destroyable Unit Test</h1>
+<div id="container"></div>
+</body>
+</html>
diff --git a/dijit/tests/Dialog.html b/dijit/tests/Dialog.html
index a8fa1ea..25d2c46 100644
--- a/dijit/tests/Dialog.html
+++ b/dijit/tests/Dialog.html
@@ -3,34 +3,35 @@
 <head>
 	<title>Dialog Widget Automated (non-robot) Tests</title>
 
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
-	</style>
+	<script src="boilerplate.js"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/dom", "dojo/dom-geometry", "dojo/dom-style", "dojo/window",
+			"dijit/focus", "dijit/registry", "dijit/Dialog", "dijit/DialogUnderlay",
+			"dijit/tests/helpers", "dojo/domReady!"
+		], function(doh, dom, domGeom, domStyle, winUtils, focus, registry, Dialog, DialogUnderlay, helpers){
+			// Non robot tests to see if nested dialogs work correctly
+			// when obscured dialogs are destroyed/hidden, on race conditions of
+			// multiple dialogs fading in/out at once, etc.
 
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
+			doh.register("setup", function(){
+				// Start focus on a button on the page (although we aren't going
+				// to click the button)
+				var d = new doh.Deferred();
 
-	<!-- functions to help test -->
-	<script type="text/javascript" src="helpers.js"></script>
+				setTimeout(d.getTestErrback(function(){
+					dom.byId("button").focus();
 
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
+					setTimeout(d.getTestCallback(function(){
+						doh.is("button", focus.curNode.id, "focus is on the main page");
+					}), 100);
+				}), 300);
 
-	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Dialog");
-		dojo.require("dijit.focus");
+				return d;
+			});
 
-		dojo.ready(function(){
-			// Non robot tests to see if nested dialogs work correctly
-			// when obscured dialogs are destroyed/hidden, on race conditions of
-			// multiple dialogs fading in/out at once, etc.
 			doh.register("out-of-order dialog hide/destroy", [
 				{
 					name: "open first dialog",
@@ -39,12 +40,8 @@
 						var d = new doh.Deferred(),
 							dlg1;
 
-						// Start focus on a button on the page (although we aren't going
-						// to click the button)
-						dojo.byId("button").focus();
-
 						// Create and show first dialog
-						dlg1 = new dijit.Dialog({
+						dlg1 = new Dialog({
 							id: "dlg1",
 							title: "dialog 1",
 							content:
@@ -58,15 +55,15 @@
 								"<input id='dlg1_inputH'><br>"
 						});
 						dlg1.show().then(d.getTestCallback(function(){
-							doh.t(isVisible(dlg1), "dialog 1 is visible");
+							doh.t(helpers.isVisible(dlg1), "dialog 1 is visible");
 
-							var dialog1Z = dojo.style(dlg1.domNode, "zIndex"),
-								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+							var dialog1Z = domStyle.get(dlg1.domNode, "zIndex"),
+								underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
 
 							doh.t(dialog1Z > underlayZ, "dialog1 (zIndex=" + dialog1Z +
 								") above underlay (zIndex=" + underlayZ + ")");
 
-							doh.is("dlg1_inputA", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
+							doh.is("dlg1_inputA", focus.curNode.id, "focus is on the first field");
 
 							// For back-compat, startup() should be called on children even if Dialog.startup()
 							// isn't called explicitly.							
@@ -81,11 +78,11 @@
 					timeout: 20000,
 					runTest: function(){
 						var d = new doh.Deferred(),
-							dlg1 = dijit.byId("dlg1"),
+							dlg1 = registry.byId("dlg1"),
 							dlg2;
 
 						// Create and show second dialog
-						dlg2 = new dijit.Dialog({
+						dlg2 = new Dialog({
 							id: "dlg2",
 							title: "dialog 2",
 							content:
@@ -97,18 +94,18 @@
 								"<input id='dlg2_inputF'><br>"
 						});
 						dlg2.show().then(d.getTestCallback(function(){
-							doh.t(isVisible(dlg2), "dialog 2 is visible");
+							doh.t(helpers.isVisible(dlg2), "dialog 2 is visible");
 
-							var dialog1Z = dojo.style(dlg1.domNode, "zIndex"),
-								dialog2Z = dojo.style(dlg2.domNode, "zIndex"),
-								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+							var dialog1Z = domStyle.get(dlg1.domNode, "zIndex"),
+								dialog2Z = domStyle.get(dlg2.domNode, "zIndex"),
+								underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
 
 							doh.t(underlayZ > dialog1Z, "underlay (zIndex=" + underlayZ +
 								") above dialog1 (zIndex=" + dialog1Z + ")");
 							doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
 								") above underlay (zIndex=" + underlayZ + ")");
 
-							doh.is("dlg2_inputA", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
+							doh.is("dlg2_inputA", focus.curNode.id, "focus is on the first field");
 						}));
 
 						return d;
@@ -119,19 +116,19 @@
 					timeout: 20000,
 					runTest: function(){
 						var d = new doh.Deferred(),
-							dlg1 = dijit.byId("dlg1"),
-							dlg2 = dijit.byId("dlg2");
+							dlg1 = registry.byId("dlg1"),
+							dlg2 = registry.byId("dlg2");
 
 						dlg1.destroy();
 
 						setTimeout(d.getTestCallback(function(){
-							doh.t(isVisible(dlg2), "dialog 2 is still visible");
-							doh.t(isVisible(dojo.global.dijit._underlay), "underlay is still visible");
+							doh.t(helpers.isVisible(dlg2), "dialog 2 is still visible");
+							doh.t(helpers.isVisible(DialogUnderlay._singleton), "underlay is still visible");
 
-							doh.is("dlg2_inputA", dojo.global.dijit.focus.curNode.id, "dialog 2 still has focus");
+							doh.is("dlg2_inputA", focus.curNode.id, "dialog 2 still has focus");
 
-							var dialog2Z = dojo.style(dlg2.domNode, "zIndex"),
-								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+							var dialog2Z = domStyle.get(dlg2.domNode, "zIndex"),
+								underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
 
 							doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
 								") above underlay (zIndex=" + underlayZ + ")");
@@ -146,11 +143,11 @@
 					timeout: 20000,
 					runTest: function(){
 						var d = new doh.Deferred(),
-							dlg2 = dijit.byId("dlg2"),
+							dlg2 = registry.byId("dlg2"),
 							dlg3;
 
 						// Create and show third dialog
-						dlg3 = new dijit.Dialog({
+						dlg3 = new Dialog({
 							id: "dlg3",
 							title: "dialog 3",
 							content:
@@ -161,20 +158,20 @@
 
 						});
 						dlg3.show().then(d.getTestCallback(function(){
-							doh.t(isVisible(dlg3), "dialog 3 is visible");
+							doh.t(helpers.isVisible(dlg3), "dialog 3 is visible");
 
 							// Even though a dialog was deleted, the zIndex of the dialog 3
 							// should be above dialog 2.    This test is to make sure we don't
 							// merely use _dialogStack.length to compute zIndex
-							var dialog2Z = dojo.style(dlg2.domNode, "zIndex"),
-								dialog3Z = dojo.style(dlg3.domNode, "zIndex"),
-								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+							var dialog2Z = domStyle.get(dlg2.domNode, "zIndex"),
+								dialog3Z = domStyle.get(dlg3.domNode, "zIndex"),
+								underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
 							doh.t(underlayZ > dialog2Z, "underlay (zIndex=" + underlayZ +
 								") above dialog2 (zIndex=" + dialog2Z + ")");
 							doh.t(dialog3Z > underlayZ, "dialog3 (zIndex=" + dialog3Z +
 								") above underlay (zIndex=" + underlayZ + ")");
 
-							doh.is("dlg3_inputA", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
+							doh.is("dlg3_inputA", focus.curNode.id, "focus is on the first field");
 						}));
 
 						return d;
@@ -185,11 +182,11 @@
 					timeout: 30000,
 					runTest: function(){
 						var d = new doh.Deferred(),
-							dlg3 = dijit.byId("dlg3"),
+							dlg3 = registry.byId("dlg3"),
 							dlg4;
 
 						// Create and show fourth dialog
-						dlg4 = new dijit.Dialog({
+						dlg4 = new Dialog({
 							id: "dlg4",
 							title: "dialog 4",
 							content:
@@ -197,17 +194,17 @@
 								"<input id='dlg4_inputB'>"
 						});
 						dlg4.show().then(d.getTestCallback(function(){
-							doh.t(isVisible(dlg4), "dialog 4 is visible");
+							doh.t(helpers.isVisible(dlg4), "dialog 4 is visible");
 
-							var dialog3Z = dojo.style(dlg3.domNode, "zIndex"),
-								dialog4Z = dojo.style(dlg4.domNode, "zIndex"),
-								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+							var dialog3Z = domStyle.get(dlg3.domNode, "zIndex"),
+								dialog4Z = domStyle.get(dlg4.domNode, "zIndex"),
+								underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
 							doh.t(underlayZ > dialog3Z, "underlay (zIndex=" + underlayZ +
 								") above dialog3 (zIndex=" + dialog3Z + ")");
 							doh.t(dialog4Z > underlayZ, "dialog4 (zIndex=" + dialog4Z +
 								") above underlay (zIndex=" + underlayZ + ")");
 
-							doh.is("dlg4_inputA", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
+							doh.is("dlg4_inputA", focus.curNode.id, "focus is on the first field");
 						}));
 
 						return d;
@@ -218,17 +215,17 @@
 					timeout: 40000,
 					runTest: function(){
 						var d = new doh.Deferred(),
-							dlg3 = dijit.byId("dlg3"),
-							dlg4 = dijit.byId("dlg4");
+							dlg3 = registry.byId("dlg3"),
+							dlg4 = registry.byId("dlg4");
 
 						dlg3.hide().then(d.getTestCallback(function(){
-							doh.t(isVisible(dlg4), "dialog 4 is still visible");
-							doh.t(isVisible(dojo.global.dijit._underlay), "underlay is still visible");
+							doh.t(helpers.isVisible(dlg4), "dialog 4 is still visible");
+							doh.t(helpers.isVisible(DialogUnderlay._singleton), "underlay is still visible");
 
-							doh.is("dlg4_inputA", dojo.global.dijit.focus.curNode.id, "dialog 4 still has focus");
+							doh.is("dlg4_inputA", focus.curNode.id, "dialog 4 still has focus");
 
-							var dialog4Z = dojo.style(dlg4.domNode, "zIndex"),
-								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+							var dialog4Z = domStyle.get(dlg4.domNode, "zIndex"),
+								underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
 
 							doh.t(dialog4Z > underlayZ, "dialog4 (zIndex=" + dialog4Z +
 								") above underlay (zIndex=" + underlayZ + ")");
@@ -243,24 +240,26 @@
 					timeout: 30000,
 					runTest: function(){
 						var d = new doh.Deferred(),
-							dlg2 = dijit.byId("dlg2"),
-							dlg3 = dijit.byId("dlg3"),
-							dlg4 = dijit.byId("dlg4");
-
-						// Closing fourth dialog should move focus to second dialog,
-						// since we already destroyed the third dialog
-						dlg4.hide().then(d.getTestCallback(function(){
-							doh.t(isHidden(dlg4), "dialog 4 is hidden");
-							doh.t(isHidden(dlg3), "dialog 3 is hidden");
-							doh.t(isVisible(dlg2), "dialog 2 is visible");
-
-							var dialog2Z = dojo.style(dlg2.domNode, "zIndex"),
-								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
-							doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
-								") above underlay (zIndex=" + underlayZ + ")");
-
-							doh.is("dlg2_inputA", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
-						}));
+							dlg2 = registry.byId("dlg2"),
+							dlg3 = registry.byId("dlg3"),
+							dlg4 = registry.byId("dlg4");
+
+						// Closing fourth dialog should move focus to second dialog, since we already destroyed the
+						// third dialog.  Delay needed for IE9+ where focus shift is asynchronous.
+						dlg4.hide().then(function(){
+							setTimeout(d.getTestCallback(function(){
+								doh.t(helpers.isHidden(dlg4), "dialog 4 is hidden");
+								doh.t(helpers.isHidden(dlg3), "dialog 3 is hidden");
+								doh.t(helpers.isVisible(dlg2), "dialog 2 is visible");
+
+								var dialog2Z = domStyle.get(dlg2.domNode, "zIndex"),
+										underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
+								doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
+										") above underlay (zIndex=" + underlayZ + ")");
+
+								doh.is("dlg2_inputA", focus.curNode.id, "focus is on the first field");
+							}));
+						});
 
 						return d;
 					}
@@ -270,16 +269,19 @@
 					timeout: 30000,
 					runTest: function(){
 						var d = new doh.Deferred(),
-							dlg2 = dijit.byId("dlg2");
+							dlg2 = registry.byId("dlg2");
 
 						// Since we already destroyed first dialog, closing second dialog should hide underlay and
-						// revert focus to the main page
-						dlg2.hide().then(d.getTestCallback(function(){
-							doh.t(isHidden(dlg2), "dialog 4 is hidden");
-							doh.t(isHidden(dojo.global.dijit._underlay), "underlay hidden");
-
-							doh.is("button", dojo.global.dijit.focus.curNode.id, "focus is on the main page");
-						}));
+						// revert focus to the main page.  Need the setTimeout() for IE9+ where focus change is not
+						// instant.
+						dlg2.hide().then(function(){
+							setTimeout(d.getTestCallback(function(){
+								doh.t(helpers.isHidden(dlg2), "dialog 4 is hidden");
+								doh.t(helpers.isHidden(DialogUnderlay._singleton), "underlay hidden");
+
+								doh.is("button", focus.curNode.id, "focus is on the main page");
+							}));
+						});
 
 						return d;
 					}
@@ -287,18 +289,18 @@
 			]);
 
 			var dlgA, dlgB;
-			doh.register("concurrent hide show", {
+			doh.register("concurrent hide show (multiple dialogs)", {
 				name: "concurrent hide show",
 				timeout: 20000,
 				setUp: function(){
 					// Create and show first dialog
-					dlgA = new dijit.Dialog({
+					dlgA = new Dialog({
 						id: "dlgA",
 						title: "Dialog A",
 						content:
 							"<button type='button'>OK</button>"
 					});
-					dlgB = new dijit.Dialog({
+					dlgB = new Dialog({
 						id: "dlgB",
 						title: "dialog B",
 						content:
@@ -322,12 +324,12 @@
 							return;
 						}
 						
-						doh.t(isVisible(shown), shown.title + " visible");
-						doh.t(isHidden(hidden), hidden.title + " hidden");
-						doh.t(isVisible(dojo.global.dijit._underlay), "underlay visible");
+						doh.t(helpers.isVisible(shown), shown.title + " visible");
+						doh.t(helpers.isHidden(hidden), hidden.title + " hidden");
+						doh.t(helpers.isVisible(DialogUnderlay._singleton), "underlay visible");
 
-						var shownZ = dojo.style(shown.domNode, "zIndex"),
-							underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+						var shownZ = domStyle.get(shown.domNode, "zIndex"),
+							underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
 						doh.t(shownZ > underlayZ, "visible dialog (zIndex=" + shownZ +
 							") above underlay (zIndex=" + underlayZ + ")");
 
@@ -353,16 +355,16 @@
 				function create(){
 					console.log("creating slow, fast");
 					var d = new doh.Deferred();
-					slow = new dijit.Dialog({
+					slow = new Dialog({
 						id: "slow",
 						title: "Dialog C",
 						content:
 							"Hello world " +
-							"<button type='button' id='slowOK' onfocus='dojo.global.slowFocused=true;'>OK</button>" +
+							"<button type='button' id='slowOK' onfocus='window.slowFocused=true;'>OK</button>" +
 							"<button type='button' id='slowCancel'>Cancel</button>",
 						duration: 500
 					});
-					fast = new dijit.Dialog({
+					fast = new Dialog({
 						id: "fast",
 						title: "dialog D",
 						content:
@@ -384,14 +386,13 @@
 						}), slow.duration / 2);
 						
 						setTimeout(d.getTestCallback(function(){
-							doh.t(isVisible(slow), "dialog C visible");
-							doh.t(isVisible(fast), "dialog D visible");
-							doh.f(dojo.global.slowFocused, "dialog C never got focus")
+							doh.t(helpers.isVisible(slow), "dialog C visible");
+							doh.t(helpers.isVisible(fast), "dialog D visible");
+							doh.f(window.slowFocused, "dialog C never got focus")
 						}), slow.duration * 2);
 						return d;
 					}
 				},
-
 				{
 					name: "close dialogD",
 					timeout: 20000,
@@ -401,12 +402,130 @@
 						fast.hide();
 						
 						setTimeout(d.getTestCallback(function(){
-							doh.is("slowOK", dojo.global.dijit.focus.curNode.id, "focused to dialog C");
-							doh.t(dojo.global.slowFocused, "onfocus handler working");
+							doh.is("slowOK", focus.curNode.id, "focused to dialog C");
+							doh.t(window.slowFocused, "onfocus handler working");
 						}), fast.duration * 2);
 
 						return d;
 					}
+				},
+				{
+					name: "close dialogC",
+					timeout: 20000,
+					runTest: function(){
+						return slow.hide();
+					}
+				}
+			]);
+
+			doh.register("fast double hide", [
+				function create(){
+					var d = new doh.Deferred();
+
+					// Create a test dialog
+					dlg = new Dialog({
+						id: "doubleHide",
+						title: "Double Hide",
+						content: "Hello World",
+						duration: 100
+					});
+
+					// First show it
+					var secondHideCalled;
+					dlg.show().then(d.getTestErrback(function(){
+						// Then call hide(), as though user had clicked close icon.
+						// Return from this test when this hide() call completes.
+						dlg.hide().then(d.getTestCallback(function(){
+							doh.t(secondHideCalled, "hide() was called while hide() in progress and no problems");
+							dlg.hide();	// this should also have no effect
+						}));
+
+						// While first hide() is in progress, call hide() a few more times to make sure it
+						// doesn't break anything
+						dlg.hide();	// should do nothing
+						setTimeout(d.getTestErrback(function(){
+							dlg.hide();	// should also do nothing
+							secondHideCalled = true;
+						}), 10);
+					}));
+					return d;
+				}
+			]);
+
+			doh.register("concurrent show hide (single dialog)", [
+				function show(){
+					var d = new doh.Deferred();
+
+					var onShowCtr = 0,
+						dlg = new Dialog({
+							id: "show",
+							title: "onShow Dialog",
+							content:"Hello world ",
+							onShow: function(){ onShowCtr++; }
+						});
+
+					doh.is(1, Dialog._dialogStack.length, "initially, no dialogs in stack");
+					dlg.show();
+					doh.is(1, onShowCtr, "onShow first time");
+					dlg.hide();
+					doh.is(1, onShowCtr, "onHide first time");
+					dlg.show();
+					doh.is(2, onShowCtr, "onShow second time");
+					dlg.hide().then(d.getTestCallback(function(){
+						doh.is(2, onShowCtr, "onHide second time");
+						doh.is(1, Dialog._dialogStack.length, "at end, no dialogs in stack");
+					}));
+
+					return d;
+				}
+			]);
+
+			doh.register("zero duration", [
+				{
+					name: "open",
+					timeout: 10000,
+					runTest: function(){
+						dlg1 = new Dialog({
+							id: "dlg1",
+							title: "dialog 1",
+							duration: 0,
+							content: "<input id='dlg1_inputA'>"
+						});
+
+						var promise = dlg1.show();
+						doh.t(promise.isResolved(), "resolved");
+						doh.t(helpers.isVisible(dlg1), "dialog visible");
+					}
+				},
+				{
+					name: "close",
+					timeout: 10000,
+					runTest: function(){
+						var promise = dlg1.hide();
+						doh.t(promise.isResolved(), "resolved");
+						doh.t(helpers.isHidden(dlg1), "dialog hidden");
+					}
+				}
+			]);
+
+			doh.register("sizing", [
+				{
+					name: "href",
+					timeout: 10000,
+					runTest: function(){
+						var dlg1 = new Dialog({
+							id: "bigHref",
+							title: "big dialog with href",
+							href: "loremIpsum"
+						});
+
+						return dlg1.show().then(function(){
+							var dlgPos = domGeom.position(dlg1.domNode),
+								viewport = winUtils.getBox();
+							doh.t(dlgPos.h < viewport.h, "viewport height");
+							doh.t(dlgPos.y > 0, "position");
+						});
+					}
 				}
 			]);
 
diff --git a/dijit/tests/Fieldset.html b/dijit/tests/Fieldset.html
new file mode 100644
index 0000000..5a1c033
--- /dev/null
+++ b/dijit/tests/Fieldset.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>Fieldset Widget Automated (non-robot) Tests</title>
+
+	<script type="text/javascript" src="boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/dom", "dojo/on", "dojo/parser",
+			"dijit/Fieldset",
+			"dojo/domReady!"
+		], function(doh, dom, on, parser, Fieldset){
+
+			doh.register("declarative", function(){
+				var d = new doh.Deferred();
+
+				parser.parse();
+
+				doh.t(!!fs1, "widget created");
+				doh.t(fs1.open, "open");
+				doh.is("Declarative", fs1.titleNode.innerHTML);
+
+				on.emit(fs1.titleNode, "click", {bubbles: true});
+				setTimeout(d.getTestCallback(function(){
+					doh.f(fs1.open, "closed");
+					doh.is("none", fs1.hideNode.style.display, "hidden")
+				}), 500);
+
+				return d;
+			});
+
+			doh.register("programmatic", function(){
+				var fs2 = (new Fieldset({
+					id: 'fs2',
+					title: 'Programmatic',
+					content: '<p>I was created programmatically!</p>'
+				})).placeAt(document.body);
+				doh.t(!!fs2, "widget created");
+			});
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">Fieldset Automated (non-robot) tests</h1>
+	<fieldset id="fs1" data-dojo-id="fs1" data-dojo-type="dijit/Fieldset">
+		<legend>Declarative</legend>
+		<p>Some content</p>
+	</fieldset>
+</body>
+</html>
+
+
diff --git a/dijit/tests/Menu.html b/dijit/tests/Menu.html
new file mode 100644
index 0000000..be8579f
--- /dev/null
+++ b/dijit/tests/Menu.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>Menu Automated (non-robot) Tests</title>
+
+	<script type="text/javascript" src="boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/dom", "dojo/dom-class", "dojo/on", "dojo/parser", "dojo/query", "dojo/domReady!",
+
+			"dojo/NodeList-dom",	// attr()
+			"dijit/DropDownMenu", "dijit/RadioMenuItem", "dijit/MenuSeparator"			// used by parser
+		], function(doh, dom, domClass, on, parser, query){
+
+			doh.register("parse", function parse(){
+				return parser.parse();
+			});
+
+			doh.register("RadioMenuItem", [
+				function click(){
+					// initial conditions
+					doh.is("g1r2, g2r2", query(".dijitRadioMenuItemChecked").attr("id").join(", "), "initially checked");
+
+					// click to change selected value in group 1; group 2 shouldn't change
+					on.emit(dom.byId("g1r3"), "click", {bubbles: true, cancelable: true});
+					doh.is("g1r3, g2r2", query(".dijitRadioMenuItemChecked").attr("id").join(", "), "clicked g1r3");
+
+					// click to change selected value in group 2; group 1 shouldn't change
+					on.emit(dom.byId("g2r1"), "click", {bubbles: true, cancelable: true});
+					doh.is("g1r3, g2r1", query(".dijitRadioMenuItemChecked").attr("id").join(", "), "clicked g2r1");
+
+					// click currently selected node; shouldn't change anything
+					on.emit(dom.byId("g1r3"), "click", {bubbles: true, cancelable: true});
+					doh.is("g1r3, g2r1", query(".dijitRadioMenuItemChecked").attr("id").join(", "), "clicked g1r3 again");
+				},
+				function set(){
+					// change selected item in group 1
+					g1r1.set("checked", true);
+					doh.is("g1r1, g2r1", query(".dijitRadioMenuItemChecked").attr("id").join(", "), "set g2r1");
+
+					// clear selected item in group 1
+					g1r1.set("checked", false);
+					doh.is("g2r1", query(".dijitRadioMenuItemChecked").attr("id").join(", "), "cleared g2r1");
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">Menu Automated (non-robot) tests</h1>
+	<div id="menu" data-dojo-type="dijit/DropDownMenu">
+		<div id="g1r1" data-dojo-id="g1r1" data-dojo-type="dijit/RadioMenuItem"
+			 data-dojo-props="group: 'g1'">red</div>
+		<div id="g1r2" data-dojo-id="g1r2" data-dojo-type="dijit/RadioMenuItem"
+			 data-dojo-props="group: 'g1', checked:true">yellow</div>
+		<div id="g1r3" data-dojo-id="g1r3" data-dojo-type="dijit/RadioMenuItem"
+			 data-dojo-props="group: 'g1', checked:false /*set to false for testing*/">green</div>
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div id="g2r1" data-dojo-id="g2r1" data-dojo-type="dijit/RadioMenuItem"
+			 data-dojo-props="group: 'g2'">small</div>
+		<div id="g2r2" data-dojo-id="g2r2" data-dojo-type="dijit/RadioMenuItem"
+			 data-dojo-props="group: 'g2', checked:true">normal</div>
+		<div id="g2r3" data-dojo-id="g2r3" data-dojo-type="dijit/RadioMenuItem"
+			 data-dojo-props="group: 'g2'">large</div>
+	</div>
+</body>
+</html>
diff --git a/dijit/tests/NodeList-instantiate.html b/dijit/tests/NodeList-instantiate.html
index 868288c..b2f9165 100644
--- a/dijit/tests/NodeList-instantiate.html
+++ b/dijit/tests/NodeList-instantiate.html
@@ -5,7 +5,7 @@
 		<style type="text/css">
 			@import "../themes/claro/document.css";
 			@import "css/dijitTests.css";
-			#container { height:200px; }
+			#container { height: 200px; }
 		</style>
 
 		<!-- required: a default dijit theme: -->
@@ -13,15 +13,15 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- not needed, for testing alternate themes -->
 		<script type="text/javascript" src="_testCommon.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("doh.runner");
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-			dojo.require("dijit._Widget");
+			dojo.require("dojo.on");
+			dojo.require("dijit._WidgetBase");
 			dojo.require("dijit.form.Button");
 			dojo.require("dijit.layout.TabContainer");
 			dojo.require("dijit.layout.ContentPane");
@@ -29,55 +29,55 @@
 	    	dojo.ready(function(){
 
 				// declare a simple widget to use as a base test:
-				dojo.declare("test._Widget",dijit._Widget,{
-					message:"",
+				dojo.declare("TestWidget", dijit._WidgetBase, {
+					message: "",
 					postCreate:function(){
 						this.inherited(arguments);
-						this.connect(this.domNode,"onclick","workit");
-						dojo.style(this.domNode,{
-							cursor:"pointer",
-							color:"#333"
+						this.own(dojo.on(this.domNode, "click", dojo.hitch(this, "workit")));
+						dojo.style(this.domNode, {
+							cursor: "pointer",
+							color: "#333"
 						});
 						this.domNode.innerHTML += this.message +" ("+this.id +")";
-						console.log('created',this.id);
+						console.log('created', this.id);
 					},
-					workit:function(){
-						dojo.place(this.domNode,this.domNode.parentNode,"end");
+					workit: function(){
+						dojo.place(this.domNode, this.domNode.parentNode, "end");
 					}
 				});
 		
 				doh.register("Instantiate", [
 					function testWidget(){
-						dojo.query("#list1 li").instantiate(test._Widget,{}).connect("onclick",console.log);
+						dojo.query("#list1 li").instantiate(TestWidget, {}).connect("onclick", console.log);
 	
-						var li = dijit.byId("test__Widget_0");
-						doh.t(li, "test__Widget_0 exists");
-						doh.is("pointer", dojo.style("test__Widget_0", "cursor"));
-						doh.is("inner (test__Widget_0)", li.domNode.innerHTML);
+						var li = dijit.byId("TestWidget_0");
+						doh.t(li, "TestWidget_0 exists");
+						doh.is("pointer", dojo.style("TestWidget_0", "cursor"));
+						doh.is("inner (TestWidget_0)", li.domNode.innerHTML);
 					},
 					
 					function testWidget2(){
-						dojo.query("#list2 li").instantiate(test._Widget,{ message:"woot" });
+						dojo.query("#list2 li").instantiate(TestWidget, { message: "woot" });
 	
-						li = dijit.byId("test__Widget_12");
-						doh.t(li, "test__Widget_12 exists");
-						doh.is("pointer", dojo.style("test__Widget_12", "cursor"));
-						doh.is("innerwoot (test__Widget_12)", li.domNode.innerHTML);
+						li = dijit.byId("TestWidget_12");
+						doh.t(li, "TestWidget_12 exists");
+						doh.is("pointer", dojo.style("TestWidget_12", "cursor"));
+						doh.is("innerwoot (TestWidget_12)", li.domNode.innerHTML);
 					},
 	
 					function TabContainer(){
 						// make a tab container from some div, and all it's children div's
 						dojo.query("#container")
 							.forEach(function(n){
-								dojo.query("div",n)
+								dojo.query("div", n)
 									// create contentpanes from the children and style them
-									.instantiate(dijit.layout.ContentPane,{})
-									.forEach(function(wn,idx){
-										dojo.mixin(dijit.byNode(wn),{ title:"tab" + (idx + 1) })
+									.instantiate(dijit.layout.ContentPane, {})
+									.forEach(function(wn, idx){
+										dojo.mixin(dijit.byNode(wn), { title: "tab" + (idx + 1) })
 									})
 								;
 							})
-							.instantiate(dijit.layout.TabContainer,{})
+							.instantiate(dijit.layout.TabContainer, {})
 						;
 						// should we add auto-startup calling?
 						dijit.byId("container").startup();
@@ -91,15 +91,15 @@
 							doh.is("tab" + (i + 1), tab.label);
 						});
 	
-						var childrenContent = tc.containerNode.childNodes;
-						doh.is(3, childrenContent.length);
-						dojo.forEach(childrenContent, function(childrenContent, i){ doh.is("pane"+(i+1), childrenContent.innerHTML); })
+						var children = tc.getChildren();
+						doh.is(3, children.length);
+						dojo.forEach(children, function(child, i){ doh.is("pane"+(i+1), child.domNode.innerHTML); })
 					},
 	
 					function Buttons(){
 						// bunches of buttons, use you imagination on how to relate them to something
 						dojo.query("#buttonTest").forEach(function(n){
-							dojo.query("button",n).instantiate(dijit.form.Button,{
+							dojo.query("button", n).instantiate(dijit.form.Button, {
 								onClick:function(){
 									this.containerNode.innerHTML = this.label + " was clicked";
 								}
diff --git a/dijit/tests/ProgressBar.html b/dijit/tests/ProgressBar.html
index e99bf48..74fcc47 100644
--- a/dijit/tests/ProgressBar.html
+++ b/dijit/tests/ProgressBar.html
@@ -1,13 +1,13 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<title>Dojo Toolkit - ProgressBar test</title>
 
 	<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"/>
 
+	<script src="boilerplate.js"></script>
+
 	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
 		body {
 			margin: 1em;
 		}
@@ -17,29 +17,19 @@
 		.smallred .dijitProgressBarLabel {
 			display:none;
 		}
-		#html5ish, #html5ish2 { width:500px; }
 	</style>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
-
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.ProgressBar");
-		dojo.require("dojo.parser");	// scan page for widgets
-		dojo.require("dojo.string");
-		dojo.require("doh.runner");
+		require([
+			"doh/runner",
+			"dojo/Deferred", "dojo/dom", "dojo/dom-class", "dojo/dom-geometry", "dojo/on", "dojo/parser", "dojo/query", "dojo/string",
+			"dijit/registry", "dijit/ProgressBar", "dojo/domReady!"
+		], function(doh, Deferred, dom, domClass, domGeometry, on, parser, query, string, registry, ProgressBar){
+
+			var dir = domGeometry.isBodyLtr() ? "ltr" : "rtl";
 
-		dojo.ready(function go(){
 			doh.register("parse", function(){
-				dojo.parser.parse();
+				return parser.parse();
 			});
 
 			doh.register("other setup", function(){
@@ -47,24 +37,29 @@
 				// the test is automated.
 
 				// note that programmatic instantiation doesn't pull any parameters from the srcNodeRef, not even id
-				var theBar = new dijit.ProgressBar({id: "testBar", width: 400, maximum: 256, duration: 2000,
-					report:function(percent){
-						return dojo.string.substitute("${0} out of ${1} max chars", [this.get('value'), this.maximum]);
+				var theBar = new ProgressBar({
+					id: "testBar",
+					width: 400,
+					maximum: 256,
+					duration: 2000,
+					dir: dir,
+					report: function(percent){
+						return string.substitute("${0} out of ${1} max chars", [this.get('value'), this.maximum]);
 					}
-				}, dojo.byId("testBar"));
-	
-				dojo.byId("test").value="";
-				dojo.byId("progressValue").value = dijit.byId("setTestBar").value;
-				dojo.byId("maximum").value = dijit.byId("setTestBar").maximum;
-				dojo.connect(dojo.byId("test"), "onkeyup", null, keyUpHandler);
-				dojo.connect(dojo.byId("set"), "onclick", null, setParameters);
-				dojo.connect(dojo.byId("startTimer"), "onclick", null,
-					function(){ remoteProgress(dijit.byId("timerBar")); } );
-					
+				}, dom.byId("testBar"));
+
+				dom.byId("test").value="";
+				dom.byId("progressValue").value = registry.byId("setTestBar").value;
+				dom.byId("maximum").value = registry.byId("setTestBar").maximum;
+				on(dom.byId("test"), "keyup", keyUpHandler);
+				on(dom.byId("set"), "click", setParameters);
+				on(dom.byId("startTimer"), "click", function(){ remoteProgress(registry.byId("timerBar")); } );
+
 				// test 7
-				new dijit.ProgressBar({
-					style:"width:400px",
-					indeterminate:true
+				new ProgressBar({
+					style: "width:400px",
+					indeterminate: true,
+					dir: dir
 				}, "pi");
 			});
 
@@ -72,12 +67,12 @@
 				{
 					name: "set valid value",
 					runTest: function(){
-						var progressBar = dijit.byId("setTestBar");
+						var progressBar = registry.byId("setTestBar");
 						progressBar.set({maximum: 100, value: 58});
-						
+
 						doh.is("58", progressBar.progress);
-						doh.is("58%", dojo.byId("setTestBar_label").innerHTML);
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("58%", dom.byId("setTestBar_label").innerHTML);
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 
 						var width = visualProgress.style.width;
 						width = width.substring(0, width.length-1);
@@ -85,16 +80,29 @@
 					}
 				},
 				{
+					name: "aria roles and attribute",
+					runTest: function(){
+						var progressBar = registry.byId("setTestBar");
+						doh.is("progressbar", progressBar.domNode.getAttribute("role"), "ProgressBar needs role=progressbar");
+						doh.is(58, progressBar.domNode.getAttribute("aria-valuenow"), "expect aria-valuenow of 58");
+						doh.is(0, progressBar.domNode.getAttribute("aria-valuemin"), "expect aria-valuemin of 0");
+						doh.is(100, progressBar.domNode.getAttribute("aria-valuemax"), "expect aria-valuemax of 100");
+						doh.is("setTestBar_label", progressBar.domNode.getAttribute("aria-labelledby"), "expect aria-labelledby on progressbar");
+						progressBar = registry.byId("pi");
+						doh.f(progressBar.domNode.getAttribute("aria-valuenow"), "indeterminate progressbars should not have aria-valuenow");
+					}
+				},
+				{
 					name: "set value too high",
 					runTest: function(){
 						var d = new doh.Deferred();
 
-						var progressBar = dijit.byId("setTestBar");
+						var progressBar = registry.byId("setTestBar");
 						progressBar.set({maximum: 100, value: 101});
 
 						doh.is("100", progressBar.progress);
-						doh.is("100%", dojo.byId("setTestBar_label").innerHTML);
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("100%", dom.byId("setTestBar_label").innerHTML);
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						doh.is("100%", visualProgress.style.width);
 					}
 				},
@@ -103,12 +111,12 @@
 					runTest: function(){
 						var d = new doh.Deferred();
 
-						var progressBar = dijit.byId("setTestBar");
+						var progressBar = registry.byId("setTestBar");
 						progressBar.set({maximum: 100, value: 0});
 
 						doh.is("0", progressBar.progress);
-						doh.is("0%", dojo.byId("setTestBar_label").innerHTML);
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("0%", dom.byId("setTestBar_label").innerHTML);
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						doh.is("0%", visualProgress.style.width);
 					}
 				},
@@ -117,23 +125,23 @@
 					runTest: function(){
 						var d = new doh.Deferred();
 
-						var progressBar = dijit.byId("setTestBar");
+						var progressBar = registry.byId("setTestBar");
 						progressBar.set({maximum: 100, value: 100});
 
 						doh.is("100", progressBar.progress);
-						doh.is("100%", dojo.byId("setTestBar_label").innerHTML);
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("100%", dom.byId("setTestBar_label").innerHTML);
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						doh.is("100%", visualProgress.style.width);
 					}
 				},
 				{
 					name: "report callback",
 					runTest: function(){
-						var progressBar = dijit.byId("testBar");
+						var progressBar = registry.byId("testBar");
 						progressBar.set({value: 79});
 						doh.is("79", progressBar.progress);
-						doh.is("79 out of 256 max chars", dojo.byId("testBar_label").innerHTML);
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("79 out of 256 max chars", dom.byId("testBar_label").innerHTML);
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						width = visualProgress.style.width;
 						doh.is("30.8", width.substring(0,4));
 					}
@@ -141,40 +149,40 @@
 				{
 					name: "default maximum",
 					runTest: function(){
-						var progressBar = dijit.byId("implied1");
+						var progressBar = registry.byId("implied1");
 						doh.is("50", progressBar.progress);
-						doh.is("50%", dojo.byId("implied1_label").innerHTML);
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("50%", dom.byId("implied1_label").innerHTML);
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						doh.is("50%", visualProgress.style.width);
-							
-						progressBar = dijit.byId("implied2");
+
+						progressBar = registry.byId("implied2");
 						doh.is("50", progressBar.progress);
-						doh.is("50%", dojo.byId("implied2_label").innerHTML);
-						visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("50%", dom.byId("implied2_label").innerHTML);
+						visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						doh.is("50%", visualProgress.style.width);
 					}
 				},
 				{
 					name: "set indeterminate, no label",
 					runTest: function(){
-						var progressBar = dijit.byId("indeterminateBar");
+						var progressBar = registry.byId("indeterminateBar");
 						progressBar.set({indeterminate: true, label: ''});
 
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						doh.is("100%", visualProgress.style.width);
-						doh.t(dojo.hasClass(progressBar.domNode, "dijitProgressBarIndeterminate"), "has class dijitProgressBarIndeterminate");
+						doh.t(domClass.contains(progressBar.domNode, "dijitProgressBarIndeterminate"), "has class dijitProgressBarIndeterminate");
 					}
 				},
 				{
 					name: "set determinate, no label",
 					runTest: function(){
-						var progressBar = dijit.byId("indeterminateBar");
-						progressBar.set({indeterminate: false, label: ''});	
-						doh.is("50%", dojo.byId("indeterminateBar_label").innerHTML);
+						var progressBar = registry.byId("indeterminateBar");
+						progressBar.set({indeterminate: false, label: ''});
+						doh.is("50%", dom.byId("indeterminateBar_label").innerHTML);
 
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						doh.is("50%", visualProgress.style.width);
-						doh.f(dojo.hasClass(progressBar.domNode, "dijitProgressBarIndeterminate"), "doesn't have class dijitProgressBarIndeterminate");
+						doh.f(domClass.contains(progressBar.domNode, "dijitProgressBarIndeterminate"), "doesn't have class dijitProgressBarIndeterminate");
 					}
 				},
 				{
@@ -182,37 +190,37 @@
 					runTest: function(){
 						var d = new doh.Deferred();
 
-						var progressBar = dijit.byId("indeterminateBar");
+						var progressBar = registry.byId("indeterminateBar");
 						progressBar.set({indeterminate: true, label: 'Loading...'});
 
-						doh.is("Loading...", dojo.byId("indeterminateBar_label").innerHTML);
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
-						doh.is("100%", visualProgress.style.width);						
-						doh.t(dojo.hasClass(progressBar.domNode, "dijitProgressBarIndeterminate"), "has class dijitProgressBarIndeterminate");
+						doh.is("Loading...", dom.byId("indeterminateBar_label").innerHTML);
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("100%", visualProgress.style.width);
+						doh.t(domClass.contains(progressBar.domNode, "dijitProgressBarIndeterminate"), "has class dijitProgressBarIndeterminate");
 					}
 				},
 				{
 					name: "set determinate, custom label",
 					runTest: function(){
-						var progressBar = dijit.byId("indeterminateBar");
+						var progressBar = registry.byId("indeterminateBar");
 						progressBar.set({indeterminate: false, label: 'Loading...'});
-						
-						doh.is("Loading...", dojo.byId("indeterminateBar_label").innerHTML);
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+
+						doh.is("Loading...", dom.byId("indeterminateBar_label").innerHTML);
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						doh.is("50%", visualProgress.style.width);
-						doh.f(dojo.hasClass(progressBar.domNode, "dijitProgressBarIndeterminate"), "doesn't have class dijitProgressBarIndeterminate");
+						doh.f(domClass.contains(progressBar.domNode, "dijitProgressBarIndeterminate"), "doesn't have class dijitProgressBarIndeterminate");
 					}
 				},
 				{
 					name: "programmatic indeterminate",
 					runTest: function(){
-						var progressBar = dijit.byId("pi");
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						var progressBar = registry.byId("pi");
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						doh.is("100%", visualProgress.style.width);
-							
-						doh.t(dojo.hasClass(progressBar.domNode, "dijitProgressBarIndeterminate"), "has class dijitProgressBarIndeterminate");
-						
-						progressBar = dijit.byId("timerBar");
+
+						doh.t(domClass.contains(progressBar.domNode, "dijitProgressBarIndeterminate"), "has class dijitProgressBarIndeterminate");
+
+						progressBar = registry.byId("timerBar");
 						doh.t(80 < progressBar.progress <= 100, "Timer progress was " + progressBar.progress);
 					}
 				},
@@ -221,116 +229,128 @@
 					runTest: function(){
 						var d = new doh.Deferred();
 
-						var progressBar = dijit.byId("setTestBar");
+						var progressBar = registry.byId("setTestBar");
 						progressBar.set({maximum: 0, value: 0});
 
 						doh.is("0", progressBar.progress);
-						doh.is("0%", dojo.byId("setTestBar_label").innerHTML);
-						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("0%", dom.byId("setTestBar_label").innerHTML);
+						var visualProgress = query("div.dijitProgressBarFull", progressBar.domNode)[0];
 						doh.is("0%", visualProgress.style.width);
 					}
+				},
+				{
+					name: "programmatic instantiation without params",
+					runTest: function(doh){
+						var pb, success;
+						try{
+							pb = new ProgressBar();
+							pb.destroyRecursive();
+							success = true;
+						}catch(e){}
+						doh.t(success, "Instantiation w/o params should not throw");
+					}
 				}
 			]);
-			
-			doh.run();
-		});
-
-		// An example of polling on a separate (heartbeat) server thread.  This is useful when the progress
-		// is entirely server bound and there is no existing interaction with the server to determine status.
-
-		// We don't have a server to run against, but a simple heartbeat implementation might look something
-		// like this:
-
-		// function getProgressReport(){
-		//	var dataSource = "http://dojotoolkit.org";
-		//	return dojo.xhrGet({url: dataSource, handleAs: "json", content: {key: "progress"}});
-		// }
-
-		// Instead, we'll just tick off intervals of 10
 
-		var fakeProgress = 0;
-		function getProgressReport(){
-			var deferred = new dojo.Deferred();
-			fakeProgress = Math.min(fakeProgress + 10, 100);
-			deferred.callback(fakeProgress+"%");
-			return deferred;
-		}
-
-		function remoteProgress(bar){
-			var _timer = setInterval(function(){
-				var report = getProgressReport();
-				report.addCallback(function(response){
-					bar.set({value: response});
-					if(response == "100%"){
-						clearInterval(_timer);
-						_timer = null;
-					}
-				});
-			}, 3000); // on 3 second intervals
-		}
-
-		function setParameters(){
-			dijit.byId("setTestBar").set({maximum: dojo.byId("maximum").value, value: dojo.byId("progressValue").value});
-		}
+			doh.run();
 
-		function keyUpHandler(){
-			dijit.byId("testBar").set({value:dojo.byId("test").value.length});
-			dijit.byId("testBarInt").set({value:dojo.byId("test").value.length});
-			dijit.byId("smallTestBar").set({value:dojo.byId("test").value.length});
-		}
+			// An example of polling on a separate (heartbeat) server thread.  This is useful when the progress
+			// is entirely server bound and there is no existing interaction with the server to determine status.
+
+			// We don't have a server to run against, but a simple heartbeat implementation might look something
+			// like this:
+
+			// function getProgressReport(){
+			//	var dataSource = "http://dojotoolkit.org";
+			//	return dojo.xhrGet({url: dataSource, handleAs: "json", content: {key: "progress"}});
+			// }
+
+			// Instead, we'll just tick off intervals of 10
+
+			var fakeProgress = 0;
+			function getProgressReport(){
+				var deferred = new Deferred();
+				fakeProgress = Math.min(fakeProgress + 10, 100);
+				deferred.callback(fakeProgress+"%");
+				return deferred;
+			}
+
+			function remoteProgress(bar){
+				var _timer = setInterval(function(){
+					var report = getProgressReport();
+					report.then(function(response){
+						bar.set({value: response});
+						if(response == "100%"){
+							clearInterval(_timer);
+							_timer = null;
+						}
+					});
+				}, 3000); // on 3 second intervals
+			}
+
+			function setParameters(){
+				registry.byId("setTestBar").set({maximum: dom.byId("maximum").value, value: dom.byId("progressValue").value});
+			}
+
+			function keyUpHandler(){
+				registry.byId("testBar").set({value:dom.byId("test").value.length});
+				registry.byId("testBarInt").set({value:dom.byId("test").value.length});
+				registry.byId("smallTestBar").set({value:dom.byId("test").value.length});
+			}
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Dijit ProgressBar Tests</h1>
 
 	<h3>Test 1</h3>
-	Progress Value <input type="text" name="progressValue" id="progressValue" />
+	<label for="progressValue">Progress Value </label><input type="text" name="progressValue" id="progressValue" />
 	<br>
-	Max Progress Value <input type="text" name="maximum" id="maximum" />
+	<label for="maximum">Max Progress Value </label><input type="text" name="maximum" id="maximum" />
 	<br>
 	<input type="button" name="set" id="set" value="set!" />
 	<br>
-	<div id="setTestBar" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px",
+	<div id="setTestBar" data-dojo-type="dijit/ProgressBar" data-dojo-props='style:"width:400px",
 		maximum:200, value:"20" '></div>
 
 	<h3>Test 2</h3>
-	Write here: <input type="text" value="" name="test" maxLength="256" id="test" style="width:300px"/>
+	<label for="test">Write here: </label><input type="text" value="" name="test" maxLength="256" id="test" style="width:300px"/>
 	<br />
 	<br />
 	<div id="testBar" style='width:300px'></div>
 	<br />
 	Small, without text and background image:
 	<br />
-	<div id="smallTestBar" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px; height:10px", "class":"smallred", maximum:256'></div>
+	<div id="smallTestBar" data-dojo-type="dijit/ProgressBar" data-dojo-props='style:"width:400px; height:10px", "class":"smallred", maximum:256'></div>
 	<br />
 	Show decimal place:
-	<div id="testBarInt" data-dojo-type="dijit.ProgressBar" data-dojo-props='places:1, style:"width:400px",
+	<div id="testBarInt" data-dojo-type="dijit/ProgressBar" data-dojo-props='places:1, style:"width:400px",
 		maximum:256'></div>
 
 	<h3>Test 3</h3>
 	No explicit maximum (both 50%)
-	<div id="implied1" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px",
+	<div id="implied1" data-dojo-type="dijit/ProgressBar" data-dojo-props='style:"width:400px",
 		value:"50" '></div>
 	<br />
-	<div id="implied2" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px",
+	<div id="implied2" data-dojo-type="dijit/ProgressBar" data-dojo-props='style:"width:400px",
 		value:"50%" '></div>
 
 	<h3>Test 4</h3>
 	<input type="button" name="startTimer" id="startTimer" value="Start Timer" />
-	<div id="timerBar" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px", maximum:100, value:"0" '></div>
+	<div id="timerBar" data-dojo-type="dijit/ProgressBar" data-dojo-props='style:"width:400px", maximum:100, value:"0" '></div>
 
 	<h3>Test 5 - indeterminate progess</h3>
 	<input id="indeterminateButton1" type="button" value="Make Indeterminate (default blank label)"
-		onclick="dijit.byId('indeterminateBar').set({indeterminate: true, label: ''});" />
+		onclick="registry.byId('indeterminateBar').set({indeterminate: true, label: ''});" />
 	<input id="labelButton1" type="button" value="Make Determinate (default percentage label)"
-		onclick="dijit.byId('indeterminateBar').set({indeterminate: false, label: ''});" />
+		onclick="registry.byId('indeterminateBar').set({indeterminate: false, label: ''});" />
 	<input id="indeterminateButton2" type="button" value="Make Indeterminate With Label"
-		onclick="dijit.byId('indeterminateBar').set({indeterminate: true, label: 'Loading...'});" />
+		onclick="registry.byId('indeterminateBar').set({indeterminate: true, label: 'Loading...'});" />
 	<input  id="labelButton2" type="button" value="Make Determinate With Label"
-		onclick="dijit.byId('indeterminateBar').set({indeterminate: false, label: 'Loading...'});" />
+		onclick="registry.byId('indeterminateBar').set({indeterminate: false, label: 'Loading...'});" />
 	
-	<div id="indeterminateBar" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px", value:"50" '></div>
+	<div id="indeterminateBar" data-dojo-type="dijit/ProgressBar" data-dojo-props='style:"width:400px", value:"50" '></div>
 
 	<h3>Test 6 - programatic indeterminate</h3>
 	<div id="pi"></div>
diff --git a/dijit/tests/Tooltip-placement.html b/dijit/tests/Tooltip-placement.html
index 34d6cfd..24cdce5 100644
--- a/dijit/tests/Tooltip-placement.html
+++ b/dijit/tests/Tooltip-placement.html
@@ -4,53 +4,38 @@
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dojo Tooltip Placement Test</title>
 
+	<script type="text/javascript" src="boilerplate.js"></script>
+
 	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
-		
 		div {font-size:9px}
 	</style>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojo.parser");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.form.ValidationTextBox");
-		dojo.require("dijit.layout.ContentPane");
-		
-		dojo.ready(function(){
-			doh.register("parse", function(){
-				dojo.parser.parse();
-			});
-
-			doh.register("other setup", function(){
-				dijit._MasterTooltip.prototype.duration = 0.05; // speed up tooltip fading
-				var view = dojo.window.getBox();
+		require([
+			"doh/runner",
+			"dojo/dom", "dojo/dom-geometry", "dojo/dom-style", "dojo/query", "dojo/sniff", "dojo/window",
+			"dijit/Tooltip",
+			"dojo/domReady!"
+		], function(doh, dom, domGeom, domStyle, query, has, winUtils, Tooltip){
+			doh.register("setup", function(){
+				Tooltip._MasterTooltip.prototype.duration = 0.05; // speed up tooltip fading
+				var view = winUtils.getBox();
 				var width = view.w;
 				var height = view.h;
 				
 				if(width < 600){
 					//Make the larger tooltips smaller so they fit on the page and pass all tests
-					dijit.byId("test2").promptMessage="really really really really really really really really really really really really really really really really really really really really";
-					dijit.byId("test5").promptMessage="really really really really really really really really really really really really really really really really really really really really";
-					dijit.byId("test12").promptMessage="really really really really really really really really really really really really really really really really really really really really";
-					dijit.byId("test17").promptMessage="really really really really really really really really really really really really really really really really really really really really";
-					dijit.byId("test19").promptMessage="really really really really really really really really really really really really really really really really really really really really";
+					dom.byId("test2").setAttribute("promptMessage", "really really really really really really really really really really really really really really really really really really really really");
+					dom.byId("test5").setAttribute("promptMessage", "really really really really really really really really really really really really really really really really really really really really");
+					dom.byId("test12").setAttribute("promptMessage", "really really really really really really really really really really really really really really really really really really really really");
+					dom.byId("test17").setAttribute("promptMessage", "really really really really really really really really really really really really really really really really really really really really");
+					dom.byId("test19").setAttribute("promptMessage", "really really really really really really really really really really really really really really really really really really really really");
 				}else if(width > 1200){
 					//Make a shorter tooltip longer in order to span the whole width
-					dijit.byId("test1").promptMessage = "really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a";
-					dijit.byId("test4").promptMessage = "really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a";
-					dijit.byId("test10").promptMessage = "really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a";
-					dijit.byId("test20").promptMessage="really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a"
+					dom.byId("test1").setAttribute("promptMessage", "really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a");
+					dom.byId("test4").setAttribute("promptMessage", "really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a");
+					dom.byId("test10").setAttribute("promptMessage", "really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a");
+					dom.byId("test20").setAttribute("promptMessage", "really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a");
 				}
 				
 				if(height < 600){
@@ -59,52 +44,52 @@
 						if(i==7){
 							//skip
 						}else{
-							dijit.byId("test"+i+"_tall_skinny").promptMessage="<br><br><br><br>a";
+							dom.byId("test"+i+"_tall_skinny").setAttribute("promptMessage", "<br><br><br><br>a");
 						}
 					}
 				}
 				
-				dijit.byId("test1").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test1_tall_skinny").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test2").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test2_tall_skinny").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test3").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test3_tall_skinny").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test4").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test4_tall_skinny").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test5").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test5_tall_skinny").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test6").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test6_tall_skinny").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test7").set("style", "width:"+width*(1.1)+"px");
-				dijit.byId("test8").set("style", "width:"+width*(0.2)+"px");
-				dijit.byId("test8_tall_skinny").set("style", "width:"+width*(0.2)+"px");
-				dijit.byId("test9").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test9_tall_skinny").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test10").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test10_tall_skinny").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test11").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test11_tall_skinny").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test12").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test12_tall_skinny").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test13").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test13_tall_skinny").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test14").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test14_tall_skinny").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test15").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test15_tall_skinny").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test16").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test16_tall_skinny").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test17").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test17_tall_skinny").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test18").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test18_tall_skinny").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test19").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test19_tall_skinny").set("style", "width:"+width*(0.3)+"px");
-				dijit.byId("test20").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test20_tall_skinny").set("style", "width:"+width*(0.6)+"px");
-				dijit.byId("test21").set("style", "width:"+width*(0.9)+"px");
-				dijit.byId("test21_tall_skinny").set("style", "width:"+width*(0.9)+"px");
+				domStyle.set("test1", "width", width*(0.3)+"px");
+				domStyle.set("test1_tall_skinny", "width", width*(0.3)+"px");
+				domStyle.set("test2", "width", width*(0.6)+"px");
+				domStyle.set("test2_tall_skinny", "width", width*(0.6)+"px");
+				domStyle.set("test3", "width", width*(0.9)+"px");
+				domStyle.set("test3_tall_skinny", "width", width*(0.9)+"px");
+				domStyle.set("test4", "width", width*(0.3)+"px");
+				domStyle.set("test4_tall_skinny", "width", width*(0.3)+"px");
+				domStyle.set("test5", "width", width*(0.6)+"px");
+				domStyle.set("test5_tall_skinny", "width", width*(0.6)+"px");
+				domStyle.set("test6", "width", width*(0.9)+"px");
+				domStyle.set("test6_tall_skinny", "width", width*(0.9)+"px");
+				domStyle.set("test7", "width", width*(1.1)+"px");
+				domStyle.set("test8", "width", width*(0.2)+"px");
+				domStyle.set("test8_tall_skinny", "width", width*(0.2)+"px");
+				domStyle.set("test9", "width", width*(0.3)+"px");
+				domStyle.set("test9_tall_skinny", "width", width*(0.3)+"px");
+				domStyle.set("test10", "width", width*(0.6)+"px");
+				domStyle.set("test10_tall_skinny", "width", width*(0.6)+"px");
+				domStyle.set("test11", "width", width*(0.9)+"px");
+				domStyle.set("test11_tall_skinny", "width", width*(0.9)+"px");
+				domStyle.set("test12", "width", width*(0.3)+"px");
+				domStyle.set("test12_tall_skinny", "width", width*(0.3)+"px");
+				domStyle.set("test13", "width", width*(0.6)+"px");
+				domStyle.set("test13_tall_skinny", "width", width*(0.6)+"px");
+				domStyle.set("test14", "width", width*(0.9)+"px");
+				domStyle.set("test14_tall_skinny", "width", width*(0.9)+"px");
+				domStyle.set("test15", "width", width*(0.9)+"px");
+				domStyle.set("test15_tall_skinny", "width", width*(0.9)+"px");
+				domStyle.set("test16", "width", width*(0.3)+"px");
+				domStyle.set("test16_tall_skinny", "width", width*(0.3)+"px");
+				domStyle.set("test17", "width", width*(0.6)+"px");
+				domStyle.set("test17_tall_skinny", "width", width*(0.6)+"px");
+				domStyle.set("test18", "width", width*(0.9)+"px");
+				domStyle.set("test18_tall_skinny", "width", width*(0.9)+"px");
+				domStyle.set("test19", "width", width*(0.3)+"px");
+				domStyle.set("test19_tall_skinny", "width", width*(0.3)+"px");
+				domStyle.set("test20", "width", width*(0.6)+"px");
+				domStyle.set("test20_tall_skinny", "width", width*(0.6)+"px");
+				domStyle.set("test21", "width", width*(0.9)+"px");
+				domStyle.set("test21_tall_skinny", "width", width*(0.9)+"px");
 			});
 
 			//Verify the following is true:
@@ -115,8 +100,8 @@
 			function testRightOrLeft(textbox, verifyFullWidthIsUtilized){
 				verifyTooltipArrowPosition(textbox);
 
-				var textboxPos = dojo.position(textbox.domNode);
-				var tooltipContainerPos = dojo.position(dojo.query(".dijitTooltip")[0]);
+				var textboxPos = domGeom.position(textbox);
+				var tooltipContainerPos = domGeom.position(query(".dijitTooltip")[0]);
 				
 				var xDiff = textboxPos.x - tooltipContainerPos.x - tooltipContainerPos.w;
 				var toTheLeft = xDiff >= -0.5 && xDiff < 2;
@@ -126,13 +111,13 @@
 
 				doh.t(toTheLeft || toTheRight, "The tooltip was not to the left or right");
 
-				var tooltip = dijit.Tooltip._masterTT.containerNode;
-				var tooltipPos = dojo.position(tooltip);
+				var tooltip = Tooltip._masterTT.containerNode;
+				var tooltipPos = domGeom.position(tooltip);
 
-				var view = dojo.window.getBox();
-				var isIE6 = dojo.isIE < 7;
+				var view = winUtils.getBox();
+				var isIE6 = has("ie") < 7;
 				//verify the entire width is utilized.  Small tooltips will not utilize the entire width.
-				if(verifyFullWidthIsUtilized && !isIE6 && !dojo.isOpera){
+				if(verifyFullWidthIsUtilized && !isIE6 && !has("opera")){
 					if(toTheLeft){
 						doh.t(tooltipContainerPos.w + 3/*space in between arrow and textbox*/ >= textboxPos.x, "The entire width was not utilized to the left");					
 					}else{
@@ -143,7 +128,7 @@
 				//If we cannot view the entire tooltip, verify they side with the most space was choosen and the entire height was utilized.
 				var canViewEntireTooltip = (tooltipContainerPos.x + tooltipContainerPos.w <= view.w+1) && 
 										   (tooltipPos.y + tooltipPos.h <= view.h+1);			
-				if(!canViewEntireTooltip && !isIE6 && !dojo.isOpera){
+				if(!canViewEntireTooltip && !isIE6 && !has("opera")){
 					if(toTheLeft){
 						//verify there is more space on the left than the right
 						doh.t(textboxPos.x >= (view.w - textboxPos.x - textboxPos.w), "There is not more space on the left than the right");
@@ -156,8 +141,8 @@
 			}
 			
 			function toTheLeftOrRight(textbox){
-				var textboxPos = dojo.position(textbox.domNode);
-				var tooltipContainerPos = dojo.position(dojo.query(".dijitTooltip")[0]);
+				var textboxPos = domGeom.position(textbox);
+				var tooltipContainerPos = domGeom.position(query(".dijitTooltip")[0]);
 				
 				var xDiff = textboxPos.x - tooltipContainerPos.x - tooltipContainerPos.w;
 				var toTheLeft = xDiff >= -1 && xDiff < 2;
@@ -170,8 +155,8 @@
 			
 			//Verify the tooltip arrow is next to the textbox
 			function verifyTooltipArrowPosition(textbox){
-				var textboxPos = dojo.position(textbox.domNode);
-				var tooltipConnectorPos = dojo.position(dojo.query(".dijitTooltipConnector")[0]);
+				var textboxPos = domGeom.position(textbox);
+				var tooltipConnectorPos = domGeom.position(query(".dijitTooltipConnector")[0]);
 				
 				var middleOfTextbox = textboxPos.y + (textboxPos.h / 2);
 				var middleOfTooltipConnector = tooltipConnectorPos.y + (tooltipConnectorPos.h /2);
@@ -181,26 +166,19 @@
 				doh.t(yAxisValid, "Y axis is invalid. yDiff was: "+yDiff);
 			}
 			
-			//Verify the following is true:
-			//	1. The tooltip arrow is next to the textbox
-			//	2. The text fits inside the tooltip
+			// Test for when the tooltip has large words or nowrap so that it can't be displayed properly,
+			// given the space available.   Verify the following is true:
+			//	   1. The tooltip arrow is next to the textbox
+			// Note that tooltip text may be cut off if there wasn't enough room to display the tooltip
+			// to the left/right of the anchor node
 			function testNoWrapOrLargeWords(textbox){
 				verifyTooltipArrowPosition(textbox);
-				
-				//Verify the text fits inside the tooltip
-				var tooltipContainer = dojo.query(".dijitTooltipContainer")[0];
-				tooltipContainer.style.overflow = "auto";
-				var scrollWidth = tooltipContainer.scrollWidth;
-				tooltipContainer.style.overflow = "visible"; //change it back
-				
-				var tooltipWidth = dojo.position(tooltipContainer).w;
-				doh.t(tooltipWidth >= scrollWidth);
 			}
 		
 			function testAboveBelow(textbox, verifyConnectorPosition){
-				var textboxPos = dojo.position(textbox.domNode);
-				var tooltipConnectorPos = dojo.position(dojo.query(".dijitTooltipConnector")[0]);
-				var tooltipContainerPos = dojo.position(dojo.query(".dijitTooltip")[0]);
+				var textboxPos = domGeom.position(textbox);
+				var tooltipConnectorPos = domGeom.position(query(".dijitTooltipConnector")[0]);
+				var tooltipContainerPos = domGeom.position(query(".dijitTooltip")[0]);
 
 				if(verifyConnectorPosition){
 					var xAxisValid = textboxPos.x <= tooltipConnectorPos.x && tooltipConnectorPos.x <= (textboxPos.x + textboxPos.w);
@@ -213,331 +191,143 @@
 	
 				yDiff = tooltipContainerPos.y - textboxPos.y - textboxPos.h;
 				var below = yDiff >= -0.5 && yDiff < 1;
-			
-				doh.t(above || below);
-			}
-
-			var widget, handler;
-
-			// init tests for each group
-			var tooltip_left_right_tall_skinny = [{
-				name: "test1_tall_skinny",
-				timeout: 4000,
-				runTest: function(){
-					var d = new doh.Deferred();
-					widget = dijit.byId("test1_tall_skinny");
-
-					dojo.byId("aboveBelowButton").focus();
-					widget.set('value', null);
-
-					handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-						testRightOrLeft(widget, false);
-					}));
-					dijit.byId("test7").focusNode.focus(); //hack for IE6.  test1 is not getting focus in IE6 if we don't focus something else first
-					widget.focusNode.focus();
-				
-					return d;
-				},
-				tearDown: function(){
-					dojo.disconnect(handler);
-				}
-			}];
-			var tooltip_left_right = [{
-				name: "test1",
-				timeout: 4000,
-				runTest: function(){
-					var d = new doh.Deferred();
-					widget = dijit.byId("test1");
-
-					dojo.byId("aboveBelowButton").focus();
-					widget.set('value', null);
-
-					handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-						testRightOrLeft(widget, true);
-					}));
-					dijit.byId("test7").focusNode.focus(); //hack for IE6.  test1 is not getting focus in IE6 if we don't focus something else first
-					widget.focusNode.focus();
-				
-					return d;
-				},
-				tearDown: function(){
-					dojo.disconnect(handler);
-				}
-			}];
-			var tooltip_left_right_small = [{
-				name: "test1_lrs",
-				timeout: 6000,
-				runTest: function(){
-					var d = new doh.Deferred();
-				
-					var widget = dijit.byId("test1");
-					widget.set('value', null);
-				
-					dijit.byId("test7").focusNode.focus();
-				
-					setTimeout(function(){ widget.focusNode.focus();}, 500);
-
-					setTimeout(d.getTestCallback(function(){
-						testRightOrLeft(widget, false);
-					}), 1000);
-					return d;
-				}
-			}];
-			var tooltip_above_below_small = [{
-				name: "test1_abs",
-				timeout: 3000,
-				runTest: function(){
-					var d = new doh.Deferred();
-		
-					var widget = dijit.byId("test1");
-					dojo.byId("aboveBelowButton").focus();
-					dojo.byId("aboveBelowButton").click();
-					widget.focusNode.focus();
-
-					setTimeout(d.getTestCallback(function(){
-						testAboveBelow(widget, true);
-					}), 1000);
-					return d;
-				}
-			}];
-			var tooltip_above_below = [{
-				name: "test1_ab",
-				timeout: 5000,
-				runTest: function(){
-					var d = new doh.Deferred();
-					widget = dijit.byId("test1");
-
-					widget.set('value', "a");
-
-					handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-						testAboveBelow(widget, true);
-					}));
-
-					widget.focusNode.focus();
-
-					return d;
-				},
-				tearDown: function(){
-					dojo.disconnect(handler);
-				}
-			}];
-			var tooltip_above_below_tall_skinny = [{
-				name: "test1_ab_tall_skinny",
-				timeout: 5000,
-				runTest: function(){
-					var d = new doh.Deferred();
-					widget = dijit.byId("test1_tall_skinny");
-
-					widget.set('value', "a");
-
-					handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-						testAboveBelow(widget, true);
-					}));
-
-					widget.focusNode.focus();
-
-					return d;
-				},
-				tearDown: function(){
-					dojo.disconnect(handler);
-				}
-			}];
-			var tooltip_left_right_overflow = [{
-				name: "test22",
-				timeout: 4000,
-				runTest: function(){
-					var d = new doh.Deferred();
-					widget = dijit.byId("test22");
-					var cp = dijit.byId("test22_cp");
-
-					dojo.byId("afterBeforeButton").focus();
-					dojo.byId("afterBeforeButton").click();
-					widget.set('value', null);
-
-					handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-						toTheLeftOrRight(cp, true);
-					}));
-					widget.focusNode.focus();
-				
-					return d;
-				},
-				tearDown: function(){
-					dojo.disconnect(handler);
-				}
-			}];
-			var tooltip_left_right_overflow_rtl = [{
-				name: "test23",
-				timeout: 4000,
-				runTest: function(){
-					var d = new doh.Deferred();
-					widget = dijit.byId("test23");
-					var cp = dijit.byId("test23_cp");
-
-					widget.set('value', null);
 
-					handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-						toTheLeftOrRight(cp, true);
-					}));
-					widget.focusNode.focus();
-				
-					return d;
-				},
-				tearDown: function(){
-					dojo.disconnect(handler);
-				}
-			}];
+				doh.t(above || below, "above || below, yDiff == " + yDiff);
+			}
 
-			// rest of tests
-			for(var i=2; i<=21; i++){
+			for(var i=1; i<=21; i++){
 				if(i==7){ continue; }
-				tooltip_left_right_tall_skinny.push({
-					name: "test"+i+"_tall_skinny",
-					widget: "test"+i+"_tall_skinny",
-					timeout: 3000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						widget = dijit.byId(this.widget);
-
-						widget.set('value', null);
-
-						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-							testRightOrLeft(widget, false);
-						}));
-						dojo.window.scrollIntoView(widget.focusNode);
-						widget.focusNode.focus();
-					
-						return d;
-					},
-					tearDown: function(){
-						dojo.disconnect(handler);
-					}
-				});
-				tooltip_left_right.push({
-					name: "test"+i,
-					widget: "test"+i,
-					timeout: 3000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						widget = dijit.byId(this.widget);
-
-						widget.set('value', null);
-
-						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-							var id = widget.id;
-							if(id=="test3" || id=="test6" || id=="test8" || id=="test9" || id=="test13" || id=="test16" || id=="test21"){
-								//These are the nowrap tests and therefore we should only verify the arrow is pointing to the textbox
-								testNoWrapOrLargeWords(widget);
-							}else{
-								testRightOrLeft(widget, true);
+				(function(i){
+					// Need the closure to run tests on each node, rather than repeating on "test21" node
+					var node = dom.byId("test"+i),
+						skinnyNode = dom.byId("test"+i+"_tall_skinny"),
+						nowrapTest = (i==3 || i==6 || i==8 || i==9 || i==13 || i==16 || i==21);
+					doh.register("test" + i, [
+						{
+							name: "test"+i+"_tall_skinny",
+							runTest: function(){
+								var d = new doh.Deferred();
+								winUtils.scrollIntoView(skinnyNode);
+								Tooltip.show(skinnyNode.getAttribute("promptMessage"), skinnyNode);
+								setTimeout(d.getTestCallback(function(){
+									// use timeout to wait for fade out of tooltip from old position, and fade in to new position
+									testRightOrLeft(skinnyNode, false);
+								}), 100);
+								return d;
 							}
-						}));
-						dojo.window.scrollIntoView(widget.focusNode);
-						widget.focusNode.focus();
-					
-						return d;
-					},
-					tearDown: function(){
-						dojo.disconnect(handler);
-					}
-				});
-				tooltip_left_right_small.push({
-					name: "test"+i+"_lrs",
-					widget: "test"+i,
-					timeout: 3000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						widget = dijit.byId(this.widget);
-
-						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-							testRightOrLeft(widget, false);
-						}));
-						widget.focusNode.focus();
-
-						return d;
-					},
-					tearDown: function(){
-						dojo.disconnect(handler);
-					}
-				});
-				tooltip_above_below_small.push({
-					name: "test"+i+"_abs",
-					widget: "test"+i,
-					timeout: 3000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						widget = dijit.byId(this.widget);
-
-						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-							testAboveBelow(widget, true);
-						}));
-						widget.focusNode.focus();
+						},
+						{
+							name: "test"+i,
+							runTest: function(){
+								var d = new doh.Deferred();
+								winUtils.scrollIntoView(node);
+								Tooltip.show(node.getAttribute("promptMessage"), node);
+								setTimeout(d.getTestCallback(function(){
+									// use timeout to wait for fade out of tooltip from old position, and fade in to new position
+									if(nowrapTest){
+										// For nowrap tests  we should only verify the arrow is pointing to the textbox
+										testNoWrapOrLargeWords(node);
+									}else{
+										testRightOrLeft(node, true);
+									}
+								}), 100);
+								return d;
+							}
+						},
+						{
+							name: "test"+i+"_lrs",
+							runTest: function(){
+								var d = new doh.Deferred();
+								Tooltip.show("!", node);
+								setTimeout(d.getTestCallback(function(){
+									// use timeout to wait for fade out of tooltip from old position, and fade in to new position
+									testRightOrLeft(node, false);
+								}), 100);
+								return d;
+							}
+						},
+						{
+							name: "test"+i+"_abs",
+							runTest: function(){
+								var d = new doh.Deferred();
+								winUtils.scrollIntoView(node);
+								Tooltip.hide(node);	// needed since show() below matches node & content of show() above
+								Tooltip.show("!", node, ["below", "above"]);
+								setTimeout(d.getTestCallback(function(){
+									// use timeout to wait for fade out of tooltip from old position, and fade in to new position
+									testAboveBelow(node, true);
+								}), 100);
+								return d;
+							}
+						},
+						{
+							name: "test"+i+"_ab",
+							runTest: function(){
+								var d = new doh.Deferred();
+								Tooltip.show(node.getAttribute("promptMessage"), node, ["below", "above"]);
+								setTimeout(d.getTestCallback(function(){
+									// use timeout to wait for fade out of tooltip from old position, and fade in to new position
+									if(nowrapTest){
+										// For nowrap tests we should only verify the arrow is pointing to the textbox
+										// (in most cases it's off the screen)
+										testAboveBelow(node, false);
+									}else{
+										testAboveBelow(node, true);
+									}
+								}), 100);
+								return d;
+							}
+						},
+						{
+							name: "test"+i+"_ab_tall_skinny",
+							runTest: function(){
+								var d = new doh.Deferred();
+								winUtils.scrollIntoView(skinnyNode);
+								Tooltip.show(skinnyNode.getAttribute("promptMessage"), skinnyNode, ["below", "above"]);
+								setTimeout(d.getTestCallback(function(){
+									// use timeout to wait for fade out of tooltip from old position, and fade in to new position
+									testAboveBelow(skinnyNode, true);
+								}), 100);
+								return d;
+							}
+						}
+					]);
+				})(i);	// end closure
+			}
 
-						return d;
-					},
-					tearDown: function(){
-						dojo.disconnect(handler);
-					}
-				});
-				tooltip_above_below.push({
-					name: "test"+i+"_ab",
-					widget: "test"+i,
-					timeout: 5000,
+			doh.register("anchor inside overflowed div", [
+				{
+					name: "test22",
 					runTest: function(){
 						var d = new doh.Deferred();
-						widget = dijit.byId(this.widget);
-
-						widget.set('value', "a");
-
-						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-							var id = widget.id;
-							if(id=="test3" || id=="test6" || id=="test8" || id=="test9" || id=="test13" || id=="test16" || id=="test21"){
-								//These are the nowrap tests and therefore we should only verify the arrow is pointing to the textbox (in most cases it's off the screen)
-								testAboveBelow(widget, false);
-							}else{
-								testAboveBelow(widget, true);
-							}
-						}));
-
-						widget.focusNode.focus();
-
+						var node = dom.byId("test22");
+						var cp = dom.byId("test22_cp");
+						winUtils.scrollIntoView(cp);
+						Tooltip.hide(node);	// needed since show() below matches node & content of show() above
+						Tooltip.show(node.getAttribute("promptMessage"), node);
+						setTimeout(d.getTestCallback(function(){
+							// use timeout to wait for fade out of tooltip from old position, and fade in to new position
+							toTheLeftOrRight(cp, true);
+						}), 100);
 						return d;
-					},
-					tearDown: function(){
-						dojo.disconnect(handler);
 					}
-				});
-				tooltip_above_below_tall_skinny.push({
-					name: "test"+i+"_ab_tall_skinny",
-					widget: "test"+i+"_tall_skinny",
-					timeout: 5000,
+				},
+				{
+					name: "test23",
 					runTest: function(){
 						var d = new doh.Deferred();
-						widget = dijit.byId(this.widget);
-
-						widget.set('value', "a");
-
-						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
-							testAboveBelow(widget, true);
-						}));
-
-						widget.focusNode.focus();
-
+						var node = dom.byId("test23");
+						var cp = dom.byId("test23_cp");
+						Tooltip.show(node.getAttribute("promptMessage"), node, null, true);
+						setTimeout(d.getTestCallback(function(){
+							// use timeout to wait for fade out of tooltip from old position, and fade in to new position
+							toTheLeftOrRight(cp, true);
+						}), 100);
 						return d;
-					},
-					tearDown: function(){
-						dojo.disconnect(handler);
 					}
-				});
-			}
+				}
+			]);
 
-			doh.register("tooltip_left_right_tall_skinny", tooltip_left_right_tall_skinny);
-			doh.register("tooltip_left_right", tooltip_left_right);
-			doh.register("tooltip_left_right_small", tooltip_left_right_small);
-			doh.register("tooltip_above_below_small", tooltip_above_below_small);
-			doh.register("tooltip_above_below", tooltip_above_below);
-			doh.register("tooltip_above_below_tall_skinny", tooltip_above_below_tall_skinny);
-			doh.register("tooltip_left_right_overflow", tooltip_left_right_overflow);
-			doh.register("tooltip_left_right_overflow_rtl", tooltip_left_right_overflow_rtl);
 			doh.run();
 		});
 	</script>
@@ -547,86 +337,77 @@
 
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test1" name="test1" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test1" promptMessage='really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>	
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test1_tall_skinny" name="test1_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test1_tall_skinny" name="test1_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test2" name="test2" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really reallyreally really really really really really r [...]
+		<input type="text" id="test2" promptMessage='really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really reallyreally really really really really really really really really really really really really reallyreally really really really really  [...]
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test2_tall_skinny" name="test2_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test2_tall_skinny" name="test2_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test3" name="test3" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'reallyreallylonggermanwordreallyreallyreallyreallyreallyreallyreallylongword big', required:true, missingMessage:'!'"/>
+		<input type="text" id="test3" promptMessage='reallyreallylonggermanwordreallyreallyreallyreallyreallyreallyreallylongword big'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test3_tall_skinny" name="test3_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test3_tall_skinny" name="test3_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test4" name="test4" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test4" promptMessage='really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test4_tall_skinny" name="test4_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test4_tall_skinny" name="test4_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test5" name="test5" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really really really really really  [...]
+		<input type="text" id="test5" promptMessage='really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really really really really really really really really really really really really really really really really really reall [...]
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test5_tall_skinny" name="test5_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test5_tall_skinny" name="test5_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test6" name="test6" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<div style=\'white-space: nowrap\'>really really really really big</div>', required:true, missingMessage:'!'"/>
+		<input type="text" id="test6" promptMessage="<div style='white-space: nowrap'>really really really really big</div>"/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test6_tall_skinny" name="test6_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test6_tall_skinny" name="test6_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test7" name="test7" data-dojo-type="dijit.form.ValidationTextBox"/>
+		<input type="text" id="test7" name="test7"/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test8" name="test8" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<div style=\'white-space: nowrap\'>really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a</div> [...]
+		<input type="text" id="test8" promptMessage="<div style='white-space: nowrap'>really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a</div>"/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test8_tall_skinny" name="test8_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
-	</td>
-	</tr>
-	<tr>
-	<td>
-		<button id="aboveBelowButton" onclick="dijit.Tooltip.defaultPosition=['above', 'below']; dojo.byId('current').innerHTML='Current: ' + dijit.Tooltip.defaultPosition;">above, below</button>
-		<button id="afterBeforeButton" onclick="dijit.Tooltip.defaultPosition=['after', 'before']; dojo.byId('current').innerHTML='Current: ' + dijit.Tooltip.defaultPosition;">after, before (default)</button>
-		<div id=current>
-			Current: default (unchanged)
-		</div>
+		<input type="text" id="test8_tall_skinny" name="test8_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
@@ -636,72 +417,72 @@
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test9" name="test9" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongword', required:true, missingMessage:'!'"/>
+		<input type="text" id="test9" promptMessage='reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongword'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test9_tall_skinny" name="test9_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test9_tall_skinny" name="test9_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test10" name="test10" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test10" promptMessage='really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test10_tall_skinny" name="test10_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test10_tall_skinny" name="test10_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test11" name="test11" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'a a a a a a a a a a a a a a a a a a a a a a a a a a a a<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test11" promptMessage='a a a a a a a a a a a a a a a a a a a a a a a a a a a a<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test11_tall_skinny" name="test11_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test11_tall_skinny" name="test11_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test12" name="test12" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really real [...]
+		<input type="text" id="test12" promptMessage='really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really real [...]
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test12_tall_skinny" name="test12_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test12_tall_skinny" name="test12_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test13" name="test13" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<div style=\'white-space: nowrap\'>really really really really really really really really really really really really really really really really really big</div>', required:true, missingMessage:'!'"/>
+		<input type="text" id="test13" promptMessage="<div style='white-space: nowrap'>really really really really really really really really really really really really really really really really really big</div>"/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test13_tall_skinny" name="test13_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test13_tall_skinny" name="test13_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test14" name="test14" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really really really really reallyreally really really really really really really really really really [...]
+		<input type="text" id="test14" promptMessage='really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really really really really reallyreally really really really really really [...]
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test14_tall_skinny" name="test14_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test14_tall_skinny" name="test14_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test15" name="test15" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'a a a a a a a a a a a a a a a a a a<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test15" promptMessage='a a a a a a a a a a a a a a a a a a<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test15_tall_skinny" name="test15_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test15_tall_skinny" name="test15_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
@@ -711,74 +492,74 @@
 	</tr>	
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test16" name="test16" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongword big word really big word', required:true, missingMessage:'!'"/>
+		<input type="text" id="test16" promptMessage='reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongword big word really big word'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test16_tall_skinny" name="test16_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test16_tall_skinny" name="test16_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test17" name="test17" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really really really really reall [...]
+		<input type="text" id="test17" promptMessage='really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really reall [...]
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test17_tall_skinny" name="test17_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test17_tall_skinny" name="test17_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test18" name="test18" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'a a a a a a a a a a a a a a a a a a a a a a<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test18" promptMessage='a a a a a a a a a a a a a a a a a a a a a a<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:right;">
-		<input type="text" id="test18_tall_skinny" name="test18_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test18_tall_skinny" name="test18_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test19" name="test19" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really real [...]
+		<input type="text" id="test19" promptMessage='really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really real [...]
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test19_tall_skinny" name="test19_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test19_tall_skinny" name="test19_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test20" name="test20" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test20" promptMessage='really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test20_tall_skinny" name="test20_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test20_tall_skinny" name="test20_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test21" name="test21" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'reallyreallyreallyreallyreallyreallylongword<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test21" promptMessage='reallyreallyreallyreallyreallyreallylongword<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 	<tr>
 	<td style="text-align:left;">
-		<input type="text" id="test21_tall_skinny" name="test21_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+		<input type="text" id="test21_tall_skinny" name="test21_tall_skinny" promptMessage='<br><br><br><br><br><br><br><br><br><br><br>a'/>
 	</td>
 	</tr>
 </table>
 
-<div id="test22_cp" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="style:{height:'90px', width:'100px', padding:'0px'}">
-   <input type="text" id="test22" name="test22" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="style:{fontSize:'100pt'}, promptMessage:'test overflow', required:true"/>
+<div id="test22_cp" style="height:90px; width:100px; padding:0px; overflow: auto;">
+   <input type="text" id="test22" style="fontSize:100pt" promptMessage='test overflow'/>
 <br><br><br><br><br>
 </div>
 
-<table width='100%' align='left'><tr><td width='95%'></td><td style="width:'5%'">
-<div id="test23_cp" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="dir:'rtl', style:{height:'100px', width:'100px', border:'1px', overflow:'scroll'}">
-   <input type="text" id="test23" name="test23" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="dir:'rtl', style:{fontSize:'20pt'}, promptMessage:'test overflow', required:true"/>
+<table width='100%' align='left'><tr><td width='95%'></td><td style="width:5%">
+<div id="test23_cp" dir='rtl' style="height:100px; width:100px; border:1px; overflow:scroll">
+   <input type="text" id="test23" dir='rtl' style="fontSize:20pt" promptMessage='test overflow'/>
 </div>
 </td></tr></table>
 
diff --git a/dijit/tests/TooltipDialog.html b/dijit/tests/TooltipDialog.html
new file mode 100644
index 0000000..d5ff3a5
--- /dev/null
+++ b/dijit/tests/TooltipDialog.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>TooltipDialog non-robot Automated Test</title>
+
+	<script src="boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner", "dojo/dom-class", "dojo/dom-geometry", "dojo/_base/window",
+			"dijit/popup", "dijit/form/DropDownButton", "dijit/TooltipDialog",
+			"dojo/domReady!"
+		], function(doh, domClass, domGeometry, win, popup, DropDownButton, TooltipDialog){
+			doh.register("TooltipDialog", [
+				function create(){
+					td = new TooltipDialog({
+						id:"mytooltip",
+						content: "hello world"
+					});
+					button = new DropDownButton({
+						id: "tooltipDropDownButton",
+						label: "show tooltip",
+						dropDown: td
+					});
+					button.placeAt(win.body());
+				},
+				function openAround(){
+					button.openDropDown();
+					doh.t(domClass.contains(td.domNode, "dijitTooltipBelow"), "dijitTooltipBelow");
+					button.closeDropDown();
+				},
+				function openAt(){
+					popup.open({
+						popup: td,
+						x: 10,
+						y: 15
+					});
+
+					var popupCoords = domGeometry.position(td.domNode);
+					doh.is(10, popupCoords.x, "popup x coord");
+					doh.is(15, popupCoords.y, "popup y coord");
+					doh.t(domClass.contains(td.domNode, "dijitTooltipBelow"), "dijitTooltipBelow");
+					doh.t(domClass.contains(td.domNode, "dijitTooltipABLeft"), "dijitTooltipABLeft");
+
+					popup.close(td);
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro" role="main">
+</body>
+</html>
diff --git a/dijit/tests/_AttachMixin.html b/dijit/tests/_AttachMixin.html
new file mode 100644
index 0000000..dc59ce0
--- /dev/null
+++ b/dijit/tests/_AttachMixin.html
@@ -0,0 +1,165 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>_AttachMixin Test</title>
+
+		<script src="boilerplate.js"></script>
+
+		<style type="text/css">
+			/* Make our tests stand out as easily identifiable content */
+			.testcontainer {
+				border: 10px yellow;
+				border-style: dashed;
+				padding: 1em;
+				margin: 1em;
+			}
+			.testcontainer > p {
+				padding: 0 1em;
+				font-weight: bold;
+			}
+		</style>
+
+		<script type="text/javascript">
+			require([
+				"doh/runner", "dojo/_base/declare", "dojo/dom", "dojo/html", "dojo/on", "dojo/parser",
+				"dijit/registry", "dijit/_WidgetBase", "dijit/_AttachMixin", "dijit/_TemplatedMixin",
+				"dijit/form/Button", "dijit/Editor", "dojo/domReady!"
+			], function(doh, declare, dom, html, on, parser,
+				registry, _WidgetBase, _AttachMixin, _TemplatedMixin, Button, Editor) {
+
+				doh.register("_AttachMixin", [
+					function basic() {
+						
+						/*** TEST _AttachMixin on a simple _WidgetBase ***/
+						var WidgetWithAttachMagic = declare([ _WidgetBase, _AttachMixin ], {
+							postCreate: function() {
+								html.set(this.heading, "I am an attach point, hear me raar!");
+								this.field.value = "Value is objective.";
+							},
+							_fieldChanged: function(e) {
+								html.set(this.heading, "Oooh! Saucy! Now I am '" + e.target.value + "'");
+							}
+						});
+
+						var mydijit = new WidgetWithAttachMagic({}, dom.byId("attachMe"));
+						mydijit.startup();
+						
+						doh.t(mydijit.heading, "heading");
+						doh.t(mydijit.field, "field");
+						doh.is("I am an attach point, hear me raar!", mydijit.heading.innerHTML, "Initial value");
+						
+						// Simulate a change
+						mydijit.field.value = 'something new';
+						on.emit(mydijit.field, "keyup", {bubbles: true});
+						
+						doh.is("Oooh! Saucy! Now I am 'something new'", mydijit.heading.innerHTML, "Post-op value");
+					},
+
+					function attachScope() {
+						/*** Test an inner dijit's attach-point and attach-event behaviour being attached to a
+						 * different widget instance, in this case the outer one.
+						 */
+						var InnerDijit = declare([ _WidgetBase, _TemplatedMixin ], {
+							declaredClass: "InnerDijit",	// for debugging
+							templateString: "<div><input data-dojo-attach-point='field' data-dojo-attach-event='onkeyup: inputKeyUp'></div>"
+						});
+						
+						var OuterDijit = declare([ _WidgetBase, _TemplatedMixin ], {
+							declaredClass: "OuterDijit",	// for debugging
+							templateString:
+									"<div>" +
+										"<h2 data-dojo-attach-point='heading'>Initial value</h2>" +
+										"<div data-dojo-attach-point='content'></div>" +
+									"</div>",
+							buildRendering: function() {
+								this.inherited(arguments);
+								this.iw = new InnerDijit({
+									attachScope: this // Cause attach points in inner dijit to attach to us
+								});
+								// NB don't own as we will do a destroy test later this.own(id);
+								this.iw.placeAt(this.content, 'last');
+							},
+							// This handler is attached to the field in our inner dijit
+							inputKeyUp: function(e) {
+								var target = e.target;
+								html.set(this.heading, "Event: " + e.type + " value: " + target.value);
+							}
+						});
+						
+						var od = new OuterDijit({}, dom.byId('destthree'));
+						od.startup();
+
+						// Confirm that the outer dijit has attached points both
+						//  from its own template, and the inner dijit.
+						doh.t(od.heading, "heading");
+						doh.t(od.field, "field");
+						doh.is("Initial value", od.heading.innerHTML, "Initial value");
+						
+						// Simulate a change on the field in the inner dijit
+						od.field.value = 'something new';
+						on.emit(od.field, "keyup", {bubbles: true});
+						
+						// Confirm the change ran the event handler in the outer dijit
+						doh.is("Event: keyup value: something new", od.heading.innerHTML, "Post-op value");
+						
+						// Now destroy the inner dijit and ensure its attach points on the parent
+						//  were removed.
+						od.iw.destroy();
+						delete od.iw;
+						doh.t(od.heading, "heading remains"); // heading remains
+						doh.f(od.field, "inner content was detached");  // inner content was detached
+					},
+
+					function containerNode(){
+						// Test that code inside of containerNode isn't scanned
+						var WidgetWithAttachMagic = declare([ _WidgetBase, _AttachMixin ]);
+						var cd = new WidgetWithAttachMagic({}, dom.byId("attachMeFive"));
+						doh.t(cd.heading, "heading attach point set up");
+						doh.f("mybutton" in cd, "attach point inside containerNode ignored");
+					}
+				]);
+				
+				doh.run();
+			});
+		</script>
+	</head>
+	<body class="claro">
+
+		<h1 class="testTitle">Dijit _AttachMixin Test</h1>
+
+		<div class="testcontainer">
+			<p>This markup may have come from a server side templating engine like Catalyst. 
+			The aim is to allow us to use data-dojo-attach-* magic on the content.<br>
+			Change the input value to see attach event and attach point at work.</p>
+			<div id="attachMe">
+				<h2 data-dojo-attach-point="heading"></h2>
+				<label for="${id}_field">You say "Hello":</label>
+				<input id="${id}_field" placeHolder="I say 'Goodbye'"
+					   data-dojo-attach-point="field"
+					   data-dojo-attach-event="onkeyup: _fieldChanged">
+			</div>
+		</div>
+		
+		<div class="testcontainer">
+			<p>This test shows an inner dijit being created with attachScope referencing its enclosing dijit.</p>
+			<div id="destthree"></div>
+		</div>
+
+		<!-- Test that data-dojo-attach-point etc. inside containerNode are ignored -->
+		<div class="testcontainer">
+			<p>This tests that nodes inside of data-dojo-attach-point="containerNode" are ignored<br>
+			<div id="attachMeFive">
+				<h2 data-dojo-attach-point='heading'></h2>
+				<div data-dojo-attach-point='containerNode'>
+					<span data-dojo-type='AnotherAttachPointWidget'>
+						<button data-dojo-attach-point='mybutton'
+							data-dojo-attach-event='onClick: _buttonClicked'>A button
+						</button>
+					</span>
+				</div>
+			</div>
+		</div>
+
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/BidiSupportModule/BidiSupportTest.js b/dijit/tests/_BidiSupport/BidiSupportModule/BidiSupportTest.js
index 28f164d..7806bee 100644
--- a/dijit/tests/_BidiSupport/BidiSupportModule/BidiSupportTest.js
+++ b/dijit/tests/_BidiSupport/BidiSupportModule/BidiSupportTest.js
@@ -1,181 +1,178 @@
-dojo.provide("dijit.tests._BidiSupport.BidiSupportModule.BidiSupportTest");
-
-//Import in the code being tested.
-dojo.require("dijit._BidiSupport");
-dojo.require("dijit._Widget");
-
-dojo.ready(function(){
-
-	doh.register("dijit.tests._BidiSupport.BidiSupportModule.BidiSupportTest", [
-		{
-			name:"1. checkContextual(), dir = LTR",
-
-			runTest:function(){
-				var bidi = new dijit._Widget({textDir:"ltr", dir:"ltr"});
-				
-				doh.is("ltr", bidi._checkContextual("Hello"),"Hello");
-				doh.is("rtl", bidi._checkContextual("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi._checkContextual("123 Hello"),"123 Hello");
-				doh.is("rtl", bidi._checkContextual("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi._checkContextual("_Hello"),"_Hello");
-				doh.is("rtl", bidi._checkContextual("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi._checkContextual("!!$%@ Hello"), "!!$%@ Hello");
-				doh.is("rtl", bidi._checkContextual("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi._checkContextual("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi._checkContextual("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
-				doh.is("ltr", bidi._checkContextual(""),"");
-				doh.is("ltr", bidi._checkContextual("123 > 456"),"123 > 456");
-				doh.is("ltr", bidi._checkContextual("%^$^&)( )_($!"),"%^$^&)( )_($!");	
-			}
-		},
-		{
-			name:"2. checkContextual(), dir = RTL",
-
-			runTest:function(){
-				var bidi = new dijit._Widget({textDir:"ltr",dir:"rtl"});
-
-				doh.is("ltr", bidi._checkContextual("Hello"),"Hello");
-				doh.is("rtl", bidi._checkContextual("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi._checkContextual("123 Hello"),"123 Hello");
-				doh.is("rtl", bidi._checkContextual("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi._checkContextual("_Hello"),"_Hello");
-				doh.is("rtl", bidi._checkContextual("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi._checkContextual("!!$%@ Hello"), "!!$%@ Hello");
-				doh.is("rtl", bidi._checkContextual("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi._checkContextual("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi._checkContextual("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
-				doh.is("rtl", bidi._checkContextual(""),"");
-				doh.is("rtl", bidi._checkContextual("123 > 456"),"123 > 456");			
-				doh.is("rtl", bidi._checkContextual("%^$^&)( )_($!"),"%^$^&)( )_($!");
-			}
-		},
-		{
-			name:"3. getTextDir(), textDir = LTR, dir = LTR",
-
-			runTest:function(){
-				var bidi = new dijit._Widget({textDir:"ltr",dir:"ltr"});
-
-				doh.is("ltr", bidi.getTextDir("Hello"),"Hello");
-				doh.is("ltr", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("123 Hello"),"123 Hello");
-				doh.is("ltr", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("_Hello"),"_Hello");
-				doh.is("ltr", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
-				doh.is("ltr", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
-				doh.is("ltr", bidi.getTextDir(""),"");
-				doh.is("ltr", bidi.getTextDir("123 > 456"),"123 > 456");
-				doh.is("ltr", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");
-			}
-		},
-		{
-			name:"4. getTextDir(), textDir = LTR, dir = RTL",
-
-			runTest:function(){
-				var bidi = new dijit._Widget({textDir:"ltr",dir:"rtl"}); 
-			
-				doh.is("ltr", bidi.getTextDir("Hello"),"Hello");
-				doh.is("ltr", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("123 Hello"),"123 Hello");
-				doh.is("ltr", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("_Hello"),"_Hello");
-				doh.is("ltr", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
-				doh.is("ltr", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
-				doh.is("ltr", bidi.getTextDir(""),"");
-				doh.is("ltr", bidi.getTextDir("123 > 456"),"123 > 456");
-				doh.is("ltr", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");
-			}
-		},
-		{
-			name:"5. getTextDir(), textDir = RTL, dir = LTR",
-
-			runTest:function(){
-				var bidi = new dijit._Widget({textDir:"rtl",dir:"ltr"});
-			
-				doh.is("rtl", bidi.getTextDir("Hello"),"Hello");
-				doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("123 Hello"),"123 Hello");
-				doh.is("rtl", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("_Hello"),"_Hello");
-				doh.is("rtl", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
-				doh.is("rtl", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
-				doh.is("rtl", bidi.getTextDir(""),"");
-				doh.is("rtl", bidi.getTextDir("123 > 456"),"123 > 456");
-				doh.is("rtl", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");
-			}
-		},
-		{
-			name:"6. getTextDir(), textDir = RTL, dir = RTL",
-
-			runTest:function(){
-				var bidi = new dijit._Widget({textDir:"rtl",dir:"rtl"});			
-			
-				doh.is("rtl", bidi.getTextDir("Hello"),"Hello");
-				doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("123 Hello"),"123 Hello");
-				doh.is("rtl", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("_Hello"),"_Hello");
-				doh.is("rtl", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
-				doh.is("rtl", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
-				doh.is("rtl", bidi.getTextDir(""),"");
-				doh.is("rtl", bidi.getTextDir("123 > 456"),"123 > 456");
-				doh.is("rtl", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");	
-			}
-		},
-		{
-			name:"7. getTextDir(), textDir = AUTO, dir = LTR",
-
-			runTest:function(){
-				var bidi = new dijit._Widget({textDir:"auto",dir:"ltr"});
-				
-				doh.is("ltr", bidi.getTextDir("Hello"),"Hello");
-				doh.is("ltr", bidi.getTextDir("123 Hello"),"123 Hello");
-				doh.is("rtl", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("_Hello"),"_Hello");
-				doh.is("rtl", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
-				doh.is("rtl", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir(""),"");
-				doh.is("ltr", bidi.getTextDir("123 > 456"),"123 > 456");
-				doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
-				doh.is("ltr", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");
-			}
-		},
-		{
-			name:"8. getTextDir(), textDir = AUTO, dir = RTL",
-
-			runTest:function(){
-				var bidi = new dijit._Widget({textDir:"auto",dir:"rtl"});
-				
-				doh.is("ltr", bidi.getTextDir("Hello"),"Hello");
-				doh.is("ltr", bidi.getTextDir("123 Hello"),"123 Hello");
-				doh.is("rtl", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("_Hello"),"_Hello");
-				doh.is("rtl", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
-				doh.is("ltr", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
-				doh.is("ltr", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir(""),"");
-				doh.is("rtl", bidi.getTextDir("123 > 456"),"123 > 456");
-				doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
-				doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
-				doh.is("rtl", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");
-				
+define(["doh/main", "dojo/has"], function(doh, has){
+
+	has.add("dojo-bidi", true);
+
+	require(["dijit/_Widget"], function(_Widget){
+		doh.register("dijit.tests._BidiSupport.BidiSupportModule.BidiSupportTest", [
+			{
+				name:"1. checkContextual(), dir = LTR",
+
+				runTest:function(){
+					var bidi = new _Widget({textDir:"ltr", dir:"ltr"});
+
+					doh.is("ltr", bidi._checkContextual("Hello"),"Hello");
+					doh.is("rtl", bidi._checkContextual("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi._checkContextual("123 Hello"),"123 Hello");
+					doh.is("rtl", bidi._checkContextual("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi._checkContextual("_Hello"),"_Hello");
+					doh.is("rtl", bidi._checkContextual("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi._checkContextual("!!$%@ Hello"), "!!$%@ Hello");
+					doh.is("rtl", bidi._checkContextual("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi._checkContextual("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi._checkContextual("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
+					doh.is("ltr", bidi._checkContextual(""),"");
+					doh.is("ltr", bidi._checkContextual("123 > 456"),"123 > 456");
+					doh.is("ltr", bidi._checkContextual("%^$^&)( )_($!"),"%^$^&)( )_($!");
+				}
+			},
+			{
+				name:"2. checkContextual(), dir = RTL",
+
+				runTest:function(){
+					var bidi = new _Widget({textDir:"ltr",dir:"rtl"});
+
+					doh.is("ltr", bidi._checkContextual("Hello"),"Hello");
+					doh.is("rtl", bidi._checkContextual("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi._checkContextual("123 Hello"),"123 Hello");
+					doh.is("rtl", bidi._checkContextual("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi._checkContextual("_Hello"),"_Hello");
+					doh.is("rtl", bidi._checkContextual("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi._checkContextual("!!$%@ Hello"), "!!$%@ Hello");
+					doh.is("rtl", bidi._checkContextual("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi._checkContextual("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi._checkContextual("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
+					doh.is("rtl", bidi._checkContextual(""),"");
+					doh.is("rtl", bidi._checkContextual("123 > 456"),"123 > 456");
+					doh.is("rtl", bidi._checkContextual("%^$^&)( )_($!"),"%^$^&)( )_($!");
+				}
+			},
+			{
+				name:"3. getTextDir(), textDir = LTR, dir = LTR",
+
+				runTest:function(){
+					var bidi = new _Widget({textDir:"ltr",dir:"ltr"});
+
+					doh.is("ltr", bidi.getTextDir("Hello"),"Hello");
+					doh.is("ltr", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("123 Hello"),"123 Hello");
+					doh.is("ltr", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("_Hello"),"_Hello");
+					doh.is("ltr", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
+					doh.is("ltr", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
+					doh.is("ltr", bidi.getTextDir(""),"");
+					doh.is("ltr", bidi.getTextDir("123 > 456"),"123 > 456");
+					doh.is("ltr", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");
+				}
+			},
+			{
+				name:"4. getTextDir(), textDir = LTR, dir = RTL",
+
+				runTest:function(){
+					var bidi = new _Widget({textDir:"ltr",dir:"rtl"});
+
+					doh.is("ltr", bidi.getTextDir("Hello"),"Hello");
+					doh.is("ltr", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("123 Hello"),"123 Hello");
+					doh.is("ltr", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("_Hello"),"_Hello");
+					doh.is("ltr", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
+					doh.is("ltr", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
+					doh.is("ltr", bidi.getTextDir(""),"");
+					doh.is("ltr", bidi.getTextDir("123 > 456"),"123 > 456");
+					doh.is("ltr", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");
+				}
+			},
+			{
+				name:"5. getTextDir(), textDir = RTL, dir = LTR",
+
+				runTest:function(){
+					var bidi = new _Widget({textDir:"rtl",dir:"ltr"});
+
+					doh.is("rtl", bidi.getTextDir("Hello"),"Hello");
+					doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("123 Hello"),"123 Hello");
+					doh.is("rtl", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("_Hello"),"_Hello");
+					doh.is("rtl", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
+					doh.is("rtl", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
+					doh.is("rtl", bidi.getTextDir(""),"");
+					doh.is("rtl", bidi.getTextDir("123 > 456"),"123 > 456");
+					doh.is("rtl", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");
+				}
+			},
+			{
+				name:"6. getTextDir(), textDir = RTL, dir = RTL",
+
+				runTest:function(){
+					var bidi = new _Widget({textDir:"rtl",dir:"rtl"});
+
+					doh.is("rtl", bidi.getTextDir("Hello"),"Hello");
+					doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("123 Hello"),"123 Hello");
+					doh.is("rtl", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("_Hello"),"_Hello");
+					doh.is("rtl", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
+					doh.is("rtl", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
+					doh.is("rtl", bidi.getTextDir(""),"");
+					doh.is("rtl", bidi.getTextDir("123 > 456"),"123 > 456");
+					doh.is("rtl", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");
+				}
+			},
+			{
+				name:"7. getTextDir(), textDir = AUTO, dir = LTR",
+
+				runTest:function(){
+					var bidi = new _Widget({textDir:"auto",dir:"ltr"});
+
+					doh.is("ltr", bidi.getTextDir("Hello"),"Hello");
+					doh.is("ltr", bidi.getTextDir("123 Hello"),"123 Hello");
+					doh.is("rtl", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("_Hello"),"_Hello");
+					doh.is("rtl", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
+					doh.is("rtl", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir(""),"");
+					doh.is("ltr", bidi.getTextDir("123 > 456"),"123 > 456");
+					doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
+					doh.is("ltr", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");
+				}
+			},
+			{
+				name:"8. getTextDir(), textDir = AUTO, dir = RTL",
+
+				runTest:function(){
+					var bidi = new _Widget({textDir:"auto",dir:"rtl"});
+
+					doh.is("ltr", bidi.getTextDir("Hello"),"Hello");
+					doh.is("ltr", bidi.getTextDir("123 Hello"),"123 Hello");
+					doh.is("rtl", bidi.getTextDir("123 \u05e9\u05dc\u05d5\u05dd"),"123 \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("_Hello"),"_Hello");
+					doh.is("rtl", bidi.getTextDir("_\u05e9\u05dc\u05d5\u05dd"),"_\u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("!!$%@ \u05e9\u05dc\u05d5\u05dd"), "!!$%@ \u05e9\u05dc\u05d5\u05dd");
+					doh.is("ltr", bidi.getTextDir("!!$%@ Hello"), "!!$%@ Hello");
+					doh.is("ltr", bidi.getTextDir("Hello \u05e9\u05dc\u05d5\u05dd"), "Hello \u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir(""),"");
+					doh.is("rtl", bidi.getTextDir("123 > 456"),"123 > 456");
+					doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd"),"\u05e9\u05dc\u05d5\u05dd");
+					doh.is("rtl", bidi.getTextDir("\u05e9\u05dc\u05d5\u05dd Hello"),"\u05e9\u05dc\u05d5\u05dd Hello");
+					doh.is("rtl", bidi.getTextDir("%^$^&)( )_($!"),"%^$^&)( )_($!");
+
+				}
 			}
-		}
-	]);
-	
+		]);
+	});
 });
diff --git a/dijit/tests/_BidiSupport/BidiSupportModule/module.js b/dijit/tests/_BidiSupport/BidiSupportModule/module.js
index c45a5aa..e06d876 100644
--- a/dijit/tests/_BidiSupport/BidiSupportModule/module.js
+++ b/dijit/tests/_BidiSupport/BidiSupportModule/module.js
@@ -1,11 +1,3 @@
-dojo.provide("dijit.tests._BidiSupport.BidiSupportModule.module");
-
-try{
-
-	dojo.require("dijit.tests._BidiSupport.BidiSupportModule.BidiSupportTest");
-
-}catch(e){
-
-	doh.debug(e);
-
-}
+define([
+	"./BidiSupportTest"
+], 1);
\ No newline at end of file
diff --git a/dijit/tests/_BidiSupport/_data/categoriesHeb.json b/dijit/tests/_BidiSupport/_data/categoriesHeb.json
index 8acefb4..1f81657 100644
--- a/dijit/tests/_BidiSupport/_data/categoriesHeb.json
+++ b/dijit/tests/_BidiSupport/_data/categoriesHeb.json
@@ -1,12 +1,12 @@
 {
-	identifier: 'id',
-	label: 'name',
-	items: [
-		{ id: '0', name:'Foods!', numberOfItems:1, children:[ {_reference: '1'},  {_reference: '2'},  {_reference: '3'} ] },
-			{ id: '1', name:'\u05E4\u05D9\u05E8\u05D5\u05EA!', numberOfItems:1, children:[ {_reference: '4'} ] },
-				{ id: '4',name:'Citrus!', numberOfItems:1, items:[ {_reference: '5'} ] },
-					{ id: '5', name:'\u05EA\u05E4\u05D5\u05D6!'},
-		{ id: '2', name:'Vegetables!', numberOfItems:0},
-		{ id: '3', name:'Cereals!', numberOfItems:0}
+	"identifier": "id",
+	"label": "name",
+	"items": [
+		{ "id": "0", "name":"Foods!", "numberOfItems":1, "children":[ {"_reference": "1"},  {"_reference": "2"},  {"_reference": "3"} ] },
+			{ "id": "1", "name":"\u05E4\u05D9\u05E8\u05D5\u05EA!", "numberOfItems":1, "children":[ {"_reference": "4"} ] },
+				{ "id": "4","name":"Citrus!", "numberOfItems":1, "items":[ {"_reference": "5"} ] },
+					{ "id": "5", "name":"\u05EA\u05E4\u05D5\u05D6!"},
+		{ "id": "2", "name":"Vegetables!", "numberOfItems":0},
+		{ "id": "3", "name":"Cereals!", "numberOfItems":0}
 	]
 }
diff --git a/dijit/tests/_BidiSupport/_data/countriesHeb.json b/dijit/tests/_BidiSupport/_data/countriesHeb.json
index 3df7477..2f481b0 100644
--- a/dijit/tests/_BidiSupport/_data/countriesHeb.json
+++ b/dijit/tests/_BidiSupport/_data/countriesHeb.json
@@ -1,46 +1,46 @@
-?{
-	identifier: 'id',
-	label: 'name',
-	items: [
-	        { id: 'AF', name:'Africa!', type:'continent', population:'900 million', area: '30,221,532 sq km',
-	        		timezone: '-1 UTC to +4 UTC',
-	        		children:[{_reference:'EG'}, {_reference:'KE'}, {_reference:'SD'}] },
-	        	{ id: 'EG', name:'\u05DE\u05E6\u05E8\u05D9\u05DD!', type:'country' },
-	        	{ id: 'KE', name:'Kenya!', type:'country',
-	        			children:[{_reference:'Nairobi!'}, {_reference:'Mombasa!'}] },
-	        		{ id: 'Nairobi!', name:'Nairobi!', type:'city' },
-	        		{ id: 'Mombasa!', name:'Mombasa!', type:'city' },
-	        	{ id: 'SD', name:'Sudan', type:'country',
-	        			children:{_reference:'Khartoum'} },
-	        		{ id: 'Khartoum', name:'Khartoum', type:'city' },
-	        	{ id: 'AS', name:'Asia!', type:'continent',
-	        			children:[{_reference:'CN'}, {_reference:'IN'}, {_reference:'RU'}, {_reference:'MN'}] },
-	        		{ id: 'CN', name:'China!', type:'country' },
-	        		{ id: 'IN', name:'India!', type:'country' },
-	        		{ id: 'RU', name:'Russia!', type:'country' },
-	        		{ id: 'MN', name:'Mongolia!', type:'country' },
-	        	{ id: 'OC', name:'\u05D0\u05D5\u05E7\u05D0\u05E0\u05D9\u05D4!', type:'continent', population:'21 million',
-	        			children:{_reference:'AU'}},
-	        	{ id: 'AU', name:'Australia!', type:'country', population:'21 million'},
-	        	{ id: 'EU', name:'Europe', type:'continent',
-	        			children:[{_reference:'DE'}, {_reference:'FR'}, {_reference:'ES'}, {_reference:'IT'}] },
-	        	{ id: 'DE', name:'\u05D2\u05E8\u05DE\u05E0\u05D9\u05D4!', type:'country' },
-	        	{ id: 'FR', name:'France!', type:'country' },
-	        	{ id: 'ES', name:'Spain!', type:'country' },
-	        	{ id: 'IT', name:'Italy!', type:'country' },
-	        { id: 'NA', name:'\u05D0\u05DE\u05E8\u05D9\u05E7\u05D4 \u05E6\u05E4\u05D5\u05E0\u05D9\u05EA!', type:'continent',
-	        		children:[{_reference:'MX'}, {_reference:'CA'}, {_reference:'US'}] },
-	        	{ id: 'MX', name:'Mexico!', type:'country',  population:'108 million', area:'1,972,550 sq km',
-	        			children:[{_reference:'Mexico City!'}, {_reference:'\u05D2\u05D5\u05D0\u05D3\u05DC\u05D2\u05E8\u05D4!'}] },
-	        		{ id: 'Mexico City!', name:'Mexico City!', type:'city', population:'19 million', timezone:'-6 UTC'},
-	        		{ id: '\u05D2\u05D5\u05D0\u05D3\u05DC\u05D2\u05E8\u05D4!', name:'\u05D2\u05D5\u05D0\u05D3\u05DC\u05D2\u05E8\u05D4!', type:'city', population:'4 million', timezone:'-6 UTC' },
-	        	{ id: 'CA', name:'\u05E7\u05E0\u05D3\u05D4!', type:'country',  population:'33 million', area:'9,984,670 sq km',
-	        			children:[{_reference:'Ottawa!'}, {_reference:'\u05D8\u05D5\u05E8\u05D5\u05E0\u05D8\u05D5!'}] },
-	        		{ id: 'Ottawa!', name:'Ottawa!', type:'city', population:'0.9 million', timezone:'-5 UTC'},
-	        		{ id: '\u05D8\u05D5\u05E8\u05D5\u05E0\u05D8\u05D5!', name:'\u05D8\u05D5\u05E8\u05D5\u05E0\u05D8\u05D5!', type:'city', population:'2.5 million', timezone:'-5 UTC' },
-	        	{ id: 'US', name:'United States of America!', type:'country' },
-	        { id: 'SA', name:'South America!', type:'continent',
-	        		children:[{_reference:'BR'}, {_reference:'AR'}] },
-	        	{ id: 'BR', name:'Brazil!', type:'country', population:'186 million' },
-	        	{ id: 'AR', name:'Argentina!', type:'country', population:'40 million' }
+{
+	"identifier": "id",
+	"label": "name",
+	"items": [
+			{ "id": "AF", "name":"Africa!", "type":"continent", "population":"900 million", "area": "30,221,532 sq km",
+					"timezone": "-1 UTC to +4 UTC",
+					"children":[{"_reference":"EG"}, {"_reference":"KE"}, {"_reference":"SD"}] },
+				{ "id": "EG", "name":"\u05DE\u05E6\u05E8\u05D9\u05DD!", "type":"country" },
+				{ "id": "KE", "name":"Kenya!", "type":"country",
+						"children":[{"_reference":"Nairobi!"}, {"_reference":"Mombasa!"}] },
+					{ "id": "Nairobi!", "name":"Nairobi!", "type":"city" },
+					{ "id": "Mombasa!", "name":"Mombasa!", "type":"city" },
+				{ "id": "SD", "name":"Sudan", "type":"country",
+						"children":{"_reference":"Khartoum"} },
+					{ "id": "Khartoum", "name":"Khartoum", "type":"city" },
+				{ "id": "AS", "name":"Asia!", "type":"continent",
+						"children":[{"_reference":"CN"}, {"_reference":"IN"}, {"_reference":"RU"}, {"_reference":"MN"}] },
+					{ "id": "CN", "name":"China!", "type":"country" },
+					{ "id": "IN", "name":"India!", "type":"country" },
+					{ "id": "RU", "name":"Russia!", "type":"country" },
+					{ "id": "MN", "name":"Mongolia!", "type":"country" },
+				{ "id": "OC", "name":"\u05D0\u05D5\u05E7\u05D0\u05E0\u05D9\u05D4!", "type":"continent", "population":"21 million",
+						"children":{"_reference":"AU"}},
+				{ "id": "AU", "name":"Australia!", "type":"country", "population":"21 million"},
+				{ "id": "EU", "name":"Europe", "type":"continent",
+						"children":[{"_reference":"DE"}, {"_reference":"FR"}, {"_reference":"ES"}, {"_reference":"IT"}] },
+				{ "id": "DE", "name":"\u05D2\u05E8\u05DE\u05E0\u05D9\u05D4!", "type":"country" },
+				{ "id": "FR", "name":"France!", "type":"country" },
+				{ "id": "ES", "name":"Spain!", "type":"country" },
+				{ "id": "IT", "name":"Italy!", "type":"country" },
+			{ "id": "NA", "name":"\u05D0\u05DE\u05E8\u05D9\u05E7\u05D4 \u05E6\u05E4\u05D5\u05E0\u05D9\u05EA!", "type":"continent",
+					"children":[{"_reference":"MX"}, {"_reference":"CA"}, {"_reference":"US"}] },
+				{ "id": "MX", "name":"Mexico!", "type":"country",  "population":"108 million", "area":"1,972,550 sq km",
+						"children":[{"_reference":"Mexico City!"}, {"_reference":"\u05D2\u05D5\u05D0\u05D3\u05DC\u05D2\u05E8\u05D4!"}] },
+					{ "id": "Mexico City!", "name":"Mexico City!", "type":"city", "population":"19 million", "timezone":"-6 UTC"},
+					{ "id": "\u05D2\u05D5\u05D0\u05D3\u05DC\u05D2\u05E8\u05D4!", "name":"\u05D2\u05D5\u05D0\u05D3\u05DC\u05D2\u05E8\u05D4!", "type":"city", "population":"4 million", "timezone":"-6 UTC" },
+				{ "id": "CA", "name":"\u05E7\u05E0\u05D3\u05D4!", "type":"country",  "population":"33 million", "area":"9,984,670 sq km",
+						"children":[{"_reference":"Ottawa!"}, {"_reference":"\u05D8\u05D5\u05E8\u05D5\u05E0\u05D8\u05D5!"}] },
+					{ "id": "Ottawa!", "name":"Ottawa!", "type":"city", "population":"0.9 million", "timezone":"-5 UTC"},
+					{ "id": "\u05D8\u05D5\u05E8\u05D5\u05E0\u05D8\u05D5!", "name":"\u05D8\u05D5\u05E8\u05D5\u05E0\u05D8\u05D5!", "type":"city", "population":"2.5 million", "timezone":"-5 UTC" },
+				{ "id": "US", "name":"United States of America!", "type":"country" },
+			{ "id": "SA", "name":"South America!", "type":"continent",
+					"children":[{"_reference":"BR"}, {"_reference":"AR"}] },
+				{ "id": "BR", "name":"Brazil!", "type":"country", "population":"186 million" },
+				{ "id": "AR", "name":"Argentina!", "type":"country", "population":"40 million" }
 ]}
diff --git a/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/DynamicChangeTextDir.html b/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/DynamicChangeTextDir.html
index 508282f..7d76526 100644
--- a/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/DynamicChangeTextDir.html
+++ b/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/DynamicChangeTextDir.html
@@ -2,7 +2,7 @@
 
 <html>
 	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">	
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Textarea with _BidiSupport</title>
 
 		<style type="text/css">
@@ -12,11 +12,10 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true">
-		</script>		
+			data-dojo-config="parseOnLoad: true, isDebug: true, has: { 'dojo-bidi': true }">
+		</script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dijit.form.Textarea");
 			dojo.require("dijit.form.TextBox");
 			dojo.require("dijit.form.SimpleTextarea");
@@ -25,7 +24,6 @@
 			dojo.require("dojo.parser");
 			dojo.require("doh.runner");
 			dojo.require("dijit.form.ComboBox");
-			dojo.require("dijit._BidiSupport");
 
 			dojo.ready(function(){
 				doh.register("parse", function(){
@@ -95,11 +93,11 @@
 					, filledTbP
 					, blankSTaP
 					, filledSTaP
-					, combo;	
-					
+					, combo;
+
 				dijit.byId("comboBM").toggleDropDown();
 				dijit.byId("comboBM").closeDropDown();
-			
+
 				doh.register("test dynamic change of textDir initial", [
 					{
 						name: "initial textDir of all the widgets",
@@ -117,11 +115,11 @@
 							blankTbP = dijit.byId("blankTbP");
 							filledTbP = dijit.byId("filledTbP");
 							blankSTaP = dijit.byId("blankSTaP");
-							filledSTaP = dijit.byId("filledSTaP");	
+							filledSTaP = dijit.byId("filledSTaP");
 
 							combo = dijit.byId("comboBM");
 						},
-						
+
 						runTest: function(){
 							doh.is("ltr",blankTaP.textDir, "direction of : blankTaP");
 							doh.is("ltr",filledTaP.textDir, "direction of : filledTaP");
@@ -136,9 +134,9 @@
 							doh.is("ltr",filledTbP.textDir, "direction of : filledTbP");
 							doh.is("ltr",blankSTaP.textDir, "direction of : blankSTaP");
 							doh.is("ltr",filledSTaP.textDir, "direction of : filledSTaP");
-							
+
 							doh.is("ltr",combo.dropDown.textDir, "direction of : combo.dropDown");
-							
+
 							var d = new doh.Deferred();
 
 							combo.toggleDropDown();
@@ -153,7 +151,7 @@
 							}), 100);
 							return d;
 						},
-						
+
 						tearDown:function(){
 							combo.closeDropDown();
 						}
@@ -221,11 +219,11 @@
 							}), 100);
 							return d;
 						},
-						
+
 						tearDown:function(){
 							combo.closeDropDown();
 						}
-						
+
 					}
 				]);
 
@@ -291,7 +289,7 @@
 							}), 100);
 							return d;
 						},
-						
+
 						tearDown:function(){
 							combo.closeDropDown();
 						}
@@ -306,7 +304,7 @@
 							var buttonAUTO = dojo.byId("switchTD_AUTO");
 							buttonAUTO.click();
 						},
-					
+
 						runTest: function(){
 
 							doh.is("auto",blankTaP.textDir, "direction of : blankTaP");
@@ -351,16 +349,16 @@
 											contextualDir = this.getTextDir(node.innerText || node.textContent || "");
 											doh.is(contextualDir, node.dir, node.innerText || node.textContent || "");
 									}
-								},combo);							
+								},combo);
 							}), 100);
 							return d;
 						},
-						
+
 						tearDown:function(){
 							combo.closeDropDown();
 						}
 					}
-				]);				
+				]);
 
 				doh.run();
 			});
@@ -368,7 +366,7 @@
 	</head>
 	<body class="tundra" data-dojo-textdir="ltr">
 		<h1 class="testTitle">Dynamically changed textDir.</h1>
-		
+
 		<h2 class="testTitle">Textarea</h2>
 		<div class="testExample">
 			<table>
@@ -376,7 +374,7 @@
 					<th>
 						<label for="filledlTaM">dijit.form.Textarea, initially filled, markup created</label>
 						<br>
-						<textarea data-dojo-type="dijit.form.Textarea" id="filledlTaM" data-dojo-props='textDir:"ltr", style:{width:"30em"}'>Hello world!</textarea>
+						<textarea data-dojo-type="dijit/form/Textarea" id="filledlTaM" data-dojo-props='textDir:"ltr", style:{width:"30em"}'>Hello world!</textarea>
 						<br>
 					</th>
 					<th>
@@ -390,7 +388,7 @@
 					<th>
 						<label for="blankTaM">dijit.form.Textarea, initially blank:</label>
 						<br>
-						<textarea data-dojo-type="dijit.form.Textarea" id="blankTaM" data-dojo-props='textDir:"ltr", style:{width:"30em"}'></textarea>
+						<textarea data-dojo-type="dijit/form/Textarea" id="blankTaM" data-dojo-props='textDir:"ltr", style:{width:"30em"}'></textarea>
 						<br>
 					</th>
 					<th>
@@ -412,7 +410,7 @@
 					<th>
 						<label for="filledTbM">dijit.form.TextBox, initially filled, markup created:</label>
 						<br>
-						<input data-dojo-type="dijit.form.TextBox" id="filledTbM" data-dojo-props='name:"filledTbM", value:"blah.", style:{width:"30em"},textDir:"ltr"'/>
+						<input data-dojo-type="dijit/form/TextBox" id="filledTbM" data-dojo-props='name:"filledTbM", value:"blah.", style:{width:"30em"},textDir:"ltr"'/>
 						<br>
 					</th>
 					<th>
@@ -426,7 +424,7 @@
 					<th>
 						<label for="blankTbM">dijit.form.TextBox, initially blank, markup created:</label>
 						<br>
-						<input data-dojo-type="dijit.form.TextBox" id="blankTbM" data-dojo-props='name:"blankTbM", style:{width:"30em"}, value:"", textDir:"ltr"'/>
+						<input data-dojo-type="dijit/form/TextBox" id="blankTbM" data-dojo-props='name:"blankTbM", style:{width:"30em"}, value:"", textDir:"ltr"'/>
 						<br>
 					</th>
 					<th>
@@ -448,7 +446,7 @@
 					<th>
 						<label>dijit.form.SimpleTextarea, initially filled, markup created</label>
 						<br>
-						<textarea id="filledStaM" data-dojo-type="dijit.form.SimpleTextarea"
+						<textarea id="filledStaM" data-dojo-type="dijit/form/SimpleTextarea"
 							data-dojo-props='name:"filledStaM",rows:"2", style:{width:"30em"}
 							'>שלום עולם, שלום לכולם אין יותר כיף מדוג'ו!
 						</textarea>
@@ -465,7 +463,7 @@
 					<th>
 						<label for="blankTbM">dijit.form.SimpleTextarea, initially blank, markup created:</label>
 						<br>
-						<textarea id="blankStaM" data-dojo-type="dijit.form.SimpleTextarea" 
+						<textarea id="blankStaM" data-dojo-type="dijit/form/SimpleTextarea"
 							data-dojo-props='name:"blankStaM",rows:"2", style:{width:"30em"},
 							textDir:"ltr"'>
 						</textarea>
@@ -483,8 +481,8 @@
 		<br>
 		<label for="comboBM">dijit.form.ComboBox, markup</label>
 		<br>
-		<select id="comboBM" 
-			data-dojo-type="dijit.form.ComboBox" 
+		<select id="comboBM"
+			data-dojo-type="dijit/form/ComboBox"
 			data-dojo-props='name:"comboBM",
 			textDir:"ltr"'>
 				<option >Apples!</option>
@@ -499,8 +497,8 @@
 
 		<input id="swithchTD_RTL" type="button" value="change textDir 2 RTL"
 			onclick="dijit.byId('blankTaP').set('textDir','rtl');
-				dijit.byId('filledTaP').set('textDir','rtl'); 
-				dijit.byId('blankTaM').set('textDir','rtl'); 
+				dijit.byId('filledTaP').set('textDir','rtl');
+				dijit.byId('blankTaM').set('textDir','rtl');
 				dijit.byId('filledlTaM').set('textDir','rtl');
 				dijit.byId('comboBM').set('textDir','rtl');
 				dijit.byId('blankTbM').set('textDir','rtl');
@@ -512,11 +510,11 @@
 				dijit.byId('blankSTaP').set('textDir','rtl');
 				dijit.byId('filledSTaP').set('textDir','rtl');
 			"/>
-		
+
 		<input id="swithchTD_LTR" type="button" value="change textDir 2 LTR"
 			onclick="dijit.byId('blankTaP').set('textDir','ltr');
-				dijit.byId('filledTaP').set('textDir','ltr'); 
-				dijit.byId('blankTaM').set('textDir','ltr'); 
+				dijit.byId('filledTaP').set('textDir','ltr');
+				dijit.byId('blankTaM').set('textDir','ltr');
 				dijit.byId('filledlTaM').set('textDir','ltr');
 				dijit.byId('comboBM').set('textDir','ltr');
 				dijit.byId('blankTbM').set('textDir','ltr');
@@ -528,11 +526,11 @@
 				dijit.byId('blankSTaP').set('textDir','ltr');
 				dijit.byId('filledSTaP').set('textDir','ltr');
 			"/>
-		
+
 		<input id="switchTD_AUTO" type="button" value="change textDir 2 AUTO"
 			onclick="dijit.byId('blankTaP').set('textDir','auto');
-				dijit.byId('filledTaP').set('textDir','auto'); 
-				dijit.byId('blankTaM').set('textDir','auto'); 
+				dijit.byId('filledTaP').set('textDir','auto');
+				dijit.byId('blankTaM').set('textDir','auto');
 				dijit.byId('filledlTaM').set('textDir','auto');
 				dijit.byId('comboBM').set('textDir','auto');
 				dijit.byId('blankTbM').set('textDir','auto');
diff --git a/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/module.js b/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/module.js
index 2057f6a..eb4f9da 100644
--- a/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/module.js
+++ b/dijit/tests/_BidiSupport/dynamicallyChangeTextDir/module.js
@@ -1,11 +1,5 @@
-dojo.provide("dijit.tests._BidiSupport.dynamicallyChangeTextDir.module");
+define(["doh/main", "require"], function(doh, require){
 
-try{
+	doh.register("_BidiSupport.dynamicallyChangeTextDir.DynamicChangeTextDir", require.toUrl("./DynamicChangeTextDir.html"));
 
-	doh.registerUrl("dijit.tests._BidiSupport.dynamicallyChangeTextDir.DynamicChangeTextDir", dojo.moduleUrl("dijit","tests/_BidiSupport/dynamicallyChangeTextDir/DynamicChangeTextDir.html"));
-	
-}catch(e){
-
-	doh.debug(e);
-
-}
+});
diff --git a/dijit/tests/_BidiSupport/form/Button.html b/dijit/tests/_BidiSupport/form/Button.html
new file mode 100644
index 0000000..eeb1924
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/Button.html
@@ -0,0 +1,400 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Dojo Button Widget Test</title>
+
+		<style type="text/css">
+			@import "../../../themes/claro/document.css";
+			@import "../../css/dijitTests.css";
+
+			/* group multiple buttons in a row */
+			.box {
+				display: block;
+				text-align: center;
+			}
+			BUTTON, INPUT,
+			.box .dijit {
+				margin-right: 10px;
+				vertical-align: middle;
+			}
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../themes/claro/claro.css"/>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, has: { 'dojo-bidi': true }"></script>
+
+		<script language="JavaScript" type="text/javascript">
+
+			require([
+				"doh/runner",
+				"dojo/dom",
+				"dojo/parser",
+				"dijit/registry",
+				"dijit/form/Button",
+				"dijit/Menu",
+				"dijit/MenuItem",
+				"dijit/form/DropDownButton",
+				"dojo/domReady!"
+			], function(doh, dom, parser, registry, Button, Menu, MenuItem, DropDownButton){
+
+				var createButton = function(){
+					var widget = new Button({label: "Button LTR ...", id: "progbLtr", textDir: "ltr"});
+					widget.placeAt("buttonContainer");	// place in page
+					var widget2 = new Button({label: "Button RTL ...", id: "progbRtl", textDir: "rtl"});
+					widget2.placeAt("buttonContainer");	// place in page
+					var widget3 = new Button({label: "START AUTO \u05e9\u05dc\u05d5\u05dd\u0021\u0021!...", id: "progbAuto1", textDir: "auto"});
+					widget3.placeAt("buttonContainer");	// place in page
+					var widget4 = new Button({label: "\u05e9\u05dc\u05d5\u05dd\u0021\u0021 AUTO END...", id: "progbAuto2"});
+					widget4.set('textDir','auto');
+					widget4.placeAt("buttonContainer");	// place in page
+				};
+
+				var createDropDownButton = function(){
+					var menu = new Menu({ });
+					menu.domNode.style.display="none";
+					var menuItem1 = new MenuItem({
+						label: "Cut!",
+						iconClass:"registryEditorIcon registryEditorIconCut",
+						id:"progCut",
+						textDir:"ltr"
+					});
+					menu.addChild(menuItem1);
+
+					var menuItem2 = new MenuItem({
+						label: "Copy!",
+						iconClass:"registryEditorIcon registryEditorIconCopy",
+						id:"progCopy",
+						textDir:"rtl"
+					});
+					menu.addChild(menuItem2);
+
+					var menuItem3 = new MenuItem({
+						label: "Paste \u05e9\u05dc\u05d5\u05dd\u0021\u0021!...",
+						iconClass:"registryEditorIcon registryEditorIconPaste",
+						id:"progPaste",
+						textDir:"auto"
+					});
+					menu.addChild(menuItem3);
+
+					var menuItem4 = new MenuItem({
+						label: "\u05e9\u05dc\u05d5\u05dd\u0021\u0021!... Save!",
+						iconClass:"registryEditorIcon registryEditorIconSave",
+						id:"progSave",
+						textDir:"auto"
+						});
+					menu.addChild(menuItem4);
+
+					var params = {
+						label: "hello!",
+						name: "programmatic2",
+						dropDown: menu,
+						id: "progButton",
+						textDir:"auto"
+					};
+					var widget = new DropDownButton(params);
+					widget.startup();
+					dom.byId("dropdownButtonContainer").appendChild(widget.domNode);
+				};
+
+				doh.register("registry.tests._BidiSupport.form.Button", [
+
+					function parse(){
+						return parser.parse();
+					},
+
+					function test_LTR_TextDir(){
+						doh.is(registry.byId("bltr").get("textDir"), "ltr");
+						doh.is(registry.byId("bltr").containerNode.dir, "ltr");
+					},
+
+					function test_LTR_TextDir_RTL_dir(){
+						doh.is(registry.byId("bltr_rtl").get("textDir"), "ltr");
+						doh.is(registry.byId("bltr_rtl").containerNode.dir, "ltr");
+					},
+
+					function test_RTL_TextDir_LTR_dir(){
+						doh.is(registry.byId("brtl_ltr").get("textDir"), "rtl");
+						doh.is(registry.byId("brtl_ltr").containerNode.dir, "rtl");
+					},
+
+					function test_RTL_TextDir(){
+						doh.is(registry.byId("brtl").get("textDir"), "rtl");
+						doh.is(registry.byId("brtl").containerNode.dir, "rtl");
+					},
+
+					function test_AUTO_TextDir(){
+						doh.is(registry.byId("bauto_ltr").get("textDir"), "auto");
+						doh.is(registry.byId("bauto_ltr").containerNode.dir, "ltr");
+						doh.is(registry.byId("bauto_rtl").get("textDir"), "auto");
+						doh.is(registry.byId("bauto_rtl").containerNode.dir, "rtl");
+					},
+
+					function test_ToggleButton_TextDirLTR(){
+						doh.is(registry.byId("togltr").get("textDir"), "ltr");
+						doh.is(registry.byId("togltr").containerNode.dir, "ltr");
+					},
+
+					function test_ToggleButton_TextDirRTL(){
+						doh.is(registry.byId("togrtl").get("textDir"), "rtl");
+						doh.is(registry.byId("togrtl").containerNode.dir, "rtl");
+					},
+
+					function test_ToggleButton_TextDirAUTO(){
+						doh.is(registry.byId("togauto_ltr").get("textDir"), "auto");
+						doh.is(registry.byId("togauto_ltr").containerNode.dir, "ltr");
+						doh.is(registry.byId("togauto_rtl").get("textDir"), "auto");
+						doh.is(registry.byId("togauto_rtl").containerNode.dir, "rtl");
+					},
+
+					function test_programmat_button(){
+						createButton();
+						doh.is(registry.byId("progbLtr").get("textDir"), "ltr");
+						doh.is(registry.byId("progbLtr").containerNode.dir, "ltr");
+						doh.is(registry.byId("progbRtl").get("textDir"), "rtl");
+						doh.is(registry.byId("progbRtl").containerNode.dir, "rtl");
+						doh.is(registry.byId("progbAuto1").get("textDir"), "auto");
+						doh.is(registry.byId("progbAuto1").containerNode.dir, "ltr");
+						doh.is(registry.byId("progbAuto2").get("textDir"), "auto");
+						doh.is(registry.byId("progbAuto2").containerNode.dir, "rtl");
+					},
+
+					function test_changeLabel_forAUTO(){
+						var item = registry.byId("bauto_rtl");
+						doh.is(item.get("textDir"), "auto");
+						doh.is(item.containerNode.dir, "rtl");
+						item.set("label", "");
+						doh.is(item.containerNode.dir, "ltr");
+						item.set("label", "new label '\u05e9\u05d9\u05de\u05d5\u05e9\u0020\u05d1\u05ea\u05d2\u05d9\u05d5\u05ea\u002e'");
+						doh.is(item.containerNode.dir, "ltr");
+						item.set("label", "'\u05e9\u05d9\u05de\u05d5\u05e9\u0020\u05d1\u05ea\u05d2\u05d9\u05d5\u05ea\u002e'");
+						doh.is(item.containerNode.dir, "rtl");
+					},
+
+					function test_DropDownButton_LTR_TextDir(){
+						doh.is(registry.byId("bltr_cut").get("textDir"), "ltr");
+						doh.is(registry.byId("bltr_cut").textDirNode.dir, "ltr");
+						doh.is(registry.byId("bltr_copy").get("textDir"), "ltr");
+						doh.is(registry.byId("bltr_copy").textDirNode.dir, "ltr");
+						doh.is(registry.byId("bltr_paste").get("textDir"), "rtl");
+						doh.is(registry.byId("bltr_paste").textDirNode.dir, "rtl");
+					},
+
+					function test_DropDownButton_RTL_TextDir(){
+						doh.is(registry.byId("brtl_cut").get("textDir"), "rtl");
+						doh.is(registry.byId("brtl_cut").textDirNode.dir, "rtl");
+						doh.is(registry.byId("brtl_copy").get("textDir"), "ltr");
+						doh.is(registry.byId("brtl_copy").textDirNode.dir, "ltr");
+						doh.is(registry.byId("brtl_paste").get("textDir"), "rtl");
+						doh.is(registry.byId("brtl_paste").textDirNode.dir, "rtl");
+					},
+
+					function test_DropDownButton_AUTO_TextDir(){
+						doh.is(registry.byId("bauto_cut").get("textDir"), "auto");
+						doh.is(registry.byId("bauto_cut").textDirNode.dir, "ltr");
+						doh.is(registry.byId("bauto_copy").get("textDir"), "auto");
+						doh.is(registry.byId("bauto_copy").textDirNode.dir, "rtl");
+					},
+
+					function test_ComboButton_TextDirLTR(){
+						doh.is(registry.byId("comboltr_cut").get("textDir"), "ltr");
+						doh.is(registry.byId("comboltr_cut").textDirNode.dir, "ltr");
+						doh.is(registry.byId("comboltr_copy").get("textDir"), "ltr");
+						doh.is(registry.byId("comboltr_copy").textDirNode.dir, "ltr");
+						doh.is(registry.byId("comboltr_paste").get("textDir"), "rtl");
+						doh.is(registry.byId("comboltr_paste").textDirNode.dir, "rtl");
+					},
+
+					function test_ComboButton_TextDirRTL(){
+						doh.is(registry.byId("combortl_cut").get("textDir"), "rtl");
+						doh.is(registry.byId("combortl_cut").textDirNode.dir, "rtl");
+						doh.is(registry.byId("combortl_copy").get("textDir"), "ltr");
+						doh.is(registry.byId("combortl_copy").textDirNode.dir, "ltr");
+						doh.is(registry.byId("combortl_paste").get("textDir"), "rtl");
+						doh.is(registry.byId("combortl_paste").textDirNode.dir, "rtl");
+					},
+
+					function test_ComboButton_TextDirAUTO(){
+						doh.is(registry.byId("comboauto_cut").get("textDir"), "auto");
+						doh.is(registry.byId("comboauto_cut").textDirNode.dir, "ltr");
+						doh.is(registry.byId("comboauto_copy").get("textDir"), "auto");
+						doh.is(registry.byId("comboauto_copy").textDirNode.dir, "rtl");
+					},
+
+					function test_programmat_DropDownButton(){
+						createDropDownButton ();
+						doh.is(registry.byId("progCut").get("textDir"), "ltr");
+						doh.is(registry.byId("progCut").textDirNode.dir, "ltr");
+						doh.is(registry.byId("progCopy").get("textDir"), "rtl");
+						doh.is(registry.byId("progCopy").textDirNode.dir, "rtl");
+						doh.is(registry.byId("progPaste").get("textDir"), "auto");
+						doh.is(registry.byId("progPaste").textDirNode.dir, "ltr");
+						doh.is(registry.byId("progSave").get("textDir"), "auto");
+						doh.is(registry.byId("progSave").textDirNode.dir, "rtl");
+					},
+
+					function test_DropDownButton_changeLabel_forAUTO(){
+						var item = registry.byId("bauto_copy");
+						doh.is(item.get("textDir"), "auto");
+						doh.is(item.textDirNode.dir, "rtl");
+						item.set("label", "");
+						doh.is(item.textDirNode.dir, "ltr");
+						item.set("label", "new label '\u05e9\u05d9\u05de\u05d5\u05e9\u0020\u05d1\u05ea\u05d2\u05d9\u05d5\u05ea\u002e'");
+						doh.is(item.textDirNode.dir, "ltr");
+						item.set("label", "'\u05e9\u05d9\u05de\u05d5\u05e9\u0020\u05d1\u05ea\u05d2\u05d9\u05d5\u05ea\u002e'");
+						doh.is(item.textDirNode.dir, "rtl");
+					},
+
+					function test_deepMenu(){
+						doh.is(registry.byId("level3_cut").get("textDir"), "auto");
+						doh.is(registry.byId("level3_cut").textDirNode.dir, "ltr");
+						doh.is(registry.byId("level4_cut").get("textDir"), "auto");
+						doh.is(registry.byId("level4_cut").textDirNode.dir, "rtl");
+					}
+				]);
+				doh.run();
+			});
+	</script>
+	</head>
+<body class="claro">
+	<h1 class="testTitle">registry Button Test</h1>
+	<h2>Simple buttons</h2>
+
+	<p class="box">
+		<button data-dojo-type="dijit/form/Button" id="bltr" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon", value:"Button LTR ...", textDir:"ltr"'>
+			Button LTR ...
+		</button>
+
+		<button data-dojo-type="dijit/form/Button" id="bltr_rtl" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon", value:"Button LTR RTL ...", textDir:"ltr", dir:"rtl"'>
+			Button LTR RTL ...
+		</button>
+
+		<button data-dojo-type="dijit/form/Button" id="brtl_ltr" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon", value:"Button RTL LTR ...", textDir:"rtl", dir:"ltr"'>
+			Button LTR RTL ...
+		</button>
+
+		<button data-dojo-type="dijit/form/Button" id="brtl" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon", value:"Button RTL ...", textDir:"rtl"'>
+			Button RTL ...
+		</button>
+
+		<button data-dojo-type="dijit/form/Button" id="bauto_ltr" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon", value:"START AUTO חדש!...", textDir:"auto"'>
+			START AUTO חדש!...
+		</button>
+
+		<button data-dojo-type="dijit/form/Button" id="bauto_rtl" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon", value:"חדש AUTO END...", textDir:"auto"'>
+			חדש AUTO END...
+		</button>
+
+		<button id="togltr" checked data-dojo-type="dijit/form/ToggleButton" data-dojo-props='
+			iconClass:"dijitCheckBoxIcon", textDir:"ltr"'>
+			Toggle Button LTR ...
+		</button>
+
+		<button id="togrtl" checked data-dojo-type="dijit/form/ToggleButton" data-dojo-props='
+			iconClass:"dijitCheckBoxIcon", textDir:"rtl"'>
+			Toggle Button RTL ...
+		</button>
+
+		<button id="togauto_ltr" checked data-dojo-type="dijit/form/ToggleButton" data-dojo-props='
+			iconClass:"dijitCheckBoxIcon", textDir:"auto"'>
+			START AUTO חדש!...
+		</button>
+
+		<button id="togauto_rtl" checked data-dojo-type="dijit/form/ToggleButton" data-dojo-props='
+			iconClass:"dijitCheckBoxIcon", textDir:"auto"'>
+			חדש AUTO END...
+		</button>
+
+		<button id="dropltr" title="edit title" value="Edit" data-dojo-type="dijit/form/DropDownButton" data-dojo-textdir="ltr" data-dojo-props='iconClass:"noteIcon"'>
+			<span>Edit<b>!</b></span>
+			<span id="bltr_editMenu" data-dojo-type="dijit/Menu">
+				<span id="bltr_cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut"'>Cut!</span>
+				<span id="bltr_copy" data-dojo-type="dijit/MenuItem" data-dojo-textdir="ltr" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy"'>Copy!</span>
+				<span id="bltr_paste" data-dojo-type="dijit/MenuItem" data-dojo-textdir="rtl" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste"'>Paste!</span>
+			</span>
+		</button>
+
+		<button id="droprtl" title="edit title" value="Edit" data-dojo-type="dijit/form/DropDownButton" data-dojo-textdir="rtl" data-dojo-props='iconClass:"noteIcon"'>
+			<span>Edit<b>!</b></span>
+			<span id="brtl_editMenu" data-dojo-type="dijit/Menu">
+				<span id="brtl_cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut"'>Cut!</span>
+				<span id="brtl_copy" data-dojo-type="dijit/MenuItem" data-dojo-textdir="ltr" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy"'>Copy!</span>
+				<span id="brtl_paste" data-dojo-type="dijit/MenuItem" data-dojo-textdir="rtl" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste"'>Paste!</span>
+			</span>
+		</button>
+
+		<button id="dropauto" title="edit title" value="Edit" data-dojo-type="dijit/form/DropDownButton" data-dojo-textdir="auto" data-dojo-props='iconClass:"noteIcon"'>
+			<span>Edit<b>!</b></span>
+			<span id="bauto_editMenu" data-dojo-type="dijit/Menu">
+				<span id="bauto_cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut"'>START AUTO חדש Cut!</span>
+				<span id="bauto_copy" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy"'>חדש Copy! AUTO END</span>
+			</span>
+		</button>
+
+		<button id="comboltr" title="edit title" value="Edit" data-dojo-type="dijit/form/ComboButton" data-dojo-textdir="ltr" data-dojo-props='optionsTitle:"save options"'>
+			<span>Edit<b>!</b></span>
+			<span id="comboltr_editMenu" data-dojo-type="dijit/Menu">
+				<span id="comboltr_cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut"'>Cut!</span>
+				<span id="comboltr_copy" data-dojo-type="dijit/MenuItem" data-dojo-textdir="ltr" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy"'>Copy!</span>
+				<span id="comboltr_paste" data-dojo-type="dijit/MenuItem" data-dojo-textdir="rtl" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste"'>Paste!</span>
+			</span>
+		</button>
+
+		<button id="combortl" title="edit title" value="Edit" data-dojo-type="dijit/form/ComboButton" data-dojo-textdir="rtl" data-dojo-props='optionsTitle:"save options"'>
+			<span>Edit<b>!</b></span>
+			<span id="combortl_editMenu" data-dojo-type="dijit/Menu">
+				<span id="combortl_cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut"'>Cut!</span>
+				<span id="combortl_copy" data-dojo-type="dijit/MenuItem" data-dojo-textdir="ltr" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy"'>Copy!</span>
+				<span id="combortl_paste" data-dojo-type="dijit/MenuItem" data-dojo-textdir="rtl" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste"'>Paste!</span>
+			</span>
+		</button>
+
+		<button id="comboauto" title="edit title" value="Edit" data-dojo-type="dijit/form/ComboButton" data-dojo-textdir="auto" data-dojo-props='optionsTitle:"save options"'>
+			<span>Edit<b>!</b></span>
+			<span id="comboauto_editMenu" data-dojo-type="dijit/Menu">
+				<span id="comboauto_cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut"'>START AUTO חדש Cut!</span>
+				<span id="comboauto_copy" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy"'>חדש Copy! AUTO END</span>
+			</span>
+		</button>
+
+		<button id="deepedit" title="edit title" value="Edit" data-dojo-type="dijit/form/DropDownButton" data-dojo-textdir="auto" data-dojo-props='iconClass:"noteIcon"'>
+			<span>Edit<b>!</b></span>
+			<span id="deepeditMenu" data-dojo-type="dijit/Menu">
+				<span id="level1_cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut"'>Cut!</span>
+				<span id="level1_copy" data-dojo-type="dijit/MenuItem" data-dojo-textdir="ltr" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy"'>Copy!</span>
+				<span id="level1_paste" data-dojo-type="dijit/MenuItem" data-dojo-textdir="rtl" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste"'>Paste!</span>
+				<span data-dojo-type="dijit/MenuSeparator"></span>
+				<span data-dojo-type="dijit/PopupMenuItem">
+					<span>Submenu!</span>
+					<span id="submenu2" data-dojo-type="dijit/Menu">
+						<span id="level2_cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut"'>Cut!</span>
+						<span id="level2_copy" data-dojo-type="dijit/MenuItem" data-dojo-textdir="ltr" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy"'>Copy!</span>
+						<span id="level2_paste" data-dojo-type="dijit/MenuItem" data-dojo-textdir="rtl" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste"'>Paste!</span>
+						<span data-dojo-type="dijit/PopupMenuItem">
+							<span>Deeper Submenu!</span>
+							<span id="submenu4" data-dojo-type="dijit/Menu">
+								<span id="level3_cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut"'>START AUTO חדש Cut!</span>
+								<span id="level3_copy" data-dojo-type="dijit/MenuItem" data-dojo-textdir="ltr" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy"'>Copy!</span>
+								<span id="level3_paste" data-dojo-type="dijit/MenuItem" data-dojo-textdir="rtl" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste"'>Paste!</span>
+								<span data-dojo-type="dijit/PopupMenuItem">
+									<span>Deeper deeper Submenu!</span>
+									<span id="submenu5" data-dojo-type="dijit/Menu">
+										<span id="level4_cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut"'>חדש Cut! AUTO END</span>
+										<span id="level4_copy" data-dojo-type="dijit/MenuItem" data-dojo-textdir="ltr" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy"'>Copy!</span>
+										<span id="level4_paste" data-dojo-type="dijit/MenuItem" data-dojo-textdir="rtl" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste"'>Paste!</span>
+									</span>
+							</span>
+						</span>
+					</span>
+				</span>
+			</span>
+		</button>
+	</p>
+	<p id="buttonContainer" style="display: none;"></p>
+	<p id="dropdownButtonContainer" style="display: none;"></p>
+
+</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/module.js b/dijit/tests/_BidiSupport/form/module.js
index d5a883a..fb5f438 100644
--- a/dijit/tests/_BidiSupport/form/module.js
+++ b/dijit/tests/_BidiSupport/form/module.js
@@ -1,23 +1,27 @@
-dojo.provide("dijit.tests._BidiSupport.form.module");
+define(["doh/main", "require"], function(doh, require){
 
-try{
+	doh.register("_BidiSupport.form.test_PlaceholderInput.", require.toUrl("./test_PlaceholderInput.html"));
 
-	doh.registerUrl("dijit.tests._BidiSupport.form.noTextDirTextWidgets", dojo.moduleUrl("dijit", "tests/_BidiSupport/form/noTextDirTextWidgets.html"));
+	doh.register("_BidiSupport.form.multiSelect", require.toUrl("./multiSelect.html"));
 
-	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
+	doh.register("_BidiSupport.form.noTextDirTextWidgets", require.toUrl("./noTextDirTextWidgets.html"));
 
-	doh.registerUrl("dijit.tests._BidiSupport.form.robot.Textarea", dojo.moduleUrl("dijit","tests/_BidiSupport/form/robot/Textarea.html"+userArgs), 999999);
-	
-	doh.registerUrl("dijit.tests._BidiSupport.form.robot.SimpleComboBoxes", dojo.moduleUrl("dijit","tests/_BidiSupport/form/robot/SimpleComboBoxes.html"+userArgs), 999999);
+	doh.register("_BidiSupport.form.Button", require.toUrl("./Button.html"));
 
-	doh.registerUrl("dijit.tests._BidiSupport.form.robot.SimpleTextarea", dojo.moduleUrl("dijit","tests/_BidiSupport/form/robot/SimpleTextarea.html"+userArgs), 999999);
+	doh.register("_BidiSupport.form.Select", require.toUrl("./test_Select.html"));
 
-    doh.registerUrl("dijit.tests._BidiSupport.form.robot.TextBoxes", dojo.moduleUrl("dijit","tests/_BidiSupport/form/robot/TextBoxes.html"+userArgs), 999999);
-	
-	doh.registerUrl("dijit.tests._BidiSupport.form.robot.InlineEditBox", dojo.moduleUrl("dijit","tests/_BidiSupport/form/robot/InlineEditBox.html"+userArgs), 999999);
+	doh.register("_BidiSupport.form.Slider", require.toUrl("./test_Slider.html"));
 
-}catch(e){
+	doh.register("_BidiSupport.form.robot.Textarea", require.toUrl("./robot/Textarea.html"), 999999);
 
-	doh.debug(e);
+	doh.register("_BidiSupport.form.robot.SimpleComboBoxes", require.toUrl("./robot/SimpleComboBoxes.html"), 999999);
 
-}
+	doh.register("_BidiSupport.form.robot.SimpleTextarea", require.toUrl("./robot/SimpleTextarea.html"), 999999);
+
+	doh.register("_BidiSupport.form.robot.TextBoxes", require.toUrl("./robot/TextBoxes.html"), 999999);
+
+	doh.register("_BidiSupport.form.robot.InlineEditBox", require.toUrl("./robot/InlineEditBox.html"), 999999);
+
+	doh.register("_BidiSupport.form.TimeTextBox", require.toUrl("./test_TimeTextBox.html?mode=test"), 999999);
+
+});
\ No newline at end of file
diff --git a/dijit/tests/_BidiSupport/form/multiSelect.html b/dijit/tests/_BidiSupport/form/multiSelect.html
new file mode 100644
index 0000000..d7c4b96
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/multiSelect.html
@@ -0,0 +1,381 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Testing MultiSelect form widget | The Dojo Toolkit</title>
+
+	<style type="text/css">
+		@import "../../../../dijit/tests/css/dijitTests.css";
+		#select1, #select2, #select3 {
+			width:255px;
+			height:300px;
+			overflow:auto;
+		}
+		div#sel1, div#sel2,div#sel3 {
+			float: left;
+
+		}
+		div#leftRightButtons,div#leftRightButtons2 {
+			float: left;
+			padding: 10em 0.5em 0 0.5em;
+		}
+	</style>
+
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+	<!-- only needed for alternate theme testing: -->
+	<script type="text/javascript" src="../../_testCommon.js"></script>
+
+	<script type="text/javascript">
+		var globalId = null;
+
+		dojo.require("dijit.form.MultiSelect");
+
+		// needed for tests:
+		dojo.require("dijit.form.Form");
+		dojo.require("dijit.form.Button");
+		dojo.require("dijit.layout.SplitContainer");
+
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		dojo.require("doh.runner");
+
+		dojo.ready(function(){
+
+			// ref a clonable node, then split it between two selects
+			var c = dojo.query(".clone")[0];
+			var l = -1;
+			opt = function(){
+				return dojo.byId((++l%2 == 0 ? "select1":"select2" ));
+			};
+
+			// turn any non-data-dojo-type selects into widgets programatically:
+			dojo.query("select").forEach(function(n){
+				if(!dijit.byNode(n)){
+					var textDir = n.id == "select3" ? "" : (n.id == "select1" ? "rtl" : "auto");
+					var foo = new dijit.form.MultiSelect({ textDir: textDir ,name: n.name }, n);
+				}
+			});
+
+			// programatic
+			var myWidget = new dijit.form.MultiSelect({textDir: "auto"});
+			myWidget.placeAt(dojo.body());
+			globalId = myWidget.id;
+
+			// listen to the "move items" buttons
+			dojo.query("button.switch")
+				.connect("onclick",function(e){
+					switch(e.target.id.toString()){
+						case "button21" : dijit.byId("select1").addSelected(dijit.byId("select2")); break;
+						case "button12" : dijit.byId("select2").addSelected(dijit.byId("select1")); break;
+						case "button32" : dijit.byId("select2").addSelected(dijit.byId("select3")); break;
+						case "button23" : dijit.byId("select3").addSelected(dijit.byId("select2")); break;
+						case "up" : dijit.byId("select4").addSelected(dijit.byId(globalId)); break;
+						case "down" : dijit.byId(globalId).addSelected(dijit.byId("select4")); break;
+					}
+			});
+
+			// listen to the invert buttons
+			dojo.query("button.invert")
+				.connect("onclick",function(e){
+					switch(e.target.id.toString()){
+						case "i1" : dijit.byId("select1").invertSelection(); break;
+						case "i2" : dijit.byId("select2").invertSelection(); break;
+						case "i3" : dijit.byId("select4").invertSelection(); break;
+						case "i4" : dijit.byId("select3").invertSelection(); break;
+					}
+			});
+
+			// there is only one debug button
+			dojo.query(".debug").connect("onclick",function(e){
+				console.log('select1 value:',dijit.byId("select1").get('value') + '/' + dijit.byId("select1").value);
+				console.log('select2 value:',dijit.byId("select2").get('value') + '/' + dijit.byId("select2").value);
+				console.log('select3 value:',dijit.byId("select3").get('value') + '/' + dijit.byId("select3").value);
+				console.log('select4 value:',dijit.byId("select4").get('value') + '/' + dijit.byId("select4").value);
+			});
+
+			dojo.connect(dojo.byId("formSubmit"), "onclick", function(e){
+				// see what the real form says about our widgets:
+				var vals = dojo.formToJson("test");
+				console.log(vals);
+			});
+
+			// Testing:
+			var originalList = [
+				"Tennessee...",
+				"\u05d5\u05d9\u05e8\u05d2\u0027\u05d9\u05e0\u05d9\u05d4...",
+				"Washington...",
+				"Florida...",
+				"California..."
+			];
+			var valueList = [
+				"Tennessee...",
+				"\u05d5\u05d9\u05e8\u05d2\u0027\u05d9\u05e0\u05d9\u05d4...",
+				"WA",
+				"FL",
+				"CA"
+			];
+			var lreList = [
+				"\u202ATennessee...\u202C",
+				"\u202A\u05d5\u05d9\u05e8\u05d2\u0027\u05d9\u05e0\u05d9\u05d4...\u202C",
+				"\u202AWashington...\u202C",
+				"\u202AFlorida...\u202C",
+				"\u202ACalifornia...\u202C"
+			];
+			var rleList = [
+				"\u202BTennessee...\u202C",
+				"\u202B\u05d5\u05d9\u05e8\u05d2\u0027\u05d9\u05e0\u05d9\u05d4...\u202C",
+				"\u202BWashington...\u202C",
+				"\u202BFlorida...\u202C",
+				"\u202BCalifornia...\u202C"
+			];
+			var autoList = [
+				"\u202ATennessee...\u202C",
+				"\u202B\u05d5\u05d9\u05e8\u05d2\u0027\u05d9\u05e0\u05d9\u05d4...\u202C",
+				"\u202AWashington...\u202C",
+				"\u202AFlorida...\u202C",
+				"\u202ACalifornia...\u202C"
+			];
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+			var select1 = dijit.byId("select1"),
+				select2 = dijit.byId("select2"),
+				select3 = dijit.byId("select3"),
+				select4 = dijit.byId("select4"),
+				select5 = dijit.byId(globalId),
+
+				button12 = dojo.byId("button12"),
+				button21 = dojo.byId("button21"),
+				button32 = dojo.byId("button32"),
+				button23 = dojo.byId("button23"),
+				buttonUp = dojo.byId("up"),
+				buttonDown = dojo.byId("down"),
+
+				bidiLtr, bidiRtl, bidiAuto;
+
+			doh.register("test multiSelect", [
+				{
+					name:"initial direction of the Lists",
+
+					runTest:function(){
+						doh.is("rtl", select1.textDir, "textDir of - " + select1.id);
+						doh.is("auto", select2.textDir, "textDir of - " + select2.id);
+						doh.is("rtl", select4.textDir, "textDir of - " + select4.id);
+						doh.is("auto", select5.textDir, "textDir of - " + select5.id);
+					}
+				},
+				{
+					name:"test options: select1, select4",
+
+					runTest:function(){
+						var select1 = dijit.byId("select1"), select4 = dijit.byId("select4");
+						var select1OptionsArr = select1.containerNode.options;
+						var select4OptionsArr = select4.containerNode.options;
+						for(var index = 0; index < select1.containerNode.options.length; index++){
+
+							doh.is(rleList[index], select1OptionsArr[index].text, "select1 - option.text: " + (index + 1));
+							doh.is(valueList[index], select1OptionsArr[index].value, "select1 - option.value: " + (index + 1));
+
+							doh.is(rleList[index], select4OptionsArr[index].text, "select4 - option.text: " + (index + 1));
+							doh.is(valueList[index], select4OptionsArr[index].value, "select4 - option.value: " + (index + 1));
+
+						}
+					}
+				},
+				{
+					name:"set value: select1, select2",
+
+					runTest:function(){
+
+						var select1OptionsArr = select1.containerNode.options;
+						var select2OptionsArr = select2.containerNode.options;
+
+						select1.set("value", ["Tennessee...","\u05d5\u05d9\u05e8\u05d2\u0027\u05d9\u05e0\u05d9\u05d4...","FL","CA"]);
+						button12.click();
+
+						// Florida button21
+						doh.is(rleList[2], select1OptionsArr[0].text, "select1 - option.text: " + 1);
+						doh.is(valueList[2], select1OptionsArr[0].value, "select1 - option.value: " + 1);
+
+						doh.is(autoList[0], select2OptionsArr[0].text, "select2 - option.text: " + 1);
+						doh.is(valueList[0], select2OptionsArr[0].value, "select2 - option.value: " + 1);
+
+						doh.is(autoList[1], select2OptionsArr[1].text, "select2 - option.text: " + 2);
+						doh.is(valueList[1], select2OptionsArr[1].value, "select2 - option.value: " + 2);
+
+						doh.is(autoList[3], select2OptionsArr[2].text, "select2 - option.text: " + 3);
+						doh.is(valueList[3], select2OptionsArr[2].value, "select2 - option.value: " + 3);
+
+						doh.is(autoList[4], select2OptionsArr[3].text, "select2 - option.text: " + 4);
+						doh.is(valueList[4], select2OptionsArr[3].value, "select2 - option.value: " + 4);
+
+					}
+				},
+				{
+					name:"set value: select2, select3",
+
+					runTest:function(){
+
+						var d = new doh.Deferred();
+
+						//select1.set("value", ["Tennessee...","\u05d5\u05d9\u05e8\u05d2\u0027\u05d9\u05e0\u05d9\u05d4...","FL","CA"]);
+						button23.click();
+
+						var select3OptionsArr = select3.containerNode.options;
+
+						doh.is(originalList[0], select3OptionsArr[0].text, "select3 - option.text: " + 1);
+						doh.is(valueList[0], select3OptionsArr[0].value, "select3 - option.value: " + 1);
+
+						doh.is(originalList[1], select3OptionsArr[1].text, "select3 - option.text: " + 2);
+						doh.is(valueList[1], select3OptionsArr[1].value, "select3 - option.value: " + 2);
+
+						doh.is(originalList[3], select3OptionsArr[2].text, "select3 - option.text: " + 3);
+						doh.is(valueList[3], select3OptionsArr[2].value, "select3 - option.value: " + 3);
+
+						doh.is(originalList[4], select3OptionsArr[3].text, "select3 - option.text: " + 4);
+						doh.is(valueList[4], select3OptionsArr[3].value, "select3 - option.value: " + 4);
+
+						select3.set("value", ["\u05d5\u05d9\u05e8\u05d2\u0027\u05d9\u05e0\u05d9\u05d4...","FL","CA"]);
+						button32.click();
+
+						var select2OptionsArr = select2.containerNode.options;
+
+						setTimeout(d.getTestCallback(function(){
+							doh.is(autoList[1], select2OptionsArr[0].text, "select2 - option.text: " + 1);
+							doh.is(valueList[1], select2OptionsArr[0].value, "select2 - option.value: " + 1);
+
+							doh.is(autoList[3], select2OptionsArr[1].text, "select2 - option.text: " + 2);
+							doh.is(valueList[3], select2OptionsArr[1].value, "select2 - option.value: " + 2);
+
+							doh.is(autoList[4], select2OptionsArr[2].text, "select2 - option.text: " + 3);
+							doh.is(valueList[4], select2OptionsArr[2].value, "select2 - option.value: " + 3);
+						}), 100);
+						return d;
+
+					}
+				},
+				{
+					name:"set value: select4, select5",
+
+					runTest:function(){
+
+						var d = new doh.Deferred();
+
+						select4.set("value", ["Tennessee...","\u05d5\u05d9\u05e8\u05d2\u0027\u05d9\u05e0\u05d9\u05d4...","FL","CA"]);
+						buttonDown.click();
+
+						var select5OptionsArr = select5.containerNode.options;
+
+						doh.is(autoList[0], select5OptionsArr[0].text, "select5 - option.text: " + 1);
+						doh.is(valueList[0], select5OptionsArr[0].value, "select5 - option.value: " + 1);
+
+						doh.is(autoList[1], select5OptionsArr[1].text, "select5 - option.text: " + 2);
+						doh.is(valueList[1], select5OptionsArr[1].value, "select5 - option.value: " + 2);
+
+						doh.is(autoList[3], select5OptionsArr[2].text, "select5 - option.text: " + 3);
+						doh.is(valueList[3], select5OptionsArr[2].value, "select5 - option.value: " + 3);
+
+						doh.is(autoList[4], select5OptionsArr[3].text, "select5 - option.text: " + 4);
+						doh.is(valueList[4], select5OptionsArr[3].value, "select5 - option.value: " + 4);
+
+						select5.set("value", ["\u05d5\u05d9\u05e8\u05d2\u0027\u05d9\u05e0\u05d9\u05d4...","FL","CA"]);
+						buttonUp.click();
+
+						var select4OptionsArr = select4.containerNode.options;
+
+						setTimeout(d.getTestCallback(function(){
+							doh.is(rleList[2], select4OptionsArr[0].text, "select4 - option.text: " + 1);
+							doh.is(valueList[2], select4OptionsArr[0].value, "select4 - option.value: " + 1);
+
+							doh.is(rleList[1], select4OptionsArr[1].text, "select4 - option.text: " + 2);
+							doh.is(valueList[1], select4OptionsArr[1].value, "select4 - option.value: " + 2);
+
+							doh.is(rleList[3], select4OptionsArr[2].text, "select4 - option.text: " + 3);
+							doh.is(valueList[3], select4OptionsArr[2].value, "select4 - option.value: " + 3);
+
+							doh.is(rleList[4], select4OptionsArr[3].text, "select4 - option.text: " + 3);
+							doh.is(valueList[4], select4OptionsArr[3].value, "select4 - option.value: " + 3);
+						}), 100);
+						return d;
+
+					}
+				}
+			]);
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro" style="padding:20px">
+
+	<h1 class="testTitle">dijit.form.MultiSelect:</h1>
+	<p>Select one or more items in First or Second list and move them between lists using the buttons provided.</p>
+	<form action="#" method="get" id="test" onsubmit="return false">
+
+		<div>
+			<div id="sel1" role="presentation">
+				<label for="select1">First list:</label><br>
+				<select id="select1" multiple size="7"  tabindex="1" name="first">
+					<option selected>Tennessee...</option>
+					<option >וירג'יניה...</option>
+					<option value="WA">Washington...</option>
+					<option value="FL">Florida...</option>
+					<option value="CA">California...</option>
+				</select>
+			</div>
+			<div id="leftRightButtons" role="presentation">
+				<span>
+					<button class="switch" id="button21" title="Move Items to First list"><</button>
+					<button class="switch" id="button12" title="Move Items to Second list">></button>
+				</span>
+			</div>
+			<div id="sel2" role="presentation">
+				<label for="select2">Second list:</label><br>
+				<select id="select2" multiple size="7" name="second">
+				</select>
+			</div>
+			<div id="leftRightButtons2" role="presentation">
+				<span>
+					<button class="switch" id="button32" title="Move Items to Third list"><</button>
+					<button class="switch" id="button23" title="Move Items to Second list">></button>
+				</span>
+			</div>
+			<div id="sel3" role="presentation">
+				<label for="select3">Third list:</label><br>
+				<select id="select3" multiple size="7" name="third">
+				</select>
+			</div>
+		</div>
+
+		<br style="clear: both;"/><br>
+
+		<button class='invert' id="i1">invert first list</button>
+		<button class="invert" id="i2">invert second list</button>
+		<button class="invert" id="i4">invert third list</button>
+		<button id="formSubmit" type="submit">Submit</button>
+		<button class="debug">call get('value')</button>
+
+		<h3><label for="select4">markup:</label></h3>
+
+		<select id="select4" multiple data-dojo-type="dijit.form.MultiSelect"
+			data-dojo-props='textDir:"rtl",name:"select4",
+			style:{height:"200px", width:"175px", border:"5px solid #ededed"}' name="fourth">
+
+			<option selected>Tennessee...</option>
+			<option >וירג'יניה...</option>
+			<option value="WA">Washington...</option>
+			<option value="FL">Florida...</option>
+			<option value="CA">California...</option>
+		</select>
+	<br><br>
+	<button class="switch" id="up">move up</button>
+	<button class="switch" id="down">move Down</button>
+	<br>
+
+</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/noTextDirTextWidgets.html b/dijit/tests/_BidiSupport/form/noTextDirTextWidgets.html
index 451e66a..06b2374 100644
--- a/dijit/tests/_BidiSupport/form/noTextDirTextWidgets.html
+++ b/dijit/tests/_BidiSupport/form/noTextDirTextWidgets.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 
-<html dir="ltr" data-dojo-textdir="rtl">
+<html>
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>DOH input fields witout textDir support Tests</title>
@@ -12,164 +12,159 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="isDebug: true">
-		</script>		
+			data-dojo-config="async: true, isDebug: true, has: { 'dojo-bidi': true }"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-			dojo.require("dijit.form.DateTextBox");
-			dojo.require("dijit.form.NumberSpinner");
-			dojo.require("dijit.form.CurrencyTextBox");
-			dojo.require("dijit.form.TimeTextBox");
-			dojo.require("dojo.currency");			
-			dojo.require("dojo.date.locale");
-			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-			dojo.require("doh.runner");
-			dojo.require("dijit._BidiSupport");
-			
-			dojo.ready(function(){
+			require([
+				"doh/runner",
+				"dojo/dom",
+				"dojo/parser",
+				"dijit/registry",
+				"dojo/domReady!"
+			], function(doh, dom, parser, registry){
 
 				doh.register("parse", function(){
-					dojo.parser.parse();
+					// Parse is asynchronous because it pulls in modules like DateTextBox, so return its promise
+					return parser.parse();
 				});
 
 				doh.register("initial direction of the textBoxes", [
 					{
-						name:"Group 1",
+						name: "Group 1",
 
-						runTest:function(){
+						runTest: function(){
 
-							var textBox1 = dijit.byId("local_1"),
-								textBox2 = dijit.byId("local_12"),
-								textBox3 = dijit.byId("local_2"),
-								textBox4 = dijit.byId("local_22");
+							var textBox1 = registry.byId("local_1"),
+								textBox2 = registry.byId("local_12"),
+								textBox3 = registry.byId("local_2"),
+								textBox4 = registry.byId("local_22");
 
 							doh.is("rtl", textBox1.textDir, "textDir of - " + textBox1.id);
-							doh.is("ltr", textBox1.dir, "dir of - " + textBox1.id);
-							doh.t(textBox1.focusNode.dir != textBox1.textDir, "textDir != dir of - " + textBox1.id);
-																				
+							doh.is("", textBox1.dir, "dir of - " + textBox1.id);
+							doh.t(textBox1.focusNode.dir === textBox1.textDir, "textDir != dir of - " + textBox1.id);
+
 							doh.is("ltr", textBox2.textDir, "textDir of - " + textBox2.id);
-							doh.is("ltr", textBox2.dir, "dir of - " + textBox2.id);
-							doh.t(textBox2.focusNode.dir != textBox2.textDir, "textDir != dir of - " + textBox2.id);
+							doh.is("", textBox2.dir, "dir of - " + textBox2.id);
+							doh.t(textBox2.focusNode.dir === textBox2.textDir, "textDir != dir of - " + textBox2.id);
 
 							doh.is("rtl", textBox3.textDir, "textDir of - " + textBox3.id);
 							doh.is("rtl", textBox3.dir, "dir of - " + textBox3.id);
-							doh.t(textBox3.focusNode.dir != textBox3.textDir, "textDir != dir of - " + textBox3.id);
+							doh.t(textBox3.focusNode.dir === textBox3.textDir, "textDir != dir of - " + textBox3.id);
 
 							doh.is("ltr", textBox4.textDir, "textDir of - " + textBox4.id);
 							doh.is("rtl", textBox4.dir, "dir of - " + textBox4.id);
-							doh.t(textBox4.focusNode.dir != textBox4.textDir, "textDir != dir of - " + textBox4.id);
+							doh.t(textBox4.focusNode.dir === textBox4.textDir, "textDir != dir of - " + textBox4.id);
 						}
-					},			
+					},
 					{
-						name:"Group 2",
-
-						runTest:function(){
-							
-							var textBox1 = dijit.byId("localLong_1"),
-								textBox2 = dijit.byId("localLong_12"),
-								textBox3 = dijit.byId("localLong_2"),
-								textBox4 = dijit.byId("localLong_22");
-						
+						name: "Group 2",
+
+						runTest: function(){
+
+							var textBox1 = registry.byId("localLong_1"),
+								textBox2 = registry.byId("localLong_12"),
+								textBox3 = registry.byId("localLong_2"),
+								textBox4 = registry.byId("localLong_22");
+
 							doh.is("rtl", textBox1.textDir, "textDir of - " + textBox1.id);
 							doh.is("ltr", textBox1.dir, "dir of - " + textBox1.id);
-							doh.t(textBox1.focusNode.dir != textBox1.textDir, "textDir != dir of - " + textBox1.id);
-																		
+							doh.t(textBox1.focusNode.dir === textBox1.textDir, "textDir != dir of - " + textBox1.id);
+
 							doh.is("ltr", textBox2.textDir, "textDir of - " + textBox2.id);
-							doh.is("ltr", textBox2.dir, "dir of - " + textBox2.id);
-							doh.t(textBox2.focusNode.dir != textBox2.textDir, "textDir != dir of - " + textBox2.id);
+							doh.is("", textBox2.dir, "dir of - " + textBox2.id);
+							doh.t(textBox2.focusNode.dir === textBox2.textDir, "textDir != dir of - " + textBox2.id);
 
 							doh.is("rtl", textBox3.textDir, "textDir of - " + textBox3.id);
 							doh.is("rtl", textBox3.dir, "dir of - " + textBox3.id);
-							doh.t(textBox3.focusNode.dir != textBox3.textDir, "textDir != dir of - " + textBox3.id);
+							doh.t(textBox3.focusNode.dir === textBox3.textDir, "textDir != dir of - " + textBox3.id);
 
 							doh.is("ltr", textBox4.textDir, "textDir of - " + textBox4.id);
 							doh.is("rtl", textBox4.dir, "dir of - " + textBox4.id);
-							doh.t(textBox4.focusNode.dir != textBox4.textDir, "textDir != dir of - " + textBox4.id);
+							doh.t(textBox4.focusNode.dir === textBox4.textDir, "textDir != dir of - " + textBox4.id);
 						}
 					},
 					{
-						name:"Group 3",
+						name: "Group 3",
+
+						runTest: function(){
 
-						runTest:function(){
+							var textBox1 = registry.byId("integerspinner_1"),
+								textBox2 = registry.byId("integerspinner_12"),
+								textBox3 = registry.byId("integerspinner_2"),
+								textBox4 = registry.byId("integerspinner_22");
 
-							var textBox1 = dijit.byId("integerspinner_1"),
-								textBox2 = dijit.byId("integerspinner_12"),
-								textBox3 = dijit.byId("integerspinner_2"),
-								textBox4 = dijit.byId("integerspinner_22");
-							
 							doh.is("rtl", textBox1.textDir, "textDir of - " + textBox1.id);
-							doh.is("ltr", textBox1.dir, "dir of - " + textBox1.id);
-							doh.t(textBox1.focusNode.dir != textBox1.textDir, "textDir != dir of - " + textBox1.id);
-																		
+							doh.is("", textBox1.dir, "dir of - " + textBox1.id);
+							doh.t(textBox1.focusNode.dir === textBox1.textDir, "textDir != dir of - " + textBox1.id);
+
 							doh.is("ltr", textBox2.textDir, "textDir of - " + textBox2.id);
-							doh.is("ltr", textBox2.dir, "dir of - " + textBox2.id);
-							doh.t(textBox2.focusNode.dir != textBox2.textDir, "textDir != dir of - " + textBox2.id);
+							doh.is("", textBox2.dir, "dir of - " + textBox2.id);
+							doh.t(textBox2.focusNode.dir === textBox2.textDir, "textDir != dir of - " + textBox2.id);
 
 							doh.is("rtl", textBox3.textDir, "textDir of - " + textBox3.id);
 							doh.is("rtl", textBox3.dir, "dir of - " + textBox3.id);
-							doh.t(textBox3.focusNode.dir != textBox3.textDir, "textDir != dir of - " + textBox3.id);
+							doh.t(textBox3.focusNode.dir === textBox3.textDir, "textDir != dir of - " + textBox3.id);
 
 							doh.is("ltr", textBox4.textDir, "textDir of - " + textBox4.id);
 							doh.is("rtl", textBox4.dir, "dir of - " + textBox4.id);
-							doh.t(textBox4.focusNode.dir != textBox4.textDir, "textDir != dir of - " + textBox4.id);
+							doh.t(textBox4.focusNode.dir === textBox4.textDir, "textDir != dir of - " + textBox4.id);
 						}
 					},
 					{
-						name:"Group 4",
+						name: "Group 4",
+
+						runTest: function(){
 
-						runTest:function(){
+							var textBox1 = registry.byId("curren_1"),
+								textBox2 = registry.byId("curren_12"),
+								textBox3 = registry.byId("curren_2"),
+								textBox4 = registry.byId("curren_22");
 
-							var textBox1 = dijit.byId("curren_1"),
-								textBox2 = dijit.byId("curren_12"),
-								textBox3 = dijit.byId("curren_2"),
-								textBox4 = dijit.byId("curren_22");
-								
 							doh.is("rtl", textBox1.textDir, "textDir of - " + textBox1.id);
-							doh.is("ltr", textBox1.dir, "dir of - " + textBox1.id);
-							doh.t(textBox1.focusNode.dir != textBox1.textDir, "textDir != dir of - " + textBox1.id);
-																		
+							doh.is("", textBox1.dir, "dir of - " + textBox1.id);
+							doh.t(textBox1.focusNode.dir === textBox1.textDir, "textDir != dir of - " + textBox1.id);
+
 							doh.is("ltr", textBox2.textDir, "textDir of - " + textBox2.id);
-							doh.is("ltr", textBox2.dir, "dir of - " + textBox2.id);
-							doh.t(textBox2.focusNode.dir != textBox2.textDir, "textDir != dir of - " + textBox2.id);
+							doh.is("", textBox2.dir, "dir of - " + textBox2.id);
+							doh.t(textBox2.focusNode.dir === textBox2.textDir, "textDir != dir of - " + textBox2.id);
 
 							doh.is("rtl", textBox3.textDir, "textDir of - " + textBox3.id);
 							doh.is("rtl", textBox3.dir, "dir of - " + textBox3.id);
-							doh.t(textBox3.focusNode.dir != textBox3.textDir, "textDir != dir of - " + textBox3.id);
+							doh.t(textBox3.focusNode.dir === textBox3.textDir, "textDir != dir of - " + textBox3.id);
 
 							doh.is("ltr", textBox4.textDir, "textDir of - " + textBox4.id);
 							doh.is("rtl", textBox4.dir, "dir of - " + textBox4.id);
-							doh.t(textBox4.focusNode.dir != textBox4.textDir, "textDir != dir of - " + textBox4.id);
+							doh.t(textBox4.focusNode.dir === textBox4.textDir, "textDir != dir of - " + textBox4.id);
 						}
 					},
 					{
-						name:"Group 5",
-
-						runTest:function(){
-	
-							var textBox1 = dijit.byId("q1"),
-								textBox2 = dijit.byId("q2"),
-								textBox3 = dijit.byId("q3"),
-								textBox4 = dijit.byId("q4");
-	
+						name: "Group 5",
+
+						runTest: function(){
+
+							var textBox1 = registry.byId("q1"),
+								textBox2 = registry.byId("q2"),
+								textBox3 = registry.byId("q3"),
+								textBox4 = registry.byId("q4");
+
 							doh.is("rtl", textBox1.textDir, "textDir of - " + textBox1.id);
 							doh.is("ltr", textBox1.dir, "dir of - " + textBox1.id);
-							doh.t(textBox1.focusNode.dir != textBox1.textDir, "textDir != dir of - " + textBox1.id);
-																		
+							doh.t(textBox1.focusNode.dir === textBox1.textDir, "textDir != dir of - " + textBox1.id);
+
 							doh.is("ltr", textBox2.textDir, "textDir of - " + textBox2.id);
 							doh.is("ltr", textBox2.dir, "dir of - " + textBox2.id);
-							doh.t(textBox2.focusNode.dir != textBox2.textDir, "textDir != dir of - " + textBox2.id);
+							doh.t(textBox2.focusNode.dir === textBox2.textDir, "textDir != dir of - " + textBox2.id);
 
 							doh.is("rtl", textBox3.textDir, "textDir of - " + textBox3.id);
 							doh.is("rtl", textBox3.dir, "dir of - " + textBox3.id);
-							doh.t(textBox3.focusNode.dir != textBox3.textDir, "textDir != dir of - " + textBox3.id);
+							doh.t(textBox3.focusNode.dir === textBox3.textDir, "textDir != dir of - " + textBox3.id);
 
 							doh.is("ltr", textBox4.textDir, "textDir of - " + textBox4.id);
 							doh.is("rtl", textBox4.dir, "dir of - " + textBox4.id);
-							doh.t(textBox4.focusNode.dir != textBox4.textDir, "textDir != dir of - " + textBox4.id);
+							doh.t(textBox4.focusNode.dir === textBox4.textDir, "textDir != dir of - " + textBox4.id);
 						}
 					}
-				]);			
+				]);
 
 				doh.run();
 			});
@@ -177,7 +172,6 @@
 	</head>
 
 	<body class="tundra">
-		<h2 class="testTitle"><b>As you can see, for the following widgets, the textDir is disabled, it's overridden by dijit.form.RangeBoundTextBox</b></h2>
 		<h1 class="testTitle">Test DateTextBox Widget with _BidiSupport</h1>
 		<div class="dojoTitlePaneLabel">
 			<label for="local_1">Group 1: Date (local format) </label>
@@ -187,25 +181,25 @@
 				<tr>
 					<th>
 						<label for="local_1"><b>dir = </b>ltr, <b>textDir = </b>rtl</label><br>
-						<input id="local_1" data-dojo-type="dijit.form.DateTextBox"
-							data-dojo-props='name:"noDOMvalue", value:"2008-12-31", type:"text"'/>
+						<input id="local_1" data-dojo-type="dijit/form/DateTextBox"
+							data-dojo-props='name: "noDOMvalue", value: "2008-12-31", type: "text", textDir: "rtl"'/>
 					</th>
 					<th>
 						<label for="local_12"><b>dir = </b>ltr, <b>textDir = </b>ltr</label><br>
-						<input id="local_12" data-dojo-type="dijit.form.DateTextBox"
-							data-dojo-props='name:"noDOMvalue12", value:"2008-12-31", type:"text", textDir:"ltr"'/>	
+						<input id="local_12" data-dojo-type="dijit/form/DateTextBox"
+							data-dojo-props='name: "noDOMvalue12", value: "2008-12-31", type: "text", textDir: "ltr"'/>
 					</th>
 				</tr>
 				<tr>
 					<th>
 						<label for="local_2"><b>dir = </b>rtl, <b>textDir = </b>rtl</label><br>
-						<input id="local_2" data-dojo-type="dijit.form.DateTextBox"
-							data-dojo-props='name:"noDOMvalue2", value:"2008-12-31", type:"text", dir:"rtl"'/>	
+						<input id="local_2" data-dojo-type="dijit/form/DateTextBox"
+							data-dojo-props='name: "noDOMvalue2", value: "2008-12-31", type: "text", dir: "rtl", textDir: "rtl"'/>
 					</th>
 					<th>
 						<label for="local_22"><b>dir = </b>rtl, <b>textDir = </b>ltr</label><br>
-						<input id="local_22" data-dojo-type="dijit.form.DateTextBox"
-							data-dojo-props='name:"noDOMvalue22", value:"2008-12-31", type:"text", dir:"rtl", textDir:"ltr"'/>	
+						<input id="local_22" data-dojo-type="dijit/form/DateTextBox"
+							data-dojo-props='name: "noDOMvalue22", value: "2008-12-31", type: "text", dir: "rtl", textDir: "ltr"'/>
 					</th>
 				</tr>
 			</table>
@@ -218,50 +212,52 @@
 				<tr>
 					<th>
 						<label for="localLong_1"><b>dir = </b>ltr, <b>textDir = </b>rtl</label><br>
-						<input id="localLong_1" data-dojo-id="localLong_1" data-dojo-type="dijit.form.DateTextBox"
-							data-dojo-props='type:"text", name:"date1", value:"2005-12-30",
-							constraints:{min:"2004-01-01",max:"2006-12-31",formatLength:"long"},
-							required:true,
-							trim:true,
-							invalidMessage:"Invalid date."'/>
+						<input id="localLong_1" data-dojo-id="localLong_1" data-dojo-type="dijit/form/DateTextBox"
+							data-dojo-props='type: "text", name: "date1", value: "2005-12-30",
+							constraints: {min: "2004-01-01", max: "2006-12-31", formatLength: "long"},
+							required: true,
+							trim: true,
+							dir: "ltr", textDir: "rtl",
+							invalidMessage: "Invalid date."'/>
 					</th>
 					<th>
 						<label for="localLong_12"><b>dir = </b>ltr, <b>textDir = </b>ltr</label><br>
-						<input id="localLong_12" data-dojo-id="localLong_12" data-dojo-type="dijit.form.DateTextBox"
-							data-dojo-props='type:"text", name:"date12", value:"2005-12-30",
-							constraints:{min:"2004-01-01",max:"2006-12-31",formatLength:"long"},
-							required:true,
-							trim:true,
-							invalidMessage:"Invalid date." ,
-							textDir:"ltr"'/>
+						<input id="localLong_12" data-dojo-id="localLong_12" data-dojo-type="dijit/form/DateTextBox"
+							data-dojo-props='type: "text", name: "date12", value: "2005-12-30",
+							constraints: {min: "2004-01-01", max: "2006-12-31", formatLength: "long"},
+							required: true,
+							trim: true,
+							invalidMessage: "Invalid date." ,
+							textDir: "ltr"'/>
 					</th>
-				</tr>							
+				</tr>
 				<tr>
-					<th>		
+					<th>
 						<label for="localLong_2"><b>dir = </b>rtl, <b>textDir = </b>rtl</label><br>
-						<input id="localLong_2" data-dojo-id="localLong_2" data-dojo-type="dijit.form.DateTextBox"
-							data-dojo-props='type:"text", name:"date2", value:"2005-12-30",
-							constraints:{min:"2004-01-01",max:"2006-12-31",formatLength:"long"},
-							required:true,
-							trim:true,
-							invalidMessage:"Invalid date." ,
-							dir:"rtl"'/>
+						<input id="localLong_2" data-dojo-id="localLong_2" data-dojo-type="dijit/form/DateTextBox"
+							data-dojo-props='type: "text", name: "date2", value: "2005-12-30",
+							constraints: {min: "2004-01-01",max: "2006-12-31",formatLength: "long"},
+							required: true,
+							trim: true,
+							invalidMessage: "Invalid date." ,
+							dir: "rtl",
+							textDir: "rtl" '/>
 					</th>
-					<th>							
+					<th>
 						<label for="localLong_22"><b>dir = </b>rtl, <b>textDir = </b>ltr</label><br>
-						<input id="localLong_22" data-dojo-id="localLong_12" data-dojo-type="dijit.form.DateTextBox"
-							data-dojo-props='type:"text", name:"date12", value:"2005-12-30",
-							constraints:{min:"2004-01-01",max:"2006-12-31",formatLength:"long"},
-							required:true,
-							trim:true,
-							invalidMessage:"Invalid date." ,
-							dir:"rtl",
-							textDir:"ltr"'/>
+						<input id="localLong_22" data-dojo-id="localLong_12" data-dojo-type="dijit/form/DateTextBox"
+							data-dojo-props='type: "text", name: "date12", value: "2005-12-30",
+							constraints: {min: "2004-01-01",max: "2006-12-31",formatLength: "long"},
+							required: true,
+							trim: true,
+							invalidMessage: "Invalid date." ,
+							dir: "rtl",
+							textDir: "ltr"'/>
 					</th>
 				</tr>
 			</table>
 		</div>
-	
+
 		<br>
 		<h1 class="testTitle">Test NumberSpinner Widget with _BidiSupport</h1>
 		<div class="dojoTitlePaneLabel">
@@ -273,51 +269,52 @@
 		<div class="testExample">
 			<table>
 				<tr>
-					<th>			
+					<th>
 						<label for="integerspinner_1"><b>dir = </b>ltr, <b>textDir = </b>rtl </label><br>
-						<input id="integerspinner_1" data-dojo-type="dijit.form.NumberSpinner"
+						<input id="integerspinner_1" data-dojo-type="dijit/form/NumberSpinner"
 							data-dojo-props='
-							value:900,
-							"class":"bigFont",
-							constraints:{max:1550,places:0},
-							name:"integerspinner_1",
-							textDir:"rtl"'/>
+							value: 900,
+							"class": "bigFont",
+							constraints: {max: 1550,places: 0},
+							name: "integerspinner_1",
+							textDir: "rtl"'/>
 					</th>
 					<th>
 						<label for="integerspinner_12"><b>dir = </b>ltr, <b>textDir = </b>ltr </label><br>
-						<input id="integerspinner_12" data-dojo-type="dijit.form.NumberSpinner"
+						<input id="integerspinner_12" data-dojo-type="dijit/form/NumberSpinner"
 							data-dojo-props='
-							value:900,
-							"class":"bigFont",
-							constraints:{max:1550,places:0},
-							name:"integerspinner_12",
-							textDir:"ltr"'/>
+							value: 900,
+							"class": "bigFont",
+							constraints: {max: 1550,places: 0},
+							name: "integerspinner_12",
+							textDir: "ltr"'/>
 					</th>
-				</tr>							
+				</tr>
 				<tr>
-					<th>		
+					<th>
 						<label for="integerspinner_2"><b>dir = </b>rtl, <b>textDir = </b>rtl </label><br>
-						<input id="integerspinner_2" data-dojo-type="dijit.form.NumberSpinner"
+						<input id="integerspinner_2" data-dojo-type="dijit/form/NumberSpinner"
 							data-dojo-props='
-							value:900,
-							"class":"bigFont",
-							constraints:{max:1550,places:0},
-							dir:"rtl",
-							name:"integerspinner_2"'/>
+							value: 900,
+							"class": "bigFont",
+							constraints: {max: 1550,places: 0},
+							dir: "rtl",
+							textDir: "rtl",
+							name: "integerspinner_2"'/>
 					</th>
-					<th>	
+					<th>
 						<label for="integerspinner_22"><b>dir = </b>rtl, <b>textDir = </b>ltr </label><br>
-						<input id="integerspinner_22" data-dojo-type="dijit.form.NumberSpinner"
+						<input id="integerspinner_22" data-dojo-type="dijit/form/NumberSpinner"
 							data-dojo-props='
-							value:900,
-							"class":"bigFont",
-							constraints:{max:1550,places:0},
-							dir:"rtl",
-							textDir:"ltr",
-							name:"integerspinner_22"'/>						
+							value: 900,
+							"class": "bigFont",
+							constraints: {max: 1550,places: 0},
+							dir: "rtl",
+							textDir: "ltr",
+							name: "integerspinner_22"'/>
 					</th>
 				</tr>
-			</table>					
+			</table>
 		</div>
 
 		<br>
@@ -332,51 +329,52 @@
 				<tr>
 					<th>
 						<label for="curren_1"><b>dir = </b>ltr, <b>textDir = </b>rtl </label><br>
-						<input id="curren_1" data-dojo-type="dijit.form.CurrencyTextBox"
-							data-dojo-props='name:"curren_1", "class":"medium", value:54775.53,
-							required:true,
-							constraints:{fractional:true},
-							currency:"USD",
-							invalidMessage:"Invalid amount. Cents are MANDATORY."'/>
-					</th> 
+						<input id="curren_1" data-dojo-type="dijit/form/CurrencyTextBox"
+							data-dojo-props='name: "curren_1", "class": "medium", value: 54775.53,
+							required: true,
+							constraints: {fractional: true},
+							currency: "USD",
+							textDir: "rtl",
+							invalidMessage: "Invalid amount. Cents are MANDATORY."'/>
+					</th>
 					<th>
 						<label for="curren_12"><b>dir = </b>ltr, <b>textDir = </b>ltr</label><br>
-						<input id="curren_12" data-dojo-type="dijit.form.CurrencyTextBox"
-							data-dojo-props='name:"curren_12", "class":"medium", value:54775.53,
-							required:true,
-							constraints:{fractional:true},
-							currency:"USD",
-							invalidMessage:"Invalid amount. Cents are MANDATORY.",
-							textDir:"ltr"'/>
+						<input id="curren_12" data-dojo-type="dijit/form/CurrencyTextBox"
+							data-dojo-props='name: "curren_12", "class": "medium", value: 54775.53,
+							required: true,
+							constraints: {fractional: true},
+							currency: "USD",
+							invalidMessage: "Invalid amount. Cents are MANDATORY.",
+							textDir: "ltr"'/>
 					</th>
 				</tr>
 				<tr>
 					<th>
-						<label for="curren_2"><b>dir = </b>rtl, <b>textDir = </b>rtl </label><br>	
-						<input id="curren_2" data-dojo-type="dijit.form.CurrencyTextBox"
-							data-dojo-props='name:"curren_2", "class":"medium", value:54775.53,
-								required:true,
-								constraints:{fractional:true},
-								currency:"USD",
-								invalidMessage:"Invalid amount. Cents are MANDATORY.",
-								textDir:"rtl",
-								dir:"rtl"'/>
+						<label for="curren_2"><b>dir = </b>rtl, <b>textDir = </b>rtl </label><br>
+						<input id="curren_2" data-dojo-type="dijit/form/CurrencyTextBox"
+							data-dojo-props='name: "curren_2", "class": "medium", value: 54775.53,
+								required: true,
+								constraints: {fractional: true},
+								currency: "USD",
+								invalidMessage: "Invalid amount. Cents are MANDATORY.",
+								textDir: "rtl",
+								dir: "rtl"'/>
 					</th>
 					<th>
-						<label for="curren_22"><b>dir = </b>rtl, <b>textDir = </b>ltr </label><br>	
-						<input id="curren_22" data-dojo-type="dijit.form.CurrencyTextBox"
-								data-dojo-props='name:"curren_22", "class":"medium", value:54775.53,
-								required:true,
-								constraints:{fractional:true},
-								currency:"USD",
-								invalidMessage:"Invalid amount. Cents are MANDATORY.",
-								textDir:"ltr",
-								dir:"rtl"'/>
+						<label for="curren_22"><b>dir = </b>rtl, <b>textDir = </b>ltr </label><br>
+						<input id="curren_22" data-dojo-type="dijit/form/CurrencyTextBox"
+								data-dojo-props='name: "curren_22", "class": "medium", value: 54775.53,
+								required: true,
+								constraints: {fractional: true},
+								currency: "USD",
+								invalidMessage: "Invalid amount. Cents are MANDATORY.",
+								textDir: "ltr",
+								dir: "rtl"'/>
 					</th>
 				</tr>
 			</table>
 		</div>
-	
+
 		<h1 class="testTitle">Test TimeTextBox Widget with _BidiSupport</h1>
 		<div class="dojoTitlePaneLabel">
 			<label >Group 5 </label>
@@ -386,45 +384,45 @@
 				<tr>
 					<th>
 						<label for="q1"><b>dir = </b>ltr, <b>textDir = </b>rtl </label><br>
-						<input id="q1" data-dojo-type="dijit.form.TimeTextBox"
-							data-dojo-props='type:"text", name:"time1", value:"T17:45:00",
-							constraints:{formatLength:"medium"},
-							required:true,
-							invalidMessage:"Invalid time.",
-							textDir:"rtl",
-							dir:"ltr"'/>					
+						<input id="q1" data-dojo-type="dijit/form/TimeTextBox"
+							data-dojo-props='type: "text", name: "time1", value: "T17:45:00",
+							constraints: {formatLength: "medium"},
+							required: true,
+							invalidMessage: "Invalid time.",
+							textDir: "rtl",
+							dir: "ltr"'/>
 					</th>
 					<th>
 						<label for="q2"><b>dir = </b>ltr, <b>textDir = </b>ltr</label><br>
-						<input id="q2" data-dojo-type="dijit.form.TimeTextBox"
-							data-dojo-props='type:"text", name:"time2", value:"T17:45:00",
-							constraints:{formatLength:"medium"},
-							required:true,
-							invalidMessage:"Invalid time.", 
-							textDir:"ltr",
-							dir:"ltr"'/>		
+						<input id="q2" data-dojo-type="dijit/form/TimeTextBox"
+							data-dojo-props='type: "text", name: "time2", value: "T17: 45: 00",
+							constraints: {formatLength: "medium"},
+							required: true,
+							invalidMessage: "Invalid time.",
+							textDir: "ltr",
+							dir: "ltr"'/>
 					</th>
 				</tr>
 				<tr>
 					<th>
-						<label for="q3"><b>dir = </b>rtl, <b>textDir = </b>rtl </label><br>	
-						<input id="q3" data-dojo-type="dijit.form.TimeTextBox"
-							data-dojo-props='type:"text", name:"time3", value:"T17:45:00",
-							constraints:{formatLength:"medium"},
-							required:true,
-							invalidMessage:"Invalid time.",
-							textDir:"rtl",
-							dir:"rtl"'/>		
+						<label for="q3"><b>dir = </b>rtl, <b>textDir = </b>rtl </label><br>
+						<input id="q3" data-dojo-type="dijit/form/TimeTextBox"
+							data-dojo-props='type: "text", name: "time3", value: "T17:45:00",
+							constraints: {formatLength: "medium"},
+							required: true,
+							invalidMessage: "Invalid time.",
+							textDir: "rtl",
+							dir: "rtl"'/>
 					</th>
 					<th>
-						<label for="q4"><b>dir = </b>rtl, <b>textDir = </b>ltr </label><br>	
-						<input id="q4" data-dojo-type="dijit.form.TimeTextBox"
-							data-dojo-props='type:"text", name:"time4", value:"T17:45:00",
-							constraints:{formatLength:"medium"},
-							required:true,
-							invalidMessage:"Invalid time.",
-							textDir:"ltr",
-							dir:"rtl"'/>		
+						<label for="q4"><b>dir = </b>rtl, <b>textDir = </b>ltr </label><br>
+						<input id="q4" data-dojo-type="dijit/form/TimeTextBox"
+							data-dojo-props='type: "text", name: "time4", value: "T17:45:00",
+							constraints: {formatLength: "medium"},
+							required: true,
+							invalidMessage: "Invalid time.",
+							textDir: "ltr",
+							dir: "rtl"'/>
 					</th>
 				</tr>
 			</table>
diff --git a/dijit/tests/_BidiSupport/form/robot/InlineEditBox.html b/dijit/tests/_BidiSupport/form/robot/InlineEditBox.html
index 99cb5ae..02e2c1f 100644
--- a/dijit/tests/_BidiSupport/form/robot/InlineEditBox.html
+++ b/dijit/tests/_BidiSupport/form/robot/InlineEditBox.html
@@ -4,45 +4,45 @@
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 		<title>doh.robot InlineEditBox textDir Tests</title>
-	
+
 		<style>
 			@import "../../../../../util/doh/robot/robot.css";
 		</style>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../../dojo/dojo.js">
-		</script>		
-			
+		</script>
+
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				doh.robot.initRobot('../test_InlineEditBox.html');
 				var textbox;
 				var inlineBox;
-				
+
 				function moveAndClick(node){
 					doh.robot.mouseMoveAt(node, 500, 1);
 					doh.robot.mouseClick({left: true}, 500);
 				}
-	
+
 				doh.register("InlineEditBox with TextBox", [
 					{
 						name: "write in English in 'ltrInlineEditBox'",
 						timeout: 10000,
-						
+
 						runTest: function(){
 							var d = new doh.Deferred();
-                            inlineBox = dijit.byId("P0");
+							inlineBox = dijit.byId("P0");
 							moveAndClick(inlineBox.domNode);
 							doh.robot.typeKeys("Hello!!!", 1000, 1200);
-								
+
 							doh.robot.sequence(d.getTestCallback(function(){
 								textBox = inlineBox.wrapperWidget.editWidget;
 								doh.is('ltr', textBox.get("textDir"), "direction of :" + inlineBox.id);
 								doh.is('ltr', textBox.focusNode.dir, "direction of :" + inlineBox.id);
 								inlineBox.save(true);
-							}), 800);							
+							}), 800);
 							return d;
 						}
 					},
@@ -52,72 +52,72 @@
 
 						runTest: function(){
 							var d = new doh.Deferred();
-                            inlineBox = dijit.byId("P1");
-						    moveAndClick(inlineBox.domNode);						
-						    doh.robot.setClipboard("\u05d5\u05e2\u05db\u05e9\u05d9\u05d5!",'text/html');
-                            var modifier = dojo.isMac ? {meta: true} : {ctrl: true};
+							inlineBox = dijit.byId("P1");
+							moveAndClick(inlineBox.domNode);
+							doh.robot.setClipboard("\u05d5\u05e2\u05db\u05e9\u05d9\u05d5!",'text/html');
+							var modifier = dojo.isMac ? {meta: true} : {ctrl: true};
 							doh.robot.keyPress("a", 400, modifier);
 							doh.robot.keyPress(dojo.keys.DELETE, 100, {});
-                            doh.robot.keyPress("v", 400, modifier);
-                            
+							doh.robot.keyPress("v", 400, modifier);
+
 							doh.robot.sequence(d.getTestCallback(function(){
-							    textBox = inlineBox.wrapperWidget.editWidget;
-							    doh.is('rtl', textBox.get("textDir"), "direction of :" + inlineBox.id);
-							    doh.is('rtl', textBox.focusNode.dir, "direction of :" + inlineBox.id);
-							    inlineBox.save(true);
-						    }), 800);					
+								textBox = inlineBox.wrapperWidget.editWidget;
+								doh.is('rtl', textBox.get("textDir"), "direction of :" + inlineBox.id);
+								doh.is('rtl', textBox.focusNode.dir, "direction of :" + inlineBox.id);
+								inlineBox.save(true);
+							}), 800);
 							return d;
 						}
 					},
-                    {
+					{
 						name: "initial text direction in 'autoInlineEditBox'",
 						timeout: 10000,
-						
+
 						runTest: function(){
-						    inlineBox = dijit.byId("P2");
-						    doh.is('ltr', inlineBox.displayNode.dir, "direction of :" + inlineBox.id);
-						}  
-						
-					},					
+							inlineBox = dijit.byId("P2");
+							doh.is('ltr', inlineBox.displayNode.dir, "direction of :" + inlineBox.id);
+						}
+
+					},
 					{
 						name: "change Value in 'autoInlineEditBox'",
 						timeout: 10000,
 
 						runTest: function(){
 							var d = new doh.Deferred();
-                            inlineBox = dijit.byId("P2");
-                          
-					        doh.robot.mouseMoveAt(function(){ return dojo.byId('button'); }, 500, 1000);
-						    doh.robot.mouseClick({left: true}, 500);
-						    moveAndClick(inlineBox.domNode);
+							inlineBox = dijit.byId("P2");
+
+							doh.robot.mouseMoveAt(function(){ return dojo.byId('button'); }, 500, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							moveAndClick(inlineBox.domNode);
 							doh.robot.sequence(d.getTestCallback(function(){
-							    textBox = inlineBox.wrapperWidget.editWidget;
-							    doh.is('auto', textBox.get("textDir"), "direction of :" + inlineBox.id);
-							    doh.is('rtl', textBox.focusNode.dir, "direction of :" + inlineBox.id);
-							    inlineBox.save(true);
-						    }), 800);					
+								textBox = inlineBox.wrapperWidget.editWidget;
+								doh.is('auto', textBox.get("textDir"), "direction of :" + inlineBox.id);
+								doh.is('rtl', textBox.focusNode.dir, "direction of :" + inlineBox.id);
+								inlineBox.save(true);
+							}), 800);
 							return d;
 						}
-					}				
-				]);				
-				
+					}
+				]);
+
 				doh.register("InlineEditBox with TextArea", [
 						{
 						name: "write in English in 'ltrInlineEditBox'",
 						timeout: 10000,
-						
+
 						runTest: function(){
 							var d = new doh.Deferred();
-                            inlineBox = dijit.byId("P3");
+							inlineBox = dijit.byId("P3");
 							moveAndClick(inlineBox.domNode);
 							doh.robot.typeKeys("Hello!!!", 1000, 1200);
-								
+
 							doh.robot.sequence(d.getTestCallback(function(){
 								textBox = inlineBox.wrapperWidget.editWidget;
 								doh.is('ltr', textBox.get("textDir"), "direction of :" + inlineBox.id);
 								doh.is('ltr', textBox.focusNode.dir, "direction of :" + inlineBox.id);
 								inlineBox.save(true);
-							}), 800);							
+							}), 800);
 							return d;
 						}
 					},
@@ -127,69 +127,69 @@
 
 						runTest: function(){
 							var d = new doh.Deferred();
-                            inlineBox = dijit.byId("P4");
-						    moveAndClick(inlineBox.domNode);						
-						    doh.robot.setClipboard("\u05d5\u05e2\u05db\u05e9\u05d9\u05d5!",'text/html');
-                            var modifier = dojo.isMac ? {meta: true} : {ctrl: true};
+							inlineBox = dijit.byId("P4");
+							moveAndClick(inlineBox.domNode);
+							doh.robot.setClipboard("\u05d5\u05e2\u05db\u05e9\u05d9\u05d5!",'text/html');
+							var modifier = dojo.isMac ? {meta: true} : {ctrl: true};
 							doh.robot.keyPress("a", 400, modifier);
 							doh.robot.keyPress(dojo.keys.DELETE, 100, {});
 							doh.robot.keyPress("v", 400, modifier);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-							    textBox = inlineBox.wrapperWidget.editWidget;
-							    doh.is('rtl', textBox.get("textDir"), "direction of :" + inlineBox.id);
-							    doh.is('rtl', textBox.focusNode.dir, "direction of :" + inlineBox.id);
-							    inlineBox.save(true);
-						    }), 800);					
+								textBox = inlineBox.wrapperWidget.editWidget;
+								doh.is('rtl', textBox.get("textDir"), "direction of :" + inlineBox.id);
+								doh.is('rtl', textBox.focusNode.dir, "direction of :" + inlineBox.id);
+								inlineBox.save(true);
+							}), 800);
 							return d;
 						}
 					},
-                    {
+					{
 						name: "initial text direction in 'autoInlineEditBox'",
 						timeout: 10000,
-						
+
 						runTest: function(){
-						    var inlineBox = dijit.byId("P5");
-						    doh.is('ltr', inlineBox.domNode.dir, "direction of :" + inlineBox.id);
-						}  
-						
-					},					
+							var inlineBox = dijit.byId("P5");
+							doh.is('ltr', inlineBox.domNode.dir, "direction of :" + inlineBox.id);
+						}
+
+					},
 					{
 						name: "change Value in 'autoInlineEditBox'",
 						timeout: 10000,
 
 						runTest: function(){
 							var d = new doh.Deferred();
-                            var inlineBox = dijit.byId("P5");
-						    doh.robot.mouseMoveAt(function(){ return dojo.byId('Button1'); }, 500, 1000);
+							var inlineBox = dijit.byId("P5");
+							doh.robot.mouseMoveAt(function(){ return dojo.byId('Button1'); }, 500, 1000);
 
-						    doh.robot.mouseClick({left: true}, 500);
-						    moveAndClick(inlineBox.domNode);
+							doh.robot.mouseClick({left: true}, 500);
+							moveAndClick(inlineBox.domNode);
 							doh.robot.sequence(d.getTestCallback(function(){
-							    textBox = inlineBox.wrapperWidget.editWidget;
-							    doh.is('auto', textBox.get("textDir"), "direction of :" + inlineBox.id);
-							    doh.is('rtl', textBox.focusNode.dir, "direction of :" + inlineBox.id);
-							    inlineBox.save(true);
-						    }), 800);					
+								textBox = inlineBox.wrapperWidget.editWidget;
+								doh.is('auto', textBox.get("textDir"), "direction of :" + inlineBox.id);
+								doh.is('rtl', textBox.focusNode.dir, "direction of :" + inlineBox.id);
+								inlineBox.save(true);
+							}), 800);
 							return d;
 						}
-					}					
-				]);	
-				
+					}
+				]);
+
 				doh.register("InlineEditBox with ComboBox", [
 						{
 						name: "test LTR ComboBox",
 						timeout: 10000,
-						
+
 						runTest: function(){
 							var d = new doh.Deferred();
-                            inlineBox = dijit.byId("combo1");
-                            moveAndClick(inlineBox.domNode);
+							inlineBox = dijit.byId("combo1");
+							moveAndClick(inlineBox.domNode);
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
 							doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
-						    doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
-						    doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
-								
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
+
 							doh.robot.sequence(d.getTestCallback(function(){
 								var combo = inlineBox.wrapperWidget.editWidget;
 								doh.is('ltr', combo.get("textDir"), "direction of :" + inlineBox.id);
@@ -199,7 +199,7 @@
 									}
 								});
 								inlineBox.save(true);
-							}), 900);							
+							}), 900);
 							return d;
 						}
 					},
@@ -208,55 +208,55 @@
 						timeout: 10000,
 
 						runTest: function(){
-						    var d = new doh.Deferred();
-                            inlineBox = dijit.byId("combo2");
-						    moveAndClick(inlineBox.domNode);
-						    doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
-						    doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
-						    doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
-						    doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
-								
-						    doh.robot.sequence(d.getTestCallback(function(){
-							    var combo = inlineBox.wrapperWidget.editWidget;
-							    doh.is('rtl', combo.get("textDir"), "direction of :" + inlineBox.id);
-							    dojo.forEach(combo.dropDown.domNode.childNodes, function(node){
-								    if(node.item){
-									    doh.is("rtl", node.dir, node.textContent);
-								    }
-							    });
-							    inlineBox.save(true);
-						    }), 900);						
+							var d = new doh.Deferred();
+							inlineBox = dijit.byId("combo2");
+							moveAndClick(inlineBox.domNode);
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var combo = inlineBox.wrapperWidget.editWidget;
+								doh.is('rtl', combo.get("textDir"), "direction of :" + inlineBox.id);
+								dojo.forEach(combo.dropDown.domNode.childNodes, function(node){
+									if(node.item){
+										doh.is("rtl", node.dir, node.textContent);
+									}
+								});
+								inlineBox.save(true);
+							}), 900);
 							return d;
 						}
 					},
-                    {
+					{
 						name: "test AUTO ComboBox",
 						timeout: 10000,
 
 						runTest: function(){
-							    var d = new doh.Deferred();
-                                inlineBox = dijit.byId("combo3");
-							    moveAndClick(inlineBox.domNode);
-							    doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
-							    doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
-							    doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
-							    doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
-    								
-							    doh.robot.sequence(d.getTestCallback(function(){
-								    var combo = inlineBox.wrapperWidget.editWidget;
-								    doh.is('auto', combo.get("textDir"), "direction of :" + inlineBox.id);
-								    dojo.forEach(combo.dropDown.domNode.childNodes, function(node){
-									    if(node.item){
-										    var contextualDir = combo.getTextDir(node.innerText || node.textContent || "");
-										    doh.is(contextualDir, node.dir, node.innerText || node.textContent || "");
-									    }	
-								    });
-								    inlineBox.save(true);
-							    }), 900);				
+								var d = new doh.Deferred();
+								inlineBox = dijit.byId("combo3");
+								moveAndClick(inlineBox.domNode);
+								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
+								doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
+								doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
+								doh.robot.keyPress(dojo.keys.UP_ARROW, 300);
+
+								doh.robot.sequence(d.getTestCallback(function(){
+									var combo = inlineBox.wrapperWidget.editWidget;
+									doh.is('auto', combo.get("textDir"), "direction of :" + inlineBox.id);
+									dojo.forEach(combo.dropDown.domNode.childNodes, function(node){
+										if(node.item){
+											var contextualDir = combo.getTextDir(node.innerText || node.textContent || "");
+											doh.is(contextualDir, node.dir, node.innerText || node.textContent || "");
+										}
+									});
+									inlineBox.save(true);
+								}), 900);
 							return d;
 						}
-					}					
-				]);	
+					}
+				]);
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/_BidiSupport/form/robot/SimpleComboBoxes.html b/dijit/tests/_BidiSupport/form/robot/SimpleComboBoxes.html
index 4a6e9c2..e04c2db 100644
--- a/dijit/tests/_BidiSupport/form/robot/SimpleComboBoxes.html
+++ b/dijit/tests/_BidiSupport/form/robot/SimpleComboBoxes.html
@@ -12,7 +12,7 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../../dojo/dojo.js">
 		</script>
-			
+
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
@@ -23,29 +23,38 @@
 
 				doh.register("Test LTR combo box", [
 					{
-						name:"check drop down items text direction.",
-						timeout:3000,
+						name: "check drop down items text direction.",
+						timeout: 6000,
 
 						setUp: function(){
 							combo = dijit.byId("fruitLtr");
+							doh.t(!!combo, "found fruitLtr");
 							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
 						},
-						
-						runTest:function(){
+
+						runTest: function(){
 							var d = new doh.Deferred();
+
 							// Open drop down
-							combo.focusNode.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								// delay is needed to work around IE bug
+								combo.focusNode.focus();
+							}), 50);
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 100);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								dojo.forEach(combo.dropDown.domNode.childNodes, function(node){
-									// so it will check only the options
-									if(node.item){
-										doh.is("ltr", node.dir, node.textContent);
-									}
-								});
-							}), 900);
-							
+
+							var handle = dojo.connect(combo, "openDropDown", function(){
+								handle.remove();
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.t(!!combo.dropDown, "dropdown exists");
+									dojo.forEach(combo.dropDown.domNode.childNodes, function(node){
+										// so it will check only the options
+										if(node.item){
+											doh.is("ltr", node.dir, node.textContent);
+										}
+									});
+								}), 50);
+							});
+
 							return d;
 						},
 
@@ -64,59 +73,64 @@
 							doh.robot.keyPress(dojo.keys.DELETE, 300, {});
 							doh.robot.typeKeys("Hi!!!", 1, 300);
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("ltr",combo.focusNode.dir,"direction of :" + combo.id);
-							}), 300);								
+								doh.is("ltr", combo.focusNode.dir,"direction of : " + combo.id);
+							}), 300);
 
 							return d;
 						}
-					},	
+					},
 					{
 						name: "paste Hebrew in 'fruitLtr'",
 						timeout: 3000,
 
 						runTest: function(){
 							var d = new doh.Deferred();
-							
+
 							doh.robot.setClipboard("\u05e9\u05dc\u05d5\u05dd\u0021",'text/html');
 							doh.robot.keyPress("a", 300, modifier);
 							doh.robot.keyPress(dojo.keys.DELETE, 300, {});
 							doh.robot.keyPress("v", 300, modifier);
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("ltr",combo.focusNode.dir,"direction of :" + combo.id);
-							}), 300);								
+								doh.is("ltr", combo.focusNode.dir,"direction of : " + combo.id);
+							}), 300);
 
 							return d;
 						}
 					}
-				]);			
-	
+				]);
+
 				doh.register("Test RTL combo box", [
 					{
-						name:"check drop down items text direction.",
-						timeout:3000,
+						name: "check drop down items text direction.",
+						timeout: 3000,
 
 						setUp: function(){
 							combo = dijit.byId("fruitRtl");
+							doh.t(!!combo, "found fruitRtl");
 						},
-						
-						runTest:function(){
+
+						runTest: function(){
 							var d = new doh.Deferred();
 							// Open drop down
 							combo.focusNode.focus();
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 100);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								dojo.forEach(combo.dropDown.domNode.childNodes, function(node){
-									// so it will check only the options
-									if(node.item){
-										doh.is("rtl", node.dir, node.textContent);
-									}
-								});
-							}), 900);
-							
+
+							var handle = dojo.connect(combo, "openDropDown", function(){
+								handle.remove();
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.t(!!combo.dropDown, "dropdown exists");
+									dojo.forEach(combo.dropDown.domNode.childNodes, function(node){
+										// so it will check only the options
+										if(node.item){
+											doh.is("rtl", node.dir, node.textContent);
+										}
+									});
+								}), 50);
+							});
+
 							return d;
 						},
-						
+
 						tearDown: function(){
 							combo.closeDropDown();
 						}
@@ -132,26 +146,26 @@
 							doh.robot.keyPress(dojo.keys.DELETE, 300, {});
 							doh.robot.typeKeys("Hi!!!", 1, 300);
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("rtl",combo.focusNode.dir,"direction of :" + combo.id);
-							}), 300);								
+								doh.is("rtl", combo.focusNode.dir,"direction of : " + combo.id);
+							}), 300);
 
 							return d;
 						}
-					},	
+					},
 					{
 						name: "paste Hebrew in 'fruitRtl'",
 						timeout: 3000,
 
 						runTest: function(){
 							var d = new doh.Deferred();
-							
+
 							doh.robot.setClipboard("\u05e9\u05dc\u05d5\u05dd\u0021",'text/html');
 							doh.robot.keyPress("a", 300, modifier);
 							doh.robot.keyPress(dojo.keys.DELETE, 300, {});
 							doh.robot.keyPress("v", 300, modifier);
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("rtl",combo.focusNode.dir,"direction of :" + combo.id);
-							}), 300);								
+								doh.is("rtl", combo.focusNode.dir,"direction of : " + combo.id);
+							}), 300);
 
 							return d;
 						}
@@ -160,30 +174,36 @@
 
 				doh.register("Test AUTO ComboBox", [
 					{
-						name:"check drop down items text direction.",
-						timeout:60000,
+						name: "check drop down items text direction.",
+						timeout: 60000,
 
-						setUp:function(){
+						setUp: function(){
 							combo = dijit.byId("fruitContextual");
+							doh.t(!!combo, "found fruitContextual");
 							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
 						},
-			
-						runTest:function(){
+
+						runTest: function(){
 							var d = new doh.Deferred();
-							var contextualDir;
+
 							// Create drop down
 							combo.focusNode.focus();
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 100);
-							doh.robot.sequence(d.getTestCallback(function(){
-								dojo.forEach(combo.dropDown.domNode.childNodes, function(node){
-									// so it will check only the options
-									if(node.item){
-										contextualDir = this.getTextDir(node.innerText || node.textContent || "");
-										doh.is(contextualDir, node.dir, node.innerText || node.textContent || "");
-									}	
-								},combo);
-							}), 900);
-							
+
+							var handle = dojo.connect(combo, "openDropDown", function(){
+								handle.remove();
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.t(!!combo.dropDown, "dropdown exists");
+									dojo.forEach(combo.dropDown.domNode.childNodes, function(node){
+										// so it will check only the options
+										if(node.item){
+											var contextualDir = this.getTextDir(node.innerText || node.textContent || "");
+											doh.is(contextualDir, node.dir, node.innerText || node.textContent || "");
+										}
+									}, combo);
+								}), 50);
+							});
+
 							return d;
 						},
 
@@ -192,48 +212,49 @@
 						}
 					},
 					{
-						name:"input field text direction for each item in the menu.",
-						timeout:6000,
+						name: "input field text direction for each item in the menu.",
+						timeout: 6000,
 
-						setUp:function(){
+						setUp: function(){
 							combo = dijit.byId("fruitContextual");
+							doh.t(!!combo, "found fruitContextual");
 							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
 						},
-			
-						runTest:function(){
+
+						runTest: function(){
 							var d = new doh.Deferred();
 
 							combo.focusNode.focus();
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 100);
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("ltr",combo.focusNode.dir, combo.id);
+								doh.is("ltr", combo.focusNode.dir, combo.id);
 							}), 200);
 
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("ltr",combo.focusNode.dir, combo.id);
+								doh.is("ltr", combo.focusNode.dir, combo.id);
 							}), 200);
 
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("ltr",combo.focusNode.dir, combo.id);
+								doh.is("ltr", combo.focusNode.dir, combo.id);
 							}), 200);
 
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("ltr",combo.focusNode.dir, combo.id);
+								doh.is("ltr", combo.focusNode.dir, combo.id);
 							}), 200);
 
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("rtl",combo.focusNode.dir, combo.id);
+								doh.is("rtl", combo.focusNode.dir, combo.id);
 							}), 200);
 
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("rtl",combo.focusNode.dir, combo.id);
+								doh.is("rtl", combo.focusNode.dir, combo.id);
 							}), 200);
-						
+
 							return d;
 						},
 
@@ -244,7 +265,7 @@
 					{
 						name: "text direction cut/paste English",
 						timeout: 3000,
-						
+
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -255,8 +276,8 @@
 
 							doh.robot.keyPress("v", 500, modifier);
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("ltr",combo.focusNode.dir,"direction of :" + combo.id);
-							}), 300);								
+								doh.is("ltr", combo.focusNode.dir,"direction of : " + combo.id);
+							}), 300);
 
 							return d;
 						}
@@ -264,24 +285,24 @@
 					{
 						name: "text direction cut/paste Hebrew before English",
 						timeout: 3000,
-						
+
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							doh.robot.setClipboard("\u05d0\u05e0\u05d9\u003a\u0020",'text/html');
 
-							dojo.isMac ? doh.robot.keyPress("a", 100, {ctrl:true}): doh.robot.keyPress(dojo.keys.HOME, 100, {});	
+							dojo.isMac ? doh.robot.keyPress("a", 100, {ctrl:true}): doh.robot.keyPress(dojo.keys.HOME, 100, {});
 
 							doh.robot.keyPress("v", 400, modifier);
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("rtl",combo.focusNode.dir,"direction of :" + combo.id);
-							}), 700);								
+								doh.is("rtl", combo.focusNode.dir,"direction of : " + combo.id);
+							}), 700);
 
 							return d;
 						}
 					}
 				]);
-				
+
 				doh.register("Test AUTO ComboBox", [
 					{
 						name: "test auto-completion popup and input field for 'auto'",
@@ -289,6 +310,7 @@
 
 						setUp: function(){
 							autoCompleted = dijit.byId("fruitContextualAC");
+							doh.t(!!autoCompleted, "found fruitContextualAC");
 						},
 
 						runTest: function(){
@@ -309,9 +331,9 @@
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("rtl",autoCompleted.focusNode.dir, "input field of fruitContextualAC");
+								doh.is("rtl", autoCompleted.focusNode.dir, "input field of fruitContextualAC");
 							}), 200);
-							
+
 							doh.robot.sequence(function(){ autoCompleted.set("value", null); }, 400);
 							doh.robot.keyPress("@", 100);
 
@@ -339,6 +361,7 @@
 
 						setUp: function(){
 							notAutoCompleted = dijit.byId("fruitContextual");
+							doh.t(!!notAutoCompleted, "found fruitContextual");
 						},
 
 						runTest: function(){
@@ -359,16 +382,16 @@
 
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("ltr",notAutoCompleted.focusNode.dir, "input field of fruitContextual - :");
+								doh.is("ltr", notAutoCompleted.focusNode.dir, "input field of fruitContextual - :");
 							}), 200);
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("rtl",notAutoCompleted.focusNode.dir, "input field of fruitContextual - :");
+								doh.is("rtl", notAutoCompleted.focusNode.dir, "input field of fruitContextual - :");
 							}), 200);
 
-							// Filter drop down list to entries starting with "@"							
-							doh.robot.sequence(function(){ 
-								notAutoCompleted.set("value", null); 
+							// Filter drop down list to entries starting with "@"
+							doh.robot.sequence(function(){
+								notAutoCompleted.set("value", null);
 							}, 400);
 							doh.robot.keyPress("@", 100);
 
@@ -381,7 +404,7 @@
 
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("ltr",notAutoCompleted.focusNode.dir, "input field of fruitContextual - :");
+								doh.is("ltr", notAutoCompleted.focusNode.dir, "input field of fruitContextual - :");
 							}), 200);
 
 
@@ -398,15 +421,15 @@
 
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("rtl",notAutoCompleted.focusNode.dir, "input field of fruitContextual - :");
+								doh.is("rtl", notAutoCompleted.focusNode.dir, "input field of fruitContextual - :");
 							}), 200);
 
-							
+
 							return d;
 						}
 					}
 				]);
-				
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/_BidiSupport/form/robot/SimpleTextarea.html b/dijit/tests/_BidiSupport/form/robot/SimpleTextarea.html
index 50bc8b5..974fd31 100644
--- a/dijit/tests/_BidiSupport/form/robot/SimpleTextarea.html
+++ b/dijit/tests/_BidiSupport/form/robot/SimpleTextarea.html
@@ -4,22 +4,22 @@
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 		<title>doh.robot SimpleTextarea textDir Tests</title>
-	
+
 		<style>
 			@import "../../../../../util/doh/robot/robot.css";
 		</style>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../../dojo/dojo.js">
-		</script>		
-			
+		</script>
+
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_SimpleTextarea.html');
 				var textarea;
-				
+
 				var focusThenRun = function(widget, fcn){
 					if(!widget.focused){
 						var handler = widget.connect(widget, '_onFocus', function(){
@@ -35,7 +35,7 @@
 				doh.register("LTR textarea", [
 					{
 						name: "initial text direction of filled 'ltrSimpleTexarea'",
-					
+
 						setUp: function(){
 							textarea = dijit.byId("ltrSimpleTexarea");
 							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
@@ -47,8 +47,8 @@
 					},
 					{
 						name: "write in English in 'ltrSimpleTexarea'",
-						timeout: 2000,
-						
+						timeout: 4000,
+
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -57,18 +57,18 @@
 								doh.robot.keyPress(dojo.keys.DELETE, 100, {});
 
 								doh.robot.typeKeys("Hi this is my new value, and it's on English!!!", 1, 300);
-								
+
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
 								}), 800);
 							});
-							
+
 							return d;
 						}
 					},
 					{
 						name: "paste Hebrew in 'ltrSimpleTexarea'",
-						timeout: 2000,
+						timeout: 4000,
 
 						setUp: function(){
 							textarea = dijit.byId("ltrSimpleTexarea");
@@ -76,7 +76,7 @@
 
 						runTest: function(){
 							var d = new doh.Deferred();
-							
+
 							focusThenRun(textarea, function(){
 								doh.robot.setClipboard("\u05d5\u05e2\u05db\u05e9\u05d9\u05d5\u0020\u05e7\u05e6\u05ea\u0020\u05d8\u05e7\u05e1\u05d8\u0020\u05d1\u05e2\u05d9\u05d1\u05e8\u05d9\u05ea\u0021\u0021\u0021\u000a\u05d0\u05e4\u05d9\u05dc\u05d5\u0020\u05e0\u05db\u05ea\u05d5\u05d1\u0020\u05e9\u05d5\u05e8\u05d4\u0020\u05e9\u05e0\u05d9\u05d9\u05d4\u002e\u0020\u0020\u0020",'text/html');
 
@@ -92,12 +92,12 @@
 							return d;
 						}
 					}
-				]);				
-				
+				]);
+
 				doh.register("RTL textarea", [
 					{
 						name: "initial text direction of filled 'rtlSimpleTexarea'",
-					
+
 						setUp: function(){
 							textarea = dijit.byId("rtlSimpleTexarea");
 						},
@@ -108,8 +108,8 @@
 					},
 					{
 						name: "write in English in 'rtlSimpleTexarea'",
-						timeout: 2000,
-						
+						timeout: 4000,
+
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -118,18 +118,18 @@
 								doh.robot.keyPress(dojo.keys.DELETE, 100, {});
 
 								doh.robot.typeKeys("Hi this is my new value, and it's on English!!!", 1, 300);
-								
+
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("rtl",textarea.focusNode.dir,"direction of :" + textarea.id);
 								}), 800);
 							});
-						
+
 							return d;
 						}
 					},
 					{
 						name: "paste Hebrew in 'rtlSimpleTexarea'",
-						timeout: 2000,
+						timeout: 4000,
 
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -148,12 +148,12 @@
 							return d;
 						}
 					}
-				]);	
+				]);
 
 				doh.register("Contextual textarea", [
 					{
 						name: "initial text direction of filled 'contextualSimpleTexarea'",
-					
+
 						setUp: function(){
 							textarea = dijit.byId("contextualSimpleTexarea");
 						},
@@ -164,22 +164,22 @@
 					},
 					{
 						name: "write in English in 'contextualSimpleTexarea'",
-						timeout: 2000,
-						
+						timeout: 4000,
+
 						runTest: function(){
 							var d = new doh.Deferred();
-							
+
 							focusThenRun(textarea, function(){
 								doh.robot.keyPress("a", 400, modifier);
 								doh.robot.keyPress(dojo.keys.DELETE, 100, {});
 
 								doh.robot.typeKeys("Hi this is my new value, and it's on English!!!", 1, 400);
-								
+
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
 								}), 500);
 							});
-							
+
 							return d;
 						}
 					},
@@ -195,7 +195,7 @@
 							focusThenRun(textarea, function(){
 								doh.robot.setClipboard("\u05d0\u05e0\u05d9\u0020\u05d0\u05d5\u05de\u05e8\u05ea\u003a\u0020");
 
-								dojo.isMac ? doh.robot.keyPress("a", 100, {ctrl:true}): doh.robot.keyPress(dojo.keys.HOME, 100, {});	
+								dojo.isMac ? doh.robot.keyPress("a", 100, {ctrl:true}): doh.robot.keyPress(dojo.keys.HOME, 100, {});
 
 								doh.robot.keyPress("v", 400, modifier);
 								doh.robot.sequence(d.getTestCallback(function(){
@@ -211,7 +211,7 @@
 				doh.register("programmaticAuto textarea in the border container", [
 					{
 						name: "initial text direction of filled 'programmaticAuto'",
-					
+
 						setUp: function(){
 							textarea = dijit.byId("programmaticAuto");
 							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
@@ -223,8 +223,8 @@
 					},
 					{
 						name: "write in English in 'programmaticAuto'",
-						timeout: 2000,
-						
+						timeout: 4000,
+
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -233,22 +233,22 @@
 								doh.robot.keyPress(dojo.keys.DELETE, 100, {});
 
 								doh.robot.typeKeys("Hi this is my new value, and it's on English!!!", 1, 300);
-								
+
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
 								}), 800);
 							});
-							
+
 							return d;
 						}
 					},
 					{
 						name: "paste Hebrew in 'programmaticAuto'",
-						timeout: 2000,
+						timeout: 4000,
 
 						runTest: function(){
 							var d = new doh.Deferred();
-							
+
 							focusThenRun(textarea, function(){
 								doh.robot.setClipboard("\u05d5\u05e2\u05db\u05e9\u05d9\u05d5\u0020\u05e7\u05e6\u05ea\u0020\u05d8\u05e7\u05e1\u05d8\u0020\u05d1\u05e2\u05d9\u05d1\u05e8\u05d9\u05ea\u0021\u0021\u0021\u000a\u05d0\u05e4\u05d9\u05dc\u05d5\u0020\u05e0\u05db\u05ea\u05d5\u05d1\u0020\u05e9\u05d5\u05e8\u05d4\u0020\u05e9\u05e0\u05d9\u05d9\u05d4\u002e\u0020\u0020\u0020",'text/html');
 
@@ -264,12 +264,12 @@
 							return d;
 						}
 					}
-				]);				
-				
+				]);
+
 				doh.register("programmaticRTL textarea in the border container", [
 					{
 						name: "initial text direction of filled 'programmaticRTL'",
-					
+
 						setUp: function(){
 							textarea = dijit.byId("programmaticRTL");
 						},
@@ -280,8 +280,8 @@
 					},
 					{
 						name: "write in English in 'programmaticRTL'",
-						timeout: 2000,
-						
+						timeout: 4000,
+
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -290,18 +290,18 @@
 								doh.robot.keyPress(dojo.keys.DELETE, 100, {});
 
 								doh.robot.typeKeys("Hi this is my new value, and it's on English!!!", 1, 300);
-								
+
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("rtl",textarea.focusNode.dir,"direction of :" + textarea.id);
 								}), 800);
 							});
-						
+
 							return d;
 						}
 					},
 					{
 						name: "paste Hebrew in 'programmaticRTL'",
-						timeout: 2000,
+						timeout: 4000,
 
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -320,12 +320,12 @@
 							return d;
 						}
 					}
-				]);	
+				]);
 
 				doh.register("programmaticLTR textarea in the border container", [
 					{
 						name: "initial text direction of filled 'programmaticLTR'",
-					
+
 						setUp: function(){
 							textarea = dijit.byId("programmaticLTR");
 						},
@@ -336,22 +336,22 @@
 					},
 					{
 						name: "write in English in 'programmaticLTR'",
-						timeout: 2000,
-						
+						timeout: 4000,
+
 						runTest: function(){
 							var d = new doh.Deferred();
-							
+
 							focusThenRun(textarea, function(){
 								doh.robot.keyPress("a", 400, modifier);
 								doh.robot.keyPress(dojo.keys.DELETE, 100, {});
 
 								doh.robot.typeKeys("Hi this is my new value, and it's on English!!!", 1, 400);
-								
+
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
 								}), 500);
 							});
-							
+
 							return d;
 						}
 					},
@@ -373,13 +373,13 @@
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
 								}), 800);
-								
+
 							});
 
 							return d;
 						}
 					}
-				]);				
+				]);
 
 				doh.run();
 			});
diff --git a/dijit/tests/_BidiSupport/form/robot/TextBoxes.html b/dijit/tests/_BidiSupport/form/robot/TextBoxes.html
index 7253c5a..f86c39d 100644
--- a/dijit/tests/_BidiSupport/form/robot/TextBoxes.html
+++ b/dijit/tests/_BidiSupport/form/robot/TextBoxes.html
@@ -4,7 +4,7 @@
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 		<title>doh.robot TextBox textDir Tests</title>
-	
+
 		<title>doh.robot Bidi Test</title>
 
 		<style>
@@ -14,13 +14,13 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../../dojo/dojo.js">
 		</script>
-			
+
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_TextBoxes.html');
-				
+
 				// execute some test as soon as the widget gets focus
 				var focusThenRun = function(widget, fcn){
 					if(!widget.focused){
@@ -33,31 +33,31 @@
 						fcn();
 					}
 				};
+				var pos, range, textBox, modifier = dojo.isMac ? {meta: true} : {ctrl: true};
 
 				doh.register("LTR textBox", [
 					{
 						name: "initial text direction of empty 'ltrTextBox'",
-						
+
 						setUp: function(){
 							textBox = dijit.byId("ltrTextBox");
-							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
 						},
 
 						runTest: function(){
 							doh.is("ltr",textBox.focusNode.dir,"direction of :" + textBox.id);
 						}
-					},				
+					},
 					{
 						name: "write in English in 'ltrTextBox'",
 						timeout: 3000,
-						
+
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							focusThenRun(textBox, function(){
-								doh.robot.typeKeys('Hello!', 1, 300);
+								doh.robot.typeKeys('Hello', 1, 300);
 								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is("ltr",textBox.focusNode.dir,"direction of :" + textBox.id);
+									doh.is("ltr",textBox.focusNode.dir, "direction of :" + textBox.id);
 								}), 400);
 							});
 
@@ -66,34 +66,45 @@
 					},
 					{
 						name: "paste Hebrew in 'ltrTextBox'",
-						timeout: 2000,
+						timeout: 5000,
 
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							focusThenRun(textBox, function(){
 								doh.robot.setClipboard("\u05e9\u05dc\u05d5\u05dd\u0021",'text/html');
-
 								doh.robot.keyPress("a", 400, modifier);
-								doh.robot.keyPress(dojo.keys.DELETE, 100, {});
-
 								doh.robot.keyPress("v", 300, modifier);
+								// select text from the left side of the textbox
+								doh.robot.mouseMoveAt(textBox.focusNode, 500, 1, 5, textBox.focusNode.offsetHeight >> 1);
+								doh.robot.mousePress({left:true}, 500);
+								doh.robot.mouseMoveAt(textBox.focusNode, 500, 1000, 20, textBox.focusNode.offsetHeight >> 1);
+								doh.robot.mouseRelease({left:true}, 500);
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("ltr",textBox.focusNode.dir,"direction of :" + textBox.id);
+									// verify text was selected from the left side of the textbox
+									if(textBox.focusNode.selectionEnd){
+										doh.t(textBox.focusNode.selectionEnd > textBox.focusNode.selectionStart, "selected text " + textBox.focusNode.selectionStart + '. ' + textBox.focusNode.selectionEnd);
+									}else{
+										range = dojo.global.window.document.selection.createRange();
+										pos = range.getBoundingClientRect();
+										doh.t(pos.right > pos.left, "selected text " + pos.left + '. ' + pos.right);
+									}
 								}), 400);
 							});
 
 							return d;
 						}
 					}
-				]);				
-				
+				]);
+
 				doh.register("RTL textBox", [
 					{
 						name: "initial text direction of empty 'rtlTextBox'",
 
 						setUp: function(){
 							textBox = dijit.byId("rtlTextBox");
+							textBox.domNode.scrollIntoView();
 						},
 
 						runTest: function(){
@@ -102,24 +113,37 @@
 					},
 					{
 						name: "write in English in 'rtlTextBox'",
-						timeout: 3000,
+						timeout: 5000,
 
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							focusThenRun(textBox, function(){
-								doh.robot.typeKeys('Hello!', 1, 300);
+								doh.robot.typeKeys('Hello', 1, 300);
+								// select text from the right side of the textbox
+								doh.robot.mouseMoveAt(textBox.focusNode, 50, 100, textBox.focusNode.offsetWidth-5, textBox.focusNode.offsetHeight >> 1);
+								doh.robot.mousePress({left:true}, 500);
+								doh.robot.mouseMoveAt(textBox.focusNode, 50, 1000, textBox.focusNode.offsetWidth-20, textBox.focusNode.offsetHeight >> 1);
+								doh.robot.mouseRelease({left:true}, 500);
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("rtl",textBox.focusNode.dir,"direction of :" + textBox.id);
+									// verify text was selected from the right side of the textbox
+									if(textBox.focusNode.selectionEnd){
+										doh.t(textBox.focusNode.selectionEnd > textBox.focusNode.selectionStart, "selected text " + textBox.focusNode.selectionStart + '. ' + textBox.focusNode.selectionEnd);
+									}else{
+										range = dojo.global.window.document.selection.createRange();
+										pos = range.getBoundingClientRect();
+										doh.t(pos.right > pos.left, "selected text " + pos.left + '. ' + pos.right);
+									}
 								}), 400);
 							});
 
 							return d;
 						}
-					},				
+					},
 					{
 						name: "paste Hebrew in 'rtlTextBox'",
-						timeout: 2000,
+						timeout: 4000,
 
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -128,10 +152,7 @@
 								doh.robot.setClipboard("\u05e9\u05dc\u05d5\u05dd\u0021",'text/html');
 
 								doh.robot.keyPress("a", 400, modifier);
-								doh.robot.keyPress(dojo.keys.DELETE, 100, {});
-
 								doh.robot.keyPress("v", 300, modifier);
-
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("rtl",textBox.focusNode.dir,"direction of :" + textBox.id);
 								}), 400);
@@ -140,7 +161,7 @@
 							return d;
 						}
 					}
-				]);	
+				]);
 
 				doh.register("Contextual textBox", [
 					{
@@ -148,6 +169,7 @@
 
 						setUp: function(){
 							textBox = dijit.byId("contextualTextBox");
+							textBox.domNode.scrollIntoView();
 						},
 
 						runTest: function(){
@@ -156,42 +178,64 @@
 					},
 					{
 						name: "write in English in 'contextualTextBox'",
-						timeout: 3000,
+						timeout: 5000,
 
 						runTest: function(){
-							var d = new doh.Deferred(),
-								modifier = dojo.isMac ? {meta: true} : {ctrl: true},
-								textBox = dijit.byId("contextualTextBox");
+							var d = new doh.Deferred();
 
 							focusThenRun(textBox, function(){
-								doh.robot.setClipboard("Hello!",'text/html');
+								doh.robot.setClipboard("Hello",'text/html');
 
 								doh.robot.keyPress("v", 600, modifier);
+								// select text from the left side of the textbox
+								doh.robot.mouseMoveAt(textBox.focusNode, 50, 100, 5, textBox.focusNode.offsetHeight >> 1);
+								doh.robot.mousePress({left:true}, 500);
+								doh.robot.mouseMoveAt(textBox.focusNode, 50, 1000, 20, textBox.focusNode.offsetHeight >> 1);
+								doh.robot.mouseRelease({left:true}, 500);
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("ltr",textBox.focusNode.dir,"direction of :" + textBox.id);
-								}), 300);	
-							});					
+									// verify text was selected from the left side of the textbox
+									if(textBox.focusNode.selectionEnd){
+										doh.t(textBox.focusNode.selectionEnd > textBox.focusNode.selectionStart, "selected text " + textBox.focusNode.selectionStart + '. ' + textBox.focusNode.selectionEnd);
+									}else{
+										range = dojo.global.window.document.selection.createRange();
+										pos = range.getBoundingClientRect();
+										doh.t(pos.right > pos.left, "selected text " + pos.left + '. ' + pos.right);
+									}
+								}), 300);
+							});
 
 							return d;
 						}
 					},
 					{
 						name: "text direction paste Hebrew before English",
-						timeout: 2000,
+						timeout: 5000,
 
 						runTest: function(){
-							var d = new doh.Deferred(),
-								modifier = dojo.isMac ? {meta: true} : {ctrl: true},
-								textBox = dijit.byId("contextualTextBox");
+							var d = new doh.Deferred();
 
 							focusThenRun(textBox, function(){
 								doh.robot.setClipboard("\u05d0\u05e0\u05d9\u0020\u05d0\u05d5\u05de\u05e8\u05ea\u003a\u0020",'text/html');
 
-								dojo.isMac ? doh.robot.keyPress("a", 100, {ctrl:true}): doh.robot.keyPress(dojo.keys.HOME, 100, {});	
+								dojo.isMac ? doh.robot.keyPress("a", 100, {ctrl:true}): doh.robot.keyPress(dojo.keys.HOME, 100, {});
 
 								doh.robot.keyPress("v", 400, modifier);
+								// select text from the right side of the textbox
+								doh.robot.mouseMoveAt(textBox.focusNode, 50, 100, textBox.focusNode.offsetWidth-5, textBox.focusNode.offsetHeight >> 1);
+								doh.robot.mousePress({left:true}, 500);
+								doh.robot.mouseMoveAt(textBox.focusNode, 50, 1000, textBox.focusNode.offsetWidth-20, textBox.focusNode.offsetHeight >> 1);
+								doh.robot.mouseRelease({left:true}, 500);
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is("rtl",textBox.focusNode.dir,"direction of :" + textBox.id);
+									// verify text was selected from the right side of the textbox
+									if(textBox.focusNode.selectionEnd){
+										doh.t(textBox.focusNode.selectionEnd > textBox.focusNode.selectionStart, "selected text " + textBox.focusNode.selectionStart + '. ' + textBox.focusNode.selectionEnd);
+									}else{
+										range = dojo.global.window.document.selection.createRange();
+										pos = range.getBoundingClientRect();
+										doh.t(pos.right > pos.left, "selected text " + pos.left + '. ' + pos.right);
+									}
 								}), 400);
 							});
 
diff --git a/dijit/tests/_BidiSupport/form/robot/Textarea.html b/dijit/tests/_BidiSupport/form/robot/Textarea.html
index d345a0c..a11b819 100644
--- a/dijit/tests/_BidiSupport/form/robot/Textarea.html
+++ b/dijit/tests/_BidiSupport/form/robot/Textarea.html
@@ -4,22 +4,22 @@
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 		<title>doh.robot Textarea textDir Tests</title>
-	
+
 		<style>
 			@import "../../../../../util/doh/robot/robot.css";
 		</style>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../../dojo/dojo.js">
-		</script>		
-			
+		</script>
+
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_Textarea.html');
 				var textarea;
-				
+
 				// execute some test as soon as the widget gets focus
 				var focusThenRun = function(widget, fcn){
 					if(!widget.focused){
@@ -36,7 +36,7 @@
 				doh.register("LTR textarea", [
 					{
 						name: "initial text direction of empty 'blankL'",
-						
+
 						setUp: function(){
 							textarea = dijit.byId("blankL");
 							modifier = dojo.isMac ? {meta: true} : {ctrl: true};
@@ -45,7 +45,7 @@
 						runTest: function(){
 							doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
 						}
-					},				
+					},
 					{
 						name: "write in English in 'blankL'",
 						timeout: 3000,
@@ -65,8 +65,8 @@
 					},
 					{
 						name: "paste Hebrew in 'blankL'",
-						timeout: 2000,
-						
+						timeout: 3000,
+
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -81,16 +81,16 @@
 									doh.is("ltr",textarea.focusNode.dir,"direction of :" + textarea.id);
 								}), 400);
 							});
-							
+
 							return d;
 						}
 					}
-				]);				
-				
+				]);
+
 				doh.register("RTL textarea", [
 					{
 						name: "initial text direction of empty 'blankR'",
-						
+
 						setUp: function(){
 							textarea = dijit.byId("blankR");
 						},
@@ -105,7 +105,7 @@
 
 						runTest: function(){
 							var d = new doh.Deferred();
- 
+
 							focusThenRun(textarea, function(){
 								doh.robot.typeKeys('Hello!', 1, 300);
 								doh.robot.sequence(d.getTestCallback(function(){
@@ -115,14 +115,14 @@
 
 							return d;
 						}
-					},				
+					},
 					{
 						name: "paste Hebrew in 'blankR'",
-						timeout: 2000,
-	
+						timeout: 3000,
+
 						runTest: function(){
 							var d = new doh.Deferred();
-							
+
 							focusThenRun(textarea, function(){
 								doh.robot.setClipboard("\u05e9\u05dc\u05d5\u05dd\u0021",'text/html');
 
@@ -138,12 +138,12 @@
 							return d;
 						}
 					}
-				]);	
+				]);
 
 				doh.register("Contextual textarea", [
 					{
 						name: "initial text direction of empty 'blankA'",
-												
+
 						setUp: function(){
 							textarea = dijit.byId("blankA");
 						},
@@ -185,7 +185,7 @@
 							focusThenRun(textarea, function(){
 								doh.robot.setClipboard("\u05d0\u05e0\u05d9\u0020\u05d0\u05d5\u05de\u05e8\u05ea\u003a\u0020",'text/html');
 
-								dojo.isMac ? doh.robot.keyPress("a", 100, {ctrl:true}): doh.robot.keyPress(dojo.keys.HOME, 100, {});	
+								dojo.isMac ? doh.robot.keyPress("a", 100, {ctrl:true}): doh.robot.keyPress(dojo.keys.HOME, 100, {});
 
 								doh.robot.keyPress("v", 400, modifier);
 								doh.robot.sequence(d.getTestCallback(function(){
@@ -257,7 +257,7 @@
 						}
 					}
 				]);
-			
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/_BidiSupport/form/test_InlineEditBox.html b/dijit/tests/_BidiSupport/form/test_InlineEditBox.html
index d294e5f..c46c0af 100644
--- a/dijit/tests/_BidiSupport/form/test_InlineEditBox.html
+++ b/dijit/tests/_BidiSupport/form/test_InlineEditBox.html
@@ -7,13 +7,6 @@
 		<style type="text/css">
 			@import "../../../../dijit/themes/claro/document.css";
 			@import "../../../../dijit/tests/css/dijitTests.css";
-			
-			.inlineEdit { background-color: #CCC76A; }
-
-			/* some style rules on nodes just to test that style gets copied to the edit widget */
-			p { font-family: cursive; }
-			.letter p { font-family: monospace; }
-			h3 { font-family: helvetica; font-style: italic; }
 		</style>
 
 		<!-- required: a default dijit theme: -->
@@ -21,10 +14,9 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+			data-dojo-config="parseOnLoad: true, isDebug: true, has: { 'dojo-bidi': true }"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dojo.data.ItemFileReadStore");
 			dojo.require("dijit.InlineEditBox");
 			dojo.require("dijit.form.Textarea");
@@ -38,9 +30,8 @@
 
 			dojo.require("dijit.Editor");
 			dojo.require("dijit._editor.plugins.AlwaysShowToolbar");
-			dojo.require("dijit._BidiSupport");//lena
 
-			dojo.require("dojo.parser");	  // scan page for widgets and instantiate them
+			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
 			function myHandler(newValue){
 				this._onChangeValue = newValue;	// used by robot test file
@@ -52,56 +43,57 @@
 
 		<h1 class="testTitle">Dijit InlineEditBox Bidi Test</h1>
 
-	
-		<span data-dojo-id="productStore" data-dojo-type="dojo.data.ItemFileReadStore" >
+
+		<span data-dojo-id="productStore" data-dojo-type="dojo/data/ItemFileReadStore" >
 			<script type="dojo/method">
-				this._jsonData =
-					{ identifier: 'name',
-					  label: 'name',
-					  items: [
+				this._jsonData = {
+					identifier: 'name',
+					label: 'name',
+					items: [
 						{ name: "refrigerator..." },
 						{ name: "\u05d0\u05e0\u05d9\u0020\u05d0\u05d5\u05de\u05e8\u05ea\u003a\u0020" },
 						{ name: "stove \u05d0\u05e0\u05d9\u0020\u05d0\u05d5\u05de\u05e8\u05ea\u003a\u0020 ..." },
 						{ name: "\u05d0\u05e0\u05d9\u0020\u05d0\u05d5\u05de\u05e8\u05ea\u003a\u0020 heater ..." }
-					]};
+					]
+				};
 			</script>
 		</span>
 
 		<h2>InlineEditBox with TextBox</h2>
-		    <h3>TextDit LTR: </h3>
-			<span id="P0" data-dojo-type="dijit.InlineEditBox" data-dojo-props='textDir:"ltr", value:"", onChange:myHandler, autoSave:true, title:"test"'>
+			<h3>TextDit LTR: </h3>
+			<span id="P0" data-dojo-type="dijit/InlineEditBox" data-dojo-props='textDir:"ltr", value:"", onChange:myHandler, autoSave:true, title:"test"'>
 			</span>
-		    <h3>TextDir RTL: </h3>
-		    <span id="P1" data-dojo-type="dijit.InlineEditBox" data-dojo-props='textDir:"rtl", value:"ערך חדש!!", onChange:myHandler, autoSave:true, title:"test"'>
-			    </span>	
-		    <h3>TextDir AUTO: </h3>	
-			    <span id="P2" data-dojo-type="dijit.InlineEditBox" data-dojo-props='textDir:"auto", value:"Hello!", onChange:myHandler, autoSave:true, title:"test"'>
-			    </span>
-		    <input id="button" type="button" onclick="dijit.byId('P2').set('value', 'ערך חדש!')"  value = "change value"/>
-		  
-		
+			<h3>TextDir RTL: </h3>
+			<span id="P1" data-dojo-type="dijit/InlineEditBox" data-dojo-props='textDir:"rtl", value:"ערך חדש!!", onChange:myHandler, autoSave:true, title:"test"'>
+				</span>
+			<h3>TextDir AUTO: </h3>
+				<span id="P2" data-dojo-type="dijit/InlineEditBox" data-dojo-props='textDir:"auto", value:"Hello!", onChange:myHandler, autoSave:true, title:"test"'>
+				</span>
+			<input id="button" type="button" onclick="dijit.byId('P2').set('value', 'ערך חדש!')"  value = "change value"/>
+
+
 		<h2>InlineEditBox with Textarea</h2>
 		<h3>TextDir LTR</h3>
-			<span id="P3" data-dojo-type="dijit.InlineEditBox" data-dojo-props='autoSave:true, textDir:"ltr", editor:"dijit.form.Textarea", value: "Text Area test ערך !!!", title:"additional details"'></span>
-		    <h3>TextDir RTL</h3>
-			<span id="P4" data-dojo-type="dijit.InlineEditBox" data-dojo-props='autoSave:true, textDir:"rtl", editor:"dijit.form.Textarea", value: "Text Area test ערך !!!", title:"additional details"'></span>		   
-			<h3>TextDir AUTO</h3>	
-			<span id="P5" data-dojo-type="dijit.InlineEditBox" data-dojo-props='autoSave:true, textDir:"auto", editor:"dijit.form.Textarea", value: "Text Area test ערך חדש!!!", title:"additional details"'></span>		   
-		    <input id="Button1" type="button" onclick="dijit.byId('P5').set('value', 'ערך חדש!')"  value = "change value"/>
-		
-		
+			<span id="P3" data-dojo-type="dijit/InlineEditBox" data-dojo-props='autoSave:true, textDir:"ltr", editor:"dijit.form.Textarea", value: "Text Area test ערך !!!", title:"additional details"'></span>
+			<h3>TextDir RTL</h3>
+			<span id="P4" data-dojo-type="dijit/InlineEditBox" data-dojo-props='autoSave:true, textDir:"rtl", editor:"dijit.form.Textarea", value: "Text Area test ערך !!!", title:"additional details"'></span>
+			<h3>TextDir AUTO</h3>
+			<span id="P5" data-dojo-type="dijit/InlineEditBox" data-dojo-props='autoSave:true, textDir:"auto", editor:"dijit.form.Textarea", value: "Text Area test ערך חדש!!!", title:"additional details"'></span>
+			<input id="Button1" type="button" onclick="dijit.byId('P5').set('value', 'ערך חדש!')"  value = "change value"/>
+
+
 		<h2>InlineEditBox with Combobox</h2>
 		<h3>TextDir LTR</h3>
-		<span id="combo1" data-dojo-type="dijit.InlineEditBox" data-dojo-props='textDir:"ltr",	 editor:"dijit.form.ComboBox",
+		<span id="combo1" data-dojo-type="dijit/InlineEditBox" data-dojo-props='textDir:"ltr", editor:"dijit.form.ComboBox",
 					editorParams:{searchAttr: "name", store: productStore, autocomplete: false, hasDownArrow: false},
-					 width:"200px", autoSave:false, title:"item name"'>refrigerators...</span>
+					width:"200px", autoSave:false, title:"item name"'>refrigerators...</span>
 		<h3>TextDir RTL</h3>
-		<span id="combo2" data-dojo-type="dijit.InlineEditBox" data-dojo-props='textDir:"rtl",	 editor:"dijit.form.ComboBox",
+		<span id="combo2" data-dojo-type="dijit/InlineEditBox" data-dojo-props='textDir:"rtl", editor:"dijit.form.ComboBox",
 					editorParams:{searchAttr: "name", store: productStore, autocomplete: false, hasDownArrow: false},
-					 width:"200px", autoSave:false, title:"item name"'>refrigerators...</span>
+					width:"200px", autoSave:false, title:"item name"'>refrigerators...</span>
 		<h3>TextDir AUTO</h3>
-		<span id="combo3" data-dojo-type="dijit.InlineEditBox" data-dojo-props='textDir:"auto",	 editor:"dijit.form.ComboBox",
+		<span id="combo3" data-dojo-type="dijit/InlineEditBox" data-dojo-props='textDir:"auto", editor:"dijit.form.ComboBox",
 					editorParams:{searchAttr: "name", store: productStore, autocomplete: false, hasDownArrow: false},
-					 width:"200px", autoSave:false, title:"item name"'>refrigerators...</span>					 
+					width:"200px", autoSave:false, title:"item name"'>refrigerators...</span>
 	</body>
 </html>
diff --git a/dijit/tests/_BidiSupport/form/test_PlaceholderInput.html b/dijit/tests/_BidiSupport/form/test_PlaceholderInput.html
new file mode 100644
index 0000000..31001d8
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/test_PlaceholderInput.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Placeholder input</title>
+
+		<style type="text/css">
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			@import "../../../../dojo/resources/dojo.css";
+		</style>
+
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="async: false, has: { 'dojo-bidi': true }"></script>
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/dom",
+			"dojo/query",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/form/TextBox",
+			"dojo/domReady!"
+		], function(doh, dom, query, parser, registry){
+
+				doh.register("parse", function(){
+					return parser.parse();
+				});
+
+				doh.register("Input tests", [
+					{
+						name: "Bidi",
+						runTest: function(){
+							var spanPlaceHolder = query("span.dijitPlaceHolder")[0];
+							doh.is("rtl", spanPlaceHolder.dir, "placeholder span 'dir' attribute should be set to 'rtl'");
+						}
+					}
+				]);
+
+				doh.register("log", function(){
+					dom.byId('failures').innerHTML = doh._failureCount;
+					dom.byId('errors').innerHTML = doh._errorCount;
+				});
+
+				doh.run();
+		});
+	</script>
+	</head>
+	<body>
+		<br><br>
+		<label >TextBox with Placeholder, textDir="auto"</label>
+		<input id="inputPlaceholder" data-dojo-type="dijit/form/TextBox" placeHolder="שplaceholder!" data-dojo-props='textDir:"auto"' name="placeHolder" value=""/>
+
+		<br>Errors: <span id="errors">?</span>
+		<br>Failures: <span id="failures">?</span>
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/test_Select.html b/dijit/tests/_BidiSupport/form/test_Select.html
new file mode 100644
index 0000000..7bb234d
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/test_Select.html
@@ -0,0 +1,299 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Bidi BTD in Select</title>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+		<style>
+			@import url(../../../themes/claro/document.css);
+			@import url(../../css/dijitTests.css);
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="isDebug: true, has: { 'dojo-bidi': true }"></script>
+
+		<!-- only needed for alternate theme testing: -->
+		<script type="text/javascript" src="../../_testCommon.js"></script>
+
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dijit/registry",
+				"dijit/form/Select",
+				"dijit/form/Button",
+				"dijit/form/Form",
+				"dijit/Dialog",
+				"dojo/domReady!"
+			], function(doh, parser, registry, Select){
+	
+				var numOptions = 0;
+				var numChanges = 0;
+				var addNum = 10;
+	
+				function testSelectWidget(element, formDir,elementTextDir,isfirstChildLatin){
+					doh.is(registry.byId(element).get("textDir"), elementTextDir);
+					doh.is(registry.byId(element).dir, formDir);
+					var t_dir = elementTextDir;
+					if(t_dir == "auto")
+						t_dir = isfirstChildLatin? "ltr" : "rtl";
+					doh.is(registry.byId(element).containerNode.dir, t_dir);
+				}
+	
+				function testDropdownList(elementName){
+					var element = registry.byId(elementName);
+					var elementTextDir = element.get("textDir");
+					var itemTextDir = elementTextDir;
+					element.loadDropDown(function(){});
+					var list = element.dropDown.getChildren();
+					dojo.forEach(list, function(entry){
+						if(elementTextDir == "auto"){
+							itemTextDir = element._checkContextual(entry.label.replace(/<[^>]*>/gm," "));
+						}
+						doh.is(itemTextDir,entry.textDirNode.dir);
+					});
+				}
+
+				var programmatic1 = new Select({
+					options: [
+						{ label: 'foo!', value: 'foo!'},
+						{ label: 'bar', value: 'bar' },
+						{ label: 'x !', value: 'x !', selected: true  },
+						{ label: '\u05D0\u05D1\u05D2!', value: '\u05D0\u05D1\u05D2!' }
+					]
+				});
+				programmatic1.placeAt('testProgramatic1');
+				programmatic1.set("textDir",'ltr');
+
+				var programmatic2 = new Select({
+					options: [
+						{ label: 'foo!', value: 'foo!'},
+						{ label: 'bar', value: 'bar' },
+						{ label: 'x !', value: 'x !', selected: true  },
+						{ label: '\u05D0\u05D1\u05D2!', value: '\u05D0\u05D1\u05D2!' }
+					]
+				});
+				programmatic2.placeAt('testProgramatic2');
+				programmatic2.set("textDir",'rtl');
+
+				var programmatic3 = new Select({
+					options: [
+						{ label: 'foo!', value: 'foo!'},
+						{ label: 'bar', value: 'bar' },
+						{ label: 'x !', value: 'x !', selected: true  },
+						{ label: '\u05D0\u05D1\u05D2!', value: '\u05D0\u05D1\u05D2!' }
+					]
+				});
+				programmatic3.placeAt('testProgramatic3');
+				programmatic3.set("textDir",'auto');
+
+				doh.register("parse", function(){
+					return parser.parse();
+				});
+
+				doh.register("dijit.tests._BidiSupport.form.Select in LTR form", [
+					{name:"LTR form, Auto/Hebrew", runTest:function(){testSelectWidget("s10","ltr","auto",false);}},
+					{name:"LTR form, Auto/English",runTest:function(){testSelectWidget("s11","ltr","auto",true);}},
+					{name:"LTR form, LTR",runTest:function(){testSelectWidget("s12","ltr","ltr",true);}},
+					{name:"LTR form, RTL",runTest:function(){testSelectWidget("s13","ltr","rtl",true);}}
+				]);
+
+				doh.register("Bidi dropdown list in Select, LTR form", [
+					{name:"LTR form, Auto/Hebrew", runTest:function(){testDropdownList("s10");}},
+					{name:"LTR form, Auto/English",runTest:function(){testDropdownList("s11");}},
+					{name:"LTR form, LTR",runTest:function(){testDropdownList("s12");}},
+					{name:"LTR form, RTL",runTest:function(){testDropdownList("s13");}}
+				]);
+
+				doh.register("dijit.tests._BidiSupport.form.Select in RTL form", [
+					{name:"RTL form, Auto/Hebrew", runTest:function(){testSelectWidget("s10R","rtl","auto",false);}},
+					{name:"RTL form, Auto/English",runTest:function(){testSelectWidget("s11R","rtl","auto",true);}},
+					{name:"RTL form, LTR",runTest:function(){testSelectWidget("s12R","rtl","ltr",true);}},
+					{name:"RTL form, RTL",runTest:function(){testSelectWidget("s13R","rtl","rtl",true);}}
+				]);
+
+				doh.register("Bidi dropdown list in Select, RTL form", [
+					{name:"LTR form, Auto/Hebrew", runTest:function(){testDropdownList("s10R");}},
+					{name:"LTR form, Auto/English",runTest:function(){testDropdownList("s11R");}},
+					{name:"LTR form, LTR",runTest:function(){testDropdownList("s12R");}},
+					{name:"LTR form, RTL",runTest:function(){testDropdownList("s13R");}}
+				]);
+
+				doh.register("dijit.tests._BidiSupport.form.Select, rich text (auto)", [
+					{name:"Rich text Auto/English Select",runTest:function(){testSelectWidget("s4","ltr","auto",true);}},
+					{name:"Rich text Auto/Hebrew Select", runTest:function(){testSelectWidget("s5","ltr","auto",false);}},
+					{name:"Rich text Auto/English Dropdown",runTest:function(){testDropdownList("s4");}},
+					{name:"Rich text Auto/Hebrew Dropdown", runTest:function(){testDropdownList("s5");}}
+
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<h1 id="_title" class="testTitle">Test: dijit/form/Select <i>BIDI</i></h1>
+
+		<form id="form" data-dojo-id="formL" data-dojo-type="dijit/form/Form" method="get"
+				onSubmit="return this.validate();">
+		<div dir="ltr">
+			<h2>dijit/form/Select LTR form</h2>
+			<h4 class="testSubtitle">Setting Defaults</h4>
+
+			<label for="s10">Test AUTO: </label>
+			<select id="s10" data-dojo-id="s10" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s10" , textDir:"auto", style:{width:"150px"}'>
+				<option value="TN">START חדש!</option>
+				<option value="TM" selected="selected">חדש END !</option>
+				<option value="VA">Hello AUTO!!</option>
+				<option value="WA">חדש.</option>
+				<option value="FL">NEW!</option>
+			</select>
+			<select id="s11" data-dojo-id="s11" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s11" , textDir:"auto", style:{width:"150px"}'>
+				<option value="TN">START חדש!</option>
+				<option value="TM">חדש END !</option>
+				<option value="VA" selected="selected">Hello AUTO!!</option>
+				<option value="WA">חדש.</option>
+				<option value="FL">NEW!</option>
+			</select>
+			<br>
+			<label for="s12">Test LTR: </label>
+			<select id="s12" data-dojo-id="s12" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s12" , textDir:"ltr", style:{width:"150px"}'>
+				<option value="TN">START חדש!</option>
+				<option value="TM">חדש END !</option>
+				<option value="VA" selected="selected">Hello LTR!!</option>
+				<option value="WA">חדש.</option>
+				<option value="FL">NEW!</option>
+			</select>
+
+			<label for="s13">Test RTL: </label>
+			<select id="s13" data-dojo-id="s13" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s13" , textDir:"rtl", style:{width:"150px"}'>
+				<option value="TN">START חדש!</option>
+				<option value="TM">חדש END !</option>
+				<option value="VA" selected="selected">Hello RTL!!</option>
+				<option value="WA">חדש.</option>
+				<option value="FL">NEW!</option>
+			</select>
+
+			<hr>
+			<h4 class="testSubtitle"> </h4>
+			<label>Rich Text (AUTO):
+			<span id="s4" data-dojo-id="s4" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s4", value:"AK" , textDir:"auto", style:{width:"150px"}'>
+				<span data-dojo-value="AL"><b>Alabama.</b></span>
+				<span data-dojo-value="AK"><span style="color:red;">A</span><span style="color:orange;">l</span><span style="color:yellow;">a</span><span style="color:green;">s</span><span style="color:blue;">k</span><span style="color:purple;">a.</span></span>
+				<span data-dojo-value="AZ"><i>Arizona.</i></span>
+				<span data-dojo-value="IL"><b><i>חדש.</i></b></span>
+				<span data-dojo-value="AR"><span class="ark">Arkansas.</span></span>
+				<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a.</span></span>
+				<button value="NM" disabled="disabled">New<br>  Mexico</button>
+			</span></label>
+			  
+			<label>
+			<span id="s5" data-dojo-id="s5" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s5", value:"IL" , textDir:"auto", style:{width:"150px"}'>
+				<span data-dojo-value="AL"><b>Alabama.</b></span>
+				<span data-dojo-value="AK"><span style="color:red;">A</span><span style="color:orange;">l</span><span style="color:yellow;">a</span><span style="color:green;">s</span><span style="color:blue;">k</span><span style="color:purple;">a.</span></span>
+				<span data-dojo-value="AZ"><i>Arizona.</i></span>
+				<span data-dojo-value="IL"><b><i>חדש.</i></b></span>
+				<span data-dojo-value="AR"><span class="ark">Arkansas.</span></span>
+				<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a.</span></span>
+				<button value="NM" disabled="disabled">New<br>  Mexico</button>
+			</span></label>
+
+
+		</div>
+		</form>
+
+<!------------------------>
+		<form id="formR" data-dojo-id="form" data-dojo-type="dijit/form/Form" method="get" >
+		<div dir="rtl">
+			<h2>dijit/form/Select RTL form</h2>
+			<h4 class="testSubtitle">Setting Defaults</h4>
+
+			<label for="s10R">Test AUTO: </label>
+			<select id="s10R" data-dojo-id="s10R" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s10R" , textDir:"auto"'>
+				<option value="TN">START חדש!</option>
+				<option value="TM" selected="selected">חדש END !</option>
+				<option value="VA">Hello AUTO!!</option>
+				<option value="WA">חדש.</option>
+				<option value="FL">NEW!</option>
+			</select>
+			<select id="s11R" data-dojo-id="s11" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s11R" , textDir:"auto"'>
+				<option value="TN">START חדש!</option>
+				<option value="TM">חדש END !</option>
+				<option value="VA" selected="selected">Hello AUTO!!</option>
+				<option value="WA">חדש.</option>
+				<option value="FL">NEW!</option>
+			</select>
+			<br>
+			<label for="s12R">Test LTR: </label>
+			<select id="s12R" data-dojo-id="s12R" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s12R" , textDir:"ltr"'>
+				<option value="TN">START חדש!</option>
+				<option value="TM">חדש END !</option>
+				<option value="VA" selected="selected">Hello LTR!!</option>
+				<option value="WA">חדש.</option>
+				<option value="FL">NEW!</option>
+			</select>
+			<br>
+			<label for="s13R">Test RTL: </label>
+			<select id="s13R" data-dojo-id="s13R" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s13R" , textDir:"rtl"'>
+				<option value="TN">START חדש!</option>
+				<option value="TM">חדש END !</option>
+				<option value="VA" selected="selected">Hello RTL!!</option>
+				<option value="WA">חדש.</option>
+				<option value="FL">NEW!</option>
+			</select>
+
+			<hr>
+			<h4 class="testSubtitle"> </h4>
+			<label>Rich Text (AUTO):
+			<span id="s4R" data-dojo-id="s4R" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s4R", value:"AK" , textDir:"auto"'>
+				<span data-dojo-value="AL"><b>Alabama.</b></span>
+				<span data-dojo-value="AK"><span style="color:red;">A</span><span style="color:orange;">l</span><span style="color:yellow;">a</span><span style="color:green;">s</span><span style="color:blue;">k</span><span style="color:purple;">a.</span></span>
+				<span data-dojo-value="AZ"><i>Arizona.</i></span>
+				<span data-dojo-value="IL"><b><i>חדש.</i></b></span>
+				<span data-dojo-value="AR"><span class="ark">Arkansas.</span></span>
+				<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a.</span></span>
+				<button value="NM" disabled="disabled">New<br>  Mexico</button>
+			</span></label>
+			  
+			<label>
+			<span id="s5R" data-dojo-id="s5" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s5R", value:"IL" , textDir:"auto"'>
+				<span data-dojo-value="AL"><b>Alabama.</b></span>
+				<span data-dojo-value="AK"><span style="color:red;">A</span><span style="color:orange;">l</span><span style="color:yellow;">a</span><span style="color:green;">s</span><span style="color:blue;">k</span><span style="color:purple;">a.</span></span>
+				<span data-dojo-value="AZ"><i>Arizona.</i></span>
+				<span data-dojo-value="IL"><b><i>חדש.</i></b></span>
+				<span data-dojo-value="AR"><span class="ark">Arkansas.</span></span>
+				<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a.</span></span>
+				<button value="NM" disabled="disabled">New<br>  Mexico</button>
+			</span></label>
+
+		</div>
+		</form>
+
+
+<!------------------------>
+		<hr>
+		<h4 class="testSubtitle">Widgets created programmatically:</h4><br>
+		<span id="testProgramatic1">LTR: </span>
+		<span id="testProgramatic2">  RTL: </span>
+		<span id="testProgramatic3">  AUTO: </span>
+
+		<!-- testing that tooltip disappears when dialog is closed -->
+		<div data-dojo-type="dijit/Dialog" id="dlg1">
+			<div data-dojo-type="dijit/form/Select" id="dlg1Select"required="true"></div>
+			<div data-dojo-type="dijit/form/Button" id="dlg1ValidateBtn">
+				<script type=dojo/method data-dojo-event="onClick">
+					var dlg1 = dijit.byId("dlg1");
+					if(dlg1.validate()){
+						dlg1.hide();
+					}
+				</script>
+				validate and close
+			</div>
+		</div>
+
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/test_SimpleComboBoxes.html b/dijit/tests/_BidiSupport/form/test_SimpleComboBoxes.html
index ef10033..73d6772 100644
--- a/dijit/tests/_BidiSupport/form/test_SimpleComboBoxes.html
+++ b/dijit/tests/_BidiSupport/form/test_SimpleComboBoxes.html
@@ -16,24 +16,19 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true">
-		</script>		
+			data-dojo-config="parseOnLoad: true, isDebug: true, has: { 'dojo-bidi': true }">
+		</script>
 
 		<script type="text/JavaScript">
 			dojo.require("dijit.form.ComboBox");
-			dojo.require("dijit._BidiSupport");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-			
-	//				dojo.ready(init);
-
+			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 		</script>
 	</head>
 	<body class="claro">
 		<label for="fruitLtr"> <b>I'm a LTR ComboBox </b> </label>
 		<br>
-		<select id="fruitLtr" 
-			data-dojo-type="dijit.form.ComboBox" 
+		<select id="fruitLtr"
+			data-dojo-type="dijit/form/ComboBox"
 			data-dojo-props='name:"fruitLtr",
 			textDir:"ltr"'>
 				<option >Apples!</option>
@@ -45,8 +40,8 @@
 		<br>
 		<label for="fruitRtl"> <b>I'm a RTL ComboBox </b> </label>
 		<br>
-		<select id="fruitRtl" 
-			data-dojo-type="dijit.form.ComboBox" 
+		<select id="fruitRtl"
+			data-dojo-type="dijit/form/ComboBox"
 			data-dojo-props='name:"fruitRtl",
 			textDir:"rtl"'>
 				<option >Apples!</option>
@@ -58,8 +53,8 @@
 		<br>
 		<label for="fruitContextual"> <b>I'm a Contextual ComboBox </b> </label>
 		<br>
-		<select id="fruitContextual" 
-			data-dojo-type="dijit.form.ComboBox" 
+		<select id="fruitContextual"
+			data-dojo-type="dijit/form/ComboBox"
 			data-dojo-props='name:"fruitContextual",
 			autoComplete:false,
 			textDir:"auto"'>
@@ -72,9 +67,9 @@
 		<br>
 		<label for="fruitContextualAC"> <b>I'm a Contextual ComboBox </b> </label>
 		<br>
-		<select id="fruitContextualAC" 
-			data-dojo-type="dijit.form.ComboBox" 
-			data-dojo-props='name:"fruitContextualAc",				
+		<select id="fruitContextualAC"
+			data-dojo-type="dijit/form/ComboBox"
+			data-dojo-props='name:"fruitContextualAc",
 			textDir:"auto"'>
 				<option >@Apples!</option>
 				<option >:Oranges!</option>
@@ -82,6 +77,6 @@
 				<option >:שלום לכם!</option>
 				<option >*תפוח אדמה!</option>
 		</select>
-		
+
 	</body>
 </html>
diff --git a/dijit/tests/_BidiSupport/form/test_SimpleTextarea.html b/dijit/tests/_BidiSupport/form/test_SimpleTextarea.html
index 797c366..5d6a944 100644
--- a/dijit/tests/_BidiSupport/form/test_SimpleTextarea.html
+++ b/dijit/tests/_BidiSupport/form/test_SimpleTextarea.html
@@ -12,13 +12,11 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true">
-		</script>		
- 
+			data-dojo-config="parseOnLoad: true, isDebug: true, has: { 'dojo-bidi': true }">
+		</script>
+
 		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dijit.form.SimpleTextarea");
-			dojo.require("dijit._BidiSupport");
 		</script>
 	</head>
 
@@ -30,7 +28,7 @@
 			<b>I'm a LTR SimpleTextarea </b>
 		</label>
 		<br>
-		<textarea id="ltrSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea" 
+		<textarea id="ltrSimpleTexarea" data-dojo-type="dijit/form/SimpleTextarea"
 			data-dojo-props='name:"ltrSimpleTexarea",rows:"4", cols:"50",
 			textDir:"ltr"'>Lorem ipsum dolor sit amet, consectetuer adipiscing elit!
 		</textarea>
@@ -40,7 +38,7 @@
 			<b>I'm a RTL SimpleTextarea </b>
 		</label>
 		<br>
-		<textarea id="rtlSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea"
+		<textarea id="rtlSimpleTexarea" data-dojo-type="dijit/form/SimpleTextarea"
 			data-dojo-props='name:"rtlSimpleTexarea",rows:"4", cols:"50",
 			textDir:"rtl"'>Lorem ipsum dolor sit amet, consectetuer adipiscing elit!
 		</textarea>
@@ -50,7 +48,7 @@
 			<b>I'm a contextual SimpleTexarea </b>
 		</label>
 		<br>
-		<textarea id="contextualSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea" 
+		<textarea id="contextualSimpleTexarea" data-dojo-type="dijit/form/SimpleTextarea"
 			data-dojo-props='name:"contextualSimpleTexarea",rows:"4", cols:"50",
 			textDir:"auto"
 			'> הטקסט מוצג כמו שצריך
@@ -62,11 +60,11 @@
 		<textarea id="programmaticLTR"></textarea>
 
 		<br>
-		<label>textDir="rtl":</label>		
+		<label>textDir="rtl":</label>
 		<textarea id="programmaticRTL"></textarea>
 
 		<br>
-		<label>textDir="auto":</label>		
+		<label>textDir="auto":</label>
 		<textarea id="programmaticAuto"></textarea>
 
 		<script type="text/javascript">
@@ -77,7 +75,7 @@
 					name: "programmaticTextAreaLTR",
 					cols: "60",
 					textDir:"ltr",
-					value: "", 
+					value: "",
 					style: "border:5px solid gray;padding:11px;margin:7px;"
 				}, "programmaticLTR");
 
@@ -100,7 +98,7 @@
 				}, "programmaticAuto");
 
 			});
-		</script>		
-		
+		</script>
+
 	</body>
 </html>
diff --git a/dijit/tests/_BidiSupport/form/test_Slider.html b/dijit/tests/_BidiSupport/form/test_Slider.html
new file mode 100644
index 0000000..ddc5c7a
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/test_Slider.html
@@ -0,0 +1,173 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Dojo Slider Widget Demo</title>
+
+		<style type="text/css">
+			@import "../../../themes/claro/document.css";
+			@import "../../css/dijitTests.css";
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="async: true, isDebug: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/dom",
+				"dojo/number",
+				"dojo/parser",
+				"dojo/query",
+				"dijit/registry",
+				"dijit/form/VerticalSlider",
+				"dijit/form/VerticalRule",
+				"dijit/form/VerticalRuleLabels",
+				"dojo/domReady!"
+			], function(doh, dom, number, parser, query, registry, VerticalSlider, VerticalRule, VerticalRuleLabels){
+
+
+				doh.register("setup", [
+					function parse(){
+						return parser.parse();
+					},
+					function programmatic(){
+						// programmatic vertical slider and labels
+						var node;
+						// setup the rules
+						var sliderRules = new VerticalRule({
+							count:11,
+							style:{width:"5px"}
+						});
+
+						// setup RuleLabels
+						var sliderRuleLabels = new VerticalRuleLabels({
+							labels: ["תגlowest!","low!", "mid!", "high!","תגhighest!"],
+							textDir: "ltr",
+							id: "rulerLabels2"
+						});
+
+						// and setup the slider
+						var sliderProps = {
+							value:1400,
+							name:"programmaticSlider",
+							slideDuration:0,
+							onChange:function(val){ dom.byId('sliderProgInput').value=val; },
+							style:{height:"165px"},
+							minimum:1000,
+							maximum:3000,
+							discreteValues:11,
+							intermediateChanges:"true",
+							showButtons:"true"
+						};
+
+						sliderProps.id = sliderProps.name = "programmaticSliderNoSrc";
+
+						var theSlider = new VerticalSlider(sliderProps, node);
+						node = theSlider.containerNode;
+						theSlider.placeAt("form1");
+						sliderRules.placeAt(node);
+						sliderRuleLabels.placeAt(node);
+
+						// and start them all
+						theSlider.startup();
+						sliderRules.startup();
+						sliderRuleLabels.startup();
+
+						//attach handler to Horizontal ruler
+						var slider1 = registry.byId("slider1");
+						slider1.watch("value", function(name, oldVal, newVal){
+							dom.byId("slider1input").value = number.format(newVal/100,{places:1,pattern:"#%"});
+						});
+					}
+				]);
+
+				doh.register("tests._BidiSupport.form.RulerLabelBidi", [
+					{
+						name: "Slider Bidi",
+						runTest: function(){
+							query(" > div",dom.byId('rulerLabels1')).forEach(function(node, index, arr){
+								doh.is("rtl", node.style.direction, "hoprizontal: label node had 'direction' style corresponding to 'textDir'");
+							});
+							registry.byId("rulerLabels2").set('textDir',"auto");
+							var verticalLabel = query("div.dijitRuleLabelContainerV")[0];
+							doh.is("rtl", verticalLabel.style.direction, "vertical: label node had 'direction' style corresponding to 'textDir'");
+						}
+					}
+				]);
+
+				doh.register("log", function(){
+					dom.byId('failures').innerHTML = doh._failureCount;
+					dom.byId('errors').innerHTML = doh._errorCount;
+				});
+
+				doh.run();
+			});
+		</script>
+	</head>
+
+	<body class="claro">
+		<h1 class="testTitle">Slider</h1>
+		Also try using the arrow keys, buttons, or clicking on the progress bar to move the slider.
+		<br>
+		<!--    to test form submission, you'll need to create an action handler similar to
+			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
+		<form id="form1" action="" name="example" method="post">
+		<br>initial value=10, min=0, max=100, pageIncrement=100, onChange event triggers input box value change immediately<br>
+		<strong>Horizontal Slider Example, "rtl" base text direction</strong>
+		<br>
+		<div id="slider1" data-dojo-type="dijit/form/HorizontalSlider" data-dojo-props='name:"horizontal1",
+			value:10,
+			maximum:100,
+			minimum:0,
+			pageIncrement:100,
+			showButtons:true,
+			intermediateChanges:true,
+			slideDuration:500,
+			style:{width:"50%", height:"20px"}
+			' >
+				<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='container:"topDecoration", count:6, style:{height:"5px"}'></div>
+				<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:{height:"5px"}'></div>
+				<ol id="rulerLabels1" data-dojo-type="dijit/form/HorizontalRuleLabels" data-dojo-props='textDir:"rtl", container:"bottomDecoration", style:{height:"1em",fontSize:"75%"}'>
+					<li>תגlowest!</li>
+					<li>תגnormal!</li>
+					<li>תגhighest!</li>
+				</ol>
+		</div>
+		Slider1 Value:<input readonly id="slider1input" size="4" value="10.0%"/>
+		<br>
+		<br>initial value=10, min=0, max=100, onChange event triggers input box value change when you mouse up or tab away<br>
+		<h1>Fancy HTML labels (no slide animation), "rtl" base text direction:</h1>
+		<div id="slider3" data-dojo-type="dijit/form/HorizontalSlider" data-dojo-props='name:"horizontal2",
+			title:"Fancy HTML Labels",
+			minimum:1,
+			value:2,
+			maximum:3,
+			discreteValues:3,
+			showButtons:false,
+			intermediateChanges:true,
+			slideDuration:0,
+			style:"width:300px; height: 30px;"
+			'>
+				<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='container:"bottomDecoration", count:3, style:{height:"5px"}'></div>
+				<ol data-dojo-type="dijit/form/HorizontalRuleLabels" data-dojo-props='textDir:"rtl", container:"bottomDecoration", style:{height:"1em", fontSize:"75%"}'>
+					<li><img width=10 height=10 src="../../images/note.gif"/><br><span style="font-size: small">תגsmall!</span></li>
+					<li><img width=15 height=15 src="../../images/note.gif"/><br><span style="font-size: small">תגmedium!</span></li>
+					<li><img width=20 height=20 src="../../images/note.gif"/><br><span style="font-size: small">תגlarge!</span></li>
+				</ol>
+		</div>
+		<br><br>
+		<h2>Completely programmatic VerticalSlider and VerticalRule, "auto" base text direction</h2>
+		<h3>min:1000, max:3000, 11 discrete values, no animation</h3>
+
+		<div id="programmaticSlider"></div>
+		Programmatic Value:<input readonly id="sliderProgInput" size="5" value="1400"/>
+		</form>
+		<br>Errors: <span id="errors">?</span>
+		<br>Failures: <span id="failures">?</span>
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/form/test_TextBoxes.html b/dijit/tests/_BidiSupport/form/test_TextBoxes.html
index e171068..330cb45 100644
--- a/dijit/tests/_BidiSupport/form/test_TextBoxes.html
+++ b/dijit/tests/_BidiSupport/form/test_TextBoxes.html
@@ -4,42 +4,40 @@
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>TextBox with _BidiSupport</title>
-		
+
 		<style type="text/css">
 			@import "../../../../dijit/themes/tundra/tundra.css";
-			@import "../../../../dojo/resources/dojo.css";	
+			@import "../../../../dojo/resources/dojo.css";
 		</style>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true">
-		</script>		
-		
+			data-dojo-config="parseOnLoad: true, isDebug: true, has: { 'dojo-bidi': true }">
+		</script>
+
 		<script type="text/JavaScript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dijit.form.TextBox");
-			dojo.require("dijit._BidiSupport");
 			dojo.require("dojo.parser");
 		</script>
-		
+
 	</head>
 	<body class="tundra">
 		<label for="ltrTextBox" >
 			<b> I'm a LTR TexBox</b>
 		</label><br>
-		<input data-dojo-type="dijit.form.TextBox" id="ltrTextBox" data-dojo-props='name:"ltrTextBox", value:"", textDir:"ltr"'/>
+		<input data-dojo-type="dijit/form/TextBox" id="ltrTextBox" data-dojo-props='name:"ltrTextBox", value:"", textDir:"ltr"'/>
 
 		<br>
 		<label for="rtlTextBox" >
 			<b>I'm a RTL TexBox </b>
 		</label><br>
-		<input data-dojo-type="dijit.form.TextBox" id="rtlTextBox" data-dojo-props='name:"rtlTextBox", value:"",textDir:"rtl"'/>
-		
+		<input data-dojo-type="dijit/form/TextBox" id="rtlTextBox" data-dojo-props='name:"rtlTextBox", value:"",textDir:"rtl"'/>
+
 		<br>
 		<label for="contextualTextBox" >
 			<b> And I'm a suprising contextual TexBox!!! </b>
 		</label><br>
-		<input data-dojo-type="dijit.form.TextBox" id="contextualTextBox" data-dojo-props='name:"contextualTextBox", value:"",textDir:"auto"'/>
+		<input data-dojo-type="dijit/form/TextBox" id="contextualTextBox" data-dojo-props='name:"contextualTextBox", value:"",textDir:"auto"'/>
 
 		<br>
 		<br>
@@ -62,7 +60,7 @@
 					value: "created programatically with custom border, padding, margin! textDir=auto!",
 					style: {border:"5px solid gray", padding:"11px", margin:"7px"}
 				}, "programmatic1");
-				
+
 				programmaticTextBox2 = new dijit.form.TextBox({
 					id: "programmatic2",
 					name: "programmaticTextbox2",
@@ -71,7 +69,7 @@
 					style: {border:"5px solid gray", padding:"11px", margin:"7px"}
 				}, "programmatic2");
 
-				
+
 				programmaticTextBox3 = new dijit.form.TextBox({
 					id: "programmatic3",
 					name: "programmaticTextbox3",
diff --git a/dijit/tests/_BidiSupport/form/test_Textarea.html b/dijit/tests/_BidiSupport/form/test_Textarea.html
index 878f8c7..1ae5e89 100644
--- a/dijit/tests/_BidiSupport/form/test_Textarea.html
+++ b/dijit/tests/_BidiSupport/form/test_Textarea.html
@@ -2,7 +2,7 @@
 
 <html>
 	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">	
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Textarea with _BidiSupport</title>
 
 		<style type="text/css">
@@ -12,16 +12,13 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true">
-		</script>		
+			data-dojo-config="parseOnLoad: true, isDebug: true, has: { 'dojo-bidi': true }">
+		</script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.dijit");
 			dojo.require("dijit.form.Textarea");
-//			dojo.require("dijit.layout.ContentPane");
-//			dojo.require("dijit.layout.TabContainer");
 			dojo.require("dojo.parser");
-			dojo.require("dijit._BidiSupport");
 		</script>
 
 	</head>
@@ -30,25 +27,25 @@
 		<h2>Various dijit.form.Textarea widgets. Type something inside</h2>
 		<label for="blankL">dijit.form.Textarea, initially blank, textDir="ltr":</label>
 		<br>
-		<textarea data-dojo-type="dijit.form.Textarea" id="blankL" data-dojo-props='textDir:"ltr", style:{width:"50em"}'></textarea>
+		<textarea data-dojo-type="dijit/form/Textarea" id="blankL" data-dojo-props='textDir:"ltr", style:{width:"50em"}'></textarea>
 		<br>
 		<label for="blankR">dijit.form.Textarea, initially blank, textDir="rtl":</label>
 		<br>
-		<textarea data-dojo-type="dijit.form.Textarea" id="blankR" data-dojo-props='textDir:"rtl", style:{width:"50em"}'></textarea>
+		<textarea data-dojo-type="dijit/form/Textarea" id="blankR" data-dojo-props='textDir:"rtl", style:{width:"50em"}'></textarea>
 		<br>
 		<label for="blankA">dijit.form.Textarea, initially blank, textDir="auto":</label>
 		<br>
-		<textarea data-dojo-type="dijit.form.Textarea" id="blankA" data-dojo-props='textDir:"auto", style:{width:"50em"}'></textarea>
+		<textarea data-dojo-type="dijit/form/Textarea" id="blankA" data-dojo-props='textDir:"auto", style:{width:"50em"}'></textarea>
 		<br>
 
 		<label for="programmaticLTR">dijit.form.Textarea in TabContainer, programmatically created with custom styling:</label><br>
 
 		<label>textDir="ltr":</label>
 		<textarea id="programmaticLTR"></textarea><br>
-			
+
 		<label >textDir="rtl":</label>
 		<textarea id="programmaticRTL"></textarea><br>
-			
+
 		<label >textDir="auto":</label>
 		<textarea id="programmaticAuto"></textarea>
 
@@ -71,7 +68,7 @@
 					name: "programmaticTextAreaLTR",
 					cols: "60",
 					textDir:"ltr",
-					value: "created programatically!", 
+					value: "created programatically!",
 					style: "border:5px solid gray;padding:11px;margin:7px;"
 				}, "programmaticLTR");
 
@@ -99,7 +96,7 @@
 
 		<label for="largeTextAreaLTR">dijit.form.Textarea, initially full with English text <b>textDir = "ltr"</b>:</label>
 		<br>
-		<textarea data-dojo-type="dijit.form.Textarea" id="largeTextAreaLTR" data-dojo-props='name:"largeTextAreaLTR", 
+		<textarea data-dojo-type="dijit/form/Textarea" id="largeTextAreaLTR" data-dojo-props='name:"largeTextAreaLTR",
 			textDir:"ltr", style:{width:"50em"}'> This is a textarea with a LOT of content.
 
 Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril d [...]
@@ -113,9 +110,9 @@ This is the end.</textarea>
 		<br>
 		<label for="largeTextAreaRTL">dijit.form.Textarea, initially full with Hebrew text <b>textDir = "rtl"</b>:</label>
 		<br>
-		<textarea data-dojo-type="dijit.form.Textarea" id="largeTextAreaRTL" data-dojo-props='name:"largeTextAreaRTL", 
-			textDir:"rtl", style:{width:"50em"}'> זהו טקסט ארוך בעיברית!!!		
-		
+		<textarea data-dojo-type="dijit/form/Textarea" id="largeTextAreaRTL" data-dojo-props='name:"largeTextAreaRTL",
+			textDir:"rtl", style:{width:"50em"}'> זהו טקסט ארוך בעיברית!!!
+
 לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית סחטיר בלובק. תצטנפל בלינדו למר&# [...]
 
 לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית סחטיר בלובק. תצטנפל בלינדו למר&# [...]
diff --git a/dijit/tests/_BidiSupport/form/test_TimeTextBox.html b/dijit/tests/_BidiSupport/form/test_TimeTextBox.html
new file mode 100644
index 0000000..87715a2
--- /dev/null
+++ b/dijit/tests/_BidiSupport/form/test_TimeTextBox.html
@@ -0,0 +1,320 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Bidi TimeTextBox</title>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<style>
+		@import url(../../../themes/claro/document.css);
+		@import url(../../css/dijitTests.css);
+	</style>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+	<!-- only needed for alternate theme testing: -->
+	<script type="text/javascript" src="../../_testCommon.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/_base/array",
+			"dojo/dom-class",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/form/TimeTextBox",
+			"dojo/domReady!"
+		], function(doh, array, domClass, parser, registry, TimeTextBox){
+
+			doh.register("parse", function(){
+				return parser.parse();
+			});
+
+			function testWidget(element, guiDir, textDir, isfirstChildLatin){
+				doh.is(registry.byId(element).get("textDir"), textDir, "widget textDir");
+				doh.is(registry.byId(element).dir, guiDir, "GUI dir");
+				if(textDir == "auto"){
+					textDir = isfirstChildLatin? "ltr" : "rtl";
+				}
+				doh.is(registry.byId(element).focusNode.dir, textDir, "focusNode textDir");
+				doh[guiDir == "rtl" ? "t" : "f"](domClass.contains(registry.byId(element).domNode, "dijitTimeTextBoxRtl"), "dijitTimeTextBoxRtl");
+			}
+
+			function testDropDownList(widgetId){
+				var widget = registry.byId(widgetId);
+				widget.openDropDown();
+				var widgetTextDir = widget.get("textDir");
+				var itemTextDir = widgetTextDir;
+				var list = widget.dropDown.getChildren();
+				var correct = true;
+				array.forEach(list, function(child){
+					if(widgetTextDir == "auto"){
+						itemTextDir = widget._checkContextual(child.label.replace(/<[^>]*>/gm," "));
+					}
+					correct &= itemTextDir == child.textDirNode.dir;
+				});
+				widget.closeDropDown();
+				doh.t(correct, "child textDir");
+			}
+
+			doh.register("setup", function(){
+				//change textDir dynamically
+				var btnLtr = registry.byId("btn1");
+				btnLtr.on("click", function(){
+					registry.byId("q1").set("textDir", "ltr");
+
+				});
+				var btnRtl = registry.byId("btn2");
+				btnRtl.on("click", function(){
+					registry.byId("q1").set("textDir", "rtl");
+
+				});
+				var btnAuto = registry.byId("btn3");
+				btnAuto.on("click", function(){
+					registry.byId("q1").set("textDir", "auto");
+
+				});
+
+				var programmatic1 = new TimeTextBox({});
+				programmatic1.placeAt('testProgramatic1');
+				programmatic1.set("textDir",'ltr');
+
+				var programmatic2 = new TimeTextBox({});
+				programmatic2.placeAt('testProgramatic2');
+				programmatic2.set("textDir",'rtl');
+
+				var programmatic3 = new TimeTextBox({});
+				programmatic3.placeAt('testProgramatic3');
+				programmatic3.set("textDir",'auto');
+			});
+
+			doh.register("LTR GUI, LTR textDir", [
+				{
+					name:"textbox",
+					runTest:function(){
+						testWidget("q1", "ltr", "ltr", true);
+					}
+				},
+				{
+					name:"dropdown",
+					runTest:function(){
+						testDropDownList("q1");
+					}
+				}
+			]);
+
+			doh.register("LTR GUI, RTL textDir", [
+				{
+					name:"textbox",
+					runTest:function(){
+						testWidget("q2", "ltr", "rtl", true);
+					}
+				},
+				{
+					name:"dropdown",
+					runTest:function(){
+						testDropDownList("q2");
+					}
+				}
+			]);
+
+			doh.register("LTR GUI, auto textDir with LTR text", [
+				{
+					name:"textbox",
+					runTest:function(){
+						testWidget("q3", "ltr", "auto", true);
+					}
+				},
+				{
+					name:"dropdown",
+					runTest:function(){
+						testDropDownList("q3");
+					}
+				}
+			]);
+
+			doh.register("LTR GUI, auto textDir with RTL text", [
+				{
+					name:"textbox",
+					runTest:function(){
+						testWidget("q4", "ltr", "auto", false);
+					}
+				},
+				{
+					name:"dropdown",
+					runTest:function(){
+						testDropDownList("q4");
+					}
+				}
+			]);
+
+			doh.register("RTL GUI, LTR textDir", [
+				{
+					name:"textbox",
+					runTest:function(){
+						testWidget("q5", "rtl", "ltr", true);
+					}
+				},
+				{
+					name:"dropdown",
+					runTest:function(){
+						testDropDownList("q5");
+					}
+				}
+			]);
+
+			doh.register("RTL GUI, RTL textDir", [
+				{
+					name:"textbox",
+					runTest:function(){
+						testWidget("q6", "rtl", "rtl", true);
+					}
+				},
+				{
+					name:"dropdown",
+					runTest:function(){
+						testDropDownList("q6");
+					}
+				}
+			]);
+
+			doh.register("RTL GUI, auto textDir with LTR text", [
+				{
+					name:"textbox",
+					runTest:function(){
+						testWidget("q7", "rtl", "auto", true);
+					}
+				},
+				{
+					name:"dropdown",
+					runTest:function(){
+						testDropDownList("q7");
+					}
+				}
+			]);
+
+			doh.register("RTL GUI, auto textDir with RTL text", [
+				{
+					name:"textbox",
+					runTest:function(){
+						testWidget("q8", "rtl", "auto", false);
+					}
+				},
+				{
+					name:"dropdown",
+					runTest:function(){
+						testDropDownList("q8");
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+
+</head>
+<body class="claro">
+
+	<h1 class="testTitle">TimeTextBox</h1>
+	<br>
+	<table border="1">
+		<tr>
+			<td colspan="2" rowspan="2"></td>
+			<th colspan="4" align="right"><h2><div align=center><font size="5">Base text direction</font></div></h2></th>
+		</tr>
+		<tr>
+			<td>  <font size=4 color=red> LTR </font></td>
+			<td>  <font size=4 color=red> RTL </font></td>
+			<td>  <font size=4 color=red> Auto/LTR </font></td>
+			<td>  <font size=4 color=red> Auto/RTL </font></td>
+		</tr>
+		<tr>
+
+			<th rowspan="2" ><h2><div align=center><font size="5">GUI direction</font></div></h2></th>
+			<td >  <font size=4 color=blue>LTR</font></td>
+			<td>
+				<input dir="ltr" id="q1" data-dojo-type="dijit/form/TimeTextBox"
+					data-dojo-props='type:"text", name:"time1a", value:"T10:30:00", textDir:"ltr",
+					constraints:{formatLength:"short"},
+					required:true,
+					invalidMessage:"" '/>
+			</td>
+			<td>
+				<input dir="ltr" id="q2" data-dojo-type="dijit/form/TimeTextBox"
+					data-dojo-props='type:"text", name:"time1a", value:"T11:30:00", textDir:"rtl",
+					constraints:{formatLength:"short"},
+					required:true,
+					invalidMessage:"" '/>
+			</td>
+			<td>
+				<input dir="ltr" id="q3" data-dojo-type="dijit/form/TimeTextBox"
+					data-dojo-props='type:"text", name:"time1a", value:"T12:30:00", textDir:"auto",
+					constraints:{formatLength:"short"},
+					required:true,
+					invalidMessage:"" '/>
+			</td>
+			<td>
+				<input dir="ltr" id="q4" data-dojo-type="dijit/form/TimeTextBox"
+					data-dojo-props='type:"text", name:"time1a", value:"T12:30:00", textDir:"auto",
+					constraints:{formatLength:"short"},
+					lang:"ar",
+					required:true,
+					invalidMessage:"" '/>
+			</td>
+		</tr>
+		<tr>
+			<td >  <font size=4 color=blue>RTL</font></td>
+			<td>
+				<input dir="rtl" id="q5" data-dojo-type="dijit/form/TimeTextBox"
+					data-dojo-props='type:"text", name:"time1a", value:"T10:30:00", textDir:"ltr",
+					constraints:{formatLength:"short"},
+					required:true,
+					invalidMessage:"" '/>
+			</td>
+			<td>
+				<input dir="rtl" id="q6" data-dojo-type="dijit/form/TimeTextBox"
+					data-dojo-props='type:"text", name:"time1a", value:"T11:30:00", textDir:"rtl",
+					constraints:{formatLength:"short"},
+					required:true,
+					invalidMessage:"" '/>
+			</td>
+			<td>
+				<input dir="rtl" id="q7" data-dojo-type="dijit/form/TimeTextBox"
+					data-dojo-props='type:"text", name:"time1a", value:"T12:30:00", textDir:"auto",
+					constraints:{formatLength:"short"},
+					required:true,
+					invalidMessage:"" '/>
+			</td>
+			<td>
+				<input dir="rtl" id="q8" data-dojo-type="dijit/form/TimeTextBox"
+					data-dojo-props='type:"text", name:"time1a", value:"T12:30:00", textDir:"auto",
+					constraints:{formatLength:"short"},
+					lang:"ar",
+					required:true,
+					invalidMessage:"" '/>
+			</td>
+		</tr>
+	</table>
+
+	<br>
+
+	<h4 class="testSubtitle">Buttons to change BTD dynamically (for LTR-LTR cell)</h4><br>
+		<button data-dojo-type="dijit/form/Button" id="btn1" data-dojo-props='label:"Set textDir to ltr"'></button>
+		<button data-dojo-type="dijit/form/Button" id="btn2" data-dojo-props='label:"Set textDir to rtl"'></button>
+		<button data-dojo-type="dijit/form/Button" id="btn3" data-dojo-props='label:"Set textDir to auto"'></button>
+	<br>
+	<br>
+	<br>
+	<hr>
+	<h4 class="testSubtitle">Widgets created programmatically:</h4><br>
+
+	<span id="testProgramatic1">LTR: </span>
+	<span id="testProgramatic2">  RTL: </span>
+	<span id="testProgramatic3">  AUTO: </span>
+
+</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/inheritance/Inher-ComplexMarkupContainers.html b/dijit/tests/_BidiSupport/inheritance/Inher-ComplexMarkupContainers.html
index 2fcff89..bbb1a44 100644
--- a/dijit/tests/_BidiSupport/inheritance/Inher-ComplexMarkupContainers.html
+++ b/dijit/tests/_BidiSupport/inheritance/Inher-ComplexMarkupContainers.html
@@ -2,7 +2,7 @@
 
 <html data-dojo-textdir="rtl">
 	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">	
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>DOH complex inheritance test</title>
 
 		<style type="text/css">
@@ -12,11 +12,10 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="isDebug: true">
-		</script>		
-	 
+			data-dojo-config="isDebug: true, has: { 'dojo-bidi': true }">
+		</script>
+
 		<script type="text/javascript">
-			dojo.require("dijit.dijit"); 
 			dojo.require("dijit.layout.AccordionContainer");
 			dojo.require("dijit.layout.ContentPane");
 			dojo.require("dijit.layout.BorderContainer");
@@ -27,11 +26,9 @@
 			dojo.require("dijit.form.Textarea");
 			dojo.require("dijit.form.TextBox");
 			dojo.require("doh.runner");
-			
-			dojo.require("dijit._BidiSupport");
-			
+
 			dojo.ready(function(){
-			
+
 				doh.register("parse", function(){
 					dojo.parser.parse();
 				});
@@ -39,23 +36,23 @@
 				doh.register("before MarkupAccordion textBox", [
 					{
 						name: "text direction of 'beforeMarkupAccordion'",
-						
+
 						setUp: function(){
 							textBox = dijit.byId("beforeMarkupAccordion");
 						},
-						
+
 						runTest: function(){
 							doh.is("rtl",textBox.focusNode.dir,"direction of :" + textBox.id);
 							textBox.set('value','\u05e9\u05d9\u05de\u05d5\u05e9\u0020\u05d1\u05ea\u05d2\u05d9\u05d5\u05ea\u002e');
 							doh.is("rtl",textBox.focusNode.dir,"direction of :" + textBox.id);
 						}
 					}
-				]);				
-				
+				]);
+
 				doh.register("test 'A Simple Pane'.", [
 					{
 						name:"check combo textDir.",
-						
+
 						runTest:function(){
 							combo = dijit.byId("selectInPane");
 							doh.is("rtl", combo.textDir, combo.id);
@@ -86,7 +83,7 @@
 							doh.is("auto",cPane2.textDir,"'contentPane2' textDir");
 
 						}
-					},	
+					},
 					{
 						name: "textDir of textBoxes in the 'contentPane1' textDir='ltr'",
 
@@ -99,7 +96,7 @@
 							doh.is("ltr",input1.textDir,"'inputLHeb' textDir");
 							doh.is("ltr",input2.textDir,"'inputLEn' textDir");
 						}
-					},	
+					},
 					{
 						name: "textDir of textBoxes in the 'contentPane2' textDir='auto'",
 
@@ -111,13 +108,13 @@
 							doh.is("auto",selectA.textDir,"'selectA' textDir");
 							doh.is("auto",input1.textDir,"'inputAHeb' textDir");
 							doh.is("auto",input2.textDir,"'inputAEn' textDir");
-								
+
 							doh.is("",selectA.dir,"'selectA' dir");
 							doh.is("rtl",input1.focusNode.dir,"'inputAHeb' textDir");
 							doh.is("ltr",input2.focusNode.dir,"'inputAEn' textDir");
 						}
-					}				
-				]);	
+					}
+				]);
 
 				doh.register("test 'Tags & panes with TextBoxesAreas'", [
 					{
@@ -132,7 +129,7 @@
 							doh.is("rtl",dijit.byId("contentPane5").textDir,"'contentPane5' textDir");
 							doh.is("auto",dijit.byId("contentPane6").textDir,"'contentPane6' textDir");
 						}
-					},	
+					},
 					{
 						name: "textDir of textBoxes",
 
@@ -142,100 +139,100 @@
 
 							doh.is("auto",dijit.byId("autoSimpleTexarea").textDir,"'autoSimpleTexarea' textDir");
 							doh.is("rtl",dijit.byId("autoSimpleTexarea").focusNode.dir,"'autoSimpleTexarea' dir");
-							
+
 							doh.is("rtl",dijit.byId("rtlSimpleTexarea").textDir,"'rtlSimpleTexarea' textDir");
 							doh.is("rtl",dijit.byId("rtlSimpleTexarea").focusNode.dir,"'rtlSimpleTexarea' dir");
 
-						
+
 
 							doh.is("auto",dijit.byId("texarea1").textDir,"'texarea1' textDir");
 							doh.is("rtl",dijit.byId("texarea1").focusNode.dir,"'texarea1' dir");
-							
+
 							doh.is("auto",dijit.byId("texarea2").textDir,"'texarea2' textDir");
 							doh.is("ltr",dijit.byId("texarea2").focusNode.dir,"'texarea2' dir");
 						}
 					}
 				]);
 
-				doh.run();			
+				doh.run();
 			});
 		</script>
 
 	</head>
 	<body class="claro" data-dojo-textdir="rtl">
-	
+
 		<h1 class="testTitle">AccordionContainer Tests textDir="rtl" - defined in body tag.</h1>
 		<h2>Accordion from markup:</h2>
-							<input id="beforeMarkupAccordion" data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"ltrMSimpleTexarea",
+							<input id="beforeMarkupAccordion" data-dojo-type="dijit/form/TextBox" data-dojo-props='name:"ltrMSimpleTexarea",
 							value:"Markup Testing.", rows:"1", cols:"20"'/>
 
-		<div id="markupAccordion" data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props='style:"width:500px; height:600px; overflow:hidden"' >
-			<div id="pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:"true",	title:"A Simple Pane"'>
-				<select id= "selectInPane" data-dojo-type="dijit.form.FilteringSelect">
+		<div id="markupAccordion" data-dojo-type="dijit/layout/AccordionContainer" data-dojo-props='style:"width:500px; height:600px; overflow:hidden"' >
+			<div id="pane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='selected:"true",	title:"A Simple Pane"'>
+				<select id= "selectInPane" data-dojo-type="dijit/form/FilteringSelect">
 					<option value="1">foo.</option>
 					<option value="2">בר.</option>
 					<option value="3">baz.</option>
 				</select>
 				<p>
-					<input id="simpleTextbox" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"שלום!"'/>
+					<input id="simpleTextbox" data-dojo-type="dijit/form/TextBox" data-dojo-props='value:"שלום!"'/>
 				</p>
 			</div>
-			
+
 			<div data-dojo-textdir="auto">
-				<div id="borderContainerPane" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='title:"BorderContainer Pane"'>
-					<div id="contentPane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:50%", splitter:"true", textDir:"ltr"'>
+				<div id="borderContainerPane" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='title:"BorderContainer Pane"'>
+					<div id="contentPane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width:50%", splitter:"true", textDir:"ltr"'>
 						<p>
 							This Pane ovverrides the body defined textDir="rtl" to textDir="ltr".
 							See some examples:
 						</p>
-						<select id="selectL" data-dojo-type="dijit.form.FilteringSelect">
+						<select id="selectL" data-dojo-type="dijit/form/FilteringSelect">
 							<option value="1">foo.</option>
 							<option value="2">בר.</option>
 							<option value="3">baz.</option>
 						</select>
 						<p>
-							<input id="inputLHeb" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"שלום!"'/> 
+							<input id="inputLHeb" data-dojo-type="dijit/form/TextBox" data-dojo-props='value:"שלום!"'/>
 						</p>
 						<p>
-							<input id="inputLEn" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"Hello!"'/>
+							<input id="inputLEn" data-dojo-type="dijit/form/TextBox" data-dojo-props='value:"Hello!"'/>
 						</p>
 					</div>
-					<div id="contentPane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+					<div id="contentPane2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 						<p>
 							This Pane inherits its textDir from the dijit.layout.BorderContainer, and now textDir="auto".
 							See some examples:
 						</p>
-						<select id="selectA" data-dojo-type="dijit.form.FilteringSelect">
+						<select id="selectA" data-dojo-type="dijit/form/FilteringSelect">
 							<option value="1">foo.</option>
 							<option value="2">בר.</option>
 							<option value="3">baz.</option>
 						</select>
 						<p>
-							<input id="inputAHeb" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"שלום!"'/> 
+							<input id="inputAHeb" data-dojo-type="dijit/form/TextBox" data-dojo-props='value:"שלום!"'/>
 						</p>
 						<p>
-							<input id="inputAEn" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"Hello!"'/>
+							<input id="inputAEn" data-dojo-type="dijit/form/TextBox" data-dojo-props='value:"Hello!"'/>
 						</p>
 					</div>
 				</div>
 			</div>
 
-			<div id="embeddedLayoutPane" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tags & panes with TextBoxesAreas",
+			<div id="embeddedLayoutPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tags & panes with TextBoxesAreas",
 				textDir:"auto"'>
 				<p>
 					Here's a BorderContainer: textDir= contextual
 				</p>
 				<div data-dojo-textdir="ltr">
 					<div id="bContainer" data-dojo-type ="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px" '>
-						<div id="contentPane3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:125px", splitter:"true"'>
+						<div id="contentPane3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width:125px", splitter:"true"'>
 							Left Pane:
-							<textarea id="ltrSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"ltrSimpleTexarea",
+							<textarea id="ltrSimpleTexarea" data-dojo-type="dijit/form/SimpleTextarea" data-dojo-props='name:"ltrSimpleTexarea",
 								rows:"8", cols:"13"'> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt.
 							</textarea>
 						</div>
-						<div id="contentPane4" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center",textDir:"auto"'>
+						<div id="contentPane4" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center",textDir:"auto"'>
 							Right Pane:
-							<textarea id="autoSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"autoSimpleTexarea", rows:"8", cols:"13"
+							<textarea id="autoSimpleTexarea" data-dojo-type="dijit/form/SimpleTextarea" data-dojo-props='name:"autoSimpleTexarea", rows:"8", cols:"13"
 								'> לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית מוסן מנת.
 							</textarea>
 						</div>
@@ -244,15 +241,15 @@
 				<p>
 					And a TabContainer:
 				</p>
-				<div id="tContainer" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:170px; width:450px"' >
-					<div id="contentPane5" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1 textDir=rtl", textDir:"rtl"'>
-						<textarea id="rtlSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"rtlSimpleTexarea", 
+				<div id="tContainer" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"height:170px; width:450px"' >
+					<div id="contentPane5" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1 textDir=rtl", textDir:"rtl"'>
+						<textarea id="rtlSimpleTexarea" data-dojo-type="dijit/form/SimpleTextarea" data-dojo-props='name:"rtlSimpleTexarea",
 							rows:"4", cols:"15" '>jhkjkh.</textarea>
 					</div>
-					<div id="contentPane6" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2 textDir=inherited from ContentPane"' >
-						<textarea id="texarea1" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"texarea1", rows:"4", cols:"14"
+					<div id="contentPane6" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2 textDir=inherited from ContentPane"' >
+						<textarea id="texarea1" data-dojo-type="dijit/form/Textarea" data-dojo-props='name:"texarea1", rows:"4", cols:"14"
 							'>מבחן.</textarea>
-						<textarea id="texarea2" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"texarea2", rows:"4", cols:"14"
+						<textarea id="texarea2" data-dojo-type="dijit/form/Textarea" data-dojo-props='name:"texarea2", rows:"4", cols:"14"
 							'>Test.</textarea>
 					</div>
 				</div>
diff --git a/dijit/tests/_BidiSupport/inheritance/Inher-MarkupContainers.html b/dijit/tests/_BidiSupport/inheritance/Inher-MarkupContainers.html
index 38aa84b..7cedae8 100644
--- a/dijit/tests/_BidiSupport/inheritance/Inher-MarkupContainers.html
+++ b/dijit/tests/_BidiSupport/inheritance/Inher-MarkupContainers.html
@@ -2,7 +2,7 @@
 
 <html>
 	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">	
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>DOH markup containers simple inheritance</title>
 
 		<style type="text/css">
@@ -12,11 +12,10 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="isDebug: true">
-		</script>		
-		
+			data-dojo-config="isDebug: true, has: { 'dojo-bidi': true }">
+		</script>
+
 		<script type="text/javascript">
-			dojo.require("dijit._BidiSupport");
 			dojo.require("dijit.form.TextBox");
 			dojo.require("dijit.form.ComboBox");
 			dojo.require("dijit.layout.AccordionContainer");
@@ -32,56 +31,56 @@
 				doh.register("parse", function(){
 					dojo.parser.parse();
 				});
-			
+
 				doh.register("dijit.tests._BidiSupport.inheritance.Inher-MarkupContainers", [
 					function test_ltrFilterSelectInheritAccordion(){
 						dijit.byId("filter1").set("value","1");
-						doh.is("ltr", dijit.byId("filter1").focusNode.dir, "option 1 of filter1"); 
+						doh.is("ltr", dijit.byId("filter1").focusNode.dir, "option 1 of filter1");
 					},
 					function test_rtlFilterSelectInheritAccordion(){
-						dijit.byId("filter1").set("value","2"); 
-						doh.is("rtl", dijit.byId("filter1").focusNode.dir, "option 2 of filter1"); 
+						dijit.byId("filter1").set("value","2");
+						doh.is("rtl", dijit.byId("filter1").focusNode.dir, "option 2 of filter1");
 					},
 					function test_ltrTextareaInheritPane1(){
-						dijit.byId("ltrTextBox1").set("value","Hello!!"); 
-						doh.is("ltr", dijit.byId("ltrTextBox1").focusNode.dir,"ltrTextBox1 : Hello!!"); 
+						dijit.byId("ltrTextBox1").set("value","Hello!!");
+						doh.is("ltr", dijit.byId("ltrTextBox1").focusNode.dir,"ltrTextBox1 : Hello!!");
 					},
 					function test_ltrTextareaInheritPane2(){
-						dijit.byId("ltrTextBox1").set("value","\u05e9\u05dc\u05d5\u05dd\u0021\u0021"); 
-						doh.is("ltr", dijit.byId("ltrTextBox1").focusNode.dir,"ltrTextBox1: \u05e9\u05dc\u05d5\u05dd\u0021\u0021"); 
+						dijit.byId("ltrTextBox1").set("value","\u05e9\u05dc\u05d5\u05dd\u0021\u0021");
+						doh.is("ltr", dijit.byId("ltrTextBox1").focusNode.dir,"ltrTextBox1: \u05e9\u05dc\u05d5\u05dd\u0021\u0021");
 					},
 					function test_autoComboBoxInheritTableLtr(){
-						dijit.byId("autoTextBox1").set("value","Hello!!"); 
-						doh.is("ltr", dijit.byId("autoTextBox1").focusNode.dir,"autoTextBox1: Hello!!"); 
+						dijit.byId("autoTextBox1").set("value","Hello!!");
+						doh.is("ltr", dijit.byId("autoTextBox1").focusNode.dir,"autoTextBox1: Hello!!");
 					},
 					function test_autoComboBoxInheritTableRtl(){
-						dijit.byId("autoTextBox1").set("value","\u05e9\u05dc\u05d5\u05dd\u0021\u0021"); 
-						doh.is("rtl", dijit.byId("autoTextBox1").focusNode.dir,"autoTextBox1: \u05e9\u05dc\u05d5\u05dd\u0021\u0021"); 
+						dijit.byId("autoTextBox1").set("value","\u05e9\u05dc\u05d5\u05dd\u0021\u0021");
+						doh.is("rtl", dijit.byId("autoTextBox1").focusNode.dir,"autoTextBox1: \u05e9\u05dc\u05d5\u05dd\u0021\u0021");
 					},
 					function test_rtlTextareaInheritPane1(){
-						dijit.byId("rtlTextBox1").set("value","\u05e9\u05dc\u05d5\u05dd\u0021\u0021"); 
-						doh.is("rtl", dijit.byId("rtlTextBox1").focusNode.dir,"rtlTextBox1: \u05e9\u05dc\u05d5\u05dd\u0021\u0021"); 
+						dijit.byId("rtlTextBox1").set("value","\u05e9\u05dc\u05d5\u05dd\u0021\u0021");
+						doh.is("rtl", dijit.byId("rtlTextBox1").focusNode.dir,"rtlTextBox1: \u05e9\u05dc\u05d5\u05dd\u0021\u0021");
 					},
 					function test_rtlTextareaInheritPane2(){
-						dijit.byId("rtlTextBox1").set("value","\u05e9\u05dc\u05d5\u05dd\u0021\u0021"); 
-						doh.is("rtl", dijit.byId("rtlTextBox1").focusNode.dir,"rtlTextBox1: \u05e9\u05dc\u05d5\u05dd\u0021\u0021"); 
+						dijit.byId("rtlTextBox1").set("value","\u05e9\u05dc\u05d5\u05dd\u0021\u0021");
+						doh.is("rtl", dijit.byId("rtlTextBox1").focusNode.dir,"rtlTextBox1: \u05e9\u05dc\u05d5\u05dd\u0021\u0021");
 					},
 					function test_autoSimpleTextareaInheritPane1(){
-						doh.is("ltr", dijit.byId("ltrSimpleTexarea").focusNode.dir, "ltrSimpleTexarea: ltrSimpleTexarea"); 
+						doh.is("ltr", dijit.byId("ltrSimpleTexarea").focusNode.dir, "ltrSimpleTexarea: ltrSimpleTexarea");
 					},
 					function test_autoSimpleTextareaInheritPane2(){
-						doh.is("rtl", dijit.byId("autoSimpleTexarea").focusNode.dir, "autoSimpleTexarea: autoSimpleTexarea"); 
+						doh.is("rtl", dijit.byId("autoSimpleTexarea").focusNode.dir, "autoSimpleTexarea: autoSimpleTexarea");
 					},
 					function test_RtrSimpleTexBoxInheritTabContainer(){
-						doh.is("rtl", dijit.byId("rtlSimpleTexarea").focusNode.dir, "rtlSimpleTexarea"); 
+						doh.is("rtl", dijit.byId("rtlSimpleTexarea").focusNode.dir, "rtlSimpleTexarea");
 						dijit.byId("rtlSimpleTexarea").set("value","Hello!!");
-						doh.is("rtl", dijit.byId("rtlSimpleTexarea").focusNode.dir,"rtlSimpleTexarea: Hello!!"); 
+						doh.is("rtl", dijit.byId("rtlSimpleTexarea").focusNode.dir,"rtlSimpleTexarea: Hello!!");
 					},
 					function test_autoSimpleTexBoxInheritTabContainersPaneRtl(){
-						doh.is("rtl", dijit.byId("ltrTexarea").focusNode.dir, "ltrTexarea"); 
+						doh.is("rtl", dijit.byId("ltrTexarea").focusNode.dir, "ltrTexarea");
 					},
 					function test_autoSimpleTexBoxInheritTabContainersPaneRtl(){
-						doh.is("ltr", dijit.byId("trTexarea").focusNode.dir, "trTexarea"); 
+						doh.is("ltr", dijit.byId("trTexarea").focusNode.dir, "trTexarea");
 					}
 				]);
 
@@ -90,43 +89,43 @@
 		</script>
 	</head>
 	<body class="tundra" data-dojo-textdir="rtl" >
-		<div id="markupAccordion" data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props='style:"width:400px; height:300px;", textDir :"auto"' data-dojo-textdir="auto">
-			
-			<div data-dojo-type="dijit.layout.BorderContainer" id="borderContainerPane" data-dojo-props=' textDir:"rtl",title:"BorderContainer Pane"' data-dojo-textdir="rtl">
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true, textDir:"ltr"'>
-					<input id="ltrTextBox1" data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"ltrTextBox1", type:"text", value:""'/>
+		<div id="markupAccordion" data-dojo-type="dijit/layout/AccordionContainer" data-dojo-props='style:"width:400px; height:300px;", textDir :"auto"' data-dojo-textdir="auto">
+
+			<div data-dojo-type="dijit/layout/BorderContainer" id="borderContainerPane" data-dojo-props=' textDir:"rtl",title:"BorderContainer Pane"' data-dojo-textdir="rtl">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true, textDir:"ltr"'>
+					<input id="ltrTextBox1" data-dojo-type="dijit/form/TextBox" data-dojo-props='name:"ltrTextBox1", type:"text", value:""'/>
 				</div>
-			
-				<div data-dojo-type="dijit.layout.ContentPane"data-dojo-props='region:"center"' data-dojo-textdir="auto" >
-					<input id="autoTextBox1" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"autoTextBox1", value:""'/>			
+
+				<div data-dojo-type="dijit/layout/ContentPane"data-dojo-props='region:"center"' data-dojo-textdir="auto" >
+					<input id="autoTextBox1" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"text", name:"autoTextBox1", value:""'/>
 				</div>
-			
-				<input id="rtlTextBox1" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"rtlTextBox1", value:""'/>
+
+				<input id="rtlTextBox1" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"text", name:"rtlTextBox1", value:""'/>
 			</div>
-		
 
-			<div id="pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:"true", title:"A Simple Pane"'>
-				<select data-dojo-type="dijit.form.FilteringSelect" id="filter1">
+
+			<div id="pane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='selected:"true", title:"A Simple Pane"'>
+				<select data-dojo-type="dijit/form/FilteringSelect" id="filter1">
 					<option value="1" selected>foo.</option>
 					<option value="2">בר.</option>
 					<option value="3">baz.</option>
 				</select>
 			</div>
 
-			<div data-dojo-type="dijit.layout.ContentPane" id="embeddedLayoutPane" data-dojo-props='title:"Tags & panes with TextBoxesAreas"'>
+			<div data-dojo-type="dijit/layout/ContentPane" id="embeddedLayoutPane" data-dojo-props='title:"Tags & panes with TextBoxesAreas"'>
 				<p>
 					Here's a BorderContainer: textDir= contextual
 				</p>
-				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px", textDir :"auto"' data-dojo-textdir="auto">
-					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:125px", splitter:"true"'>
+				<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='style:"height:200px; width:300px", textDir :"auto"' data-dojo-textdir="auto">
+					<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width:125px", splitter:"true"'>
 						Left Pane:
-						<textarea id="ltrSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"ltrSimpleTexarea", rows:"8", cols:"13"
+						<textarea id="ltrSimpleTexarea" data-dojo-type="dijit/form/SimpleTextarea" data-dojo-props='name:"ltrSimpleTexarea", rows:"8", cols:"13"
 							'> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt.
 						</textarea>
 					</div>
-					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+					<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 						Right Pane:
-						<textarea id="autoSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"autoSimpleTexarea", rows:"8", cols:"13"
+						<textarea id="autoSimpleTexarea" data-dojo-type="dijit/form/SimpleTextarea" data-dojo-props='name:"autoSimpleTexarea", rows:"8", cols:"13"
 							'> לורם איפסום דולור סיט אמט, קונסקטורר אדיפיסינג אלית מוסן מנת.
 						</textarea>
 					</div>
@@ -134,17 +133,17 @@
 				<p>
 					And a TabContainer:
 				</p>
-				<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px", textDir:"rtl"' data-dojo-textdir="rtl">
-					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1 textDir=rtl" ' >
-						<textarea id="rtlSimpleTexarea" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"rtlSimpleTexarea", rows:"4", cols:"15"
+				<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"height:200px; width:300px", textDir:"rtl"' data-dojo-textdir="rtl">
+					<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1 textDir=rtl" ' >
+						<textarea id="rtlSimpleTexarea" data-dojo-type="dijit/form/SimpleTextarea" data-dojo-props='name:"rtlSimpleTexarea", rows:"4", cols:"15"
 							'>לורם איפסום.
 						</textarea>
 					</div>
-					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2 textDir=inherited"' data-dojo-textdir="auto">
-						<textarea id="ltrTexarea" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"ltrTexarea", rows:"4", cols:"14"
+					<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2 textDir=inherited"' data-dojo-textdir="auto">
+						<textarea id="ltrTexarea" data-dojo-type="dijit/form/Textarea" data-dojo-props='name:"ltrTexarea", rows:"4", cols:"14"
 							'>מבחן.
 						</textarea>
-						<textarea id="trTexarea" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"trTexarea", rows:"4", cols:"14"
+						<textarea id="trTexarea" data-dojo-type="dijit/form/Textarea" data-dojo-props='name:"trTexarea", rows:"4", cols:"14"
 							'>Test.
 						</textarea>
 					</div>
diff --git a/dijit/tests/_BidiSupport/inheritance/Inher-Simple.html b/dijit/tests/_BidiSupport/inheritance/Inher-Simple.html
index f415b8a..1c23213 100644
--- a/dijit/tests/_BidiSupport/inheritance/Inher-Simple.html
+++ b/dijit/tests/_BidiSupport/inheritance/Inher-Simple.html
@@ -2,7 +2,7 @@
 
 <html>
 	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">	
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>DOH simple inheritance textDir Tests</title>
 
 		<style type="text/css">
@@ -12,13 +12,12 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="isDebug: true">
-		</script>		
-		
+			data-dojo-config="isDebug: true, has: { 'dojo-bidi': true }">
+		</script>
+
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("doh.runner");
-			dojo.require("dijit._BidiSupport");
 			dojo.require("dijit.form.TextBox");
 			dojo.require("dijit.form.ComboBox");
 
@@ -27,31 +26,31 @@
 				doh.register("parse", function(){
 					dojo.parser.parse();
 				});
-				
+
 				doh.register("dijit.tests._BidiSupport.inheritance.Inher-Simple", [
-				 
+
 					function test_ltrTextBoxInheritFromDiv(){
-						doh.is("ltr", dijit.byId("ltrTextBox").focusNode.dir,"ltrTextBox"); 
+						doh.is("ltr", dijit.byId("ltrTextBox").focusNode.dir,"ltrTextBox");
 					},
 					function test_rtlTextBoxInheritBody(){
-						doh.is("rtl", dijit.byId("rtlTextBox").focusNode.dir, "rtlTextBox"); 
+						doh.is("rtl", dijit.byId("rtlTextBox").focusNode.dir, "rtlTextBox");
 					},
 					function test_ltrComboBoxInheritTable(){
-						doh.is("ltr", dijit.byId("fruitLtr").focusNode.dir, "fruitLtr"); 
+						doh.is("ltr", dijit.byId("fruitLtr").focusNode.dir, "fruitLtr");
 					},
 					function test_rtlComboBoxInheritTable(){
-						doh.is("rtl", dijit.byId("fruitRtl").focusNode.dir, "fruitRtl"); 
+						doh.is("rtl", dijit.byId("fruitRtl").focusNode.dir, "fruitRtl");
 					},
 					function test_autoComboBoxInheritTableLtr(){
 						dijit.byId("autoTextBox").set("value","Hello!!");
-						doh.is("ltr", dijit.byId("autoTextBox").focusNode.dir, "autoTextBox: Hello!!"); 
+						doh.is("ltr", dijit.byId("autoTextBox").focusNode.dir, "autoTextBox: Hello!!");
 					},
 					function test_autoComboBoxInheritTableRtl(){
 						dijit.byId("autoTextBox").set("value","\u05e9\u05dc\u05d5\u05dd\u0021\u0021");
-						doh.is("rtl", dijit.byId("autoTextBox").focusNode.dir, "autoTextBox: \u05e9\u05dc\u05d5\u05dd\u0021\u0021"); 
+						doh.is("rtl", dijit.byId("autoTextBox").focusNode.dir, "autoTextBox: \u05e9\u05dc\u05d5\u05dd\u0021\u0021");
 					}
 				]);
-				
+
 				doh.run();
 			});
 		</script>
@@ -64,30 +63,30 @@
 						<label for="ltrTextBox" >
 							<b>I'm a LTR TexBox </b>
 						</label>
-						<input data-dojo-type="dijit.form.TextBox" id="ltrTextBox" data-dojo-props='name:"ltrTextBox", value:"", type:"text"'/>
+						<input data-dojo-type="dijit/form/TextBox" id="ltrTextBox" data-dojo-props='name:"ltrTextBox", value:"", type:"text"'/>
 					</div>
 				</td>
-			</tr>		
+			</tr>
 			<tr>
 				<td>
 					<label for="autoTextBox" >
 						<b>I'm a Auto TexBox </b>
 					</label>
-					<input data-dojo-type="dijit.form.TextBox" id="autoTextBox" data-dojo-props='name:"autoTextBox", value:"",type:"text"'/>
+					<input data-dojo-type="dijit/form/TextBox" id="autoTextBox" data-dojo-props='name:"autoTextBox", value:"",type:"text"'/>
 				</td>
 			</tr>
 			<tr>
 				<td>
-					<select id="fruitLtr" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"fruitLtr"'>
+					<select id="fruitLtr" data-dojo-type="dijit/form/ComboBox" data-dojo-props='name:"fruitLtr"'>
 						<option >Apples!</option>
 						<option >Oranges!</option>
 						<option selected>Pears!</option>
 					</select>
 				</td>
-			</tr>		
+			</tr>
 			<tr>
 				<td>
-					<select id="fruitRtl" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"fruitRtr"'>
+					<select id="fruitRtl" data-dojo-type="dijit/form/ComboBox" data-dojo-props='name:"fruitRtr"'>
 						<option >תפוחים.</option>
 						<option >אגסים.</option>
 						<option selected>אפרסקים.</option>
@@ -95,10 +94,10 @@
 				</td>
 			</tr>
 		</table>
-		
+
 		<label for="rtlTextBox" >
 			<b>I'm a RTL TexBox </b>
 		</label>
-		<input data-dojo-type="dijit.form.TextBox" id="rtlTextBox" data-dojo-props='name:"rtlTextBox", value:"", type:"text"'/>
+		<input data-dojo-type="dijit/form/TextBox" id="rtlTextBox" data-dojo-props='name:"rtlTextBox", value:"", type:"text"'/>
 	</body>
 </html>
diff --git a/dijit/tests/_BidiSupport/inheritance/module.js b/dijit/tests/_BidiSupport/inheritance/module.js
index d1907d4..1fda763 100644
--- a/dijit/tests/_BidiSupport/inheritance/module.js
+++ b/dijit/tests/_BidiSupport/inheritance/module.js
@@ -1,15 +1,9 @@
-dojo.provide("dijit.tests._BidiSupport.inheritance.module");
+define(["doh/main", "require"], function(doh, require){
 
-try{
+	doh.register("_BidiSupport.inheritance.Inher-Simple", require.toUrl("./Inher-Simple.html"));
 
-	doh.registerUrl("dijit.tests._BidiSupport.inheritance.Inher-Simple", dojo.moduleUrl("dijit", "tests/_BidiSupport/inheritance/Inher-Simple.html"));
- 
-	doh.registerUrl("dijit.tests._BidiSupport.inheritance.Inher-MarkupContainers", dojo.moduleUrl("dijit", "tests/_BidiSupport/inheritance/Inher-MarkupContainers.html"));	
+	doh.register("_BidiSupport.inheritance.Inher-MarkupContainers", require.toUrl("./Inher-MarkupContainers.html"));
 
-	doh.registerUrl("dijit.tests._BidiSupport.inheritance.Inher-ComplexMarkupContainers", dojo.moduleUrl("dijit", "tests/_BidiSupport/inheritance/Inher-ComplexMarkupContainers.html"));
+	doh.register("_BidiSupport.inheritance.Inher-ComplexMarkupContainers", require.toUrl("./Inher-ComplexMarkupContainers.html"));
 
-}catch(e){
-
-	doh.debug(e);
-
-}
+});
diff --git a/dijit/tests/_BidiSupport/layout/AccordionContainer.html b/dijit/tests/_BidiSupport/layout/AccordionContainer.html
new file mode 100644
index 0000000..9a09d4e
--- /dev/null
+++ b/dijit/tests/_BidiSupport/layout/AccordionContainer.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Accordion Widget Demo</title>
+
+	<!-- only needed for test files: -->
+	<style type="text/css">
+		@import "../../../themes/claro/document.css";
+		@import "../../css/dijitTests.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="async: true, isDebug: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/dom",
+			"dojo/parser",
+			"dojo/query",
+			"dijit/registry",
+			"dijit/layout/AccordionContainer",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dojo/domReady!"
+		], function(doh, dom, parser, query, registry, ContentPane){
+
+			doh.register("parse", function(){
+				return parser.parse();
+			});
+
+			doh.register("tests._BidiSupport.layout.Accordion.Bidi", [
+				{
+					name: "Accordion Bidi",
+					runTest: function(){
+						query("span.dijitAccordionText").forEach(function(node, index, arr){
+							if(registry.getEnclosingWidget(node).textDir !== 'auto') {
+								doh.is(node.dir, registry.getEnclosingWidget(node).textDir, "tab button direction should coincide with widget's 'textDir'");
+							}
+						});
+					}
+				}
+			]);
+
+			doh.register("log", function(){
+				dom.byId('failures').innerHTML = doh._failureCount;
+				dom.byId('errors').innerHTML = doh._errorCount;
+			});
+
+			doh.run();
+		});
+	</script>
+
+</head>
+<body class="claro" style="padding: 50px;">
+
+	<h1 class="testTitle">Bidi Accordion Container Test</h1>
+
+	<div id="markupAccordion" data-dojo-type="dijit/layout/AccordionContainer" data-dojo-props='textDir:"rtl", style:"width: 300px; height: 200px; overflow: hidden"'>
+		<div id="Pane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='selected:true,textDir:"ltr",
+			title:"Explicit LTR!", iconClass:"dijitEditorIcon dijitEditorIconSave", tooltip:"Explicit LTR!" '>
+				<p>Explicit LTR text direction of content pane</p>
+		</div>
+
+		<div id="borderContainerPane" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='title:"Inherited RTL!", tooltip:"Inherited RTL!",iconClass:"dijitEditorIcon dijitEditorIconPaste"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width:50%", splitter:true'>
+			Inherited RTL title text direction of accordion button.
+			</div>
+		</div>
+
+		<div id="embeddedLayoutPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='textDir:"auto", title:"אExplicit AUTO!", tooltip:"אExplicit AUTO!",iconClass:"dijitEditorIcon dijitEditorIconCut"'>
+			<p>Explicit 'auto' text direction of content pane</p>
+		</div>
+	</div>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>
+</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/layout/StackContainer.html b/dijit/tests/_BidiSupport/layout/StackContainer.html
new file mode 100644
index 0000000..c8dbc55
--- /dev/null
+++ b/dijit/tests/_BidiSupport/layout/StackContainer.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>StackContainer Demo</title>
+
+	<style>
+		@import "../../../themes/claro/document.css";
+		@import "../../css/dijitTests.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="async: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/dom",
+			"dojo/parser",
+			"dojo/query",
+			"dijit/registry",
+			"dijit/layout/StackController",
+			"dijit/layout/ContentPane",
+			"dojo/domReady!"
+		], function(doh, dom, parser, query, registry){
+
+			doh.register("parse", function(){
+				return parser.parse();
+			});
+
+			doh.register("tests._BidiSupport.layout.StackContainer.Bidi", [
+				{
+					name: "StackContainer Bidi",
+					runTest: function(){
+						query("span.dijitButtonText").forEach(function(node, index, arr){
+							if(registry.getEnclosingWidget(node).textDir !== 'auto') {
+								doh.is(node.dir, registry.getEnclosingWidget(node).textDir, "tab button direction should coinside with widget's 'textDir'");
+							}
+						});
+					}
+				}
+			]);
+
+			doh.register("log", function(){
+				dom.byId('failures').innerHTML = doh._failureCount;
+				dom.byId('errors').innerHTML = doh._errorCount;
+			});
+
+			doh.run();
+		});
+	</script>
+</head>
+
+<body class="claro">
+	<h1 class="testTitle">Bidi RTL stack container</h1>
+	<span data-dojo-type="dijit/layout/StackController" data-dojo-props='containerId:"stackContainer"'></span>
+	<div id="stackContainer" data-dojo-type="dijit/layout/StackContainer"
+		data-dojo-props='textDir:"rtl", style:"width: 90%; border: 1px solid #9b9b9b; height: 6em; margin: 0.5em 0 0.5em 0; padding: 0.5em;"'>
+		<p id="page1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='textDir:"ltr",title:"Explicit LTR!"'>Explicit LTR text direction of content pane</p>
+		<p id="page2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Inherited RTL!"'>Inherited RTL title text direction of stack button</p>
+		<p id="page3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='textDir:"auto",title:"אExplicit AUTO!"'>Explicit 'auto' text direction of content pane</p>
+	</div>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>
+</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/layout/TabContainer.html b/dijit/tests/_BidiSupport/layout/TabContainer.html
new file mode 100644
index 0000000..a4e4821
--- /dev/null
+++ b/dijit/tests/_BidiSupport/layout/TabContainer.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>TabContainer BIDI DOH Test</title>
+
+	<style>
+		@import "../../../themes/claro/document.css";
+		@import "../../css/dijitTests.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="async: true,isDebug: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/dom",
+			"dojo/parser",
+			"dojo/query",
+			"dijit/registry",
+			"dijit/layout/TabContainer",
+			"dijit/layout/ContentPane",
+			"dojo/domReady!"
+		], function(doh, dom, parser, query, registry, TabContainer, ContentPane){
+
+			doh.register("parse", function(){
+				return parser.parse();
+			});
+
+			doh.register("tests._BidiSupport.layout.TabContainer.Bidi", [
+				{
+					name: 'changing Tabs',
+					runTest: function(){
+						var tc = registry.byId("tc1");
+						var cp = new ContentPane({
+							id: "newTab1",
+							title: "Added Panel,RTL textDir !",
+							content: "Added content pane with RTL textDir",
+							textDir: "rtl"
+						});
+						tc.addChild(cp);
+
+						var t1 = registry.byId('t1');
+						t1.set('title', 'LTR panel,changed title!');
+
+						var tc1 = registry.byId("tc1");
+						children = tc1.getChildren();
+						children[1].set({
+							title: "Panel with no direction,changed title!"
+						});
+
+						doh.is('ltr', query("#tc1_tablist_t1")[0].dir, "Pane have explicit LTR text direction");
+						doh.is('rtl', query("#tc1_tablist_t2")[0].dir, "Pane inherits RTL text direction from container");
+						doh.is('ltr', query("#tc1_tablist_t3")[0].dir, "Pane have explicit LTR text direction");
+						doh.is('rtl', query("#tc1_tablist_t4")[0].dir, "Pane inherits RTL text direction from container");
+						doh.is('rtl', query("#tc1_tablist_newTab1")[0].dir, "Added pane have explicit 'Auto' text direction");
+						doh.is('rtl', query("#tc3_tablist_three")[0].dir, "Pane have explicit RTL text direction");
+						doh.is('rtl', query("#tc3_tablist_four")[0].dir, "Pane have explicit RTL text direction");
+					}
+				}
+			]);
+
+			doh.register("testingMenu", {
+				name: "Test menu",
+				runTest: function(){
+					var menuBtn = registry.byId("tc1_tablist_menuBtn");
+					menuBtn.toggleDropDown();
+					var menu = registry.byId("tc1_menu");
+					doh.is('ltr', menu.getChildren()[0].textDirNode.dir, "Menu item should have LTR text direction");
+					doh.is('rtl', menu.getChildren()[1].textDirNode.dir, "Menu item should have RTL text direction 1");
+					doh.is('ltr', menu.getChildren()[2].textDirNode.dir, "Menu item should have LTR text direction 2");
+					doh.is('rtl', menu.getChildren()[3].textDirNode.dir, "Menu item should have RTL text direction 3");
+
+					menuBtn.closeDropDown();
+				}
+			});
+
+			doh.register("log", function(){
+				dom.byId('failures').innerHTML = doh._failureCount;
+				dom.byId('errors').innerHTML = doh._errorCount;
+			});
+
+			doh.run();
+		});
+	</script>
+
+</head>
+<body class="claro">
+
+	<h1 class="testTitle">Bidi TabContainer tests</h1>
+	<h2 class="testTitle">TabContainer with RTL text direction and changed tabs</h2>
+	<div id="tc1" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='textDir: "rtl", style:"width: 550px; height: 60px;" '>
+		<div id="t1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='textDir: "ltr", title:"tab1 @", selected:true'>
+			Title of this LTR pane has been changed
+		</div>
+		<div id="t2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab2 @", closable:true'>
+			Title of this pane with no text direction specified (inherited) has been changed
+		</div>
+		<div id="t3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='textDir: "ltr", title:"Explicit LTR!", closable:true'>
+			Explicit LTR text direction of content pane
+		</div>
+		<div id="t4" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Inherited RTL!", closable:true'>
+			Inherited RTL text direction of content pane tab
+		</div>
+	</div>
+	<br />
+	<h2 class="testTitle">TabContainer with RTL text direction</h2>
+	<div id="tc3" data-dojo-type="dijit/layout/TabContainer" textDir="rtl" data-dojo-id="tc3" style="width: 300px; height:100px;">
+		<div data-dojo-type="dijit/layout/ContentPane" title="Explicit LTR!" textDir="ltr" data-dojo-id="one" id="one">Explicit LTR text direction of content pane</div>
+		<div data-dojo-type="dijit/layout/ContentPane" title="Inherited RTL!" data-dojo-id="two" id="two">Inherited RTL text direction of content pane tab</div>
+		<div data-dojo-type="dijit/layout/ContentPane" title="אExplicit AUTO!" data-dojo-id="three" id="three">Explicit 'auto' text direction of content pane</div>
+		<div data-dojo-type="dijit/layout/ContentPane" title="Explicit RTL!" textDir="rtl" data-dojo-id="four" id="four">Explicit RTL text direction of content pane</div>
+	</div>
+		<br>Errors: <span id="errors">?</span>
+		<br>Failures: <span id="failures">?</span>
+</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/layout/module.js b/dijit/tests/_BidiSupport/layout/module.js
new file mode 100644
index 0000000..3a13aff
--- /dev/null
+++ b/dijit/tests/_BidiSupport/layout/module.js
@@ -0,0 +1,5 @@
+define(["doh/main", "require"], function(doh, require){
+	doh.register("_BidiSupport.layout.TabContainer", require.toUrl("./TabContainer.html"), 999999);
+	doh.register("_BidiSupport.layout.StackContainer", require.toUrl("./StackContainer.html"), 999999);
+	doh.register("_BidiSupport.layout.AccordionContainer", require.toUrl("./AccordionContainer.html"), 999999);
+});
diff --git a/dijit/tests/_BidiSupport/layout/runTests.html b/dijit/tests/_BidiSupport/layout/runTests.html
new file mode 100644
index 0000000..7195415
--- /dev/null
+++ b/dijit/tests/_BidiSupport/layout/runTests.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<title>Bidi Layout Unit Test Runner</title>
+		<meta http-equiv="REFRESH" content="0;url=../../../../util/doh/runner.html?testModule=dijit.tests._BidiSupport.layout.module"></head>
+	<body>
+		Redirecting to D.O.H runner.
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/misc/Dialog.html b/dijit/tests/_BidiSupport/misc/Dialog.html
new file mode 100644
index 0000000..20e8743
--- /dev/null
+++ b/dijit/tests/_BidiSupport/misc/Dialog.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dialog Widget Automated (non-robot) Tests</title>
+
+	<style type="text/css">
+		@import "../../../themes/claro/document.css";
+		@import "../../css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="async: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/query",
+			"dijit/Dialog",
+			"dojo/domReady!"
+		], function(doh, query, Dialog){
+			toggleTextDir = function(){
+				dlg.set("textDir", (dlg.get("textDir") !== "rtl") ? "rtl" : "ltr");
+			};
+			doh.register("tests._BidiSupport.form.DialogBidi", [
+				{
+					name: "Bidi Dialog test",
+					runTest: function(){
+						var d = new doh.Deferred();
+						dlg = new Dialog({
+							textDir: "rtl",
+							title: "Title!",
+							content: "<input id='dlg1_inputA'><br>" +
+									"<input id='dlg1_inputB'><br>" +
+									"<input id='dlg1_inputC'><br>" +
+									"<input type='button' value='Toggle title textDir' onclick='toggleTextDir()'>"
+						});
+						dlg.show().then(d.getTestCallback(function(){
+							doh.is(dlg.get("textDir"), query(".dijitDialogTitle")[0].dir, "Dialog title node should have 'dir' attribute equal to dialog's 'textDir' property");
+						}));
+						return d;
+					}
+				}
+			]);
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+<h1 class="testTitle">Bidi Dialog Test</h1>
+</body>
+</html>
+
+
diff --git a/dijit/tests/_BidiSupport/misc/MenuItem.html b/dijit/tests/_BidiSupport/misc/MenuItem.html
new file mode 100644
index 0000000..01b79d6
--- /dev/null
+++ b/dijit/tests/_BidiSupport/misc/MenuItem.html
@@ -0,0 +1,311 @@
+<!DOCTYPE html>
+<html>
+<head>
+
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
+	<title>Test Bidi support for Menu Item</title>
+
+	<style type="text/css">
+		@import "../../../../dijit/themes/claro/document.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+
+		body { padding: 0; }
+
+		/* styling for left-hand-side navigation menu to become a column equal to length of page */
+		#formattingTable {
+			border: 0;
+			border-spacing: 0;
+		}
+		#contentContainer { padding: 2em; }
+
+		#navMenu {
+			/* make the sidebar menu blend in with the whole sidebar */
+			border: none;
+		}
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad: true, isDebug: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		dojo.require("dijit.Menu");
+		dojo.require("dijit.MenuItem");
+		dojo.require("dijit.PopupMenuItem");
+		dojo.require("dijit.CheckedMenuItem");
+		dojo.require("dijit.MenuSeparator");
+
+		dojo.require("dijit.MenuBar");
+		dojo.require("dijit.MenuBarItem");
+		dojo.require("dijit.PopupMenuBarItem");
+
+		dojo.require("dijit.ColorPalette");
+		dojo.require("dijit.form.TextBox");
+		dojo.require("doh.runner");
+
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+	</script>
+
+	<script type="text/javascript">
+		function createMenu(){
+			// create a menu programmatically
+			function fClick(){console.log("clicked!")}
+
+			pMenu = new dijit.Menu({targetNodeIds:["prog_menu"], id:"progMenu"});
+			pMenu.addChild(new dijit.MenuItem({label:"Programmatic Context Menu", disabled:true}));
+			pMenu.addChild(new dijit.MenuSeparator());
+			pMenu.addChild(new dijit.MenuItem({label:"\u05e9\u05dc\u05d5\u05dd\u0021\u0021 rtl", onClick:fClick, accelKey:"Shift+S", textDir:"rtl", id:"progItemRtl"}));
+			pMenu.addChild(new dijit.MenuItem({label:"Another menu item...", onClick:fClick, accelKey:"Ctrl+A",  textDir:"ltr", id:"progItemLtr"}));
+			pMenu.addChild(new dijit.MenuItem({label:"With an icon", iconClass:"dijitEditorIcon dijitEditorIconCut", onClick:fClick}));
+			var mItem = new dijit.MenuItem({label:"dojo.event clicking!! auto", accelKey: "Alt+D", textDir:"auto", id:"progItemAuto1"});
+			dojo.connect(mItem, "onClick", function(){console.log("click! handler created via dojo.connect()")});
+			pMenu.addChild(mItem);
+			mItem = new dijit.CheckedMenuItem({label:"\u05e9\u05dc\u05d5\u05dd\u0021\u0021 auto", textDir:"auto", id:"progItemAuto2"});
+			pMenu.addChild(mItem);
+
+			var pSubMenu = new dijit.Menu({parentMenu:pMenu, id:"progSubMenu"});
+			pSubMenu.addChild(new dijit.MenuItem({label:"Submenu item", onClick:fClick}));
+			pSubMenu.addChild(new dijit.MenuItem({label:"Submenu item", onClick:fClick}));
+
+			var pSubSubMenu = new dijit.Menu({parentMenu:pSubMenu, id:"progSubSubMenu"});
+			pSubSubMenu.addChild(new dijit.MenuItem({label:"SubSubmenu item", onClick:fClick}));
+			pSubSubMenu.addChild(new dijit.MenuItem({label:"SubSubmenu item", onClick:fClick}));
+			pSubMenu.addChild(new dijit.PopupMenuItem({label:"SubSubmenu rtl...", popup:pSubSubMenu, textDir:"rtl"}));
+
+			pMenu.addChild(new dijit.PopupMenuItem({label:"Submenu", popup:pSubMenu}));
+
+			pMenu.startup();
+
+				updateButtons(true);
+			dojo.byId("prog_menu").innerHTML="This div has a programmatic context menu on it that's different to the page menu.";
+
+			dojo.byId("createButton").disabled = true;
+			dojo.byId("destroyButton").disabled = false;
+		}
+
+		function destroyMenu(){
+			pMenu.destroyRecursive();
+			updateButtons(false);
+		}
+
+		function updateButtons(created){
+			dojo.byId("prog_menu").innerHTML=created?"This div has a programmatic context menu on it that's different to the page menu.":"No programmatic menu on this div, should get page level menu.";
+			dojo.byId("createButton").disabled = created;
+			dojo.byId("destroyButton").disabled = !created;
+		}
+		dojo.ready(function(){
+			// need to explicitly update our buttons states, otherwise the
+			// browser will remember the last states of them before reloading
+			// (so a programmatic menu is created, reload, and "the create
+			// programmatic menu" button is still in disabled state)
+			updateButtons(false);
+
+			doh.register("dijit.tests._BidiSupport.widget.MenuItem", [
+				function test_LTR_TextDir(){
+					doh.is(dijit.byId("open").get("textDir"), "ltr");
+					doh.is(dijit.byId("open").textDirNode.dir, "ltr");
+					doh.is(dijit.byId("navMenuComedy").get("textDir"), "ltr");
+					doh.is(dijit.byId("navMenuComedy").textDirNode.dir, "ltr");
+				},
+
+				function test_LTR_TextDir_RTL_dir(){
+					doh.is(dijit.byId("menu2").get("textDir"), "ltr");
+					doh.is(dijit.byId("menu2").textDirNode.dir, "ltr");
+				},
+
+				function test_RTL_TextDir_LTR_dir(){
+					doh.is(dijit.byId("menu1").get("textDir"), "rtl");
+					doh.is(dijit.byId("menu1").textDirNode.dir, "rtl");
+				},
+
+				function test_RTL_TextDir(){
+					doh.is(dijit.byId("new").get("textDir"), "rtl");
+					doh.is(dijit.byId("new").textDirNode.dir, "rtl");
+					doh.is(dijit.byId("navMenuDrama").get("textDir"), "rtl");
+					doh.is(dijit.byId("navMenuDrama").textDirNode.dir, "rtl");
+				},
+
+				function test_AUTO_TextDir(){
+					doh.is(dijit.byId("save").get("textDir"), "auto");
+					doh.is(dijit.byId("save").textDirNode.dir, "ltr");
+					doh.is(dijit.byId("saveas").get("textDir"), "auto");
+					doh.is(dijit.byId("saveas").textDirNode.dir, "rtl");
+				},
+
+				function test_PopupMenuBarItem_TextDirLTR(){
+					doh.is(dijit.byId("file").get("textDir"), "ltr");
+					doh.is(dijit.byId("file").textDirNode.dir, "ltr");
+				},
+
+				function test_PopupMenuBarItem_TextDirRTL(){
+					doh.is(dijit.byId("view").get("textDir"), "rtl");
+					doh.is(dijit.byId("view").textDirNode.dir, "rtl");
+				},
+
+				function test_PopupMenuBarItem_TextDirAUTO(){
+					doh.is(dijit.byId("empty").get("textDir"), "auto");
+					doh.is(dijit.byId("empty").textDirNode.dir, "ltr");
+				},
+
+				function test_PopupMenuItem_TextDirRTL(){
+					doh.is(dijit.byId("popupMenuItem").get("textDir"), "rtl");
+					doh.is(dijit.byId("popupMenuItem").textDirNode.dir, "rtl");
+				},
+
+				function test_PopupMenuItem_TextDirAUTO(){
+					doh.is(dijit.byId("navMenuDisabledItem").get("textDir"), "auto");
+					doh.is(dijit.byId("navMenuDisabledItem").textDirNode.dir, "rtl");
+				},
+
+				function test_programmat_menuitem(){
+					createMenu();
+					doh.is(dijit.byId("progItemLtr").get("textDir"), "ltr");
+					doh.is(dijit.byId("progItemLtr").textDirNode.dir, "ltr");
+					doh.is(dijit.byId("progItemRtl").get("textDir"), "rtl");
+					doh.is(dijit.byId("progItemRtl").textDirNode.dir, "rtl");
+					doh.is(dijit.byId("progItemAuto1").get("textDir"), "auto");
+					doh.is(dijit.byId("progItemAuto1").textDirNode.dir, "ltr");
+					doh.is(dijit.byId("progItemAuto2").get("textDir"), "auto");
+					doh.is(dijit.byId("progItemAuto2").textDirNode.dir, "rtl");
+					destroyMenu();
+				},
+
+				function test_changeLabel_forAUTO(){
+					var item = dijit.byId("saveas");
+					doh.is(item.get("textDir"), "auto");
+					doh.is(item.textDirNode.dir, "rtl");
+					item.set("label", "");
+					doh.is(item.textDirNode.dir, "ltr");
+					item.set("label", "new label '\u05e9\u05d9\u05de\u05d5\u05e9\u0020\u05d1\u05ea\u05d2\u05d9\u05d5\u05ea\u002e'");
+					doh.is(item.textDirNode.dir, "ltr");
+					item.set("label", "'\u05e9\u05d9\u05de\u05d5\u05e9\u0020\u05d1\u05ea\u05d2\u05d9\u05d5\u05ea\u002e'");
+					doh.is(item.textDirNode.dir, "rtl");
+				}
+			]);
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+
+	<div id="windowContextMenu" data-dojo-type="dijit/Menu" data-dojo-props='contextMenuForWindow:true, style:"display: none;"'>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Hello world"); }'> ערך חדש for context Menu</div>
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='disabled:true, onClick:function(){ alert("this should NOT appear"); }'>Disabled Item</div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+			onClick:function(){ console.log("not actually cutting anything, just a test!") }, accelKey:"Ctrl+X"' textDir="rtl" >Cut RTL...</div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+			onClick:function(){ console.log("not actually copying anything, just a test!") }, accelKey:"Ctrl+C"' textDir="ltr" >Copy LTR...</div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+			onClick:function(){ console.log("not actually pasting anything, just a test!") }, accelKey:"Ctrl+V"' textDir="auto" >חדש AUTO...</div>
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+
+
+	</div>
+
+
+	<table id="formattingTable">
+		<tr>
+			<td style="width:0;">
+				<!-- This is here for tabIndex testing.
+					Use textarea since Chrome 1.0 likes it better for TABing and
+					because it has innerText property and because it doesn't mess
+					with the URL when clicked -->
+				<textarea id="link" tabIndex="0" readOnly class="dijitReset" style="font-family:monospace;font-size:12px;width:84px;text-decoration:underline;overflow:hidden;background-color:transparent;" rows=1>random link</textarea>
+			</td>
+			<td id="menuBarContainer" style="width:100%;">
+				<div id="menubar" data-dojo-type="dijit/MenuBar">
+					<div id="file" data-dojo-type="dijit/PopupMenuBarItem" textDir="ltr">
+						<span>File...</span>
+						<div id="fileMenu" data-dojo-type="dijit/Menu" >
+							<div id="new" data-dojo-type="dijit/MenuItem" textDir="rtl"  label="File RTL ..."></div>
+							<div id="open" data-dojo-type="dijit/MenuItem" textDir="ltr">Open LTR ...</div>
+							<div id="separator" data-dojo-type="dijit/MenuSeparator" ></div>
+							<div id="save" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIconSave"'  textDir="auto">START AUTO חדש!...</div>
+							<div id="saveas" data-dojo-type="dijit/MenuItem" textDir="auto" >חדש AUTO END...</div>
+						</div>
+					</div>
+					<div id="view" data-dojo-type="dijit/PopupMenuBarItem" textDir="rtl" >
+						<span>חדש...</span>
+						<div id="viewMenu" data-dojo-type="dijit/Menu" >
+							<div data-dojo-type="dijit/MenuItem">Normal w/o textDir....</div>
+							<div id="popupMenuItem" data-dojo-type="dijit/PopupMenuItem" textDir="rtl">
+								<span>Submenu test RTL חדש...</span>
+								<div id="zoomMenu" data-dojo-type="dijit/Menu" >
+									<div id="menu1" data-dojo-type="dijit/MenuItem" textDir="rtl" dir="ltr">חדש new RTL menu...</div>
+									<div id="menu2" data-dojo-type="dijit/MenuItem" textDir="ltr" dir="rtl">חדש new LTR menu...</div>
+									<div data-dojo-type="dijit/MenuItem" textDir="auto">חדש new Auto menu...</div>
+								</div>
+							</div>
+						</div>
+					</div>
+					<div id="empty" data-dojo-type="dijit/PopupMenuBarItem" textDir="auto">
+						<span>Empty auto חדש... </span>
+						<div data-dojo-type="dijit/Menu">
+						</div>
+					</div>
+					<div data-dojo-type="dijit/PopupMenuBarItem" data-dojo-props='disabled:true' textDir="rtl">
+						<span>חדש Disabled RTL !!!</span>
+						<div data-dojo-type="dijit/Menu">
+							<div data-dojo-type="dijit/MenuItem">You should not see this</div>
+						</div>
+					</div>
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td id="navMenuContainer" class="dijitMenu" style="vertical-align:top; width:0;">
+
+				<h3 style="margin-bottom: 2em;">Navigation menu:</h3>
+				<div id="navMenu" data-dojo-type="dijit/Menu" >
+					<div id="navMenuDrama" data-dojo-type="dijit/MenuItem" textDir="rtl" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+						onClick:function(){ console.log("drama!"); }'>Drama RTL ...</div>
+					<div id="navMenuComedy"data-dojo-type="dijit/MenuItem" textDir="ltr" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+						onClick:function(){ console.log("comedy!") }'>Comedy LTR ...</div>
+
+					<div id="navMenuDisabledItem" data-dojo-type="dijit/PopupMenuItem" textDir="auto" data-dojo-props='disabled:true '>
+						<span>חדש new disabled submenu</span>
+						<div id="navMenuSub3" data-dojo-type="dijit/Menu" data-dojo-props='style:"display: none;"'>
+							<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }' textDir="auto">START AUTO חדש!...</div>
+							<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu 2!</div>
+						</div>
+					</div>
+					<div data-dojo-type="dijit/PopupMenuItem">
+						<span>Different popup</span>
+						<div data-dojo-type="dijit/ColorPalette"></div>
+					</div>
+					<div data-dojo-type="dijit/MenuSeparator"></div>
+					<div data-dojo-type="dijit/CheckedMenuItem" textDir="rtl" data-dojo-props='checked:true, onChange:function(val){ console.log("Now set to " + val); }'>חדש checked RTL ...</div>
+					<div id="checked2" data-dojo-type="dijit/CheckedMenuItem" >Not Checked</div>
+					<div data-dojo-type="dijit/CheckedMenuItem" data-dojo-props='checked:true, disabled:true'>Checked Disabled</div>
+				</div>
+			</td>
+
+			<td style="padding: 1em" id="contentContainer">
+
+				<h1 class="testTitle">Test Bidi support for Menu Item</h1>
+
+				<p>This page contains:</p>
+				<ul>
+					<li>"Navigation bar" Menu widget on left, a.k.a vertical MenuBar
+					<li>MenuBar on top
+					<li>page level context menu (right-click anywhere on page)
+					<li>form widget context menu (right-click on textbox widget)</li>
+					<li>Example of programatically created menu
+					<li>Note: while some accelerator (shortcut) keys are displayed in the context menu, they are not actually hooked up to the corresponding actions (if any), they need to be setup explicitly by the user
+				</ul>
+
+				<div id="prog_menu" style="clear: both; border:1px solid blue; padding:10px; margin:20px 0;">
+					Click button below to create special menu on this div.
+				</div>
+				<button id="createButton" onclick="createMenu();">create programmatic menu</button>
+				<button id="destroyButton" onclick="destroyMenu();" disabled>destroy programmatic menu</button>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/misc/TitlePane.html b/dijit/tests/_BidiSupport/misc/TitlePane.html
new file mode 100644
index 0000000..31c37fd
--- /dev/null
+++ b/dijit/tests/_BidiSupport/misc/TitlePane.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>TitlePane Test</title>
+
+	<style type="text/css">
+		@import "../../../themes/claro/document.css";
+		@import "../../css/dijitTests.css";
+	</style>
+
+	<link id="themeStyles" rel="stylesheet" href="../../../themes/claro/claro.css"/>
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="async: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/dom",
+			"dojo/parser",
+			"dojo/query",
+			"dijit/registry",
+			"dijit/TitlePane",
+			"dojo/domReady!"
+		], function(doh, dom, parser, query, registry){
+
+			doh.register("parse", function(){
+				return parser.parse();
+			});
+
+			doh.register("tests._BidiSupport.misc.TitlePane.Bidi", [
+				{
+					name: "TitlePane Bidi",
+					runTest: function(){
+						registry.byId("pane_2").set('textDir', "rtl");
+						doh.is("rtl", registry.byId("pane_1").titleNode.dir, "title node had direction correspondent to 'textDir'");
+						doh.is("rtl", registry.byId("pane_2").titleNode.dir, "title node had direction correspondent to 'textDir'");
+					}
+				}
+			]);
+
+			doh.register("log", function(){
+				dom.byId('failures').innerHTML = doh._failureCount;
+				dom.byId('errors').innerHTML = doh._errorCount;
+			});
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle"><b>Bidi TitlePane Test</b></h1>
+	<h1>Title pane with tooltip, textDir == 'auto'</h1>
+	<div id="pane_1" data-dojo-id="pane1" data-dojo-type="dijit/TitlePane" data-dojo-props='textDir:"auto", title:"\u05e9\u05dc\u05d5\u05dd Title Pane!",
+		tooltip:"\u05e9\u05dc\u05d5\u05dd I\"m the tooltip for Title Pane\"s title bar!",
+		style:"width: 500px;" '>
+		Arabic, Hebrew, Urdu, and Farsi (Persian) are written from right to left,
+		while numbers and segments of Latin (or Cyrillic or Greek) text are embedded in
+		this text from left to right. The dual directionality aspects of such
+		bidirectional (bidi) text are posing challenges to the way this text is processed and presented in computer applications.
+
+	</div>
+	<h1>Title pane, textDir == 'rtl'</h1>
+	<div id="pane_2" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Title Pane!", textDir:"ltr", tooltip:"Title Pane!", style:"width: 500px;"'>
+		The Unicode Bidirectional Algorithm, which is commonly used for preparation of Bidi text for display,
+		is not capable to reliably identify the natural base text direction for a given text.
+		Only a human reader can unfailingly recognize the natural base text direction for a given text.
+		Support for enforcing the base text direction is provided out of the box by most platforms / technologies,
+		but very often the default settings do not guarantee proper display of English and Arabic/Hebrew text in the
+		same application.	See for reference:	http://w3-03.ibm.com/globalization/page/publish/4353
+	</div>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>
+</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/misc/Tooltip.html b/dijit/tests/_BidiSupport/misc/Tooltip.html
new file mode 100644
index 0000000..dd16a09
--- /dev/null
+++ b/dijit/tests/_BidiSupport/misc/Tooltip.html
@@ -0,0 +1,300 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo Tooltip Widget Test with Bidi support</title>
+
+	<style type="text/css">
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		@import "../../../../dojo/resources/dojo.css";
+
+		td { padding: 20px; }
+	</style>
+
+
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="parseOnLoad: true, isDebug: true, has: { 'dojo-bidi': true }">
+		</script>
+
+	<script type="text/javascript">
+		dojo.require("dojo.parser");
+		dojo.require("doh.runner");
+
+		dojo.require("dijit.form.ValidationTextBox");
+		dojo.require("dijit.Tooltip");
+
+		dojo.ready(function(){
+			function checkContextualDir(text){
+				var fdc = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(text);
+				// if found return the direction that defined by the character, else return widgets dir as defult.
+				return fdc ? ( fdc[0] <= 'z' ? "ltr" : "rtl" ) : "ltr";
+			}
+			doh.register("tooltip text direction", [
+				{
+					name: "tooltip LTR text direction for LTR widget",
+					runTest: function(){
+						var d = new doh.Deferred();
+						var tt = dijit.byId("id1_tooltip");
+						tt.open(dojo.byId("id1"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is("ltr",tt.textDir, "textDir of : " + tt.id);
+							doh.is("ltr",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
+							tt.close();
+						}), 200);
+						return d;
+					}
+				},
+				{
+					name: "tooltip RTL text direction for LTR widget",
+					runTest: function(){
+					var d = new doh.Deferred();
+						var tt = dijit.byId("id2_tooltip");
+						tt.open(dojo.byId("id2"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is("rtl",tt.textDir, "textDir of : " + tt.id);
+							doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
+							tt.close();
+						}), 400);
+						return d;
+
+					}
+				},
+				{
+					name: "tooltip AUTO text direction for LTR widget",
+					runTest: function(){
+					var d = new doh.Deferred();
+						var tt = dijit.byId("id3_tooltip");
+						tt.open(dojo.byId("id3"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is("auto",tt.textDir, "textDir of : " + tt.id);
+							doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
+							tt.close();
+						}), 400);
+						return d;
+					}
+				}
+			]);
+			doh.register("tooltip RTL text direction for tooltip with HTML inline elements", [
+				{
+					name: "tooltip RTL text direction for LTR widget",
+					runTest: function(){
+					var d = new doh.Deferred();
+						var tt = dijit.byId("id7_tooltip");
+						tt.open(dojo.byId("id7"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is("rtl",tt.textDir, "textDir of : " + tt.id);
+							doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
+							tt.close();
+						}), 400);
+						return d;
+					}
+				},
+				{
+					name: "tooltip LTR text direction for RTL widget",
+					runTest: function(){
+					var d = new doh.Deferred();
+						var tt = dijit.byId("id4_tooltip");
+						tt.open(dojo.byId("id4"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is("ltr",tt.textDir, "textDir of : " + tt.id);
+							doh.is("ltr",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
+							tt.close();
+						}), 400);
+						return d;
+					}
+				},
+				{
+					name: "tooltip text alignment for tooltip with dir 'rtl'",
+					runTest: function(){
+					var d = new doh.Deferred();
+						var tt = dijit.byId("id4_tooltip");
+						tt.open(dojo.byId("id4"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is("right",dijit._masterTT.containerNode.align, "alignment of : " + tt.id);
+							tt.close();
+						}), 400);
+						return d;
+					}
+				},
+				{
+					name: "tooltip RTL text direction for RTL widget",
+					runTest: function(){
+					var d = new doh.Deferred();
+						var tt = dijit.byId("id5_tooltip");
+						tt.open(dojo.byId("id5"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is("rtl",tt.textDir, "textDir of : " + tt.id);
+							doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
+							tt.close();
+						}), 400);
+						return d;
+					}
+				},
+				{
+					name: "tooltip AUTO text direction for RTL widget",
+					runTest: function(){
+					var d = new doh.Deferred();
+						var tt = dijit.byId("id6_tooltip");
+						tt.open(dojo.byId("id6"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is("auto",tt.textDir, "textDir of : " + tt.id);
+							doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
+							tt.close();
+						}), 400);
+						return d;
+					}
+				}
+			]);
+
+			doh.register("tooltip RTL text direction for tooltip with HTML inline elements", [
+				{
+					name: "tooltip RTL text direction for LTR widget",
+					runTest: function(){
+					var d = new doh.Deferred();
+						var tt = dijit.byId("id7_tooltip");
+						tt.open(dojo.byId("id7"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is("rtl",tt.textDir, "textDir of : " + tt.id);
+							doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
+							tt.close();
+						}), 400);
+						return d;
+					}
+				}
+			]);
+
+			doh.register("tooltip with children nodes", [
+				{
+					name: "tooltip AUTO text direction, check text direction for children",
+					runTest: function(){
+					var d = new doh.Deferred();
+						var tt = dijit.byId("id8_tooltip");
+						tt.open(dojo.byId("id8"));
+						setTimeout(d.getTestCallback(function(){
+							dojo.forEach(dijit._masterTT.containerNode.children, function(child){
+								var dir = checkContextualDir(dojo.isIE? child.outerText : child.textContent);
+								doh.is(dir, child.dir, "direction of : " + tt.id);
+							}, this);
+							doh.is("auto",tt.textDir, "textDir of : " + tt.id);
+							tt.close();
+						}), 400);
+						return d;
+					}
+				},
+				{
+					name: "Check text direction for tooltip with AUTO text direction and RTL dir attribute",
+					runTest: function(){
+					var d = new doh.Deferred();
+						var tt = dijit.byId("id10_tooltip");
+						tt.open(dojo.byId("id10"));
+						setTimeout(d.getTestCallback(function(){
+							dojo.forEach(dijit._masterTT.containerNode.children, function(child){
+								var dir = checkContextualDir(dojo.isIE? child.outerText : child.textContent);
+								doh.is(dir, child.dir, "direction of nodes : " + tt.id);
+							}, this);
+							doh.is("auto",tt.textDir, "textDir of : " + tt.id);
+							tt.close();
+						}), 400);
+						return d;
+					}
+				},
+				{
+					name: "Check alignment for tooltip with RTL dir attribute",
+					runTest: function(){
+					var d = new doh.Deferred();
+						var tt = dijit.byId("id10_tooltip");
+						tt.open(dojo.byId("id10"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is("right",dijit._masterTT.containerNode.align, "alignment of : " + tt.id);
+							tt.close();
+						}), 400);
+						return d;
+					}
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+<body class="tundra">
+
+	<h1 class="testTitle">Tooltip test</h1>
+
+	<p>Mouse-over or focus the items below to test tooltips.</p>
+
+		<input type="text" id="id1" name="test1" data-dojo-type="dijit/form/ValidationTextBox" value="#1 tooltip ltr"/><br>
+		<input type="text" id="id2" name="test2" data-dojo-type="dijit/form/ValidationTextBox" value="#2 tooltip rtl"/><br>
+		<input type="text" id="id3" name="test3" data-dojo-type="dijit/form/ValidationTextBox" value="#3 tooltip auto"/><br><br />
+
+		<input type="text" id="id7" name="test7" data-dojo-type="dijit/form/ValidationTextBox" value="tooltip inline HTML elements"/><br><br />
+		<input type="text" id="id8" name="test8" data-dojo-type="dijit/form/ValidationTextBox" value="tooltip auto with children nodes"/><br>
+
+		<div dir="rtl">
+		<input type="text" id="id4" name="test4" data-dojo-type="dijit/form/ValidationTextBox" value="#4 tooltip ltr"/><br>
+		<input type="text" id="id5" name="test5" data-dojo-type="dijit/form/ValidationTextBox" value="#5 tooltip rtl"/><br>
+		<input type="text" id="id6" name="test5" data-dojo-type="dijit/form/ValidationTextBox" value="#6 tooltip auto"/><br><br />
+		</div>
+		<input type="text" id="id10" name="test10" data-dojo-type="dijit/form/ValidationTextBox" value="tooltip auto with children nodes" dir="rtl"/><br>
+
+	<br>
+
+
+
+	<span id="id1_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id1"], textDir: "ltr"'>חדש! tooltip #1 !!!</span>
+	<span id="id2_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id2"], textDir: "rtl"'>חדש! tooltip #2!!!</span>
+	<span id="id3_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id3"], textDir: "auto"'>חדש! tooltip  #3...</span>
+	<span id="id4_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id4"], textDir: "ltr", dir: "rtl"'>חדש!   tooltip #4 !!!</span>
+	<span id="id5_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id5"], textDir: "rtl"'>חדש! tooltip #5!!!</span>
+	<span id="id6_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id6"], textDir: "auto"'>חדש! tooltip  #6...</span>
+
+
+
+	<span id="id7_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id7"], textDir:"rtl"'>
+	<i>
+		ערך חדש!
+	</i>
+	textDir :
+	<b>
+		RTL...
+	</b></span>
+
+	<span id="id8_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id8"], textDir: "auto"'>
+		<b>
+			Tooltip "auto" with block elements
+		</b>
+		<div>
+			DIV element
+			<p> ערך חדש p element! </p>
+		</div>
+		<b>
+			ערך חדש!
+		</b>
+		<div>
+			ערך חדש!
+		</div>
+		<p>long long long long long long long long long long long text ..</p>
+	</span>
+
+	<span id="id10_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id10"], textDir: "auto", dir: "rtl"'>
+		<b>
+			Tooltip "auto" with block elements
+		</b>
+		<div>
+			DIV element
+			<p> ערך חדש p element! </p>
+		</div>
+		<b>
+			ערך חדש!
+		</b>
+		<div>
+			ערך חדש!
+		</div>
+		<p>long long long long long long long long long long long text ..</p>
+	</span>
+
+</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/misc/TooltipDialog.html b/dijit/tests/_BidiSupport/misc/TooltipDialog.html
new file mode 100644
index 0000000..892b0dd
--- /dev/null
+++ b/dijit/tests/_BidiSupport/misc/TooltipDialog.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>TooltipDialog Widget Automated (non-robot) Tests</title>
+
+	<style type="text/css">
+		@import "../../../themes/claro/document.css";
+		@import "../../css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="async: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dijit/registry",
+			"dijit/TooltipDialog",
+			"dijit/popup",
+			"dojo/domReady!"
+		], function(doh, registry, TooltipDialog, popup){
+
+			// Setup intentional global
+			toggleTextDir = function(){
+				var td = registry.byId("td");
+				td.set("textDir", (td.get("textDir") !== "rtl") ? "rtl" : "ltr");
+			};
+
+			doh.register("tests._BidiSupport.misc.TooltipDialog", [
+				{
+					name: "Bidi TooltipDialog test",
+					runTest: function(){
+						var d = new doh.Deferred();
+						var td = new TooltipDialog({
+							id: "td",
+							textDir: "rtl",
+							title: "Title!",
+							content:
+								"<input id='dlg1_inputA'><br>" +
+								"<input id='dlg1_inputB'><br>" +
+								"<input id='dlg1_inputC'><br>" +
+								"<input type='button' value='Toggle title textDir' onclick='toggleTextDir();'>"
+						});
+						popup.open({
+							popup: td,
+							x: 10,
+							y: 50
+						});
+						doh.is(String.fromCharCode(8235), td.containerNode.title.charAt(0), "Dialog title tooltip should have direction correspondent to dialog's 'textDir'");
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">Bidi TooltipDialog Test</h1>
+</body>
+</html>
+
+
diff --git a/dijit/tests/_BidiSupport/misc/module.js b/dijit/tests/_BidiSupport/misc/module.js
new file mode 100644
index 0000000..3574208
--- /dev/null
+++ b/dijit/tests/_BidiSupport/misc/module.js
@@ -0,0 +1,9 @@
+define(["doh/main", "require"], function(doh, require){
+
+	doh.register("_BidiSupport.misc.Tooltip.html", require.toUrl("./Tooltip.html"), 999999);
+	doh.register("_BidiSupport.misc.Dialog.html", require.toUrl("./Dialog.html"), 999999);
+	doh.register("_BidiSupport.misc.TooltipDialog.html", require.toUrl("./TooltipDialog.html"), 999999);
+	doh.register("_BidiSupport.misc.MenuItem.html", require.toUrl("./MenuItem.html"), 999999);
+	doh.register("_BidiSupport.layout.TitlePane", require.toUrl("./TitlePane.html"), 999999);
+
+});
diff --git a/dijit/tests/_BidiSupport/misc/runTests.html b/dijit/tests/_BidiSupport/misc/runTests.html
new file mode 100644
index 0000000..5466191
--- /dev/null
+++ b/dijit/tests/_BidiSupport/misc/runTests.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+
+<html>
+	<head>
+		<title>textDirTests Unit Test Runner</title>
+		<meta http-equiv="REFRESH" content="0;url=../../../../util/doh/runner.html?testModule=dijit.tests._BidiSupport.misc.module">
+	</head>
+	<body>
+		Redirecting to D.O.H runner.
+	</body>
+</html>
diff --git a/dijit/tests/_BidiSupport/module.js b/dijit/tests/_BidiSupport/module.js
index 5de408c..d12d342 100644
--- a/dijit/tests/_BidiSupport/module.js
+++ b/dijit/tests/_BidiSupport/module.js
@@ -1,21 +1,9 @@
-dojo.provide("dijit.tests._BidiSupport.module");
-
-try{
-
-	dojo.require("dijit.tests._BidiSupport.form.module");
-
-	dojo.require("dijit.tests._BidiSupport.BidiSupportModule.module");
-
-	dojo.require("dijit.tests._BidiSupport.inheritance.module");
-
-	dojo.require("dijit.tests._BidiSupport.dynamicallyChangeTextDir.module");
-
-	dojo.require("dijit.tests._BidiSupport.tree.module");
-	
-	dojo.require("dijit.tests._BidiSupport.widgets.module");
-
-}catch(e){
-
-	doh.debug(e);
-
-}
+define([
+	"./layout/module",
+	"./misc/module",
+	"./form/module",
+	"./BidiSupportModule/module",
+	"./inheritance/module",
+	"./dynamicallyChangeTextDir/module",
+	"./tree/module"
+], 1);
diff --git a/dijit/tests/_BidiSupport/tree/ProgrammaticTree.html b/dijit/tests/_BidiSupport/tree/ProgrammaticTree.html
index 499ef3b..39b9397 100644
--- a/dijit/tests/_BidiSupport/tree/ProgrammaticTree.html
+++ b/dijit/tests/_BidiSupport/tree/ProgrammaticTree.html
@@ -1,29 +1,22 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html dir="ltr">
-    
     <head>
         <style type="text/css">
             body, html { font-family:helvetica,arial,sans-serif; font-size:90%; }
         </style>
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true">
-		</script>	
-
+			data-dojo-config="parseOnLoad: true, isDebug: true, has: { 'dojo-bidi': true }">
+		</script>
 		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
-		
         <script type="text/javascript">
             dojo.require("doh.runner");
-			dojo.require("dojo.parser");
-			
 			dojo.require("dojo.data.ItemFileReadStore");
             dojo.require("dijit.Tree");
-            dojo.require("dijit._BidiSupport");
 
-            dojo.addOnLoad(function() {
+            dojo.ready(function() {
                 var store = new dojo.data.ItemFileReadStore({
                     url: "../../../../dijit/tests/_BidiSupport/_data/countriesHeb.json"
                 });
-
                 var treeModel = new dijit.tree.ForestStoreModel({
                    store: store,
                     query: {
@@ -33,55 +26,24 @@
                     rootLabel: "Continents!",
                     childrenAttrs: ["children"]
                 });
-
                 new dijit.Tree({
  					textDir: "ltr",
                     model: treeModel
                 },
                 "treeLtr");
-				
 				new dijit.Tree({
  					textDir: "rtl",
                     model: treeModel
                 },
                 "treeRtl");
-
                 new dijit.Tree({
  					textDir: "auto",
                     model: treeModel
                 },
-                "treeAuto");	
-
-				doh.register("parse", function(){
-					dojo.parser.parse();
-				});
-
+                "treeAuto");
 				var treeRtl, treeLtr, treeAuto, buttonLtr, buttonRtl, buttonAuto;
-				
-				function expandNode(tree, node){
-					var d = new doh.Deferred();
-
-					if(!node.isExpandable){
-						return;
-					}
-					if(!node.isExpanded){
-						tree._onExpandoClick({node: node});	
-					}
-					//node.expand();
-					setTimeout(d.getTestCallback(function(){
-						dojo.forEach(node.getChildren(),  function(child){expandNode(tree,child)});
-					}), 100);
-					return d;
-				};
-				function expandAll(tree){
-					expandNode(tree,tree.rootNode);
-				};
-				
-
 				function testNodeAuto(node,textDir){
-
 					doh.is(node.tree._checkContextual(node.label), node.labelNode.dir, "direction of " + node.tree.id +" : rootNode");
-				
 					if(!node.item.children){
 						return;
 					}
@@ -89,13 +51,9 @@
 						//doh.is(textDir, childNode.labelNode.dir, "direction of " + childNode.tree.id + " element: " + i);
 						testNodeAuto(childNode,textDir);
 					});
-					
-				};
-				
+				}
 				function testNode(node,textDir){
-
 					doh.is(textDir, node.labelNode.dir, "direction of " + node.tree.id +" : rootNode");
-				
 					if(!node.item.children){
 						return;
 					}
@@ -103,27 +61,20 @@
 						//doh.is(textDir, childNode.labelNode.dir, "direction of " + childNode.tree.id + " element: " + i);
 						testNode(childNode,textDir);
 					});
-					
-				};
+				}
 				function expandedNodesTextDirTest(tree, textDir){
-
 					textDir == "auto" ? testNodeAuto(tree.rootNode, textDir) : testNode(tree.rootNode, textDir);
-
-				};
-				
-				doh.register("paths", [
+				}
+				doh.register("initial", [
 					{
 						name: "initial dirs",
-						
 						setUp: function(){
-							treeRtl = dijit.byId("treeRtl");						
-							treeLtr = dijit.byId("treeLtr");						
-							treeAuto = dijit.byId("treeAuto");						
+							treeRtl = dijit.byId("treeRtl");
+							treeLtr = dijit.byId("treeLtr");
+							treeAuto = dijit.byId("treeAuto");
 						},
-
 						runTest: function(){
 							var d = new doh.Deferred();
-							
 							setTimeout(d.getTestCallback(function(){
 								doh.is("rtl", treeRtl.rootNode.labelNode.dir, "direction of treeRtl: rootNode");
 								doh.is("ltr", treeLtr.rootNode.labelNode.dir, "direction of treeLtr: rootNode");
@@ -134,121 +85,95 @@
 									doh.is("rtl", rtlChildren[i].labelNode.dir, "direction of treeRtl element: " + i);
 									doh.is("ltr", ltrChildren[i].labelNode.dir, "direction of treeLtr element: " + i);
 									doh.is(treeAuto._checkContextual(autoChildren[i].label), autoChildren[i].labelNode.dir, "direction of treeAuto element: " + autoChildren[i].label);
-								};
+								}
 							}), 100);
-
 							return d;
 						}
 					},
 					{
 						name: "expanded RTL",
-						
+						timeout: 5000,
 						runTest: function(){
-							var d = expandAll(treeRtl);
-							
-							expandedNodesTextDirTest(treeRtl, "rtl");
-							
+							var d = new doh.Deferred();
+							treeRtl.expandAll().then(d.getTestCallback(function(){
+								expandedNodesTextDirTest(treeRtl, "rtl");
+							}));
 							return d;
-
 						}
 					},
 					{
 						name: "expanded LTR",
-						
+						timeout: 5000,
 						runTest: function(){
-							var d = expandAll(treeLtr);
-							
-							expandedNodesTextDirTest(treeLtr, "ltr");
-							
+							var d = new doh.Deferred();
+							treeLtr.expandAll().then(d.getTestCallback(function(){
+								expandedNodesTextDirTest(treeLtr, "ltr");
+							}));
 							return d;
-
 						}
 					},
 					{
 						name: "expanded AUTO",
-						
+						timeout: 5000,
 						runTest: function(){
-							var d = expandAll(treeAuto);
-							
-							expandedNodesTextDirTest(treeAuto, "auto");
-							
+							var d = new doh.Deferred();
+							treeAuto.expandAll().then(d.getTestCallback(function(){
+								expandedNodesTextDirTest(treeAuto, "auto");
+							}));
 							return d;
-
 						}
 					}
 				]);
 				doh.register("Dynamic change textDir", [
 					{
 						name: 'check "set("textDir", textDir)" function',
-						
 						setUp: function(){
-							treeRtl = dijit.byId("treeRtl");						
-							treeLtr = dijit.byId("treeLtr");						
-							treeAuto = dijit.byId("treeAuto");	
+							treeRtl = dijit.byId("treeRtl");
+							treeLtr = dijit.byId("treeLtr");
+							treeAuto = dijit.byId("treeAuto");
 							buttonLtr = dojo.byId("buttonLtr");
 							buttonRtl = dojo.byId("buttonRtl");
 							buttonAuto = dojo.byId("buttonAuto");
-							
 						},
-
 						runTest: function(){
-
 							dijit.byId("treeRtl").set("textDir", "ltr");
-							
 							expandedNodesTextDirTest(treeRtl, "ltr");
-							
 							expandedNodesTextDirTest(treeAuto, "auto");
 						}
 					},
 					{
 						name: 'set using the buttons: LTR',
-						
 						runTest: function(){
-							
 							buttonLtr.click();
-
 							expandedNodesTextDirTest(treeRtl, "ltr");
-							
 							expandedNodesTextDirTest(treeLtr, "ltr");
-							
 							expandedNodesTextDirTest(treeAuto, "ltr");
 						}
 					},
 					{
 						name: 'set using the buttons: RTL',
-						
 						runTest: function(){
-							
 							buttonRtl.click();
-
 							expandedNodesTextDirTest(treeRtl, "rtl");
-							
 							expandedNodesTextDirTest(treeLtr, "rtl");
-							
 							expandedNodesTextDirTest(treeAuto, "rtl");
 						}
 					},
 					{
 						name: 'set using the buttons: AUTO',
-						
 						runTest: function(){
-							
 							buttonAuto.click();
-
 							expandedNodesTextDirTest(treeRtl, "auto");
-							
 							expandedNodesTextDirTest(treeLtr, "auto");
-							
 							expandedNodesTextDirTest(treeAuto, "auto");
 						}
-					}					
-				]);					
-				doh.run();				
+					}
+				]);
+				doh.run();
             });
         </script>
     </head>
-    
-    <body class=" claro ">
+    <body class="claro">
 		<table>
 			<tr><td>
 					<label for="treeLtr" >
@@ -260,13 +185,13 @@
 					<label for="treeRtl" >
 						<b>  I'm a RTL Tree   </b>
 					</label>
-					<div id="treeRtl"></td>
+					<div id="treeRtl"></div>
 				</td>
 				<td>
 					<label for="treeAuto" >
 						<b>  I'm a Contextual Tree   </b>
 					</label>
-					<div id="treeAuto"></td>
+					<div id="treeAuto"></div>
 				</td>
 			</tr>
 		</table>
@@ -284,9 +209,6 @@
 			onclick="dijit.byId('treeLtr').set('textDir','auto');
 				dijit.byId('treeRtl').set('textDir','auto');
 				dijit.byId('treeAuto').set('textDir','auto');"
-		/>		
-
- 
+		/>
     </body>
-
-</html>
+</html>
\ No newline at end of file
diff --git a/dijit/tests/_BidiSupport/tree/SimpleTree.html b/dijit/tests/_BidiSupport/tree/SimpleTree.html
deleted file mode 100644
index edad3fe..0000000
--- a/dijit/tests/_BidiSupport/tree/SimpleTree.html
+++ /dev/null
@@ -1,270 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-	<title>dijit.Tree</title>
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true">
-		</script>		
-		<style type="text/css">
-			body, html { font-family:helvetica,arial,sans-serif; font-size:90%; }
-		</style>
-		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.require("dojo.parser");
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-
-			dojo.require("dojo.data.ItemFileReadStore");
-			dojo.require("dijit.Tree");
-			
-			dojo.require("dijit._BidiSupport");
-
-			dojo.addOnLoad(function(){
-				doh.register("parse", function(){
-					dojo.parser.parse();
-				});
-
-				var treeRtl, treeLtr, treeAuto, buttonLtr, buttonRtl, buttonAuto;
-				
-				function expandNode(tree, node){
-					var d = new doh.Deferred();
-
-					if(!node.isExpandable){
-						return;
-					}
-					if(!node.isExpanded){
-						tree._onExpandoClick({node: node});	
-					}
-					//node.expand();
-					setTimeout(d.getTestCallback(function(){
-						dojo.forEach(node.getChildren(),  function(child){expandNode(tree,child)});
-					}), 100);
-					return d;
-				};
-				function expandAll(tree){
-					expandNode(tree,tree.rootNode);
-				};
-				
-
-				function testNodeAuto(node,textDir){
-
-					doh.is(node.tree._checkContextual(node.label), node.labelNode.dir, "direction of " + node.tree.id +" : rootNode");
-				
-					if(!node.item.children){
-						return;
-					}
-					dojo.forEach(node.getChildren(), function(childNode){
-						//doh.is(textDir, childNode.labelNode.dir, "direction of " + childNode.tree.id + " element: " + i);
-						testNodeAuto(childNode,textDir);
-					});
-					
-				};
-				
-				function testNode(node,textDir){
-
-					doh.is(textDir, node.labelNode.dir, "direction of " + node.tree.id +" : rootNode");
-				
-					if(!node.item.children){
-						return;
-					}
-					dojo.forEach(node.getChildren(), function(childNode){
-						//doh.is(textDir, childNode.labelNode.dir, "direction of " + childNode.tree.id + " element: " + i);
-						testNode(childNode,textDir);
-					});
-					
-				};
-				function expandedNodesTextDirTest(tree, textDir){
-
-					textDir == "auto" ? testNodeAuto(tree.rootNode, textDir) : testNode(tree.rootNode, textDir);
-
-				};
-				
-				doh.register("paths", [
-					{
-						name: "initial dirs",
-						
-						setUp: function(){
-							treeRtl = dijit.byId("treeRtl");						
-							treeLtr = dijit.byId("treeLtr");						
-							treeAuto = dijit.byId("treeAuto");						
-						},
-
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							setTimeout(d.getTestCallback(function(){
-								doh.is("rtl", treeRtl.rootNode.labelNode.dir, "direction of treeRtl: rootNode");
-								doh.is("ltr", treeLtr.rootNode.labelNode.dir, "direction of treeLtr: rootNode");
-								doh.is("ltr", treeAuto.rootNode.labelNode.dir, "direction of treeAuto: rootNode");
-								var rtlChildren = treeRtl.rootNode.getChildren(), ltrChildren = treeLtr.rootNode.getChildren(),
-									autoChildren = treeAuto.rootNode.getChildren();
-								for(var i = 0 ; i < rtlChildren.length ; i++){
-									doh.is("rtl", rtlChildren[i].labelNode.dir, "direction of treeRtl element: " + i);
-									doh.is("ltr", ltrChildren[i].labelNode.dir, "direction of treeLtr element: " + i);
-									doh.is(treeAuto._checkContextual(autoChildren[i].label), autoChildren[i].labelNode.dir, "direction of treeAuto element: " + autoChildren[i].label);
-								};
-							}), 100);
-
-							return d;
-						}
-					},
-					{
-						name: "expanded RTL",
-						
-						runTest: function(){
-							var d = expandAll(treeRtl);
-							
-							expandedNodesTextDirTest(treeRtl, "rtl");
-							
-							return d;
-
-						}
-					},
-					{
-						name: "expanded LTR",
-						
-						runTest: function(){
-							var d = expandAll(treeLtr);
-							
-							expandedNodesTextDirTest(treeLtr, "ltr");
-							
-							return d;
-
-						}
-					},
-					{
-						name: "expanded AUTO",
-						
-						runTest: function(){
-							var d = expandAll(treeAuto);
-							
-							expandedNodesTextDirTest(treeAuto, "auto");
-							
-							return d;
-
-						}
-					}
-				]);
-				doh.register("Dynamic change textDir", [
-					{
-						name: 'check "set("textDir", textDir)" function',
-						
-						setUp: function(){
-							treeRtl = dijit.byId("treeRtl");						
-							treeLtr = dijit.byId("treeLtr");						
-							treeAuto = dijit.byId("treeAuto");	
-							buttonLtr = dojo.byId("buttonLtr");
-							buttonRtl = dojo.byId("buttonRtl");
-							buttonAuto = dojo.byId("buttonAuto");
-							
-						},
-
-						runTest: function(){
-
-							dijit.byId("treeRtl").set("textDir", "ltr");
-							
-							expandedNodesTextDirTest(treeRtl, "ltr");
-							
-							expandedNodesTextDirTest(treeAuto, "auto");
-						}
-					},
-					{
-						name: 'set using the buttons: LTR',
-						
-						runTest: function(){
-							
-							buttonLtr.click();
-
-							expandedNodesTextDirTest(treeRtl, "ltr");
-							
-							expandedNodesTextDirTest(treeLtr, "ltr");
-							
-							expandedNodesTextDirTest(treeAuto, "ltr");
-						}
-					},
-					{
-						name: 'set using the buttons: RTL',
-						
-						runTest: function(){
-							
-							buttonRtl.click();
-
-							expandedNodesTextDirTest(treeRtl, "rtl");
-							
-							expandedNodesTextDirTest(treeLtr, "rtl");
-							
-							expandedNodesTextDirTest(treeAuto, "rtl");
-						}
-					},
-					{
-						name: 'set using the buttons: AUTO',
-						
-						runTest: function(){
-							
-							buttonAuto.click();
-
-							expandedNodesTextDirTest(treeRtl, "auto");
-							
-							expandedNodesTextDirTest(treeLtr, "auto");
-							
-							expandedNodesTextDirTest(treeAuto, "auto");
-						}
-					}					
-				]);					
-				doh.run();
-			});
-
-		</script>
- 	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
-
-    </head>
-	    <body class=" claro ">
-        <div data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-id="continentStore" data-dojo-props='url:"../../../../dijit/tests/_BidiSupport/_data/countriesHeb.json"'>
-        </div>
-	<div data-dojo-id="continentModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
-		rootId:"continentRoot", rootLabel:"Continents!", childrenAttrs:["children"]'></div>
-		
-		<table>
-			<tr><td>
-					<label for="treeAuto" >
-						<b>  I'm a Contextual Tree   </b>
-					</label>
-					<div data-dojo-type="dijit.Tree" id="treeAuto" data-dojo-props='model:continentModel, openOnClick:true, textDir:"auto"'>
-					</div>
-				</td>
-				<td></td><td></td><td></td><td></td><td></td><td></td><td></td>
-				<td>
-					<label for="treeLtr" >
-						<b>  I'm a LTR Tree   </b>
-					</label>
-					<div data-dojo-type="dijit.Tree" id="treeLtr" data-dojo-props='model:continentModel, openOnClick:true, textDir:"ltr"'>
-					</div>
-				</td>	
-				<td></td><td></td><td></td><td></td><td></td><td></td><td></td>
-				<td>
-					<label for="treeRtl" >
-						<b>  I'm a RTL Tree   </b>
-					</label>
-					<div data-dojo-type="dijit.Tree" id="treeRtl" data-dojo-props='model:continentModel, openOnClick:true, textDir:"rtl"'>
-					</div>
-				</td>
-			</tr>
-		</table>
-		<input id= "buttonRtl" type="button" value="RTL"
-			onclick="dijit.byId('treeAuto').set('textDir','rtl');
-				dijit.byId('treeLtr').set('textDir','rtl');
-				dijit.byId('treeRtl').set('textDir','rtl');"
-			/>
-		<input id= "buttonLtr" type="button" value="LTR"
-			onclick="dijit.byId('treeAuto').set('textDir','ltr');
-				dijit.byId('treeLtr').set('textDir','ltr');
-				dijit.byId('treeRtl').set('textDir','ltr');"
-			/>
-		<input id= "buttonAuto" type="button" value="AUTO"
-			onclick="dijit.byId('treeAuto').set('textDir','auto');
-				dijit.byId('treeLtr').set('textDir','auto');
-				dijit.byId('treeRtl').set('textDir','auto');"
-			/>
-    </body>
-
-</html>
-
diff --git a/dijit/tests/_BidiSupport/tree/TreeRootlessCustomIcons.html b/dijit/tests/_BidiSupport/tree/TreeRootlessCustomIcons.html
deleted file mode 100644
index 1d3de73..0000000
--- a/dijit/tests/_BidiSupport/tree/TreeRootlessCustomIcons.html
+++ /dev/null
@@ -1,267 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>Dijit Tree Test</title>
-
-	<style type="text/css">
-		@import "../../../themes/claro/document.css";
-		@import "../../css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-	<script type="text/javascript">
-		dojo.require("dojo.data.ItemFileReadStore");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.ForestStoreModel");
-
-		dojo.require("dijit.ColorPalette");
-
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.MenuItem");
-		dojo.require("dijit.PopupMenuItem");
-		
-		dojo.require("dijit._BidiSupport");
-		dojo.require("doh.runner");
-
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		dojo.addOnLoad(function(){
-
-			var treeRootless, treeCustIcons, buttonLtr, buttonRtl, buttonAuto;
-			
-			function expandNode(tree, node){
-				var d = new doh.Deferred();
-
-				if(!node.isExpandable){
-					return;
-				}
-				if(!node.isExpanded){
-					tree._onExpandoClick({node: node});	
-				}
-				//node.expand();
-				setTimeout(d.getTestCallback(function(){
-					dojo.forEach(node.getChildren(),  function(child){expandNode(tree,child)});
-				}), 100);
-				return d;
-			};
-			function expandAll(tree){
-				expandNode(tree,tree.rootNode);
-			};
-			
-
-			function testNodeAuto(node,textDir){
-
-				doh.is(node.tree._checkContextual(node.label), node.labelNode.dir, "direction of " + node.tree.id +" : rootNode");
-			
-				if(!node.item.children){
-					return;
-				}
-				dojo.forEach(node.getChildren(), function(childNode){
-					//doh.is(textDir, childNode.labelNode.dir, "direction of " + childNode.tree.id + " element: " + i);
-					testNodeAuto(childNode,textDir);
-				});
-				
-			};
-			
-			function testNode(node,textDir){
-
-				doh.is(textDir, node.labelNode.dir, "direction of " + node.tree.id +" : rootNode");
-			
-				if(!node.item.children){
-					return;
-				}
-				dojo.forEach(node.getChildren(), function(childNode){
-					//doh.is(textDir, childNode.labelNode.dir, "direction of " + childNode.tree.id + " element: " + i);
-					testNode(childNode,textDir);
-				});
-				
-			};
-			function expandedNodesTextDirTest(tree, textDir){
-
-				textDir == "auto" ? testNodeAuto(tree.rootNode, textDir) : testNode(tree.rootNode, textDir);
-
-			};
-			
-			doh.register("paths", [
-				{
-					name: "initial dirs",
-					
-					setUp: function(){
-						treeRootless = dijit.byId("treeRootless");						
-						treeCustIcons = dijit.byId("treeCustIcons");						
-					},
-
-					runTest: function(){
-						var d = new doh.Deferred();
-						
-						setTimeout(d.getTestCallback(function(){
-							doh.is("ltr", treeCustIcons.rootNode.labelNode.dir, "direction of treeCustIcons: rootNode");
-							var autoChildren = treeCustIcons.rootNode.getChildren(); // rtlChildren = treeRootless.rootNode.getChildren(), 
-							
-							for(var i = 0 ; i < autoChildren.length ; i++){
-								doh.is(treeCustIcons._checkContextual(autoChildren[i].label), autoChildren[i].labelNode.dir, "direction of treeCustIcons element: " + autoChildren[i].label);
-							};
-						}), 100);
-
-						return d;
-					}
-				},
-				{
-					name: "expanded RTL",
-					
-					runTest: function(){
-						var d = expandAll(treeRootless);
-						
-						expandedNodesTextDirTest(treeRootless, "rtl");
-						
-						return d;
-
-					}
-				},
-				{
-					name: "expanded AUTO",
-					
-					runTest: function(){
-						expandedNodesTextDirTest(treeCustIcons, "auto");
-					}
-				}
-			]);
-			doh.register("Dynamic change textDir", [
-				{
-					name: 'check "set("textDir", textDir)" function',
-					
-					setUp: function(){
-						treeRootless = dijit.byId("treeRootless");						
-						treeCustIcons = dijit.byId("treeCustIcons");	
-						buttonLtr = dojo.byId("buttonLtr");
-						buttonRtl = dojo.byId("buttonRtl");
-						buttonAuto = dojo.byId("buttonAuto");
-						
-					},
-
-					runTest: function(){
-
-						dijit.byId("treeRootless").set("textDir", "ltr");
-						
-						expandedNodesTextDirTest(treeRootless, "ltr");
-						
-						expandedNodesTextDirTest(treeCustIcons, "auto");
-					}
-				},
-				{
-					name: 'set using the buttons: LTR',
-					
-					runTest: function(){
-						
-						buttonLtr.click();
-
-						expandedNodesTextDirTest(treeRootless, "ltr");
-						
-						expandedNodesTextDirTest(treeCustIcons, "ltr");
-					}
-				},
-				{
-					name: 'set using the buttons: RTL',
-					
-					runTest: function(){
-						
-						buttonRtl.click();
-
-						expandedNodesTextDirTest(treeRootless, "rtl");
-						
-						expandedNodesTextDirTest(treeCustIcons, "rtl");
-					}
-				},
-				{
-					name: 'set using the buttons: AUTO',
-					
-					runTest: function(){
-						
-						buttonAuto.click();
-
-						expandedNodesTextDirTest(treeRootless, "auto");
-						
-						expandedNodesTextDirTest(treeCustIcons, "auto");
-					}
-				}					
-			]);					
-			doh.run();
-		});		
-	
-	</script>
-
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit Tree Test</h1>
-
-	<div data-dojo-id="continentStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"../../../../dijit/tests/_BidiSupport/_data/countriesHeb.json"'></div>
-	<div data-dojo-id="continentModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
-		rootId:"continentRoot", rootLabel:"Continents!", childrenAttrs:["children"]'></div>
-	
-		<table>
-			<tr>
-				<td>
-					<h2>A rootless tree (no "continents" node) with custom icons</h2>
-
-					<div id="treeRootless" data-dojo-type="dijit.Tree" data-dojo-props='textDir:"rtl",model:continentModel, showRoot:false, openOnClick:true'>
-
-						<script type="dojo/method" data-dojo-event="getIconClass" data-dojo-args="item, opened">
-						   return (item == this.model.root || continentStore.getValue(item, "type") == "continent") ?
-								   (opened ? "customFolderOpenedIcon" : "customFolderClosedIcon") :
-									"noteIcon";
-						</script>
-					</div>
-				</td>
-				<td></td><td></td><td></td><td></td><td></td><td></td><td></td>
-				<td>
-					<div id="treeCustIcons" data-dojo-type="dijit.Tree" data-dojo-props='textDir:"auto",store:continentStore, query:{type:"continent"},
-						label:"Continents!", openOnClick:false, openOnDblClick:true,
-						autoExpand:true'>
-						<script type="dojo/method" data-dojo-event="getLabelStyle" data-dojo-args="item,opened">
-							if(item && continentStore.getValue(item,"type") == "continent"){
-								return {color: "red"};
-							}else{
-								return {color: "green"};
-							}
-						</script>
-						<script type="dojo/method" data-dojo-event="getIconStyle" data-dojo-args="item,opened">
-							if(item && continentStore.getValue(item,"type") == "continent"){
-								return {
-									backgroundImage: "url('../../images/flatScreen.gif')",
-									height: "32px",
-									width: "32px"
-								};
-							}else{
-								return null;
-							}
-						</script>
-						<script type="dojo/method" data-dojo-event="getIconClass" data-dojo-args="item, opened">
-						   if(!item || continentStore.getValue(item, "type") != "continent")
-								return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf"
-							else
-								return "";
-						</script>
-					</div>
-				</td>
-			</tr>
-		</table>
-		
-	<input id="buttonRtl" type="button" onclick="dijit.byId('treeRootless').set('textDir','rtl');dijit.byId('treeCustIcons').set('textDir','rtl');"
-	value="RTL"/>
-	<input id="buttonLtr" type="button" onclick="dijit.byId('treeRootless').set('textDir','ltr');dijit.byId('treeCustIcons').set('textDir','ltr');"
-	value="LTR"/>
-	<input id="buttonAuto" type="button" onclick="dijit.byId('treeRootless').set('textDir','auto');dijit.byId('treeCustIcons').set('textDir','auto');"
-	value="AUTO"/>
-
-
-</body>
-</html>
diff --git a/dijit/tests/_BidiSupport/tree/module.js b/dijit/tests/_BidiSupport/tree/module.js
index 8370f21..4375fe4 100644
--- a/dijit/tests/_BidiSupport/tree/module.js
+++ b/dijit/tests/_BidiSupport/tree/module.js
@@ -1,15 +1,5 @@
-dojo.provide("dijit.tests._BidiSupport.tree.module");
+define(["doh/main", "require"], function(doh, require){
 
-try{
+	doh.register("_BidiSupport.tree.ProgrammaticTree.html", require.toUrl("./ProgrammaticTree.html"), 999999);
 
-	doh.registerUrl("dijit.tests._BidiSupport.tree.SimpleTree.html", dojo.moduleUrl("dijit","tests/_BidiSupport/tree/SimpleTree.html"));
-	
-	doh.registerUrl("dijit.tests._BidiSupport.tree.ProgrammaticTree.html", dojo.moduleUrl("dijit","tests/_BidiSupport/tree/ProgrammaticTree.html"));
-	
-	doh.registerUrl("dijit.tests._BidiSupport.tree.TreeRootlessCustomIcons.html", dojo.moduleUrl("dijit","tests/_BidiSupport/tree/TreeRootlessCustomIcons.html"));
-	
-}catch(e){
-
-	doh.debug(e);
-
-}
+});
diff --git a/dijit/tests/_BidiSupport/widgets/Tooltip.html b/dijit/tests/_BidiSupport/widgets/Tooltip.html
deleted file mode 100644
index 3ed4ddb..0000000
--- a/dijit/tests/_BidiSupport/widgets/Tooltip.html
+++ /dev/null
@@ -1,305 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>Dojo Tooltip Widget Test with Bidi support</title>
-
-	<style type="text/css">
-		@import "../../../../dijit/themes/tundra/tundra.css";
-		@import "../../../../dojo/resources/dojo.css";			
-
-		td { padding: 20px; }
-	</style>
-
-
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true">
-		</script>	
-
-	<script type="text/javascript">
-		dojo.require("dojo.parser");
-        dojo.require("doh.runner");
-        
-        dojo.require("dijit.dijit"); // optimize: load dijit layer
-        dojo.require("dijit.form.ValidationTextBox");
-		dojo.require("dijit.Tooltip");
-		dojo.require("dijit._BidiSupport");
-		
-        
-          dojo.addOnLoad(function(){
-				function checkContextualDir(text){
-			        var fdc = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(text);
-			        // if found return the direction that defined by the character, else return widgets dir as defult.
-			        return fdc ? ( fdc[0] <= 'z' ? "ltr" : "rtl" ) : "ltr"; 
-			    }
-				doh.register("tooltip text direction", [
-					{
-						name: "tooltip LTR text direction for LTR widget",
-                    	runTest: function(){
-                       	    var d = new doh.Deferred();
-						    var tt = dijit.byId("id1_tooltip");
-						    tt.open(dojo.byId("id1"));						    
-						    setTimeout(d.getTestCallback(function(){
-					            doh.is("ltr",tt.textDir, "textDir of : " + tt.id);
-						        doh.is("ltr",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
-				                tt.close(); 
-				            }), 200);
-					        return d;
-					       }	      				        
-					},
-					{
-						name: "tooltip RTL text direction for LTR widget",
-						runTest: function(){
-						var d = new doh.Deferred();
-						    var tt = dijit.byId("id2_tooltip");
-						    tt.open(dojo.byId("id2"));						    
-						    setTimeout(d.getTestCallback(function(){
-					            doh.is("rtl",tt.textDir, "textDir of : " + tt.id);
-						        doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
-				                tt.close();
-					        }), 400);
-					        return d;
-		
-						}
-					},
-				    {
-					    name: "tooltip AUTO text direction for LTR widget",
-					    runTest: function(){
-					    var d = new doh.Deferred();
-					        var tt = dijit.byId("id3_tooltip");
-					        tt.open(dojo.byId("id3"));
-					        setTimeout(d.getTestCallback(function(){
-					            doh.is("auto",tt.textDir, "textDir of : " + tt.id);
-						        doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
-				                tt.close(); 
-					        }), 400);
-					        return d;
-					    }
-					}
-				]);
-				doh.register("tooltip RTL text direction for tooltip with HTML inline elements", [
-					{
-						name: "tooltip RTL text direction for LTR widget",						
-                     	runTest: function(){
-                     	var d = new doh.Deferred();
-						    var tt = dijit.byId("id7_tooltip");
-						    tt.open(dojo.byId("id7"));
-						    setTimeout(d.getTestCallback(function(){
-						        doh.is("rtl",tt.textDir, "textDir of : " + tt.id);
-							    doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
-    							tt.close();
-					        }), 400);
-					        return d;
-						}	      				        
-					},
-					{
-					    name: "tooltip LTR text direction for RTL widget",
-					    runTest: function(){
-					    var d = new doh.Deferred();
-					        var tt = dijit.byId("id4_tooltip");
-					        tt.open(dojo.byId("id4"));
-					        setTimeout(d.getTestCallback(function(){
-					           doh.is("ltr",tt.textDir, "textDir of : " + tt.id);
-						       doh.is("ltr",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
-						       tt.close(); 
-					        }), 400);
-					        return d;
-					    }
-					},	
-				    {
-					    name: "tooltip text alignment for tooltip with dir 'rtl'",
-					    runTest: function(){
-					    var d = new doh.Deferred();
-					        var tt = dijit.byId("id4_tooltip");
-					        tt.open(dojo.byId("id4"));
-					        setTimeout(d.getTestCallback(function(){
-						        doh.is("right",dijit._masterTT.containerNode.align, "alignment of : " + tt.id);
-				                tt.close(); 
-					        }), 400);
-					        return d;
-					    }
-					},	
-				    {
-					    name: "tooltip RTL text direction for RTL widget",
-					    runTest: function(){
-					    var d = new doh.Deferred();
-					        var tt = dijit.byId("id5_tooltip");
-					        tt.open(dojo.byId("id5"));
-					        setTimeout(d.getTestCallback(function(){
-					           doh.is("rtl",tt.textDir, "textDir of : " + tt.id);
-						       doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
-						       tt.close(); 
-					        }), 400);
-					        return d;
-					    }
-					},
-					{
-					    name: "tooltip AUTO text direction for RTL widget",
-					    runTest: function(){
-					    var d = new doh.Deferred();
-					        var tt = dijit.byId("id6_tooltip");
-					        tt.open(dojo.byId("id6"));
-					        setTimeout(d.getTestCallback(function(){
-					           doh.is("auto",tt.textDir, "textDir of : " + tt.id);
-						       doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
-						       tt.close(); 
-					        }), 400);
-					        return d;
-					    }
-					}	
-				]);
-				
-                doh.register("tooltip RTL text direction for tooltip with HTML inline elements", [
-					{
-						name: "tooltip RTL text direction for LTR widget",						
-                     	runTest: function(){
-                     	var d = new doh.Deferred();
-						    var tt = dijit.byId("id7_tooltip");		    
-						    tt.open(dojo.byId("id7"));
-						    setTimeout(d.getTestCallback(function(){
-						        doh.is("rtl",tt.textDir, "textDir of : " + tt.id);
-							    doh.is("rtl",dijit._masterTT.containerNode.dir, "direction of : " + tt.id);
-    							tt.close();
-					        }), 400);
-					        return d;
-						}	      				        
-					}
-				]);
-							
-                doh.register("tooltip with children nodes", [
-					{
-						name: "tooltip AUTO text direction, check text direction for children",						
-                     	runTest: function(){
-                     	var d = new doh.Deferred();
-						    var tt = dijit.byId("id8_tooltip");
-						    tt.open(dojo.byId("id8"));
-						    setTimeout(d.getTestCallback(function(){
-						        dojo.forEach(dijit._masterTT.containerNode.children, function(child){
-						            var dir = checkContextualDir(dojo.isIE? child.outerText : child.textContent); 
-						            doh.is(dir, child.dir, "direction of : " + tt.id);
-						        }, this);
-						        doh.is("auto",tt.textDir, "textDir of : " + tt.id);
-					            tt.close(); 
-					        }), 400);
-					        return d;
-						}	      				        
-					},
-					{
-						name: "Check text direction for tooltip with AUTO text direction and RTL dir attribute",						
-                     	runTest: function(){
-                     	var d = new doh.Deferred();
-						    var tt = dijit.byId("id10_tooltip");
-						    tt.open(dojo.byId("id10"));
-						    setTimeout(d.getTestCallback(function(){
-						        dojo.forEach(dijit._masterTT.containerNode.children, function(child){
-						            var dir = checkContextualDir(dojo.isIE? child.outerText : child.textContent); 
-						            doh.is(dir, child.dir, "direction of nodes : " + tt.id);
-						        }, this);
-						        doh.is("auto",tt.textDir, "textDir of : " + tt.id);
-					            tt.close(); 
-					        }), 400);
-					        return d;
-						}	      				        
-					},
-    				{
-						name: "Check alignment for tooltip with RTL dir attribute",			
-                     	runTest: function(){
-                     	var d = new doh.Deferred();
-						    var tt = dijit.byId("id10_tooltip");   
-						    tt.open(dojo.byId("id10"));
-						    setTimeout(d.getTestCallback(function(){
-						        doh.is("right",dijit._masterTT.containerNode.align, "alignment of : " + tt.id);
-					            tt.close(); 
-					        }), 400);
-					        return d;
-						}	      				        
-					}		
-				]);
-
-				doh.run();
-			});
-
-	</script>
-</head>
-<body class="tundra">
-
-	<h1 class="testTitle">Tooltip test</h1>
-
-	<p>Mouse-over or focus the items below to test tooltips.</p>
-
-		<input type="text" id="id1" name="test1" data-dojo-type="dijit.form.ValidationTextBox" value="#1 tooltip ltr"/><br>
-		<input type="text" id="id2" name="test2" data-dojo-type="dijit.form.ValidationTextBox" value="#2 tooltip rtl"/><br>
-		<input type="text" id="id3" name="test3" data-dojo-type="dijit.form.ValidationTextBox" value="#3 tooltip auto"/><br><br />	
-		
-	    <input type="text" id="id7" name="test7" data-dojo-type="dijit.form.ValidationTextBox" value="tooltip inline HTML elements"/><br><br />		
-		<input type="text" id="id8" name="test8" data-dojo-type="dijit.form.ValidationTextBox" value="tooltip auto with children nodes"/><br>
-		
-		<div dir="rtl">		
-        <input type="text" id="id4" name="test4" data-dojo-type="dijit.form.ValidationTextBox" value="#4 tooltip ltr"/><br>
-		<input type="text" id="id5" name="test5" data-dojo-type="dijit.form.ValidationTextBox" value="#5 tooltip rtl"/><br>
-		<input type="text" id="id6" name="test5" data-dojo-type="dijit.form.ValidationTextBox" value="#6 tooltip auto"/><br><br />
-		</div>
-		<input type="text" id="id10" name="test10" data-dojo-type="dijit.form.ValidationTextBox" value="tooltip auto with children nodes" dir="rtl"/><br>		
-
-	<br>
-
-
- 
-    <span id="id1_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id1"], textDir: "ltr"'>חדש!   tooltip #1 !!!</span>
-	<span id="id2_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id2"], textDir: "rtl"'>חדש!   tooltip #2!!!</span>
-	<span id="id3_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id3"], textDir: "auto"'>חדש!  tooltip  #3...</span>
-    <span id="id4_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id4"], textDir: "ltr", dir: "rtl"'>חדש!   tooltip #4 !!!</span>
-	<span id="id5_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id5"], textDir: "rtl"'>חדש!   tooltip #5!!!</span>
-	<span id="id6_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id6"], textDir: "auto"'>חדש!  tooltip  #6...</span>
-		
-	
-
-	<span id="id7_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id7"], textDir:"rtl"'>
-	<i>
-       ערך חדש!
-    </i>
-    textDir :
-    <b>
-        RTL...
-    </b></span>
-    
-   <span id="id8_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id8"], textDir: "auto"'>
-	<b>
-	Tooltip "auto" with block elements
-	</b>
-    <div> 
-    DIV element
-    <p > ערך חדש p element! </p>
-    </div>
-    <b>
-    ערך חדש!
-   </b>
-    <div > 
-     ערך חדש! 
-    </div>
-	<p>long long long long long long long long long long long text ..</p>
-	</span>
-	
-	<span id="id10_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id10"], textDir: "auto", dir: "rtl"'>
-	<b>
-	Tooltip "auto" with block elements
-	</b>
-    <div> 
-    DIV element
-    <p> ערך חדש p element! </p>
-    </div>
-    <b>
-    ערך חדש!
-   </b>
-    <div > 
-     ערך חדש! 
-    </div>
-	<p>long long long long long long long long long long long text ..</p>
-	</span>
-<p></p>
-<br>
-
-</body>
-</html>
diff --git a/dijit/tests/_BidiSupport/widgets/module.js b/dijit/tests/_BidiSupport/widgets/module.js
deleted file mode 100644
index 5977ffa..0000000
--- a/dijit/tests/_BidiSupport/widgets/module.js
+++ /dev/null
@@ -1,11 +0,0 @@
-dojo.provide("dijit.tests._BidiSupport.widgets.module");
-
-try{
-
-	doh.registerUrl("dijit.tests._BidiSupport.widgets.Tooltip.html", dojo.moduleUrl("dijit","tests/_BidiSupport/widgets/Tooltip.html"));
-
-}catch(e){
-
-	doh.debug(e);
-
-}
diff --git a/dijit/tests/_BidiSupport/widgets/runTests.html b/dijit/tests/_BidiSupport/widgets/runTests.html
deleted file mode 100644
index 0326313..0000000
--- a/dijit/tests/_BidiSupport/widgets/runTests.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-	<head>
-		<title>textDirTests Unit Test Runner</title>
-		<meta http-equiv="REFRESH" content="0;url=../../../../util/doh/runner.html?testModule=dijit.tests._BidiSupport.widgets.module">
-	</head>
-	<body>
-		Redirecting to D.O.H runner.
-	</body>
-</html>
diff --git a/dijit/tests/_Container.html b/dijit/tests/_Container.html
index 418cb65..d86d480 100644
--- a/dijit/tests/_Container.html
+++ b/dijit/tests/_Container.html
@@ -8,126 +8,133 @@
 
 	<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit._Widget");
-		dojo.require("dijit._Container");
-		dojo.require("dijit._Contained");
+		require([
+			"doh/runner",
+			"dojo/_base/declare", "dojo/dom", "dojo/parser",
+			"dijit/a11y", "dijit/focus", "dijit/registry", "dijit/_WidgetBase", "dijit/_Container", "dijit/_Contained",
+			"dijit/tests/helpers", "dojo/domReady!"
+		], function(doh, declare, dom, parser, a11y, focus, registry, _WidgetBase, _Container, _Contained, helpers){
 
-		dojo.require("dojo.parser");
-
-		dojo.ready(function(){
-			dojo.declare("dijit.TestContainer",
-				[dijit._Widget, dijit._Container], { }
+			declare("TestContainer",
+					[_WidgetBase, _Container], { }
 			);
-	
-			dojo.declare("dijit.TestContained",
-				[dijit._Widget, dijit._Contained], {}
+
+			declare("TestContained",
+					[_WidgetBase, _Contained], {}
 			);
 
 			doh.register("parse", function(){
-				dojo.parser.parse();
+				parser.parse();
 			});
 
-			doh.register("dijit._Container",
-				[
-					{
-						name: "getChildren",
-						runTest: function(t){
-							console.log("getChildren test");
-							var c = dijit.byId("container");
-							var children = c.getChildren();
-							t.is(4, children.length);
-							t.is("zero", children[0].id);
-							t.is("one", children[1].id);
-							t.is("two", children[2].id);
-							t.is("three", children[3].id);
-						}
-					},
-					{
-						name: "_getSiblingOfChild",
-						runTest: function(t){
-							var c = dijit.byId("container");
-							var children = c.getChildren();
-							t.is("one", c._getSiblingOfChild(children[0], 1).id);
-							t.is("two", c._getSiblingOfChild(children[1], 1).id);
-							t.is("three", c._getSiblingOfChild(children[2], 1).id);
-							t.is(null, c._getSiblingOfChild(children[3], 1));
-							t.is(null, c._getSiblingOfChild(children[0], -1));
-							t.is("zero", c._getSiblingOfChild(children[1], -1).id);
-							t.is("one", c._getSiblingOfChild(children[2], -1).id);
-							t.is("two", c._getSiblingOfChild(children[3], -1).id);
-						}
-					},
-					{
-						name: "getIndexOfChild",
-						runTest: function(t){
-							var c = dijit.byId("container");
-							t.is(0, c.getIndexOfChild(dijit.byId("zero")));
-							t.is(1, c.getIndexOfChild(dijit.byId("one")));
-							t.is(2, c.getIndexOfChild(dijit.byId("two")));
-							t.is(3, c.getIndexOfChild(dijit.byId("three")));
-							t.is(-1, c.getIndexOfChild(dijit.byId("outside")));
-							t.is(-1, c.getIndexOfChild(dijit.byId("outsideCont")));
-						}
-					},
-					{
-						name: "getIndexInParent",
-						runTest: function(t){
-							t.is(0, dijit.byId("zero").getIndexInParent());
-							t.is(1, dijit.byId("one").getIndexInParent());
-							t.is(2, dijit.byId("two").getIndexInParent());
-							t.is(-1, dijit.byId("outsideCont").getIndexInParent());
-						}
-					},
-					{
-						name: "removeChild",
-						runTest: function(t){
-							var c = dijit.byId("container");
-							var children = c.getChildren();
-							t.is(4, children.length);
-							c.removeChild(dijit.byId("zero"));
-							c.removeChild(1); // should remove "two" - because zero is already removed
-							children = c.getChildren();
-							t.is(2, children.length);
-							t.is("one", children[0].id);
-							t.is("three", children[1].id);
-						}
-					},
-					{
-						name: "addChild",
-						runTest: function(t){
-							var c = dijit.byId("container");
+			doh.register("basic tests", [
+				{
+					name: "getChildren",
+					runTest: function(t){
+						var c = registry.byId("container");
+						var children = c.getChildren();
+						t.is(4, children.length);
+						t.is("zero", children[0].id);
+						t.is("one", children[1].id);
+						t.is("two", children[2].id);
+						t.is("three", children[3].id);
+					}
+				},
+				{
+					name: "_getSiblingOfChild",
+					runTest: function(t){
+						var c = registry.byId("container");
+						var children = c.getChildren();
+						t.is("one", c._getSiblingOfChild(children[0], 1).id);
+						t.is("two", c._getSiblingOfChild(children[1], 1).id);
+						t.is("three", c._getSiblingOfChild(children[2], 1).id);
+						t.is(null, c._getSiblingOfChild(children[3], 1));
+						t.is(null, c._getSiblingOfChild(children[0], -1));
+						t.is("zero", c._getSiblingOfChild(children[1], -1).id);
+						t.is("one", c._getSiblingOfChild(children[2], -1).id);
+						t.is("two", c._getSiblingOfChild(children[3], -1).id);
+					}
+				},
+				{
+					name: "getIndexOfChild",
+					runTest: function(t){
+						var c = registry.byId("container");
+						t.is(0, c.getIndexOfChild(registry.byId("zero")));
+						t.is(1, c.getIndexOfChild(registry.byId("one")));
+						t.is(2, c.getIndexOfChild(registry.byId("two")));
+						t.is(3, c.getIndexOfChild(registry.byId("three")));
+						t.is(-1, c.getIndexOfChild(registry.byId("outside")));
+						t.is(-1, c.getIndexOfChild(registry.byId("outsideCont")));
+					}
+				},
+				{
+					name: "getIndexInParent",
+					runTest: function(t){
+						t.is(0, registry.byId("zero").getIndexInParent());
+						t.is(1, registry.byId("one").getIndexInParent());
+						t.is(2, registry.byId("two").getIndexInParent());
+						t.is(-1, registry.byId("outsideCont").getIndexInParent());
+					}
+				},
+				{
+					name: "removeChild",
+					runTest: function(t){
+						var c = registry.byId("container");
+						var children = c.getChildren();
+						t.is(4, children.length);
+						c.removeChild(registry.byId("zero"));
+						c.removeChild(1); // should remove "two" - because zero is already removed
+						children = c.getChildren();
+						t.is(2, children.length);
+						t.is("one", children[0].id);
+						t.is("three", children[1].id);
+					}
+				},
+				{
+					name: "addChild",
+					runTest: function(t){
+						var c = registry.byId("container");
 
-							// Add child at beginning
-							c.addChild(dijit.byId("zero"), 0);
-							children = c.getChildren();
-							t.is(3, children.length);
-							t.is("zero", children[0].id, "after addChild(zero), zero");
-							t.is("one", children[1].id, "after addChild(zero), one");
-							t.is("three", children[2].id, "after addChild(zero), three");
+						// Add child at beginning
+						c.addChild(registry.byId("zero"), 0);
+						children = c.getChildren();
+						t.is(3, children.length);
+						t.is("zero", children[0].id, "after addChild(zero), zero");
+						t.is("one", children[1].id, "after addChild(zero), one");
+						t.is("three", children[2].id, "after addChild(zero), three");
 
-							// Add child in middle
-							c.addChild(dijit.byId("two"), 2);
-							children = c.getChildren();
-							t.is(4, children.length);
-							t.is("zero", children[0].id, "after addChild(two), zero");
-							t.is("one", children[1].id, "after addChild(two), one");
-							t.is("two", children[2].id, "after addChild(two), two");
-							t.is("three", children[3].id, "after addChild(two), three");
+						// Add child in middle
+						c.addChild(registry.byId("two"), 2);
+						children = c.getChildren();
+						t.is(4, children.length);
+						t.is("zero", children[0].id, "after addChild(two), zero");
+						t.is("one", children[1].id, "after addChild(two), one");
+						t.is("two", children[2].id, "after addChild(two), two");
+						t.is("three", children[3].id, "after addChild(two), three");
 
-							// Add child at end
-							c.addChild(new dijit.TestContained({id: "four"}));
-							children = c.getChildren();
-							t.is(5, children.length);
-							t.is("zero", children[0].id, "after addChild(four), zero");
-							t.is("one", children[1].id, "after addChild(four), one");
-							t.is("two", children[2].id, "after addChild(four), two");
-							t.is("three", children[3].id, "after addChild(four), three");
-							t.is("four", children[4].id, "after addChild(four), three");
-						}
+						// Add child at end
+						c.addChild(new TestContained({id: "four"}));
+						children = c.getChildren();
+						t.is(5, children.length);
+						t.is("zero", children[0].id, "after addChild(four), zero");
+						t.is("one", children[1].id, "after addChild(four), one");
+						t.is("two", children[2].id, "after addChild(four), two");
+						t.is("three", children[3].id, "after addChild(four), three");
+						t.is("four", children[4].id, "after addChild(four), four");
+
+						// Add child at end with explicit position specified
+						c.addChild(new TestContained({id: "five"}), 5);
+						children = c.getChildren();
+						t.is(6, children.length);
+						t.is("zero", children[0].id, "after addChild(five), zero");
+						t.is("one", children[1].id, "after addChild(five), one");
+						t.is("two", children[2].id, "after addChild(five), two");
+						t.is("three", children[3].id, "after addChild(five), three");
+						t.is("four", children[4].id, "after addChild(five), four");
+						t.is("five", children[5].id, "after addChild(five), five");
 					}
-				]
-			);
+				}
+			]);
 
 			doh.run();
 		});
@@ -136,14 +143,15 @@
 </head>
 <body class="claro">
 
-	<div id="container" data-dojo-type="dijit.TestContainer">
-		<!-- comment just to make sure that numbering isn't thrown off -->
-		<div id="zero" data-dojo-type="dijit.TestContained"></div>
-		<div id="one" data-dojo-type="dijit.TestContained"></div>
-		<div id="two" data-dojo-type="dijit.TestContained"></div>
-		<div id="three" data-dojo-type="dijit._Widget"></div>
-	</div>
-	<div id="outside" data-dojo-type="dijit._Widget"></div>
-	<div id="outsideCont" data-dojo-type="dijit.TestContained"></div>
+<label for="input">before:</label><input id="input"/>
+<div id="container" data-dojo-type="TestContainer">
+	<!-- comment just to make sure that numbering isn't thrown off -->
+	<div id="zero" data-dojo-type="TestContained"></div>
+	<div id="one" data-dojo-type="TestContained"></div>
+	<div id="two" data-dojo-type="TestContained"></div>
+	<div id="three" data-dojo-type="dijit/_WidgetBase"></div>
+</div>
+<div id="outside" data-dojo-type="dijit/_WidgetBase"></div>
+<div id="outsideCont" data-dojo-type="TestContained"></div>
 </body>
 </html>
diff --git a/dijit/tests/_HasDropDown.html b/dijit/tests/_HasDropDown.html
new file mode 100644
index 0000000..dfb495b
--- /dev/null
+++ b/dijit/tests/_HasDropDown.html
@@ -0,0 +1,149 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>_HasDropDown unit test</title>
+
+<script type="text/javascript" src="boilerplate.js"></script>
+
+<script type="text/javascript">
+require([
+	"doh/runner",
+	"dojo/_base/declare", "dojo/keys", "dojo/on", "dojo/_base/window",
+	"dijit/_HasDropDown", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
+	"dijit/tests/helpers", "dojo/domReady!"
+], function(doh, declare, keys, on, win,
+			_HasDropDown, _WidgetBase, _TemplatedMixin, helpers){
+
+
+	var SimplePopup = declare([_WidgetBase, _TemplatedMixin], {
+		// summary:
+		//		A trivial popup widget
+
+		label: "i'm a popup",
+		templateString: "<span>${label}</span>"
+	});
+
+	var SimpleDropDownButton = declare([_WidgetBase, _TemplatedMixin, _HasDropDown], {
+		// summary:
+		//		A button that shows a popup.
+
+		label: "show popup",
+		popupLabel: "i'm a popup",
+		orient: ["below"],
+
+		templateString: "<button>${label}</button>",
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this.dropDown = new SimplePopup({
+				id: this.id + "_popup",
+				label: this.popupLabel
+			});
+		}
+	});
+
+	var NonFocusableDropDownButton = declare([_WidgetBase, _TemplatedMixin, _HasDropDown], {
+		// summary:
+		//		A non-focusable "button" that shows a popup.   Should work for mouse, although not for keyboard.
+
+		label: "show popup (non-focusable)",
+		orient: ["below"],
+
+		templateString: "<span>${label}</span>",
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this.dropDown = new SimplePopup({
+				id: this.id + "_popup",
+				label: "popup from non-focusable"
+			});
+		}
+	});
+
+	// Synthetic events.   Could alternately use robot.
+	function key(node, key){
+		on.emit(node, "keydown", {
+			keyCode: key,
+			bubbles: true
+		});
+		on.emit(node, "keyup", {
+			keyCode: key,
+			bubbles: true
+		});
+	}
+	function click(node){
+		on.emit(node, navigator.msPointerEnabled ? "MSPointerDown" : "mousedown", {
+			button: 0,	// left button (except on IE quirks mode, when it's 1)
+			bubbles: true
+		});
+		on.emit(node, navigator.msPointerEnabled ? "MSPointerUp" : "mouseup", {
+			button: 0,	// left button (except on IE quirks mode, when it's 1)
+			bubbles: true
+		});
+		on.emit(node, "click", {
+			bubbles: true
+		});
+	}
+
+	doh.register("basic", [
+		function setup(){
+			dd = new SimpleDropDownButton({id: "dd"}).placeAt(win.body());
+			popup = dd.dropDown;
+			doh.t(!!popup, "popup exists");
+		},
+		function open(){
+			var d = new doh.Deferred();
+			click(dd.domNode);
+			setTimeout(d.getTestCallback(function(){
+				doh.t(helpers.isVisible(popup), "popup visible");
+			}), 10);
+			return d;
+		},
+		function close(){
+			dd.closeDropDown();
+			doh.t(helpers.isHidden(popup), "popup hidden");
+		},
+		function openBySpace(){
+			var d = new doh.Deferred();
+			key(dd.domNode, keys.SPACE);
+			setTimeout(d.getTestCallback(function(){
+				doh.t(!!popup, "popup exists");
+				doh.t(helpers.isVisible(popup), "popup visible again");
+			}), 10);
+			return d;
+		},
+		function close2(){
+			dd.closeDropDown();
+			doh.t(helpers.isHidden(popup), "popup hidden again");
+		}
+		// TODO: open by down arrow
+	]);
+
+
+	doh.register("non focusable", [
+		function setup(){
+			ndd = new NonFocusableDropDownButton({id: "ndd"}).placeAt(win.body());
+			popup = ndd.dropDown;
+			doh.t(!!popup, "popup exists");
+		},
+		function open(){
+			var d = new doh.Deferred();
+			click(ndd.domNode);
+			setTimeout(d.getTestCallback(function(){
+				doh.t(helpers.isVisible(popup), "popup visible");
+			}), 10);
+			return d;
+		},
+		function close(){
+			ndd.closeDropDown();
+		}
+	]);
+
+	doh.run();
+});
+</script>
+</head>
+<body class="claro">
+<h1>_HasDropDown Unit Test</h1>
+</body>
+</html>
diff --git a/dijit/tests/_KeyNavContainer.html b/dijit/tests/_KeyNavContainer.html
new file mode 100644
index 0000000..f57cc27
--- /dev/null
+++ b/dijit/tests/_KeyNavContainer.html
@@ -0,0 +1,165 @@
+<!DOCTYPE html>
+<html>
+<head>
+
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
+	<title>_KeyNavContainer</title>
+
+	<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/_base/declare", "dojo/dom", "dojo/keys", "dojo/on", "dojo/parser",
+			"dijit/a11y", "dijit/focus", "dijit/registry",
+			"dijit/_WidgetBase", "dijit/_KeyNavContainer",
+			"dijit/tests/helpers", "dojo/domReady!"
+		], function(doh, declare, dom, keys, on, parser, a11y, focus, registry, _WidgetBase, _KeyNavContainer, helpers){
+
+			declare("TestContainer", [_WidgetBase, _KeyNavContainer], {
+				postCreate: function(){
+					this.inherited(arguments);
+					this.connectKeyNavHandlers([keys.LEFT_ARROW, keys.UP_ARROW], [keys.RIGHT_ARROW, keys.DOWN_ARROW]);
+				}
+			});
+	
+			declare("TestContained", _WidgetBase, {
+				// _KeyNavContainer requires children to have focus()
+				focus: function(){
+					this.domNode.focus();
+				}
+			});
+
+			doh.register("parse", function(){
+				parser.parse();
+			});
+
+
+			/*
+			 * Most of _KeyNavContainer is tested indirectly via Menu, Toolbar, etc. test suites, but
+			 * starting to build up some basic tests here.
+			 */
+
+			doh.register("basic", [
+				{
+					name: "initial",
+					runTest: function(){
+						var c = registry.byId("container");
+
+						// initially container has tabIndex of 0
+						doh.is(0, c.domNode.getAttribute("tabIndex"), "container tabIndex=0");
+
+						// and all the contents have tabIndex of -1, or no tab index
+						doh.f(a11y.isTabNavigable("zero"), "child not tab navigable");
+					}
+				},
+				{
+					name: "tab in",
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						var c = registry.byId("container");
+
+						// focusing container (simulated tabbing into container) should move focus to first child
+						c.focus();
+
+						setTimeout(d.getTestCallback(function(){
+							doh.is("zero", focus.curNode.id, "focus moved to first child");
+							doh.t(a11y.isTabNavigable("zero"), "child is tab navigable");
+							doh.isNot(0, c.domNode.getAttribute("tabIndex"), "container tabIndex removed or set to -1");
+						}), 0);
+
+						return d;
+					}
+				},
+				{
+					name: "next",
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						var c = registry.byId("container");
+
+						on.emit(c.domNode, "keydown", {keyCode: keys.DOWN_ARROW, bubbles: true, cancelable: true});
+
+						setTimeout(d.getTestCallback(function(){
+							doh.is("one", focus.curNode.id, "focus moved to second child");
+							doh.f(a11y.isTabNavigable("zero"), "zero not tab navigable");
+							doh.t(a11y.isTabNavigable("one"), "one tab navigable");
+						}), 0);
+
+						return d;
+					}
+				},
+				{
+					name: "previous",
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						var c = registry.byId("container");
+
+						on.emit(c.domNode, "keydown", {keyCode: keys.LEFT_ARROW, bubbles: true, cancelable: true});
+
+						setTimeout(d.getTestCallback(function(){
+							doh.is("zero", focus.curNode.id, "focus moved to first child");
+							doh.f(a11y.isTabNavigable("one"), "one not tab navigable");
+							doh.t(a11y.isTabNavigable("zero"), "zero tab navigable");
+						}), 0);
+
+						return d;
+					}
+				},
+				{
+					name: "tab out",
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						var c = registry.byId("container");
+
+						dom.byId("input").focus();
+
+						// tab index on container restored
+						setTimeout(d.getTestCallback(function(){
+							doh.f(a11y.isTabNavigable("zero"), "child not tab navigable");
+							doh.is(0, c.domNode.getAttribute("tabIndex"), "container tabIndex restored");
+						}), 0);
+
+						return d;
+					}
+				},
+				{
+					name: "mouse in",
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						var c = registry.byId("container");
+
+						dom.byId("zero").focus();
+
+						// focusing first child directly (simulated mouse click) should remove tabIndex on container
+						setTimeout(d.getTestCallback(function(){
+							doh.isNot(0, c.domNode.getAttribute("tabIndex"), "container tabIndex removed or set to -1");
+							doh.t(a11y.isTabNavigable("zero"), "child tab navigable");
+						}), 0);
+
+						return d;
+					}
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+<body class="claro">
+
+	<label for="input">before:</label><input id="input"/>
+	<div id="container" data-dojo-type="TestContainer">
+		<!-- comment just to make sure that numbering isn't thrown off -->
+		<div id="zero" data-dojo-type="TestContained">zero</div>
+		<div id="one" data-dojo-type="TestContained">one</div>
+		<div id="two" data-dojo-type="TestContained">two</div>
+		<div id="three" data-dojo-type="TestContained">three</div>
+	</div>
+</body>
+</html>
diff --git a/dijit/tests/_Templated-widgetsInTemplate1.x.html b/dijit/tests/_Templated-widgetsInTemplate1.x.html
index 1a7f7f9..29a8ec1 100644
--- a/dijit/tests/_Templated-widgetsInTemplate1.x.html
+++ b/dijit/tests/_Templated-widgetsInTemplate1.x.html
@@ -22,7 +22,6 @@
 			dojo.require("dijit._Container");
 			dojo.require("dijit._Contained");
 			dojo.require("dijit.layout._LayoutWidget");
-			dojo.require("dijit.focus");	// dijit.focus()
 
 			dojo.ready(function(){
 				var testW;
@@ -64,7 +63,7 @@
 		
 				function validateTest4Widget(t, testW){
 					var selectedTab = dojo.query(".dijitTabChecked", testW.domNode)[0];
-					var selectedPane = dojo.query(".dijitTabPane.dijitVisible", testW.domNode)[0];
+					var selectedPane = dojo.query(".dijitVisible > .dijitTabPane", testW.domNode)[0];
 					var tabBox = selectedTab ? dojo.contentBox(selectedTab) : null;
 					var paneBox = selectedPane ? dojo.contentBox(selectedPane) : null;
 					t.t(tabBox && tabBox.w > 0 && tabBox.h > 0, "tabBox && tabBox.w > 0 && tabBox.h > 0");
@@ -318,9 +317,8 @@
 							// Compare programmatic and declaratively created widget with layout widgets in template
 							name: "programmatic vs declarative with layout widgets",
 							runTest: function(t){
-								// Focus the body, so that we don't have different classes on our
-								// two widgets
-								dijit.focus(dojo.body());
+								// Focus unrelated element, so that we don't have different classes on our two widgets
+								dojo.byId("plainInput").focus();
 								var declW = dijit.byId("test4Widget");
 								var progW = test4WidgetProgrammatic;
 
@@ -486,6 +484,7 @@
 	<div dojoType="Test5Widget" id="test5Widget" ></div>
 
 	<div dojoType="Missing" id="missing"></div>
+	<input id="plainInput"/>
 	</body>
 </html>
 
diff --git a/dijit/tests/_TemplatedMixin.html b/dijit/tests/_TemplatedMixin.html
index d44bcb0..ca258b7 100644
--- a/dijit/tests/_TemplatedMixin.html
+++ b/dijit/tests/_TemplatedMixin.html
@@ -1,230 +1,284 @@
 <!DOCTYPE html>
 <html>
 	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>_Templated tests</title>
-		<script type="text/javascript" src="../../dojo/dojo.js"
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>_Templated tests</title>
+	<script type="text/javascript" src="../../dojo/dojo.js"
 			data-dojo-config="isDebug: true"></script>
-		<script type="text/javascript">
-			dojo.require("doh.runner");
-
-			dojo.require("dojo.parser");
-
-			dojo.require("dijit._Widget");
-			dojo.require("dijit._TemplatedMixin");
-			dojo.require("dijit._WidgetsInTemplateMixin");
-
-			dojo.require("dijit.layout.LayoutContainer");
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/_base/array", "dojo/_base/declare", "dojo/dom", "dojo/query",
+			"dijit/_WidgetBase", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin", "dijit/layout/LayoutContainer",
+			"dojo/domReady!"
+		], function(doh, array, declare, dom, query, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin){
 
 			function getOuterHTML(/*DomNode*/ node){
-				var wrapper = dojo.doc.createElement("div");
+				var wrapper = document.createElement("div");
 				wrapper.appendChild(node);
 				return wrapper.innerHTML.toLowerCase();		// IE prints <BUTTON> rather than <button>; normalize it.
 			}
 
-			dojo.ready(function(){
-				// Template with no variables (should be cached as a DOM tree)
-				dojo.declare("SimpleTemplate", [dijit._Widget, dijit._TemplatedMixin], {
-					id: "test1",
-					_setIdAttr: null,	// override _Widget to not copy id to domNode
-
-					templateString: "<button type='button'><span>hello < world</span></button>"
-				});
-
-				// Template with variables
-				dojo.declare("VariableTemplate", [dijit._Widget, dijit._TemplatedMixin], {
-					id: "test2",
-					_setIdAttr: null,	// override _Widget to not copy id to domNode
-
-					num: 5,
-					bool: false,
-					text: "hello <\"' world",
-
-					templateString: "<button><span num=\"${num}\" value=\"${bool}\">${text}</span></button>"
-				});
-
-				// Template with ! variables (for literal substitution)
-				dojo.declare("ExclamationVariableTemplate", [dijit._Widget, dijit._TemplatedMixin], {
-					markup: "<span>hello world</span>",
-
-					templateString: "<div>${!markup}</div>"
-				});
-
-				// Template that starts with special node (has to be constructed inside a <tbody>)
-				dojo.declare("TableRowTemplate", [dijit._Widget, dijit._TemplatedMixin], {
-					id: "test3",
-					_setIdAttr: null,	// override _Widget to not copy id to domNode
-					text: "bar",
-
-					templateString: "<tr><td>${text}</td></tr>"
-				});
-
-				// Illegal substitution variable name
-				dojo.declare("IllegalSubstitution", [dijit._Widget, dijit._TemplatedMixin], {
-					templateString: "<tr><td>${fake}</td></tr>"
-				});
-
-				// data-dojo-attach-point
-				dojo.declare("AttachPoint", [dijit._Widget, dijit._TemplatedMixin], {
-					templateString: "<div style='border: 1px solid red'>" +
-										"<button data-dojo-attach-point='buttonNode,focusNode'>hi</button>" +
-										'<span><input data-dojo-attach-point="inputNode" value="input"/></span>' +
-										"<span data-dojo-attach-point='containerNode'></span>" +
-									"</div>"
-				});
-
-				// data-dojo-attach-event
-				dojo.declare("AttachEvent", [dijit._Widget, dijit._TemplatedMixin], {
-					click: function(){ this.clickCalled=true; },
-					onfocus: function(){ this.focusCalled=true; },
-					focus2: function(){ this.focus2Called=true; },
-					templateString: "<table style='border: 1px solid blue'><tr>" +
-										"<td><button type='button' data-dojo-attach-point='left' data-dojo-attach-event='onclick: click, onfocus'>left</button></td>" +
-										"<td><button type='button' data-dojo-attach-point='right' data-dojo-attach-event='onclick: click, onfocus: focus2'>right</button></td>" +
-									"</tr></table>"
-				});
-
-				var testW;
-
-				doh.register("parse", function(){
-					dojo.parser.parse();
-				});
-
-				doh.register("_TemplatedMixin",
-					[
-						function simple(t){
-							var widget=new SimpleTemplate();
-							var wrapper=dojo.byId("simpleWrapper");
-							wrapper.appendChild(widget.domNode);
-							
-							// Different browsers have different orders for type=button and widgetid=... so simplify
-							// by just removing the type=button.
-							t.is('<button widgetid=\"test1\"><span>hello < world</span></button>', wrapper.innerHTML.toLowerCase().replace(/ type="?button"?/, ""));
-						},
+			// Template with no variables (should be cached as a DOM tree)
+			declare("SimpleTemplate", [_WidgetBase, _TemplatedMixin], {
+				id: "test1",
+				_setIdAttr: null, // override _Widget to not copy id to domNode
 
-						function variables(t){
-							var widget=new VariableTemplate();
-							var span = widget.domNode.getElementsByTagName("span")[0];
-							var text = span.innerHTML;
-							t.is("5", span.getAttribute("num"));
-							t.is("false", span.getAttribute("value"));
-							t.is("hello <\"' world", text);
-						},
-						function variables2(t){
-							var widget = new VariableTemplate({id: "myid", num: -5, bool: true, text: ""});
-							var span = widget.domNode.getElementsByTagName("span")[0];
-							var text = span.innerHTML;
-							t.is("-5", span.getAttribute("num"));
-							t.is("true", span.getAttribute("value"));
-							t.is("", text);
-						},
-						function variablesWithExclamation(t){
-							var widget=new ExclamationVariableTemplate();
-
-							// ExclamationVariableTemplate should create markup like
-							//		<div><span>hello world</span></div>
-							// The <span> comes from the ${!markup} variable.
-							var span = dojo.query("> *", widget.domNode);
-							t.is(1, span.length, "dom node has one child");
-							t.is("SPAN", span[0].nodeName.toUpperCase(), "which is a span");
-							t.is("hello world", span[0].innerHTML, "and the text is set correctly too");
-						},
+				templateString: "<button type='button'><span>hello < world</span></button>"
+			});
 
-						function table(t){
-							var widget=new TableRowTemplate({text: "hello"});
-							var wrapper = dojo.byId("trWrapper");
-							wrapper.appendChild(widget.domNode);
-							var actual = wrapper.innerHTML.toLowerCase().replace(/\r/g, "").replace(/\n/g, "");
-							t.is('<tr widgetid="test3"><td>hello</td></tr>', actual);
-						},
-						function illegal(t){
-							var hadException=false;
-							try{
-								var widget=new IllegalSubstitution();
-							}catch(e){
-								console.log(e);
-								hadException=true;
-							}
-							t.t(hadException);
-						},
-						function attachPoint(t){
-							var widget=new AttachPoint();
-							var wrapper = dojo.byId("attachPointWrapper");
-							wrapper.appendChild(widget.domNode);
-							t.is(widget.containerNode.tagName.toLowerCase(), "span");
-							t.is(widget.buttonNode.tagName.toLowerCase(), "button");
-							t.is(widget.focusNode.tagName.toLowerCase(), "button");
-							t.is(widget.inputNode.tagName.toLowerCase(), "input");
+			// Template with variables
+			declare("VariableTemplate", [_WidgetBase, _TemplatedMixin], {
+				id: "test2",
+				_setIdAttr: null, // override _Widget to not copy id to domNode
+
+				num: 5,
+				bool: false,
+				text: "hello <\"' world",
+
+				templateString: "<button><span num=\"${num}\" value=\"${bool}\">${text}</span></button>"
+			});
+
+			// Template with ! variables (for literal substitution)
+			declare("ExclamationVariableTemplate", [_WidgetBase, _TemplatedMixin], {
+				markup: "<span>hello world</span>",
+
+				templateString: "<div>${!markup}</div>"
+			});
+
+			// Template that starts with special node (has to be constructed inside a <tbody>)
+			declare("TableRowTemplate", [_WidgetBase, _TemplatedMixin], {
+				id: "test3",
+				_setIdAttr: null, // override _Widget to not copy id to domNode
+				text: "bar",
+
+				templateString: "<tr><td>${text}</td></tr>"
+			});
+
+			// Illegal substitution variable name
+			declare("IllegalSubstitution", [_WidgetBase, _TemplatedMixin], {
+				templateString: "<tr><td>${fake}</td></tr>"
+			});
+
+			// data-dojo-attach-point
+			declare("AttachPoint", [_WidgetBase, _TemplatedMixin], {
+				templateString: "<div style='border: 1px solid red'>" +
+						"<button data-dojo-attach-point='buttonNode,focusNode'>hi</button>" +
+						'<span><input data-dojo-attach-point="inputNode" value="input"/></span>' +
+						"<span data-dojo-attach-point='containerNode'></span>" +
+						"</div>"
+			});
+
+			// data-dojo-attach-event
+			declare("AttachEvent", [_WidgetBase, _TemplatedMixin], {
+				click: function(){
+					this.clickCalled = true;
+				},
+				onfocus: function(){
+					this.focusCalled = true;
+				},
+				focus2: function(){
+					this.focus2Called = true;
+				},
+				templateString: "<table style='border: 1px solid blue'><tr>" +
+						"<td><button type='button' data-dojo-attach-point='left' data-dojo-attach-event='onclick: click, onfocus'>left</button></td>" +
+						"<td><button type='button' data-dojo-attach-point='right' data-dojo-attach-event='onclick: click, onfocus: focus2'>right</button></td>" +
+						"</tr></table>"
+			});
+
+			var testW;
+
+			doh.register("_TemplatedMixin", [
+				function simple(t){
+					var widget = new SimpleTemplate();
+					var wrapper = dom.byId("simpleWrapper");
+					wrapper.appendChild(widget.domNode);
+
+					// Different browsers have different orders for type=button and widgetid=... so simplify
+					// by just removing the type=button.
+					t.is('<button widgetid=\"test1\"><span>hello < world</span></button>', wrapper.innerHTML.toLowerCase().replace(/ type="?button"?/, ""));
+				},
+
+				function variables(t){
+					var widget = new VariableTemplate();
+					var span = widget.domNode.getElementsByTagName("span")[0];
+					var text = span.innerHTML;
+					t.is("5", span.getAttribute("num"));
+					t.is("false", span.getAttribute("value"));
+					t.is("hello <\"' world", text);
+				},
+				function variables2(t){
+					var widget = new VariableTemplate({id: "myid", num: -5, bool: true, text: ""});
+					var span = widget.domNode.getElementsByTagName("span")[0];
+					var text = span.innerHTML;
+					t.is("-5", span.getAttribute("num"));
+					t.is("true", span.getAttribute("value"));
+					t.is("", text);
+				},
+				function variablesWithExclamation(t){
+					var widget = new ExclamationVariableTemplate();
+
+					// ExclamationVariableTemplate should create markup like
+					//		<div><span>hello world</span></div>
+					// The <span> comes from the ${!markup} variable.
+					var span = query("> *", widget.domNode);
+					t.is(1, span.length, "dom node has one child");
+					t.is("SPAN", span[0].nodeName.toUpperCase(), "which is a span");
+					t.is("hello world", span[0].innerHTML, "and the text is set correctly too");
+				},
+
+				function table(t){
+					var widget = new TableRowTemplate({text: "hello"});
+					var wrapper = dom.byId("trWrapper");
+					wrapper.appendChild(widget.domNode);
+					var actual = wrapper.innerHTML.toLowerCase().replace(/\r/g, "").replace(/\n/g, "");
+					t.is('<tr widgetid="test3"><td>hello</td></tr>', actual);
+				},
+				function illegal(t){
+					var hadException = false;
+					try{
+						var widget = new IllegalSubstitution();
+					}catch(e){
+						console.log(e);
+						hadException = true;
+					}
+					t.t(hadException);
+				},
+				function attachPoint(t){
+					var widget = new AttachPoint();
+					var wrapper = dom.byId("attachPointWrapper");
+					wrapper.appendChild(widget.domNode);
+					t.is(widget.containerNode.tagName.toLowerCase(), "span");
+					t.is(widget.buttonNode.tagName.toLowerCase(), "button");
+					t.is(widget.focusNode.tagName.toLowerCase(), "button");
+					t.is(widget.inputNode.tagName.toLowerCase(), "input");
+				},
+				function attachEvent(t){
+					var deferred = new doh.Deferred();
+					var widget = new AttachEvent();
+					var wrapper = dom.byId("attachEventWrapper");
+					wrapper.appendChild(widget.domNode);
+					widget.left.focus();
+					widget.right.focus();
+					setTimeout(deferred.getTestCallback(function(){
+						t.t(widget.focusCalled, "left focused");
+						t.t(widget.focus2Called, "right focused");
+					}), 50);
+					return deferred;
+				},
+
+				function widgetsInTemplateLifecycle(t){
+
+					var result = [], expected = [1, 1, 0, 2, 2, 3];
+
+					// widgetsInTemplateLifecycle
+					declare("SubThing", _WidgetBase, {
+						postCreate: function(){
+							this.inherited(arguments);
+							result.push(1);
 						},
-						function attachEvent(t){
-							var deferred = new doh.Deferred();
-							var widget = new AttachEvent();
-							var wrapper = dojo.byId("attachEventWrapper");
-							wrapper.appendChild(widget.domNode);
-							widget.left.focus();
-							widget.right.focus();
-							setTimeout(deferred.getTestCallback(function(){
-								t.t(widget.focusCalled, "left focused");
-								t.t(widget.focus2Called, "right focused");
-							}), 50);
-							return deferred;
+						startup: function(){
+							this.inherited(arguments);
+							result.push(2);
+						}
+					});
+
+					declare("ParentThing", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+						templateString: "<div>" +
+								"<span data-dojo-type='SubThing'>a</span>" +
+								"<div data-dojo-type='dijit/layout/LayoutContainer'>" +
+								"<span data-dojo-type='SubThing' data-dojo-props='region: \"center\"'>b</span>" +
+								"</div>" +
+								"</div>",
+						postCreate: function(){
+							// children postcreate (x2) called before this postCreate
+							this.inherited(arguments);
+							result.push(0);
 						},
+						startup: function(){
+							// then children startup (x2) then our startup
+							// (we can call inherited after push(), and change the order)
+							this.inherited(arguments);
+							result.push(3);
+						}
+					});
 
-						function widgetsInTemplateLifecycle(t){
-
-							var result = [], expected = [1,1,0,2,2,3];
-
-							// widgetsInTemplateLifecycle
-							dojo.declare("SubThing", dijit._Widget, {
-								postCreate:function(){
-									this.inherited(arguments);
-									result.push(1);
-								},
-								startup:function(){
-									this.inherited(arguments);
-									result.push(2);
-								}
-							});
-
-							dojo.declare("ParentThing", [dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
-								templateString: "<div>" +
-													"<span data-dojo-type='SubThing'>a</span>" +
-													"<div data-dojo-type='dijit.layout.LayoutContainer'>" +
-														"<span data-dojo-type='SubThing'>b</span>" +
-													"</div>" +
-												"</div>",
-								postCreate:function(){
-									// children postcreate (x2) called before this postCreate
-									this.inherited(arguments);
-									result.push(0);
-								},
-								startup: function(){
-									// then children startup (x2) then our startup
-									// (we can call inherited after push(), and change the order)
-									this.inherited(arguments);
-									result.push(3);
-								}
-							});
-
-							new ParentThing().startup();
-
-							t.is(expected.length, result.length);
-							dojo.forEach(expected, function(r){
-								t.is(r, result.shift());
-							});
+					new ParentThing().startup();
 
-						}
-					]
-				);
-				doh.run();
-			});
-		</script>
+					t.is(expected.length, result.length);
+					array.forEach(expected, function(r){
+						t.is(r, result.shift());
+					});
+
+				},
+
+				// Test IE problem having "length" as data-dojo-attach-point name
+				function length(){
+					var MyWidget = declare([_WidgetBase, _TemplatedMixin], {
+						name: "",
+						templateString: "<div>" +
+								"<input data-dojo-attach-point='focusNode' name='${name}'>" +
+								"<span data-dojo-attach-point='spanNode'>" +
+								"</div>"
+					});
+					var widget = new MyWidget({name: "length"});
+					doh.isNot(undefined, widget.focusNode, "focusNode");
+					doh.isNot(undefined, widget.spanNode, "spanNode");
+				}
+			]);
+
+			// This is more of a test of _WidgetBase, but putting here for convenience
+			// since it tests the case when srcNodeRef is swapped for a widget's template
+			doh.register("srcNodeRef", [
+				function replaceMe(){
+					var prev = dom.byId("replaceMe").previousSibling;
+
+					// This should swap out the <span id="replaceMe"> w/the widget
+					var widget = new SimpleTemplate({}, "replaceMe");
+
+					// Make sure the swap occurred
+					doh.is(widget.domNode, prev.nextSibling, "swapped");
+					doh.is(null, dom.byId("replaceMe"), "original node removed");
+
+					// For garbage collection widget.srcNodeRef should also be cleared
+					doh.is(null, widget.srcNodeRef, "srcNodeRef cleared");
+				}
+			]);
+
+			doh.register("_rendered", [
+				function preRendered(){
+					// Testing for when a widget's template is expanded on the server, so _rendered:true is passed
+					// as a parameter to the widget constructor.
+					var MyWidget = declare([_WidgetBase, _TemplatedMixin], {
+						declaredClass: "MyWidget",
+						templateString: "<input>"	// shouldn't be used, just listing a template for testing purposes
+					});
+					var widget = new MyWidget({
+						_rendered: true	// flag to not do template insertion
+					}, dom.byId("prerendered"));
+					doh.t(widget.heading, "heading attach point setup");
+					doh.is("h2", widget.heading.tagName.toLowerCase());
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
 	</head>
 	<body>
-		<h1>_Templated test</h1>
-		<div id="simpleWrapper"></div>
-		<table><tbody id="trWrapper"></tbody></table>
-		<div id="attachPointWrapper"></div>
-		<div id="attachEventWrapper"></div>
+	<h1>_TemplatedMixin test</h1>
+
+	<div id="simpleWrapper"></div>
+	<table>
+		<tbody id="trWrapper"></tbody>
+	</table>
+	<div id="attachPointWrapper"></div>
+	<div id="attachEventWrapper"></div>
+	<span id="replaceMe"></span>
+
+	<!-- test for _rendered=true flag -->
+	<div id="prerendered">
+		<h2 data-dojo-attach-point="heading">hi</h2>
+	</div>
 	</body>
 </html>
diff --git a/dijit/tests/_TimePicker.html b/dijit/tests/_TimePicker.html
new file mode 100644
index 0000000..d74486c
--- /dev/null
+++ b/dijit/tests/_TimePicker.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>_TimePicker DOH Test</title>
+
+	<script type="text/javascript" src="boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dijit/_TimePicker",
+			"dojo/domReady!"
+		], function(doh, _TimePicker){
+
+			doh.register("tests",
+				function extended_range(){
+					var t1 = _TimePicker({}, "t1");
+					t1.set('value', new Date("December 11, 2011 00:09:30"));
+					doh.is(96, t1.timeMenu.children.length, 'num entries 1');
+				}
+			);
+
+			doh.run();
+		});
+	</script>
+
+</head>
+<body class="claro">
+	<h1 class="testTitle">dijit._TimePicker automated tests (non-robot)</h1>
+	
+	<label for="t1">t1:</label>
+	<div id="t1" style="height: 200px; width: 150px; overflow: auto;"></div>
+</body>
+</html>
diff --git a/dijit/tests/_Widget-attr.html b/dijit/tests/_Widget-attr.html
index 0b86518..641f83b 100644
--- a/dijit/tests/_Widget-attr.html
+++ b/dijit/tests/_Widget-attr.html
@@ -2,203 +2,290 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
-	<title>widget.get()/set() unit test</title>
+	<title>widget attribute unit test (in constructor and get()/set())</title>
 	<style type="text/css">
 		@import "../themes/claro/document.css";
 		@import "css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
-	<script type="text/javascript" src="_testCommon.js"></script>
+		data-dojo-config="isDebug: true, async: true"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-
-		dojo.require("dijit._Widget");
-		dojo.require("dijit._TemplatedMixin");
-
-		dojo.ready(function(){
-			doh.register("attribute set/get",
-				[
-					// Test attributes mapped to DOMNodes
-					function domMapping(){
-						var IndividualMaps = dojo.declare([dijit._Widget, dijit._TemplatedMixin], {
-							// Mapping foo to this.domNode.foo
-							foo:"",
-							_setFooAttr: "",
-			
-							// Mapping bar to this.buttonNode.bar
-							bar: "",
-							_setBarAttr: "buttonNode",
-			
-							// Mapping plainText to this.plainTextNode.innerHTML
-							plainText: "",
-							_setPlainTextAttr: {node: "plainTextNode", type: "innerText"},
-	
-							templateString: "<div class='class1' style='border: 1px solid red; width: 456px'>" +
-												"<button data-dojo-attach-point='buttonNode,focusNode'>hi</button>" +
-												'<span><input data-dojo-attach-point="inputNode" value="input"></span>' +
-												"<span data-dojo-attach-point='containerNode'></span>" +
-												"<span data-dojo-attach-point='plainTextNode'>original plain text</span>" +
-											"</div>"
-						});
-
-						var widget = new IndividualMaps({
-							foo:"value1",
-							bar:"value2",
-							"class":"class2",
-							style:"height: 123px",
-							plainText: "hello world <>&;",
-							"name-with-dashes": "name with dashes"
-						}).placeAt(dojo.byId("wrapper"));
-
-						// test attributes specified to constructor were copied over to DOM
-						doh.is("value1", widget.domNode.getAttribute("foo"), "widget.domNode.getAttribute('foo')");
-						doh.is("value2", widget.buttonNode.getAttribute("bar"), "widget.domNode.getAttribute('bar')");
-						doh.t(dojo.hasClass(widget.domNode, "class1"), "class1");
-						doh.t(dojo.hasClass(widget.domNode, "class2"), "class2");
-						doh.is("123px", dojo.style(widget.domNode).height, "height");
-						doh.is("456px", dojo.style(widget.domNode).width, "width");
-						doh.is("hello world <>&;", widget.plainTextNode.innerHTML, "innerHTML");
-					},
-
-					// Test that certain attributes are automatically applied to focusNode or domNode.
-					// These are attributes that aren't mentioned at all in _Widget.
-					function autoDomMapping(){
-						// Mapping to this.domNode
-						var w = new dijit._Widget({
-							title: "dom title",
-							"aria-labelledby": "foo",
-							role: "button"
-						});
-						doh.is("dom title", dojo.attr(w.domNode, "title"), "domNode title");
-						doh.is("foo", w.domNode.getAttribute("aria-labelledby", "domNode labelledby"));
-						doh.is("button", dojo.attr(w.domNode, "role"), "domNode role");
-
-						// Mapping to this.focusNode
-						var fw = (new dojo.declare([dijit._WidgetBase, dijit._TemplatedMixin], {
-							templateString: "<div><input data-dojo-attach-point='focusNode'/></div>"
-						}))({
-							title: "my title",
-							"aria-labelledby": "foo"
-						});
-						doh.is("my title", dojo.attr(fw.focusNode, "title"), "focusNode title");
-						doh.is("foo", fw.focusNode.getAttribute("aria-labelledby"), "focusNode labelledby");
-
-						// Mapping attributes with dashes and mixed case
-						var mc = (new dojo.declare([dijit._WidgetBase, dijit._TemplatedMixin], {
-							templateString: "<form></form>"
-						}))({
-							"accept-charset": "utf8",
-							"novalidate": "true"	// parser delivers as lowercase even though it's noValidate in JS obj
-						});
-						doh.is("utf8", mc.domNode.getAttribute("accept-charset"), "accept-charset");
-						if(dojo.isFF >= 4 || dojo.isIE >= 10 || dojo.isWebKit){
-							// only works for HTML5 compliant browsers where novalidate is understood
-							doh.t(mc.domNode.hasAttribute("novalidate"), "noValidate");
+		require([
+			"doh/runner", "dojo/_base/declare",
+			"dojo/dom", "dojo/dom-attr", "dojo/dom-class", "dojo/dom-style", "dojo/sniff",
+			"dijit/_WidgetBase", "dijit/_Widget",
+			"dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin",
+			"dojo/domReady!"
+		], function(doh, declare, dom, domAttr, domClass, domStyle, has,
+					_WidgetBase, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin){
+
+			doh.register("attributes", [
+				// Test attributes mapped to DOMNodes
+				function domMapping(){
+					var IndividualMaps = declare([_WidgetBase, _TemplatedMixin], {
+						// Mapping foo to this.domNode.foo
+						foo:"",
+						_setFooAttr: "",
+		
+						// Mapping bar to this.buttonNode.bar
+						bar: "",
+						_setBarAttr: "buttonNode",
+		
+						// Mapping plainText to this.plainTextNode.innerHTML
+						plainText: "",
+						_setPlainTextAttr: {node: "plainTextNode", type: "innerText"},
+
+						templateString: "<div class='class1' style='border: 1px solid red; width: 456px'>" +
+											"<button data-dojo-attach-point='buttonNode,focusNode'>hi</button>" +
+											'<span><input data-dojo-attach-point="inputNode" value="input"></span>' +
+											"<span data-dojo-attach-point='containerNode'></span>" +
+											"<span data-dojo-attach-point='plainTextNode'>original plain text</span>" +
+										"</div>"
+					});
+
+					var widget = new IndividualMaps({
+						foo:"value1",
+						bar:"value2",
+						"class":"class2",
+						style:"height: 123px",
+						plainText: "hello world <>&;",
+						"name-with-dashes": "name with dashes"
+					}).placeAt(dom.byId("wrapper"));
+
+					// test attributes specified to constructor were copied over to DOM
+					doh.is("value1", widget.domNode.getAttribute("foo"), "widget.domNode.getAttribute('foo')");
+					doh.is("value2", widget.buttonNode.getAttribute("bar"), "widget.domNode.getAttribute('bar')");
+					doh.t(domClass.contains(widget.domNode, "class1"), "class1");
+					doh.t(domClass.contains(widget.domNode, "class2"), "class2");
+					doh.is("123px", widget.domNode.style.height, "height");
+					doh.is("456px", widget.domNode.style.width, "width");
+					doh.is("hello world <>&;", widget.plainTextNode.innerHTML, "innerHTML");
+				},
+
+				// Test attributes mapped to subwidgets
+				function subwidgetMapping(){
+					declare("MySubWidget", [_WidgetBase], {
+						_setFooAttr: function(val){
+							this.foo = val;
+							this.gotValue = true;	// set flag for testing purposes
 						}
-					},
-
-					// Test custom setters/getter methods
-					function customSetters(){
-						var CustomSetters = dojo.declare([dijit._Widget], {
-							foo: 0,
-							_setFooAttr: function(val){ this.foo = val + 5; },
-							_getFooAttr: function(val){ return this.foo - 10; }
-						});
-
-						var widget = new CustomSetters({
-							foo: 100
-						});
-
-						doh.is(105, widget.foo, "custom setter called at initialize time");
-						doh.is(95, widget.get("foo"), "custom getter called");
-
-						widget.set("foo", 50);
-						doh.is(55, widget.foo, "custom setter called dynamically");
-						doh.is(45, widget.get("foo"), "custom getter still called");
-					},
-
-					// Test setters for attribute names with dashes
-					function settersForNamesWithDashes(){
-						var MyWidget = dojo.declare([dijit._Widget, dijit._TemplatedMixin], {
-							"name-with-dashes": "",
-							_setNameWithDashesAttr: {node: "dashNode", type: "innerHTML"},
-	
-							templateString: "<div>" +
-												"<span data-dojo-attach-point='dashNode'></span>" +
-											"</div>"
-						});
-
-						var widget = new MyWidget({
-							"name-with-dashes": "name with dashes"
-						}).placeAt(dojo.byId("wrapper"));
-
-						doh.is("name with dashes", widget.get("name-with-dashes"), "get()");
-						doh.is("name with dashes", widget.dashNode.innerHTML, "innerHTML");
-
-						widget.set("name-with-dashes", "hello");
-						doh.is("hello", widget.dashNode.innerHTML);
-					},
-
-					// Test deprecated attr() method				
-					function attr(){
-						var MyWidget = new dojo.declare([dijit._Widget, dijit._TemplatedMixin], {
-							templateString: "<div><span data-dojo-attach-point=nameNode></span></div>",
-							_setNameAttr:  {node: "nameNode", type: "innerHTML"}
-						});
-
-						var b = new MyWidget();
-
-						// simple setting
-						b.attr("name", "thinger");
-						doh.is("thinger", b.attr("name"), "b.attr('name')");
-						doh.is("thinger", b.nameNode.innerHTML, "innerHTML");
-
-						// hash setting
-						b.attr({
-							name: "bang",
-							foo: "zap"
-						});
-						doh.is("bang", b.attr("name"), "hash set of bang");
-						doh.is("zap", b.attr("foo"), "hash set of zap");
-					},
-					
-					// Test deprecated attributeMap
-					function attributeMap(){
-						var AttrMap = dojo.declare([dijit._Widget, dijit._TemplatedMixin], {
-							attributeMap: {foo: "", bar: "buttonNode", plainText: {node: "plainTextNode", type: "innerText"}},
-							templateString: "<div class='class1' style='border: 1px solid red; width: 456px'>" +
-												"<button data-dojo-attach-point='buttonNode,focusNode'>hi</button>" +
-												'<span><input data-dojo-attach-point="inputNode" value="input"></span>' +
-												"<span data-dojo-attach-point='containerNode'></span>" +
-												"<span data-dojo-attach-point='plainTextNode'>original plain text</span>" +
-											"</div>"
-						});
-
-						var widget = new AttrMap({
-							foo:"value1",
-							bar:"value2",
-							"class":"class2",
-							style:"height: 123px",
-							plainText: "hello world <>&;"
-						}).placeAt(dojo.byId("wrapper"));
-
-						// test that attributes specified to constructor were copied over to the DOM
-						doh.is("value1", widget.domNode.getAttribute("foo"), "widget.domNode.getAttribute('foo')");
-						doh.is("value2", widget.buttonNode.getAttribute("bar"), "widget.domNode.getAttribute('bar')");
-						doh.t(dojo.hasClass(widget.domNode, "class1"), "class1");
-						doh.t(dojo.hasClass(widget.domNode, "class2"), "class2");
-						doh.is("123px", dojo.style(widget.domNode).height, "height");
-						doh.is("456px", dojo.style(widget.domNode).width, "width");
-						doh.is("hello world <>&;", widget.plainTextNode.innerHTML, "innerHTML");
+					});
+					var IndividualMaps = declare(
+							[_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+
+						// Mapping foo to this.subwidget.foo
+						foo:"",
+						_setFooAttr: "subwidget",
+
+						templateString:
+							"<div class='class1' style='border: 1px solid red; width: 456px'>" +
+								"<button data-dojo-type='MySubWidget' data-dojo-attach-point='subwidget'>hi</button>" +
+							"</div>"
+					});
+
+					var widget = new IndividualMaps({
+						foo: "value1"
+					}).placeAt(dom.byId("wrapper"));
+
+					// test attribute specified to constructor was copied over to subwidget
+					doh.is("value1", widget.subwidget.get("foo"), "widget.subwidget.get('foo')");
+					doh.t(widget.subwidget.gotValue, "gotValue");
+				},
+
+				// Test that certain attributes are automatically applied to focusNode or domNode.
+				// These are attributes that aren't mentioned at all in _WidgetBase.
+				function autoDomMapping(){
+					// Mapping to this.domNode
+					var w = new _WidgetBase({
+						title: "dom title",
+						"aria-labelledby": "foo",
+						role: "button"
+					});
+					doh.is("dom title", domAttr.get(w.domNode, "title"), "domNode title");
+					doh.is("foo", w.domNode.getAttribute("aria-labelledby", "domNode labelledby"));
+					doh.is("button", domAttr.get(w.domNode, "role"), "domNode role");
+
+					// Mapping to this.focusNode
+					var fw = new (declare([_WidgetBase, _TemplatedMixin], {
+						templateString: "<div><input data-dojo-attach-point='focusNode'/></div>"
+					}))({
+						title: "my title",
+						"aria-labelledby": "foo"
+					});
+					doh.is("my title", domAttr.get(fw.focusNode, "title"), "focusNode title");
+					doh.is("foo", fw.focusNode.getAttribute("aria-labelledby"), "focusNode labelledby");
+
+					// Mapping attributes with dashes and mixed case
+					var mc = new (declare([_WidgetBase, _TemplatedMixin], {
+						templateString: "<form></form>"
+					}))({
+						"accept-charset": "utf8",
+						"novalidate": "true"	// parser delivers as lowercase even though it's noValidate in JS obj
+					});
+					doh.is("utf8", mc.domNode.getAttribute("accept-charset"), "accept-charset");
+					if(has("ff") >= 4 || has("ie") >= 10 || has("webkit")){
+						// only works for HTML5 compliant browsers where novalidate is understood
+						// (also, hasAttribute() is not available on IE6/7)
+						doh.t(mc.domNode.hasAttribute("novalidate"), "noValidate");
 					}
+				},
+
+				// Test custom setters/getter methods
+				function customSetters(){
+					var CustomSetters = declare([_WidgetBase], {
+						foo: 0,
+						_setFooAttr: function(val){ this._set("foo", val + 5); },
+						_getFooAttr: function(val){ return this._get("foo") - 10; }
+					});
+
+					var widget = new CustomSetters({
+						foo: 100
+					});
+
+					doh.is(105, widget._get("foo"), "custom setter called at initialize time");
+					doh.is(95, widget.get("foo"), "custom getter called");
+
+					widget.set("foo", 50);
+					doh.is(55, widget._get("foo"), "custom setter called dynamically");
+					doh.is(45, widget.get("foo"), "custom getter still called");
+				},
+
+				// Test setters for attribute names with dashes
+				function settersForNamesWithDashes(){
+					var MyWidget = declare([_WidgetBase, _TemplatedMixin], {
+						"name-with-dashes": "",
+						_setNameWithDashesAttr: {node: "dashNode", type: "innerHTML"},
+
+						templateString: "<div>" +
+											"<span data-dojo-attach-point='dashNode'></span>" +
+										"</div>"
+					});
 
-				]
-			);
+					var widget = new MyWidget({
+						"name-with-dashes": "name with dashes"
+					}).placeAt(dom.byId("wrapper"));
+
+					doh.is("name with dashes", widget.get("name-with-dashes"), "get()");
+					doh.is("name with dashes", widget.dashNode.innerHTML, "innerHTML");
+
+					widget.set("name-with-dashes", "hello");
+					doh.is("hello", widget.dashNode.innerHTML);
+				},
+
+				// Test deprecated attr() method (remove for 2.0)
+				function attr(){
+					var MyWidget = new declare([_Widget, _TemplatedMixin], {
+						templateString: "<div><span data-dojo-attach-point=nameNode></span></div>",
+						_setNameAttr:  {node: "nameNode", type: "innerHTML"}
+					});
+
+					var b = new MyWidget();
+
+					// simple setting
+					b.attr("name", "thinger");
+					doh.is("thinger", b.attr("name"), "b.attr('name')");
+					doh.is("thinger", b.nameNode.innerHTML, "innerHTML");
+
+					// hash setting
+					b.attr({
+						name: "bang",
+						foo: "zap"
+					});
+					doh.is("bang", b.attr("name"), "hash set of bang");
+					doh.is("zap", b.attr("foo"), "hash set of zap");
+				},
+				
+				// Test deprecated attributeMap (remove for 2.0)
+				function attributeMap(){
+					var AttrMap = declare([_WidgetBase, _TemplatedMixin], {
+						attributeMap: {foo: "", bar: "buttonNode", plainText: {node: "plainTextNode", type: "innerText"}},
+						templateString: "<div class='class1' style='border: 1px solid red; width: 456px'>" +
+											"<button data-dojo-attach-point='buttonNode,focusNode'>hi</button>" +
+											'<span><input data-dojo-attach-point="inputNode" value="input"></span>' +
+											"<span data-dojo-attach-point='containerNode'></span>" +
+											"<span data-dojo-attach-point='plainTextNode'>original plain text</span>" +
+										"</div>"
+					});
+
+					var widget = new AttrMap({
+						foo:"value1",
+						bar:"value2",
+						"class":"class2",
+						style:"height: 123px",
+						plainText: "hello world <>&;"
+					}).placeAt(dom.byId("wrapper"));
+
+					// test that attributes specified to constructor were copied over to the DOM
+					doh.is("value1", widget.domNode.getAttribute("foo"), "widget.domNode.getAttribute('foo')");
+					doh.is("value2", widget.buttonNode.getAttribute("bar"), "widget.domNode.getAttribute('bar')");
+					doh.t(domClass.contains(widget.domNode, "class1"), "class1");
+					doh.t(domClass.contains(widget.domNode, "class2"), "class2");
+					doh.is("123px", widget.domNode.style.height, "height");
+					doh.is("456px", widget.domNode.style.width, "width");
+					doh.is("hello world <>&;", widget.plainTextNode.innerHTML, "innerHTML");
+				},
+
+				// Test that attributes set in the ctor when side effects setter exist
+				// are correctly applied
+				function ctorDependentAttributes(){
+					var TestWidget = declare(_WidgetBase, {
+						single: null,
+						multiple: [],
+						_setSingleAttr: function(value){
+							this._set("multiple", value != null ? [value] : null);
+							this._set("single", value);
+						},
+						_setMultipleAttr: function(value){
+							this._set("single", value ? (value.length > 0 ? value[0] : null) : null);
+							this._set("multiple", value);
+						}
+					});
+
+					var w1 = new TestWidget({
+							single : 5
+					});
+					var w2 = new TestWidget({
+							multiple: [5]
+					});
+					doh.is(5, w1.get("single"), "w1.single");
+					doh.is([5], w1.get("multiple"), "w1.multiple");
+					doh.is(5, w2.get("single"), "w2.single");
+					doh.is([5], w2.get("multiple"), "w2.multiple");
+				},
+
+				function moreCorrelatedProperties(){
+					var Widget = declare([_WidgetBase], {
+						foo: 10,
+						_setFooAttr: function(val){
+							this._set("foo", val);
+							this._set("bar", val + 1);
+						},
+
+						bar: 11,
+						_setBarAttr: function(val){
+							this._set("bar", val);
+							this._set("foo", val - 1);
+						}
+					});
+
+					var w1 = new Widget({foo: 30});
+					doh.is(30, w1.get("foo"), "w1.foo");
+					doh.is(31, w1.get("bar"), "w1.bar");
+
+					var w2 = new Widget({bar: 30});
+					doh.is(30, w2.get("bar"), "w2.bar");
+					doh.is(29, w2.get("foo"), "w2.foo");
+
+					var w3 = new Widget({});
+					doh.is(10, w3.get("foo"), "w3.foo");
+					doh.is(11, w3.get("bar"), "w3.bar");
+				}
+			]);	// doh.register()
 
 			doh.run();
-		});
+
+		});	// require()
 
 	</script>
 </head>
diff --git a/dijit/tests/_Widget-connect-performance.html b/dijit/tests/_Widget-connect-performance.html
index 6670ccc..4d6425a 100644
--- a/dijit/tests/_Widget-connect-performance.html
+++ b/dijit/tests/_Widget-connect-performance.html
@@ -13,7 +13,7 @@
 		dojo.require("dojo.parser");
 
 		dojo.ready(function(){
-			dojo.declare("dijit.MyWidget", dijit._Widget, {
+			dojo.declare("MyWidget", dijit._Widget, {
 				_eventHandler: function(){}
 			});
 
@@ -70,6 +70,6 @@
 </head>
 <body class="claro">
 	<div id="externalNode"></div>
-	<div id="widget1" data-dojo-type="dijit.MyWidget"></div>
+	<div id="widget1" data-dojo-type="MyWidget"></div>
 </body>
 </html>
diff --git a/dijit/tests/_Widget-deferredConnect.html b/dijit/tests/_Widget-deferredConnect.html
index 82864f6..fcc726c 100644
--- a/dijit/tests/_Widget-deferredConnect.html
+++ b/dijit/tests/_Widget-deferredConnect.html
@@ -60,7 +60,7 @@
 	<!--
 		"overrode" button specifies an onmousemove handler on initialization.
 	-->
-	<button id="overrode" data-dojo-type="dijit.form.Button"
+	<button id="overrode" data-dojo-type="dijit/form/Button"
 		data-dojo-props='onMouseMove:function(){ if(!overrodeMouseMoved){ console.log("\"overrode\" button: mouse moved"); } overrodeMouseMoved = true; }'>
 		overrode
 	</button>
@@ -70,11 +70,11 @@
 		This should trigger an additional dojo.connect() call from Button.focusNode.onmousemove
 		to the Button.onMouseMove empty function.
 	-->
-	<button id="connect" data-dojo-type="dijit.form.Button">
+	<button id="connect" data-dojo-type="dijit/form/Button">
 		connected
 	</button>
 
-	<button id="both" data-dojo-type="dijit.form.Button" data-dojo-props='onMouseMove:bothHandler'>
+	<button id="both" data-dojo-type="dijit/form/Button" data-dojo-props='onMouseMove:bothHandler'>
 		both
 	</button>
 </body>
diff --git a/dijit/tests/_Widget-lifecycle.html b/dijit/tests/_Widget-lifecycle.html
index f9b3c91..09ca399 100644
--- a/dijit/tests/_Widget-lifecycle.html
+++ b/dijit/tests/_Widget-lifecycle.html
@@ -3,24 +3,31 @@
 <html>
 <head>
 
-	<title>_Widget.destroy() unit test</title>
+	<title>_WidgetBase lifecycle unit test</title>
 
-	<script type="text/javascript" src="../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit._Widget");
+		require([
+			"doh/runner",
+			"dojo/_base/declare", "dojo/dom",
+			"dijit/registry", "dijit/_WidgetBase",
+			"dojo/domReady!"
+		], function(doh, declare, dom, registry, _WidgetBase){
 
-		dojo.ready(function(){
 			var obj = {
 				foo: function(){
 					// summary: empty function that we connect to
 				}
 			};
-	
+
 			// Number of times foo was called while TestWidget existed
 			var calls = 0;
-	
-			dojo.declare("dijit.TestWidget", dijit._Widget, {
+
+			declare("TestWidget", _WidgetBase, {
+				postMixInProperties: function(){
+					// make sure we can call set for parameters that don't touch the DOM
+					this.set("foo", "bar");
+				},
 				postCreate: function(){
 					// Rather odd call to this.connect() For testing the connections are dropped on destroy()
 					this.connect(obj, "foo", function(){
@@ -28,80 +35,91 @@
 					});
 				}
 			});
-	
+
 			var w;
 
-			doh.register("dijit._Widget-lifecycle",
-				[
-					{
-						name: "create",
-						runTest: function(t){
-							w = new dijit.TestWidget({id: "w1"}, "w1");
+			doh.register("create and destroy", [
+				{
+					name: "create",
+					runTest: function(t){
+						w = new TestWidget({id: "w1"}, "w1");
 
-							doh.t(dijit.byId("w1"), "widget in registry");
+						doh.t(registry.byId("w1"), "widget in registry");
 
-							// since there's no template, the widget just points to the srcNodeRef
-							doh.is(w.domNode, dojo.byId("w1"), "srcNodeRef read in");
+						// since there's no template, the widget just points to the srcNodeRef
+						doh.is(w.domNode, dom.byId("w1"), "srcNodeRef read in");
 
-							// test the connection
-							doh.is(0, calls, "foo() not called yet");
-							obj.foo();
-							doh.is(1, calls, "foo() called");
-						}
-					},
-					{
-						name: "destroy",
-						runTest: function(t){
-							w.destroy();
+						// test the connection
+						doh.is(0, calls, "foo() not called yet");
+						obj.foo();
+						doh.is(1, calls, "foo() called");
+					}
+				},
+				{
+					name: "destroy",
+					runTest: function(t){
+						w.destroy();
 
-							doh.f(dijit.byId("w1"), "widget no longer in registry");
+						doh.f(registry.byId("w1"), "widget no longer in registry");
 
-							// test the connection was destroyed
-							calls = 0;
-							obj.foo();
-							doh.is(0, calls, "connection was deleted");
+						// test the connection was destroyed
+						calls = 0;
+						obj.foo();
+						doh.is(0, calls, "connection was deleted");
 
-							// test the DOM node was removed
-							doh.f(dojo.byId("w1"), "DOM Node removed");
-						}
-					},
-					{
-						name: "destroy(true)  (preserving DOM node)",
-						runTest: function(t){
-							w = new dijit.TestWidget({id: "w2"}, "w2");
+						// test the DOM node was removed
+						doh.f(dom.byId("w1"), "DOM Node removed");
+					}
+				},
+				{
+					name: "destroy(true)  (preserving DOM node)",
+					runTest: function(t){
+						w = new TestWidget({id: "w2"}, "w2");
 
-							doh.t(dijit.byId("w2"), "widget in registry");
-							w.destroy(true);
+						doh.t(registry.byId("w2"), "widget in registry");
+						w.destroy(true);
 
-							doh.f(dijit.byId("w2"), "widget no longer in registry");
+						doh.f(registry.byId("w2"), "widget no longer in registry");
 
-							// test the DOM node *wasn't* removed
-							doh.t(dojo.byId("w2"), "DOM Node left");
-						}
+						// test the DOM node *wasn't* removed
+						doh.t(dom.byId("w2"), "DOM Node left");
 					}
-
-				]
-			);
+				},
+				{
+					name: "create with undefined id",
+					runTest: function(t){
+						// If id is "specified" as undefined, generate a new one
+						w = new TestWidget({id: undefined});
+
+						doh.isNot(undefined, w.id)
+					}
+				}
+			]);
 
 			doh.register("setter calls on creation", function(){
 				// Make sure setters are called even for anonymous classes (#12122),
 				// and even when there's no value explicitly specified in the parameters
 				var fooSetterCalled,
-					Widget1 = dojo.declare([dijit._Widget], {}),
-				    Widget2 = dojo.declare([dijit._Widget], {
+					MyWidget = declare(_WidgetBase, {
 						foo: 345,
-				        _setFooAttr: function(val){
+						_setFooAttr: function(val){
 							fooSetterCalled = val;
-				            this.foo = val;
-				        }
-				    });
-				
-				new Widget1();
-				new Widget2();
-				
+							this._set("foo", val);
+						}
+					});
+
+				new MyWidget();
+
 				doh.is(345, fooSetterCalled, "fooSetterCalled");
 			});
-	
+
+			doh.register("tweaking params in postMixInProperties", function(){
+				// Tests that property changes in postMixInProperties() are not lost (#16080)
+				var Test = declare(_WidgetBase, { foo: "bar", postMixInProperties: function(){ this.foo = "baz"; } });
+				var t = new Test({ foo: "blah" });
+				doh.is("baz", t.foo);
+			});
+
 			doh.run();
 		});
 
diff --git a/dijit/tests/_Widget-on.html b/dijit/tests/_Widget-on.html
index 1cc342d..971c1ab 100644
--- a/dijit/tests/_Widget-on.html
+++ b/dijit/tests/_Widget-on.html
@@ -2,7 +2,7 @@
 <html>
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>_Widget on() test</title>
+	<title>_WidgetBase on() test</title>
 	<style type="text/css">
 		@import "../themes/claro/document.css";
 		@import "../themes/claro/claro.css";
@@ -12,22 +12,19 @@
 	<script type="text/javascript" src="../../dojo/dojo.js"
 		data-dojo-config="isDebug: true"></script>
 	<script>
-		dojo.require("doh.runner");
-		dojo.require("dojo.parser");
-		dojo.require("dojo.on");
-		dojo.require("dojo._base.declare");
-		dojo.require("dijit._Widget");
-		dojo.require("dijit.registry");
+		require([
+			"doh/runner",
+			"dojo/_base/declare", "dojo/has", "dojo/_base/lang", "dojo/on", "dojo/parser", "dojo/touch",
+			"dijit/registry", "dijit/_WidgetBase", "dojo/domReady!"
+		], function(doh, declare, has, lang, on, parser, touch, registry, _WidgetBase){
 
-
-		dojo.ready(function(){
 			var mousedOver, clicked;
 
 			doh.register("on", [
 				function setup(){
-					dojo.declare("MyWidget", [dijit._Widget], {
+					declare("MyWidget", _WidgetBase, {
 						postCreate: function(){
-							dojo.on(this.domNode, "click", dojo.hitch(this, "onFooBar"));
+							on(this.domNode, "click", lang.hitch(this, "onFooBar"));
 						},
 						onFooBar: function(){
 							// This is called whenever the widget is clicked
@@ -37,45 +34,78 @@
 						}
 					});
 
-					dojo.parser.parse();
+					parser.parse();
 				},
 
 				function connect(){
 					// This should work despite the fact that the function onMouseOver has
 					// multiple capital letters
-					dijit.registry.byId("myWidget").on("mouseover", function(){
+					registry.byId("myWidget").on("mouseover", function(){
 						mousedOver = true;
 						console.log("mouseover event");
 					});
 
 					// Likewise, this should work despite the fact that the function onFooBar has
 					// multiple capital letters
-					dijit.registry.byId("myWidget").on("foobar", function(){
+					registry.byId("myWidget").on("foobar", function(){
 						clicked = true;
 						console.log("click event");
 					});
 				},
 
 				function test(){
-					var myWidget = dijit.registry.byId("myWidget");
+					var myWidget = registry.byId("myWidget");
 
-					// Test that _Widget.on() catches click event
+					// Test that _WidgetBase.on() catches click event
 					doh.f(clicked, "clicked");
-					dojo.on.emit(myWidget.domNode, "click", {
+					on.emit(myWidget.domNode, "click", {
 						bubbles: true,
 						cancelable: true,
 						which: 1
 					});
 					doh.t(clicked, "clicked");
 
-					// Test that _Widget.on() catches mouseover event
+					// Test that _WidgetBase.on() catches mouseover event
 					doh.f(mousedOver, "mousedOver");
-					dojo.on.emit(myWidget.domNode, "mouseover", {
+					on.emit(myWidget.domNode, "mouseover", {
 						bubbles: true,
 						cancelable: true,
 						which: 1
 					});
 					doh.t(mousedOver, "mousedOver");
+				},
+
+				function synthetic(){
+					// Test that on() works for synthetic events
+
+					var myWidget = registry.byId("myWidget"),
+						touched;
+
+					myWidget.on(dojo.touch.press, function(){
+						touched = true;
+					});
+
+					on.emit(myWidget.domNode, navigator.msPointerEnabled ? "MSPointerDown" : has("touch") ? "touchstart" : "mousedown", {
+						bubbles: true,
+						cancelable: true,
+						which: 1
+					});
+
+					doh.t(touched, "touched");
+				},
+
+				function syntheticNoCallbackArgs(){
+					var evt = null;
+					var MyWidget = declare(_WidgetBase, {
+						show: function(){
+							return this.emit('show');
+						},
+						onshow: function(e){
+							evt = e;
+						}
+					});
+					new MyWidget({}).show();
+					doh.isNot(null, evt, "onshow was called with event object");
 				}
 			]);
 
diff --git a/dijit/tests/_Widget-ondijitclick.html b/dijit/tests/_Widget-ondijitclick.html
index fb611cd..b777ef8 100644
--- a/dijit/tests/_Widget-ondijitclick.html
+++ b/dijit/tests/_Widget-ondijitclick.html
@@ -6,37 +6,36 @@
 
 	<title>Test Dijit Internal Event: "ondijitclick"</title>
 
+	<style>
+		div {
+			border: 1px solid blue;
+			margin: 1em;
+		}
+	</style>
+
 	<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
-		dojo.require("dijit._Widget");
+		dojo.require("dijit._WidgetBase");
+		dojo.require("dijit._OnDijitClickMixin");
 		dojo.require("dojo.parser");
 
 		dojo.ready(function(){
-			dojo.declare("dijit.WidgetWithOndijitclick",
-				dijit._Widget,
-				{
-					clickCount: 0,
-					onClick: function(){
-					},
-					_onClick: function(){
-						this.clickCount++;
-						this.onClick();
-					},
-					postCreate: function(){
-						this.connect(this.domNode, "ondijitclick", "_onClick");
-					}
+			dojo.declare("WidgetWithOndijitclick", [dijit._WidgetBase, dijit._OnDijitClickMixin], {
+				clickCount: 0,
+				onClick: function(){
+				},
+				_onClick: function(evt){
+					this.clickCount++;
+					this.onClick(evt);
+				},
+				postCreate: function(){
+					this.connect(this.domNode, "ondijitclick", "_onClick");
 				}
-			);
+			});
 
 			dojo.parser.parse();
 		});
 	</script>
-	<style>
-		div {
-			border: 1px solid blue;
-			margin-top: 1em;
-		}
-	</style>
 </head>
 <body class="claro">
 	<h1>_Widget.ondijitclick test</h1>
@@ -51,13 +50,13 @@
 		whether catch clicks on key-down or key-up so this tests to make sure we are doing
 		the right one.)
 	</p>
-	<div id="first" tabIndex="0" data-dojo-type="dijit.WidgetWithOndijitclick" data-dojo-props='
+	<div id="first" tabIndex="0" data-dojo-type="WidgetWithOndijitclick" data-dojo-props='
 			onClick:function(){ dojo.byId("plainbutton").focus(); }'>
 		click me using space or enter, to focus button below
 	</div>
 	<button id="plainbutton" onclick="console.log('plain button clicked'); window.clicked = true;" type="button" >plain button</button>
 
-	<div id="second" tabIndex="0" data-dojo-type="dijit.WidgetWithOndijitclick" data-dojo-props='
+	<div id="second" tabIndex="0" data-dojo-type="WidgetWithOndijitclick" data-dojo-props='
 			onClick:function(){ dojo.byId("textarea").focus(); }'>
 		click me using space or enter, to focus textarea below
 	</div>
@@ -68,20 +67,28 @@
 			onClick="dojo.byId('third').focus();">
 		click me using space or enter, to focus ondijitclick widget below
 	</button>
-	<div id="third" tabIndex="0" data-dojo-type="dijit.WidgetWithOndijitclick" data-dojo-props='style:"margin-top: 0px;",
+	<div id="third" tabIndex="0" data-dojo-type="WidgetWithOndijitclick" data-dojo-props='style:"margin-top: 0px;",
 			onFocus:function(){ console.log("onfocus on third"); window.onDijitClickFocus = true; },
 			onClick:function(){ console.log("onclick on third"); window.spuriousOnDijitClick = true; }'>
 		clicking the button above shouldn't cause my ondijitclick handler to fire
 	</div>
 	<br>
-	<div id="fourth" tabIndex="0" data-dojo-type="dijit.WidgetWithOndijitclick" data-dojo-props='style:"margin-top: 0px;",
+	<div id="fourth" tabIndex="0" data-dojo-type="WidgetWithOndijitclick" data-dojo-props='style:"margin-top: 0px;",
 			onClick:function(){ alert("make sure can close this alert via keyboard"); }'>
 		Manual Test: Click me using space or enter to launch a JavaScript alert() from element using ondijitclick
 	</div>
 	<br>
 	Clicking this button should produce exactly one click event to console:
-	<button id="widgetbutton" tabIndex="0" data-dojo-type="dijit.WidgetWithOndijitclick">
+	<button id="widgetbutton" tabIndex="0" data-dojo-type="WidgetWithOndijitclick">
 		button w/ondijitclick
 	</button>
+
+	<div id="outer">
+		Test for bubble of click
+		<div id="inner">
+			<span data-dojo-type="WidgetWithOndijitclick" id="bubbleTestWidget" tabindex="0">click me</span>
+			<span data-dojo-type="WidgetWithOndijitclick" id="bubbleTestWidget2" tabindex="0">click me too</span>
+		</div>
+	</div>
 </body>
 </html>
diff --git a/dijit/tests/_Widget-placeAt.html b/dijit/tests/_Widget-placeAt.html
index e179155..73338b9 100644
--- a/dijit/tests/_Widget-placeAt.html
+++ b/dijit/tests/_Widget-placeAt.html
@@ -6,124 +6,196 @@
 
 	<title>_Widget.placeAt tests</title>
 
-	<!-- test decoration styles -->
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "../../dijit/tests/css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: load the dojo base -->
-	<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="isDebug:true" ></script>
-	<!-- for theme-switching, only for dijit -->
-	<script type="text/javascript" src="../../dijit/tests/_testCommon.js"></script>
+	<script src="boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-
-		// load components need for this test
-		dojo.require("dojo.parser");
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.BorderContainer");
-
-		// run all the tests onload
-		dojo.ready(function(){
+		require([
+			"doh/runner", "dojo/_base/declare", "dojo/dom",
+			"dijit/_WidgetBase", "dijit/form/Button",
+			"dijit/layout/ContentPane", "dijit/layout/TabContainer", "dijit/layout/BorderContainer",
+			"dojo/domReady!"
+		], function(doh, declare, dom, _WidgetBase, Button, ContentPane, TabContainer, BorderContainer){
+
+			var SimpleWidget = declare(_WidgetBase, {
+				buildRendering: function(){
+					this.domNode = document.createElement("div");
+					this.containerNode = document.createElement("div");
+					this.domNode.appendChild(this.containerNode);
+				}
+			});
 
-			var pane1, pane2, tc;
+			var simple, pane1, pane2, pane3, pane4, pane5;
+			doh.register("parent without addChild", [
+				function placeAsDOMNodeChild(){
+					// create a SimpleWidget
+					simple = (new SimpleWidget({id: "simple"})).placeAt("container");
+					doh.is(dom.byId("container"), simple.domNode.parentNode, "simple is child of container");
+				},
+
+				function placeAsWidgetChild(){
+					// add the child to the SimpleWidget now
+					pane1 = (new ContentPane({ title: "pane1" })).placeAt(simple);
+					doh.is(pane1, simple.getChildren()[0], "pane1 is child of SimpleWidget");
+					doh.is(simple.containerNode, pane1.domNode.parentNode, "pane1 added to simple.containerNode not simple.domNode")
+				},
+
+				function placeAsWidgetChildOrdered(){
+					// add this child (created second) as the new first child
+					pane2 = (new ContentPane({ title: "pane2" })).placeAt("simple", 0);
+					doh.is(simple.containerNode, pane2.domNode.parentNode, "pane2 added to simple.containerNode not simple.domNode")
+					doh.is(pane2, simple.getChildren()[0], "pane2 is new first child of SimpleWidget");
+					doh.is(pane1, simple.getChildren()[1], "pane1 is now second child of SimpleWidget");
+				},
+
+				function placeBeforeDomNode(){
+					var button = (new Button({})).placeAt(dom.byId("container"), "before");
+					doh.is(dom.byId("container"), button.domNode.nextSibling, "button is before tab container");
+				},
+
+				function placeBeforeDomNodeId(){
+					var button = (new Button({})).placeAt("container", "before");
+					doh.is(dom.byId("container"), button.domNode.nextSibling, "button is before tab container");
+				},
+
+				function placeFirstWidget(){
+					simple.startup();
+					pane4 = (new ContentPane({ title: "pane4" })).placeAt("simple", "first");
+					doh.is(simple.containerNode, pane4.domNode.parentNode, "pane4 added to simple.containerNode not simple.domNode")
+					doh.is(pane4, simple.getChildren()[0], "pane4 is new first child of SimpleWidget");
+					doh.t(pane4._started, "pane4 was automatically started because simple was already started")
+				},
+				function placeLastWidget(){
+					pane5 = (new ContentPane({ title: "pane5" })).placeAt(simple.containerNode, "last");
+					doh.is(pane5, simple.getChildren()[simple.getChildren().length-1], "pane5 is new last child of SimpleWidget");
+					doh.t(pane5._started, "pane5 was automatically started because simple was already started")
+				}
+			]);
+
+			var tc;
+			doh.register("TabContainer parent", [
+				function placeAsDOMNodeChild(){
+					// create a TabContainer
+					tc = (new TabContainer({
+						id: "tc",
+						style: "height:200px; width:200px"
+					}, "tabContainerThinger")).placeAt("container");
+
+					doh.is(dom.byId("container"), tc.domNode.parentNode, "TabContainer is child of container");
+				},
+
+				function placeAsWidgetChild(){
+					// add the child to the TabContainer now:
+					pane1 = (new ContentPane({ title: "pane1" })).placeAt(tc);
+
+					doh.is(pane1, tc.getChildren()[0], "pane1 is child of TabContainer");
+				},
+
+				function placeAsWidgetChildOrdered(){
+					// add this child (created second) as the first tab:
+					pane2 = (new ContentPane({ title: "pane2" })).placeAt(tc, 0);
+
+					doh.is(pane2, tc.getChildren()[0], "pane2 is new first child of TabContainer");
+					doh.is(pane1, tc.getChildren()[1], "pane1 is now second child of TabContainer");
+				},
+
+				function placeAsWidgetIdChild(){
+					// add the child to the TabContainer now:
+					pane3 = (new ContentPane({ title: "pane1" })).placeAt("tc");
+
+					doh.is(pane3, tc.getChildren()[2], "pane3 is child of TabContainer");
+				},
+
+				function startup(){
+					// just starting the TabContainer so we can do some more tests
+					tc.startup();
+					tc.selectChild(pane2);
+				},
+
+				function placeAsFirst(){
+					pane2.set("content","button should appear BEFORE this text");
+
+					// create a button, and add it to pane2 before the above text
+					var button = (new Button({
+						label:"alert",
+						onClick: function(){
+							alert('woot');
+						}
+					})).placeAt(pane2.containerNode, "first");
+
+					doh.is(button.domNode, pane2.containerNode.firstChild, "button is first child");
+					doh.is(3, button.domNode.nextSibling.nodeType, "button went before other content");
+				},
+
+				function placeBefore(){
+					// And a button, this time we'll place it before the TabContainer's dom.
+					// placeAt(refWidget, "before"/"after"/"replace") isn't supported in general,
+					// especially not when the grandparent has addChild()/removeChild() methods, but testing
+					// here for regressions in what does work
+					var otherButton = new Button({
+						label:"destroy TabContainer",
+						onClick:function(){
+							tc.destroyRecursive();
+						}
+					});
+					otherButton.placeAt("tc", "before");
+
+					// make sure it went before tc.domNode, not before tc.containerNode
+					doh.is(tc.domNode, otherButton.domNode.nextSibling, "otherButton is before tab container");
+
+					// since it doesn't have a widget parent it should have been started
+					doh.f(otherButton._started, "button wasn't started");
+				}
+			]);
+
+			doh.register("startup tests", [
+				function startup(){
+					var bc = new BorderContainer({
+						id: "bc",
+						style: "width:600px; height:400px"
+					});
+					bc.placeAt(dojo.body());
+					doh.is(dojo.body(), bc.domNode.parentNode, "BorderContainer parentNode == dojo.body()");
+
+					// add a center pane before BC startup
+					var centerStarted;
+					var center = new ContentPane({
+						region: "center",
+						content: "<p>center</p>"
+					});
+					dojo.connect(center, "startup", function(){ centerStarted = true; });
+					center.placeAt(bc);
+					doh.f(centerStarted, "center not started");	// shouldn't be started since BC itself isn't started
+					doh.is(bc, center.getParent(), "center ContentPane parent == BorderContainer");
+
+					// start BorderContainer
+					bc.startup();
+					doh.t(centerStarted, "center started");	// should be started along with BC
+
+					// add a left pane after startup
+					var leftStarted;
+					var left = new ContentPane({
+						region: "left",
+						content: "<p>wowzers</p>",
+						style: "width:100px"
+					});
+					dojo.connect(left, "startup", function(){ leftStarted = true; });
+					left.placeAt("bc");
+					doh.is(bc, left.getParent(), "left ContentPane parent == BorderContainer");
+					doh.t(leftStarted, "left ContentPane automatically started since BorderContainer was already started");
 
-			doh.register("parse", function(){
-				dojo.parser.parse();
-			});
+					// add a top pane, and add content
+					var topStarted;
+					var top = new ContentPane({
+						region: "top",
+						style: "height:100px"
+					});
+					dojo.connect(top, "startup", function(){ topStarted = true; });
+					top.placeAt(bc).set("content","<div>some HTML text</div>");
+					doh.is(bc, top.getParent(), "top ContentPane parent == BorderContainer");
+					doh.t(topStarted, "top ContentPane automatically started since BorderContainer was already started");
+				}
+			]);
 
-			doh.register("dijit.tests.placeAt",
-				[
-					function placeAsDOMNodeChild(){
-						// create a TabContainer
-						tc = new dijit.layout.TabContainer({
-							style: "height:200px; width:200px"
-						}, "tabContainerThinger").placeAt("container");
-
-						doh.is(dojo.byId("container"), tc.domNode.parentNode, "TabContainer is child of container");
-					},
-
-					function placeAsWidgetChild(){
-						// add the child to the TabContainer now:
-						pane1 = new dijit.layout.ContentPane({ title:"empty" }).placeAt(tc);
-
-						doh.is(pane1, tc.getChildren()[0], "pane1 is child of TabContainer");
-					},
-
-					function placeAsWidgetChildOrdered(){
-						// add this child (created second) as the first tab:
-						pane2 = new dijit.layout.ContentPane({ title:"first" }).placeAt(tc, 0);
-
-						doh.is(pane2, tc.getChildren()[0], "pane2 is new first child of TabContainer");
-						doh.is(pane1, tc.getChildren()[1], "pane1 is now second child of TabContainer");
-					},
-
-					function startup(){
-						// just starting the TabContainer so we can do some more tests
-						tc.startup();
-						tc.selectChild(pane2);
-					},
-
-					function placeAsFirst(){
-						pane2.set("content","button should appear BEFORE this text");
-
-						// create a button, and add it to pane2 before the above text
-						var button = new dijit.form.Button({
-							label:"alert",
-							onClick: function(){
-								alert('woot');
-							}
-						}).placeAt(pane2.containerNode, "first");
-
-						doh.is(button.domNode, pane2.containerNode.firstChild, "button is first child");
-						doh.is(3, button.domNode.nextSibling.nodeType, "button went before other content");
-					},
-
-					function placeBefore(){
-						// and a button, this time we'll place it before the TabContainer's dom
-						var otherButton = new dijit.form.Button({
-							label:"destroy TabContainer",
-							onClick:function(){
-								tc.destroyRecursive();
-							}
-						}).placeAt(tc.domNode, "before");
-
-						doh.is(tc.domNode, otherButton.domNode.nextSibling, "otherButton is before tab container");
-					}
-				]
-			);
-			doh.register("dijit.tests.placeAt BorderContainer",
-				[
-					function addPanes(){
-						// Add top and left pane
-						dijit.byId("addStuff").onClick();
-
-						var bc = dijit.byId("bc1"),
-							children = bc.getChildren();
-							
-						doh.is(3, children.length);
-						
-						var bcPos = dojo.position(bc.domNode),
-							center = dijit.byId("center"),
-							centerPos = dojo.position(center.domNode),
-							left = dojo.filter(children, function(child){ return child.region == "left";})[0],
-							leftPos = dojo.position(left.domNode),
-							top =  dojo.filter(children, function(child){ return child.region == "top";})[0];
-
-						doh.t(leftPos.x >= bcPos.x, "left in BorderContainer");
-						doh.t(centerPos.x >= leftPos.x + leftPos.w, "left vs. center horizontal");
-						doh.is("<p>wowzers</p>", left.domNode.innerHTML.toLowerCase(), "left pane");
-						doh.is("<div>some html text</div>", top.domNode.innerHTML.toLowerCase(), "top pane");
-					}
-				]
-			);
 			doh.run();
 		});
 	</script>
@@ -132,40 +204,6 @@
 	<h1 class="testTitle">_Widget.placeAt tests</h1>
 
 	<div id="container">
-
 	</div>
-
-	<h2>Node2</h2>
-	<p>This is where the tab srcNodeRef is, but it gets moved above us into the id="container" div.  (Should be there already.)</p>
-	<div id="otherContainer">
-		<div id="tabContainerThinger"></div>
-	</div>
-
-	<h2>BorderContainer sample</h2>
-	<div id="bc1" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"width:600px; height:400px"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"center", region:"center"'>
-			<button id="addStuff" data-dojo-type="dijit.form.Button">
-				Add Stuff
-				<script type="dojo/method" data-dojo-event="onClick">
-					this.set("disabled", true);
-					var bc = dijit.byId("bc1");
-
-					// add a left pane and add content
-					new dijit.layout.ContentPane({
-						region:"left",
-						style:"width:100px"
-					}).placeAt(bc).set("content","<p>wowzers</p>");
-
-					// add a top pane, and add content
-					new dijit.layout.ContentPane({
-						region:"top",
-						style:"height:100px"
-					}).placeAt(bc).set("content","<div>some HTML text</div>");
-
-				</script>
-			</button>
-		</div>
-	</div>
-
 </body>
 </html>
diff --git a/dijit/tests/_Widget-subscribe.html b/dijit/tests/_Widget-subscribe.html
index 2996275..78d9aa3 100644
--- a/dijit/tests/_Widget-subscribe.html
+++ b/dijit/tests/_Widget-subscribe.html
@@ -18,7 +18,7 @@
 			var externalString = "";
 			var internalSubscribe = null;
 	
-			dojo.declare("dijit.MyWidget", dijit._Widget, {
+			dojo.declare("MyWidget", dijit._Widget, {
 				_subscribeHandlerInternal: function(){ numCallsInternal++; }
 			});
 
@@ -68,12 +68,12 @@
 						runTest: function(t){
 							var w = dijit.byId("widget1");
 							dojo.publish("/custom/event", []);
-							doh.is(2, numCallsInternal);
-							doh.is(2, numCallsExternal);
+							doh.is(2, numCallsInternal, "numCallsInternal");
+							doh.is(2, numCallsExternal, "numCallsExternal");
 							w.unsubscribe(internalSubscribe);
 							dojo.publish("/custom/event", []);
-							doh.is(2, numCallsInternal);
-							doh.is(3, numCallsExternal);
+							doh.is(2, numCallsInternal, "numCallsInternal again");
+							doh.is(3, numCallsExternal, "numCallsExternal again");
 						}
 					},
 					{
@@ -82,10 +82,10 @@
 							var w = dijit.byId("widget1");
 							w.destroy();
 							dojo.publish("/custom/event", []);
-							doh.is(2, numCallsInternal);
-							doh.is(3, numCallsExternal);
+							doh.is(2, numCallsInternal, "numCallsInternal");
+							doh.is(3, numCallsExternal, "numCallsExternal");
 							dojo.publish("/custom/setString", ["myString"]);
-							doh.is("anotherString", externalString);
+							doh.is("anotherString", externalString, "externalString");
 						}
 					}
 				]
@@ -97,6 +97,6 @@
 	</script>
 </head>
 <body class="claro">
-	<div id="widget1" data-dojo-type="dijit.MyWidget"></div>
+	<div id="widget1" data-dojo-type="MyWidget"></div>
 </body>
 </html>
diff --git a/dijit/tests/_WidgetsInTemplateMixin.html b/dijit/tests/_WidgetsInTemplateMixin.html
index f09d795..af1ab5c 100644
--- a/dijit/tests/_WidgetsInTemplateMixin.html
+++ b/dijit/tests/_WidgetsInTemplateMixin.html
@@ -7,34 +7,40 @@
 		<style type="text/css">
 			@import "../themes/claro/document.css";
 			@import "../themes/claro/claro.css";
+
+			/* Make our tests stand out as easily identifiable content */
+			.testcontainer {
+				border: 10px yellow;
+				border-style: dashed;
+				padding: 1em;
+				margin: 1em;
+			}
+			.testcontainer > p {
+				padding: 0 1em;
+				font-weight: bold;
+			}
 		</style>
 
 		<script type="text/javascript" src="../../dojo/dojo.js"
-			data-dojo-config="isDebug: true"></script>
+			data-dojo-config="isDebug: true, async: true"></script>
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-
-			dojo.require("dojo.parser");
-
-			dojo.require("dijit._WidgetBase");
-			dojo.require("dijit._Widget");		// for getDescendants() testing
-			dojo.require("dijit._TemplatedMixin");
-			dojo.require("dijit._WidgetsInTemplateMixin");
-			dojo.require("dijit.form.Button");
-			dojo.require("dijit.form.CheckBox");
-			dojo.require("dijit.ProgressBar");
-			dojo.require("dijit.layout.ContentPane");
-			dojo.require("dijit.layout.TabContainer");
-			dojo.require("dijit._Container");
-			dojo.require("dijit._Contained");
-			dojo.require("dijit.layout._LayoutWidget");
-			dojo.require("dijit.focus");	// dijit.focus()
-
-			dojo.ready(function(){
-				dojo.declare('Test1Widget',
-					[dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin],
-				{
-					templateString: dojo.byId('Test1Template').value,
+			require([
+				"doh", "dojo/_base/array", "dojo/_base/declare", "dojo/_base/window", "dojo/dom", "dojo/dom-geometry",
+				"dojo/html", "dojo/query", "dojo/parser",
+				"dijit/registry", "dijit/_WidgetBase", "dijit/_Widget",
+				"dijit/_AttachMixin", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin",
+				"dijit/form/Button", "dijit/form/CheckBox", "dijit/form/TextBox",
+				"dijit/ProgressBar", "dijit/layout/ContentPane", "dijit/layout/TabContainer", "dijit/_Container",
+				"dijit/_Contained", "dijit/layout/_LayoutWidget", "dijit/tests/resources/TestContextRequireWidget",
+				"dijit/focus",
+				"dojo/domReady!"
+			], function(doh, array, declare, win, dom, domGeom, html, query, parser,
+					registry, _WidgetBase, _Widget, _AttachMixin, _TemplatedMixin, _WidgetsInTemplateMixin,
+					Button, CheckBox, TextBox, ProgressBar, ContentPane, TabContainer,
+					_Container, _Contained, _LayoutWidget, TestContextRequireWidget, focusUtil){
+
+				declare('Test1Widget', [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+					templateString: dom.byId('Test1Template').value,
 					onClick: function(e){
 						if(e.target){
 							alert('onClick widgetId='+e.target.id);
@@ -48,23 +54,19 @@
 					}
 				});
 
-				dojo.declare('Test3Widget',
-					[dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin],
-				{
-					templateString: dojo.byId('Test3Template').value
+				declare('Test3Widget', [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+					templateString: dom.byId('Test3Template').value
 				});
 
-				dojo.declare('Test4Widget',
-					[dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin],
-				{
-					templateString: dojo.byId('Test4Template').value
+				declare('Test4Widget', [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+					templateString: dom.byId('Test4Template').value
 				});
 		
 				function validateTest4Widget(t, testW){
-					var selectedTab = dojo.query(".dijitTabChecked", testW.domNode)[0];
-					var selectedPane = dojo.query(".dijitTabPane.dijitVisible", testW.domNode)[0];
-					var tabBox = selectedTab ? dojo.contentBox(selectedTab) : null;
-					var paneBox = selectedPane ? dojo.contentBox(selectedPane) : null;
+					var selectedTab = query(".dijitTabChecked", testW.domNode)[0];
+					var selectedPane = query(".dijitVisible > .dijitTabPane", testW.domNode)[0];
+					var tabBox = selectedTab ? domGeom.getContentBox(selectedTab) : null;
+					var paneBox = selectedPane ? domGeom.getContentBox(selectedPane) : null;
 					doh.t(tabBox && tabBox.w> 0 && tabBox.h> 0, "tabBox && tabBox.w> 0 && tabBox.h> 0");
 					doh.t(paneBox && paneBox.w> 0 && paneBox.h> 0, "paneBox && paneBox.w> 0 && paneBox.h");
 					// Check that everything got started
@@ -74,7 +76,7 @@
 					doh.t(testW.tab2._started, "tab2._started");
 				}
 			
-				dojo.declare('TestLayoutWidget', dijit.layout._LayoutWidget, {
+				declare('TestLayoutWidget', _LayoutWidget, {
 					startup: function(){
 						if(this._started){
 							this._doubleStarted = true;
@@ -89,7 +91,8 @@
 						this._destroyed = true;
 					}
 				});
-				dojo.declare('TestCtnrWidget', [dijit._WidgetBase, dijit._Container], {
+
+				declare('TestCtnrWidget', [_WidgetBase, _Container], {
 					startup: function(){
 						if(this._started){
 							this._doubleStarted = true;
@@ -104,7 +107,8 @@
 						this._destroyed = true;
 					}
 				});
-				dojo.declare('TestCtndWidget', [dijit._WidgetBase, dijit._Contained], {
+
+				declare('TestCtndWidget', [_WidgetBase, _Contained], {
 					startup: function(){
 						if(this._started){
 							this._doubleStarted = true;
@@ -119,7 +123,8 @@
 						this._destroyed = true;
 					}
 				});
-				dojo.declare('TestNonCtnrWidget', [dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
+
+				declare('TestNonCtnrWidget', [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
 					templateString: "<div data-dojo-attach-point=containerNode></div>",
 					startup: function(){
 						if(this._started){
@@ -135,7 +140,8 @@
 						this._destroyed = true;
 					}
 				});
-				dojo.declare('TestStubWidget', dijit._WidgetBase, {
+
+				declare('TestStubWidget', _WidgetBase, {
 					startup: function(){
 						if(this._started){
 							this._doubleStarted = true;
@@ -151,10 +157,10 @@
 					}
 				});
 	
-				dojo.declare('Test5Widget',
-					[dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin],
+				declare('Test5Widget',
+					[_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin],
 				{
-					templateString: dojo.byId('Test5Template').value,
+					templateString: dom.byId('Test5Template').value,
 					startup: function(){
 						if(this._started){
 							this._doubleStarted = true;
@@ -169,11 +175,19 @@
 						this._destroyed = true;
 					}
 				});
-	
-				dojo.declare("Missing", [dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
+
+				declare('Test6Widget', [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+					templateString: dom.byId('Test6Template').value,
+					clickCount: 0,
+					handleClick: function(){
+						this.clickCount++;
+					}
+				});
+
+				declare("Missing", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
 					templateString: '<div>' +
-										'<div data-dojo-type="dijit.layout.ContentPane">' +
-											'<div data-dojo-type="dijit.form.Button" data-dojo-props="id: \'missingButtonId\'" ' +
+										'<div data-dojo-type="dijit/layout/ContentPane">' +
+											'<div data-dojo-type="dijit/form/Button" data-dojo-props="id: \'missingButtonId\'" ' +
 											'data-dojo-attach-point="missingButton">Missing...</div>' +
 										'</div>' +
 									'</div>'
@@ -203,7 +217,7 @@
 		
 				function validateTest5Widget(t, testW){
 					// Check that everything got started, but not double-started
-					dojo.forEach(getTestWidgets(testW), function(w){
+					array.forEach(getTestWidgets(testW), function(w){
 						doh.t(w._started, "w._started: " + w);
 						doh.is(undefined, w._doubleStarted, "w._doubleStarted: " + w);
 					});
@@ -212,181 +226,269 @@
 				function validateTest5WidgetDestroy(t, testW){
 					var savedWidgets = getTestWidgets(testW);
 					testW.destroy();
-					dojo.forEach(savedWidgets, function(w, idx){
+					array.forEach(savedWidgets, function(w, idx){
 						doh.t(w._destroyed, "w._destroyed: " + w);
 						doh.is(undefined, w._doubleDestroyed, "w._doubleDestroyed: " + w);
 					});
 				}
 
-				doh.register("parse", function(){
-					dojo.parser.parse();
-				});
+				doh.register("_AttachMixin-widgetInTemplate", [
+					function createAttachWidgetsCombo() {
+						/*** TEST _AttachMixin combined with _WidgetsInTemplateMixin ***/
+						var AttachWidgetsCombo = declare([ _WidgetBase, _AttachMixin, _WidgetsInTemplateMixin ], {
 
-				doh.register("_Templated-widgetsInTemplate",
-					[
-						{
-							name: "data-dojo-attach-point",
-							runTest: function(t){
-								var testW = dijit.byId("test1Widget");
-								doh.t(testW, "test1Widget was instantiated");
-								doh.t(testW.normalNode, "normalNode");
-								doh.f(isNaN(testW.normalNode.nodeType), "normalNode.nodeType");
-								doh.t(testW.buttonWidget instanceof dijit.form.Button, "buttonWidget is Button");
-								doh.t(testW.checkboxWidget instanceof dijit.form.CheckBox, "checkboxWidget is CheckBox");
-								doh.t(testW.progressBarWidget instanceof dijit.ProgressBar, "progressBarWidget is ProgressBar");
+							postCreate: function() {
+								html.set(this.heading, "Amazing things will happen if you click this button!!!");
+							},
+							_buttonClicked: function(e) {
+								html.set(this.heading, "Well that was boring. " +
+										"My attach point button thinks it is a " + (this.mybutton.isInstanceOf(Button) ? 'dijit/form/Button':'Gruffalo'));
 							}
-						},
-						{
-							name: "data-dojo-attach-event",
-							runTest: function(t){
-								var testW = dijit.byId("test1Widget");
-								testW.buttonWidget._counter=0;
-								testW.buttonWidget.onClick(testW.buttonWidget);
-								testW.checkboxWidget._counter=0;
-								testW.checkboxWidget.onClick(testW.checkboxWidget);
-								testW.progressBarWidget._counter=0;
-								testW.progressBarWidget.onChange(testW.progressBarWidget);
-								doh.is(1,testW.buttonWidget._counter, "buttonWidget._counter");
-								doh.is(1,testW.checkboxWidget._counter, "checkboxWidget._counter");
-								doh.is(1,testW.progressBarWidget._counter, "progressBarWidget._counter");
+						});
+
+						var myawc = new AttachWidgetsCombo({}, dom.byId('attachMeThree'));
+
+						doh.t(myawc.heading, "heading");
+						doh.t(myawc.mybutton, "mybutton");
+						doh.is("Amazing things will happen if you click this button!!!", myawc.heading.innerHTML, "Initial value");
+
+						// Simulate a change
+						myawc.mybutton.onClick();
+
+						doh.is("Well that was boring. My attach point button thinks it is a dijit/form/Button", myawc.heading.innerHTML, "Post-op value");
+					},
+
+					function containerNode(){
+						// Test that widgets inside of containerNode aren't parsed by _WidgetsInTemplateMixin
+
+						declare("OuterWidget", [ _WidgetBase, _AttachMixin, _WidgetsInTemplateMixin ], {
+							// Prevent the main parser call from hitting my supporting widgets.
+							// But this also stops the parser from hitting anything inside my containerNode, so I need
+							// to do a recursive parse() like ContentPane does (or just extend ContentPane)
+							stopParser: true,
+
+							postCreate: function(){
+								doh.is(0, this.getChildren().length, "contained widget not created yet");
+								parser.parse(this.containerNode);
 							}
-						},
-						{
-							// Test that getDescendants ()
-							// finds direct descendants but skips widgetsInTemplates
-							// and also nested widgets (if direct==true)
-							name: "destruction",
-							runTest: function(t){
-								var testW = dijit.byId("test3Widget");
+						});
+						declare("SupportingWidget", _WidgetBase);
+						declare("ContainedWidget", _WidgetBase);
+						parser.parse(dom.byId("containerNode"));
+
+						doh.t("outerWidget" in window, "outer widget created");
+						doh.t(outerWidget.supportingWidget, "supporting widget instantiated");
+						doh.f(outerWidget.containedWidget, "contained widget not instantiated by _WidgetsInTemplateMixin parse call");
+
+						doh.is(1, outerWidget.getChildren().length, "contained widget created too");
+					}
+				]);
+
+				doh.register("_Templated-widgetsInTemplate", [
+					function parse(){
+						parser.parse("templateTests");
+					},
+					{
+						name: "data-dojo-attach-point",
+						runTest: function(t){
+							var testW = registry.byId("test1Widget");
+							doh.t(testW, "test1Widget was instantiated");
+							doh.t(testW.normalNode, "normalNode");
+							doh.f(isNaN(testW.normalNode.nodeType), "normalNode.nodeType");
+							doh.t(testW.buttonWidget instanceof Button, "buttonWidget is Button");
+							doh.t(testW.checkboxWidget instanceof CheckBox, "checkboxWidget is CheckBox");
+							doh.t(testW.progressBarWidget instanceof ProgressBar, "progressBarWidget is ProgressBar");
+						}
+					},
+					{
+						name: "data-dojo-attach-event",
+						runTest: function(t){
+							var testW = registry.byId("test1Widget");
+							testW.buttonWidget._counter=0;
+							testW.buttonWidget.onClick(testW.buttonWidget);
+							testW.checkboxWidget._counter=0;
+							testW.checkboxWidget.onClick(testW.checkboxWidget);
+							testW.progressBarWidget._counter=0;
+							testW.progressBarWidget.onChange(testW.progressBarWidget);
+							doh.is(1,testW.buttonWidget._counter, "buttonWidget._counter");
+							doh.is(1,testW.checkboxWidget._counter, "checkboxWidget._counter");
+							doh.is(1,testW.progressBarWidget._counter, "progressBarWidget._counter");
+						}
+					},
+					{
+						name: "data-dojo-attach-event strange name",
+						runTest: function(t){
+							// This is for testing data-dojo-attach-event to attach to a method in the widget,
+							// rather than using _WidgetBase.on(...).   Remove for 2.0.
+							var SubWidget = declare("SubWidget", _WidgetBase, {
+								f: function(){
+									// just for attaching to
+								}
+							});
+							var MainWidget = declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+								templateString:
+									'<div>' +
+										'<div data-dojo-type="SubWidget" data-dojo-attach-point="sw" ' +
+											' data-dojo-attach-event="f: g">' +
+									'</div>',
+								g: function(){
+									this.gWasCalled = true;
+								}
+							});
+							var mw = new MainWidget();
+							doh.t(mw.sw, "attach-point exists");
+							mw.sw.f();
+							doh.t(mw.gWasCalled, "attach-event worked");
+						}
+					},
+					{
+						// Test that getDescendants ()
+						// finds direct descendants but skips widgetsInTemplates
+						// and also nested widgets (if direct==true)
+						name: "getChildren",
+						runTest: function(t){
+							var testW = registry.byId("test3Widget");
 
 /*** performance tests
-								var start = new Date();
-								for(var i=0; i<1000; i++)
-									testW.getChildren();
-								console.log("*** time for getChildren(): " + (new Date()-start));
-								var start = new Date();
-								for(var i=0; i<1000; i++)
-									testW.getDescendants();
-								console.log("*** time for getDescendants(false): " + (new Date()-start));
+							var start = new Date();
+							for(var i=0; i<1000; i++)
+								testW.getChildren();
+							console.log("*** time for getChildren(): " + (new Date()-start));
+							var start = new Date();
+							for(var i=0; i<1000; i++)
+								testW.getDescendants();
+							console.log("*** time for getDescendants(false): " + (new Date()-start));
 ***/
-								var chil = testW.getChildren();
-								doh.is(5, chil.length, "number of direct descendants");
-								doh.is(chil[0].id, "3.1");
-								doh.is(chil[1].id, "3.2");
-								doh.is(chil[2].id, "3.3");
-								doh.is(chil[3].id, "3.4");
-								doh.is(chil[4].id, "3.5");
-
-								var desc = testW.getDescendants();
-								doh.is(7, desc.length, "number of descendants (including nested ones)");
-								doh.is(desc[0].id, "3.1");
-								doh.is(desc[1].id, "3.2");
-								doh.is(desc[2].id, "3.3");
-								doh.is(desc[3].id, "3.nested");
-								doh.is(desc[4].id, "3.nested2");
-								doh.is(desc[5].id, "3.4");
-								doh.is(desc[6].id, "3.5");
-							}
-						},
-						{
-							// Check that declarative widget with layout widgets in template is correctly created and rendered
-							name: "declarative widget with layout widgets",
-							runTest: function(t){
-								validateTest4Widget(t, dijit.byId("test4Widget"));
-							}
-						},
-						{
-							// Check that programatic widget with layout widgets in template is correctly created and rendered
-							name: "programmatic widget with layout widgets",
-							runTest: function(t){
-								test4WidgetProgrammatic = new Test4Widget({}).placeAt("test4Widget", "after");
-								test4WidgetProgrammatic.startup();
-								validateTest4Widget(t, test4WidgetProgrammatic);
-							}
-						},
-						{
-							// Compare programmatic and declaratively created widget with layout widgets in template
-							name: "programmatic vs declarative with layout widgets",
-							runTest: function(t){
-								// Focus the body, so that we don't have different classes on our
-								// two widgets
-								dijit.focus(dojo.body());
-								var declW = dijit.byId("test4Widget");
-								var progW = test4WidgetProgrammatic;
-
-								// Check that generated HTML in DOM is same
-								var declNeutralHtml = declW.domNode.innerHTML.replace(/_\d+/g, "");
-								var progNeutralHtml = progW.domNode.innerHTML.replace(/_\d+/g, "");
-								if(declNeutralHtml != progNeutralHtml){
-									for(var i=0; i<declNeutralHtml.length; i++){
-										if(progNeutralHtml.charAt(i) != declNeutralHtml.charAt(i)){
-											console.log("***Difference starting at " + i);
-											console.log("declarative: " + declNeutralHtml.substr(Math.max(0, i-5), 50));
-											console.log("programmatic: " + progNeutralHtml.substr(Math.max(0, i-5), 50));
-											break;
-										}
+							var chil = testW.getChildren();
+							doh.is(5, chil.length, "number of direct descendants");
+							doh.is(chil[0].id, "3.1");
+							doh.is(chil[1].id, "3.2");
+							doh.is(chil[2].id, "3.3");
+							doh.is(chil[3].id, "3.4");
+							doh.is(chil[4].id, "3.5");
+
+							// remove this test for 2.0
+							var desc = testW.getDescendants();
+							doh.is(7, desc.length, "number of descendants (including nested ones)");
+							doh.is(desc[0].id, "3.1");
+							doh.is(desc[1].id, "3.2");
+							doh.is(desc[2].id, "3.3");
+							doh.is(desc[3].id, "3.nested");
+							doh.is(desc[4].id, "3.nested2");
+							doh.is(desc[5].id, "3.4");
+							doh.is(desc[6].id, "3.5");
+						}
+					},
+					{
+						// Check that declarative widget with layout widgets in template is correctly created and rendered
+						name: "declarative widget with layout widgets",
+						runTest: function(t){
+							validateTest4Widget(t, registry.byId("test4Widget"));
+						}
+					},
+					{
+						// Check that programatic widget with layout widgets in template is correctly created and rendered
+						name: "programmatic widget with layout widgets",
+						runTest: function(t){
+							test4WidgetProgrammatic = new Test4Widget({}).placeAt("test4Widget", "after");
+							test4WidgetProgrammatic.startup();
+							validateTest4Widget(t, test4WidgetProgrammatic);
+						}
+					},
+					{
+						// Compare programmatic and declaratively created widget with layout widgets in template
+						name: "programmatic vs declarative with layout widgets",
+						runTest: function(t){
+							// Focus the body, so that we don't have different classes on our
+							// two widgets
+							focusUtil.focus(win.body());
+							var declW = registry.byId("test4Widget");
+							var progW = test4WidgetProgrammatic;
+
+							// Check that generated HTML in DOM is same
+							var declNeutralHtml = declW.domNode.innerHTML.replace(/_\d+/g, "");
+							var progNeutralHtml = progW.domNode.innerHTML.replace(/_\d+/g, "");
+							if(declNeutralHtml != progNeutralHtml){
+								for(var i=0; i<declNeutralHtml.length; i++){
+									if(progNeutralHtml.charAt(i) != declNeutralHtml.charAt(i)){
+										console.log("***Difference starting at " + i);
+										console.log("declarative: " + declNeutralHtml.substr(Math.max(0, i-5), 50));
+										console.log("programmatic: " + progNeutralHtml.substr(Math.max(0, i-5), 50));
+										break;
 									}
-									doh.t(declNeutralHtml == progNeutralHtml, "declNeutralHtml == progNeutralHtml");
 								}
-
-								// Check that dimensions are same
-								var declBox = dojo.contentBox(declW.domNode);
-								var progBox = dojo.contentBox(progW.domNode);
-								doh.is(declBox.h, progBox.h, "progBox.h");
-								doh.is(declBox.w, progBox.w, "progBox.w");
-							}
-						},
-						{
-							// Check that declarative widget with other widgets in template is correctly started
-							name: "declarative widget with many child widgets",
-							runTest: function(t){
-								validateTest5Widget(t, dijit.byId("test5Widget"));
-							}
-						},
-						{
-							// Check that programmatic widget with other widgets in template is correctly started
-							name: "programmatic widget with many child widgets",
-							runTest: function(t){
-								test5WidgetProgrammatic = new Test5Widget().placeAt("test5Widget", "after");
-								test5WidgetProgrammatic.startup();
-								validateTest5Widget(t, test5WidgetProgrammatic);
-							}
-						},
-						{
-							// Check that destroying our declarative widget works correctly
-							name: "declarative widget destruction",
-							runTest: function(t){
-								validateTest5WidgetDestroy(t, dijit.byId("test5Widget"));
-							}
-						},
-						{
-							// Check that destroying our programmatic widget works correctly
-							name: "programmatic widget destruction",
-							runTest: function(t){
-								validateTest5WidgetDestroy(t, test5WidgetProgrammatic);
-							}
-						},
-						{
-							// Test that data-dojo-attach-point inside of a ContentPane (inside of a template) works
-							name: "ContentPane",
-							runTest: function(){
-								var testW = dijit.byId("missing");
-								doh.t(testW, "widget was created");
-								doh.t(testW.missingButton, "data-dojo-attach-point created");
-								doh.is("dijit.form.Button", testW.missingButton.declaredClass, "and it's to a widget");
-								doh.t(dijit.byId("missingButtonId"), "nested widget also registered by id");
+								doh.t(declNeutralHtml == progNeutralHtml, "declNeutralHtml == progNeutralHtml");
 							}
+
+							// Check that dimensions are same
+							var declBox = domGeom.getContentBox(declW.domNode);
+							var progBox = domGeom.getContentBox(progW.domNode);
+							doh.is(declBox.h, progBox.h, "progBox.h");
+							doh.is(declBox.w, progBox.w, "progBox.w");
 						}
-					]
-				);
+					},
+					{
+						// Check that declarative widget with other widgets in template is correctly started
+						name: "declarative widget with many child widgets",
+						runTest: function(t){
+							validateTest5Widget(t, registry.byId("test5Widget"));
+						}
+					},
+					{
+						// Check that programmatic widget with other widgets in template is correctly started
+						name: "programmatic widget with many child widgets",
+						runTest: function(t){
+							test5WidgetProgrammatic = new Test5Widget().placeAt("test5Widget", "after");
+							test5WidgetProgrammatic.startup();
+							validateTest5Widget(t, test5WidgetProgrammatic);
+						}
+					},
+					{
+						// Check that destroying our declarative widget works correctly
+						name: "declarative widget destruction",
+						runTest: function(t){
+							validateTest5WidgetDestroy(t, registry.byId("test5Widget"));
+						}
+					},
+					{
+						// Check that destroying our programmatic widget works correctly
+						name: "programmatic widget destruction",
+						runTest: function(t){
+							validateTest5WidgetDestroy(t, test5WidgetProgrammatic);
+						}
+					},
+					{
+						// Test that data-dojo-attach-point inside of a ContentPane (inside of a template) works
+						name: "ContentPane",
+						runTest: function(){
+							var testW = registry.byId("missing");
+							doh.t(testW, "widget was created");
+							doh.t(testW.missingButton, "data-dojo-attach-point created");
+							doh.is("dijit.form.Button", testW.missingButton.declaredClass, "and it's to a widget");
+							doh.t(registry.byId("missingButtonId"), "nested widget also registered by id");
+						}
+					},
+					{
+						// Test that data-dojo-attach-event bindings work with widgets in template, when
+						// binding to dijit/_Widget methods
+						name: "_Widget Deferred Connect methods",
+						runTest: function(){
+							var test6Widget = registry.byId("test6Widget");
+							doh.t(test6Widget.clickCount === 0, "click count was initially zero");
+							// Issue a 'click' event directly on the interior input of the TextBox
+							test6Widget.textbox.textbox.click();
+							doh.t(test6Widget.clickCount === 1, "click count incremented properly");
+						}
+					}
+				]);
 
 				// Test that "this" referenced from data-dojo-props can refer to the hosting widget
 				doh.register("data-dojo-props this", function(){
-					var host = dojo.declare([dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
+					var host = declare([dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
 						obj: {hello: "world"},
 						templateString:
 							"<div>" +
-								"<div data-dojo-type='dijit._WidgetBase' data-dojo-props='hostObj: this.obj'" +
+								"<div data-dojo-type='dijit/_WidgetBase' data-dojo-props='hostObj: this.obj'" +
 								" data-dojo-attach-point='subWidget'></div>" +
 							"</div>"
 					});
@@ -399,96 +501,144 @@
 					doh.is("world", subWidget.hostObj.hello, "object is correct")
 				});
 
+				// Test that a context require can be passed to the parser
+				doh.register("context require", function(){
+					var cw = registry.byId("testContextWidget");
+					doh.is(typeof cw.fooNode, "object", "button created");
+					doh.is(cw.fooNode.fooNode.innerHTML, "TestWidget", "sub widget contains right properties");
+				});
+
 				doh.run();
 			});
 		</script>
 	</head>
 	<body class="claro">
 		<h1>WidgetsInTemplateMixin</h1>
-		<textarea id="Test1Template" style="display:none;">
-			<div>
-				<div data-dojo-attach-point="normalNode">normal node</div>
-				<button data-dojo-attach-point="buttonWidget" data-dojo-attach-event="onClick:onClick" data-dojo-type="dijit.form.Button">button #1</button>
-				<div data-dojo-attach-point="checkboxWidget" data-dojo-attach-event="onClick:onClick" data-dojo-type="dijit.form.CheckBox"></div> checkbox #1
-				<div data-dojo-attach-point="progressBarWidget" data-dojo-attach-event="onChange:onClick"
-					data-dojo-type="dijit.ProgressBar" data-dojo-props='value: 20, maximum: 200, style: "width:400px;"'></div>
-			</div>
-		</textarea>
 
-		<div data-dojo-type="Test1Widget" data-dojo-props="id: 'test1Widget'"></div>
-	
-	
-		<textarea id="Test3Template" style="display:none;">
-			<div>
-				<div data-dojo-attach-point="checkboxWidget" data-dojo-type="dijit.form.CheckBox"></div> checkbox #3
-				<div data-dojo-attach-point="containerNode"></div>
-			</div>
-		</textarea>
-
-		<div data-dojo-type="Test3Widget" data-dojo-props="id: 'test3Widget'">
-			<span>hello world</span>
-			<b style="border: 1px solid blue;">this is my
-				<button data-dojo-type="dijit.form.Button" data-dojo-props="id: '3.1'">first button</button>
-			</b>
-			<button data-dojo-type="dijit.form.Button" data-dojo-props="id: '3.2'">another button</button>
-			<i>and some more</i>
-			<div style="border: 1px solid red;">
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="style: {border: '1px solid gray'}, id: '3.3'">
-					<button data-dojo-type="dijit.form.Button" data-dojo-props="id: '3.nested'">a nested button</button>
-					<button data-dojo-type="dijit.form.Button" data-dojo-props="id: '3.nested2'">another nested button</button>
-				</div>
-				<button data-dojo-type="dijit.form.Button" data-dojo-props="id: '3.4'">yet another button</button>
-				<button data-dojo-type="dijit.form.Button" data-dojo-props="id: '3.5'">yet yet another button</button>
+		<!-- Tests for _WidgetsInTemplateMixin combined with _AttachMixin -->
+		<div class="testcontainer">
+			<p>This test shows that a _AttachMixin dijit with _WidgetsInTemplate properly attaches widgets from the template.<br>
+			<div id="attachMeThree">
+				<h2 data-dojo-attach-point='heading'></h2>
+				<button data-dojo-type='dijit/form/Button'
+						data-dojo-attach-point='mybutton'
+						data-dojo-attach-event='onClick: _buttonClicked'>A button</button>
 			</div>
 		</div>
 
-		<!-- Test templated widget containing layout widgets in template -->
-		<textarea id="Test4Template" style="display:none;">
-			<div>
-				<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props="style: {height: '5em', width: '100em'}" data-dojo-attach-point="tabCont">
-					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title: 'Tab 1'" data-dojo-attach-point="tab1">
-						pane 1
-					</div>
-					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title: 'Tab 2'" data-dojo-attach-point="tab2">
-						pane 2
-					</div>
+		<!-- Test that widgets inside containerNode aren't parsed by _WidgetsInTemplateMixin-->
+		<div id="containerNode" class="testcontainer">
+			<p>This tests that nodes inside of data-dojo-attach-point="containerNode" are ignored<br>
+			<div data-dojo-id="outerWidget" data-dojo-type="OuterWidget">
+				<h2 data-dojo-attach-point="heading">heading</h2>
+				<div data-dojo-type="SupportingWidget" data-dojo-attach-point="supportingWidget">supporting widget</div>
+				<div data-dojo-attach-point="containerNode">
+					<span data-dojo-type="ContainedWidget" data-dojo-attach-point="containedWidget">contained widget</span>
 				</div>
 			</div>
-		</textarea>
+		</div>
 
-		<div data-dojo-type="Test4Widget" data-dojo-props="id: 'test4Widget'"></div>
-	
-		<!-- Test templated widget containing container and nested widgets in template -->
-		<textarea id="Test5Template" style="display:none;">
-			<div>
-				<div data-dojo-type="TestLayoutWidget" data-dojo-attach-point="layout">
-					<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="layChild1"></div>
-					<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="layChild2"></div>
+		<!-- Tests for _WidgetsInTemplateMixin combined with _TemplatedMixin -->
+		<div id="templateTests">
+			<textarea id="Test1Template" style="display:none;">
+				<div>
+					<div data-dojo-attach-point="normalNode">normal node</div>
+					<button data-dojo-attach-point="buttonWidget" data-dojo-attach-event="onClick:onClick" data-dojo-type="dijit/form/Button">button #1</button>
+					<div data-dojo-attach-point="checkboxWidget" data-dojo-attach-event="onClick:onClick" data-dojo-type="dijit/form/CheckBox"></div> checkbox #1
+					<div data-dojo-attach-point="progressBarWidget" data-dojo-attach-event="onChange:onClick"
+						 data-dojo-type="dijit/ProgressBar" data-dojo-props='value: 20, maximum: 200, style: "width:400px;"'></div>
 				</div>
-				<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="container">
-					<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="contained1"></div>
-					<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="contained2"></div>
+			</textarea>
+
+			<div data-dojo-type="Test1Widget" data-dojo-props="id: 'test1Widget'"></div>
+
+
+			<textarea id="Test3Template" style="display:none;">
+				<div>
+					<div data-dojo-attach-point="checkboxWidget" data-dojo-type="dijit/form/CheckBox"></div> checkbox #3
+					<div data-dojo-attach-point="containerNode"></div>
 				</div>
-				<div data-dojo-type="TestStubWidget" data-dojo-attach-point="stub1"></div>
-				<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="nonContainer">
-					<div data-dojo-type="TestStubWidget" data-dojo-attach-point="nonContained1"></div>
-					<div data-dojo-type="TestStubWidget" data-dojo-attach-point="nonContained2"></div>
+			</textarea>
+
+			<div data-dojo-type="Test3Widget" data-dojo-props="id: 'test3Widget'">
+				<span>hello world</span>
+				<b style="border: 1px solid blue;">this is my
+					<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.1'">first button</button>
+				</b>
+				<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.2'">another button</button>
+				<i>and some more</i>
+				<div style="border: 1px solid red;">
+					<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="style: {border: '1px solid gray'}, id: '3.3'">
+						<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.nested'">a nested button</button>
+						<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.nested2'">another nested button</button>
+					</div>
+					<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.4'">yet another button</button>
+					<button data-dojo-type="dijit/form/Button" data-dojo-props="id: '3.5'">yet yet another button</button>
 				</div>
-				<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="threeLevel">
-					<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="secondLevel">
-						<div data-dojo-type="TestStubWidget" data-dojo-attach-point="bottomLevel"></div>
+			</div>
+
+			<!-- Test templated widget containing layout widgets in template -->
+			<textarea id="Test4Template" style="display:none;">
+				<div>
+					<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props="style: {height: '5em', width: '100em'}" data-dojo-attach-point="tabCont">
+						<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="title: 'Tab 1'" data-dojo-attach-point="tab1">
+							pane 1
+						</div>
+						<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="title: 'Tab 2'" data-dojo-attach-point="tab2">
+							pane 2
+						</div>
 					</div>
 				</div>
-				<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="anotherThree">
-					<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="anotherSecond">
-						<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="anotherBottom"></div>
+			</textarea>
+
+			<div data-dojo-type="Test4Widget" data-dojo-props="id: 'test4Widget'"></div>
+
+			<!-- Test templated widget containing container and nested widgets in template -->
+			<textarea id="Test5Template" style="display:none;">
+				<div>
+					<div data-dojo-type="TestLayoutWidget" data-dojo-attach-point="layout">
+						<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="layChild1"></div>
+						<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="layChild2"></div>
+					</div>
+					<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="container">
+						<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="contained1"></div>
+						<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="contained2"></div>
+					</div>
+					<div data-dojo-type="TestStubWidget" data-dojo-attach-point="stub1"></div>
+					<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="nonContainer">
+						<div data-dojo-type="TestStubWidget" data-dojo-attach-point="nonContained1"></div>
+						<div data-dojo-type="TestStubWidget" data-dojo-attach-point="nonContained2"></div>
+					</div>
+					<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="threeLevel">
+						<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="secondLevel">
+							<div data-dojo-type="TestStubWidget" data-dojo-attach-point="bottomLevel"></div>
+						</div>
+					</div>
+					<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="anotherThree">
+						<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="anotherSecond">
+							<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="anotherBottom"></div>
+						</div>
 					</div>
 				</div>
-			</div>
-		</textarea>
+			</textarea>
+
+			<div data-dojo-type="Test5Widget" data-dojo-props="id: 'test5Widget'"></div>
 
-		<div data-dojo-type="Test5Widget" data-dojo-props="id: 'test5Widget'"></div>
+			<div data-dojo-type="Missing" data-dojo-props="id: 'missing'"></div>
+
+			<!-- Test templated widget containing relative MIDs for data-dojo-type -->
+			<div data-dojo-type="dijit/tests/resources/TestContextRequireWidget" data-dojo-props="id: 'testContextWidget'"></div>
+
+			<!-- Test templated widget for back-compat with inherited onClick etc events when using widgets in template -->
+			<textarea id="Test6Template" style="display:none;">
+				<div>
+					<div data-dojo-type="dijit/form/TextBox" data-dojo-attach-point="textbox" data-dojo-attach-event="onClick: handleClick"></div>
+				</div>
+			</textarea>
+
+			<div data-dojo-type="Test6Widget" data-dojo-props="id: 'test6Widget'"></div>
+
+		</div>
 
-		<div data-dojo-type="Missing" data-dojo-props="id: 'missing'"></div>
 	</body>
 </html>
diff --git a/dijit/tests/_altCalendar.html b/dijit/tests/_altCalendar.html
deleted file mode 100644
index 134e45e..0000000
--- a/dijit/tests/_altCalendar.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<table cellspacing="0" cellpadding="0" class="dijitCalendarContainer" role="grid">
-	<thead>
-		<tr class="dijitReset dijitCalendarMonthContainer" valign="top">
-			<th>			
-			<span class='dijitReset dijitCalendarArrow' data-dojo-attach-point="decrementMonth">
-				<img src="${_blankGif}" alt="" class="dijitCalendarIncrementControl dijitCalendarDecrease" role="presentation">
-				<span data-dojo-attach-point="decreaseArrowNode" class="dijitA11ySideArrow">-</span>
-			</span>
-			<span data-dojo-attach-event="onclick: goToToday" style="cursor: pointer">ࣻ</span>
-			<span class='dijitReset dijitCalendarArrow' data-dojo-attach-point="incrementMonth">
-				<img src="${_blankGif}" alt="" class="dijitCalendarIncrementControl dijitCalendarIncrease" role="presentation"/>
-				<span data-dojo-attach-point="increaseArrowNode" class="dijitA11ySideArrow">+</span>
-			</span></th>
-			<th class='dijitReset' colspan="6">
-				<div data-dojo-attach-point="monthNode">
-				</div>
-			</th>
-		</tr>
-		<tr>
-			${!dayCellsHtml}
-		</tr>
-	</thead>
-	<tbody data-dojo-attach-point="dateRowsNode" data-dojo-attach-event="onclick: _onDayClick" class="dijitReset dijitCalendarBodyContainer">
-		${!dateRowsHtml}
-	</tbody>
-	<tfoot class="dijitReset dijitCalendarYearContainer">
-		<tr>
-			<td class='dijitReset' valign="top" colspan="7" role="presentation">
-				<h3 class="dijitCalendarYearLabel">
-					<span data-dojo-attach-point="previousYearLabelNode" class="dijitInline dijitCalendarPreviousYear" role="button"></span>
-					«<span data-dojo-attach-point="currentYearLabelNode" class="dijitInline dijitCalendarSelectedYear" role="button"></span>»
-					<span data-dojo-attach-point="nextYearLabelNode" class="dijitInline dijitCalendarNextYear" role="button"></span>
-				</h3>
-			</td>
-		</tr>
-	</tfoot>
-</table>
diff --git a/dijit/tests/_base/manager.html b/dijit/tests/_base/manager.html
index 6cf6e27..4477614 100644
--- a/dijit/tests/_base/manager.html
+++ b/dijit/tests/_base/manager.html
@@ -1,4 +1,9 @@
 <!DOCTYPE html>
+
+<!--
+	Remove in 2.0.   Replaced by dijit/tests/registry.html
+-->
+
 <html>
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
diff --git a/dijit/tests/_base/module.js b/dijit/tests/_base/module.js
index 222b5b7..d8a0fd3 100644
--- a/dijit/tests/_base/module.js
+++ b/dijit/tests/_base/module.js
@@ -1,21 +1,15 @@
-dojo.provide("dijit.tests._base.module");
+define(["doh/main", "require"], function(doh, require){
 
-try{
-	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?"),
-		test_robot = true;
+	var test_robot = true;
 
-	doh.registerUrl("dijit.tests._base.manager", dojo.moduleUrl("dijit", "tests/_base/manager.html"), 999999);
-	doh.registerUrl("dijit.tests._base.tabindex", dojo.moduleUrl("dijit", "tests/_base/tabindex.html"), 999999);
-	doh.registerUrl("dijit.tests._base.wai", dojo.moduleUrl("dijit", "tests/_base/wai.html"), 999999);
-	doh.registerUrl("dijit.tests._base.place", dojo.moduleUrl("dijit", "tests/_base/place.html"), 999999);
+	doh.register("_base.manager", require.toUrl("./manager.html"), 999999);
+	doh.register("_base.wai", require.toUrl("./wai.html"), 999999);
+	doh.register("_base.place", require.toUrl("./place.html"), 999999);
+	doh.register("_base.popup", require.toUrl("./popup.html"), 999999);
 	if(test_robot){
-		doh.registerUrl("dijit.tests._base.robot.popup", dojo.moduleUrl("dijit", "tests/_base/robot/popup.html"), 999999);
-		doh.registerUrl("dijit.tests._base.robot.CrossWindow", dojo.moduleUrl("dijit","tests/_base/robot/CrossWindow.html"), 999999);
-		doh.registerUrl("dijit.tests._base.robot.FocusManager", dojo.moduleUrl("dijit","tests/_base/robot/FocusManager.html"), 999999);
-		doh.registerUrl("dijit.tests._base.robot.focus_mouse", dojo.moduleUrl("dijit","tests/_base/robot/focus_mouse.html"), 999999);
-		doh.registerUrl("dijit.tests._base.robot.typematic", dojo.moduleUrl("dijit","tests/_base/robot/typematic.html"), 999999);
+		doh.register("_base.robot.CrossWindow", require.toUrl("./robot/CrossWindow.html"), 999999);
+		doh.register("_base.robot.FocusManager", require.toUrl("./robot/FocusManager.html"), 999999);
+		doh.register("_base.robot.focus_mouse", require.toUrl("./robot/focus_mouse.html"), 999999);
 	}
 
-}catch(e){
-	doh.debug(e);
-}
+});
diff --git a/dijit/tests/_base/place.html b/dijit/tests/_base/place.html
index f0fe3c4..a893301 100644
--- a/dijit/tests/_base/place.html
+++ b/dijit/tests/_base/place.html
@@ -1,8 +1,14 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 		"http://www.w3.org/TR/html4/strict.dtd">
+
+<!--
+    Test case for dijit/_base/place.
+    Remove in 2.0 in favor of dijit/tests/place.html
+-->
+
 <html>
 <head>
-	<title>Dijit.place unit test</title>
+	<title>dijit/_base/place unit test</title>
 	<style type="text/css">
 		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
@@ -32,7 +38,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: false"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: false"></script>
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
 	<script type="text/javascript">
@@ -52,7 +58,7 @@
 			// The popup (aka dropdown)
 			var popup = dojo.byId("popup");
 
-			doh.register("dijit._base.place",
+			doh.register("dijit/_base/place",
 				[
 					function placeOnScreenTL(t){
 						// Place popup at (10,7)... dijit.placeOnScreen() should choose the top-left corner, because
@@ -82,13 +88,14 @@
 						var ret = dijit.placeOnScreenAroundNode(popup, aroundTop, {
 							"TL": "BL",	// aroundTop's top-left corner with the popup's bottom-left corner (fails)
 							"BL": "TL",	// aroundTop's bottom-left corner with the popup's top-left corner (works)
-							"BR": "TR"	// aroundTop's bottom-left corner with the popup's top-left corner (works)
+							"BR": "TR"	// aroundTop's bottom-right corner with the popup's top-right corner (works)
 						});
 
 						doh.is("BL", ret.aroundCorner, "around corner");
 						doh.is("TL", ret.corner, "popup's corner");
 						doh.is("20px", popup.style.top, "underneath around node");
-						doh.is(dojo.position(aroundTop).x+"px", popup.style.left, "left sides aligned");
+						doh.is(Math.round(dojo.position(aroundTop).x), Math.round(popup.style.left.replace("px", "")),
+								"left sides aligned");
 					},
 					function placeOnScreenAroundNodeTooltip(t){
 						// Same as above test except that shape of drop down changes depending on where it's positioned.
@@ -101,14 +108,14 @@
 						var ret = dijit.placeOnScreenAroundNode(popup, aroundTop, {
 							"TL": "BL",	// aroundTop's top-left corner with the popup's bottom-left corner (fails)
 							"BL": "TL",	// aroundTop's bottom-left corner with the popup's top-left corner (works)
-							"BR": "TR"	// aroundTop's bottom-left corner with the popup's top-left corner (works)
+							"BR": "TR"	// aroundTop's bottom-right corner with the popup's top-right corner (works)
 						}, layoutNode);
 
 						doh.is("BR", ret.aroundCorner, "around corner");
 						doh.is("TR", ret.corner, "popup's corner");
 						doh.is("20px", popup.style.top, "underneath around node");
-						doh.is(dojo.position(aroundTop).x+dojo.position(aroundTop).w,
-							dojo.position(popup).x+dojo.position(popup).w,
+						doh.is(Math.round(dojo.position(aroundTop).x + dojo.position(aroundTop).w),
+							Math.round(dojo.position(popup).x + dojo.position(popup).w),
 							"right sides aligned");
 					},
 					function placeOnScreenAroundNodeB(t){
@@ -117,12 +124,13 @@
 						var ret = dijit.placeOnScreenAroundNode(popup, aroundBottom, {
 							"BL": "TL",	// aroundBottom's bottom-left corner with the popup's top-left corner (fails)
 							"TL": "BL",	// aroundBottom's top-left corner with the popup's bottom-left corner (works)
-							"BR": "TR"	// aroundBottom's bottom-left corner with the popup's top-left corner (fails)
+							"BR": "TR"	// aroundBottom's bottom-right corner with the popup's top-right corner (fails)
 						});
 
 						doh.is("TL", ret.aroundCorner, "around corner");
 						doh.is("BL", ret.corner, "popup's corner");
-						doh.is(dojo.position(aroundBottom).y, dojo.position(popup).y + dojo.position(popup).h, "above around node");
+						doh.is(Math.round(dojo.position(aroundBottom).y),
+								Math.round(dojo.position(popup).y + dojo.position(popup).h), "above around node");
 					},
 					function placeOnScreenAroundNodeBM(t){
 						// bottom middle popup from "aroundBottom" node
@@ -137,7 +145,7 @@
 						doh.is("BM", ret.corner, "popup's middle");
 						var popupPos = dojo.position(popup);
 						var aroundPos = dojo.position(aroundBottom);
-						doh.is(aroundPos.y, popupPos.y + popupPos.h, "above around node");
+						doh.is(Math.round(aroundPos.y), Math.round(popupPos.y + popupPos.h), "above around node");
 						doh.t(aroundPos.x > popupPos.x, "starts before around node");
 						doh.t(aroundPos.x < (popupPos.x + popupPos.w), "ends after around node");
 					},
@@ -154,7 +162,7 @@
 						doh.is("TM", ret.corner, "popup's middle");
 						var popupPos = dojo.position(popup);
 						var aroundPos = dojo.position(aroundTop);
-						doh.is(aroundPos.y + aroundPos.h, popupPos.y, "below around node");
+						doh.is(Math.round(aroundPos.y + aroundPos.h), Math.round(popupPos.y), "below around node");
 						doh.t(aroundPos.x > popupPos.x, "starts before around node");
 						doh.t(aroundPos.x < (popupPos.x + popupPos.w), "ends after around node");
 					},
@@ -188,7 +196,7 @@
 						doh.is("MR", ret.corner, "popup's middle");
 						var popupPos = dojo.position(popup);
 						var aroundPos = dojo.position(aroundRight);
-						doh.is(popupPos.x + popupPos.w, aroundPos.x, "before around node");
+						doh.is(Math.round(popupPos.x + popupPos.w), Math.round(aroundPos.x), "before around node");
 						doh.t(aroundPos.y > popupPos.y, "starts before around node");
 						doh.t(aroundPos.y < (popupPos.y + popupPos.h), "ends after around node");
 					},
@@ -196,7 +204,7 @@
 						// bottom middle popup from "aroundLeft" node
 						var ret = dijit.placeOnScreenAroundNode(popup, aroundLeft, {
 							"BR": "TR",	// aroundLeft's bottom-right corner with the popup's top-right corner (fails)
-							"BM": "TM",	// aroundLeft's bottom-middle with the popup's top-middle (works)
+							"BM": "TM",	// aroundLeft's bottom-middle with the popup's top-middle (works, sort of)
 							"TR": "BR"	// aroundLeft's top-right corner with the popup's bottom-right corner (fails)
 						});
 
@@ -204,7 +212,7 @@
 						doh.is("TM", ret.corner, "popup's middle");
 						var popupPos = dojo.position(popup);
 						var aroundPos = dojo.position(aroundLeft);
-						doh.is(aroundPos.y + aroundPos.h, popupPos.y, "below around node");
+						doh.is(Math.round(aroundPos.y + aroundPos.h), Math.round(popupPos.y), "below around node");
 						doh.is(aroundPos.x, popupPos.x, "left aligned with around node");
 					},
 					function placeOnScreenAroundNodeMRT(t){
@@ -219,8 +227,9 @@
 						doh.is("BM", ret.corner, "popup's middle");
 						var popupPos = dojo.position(popup);
 						var aroundPos = dojo.position(aroundRight);
-						doh.is(popupPos.x + popupPos.w, aroundPos.x + aroundPos.w + 1/*right:1px*/, "right aligned with around node");
-						doh.is(popupPos.y + popupPos.h, aroundPos.y, "above around node");
+						doh.is(Math.round(popupPos.x + popupPos.w),
+								Math.round(aroundPos.x + aroundPos.w + 1/*right:1px*/), "right aligned with around node");
+						doh.is(Math.round(popupPos.y + popupPos.h), Math.round(aroundPos.y), "above around node");
 					},
 					function placeOnScreenAroundNodeTML(t){
 						// middle left popup from "aroundTop" node
@@ -234,7 +243,7 @@
 						doh.is("MR", ret.corner, "popup's middle");
 						var popupPos = dojo.position(popup);
 						var aroundPos = dojo.position(aroundTop);
-						doh.is(aroundPos.x, popupPos.x + popupPos.w, "before around node");
+						doh.is(Math.round(aroundPos.x), Math.round(popupPos.x + popupPos.w), "before around node");
 						doh.is(aroundPos.y, popupPos.y, "top aligned with around node");
 					},
 					function placeOnScreenAroundNodeBMR(t){
@@ -249,8 +258,9 @@
 						doh.is("ML", ret.corner, "popup's middle");
 						var popupPos = dojo.position(popup);
 						var aroundPos = dojo.position(aroundBottom);
-						doh.is(aroundPos.x + aroundPos.w, popupPos.x, "after around node");
-						doh.is(aroundPos.y + aroundPos.h + 5/*bottom:5px*/, popupPos.y + popupPos.h, "bottom aligned with around node");
+						doh.is(Math.round(aroundPos.x + aroundPos.w), Math.round(popupPos.x), "after around node");
+						doh.is(Math.round(aroundPos.y + aroundPos.h + 5/*bottom:5px*/),
+								Math.round(popupPos.y + popupPos.h), "bottom aligned with around node");
 					}
 				]
 			);
@@ -260,9 +270,9 @@
 	</script>
 </head>
 <body>
-	<h1>Dijit Place Unit Test</h1>
-	<div id="aroundTop" class="aroundNode" style="top: 0; left: 200px;">T</div>
-	<div id="aroundLeft" class="aroundNode" style="top: 350px; left: 0;">L</div>
+	<h1>Dijit/_base/place Unit Test</h1>
+	<div id="aroundTop" class="aroundNode" style="top: 0; left: 50%;">T</div>
+	<div id="aroundLeft" class="aroundNode" style="bottom: 30%; left: 0;">L</div>
 	<div id="aroundRight" class="aroundNode" style="bottom: 30%; right: 1px;">R</div>
 	<div id="aroundBottom" class="aroundNode" style="bottom: 5px; left: 50%;">B</div>
 
diff --git a/dijit/tests/_base/popup.html b/dijit/tests/_base/popup.html
new file mode 100644
index 0000000..13a61e3
--- /dev/null
+++ b/dijit/tests/_base/popup.html
@@ -0,0 +1,472 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+
+<!--
+	Tests the old dijit/_base/popup API.
+	Remove in 2.0.   Replaced by dijit/tests/popup.html.
+-->
+
+<html>
+<head>
+	<title>Dijit.popup and BackgroundIFrame unit test</title>
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../../themes/dijit.css";
+		@import "../css/dijitTests.css";
+
+		body {
+			height: 100%;
+			padding: 0;
+			margin: 0;
+		}
+
+		div {
+			background: white;
+			border: solid 1px gray;
+		}
+
+		/* the menu type test widgets */
+		.choice div {
+			width: 200px;
+			cursor: pointer;
+		}
+		.choice div:hover {
+			background: #ccc;
+		}
+	</style>
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, parseOnLoad: false"></script>
+	<script type="text/javascript" src="../_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit._base.popup");
+		dojo.require("dijit._Widget");
+		dojo.require("dijit._TemplatedMixin");
+		dojo.require("dijit.tests.helpers");	// functions to help test
+
+		function log(str){
+			console.log(str);
+		}
+
+		dojo.ready(function(){
+
+			dojo.declare("SimpleDropDownButton", [dijit._Widget, dijit._TemplatedMixin], {
+				// summary:
+				//		A button that shows a popup.
+				//		Supply popup as parameter when instantiating this widget.
+
+				label: "show popup",
+				orient: {'BL': 'TL', 'BR': 'TR'},
+
+				templateString: "<button data-dojo-attach-event='onclick: openPopup'>${label}</button>",
+
+				openPopup: function(){
+					var self = this;
+
+					dijit.popup.open({
+						popup: this.popup,
+						parent: this,
+						around: this.domNode,
+						orient: this.orient,
+						onCancel: function(){
+							log(self.id + ": cancel of child");
+						},
+						onExecute: function(){
+							log(self.id + ": execute of child");
+							dijit.popup.close(self.popup);
+							self.open = false;
+						}
+					});
+
+					this.open = true;
+				},
+
+				closePopup: function(){
+					if(this.open){
+						log(this.id + ": close popup due to blur");
+						dijit.popup.close(this.popup);
+						this.open = false;
+					}
+				},
+
+				_onBlur: function(){
+					// summary:
+					//		This is called from focus manager and when we get the signal we
+					//		need to close the drop down
+					this.closePopup();
+				}
+			});
+
+			dojo.declare("SimplePopup",  [dijit._Widget, dijit._TemplatedMixin], {
+				// summary:
+				//		A trivial popup widget
+
+				templateString: "<span>i'm a popup</span>"
+			});
+
+			dojo.declare("SimpleChoiceWidget",  [dijit._Widget, dijit._TemplatedMixin], {
+				// summary:
+				//		A list of values; select a value by pressing an entry in the list.
+
+				choice1: "1",
+				choice2: "2",
+				choice3: "3",
+
+				templateString:
+					"<div class='choice'>" +
+						"<div data-dojo-attach-event='onclick: onClick'>${choice1}</div>" +
+						"<div data-dojo-attach-event='onclick: onClick'>${choice2}</div>" +
+						"<div data-dojo-attach-event='onclick: onClick'>${choice3}</div>" +
+					"</div>",
+
+				onClick: function(e){
+					this.onChange(e.target.innerHTML);
+				},
+
+				onChange: function(val){
+					// summary:
+					//		When this widget is used as a popup, dijit.popup monitors calls
+					//		to onChange and then closes the popup
+					log(this.id + ": selected " + val);
+				}
+			});
+
+			// Create a button that displays a simple drop down
+			choiceDropDown = new SimpleChoiceWidget();
+			(choiceDropDownButton = new SimpleDropDownButton({
+				id: "choiceDropDownButton",
+				label: "show choice drop down",
+				popup: choiceDropDown
+			})).placeAt(dojo.byId("widgets"));
+
+			dojo.declare("DialogWithPopupWidget",  [dijit._Widget, dijit._TemplatedMixin], {
+				// summary:
+				//		This is a dialog that contains a button that spawns a drop down.
+				//		Supply popup as an argument to this widget.
+
+				title: "I'm a dialog",
+				label: "click me",
+
+				templateString:
+					"<div style='width: 300px'>" +
+						"<div>${title}</div>" +
+						"<input><br>" +
+						"<button data-dojo-attach-point='button'>${label}</button><br>" +
+						"<button data-dojo-attach-event='onclick: onExecute'>OK</button>" +
+					"</div>",
+
+				postCreate: function(){
+					// Convert the plain button into a SimpleDropDownButton widget.
+					// Having it be a widget is important because that's how the popup
+					// code knows where a stack of nested popups (typically menus) ends.
+					// (In this case closing a stack of menus shouldn't close the dialog.)
+
+					new SimpleDropDownButton({
+						id: this.id + "PopupButton",
+						label: this.label,
+						popup: this.popup,
+						orient: {'BR': 'BL', 'TR': 'tL'}	// so popup doesn't cover OK button
+					}, this.button);
+				},
+
+				onExecute: function(){
+					// summary:
+					//		Called when OK button is pressed.
+					//		If this is used as a popup this signals to the parent that
+					//		Dialog can be closed.
+					console.log(this.id + ": executed");
+				}
+			});
+
+			// Create a button that displays a dialog that displays a choice widget
+			dialogDropDownButton = new SimpleDropDownButton({
+				id: "showSimpleDialogButton",
+				label: "show dialog",
+				popup: new DialogWithPopupWidget({
+					id: "simpleDialog",
+					label: 'show simple choice drop down',
+					popup: new SimpleChoiceWidget({
+						id: "choiceFromDialog"
+					})
+				})
+			}).placeAt(dojo.byId("widgets"));
+
+			dojo.declare("NestedPopupOpener",  [dijit._Widget, dijit._TemplatedMixin], {
+				// summary:
+				//		Clicking a value in this list will open a nested popup.
+				//		Specify popup1 and popup2 as parameters to this widget.
+
+				templateString:
+					"<div class='choice'>" +
+						"<div data-dojo-attach-event='onclick: onClick'>popup1</div>" +
+						"<div data-dojo-attach-event='onclick: onClick'>popup2</div>" +
+					"</div>",
+
+				onClick: function(e){
+					var id = this.id,
+						popup = this[e.target.innerHTML];
+					log(id + ": opening popup " + popup.id);
+					this.openPopup(popup);
+				},
+
+				openPopup: function(popup){
+					dijit.popup.open({
+						popup: popup,
+						parent: this,
+						around: this.domNode,
+						orient: {'TR': 'TL', 'TL': 'TR'},
+						onCancel: function(){
+							log(id + ": cancel of child " + popup.id);
+						},
+						onExecute: function(){
+							log(id + ": execute of child " + popup.id);
+							dijit.popup.close(popup);
+						}
+					})
+				},
+
+				closePopup: function(popup){
+					dijit.popup.close(popup);
+				}
+			});
+
+			// Create a button that displays a nested drop down.
+			nestedOpener = new NestedPopupOpener({
+				id: 'nestedPopupOpener',
+				popup1: (nestedChoice1 = new SimpleChoiceWidget({
+					id: "nestedChoice1"
+				})),
+				popup2: (nestedChoice2 = new SimpleChoiceWidget({
+					id: "nestedChoice2",
+					choice1: "4",
+					choice2: "5",
+					choice3: "6"
+				}))
+			});
+			nestedDropDownButton = new SimpleDropDownButton({
+				id: "showNestedMenuButton",
+				label: "show nested drop down",
+				popup: nestedOpener
+			}).placeAt(dojo.byId("widgets"));
+
+			// Create a button that displays a dialog that displays a nested drop down
+			dialogNestedChoice1 = new SimpleChoiceWidget({
+				id: "dialogNestedChoice1"
+			});
+			dialogNestedChoice2 = new SimpleChoiceWidget({
+				id: "dialogNestedChoice2",
+				choice1: "4",
+				choice2: "5",
+				choice3: "6"
+			});
+			dialogNestedPopupOpener = new NestedPopupOpener({
+				id: "nestedPopupOpenerFromDialog",
+				popup1: dialogNestedChoice1,
+				popup2: dialogNestedChoice2
+			});
+			dialogWithNestedPopup = new DialogWithPopupWidget({
+				id: "buttonInComplexDialog",
+				label: 'show nested menu',
+				popup: dialogNestedPopupOpener
+			});
+			dialogDropDownButton = new SimpleDropDownButton({
+				id: "showComplexDialogButton",
+				label: "show dialog w/nested menu",
+				popup: dialogWithNestedPopup
+			}).placeAt(dojo.byId("widgets"));
+
+			// For testing, create an unattached widget and unattached DOMNode
+			new SimplePopup({id: "spw"}).placeAt(dojo.body());
+			dojo.place("<span id='sdn'>simple dom node</span>", dojo.body());
+
+			doh.register("API", [
+					function repeatMoveOffScreen(){
+						// Previously, calling moveOffScreen twice would cause an exception
+						dijit.popup.moveOffScreen(dijit.byId("spw"));
+						dijit.popup.moveOffScreen(dijit.byId("spw"));
+
+						// Deprecated API where moveOffScreen() takes a DOMNode
+						dijit.popup.moveOffScreen(dojo.byId("sdn"));
+						dijit.popup.moveOffScreen(dojo.byId("sdn"));
+					}
+			]);
+
+			doh.register("simple open and close", [
+				function initialConditions(t){
+					// If the popup code has cached any iframes, make sure they are hidden
+					dojo.query("iframe").forEach(function(node){
+						console.log("found iframe", node);
+						doh.is("none", node.style.display, "background iframe is hidden");
+					});
+				},
+
+				// Create popup on the edge of another widget
+				function openAround(){
+					var d = new doh.Deferred();
+
+					var around = dojo.global.choiceDropDownButton,
+						popup = dojo.global.choiceDropDown;
+
+					around.openPopup();
+
+					setTimeout(d.getTestCallback(function(){
+						doh.t(isVisible(popup.domNode), "popup is visible");
+
+						if(dojo.isIE <= 6){
+							// Test the BackgroundIFrame
+							var iframes = dojo.query("iframe");
+							doh.is(1, iframes.length, "one background iframe on IE6");
+
+							var popupCoords = dojo.position(popup.domNode),
+								iframeCoords = dojo.position(iframes[0]);
+							doh.is(popupCoords.x, iframeCoords.x, "x is same: " + popupCoords.x);
+							doh.is(popupCoords.y, iframeCoords.y, "y is same: " + popupCoords.y);
+							doh.is(popupCoords.w, iframeCoords.w, "w is same: " + popupCoords.w);
+							doh.is(popupCoords.h, iframeCoords.h, "h is same: " + popupCoords.h);
+							doh.is("", iframes[0].style.display, "not display:none");
+						}
+						// TODO: test stack
+					}), 500);
+
+					return d;
+				},
+
+				function closeAround(){
+					// Close the popup
+					var around = dojo.global.choiceDropDownButton,
+						popup = dojo.global.choiceDropDown;
+
+					around.closePopup();
+
+					// Make sure the popup is hidden
+					doh.is("none", popup.domNode.parentNode.style.display, "popup is hidden");
+				}
+			]);
+
+			doh.register("nested open and close", [
+				// Open first level
+				function openAround(){
+					var d = new doh.Deferred();
+
+					var around = dojo.global.nestedDropDownButton,
+						popup = dojo.global.nestedOpener,
+						nestedPopup = dojo.global.nestedChoice1;
+
+					around.openPopup();
+
+					setTimeout(d.getTestCallback(function(){
+						doh.t(isVisible(popup.domNode), "popup is visible");
+
+						if(dojo.isIE <= 6){
+							// Test the BackgroundIFrame
+							var iframes = dojo.query("iframe", popup.domNode.parentNode);
+							doh.is(1, iframes.length, "one background iframe on IE6");
+
+							var popupCoords = dojo.position(popup.domNode),
+								iframeCoords = dojo.position(iframes[0]);
+							doh.is(popupCoords.x, iframeCoords.x, "x is same: " + popupCoords.x);
+							doh.is(popupCoords.y, iframeCoords.y, "y is same: " + popupCoords.y);
+							doh.is(popupCoords.w, iframeCoords.w, "w is same: " + popupCoords.w);
+							doh.is(popupCoords.h, iframeCoords.h, "h is same: " + popupCoords.h);
+							doh.is("", iframes[0].style.display, "not display:none");
+						}
+						// TODO: test stack
+					}), 500);
+
+					return d;
+				},
+
+				function openNested(){
+					var d = new doh.Deferred();
+
+					var around = dojo.global.nestedDropDownButton,
+						popup = dojo.global.nestedOpener,
+						nestedPopup = dojo.global.nestedChoice1;
+
+					popup.openPopup(nestedPopup);
+
+					setTimeout(d.getTestCallback(function(){
+						doh.t(isVisible(nestedPopup.domNode), "nested popup is visible");
+
+						if(dojo.isIE <= 6){
+							// Test the BackgroundIFrame
+							var iframes = dojo.query("iframe", popup.domNode.parentNode);
+							doh.is(1, iframes.length, "one background iframe for popup");
+
+							iframes = dojo.query("iframe", nestedPopup.domNode.parentNode);
+							doh.is(1, iframes.length, "another background iframe for nested popup");
+
+							var popupCoords = dojo.position(nestedPopup.domNode),
+								iframeCoords = dojo.position(iframes[0]);
+							doh.is(popupCoords.x, iframeCoords.x, "x is same: " + popupCoords.x);
+							doh.is(popupCoords.y, iframeCoords.y, "y is same: " + popupCoords.y);
+							doh.is(popupCoords.w, iframeCoords.w, "w is same: " + popupCoords.w);
+							doh.is(popupCoords.h, iframeCoords.h, "h is same: " + popupCoords.h);
+							doh.is("", iframes[0].style.display, "not display:none");
+						}
+						// TODO: test stack
+					}), 500);
+
+					return d;
+				},
+
+				function closeAround(){
+					// Close the layer of popups
+					var around = dojo.global.nestedDropDownButton,
+						popup = dojo.global.nestedOpener,
+						nestedPopup = dojo.global.nestedChoice1;
+
+					around.closePopup();
+
+					// Make sure the popups are both hidden
+					// (in a future release this might change to display:none etc but currently it's visibility:hidden)
+					doh.is("none", popup.domNode.parentNode.style.display, "popup is hidden");
+					doh.is("none", nestedPopup.domNode.parentNode.style.display, "nested popup is hidden");
+				}
+			]);
+
+			// Make sure there are no hidden tab stops when popups are closed.
+			// This test doesn't work on safari (due to safari bugs) although there aren't any hidden tab stops.
+			doh.register("no hidden tab stops", function hiddenTabStops(){
+				var tabbable = tabOrder();
+				doh.is("inputAtStart", tabbable[0].id, "first tabbable node");
+				doh.is("inputAtEnd", tabbable[tabbable.length - 1].id, "last tabbable node");
+			});
+
+			// TODO: test x/y placement
+
+			// Test that onCancel goes back one level.
+			// Call nestedChoice2.onCancel() and that should trigger nestedChoice2 to close
+			// but nestedOpener stays open.
+			// (TODO)
+
+			// Test that onChange/onExecute goes back to top of popup chain.
+			// Call dialogNestedChoice2.onChange() and that should trigger dialogNestedChoice2
+			// and dialogNestedPopupOpener to close, but not dialogWithNestedPopup.
+			// (TODO)
+
+			// ---------------------
+			// a11y tests
+
+			// Test that ESC key closes one level of a popup chain.
+			// Focus nestedChoice2 and type ESC, and that should trigger nestedChoice2 to close
+			// but nestedOpener stays open.
+			// (TODO)
+
+			// Test that TAB key cancels back to top of popup chain.
+			// Focus nestedChoice2 and type TAB, and that should trigger dialogNestedChoice2
+			// and dialogNestedPopupOpener to close, but not dialogWithNestedPopup.
+			// (TODO)
+
+			doh.run();
+		});
+	</script>
+</head>
+<body>
+	<h1>dijit.popup and BackgroundIFrame Unit Test</h1>
+	<input id="inputAtStart">
+	<span id="widgets"></span>
+	<input id="inputAtEnd">
+</body>
+</html>
diff --git a/dijit/tests/_base/robot/CrossWindow.html b/dijit/tests/_base/robot/CrossWindow.html
index b9fc602..a3b58fd 100644
--- a/dijit/tests/_base/robot/CrossWindow.html
+++ b/dijit/tests/_base/robot/CrossWindow.html
@@ -11,10 +11,9 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_CrossWindow.html');
diff --git a/dijit/tests/_base/robot/FocusManager.html b/dijit/tests/_base/robot/FocusManager.html
index 072f891..7745e14 100644
--- a/dijit/tests/_base/robot/FocusManager.html
+++ b/dijit/tests/_base/robot/FocusManager.html
@@ -1,5 +1,8 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 		"http://www.w3.org/TR/html4/strict.dtd">
+
+<!-- Remove in 2.0, replaced by dijit/tests/focus.html -->
+
 <html>
 	<head>
 		<title>Dijit focus manager DOH Robot test</title>
diff --git a/dijit/tests/_base/robot/focus_mouse.html b/dijit/tests/_base/robot/focus_mouse.html
index 6093863..8105cf7 100644
--- a/dijit/tests/_base/robot/focus_mouse.html
+++ b/dijit/tests/_base/robot/focus_mouse.html
@@ -1,5 +1,8 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 		"http://www.w3.org/TR/html4/strict.dtd">
+
+<!-- Remove in 2.0, replaced by dijit/tests/focus.html -->
+
 <html>
 	<head>
 		<title>Dijit focus manager DOH Robot test</title>
@@ -96,10 +99,7 @@
 
 								// The focus stack should show the ComboBox plus all parent widgets
 								var stack = dojo.global.dijit._activeStack;
-								doh.is(3, stack.length, "3 active widgets in stack");
-								doh.is("form", stack[0], "grandparent of combobox");
-								doh.is("fieldset1", stack[1], "parent of combobox");
-								doh.is("select", stack[2], "combobox itself (last in stack)");
+								doh.is("form, fieldset1, select", stack.join(", "), "combobox stack");
 
 								// _onFocus()/_onBlur was called appropriately
 								doh.f(focusEvents["form"], "form was already focused, no duplicate event");
@@ -133,9 +133,7 @@
 							doh.robot.sequence(d.getTestCallback(function(){
 								// The focus stack should show the Editor plus all parent widgets
 								var stack = dojo.global.dijit._activeStack;
-								doh.is(2, stack.length, "2 active widgets in stack");
-								doh.is("form", stack[0], "parent of editor");
-								doh.is("editor", stack[1], "editor itself (last in stack)");
+								doh.is("form, editor", stack.join(", "), "editor stack");
 
 								// _onFocus()/_onBlur was called appropriately
 								doh.f(focusEvents["form"], "form was already focused, no duplicate event");
@@ -157,29 +155,26 @@
 					// though there's no actual DOM focus event
 					{
 						name: "spinner",
-						timeout: 4000,
+						timeout: 8000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							var upArrow = dojo.query(".dijitSpinner .dijitUpArrowButton")[0];
 							doh.t(upArrow, "found the up arrow");
 
-							doh.robot.mouseMoveAt(upArrow);
+							doh.robot.mouseMoveAt(upArrow, 500);
 							doh.robot.mouseClick({left: true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// The focus stack should show the Spinner plus all parent widgets
 								var stack = dojo.global.dijit._activeStack;
-								doh.is(3, stack.length, "3 active widgets in stack");
-								doh.is("form", stack[0], "grandparent of spinner");
-								doh.is("fieldset2", stack[1], "parent of spinner");
-								doh.is("spinner", stack[2], "spinner itself (last in stack)");
+								doh.is("form, fieldset2, spinner", stack.join(", "), "spinner stack");
 
 								// check watch callbacks
 								doh.f(focusedWatchLog["form"], "grandparent of spinner stayed focused, so no new watch event (watch)");
 								doh.is("focused", focusedWatchLog["fieldset2"], "parent of spinner (watch)");
 								doh.is("focused", focusedWatchLog["spinner"], "spinner (watch)");
-							}), 500);
+							}), 1000);
 
 							return d;
 						}
@@ -204,12 +199,7 @@
 								// The focus stack should show the ComboBox plus all parent widgets
 								var stack = dojo.global.dijit._activeStack;
 								console.log("menu stack is ", stack);
-								doh.is(5, stack.length, "5 active widgets in stack");
-								doh.is("form", stack[0], "grandparent of combobutton");
-								doh.is("fieldset2", stack[1], "parent of combobutton");
-								doh.is("button", stack[2], "combobutton");
-								doh.is("menu", stack[3], "menu");
-								doh.is("mi1", stack[4], "menuitem");
+								doh.is("form, fieldset2, button, menu, mi1", stack.join(", "), "menuitem stack");
 							}), 500);
 
 							return d;
@@ -240,14 +230,8 @@
 								// to the ComboButton, and the rest
 								var stack = dojo.global.dijit._activeStack;
 								console.log("menu stack is ", stack);
-								doh.is(7, stack.length, "7 active widgets in stack");
-								doh.is("form", stack[0], "grandparent of combobutton");
-								doh.is("fieldset2", stack[1], "parent of combobutton");
-								doh.is("button", stack[2], "combobutton");
-								doh.is("menu", stack[3], "menu");
-								doh.is("mi1", stack[4], "menuitem");
-								doh.is("submenu", stack[5], "menu");
-								doh.is("smi1", stack[6], "menuitem");
+								doh.is("form, fieldset2, button, menu, mi1, submenu, smi1", stack.join(", "),
+								 	"submenuitem stack");
 							}), 1000);
 
 							return d;
diff --git a/dijit/tests/_base/robot/popup.html b/dijit/tests/_base/robot/popup.html
deleted file mode 100644
index 4309a5a..0000000
--- a/dijit/tests/_base/robot/popup.html
+++ /dev/null
@@ -1,207 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>doh.robot popup/BackgroundIFrame Test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_popup.html');
-
-				doh.register("API", [
-						function repeatMoveOffScreen(){
-							// Previously, calling moveOffScreen twice would cause an exception
-							dijit.popup.moveOffScreen(dijit.byId("spw"));
-							dijit.popup.moveOffScreen(dijit.byId("spw"));
-
-							// Deprecated API where moveOffScreen() takes a DOMNode
-							dijit.popup.moveOffScreen(dojo.byId("sdn"));
-							dijit.popup.moveOffScreen(dojo.byId("sdn"));
-						}
-				]);
-
-				doh.register("simple open and close", [
-					function initialConditions(t){
-						// If the popup code has cached any iframes, make sure they are hidden
-						dojo.query("iframe").forEach(function(node){
-							console.log("found iframe", node);
-							doh.is("none", node.style.display, "background iframe is hidden");
-						});
-					},
-
-					// Create popup on the edge of another widget
-					function openAround(){
-						var d = new doh.Deferred();
-
-						var around = dojo.global.choiceDropDownButton,
-							popup = dojo.global.choiceDropDown;
-
-						around.openPopup();
-
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.t(isVisible(popup.domNode), "popup is visible");
-
-							if(dojo.isIE <= 6){
-								// Test the BackgroundIFrame
-								var iframes = dojo.query("iframe");
-								doh.is(1, iframes.length, "one background iframe on IE6");
-
-								var popupCoords = dojo.position(popup.domNode),
-									iframeCoords = dojo.position(iframes[0]);
-								doh.is(popupCoords.x, iframeCoords.x, "x is same: " + popupCoords.x);
-								doh.is(popupCoords.y, iframeCoords.y, "y is same: " + popupCoords.y);
-								doh.is(popupCoords.w, iframeCoords.w, "w is same: " + popupCoords.w);
-								doh.is(popupCoords.h, iframeCoords.h, "h is same: " + popupCoords.h);
-								doh.is("", iframes[0].style.display, "not display:none");
-							}
-							// TODO: test stack
-						}), 500);
-
-						return d;
-					},
-
-					function closeAround(){
-						// Close the popup
-						var around = dojo.global.choiceDropDownButton,
-							popup = dojo.global.choiceDropDown;
-
-						around.closePopup();
-
-						// Make sure the popup is hidden
-						doh.is("none", popup.domNode.parentNode.style.display, "popup is hidden");
-					}
-				]);
-
-				doh.register("nested open and close", [
-					// Open first level
-					function openAround(){
-						var d = new doh.Deferred();
-
-						var around = dojo.global.nestedDropDownButton,
-							popup = dojo.global.nestedOpener,
-							nestedPopup = dojo.global.nestedChoice1;
-
-						around.openPopup();
-
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.t(isVisible(popup.domNode), "popup is visible");
-
-							if(dojo.isIE <= 6){
-								// Test the BackgroundIFrame
-								var iframes = dojo.query("iframe", popup.domNode.parentNode);
-								doh.is(1, iframes.length, "one background iframe on IE6");
-
-								var popupCoords = dojo.position(popup.domNode),
-									iframeCoords = dojo.position(iframes[0]);
-								doh.is(popupCoords.x, iframeCoords.x, "x is same: " + popupCoords.x);
-								doh.is(popupCoords.y, iframeCoords.y, "y is same: " + popupCoords.y);
-								doh.is(popupCoords.w, iframeCoords.w, "w is same: " + popupCoords.w);
-								doh.is(popupCoords.h, iframeCoords.h, "h is same: " + popupCoords.h);
-								doh.is("", iframes[0].style.display, "not display:none");
-							}
-							// TODO: test stack
-						}), 500);
-
-						return d;
-					},
-
-					function openNested(){
-						var d = new doh.Deferred();
-
-						var around = dojo.global.nestedDropDownButton,
-							popup = dojo.global.nestedOpener,
-							nestedPopup = dojo.global.nestedChoice1;
-
-						popup.openPopup(nestedPopup);
-
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.t(isVisible(nestedPopup.domNode), "nested popup is visible");
-
-							if(dojo.isIE <= 6){
-								// Test the BackgroundIFrame
-								var iframes = dojo.query("iframe", popup.domNode.parentNode);
-								doh.is(1, iframes.length, "one background iframe for popup");
-
-								iframes = dojo.query("iframe", nestedPopup.domNode.parentNode);
-								doh.is(1, iframes.length, "another background iframe for nested popup");
-
-								var popupCoords = dojo.position(nestedPopup.domNode),
-									iframeCoords = dojo.position(iframes[0]);
-								doh.is(popupCoords.x, iframeCoords.x, "x is same: " + popupCoords.x);
-								doh.is(popupCoords.y, iframeCoords.y, "y is same: " + popupCoords.y);
-								doh.is(popupCoords.w, iframeCoords.w, "w is same: " + popupCoords.w);
-								doh.is(popupCoords.h, iframeCoords.h, "h is same: " + popupCoords.h);
-								doh.is("", iframes[0].style.display, "not display:none");
-							}
-							// TODO: test stack
-						}), 500);
-
-						return d;
-					},
-
-					function closeAround(){
-						// Close the layer of popups
-						var around = dojo.global.nestedDropDownButton,
-							popup = dojo.global.nestedOpener,
-							nestedPopup = dojo.global.nestedChoice1;
-
-						around.closePopup();
-
-						// Make sure the popups are both hidden
-						// (in a future release this might change to display:none etc but currently it's visibility:hidden)
-						doh.is("none", popup.domNode.parentNode.style.display, "popup is hidden");
-						doh.is("none", nestedPopup.domNode.parentNode.style.display, "nested popup is hidden");
-					}
-				]);
-
-				// Make sure there are no hidden tab stops when popups are closed.
-				// This test doesn't work on safari (due to safari bugs) although there aren't any hidden tab stops.
-				doh.register("no hidden tab stops", function hiddenTabStops(){
-					var tabbable = tabOrder();
-					doh.is("inputAtStart", tabbable[0].id, "first tabbable node");
-					doh.is("inputAtEnd", tabbable[tabbable.length - 1].id, "last tabbable node");
-				});
-
-				// TODO: test x/y placement
-
-				// Test that onCancel goes back one level.
-				// Call nestedChoice2.onCancel() and that should trigger nestedChoice2 to close
-				// but nestedOpener stays open.
-				// (TODO)
-
-				// Test that onChange/onExecute goes back to top of popup chain.
-				// Call dialogNestedChoice2.onChange() and that should trigger dialogNestedChoice2
-				// and dialogNestedPopupOpener to close, but not dialogWithNestedPopup.
-				// (TODO)
-
-				// ---------------------
-				// a11y tests
-
-				// Test that ESC key closes one level of a popup chain.
-				// Focus nestedChoice2 and type ESC, and that should trigger nestedChoice2 to close
-				// but nestedOpener stays open.
-				// (TODO)
-
-				// Test that TAB key cancels back to top of popup chain.
-				// Focus nestedChoice2 and type TAB, and that should trigger dialogNestedChoice2
-				// and dialogNestedPopupOpener to close, but not dialogWithNestedPopup.
-				// (TODO)
-
-				doh.run();
-			});
-		</script>
-	</head>
-</html>
diff --git a/dijit/tests/_base/robot/typematic.html b/dijit/tests/_base/robot/typematic.html
deleted file mode 100644
index f18d371..0000000
--- a/dijit/tests/_base/robot/typematic.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>typematic DOH Robot test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_typematic.html');
-
-				doh.register("press and hold test", [
-					{
-						name: "keyboard",
-						timeout: 9000,
-						runTest: function(){
-							var
-								d = new doh.Deferred(),
-								input = dojo.byId("typematicInput"),
-								v;
-							input.value = "";
-							input.focus();
-
-							doh.robot.keyDown(dojo.keys.CTRL, 1000);
-							doh.robot.keyDown(dojo.keys.F11, 200);
-							doh.robot.sequence(function(){
-								v = input.value; // get value before releasing key to reduce timing dependence on the robot
-							}, 2000);
-							doh.robot.keyUp(dojo.keys.F11, 100);
-							doh.robot.keyUp(dojo.keys.CTRL, 100);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								// allow off by 1
-								doh.t(v=="aaaaaaaaa"||v=="aaaaaaaaaa"||v=="aaaaaaaaaaa", "a letters typed " + v);
-							}), 100);
-
-							return d;
-						}
-					},
-					{
-						name: "mouse",
-						timeout: 5000,
-						runTest: function(){
-							var
-								d = new doh.Deferred(),
-								input = dojo.byId("typematicInput"),
-								v;
-							input.value = "";
-
-							doh.robot.mouseMoveAt("typematicButton", 500, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.sequence(function(){
-								v = input.value; // get value before releasing button to reduce timing dependence on the robot
-							}, 1000);
-							doh.robot.mouseRelease({left: true}, 100);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								// allow off by 1
-								doh.t(v=="bbbbbb"||v=="bbbbbbb"||v=="bbbbbbbb", "b letters typed " + v);
-							}), 100);
-
-							return d;
-						}
-					}
-				]);
-
-				doh.run();
-			});
-		</script>
-	</head>
-</html>
diff --git a/dijit/tests/_base/tabindex.html b/dijit/tests/_base/tabindex.html
deleted file mode 100644
index c102995..0000000
--- a/dijit/tests/_base/tabindex.html
+++ /dev/null
@@ -1,296 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>Dijit tabindex related functions unit test</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-		@import "../../themes/claro/claro.css";
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojo.parser");
-		dojo.require("dijit.dijit");
-		dojo.require("dijit.Editor");
-
-		dojo.ready(function(){
-			doh.register("parse", function(){
-				dojo.parser.parse();
-			});
-
-			doh.register("dijit.tabindex",
-				[
-					function isTabNavigable(t){
-						var d = new doh.Deferred();
-						t.t(dijit.isTabNavigable(dojo.byId("a-with-href")), "a-with-href");
-						t.f(dijit.isTabNavigable(dojo.byId("a-without-href")), "a-without-href");
-						t.t(dijit.isTabNavigable(dojo.byId("area")), "area");
-						t.t(dijit.isTabNavigable(dojo.byId("button")), "button");
-						t.t(dijit.isTabNavigable(dojo.byId("input")), "input");
-						t.t(dijit.isTabNavigable(dojo.byId("object")), "object");
-						t.t(dijit.isTabNavigable(dojo.byId("select")), "select");
-						t.t(dijit.isTabNavigable(dojo.byId("textarea")), "textarea");
-						t.f(dijit.isTabNavigable(dojo.byId("empty")), "empty");
-						t.t(dijit.isTabNavigable(dojo.byId("zero-tabindex-div")), "zero-tabindex-div");
-						t.f(dijit.isTabNavigable(dojo.byId("no-tabindex-div")), "no-tabindex-div");
-						t.f(dijit.isTabNavigable(dojo.byId("iframe")), "iframe");
-
-						dijit.byId("editor").onLoadDeferred.addCallback(d.getTestCallback(function(){
-							t.t(dijit.isTabNavigable(dojo.byId("editor_iframe")), "editor_iframe");
-						}));
-
-						return d;
-					},
-					function findTabNullOnEmpty(t){
-						t.is(null, dijit.getFirstInTabbingOrder("empty"));
-						t.is(null, dijit.getLastInTabbingOrder("empty"));
-					},
-					function findTabElements(t){
-						t.is(null, dijit.getFirstInTabbingOrder("div-container"));
-						t.is(null, dijit.getFirstInTabbingOrder("a-without-href-container"));
-						t.is("a-with-href", dijit.getFirstInTabbingOrder("a-with-href-container").id);
-
-						// in WebKit area elements are not in the tab order
-						// and their display style property is "none";
-						// therefore it is expected that this test will fail
-						if(!dojo.isWebKit){
-							// TODO: failing on FF3.0/mac; I think there's a race condition waiting
-							// for the image to load
-							t.is("area", dijit.getFirstInTabbingOrder("area-map").id);
-						}
-
-						t.is("button", dijit.getFirstInTabbingOrder("button-container").id);
-						t.is("input", dijit.getFirstInTabbingOrder("input-container").id);
-						t.is("object", dijit.getFirstInTabbingOrder("object-container").id);
-						t.is("select", dijit.getFirstInTabbingOrder("select-container").id);
-						t.is("textarea", dijit.getFirstInTabbingOrder("textarea-container").id);
-						t.is(null, dijit.getLastInTabbingOrder("div-container"));
-						t.is(null, dijit.getLastInTabbingOrder("a-without-href-container"));
-						t.is("a-with-href", dijit.getLastInTabbingOrder("a-with-href-container").id);
-
-						// in WebKit area elements are not in the tab order
-						// and their display style property is "none";
-						// therefore it is expected that this test will fail
-						if(!dojo.isWebKit){
-							t.is("area", dijit.getLastInTabbingOrder("area-map").id);
-						}
-
-						t.is("button", dijit.getLastInTabbingOrder("button-container").id);
-						t.is("input", dijit.getLastInTabbingOrder("input-container").id);
-						t.is("object", dijit.getLastInTabbingOrder("object-container").id);
-						t.is("select", dijit.getLastInTabbingOrder("select-container").id);
-						t.is("textarea", dijit.getLastInTabbingOrder("textarea-container").id);
-					},
-					function findTabOnElementRatherThanString(t){
-						t.is("a-with-href", dijit.getFirstInTabbingOrder(dojo.byId("a-with-href-container")).id);
-						t.is("a-with-href", dijit.getLastInTabbingOrder(dojo.byId("a-with-href-container")).id);
-					},
-					function findTabSkipDisabled(t){
-						t.is("not-disabled-input", dijit.getFirstInTabbingOrder("skip-disabled").id);
-						t.is("not-disabled-input", dijit.getLastInTabbingOrder("skip-disabled").id);
-					},
-					function findTabZeroTabindex(t){
-						t.is("zero-tabindex-div", dijit.getFirstInTabbingOrder("zero-tabindex-div-container").id);
-						t.is("zero-tabindex-input", dijit.getFirstInTabbingOrder("zero-tabindex-input-container").id);
-						t.is("zero-tabindex-div", dijit.getLastInTabbingOrder("zero-tabindex-div-container").id);
-						t.is("zero-tabindex-input", dijit.getLastInTabbingOrder("zero-tabindex-input-container").id);
-					},
-					function findTabPositiveTabindex(t){
-						t.is("positive-tabindex-input1a", dijit.getFirstInTabbingOrder("positive-tabindex-mixed-with-no-tabindex").id);
-						t.is("positive-tabindex-input3a", dijit.getFirstInTabbingOrder("positive-tabindex").id);
-						t.is("no-tabindex-input2", dijit.getLastInTabbingOrder("positive-tabindex-mixed-with-no-tabindex").id);
-						t.is("positive-tabindex-input4b", dijit.getLastInTabbingOrder("positive-tabindex").id);
-					},
-					function findTabSkipMinusOneTabindex(t){
-						t.is("not-minus-one-input", dijit.getFirstInTabbingOrder("skip-minus-one").id);
-						t.is("not-minus-one-input", dijit.getLastInTabbingOrder("skip-minus-one").id);
-					},
-					function findTabDescend(t){
-						t.is("child-input1", dijit.getFirstInTabbingOrder("descend").id);
-						t.is("child-input2", dijit.getLastInTabbingOrder("descend").id);
-					},
-					function findTabOuterInner(t){
-						t.is("outer1", dijit.getFirstInTabbingOrder("outer-inner-container").id);
-						t.is("inner2", dijit.getLastInTabbingOrder("outer-inner-container").id);
-					},
-					function skipNotShown(t){
-						t.is(null, dijit.getFirstInTabbingOrder("hidden-element-container"));
-						t.is(null, dijit.getFirstInTabbingOrder("hidden-container-tabindex-zero"));
-						t.is(null, dijit.getFirstInTabbingOrder("hidden-container-no-tabindex"));
-						t.is(null, dijit.getFirstInTabbingOrder("container-with-hidden-containers"));
-
-						t.is(null, dijit.getFirstInTabbingOrder("display-none-element-container"));
-						t.is(null, dijit.getFirstInTabbingOrder("display-none-container-tabindex-zero"));
-						t.is(null, dijit.getFirstInTabbingOrder("display-none-container-no-tabindex"));
-						t.is(null, dijit.getFirstInTabbingOrder("container-with-display-none-containers"));
-					}
-				]
-			);
-
-			doh.run();
-		});
-
-	</script>
-</head>
-<body class="claro">
-	<h1>Dijit TabIndex Related Functions Unit Test</h1>
-
-	<div id="empty"></div>
-
-	<div id="div-container">
-		<div id="div"></div>
-	</div>
-	<div id="a-without-href-container">
-		<a id="a-without-href"></a>
-	</div>
-	<div id="a-with-href-container">
-		<a id="a-with-href" href="#a-without-href"></a>
-	</div>
-
-	<div><img src="../images/flatScreen.gif" alt="picture of a flat-screen monitor" usemap="#area-map"/></div>
-	<map id="area-map" name="area-map">
-		<area id="area" href="#" alt="example area" shape="rect" coords="0,0,8,8"/>
-	</map>
-
-	<div id="button-container">
-		<button id="button"></button>
-	</div>
-	<div id="input-container">
-		<input id="input"/>
-	</div>
-	<div id="object-container">
-		<object id="object" type="text/javascript"></object>
-	</div>
-	<div id="select-container">
-		<select id="select"></select>
-	</div>
-	<div id="textarea-container">
-		<textarea id="textarea"></textarea>
-	</div>
-
-	<div id="skip-disabled">
-		<input id="disabled-input1" disabled="disabled"/>
-		<input id="not-disabled-input"/>
-		<input id="disabled-input2" disabled="disabled"/>
-	</div>
-
-	<div id="zero-tabindex-div-container">
-		<div id="zero-tabindex-div" tabindex="0"></div>
-	</div>
-
-	<div id="no-tabindex-div-container">
-		<div id="no-tabindex-div"></div>
-	</div>
-
-	<div id="zero-tabindex-input-container">
-		<input id="zero-tabindex-input" tabindex="0"/>
-	</div>
-
-	<div id="iframe-container">
-		<div id="iframe"></div>
-	</div>
-
-	<div id="editor-container">
-		<div id="editor" data-dojo-type="dijit.Editor"></div>
-	</div>
-
-	<div id="positive-tabindex-mixed-with-no-tabindex">
-		<input id="no-tabindex-input1"/>
-		<input id="no-tabindex-input2"/>
-		<input id="positive-tabindex-input1a" tabindex="1"/>
-		<input id="positive-tabindex-input1b" tabindex="1"/>
-		<input id="positive-tabindex-input2a" tabindex="2"/>
-		<input id="positive-tabindex-input2b" tabindex="2"/>
-	</div>
-
-	<div id="positive-tabindex">
-		<input id="positive-tabindex-input3a" tabindex="3"/>
-		<input id="positive-tabindex-input3b" tabindex="3"/>
-		<input id="positive-tabindex-input4a" tabindex="4"/>
-		<input id="positive-tabindex-input4b" tabindex="4"/>
-	</div>
-
-	<div id="skip-minus-one">
-		<input id="minus-one-input1" tabindex="-1"/>
-		<input id="not-minus-one-input"/>
-		<input id="minus-one-input2" tabindex="-1"/>
-	</div>
-
-	<div id="descend">
-		<input disabled="disabled"/>
-		<div>
-			<input disabled="disabled"/>
-			<div>
-				<input disabled="disabled"/>
-			</div>
-		</div>
-		<div>
-			<input disabled="disabled"/>
-			<div>
-				<input disabled="disabled"/>
-			</div>
-			<div>
-				<input id="child-input1"/>
-			</div>
-			<div>
-				<input id="child-input2"/>
-			</div>
-		</div>
-		<div>
-			<div>
-				<input disabled="disabled"/>
-			</div>
-			<input disabled="disabled"/>
-		</div>
-		<input disabled="disabled"/>
-	</div>
-
-	<div id="outer-inner-container">
-		<div id="outer1" tabindex="0">
-			<div id="inner1" tabindex="0"></div>
-		</div>
-		<div id="outer2" tabindex="0">
-			<div id="inner2" tabindex="0"></div>
-		</div>
-	</div>
-
-	<div id="hidden-element-container">
-		<div id="hidden-element" tabindex="0" style="visibility: hidden;">
-		</div>
-	</div>
-
-	<div id="container-with-hidden-containers">
-		<div id="hidden-container-tabindex-zero" tabindex="0" style="visibility: hidden;">
-			<div id="inside-hidden-container-tabindex-zero" tabindex="0">
-			</div>
-		</div>
-
-		<div id="hidden-container-no-tabindex" style="visibility: hidden;">
-			<div id="inside-hidden-container-no-tabindex" tabindex="0">
-			</div>
-		</div>
-	</div>
-
-	<div id="display-none-element-container">
-		<div id="display-none-element" tabindex="0" style="display: none;">
-		</div>
-	</div>
-
-	<div id="container-with-display-none-containers">
-		<div id="display-none-container-tabindex-zero" tabindex="0" style="display: none;">
-			<div id="inside-display-none-container-tabindex-zero" tabindex="0">
-			</div>
-		</div>
-
-		<div id="display-none-container-no-tabindex" style="display: none;">
-			<div id="inside-display-none-container-no-tabindex" tabindex="0">
-			</div>
-		</div>
-	</div>
-</body>
-</html>
diff --git a/dijit/tests/_base/test_CrossWindow.html b/dijit/tests/_base/test_CrossWindow.html
index 035db11..caf9c31 100644
--- a/dijit/tests/_base/test_CrossWindow.html
+++ b/dijit/tests/_base/test_CrossWindow.html
@@ -10,7 +10,7 @@
 		</style>
 		<script type="text/javascript"
 			src="../../../dojo/dojo.js"
-			djConfig="isDebug:true, popup:false, parseOnLoad:false">
+			data-dojo-config="isDebug:true, popup:false, parseOnLoad:false">
 		</script>
 		<script type="text/javascript">
 
@@ -23,7 +23,7 @@
 			var widgetClass;
 			var popwin;
 			var globalDocument;
-			var mainwin = this;
+			var mainwin = window;
 
 			onPopClose = function(){
 				console.log("setting context back to main window...");
diff --git a/dijit/tests/_base/test_FocusManager.html b/dijit/tests/_base/test_FocusManager.html
index 5fdf59f..8c827ae 100644
--- a/dijit/tests/_base/test_FocusManager.html
+++ b/dijit/tests/_base/test_FocusManager.html
@@ -1,5 +1,8 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 		"http://www.w3.org/TR/html4/strict.dtd">
+
+<!-- Remove in 2.0, replaced by dijit/tests/focus.html -->
+
 <html>
 <head>
 	<title>dijit.focus Test</title>
@@ -10,7 +13,7 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.focus");		// dijit.focus()
 		dojo.require("dijit._base.focus");	// dijit.getFocus()
diff --git a/dijit/tests/_base/test_focusWidget.html b/dijit/tests/_base/test_focusWidget.html
index 300204b..1b0281f 100644
--- a/dijit/tests/_base/test_focusWidget.html
+++ b/dijit/tests/_base/test_focusWidget.html
@@ -1,4 +1,7 @@
 <!DOCTYPE html>
+
+<!-- Remove in 2.0, replaced by dijit/tests/focus.html -->
+
 <html>
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
@@ -105,13 +108,13 @@
 	</p>
 
 	<label>a form ContentPane widget:</label><br>
-	<form id="form" data-dojo-type="dijit.layout.ContentPane" >
+	<form id="form" data-dojo-type="dijit/layout/ContentPane" >
 		<label for="first">simple input: </label><input id="first"/><br>
 
 		<label>a fieldset ContentPane widget:</label><br>
-		<fieldset id=fieldset1 data-dojo-type="dijit.layout.ContentPane">
+		<fieldset id=fieldset1 data-dojo-type="dijit/layout/ContentPane">
 			<label for="select">a ComboBox widget:</label>
-			<select id=select data-dojo-type="dijit.form.ComboBox">
+			<select id=select data-dojo-type="dijit/form/ComboBox">
 				<option>this</option>
 				<option>is</option>
 				<option>a</option>
@@ -120,32 +123,32 @@
 			<label for="plain">a plain input:</label>
 			<input id=plain value=plain/>
 		</fieldset>
-		<div id=editor data-dojo-type="dijit.Editor" >
+		<div id=editor data-dojo-type="dijit/Editor" >
 			Hello world, this is an <i>editor</i>
 		</div>
 		<br>
 		<label>another fieldset ContentPane:</label><br>
-		<fieldset id=fieldset2 data-dojo-type="dijit.layout.ContentPane">
+		<fieldset id=fieldset2 data-dojo-type="dijit/layout/ContentPane">
 			<label for="date">a DateTextBox widget:</label>
-			<input id=date data-dojo-type="dijit.form.DateTextBox"/><br>
+			<input id=date data-dojo-type="dijit/form/DateTextBox"/><br>
 
 			<label for="textarea">a plain textarea:</label><br>
 			<textarea id=textarea>hello there!</textarea><br>
 
 			<label for="spinner">a Spinner widget:</label>
-			<input id=spinner data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='value:100'/><br>
+			<input id=spinner data-dojo-type="dijit/form/NumberSpinner" data-dojo-props='value:100'/><br>
 
 			<label>a Combobutton widget:</label>
-			<div id=button data-dojo-type="dijit.form.ComboButton" data-dojo-props='tabIndex:"0"'>
+			<div id=button data-dojo-type="dijit/form/ComboButton" data-dojo-props='tabIndex:"0"'>
 				<span>push me</span>
-				<div id=menu data-dojo-type="dijit.Menu">
-					<div id=mi1 data-dojo-type="dijit.MenuItem">menu item 1</div>
-					<div id=mi2 data-dojo-type="dijit.MenuItem">menu item 2</div>
-					<div id=popupMenuItem data-dojo-type="dijit.PopupMenuItem">
+				<div id=menu data-dojo-type="dijit/Menu">
+					<div id=mi1 data-dojo-type="dijit/MenuItem">menu item 1</div>
+					<div id=mi2 data-dojo-type="dijit/MenuItem">menu item 2</div>
+					<div id=popupMenuItem data-dojo-type="dijit/PopupMenuItem">
 						<span>submenu</span>
-						<div id=submenu data-dojo-type="dijit.Menu">
-							<div id=smi1 data-dojo-type="dijit.MenuItem">submenu item 1</div>
-							<div id=smi2 data-dojo-type="dijit.MenuItem">submenu item 2</div>
+						<div id=submenu data-dojo-type="dijit/Menu">
+							<div id=smi1 data-dojo-type="dijit/MenuItem">submenu item 1</div>
+							<div id=smi2 data-dojo-type="dijit/MenuItem">submenu item 2</div>
 						</div>
 					</div>
 				</div>
diff --git a/dijit/tests/_base/test_popup.html b/dijit/tests/_base/test_popup.html
deleted file mode 100644
index b366135..0000000
--- a/dijit/tests/_base/test_popup.html
+++ /dev/null
@@ -1,283 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>Dijit.popup and BackgroundIFrame unit test</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../../themes/dijit.css";
-		@import "../css/dijitTests.css";
-
-		body {
-			height: 100%;
-			padding: 0;
-			margin: 0;
-		}
-
-		div {
-			background: white;
-			border: solid 1px gray;
-		}
-
-		/* the menu type test widgets */
-		.choice div {
-			width: 200px;
-			cursor: pointer;
-		}
-		.choice div:hover {
-			background: #ccc;
-		}
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: false"></script>
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<script type="text/javascript">
-		dojo.require("dijit._base.popup");
-		dojo.require("dijit._Widget");
-		dojo.require("dijit._TemplatedMixin");
-
-		function log(str){
-			console.log(str);
-		}
-
-		dojo.ready(function(){
-
-			dojo.declare("SimpleDropDownButton", [dijit._Widget, dijit._TemplatedMixin], {
-				// summary:
-				//		A button that shows a popup.
-				//		Supply popup as parameter when instantiating this widget.
-
-				label: "show popup",
-				orient: {'BL': 'TL', 'BR': 'TR'},
-
-				templateString: "<button data-dojo-attach-event='onclick: openPopup'>${label}</button>",
-
-				openPopup: function(){
-					var self = this;
-
-					dijit.popup.open({
-						popup: this.popup,
-						parent: this,
-						around: this.domNode,
-						orient: this.orient,
-						onCancel: function(){
-							log(self.id + ": cancel of child");
-						},
-						onExecute: function(){
-							log(self.id + ": execute of child");
-							dijit.popup.close(self.popup);
-							self.open = false;
-						}
-					});
-
-					this.open = true;
-				},
-
-				closePopup: function(){
-					if(this.open){
-						log(this.id + ": close popup due to blur");
-						dijit.popup.close(this.popup);
-						this.open = false;
-					}
-				},
-
-				_onBlur: function(){
-					// summary:
-					//		This is called from focus manager and when we get the signal we
-					//		need to close the drop down
-					this.closePopup();
-				}
-			});
-
-			dojo.declare("SimplePopup",  [dijit._Widget, dijit._TemplatedMixin], {
-				// summary:
-				//		A trivial popup widget
-
-				templateString: "<span>i'm a popup</span>"
-			});
-
-			dojo.declare("SimpleChoiceWidget",  [dijit._Widget, dijit._TemplatedMixin], {
-				// summary:
-				//		A list of values; select a value by pressing an entry in the list.
-
-				choice1: "1",
-				choice2: "2",
-				choice3: "3",
-
-				templateString:
-					"<div class='choice'>" +
-						"<div data-dojo-attach-event='onclick: onClick'>${choice1}</div>" +
-						"<div data-dojo-attach-event='onclick: onClick'>${choice2}</div>" +
-						"<div data-dojo-attach-event='onclick: onClick'>${choice3}</div>" +
-					"</div>",
-
-				onClick: function(e){
-					this.onChange(e.target.innerHTML);
-				},
-
-				onChange: function(val){
-					// summary:
-					//		When this widget is used as a popup, dijit.popup monitors calls
-					//		to onChange and then closes the popup
-					log(this.id + ": selected " + val);
-				}
-			});
-
-			// Create a button that displays a simple drop down
-			choiceDropDown = new SimpleChoiceWidget();
-			(choiceDropDownButton = new SimpleDropDownButton({
-				id: "choiceDropDownButton",
-				label: "show choice drop down",
-				popup: choiceDropDown
-			})).placeAt(dojo.byId("widgets"));
-
-			dojo.declare("DialogWithPopupWidget",  [dijit._Widget, dijit._TemplatedMixin], {
-				// summary:
-				//		This is a dialog that contains a button that spawns a drop down.
-				//		Supply popup as an argument to this widget.
-
-				title: "I'm a dialog",
-				label: "click me",
-
-				templateString:
-					"<div style='width: 300px'>" +
-						"<div>${title}</div>" +
-						"<input><br>" +
-						"<button data-dojo-attach-point='button'>${label}</button><br>" +
-						"<button data-dojo-attach-event='onclick: onExecute'>OK</button>" +
-					"</div>",
-
-				postCreate: function(){
-					// Convert the plain button into a SimpleDropDownButton widget.
-					// Having it be a widget is important because that's how the popup
-					// code knows where a stack of nested popups (typically menus) ends.
-					// (In this case closing a stack of menus shouldn't close the dialog.)
-
-					new SimpleDropDownButton({
-						id: this.id + "PopupButton",
-						label: this.label,
-						popup: this.popup,
-						orient: {'BR': 'BL', 'TR': 'tL'}	// so popup doesn't cover OK button
-					}, this.button);
-				},
-
-				onExecute: function(){
-					// summary:
-					//		Called when OK button is pressed.
-					//		If this is used as a popup this signals to the parent that
-					//		Dialog can be closed.
-					console.log(this.id + ": executed");
-				}
-			});
-
-			// Create a button that displays a dialog that displays a choice widget
-			dialogDropDownButton = new SimpleDropDownButton({
-				id: "showSimpleDialogButton",
-				label: "show dialog",
-				popup: new DialogWithPopupWidget({
-					id: "simpleDialog",
-					label: 'show simple choice drop down',
-					popup: new SimpleChoiceWidget({
-						id: "choiceFromDialog"
-					})
-				})
-			}).placeAt(dojo.byId("widgets"));
-
-			dojo.declare("NestedPopupOpener",  [dijit._Widget, dijit._TemplatedMixin], {
-				// summary:
-				//		Clicking a value in this list will open a nested popup.
-				//		Specify popup1 and popup2 as parameters to this widget.
-
-				templateString:
-					"<div class='choice'>" +
-						"<div data-dojo-attach-event='onclick: onClick'>popup1</div>" +
-						"<div data-dojo-attach-event='onclick: onClick'>popup2</div>" +
-					"</div>",
-
-				onClick: function(e){
-					var id = this.id,
-						popup = this[e.target.innerHTML];
-					log(id + ": opening popup " + popup.id);
-					this.openPopup(popup);
-				},
-
-				openPopup: function(popup){
-					dijit.popup.open({
-						popup: popup,
-						parent: this,
-						around: this.domNode,
-						orient: {'TR': 'TL', 'TL': 'TR'},
-						onCancel: function(){
-							log(id + ": cancel of child " + popup.id);
-						},
-						onExecute: function(){
-							log(id + ": execute of child " + popup.id);
-							dijit.popup.close(popup);
-						}
-					})
-				},
-
-				closePopup: function(popup){
-					dijit.popup.close(popup);
-				}
-			});
-
-			// Create a button that displays a nested drop down.
-			nestedOpener = new NestedPopupOpener({
-				id: 'nestedPopupOpener',
-				popup1: (nestedChoice1 = new SimpleChoiceWidget({
-					id: "nestedChoice1"
-				})),
-				popup2: (nestedChoice2 = new SimpleChoiceWidget({
-					id: "nestedChoice2",
-					choice1: "4",
-					choice2: "5",
-					choice3: "6"
-				}))
-			});
-			nestedDropDownButton = new SimpleDropDownButton({
-				id: "showNestedMenuButton",
-				label: "show nested drop down",
-				popup: nestedOpener
-			}).placeAt(dojo.byId("widgets"));
-
-			// Create a button that displays a dialog that displays a nested drop down
-			dialogNestedChoice1 = new SimpleChoiceWidget({
-				id: "dialogNestedChoice1"
-			});
-			dialogNestedChoice2 = new SimpleChoiceWidget({
-				id: "dialogNestedChoice2",
-				choice1: "4",
-				choice2: "5",
-				choice3: "6"
-			});
-			dialogNestedPopupOpener = new NestedPopupOpener({
-				id: "nestedPopupOpenerFromDialog",
-				popup1: dialogNestedChoice1,
-				popup2: dialogNestedChoice2
-			});
-			dialogWithNestedPopup = new DialogWithPopupWidget({
-				id: "buttonInComplexDialog",
-				label: 'show nested menu',
-				popup: dialogNestedPopupOpener
-			});
-			dialogDropDownButton = new SimpleDropDownButton({
-				id: "showComplexDialogButton",
-				label: "show dialog w/nested menu",
-				popup: dialogWithNestedPopup
-			}).placeAt(dojo.byId("widgets"));
-
-			// To help the robot code, create an unattached widget and unattached DOMNode
-			new SimplePopup({id: "spw"}).placeAt(dojo.body());
-			dojo.place("<span id='sdn'>simple dom node</span>", dojo.body());
-		});
-	</script>
-</head>
-<body>
-	<h1>dijit.popup and BackgroundIFrame Unit Test</h1>
-	<input id="inputAtStart">
-	<span id="widgets"></span>
-	<input id="inputAtEnd">
-</body>
-</html>
diff --git a/dijit/tests/_base/test_typematic.html b/dijit/tests/_base/test_typematic.html
deleted file mode 100644
index bbbc477..0000000
--- a/dijit/tests/_base/test_typematic.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>Typematic Test</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../../themes/claro/claro.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
-	<script type="text/javascript">
-		dojo.require("dijit.typematic");
-
-		var lastCount = 0;
-		function typematicCallBack(count, node, evt){
-			var inputNode = dojo.byId('typematicInput');
-			if(node == inputNode){
-				key = "a";
-			}else{
-				key = "b";
-			}
-			if(-1 == count){
-				console.debug((lastCount+1) + ' ' + key + ' events');
-			}else{
-				lastCount = count;
-				inputNode.value += key;
-			}
-				inputNode.focus();
-		}
-		dojo.ready(function(){
-			var keyNode = dojo.byId('typematicInput');
-			var mouseNode = dojo.byId('typematicButton');
-			dijit.typematic.addKeyListener(keyNode,
-				{
-					charOrCode:dojo.keys.F11,
-					shiftKey:false,
-					metaKey:false,
-					ctrlKey:true // ALT is optional since its unspecified
-				},
-				this, typematicCallBack, 200, 200);
-			dijit.typematic.addMouseListener(mouseNode,
-				this, typematicCallBack, 0.9, 200);
-
-			try {
-				// Focus the input so it's easier for user to start typing.
-				// Doesn't work well in IE6 though, when this test is loaded from robot/typematic.html,
-				// Apparently the robot code sets up a cover <div> over this page and IE doesn't want to focus
-				// the input since it's hidden.
-				keyNode.focus();
-			}catch(e){}
-		});
-	</script>
-</head>
-<body class="claro">
-
-	<h2>Dijit typematic tests</h2>
-	Press and hold the <b>ctrl+F11</b> keys (ALT optional, but not Shift or Meta) to see a's typed (constant rate) in the input field,<br>
-	or left-mouse click the button and hold down to see b's typed (increasing rate) in the input field.<br>
-	<input id="typematicInput" size="500"><button id="typematicButton">to B or not to B</button>
-
-</body>
-</html>
diff --git a/dijit/tests/_base/wai.html b/dijit/tests/_base/wai.html
index 83a1720..0389b39 100644
--- a/dijit/tests/_base/wai.html
+++ b/dijit/tests/_base/wai.html
@@ -2,7 +2,7 @@
 <head>
 	<title>Dijit wai unit test</title>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 		dojo.require("doh.runner");
 		dojo.require("dijit.dijit");
diff --git a/dijit/tests/_data/SlowStore.js b/dijit/tests/_data/SlowStore.js
index c304d9d..966b63b 100644
--- a/dijit/tests/_data/SlowStore.js
+++ b/dijit/tests/_data/SlowStore.js
@@ -1,90 +1,89 @@
-dojo.provide("dijit.tests._data.SlowStore");
+define(["dojo/_base/declare", "dojo/data/ItemFileReadStore"], function(declare, ItemFileReadStore){
 
-dojo.require("dojo.data.ItemFileReadStore");
+	return declare("dijit.tests._data.SlowStore", ItemFileReadStore, {
+		// summary:
+		//		This wrapper decorates an ItemFileReadStore by delaying queries issued according to the
+		//		length of the query:
+		//
+		//		- empty query: 2000ms,
+		//		- 1 or 2 characters: 1000ms,
+		//		- 3 characters: 500ms,
+		//		- 4 or more characters: 100ms.
 
-dojo.declare("dijit.tests._data.SlowStore", dojo.data.ItemFileReadStore, {
-	// summary:
-	//		This wrapper decorates an ItemFileReadStorere by delaying queries issued according to the
-	//		length of the query:
-	//
-	//			empty query: 2000ms,
-	//			1 or 2 characters: 1000ms,
-	//			3 characters: 500ms,
-	//			4 or more characters: 100ms.
-	//
+		constructor: function(){
+			this.log = [];
+		},
 
-	constructor: function(){
-		this.log = [];
-	},
-
-	fetch: function(/* Object */ keywordArgs){
-		// Get the query phrase (store into first), and the # of chars it has
-		var count = 0;
-		var first;
-		if("query" in keywordArgs){
-			var query = keywordArgs.query;
-			for(var attr in query){
-				first = query[attr];
-				break;
+		fetch: function(/* Object */ keywordArgs){
+			// Get the query phrase (store into first), and the # of chars it has
+			var count = 0;
+			var first;
+			if("query" in keywordArgs){
+				var query = keywordArgs.query;
+				for(var attr in query){
+					first = query[attr];
+					break;
+				}
+				count = first.toString().length;
 			}
-			count = first.toString().length;
-		}
-
-		var delay = 100;
-		switch(count || 0){
-			case 0:
-				delay = 2000;
-				break;
-			case 1:
-			case 2:
-				delay = 1000;
-				break;
-			case 3:
-				delay = 500;
-				break;
-			case 4:
-				delay = 100;
-				break;
-		}
 
-		this.log.push({
-			type: "start",
-			date: new Date(),
-			query: query,
-			count: count,
-			delay: delay
-		});
-		console.log("START query on " + (first || "{}") + " (" + count + " chars), delay = " + delay);
+			var delay = 100;
+			switch(count || 0){
+				case 0:
+					delay = 2000;
+					break;
+				case 1:
+				case 2:
+					delay = 1000;
+					break;
+				case 3:
+					delay = 500;
+					break;
+				case 4:
+					delay = 100;
+					break;
+			}
 
-		var that = this,
-			thatArgs = arguments;
-		var handle = setTimeout(function(){
-			that.log.push({
-				type: "end",
+			this.log.push({
+				type: "start",
 				date: new Date(),
 				query: query,
 				count: count,
 				delay: delay
 			});
-			console.log("END query on " + (first || "{}") + " (" + count + " chars), delay = " + delay);
-			dojo.data.ItemFileReadStore.prototype.fetch.apply(that, thatArgs);
-		}, delay);
+			console.log("START query on " + (first || "{}") + " (" + count + " chars), delay = " + delay);
 
-		// This abort() method cancels a request before it has even been sent to ItemFileReadStore.
-		// (Since ItemFileReadStore has already loaded the data (as per code in the test file),
-		// it operates synchronously; there is never a case to send the cancel request to that object)
-		keywordArgs.abort = function(){
-			clearTimeout(handle);
-			that.log.push({
-				type: "cancel",
-				date: new Date(),
-				query: query,
-				count: count,
-				delay: delay
-			});
-			console.log("CANCEL query on " + (first || "{}") + " (" + count + " chars), delay = " + delay);
-		};
+			var that = this,
+				thatArgs = arguments;
+			var handle = setTimeout(function(){
+				that.log.push({
+					type: "end",
+					date: new Date(),
+					query: query,
+					count: count,
+					delay: delay
+				});
+				console.log("END query on " + (first || "{}") + " (" + count + " chars), delay = " + delay);
+				ItemFileReadStore.prototype.fetch.apply(that, thatArgs);
+			}, delay);
+
+			// This abort() method cancels a request before it has even been sent to ItemFileReadStore.
+			// (Since ItemFileReadStore has already loaded the data (as per code in the test file),
+			// it operates synchronously; there is never a case to send the cancel request to that object)
+			keywordArgs.abort = function(){
+				clearTimeout(handle);
+				that.log.push({
+					type: "cancel",
+					date: new Date(),
+					query: query,
+					count: count,
+					delay: delay
+				});
+				console.log("CANCEL query on " + (first || "{}") + " (" + count + " chars), delay = " + delay);
+			};
+
+			return keywordArgs;
+		}
+	});
 
-		return keywordArgs;
-	}
 });
diff --git a/dijit/tests/_data/categories.json b/dijit/tests/_data/categories.json
index ff5ffe1..0bf996c 100644
--- a/dijit/tests/_data/categories.json
+++ b/dijit/tests/_data/categories.json
@@ -1,12 +1,12 @@
 {
-	identifier: 'id',
-	label: 'name',
-	items: [
-		{ id: '0', name:'Foods', numberOfItems:1, children:[ {_reference: '1'},  {_reference: '2'},  {_reference: '3'} ] },
-			{ id: '1', name:'Fruits', numberOfItems:1, children:[ {_reference: '4'} ] },
-				{ id: '4',name:'Citrus', numberOfItems:1, items:[ {_reference: '5'} ] },
-					{ id: '5', name:'Orange'},
-		{ id: '2', name:'Vegetables', numberOfItems:0},
-		{ id: '3', name:'Cereals', numberOfItems:0}
+	"identifier": "id",
+	"label": "name",
+	"items": [
+		{ "id": "0", "name":"Foods", "numberOfItems":1, "children":[ {"_reference": "1"},  {"_reference": "2"},  {"_reference": "3"} ] },
+			{ "id": "1", "name":"Fruits", "numberOfItems":1, "children":[ {"_reference": "4"} ] },
+				{ "id": "4","name":"Citrus", "numberOfItems":1, "items":[ {"_reference": "5"} ] },
+					{ "id": "5", "name":"Orange"},
+		{ "id": "2", "name":"Vegetables", "numberOfItems":0},
+		{ "id": "3", "name":"Cereals", "numberOfItems":0}
 	]
 }
diff --git a/dijit/tests/_data/categoriesNested.json b/dijit/tests/_data/categoriesNested.json
index f130ae5..c264344 100644
--- a/dijit/tests/_data/categoriesNested.json
+++ b/dijit/tests/_data/categoriesNested.json
@@ -1,13 +1,13 @@
 {
-	identifier: 'id',
-	label: 'name',
-	items: [
-		{ id: '0', name:'Fruits', numberOfItems:1, children:[
-			{ id: '1',name:'Citrus', numberOfItems:1, items:[
-				{ id: '4', name:'Orange'}
+	"identifier": "id",
+	"label": "name",
+	"items": [
+		{ "id": "0", "name":"Fruits", "numberOfItems":1, "children":[
+			{ "id": "1","name":"Citrus", "numberOfItems":1, "items":[
+				{ "id": "4", "name":"Orange"}
 			]}
 		]},
-		{ id: '2', name:'Vegetables', numberOfItems:0},
-		{ id: '3', name:'Cereals', numberOfItems:0}
+		{ "id": "2", "name":"Vegetables", "numberOfItems":0},
+		{ "id": "3", "name":"Cereals", "numberOfItems":0}
 	]
 }
diff --git a/dijit/tests/_data/countries.json b/dijit/tests/_data/countries.json
index 155b93c..8b39dec 100644
--- a/dijit/tests/_data/countries.json
+++ b/dijit/tests/_data/countries.json
@@ -1,46 +1,46 @@
 {
-	identifier: 'id',
-	label: 'name',
-	items: [
-	        { id: 'AF', name:'Africa', type:'continent', population:'900 million', area: '30,221,532 sq km',
-	        		timezone: '-1 UTC to +4 UTC',
-	        		children:[{_reference:'EG'}, {_reference:'KE'}, {_reference:'SD'}] },
-	        	{ id: 'EG', name:'Egypt', type:'country' },
-	        	{ id: 'KE', name:'Kenya', type:'country',
-	        			children:[{_reference:'Nairobi'}, {_reference:'Mombasa'}] },
-	        		{ id: 'Nairobi', name:'Nairobi', type:'city' },
-	        		{ id: 'Mombasa', name:'Mombasa', type:'city' },
-	        	{ id: 'SD', name:'Sudan', type:'country',
-	        			children:{_reference:'Khartoum'} },
-	        		{ id: 'Khartoum', name:'Khartoum', type:'city' },
-	        	{ id: 'AS', name:'Asia', type:'continent',
-	        			children:[{_reference:'CN'}, {_reference:'IN'}, {_reference:'RU'}, {_reference:'MN'}] },
-	        		{ id: 'CN', name:'China', type:'country' },
-	        		{ id: 'IN', name:'India', type:'country' },
-	        		{ id: 'RU', name:'Russia', type:'country' },
-	        		{ id: 'MN', name:'Mongolia', type:'country' },
-	        	{ id: 'OC', name:'Oceania', type:'continent', population:'21 million',
-	        			children:{_reference:'AU'}},
-	        	{ id: 'AU', name:'Australia', type:'country', population:'21 million'},
-	        	{ id: 'EU', name:'Europe', type:'continent',
-	        			children:[{_reference:'DE'}, {_reference:'FR'}, {_reference:'ES'}, {_reference:'IT'}] },
-	        	{ id: 'DE', name:'Germany', type:'country' },
-	        	{ id: 'FR', name:'France', type:'country' },
-	        	{ id: 'ES', name:'Spain', type:'country' },
-	        	{ id: 'IT', name:'Italy', type:'country' },
-	        { id: 'NA', name:'North America', type:'continent',
-	        		children:[{_reference:'MX'}, {_reference:'CA'}, {_reference:'US'}] },
-	        	{ id: 'MX', name:'Mexico', type:'country',  population:'108 million', area:'1,972,550 sq km',
-	        			children:[{_reference:'Mexico City'}, {_reference:'Guadalajara'}] },
-	        		{ id: 'Mexico City', name:'Mexico City', type:'city', population:'19 million', timezone:'-6 UTC'},
-	        		{ id: 'Guadalajara', name:'Guadalajara', type:'city', population:'4 million', timezone:'-6 UTC' },
-	        	{ id: 'CA', name:'Canada', type:'country',  population:'33 million', area:'9,984,670 sq km',
-	        			children:[{_reference:'Ottawa'}, {_reference:'Toronto'}] },
-	        		{ id: 'Ottawa', name:'Ottawa', type:'city', population:'0.9 million', timezone:'-5 UTC'},
-	        		{ id: 'Toronto', name:'Toronto', type:'city', population:'2.5 million', timezone:'-5 UTC' },
-	        	{ id: 'US', name:'United States of America', type:'country' },
-	        { id: 'SA', name:'South America', type:'continent',
-	        		children:[{_reference:'BR'}, {_reference:'AR'}] },
-	        	{ id: 'BR', name:'Brazil', type:'country', population:'186 million' },
-	        	{ id: 'AR', name:'Argentina', type:'country', population:'40 million' }
+	"identifier": "id",
+	"label": "name",
+	"items": [
+	        { "id": "AF", "name":"Africa", "type":"continent", "population":"900 million", "area": "30,221,532 sq km",
+	        		"timezone": "-1 UTC to +4 UTC",
+	        		"children":[{"_reference":"EG"}, {"_reference":"KE"}, {"_reference":"SD"}] },
+	        	{ "id": "EG", "name":"Egypt", "type":"country" },
+	        	{ "id": "KE", "name":"Kenya", "type":"country",
+	        			"children":[{"_reference":"Nairobi"}, {"_reference":"Mombasa"}] },
+	        		{ "id": "Nairobi", "name":"Nairobi", "type":"city" },
+	        		{ "id": "Mombasa", "name":"Mombasa", "type":"city" },
+	        	{ "id": "SD", "name":"Sudan", "type":"country",
+	        			"children":{"_reference":"Khartoum"} },
+	        		{ "id": "Khartoum", "name":"Khartoum", "type":"city" },
+	        	{ "id": "AS", "name":"Asia", "type":"continent",
+	        			"children":[{"_reference":"CN"}, {"_reference":"IN"}, {"_reference":"RU"}, {"_reference":"MN"}] },
+	        		{ "id": "CN", "name":"China", "type":"country" },
+	        		{ "id": "IN", "name":"India", "type":"country" },
+	        		{ "id": "RU", "name":"Russia", "type":"country" },
+	        		{ "id": "MN", "name":"Mongolia", "type":"country" },
+	        	{ "id": "OC", "name":"Oceania", "type":"continent", "population":"21 million",
+	        			"children":{"_reference":"AU"}},
+	        	{ "id": "AU", "name":"Australia", "type":"country", "population":"21 million"},
+	        	{ "id": "EU", "name":"Europe", "type":"continent",
+	        			"children":[{"_reference":"DE"}, {"_reference":"FR"}, {"_reference":"ES"}, {"_reference":"IT"}] },
+	        	{ "id": "DE", "name":"Germany", "type":"country" },
+	        	{ "id": "FR", "name":"France", "type":"country" },
+	        	{ "id": "ES", "name":"Spain", "type":"country" },
+	        	{ "id": "IT", "name":"Italy", "type":"country" },
+	        { "id": "NA", "name":"North America", "type":"continent",
+	        		"children":[{"_reference":"MX"}, {"_reference":"CA"}, {"_reference":"US"}] },
+	        	{ "id": "MX", "name":"Mexico", "type":"country",  "population":"108 million", "area":"1,972,550 sq km",
+	        			"children":[{"_reference":"Mexico City"}, {"_reference":"Guadalajara"}] },
+	        		{ "id": "Mexico City", "name":"Mexico City", "type":"city", "population":"19 million", "timezone":"-6 UTC"},
+	        		{ "id": "Guadalajara", "name":"Guadalajara", "type":"city", "population":"4 million", "timezone":"-6 UTC" },
+	        	{ "id": "CA", "name":"Canada", "type":"country",  "population":"33 million", "area":"9,984,670 sq km",
+	        			"children":[{"_reference":"Ottawa"}, {"_reference":"Toronto"}] },
+	        		{ "id": "Ottawa", "name":"Ottawa", "type":"city", "population":"0.9 million", "timezone":"-5 UTC"},
+	        		{ "id": "Toronto", "name":"Toronto", "type":"city", "population":"2.5 million", "timezone":"-5 UTC" },
+	        	{ "id": "US", "name":"United States of America", "type":"country" },
+	        { "id": "SA", "name":"South America", "type":"continent",
+	        		"children":[{"_reference":"BR"}, {"_reference":"AR"}] },
+	        	{ "id": "BR", "name":"Brazil", "type":"country", "population":"186 million" },
+	        	{ "id": "AR", "name":"Argentina", "type":"country", "population":"40 million" }
 ]}
diff --git a/dijit/tests/_data/geography.js b/dijit/tests/_data/geography.js
new file mode 100644
index 0000000..f3eff4e
--- /dev/null
+++ b/dijit/tests/_data/geography.js
@@ -0,0 +1,37 @@
+// Array of countries and cities, with children having references to their parents rather than vice-versa.
+// Used with dijit/tree/ObjectStoreModel.
+
+define([
+	{ id: "earth", name:"The earth", type:"planet", population: "6 billion"},
+	{ id: "AF", name:"Africa", type:"continent", population:"900 million", area: "30,221,532 sq km",
+		timezone: "-1 UTC to +4 UTC", parent: "earth"},
+	{ id: "EG", name:"Egypt", type:"country", parent: "AF" },
+	{ id: "KE", name:"Kenya", type:"country", parent: "AF" },
+	{ id: "Nairobi", name:"Nairobi", type:"city", parent: "KE" },
+	{ id: "Mombasa", name:"Mombasa", type:"city", parent: "KE" },
+	{ id: "SD", name:"Sudan", type:"country", parent: "AF" },
+	{ id: "Khartoum", name:"Khartoum", type:"city", parent: "SD" },
+	{ id: "AS", name:"Asia", type:"continent", parent: "earth" },
+	{ id: "CN", name:"China", type:"country", parent: "AS" },
+	{ id: "IN", name:"India", type:"country", parent: "AS" },
+	{ id: "RU", name:"Russia", type:"country", parent: "AS" },
+	{ id: "MN", name:"Mongolia", type:"country", parent: "AS" },
+	{ id: "OC", name:"Oceania", type:"continent", population:"21 million", parent: "earth"},
+	{ id: "AU", name:"Australia", type:"country", population:"21 million", parent: "OC"},
+	{ id: "EU", name:"Europe", type:"continent", parent: "earth" },
+	{ id: "DE", name:"Germany", type:"country", parent: "EU" },
+	{ id: "FR", name:"France", type:"country", parent: "EU" },
+	{ id: "ES", name:"Spain", type:"country", parent: "EU" },
+	{ id: "IT", name:"Italy", type:"country", parent: "EU" },
+	{ id: "NA", name:"North America", type:"continent", parent: "earth" },
+	{ id: "MX", name:"Mexico", type:"country",  population:"108 million", area:"1,972,550 sq km", parent: "NA" },
+	{ id: "Mexico City", name:"Mexico City", type:"city", population:"19 million", timezone:"-6 UTC", parent: "MX"},
+	{ id: "Guadalajara", name:"Guadalajara", type:"city", population:"4 million", timezone:"-6 UTC", parent: "MX" },
+	{ id: "CA", name:"Canada", type:"country",  population:"33 million", area:"9,984,670 sq km", parent: "NA" },
+	{ id: "Ottawa", name:"Ottawa", type:"city", population:"0.9 million", timezone:"-5 UTC", parent: "CA"},
+	{ id: "Toronto", name:"Toronto", type:"city", population:"2.5 million", timezone:"-5 UTC", parent: "CA" },
+	{ id: "US", name:"United States of America", type:"country", parent: "NA" },
+	{ id: "SA", name:"South America", type:"continent", parent: "earth" },
+	{ id: "BR", name:"Brazil", type:"country", population:"186 million", parent: "SA" },
+	{ id: "AR", name:"Argentina", type:"country", population:"40 million", parent: "SA" }
+]);
\ No newline at end of file
diff --git a/dijit/tests/_data/states.json b/dijit/tests/_data/states.json
index 9f29108..b2bc408 100644
--- a/dijit/tests/_data/states.json
+++ b/dijit/tests/_data/states.json
@@ -1,67 +1,67 @@
 {
-  identifier:"abbreviation",
-  label: "name",
-  items: [
-	{name:"Alabama", label:"<img width='97px' height='127px' src='images/Alabama.jpg'/>Alabama",abbreviation:"AL"},
-	{name:"Alaska", label:"Alaska",abbreviation:"AK"},
-	{name:"American Samoa", label:"American Samoa",abbreviation:"AS"},
-	{name:"Arizona", label:"Arizona",abbreviation:"AZ"},
-	{name:"Arkansas", label:"Arkansas",abbreviation:"AR"},
-	{name:"Armed Forces Europe", label:"Armed Forces Europe",abbreviation:"AE"},
-	{name:"Armed Forces Pacific", label:"Armed Forces Pacific",abbreviation:"AP"},
-	{name:"Armed Forces the Americas", label:"Armed Forces the Americas",abbreviation:"AA"},
-	{name:"California", label:"California",abbreviation:"CA"},
-	{name:"Colorado", label:"Colorado",abbreviation:"CO"},
-	{name:"Connecticut", label:"Connecticut",abbreviation:"CT"},
-	{name:"Delaware", label:"Delaware",abbreviation:"DE"},
-	{name:"District of Columbia", label:"District of Columbia",abbreviation:"DC"},
-	{name:"Federated States of Micronesia", label:"Federated States of Micronesia",abbreviation:"FM"},
-	{name:"Florida", label:"Florida",abbreviation:"FL"},
-	{name:"Georgia", label:"Georgia",abbreviation:"GA"},
-	{name:"Guam", label:"Guam",abbreviation:"GU"},
-	{name:"Hawaii", label:"Hawaii",abbreviation:"HI"},
-	{name:"Idaho", label:"Idaho",abbreviation:"ID"},
-	{name:"Illinois", label:"Illinois",abbreviation:"IL"},
-	{name:"Indiana", label:"Indiana",abbreviation:"IN"},
-	{name:"Iowa", label:"Iowa",abbreviation:"IA"},
-	{name:"Kansas", label:"Kansas",abbreviation:"KS"},
-	{name:"Kentucky", label:"Kentucky",abbreviation:"KY"},
-	{name:"Louisiana", label:"Louisiana",abbreviation:"LA"},
-	{name:"Maine", label:"Maine",abbreviation:"ME"},
-	{name:"Marshall Islands", label:"Marshall Islands",abbreviation:"MH"},
-	{name:"Maryland", label:"Maryland",abbreviation:"MD"},
-	{name:"Massachusetts", label:"Massachusetts",abbreviation:"MA"},
-	{name:"Michigan", label:"Michigan",abbreviation:"MI"},
-	{name:"Minnesota", label:"Minnesota",abbreviation:"MN"},
-	{name:"Mississippi", label:"Mississippi",abbreviation:"MS"},
-	{name:"Missouri", label:"Missouri",abbreviation:"MO"},
-	{name:"Montana", label:"Montana",abbreviation:"MT"},
-	{name:"Nebraska", label:"Nebraska",abbreviation:"NE"},
-	{name:"Nevada", label:"Nevada",abbreviation:"NV"},
-	{name:"New Hampshire", label:"New Hampshire",abbreviation:"NH"},
-	{name:"New Jersey", label:"New Jersey",abbreviation:"NJ"},
-	{name:"New Mexico", label:"New Mexico",abbreviation:"NM"},
-	{name:"New York", label:"New York",abbreviation:"NY"},
-	{name:"North Carolina", label:"North Carolina",abbreviation:"NC"},
-	{name:"North Dakota", label:"North Dakota",abbreviation:"ND"},
-	{name:"Northern Mariana Islands", label:"Northern Mariana Islands",abbreviation:"MP"},
-	{name:"Ohio", label:"Ohio",abbreviation:"OH"},
-	{name:"Oklahoma", label:"Oklahoma",abbreviation:"OK"},
-	{name:"Oregon", label:"Oregon",abbreviation:"OR"},
-	{name:"Pennsylvania", label:"Pennsylvania",abbreviation:"PA"},
-	{name:"Puerto Rico", label:"Puerto Rico",abbreviation:"PR"},
-	{name:"Rhode Island", label:"Rhode Island",abbreviation:"RI"},
-	{name:"South Carolina", label:"South Carolina",abbreviation:"SC"},
-	{name:"South Dakota", label:"South Dakota",abbreviation:"SD"},
-	{name:"Tennessee", label:"Tennessee",abbreviation:"TN"},
-	{name:"Texas", label:"Texas",abbreviation:"TX"},
-	{name:"Utah", label:"Utah",abbreviation:"UT"},
-	{name:"Vermont", label:"Vermont",abbreviation:"VT"},
-	{name: "Virgin Islands, U.S.",label:"Virgin Islands, U.S.",abbreviation:"VI"},
-	{name:"Virginia", label:"Virginia",abbreviation:"VA"},
-	{name:"Washington", label:"Washington",abbreviation:"WA"},
-	{name:"West Virginia", label:"West Virginia",abbreviation:"WV"},
-	{name:"Wisconsin", label:"Wisconsin",abbreviation:"WI"},
-	{name:"Wyoming", label:"Wyoming",abbreviation:"WY"}
+  "identifier":"abbreviation",
+  "label": "name",
+  "items": [
+	{"name":"Alabama", "label":"<img width='97px' height='127px' src='images/Alabama.jpg'/>Alabama","abbreviation":"AL"},
+	{"name":"Alaska", "label":"Alaska","abbreviation":"AK"},
+	{"name":"American Samoa", "label":"American Samoa","abbreviation":"AS"},
+	{"name":"Arizona", "label":"Arizona","abbreviation":"AZ"},
+	{"name":"Arkansas", "label":"Arkansas","abbreviation":"AR"},
+	{"name":"Armed Forces Europe", "label":"Armed Forces Europe","abbreviation":"AE"},
+	{"name":"Armed Forces Pacific", "label":"Armed Forces Pacific","abbreviation":"AP"},
+	{"name":"Armed Forces the Americas", "label":"Armed Forces the Americas","abbreviation":"AA"},
+	{"name":"California", "label":"California","abbreviation":"CA"},
+	{"name":"Colorado", "label":"Colorado","abbreviation":"CO"},
+	{"name":"Connecticut", "label":"Connecticut","abbreviation":"CT"},
+	{"name":"Delaware", "label":"Delaware","abbreviation":"DE"},
+	{"name":"District of Columbia", "label":"District of Columbia","abbreviation":"DC"},
+	{"name":"Federated States of Micronesia", "label":"Federated States of Micronesia","abbreviation":"FM"},
+	{"name":"Florida", "label":"Florida","abbreviation":"FL"},
+	{"name":"Georgia", "label":"Georgia","abbreviation":"GA"},
+	{"name":"Guam", "label":"Guam","abbreviation":"GU"},
+	{"name":"Hawaii", "label":"Hawaii","abbreviation":"HI"},
+	{"name":"Idaho", "label":"Idaho","abbreviation":"ID"},
+	{"name":"Illinois", "label":"Illinois","abbreviation":"IL"},
+	{"name":"Indiana", "label":"Indiana","abbreviation":"IN"},
+	{"name":"Iowa", "label":"Iowa","abbreviation":"IA"},
+	{"name":"Kansas", "label":"Kansas","abbreviation":"KS"},
+	{"name":"Kentucky", "label":"Kentucky","abbreviation":"KY"},
+	{"name":"Louisiana", "label":"Louisiana","abbreviation":"LA"},
+	{"name":"Maine", "label":"Maine","abbreviation":"ME"},
+	{"name":"Marshall Islands", "label":"Marshall Islands","abbreviation":"MH"},
+	{"name":"Maryland", "label":"Maryland","abbreviation":"MD"},
+	{"name":"Massachusetts", "label":"Massachusetts","abbreviation":"MA"},
+	{"name":"Michigan", "label":"Michigan","abbreviation":"MI"},
+	{"name":"Minnesota", "label":"Minnesota","abbreviation":"MN"},
+	{"name":"Mississippi", "label":"Mississippi","abbreviation":"MS"},
+	{"name":"Missouri", "label":"Missouri","abbreviation":"MO"},
+	{"name":"Montana", "label":"Montana","abbreviation":"MT"},
+	{"name":"Nebraska", "label":"Nebraska","abbreviation":"NE"},
+	{"name":"Nevada", "label":"Nevada","abbreviation":"NV"},
+	{"name":"New Hampshire", "label":"New Hampshire","abbreviation":"NH"},
+	{"name":"New Jersey", "label":"New Jersey","abbreviation":"NJ"},
+	{"name":"New Mexico", "label":"New Mexico","abbreviation":"NM"},
+	{"name":"New York", "label":"New York","abbreviation":"NY"},
+	{"name":"North Carolina", "label":"North Carolina","abbreviation":"NC"},
+	{"name":"North Dakota", "label":"North Dakota","abbreviation":"ND"},
+	{"name":"Northern Mariana Islands", "label":"Northern Mariana Islands","abbreviation":"MP"},
+	{"name":"Ohio", "label":"Ohio","abbreviation":"OH"},
+	{"name":"Oklahoma", "label":"Oklahoma","abbreviation":"OK"},
+	{"name":"Oregon", "label":"Oregon","abbreviation":"OR"},
+	{"name":"Pennsylvania", "label":"Pennsylvania","abbreviation":"PA"},
+	{"name":"Puerto Rico", "label":"Puerto Rico","abbreviation":"PR"},
+	{"name":"Rhode Island", "label":"Rhode Island","abbreviation":"RI"},
+	{"name":"South Carolina", "label":"South Carolina","abbreviation":"SC"},
+	{"name":"South Dakota", "label":"South Dakota","abbreviation":"SD"},
+	{"name":"Tennessee", "label":"Tennessee","abbreviation":"TN"},
+	{"name":"Texas", "label":"Texas","abbreviation":"TX"},
+	{"name":"Utah", "label":"Utah","abbreviation":"UT"},
+	{"name":"Vermont", "label":"Vermont","abbreviation":"VT"},
+	{"name": "Virgin Islands, U.S.","label":"Virgin Islands, U.S.","abbreviation":"VI"},
+	{"name":"Virginia", "label":"Virginia","abbreviation":"VA"},
+	{"name":"Washington", "label":"Washington","abbreviation":"WA"},
+	{"name":"West Virginia", "label":"West Virginia","abbreviation":"WV"},
+	{"name":"Wisconsin", "label":"Wisconsin","abbreviation":"WI"},
+	{"name":"Wyoming", "label":"Wyoming","abbreviation":"WY"}
   ]
 }
\ No newline at end of file
diff --git a/dijit/tests/_loadTest.js b/dijit/tests/_loadTest.js
index 4ab4cb1..5ef26d6 100644
--- a/dijit/tests/_loadTest.js
+++ b/dijit/tests/_loadTest.js
@@ -67,14 +67,15 @@ if(/MSIE/.test(navigator.userAgent)){ // need to load scripts serially
 		if(/^script$/i.test(tag)){
 			var scripts = document.scripts;
 			for(var i=0; i <scripts.length; i++){
-				var script = scripts[i];
-				if(!script['_oldGetAttribute']){
-					var src = script.getAttribute('_oldsrc');
-					if(src){
-						script._oldGetAttribute = script.getAttribute;
-						script.getAttribute = function(attr){ if(/^src$/i.test(attr))attr='_oldsrc';return script._oldGetAttribute(attr) };
+				(function(script){
+					if(!('_oldGetAttribute' in script)){
+						var src = script.getAttribute('_oldsrc');
+						if(src){
+							script._oldGetAttribute = script.getAttribute;
+							script.getAttribute = function(attr){ return /^src$/i.test(attr) ? src : script._oldGetAttribute(attr); };
+						}
 					}
-				}
+				}).call(this, scripts[i]);
 			}
 			return scripts;
 		}
diff --git a/dijit/tests/_testCommon.js b/dijit/tests/_testCommon.js
index 0fc8ee8..20fa930 100644
--- a/dijit/tests/_testCommon.js
+++ b/dijit/tests/_testCommon.js
@@ -1,20 +1,8 @@
 // module:
 //		dijit/tests/_testCommon.js
 // description:
-//		A simple module to be included in dijit test pages to allow
-//		for easy switching between the many many points of the test-matrix.
-//
-//		in your test browser, provides a way to switch between available themes,
-//		and optionally enable RTL (right to left) mode, and/or dijit_a11y (high-
-//		contrast/image off emulation) ... probably not a genuine test for a11y.
-//
-//		usage: on any dijit test_* page, press ctrl-f9 to popup links.
-//
-//		there are currently (3 themes * 4 tests) * (10 variations of supported browsers)
-//		not including testing individual locale-strings
-//
-//		you should NOT be using this in a production environment. include
-//		your css and set your classes manually. for test purposes only ...
+//		Deprecated, remove in 2.0.   New test files should use boilerplate.html rather than this file,
+//		and non-test files shouldn't be using either.
 
 require([
 	"require",
@@ -60,7 +48,7 @@ require([
 					theme = value;
 					break;
 				case "a11y":
-					if(value){ testMode = "dijit_a11y"; }
+					if(value){ testMode = "dj_a11y"; }
 					break;
 				case "themeModule":
 					// moduleName | null
diff --git a/dijit/tests/a11y.html b/dijit/tests/a11y.html
new file mode 100644
index 0000000..0c932b3
--- /dev/null
+++ b/dijit/tests/a11y.html
@@ -0,0 +1,303 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>dijit/a11y unit test</title>
+
+	<script src="boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner", "dojo/dom", "dojo/parser",
+			"dijit/a11y", "dijit/registry", "dojo/domReady!", "dijit/Editor"
+		], function(doh, dom, parser, a11y, registry){
+
+			doh.register("dijit/a11y", [
+				function parse(){
+					parser.parse();
+				},
+
+				function isTabNavigable(t){
+					var d = new doh.Deferred();
+					doh.t(a11y.isTabNavigable(dom.byId("a-with-href")), "a-with-href");
+					doh.f(a11y.isTabNavigable(dom.byId("a-without-href")), "a-without-href");
+					doh.t(a11y.isTabNavigable(dom.byId("area")), "area");
+					doh.t(a11y.isTabNavigable(dom.byId("button")), "button");
+					doh.t(a11y.isTabNavigable(dom.byId("input")), "input");
+					doh.t(a11y.isTabNavigable(dom.byId("object")), "object");
+					doh.t(a11y.isTabNavigable(dom.byId("select")), "select");
+					doh.t(a11y.isTabNavigable(dom.byId("textarea")), "textarea");
+					doh.f(a11y.isTabNavigable(dom.byId("empty")), "empty");
+					doh.t(a11y.isTabNavigable(dom.byId("zero-tabindex-div")), "zero-tabindex-div");
+					doh.f(a11y.isTabNavigable(dom.byId("no-tabindex-div")), "no-tabindex-div");
+					doh.f(a11y.isTabNavigable(dom.byId("iframe")), "iframe");
+
+					registry.byId("editor").onLoadDeferred.then(d.getTestCallback(function(){
+						doh.t(a11y.isTabNavigable(dom.byId("editor_iframe")), "editor_iframe");
+					}));
+
+					return d;
+				},
+				function findTabNullOnEmpty(t){
+					doh.is(null, a11y.getFirstInTabbingOrder("empty"));
+					doh.is(null, a11y.getLastInTabbingOrder("empty"));
+				},
+				function findTabElements(t){
+					doh.is(null, a11y.getFirstInTabbingOrder("div-container"));
+					doh.is(null, a11y.getFirstInTabbingOrder("a-without-href-container"));
+					doh.is("a-with-href", a11y.getFirstInTabbingOrder("a-with-href-container").id);
+
+					// in WebKit area elements are not in the tab order
+					// and their display style property is "none";
+					// therefore it is expected that this test will fail
+					if(!dojo.isWebKit){
+						doh.is("area", a11y.getFirstInTabbingOrder("area-map").id);
+					}
+
+					doh.is("button", a11y.getFirstInTabbingOrder("button-container").id);
+					doh.is("input", a11y.getFirstInTabbingOrder("input-container").id);
+					doh.is("object", a11y.getFirstInTabbingOrder("object-container").id);
+					doh.is("select", a11y.getFirstInTabbingOrder("select-container").id);
+					doh.is("textarea", a11y.getFirstInTabbingOrder("textarea-container").id);
+					doh.is(null, a11y.getLastInTabbingOrder("div-container"));
+					doh.is(null, a11y.getLastInTabbingOrder("a-without-href-container"));
+					doh.is("a-with-href", a11y.getLastInTabbingOrder("a-with-href-container").id);
+
+					// in WebKit area elements are not in the tab order
+					// and their display style property is "none";
+					// therefore it is expected that this test will fail
+					if(!dojo.isWebKit){
+						doh.is("area", a11y.getLastInTabbingOrder("area-map").id);
+					}
+
+					doh.is("button", a11y.getLastInTabbingOrder("button-container").id);
+					doh.is("input", a11y.getLastInTabbingOrder("input-container").id);
+					doh.is("object", a11y.getLastInTabbingOrder("object-container").id);
+					doh.is("select", a11y.getLastInTabbingOrder("select-container").id);
+					doh.is("textarea", a11y.getLastInTabbingOrder("textarea-container").id);
+				},
+				function findTabOnElementRatherThanString(t){
+					doh.is("a-with-href", a11y.getFirstInTabbingOrder(dom.byId("a-with-href-container")).id);
+					doh.is("a-with-href", a11y.getLastInTabbingOrder(dom.byId("a-with-href-container")).id);
+				},
+				function findTabSkipDisabled(t){
+					doh.is("not-disabled-input", a11y.getFirstInTabbingOrder("skip-disabled").id);
+					doh.is("not-disabled-input", a11y.getLastInTabbingOrder("skip-disabled").id);
+				},
+				function findTabZeroTabindex(t){
+					doh.is("zero-tabindex-div", a11y.getFirstInTabbingOrder("zero-tabindex-div-container").id);
+					doh.is("zero-tabindex-input", a11y.getFirstInTabbingOrder("zero-tabindex-input-container").id);
+					doh.is("zero-tabindex-div", a11y.getLastInTabbingOrder("zero-tabindex-div-container").id);
+					doh.is("zero-tabindex-input", a11y.getLastInTabbingOrder("zero-tabindex-input-container").id);
+				},
+				function findTabPositiveTabindex(t){
+					doh.is("positive-tabindex-input1a", a11y.getFirstInTabbingOrder("positive-tabindex-mixed-with-no-tabindex").id);
+					doh.is("positive-tabindex-input3a", a11y.getFirstInTabbingOrder("positive-tabindex").id);
+					doh.is("no-tabindex-input2", a11y.getLastInTabbingOrder("positive-tabindex-mixed-with-no-tabindex").id);
+					doh.is("positive-tabindex-input4b", a11y.getLastInTabbingOrder("positive-tabindex").id);
+				},
+				function findTabSkipMinusOneTabindex(t){
+					doh.is("not-minus-one-input", a11y.getFirstInTabbingOrder("skip-minus-one").id);
+					doh.is("not-minus-one-input", a11y.getLastInTabbingOrder("skip-minus-one").id);
+				},
+				function findTabDescend(t){
+					doh.is("child-input1", a11y.getFirstInTabbingOrder("descend").id);
+					doh.is("child-input2", a11y.getLastInTabbingOrder("descend").id);
+				},
+				function findTabOuterInner(t){
+					doh.is("outer1", a11y.getFirstInTabbingOrder("outer-inner-container").id);
+					doh.is("inner2", a11y.getLastInTabbingOrder("outer-inner-container").id);
+				},
+				function skipNotShown(t){
+					doh.is(null, a11y.getFirstInTabbingOrder("hidden-element-container"));
+					doh.is(null, a11y.getFirstInTabbingOrder("hidden-container-tabindex-zero"));
+					doh.is(null, a11y.getFirstInTabbingOrder("hidden-container-no-tabindex"));
+					doh.is(null, a11y.getFirstInTabbingOrder("container-with-hidden-containers"));
+
+					doh.is(null, a11y.getFirstInTabbingOrder("display-none-element-container"));
+					doh.is(null, a11y.getFirstInTabbingOrder("display-none-container-tabindex-zero"));
+					doh.is(null, a11y.getFirstInTabbingOrder("display-none-container-no-tabindex"));
+					doh.is(null, a11y.getFirstInTabbingOrder("container-with-display-none-containers"));
+				},
+				function multiDigitTabIndex(){
+					doh.is("one", a11y.getFirstInTabbingOrder("multiDigitTabIndex").name, "first");
+					doh.is("eleven", a11y.getLastInTabbingOrder("multiDigitTabIndex").name, "last");
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+<body class="claro">
+	<h1>Dijit TabIndex Related Functions Unit Test</h1>
+
+	<div id="empty"></div>
+
+	<div id="div-container">
+		<div id="div"></div>
+	</div>
+	<div id="a-without-href-container">
+		<a id="a-without-href"></a>
+	</div>
+	<div id="a-with-href-container">
+		<a id="a-with-href" href="#a-without-href"></a>
+	</div>
+
+	<div><img src="images/flatScreen.gif" alt="picture of a flat-screen monitor" usemap="#area-map"/></div>
+	<map id="area-map" name="area-map">
+		<area id="area" href="#" alt="example area" shape="rect" coords="0,0,8,8"/>
+	</map>
+
+	<div id="button-container">
+		<button id="button"></button>
+	</div>
+	<div id="input-container">
+		<input id="input"/>
+	</div>
+	<div id="object-container">
+		<object id="object" type="text/javascript"></object>
+	</div>
+	<div id="select-container">
+		<select id="select"></select>
+	</div>
+	<div id="textarea-container">
+		<textarea id="textarea"></textarea>
+	</div>
+
+	<div id="skip-disabled">
+		<input id="disabled-input1" disabled="disabled"/>
+		<input id="not-disabled-input"/>
+		<input id="disabled-input2" disabled="disabled"/>
+	</div>
+
+	<div id="zero-tabindex-div-container">
+		<div id="zero-tabindex-div" tabindex="0"></div>
+	</div>
+
+	<div id="no-tabindex-div-container">
+		<div id="no-tabindex-div"></div>
+	</div>
+
+	<div id="zero-tabindex-input-container">
+		<input id="zero-tabindex-input" tabindex="0"/>
+	</div>
+
+	<div id="iframe-container">
+		<div id="iframe"></div>
+	</div>
+
+	<div id="editor-container">
+		<div id="editor" data-dojo-type="dijit/Editor"></div>
+	</div>
+
+	<div id="positive-tabindex-mixed-with-no-tabindex">
+		<input id="no-tabindex-input1"/>
+		<input id="no-tabindex-input2"/>
+		<input id="positive-tabindex-input1a" tabindex="1"/>
+		<input id="positive-tabindex-input1b" tabindex="1"/>
+		<input id="positive-tabindex-input2a" tabindex="2"/>
+		<input id="positive-tabindex-input2b" tabindex="2"/>
+	</div>
+
+	<div id="positive-tabindex">
+		<input id="positive-tabindex-input3a" tabindex="3"/>
+		<input id="positive-tabindex-input3b" tabindex="3"/>
+		<input id="positive-tabindex-input4a" tabindex="4"/>
+		<input id="positive-tabindex-input4b" tabindex="4"/>
+	</div>
+
+	<div id="skip-minus-one">
+		<input id="minus-one-input1" tabindex="-1"/>
+		<input id="not-minus-one-input"/>
+		<input id="minus-one-input2" tabindex="-1"/>
+	</div>
+
+	<div id="descend">
+		<input disabled="disabled"/>
+		<div>
+			<input disabled="disabled"/>
+			<div>
+				<input disabled="disabled"/>
+			</div>
+		</div>
+		<div>
+			<input disabled="disabled"/>
+			<div>
+				<input disabled="disabled"/>
+			</div>
+			<div>
+				<input id="child-input1"/>
+			</div>
+			<div>
+				<input id="child-input2"/>
+			</div>
+		</div>
+		<div>
+			<div>
+				<input disabled="disabled"/>
+			</div>
+			<input disabled="disabled"/>
+		</div>
+		<input disabled="disabled"/>
+	</div>
+
+	<div id="outer-inner-container">
+		<div id="outer1" tabindex="0">
+			<div id="inner1" tabindex="0"></div>
+		</div>
+		<div id="outer2" tabindex="0">
+			<div id="inner2" tabindex="0"></div>
+		</div>
+	</div>
+
+	<div id="hidden-element-container">
+		<div id="hidden-element" tabindex="0" style="visibility: hidden;">
+		</div>
+	</div>
+
+	<div id="container-with-hidden-containers">
+		<div id="hidden-container-tabindex-zero" tabindex="0" style="visibility: hidden;">
+			<div id="inside-hidden-container-tabindex-zero" tabindex="0">
+			</div>
+		</div>
+
+		<div id="hidden-container-no-tabindex" style="visibility: hidden;">
+			<div id="inside-hidden-container-no-tabindex" tabindex="0">
+			</div>
+		</div>
+	</div>
+
+	<div id="display-none-element-container">
+		<div id="display-none-element" tabindex="0" style="display: none;">
+		</div>
+	</div>
+
+	<div id="container-with-display-none-containers">
+		<div id="display-none-container-tabindex-zero" tabindex="0" style="display: none;">
+			<div id="inside-display-none-container-tabindex-zero" tabindex="0">
+			</div>
+		</div>
+
+		<div id="display-none-container-no-tabindex" style="display: none;">
+			<div id="inside-display-none-container-no-tabindex" tabindex="0">
+			</div>
+		</div>
+	</div>
+
+	<div id="multiDigitTabIndex">
+		<input name="one" tabindex=1>
+		<input name="two" tabindex=2>
+		<input name="three" tabindex=3>
+		<input name="four" tabindex=4>
+		<input name="five" tabindex=5>
+		<input name="six" tabindex=6>
+		<input name="seven" tabindex=7>
+		<input name="eight" tabindex=8>
+		<input name="nine" tabindex=9>
+		<input name="ten" tabindex=10>
+		<input name="eleven" tabindex=11>
+	</div>
+</body>
+</html>
diff --git a/dijit/tests/boilerplate.js b/dijit/tests/boilerplate.js
new file mode 100644
index 0000000..2ae1d67
--- /dev/null
+++ b/dijit/tests/boilerplate.js
@@ -0,0 +1,137 @@
+// module:
+//		dijit/tests/boilerplate
+// description:
+//		A <script src="boilerplate.js"> on your test page will:
+//
+//		- load claro or a specified theme
+//		- load the loader (i.e. define the require() method)
+//
+//		By URL flags you can specify the theme,
+//		and optionally enable RTL (right to left) mode, and/or dj_a11y (high-
+//		contrast/image off emulation) ... probably not a genuine test for a11y.
+//
+//		You should NOT be using this in a production environment.  Include
+//		your css and set your classes manually:
+//
+//		<style type="text/css">
+//			@import "dijit/themes/claro/document.css";
+//		</style>
+//		<link id="themeStyles" rel="stylesheet" href="dijit/themes/claro/claro.css"/>
+//		<script type="text/javascript" src="dojo/dojo.js"></script>
+//		...
+//		<body class="claro">
+
+var dir = "",
+	theme = "claro",
+	testMode = null;
+
+dojoConfig = {
+	async: true,
+	isDebug: true
+};
+
+// Parse the URL, get parameters
+if(window.location.href.indexOf("?") > -1){
+	var str = window.location.href.substr(window.location.href.indexOf("?")+1).split(/#/);
+	var ary  = str[0].split(/&/);
+	for(var i = 0; i < ary.length; i++){
+		var split = ary[i].split("="),
+			key = split[0],
+			value = (split[1]||'').replace(/[^\w]/g, "");	// replace() to prevent XSS attack
+		switch(key){
+			case "locale":
+				// locale string | null
+				dojoConfig.locale = value;
+				break;
+			case "dir":
+				// rtl | null
+				dir = value;
+				break;
+			case "theme":
+				// tundra | soria | nihilo | claro | null
+				theme = /null|none/.test(value) ? null : value;
+				break;
+			case "a11y":
+				if(value){ testMode = "dj_a11y"; }
+				break;
+		}
+	}
+}
+
+// Find the <script src="boilerplate.js"> tag, to get test directory and data-dojo-config argument
+var scripts = document.getElementsByTagName("script"), script, testDir;
+for(i = 0; script = scripts[i]; i++){
+	var src = script.getAttribute("src"),
+		match = src && src.match(/(.*|^)boilerplate\.js/i);
+	if(match){
+		// Sniff location of dijit/tests directory relative to this test file.   testDir will be an empty string if it's
+		// the same directory, or a string including a slash, ex: "../", if the test is in a subdirectory.
+		testDir = match[1];
+
+		// Sniff configuration on attribute in script element.
+		// Allows syntax like <script src="boilerplate.js data-dojo-config="parseOnLoad: true">, where the settings
+		// specified override the default settings.
+		var attr = script.getAttribute("data-dojo-config");
+		if(attr){
+			var overrides = eval("({ " + attr + " })");
+			for(var key in overrides){
+				dojoConfig[key] = overrides[key];
+			}
+		}
+		break;
+	}
+}
+
+// Output the boilerplate text to load the theme CSS
+if(theme){
+	var themeDir = testDir + "../themes/" + theme + "/";
+	document.write([
+		'<style type="text/css">',
+			theme == "claro" ? '@import "' + themeDir + 'document.css";' : "",
+			'@import "' + testDir + 'css/dijitTests.css";',
+		'</style>',
+		'<link id="themeStyles" rel="stylesheet" href="' + themeDir + theme + '.css"/>'
+	].join("\n"));
+}
+
+// Output the boilerplate text to load the loader, and to do some initial manipulation when the page finishes loading
+// For 2.0 this should be changed to require the loader (ex: requirejs) directly, rather than dojo.js.
+document.write('<script type="text/javascript" src="' + testDir + '../../dojo/dojo.js"></script>');
+
+// On IE9 the following inlined script will run before dojo has finished loading, leading to an error because require()
+// isn't defined yet.  Workaround it by putting the code in a separate file.
+//document.write('<script type="text/javascript">require(["dojo/domReady!"], boilerplateOnLoad);</script>');
+document.write('<script type="text/javascript" src="' + testDir + 'boilerplateOnload.js"></script>');
+
+function boilerplateOnLoad(){
+	// This function is the first registered domReady() callback, allowing us to setup
+	// theme stuff etc. before the widgets start instantiating.
+
+	// theme (claro, tundra, etc.)
+	if(theme){
+		// Set <body> to point to the specified theme
+		document.body.className = theme;
+	}
+
+	// a11y (flag for faux high-contrast testing)
+	if(testMode){
+		document.body.className += " " + testMode;
+	}
+
+	// BIDI
+	if(dir == "rtl"){
+		// set dir=rtl on <html> node
+		document.body.parentNode.setAttribute("dir", "rtl");
+
+		require(["dojo/query!css2"], function(query){
+			// pretend all the labels are in an RTL language, because
+			// that affects how they lay out relative to inline form widgets
+			query("label").attr("dir", "rtl");
+		});
+	}
+
+	// parseOnLoad: true requires that the parser itself be loaded.
+	if(dojoConfig.parseOnLoad){
+		require(["dojo/parser"]);
+	}
+}
diff --git a/dijit/tests/boilerplateOnload.js b/dijit/tests/boilerplateOnload.js
new file mode 100644
index 0000000..e12fbf2
--- /dev/null
+++ b/dijit/tests/boilerplateOnload.js
@@ -0,0 +1,3 @@
+// Part of boilerplate.js but need to put it in a separate file for IE9, so it doesn't run until dojo has finished
+// loading and require is defined
+require(["dojo/domReady!"], boilerplateOnLoad);
diff --git a/dijit/tests/css/dijitTests.css b/dijit/tests/css/dijitTests.css
index 33efb89..df16d1e 100644
--- a/dijit/tests/css/dijitTests.css
+++ b/dijit/tests/css/dijitTests.css
@@ -1,13 +1,13 @@
 /* Test file styles for Dijit widgets */
 
 body {
-	background:#fff url("../images/testsBodyBg.gif") repeat-x top left;
-	padding:2em 2em 2em 2em;
+	background: #fff url("../images/testsBodyBg.gif") repeat-x top left;
+	padding: 20px;
 }
 
 h1.testTitle {
-	font-size:2em;
-	margin:0 0 1em 0;
+	font-size: 2em;
+	margin: 0 0 1em 0;
 }
 
 /* Icons used in the tests */
diff --git a/dijit/tests/delay.js b/dijit/tests/delay.js
index 39090e0..820a7c7 100644
--- a/dijit/tests/delay.js
+++ b/dijit/tests/delay.js
@@ -6,6 +6,9 @@
 //		(Used by _testCommon.html)
 //
 //		Usage: ready(1, function(){ require(["dijit/tests/delay!300"]); });
+
+// TODO: remove for 2.0, it's only used by _testCommon.js which will also be removed.
+
 define({
 	load: function(delay, req, loaded){
 		setTimeout(function(){
diff --git a/dijit/tests/editor/BackForwardState.html b/dijit/tests/editor/BackForwardState.html
index 4ea1d6e..46f4068 100644
--- a/dijit/tests/editor/BackForwardState.html
+++ b/dijit/tests/editor/BackForwardState.html
@@ -1,32 +1,23 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Back/Forward Button Test</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/Editor",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
 
-<body class="claro">
+<body class="claro" role="main">
 	<h1>Editor back/forward button value restore tests</h1>
 	<p>
 		Try typing something into the editors below, and then click the page refrsh link or the back then forward buttons.
@@ -40,8 +31,8 @@
 	</ol>
 	<p><a href="BackForwardStateHelper.html" id="away">Navigate to another page</a></p>
 
-	<div id="editor0" data-dojo-type="dijit.Editor" data-dojo-props='name:"editor0", height:"100", plugins:[]'>editor0 original contents</div>
-	<div id="editor1" data-dojo-type="dijit.Editor" data-dojo-props='name:"editor1", height:"100", plugins:[]'>editor1 original contents</div>
+	<div id="editor0" data-dojo-type="dijit/Editor" aria-label="editor0" data-dojo-props='name:"editor0", height:"100", plugins:[]'>editor0 original contents</div>
+	<div id="editor1" data-dojo-type="dijit/Editor" aria-label="editor1" data-dojo-props='name:"editor1", height:"100", plugins:[]'>editor1 original contents</div>
 	<textarea id="dijit._editor.RichText.value" style="display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;"></textarea>
 </body>
 </html>
diff --git a/dijit/tests/editor/BackForwardStateHelper.html b/dijit/tests/editor/BackForwardStateHelper.html
index dcd034a..ac1a046 100644
--- a/dijit/tests/editor/BackForwardStateHelper.html
+++ b/dijit/tests/editor/BackForwardStateHelper.html
@@ -1,3 +1,7 @@
+<!DOCTYPE html>
+<html lang="en">
+<head><title>Back/forward test helper page</title></head>
+<body role="main">
 <h1>Back/forward test helper page</h1>
 <p>
 	You've navigated to this page from <a href="BackForwardState.html">backForward.html</a>.
@@ -8,4 +12,6 @@
 	Note that pressing the link above will not work, since the browser doesn't consider it
 	as "returning" to the previous page.
 </p>
-<a href="javascript:history.go(-1)" id="back">Go Back</a>
\ No newline at end of file
+<a href="javascript:history.go(-1)" id="back">Go Back</a>
+</body>
+</html>
\ No newline at end of file
diff --git a/dijit/tests/editor/Editor_IE8Compat.html b/dijit/tests/editor/Editor_IE8Compat.html
new file mode 100644
index 0000000..9e9c1eb
--- /dev/null
+++ b/dijit/tests/editor/Editor_IE8Compat.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<meta http-equiv="X-UA-Compatible" content="IE=8">
+		<title>Demo: Basic Editor</title>
+		<link rel="stylesheet" href="../../themes/claro/claro.css" />
+		<script src="../../../dojo/dojo.js"
+				data-dojo-config="async: true, parseOnLoad: true"></script>
+		<script>
+			// Include the class
+			require(["dojo/has", "dijit/Editor", "dojo/parser", "dojo/domReady!"], function(has){
+				console.log("has(ie) == " + has("ie"));
+			});
+		</script>
+	</head>
+	<body class="claro" role="main">
+		<h1>Test of Editor on IE9 in IE8 Compatibility mode</h1>
+		<div data-dojo-type="dijit.Editor" aria-label="editor1" id="editor1"></div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dijit/tests/editor/Editor_stylesheet.html b/dijit/tests/editor/Editor_stylesheet.html
new file mode 100644
index 0000000..866e956
--- /dev/null
+++ b/dijit/tests/editor/Editor_stylesheet.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<title>Editor StyleSheet Test</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+
+	<script type="text/javascript" src="../boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/parser",
+			"dojo/query",
+			"dijit/registry",
+			"dijit/Editor",
+			"dojo/NodeList-dom",	// style()
+			"dojo/domReady!"
+		], function(doh, parser, query, registry){
+
+			var editor;
+
+			doh.register("setup", [
+				function parse(){
+					parser.parse();
+					editor = registry.byId("editor");
+				},
+				{
+					name: "wait for load",
+					timeout: 5000,
+					runTest: function(){
+						// Editor.onLoadDeferred doesn't seem good enough, editor.window is still unset
+						// after it fires
+						var d = new doh.Deferred();
+						console.log("initially, editor.window is", editor.window);
+						editor.onLoadDeferred.then(function(){
+							var handle = setInterval(function(){
+								if(editor.window){
+									clearInterval(handle);
+									d.callback(true);
+								}
+							}, 50);
+						});
+						return d;
+					}
+				}
+			]);
+
+			doh.register("stylesheets", [
+				{
+					name: "add sheet",
+					runTest: function(){
+						editor.addStyleSheet('test_editor.css');
+
+						// Wait for stylesheet to take effect and then check if <h1> has border.
+						// Not checking background color because it could be "red" or #FF0000 or rgb(...
+						var d = new doh.Deferred();
+						setTimeout(d.getTestCallback(function(){
+							var h1styles = query("h1", editor.window.document).style("borderTopStyle");
+							doh.is(1, h1styles.length, "found h1");
+							doh.is("solid", h1styles[0], "h1 border");
+						}), 250);
+						return d;
+					}
+				},
+				{
+					name: "remove sheet",
+					runTest: function(){
+						editor.removeStyleSheet('test_editor.css');
+
+						var h1styles = query("h1", editor.window.document).style("borderTopWidth");
+
+						// Wait for stylesheet removal to take effect and then check if <h1> has border.
+						// Not checking background color because it could be "red" or #FF0000 or rgb(...
+						// Not checking border-width because on IE it's 4px, but border-style is none
+						// (which means that there's really no border).
+						var d = new doh.Deferred();
+						setTimeout(d.getTestCallback(function(){
+							var h1styles = query("h1", editor.window.document).style("borderTopStyle");
+							doh.is(1, h1styles.length, "found h1");
+							doh.is("none", h1styles[0], "h1 border style");
+						}), 250);
+						return d;
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro" role="main">
+<script type="dojo/require">
+	registry: "dijit/registry"
+</script>
+<p>Turning on the stylesheet should make header red</p>
+<div id="editor" data-dojo-type="dijit/Editor" aria-label="editor" data-dojo-props='name:"field"'>
+	<h1>Adding stylesheet should make my background red</h1>
+	<h2>I shouldn't change</h2>
+</div>
+<button id="addStyleSheet" onclick="registry.byId('editor').addStyleSheet('test_editor.css');">add stylesheet</button>
+<button id="removeStyleSheet" onclick="registry.byId('editor').removeStyleSheet('test_editor.css');">remove stylesheet</button>
+
+</body>
+</html>
diff --git a/dijit/tests/editor/EnterKeyHandling.html b/dijit/tests/editor/EnterKeyHandling.html
index 8167821..ef05299 100644
--- a/dijit/tests/editor/EnterKeyHandling.html
+++ b/dijit/tests/editor/EnterKeyHandling.html
@@ -1,85 +1,77 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.ViewSource");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/_editor/RichText",
+			"dijit/Editor",
+			"dijit/_editor/plugins/ViewSource",
+			"dojo/domReady!"
+		], function(parser, RichText){
+			// Make editor indent work for paragraphs in addition to lists
+			var oldQCE = RichText.prototype.queryCommandEnabled;
+			RichText.prototype.queryCommandEnabled = function(command){
+				return command == 'indent' || command == 'outdent' || oldQCE.call(this, command);
+			};
 
-		// Make editor indent work for paragraphs in addition to lists
-		var oldQCE = dijit._editor.RichText.prototype.queryCommandEnabled;
-		dijit._editor.RichText.prototype.queryCommandEnabled = function(command){
-			return command == 'indent' || command == 'outdent' || oldQCE.call(this, command);
-		};
+			parser.parse();
+		});
 	</script>
 </head>
 
-<body class="claro">
+<body class="claro" role="main">
 	<h1>Test file for Editor EnterKeyHandling plugin</h1>
 
 	<h2>blockNodeforEnter='BR'</h2>
-	<div id="br" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"BR"}, "viewsource"]
+	<div id="br" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor_br", plugins:[{name:"dijit/_editor/plugins/EnterKeyHandling", blockNodeForEnter:"BR"}, "viewsource"]
 		'><p>para 1<br>line 2</p>
 		<p>para 2<br>line 2</p>
  	</div>
 
  	<h2>blockNodeforEnter='DIV'</h2>
-	<div id="div" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]
+	<div id="div" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor_div", plugins:[{name:"dijit/_editor/plugins/EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]
 		'><p>para 1<br>line 2</p>
 		<p>para 2<br>line 2</p>
  	</div>
 
  	<h2>blockNodeforEnter='DIV' split test</h2>
-	<div id="div2" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]'>
+	<div id="div2" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor_div2", plugins:[{name:"dijit/_editor/plugins/EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]'>
 		<div> </div>
-		<div id="lineOne">this is a line of text.  It <b id="boldLine0">is</b> intended to be split up by pressing enter.</div>
+		<div id="lineOne">this is a line of text.  It <b id="boldLine0">IS</b> intended to be split up by pressing enter.</div>
 		<div> </div>
  	</div>
 
  	<h2>blockNodeforEnter='DIV' split test style clone</h2>
-	<div id="div3" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]'>
+	<div id="div3" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor_div3", plugins:[{name:"dijit/_editor/plugins/EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]'>
 		<div> </div>
-		<div id="lineOne">this is a line of text.  It <b id="boldLine1" style="font-size: 4em">is</b> intended to be split up by pressing enter.</div>
+		<div id="lineOne">this is a line of text.  It <b id="boldLine1" style="font-size: 4em">IS</b> intended to be split up by pressing enter.</div>
 		<div> </div>
  	</div>
 
  	<h2>blockNodeforEnter='DIV' split test font clone</h2>
-	<div id="div4" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]'>
+	<div id="div4" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor_div4", plugins:[{name:"dijit/_editor/plugins/EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]'>
 		<div> </div>
-		<div id="lineOne">this is a line of text.  It <font id="fontLine1" size="5">is</font> intended to be split up by pressing enter.</div>
+		<div id="lineOne">this is a line of text.  It <font id="fontLine1" size="5">IS</font> intended to be split up by pressing enter.</div>
 		<div> </div>
  	</div>
 
  	<h2>blockNodeforEnter='P'</h2>
-	<div id="p" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"P"}, "viewsource"]
+	<div id="p" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor_p", plugins:[{name:"dijit/_editor/plugins/EnterKeyHandling", blockNodeForEnter:"P"}, "viewsource"]
 		'><p>para 1<br>line 2</p>
 		<p>para 2<br>line 2</p>
  	</div>
  	
 	<h2>blockNodeforEnter='P' split test</h2>
-	<div id="p2" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"P"}, "viewsource"]'>
+	<div id="p2" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor_p2", plugins:[{name:"dijit/_editor/plugins/EnterKeyHandling", blockNodeForEnter:"P"}, "viewsource"]'>
 		<p> </p>
-		<p id="lineOne">this is a line of text.  It <b id="boldLine2">is</b> intended to be split up by pressing enter.</p>
+		<p id="lineOne">this is a line of text.  It <b id="boldLine2">IS</b> intended to be split up by pressing enter.</p>
 		<p> </p>
  	</div>
 </body>
diff --git a/dijit/tests/editor/html.html b/dijit/tests/editor/html.html
new file mode 100644
index 0000000..36d9e49
--- /dev/null
+++ b/dijit/tests/editor/html.html
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<title>html utility tests</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+
+	<script type="text/javascript" src="../boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require(["doh/runner", "dojo/dom", "dojo/_base/lang", "dojo/sniff", "dijit/_editor/html", "dojo/domReady!"],
+				function(doh, dom, lang, has, htmlAPI){
+
+			doh.register("getNodeHtml", [
+				function general(){
+					var html = htmlAPI.getNodeHtml(dom.byId("general"));
+					html = html.replace(/\s+/g, " ").replace(/>\s*</g, "><").replace(/10%;"/, '10%"');
+					doh.is('<div id="general"><img alt="" base="foo" style="width: 10%; height: 10%" /><span><i>hello<b>world</b></i></span></div>', html);
+				},
+				function tagClose(){
+					var html = htmlAPI.getNodeHtml(dom.byId("tagclosure"));
+					html = html.replace(/\s+/g, " ").replace(/>\s*</g, "><");
+					doh.is('<div id="tagclosure"><span><span></span><br /><hr /></span></div>', html);
+				},
+				function djrealurl(){
+					var html = htmlAPI.getNodeHtml(dom.byId("djrealurl"));
+					html = html.replace(/\s+/g, " ").replace(/>\s*</g, "><");
+					doh.is('<div id="djrealurl"><a href="real">hi</a><img alt="" src="real" /></div>', html);
+				}
+			]);
+
+			doh.register("getChildrenHtml", [
+				function general(){
+					var html = htmlAPI.getChildrenHtml(dom.byId("general"));
+					html = lang.trim(html.replace(/\s+/g, " ").replace(/>\s*</g, "><").replace(/10%;"/, '10%"'));
+					doh.is('<img alt="" base="foo" style="width: 10%; height: 10%" /><span><i>hello<b>world</b></i></span>', html);
+				},
+				function tagClose(){
+					var html = htmlAPI.getChildrenHtml(dom.byId("tagclosure"));
+					html = lang.trim(html.replace(/\s+/g, " ").replace(/>\s*</g, "><"));
+					doh.is('<span><span></span><br /><hr /></span>', html);
+				},
+				function djrealurl(){
+					var html = htmlAPI.getChildrenHtml(dom.byId("djrealurl"));
+					html = lang.trim(html.replace(/\s+/g, " ").replace(/>\s*</g, "><"));
+					doh.is('<a href="real">hi</a><img alt="" src="real" />', html);
+				},
+				function specialchars(){
+					var html = htmlAPI.getChildrenHtml(dom.byId("specialchars"));
+					html = lang.trim(html.replace(/\s+/g, " ").replace(/>\s*</g, "><"));
+					doh.is('hello&goodbye<span>3>2</span>', html);
+				},
+				function image(){
+					var html = htmlAPI.getChildrenHtml(dom.byId("image"));
+					html = lang.trim(html.replace(/\s+/g, " ").replace(/>\s*</g, "><"));
+					doh.is('<img alt="alt text" height="88" id="bibli_WR4479" src="http://acme.com/logo.png" title="test" width="150" />', html)
+				}
+			]);
+
+			// This is testing a bug with IE and malformed HTML.   Since the HTML is malformed different
+			// browsers get different results (but still results that can't be considered errors).   The
+			// only browsers that get error results are IE.   Thus limiting the test to IE6-8.
+			if(has("ie") < 9){
+				doh.register("IE6-8", [
+					function graph(){
+						var html = htmlAPI.getChildrenHtml(dom.byId("graph"));
+						html = lang.trim(html.replace(/\s+/g, " ").replace(/>\s*</g, "><")).toUpperCase();
+						doh.is('<FONT SIZE="2"><P>123<FONT SIZE="6">456</FONT><FONT SIZE="2">789</FONT></P></FONT>', html);
+					}
+				]);
+			}
+
+			doh.register("escapeXML", [
+				function regular(){
+					var escaped = htmlAPI.escapeXml("hello<b>\"&'</b>goodbye");
+					doh.is("hello<b>"&'</b>goodbye", escaped);
+				},
+				function noSingleQuote(){
+					var escaped = htmlAPI.escapeXml("hello<b>\"&'</b>goodbye", true);
+					doh.is("hello<b>"&'</b>goodbye", escaped);
+				}
+			]);
+			doh.run();
+		});
+	</script>
+</head>
+<body role="main">
+
+<!--
+this tests that tag case is normalized, and that attributes are sorted
+(the style vs. base attributes for the <img>
+-->
+<div id="general">
+	<imG alt="" style="width: 10%; height: 10%" base="foo">
+	<SPAN><i>hello<b>world</b></i></SPAN>
+</div>
+
+<!--
+testing tag closure: br, hr, etc close with /> but others like <span> close with </span>
+-->
+<div id="tagclosure">
+<span><span></span><br><hr></span>
+</div>
+
+<!--
+src and href attributes get converted to _djrealurl, which is dropped
+-->
+<div id="djrealurl">
+<a href="javascript:1" _djrealurl="real">hi</a>
+<img alt="" src="javascript:1" _djrealurl="real">
+</div>
+
+<div id="specialchars">
+	hello&goodbye<span>3>2</span>
+</div>
+</body>
+
+<!--
+image tag (was problem on IE9, see #15032)
+-->
+<div id="image">
+	<img alt="alt text"  width="150" height="88" id="bibli_WR4479" src="http://acme.com/logo.png" title="test" />
+</div>
+
+<!--
+Graph test, for bug where IE has nodes with multiple parents, see #8363
+-->
+<div id="graph">
+<FONT size=2><P>123</FONT><FONT size=6>456</FONT><FONT size=2>789</P></FONT>
+</div>
+
+</html>
diff --git a/dijit/tests/editor/module.js b/dijit/tests/editor/module.js
index 89e8728..3b28818 100755
--- a/dijit/tests/editor/module.js
+++ b/dijit/tests/editor/module.js
@@ -1,39 +1,42 @@
-dojo.provide("dijit.tests.editor.module");
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
 
-try{
-	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
+	// inline doh tests
+	doh.register("editor.nls_8859-2", require.toUrl("./nls_8859-2.html"), 999999);
+	doh.register("editor.nls_sjis", require.toUrl("./nls_sjis.html"), 999999);
+	doh.register("editor.nls_utf8", require.toUrl("./nls_utf8.html"), 999999);
+	doh.register("editor.Editor_stylesheet", require.toUrl("./Editor_stylesheet.html"), 999999);
+	doh.register("editor.html", require.toUrl("./html.html"), 999999);
 
-	//inline doh tests
-	doh.registerUrl("dijit.tests.editor.nls_8859-2", dojo.moduleUrl("dijit","tests/editor/nls_8859-2.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.nls_sjis", dojo.moduleUrl("dijit","tests/editor/nls_sjis.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.nls_utf8", dojo.moduleUrl("dijit","tests/editor/nls_utf8.html"+userArgs), 999999);
-	
 	// Base editor functionality
-	doh.registerUrl("dijit.tests.editor.robot.Editor_mouse", dojo.moduleUrl("dijit","tests/editor/robot/Editor_mouse.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.robot.Editor_a11y", dojo.moduleUrl("dijit","tests/editor/robot/Editor_a11y.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.robot.Misc", dojo.moduleUrl("dijit","tests/editor/robot/Editor_misc.html"+userArgs), 999999);
+	doh.register("editor.robot.Editor_mouse", require.toUrl("./robot/Editor_mouse.html"), 999999);
+	doh.register("editor.robot.Editor_a11y", require.toUrl("./robot/Editor_a11y.html"), 999999);
+	doh.register("editor.robot.Misc", require.toUrl("./robot/Editor_misc.html"), 999999);
 
 	// Plugins
-	doh.registerUrl("dijit.tests.editor.robot.CustomPlugin", dojo.moduleUrl("dijit","tests/editor/robot/CustomPlugin.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.robot.EnterKeyHandling", dojo.moduleUrl("dijit","tests/editor/robot/EnterKeyHandling.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.robot.FullScreen", dojo.moduleUrl("dijit","tests/editor/robot/Editor_FullScreen.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.robot.ViewSource", dojo.moduleUrl("dijit","tests/editor/robot/Editor_ViewSource.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.robot.NewPage", dojo.moduleUrl("dijit","tests/editor/robot/Editor_NewPage.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.robot.LinkDialog", dojo.moduleUrl("dijit","tests/editor/robot/Editor_LinkDialog.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.robot.FontChoice", dojo.moduleUrl("dijit","tests/editor/robot/Editor_FontChoice.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.robot.ToggleDir", dojo.moduleUrl("dijit","tests/editor/robot/ToggleDir.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.robot.ToggleDir_rtl", dojo.moduleUrl("dijit","tests/editor/robot/ToggleDir_rtl.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.editor.robot.TabIndent", dojo.moduleUrl("dijit","tests/editor/robot/TabIndent.html"+userArgs), 999999);
-	
-	if(!dojo.isWebKit){
+	doh.register("editor.robot.CustomPlugin", require.toUrl("./robot/CustomPlugin.html"), 999999);
+	doh.register("editor.robot.EnterKeyHandling", require.toUrl("./robot/EnterKeyHandling.html"), 999999);
+	doh.register("editor.robot.FullScreen", require.toUrl("./robot/Editor_FullScreen.html"), 999999);
+	doh.register("editor.robot.ViewSource", require.toUrl("./robot/Editor_ViewSource.html"), 999999);
+	doh.register("editor.robot.NewPage", require.toUrl("./robot/Editor_NewPage.html"), 999999);
+	doh.register("editor.robot.LinkDialog", require.toUrl("./robot/Editor_LinkDialog.html"), 999999);
+	doh.register("editor.robot.FontChoice", require.toUrl("./robot/Editor_FontChoice.html"), 999999);
+	doh.register("editor.robot.ToggleDir", require.toUrl("./robot/ToggleDir.html"), 999999);
+	doh.register("editor.robot.ToggleDir_rtl", require.toUrl("./robot/ToggleDir_rtl.html"), 999999);
+	doh.register("editor.robot.TabIndent", require.toUrl("./robot/TabIndent.html"), 999999);
+
+	if(!has("webkit")){
 		// The back button on webkit is URL for the browser itself, restarting the entire test suite,
 		// rather than just for the iframe holding the test file (BackForwardState.html and BackForwardStateHelper.html)
-		doh.registerUrl("dijit.tests.editor.robot.BackForwardState", dojo.moduleUrl("dijit","tests/editor/robot/BackForwardState.html"+userArgs), 999999);
+		doh.register("editor.robot.BackForwardState", require.toUrl("./robot/BackForwardState.html"), 999999);
+	}
+
+	// Special test for IE9 in IE8 compat mode (#14900)
+	if(has("ie") == 9){
+		doh.register("editor.robot.Editor_IE8Compat", require.toUrl("./robot/Editor_IE8Compat.html"), 999999);
+
 	}
 
-}catch(e){
-	doh.debug(e);
-}
+});
 
 
 
diff --git a/dijit/tests/editor/nls_8859-2.html b/dijit/tests/editor/nls_8859-2.html
index 8b22892..9ebc3b8 100644
--- a/dijit/tests/editor/nls_8859-2.html
+++ b/dijit/tests/editor/nls_8859-2.html
@@ -1,36 +1,26 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<title>Editor Test</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-2"/>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 		
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit.dijit");
-		dojo.require("dijit.Editor");
-		dojo.require("dojo.parser");
+		require([
+			"doh/runner",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/Editor",
+			"dojo/domReady!"
+		], function(doh, parser, registry){
 		
-		dojo.ready(function(){
-
 			doh.register("parse", function(){
-				dojo.parser.parse();
+				parser.parse();
 			});
 
 
-			 doh.register("test value", [
+			doh.register("test value", [
 				{
 					name: "test value",
 					timeout: 10000,
@@ -39,14 +29,14 @@
 
 						
 						setTimeout(d.getTestCallback(function(){
-							var value = dijit.byId('editor').get('value');
+							var value = registry.byId('editor').get('value');
 							doh.is("�󱶳�����ӣ�������", value );
 							
-							dijit.byId('editor').set('value', '\u65e5\u672c\u8a9e');
-							value = dijit.byId('editor').get('value');
+							registry.byId('editor').set('value', '\u65e5\u672c\u8a9e');
+							value = registry.byId('editor').get('value');
 							doh.is("\u65e5\u672c\u8a9e", value );
 
-							dijit.byId('editor').set('value', '�󱶳�����ӣ�������');
+							registry.byId('editor').set('value', '�󱶳�����ӣ�������');
 						}), 2000);
 
 						return d;
@@ -58,7 +48,10 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
+<script type="dojo/require">
+	registry: "dijit/registry"
+</script>
 <form method="post">
 <p>
 Plain text: �󱶳�����ӣ�������
@@ -67,10 +60,10 @@ Plain text: 
 <p>
 Same text should show up in the Editor:
 </p>
-<div id="editor" data-dojo-type="dijit.Editor" data-dojo-props='name:"field"'>�󱶳�����ӣ�������</div>
+<div id="editor" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor", name:"field"'>�󱶳�����ӣ�������</div>
 <input type="submit" value="Save" />
-<button type=button onclick="console.log(dijit.byId('editor').get('value'))">getValue</button>
-<button type=button onclick="dijit.byId('editor').set('value', '\u65e5\u672c\u8a9e')">set value to &#x65e5;&#x672c;&#x8a9e;</button>
+<button type=button onclick="console.log(registry.byId('editor').get('value'))">getValue</button>
+<button type=button onclick="registry.byId('editor').set('value', '\u65e5\u672c\u8a9e')">set value to &#x65e5;&#x672c;&#x8a9e;</button>
 
 </form>
 </body>
diff --git a/dijit/tests/editor/nls_sjis.html b/dijit/tests/editor/nls_sjis.html
index c998f1e..e8a9302 100644
--- a/dijit/tests/editor/nls_sjis.html
+++ b/dijit/tests/editor/nls_sjis.html
@@ -1,36 +1,26 @@
 <!DOCTYPE html>
-<html>
+<html lang="jp">
 <head>
 	<title>Editor Test</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=Shift-JIS"/>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 		
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit.dijit");
-		dojo.require("dijit.Editor");
-		dojo.require("dojo.parser");
-		
-		dojo.ready(function(){
+		require([
+			"doh/runner",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/Editor",
+			"dojo/domReady!"
+		], function(doh, parser, registry){
 
 			doh.register("parse", function(){
-				dojo.parser.parse();
+				parser.parse();
 			});
 
 
-			 doh.register("test value", [
+			doh.register("test value", [
 				{
 					name: "test value",
 					timeout: 10000,
@@ -39,14 +29,14 @@
 
 						
 						setTimeout(d.getTestCallback(function(){
-							var value = dijit.byId('editor').get('value');
+							var value = registry.byId('editor').get('value');
 							doh.is("���{��", value );
 							
-							dijit.byId('editor').set('value', '����ɂ���');
-							value = dijit.byId('editor').get('value');
+							registry.byId('editor').set('value', '����ɂ���');
+							value = registry.byId('editor').get('value');
 							doh.is("����ɂ���", value );
 
-							dijit.byId('editor').set('value', '���{��');
+							registry.byId('editor').set('value', '���{��');
 						}), 2000);
 
 						return d;
@@ -58,7 +48,10 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
+<script type="dojo/require">
+	registry: "dijit/registry"
+</script>
 <form method="get">
 <p>
 Plain text: ���{��
@@ -67,10 +60,10 @@ Plain text: 
 <p>
 Same text should show up in the Editor:
 </p>
-<div id="editor" data-dojo-type="dijit.Editor" data-dojo-props='name:"field"'>���{��</div>
+<div id="editor" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor", name:"field"'>���{��</div>
 <input type="submit" value="Save" />
-<button type=button onclick="console.log(dijit.byId('editor').get('value'))">getValue</button>
-<button type=button onclick="dijit.byId('editor').set('value', '����ɂ���')">set value to ����ɂ���</button>
+<button type=button onclick="console.log(registry.byId('editor').get('value'))">getValue</button>
+<button type=button onclick="registry.byId('editor').set('value', '����ɂ���')">set value to ����ɂ���</button>
 
 </form>
 </body>
diff --git a/dijit/tests/editor/nls_utf8.html b/dijit/tests/editor/nls_utf8.html
index ab60e86..ca69d5f 100644
--- a/dijit/tests/editor/nls_utf8.html
+++ b/dijit/tests/editor/nls_utf8.html
@@ -1,35 +1,25 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<title>Editor Test</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit.dijit");
-		dojo.require("dijit.Editor");
-		dojo.require("dojo.parser");
-		
-		dojo.ready(function(){
+		require([
+			"doh/runner",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/Editor",
+			"dojo/domReady!"
+		], function(doh, parser, registry){
 			 
 			doh.register("parse", function(){
-				dojo.parser.parse();
+				parser.parse();
 			});
 
-			 doh.register("test value", [
+			doh.register("test value", [
 				{
 					name: "test value",
 					timeout: 10000,
@@ -38,14 +28,14 @@
 
 						
 						setTimeout(d.getTestCallback(function(){
-							var value = dijit.byId('editor').get('value');
+							var value = registry.byId('editor').get('value');
 							doh.is("日本語", value );
 							
-							dijit.byId('editor').set('value', 'こんにちは');
-							value = dijit.byId('editor').get('value');
+							registry.byId('editor').set('value', 'こんにちは');
+							value = registry.byId('editor').get('value');
 							doh.is("こんにちは", value );
 							
-							dijit.byId('editor').set('value', '日本語');
+							registry.byId('editor').set('value', '日本語');
 						}), 2000);
 
 						return d;
@@ -57,7 +47,10 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
+<script type="dojo/require">
+	registry: "dijit/registry"
+</script>
 <form method="get">
 <p>
 Plain text: 日本語
@@ -66,10 +59,10 @@ Plain text: 日本語
 <p>
 Same text should show up in the Editor:
 </p>
-<div id="editor" data-dojo-type="dijit.Editor" data-dojo-props='name:"field"'>日本語</div>
+<div id="editor" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor",name:"field"'>日本語</div>
 <input type="submit" value="Save" />
-<button type=button onclick="console.log(dijit.byId('editor').get('value'))">getValue</button>
-<button type=button onclick="dijit.byId('editor').set('value', 'こんにちは')">set value to こんにちは</button>
+<button type=button onclick="console.log(registry.byId('editor').get('value'))">getValue</button>
+<button type=button onclick="registry.byId('editor').set('value', 'こんにちは')">set value to こんにちは</button>
 
 </form>
 </body>
diff --git a/dijit/tests/editor/robot/BackForwardState.html b/dijit/tests/editor/robot/BackForwardState.html
index bf47ebb..f848aff 100644
--- a/dijit/tests/editor/robot/BackForwardState.html
+++ b/dijit/tests/editor/robot/BackForwardState.html
@@ -11,38 +11,38 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			// This page tests that the editor's value won't be lost if the user
-			// accidentlly navigates to a different page, and then returns to the
+			// accidentally navigates to a different page, and then returns to the
 			// page w/the editor by pressing the back button.
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../BackForwardState.html');
 
-				doh.register("back button restore", [
+				var registry;
+				doh.register("setup", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){return w.onLoadDeferred;})
-						    );
-						}
+						runTest: waitForLoad
 					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+					}
+				]);
+
+				doh.register("back button restore", [
 					{
 						name: "set editor value",
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var editor0 = dijit.byId("editor0"),
-								editor1 = dijit.byId("editor1");
+							var editor0 = registry.byId("editor0"),
+								editor1 = registry.byId("editor1");
 
 							doh.is("editor0 original contents", editor0.get('value'));
 							doh.is("editor1 original contents", editor1.get('value'));
@@ -94,13 +94,11 @@
 					{
 						name: "wait for editors to load again",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){return w.onLoadDeferred;})
-						    );
-						}
+						runTest: waitForLoad
+					},
+					function setVarsAgain(){
+						registry = doh.robot.window.require("dijit/registry");
 					},
-
 					{
 						name: "check that editor values restored",
 						timeout: 10000,
@@ -108,8 +106,8 @@
 							var d = new doh.Deferred();
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								var editor0 = dijit.byId("editor0"),
-									editor1 = dijit.byId("editor1");
+								var editor0 = registry.byId("editor0"),
+									editor1 = registry.byId("editor1");
 
 								doh.t(editor0, "editor0 found");
 								doh.is("hello", editor0.get('value'));
diff --git a/dijit/tests/editor/robot/CustomPlugin.html b/dijit/tests/editor/robot/CustomPlugin.html
index ce0519b..4a767ff 100644
--- a/dijit/tests/editor/robot/CustomPlugin.html
+++ b/dijit/tests/editor/robot/CustomPlugin.html
@@ -11,27 +11,30 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
+
+			// TODO: convert this to non-robot test, clicking button using button.click()
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_CustomPlugin.html');
-				
-				var myPlugin;
 
-				doh.register("isVisible", [
+				var registry;
+				doh.register("setup", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
-						}
+						runTest: waitForLoad
 					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+					}
+				]);
+
+				var myPlugin;
+
+				doh.register("isVisible", [
 					function initialConditions(){
 						var pluginIcon = dojo.query(".customIcon")[0];
 						doh.t(isVisible(pluginIcon), "isVisible(pluginIcon)");
@@ -43,7 +46,7 @@
 					{
 						name: "toggleOn",
 						setUp: function(){
-							var editor = dijit.byId("editor1");
+							var editor = registry.byId("editor1");
 							dojo.forEach(editor._plugins, function(plugin){
 								if(plugin.name === "MyPlugin"){
 									myPlugin = plugin;
@@ -52,7 +55,7 @@
 						},
 						timeout: 15000,
 						runTest: function(){
-							var d = new doh.Deferred();	
+							var d = new doh.Deferred();
 							myPlugin.button.focus();
 							doh.robot.mouseMoveAt(myPlugin.button.domNode, 500);
 							doh.robot.mouseClick({left:true}, 500);
@@ -69,7 +72,7 @@
 					{
 						name: "toggleOff",
 						setUp: function(){
-							var editor = dijit.byId("editor1");
+							var editor = registry.byId("editor1");
 							dojo.forEach(editor._plugins, function(plugin){
 								if(plugin.name === "MyPlugin"){
 									myPlugin = plugin;
diff --git a/dijit/tests/editor/robot/Editor_FontChoice.html b/dijit/tests/editor/robot/Editor_FontChoice.html
index e9cc32a..39c6b28 100755
--- a/dijit/tests/editor/robot/Editor_FontChoice.html
+++ b/dijit/tests/editor/robot/Editor_FontChoice.html
@@ -11,13 +11,10 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_FontChoice.html');
@@ -27,7 +24,7 @@
 				var value;		// HTML value of editor
 
 				function getPlugin(/*String*/ command){
-					var editor = dijit.byId("editor0");
+					var editor = registry.byId("editor0");
 					var edPlugins = editor._plugins, i;
 					for(i = 0; i < edPlugins.length; i++){
 						var p = edPlugins[i];
@@ -35,19 +32,21 @@
 							return p;
 						}
 					}
-					doh.f(true, "didn't find plugin " + command);
+					throw new Error("didn't find plugin " + command);
 				}
 
-				
-				doh.register("init", {
-					name: "wait for editors to load",
-					timeout: 5000,
-					runTest: function(){
-					    return new dojo.DeferredList(
-					        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-					    );
+
+				var registry;
+				doh.register("setup", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: waitForLoad
+					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
 					}
-				});
+				]);
 
 				// Verify that the formatBlock, fontSize, and fontName
 				// plugins correctly display the format / font-size / font-name of the selected text.
@@ -76,7 +75,7 @@
 									].join(" ").replace(/ +/g, " "),
 								timeout: 20000,
 								setUp: function(){
-									editor = dijit.byId("editor0");
+									editor = registry.byId("editor0");
 									value = editor.get("value");
 								},
 								runTest: function(){
@@ -90,16 +89,14 @@
 	
 									doh.robot.sequence(d.getTestErrback(function(){
 										// Find node w/specified id
-										var node = dojo.withGlobal(editor.window, function(){ return dojo.byId(params.id); });
+										var node = dojo.byId(params.id, editor.document);
 										doh.is(params.id, node && node.id, "found " + params.id);
 
 										// Select the text, collapse to the start of it
 										// Using "dojo.global.dojo" to access the inner dojo, in test_FontChoice.html
 										// (not the one in this file), since that's the one that dijit is referencing.
-										dojo.global.dojo.withGlobal(editor.window, function(){
-											dijit._editor.selection.selectElementChildren(node);
-											dijit._editor.selection.collapse(true);
-										});
+										editor.selection.selectElementChildren(node);
+										editor.selection.collapse(true);
 									}),1000);
 					                doh.robot.sequence(d.getTestErrback(function(){
 										// Make sure states update.
@@ -158,20 +155,18 @@
 	
 									doh.robot.sequence(d.getTestErrback(function(){
 										// Find node
-										var p = dojo.withGlobal(editor.window, function(){ return dojo.byId(params.id); });
+										var p = dojo.byId(params.id, editor.document);
 										doh.is(params.id, p && p.id, "found node");
 	
-										dojo.global.dojo.withGlobal(editor.window, function(){
-											// Select the text, collapse to the start of it
-											dijit._editor.selection.selectElementChildren(p);
-											// Disable collapse.  Webkit changed behavior so it now requires
-											// a selection.
-											if(!dojo.isWebKit){ dijit._editor.selection.collapse(true) }
-											
-											// Set the format / font-size / font-name plugin to the new value
-											// TODO: use mouse/keyboard to set the value
-											fcPlugin.button.set("value", params.to);
-										});
+										// Select the text, collapse to the start of it
+										editor.selection.selectElementChildren(p);
+										// Disable collapse.  Webkit changed behavior so it now requires
+										// a selection.
+										if(!dojo.isWebKit){ editor.selection.collapse(true) }
+
+										// Set the format / font-size / font-name plugin to the new value
+										// TODO: use mouse/keyboard to set the value
+										fcPlugin.button.set("value", params.to);
 									}),1000);
 					                doh.robot.sequence(d.getTestErrback(function(){
 										// Make sure states update.
@@ -198,7 +193,7 @@
 						name: "formatBlock: Verify changing multiple nodes to h3",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor0");
+							editor = registry.byId("editor0");
 							fcPlugin = getPlugin("formatBlock");
 							value = editor.get("value");
 						},
@@ -215,18 +210,16 @@
 							doh.t(fcPlugin !== null, "formatBlock was found");
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								var p = dojo.withGlobal(editor.window, function(){ return dojo.byId("text"); });
+								var p = dojo.byId("text", editor.document);
 								doh.is("text", p && p.id, "found text");
 
-								dojo.global.dojo.withGlobal(editor.window, function(){
-									// Select the text, collapse to the start of it
-									dijit._editor.selection.selectElementChildren(p);
-									dijit._editor.selection.collapse(true);
+								// Select the text, collapse to the start of it
+								editor.selection.selectElementChildren(p);
+								editor.selection.collapse(true);
 
-									// Set the format / font-size / font-name plugin to the new value
-									// TODO: use mouse/keyboard to set the value
-									fcPlugin.button.set("value", "h3");
-								});
+								// Set the format / font-size / font-name plugin to the new value
+								// TODO: use mouse/keyboard to set the value
+								fcPlugin.button.set("value", "h3");
 							}),1000);
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Make sure states update.
@@ -239,18 +232,16 @@
 
 							// Move to the next block and try to change it to h3 too.
 							doh.robot.sequence(d.getTestErrback(function(){
-								var p = dojo.withGlobal(editor.window, function(){ return dojo.byId("text1"); });
+								var p = dojo.byId("text1", editor.document);
 								doh.is("text1", p && p.id, "found text1");
 
-								dojo.global.dojo.withGlobal(editor.window, function(){
-									// Select the text, collapse to the start of it
-									dijit._editor.selection.selectElementChildren(p);
-									dijit._editor.selection.collapse(true);
+								// Select the text, collapse to the start of it
+								editor.selection.selectElementChildren(p);
+								editor.selection.collapse(true);
 
-									// Set the format / font-size / font-name plugin to the new value
-									// TODO: use mouse/keyboard to set the value
-									fcPlugin.button.set("value", "h3");
-								});
+								// Set the format / font-size / font-name plugin to the new value
+								// TODO: use mouse/keyboard to set the value
+								fcPlugin.button.set("value", "h3");
 							}),1000);
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Make sure states update.
@@ -283,7 +274,7 @@
 						name: "formatBlock: Verify single level format is removed (inside format block).",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor0");
+							editor = registry.byId("editor0");
 							fcPlugin = getPlugin("formatBlock");
 							value = editor.get("value");
 						},
@@ -300,13 +291,12 @@
 							doh.t(fcPlugin !== null, "formatBlock was found");
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								var p = dojo.withGlobal(editor.window, function(){ return dojo.byId("text"); });
+								var p = dojo.byId("text", editor.document);
 								doh.is("text", p && p.id, "found text");
-								dojo.global.dojo.withGlobal(editor.window, function(){
-									// Select the text, collapse to the start of it
-									dijit._editor.selection.selectElementChildren(p);
-									dijit._editor.selection.collapse(true);
-								});
+
+								// Select the text, collapse to the start of it
+								editor.selection.selectElementChildren(p);
+								editor.selection.collapse(true);
 							}),1000);
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Make sure states update.
@@ -336,7 +326,7 @@
 						name: "formatBlock: Verify multiple format removal via selection",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor0");
+							editor = registry.byId("editor0");
 							fcPlugin = getPlugin("formatBlock");
 							value = editor.get("value");
 						},
@@ -350,16 +340,15 @@
 							doh.robot.mouseClick({left:true}, 1000);
 
 							// Verify the formatBlock plugin was found
-							doh.t(fcPlugin !== null, "formatBlock was found");
+							doh.isNot(null, fcPlugin, "formatBlock was found");
 
 							doh.robot.sequence(d.getTestErrback(function(){
-								var p = dojo.withGlobal(editor.window, function(){ return dojo.byId("text"); });
+								var p = dojo.byId("text", editor.document);
 								doh.is("text", p && p.id, "found text");
-								dojo.global.dojo.withGlobal(editor.window, function(){
-									// Select the text, collapse to the start of it
-									dijit._editor.selection.selectElementChildren(p);
-									dijit._editor.selection.collapse(true);
-								});
+
+								// Select the text, collapse to the start of it
+								editor.selection.selectElementChildren(p);
+								editor.selection.collapse(true);
 							}),1000);
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Make sure states update.
@@ -367,28 +356,26 @@
 							}), 1000);
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Select the children of the block and try to flatten the formatting.
-
-								var selection = dojo.withDoc(editor.document, function(){ return dojo.byId("selectionContainer"); });
-								dojo.global.dojo.withGlobal(editor.window, function(){
-									dojo.window.scrollIntoView(selection);
-									dijit._editor.selection.selectElementChildren(selection);
-								});
+								var selection = dojo.byId("selectionContainer", editor.document);
+								dojo.window.scrollIntoView(selection);
+								editor.selection.selectElementChildren(selection);
 								fcPlugin.button.set("value", "noFormat");
 							}), 1000);
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Now check that the elements are all gone.
-								var selection = dojo.withDoc(editor.document, function(){ return dojo.byId("selectionContainer"); });
-								doh.t(selection.childNodes.length > 0, "Checking that there are still child nodes.");
+								var selection = dojo.byId("selectionContainer", editor.document);
+								doh.t(selection.childNodes.length > 0,
+										"Checking that there are still child nodes, actual was " + selection.childNodes.length);
 
 								var i;
 								var nodes = selection.childNodes;
 								for(i = 0; i < nodes.length; i++){
 									var n = nodes[i];
 									if(n.nodeType == 1){
-										var tag = n.nodeName? n.nodeName.toLowerCase() : "";
-										doh.t(tag != "p");
-										doh.t(tag != "h3");
-										doh.t(tag != "pre");
+										var tag = n.nodeName ? n.nodeName.toLowerCase() : "";
+										doh.isNot("p", tag, "selection node #" + i + " of " + nodes.length);
+										doh.isNot("h3", tag, "selection node #" + i + " of " + nodes.length);
+										doh.isNot("pre", tag, "selection node #" + i + " of " + nodes.length);
 									}
 								}
 							}), 1000);
@@ -406,7 +393,7 @@
 						name: "FontChoice: Plain Text labels",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor1");
+							editor = registry.byId("editor1");
 							fcPlugin = [];
 							var edPlugins = editor._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
@@ -450,7 +437,7 @@
 						name: "FontChoice: Validate usage of generic names",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("generic");
+							editor = registry.byId("generic");
 							fcPlugin = null;
 							var edPlugins = editor._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
@@ -501,7 +488,7 @@
 						name: "FontChoice: Validate custom font names",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("custom");
+							editor = registry.byId("custom");
 							fcPlugin = null;
 							var edPlugins = editor._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
diff --git a/dijit/tests/editor/robot/Editor_FullScreen.html b/dijit/tests/editor/robot/Editor_FullScreen.html
index 5edd206..6b8722a 100644
--- a/dijit/tests/editor/robot/Editor_FullScreen.html
+++ b/dijit/tests/editor/robot/Editor_FullScreen.html
@@ -11,13 +11,10 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_FullScreen.html');
@@ -33,24 +30,24 @@
 							return p;				
 						}
 					}
-					doh.t(false, "didn't find plugin");
+					throw new Error("didn't find plugin");
 				}
 
-				doh.register("load", [
+				var registry;
+				doh.register("setup", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
-						}
+						runTest: waitForLoad
+					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
 					}
 				]);
 
 				doh.register("General", [
 					function setUp(){
-						editor = dijit.byId("editor0");
+						editor = registry.byId("editor0");
 						fsPlugin = getPlugin(editor);
 					},
 					{
@@ -197,9 +194,9 @@
 
 				doh.register("BorderContainer", [
 					function setUp(){
-						editor = dijit.byId("editor1");
+						editor = registry.byId("editor1");
 						fsPlugin = getPlugin(editor);
-						container = dijit.byId("bc");
+						container = registry.byId("bc");
 					},
 
 					{
@@ -242,8 +239,8 @@
 
 								doh.t(origEditorSize.w > curEditorSize.w, "Validating new width is less that the original size");
 								doh.t(origEditorSize.h > curEditorSize.h, "Validating new height is less that the original size");
-								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rough check that the editor width resized roughly to the Container difference, eWdiff = " + eWdiff + ", containerWdiff = " + containerWdiff);
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rough check that the editor height resized roughly to the Container difference, eHdiff = " + eHdiff + ", containerHdiff = " + containerHdiff);
 							}), 1000);
 
 							return d;
@@ -293,8 +290,8 @@
 
 								doh.t(origEditorSize.w < curEditorSize.w, "Validating new width is less that the original size");
 								doh.t(origEditorSize.h < curEditorSize.h, "Validating new height is less that the original size");
-								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rough check that the editor width resized roughly to the Container difference, eWdiff = " + eWdiff + ", containerWdiff = " + containerWdiff);
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rough check that the editor height resized roughly to the Container difference, eHdiff = " + eHdiff + ", containerHdiff = " + containerHdiff);
 							}), 1000);
 
 							return d;
@@ -308,9 +305,9 @@
 
 				doh.register("TabContainer", [
 					function setUp(){
-						editor = dijit.byId("editor2");
+						editor = registry.byId("editor2");
 						fsPlugin = getPlugin(editor);
-						container = dijit.byId("tc");
+						container = registry.byId("tc");
 					},
 
 					{
@@ -353,8 +350,8 @@
 
 								doh.t(origEditorSize.w > curEditorSize.w, "Validating new width is less that the original size");
 								doh.t(origEditorSize.h > curEditorSize.h, "Validating new height is less that the original size");
-								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rough check that the editor width resized roughly to the Container difference, eWdiff = " + eWdiff + ", containerWdiff = " + containerWdiff);
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rough check that the editor height resized roughly to the Container difference, eHdiff = " + eHdiff + ", containerHdiff = " + containerHdiff);
 							}), 1000);
 
 							return d;
@@ -404,8 +401,8 @@
 
 								doh.t(origEditorSize.w < curEditorSize.w, "Validating new width is less that the original size");
 								doh.t(origEditorSize.h < curEditorSize.h, "Validating new height is less that the original size");
-								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rough check that the editor width resized roughly to the Container difference, eWdiff = " + eWdiff + ", containerWdiff = " + containerWdiff);
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rough check that the editor height resized roughly to the Container difference, eHdiff = " + eHdiff + ", containerHdiff = " + containerHdiff);
 							}), 1000);
 
 							return d;
@@ -419,9 +416,9 @@
 
 				doh.register("AccordionContainer", [
 					function setUp(){
-						editor = dijit.byId("editor3");
+						editor = registry.byId("editor3");
 						fsPlugin = getPlugin(editor);
-						container = dijit.byId("ac");
+						container = registry.byId("ac");
 					},
 
 					{
@@ -464,8 +461,8 @@
 
 								doh.t(origEditorSize.w > curEditorSize.w, "Validating new width is less that the original size");
 								doh.t(origEditorSize.h > curEditorSize.h, "Validating new height is less that the original size");
-								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rough check that the editor width resized roughly to the Container difference, eWdiff = " + eWdiff + ", containerWdiff = " + containerWdiff);
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rough check that the editor height resized roughly to the Container difference, eHdiff = " + eHdiff + ", containerHdiff = " + containerHdiff);
 							}), 1000);
 
 							return d;
@@ -515,8 +512,8 @@
 
 								doh.t(origEditorSize.w < curEditorSize.w, "Validating new width is less that the original size");
 								doh.t(origEditorSize.h < curEditorSize.h, "Validating new height is less that the original size");
-								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rough check that the editor width resized roughly to the Container difference, eWdiff = " + eWdiff + ", containerWdiff = " + containerWdiff);
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rough check that the editor height resized roughly to the Container difference, eHdiff = " + eHdiff + ", containerHdiff = " + containerHdiff);
 							}), 1000);
 
 							return d;
@@ -530,9 +527,9 @@
 
 				doh.register("StackContainer", [
 					function setUp(){
-						editor = dijit.byId("editor4");
+						editor = registry.byId("editor4");
 						fsPlugin = getPlugin(editor);
-						container = dijit.byId("sc");
+						container = registry.byId("sc");
 					},
 
 					{
@@ -575,8 +572,8 @@
 
 								doh.t(origEditorSize.w > curEditorSize.w, "Validating new width is less that the original size");
 								doh.t(origEditorSize.h > curEditorSize.h, "Validating new height is less that the original size");
-								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rough check that the editor width resized roughly to the Container difference, eWdiff = " + eWdiff + ", containerWdiff = " + containerWdiff);
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rough check that the editor height resized roughly to the Container difference, eHdiff = " + eHdiff + ", containerHdiff = " + containerHdiff);
 							}), 1000);
 
 							return d;
@@ -626,8 +623,8 @@
 
 								doh.t(origEditorSize.w < curEditorSize.w, "Validating new width is less that the original size");
 								doh.t(origEditorSize.h < curEditorSize.h, "Validating new height is less that the original size");
-								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+								doh.t((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rough check that the editor width resized roughly to the Container difference, eWdiff = " + eWdiff + ", containerWdiff = " + containerWdiff);
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rough check that the editor height resized roughly to the Container difference, eHdiff = " + eHdiff + ", containerHdiff = " + containerHdiff);
 							}), 1000);
 
 							return d;
diff --git a/dijit/tests/editor/robot/Editor_IE8Compat.html b/dijit/tests/editor/robot/Editor_IE8Compat.html
new file mode 100644
index 0000000..52bcde8
--- /dev/null
+++ b/dijit/tests/editor/robot/Editor_IE8Compat.html
@@ -0,0 +1,69 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot Editor IE9 in IE8 Compat Mode Test</title>
+
+		<style>
+			@import "../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dojo.window");
+			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
+
+			dojo.ready(function(){
+				doh.robot.initRobot('../Editor_IE8Compat.html');
+
+				var editor1;
+
+				var registry;
+				doh.register("setup", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: waitForLoad
+					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+						editor1 = registry.byId("editor1");
+					}
+				]);
+
+				doh.register("general", [
+					{
+						name: "general",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							dojo.window.scrollIntoView(editor1.domNode);
+
+							// Set contents of editor1
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor1.focus();
+							}), 500);
+							doh.robot.typeKeys("hello", 500, 750);
+							doh.robot.keyPress(dojo.keys.ENTER, 500);
+							doh.robot.typeKeys("world", 500, 1650);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var val = editor1.get('value').replace(/ +/g, "").toLowerCase();
+								doh.is("hello<br/>world", val);
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+
+
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/editor/robot/Editor_LinkDialog.html b/dijit/tests/editor/robot/Editor_LinkDialog.html
index 136d023..9f9d3c0 100644
--- a/dijit/tests/editor/robot/Editor_LinkDialog.html
+++ b/dijit/tests/editor/robot/Editor_LinkDialog.html
@@ -11,13 +11,10 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_LinkDialog.html');
@@ -27,22 +24,22 @@
 				var value;
 				var node;
 
-				doh.register("Setup", [
+				var registry, focus;
+				doh.register("setup", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-							// TODO: test if this is working
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
-						}
+						runTest: waitForLoad
+					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+						focus = doh.robot.window.require("dijit/focus");
 					}
 				]);
 
 				doh.register("LinkDialog_tests", [
 					function setUp(){
-						editor = dijit.byId("editor");
+						editor = registry.byId("editor");
 						ldPlugin = null;
 						var edPlugins = editor._plugins, i;
 						for(i = 0; i < edPlugins.length; i++){
@@ -73,13 +70,13 @@
 							doh.robot.mouseClick({left:true}, 500);
 							var url, desc;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
 								url.set("value", "http://example.com/");
 								desc.set("value", "This is my example link.");
 							}),2000);
 
-							doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
+							doh.robot.mouseMoveAt(function(){return registry.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Now check the state!
@@ -116,14 +113,14 @@
 
 							var url, target, desc;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
+								target = registry.byId(ldPlugin._uniqueId + "_targetSelect");
 								url.set("value", "http://example.com/");
 								desc.set("value", "This is my example link.");
 								target.set("value", "_blank");
 							}),2000);
-							doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
+							doh.robot.mouseMoveAt(function(){return registry.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Now check the state!
@@ -160,14 +157,14 @@
 
 							var url, desc, target;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
+								target = registry.byId(ldPlugin._uniqueId + "_targetSelect");
 								url.set("value", "example.com/");
 								desc.set("value", "This is my example link.");
 								target.set("value", "_blank");
 							}),2000);
-							doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
+							doh.robot.mouseMoveAt(function(){return registry.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Now check the state!
@@ -186,7 +183,7 @@
 						}
 					},
 					{
-						name: "Anchor Tag: Test insertion 'relative' urls.",
+						name: "Anchor Tag: Test insertion 'relative' urls (./)",
 						timeout: 20000,
 						setUp: function(){
 							value = editor.get("value");
@@ -204,21 +201,65 @@
 
 							var url, desc, target;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
+								target = registry.byId(ldPlugin._uniqueId + "_targetSelect");
 								url.set("value", "./myDirectory/myfile.html");
 								desc.set("value", "This is my example relative link.");
 								target.set("value", "_blank");
 							}),2000);
-							doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
+							doh.robot.mouseMoveAt(function(){return registry.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Now check the state!
 								var newVal = editor.get("value");
 								doh.isNot(value, newVal, "Verify the contents have changed.");
 								doh.f(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
-								doh.t(new RegExp("href=(\"|\')./myDirectory/myfile.html(\"|\')").test(newVal), "Verifying URL has been inserted.");
+								doh.t(new RegExp("href=(\"|\')\./myDirectory/myfile.html(\"|\')").test(newVal), "Verifying URL has been inserted.");
+								doh.t(new RegExp("target=(\"|\')_blank(\"|\')").test(newVal), "Verifying target has been inserted.");
+								doh.t(new RegExp(">This is my example relative link.<").test(newVal), "Verifying description has been inserted.");
+							}), 2000);
+
+							return d;
+						},
+						tearDown: function(){
+							if(editor){editor.set("value", value);}
+						}
+					},
+					{
+						name: "Anchor Tag: Test insertion 'relative' url (../)",
+						timeout: 20000,
+						setUp: function(){
+							value = editor.get("value");
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var url, desc, target;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
+								target = registry.byId(ldPlugin._uniqueId + "_targetSelect");
+								url.set("value", "../myDirectory/myfile.html");
+								desc.set("value", "This is my example relative link.");
+								target.set("value", "_blank");
+							}),2000);
+							doh.robot.mouseMoveAt(function(){return registry.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								doh.f(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
+								doh.t(new RegExp("href=(\"|\')\.\./myDirectory/myfile.html(\"|\')").test(newVal), "Verifying URL has been inserted.");
 								doh.t(new RegExp("target=(\"|\')_blank(\"|\')").test(newVal), "Verifying target has been inserted.");
 								doh.t(new RegExp(">This is my example relative link.<").test(newVal), "Verifying description has been inserted.");
 							}), 2000);
@@ -233,9 +274,7 @@
 						name: "Anchor Tag: Update existing anchor tag",
 						timeout: 20000,
 						setUp: function(){
-							dojo.withGlobal(editor.window, function(){
-								node = dojo.byId("exampleLink");
-							});
+							node = dojo.byId("exampleLink", editor.document);
 							value = editor.get("value");
 						},
 						runTest: function(){
@@ -248,15 +287,15 @@
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Okay, select the text of the hyperlink so we can then perform an edit on it.
-								editor._sCall("selectElement", [node]);
+								editor.selection.selectElement(node);
 							}),500);
 							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							var url, desc, target, oldUrl, oldDesc;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
+								target = registry.byId(ldPlugin._uniqueId + "_targetSelect");
 
 								oldUrl = url.get("value");
 								doh.is("http://www.example.com/example.html", oldUrl, "old url");
@@ -267,7 +306,7 @@
 								desc.set("value", oldDesc + "_2");
 								target.set("value", "_blank");
 							}), 2000);
-							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return registry.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Now check the state!
@@ -292,9 +331,7 @@
 						name: "Anchor Tag: Blank description invalid.",
 						timeout: 20000,
 						setUp: function(){
-							dojo.withGlobal(editor.window, function(){
-								node = dojo.byId("exampleLink");
-							});
+							node = dojo.byId("exampleLink", editor.document);
 							value = editor.get("value");
 						},
 						runTest: function(){
@@ -307,30 +344,30 @@
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Okay, select the text of the hyperlink so we can then perform an edit on it.
-								editor._sCall("selectElement", [node]);
+								editor.selection.selectElement(node);
 							}),500);
 							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							var url, desc, target, oldDesc;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
+								target = registry.byId(ldPlugin._uniqueId + "_targetSelect");
 								oldDesc = desc.get("value");
 								desc.set("value", "");
 								target.set("value", "_blank");
 							}), 2000);
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Verify setting the content is disabled.
-								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								var setButton = registry.byId(ldPlugin._uniqueId + "_setButton");
 								doh.t(setButton.get("disabled"));
 							}), 500);
-							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return registry.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Now check the state!
 								var newVal = editor.get("value");
-								doh.t(newVal === value, "Verify the contents have not changed.");
+								doh.is(value, newVal, "Verify the contents have not changed.");
 							}), 2000);
 
 							return d;
@@ -358,19 +395,19 @@
 
 							var url, desc, target;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
+								target = registry.byId(ldPlugin._uniqueId + "_targetSelect");
 								url.set("value", "http://this is not/valid/bad.html");
 								desc.set("value", "This is my example relative link.");
 								target.set("value", "_blank");
 								url.validate();
 							}),2000);
 							doh.robot.sequence(d.getTestErrback(function(){
-								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								var setButton = registry.byId(ldPlugin._uniqueId + "_setButton");
 								doh.t(setButton.get("disabled"), "set button disabled");
 							}), 500);
-							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return registry.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.mouseMoveAt(editor.iframe, 500, 0, 0, 0);
 							doh.robot.mouseClick({left:true}, 500);
@@ -405,19 +442,19 @@
 
 							var url, desc, target;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
+								target = registry.byId(ldPlugin._uniqueId + "_targetSelect");
 								url.set("value", "mailto:johndoe at example.com");
 								desc.set("value", "Send a message to John.");
 								target.set("value", "_blank");
 								url.isValid();
 							}),2000);
 							doh.robot.sequence(d.getTestErrback(function(){
-								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								var setButton = registry.byId(ldPlugin._uniqueId + "_setButton");
 								doh.t(!setButton.get("disabled"));
 							}), 500);
-							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return registry.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.mouseMoveAt(editor.iframe, 500, 0, 0, 0);
 							doh.robot.mouseClick({left:true}, 500);
@@ -452,19 +489,19 @@
 
 							var url, desc, target;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
+								target = registry.byId(ldPlugin._uniqueId + "_targetSelect");
 								url.set("value", "johndoe at example.com");
 								desc.set("value", "Send a message to John.");
 								target.set("value", "_blank");
 								url.isValid();
 							}),2000);
 							doh.robot.sequence(d.getTestErrback(function(){
-								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								var setButton = registry.byId(ldPlugin._uniqueId + "_setButton");
 								doh.t(!setButton.get("disabled"));
 							}), 500);
-							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return registry.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.mouseMoveAt(editor.iframe, 500, 0, 0, 0);
 							doh.robot.mouseClick({left:true}, 500);
@@ -499,19 +536,19 @@
 
 							var url, desc, target;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
+								target = registry.byId(ldPlugin._uniqueId + "_targetSelect");
 								url.set("value", "mailto:john doe at example.com");
 								desc.set("value", "Send a message to John.");
 								target.set("value", "_blank");
 								url.isValid();
 							}),2000);
 							doh.robot.sequence(d.getTestErrback(function(){
-								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								var setButton = registry.byId(ldPlugin._uniqueId + "_setButton");
 								doh.t(setButton.get("disabled"));
 							}), 500);
-							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return registry.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.mouseMoveAt(editor.iframe, 500, 0, 0, 0);
 							doh.robot.mouseClick({left:true}, 500);
@@ -531,9 +568,7 @@
 						name: "Anchor Tag: Double-Click opens TooltipDialog.",
 						timeout: 20000,
 						setUp: function(){
-							dojo.withGlobal(editor.window, function(){
-								node = dojo.byId("exampleLink");
-							});
+							node = dojo.byId("exampleLink", editor.document);
 							value = editor.get("value");
 						},
 						runTest: function(){
@@ -557,16 +592,16 @@
 							var f;
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(ldPlugin.dropDown.domNode),  "tooltip dialog is visible");
-								f = dijit.getFocus();
-								doh.isNot(null, f && f.node, "is focus");
-								var w = dijit.getEnclosingWidget(f.node);
+								f = focus.curNode;
+								doh.isNot(null, f, "is focus");
+								var w = registry.getEnclosingWidget(f);
 								doh.isNot(null, w, "focused on widget");
 								var val = w.get("value");
 								doh.t(new RegExp("http://www.example.com/example.html").test(val), "Verifying the contents contained link url");
 							}), 2000);
 
 							// Clicking the <input> shouldn't close TooltipDialog (#14395)
-							doh.robot.mouseMoveAt(function(){ return f.node; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return f; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 100);
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isVisible(ldPlugin.dropDown.domNode),  "tooltip dialog still visible");
@@ -583,7 +618,7 @@
 
 				doh.register("ImgDialog_tests", [
 					function setUp(){
-						editor = dijit.byId("editor");
+						editor = registry.byId("editor");
 						ldPlugin = null;
 						var edPlugins = editor._plugins, i;
 						for(i = 0; i < edPlugins.length; i++){
@@ -616,12 +651,12 @@
 
 							var url, desc;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
 								url.set("value", "./sample2.jpg");
 								desc.set("value", "This is my example image 2.");
 							}),2000);
-							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return registry.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Now check the state!
@@ -657,12 +692,12 @@
 
 							var url, desc;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
 								url.set("value", "example.com/example.jpg");
 								desc.set("value", "This is my example image.");
 							}),2000);
-							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return registry.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Now check the state!
@@ -683,9 +718,7 @@
 						name: "Image Tag: Update existing image tag",
 						timeout: 20000,
 						setUp: function(){
-							dojo.withGlobal(editor.window, function(){
-								node = dojo.byId("exampleImage");
-							});
+							node = dojo.byId("exampleImage", editor.document);
 							value = editor.get("value");
 						},
 						runTest: function(){
@@ -696,20 +729,20 @@
 							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(d.getTestErrback(function(){editor._sCall("selectElement", [node]);}), 500);
+							doh.robot.sequence(d.getTestErrback(function(){editor.selection.selectElement(node);}), 500);
 							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							var url, desc, oldDesc;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
 								doh.t(new RegExp(".*/sample.jpg").test(url.get("value")), "original URL");
 								oldDesc = desc.get("value");
 								doh.is("Sample Image", oldDesc, "original alt-text");
 								url.set("value", "./sample2.jpg");
 								desc.set("value", oldDesc + "_2");
 							}), 2000);
-							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return registry.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Now check the state!
@@ -732,9 +765,7 @@
 						name: "Image Tag: Blank description valid.",
 						timeout: 20000,
 						setUp: function(){
-							dojo.withGlobal(editor.window, function(){
-								node = dojo.byId("exampleImage");
-							});
+							node = dojo.byId("exampleImage", editor.document);
 							value = editor.get("value");
 						},
 						runTest: function(){
@@ -745,23 +776,23 @@
 							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(d.getTestErrback(function(){editor._sCall("selectElement", [node]);}), 500);
+							doh.robot.sequence(d.getTestErrback(function(){editor.selection.selectElement(node);}), 500);
 							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							var url, desc, oldDesc;
 							doh.robot.sequence(d.getTestErrback(function(){
-								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								url = registry.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = registry.byId(ldPlugin._uniqueId + "_textInput");
 								oldDesc = desc.get("value");
 								url.set("value", "./sample2.jpg");
 								desc.set("value", "");
 							}), 2000);
 							doh.robot.sequence(d.getTestErrback(function(){
 								// Verify setting the content is disabled.
-								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								var setButton = registry.byId(ldPlugin._uniqueId + "_setButton");
 								doh.f(setButton.get("disabled"));
 							}), 500);
-							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return registry.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Now check the state!
@@ -784,9 +815,7 @@
 						name: "Image Tag: Single click selects image.",
 						timeout: 20000,
 						setUp: function(){
-							dojo.withGlobal(editor.window, function(){
-								node = dojo.byId("exampleImage");
-							});
+							node = dojo.byId("exampleImage", editor.document);
 							value = editor.get("value");
 						},
 						runTest: function(){
@@ -800,11 +829,11 @@
 							doh.robot.mouseMoveAt(node, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
-								var selectedElement = editor._sCall("getSelectedElement", [null]);
+								var selectedElement = editor.selection.getSelectedElement(null);
 								doh.t(selectedElement != null);
 								var tag = selectedElement.tagName? selectedElement.tagName.toLowerCase() : "";
-								doh.t(tag === "img");
-								doh.t(selectedElement.getAttribute("id") === "exampleImage");
+								doh.is("img", tag);
+								doh.is("exampleImage", selectedElement.getAttribute("id"));
 							}), 2000);
 
 							return d;
@@ -817,9 +846,7 @@
 						name: "Image Tag: Double-Click opens TooltipDialog.",
 						timeout: 20000,
 						setUp: function(){
-							dojo.withGlobal(editor.window, function(){
-								node = dojo.byId("exampleImage");
-							});
+							node = dojo.byId("exampleImage", editor.document);
 							value = editor.get("value");
 						},
 						runTest: function(){
@@ -844,10 +871,10 @@
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(ldPlugin.dropDown.domNode),  "tooltip dialog is visible");
 
-								f = dijit.getFocus();
-								doh.t(f.node, "got focus");
+								f = focus.curNode;
+								doh.t(f, "got focus");
 
-								var w = dijit.getEnclosingWidget(f.node);
+								var w = registry.getEnclosingWidget(f);
 								doh.t(w, "found enclosing widget");
 
 								var val = w.get("value");
@@ -855,7 +882,7 @@
 							}), 2000);
 
 							// Clicking the <input> shouldn't close TooltipDialog (#14395)
-							doh.robot.mouseMoveAt(function(){ return f.node; }, 500, 1);
+							doh.robot.mouseMoveAt(function(){ return f; }, 500, 1);
 							doh.robot.mouseClick({left:true}, 100);
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isVisible(ldPlugin.dropDown.domNode),  "tooltip dialog still visible");
diff --git a/dijit/tests/editor/robot/Editor_NewPage.html b/dijit/tests/editor/robot/Editor_NewPage.html
index d919695..62f7128 100755
--- a/dijit/tests/editor/robot/Editor_NewPage.html
+++ b/dijit/tests/editor/robot/Editor_NewPage.html
@@ -11,13 +11,10 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_NewPage.html');
@@ -33,24 +30,27 @@
 							return p;				
 						}
 					}
-					doh.t(false, "didn't find plugin");
+					throw new Error("didn't find plugin");
 				}
 
-				doh.register("NewPage_tests", [
+				var registry;
+				doh.register("setup", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
-						}
+						runTest: waitForLoad
 					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+					}
+				]);
+
+				doh.register("NewPage_tests", [
 					{
 						name: "Mouse: Click new page clears editor",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor0");
+							editor = registry.byId("editor0");
 							npPlugin = getPlugin(editor);
 						},
 						runTest: function(){
@@ -86,7 +86,7 @@
 						name: "Mouse: Click new page sets editor with default content.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor1");
+							editor = registry.byId("editor1");
 							npPlugin = getPlugin(editor);
 						},
 						runTest: function(){
diff --git a/dijit/tests/editor/robot/Editor_ViewSource.html b/dijit/tests/editor/robot/Editor_ViewSource.html
index 94ab03f..d13f152 100755
--- a/dijit/tests/editor/robot/Editor_ViewSource.html
+++ b/dijit/tests/editor/robot/Editor_ViewSource.html
@@ -11,13 +11,10 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_ViewSource.html');
@@ -26,21 +23,24 @@
 				var fsPlugin;
 				var vsPlugin;
 
-				doh.register("ViewSource_Tests", [
+				var registry;
+				doh.register("setup", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
-						}
+						runTest: waitForLoad
 					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+					}
+				]);
+
+				doh.register("ViewSource_Tests", [
 					{
 						name: "Keyboard: Go to view source (CTRL-SHIFT-F12)",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
+							editor0 = registry.byId("editor0");
 							var edPlugins = editor0._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -85,7 +85,7 @@
 						name: "Keyboard: Go to source mode and back",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
+							editor0 = registry.byId("editor0");
 							var edPlugins = editor0._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -128,7 +128,7 @@
 						name: "Mouse Click: Go to View Source",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
+							editor0 = registry.byId("editor0");
 							var edPlugins = editor0._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -170,7 +170,7 @@
 						name: "Mouse Click: Go to View Source, then mouseclick twice (open/close sourceview)",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
+							editor0 = registry.byId("editor0");
 							var edPlugins = editor0._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -214,7 +214,7 @@
 						name: "Combination Test:  FullScreen + ViewSource (Verify view source works in fullscreen mode)",
 						timeout: 20000,
 						setUp: function(){
-							editor1 = dijit.byId("editor1");
+							editor1 = registry.byId("editor1");
 							var edPlugins = editor1._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -267,7 +267,7 @@
 						name: "Combination Test:  FullScreen + ViewSource (toggle on and off)",
 						timeout: 20000,
 						setUp: function(){
-							editor1 = dijit.byId("editor1");
+							editor1 = registry.byId("editor1");
 							var edPlugins = editor1._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -326,7 +326,7 @@
 						name: "XSS: Verify simple script tags get stripped.",
 						timeout: 30000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
+							editor0 = registry.byId("editor0");
 							var edPlugins = editor0._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -388,7 +388,7 @@
 						name: "XSS: Verify complex/odd script tags get stripped.",
 						timeout: 30000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
+							editor0 = registry.byId("editor0");
 							var edPlugins = editor0._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -443,7 +443,7 @@
 						name: "XSS: Verify single line comment blocks are stripped.",
 						timeout: 30000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
+							editor0 = registry.byId("editor0");
 							var edPlugins = editor0._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -500,7 +500,7 @@
 						name: "XSS: Verify multi line comment blocks are stripped.",
 						timeout: 30000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
+							editor0 = registry.byId("editor0");
 							var edPlugins = editor0._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -560,7 +560,7 @@
 						name: "XSS: Verify iframe tags are stripped.",
 						timeout: 30000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
+							editor0 = registry.byId("editor0");
 							var edPlugins = editor0._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -619,7 +619,7 @@
 						name: "XSS Disabled: Verify script, comment, and iframes are not stripped.",
 						timeout: 30000,
 						setUp: function(){
-							editor3 = dijit.byId("editor3");
+							editor3 = registry.byId("editor3");
 							var edPlugins = editor3._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -693,7 +693,7 @@
 						name: "ReadOnly:  Verify View Source can be put in ReadOnly mode.",
 						timeout: 30000,
 						setUp: function(){
-							editor2 = dijit.byId("editor2");
+							editor2 = registry.byId("editor2");
 							var edPlugins = editor2._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
 								var p = edPlugins[i];
@@ -737,7 +737,7 @@
 						name: "ViewSource:  GetValue",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
+							editor0 = registry.byId("editor0");
 							value = editor0.get("value");
 							var edPlugins = editor0._plugins, i;
 							for(i = 0; i < edPlugins.length; i++){
@@ -783,6 +783,57 @@
 							fsPlugin = null;
 							vsPlugin = null;
 						}
+					},
+					{
+						name: "ViewSource:  SetValue",
+						timeout: 20000,
+						setUp: function(){
+							editor0 = registry.byId("editor0");
+							value = editor0.get("value");
+							var edPlugins = editor0._plugins, i;
+							for(i = 0; i < edPlugins.length; i++){
+								var p = edPlugins[i];
+								if(p.declaredClass === "dijit._editor.plugins.ViewSource"){
+									vsPlugin = p;
+								}
+								if(vsPlugin){
+									break;
+								}
+							}
+							doh.t(vsPlugin != null, "Checking for VS plugin.");
+							if(vsPlugin){ vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//Timing gets wonky here, so we need to do this on a timeout
+							//so the browser has time  to shift focus.
+							doh.robot.sequence(d.getTestErrback(function(){
+								//Focus on the editor window
+								dojo.window.scrollIntoView(editor0.domNode);
+								editor0.focus();
+							}), 500);
+
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.t(vsPlugin._sourceShown, "Verifying the plugin believes the source is shown.");
+								doh.is("none", dojo.style(editor0.iframe, "display"), "Verifying iframe is invisible");
+								doh.is("block", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is visible");
+								doh.is(vsPlugin.sourceArea.nextSibling, editor0.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
+								editor0.set("value", "FOO");
+								doh.is("FOO", editor0.get("value"), "Verifying the source area returns FOO when getValue is called.");
+							}), 3000);
+
+							return d;
+						},
+						tearDown: function(){
+							if(vsPlugin){vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							editor0.set("value", value); 
+							fsPlugin = null;
+							vsPlugin = null;
+						}
 					}
 				]);
 				doh.run();
diff --git a/dijit/tests/editor/robot/Editor_a11y.html b/dijit/tests/editor/robot/Editor_a11y.html
index 14c529a..e3e4f20 100644
--- a/dijit/tests/editor/robot/Editor_a11y.html
+++ b/dijit/tests/editor/robot/Editor_a11y.html
@@ -11,13 +11,10 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			function normalize(str){
 				// try to do some normalization to make all browsers look
@@ -40,19 +37,17 @@
 				var editor0,
 					editor1, editor1oldValue, editor1newValue, editor1onChange = "no onchange event yet";
 
+				var registry;
 				doh.register("setup", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
-						}
+						runTest: waitForLoad
 					},
-					function setUp(){
-						editor0 = dijit.byId("editor0");
-						editor1 = dijit.byId("editor1");					
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+						editor0 = registry.byId("editor0");
+						editor1 = registry.byId("editor1");
 						editor1.watch("value", function(attr, oldVal, newVal){
 							editor1oldValue = normalize(oldVal);
 							editor1newValue = normalize(newVal);
@@ -248,7 +243,7 @@
 								// probably happen as pre and post filters on the editor
 								var val = normalize(editor1.get('value'));
 								doh.is("hello <b>world</b>", val);
-							}), 500);
+							}), 1500);
 
 							return d;
 						}
diff --git a/dijit/tests/editor/robot/Editor_misc.html b/dijit/tests/editor/robot/Editor_misc.html
index 53282b5..ca9f51a 100755
--- a/dijit/tests/editor/robot/Editor_misc.html
+++ b/dijit/tests/editor/robot/Editor_misc.html
@@ -11,13 +11,10 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_Editor.html');
@@ -25,25 +22,35 @@
 				var height;
 				var value;
 				var editor1;
-				var editor1OrigionalBackgroundColor;
-				doh.register("Miscellaneous_tests", [
+				var editor1OriginalBackgroundColor;
+
+				function getPlugin(/*Editor*/ editor, /*String*/ command){
+					return dojo.filter(editor._plugins, function(p){
+						return p.command == command;
+					})[0];
+				}
+
+				var registry;
+				doh.register("setup", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
-						}
+						runTest: waitForLoad
 					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+					}
+				]);
+
+				doh.register("Miscellaneous_tests", [
 					{
 						name: "addStylesheet",
 						timeout: 3000,
 						setUp: function(){
-							editor1 = dijit.byId("editor1");
+							editor1 = registry.byId("editor1");
 							editor1.setValue("<h1>header one</h1>");
 							var editorTextNode = editor1.editNode.firstChild;
-							editor1OrigionalBackgroundColor = dojo.getComputedStyle(editorTextNode).backgroundColor;
+							editor1OriginalBackgroundColor = dojo.getComputedStyle(editorTextNode).backgroundColor;
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -76,24 +83,24 @@
 								var editorNodeText = editor1.editNode.firstChild;
 								var backgroundColor = dojo.getComputedStyle(editorNodeText).backgroundColor;
 								doh.is("header one", editorNodeText.innerHTML);
-								doh.is(editor1OrigionalBackgroundColor, backgroundColor, "backgroundColor");
+								doh.is(editor1OriginalBackgroundColor, backgroundColor, "backgroundColor");
 							}), 1000);
 
 							return d;
 						}
 					},
 					{
-						name: "Test AutoExpanding Edtor",
+						name: "auto expand",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("thud");
+							editor0 = registry.byId("thud");
 							height = dojo.style(editor0.domNode, "height");
 							value = editor0.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							//Focus on the editor window
+							// Focus on the editor window
 							dojo.window.scrollIntoView(editor0.domNode);
 							doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
 							doh.robot.mouseClick({left:true}, 500);
@@ -106,7 +113,7 @@
 							doh.robot.keyPress(dojo.keys.ENTER, 500);
 							doh.robot.keyPress(dojo.keys.ENTER, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
-								//Now check the state!
+								// Now check the state!
 								var newHeight = dojo.style(editor0.domNode, "height");
 								doh.t(height < newHeight, "height decreased from " + height + " to " + newHeight);
 							}), 1000);
@@ -118,30 +125,30 @@
 						}
 					},
 					{
-						name: "Test font-size style migrated to editor body",
+						name: "font-size style migrated to editor body",
 						runTest: function(){
-							editor0 = dijit.byId("fontSizedEditor");
+							editor0 = registry.byId("fontSizedEditor");
 							var bStyle = editor0.document.body.style["fontSize"];
 							doh.t(bStyle != null, "bStyle set");
 							doh.is("30pt", bStyle.toLowerCase());
 						}
 					},
 					{
-						name: "Test prefilters do process initial content",
+						name: "prefilters do process initial content",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("filteredEditor");
+							editor0 = registry.byId("filteredEditor");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							//Focus on the editor window
+							// Focus on the editor window
 							dojo.window.scrollIntoView(editor0.domNode);
 							doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
 							doh.robot.mouseClick({left:true}, 500);
 
-								doh.robot.sequence(d.getTestCallback(function(){
-								//Now check the state!
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
 								var val = editor0.get("value");
 								doh.t(val.indexOf("DOJO") >= 0, "dojo in val " + val);
 								doh.t(val.indexOf("notdojo") < 0, "notdojo not in val " + val);
@@ -151,25 +158,25 @@
 						}
 					},
 					{
-						name: "Test placeCurorAtStart (br tag) moves input before br, not inside.",
+						name: "placeCursorAtStart (br tag) moves input before br, not inside",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("brEditor");
+							editor0 = registry.byId("brEditor");
 							value = editor0.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							//Focus on the editor window
+							// Focus on the editor window
 							dojo.window.scrollIntoView(editor0.domNode);
 							doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
 							doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestErrback(function(){
+							doh.robot.sequence(d.getTestErrback(function(){
 								editor0.placeCursorAtStart();
 							}), 500);
 							doh.robot.typeKeys("abc", 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-								//Now check the state!
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
 								var content = editor0.get("value").replace(/[\s]/g, "");
 								doh.t(content.indexOf("abc<br") >= 0, "looked for 'abc<br', found: " + content);
 							}), 1000);
@@ -181,21 +188,21 @@
 						}
 					},
 					{
-						name: "Test custom editor content (programmatic creation).",
+						name: "custom editor content (programmatic creation)",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("programmatic3");
+							editor0 = registry.byId("programmatic3");
 							value = editor0.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							//Focus on the editor window
+							// Focus on the editor window
 							dojo.window.scrollIntoView(editor0.domNode);
 							doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
 							doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-								//Now check the state!
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
 								var content = editor0.get("value");
 								doh.t(content.indexOf("Custom Initial Content.") >= 0);
 							}), 1000);
@@ -207,21 +214,21 @@
 						}
 					},
 					{
-						name: "Verify custom filters passed in constructor are not lost",
+						name: "custom filters passed in constructor are not lost",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("programmatic4");
+							editor0 = registry.byId("programmatic4");
 							value = editor0.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							//Focus on the editor window
+							// Focus on the editor window
 							dojo.window.scrollIntoView(editor0.domNode);
 							doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
-								//Now check the state!
+								// Now check the state!
 								doh.t(editor0.contentPreFilters.length > 1);
 							}), 1000);
 
@@ -232,30 +239,30 @@
 						}
 					},
 					{
-						name: "Test replaceValue.",
+						name: "replaceValue",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("programmatic4");
+							editor0 = registry.byId("programmatic4");
 							value = editor0.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							//Focus on the editor window
+							// Focus on the editor window
 							dojo.window.scrollIntoView(editor0.domNode);
 							dojo.style(editor0.domNode, "display", "none");
 							editor0.replaceValue("New Value");
 							dojo.style(editor0.domNode, "display", "none");
 							doh.robot.sequence(d.getTestCallback(function(){
-								//Now check the state!
+								// Now check the state!
 								dojo.style(editor0.domNode, "display", "");
 								dojo.window.scrollIntoView(editor0.domNode);
 								var newValue = editor0.get("value");
 								editor0.undo();
 								var curValue = editor0.get("value");
-								doh.t(newValue.indexOf(value) < 0, "Verifying content changed with no trace of old content.");
-								doh.t(curValue != newValue, "Verify that undo undid the change.");
-								doh.t(curValue == value, "Verify original value was restored.");
+								doh.t(newValue.indexOf(value) < 0, "content changed with no trace of old content");
+								doh.t(curValue != newValue, "undo undid the change");
+								doh.t(curValue == value, "original value was restored");
 							}), 1000);
 
 							return d;
@@ -265,16 +272,16 @@
 						}
 					},
 					{
-						name: "Test page up/down.",
-						timeout: 4000,
+						name: "page up/down",
+						timeout: 6000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
+							editor0 = registry.byId("editor0");
 							value = editor0.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							//Focus on the editor window
+							// Focus on the editor window
 							dojo.window.scrollIntoView(editor0.domNode);
 							doh.robot.sequence(d.getTestErrback(function(){
 								editor0.focus();
@@ -297,7 +304,75 @@
 						tearDown: function(){
 							if(editor0){editor0.set("value", value);}
 						}
+					},
+					{
+						name: "emptyAltTag",
+						timeout: 20000,
+						setUp: function(){
+							editor0 = registry.byId("programmatic4");
+							value = editor0.get("value");
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							// Focus on the editor window
+							dojo.window.scrollIntoView(editor0.domNode);
+							editor0.set("value", "<img alt=\"''\" src=\"http://blogsearch.google.com/blogsearch/intl/en_ALL/images/blogs_logo.gif\">");
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								dojo.window.scrollIntoView(editor0.domNode);
+								var newValue = editor0.get("value");
+								var test = "alt=\"''\"";
+								doh.t(newValue.indexOf(test) > 0, "content includes empty string alt");
+							}), 1000);
+
+							return d;
+						},
+						tearDown: function(){
+							if(editor0){editor0.set("value", value);}
+						}
+					}
+
+				/*****
+				 * comment out test, it doesn't work
+					{
+						name: "caret pos #1",
+						timeout: 20000,
+						setUp: function(){
+							editor1 = registry.byId("editor1");
+							value = editor1.get("value");
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Scroll editor into view, set content to list except for middle item isn't part of list
+							dojo.window.scrollIntoView(editor1.domNode);
+							editor1.set("value", "<ul><li>one</li><li>two</li></ul><p id='three'>three</p><ul><li>four</li><li>five</li></ul>");
+
+							// Select middle item ("three")
+							doh.robot.sequence(d.getTestErrback(function(){
+								var node = dojo.byId("three", editor1.document);
+								editor1.selection.selectElementChildren(node);
+								editor1.selection.collapse(true);
+							}), 500);
+
+							// Press indent button so "three" becomes part of list
+							doh.robot.mouseMoveAt(function(){
+								return getPlugin(editor1, "indent").button.domNode;
+							}, 500);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("<ul><li>one</li><li>two</li><li>three</li><li>four</li><li>five</li></ul>",
+										editor1.get("value"), "element 'three' indented to become part of list")
+							}), 500);
+
+							return d;
+						},
+						tearDown: function(){
+							//if(editor0){editor0.set("value", value);}
+						}
 					}
+				 */
 				]);
 				doh.run();
 			});
diff --git a/dijit/tests/editor/robot/Editor_mouse.html b/dijit/tests/editor/robot/Editor_mouse.html
index 1130ad7..f32c566 100644
--- a/dijit/tests/editor/robot/Editor_mouse.html
+++ b/dijit/tests/editor/robot/Editor_mouse.html
@@ -2,36 +2,34 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Editor Mouse Test</title>
+		<title>robot Editor Mouse Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
-			dojo.require("dojo.window");
-			dojo.require("dijit.robotx");
-
-			function normalize(str){
-				// try to do some normalization to make all browsers look
-				// the same.   Would be nice if we didn't need this, the normalization should
-				// probably happen as pre and post filters on the editor
-				return str.
-					replace(/\s*\/>/g, "/>").
-					replace(/<br\/>$/, '').		// FF.  Because of EnterKeyHandling plugin?
-					replace(/^<p>/, '').replace(/<\/p>$/, '').		// Safari.  Because of EnterKeyHandling plugin?
-					replace(new RegExp(String.fromCharCode(160), "g"), " ");	// Safari: nbsp (char code 160) to normal space (char code 32)
-			}
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Editor.html');
+			require([
+				"doh/runner",  "dojo/robotx",
+				"dojo/dom-class", "dojo/keys", "dojo/query", "dojo/sniff",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, domClass, keys, query, has, helpers){
+
+				function normalize(str){
+					// try to do some normalization to make all browsers look
+					// the same.   Would be nice if we didn't need this, the normalization should
+					// probably happen as pre and post filters on the editor
+					return str.
+						replace(/\s*\/>/g, "/>").
+						replace(/<br\/>$/, '').		// FF.  Because of EnterKeyHandling plugin?
+						replace(/^<p>/, '').replace(/<\/p>$/, '').		// Safari.  Because of EnterKeyHandling plugin?
+						replace(new RegExp(String.fromCharCode(160), "g"), " ");	// Safari: nbsp (char code 160) to normal space (char code 32)
+				}
+
+				robot.initRobot('../test_Editor.html');
 
 				// For some reason the meta key (meta-a for selection, meta-b for bold, etc) isn't working
 				// on mac... use ctrl- instead, just like on windows. (#9553)
@@ -43,15 +41,14 @@
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
-						}
+						runTest: helpers.waitForLoad
 					},
 					function setVars(){
-						editor0 = dijit.byId("editor0");
-						editor1 = dijit.byId("editor1");
+						registry = doh.robot.window.require("dijit/registry");
+						editor0 = registry.byId("editor0");
+						doh.t(!!editor0, "editor0");
+						editor1 = registry.byId("editor1");
+						doh.t(!!editor1, "editor1");
 					}
 				]);
 
@@ -66,43 +63,39 @@
 								boldButton = toolbar.getChildren()[7],
 								italicButton = toolbar.getChildren()[8];
 
-							dojo.window.scrollIntoView(editor1.domNode);
-
 							// Focus the editor
-							doh.robot.mouseMoveAt(editor1.editNode, 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							// select all
-							doh.robot.sequence(function(){
-								editor1.execCommand("SelectAll");
-							}, 500);
+							robot.mouseMoveAt(editor1.editNode, 500, 1);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.typeKeys("hello ", 1000, 1000);		// and erase (by typing something new)
+							// select all and erase, by typing something new
+							robot.keyPress("a", 500, metaKey);
+							robot.typeKeys("hello ", 1000, 1000);
 
 							// turn on bold
-							doh.robot.mouseMoveAt(boldButton.domNode, 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt(boldButton.domNode, 500, 1);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.typeKeys("world", 1000, 1000);
+							robot.typeKeys("world", 1000, 1000);
 
 							// turn off bold
-							doh.robot.mouseMoveAt(boldButton.domNode, 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt(boldButton.domNode, 500, 1);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.typeKeys(". ", 1000, 400);
+							robot.typeKeys(". ", 1000, 400);
 
 							// turn on italic
-							doh.robot.mouseMoveAt(italicButton.domNode, 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt(italicButton.domNode, 500, 1);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.typeKeys("how are you", 1000, 2000);
+							robot.typeKeys("how are you", 1000, 2000);
 
 							// turn off italic
-							doh.robot.mouseMoveAt(italicButton.domNode, 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt(italicButton.domNode, 500, 1);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.typeKeys("?", 1000, 200);
+							robot.typeKeys("?", 1000, 200);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// Get the value and try to do some normalization to make all browsers look
 								// the same.   Would be nice if we didn't need this, the normalization should
 								// probably happen as pre and post filters on the editor
@@ -120,24 +113,24 @@
 							var d = new doh.Deferred();
 
 							// Find the bolded "world" word in the editor
-							var bold=dojo.query('b', editor1.editNode);
+							var bold = query('b', editor1.editNode);
 							if(!bold.length){
-								bold=dojo.query('strong', editor1.editNode)
+								bold = query('strong', editor1.editNode)
 							}
 
 							// Double-click "world" to select it
-							doh.robot.mouseMoveAt(bold[0], 500, 1, 5, 5);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseClick({left: true}, 50);
+							robot.mouseMoveAt(bold[0], 500, 1, 5, 5);
+							robot.mouseClick({left: true}, 500);
+							robot.mouseClick({left: true}, 50);
 
 							// Delete "world" and the space before it
-							doh.robot.keyPress(dojo.keys.DELETE, 500);
-							if(!dojo.isSafari && !(dojo.isChrome && dojo.isMac)){
+							robot.keyPress(keys.DELETE, 500);
+							if(!has("safari") && !(has("chrome") && has("mac"))){
 								// they delete the space too?
-								doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
+								robot.keyPress(keys.BACKSPACE, 500);
 							}
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is("hello. <i>how are you</i>?", normalize(editor1.get("value")));
 							}), 500);
 
@@ -152,16 +145,16 @@
 						timeout: 10000,
 						runTest: function(){
 							var cutButton = editor1.toolbar.getChildren()[3].domNode;
-							doh.t(dojo.hasClass(cutButton, "dijitButtonDisabled"), "Cut should be disabled " + cutButton.className);
+							doh.t(domClass.contains(cutButton, "dijitButtonDisabled"), "Cut should be disabled " + cutButton.className);
 
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt(editor1.editNode, 500, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(editor1.editNode, 500, 500, -10, 0); // move off of editNode
-							doh.robot.mouseRelease({left: true}, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.f(dojo.hasClass(cutButton, "dijitButtonDisabled"), "Cut should not be disabled " + cutButton.className);
+							robot.mouseMoveAt(editor1.editNode, 500, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(editor1.editNode, 500, 500, -10, 0); // move off of editNode
+							robot.mouseRelease({left: true}, 500);
+							robot.sequence(d.getTestCallback(function(){
+								doh.f(domClass.contains(cutButton, "dijitButtonDisabled"), "Cut should not be disabled " + cutButton.className);
 							}), 1000);
 
 							return d;
diff --git a/dijit/tests/editor/robot/EnterKeyHandling.html b/dijit/tests/editor/robot/EnterKeyHandling.html
index 5a30fcc..e4e8414 100644
--- a/dijit/tests/editor/robot/EnterKeyHandling.html
+++ b/dijit/tests/editor/robot/EnterKeyHandling.html
@@ -11,12 +11,9 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			function dom2string(root){
 				// summary:
@@ -58,16 +55,26 @@
 				doh.robot.initRobot('../EnterKeyHandling.html');
 
 				var metaKey = dojo.isMac? {meta: true} : {ctrl: true};
-				
+
+				var registry;
+				doh.register("setup", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: waitForLoad
+					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+					}
+				]);
+
 				// Tests for BR mode
 				doh.register("blockNodeForEnter=BR", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
 						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
+						    return waitForLoad
 						}
 					},
 					{
@@ -76,7 +83,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var br = dijit.byId("br");
+							var br = registry.byId("br");
 							br.set("value", "");
 							br.focus();
 							
@@ -111,7 +118,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var br = dijit.byId("br");
+							var br = registry.byId("br");
 							br.set("value", "");
 							br.focus();
 							
@@ -132,6 +139,13 @@
 								var value = br.get('value');
 								value = value.replace(/ /g, "");
 								value = value.replace(/\xA0/g, "");
+								if(dojo.isWebKit && !dojo.isMac){
+									// Work around webkit bug:
+									// http://code.google.com/p/chromium/issues/detail?id=106551
+									// Should hopefully be fixed in Chrome 19.
+									value = value.replace(/\n/g, "");
+									value = value.replace(/\r\f/g, "");
+								}
 								
 								// Safari may end with a trailing/extra br, so we need to remove it.
 								if(/<br\/><br\/>$/.test(value)){
@@ -150,7 +164,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var br = dijit.byId("br");
+							var br = registry.byId("br");
 							br.set("value", "");
 							br.focus();
 							
@@ -174,6 +188,14 @@
 								// paragraphs.
 								var value = br.get('value');
 								value = value.replace(/ /g, "");
+								if(dojo.isWebKit && !dojo.isMac){
+									// Work around webkit bug:
+									// http://code.google.com/p/chromium/issues/detail?id=106551
+									// Should hopefully be fixed in Chrome 19.
+									value = value.replace(/\n/g, "");
+									value = value.replace(/\r\f/g, "");
+								}
+								
 
 								// Safari may end with a trailing/extra br, so we need to remove it.
 								if(/aste<br\/>$/.test(value)){
@@ -196,21 +218,19 @@
 							var d = new doh.Deferred();
 							// The initial input was a div with a line of text with a bold tag in the middle.
 							// we want to focus on the bold and enter there, splitting it.
-							var editor = dijit.byId("div2");
+							var editor = registry.byId("div2");
 							dojo.window.scrollIntoView(editor.iframe);
-							var node = dojo.withGlobal(editor.window, function(){
-								return dojo.byId("boldLine0");
-							});
-							
+							var node = dojo.byId("boldLine0", editor.document);
+
 							doh.robot.mouseMoveAt(editor.iframe, 500);
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(function(){
-								editor._sCall("selectElementChildren", [node]);
-							}, 500);
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor.selection.selectElementChildren(node);
+							}), 500);
 							
-							//Keyboard kill the selection and shift position between i and s.
-							if(!dojo.isMoz || dojo.isMac){doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 100, {}); }
+							// Keyboard kill the selection and shift position between I and S.
+							if(!dojo.isMoz || dojo.isMac){ doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 100, {}); }
 							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 100, {});
 							doh.robot.keyPress(dojo.keys.ENTER, 500);
 
@@ -218,8 +238,8 @@
 								// Do tests here.
 								var val = editor.get("value");
 								// Check that it split the is into two and that the bold and div were properly split.
-								doh.t(val.indexOf("It <b id=\"boldLine0\">i</b></div>") > 0, "start");
-								doh.t(val.indexOf("<div><b>s</b>") > 0, "end");
+								doh.t(val.indexOf("It <b id=\"boldLine0\">I</b></div>") > 0, "start");
+								doh.t(val.indexOf("<div><b>S</b>") > 0, "end");
 							}), 500);
 
 							return d;
@@ -233,21 +253,19 @@
 							var d = new doh.Deferred();
 							// The initial input was a div with a line of text with a bold tag in the middle.
 							// we want to focus on the bold and enter there, splitting it.
-							var editor = dijit.byId("div3");
+							var editor = registry.byId("div3");
 							dojo.window.scrollIntoView(editor.iframe);
-							var node = dojo.withGlobal(editor.window, function(){
-								return dojo.byId("boldLine1");
-							});
+							var node = dojo.byId("boldLine1", editor.document);
 							
 							doh.robot.mouseMoveAt(editor.iframe, 500);
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(function(){
-								editor._sCall("selectElementChildren", [node]);
-							}, 500);
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor.selection.selectElementChildren(node);
+							}), 500);
 							
-							//Keyboard kill the selection and shift position between i and s.
-							if(!dojo.isMoz || dojo.isMac){doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 100, {}); }
+							// Keyboard kill the selection and shift position between I and S.
+							if(!dojo.isMoz || dojo.isMac){ doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 100, {}); }
 							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 100, {});
 							doh.robot.keyPress(dojo.keys.ENTER, 500);
 
@@ -270,21 +288,19 @@
 							var d = new doh.Deferred();
 							// The initial input was a div with a line of text with a font tag in the middle.
 							// we want to focus on the font and enter there, splitting it.
-							var editor = dijit.byId("div4");
+							var editor = registry.byId("div4");
 							dojo.window.scrollIntoView(editor.iframe);
-							var node = dojo.withGlobal(editor.window, function(){
-								return dojo.byId("fontLine1");
-							});
+							var node = dojo.byId("fontLine1", editor.document);
 							
 							doh.robot.mouseMoveAt(editor.iframe, 500);
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(function(){
-								editor._sCall("selectElementChildren", [node]);
-							}, 500);
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor.selection.selectElementChildren(node);
+							}), 500);
 							
-							//Keyboard kill the selection and shift position between i and s.
-							if(!dojo.isMoz || dojo.isMac){doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 100, {}); }
+							// Keyboard kill the selection and shift position between I and S.
+							if(!dojo.isMoz || dojo.isMac){ doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 100, {}); }
 							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 100, {});
 							doh.robot.keyPress(dojo.keys.ENTER, 500);
 
@@ -293,8 +309,8 @@
 								var val = editor.get("value");
 								// Check that it split the is into two and that the bold and div were properly split.
 								val = val.toLowerCase();
-								doh.assertTrue(/it <font\s+id="fontline1"\s+size\s*=\s*"\s*5?\s*">i<\/font><\/div>/.test(val),"font not set on first line");
-								doh.assertTrue(/<div><font\s+size\s*=\s*"\s*5?\s*">s<\/font>/.test(val),"font not set on split line");
+								doh.t(/it <font\s+id="fontline1"\s+size\s*=\s*"\s*5?\s*">i<\/font><\/div>/.test(val),"font not set on first line");
+								doh.t(/<div><font\s+size\s*=\s*"\s*5?\s*">s<\/font>/.test(val),"font not set on split line");
 							}), 500);
 
 							return d;
@@ -306,7 +322,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var editor = dijit.byId("div3");
+							var editor = registry.byId("div3");
 							dojo.window.scrollIntoView(editor.iframe);
 							editor.set("value", "");
 							editor.focus();
@@ -325,6 +341,13 @@
 							doh.robot.sequence(d.getTestCallback(function(){
 								var value = editor.get('value');
 								value = value.replace(/\xA0/g, "");
+								if(dojo.isWebKit && !dojo.isMac){
+									// Work around webkit bug:
+									// http://code.google.com/p/chromium/issues/detail?id=106551
+									// Should hopefully be fixed in Chrome 19.
+									value = value.replace(/\n/g, "");
+									value = value.replace(/\r\f/g, "");
+								}
 								doh.is('<div>testingCopyAndPastetestingCopyAndPastetestingCopyAndPaste</div><div></div>',
 										value,
 										"get('value')");
@@ -338,7 +361,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var editor = dijit.byId("div3");
+							var editor = registry.byId("div3");
 							dojo.window.scrollIntoView(editor.iframe);
 							editor.set("value", "");
 							editor.focus();
@@ -363,6 +386,14 @@
 								// paragraphs.
 								var value = editor.get('value');
 								value = value.replace(/\xA0/g, "");
+								if(dojo.isWebKit && !dojo.isMac){
+									// Work around webkit bug:
+									// http://code.google.com/p/chromium/issues/detail?id=106551
+									// Should hopefully be fixed in Chrome 19.
+									value = value.replace(/\n/g, "");
+									value = value.replace(/\r\f/g, "");
+								}
+								
 
 								doh.is('<div>testingCopyAndPastetestingCopyAndPastetestingCopyAndP</div><div>aste</div>',
 									value,
@@ -378,21 +409,19 @@
 							var d = new doh.Deferred();
 							// The initial input was a div with a line of text with a bold tag in the middle.
 							// we want to focus on the bold and enter there, splitting it.
-							var editor = dijit.byId("p2");
+							var editor = registry.byId("p2");
 							dojo.window.scrollIntoView(editor.iframe);
-							var node = dojo.withGlobal(editor.window, function(){
-								return dojo.byId("boldLine2");
-							});
+							var node = dojo.byId("boldLine2", editor.document);
 							
 							doh.robot.mouseMoveAt(editor.iframe, 500);
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(function(){
-								editor._sCall("selectElementChildren", [node]);
-							}, 500);
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor.selection.selectElementChildren(node);
+							}), 500);
 							
-							//Keyboard kill the selection and shift position between i and s.
-							if(!dojo.isMoz || dojo.isMac){doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 100, {}); }
+							// Keyboard kill the selection and shift position between I and S.
+							if(!dojo.isMoz || dojo.isMac){ doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 100, {}); }
 							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 100, {});
 							doh.robot.keyPress(dojo.keys.ENTER, 500);
 
@@ -400,8 +429,8 @@
 								// Do tests here.
 								var val = editor.get("value");
 								// Check that it split the is into two and that the bold and div were properly split.
-								doh.t(val.indexOf("It <b id=\"boldLine2\">i</b></p>") > 0, "start");
-								doh.t(val.indexOf("<p><b>s</b>") > 0, "end");
+								doh.t(val.indexOf("It <b id=\"boldLine2\">I</b></p>") > 0, "start");
+								doh.t(val.indexOf("<p><b>S</b>") > 0, "end");
 							}), 500);
 
 							return d;
@@ -412,16 +441,14 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var editor = dijit.byId("p2");
+							var editor = registry.byId("p2");
 							editor.set('value','<p>ab</p>');
-							dojo.withGlobal(editor.window, function(){
-								var selection=dijit.range.getSelection(dojo.global);
-								selection.removeAllRanges();
-								var range=dijit.range.create(dojo.global);
-								range.setStart(editor.editNode.firstChild, 0);
-								range.setEnd(editor.editNode.firstChild, 1);
-								selection.addRange(range);
-							});
+							var selection=dijit.range.getSelection(editor.window);
+							selection.removeAllRanges();
+							var range=dijit.range.create(editor.window);
+							range.setStart(editor.editNode.firstChild, 0);
+							range.setEnd(editor.editNode.firstChild, 1);
+							selection.addRange(range);
 							doh.robot.keyPress(dojo.keys.ENTER, 500, {shift: true});
 							doh.robot.sequence(d.getTestCallback(function(){
 								var val = editor.get("value");
@@ -436,7 +463,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var editor = dijit.byId("p2");
+							var editor = registry.byId("p2");
 							dojo.window.scrollIntoView(editor.iframe);
 							editor.set("value", "");
 							editor.focus();
@@ -455,6 +482,14 @@
 							doh.robot.sequence(d.getTestCallback(function(){
 								var value = editor.get('value');
 								value = value.replace(/\xA0/g, "");
+								if(dojo.isWebKit && !dojo.isMac){
+									// Work around webkit bug:
+									// http://code.google.com/p/chromium/issues/detail?id=106551
+									// Should hopefully be fixed in Chrome 19.
+									value = value.replace(/\n/g, "");
+									value = value.replace(/\r\f/g, "");
+								}
+								
 								doh.is('<p>testingCopyAndPastetestingCopyAndPastetestingCopyAndPaste</p><p></p>',
 									value,
 									"get('value')");
@@ -468,7 +503,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var editor = dijit.byId("p2");
+							var editor = registry.byId("p2");
 							dojo.window.scrollIntoView(editor.iframe);
 							editor.set("value", "");
 							editor.focus();
@@ -493,6 +528,14 @@
 								// paragraphs.
 								var value = editor.get('value');
 								value = value.replace(/\xA0/g, "");
+								if(dojo.isWebKit && !dojo.isMac){
+									// Work around webkit bug:
+									// http://code.google.com/p/chromium/issues/detail?id=106551
+									// Should hopefully be fixed in Chrome 19.
+									value = value.replace(/\n/g, "");
+									value = value.replace(/\r\f/g, "");
+								}
+								
 								doh.is('<p>testingCopyAndPastetestingCopyAndPastetestingCopyAndP</p><p>aste</p>',
 										value,
 										"get('value')");
diff --git a/dijit/tests/editor/robot/TabIndent.html b/dijit/tests/editor/robot/TabIndent.html
index 7d57f38..7df364b 100644
--- a/dijit/tests/editor/robot/TabIndent.html
+++ b/dijit/tests/editor/robot/TabIndent.html
@@ -11,34 +11,35 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_TabIndent.html');
 					
 				var metaKey = {ctrl: true};
-					
-				doh.register("testTabIndent", [
+
+				var registry;
+				doh.register("setup", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
-						}
+						runTest: waitForLoad
 					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+					}
+				]);
+
+				doh.register("testTabIndent", [
 					{
-						name: "toggleDir_toggleOn",
+						name: "toggleOn",
 						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							var editor = dijit.byId("tiTest");
+							var editor = registry.byId("tiTest");
 							
 							doh.robot.sequence(d.getTestErrback(function(){
 								editor.setValue("<ol><li>a list item.</li><li>a list item2.</li></ol>");
@@ -58,11 +59,11 @@
 						}
 					},
 					{
-						name: "toggleDir_shiftTab",
+						name: "shiftTab",
 						timeout: 2000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var editor = dijit.byId("tiTest");
+							var editor = registry.byId("tiTest");
 							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
 							
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -76,12 +77,12 @@
 						}
 					},
 					{
-						name: "toggleDir_toggleOff",
+						name: "toggleOff",
 						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							var editor = dijit.byId("tiTest");
+							var editor = registry.byId("tiTest");
 							var origValue;
 							doh.robot.sequence(d.getTestErrback(function(){ origValue = editor.getValue(); }), 1000); 
 							doh.robot.mouseMoveAt(dojo.query(".dijitEditorIconTabIndent")[0], 1000);
@@ -98,12 +99,12 @@
 						}
 					},
 					{
-						name: "toggleDir_toggleOn_ctrlM",
+						name: "toggleOn_ctrlM",
 						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							var editor = dijit.byId("tiTest");
+							var editor = registry.byId("tiTest");
 
 							doh.robot.mouseMoveAt(function(){ return editor.editNode }, 500);
 							doh.robot.mouseClick({left: true}, 500);
@@ -120,12 +121,12 @@
 						}
 					},
 					{
-						name: "toggleDir_toggleOff_ctrlM",
+						name: "toggleOff_ctrlM",
 						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							var editor = dijit.byId("tiTest");
+							var editor = registry.byId("tiTest");
 							var origValue;
 							doh.robot.sequence(d.getTestErrback(function(){ origValue = editor.getValue(); }), 1000); 
 							doh.robot.mouseMoveAt(function(){ return editor.editNode }, 500);
diff --git a/dijit/tests/editor/robot/ToggleDir.html b/dijit/tests/editor/robot/ToggleDir.html
index 3084060..ac8d50a 100644
--- a/dijit/tests/editor/robot/ToggleDir.html
+++ b/dijit/tests/editor/robot/ToggleDir.html
@@ -11,27 +11,28 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_ToggleDir.html');
 					
 				var metaKey = {ctrl: true};
-					
-				doh.register("testToggleDir", [
+
+				var registry;
+				doh.register("setup", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
-						}
+						runTest: waitForLoad
 					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+					}
+				]);
+
+				doh.register("testToggleDir", [
 					{
 						name: "toggleDir_toggleOn",
 						timeout: 6000,
@@ -40,34 +41,15 @@
 							
 							doh.robot.mouseMoveAt(dojo.query(".dijitEditorIconToggleDir")[0], 1000);
 							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("ed0", 1000);
-							doh.robot.mouseClick({left:true}, 500);
-							if(!dojo.isOpera){
-								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {shift: true});
-							}
-							
+
 							doh.robot.sequence(d.getTestCallback(function(){
-								var editor = dijit.byId("ed0");
-								if(!dojo.isOpera){ /*This test is not valid in opera because the rtl test ends up being the same as the ltr test, therefore, there is no way to disnguish between the two.*/
-									var selection = dijit.range.getSelection(editor.window);
-									if(selection && selection.rangeCount){				
-										var range = selection.getRangeAt(0);
-										var firstNode = range.startContainer;
-										var startOffset = range.startOffset;
-										var selectedText = firstNode.nodeValue.charAt(startOffset);
-										doh.is(".", selectedText);
-									}else{
-										doh.t(false);
-									}
-								}
-								
+								var editor = registry.byId("ed0");
 								var editDoc = editor.editorObject.contentWindow.document.documentElement;
 			                    editDoc = editDoc.getElementsByTagName("body")[0];
 			                    doh.is("rtl", editDoc.dir);
 							
-							}), 1000);
+							}), 500);
+
 							return d;
 						}
 					},
@@ -82,25 +64,9 @@
 							
 							doh.robot.mouseMoveAt("ed0", 1000);
 							doh.robot.mouseClick({left:true}, 500);
-							if(!dojo.isOpera){
-								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
-								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {shift: true});
-							}
-							
+
 							doh.robot.sequence(d.getTestCallback(function(){
-								var editor = dijit.byId("ed0");
-								if(!dojo.isOpera){
-									var selection = dijit.range.getSelection(editor.window);
-									if(selection && selection.rangeCount){				
-										var range = selection.getRangeAt(0);
-										var firstNode = range.startContainer;
-										var startOffset = range.startOffset;
-										var selectedText = firstNode.nodeValue.charAt(startOffset);
-										doh.is(".", selectedText);
-									}else{
-										doh.t(false);
-									}
-								}
+								var editor = registry.byId("ed0");
 								var editDoc = editor.editorObject.contentWindow.document.documentElement;
 			                    editDoc = editDoc.getElementsByTagName("body")[0];
 			                    doh.is("ltr", editDoc.dir);
diff --git a/dijit/tests/editor/robot/ToggleDir_rtl.html b/dijit/tests/editor/robot/ToggleDir_rtl.html
index d010596..8350b03 100644
--- a/dijit/tests/editor/robot/ToggleDir_rtl.html
+++ b/dijit/tests/editor/robot/ToggleDir_rtl.html
@@ -11,27 +11,28 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_ToggleDir_rtl.html');
 					
 				var metaKey = {ctrl: true};
-					
-				doh.register("testToggleDir", [
+
+				var registry;
+				doh.register("setup", [
 					{
 						name: "wait for editors to load",
 						timeout: 5000,
-						runTest: function(){
-						    return new dojo.DeferredList(
-						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
-						    );
-						}
+						runTest: waitForLoad
 					},
+					function setVars(){
+						registry = doh.robot.window.require("dijit/registry");
+					}
+				]);
+
+				doh.register("testToggleDir", [
 					{
 						name: "toggleDir_toggleOn",
 						timeout: 6000,
@@ -43,31 +44,14 @@
 							
 							doh.robot.mouseMoveAt("ed0", 1000);
 							doh.robot.mouseClick({left:true}, 500);
-							if(!dojo.isOpera){
-								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
-								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {shift: true});
-							}
-							
+
 							doh.robot.sequence(d.getTestCallback(function(){
-								var editor = dijit.byId("ed0");
-								if(!dojo.isOpera){ /*This test is not valid in opera because the rtl test ends up being the same as the ltr test, therefore, there is no way to disnguish between the two.*/
-									var selection = dijit.range.getSelection(editor.window);
-									if(selection && selection.rangeCount){				
-										var range = selection.getRangeAt(0);
-										var firstNode = range.startContainer;
-										var startOffset = range.startOffset;
-										var selectedText = firstNode.nodeValue.charAt(startOffset);
-										doh.is(".", selectedText);
-									}else{
-										doh.t(false);
-									}
-								}
-								
+								var editor = registry.byId("ed0");
 								var editDoc = editor.editorObject.contentWindow.document.documentElement;
 			                    editDoc = editDoc.getElementsByTagName("body")[0];
 			                    doh.is("ltr", editDoc.dir);
 							
-							}), 1000);
+							}), 500);
 							return d;
 						}
 					},
@@ -82,29 +66,13 @@
 							
 							doh.robot.mouseMoveAt("ed0", 1000);
 							doh.robot.mouseClick({left:true}, 500);
-							if(!dojo.isOpera){
-								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {shift: true});
-							}
-							
+
 							doh.robot.sequence(d.getTestCallback(function(){
-								var editor = dijit.byId("ed0");
-								if(!dojo.isOpera){
-									var selection = dijit.range.getSelection(editor.window);
-									if(selection && selection.rangeCount){				
-										var range = selection.getRangeAt(0);
-										var firstNode = range.startContainer;
-										var startOffset = range.startOffset;
-										var selectedText = firstNode.nodeValue.charAt(startOffset);
-										doh.is(".", selectedText);
-									}else{
-										doh.t(false);
-									}
-								}
+								var editor = registry.byId("ed0");
 								var editDoc = editor.editorObject.contentWindow.document.documentElement;
 			                    editDoc = editDoc.getElementsByTagName("body")[0];
 			                    doh.is("rtl", editDoc.dir);
-							}), 1000);
+							}), 500);
 							return d;
 						}
 					}					
diff --git a/dijit/tests/editor/runTests.html b/dijit/tests/editor/runTests.html
index 932a6e9..7f2a5c4 100755
--- a/dijit/tests/editor/runTests.html
+++ b/dijit/tests/editor/runTests.html
@@ -2,7 +2,7 @@
 <html>
 	<head>
 	<title>Dijit Unit Test Runner</title>
-	<meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dijit.tests.editor.module"></HEAD>
+	<meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dijit/tests/editor/module"></HEAD>
 	<BODY>
 		Redirecting to D.O.H runner.
 	</BODY>
diff --git a/dijit/tests/editor/test_CustomPlugin.html b/dijit/tests/editor/test_CustomPlugin.html
index c093120..288c8d9 100644
--- a/dijit/tests/editor/test_CustomPlugin.html
+++ b/dijit/tests/editor/test_CustomPlugin.html
@@ -1,23 +1,10 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Custom Plugin Test/Tutorial</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<style>
 		.customIconHtmlToggle {
@@ -30,76 +17,81 @@
 	</style>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/_base/declare",
+			"dojo/dom-construct",
+			"dojo/dom-geometry",
+			"dojo/dom-style",
+			"dojo/_base/lang",
+			"dojo/parser",
+			"dojo/sniff",
+			"dijit/registry",
+			"dijit/Editor",
+			"dijit/_editor/_Plugin",
+			"dijit/form/ToggleButton",
+			"dojo/domReady!"
+		], function(declare, domConstruct, domGeom, domStyle, lang, parser, has, registry, Editor, _Plugin, ToggleButton){
 
-		dojo.require("dijit._editor._Plugin");
-		dojo.require("dojo.string");
+			var MyPlugin = declare("MyPlugin", _Plugin, {
+				buttonClass: ToggleButton,
+				useDefaultCommand: false,
+				name: "MyPlugin",
 
-		dojo.ready(function(){
-			dojo.declare("MyPlugin",
-				dijit._editor._Plugin,
-				{
-					buttonClass: dijit.form.ToggleButton,
-					useDefaultCommand: false,
-	
-					_initButton: function(){
-						this.command = "htmlToggle";
-						this.editor.commands[this.command] = "View HTML source"; // note: should be localized
-						this.iconClassPrefix = "customIcon";
-						this.inherited(arguments);
-						delete this.command; // kludge so setEditor doesn't make the button invisible
-						this.connect(this.button, "onClick", this._toggleSource);
-					},
-	
-					destroy: function(f){
-						this.inherited(arguments);
-						if(this.sourceArea){ dojo.destroy(this.sourceArea); }
-					},
-	
-					_toggleSource: function(){
-						this.source = !this.source;
-						if(!this.sourceArea){
-							this.sourceArea = dojo.doc.createElement('textarea');
-							this.sourceArea.style.position = 'absolute';
-							dojo.place(this.sourceArea, this.editor.domNode, "last");
-						}
-						if(this.source){
-							this.sourceArea.style.display = "";
-							this.sourceArea.value = this.editor.getValue();
-							dojo.style(this.sourceArea, "borderWidth", dojo.style(this.editor.editingArea, "borderStyle") == "none" ? "0" : dojo.style(this.editor.editingArea, "borderWidth"));
-							dojo.marginBox(this.sourceArea, dojo.marginBox(this.editor.editingArea));
-							if(dojo.isIE){
-								//work around IE oddity with offsetParent mismatch
-								var p = dojo.position(this.editor.editingArea);
-								dojo.style(this.sourceArea, { left: p.x, top: p.y });
-							}
-						}else{
-							this.editor.setValue(this.sourceArea.value);
-							this.sourceArea.style.top = "-999px";
-							this.sourceArea.style.display = "none";
+				_initButton: function(){
+					this.command = "htmlToggle";
+					this.editor.commands[this.command] = "View HTML source"; // note: should be localized
+					this.iconClassPrefix = "customIcon";
+					this.inherited(arguments);
+					delete this.command; // kludge so setEditor doesn't make the button invisible
+					this.button.on("click", lang.hitch(this, "_toggleSource"));
+				},
+
+				destroy: function(f){
+					this.inherited(arguments);
+					if(this.sourceArea){ domConstruct.destroy(this.sourceArea); }
+				},
+
+				_toggleSource: function(){
+					this.source = !this.source;
+					if(!this.sourceArea){
+						this.sourceArea = document.createElement('textarea');
+						this.sourceArea.style.position = 'absolute';
+						this.sourceArea.setAttribute("aria-label", "sourceArea");
+						domConstruct.place(this.sourceArea, this.editor.domNode, "last");
+					}
+					if(this.source){
+						this.sourceArea.style.display = "";
+						this.sourceArea.value = this.editor.getValue();
+						domStyle.set(this.sourceArea, "borderWidth",
+								domStyle.get(this.editor.editingArea, "borderStyle") == "none" ? "0" :
+										domStyle.get(this.editor.editingArea, "borderWidth"));
+						domGeom.setMarginBox(this.sourceArea, domGeom.getMarginBox(this.editor.editingArea));
+						if(has("ie")){
+							//work around IE oddity with offsetParent mismatch
+							var p = domGeom.position(this.editor.editingArea);
+							domStyle.set(this.sourceArea, { left: p.x, top: p.y });
 						}
-	
-						this.button.set('label', this.source ? "View WYSIWYG" : this.editor.commands["htmlToggle"]); // note: should be localized
+					}else{
+						this.editor.setValue(this.sourceArea.value);
+						this.sourceArea.style.top = "-999px";
+						this.sourceArea.style.display = "none";
 					}
+
+					this.button.set('label', this.source ? "View WYSIWYG" : this.editor.commands["htmlToggle"]); // note: should be localized
 				}
-			);
+			});
 	
 			/* the following code registers my plugin */
-			dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-				if(o.plugin){ return; }
-				if(o.args.name == "MyPlugin"){
-					return new MyPlugin({});
-				}
-			});
+			_Plugin.registry["MyPlugin"] = function(args){
+				return new MyPlugin({});
+			};
 			
-			dojo.parser.parse();
+			parser.parse();
 		});
 	</script>
 </head>
-<body class="claro">
-	<div id="editor1" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["MyPlugin"], height: 150'><p>
+<body class="claro" role="main">
+	<div id="editor1" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editorExtraPlugin",extraPlugins:["MyPlugin"], height: 150'><p>
 	This editor should have my custom plugin
 	</p></div>
 </body>
diff --git a/dijit/tests/editor/test_Editor.html b/dijit/tests/editor/test_Editor.html
index d421a89..97db8c7 100644
--- a/dijit/tests/editor/test_Editor.html
+++ b/dijit/tests/editor/test_Editor.html
@@ -1,39 +1,29 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor._Plugin");
-		dojo.require("dijit._editor.plugins.AlwaysShowToolbar");
-		dojo.require("dijit._editor.plugins.FontChoice");  // 'fontName','fontSize','formatBlock'
-		dojo.require("dijit._editor.plugins.TextColor");
-		dojo.require("dijit._editor.plugins.LinkDialog");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-		dojo.ready(function(){
+		require([
+			"dojo/_base/declare",
+			"dojo/parser",	// scan page for widgets and instantiate them
+			"dijit/Editor",
+			"dijit/_editor/_Plugin",
+			"dijit/_editor/plugins/AlwaysShowToolbar",
+			"dijit/_editor/plugins/FontChoice",  // 'fontName','fontSize','formatBlock'
+			"dijit/_editor/plugins/TextColor",
+			"dijit/_editor/plugins/LinkDialog",
+			"dojo/NodeList-dom",	// orphan()
+			"dojo/domReady!"
+		], function(declare, parser, Editor, _Plugin){
+
 			// Dummy simple plugin for testing that filters registered this way work
 			// properly with content setting on load.
-			dojo.declare("dijit.tests.editor.TestFilter", [dijit._editor._Plugin], {
+			declare("TestFilter", _Plugin, {
 				setEditor: function(editor){
 					this.editor = editor;
 					this.editor.contentPreFilters.push(function(val){
@@ -45,39 +35,50 @@
 				}
 			});
 
-			dojo.parser.parse();
+			parser.parse();
 
-			var progEditor = new dijit.Editor({
-				value: "Custom Initial Content."
+			var progEditor = new Editor({
+				value: "Custom Initial Content.",
+				"aria-label": "progEditor"
 			}, "programmatic3");
+			progEditor.startup();
 
-			var progEditor2 = new dijit.Editor({
-				contentPreFilters: [function(txt){ return txt; }]
+			var progEditor2 = new Editor({
+				contentPreFilters: [function(txt){ return txt; }],
+				"aria-label": "progEditor2"
 			}, "programmatic4");
+			progEditor2.startup();
 		});
 
 	</script>
 </head>
 
-<body class="claro">
-	<div data-dojo-type="dijit.Editor" data-dojo-props="plugins:[], focusOnLoad:true, height:'1.5em', style:'border:0px;'" id="automated"
+<body class="claro" role="main">
+	<script type="dojo/require">
+		dom: "dojo/dom",
+		lang: "dojo/_base/lang",
+		query: "dojo/query",
+		registry: "dijit/registry",
+		Editor: "dijit/Editor"
+	</script>
+	<div data-dojo-type="dijit/Editor" data-dojo-props="plugins:[], focusOnLoad:true, height:'1.5em', style:'border:0px;','aria-label':'automated'" id="automated"
 	>Automated Test - all check boxes should be checked<script type='dojo/method' data-dojo-event='onFocus'>
 			if(!document.getElementById('onFocusFired').checked){
 				document.getElementById('onFocusFired').checked=true;
-				document.getElementById('initialValueOK').checked = (dijit.byId('automated').getValue() == 'Automated Test - all check boxes should be checked');
-				dijit.byId('automated').document.execCommand('selectall', false, false);
+				document.getElementById('initialValueOK').checked = (registry.byId('automated').getValue() == 'Automated Test - all check boxes should be checked');
+				registry.byId('automated').document.execCommand('selectall', false, false);
 				document.getElementById('onChangeOKnow').checked=true;
-				dijit.byId('automated').document.execCommand('underline', false, false);
-				setTimeout(dojo.hitch(dijit.byId('editor0'),"focus",0));
+				registry.byId('automated').document.execCommand('underline', false, false);
+				setTimeout(lang.hitch(registry.byId('editor0'),"focus",0));
 			}
 		</script
 		><script type='dojo/method' data-dojo-event='onBlur'>
 			if(!document.getElementById('onBlurFired').checked){
 				document.getElementById('onBlurFired').checked=true;
-				dijit.byId('automated').set('disabled', true);
+				registry.byId('automated').set('disabled', true);
 				setTimeout(function(){ try {
-					dijit.byId('automated').document.execCommand('bold', false, false);
-					document.getElementById('disabledOK').checked = (dijit.byId('automated').document.queryCommandState('bold') == false);
+					registry.byId('automated').document.execCommand('bold', false, false);
+					document.getElementById('disabledOK').checked = (registry.byId('automated').document.queryCommandState('bold') == false);
 				}catch(e){ document.getElementById('disabledOK').checked = true; }}, 0);
 			}
 		</script
@@ -87,39 +88,37 @@
 			}
 		</script
 	></div>
-	Focus:<input type="checkbox" id="onFocusFired" disabled />
-	Value:<input type="checkbox" id="initialValueOK" disabled />
+	<label for="onFocusFired">Focus:</label><input type="checkbox" id="onFocusFired" disabled />
+	<label for="initialValueOK">Value:</label><input type="checkbox" id="initialValueOK" disabled />
 	<input type="checkbox" id="onChangeOKnow" disabled style="display:none;"/>
-	Change:<input type="checkbox" id="onChangeFired" disabled />
-	Blur:<input type="checkbox" id="onBlurFired" disabled />
-	Disabled:<input type="checkbox" id="disabledOK" disabled />
+	<label for="onChangeFired">Change:</label><input type="checkbox" id="onChangeFired" disabled />
+	<label for="onBlurFired">Blur:</label><input type="checkbox" id="onBlurFired" disabled />
+	<label for="disabledOK">Disabled:</label><input type="checkbox" id="disabledOK" disabled />
 	<br>
 	<br>
 
 	<h1 class="testTitle">Editor + Plugins Test</h1>
 
 	<h2>No plugins, initially empty</h2>
-	<div data-dojo-type="dijit.Editor" data-dojo-props="plugins:[], height:'100'" id="editor0"></div>
+	<div data-dojo-type="dijit/Editor" data-dojo-props="plugins:[], height:'100', 'aria-label':'applied with aria'" id="editor0"></div>
 
-	<h2>Created from div</h2>
-	<input id="focusBefore" value="input before editor1"/>
-	<div data-dojo-type="dijit.Editor" data-dojo-props="onChange:function(v){console.log('editor1 onChange handler: ' + v)}, disableSpellCheck:true" id="editor1"
+	<h2><label id="label_editor1">Created from div</label></h2>
+	<label for="focusBefore">lbl:</label><input id="focusBefore" value="input before editor1"/>
+	<div data-dojo-type="dijit/Editor" aria-labelledby="label_editor1" data-dojo-props="onChange:function(v){console.log('editor1 onChange handler: ' + v)}, disableSpellCheck:true" id="editor1"
 	><p>This instance is created from a div directly with default toolbar and plugins</p>
 	The following HTML should appear as source: <INPUT TYPE="IMAGE" SRC="javascript:alert('no scripting attacks')">
 	</div>
-	<input id="focusAfter" value="input after editor1"/>
-	<button onClick="dijit.byId('editor1').destroy()">destroy</button>
-	<button onClick="dijit.byId('editor1').set('disableSpellCheck', !dijit.byId('editor1').get('disableSpellCheck'))">toggle spell check</button>
-	<button onclick="console.log(dijit.byId('editor1').get('value'))">getValue</button>
-	<button id="addStyleSheet" onclick="dijit.byId('editor1').addStyleSheet('test_editor.css')">add stylesheet</button>
-	<button id="removeStyleSheet" onclick="dijit.byId('editor1').removeStyleSheet('test_editor.css')">remove stylesheet</button>
+	<label for="focusAfter">lbl:</label><input id="focusAfter" value="input after editor1"/>
+	<button onClick="registry.byId('editor1').destroy()">destroy</button>
+	<button onClick="registry.byId('editor1').set('disableSpellCheck', !registry.byId('editor1').get('disableSpellCheck'))">toggle spell check</button>
+	<button onclick="console.log(registry.byId('editor1').get('value'))">getValue</button>
 	<hr/>
 
 	<h2>Created from div, auto-expanding</h2>
-	<h3><label>label for editor:</label></h3>
-	<div data-dojo-type="dijit.Editor" 
-		data-dojo-props="onChange:function(v){console.log('thud onChange handler: ' + v)}, extraPlugins:['dijit._editor.plugins.AlwaysShowToolbar'], styleSheets:'../../themes/claro/document.css', minHeight:'75px', height:''"
-		id="thud">
+	<h3><label id="label_thud">label for editor:</label></h3>
+	<div data-dojo-type="dijit/Editor"
+		data-dojo-props="onChange:function(v){console.log('thud onChange handler: ' + v)}, extraPlugins:['dijit/_editor/plugins/AlwaysShowToolbar'], styleSheets:'../../themes/claro/document.css', minHeight:'75px', height:''"
+		id="thud" aria-labelledby="label_thud">
 		Extra text
 		<p>
 			This editor is created from a div with AlwaysShowToolbar plugin (do not forget to set height="").
@@ -138,12 +137,12 @@
 	<hr/>
 
 	<h2>Optional toolbar buttons</h2>
-	<h3><label>blah entry</label></h3>
-	<div data-dojo-type="dijit.Editor"
-		data-dojo-props="plugins:['bold','italic','|','createLink','foreColor','hiliteColor',{name:'dijit._editor.plugins.FontChoice', command:'fontName', generic:true},'fontSize','formatBlock','insertImage','insertHorizontalRule'], styleSheets:'../../themes/claro/document.css'"
-		id="blah">
+	<h3><label id="label_blah">blah entry</label></h3>
+	<div data-dojo-type="dijit/Editor"
+		data-dojo-props="plugins:['bold','italic','|','createLink','foreColor','hiliteColor',{name:'dijit/_editor/plugins/FontChoice', command:'fontName', generic:true},'fontSize','formatBlock','insertImage','insertHorizontalRule'], styleSheets:'../../themes/claro/document.css'"
+		id="blah" aria-labelledby="label_blah">
 		This instance includes optional toolbar buttons which pull in additional ui (dijit) code.
-		Note the dojo.require() statements required to pull in the associated editor plugins to make
+		Note the require() arguments to pull in the associated editor plugins to make
 		this work.
 		<br>
 		<span style="font-family: serif">This is serif.</span>
@@ -158,13 +157,13 @@
 		<br>
 	</div>
 	<h3>..after</h3>
-	<button onclick="alert(dijit.byId('blah').get('value'));">getValue</button>
+	<button onclick="alert(registry.byId('blah').get('value'));">getValue</button>
 	<hr/>
 
 	<h2>Plugins specified</h2>
-	<h3><label>Another blah entry</label></h3>
-	<div data-dojo-type="dijit.Editor"
-		data-dojo-props="plugins:['bold','italic','|',{name:'dijit._editor.plugins.FontChoice', command:'fontName', custom:['Verdana','Myriad','Garamond','Apple Chancery','Hiragino Mincho Pro']}, {name:'dijit._editor.plugins.FontChoice', command:'fontSize', custom:[3,4,5]}, {name:'dijit._editor.plugins.EnterKeyHandling', blockNodeForEnter:'DIV'}], styleSheets:'../../themes/claro/document.css'"
+	<h3><label id="label_blah2">Another blah entry</label></h3>
+	<div data-dojo-type="dijit/Editor" aria-labelledby="label_blah2"
+		data-dojo-props="plugins:['bold','italic','|',{name:'dijit/_editor/plugins/FontChoice', command:'fontName', custom:['Verdana','Myriad','Garamond','Apple Chancery','Hiragino Mincho Pro']}, {name:'dijit/_editor/plugins/FontChoice', command:'fontSize', custom:[3,4,5]}, {name:'dijit/_editor/plugins/EnterKeyHandling', blockNodeForEnter:'DIV'}], styleSheets:'../../themes/claro/document.css'"
 		id="blah2">
 		This instance demos how to:
 		<ol>
@@ -176,17 +175,17 @@
 	<hr/>
 
 	<h2>Font sizing via style</h2> 
-	<div data-dojo-type="dijit.Editor" data-dojo-props="style:'text-align:left; font-size:30pt'" id="fontSizedEditor"> 
+	<div data-dojo-type="dijit/Editor" data-dojo-props="style:'text-align:left; font-size:30pt'" aria-label="fontSizedEditor" id="fontSizedEditor">
 		Hello World! 
 	</div> 
 
 	<h2>Checking pre-filter application</h2> 
-	<div data-dojo-type="dijit.Editor" data-dojo-props="extraPlugins:[{name: 'dijit.tests.editor.TestFilter'}]" id="filteredEditor"> 
+	<div data-dojo-type="dijit/Editor" data-dojo-props="extraPlugins:[{name: 'TestFilter'}]" aria-label="filteredEditor" id="filteredEditor">
 		notdojo 
 	</div> 
 
 	<h2>Checking editor starting with br</h2> 
-	<div data-dojo-type="dijit.Editor" id="brEditor"> 
+	<div data-dojo-type="dijit/Editor" id="brEditor" aria-label="brEditor">
 		<br>
 		some stuff
 		<br>
@@ -197,13 +196,13 @@
 	<div id="programmatic">This div will become an editor.</div>
 	<button
 		id="create"
-		onclick="new dijit.Editor({}, dojo.byId('programmatic')); dojo.query('#create').orphan();">
+		onclick="new Editor({}, dom.byId('programmatic')); query('#create').orphan();">
 	create static editor
 	</button>
 	<div id="programmatic2">This div will become an auto-expanding editor.</div>
 	<button
 		id="create2"
-		onclick="new dijit.Editor({height: '', extraPlugins: ['dijit._editor.plugins.AlwaysShowToolbar']}, dojo.byId('programmatic2')); dojo.query('#create2').orphan();">
+		onclick="new Editor({height: '', extraPlugins: ['dijit/_editor/plugins/AlwaysShowToolbar']}, dom.byId('programmatic2')); query('#create2').orphan();">
 	create expanding editor
 	</button>
 
diff --git a/dijit/tests/editor/test_FontChoice.html b/dijit/tests/editor/test_FontChoice.html
index 82c41e9..3f5b671 100755
--- a/dijit/tests/editor/test_FontChoice.html
+++ b/dijit/tests/editor/test_FontChoice.html
@@ -1,37 +1,32 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: FontChoice Plugin</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.FontChoice");
-		dojo.require("dijit._editor.plugins.ViewSource");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/Editor",
+			"dijit/_editor/plugins/FontChoice",
+			"dijit/_editor/plugins/ViewSource",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<br>
 	<br>
 	<div>Content before the editor.</div>
 	<br>
 	<br>
 	<p>Editor with default drop down lists:</p>
-	<div id="editor0" data-dojo-type="dijit.Editor"
-		data-dojo-props='extraPlugins:["fontName", "fontSize", "formatBlock", "viewSource"], height: "400px", style:"background-color: white; width: 100%;"'>
+	<div id="editor0" data-dojo-type="dijit/Editor"
+		data-dojo-props='"aria-label":"editor0", extraPlugins:["fontName", "fontSize", "formatBlock", "viewSource"], height: "400px", style:"background-color: white; width: 100%;"'>
 		<h1>Font Choice Plugin details</h1>
 		<ol>
 			<li>The Fontchoice plugin provides three dropdown menus for manipulating font information, such as
@@ -101,8 +96,8 @@
 	<br>
 	<br>
 	<p>Editor w/ plain text dropdown values:</p>
-	<div id="editor1" data-dojo-type="dijit.Editor"
-		data-dojo-props='extraPlugins:[{name: "fontName", plainText: true}, {name: "fontSize", plainText: true}, {name: "formatBlock", plainText: true}, "viewSource"], style:"background-color: white; width: 100%;", height: "400px"'>
+	<div id="editor1" data-dojo-type="dijit/Editor"
+		data-dojo-props='"aria-label":"editor1", extraPlugins:[{name: "fontName", plainText: true}, {name: "fontSize", plainText: true}, {name: "formatBlock", plainText: true}, "viewSource"], style:"background-color: white; width: 100%;", height: "400px"'>
 		<h1>Font Choice Plugin details</h1>
 		<ol>
 			<li>This instance of the FontChoice plugin just turns off formatted content in the dropdowns.  Everything should be the same font and size.</li>
@@ -119,8 +114,8 @@
 	<br>
 	<br>
 	<p>Editor w/ generic (web font names) font selector, traditional font name selector, font size selector, and format block selector:</p>
-	<div id="generic" data-dojo-type="dijit.Editor" data-dojo-props='height:"10em",
-		plugins:["bold", "italic", "underline", {name: "dijit._editor.plugins.FontChoice", command: "fontName", generic: true}, "fontName", "fontSize", "formatBlock"]'>hello world</div>
+	<div id="generic" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"generic", height:"10em",
+		plugins:["bold", "italic", "underline", {name: "dijit/_editor/plugins/FontChoice", command: "fontName", generic: true}, "fontName", "fontSize", "formatBlock"]'>hello world</div>
 	<br>
 	<br>
 	<div>Content after the editor.</div>
@@ -130,8 +125,8 @@
 	<br>
 	<br>
 	<p>Editor w/ custom font drop down list:</p>
-	<div id="custom" data-dojo-type="dijit.Editor" data-dojo-props='height:"10em",
-		plugins:["bold", "italic", "underline", {name: "dijit._editor.plugins.FontChoice", command: "fontName", custom:["Verdana","Myriad","Garamond"]}]'>
+	<div id="custom" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"custom", height:"10em",
+		plugins:["bold", "italic", "underline", {name: "dijit/_editor/plugins/FontChoice", command: "fontName", custom:["Verdana","Myriad","Garamond"]}]'>
 			This editor should let you set the fonts to
 			<span style="font-family:Verdana;">Verdana</span>, <span style="font-family:Myriad;">Myriad</span>, and <span style="font-family:Garamond;">Garamond</span>.
 	</div>
diff --git a/dijit/tests/editor/test_FullScreen.html b/dijit/tests/editor/test_FullScreen.html
index 2e852f8..0c1a400 100755
--- a/dijit/tests/editor/test_FullScreen.html
+++ b/dijit/tests/editor/test_FullScreen.html
@@ -1,41 +1,36 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: FullScreen Plugin</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.FullScreen");
-		dojo.require("dijit._editor.plugins.ViewSource");
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.layout.AccordionContainer");
-		dojo.require("dijit.layout.StackContainer");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/Editor",
+			"dijit/_editor/plugins/FullScreen",
+			"dijit/_editor/plugins/ViewSource",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/AccordionContainer",
+			"dijit/layout/StackContainer",
+			"dijit/layout/TabContainer",
+			"dijit/layout/ContentPane",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<br>
 	<br>
 	<div>Content before the editor.</div>
 	<br>
 	<br>
-	<div id="editor0" data-dojo-type="dijit.Editor"
-		data-dojo-props='extraPlugins:["fullscreen"], style:"background-color: white; width: 800px; height: 400px;" '>
+	<div id="editor0" data-dojo-type="dijit/Editor"
+		data-dojo-props='"aria-label":"editor0", extraPlugins:["fullscreen"], style:"background-color: white; width: 800px; height: 400px;" '>
 		<h1>Full Screen Plugin details</h1>
 		<ol>
 			<li>The Fullscreen plugin provides an extra button on the toolbar to allow switching the
@@ -64,13 +59,13 @@
 	<div>Content after the editor.</div>
 	<br>
 	<h1>BorderContainer with center region containing editor.</h1>
-	<div id="bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"width: 600px; height: 500px;"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width: 50px;"'>left</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"height: 50px;"'>top</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"right", style:"width: 50px;"'>right</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"height: 50px;"'>bottom</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
-			<div id="editor1" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["fullscreen","viewsource"], height:"100%"'>
+	<div id="bc" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='style:"width: 600px; height: 500px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width: 50px;"'>left</div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", style:"height: 50px;"'>top</div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"right", style:"width: 50px;"'>right</div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"bottom", style:"height: 50px;"'>bottom</div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
+			<div id="editor1" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor1", extraPlugins:["fullscreen","viewsource"], height:"100%"'>
 				<h1>Full Screen Plugin details</h1>
 				<ol>
 					<li>The Fullscreen plugin provides an extra button on the toolbar to allow switching the
@@ -98,9 +93,9 @@
 	</div>
 	<br>
 	<h1>TabContainer with tab containing editor.</h1>
-	<div id="tc" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Editor Tab"'>
-			<div id="editor2" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["fullscreen","viewsource"], height:"100%"'>
+	<div id="tc" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Editor Tab"'>
+			<div id="editor2" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor2", extraPlugins:["fullscreen","viewsource"], height:"100%"'>
 				<h1>Full Screen Plugin details</h1>
 				<ol>
 					<li>The Fullscreen plugin provides an extra button on the toolbar to allow switching the
@@ -125,18 +120,18 @@
 				</ol>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Tab 1"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Blank Tab 1"'>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Tab 2"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Blank Tab 2"'>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Tab 3"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Blank Tab 3"'>
 		</div>
 	</div>
 	<br>
 	<h1>AccordionContainer with pane containing editor.</h1>
-	<div id="ac" data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props='style:"width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Editor Pane"'>
-			<div id="editor3" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["fullscreen","viewsource"], height:"100%"'>
+	<div id="ac" data-dojo-type="dijit/layout/AccordionContainer" data-dojo-props='style:"width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Editor Pane"'>
+			<div id="editor3" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor3", extraPlugins:["fullscreen","viewsource"], height:"100%"'>
 				<h1>Full Screen Plugin details</h1>
 				<ol>
 					<li>The Fullscreen plugin provides an extra button on the toolbar to allow switching the
@@ -161,18 +156,18 @@
 				</ol>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 1"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Blank Pane 1"'>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 2"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Blank Pane 2"'>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 3"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Blank Pane 3"'>
 		</div>
 	</div>
 	<br>
 	<h1>StackContainer with pane containing editor.</h1>
-	<div id="sc" data-dojo-type="dijit.layout.StackContainer" data-dojo-props='style:"width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Editor Pane"'>
-			<div id="editor4" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["fullscreen","viewsource"], height:"100%"'>
+	<div id="sc" data-dojo-type="dijit/layout/StackContainer" data-dojo-props='style:"width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Editor Pane"'>
+			<div id="editor4" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor4", extraPlugins:["fullscreen","viewsource"], height:"100%"'>
 				<h1>Full Screen Plugin details</h1>
 				<ol>
 					<li>The Fullscreen plugin provides an extra button on the toolbar to allow switching the
@@ -197,11 +192,11 @@
 				</ol>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 1"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Blank Pane 1"'>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 2"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Blank Pane 2"'>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 3"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Blank Pane 3"'>
 		</div>
 	</div>
 </body>
diff --git a/dijit/tests/editor/test_LinkDialog.html b/dijit/tests/editor/test_LinkDialog.html
index 0024fb0..1681b6e 100755
--- a/dijit/tests/editor/test_LinkDialog.html
+++ b/dijit/tests/editor/test_LinkDialog.html
@@ -1,31 +1,26 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: LinkDialog Plugin</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.LinkDialog");
-		dojo.require("dijit._editor.plugins.ViewSource");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/Editor",
+			"dijit/_editor/plugins/LinkDialog",
+			"dijit/_editor/plugins/ViewSource",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<div style="border: 1px dotted black;">
-		<div id="editor" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["createLink", "insertImage", "viewSource"]'>
+		<div id="editor" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor",extraPlugins:["createLink", "insertImage", "viewSource"]'>
 			<ol>
 				<li>The LinkDialog plugin is an 'example' style plugin that shows how to insert basic web links as well as
 				image tags.  This plugin is intended to guide users in writing their own, more complex, link and image handlers
@@ -40,5 +35,23 @@
 			<br>
 		</div>
 	</div>
+
+	<p>RTL Editor:</p>
+	<div style="border: 1px dotted black;">
+		<div id="reditor" data-dojo-type="dijit/Editor" dir="rtl" data-dojo-props='"aria-label":"reditor",extraPlugins:["createLink", "insertImage"]'>
+			<ol>
+				<li>The LinkDialog plugin is an 'example' style plugin that shows how to insert basic web links as well as
+				image tags.  This plugin is intended to guide users in writing their own, more complex, link and image handlers
+				while still providing useful function.</li>
+			</ol>
+			<br>
+			<div><a href="http://www.example.com/example.html" target="_top" id="rexampleLink">This is an example link in the page.</a></div>
+			<br>
+			<br>
+			<div><img src="./sample.jpg" alt="Sample Image" id="rexampleImage" /></div>
+			<br>
+			<br>
+		</div>
+	</div>
 </body>
 </html>
diff --git a/dijit/tests/editor/test_NewPage.html b/dijit/tests/editor/test_NewPage.html
index 371bc9b..e14e830 100755
--- a/dijit/tests/editor/test_NewPage.html
+++ b/dijit/tests/editor/test_NewPage.html
@@ -1,35 +1,30 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: New Page Plugin</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.NewPage");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/Editor",
+			"dijit/_editor/plugins/NewPage",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<br>
 	<br>
 	<div>Content before the editor.</div>
 	<br>
 	<br>
-	<div id="editor0" data-dojo-type="dijit.Editor"
-		data-dojo-props='extraPlugins:["newpage"], style:"background-color: white; width: 800px;", height:"400px" '>
+	<div id="editor0" data-dojo-type="dijit/Editor"
+		data-dojo-props='"aria-label":"editor0",extraPlugins:["newpage"], style:"background-color: white; width: 800px;", height:"400px" '>
 		<h1>New Page Plugin details</h1>
 		<ol>
 			<li>The new page plugin is a small plugin that adds the capability of making a 'new page'.  In other words
@@ -43,8 +38,8 @@
 	</div>
 	<br>
 	<br>
-	<div id="editor1" data-dojo-type="dijit.Editor"
-		data-dojo-props='extraPlugins:[{name: "newpage", content: "<p>This page intentionally left blank</p>"}], style:"background-color: white; width: 800px;", height:"400px" '>
+	<div id="editor1" data-dojo-type="dijit/Editor"
+		data-dojo-props='"aria-label":"editor1",extraPlugins:[{name: "newpage", content: "<p>This page intentionally left blank</p>"}], style:"background-color: white; width: 800px;", height:"400px" '>
 		<h1>New Page Plugin details</h1>
 		<ol>
 			<li>The new page plugin is a small plugin that adds the capability of making a 'new page'.  In other words
diff --git a/dijit/tests/editor/test_Print.html b/dijit/tests/editor/test_Print.html
index f5ff6df..bb3de84 100755
--- a/dijit/tests/editor/test_Print.html
+++ b/dijit/tests/editor/test_Print.html
@@ -1,35 +1,30 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: Print  Plugin</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.Print");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/Editor",
+			"dijit/_editor/plugins/Print",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<br>
 	<br>
 	<div>Content before the editor.</div>
 	<br>
 	<br>
-	<div id="editor0" data-dojo-type="dijit.Editor"
-		data-dojo-props='extraPlugins:["print"], style:"background-color: white; width: 800px;", height: "400px"'>
+	<div id="editor0" data-dojo-type="dijit/Editor"
+		data-dojo-props='"aria-label":"editor0",extraPlugins:["print"], style:"background-color: white; width: 800px;", height: "400px"'>
 		<h1>Print Plugin details</h1>
 		<ol>
 			<li>The print plugin is a small plugin that adds the capability of printing the document in the editor</li>
diff --git a/dijit/tests/editor/test_TabIndent.html b/dijit/tests/editor/test_TabIndent.html
index ad32fb7..f750d20 100644
--- a/dijit/tests/editor/test_TabIndent.html
+++ b/dijit/tests/editor/test_TabIndent.html
@@ -1,33 +1,29 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor TabIndent Plugin Test</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
-	<script type="text/javascript" src="../_testCommon.js"></script>
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.TabIndent");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/Editor",
+			"dijit/_editor/plugins/TabIndent",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<p>Paragraph with focusable <span tabindex="0" style="color:blue">item </span>before editor. </p>
 	<label>Test TabIndent Plugin</label>
 	<div style="border: 1px dotted black;">
 	
-		<div id="tiTest" data-dojo-type="dijit.Editor"
-			data-dojo-props='extraPlugins:["tabIndent"]'>
+		<div id="tiTest" data-dojo-type="dijit/Editor"
+			data-dojo-props='"aria-label":"tiTest",extraPlugins:["tabIndent"]'>
 			<div>
 				<ol>
 				<li>the tabIndent plugin allows the use of the tab and shift-tab keys to
diff --git a/dijit/tests/editor/test_ToggleDir.html b/dijit/tests/editor/test_ToggleDir.html
index b9004d0..4fcdf17 100644
--- a/dijit/tests/editor/test_ToggleDir.html
+++ b/dijit/tests/editor/test_ToggleDir.html
@@ -1,31 +1,26 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: ToggleDir Plugin</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.ToggleDir");
-		dojo.require("dijit._editor.plugins.TabIndent");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/Editor",
+			"dijit/_editor/plugins/ToggleDir",
+			"dijit/_editor/plugins/TabIndent",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<div style="border: 1px dotted black;">
-		<div id="ed0" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["dijit._editor.plugins.ToggleDir"]'>
+		<div id="ed0" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"ed0",extraPlugins:["dijit/_editor/plugins/ToggleDir"]'>
 			<ol><li>the toggleDir plugin provides an extra button to switch text direction (BiDi). Useful when right-to-left 
 					languages are used with left-to-right languages.</li></ol>
 		</div>
diff --git a/dijit/tests/editor/test_ToggleDir_rtl.html b/dijit/tests/editor/test_ToggleDir_rtl.html
index a5a17be..1b09a28 100755
--- a/dijit/tests/editor/test_ToggleDir_rtl.html
+++ b/dijit/tests/editor/test_ToggleDir_rtl.html
@@ -1,32 +1,27 @@
 <!DOCTYPE html>
-<html style="overflow:hidden"> <!-- hide the scroll bars on ie6, to work around a doh robot bug-->
+<html style="overflow:hidden" lang="en"> <!-- hide the scroll bars on ie6, to work around a doh robot bug-->
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: ToggleDir Plugin (page in RTL)</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.ToggleDir");
-		dojo.require("dijit._editor.plugins.TabIndent");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/Editor",
+			"dijit/_editor/plugins/ToggleDir",
+			"dijit/_editor/plugins/TabIndent",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro" dir="rtl">
+<body class="claro" dir="rtl" role="main">
 <div style="position:absolute;left:0;" id=dummy>Text</div>
 	<div style="border: 1px dotted black;">
-		<div id="ed0" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:[{name:"dijit._editor.plugins.ToggleDir"}]'>
+		<div id="ed0" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"ed0",extraPlugins:[{name:"dijit/_editor/plugins/ToggleDir"}]'>
 			<ol><li>the toggleDir plugin provides an extra button to switch text direction (BiDi). Useful when right-to-left 
 					languages are used with left-to-right languages.</li></ol>
 		</div>
diff --git a/dijit/tests/editor/test_ViewSource.html b/dijit/tests/editor/test_ViewSource.html
index 3bbc6ed..f952898 100755
--- a/dijit/tests/editor/test_ViewSource.html
+++ b/dijit/tests/editor/test_ViewSource.html
@@ -1,36 +1,32 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: ViewSource Plugin</title>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!--<script type="text/javascript" src="../_testCommon.js"></script>-->
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.ViewSource");
-		dojo.require("dijit._editor.plugins.FullScreen");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/Editor",
+			"dijit/_editor/plugins/ViewSource",
+			"dijit/_editor/plugins/FullScreen",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<br>
 	<br>
 	<div>Content before the editors.</div>
 	<br>
 	<br>
 	<div>
-		<div id="editor0" data-dojo-type="dijit.Editor"
-			data-dojo-props='extraPlugins:["viewSource"], style:"background-color: white; width: 800px;", height:"400px" '>
+		<div id="editor0" data-dojo-type="dijit/Editor"
+			data-dojo-props='"aria-label":"editor0",extraPlugins:["viewSource"], style:"background-color: white; width: 800px;", height:"400px" '>
 			<h1>ViewSource Plugin details</h1>
 			<ol>
 				<li>The ViewSource plugin provides an extra button on the toolbar to allow switching the
@@ -60,8 +56,8 @@
 	<br>
 	<br>
 	<div>
-		<div id="editor1" data-dojo-type="dijit.Editor"
-			data-dojo-props='extraPlugins:["fullScreen","viewSource"], style:"background-color: white; width: 800px;", height:"300px" '>
+		<div id="editor1" data-dojo-type="dijit/Editor"
+			data-dojo-props='"aria-label":"editor1",extraPlugins:["fullScreen","viewSource"], style:"background-color: white; width: 800px;", height:"300px" '>
 			<h1>ViewSource Plugin with FullScreen Plugin details</h1>
 			<ol>
 				<li>The ViewSource plugin is FullScreen aware.  It will  should work appropriately when in full screen mode.</li>
@@ -77,8 +73,8 @@
 	<br>
 	<br>
 	<div>
-		<div id="editor2" data-dojo-type="dijit.Editor"
-			data-dojo-props='extraPlugins:["fullScreen",{name: "viewSource", readOnly: true}], style:"background-color: white; width: 800px;", height:"300px" '>
+		<div id="editor2" data-dojo-type="dijit/Editor"
+			data-dojo-props='"aria-label":"editor2",extraPlugins:["fullScreen",{name: "viewSource", readOnly: true}], style:"background-color: white; width: 800px;", height:"300px" '>
 			<h1>ViewSource Plugin with readOnly enabled details</h1>
 			<ol>
 				<li>The ViewSource plugin supports a readonly mode.  This should display the content but not allow any edits..</li>
@@ -93,8 +89,8 @@
 	<br>
 	<br>
 	<div>
-		<div id="editor3" data-dojo-type="dijit.Editor"
-			data-dojo-props='extraPlugins:["fullScreen",{name: "viewSource", stripScripts: false, stripComments: false, stripIFrames: false}],
+		<div id="editor3" data-dojo-type="dijit/Editor"
+			data-dojo-props='"aria-label":"editor3",extraPlugins:["fullScreen",{name: "viewSource", stripScripts: false, stripComments: false, stripIFrames: false}],
 			style:"background-color: white; width: 800px;", height:"300px" '>
 			<h1>ViewSource Plugin with script* disabled</h1>
 			<ol>
diff --git a/dijit/tests/editor/test_performance.html b/dijit/tests/editor/test_performance.html
new file mode 100644
index 0000000..ed85625
--- /dev/null
+++ b/dijit/tests/editor/test_performance.html
@@ -0,0 +1,169 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+	<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+	<title>test_performance</title>
+
+	<script type="text/javascript" src="../boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/_base/lang",
+			"dojo/parser",
+			"dijit/Editor",
+			"dijit/_editor/_Plugin",
+			"dijit/form/Button",
+			"dojo/domReady!"
+		], function(declare, lang, parser, Editor, _Plugin, Button){
+
+			var TestPluginGet = declare("TestPluginGet", _Plugin, {
+				// summary:
+				//		Get the value of the editor
+
+				showAlert: false,
+				logResults: false,
+
+				_initButton: function(){
+					this.button = new Button({
+						label: "get",
+						showLabel: true,
+						onClick: lang.hitch(this, "_get"),
+						title: "Dojo"
+					});
+				},
+
+				setEditor: function(editor){
+					this.editor = editor;
+					this._initButton();
+				},
+
+				_get: function(){
+					var getDate1 = new Date();
+					var html = this.editor.get("value");
+					var getDate2 = new Date();
+
+					var timeTakenGet = (getDate2.getTime() - getDate1.getTime()) / 1000;
+
+					if(this.showAlert){
+						alert("Get (" + timeTakenGet + " secs)\n"
+								+ "Steps: " + this.editor._steps.length);
+					}
+					if(this.logResults){
+						console.log("Get (" + timeTakenGet + " secs)");
+						console.log("Steps: " + this.editor._steps.length);
+					}
+				}
+
+			});
+			_Plugin.registry["testpluginget"] = function(args){
+				return new TestPluginGet(args);
+			};
+
+			var TestPluginSet = declare("TestPluginSet", _Plugin, {
+				// summary:
+				//		Set editor value
+
+				showAlert: false,
+
+				logResults: false,
+
+				htmlValue: "Lorem ipsum dolor sit amet.<br/> consectetur adipiscing elit.<br/> Aliquam at arcu sit amet enim tincidunt mattis.<br/> Pellentesque tincidunt interdum ipsum.<br/> condimentum congue libero <br/> a.<br/> Vivamus arcu metus.<br/> pharetra sed iaculis a.<br/> ullamcorper <br/> tortor.<br/> Praesent volutpat.<br/> erat in <br/> fringilla.<br/> dolor mi malesuada ligula.<br/> non adipiscing mi sem vel neque.<br/> Nam odio nibh.<br/> ultrices nec fringilla non.<br/> tempus vel [...]
+
+				_initButton: function(){
+					this.button = new Button({
+						label: "set",
+						showLabel: true,
+						onClick: lang.hitch(this, "_set"),
+						title: "Dojo"
+					});
+				},
+
+				setEditor: function(editor){
+					this.editor = editor;
+					this._initButton();
+				},
+
+				_set: function(){
+					var setDate1 = new Date();
+					this.editor.set("value", this.htmlValue);
+					var setDate2 = new Date();
+
+					var timeTakenSet = (setDate2.getTime() - setDate1.getTime()) / 1000;
+
+					if(this.showAlert){
+						alert("Set(" + timeTakenSet + " secs)\n"
+								+ "Steps: " + this.editor._steps.length
+						);
+					}
+					if(this.logResults){
+						console.log("Set(" + timeTakenSet + " secs)");
+						console.log("Steps: " + this.editor._steps.length);
+					}
+				}
+
+			});
+			_Plugin.registry["testpluginset"] = function(args){
+				return new TestPluginSet(args);
+			};
+
+			var TestPluginInsert = declare("TestPluginInsert", _Plugin, {
+				// summary:
+				//		Execute the inserthtml command at the current caret position
+
+				showAlert: false,
+
+				logResults: false,
+
+				_initButton: function(){
+					this.button = new Button({
+						label: "inserthtml",
+						showLabel: true,
+						onClick: lang.hitch(this, "_insert"),
+						title: "Dojo"
+					});
+				},
+
+				setEditor: function(editor){
+					this.editor = editor;
+					this._initButton();
+				},
+
+				_insert: function(){
+					var insertDate1 = new Date();
+					this.editor.execCommand("inserthtml", "<span class=\"cursorSpan\">Insert</span>");
+					var insertDate2 = new Date();
+
+					var timeTakenInsert = (insertDate2.getTime() - insertDate1.getTime()) / 1000;
+
+					if(this.showAlert){
+						alert("insertHTML(" + timeTakenInsert + " secs)\n"
+								+ "Steps: " + this.editor._steps.length);
+					}
+					if(this.logResults){
+						console.log("insertHTML(" + timeTakenInsert + " secs)");
+						console.log("Steps: " + this.editor._steps.length);
+					}
+				}
+			});
+			_Plugin.registry["testplugininsert"] = function(args){
+				return new TestPluginInsert(args);
+			};
+
+			parser.parse();
+		});
+	</script>
+</head>
+<body class="claro" role="main">
+	<h1>Dojo Editor PerformanceTest</h1>
+	<!-- plugins="[]"  -->
+	<div dojoType="dijit/Editor" aria-label="editor1" id="editor1"
+		 customUndo="false"
+		 extraPlugins="[
+		  {name: 'testpluginset', showAlert: true},
+		  {name: 'testpluginget', showAlert: true},
+		  {name: 'testplugininsert', showAlert: true}
+		]">
+	</div>
+</body>
+</html>
diff --git a/dijit/tests/focus.html b/dijit/tests/focus.html
new file mode 100644
index 0000000..f808a84
--- /dev/null
+++ b/dijit/tests/focus.html
@@ -0,0 +1,392 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>dijit/focus automated test</title>
+
+		<style type="text/css">
+			@import "../themes/claro/document.css";
+			@import "css/dijitTests.css";
+		</style>
+
+		<!-- required: a default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../dojo/dojo.js"></script>
+
+		<script type="text/javascript">
+			require([
+				"doh/runner", "dojo/_base/array", "dojo/dom", "dojo/on", "dojo/parser", "dojo/query",
+				"dijit/focus", "dijit/registry", "dijit/tests/helpers",
+				"dojo/domReady!",
+				"dijit/form/DateTextBox", "dijit/form/ComboBox", "dijit/form/NumberSpinner","dijit/form/ComboButton",
+				"dijit/Menu", "dijit/MenuItem", "dijit/PopupMenuItem", "dijit/layout/ContentPane", "dijit/Editor"
+			], function(doh, array, dom, on, parser, query, focus, registry, helpers){
+
+				doh.register("setup", [
+					function parse(){
+						parser.parse();
+						return helpers.waitForLoad();
+					},
+					function listeners(){
+						array.forEach(["form", "fieldset1", "fieldset2", "select", "editor", "spinner"], function(id){
+							var w = registry.byId(id);
+
+							// old API is to connect to onFocus/onBlur (remove in 2.0)
+							w.on("focus", function(){
+								focusEvents[id] = true;
+							});
+							w.on("blur", function(){
+								blurEvents[id] = true;
+							});
+
+							// new API is to watch "focused" attribute
+							w.watch("focused", function(name, oldValue, newValue){
+								// keep track of current state
+								focusedState[name] = newValue;
+
+								// keep log of every watch notification
+								var nvs = newValue ? "focused" : "blurred";
+								focusedWatchLog[w.id] = !focusedWatchLog[w.id] ? nvs : focusedWatchLog[w.id] + ", " + nvs;
+							});
+						});
+
+						// And there's also a curNode attribute that you can watch
+						focus.watch("curNode", function(name, oldValue, newValue){
+							curNodeWatchLog.push(newValue ? newValue.id || newValue.tagName : "null")
+						});
+					}
+				]);
+
+				function resetEvents(){
+					// These are objects used to track calls to _onFocus and _onBlur in various widgets
+					focusEvents = {};
+					blurEvents = {};
+					focusedState = {};
+					focusedWatchLog = {};
+
+					// This tracks watch("curNode")
+					curNodeWatchLog = [];
+				}
+				resetEvents();
+
+				doh.register("basic", [
+					{
+						name: "focus simple input",
+						timeout: 4000,
+						setUp: function(){
+							resetEvents();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Focus the simple input
+							dom.byId("first").focus();
+
+							setTimeout(d.getTestCallback(function(){
+								// Make sure that focus manager caught the focus event
+								doh.is(dom.byId("first"), focus.curNode);
+								doh.is("first", curNodeWatchLog.join(", "), "curNodeWatchLog");
+
+								// And that the dijit.form.Form widget is marked as
+								// being "in focus"
+								doh.t(focusEvents["form"], "form focused");
+								
+								// And that it got one watch event
+								doh.is("focused", focusedWatchLog["form"], "watch callback");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "focus another simple input",
+						timeout: 4000,
+						setUp: function(){
+							resetEvents();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Focus the simple input
+							dom.byId("second").focus();
+
+							setTimeout(d.getTestCallback(function(){
+								// Make sure that focus manager caught the focus event
+								doh.is(dom.byId("second"), focus.curNode);
+								doh.is("second", curNodeWatchLog.join(", "), "curNodeWatchLog");
+
+								// Since the dijit.form.Form widget didn't leave the focus chain it
+								// shouldn't have any more events (since the resetEvents() call in setUp() above)
+								doh.f("form" in focusEvents, "form no new focus event");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "focus combobox",
+						timeout: 4000,
+						setUp: function(){
+							resetEvents();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var watchedActiveStack, activeStackWatchNotifications = 0;
+							focus.watch("activeStack", function(attr, oldVal, newVal){
+								watchedActiveStack = newVal;
+								activeStackWatchNotifications++;
+							});
+
+							// This onFocus() function from helpers.js would be useful here, except it
+							// defeats the purpose of the test by using dijit/focus.
+							on.once(registry.byId("select").focusNode, "focus", function(){
+								setTimeout(d.getTestCallback(function(){
+									// Focus goes to an <input> node deep inside of select.domNode,
+									// but that <input> node has the id of the widget
+									doh.is(dom.byId("select"), focus.curNode);
+
+									// The focus stack should show the ComboBox plus all parent widgets
+									var stack = focus.activeStack;
+									doh.is("form, fieldset1, select", stack.join(", "), "active stack");
+
+									// Also check that we got (exactly) one watch notification about active stack
+									doh.is(1, activeStackWatchNotifications, "one watch() on activeStack");
+									doh.is("form, fieldset1, select", watchedActiveStack.join(", "), "watched active stack");
+
+									// _onFocus()/_onBlur was called appropriately
+									doh.f(focusEvents["form"], "form was already focused, no duplicate event");
+									doh.f(blurEvents["form"], "form wasn't blurred");
+									doh.t(focusEvents["fieldset1"], "fieldset1 focused");
+									doh.t(focusEvents["select"], "select focused");
+
+									doh.f(focusedWatchLog["form"], "form watch callback (no new notification)");
+									doh.is("focused", focusedWatchLog["fieldset1"], "fieldset watch callback");
+									doh.is("focused", focusedWatchLog["select"], "select watch callback");
+								}), 100);
+							});
+							registry.byId("select").focus();
+
+							return d;
+						}
+					},
+					{
+						name: "focus combobox again",
+						timeout: 4000,
+						setUp: function(){
+							resetEvents();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var again;
+							focus.watch("activeStack", function(){
+								again = true;
+							});
+
+							registry.byId("select").focus();
+
+							on.emit(registry.byId("select").focusNode, "mousedown", {bubbles: true});
+							on.emit(registry.byId("select").focusNode, "mouseup", {bubbles: true});
+
+							setTimeout(d.getTestCallback(function(){
+								doh.f(again, "duplicate notification about activeStack");
+							}), 100);
+
+							return d;
+						}
+					},
+					{
+						name: "focus editor",
+						timeout: 4000,
+						setUp: function(){
+							resetEvents();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							registry.byId("editor").focus();
+
+							setTimeout(d.getTestCallback(function(){
+								// The focus stack should show the Editor plus all parent widgets
+								var stack = focus.activeStack;
+								doh.is("form, editor", stack.join(", "), "active stack");
+
+								// _onFocus()/_onBlur was called appropriately
+								doh.f(focusEvents["form"], "form was already focused, no duplicate event");
+								doh.f(blurEvents["form"], "form wasn't blurred");
+								doh.t(blurEvents["fieldset1"], "fieldset no longer focused");
+								doh.t(focusEvents["editor"], "editor focused");
+
+								doh.f(focusedWatchLog["form"], "form watch callback (no new notification)");
+								doh.is("blurred", focusedWatchLog["fieldset1"], "fieldset watch callback, no longer focused");
+								doh.is("blurred", focusedWatchLog["select"], "select watch callback, no longer focused");
+								doh.is("focused", focusedWatchLog["editor"], "editor watch callback");
+							}), 500);
+
+							return d;
+						}
+					},
+
+					// clicking spinner buttons should activate the spinner, even
+					// though there's no actual DOM focus event
+					{
+						name: "spinner",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var upArrow = query(".dijitSpinner .dijitUpArrowButton")[0];
+							doh.t(upArrow, "found the up arrow");
+
+							on.emit(upArrow, "mousedown", {
+								bubbles: true,
+								cancelable: true,
+								which: 1
+							});
+							on.emit(upArrow, "mouseup", {
+								bubbles: true,
+								cancelable: true,
+								which: 1
+							});
+							on.emit(upArrow, "click", {
+								bubbles: true,
+								cancelable: true,
+								which: 1
+							});
+
+							setTimeout(d.getTestCallback(function(){
+								// The focus stack should show the Spinner plus all parent widgets
+								var stack = focus.activeStack;
+								doh.is("form, fieldset2, spinner", stack.join(", "), "active stack");
+
+								// check watch callbacks
+								doh.f(focusedWatchLog["form"], "grandparent of spinner stayed focused, so no new watch event (watch)");
+								doh.is("focused", focusedWatchLog["fieldset2"], "parent of spinner (watch)");
+								doh.is("focused", focusedWatchLog["spinner"], "spinner (watch)");
+							}), 500);
+
+							return d;
+						}
+					}/*,
+					// FIXME: this test is invalid because focus is not designed to change on mouse click to the first item in the menu
+					{
+						name: "combo button menu",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var button = registry.byId('button').focusNode;
+							doh.t(button, "found drop down button");
+
+							doh.robot.mouseMoveAt(button);
+							doh.robot.mouseClick({left: true}, 500);
+
+							setTimeout(d.getTestCallback(function(){
+								// Focus goes to an first item in the drop down menu
+								doh.is(dom.byId("mi1").id, focus.curNode.id);
+
+								// The focus stack should show the ComboBox plus all parent widgets
+								var stack = focus.activeStack;
+								console.log("menu stack is ", stack);
+								doh.is("form, fieldset2, button, menu, mil", stack.join(", "), "active stack");
+							}), 500);
+
+							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handle);
+						}
+					}*/
+
+/*
+					// Commented out because
+					// in order to allow dijit.popup's getTopPopup() to work,a sub menu's popupParent
+					// points to the parent Menu, bypassing the parent MenuItem... thus the
+					// MenuItem is not in the chain of active widgets
+					{
+						name: "nested menu",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("popupMenuItem");
+
+							setTimeout(d.getTestCallback(function(){
+								// Focus goes to an first item in the sub menu
+								doh.is(dom.byId("smi1"), focus.curNode);
+
+								// The focus stack should show the two submenus and then upwards
+								// to the ComboButton, and the rest
+								var stack = focus.activeStack;
+								console.log("menu stack is ", stack);
+								doh.is("form, fieldset2, button, menu, mil, submenu, smil", stack.join(", "), "active stack");
+							}), 1000);
+
+							return d;
+						}
+					}
+*/
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+	<body style="background-color: #fff; color: black; padding: 0; margin: 0" class="claro">
+	
+		<h3>Dijit/focus Automated Test</h3>
+
+		<label>a form ContentPane widget:</label><br>
+		<form id="form" data-dojo-type="dijit/layout/ContentPane" >
+			<label for="first">simple input: </label><input id="first"/><br>
+			<label for="second">another simple input: </label><input id="second"/><br>
+
+			<label>a fieldset ContentPane widget:</label><br>
+			<fieldset id=fieldset1 data-dojo-type="dijit/layout/ContentPane">
+				<label for="select">a ComboBox widget:</label>
+				<select id=select data-dojo-type="dijit/form/ComboBox">
+					<option>this</option>
+					<option>is</option>
+					<option>a</option>
+					<option>list</option>
+				</select>
+				<label for="plain">a plain input:</label>
+				<input id=plain value=plain/>
+			</fieldset>
+			<div id=editor data-dojo-type="dijit/Editor" >
+				Hello world, this is an <i>editor</i>
+			</div>
+			<br>
+			<label>another fieldset ContentPane:</label><br>
+			<fieldset id=fieldset2 data-dojo-type="dijit/layout/ContentPane">
+				<label for="date">a DateTextBox widget:</label>
+				<input id=date data-dojo-type="dijit/form/DateTextBox"/><br>
+	
+				<label for="textarea">a plain textarea:</label><br>
+				<textarea id=textarea>hello there!</textarea><br>
+	
+				<label for="spinner">a Spinner widget:</label>
+				<input id=spinner data-dojo-type="dijit/form/NumberSpinner" data-dojo-props='value:100'/><br>
+	
+				<label>a Combobutton widget:</label>
+				<div id=button data-dojo-type="dijit/form/ComboButton" data-dojo-props='tabIndex:"0"'>
+					<span>push me</span>
+					<div id=menu data-dojo-type="dijit/Menu">
+						<div id=mi1 data-dojo-type="dijit/MenuItem">menu item 1</div>
+						<div id=mi2 data-dojo-type="dijit/MenuItem">menu item 2</div>
+						<div id=popupMenuItem data-dojo-type="dijit/PopupMenuItem">
+							<span>submenu</span>
+							<div id=submenu data-dojo-type="dijit/Menu">
+								<div id=smi1 data-dojo-type="dijit/MenuItem">submenu item 1</div>
+								<div id=smi2 data-dojo-type="dijit/MenuItem">submenu item 2</div>
+							</div>
+						</div>
+					</div>
+				</div>
+			</fieldset>
+		</form>
+	</body>
+</html>
diff --git a/dijit/tests/form/AutoCompleterMixin.html b/dijit/tests/form/AutoCompleterMixin.html
index 5958b79..f05e350 100644
--- a/dijit/tests/form/AutoCompleterMixin.html
+++ b/dijit/tests/form/AutoCompleterMixin.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
@@ -147,7 +147,7 @@
 					name: "dijit",
 					timeout: 2000,
 					runTest: function(){
-						new dijit.form.ComboBox({id:"dijit_programmatic", list:"states"}).placeAt("dijit_programmatic_container", "first");
+						new dijit.form.ComboBox({id:"dijit_programmatic", list:"states", "aria-label":"dijit_programmatic",value:"Alabama"}).placeAt("dijit_programmatic_container", "first");
 						var dijit_programmatic = dijit.byId('dijit_programmatic');
 						var focushandle = dijit_programmatic.connect(dijit_programmatic, '_onFocus',
 							function(){
@@ -169,7 +169,7 @@
 					name: "mobile",
 					timeout: 2000,
 					runTest: function(){
-						new dojox.mobile.ComboBox({id:"mobile_programmatic", list:"states"}).placeAt("mobile_programmatic_container", "first");
+						new dojox.mobile.ComboBox({id:"mobile_programmatic", list:"states", "aria-label":"mobile_programmatic", value:"Alabama"}).placeAt("mobile_programmatic_container", "first");
 						var mobile_programmatic = dijit.byId('mobile_programmatic');
 						var focushandle = mobile_programmatic.connect(mobile_programmatic.textbox, 'onfocus',
 							function(){
@@ -193,10 +193,10 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1 class="testTitle">_AutoCompleterMixin (dijit and mobile) non-robot tests</h1>
 	<datalist id="states">
-	<select data-dojo-type="dijit.form.DataList" data-dojo-props='id:"states"' >
+	<select data-dojo-type="dijit/form/DataList" data-dojo-props='id:"states"' >
 		<option value="AL">Alabama</option>
 		<option value="AK">Alaska</option>
 		<option value="AS">American Samoa</option>
@@ -268,13 +268,13 @@
 		</tr>
 		<tr>
 			<td class="layout">attributes</td>
-			<td class="layout"><input id="dijit_attributes" data-dojo-type="dijit.form.ComboBox" data-dojo-props='value:"", list:"states"'/></td>
-			<td class="layout"><input id="mobile_attributes" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"", list:"states"'></td>
+			<td class="layout"><input id="dijit_attributes" aria-label="dijit_attributes" data-dojo-type="dijit/form/ComboBox" data-dojo-props='value:"", list:"states"'/></td>
+			<td class="layout"><input id="mobile_attributes" aria-label="mobile_attributes" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"", list:"states"'></td>
 		</tr>
 		<tr>
 			<td class="layout">Events</td>
-			<td class="layout"><input id="dijit_events" data-dojo-type="dijit.form.ComboBox" data-dojo-props='value:"", list:"states", onFocus:function(){ return false; }, onBlur:function(){ return false; }, onChange:function(){ return false; }'/></td>
-			<td class="layout"><input id="mobile_events" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"", list:"states", onChange:function(){ return false; }'></td>
+			<td class="layout"><input id="dijit_events" aria-label="dijit_events" data-dojo-type="dijit/form/ComboBox" data-dojo-props='value:"", list:"states", onFocus:function(){ return false; }, onBlur:function(){ return false; }, onChange:function(){ return false; }'/></td>
+			<td class="layout"><input id="mobile_events" aria-label="mobile_events" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"", list:"states", onChange:function(){ return false; }'></td>
 		</tr>
 		<tr>
 			<td class="layout">Programmatic</td>
diff --git a/dijit/tests/form/ButtonMixin.html b/dijit/tests/form/ButtonMixin.html
index d9eaa2b..92b3f54 100644
--- a/dijit/tests/form/ButtonMixin.html
+++ b/dijit/tests/form/ButtonMixin.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
@@ -31,6 +31,7 @@
 	<script type="text/javascript">
 		dojo.require("doh.runner");
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.Dialog");
 		dojo.require("dijit.form.Button");
 		dojo.require("dojox.mobile.Button");
 
@@ -65,50 +66,6 @@
 	 			}
 			]);
 
-			doh.register("events", [
-				{
-					name: "dijit",
-					timeout: 2000,
-					runTest: function(){
-						var
-							dijit_events = dijit.byId('dijit_events'),
-							calledOnClick = false,
-							nop = function(){ return false; };
-
-						function onClick(){
-							dijit_events.set('onClick', nop);
-							calledOnClick = true;
-							return true;
-						}
-						doh.f(dijit_events._onClick({ preventDefault: nop }), "_onClick");
-						dijit_events.set('onClick', onClick);
-						dijit_events._onClick({ preventDefault: nop });
-						doh.t(calledOnClick, "calledOnClick");
-					}
-	 			},
-				{
-					name: "mobile",
-					timeout: 2000,
-					runTest: function(){
-						var
-							d = new doh.Deferred(),
-							mobile_events = dijit.byId('mobile_events'),
-							nop = function(){ return false; };
-
-						function onClick(){
-							mobile_events.set('onClick', nop);
-							d.callback(true);
-							return true;
-						}
-						doh.f(mobile_events._onClick({ preventDefault: nop }), "_onClick");
-						mobile_events.set("onClick", onClick);
-						setTimeout(function(){ mobile_events.focusNode.click({ preventDefault: nop }); }, 0);
-
-						return d;
-					}
-	 			}
-			]);
-
 			doh.register("programmatic", [
 				{
 					name: "dijit",
@@ -134,11 +91,103 @@
 	 			}
 			]);
 
+			var runTests = function(t,i){
+				var	d = new doh.Deferred(),
+					form = document.getElementById('myform'),
+					clicks = document.getElementById('clicks'),
+					submits = document.getElementById('submits'),
+					bubbles = document.getElementById('bubbles');
+				form.reset();
+				document.getElementById('native'+i).click();
+				setTimeout(function(){
+					var nativeClicks = clicks.value;
+					var nativeSubmits = submits.value;
+					var nativeBubbles = bubbles.value;
+					form.reset();
+					document.getElementById('widget'+i).click();
+					setTimeout(function(){
+						var widgetClicks = clicks.value;
+						var widgetSubmits = submits.value;
+						var widgetBubbles = bubbles.value;
+						form.reset();
+						document.getElementById('mobile'+i).click();
+						setTimeout(function(){
+							var mobileClicks = clicks.value;
+							var mobileSubmits = submits.value;
+							var mobileBubbles = bubbles.value;
+							form.reset();
+							document.getElementById('dialogButton'+i).click();
+							setTimeout(d.getTestCallback(function(){
+								var dialogClicks = clicks.value;
+								var dialogSubmits = submits.value;
+								var dialogBubbles = bubbles.value;
+								t.is(nativeClicks, widgetClicks, "widget clicks");
+								t.is(nativeSubmits, widgetSubmits, "widget submits");
+								t.is(nativeBubbles, widgetBubbles, "widget bubbles");
+								t.isNot("000", widgetClicks+""+widgetSubmits+""+widgetBubbles, "not all 0");
+								t.is(nativeClicks, mobileClicks, "mobile clicks");
+								t.is(nativeSubmits, mobileSubmits, "mobile submits");
+								t.is(nativeBubbles, mobileBubbles, "mobile bubbles");
+								t.is(nativeClicks, dialogClicks, "dialog clicks");
+								t.is(nativeSubmits, dialogSubmits, "dialog submits");
+								t.is(nativeBubbles, dialogBubbles, "dialog bubbles");
+							}), 0);
+						}, 0);
+					}, 0);
+				}, 0);
+				return d;
+			};
+
+			doh.register("click behavior", [
+				{
+					name: "return true",
+					timeout: 1000,
+					runTest: function(t){
+						runTests(t,1);
+					}
+				},
+				{
+					name: "return false",
+					timeout: 1000,
+					runTest: function(t){
+						runTests(t,2);
+					}
+				},
+				{
+					name: "stopProgation + return true",
+					timeout: 1000,
+					runTest: function(t){
+						runTests(t,3);
+					}
+				},
+				{
+					name: "stopProgation + return false",
+					timeout: 1000,
+					runTest: function(t){
+						runTests(t,4);
+					}
+				},
+				{
+					name: "preventDefault + return true",
+					timeout: 1000,
+					runTest: function(t){
+						runTests(t,5);
+					}
+				},
+				{
+					name: "preventDefault + return false",
+					timeout: 1000,
+					runTest: function(t){
+						runTests(t,6);
+					}
+				}
+			]);
+
 			doh.run();
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1 class="testTitle">_ButtonMixin (dijit and mobile) non-robot tests</h1>
 
 	<table id="table">
@@ -149,20 +198,59 @@
 		</tr>
 		<tr>
 			<td class="layout">attributes</td>
-			<td class="layout"><input id="dijit_attributes" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", label:"original", "class":"mblRedButton"'/></td>
+			<td class="layout"><input id="dijit_attributes" data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", label:"original", "class":"mblRedButton"'/></td>
 			<td class="layout"><button type="button" class="mblRedButton" id="mobile_attributes" dojoType="dojox.mobile.Button" label="original"/></td>
 		</tr>
 		<tr>
-		<tr>
-			<td class="layout">Events</td>
-			<td class="layout"><button id="dijit_events" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ return false; }'>innerHTML</button></td>
-			<td class="layout"><button type="button" id="mobile_events" data-dojo-type="dojox.mobile.Button" data-dojo-props='type:"button", onClick:function(){ return false; }'>innerHTML</button></td>
-		</tr>
-		<tr>
 			<td class="layout">Programmatic</td>
 			<td class="layout" id="dijit_programmatic_container"></td>
 			<td class="layout" id="mobile_programmatic_container"></td>
 		</tr>
 	</table>
+	<form id="myform" method="get" onsubmit="document.getElementById('submits').value++;return false" onclick="document.getElementById('bubbles').value++;return true;" style="border:1px solid black;margin:10px 0;">
+		<legend>Compare native and widget click event behavior:</legend>
+		<label for="submits">Submits</label><input id="submits" size="4" disabled value="0">
+		<label for="bubbles">Bubbles</label><input id="bubbles" size="4" disabled value="0">
+		<label for="clicks">Clicks</label><input id="clicks" size="4" disabled value="0">
+		<input type="reset" id="formContainerReset">
+		<br>
+		<button id="native1" type="submit" onclick="document.getElementById('clicks').value++;return true;">native return true</button>
+		<button id="widget1" type="submit" onclick="document.getElementById('clicks').value++;return true;" data-dojo-type="dijit/form/Button">widget return true</button>
+		<button id="mobile1" type="submit" onclick="document.getElementById('clicks').value++;return true;" data-dojo-type="dojox/mobile/Button">mobile return true</button>
+		<button id="dialog1" type="button" onclick="arguments[0].stopPropagation();arguments[0].preventDefault();document.getElementById('dialogButton1').click();return false;" data-dojo-type="dijit/form/Button">dialog return true</button>
+		<br>
+		<button id="native2" type="submit" onclick="document.getElementById('clicks').value++;return false;">native return false</button>
+		<button id="widget2" type="submit" onclick="document.getElementById('clicks').value++;return false;" data-dojo-type="dijit/form/Button">widget return false</button>
+		<button id="mobile2" type="submit" onclick="document.getElementById('clicks').value++;return false;" data-dojo-type="dojox/mobile/Button">mobile return false</button>
+		<button id="dialog2" type="button" onclick="arguments[0].stopPropagation();arguments[0].preventDefault();document.getElementById('dialogButton2').click();return false;" data-dojo-type="dijit/form/Button">dialog return false</button>
+		<br>
+		<button id="native3" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].stopPropagation();return true;">native stopPropagation + return true</button>
+		<button id="widget3" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].stopPropagation();return true;" data-dojo-type="dijit/form/Button">widget stopPropagation + return true</button>
+		<button id="mobile3" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].stopPropagation();return true;" data-dojo-type="dojox/mobile/Button">mobile stopPropagation + return true</button>
+		<button id="dialog3" type="button" onclick="arguments[0].stopPropagation();arguments[0].preventDefault();document.getElementById('dialogButton3').click();return false;" data-dojo-type="dijit/form/Button">dialog stopPropagation + return true</button>
+		<br>
+		<button id="native4" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].stopPropagation();return false;">native stopPropagation + return false</button>
+		<button id="widget4" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].stopPropagation();return false;" data-dojo-type="dijit/form/Button">widget stopPropagation + return false</button>
+		<button id="mobile4" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].stopPropagation();return false;" data-dojo-type="dojox/mobile/Button">mobile stopPropagation + return false</button>
+		<button id="dialog4" type="button" onclick="arguments[0].stopPropagation();arguments[0].preventDefault();document.getElementById('dialogButton4').click();return false;" data-dojo-type="dijit/form/Button">dialog stopPropagation + return false</button>
+		<br>
+		<button id="native5" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].preventDefault();return true;">native preventDefault + return true</button>
+		<button id="widget5" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].preventDefault();return true;" data-dojo-type="dijit/form/Button">widget preventDefault + return true</button>
+		<button id="mobile5" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].preventDefault();return true;" data-dojo-type="dojox/mobile/Button">mobile preventDefault + return true</button>
+		<button id="dialog5" type="button" onclick="arguments[0].stopPropagation();arguments[0].preventDefault();document.getElementById('dialogButton5').click();return false;" data-dojo-type="dijit/form/Button">dialog preventDefault + return true</button>
+		<br>
+		<button id="native6" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].preventDefault();return false;">native preventDefault + return false</button>
+		<button id="widget6" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].preventDefault();return false;" data-dojo-type="dijit/form/Button">widget preventDefault + return false</button>
+		<button id="mobile6" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].preventDefault();return false;" data-dojo-type="dojox/mobile/Button">mobile preventDefault + return false</button>
+		<button id="dialog6" type="button" onclick="arguments[0].stopPropagation();arguments[0].preventDefault();document.getElementById('dialogButton6').click();return false;" data-dojo-type="dijit/form/Button">dialog preventDefault + return false</button>
+	</form> 
+	<div data-dojo-type="dijit/Dialog" onExecute="document.getElementById('submits').value++;return false" onclick="document.getElementById('bubbles').value++;return true;">
+		<button id="dialogButton1" type="submit" onclick="document.getElementById('clicks').value++;return true;" data-dojo-type="dijit/form/Button"></button>
+		<button id="dialogButton2" type="submit" onclick="document.getElementById('clicks').value++;return false;" data-dojo-type="dijit/form/Button"></button>
+		<button id="dialogButton3" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].stopPropagation();return true;" data-dojo-type="dijit/form/Button"></button>
+		<button id="dialogButton4" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].stopPropagation();return false;" data-dojo-type="dijit/form/Button"></button>
+		<button id="dialogButton5" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].preventDefault();return true;" data-dojo-type="dijit/form/Button"></button>
+		<button id="dialogButton6" type="submit" onclick="document.getElementById('clicks').value++;arguments[0].preventDefault();return false;" data-dojo-type="dijit/form/Button"></button>
+	</div>
 </body>
 </html>
diff --git a/dijit/tests/form/CheckBox.html b/dijit/tests/form/CheckBox.html
new file mode 100644
index 0000000..34defbd
--- /dev/null
+++ b/dijit/tests/form/CheckBox.html
@@ -0,0 +1,262 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Checkbox unit Test</title>
+
+		<style type="text/css">
+			@import "../../themes/claro/document.css";
+			@import "../css/dijitTests.css";
+
+			label { margin-right: 0.80em; }
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+
+		<script type="text/javascript">
+			function defaultSubmitHandler(values){
+				console.debug('actual submitted values: ' + json.stringify(values));
+			}
+			submittedValues = defaultSubmitHandler;
+
+			require([
+				"doh/runner",
+				"dojo/dom", "dojo/json", "dojo/parser", "dojo/query",
+				"dijit/registry", "dijit/form/CheckBox", "dijit/form/Form", "dojo/domReady!"
+			], function(doh, dom, json, parser, query, registry, CheckBox){
+
+				// These are the values assigned to the widgets in the page's HTML
+				var originalGet = {
+					cb1: [],
+					cb2: ["on"],
+					cb4: ["on"],
+					cb5: [],
+					cb6: ["on"],
+					cb7: []
+				};
+	
+				var originalSubmit = {
+					cb2: "on",
+					cb4: "on",
+					cb6: "on"
+				};
+	
+				// attempt to change these values
+				var change = {
+					cb1: ["foo"],
+					cb2: [],
+					cb3: ["on"],
+					cb4: [],
+					cb5: ["on"],
+					cb6: ["foo"]
+				};
+	
+				// changed values
+				var changedGet = {
+					cb1: ["foo"],
+					cb2: [],
+					cb4: [],
+					cb5: ["on"],
+					cb6: [],
+					cb7: []
+				};
+	
+				var changedSubmit = {
+					cb1: "foo",
+					cb5: "on"
+				};
+		
+				doh.register("setup", [
+					function parse(){
+						parser.parse();
+					},
+					function programmatic(){
+						new CheckBox({id: "cb6", name: "cb6", checked: true }, "cb6");
+					}
+				]);
+
+				// should be able to query for all of the inputs, including hidden ones
+				doh.register("query input by checked state", [
+					{
+						name: "query checked",
+						runTest: function(){
+							var queried = query("input[checked]", dom.byId('myForm'));
+							doh.is(3, queried.length, "num checked widgets");
+						}
+					}
+				]);
+
+				doh.register("query input by name", [
+					{
+						name: "query name",
+						runTest: function(){
+							var queried = query("input[name]", dom.byId('myForm'));
+							doh.is(7, queried.length, "input[name]");
+						}
+					}
+				]);
+
+				var formWidget = registry.byId("myForm");
+
+				var submitForm = function(name, testValues){
+					return {
+						name: name,
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							submittedValues = function(formValues){
+								d.getTestCallback(function(){
+									for(var i in originalGet){ doh.is(testValues[i], formValues[i], i); }
+								})();
+							};
+							formWidget.submit();
+							return d;
+						},
+						tearDown: function(){
+							submittedValues = defaultSubmitHandler;
+						}
+					};
+				};
+
+				doh.register("CheckBox values", [
+					function getValues(){
+						doh.is( json.stringify(originalGet), json.stringify(registry.byId("myForm").get('value')) );
+					},
+					{
+						timeout:3000,
+						name: "setValues",
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							setTimeout(d.getTestErrback(function(){
+								submitForm("original submit", originalSubmit);
+								setTimeout(d.getTestErrback(function(){
+									registry.byId("myForm").set('value', change);
+									setTimeout(d.getTestCallback(function(){
+										doh.is(json.stringify(changedGet), json.stringify(registry.byId("myForm").get('value')) );
+									}), 1000);
+								}), 500);
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						timeout: 3000,
+						name: "resetValues",
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							setTimeout(d.getTestErrback(function(){
+								submitForm("changed submit", changedSubmit);
+								setTimeout(d.getTestErrback(function(){
+									registry.byId("myForm").reset();
+									setTimeout(d.getTestCallback(function(){
+										doh.is( json.stringify(originalGet), json.stringify(registry.byId("myForm").get('value')), "reset to original values" );
+									}), 1000);
+								}), 500);
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "reset blank value",
+						runTest: function(){
+							doh.f(registry.byId('cb4').params.value, "blank parameter");
+							doh.is("on", registry.byId('cb4').value, "value initially on");
+							registry.byId('cb4').reset();
+							doh.is("on", registry.byId('cb4').value, "on after reset");
+						}
+					}
+				]);
+
+				doh.register("CheckBox onChange", [
+					function fireOnChange(){
+						var d = new doh.Deferred();
+						var cb = registry.byId('cb2');
+						var changed;
+						cb.on("change", function(){ changed = true; });
+						cb.set('checked', !cb.get('checked'));
+						setTimeout(d.getTestCallback(function(){
+							doh.t(changed, "got onchange");
+						}), 50);
+						return d;
+					},
+
+					function skipOnChange(){
+						var d = new doh.Deferred();
+						var cb = registry.byId('cb2');
+						var changed;
+						cb.on("change", function(){ changed = true; });
+						cb.set('checked', !cb.get('checked'), false);
+						setTimeout(d.getTestCallback(function(){
+							doh.f(changed, "no onchange");
+						}), 50);
+						return d;
+					}
+				]);
+
+				doh.register("CheckBox watch", [
+					function w(){
+						var cb = registry.byId('cb2');
+						cb.set("checked", true);
+
+						var oldWatch, newWatch;
+						cb.watch("checked", function(name, o, n){
+							oldWatch = o;
+							newWatch = n;
+						});
+
+						cb.set("checked", false);
+						doh.t(oldWatch, "old value was checked");
+						doh.f(newWatch, "new value is unchecked");
+
+						cb.set("checked", true);
+						doh.f(oldWatch, "old value was unchecked");
+						doh.t(newWatch, "new value is checked");
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+	<body class="claro" role="main">
+
+		<h1 class="testTitle">Dijit CheckBox Test</h1>
+		<p>
+			Here are some checkboxes.  Try clicking, and hovering, tabbing, and using the space bar to select:
+		</p>
+		<!--    to test form submission, you'll need to create an action handler similar to
+			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
+		<form id="myForm" data-dojo-type="dijit/form/Form" data-dojo-props='action:"../formAction.html", method:"", target:"formSubmitIframe"'>
+			<input id="cb1" data-dojo-id="cb1" data-dojo-type="dijit/form/CheckBox" name="cb1" value="foo"/>
+			<label for="cb1">cb1: normal checkbox, with value=foo</label>
+			<br>
+			<input id="cb2" data-dojo-type="dijit/form/CheckBox" name="cb2" checked/>
+			<label for="cb2">cb2: normal checkbox, with default value, initially turned on.</label>
+			<br>
+			<input id="cb3" data-dojo-type="dijit/form/CheckBox" name="cb3" disabled/>
+			<label for="cb3">cb3: disabled checkbox</label>
+			<br>
+			<input id="cb4" data-dojo-type="dijit/form/CheckBox" name="cb4" readOnly checked value=""/><!-- blank value => "on" -->
+			<label for="cb4">cb4: readOnly checkbox, turned on</label>
+			<br>
+			<input id="cb5" data-dojo-type="dijit/form/CheckBox" name="cb5" value=""/>
+			<label for="cb5">cb5: normal checkbox, with specified value=""</label>
+			<br>
+			<input id="cb6"/>
+			<label for="cb6">cb6: instantiated from script</label>
+			<br>
+			<input id="cb7" data-dojo-type="dijit/form/CheckBox" name="cb7"/>
+			<label for="cb7">cb7: normal checkbox.</label>
+			<br>
+		</form>
+		<iframe name="formSubmitIframe" src="about:blank" onload="if(this.values)submittedValues(this.values)" style="display:none;"></iframe>
+	</body>
+</html>
diff --git a/dijit/tests/form/CheckBoxMixin.html b/dijit/tests/form/CheckBoxMixin.html
index d1fa521..e9bead6 100644
--- a/dijit/tests/form/CheckBoxMixin.html
+++ b/dijit/tests/form/CheckBoxMixin.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
@@ -59,9 +59,11 @@
 
 	<script type="text/javascript">
 		dojo.require("doh.runner");
+		dojo.require("dojo.query");
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.form.CheckBox");
 		dojo.require("dojox.mobile.CheckBox");
+		var on = dojo.require("dojo.on");
 
 		dojo.ready(function(){
 
@@ -120,7 +122,7 @@
 							d.callback(true);
 						}
 						dijit_events.set('onChange', onChange);
-						dijit_events._onClick({ preventDefault: nop });
+						dijit_events.focusNode.click();
 
 						return d;
 					}
@@ -139,7 +141,7 @@
 							d.callback(true);
 						}
 						mobile_events.set("onChange", onChange);
-						setTimeout(function(){ mobile_events.focusNode.click({ preventDefault: nop }); }, 0);
+						mobile_events.focusNode.click();
 
 						return d;
 					}
@@ -151,7 +153,7 @@
 					name: "dijit",
 					timeout: 2000,
 					runTest: function(){
-						new dijit.form.CheckBox({id:"dijit_programmatic", checked:true}).placeAt("dijit_programmatic_container", "first");
+						new dijit.form.CheckBox({id:"dijit_programmatic", checked:true,"aria-label":"check3dijit"}).placeAt("dijit_programmatic_container", "first");
 						var dijit_programmatic = dijit.byId('dijit_programmatic');
 						var pos = dojo.position(dijit_programmatic.domNode, true);
 						doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'dijit position');
@@ -163,7 +165,7 @@
 					name: "mobile",
 					timeout: 2000,
 					runTest: function(){
-						new dojox.mobile.CheckBox({id:"mobile_programmatic", checked:true}).placeAt("mobile_programmatic_container", "first");
+						new dojox.mobile.CheckBox({id:"mobile_programmatic", checked:true,"aria-label":"check3mobile"}).placeAt("mobile_programmatic_container", "first");
 						var mobile_programmatic = dijit.byId('mobile_programmatic');
 						if(dojo.isIE < 8){ // older IE ignores setting checked after creation but before appending to the DOM
 							dojo.attr(mobile_programmatic.focusNode, "checked", mobile_programmatic.checked);
@@ -176,28 +178,47 @@
 	 			}
 			]);
 
-			var widgets = dijit.findWidgets(dojo.byId('onClickTests'));
+			var form = dojo.byId('onClickTests');
+			form.reset(); // so reload works
+
+			dojo.query("INPUT[type=checkbox]", form).forEach(function(inputNode){
+				// click all the checkboxes, but not too fast
+				doh.register("click " + inputNode.id,
+				{
+					timeout: 2000,
+					name: inputNode.id,
+					runTest: function(){
+						var d = new doh.Deferred();
+						on.once(form, "click", function(){
+							setTimeout(function(){ d.callback(true); }, 1);
+						});
+						setTimeout(function(){ inputNode.click(); }, 1);
+						return d;
+					}
+				});
+			});
+
+			var widgets = dijit.findWidgets(form);
 			dojo.forEach(widgets, function(widget){
-				widget.focusNode.click();
-				var id = widget.id;
-				var widgetVal = widget.checked;
-				var testId = "t" + id.substr(1);
-				dojo.byId(testId).click();
-				var expectedVal = !!dojo.byId(testId).checked;
-				var widgetNodeVal = !!dojo.byId(id).checked;
-				doh.register("onclick " + id,
+				doh.register("onclick " + widget.id,
 					function(){
+						var	id = widget.id,
+							testId = "t" + id.substr(1),
+							native = dojo.byId(testId);
+						var widgetVal = widget.checked;
+						var expectedVal = !!native.checked;
+						var widgetNodeVal = !!dojo.byId(id).checked;
 						doh.is(expectedVal, widgetVal, 'widget value');
 						doh.is(expectedVal, widgetNodeVal, 'hidden node');
 					}
-				)
+				);
 			});
 
 			doh.run();
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1 class="testTitle">_CheckBoxMixin (dijit and mobile) non-robot tests</h1>
 
 	<table id="table">
@@ -208,14 +229,14 @@
 		</tr>
 		<tr>
 			<td class="layout">attributes</td>
-			<td class="layout"><input id="dijit_attributes" data-dojo-type="dijit.form.CheckBox" data-dojo-props='checked: true, "class":"mblRedButton", value:"something"'/></td>
-			<td class="layout"><input type="checkbox" value="something" class="mblRedButton" checked id="mobile_attributes" dojoType="dojox.mobile.CheckBox"/></td>
+			<td class="layout"><input id="dijit_attributes"  aria-label="check1dijit" data-dojo-type="dijit/form/CheckBox" data-dojo-props='checked: true, "class":"mblRedButton", value:"something"'/></td>
+			<td class="layout"><input type="checkbox" aria-label="check1mobile" value="something" class="mblRedButton" checked id="mobile_attributes" dojoType="dojox/mobile/CheckBox"/></td>
 		</tr>
 		<tr>
 		<tr>
 			<td class="layout">Events</td>
-			<td class="layout"><input id="dijit_events" data-dojo-type="dijit.form.CheckBox" data-dojo-props='onClick:function(){ return true; }' /></td>
-			<td class="layout"><input type="checkbox" id="mobile_events" data-dojo-type="dojox.mobile.CheckBox" data-dojo-props='onClick:function(){ return true; }' /></td>
+			<td class="layout"><input id="dijit_events" aria-label="check2dijit" data-dojo-type="dijit/form/CheckBox" data-dojo-props='onClick:function(){ return true; }' /></td>
+			<td class="layout"><input type="checkbox" aria-label="check2mobile" id="mobile_events" data-dojo-type="dojox/mobile/CheckBox" data-dojo-props='onClick:function(){ return true; }' /></td>
 		</tr>
 		<tr>
 			<td class="layout">Programmatic</td>
@@ -223,73 +244,79 @@
 			<td class="layout" id="mobile_programmatic_container"></td>
 		</tr>
 	</table>
-	<div id="onClickTests" style="font-family:monospace;">
-		before click: checked=true,  onclick handler: return false, after click:
-			<input id="t1" type="checkbox" checked onclick="return false">
-			<input dojoType="dijit.form.CheckBox" id="w1" type="checkbox" checked onclick="return false"><br>
-		before click: checked=true,  onclick handler: return true,   after click:
-			<input id="t2" type="checkbox" checked onclick="return true">
-			<input dojoType="dijit.form.CheckBox" id="w2" type="checkbox" checked onclick="return true"><br>
-		before click: checked=true,  onclick handler: return false, after click:
-			<input id="t3" type="checkbox" checked onclick="return false">
-			<input dojoType="dijit.form.CheckBox" id="w3" type="checkbox" checked onclick="return false"><br>
-		before click: checked=true,  onclick handler: return true,   after click:
-			<input id="t4" type="checkbox" checked onclick="return true">
-			<input dojoType="dijit.form.CheckBox" id="w4" type="checkbox" checked onclick="return true"><br>
-		before click: checked=false, onclick handler: return false, after click:
-			<input id="t5" type="checkbox" onclick="return false">
-			<input dojoType="dijit.form.CheckBox" id="w5" type="checkbox" onclick="return false"><br>
-		before click: checked=false, onclick handler: return true,   after click:
-			<input id="t6" type="checkbox" onclick="return true">
-			<input dojoType="dijit.form.CheckBox" id="w6" type="checkbox" onclick="return true"><br>
+	<form method="get" id="onClickTests" style="font-family:monospace;font-size:16px;">
+		before click: checked=true, onclick handler: return false, after click:
+			<input aria-label="t1" id="t1" type="checkbox" checked onclick="return false;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w1" id="w1" type="checkbox" checked onclick="return false;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m1" id="m1" type="checkbox" checked onclick="return false;"><br>
+		before click: checked=true, onclick handler: return true,  after click:
+			<input aria-label="t2" id="t2" type="checkbox" checked onclick="return true;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w2" id="w2" type="checkbox" checked onclick="return true;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m2" id="m2" type="checkbox" checked onclick="return true;"><br>
 		before click: checked=false, onclick handler: return false, after click:
-			<input id="t7" type="checkbox" onclick="return false">
-			<input dojoType="dijit.form.CheckBox" id="w7" type="checkbox" onclick="return false"><br>
-		before click: checked=false, onclick handler: return true,   after click:
-			<input id="t8" type="checkbox" onclick="return true">
-			<input dojoType="dijit.form.CheckBox" id="w8" type="checkbox" onclick="return true"><br>
-		before click: checked=true,  onclick handler: no return, after click:
-			<input id="t11" type="checkbox" checked onclick="return">
-			<input dojoType="dijit.form.CheckBox" id="w11" type="checkbox" checked onclick="return"><br>
+			<input aria-label="t5" id="t5" type="checkbox" onclick="return false;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w5" id="w5" type="checkbox" onclick="return false;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m5" id="m5" type="checkbox" onclick="return false;"><br>
+		before click: checked=false, onclick handler: return true,  after click:
+			<input aria-label="t6" id="t6" type="checkbox" onclick="return true;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w6" id="w6" type="checkbox" onclick="return true;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m6" id="m6" type="checkbox" onclick="return true;"><br>
+		before click: checked=true, onclick handler: no return, after click:
+			<input aria-label="t11" id="t11" type="checkbox" checked onclick="return;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w11" id="w11" type="checkbox" checked onclick="return;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m11" id="m11" type="checkbox" checked onclick="return;"><br>
 		before click: checked=false, onclick handler: no return, after click:
-			<input id="t15" type="checkbox" onclick="return">
-			<input dojoType="dijit.form.CheckBox" id="w15" type="checkbox" onclick="return"><br>
-		before click: checked=true,  onclick handler: checked=false and return false, after click:
-			<input id="t101" type="checkbox" checked onclick="this.checked=false;return false">
-			<input dojoType="dijit.form.CheckBox" id="w101" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',false);return false"><br>
-		before click: checked=true,  onclick handler: checked=false and return true,   after click:
-			<input id="t102" type="checkbox" checked onclick="this.checked=false;return true">
-			<input dojoType="dijit.form.CheckBox" id="w102" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',false);return true"><br>
-		before click: checked=true,  onclick handler: checked=true   and return false, after click:
-			<input id="t103" type="checkbox" checked onclick="this.checked=true;return false">
-			<input dojoType="dijit.form.CheckBox" id="w103" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',true);return false"><br>
-		before click: checked=true,  onclick handler: checked=true   and return true,   after click:
-			<input id="t104" type="checkbox" checked onclick="this.checked=true;return true">
-			<input dojoType="dijit.form.CheckBox" id="w104" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',true);return true"><br>
+			<input aria-label="t15" id="t15" type="checkbox" onclick="return;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w15" id="w15" type="checkbox" onclick="return;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m15" id="m15" type="checkbox" onclick="return;"><br>
+		before click: checked=true, onclick handler: checked=false and return false, after click:
+			<input id="t101" aria-label="t101" type="checkbox" checked onclick="this.checked=false;return false;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w101" id="w101" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',false);return false;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m101" id="m101" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',false);return false;"><br>
+		before click: checked=true, onclick handler: checked=false and return true,  after click:
+			<input aria-label="t102" id="t102" type="checkbox" checked onclick="this.checked=false;return true;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w102" id="w102" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',false);return true;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m102" id="m102" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',false);return true;"><br>
+		before click: checked=true, onclick handler: checked=true  and return false, after click:
+			<input aria-label="t103" id="t103" type="checkbox" checked onclick="this.checked=true;return false;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w103" id="w103" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',true);return false;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m103" id="m103" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',true);return false;"><br>
+		before click: checked=true, onclick handler: checked=true  and return true, after click:
+			<input aria-label="t104" id="t104" type="checkbox" checked onclick="this.checked=true;return true;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w104" id="w104" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',true);return true;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m104" id="m104" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',true);return true;"><br>
 		before click: checked=false, onclick handler: checked=false and return false, after click:
-			<input id="t105" type="checkbox" onclick="this.checked=false;return false">
-			<input dojoType="dijit.form.CheckBox" id="w105" type="checkbox" onclick="dijit.byId(this.id).set('checked',false);return false"><br>
-		before click: checked=false, onclick handler: checked=false and return true,   after click:
-			<input id="t106" type="checkbox" onclick="this.checked=false;return true">
-			<input dojoType="dijit.form.CheckBox" id="w106" type="checkbox" onclick="dijit.byId(this.id).set('checked',false);return true"><br>
-		before click: checked=false, onclick handler: checked=true   and return false, after click:
-			<input id="t107" type="checkbox" onclick="this.checked=true;return false">
-			<input dojoType="dijit.form.CheckBox" id="w107" type="checkbox" onclick="dijit.byId(this.id).set('checked',true);return false"><br>
-		before click: checked=false, onclick handler: checked=true   and return true,   after click:
-			<input id="t108" type="checkbox" onclick="this.checked=true;return true">
-			<input dojoType="dijit.form.CheckBox" id="w108" type="checkbox" onclick="dijit.byId(this.id).set('checked',true);return true"><br>
-		before click: checked=true,  onclick handler: checked=false and no return, after click:
-			<input id="t111" type="checkbox" checked onclick="this.checked=false;return">
-			<input dojoType="dijit.form.CheckBox" id="w111" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',false);return"><br>
-		before click: checked=true,  onclick handler: checked=true   and no return, after click:
-			<input id="t113" type="checkbox" checked onclick="this.checked=true;return">
-			<input dojoType="dijit.form.CheckBox" id="w113" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',true);return"><br>
+			<input aria-label="t105" id="t105" type="checkbox" onclick="this.checked=false;return false;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w105" id="w105" type="checkbox" onclick="dijit.byId(this.id).set('checked',false);return false;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m105" id="m105" type="checkbox" onclick="dijit.byId(this.id).set('checked',false);return false;"><br>
+		before click: checked=false, onclick handler: checked=false and return true,  after click:
+			<input aria-label="t106" id="t106" type="checkbox" onclick="this.checked=false;return true;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w106" id="w106" type="checkbox" onclick="dijit.byId(this.id).set('checked',false);return true;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m106" id="m106" type="checkbox" onclick="dijit.byId(this.id).set('checked',false);return true;"><br>
+		before click: checked=false, onclick handler: checked=true  and return false, after click:
+			<input aria-label="t107" id="t107" type="checkbox" onclick="this.checked=true;return false;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w107" id="w107" type="checkbox" onclick="dijit.byId(this.id).set('checked',true);return false;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m107" id="m107" type="checkbox" onclick="dijit.byId(this.id).set('checked',true);return false;"><br>
+		before click: checked=false, onclick handler: checked=true  and return true,  after click:
+			<input aria-label="t108" id="t108" type="checkbox" onclick="this.checked=true;return true;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w108" id="w108" type="checkbox" onclick="dijit.byId(this.id).set('checked',true);return true;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m108" id="m108" type="checkbox" onclick="dijit.byId(this.id).set('checked',true);return true;"><br>
+		before click: checked=true, onclick handler: checked=false and no return, after click:
+			<input aria-label="t111" id="t111" type="checkbox" checked onclick="this.checked=false;return;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w111" id="w111" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',false);return;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m111" id="m111" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',false);return;"><br>
+		before click: checked=true, onclick handler: checked=true  and no return, after click:
+			<input aria-label="t113" id="t113" type="checkbox" checked onclick="this.checked=true;return;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w113" id="w113" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',true);return;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m113" id="m113" type="checkbox" checked onclick="dijit.byId(this.id).set('checked',true);return;"><br>
 		before click: checked=false, onclick handler: checked=false and no return, after click:
-			<input id="t115" type="checkbox" onclick="this.checked=false;return">
-			<input dojoType="dijit.form.CheckBox" id="w115" type="checkbox" onclick="dijit.byId(this.id).set('checked',false);return"><br>
-		before click: checked=false, onclick handler: checked=true   and no return, after click:
-			<input id="t117" type="checkbox" onclick="this.checked=true;return">
-			<input dojoType="dijit.form.CheckBox" id="w117" type="checkbox" onclick="dijit.byId(this.id).set('checked',true);return"><br>
-	</div>
+			<input aria-label="t115" id="t115" type="checkbox" onclick="this.checked=false;return;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w115" id="w115" type="checkbox" onclick="dijit.byId(this.id).set('checked',false);return;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m115" id="m115" type="checkbox" onclick="dijit.byId(this.id).set('checked',false);return;"><br>
+		before click: checked=false, onclick handler: checked=true  and no return, after click:
+			<input aria-label="t117" id="t117" type="checkbox" onclick="this.checked=true;return;">
+			<input data-dojo-type="dijit/form/CheckBox" aria-label="w117" id="w117" type="checkbox" onclick="dijit.byId(this.id).set('checked',true);return;">
+			<input data-dojo-type="dojox/mobile/CheckBox" aria-label="m117" id="m117" type="checkbox" onclick="dijit.byId(this.id).set('checked',true);return;"><br>
+	</form>
 </body>
 </html>
diff --git a/dijit/tests/form/DateTextBox.html b/dijit/tests/form/DateTextBox.html
deleted file mode 100644
index ce4868b..0000000
--- a/dijit/tests/form/DateTextBox.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>DateTextBox DOH Test</title>
-
-	<style>
-		@import "../../../dojo/resources/dojo.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-	<script type="text/javascript" src="../helpers.js"></script>
-
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-
-	<script type="text/javascript">
-		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.form.DateTextBox");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-		dojo.ready(function(){
-
-			doh.register("parse", function(){
-				dojo.parser.parse();
-			});
-
-			doh.register("tests",
-				function noYear(){
-					var widget = dijit.byId("noyear");
-					doh.t(widget.isValid(false), "isValid");
-					doh.is(2011, widget.get('value').getFullYear(), "programmatic value");
-					doh.is(2011, widget.value.getFullYear(), "JS value");
-				}
-			);
-
-			doh.run();
-
-		});
-	</script>
-
-</head>
-<body class="claro">
-	<h1 class="testTitle">dijit.form.DateTextBox automated tests (non-robot)</h1>
-	
-	<label for="noyear">Pick a day in 3Q 2011</label>
-	<input data-dojo-type="dijit.form.DateTextBox" id="noyear", data-dojo-props='
-		required:"true",
-		constraints:{datePattern:"MMMM dd",
-			min:new Date(2011,9,1),
-			max:new Date(2011,11,31)
-		},
-		parse:function(){
-			var d = this.inherited("parse", arguments);
-			if(d instanceof Date)d.setFullYear(2011);
-			return d;
-		},
-		value:new Date(2011,10,25)'
-	/>
-</body>
-</html>
diff --git a/dijit/tests/form/ExpandingTextAreaMixin.html b/dijit/tests/form/ExpandingTextAreaMixin.html
index b99a669..6d3a8ab 100644
--- a/dijit/tests/form/ExpandingTextAreaMixin.html
+++ b/dijit/tests/form/ExpandingTextAreaMixin.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
@@ -103,18 +103,18 @@
 
 						function onFocus(){
 							dijit_events.set('onFocus', nop);
-							dijit_events.textbox.value = "Focus";
+							dijit_events.set("value", "Focus");
 							dijit_events.set('onBlur', onBlur);
 							dijit.byId('mobile_events').focus();
 						}
 						function onBlur(){
 							dijit_events.set('onChange', onChange);
 							dijit_events.set('onBlur', nop);
-							dijit_events.textbox.value = "Blur";
+							dijit_events.set("value", "Blur");
 						}
 						function onChange(){
 							dijit_events.set('onChange', nop);
-							dijit_events.textbox.value = "Change";
+							dijit_events.set("value", "Change");
 							dijit_events.focus();
 							d.callback(true);
 						}
@@ -139,18 +139,18 @@
 
 						function onFocus(){
 							mobile_events.disconnect(focusHandle);
-							mobile_events.textbox.value = "Focus";
+							mobile_events.set("value", "Focus");
 							blurhandle = mobile_events.connect(mobile_events, '_onBlur', onBlur);
 							dijit.byId('dijit_events').focus();
 						}
 						function onBlur(){
 							mobile_events.set('onChange', onChange);
 							mobile_events.disconnect(blurhandle);
-							mobile_events.textbox.value = "Blur";
+							mobile_events.set("value", "Blur");
 						}
 						function onChange(){
 							mobile_events.set('onChange', nop);
-							mobile_events.textbox.value = "Change";
+							mobile_events.set("value", "Change");
 							mobile_events.focus();
 							d.callback(true);
 						}
@@ -169,7 +169,7 @@
 					name: "dijit",
 					timeout: 2000,
 					runTest: function(){
-						new dijit.form.Textarea({id:"dijit_programmatic", value:"No srcNodeRef"}).placeAt("dijit_programmatic_container", "first");
+						new dijit.form.Textarea({id:"dijit_programmatic", value:"No srcNodeRef", "aria-label":"dijit_programmatic"}).placeAt("dijit_programmatic_container", "first");
 						var dijit_programmatic = dijit.byId('dijit_programmatic');
 						dijit_programmatic.resize();
 						var focushandle = dijit_programmatic.connect(dijit_programmatic, '_onFocus',
@@ -192,7 +192,7 @@
 					name: "mobile",
 					timeout: 2000,
 					runTest: function(){
-						new dojox.mobile.ExpandingTextArea({id:"mobile_programmatic", value:"No srcNodeRef"}).placeAt("mobile_programmatic_container", "first");
+						new dojox.mobile.ExpandingTextArea({id:"mobile_programmatic", value:"No srcNodeRef","aria-label":"mobile_programmatic"}).placeAt("mobile_programmatic_container", "first");
 						var mobile_programmatic = dijit.byId('mobile_programmatic');
 						mobile_programmatic.resize();
 						var focushandle = mobile_programmatic.connect(mobile_programmatic, '_onFocus',
@@ -247,7 +247,7 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1 class="testTitle">_ExpandingTextAreaMixin (dijit and mobile) non-robot tests</h1>
 	<table id="table">
 		<tr>
@@ -257,13 +257,13 @@
 		</tr>
 		<tr>
 			<td class="layout">attributes</td>
-			<td class="layout"><input id="dijit_attributes" data-dojo-type="dijit.form.Textarea" data-dojo-props='value:"", placeHolder:"original", maxLength:"20", cols:20'/></td>
-			<td class="layout"><textarea id="mobile_attributes" data-dojo-type="dojox.mobile.ExpandingTextArea" data-dojo-props='cols:20, placeHolder:"original", maxLength:20'></textarea></td>
+			<td class="layout"><input id="dijit_attributes" aria-label="dijit_attr" data-dojo-type="dijit/form/Textarea" data-dojo-props='value:"", placeHolder:"original", maxLength:"20", cols:20'/></td>
+			<td class="layout"><textarea id="mobile_attributes" aria-label="mobilet_attr" data-dojo-type="dojox.mobile.ExpandingTextArea" data-dojo-props='cols:20, placeHolder:"original", maxLength:20'></textarea></td>
 		</tr>
 		<tr>
 			<td class="layout">Events</td>
-			<td class="layout"><input id="dijit_events" data-dojo-type="dijit.form.Textarea" data-dojo-props='value:"", onFocus:function(){ return false; }, onBlur:function(){ return false; }, onChange:function(){ return false; }'/></td>
-			<td class="layout"><textarea id="mobile_events" data-dojo-type="dojox.mobile.ExpandingTextArea" data-dojo-props='onChange:function(){ return false; }'></textarea></td>
+			<td class="layout"><input id="dijit_events" aria-label="dijit_events"data-dojo-type="dijit/form/Textarea" data-dojo-props='value:"", onFocus:function(){ return false; }, onBlur:function(){ return false; }, onChange:function(){ return false; }'/></td>
+			<td class="layout"><textarea id="mobile_events" aria-label="mobile_events" data-dojo-type="dojox.mobile.ExpandingTextArea" data-dojo-props='onChange:function(){ return false; }'></textarea></td>
 		</tr>
 		<tr>
 			<td class="layout">Programmatic</td>
@@ -272,11 +272,11 @@
 		</tr>
 		<tr>
 			<td class="layout">Size</td>
-			<td class="layout"><textarea id="dijit_size" data-dojo-type="dijit.form.Textarea" data-dojo-props=''
+			<td class="layout"><textarea id="dijit_size" aria-label="dijit_size" data-dojo-type="dijit/form/Textarea" data-dojo-props=''
 >line 1
 line 2
 line 3</textarea></td>
-			<td class="layout"><textarea id="mobile_size" data-dojo-type="dojox.mobile.ExpandingTextArea" data-dojo-props=''
+			<td class="layout"><textarea id="mobile_size" aria-label="mobile_size" data-dojo-type="dojox.mobile.ExpandingTextArea" data-dojo-props=''
 >line 1
 line 2
 line 3</textarea></td>
diff --git a/dijit/tests/form/Form.html b/dijit/tests/form/Form.html
index 6d21b10..a1abebb 100644
--- a/dijit/tests/form/Form.html
+++ b/dijit/tests/form/Form.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
@@ -36,6 +36,7 @@
 		dojo.require("dijit.form.DateTextBox");
 		dojo.require("dijit.form.Button");
 		dojo.require("dijit.form.MultiSelect");
+		dojo.require("dijit.form.Select");
 		dojo.require("dijit.form.Textarea");
 		dojo.require("dijit.form.SimpleTextarea");
 		dojo.require("dijit.Editor");
@@ -75,6 +76,7 @@
 							cb: ["2", "3"],
 							r: "2",
 							ms1: ["VA", "WA"],
+							s1: "VA",
 							h1: "hidden",
 							t1: "line 1\nline 2",
 							st1: "simple line 1\nsimple line 2",
@@ -93,6 +95,7 @@
 							cb: ["4"],
 							r: "1",
 							ms1: ["FL", "CA"],
+							s1: "FL",
 							h1: "still hidden",
 							t1: "new line 1\nnew line 2",
 							st1: "new simple line 1\nnew simple line 2",
@@ -169,6 +172,7 @@
 					doh.is(testValues.cb, formValues.cb);
 					doh.is(testValues.r, formValues.r);
 					doh.is(testValues.ms1, formValues.ms1);
+					doh.is(testValues.s1, formValues.s1);
 					doh.is(testValues.h1, formValues.h1);
 					doh.is(testValues.t1, formValues.t1);
 					doh.is(testValues.st1, formValues.st1);
@@ -327,7 +331,7 @@
 					var d = new doh.Deferred();
 
 					calls = 0;
-					formWidget.set("value", {cb: [1,4]});
+					formWidget.set("value", {cb: ["1", "4"]});
 					
 					setTimeout(d.getTestCallback(function(){
 						doh.is(1, calls, "exactly one watch(value) call");
@@ -396,7 +400,7 @@
 					var d = new doh.Deferred();
 
 					calls = 0;
-					formWidget.set("value", {r: 3});
+					formWidget.set("value", {r: "3"});
 					
 					setTimeout(d.getTestCallback(function(){
 						doh.is(1, calls, "exactly one watch(value) call");
@@ -604,10 +608,18 @@
 				formWidget.validate();
 				
 				doh.t(dojo.hasClass(dojo.byId("widget_rw"), "dijitValidationTextBoxError"), "required but empty marked as error");
-				doh.is("dtb2", dijit.focus.curNode.id, "focused on first invalid DateTextBox");
+
+				// Check that focus went to invalid field.  But on IE9+ focus change is asynchronous so use a timer.
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					doh.is("dtb2", dijit.focus.curNode.id, "focused on first invalid DateTextBox");
+				}), 0);
+				return d;
 			});
 
 			if(dojo.isFF >= 4 || dojo.isIE >= 10 || dojo.isWebKit){
+				// only works for HTML5 compliant browsers where novalidate is understood
+				// (also, hasAttribute() is not available on IE6/7)
 				doh.register("novalidate", function noValidate(){
 					// Making sure the parser picks up the flag and _WidgetBase copies it to this.domNode
 					doh.t(dijit.byId("noValidateForm").domNode.hasAttribute("novalidate"), "novalidate");
@@ -619,7 +631,7 @@
 
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1>Form Widget Unit Test</h1>
 	<p>
 		The form widget takes data in a form and serializes/deserializes it, so
@@ -629,7 +641,7 @@
 	<!--    to test form submission, you'll need to create an action handler similar to
 			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi
 		http://www.tipjar.com/cgi-bin/test -->
-	<form id="myForm" data-dojo-type="dijit.form.Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe"'>
+	<form id="myForm" data-dojo-type="dijit/form/Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe"'>
 		<script type="dojo/method" data-dojo-event="onReset">
 			return ("_onResetReturn" in this)? this._onResetReturn : confirm('Press OK to reset widget values');
 		</script>
@@ -673,32 +685,32 @@
 
 				<tr>
 					<td>DateTextBox inside contentpane</td>
-					<td>foo.bar.baz.quux</td>
+					<td><label for="dtb1">foo.bar.baz.quux</label></td>
 					<td>
-						<div data-dojo-type="dijit.layout.ContentPane">
-						<input data-dojo-type="dijit.form.DateTextBox" data-dojo-props='id:"dtb1", name:"foo.bar.baz.quux", value:"2007-12-30" '/>
+						<div data-dojo-type="dijit/layout/ContentPane">
+						<input data-dojo-type="dijit/form/DateTextBox" data-dojo-props='id:"dtb1", name:"foo.bar.baz.quux", value:"2007-12-30" '/>
 						</div>
 					</td>
 				</tr>
 				<tr>
 					<td>DateTextBox 2</td>
-					<td>available.from</td>
+					<td><label for="dtb2">available.from</label></td>
 					<td>
-						<input data-dojo-type="dijit.form.DateTextBox" data-dojo-props='id:"dtb2", name:"available.from", value:"2005-01-02" '/>
+						<input data-dojo-type="dijit/form/DateTextBox" data-dojo-props='id:"dtb2", name:"available.from", value:"2005-01-02" '/>
 					</td>
 				</tr>
 				<tr>
 					<td>DateTextBox 3</td>
-					<td>available.to</td>
+					<td><label for="dtb3">available.to</label></td>
 					<td>
-						<input data-dojo-type="dijit.form.DateTextBox" data-dojo-props='id:"dtb3", name:"available.to", value:"2006-01-02" '/>
+						<input data-dojo-type="dijit/form/DateTextBox" data-dojo-props='id:"dtb3", name:"available.to", value:"2006-01-02" '/>
 					</td>
 				</tr>
 				<tr>
 					<td>ComboBox</td>
-					<td>plop.combo</td>
+					<td><label for="plopcombo">plop.combo</label></td>
 					<td>
-						<select data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"plop.combo" '>
+						<select data-dojo-type="dijit/form/ComboBox" id="plopcombo" data-dojo-props='name:"plop.combo" '>
 							<option value="one">one</option>
 							<option value="two">two</option>
 							<option value="three">three</option>
@@ -735,10 +747,10 @@
 					<td>CheckBox widget</td>
 					<td>cb</td>
 					<td>
-						<input data-dojo-type="dijit.form.CheckBox" data-dojo-props='id: "cb_1", name:"cb", value:"1" '/> 1
-						<input data-dojo-type="dijit.form.CheckBox" data-dojo-props='id: "cb_2", name:"cb", value:"2", checked:true '/> 2
-						<input data-dojo-type="dijit.form.CheckBox" data-dojo-props='id: "cb_3", name:"cb", value:"3", checked:true '/> 3
-						<input data-dojo-type="dijit.form.CheckBox" data-dojo-props='id: "cb_4", name:"cb", value:"4" '/> 4
+						<input data-dojo-type="dijit/form/CheckBox" id="cb_1" name="cb" value="1"/> <label for="cb_1">1</label>
+						<input data-dojo-type="dijit/form/CheckBox" id="cb_2" name="cb" value="2" checked/> <label for="cb_2">2</label>
+						<input data-dojo-type="dijit/form/CheckBox" id="cb_3" name="cb" value="3" checked/> <label for="cb_3">3</label>
+						<input data-dojo-type="dijit/form/CheckBox" id="cb_4" name="cb" value="4"/> <label for="cb_4">4</label>
 					</td>
 				</tr>
 
@@ -758,10 +770,10 @@
 				<tr>
 				<td>Radio widget</td><td>r</td>
 				<td id="radio-cells">
-				<input data-dojo-type="dijit.form.RadioButton" data-dojo-props='id:"r_1", name:"r", value:"1" '/> 1
-				<input data-dojo-type="dijit.form.RadioButton" data-dojo-props='id:"r_2", name:"r", value:"2", checked:true '/> 2
-				<input data-dojo-type="dijit.form.RadioButton" data-dojo-props='id:"r_3", name:"r", value:"3"'/> 3
-				<input data-dojo-type="dijit.form.RadioButton" data-dojo-props='id:"r_4", name:"r", value:"4" '/> 4
+					<input data-dojo-type="dijit/form/RadioButton" id="r_1" name="r" value="1"/> <label for="r_1">1</label>
+					<input data-dojo-type="dijit/form/RadioButton" id="r_2" name="r" value="2" checked/> <label for="r_2">2</label>
+					<input data-dojo-type="dijit/form/RadioButton" id="r_3" name="r" value="3"/> <label for="r_3">3</label>
+					<input data-dojo-type="dijit/form/RadioButton" id="r_4" name="r" value="4"/> <label for="r_4">4</label>
 				<input type="button" onclick="dojo.query('INPUT[type=radio]','radio-cells').forEach(function(n){dijit.getEnclosingWidget(n).set('checked',false);});return true;" value="Unset all radio buttons"/>
 				</td>
 				</tr>
@@ -769,8 +781,8 @@
 				<tr>
 					<td>Multi-select</td><td>ms1</td>
 					<td>
-						<select id="ms1" multiple data-dojo-type="dijit.form.MultiSelect"
-							data-dojo-props='name:"ms1",
+						<select id="ms1" multiple data-dojo-type="dijit/form/MultiSelect"
+							data-dojo-props='name:"ms1", "aria-label":"ms1",
 							style:{height:"100px", width:"175px", border:"5px solid #ededed"}'>
 
 							<option value="TN">Tennessee</option>
@@ -784,10 +796,25 @@
 				</tr>
 
 				<tr>
+					<td>Select</td><td>s1</td>
+					<td>
+						<select id="s1" data-dojo-type="dijit/form/Select"
+							data-dojo-props='name:"s1", style:{width:"175px"}, "aria-label":"s1"'>
+							<option value="TN">Tennessee</option>
+							<option value="VA" selected="selected">Virginia</option>
+							<option value="WA">Washington</option>
+							<option value="FL">Florida</option>
+							<option value="CA">California</option>
+
+						</select>
+					</td>
+				</tr>
+
+				<tr>
 					<td>Hidden input</td>
 					<td>h1</td>
 					<td>
-						<input id="h1" data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"h1", type:"hidden", value:"hidden"'/>
+						<input id="h1" data-dojo-type="dijit/form/TextBox" data-dojo-props='name:"h1", type:"hidden", value:"hidden", "aria-label":"h1" '/>
 					</td>
 				</tr>
 
@@ -795,8 +822,7 @@
 					<td>Auto-sizing textarea</td>
 					<td>t1</td>
 					<td>
-						<textarea id="t1" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"t1"
-	'>line 1
+						<textarea id="t1" data-dojo-type="dijit/form/Textarea" data-dojo-props='name:"t1", "aria-label":"t1" '>line 1
 line 2</textarea>
 					</td>
 				</tr>
@@ -805,7 +831,7 @@ line 2</textarea>
 					<td>Fixed size textarea</td>
 					<td>st1</td>
 					<td>
-						<textarea id="st1" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"st1", rows:"5", cols:"50"'>
+						<textarea id="st1" data-dojo-type="dijit/form/SimpleTextarea" data-dojo-props='name:"st1", rows:"5", cols:"50", "aria-label":"st1" '>
 simple line 1
 simple line 2</textarea>
 					</td>
@@ -815,7 +841,7 @@ simple line 2</textarea>
 					<td>Editor widget</td>
 					<td>richtext</td>
 					<td>
-						<textarea id="editor" name="richtext" data-dojo-type="dijit.Editor" data-dojo-props='plugins:["bold", "italic"]'><h1>original</h1><p>This is the default content</p></textarea>
+						<textarea id="editor" name="richtext" data-dojo-type="dijit/Editor" data-dojo-props='"aria-label":"editor", plugins:["bold", "italic"]'><h1>original</h1><p>This is the default content</p></textarea>
 					</td>
 				</tr>
 
@@ -823,73 +849,73 @@ simple line 2</textarea>
 					<td>File upload</td>
 					<td>filename</td>
 					<td>
-						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"filename", type:"file"'/>
+						<input data-dojo-type="dijit/form/TextBox" data-dojo-props='name:"filename", type:"file", "aria-label":"filename" '/>
 					</td>
 				</tr>
 				<tr>
 					<td>Required Widget</td>
 					<td>requiredWidget</td>
 					<td>
-						<input data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='id: "rw", name:"requiredWidget", required:true, value:""'/>
+						<input data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='id: "rw", name:"requiredWidget", required:true, value:"", "aria-label":"rw" '/>
 					</td>
 				</tr>
 				<tr>
 					<td>Disabled Widget</td>
 					<td>disabledWidget</td>
 					<td>
-						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"disabledWidget", disabled:true, value:"Should not be returned"'/>
+						<input data-dojo-type="dijit/form/TextBox" data-dojo-props='name:"disabledWidget", disabled:true, value:"Should not be returned", "aria-label":"disabled" '/>
 					</td>
 				</tr>
 				<tr>
 					<td>Disabled Required Widget</td>
 					<td>disabledRequiredWidget</td>
 					<td>
-						<input data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='id: "drw", name:"disabledRequiredWidget", disabled:true, required:true, value:""'/>
+						<input data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='id: "drw", name:"disabledRequiredWidget", disabled:true, required:true, value:"", "aria-label":"disabledRequired" '/>
 					</td>
 				</tr>
 				<tr>
 					<td>Read-only Widget</td>
 					<td>readOnlyWidget</td>
 					<td>
-						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"readOnlyWidget", readOnly:true, value:"Should be returned"'/>
+						<input data-dojo-type="dijit/form/TextBox" data-dojo-props='name:"readOnlyWidget", readOnly:true, value:"Should be returned", "aria-label":"readonly" '/>
 					</td>
 				</tr>
 				<tr>
 					<td>Duplicate named TextBox 1</td>
 					<td>duplicate</td>
 					<td>
-						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"duplicate", value:"first"'/>
+						<input data-dojo-type="dijit/form/TextBox" data-dojo-props='name:"duplicate", value:"first", "aria-label":"duplicate" '/>
 					</td>
 				</tr>
 				<tr>
 					<td>Duplicate named TextBox 2</td>
 					<td>duplicate</td>
 					<td>
-						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"duplicate", value:"second"'/>
+						<input data-dojo-type="dijit/form/TextBox" data-dojo-props='name:"duplicate", value:"second", "aria-label":"duplicate2" '/>
 					</td>
 				</tr>
 				<tr>
 					<td>Duplicate named TextBox 3</td>
 					<td>duplicate</td>
 					<td>
-						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"duplicate", value:"third"'/>
+						<input data-dojo-type="dijit/form/TextBox" data-dojo-props='name:"duplicate", value:"third", "aria-label":"duplicate3" '/>
 					</td>
 				</tr>
 			</tbody>
 		</table>
 
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ getValues(); }'>Get Values from form!</button>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ setValues(); }'>Set Values to form!</button>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ validate(); }'>Validate form!</button>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", value:"Submit"'>Submit</button>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset"'>HTML Reset</button>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ dijit.byId("myForm").reset() }'>reset()</button>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ getValues(); }'>Get Values from form!</button>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ setValues(); }'>Set Values to form!</button>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ validate(); }'>Validate form!</button>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='type:"submit", value:"Submit"'>Submit</button>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='type:"reset"'>HTML Reset</button>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", onClick:function(){ dijit.byId("myForm").reset() }'>reset()</button>
 	</form>
-<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button",
+<button data-dojo-type="dijit/form/Button" data-dojo-props='type:"button",
 onClick:function(){ dijit.byId("myForm").submit() }'>Submit programmatically</button>
 
 <iframe name="formSubmitIframe" src="about:blank" onload="if(this.values)submittedValues(this.values)" style="display:none;"></iframe>
 
-	<form id="noValidateForm" data-dojo-type="dijit.form.Form" novalidate></form>
+	<form id="noValidateForm" data-dojo-type="dijit/form/Form" novalidate></form>
 </body>
 </html>
diff --git a/dijit/tests/form/RadioButtonMixin.html b/dijit/tests/form/RadioButtonMixin.html
index 9689cd7..c1c9ccb 100644
--- a/dijit/tests/form/RadioButtonMixin.html
+++ b/dijit/tests/form/RadioButtonMixin.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
@@ -122,7 +122,7 @@
 					name: "dijit",
 					timeout: 2000,
 					runTest: function(){
-						new dijit.form.RadioButton({name:"dijit_programmatic", id:"dijit_programmatic", checked:true}).placeAt("dijit_programmatic_container", "first");
+						new dijit.form.RadioButton({name:"dijit_programmatic", id:"dijit_programmatic", checked:true, "aria-label":"dijit_programmatic"}).placeAt("dijit_programmatic_container", "first");
 						var dijit_programmatic = dijit.byId('dijit_programmatic');
 						var pos = dojo.position(dijit_programmatic.domNode, true);
 						doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'dijit position');
@@ -134,7 +134,7 @@
 					name: "mobile",
 					timeout: 2000,
 					runTest: function(){
-						new dojox.mobile.RadioButton({name:"mobile_programmatic", id:"mobile_programmatic", checked:true}).placeAt("mobile_programmatic_container", "first");
+						new dojox.mobile.RadioButton({name:"mobile_programmatic", id:"mobile_programmatic", checked:true, "aria-label":"mobile_programmatic"}).placeAt("mobile_programmatic_container", "first");
 						var mobile_programmatic = dijit.byId('mobile_programmatic');
 						if(dojo.isIE < 8){ // older IE ignores setting checked after creation but before appending to the DOM
 							dojo.attr(mobile_programmatic.focusNode, "checked", mobile_programmatic.checked);
@@ -151,7 +151,7 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1 class="testTitle">_RadioButtonMixin (dijit and mobile) non-robot tests</h1>
 
 	<table id="table">
@@ -162,25 +162,25 @@
 		</tr>
 		<tr>
 			<td class="layout">attributes</td>
-			<td class="layout"><input name="dijit_attributes" id="dijit_attributes" data-dojo-type="dijit.form.RadioButton" data-dojo-props='checked: true, "class":"mblRedButton", value:"something", name:"dijit_attributes"'/></td>
-			<td class="layout"><input name="dijit_attributes" id="dijit_attributes2" type="radio" value="other" dojoType="dijit.form.RadioButton">
-			<td class="layout"><input name="mobile_attributes" type="radio" value="something" class="mblRedButton" checked id="mobile_attributes" dojoType="dojox.mobile.RadioButton"/></td>
-			<td class="layout"><input name="mobile_attributes" id="mobile_attributes2" type="radio" value="other" dojoType="dojox.mobile.RadioButton">
+			<td class="layout"><input name="dijit_attributes" id="dijit_attributes" data-dojo-type="dijit/form/RadioButton" data-dojo-props='checked: true, "class":"mblRedButton", value:"something", name:"dijit_attributes", "aria-label":"dijit_attributes" '/></td>
+			<td class="layout"><input name="dijit_attributes" aria-label="dijit_attributes2" id="dijit_attributes2" type="radio" value="other" dojoType="dijit.form.RadioButton">
+			<td class="layout"><input name="mobile_attributes" aria-label="mobile_attributes" type="radio" value="something" class="mblRedButton" checked id="mobile_attributes" dojoType="dojox.mobile.RadioButton"/></td>
+			<td class="layout"><input name="mobile_attributes" aria-label="mobile_attributes2" id="mobile_attributes2" type="radio" value="other" dojoType="dojox.mobile.RadioButton">
 		</tr>
 		<tr>
 		<tr>
 			<td class="layout">Events</td>
-			<td class="layout"><input name="dijit_events" id="dijit_events" data-dojo-type="dijit.form.RadioButton" data-dojo-props='onClick:function(){ return true; }, name:"dijit_events"' /></td>
-			<td class="layout"><input name="dijit_events" type="radio" value="other" dojoType="dijit.form.RadioButton">
-			<td class="layout"><input name="mobile_events" type="radio" id="mobile_events" data-dojo-type="dojox.mobile.RadioButton" data-dojo-props='onClick:function(){ return true; }' /></td>
-			<td class="layout"><input name="mobile_events" type="radio" value="other" dojoType="dojox.mobile.RadioButton">
+			<td class="layout"><input name="dijit_events" id="dijit_events" data-dojo-type="dijit/form/RadioButton" data-dojo-props='onClick:function(){ return true; }, name:"dijit_events", "aria-label":"dijit_events"' /></td>
+			<td class="layout"><input name="dijit_events" aria-label="dijit_events2" type="radio" value="other" dojoType="dijit.form.RadioButton">
+			<td class="layout"><input name="mobile_events" aria-label="mobile_events" type="radio" id="mobile_events" data-dojo-type="dojox.mobile.RadioButton" data-dojo-props='onClick:function(){ return true; }' /></td>
+			<td class="layout"><input name="mobile_events" aria-label="mobile_events2" type="radio" value="other" dojoType="dojox.mobile.RadioButton">
 		</tr>
 		<tr>
 			<td class="layout">Programmatic</td>
 			<td class="layout" id="dijit_programmatic_container"></td>
-			<td class="layout"><input name="dijit_programmatic" type="radio" value="other" dojoType="dijit.form.RadioButton">
+			<td class="layout"><input name="dijit_programmatic" type="radio" aria-label="dijit_programmatic" value="other" dojoType="dijit.form.RadioButton">
 			<td class="layout" id="mobile_programmatic_container"></td>
-			<td class="layout"><input name="mobile_programmatic" type="radio" value="other" dojoType="dojox.mobile.RadioButton">
+			<td class="layout"><input name="mobile_programmatic" type="radio" aria-label="mobile_programmatic" value="other" dojoType="dojox.mobile.RadioButton">
 		</tr>
 	</table>
 </body>
diff --git a/dijit/tests/form/TextBoxMixin.html b/dijit/tests/form/TextBoxMixin.html
index cdf1bbf..3b2e5a4 100644
--- a/dijit/tests/form/TextBoxMixin.html
+++ b/dijit/tests/form/TextBoxMixin.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
@@ -184,7 +184,7 @@
 					name: "dijit",
 					timeout: 2000,
 					runTest: function(){
-						new dijit.form.TextBox({id:"dijit_programmatic", selectOnClick:true, value:"No srcNodeRef"}).placeAt("dijit_programmatic_container", "first");
+						new dijit.form.TextBox({id:"dijit_programmatic", selectOnClick:true, value:"No srcNodeRef", "aria-label":"dijit_programmatic"}).placeAt("dijit_programmatic_container", "first");
 						var dijit_programmatic = dijit.byId('dijit_programmatic');
 						var focushandle = dijit_programmatic.connect(dijit_programmatic, '_onFocus',
 							function(){
@@ -206,7 +206,7 @@
 					name: "mobile",
 					timeout: 2000,
 					runTest: function(){
-						new dojox.mobile.TextBox({id:"mobile_programmatic", selectOnClick:true, value:"No srcNodeRef"}).placeAt("mobile_programmatic_container", "first");
+						new dojox.mobile.TextBox({id:"mobile_programmatic", selectOnClick:true, value:"No srcNodeRef","aria-label":"mobile_programmatic"}).placeAt("mobile_programmatic_container", "first");
 						var mobile_programmatic = dijit.byId('mobile_programmatic');
 						var focushandle = mobile_programmatic.connect(mobile_programmatic, '_onFocus',
 							function(){
@@ -230,7 +230,7 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1 class="testTitle">_TextBoxMixin (dijit and mobile) non-robot tests</h1>
 
 	<table id="table">
@@ -241,18 +241,18 @@
 		</tr>
 		<tr>
 			<td class="layout">DOM attr</td>
-			<td class="layout"><input id="dijit_DOMattr" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", value:"", placeHolder:"original", maxLength:20'/></td>
-			<td class="layout"><input id="mobile_DOMattr" data-dojo-type="dojox.mobile.TextBox" data-dojo-props='type:"text", value:"", placeHolder:"original", maxLength:20'/></td>
+			<td class="layout"><input id="dijit_DOMattr" data-dojo-type="dijit/form/TextBox" data-dojo-props='"aria-label":"dijit_DOMattr",type:"text", value:"", placeHolder:"original", maxLength:20'/></td>
+			<td class="layout"><input id="mobile_DOMattr" data-dojo-type="dojox.mobile.TextBox" data-dojo-props='"aria-label":"mobile_DOMattr",type:"text", value:"", placeHolder:"original", maxLength:20'/></td>
 		</tr>
 		<tr>
 			<td class="layout">Widget attr</td>
-			<td class="layout"><input id="dijit_WidgetAttr" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", value:"", propercase:false'/></td>
-			<td class="layout"><input id="mobile_WidgetAttr" data-dojo-type="dojox.mobile.TextBox" data-dojo-props='type:"text", value:"", propercase:false'/></td>
+			<td class="layout"><input id="dijit_WidgetAttr" data-dojo-type="dijit/form/TextBox" data-dojo-props='"aria-label":"dijit_WidgetAttr", type:"text", value:"", propercase:false'/></td>
+			<td class="layout"><input id="mobile_WidgetAttr" data-dojo-type="dojox.mobile.TextBox" data-dojo-props='"aria-label":"mobile_WidgetAttr", type:"text", value:"", propercase:false'/></td>
 		</tr>
 		<tr>
 			<td class="layout">Events</td>
-			<td class="layout"><input id="dijit_events" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", value:"", onFocus:function(){ return false; }, onBlur:function(){ return false; }, onChange:function(){ return false; }'/></td>
-			<td class="layout"><input id="mobile_events" data-dojo-type="dojox.mobile.TextBox" data-dojo-props='type:"text", value:"", onChange:function(){ return false; }'/></td>
+			<td class="layout"><input id="dijit_events" data-dojo-type="dijit/form/TextBox" data-dojo-props='"aria-label":"dijit_events", type:"text", value:"", onFocus:function(){ return false; }, onBlur:function(){ return false; }, onChange:function(){ return false; }'/></td>
+			<td class="layout"><input id="mobile_events" data-dojo-type="dojox.mobile.TextBox" data-dojo-props='"aria-label":"mobile_events", type:"text", value:"", onChange:function(){ return false; }'/></td>
 		</tr>
 		<tr>
 			<td class="layout">Programmatic</td>
diff --git a/dijit/tests/form/TextBox_sizes.html b/dijit/tests/form/TextBox_sizes.html
index 329c545..0999511 100644
--- a/dijit/tests/form/TextBox_sizes.html
+++ b/dijit/tests/form/TextBox_sizes.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html dir="ltr">
+<html dir="ltr" lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>dijit.form.TextBox size tests</title>
@@ -11,36 +11,55 @@
 		@import "../../themes/tundra/Common.css";
 		@import "../../themes/tundra/form/Button.css";
 		@import "../../themes/tundra/form/Common.css";
+		@import "../../themes/tundra/form/Select.css";
 		@import "../../themes/claro/Common.css";
 		@import "../../themes/claro/form/Button.css";
 		@import "../../themes/claro/form/Button_rtl.css";
 		@import "../../themes/claro/form/Common.css";
 		@import "../../themes/claro/form/Common_rtl.css";
 		@import "../../themes/claro/form/NumberSpinner.css";
+		@import "../../themes/claro/form/Select.css";
 		@import "../../themes/soria/Common.css";
 		@import "../../themes/soria/form/Button.css";
 		@import "../../themes/soria/form/Button_rtl.css";
 		@import "../../themes/soria/form/Common.css";
+		@import "../../themes/soria/form/Select.css";
 		@import "../../themes/nihilo/Common.css";
 		@import "../../themes/nihilo/form/Button.css";
 		@import "../../themes/nihilo/form/Button_rtl.css";
 		@import "../../themes/nihilo/form/Common.css";
+		@import "../../themes/nihilo/form/Select.css";
 
-		#table TD {
+		.dijitTextBox,
+		.dijitSelect {
+			box-sizing: border-box !important;
+			-moz-box-sizing: border-box !important;
+			width: 330px !important;
+		}
+		.dj_ie6 .dijitSelect,
+		.dj_ie7 .dijitSelect {
+			width: 332px !important; /* lack of box-sizing support */
+		}
+		.dj_iequirks .dijitSelect {
+			width: 330px !important; /* lack of box-sizing support */
+		}
+		#table > TBODY > TR > TD {
 			background-color: pink;
 			font-size: 100%;
 			padding: 0;
 			margin: 0;
 		}
-		TABLE#table, #table TD, #table .dijit {
-			border-color: black !important;
+		TABLE#table, #table > TBODY > TR > TD, .dijit {
 			margin: 0 !important;
 		}
-		.dj_ie8 #table .dijit {
-			vertical-align: top; /* needed for IE8 strict */
+		#table .dijit {
+			vertical-align: bottom;
 		}
-		.dj_iequirks #table .dijit {
-			vertical-align: auto; /* needed for IE8 quirks */
+		.dj_ie9 table.dijitSelect {
+			border-width: thin !important; /* needed for IE9 strict bug since 1px table border only measures 0.8px */
+		}
+		.dj_iequirks.dj_ie9 table.dijitSelect {
+			border-width: 1px !important; /* needed for IE9 quirks due to strict rule above */
 		}
 		.padded .dijitInputField {
 			padding: 10px !important;
@@ -57,6 +76,12 @@
 			padding: 1px;
 			border: 1px solid black;
 		}
+		.dj_a11y, /* a11y emulation rules */
+		.dj_a11y * {
+			background: white none !important;
+			border-color: black !important;
+			color: black !important;
+		}
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
@@ -70,17 +95,18 @@
 		dojo.require("dijit.form.ComboBox");
 		dojo.require("dijit.form.FilteringSelect");
 		dojo.require("dijit.form.NumberSpinner");
+		dojo.require("dijit.form.Select");
 		dojo.require("dijit.form.Button");
 
 		dojo.ready(function(){
 
 			var padding = "padded";
-			var theme = "tundra";
+			var theme = "claro";
 			var direction = "ltr";
 			var fontSize = "12pt";
 			var fontFamily = "monospace";
 
-			dijit.byId("theme").isRealA11y = dojo.hasClass(dojo.body(), "dijit_a11y");
+			dijit.byId("theme").isRealA11y = dojo.hasClass(dojo.body(), "dj_a11y");
 
 			var str = window.location.href.substr(window.location.href.indexOf("?")+1).split(/#/);
 			var ary  = str[0].split(/&/);
@@ -115,7 +141,7 @@
 						case "family":
 						case "fontfamily":
 						case "fontFamily":
-							// family string (e.g Courier)
+							// family string (e.g monospace)
 							fontFamily = value;
 							break;
 						case "padding":
@@ -132,36 +158,45 @@
 			dijit.byId('fontSize').set('value', fontSize, true);
 			dijit.byId('fontFamily').set('value', fontFamily, true);
 
-			var textbox = dijit.byId("textbox");
-			var validation = dijit.byId("validation");
-			var combobox = dijit.byId("combobox");
-			var spinner = dijit.byId("spinner");
+			var	textbox = dijit.byId("textbox"),
+				validation = dijit.byId("validation"),
+				combobox = dijit.byId("combobox"),
+				select = dijit.byId("select"),
+				spinner = dijit.byId("spinner");
 
-			var compareToTextBox = function(attr, isParent){
+			var compareToTextBox = function(attr){
 				try{
 				var
 					attrMap = {
+						x: 'offsetLeft',
 						h: 'offsetHeight',
 						w: 'offsetWidth'
 					},
-					textboxNode = isParent ? textbox.domNode.parentNode : textbox.domNode,
-					validationNode = isParent ? validation.domNode.parentNode : validation.domNode,
-					comboboxNode = isParent ? combobox.domNode.parentNode : combobox.domNode,
-					spinnerNode = isParent ? spinner.domNode.parentNode : spinner.domNode,
+					textboxNode = textbox.domNode,
+					validationNode = validation.domNode,
+					comboboxNode = combobox.domNode,
+					selectNode = select.domNode,
+					spinnerNode = spinner.domNode,
 					textboxPos = dojo.position(textboxNode),
 					validationPos = dojo.position(validationNode),
 					comboboxPos = dojo.position(comboboxNode),
-					spinnerPos = dojo.position(spinnerNode);
+					selectPos = dojo.position(selectNode),
+					spinnerPos = dojo.position(spinnerNode),
+					attrMapAttr = attrMap[attr];
 					// IE9 sometimes reports getBoundingClientRect.bottom incorrectly for TD so also check offset*
-					doh.t(Math.round(textboxPos[attr]) == Math.round(validationPos[attr])
-						|| (attrMap[attr] && textboxNode[attrMap[attr]] > 0 && textboxNode[attrMap[attr]] == validationNode[attrMap[attr]]),
-						"validationPos " + attr + " " + textboxPos[attr] + " vs " + validationPos[attr]);
-					doh.t(Math.round(textboxPos[attr]) == Math.round(comboboxPos[attr])
-						|| (attrMap[attr] && textboxNode[attrMap[attr]] > 0 && textboxNode[attrMap[attr]] == comboboxNode[attrMap[attr]]),
-						"comboboxPos " + attr + " " + textboxPos[attr] + " vs " + comboboxPos[attr]);
-					doh.t(Math.round(textboxPos[attr]) == Math.round(spinnerPos[attr])
-						|| (attrMap[attr] && textboxNode[attrMap[attr]] > 0 && textboxNode[attrMap[attr]] == spinnerNode[attrMap[attr]]),
-						"spinnerPos " + attr + " " + textboxPos[attr] + " vs " + spinnerPos[attr]);
+				doh.t(Math.round(textboxPos[attr]) == Math.round(validationPos[attr])
+					|| (attrMapAttr && textboxNode[attrMapAttr] > 0 && textboxNode[attrMapAttr] == validationNode[attrMapAttr]),
+					"validationPos " + attr + " " + textboxPos[attr] + " vs " + validationPos[attr]);
+				doh.t(Math.round(textboxPos[attr]) == Math.round(comboboxPos[attr])
+					|| (attrMapAttr && textboxNode[attrMapAttr] > 0 && textboxNode[attrMapAttr] == comboboxNode[attrMapAttr]),
+					"comboboxPos " + attr + " " + textboxPos[attr] + " vs " + comboboxPos[attr]);
+				doh.t(Math.round(textboxPos[attr]) == Math.round(selectPos[attr])
+					|| (attrMapAttr && textboxNode[attrMapAttr] > 0 && textboxNode[attrMapAttr] == selectNode[attrMapAttr])
+					|| (dojo.isIE <= 7 && (Math.round(textboxPos[attr]) - Math.round(selectPos[attr]) == 2)), // box-sizing issue
+					"selectPos " + attr + " " + textboxPos[attr] + " vs " + selectPos[attr]);
+				doh.t(Math.round(textboxPos[attr]) == Math.round(spinnerPos[attr])
+					|| (attrMapAttr && textboxNode[attrMapAttr] > 0 && textboxNode[attrMapAttr] == spinnerNode[attrMapAttr]),
+					"spinnerPos " + attr + " " + textboxPos[attr] + " vs " + spinnerPos[attr]);
 				}catch(e){
 					throw e; // prevent consoles from including entire function text in output
 				}
@@ -173,10 +208,6 @@
 						runTest: function(){ compareToTextBox("x"); }
 				},
 				{
-						name: "y",
-						runTest: function(){ compareToTextBox("h", true); }
-				},
-				{
 						name: "h",
 						runTest: function(){ compareToTextBox("h"); }
 				},
@@ -195,6 +226,8 @@
 				combobox.set('displayedValue', "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz");
 				spinner._hasBeenBlurred = true;
 				spinner.set('displayedValue', "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz");
+				select._hasBeenBlurred = true;
+				select.set('value', "");
 			};
 
 			doh.register("create normal boxes", {
@@ -208,26 +241,27 @@
 					spinner.set('value', 32);
 					combobox.onChange = function(v){ if(v == "KY"){ d.callback(true); combobox.onChange = function(){}; }};
 					combobox.set('value', "KY");
+					select.set('value', "noError");
 					return d;
 				}
  			});
 
 			doh.register("check normal sizes", runTest);
 
-			dojo.forEach([textbox, validation, combobox, spinner], function(widget){
+			dojo.forEach([textbox, validation, combobox, select, spinner], function(widget){
 				var widgetName = widget.baseClass.replace(/^.* /, "");
 				doh.register("valid internal offsets", [
 					{
 						name: "textbox: " + widgetName,
 						timeout: 1000,
 						runTest: function(){
-							var paddedBoxPos = dojo.position(widget.focusNode.parentNode);
-							var inputPos = dojo.position(widget.focusNode);
-							var paddingLeft = Math.abs(inputPos.x - paddedBoxPos.x);
-							var paddingRight = Math.abs(inputPos.w - paddedBoxPos.w) - paddingLeft;
-							var paddingTop = Math.abs(inputPos.y - paddedBoxPos.y);
-							var paddingBottom = Math.abs(inputPos.h - paddedBoxPos.h) - paddingTop;
-							var pad = undefined;
+							var	paddedBoxPos = dojo.position(widget.containerNode || widget.focusNode.parentNode),
+								inputPos = dojo.position(dojo.query('.dijitSelectLabel', widget.domNode)[0] || widget.focusNode),
+								paddingLeft = Math.abs(inputPos.x - paddedBoxPos.x),
+								paddingRight = Math.abs(inputPos.w - paddedBoxPos.w) - paddingLeft,
+								paddingTop = Math.abs(inputPos.y - paddedBoxPos.y),
+								paddingBottom = Math.abs(inputPos.h - paddedBoxPos.h) - paddingTop,
+								pad = undefined;
 							if(dojo.hasClass(testtable, "padded")){
 								pad = 10;
 							}else if(dojo.hasClass(testtable, "unPadded")){
@@ -245,31 +279,53 @@
 						name: "padded box: " + widgetName,
 						timeout: 1000,
 						runTest: function(){
-							var domNodePos = dojo.position(widget.domNode);
-							var paddedBoxPos = dojo.position(widget.focusNode.parentNode);
-							var clientHeight = widget.domNode.clientHeight;
-							var clientWidth = widget.domNode.clientWidth;
+							var	domNodePos = dojo.position(widget.domNode),
+								contentNode = (widget.containerNode || widget.focusNode).parentNode,
+								paddedBoxPos = dojo.position(contentNode),
+								//paddedBoxPos = dojo.position(widget.containerNode || widget.focusNode.parentNode),
+								// getBorderExtents bug neccesitates use of currentStyle
+								borderV = ((widget.domNode.currentStyle && widget.domNode.currentStyle.borderTopWidth) 
+									? (parseInt(widget.domNode.currentStyle.borderTopWidth) + parseInt(widget.domNode.currentStyle.borderBottomWidth)) 
+									: dojo.getBorderExtents(widget.domNode).h)
+									|| (widget.domNode.offsetHeight - widget.domNode.firstChild.offsetHeight),
+								borderH = ((widget.domNode.currentStyle && widget.domNode.currentStyle.borderLeftWidth) 
+									? (parseInt(widget.domNode.currentStyle.borderLeftWidth) + parseInt(widget.domNode.currentStyle.borderRightWidth)) 
+									: dojo.getBorderExtents(widget.domNode).h)
+									|| (widget.domNode.offsetWidth - widget.domNode.firstChild.offsetWidth);
+							if(!borderV || !borderH){ // border is inside domNode
+								var be = dojo.getBorderExtents(contentNode);
+								paddedBoxPos.x += be.l;
+								paddedBoxPos.y += be.t;
+								paddedBoxPos.w -= be.w;
+								paddedBoxPos.h -= be.h;
+								borderV = be.h;
+								borderH = be.w;
+							}
+							var	clientHeight = widget.domNode.offsetHeight - borderV,
+								clientWidth = widget.domNode.offsetWidth - borderH,
+								offset = Math.min(Math.abs(domNodePos.x + (borderH >> 1) - paddedBoxPos.x), Math.abs(domNodePos.x + domNodePos.w - (borderH >> 1) - paddedBoxPos.x - paddedBoxPos.w));
 							doh.t(Math.abs(clientHeight-paddedBoxPos.h) <= 1, "padded textbox height: " + clientHeight + " vs " + paddedBoxPos.h);
-							var border = (domNodePos.w - clientWidth) >> 1; // average border width
-							var offset = Math.min(Math.abs(domNodePos.x + border - paddedBoxPos.x), Math.abs(domNodePos.x + domNodePos.w - border - paddedBoxPos.x - paddedBoxPos.w));
-							doh.t(offset <= 1, "padded textbox horizontally just left or right (" + offset + ") of domNode: domNode x/w/b = " + domNodePos.x+"/"+domNodePos.w+"/"+border + ", pad box x/w = " + paddedBoxPos.x+"/"+paddedBoxPos.w);
+							doh.t(offset <= 1, "padded textbox horizontally just left or right (" + offset + ") of domNode: domNode x/w/b = " + domNodePos.x+"/"+domNodePos.w+"/"+borderH + ", pad box x/w = " + paddedBoxPos.x+"/"+paddedBoxPos.w);
 						}
 					},
 					{
 						name: "button: " + widgetName,
 						timeout: 1000,
 						runTest: function(){
-							if(widgetName == "dijitTextBox" || widgetName == "dijitValidationTextBox" ||
-								widgetName == "dijitNumberTextBox" || widgetName == "dijitCurrencyTextBox"){ return; }
-							var paddedBoxPos = dojo.position(widget.focusNode.parentNode);
-							var buttonNode = dojo.query(".dijitValidationContainer", widget.domNode)[0].previousSibling;
-							var buttonPos = dojo.position(buttonNode);
-							var offset = Math.min(Math.abs(paddedBoxPos.x + paddedBoxPos.w - buttonPos.x), Math.abs(buttonPos.x + buttonPos.w - paddedBoxPos.x));
-							// IE 6 float bug(s) causes a known 3px margin between input field & validation icon 
+							var buttonNode = dojo.query(".dijitArrowButton", widget.domNode)[0];
+							if(!buttonNode){ return; }
+							var paddedBoxNode = (widget.containerNode || widget.focusNode).parentNode;
+							while(buttonNode.parentNode != paddedBoxNode.parentNode){
+								buttonNode = buttonNode.parentNode;
+							}
+							var	paddedBoxPos = dojo.position(paddedBoxNode),
+								buttonPos = dojo.position(buttonNode),
+								offset = Math.min(Math.abs(paddedBoxPos.x + paddedBoxPos.w - buttonPos.x), Math.abs(buttonPos.x + buttonPos.w - paddedBoxPos.x));
+							// IE 6 & quirks float bug(s) causes a known 3px margin between input field & validation icon 
 							// Fix could be .dj_ie .dijitInputField { float:right; }
 							// But this breaks even more the tests, dojo.position() bug?
 							if(dojo.isIE < 7 || dojo.isQuirks)
-								doh.t(offset <= 3, "button node horizontally just left or right (" + offset + ") of padded input node: input x/w = " + paddedBoxPos.x+"/"+paddedBoxPos.w + ", button x/w = " + buttonPos.x+"/"+buttonPos.w);
+								doh.t(offset <= 4, "button node horizontally just left or right (" + offset + ") of padded input node: input x/w = " + paddedBoxPos.x+"/"+paddedBoxPos.w + ", button x/w = " + buttonPos.x+"/"+buttonPos.w);
 							else
 								doh.t(offset <= 1, "button node horizontally just left or right (" + offset + ") of padded input node: input x/w = " + paddedBoxPos.x+"/"+paddedBoxPos.w + ", button x/w = " + buttonPos.x+"/"+buttonPos.w);
 						}
@@ -296,8 +352,8 @@
 					name: "ComboBox",
 					timeout: 1000,
 					runTest: function(){
-						var inputPos = dojo.position(combobox.focusNode.parentNode);
-						var arrowPos = dojo.position(combobox._buttonNode);
+						var	inputPos = dojo.position(combobox.focusNode.parentNode),
+							arrowPos = dojo.position(combobox._buttonNode);
 						doh.t(Math.abs(inputPos.h-arrowPos.h) <= 1, "ComboBox button height (" + arrowPos.h + ") is same as input height (" + inputPos.h + ")");
 					}
 				},
@@ -306,9 +362,9 @@
 					timeout: 1000,
 					runTest: function(){
 						// use offsetHeight since the buttons could be truncated by overflow:hidden
-						var inputHeight = spinner.focusNode.parentNode.offsetHeight;
-						var downArrowHeight = spinner.downArrowNode.offsetHeight;
-						var upArrowHeight = spinner.upArrowNode.offsetHeight;
+						var	inputHeight = spinner.focusNode.parentNode.offsetHeight,
+							downArrowHeight = spinner.downArrowNode.offsetHeight,
+							upArrowHeight = spinner.upArrowNode.offsetHeight;
 						doh.t((inputHeight-downArrowHeight-upArrowHeight) <= 1, "Spinner button heights (" + upArrowHeight + "," + downArrowHeight + ") are equal to the input height (" + inputHeight + ")");
 						doh.t(Math.abs(upArrowHeight - downArrowHeight) <= 1, "Spinner UP button height (" + upArrowHeight + ") is equal to the DOWN button height (" + downArrowHeight + ")");
 					}
@@ -322,13 +378,13 @@
 						name: "textbox: " + widgetName,
 						timeout: 1000,
 						runTest: function(){
-							var paddedBoxPos = dojo.position(widget.focusNode.parentNode);
-							var inputPos = dojo.position(widget.focusNode);
-							var paddingLeft = Math.abs(inputPos.x - paddedBoxPos.x);
-							var paddingRight = Math.abs(inputPos.w - paddedBoxPos.w) - paddingLeft;
-							var paddingTop = Math.abs(inputPos.y - paddedBoxPos.y);
-							var paddingBottom = Math.abs(inputPos.h - paddedBoxPos.h) - paddingTop;
-							var pad = undefined;
+							var	paddedBoxPos = dojo.position(widget.focusNode.parentNode),
+								inputPos = dojo.position(widget.focusNode),
+								paddingLeft = Math.abs(inputPos.x - paddedBoxPos.x),
+								paddingRight = Math.abs(inputPos.w - paddedBoxPos.w) - paddingLeft,
+								paddingTop = Math.abs(inputPos.y - paddedBoxPos.y),
+								paddingBottom = Math.abs(inputPos.h - paddedBoxPos.h) - paddingTop,
+								pad = undefined;
 							if(dojo.hasClass(testtable, "padded")){
 								pad = 10;
 							}else if(dojo.hasClass(testtable, "unPadded")){
@@ -346,13 +402,13 @@
 						name: "padded box: " + widgetName,
 						timeout: 1000,
 						runTest: function(){
-							var domNodePos = dojo.position(widget.domNode);
-							var paddedBoxPos = dojo.position(widget.focusNode.parentNode);
-							var clientHeight = widget.domNode.clientHeight;
-							var clientWidth = widget.domNode.clientWidth;
+							var	domNodePos = dojo.position(widget.domNode),
+								paddedBoxPos = dojo.position(widget.focusNode.parentNode),
+								clientHeight = widget.domNode.clientHeight,
+								clientWidth = widget.domNode.clientWidth,
+								border = (domNodePos.w - clientWidth) >> 1, // average border width
+								offset = Math.min(Math.abs(domNodePos.x + border - paddedBoxPos.x), Math.abs(domNodePos.x + domNodePos.w - border - paddedBoxPos.x - paddedBoxPos.w));
 							doh.t(Math.abs(clientHeight-paddedBoxPos.h) <= 1, "padded textbox height: " + clientHeight + " vs " + paddedBoxPos.h);
-							var border = (domNodePos.w - clientWidth) >> 1; // average border width
-							var offset = Math.min(Math.abs(domNodePos.x + border - paddedBoxPos.x), Math.abs(domNodePos.x + domNodePos.w - border - paddedBoxPos.x - paddedBoxPos.w));
 							doh.t(offset <= 1, "padded textbox horizontally just left or right (" + offset + ") of domNode: domNode x/w/b = " + domNodePos.x+"/"+domNodePos.w+"/"+border + ", pad box x/w = " + paddedBoxPos.x+"/"+paddedBoxPos.w);
 						}
 					},
@@ -361,16 +417,16 @@
 						timeout: 1000,
 						runTest: function(){
 							if(widget.state != "Error"){ return; }
-							var validationNode = dojo.query(".dijitValidationContainer", widget.domNode)[0];
-							var validationPos = dojo.position(validationNode);
-							var paddedBoxPos = dojo.position(widget.focusNode.parentNode);
-							var offset = Math.min(Math.abs(paddedBoxPos.x + paddedBoxPos.w - validationPos.x), Math.abs(validationPos.x + validationPos.w - paddedBoxPos.x));
+							var	validationNode = dojo.query(".dijitValidationContainer", widget.domNode)[0],
+								validationPos = dojo.position(validationNode),
+								paddedBoxPos = dojo.position(widget.focusNode.parentNode),
+								offset = Math.min(Math.abs(paddedBoxPos.x + paddedBoxPos.w - validationPos.x), Math.abs(validationPos.x + validationPos.w - paddedBoxPos.x));
 
-							// IE 6 float bug(s) causes a known 3px margin between input field & validation icon 
+							// IE 6 & quirks float bug(s) causes a known 3px margin between input field & validation icon 
 							// Fix could be .dj_ie .dijitInputField { float:right; }
 							// But this breaks even more the tests, dojo.position() bug?
 							if(dojo.isIE < 7 || dojo.isQuirks)
-								doh.t(offset <= 3, "padded textbox horizontally just left or right (" + offset + ") of validation node: valiation node x/w = " + validationPos.x+"/"+validationPos.w + ", pad box x/w = " + paddedBoxPos.x+"/"+paddedBoxPos.w);
+								doh.t(offset <= 4, "padded textbox horizontally just left or right (" + offset + ") of validation node: valiation node x/w = " + validationPos.x+"/"+validationPos.w + ", pad box x/w = " + paddedBoxPos.x+"/"+paddedBoxPos.w);
 							else
 								doh.t(offset <= 1, "padded textbox horizontally just left or right (" + offset + ") of validation node: valiation node x/w = " + validationPos.x+"/"+validationPos.w + ", pad box x/w = " + paddedBoxPos.x+"/"+paddedBoxPos.w);
 						}
@@ -381,11 +437,11 @@
 						runTest: function(){
 							if(widget.state != "Error" || widgetName == "dijitValidationTextBox" ||
 								widgetName == "dijitNumberTextBox" || widgetName == "dijitCurrencyTextBox"){ return; }
-							var validationNode = dojo.query(".dijitValidationContainer", widget.domNode)[0];
-							var buttonNode = dojo.query(".dijitValidationContainer", widget.domNode)[0].previousSibling;
-							var validationPos = dojo.position(validationNode);
-							var buttonPos = dojo.position(buttonNode);
-							var offset = Math.min(Math.abs(validationPos.x + validationPos.w - buttonPos.x), Math.abs(buttonPos.x + buttonPos.w - validationPos.x));
+							var	validationNode = dojo.query(".dijitValidationContainer", widget.domNode)[0],
+								buttonNode = dojo.query(".dijitValidationContainer", widget.domNode)[0].previousSibling,
+								validationPos = dojo.position(validationNode),
+								buttonPos = dojo.position(buttonNode),
+								offset = Math.min(Math.abs(validationPos.x + validationPos.w - buttonPos.x), Math.abs(buttonPos.x + buttonPos.w - validationPos.x));
 							doh.t(offset <= 1, "button node horizontally just left or right (" + offset + ") of validation node: valiation node x/w = " + validationPos.x+"/"+validationPos.w + ", button x/w = " + buttonPos.x+"/"+buttonPos.w);
 						}
 					}
@@ -396,11 +452,11 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">dijit.form.TextBox size tests</h1>
 
-	<table class="padded" id="table" style="font-family:monospace;font-size:12pt;">
+	<table class="padded" id="table" style="font-family:monospace;font-size:12pt;" role="presentation">
 		<tr>
 			<td style="font-size:1px;overflow:hidden;"> </td>
 			<td style="font-size:1px;overflow:hidden;"> </td>
@@ -408,29 +464,39 @@
 		</tr>
 		<tr>
 			<td class="layout">TextBox</td>
-			<td class="layout"><input id="textbox" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", value:"text"'/></td>
+			<td class="layout"><input id="textbox" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"text", value:"text", "aria-label":"textbox"'/></td>
 			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 		<tr>
 			<td class="layout">NumberTextBox</td>
-			<td class="layout"><input id="validation" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='type:"text", value:54, required:true'/></td>
+			<td class="layout"><input id="validation" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='type:"text", value:54, required:true, "aria-label":"NumberTextBox"'/></td>
 			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 		<tr>
 			<td class="layout">FilteringSelect</td>
-			<td class="layout"><select id="combobox" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props='required:true'>
+			<td class="layout"><select id="combobox" data-dojo-type="dijit/form/FilteringSelect" data-dojo-props='required:true, "aria-label":"FilteringSelect"'>
 				<option value="KY">Kentucky</option>
 			</select></td>
 			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 		<tr>
+			<td class="layout">Select</td>
+			<td class="layout">
+			<!-- width:0px prevents IE from resizing the table columns inappropriately -->
+			<select id="select" data-dojo-type="dijit/form/Select" style="width:0px;" data-dojo-props='required:true, "aria-label":"Select"'>
+				<option data-dojo-value="">Invalid</option>
+				<option data-dojo-value="noError">Some Label</option>
+			</select></td>
+			<td style="font-size:1px;overflow:hidden;"> </td>
+		</tr>
+		<tr>
 			<td class="layout">NumberSpinner</td>
-			<td class="layout"><div id="spinner" data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='type:"text", value:45, required:true'></div></td>
+			<td class="layout"><div id="spinner" data-dojo-type="dijit/form/NumberSpinner" data-dojo-props='type:"text", value:45, required:true, "aria-label":"numberSpinner"'></div></td>
 			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 		<tr>
 			<td class="layout">INPUT type=file</td>
-			<td class="layout"><input id="file" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"file" '/></td>
+			<td class="layout"><input id="file" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"file", "aria-label":"textboxFile" '/></td>
 			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 		<tr>
@@ -445,14 +511,22 @@
 		function fontFamilyOnChange(fontFamily){
 			testtable.style.fontFamily = fontFamily;
 			if(dojo.isIE){
-				dojo.query('INPUT', testtable).forEach(function(node){
+				dojo.query('[widgetId]', document.body).forEach(function(node){
 					node.style.fontFamily = fontFamily;
+					dojo.query('*', node).forEach(function(node){
+						node.style.fontFamily = fontFamily;
+					});
 				});
 			}
 		}
 
 		function directionOnChange(direction){
-			dojo.query('.dijitTextBox', testtable).forEach(function(node){
+			dojo.query('[widgetId]', testtable).forEach(function(node){
+				if(dojo.isIE == 7){ // IE layout bugs
+					dojo.query('INPUT', node).forEach(function(node){
+						node.className = node.className;
+					});
+				}
 				node.style.direction = direction;
 				node.parentNode.style.direction = direction;
 				dojo.forEach(node.className.split(' '), function(cls){
@@ -475,24 +549,46 @@
 
 		function themeOnChange(theme){
 			if(theme == "a11y"){
-				theme="dijit_a11y";
+				theme="dj_a11y";
 			}
-			dojo.body().className = theme + ((this.isRealA11y && theme != "dijit_a11y") ? " dijit_a11y" : "");
+			dojo.body().className = theme + ((this.isRealA11y && theme != "dj_a11y") ? " dj_a11y" : "");
+		}
+
+
+		function sizeOnChange(size){
+			testtable.style.fontSize = size;
+			dojo.query('[widgetId]', testtable).forEach(function(node){
+				if(dojo.isIE == 7){ // IE layout bugs
+					dojo.query('INPUT', node).forEach(function(node){
+						node.className = node.className;
+					});
+				}
+			});
+		}
+
+		function paddingOnChange(padding){
+			testtable.className = padding;
+			dojo.query('[widgetId]', testtable).forEach(function(node){
+				if(dojo.isIE == 7){ // IE layout bugs
+					dojo.query('INPUT', node).forEach(function(node){
+						node.className = node.className;
+					});
+				}
+			});
 		}
 	</script>
-	<table style="display:block;">
+	<table style="background-color:cyan;" border="1" role="presentation">
 	<tr><td class="layout" style="text-align:right;">Font family:
-	<select id="fontFamily" data-dojo-type="dijit.form.ComboBox" data-dojo-props='style:{fontSize:"14pt"}, value:"", onChange:fontFamilyOnChange'>
-		<option>monospace</option>
-		<option selected>Courier</option>
+	<select id="fontFamily" data-dojo-type="dijit/form/ComboBox" data-dojo-props='style:{fontSize:"14pt"}, value:"", onChange:fontFamilyOnChange, "aria-label":"fontFamily"'>
+		<option selected>monospace</option>
 		<option>Helvetica</option>
 		<option>Times</option>
-		<option>system,fixed</option>
+		<option>Verdana</option>
 	</select></td></tr>
 	<tr><td class="layout" style="text-align:right;">Font size:
-	<select id="fontSize" data-dojo-type="dijit.form.ComboBox" data-dojo-props='style:{fontSize:"14pt"}, value:"", onChange:function(val){ testtable.style.fontSize = val; }'>
+	<select id="fontSize" data-dojo-type="dijit/form/ComboBox" data-dojo-props='style:{fontSize:"14pt"}, value:"", onChange:sizeOnChange, "aria-label":"fontSize"'>
 		<option>small</option>
-		<option>medium</option>
+		<option selected>12pt</option>
 		<option>xx-large</option>
 		<option>8pt</option>
 		<option>21px</option>
@@ -501,25 +597,25 @@
 		<option>200%</option>
 	</select></td></tr>
 	<tr><td class="layout" style="text-align:right;">Padding:
-	<select id="padding" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props='style:{fontSize:"14pt"}, required:false, value:"", onChange:function(val){ testtable.className = val; }'>
+	<select id="padding" data-dojo-type="dijit/form/Select" data-dojo-props='style:{width:"0px", fontSize:"14pt"}, value:"padded", onChange:paddingOnChange, "aria-label":"padding"'>
 		<option value="default">default</option>
 		<option value="padded">padded</option>
 		<option value="unPadded">unPadded</option>
 	</select></td></tr>
 	<tr><td class="layout" style="text-align:right;">Direction:
-	<select id="direction" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props='style:{fontSize:"14pt"}, required:false, value:"", onChange:directionOnChange'>
-		<option value="ltr">left-to-right</option>
-		<option value="rtl">right-to-left</option>
-	</select></td></tr>
+	<span id="direction" data-dojo-type="dijit/form/Select" data-dojo-props='style:{width:"0px", fontSize:"14pt"}, value:"ltr", onChange:directionOnChange, "aria-label":"direction"'>
+		<span data-dojo-value="ltr">left-to-right</span>
+		<span data-dojo-value="rtl">right-to-left</span>
+	</span></td></tr>
 	<tr><td class="layout" style="text-align:right;">Theme:
-	<select id="theme" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props='style:{fontSize:"14pt"}, required:false, value:"", onChange:themeOnChange'>
-		<option value="tundra">tundra</option>
-		<option value="soria">soria</option>
-		<option value="nihilo">nihilo</option>
-		<option value="claro">claro</option>
-		<option value="a11y">a11y</option>
+	<select id="theme" data-dojo-type="dijit/form/Select" data-dojo-props='style:{width:"0px", fontSize:"14pt"}, value:"claro", onChange:themeOnChange, "aria-label":"theme"'>
+		<option data-dojo-value="tundra">tundra</option>
+		<option data-dojo-value="soria">soria</option>
+		<option data-dojo-value="nihilo">nihilo</option>
+		<option data-dojo-value="claro">claro</option>
+		<option data-dojo-value="a11y">a11y</option>
 	</select></td></tr>
 	</table>
-	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ doh.run(); }'>Run tests</button>
+	<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ doh.run(); }'>Run tests</button>
 </body>
 </html>
diff --git a/dijit/tests/form/TextBox_sizes.js b/dijit/tests/form/TextBox_sizes.js
index 35541ef..e877764 100644
--- a/dijit/tests/form/TextBox_sizes.js
+++ b/dijit/tests/form/TextBox_sizes.js
@@ -53,402 +53,55 @@ doh.registerUrl('t.monospace.2em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tes
 doh.registerUrl('t.monospace.2em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
 doh.registerUrl('t.monospace.2em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
 doh.registerUrl('t.monospace.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.Courier.small.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.system.small.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-}catch(e){
-	doh.debug(e);
-}
+doh.registerUrl('t.Times.small.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.small.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.small.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.small.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.small.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.small.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.small.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.small.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.small.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.small.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.small.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.small.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.large.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.1em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=2em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=2em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=2em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=2em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=2em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=2em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Times'), 999999);
+doh.registerUrl('t.Times.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Times'), 999999);
 
-try{
-
-doh.registerUrl('t.monospace.small.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.Courier.small.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.system.small.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-}catch(e){
-	doh.debug(e);
-}
-
-try{
-
-doh.registerUrl('t.monospace.small.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.small.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=small&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.large.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=large&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.1em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.monospace.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=monospace'), 999999);
-doh.registerUrl('t.Courier.small.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.small.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=small&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.large.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=large&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.1em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.Courier.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=Courier'), 999999);
-doh.registerUrl('t.system.small.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.small.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=small&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.large.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=large&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.1em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=1em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.padded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=padded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.ltr.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.ltr.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.ltr.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=ltr&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.rtl.claro',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=claro&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.rtl.tundra',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=tundra&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
-doh.registerUrl('t.system.2em.unPadded.rtl.a11y',dojo.moduleUrl('dijit', 'tests/form/TextBox_sizes.html?theme=a11y&dir=rtl&padding=unPadded&fontSize=2em&fontFamily=system'), 999999);
 }catch(e){
 	doh.debug(e);
 }
diff --git a/dijit/tests/form/TextBox_types.html b/dijit/tests/form/TextBox_types.html
index 6d4a484..b3548c6 100644
--- a/dijit/tests/form/TextBox_types.html
+++ b/dijit/tests/form/TextBox_types.html
@@ -1,5 +1,5 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="en">
 <head>
 
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
@@ -63,25 +63,25 @@
 
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1>TextBox type Tests</h1>
-	<input id="hn" type="number" value="1234" /><br>
-	<input id="hd" type="date" value="2011-05-19" /><br>
-	<input id="ht" type="time" value="10:11:00" /><br>
-	<input id="hp" type="password" value="password" /><br>
+	<input id="hn" aria-label="hn" type="number" value="1234" /><br>
+	<input id="hd" aria-label="hd" type="date" value="2011-05-19" /><br>
+	<input id="ht" aria-label="ht" type="time" value="10:11:00" /><br>
+	<input id="hp" aria-label="hp" type="password" value="password" /><br>
 <br>
-	<input id="dr" type="number" dojoType="dijit.form.RangeBoundTextBox" value="1234" /><br>
-	<input id="dp" type="password" dojoType="dijit.form.TextBox" value="password" /><br>
-	<input id="dn" type="number" dojoType="dijit.form.NumberTextBox" value="1234" /><br>
-	<input id="dc" type="number" dojoType="dijit.form.CurrencyTextBox" value="1234.00" /><br>
-	<input id="dd" type="date" dojoType="dijit.form.DateTextBox" value="2011-05-19" /><br>
-	<input id="dt" type="time" dojoType="dijit.form.TimeTextBox" value="T10:11:00" /><br>
+	<input aria-label="dr" id="dr" type="number" dojoType="dijit.form.RangeBoundTextBox" value="1234" /><br>
+	<input aria-label="dp" id="dp" type="password" dojoType="dijit.form.TextBox" value="password" /><br>
+	<input aria-label="dn" id="dn" type="number" dojoType="dijit.form.NumberTextBox" value="1234" /><br>
+	<input aria-label="dc" id="dc" type="number" dojoType="dijit.form.CurrencyTextBox" value="1234.00" /><br>
+	<input aria-label="dd" id="dd" type="date" dojoType="dijit.form.DateTextBox" value="2011-05-19" /><br>
+	<input aria-label="dt" id="dt" type="time" dojoType="dijit.form.TimeTextBox" value="T10:11:00" /><br>
 <br>
-	<input id="wr" data-dojo-type="dijit.form.RangeBoundTextBox" data-dojo-props='value:1234, type:"number"' /><br>
-	<input id="wp" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"password", type:"password"' /><br>
-	<input id="wn" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='value:1234, type:"number"' /><br>
-	<input id="wc" data-dojo-type="dijit.form.CurrencyTextBox" data-dojo-props='value:1234, type:"number"' /><br>
-	<input id="wd" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='value:new Date(2011,04,19,0,0,0,0), type:"date"' /><br>
-	<input id="wt" data-dojo-type="dijit.form.TimeTextBox" data-dojo-props='value:new Date(0,0,0,10,11,0,0), type:"time"' /><br>
+	<input id="wr" data-dojo-type="dijit/form/RangeBoundTextBox" data-dojo-props='value:1234, type:"number", "aria-label":"wr" ' /><br>
+	<input id="wp" data-dojo-type="dijit/form/TextBox" data-dojo-props='value:"password", type:"password", "aria-label":"wp" ' /><br>
+	<input id="wn" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='value:1234, type:"number", "aria-label":"wn" ' /><br>
+	<input id="wc" data-dojo-type="dijit/form/CurrencyTextBox" data-dojo-props='value:1234, type:"number", "aria-label":"wc" ' /><br>
+	<input id="wd" data-dojo-type="dijit/form/DateTextBox" data-dojo-props='value:new Date(2011,04,19,0,0,0,0), type:"date", "aria-label":"wd" ' /><br>
+	<input id="wt" data-dojo-type="dijit/form/TimeTextBox" data-dojo-props='value:new Date(0,0,0,10,11,0,0), type:"time", "aria-label":"wt" ' /><br>
 </body>
 </html>
diff --git a/dijit/tests/form/ToggleButtonMixin.html b/dijit/tests/form/ToggleButtonMixin.html
index 95f39c5..e36d8a7 100644
--- a/dijit/tests/form/ToggleButtonMixin.html
+++ b/dijit/tests/form/ToggleButtonMixin.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
@@ -84,7 +84,10 @@
 							d.callback(true);
 						}
 						dijit_events.set('onChange', onChange);
-						dijit_events._onClick({ preventDefault: nop });
+						dijit_events._onClick({
+							preventDefault: nop,
+							stopPropagation: nop
+						});
 
 						return d;
 					}
@@ -103,7 +106,12 @@
 							d.callback(true);
 						}
 						mobile_events.set("onChange", onChange);
-						setTimeout(function(){ mobile_events.focusNode.click({ preventDefault: nop }); }, 0);
+						setTimeout(function(){
+							mobile_events.focusNode.click({
+								preventDefault: nop,
+								stopPropagation: nop
+							});
+						}, 0);
 
 						return d;
 					}
@@ -115,7 +123,7 @@
 					name: "dijit",
 					timeout: 2000,
 					runTest: function(){
-						new dijit.form.ToggleButton({id:"dijit_programmatic", type:"button", checked:true, label:"No srcNodeRef"}).placeAt("dijit_programmatic_container", "first");
+						new dijit.form.ToggleButton({id:"dijit_programmatic", type:"button", checked:true, label:"No srcNodeRef", "aria-label":"dijit_programmatic"}).placeAt("dijit_programmatic_container", "first");
 						var dijit_programmatic = dijit.byId('dijit_programmatic');
 						var pos = dojo.position(dijit_programmatic.domNode, true);
 						doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'dijit position');
@@ -126,7 +134,7 @@
 					name: "mobile",
 					timeout: 2000,
 					runTest: function(){
-						new dojox.mobile.ToggleButton({id:"mobile_programmatic", type:"button", checked:true, label:"No srcNodeRef"}).placeAt("mobile_programmatic_container", "first");
+						new dojox.mobile.ToggleButton({id:"mobile_programmatic", type:"button", checked:true, label:"No srcNodeRef", "aria-label":"mobile_programmatic"}).placeAt("mobile_programmatic_container", "first");
 						var mobile_programmatic = dijit.byId('mobile_programmatic');
 						var pos = dojo.position(mobile_programmatic.domNode, true);
 						doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'mobile position');
@@ -139,7 +147,7 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1 class="testTitle">_ToggleButtonMixin (dijit and mobile) non-robot tests</h1>
 
 	<table id="table">
@@ -150,13 +158,13 @@
 		</tr>
 		<tr>
 			<td class="layout">attributes</td>
-			<td class="layout"><input id="dijit_attributes" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='type:"button", checked: true, label:"original", "class":"mblRedButton"'/></td>
+			<td class="layout"><input id="dijit_attributes" data-dojo-type="dijit/form/ToggleButton" data-dojo-props='type:"button", checked: true, label:"original", "class":"mblRedButton"'/></td>
 			<td class="layout"><button type="button" class="mblRedButton" checked id="mobile_attributes" dojoType="dojox.mobile.ToggleButton" label="original"/></td>
 		</tr>
 		<tr>
 		<tr>
 			<td class="layout">Events</td>
-			<td class="layout"><button id="dijit_events" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='type:"button", onClick:function(){ return true; }'>innerHTML</button></td>
+			<td class="layout"><button id="dijit_events" data-dojo-type="dijit/form/ToggleButton" data-dojo-props='type:"button", onClick:function(){ return true; }'>innerHTML</button></td>
 			<td class="layout"><button type="button" id="mobile_events" data-dojo-type="dojox.mobile.ToggleButton" data-dojo-props='type:"button", onClick:function(){ return true; }'>innerHTML</button></td>
 		</tr>
 		<tr>
diff --git a/dijit/tests/form/_autoComplete.html b/dijit/tests/form/_autoComplete.html
index 79c152f..b913723 100644
--- a/dijit/tests/form/_autoComplete.html
+++ b/dijit/tests/form/_autoComplete.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>dijit.form.ComboBox Unit Test</title>
@@ -21,6 +21,7 @@
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
 	<script type="text/javascript">
+		var isUnitTest = false;
 		var testWidget = "dijit.form.ComboBox";
 		var qstr = window.location.search.substr(1);
 		if(qstr.length){
@@ -30,14 +31,20 @@
 		                if(tp[0] == "testWidget"){
 		                        testWidget = tp[1];
 					document.title = testWidget + " Unit Test";
-		                }
+		                }else if(tp[0] == "mode"){
+					isUnitTest = tp[1] == "test";
+				}
 		        }
 		}
+		var isComboBox = testWidget == "dijit.form.ComboBox";
+		dojo.require("dojo.store.Memory");
+		dojo.require("dojo._base.Deferred");
 		dojo.require("dojo.data.ItemFileReadStore");
 		dojo.require("dijit.tests._data.SlowStore");
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require(testWidget);
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		dojo.require("doh.runner");
 
 		function setVal2(val){
 			dojo.byId('value2').value=val;
@@ -61,7 +68,20 @@
 			return label;
 		}
 
+		// Test Custom Store
+		dojo.declare("StateSelect", isComboBox ? dijit.form.ComboBox : dijit.form.FilteringSelect , {
+			placeHolder: "Select a State",
+			searchAttr: "name",
+			label: "State:",
+			name: "state",
+			style: "width: 160px",
+			store: new dojo.data.ItemFileReadStore({ url: dojo.moduleUrl("dijit.tests._data", "states.json") }),
+			value: ''
+		});
+
 		function init(){
+			var combo;
+
 			var testClass = dojo.getObject(testWidget);
 			// substitute testWidget for each data-dojo-type=$testWidget
 			dojo.query('[data-dojo-type="$testWidget"]').forEach(function(node){
@@ -93,6 +113,208 @@
 				searchAttr:"name",
 				fetchProperties: {sort:[{attribute: 'name', descending: true}]}
 			}, dojo.byId("progCombo3"));
+
+			// change Memory store to have an asynchronous total
+			var oldMemoryQuery = dojo.store.Memory.prototype.query;
+			dojo.store.Memory.extend({
+				query: function(){
+					var results = oldMemoryQuery.apply(this, arguments);
+					var total = results.total;
+					results.total = new dojo.Deferred();
+					setTimeout(function(){
+						results.total.resolve(total);
+					}, 100);
+					return results;
+				}
+			});
+
+			if(!isUnitTest){ return; }
+
+			doh.register("label", [
+				{
+					name: "user-specified id",
+					runTest: function(){
+						combo = dijit.byId("setvaluetest");
+						var labelId = combo.domNode.getAttribute('aria-labelledby');
+						doh.is("setvaluetest_mylabel", labelId, "labelledby");
+						doh.is(labelId, dojo.byId(labelId).id, "label id");
+					}
+				},
+				{
+					name: "generated id",
+					runTest: function(){
+						combo = dijit.byId("datatest");
+						var labelId = combo.domNode.getAttribute('aria-labelledby');
+						doh.is("datatest_label", labelId, "labelledby");
+						doh.is(labelId, dojo.byId(labelId).id, "label id");
+					}
+				},
+				{
+					name: "aria roles and attributes",
+					timeout: 2000,
+					runTest:function(){
+						var d = new doh.Deferred();
+						combo = dijit.byId("setvaluetest");
+						// ComboBox and FilteringSelect have the same roles and attributes
+						doh.is("combobox", combo._popupStateNode.getAttribute("role"), "combo _popupStateNode role");
+						doh.t(combo._popupStateNode.getAttribute("aria-haspopup"), "aria-haspopup on combo");
+						doh.is("setvaluetest_mylabel", combo._popupStateNode.getAttribute("aria-labelledby"), "aria-labelledby");
+						doh.f(combo._popupStateNode.getAttribute("aria-expanded"), "initially missing aria-expanded");
+						doh.f(combo._popupStateNode.getAttribute("aria-owns"), "initally missing aria-owns");					
+							
+						var handler = dojo.connect(combo, "openDropDown", function(){
+							dojo.disconnect(handler);
+							setTimeout(d.getTestCallback(function(){
+								doh.t(combo._popupStateNode.getAttribute("aria-expanded"), "now aria-expanded should be true");
+								doh.is("setvaluetest_popup", combo._popupStateNode.getAttribute("aria-owns"), "should aria-own the popup");
+							
+								doh.is("listbox", combo.dropDown.domNode.getAttribute("role"), "dropDown.domNode should have a role");
+								doh.is("setvaluetest", combo.dropDown.domNode.getAttribute("aria-labelledby"), "aria-labelledby should point back to button");
+								doh.is("region", dojo.byId("widget_setvaluetest_dropdown").getAttribute("role"), "popup wrapper should have role=region since it gets appended to the end of the body");
+								doh.is("setvaluetest_popup", dojo.byId("widget_setvaluetest_dropdown").getAttribute("aria-label"), "popup wrapper should have aria-label since role=region");
+							}), 500);
+						});
+
+						combo.loadDropDown();
+						return d;
+					},
+					tearDown:function(){
+						combo.closeDropDown();
+					}
+				}
+			]);
+
+			doh.register("placeHolder", [
+				{
+					timeout: 2000,
+					name: "focus enpty",
+					combo: "placeholdertest",
+					setUp: function(){
+						dojo.byId('native').focus(); // blur combo so onfocus fires
+						combo = dijit.byId(this.combo);
+					},
+					runTest: function(){
+						var d = new doh.Deferred();
+						doh.is("", combo.get("value"), "value");
+						doh.is("", combo.get('displayedValue'), "displayedValue");
+						doh.is("Select a New England State", combo._phspan.innerHTML, "_phspan.innerHTML");
+						doh.isNot("none", combo._phspan.style.display, "_phspan.style.display 1");
+
+						var handler = dojo.connect(combo.textbox, "onfocus", function(){
+							dojo.disconnect(handler);
+							setTimeout(d.getTestCallback(function(){
+								doh.isNot("none", combo._phspan.style.display, "_phspan.style.display 2");
+							}), 0);
+						});
+						combo.focus();
+						return d;
+					}
+				},
+				{
+					timeout: 2000,
+					name: "blur empty",
+					runTest: function(){
+						var d = new doh.Deferred();
+						var handler = dojo.connect(dojo.byId('native'), "onfocus", function(){
+							dojo.disconnect(handler);
+							setTimeout(d.getTestCallback(function(){
+								doh.is("", combo.get("value"), "value");
+								doh.is("", combo.get('displayedValue'), "displayedValue");
+								doh.isNot("none", combo._phspan.style.display, "_phspan.style.display");
+							}), 0);
+						});
+						dojo.byId('native').focus(); // blur combo
+						return d;
+					}
+				},
+				{
+					timeout: 2000,
+					name: "focus non enpty",
+					combo: "placeholdertest",
+					setUp: function(){
+						dojo.byId('native').focus(); // blur combo so onfocus fires
+						combo = dijit.byId(this.combo);
+					},
+					runTest: function(){
+						var d = new doh.Deferred();
+						var value = isComboBox? 'Connecticut' : 'ct';
+						combo.set("value", value);
+						doh.is(value, combo.get("value"), "value");
+						doh.is("none", combo._phspan.style.display, "_phspan.style.display 1");
+
+						var handler = dojo.connect(combo.textbox, "onfocus", function(){
+							dojo.disconnect(handler);
+							setTimeout(d.getTestCallback(function(){
+								doh.is("none", combo._phspan.style.display, "_phspan.style.display 2");
+							}), 0);
+						});
+						combo.focus();
+						return d;
+					}
+				},
+				{
+					timeout: 2000,
+					name: "blur non empty",
+					runTest: function(){
+						var d = new doh.Deferred();
+						var value = isComboBox? 'Connecticut' : 'ct';
+						var handler = dojo.connect(dojo.byId('native'), "onfocus", function(){
+							dojo.disconnect(handler);
+							setTimeout(d.getTestCallback(function(){
+								doh.is(value, combo.get("value"), "value");
+								doh.is("none", combo._phspan.style.display, "_phspan.style.display");
+								doh.is('Connecticut', combo.textbox.value, "textbox.value");
+							}), 0);
+						});
+						dojo.byId('native').focus(); // blur combo
+						return d;
+					}
+				},
+				{
+					timeout: 2000,
+					name: "re-empty",
+					runTest: function(){
+						var d = new doh.Deferred();
+						var handler = dojo.connect(combo, "onChange", function(){
+							dojo.disconnect(handler);
+							setTimeout(d.getTestCallback(function(){
+								doh.is("", combo.get("value"), "value");
+								doh.is("", combo.get("displayedValue"), "displayedValue");
+								doh.isNot("none", combo._phspan.style.display, "_phspan.style.display");
+							}), 0);
+						});
+						combo.set("value", '');
+						return d;
+					}
+				}
+			]);
+
+			doh.register("asynchronous data store", [
+				{
+					timeout:5000,
+					name:"total",
+					runTest: function(){
+						var d = new doh.Deferred();
+						var combo = dijit.byId("slow");
+						var handler = dojo.connect(combo, "onSearch", function(results, query, options){
+							dojo.disconnect(handler);
+							d.getTestCallback(function(){
+								doh.is(30, options.start, "start");
+								doh.is(4, results.length, "count");
+								doh.is(61, results.total, "total");
+							})();
+						});
+						combo._set('fetchProperties', { start:30, count:4 });
+						combo._startSearch("");
+						return d;
+					},
+					tearDown:function(){
+						dijit.byId("slow").closeDropDown();
+					}
+				}
+			]);
+
+			doh.run();
 		}
 		dojo.ready(init);
 
@@ -124,7 +346,7 @@
 	</script>
 </head>
 
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle" id="title"></h1>
 	<script>dojo.byId('title').appendChild(document.createTextNode(testWidget+" Unit Test"))</script>
@@ -142,7 +364,7 @@
 		<hr>
 
 		<p>Option tags, autoComplete=false, selectOnClick=true, default value of California, pageSize=30, custom labelFunc method</p>
-		<label for="setvaluetest">US State test 1 (200% Courier font):</label>
+		<label id="setvaluetest_mylabel" for="setvaluetest">US State test 1 (200% Courier font):</label>
 		<script type="text/javascript">
 			function setValueTestOnChange(newValue){
 				if(this.lastlabelFuncMsg){
@@ -250,10 +472,10 @@
 			<option value="WI">Wisconsin</option>
 			<option value="WY">Wyoming</option>
 		</select>
-		<br>onChange:<input id="oc1" disabled value="not fired yet!" autocomplete="off"/>
-		<br>value:<input id="v1" disabled value="not fired yet!" autocomplete="off"/>
-		<br>blur:<input id="b1" disabled value="not fired yet!" autocomplete="off"/>
-		<br>this.item:<input id="i1" disabled value="no onChange yet!" autocomplete="off"/>
+		<br><label for="oc1">onChange:</label><input id="oc1" disabled value="not fired yet!" autocomplete="off"/>
+		<br><label for="v1">value:</label><input id="v1" disabled value="not fired yet!" autocomplete="off"/>
+		<br><label for="b1">blur:</label><input id="b1" disabled value="not fired yet!" autocomplete="off"/>
+		<br><label for="i1">this.item:</label><input id="i1" disabled value="no onChange yet!" autocomplete="off"/>
 		<input type="button" id="sv1_1" value="Set displayed value to Kentucky" onClick="dijit.byId('setvaluetest').set('displayedValue', 'Kentucky')"/>
 	        <input type="button" id="sv1_2" value="Set displayed value to Canada" onClick="dijit.byId('setvaluetest').set('displayedValue', 'Canada')"/>
 	        <input type="button" id="sv1_3" value="Set value to null" onClick="dijit.byId('setvaluetest').set('value', null)"/>
@@ -261,10 +483,10 @@
 
 		<hr>
 
-		<div data-dojo-id="stateStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"../_data/states.json"'></div>
-		<div data-dojo-id="slowStateStore" data-dojo-type="dijit.tests._data.SlowStore" data-dojo-props='url:"../_data/states.json"'></div>
+		<div data-dojo-id="stateStore" data-dojo-type="dojo/data/ItemFileReadStore" data-dojo-props='url:"../_data/states.json"'></div>
+		<div data-dojo-id="slowStateStore" data-dojo-type="dijit/tests/_data/SlowStore" data-dojo-props='url:"../_data/states.json"'></div>
 
-		<div data-dojo-id="dijitStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"../_data/dijits.json"'></div>
+		<div data-dojo-id="dijitStore" data-dojo-type="dojo/data/ItemFileReadStore" data-dojo-props='url:"../_data/dijits.json"'></div>
 
 		<p>Data store, autoComplete=true:</p>
 		<label for="datatest">US State test 2 (8pt font):</label>
@@ -276,7 +498,7 @@
 				name:"state2",
 				onChange:setVal2
 				'/>
-		<br>onChange:<input id="value2" disabled value="not fired yet!" autocomplete="off"/>
+		<br><label for="value2">onChange:</label><input id="value2" disabled value="not fired yet!" autocomplete="off"/>
 		<hr>
 		<p>Artificially slowed-down data store, autoComplete=true:</p>
 		<label for="slow">US State test slow:</label>
@@ -287,7 +509,7 @@
 				name:"stateSlow",
 				onChange:function(val){ dojo.byId("ocSlow").value = val; }
 				'/>
-		<br>onChange:<input id="ocSlow" disabled value="not fired yet!" autocomplete="off"/>
+		<br><label for="ocSlow">onChange:</label><input id="ocSlow" disabled value="not fired yet!" autocomplete="off"/>
 		<button id="slowDestroy" type="button" onclick="dijit.byId('slow').destroy();return false">Destroy widget to test in-flight query cancel</button>
 		<hr>
 
@@ -314,7 +536,7 @@
 				onChange:setVal3,
 				disabled:true
 		'/>
-		<br>onChange:<input id="value3" disabled value="not fired yet!" autocomplete="off"/>
+		<br><label for="value3">onChange:</label><input id="value3" disabled value="not fired yet!" autocomplete="off"/>
 		<div>
 			<button id="combo3_disable" type="button" onclick='toggleDisabled("combo3_disable", "combo3"); return false;' tabIndex="-1">Enable</button>
 		</div>
@@ -332,7 +554,7 @@
 				required:true,
 				highlightMatch:"none"
 		'/>
-		<br>onChange:<input id="value4" disabled value="not fired yet!" autocomplete="off"/>
+		<br><label for="value4">onChange:</label><input id="value4" disabled value="not fired yet!" autocomplete="off"/>
 		<hr>
 		<p>test that title used as label is preserved on input</p>
 		<select id="preservetitletest" data-dojo-type="$testWidget"
@@ -351,6 +573,7 @@
 		</select>
 		<hr>
 		<p>No arrow, data store which searches and highlights matches anywhere in the string</p>
+		<label for="arrowless">Arrowless:</label>
 	 	<input id="arrowless" data-dojo-type="$testWidget"
 				data-dojo-props='value: (testWidget == "dijit.form.ComboBox") ? "California" : "CA",
 				store:stateStore,
@@ -363,15 +586,19 @@
 		'/>
 		<hr>
 		<p>Created programmatically</p>
+		<label for="progCombo">progCombo:</label>
 		<input id="progCombo"/>
 		<hr>
 		<p>Created programmatically with an initial query.  (Limits list to items with type = country.)</p>
+		<label for="progCombo2">progCombo2</label>
 		<input id="progCombo2"/>
 		<hr>
 		<p>Created programmatically with an ItemFileReadStore and a descending sort.  (Limits list to items with type = country.)</p>
+		<label for="progCombo3">progCombo3:</label>
 		<input id="progCombo3"/>
 		<hr>
 		<p>With option tags, autoComplete=true, pageSize=30, and a descending sort.</p>
+		<label for="descending">descending:</label>
 		<select id="descending" data-dojo-type="$testWidget"
 				data-dojo-props='name:"descending",
 				style:{width:"50%",fontSize:"200%",fontFamily:"Courier"},
@@ -446,7 +673,7 @@
 		<p>The drop down list should be:</p>
 		<ul>
 		   <li>sticks & stones</li>
-		   <li>rags --> riches</li>
+		   <li>rags --> riches to</li>
 		   <li>more\less</li>
 		   <li>3 * 5</li>
 		</ul>
@@ -455,13 +682,15 @@
 			data-dojo-props='name:"specialchars"
 			'>
 			<option value="sticks" selected>sticks & stones</option>
-			<option value="rags">rags --> riches</option>
+			<option value="rags">rags --> riches to</option>
 			<option value="more">more\less</option>
 			<option value="times">3 * 5</option>
 		</select>
 		<hr>
 		<p>Japanese</p>
-		<p>Try typing &#x6771;&#x533A; (East), &#x897F;&#x533A; (West), &#x5317;&#x533A; (North), &#x5357;&#x533A; (South) and a few choices will pop up.</p>
+		<p>Try typing &#x6771;&#x533A; (East), &#x897F;&#x533A; (West), &#x5317;&#x533A; (North), &#x5357;&#x533A; (South) and a few choices will pop up.<br>
+		Using the Microsoft IME for Japanese (Hiragana), &#x6771; can be inputed by typing higashi followed by SPACE.
+		</p>
 		<label for="japanese">Japanese list:</label>
 		<select id="japanese" data-dojo-type="$testWidget" data-dojo-props='name:"japanese", style:{width:"300px"}, autoComplete:true, required:true, value:""'>
 			<option value="nanboku">&#x5357;&#x5317; (Nanboku)</option>
@@ -514,7 +743,7 @@
 	</form>
 	
 	<hr>
-	<p>test placeholder</p>
+	<p><label for="placeholdertest">test placeholder</label></p>
 	<select id="placeholdertest" data-dojo-type="$testWidget"
 			data-dojo-props='name:"placetest",
 			style:{width:"50%",fontFamily:"Courier"},
@@ -530,18 +759,18 @@
 		<option value="nh">New Hampshire</option>
 		<option value="vt">Vermont</option>
 	</select>
-	<p>
+	<p id="nativeLabel">
 	This is some text below the boxes. It shouldn't get pushed out of the way when search results get returned.
 	A native select tag to test IE bleed through problem:
 	</p>
 
-	<select id="native">
+	<select id="native" aria-labelledby="nativeLabel">
 	  <option>test for</option>
 	  <option>IE bleed through</option>
 	  <option>problem</option>
 	</select>
 	
-	Destroy test:<div id="destroyDiv"
+	<label for="combo_01">Destroy test:</label><div id="destroyDiv"
 		><select id="combo_01" data-dojo-type="$testWidget" 
 				data-dojo-props='name:"state", 
 				disabled:true,
@@ -559,19 +788,21 @@
 
 	<br>
 	<fieldset style="position:relative;border:1px solid black;display:inline;">
-		<span style="position:absolute;">Highlight test</span>
+		<legend>Highlight test</legend>
 		<div style="border:0;margin:1.5em;">
 			<span style='white-space:nowrap;'>
-			ignoreCase:<select onchange="dijit.byId('highlight').set('ignoreCase', this.value=='true')">
+			<label for="ignoreCase">ignoreCase:</label><select id="ignoreCase" onchange="dijit.byId('highlight').set('ignoreCase', this.value=='true')">
 				<option value="true" selected>true</option>
 				<option value="false">false</option>
 			</select>
-			highlightMatch:<select onchange="dijit.byId('highlight').set('highlightMatch', this.value)">
+			<label for="highlightMatch">highlightMatch:</label>
+			<select id="highlightMatch" onchange="dijit.byId('highlight').set('highlightMatch', this.value)">
 				<option value="first" selected>first</option>
 				<option value="all">all</option>
 				<option value="none">none</option>
 			</select>
-			queryExpr:<select onchange="dijit.byId('highlight').set('queryExpr', this.value)">
+			<label for="queryExpr">queryExpr:</label>
+			<select id="queryExpr" onchange="dijit.byId('highlight').set('queryExpr', this.value)">
 				<option value="${0}*" selected>${0}*</option>
 				<option value="*${0}*">*${0}*</option>
 				<option value="*${0}">*${0}</option>
@@ -579,7 +810,8 @@
 			</span>
 			<br>
 			<span style='white-space:nowrap;'>
-			Highlight test:<select id="highlight" data-dojo-type="$testWidget"
+			<label for="highlight">Highlight test:</label>
+			<select id="highlight" data-dojo-type="$testWidget"
 					data-dojo-props='ignoreCase:true,
 					highlightMatch:"first",
 					autoComplete:false,
@@ -597,5 +829,9 @@
 	</fieldset>
 
 	<div id="debugbox"></div>
+
+	<p><label for="subclass">User-defined subclass of ComboBox/FilteringSelect:</label></p>
+	<input id="subclass" data-dojo-type="StateSelect"/>
+
 </body>
 </html>
diff --git a/dijit/tests/form/mobile.html b/dijit/tests/form/mobile.html
index 55092d5..4b42e6f 100644
--- a/dijit/tests/form/mobile.html
+++ b/dijit/tests/form/mobile.html
@@ -1,6 +1,7 @@
 <!DOCTYPE>
-<html>
+<html lang="en">
 	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 		<meta name="apple-mobile-web-app-capable" content="yes" />
 		<title>Form widgets mobile test page</title>
@@ -11,8 +12,6 @@
 
 		<script language="JavaScript" type="text/javascript">
 			require([
-				"dojo/_base/kernel",
-				"dijit",
 				"dojo/parser",
 
 				"dijit/form/Button",
@@ -32,39 +31,40 @@
 
 				"dijit/form/FilteringSelect",
 				"dijit/form/Select",
+				"dijit/form/MultiSelect",
 
 				"dijit/form/HorizontalSlider",
 				"dijit/form/HorizontalRule",
 				"dijit/form/HorizontalRuleLabels",
 				"dojo/domReady!"
-			], function(dojo, dijit){
-				dojo.parser.parse();
+			], function(parser){
+				parser.parse();
 			});
 		</script>
 	</head>
-	<body class="claro">
+	<body class="claro" role="main">
 		<h1>Buttons</h1>
-		<button data-dojo-type="dijit.form.Button" id="T1465" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon", value:"Create"'>
+		<button data-dojo-type="dijit/form/Button" id="T1465" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon", value:"Create"'>
 			Button
 		</button>
-		<button id="SubmitDropDown" data-dojo-type="dijit.form.DropDownButton" name="DropDown" type="submit" value="DropDown Submit"
+		<button id="SubmitDropDown" data-dojo-type="dijit/form/DropDownButton" name="DropDown" type="submit" value="DropDown Submit"
 				data-dojo-props="label: 'DropDown Submit'">
 			DropDownButton
-			<span data-dojo-type="dijit.DropDownMenu">
-				<span id="SubmitDropDownMenuItem" data-dojo-type="dijit.MenuItem">DropDown MenuItem</span>
+			<span data-dojo-type="dijit/DropDownMenu">
+				<span id="SubmitDropDownMenuItem" data-dojo-type="dijit/MenuItem">DropDown MenuItem</span>
 			</span>
 		</button>
-		<button id="comboCreate" title="creative title" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save") },
+		<button id="comboCreate" title="creative title" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save") },
 				iconClass:"plusIcon"'>
 			<span>ComboButton</span>
-			<span id="createMenu" data-dojo-type="dijit.DropDownMenu">
-				<span data-dojo-type="dijit.MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+			<span id="createMenu" data-dojo-type="dijit/DropDownMenu">
+				<span data-dojo-type="dijit/MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
 					onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Create blank</span>
-				<span data-dojo-type="dijit.MenuItem"
+				<span data-dojo-type="dijit/MenuItem"
 					data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Create from template</span>
 			</span>
 		</button>
-		<button id="toggle2" data-dojo-type="dijit.form.ToggleButton"
+		<button id="toggle2" data-dojo-type="dijit/form/ToggleButton"
 			data-dojo-props='onChange:function(val){ console.log("toggled button checked="+val); }, iconClass:"dijitRadioIcon"'>
 			Toggle me
 		</button>
@@ -72,22 +72,26 @@
 		<h1>CheckBox, RadioButton</h1>
 		<fieldset>
 			<legend>check boxes</legend>
-			<label for="cb1">cb1</label>
-			<input id="cb1" data-dojo-id="cb1" data-dojo-type="dijit.form.CheckBox" data-dojo-props='name:"cb1", value:"foo", onClick:function(){ console.log("clicked cb1") }'/>
+			<label for="cb1">cb1:</label>
+			<input id="cb1" data-dojo-id="cb1" data-dojo-type="dijit/form/CheckBox"
+				   name="cb" value="foo" onClick="console.log('clicked cb1');"/>
 			<label for="cb2">cb2</label>
-			<input id="cb2" data-dojo-id="cb2" data-dojo-type="dijit.form.CheckBox" data-dojo-props='name:"cb2", value:"foo", onClick:function(){ console.log("clicked cb2") }'/>
+			<input id="cb2" data-dojo-id="cb2" data-dojo-type="dijit/form/CheckBox"
+				   name="cb" value="bar" onClick="console.log('clicked rb2');"/>
 		</fieldset>
 		<fieldset>
 			<legend>radio buttons</legend>
 			<label for="rb1">rb1</label>
-			<input id="rb1" data-dojo-id="rb1" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"rb1", value:"foo", onClick:function(){ console.log("clicked rb1") }'/>
+			<input id="rb1" data-dojo-id="rb1" data-dojo-type="dijit/form/RadioButton"
+				   name="rb" value="foo" onClick="console.log('clicked rb1');"/>
 			<label for="rb2">rb2</label>
-			<input id="rb2" data-dojo-id="rb2" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"rb2", value:"foo", onClick:function(){ console.log("clicked rb2") }'/>
+			<input id="rb2" data-dojo-id="rb2" data-dojo-type="dijit/form/RadioButton"
+				   name="rb" value="foo" onClick="console.log('clicked rb2');"/>
 		</fieldset>
 
 		<h1>TextBoxes</h1>
 		<label for="q03">NumberSpinner:</label>
-		<input id="q03" data-dojo-type="dijit.form.NumberSpinner"
+		<input id="q03" data-dojo-type="dijit/form/NumberSpinner"
 			name="age" tabIndex="1" class="small"
 			data-dojo-props='
 			promptMessage:"(optional) Enter an age between 0 and 120",
@@ -97,23 +101,23 @@
 			tooltipPosition:["above", "below"]
 		'/>
 		<label for="locald">Date:</label>
-		<input id="local" data-dojo-type="dijit.form.DateTextBox"
+		<input id="locald" data-dojo-type="dijit/form/DateTextBox"
 			name="date" value="2008-12-31" onChange="console.log(arguments[0]);"
 		/>
 		<label for="localt">Time:</label>
-		<input id="localt" data-dojo-type="dijit.form.TimeTextBox"
+		<input id="localt" data-dojo-type="dijit/form/TimeTextBox"
 			   name="time" value="T17:45:00" onChange="console.log(arguments[0]);"
 		/>
 
 		<h1>Selects</h1>
-		<select id="s" data-dojo-type="dijit.form.Select">
+		<select id="s" data-dojo-type="dijit/form/Select">
 			<option value="TN">Tennessee</option>
 			<option value="VA" selected="selected">Virginia</option>
 			<option value="WA">Washington</option>
 			<option value="FL">Florida</option>
 			<option value="CA">California</option>
 		</select>
-		<select id="fs" data-dojo-type="dijit.form.FilteringSelect">
+		<select id="fs" aria-label="fs" data-dojo-type="dijit/form/FilteringSelect">
 			<option value="AL">Alabama</option>
 			<option value="AK">Alaska</option>
 			<option value="AS">American Samoa</option>
@@ -176,9 +180,19 @@
 			<option value="WI">Wisconsin</option>
 			<option value="WY">Wyoming</option>
 		</select>
+		<select id="multiselect" multiple data-dojo-type="dijit/form/MultiSelect"
+				name="multiselect" style="height:100px; width:175px;">
+
+			<option value="TN" selected>Tennessee</option>
+			<option value="VA">Virginia</option>
+			<option value="WA">Washington</option>
+			<option value="FL">Florida</option>
+			<option value="CA">California</option>
+
+		</select>
 
 		<h1>HorizontalSlider</h1>
-		<div id="slider1" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props='name:"horizontal1",
+		<div id="slider1" data-dojo-type="dijit/form/HorizontalSlider" data-dojo-props='name:"horizontal1",
 			value:10,
 			maximum:100,
 			minimum:0,
@@ -188,10 +202,10 @@
 			slideDuration:500,
 			style:{width:"100%", height:"20px"}
 			'>
-				<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:{height:"1.2em",fontSize:"75%"}, count:6, numericMargin:1'></ol>
-				<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"topDecoration", count:6, style:{height:"5px"}'></div>
-				<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:{height:"5px"}'></div>
-				<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:{height:"1em",fontSize:"75%"}'>
+				<ol data-dojo-type="dijit/form/HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:{height:"1.2em",fontSize:"75%"}, count:6, numericMargin:1'></ol>
+				<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='container:"topDecoration", count:6, style:{height:"5px"}'></div>
+				<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:{height:"5px"}'></div>
+				<ol data-dojo-type="dijit/form/HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:{height:"1em",fontSize:"75%"}'>
 					<li>lowest</li>
 					<li>normal</li>
 					<li>highest</li>
diff --git a/dijit/tests/form/module.js b/dijit/tests/form/module.js
index ecdd953..8316f1a 100644
--- a/dijit/tests/form/module.js
+++ b/dijit/tests/form/module.js
@@ -1,73 +1,74 @@
-dojo.provide("dijit.tests.form.module");
+define(["doh/main", "require"], function(doh, require){
 
-try{
-	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
+	doh.register("form.Button", require.toUrl("./test_Button.html?mode=test"), 999999);
+	doh.register("form.ToggleButtonMixin", require.toUrl("./ToggleButtonMixin.html"));
+	doh.register("form.robot.Button_mouse", require.toUrl("./robot/Button_mouse.html"), 999999);
+	doh.register("form.robot.Button_a11y", require.toUrl("./robot/Button_a11y.html"), 999999);
 
-	doh.registerUrl("dijit.tests.form.ButtonMixin", dojo.moduleUrl("dijit","tests/form/AutoCompleterMixin.html"+userArgs));
-	doh.registerUrl("dijit.tests.form.ToggleButtonMixin", dojo.moduleUrl("dijit","tests/form/ToggleButtonMixin.html"+userArgs));
-	doh.registerUrl("dijit.tests.form.robot.Button_mouse", dojo.moduleUrl("dijit","tests/form/robot/Button_mouse.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.form.robot.Button_a11y", dojo.moduleUrl("dijit","tests/form/robot/Button_a11y.html"+userArgs), 999999);
-	
-	doh.registerUrl("dijit.tests.form.CheckBoxMixin", dojo.moduleUrl("dijit","tests/form/CheckBoxMixin.html"+userArgs));
-	doh.registerUrl("dijit.tests.form.RadioButtonMixin", dojo.moduleUrl("dijit","tests/form/RadioButtonMixin.html"+userArgs));
-	doh.registerUrl("dijit.tests.form.robot.CheckBox_mouse", dojo.moduleUrl("dijit","tests/form/robot/CheckBox_mouse.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.form.robot.CheckBox_a11y", dojo.moduleUrl("dijit","tests/form/robot/CheckBox_a11y.html"+userArgs), 999999);
+	doh.register("form.CheckBoxMixin", require.toUrl("./CheckBoxMixin.html"));
+	doh.register("form.CheckBox", require.toUrl("./CheckBox.html"));
+	doh.register("form.RadioButtonMixin", require.toUrl("./RadioButtonMixin.html"));
+	doh.register("form.robot.CheckBox_mouse", require.toUrl("./robot/CheckBox_mouse.html"), 999999);
+	doh.register("form.robot.CheckBox_a11y", require.toUrl("./robot/CheckBox_a11y.html"), 999999);
 
-	doh.registerUrl("dijit.tests.form.ButtonMixin", dojo.moduleUrl("dijit","tests/form/ButtonMixin.html"+userArgs));
-	doh.registerUrl("dijit.tests.form.test_validate", dojo.moduleUrl("dijit","tests/form/test_validate.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.form.robot.ValidationTextBox", dojo.moduleUrl("dijit","tests/form/robot/ValidationTextBox.html"+userArgs), 999999);
+	doh.register("form.ButtonMixin", require.toUrl("./ButtonMixin.html"));
+	doh.register("form.test_validate", require.toUrl("./test_validate.html?mode=test"), 999999);
+	doh.register("form.robot.ValidationTextBox", require.toUrl("./robot/ValidationTextBox.html"), 999999);
+	doh.register("form.robot.TextBox_onInput", require.toUrl("./robot/TextBox_onInput.html"), 999999);
 
-	doh.registerUrl("dijit.tests.form.DateTextBox", dojo.moduleUrl("dijit","tests/form/DateTextBox.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.form.robot.DateTextBox", dojo.moduleUrl("dijit","tests/form/robot/DateTextBox.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.form.robot.TimeTextBox", dojo.moduleUrl("dijit","tests/form/robot/TimeTextBox.html"+userArgs), 999999);
+	doh.register("form.DateTextBox", require.toUrl("./test_DateTextBox.html?mode=test"), 999999);
+	doh.register("form.robot.DateTextBox", require.toUrl("./robot/DateTextBox.html"), 999999);
+	doh.register("form.robot.TimeTextBox", require.toUrl("./robot/TimeTextBox.html"), 999999);
 
-	doh.registerUrl("dijit.tests.form.Form", dojo.moduleUrl("dijit", "tests/form/Form.html"), 999999);
-	doh.registerUrl("dijit.tests.form.robot.FormState", dojo.moduleUrl("dijit","tests/form/robot/Form_state.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.form.robot.Form_onsubmit", dojo.moduleUrl("dijit","tests/form/robot/Form_onsubmit.html"+userArgs), 999999);
+	doh.register("form.Form", require.toUrl("./Form.html"), 999999);
+	doh.register("form.robot.FormState", require.toUrl("./robot/Form_state.html"), 999999);
+	doh.register("form.robot.Form_onsubmit", require.toUrl("./robot/Form_onsubmit.html"), 999999);
 
-	doh.registerUrl("dijit.tests.form.Select", dojo.moduleUrl("dijit", "tests/form/test_Select.html?mode=test"), 999999);
-	doh.registerUrl("dijit.tests.form.robot.Select", dojo.moduleUrl("dijit", "tests/form/robot/Select.html"), 999999);
+	doh.register("form.Select", require.toUrl("./test_Select.html?mode=test"), 999999);
+	doh.register("form.robot.Select", require.toUrl("./robot/Select.html"), 999999);
 
-	doh.registerUrl("dijit.tests.form.AutoCompleterMixin", dojo.moduleUrl("dijit","tests/form/AutoCompleterMixin.html"+userArgs));
-	doh.registerUrl("dijit.tests.form.robot.ComboBox_mouse", dojo.moduleUrl("dijit","tests/form/robot/_autoComplete_mouse.html"+(userArgs+"&testWidget=dijit.form.ComboBox").replace(/^&/,"?")), 999999);
-	doh.registerUrl("dijit.tests.form.robot.ComboBox_a11y", dojo.moduleUrl("dijit","tests/form/robot/_autoComplete_a11y.html"+(userArgs+"&testWidget=dijit.form.ComboBox").replace(/^&/,"?")), 999999);
-	doh.registerUrl("dijit.tests.form.robot.FilteringSelect_mouse", dojo.moduleUrl("dijit","tests/form/robot/_autoComplete_mouse.html"+(userArgs+"&testWidget=dijit.form.FilteringSelect").replace(/^&/,"?")), 999999);
-	doh.registerUrl("dijit.tests.form.robot.FilteringSelect_a11y", dojo.moduleUrl("dijit","tests/form/robot/_autoComplete_a11y.html"+(userArgs+"&testWidget=dijit.form.FilteringSelect").replace(/^&/,"?")), 999999);
+	doh.register("form.AutoCompleterMixin", require.toUrl("./AutoCompleterMixin.html"));
+	doh.register("form.ComboBox", require.toUrl("./_autoComplete.html?testWidget=dijit.form.ComboBox&mode=test"), 999999);
+	doh.register("form.robot.ComboBox_mouse", require.toUrl("./robot/_autoComplete_mouse.html?testWidget=dijit.form.ComboBox"), 999999);
+	doh.register("form.robot.ComboBox_a11y", require.toUrl("./robot/_autoComplete_a11y.html?testWidget=dijit.form.ComboBox"), 999999);
+	doh.register("form.FilteringSelect", require.toUrl("./_autoComplete.html?testWidget=dijit.form.FilteringSelect&mode=test"), 999999);
+	doh.register("form.robot.FilteringSelect_mouse", require.toUrl("./robot/_autoComplete_mouse.html?testWidget=dijit.form.FilteringSelect"), 999999);
+	doh.register("form.robot.FilteringSelect_a11y", require.toUrl("./robot/_autoComplete_a11y.html?testWidget=dijit.form.FilteringSelect"), 999999);
 
-	doh.registerUrl("dijit.tests.form.robot.MultiSelect", dojo.moduleUrl("dijit","tests/form/robot/MultiSelect.html"+userArgs), 999999);
+	doh.register("form.MultiSelect", require.toUrl("./test_MultiSelect.html?mode=test"), 999999);
+	doh.register("form.robot.MultiSelect", require.toUrl("./robot/MultiSelect.html"), 999999);
 
-	doh.registerUrl("dijit.tests.form.robot.SimpleTextarea", dojo.moduleUrl("dijit","tests/form/robot/SimpleTextarea.html"+userArgs), 999999);
+	doh.register("form.robot.SimpleTextarea", require.toUrl("./robot/SimpleTextarea.html"), 999999);
 	
-	doh.registerUrl("dijit.tests.form.robot.Slider_mouse", dojo.moduleUrl("dijit","tests/form/robot/Slider_mouse.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.form.robot.Slider_a11y", dojo.moduleUrl("dijit","tests/form/robot/Slider_a11y.html"+userArgs), 999999);
-
-	doh.registerUrl("dijit.tests.form.robot.Spinner_mouse", dojo.moduleUrl("dijit","tests/form/robot/Spinner_mouse.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.form.robot.Spinner_a11y", dojo.moduleUrl("dijit","tests/form/robot/Spinner_a11y.html"+userArgs), 999999);
-
-	doh.registerUrl("dijit.tests.form.ExpandingTextAreaMixin", dojo.moduleUrl("dijit","tests/form/ExpandingTextAreaMixin.html"+userArgs));
-	doh.registerUrl("dijit.tests.form.robot.Textarea", dojo.moduleUrl("dijit","tests/form/robot/Textarea.html"+userArgs), 999999);
-
-	doh.registerUrl("dijit.tests.form.robot.validationMessages", dojo.moduleUrl("dijit","tests/form/robot/validationMessages.html"+userArgs), 999999);
-
-	doh.registerUrl("dijit.tests.form.verticalAlign", dojo.moduleUrl("dijit","tests/form/test_verticalAlign.html"+userArgs), 999999);
-
-	doh.registerUrl("dijit.tests.form.TextBox_types", dojo.moduleUrl("dijit","tests/form/TextBox_types.html"+userArgs), 999999);
-
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.tundra.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=tundra&dir=ltr"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.tundra.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=tundra&dir=rtl"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.tundra.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=tundra&dir=ltr"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.claro.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=claro&dir=ltr"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.claro.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=claro&dir=rtl"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.claro.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=claro&dir=ltr"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.soria.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=soria&dir=ltr"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.soria.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=soria&dir=rtl"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.soria.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=soria&dir=rtl"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.nihilo.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=nihilo&dir=ltr"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.nihilo.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=nihilo&dir=rtl"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.nihilo.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=nihilo&dir=rtl"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.a11y.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?a11y=1&dir=ltr"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.a11y.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?a11y=1&dir=rtl"), 999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.a11y.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&a11y=1&dir=ltr"), 999999);
-}catch(e){
-	doh.debug(e);
-}
+	doh.register("form.robot.Slider_mouse", require.toUrl("./robot/Slider_mouse.html"), 999999);
+	doh.register("form.robot.Slider_a11y", require.toUrl("./robot/Slider_a11y.html"), 999999);
+
+	doh.register("form.robot.Spinner_mouse", require.toUrl("./robot/Spinner_mouse.html"), 999999);
+	doh.register("form.robot.Spinner_a11y", require.toUrl("./robot/Spinner_a11y.html"), 999999);
+
+	doh.register("form.ExpandingTextAreaMixin", require.toUrl("./ExpandingTextAreaMixin.html"));
+	doh.register("form.robot.Textarea", require.toUrl("./robot/Textarea.html"), 999999);
+
+	doh.register("form.robot.validationMessages", require.toUrl("./robot/validationMessages.html"), 999999);
+
+	doh.register("form.verticalAlign", require.toUrl("./test_verticalAlign.html"), 999999);
+
+	doh.register("form.TextBox_types", require.toUrl("./TextBox_types.html"), 999999);
+
+	doh.register("form.TextBox_sizes.tundra.ltr", require.toUrl("./TextBox_sizes.html?theme=tundra&dir=ltr"), 999999);
+	doh.register("form.TextBox_sizes.tundra.rtl", require.toUrl("./TextBox_sizes.html?theme=tundra&dir=rtl"), 999999);
+	doh.register("form.TextBox_sizes.tundra.quirks", require.toUrl("../quirks.html?file=form/TextBox_sizes.html&theme=tundra&dir=ltr"), 999999);
+	doh.register("form.TextBox_sizes.claro.ltr", require.toUrl("./TextBox_sizes.html?theme=claro&dir=ltr"), 999999);
+	doh.register("form.TextBox_sizes.claro.rtl", require.toUrl("./TextBox_sizes.html?theme=claro&dir=rtl"), 999999);
+	doh.register("form.TextBox_sizes.claro.quirks", require.toUrl("../quirks.html?file=form/TextBox_sizes.html&theme=claro&dir=ltr"), 999999);
+	doh.register("form.TextBox_sizes.soria.ltr", require.toUrl("./TextBox_sizes.html?theme=soria&dir=ltr"), 999999);
+	doh.register("form.TextBox_sizes.soria.rtl", require.toUrl("./TextBox_sizes.html?theme=soria&dir=rtl"), 999999);
+	doh.register("form.TextBox_sizes.soria.quirks", require.toUrl("../quirks.html?file=form/TextBox_sizes.html&theme=soria&dir=rtl"), 999999);
+	doh.register("form.TextBox_sizes.nihilo.ltr", require.toUrl("./TextBox_sizes.html?theme=nihilo&dir=ltr"), 999999);
+	doh.register("form.TextBox_sizes.nihilo.rtl", require.toUrl("./TextBox_sizes.html?theme=nihilo&dir=rtl"), 999999);
+	doh.register("form.TextBox_sizes.nihilo.quirks", require.toUrl("../quirks.html?file=form/TextBox_sizes.html&theme=nihilo&dir=rtl"), 999999);
+	doh.register("form.TextBox_sizes.a11y.ltr", require.toUrl("./TextBox_sizes.html?a11y=1&dir=ltr"), 999999);
+	doh.register("form.TextBox_sizes.a11y.rtl", require.toUrl("./TextBox_sizes.html?a11y=1&dir=rtl"), 999999);
+	doh.register("form.TextBox_sizes.a11y.quirks", require.toUrl("../quirks.html?file=form/TextBox_sizes.html&a11y=1&dir=ltr"), 999999);
+
+});
diff --git a/dijit/tests/form/robot/Button_a11y.html b/dijit/tests/form/robot/Button_a11y.html
index 1c56b73..4cf67a0 100644
--- a/dijit/tests/form/robot/Button_a11y.html
+++ b/dijit/tests/form/robot/Button_a11y.html
@@ -11,17 +11,16 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
+			dojo.require("dojo.on");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_Button.html');
 
 				var submitCount = 0, resetCount = 0;
 
-
 				doh.register("setup", function(){
 					doh.robot.sequence(function(){
 						dojo.connect(dijit.byId("testForm"), "onSubmit", function(){
@@ -92,6 +91,10 @@
 				]);
 
 				doh.register("dijit.form.DropDownButton", [
+					function initialState(){
+						doh.f(dojo.hasClass(dijit.byId("edit").domNode, "dijitDropDownButtonOpened"),
+								"no dijitDropDownButtonOpened class");
+					},
 					{
 						name: "down arrow opens menu",
 						timeout: 4000,
@@ -102,6 +105,8 @@
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dojo.hasClass(dijit.byId("edit").domNode, "dijitDropDownButtonOpened"),
+										"dijitDropDownButtonOpened class");
 								doh.t(isVisible("editMenu"), "edit menu is visible: " + dijit.byId("editMenu").domNode.style.cssText);
 								doh.is("cut", dojo.global.dijit.focus.curNode.id, "focus is on menu");
 							}), 500);
@@ -120,6 +125,8 @@
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden("editMenu"), "edit menu is hidden: " + dijit.byId("editMenu").domNode.style.cssText);
 								doh.is("edit", dojo.global.dijit.focus.curNode.id, "focus is back on button");
+								doh.f(dojo.hasClass(dijit.byId("edit").domNode, "dijitDropDownButtonOpened"),
+										"no dijitDropDownButtonOpened class");
 							}), 1000);
 							return d;
 						}
@@ -216,12 +223,72 @@
 							}), 1000);
 							return d;
 						}
-					}
+					},
+					{
+						name: "aria role and attributes",
+						timeout: 2000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+							button = dijit.byId("dropdown_default");	//testing dropDownButton
+								
+							doh.is("button", button._popupStateNode.getAttribute("role"), "button._popupStateNode role");
+							doh.t(button._popupStateNode.getAttribute("aria-haspopup"), "button._popupStateNode aria-haspopup");
+							doh.is("dropdown_default_label", button._popupStateNode.getAttribute("aria-labelledby"), "aria-labelledby");
+							doh.f(button._popupStateNode.getAttribute("aria-expanded"), "dont expect initial aria-expanded");
+							doh.f(button._popupStateNode.getAttribute("aria-owns"), "initally missing aria-owns");
+							
+							// open the drop down, check that button now has aria-owns to the dropDown
+							button.focus();
+							doh.robot.keyPress(dojo.keys.ENTER, 1000, {});
 
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(button._popupStateNode.getAttribute("aria-expanded"), "now aria-expanded should be true");
+								doh.is("dijit_ColorPalette_0", button._popupStateNode.getAttribute("aria-owns"), "should aria-own the Dlg");
+								// Check roles and attributes on the popped out ColorPalette					
+								var popup = dijit.byId("dijit_ColorPalette_0");
+								doh.is("grid", popup.domNode.getAttribute("role"), "popup domNode role");
+								doh.is("dropdown_default", popup.domNode.getAttribute("aria-labelledby"), "aria-labelledby of popup should point to the button");
+							}), 500);
+							
+							return d;
+						},
+						tearDown: function(){
+						    dijit.byId("combo_default").focus();
+						}
+					}
 				]);
 
 				doh.register("dijit.form.ComboButton", [
 					{
+						name: "aria role and attributes",
+						timeout: 20000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+							button = dijit.byId("combo_default");
+															
+							doh.is("button", button._popupStateNode.getAttribute("role"), "button._popupStateNode role");
+							doh.t(button._popupStateNode.getAttribute("aria-haspopup"), "button._popupStateNode aria-haspopup");
+							doh.f(button._popupStateNode.getAttribute("aria-expanded"), "dont expect initial aria-expanded");
+							doh.f(button._popupStateNode.getAttribute("aria-owns"), "initally missing aria-owns");
+
+							button.focus();		//calling focus() on a ComboButton focuses the dropDownArrow node
+							doh.robot.keyPress(dojo.keys.ENTER, 2000, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(button._popupStateNode.getAttribute("aria-expanded"), "post click aria-expanded");
+								doh.is("dijit_Menu_0", button._popupStateNode.getAttribute("aria-owns"), "should aria-own the Menu");
+								var popup = dijit.byId("dijit_Menu_0");
+								doh.is("menu", popup.domNode.getAttribute("role"), "popup domNode role");		
+								doh.is("combo_default", popup.domNode.getAttribute("aria-labelledby"), "aria-labelledby of popup should point to the button");
+							}), 500);
+							
+							return d;
+						},
+						tearDown: function(){
+							dijit.byId("combo_default").focus();
+						}
+					},
+					{
 						name: "tab to button",
 						timeout: 4000,
 						runTest: function(){
@@ -236,7 +303,8 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.is(leftPart, dojo.global.dijit.focus.curNode, "focused on left part");
-								console.log("cur focus: ",  dojo.global.dijit.focus.curNode);
+								doh.f(dojo.hasClass(dijit.byId("save").domNode, "dijitComboButtonOpened"),
+										"no dijitComboButtonOpened class");
 							}), 1000);
 							return d;
 						}
@@ -255,6 +323,8 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(clicked, "button was clicked");
+								doh.f(dojo.hasClass(dijit.byId("save").domNode, "dijitComboButtonOpened"),
+										"no dijitComboButtonOpened class");
 							}), 1000);
 							return d;
 						}
@@ -273,6 +343,8 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.is(rightPart, dojo.global.dijit.focus.curNode, "focused on right part of combo");
+								doh.f(dojo.hasClass(dijit.byId("save").domNode, "dijitComboButtonOpened"),
+										"no dijitComboButtonOpened class");
 							}), 1000);
 							return d;
 						}
@@ -291,6 +363,8 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isVisible("saveMenu"), "save menu is visible: " + dijit.byId("saveMenu").domNode.style.cssText);
+								doh.t(dojo.hasClass(dijit.byId("save").domNode, "dijitComboButtonOpened"),
+										"dijitComboButtonOpened class");
 							}), 1000);
 							return d;
 						}
@@ -377,21 +451,22 @@
 						name: "uncheck",
 						timeout: 4000,
 						runTest: function(){
-							var d = new doh.Deferred();
-
-							var checked = dijit.byId("toggle1").get("checked");
+							var toggle1 = dijit.byId("toggle1");
+							var checked = toggle1.get("checked");
 							doh.t(checked, "toggle1 initially checked");
 							doh.is("true", dojo.byId('toggle1').getAttribute("aria-pressed"), "aria-pressed 1");
 
+							var d = new doh.Deferred();
+
 							var watchOld, watchNew;
-							dijit.byId("toggle1").set("onChange", function(v){ checked = v; });
-							dijit.byId("toggle1").watch("checked", function(name, o, n){
+							toggle1.set("onChange", function(v){ checked = v; });
+							toggle1.watch("checked", function(name, o, n){
 								watchOld = o;
 								watchNew = n;
 							});
 
-							dijit.byId("toggle1").focus();
-							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
+							toggle1.focus();
+							doh.robot.typeKeys(' ', 1000, 250);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.f(checked, "toggle1 unchecked");
@@ -406,21 +481,21 @@
 						name: "check",
 						timeout: 4000,
 						runTest: function(){
-							var d = new doh.Deferred();
-
-							var checked = dijit.byId("toggle1").get("checked");
+							var toggle1 = dijit.byId("toggle1");
+							var checked = toggle1.get("checked");
 							doh.f(checked, "toggle1 unchecked");
 							doh.is("false", dojo.byId('toggle1').getAttribute("aria-pressed"), "aria-pressed 1");
 
+							var d = new doh.Deferred();
+
 							var watchOld, watchNew;
-							dijit.byId("toggle1").set("onChange", function(v){ checked = v; });
-							dijit.byId("toggle1").watch("checked", function(name, o, n){
+							toggle1.set("onChange", function(v){ checked = v; });
+							toggle1.watch("checked", function(name, o, n){
 								watchOld = o;
 								watchNew = n;
 							});
 
-							dijit.byId("toggle1").focus();
-							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
+							doh.robot.typeKeys(' ', 500, 250);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(checked, "toggle1 checked");
@@ -496,6 +571,38 @@
 					}
 				});
 
+				doh.register("bubbling", [
+					{
+						name: "bubbling",
+						timeout: 5000,
+						runTest: function(){
+
+							var d = new doh.Deferred(),
+								wrapper = dojo.byId("bubbleContainer"),
+								buttonNode = dojo.byId("bubble2");
+
+							// Listen for click events on the outer DOMNode.
+							var clicks = 0;
+							dojo.on(wrapper, "click", function(){
+								clicks++;
+							});
+
+							// Keyboard-click the widget button
+							doh.robot.sequence(function(){
+								buttonNode.focus();
+							}, 500);
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+
+							// Check that one click event bubbled
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(1, clicks, "one click event bubbled");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/form/robot/Button_mouse.html b/dijit/tests/form/robot/Button_mouse.html
index a94526a..f764f07 100644
--- a/dijit/tests/form/robot/Button_mouse.html
+++ b/dijit/tests/form/robot/Button_mouse.html
@@ -11,10 +11,10 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
+			dojo.require("dojo.on");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_Button.html');
@@ -699,6 +699,33 @@
 					}
 				]);
 
+				doh.register("bubbling", [
+					{
+						name: "bubbling",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+								wrapper = dojo.byId("bubbleContainer");
+
+							// Listen for click events on the outer DOMNode.
+							var clicks = 0;
+							dojo.on(wrapper, "click", function(){
+								clicks++;
+							});
+
+							doh.robot.mouseMoveAt("bubble2", 500);
+							doh.robot.mouseClick({left:true}, 500);
+
+							// Check that one click event bubbled
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(1, clicks, "one click event bubbled");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/form/robot/CheckBox_a11y.html b/dijit/tests/form/robot/CheckBox_a11y.html
index af203a0..3d0ecdc 100644
--- a/dijit/tests/form/robot/CheckBox_a11y.html
+++ b/dijit/tests/form/robot/CheckBox_a11y.html
@@ -11,10 +11,9 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_CheckBox.html');
@@ -131,6 +130,38 @@
 
 				doh.register("Radio button a11y",[
 					{
+						name: "reset blank value",
+						runTest: function(){
+							doh.is("", dijit.byId('g1rb3').params.value, "blank parameter");
+							doh.is("", dijit.byId('g1rb3').value, "initially blank");
+							dijit.byId('g1rb3').reset();
+							doh.is("", dijit.byId('g1rb3').value, "blank after reset");
+						}
+					},
+					{
+						timeout: 5000,
+						name: "initial tab order",
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dojo.byId("enableWeatherButton").focus();
+							doh.robot.keyPress(dojo.keys.TAB, 500, {
+								shift: true
+							});
+							doh.robot.keyPress(dojo.keys.TAB, 500, {
+								shift: true
+							});
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.keyPress(dojo.keys.SPACE, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId('g1rb2').checked, "talk should have been checked");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
 						timeout:6000,
 						name:"weather enabled a11y",
 						runTest:function(){
@@ -153,8 +184,31 @@
 						}
 					},
 					{
+						timeout: 5000,
+						name: "changed tab order",
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dojo.byId("enableWeatherButton").focus();
+							doh.robot.keyPress(dojo.keys.TAB, 500, {
+								shift: true
+							});
+							doh.robot.keyPress(dojo.keys.TAB, 500, {
+								shift: true
+							});
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId('g1rb2').checked, "talk should have been checked");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
 						timeout:6000,
-						name:"change value to county a11y",
+						name:"change value to country a11y",
 						runTest:function(){
 							var d = new doh.Deferred();
  
@@ -342,29 +396,6 @@
 					}
 				]);
 
-				doh.register("CheckBox watch",
-					[
-						function w(){
-							var cb = dijit.byId('cb2');
-							cb.set("checked", true);
-
-							var oldWatch, newWatch;
-							cb.watch("checked", function(name, o, n){
-								oldWatch = o;
-								newWatch = n;
-							});
-
-							cb.set("checked", false);
-							doh.t(oldWatch, "old value was checked");
-							doh.f(newWatch, "new value is unchecked");
-
-							cb.set("checked", true);
-							doh.f(oldWatch, "old value was unchecked");
-							doh.t(newWatch, "new value is checked");
-						}
-					]
-				);
-
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/form/robot/CheckBox_mouse.html b/dijit/tests/form/robot/CheckBox_mouse.html
index 144a791..d7cea1c 100644
--- a/dijit/tests/form/robot/CheckBox_mouse.html
+++ b/dijit/tests/form/robot/CheckBox_mouse.html
@@ -11,11 +11,9 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
-			dojo.require("dijit.form.CheckBox");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			// These are the values assigned to the widgets in the page's HTML
 			var originalGet = {
@@ -25,7 +23,7 @@
 				cb5: [],
 				cb6: ["on"],
 				cb7: [],
-				'g[1]': "talk",
+				'g[1]': "on",
 				g2: null
 			};
 
@@ -33,7 +31,7 @@
 				cb2: "on",
 				cb4: "on",
 				cb6: "on",
-				'g[1]': "talk"
+				'g[1]': "on"
 			};
 
 			// attempt to change these values
@@ -44,7 +42,7 @@
 				cb4: [],
 				cb5: ["on"],
 				cb6: ["foo"],
-				'g[1]': "weather",
+				'g[1]': "", // weather
 				g2: "country"
 			};
 
@@ -69,28 +67,6 @@
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_CheckBox.html');
 
-				// should be able to query for all of the inputs, including hidden ones
-				doh.register("query input by checked state", [
-					{
-						name: "query checked",
-						runTest: function(){
-							var queried=dojo.query("input[checked]", dojo.byId('myForm'));
-							doh.is(5,queried.length,"expected: 5 checked widgets, got: "+queried.length);
-						}
-					}
-				]);
-
-				doh.register("query input by name", [
-					{
-						name: "query name",
-						runTest: function(){
-							var queried=dojo.query("input[name]", dojo.byId('myForm'));
-							doh.is(13,queried.length,"expected: 13 named widgets, got: "+queried.length);
-						}
-					}
-				]);
-
-				var formWidget = dijit.byId("myForm");
 
 				var submitForm = function(name, testValues){
 					return {
@@ -98,6 +74,7 @@
 						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred();
+							var formWidget = dijit.byId("myForm");
 							submittedValues = function(formValues){
 								d.getTestCallback(function(){
 									for(var i in originalGet){ doh.is(testValues[i], formValues[i], i); }
@@ -113,41 +90,6 @@
 				};
 
 				doh.register("CheckBox values", [
-					function getValues(){
-						doh.is( dojo.toJson(originalGet), dojo.global.dojo.toJson(dijit.byId("myForm").get('value')) );
-					},
-					{
-						timeout:3000,
-						name:"setValues",
-						runTest:function(){
-							var d = new doh.Deferred();
-
-							doh.robot.sequence(function(){ submitForm("original submit", originalSubmit); }, 500); 
-							doh.robot.sequence(function(){ dijit.byId("myForm").set('value', change); }, 500); 
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is( dojo.toJson(changedGet), dojo.global.dojo.toJson(dijit.byId("myForm").get('value')) );
-							}), 1000);
-
-							return d;
-						}
-					},
-					{
-						timeout:3000,
-						name:"resetValues",
-						runTest:function(){
-							var d = new doh.Deferred();
-
-							doh.robot.sequence(function(){ submitForm("changed submit", changedSubmit); }, 500); 
-							doh.robot.sequence(function(){ dijit.byId("myForm").reset(); }, 500); 
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is( dojo.toJson(originalGet), dojo.global.dojo.toJson(dijit.byId("myForm").get('value')), "reset to original values" );
-							}), 1000);
-
-							return d;
-						}
-					},
 					{
 						timeout:3000,
 						name:"readOnly",
@@ -168,32 +110,6 @@
 					}
 				]);
 
-				doh.register("CheckBox onChange",
-					[
-						function fireOnChange(){
-							var d = new doh.Deferred();
-							var cb = dijit.byId('cb2');
-							var lastOnChange = dojo.byId('oncheckedoutput').innerHTML;
-							cb.set('checked', !cb.get('checked'));
-							setTimeout(d.getTestCallback(function(){
-								doh.isNot(lastOnChange, dojo.byId('oncheckedoutput').innerHTML);
-							}), 500);
-							return d;
-						},
-
-						function skipOnChange(){
-							var d = new doh.Deferred();
-							var cb = dijit.byId('cb2');
-							var lastOnChange = dojo.byId('oncheckedoutput').innerHTML;
-							cb.set('checked', !cb.get('checked'), false);
-							setTimeout(d.getTestCallback(function(){
-								doh.is(lastOnChange, dojo.byId('oncheckedoutput').innerHTML);
-							}), 500);
-							return d;
-						}
-					]
-				);
-				
 				doh.register("Radio button onChange",[
 					function checkInitialValues(){
 						doh.f(dijit.byId('g1rb1').checked, "news was checked");
diff --git a/dijit/tests/form/robot/DateTextBox.html b/dijit/tests/form/robot/DateTextBox.html
index f6dcd26..574cf9c 100644
--- a/dijit/tests/form/robot/DateTextBox.html
+++ b/dijit/tests/form/robot/DateTextBox.html
@@ -11,17 +11,17 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
-		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 			dojo.require("dojo.date");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_DateTextBox.html');
 
 				// refs to DateTextBox widgets
-				var american, german, localLong;
+				var american, german, localLong, pattern, handler;
 
 				// log of calls to onChange handler, and watch(value)
 				var changes = [], watches = [];
@@ -33,12 +33,12 @@
 				doh.register("setup",
 					function setUp(){
 						// refs to DateTextBox widgets
-				    	american = dijit.byId('american');
-				    	german = dijit.byId('german');
+				    		american = dijit.byId('american');
+				    		german = dijit.byId('german');
 						localLong = dijit.byId('localLong');
-				    	pattern = dijit.byId('pattern');
+				    		pattern = dijit.byId('pattern');
 
-				    	// setup onChange handler to monitor onChange calls on american textbox
+						// setup onChange handler to monitor onChange calls on american textbox
 						dojo.connect(american, 'onChange', function(val){
 							console.log('onchange w/value: ', val);
 							changes.push(val);
@@ -50,124 +50,6 @@
 				    }
 				);
 
-				doh.register("API", [
-					function initial(){
-						// initial conditions
-						doh.is(0, dojo.date.compare(new Date(2005,11,30), american.get('value')), 'wire value of american: ' + american.get('value'));
-						doh.is('12/30/2005', american.get('displayedValue'), 'displayed value of american');
-					},
-
-					function setValue(){
-						american.set('value', new Date(2004,9,20));
-						doh.is(0, dojo.date.compare(new Date(2004,9,20), american.get('value')),
-								'wire value of american is: ' + american.get('value') +
-								' but should be: ' + new Date(2004,9,20));
-						doh.is('10/20/2004', american.get('displayedValue'), 'displayed value of american');
-						doh.t(american.isValid(), 'marked as valid');
-					},
-
-					function setDisplayedValue(){
-						american.set('displayedValue', '11/12/2006');
-						doh.is(0, dojo.date.compare(new Date(2006, 10, 12), american.get('value')), 'wire value of american');
-						doh.is('11/12/2006', american.get('displayedValue'), 'displayed value of american');
-						doh.t(american.isValid(), 'marked as valid');
-					},
-
-					function setInvalidDisplayedValue(){
-						american.set('displayedValue', 'foo');
-						doh.t(american.get('value') === undefined, 'value is undefined if displayedValue is garbage');
-						doh.f(american.isValid(), 'marked as invalid');
-
-						// setting the value to get('value') should never change anything, so
-						// therefore setting the value to undefined shouldn't affect the displayed value
-						american.set('value', undefined);
-						doh.is(american.get('displayedValue'), 'foo');
-					},
-
-					function setOutOfRange(){
-						// This widget is set to be valid between 2004 and 2006 only
-						american.set('displayedValue', '12/1/2008');
-						doh.f(american.isValid(), 'marked as invalid since out of range');
-						doh.is('12/1/2008', american.get('displayedValue'), 'displayed value of american');
-					},
-
-					function noInitialValue(){
-				    		var fromDate = dijit.byId('fromDate');
-						doh.is('', fromDate.get('displayedValue'), 'initially blank');
-						doh.is(dijit.form.DateTextBox.prototype.value, fromDate.value, 'default value');
-						var d = new doh.Deferred();
-						var today = new Date();
-						fromDate.set('value', today, true);
-						doh.robot.sequence(d.getTestCallback(function(){
-				    			var toDate = dijit.byId('toDate');
-							doh.is(today.toDateString(), fromDate.value.toDateString(), 'changed value');
-							doh.is(today.toDateString(), toDate.constraints.min.toDateString(), 'onChange');
-						}), 500);
-						return d;
-					}
-				]);
-
-
-				doh.register("localization", [
-					function initialGerman(){
-						doh.is(0, dojo.date.compare(new Date(2006,10,29), german.get('value')), 'wire value of german: ' + german.get('value'));
-						doh.is('29.11.2006', german.get('displayedValue'), 'displayed value of german');
-					},
-
-					function setValueGerman(){
-						german.set('value', new Date(2004,9,20));
-						doh.is(0, dojo.date.compare(new Date(2004,9,20), german.get('value')),
-								'wire value of german is: ' + german.get('value') +
-								' but should be: ' + new Date(2004,9,20));
-						doh.is('20.10.2004', german.get('displayedValue'), 'displayed value of german');
-						doh.t(german.isValid(), 'marked as valid');
-					},
-
-					function setDisplayedValueGerman(){
-						german.set('displayedValue', '12.11.2006');
-						doh.is(0, dojo.date.compare(new Date(2006, 10, 12), german.get('value')), 'wire value of german');
-						doh.is('12.11.2006', german.get('displayedValue'), 'displayed value of german');
-						doh.t(german.isValid(), 'marked as valid');
-					},
-
-					{
-						name: "labels",
-						timeout: 6000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							german.set('value', new Date(2006, 9, 15));	// 10/15/2006
-
-							doh.robot.mouseMoveAt(german.domNode, 0, 1);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								var calendar = dijit.byId("german_popup");
-
-								// calendar exists and is shown
-								doh.t(calendar, "calendar popup exists");
-								doh.t(isVisible(calendar), "calendar is visible");
-
-								// Month label
-								doh.is("Oktober", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]));
-
-								// Day labels
-								var dayLabels = dojo.query(".dijitCalendarDayLabelTemplate", calendar.domNode);
-								doh.is(7, dayLabels.length, "7 day labels");
-								doh.is("M", innerText(dayLabels[0]), "day 0");
-								doh.is("D", innerText(dayLabels[1]), "day 1");
-								doh.is("M", innerText(dayLabels[2]), "day 2");
-								doh.is("D", innerText(dayLabels[3]), "day 3");
-								doh.is("F", innerText(dayLabels[4]), "day 4");
-								doh.is("S", innerText(dayLabels[5]), "day 5");
-								doh.is("S", innerText(dayLabels[6]), "day 6");
-							}), 1000);
-
-							return d;
-						}
-					}
-				]);
-
 				doh.register("keyboard: direct input", {
 					name: "direct input",
 					timeout: 6000,
@@ -175,18 +57,28 @@
 						// clear the field
 						changes = [];
 						watches = [];
-						american.set('value', null, false);
+						american.focus();
 					},
 					runTest: function(){
-						var d = new doh.Deferred();
-
-						doh.is(1, watches.length, 'one watch(value) event from the set("value")');
-
-						american.focus();
-
-						doh.robot.typeKeys('1/3/2005', 1000, 1600);
-						doh.robot.keyPress(dojo.keys.TAB, 500, {});
-						doh.robot.sequence(d.getTestCallback(function(){
+						var	d = new doh.Deferred(),
+							r1 = true,
+							r2 = true,
+							r3 = true,
+							r4 = true,
+							r5 = true,
+							r6 = false,
+							r7 = false,
+							r8 = true;
+
+						handler = dojo.connect(american, 'onChange', d.getTestCallback(function(){
+							doh.f(r1, "1 out of range");
+							doh.f(r2, "1/ out of range");
+							doh.f(r3, "1/3 out of range");
+							doh.f(r4, "1/3/ out of range");
+							doh.f(r5, "1/3/2 out of range");
+							doh.t(r6, "1/3/20 in range");
+							doh.t(r7, "1/3/200 in range");
+							doh.f(r8, "1/3/2005 out of range");
 							var value = american.get('value');
 							doh.is(0, dojo.date.compare(new Date(2005, 0, 3), value), 'actual value is ' + value);
 							doh.is(1, changes.length, 'one onchange event');	// #9018
@@ -197,59 +89,105 @@
 							doh.is(0, dojo.date.compare(new Date(2005, 0, 3), watches[1]),
 									'value reported by watch(value): ' + watches[1] +
 									', should be ' + new Date(2005, 0, 3));
-						}), 1000);
+						}));
+
+						american.set('value', null, false);
+
+						doh.robot.typeKeys('1', 1000, 200);
+						doh.robot.sequence(function(){
+							r1 = american._isDefinitelyOutOfRange();
+						}, 100);
+						doh.robot.typeKeys('/', 100, 200);
+						doh.robot.sequence(function(){
+							r2 = american._isDefinitelyOutOfRange();
+						}, 100);
+						doh.robot.typeKeys('3', 100, 200);
+						doh.robot.sequence(function(){
+							r3 = american._isDefinitelyOutOfRange();
+						}, 100);
+						doh.robot.typeKeys('/', 100, 200);
+						doh.robot.sequence(function(){
+							r4 = american._isDefinitelyOutOfRange();
+						}, 100);
+						doh.robot.typeKeys('2', 100, 200);
+						doh.robot.sequence(function(){
+							r5 = american._isDefinitelyOutOfRange();
+						}, 100);
+						doh.robot.typeKeys('0', 100, 200);
+						doh.robot.sequence(function(){
+							r6 = american._isDefinitelyOutOfRange();
+						}, 100);
+						doh.robot.typeKeys('0', 100, 200);
+						doh.robot.sequence(function(){
+							r7 = american._isDefinitelyOutOfRange();
+						}, 100);
+						doh.robot.typeKeys('5', 100, 200);
+						doh.robot.sequence(function(){
+							r8 = american._isDefinitelyOutOfRange();
+						}, 100);
+
+						doh.robot.keyPress(dojo.keys.TAB, 500, {}); // focus german
+
 						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(handler);
 					}
 				});
 
 				doh.register("keyboard: drop down", [
-					function setUp(){
-						// set to may 10
-						changes = [];
-						american.set('displayedValue', "", false);
-						watches = [];	// put after set() so we can ignore the watch() published by set()
-					},
-
 					{
 						name: "initial popup display",
 						timeout: 6000,
+						setUp: function(){
+							// set to may 10
+							changes = [];
+							american.set('displayedValue', "", false);
+							watches = [];	// put after set() so we can ignore the watch() published by set()
+							american.focus();
+						},
 						runTest: function(){
 							var d = new doh.Deferred(),
 								calendar;
 
-							american.focus();
+							handler = dojo.connect(american, 'openDropDown', function(){
+								dojo.disconnect(handler);
+								calendar = dijit.byId("american_popup");
+								handler = dojo.connect(calendar, 'focus', function(){
+									// Use setTimeout() because focus on IE9+ is asynchronous.
+									setTimeout(d.getTestCallback(function(){
+										// calendar exists and is shown
+										doh.t(calendar && isVisible(calendar), "calendar is visible");
+
+										// calendar is on the right month
+										doh.is("May", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "calendar starts on month selected in input box");
+
+										// and the right year
+										var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
+										doh.is(1, selectedYearButtons.length, "current year is shown");
+										doh.is("2005", innerText(selectedYearButtons[0]), "current year is 2005");
+
+										// and the currently selected date is right too
+										var selectedDays = dojo.query(".dijitCalendarSelectedDate", calendar.domNode);
+										doh.is(1, selectedDays.length, "one day selected");
+										doh.is("10", innerText(selectedDays[0]), "correct day is selected");
+
+										// focus moved to the calendar
+										doh.is(10, innerText(dojo.global.dijit.focus.curNode), "focus on selected calendar cell");
+
+										doh.is(0, changes.length, "no onchange events yet");
+										doh.is(0, watches.length, "no watch(value) events yet");
+									}), 0);
+								});
+							});
 
 							doh.robot.typeKeys("5/10/2005", 1000, 1800);
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 700, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								calendar = dijit.byId("american_popup");
-
-								// calendar exists and is shown
-								doh.t(calendar, "calendar popup exists");
-								doh.t(isVisible(calendar), "calendar is visible");
-
-								// calendar is on the right month
-								doh.is("May", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "calendar starts on month selected in input box");
-
-								// and the right year
-								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
-								doh.is(1, selectedYearButtons.length, "current year is shown");
-								doh.is("2005", innerText(selectedYearButtons[0]), "current year is 2005");
-
-								// and the currently selected date is right too
-								var selectedDays = dojo.query(".dijitCalendarSelectedDate", calendar.domNode);
-								doh.is(1, selectedDays.length, "one day selected");
-								doh.is("10", innerText(selectedDays[0]), "correct day is selected");
-
-								// focus moved to the calendar
-								doh.is(10, innerText(dojo.global.dijit.focus.curNode), "focus on selected calendar cell");
-
-								doh.is(0, changes.length, "no onchange events yet");
-								doh.is(0, watches.length, "no watch(value) events yet");
-							}), 1000);
-
 							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handler);
 						}
 					},
 
@@ -578,14 +516,18 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-
-							doh.robot.sequence(d.getTestCallback(function(){
+							handler = dojo.connect(american, '_onFocus', d.getTestCallback(function(){
 								doh.is(1, changes.length, "no new onchange events");	// #9018
 								doh.is(1, watches.length, "no new watch(value) events yet");
-								doh.is("german", dojo.global.dijit.focus.curNode.id, "tabbed from american to german")
-							}), 1000);
+							}));
+
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
+
 							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handler);
 						}
 					}
 				]);
@@ -593,39 +535,35 @@
 // TODO: add key-repeat tests
 
 				doh.register("mouse: drop down", [
-					function setUp(){
-						// clear the field
-						changes = [];
-						american.set('displayedValue', "", false);
-						watches = [];	// do it here to ignore watch() notification for above set() call
-					},
-
 					{
 						name: "initial popup display",
 						timeout: 6000,
+						setUp: function(){
+							// clear the field
+							changes = [];
+							american.set('displayedValue', "", false);
+							watches = [];	// do it here to ignore watch() notification for above set() call
+						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is(0, changes.length, "no onchange events yet #1");
-								doh.is(0, watches.length, "no watch(value) events yet #1");
-							}), 500);
-
-							doh.robot.mouseMoveAt(american.focusNode, 0, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
+							handler = dojo.connect(american, 'openDropDown', d.getTestCallback(function(){
 								var calendar = dijit.byId("american_popup");
 
 								// drop down automatically opened on click
-								doh.t(calendar, "calendar popup exists");
-								doh.t(isVisible(calendar), "calendar is visible");
+								doh.t(calendar && isVisible(calendar), "calendar is visible");
 
-								doh.is(0, changes.length, "no onchange events yet #2");
-								doh.is(0, watches.length, "no watch(value) events yet #2");
-							}), 1000);
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}));
+
+							doh.robot.mouseMoveAt(american._buttonNode, 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
 
 							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handler);
 						}
 					},
 					
@@ -635,39 +573,46 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							// Close drop down and then type a value
+							handler = dojo.connect(american, 'closeDropDown', function(){
+								dojo.disconnect(handler);
+
+								handler = dojo.connect(american, 'openDropDown', d.getTestCallback(function(){
+									var calendar = dijit.byId("american_popup");
+	
+									// calendar exists and is shown
+									doh.t(calendar && isVisible(calendar), "calendar is visible");
+	
+									// calendar is on the right month
+									doh.is("May", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "calendar starts on month selected in input box");
+	
+									// and the right year
+									var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
+									doh.is(1, selectedYearButtons.length, "current year is shown");
+									doh.is("2005", innerText(selectedYearButtons[0]), "current year is 2005");
+	
+									// and the currently selected date is right too
+									var selectedDays = dojo.query(".dijitCalendarSelectedDate", calendar.domNode);
+									doh.is(1, selectedDays.length, "one day selected");
+									doh.is("10", innerText(selectedDays[0]), "correct day is selected");
+	
+									doh.is(0, changes.length, "no onchange events yet");
+									doh.is(0, watches.length, "no watch(value) events yet");
+								}));
+	
+								// type a value
+								doh.robot.typeKeys("5/10/2005", 500, 1800);
+								// And open dropdown again (manually)
+								doh.robot.mouseMoveAt(american._buttonNode, 500, 1);
+								doh.robot.mouseClick({left:true}, 500);
+							});
+
+							// Close drop down
 							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
-							doh.robot.typeKeys("5/10/2005", 500, 1800);
 							
-							// And open dropdown again (manually)
-							doh.robot.mouseMoveAt(american._buttonNode, 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								var calendar = dijit.byId("american_popup");
-
-								// calendar exists and is shown
-								doh.t(calendar, "calendar popup exists");
-								doh.t(isVisible(calendar), "calendar is visible");
-
-								// calendar is on the right month
-								doh.is("May", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "calendar starts on month selected in input box");
-
-								// and the right year
-								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
-								doh.is(1, selectedYearButtons.length, "current year is shown");
-								doh.is("2005", innerText(selectedYearButtons[0]), "current year is 2005");
-
-								// and the currently selected date is right too
-								var selectedDays = dojo.query(".dijitCalendarSelectedDate", calendar.domNode);
-								doh.is(1, selectedDays.length, "one day selected");
-								doh.is("10", innerText(selectedDays[0]), "correct day is selected");
-
-								doh.is(0, changes.length, "no onchange events yet");
-								doh.is(0, watches.length, "no watch(value) events yet");
-							}), 1000);
-
 							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handler);
 						}
 					},
 
@@ -681,13 +626,12 @@
 
 							doh.is(1, nextMonthButtons.length, "found next month button");
 
-							doh.robot.mouseMoveAt(nextMonthButtons[0], 0, 1);
+							doh.robot.mouseMoveAt(nextMonthButtons[0], 100, 1); // delay to allow previous keyUp to occur
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// calendar still exists and is shown
-								doh.t(calendar, "calendar popup exists");
-								doh.t(isVisible(calendar), "calendar is visible");
+								doh.t(calendar && isVisible(calendar), "calendar is visible");
 
 								// calendar moved to the next month
 								doh.is("June", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "moved from may to june");
@@ -721,8 +665,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// calendar still exists and is shown
-								doh.t(calendar, "calendar popup exists");
-								doh.t(isVisible(calendar), "calendar is visible");
+								doh.t(calendar && isVisible(calendar), "calendar is visible");
 
 								// calendar moved to the next month
 								doh.is("July", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "moved from june to july");
@@ -757,8 +700,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// calendar still exists and is shown
-								doh.t(calendar, "calendar popup exists");
-								doh.t(isVisible(calendar), "calendar is visible");
+								doh.t(calendar && isVisible(calendar), "calendar is visible");
 
 								// calendar moved to the next year
 								var yearNodes = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
@@ -942,9 +884,6 @@
 							}), 500);
 
 							return d;
-						},
-						tearDown: function(){
-							german.closeDropDown(true);
 						}
 					},
 					{
@@ -971,9 +910,6 @@
 							}), 500);
 
 							return d;
-						},
-						tearDown: function(){
-							german.closeDropDown(true);
 						}
 					},
 
@@ -984,7 +920,7 @@
 						setUp: function(){
 							german.closeDropDown(true);
 							german.set("dropDownDefaultValue", new Date(2000,11,21));
-							german.set('value', new Date(1900,10,25));
+							german.set('value', new Date(2004,10,25));
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -993,7 +929,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", german.dropDown.domNode);
-								doh.is("1900", innerText(selectedYearButtons[0]), "textbox year is selected");
+								doh.is("2004", innerText(selectedYearButtons[0]), "textbox year is selected");
 	
 								var selectedDates = dojo.query(".dijitCalendarSelectedDate", german.dropDown.domNode);
 								doh.is(1, selectedDates.length, "one selected date");
@@ -1003,66 +939,78 @@
 							}), 500);
 
 							return d;
+						}
+					},
+					{
+						name: "close",
+						timeout: 3000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							handler = dojo.connect(german, 'closeDropDown', d.getTestCallback(function(){}));
+							// Close the drop down so it doesn't interfere with the next test by covering up the
+							// <input> that we want to focus.
+							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
+							return d;
 						},
 						tearDown: function(){
-							german.closeDropDown(true);
+							dojo.disconnect(handler);
 						}
 					}
 				]);
 
 				// Testing that canceling an edit doesn't select anything
-				doh.register("cancel", [
-					{
-						name: "no value",
-						timeout: 6000,
-						runTest: function(){
-							var d = new doh.Deferred();
+				doh.register("cancel edit", {
+					name: "no value",
+					timeout: 6000,
+					runTest: function(){
+						var d = new doh.Deferred();
 
-							doh.f(pattern.get("value"), "initially blank");
+						var wasBlank = !pattern.get("value");
 
-							// open the drop down
-							doh.robot.mouseMoveAt("pattern", 0, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.sequence(d.getTestErrback(function(){
+						handler = dojo.connect(pattern, 'openDropDown', function(){
+							dojo.disconnect(handler);
+							var calendar = dijit.byId("pattern_popup");
+							var wasVisible = calendar && isVisible(calendar);
+
+							handler = dojo.connect(pattern, 'closeDropDown', d.getTestCallback(function(){
+								doh.t(wasBlank, "initially blank");
+								doh.t(wasVisible, "calendar was visible");
 								var calendar = dijit.byId("pattern_popup");
-								doh.t(calendar, "calendar popup exists");
-								doh.t(isVisible(calendar), "calendar is visible");
-							}), 500);
+								doh.f(calendar && isVisible(calendar), "calendar popup destroyed or hidden");
+								doh.t(!pattern.get("value"), "no value set into DateTextBox")
+							}));
 
 							// close the drop down
-							doh.robot.mouseMoveAt("pattern", 500, 1, pattern.domNode.offsetWidth + 20, pattern.domNode.offsetHeight/2);
+							doh.robot.mouseMoveAt("pattern", 0, 1, pattern.domNode.offsetWidth + 20, pattern.domNode.offsetHeight/2);
 							doh.robot.mouseClick({left:true}, 500);			
-							doh.robot.sequence(d.getTestCallback(function(){
-								var calendar = dijit.byId("pattern_popup");
-								doh.f(calendar && isVisible(calendar), "calendar popup destroyed or hidden");
-								doh.f(pattern.get("value"), "no value set into DateTextBox")
-							}), 500);
+						});
 
-							return d;
-						}
-					}
-				]);
+						// open the drop down
+						doh.robot.mouseMoveAt(pattern._buttonNode, 100, 1); // delay to allow previous keyUp to occur
+						doh.robot.mouseClick({left:true}, 500);
 
-				doh.register("month drop down edge case", [
-					function setUp(){
-						american.set('value', new Date(2010, 11, 31), false);
+						return d;
 					},
+					tearDown: function(){
+						dojo.disconnect(handler);
+					}
+				});
 
+				doh.register("month drop down edge case", [
 					{
 						name: "initial popup display",
 						timeout: 6000,
+						setUp: function(){
+							american.set('value', new Date(2006, 11, 31), false);
+						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt(american.focusNode, 0, 1);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
+							handler = dojo.connect(american, 'openDropDown', d.getTestCallback(function(){
 								var calendar = dijit.byId("american_popup");
 
 								// calendar exists and is shown
-								doh.t(calendar, "calendar popup exists");
-								doh.t(isVisible(calendar), "calendar is visible");
+								doh.t(calendar && isVisible(calendar), "calendar is visible");
 
 								// calendar is on the right month
 								doh.is("December", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "calendar starts on month selected in input box");
@@ -1070,13 +1018,19 @@
 								// and the right year
 								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
 								doh.is(1, selectedYearButtons.length, "current year is shown");
-								doh.is("2010", innerText(selectedYearButtons[0]), "current year");
+								doh.is("2006", innerText(selectedYearButtons[0]), "current year");
 
 								// and the currently focused date is the 31'st
-								doh.is("31", innerText(dojo.global.dijit.focus.curNode), "correct day is focused");
-							}), 1000);
+								doh.is("31", innerText(dojo.query(".dijitCalendarSelectedDate", calendar.domNode)[0]), "correct day is selected");
+							}));
+
+							doh.robot.mouseMoveAt(american._buttonNode, 100, 1); // delay to allow previous mouseUp to occur
+							doh.robot.mouseClick({left:true}, 500);
 
 							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handler);
 						}
 					},
 
@@ -1105,11 +1059,11 @@
 								doh.t(calendar, "calendar popup exists");
 								doh.t(isVisible(calendar), "calendar is visible");
 
-								// calendar moved to feb 2010
+								// calendar moved to feb 2006
 								doh.is("February", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "moved from December to February");
 								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
 								doh.is(1, selectedYearButtons.length, "current year is shown");
-								doh.is("2010", innerText(selectedYearButtons[0]), "current year");
+								doh.is("2006", innerText(selectedYearButtons[0]), "current year");
 							}), 500);
 
 							return d;
@@ -1141,11 +1095,11 @@
 								doh.t(calendar, "calendar popup exists");
 								doh.t(isVisible(calendar), "calendar is visible");
 
-								// calendar moved to dec 2010
+								// calendar moved to dec 2006
 								doh.is("December", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "moved from june to july");
 								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
 								doh.is(1, selectedYearButtons.length, "current year is shown");
-								doh.is("2010", innerText(selectedYearButtons[0]), "current year");
+								doh.is("2006", innerText(selectedYearButtons[0]), "current year");
 							}), 1000);
 
 							return d;
@@ -1154,47 +1108,52 @@
 
 					{
 						name: "cancel",
-						timeout: 6000,
+						timeout: 3000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
+							handler = dojo.connect(american, 'closeDropDown', d.getTestCallback(function(){
+								var calendar = dijit.byId("american_popup");
+								doh.f(calendar && isVisible(calendar), "calendar isn't visible");
+							}));
 							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-							}), 5);
-
 							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handler);
 						}
 					}
 				]);
 
-				doh.register("openOnClick=false", [
+				doh.register("clicking input", [
 					{
 						name: "click on input",
-						timeout: 6000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt(localLong.focusNode, 0, 1);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.sequence(d.getTestErrback(function(){
+							handler = dojo.connect(localLong.focusNode, 'onfocus', function(){
+								dojo.disconnect(handler);
 								var calendar = dijit.byId("localLong_popup");
-								doh.f(calendar && isVisible(calendar), "calendar isn't visible");
-								doh.is(localLong.focusNode, dojo.global.dijit.focus.curNode, "focused on input");
-							}), 1000);
-
-							doh.robot.mouseMoveAt(localLong._buttonNode, 0, 1);
+								var wasVisible = calendar && isVisible(calendar);
+								handler = dojo.connect(localLong, 'openDropDown', d.getTestCallback(function(){
+									doh.f(wasVisible, "calendar isn't visible");
+									calendar = dijit.byId("localLong_popup");
+									doh.t(calendar && isVisible(calendar), "calendar is visible");
+								}));
+								doh.robot.mouseMoveAt(localLong._buttonNode, 0, 1);
+								doh.robot.mouseClick({left:true}, 500);
+							});
+
+							doh.robot.mouseMoveAt(localLong.focusNode, 100, 1); // delay to allow previous keyUp to occur
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								var calendar = dijit.byId("localLong_popup");
-
-								// calendar isn't displayed
-								doh.t(calendar && isVisible(calendar), "calendar is visible");
-							}), 1000);
-
 							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handler);
+							localLong.closeDropDown();
 						}
 					}
 				]);
diff --git a/dijit/tests/form/robot/Form_onsubmit.html b/dijit/tests/form/robot/Form_onsubmit.html
index 2ce2878..f398ade 100644
--- a/dijit/tests/form/robot/Form_onsubmit.html
+++ b/dijit/tests/form/robot/Form_onsubmit.html
@@ -11,10 +11,9 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_Form_onsubmit.html');
diff --git a/dijit/tests/form/robot/Form_state.html b/dijit/tests/form/robot/Form_state.html
index 5ae48db..c325c9f 100644
--- a/dijit/tests/form/robot/Form_state.html
+++ b/dijit/tests/form/robot/Form_state.html
@@ -11,10 +11,9 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			// Some of these tests are duplicated in Form.html, maybe the Form.html watch(state) and validate()
 			// tests groups should be moved here.
diff --git a/dijit/tests/form/robot/MultiSelect.html b/dijit/tests/form/robot/MultiSelect.html
index 16c4f86..0e790cd 100644
--- a/dijit/tests/form/robot/MultiSelect.html
+++ b/dijit/tests/form/robot/MultiSelect.html
@@ -11,10 +11,9 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			function testInverted(allOptions, selected, newSelected){
 				doh.is(allOptions.length, selected.length+newSelected.length); //newSelected + the no longer selected list size should be the same as the length of the whole list
@@ -241,20 +240,6 @@
 							}), 1000);
 							return d;
 						}
-					},
-					{
-						name: "formSubmit",
-						timeout: 1500,
-						runTest: function(){
-							var d=new doh.Deferred();
-							dijit.byId('select3').set('value', ['TN','FL']);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-									var vals = dojo.fromJson(dojo.formToJson("test"));
-									doh.is("TN,FL", vals.select3);
-							}), 500);
-							return d;
-						}
 					}
 
 				]);
diff --git a/dijit/tests/form/robot/Select.html b/dijit/tests/form/robot/Select.html
index 05ee051..a36ef65 100644
--- a/dijit/tests/form/robot/Select.html
+++ b/dijit/tests/form/robot/Select.html
@@ -11,29 +11,31 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
-		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 			dojo.require("dojo.date");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_Select.html');
 
 				// refs to parts of s1 Select
 				var s1, s1menu, Tenessee, Virginia, Washington,	// s1 select
-					s8a, s8a_menu, s8b, s8b_menu, s3, s3_menu;				// long list selects
+					s2, s2menu, s8a, s8a_menu, s8b, s8b_menu, s3, s3_menu;				// long list selects
 
 				// log of calls to onChange handler
 				var changes = [];
 
 				doh.register("setup",
 					function setUp(){
-				    	s1 = dijit.byId('s1');
+						s1 = dijit.byId('s1');
 						s1_menu = dijit.byId('s1_menu');
 						doh.t(s1, "s1 select exists");
 						doh.t(s1_menu, "s1 menu exists");
 						
+						s2 = dijit.byId('s2');
+						s2_menu = dijit.byId('s2_menu');
 						s8a = dijit.byId('s8a');
 						s8a_menu = dijit.byId('s8a_menu');
 						s8b = dijit.byId('s8b');
@@ -69,6 +71,8 @@
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(s1_menu), "drop down menu displayed after click");
+								doh.is("true", s1.domNode.getAttribute('aria-expanded'), 'aria-expanded');
+								doh.is("listbox", s1_menu.domNode.getAttribute('role'), 'menu role');
 								doh.is(5, dojo.query("tr", s1_menu.domNode).length, "5 options in menu");
 								
 								var selectedOptions = dojo.query(".dijitSelectSelectedOption .dijitMenuItemLabel", s1_menu.domNode);
@@ -87,6 +91,7 @@
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isHidden(s1_menu), "clicking choice hides menu");
+								doh.is("false", s1.domNode.getAttribute('aria-expanded'), 'aria-expanded');
 								
 								doh.is("Washington", innerText(s1.containerNode), "select shows selected option");
 								doh.is("WA", s1.get("value"), "get(value) after selecting Washington");
@@ -190,7 +195,7 @@
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(s8a_menu.domNode), "drop down menu displayed after mouse down");
 								
-								var pos = dojo.position(s8a_menu.domNode);
+								var pos = dojo.position(s8a_menu.domNode.parentNode);	// scrollbar on wrapper
 								doh.t(pos.h >= 200, "height at least 200: " + pos.h);
 								doh.t(pos.h < 220, "height including borders not much more than 200: " + pos.h);
 							}), 1000);
@@ -281,40 +286,44 @@
 					},
 					{
 						name: "selecting",
-						timeout: 15000,
+						timeout: 9000,
 						setUp: function(){
 							dojo.byId("htmlSelect2").focus();
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
+							var nextFocused, previousSelectionFocused, wasVisible, stillVisible, widgetFocused;
 
 							// tab to s1
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("s1", dojo.global.dijit.focus.curNode.id)
-							}), 1000);
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
+							doh.robot.sequence(function(){
+								widgetFocused = dojo.global.dijit.focus.curNode.id == "s1";
+							}, 1000);
 
 							// down arrow to open drop down and focus first item
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible(s1_menu), "drop down menu displayed after down arrow");
-								Tenessee = dojo.query("tr", s1_menu.domNode)[0];
-								doh.is(Tenessee, dojo.global.dijit.focus.curNode, "focused on first menu item")
-							}), 1000);
+							doh.robot.sequence(function(){
+								wasVisible = isVisible(s1_menu);
+								previousSelectionFocused = dojo.query("tr", s1_menu.domNode)[2] == dojo.global.dijit.focus.curNode;
+							}, 1000);
 
 							// down arrow to next menu choice
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible(s1_menu), "drop down menu still displayed");
-								Virginia = dojo.query("tr", s1_menu.domNode)[1];
-								doh.is(Virginia, dojo.global.dijit.focus.curNode, "focused on second menu item")
-							}), 1000);
+							doh.robot.sequence(function(){
+								stillVisible = isVisible(s1_menu);
+								nextFocused = dojo.query("tr", s1_menu.domNode)[3] == dojo.global.dijit.focus.curNode;
+							}, 500);
 
 							// ENTER to select option
 							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
 							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(widgetFocused, "widget focus");
+								doh.t(wasVisible, "drop down menu displayed after down arrow");
+								doh.t(previousSelectionFocused, "focused on previously selected item")
+								doh.t(stillVisible, "drop down menu still displayed");
+								doh.t(nextFocused, "focused on next menu item")
 								doh.t(isHidden(s1_menu), "drop down menu closes after ENTER key");
-								doh.is("VA", s1.get("value"));
+								doh.is("FL", s1.get("value"));
 							}), 1000);
 
 							return d;
@@ -325,32 +334,38 @@
 					},
 					{
 						name: "ESC to close menu",
-						timeout: 10000,
+						timeout: 9000,
 						setUp: function(){
 							dojo.byId("htmlSelect2").focus();
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
+							var nextFocused, wasVisible, widgetFocused;
 
 							// tab to s1
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("s1", dojo.global.dijit.focus.curNode.id)
-							}), 1000);
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
+							doh.robot.sequence(function(){
+								widgetFocused = dojo.global.dijit.focus.curNode.id == "s1";
+							}, 1000);
 
 							// down arrow to open drop down and focus first item
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible(s1_menu), "drop down menu displayed after down arrow");
-								Tenessee = dojo.query("tr", s1_menu.domNode)[0];
-								doh.is(Tenessee, dojo.global.dijit.focus.curNode, "focused on first menu item")
-							}), 1000);
+							doh.robot.sequence(function(){
+								wasVisible = isVisible(s1_menu);
+							}, 1000);
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							doh.robot.sequence(function(){
+								nextFocused = dojo.query("tr", s1_menu.domNode)[2] == dojo.global.dijit.focus.curNode;
+							}, 500);
 
 							// ESC to close menu
 							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
 							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(widgetFocused, "widget focus");
+								doh.t(wasVisible, "drop down menu displayed after down arrow");
+								doh.t(nextFocused, "focused next menu item")
 								doh.t(isHidden(s1_menu), "drop down menu closes after ENTER key");
-								doh.is("VA", s1.get("value"), "value hasn't changed");
+								doh.is("VA", s1.get("value"), "value unchanged");
 							}), 1000);
 
 							return d;
@@ -358,6 +373,200 @@
 						tearDown: function(){
 							dijit.byId("s1").set("value", "VA");
 						}
+					},
+					{
+						name: "single letter search after failed multiple letter search, no dropdown",
+						timeout: 9000,
+						setUp: function(){
+							s2.set("value", "CA");
+							s2.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// c search fails to find CA due to multi-character searching
+							doh.robot.typeKeys("aaaaaaac", 1000, 1200);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("AZ", s2.get("value"), "hidden value");
+								doh.f(isVisible(s2_menu), "no menu");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "multiple letter search after failed multiple letter search, no dropdown",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// ala suffix fails to find either alabama or alaska due to multi-character searching
+							doh.robot.typeKeys("aaaaaaaaala", 1000, 1400);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("AR", s2.get("value"), "hidden value");
+								doh.f(isVisible(s2_menu), "no menu");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "multiple letter searching from current, no dropdown",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// search for Alabama
+							doh.robot.typeKeys("al", 1000, 1600); // al search finds alabama
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("AL", s2.get("value"), "hidden value");
+								doh.f(isVisible(s2_menu), "no menu");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "multiple letter searching find next, no dropdown",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.typeKeys("alas", 1000, 1600); // s search finds alaska
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("AK", s2.get("value"), "hidden value");
+								doh.f(isVisible(s2_menu), "no menu");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "single letter searching, no dropdown",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// c search finds CA 
+							doh.robot.typeKeys("c", 500, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("CA", s2.get("value"), "hidden value");
+								doh.f(isVisible(s2_menu), "no menu");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "multi letter searching with SPACE, no dropdown",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// c search fails to find CA due to multi-character searching
+							doh.robot.typeKeys("new m", 500, 1200);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("NM", s2.get("value"), "hidden value");
+								doh.f(isVisible(s2_menu), "no menu");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "single letter searching from dropdown",
+						timeout: 9000,
+						setUp: function(){
+							s2.set("value", "CA");
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// down arrow to open drop down and search with several a's
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							doh.robot.typeKeys("aaaaaaac", 1000, 1200); // c search fails to find CA due to multi-character searching
+
+							// SPACE to close menu
+							doh.robot.keyPress(dojo.keys.SPACE, 1100, {}); // long delay so that multi-letter searching is deactivated
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("AZ", s2.get("value"), "hidden value");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "multiple letter searching no match from dropdown",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// ENTER to open drop down and search with several a's
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.typeKeys("aaaaaaaaala", 1000, 1400); // ala suffix fails to find either alabama or alaska
+
+							// ENTER to close menu
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("AR", s2.get("value"), "hidden value");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "multiple letter searching from current from dropdown",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var wasVisible;
+
+							// SPACE to open drop down and search with several a's
+							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							doh.robot.typeKeys("al", 1000, 1600); // al search finds alabama
+							doh.robot.sequence(function(){
+								wasVisible = isVisible(s2_menu);
+							}, 1000);
+
+							// SPACE to close menu
+							doh.robot.keyPress(dojo.keys.SPACE, 1100, {}); // long delay so that multi-letter searching is deactivated
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(wasVisible, "no auto selection");
+								doh.is("AL", s2.get("value"), "hidden value");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "multiple letter searching find next from dropdown",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var wasVisible;
+
+							// down arrow to open drop down and search with several a's
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							doh.robot.typeKeys("alas", 1000, 1600); // s search finds alaska
+							doh.robot.sequence(function(){
+								wasVisible = isVisible(s2_menu);
+							}, 1000);
+
+							// ENTER to close menu
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(wasVisible, "no auto selection");
+								doh.is("AK", s2.get("value"), "hidden value");
+							}), 1000);
+
+							return d;
+						}
 					}
 				]);
 
diff --git a/dijit/tests/form/robot/SimpleTextarea.html b/dijit/tests/form/robot/SimpleTextarea.html
index 157f2d6..53f504a 100644
--- a/dijit/tests/form/robot/SimpleTextarea.html
+++ b/dijit/tests/form/robot/SimpleTextarea.html
@@ -11,10 +11,9 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_SimpleTextarea.html');
diff --git a/dijit/tests/form/robot/Slider_mouse.html b/dijit/tests/form/robot/Slider_mouse.html
index 09764f6..cd2fdf7 100644
--- a/dijit/tests/form/robot/Slider_mouse.html
+++ b/dijit/tests/form/robot/Slider_mouse.html
@@ -112,6 +112,9 @@
 				doh.is(2, dijit.byId("slider3").get("value"), "horizontal2");
 				doh.is(10, dijit.byId("sliderH2").get("value"), "sliderH2");
 				doh.is(1400, dijit.byId("programaticSlider").get("value"), "programaticSlider");
+				doh.t(dijit.byId("programmaticSliderNoSrc"),
+					"programmaticSliderNoSrc (containing RuleLabels w/o srcNodeRef) was initialized (see #13815)");
+				doh.is(1400, dijit.byId("programmaticSliderNoSrc").get("value"), "programmaticSliderNoSrc");
 			});
 
 			doh.register("set('value', ...)", [
@@ -315,7 +318,7 @@
 			doh.register("drag tests", [
 				{
 					name: "horizontal",
-					timeout: 5000,
+					timeout: 10000,
 					runTest: function(){
 						var d = new doh.Deferred();
 						var slider = dijit.byId("slider1");
diff --git a/dijit/tests/form/robot/Spinner_a11y.html b/dijit/tests/form/robot/Spinner_a11y.html
index 8957268..942323b 100644
--- a/dijit/tests/form/robot/Spinner_a11y.html
+++ b/dijit/tests/form/robot/Spinner_a11y.html
@@ -54,8 +54,10 @@
 					results = populateExpected(spinner);
 					strokeIndex = 0;
 					noteConnect = spinner.connect(spinner.focusNode, "onkeypress", function(){
-						results[strokeIndex].actual = spinner.get('value');
-						strokeIndex++;
+						setTimeout(function(){
+							results[strokeIndex].actual = spinner.get('value');
+							strokeIndex++;
+						}, 5);
 					});
 				}
 
@@ -313,7 +315,7 @@
 						runTest: function(){
 							// assert invalid works
 							var d=new doh.Deferred();
-							spin2.focusNode.value="";
+							spin2.set("value", NaN);
 							focusThenRun(spin2, function(){
 								doh.robot.typeKeys("0.5", 1, 600);
 								doh.robot.sequence(d.getTestCallback(function(){
@@ -355,7 +357,9 @@
 							if(spinner.constraints.max){
 								doh.is(spinner.focusNode.getAttribute("aria-valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
 							}else{
-								doh.f(spinner.focusNode.hasAttribute("aria-valuemax"), spinner.id + ": aria-valuemax");
+								if(spinner.focusNode.hasAttribute){		// not available on IE6/7
+									doh.f(spinner.focusNode.hasAttribute("aria-valuemax"), spinner.id + ": aria-valuemax");
+								}
 							}
 						},
 						function maxOnly(){
@@ -365,7 +369,9 @@
 							if(spinner.constraints.min){
 								doh.is(spinner.focusNode.getAttribute("aria-valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
 							}else{
-								doh.f(spinner.focusNode.hasAttribute("aria-valuemin"), spinner.id + ": aria-valuemin");
+								if(spinner.focusNode.hasAttribute){		// not available on IE6/7
+									doh.f(spinner.focusNode.hasAttribute("aria-valuemin"), spinner.id + ": aria-valuemin");
+								}
 							}
 						},
 						function neitherMinNorMax(){
@@ -374,12 +380,16 @@
 							if(spinner.constraints.min){
 								doh.is(spinner.focusNode.getAttribute("aria-valuemin"), spinner.constraints.min, spinner.id + ": aria-valuemin");
 							}else{
-								doh.f(spinner.focusNode.hasAttribute("aria-valuemin"), spinner.id + ": aria-valuemin");
+								if(spinner.focusNode.hasAttribute){		// not available on IE6/7
+									doh.f(spinner.focusNode.hasAttribute("aria-valuemin"), spinner.id + ": aria-valuemin");
+								}
 							}
 							if(spinner.constraints.max){
 								doh.is(spinner.focusNode.getAttribute("aria-valuemax"), spinner.constraints.max, spinner.id + ": aria-valuemax");
 							}else{
-								doh.f(spinner.focusNode.hasAttribute("aria-valuemax"), spinner.id + ": aria-valuemax");
+								if(spinner.focusNode.hasAttribute){		// not available on IE6/7
+									doh.f(spinner.focusNode.hasAttribute("aria-valuemax"), spinner.id + ": aria-valuemax");
+								}
 							}
 						}
 					]
@@ -516,7 +526,7 @@
 						timeout: 5000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							spin4.focusNode.value="";
+							spin4.set("value", NaN);
 							focusThenRun(spin4, function(){
 								var handler = spin4.connect(spin4, '_onBlur',
 									function(){
@@ -539,7 +549,7 @@
 						timeout: 5000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							spin4.focusNode.value="";
+							spin4.set("value", NaN);
 							focusThenRun(spin4, function(){
 								var handler = spin4.connect(spin4, '_onBlur',
 									function(){
@@ -563,7 +573,7 @@
 						timeout: 9000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							spin4.focusNode.value="";
+							spin4.set("value", NaN);
 							focusThenRun(spin4, function(){
 								var handler = spin4.connect(spin4, '_onBlur',
 									function(){
@@ -593,7 +603,7 @@
 						timeout: 5000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							spin4.focusNode.value="";
+							spin4.set("value", NaN);
 							focusThenRun(spin4, function(){
 								doh.robot.typeKeys("0.5e99", 1, 1200);
 								doh.robot.keyPress(dojo.keys.HOME, 500);
@@ -612,7 +622,7 @@
 						timeout: 9000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							spin4.focusNode.value="";
+							spin4.set("value", NaN);
 							focusThenRun(spin4, function(){
 								doh.robot.typeKeys(".5e9a", 1, 1000);
 								doh.robot.keyPress(dojo.keys.HOME, 500);
@@ -638,7 +648,7 @@
 						timeout: 5000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							spin3.focusNode.value="";
+							spin3.set("value", NaN);
 							focusThenRun(spin3, function(){
 								var handler = spin3.connect(spin3, '_onBlur',
 									function(){
@@ -660,7 +670,7 @@
 						timeout: 5000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							spin4.focusNode.value="";
+							spin4.set("value", NaN);
 							focusThenRun(spin4, function(){
 								var handler = spin4.connect(spin4, '_onBlur',
 									function(){
diff --git a/dijit/tests/form/robot/Spinner_mouse.html b/dijit/tests/form/robot/Spinner_mouse.html
index efbee57..fd44c9d 100644
--- a/dijit/tests/form/robot/Spinner_mouse.html
+++ b/dijit/tests/form/robot/Spinner_mouse.html
@@ -86,7 +86,7 @@
 							doh.robot.mouseMoveAt(spin1.focusNode, 1, 0);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(function(){
-								spin1.focusNode.value="";
+								spin1.set("value", NaN);
 							}, 500);
 							doh.robot.typeKeys("0.5", 500, 600);
 							doh.robot.sequence(function(){
@@ -116,7 +116,7 @@
 							doh.robot.mouseMoveAt(spin3.focusNode, 1, 0);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(function(){
-								spin3.focusNode.value="";
+								spin3.set("value", NaN);
 							}, 500);
 							doh.robot.typeKeys("0.a", 500, 600); // vs 0.5 in spinner1_invalid, spin3 would accept that
 							doh.robot.sequence(function(){
diff --git a/dijit/tests/form/robot/TextBox_onInput.html b/dijit/tests/form/robot/TextBox_onInput.html
new file mode 100644
index 0000000..e63097d
--- /dev/null
+++ b/dijit/tests/form/robot/TextBox_onInput.html
@@ -0,0 +1,137 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>robot TextBox onInput Test</title>
+
+	<style>
+		@import "../../../../util/doh/robot/robot.css";
+	</style>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner", "dojo/robotx",
+			"dojo/aspect", "dojo/json", "dojo/keys", "dojo/on",
+			"dojo/domReady!"
+		], function(doh, robot, aspect, json, keys, on){
+			robot.initRobot('../test_validate.html');
+
+			var widget, registry
+
+			doh.register("onInput", [
+				function setup(){
+					// get pointers to singletons loaded on test page
+					registry = robot.window.require("dijit/registry");
+					widget = registry.byId('q01');
+				},
+				{
+					name: "focus",
+					timeout: 2000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						var handler = on.once(widget.focusNode, "focus",
+								function(){
+									setTimeout(d.getTestCallback(function(){
+										doh.t(true);
+									}), 0);
+								}
+						);
+						setTimeout(function(){
+							widget.focus();
+						}, 1); // return d before calling onfocus
+						return d;
+					}
+				},
+				{
+					name: "space",
+					timeout: 2000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						var handler = aspect.after(widget, "onInput", d.getTestErrback(function(e){
+							var expEvt = expected.shift() || { type: null, charOrCode: null };
+							if(expEvt.type != e.type || expEvt.charOrCode !== e.charOrCode || expEvt.ctrlKey != e.ctrlKey || expEvt.shiftKey != e.shiftKey || expEvt.altKey != e.altKey){
+								handler.remove();
+								d.getTestCallback(function(){
+									doh.is(expEvt.type, e.type);
+									doh.is(expEvt.charOrCode, e.charOrCode);
+									doh.is(expEvt.ctrlKey, e.ctrlKey);
+									doh.is(expEvt.shiftKey, e.shiftKey);
+									doh.is(expEvt.altKey, e.altKey);
+								})(); // fail asap
+							}else if(expected.length == 0){
+								setTimeout(d.getTestCallback(function(){
+									handler.remove();
+								}), 100); // wait to see if an extra onInput event arrives
+							}
+						}), true);
+						var expected = [
+							{ type: "keypress", charOrCode: ' ', ctrlKey: false, shiftKey: false, altKey: false }
+						];
+						robot.keyPress(keys.SPACE, 100, {});
+
+						return d;
+					}
+				},
+				{
+					name: "test all",
+					timeout: 9000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						var handler = aspect.after(widget, "onInput", d.getTestErrback(function(e){
+							var expEvt = expected.shift() || { type: null, charOrCode: null, ctrlKey: false, shiftKey: false, altKey: false };
+							if(expEvt.charOrCode == ' '/*the end sentinel*/ || (expEvt.type != e.type || expEvt.charOrCode !== e.charOrCode || expEvt.ctrlKey != e.ctrlKey || (expEvt.shiftKey != null && expEvt.shiftKey != e.shiftKey) || expEvt.altKey != e.altKey)){
+								handler.remove();
+								d.getTestCallback(function(){
+									var hint = "Expected: " +
+											json.stringify({ type: expEvt.type, charOrCode: expEvt.charOrCode, ctrlKey: expEvt.ctrlKey, shiftKey: expEvt.shiftKey, altKey: expEvt.altKey }) +
+											", Actual " +
+											json.stringify({ type: e.type, charOrCode: e.charOrCode, ctrlKey: e.ctrlKey, shiftKey: e.shiftKey, altKey: e.altKey });
+									doh.is(expEvt.type, e.type, hint);
+									doh.is(expEvt.charOrCode, e.charOrCode, hint);
+									doh.is(expEvt.ctrlKey, e.ctrlKey, hint);
+									doh.is(expEvt.altKey, e.altKey, hint);
+									doh.t(expEvt.shiftKey == null || expEvt.shiftKey == e.shiftKey, hint);
+								})();
+							}
+						}), true);
+						var expected = [
+							{ type: "keypress", charOrCode: 'a', ctrlKey: false, shiftKey: false, altKey: false },
+							{ type: "keypress", charOrCode: 'Z', ctrlKey: false, shiftKey: true, altKey: false },
+							{ type: "keypress", charOrCode: '0', ctrlKey: false, shiftKey: null, altKey: false },
+							{ type: "keypress", charOrCode: '_', ctrlKey: false, shiftKey: null, altKey: false },
+							{ type: "keypress", charOrCode: '-', ctrlKey: false, shiftKey: null, altKey: false },
+							{ type: "keypress", charOrCode: '+', ctrlKey: false, shiftKey: null, altKey: false },
+							{ type: "keypress", charOrCode: '=', ctrlKey: false, shiftKey: null, altKey: false },
+							{ type: "keypress", charOrCode: '/', ctrlKey: false, shiftKey: null, altKey: false },
+							{ type: "keypress", charOrCode: '*', ctrlKey: false, shiftKey: null, altKey: false },
+							{ type: "keypress", charOrCode: '.', ctrlKey: false, shiftKey: null, altKey: false },
+							{ type: "keypress", charOrCode: 'Q', ctrlKey: false, shiftKey: true, altKey: false },
+							{ type: "keydown", charOrCode: 'C', ctrlKey: true, shiftKey: false, altKey: false },
+							{ type: "keydown", charOrCode: keys.RIGHT_ARROW, ctrlKey: false, shiftKey: false, altKey: false },
+							{ type: "keydown", charOrCode: keys.ENTER, ctrlKey: true, shiftKey: false, altKey: true },
+							{ type: "keydown", charOrCode: keys.TAB, ctrlKey: false, shiftKey: false, altKey: false },
+							{ type: "keypress", charOrCode: ' ', ctrlKey: false, shiftKey: false, altKey: false }
+						];
+						robot.typeKeys('aZ0_-+=/*.', 100, 2000);
+						robot.keyPress('q', 200, { shift: true });
+						robot.keyPress('c', 200, { ctrl: true });
+						robot.keyPress(keys.RIGHT_ARROW, 200, {});
+						robot.keyPress(keys.ENTER, 200, { ctrl: true, shift: false, alt: true });
+						robot.keyPress(keys.TAB, 200, {});
+						robot.keyPress(keys.TAB, 500, { shift: true });
+						robot.keyPress(keys.SPACE, 500, {});
+
+						return d;
+					}
+				}
+			]);
+			doh.run();
+		});
+	</script>
+</head>
+</html>
diff --git a/dijit/tests/form/robot/Textarea.html b/dijit/tests/form/robot/Textarea.html
index cb22dda..94baf8d 100644
--- a/dijit/tests/form/robot/Textarea.html
+++ b/dijit/tests/form/robot/Textarea.html
@@ -3,7 +3,7 @@
 <html>
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-		<title>doh.robot Textarea Test</title>
+		<title>robot Textarea Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
@@ -13,25 +13,29 @@
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Textarea.html');
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom-geometry", "dojo/keys", "dojo/sniff",
+				"dojo/domReady!"
+			], function(doh, robot, domGeom, keys, has){
+				robot.initRobot('../test_Textarea.html');
 
 				// execute some test as soon as the widget gets focus
-				var focusThenRun = function(widget, fcn){
+				function focusThenRun(widget, fcn){
 					if(!widget.focused){
-						var handler = widget.connect(widget, '_onFocus', function(){
-							widget.disconnect(handler);
+						var handle = widget.on('focus', function(){
+							handle.remove();
 							setTimeout(fcn, 1);
 						});
 						widget.focus();
 					}else{
 						fcn();
 					}
-				};
+				}
 
 				doh.register("init", function init(){
+					registry = robot.window.require("dijit/registry");
+
 					// Wait for Textarea widgets to size themselves... it's done on a setTimeout(func, 0)
 					var d = new doh.Deferred();
 					setTimeout(function(){
@@ -44,8 +48,9 @@
 					{
 						name: "initial height",
 						runTest: function(){
-							var blank = dojo.marginBox("blank").h,
-							large = dojo.marginBox("largeTextArea").h;
+							var blank = domGeom.getMarginBox("blank").h,
+							large = domGeom.getMarginBox("largeTextArea").h;
+							doh.t(blank > 8, "blank: " + blank);
 							doh.t(large > blank, "blank: " + blank + ", large: " + large);
 						}
 					},
@@ -55,24 +60,24 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								w = dijit.byId("blank"),
-								height1 = dojo.marginBox(w.domNode).h,
+								w = registry.byId("blank"),
+								height1 = domGeom.getMarginBox(w.domNode).h,
 								height2, height3;
 
 							focusThenRun(w, function(){
 								// Test expand on newline
-								doh.robot.typeKeys('Row of text.', 1, 2000);
-								doh.robot.keyPress(dojo.keys.ENTER, 100, {});
-								doh.robot.keyPress(dojo.keys.ENTER, 100, {});
-								doh.robot.sequence(function(){
-									height2 = dojo.marginBox(w.domNode).h;
-								}, 1000);
+								robot.typeKeys('Row of text.', 1, 2000);
+								robot.keyPress(keys.ENTER, 100, {});
+								robot.keyPress(keys.ENTER, 100, {});
+								robot.sequence(d.getTestErrback(function(){
+									height2 = domGeom.getMarginBox(w.domNode).h;
+								}), 1000);
 
 								// Test shrink on delete of newline
-								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});
-								doh.robot.keyPress(dojo.keys.DELETE, 200, {});
-								doh.robot.sequence(d.getTestCallback(function(){
-									height3 = dojo.marginBox(w.domNode).h;
+								robot.keyPress(keys.LEFT_ARROW, 200, {});
+								robot.keyPress(keys.DELETE, 200, {});
+								robot.sequence(d.getTestCallback(function(){
+									height3 = domGeom.getMarginBox(w.domNode).h;
 									doh.t(height2 > height1, "height ("+height2+") should have increased from " + height1);
 									doh.t(height3 < height2, "height ("+height3+") should have decreased from " + height2);
 								}), 1000);
@@ -87,8 +92,8 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								w = dijit.byId("blank"),
-								height1 = dojo.marginBox(w.domNode).h,
+								w = registry.byId("blank"),
+								height1 = domGeom.getMarginBox(w.domNode).h,
 								height2,
 								height3,
 								handler,
@@ -98,74 +103,70 @@
 								typing = true;
 
 							w.set('intermediateChanges', true);
-							focusThenRun(w, function(){
-								// Test expand by wordwrap
-								text = text+text+text+text;
-								// onChange handler enables very fast typing and deleting, but not too fast
-								handler = w.connect(w, 'onChange', function(nv){
-									if(typing){
-										pos = nv.indexOf(text);
-										if(pos <= 0){
-											doh.robot.typeKeys(text.substr(i++,1), 1, 0);
-											return;
-										} // still typing
-										height2 = dojo.marginBox(w.domNode).h;
-										typing = false;
-										// Test shrink on delete (backspace) of text.   delete seems to delete the next character
-										// rather than the previous character, hence the LEFT_ARROW.
-										doh.robot.keyPress(dojo.keys.LEFT_ARROW, 0, {});
-										doh.robot.keyPress(dojo.keys.DELETE, 0, {});
-									}else{
-										if(nv.length > pos){
-											doh.robot.keyPress(dojo.keys.LEFT_ARROW, 0, {});
-											doh.robot.keyPress(dojo.keys.DELETE, 0, {});
-											return; // still deleting
-										}
-										w.disconnect(handler);
-										doh.robot.sequence(d.getTestCallback(function(){
-											doh.t(height2 > height1, "height ("+height2+") should have increased from " + height1);
-											height3 = dojo.marginBox(w.domNode).h;
-											doh.t(height3 < height2, "height ("+height3+") should have decreased from " + height2);
-										}), 1);
+							// Test expand by wordwrap
+							text = text+text+text+text;
+							// onChange handler enables very fast typing and deleting, but not too fast
+							handler = w.on('change', function(nv){
+								if(typing){
+									pos = nv.indexOf(text);
+									if(pos <= 0){
+										robot.typeKeys(text.substr(i++,1), 1, 0);
+										return;
+									} // still typing
+									height2 = domGeom.getMarginBox(w.domNode).h;
+									typing = false;
+									// Test shrink on delete (backspace) of text.   delete seems to delete the next character
+									// rather than the previous character, hence the LEFT_ARROW.
+									robot.keyPress(keys.LEFT_ARROW, 0, {});
+									robot.keyPress(keys.DELETE, 0, {});
+								}else{
+									if(nv.length > pos){
+										robot.keyPress(keys.LEFT_ARROW, 0, {});
+										robot.keyPress(keys.DELETE, 0, {});
+										return; // still deleting
 									}
-								});
-								doh.robot.typeKeys(text.substr(i++,1), 1, 0);
+									handler.remove();
+									robot.sequence(d.getTestCallback(function(){
+										doh.t(height2 > height1, "height ("+height2+") should have increased from " + height1);
+										height3 = domGeom.getMarginBox(w.domNode).h;
+										doh.t(height3 < height2, "height ("+height3+") should have decreased from " + height2);
+									}), 1);
+								}
 							});
+							robot.typeKeys(text.substr(i++,1), 1, 0);
 
 							return d;
 						}
 					},
 					{
 						name: "expansion/contraction by cut/paste",
-						timeout: 5000,
+						timeout: 9000,
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								modifier = dojo.isMac ? {meta: true} : {ctrl: true},
-								w = dijit.byId("blank"),
+								modifier = has("mac") ? {meta: true} : {ctrl: true},
+								w = registry.byId("blank"),
 								height1, height2, height3;
 
-							focusThenRun(w, function(){
-								doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-								doh.robot.sequence(function(){
-									height1 = dojo.marginBox(w.domNode).h;
-								}, 500);
-								// Cut text, height should decrease
-								doh.robot.keyPress("a", 1, modifier);
-								doh.robot.keyPress("x", 500, modifier);
-								doh.robot.sequence(function(){
-									height2 = dojo.marginBox(w.domNode).h;
-								}, 500);
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.sequence(function(){
+								height1 = domGeom.getMarginBox(w.domNode).h;
+								w.domNode.select();
+							}, 500);
+							// Cut text, height should decrease
+							robot.keyPress("x", 500, modifier);
+							robot.sequence(function(){
+								height2 = domGeom.getMarginBox(w.domNode).h;
+							}, 500);
 
-								// Paste text, height should increase
-								doh.robot.keyPress("v", 500, modifier);
-								doh.robot.keyPress("v", 500, modifier);
-								doh.robot.sequence(d.getTestCallback(function(){
-									height3 = dojo.marginBox(w.domNode).h;
-									doh.t(height2 < height1, "height went from " + height1 + " to " + height2);
-									doh.t(height3 > height2, "height went from " + height2 + " to " + height3);
-								}), 500);
-							});
+							// Paste text, height should increase
+							robot.keyPress("v", 500, modifier);
+							robot.keyPress("v", 500, modifier);
+							robot.sequence(d.getTestCallback(function(){
+								height3 = domGeom.getMarginBox(w.domNode).h;
+								doh.t(height2 < height1, "height went from " + height1 + " to " + height2);
+								doh.t(height3 > height2, "height went from " + height2 + " to " + height3);
+							}), 500);
 
 							return d;
 						}
@@ -173,35 +174,35 @@
 
 				]);
 
-				doh.register("miscellaneous", [
+				doh.register("maxLength",
 					{
 						name: "maxLength",
 						timeout: 10000,
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								ta = dijit.byId("simple"),
+								ta = registry.byId("simple"),
 								value1, value2, value3;
 
 							focusThenRun(ta, function(){
 								// Limit is 50, and there's text there already, so not all of
 								// these characters will fit; some should be rejected.
-								doh.robot.typeKeys('0123456789', 1, 2000);
-								doh.robot.sequence(function(){
+								robot.typeKeys('0123456789', 1, 2000);
+								robot.sequence(function(){
 									value1 = ta.get("value");
 								}, 500);
 
 								// Erase a character
-								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 100, {});
-								doh.robot.keyPress(dojo.keys.DELETE, 500, {});
-								doh.robot.sequence(function(){
+								robot.keyPress(keys.LEFT_ARROW, 100, {});
+								robot.keyPress(keys.DELETE, 500, {});
+								robot.sequence(function(){
 									value2 = ta.get("value");
 								}, 500);
 
 								// And try to type a new character, there should be room now,
 								// but just for one character
-								doh.robot.typeKeys('AB', 500, 400);
-								doh.robot.sequence(d.getTestCallback(function(){
+								robot.typeKeys('AB', 500, 400);
+								robot.sequence(d.getTestCallback(function(){
 									value3 = ta.get("value");
 									doh.is(50, value1.length, "should have stopped at 50, value is " + value1);
 									doh.is(49, value2.length, "erased a char, value is " + value2);
@@ -211,6 +212,16 @@
 
 							return d;
 						}
+					});
+				doh.register("min/max height", [
+					{
+						name: "initial height",
+						timeout: 1000,
+						runTest: function(){
+							var w = registry.byId("programmatic");
+							var h = w.domNode.offsetHeight;
+							doh.t(h > 64, "initial 3 line height " + h);
+						}
 					},
 					{
 						name: "#13166",
@@ -218,18 +229,97 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								w = dijit.byId("programmatic");
+								w = registry.byId("programmatic");
 
 							focusThenRun(w, function(){
-								var h = parseInt(w.domNode.style.height);
-								doh.robot.keyPress(" ", 500, {});
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.t(parseInt(w.domNode.style.height) >= h, "height should not shrink");
+								var h = w.domNode.offsetHeight;
+								robot.keyPress(keys.SPACE, 500, {});
+								robot.sequence(d.getTestCallback(function(){
+									doh.is(0, w.domNode.scrollTop, "no scroll");
+									doh.is(h, w.domNode.offsetHeight, "height should not change");
 								}), 500);
 							});
 
 							return d;
 						}
+					},
+					{
+						name: "less than max-height",
+						timeout: 5000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								w = registry.byId("programmatic");
+
+							var h = w.domNode.offsetHeight;
+							w.set('value', '');
+							doh.t(h > w.domNode.offsetHeight, "min-height is smaller than 3 lines: " + w.domNode.offsetHeight);
+							doh.t(40 < w.domNode.offsetHeight, "min-height is at least 1 line: " + w.domNode.offsetHeight);
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(0, w.domNode.scrollTop, "no scroll");
+								doh.t(h < w.domNode.offsetHeight, "height grew " + w.domNode.offsetHeight);
+								if(has("ie") <= 7){
+									doh.t(w.domNode.parentNode.parentNode.clientHeight >= w.domNode.parentNode.parentNode.scrollHeight, "non-scrolled parent");
+								}
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "more than max-height",
+						timeout: 5000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								w = registry.byId("programmatic");
+
+							var h = w.domNode.offsetHeight;
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.sequence(d.getTestCallback(function(){
+								if(has("ie") <= 6){
+									doh.is(0, w.domNode.scrollTop, "no scroll");
+									doh.t(w.domNode.parentNode.parentNode.clientHeight < w.domNode.parentNode.parentNode.scrollHeight, "scrolled parent");
+								}else{
+									doh.isNot(0, w.domNode.scrollTop, "scroll");
+								}
+								doh.t(h < w.domNode.offsetHeight, "height grew " + w.domNode.offsetHeight);
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "delete until less than max-height",
+						timeout: 5000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								w = registry.byId("programmatic");
+
+							var h = w.domNode.offsetHeight;
+							robot.keyPress(keys.BACKSPACE, 500, {});
+							robot.keyPress(keys.BACKSPACE, 500, {});
+							robot.keyPress(keys.BACKSPACE, 500, {});
+							robot.keyPress(keys.BACKSPACE, 500, {});
+							robot.keyPress(keys.BACKSPACE, 500, {});
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(0, w.domNode.scrollTop, "no scroll");
+								if(has("ie") <= 7){
+									doh.t(w.domNode.parentNode.parentNode.clientHeight >= w.domNode.parentNode.parentNode.scrollHeight, "non-scrolled parent");
+								}
+								doh.t(h > w.domNode.offsetHeight, "height shrank " + w.domNode.offsetHeight);
+							}), 500);
+
+							return d;
+						}
 					}
 
 				]);
diff --git a/dijit/tests/form/robot/TimeTextBox.html b/dijit/tests/form/robot/TimeTextBox.html
index 7454c19..e1ae369 100644
--- a/dijit/tests/form/robot/TimeTextBox.html
+++ b/dijit/tests/form/robot/TimeTextBox.html
@@ -12,24 +12,25 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 			dojo.require("dojo.date.stamp");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_TimeTextBox.html');
 
+				var w;
 				doh.register("keyboard", [
 					{
 						name: "select",
-						timeout: 6000,
+						timeout: 10000,
 						runTest: function(){
-							var d = new doh.Deferred(),
-								w = dijit.byId('q1');
+							var d = new doh.Deferred();
+
+							w = dijit.byId('q1');
 							dojo.global.formValue = null;
-	
+
 							// focus field... drop down shouldn't open yet
 							w.focus();
 							doh.robot.sequence(d.getTestErrback(function(){
@@ -43,17 +44,17 @@
 								var popup = dijit.byId('q1_popup');
 								doh.t(popup && isVisible(popup), "popup visible");
 							}), 500);
-	
+
 							// advance from 5:45PM to 6PM, and select
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
 							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-							
+
 							doh.robot.sequence(d.getTestErrback(function(){
 								var popup = dijit.byId('q1_popup');
-								doh.t(!popup || isHidden(popup), "popup hidden");
+								doh.t(!popup || isHidden(popup), "popup hidden again");
 
-								var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});	
-								doh.is(val, "T18:00:00", "6PM was selected");
+								var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});
+								doh.is("T18:00:00", val, "6PM was selected");
 
 								doh.is(null, dojo.global.formValue, "no form submit");
 							}), 500);
@@ -65,15 +66,19 @@
 							}), 500);
 
 							return d;
+						},
+						tearDown: function(){
+							// Even if test failed, make sure drop down is closed so it doesn't interfere w/next test
+							w.closeDropDown();
 						}
 					},
 					{
 						name: "select original value",
 						timeout: 6000,
 						runTest: function(){
-							var d = new doh.Deferred(),
-								w = dijit.byId('q1');
-	
+							var d = new doh.Deferred();
+
+							w = dijit.byId('q1');
 							dojo.global.formValue = null;
 
 							// focus field... drop down shouldn't open yet
@@ -89,15 +94,15 @@
 								var popup = dijit.byId('q1_popup');
 								doh.t(popup && isVisible(popup), "popup visible");
 							}), 500);
-	
+
 							// select the initial value
 							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
 							doh.robot.sequence(d.getTestErrback(function(){
 								var popup = dijit.byId('q1_popup');
-								doh.t(!popup || isHidden(popup), "popup hidden");
+								doh.t(!popup || isHidden(popup), "popup hidden again");
 
-								var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});	
-								doh.is(val, "T18:00:00", "6PM was selected (again)");
+								var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});
+								doh.is("T18:00:00", val, "6PM was selected (again)");
 
 								doh.is(null, dojo.global.formValue, "no form submit");
 							}), 500);
@@ -109,15 +114,19 @@
 							}), 500);
 
 							return d;
+						},
+						tearDown: function(){
+							// Even if test failed, make sure drop down is closed so it doesn't interfere w/next test
+							w.closeDropDown();
 						}
 					},
 					{
 						name: "cancel",
 						timeout: 6000,
 						runTest: function(){
-							var d = new doh.Deferred(),
-								w = dijit.byId('q1');
+							var d = new doh.Deferred();
 
+							w = dijit.byId('q1');
 							dojo.global.formValue = null;
 
 							// focus field... drop down shouldn't open yet
@@ -129,43 +138,47 @@
 
 							// open drop down
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 100, {}); // needed to prevent FF8 bug: reset on ESC
 							doh.robot.sequence(d.getTestErrback(function(){
 								var popup = dijit.byId('q1_popup');
 								doh.t(popup && isVisible(popup), "popup visible");
 							}), 500);
-	
+
 							// close drop down
 							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
-							
+
 							doh.robot.sequence(d.getTestCallback(function(){
 								var popup = dijit.byId('q1_popup');
-								doh.t(!popup || isHidden(popup), "popup hidden");
+								doh.t(!popup || isHidden(popup), "popup hidden again");
 
-								var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});	
-								doh.is(val, "T18:00:00", "same value as before");
+								var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});
+								doh.is("T18:00:00", val, "same value as before");
 							}), 500);
 							return d;
+						},
+						tearDown: function(){
+							// Even if test failed, make sure drop down is closed so it doesn't interfere w/next test
+							w.closeDropDown();
 						}
 					},
 					{
 						name: "partial input",
-						timeout: 6000,
+						timeout: 10000,
 						setUp: function(){
 							// clear the field
-							var w = dijit.byId('q2');
+							w = dijit.byId('q2');
 							w.set('value', null, false);
 						},
 						runTest: function(){
-							var d = new doh.Deferred(),
-								w = dijit.byId('q2');
-	
+							var d = new doh.Deferred();
+
 							// focus field... drop down shouldn't open yet
 							w.focus();
 							doh.robot.sequence(d.getTestErrback(function(){
 								var popup = dijit.byId('q2_popup');
 								doh.t(!popup || isHidden(popup), "popup hidden");
 							}), 1000);
-		
+
 							// do partial input
 							doh.robot.typeKeys('12', 500, 400);
 
@@ -176,7 +189,7 @@
 								doh.t(w._isValidSubset(), 'partially valid');
 								doh.isNot("Error", w.state, 'no error shown');
 
-								// typing caused drop down to open							
+								// typing caused drop down to open
 								var popup = dijit.byId('q2_popup');
 								doh.t(popup && isVisible(popup), "popup visible");
 
@@ -194,16 +207,121 @@
 								doh.is("12:45 PM", innerText(children[7]));
 							}), 1000);
 
+							// Setup handler to fire when TAB keypress below fires
+							doh.robot.sequence(function(){
+								onFocus(d.getTestCallback(function(){
+									var popup = dijit.byId('q2_popup');
+									doh.t(!popup || isHidden(popup), "popup hidden again");
+
+									doh.is("q3", dojo.global.dijit.focus.curNode.id, "tab moved to next input widget");
+								}));
+							}, 0);
+
 							// tab away to close drop down
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+
+							return d;
+						},
+						tearDown: function(){
+							// Even if test failed, make sure drop down is closed so it doesn't interfere w/next test
+							w.closeDropDown();
+						}
+					},
+					{
+						name: "invalid input",
+						timeout: 10000,
+						setUp: function(){
+							// clear the field
+							w = dijit.byId('q2');
+							w.set('value', null, false);
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// focus field... drop down shouldn't open yet
+							w.focus();
+
+							// do partial input
+							doh.robot.typeKeys('12a', 500, 600);
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// partial input shouldn't be flagged as an error, because probably
+								// the user just hasn't finished typing yet
+								doh.f(w.isValid(), 'fully invalid');
+								doh.f(w._isValidSubset(), 'subset invalid');
+								doh.is("Error", w.state, 'error shown');
+
+								// typing caused drop down to open
+								var popup = dijit.byId('q2_popup');
+								doh.t(popup && isVisible(popup), "popup visible");
+
+								// illegal pattern, so all entries are in the drop down
+								var children = dojo.query(".dijitTimePickerItem", popup.domNode);
+								doh.is(96, children.length, "# of items in drop down");
+							}), 1000);
+
+							// tab away to close drop down
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+
 							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(w._opened, "drop down closed");
+							}), 500);
+
+							return d;
+						},
+						tearDown: function(){
+							// Even if test failed, make sure drop down is closed so it doesn't interfere w/next test
+							w.closeDropDown();
+						}
+					},
+					{
+						name: "corrected invalid input",
+						timeout: 10000,
+						setUp: function(){
+							// clear the field
+							w = dijit.byId('q2');
+							w.set('value', null, false);
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// focus field... drop down shouldn't open yet
+							w.focus();
+
+							// do partial input
+							doh.robot.typeKeys('12a', 500, 600);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// partial input shouldn't be flagged as an error, because probably
+								// the user just hasn't finished typing yet
+								doh.f(w.isValid(), 'fully invalid');
+								doh.t(w._isValidSubset(), 'subset valid');
+								doh.is("Error", w.state, 'error shown');
+
+								// typing caused drop down to open
 								var popup = dijit.byId('q2_popup');
-								doh.t(!popup || isHidden(popup), "popup hidden");
-								
-								doh.is("q3", dojo.global.dijit.focus.curNode.id, "tab moved to next input widget");
+								doh.t(popup && isVisible(popup), "popup visible");
+
+								// drop down list should be filtered to times starting with 12:,
+								// and they should appear in chronological order
+								var children = dojo.query(".dijitTimePickerItem", popup.domNode);
+								doh.is(8, children.length, "# of items in drop down");
 							}), 1000);
 
+							// tab away to close drop down
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(w._opened, "drop down closed");
+							}), 500);
+
 							return d;
+						},
+						tearDown: function(){
+							// Even if test failed, make sure drop down is closed so it doesn't interfere w/next test
+							w.closeDropDown();
+							console.log("closed drop down for " + w.id)
 						}
 					}
 				]);
@@ -215,53 +333,41 @@
 						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								w = dijit.byId('q1'),
+								popup,
 								toClick;
-	
-							// click field, thus opening drop down
-							doh.robot.mouseMoveAt(w.domNode, 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-	
-							doh.robot.sequence(d.getTestErrback(function(){
-								var popup = dijit.byId('q1_popup');
-								doh.t(popup && isVisible(popup), "popup visible");
+							w = dijit.byId('q1');
+
+							handler = w.connect(w, 'openDropDown', d.getTestErrback(function(){
+								console.log("drop down opened");
+								w.disconnect(handler);
+								popup = dijit.byId('q1_popup');
+								var wasVisible = popup && isVisible(popup);
 								toClick = dojo.query(".dijitTimePickerItemInner:contains(6:45)", popup.domNode);
-								doh.is(1, toClick.length, "found 6:45 in drop down");
-							}), 500);
 
-							// click 6:45, thus selecting it and closing drop down
-							doh.robot.mouseMoveAt(function(){return toClick[0]; }, 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								var popup = dijit.byId('q1_popup');
-								doh.t(!popup || isHidden(popup), "popup hidden");
-								var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});	
-								doh.is(val, "T18:45:00", "should be 6:45PM");
-							}), 500);
-							return d;
-						}
-					},
-					{
-						name: "constraints propagation",
-						timeout: 5000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							q5 = dijit.byId('q5');
-							handler = q5.connect(q5.focusNode, 'onmouseup', d.getTestCallback(function(){
-								// drop down list should be filtered to 1 hour and 15 minute increments
-								var popup = dijit.byId("q5_popup"),
-									children = dojo.query(".dijitTimePickerItem", popup.domNode);
-								doh.is(4, children.length, "# of items in drop down");
+								handler = w.connect(w, 'closeDropDown', d.getTestCallback(function(){
+									console.log("drop down closed");
+									doh.t(wasVisible, "popup visible");
+									doh.is(2, toClick.length, "found 6:45am and 6:45pm in drop down");
+									popup = dijit.byId('q1_popup');
+									doh.t(!popup || isHidden(popup), "popup hidden");
+									var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});
+									doh.is("T18:45:00", val, "should be 6:45PM");
+								}));
+
+								// click 6:45pm, thus selecting it and closing drop down
+								doh.robot.mouseMoveAt(function(){return toClick[1]; }, 500, 1);
+								doh.robot.mouseClick({left:true}, 500);
 							}));
-							// click field, thus opening drop down
-							doh.robot.mouseMoveAt(q5.focusNode, 500, 1);
+
+							// click down arrow, opening drop down
+							doh.robot.mouseMoveAt(w._buttonNode, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
+
 							return d;
 						},
 						tearDown: function(){
-							q5.disconnect(handler);
-							q5.closeDropDown();
+							w.disconnect(handler);
+							w.closeDropDown();
 						}
 					}
 				]);
@@ -274,18 +380,18 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							q20 = dijit.byId('q20');
-	
+
 							q20.set('disabled',true);
-							// click field, thus opening drop down
-							doh.robot.mouseMoveAt(q20.domNode, 500, 1);
+							// click down arrow, but disabled so won't open drop down
+							doh.robot.mouseMoveAt(q20._buttonNode, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.typeKeys('1', 500, 200);
-	
+
 							doh.robot.sequence(d.getTestCallback(function(){
 								var popup = dijit.byId('q20_popup');
 								doh.t(!popup || isHidden(popup), "popup hidden");
-								var val = dojo.date.stamp.toISOString(q20.get('value'), {selector: "time"});	
-								doh.is(val, "T17:45:00", "should be 5:45PM");
+								var val = dojo.date.stamp.toISOString(q20.get('value'), {selector: "time"});
+								doh.is("T17:45:00", val, "should be 5:45PM");
 							}), 1000);
 							return d;
 						},
@@ -300,18 +406,18 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							q20 = dijit.byId('q20');
-	
+
 							q20.set('readOnly',true);
-							// click field, thus opening drop down
-							doh.robot.mouseMoveAt(q20.domNode, 500, 1);
+							// click down arrow, but readonly so won't open drop down
+							doh.robot.mouseMoveAt(q20._buttonNode, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.typeKeys('1', 500, 200);
-	
+
 							doh.robot.sequence(d.getTestCallback(function(){
 								var popup = dijit.byId('q20_popup');
 								doh.t(!popup || isHidden(popup), "popup hidden");
-								var val = dojo.date.stamp.toISOString(q20.get('value'), {selector: "time"});	
-								doh.is(val, "T17:45:00", "should be 5:45PM");
+								var val = dojo.date.stamp.toISOString(q20.get('value'), {selector: "time"});
+								doh.is("T17:45:00", val, "should be 5:45PM");
 							}), 1000);
 							return d;
 						},
diff --git a/dijit/tests/form/robot/ValidationTextBox.html b/dijit/tests/form/robot/ValidationTextBox.html
index c0cd782..92e8c5d 100644
--- a/dijit/tests/form/robot/ValidationTextBox.html
+++ b/dijit/tests/form/robot/ValidationTextBox.html
@@ -11,178 +11,15 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<script type="text/javascript" src="../../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
-
-			function fixNbsp(val){
-				return typeof val == "string" ? val.replace(/\xA0/g, " ") : val;
-			}
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_validate.html');
 
-				// Test initial conditions
-				doh.register("initial conditions", {
-					name: "initial conditions",
-					runTest: function(){
-						var form1 = dojo.byId("form1");
-						
-						doh.is("Testing Testing", form1.firstname.value, "firstname");
-						doh.is("not fired yet!", dojo.byId("oc1").value, "firstname onchange");
-
-						doh.is("TESTING TESTING", form1.lastname.value, "lastname");
-						
-						doh.is("", form1.age.value, "age");
-						doh.is("not fired yet!", dojo.byId("oc3").value, "age onchange");
-						
-						doh.is("", form1.occupation.value, "occupation");
-						
-						doh.is("3000", form1.elevation.value, "elevation");
-						doh.is("3,000", dojo.byId("q05").value, "elevation display value");
-						doh.is("not fired yet!", dojo.byId("oc5").value, "elevation onchange");
-						
-						doh.is("54775.53", form1.income1.value, "income1");
-						doh.is("$54,775.53", dojo.byId("q08").value, "income1 display value");
-						doh.is("not fired yet!", dojo.byId("oc8").value, "income1 onchange");
-
-						doh.is("54775.53", form1.income2.value, "income2");
-						doh.is("€54,775.53", dojo.byId("q08eur").value, "income2 display value");
-
-						doh.is("someTestString", form1.phone.value, "phone");
-						doh.is("", form1.password.value, "password");
-						doh.is("", form1.ticket1651.value, "ticket1651");
-						doh.is("cannot type here", form1.readOnly.value, "readonly");
-						doh.is("cannot type here", form1.disabled.value, "disabled");
-					}
-				});
-
-				var watchHandle, onChangeHandle;
-
-				function setTest(testName, textbox, setDict, watchExpected, unchangedExpected, isValid, onChangeExpected){
-					// summary:
-					//		Generate test to call set("value", ...) and check response
-					// textbox: String
-					//		id of TextBox widget
-					// setDict: Dictionary
-					//		Value to pass to textbox.set(), such as {value: "123"} or {displayedValue: "1,234"}.
-					// watchExpected: Dictionary
-					//		Expected changes in state of TextBox, such as
-					//			{value: 1234, displayedValue: "1,234"}
-					//		Checks that watch() returns these values.
-					//		Also checks that textbox is actually displaying displayedValue
-					// unchangedExpected: Dictionary
-					//		Attributes of textbox that shouldn't change/be reported by watch(), and their values
-					//			{value: 1234, displayedValue: "1,234"}
-					//		Checks that watch() returns these values.
-					//		Also checks that textbox is actually displaying displayedValue
-					// isValid: Boolean
-					//		Checks return of textbox.isValid().   TODO: this should be watchable.
-					// onChangeExpected:
-					//		Check that onChange reports this value
-
-
-					return {
-						name: testName,
-						timeout: 1000,
-						runTest: function(){
-
-							textbox = dijit.byId(textbox);
-		
-							// expectedState is a combination of the attributes that we expect to change
-							// and the attributes that we expect not to change
-							var expectedState = dojo.delegate(watchExpected, unchangedExpected);
-
-							// save all notifications from watch()		
-							var watchActual = {};
-							watchHandle = textbox.watch(function(attr, oldVal, newVal){
-									console.log(textbox.id + ": " + attr + ": " + oldVal + " --> " + newVal);
-									watchActual[attr] = fixNbsp(newVal);
-								});
-
-							// and monitor onChange() calls too
-							var onChangeActual;
-							if(onChangeExpected){
-								onChangeHandle = dojo.connect(textbox, "onChange", function(newVal){
-									onChangeActual = fixNbsp(newVal);
-								});
-							}
-
-							// do the set
-							textbox.set(setDict);
-							
-							doh.is(expectedState.displayedValue, fixNbsp(textbox.focusNode.value), "focusNode.value");
-		
-							doh.is(isValid, textbox.isValid(), "isValid()");
-		
-							var d = new doh.Deferred();
-		
-							doh.robot.sequence(d.getTestCallback(function(){
-								// test that onChange() was called correctly
-								if(onChangeExpected){
-									doh.is(onChangeExpected, onChangeActual, "onChange()");
-								}
-								
-								// check that watch() callbacks were called
-								for(attr in watchExpected){
-									doh.t(attr in watchActual, "watch(" + attr + ") fired");
-									doh.is(watchExpected[attr], watchActual[attr], "watch(" + attr + ")");
-									doh.is(typeof watchExpected[attr], typeof watchActual[attr], "typeof watch(" + attr + ")")
-								}
-		
-								// check that direct get(...) calls are also working, for both the attributes
-								// that were supposed to change and the attributes that weren't supposed to change
-								for(attr in expectedState){
-									doh.is(expectedState[attr], fixNbsp(textbox.get(attr)), "get(" + attr + ")");
-									doh.is(typeof expectedState[attr], typeof textbox.get(attr), "typeof get(" + attr + ")")
-								}
-
-								// check that watch() didn't report attributes as changed when they didn't change
-								for(attr in unchangedExpected){
-									doh.f(attr in watchActual, attr + " shouldn't have been reported as changed by watch " + 
-										watchActual[attr]);
-								}
-							}), 50);		
-		
-							return d;
-						},
-						tearDown: function(){
-							watchHandle.unwatch();
-							watchHandle = null;
-							if(onChangeHandle){
-								dojo.disconnect(onChangeHandle);
-								onChangeHandle = null;
-							}
-						}
-					};
-				}
-
-				doh.register("set('value')", [
-					// test valid and invalid settings of value
-					setTest("valid_max", 'q03', {value: 120}, {value: 120, displayedValue: "120"}, {}, true),
-					setTest("out_of_range_max",'q03', {value: 121}, {value: 121, displayedValue: "121", state: "Error"}, {}, false),
-					setTest("valid_min", 'q03', {value: 0}, {value: 0, displayedValue: "0", state: ""}, {}, true),
-					setTest("out_of_range_min", 'q03', {value: -1}, {value: -1, displayedValue: "-1", state: "Error"}, {}, false),
-					setTest("invalid", 'q03', {value: 'two'}, {value: undefined, displayedValue: 'two'}, {}, false),
-					setTest("null_required", 'q03', {required: true, value: null},
-							{required: true, value: NaN, displayedValue: ''}, {state: "Error"}, false),	
-					setTest("null_notrequired", 'q03', {required: false, value: null}, {}, {displayedValue: ''}, true),
-
-					// test formatting of value vs. displayed value
-					setTest("number format", 'q05', {value: 1234}, {value: 1234, displayedValue: "1,234"}, {}, true),
-					setTest("currency format", 'q08', {value: 1234}, {value: 1234, displayedValue: "$1,234.00"}, {}, true)
-				]);
-
-				doh.register("set('displayedValue')", [
-					// test formatting of value vs. displayed value, in reverse
-					setTest("number format", 'q05', {displayedValue: "4,321"}, {value: 4321, displayedValue: "4,321"}, {}, true),
-					setTest("european currency format", 'q08eurde', {displayedValue: "4.321,98"},
-						{value: 4321.98, displayedValue: "4.321,98 €"}, {}, true)
-				]);
-
 				doh.register("intermediatechanges", {
 					name: "valid",
 					textbox: "q01",
@@ -484,7 +321,6 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								// comma should disappear on click, value shouldn't change
 								doh.is('54775.53', this.textbox.focusNode.value, "focusNode.value");
@@ -569,7 +405,6 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
 							doh.robot.typeKeys('123', 1000, 600);
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								doh.is('123', this.textbox.focusNode.value, "focusNode.value");
@@ -590,7 +425,6 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
 							doh.robot.typeKeys('123.0', 1000, 1000);
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								doh.is('123.0', this.textbox.focusNode.value, "focusNode.value");
@@ -611,7 +445,6 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
 							doh.robot.typeKeys('123.000', 1000, 1400);
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								doh.is('123.000', this.textbox.focusNode.value, "focusNode.value");
@@ -632,7 +465,6 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
 							doh.robot.typeKeys('-123.00', 1000, 1400);
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								doh.is('-123.00', this.textbox.focusNode.value, "focusNode.value");
@@ -653,13 +485,12 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
 							doh.robot.typeKeys('($123.00)', 1000, 1600);
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								doh.is('($123.00)', this.textbox.focusNode.value, "focusNode.value");
 								doh.is(-123, this.textbox.get('value'), "get('value')");
 								doh.t(this.textbox.isValid(), "isValid()");
-							})), 1500);
+							})), 2000);
 							return d;
 						}
 					},
@@ -674,7 +505,6 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
 							doh.robot.typeKeys('-123.45', 1000, 1400);
 
 							var textbox = this.textbox;
@@ -702,7 +532,6 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
 							doh.robot.typeKeys('($123.45)', 1000, 1800);
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
@@ -725,7 +554,6 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
 							doh.robot.typeKeys('1.23e0', 1000, 1200);
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
@@ -1105,7 +933,7 @@
 							
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.is("", textWidget.get('value'), "get('value')");
-								doh.is("none", textWidget._phspan.style.display, "_phspan.style.display");
+								doh.isNot("none", textWidget._phspan.style.display, "_phspan.style.display");
 								
 								doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
 								doh.robot.sequence(d.getTestCallback(function(){
@@ -1130,7 +958,7 @@
 							
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.is("", textWidget.get('value'), "get('value')");
-								doh.is("none", textWidget._phspan.style.display, "_phspan.style.display 1");
+								doh.isNot("none", textWidget._phspan.style.display, "_phspan.style.display 1");
 								
 								doh.robot.typeKeys('new', 0, 600);
 								doh.robot.sequence(d.getTestCallback(function(){
@@ -1151,13 +979,13 @@
 							textWidget.set('value','');
 							
 							doh.is("", textWidget.get('value'), "get('value') 1");
-							doh.is("none", textWidget._phspan.style.display, "_phspan.style.display");
+							doh.isNot("none", textWidget._phspan.style.display, "_phspan.style.display");
 							
 							textWidget.set('value','abc');
 							textWidget.reset();
 							
 							doh.is("", textWidget.get('value'), "get('value') 2");
-							doh.is("none", textWidget._phspan.style.display, "_phspan.style.display 1");
+							doh.isNot("none", textWidget._phspan.style.display, "_phspan.style.display 1");
 							
 							var handler = textWidget.connect(textWidget, '_onBlur',
 								function(){
@@ -1185,57 +1013,6 @@
 					}
 				]);
 
-				doh.register("#11889", [
-					{
-						name: "non-focused places:5",
-						timeout: 2000,
-						textbox: "q05",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('constraints', { places: 5 });
-							this.textbox.set('editOptions', { places: "2,4" });
-						},
-						runTest: function(){
-							this.textbox.set('value', 1.625);
-							doh.is(1.625, this.textbox.get('value'), 'numeric value is unchanged');
-							doh.is('1.62500', this.textbox.get('displayedValue'), 'formatted displayed value');
-							doh.t(true, this.textbox.isValid(false), 'nonfocused is valid');
-						}
-					},
-					{
-						name: "focused places:2,4. blur to places:5",
-						timeout: 2000,
-						textbox: "q05",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('constraints', { places: 5 });
-							this.textbox.set('editOptions', { places: "2,4" });
-							this.textbox.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var textbox = this.textbox;
-							textbox.set('value', 1.125);
-
-							doh.is(1.125, textbox.get('value'), 'numeric value is unchanged');
-							doh.is('1.125', textbox.get('displayedValue'), 'formatted displayed value');
-							doh.t(true, textbox.isValid(true), 'focused is valid');
-
-							var handler = textbox.connect(textbox, '_onBlur',
-								function(){
-									textbox.disconnect(handler);
-									setTimeout(d.getTestCallback(function(){
-										doh.is(1.125, textbox.get('value'), 'numeric value is unchanged');
-										doh.is('1.12500', textbox.get('displayedValue'), 'formatted displayed value');
-										doh.t(true, textbox.isValid(false), 'nonfocused is valid');
-									}), 150);
-								});
-							dojo.byId("q01").focus();
-							return d;
-						}
-					}
-				]);
-
 				function testOn(evt, widget, deferred, callback, delay){
 					var handler = widget.connect(widget.focusNode, "on"+evt,
 						function(){
@@ -1326,36 +1103,6 @@
 					}
 				]);
 
-				doh.register("validation in dialog", [
-					function showDialog(){
-						// Show dialog, returning Deferred that fires when show dialog is finished.
-						// Before showing, focus the open button, so that Dialog knows where to return focus to.
-						dijit.byId("dlgOpenBtn").focus();
-						return dijit.byId("dlg").show();
-					},
-					function enterInvalidValue(){
-						// Entering invalid value should make validation tooltip appear
-						var d = new doh.Deferred();
-						dijit.byId("dlgNTB").set("value", "invalid");
-						dijit.byId("dlgNTB").focus();
-						setTimeout(d.getTestCallback(function(){
-							masterTT = dojo.global.dijit._masterTT;
-							doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
-						}), 300);
-						return d;
-					},
-					function hideDialog(){
-						// Hiding the dialog should make the validation tooltip disappear
-						var d = new doh.Deferred();
-						dijit.byId("dlg").hide().then(function(){
-							setTimeout(d.getTestCallback(function(){
-								doh.t(isHidden(masterTT.domNode), "tooltip hidden");
-							}), 300);
-						});
-						return d;
-					}
-				]);
-
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/form/robot/_autoComplete_a11y.html b/dijit/tests/form/robot/_autoComplete_a11y.html
index 5ae5f58..90fb759 100644
--- a/dijit/tests/form/robot/_autoComplete_a11y.html
+++ b/dijit/tests/form/robot/_autoComplete_a11y.html
@@ -11,11 +11,11 @@
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-	<script type="text/javascript" src="../../helpers.js"></script>
-
 	<script type="text/javascript">
 		dojo.require("dijit.robotx");
 		dojo.require("dojo.aspect");
+		dojo.require("dijit.tests.helpers");	// functions to help test
+		dojo.require("dijit.form._TextBoxMixin");	// selectInputText
 
 		// TODO: provide URL toggle for FilteringSelect
 		var testWidget = "dijit.form.ComboBox";
@@ -401,7 +401,7 @@
 				}
 			]);
 
-			// Test that enter key submits the form, but only when the drop down is closed
+			// Test that enter key submits the form, but only when nothing is selected in the drop down
 			doh.register("enter key", {
 				timeout:60000,
 				name:"submit",
@@ -425,6 +425,7 @@
 					}), 500);
 
 					// Enter key should select value and close drop down but not submit form
+					doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); // highlight value
 					doh.robot.keyPress(dojo.keys.ENTER, 500);
 					doh.robot.sequence(d.getTestErrback(function(){
 						var popup = dijit.byId('setvaluetest_popup');
@@ -446,7 +447,7 @@
 
 			doh.register("drop down navigation / keyboard", [
 				// Select a value from the drop down using the keyboard,
-				// used "more choices" button to page as necessary
+				// use "more choices" button to page as necessary
 				{
 					timeout:60000,
 					name:"setvaluetest_a11y",
@@ -683,7 +684,7 @@
 						doh.robot.typeKeys("o", 300, 100); // 300ms > searchDelay, so C* query has been sent (but not yet returned results) when the o is typed
 
 						doh.robot.sequence(d.getTestCallback(function(){
-							// The query "C*" should be canceled when "Co*" is started
+							// The query "c*" should be canceled when "co*" is started
 							var log = dojo.global.slowStateStore.log;
 							doh.is(4, log.length, "4 events on data store");
 							doh.is("start c*", log[0].type + " " + log[0].query.name);
@@ -719,11 +720,11 @@
 						var combo = dijit.byId("slow");
 
 						dojo.global.formSubmitted = false;
-						combo.focusNode.focus();
-						doh.robot.sequence(function(){ combo.set("value", null); }, 1000, 100); // wait for focus
+						dijit.form._TextBoxMixin.selectInputText(combo.focusNode);
 
 						// Start to filter drop down list to entries starting with "Co"
-						doh.robot.typeKeys("Co", 500, 100);
+						doh.robot.typeKeys("C", 500, 0);
+						doh.robot.typeKeys("o", 300, 0); // 300ms > searchDelay, so C* query has been sent (but not yet returned results) when the o is typed
 
 						// But then hit ENTER after we've started the query to the data store, but
 						// before the data store returns query results... that should cancel the query.
@@ -732,20 +733,14 @@
 						doh.robot.sequence(d.getTestCallback(function(){
 							var log = dojo.global.slowStateStore.log;
 							var len = log.length;
-							if(!isComboBox){
-								doh.is(6, len, "query was issued for 'Co' but canceled");
-								doh.is("cancel ", log[1].type + " " + log[1].query.name);
-								doh.is("cancel Co*", log[3].type + " " + log[3].query.name);
-								doh.is("start Co", log[4].type + " " + log[4].query.name);	// trying to lookup ID for item named "co"
-								doh.is("end Co", log[5].type + " " + log[5].query.name);
-
-								// also, form should not have submitted because the FilteringSelect
-								// is still trying to fill in it's item value
-								doh.f(dojo.global.formSubmitted, "form not submitted");
-							}else{ // this will look more like the IF block above once #6022 is committed
-								doh.is(2, len, "query was issued for 'Co' but canceled");
-								doh.is("cancel Co*", log[1].type + " " + log[1].query.name);
-							}
+							doh.t(len >= 4, "log length " + len);
+							doh.is("start C*", log[0].type + " " + log[0].query.name);
+							doh.is("cancel C*", log[1].type + " " + log[1].query.name);
+							doh.is("start Co*", log[2].type + " " + log[2].query.name);
+							doh.is("cancel Co*", log[3].type + " " + log[3].query.name);
+
+							// also, form SHOULD have submitted because no popup was visible
+							doh.t(dojo.global.formSubmitted, "form submitted");
 
 							var list = dojo.byId("slow_popup");
 							doh.t(!list || isHidden(list), "drop down is *not* visible");
@@ -775,20 +770,24 @@
 
 				// Test that you can't focus a disabled combobox
 				{
-					timeout:60000,
+					timeout: 5000,
 					name:"tab over disabled elements",
 					runTest: function(){
 						var d = new doh.Deferred();
 
 						dojo.byId("datatestDijit").focus();
-						doh.is("datatestDijit", dojo.global.dijit.focus.curNode.id, "focused on elem before disabled combo");
+
+						doh.robot.sequence(d.getTestErrback(function(){
+							// use sequence because focus on IE9+ is asynchronous
+							doh.is("datatestDijit", dojo.global.dijit.focus.curNode.id, "focused on elem before disabled combo");
+						}), 100);
 
 						// Tab over the disabled ComboBox
-						doh.robot.keyPress(dojo.keys.TAB, 1000);
+						doh.robot.keyPress(dojo.keys.TAB, 100);
 
 						doh.robot.sequence(d.getTestCallback(function(){
 							doh.is("combobox4", dojo.global.dijit.focus.curNode.id, "focused on 'enable' button after disabled combo");
-						}), 1000);
+						}), 200);
 
 						return d;
 					}
@@ -813,21 +812,56 @@
 
 			doh.register("specialchars", [
 				{
-					timeout:60000,
+					timeout:10000,
 					name:"specialchars_type",
 					combo:"specialchars",
 					runTest:function(){
 						return robot_typeValue(dijit.byId(this.combo), "sticks & stones", isComboBox? undefined : "sticks");
 					}
 				},
-
 				{
-					timeout:60000,
+					timeout:10000,
 					name:"specialchars_a11y",
 					combo:"specialchars",
 					runTest:function(){
 						return robot_a11ySelectValue(dijit.byId(this.combo), "more\\less", isComboBox? undefined : "more");
 					}
+				},
+				{
+					timeout:10000,
+					name:"specialchars_escape",
+					combo:"specialchars",
+					runTest:function(){
+						var combo = dijit.byId(this.combo);
+						combo.focusNode.focus();
+						doh.robot.sequence(function(){ combo.set("value", null); }, 1000);
+						var d = new doh.Deferred();
+						doh.robot.typeKeys("3 *", 500, 600);
+						doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
+						doh.robot.sequence(d.getTestCallback(function(){
+							doh.is("3 *", combo.focusNode.value);
+						}), 500);
+						return d;
+					}
+				},
+				{
+					timeout:10000,
+					name:"specialchars_highlight",
+					combo:"specialchars",
+					runTest:function(){
+						var combo = dijit.byId(this.combo);
+						combo.queryExpr = '*${0}*';
+						combo.focusNode.focus();
+						doh.robot.sequence(function(){ combo.set("value", null); }, 500);
+						var d = new doh.Deferred();
+						doh.robot.typeKeys("t", 1, 100);
+						doh.robot.sequence(d.getTestCallback(function(){
+							var item = findMenuItem(combo, 'riches to');
+							doh.t(item, 'item "rags --> riches to" should be visible');
+							doh.is('rags --> riches <>t<>o',item.innerHTML.replace(/<[^>]*>/g,'<>'), '"t" in "to" should be highlighted');
+						}), 1000, 500);
+						return d;
+					}
 				}
 			]);
 
@@ -845,16 +879,46 @@
 				},
 
 				{
-					timeout:60000,
+					timeout:20000,
 					name:"japanese_type",
 					runTest:function(){
-						var d = new doh.Deferred(),
+						var	d = new doh.Deferred(),
+							s0 = null,
+							s1 = null,
+							s2 = null,
+							s3 = null,
+							s4 = null,
+							s5 = null,
 							combo = dijit.byId("japanese");
 
 						combo.focusNode.focus();
 
 						doh.robot.keyPress(dojo.keys.END, 1000);
+
+						doh.robot.typeKeys("x", 500, 200);
+						doh.robot.sequence(function(){
+							s0 = combo.state;
+						}, 500);
 						doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
+						doh.robot.sequence(function(){
+							s1 = combo.state;
+						}, 500);
+						doh.robot.typeKeys("xx", 500, 400);
+						doh.robot.sequence(function(){
+							s2 = combo.state;
+						}, 500);
+						doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
+						doh.robot.sequence(function(){
+							s3 = combo.state;
+						}, 500);
+						doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
+						doh.robot.sequence(function(){
+							s4 = combo.state;
+						}, 500);
+						doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
+						doh.robot.sequence(function(){
+							s5 = combo.state;
+						}, 500);
 						doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
 						doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
 						doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
@@ -862,20 +926,52 @@
 						doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
 						doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
 						doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
-						doh.robot.keyPress('x', 500, {ctrl:true});
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
 						doh.robot.keyPress(dojo.keys.ENTER, 500);
 						doh.robot.sequence(dojo.hitch(this, function(){
+							if(!isComboBox){
+								doh.is("Error", s0, "s0");
+								doh.is("Incomplete", s1, "s1");
+								doh.is("Error", s2, "s2");
+								doh.is("Error", s3, "s3");
+								doh.is("Incomplete", s4, "s4");
+								doh.is("Incomplete", s5, "s5");
+							}
 							if(combo.get("value") == (isComboBox?"\u6771\u897F (Touzai)":"touzai") && combo.focusNode.value=="\u6771\u897F (Touzai)"){
 								d.callback(true);
 							}else{
 								d.errback(combo.id+" was supposed to have a value of "+(isComboBox?"\u6771\u897F (Touzai)":"touzai")+". Text is "+combo.focusNode.value+", value is "+combo.get("value"));
 							}
-						}), 900);
+						}), 1000);
 						return d;
 					}
 				}
 			]);
 
+			doh.register("readOnly", [
+				{
+					timeout:5000,
+					name:"cannot type",
+					combo: "labelFunc",
+					runTest:function(){
+						var	d = new doh.Deferred(),
+							combo = dijit.byId(this.combo),
+							initVal = combo.get('value');
+						combo.set('readOnly', true);
+						combo.focus();
+						doh.robot.typeKeys("xz", 1000, 500);
+						doh.robot.sequence(d.getTestCallback(function(){
+							doh.t(combo.isValid(), 'isValid');
+							doh.is(initVal, combo.get('value'), 'changed from ' + initVal + ' to ' + combo.get('value'));
+						}), 500, 500);
+						return d;
+					},
+					tearDown:function(){
+						dijit.byId(this.combo).set("readOnly", false);
+					}
+				}
+			]);
+
 			// Labelfunc tests.   See also initial tests on "setvaluetest" ComboBox.
 			doh.register("labelFunc", [
 				{
@@ -1040,8 +1136,9 @@
 						combo.focusNode.focus();
 
 						// Show list, should be in reverse order
-						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);
-						for(var i=0; i < 14; i++){
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000); // wait for focus
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); // wait for dropdown to open
+						for(var i=1; i < 14; i++){
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 250); // down arrow and wrap twice
 						}
 						for(i=0; i < 4; i++){
@@ -1066,8 +1163,9 @@
 						combo.focusNode.focus();
 
 						// Show list, should be in reverse order
-						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);
-						for(var i=0; i < 14; i++){
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000); // wait for focus
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); // wait for dropdown to open
+						for(var i=1; i < 14; i++){
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 250); // down arrow and wrap twice
 						}
 						for(i=0; i < 5; i++){
@@ -1094,8 +1192,9 @@
 						combo.focusNode.focus();
 
 						// Show list, should be in reverse order
-						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);
-						for(var i=0; i < 5; i++){
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000); // wait for focus
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); // wait for dropdown to open
+						for(var i=1; i < 5; i++){
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 250); // down arrow to More choices
 						}
 						doh.robot.keyPress(dojo.keys.ENTER, 500); // select More choices
@@ -1464,6 +1563,19 @@
 				}
 			);
 
+			doh.register("custom class", [
+				// Select a value from the drop down using the keyboard,
+				// use "more choices" button to page as necessary
+				{
+					timeout: 60000,
+					name:" customstore_a11y",
+					combo: "subclass",
+					runTest: function(){
+						return robot_a11ySelectValue(dijit.byId(this.combo), "Delaware", isComboBox ? "Delaware" : "DE", "Delaware");
+					}
+				}
+			]);
+
 			doh.run();
 		});
 	</script>
diff --git a/dijit/tests/form/robot/_autoComplete_mouse.html b/dijit/tests/form/robot/_autoComplete_mouse.html
index f766c48..d6d57ad 100644
--- a/dijit/tests/form/robot/_autoComplete_mouse.html
+++ b/dijit/tests/form/robot/_autoComplete_mouse.html
@@ -11,11 +11,10 @@
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-	<script type="text/javascript" src="../../helpers.js"></script>
-
 	<script type="text/javascript">
 		dojo.require("dijit.robotx");
 		dojo.require("dojo.window");
+		dojo.require("dijit.tests.helpers");	// functions to help test
 
 		// TODO: provide URL toggle for FilteringSelect
 		var testWidget = "dijit.form.ComboBox";
@@ -464,76 +463,6 @@
 				}
 			]);
 			
-			doh.register("placeHolder", [
-				{
-					timeout: 6000,
-					name: "focus/blur",
-					combo: "placeholdertest",
-					setUp: function(){
-						combo = dijit.byId(this.combo);
-					},
-					runTest: function(){
-						var d = new doh.Deferred();
-						doh.is("", combo.get("value"), "value");
-						doh.is("", combo.get('displayedValue'), "displayedValue");
-						doh.is("Select a New England State", combo._phspan.innerHTML, "_phspan.innerHTML");
-						doh.isNot("none", combo._phspan.style.display, "_phspan.style.display 1");
-
-						doh.robot.mouseMoveAt(combo.focusNode, 0, 0);
-						doh.robot.mouseClick({left:true}, 500);
-
-						doh.robot.sequence(d.getTestErrback(function(){
-							doh.is("none", combo._phspan.style.display, "_phspan.style.display 2");
-						
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("", combo.get("value"), "value");
-								doh.is("", combo.get('displayedValue'), "displayedValue");
-								doh.isNot("none", combo._phspan.style.display, "_phspan.style.display 3");
-							}), 1000, 500);
-						}), 1500, 500);
-						return d;
-					},
-					tearDown: function(){
-						combo.closeDropDown();
-					}
-				},
-				{
-					timeout: 6000,
-					name: "select a value",
-					combo: "placeholdertest",
-					setUp: function(){
-						combo = dijit.byId(this.combo);
-					},
-					runTest: function(){
-						var d = new doh.Deferred(), value = isComboBox?'Connecticut':'ct';
-						combo.set("value", value);
-						doh.is(value, combo.get("value"), "selected Connecticut from drop down");
-
-						doh.robot.mouseMoveAt(combo.focusNode, 500, 0);
-						doh.robot.mouseClick({left:true}, 500);
-
-						doh.robot.sequence(d.getTestErrback(function(){
-							doh.is("none", combo._phspan.style.display, "_phspan.style.display 1");
-						
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(value, combo.get("value"), "value");
-								doh.is("none", combo._phspan.style.display, "_phspan.style.display 2");
-								doh.is('Connecticut', combo.textbox.value, "textbox.value 2");
-							}), 1000, 500);
-						}), 1000, 500);
-						return d;
-					},
-					tearDown: function(){
-						combo.closeDropDown();
-					}
-				}
-			]);
-
-
 			doh.run();
 		});
 	</script>
diff --git a/dijit/tests/form/robot/validationMessages.html b/dijit/tests/form/robot/validationMessages.html
index 89e3bb9..d25c3ad 100644
--- a/dijit/tests/form/robot/validationMessages.html
+++ b/dijit/tests/form/robot/validationMessages.html
@@ -75,7 +75,7 @@
 									runTest: function(){
 										var d = new doh.Deferred();
 										testOn('keyup', textbox, d, function(){
-											doh.is(!rangeBound, textbox.isValid(false), "isValid");
+											doh.is(!rangeBound, textbox.isValid(true), "isValid");
 											doh.is(rangeBound ? "Incomplete" : "", textbox.state, "state");
 											doh.is(rangeBound? promptMessage : "", tooltip, "tooltip");
 										});
@@ -89,7 +89,7 @@
 									runTest: function(){
 										var d = new doh.Deferred();
 										testOn('keyup', textbox, d, function(){
-											doh.is(true, textbox.isValid(false), "isValid");
+											doh.is(true, textbox.isValid(true), "isValid");
 											doh.is("", textbox.state, "state");
 											doh.is("", tooltip, "tooltip");
 										});
@@ -103,7 +103,7 @@
 									runTest: function(){
 										var d = new doh.Deferred();
 										testOn('keyup', textbox, d, function(){
-											doh.is(false, textbox.isValid(false), "isValid");
+											doh.is(false, textbox.isValid(true), "isValid");
 											doh.is("Error", textbox.state, "state");
 											doh.is(invalidMessage||promptMessage, tooltip, "tooltip");
 										});
@@ -117,7 +117,7 @@
 									runTest: function(){
 										var d = new doh.Deferred();
 										testOn('keyup', textbox, d, function(){
-											doh.is(true, textbox.isValid(false), "isValid");
+											doh.is(true, textbox.isValid(true), "isValid");
 											doh.is("", textbox.state, "state");
 											doh.is("", tooltip, "tooltip");
 										});
@@ -126,12 +126,125 @@
 									}
 								},
 								{
-									name: name + " delete last valid character",
+									name: name + " period",
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
 										testOn('keyup', textbox, d, function(){
-											doh.is(!rangeBound, textbox.isValid(false), "isValid");
+											// number.parse("12.", {fractional:[true,false], pattern:"#.#####"}) is valid
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.typeKeys(".", 0, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " invalid pre-fractional character",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(false, textbox.isValid(true), "isValid");
+											doh.is("Error", textbox.state, "state");
+											doh.is(invalidMessage||promptMessage, tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("a", 0, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " delete invalid pre-fractional character",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " valid fractional digit",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("1", 0, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " invalid fractional character",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(false, textbox.isValid(true), "isValid");
+											doh.is("Error", textbox.state, "state");
+											doh.is(invalidMessage||promptMessage, tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("a", 0, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " delete invalid fractional character",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " delete valid fractional digit",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " delete period",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " delete right-most valid character",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(!rangeBound, textbox.isValid(true), "isValid");
 											doh.is(rangeBound ? "Incomplete" : "", textbox.state, "state");
 											doh.is(rangeBound? promptMessage : "", tooltip, "tooltip");
 										});
@@ -140,7 +253,7 @@
 									}
 								},
 								{
-									name: name + " delete first valid character",
+									name: name + " delete remaining valid character",
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
@@ -258,7 +371,7 @@
 									runTest: function(){
 										var d = new doh.Deferred();
 										testOn('keyup', textbox, d, function(){
-											doh.is(!rangeBound, textbox.isValid(false), "isValid");
+											doh.is(!rangeBound, textbox.isValid(true), "isValid");
 											doh.is(rangeBound ? "Error" : "", textbox.state, "state");
 											doh.is(rangeBound? textbox.rangeMessage : "", tooltip, "tooltip");
 										});
@@ -277,7 +390,7 @@
 									runTest: function(){
 										var d = new doh.Deferred();
 										testOn('keyup', textbox, d, function(){
-											doh.is(true, textbox.isValid(false), "isValid");
+											doh.is(true, textbox.isValid(true), "isValid");
 											doh.is("", textbox.state, "state");
 											doh.is("", tooltip, "tooltip");
 
@@ -287,6 +400,118 @@
 									}
 								},
 								{
+									name: name + " period after refocus",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.typeKeys(".", 0, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " invalid pre-fractional character after refocus",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(false, textbox.isValid(true), "isValid");
+											doh.is("Error", textbox.state, "state");
+											doh.is(invalidMessage||promptMessage, tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("a", 0, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " delete invalid pre-fractional character after refocus",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " valid fractional digit after refocus",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("1", 0, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " invalid fractional character after refocus",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(false, textbox.isValid(true), "isValid");
+											doh.is("Error", textbox.state, "state");
+											doh.is(invalidMessage||promptMessage, tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("a", 0, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " delete invalid fractional character after refocus",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " delete valid fractional digit after refocus",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " delete period after refocus",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
+											doh.is(true, textbox.isValid(true), "isValid");
+											doh.is("", textbox.state, "state");
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
+										return d;
+									}
+								},
+								{
 									name: name + " delete last in-range character",
 									timeout: 2000,
 									runTest: function(){
@@ -305,7 +530,7 @@
 									runTest: function(){
 										var d = new doh.Deferred();
 										testOn('keyup', textbox, d, function(){
-											doh.is(!required, textbox.isValid(false), "isValid");
+											doh.is(!required, textbox.isValid(true), "isValid");
 											doh.is(required ? "Incomplete" : "", textbox.state, "state");
 											doh.is(promptMessage, tooltip, "tooltip");
 										});
@@ -354,131 +579,131 @@
 	</head>
 	<body>
 		<label for="t00000">not required, no min/max, no prompt message, no invalid message, no missing message</label><br>
-		<input id="t00000" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:false, promptMessage:"", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t00000" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:false, promptMessage:"", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t00000"/><br>
 
 		<label for="t00001">not required, no min/max, no prompt message, no invalid message, missing message</label><br>
-		<input id="t00001" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:false, promptMessage:"", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t00001" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:false, promptMessage:"", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t00001"/><br>
 
 		<label for="t00010">not required, no min/max, no prompt message, invalid message, no missing message</label><br>
-		<input id="t00010" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:false, promptMessage:"", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t00010" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:false, promptMessage:"", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t00010"/><br>
 
 		<label for="t00011">not required, no min/max, no prompt message, invalid message, missing message</label><br>
-		<input id="t00011" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:false, promptMessage:"", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t00011" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:false, promptMessage:"", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t00011"/><br>
 
 		<label for="t00100">not required, no min/max, prompt message, no invalid message, no missing message</label><br>
-		<input id="t00100" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:false, promptMessage:"p", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t00100" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:false, promptMessage:"p", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t00100"/><br>
 
 		<label for="t00101">not required, no min/max, prompt message, no invalid message, missing message</label><br>
-		<input id="t00101" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:false, promptMessage:"p", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t00101" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:false, promptMessage:"p", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t00101"/><br>
 
 		<label for="t00110">not required, no min/max, prompt message, invalid message, no missing message</label><br>
-		<input id="t00110" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:false, promptMessage:"p", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t00110" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:false, promptMessage:"p", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t00110"/><br>
 
 		<label for="t00111">not required, no min/max, prompt message, invalid message, missing message</label><br>
-		<input id="t00111" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:false, promptMessage:"p", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t00111" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:false, promptMessage:"p", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t00111"/><br>
 
 		<label for="t01000">required, no min/max, no prompt message, no invalid message, no missing message</label><br>
-		<input id="t01000" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:true, promptMessage:"", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t01000" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:true, promptMessage:"", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t01000"/><br>
 
 		<label for="t01001">required, no min/max, no prompt message, no invalid message, missing message</label><br>
-		<input id="t01001" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:true, promptMessage:"", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t01001" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:true, promptMessage:"", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t01001"/><br>
 
 		<label for="t01010">required, no min/max, no prompt message, invalid message, no missing message</label><br>
-		<input id="t01010" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:true, promptMessage:"", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t01010" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:true, promptMessage:"", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t01010"/><br>
 
 		<label for="t01011">required, no min/max, no prompt message, invalid message, missing message</label><br>
-		<input id="t01011" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:true, promptMessage:"", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t01011" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:true, promptMessage:"", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t01011"/><br>
 
 		<label for="t01100">required, no min/max, prompt message, no invalid message, no missing message</label><br>
-		<input id="t01100" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:true, promptMessage:"p", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t01100" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:true, promptMessage:"p", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t01100"/><br>
 
 		<label for="t01101">required, no min/max, prompt message, no invalid message, missing message</label><br>
-		<input id="t01101" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:true, promptMessage:"p", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t01101" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:true, promptMessage:"p", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t01101"/><br>
 
 		<label for="t01110">required, no min/max, prompt message, invalid message, no missing message</label><br>
-		<input id="t01110" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:true, promptMessage:"p", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t01110" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:true, promptMessage:"p", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t01110"/><br>
 
 		<label for="t01111">required, no min/max, prompt message, invalid message, missing message</label><br>
-		<input id="t01111" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='required:true, promptMessage:"p", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t01111" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false] }, required:true, promptMessage:"p", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t01111"/><br>
 
 		<label for="t10000">not required, min=10, max=100, no prompt message, no invalid message, no missing message</label><br>
-		<input id="t10000" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:false, promptMessage:"", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t10000" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:false, promptMessage:"", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t10000"/><br>
 
 		<label for="t10001">not required, min=10, max=100, no prompt message, no invalid message, missing message</label><br>
-		<input id="t10001" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:false, promptMessage:"", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t10001" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:false, promptMessage:"", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t10001"/><br>
 
 		<label for="t10010">not required, min=10, max=100, no prompt message, invalid message, no missing message</label><br>
-		<input id="t10010" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:false, promptMessage:"", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t10010" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:false, promptMessage:"", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t10010"/><br>
 
 		<label for="t10011">not required, min=10, max=100, no prompt message, invalid message, missing message</label><br>
-		<input id="t10011" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:false, promptMessage:"", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t10011" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:false, promptMessage:"", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t10011"/><br>
 
 		<label for="t10100">not required, min=10, max=100, prompt message, no invalid message, no missing message</label><br>
-		<input id="t10100" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:false, promptMessage:"p", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t10100" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:false, promptMessage:"p", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t10100"/><br>
 
 		<label for="t10101">not required, min=10, max=100, prompt message, no invalid message, missing message</label><br>
-		<input id="t10101" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:false, promptMessage:"p", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t10101" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:false, promptMessage:"p", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t10101"/><br>
 
 		<label for="t10110">not required, min=10, max=100, prompt message, invalid message, no missing message</label><br>
-		<input id="t10110" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:false, promptMessage:"p", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t10110" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:false, promptMessage:"p", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t10110"/><br>
 
 		<label for="t10111">not required, min=10, max=100, prompt message, invalid message, missing message</label><br>
-		<input id="t10111" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:false, promptMessage:"p", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t10111" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:false, promptMessage:"p", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t10111"/><br>
 
 		<label for="t11000">required, min=10, max=100, no prompt message, no invalid message, no missing message</label><br>
-		<input id="t11000" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:true, promptMessage:"", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t11000" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:true, promptMessage:"", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t11000"/><br>
 
 		<label for="t11001">required, min=10, max=100, no prompt message, no invalid message, missing message</label><br>
-		<input id="t11001" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:true, promptMessage:"", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t11001" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:true, promptMessage:"", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t11001"/><br>
 
 		<label for="t11010">required, min=10, max=100, no prompt message, invalid message, no missing message</label><br>
-		<input id="t11010" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:true, promptMessage:"", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t11010" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:true, promptMessage:"", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t11010"/><br>
 
 		<label for="t11011">required, min=10, max=100, no prompt message, invalid message, missing message</label><br>
-		<input id="t11011" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:true, promptMessage:"", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t11011" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:true, promptMessage:"", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t11011"/><br>
 
 		<label for="t11100">required, min=10, max=100, prompt message, no invalid message, no missing message</label><br>
-		<input id="t11100" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:true, promptMessage:"p", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t11100" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:true, promptMessage:"p", invalidMessage:"", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t11100"/><br>
 
 		<label for="t11101">required, min=10, max=100, prompt message, no invalid message, missing message</label><br>
-		<input id="t11101" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:true, promptMessage:"p", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t11101" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:true, promptMessage:"p", invalidMessage:"", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t11101"/><br>
 
 		<label for="t11110">required, min=10, max=100, prompt message, invalid message, no missing message</label><br>
-		<input id="t11110" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:true, promptMessage:"p", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
+		<input id="t11110" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:true, promptMessage:"p", invalidMessage:"i", missingMessage:"", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t11110"/><br>
 
 		<label for="t11111">required, min=10, max=100, prompt message, invalid message, missing message</label><br>
-		<input id="t11111" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='constraints:{min:10, max:100}, required:true, promptMessage:"p", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
+		<input id="t11111" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='constraints:{ fractional:[true,false], min:10, max:100 }, required:true, promptMessage:"p", invalidMessage:"i", missingMessage:"m", rangeMessage:"r"'/>
 		<input style="border:0;" size="6" value="t11111"/><br>
 
 	</body>
diff --git a/dijit/tests/form/test_Button.html b/dijit/tests/form/test_Button.html
index 7c8e221..420c7e6 100644
--- a/dijit/tests/form/test_Button.html
+++ b/dijit/tests/form/test_Button.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Dojo Button Widget Test</title>
@@ -57,6 +57,7 @@
 			dojo.require("dijit.ColorPalette");
 			dojo.require("dijit.Tooltip");
 
+			dojo.require("dijit.Dialog");
 			dojo.require("dijit.Menu");
 			dojo.require("dijit.MenuItem");
 			dojo.require("dijit.PopupMenuItem");
@@ -70,16 +71,26 @@
 			dojo.require("dijit.form.Form");
 			dojo.require("dijit.form.TextBox");
 
+			dojo.require("doh.runner");
 			dojo.require("dojo.parser");
 
 			dojo.ready(99, function(){
-				dijit.form.ViewButton = dojo.declare([dijit.form.Button], {
+				ViewButton = dojo.declare([dijit.form.Button], {
 					label: "View"
 				});
 			});
+
+			// Add test=true to the URL to run unit tests.
+			var test = /mode=test/i.test(window.location.href);
+
+			dojo.ready(function(){
+				if(test){
+					doh.run();
+				}
+			});
 		</script>
 	</head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1 class="testTitle">Dijit Button Test</h1>
 	<h2>Simple, drop down & combo buttons</h2>
 	<p>
@@ -88,149 +99,149 @@
 	<p class="box">
 		<button id="button" onclick="console.log('clicked native button');"><button></button>
 		<input id="input" type="button" value="<input type='button'>" onclick="console.log('clicked native input button');"/>
-		<button data-dojo-type="dijit.form.Button" id="T1465" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon", value:"Create"'>
+		<button data-dojo-type="dijit/form/Button" id="T1465" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon", value:"Create"'>
 			Create
 		</button>
-		<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["1465"]'>tooltip on button</span>
-		<button data-dojo-type="dijit.form.ViewButton" id="T1466" title="view title" data-dojo-props='onClick:function(){ console.log("clicked simple"); }'>
+		<span data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["1465"]'>tooltip on button</span>
+		<button data-dojo-type="ViewButton" id="T1466" title="view title" data-dojo-props='onClick:function(){ console.log("clicked simple"); }'>
 		</button>
-		<button id="comboCreate" title="creative title" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save") },
+		<button id="comboCreate" title="creative title" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save") },
 				iconClass:"plusIcon"'>
 			<span>Create</span>
-			<span id="createMenu" data-dojo-type="dijit.Menu">
-				<span data-dojo-type="dijit.MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+			<span id="createMenu" data-dojo-type="dijit/Menu">
+				<span data-dojo-type="dijit/MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
 					onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Create blank</span>
-				<span data-dojo-type="dijit.MenuItem"
+				<span data-dojo-type="dijit/MenuItem"
 					data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Create from template</span>
 			</span>
 		</button>
-		<button id="edit" title="edit title" value="Edit" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"noteIcon"'>
+		<button id="edit" title="edit title" value="Edit" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"noteIcon"'>
 			<span>Edit<b>!</b></span>
-			<span id="editMenu" data-dojo-type="dijit.Menu" >
-				<span id="cut" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+			<span id="editMenu" data-dojo-type="dijit/Menu" >
+				<span id="cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
 					onClick:function(){ console.log("not actually cutting anything, just a test!"); }'>Cut</span>
-				<span id="copy" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+				<span id="copy" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
 					onClick:function(){ console.log("not actually copying anything, just a test!"); }'>Copy</span>
-				<span id="paste" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+				<span id="paste" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
 					onClick:function(){ console.log("not actually pasting anything, just a test!"); }'>Paste</span>
-				<span data-dojo-type="dijit.MenuSeparator"></span>
-				<span data-dojo-type="dijit.PopupMenuItem">
+				<span data-dojo-type="dijit/MenuSeparator"></span>
+				<span data-dojo-type="dijit/PopupMenuItem">
 					<span>Submenu</span>
-					<span id="submenu2" data-dojo-type="dijit.Menu" >
-						<span data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!"); }'>Submenu Item One</span>
-						<span data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!"); }'>Submenu Item Two</span>
-						<span data-dojo-type="dijit.PopupMenuItem">
+					<span id="submenu2" data-dojo-type="dijit/Menu" >
+						<span data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!"); }'>Submenu Item One</span>
+						<span data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!"); }'>Submenu Item Two</span>
+						<span data-dojo-type="dijit/PopupMenuItem">
 							<span>Deeper Submenu</span>
-							<span id="submenu4" data-dojo-type="dijit.Menu" >
-								<span data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!"); }'>Sub-sub-menu Item One</span>
-								<span data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!"); }'>Sub-sub-menu Item Two</span>
+							<span id="submenu4" data-dojo-type="dijit/Menu" >
+								<span data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!"); }'>Sub-sub-menu Item One</span>
+								<span data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!"); }'>Sub-sub-menu Item Two</span>
 							</span>
 						</span>
 					</span>
 				</span>
 			</span>
 		</button>
-		<button id="color" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"noteIcon", value:"color"'>
+		<button id="color" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"noteIcon", value:"color"'>
 			<span>Color</span>
-			<span id="colorPalette" data-dojo-type="dijit.ColorPalette"
+			<span id="colorPalette" data-dojo-type="dijit/ColorPalette"
 				data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 		</button>
-		<button id="save" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
+		<button id="save" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
 				iconClass:"plusBlockIcon"'>
 			<span>Save</span>
-			<span id="saveMenu" data-dojo-type="dijit.Menu">
-				<span id="saveMenuItem" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+			<span id="saveMenu" data-dojo-type="dijit/Menu">
+				<span id="saveMenuItem" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
 					onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</span>
-				<span id="saveAs" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</span>
+				<span id="saveAs" data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</span>
 			</span>
 		</button>
-		<button id="disabled" disabled data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon"'>
+		<button id="disabled" disabled data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon"'>
 			Disabled
 		</button>
 	</p>
 	<br style="clear:both;"/>
 	<h2>DropDownButtons with different drop down positions</h2>
-	<button id="dropdown_default" value="color" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"noteIcon"'>
+	<button id="dropdown_default" value="color" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"noteIcon"'>
 		<span>Default (below)</span>
-		<span data-dojo-type="dijit.ColorPalette"
+		<span data-dojo-type="dijit/ColorPalette"
 			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 	</button>
-	<button id="dropdown_up" value="color" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='dropDownPosition:["above"], iconClass:"noteIcon"'>
+	<button id="dropdown_up" value="color" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='dropDownPosition:["above"], iconClass:"noteIcon"'>
 		<span>Above</span>
-		<span data-dojo-type="dijit.ColorPalette"
+		<span data-dojo-type="dijit/ColorPalette"
 			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 	</button>
-	<button id="dropdown_before" value="color" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='dropDownPosition:["before"], iconClass:"noteIcon"'>
+	<button id="dropdown_before" value="color" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='dropDownPosition:["before"], iconClass:"noteIcon"'>
 		<span>Before</span>
-		<span data-dojo-type="dijit.ColorPalette"
+		<span data-dojo-type="dijit/ColorPalette"
 			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 	</button>
-	<button id="dropdown_after" value="color" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='dropDownPosition:["after"], iconClass:"noteIcon"'>
+	<button id="dropdown_after" value="color" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='dropDownPosition:["after"], iconClass:"noteIcon"'>
 		<span>After</span>
-		<span data-dojo-type="dijit.ColorPalette"
+		<span data-dojo-type="dijit/ColorPalette"
 			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 	</button>
 	<h2>ComboButtons with different drop down positions</h2>
-	<button id="combo_default" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save") },
+	<button id="combo_default" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save") },
 			iconClass:"plusBlockIcon"'>
 		<span>Default (below)</span>
-		<span data-dojo-type="dijit.Menu">
-			<span data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+		<span data-dojo-type="dijit/Menu">
+			<span data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
 				onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</span>
-			<span data-dojo-type="dijit.MenuItem"
+			<span data-dojo-type="dijit/MenuItem"
 				data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</span>
 		</span>
 	</button>
-	<button id="combo_above" data-dojo-type="dijit.form.ComboButton" data-dojo-props='dropDownPosition:["above"], optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
+	<button id="combo_above" data-dojo-type="dijit/form/ComboButton" data-dojo-props='dropDownPosition:["above"], optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
 			iconClass:"plusBlockIcon"'>
 		<span>Up</span>
-		<span data-dojo-type="dijit.Menu">
-			<span data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+		<span data-dojo-type="dijit/Menu">
+			<span data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
 				onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</span>
-			<span data-dojo-type="dijit.MenuItem"
+			<span data-dojo-type="dijit/MenuItem"
 				data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</span>
 		</span>
 	</button>
-	<button id="combo_before" data-dojo-type="dijit.form.ComboButton" data-dojo-props='dropDownPosition:["before"], optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
+	<button id="combo_before" data-dojo-type="dijit/form/ComboButton" data-dojo-props='dropDownPosition:["before"], optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
 			iconClass:"plusBlockIcon"'>
 		<span>Before</span>
-		<span data-dojo-type="dijit.Menu">
-			<span data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+		<span data-dojo-type="dijit/Menu">
+			<span data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
 				onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</span>
-			<span data-dojo-type="dijit.MenuItem"
+			<span data-dojo-type="dijit/MenuItem"
 				data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</span>
 		</span>
 	</button>
-	<button id="combo_after" data-dojo-type="dijit.form.ComboButton" data-dojo-props='dropDownPosition:["after"], optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
+	<button id="combo_after" data-dojo-type="dijit/form/ComboButton" data-dojo-props='dropDownPosition:["after"], optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
 			iconClass:"plusBlockIcon"'>
 		<span>After</span>
-		<span data-dojo-type="dijit.Menu">
-			<span data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+		<span data-dojo-type="dijit/Menu">
+			<span data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
 				onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</span>
-			<span data-dojo-type="dijit.MenuItem"
+			<span data-dojo-type="dijit/MenuItem"
 				data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</span>
 		</span>
 	</button>
 	<h2>Buttons with no text label</h2>
 	<p>Buttons have showLabel=false so text is not displayed.  If no title attribute supplied, Should have label as title attribute displayed on mouse over</p>
 	<div class="box">
-		<button id="buttonNoLabel" title="title attrib rather than label" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("clicked simple button with no text label"); },
+		<button id="buttonNoLabel" title="title attrib rather than label" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ console.log("clicked simple button with no text label"); },
 		iconClass:"plusIcon", showLabel:false'>
 			<span><b>Rich</b><i> Text</i> Test!</span>
 		</button>
-		<div id="dropDownNoLabel" title="color title" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"noteIcon", showLabel:false'>
+		<div id="dropDownNoLabel" title="color title" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"noteIcon", showLabel:false'>
 			<span>Color</span>
-			<div id="colorPalette2" data-dojo-type="dijit.ColorPalette"
+			<div id="colorPalette2" data-dojo-type="dijit/ColorPalette"
 				data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'>
 			</div>
 		</div>
-		<div id="comboNoLabel" title="save title" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
+		<div id="comboNoLabel" title="save title" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
 				iconClass:"plusBlockIcon", showLabel:false'>
 			<span>Save</span>
-			<div id="saveMenu2" data-dojo-type="dijit.Menu">
-				<div data-dojo-type="dijit.MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+			<div id="saveMenu2" data-dojo-type="dijit/Menu">
+				<div data-dojo-type="dijit/MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
 					onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</div>
-				<div data-dojo-type="dijit.MenuItem"
+				<div data-dojo-type="dijit/MenuItem"
 					data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</div>
 			</div>
 		</div>
@@ -239,14 +250,14 @@
 	<h2>Toggle buttons</h2>
 	<p>The button CSS as well as the icon CSS can change on toggle </p>
 	<div class="box">
-		<button id="toggle1" checked data-dojo-type="dijit.form.ToggleButton" data-dojo-props='
+		<button id="toggle1" checked data-dojo-type="dijit/form/ToggleButton" data-dojo-props='
 			onChange:function(val){
 				console.log("toggled button checked="+val);
 				this.set("label", val ? "toggle me off" : "toggle me on");
 			}, iconClass:"dijitCheckBoxIcon"'>
 			Toggle me off
 		</button>
-		<button id="toggle2" data-dojo-type="dijit.form.ToggleButton"
+		<button id="toggle2" data-dojo-type="dijit/form/ToggleButton"
 			data-dojo-props='onChange:function(val){ console.log("toggled button checked="+val); }, iconClass:"dijitRadioIcon"'>
 			Toggle me
 		</button>
@@ -256,19 +267,19 @@
 	<p>Short button, tall buttons, big buttons, small buttons...
 	These buttons size to their content (just like <button>).</p>
 	<div class="box">
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("big"); }, iconClass:"flatScreenIcon"'>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ console.log("big"); }, iconClass:"flatScreenIcon"'>
 			<span style="font-size:xx-large">big</span>
 		</button>
-		<button id="smallButton1" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("small"); }'>
-			<img src="../images/arrowSmall.gif" width="15" height="5"/>
+		<button id="smallButton1" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ console.log("small"); }'>
+			<img src="../images/arrowSmall.gif" alt="small" width="15" height="5"/>
 			<span style="font-size:x-small">small</span>
 		</button>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("long"); }'>
-			<img src="../images/tube.gif" width="150" height="16"/>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ console.log("long"); }'>
+			<img src="../images/tube.gif" alt="long" width="150" height="16"/>
 			long
 		</button>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("tall"); }'>
-			<img src="../images/tubeTall.gif" height="75" width="35"/><br>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ console.log("tall"); }'>
+			<img src="../images/tubeTall.gif" alt="tall" height="75" width="35"/><br>
 			<span style="font-size:medium">tall</span>
 		</button>
 		<div style="clear: both;"></div>
@@ -277,13 +288,13 @@
 	<h2>Customized buttons</h2>
 	<p>Dojo users can customize styles.  Here's an example:</p>
 	<div class="box">
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='baseClass:"acmeButton", onClick:function(){ console.log("short"); }'>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='baseClass:"acmeButton", onClick:function(){ console.log("short"); }'>
 			short
 		</button>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='baseClass:"acmeButton", onClick:function(){ console.log("longer"); }'>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='baseClass:"acmeButton", onClick:function(){ console.log("longer"); }'>
 			bit longer
 		</button>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='baseClass:"acmeButton", onClick:function(){ console.log("longer yet"); }'>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='baseClass:"acmeButton", onClick:function(){ console.log("longer yet"); }'>
 			ridiculously long
 		</button>
 		<div style="clear: both;"></div>
@@ -293,15 +304,15 @@
 	(Ticket <a href="http://trac.dojotoolkit.org/ticket/403">#403</a>)
 	</p>
 	<div class="box">
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dojo.byId("hiddenNode").style.display="inline"; }'>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ dojo.byId("hiddenNode").style.display="inline"; }'>
 			Show Hidden Buttons
 		</button>
 	</div>
 	<div class="box" style="display:none;" id="hiddenNode">
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon"'>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon"'>
 			Create
 		</button>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon"'>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon"'>
 			Create
 		</button>
 	</div>
@@ -359,53 +370,53 @@
 			widget2.placeAt("buttonContainer");	// place in page
 		});
 	</script>
-    <h3>DropDownButton instantiated via javacript:</h3>
+	<h3>DropDownButton instantiated via javacript:</h3>
 	<div id="dropdownButtonContainer"></div>
 	<script type="text/javascript">
-	    // See if we can make a drop down button in script and attach it to the DOM ourselves.
-        function createButton(){
-            var menu = new dijit.Menu({ });
-            menu.domNode.style.display="none";
-            var menuItem1 = new dijit.MenuItem({
-                label: "Save",
-                iconClass:"dijitEditorIcon dijitEditorIconSave",
-                onClick: function(){ alert('save'); }
-            });
-            menu.addChild(menuItem1);
+		// See if we can make a drop down button in script and attach it to the DOM ourselves.
+		function createButton(){
+			var menu = new dijit.Menu({ });
+			menu.domNode.style.display="none";
+			var menuItem1 = new dijit.MenuItem({
+				label: "Save",
+				iconClass:"dijitEditorIcon dijitEditorIconSave",
+				onClick: function(){ alert('save'); }
+			});
+			menu.addChild(menuItem1);
 
-            var menuItem2 = new dijit.MenuItem({
-                label: "Cut",
-                iconClass:"dijitEditorIcon dijitEditorIconCut",
-                onClick: function(){ alert('cut'); }
-            });
-            menu.addChild(menuItem2);
+			var menuItem2 = new dijit.MenuItem({
+				label: "Cut",
+				iconClass:"dijitEditorIcon dijitEditorIconCut",
+				onClick: function(){ alert('cut'); }
+			});
+			menu.addChild(menuItem2);
 
-            var params = {
-                label: "hello!",
-                name: "programmatic2",
-                dropDown: menu,
-                id: "progButton"
-            };
-            var widget = new dijit.form.DropDownButton(params);
-            dojo.byId("dropdownButtonContainer").appendChild(widget.domNode);
-            dojo.byId("createButton").disabled = true;
-            dojo.byId("destroyButton").disabled = false;
-	    }
-        function destroyButton(){
-            var button = dijit.byId("progButton");
-            button.destroyRecursive();
-            dojo.byId("createButton").disabled = false;
-            dojo.byId("destroyButton").disabled = true;
-        }
-    </script>
-    <button id="createButton" onclick="createButton();">create dropdown button</button>
-    <button id="destroyButton" onclick="destroyButton();">destroy dropdown button</button>
+			var params = {
+				label: "hello!",
+				name: "programmatic2",
+				dropDown: menu,
+				id: "progButton"
+			};
+			var widget = new dijit.form.DropDownButton(params);
+			dojo.byId("dropdownButtonContainer").appendChild(widget.domNode);
+			dojo.byId("createButton").disabled = true;
+			dojo.byId("destroyButton").disabled = false;
+		}
+		function destroyButton(){
+			var button = dijit.byId("progButton");
+			button.destroyRecursive();
+			dojo.byId("createButton").disabled = false;
+			dojo.byId("destroyButton").disabled = true;
+		}
+	</script>
+	<button id="createButton" onclick="createButton();">create dropdown button</button>
+	<button id="destroyButton" onclick="destroyButton();">destroy dropdown button</button>
 
 	<h3>Submit and Reset Buttons</h3>
 	<div>Testing that submit and reset buttons work properly.  OnSubmit and OnReset handlers
 		for the form just output to the console.
 	</div>
-	<form id="testForm" encType="multipart/form-data" name="testForm" action="../formAction.html" method="" data-dojo-type="dijit.form.Form">
+	<form id="testForm" encType="multipart/form-data" name="testForm" action="../formAction.html" method="" data-dojo-type="dijit/form/Form">
 		<script type="dojo/method" data-dojo-event="onReset">
 			console.log("testForm onReset invoked");
 		</script>
@@ -413,9 +424,9 @@
 			console.log("testForm onSubmit invoked - not really submitting");
 			return false;
 		</script>
-		<label for="testName">Name: </label><input id="testName" data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"testName", value:""'/><br>
-		<button id="bSubmit" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit" '>Submit</button>  
-		<button id="bReset" data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset" '>Reset</button>
+		<label for="testName">Name: </label><input id="testName" data-dojo-type="dijit/form/TextBox" data-dojo-props='name:"testName", value:""'/><br>
+		<button id="bSubmit" data-dojo-type="dijit/form/Button" data-dojo-props='type:"submit" '>Submit</button>  
+		<button id="bReset" data-dojo-type="dijit/form/Button" data-dojo-props='type:"reset" '>Reset</button>
 	</form>
 
 	<h3>onClick Tests</h3>
@@ -423,15 +434,15 @@
 	</div>
 	<form>
 		<label for="onClickName">Value: </label><input id="onClickName" name="onClickName" value="RESET"/><br>
-		<button id="reset1" type="reset" data-dojo-type="dijit.form.Button">Reset with no onClick handler should reset</button>
+		<button id="reset1" type="reset" data-dojo-type="dijit/form/Button">Reset with no onClick handler should reset</button>
 		<button type="reset" id="reset1N">Native Reset with no onClick handler should reset</button><br>
-		<button id="reset2" type="reset" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ return false }'>Reset with "return false" onClick handler should not reset</button>
+		<button id="reset2" type="reset" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ return false }'>Reset with "return false" onClick handler should not reset</button>
 		<button type="reset" id="reset2N" onClick="return false;">Native Reset with "return false" onClick handler should not reset</button><br>
-		<button id="reset3" type="reset" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ return true }'>Reset with "return true" onClick handler should reset</button>
+		<button id="reset3" type="reset" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ return true }'>Reset with "return true" onClick handler should reset</button>
 		<button type="reset" id="reset3N" onClick="return true;">Native Reset with "return true" onClick handler should reset</button><br>
-		<button id="reset4" type="reset" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ return }'>Reset with "return" onClick handler should reset</button>
+		<button id="reset4" type="reset" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ return }'>Reset with "return" onClick handler should reset</button>
 		<button type="reset" id="reset4N" onClick="return;">Native Reset with "return" onClick handler should reset</button><br>
-		<button id="reset5" type="reset" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){  }'>Reset with "" onClick handler should reset</button>
+		<button id="reset5" type="reset" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){  }'>Reset with "" onClick handler should reset</button>
 		<button type="reset" id="reset5N" onClick="">Native Reset with "" onClick handler should reset</button><br>
 	</form>
 
@@ -444,28 +455,46 @@
 			}
 		};
 	</script>
-	<form id="myForm" data-dojo-type="dijit.form.Form" encType="multipart/form-data" action="../formAction.html" method="" target="formSubmitIframe">
-		<button id="SubmitPlain" data-dojo-type="dijit.form.Button" name="Plain" type="submit" value="Plain Submit">Plain Submit</button>
-		<button id="SubmitCombo" data-dojo-type="dijit.form.ComboButton" name="Combo" type="submit" value="Combo Submit"
+	<form id="myForm" data-dojo-type="dijit/form/Form" encType="multipart/form-data" action="../formAction.html" method="" target="formSubmitIframe">
+		<button id="SubmitPlain" data-dojo-type="dijit/form/Button" name="Plain" type="submit" value="Plain Submit">Plain Submit</button>
+		<button id="SubmitCombo" data-dojo-type="dijit/form/ComboButton" name="Combo" type="submit" value="Combo Submit"
 				data-dojo-props="label: 'Combo Submit'">
 			Combo Submit
-			<span data-dojo-type="dijit.Menu">
-				<span id="SubmitComboMenuItem" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ dijit.byId("myForm").submit(); }'>Combo MenuItem Submit</span>
+			<span data-dojo-type="dijit/Menu">
+				<span id="SubmitComboMenuItem" data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ dijit.byId("myForm").submit(); }'>Combo MenuItem Submit</span>
 			</span>
 		</button>
-		<button id="SubmitDropDown" data-dojo-type="dijit.form.DropDownButton" name="DropDown" type="submit" value="DropDown Submit"
+		<button id="SubmitDropDown" data-dojo-type="dijit/form/DropDownButton" name="DropDown" type="submit" value="DropDown Submit"
 				data-dojo-props="label: 'DropDown Submit'">
 			DropDown Submit
-			<span data-dojo-type="dijit.Menu">
-				<span id="SubmitDropDownMenuItem" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ dijit.byId("myForm").submit(); }'>DropDown MenuItem Submit</span>
+			<span data-dojo-type="dijit/Menu">
+				<span id="SubmitDropDownMenuItem" data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ dijit.byId("myForm").submit(); }'>DropDown MenuItem Submit</span>
 			</span>
 		</button>
-		<button id="SubmitDisabled" data-dojo-type="dijit.form.Button" name="Disabled" type="submit" disabled value="Disabled Submit">Disabled Submit</button>
+		<button id="SubmitDisabled" data-dojo-type="dijit/form/Button" name="Disabled" type="submit" disabled value="Disabled Submit">Disabled Submit</button>
 	</form>
 	<br>
 	<label for="buttonName">Submitted name:</label><input id="buttonName"/><br>
 	<label for="buttonValue">Submitted value:</label><input id="buttonValue"/>
 	<br>
 	<iframe name="formSubmitIframe" src="about:blank" onload="if(this.values) submittedValues(this.values);" style="display:none;"></iframe>
+
+
+	<p>Tests for bubbling:</p>
+	<div id="bubbleContainer" style="border: solid #aaa 3px">
+		<button type="button" data-dojo-type="dijit/form/Button" id="bubble1">1</button>
+		<button type="button" data-dojo-type="dijit/form/Button" id="bubble2">2</button>
+		<button type="button" data-dojo-type="dijit/form/Button" id="bubble3">3</button>
+	</div>
+	<script>
+		require(["dojo/dom", "dojo/on", "dijit/registry"], function(dom, on, registry){
+			on(dom.byId("bubbleContainer"), "click", function(evt){
+				var widget = registry.getEnclosingWidget(evt.target);
+				if(widget){
+					console.log("click on widget " + widget.id);
+				}
+			});
+		});
+	</script>
 </body>
 </html>
diff --git a/dijit/tests/form/test_CheckBox.html b/dijit/tests/form/test_CheckBox.html
index feb2f09..cc0cc8c 100644
--- a/dijit/tests/form/test_CheckBox.html
+++ b/dijit/tests/form/test_CheckBox.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>CheckBox Widget Demo</title>
@@ -23,8 +23,6 @@
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.form.CheckBox");
 		dojo.require("dijit.form.RadioButton");
 		dojo.require("dijit.form.Form");
@@ -59,7 +57,7 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Dijit CheckBox Test</h1>
 	<p>
@@ -67,33 +65,33 @@
 	</p>
 	<!--    to test form submission, you'll need to create an action handler similar to
 		http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
-	<form id="myForm" data-dojo-type="dijit.form.Form" data-dojo-props='action:"../formAction.html", method:"", target:"formSubmitIframe"'>
+	<form id="myForm" data-dojo-type="dijit/form/Form" data-dojo-props='action:"../formAction.html", method:"", target:"formSubmitIframe"'>
 		<input type="checkbox" id="cb0" checked/>
 			<label for="cb0">cb0: Vanilla (non-dojo) checkbox (for comparison purposes)</label>
 		<br>
-		<input id="cb1" data-dojo-id="cb1" data-dojo-type="dijit.form.CheckBox" data-dojo-props='name:"cb1", value:"foo", onClick:function(){ console.log("clicked cb1") }'/>
+		<input id="cb1" data-dojo-id="cb1" data-dojo-type="dijit/form/CheckBox" data-dojo-props='name:"cb1", value:"foo", onClick:function(){ console.log("clicked cb1") }'/>
 			<label for="cb1">cb1: normal checkbox, with value=foo, clicking generates console log messages</label>
 			<button type=button onclick="alert(dijit.byId('cb1').get('value'));">get('value')</button>
 		<br>
-		<input id="cb2" data-dojo-type="dijit.form.CheckBox" data-dojo-props='onChange:reportChecked, name:"cb2", checked:true'/>
+		<input id="cb2" data-dojo-type="dijit/form/CheckBox" data-dojo-props='onChange:reportChecked, name:"cb2", checked:true'/>
 			<label for="cb2">cb2: normal checkbox, with default value, initially turned on.</label>
 			<span>"onChange" handler updates: [<span id="oncheckedoutput"></span>]</span>
 			<button type=button onclick="alert(dijit.byId('cb2').get('value'));">get('value')</button>
 		<br>
-		<input id="cb3" data-dojo-type="dijit.form.CheckBox" data-dojo-props='name:"cb3", disabled:true'/>
+		<input id="cb3" data-dojo-type="dijit/form/CheckBox" data-dojo-props='name:"cb3", disabled:true'/>
 			<label for="cb3">cb3: disabled checkbox</label>
 		<br>
-		<input id="cb4" data-dojo-type="dijit.form.CheckBox" data-dojo-props='name:"cb4", readOnly:true, checked:true'/>
+		<input id="cb4" data-dojo-type="dijit/form/CheckBox" data-dojo-props='name:"cb4", readOnly:true, checked:true, value:"" '/><!-- blank value => "on" -->
 			<label for="cb4">cb4: readOnly checkbox, turned on</label>
 		<br>
-		<input id="cb5" data-dojo-type="dijit.form.CheckBox" data-dojo-props='name:"cb5", value:"", onClick:function(){ console.log("clicked cb5"); }'/>
+		<input id="cb5" data-dojo-type="dijit/form/CheckBox" data-dojo-props='name:"cb5", value:"", onClick:function(){ console.log("clicked cb5"); }'/>
 			<label for="cb5">cb5: normal checkbox, with specified value="", clicking generates console log messages</label>
 			<button type=button onclick="alert(dijit.byId('cb5').get('value'));">get('value')</button>
 		<br>
 		<input id="cb6"/>
 			<label for="cb6">cb6: instantiated from script</label>
 		<br>
-		<input id="cb7" data-dojo-type="dijit.form.CheckBox" data-dojo-props='onChange:reportValueChanged, name:"cb7" '/>
+		<input id="cb7" data-dojo-type="dijit/form/CheckBox" data-dojo-props='onChange:reportValueChanged, name:"cb7" '/>
 			<label for="cb7">cb7: normal checkbox.</label>
 			<input type="button" onclick='dijit.byId("cb7").set("disabled",true);' value="disable" />
 			<input type="button" onclick='dijit.byId("cb7").set("disabled",false);' value="enable" />
@@ -106,27 +104,27 @@
 	</p>
 		<p>
 			<span>Radio group #1:</span>
-			<input id="g1rb1" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g[1]", value:"news" '/>
+			<input id="g1rb1" data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"g[1]", value:"news" '/>
 			<label for="g1rb1">news</label>
-			<input id="g1rb2" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g[1]", value:"talk", checked:true'/>
+			<input id="g1rb2" data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"g[1]", checked:true'/><!-- no value => "on" -->
 			<label for="g1rb2">talk</label>
-			<input id="g1rb3" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g[1]", value:"weather", disabled:true'/>
+			<input id="g1rb3" data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"g[1]", value:"", disabled:true'/><!-- blank value => "" -->
 			<label for="g1rb3">weather</label>
 			<input type="button" id="enableWeatherButton" onclick='dijit.byId("g1rb3").set("disabled",false);' value="enable weather" />
 			<input type="button" onclick='dijit.byId("g1rb3").set("disabled",true);' value="disable weather" />
 		</p>
 		<p>
 			<span>Radio group #2: (no default value, and has breaks)</span><br>
-			<input id="g2rb1" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g2", value:"top40" '/>
+			<input id="g2rb1" data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"g2", value:"top40" '/>
 			<label for="g2rb1">top 40</label><br>
-			<input id="g2rb2" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g2", value:"oldies" '/>
+			<input id="g2rb2" data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"g2", value:"oldies" '/>
 			<label for="g2rb2">oldies</label><br>
-			<input id="g2rb3" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g2", value:"country" '/>
+			<input id="g2rb3" data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"g2", value:"country" '/>
 			<label for="g2rb3">country</label><br>
 			(Note if using keyboard: tab to navigate, and use arrow or space to select)
 		</p>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", value:"Submit"'>Submit</button>
-		<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset"'>HTML Reset</button>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='type:"submit", value:"Submit"'>Submit</button>
+		<button data-dojo-type="dijit/form/Button" data-dojo-props='type:"reset"'>HTML Reset</button>
 	</form>
 
 	<p>
@@ -143,24 +141,24 @@
 		These 6 radio buttons have the same name but are in separate forms so they can be selected independently.
 		<form>
 			1:
-			<input id='b1' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"1"'/><label for='b1'>b1</label>
-			<input id='b2' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"2"'/><label for='b2'>b2</label>
+			<input id='b1' data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"a1", value:"1"'/><label for='b1'>b1</label>
+			<input id='b2' data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"a1", value:"2"'/><label for='b2'>b2</label>
 		</form>
 		<form>
 			2:
-			<input id='c1' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"1"'/><label for='c1'>c1</label>
-			<input id='c2' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"2"'/><label for='c2'>c2</label>
+			<input id='c1' data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"a1", value:"1"'/><label for='c1'>c1</label>
+			<input id='c2' data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"a1", value:"2"'/><label for='c2'>c2</label>
 		</form>
 		<div>
 			3:
-			<input id='d1' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"1"'/><label for='d1'>d1</label>
-			<input id='d2' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"2"'/><label for='d2'>d2</label>
+			<input id='d1' data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"a1", value:"1"'/><label for='d1'>d1</label>
+			<input id='d2' data-dojo-type="dijit/form/RadioButton" data-dojo-props='name:"a1", value:"2"'/><label for='d2'>d2</label>
 		</div>
 	</div>
 	
 	<div>
 		<span>Programmatic radio buttons:</span>
-		<form id="myform">
+		<form id="radioForm">
 			<input type="radio" name="drink" id="g4rb1" checked value="tea"/> <label for="g4rb1">Tea</label> <br />
 			<input type="radio" name="drink" id="g4rb2" checked value="coffee"/> <label for="g4rb2">Coffee</label> <br />
 		</form>
diff --git a/dijit/tests/form/test_DateTextBox.html b/dijit/tests/form/test_DateTextBox.html
index 16b95a3..6c56944 100644
--- a/dijit/tests/form/test_DateTextBox.html
+++ b/dijit/tests/form/test_DateTextBox.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Test DateTextBox Widget</title>
@@ -37,28 +37,270 @@
 		<script type="text/javascript" src="../_testCommon.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("doh.runner");
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dijit.form.DateTextBox");
 			dojo.require("dijit.form.Form");
 			dojo.require("dojo.date.locale");
+			dojo.require("dijit.tests.helpers");    // functions to help test
 			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
+			// Add test=true to the URL to run unit tests.
+			var test = /mode=test/i.test(window.location.href);
+
 			function eventHandler(e){
 				// use this.domNode.getAttribute('widgetId') to show "this" is the widget
 				// mouseleave/enter map to mouseout/over in all browsers except IE
 				console.log(this.domNode.getAttribute('widgetId') + ' ' + e.type);
 			}
 			dojo.ready(function(){
-				dijit.byId("localLong").parse = function(value,constraints){
+				// See if we can make a widget in script and attach it to the DOM ourselves.
+				dojo.connect(dijit.byId('pattern'), "onMouseEnter", eventHandler);
+				dojo.connect(dijit.byId('pattern'), "onMouseLeave", eventHandler);
+				dojo.connect(dijit.byId('pattern'), "onKeyDown", eventHandler);
+
+				var props = {
+					name: "date4",
+					value: new Date(2006,10,29),
+					constraints: {min:new Date(2004,0,1),max:new Date(2006,11,31)},
+					lang: "de-de",
+					hasDownArrow: false,
+					onMouseEnter: eventHandler,
+					onMouseLeave: eventHandler,
+					onKeyDown: eventHandler,
+					promptMessage: "dd.mm.yy",
+					rangeMessage: "Enter a date in the year range 2004-2006.",
+					invalidMessage: "Invalid date. Use dd.mm.yy format."
+				};
+				var german = new dijit.form.DateTextBox(props, "german");
+				german.startup();
+				var localLong = dijit.byId("localLong");
+				var american = dijit.byId("american");
+
+				localLong.parse = function(value,constraints){
 					return this.dateLocaleModule.parse(value, (constraints.formatLength="long") && constraints) ||
 						 this.dateLocaleModule.parse(value, (constraints.formatLength="short") && constraints) ||
 						(this._isEmpty(value) ? null : undefined);	 // Date
 				};
+
+				if(test){
+					doh.register("constraints", [
+						{
+							name: "initial state",
+							timeout: 1000,
+							runTest: function(t){
+								var expected = new Date(2005,11,30);
+								var actual = localLong.get('value');
+								t.is(0, dojo.date.compare(expected, actual), 'expected ' + expected.toDateString() + ' but got ' + actual.toDateString());
+								t.is("", localLong.get('state'));
+							}
+						},
+						{
+							name: "change value, now invalid",
+							timeout: 1000,
+							runTest: function(t){
+								var expected = new Date(2007,6,15);
+								localLong.set("value", expected);
+								var actual = localLong.get('value');
+								t.is(0, dojo.date.compare(expected, actual), 'expected ' + expected.toDateString() + ' but got ' + actual.toDateString());
+								t.is("Error", localLong.get('state'));
+							}
+						},
+						{
+							name: "change max, still invalid",
+							timeout: 1000,
+							runTest: function(t){
+								localLong.set("constraints", dojo.mixin(localLong.get('constraints'), { max: new Date(2007,5,30)}));
+								var expected = new Date(2007,6,15);
+								var actual = localLong.get('value');
+								t.is(0, dojo.date.compare(expected, actual), 'expected ' + expected.toDateString() + ' but got ' + actual.toDateString());
+								t.is("Error", localLong.get('state'));
+							}
+						},
+						{
+							name: "change max, now valid",
+							timeout: 1000,
+							runTest: function(t){
+								localLong.set("constraints", dojo.mixin(localLong.get('constraints'), { max: new Date(2007,11,31)}));
+								var expected = new Date(2007,6,15);
+								var actual = localLong.get('value');
+								t.is(0, dojo.date.compare(expected, actual), 'expected ' + expected.toDateString() + ' but got ' + actual.toDateString());
+								t.is("", localLong.get('state'));
+							}
+						},
+						{
+							name: "change max, now invalid",
+							timeout: 1000,
+							runTest: function(t){
+								localLong.set("constraints", dojo.mixin(localLong.get('constraints'), { max: new Date(2006,11,30)}));
+								var expected = new Date(2007,6,15);
+								var actual = localLong.get('value');
+								t.is(0, dojo.date.compare(expected, actual), 'expected ' + expected.toDateString() + ' but got ' + actual.toDateString());
+								t.is("Error", localLong.get('state'));
+							}
+						},
+						{
+							name: "change value, now valid",
+							timeout: 1000,
+							runTest: function(t){
+								var expected = new Date(2005,11,30);
+								localLong.set("value", expected);
+								var actual = localLong.get('value');
+								t.is(0, dojo.date.compare(expected, actual), 'expected ' + expected.toDateString() + ' but got ' + actual.toDateString());
+								t.is("", localLong.get('state'));
+							}
+						}
+					]);
+
+					doh.register("tests",
+						function noYear(){
+							var widget = dijit.byId("noyear");
+							doh.t(widget.isValid(false), "isValid");
+							doh.is(2011, widget.get('value').getFullYear(), "programmatic value");
+							doh.is(2011, widget.value.getFullYear(), "JS value");
+						}
+					);
+
+				doh.register("API", [
+					function initial(){
+						// initial conditions
+						doh.is(0, dojo.date.compare(new Date(2005,11,30), american.get('value')), 'wire value of american: ' + american.get('value'));
+						doh.is('12/30/2005', american.get('displayedValue'), 'displayed value of american');
+					},
+
+					function setValue(){
+						american.set('value', new Date(2004,9,20));
+						doh.is(0, dojo.date.compare(new Date(2004,9,20), american.get('value')),
+								'wire value of american is: ' + american.get('value') +
+								' but should be: ' + new Date(2004,9,20));
+						doh.is('10/20/2004', american.get('displayedValue'), 'displayed value of american');
+						doh.t(american.isValid(), 'marked as valid');
+					},
+
+					function setDisplayedValue(){
+						american.set('displayedValue', '11/12/2006');
+						doh.is(0, dojo.date.compare(new Date(2006, 10, 12), american.get('value')), 'wire value of american');
+						doh.is('11/12/2006', american.get('displayedValue'), 'displayed value of american');
+						doh.t(american.isValid(), 'marked as valid');
+					},
+
+					function setInvalidDisplayedValue(){
+						american.set('displayedValue', 'foo');
+						doh.t(american.get('value') === undefined, 'value is undefined if displayedValue is garbage');
+						doh.f(american.isValid(), 'marked as invalid');
+
+						// setting the value to get('value') should never change anything, so
+						// therefore setting the value to undefined shouldn't affect the displayed value
+						american.set('value', undefined);
+						doh.is(american.get('displayedValue'), 'foo');
+					},
+
+					function setOutOfRange(){
+						// This widget is set to be valid between 2004 and 2006 only
+						american.set('displayedValue', '12/1/2008');
+						doh.f(american.isValid(), 'marked as invalid since out of range');
+						doh.is('12/1/2008', american.get('displayedValue'), 'displayed value of american');
+					},
+
+					function noInitialValue(){
+						var fromDate = dijit.byId('fromDate');
+						doh.is('', fromDate.get('displayedValue'), 'initially blank');
+						doh.is(dijit.form.DateTextBox.prototype.value, fromDate.value, 'default value');
+						var d = new doh.Deferred();
+						var today = new Date();
+						fromDate.set('value', today, true);
+						setTimeout(d.getTestCallback(function(){
+				    			var toDate = dijit.byId('toDate');
+							doh.is(today.toDateString(), fromDate.value.toDateString(), 'changed value');
+							doh.is(today.toDateString(), toDate.constraints.min.toDateString(), 'onChange');
+						}), 500);
+						return d;
+					},
+					
+					function ariaRolesAndAttributes(){
+						var d = new doh.Deferred(),
+							button = dijit.byId("local");
+
+						doh.is("combobox", button._popupStateNode.getAttribute("role"), "button _popupStateNode role");
+						doh.t(button._popupStateNode.getAttribute("aria-haspopup"), "aria-haspopup on button");
+						doh.f(button._popupStateNode.getAttribute("aria-expanded"), "initially missing aria-expanded");
+						doh.f(button._popupStateNode.getAttribute("aria-owns"), "initally missing aria-owns");
+
+						button.openDropDown();
+
+						setTimeout(d.getTestCallback(function(){
+							doh.t(button._popupStateNode.getAttribute("aria-expanded"), "now aria-expanded should be true");
+							doh.is("local_popup", button._popupStateNode.getAttribute("aria-owns"), "should aria-own the Dlg");
+							// Check roles and attributes on the dialog
+							var dlg = dijit.byId("local_popup");
+							doh.is("grid", dlg.domNode.getAttribute("role"), "Dlg.domNode should have a role");
+							doh.is("local_popup_mddb local_popup_year", dlg.domNode.getAttribute("aria-labelledby"), "aria-labelledby should not overwrite existing labelledby for the Calendar");
+
+							button.closeDropDown();
+						}), 500);
+						
+						return d;
+					}
+				]);
+
+				doh.register("localization", [
+					function initialGerman(){
+						doh.is(0, dojo.date.compare(new Date(2006,10,29), german.get('value')), 'wire value of german: ' + german.get('value'));
+						doh.is('29.11.2006', german.get('displayedValue'), 'displayed value of german');
+					},
+
+					function setValueGerman(){
+						german.set('value', new Date(2004,9,20));
+						doh.is(0, dojo.date.compare(new Date(2004,9,20), german.get('value')),
+								'wire value of german is: ' + german.get('value') +
+								' but should be: ' + new Date(2004,9,20));
+						doh.is('20.10.2004', german.get('displayedValue'), 'displayed value of german');
+						doh.t(german.isValid(), 'marked as valid');
+					},
+
+					function setDisplayedValueGerman(){
+						german.set('displayedValue', '12.11.2006');
+						doh.is(0, dojo.date.compare(new Date(2006, 10, 12), german.get('value')), 'wire value of german');
+						doh.is('12.11.2006', german.get('displayedValue'), 'displayed value of german');
+						doh.t(german.isValid(), 'marked as valid');
+					},
+					{
+						name: "labels",
+						timeout: 6000,
+						runTest: function(){
+							german.set('value', new Date(2006, 9, 15));	// 10/15/2006
+
+							german.openDropDown();
+							var calendar = dijit.byId("german_popup");
+
+							// calendar exists and is shown
+							doh.t(calendar && isVisible(calendar), "calendar is visible");
+
+							// Month label
+							doh.is("Oktober", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]));
+
+							// Day labels
+							var dayLabels = dojo.query(".dijitCalendarDayLabelTemplate", calendar.domNode);
+							doh.is(7, dayLabels.length, "7 day labels");
+							doh.is("M", innerText(dayLabels[0]), "day 0");
+							doh.is("D", innerText(dayLabels[1]), "day 1");
+							doh.is("M", innerText(dayLabels[2]), "day 2");
+							doh.is("D", innerText(dayLabels[3]), "day 3");
+							doh.is("F", innerText(dayLabels[4]), "day 4");
+							doh.is("S", innerText(dayLabels[5]), "day 5");
+							doh.is("S", innerText(dayLabels[6]), "day 6");
+							german.closeDropDown();
+						}
+					}
+				]);
+					doh.run();
+				}
+
 			});
 		</script>
 	</head>
 
-	<body class="claro">
+	<body class="claro" role="main">
 
 		<h1 class="testTitle">Test DateTextBox Widget</h1>
 		<!--	to test form submission, you'll need to create an action handler similar to
@@ -69,38 +311,37 @@
 				<span class="noticeMessage">DateTextBox class, no attributes</span>
 			</div>
 			<div class="testExample">
-				<input id="local" data-dojo-type="dijit.form.DateTextBox"
+				<input id="local" data-dojo-type="dijit/form/DateTextBox" style="width: 100px"
 					data-dojo-props='name:"noDOMvalue", value:"2008-12-31", type:"text", onMouseEnter:eventHandler,
 					onMouseLeave:eventHandler,
 					onKeyDown:eventHandler,
 					onChange:function(val){ dojo.byId("oc1").value = "" + val; }
 				'/>
-				onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off"/>
+				<label for="oc1">onChange:</label><input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off"/>
 				<span style='white-space:nowrap;'>
 				<button type="button" onclick="dijit.byId('local').set('value', null);">set('value',null)</button>
 				<button type="button" onclick="dojo.byId('gv1').value=''+dijit.byId('local').get('value');">get('value')</button>
 				<button type="button" onclick="dojo.byId('gv1').value=''+dijit.byId('local').value;">.value</button>
-				<input id="gv1" size="34" disabled value="not called yet!" autocomplete="off"/>
+				<label for="gv1">l:</label><input id="gv1" size="34" disabled value="not called yet!" autocomplete="off"/>
 				</span>
 			</div>
 			<div class="dojoTitlePaneLabel">
 				<label for="localLong"> Date (local format - long) </label>
 				<span class="noticeMessage">DateTextBox class,
-					Attributes: required="true", trim="true", openOnClick=false, constraints={min:'2004-01-01',max:'2006-12-31',formatLength:'long'}. Works for leap years</span>
+					Attributes: required="true", trim="true", constraints={min:'2004-01-01',max:'2006-12-31',formatLength:'long'}. Works for leap years</span>
 			</div>
 			<div class="testExample">
-				<input id="localLong" data-dojo-id="localLong" data-dojo-type="dijit.form.DateTextBox"
+				<input id="localLong" data-dojo-id="localLong" data-dojo-type="dijit/form/DateTextBox"
 					data-dojo-props='type:"text", name:"date1", value:"2005-12-30",
 					constraints:{min:"2004-01-01",max:"2006-12-31",formatLength:"long"},
 					required:true,
 					trim:true,
-					openOnClick:false,
 					onChange:function(val){ dojo.byId("oc2").value = val; },
 					onMouseEnter:eventHandler,
 					onMouseLeave:eventHandler,
 					onKeyDown:eventHandler,
 					invalidMessage:"Invalid date." '/>
- 				onChange:<input id="oc2" size="34" disabled value="not fired yet!" autocomplete="off"/>
+ 				<label for="oc2">onChange:</label><input id="oc2" size="34" disabled value="not fired yet!" autocomplete="off"/>
 				<input type="button" value="Destroy" onClick="dijit.byId('localLong').destroy(); return false;"/>
 				<input type="button" value="set max to 2007-12-31" onClick="dijit.byId('localLong').constraints.max = new Date(2007,11,31); dijit.byId('localLong').validate(false); return false;"/>
 			</div>
@@ -112,7 +353,7 @@
 				</span>
 			</div>
 			<div class="testExample">
-				<input id="american" data-dojo-type="dijit.form.DateTextBox"
+				<input id="american" data-dojo-type="dijit/form/DateTextBox"
 					data-dojo-props='type:"text", name:"date2", value:"2005-12-30",
 					constraints:{min:"2004-01-01",max:"2006-12-31"},
 					lang:"en-us",
@@ -139,17 +380,17 @@
 				<span class="noticeMessage">Date, overriding pattern with dd-MM-yyyy</span>
 			</div>
 			<div class="testExample">
-				<input id="pattern" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='name:"noDOMvalue", type:"text", constraints:{datePattern:"dd-MM-yyyy", strict:true}'/>
+				<input id="pattern" data-dojo-type="dijit/form/DateTextBox" data-dojo-props='name:"noDOMvalue", type:"text", constraints:{datePattern:"dd-MM-yyyy", strict:true}'/>
 			</div>
 			<div class="dojoTitlePaneLabel">
-				<strong>Using title attrib for label</strong>
+				<strong>Using title attribute for label</strong>
 				<span class="noticeMessage">DateTextBox class,
-					Attributes: lang="en-us", required="true", prompt meessage, invalid message
+					Attributes: lang="en-us", required="true", prompt message, invalid message
 					Prompt message whenever field is blank.
 				</span>
 			</div>
 			<div class="testExample">
-				<div id="american2" data-dojo-type="dijit.form.DateTextBox"
+				<div id="american2" data-dojo-type="dijit/form/DateTextBox"
 					data-dojo-props='type:"text", name:"date20", value:"2008-12-30",
 					title:"Date in month, day, year format",
 					lang:"en-us",
@@ -160,30 +401,6 @@
 			</div>
 
 			<script>
-			// See if we can make a widget in script and attach it to the DOM ourselves.
-			dojo.ready(function(){
-				dojo.connect(dijit.byId('pattern'), "onMouseEnter", eventHandler);
-				dojo.connect(dijit.byId('pattern'), "onMouseLeave", eventHandler);
-				dojo.connect(dijit.byId('pattern'), "onKeyDown", eventHandler);
-
-				var props = {
-					name: "date4",
-					value: new Date(2006,10,29),
-					constraints: {min:new Date(2004,0,1),max:new Date(2006,11,31)},
-					lang: "de-de",
-					hasDownArrow: false,
-					onMouseEnter: eventHandler,
-					onMouseLeave: eventHandler,
-					onKeyDown: eventHandler,
-					promptMessage: "dd.mm.yy",
-					rangeMessage: "Enter a date in the year range 2004-2006.",
-					invalidMessage: "Invalid date. Use dd.mm.yy format."
-				};
-				var w = new dijit.form.DateTextBox(props, "german");
-			});
-			</script>
-
-			<script>
 				function displayData(){
 					var f = document.getElementById("form1");
 					var s = "";
@@ -200,17 +417,38 @@
 				 Date pairs, from/to (won't submit unless from/to fields filled in correctly):
 			</div>
 			<div class="testExample">
-				<label for="fromDate">From:</label> <input id="fromDate" data-dojo-type="dijit.form.DateTextBox"
+				<label for="fromDate">From:</label> <input id="fromDate" data-dojo-type="dijit/form/DateTextBox"
 					data-dojo-props='type:"text", name:"fromDate", required:true,
 					onChange:function(){ dijit.byId("toDate").constraints.min = this.get("value"); } '/>
-				<label for="toDate">To:</label> <input id="toDate" data-dojo-type="dijit.form.DateTextBox"
+				<label for="toDate">To:</label> <input id="toDate" data-dojo-type="dijit/form/DateTextBox"
 					data-dojo-props='type:"text", name:"toDate", required:true,
 					onChange:function(){ dijit.byId("fromDate").constraints.max = this.get("value"); } '/>
 
-				<button type="button" name="button" onclick="displayData(); return false;">view data</button>
-				<input type="submit" name="submit" />
-				<input type="reset" name="reset" />
 			</div>
+
+			<div class="dojoTitlePaneLabel">
+				<label for="noyear">Pick a day in 3Q 2011</label>
+			</div>
+			<div class="testExample">
+				<input data-dojo-type="dijit/form/DateTextBox" id="noyear" data-dojo-props='
+					name:"noyear",
+					required:"true",
+					constraints:{datePattern:"MMMM dd",
+						min:new Date(2011,9,1),
+						max:new Date(2011,11,31)
+					},
+					parse:function(){
+						var d = this.inherited("parse", arguments);
+						if(d instanceof Date)d.setFullYear(2011);
+						return d;
+					},
+					value:new Date(2011,10,25)'
+				/>
+			</div>
+
+			<button type="button" name="button" onclick="displayData(); return false;">view data</button>
+			<input type="submit" name="submit" />
+			<input type="reset" name="reset" />
 		</form>
 	</body>
 </html>
diff --git a/dijit/tests/form/test_DateTextBox_iframe.html b/dijit/tests/form/test_DateTextBox_iframe.html
index a09fbcf..549f88e 100644
--- a/dijit/tests/form/test_DateTextBox_iframe.html
+++ b/dijit/tests/form/test_DateTextBox_iframe.html
@@ -1,5 +1,6 @@
-<html>
+<html lang="en">
+<head><title>test_DateTextBox iframe</title></head>
 <body>
-<iframe src="test_DateTextBox.html" width="100%" height="100%" onclick="console.log('iframe click')">
+<iframe src="test_DateTextBox.html" title="test_DateTextBox" width="100%" height="100%" onclick="console.log('iframe click')" role="main"></iframe>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dijit/tests/form/test_Form_onsubmit.html b/dijit/tests/form/test_Form_onsubmit.html
index 6149409..09c979b 100644
--- a/dijit/tests/form/test_Form_onsubmit.html
+++ b/dijit/tests/form/test_Form_onsubmit.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
@@ -35,15 +35,15 @@
 	</script>
 
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Form Widget Submit Test</h1>
 	<p>Tests dojo.stopEvent() etc. calls inside dijit.form.Form onSubmit and onReset callbacks.</p>
-	<form id="myForm1" data-dojo-type="dijit.form.Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
+	<form id="myForm1" data-dojo-type="dijit/form/Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
 		onSubmit:function(e){ dojo.stopEvent(e); },
 		onReset:function(e){ dojo.stopEvent(e); }'>
 		<h3>This form shouldn't submit, nor reset</h3>
-		<select id="combo1" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"plopcombo" '>
+		<select id="combo1" data-dojo-type="dijit/form/ComboBox" data-dojo-props='name:"plopcombo","aria-label":"plopcombo" '>
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
@@ -52,11 +52,11 @@
 		<button id="reset1" data-dojo-type=dijit.form.Button data-dojo-props='type:"reset"'>Reset</button>
 	</form>
 
-	<form id="myForm2" data-dojo-type="dijit.form.Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
+	<form id="myForm2" data-dojo-type="dijit/form/Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
 		onSubmit:function(){ return false; },
 		onReset:function(){ return false; }'>
 		<h3>This form shouldn't submit, nor reset</h3>
-		<select id="combo2" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"plopcombo" '>
+		<select id="combo2" data-dojo-type="dijit/form/ComboBox" data-dojo-props='name:"plopcombo","aria-label":"plopcombo2" '>
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
@@ -65,11 +65,11 @@
 		<button id="reset2" data-dojo-type=dijit.form.Button data-dojo-props='type:"reset"'>Reset</button>
 	</form>
 
-	<form id="myForm3" data-dojo-type="dijit.form.Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
+	<form id="myForm3" data-dojo-type="dijit/form/Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
 		onSubmit:function(){ return true; },
 		onReset:function(){ return true; }'>
 		<h3>This form <em>should</em> submit and reset</h3>
-		<select id="combo3" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"plopcombo" '>
+		<select id="combo3" data-dojo-type="dijit/form/ComboBox" data-dojo-props='name:"plopcombo","aria-label":"plopcombo3" '>
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
@@ -78,11 +78,11 @@
 		<button id="reset3" data-dojo-type=dijit.form.Button data-dojo-props='type:"reset"'>Reset</button>
 	</form>
 
-	<form id="myForm4" data-dojo-type="dijit.form.Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
+	<form id="myForm4" data-dojo-type="dijit/form/Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
 		onSubmit:function(){ void(0) },
 		onReset:function(){ void(0) }'>
 		<h3>This form <em>should</em> submit and reset</h3>
-		<select id="combo4" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"plopcombo" '>
+		<select id="combo4" data-dojo-type="dijit/form/ComboBox" data-dojo-props='name:"plopcombo","aria-label":"plopcombo4" '>
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
@@ -92,7 +92,7 @@
 	</form>
 	
 	<h3>Submitted value:</h3>
-	<input id="textbox" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text"'/>
+	<input id="textbox" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"text","aria-label":"textbox"'/>
 	
 	<iframe name="formSubmitIframe" src="about:blank" onload="if(this.values)submittedValues(this.values)" style="display:none;"></iframe>
 </body>
diff --git a/dijit/tests/form/test_Form_state.html b/dijit/tests/form/test_Form_state.html
index 8c3e4f7..33146f7 100644
--- a/dijit/tests/form/test_Form_state.html
+++ b/dijit/tests/form/test_Form_state.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>dijit.form.Form Valid/Invalid State Test</title>
@@ -29,13 +29,13 @@
 		</script>
 	</head>
 
-	<body class="claro">
+	<body class="claro" role="main">
 		<h1 class="testTitle">dijit.form.Form Valid/Invalid State Test</h1>
 		<p>
 			Tests that dijit.form.Form correctly changes state from valid to invalid (as indicated by disabled/enabled submit button)
 			according to child widget state.
 		</p>
-		<form id="form1" data-dojo-type="dijit.form.Form" data-dojo-props='action:"", name:"example", method:""'>
+		<form id="form1" data-dojo-type="dijit/form/Form" data-dojo-props='action:"", name:"example", method:""'>
 			<script type="dojo/connect" data-dojo-event="startup">
 				var submitButton = dijit.byId("submitButton");
 				//  set initial state
@@ -44,10 +44,10 @@
 						submitButton.set("disabled", !state);
 				});
 			</script>
-			<table>
+			<table role="presentation">
 				<tr>
 					<td><label for="name">Name:</label></td>
-					<td><input id="name" data-dojo-type="dijit.form.ValidationTextBox"
+					<td><input id="name" data-dojo-type="dijit/form/ValidationTextBox"
 						data-dojo-props='required:true, name:"name" '/></td>
 				</tr>
 				<tr id="newRow" style="display: none;">
@@ -56,7 +56,7 @@
 				</tr>
 				<tr>
 					<td><label for="birth">Birthdate (before 2006-12-31):</label><br><br><br><br></td>
-					<td><div><input id="birth" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='value:"2000-01-01",
+					<td><div><input id="birth" data-dojo-type="dijit/form/DateTextBox" data-dojo-props='value:"2000-01-01",
 						required:true, name:"birth", constraints:{min:"1900-01-01", max:"2006-12-31"} '/> <br>
 					<button id="disable" onclick="dijit.byId('birth').set('disabled',true);return false;">Disable</button>
 					<button id="enable" onclick="dijit.byId('birth').set('disabled',false);return false;">Enable</button>
@@ -65,7 +65,7 @@
 				</tr>
 				<tr>
 					<td><label for="notes">Notes (optional)</label></td>
-					<td><input id="notes" data-dojo-type="dijit.form.TextBox"
+					<td><input id="notes" data-dojo-type="dijit/form/TextBox"
 						data-dojo-props='name:"notes" '/></td>
 				</tr>
 				<tr id="newRow2" style="display: none;">
@@ -77,13 +77,13 @@
 					</select></td>
 				</tr>
 			</table>
-			<button id="submitButton" data-dojo-type="dijit.form.Button" >
+			<button id="submitButton" data-dojo-type="dijit/form/Button" >
 				<script type="dojo/method" data-dojo-event="onClick">
 					console.dir(dijit.byId("form1").get('value'));
 				</script>
 				Submit
 			</button>
-			<button id="addMoreFields" data-dojo-type="dijit.form.Button" >
+			<button id="addMoreFields" data-dojo-type="dijit/form/Button" >
 				<script type="dojo/method" data-dojo-event="onClick">
 					new dijit.form.FilteringSelect({id: "color",
 													name: "color",
@@ -103,7 +103,7 @@
 				</script>
 				Add More Fields
 			</button>
-			<button data-dojo-type="dijit.form.Button">
+			<button data-dojo-type="dijit/form/Button">
 				<script type="dojo/method" data-dojo-event="onClick">
 					dijit.byId("name").validate();
 				</script>
diff --git a/dijit/tests/form/test_MultiSelect.html b/dijit/tests/form/test_MultiSelect.html
index cd9d70b..19b875c 100644
--- a/dijit/tests/form/test_MultiSelect.html
+++ b/dijit/tests/form/test_MultiSelect.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Testing MultiSelect form widget | The Dojo Toolkit</title>
@@ -26,80 +26,134 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: false"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
 	<script type="text/javascript">
-		var globalVals = null;
-
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.form.MultiSelect");
-
-		// needed for tests:
-		dojo.require("dijit.form.Form");
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.layout.SplitContainer");
-
-		dojo.ready(function(){
+		require([
+			"doh/runner",
+			"dojo/query",
+			"dojo/dom-form",
+			"dojo/_base/json",
+			"dojo/_base/array",
+			"dojo/_base/lang",
+			"dojo/dom-class",
+			"dojo/parser",
+			"dijit/dijit",
+			"dijit/focus",
+			"dijit/registry",
+			"dijit/form/MultiSelect",
+			"dijit/form/Button",
+			"dijit/form/Form",
+			"dijit/tests/helpers",
+			"dojo/domReady!"
+		], function(doh, query, domForm, json, array, lang, domClass, parser, dijit, focus, registry, MultiSelect, Button, Form,  helpers){
+
+			parser.parse();
+
+			// Add mode=test to the URL to run unit tests.
+			var test = /mode=test/i.test(window.location.href);
 
 			// ref a clonable node, then split it between two selects
-			var c = dojo.query(".clone")[0];
+			var c = query(".clone")[0];
 			var l = -1;
 			opt = function(){
 				return dojo.byId((++l % 2 == 0 ? "select" : "select2" ));
 			};
 			// based on the the 'dijit' object
 			var count=0;
+			var select1Values = "dojo._defaultEasing";
 			for(var i in dijit){
 				var n = opt().appendChild(dojo.clone(c));
 				n.value = count++;
+				if(l % 2 == 0){
+					select1Values += "," + i;
+				}
 				n.innerHTML = i;
 			}
 
 			// turn any non-data-dojo-type selects into widgets programatically:
-			dojo.query("select").forEach(function(n){
+			query("select").forEach(function(n){
 				if(!dijit.byNode(n)){
-					var foo = new dijit.form.MultiSelect({ name: n.name }, n);
+					var foo = new dijit.form.MultiSelect({ name: n.name }, n).startup();
 				}
 			});
 
 			// listen to the "move items" buttons
-			dojo.query("button.switch")
+			query("button.switch")
 				.connect("onclick",function(e){
 					switch(e.target.id.toString()){
-						case "left" : dijit.byId("select").addSelected(dijit.byId("select2")); break;
-						case "right" : dijit.byId("select2").addSelected(dijit.byId("select")); break;
+						case "left" : registry.byId("select").addSelected(registry.byId("select2")); break;
+						case "right" : registry.byId("select2").addSelected(registry.byId("select")); break;
 					}
 			});
 
 			// listen to the invert buttons
-			dojo.query("button.invert")
+			query("button.invert")
 				.connect("onclick",function(e){
 					switch(e.target.id.toString()){
-						case "i1" : dijit.byId("select").invertSelection(); break;
-						case "i2" : dijit.byId("select2").invertSelection(); break;
-						case "i3" : dijit.byId("select3").invertSelection(); break;
+						case "i1" : registry.byId("select").invertSelection(); break;
+						case "i2" : registry.byId("select2").invertSelection(); break;
+						case "i3" : registry.byId("select3").invertSelection(); break;
 					}
 			});
 
 			// there is only one debug button
-			dojo.query(".debug").connect("onclick",function(e){
-				console.log('select value:',dijit.byId("select").get('value') + '/' + dijit.byId("select").value);
-				console.log('select2 value:',dijit.byId("select2").get('value') + '/' + dijit.byId("select2").value);
-				console.log('select3 value:',dijit.byId("select3").get('value') + '/' + dijit.byId("select3").value);
+			query(".debug").connect("onclick",function(e){
+				console.log('select value:',registry.byId("select").get('value') + '/' + registry.byId("select").value);
+				console.log('select2 value:',registry.byId("select2").get('value') + '/' + registry.byId("select2").value);
+				console.log('select3 value:',registry.byId("select3").get('value') + '/' + registry.byId("select3").value);
 			});
 
-			dojo.connect(dojo.byId("formSubmit"), "onclick", function(e){
+			query("#formSubmit").connect("onclick", function(e){
 				// see what the real form says about our widgets:
-				var vals = dojo.formToJson("test");
+				var vals = domForm.toJson("test");
 				console.log(vals);
 			});
+
+			query("#s1").connect("onclick", function(e){
+				registry.byId('select3').set('value', ['VA', 'WA']);
+			});
+
+			if(test){
+				doh.register("API", [
+					function initial(t){
+						var vals = json.fromJson(domForm.toJson("test"));
+						t.is(select1Values, query("option", registry.byId('select').containerNode).map(function(n){ return n.innerHTML; }).join(','));
+						t.is("", registry.byId('select').get('value').join(''), 'easing widget value');
+						t.is("", registry.byId('select2').get('value').join(''), 'second widget value');
+						t.is("TN", registry.byId('select3').get('value').join(''), 'select3 widget value');
+						t.is("", vals.easing, 'easing form value');
+						t.is("", vals.second, 'second form value');
+						t.is("TN", vals.select3, 'select3 form value');
+						t.t(domClass.contains(registry.byId('select2').domNode, "dijitMultiSelect"), 'second base class');
+						t.t(domClass.contains(registry.byId('select3').domNode, "dijitMultiSelect"), 'select3 base class');
+						t.t(domClass.contains(registry.byId('select3').domNode, "addedClass"), 'select3 added class');
+					},
+					{
+						name: "set",
+						timeout: 1000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							registry.byId('select3').set('value', ['TN','FL']);
+							setTimeout(d.getTestCallback(function(){
+								var vals = json.fromJson(domForm.toJson("test"));
+								t.is("TN,FL", registry.byId('select3').get('value').join(','), "select3 widget value");
+								t.is("TN,FL", vals.select3, "select3 form value");
+							}), 500);
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			}
 		});
 	</script>
 </head>
-<body class="claro" style="padding:20px">
+<body class="claro" style="padding:20px" role="main">
 
 		<h1 class="testTitle">dijit.form.MultiSelect:</h1>
 		<p>Select one or more items in First or Second list and move them between lists using the buttons provided.</p>
@@ -136,9 +190,8 @@
 
 		<h3><label for="select3">markup:</label></h3>
 
-		<select id="select3" multiple data-dojo-type="dijit.form.MultiSelect"
-			data-dojo-props='name:"select3",
-			style:{height:"200px", width:"175px", border:"5px solid #ededed"}'>
+		<select class="addedClass" id="select3" multiple data-dojo-type="dijit/form/MultiSelect"
+			data-dojo-props='name:"select3",style:{height:"200px", width:"175px", border:"5px solid #ededed"}'>
 
 			<option value="TN" selected>Tennessee</option>
 			<option value="VA">Virginia</option>
@@ -150,7 +203,6 @@
 		</form>
 		<br><br>
 		<button class='invert' id="i3">invert markup list</button>
-		<button class='set' id="s1" onclick="dijit.byId('select3').set('value', ['VA', 'WA']);">set markup list to [VA, WA]</button>
-		
+		<button class='set' id="s1">set markup list to [VA, WA]</button>
 </body>
 </html>
diff --git a/dijit/tests/form/test_Select.html b/dijit/tests/form/test_Select.html
index 447a19c..e70a25c 100644
--- a/dijit/tests/form/test_Select.html
+++ b/dijit/tests/form/test_Select.html
@@ -1,55 +1,126 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>dijit.form.Select test</title>
+		<title>dijit/form/Select test</title>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 		<style>
 			@import url(../../themes/claro/document.css);
-			@import url(../../themes/claro/claro.css);
 			@import url(../css/dijitTests.css);
 			.ark { text-decoration: underline; }
 			form {
 				margin:  10px 0px;
 				border:  solid gray 2px;
 			}
+			.area {
+				border: 1px solid gray;
+				padding: 2px;
+				display: inline;
+				white-space: nowrap;
+			}
+			h3 {
+				margin: 0;
+			}
+			body .customStyled .dijitSelect,
+			body .customStyled .dijitSelect .dijitButtonContents {
+				border-width: 2px;
+				border-color: blue;
+			}
+			body .customStyled .dijitSelect .dijitInputField {
+				padding: 5px;
+				font-family: Arial;
+				font-size: 150%;
+			}
+			.dj_a11y .dijitSelect,
+			.dj_a11y .dijitSelect .dijitButtonContents {
+				border-width: medium !important;
+			}
+			.dj_a11y .dijitSelect,
+			.dj_a11y .customStyled .dijitSelect,
+			.dj_a11y .dijitSelect *,
+			.dj_a11y .customStyled .dijitSelect * {
+				background-color: white !important;
+				background-image: none !important;
+				border-color: black !important;
+				color: black !important;
+			}
 		</style>
-
-		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 	
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true"></script>
 	
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../_testCommon.js"></script>
 
-		<script type="text/javascript" src="../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.require("dojo.parser");
-			dojo.require("dijit.form.Select");
-			dojo.require("dijit.form.Button");
-			dojo.require("dijit.form.Form");
-			dojo.require("dojo.data.ItemFileWriteStore");
-			dojo.require("dijit.Dialog");
-
-			var numOptions = 0;
-			var numChanges = 0;
-			var addNum = 10;
-
-			// Add test=true to the URL to run unit tests.
-			// Add testPerformance=true to the URL to run performance tests - note SLOW to run
-			var test = /mode=test/i.test(window.location.href),
-				testPerformance = /mode=benchmark/i.test(window.location.href);
-
-			// Data and stores here for store-based selects
-			var data = {
-				identifier: "value",
-				label: "label",
-				items: [
+			require([
+				"doh/runner",
+				"dojo/_base/array",
+				"dojo/_base/lang",
+				"dojo/parser",
+				"dojo/data/ItemFileReadStore",	// for testing old API (remove for 2.0)
+				"dojo/data/ItemFileWriteStore",	// for testing old API (remove for 2.0)
+				"dojo/store/Memory",
+				"dojo/store/Observable",
+				"dijit/focus",
+				"dijit/registry",
+				"dijit/form/Select",
+				"dijit/form/Button",
+				"dijit/form/Form",
+				"dijit/Dialog",
+				"dijit/Tooltip",
+				"dijit/tests/helpers",
+				"dojo/domReady!"
+			], function(doh, array, lang, parser, ItemFileReadStore, ItemFileWriteStore, Memory, Observable,
+						focus, registry, Select, Button, Form, Dialog, Tooltip, helpers){
+
+				var numOptions = 0;
+				var numChanges = 0;
+				var addNum = 10;
+	
+				// Add test=true to the URL to run unit tests.
+				// Add testPerformance=true to the URL to run performance tests - note SLOW to run
+				var test = /mode=test/i.test(window.location.href),
+					testPerformance = /mode=benchmark/i.test(window.location.href);
+	
+				// dojo/data (legacy) data stores
+				var data = {
+					identifier: "value",
+					label: "label",
+					items: [
+						{value: "AL", label: "Alabama"},
+						{value: "AK", label: "Alaska"},
+						{value: "AZ", label: "Arizona"},
+						{value: "AR", label: "Arkansas"},
+						{value: "CA", label: "California"},
+						{value: "CO", label: "Colorado"},
+						{value: "CT", label: "Connecticut"}
+					]
+				};
+				var data2 = {
+					identifier: "value",
+					label: "label",
+					items: [
+						{value: "DE", label: "Delaware"},
+						{value: "FL", label: "Florida"},
+						{value: "GA", label: "Georgia"},
+						{value: "HI", label: "Hawaii"},
+						{value: "ID", label: "Idaho"},
+						{value: "IL", label: "Illinois"},
+						{value: "IN", label: "Indiana"}
+					]
+				};
+	
+				readStore = new ItemFileReadStore({data: lang.clone(data)});
+				store2 = new ItemFileReadStore({data: lang.clone(data2)});
+				writeStore = new ItemFileWriteStore({data: lang.clone(data)});
+
+				// dojo/store (new API) data stores
+				var vals = [
 					{value: "AL", label: "Alabama"},
 					{value: "AK", label: "Alaska"},
 					{value: "AZ", label: "Arizona"},
@@ -57,12 +128,8 @@
 					{value: "CA", label: "California"},
 					{value: "CO", label: "Colorado"},
 					{value: "CT", label: "Connecticut"}
-				]
-			};
-			var data2 = {
-				identifier: "value",
-				label: "label",
-				items: [
+				];
+				var vals2 = [
 					{value: "DE", label: "Delaware"},
 					{value: "FL", label: "Florida"},
 					{value: "GA", label: "Georgia"},
@@ -70,37 +137,43 @@
 					{value: "ID", label: "Idaho"},
 					{value: "IL", label: "Illinois"},
 					{value: "IN", label: "Indiana"}
-				]
-			};
-
-			var readStore = new dojo.data.ItemFileReadStore({data:dojo.clone(data)});
-			var store2 = new dojo.data.ItemFileReadStore({data:dojo.clone(data2)});
-			var writeStore = new dojo.data.ItemFileWriteStore({data:dojo.clone(data)});
+				];
+				memoryStore = new Memory({
+					idProperty: "value",
+					data: lang.clone(vals)
+				});
+				memoryStore2 = new Memory({
+					idProperty: "value",
+					data: lang.clone(vals2)
+				});
+				memoryStore3 = new Observable(new Memory({	// updates will reflect to select
+					idProperty: "value",
+					data: lang.clone(vals)
+				}));
 
-			function wrapLabel(expected){
-				return ("<span class=\"dijitReset dijitInline dijitSelectLabel\">" + expected + "</span>").toLowerCase().replace(/ */g, "");
-			}
+				parser.parse();
 
-			dojo.ready(function(){
-				dojo.connect(s1, "onChange", function(val){
+				s1.on("change", function(val){
 					console.log("First Select Changed to " + val);
 					numChanges++;
 				});
 
-				var programmatic = new dijit.form.Select({
+				var programmatic = new Select({
 					options: [
 						{ label: 'foo', value: 'foo', selected: true },
 						{ label: 'bar', value: 'bar' }
-					]
+					],
+					"aria-label":"programmatic"
 				});
 				programmatic.placeAt('testProgramatic');
 
-				var programmaticDisabled = new dijit.form.Select({
+				var programmaticDisabled = new Select({
 					disabled: true,
 					options: [
 						{ label: 'foo', value: 'foo', selected: true },
 						{ label: 'bar', value: 'bar' }
-					]
+					],
+					"aria-label":"programmatic disabled"
 				});
 				programmaticDisabled.placeAt('testProgramatic');
 
@@ -112,7 +185,7 @@
 							runTest: function(t){
 								var d = new doh.Deferred();
 								t.is("VA", form.get("value").s1, "initial value");
-								s1.set("value", "WA"); // set s1 to a valid value
+								s1.set("value", s1.getOptions(2)); // set s1 to a valid value via index search
 								t.is("WA", s1.value);
 
 								setTimeout(function(){ try{ // allow onChange to fire
@@ -138,6 +211,38 @@
 							}
 						},
 						{
+							name: "test_set by number",
+							timeout: 5000,
+							runTest: function(t){
+								var d = new doh.Deferred();
+								t.is(100, form.get("value").s5, "initial value");
+								s5.set("value", s5.getOptions(2)); // set s5 to a valid value via index search
+								t.is(102, s5.value);
+
+								setTimeout(function(){ try{ // allow onChange to fire
+
+									// set s5 to non-existing value, which (currently) makes the Select pick
+									// the first option in the drop down
+									s5.set("value", 200);
+									t.is(100, s5.value);
+
+									setTimeout(function(){ try{ // allow onChange to fire
+										t.is(2, numChanges);
+										
+										// prevent onChange from firing
+										s5.set("value", 103, false);
+										t.t(/.*No Move.*/.test(s5.containerNode.innerHTML), s5.containerNode.innerHTML);
+										
+										setTimeout(function(){ try{ // allow onChange to fire if it's wrong
+											t.is(2, numChanges);
+											d.callback(true);
+										}catch(e){ d.errback(e); }}, 0)
+									}catch(e){ d.errback(e); }}, 0);
+								}catch(e){ d.errback(e); }}, 0);
+								return d;
+							}
+						},
+						{
 							name: 'test_disabled',
 							runTest: function(t){
 								t.is(testDisabled.disabled, true);
@@ -151,37 +256,71 @@
 								t.is(programmaticDisabled.disabled, true);
 							}
 						},
-
+						function test_setOptions(t){
+							programmatic.set('options', data2.items);
+							programmatic.reset();
+							t.is(7, programmatic.getOptions().length);
+							t.is("DE", programmatic.value);
+						},
 						// Test that destroying a Select destroys the internal Menu and MenuItems too
 						{
 							name: "test_destroy",
 							timeout: 5000,
 							runTest: function(t){
-								var oldCnt = dijit.registry.length;
+								var oldCnt = registry.length;
 									
 								s1.destroy();
 
-								var newCnt = dijit.registry.length;
+								var newCnt = registry.length;
 								t.t(newCnt < oldCnt + 3, "should have destroyed many widgets, went from " + oldCnt + " to " + newCnt);
 							}
+						},
+						{
+							name: "aria attributes",
+							timeout: 2000,
+							runTest:function(){
+								var d = new doh.Deferred();
+								select = registry.byId("s2");
+																
+								doh.is("listbox", select._popupStateNode.getAttribute("role"), "select _popupStateNode role");
+								doh.t(select._popupStateNode.getAttribute("aria-haspopup"), "aria-haspopup on select");
+								doh.f(select._popupStateNode.getAttribute("aria-expanded"), "initially false aria-expanded");
+								doh.f(select._popupStateNode.getAttribute("aria-owns"), "initially missing aria-owns");
+
+								select.openDropDown();
+								setTimeout(d.getTestCallback(function(){
+									doh.t(select._popupStateNode.getAttribute("aria-expanded"), "now aria-expanded should be true");
+									doh.is("s2_menu", select._popupStateNode.getAttribute("aria-owns"), "should aria-own the menu");
+									// Check roles and attributes on the Menu
+									var menu = registry.byId("s2_menu");
+									doh.is("listbox", menu.domNode.getAttribute("role"), "Dlg.domNode should have a role");
+									doh.is("s2", menu.domNode.getAttribute("aria-labelledby"), "aria-labelledby should point back to button");
+								}), 0);
+
+								return d;
+							},
+							tearDown:function(){
+								select.closeDropDown();
+							}
 						}
 					]);
 
-					doh.register("data store", [
+					// Test legacy dojo/data API, remove for 2.0
+					doh.register("dojo/data store", [
 						// Tests that when the currently selected item is changed in the data store,
 						// the change is reflected in the Select widget
 						function test_changeSelected(t){
 							t.is("AL", s11.value);
-							t.is(wrapLabel("Alabama"), s11.containerNode.innerHTML.toLowerCase().replace(/ */g, ""));
-							s11.set("value", "AK");
+							t.t(/<span.*>Alabama<\/span>/i.test(s11.containerNode.innerHTML), "expected Alabama but got " + s11.containerNode.innerHTML);
+							s11.set("value", ["AK"]); // test array
 							t.is("AK", s11.value);
-							t.is(wrapLabel("Alaska"), s11.containerNode.innerHTML.toLowerCase().replace(/ */g, ""));
+							t.t(/<span.*>Alaska<\/span>/i.test(s11.containerNode.innerHTML), "expected Alaska but got " + s11.containerNode.innerHTML);
 							var d = new doh.Deferred();
 							writeStore.fetchItemByIdentity({
 								identity: "AK",
 								onItem: d.getTestCallback(function(item){
 									writeStore.setValue(item, "label", "North Pole");
-									t.is(wrapLabel("North Pole"), s11.containerNode.innerHTML.toLowerCase().replace(/ */g, ""), "select displayed value updated");
+									t.t(/<span.*>North Pole<\/span>/i.test(s11.containerNode.innerHTML), "expected North Pole but got " + s11.containerNode.innerHTML);
 								})
 							});
 							return d;
@@ -228,9 +367,9 @@
 							var d = new doh.Deferred();
 							writeStore.newItem({value: "NY", label: "New York"});
 							setTimeout(d.getTestCallback(function(){
-									t.is(6, s11.getOptions().length);
-									s11.set("value", "NY");
-									t.is("NY", s11.value);
+								t.is(6, s11.getOptions().length);
+								s11.set("value", s11.getOptions({ label: "New York" })); // set via label search
+								t.is("NY", s11.value);
 							}), 100);
 
 							return d;
@@ -251,9 +390,81 @@
 						}
 					]);
 
+					doh.register("dojo/store", [
+						// Tests that when the currently selected item is changed in the data store,
+						// the change is reflected in the Select widget
+						function test_changeSelected(t){
+							t.is("AL", ds11.value);
+							t.t(/<span.*>Alabama<\/span>/i.test(ds11.containerNode.innerHTML));
+							ds11.set("value", "AK");
+							t.is("AK", ds11.value);
+							t.t(/<span.*>Alaska<\/span>/i.test(ds11.containerNode.innerHTML));
+
+							var item = memoryStore3.get("AK");
+							item.label = "North Pole";
+							memoryStore3.put(item);
+							t.t(/<span.*>North Pole<\/span>/i.test(ds11.containerNode.innerHTML), "select displayed value updated");
+						},
+
+						// Test that a delete of the non-selected item will remove that item from the Select's
+						// list of options.
+						function test_deleteNonSelected(t){
+							t.is(7, ds11.getOptions().length);
+							t.is("AK", ds11.value);
+
+							memoryStore3.remove("AZ");
+							t.is(6, ds11.getOptions().length);
+						},
+
+						// Test that a delete of the selected item will remove that item from the Select's
+						// list of options, and switch to a new selected item
+						function test_deleteSelected(t){
+							t.is(6, ds11.getOptions().length);
+							t.is("AK", ds11.value);
+
+							memoryStore3.remove("AK");
+							t.is("AL", ds11.value);
+							t.is(5, ds11.getOptions().length);
+						},
+
+						// Test that new items added to the data store appear in the select's options
+						function test_newItem(t){
+							t.is(5, ds11.getOptions().length);
+							t.is("AL", ds11.value);	
+
+							memoryStore3.add({value: "NY", label: "New York"});
+
+							// TODO: try w/out the timeout
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+									t.is(6, ds11.getOptions().length);
+									ds11.set("value", "NY");
+									t.is("NY", ds11.value);
+							}), 100);
+							return d;
+						},
+
+						// Test that a Select's store can be changed
+						// TODO: should be supported/tested through set("store", ...), although
+						// I guess that wouldn't allow setting the selected item at the same time.
+						function test_setStore(t){
+							t.is(7, ds12.getOptions().length);
+							t.is("AL", ds12.value);
+							ds12.setStore(memoryStore2, "FL");
+							t.is(7, ds12.getOptions().length);
+							t.is("FL", ds12.value);
+							ds12.setStore(memoryStore, "CA");
+							t.is(7, ds12.getOptions().length);
+							t.is("CA", ds12.value);
+							ds12.setStore(memoryStore2);
+							t.is(7, ds12.getOptions().length);
+							t.is("DE", ds12.value);
+						}
+					]);
+					
 					doh.register("validation", [
 						function required(){
-							var s3 = dijit.byId("s3");
+							var s3 = registry.byId("s3");
 							doh.is("Incomplete", s3.get("state"), "incomplete because required but no value");
 
 							var stateWatch = "no notification";
@@ -275,27 +486,27 @@
 						function showDialog(){
 							// Show dialog, returning Deferred that fires when show dialog is finished.
 							// Before showing, focus the open button, so that Dialog knows where to return focus to.
-							dijit.byId("dlg1OpenBtn").focus();
-							return dijit.byId("dlg1").show();
+							registry.byId("dlg1OpenBtn").focus();
+							return registry.byId("dlg1").show();
 						},
 						function validateDialog(){
 							// Clicking validate button should show "required but empty" tooltip on the Select
 							var d = new doh.Deferred();
-							dijit.byId("dlg1ValidateBtn").focus();
-							dijit.byId("dlg1").validate();
+							registry.byId("dlg1ValidateBtn").focus();
+							registry.byId("dlg1").validate();
 							setTimeout(d.getTestCallback(function(){
-								doh.is("dlg1Select", dijit._curFocus && dijit._curFocus.id, "focused on select");
-								masterTT = dojo.global.dijit._masterTT;
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
+								doh.is("dlg1Select", focus.curNode && focus.curNode.id, "focused on select");
+								masterTT = Tooltip._masterTT;
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
 							}), 300);
 							return d;
 						},
 						function hideDialog(){
 							// Hiding the dialog should make the validation tooltip disappear
 							var d = new doh.Deferred();
-							dijit.byId("dlg1").hide().then(function(){
+							registry.byId("dlg1").hide().then(function(){
 								setTimeout(d.getTestCallback(function(){
-									doh.t(isHidden(masterTT.domNode), "tooltip hidden");
+									doh.t(helpers.isHidden(masterTT.domNode), "tooltip hidden");
 								}), 300);
 							});
 							return d;
@@ -303,25 +514,25 @@
 						function showDialogAgain(){
 							// Show dialog, returning Deferred that fires when show dialog is finished.
 							// Before showing, focus the open button, so that Dialog knows where to return focus to.
-							dijit.byId("dlg1OpenBtn").focus();
-							return dijit.byId("dlg1").show();
+							registry.byId("dlg1OpenBtn").focus();
+							return registry.byId("dlg1").show();
 						},
 						function tooltipAppears(){
 							// Opening the dialog focuses the select, which is invalid since it's got no value.
 							// Since this is the second time it's being focused, it should popup the tooltip
 							// immediately.
 							var d = new doh.Deferred();
-							dijit.byId("dlg1ValidateBtn").focus();
-							dijit.byId("dlg1").validate();
+							registry.byId("dlg1ValidateBtn").focus();
+							registry.byId("dlg1").validate();
 							setTimeout(d.getTestCallback(function(){
-								doh.is("dlg1Select", dijit._curFocus && dijit._curFocus.id, "focused on select");
-								masterTT = dojo.global.dijit._masterTT;
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
+								doh.is("dlg1Select", focus.curNode && focus.curNode.id, "focused on select");
+								masterTT = Tooltip._masterTT;
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
 							}), 300);
 							return d;
 						},
 						function tearDown(){
-							return dijit.byId("dlg1").hide();
+							return registry.byId("dlg1").hide();
 						}
 					]);
 
@@ -329,27 +540,27 @@
 						function showDialog(){
 							// Show dialog, returning Deferred that fires when show dialog is finished.
 							// Before showing, focus the open button, so that Dialog knows where to return focus to.
-							dijit.byId("dlg2OpenBtn").focus();
-							return dijit.byId("dlg2").show();
+							registry.byId("dlg2OpenBtn").focus();
+							return registry.byId("dlg2").show();
 						},
 						function validateDialog(){
 							// Clicking validate button should show "required but empty" tooltip on the Select
 							var d = new doh.Deferred();
-							dijit.byId("dlg2ValidateBtn").focus();
-							dijit.byId("dlg2").validate();
+							registry.byId("dlg2ValidateBtn").focus();
+							registry.byId("dlg2").validate();
 							setTimeout(d.getTestCallback(function(){
-								doh.is("dlg2Select1", dijit._curFocus && dijit._curFocus.id, "focused on select");
-								masterTT = dojo.global.dijit._masterTT;
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
+								doh.is("dlg2Select1", focus.curNode && focus.curNode.id, "focused on select");
+								masterTT = Tooltip._masterTT;
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
 							}), 300);
 							return d;
 						},
 						function hideDialog(){
 							// Hiding the dialog should make the validation tooltip disappear
 							var d = new doh.Deferred();
-							dijit.byId("dlg2").hide().then(function(){
+							registry.byId("dlg2").hide().then(function(){
 								setTimeout(d.getTestCallback(function(){
-									doh.t(isHidden(masterTT.domNode), "tooltip hidden");
+									doh.t(helpers.isHidden(masterTT.domNode), "tooltip hidden");
 								}), 300);
 							});
 							return d;
@@ -384,10 +595,10 @@
 								}
 							},
 							runTest: function(t){
-								dojo.forEach(t.options, function(opt){
+								array.forEach(t.options, function(opt){
 									s6.addOption(opt);
 								});
-								dojo.forEach(t.options, function(opt){
+								array.forEach(t.options, function(opt){
 									s6.removeOption(opt);
 								});
 							},
@@ -424,18 +635,22 @@
 			});
 		</script>
 	</head>
-	<body class="claro">
-		<h1 class="testTitle">Test: dijit.form.Select</h1>
+	<body class="claro" role="main">
+		<h1 class="testTitle">Test: dijit/form/Select</h1>
 
 		<p>
 			Note: load <a href="test_Select.html?mode=test">test_Select.html?mode=test</a> to run unit tests, or
 			<a href="test_Select.html?mode=benchmark">test_Select.html?mode=benchmark</a> to run performance tests.
 		</p>
 
+		<script type="dojo/require">
+			registry: "dijit/registry"
+		</script>
+
 		<form method="get" id="htmlForm" action="get">
 			<h2>HTML select for comparison</h2>
 			<label for="htmlSelect">Four options:</label>
-			<select id="htmlSelect">
+			<select id="htmlSelect" title="native title">
 				<option value="one">one</option>
 				<option value="two">two</option>
 				<option value="three">three</option>
@@ -445,31 +660,35 @@
 			<select id="htmlSelect2">
 			</select>
 		</form>
-		<form id="form" data-dojo-id="form" data-dojo-type="dijit.form.Form" method="get"
+		<form id="form" data-dojo-id="form" data-dojo-type="dijit/form/Form" method="get"
 				onSubmit="return this.validate();">
-			<h2>dijit.form.Select form</h2>
+			<h2>dijit/form/Select form</h2>
 			<h4 class="testSubtitle">Setting Defaults</h4>
 			<label for="s1">Test One: </label>
-			<select id="s1" data-dojo-id="s1" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s1" '>
+			<select id="s1" data-dojo-id="s1" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s1" '>
 				<option value="TN">Tennessee</option>
 				<option value="VA" selected="selected">Virginia</option>
 				<option value="WA">Washington</option>
 				<option value="FL">Florida</option>
 				<option value="CA">California</option>
 			</select>
-			<button id="s1button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ console.log(s1.get("displayedValue")); }'>
+			<button id="s1button" data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", onClick:function(){ console.log(s1.get("displayedValue")); }'>
 				Get Displayed Value
 			</button>
 			<label for="s2">Test Two: </label>
-			<select id="s2" data-dojo-id="s2" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s2", value:"CA" '>
+			<select id="s2" data-dojo-id="s2" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s2", value:"CA", title: "widget title" '>
 				<option value="AL">Alabama</option>
 				<option value="AK">Alaska</option>
 				<option value="AZ">Arizona</option>
 				<option value="AR">Arkansas</option>
 				<option value="CA">California</option>
+				<option value="NH">New Hampshire</option>
+				<option value="NJ">New Jersey</option>
+				<option value="NM">New Mexico</option>
+				<option value="NY">New York</option>
 			</select>
 			<label for="s3">Test Three (required): </label>
-			<select id="s3" data-dojo-id="s3" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s3", style:{width:"150px"},
+			<select id="s3" data-dojo-id="s3" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s3", style:{width:"150px"},
 					required:true,
 					onChange: function(){
 						if(!this.options[0].value){
@@ -488,48 +707,48 @@
 			</select>
 		<hr>
 			<h4 class="testSubtitle">Rich Text (Need to use divs and spans - since browsers hack selects to pieces)</h4>
-			<label>Rich text One: 
-			<span id="s4" data-dojo-id="s4" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s4", value:"AK" '>
+			<label id="ls4">Rich text One:</label>
+			<span id="s4" data-dojo-id="s4" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s4", value:"AK", "aria-labelledby":"ls4" '>
 				<span data-dojo-value="AL"><b>Alabama</b></span>
 				<span data-dojo-value="AK"><span style="color:red;">A</span><span style="color:orange;">l</span><span style="color:yellow;">a</span><span style="color:green;">s</span><span style="color:blue;">k</span><span style="color:purple;">a</span></span>
 				<span data-dojo-value="AZ"><i>Arizona</i></span>
 				<span data-dojo-value="AR"><span class="ark">Arkansas</span></span>
 				<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
 				<button value="NM" disabled="disabled">New<br>  Mexico</button>
-			</span></label>
-			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ s4.set("disabled", !s4.get("disabled")); }'>
+			</span>
+			<button data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", onClick:function(){ s4.set("disabled", !s4.get("disabled")); }'>
 				Toggle Disabled
 			</button>
-			<label>Rich text two: 
-			<span id="s5" data-dojo-id="s5" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s5", value:"move" '>
-				<span data-dojo-value="copy"><img style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndCopy.png" /> Copy</span>
-				<span data-dojo-value="move"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndMove.png" /> Move</span>
-				<span data-dojo-value="nocopy"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoCopy.png" /> No Copy</span>
-				<span data-dojo-value="nomove"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoMove.png" /> No Move</span>
-				<span data-dojo-value="long"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoMove.png" /> Very Long Menu Entry</span>
-			</span></label>
+			<label for="s5">Rich text two: </label>
+			<span id="s5" data-dojo-id="s5" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s5", value:"move"'>
+				<span data-dojo-value=100><img style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndCopy.png" alt="copy" /> Copy</span>
+				<span data-dojo-value=101><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndMove.png" alt="move" /> Move</span>
+				<span data-dojo-value=102><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoCopy.png" alt="no copy" /> No Copy</span>
+				<span data-dojo-value=103><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoMove.png" alt="no move" /> No Move</span>
+				<span data-dojo-value=104><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoMove.png" alt="very long menu" /> Very Long Menu Entry</span>
+			</span>
 		<hr>
 			<h4 class="testSubtitle"><label for="s6">Initially Empty</label></h4>
-			<select id="s6" data-dojo-id="s6" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s6", maxHeight:100 '>
+			<select id="s6" data-dojo-id="s6" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s6", maxHeight:100 '>
 			</select>
-			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ numOptions++; s6.addOption({value: numOptions + "", label: "Option " + numOptions}); }'>
+			<button data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", onClick:function(){ numOptions++; s6.addOption({value: numOptions + "", label: "Option " + numOptions}); }'>
 				Add Option
 			</button>
-			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ s6.removeOption(0); }'>
+			<button data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", onClick:function(){ s6.removeOption(0); }'>
 				Remove Top Option
 			</button>
-			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ s6.set("disabled", !s6.get("disabled")); }'>
+			<button data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", onClick:function(){ s6.set("disabled", !s6.get("disabled")); }'>
 				Toggle Disabled
 			</button>
 			<hr>
 		<h4 class="testSubtitle"><label for="s7">Single Item</label></h4>
-			<select id="s7" data-dojo-id="s7" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s7" '>
+			<select id="s7" data-dojo-id="s7" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s7" '>
 				<option value="NY">New York</option>
 			</select>
 		<hr>
 		<h4 class="testSubtitle">Long lists</h4>
 			<label for="s8a">maxHeight=200:</label>
-			<select id="s8a" data-dojo-id="s8a" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s8a", maxHeight:200 '>
+			<select id="s8a" data-dojo-id="s8a" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s8a", maxHeight:200 '>
 				<option value="AL">Alabama</option>
 				<option value="AK">Alaska</option>
 				<option value="AZ">Arizona</option>
@@ -583,7 +802,7 @@
 				<option value="WY">Wyoming</option>
 			</select>
 			<label for="s8b">no maxHeight:</label>
-			<select id="s8b" data-dojo-id="s8b" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s8b" '>
+			<select id="s8b" data-dojo-id="s8b" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s8b" '>
 				<option value="AL">Alabama</option>
 				<option value="AK">Alaska</option>
 				<option value="AZ">Arizona</option>
@@ -636,24 +855,45 @@
 				<option value="WI">Wisconsin</option>
 				<option value="WY">Wyoming</option>
 			</select>
+
 			<hr>
-			<h4 class="testSubtitle">Store-based</h4>
+			<h4 class="testSubtitle">dojo/data store (legacy API) based</h4>
 			<label for="s9">Example 1</label>
-			<select id="s9" data-dojo-id="s9" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s9", store:readStore, value:"CT" '>
+			<select id="s9" data-dojo-id="s9" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s9", store:readStore, value:"CT" '>
 			</select>
 			<label for="s10">Example 2</label>
-			<select id="s10" data-dojo-id="s10" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s10", store:readStore '>
+			<select id="s10" data-dojo-id="s10" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s10", store:readStore '>
 			</select>
 			<label for="s11">Example 3</label>
-			<select id="s11" data-dojo-id="s11" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s11", store:writeStore '>
+			<select id="s11" data-dojo-id="s11" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s11", store:writeStore '>
 			</select>
 			<label for="s12">Example 4</label>
-			<select id="s12" data-dojo-id="s12" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s12", store:readStore '>
+			<select id="s12" data-dojo-id="s12" data-dojo-type="dijit/form/Select" data-dojo-props='name:"s12", store:readStore '>
 			</select>
+
+			<hr>
+			<h4 class="testSubtitle">dojo/store based</h4>
+			<label for="ds9">Example 1</label>
+			<select id="ds9" data-dojo-id="ds" data-dojo-type="dijit/form/Select"
+					data-dojo-props='name:"ds", store:memoryStore, value:"CT", labelAttr:"label" '>
+			</select>
+			<label for="ds10">Example 2</label>
+			<select id="ds10" data-dojo-id="ds10"
+					data-dojo-type="dijit/form/Select" data-dojo-props='name:"ds10", store:memoryStore, labelAttr:"label" '>
+			</select>
+			<label for="ds11">Example 3</label>
+			<select id="ds11" data-dojo-id="ds11" data-dojo-type="dijit/form/Select"
+					data-dojo-props='name:"ds11", store:memoryStore3, labelAttr:"label" '>
+			</select>
+			<label for="ds12">Example 4</label>
+			<select id="ds12" data-dojo-id="ds12" data-dojo-type="dijit/form/Select"
+					data-dojo-props='name:"ds12", store:memoryStore, labelAttr:"label" '>
+			</select>
+
 			<hr>
 			<h4 class="testSubtitle">Inlined with text (all IE modes except for IE8 Standards)</h4>
 			<label for="txtPrompt">Text Prompt:</label>
-			<select id="txtPrompt" data-dojo-type="dijit.form.Select" >
+			<select id="txtPrompt" data-dojo-type="dijit/form/Select" >
 				<option value="SEL" selected="selected">Select</option>
 				<option value="OTHER">Other</option>
 			</select>
@@ -661,7 +901,7 @@
 			<hr>
 			<h4 class="testSubtitle">More required but blank selects</h4>
 			<label for="s13">required s13:</label>
-			<select id="s13" data-dojo-id="s13" data-dojo-type="dijit.form.Select"
+			<select id="s13" data-dojo-id="s13" data-dojo-type="dijit/form/Select"
 					name="s13" style="width: 150px;" required="true">
 				<option> </option>
 				<option value="AL">Alabama</option>
@@ -673,7 +913,7 @@
 				<option value="CA">California</option>
 			</select>
 			<label for="s14">required s14:</label>
-			<select id="s14" data-dojo-id="s14" data-dojo-type="dijit.form.Select"
+			<select id="s14" data-dojo-id="s14" data-dojo-type="dijit/form/Select"
 					name="s14" style="width: 150px;" required="true">
 				<option> </option>
 				<option value="AL">Alabama</option>
@@ -686,15 +926,15 @@
 			</select>
 
 			<hr>
-			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ console.dir(form.getValues()); }'>
+			<button data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", onClick:function(){ console.dir(form.getValues()); }'>
 				Get Values
 			</button>
-			<button data-dojo-type="dijit.form.Button" data-dojo-props='id:"submit", type:"submit"'>Submit</button>
+			<button data-dojo-type="dijit/form/Button" data-dojo-props='id:"submit", type:"submit"'>Submit</button>
 		</form>
 
 		<h4 class="testSubtitle">Disabled</h4>
 		<label for="testDisabled">Disabled:</label>
-		<select id='testDisabled' data-dojo-id='testDisabled' data-dojo-type="dijit.form.Select" data-dojo-props='disabled:true, name:"testDisabled" '>
+		<select id='testDisabled' data-dojo-id='testDisabled' data-dojo-type="dijit/form/Select" data-dojo-props='disabled:true, name:"testDisabled" '>
 			<option value="foo">foo</option>
 			<option value="bar">bar</option>
 		</select>
@@ -703,11 +943,11 @@
 		<div id="testProgramatic"></div>
 
 		<!-- testing that tooltip disappears when dialog is closed -->
-		<div dojoType="dijit.Dialog" id="dlg1">
-			<div dojoType="dijit.form.Select" id="dlg1Select"required="true"></div>
-			<div dojoType="dijit.form.Button" id="dlg1ValidateBtn">
-				<script type=dojo/method event="onClick">
-					var dlg1 = dijit.byId("dlg1");
+		<div dojoType="dijit/Dialog" id="dlg1">
+			<div dojoType="dijit/form/Select" id="dlg1Select"required="true"></div>
+			<div dojoType="dijit/form/Button" id="dlg1ValidateBtn">
+				<script type=dojo/method data-dojo-event="onClick">
+					var dlg1 = registry.byId("dlg1");
 					if(dlg1.validate()){
 						dlg1.hide();
 					}
@@ -715,15 +955,15 @@
 				validate and close
 			</div>
 		</div>
-		<button dojoType="dijit.form.Button" id="dlg1OpenBtn"
-				onclick="dijit.byId('dlg1').show();">show one select dialog</button>
-
-		<div dojoType="dijit.Dialog" id="dlg2">
-			<div dojoType="dijit.form.Select" id="dlg2Select1"required="true"></div>
-			<div dojoType="dijit.form.Select" id="dlg2Select2"required="true"></div>
-			<div dojoType="dijit.form.Button" id="dlg2ValidateBtn">
-				<script type=dojo/method event="onClick">
-					var dlg2 = dijit.byId("dlg2");
+		<button dojoType="dijit/form/Button" id="dlg1OpenBtn"
+				onclick="registry.byId('dlg1').show();">show one select dialog</button>
+
+		<div dojoType="dijit/Dialog" id="dlg2">
+			<div dojoType="dijit/form/Select" id="dlg2Select1"required="true"></div>
+			<div dojoType="dijit/form/Select" id="dlg2Select2"required="true"></div>
+			<div dojoType="dijit/form/Button" id="dlg2ValidateBtn">
+				<script type=dojo/method data-dojo-event="onClick">
+					var dlg2 = registry.byId("dlg2");
 					if(dlg2.validate()){
 						dlg2.hide();
 					}
@@ -731,7 +971,250 @@
 				validate and close
 			</div>
 		</div>
-		<button dojoType="dijit.form.Button" id="dlg2OpenBtn"
-				onclick="dijit.byId('dlg2').show();">show two select dialog</button>
+		<button dojoType="dijit/form/Button" id="dlg2OpenBtn"
+				onclick="registry.byId('dlg2').show();">show two select dialog</button>
+		<br>
+		<fieldset class="area">
+			<legend>Rendering tests</legend>
+			<fieldset class="area">
+				<legend>unstyled widget</legend>
+				<fieldset class="area">
+					<legend id="lr1">normal</legend>
+					<select aria-labelledby="lr1" id="r1" data-dojo-type="dijit/form/Select">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="lr2">disabled</legend>
+					<select aria-labelledby="lr2" id="r2" data-dojo-type="dijit/form/Select" disabled>
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="lr3">error</legend>
+					<select id="r3" aria-labelledby="lr3" data-dojo-type="dijit/form/Select" class="dijitError dijitSelectError dijitValidationTextBoxError" data-dojo-props="required:true">
+						<option data-dojo-value=""></option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="lr4">hover</legend>
+					<select id="r4" aria-labelledby="lr4" data-dojo-type="dijit/form/Select" class="dijitHover dijitSelectHover">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="lr5">focused</legend>
+					<select id="r5" aria-labelledby="lr5" data-dojo-type="dijit/form/Select" class="dijitFocused dijitSelectFocused">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="lr6">RTL</legend>
+					<select id="r6" aria-labelledby="lr6" data-dojo-type="dijit/form/Select" dir="rtl">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="lr7">RTL error</legend>
+					<select id="r7" aria-labelledby="lr7" data-dojo-type="dijit/form/Select" class="dijitError dijitSelectError dijitValidationTextBoxError" dir="rtl" data-dojo-props="required:true">
+						<option data-dojo-value=""></option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="lr8">styled option</legend>
+					<span id="r8" aria-labelledby="lr8" data-dojo-type="dijit/form/Select">
+						<span data-dojo-value="1"><span style="font-size:200%;color:pink;">Large</span></span>
+						<span data-dojo-value="2">2</span>
+					</span>
+				</fieldset>
+			</fieldset>
+			<br>
+			<fieldset class="area">
+				<legend>width:60px;font-family:Arial;font-size:150%;border:2px blue;padding:5px;color:red</legend>
+				<fieldset class="area customStyled">
+					<legend id="lcs1">normal</legend>
+					<select id="cs1" aria-labelledby="lcs1" data-dojo-type="dijit/form/Select" style="color:red;width:60px;">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lcs2">disabled</legend>
+					<select id="cs2" aria-labelledby="lcs2" data-dojo-type="dijit/form/Select" style="color:red;width:60px;" disabled>
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lcs3">error</legend>
+					<select id="cs3" aria-labelledby="lcs3" data-dojo-type="dijit/form/Select" class="dijitError dijitSelectError dijitValidationTextBoxError" style="color:red;width:60px;" data-dojo-props="required:true">
+						<option data-dojo-value=""></option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lcs4">hover</legend>
+					<select id="cs4" aria-labelledby="lcs4" data-dojo-type="dijit/form/Select" class="dijitHover dijitSelectHover" style="color:red;width:60px;">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lcs5">focused</legend>
+					<select id="cs5" data-dojo-type="dijit/form/Select" aria-labelledby="lcs5" class="dijitFocused dijitSelectFocused" style="color:red;width:60px;">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lcs6">RTL</legend>
+					<select id="cs6" aria-labelledby="lcs6" data-dojo-type="dijit/form/Select" dir="rtl" style="color:red;width:60px;">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lcs7">RTL error</legend>
+					<select id="cs7" aria-labelledby="lcs7" data-dojo-type="dijit/form/Select" class="dijitError dijitSelectError dijitValidationTextBoxError" style="color:red;width:60px;" dir="rtl" data-dojo-props="required:true">
+						<option data-dojo-value=""></option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lcs8">styled option</legend>
+					<span id="cs8" aria-labelledby="lcs8" data-dojo-type="dijit/form/Select" style="color:red;width:120px;">
+						<span data-dojo-value="1"><span style="font-size:200%;color:pink;">Large</span></span>
+						<span data-dojo-value="2">2</span>
+					</span>
+				</fieldset>
+			</fieldset>
+			<br>
+			<fieldset class="area dj_a11y">
+				<legend>a11y, unstyled</legend>
+				<fieldset class="area">
+					<legend id="la1">normal</legend>
+					<select id="a1" aria-labelledby="la1" data-dojo-type="dijit/form/Select">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="la2">disabled</legend>
+					<select id="a2" aria-labelledby="la2" data-dojo-type="dijit/form/Select" disabled>
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="la3">error</legend>
+					<select id="a3" aria-labelledby="la3" data-dojo-type="dijit/form/Select" class="dijitError dijitSelectError dijitValidationTextBoxError" data-dojo-props="required:true">
+						<option data-dojo-value=""></option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="la4">hover</legend>
+					<select id="a4" aria-labelledby="la4" data-dojo-type="dijit/form/Select" class="dijitHover dijitSelectHover">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="la5">focused</legend>
+					<select id="a5" aria-labelledby="la5" data-dojo-type="dijit/form/Select" class="dijitFocused dijitSelectFocused">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="la6">RTL</legend>
+					<select id="a6" aria-labelledby="la6" data-dojo-type="dijit/form/Select" dir="rtl">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="la7">RTL error</legend>
+					<select id="a7" aria-labelledby="la7" data-dojo-type="dijit/form/Select" class="dijitError dijitSelectError dijitValidationTextBoxError" dir="rtl" data-dojo-props="required:true">
+						<option data-dojo-value=""></option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area">
+					<legend id="la8">styled option</legend>
+					<span id="a8" aria-labelledby="la8" data-dojo-type="dijit/form/Select">
+						<span data-dojo-value="1"><span style="font-size:200%;color:pink;">Large</span></span>
+						<span data-dojo-value="2">2</span>
+					</span>
+				</fieldset>
+			</fieldset>
+			<br>
+			<fieldset class="area dj_a11y">
+				<legend>a11y styled</legend>
+				<fieldset class="area customStyled">
+					<legend id="lacs1">normal</legend>
+					<select id="acs1" aria-labelledby="lacs1" data-dojo-type="dijit/form/Select" style="color:red;width:60px;">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lacs2">disabled</legend>
+					<select id="acs2" aria-labelledby="lacs2" data-dojo-type="dijit/form/Select" style="color:red;width:60px;" disabled>
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lacs3">error</legend>
+					<select id="acs3" aria-labelledby="lacs3" data-dojo-type="dijit/form/Select" class="dijitError dijitSelectError dijitValidationTextBoxError" style="color:red;width:60px;" data-dojo-props="required:true">
+						<option data-dojo-value=""></option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lacs4">hover</legend>
+					<select id="acs4" aria-labelledby="lacs5" data-dojo-type="dijit/form/Select" class="dijitHover dijitSelectHover" style="color:red;width:60px;">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lacs5">focused</legend>
+					<select id="acs5" aria-labelledby="lacs5" data-dojo-type="dijit/form/Select" class="dijitFocused dijitSelectFocused" style="color:red;width:60px;">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lacs6">RTL</legend>
+					<select id="acs6" aria-labelledby="lacs6" data-dojo-type="dijit/form/Select" dir="rtl" style="color:red;width:60px;">
+						<option data-dojo-value="1">1</option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lacs7">RTL error</legend>
+					<select id="acs7" aria-labelledby="lacs7" data-dojo-type="dijit/form/Select" class="dijitError dijitSelectError dijitValidationTextBoxError" style="color:red;width:60px;" dir="rtl" data-dojo-props="required:true">
+						<option data-dojo-value=""></option>
+						<option data-dojo-value="2">2</option>
+					</select>
+				</fieldset>
+				<fieldset class="area customStyled">
+					<legend id="lacs8">styled option</legend>
+					<span id="acs8" aria-labelledby="lacs8" data-dojo-type="dijit/form/Select" style="color:red;width:120px;">
+						<span data-dojo-value="1"><span style="font-size:200%;color:pink;">Large</span></span>
+						<span data-dojo-value="2">2</span>
+					</span>
+				</fieldset>
+			</fieldset>
+		</fieldset>
 	</body>
 </html>
diff --git a/dijit/tests/form/test_SimpleTextarea.html b/dijit/tests/form/test_SimpleTextarea.html
index 834c9f4..919cab2 100644
--- a/dijit/tests/form/test_SimpleTextarea.html
+++ b/dijit/tests/form/test_SimpleTextarea.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Testing SimpleTextArea | The Dojo Toolkit</title>
@@ -28,7 +28,7 @@
 	</script>
 </head>
 
-<body class="claro" style="padding:20px">
+<body class="claro" style="padding:20px" role="main">
 
 		<h1 class="testTitle">SimpleTextarea</h1>
 
@@ -37,8 +37,8 @@
 			It can be used inside layout containers.
 		</p>
 
-		<h2>Plain textarea (rows=5, cols=50), selectOnClick=true</h2>
-		<textarea id="ta1" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"ta1", rows:"5", cols:"50",
+		<h2><label for="ta1">Plain textarea (rows=5, cols=50), selectOnClick=true</label></h2>
+		<textarea id="ta1" data-dojo-type="dijit/form/SimpleTextarea" data-dojo-props='name:"ta1", rows:"5", cols:"50",
 			onFocus:function(){ console.log("user focus handler") },
 			onBlur:function(){ console.log("user blur handler") },
 			onChange:function(val){ dojo.byId("oc1").value = "" + val; },
@@ -46,35 +46,35 @@
 		'>
 			shichashaw, textarea text baw.
 		</textarea>
-		onChange:<textarea id="oc1" rows="6" cols="50" disabled >not fired yet!</textarea>
+		<label for="oc1">onChange:</label><textarea id="oc1" rows="6" cols="50" disabled >not fired yet!</textarea>
 		<span style='white-space:nowrap;'>
 		<button id="resetButton" onclick="dijit.byId('ta1').reset();">reset</button>
 		<button id="setNullButton" onclick="dijit.byId('ta1').set('value', null);">set value to null</button>
 		<button id="getValueButton" onclick="dojo.byId('gv1').value=''+dijit.byId('ta1').get('value');">get value</button>
-		<textarea id="gv1" rows="6" cols="50" disabled >no value yet!</textarea>
+		<textarea id="gv1" rows="6" cols="50" disabled aria-label="hi">no value yet!</textarea>
 		</span>
 
 
-		<h2>Plain textarea with style="height: 300px; width: 300px" rows="" cols=""</h2>
-		<textarea id="ta2" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"ta2",
+		<h2><label for="ta2">Plain textarea with style="height: 300px; width: 300px" rows="" cols=""</label></h2>
+		<textarea id="ta2" data-dojo-type="dijit/form/SimpleTextarea" data-dojo-props='name:"ta2",
 			style:{height:"300px", width:"300px"}, rows:"", cols:""'>I have a style setting rather than rows/cols setting</textarea>
 
 		<h2>In a BorderContainer</h2>
 
-		<div id="container" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:{width:"500px", height:"400px", border:"inset gray 3px"}'>
-			<textarea id="top" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"top", region:"top", splitter:true, style:{height:"100px"}'>
+		<div id="container" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='style:{width:"500px", height:"400px", border:"inset gray 3px"}'>
+			<textarea id="top" data-dojo-type="dijit/form/SimpleTextarea" aria-label="top" data-dojo-props='name:"top", region:"top", splitter:true, style:{height:"100px"}'>
 				This is just some text in the top region.
 			</textarea>
-			<textarea id="left" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"left", region:"left", splitter:true, style:{width:"200px"}'>
+			<textarea id="left" data-dojo-type="dijit/form/SimpleTextarea" aria-label="left" data-dojo-props='name:"left", region:"left", splitter:true, style:{width:"200px"}'>
 				This is just some text in the left region.
 			</textarea>
-			<textarea id="center" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"center", region:"center"'>
+			<textarea id="center" data-dojo-type="dijit/form/SimpleTextarea" aria-label="center" data-dojo-props='name:"center", region:"center"'>
 				This is just some text in the center region.
 			</textarea>
-			<textarea id="right" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"right", region:"right", splitter:true, style:{width:"200px"}'>
+			<textarea id="right" data-dojo-type="dijit/form/SimpleTextarea" aria-label="right" data-dojo-props='name:"right", region:"right", splitter:true, style:{width:"200px"}'>
 				This is just some text in the right region.
 			</textarea>
-			<textarea id="bottom" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"bottom", region:"bottom", splitter:true, style:{height:"100px"}'>
+			<textarea id="bottom" data-dojo-type="dijit/form/SimpleTextarea" aria-label="bottom" data-dojo-props='name:"bottom", region:"bottom", splitter:true, style:{height:"100px"}'>
 				This is just some text in the bottom region.
 			</textarea>
 		</div>
diff --git a/dijit/tests/form/test_Slider.html b/dijit/tests/form/test_Slider.html
index d63e578..19e387b 100644
--- a/dijit/tests/form/test_Slider.html
+++ b/dijit/tests/form/test_Slider.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Dojo Slider Widget Demo</title>
@@ -41,25 +41,28 @@
 				dojo.require("dojo.parser"); // scan page for widgets
 
 				// programatic vertical slider and labels
-				var programaticExample = function(){
+				var programaticExample = function(noSrcNodeRef){
 
-					var node = dojo.byId("programaticSlider");
+					var node;
+					if (!noSrcNodeRef){ node = dojo.byId("programaticSlider"); }
 					// or var node = dojo.body().appendChild(document.createElement('div'));
 
-					// our rules are to be children of the slider
-					var rulesNode = document.createElement('div');
-					node.appendChild(rulesNode);
-
 					// setup the rules
 					var sliderRules = new dijit.form.VerticalRule({
 						count:11,
 						style:{width:"5px"}
-					},rulesNode);
+					}, noSrcNodeRef ? undefined : dojo.create("div", {}, node));
+
+					// setup RuleLabels
+					var sliderRuleLabels = new dijit.form.VerticalRuleLabels({
+						labels: ["low", "mid", "high"]
+					}, noSrcNodeRef ? undefined : dojo.create("div", {}, node));
 
 					// and setup the slider
-					var theSlider = new dijit.form.VerticalSlider({
+					var sliderProps = {
 						value:1400,
 						name:"programaticSlider",
+						"aria-label":"programatic slider",
 						slideDuration:0,
 						onChange:function(val){ dojo.byId('sliderProgInput').value=val; },
 						style:{height:"165px"},
@@ -68,18 +71,42 @@
 						discreteValues:11,
 						intermediateChanges:"true",
 						showButtons:"true"
-					},node);
+					};
 
-					// and start them both
-					theSlider.startup();
-        				sliderRules.startup();
+					if(noSrcNodeRef){
+						// give no-srcNodeRef test instance distinguishable name/id
+						sliderProps.id = sliderProps.name = "programmaticSliderNoSrc";
+					}
+
+					var theSlider = new dijit.form.VerticalSlider(sliderProps, node);
 
+					if(noSrcNodeRef){
+						node = theSlider.containerNode;
+						// call placeAt if we're not using srcNodeRef
+						theSlider.placeAt("form1");
+						sliderRules.placeAt(node);
+						sliderRuleLabels.placeAt(node);
+					}
+
+					// and start them all
+					theSlider.startup();
+					sliderRules.startup();
+					sliderRuleLabels.startup();
 				};
+				// test programmatic VerticalSlider/Rule/RuleDef with srcNodeRef
 				dojo.ready(programaticExample);
+				// test programmatic VerticalSlider/Rule/RuleDef WITHOUT srcNodeRef
+				dojo.ready(function(){
+					try{
+						programaticExample(true);
+					}catch(e){
+						console.error("BUG #13815", e);
+					}
+				});
 		</script>
 	</head>
 
-	<body class="claro">
+	<body class="claro" role="main">
 		<h1 class="testTitle">Slider</h1>
 		Also try using the arrow keys, buttons, or clicking on the progress bar to move the slider.
 		<br>
@@ -88,7 +115,7 @@
 		<form id="form1" action="" name="example" method="post">
 		<br>initial value=10, min=0, max=100, pageIncrement=100, onChange event triggers input box value change immediately<br>
 		<strong>Horizontal Slider Example</strong>
-		<div id="slider1" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props='name:"horizontal1",
+		<div id="slider1" data-dojo-type="dijit/form/HorizontalSlider" aria-label="slider 1" data-dojo-props='name:"horizontal1",
 			onChange:function(val){ dojo.byId("slider1input").value=dojo.number.format(val/100,{places:1,pattern:"#%"}); },
 			value:10,
 			maximum:100,
@@ -99,42 +126,43 @@
 			slideDuration:500,
 			style:{width:"50%", height:"20px"}
 			'>
-				<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:{height:"1.2em",fontSize:"75%"}, count:6, numericMargin:1'></ol>
-				<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"topDecoration", count:6, style:{height:"5px"}'></div>
-				<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:{height:"5px"}'></div>
-				<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:{height:"1em",fontSize:"75%"}'>
+				<ol data-dojo-type="dijit/form/HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:{height:"1.2em",fontSize:"75%"}, count:6, numericMargin:1'></ol>
+				<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='container:"topDecoration", count:6, style:{height:"5px"}'></div>
+				<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:{height:"5px"}'></div>
+				<ol data-dojo-type="dijit/form/HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:{height:"1em",fontSize:"75%"}'>
 					<li>lowest</li>
 					<li>normal</li>
 					<li>highest</li>
 				</ol>
 		</div>
 
-		Slider1 Value:<input readonly id="slider1input" size="4" value="10.0%"/>
+		<label for="slider1input">Slider1 Value:</label><input readonly id="slider1input" size="4" value="10.0%"/>
 		<br>
-		<button id="disableButton" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("slider1").set("disabled", true);dijit.byId("disableButton").set("disabled",true);dijit.byId("enableButton").set("disabled",false); }'>Disable previous slider</button>
-		<button id="enableButton" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("slider1").set("disabled",false);dijit.byId("disableButton").set("disabled",false);dijit.byId("enableButton").set("disabled", true); }, disabled:true'>Enable previous slider</button>
+		<button id="disableButton" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ dijit.byId("slider1").set("disabled", true);dijit.byId("disableButton").set("disabled",true);dijit.byId("enableButton").set("disabled",false); }'>Disable previous slider</button>
+		<button id="enableButton" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ dijit.byId("slider1").set("disabled",false);dijit.byId("disableButton").set("disabled",false);dijit.byId("enableButton").set("disabled", true); }, disabled:true'>Enable previous slider</button>
 		<br>
 		<br>initial value=10, min=0, max=100, onChange event triggers input box value change when you mouse up or tab away<br>
 		<strong>Vertical Slider Example</strong>
-		<div id="slider2" data-dojo-type="dijit.form.VerticalSlider" data-dojo-props='name:"vertical1",
+		<div id="slider2" data-dojo-type="dijit/form/VerticalSlider" data-dojo-props='name:"vertical1",
 			onChange:function(val){ dojo.byId("slider2input").value = val; },
 			value:10,
 			maximum:100,
 			minimum:0,
 			discreteValues:11,
+			"aria-label":"slider 2",
 			style:{height:"300px"}
 			'>
-				<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props='container:"leftDecoration", style:{width:"2em"}, labelStyle:"right:0px;"'>
+				<ol data-dojo-type="dijit/form/VerticalRuleLabels" data-dojo-props='container:"leftDecoration", style:{width:"2em"}, labelStyle: document.documentElement.dir=="rtl" ? "left:3px;" : "right:3px;"'>
 					<li>0</li>
 					<li>100</li>
 				</ol>
-				<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props='container:"leftDecoration", count:11, style:{width:"5px"}, ruleStyle:"border-color: #888"'></div>
-				<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props='container:"rightDecoration", count:11, style:{width:"5px"}, ruleStyle:"border-color: #888"'></div>
-				<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props='container:"rightDecoration", style:{width:"2em"}, count:6, numericMargin:1, maximum:100, constraints:{pattern:"#"}'></ol>
+				<div data-dojo-type="dijit/form/VerticalRule" data-dojo-props='container:"leftDecoration", count:11, style:{width:"5px"}, ruleStyle:"border-color: #888"'></div>
+				<div data-dojo-type="dijit/form/VerticalRule" data-dojo-props='container:"rightDecoration", count:11, style:{width:"5px"}, ruleStyle:"border-color: #888"'></div>
+				<ol data-dojo-type="dijit/form/VerticalRuleLabels" data-dojo-props='container:"rightDecoration", style:{width:"2em"}, count:6, numericMargin:1, maximum:100, constraints:{pattern:"#"}'></ol>
 		</div>
-		Slider2 Value:<input readonly id="slider2input" size="3" value="10"/>
+		<label for="slider2input">Slider2 Value:</label><input readonly id="slider2input" size="3" value="10"/>
 		<h1>Fancy HTML labels (no slide animation):</h1>
-		<div id="slider3" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props='name:"horizontal2",
+		<div id="slider3" data-dojo-type="dijit/form/HorizontalSlider" aria-label="slider 3" data-dojo-props='name:"horizontal2",
 			title:"Fancy HTML Labels",
 			minimum:1,
 			value:2,
@@ -145,22 +173,22 @@
 			slideDuration:0,
 			style:"width:300px; height: 40px;"
 			'>
-				<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:3, style:{height:"5px"}'></div>
-				<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:{height:"1em", fontSize:"75%"}'>
-					<li><img width=10 height=10 src="../images/note.gif"/><br><span style="font-size: small">small</span></li>
-					<li><img width=15 height=15 src="../images/note.gif"/><br><span style="font-size: medium">medium</span></li>
-					<li><img width=20 height=20 src="../images/note.gif"/><br><span style="font-size: large">large</span></li>
+				<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='container:"bottomDecoration", count:3, style:{height:"5px"}'></div>
+				<ol data-dojo-type="dijit/form/HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:{height:"1em", fontSize:"75%"}'>
+					<li><img width=10 height=10 alt="small" src="../images/note.gif"/><br><span style="font-size: small">small</span></li>
+					<li><img width=15 height=15 alt="medium" src="../images/note.gif"/><br><span style="font-size: medium">medium</span></li>
+					<li><img width=20 height=20 alt="large" src="../images/note.gif"/><br><span style="font-size: large">large</span></li>
 				</ol>
 		</div>
 
 		<p></p><h1>Standalone ruler example:</h1><p></p>
 
 		<div style="width:2in;border-top:1px solid black;">
-			<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='count:17, style:{height:".4em"}'></div>
-			<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='count:9, style:{height:".4em"}'></div>
-			<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='count:5, style:{height:".4em"}'></div>
-			<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='count:3, style:{height:".4em"}'></div>
-			<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='labelStyle:"font-style:monospace;fontSize:.7em;margin:-1em 0px 0px -.35em;"'>
+			<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='count:17, style:{height:".4em"}'></div>
+			<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='count:9, style:{height:".4em"}'></div>
+			<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='count:5, style:{height:".4em"}'></div>
+			<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='count:3, style:{height:".4em"}'></div>
+			<ol data-dojo-type="dijit/form/HorizontalRuleLabels" data-dojo-props='labelStyle:"font-style:monospace;fontSize:.7em;margin:-1em 0px 0px -.35em;"'>
 				<li></li>
 				<li>1</li>
 				<li>2</li>
@@ -169,7 +197,7 @@
 
 		<h1>horizontal, with buttons, disabled (to show styling):</h1>
 
-		<div id="sliderH2" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props='name:"horizontalH2",
+		<div id="sliderH2" aria-label="horizontal slider 2" data-dojo-type="dijit/form/HorizontalSlider" data-dojo-props='name:"horizontalH2",
 			onChange:function(val){ dojo.byId("slider1input").value = val; },
 			value:10,
 			maximum:100,
@@ -179,10 +207,10 @@
 			intermediateChanges:true,
 			style:{width:"50%", height:"20px"}
 			'>
-				<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:{height:"1.2em", fontSize:"75%"}, count:7, constraints:{pattern:"#.00%"}'></ol>
-				<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"topDecoration", count:7, style:"height:5px;"'></div>
-				<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:"height:5px;"'></div>
-				<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:{height:"1em", fontSize:"75%"}'>
+				<ol data-dojo-type="dijit/form/HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:{height:"1.2em", fontSize:"75%"}, count:7, constraints:{pattern:"#.00%"}'></ol>
+				<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='container:"topDecoration", count:7, style:"height:5px;"'></div>
+				<div data-dojo-type="dijit/form/HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:"height:5px;"'></div>
+				<ol data-dojo-type="dijit/form/HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:{height:"1em", fontSize:"75%"}'>
 					<li>lowest</li>
 					<li>normal</li>
 					<li>highest</li>
@@ -194,7 +222,7 @@
 		<h3>min:1000, max:3000, 11 discrete values, no animation</h3>
 
 		<div id="programaticSlider"></div>
-		Programmatic Value:<input readonly id="sliderProgInput" size="5" value="1400"/>
+		<label for="sliderProgInput">Programmatic Value:</label><input readonly id="sliderProgInput" size="5" value="1400"/>
 
 		        <script>
 				// so robot can get to it easily
diff --git a/dijit/tests/form/test_Spinner.html b/dijit/tests/form/test_Spinner.html
index 915955e..e21ed13 100644
--- a/dijit/tests/form/test_Spinner.html
+++ b/dijit/tests/form/test_Spinner.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Dojo Spinner Widget Test</title>
@@ -33,7 +33,7 @@
 
 	</head>
 
-	<body class="claro">
+	<body class="claro" role="main">
 		<h1 class="testTitle">Dijit Spinner Test</h1>
 			Try typing values, and use the up/down arrow keys and/or the arrow push
 			buttons to spin
@@ -43,14 +43,14 @@
 			<br>
 			initial value=900, no delta specified, no min specified, max=1550, onChange captured, big font<br>
 			<label for="integerspinner1">Spinbox #1: </label><br>
-			<input id="integerspinner1" data-dojo-type="dijit.form.NumberSpinner"
+			<input id="integerspinner1" data-dojo-type="dijit/form/NumberSpinner"
 				data-dojo-props='onChange:function(val){ dojo.byId("oc1").value = val; },
 				value:900,
 				"class":"bigFont",
 				constraints:{max:1550,places:0},
 				name:"integerspinner1"
 				'/>
-			onChange:<input id="oc1" disabled value="not fired yet!" autocomplete="off"/>
+			<label for="oc1">onChange:</label><input id="oc1" disabled value="not fired yet!" autocomplete="off"/>
 			<input type="button" id="sv1_1" value="Set value to 400" onClick="dijit.byId('integerspinner1').set('value',400)" tabIndex="-1"/>
 			<input type="button" id="sv1_2" value="Set value to null" onClick="dijit.byId('integerspinner1').set('value',null)" tabIndex="-1"/>
 			<input type="button" id="sv1_3" value="Set required to false" onClick="dijit.byId('integerspinner1').set('required',false)" tabIndex="-1"/>
@@ -59,19 +59,20 @@
 			<br>
 			initial value=1000, delta=10, min=9 max=1550<br>
 			<label for="integerspinner2">Spinbox with custom styling (width=50%, 200% Courier font): </label>
-			<input id="integerspinner2" data-dojo-type="dijit.form.NumberSpinner"
+			<input id="integerspinner2" data-dojo-type="dijit/form/NumberSpinner"
 				data-dojo-props='style:{fontSize:"200%", fontFamily:"Courier", border:"1px solid blue", width:"50%"},
 				value:1000,
 				smallDelta:10,
 				largeDelta:100,
 				constraints:{min:9,max:1550,places:0},
+				style:{ textAlign: "right" },
 				name:"integerspinner2"
 				'/>
 			<br>
 			<br>
 			<label for="integertextbox3">Spinner line break test: </label>initial value not specified, delta not specified, min not specified, max not specified, signed not specified, separator not specified<br>
 			[verify no line break just after this text]
-			<input id="integertextbox3" data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='name:"integertextbox3" '/>
+			<input id="integertextbox3" data-dojo-type="dijit/form/NumberSpinner" data-dojo-props='name:"integertextbox3" '/>
 			[verify no line break just before this text]
 			<br>
 			<br>
@@ -79,7 +80,7 @@
 			<br>
 			initial value=+1.0, smalldelta=0.1, largedelta=1.0, min=-10.9, max=155, places=1, maxLength=20, exponent=false<br>
 			<label for="realspinner1">Real Number Spinbox #1: </label><br>
-			<input id="realspinner1" data-dojo-type="dijit.form.NumberSpinner"
+			<input id="realspinner1" data-dojo-type="dijit/form/NumberSpinner"
 				data-dojo-props='value:1.0,
 				smallDelta:0.1,
 				largeDelta:1.0,
@@ -91,7 +92,7 @@
 
 			<p>
 			<label for="spinnerMinOnly">Spinner with no maximum, 1 decimal place: </label><br>
-			<input id="spinnerMinOnly" data-dojo-type="dijit.form.NumberSpinner"
+			<input id="spinnerMinOnly" data-dojo-type="dijit/form/NumberSpinner"
 				data-dojo-props='value:1.0,
 				smallDelta:0.1,
 				largeDelta:1.0,
diff --git a/dijit/tests/form/test_Textarea.html b/dijit/tests/form/test_Textarea.html
index 5036980..08e3af8 100644
--- a/dijit/tests/form/test_Textarea.html
+++ b/dijit/tests/form/test_Textarea.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <!-- IE8 beta 2 incorrectly sets TEXTAREA scrollHeight when using strict DTD -->
-<html>
+<html lang="en">
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Dojo dijit.form.Textarea Widget Test</title>
@@ -13,44 +13,75 @@
 		</style>
 
 		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+		<link id="themeStyles" rel="stylesheet" href="../../themes/claro/claro.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../_testCommon.js"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-			dojo.require("dijit.form.Textarea");
-			dojo.require("dijit.layout.ContentPane");
-			dojo.require("dijit.layout.TabContainer");
-			dojo.require("dojo.parser");
+			require([
+				"dojo/dom", "dojo/_base/lang", "dojo/parser",
+				"dijit/registry", "dijit/form/Textarea", "dijit/layout/ContentPane", "dijit/layout/TabContainer",
+				"dojo/domReady!"
+			], function(dom, lang, parser, registry, Textarea){
+				parser.parse();
+
+				programmaticTextarea = new Textarea({
+					id: "programmatic",
+					name: "programmaticTextArea",
+					cols: "70",
+					value: "created programatically with\ncustom border, padding,\nmargin",
+					style: {display:"block", border:"5px solid gray", padding:"11px", margin:"7px", fontSize:"14px", minHeight:"49px", maxHeight:"125px"}
+				});
+				setTimeout(function(){ programmaticTextarea.placeAt("programmaticContainer").startup(); }, 500); // make sure sizing can happen later
+
+				displayData = function(){
+					var f = dom.byId("form1");
+					var s = "";
+					for(var i = 0; i < f.elements.length; i++){
+						var elem = f.elements[i];
+						if(elem.name == "button" || !lang.isString(elem.value)){ continue; }
+						s += elem.name + ":[" + elem.value + "]\n";
+					}
+					console.log(s);
+				};
+
+				setAttr = function(attr, value){
+					var widgets = registry.findWidgets(document.body);
+					for(var i = 0 ; i < widgets.length; i++){
+						if(widgets[i].isInstanceOf(Textarea)){
+							widgets[i].set(attr, value);
+						}
+					}
+				}
+			});
 		</script>
 
 	</head>
-	<body class="claro">
+	<body class="claro" role="main">
 
 		<h1 class="testTitle">Auto-sizing Textarea Widget Test</h1>
 
 		<!--    to test form submission, you'll need to create an action handler similar to
 		        http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
-		<form id="form1" action="" name="example" method="GET" style="width: 800px;">
-
-			<h2>Various dijit.form.Textarea widgets</h2>
+		<form id="form1" action="" name="example" method="GET">
+			<fieldset class="dijitReset" style="width:800px;">
+			<legend>Various dijit.form.Textarea widgets</legend>
 			<label for="blank">dijit.form.Textarea, initially blank:</label>
-			<textarea id="blank" data-dojo-type="dijit.form.Textarea" ></textarea>
+			<textarea id="blank" data-dojo-type="dijit/form/Textarea" data-dojo-props='style:{ fontSize:"24px" }'></textarea>
 			<br>
 
 			<label for="simple">dijit.form.Textarea, inline with maxLength=50:</label>
-			<textarea id="simple" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"simpleTextArea", maxLength:"50", style:{width:"33%"},
+			<textarea id="simple" data-dojo-type="dijit/form/Textarea" data-dojo-props='name:"simpleTextArea", maxLength:"50", style:{width:"33%"},
 	         		onChange:function(val){ dojo.byId("ocSimple").value = val; },
 	         		onFocus:function(){ console.log("user focus handler"); },
 	         		onBlur:function(){ console.log("user blur handler"); }
 				'>this is a very simple resizable text area</textarea>
-			onChange:<textarea id="ocSimple" readOnly>not fired yet!</textarea>
+			<label for="ocSimple">onChange:</label><textarea id="ocSimple" readOnly>not fired yet!</textarea>
 			<br>
 
 			<label for="plain">Native HTML textarea, for comparison: </label><textarea name="plainTextArea" id="plain" rows="3">
@@ -59,34 +90,23 @@
 			</textarea>
 			<br>
 
-			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='persist:true, tabStrip:true, style:{width:"100%", height:"20em"}'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
-					<label for="programmatic">dijit.form.Textarea in TabContainer, programmatically created with custom styling:</label><br>
-					<textarea id="programmatic"></textarea>
+			<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='persist:true, tabStrip:true, style:{width:"100%", fontSize:"14px", height:"17em"}, "aria-label":"tabContainer"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1", "aria-label":"contentpane"'>
+					<label for="programmatic">dijit.form.Textarea in TabContainer, programmatically created with custom styling:</label>
+					<div id="programmaticContainer"></div>
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>
 					<input type="button" onclick="programmaticTextarea.set('value', 'new value for programmatic textarea\nmore text for testing\nmore\neven more\nvery last line');" value="change value"/>
 				</div>
 			</div>
-			<script type="text/javascript">
-				// See if we can make a widget in script
-				dojo.ready(function(){
-					programmaticTextarea = new dijit.form.Textarea({
-						id: "programmatic",
-						name: "programmaticTextArea",
-						cols: "60",
-						value: "created programatically with custom border, padding, margin",
-						style: {border:"5px solid gray", padding:"11px", margin:"7px", minHeight:"2em"}
-					}, "programmatic");
-				});
-			</script>
+			</fieldset>
 			<br>
 
 
 			<label for="largeTextArea">dijit.form.Textarea, initially full:</label>
 <!--	‪ and ‬ are inserted solely for testing purposes to mark the beginning and end of left-to-right text so that 
 	cogniscent browsers don't render garbled punctuation nor exhibit strange home/end key behavior while in right-to-left mode -->
-		<textarea id="largeTextArea" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"largeTextArea" '>
+			<textarea id="largeTextArea" data-dojo-type="dijit/form/Textarea" data-dojo-props='name:"largeTextArea", style:{ width:"90%" }'>
 ‪This is a textarea with a LOT of content.‬
 
 Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril d [...]
@@ -109,12 +129,7 @@ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
 
 ‪This is the end.‬</textarea>
 
-			<h2>Set properties for every dijit.form.Textarea</h2>			
-			<script>
-				function setAttr(attr, value){
-					dijit.registry.byClass('dijit.form.Textarea').forEach(function(widget){ widget.set(attr, value);});
-				}
-			</script>
+			<h2>Set properties for every dijit.form.Textarea</h2>
 			<input type="button" onclick="setAttr('readOnly', false);" value="Remove readOnly"/>
 			<input type="button" onclick="setAttr('readOnly', true);" value="Set readOnly"/>
 			<input type="button" onclick="setAttr('disabled', true);" value="Disable"/>
@@ -125,19 +140,6 @@ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
 				<button type="button" name="button" onclick="displayData();">view data</button>
 				<input type="submit" name="submit" />
 			</div>
-			<script type="text/javascript">
-				function displayData(){
-					var f = dojo.byId("form1");
-					var s = "";
-					for(var i = 0; i < f.elements.length; i++){
-						var elem = f.elements[i];
-						if(elem.name == "button" || !dojo.isString(elem.value)){ continue; }
-						s += elem.name + ":[" + elem.value + "]\n";
-					}
-					console.log(s);
-				}
-			</script>
-
 		</form>
 	</body>
 </html>
diff --git a/dijit/tests/form/test_TimeTextBox.html b/dijit/tests/form/test_TimeTextBox.html
index 817e455..504e51c 100644
--- a/dijit/tests/form/test_TimeTextBox.html
+++ b/dijit/tests/form/test_TimeTextBox.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Test TimeTextBox Widget</title>
@@ -24,6 +24,11 @@
 			.dojoTitlePaneLabel label {
 				font-weight:bold;
 			}
+
+			.dijitDownArrowActive,
+			.dijitUpArrowActive {
+				opacity:0.5 !important; /* just to test effect of clicking the up or down arrows */
+			}
 		</style>
 
 		<!-- required: the default dijit theme: -->
@@ -64,7 +69,7 @@
 		</script>
 	</head>
 
-	<body class="claro">
+	<body class="claro" role="main">
 		<h1 class="testTitle">Test TimeTextBox Widget</h1>
 		<!--
 			To really test form submission, you'll need to create an action handler similar to
@@ -84,13 +89,13 @@
 					Attributes: {formatLength:'medium'}</span>
 			</div>
 			<div class="testExample">
-				<input id="q1" data-dojo-type="dijit.form.TimeTextBox"
+				<input id="q1" data-dojo-type="dijit/form/TimeTextBox"
 					data-dojo-props='type:"text", name:"time1", value:"T17:45:00",
 					constraints:{formatLength:"medium"},
 					required:true,
 					onChange:function(val){ dojo.byId("oc1").value = val; },
 					invalidMessage:"Invalid time." '/>
-				onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off"/>
+				<label for="oc1">onChange:</label><input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off"/>
 			</div>
 		
 			<div class="dojoTitlePaneLabel">
@@ -99,7 +104,7 @@
 					Attributes: {formatLength:'short'}</span>
 			</div>
 			<div class="testExample">
-				<input id="q2" data-dojo-type="dijit.form.TimeTextBox"
+				<input id="q2" data-dojo-type="dijit/form/TimeTextBox"
 					data-dojo-props='type:"text", name:"time1a", value:"T17:45:00",
 					constraints:{formatLength:"short"},
 					required:true,
@@ -112,7 +117,7 @@
 					Attributes: {timePattern:'h:mm:ss a'}</span>
 			</div>
 			<div class="testExample">
-				<input id="q3" data-dojo-type="dijit.form.TimeTextBox"
+				<input id="q3" data-dojo-type="dijit/form/TimeTextBox"
 					data-dojo-props='type:"text", name:"time1b", value:"T17:45:00",
 					constraints:{timePattern:"h:mm:ss a"},
 					required:true,
@@ -125,39 +130,26 @@
 					Attributes: {timePattern:'HH:mm:ss'}</span>
 			</div>
 			<div class="testExample">
-				<input id="q4" data-dojo-type="dijit.form.TimeTextBox"
+				<input id="q4" data-dojo-type="dijit/form/TimeTextBox"
 					data-dojo-props='type:"text", name:"time2", value:"T17:45:00",
 					constraints:{timePattern:"HH:mm:ss"},
 					required:true,
 					invalidMessage:"Invalid time. Use HH:mm:ss where HH is 00 - 23 hours."'/>
 			</div>
-		
-			<div class="dojoTitlePaneLabel">
-				<label for="q5">24 Hour Time with 1 Hour TimePicker</label>
-				<span class="noticeMessage">TimeTextBox class,
-					Attributes: {timePattern:'HH:mm:ss', clickableIncrement:'T00:15:00', visibleIncrement:'T00:15:00', visibleRange:'T01:00:00'}</span>
-			</div>
-			<div class="testExample">
-				<input id="q5" data-dojo-type="dijit.form.TimeTextBox"
-					data-dojo-props='type:"text", name:"time2", value:"T17:45:00",
-					constraints:{timePattern:"HH:mm:ss", clickableIncrement:"T00:15:00", visibleIncrement:"T00:15:00", visibleRange:"T01:00:00"},
-					required:true,
-					invalidMessage:"Invalid time. Use HH:mm:ss where HH is 00 - 23 hours."'/>
-			</div>
-		
+
 			<div class="dojoTitlePaneLabel">
 				<label for="q6">Initially empty time text box</label>
 				<span class="noticeMessage">TimeTextBox class,
 					Attributes: {formatLength:'medium',min:'T00:00:00',max:'T12:00:00'}</span>
 			</div>
 			<div class="testExample">
-				<input id="q6" data-dojo-type="dijit.form.TimeTextBox"
+				<input id="q6" data-dojo-type="dijit/form/TimeTextBox"
 					data-dojo-props='type:"text", name:"time6",
 					constraints:{formatLength:"medium",min:"T00:00:00",max:"T12:00:00"},
 					required:true,
 					onChange:function(val){ dojo.byId("oc6").value = val; },
 					invalidMessage:"Invalid time." '/>
-				onChange:<input id="oc6" size="34" disabled value="not fired yet!" autocomplete="off"/>
+				<label for="oc6">onChange:</label><input id="oc6" size="34" disabled value="not fired yet!" autocomplete="off"/>
 			</div>
 			<div class="dojoTitlePaneLabel">
 				<strong>Using title attribute for label.</strong>
@@ -165,7 +157,7 @@
 					Attributes: {formatLength:'short'} Time using local conventions without seconds, required, no invalid message tooltip</span>
 			</div>
 			<div class="testExample">
-				<input id="q20" data-dojo-type="dijit.form.TimeTextBox"
+				<input id="q20" data-dojo-type="dijit/form/TimeTextBox"
 					data-dojo-props='type:"text", name:"q20", value:"T17:45:00",
 					title:"title: Time using local conventions",
 					constraints:{formatLength:"short"},
diff --git a/dijit/tests/form/test_validStatePerformance.html b/dijit/tests/form/test_validStatePerformance.html
index 2438d18..0aab07b 100644
--- a/dijit/tests/form/test_validStatePerformance.html
+++ b/dijit/tests/form/test_validStatePerformance.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
   <head>
     <meta http-equiv="Content-type" content="text/html; charset=utf-8">
     <title>Performance Test of NumberTextBox</title>
@@ -30,7 +30,7 @@
 
   </head>
 
-  <body class="claro">
+  <body class="claro" role="main">
     <script>
       function performancetest(){
         console.log("Dojo version " + dojo.version);
@@ -66,50 +66,50 @@
 		console.log("Time 4: Inserting value into ValidationTextBox-fields: " + ((new Date()).getTime() - startTime4) + " millis");
       }
     </script>
-      <form id="form1" data-dojo-type="dijit.form.Form" data-dojo-props='action:"", method:""'>
-      <input id="input1_1" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_2" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_3" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_4" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_5" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_6" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_7" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_8" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_9" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_10" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_11" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_12" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_13" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_14" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_15" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_16" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_17" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_18" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_19" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input1_20" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <form id="form1" data-dojo-type="dijit/form/Form" data-dojo-props='action:"", method:""'>
+      <input id="input1_1" aria-label="input1_1" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_2" aria-label="input1_2" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_3" aria-label="input1_3" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_4" aria-label="input1_4" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_5" aria-label="input1_5" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_6" aria-label="input1_6" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_7" aria-label="input1_7" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_8" aria-label="input1_8" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_9" aria-label="input1_9" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_10" aria-label="input1_10" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_11" aria-label="input1_11" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_12" aria-label="input1_12" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_13" aria-label="input1_13" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_14" aria-label="input1_14" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_15" aria-label="input1_15" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_16" aria-label="input1_16" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_17" aria-label="input1_17" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_18" aria-label="input1_18" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_19" aria-label="input1_19" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_20" aria-label="input1_20" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
       </form>
       <br/>
-      <form id="form2" data-dojo-type="dijit.form.Form" data-dojo-props='action:"", method:""'>
-      <input id="input2_1" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_2" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_3" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_4" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_5" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_6" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_7" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_8" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_9" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_10" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_11" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_12" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_13" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_14" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_15" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_16" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_17" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_18" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_19" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
-      <input id="input2_20" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <form id="form2" data-dojo-type="dijit/form/Form" data-dojo-props='action:"", method:""'>
+      <input id="input2_1" aria-label="input2_1" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_2" aria-label="input2_2" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_3" aria-label="input2_3" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_4" aria-label="input2_4" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_5" aria-label="input2_5" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_6" aria-label="input2_6" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_7" aria-label="input2_7" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_8" aria-label="input2_8" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_9" aria-label="input2_9" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_10" aria-label="input2_10" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_11" aria-label="input2_11" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_12" aria-label="input2_12" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_13" aria-label="input2_13" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_14" aria-label="input2_14" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_15" aria-label="input2_15" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_16" aria-label="input2_16" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_17" aria-label="input2_17" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_18" aria-label="input2_18" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_19" aria-label="input2_19" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_20" aria-label="input2_20" data-dojo-type="dijit/form/ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
       </form>
       <br/>
       <button name="button" onclick="performancetest()">Run tests</button>
diff --git a/dijit/tests/form/test_validate.html b/dijit/tests/form/test_validate.html
index 7c39dc9..73b3716 100644
--- a/dijit/tests/form/test_validate.html
+++ b/dijit/tests/form/test_validate.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Test TextBox Validation Widgets</title>
@@ -70,18 +70,210 @@
 
 			dojo.require("dijit.Dialog");
 			dojo.require("dijit.form.Button");
+			dojo.require("dijit.tests.helpers");    // functions to help test
 
 			dojo.require("dojo.currency");
 			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
+			// Add test=true to the URL to run unit tests.
+			var test = /mode=test/i.test(window.location.href);
+
+			function fixNbsp(val){
+				return typeof val == "string" ? val.replace(/\xA0/g, " ") : val;
+			}
+
 			dojo.ready(function(){
 
-				new dijit.form.TextBox({id: 'monospace1', disabled: true, value: 'M|M:monospace?'}, 'monospace1');
-				new dijit.form.TextBox({id: 'monospace2', disabled: true, value: 'M|M:monospace?'}).placeAt('widget_monospace1', 'after');
+				new dijit.form.TextBox({id: 'monospace1', "aria-label":"monospace1", disabled: true, value: 'M|M:monospace?'}, 'monospace1');
+				new dijit.form.TextBox({id: 'monospace2', "aria-label":"monospace2",disabled: true, value: 'M|M:monospace?'}).placeAt('widget_monospace1', 'after');
 				
-				new dijit.form.TextBox({id: 'sans1', disabled: true, value: 'sans1'}, 'sans1');
-				new dijit.form.TextBox({id: 'sans2', disabled: true, value: 'sans2'}).placeAt('widget_sans1', 'after');
+				new dijit.form.TextBox({id: 'sans1', "aria-label":"sans1", disabled: true, value: 'sans1'}, 'sans1');
+				new dijit.form.TextBox({id: 'sans2', "aria-label":"sans2", disabled: true, value: 'sans2'}).placeAt('widget_sans1', 'after');
+
+				// See if we can make a widget in script and attach it to the DOM ourselves.
+				var props = {
+					name: "elevation",
+					value: 3000,
+					constraints: {min:-20000,max:20000,places:0},
+					promptMessage: "Enter a value between -20000 and +20000",
+					required: true,
+					style:{ textAlign: document.documentElement.dir == "rtl" ? "left" : "right" },
+					editOptions:{pattern:'#,##0'},
+					invalidMessage: "Invalid elevation.",
+					onChange: function(val){dojo.byId('oc5').value = val; },
+					"class": "medium"
+				};
+				(new dijit.form.NumberTextBox(props, "q05")).startup();
+
+				props = {
+					name: "ticket1651",
+					id: "mname",
+					templateString: null, // #11493
+					templatePath: dojo.moduleUrl('dijit.form.templates', 'TextBox.html'),
+					value: null,
+					"aria-labelledby":"l_ticket1651"
+				};
+				(new dijit.form.TextBox(props, "ticket1651")).startup();
+
+				if(!test){ return; }
+
+				// Test initial conditions
+				doh.register("initial conditions", {
+					name: "initial conditions",
+					runTest: function(){
+						var form1 = dojo.byId("form1");
+						
+						doh.is("Testing Testing", form1.firstname.value, "firstname");
+						doh.is("not fired yet!", dojo.byId("oc1").value, "firstname onchange");
+
+						doh.is("TESTING TESTING", form1.lastname.value, "lastname");
+						
+						doh.is("", form1.age.value, "age");
+						doh.is("not fired yet!", dojo.byId("oc3").value, "age onchange");
+						
+						doh.is("", form1.occupation.value, "occupation");
+						
+						doh.is("3000", form1.elevation.value, "elevation");
+						doh.is("3,000", dojo.byId("q05").value, "elevation display value");
+						doh.is("not fired yet!", dojo.byId("oc5").value, "elevation onchange");
+						
+						doh.is("54775.53", form1.income1.value, "income1");
+						doh.is("$54,775.53", dojo.byId("q08").value, "income1 display value");
+						doh.is("not fired yet!", dojo.byId("oc8").value, "income1 onchange");
+
+						doh.is("54775.53", form1.income2.value, "income2");
+						doh.is("€54,775.53", dojo.byId("q08eur").value, "income2 display value");
+
+						doh.is("someTestString", form1.phone.value, "phone");
+						doh.is("", form1.password.value, "password");
+						doh.is("", form1.ticket1651.value, "ticket1651");
+						doh.is("cannot type here", form1.readOnly.value, "readonly");
+						doh.is("cannot type here", form1.disabled.value, "disabled");
+					}
+				});
+
+				var watchHandle, onChangeHandle;
+
+				function setTest(testName, textbox, setDict, watchExpected, unchangedExpected, isValid, onChangeExpected){
+					// summary:
+					//		Generate test to call set("value", ...) and check response
+					// textbox: String
+					//		id of TextBox widget
+					// setDict: Dictionary
+					//		Value to pass to textbox.set(), such as {value: "123"} or {displayedValue: "1,234"}.
+					// watchExpected: Dictionary
+					//		Expected changes in state of TextBox, such as
+					//			{value: 1234, displayedValue: "1,234"}
+					//		Checks that watch() returns these values.
+					//		Also checks that textbox is actually displaying displayedValue
+					// unchangedExpected: Dictionary
+					//		Attributes of textbox that shouldn't change/be reported by watch(), and their values
+					//			{value: 1234, displayedValue: "1,234"}
+					//		Checks that watch() returns these values.
+					//		Also checks that textbox is actually displaying displayedValue
+					// isValid: Boolean
+					//		Checks return of textbox.isValid().   TODO: this should be watchable.
+					// onChangeExpected:
+					//		Check that onChange reports this value
+
+
+					return {
+						name: testName,
+						timeout: 1000,
+						runTest: function(){
 
+							textbox = dijit.byId(textbox);
+		
+							// expectedState is a combination of the attributes that we expect to change
+							// and the attributes that we expect not to change
+							var expectedState = dojo.delegate(watchExpected, unchangedExpected);
+
+							// save all notifications from watch()		
+							var watchActual = {};
+							watchHandle = textbox.watch(function(attr, oldVal, newVal){
+									console.log(textbox.id + ": " + attr + ": " + oldVal + " --> " + newVal);
+									watchActual[attr] = fixNbsp(newVal);
+								});
+
+							// and monitor onChange() calls too
+							var onChangeActual;
+							if(onChangeExpected){
+								onChangeHandle = textbox.on("change", function(newVal){
+									onChangeActual = fixNbsp(newVal);
+								});
+							}
+
+							// do the set
+							textbox.set(setDict);
+							
+							doh.is(expectedState.displayedValue, fixNbsp(textbox.focusNode.value), "focusNode.value");
+		
+							doh.is(isValid, textbox.isValid(), "isValid()");
+		
+							var d = new doh.Deferred();
+		
+							setTimeout(d.getTestCallback(function(){
+								// test that onChange() was called correctly
+								if(onChangeExpected){
+									doh.is(onChangeExpected, onChangeActual, "onChange()");
+								}
+								
+								// check that watch() callbacks were called
+								for(attr in watchExpected){
+									doh.t(attr in watchActual, "watch(" + attr + ") fired");
+									doh.is(watchExpected[attr], watchActual[attr], "watch(" + attr + ")");
+									doh.is(typeof watchExpected[attr], typeof watchActual[attr], "typeof watch(" + attr + ")")
+								}
+		
+								// check that direct get(...) calls are also working, for both the attributes
+								// that were supposed to change and the attributes that weren't supposed to change
+								for(attr in expectedState){
+									doh.is(expectedState[attr], fixNbsp(textbox.get(attr)), "get(" + attr + ")");
+									doh.is(typeof expectedState[attr], typeof textbox.get(attr), "typeof get(" + attr + ")")
+								}
+
+								// check that watch() didn't report attributes as changed when they didn't change
+								for(attr in unchangedExpected){
+									doh.f(attr in watchActual, attr + " shouldn't have been reported as changed by watch " + 
+										watchActual[attr]);
+								}
+							}), 50);		
+		
+							return d;
+						},
+						tearDown: function(){
+							watchHandle.unwatch();
+							watchHandle = null;
+							if(onChangeHandle){
+								onChangeHandle.remove();
+								onChangeHandle = null;
+							}
+						}
+					};
+				}
+
+				doh.register("set('value')", [
+					// test valid and invalid settings of value
+					setTest("valid_max", 'q03', {value: 120}, {value: 120, displayedValue: "120"}, {}, true),
+					setTest("out_of_range_max",'q03', {value: 121}, {value: 121, displayedValue: "121", state: "Error"}, {}, false),
+					setTest("valid_min", 'q03', {value: 0}, {value: 0, displayedValue: "0", state: ""}, {}, true),
+					setTest("out_of_range_min", 'q03', {value: -1}, {value: -1, displayedValue: "-1", state: "Error"}, {}, false),
+					setTest("invalid", 'q03', {value: 'two'}, {value: undefined, displayedValue: 'two'}, {}, false),
+					setTest("null_required", 'q03', {required: true, value: null},
+							{required: true, value: NaN, displayedValue: ''}, {state: "Error"}, false),	
+					setTest("null_notrequired", 'q03', {required: false, value: null}, {}, {displayedValue: ''}, true),
+
+					// test formatting of value vs. displayed value
+					setTest("number format", 'q05', {value: 1234}, {value: 1234, displayedValue: "1,234"}, {}, true),
+					setTest("currency format", 'q08', {value: 1234}, {value: 1234, displayedValue: "$1,234.00"}, {}, true)
+				]);
+
+				doh.register("set('displayedValue')", [
+					// test formatting of value vs. displayed value, in reverse
+					setTest("number format", 'q05', {displayedValue: "4,321"}, {value: 4321, displayedValue: "4,321"}, {}, true),
+					setTest("european currency format", 'q08eurde', {displayedValue: "4.321,98"},
+						{value: 4321.98, displayedValue: "4.321,98 €"}, {}, true)
+				]);
 
 				doh.register("font inheritance", [
 					{
@@ -126,12 +318,148 @@
 					}
 				]);
 
+				doh.register("pattern", [
+					{
+						name: "pattern markup",
+						runTest: function(){
+							var w = dijit.byId('q22');
+							w.set('value', 'someTestString');
+							doh.is(true, w.isValid(false));
+							doh.f(!!w.focusNode.getAttribute('pattern'), "native pattern");
+						}
+					},
+					{
+						name: "pattern string",
+						runTest: function(){
+							var w = dijit.byId('q22');
+							w.set('value', 'someTestString');
+							w.set('pattern', "some[a-z]+"); // invalid
+							doh.is(false, w.isValid(false), "invalid");
+							doh.is(false, w._isValidSubset(), "invalid partial");
+							w.set('value', 'some');
+							doh.is(true, w._isValidSubset(), "valid partial");
+							w.set('value', 'someTestString');
+							w.set('pattern', "someT[a-z]+S[a-z]+"); // valid
+							doh.is(true, w.isValid(false), "valid");
+							doh.is(true, w._isValidSubset(), "valid partial 2");
+							doh.f(!!w.focusNode.getAttribute('pattern'), "native pattern");
+						}
+					},
+					{
+						name: "pattern function",
+						runTest: function(){
+							var w = dijit.byId('q22');
+							w.set('value', 'someTestString');
+							w.set('pattern', function(){ return "[a-z]+"; }); // invalid
+							doh.is(false, w.isValid(false), "invalid string");
+							w.set('pattern', function(){ return "[a-zTS]+"; }); // valid
+							doh.is(true, w.isValid(false), "valid string");
+						}
+					}
+				]);
+
+				doh.register("#11889", [
+					{
+						name: "non-focused places:5",
+						timeout: 2000,
+						textbox: "q05",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('constraints', { places: 5 });
+							this.textbox.set('editOptions', { places: "2,4" });
+						},
+						runTest: function(){
+							this.textbox.set('value', 1.625);
+							doh.is(1.625, this.textbox.get('value'), 'numeric value is unchanged');
+							doh.is('1.62500', this.textbox.get('displayedValue'), 'formatted displayed value');
+							doh.t(this.textbox.isValid(false), 'nonfocused is valid');
+						}
+					},
+					{
+						name: "focused places:2,4. blur to places:5",
+						timeout: 2000,
+						textbox: "q05",
+						runTest: function(){
+							var d = new doh.Deferred();
+							var textbox = this.textbox;
+
+							textbox = dijit.byId(this.textbox);
+							textbox.set('constraints', { places: 5 });
+							textbox.set('editOptions', { places: "2,4" });
+							textbox.focus();
+
+							setTimeout(d.getTestErrback(function(){	// allow time for async focus on IE9+
+								textbox.set('value', 1.125);
+
+								doh.is(1.125, textbox.get('value'), 'numeric value is unchanged');
+								doh.is('1.125', textbox.get('displayedValue'), 'formatted displayed value');
+								doh.t(textbox.isValid(true), 'focused is valid');
+
+
+								var handler = textbox.on("blur", function(){
+									handler.remove();
+									setTimeout(d.getTestCallback(function(){
+										doh.is(1.125, textbox.get('value'), 'numeric value is unchanged #2');
+										doh.is('1.12500', textbox.get('displayedValue'), 'formatted displayed value #2');
+										doh.t(textbox.isValid(false), 'nonfocused is valid #2');
+									}), 150);
+								});
+								dojo.byId("q01").focus();
+							}), 0);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("validation in dialog", [
+					function showDialog(){
+						// Show dialog, returning Deferred that fires when show dialog is finished.
+						// Before showing, focus the open button, so that Dialog knows where to return focus to.
+
+						var d = new doh.Deferred();
+
+						dijit.byId("dlgOpenBtn").focus();
+
+						// Focus on IE9+ is asynchronous, so wait for it to occur before showing Dialog.   Otherwise,
+						// when Dialog closes it restores focus somewhere strange.
+						setTimeout(function(){
+							dijit.byId("dlg").show().then(function(){
+								d.resolve(true);
+							});
+						}, 0);
+
+						return d;
+					},
+					function enterInvalidValue(){
+						// Entering invalid value should make validation tooltip appear
+						var d = new doh.Deferred();
+						dijit.byId("dlgNTB").set("value", "invalid");
+						dijit.byId("dlgNTB").focus();
+						setTimeout(d.getTestCallback(function(){
+							masterTT = dojo.global.dijit._masterTT;
+							doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
+						}), 300);
+						return d;
+					},
+					function hideDialog(){
+						// Hiding the dialog should make the validation tooltip disappear
+						var d = new doh.Deferred();
+						dijit.byId("dlg").hide().then(function(){
+							setTimeout(d.getTestCallback(function(){
+								doh.t(isHidden(masterTT.domNode), "tooltip hidden");
+							}), 300);
+						});
+						return d;
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
 	</head>
 
-	<body class="claro">
+	<body class="claro" role="main">
 		<h1 class="testTitle">Dijit Validation Widgets</h1>
 		<!--	to test form submission, you'll need to create an action handler similar to
 			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
@@ -142,7 +470,7 @@
 				<span class="noticeMessage"> TextBox class, <b>tabIndex=2</b>, Attributes: {trim: true, propercase: true, intermediateChanges: true, style: 'width:700px', selectOnClick: true}, First letter of each word is upper case.</span>
 			</div>
 			<div class="testExample">
-				<input id="q01" data-dojo-type="dijit.form.TextBox"
+				<input id="q01" data-dojo-type="dijit/form/TextBox"
 					name="firstname" value="testing testing" style="width:700px" tabIndex="2"
 					data-dojo-props='
 					trim:true,
@@ -152,7 +480,7 @@
 					onChange:function(v){ dojo.byId("oc1").value=v; },
 					intermediateChanges:true,
 					propercase:true '/>
-				<br>onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off"/>
+				<br><label for="oc1">onChange:</label><input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off"/>
 				<input tabIndex="-1" type="button" onclick="dijit.byId('q01').set('disabled', true);" value="Disable"/>
 				<input tabIndex="-1" type="button" onclick="dijit.byId('q01').set('disabled', false);" value="Enable"/>
 			</div>
@@ -162,7 +490,7 @@
 				<span class="noticeMessage"> TextBox class, Attributes: {trim: true, uppercase: true, "class": 'verylong'}, all letters converted to upper case. </span>
 			</div>
 			<div class="testExample">
-				<input id="q02" data-dojo-type="dijit.form.TextBox"
+				<input id="q02" data-dojo-type="dijit/form/TextBox"
 					name="lastname" value="testing testing" class="verylong"
 					data-dojo-props='trim:true, uppercase:true '/>
 			</div>
@@ -172,7 +500,7 @@
 				<span class="noticeMessage"> NumberTextBox class, <b>tabIndex=1</b>, Attributes: {trim: true}, no initial value specified, tooltipPosition=[above, below].  Displays a prompt message if field is blank.</span>
 			</div>
 			<div class="testExample">
-				<input id="q03" data-dojo-type="dijit.form.NumberTextBox"
+				<input id="q03" data-dojo-type="dijit/form/NumberTextBox"
 					name="age" tabIndex="1" class="small"
 					data-dojo-props='
 					promptMessage:"(optional) Enter an age between 0 and 120",
@@ -181,14 +509,14 @@
 					onChange:function(val){ dojo.byId("oc3").value=""+val; },
 					tooltipPosition:["above", "below"]
 				'/>
-				onChange:<input id="oc3" size="14" disabled value="not fired yet!" autocomplete="off"/>
+				<label for="oc3">onChange:</label><input id="oc3" size="14" disabled value="not fired yet!" autocomplete="off"/>
 				<span style='white-space:nowrap;'>
 				<button id="q03_valid" type=button onclick="dijit.byId('q03').set('value', 120);">set value to 120</button>
 				<button id="q03_outofrange" type=button onclick="dijit.byId('q03').set('value', 121);">set value to 121</button>
 				<button id="q03_invalid" type=button onclick="dijit.byId('q03').set('value', 'two');">set value to two</button>
 				<button id="q03_null" type=button onclick="dijit.byId('q03').set('value', null);">set value to null</button>
 				<button type=button onclick="dojo.byId('gv3').value=''+dijit.byId('q03').get('value');">get value</button>
-				<input id="gv3" size="10" disabled value="" autocomplete="off"/>
+				<input id="gv3" aria-label="get value 3" size="10" disabled value="" autocomplete="off"/>
 				</span>
 			</div>
 
@@ -197,9 +525,9 @@
 				<span class="noticeMessage"> NumberTextBox class, Attributes: required=true, must be integer, no messages provided,  no initial value specified, maxlength=3</span>
 			</div>
 			<div class="testExample">
-				<input id="fav" data-dojo-type="dijit.form.NumberTextBox"
+				<input id="fav" data-dojo-type="dijit/form/NumberTextBox"
 					name="fav" class="small" required
-					data-dojo-props='maxLength:"3",constraints:{places:0,min:1,max:100},regExpGen:function(){ return "\\d+" }'/>
+					data-dojo-props='maxLength:"3",constraints:{places:0,min:1,max:100},pattern:"\\d+"'/>
 					<button onclick="dijit.byId('fav').set('required', true); return false;">attr(required, true)</button>
 					<button onclick="dijit.byId('fav').set('required', false); return false;">attr(required, false)</button>
 			</div>
@@ -210,7 +538,7 @@
 					Attributes: {lowercase: true, required: true, "class": verylong, style: font-size: 15pt;}. Displays a prompt message if field is blank.</span>
 			</div>
 			<div class="testExample">
-				<input id="q04" data-dojo-type="dijit.form.ValidationTextBox"
+				<input id="q04" data-dojo-type="dijit/form/ValidationTextBox"
 					name="occupation" class="verylong" style="fontSize:15pt" required="true"
 					data-dojo-props='lowercase:true, promptMessage:"Enter an occupation" '/>
 			</div>
@@ -223,25 +551,8 @@
 			</div>
 			<div class="testExample">
 				<input id="q05" class="small"/>
-				onChange:<input id="oc5" size="10" disabled value="not fired yet!" autocomplete="off"/>
-			</div>
-<script>
-	// See if we can make a widget in script and attach it to the DOM ourselves.
-	dojo.ready(function(){
-		var props = {
-			name: "elevation",
-			value: 3000,
-			constraints: {min:-20000,max:20000,places:0},
-			promptMessage: "Enter a value between -20000 and +20000",
-			required: true,
-			editOptions:{pattern:'#,##0'},
-			invalidMessage: "Invalid elevation.",
-			onChange: function(val){dojo.byId('oc5').value = val; },
-			"class": "medium"
-		};
-		var w = new dijit.form.NumberTextBox(props, "q05");
-	});
-</script>
+				<label for="oc5">onChange:</label><input id="oc5" size="10" disabled value="not fired yet!" autocomplete="off"/>
+			</div>
 <!--
 			<div class="dojoTitlePaneLabel">
 				<label for="attach-here">Population:  </label>
@@ -260,7 +571,7 @@
 						value: "1,500,000",
 						trim: "true",
 						required: "true",
-						regExpGen: dojo.regexp.integer,
+						pattern: dojo.regexp.integer,
 						constraints: {signed:false, separator: ","},
 						invalidMessage: "Invalid population.  Enter a number."
 					};
@@ -275,8 +586,8 @@
 			</div>
 			<div class="testExample">
 				<input id="q06" type="text" name="real1" class="medium" value="+0.1234"
-					data-dojo-type="dijit.form.ValidationTextBox"
-					regExpGen="dojo.regexp.realNumber"
+					data-dojo-type="dijit/form/ValidationTextBox"
+					pattern="dojo.regexp.realNumber"
 					trim="true"
 					required="true"
 					invalidMessage="This is not a valid real number." />
@@ -288,8 +599,8 @@
 			</div>
 			<div class="testExample">
 				<input id="q07" type="text" name="real2" class="medium" value="+0.12"
-					data-dojo-type="dijit.form.ValidationTextBox"
-					regExpGen="dojo.regexp.realNumber"
+					data-dojo-type="dijit/form/ValidationTextBox"
+					pattern="dojo.regexp.realNumber"
 					trim="true"
 					required="true"
 					constraints="{exponent:true}"
@@ -304,18 +615,18 @@
 			</div>
 
 			<div class="testExample">
-				<input id="q08" data-dojo-type="dijit.form.CurrencyTextBox"
+				<input id="q08" data-dojo-type="dijit/form/CurrencyTextBox"
 					name="income1" class="medium" value="54775.53" required
 					data-dojo-props='constraints:{fractional:true},
 						currency:"USD",
 						onChange:function(val){ dojo.byId("oc8").value = val; },
 						invalidMessage:"Invalid amount.  Cents are MANDATORY." '/>USD
-				 onChange:<input id="oc8" size="15" disabled value="not fired yet!" autocomplete="off"/>
+				 <label for="oc8">onChange:</label><input id="oc8" size="15" disabled value="not fired yet!" autocomplete="off"/>
 			</div>
 
 			<div class="testExample">
-				euro currency (local format) fractional part is optional:
-				<input id="q08eur" data-dojo-type="dijit.form.CurrencyTextBox"
+				<label for="q08eur">euro currency (local format) fractional part is optional:</label>
+				<input id="q08eur" data-dojo-type="dijit/form/CurrencyTextBox"
 					name="income2" class="medium" value="54775.53" required
 					data-dojo-props='currency:"EUR", invalidMessage:"Invalid amount.  Include cents." '/>EUR
 				<button onclick="dijit.byId('q08eur').set('disabled',true); return false;">Disable</button>
@@ -343,7 +654,8 @@
 						lang: 'de-de',
 						required: true,
 						currency: "EUR",
-						invalidMessage: "Invalid amount.  Example: " + example
+						invalidMessage: "Invalid amount.  Example: " + example,
+						"aria-label": "income3 de-de"
 					};
 					var w = new dijit.form.CurrencyTextBox(props, "q08eurde");
 				});
@@ -357,8 +669,8 @@
 			</div>
 			<div class="testExample">
 				<input id="q08a" type="text" name="income3" class="medium" value="$54,775.53"
-					data-dojo-type="dijit.form.ValidationTextBox"
-					regExpGen="dojo.regexp.currency"
+					data-dojo-type="dijit/form/ValidationTextBox"
+					pattern="dojo.regexp.currency"
 					trim="true"
 					required="true"
 					constraints="{fractional:true}"
@@ -372,8 +684,8 @@
 			</div>
 			<div class="testExample">
 				<input id="q09" type="text" name="ipv4" class="medium" value="24.17.155.40"
-					data-dojo-type="dijit.form.ValidationTextBox"
-					regExpGen="dojo.regexp.ipAddress"
+					data-dojo-type="dijit/form/ValidationTextBox"
+					pattern="dojo.regexp.ipAddress"
 					trim="true"
 					required="true"
 					constraints="{allowIPv6:false,allowHybrid:false}"
@@ -388,8 +700,8 @@
 			</div>
 			<div class="testExample">
 				<input id="q10" type="text" name="ipv6" class="long" value="0000:0000:0000:0000:0000:0000:0000:0000"
-					data-dojo-type="dijit.form.ValidationTextBox"
-					regExpGen="dojo.regexp.ipAddress"
+					data-dojo-type="dijit/form/ValidationTextBox"
+					pattern="dojo.regexp.ipAddress"
 					trim="true"
 					uppercase = "true"
 					required="true"
@@ -405,8 +717,8 @@
 
 			<div class="testExample">
 				<input id="q11" type="text" name="url" class="long" value="http://www.xyz.com/a/b/c?x=2#p3"
-					data-dojo-type="dijit.form.ValidationTextBox"
-					regExpGen="dojo.regexp.url"
+					data-dojo-type="dijit/form/ValidationTextBox"
+					pattern="dojo.regexp.url"
 					trim="true"
 					required="true"
 					constraints="{scheme:true}"
@@ -421,8 +733,8 @@
 
 			<div class="testExample">
 				<input id="q12" type="text" name="email" class="long" value="fred&barney at stonehenge.com"
-					data-dojo-type="dijit.form.ValidationTextBox"
-					regExpGen="dojo.regexp.emailAddress"
+					data-dojo-type="dijit/form/ValidationTextBox"
+					pattern="dojo.regexp.emailAddress"
 					trim="true"
 					required="true"
 					invalidMessage="Invalid Email Address." />
@@ -436,8 +748,8 @@
 
 			<div class="testExample">
 				<input id="q13" type="text" name="email" class="long" value="a at xyz.com; b at xyz.com; c at xyz.com; "
-					data-dojo-type="dijit.form.ValidationTextBox"
-					regExpGen="dojo.regexp.emailAddressList"
+					data-dojo-type="dijit/form/ValidationTextBox"
+					pattern="dojo.regexp.emailAddressList"
 					trim="true"
 					required="true"
 					invalidMessage="Invalid Email Address List." />
@@ -449,9 +761,9 @@
 					Attributes: {required: true} </span>
 			</div>
 			<div class="testExample">
-				<input id="q22" data-dojo-type="dijit.form.ValidationTextBox"
+				<input id="q22" data-dojo-type="dijit/form/ValidationTextBox"
 					name="phone" class="medium" value="someTestString" required
-					data-dojo-props='regExp:"[\\w]+", invalidMessage:"Invalid Non-Space Text."'/>
+					data-dojo-props='pattern:"[\\w]+", invalidMessage:"Invalid Non-Space Text."'/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
@@ -459,37 +771,23 @@
 				<span class="noticeMessage">(just a test that type attribute is obeyed) </span>
 			</div>
 			<div class="testExample">
-				<input id="q23" data-dojo-type="dijit.form.TextBox" type="password" name="password" class="medium"/>
+				<input id="q23" data-dojo-type="dijit/form/TextBox" type="password" name="password" class="medium"/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
-				<label for="ticket1651">Trac ticket 1651:  </label>
+				<label id="l_ticket1651">Trac ticket 1651:  </label>
 				<span class="noticeMessage">value: null should show up as empty</span>
 			</div>
 			<div class="testExample">
 				<input id="ticket1651" class="medium" value="not null"/>
 			</div>
 
-			<script>
-				// See if we can make a widget in script and attach it to the DOM ourselves.
-				dojo.ready(function(){
-					var props = {
-							name: "ticket1651",
-							id: "mname",
-							templateString: null, // #11493
-							templatePath: dojo.moduleUrl('dijit.form.templates', 'TextBox.html'),
-							value: null
-					};
-					var w = new dijit.form.TextBox(props, "ticket1651");
-				});
-			</script>
-
 			<div class="dojoTitlePaneLabel">
 				<label for="q24">initially readOnly TextBox</label>
 				<span class="noticeMessage">a test that readOnly and disabled are understood for TextBox</span>
 			</div>
 			<div class="testExample">
-				<input id="q24" data-dojo-type="dijit.form.TextBox"
+				<input id="q24" data-dojo-type="dijit/form/TextBox"
 					name="readOnly" class="medium" readOnly value="cannot type here" title="hint text"/>
 				<input type="button" id="removereadonly" onclick="dijit.byId('q24').set('readOnly',false);" value="Remove readOnly" tabIndex="-1"/>
 				<input type="button" onclick="dijit.byId('q24').set('readOnly',true);" value="Set readOnly" tabIndex="-1"/>
@@ -501,7 +799,7 @@
 				<span class="noticeMessage">a test that disabled is understood for ValidationTextBox</span>
 			</div>
 			<div class="testExample">
-				<input id="q25" data-dojo-type="dijit.form.ValidationTextBox"
+				<input id="q25" data-dojo-type="dijit/form/ValidationTextBox"
 					name="disabled" class="medium" disabled value="cannot type here"/>
 				<input type="button" onclick="dijit.byId('q25').set('readOnly',false);" value="Remove readOnly" tabIndex="-1"/>
 				<input type="button" onclick="dijit.byId('q25').set('readOnly',true);" value="Set readOnly" tabIndex="-1"/>
@@ -534,7 +832,7 @@
 				<span class="noticeMessage">a test that placeholder works for TextBox.  10px padding added for testing.</span>
 		</div>
 		<div class="testExample">
-			<input id="q26" data-dojo-type="dijit.form.TextBox" placeHolder="placeholder is here" name="placeHolder" value=""/>
+			<input id="q26" data-dojo-type="dijit/form/TextBox" placeHolder="placeholder is here" name="placeHolder" value=""/>
 		</div>
 		<h2>Tooltip positioning</h2>
 		<p>
diff --git a/dijit/tests/form/test_verticalAlign.html b/dijit/tests/form/test_verticalAlign.html
index 8d7e2a7..d53f9cf 100644
--- a/dijit/tests/form/test_verticalAlign.html
+++ b/dijit/tests/form/test_verticalAlign.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dojo Form Widget Vertical Alignment Test</title>
@@ -86,122 +86,122 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1 class="testTitle">Dojo Form Widget Vertical Alignment Test</h1>
 
 	<p>In a P</p>
-	<p class="box"><span style='white-space:nowrap;'>
+	<p class="box" style='white-space:nowrap;'>
 		<button id="p_native">native</button>
-		<button id="p_Button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", iconClass:"plusIcon", value:"Button"'>
+		<button id="p_Button" data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", iconClass:"plusIcon", value:"Button"'>
 			Button
 		</button>
-		<button id="p_DropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='type:"button", value:"DropDown", label:"DropDown"'>
-			<span data-dojo-type="dijit.Menu" data-dojo-props='style:"display:none;"'>
-				<span data-dojo-type="dijit.MenuItem">DropDown MenuItem</span>
+		<button id="p_DropDown" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='type:"button", value:"DropDown", label:"DropDown"'>
+			<span data-dojo-type="dijit/Menu" data-dojo-props='style:"display:none;"'>
+				<span data-dojo-type="dijit/MenuItem">DropDown MenuItem</span>
 			</span>
 		</button>
-		<button id="p_ComboButton" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"options", iconClass:"plusIcon", title:"title"'>
+		<button id="p_ComboButton" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"options", iconClass:"plusIcon", title:"title"'>
 			<span>Create</span>
-			<span data-dojo-type="dijit.Menu">
-				<span data-dojo-type="dijit.MenuItem">One</span>
-				<span data-dojo-type="dijit.MenuItem">Two</span>
+			<span data-dojo-type="dijit/Menu">
+				<span data-dojo-type="dijit/MenuItem">One</span>
+				<span data-dojo-type="dijit/MenuItem">Two</span>
 			</span>
 		</button>
 		<label for="p_Select">Select</label>
-		<select id="p_Select" data-dojo-type="dijit.form.Select">
+		<select id="p_Select" data-dojo-type="dijit/form/Select">
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
 			<option value="four">four</option>
 		</select>
 		<label for="p_ComboBox">ComboBox</label>
-		<select id="p_ComboBox" data-dojo-type="dijit.form.ComboBox" data-dojo-props='style:{width:"5em"}'>
+		<select id="p_ComboBox" data-dojo-type="dijit/form/ComboBox" data-dojo-props='style:{width:"5em"}'>
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
 			<option value="four">four</option>
 		</select>
 		<label for="p_TextBox">TextBox</label>
-		<input id="p_TextBox" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"Text", style:{width:"5em"}'/>
+		<input id="p_TextBox" data-dojo-type="dijit/form/TextBox" data-dojo-props='value:"Text", style:{width:"5em"}'/>
 		<label for="p_NumberTextBox">NumberTextBox</label>
-		<input id="p_NumberTextBox" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='value:23, style:{width:"3em"}'/>
-	</span></p>
+		<input id="p_NumberTextBox" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='value:23, style:{width:"3em"}'/>
+	</p>
 
 	<p>In a DIV</p>
-	<div><span style='white-space:nowrap;'>
+	<div style='white-space:nowrap;'>
 		<button id="div_native">native</button>
-		<button id="div_Button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", iconClass:"plusIcon", value:"Create"'>
+		<button id="div_Button" data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", iconClass:"plusIcon", value:"Create"'>
 			Button
 		</button>
-		<button id="div_DropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='type:"button", value:"DropDown", label:"DropDown"'>
-			<span data-dojo-type="dijit.Menu">
-				<span data-dojo-type="dijit.MenuItem">DropDown MenuItem</span>
+		<button id="div_DropDown" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='type:"button", value:"DropDown", label:"DropDown"'>
+			<span data-dojo-type="dijit/Menu">
+				<span data-dojo-type="dijit/MenuItem">DropDown MenuItem</span>
 			</span>
 		</button>
-		<button id="div_ComboButton" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"options", iconClass:"plusIcon", title:"title"'>
+		<button id="div_ComboButton" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"options", iconClass:"plusIcon", title:"title"'>
 			<span>Create</span>
-			<span data-dojo-type="dijit.Menu">
-				<span data-dojo-type="dijit.MenuItem">One</span>
-				<span data-dojo-type="dijit.MenuItem">Two</span>
+			<span data-dojo-type="dijit/Menu">
+				<span data-dojo-type="dijit/MenuItem">One</span>
+				<span data-dojo-type="dijit/MenuItem">Two</span>
 			</span>
 		</button>
 		<label for="div_Select">Select</label>
-		<select id="div_Select" data-dojo-type="dijit.form.Select">
+		<select id="div_Select" data-dojo-type="dijit/form/Select">
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
 			<option value="four">four</option>
 		</select>
 		<label for="div_ComboBox">ComboBox</label>
-		<select id="div_ComboBox" data-dojo-type="dijit.form.ComboBox" data-dojo-props='style:{width:"5em"}'>
+		<select id="div_ComboBox" data-dojo-type="dijit/form/ComboBox" data-dojo-props='style:{width:"5em"}'>
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
 			<option value="four">four</option>
 		</select>
 		<label for="div_TextBox">TextBox</label>
-		<input id="div_TextBox" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"Text", style:{width:"5em"}'/>
+		<input id="div_TextBox" data-dojo-type="dijit/form/TextBox" data-dojo-props='value:"Text", style:{width:"5em"}'/>
 		<label for="div_NumberTextBox">NumberTextBox</label>
-		<input id="div_NumberTextBox" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='value:23, style:{width:"3em"}'/>
-	</span></div>
+		<input id="div_NumberTextBox" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='value:23, style:{width:"3em"}'/>
+	</div>
 
 	<p>font-size 200%</p>
-	<div style="font-size: 200%;"><span style='white-space:nowrap;'>
+	<div style="font-size: 200%;white-space:nowrap;">
 		<button id="font_native">native</button>
-		<button id="font_Button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", iconClass:"plusIcon", value:"Button"'>
+		<button id="font_Button" data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", iconClass:"plusIcon", value:"Button"'>
 			Button
 		</button>
-		<button id="font_DropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='type:"button", value:"DropDown", label:"DropDown"'>
-			<span data-dojo-type="dijit.Menu"'>
-				<span data-dojo-type="dijit.MenuItem">DropDown MenuItem</span>
+		<button id="font_DropDown" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='type:"button", value:"DropDown", label:"DropDown"'>
+			<span data-dojo-type="dijit/Menu">
+				<span data-dojo-type="dijit/MenuItem">DropDown MenuItem</span>
 			</span>
 		</button>
-		<button id="font_ComboButton" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"options", iconClass:"plusIcon", title:"title"'>
+		<button id="font_ComboButton" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"options", iconClass:"plusIcon", title:"title"'>
 			<span>Create</span>
-			<span data-dojo-type="dijit.Menu">
-				<span data-dojo-type="dijit.MenuItem">One</span>
-				<span data-dojo-type="dijit.MenuItem">Two</span>
+			<span data-dojo-type="dijit/Menu">
+				<span data-dojo-type="dijit/MenuItem">One</span>
+				<span data-dojo-type="dijit/MenuItem">Two</span>
 			</span>
 		</button>
 		<label for="font_Select">Select</label>
-		<select id="font_Select" data-dojo-type="dijit.form.Select">
+		<select id="font_Select" data-dojo-type="dijit/form/Select">
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
 			<option value="four">four</option>
 		</select>
 		<label for="font_ComboBox">ComboBox</label>
-		<select id="font_ComboBox" data-dojo-type="dijit.form.ComboBox" data-dojo-props='style:{width:"5em"}'>
+		<select id="font_ComboBox" data-dojo-type="dijit/form/ComboBox" data-dojo-props='style:{width:"5em"}'>
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
 			<option value="four">four</option>
 		</select>
 		<label for="font_TextBox">TextBox</label>
-		<input id="font_TextBox" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"Text", style:{width:"5em"}'/>
+		<input id="font_TextBox" data-dojo-type="dijit/form/TextBox" data-dojo-props='value:"Text", style:{width:"5em"}'/>
 		<label for="font_NumberTextBox">NumberTextBox</label>
-		<input id="font_NumberTextBox" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='value:23, style:{width:"3em"}'/>
-	</span></div>
+		<input id="font_NumberTextBox" data-dojo-type="dijit/form/NumberTextBox" data-dojo-props='value:23, style:{width:"3em"}'/>
+	</div>
 
 </body>
 </html>
diff --git a/dijit/tests/formAction.html b/dijit/tests/formAction.html
index 319893d..6ecc40b 100644
--- a/dijit/tests/formAction.html
+++ b/dijit/tests/formAction.html
@@ -7,8 +7,8 @@
         var str = window.location.search.substr(1).replace(/[%]0D/g, "").replace(/[+]/g, " ").split(/&/);
         for(var i=0; i<str.length; i++){
                 var split = str[i].split(/=/),
-                        key = unescape(split[0] || ''),
-                        value = unescape(split[1] || '');
+                        key = decodeURIComponent(split[0] || ''),
+                        value = decodeURIComponent(split[1] || '');
 		if(values[key] === undefined){
 			values[key] = value;
 		}else if(values[key] instanceof Array || typeof values[key] == "array"){
diff --git a/dijit/tests/general-module.js b/dijit/tests/general-module.js
index ffd42bb..a0c7003 100644
--- a/dijit/tests/general-module.js
+++ b/dijit/tests/general-module.js
@@ -1,42 +1,41 @@
-dojo.provide("dijit.tests.general-module");
-
-try{
-	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
+define(["doh/main", "require"], function(doh, require){
 
 	// top level widget tests
-	doh.registerUrl("dijit.tests.Bidi", dojo.moduleUrl("dijit","tests/Bidi.html"+userArgs), 999999);
+	doh.register("Bidi", require.toUrl("./Bidi.html"), 999999);
 
-	doh.registerUrl("dijit.tests.robot.Menu_mouse", dojo.moduleUrl("dijit","tests/robot/Menu_mouse.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.robot.Menu_a11y", dojo.moduleUrl("dijit","tests/robot/Menu_a11y.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.robot.Menu_iframe", dojo.moduleUrl("dijit","tests/robot/Menu_iframe.html"+userArgs), 999999);
+	doh.register("Menu", require.toUrl("./Menu.html"), 999999);
+	doh.register("robot.Menu_mouse", require.toUrl("./robot/Menu_mouse.html"), 999999);
+	doh.register("robot.Menu_a11y", require.toUrl("./robot/Menu_a11y.html"), 999999);
+	doh.register("robot.Menu_iframe", require.toUrl("./robot/Menu_iframe.html"), 999999);
 
-	doh.registerUrl("dijit.tests.Dialog", dojo.moduleUrl("dijit","tests/Dialog.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.robot.Dialog_mouse", dojo.moduleUrl("dijit","tests/robot/Dialog_mouse.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.robot.Dialog_a11y", dojo.moduleUrl("dijit","tests/robot/Dialog_a11y.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.robot.Dialog_focusDestroy", dojo.moduleUrl("dijit","tests/robot/Dialog_focusDestroy.html"+userArgs), 999999);
-	
-	doh.registerUrl("dijit.tests.ProgressBar", dojo.moduleUrl("dijit","tests/ProgressBar.html"+userArgs), 999999);
-	
-	doh.registerUrl("dijit.tests.robot.Tooltip_a11y", dojo.moduleUrl("dijit","tests/robot/Tooltip_a11y.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.robot.Tooltip_mouse", dojo.moduleUrl("dijit","tests/robot/Tooltip_mouse.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.robot.Tooltip_mouse_quirks", dojo.moduleUrl("dijit","tests/robot/Tooltip_mouse_quirks.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.Tooltip-placement", dojo.moduleUrl("dijit","tests/Tooltip-placement.html"+userArgs), 999999);
+	doh.register("Dialog", require.toUrl("./Dialog.html"), 999999);
+	doh.register("robot.Dialog_mouse", require.toUrl("./robot/Dialog_mouse.html"), 999999);
+	doh.register("robot.Dialog_a11y", require.toUrl("./robot/Dialog_a11y.html"), 999999);
+	doh.register("robot.Dialog_focusDestroy", require.toUrl("./robot/Dialog_focusDestroy.html"), 999999);
+
+	doh.register("ProgressBar", require.toUrl("./ProgressBar.html"), 999999);
+
+	doh.register("robot.Tooltip_a11y", require.toUrl("./robot/Tooltip_a11y.html"), 999999);
+	doh.register("robot.Tooltip_mouse", require.toUrl("./robot/Tooltip_mouse.html"), 999999);
+	doh.register("robot.Tooltip_mouse_quirks", require.toUrl("./robot/Tooltip_mouse_quirks.html"), 999999);
+	doh.register("Tooltip-placement", require.toUrl("./Tooltip-placement.html"), 999999);
 
-	doh.registerUrl("dijit.tests.robot.TooltipDialog_mouse", dojo.moduleUrl("dijit","tests/robot/TooltipDialog_mouse.html"+userArgs), 999999);
-	doh.registerUrl("dijit.tests.robot.TooltipDialog_a11y", dojo.moduleUrl("dijit","tests/robot/TooltipDialog_a11y.html"+userArgs), 999999);
+	doh.register("TooltipDialog", require.toUrl("./TooltipDialog.html"), 999999);
+	doh.register("robot.TooltipDialog_mouse", require.toUrl("./robot/TooltipDialog_mouse.html"), 999999);
+	doh.register("robot.TooltipDialog_a11y", require.toUrl("./robot/TooltipDialog_a11y.html"), 999999);
 
-	doh.registerUrl("dijit.tests.robot.InlineEditBox", dojo.moduleUrl("dijit","tests/robot/InlineEditBox.html"+userArgs), 999999);
+	doh.register("robot.InlineEditBox", require.toUrl("./robot/InlineEditBox.html"), 999999);
 	
-	doh.registerUrl("dijit.tests.robot.ColorPalette", dojo.moduleUrl("dijit","tests/robot/ColorPalette.html"+userArgs), 999999);
+	doh.register("robot.ColorPalette", require.toUrl("./robot/ColorPalette.html"), 999999);
 
-	doh.registerUrl("dijit.tests.robot.Calendar_a11y", dojo.moduleUrl("dijit","tests/robot/Calendar_a11y.html"+userArgs), 999999);
+	doh.register("CalendarLite", require.toUrl("./CalendarLite.html"), 999999);
+	doh.register("robot.Calendar_a11y", require.toUrl("./robot/Calendar_a11y.html"), 999999);
 
-	doh.registerUrl("dijit.tests.robot.TitlePane", dojo.moduleUrl("dijit","tests/robot/TitlePane.html"+userArgs), 999999);
+	doh.register("robot.TitlePane", require.toUrl("./robot/TitlePane.html"), 999999);
+	doh.register("Fieldset", require.toUrl("./Fieldset.html"), 999999);
 
-	doh.registerUrl("dijit.tests.robot.Toolbar", dojo.moduleUrl("dijit","tests/robot/Toolbar.html"+userArgs), 999999);
+	doh.register("robot.Toolbar", require.toUrl("./robot/Toolbar.html"), 999999);
 
-	doh.registerUrl("dijit.tests.robot.BgIframe", dojo.moduleUrl("dijit","tests/robot/BgIframe.html"+userArgs), 999999);
+	doh.register("_TimePicker", require.toUrl("./_TimePicker.html"), 999999);
 
-}catch(e){
-	doh.debug(e);
-}
+});
\ No newline at end of file
diff --git a/dijit/tests/helpers.js b/dijit/tests/helpers.js
index b624deb..acef77d 100644
--- a/dijit/tests/helpers.js
+++ b/dijit/tests/helpers.js
@@ -1,50 +1,65 @@
 // Helper methods for automated testing
 
-function isVisible(/*dijit._Widget || DomNode*/ node){
+define([
+	"dojo/_base/array", "dojo/Deferred", "dojo/promise/all",
+	"dojo/dom-attr", "dojo/dom-class", "dojo/dom-geometry", "dojo/dom-style",
+	"dojo/_base/kernel", "dojo/_base/lang", "dojo/on", "dojo/query", "dojo/ready", "dojo/sniff",
+	"dijit/a11y"	// isTabNavigable, dijit._isElementShown
+], function(array,  Deferred, all,
+			domAttr, domClass, domGeometry, domStyle,
+			kernel, lang, on, query, ready, has, a11y){
+
+
+// Globals used by onFocus()
+var curFocusNode, focusListener, focusCallback, focusCallbackDelay;
+
+var exports = {
+
+isVisible: function isVisible(/*dijit/_WidgetBase|DomNode*/ node){
 	// summary:
 	//		Return true if node/widget is visible
 	var p;
 	if(node.domNode){ node = node.domNode; }
-	return (dojo.style(node, "display") != "none") &&
-		(dojo.style(node, "visibility") != "hidden") &&
-		(p = dojo.position(node, true), p.y + p.h >= 0 && p.x + p.w >= 0 && p.h && p.w);
-}
+	return (domStyle.get(node, "display") != "none") &&
+		(domStyle.get(node, "visibility") != "hidden") &&
+		(p = domGeometry.position(node, true), p.y + p.h >= 0 && p.x + p.w >= 0 && p.h && p.w);
+},
 
-function isHidden(/*dijit._Widget || DomNode*/ node){
+isHidden: function isHidden(/*dijit/_WidgetBase|DomNode*/ node){
 	// summary:
 	//		Return true if node/widget is hidden
 	var p;
 	if(node.domNode){ node = node.domNode; }
-	return (dojo.style(node, "display") == "none") ||
-		(dojo.style(node, "visibility") == "hidden") ||
-		(p = dojo.position(node, true), p.y + p.h < 0 || p.x + p.w < 0 || p.h <= 0 || p.w <= 0);
-}
+	return (domStyle.get(node, "display") == "none") ||
+		(domStyle.get(node, "visibility") == "hidden") ||
+		(p = domGeometry.position(node, true), p.y + p.h < 0 || p.x + p.w < 0 || p.h <= 0 || p.w <= 0);
+},
 
-function innerText(/*DomNode*/ node){
+innerText: function innerText(/*DomNode*/ node){
 	// summary:
 	//		Browser portable function to get the innerText of specified DOMNode
-	return node.textContent || node.innerText || "";
-}
+	return lang.trim(node.textContent || node.innerText || "");
+},
 
-function tabOrder(/*DomNode?*/ root){
+tabOrder: function tabOrder(/*DomNode?*/ root){
 	// summary:
 	//		Return all tab-navigable elements under specified node in the order that
 	//		they will be visited (by repeated presses of the tab key)
 
 	var elems = [];
 
-	function walkTree(/*DOMNode*/parent){
-		dojo.query("> *", parent).forEach(function(child){
+	function walkTree(/*DOMNode*/ parent){
+		query("> *", parent).forEach(function(child){
 			// Skip hidden elements, and also non-HTML elements (those in custom namespaces) in IE,
-			// since show() invokes getAttribute("type"), which crash on VML nodes in IE.
-			if((dojo.isIE && child.scopeName!=="HTML") || !dijit._isElementShown(child)){
+			// since show() invokes getAttribute("type"), which crashes on VML nodes in IE.
+			if((has("ie") <= 8 && child.scopeName !== "HTML") || !a11y._isElementShown(child)){
 				return;
 			}
 
-			if(dijit.isTabNavigable(child)){
+			if(a11y.isTabNavigable(child)){
 				elems.push({
 					elem: child,
-					tabIndex: dojo.hasAttr(child, "tabIndex") ? dojo.attr(child, "tabIndex") : 0,
+					tabIndex: domClass.contains(child, "tabIndex") ? domAttr.get(child, "tabIndex") : 0,
 					pos: elems.length
 				});
 			}
@@ -59,16 +74,64 @@ function tabOrder(/*DomNode?*/ root){
 	elems.sort(function(a, b){
 		return a.tabIndex != b.tabIndex ? a.tabIndex - b.tabIndex : a.pos - b.pos;
 	});
-	return dojo.map(elems, function(elem){ return elem.elem; });
-}
+	return array.map(elems, function(elem){ return elem.elem; });
+},
+
+
+onFocus: function onFocus(func, delay){
+	// summary:
+	//		Wait for the next change of focus, and then delay ms (so widget has time to react to focus event),
+	//		then call func(node) with the currently focused node.  Note that if focus changes again during delay,
+	//		newest focused node is passed to func.
+
+	if(!focusListener){
+		focusListener = on(dojo.doc, "focusin", function(evt){
+			// Track most recently focused node; note it may change again before delay completes
+			curFocusNode = evt.target;
 
+			// If a handler was specified to fire after the next focus event (plus delay), set timeout to run it.
+			if(focusCallback){
+				var callback = focusCallback;
+				focusCallback = null;
+				setTimeout(function(){
+					callback(curFocusNode);		// return current focus, may be different than 10ms earlier
+				}, focusCallbackDelay);	// allow time for focus to change again, see #8285
+			}
+		});
+	}
 
-function onFocus(func){
+	focusCallback = func;
+	focusCallbackDelay = delay || 10;
+},
+
+waitForLoad: function(){
 	// summary:
-	//		On the next change of focus, and after widget has had time to react to focus event,
-	//		call func(node) with the newly focused node
-	var handle = dojo.subscribe("focusNode", function(node){
-		dojo.unsubscribe(handle);
-		setTimeout(function(){ func(node); }, 0);
+	//		Returns Promise that fires when all widgets have finished initializing
+
+	var d = new Deferred();
+
+	dojo.global.require(["dojo/ready", "dijit/registry"], function(ready, registry){
+		ready(function(){
+			// Deferred fires when all widgets with an onLoadDeferred have fired
+			var widgets = array.filter(registry.toArray(), function(w){ return w.onLoadDeferred; }),
+				deferreds = array.map(widgets, function(w){ return w.onLoadDeferred; });
+			console.log("Waiting for " + widgets.length + " widgets: " +
+				array.map(widgets, function(w){ return w.id; }).join(", "));
+			new all(deferreds).then(function(){
+				console.log("All widgets loaded.");
+				d.resolve(widgets);
+			});
+		});
 	});
+
+	return d.promise;
 }
+
+};
+
+// All the old tests expect these symbols to be global
+lang.mixin(kernel.global, exports);
+
+return exports;
+
+});
diff --git a/dijit/tests/i18n/calendar.html b/dijit/tests/i18n/calendar.html
index a23f9d7..70fece6 100644
--- a/dijit/tests/i18n/calendar.html
+++ b/dijit/tests/i18n/calendar.html
@@ -33,10 +33,10 @@
 
 		before
 
-		<input id="calendar1" data-dojo-type="dijit.Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"en-us"'/>
-		<input id="calendar2" data-dojo-type="dijit.Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"es-es"'/>
-		<input id="calendar3" data-dojo-type="dijit.Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"zh-cn"'/>
-		<input id="calendar4" data-dojo-type="dijit.Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"ar-sy"'/>
+		<input id="calendar1" data-dojo-type="dijit/Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"en-us"'/>
+		<input id="calendar2" data-dojo-type="dijit/Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"es-es"'/>
+		<input id="calendar3" data-dojo-type="dijit/Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"zh-cn"'/>
+		<input id="calendar4" data-dojo-type="dijit/Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"ar-sy"'/>
 
 		after
 
diff --git a/dijit/tests/i18n/currency.html b/dijit/tests/i18n/currency.html
index 4da4ca2..1fd95e7 100644
--- a/dijit/tests/i18n/currency.html
+++ b/dijit/tests/i18n/currency.html
@@ -6,9 +6,7 @@
 		<title>Test CurrencyTextBox</title>
 
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, extraLocale: ['zh-cn','fr-fr','ja-jp']"></script>
-		<script type="text/javascript" src="../../../dojo/currency.js"></script>
-		<script type="text/javascript" src="../../../dojo/number.js"></script>
+			data-dojo-config="isDebug: true, extraLocale: ['zh-cn','fr-fr','ja-jp']"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dijit.form.NumberTextBox");
@@ -23,6 +21,9 @@
 		<script src="test_i18n.js"></script>
 		<script type="text/javascript">
 			dojo.ready(function(){
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
 				doh.register("t", getAllTestCases());
 				doh.run();
 			});
@@ -152,8 +153,6 @@
 				}
 			]);
 
-			dojo.parser.parse();
-
 		})();
 
 		</script>
diff --git a/dijit/tests/i18n/date.html b/dijit/tests/i18n/date.html
index 46960f1..7cf2a39 100644
--- a/dijit/tests/i18n/date.html
+++ b/dijit/tests/i18n/date.html
@@ -6,9 +6,7 @@
 		<title>Test DateTextBox</title>
 
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, extraLocale: ['zh-cn','fr-fr','ja-jp','ru-ru','en-us','de-de','es-es','it-it','pt-br','ko-kr','zh-tw']"></script>
-		<script type="text/javascript" src="../../../dojo/currency.js"></script>
-		<script type="text/javascript" src="../../../dojo/number.js"></script>
+			data-dojo-config="isDebug: true, extraLocale: ['zh-cn','fr-fr','ja-jp','ru-ru','en-us','de-de','es-es','it-it','pt-br','ko-kr','zh-tw']"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dijit.form.NumberTextBox");
@@ -23,6 +21,9 @@
 		<script src="test_i18n.js"></script>
 		<script type="text/javascript">
 			dojo.ready(function(){
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
 				doh.register("t", getAllTestCases());
 				doh.run();
 			});
@@ -148,8 +149,6 @@
 			gen4DateFormat(testCases, "zh-tw", "zh-TW", new Date(2005, 6, 31),
 				"2005/7/31", "", "2005/7/31", "", "2005年7月31日", "", "2005年7月31日星期日", "");
 			genValidateTestCases("Date Validate", "dijit.form.DateTextBox", testCases);
-
-			dojo.parser.parse();
 		})();
 		</script>
 	</body>
diff --git a/dijit/tests/i18n/digit.html b/dijit/tests/i18n/digit.html
index 6527d9e..e10c540 100644
--- a/dijit/tests/i18n/digit.html
+++ b/dijit/tests/i18n/digit.html
@@ -6,9 +6,7 @@
 		<title>Test Hindi/Arabic numerals</title>
 
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, extraLocale: ['ar-eg','hi-in']"></script>
-		<script type="text/javascript" src="../../../dojo/currency.js"></script>
-		<script type="text/javascript" src="../../../dojo/number.js"></script>
+			data-dojo-config="isDebug: true, extraLocale: ['ar-eg','hi-in']"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dijit.form.NumberTextBox");
@@ -23,39 +21,42 @@
 		<script src="test_i18n.js"></script>
 		<script type="text/javascript">
 			dojo.ready(function(){
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
 				doh.register("t", getAllTestCases());
 				doh.run();
 			});
 		</script>
 
 		<script>
-			function gen4DateFormat(testCases, language, locale, date, short, shortCmt, medium, mediumCmt, long, longCmt, full, fullCmt){
+			function gen4DateFormat(testCases, language, locale, date, shortVal, shortCmt, mediumVal, mediumCmt, longVal, longCmt, fullVal, fullCmt){
 				testCases.push({
 				  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'short', localeDigit: true}" : "{formatLength:'short'}", lang: language},
 				  desc: "Locale: <b>" + locale + "</b> Format: <b>Short</b>",
 				  value: date,
-				  expValue: short,
+				  expValue: shortVal,
 				  comment: shortCmt
 				});
 				testCases.push({
 				  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'medium', localeDigit: true}" : "{formatLength:'medium'}", lang: language},
 				  desc: "Locale: <b>" + locale + "</b> Format: <b>Medium</b>",
 				  value: date,
-				  expValue: medium,
+				  expValue: mediumVal,
 				  comment: mediumCmt
 				});
 				testCases.push({
 				  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'long', localeDigit: true}" : "{formatLength:'long'}", lang: language},
 				  desc: "Locale: <b>" + locale + "</b> Format: <b>Long</b>",
 				  value: date,
-				  expValue: long,
+				  expValue: longVal,
 				  comment: longCmt
 				});
 				testCases.push({
 				  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'full', localeDigit: true}" : "{formatLength:'full'}", lang: language},
 				  desc: "Locale: <b>" + locale + "</b> Format: <b>Full</b>",
 				  value: date,
-				  expValue: full,
+				  expValue: fullVal,
 				  comment: fullCmt
 				});
 			}
@@ -255,8 +256,6 @@
 				"२००५-०७-३१", "<a href='currency.html#cmt_3'>See #3 (currency.html).</a>", "२००५ जुलाई ३१", "<a href='currency.html#cmt_3'>See #3 (currency.html).</a>", "२००५ जुलाई ३१", "<a href='currency.html#cmt_3'>See #3 (currency.html).</a>", "रविवार, २००५ जुलाई ३१", "<a href='currency.html#cmt_3'>See #3 (currency.html).</a>");
 			genValidateTestCases("Date Validate", "dijit.form.DateTextBox", testCases);
 
-			dojo.parser.parse();
-
 		})();
 
 		</script>
diff --git a/dijit/tests/i18n/module.js b/dijit/tests/i18n/module.js
index 40cc667..6971b0b 100644
--- a/dijit/tests/i18n/module.js
+++ b/dijit/tests/i18n/module.js
@@ -1,14 +1,10 @@
-dojo.provide("dijit.tests.i18n.module");
+define(["doh/main", "require"], function(doh, require){
 
-try{
-	if(dojo.isBrowser){
-		doh.registerUrl("dijit.tests.i18n.currency", dojo.moduleUrl("dijit", "tests/i18n/currency.html"), 999999);
-		doh.registerUrl("dijit.tests.i18n.date", dojo.moduleUrl("dijit", "tests/i18n/date.html"), 999999);
-		doh.registerUrl("dijit.tests.i18n.number", dojo.moduleUrl("dijit", "tests/i18n/number.html"), 999999);
-		doh.registerUrl("dijit.tests.i18n.textbox", dojo.moduleUrl("dijit", "tests/i18n/textbox.html"), 999999);
-		doh.registerUrl("dijit.tests.i18n.time", dojo.moduleUrl("dijit", "tests/i18n/time.html"), 999999);
-		doh.registerUrl("dijit.tests.i18n.digit", dojo.moduleUrl("dijit", "tests/i18n/digit.html"), 999999);
-	}
-}catch(e){
-	doh.debug(e);
-}
+	doh.register("i18n.currency", require.toUrl("./currency.html"), 999999);
+	doh.register("i18n.date", require.toUrl("./date.html"), 999999);
+	doh.register("i18n.number", require.toUrl("./number.html"), 999999);
+	doh.register("i18n.textbox", require.toUrl("./textbox.html"), 999999);
+	doh.register("i18n.time", require.toUrl("./time.html"), 999999);
+	doh.register("i18n.digit", require.toUrl("./digit.html"), 999999);
+
+});
diff --git a/dijit/tests/i18n/number.html b/dijit/tests/i18n/number.html
index e05c297..9a128db 100644
--- a/dijit/tests/i18n/number.html
+++ b/dijit/tests/i18n/number.html
@@ -6,9 +6,7 @@
 		<title>Test NumberTextBox</title>
 
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, extraLocale: ['zh-cn','fr-fr']"></script>
-		<script type="text/javascript" src="../../../dojo/currency.js"></script>
-		<script type="text/javascript" src="../../../dojo/number.js"></script>
+			data-dojo-config="isDebug: true, extraLocale: ['zh-cn','fr-fr']"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dijit.form.NumberTextBox");
@@ -23,6 +21,9 @@
 		<script src="test_i18n.js"></script>
 		<script type="text/javascript">
 			dojo.ready(function(){
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
 				doh.register("t", getAllTestCases());
 				doh.run();
 			});
@@ -126,8 +127,6 @@
 				}
 			]);
 
-			dojo.parser.parse();
-
 		})();
 
 		</script>
diff --git a/dijit/tests/i18n/test_i18n.js b/dijit/tests/i18n/test_i18n.js
index 2e0d6fd..07aee31 100644
--- a/dijit/tests/i18n/test_i18n.js
+++ b/dijit/tests/i18n/test_i18n.js
@@ -27,25 +27,6 @@ function startTest(t){
 	startTestValidate(t);
 }
 
-function escapeEx(s){
-	var result = "";
-	for(var i = 0; i < s.length; i++){
-		var c = s.charAt(i);
-		switch (c){
-			case '"':
-				result += '\\"';
-				break;
-			case "'":
-				result += "\\'";
-				break;
-			default:
-				result += escape(c);
-				break;
-		}
-	}
-	return result;
-}
-
 function getAllTestCases(){
 	var allTestCases = [];
 	for(var i = 0; i < formatWidgetCount; i++){
@@ -69,14 +50,11 @@ function startTestFormat(i, t){
 	var res_node = dojo.doc.getElementById("test_display_result_" + i);
 	res_node.innerHTML = test_node.value;
 	res_node.style.backgroundColor = (test_node.value == exp) ? "#AFA" : "#FAA";
-	res_node.innerHTML += " <a style='font-size:0.8em' href='javascript:alert(\"Expected: " + escapeEx(exp) + "\\n Result: " + escapeEx(test_node.value) + "\")'>Compare (Escaped)</a>";
+	res_node.innerHTML += " <a style='font-size:0.8em' href='javascript:alert(\"Expected: " + encodeURIComponent(exp) + "\\n Result: " + encodeURIComponent(test_node.value) + "\")'>Compare (Escaped)</a>";
 	t.is(exp, test_node.value);
 }
 
 function startTestValidate(i, t){
-	/*
-	 * The dijit.byNode has an issue: cannot handle same id.
-	 */
 	var test_node = dojo.doc.getElementById("test_validate_" + i);
 	var inp_node = dojo.doc.getElementById("test_validate_input_" + i);
 	var exp = dojo.doc.getElementById("test_validate_expected_" + i).innerHTML;
@@ -84,17 +62,8 @@ function startTestValidate(i, t){
 	var val_node = dojo.doc.getElementById("test_display_value_" + i);
 
 	test_node.value = inp_node.value;
-	/*
-	 * The dijit.byNode has an issue.
-	 */
-	var widget = null;
-	var node = test_node;
-	while ((widget = dijit.byNode(node)) == null){
-		node = node.parentNode;
-		if(!node){
-			break;
-		}
-	}
+
+	var widget = widget = dijit.getEnclosingWidget(test_node);
 
 	if(widget){
 		widget.focus();
diff --git a/dijit/tests/i18n/textbox.html b/dijit/tests/i18n/textbox.html
index 97ebe2d..9e19237 100644
--- a/dijit/tests/i18n/textbox.html
+++ b/dijit/tests/i18n/textbox.html
@@ -6,9 +6,7 @@
 		<title>Test TextBox</title>
 
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-		<script type="text/javascript" src="../../../dojo/currency.js"></script>
-		<script type="text/javascript" src="../../../dojo/number.js"></script>
+			data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dijit.form.NumberTextBox");
@@ -23,6 +21,9 @@
 		<script src="test_i18n.js"></script>
 		<script type="text/javascript">
 			dojo.ready(function(){
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
 				doh.register("t", getAllTestCases());
 				doh.run();
 			});
@@ -149,8 +150,6 @@
 
 			]);
 
-			dojo.parser.parse();
-
 		})();
 		</script>
 
diff --git a/dijit/tests/i18n/time.html b/dijit/tests/i18n/time.html
index 207fe88..ba9ddda 100644
--- a/dijit/tests/i18n/time.html
+++ b/dijit/tests/i18n/time.html
@@ -33,9 +33,7 @@
 		</style>
 
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, extraLocale: ['zh-cn','fr-fr','ja-jp','ar-eg','ru-ru','hi-in','en-us']"></script>
-		<script type="text/javascript" src="../../../dojo/currency.js"></script>
-		<script type="text/javascript" src="../../../dojo/number.js"></script>
+			data-dojo-config="isDebug: true, extraLocale: ['zh-cn','fr-fr','ja-jp','ar-eg','ru-ru','hi-in','en-us']"></script>
 		<script type="text/javascript" src="test_i18n.js"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.form.ValidationTextBox");
@@ -43,21 +41,11 @@
 			dojo.require("dojo.date.stamp");
 			dojo.require("dojo.date");
 			dojo.require("dojo.string");
+			dojo.require("dojo.number");
 			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 			dojo.require("doh.runner");
 
 			dojo.ready(function(){
-				dojo.declare(
-					"dijit.form.TimeTextBox",
-					dijit.form.ValidationTextBox,
-					{
-						regExpGen: dojo.date.locale.regexp,
-						format: dojo.date.locale.format,
-						parse: dojo.date.locale.parse,
-						value: new Date()
-					}
-				);
-	
 				var tz_s = dojo.date.getTimezoneName(new Date());
 				if(!tz_s){
 					var offset = new Date().getTimezoneOffset();
@@ -158,7 +146,9 @@
 					"१५:२५", "", "१५:२५:३५", "", "१५:२५:३५ UTC", " ", "१५:२५:३५ UTC", " ");
 				genValidateTestCases("Time Validate", "dijit.form.TimeTextBox", testCases);
 
-				dojo.parser.parse();
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
 
 				doh.register("t", getAllTestCases());
 
diff --git a/dijit/tests/infrastructure-module.js b/dijit/tests/infrastructure-module.js
index 276a4bb..3a6cd9d 100644
--- a/dijit/tests/infrastructure-module.js
+++ b/dijit/tests/infrastructure-module.js
@@ -1,27 +1,40 @@
-dojo.provide("dijit.tests.infrastructure-module");
+define(["doh/main", "require"], function(doh, require){
+
+	// Utility methods (previously in dijit/_base)
+	doh.register("registry", require.toUrl("./registry.html"), 999999);
+	doh.register("focus", require.toUrl("./focus.html"), 999999);
+	doh.register("place", require.toUrl("./place.html"), 999999);
+	doh.register("place-margin", require.toUrl("./place-margin.html"), 999999);
+	doh.register("place-clip", require.toUrl("./place-clip.html"), 999999);
+	doh.register("popup", require.toUrl("./popup.html"), 999999);
+	doh.register("a11y", require.toUrl("./a11y.html"), 999999);
+	doh.register("robot.typematic", require.toUrl("./robot/typematic.html"), 999999);
 
-try{
 	// _Widget
-	doh.registerUrl("dijit.tests._Widget-lifecycle", dojo.moduleUrl("dijit", "tests/_Widget-lifecycle.html"), 999999);
-	doh.registerUrl("dijit.tests._Widget-attr", dojo.moduleUrl("dijit", "tests/_Widget-attr.html"), 999999);
-	doh.registerUrl("dijit.tests._Widget-subscribe", dojo.moduleUrl("dijit", "tests/_Widget-subscribe.html"), 999999);
-	doh.registerUrl("dijit.tests._Widget-placeAt", dojo.moduleUrl("dijit", "tests/_Widget-placeAt.html"), 999999);
-	doh.registerUrl("dijit.tests.robot._Widget-on", dojo.moduleUrl("dijit","tests/_Widget-on.html"), 999999);
-	doh.registerUrl("dijit.tests.robot._Widget-deferredConnect", dojo.moduleUrl("dijit","tests/robot/_Widget-deferredConnect.html"), 999999);
-	doh.registerUrl("dijit.tests.robot._Widget-ondijitclick_mouse", dojo.moduleUrl("dijit","tests/robot/_Widget-ondijitclick_mouse.html"), 999999);
-	doh.registerUrl("dijit.tests.robot._Widget-ondijitclick_a11y", dojo.moduleUrl("dijit","tests/robot/_Widget-ondijitclick_a11y.html"), 999999);
+	doh.register("_Widget-lifecycle", require.toUrl("./_Widget-lifecycle.html"), 999999);
+	doh.register("_Widget-attr", require.toUrl("./_Widget-attr.html"), 999999);
+	doh.register("_Widget-subscribe", require.toUrl("./_Widget-subscribe.html"), 999999);
+	doh.register("_Widget-placeAt", require.toUrl("./_Widget-placeAt.html"), 999999);
+	doh.register("robot._Widget-on", require.toUrl("./_Widget-on.html"), 999999);
+	doh.register("robot._Widget-deferredConnect", require.toUrl("./robot/_Widget-deferredConnect.html"), 999999);
+	doh.register("robot._Widget-ondijitclick_mouse", require.toUrl("./robot/_Widget-ondijitclick_mouse.html"), 999999);
+	doh.register("robot._Widget-ondijitclick_a11y", require.toUrl("./robot/_Widget-ondijitclick_a11y.html"), 999999);
 
 	// _Templated and other mixins
-	doh.registerUrl("dijit.tests._TemplatedMixin", dojo.moduleUrl("dijit", "tests/_TemplatedMixin.html"), 999999);
-	doh.registerUrl("dijit.tests._WidgetsInTemplateMixin", dojo.moduleUrl("dijit", "tests/_WidgetsInTemplateMixin.html"), 999999);
-	doh.registerUrl("dijit.tests._Templated-widgetsInTemplate1.x", dojo.moduleUrl("dijit", "tests/_Templated-widgetsInTemplate1.x.html"), 999999);
-	doh.registerUrl("dijit.tests._Container", dojo.moduleUrl("dijit", "tests/_Container.html"), 999999);
+	doh.register("_AttachMixin", require.toUrl("./_AttachMixin.html"), 999999);
+	doh.register("_TemplatedMixin", require.toUrl("./_TemplatedMixin.html"), 999999);
+	doh.register("_WidgetsInTemplateMixin", require.toUrl("./_WidgetsInTemplateMixin.html"), 999999);
+	doh.register("_Templated-widgetsInTemplate1.x", require.toUrl("./_Templated-widgetsInTemplate1.x.html"), 999999);
+	doh.register("_Container", require.toUrl("./_Container.html"), 999999);
+	doh.register("_KeyNavContainer", require.toUrl("./_KeyNavContainer.html"), 999999);
+	doh.register("_HasDropDown", require.toUrl("./_HasDropDown.html"), 999999);
 
-	doh.registerUrl("dijit.tests.Declaration", dojo.moduleUrl("dijit","tests/test_Declaration.html"), 999999);
-	doh.registerUrl("dijit.tests.Declaration_1.x", dojo.moduleUrl("dijit","tests/test_Declaration_1.x.html"), 999999);
+	doh.register("Declaration", require.toUrl("./test_Declaration.html"), 999999);
+	doh.register("Declaration_1.x", require.toUrl("./test_Declaration_1.x.html"), 999999);
 
 	// Miscellaneous
-	doh.registerUrl("dijit.tests.NodeList-instantiate", dojo.moduleUrl("dijit","tests/NodeList-instantiate.html"), 999999);
-}catch(e){
-	doh.debug(e);
-}
+	doh.register("NodeList-instantiate", require.toUrl("./NodeList-instantiate.html"), 999999);
+	doh.register("Destroyable", require.toUrl("./Destroyable.html"), 999999);
+	doh.register("robot.BgIframe", require.toUrl("./robot/BgIframe.html"), 999999);
+
+});
diff --git a/dijit/tests/layout/AccordionContainer.html b/dijit/tests/layout/AccordionContainer.html
index 4324766..a5f4fde 100644
--- a/dijit/tests/layout/AccordionContainer.html
+++ b/dijit/tests/layout/AccordionContainer.html
@@ -1,53 +1,53 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Accordion Widget Automated Test</title>
 
-	<!-- only needed for test files: -->
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<!-- only needed for alternate theme testing: -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<!-- helper methods -->
-	<script type="text/javascript" src="../helpers.js"></script>
+	<script src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojo.parser");
-		dojo.require("dijit.registry");
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.layout.AccordionContainer");
-		dojo.require("dijit.layout.ContentPane");
-
-		var accordion;
+		require([
+			"doh/runner",
+			"dojo/_base/array", "dojo/data/ItemFileReadStore", "dojo/dom", "dojo/dom-geometry", "dojo/parser", "dojo/query",
+			"dijit/registry", "dijit/layout/AccordionContainer", "dijit/layout/ContentPane", "dijit/Tree",
+			"dijit/tree/ForestStoreModel", "dijit/tests/helpers",
+			"dijit/form/Button", "dojo/domReady!"
+		], function(doh, array, ItemFileReadStore, dom, domGeom, parser, query,
+					registry, AccordionContainer, ContentPane, Tree, ForestStoreModel, helpers){
+
+			// Data used by Tree in markup test
+			data = {
+				identifier: 'id',
+				label: 'name',
+				items: [
+					{ id: 'AF', name:'Africa', type:'continent', population:'900 million', area: '30,221,532 sq km',
+							timezone: '-1 UTC to +4 UTC'},
+					{ id: 'AS', name:'Asia', type:'continent' },
+					{ id: 'OC', name:'Oceania', type:'continent', population:'21 million'},
+					{ id: 'AU', name:'Australia', type:'country', population:'21 million'},
+					{ id: 'EU', name:'Europe', type:'continent' },
+					{ id: 'NA', name:'North America', type:'continent' },
+					{ id: 'SA', name:'South America', type:'continent' }
+				]
+			};
+	
+			var accordion;
 
-		dojo.ready(function(){
 			doh.register("basic",
 				[
 					{
 						name: "create",
 						runTest: function(t){
-							accordion = new dijit.layout.AccordionContainer({style: "width: 400px; height: 400px;"}).placeAt(dojo.body());
+							accordion = new AccordionContainer({style: "width: 400px; height: 400px;"}).placeAt(document.body);
 
-							dojo.forEach([ "pane 1", "pane 2", "pane 3" ], function(title, i){
-								var content = new dijit.layout.ContentPane({id: title, title: title, selected: i==1});
+							array.forEach([ "pane 1", "pane 2", "pane 3" ], function(title, i){
+								var content = new ContentPane({id: title, title: title, selected: i==1});
 								content.containerNode.innerHTML = "this is " + title;
 								accordion.addChild(content);
 							});
 							accordion.startup();
-							var titles = dojo.query(".dijitAccordionText", accordion.domNode);
+							var titles = query(".dijitAccordionText", accordion.domNode);
 							t.is(3, titles.length, "number of titles");
 							t.is("pane 3", titles[2].innerHTML);
 
@@ -59,14 +59,14 @@
 						name: "initially open pane",
 						runTest: function(t){
 							// Pane 2 is initially open
-							var openPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+							var openPanes = query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
 								return node.parentNode.style.display != "none";
 							});
 							t.is(1, openPanes.length, "exactly one open pane");
-							t.is("pane 2", dijit.byNode(openPanes[0]).title, "pane 2 is initially open");
+							t.is("pane 2", registry.byNode(openPanes[0]).title, "pane 2 is initially open");
 
 							// And others are closed
-							var closedPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+							var closedPanes = query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
 								return node.parentNode.style.display == "none";
 							});
 							t.is(2, closedPanes.length, "n-1 closed panes");
@@ -75,10 +75,10 @@
 					{
 						name: "addChild at end",
 						runTest: function(t){
-							var pane4 = new dijit.layout.ContentPane({title: "pane 4", content: "this is pane 4"});
+							var pane4 = new ContentPane({title: "pane 4", content: "this is pane 4"});
 							accordion.addChild(pane4);
 
-							var titles = dojo.query(".dijitAccordionText", accordion.domNode);
+							var titles = query(".dijitAccordionText", accordion.domNode);
 							t.is(4, titles.length, "number of titles");
 							t.is("pane 4", titles[3].innerHTML);
 
@@ -90,10 +90,10 @@
 					{
 						name: "addChild after pane 1",
 						runTest: function(t){
-							pane1half = new dijit.layout.ContentPane({id: "pane1half", title: "pane 1.5", content: "this is pane 1.5"});
+							pane1half = new ContentPane({id: "pane1half", title: "pane 1.5", content: "this is pane 1.5"});
 							accordion.addChild(pane1half, 1);
 
-							var titles = dojo.query(".dijitAccordionText", accordion.domNode);
+							var titles = query(".dijitAccordionText", accordion.domNode);
 							t.is(5, titles.length, "number of titles");
 							t.is("pane 1.5", titles[1].innerHTML);
 
@@ -105,9 +105,9 @@
 					{
 						name: "removeChild(pane 1.5)",
 						runTest: function(t){
-							accordion.removeChild(dijit.byId('pane1half'));
+							accordion.removeChild(registry.byId('pane1half'));
 
-							var titles = dojo.query(".dijitAccordionText", accordion.domNode);
+							var titles = query(".dijitAccordionText", accordion.domNode);
 							t.is(4, titles.length, "number of titles");
 							t.is("pane 2", titles[1].innerHTML);
 
@@ -116,21 +116,21 @@
 							t.is("pane 2", children[1].title, "second child is again 'pane 2'");
 							
 							// spec is that removing a child shouldn't delete it
-							t.t(dijit.byId("pane1half"), "child removed but still exists");
+							t.t(registry.byId("pane1half"), "child removed but still exists");
 						}
 					},
 					{
 						name: "initially open pane (checking again)",
 						runTest: function(t){
 							// Pane 2 is initially open
-							var openPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+							var openPanes = query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
 								return node.parentNode.style.display != "none";
 							});
 							t.is(1, openPanes.length, "exactly one open pane");
-							t.is("pane 2", dijit.byNode(openPanes[0]).title, "pane 2 is initially open");
+							t.is("pane 2", registry.byNode(openPanes[0]).title, "pane 2 is initially open");
 
 							// And others are closed
-							var closedPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+							var closedPanes = query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
 								return node.parentNode.style.display == "none";
 							});
 							t.is(3, closedPanes.length, "n-1 closed panes");
@@ -142,17 +142,17 @@
 							// Selecting pane 3 should open it and close pane 1
 
 							// select w/out animation
-							accordion.selectChild(dijit.byId('pane 3'));
+							accordion.selectChild(registry.byId('pane 3'));
 
 							// Pane 3 is now open
-							var openPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+							var openPanes = query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
 								return node.parentNode.style.display != "none";
 							});
 							t.is(1, openPanes.length, "exactly one open pane");
-							t.is("pane 3", dijit.byNode(openPanes[0]).title, "pane 3 is now open");
+							t.is("pane 3", registry.byNode(openPanes[0]).title, "pane 3 is now open");
 
 							// And others are closed
-							var closedPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+							var closedPanes = query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
 								return node.parentNode.style.display == "none";
 							});
 							t.is(3, closedPanes.length, "n-1 closed panes");
@@ -164,21 +164,21 @@
 						setUp: function(t){
 							// Note that this kicks off an animation so it might be a while before the
 							// bottom setTimeout() fires, likely longer than the 300ms specified
-							accordion.selectChild(dijit.byId('pane 2'), true);
+							accordion.selectChild(registry.byId('pane 2'), true);
 						},
 						runTest: function(t){
 							// Selecting pane 2 should open it and close pane 3
 							var d = new doh.Deferred();
 							setTimeout(d.getTestCallback(function(){
 								// Pane 2 is now open
-								var openPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+								var openPanes = query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
 									return node.parentNode.style.display != "none";
 								});
 								t.is(1, openPanes.length, "exactly one open pane");
-								t.is("pane 2", dijit.byNode(openPanes[0]).title, "pane 3 is now open");
+								t.is("pane 2", registry.byNode(openPanes[0]).title, "pane 3 is now open");
 
 								// And others are closed
-								var closedPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+								var closedPanes = query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
 									return node.parentNode.style.display == "none";
 								});
 								t.is(3, closedPanes.length, "n-1 closed panes");
@@ -190,31 +190,31 @@
 						name: "destroy recursive",
 						runTest: function(t){
 							accordion.destroyRecursive();
-							t.is(1, dijit.registry.toArray().length, "accordion and subwidgets destroyed, pane1half remains");
+							t.is(1, registry.toArray().length, "accordion and subwidgets destroyed, pane1half remains");
 						}
 					}
 				]
 			);
 
 			doh.register("child events", function childEvents(t){
-				accordion = new dijit.layout.AccordionContainer({style: "width: 400px; height: 400px;"}).placeAt(dojo.body());
+				accordion = new AccordionContainer({style: "width: 400px; height: 400px;"}).placeAt(document.body);
 
-				dojo.forEach([ "a", "b", "c" ], function(title, i){
-					var content = new dijit.layout.ContentPane({id: title, title: title, selected: i==1});
+				array.forEach([ "a", "b", "c" ], function(title, i){
+					var content = new ContentPane({id: title, title: title, selected: i==1});
 					content.containerNode.innerHTML = "this is " + title;
 					accordion.addChild(content);
 				});
 				accordion.startup();
 
 				// Change title of a pane, should change corresponding button label			
-				dijit.byId("b").set("title", "b changed");
-				var titles = dojo.query(".dijitAccordionText", accordion.domNode);
+				registry.byId("b").set("title", "b changed");
+				var titles = query(".dijitAccordionText", accordion.domNode);
 				t.is(3, titles.length, "number of titles");
 				t.is("b changed", titles[1].innerHTML);
 
 				// Change tooltip of a pane, should change corresponding button tooltip			
-				dijit.byId("c").set("tooltip", "c tooltip changed");
-				titles = dojo.query(".dijitAccordionText", accordion.domNode);
+				registry.byId("c").set("tooltip", "c tooltip changed");
+				titles = query(".dijitAccordionText", accordion.domNode);
 				t.is(3, titles.length, "number of titles");
 				t.is("c tooltip changed", titles[2].title);
 			});
@@ -224,7 +224,7 @@
 					{
 						name: "create w/no children",
 						runTest: function(t){
-							accordion = new dijit.layout.AccordionContainer({style: "width: 400px; height: 400px;"}).placeAt(dojo.body());
+							accordion = new AccordionContainer({style: "width: 400px; height: 400px;"}).placeAt(document.body);
 							accordion.startup();
 							var children = accordion.getChildren();
 							t.is(0, children.length, "no children");
@@ -235,8 +235,8 @@
 					{
 						name: "add children",
 						runTest: function(t){
-							dojo.forEach([ "pane 10", "pane 11"], function(title, i){
-								var content = new dijit.layout.ContentPane({id: title, title: title});
+							array.forEach([ "pane 10", "pane 11"], function(title, i){
+								var content = new ContentPane({id: title, title: title});
 								content.containerNode.innerHTML = "this is " + title;
 								accordion.addChild(content);
 							});
@@ -247,8 +247,8 @@
 					{
 						name: "remove all children",
 						runTest: function(t){
-							var pane10 = dijit.byId("pane 10"),
-								pane11 = dijit.byId("pane 11");
+							var pane10 = registry.byId("pane 10"),
+								pane11 = registry.byId("pane 11");
 
 							t.is(pane10, accordion.selectedChildWidget, "pane 10 initially selected");
 
@@ -264,15 +264,15 @@
 					{
 						name: "add back children",
 						runTest: function(t){
-							dojo.forEach([ "pane 12", "pane 13"], function(title, i){
-								var content = new dijit.layout.ContentPane({id: title, title: title});
+							array.forEach([ "pane 12", "pane 13"], function(title, i){
+								var content = new ContentPane({id: title, title: title});
 								content.containerNode.innerHTML = "this is " + title;
 								accordion.addChild(content);
 							});
 
 							var children = accordion.getChildren();
 							t.is(2, children.length, "two new children");
-							t.is(dijit.byId("pane 12"), accordion.selectedChildWidget, "pane 12 selected");
+							t.is(registry.byId("pane 12"), accordion.selectedChildWidget, "pane 12 selected");
 						}
 					}
 				]
@@ -285,19 +285,20 @@
 					{
 						name: "create",
 						runTest: function(t){
-							accordion = new dijit.layout.AccordionContainer({style: "width: 400px; height: 400px;"}).placeAt(dojo.body());
+							accordion = new AccordionContainer({style: "width: 400px; height: 400px;"}).placeAt(document.body);
 
-							dojo.forEach([ "pane 1", "pane 2", "pane 3" ], function(title, i){
-								var content = new dijit.layout.ContentPane({id: title, title: title, selected: i==1});
+							array.forEach([ "pane 1", "pane 2", "pane 3" ], function(title, i){
+								var content = new ContentPane({id: title, title: title, selected: i==1});
 								content.containerNode.innerHTML = "this is " + title;
 								accordion.addChild(content);
 							});
 							accordion.startup();
 
 							// make sure size of selected child is correct						
-							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
-							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
-							doh.is(dojo.marginBox(accordion.selectedChildWidget.domNode).h, dojo.contentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
+							doh.t(domGeom.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
+							doh.t(domGeom.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
+							doh.is(domGeom.getMarginBox(accordion.selectedChildWidget.domNode).h,
+									domGeom.getContentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
 						}
 					},
 					{
@@ -306,7 +307,7 @@
 						setUp: function(t){
 							// Note that this kicks off an animation so it might be a while before the
 							// bottom setTimeout() fires, likely longer than the 300ms specified
-							accordion.selectChild(dijit.byId('pane 2'), true);
+							accordion.selectChild(registry.byId('pane 2'), true);
 						},
 						runTest: function(t){
 							// Selecting pane 2 should open it and close pane 3
@@ -315,9 +316,9 @@
 								doh.is("pane 2", accordion.selectedChildWidget.title);
 
 								// make sure size of selected child is correct						
-								doh.t(dojo.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
-								doh.t(dojo.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
-								doh.is(dojo.marginBox(accordion.selectedChildWidget.domNode).h, dojo.contentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
+								doh.t(domGeom.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
+								doh.t(domGeom.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
+								doh.is(domGeom.getMarginBox(accordion.selectedChildWidget.domNode).h, domGeom.getContentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
 							}), 300);
 							return d;
 						}
@@ -328,14 +329,14 @@
 					{
 						name: "remove pane #2, reselecting pane #1",
 						runTest: function(t){
-							accordion.removeChild(dijit.byId("pane 2"));
+							accordion.removeChild(registry.byId("pane 2"));
 
 							doh.is("pane 1", accordion.selectedChildWidget.title);
 
 							// make sure size of selected child is correct						
-							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
-							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
-							doh.is(dojo.marginBox(accordion.selectedChildWidget.domNode).h, dojo.contentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
+							doh.t(domGeom.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
+							doh.t(domGeom.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
+							doh.is(domGeom.getMarginBox(accordion.selectedChildWidget.domNode).h, domGeom.getContentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
 						}
 					},
 					{
@@ -344,7 +345,7 @@
 						setUp: function(t){
 							// Note that this kicks off an animation so it might be a while before the
 							// bottom setTimeout() fires, likely longer than the 300ms specified
-							accordion.selectChild(dijit.byId('pane 3'), true);
+							accordion.selectChild(registry.byId('pane 3'), true);
 						},
 						runTest: function(t){
 							// Selecting pane 2 should open it and close pane 3
@@ -353,9 +354,9 @@
 								doh.is("pane 3", accordion.selectedChildWidget.title);
 
 								// make sure size of selected child is correct						
-								doh.t(dojo.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
-								doh.t(dojo.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
-								doh.is(dojo.marginBox(accordion.selectedChildWidget.domNode).h, dojo.contentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
+								doh.t(domGeom.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
+								doh.t(domGeom.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
+								doh.is(domGeom.getMarginBox(accordion.selectedChildWidget.domNode).h, domGeom.getContentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
 							}), 300);
 							return d;
 						}
@@ -370,9 +371,9 @@
 							accordion.resize({h: 200});
 
 							// make sure size of selected child is correct						
-							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h > 100, "child height > 150");
-							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h < 200, "child height < 200");
-							doh.is(dojo.marginBox(accordion.selectedChildWidget.domNode).h, dojo.contentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
+							doh.t(domGeom.position(accordion.selectedChildWidget.domNode).h > 100, "child height > 150");
+							doh.t(domGeom.position(accordion.selectedChildWidget.domNode).h < 200, "child height < 200");
+							doh.is(domGeom.getMarginBox(accordion.selectedChildWidget.domNode).h, domGeom.getContentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
 						}
 					}
 				]
@@ -380,17 +381,17 @@
 
 			doh.register("destroy", [
 				function setUp(){
-					accPane = new dijit.layout.ContentPane({
+					accPane = new ContentPane({
 						id: "accPane",
 						onContentError: function(msg){
 							throw new Error(msg);
 						}
 					});
-					accPane.placeAt(dojo.body());
-					html='<div data-dojo-type="dijit.layout.AccordionContainer" id="Accordion" style="height: 300px;">' +
-						 	'<div data-dojo-type="dijit.layout.ContentPane" title="first" id="first">' +
-								'<div data-dojo-type=dijit.form.Button id=myButton>hello world</div></div>' +
-						 	'<div data-dojo-type="dijit.layout.ContentPane" title="second" id="second">second</div>' +
+					accPane.placeAt(document.body);
+					html='<div data-dojo-type="dijit/layout/AccordionContainer" id="Accordion" style="height: 300px;">' +
+						 	'<div data-dojo-type="dijit/layout/ContentPane" title="first" id="first">' +
+								'<div data-dojo-type=dijit/form/Button id=myButton>hello world</div></div>' +
+						 	'<div data-dojo-type="dijit/layout/ContentPane" title="second" id="second">second</div>' +
 							'</div>';
 				},
 
@@ -398,10 +399,10 @@
 					// Since the wrapper ContentPane hasn't been started yet, the Accordion won't be started, and wrapper
 					// (AccordionInnerContainer) widgets won't be created...
 					accPane.set("content", html);
-					doh.t(dojo.byId("Accordion"), "accordion created #1");
+					doh.t(dom.byId("Accordion"), "accordion created #1");
 					accPane.set("content", html); //setting the content twice will initiate a destroy
-					dijit.byId("Accordion").destroy();
-					doh.is(undefined, dojo.byId("Accordion"), "accordion destroyed #1");
+					registry.byId("Accordion").destroy();
+					doh.is(undefined, dom.byId("Accordion"), "accordion destroyed #1");
 				},
 				
 				function destroyStarted(){
@@ -409,10 +410,10 @@
 					accPane.startup();
 
 					accPane.set("content", html);
-					doh.t(dojo.byId("Accordion"), "accordion created #2");
+					doh.t(dom.byId("Accordion"), "accordion created #2");
 					accPane.set("content", html); //setting the content twice will initiate a destroy
-					dijit.byId("Accordion").destroy();
-					doh.is(undefined, dojo.byId("Accordion"), "accordion destroyed #2");
+					registry.byId("Accordion").destroy();
+					doh.is(undefined, dom.byId("Accordion"), "accordion destroyed #2");
 				}
 			]);
 
@@ -420,11 +421,11 @@
 				{
 					name: "create",
 					runTest: function(t){
-						dojo.parser.parse();
+						parser.parse();
 
-						accordion = dijit.byId("markupAccordion");
+						accordion = registry.byId("markupAccordion");
 
-						var titles = dojo.query(".dijitAccordionText", accordion.domNode);
+						var titles = query(".dijitAccordionText", accordion.domNode);
 						t.is(3, titles.length, "number of titles");
 						t.is("Other Lazy Load Pane", titles[2].innerHTML);
 
@@ -435,10 +436,10 @@
 				{
 					name: "addChild after pane 1",
 					runTest: function(t){
-						pane1half = new dijit.layout.ContentPane({id: "otherPane1half", title: "pane 1.5", content: "this is pane 1.5"});
+						pane1half = new ContentPane({id: "otherPane1half", title: "pane 1.5", content: "this is pane 1.5"});
 						accordion.addChild(pane1half, 1);
 
-						var titles = dojo.query(".dijitAccordionText", accordion.domNode);
+						var titles = query(".dijitAccordionText", accordion.domNode);
 						t.is(4, titles.length, "number of titles");
 						t.is("pane 1.5", titles[1].innerHTML);
 
@@ -453,53 +454,31 @@
 		});
 	</script>
 </head>
-<body class="claro" style="padding: 50px;">
+<body class="claro" style="padding: 50px;" role="main">
 
 	<h1 class="testTitle">AccordionContainer Automated Tests</h1>
 
 	<h2 class="testTitle">Markup Accordion</h2>
-	<div id="markupAccordion" data-dojo-type="dijit.layout.AccordionContainer"
+
+	<div data-dojo-type="dojo/data/ItemFileReadStore" data-dojo-id="continentStore" data="data"></div>
+	<div data-dojo-type="dijit/tree/ForestStoreModel" data-dojo-id="continentModel"
+		store="continentStore" query="{type:'continent'}"
+		rootId="continentRoot" rootLabel="Continents" childrenAttrs="children">
+	</div>
+
+
+	<div id="markupAccordion" data-dojo-type="dijit/layout/AccordionContainer"
 		 data-dojo-props='style:"width: 400px; height: 300px; overflow: hidden"'>
-		<div id="pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true,
-			title:"A Simple Pane", iconClass:"dijitEditorIcon dijitEditorIconSave", tooltip:"tooltip for simple pane" '>
-				<select>
-					<option>red</option>
-					<option>blue</option>
-					<option>green</option>
-				</select>
-				<p>
-				Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
-				suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.
-				Nulla facilisi. Cras venenatis urna et magna. Aenean magna mauris,
-				bibendum sit amet, semper quis, aliquet nec, sapien.  Aliquam
-				aliquam odio quis erat. Etiam est nisi, condimentum non, lacinia
-				ac, vehicula laoreet, elit. Sed interdum augue sit amet quam
-				dapibus semper. Nulla facilisi. Pellentesque lobortis erat nec
-				quam.
-				</p>
-				<p>
-				Sed arcu magna, molestie at, <input value="fringilla in, sodales"/> fringilla in, sodales eu, elit.
-				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
-				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
-				augue. Integer fermentum odio lobortis odio. Nullam mollis nisl non
-				metus. Maecenas nec nunc eget pede ultrices blandit. Ut non purus
-				ut elit convallis eleifend. Fusce tincidunt, justo quis tempus
-				euismod, magna nulla viverra libero, sit amet lacinia odio diam id
-				risus. Ut varius viverra turpis. Morbi urna elit, imperdiet eu,
-				porta ac, pharetra sed, nisi. Etiam ante libero, ultrices ac,
-				faucibus ac, cursus sodales, nisl. Praesent nisl sem, fermentum eu,
-				consequat quis, varius interdum, nulla. Donec neque tortor,
-				sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
-				ut eros sit amet ante pharetra interdum.
-				</p>
+		<div id="pane1" data-dojo-type="dijit/Tree" model="continentModel" data-dojo-props='selected:true,
+			title:"Tree Pane", iconClass:"dijitEditorIcon dijitEditorIconSave", tooltip:"tooltip for simple pane"'>
 		</div>
 
 		<!-- test lazy loading.   margin style for testing size calculations. -->
-		<div id="lazyLoadPane1" data-dojo-type="dijit.layout.ContentPane"
+		<div id="lazyLoadPane1" data-dojo-type="dijit/layout/ContentPane"
 			 data-dojo-props='title:"Lazy Load Pane", href:"doc1.html"'></div>
 
 		<!-- test lazy loading.   margin style for testing size calculations. -->
-		<div id="lazyLoadPane2" data-dojo-type="dijit.layout.ContentPane"
+		<div id="lazyLoadPane2" data-dojo-type="dijit/layout/ContentPane"
 			 data-dojo-props='title:"Other Lazy Load Pane", href:"doc1.html"'></div>
 
 	</div>
diff --git a/dijit/tests/layout/BorderContainer.html b/dijit/tests/layout/BorderContainer.html
index e49658b..1e8070f 100644
--- a/dijit/tests/layout/BorderContainer.html
+++ b/dijit/tests/layout/BorderContainer.html
@@ -1,324 +1,327 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>dijit.layout.BorderContainer DOH Test</title>
-
-	<!-- only needed for test files: -->
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<!-- only needed for alternate theme testing: -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<script type="text/javascript" src="robot/borderContainerTestFunctions.js"></script>
-	<script type="text/javascript" src="../helpers.js"></script>
-
-	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.form.FilteringSelect");
-
-		dojo.require("dijit.MenuBar");
-		dojo.require("dijit.PopupMenuBarItem");
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.MenuItem");
-
-		dojo.require("doh.runner");
-
-		var bc, cp1, cp2, cp3;
-        dojo.ready(function(){
-
-			doh.register("markup", [
-				function parse(){
-					dojo.parser.parse();
-				},
-				function initialConditions(){
-					checkBCpanes(dijit.byId("border1"));
-					checkBCpanes(dijit.byId("border2"));
-					doh.is("auto", dojo.style("border1-left", "overflow"), "overflow on ContentPane should be auto");
-					doh.t("layoutPriority" in dijit.byId("menu"),
-							"make sure layoutPriority flag added to _WidgetBase is visible in MenuBar");
-				},
-
-				function resize(){
-					// current size of panes
-					var oTop = dojo.position(dojo.byId("border1-top")),
-						oLeft = dojo.position(dojo.byId("border1-left")),
-						oCenter = dojo.position(dojo.byId("border1-center")),
-						oRight = dojo.position(dojo.byId("border1-right")),
-						oBottom = dojo.position(dojo.byId("border1-bottom"));
-
-					// make whole BorderContainer 100px bigger (width and height)
-					var mb = dojo.marginBox("border1");
-					dijit.byId("border1").resize({w: mb.w + 100, h: mb.h + 100});
-
-					// new size of panes
-					var nTop = dojo.position(dojo.byId("border1-top")),
-						nLeft = dojo.position(dojo.byId("border1-left")),
-						nCenter = dojo.position(dojo.byId("border1-center")),
-						nRight = dojo.position(dojo.byId("border1-right")),
-						nBottom = dojo.position(dojo.byId("border1-bottom"));
-
-					doh.is(oTop.w + 100, nTop.w, "top width + 100");
-					doh.is(oTop.h, nTop.h, "top height unchanged");
-					doh.is(oCenter.w + 100, nCenter.w, "center width + 100");
-					doh.is(oCenter.h + 100, nCenter.h, "center height + 100");
-					doh.is(oBottom.w + 100, nBottom.w, "bottom width + 100");
-					doh.is(oBottom.h, nBottom.h, "bottom height unchanged");
-					doh.is(oLeft.w, nLeft.w, "left width unchanged");
-					doh.is(oLeft.h + 100, nLeft.h, "left height + 100");
-					doh.is(oRight.w, nRight.w, "right width unchanged");
-					doh.is(oRight.h + 100, nRight.h, "right height + 100");
-
-					// size BorderContainer back to original size
-					dijit.byId("border1").resize({w: mb.w, h: mb.h});
-
-					var nnTop = dojo.position(dojo.byId("border1-top")),
-						nnLeft = dojo.position(dojo.byId("border1-left")),
-						nnCenter = dojo.position(dojo.byId("border1-center")),
-						nnRight = dojo.position(dojo.byId("border1-right")),
-						nnBottom = dojo.position(dojo.byId("border1-bottom"));
-
-					doh.is(dojo.toJson(oTop), dojo.toJson(nnTop), "top after second resize");
-					doh.is(dojo.toJson(oCenter), dojo.toJson(nnCenter), "center after second resize");
-					doh.is(dojo.toJson(oBottom), dojo.toJson(nnBottom), "bottom after second resize");
-					doh.is(dojo.toJson(oLeft), dojo.toJson(nnLeft), "left after second resize");
-					doh.is(dojo.toJson(oRight), dojo.toJson(nnRight), "right after second resize");
-				},
-
-				function addRemovePanes(){
-					// current size of panes
-					var oLeft = dojo.position(dojo.byId("border1-left")),
-						oCenter = dojo.position(dojo.byId("border1-center")),
-						oRight = dojo.position(dojo.byId("border1-right")),
-						oBottom = dojo.position(dojo.byId("border1-bottom"));
-
-					// remove top pane... should expand left/center/right
-					dijit.byId("border1").removeChild(dijit.byId("border1-top"));
-					doh.is("auto", dijit.byId("border1-top").domNode.style.top, "border1-topremove, style.top-->auto");
-					doh.is("auto", dijit.byId("border1-top").domNode.style.left, "border1-topremove, style.left-->auto");
-					doh.is("static", dijit.byId("border1-top").domNode.style.position, "border1-topremove, style.position");
-
-					// new size of panes
-					var nLeft = dojo.position(dojo.byId("border1-left")),
-						nCenter = dojo.position(dojo.byId("border1-center")),
-						nRight = dojo.position(dojo.byId("border1-right")),
-						nBottom = dojo.position(dojo.byId("border1-bottom"));
-
-					doh.t(nLeft.h > oLeft.h, "left height increased");
-					doh.t(nCenter.h > oCenter.h, "center height increased");
-					doh.t(nRight.h > oRight.h, "left height increased");
-					doh.is(oBottom.h, nBottom.h, "bottom height didn't change");
-
-					// remove left pane... should just expand center pane
-					dijit.byId("border1").removeChild(dijit.byId("border1-left"));
-
-					// new size of panes
-					var nnCenter = dojo.position(dojo.byId("border1-center")),
-						nnRight = dojo.position(dojo.byId("border1-right")),
-						nnBottom = dojo.position(dojo.byId("border1-bottom"));
-
-					doh.t(nnCenter.w > nCenter.w, "center width increased");
-					doh.is(dojo.toJson(nRight), dojo.toJson(nnRight), "right stayed same");
-					doh.is(dojo.toJson(nBottom), dojo.toJson(nnBottom), "bottom stayed same");
-
-					// check that all panes sane
-					checkBCpanes(dijit.byId("border1"));
-
-					// put back left pane as the top pane
-					dijit.byId("border1").addChild(dijit.byId("border1-left"));
-
-					// check that all panes sane
-					checkBCpanes(dijit.byId("border1"));
-				}
-			]);
-
-			doh.register("programmatic creation", [
-				function createProgramatically(){
-					originalWidgetCnt = dijit.registry.length;
-
-					bc = new dijit.layout.BorderContainer({style:'height:400px;width:500px;border:1px solid black'}).
-							placeAt("programmatic", "after");
-		
-					cp1 = new dijit.layout.ContentPane({region:'top',style:'height:100px;background-color:red',splitter:true, id:"cp1"});
-					cp1.domNode.innerHTML = "top pane";
-					bc.addChild(cp1);
-		
-					cp2 = new dijit.layout.ContentPane({region:'center',style:'background-color:green', id:'cp2'});
-					cp2.domNode.innerHTML = "center pane";
-					bc.addChild(cp2);
-		
-					cp3 = new dijit.layout.ContentPane({region:'left', splitter: true, style:'width: 100px;', id:'cp3'});
-					cp3.domNode.innerHTML = "left pane";
-					
-					bc.startup();
-
-					checkBCpanes(bc);
-				},
-				function addLeftPane(){
-					var nWidgetsBefore = dijit.registry.length;
-					bc.addChild(cp3);
-					checkBCpanes(bc);
-					doh.t(isVisible(cp3));
-					doh.is(nWidgetsBefore + 1, dijit.registry.length, "splitter widget created");
-				},
-				function removeTopPane(){
-					var nWidgetsBefore = dijit.registry.length;
-					bc.removeChild(cp1);
-					checkBCpanes(bc);
-					doh.f(isVisible(cp1));
-					doh.is(nWidgetsBefore - 1, dijit.registry.length, "splitter widget destroyed");
-				},
-				function removeLeftPane(){
-					bc.removeChild(cp3);
-					checkBCpanes(bc);
-					doh.f(isVisible(cp3));
-				},
-				function addLeftPane2(){
-					bc.addChild(cp3);
-					checkBCpanes(bc);
-					doh.t(isVisible(cp3));
-				},
-				function addTopPane(){
-					bc.addChild(cp1);
-					checkBCpanes(bc);
-					doh.t(isVisible(cp3));
-				},
-				function destroyAll(){
-					bc.destroyRecursive();
-					doh.is(originalWidgetCnt, dijit.registry.length, "BorderContainer and all contained widgets destroyed");
-				}
-			]);
-
-			doh.register("exceptions", [
-				function createProgramatically(){
-					bc = new dijit.layout.BorderContainer({style:'height:400px;width:500px;border:1px solid black'}, dojo.byId('main'));
-					doh.isNot(null, bc.domNode.parentNode, "has parent");
-
-					cp1 = new dijit.layout.ContentPane({region:'top',style:'height:100px;background-color:red',splitter:true, id:"cp1"});
-					cp1.domNode.innerHTML = "top pane";
-					bc.addChild(cp1);
-
-					cp2 = new dijit.layout.ContentPane({region:'center',style:'background-color:green', id:'cp2'});
-					cp2.domNode.innerHTML = "center pane";
-					bc.addChild(cp2);
-
-					var exception;
-					try{
-						cp3 = new dijit.layout.ContentPane({splitter: true, style:'width: 100px;', id:'cp3'});
-						cp3.domNode.innerHTML = "left pane";
-						bc.addChild(cp3);
-						bc.startup();
-					}catch(e){
-						doh.t(/No region setting for cp3/.test(e.toString()), "check exception: " + e);
-						exception = true;
-					}
-					doh.t(exception, "exception was fired");
-				}
-			]);
-
-			doh.run();
-        });
-
-	</script>
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+<title>BorderContainer DOH Test</title>
+
+<script type="text/javascript" src="../boilerplate.js"></script>
+
+<script type="text/javascript">
+require([
+	"doh/runner",
+	"dojo/dom", "dojo/dom-geometry", "dojo/dom-style", "dojo/json", "dojo/parser", "dojo/query",
+	"dijit/registry", "dijit/tests/helpers",
+	"dijit/tests/layout/robot/borderContainerTestFunctions",
+	"dijit/layout/BorderContainer",
+	"dijit/layout/ContentPane",
+
+	// used by parser
+	"dijit/form/FilteringSelect",
+	"dijit/MenuBar",
+	"dijit/PopupMenuBarItem",
+	"dijit/Menu",
+	"dijit/MenuItem",
+
+	"dojo/domReady!"
+
+], function(doh, dom, geom, style, json, parser, query, registry, helpers, bcTest,
+		BorderContainer, ContentPane){
+
+	var bc, cp1, cp2, cp3;
+
+	doh.register("markup", [
+		function parse(){
+			parser.parse();
+		},
+
+		function initialConditions(){
+			bcTest.checkBCpanes(registry.byId("border1"));
+			bcTest.checkBCpanes(registry.byId("border2"));
+			doh.is("auto", style.get("border1-left", "overflow"), "overflow on ContentPane should be auto");
+			doh.t("layoutPriority" in registry.byId("menu"),
+					"make sure layoutPriority flag added to _WidgetBase is visible in MenuBar");
+		},
+
+		function tabOrder(){
+			// The tab order between panes and splitters should match the visual layout, so that (in LTR mode)
+			// you tab to the left pane before its corresponding splitter, but tab to the right splitter before
+			// its corresponding pane.
+			var children = query("> *", registry.byId("border1").domNode).map(function(node){
+				return node.id;
+			});
+			doh.is("border1-top, border1-top_splitter, border1-left, border1-left_splitter, border1-center, " +
+					"border1-right_splitter, border1-right, border1-bottom_splitter, border1-bottom",
+				children.join(", "));
+		},
+
+		function resize(){
+			// current size of panes
+			var oTop = geom.position(dom.byId("border1-top")),
+					oLeft = geom.position(dom.byId("border1-left")),
+					oCenter = geom.position(dom.byId("border1-center")),
+					oRight = geom.position(dom.byId("border1-right")),
+					oBottom = geom.position(dom.byId("border1-bottom"));
+
+			// make whole BorderContainer 100px bigger (width and height)
+			var mb = geom.getMarginBox("border1");
+			registry.byId("border1").resize({w: mb.w + 100, h: mb.h + 100});
+
+			// new size of panes
+			var nTop = geom.position(dom.byId("border1-top")),
+					nLeft = geom.position(dom.byId("border1-left")),
+					nCenter = geom.position(dom.byId("border1-center")),
+					nRight = geom.position(dom.byId("border1-right")),
+					nBottom = geom.position(dom.byId("border1-bottom"));
+
+			doh.is(oTop.w + 100, nTop.w, "top width + 100");
+			doh.is(oTop.h, nTop.h, "top height unchanged");
+			doh.is(oCenter.w + 100, nCenter.w, "center width + 100");
+			doh.is(oCenter.h + 100, nCenter.h, "center height + 100");
+			doh.is(oBottom.w + 100, nBottom.w, "bottom width + 100");
+			doh.is(oBottom.h, nBottom.h, "bottom height unchanged");
+			doh.is(oLeft.w, nLeft.w, "left width unchanged");
+			doh.is(oLeft.h + 100, nLeft.h, "left height + 100");
+			doh.is(oRight.w, nRight.w, "right width unchanged");
+			doh.is(oRight.h + 100, nRight.h, "right height + 100");
+
+			// size BorderContainer back to original size
+			registry.byId("border1").resize({w: mb.w, h: mb.h});
+
+			var nnTop = geom.position(dom.byId("border1-top")),
+					nnLeft = geom.position(dom.byId("border1-left")),
+					nnCenter = geom.position(dom.byId("border1-center")),
+					nnRight = geom.position(dom.byId("border1-right")),
+					nnBottom = geom.position(dom.byId("border1-bottom"));
+
+			doh.is(json.stringify(oTop), json.stringify(nnTop), "top after second resize");
+			doh.is(json.stringify(oCenter), json.stringify(nnCenter), "center after second resize");
+			doh.is(json.stringify(oBottom), json.stringify(nnBottom), "bottom after second resize");
+			doh.is(json.stringify(oLeft), json.stringify(nnLeft), "left after second resize");
+			doh.is(json.stringify(oRight), json.stringify(nnRight), "right after second resize");
+		},
+
+		function addRemovePanes(){
+			// current size of panes
+			var oLeft = geom.position(dom.byId("border1-left")),
+					oCenter = geom.position(dom.byId("border1-center")),
+					oRight = geom.position(dom.byId("border1-right")),
+					oBottom = geom.position(dom.byId("border1-bottom"));
+
+			// remove top pane... should expand left/center/right
+			registry.byId("border1").removeChild(registry.byId("border1-top"));
+			doh.is("auto", registry.byId("border1-top").domNode.style.top, "border1-topremove, style.top-->auto");
+			doh.is("auto", registry.byId("border1-top").domNode.style.left, "border1-topremove, style.left-->auto");
+			doh.is("static", registry.byId("border1-top").domNode.style.position, "border1-topremove, style.position");
+
+			// new size of panes
+			var nLeft = geom.position(dom.byId("border1-left")),
+					nCenter = geom.position(dom.byId("border1-center")),
+					nRight = geom.position(dom.byId("border1-right")),
+					nBottom = geom.position(dom.byId("border1-bottom"));
+
+			doh.t(nLeft.h > oLeft.h, "left height increased");
+			doh.t(nCenter.h > oCenter.h, "center height increased");
+			doh.t(nRight.h > oRight.h, "left height increased");
+			doh.is(oBottom.h, nBottom.h, "bottom height didn't change");
+
+			// remove left pane... should just expand center pane
+			registry.byId("border1").removeChild(registry.byId("border1-left"));
+
+			// new size of panes
+			var nnCenter = geom.position(dom.byId("border1-center")),
+					nnRight = geom.position(dom.byId("border1-right")),
+					nnBottom = geom.position(dom.byId("border1-bottom"));
+
+			doh.t(nnCenter.w > nCenter.w, "center width increased");
+			doh.is(json.stringify(nRight), json.stringify(nnRight), "right stayed same");
+			doh.is(json.stringify(nBottom), json.stringify(nnBottom), "bottom stayed same");
+
+			// check that all panes sane
+			bcTest.checkBCpanes(registry.byId("border1"));
+
+			// put back left pane as the top pane
+			registry.byId("border1").addChild(registry.byId("border1-left"));
+
+			// check that all panes sane
+			bcTest.checkBCpanes(registry.byId("border1"));
+		}
+	]);
+
+	doh.register("programmatic creation", [
+		function createProgramatically(){
+			originalWidgetCnt = registry.length;
+
+			bc = new BorderContainer({style:'height:400px;width:500px;border:1px solid black'}).
+					placeAt("programmatic", "after");
+
+			cp1 = new ContentPane({region:'top',style:'height:100px;background-color:red',splitter:true, id:"cp1"});
+			cp1.domNode.innerHTML = "top pane";
+			bc.addChild(cp1);
+
+			cp2 = new ContentPane({region:'center',style:'background-color:green', id:'cp2'});
+			cp2.domNode.innerHTML = "center pane";
+			bc.addChild(cp2);
+
+			cp3 = new ContentPane({region:'left', splitter: true, style:'width: 100px;', id:'cp3'});
+			cp3.domNode.innerHTML = "left pane";
+
+			bc.startup();
+
+			bcTest.checkBCpanes(bc);
+		},
+		function addLeftPane(){
+			var nWidgetsBefore = registry.length;
+			bc.addChild(cp3);
+			bcTest.checkBCpanes(bc);
+			doh.t(helpers.isVisible(cp3));
+			doh.is(nWidgetsBefore + 1, registry.length, "splitter widget created");
+		},
+		function removeTopPane(){
+			var nWidgetsBefore = registry.length;
+			bc.removeChild(cp1);
+			bcTest.checkBCpanes(bc);
+			doh.f(helpers.isVisible(cp1));
+			doh.is(nWidgetsBefore - 1, registry.length, "splitter widget destroyed");
+		},
+		function removeLeftPane(){
+			bc.removeChild(cp3);
+			bcTest.checkBCpanes(bc);
+			doh.f(helpers.isVisible(cp3));
+		},
+		function addLeftPane2(){
+			bc.addChild(cp3);
+			bcTest.checkBCpanes(bc);
+			doh.t(helpers.isVisible(cp3));
+		},
+		function addTopPane(){
+			bc.addChild(cp1);
+			bcTest.checkBCpanes(bc);
+			doh.t(helpers.isVisible(cp3));
+		},
+		function destroyAll(){
+			bc.destroyRecursive();
+			doh.is(originalWidgetCnt, registry.length, "BorderContainer and all contained widgets destroyed");
+		}
+	]);
+
+	doh.register("exceptions", [
+		function createProgramatically(){
+			bc = new BorderContainer({style:'height:400px;width:500px;border:1px solid black'}, dom.byId('main'));
+			doh.isNot(null, bc.domNode.parentNode, "has parent");
+
+			cp1 = new ContentPane({region:'top',style:'height:100px;background-color:red',splitter:true, id:"cp1"});
+			cp1.domNode.innerHTML = "top pane";
+			bc.addChild(cp1);
+
+			cp2 = new ContentPane({region:'center',style:'background-color:green', id:'cp2'});
+			cp2.domNode.innerHTML = "center pane";
+			bc.addChild(cp2);
+
+			var exception;
+			try{
+				cp3 = new ContentPane({splitter: true, style:'width: 100px;', id:'cp3'});
+				cp3.domNode.innerHTML = "left pane";
+				bc.addChild(cp3);
+				bc.startup();
+			}catch(e){
+				doh.t(/No region setting for cp3/.test(e.message), "check exception: " + e);
+				exception = true;
+			}
+			doh.t(exception, "exception was fired");
+		}
+	]);
+
+	doh.run();
+});
+
+</script>
 </head>
-<body class="claro">
-	<p>Headline layout (default), left is constrained - min:150, max:250</p>
-	<div id="border1" data-dojo-type="dijit.layout.BorderContainer"
-		data-dojo-props='style:"width: 1000px; height: 300px; border: 2px solid blue;"'>
-		<div role="banner" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-top", region:"top", style:"background-color: #b39b86; border: 15px black solid; height: 50px;", splitter:true'>
-			top bar (resizable)
-		</div>
-		<div role="navigation" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-left", region:"left", style:"background-color: #acb386; border: 10px green solid; width: 100px;",
+<body class="claro" role="main" aria-label="body">
+<p>Headline layout (default), left is constrained - min:150, max:250</p>
+<div id="border1" data-dojo-type="dijit/layout/BorderContainer"
+	 data-dojo-props='style:"width: 1000px; height: 300px; border: 2px solid blue;"'>
+	<div role="banner" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border1-top", region:"top", style:"background-color: #b39b86; border: 15px black solid; height: 50px;", splitter:true'>
+		top bar (resizable)
+	</div>
+	<div role="navigation" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border1-left", region:"left", style:"background-color: #acb386; border: 10px green solid; width: 100px;",
 		splitter:true, minSize:150, maxSize:250'>
-			left (resizable b/w 150 → 250)
-		</div>
-		<div role="main" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-center", region:"center", style:"background-color: #f5ffbf; padding: 30px;"'>
-			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
-			(to check we're copying children around properly).<br />
-			<select data-dojo-type="dijit.form.FilteringSelect">
-				<option value="1">foo</option>
-				<option value="2">bar</option>
-				<option value="3">baz</option>
-			</select>
-			Here's some text that comes AFTER the combo box.
-		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-right", region:"right", style:"background-color: #acb386; width: 100px;"'>
-			right (fixed size)
-		</div>
-		<div role="contentinfo" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-bottom", region:"bottom", style:"background-color: #b39b86; height: 50px;", splitter:true'>
-			bottom bar (resizable)
-		</div>
+		left (resizable b/w 150 → 250)
 	</div>
+	<div role="main" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border1-center", region:"center", style:"background-color: #f5ffbf; padding: 30px;"' aria-labelledby="mylabel">
+		<label id="mylabel">main panel</label> with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+		(to check we're copying children around properly).<br />
+		<select aria-label="select" data-dojo-type="dijit/form/FilteringSelect">
+			<option value="1">foo</option>
+			<option value="2">bar</option>
+			<option value="3">baz</option>
+		</select>
+		Here's some text that comes AFTER the combo box.
+	</div>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border1-right", region:"right", style:"background-color: #acb386; width: 100px;"'>
+		right (fixed size)
+	</div>
+	<div role="contentinfo" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border1-bottom", region:"bottom", style:"background-color: #b39b86; height: 50px;", splitter:true'>
+		bottom bar (resizable)
+	</div>
+</div>
 
-	<p>Sidebar layout, BiDi sensitive, liveSplitters: false</p>
-	<div id="border2" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar", liveSplitters:false,
+<p>Sidebar layout, BiDi sensitive, liveSplitters: false</p>
+<div id="border2" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='design:"sidebar", liveSplitters:false,
 		style:"border: 20px solid black; width: 1000px; height: 300px;"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-leading", region:"leading", style:"background-color: #acb386; width: 100px;"'>
-			leading (fixed size)
-		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-top", region:"top", style:"background-color: #b39b86; height: 80px;"'>
-			top bar (fixed size)
-		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
-			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
-			(to check we're copying children around properly).<br />
-			<select data-dojo-type="dijit.form.FilteringSelect">
-				<option value="1">foo</option>
-				<option value="2">bar</option>
-				<option value="3">baz</option>
-			</select>
-			Here's some text that comes AFTER the combo box.
-		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-bottom", region:"bottom", style:"background-color: #b39b86; height: 80px;", splitter:true'>
-			bottom bar (resizable)
-		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-trailing", region:"trailing", style:"background-color: #acb386; width: 100px;", splitter:true'>
-			trailing (resizable)
-		</div>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border2-leading", region:"leading", style:"background-color: #acb386; width: 100px;"'>
+		leading (fixed size)
 	</div>
-
-	<p id="programmatic">Programatically created, then destroyed</p>
-	<div id='main'></div>
-
-	<p>BorderContainer with MenuBar</p>
-	<div id="menuBorder" data-dojo-type="dijit.layout.BorderContainer"
-		data-dojo-props='style:"width: 1000px; height: 300px; border: 2px solid blue;"'>
-		<div id="menu" data-dojo-type="dijit.MenuBar" data-dojo-props='region:"top", splitter:true'>
-			<div id="file" data-dojo-type="dijit.PopupMenuBarItem" >
-				<span>File</span>
-				<div id="fileMenu" data-dojo-type="dijit.Menu" >
-					<div id="new" data-dojo-type="dijit.MenuItem" >New</div>
-					<div id="open" data-dojo-type="dijit.MenuItem" >Open</div>
-				</div>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border2-top", region:"top", style:"background-color: #b39b86; height: 80px;"'>
+		top bar (fixed size)
+	</div>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border2-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+		main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+		(to check we're copying children around properly).<br />
+		<select aria-label="select2" data-dojo-type="dijit/form/FilteringSelect">
+			<option value="1">foo</option>
+			<option value="2">bar</option>
+			<option value="3">baz</option>
+		</select>
+		Here's some text that comes AFTER the combo box.
+	</div>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border2-bottom", region:"bottom", style:"background-color: #b39b86; height: 80px;", splitter:true'>
+		bottom bar (resizable)
+	</div>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border2-trailing", region:"trailing", style:"background-color: #acb386; width: 100px;", splitter:true'>
+		trailing (resizable)
+	</div>
+</div>
+
+<p id="programmatic">Programatically created, then destroyed</p>
+<div id='main'></div>
+
+<p>BorderContainer with MenuBar</p>
+<div id="menuBorder" data-dojo-type="dijit/layout/BorderContainer"
+	 data-dojo-props='style:"width: 1000px; height: 300px; border: 2px solid blue;"'>
+	<div id="menu" data-dojo-type="dijit/MenuBar" data-dojo-props='region:"top", splitter:true'>
+		<div id="file" data-dojo-type="dijit/PopupMenuBarItem" >
+			<span>File</span>
+			<div id="fileMenu" data-dojo-type="dijit/Menu" >
+				<div id="new" data-dojo-type="dijit/MenuItem" >New</div>
+				<div id="open" data-dojo-type="dijit/MenuItem" >Open</div>
 			</div>
-			<div id="edit" data-dojo-type="dijit.PopupMenuBarItem" >
-				<span>Edit</span>
-				<div id="editMenu" data-dojo-type="dijit.Menu" >
-					<div id="cut" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+		</div>
+		<div id="edit" data-dojo-type="dijit/PopupMenuBarItem" >
+			<span>Edit</span>
+			<div id="editMenu" data-dojo-type="dijit/Menu" >
+				<div id="cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
 						onClick:function(){ console.log("not actually cutting anything, just a test!"); }, accelKey:"Ctrl+X"'>Cut</div>
-					<div id="copy" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+				<div id="copy" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
 						onClick:function(){ console.log("not actually copying anything, just a test!") }, accelKey:"Ctrl+C"'>Copy</div>
-					<div id="paste" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+				<div id="paste" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
 						onClick:function(){ console.log("not actually pasting anything, just a test!") }, accelKey:"Ctrl+V"'>Paste</div>
-				</div>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region: "center", splitter:true'>
-			content pane under menu
-		</div>
 	</div>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region: "center", splitter:true'>
+		content pane under menu
+	</div>
+</div>
 
 </body>
 </html>
diff --git a/dijit/tests/layout/ContentPane-auto-require.html b/dijit/tests/layout/ContentPane-auto-require.html
new file mode 100644
index 0000000..8342bc8
--- /dev/null
+++ b/dijit/tests/layout/ContentPane-auto-require.html
@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>ContentPane Auto Require Tests</title>
+
+	<script src="../boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh",
+			"dojo/_base/declare",
+			"dojo/Deferred",
+			"dojo/dom",
+			"dojo/_base/lang",
+			"dojo/parser",
+			"dijit/registry",
+			"dojo/domReady!"
+		], function(doh, declare, Deferred, dom, lang, parser, registry){
+
+			// instances of AsyncWidget will finish initializing when this Deferred is resolved
+			var finishCreatingAsyncWidgets = new Deferred();
+
+			AsyncWidget = declare(null, {
+				declaredClass: "AsyncWidget",
+				markupFactory: function(params, node){
+					// the markup factory can return a promise, and the parser will wait
+					return finishCreatingAsyncWidgets.then(function(){return new AsyncWidget(params, node); });
+				},
+				constructor: function(args, node){
+					this.params = args;
+					lang.mixin(this, args);
+				},
+				startup: function(){
+					this._started = true;
+				}
+			});
+
+			doh.register("auto require", [
+				{
+					name: "auto-load parse",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						// This will test auto-loading but only if dijit/form/TextBox isn't in the cache
+						parser.parse(dom.byId("simple")).then(d.getTestCallback(function(){
+							t.is(typeof registry.byId("tb1"), "object", "objected created");
+						}));
+
+						return d;
+					}
+				},
+
+				{
+					name: "href",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						// This will test auto-loading but only if dijit/form/Button isn't in the cache
+						registry.byId("parsedPane1").set("href", "doc3.html").then(d.getTestCallback(function(){
+							t.is(typeof registry.byId("button1"), "object", "object created");
+						}));
+
+						return d;
+					}
+				},
+
+				function nested(){
+					var d = new doh.Deferred();
+
+					var parsePromise = parser.parse(dom.byId("nested"));
+
+					// Parser should wait for innerPane Contentpane,
+					// innerPane should wait for nested call to parser.parse(),
+					// and the nested parser.parse() call is waiting for AsyncWidget to initialize.
+					// This is to simulate when the nested parse() call is waiting for auto-load.
+					doh.f(parsePromise.isFulfilled(), "parse not completed yet");
+					doh.f(formWidget._started, "wrapper form widget not started yet");
+
+					finishCreatingAsyncWidgets.resolve(true);
+
+					return parsePromise.then(d.getTestCallback(function(){
+						doh.t(formWidget._started, "wrapper form widget started");
+					}));
+
+					return d;
+				}
+			]);
+				
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro" role="main">
+	<h1 class="testTitle">Dijit layout.ContentPane Auto-Require Tests</h1>
+
+	<h2>ContentPane Loading Content that Requires Auto-Require</h2>
+
+	<div id="simple">
+		<div data-dojo-type="dijit/layout/ContentPane" id="parsedPane1">
+			<input type="text" aria-label="tb1" id="tb1" data-dojo-type="dijit/form/TextBox" data-dojo-props="value: 'testValue'" />
+		</div>
+	</div>
+
+	<div id="nested">
+		<div data-dojo-type="dijit/_WidgetBase" data-dojo-id="formWidget">
+			<div data-dojo-type="dijit/layout/ContentPane" id="innerPane">
+				<!-- for simulating an asynchronous nested parse due to waiting for module to load -->
+				<span data-dojo-id="asyncWidget" data-dojo-type="AsyncWidget">hi</span>
+			</div>
+		</div>
+	</div>
+
+</body>
+</html>
diff --git a/dijit/tests/layout/ContentPane-remote.html b/dijit/tests/layout/ContentPane-remote.html
index 4bcbca9..81c64de 100644
--- a/dijit/tests/layout/ContentPane-remote.html
+++ b/dijit/tests/layout/ContentPane-remote.html
@@ -1,93 +1,85 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>ContentPane Remote Loading Test</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: false"></script>
-
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<!-- functions to help test -->
-	<script type="text/javascript" src="../helpers.js"></script>
+	<script src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-
-		dojo.require("dojo.parser");
-
-		dojo.require("dijit._Widget");
-		dojo.require("dijit._TemplatedMixin");
-
-		dojo.require("dijit.Tooltip");
-		dojo.require("dijit.TooltipDialog");
-
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.form.DropDownButton");
-
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.AccordionContainer");
-		dojo.require("dijit.layout.LinkPane");
-
-		var tabCounter;
-		function testClose(pane, tab){
-			// remove html from title
-			var title = dojo.trim(tab.title.replace(/<\/?[a-z][a-z0-9]*[^>]*>/ig, ""));
-			return confirm("Please confirm that you want tab "+title+" closed");
-		}
-
-		function createTab(){
-			if(!tabCounter){ tabCounter = 3; }
-
-			var title = '<img src="../images/plus.gif" style="background-color:#95B7D3;"/> Tab ' +(++tabCounter);
-			var refreshOnShow = !!(tabCounter % 2);
-
-			var newTab = new dijit.layout.ContentPane({
-				id: "ttab" + tabCounter,
-				title: title + (refreshOnShow ? ' <i>refreshOnShow</i>': ''),
-				closable:true,
-				refreshOnShow: refreshOnShow,
-				href: 'getResponse.php?delay=1000&messId='+tabCounter
-					+"&message="+encodeURI("<h1>Programmatically created Tab "+tabCounter+"</h1>")
-			}, dojo.doc.createElement('div'));
-
-			dijit.byId('ttabs').addChild(newTab);
-
-			newTab.startup();
-		}
-
-		function isLoading(domNode){
-			return domNode.firstChild.innerHTML == "Loading...";
-		}
+		require([
+			"doh/runner",
+			"dojo/_base/array",
+			"dojo/aspect",
+			"dojo/_base/declare",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/_base/lang",
+			"dojo/parser",
+			"dojo/request",
+			"dojo/when",
+			"dijit/registry",
+			"dijit/_WidgetBase",
+			"dijit/_TemplatedMixin",
+			"dijit/Tooltip",
+			"dijit/TooltipDialog",
+			"dijit/form/Button",
+			"dijit/form/DropDownButton",
+			"dijit/layout/ContentPane",
+			"dijit/layout/StackContainer",
+			"dijit/layout/TabContainer",
+			"dijit/layout/AccordionContainer",
+			"dijit/tests/helpers",
+			"dojo/domReady!"
+		], function(doh, array, aspect, declare, dom, domClass, lang, parser, request, when,
+				registry, _WidgetBase, _TemplatedMixin, Tooltip, TooltipDialog, Button, DropDownButton,
+				ContentPane, StackContainer, TabContainer, AccordionContainer, helpers){
+
+			var tabCounter;
+			testClose = function(pane, tab){
+				// remove html from title
+				var title = lang.trim(tab.title.replace(/<\/?[a-z][a-z0-9]*[^>]*>/ig, ""));
+				return confirm("Please confirm that you want tab "+title+" closed");
+			};
+
+
+			createTab = function(){
+				if(!tabCounter){ tabCounter = 3; }
+	
+				var title = '<img src="../images/plus.gif" style="background-color:#95B7D3;"/> Tab ' +(++tabCounter);
+				var refreshOnShow = !!(tabCounter % 2);
+	
+				var newTab = new ContentPane({
+					id: "ttab" + tabCounter,
+					title: title + (refreshOnShow ? ' <i>refreshOnShow</i>': ''),
+					closable:true,
+					refreshOnShow: refreshOnShow,
+					href: 'getResponse.php?delay=1000&messId='+tabCounter
+						+"&message="+encodeURI("<h1>Programmatically created Tab "+tabCounter+"</h1>")
+				}, document.createElement('div'));
+	
+				registry.byId('ttabs').addChild(newTab);
+	
+				newTab.startup();
+			};
 
-		dojo.ready(function(){
 			// create a do nothing, only for test widget
-			dojo.declare("dijit.TestWidget",
-				[dijit._Widget, dijit._TemplatedMixin], {
+			declare("TestWidget",
+				[_WidgetBase, _TemplatedMixin], {
 				templateString: "<span class='dijitTestWidget'></span>"
 			});
 
+
 			doh.register("parse", function parse(){
-				dojo.parser.parse();
+				console.log("parse");
+				return parser.parse();
 			});
 
 			var cp;
 
 			doh.register("ContentPane", [
 				function create(){
-					cp = new dijit.layout.ContentPane({}, dojo.byId("cp"));
+					cp = new ContentPane({}, dom.byId("cp"));
 				},
 
 				{
@@ -99,7 +91,7 @@
 						var d = new doh.Deferred();
 
 						cp.set('href', 'getResponse.php?messId=1').then(d.getTestCallback(function(){
-							doh.is(1, dijit._Widget.prototype.getChildren.call(cp).length);
+							doh.is(1, _WidgetBase.prototype.getChildren.call(cp).length);
 						}));
 						return d;
 					}
@@ -157,10 +149,10 @@
 						cp.set("content", "");
 					},
 					runTest: function(t){
-						dojo.connect(cp, "onUnload", function(){
+						cp.on("unload", function(){
 							console.log("cp unload of: " + cp.get('content'));
 						});
-						dojo.connect(cp, "onLoad", function(){
+						cp.on("load", function(){
 							console.log("cp load of: " + cp.get('content'));
 						});
 						var msgCanceled = "This message be canceled";
@@ -216,8 +208,8 @@
 						// including tracking if they get called repeatedly (they shouldn't)
 						var history = "";
 						var handles = [
-							dojo.connect(cp, "onUnload", function(){ history += "unloaded"}),
-							dojo.connect(cp, "onLoad", function(){ history += " and reloaded"})
+							cp.on("unload", function(){ history += "unloaded"}),
+							cp.on("load", function(){ history += " and reloaded"})
 						];
 
 						cp.set('href', "getResponse.php?delay=300&message=test");
@@ -233,13 +225,15 @@
 						}, 200);
 
 						var d = new t.Deferred();
-						handles.push(dojo.connect(cp, "_setContent", d.getTestCallback(function(){
+						handles.push(aspect.after(cp, "_setContent", d.getTestCallback(function(){
 							doh.f(ilObj.probed, "200ms after href set, cp was not loaded");
 							doh.t(cp.isLoaded, "eventually, cp was loaded");
 							doh.is("unloaded and reloaded", history);
 
-							dojo.forEach(handles, dojo.disconnect);
-						})));
+							array.forEach(handles, function(handle){
+								handle.remove();
+							});
+						}), true));
 						return d;
 					}
 				},
@@ -282,7 +276,7 @@
 
 						var d = new doh.Deferred();
 
-						evtHandle = dojo.connect(cp, 'onDownloadError', d.getTestErrback(function(e){
+						evtHandle = cp.on("downloaderror", d.getTestErrback(function(e){
 							doh.t(e, "onDownloadError got event argument on invokation");
 							setTimeout(d.getTestCallback(function(){
 								doh.is(msg, cp.domNode.innerHTML, "custom errortext set");
@@ -295,7 +289,7 @@
 						return d;
 					},
 					tearDown: function(){
-						dojo.disconnect(evtHandle);
+						evtHandle.remove();
 						cp.onDownloadError = orig;
 					}
 				},
@@ -316,25 +310,25 @@
 						var msg = "custom downloadstart message";
 						cp.onDownloadStart = function(){ return msg; };
 
-						startHandle = dojo.connect(cp, 'onDownloadStart', d.getTestErrback(function(){
+						startHandle = cp.on("downloadstart", d.getTestErrback(function(){
 							setTimeout(d.getTestErrback(function(){
 								// check that custom message was set
 								doh.is(msg, cp.containerNode.innerHTML, "custom download message was set");
 
 								// and then wait for the download to complete						
-								endHandle = dojo.connect(cp, 'onDownloadEnd', d.getTestCallback(function(){
+								endHandle = cp.on("downloadend", d.getTestCallback(function(){
 									// if this gets called (before the test timeout) then test succeeded
 								}));
 							}), 1);
 						}));
-						cp.set('href', 'getResponse.php?delay=400');
+						cp.set('href', 'getResponse.php?delay=400&messId=3');
 
 						return d;
 					},
 					tearDown: function(){
 						cp.onDownloadStart = origStart;
-						dojo.disconnect(startHandle);
-						dojo.disconnect(endHandle);
+						startHandle.remove();
+						endHandle.remove();
 					}
 				},
 
@@ -348,18 +342,18 @@
 					runTest:function(t){
 						var d = new doh.Deferred();
 
-						loadHandle = dojo.connect(cp, 'onUnload', d.getTestErrback(function(){							
-							unloadHandle = dojo.connect(cp, 'onLoad', d.getTestCallback(function(){
+						loadHandle = cp.on("unload", d.getTestErrback(function(){							
+							unloadHandle = cp.on("load", d.getTestCallback(function(){
 								// if this gets called (before the test timeout) then test succeeded
 							}));
 						}));
-						cp.set('href', 'getResponse.php?delay=400');
+						cp.set('href', 'getResponse.php?delay=400&messId=2');
 
 						return d;
 					},
 					tearDown: function(){
-						dojo.disconnect(loadHandle);
-						dojo.disconnect(unloadHandle);
+						loadHandle.remove();
+						unloadHandle.remove();
 					}
 				}
 			]);
@@ -370,20 +364,20 @@
 
 				var d = new doh.Deferred(),
 					loadingContent,
-					child = dijit.byId(childId),
-					contentNode = dojo.byId(childId);
+					child = registry.byId(childId),
+					contentNode = dom.byId(childId);
 
 				child.ioMethod = function(args){
-					loadingContent = innerText(contentNode);
+					loadingContent = helpers.innerText(contentNode);
 					delete child.ioMethod;
-					return dojo.xhrGet(args);
+					return request(args.url, args);
 				};
 
-				dojo.when(dijit.byId(parentId).selectChild(child), function(){
+				when(registry.byId(parentId).selectChild(child), function(){
 					setTimeout(d.getTestCallback(
 						function(){
 							doh.is(child.loadingMessage.replace(/<[^>]*>/g, ""), loadingContent, "loading message");
-							var startOfActualContent = innerText(contentNode).substring(0, startOfExpectedContent.length);
+							var startOfActualContent = helpers.innerText(contentNode).substring(0, startOfExpectedContent.length);
 							doh.is(startOfExpectedContent, startOfActualContent, "expected content");
 						}
 					), 1); // return from handler, then test
@@ -403,22 +397,22 @@
 					name: "setUp_StackContainer",
 					setUp:function(t){
 						// create a StackContainer
-						st = dojo.byId('stackcontainer');
-						dojo.addClass(st, 'box');
-						st = new dijit.layout.StackContainer({style: {height: "150px"}}, st);
+						st = dom.byId('stackcontainer');
+						domClass.add(st, 'box');
+						st = new StackContainer({style: {height: "150px"}}, st);
 
 						// the first child (by default) is the one that will
 						// be shown
-						st.addChild(new dijit.TestWidget());
+						st.addChild(new TestWidget());
 
 						// the second child *won't* be shown until selected
-						pane3 = new dijit.layout.ContentPane({
+						pane3 = new ContentPane({
 							id:"sc_pane2",
 							href:'getResponse.php?delay=300&message=Loaded!',
 							preventCache: true,
 							onLoad: function(){ pane3LoadCnt++; },
 							onUnload: function(){ pane3UnloadCnt++; }
-						}, dojo.doc.createElement('div'));
+						}, document.createElement('div'));
 						st.addChild(pane3);
 
 						// start the StackContainer; shouldn't cause ContentPane to load.
@@ -450,7 +444,7 @@
 
 						var d = new doh.Deferred();
 
-						dojo.when(st.selectChild(pane3), function(){
+						when(st.selectChild(pane3), function(){
 							setTimeout(d.getTestCallback(function(){
 								doh.t(pane3.isLoaded, "pane3.isLoaded");
 								doh.is(1, pane3LoadCnt, "onload was called");
@@ -474,8 +468,8 @@
 							onUnload: function(){ this._unload_fired = 1; },
 							onLoad: function(){ this._load_fired = 1; }
 						};
-						tmp.unloadHandle = dojo.connect(pane3, 'onUnload', tmp, 'onUnload');
-						tmp.loadHandle = dojo.connect(pane3, 'onLoad', tmp, 'onLoad');
+						tmp.unloadHandle = pane3.on("unload", lang.hitch(tmp, 'onUnload'));
+						tmp.loadHandle = pane3.on("load", lang.hitch(tmp, 'onLoad'));
 
 						pane3.refreshOnShow = true;
 					},
@@ -495,8 +489,8 @@
 						return d;
 					},
 					tearDown: function(){
-						dojo.disconnect(tmp.unloadHandle);
-						dojo.disconnect(tmp.loadHandle);
+						tmp.unloadHandle.remove();
+						tmp.loadHandle.remove();
 						pane3.refreshOnShow = pane3.constructor.prototype.refreshOnShow;
 					}
 				}
@@ -527,16 +521,16 @@
 					runTest: function(t){
 						var d = new doh.Deferred(),
 						wasLoading = false,
-						widget = dijit.byId("ac_pane3"),
+						widget = registry.byId("ac_pane3"),
 						loadhandler = widget.connect(widget, "onDownloadStart",
 							function(){
-    							widget.disconnect(loadhandler);
+    							loadhandler.remove();
 								wasLoading = true;
 							}
 						),
 						showhandler = widget.connect(widget, "_onShow",
 							function(){
-    							widget.disconnect(showhandler);
+    							showhandler.remove();
 								setTimeout(d.getTestCallback(
 									function(){
 										doh.f(wasLoading, "should not have reloaded")
@@ -545,7 +539,7 @@
 							}
 						);
 
-						dijit.byId("ac").selectChild("ac_pane3");
+						registry.byId("ac").selectChild("ac_pane3");
 						
 						return d;
 					}
@@ -564,14 +558,10 @@
 					name: "preload=true",
 					timeout: 5000,
 					runTest: function(t){
-						var dlg = dijit.byId("preloadTooltipDlg");
+						var dlg = registry.byId("preloadTooltipDlg");
 						if(!dlg.isLoaded){
-							var d = new doh.Deferred();
-							dlg.onLoadDeferred.then(
-								function(){ d.callback(true); },
-								function(e){ d.errback(e); }
-							);
-							return d;
+							doh.t(dlg.onLoadDeferred, "onLoadDeferred exists");
+							return dlg.onLoadDeferred;
 						}
 					}
 				},
@@ -582,20 +572,15 @@
 					timeout: 5000,
 					runTest: function(){
 						// Check that it isn't loaded yet
-						var dlg = dijit.byId("noPreloadTooltipDlg");
+						var dlg = registry.byId("noPreloadTooltipDlg");
 						doh.f(dlg.isLoaded, "didn't load yet");
 	
 						// Open the dialog and then return Deferred waiting for it to load.
 						// If it doesn't load then this test will get a timeout.
-						var btn = dijit.byId("noPreloadTooltipDlgBtn");
+						var btn = registry.byId("noPreloadTooltipDlgBtn");
 						btn.openDropDown();
 						doh.t(dlg.onLoadDeferred, "onLoadDeferred exists");
-						var d = new doh.Deferred();
-						dlg.onLoadDeferred.then(
-							function(){ d.callback(true); },
-							function(e){ d.errback(e); }
-						);
-						return d;
+						return dlg.onLoadDeferred;
 					}
 				}
 			]);
@@ -604,7 +589,7 @@
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Dijit layout.ContentPane (delayed) remote tests</h1>
 
@@ -619,49 +604,45 @@
 	The tabs also tests to insert html in the Tab title
 	</p>
 
-	<div id="createTab" data-dojo-type='dijit.form.Button' data-dojo-props='onClick:function(){ createTab() }'>Create a Tab</div>
-	<div id="ttabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"top", style:"width: 100%; height: 20em;"'>
-		<a id="ttab1" data-dojo-type="dijit.layout.LinkPane"
+	<div id="createTabButton" data-dojo-type='dijit/form/Button' data-dojo-props='onClick:function(){ createTab() }'>Create a Tab</div>
+	<div id="ttabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabPosition:"top", style:"width: 100%; height: 20em;"'>
+		<div id="ttab1" data-dojo-type="dijit/layout/ContentPane"
 			data-dojo-props='href:"getResponse.php?messId=3&delay=1000",
-			closable:true
-		'><img src='../images/copy.gif'/> Tab1</a>
-		<a id="ttab2" data-dojo-type="dijit.layout.LinkPane"
+			closable:true'
+		title="Tab1"></div>
+		<div id="ttab2" data-dojo-type="dijit/layout/ContentPane"
 			data-dojo-props='href:"getResponse.php?messId=4&delay=1000",
 			refreshOnShow:true, title:"Tab 2 ",
 			selected:true,
-			closable:true
-		'><i>refreshOnShow</i>
-			<img src='../images/cut.gif'/>
-		</a>
-		<a id="ttab3" data-dojo-type="dijit.layout.LinkPane"
+			closable:true'
+		title="refreshOnShow"></div>
+		<div id="ttab3" data-dojo-type="dijit/layout/ContentPane"
 			data-dojo-props='href:"getResponse.php?messId=5&delay=1000",
 			onClose:testClose,
 			closable:true
-		'>
-			<b>Tab 3</b>
-			<img src='../images/paste.gif'/>
-		</a>
+		' title="Tab 3">
+		</div>
 	</div>
 
 	<h2>AccordionContainer</h2>
-	<div data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props='id:"ac", style:"height:300px; width:400px;"'>
-		<div id="ac_pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"one", refreshOnShow:false, href:"getResponse.php?messId=4&delay=1000"'></div>
-		<div id="ac_pane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"two", refreshOnShow:true, href:"getResponse.php?messId=4&delay=4000"'></div>
-		<div id="ac_pane3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"three", refreshOnShow:false, href:"getResponse.php?messId=4&delay=4100"'></div>
+	<div data-dojo-type="dijit/layout/AccordionContainer" data-dojo-props='id:"ac", style:"height:300px; width:400px;"'>
+		<div id="ac_pane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"one", refreshOnShow:false, href:"getResponse.php?messId=4&delay=1000"'></div>
+		<div id="ac_pane2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"two", refreshOnShow:true, href:"getResponse.php?messId=4&delay=4000"'></div>
+		<div id="ac_pane3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"three", refreshOnShow:false, href:"getResponse.php?messId=4&delay=4100"'></div>
 	</div>
 
 	<h2>TooltipDialog</h2>
-	<div data-dojo-type="dijit.layout.ContentPane">
-		<div id="preloadTooltipDlgBtn" data-dojo-type="dijit.form.DropDownButton">
+	<div data-dojo-type="dijit/layout/ContentPane">
+		<div id="preloadTooltipDlgBtn" data-dojo-type="dijit/form/DropDownButton">
 			<span>Show Preload TooltipDialog</span>
-			<div id="preloadTooltipDlg" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information", preload: true, href: "doc1.html"'>
+			<div id="preloadTooltipDlg" data-dojo-type="dijit/TooltipDialog" data-dojo-props='title:"Enter Login information", preload: true, href: "doc1.html"'>
 			</div>
 		</div>
 	</div>
 
-	<div id="noPreloadTooltipDlgBtn" data-dojo-type="dijit.form.DropDownButton">
+	<div id="noPreloadTooltipDlgBtn" data-dojo-type="dijit/form/DropDownButton">
 		<span>Show No-Preload TooltipDialog</span>
-		<div id="noPreloadTooltipDlg" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information", preload: false, href: "doc1.html"'>
+		<div id="noPreloadTooltipDlg" data-dojo-type="dijit/TooltipDialog" data-dojo-props='title:"Enter Login information", preload: false, href: "doc1.html"'>
 		</div>
 	</div>
 
diff --git a/dijit/tests/layout/ContentPane.html b/dijit/tests/layout/ContentPane.html
index 8446de4..ce2ab0a 100644
--- a/dijit/tests/layout/ContentPane.html
+++ b/dijit/tests/layout/ContentPane.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>ContentPane DOH test</title>
@@ -15,478 +15,495 @@
 
 		.dijitTestWidget {
 			border: 1px dashed red;
-			background-color: #C0E209 ;
+			background-color: #C0E209;
 		}
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
 		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
-		dojo.require("doh.runner");
+		require([
+			"doh/runner",
+			"dojo/_base/array",
+			"dojo/_base/declare",
+			"dojo/dom",
+			"dojo/data/ItemFileReadStore",
+			"dojo/_base/NodeList",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/_WidgetBase",
+			"dijit/_TemplatedMixin",
+			"dijit/_WidgetsInTemplateMixin",
+			"dijit/_Container",
+			"dijit/Dialog",
+			"dijit/layout/_LayoutWidget",
+			"dijit/layout/ContentPane",
+			"dijit/layout/StackContainer",
+			"dojo/domReady!"
+		], function(doh, array, declare, dom, ItemFileReadStore, NodeList, parser,
+					registry, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _Container, Dialog, _LayoutWidget,
+					ContentPane, StackContainer){
 
-		dojo.require("dojo.parser");
-		dojo.require("dojo.data.ItemFileReadStore");
-
-		dojo.require("dijit._Widget");
-		dojo.require("dijit._TemplatedMixin");
-		dojo.require("dijit._WidgetsInTemplateMixin");
-		dojo.require("dijit._Container");
-		dojo.require("dijit.layout._LayoutWidget");
-		dojo.require("dijit.layout.StackContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.Dialog");
-
-
-		dojo.ready(function(){
 			// create a do nothing, only for test widget
-			dojo.declare("dijit.TestWidget",
-				[dijit._Widget, dijit._TemplatedMixin], {
+			declare("TestWidget",
+				[_WidgetBase, _TemplatedMixin], {
 				templateString: "<span class='dijitTestWidget'></span>"
 			});
 
-			doh.register("pane1",
-				[
-					{
-						name: "no_autoparse",
-						runTest: function(t){
-							if(dijit.byId("pane1")){
-								throw doh._AssertFailure("Page got autoparsed when it shouldn't");
-							}
+			doh.register("pane1", [
+				{
+					name: "no_autoparse",
+					runTest: function(t){
+						if(registry.byId("pane1")){
+							throw doh._AssertFailure("Page got autoparsed when it shouldn't");
 						}
 					}
-				]
-			);
+				}
+			]);
 
 			var pane2, MyWidget;
 
-			doh.registerGroup("pane2",
-				[
-					{
-						name: "clear_content",
-						setUp: function(t){
-							pane2 = new dijit.layout.ContentPane({
-								preventCache: true
-							}, dojo.byId("pane2"));
-							pane2.set("content", "");// pass undefined on purpose
-						},
-						runTest: function(t){
-							doh.is(0, dijit._Widget.prototype.getChildren.call(pane2).length);
-							doh.is("", pane2.domNode.innerHTML)
-						}
+			doh.registerGroup("pane2", [
+				{
+					name: "clear_content",
+					setUp: function(t){
+						pane2 = new ContentPane({
+							preventCache: true
+						}, dom.byId("pane2"));
+						pane2.set("content", "");// pass undefined on purpose
 					},
-					{
-						name: "setContent_String",
-						setUp: function(){
-							pane2.set("content", "");
-						},
-						runTest: function(t){
-							var msg = "<h3>a simple html string</h3>";
-							pane2.set("content", msg);
-							doh.is(msg, pane2.domNode.innerHTML.toLowerCase());
-						}
+					runTest: function(t){
+						doh.is(0, _WidgetBase.prototype.getChildren.call(pane2).length);
+						doh.is("", pane2.domNode.innerHTML)
+					}
+				},
+				{
+					name: "setContent_String",
+					setUp: function(){
+						pane2.set("content", "");
 					},
-					{
-						name: "setContent_DOMNode",
-						setUp: function(t){
-							var div = dojo.doc.createElement('div');
-							div.innerHTML = "set('content', [DOMNode] )";
-							div.setAttribute('data-dojo-type', 'dijit.TestWidget');
-							pane2.set("content", div);
-						},
-						runTest: function(t){
-							doh.is(1, dijit._Widget.prototype.getChildren.call(pane2).length);
-						},
-						tearDown: function(t){
-							pane2.set("content", ""); // clear content for next test
-						}
+					runTest: function(t){
+						var msg = "<h3>a simple html string</h3>";
+						pane2.set("content", msg);
+						doh.is(msg, pane2.domNode.innerHTML.toLowerCase());
+					}
+				},
+				{
+					name: "setContent_DOMNode",
+					setUp: function(t){
+						var div = document.createElement('div');
+						div.innerHTML = "set('content', [DOMNode] )";
+						div.setAttribute('data-dojo-type', 'TestWidget');
+						pane2.set("content", div);
 					},
-					{
-						name: "setContent_NodeList",
-						setUp: function(t){
-							var div = dojo.doc.createElement('div');
-							div.innerHTML = "<div data-dojo-type='dijit.TestWidget'>above</div>"
-											+"Testing!<div><p><span><b>Deep nested</b></span></p></div>"
-											+"<div data-dojo-type='dijit.TestWidget'>below</div>";
-
-							var list = div.childNodes;
-							pane2.set("content", div.childNodes);
-						},
-						runTest: function(t){
-							doh.is(2, dijit._Widget.prototype.getChildren.call(pane2).length);
-
-							//regular DOM check
-							var children = pane2.domNode.childNodes;
-							doh.is(4, children.length);
-							doh.is("Testing!", children[1].nodeValue);
-							doh.is("div", children[2].nodeName.toLowerCase());
-							doh.is("<p><span><b>deep nested</b></span></p>", children[2].innerHTML.toLowerCase());
-						}
+					runTest: function(t){
+						doh.is(1, _WidgetBase.prototype.getChildren.call(pane2).length);
 					},
-					{
-						name: "setContent_dojo_NodeList",
-						setUp: function(t){
-							pane2.set("content", "");
-						},
-						runTest: function(t){
-							var div = dojo.doc.createElement('div');
-							div.innerHTML = "<div data-dojo-type='dijit.TestWidget'>above</div>"
+					tearDown: function(t){
+						pane2.set("content", ""); // clear content for next test
+					}
+				},
+				{
+					name: "setContent_NodeList",
+					setUp: function(t){
+						var div = document.createElement('div');
+						div.innerHTML = "<div data-dojo-type='TestWidget'>above</div>"
 										+"Testing!<div><p><span><b>Deep nested</b></span></p></div>"
-										+"<div data-dojo-type='dijit.TestWidget'>below</div>";
-
-							var list = new dojo.NodeList();
-							dojo.forEach(div.childNodes, function(n){
-								list.push(n.cloneNode(true));
-							});
+										+"<div data-dojo-type='TestWidget'>below</div>";
 
-							pane2.set("content", list);
-							doh.is(4, pane2.domNode.childNodes.length);
-						}
+						var list = div.childNodes;
+						pane2.set("content", div.childNodes);
 					},
-					{
-						name: "extractContent",
-						runTest: function(t){
-							var def = pane2.extractContent;
-							doh.f(def);
-
-							// test that it's actually working
-							pane2.extractContent = true;
-							pane2.set("content", '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" '
-								+'"http://www.w3.org/TR/html4/strict.dtd">'
-								+'<html><head><style>body{font-weight:bold;}</style></head>'
-								+'<body>extractContent test</body></html>');
-
-							doh.is("extractContent test", pane2.domNode.innerHTML);
-
-							// reset back to default
-							pane2.extractContent = def;
-						}
+					runTest: function(t){
+						doh.is(2, _WidgetBase.prototype.getChildren.call(pane2).length);
+
+						//regular DOM check
+						var children = pane2.domNode.childNodes;
+						doh.is(4, children.length);
+						doh.is("Testing!", children[1].nodeValue);
+						doh.is("div", children[2].nodeName.toLowerCase());
+						doh.is("<p><span><b>deep nested</b></span></p>", children[2].innerHTML.toLowerCase());
+					}
+				},
+				{
+					name: "setContent_dojo_NodeList",
+					setUp: function(t){
+						pane2.set("content", "");
 					},
-					{
-						name: "setContent_widget", // for #12348
-						setUp: function(t){
-							// declare a widget whose template contains a non-templated widget
-							MyWidget = dojo.declare([dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
-								templateString: '<div><div '
-									+ 'data-dojo-type="dijit.layout.StackContainer"></div></div>'
-							});
-						},
-						runTest: function(t){
-							var w = new MyWidget(), dfd = new doh.Deferred();
-							pane2.set("content", w).then(function(){
-									dfd.callback(true);
-								}, function(e){
-									dfd.errback(e);
-							});
-							return dfd;
-						}
+					runTest: function(t){
+						var div = document.createElement('div');
+						div.innerHTML = "<div data-dojo-type='TestWidget'>above</div>"
+									+"Testing!<div><p><span><b>Deep nested</b></span></p></div>"
+									+"<div data-dojo-type='TestWidget'>below</div>";
+
+						var list = new NodeList();
+						array.forEach(div.childNodes, function(n){
+							list.push(n.cloneNode(true));
+						});
+
+						pane2.set("content", list);
+						doh.is(4, pane2.domNode.childNodes.length);
 					}
-				]
-			);
+				},
+				{
+					name: "extractContent",
+					runTest: function(t){
+						var def = pane2.extractContent;
+						doh.f(def);
+
+						// test that it's actually working
+						pane2.extractContent = true;
+						pane2.set("content", '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" '
+							+'"http://www.w3.org/TR/html4/strict.dtd">'
+							+'<html><head><style>body{font-weight:bold;}</style></head>'
+							+'<body>extractContent test</body></html>');
+
+						doh.is("extractContent test", pane2.domNode.innerHTML);
+
+						// reset back to default
+						pane2.extractContent = def;
+					}
+				},
+				{
+					name: "setContent_widget", // for #12348
+					setUp: function(t){
+						// declare a widget whose template contains a non-templated widget
+						MyWidget = declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+							templateString: '<div><div '
+								+ 'data-dojo-type="dijit/layout/StackContainer"></div></div>'
+						});
+					},
+					runTest: function(t){
+						var w = new MyWidget(), dfd = new doh.Deferred();
+						pane2.set("content", w).then(function(){
+								dfd.callback(true);
+							}, function(e){
+								dfd.errback(e);
+						});
+						return dfd;
+					}
+				}
+			]);
 
 			// Tests for doLayout parameter.
 			// When this parameter is true, the single ContentPane child is resized
 			// to match the size of the ContentPane.
+			// See also ContentPaneLayout.html.
 			var pane5;
-			doh.registerGroup("doLayout",
-				[
-					{
-						name: "simple",
-						setUp: function(t){
-							pane5 = new dijit.layout.ContentPane({
-								content:"<div data-dojo-type='dijit.layout.StackContainer'></div>"
-							}, dojo.byId("pane5"));
-							console.log(pane5);
-						},
-						runTest: function(t){
-							// since there's just a single child it should be marked
-							// for layout/resize along w/the ContentPane
-							doh.t(pane5._singleChild);
-						},
-						tearDown: function(t){
-							pane5.destroyRecursive();
-						}
+			doh.registerGroup("doLayout", [
+				{
+					name: "simple",
+					setUp: function(t){
+						pane5 = new ContentPane({
+							content:"<div data-dojo-type='dijit/layout/StackContainer'></div>"
+						}).placeAt(document.body);
+						pane5.startup();
 					},
-					{
-						name: "doLayout=false",
-						setUp: function(t){
-							pane5 = new dijit.layout.ContentPane({
-								content:
-									"<div data-dojo-type='dijit.layout.StackContainer'></div>",
-								doLayout: false
-							}, dojo.byId("pane5"));
-						},
-						runTest: function(t){
-							// since doLayout=false shouldn't try to resize child
-							doh.f(pane5._singleChild);
-						},
-						tearDown: function(t){
-							pane5.destroyRecursive();
-						}
+					runTest: function(t){
+						// since there's just a single child it should be marked
+						// for layout/resize along w/the ContentPane
+						doh.t(pane5._singleChild);
 					},
-					{
-						name: "mixed content",
-						setUp: function(t){
-							pane5 = new dijit.layout.ContentPane({
-								content:
-									"<span>hello world</span>" +
-									"<div data-dojo-type='dijit.layout.StackContainer'></div>"
-							}, dojo.byId("pane5"));
-						},
-						runTest: function(t){
-							// since there's plain HTML along with the widget, ContentPane shouldn't try to adjust
-							// this size of the widget (since that would cover up the other HTML)
-							doh.f(pane5._singleChild);
-						},
-						tearDown: function(t){
-							pane5.destroyRecursive();
-						}
+					tearDown: function(t){
+						pane5.destroyRecursive();
+					}
+				},
+				{
+					name: "doLayout=false",
+					setUp: function(t){
+						pane5 = new ContentPane({
+							content:
+								"<div data-dojo-type='dijit/layout/StackContainer'></div>",
+							doLayout: false
+						}).placeAt(document.body);
+						pane5.startup();
 					},
-					{
-						name: "two widgets",
-						setUp: function(t){
-							pane5 = new dijit.layout.ContentPane({
-								content:
-									"<div data-dojo-type='dijit.layout.StackContainer'></div>" +
-									"<div data-dojo-type='dijit.layout.StackContainer'></div>"
-							}, dojo.byId("pane5"));
-						},
-						runTest: function(t){
-							// since there are multiple children, neither should be marked
-							// for layout/resize along w/the ContentPane
-							doh.f(pane5._singleChild);
-						},
-						tearDown: function(t){
-							pane5.destroyRecursive();
-						}
+					runTest: function(t){
+						// since doLayout=false shouldn't try to resize child
+						doh.f(pane5._singleChild);
 					},
-					{
-						name: "dojo.data",
-						setUp: function(t){
-							pane5 = new dijit.layout.ContentPane({
-								content:
-									"<div data-dojo-type='dojo.data.ItemFileReadStore' data-dojo-id='dd'></div>" +
-									"<div data-dojo-type='dijit.layout.StackContainer' id='sc'></div>"
-							}, dojo.byId("pane5"));
-						},
-						runTest: function(t){
-							// there are two children but one is invisible, so the other should be marked
-							// for layout/resize along w/the ContentPane
-							doh.t(dd, "dd exists");
-							doh.t(dijit.byId("sc"), "sc exists");
-							doh.is(dijit.byId("sc"), pane5._singleChild, "pane5._singleChild");
-						},
-						tearDown: function(t){
-							pane5.destroyRecursive();
-						}
+					tearDown: function(t){
+						pane5.destroyRecursive();
+					}
+				},
+				{
+					name: "mixed content",
+					setUp: function(t){
+						pane5 = new ContentPane({
+							content:
+								"<span>hello world</span>" +
+								"<div data-dojo-type='dijit/layout/StackContainer'></div>"
+						}).placeAt(document.body);
+						pane5.startup();
 					},
-					{
-						name: "script tags ignored",
-						setUp: function(t){
-							pane5 = new dijit.layout.ContentPane({
-								content:
-									"<scri" + "pt></scri" + "pt>" +
-									"<div data-dojo-type='dijit.layout.StackContainer' id='sc'></div>"
-							}, dojo.byId("pane5"));
-						},
-						runTest: function(t){
-							// script tag should be ignored, should be detected as single child
-							doh.t(pane5._singleChild, "script tag ignored, marked as single child");
-						},
-						tearDown: function(t){
-							pane5.destroyRecursive();
-						}
+					runTest: function(t){
+						// since there's plain HTML along with the widget, ContentPane shouldn't try to adjust
+						// this size of the widget (since that would cover up the other HTML)
+						doh.f(pane5._singleChild);
+					},
+					tearDown: function(t){
+						pane5.destroyRecursive();
 					}
-				]
-			);
-
-			dojo.declare("dijit.TestContained",
-				dijit.layout._LayoutWidget, {
-					startup: function(){
-						this.inherited(arguments);
-						this._started = true;
+				},
+				{
+					name: "two widgets",
+					setUp: function(t){
+						pane5 = new ContentPane({
+							content:
+								"<div data-dojo-type='dijit/layout/StackContainer'></div>" +
+								"<div data-dojo-type='dijit/layout/StackContainer'></div>"
+						}).placeAt(document.body);
+						pane5.startup();
 					},
-					resize: function(){
-						this.inherited(arguments);
-						this._resized = true;
+					runTest: function(t){
+						// since there are multiple children, neither should be marked
+						// for layout/resize along w/the ContentPane
+						doh.f(pane5._singleChild);
+					},
+					tearDown: function(t){
+						pane5.destroyRecursive();
+					}
+				},
+				{
+					name: "dojo.data",
+					setUp: function(t){
+						pane5 = new ContentPane({
+							content:
+								"<div data-dojo-type='dojo/data/ItemFileReadStore' data-dojo-id='dd'></div>" +
+								"<div data-dojo-type='dijit/layout/StackContainer' id='sc'></div>"
+						}).placeAt(document.body);
+						pane5.startup();
+					},
+					runTest: function(t){
+						// there are two children but one is invisible, so the other should be marked
+						// for layout/resize along w/the ContentPane
+						doh.t(dd, "dd exists");
+						doh.t(registry.byId("sc"), "sc exists");
+						doh.is(registry.byId("sc"), pane5._singleChild, "pane5._singleChild");
+					},
+					tearDown: function(t){
+						pane5.destroyRecursive();
+					}
+				},
+				{
+					name: "non-visual tags ignored",
+					setUp: function(t){
+						pane5 = new ContentPane({
+							content:
+								"<scri" + "pt></scri" + "pt>" +
+								"<link rel='stylesheet' href='../../themes/claro/claro.css'>" +
+								"<style>body { background: red; }</style>" +
+								"<div data-dojo-type='dijit/layout/StackContainer' id='sc'></div>"
+						}).placeAt(document.body);
+						pane5.startup();
+					},
+					runTest: function(t){
+						// <script> etc. tags should be ignored, <div> should be detected as single child
+						doh.t(pane5._singleChild, "script,link,style tags ignored, marked as single child");
+					},
+					tearDown: function(t){
+						pane5.destroyRecursive();
 					}
 				}
-			);
+			]);
+
+			declare("TestContained", _LayoutWidget, {
+				startup: function(){
+					this.inherited(arguments);
+					this._started = true;
+				},
+				resize: function(){
+					this.inherited(arguments);
+					this._resized = true;
+				}
+			});
 
 			var container;
-			doh.register("ContentPane as _Container-like widget",
-				[
-					{
-						name: "creation",
-						runTest: function(t){
-							container = new dijit.layout.ContentPane();
-							container.placeAt(dojo.body(), "last");
-							container.startup();
-							t.is(0, container.getChildren().length, "number of children before set('content', ...)");
-							container.set('content',
-								'<span>plain non-widget content</span>' +
-								'<div><span>' +
-									'<div id="zero" data-dojo-type="dijit.TestContained"></div>' +
-									'<div id="one" data-dojo-type="dijit.TestContained"></div>' +
-								'</span></div>' +
-								'<div id="two" data-dojo-type="dijit.TestContained"></div>' +
-								'<div id="three" data-dojo-type="dijit._Widget"></div>'
-							);
-
-							// Since ContentPane is a container it should call startup
-							// on it's children
-							t.t(dijit.byId('two')._started, "started");
-
-							// Also, Layout widgets expect resize() to be
-							// called by their parent
-							t.t(dijit.byId('two')._resized, "resized");
-						}
-					},
-					{
-						name: "getChildren",
-						runTest: function(t){
-							var children = container.getChildren();
-							t.is(4, children.length, "number of children");
-							t.is("zero", children[0].id);
-							t.is("one", children[1].id);
-							t.is("two", children[2].id);
-							t.is("three", children[3].id);
-						}
-					},
+			doh.register("ContentPane as _Container-like widget", [
+				{
+					name: "creation",
+					runTest: function(t){
+						container = new ContentPane();
+						container.placeAt(document.body, "last");
+						container.startup();
+						t.is(0, container.getChildren().length, "number of children before set('content', ...)");
+						container.set('content',
+							'<span>plain non-widget content</span>' +
+							'<div><span>' +
+								'<div id="zero" data-dojo-type="TestContained"></div>' +
+								'<div id="one" data-dojo-type="TestContained"></div>' +
+							'</span></div>' +
+							'<div id="two" data-dojo-type="TestContained"></div>' +
+							'<div id="three" data-dojo-type="dijit/_WidgetBase"></div>'
+						);
+
+						// Since ContentPane is a container it should call startup
+						// on it's children
+						t.t(registry.byId('two')._started, "started");
+
+						// Also, Layout widgets expect resize() to be
+						// called by their parent
+						t.t(registry.byId('two')._resized, "resized");
+					}
+				},
+				{
+					name: "getChildren",
+					runTest: function(t){
+						var children = container.getChildren();
+						t.is(4, children.length, "number of children");
+						t.is("zero", children[0].id);
+						t.is("one", children[1].id);
+						t.is("two", children[2].id);
+						t.is("three", children[3].id);
+					}
+				},
 
-					{
-						name: "deferred resize",
-						runTest: function(t){
-							// This tests that startup isn't called on the child widgets
-							// until the contentpane is made visible
-
-							var hiddenCP = new dijit.layout.ContentPane({style: {display: "none"}});
-							hiddenCP.placeAt(dojo.body(), "last");
-							hiddenCP.startup();
-
-							t.is(0, hiddenCP.getChildren().length, "number of children before set('content', ...)");
-							hiddenCP.set('content',
-								'<span>plain non-widget content</span>' +
-								'<div><span>' +
-									'<div id="deferredZero" data-dojo-type="dijit.TestContained"></div>' +
-									'<div id="deferredOne" data-dojo-type="dijit.TestContained"></div>' +
-								'</span></div>' +
-								'<div id="deferredTwo" data-dojo-type="dijit.TestContained"></div>' +
-								'<div id="deferredThree" data-dojo-type="dijit._Widget"></div>'
-							);
-
-							t.f(dijit.byId('deferredTwo')._resized, "not resized yet");
-
-							hiddenCP.set("style", {display: "block"});
-							hiddenCP._onShow();
-
-							t.t(dijit.byId('deferredTwo')._resized, "resized");
-						}
+				{
+					name: "deferred resize",
+					runTest: function(t){
+						// This tests that startup isn't called on the child widgets
+						// until the contentpane is made visible
+
+						var hiddenCP = new ContentPane({style: {display: "none"}});
+						hiddenCP.placeAt(document.body, "last");
+						hiddenCP.startup();
+
+						t.is(0, hiddenCP.getChildren().length, "number of children before set('content', ...)");
+						hiddenCP.set('content',
+							'<span>plain non-widget content</span>' +
+							'<div><span>' +
+								'<div id="deferredZero" data-dojo-type="TestContained"></div>' +
+								'<div id="deferredOne" data-dojo-type="TestContained"></div>' +
+							'</span></div>' +
+							'<div id="deferredTwo" data-dojo-type="TestContained"></div>' +
+							'<div id="deferredThree" data-dojo-type="dijit/_WidgetBase"></div>'
+						);
+
+						t.f(registry.byId('deferredTwo')._resized, "not resized yet");
+
+						hiddenCP.set("style", {display: "block"});
+						hiddenCP._onShow();
+
+						t.t(registry.byId('deferredTwo')._resized, "resized");
 					}
+				}
 
 /***
-					,
-					{
-						name: "addChild",
-						runTest: function(t){
-							var afterTwo = new dijit.TestContained({id: "twoPointFive"});
-							container.addChild(afterTwo, 3);
-
-							// Make sure child was added and is in order
-							var children = container.getChildren();
-							t.is(5, children.length);
-							t.is("zero", children[0].id);
-							t.is("one", children[1].id);
-							t.is("two", children[2].id);
-							t.is("twoPointFive", children[3].id);
-							t.is("three", children[4].id);
-
-							// Since ContentPane is a container it should call startup
-							// on it's children
-							t.t(afterTwo._started, "started");
-
-							// Also, Layout widgets expect resize() to be
-							// called by their parent
-							t.t(afterTwo._resized, "resized");
-						}
-					},
-					{
-						name: "removeChild",
-						runTest: function(t){
-							var children = container.getChildren();
-							t.is(5, children.length);
-							container.removeChild(dijit.byId("zero"));
-							container.removeChild(1); // should remove "two" - because zero is already removed
-							children = container.getChildren();
-							t.is(3, children.length);
-							t.is("one", children[0].id);
-							t.is("three", children[2].id);
-						}
+				,
+				{
+					name: "addChild",
+					runTest: function(t){
+						var afterTwo = new TestContained({id: "twoPointFive"});
+						container.addChild(afterTwo, 3);
+
+						// Make sure child was added and is in order
+						var children = container.getChildren();
+						t.is(5, children.length);
+						t.is("zero", children[0].id);
+						t.is("one", children[1].id);
+						t.is("two", children[2].id);
+						t.is("twoPointFive", children[3].id);
+						t.is("three", children[4].id);
+
+						// Since ContentPane is a container it should call startup
+						// on it's children
+						t.t(afterTwo._started, "started");
+
+						// Also, Layout widgets expect resize() to be
+						// called by their parent
+						t.t(afterTwo._resized, "resized");
 					}
+				},
+				{
+					name: "removeChild",
+					runTest: function(t){
+						var children = container.getChildren();
+						t.is(5, children.length);
+						container.removeChild(registry.byId("zero"));
+						container.removeChild(1); // should remove "two" - because zero is already removed
+						children = container.getChildren();
+						t.is(3, children.length);
+						t.is("one", children[0].id);
+						t.is("three", children[2].id);
+					}
+				}
 ****/
-				]
-			);
+			]);
 
 			// Test that popup widgets in a ContentPane are created and deleted correctly
 			doh.register("popup test", [
 				function create(){
-					dojo.parser.parse(dojo.byId("popupTest"));
-					doh.t(dijit.byId("popupPane"), "popup ContentPane created");
-					doh.t(dijit.byId("dialog"), "dialog created");
-					doh.is(dojo.body(), dijit.byId("dialog").domNode.parentNode, "dialog child of <body>");
+					parser.parse(dom.byId("popupTest"));
+					doh.t(registry.byId("popupPane"), "popup ContentPane created");
+					doh.t(registry.byId("dialog"), "dialog created");
+					doh.is(document.body, registry.byId("dialog").domNode.parentNode, "dialog child of <body>");
 				},
 				function destroy(){
-					dijit.byId("popupPane").destroyRecursive();
-					doh.f(dijit.byId("popupPane"), "popup ContentPane destroyed");
-					doh.f(dijit.byId("dialog"), "dialog widget destroyed");
-					doh.f(dojo.byId("dialog"), "dialog DOMNode gone too");
+					registry.byId("popupPane").destroyRecursive();
+					doh.f(registry.byId("popupPane"), "popup ContentPane destroyed");
+					doh.f(registry.byId("dialog"), "dialog widget destroyed");
+					doh.f(dom.byId("dialog"), "dialog DOMNode gone too");
 				}
 			]);
 
 			// Test that startup() on child widgets and plain JS objects is called at the correct time
 
-			var nwStartupCalls = 0;
-			dojo.declare("NonWidget", null, {
-				// summary: doesn't extend _Widget, used to test that startup() is still called
+			var nwStartupCalls = 0, nwDestroyCalls = 0;
+			declare("NonWidget", null, {
+				// summary:
+				//		Doesn't extend _WidgetBase.  Used to test that startup() is still called.
 				startup: function(){
 					if(!this._started){
 						nwStartupCalls++;
 						this._started = true;
 					}
+				},
+				destroyRecursive: function(){
+					nwDestroyCalls++;
 				}
 			});
 
 			doh.register("startup", [
 				function startupAfter(){
-					var cp1 = new dijit.layout.ContentPane({
-						content: "<div id='startup-c1' data-dojo-type='dijit.TestContained'></div>"
-					}).placeAt(dojo.body());
-					
-					var child = dijit.byId("startup-c1");
+					var cp1 = new ContentPane({
+						content: "<div id='startup-c1' data-dojo-type='TestContained'></div>"
+					}).placeAt(document.body);
+
+					var child = registry.byId("startup-c1");
 					doh.t(child, "child widget created");
 					doh.f(child._started, "child widget not started yet");
-					
+
 					cp1.startup();
-					
+
 					doh.t(child._started, "starting ContentPane starts child widget");
 				},
 				function startupBefore(){
-					var cp2 = new dijit.layout.ContentPane({}).placeAt(dojo.body());
+					var cp2 = new ContentPane({}).placeAt(document.body);
 					cp2.startup();
-					
-					cp2.set("content", "<div id='startup-c2' data-dojo-type='dijit.TestContained'></div>");
-					var child = dijit.byId("startup-c2");
+
+					cp2.set("content", "<div id='startup-c2' data-dojo-type='TestContained'></div>");
+					var child = registry.byId("startup-c2");
 					doh.t(child, "child widget created");
 					doh.t(child._started, "child widget started");
-				},
+				}
+			]);
 
-				function nonWidget(){
+			// Tests for when ContentPane contains objects not descended from _WidgetBase,
+			// like dojo.Dnd.Source
+			doh.register("non widget", [
+				function startupAndDestroy(){
 					// even non-widgets inside of ContentPane (like dojo.dnd.Source) should have
 					// startup called on them
-					dojo.parser.parse(dojo.byId("nonWidgetTest"));
+					parser.parse(dom.byId("nonWidgetTest"));
 					doh.is(1, nwStartupCalls, "startup() on non-widgets called on parse");
 
 					nwp.set("content", "<div><div data-dojo-type='NonWidget' data-dojo-id='nw2'></div></div>");
 					doh.is(2, nwStartupCalls, "startup() called on non-widgets via set(content, ...)");
+					doh.is(1, nwDestroyCalls, "resetting the ContentPane content destroyed the old non-widget content");
+
+					// And also check that destroying ContentPane destroys the non-widget
+					nwp.destroyRecursive();
+					doh.is(2, nwDestroyCalls, "destroying ContentPane destroyed NonWidget content");
 				}
 			]);
 
@@ -494,40 +511,39 @@
 		});
 	</script>
 </head>
-<body class="claro">
-	<h2>dijit.layout.ContentPane DOH test</h2>
+<body class="claro" role="main">
+	<h2>dijit/layout/ContentPane DOH test</h2>
 	<h3>Test designed to run on localhost (minimize impact from network latency)</h3>
 
 	<h4>This should NOT be parsed automatically</h4>
-	<div id="pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
-		<div data-dojo-type='dijit.TestWidget'>If this has a different background and a red border, the page parsed when it shouldn't</div>
+	<div id="pane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"box"'>
+		<div data-dojo-type='TestWidget'>If this has a different background and a red border, the page parsed when it shouldn't</div>
 	</div>
 	<br/><h3>Testing ContentPane</h3>
 	<div id='pane2' class='box'>
 		Even though the entire page isn't scanned for widgets,
 		any sub widgets of a ContentPane will be created when a ContentPane is created<br/>
-		<span id="2_zero" data-dojo-type='dijit.TestWidget'>This should have a backgroundcolor and a border</span>
-		<div id="2_one" data-dojo-type="dijit._Widget"></div>
-		<div id="2_two" data-dojo-type="dijit._Widget"></div>
-		<div id="2_three" data-dojo-type="dijit._Widget"></div>
+		<span id="2_zero" data-dojo-type='TestWidget'>This should have a backgroundcolor and a border</span>
+		<div id="2_one" data-dojo-type="dijit/_WidgetBase"></div>
+		<div id="2_two" data-dojo-type="dijit/_WidgetBase"></div>
+		<div id="2_three" data-dojo-type="dijit/_WidgetBase"></div>
 	</div>
 	<br/><br/>
-	<div id="pane5"></div>
 
 	<!-- for container tests -->
-	<div id="container" data-dojo-type="dijit.layout.ContentPane">
-		<div id="zero" data-dojo-type="dijit.TestContained"></div>
-		<div id="one" data-dojo-type="dijit.TestContained"></div>
-		<div id="two" data-dojo-type="dijit.TestContained"></div>
-		<div id="three" data-dojo-type="dijit._Widget"></div>
+	<div id="container" data-dojo-type="dijit/layout/ContentPane">
+		<div id="zero" data-dojo-type="TestContained"></div>
+		<div id="one" data-dojo-type="TestContained"></div>
+		<div id="two" data-dojo-type="TestContained"></div>
+		<div id="three" data-dojo-type="dijit/_WidgetBase"></div>
 	</div>
-	<div id="outside" data-dojo-type="dijit._Widget"></div>
-	<div id="outsideCont" data-dojo-type="dijit.TestContained"></div>
+	<div id="outside" data-dojo-type="dijit/_WidgetBase"></div>
+	<div id="outsideCont" data-dojo-type="TestContained"></div>
 
 	<!-- for testing popup widgets inside of a content pane -->
 	<div id="popupTest">
-		<div id="popupPane" data-dojo-type="dijit.layout.ContentPane">
-			<div id="dialog" data-dojo-type="dijit.Dialog">
+		<div id="popupPane" data-dojo-type="dijit/layout/ContentPane">
+			<div id="dialog" data-dojo-type="dijit/Dialog">
 				hello world
 			</div>
 		</div>
@@ -535,7 +551,7 @@
 
 	<!-- for testing non-widgets inside of a content pane -->
 	<div id="nonWidgetTest">
-		<div id="nonWidgetPane" data-dojo-type="dijit.layout.ContentPane" data-dojo-id="nwp">
+		<div id="nonWidgetPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-id="nwp">
 			<div data-dojo-type="NonWidget" data-dojo-id="nw1"></div>
 		</div>
 	</div>
diff --git a/dijit/tests/layout/ContentPaneLayout.html b/dijit/tests/layout/ContentPaneLayout.html
index bd5c205..4752cdf 100644
--- a/dijit/tests/layout/ContentPaneLayout.html
+++ b/dijit/tests/layout/ContentPaneLayout.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>ContentPane layout-related DOH test</title>
@@ -18,36 +18,41 @@
 		data-dojo-config="isDebug: true"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojo.parser");
-
-		dojo.require("dijit._Widget");
-		dojo.require("dijit._TemplatedMixin");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.TitlePane");
-		dojo.require("dijit.form.Form");
-		dojo.require("dijit.Dialog");
-
-		// widgets used in doc loaded via href
-		dojo.require("dijit.form.ComboBox");
-		dojo.require("dijit.form.Button");
-
-		// Keep track of which panes have had a load event, and how
-		// many load events have occurred for those panes
-		var loadEvents = {
-		};
-		function myOnLoad(){
-			console.log("onload for " + this);
-			loadEvents[this.id] = (loadEvents[this.id] || 0) + 1;
-		}
-
-		dojo.ready(function(){
+		require([
+			"doh/runner",
+			"dojo/_base/array",
+			"dojo/aspect",
+			"dojo/_base/declare",
+			"dojo/dom-geometry",
+			"dojo/store/Memory",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/_WidgetBase",
+			"dijit/_TemplatedMixin",
+			"dijit/Dialog",
+			"dijit/form/ComboBox",
+			"dijit/form/Form",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/layout/_LayoutWidget",
+			"dijit/layout/TabContainer",
+			"dijit/TitlePane",
+			"dojo/domReady!"
+		], function(doh, array, aspect, declare, domGeom, Memory, parser,
+				registry, _WidgetBase, _TemplatedMixin,
+				Dialog, Form, BorderContainer, ContentPane, _LayoutWidget, TabContainer, TitlePane){
+
+			// Keep track of which panes have had a load event, and how
+			// many load events have occurred for those panes
+			var loadEvents = {
+			};
+			myOnLoad = function(){
+				console.log("onload for " + this);
+				loadEvents[this.id] = (loadEvents[this.id] || 0) + 1;
+			};
 
 			// create a do nothing, only for test widget
-			dojo.declare("ResizableWidget",
-				[dijit._Widget, dijit._TemplatedMixin], {
+			declare("ResizableWidget", [_WidgetBase, _TemplatedMixin], {
 				templateString: "<span class='dijitInline resizableWidget'>resizable widget</span>",
 				_resized: 0,
 				_resizeArgs: null,
@@ -65,20 +70,39 @@
 					this._resized++;
 					this._resizeArgs = arguments;
 					if(newSize){
-						dojo.marginBox(this.domNode, newSize);
+						domGeom.setMarginBox(this.domNode, newSize);
 					}
 				}
 			});
-	
-			// Keep track of the number of startup() calls to every widget.
-			// Since the href's widgets haven't been created yet we monitor startup() calls on the prototype
+
+			// Monitor lifecycle of widgets.  This used to be done by attaching to _WidgetBase.prototype and
+			// _LayoutWidget.prototype, but that leads to race conditions since declare() runs first, and looks
+			// at the original methods, not the advised-methods.
 			var startups = {};
-			dojo.connect(dijit._Widget.prototype, "startup", function(){
-				startups[this.id] = (startups[this.id] || 0) + 1;
-			});
+			var layoutResizes = {};
+			aspect.after(registry, "add", function(widget){
+				// Keep track of the number of startup() calls to every widget.
+				// Since the href's widgets haven't been created yet we monitor startup() calls on the prototype
+				aspect.after(widget, "startup", function(){
+					startups[widget.id] = (startups[widget.id] || 0) + 1;
+				}, true);
+
+				// Keep track of which layout widgets each resize call to each layout widget,
+				// specifically whether each call specified a size or not.
+				// Since the href's widgets haven't been created yet we can't connect to their resize()
+				// methods, but we can monitor resize() on the prototype
+				aspect.after(widget, "resize", function(){
+					// this is the pointer to the widget, and arguments are newsize/curSize args to resize()
+					var ary = layoutResizes[widget.id];
+					if(!ary){
+						ary = layoutResizes[widget.id] = [];
+					}
+					ary.push(arguments);
+				}, true);
+			}, true);
 
 			doh.register("parse", function(){
-				dojo.parser.parse();
+				return parser.parse();
 			});
 
 			// Test that ContentPanes calls startup() on child widgets appropriately
@@ -91,7 +115,7 @@
 						var d = new doh.Deferred();
 						// Wait for load events to occur (after fetching URL's)
 						setTimeout(d.getTestCallback(function(){
-							var pane1 = dijit.byId("pane1"),
+							var pane1 = registry.byId("pane1"),
 								children = pane1.getChildren();
 							doh.is(2, children.length, "found combobox and button");
 							doh.is(1, startups[children[0].id], "combobox started once");
@@ -106,572 +130,579 @@
 			);
 
 			// Test that ContentPanes defer their load until they are shown
-			doh.register("load events",
-				[
-					{
-						name: "initial conditions",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-							// Wait for load events to occur (after fetching URL's)
-							setTimeout(d.getTestCallback(function(){
-								doh.is(1, loadEvents.pane1, "pane1");
-								dojo.forEach(["pane2", "innerPane1", "innerPane2", "bcPane1", "bcPane2"], function(pane){
-									doh.f(loadEvents[pane], pane, pane + " shouldn't be loaded");
-								});
-							}), 4000);
-							return d;
-						}
-					},
-					{
-						name: "reset href in hidden pane, pane2",
-						timeout: 2000,
-						runTest: function(t){
-							// Resetting an href on a hidden pane should have no effect
-							var d = new doh.Deferred();
-
-							dijit.byId("pane2").set("href", "doc0.html");
-							setTimeout(d.getTestCallback(function(){
-								doh.f(loadEvents.pane2, "pane2 shouldn't be loaded");
-							}), 750);
-
-							return d;
-						}
-					},
-					{
-						name: "reset href in hidden pane, innerPane1",
-						timeout: 2000,
-						runTest: function(t){
-							// Resetting an href on a hidden pane should have no effect
-							var d = new doh.Deferred();
-
-							dijit.byId("innerPane1").set("href", "doc1.html");
-							setTimeout(d.getTestCallback(function(){
-								doh.f(loadEvents.innerPane1, "innerPane1 shouldn't be loaded");
-							}), 750);
-
-							return d;
-						}
-					},
-					{
-						name: "reset href in hidden pane, bcPane2",
-						timeout: 2000,
-						runTest: function(t){
-							// Resetting an href on a hidden pane should have no effect
-							var d = new doh.Deferred();
-
-							dijit.byId("bcPane2").set("href", "doc0.html");
-							setTimeout(d.getTestCallback(function(){
-								doh.f(loadEvents.bcPane2, "bcPane2 shouldn't be loaded");
-							}), 750);
-
-							return d;
-						}
-					},
-					{
-						name: "selecting ContentPane causes it to load",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							dijit.byId("outerTC").selectChild(dijit.byId("pane2"));
-							setTimeout(d.getTestCallback(function(){
-								doh.is(1, loadEvents.pane2, "pane2");
-							}), 4000);
-
-							return d;
-						}
-					},
-					{
-						name: "selecting a TabContainer causes it's selected child to load",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.f(loadEvents.innerPane1, "innerPane1 not loaded yet");
-							dijit.byId("outerTC").selectChild(dijit.byId("innerTC"));
-							setTimeout(d.getTestCallback(function(){
-								doh.is(1, loadEvents.innerPane1, "innerPane1 now loaded");
-							}), 4000);
-
-							return d;
-						}
-					},
-					{
-						name: "selecting a BorderContainer causes it's children to load",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
+			doh.register("load events", [
+				{
+					name: "initial conditions",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+						// Wait for load events to occur (after fetching URL's)
+						setTimeout(d.getTestCallback(function(){
+							doh.is(1, loadEvents.pane1, "pane1");
+							array.forEach(["pane2", "innerPane1", "innerPane2", "bcPane1", "bcPane2"], function(pane){
+								doh.f(loadEvents[pane], pane, pane + " shouldn't be loaded");
+							});
+						}), 4000);
+						return d;
+					}
+				},
+				{
+					name: "reset href in hidden pane, pane2",
+					timeout: 2000,
+					runTest: function(t){
+						// Resetting an href on a hidden pane should have no effect
+						var d = new doh.Deferred();
 
-							//doh.f(loadEvents.bcPane1, "bcPane1 not loaded");
-							//doh.f(loadEvents.bcPane2, "bcPane2 not loaded");
+						registry.byId("pane2").set("href", "doc0.html");
+						setTimeout(d.getTestCallback(function(){
+							doh.f(loadEvents.pane2, "pane2 shouldn't be loaded");
+						}), 750);
 
-							dijit.byId("outerTC").selectChild(dijit.byId("bc"));
+						return d;
+					}
+				},
+				{
+					name: "reset href in hidden pane, innerPane1",
+					timeout: 2000,
+					runTest: function(t){
+						// Resetting an href on a hidden pane should have no effect
+						var d = new doh.Deferred();
 
-							setTimeout(d.getTestCallback(function(){
-								doh.is(1, loadEvents.bcPane1, "bcPane1");
-								doh.is(1, loadEvents.bcPane2, "bcPane2");
-							}), 4000);
+						registry.byId("innerPane1").set("href", "doc1.html");
+						setTimeout(d.getTestCallback(function(){
+							doh.f(loadEvents.innerPane1, "innerPane1 shouldn't be loaded");
+						}), 750);
 
-							return d;
-						}
+						return d;
 					}
-				]
-			);
+				},
+				{
+					name: "reset href in hidden pane, bcPane2",
+					timeout: 2000,
+					runTest: function(t){
+						// Resetting an href on a hidden pane should have no effect
+						var d = new doh.Deferred();
 
-			// Keep track of which layout widgets each resize call to each layout widget,
-			// specifically whether each call specified a size or not.
-			// Since the href's widgets haven't been created yet we can't connect to their resize()
-			// methods, but we can monitor resize() on the prototype
-			var layoutResizes = {};
-			dojo.connect(dijit.layout._LayoutWidget.prototype, "resize", function(){
-				// this is the pointer to the widget, and arguments are newsize/curSize args to resize()
-				var ary = layoutResizes[this.id];
-				if(!ary){
-					ary = layoutResizes[this.id] = [];
+						registry.byId("bcPane2").set("href", "doc0.html");
+						setTimeout(d.getTestCallback(function(){
+							doh.f(loadEvents.bcPane2, "bcPane2 shouldn't be loaded");
+						}), 750);
+
+						return d;
+					}
+				},
+				{
+					name: "selecting ContentPane causes it to load",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						registry.byId("outerTC").selectChild(registry.byId("pane2"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is(1, loadEvents.pane2, "pane2");
+						}), 4000);
+
+						return d;
+					}
+				},
+				{
+					name: "selecting a TabContainer causes it's selected child to load",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						doh.f(loadEvents.innerPane1, "innerPane1 not loaded yet");
+						registry.byId("outerTC").selectChild(registry.byId("innerTC"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is(1, loadEvents.innerPane1, "innerPane1 now loaded");
+						}), 4000);
+
+						return d;
+					}
+				},
+				{
+					name: "selecting a BorderContainer causes it's children to load",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						//doh.f(loadEvents.bcPane1, "bcPane1 not loaded");
+						//doh.f(loadEvents.bcPane2, "bcPane2 not loaded");
+
+						registry.byId("outerTC").selectChild(registry.byId("bc"));
+
+						setTimeout(d.getTestCallback(function(){
+							doh.is(1, loadEvents.bcPane1, "bcPane1");
+							doh.is(1, loadEvents.bcPane2, "bcPane2");
+						}), 4000);
+
+						return d;
+					}
 				}
-				ary.push(arguments);
-			});
+			]);
+
+			doh.register("resize events", [
+				// Test that when ContentPane w/single resizable child is shown,
+				// the child is sized to match the ContentPane
+				{
+					name: "single child",
+					runTest: function(t){
+						var child = registry.byId("singleChildResizable");
+						doh.is(0, child._resized, "hasn't been shown yet so no resize events");
+
+						registry.byId("resizeTC").selectChild(registry.byId("singleChildPane"));
+
+						doh.t(child._resized, "got resize event");	// note: should only be 1 but currently gets 2
+						doh.t(child._resizeArgs && child._resizeArgs.length, "got size specified");
+
+						var size = child._resizeArgs[0];
+						doh.t(size && size.h, "non-0 height specified");
+						doh.t(size && size.w, "non-0 width specified");
+					}
+				},
+				// Test that when ContentPane w/multiple resizable children is shown,
+				// the children aren't sized to match the ContentPane, but we do call
+				// resize on them so they can lay themselves out
+				{
+					name: "multiple children",
+					runTest: function(t){
+						var child1 = registry.byId("multipleChildResizable1"),
+							child2 = registry.byId("multipleChildResizable2");
+
+						doh.is(0, child1._resized, "child1 hasn't been shown yet so no resize events");
+						doh.is(0, child2._resized, "child2 hasn't been shown yet so no resize events");
+
+						registry.byId("resizeTC").selectChild(registry.byId("multipleChildPanes"));
+
+						doh.t(child1._resized, "got resize event for child1");
+						doh.is(0, child1._resizeArgs && child1._resizeArgs.length, "no size specified for child1");
+						doh.t(child2._resized, "got resize event for child2");
+						doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2")
+					}
+				},
+
+				{
+					name: "single resizable widget, plus invisible widget",
+					runTest: function(t){
+						var child = registry.byId("fss2_rc");
+						doh.t(child._resized, "got resize event for child");
+						doh.is(1, child._resizeArgs && child._resizeArgs.length, "size specified");
+						doh.is("fss2_rc", registry.byId("fss2")._singleChild.id, "the resizable child memoed")
+					}
+				},
+
+				{
+					name: "multiple resizable widgets in form with size",
+					runTest: function(t){
+						var child1 = registry.byId("fsmc1"),
+							child2 = registry.byId("fsmc2");
+
+						doh.t(child1._resized, "got resize event for child1");
+						doh.is(0, child1._resizeArgs && child1._resizeArgs.length, "no size specified for child1");
+						doh.t(child2._resized, "got resize event for child2");
+						doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2");
+					}
+				},
+				{
+					name: "single resizable widget, single non-resizable (but visible) widget",
+					runTest: function(t){
+						var child = registry.byId("fsm2_rc");
+						doh.t(child._resized, "got resize event for child");
+						doh.is(0, child._resizeArgs && child._resizeArgs.length, "no size specified for child");
+					}
+				},
 
-			doh.register("resize events",
-				[
-					// Test that when ContentPane w/single resizable child is shown,
-					// the child is sized to match the ContentPane
-					{
-						name: "single child",
-						runTest: function(t){
-							var child = dijit.byId("singleChildResizable");
-							doh.is(0, child._resized, "hasn't been shown yet so no resize events");
+				// Test that resize event works correctly for href w/single layout widget
+				{
+					name: "single resizable href",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
 
-							dijit.byId("resizeTC").selectChild(dijit.byId("singleChildPane"));
+						registry.byId("resizeTC").selectChild(registry.byId("singleChildHref"));
 
-							doh.t(child._resized, "got resize event");	// note: should only be 1 but currently gets 2
-							doh.t(child._resizeArgs && child._resizeArgs.length, "got size specified");
+						// Wait for load events to occur (after fetching URL's)
+						setTimeout(d.getTestCallback(function(){
+							// Check top level border container got sized to fit ContentPane
+							var child = registry.byId("singleChildHrefBorderContainer");
+							doh.t(child, "href was loaded and top level BorderContainer was created");
+							doh.t(layoutResizes["singleChildHrefBorderContainer"], "got resize event");
+							doh.t(layoutResizes["singleChildHrefBorderContainer"][0].length, "got size specified");
 
-							var size = child._resizeArgs[0];
+							var size = layoutResizes["singleChildHrefBorderContainer"][0][0];
 							doh.t(size && size.h, "non-0 height specified");
 							doh.t(size && size.w, "non-0 width specified");
-						}
-					},
-					// Test that when ContentPane w/multiple resizable children is shown,
-					// the children aren't sized to match the ContentPane, but we do call
-					// resize on them so they can lay themselves out
-					{
-						name: "multiple children",
-						runTest: function(t){
-							var child1 = dijit.byId("multipleChildResizable1"),
-								child2 = dijit.byId("multipleChildResizable2");
-
-							doh.is(0, child1._resized, "child1 hasn't been shown yet so no resize events");
-							doh.is(0, child2._resized, "child2 hasn't been shown yet so no resize events");
-
-							dijit.byId("resizeTC").selectChild(dijit.byId("multipleChildPanes"));
-
-							doh.t(child1._resized, "got resize event for child1");
-							doh.is(0, child1._resizeArgs && child1._resizeArgs.length, "no size specified for child1");
-							doh.t(child2._resized, "got resize event for child2");
-							doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2")
-						}
-					},
 
-					// Test that resize event works correctly for href w/single layout widget
-					{
-						name: "single resizable href",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							dijit.byId("resizeTC").selectChild(dijit.byId("singleChildHref"));
-
-							// Wait for load events to occur (after fetching URL's)
-							setTimeout(d.getTestCallback(function(){
-								// Check top level border container got sized to fit ContentPane
-								var child = dijit.byId("singleChildHrefBorderContainer");
-								doh.t(child, "href was loaded and top level BorderContainer was created");
-								doh.t(layoutResizes["singleChildHrefBorderContainer"], "got resize event");
-								doh.t(layoutResizes["singleChildHrefBorderContainer"][0].length, "got size specified");
-
-								var size = layoutResizes["singleChildHrefBorderContainer"][0][0];
-								doh.t(size && size.h, "non-0 height specified");
-								doh.t(size && size.w, "non-0 width specified");
-
-								// Check that resize() events also trickled down to inner TabContainer
-								var child2 = dijit.byId("singleChildHrefInnerTabContainer");
-								doh.t(child2, "inner TabContainer was created");
-								doh.t(layoutResizes["singleChildHrefInnerTabContainer"], "got resize event");
-								doh.is(0, layoutResizes["singleChildHrefInnerTabContainer"][0].length, "no size specified")
-							}), 4000);
-							return d;
-						}
-					},
+							// Check that resize() events also trickled down to inner TabContainer
+							var child2 = registry.byId("singleChildHrefInnerTabContainer");
+							doh.t(child2, "inner TabContainer was created");
+							doh.t(layoutResizes["singleChildHrefInnerTabContainer"], "got resize event");
+							doh.is(0, layoutResizes["singleChildHrefInnerTabContainer"][0].length, "no size specified")
+						}), 4000);
+						return d;
+					}
+				},
 
-					// Test that resize event works correctly for href w/multiple layout widgets
-					{
-						name: "multiple resizable href",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							dijit.byId("resizeTC").selectChild(dijit.byId("multipleChildHref"));
-
-							// Wait for load events to occur (after fetching URL's)
-							setTimeout(d.getTestCallback(function(){
-								// Check that resize() done on TabContainer
-								var child = dijit.byId("multipleChildHrefTabContainer");
-								doh.t(child, "TabContainer was created");
-								doh.t(layoutResizes["multipleChildHrefTabContainer"], "got resize event");
-								doh.is(0, layoutResizes["multipleChildHrefTabContainer"][0].length, "no size specified")
-							}), 4000);
-							return d;
-						}
-					},
+				// Test that resize event works correctly for href w/multiple layout widgets
+				{
+					name: "multiple resizable href",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
 
-					// Test that resize() is called on resizable children hidden inside of a form widget
-					// where the form widget is inside a layout container
-					{
-						name: "multiple resizable elements hidden in form in TabContainer",
-						runTest: function(t){
-							var child1 = dijit.byId("resizableInForm1"),
-								child2 = dijit.byId("resizableInForm2");
-
-							doh.is(0, child1._resized, "child1 hasn't been shown yet so no resize events");
-							doh.is(1, child1.history.length, "child1 # of history events (before show)");
-							doh.is("started", child1.history[0], "child1 history");
-
-							doh.is(0, child2._resized, "child2 hasn't been shown yet so no resize events");
-							doh.is(1, child1.history.length, "child2 # of history events (before show)");
-							doh.is("started", child2.history[0], "child2 history");
-
-							dijit.byId("resizeTC").selectChild(dijit.byId("multipleResizableInForm"));
-
-							doh.t(child1._resized, "got resize event for child1");
-							doh.is(0, child1._resizeArgs && child1._resizeArgs.length, "no size specified for child1");
-							doh.t(child2._resized, "got resize event for child2");
-							doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2")
-						}
-					},
+						registry.byId("resizeTC").selectChild(registry.byId("multipleChildHref"));
 
-					{
-						name: "single resizable element hidden in form in TabContainer",
-						runTest: function(t){
-							var child = dijit.byId("resizableInForm0");
+						// Wait for load events to occur (after fetching URL's)
+						setTimeout(d.getTestCallback(function(){
+							// Check that resize() done on TabContainer
+							var child = registry.byId("multipleChildHrefTabContainer");
+							doh.t(child, "TabContainer was created");
+							doh.t(layoutResizes["multipleChildHrefTabContainer"], "got resize event");
+							doh.is(0, layoutResizes["multipleChildHrefTabContainer"][0].length, "no size specified")
+						}), 4000);
+						return d;
+					}
+				},
 
-							doh.is(0, child._resized, "child hasn't been shown yet so no resize events");
-							doh.is(1, child.history.length, "child # of history events (before show)");
-							doh.is("started", child.history[0], "child history");
+				// Test that resize() is called on resizable children hidden inside of a form widget
+				// where the form widget is inside a layout container
+				{
+					name: "multiple resizable elements hidden in form in TabContainer",
+					runTest: function(t){
+						var child1 = registry.byId("resizableInForm1"),
+							child2 = registry.byId("resizableInForm2");
 
-							dijit.byId("resizeTC").selectChild(dijit.byId("singleResizableInForm"));
+						doh.is(0, child1._resized, "child1 hasn't been shown yet so no resize events");
+						doh.is(1, child1.history.length, "child1 # of history events (before show)");
+						doh.is("started", child1.history[0], "child1 history");
 
-							doh.t(child._resized, "got resize event for child");
-							doh.is(1, child._resizeArgs && child._resizeArgs.length, "size specified")
-						}
-					},
+						doh.is(0, child2._resized, "child2 hasn't been shown yet so no resize events");
+						doh.is(1, child1.history.length, "child2 # of history events (before show)");
+						doh.is("started", child2.history[0], "child2 history");
 
-					// Test that form where parent *isn't* a layout container calls startup() and resize()
-					// on it's child layout widgets
-					{
-						name: "single resizable element in form with size",
-						runTest: function(t){
-							var child = dijit.byId("fssc");
-							doh.t(child._resized, "got resize event for child");
-							doh.is(1, child._resizeArgs && child._resizeArgs.length, "size specified")
-						}
-					},
-					
-					{
-						name: "multiple resizable elements in form with size",
-						runTest: function(t){
-							var child1 = dijit.byId("fsmc1"),
-								child2 = dijit.byId("fsmc2");
-
-							doh.t(child1._resized, "got resize event for child1");
-							doh.is(0, child1._resizeArgs && child1._resizeArgs.length, "no size specified for child1");
-							doh.t(child2._resized, "got resize event for child2");
-							doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2")
-						}
-					},
+						registry.byId("resizeTC").selectChild(registry.byId("multipleResizableInForm"));
 
-					{
-						name: "single resizable elements in form with no size, doLayout=false",
-						runTest: function(t){
-							var child = dijit.byId("fnsc");
+						doh.t(child1._resized, "got resize event for child1");
+						doh.is(0, child1._resizeArgs && child1._resizeArgs.length, "no size specified for child1");
+						doh.t(child2._resized, "got resize event for child2");
+						doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2")
+					}
+				},
 
-							doh.t(child._resized, "got resize event for child");
-							doh.is(0, child._resizeArgs && child._resizeArgs.length, "no size specified for child")
-						}
-					},
+				{
+					name: "single resizable element hidden in form in TabContainer",
+					runTest: function(t){
+						var child = registry.byId("resizableInForm0");
+
+						doh.is(0, child._resized, "child hasn't been shown yet so no resize events");
+						doh.is(1, child.history.length, "child # of history events (before show)");
+						doh.is("started", child.history[0], "child history");
 
-					{
-						name: "multiple resizable elements in form with no size",
-						runTest: function(t){
-							var child1 = dijit.byId("fnmc1"),
-								child2 = dijit.byId("fnmc2");
+						registry.byId("resizeTC").selectChild(registry.byId("singleResizableInForm"));
 
-							doh.t(child1._resized, "got resize event for child1");
-							doh.is(0, child1._resizeArgs && child1._resizeArgs.length, "no size specified for child1");
-							doh.t(child2._resized, "got resize event for child2");
-							doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2")
-						}
+						doh.t(child._resized, "got resize event for child");
+						doh.is(1, child._resizeArgs && child._resizeArgs.length, "size specified")
 					}
-				]
-			);
+				},
+
+				// Test that form where parent *isn't* a layout container calls startup() and resize()
+				// on it's child layout widgets
+				{
+					name: "single resizable element in form with size",
+					runTest: function(t){
+						var child = registry.byId("fssc");
+						doh.t(child._resized, "got resize event for child");
+						doh.is(1, child._resizeArgs && child._resizeArgs.length, "size specified")
+					}
+				},
+
+				{
+					name: "multiple resizable elements in form with size",
+					runTest: function(t){
+						var child1 = registry.byId("fsmc1"),
+							child2 = registry.byId("fsmc2");
+
+						doh.t(child1._resized, "got resize event for child1");
+						doh.is(0, child1._resizeArgs && child1._resizeArgs.length, "no size specified for child1");
+						doh.t(child2._resized, "got resize event for child2");
+						doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2")
+					}
+				},
+
+				{
+					name: "single resizable elements in form with no size, doLayout=false",
+					runTest: function(t){
+						var child = registry.byId("fnsc");
+
+						doh.t(child._resized, "got resize event for child");
+						doh.is(0, child._resizeArgs && child._resizeArgs.length, "no size specified for child")
+					}
+				},
+
+				{
+					name: "multiple resizable elements in form with no size",
+					runTest: function(t){
+						var child1 = registry.byId("fnmc1"),
+							child2 = registry.byId("fnmc2");
+
+						doh.t(child1._resized, "got resize event for child1");
+						doh.is(0, child1._resizeArgs && child1._resizeArgs.length, "no size specified for child1");
+						doh.t(child2._resized, "got resize event for child2");
+						doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2")
+					}
+				}
+			]);
 
 			// Make sure that TitlePane loads it's href at the appropriate time, and also that
 			// it calls resize on it's children at the appropriate time (since that's the contract
 			// for layout widgets, and ContentPane is acting as a layout widget).
-			doh.register("TitlePane",
-				[
-				/***
-				 * test for #8197, uncomment when it's fixed.
-					{
-						name: "initially open, single child",
-						timeout: 2000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							var tp = dijit.byId("otpHsc");
-
-							// Allow time for href to load
-							setTimeout(d.getTestCallback(function(){
-								// Check that href loaded
-								doh.is(1, loadEvents["otpHsc"], "otpHsc loaded on page load");
-
-								// Check that resize() done on child
-								doh.t(layoutResizes["otpHscBorderContainer"], "got resize event");
-								doh.is(0, layoutResizes["otpHscBorderContainer"][0].length, "no size specified")
-							}), 750);
-
-							return d;
-						}
-					},
-				  */
-					{
-						name: "initially open, href multiple children",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							var tp = dijit.byId("otpHmc");
-
-							// Allow time for href to load
-							setTimeout(d.getTestCallback(function(){
-								// Check that href loaded
-								doh.is(1, loadEvents["otpHmc"], "otpHmc loaded on page load");
-
-								// Check that resize() done on children
-								doh.t(layoutResizes["otpHmcBorderContainer"], "got resize event for BC");
-								doh.t(layoutResizes["otpHmcTabContainer"], "got resize event for TC");
-								doh.is(0, layoutResizes["otpHmcBorderContainer"][0].length, "no size specified for BC")
-							}), 4000);
-
-							return d;
-						}
-					},
+			doh.register("TitlePane", [
+			/***
+			 * test for #8197, uncomment when it's fixed.
+				{
+					name: "initially open, single child",
+					timeout: 2000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						var tp = registry.byId("otpHsc");
+
+						// Allow time for href to load
+						setTimeout(d.getTestCallback(function(){
+							// Check that href loaded
+							doh.is(1, loadEvents["otpHsc"], "otpHsc loaded on page load");
 
-					{
-						name: "initially open, multiple children",
-						runTest: function(t){
-							var tp = dijit.byId("otpMc");
+							// Check that resize() done on child
+							doh.t(layoutResizes["otpHscBorderContainer"], "got resize event");
+							doh.is(0, layoutResizes["otpHscBorderContainer"][0].length, "no size specified")
+						}), 750);
+
+						return d;
+					}
+				},
+			  */
+				{
+					name: "initially open, href multiple children",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						var tp = registry.byId("otpHmc");
+
+						// Allow time for href to load
+						setTimeout(d.getTestCallback(function(){
+							// Check that href loaded
+							doh.is(1, loadEvents["otpHmc"], "otpHmc loaded on page load");
 
 							// Check that resize() done on children
-							doh.t(dijit.byId("otpMc_child1")._resized, "got resize event for child1");
-							doh.t(dijit.byId("otpMc_child2")._resized, "got resize event for child2");
-						}
-					},
+							doh.t(layoutResizes["otpHmcBorderContainer"], "got resize event for BC");
+							doh.t(layoutResizes["otpHmcTabContainer"], "got resize event for TC");
+							doh.is(0, layoutResizes["otpHmcBorderContainer"][0].length, "no size specified for BC")
+						}), 4000);
+
+						return d;
+					}
+				},
+
+				{
+					name: "initially open, multiple children",
+					runTest: function(t){
+						var tp = registry.byId("otpMc");
+
+						// Check that resize() done on children
+						doh.t(registry.byId("otpMc_child1")._resized, "got resize event for child1");
+						doh.t(registry.byId("otpMc_child2")._resized, "got resize event for child2");
+					}
+				},
 
-					{
-						name: "initially closed, href multiple children",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
+				{
+					name: "initially closed, href multiple children",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
 
-							doh.f(loadEvents["ctpHmc"], "ctpHmc load deferred until open");
+						doh.f(loadEvents["ctpHmc"], "ctpHmc load deferred until open");
 
-							var tp = dijit.byId("ctpHmc");
-							tp.set("open", true);
+						var tp = registry.byId("ctpHmc");
+						tp.set("open", true);
 
-							// Allow time for href to load, pane to expand, and resize to be called on children
-							setTimeout(d.getTestCallback(function(){
-								// Check that href loaded
-								doh.is(1, loadEvents["ctpHmc"], "ctpHmc loaded when expanded");
+						// Allow time for href to load, pane to expand, and resize to be called on children
+						setTimeout(d.getTestCallback(function(){
+							// Check that href loaded
+							doh.is(1, loadEvents["ctpHmc"], "ctpHmc loaded when expanded");
 
-								// Check that resize() done on children
-								doh.t(layoutResizes["ctpHmcBorderContainer"], "got resize event for BC");
-								doh.t(layoutResizes["ctpHmcTabContainer"], "got resize event for TC");
-								doh.is(0, layoutResizes["ctpHmcBorderContainer"][0].length, "no size specified for BC")
-							}), 4000);
+							// Check that resize() done on children
+							doh.t(layoutResizes["ctpHmcBorderContainer"], "got resize event for BC");
+							doh.t(layoutResizes["ctpHmcTabContainer"], "got resize event for TC");
+							doh.is(0, layoutResizes["ctpHmcBorderContainer"][0].length, "no size specified for BC")
+						}), 4000);
 
-							return d;
-						}
-					},
+						return d;
+					}
+				},
 
-					{
-						name: "initially closed, multiple children",
-						timeout: 2000,
-						runTest: function(t){
-							var d = new doh.Deferred();
+				{
+					name: "initially closed, multiple children",
+					timeout: 2000,
+					runTest: function(t){
+						var d = new doh.Deferred();
 
-							doh.f(dijit.byId("ctpMc_child1")._resized, "resize event for child1 deferred");
-							doh.f(dijit.byId("ctpMc_child2")._resized, "resize event for child2 deferred");
+						doh.f(registry.byId("ctpMc_child1")._resized, "resize event for child1 deferred");
+						doh.f(registry.byId("ctpMc_child2")._resized, "resize event for child2 deferred");
 
-							var tp = dijit.byId("ctpMc");
-							tp.set("open", true);
+						var tp = registry.byId("ctpMc");
+						tp.set("open", true);
 
-							// Allow time for pane to expand, and resize to be called on children
-							setTimeout(d.getTestCallback(function(){
-								// Check that resize() done on children
-								doh.t(dijit.byId("ctpMc_child1")._resized, "got resize event for child1");
-								doh.t(dijit.byId("ctpMc_child2")._resized, "got resize event for child2");
-							}), 750);
+						// Allow time for pane to expand, and resize to be called on children
+						setTimeout(d.getTestCallback(function(){
+							// Check that resize() done on children
+							doh.t(registry.byId("ctpMc_child1")._resized, "got resize event for child1");
+							doh.t(registry.byId("ctpMc_child2")._resized, "got resize event for child2");
+						}), 750);
 
-							return d;
-						}
+						return d;
 					}
-				]
-			);
+				}
+			]);
 
 			// Make sure that Dialog loads it's href when shown, and also that
 			// it calls resize on it's children when shown (since that's the contract
 			// for layout widgets, and ContentPane is acting as a layout widget).
-			doh.register("Dialog",
-				[
-					{
-						name: "href multiple children",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.f(loadEvents["dlgHmc"], "dlgHmc load deferred until open");
-
-							var dlg = dijit.byId("dlgHmc");
-							dlg.show();
-
-							// Allow time for href to load, pane to expand, and resize to be called on children
-							setTimeout(d.getTestCallback(function(){
-								// Check that href loaded
-								doh.is(1, loadEvents["dlgHmc"], "dlgHmc loaded when expanded");
-
-								// Check that resize() done on children
-								doh.t(layoutResizes["dlgHmcBorderContainer"], "got resize event for BC");
-								doh.t(layoutResizes["dlgHmcTabContainer"], "got resize event for TC");
-								doh.is(0, layoutResizes["dlgHmcBorderContainer"][0].length, "no size specified for BC")
-							}), 4000);
-
-							return d;
-						},
-						tearDown: function(){
-							var dlg = dijit.byId("dlgHmc");
-							dlg.hide();
-						}
-					},
+			doh.register("Dialog", [
+				{
+					name: "href multiple children",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
 
-					{
-						name: "multiple inlined children",
-						timeout: 2000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							doh.f(dijit.byId("dlgMc_child1")._resized, "resize event for child1 deferred");
-							doh.f(dijit.byId("dlgMc_child2")._resized, "resize event for child2 deferred");
-
-							var dlg = dijit.byId("dlgMc");
-							dlg.show();
-
-							// Allow time for pane to expand, and resize to be called on children
-							setTimeout(d.getTestCallback(function(){
-								// Check that resize() done on children
-								doh.t(dijit.byId("dlgMc_child1")._resized, "got resize event for child1");
-								doh.t(dijit.byId("dlgMc_child2")._resized, "got resize event for child2");
-							}), 750);
-
-							return d;
-						},
-						tearDown: function(){
-							var dlg = dijit.byId("dlgMc");
-							dlg.hide();
-						}
-					}
-				]
-			);
+						doh.f(loadEvents["dlgHmc"], "dlgHmc load deferred until open");
 
-			// Test that resizing a TabContainer doesn't reload href (when refreshOnShow=true), bug #8197
-			doh.register("TabContainer resize/reload tests",
-				[
-					{
-						name: "initial conditions",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-							// Wait for load events to occur (after fetching URL's)
-							setTimeout(d.getTestCallback(function(){
-								doh.is(1, loadEvents.reloadTC_pane1, "pane1 loaded");
-							}), 4000);
-							return d;
-						}
+						var dlg = registry.byId("dlgHmc");
+						dlg.show();
+
+						// Allow time for href to load, pane to expand, and resize to be called on children
+						setTimeout(d.getTestCallback(function(){
+							// Check that href loaded
+							doh.is(1, loadEvents["dlgHmc"], "dlgHmc loaded when expanded");
+
+							// Check that resize() done on children
+							doh.t(layoutResizes["dlgHmcBorderContainer"], "got resize event for BC");
+							doh.t(layoutResizes["dlgHmcTabContainer"], "got resize event for TC");
+							doh.is(0, layoutResizes["dlgHmcBorderContainer"][0].length, "no size specified for BC")
+						}), 4000);
+
+						return d;
 					},
-					{
-						name: "reload on reshow",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							dijit.byId("reloadTC").selectChild(dijit.byId("reloadTC_pane2"));
-							dijit.byId("reloadTC").selectChild(dijit.byId("reloadTC_pane1"));
-							setTimeout(d.getTestCallback(function(){
-								doh.is(2, loadEvents.reloadTC_pane1, "pane1 loaded again");
-							}), 4000);
-							return d;
-						}
+					tearDown: function(){
+						var dlg = registry.byId("dlgHmc");
+						dlg.hide();
+					}
+				},
+
+				{
+					name: "multiple inlined children",
+					timeout: 2000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						doh.f(registry.byId("dlgMc_child1")._resized, "resize event for child1 deferred");
+						doh.f(registry.byId("dlgMc_child2")._resized, "resize event for child2 deferred");
+
+						var dlg = registry.byId("dlgMc");
+						dlg.show();
+
+						// Allow time for pane to expand, and resize to be called on children
+						setTimeout(d.getTestCallback(function(){
+							// Check that resize() done on children
+							doh.t(registry.byId("dlgMc_child1")._resized, "got resize event for child1");
+							doh.t(registry.byId("dlgMc_child2")._resized, "got resize event for child2");
+						}), 750);
+
+						return d;
 					},
-					{
-						name: "no reload on TabContainer resize",
-						timeout: 5000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-
-							dijit.byId("reloadTC").resize({h: 300, w: 300});
-							setTimeout(d.getTestCallback(function(){
-								doh.is(2, loadEvents.reloadTC_pane1, "pane1 not loaded again");
-							}), 4000);
-							return d;
-						}
-					}
-				]
-			);
+					tearDown: function(){
+						var dlg = registry.byId("dlgMc");
+						dlg.hide();
+					}
+				}
+			]);
+
+			// Test that resizing a TabContainer doesn't reload href (when refreshOnShow=true), bug #8197
+			doh.register("TabContainer resize/reload tests", [
+				{
+					name: "initial conditions",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+						// Wait for load events to occur (after fetching URL's)
+						setTimeout(d.getTestCallback(function(){
+							doh.is(1, loadEvents.reloadTC_pane1, "pane1 loaded");
+						}), 4000);
+						return d;
+					}
+				},
+				{
+					name: "reload on reshow",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						registry.byId("reloadTC").selectChild(registry.byId("reloadTC_pane2"));
+						registry.byId("reloadTC").selectChild(registry.byId("reloadTC_pane1"));
+						setTimeout(d.getTestCallback(function(){
+							doh.is(2, loadEvents.reloadTC_pane1, "pane1 loaded again");
+						}), 4000);
+						return d;
+					}
+				},
+				{
+					name: "no reload on TabContainer resize",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						registry.byId("reloadTC").resize({h: 300, w: 300});
+						setTimeout(d.getTestCallback(function(){
+							doh.is(2, loadEvents.reloadTC_pane1, "pane1 not loaded again");
+						}), 4000);
+						return d;
+					}
+				}
+			]);
 
 			doh.run();
 		});
 
 	</script>
 </head>
-<body class="claro">
-	<h1>dijit.layout.ContentPane layout related DOH test</h1>
+<body class="claro" role="main">
+	<h1>dijit/layout/ContentPane layout related DOH test</h1>
 
 	<p>
 		Tests ContentPane in it's role as a layout widget, including as child of another layout widgets (especially TabContainer).
 	</p>
 
 	<h2>Tests that href gets loaded when ContentPane is first made visible</h2>
-	<div id="outerTC" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 880px; height: 200px;"'>
-		<div id="pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc0.html", title:"Initially Selected", onLoad:myOnLoad'>
+	<div id="outerTC" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 880px; height: 200px;","aria-label":"outerTC"'>
+		<div id="pane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"doc0.html", title:"Initially Selected", onLoad:myOnLoad'>
 			initially selected pane
 		</div>
-		<div id="pane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc1.html", title:"Initially Hidden", onLoad:myOnLoad'>
+		<div id="pane2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"doc1.html", title:"Initially Hidden", onLoad:myOnLoad'>
 			unselected pane
 		</div>
-		<div id="innerTC" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='nested:true, title:"Nested TabContainer"'>
-			<div id="innerPane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc0.html", title:"Initially Selected", onLoad:myOnLoad'>
+		<div id="innerTC" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='nested:true, title:"Nested TabContainer"'>
+			<div id="innerPane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"doc0.html", title:"Initially Selected", onLoad:myOnLoad'>
 				initially selected inner pane
 			</div>
-			<div id="innerPane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc1.html", title:"Initially Hidden", onLoad:myOnLoad'>
+			<div id="innerPane2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"doc1.html", title:"Initially Hidden", onLoad:myOnLoad'>
 				unselected pane
 			</div>
 		</div>
-		<div id="bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='title:"BorderContainer"'>
-			<div id="bcPane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc0.html", region:"left", style:"width: 200px;", onLoad:myOnLoad'>
+		<div id="bc" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='title:"BorderContainer"'>
+			<div id="bcPane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"doc0.html", region:"left", style:"width: 200px;", onLoad:myOnLoad'>
 				left pane
 			</div>
-			<div id="bcPane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc1.html", region:"center", onLoad:myOnLoad'>
+			<div id="bcPane2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"doc1.html", region:"center", onLoad:myOnLoad'>
 				center pane
 
 				<!-- when this ContentPane is shown each of these widgets should get a resize()
@@ -683,14 +714,14 @@
 	</div>
 
 	<h2>Tests for resizing in a layout container hierarchy</h2>
-	<div id="resizeTC" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 880px; height: 200px;"'>
-		<div id="resizePane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Initially Selected", onLoad:myOnLoad'>
+	<div id="resizeTC" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 880px; height: 200px;","aria-label":"resizeTC"'>
+		<div id="resizePane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Initially Selected", onLoad:myOnLoad'>
 			initially selected pane
 		</div>
-		<div id="singleChildPane" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Single ResizableChild", onLoad:myOnLoad'>
+		<div id="singleChildPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Single ResizableChild", onLoad:myOnLoad'>
 			<div id="singleChildResizable" data-dojo-type="ResizableWidget" ></div>
 		</div>
-		<div id="multipleChildPanes" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Multiple ResizableChild", onLoad:myOnLoad'>
+		<div id="multipleChildPanes" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Multiple ResizableChild", onLoad:myOnLoad'>
 			<div id="multipleChildResizable1" data-dojo-type="ResizableWidget" ></div>
 			<div style="border: groove blue medium;">
 				<span>hide the second widget to see if ContentPane can still find it</span>
@@ -698,32 +729,36 @@
 				<span>ending text</span>
 			</div>
 		</div>
-		<div id="multipleResizableInForm" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Multiple resizable in form", onLoad:myOnLoad'>
-			<div data-dojo-type="dijit.form.Form">
+		<div id="multipleResizableInForm" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Multiple resizable in form", onLoad:myOnLoad'>
+			<div data-dojo-type="dijit/form/Form">
 				<div id="resizableInForm1" data-dojo-type="ResizableWidget" ></div>
 				<div id="resizableInForm2" data-dojo-type="ResizableWidget" ></div>
 			</div>
 		</div>
-		<div id="singleResizableInForm" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Single resizable in form", onLoad:myOnLoad'>
-			<div data-dojo-type="dijit.form.Form">
+		<div id="singleResizableInForm" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Single resizable in form", onLoad:myOnLoad'>
+			<div data-dojo-type="dijit/form/Form">
 				<div id="resizableInForm0" data-dojo-type="ResizableWidget" ></div>
 			</div>
 		</div>
-		<div id="singleChildHref" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Href Single Child",
+		<div id="singleChildHref" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Href Single Child",
 			href:"borderContainer.php?id=singleChildHref", onLoad:myOnLoad'></div>
-		<div id="multipleChildHref" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Href Multiple Children",
+		<div id="multipleChildHref" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Href Multiple Children",
 			href:"multipleLayoutWidgets.php?id=multipleChildHref", onLoad:myOnLoad'></div>
 	</div>
 
 	
-	<h2>Size on Form, single nested layout widgets</h2>
-	<form data-dojo-type="dijit.form.Form" style="height:100px; width: 100px; border: medium inset gray; padding: 10px;" id="fss">
-		<div data-dojo-type="ResizableWidget" id="fssc">
-		</div>
+	<h2>Size on Form, single nested layout widget</h2>
+	<form data-dojo-type="dijit/form/Form" style="height:100px; width: 100px; border: medium inset gray; padding: 10px;" id="fss">
+		<div data-dojo-type="ResizableWidget" id="fssc"></div>
 	</form>
-
-	<h2>Size on Form, multiple nested layout widget</h2>
-	<form data-dojo-type="dijit.form.Form" style="height:250px; width: 150px; border: medium inset gray; padding: 10px;" id="fsm">
+	<form data-dojo-type="dijit/form/Form" style="height:100px; width: 100px; border: medium inset gray; padding: 10px;" id="fss2">
+		<!-- this form has one resizable child, and an invisible child, so the resizable child should be expanded -->
+		<div id="fss2_rc" data-dojo-type="ResizableWidget">resizable</div>
+		<div id="fss2_ic" data-dojo-type="dojo/store/Memory"></div>
+	</form>
+	<h2>Size on Form, multiple nested widgets</h2>
+	<!-- two layout widgets -->
+	<form data-dojo-type="dijit/form/Form" style="height:250px; width: 150px; border: medium inset gray; padding: 10px;" id="fsm">
 		<div data-dojo-type="ResizableWidget" style="width: 100px; height: 100px; border: 1px solid black;" id="fsmc1">
 			child #1 (100x100)
 		</div>
@@ -731,15 +766,19 @@
 			child #2 (100x100)
 		</div>
 	</form>
+	<form data-dojo-type="dijit/form/Form" style="height:250px; width: 150px; border: medium inset gray; padding: 10px;" id="fsm2">
+		<div id="fsm2_vc" data-dojo-type="dijit/_WidgetBase">visible</div>
+		<div id="fsm2_rc" data-dojo-type="ResizableWidget">resizable</div>
+	</form>
 
 	<h2>No size on Form, single nested layout widgets</h2>
-	<form data-dojo-type="dijit.form.Form" style="border: medium inset gray; padding: 10px;" data-dojo-props="doLayout: false" id="fns">
+	<form data-dojo-type="dijit/form/Form" style="border: medium inset gray; padding: 10px;" data-dojo-props="doLayout: false" id="fns">
 		<div data-dojo-type="ResizableWidget" style="height:200px; width: 400px;" id="fnsc">
 		</div>
 	</form>
 
 	<h2>No size on Form, multiple nested layout widget</h2>
-	<form data-dojo-type="dijit.form.Form" style="border: medium inset gray; padding: 10px;" id="fnm">
+	<form data-dojo-type="dijit/form/Form" style="border: medium inset gray; padding: 10px;" id="fnm">
 		<div data-dojo-type="ResizableWidget" style="width: 100px; height: 100px; border: 1px solid black;" id="fnmc1">
 			child #1 (100x100)
 		</div>
@@ -749,51 +788,51 @@
 	</form>
 
 	<h2>Tests that ContentPane resize doesn't trigger reload</h2>
-	<div id="reloadTC" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 880px; height: 200px;"'>
-		<div id="reloadTC_pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc0.html", title:"Initially Selected", onLoad:myOnLoad, refreshOnShow:true'>
+	<div id="reloadTC" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 880px; height: 200px;","aria-label":"outerTC"'>
+		<div id="reloadTC_pane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"doc0.html", title:"Initially Selected", onLoad:myOnLoad, refreshOnShow:true'>
 			initially selected pane
 		</div>
-		<div id="reloadTC_pane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc1.html", title:"Initially Hidden", onLoad:myOnLoad'>
+		<div id="reloadTC_pane2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"doc1.html", title:"Initially Hidden", onLoad:myOnLoad'>
 			unselected pane
 		</div>
 	</div>
 
 	<h2>Test the ContentPane loads href and resizes children (as per it's contract a layout widget)
 			when it's not a child of a layout container itself</h2>
-	<div id="ctpHsc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Closed TitlePane Href Single Child", open:false,
+	<div id="ctpHsc" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Closed TitlePane Href Single Child", open:false,
 		href:"borderContainer.php?id=ctpHsc&sized=true", onLoad:myOnLoad'></div>
 	<br><br>
 
-	<div id="ctpHmc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Closed TitlePane Href Multiple Children", open:false,
+	<div id="ctpHmc" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Closed TitlePane Href Multiple Children", open:false,
 		href:"multipleLayoutWidgets.php?id=ctpHmc", onLoad:myOnLoad'></div>
 	<br><br>
 
-	<div id="otpHsc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Opened TitlePane Href Single Child",
+	<div id="otpHsc" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Opened TitlePane Href Single Child",
 		href:"borderContainer.php?id=otpHsc&sized=true", onLoad:myOnLoad'></div>
 	<br><br>
 
-	<div id="otpHmc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Opened TitlePane Href Multiple Children",
+	<div id="otpHmc" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Opened TitlePane Href Multiple Children",
 		href:"multipleLayoutWidgets.php?id=otpHmc", onLoad:myOnLoad'></div>
 	<br><br>
 
-	<div id="otpMc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Opened TitlePane Multiple Children"'>
+	<div id="otpMc" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Opened TitlePane Multiple Children"'>
 		<!-- these widgets should get a resize on page load -->
 		<div id="otpMc_child1" data-dojo-type="ResizableWidget" ></div>
 		<div id="otpMc_child2" data-dojo-type="ResizableWidget" ></div>
 	</div>
 	<br><br>
 
-	<div id="ctpMc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Closed TitlePane Multiple Children", open:false'>
+	<div id="ctpMc" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Closed TitlePane Multiple Children", open:false'>
 		<!-- these widgets should get a resize() when the TitlePane is opened -->
 		<div id="ctpMc_child1" data-dojo-type="ResizableWidget" ></div>
 		<div id="ctpMc_child2" data-dojo-type="ResizableWidget" ></div>
 	</div>
 	<br><br>
 
-	<div id="dlgHmc" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Dialog Href Multiple Children",
+	<div id="dlgHmc" data-dojo-type="dijit/Dialog" data-dojo-props='title:"Dialog Href Multiple Children",
 		href:"multipleLayoutWidgets.php?id=dlgHmc", onLoad:myOnLoad'></div>
 
-	<div id="dlgMc" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Dialog Multiple Children"'>
+	<div id="dlgMc" data-dojo-type="dijit/Dialog" data-dojo-props='title:"Dialog Multiple Children"'>
 		<!-- these widgets should get a resize() when the Dialog is opened -->
 		<div id="dlgMc_child1" data-dojo-type="ResizableWidget" ></div>
 		<div id="dlgMc_child2" data-dojo-type="ResizableWidget" ></div>
diff --git a/dijit/tests/layout/LayoutContainer.html b/dijit/tests/layout/LayoutContainer.html
index 05493a4..10e6f5b 100644
--- a/dijit/tests/layout/LayoutContainer.html
+++ b/dijit/tests/layout/LayoutContainer.html
@@ -1,95 +1,87 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="en">
 <head>
-	<title>dijit.layout.LayoutContainer Test</title>
+	<title>dijit/layout/LayoutContainer Test</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../../themes/claro/claro.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
-
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<script type="text/javascript" src="../helpers.js"></script>
+	<script src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.LayoutContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.form.FilteringSelect");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		
-		function checkInside(/*Widget*/ child, /*Widget*/ parent){
-			// summary:
-			//		Test that child is fully inside of parent
-			var cp = dojo.position(child.domNode, true),
-				pp = dojo.position(parent.domNode, true);
-
-			doh.t(
-				cp.y > pp.y && cp.y+cp.h < pp.y+pp.h &&
-				cp.x > pp.x && cp.x+cp.w < pp.x+pp.w,
-				child.layoutAlign + " inside " + parent.id + dojo.toJson(cp) + dojo.toJson(pp)
-			);
-		}
-		function checkAbove(/*String*/ comment, /*Widget*/ above, /*Widget*/ below){
-			// summary:
-			//		Test that child is fully inside of parent
-
-			var ap = dojo.position(above.domNode, true),
-				bp = dojo.position(below.domNode, true);
+		require([
+			"doh/runner",
+			"dojo/_base/array",
+			"dojo/dom-geometry",
+			"dojo/json",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/layout/ContentPane",
+			"dijit/layout/LayoutContainer",
+			"dijit/tests/helpers",
+			"dijit/form/FilteringSelect",
+			"dojo/domReady!"
+		], function(doh, array,domGeom, json, parser,
+					registry, ContentPane, LayoutContainer, helpers){
+
+			function checkInside(/*Widget*/ child, /*Widget*/ parent){
+				// summary:
+				//		Test that child is fully inside of parent
+				var cp = domGeom.position(child.domNode, true),
+					pp = domGeom.position(parent.domNode, true);
+
+				doh.t(
+					cp.y > pp.y && cp.y+cp.h < pp.y+pp.h &&
+					cp.x > pp.x && cp.x+cp.w < pp.x+pp.w,
+					"check " + child.id + "( " + json.stringify(cp) + " ) inside " + parent.id  + "( " +
+							json.stringify(pp) + " )");
+			}
+			function checkAbove(/*Widget*/ above, /*Widget*/ below){
+				// summary:
+				//		Test that "above" widget is above "below" widget
+
+				var ap = domGeom.position(above.domNode, true),
+					bp = domGeom.position(below.domNode, true);
+
+				doh.t(Math.round(ap.y+ap.h) <= Math.round(bp.y),
+					"check " + above.id + "( " + json.stringify(ap) + " ) above " + below.id + "( " +
+							json.stringify(bp) + " )");
+			}
+			function checkLeft(/*Widget*/ left, /*Widget*/ right){
+				// summary:
+				//		Test that "left" widget is to left of "right" widget
+
+				var lp = domGeom.position(left.domNode, true),
+					rp = domGeom.position(right.domNode, true);
+
+				doh.t(lp.x+lp.w <= rp.x,
+					"check " + left.id + "( " + json.stringify(lp) + " ) to left of " + right.id + "( " +
+							json.stringify(rp) + " )");
+			}
 
-			doh.t(ap.y+ap.h <= bp.y,
-				comment + " " + above.layoutAlign + " above " + below.layoutAlign + dojo.toJson(ap) + dojo.toJson(bp)
-			);
-		}
-		function checkLeft(/*String*/ comment, /*Widget*/ left, /*Widget*/ right){
-			// summary:
-			//		Test that child is fully inside of parent
-
-			var lp = dojo.position(left.domNode, true),
-				rp = dojo.position(right.domNode, true);
-
-			doh.t(lp.x+lp.w <= rp.x,
-				comment + " " + left.layoutAlign + " to left of " + right.layoutAlign + dojo.toJson(lp) + dojo.toJson(rp)
-			);
-		}
-
-		dojo.ready(function(){
 			doh.register("parse", function(){
-				dojo.parser.parse();
+				return parser.parse();
 			});
 
 			doh.register("LayoutContainer", [
 				function basic(){
-					var lc = dijit.byId("basic");
-					dojo.forEach(lc.getChildren(), function(child){
+					var lc = registry.byId("basic");
+					array.forEach(lc.getChildren(), function(child){
 						checkInside(child, lc);
 					});
 
-					var left = dijit.byId("leftcp_layout1"),
-						top = dijit.byId("topcp_layout1"),
-						right = dijit.byId("rightcp_layout1"),
-						center = dijit.byId("centercp_layout1"),
-						bottom = dijit.byId("bottomcp_layout1");
+					var left = registry.byId("leftcp_layout1"),
+						top = registry.byId("topcp_layout1"),
+						right = registry.byId("rightcp_layout1"),
+						center = registry.byId("centercp_layout1"),
+						bottom = registry.byId("bottomcp_layout1");
 
 					// Check positions
-					checkLeft("left vs top", left, top);
-					checkLeft("left vs center", left, center);
-					checkLeft("bottom vs right", bottom, right);
-					checkAbove("top vs center", top, center);
-					checkAbove("center vs bottom", center, bottom);
+					checkLeft(left, top);
+					checkLeft(left, center);
+					checkLeft(bottom, right);
+					checkAbove(top, center);
+					checkAbove(center, bottom);
 
 					// Check tab order
-					var tabbable = tabOrder(lc.domNode);
+					var tabbable = helpers.tabOrder(lc.domNode);
 					doh.is(7, tabbable.length, "each pane plus link and select");
 					doh.is(left.id, tabbable[0].id, "left");
 					doh.is(right.id, tabbable[1].id, "right");
@@ -99,37 +91,38 @@
 				},
 
 				function advanced(){
-					var lc = dijit.byId("advanced");
-					dojo.forEach(lc.getChildren(), function(child){
+					var lc = registry.byId("advanced");
+					array.forEach(lc.getChildren(), function(child){
 						checkInside(child, lc);
 					});
 
-					var left = dijit.byId("leftcp_layout2"),
-						top = dijit.byId("topcp_layout2"),
-						right = dijit.byId("rightcp_layout2"),
-						centerLeft = dijit.byId("centerLeftcp_layout2"),
-						center = dijit.byId("centercp_layout2"),
-						centerRight = dijit.byId("centerRightcp_layout2"),
-						bottom = dijit.byId("bottomcp_layout2");
+					var left = registry.byId("leftcp_layout2"),
+						top = registry.byId("topcp_layout2"),
+						right = registry.byId("rightcp_layout2"),
+						centerLeft = registry.byId("centerLeftcp_layout2"),
+						center = registry.byId("centercp_layout2"),
+						centerRight = registry.byId("centerRightcp_layout2"),
+						bottom = registry.byId("bottomcp_layout2");
 
 					// Check positions
-					checkLeft("left vs top", left, top);
-					checkLeft("left vs centerLeft", left, centerLeft);
-					checkLeft("centerLeft vs center", centerLeft, center);
-					checkLeft("center vs centerRight", center, centerRight);
-					checkAbove("top vs center", top, center);
-					checkAbove("top vs inner right", top, centerRight);
-					checkAbove("centerLeft vs bottom", centerLeft, bottom);
+					checkLeft(left, top);
+					checkLeft(left, centerLeft);
+					checkLeft(centerLeft, center);
+					checkLeft(center, centerRight);
+					checkAbove(top, center);
+					checkAbove(top, centerRight);
+					checkAbove(centerLeft, bottom);
 
 					// Check tab order
-					var tabbable = tabOrder(lc.domNode);
+					var tabbable = helpers.tabOrder(lc.domNode);
 					doh.is(8, tabbable.length, "each pane plus link and select");
 					doh.is(left.id, tabbable[0].id, "left");
 					doh.is(top.id, tabbable[1].id, "top");
-					doh.is(bottom.id, tabbable[2].id, "bottom");
-					doh.is(centerLeft.id, tabbable[3].id, "center left");
-					doh.is(center.id, tabbable[4].id, "center");
-					doh.is(centerRight.id, tabbable[7].id, "center right");
+					doh.is(centerLeft.id, tabbable[2].id, "inner left");
+					doh.is(center.id, tabbable[3].id, "center");
+					/* two random widgets inside center pane ... */
+					doh.is(centerRight.id, tabbable[6].id, "inner right");
+					doh.is(bottom.id, tabbable[7].id, "bottom");
 				}
 			]);
 			
@@ -138,28 +131,28 @@
 	</script>
 
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h2 id="heading" >Dijit layout.LayoutContainer tests</h2>
 
 	<p>Basic layout. Tabindex="0" added to each pane to test for tab order matching source code order.  Tab order
 	should be:  left, right, top, middle/main, bottom</p>
 
-	<div id="basic" dojoType="dijit.layout.LayoutContainer"
+	<div id="basic" data-dojo-type="dijit/layout/LayoutContainer" data-dojo-props="design: 'sidebar'"
 		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
 	>
-		<div dojoType="dijit.layout.ContentPane" id="leftcp_layout1" layoutAlign="left" style="background-color: #acb386; width: 100px;" tabindex="0">
+		<div data-dojo-type="dijit/layout/ContentPane" id="leftcp_layout1" region="left" style="background-color: #acb386; width: 100px;" tabindex="0">
 			left
 		</div>
-		<div dojoType="dijit.layout.ContentPane" id="rightcp_layout1" layoutAlign="right" style="background-color: #acb386;"  tabindex="0">
+		<div data-dojo-type="dijit/layout/ContentPane" id="rightcp_layout1" region="right" style="background-color: #acb386;"  tabindex="0">
 			right
 		</div>
-		<div dojoType="dijit.layout.ContentPane" id="topcp_layout1" layoutAlign="top" style="background-color: #b39b86; "  tabindex="0">
+		<div data-dojo-type="dijit/layout/ContentPane" id="topcp_layout1" region="top" style="background-color: #b39b86; "  tabindex="0">
 			top bar
 		</div>
-		<div dojoType="dijit.layout.ContentPane" id="centercp_layout1" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px;"  tabindex="0">
+		<div data-dojo-type="dijit/layout/ContentPane" id="centercp_layout1" region="center" style="background-color: #f5ffbf; padding: 10px;"  tabindex="0">
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
+			<select data-dojo-type="dijit/form/FilteringSelect" aria-label="select">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
@@ -167,128 +160,52 @@
 			Here's some text that comes AFTER the combo box.
 		</div>
 
-		<div dojoType="dijit.layout.ContentPane" id="bottomcp_layout1" layoutAlign="bottom" style="background-color: #b39b86;"  tabindex="0">
+		<div data-dojo-type="dijit/layout/ContentPane" id="bottomcp_layout1" region="bottom" style="background-color: #b39b86;"  tabindex="0">
 			bottom bar
 		</div>
 
 	</div>
 
 	<p>Advanced layout. Tabindex="0" added to each pane to test for tab order matching source code order.  Tab order
-	should be:  left, top, bottom, inner left, inner middle, inner right. This is not an ideal tab order. See below to use nested
+	should be:  left, top, inner left, inner middle, inner right, bottom. This is not an ideal tab order. See below to use nested
 	layout containers to achieve a tab order which matches presentation and source code order.</p>
-	<div id="advanced" dojoType="dijit.layout.LayoutContainer"
+	<div id="advanced" data-dojo-type="dijit/layout/LayoutContainer"
 		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
 	>
-		<div dojoType="dijit.layout.ContentPane" id="leftcp_layout2" layoutAlign="left" style="background-color: #acb386; width: 100px; margin: 5px;" tabindex="0">
+		<div data-dojo-type="dijit/layout/ContentPane" id="leftcp_layout2" data-dojo-props="region:'left',layoutPriority:1"
+			 style="background-color: #acb386; width: 100px; margin: 5px;" tabindex="0">
 			left
 		</div>
-		<div dojoType="dijit.layout.ContentPane" id="topcp_layout2" layoutAlign="top" style="background-color: #b39b86;  margin: 5px;" tabindex="0">
+		<div data-dojo-type="dijit/layout/ContentPane" id="topcp_layout2" data-dojo-props="region:'top',layoutPriority:2"
+			 style="background-color: #b39b86;  margin: 5px;" tabindex="0">
 			top bar
 		</div>
-		<div dojoType="dijit.layout.ContentPane" id="bottomcp_layout2" layoutAlign="bottom" style="background-color: #b39b86; margin: 5px;" tabindex="0">
-
-			bottom bar
-		</div>
-		<div dojoType="dijit.layout.ContentPane" id="centerLeftcp_layout2" layoutAlign="left" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
+		<div data-dojo-type="dijit/layout/ContentPane" id="centerLeftcp_layout2" data-dojo-props="region:'left',layoutPriority:3"
+			 style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
 			inner left
 		</div>
 
-		<div dojoType="dijit.layout.ContentPane" id="centercp_layout2" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px; margin: 5px;" tabindex="0">
+		<div data-dojo-type="dijit/layout/ContentPane" id="centercp_layout2" data-dojo-props="region:'center'"
+			 style="background-color: #f5ffbf; padding: 10px; margin: 5px;" tabindex="0">
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 
 			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
+			<select data-dojo-type="dijit/form/FilteringSelect" aria-label="select">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
 			</select>
 			Here's some text that comes AFTER the combo box.
 		</div>
-		<div dojoType="dijit.layout.ContentPane" id="centerRightcp_layout2" layoutAlign="right" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
+		<div data-dojo-type="dijit/layout/ContentPane" id="centerRightcp_layout2" data-dojo-props="region:'right',layoutPriority:3"
+			 style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
 			inner right
 		</div>
-	</div>
-
-	<p>Advanced layout with nested containers.  Tabindex="0" added to content panes to show tab order. Order should be:
-	left, top, inner left, inner middle, inner right, bottom. This is the preferred tab order for this type of layout.</p>
-	<div dojoType="dijit.layout.LayoutContainer"
-		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
-	>
-		<div dojoType="dijit.layout.ContentPane" id="leftcp_layout3" layoutAlign="left" style="background-color: #acb386; width: 100px; margin: 5px;" tabindex="0">
-			left
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="margin: 5px;" >
-			<div dojoType="dijit.layout.LayoutContainer"	style="height:90%;border: 2px solid black;padding: 10px;">
-
-				<div dojoType="dijit.layout.ContentPane" id="topcp_layout3" layoutAlign="top" style="background-color: #b39b86;  margin: 5px;" tabindex="0">
-					top bar
-				</div>
-				<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="margin: 5px;">
-					<div dojoType="dijit.layout.LayoutContainer"	style="height:80%;border: 2px solid black;padding: 10px;">
-						<div dojoType="dijit.layout.ContentPane" id="centerLeftcp_layout3" layoutAlign="left" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
-							inner left
-						</div>
-						<div dojoType="dijit.layout.ContentPane" id="centercp_layout3" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px; margin: 5px;" tabindex="0">
-							main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
-							(to check we're copying children around properly).<br />
-							<select dojoType="dijit.form.FilteringSelect">
-								<option value="1">foo</option>
-								<option value="2">bar</option>
-								<option value="3">baz</option>
-							</select>
-							Here's some text that comes AFTER the combo box.
-						</div>
-						<div dojoType="dijit.layout.ContentPane" id="centerRightcp_layout3" layoutAlign="right" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
-							inner right
-						</div>
-					</div>
-				</div>
-				<div dojoType="dijit.layout.ContentPane" id="bottomcp_layout3" layoutAlign="bottom" style="background-color: #b39b86; margin: 5px;" tabindex="0"	>
-					bottom bar
-				</div>
-			</div>
-		</div>
-	</div>
+		<div data-dojo-type="dijit/layout/ContentPane" id="bottomcp_layout2" data-dojo-props="region:'bottom',layoutPriority:2"
+			 style="background-color: #b39b86; margin: 5px;" tabindex="0">
 
-	<p>Goofy spiral layout.  Match of source code order to tab order can not be achieved with this type of layout.</p>
-	<div dojoType="dijit.layout.LayoutContainer"
-		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
-	>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color: #663333; color: white; width: 100px;">
-			outer left
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="top" style="background-color: #333366; color: white; height: 50px;">
-			outer top
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="right" style="background-color: #663333; color: white; width: 100px;">
-			outer right
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="bottom" style="background-color: #333366; color: white; height: 50px;">
-			outer bottom
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color: #99CC99; width: 100px;">
-			inner left
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="top" style="background-color: #999966; height: 50px;">
-			inner top
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="right" style="background-color: #99CC99; width: 100px;">
-			inner right
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="bottom" style="background-color: #999966; height: 50px;">
-			inner bottom
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="padding: 10px;">
-			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
-			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
-				<option value="1">foo</option>
-				<option value="2">bar</option>
-				<option value="3">baz</option>
-			</select>
-			Here's some text that comes AFTER the combo box.
+			bottom bar
 		</div>
 	</div>
-
 </body>
 </html>
diff --git a/dijit/tests/layout/LayoutContainer_v1.html b/dijit/tests/layout/LayoutContainer_v1.html
new file mode 100644
index 0000000..0d006dd
--- /dev/null
+++ b/dijit/tests/layout/LayoutContainer_v1.html
@@ -0,0 +1,290 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+	<title>dijit/layout/LayoutContainer Test</title>
+
+	<script type="text/javascript" src="../boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/_base/array",
+			"dojo/dom-geometry",
+			"dojo/json",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/layout/ContentPane",
+			"dijit/layout/LayoutContainer",
+			"dijit/tests/helpers",
+			"dijit/form/FilteringSelect",
+			"dojo/domReady!"
+		], function(doh, array,domGeom, json, parser,
+					registry, ContentPane, LayoutContainer, helpers){
+
+			function checkInside(/*Widget*/ child, /*Widget*/ parent){
+				// summary:
+				//		Test that child is fully inside of parent
+				var cp = domGeom.position(child.domNode, true),
+					pp = domGeom.position(parent.domNode, true);
+
+				doh.t(
+					cp.y > pp.y && cp.y+cp.h < pp.y+pp.h &&
+					cp.x > pp.x && cp.x+cp.w < pp.x+pp.w,
+					child.layoutAlign + " inside " + parent.id + json.stringify(cp) + json.stringify(pp)
+				);
+			}
+			function checkAbove(/*String*/ comment, /*Widget*/ above, /*Widget*/ below){
+				// summary:
+				//		Test that "above" widget is above "below" widget
+
+				var ap = domGeom.position(above.domNode, true),
+					bp = domGeom.position(below.domNode, true);
+
+				doh.t(Math.round(ap.y+ap.h) <= Math.round(bp.y),
+					comment + " " + above.layoutAlign + " above " + below.layoutAlign + json.stringify(ap) + json.stringify(bp)
+				);
+			}
+			function checkLeft(/*String*/ comment, /*Widget*/ left, /*Widget*/ right){
+				// summary:
+				//		Test that "left" widget is to left of "right" widget
+
+				var lp = domGeom.position(left.domNode, true),
+					rp = domGeom.position(right.domNode, true);
+
+				doh.t(lp.x+lp.w <= rp.x,
+					comment + " " + left.layoutAlign + " to left of " + right.layoutAlign + json.stringify(lp) + json.stringify(rp)
+				);
+			}
+
+			doh.register("parse", function(){
+				return parser.parse();
+			});
+
+			doh.register("LayoutContainer", [
+				function basic(){
+					var lc = registry.byId("basic");
+					array.forEach(lc.getChildren(), function(child){
+						checkInside(child, lc);
+					});
+
+					var left = registry.byId("leftcp_layout1"),
+						top = registry.byId("topcp_layout1"),
+						right = registry.byId("rightcp_layout1"),
+						center = registry.byId("centercp_layout1"),
+						bottom = registry.byId("bottomcp_layout1");
+
+					// Check positions
+					checkLeft("left vs top", left, top);
+					checkLeft("left vs center", left, center);
+					checkLeft("bottom vs right", bottom, right);
+					checkAbove("top vs center", top, center);
+					checkAbove("center vs bottom", center, bottom);
+
+					// Check tab order
+					var tabbable = helpers.tabOrder(lc.domNode);
+					doh.is(7, tabbable.length, "each pane plus link and select");
+					doh.is(left.id, tabbable[0].id, "left");
+					doh.is(right.id, tabbable[1].id, "right");
+					doh.is(top.id, tabbable[2].id, "top");
+					doh.is(center.id, tabbable[3].id, "center");
+					doh.is(bottom.id, tabbable[6].id, "bottom");
+				},
+
+				function advanced(){
+					var lc = registry.byId("advanced");
+					array.forEach(lc.getChildren(), function(child){
+						checkInside(child, lc);
+					});
+
+					var left = registry.byId("leftcp_layout2"),
+						top = registry.byId("topcp_layout2"),
+						right = registry.byId("rightcp_layout2"),
+						centerLeft = registry.byId("centerLeftcp_layout2"),
+						center = registry.byId("centercp_layout2"),
+						centerRight = registry.byId("centerRightcp_layout2"),
+						bottom = registry.byId("bottomcp_layout2");
+
+					// Check positions
+					checkLeft("left vs top", left, top);
+					checkLeft("left vs centerLeft", left, centerLeft);
+					checkLeft("centerLeft vs center", centerLeft, center);
+					checkLeft("center vs centerRight", center, centerRight);
+					checkAbove("top vs center", top, center);
+					checkAbove("top vs inner right", top, centerRight);
+					checkAbove("centerLeft vs bottom", centerLeft, bottom);
+
+					// Check tab order
+					var tabbable = helpers.tabOrder(lc.domNode);
+					doh.is(8, tabbable.length, "each pane plus link and select");
+					doh.is(left.id, tabbable[0].id, "left");
+					doh.is(top.id, tabbable[1].id, "top");
+					doh.is(bottom.id, tabbable[2].id, "bottom");
+					doh.is(centerLeft.id, tabbable[3].id, "center left");
+					doh.is(center.id, tabbable[4].id, "center");
+					doh.is(centerRight.id, tabbable[7].id, "center right");
+				}
+			]);
+			
+			doh.run();
+		});
+	</script>
+
+</head>
+<body class="claro" role="main">
+	<h2 id="heading" >Dijit layout.LayoutContainer Old API tests</h2>
+	<p>
+		Tests for using layoutAlign property rather than region, so design setting (headline or sidebar) has no effect.
+		Remove for 2.0.
+	</p>
+
+	<p>Basic layout. Tabindex="0" added to each pane to test for tab order matching source code order.  Tab order
+	should be:  left, right, top, middle/main, bottom</p>
+
+	<div id="basic" data-dojo-type="dijit/layout/LayoutContainer"
+		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
+	>
+		<div data-dojo-type="dijit/layout/ContentPane" id="leftcp_layout1" layoutAlign="left" style="background-color: #acb386; width: 100px;" tabindex="0">
+			left
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" id="rightcp_layout1" layoutAlign="right" style="background-color: #acb386;"  tabindex="0">
+			right
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" id="topcp_layout1" layoutAlign="top" style="background-color: #b39b86; "  tabindex="0">
+			top bar
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" id="centercp_layout1" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px;"  tabindex="0">
+			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+			(to check we're copying children around properly).<br />
+			<select data-dojo-type="dijit/form/FilteringSelect" aria-label="select">
+				<option value="1">foo</option>
+				<option value="2">bar</option>
+				<option value="3">baz</option>
+			</select>
+			Here's some text that comes AFTER the combo box.
+		</div>
+
+		<div data-dojo-type="dijit/layout/ContentPane" id="bottomcp_layout1" layoutAlign="bottom" style="background-color: #b39b86;"  tabindex="0">
+			bottom bar
+		</div>
+
+	</div>
+
+	<p>Advanced layout. Tabindex="0" added to each pane to test for tab order matching source code order.  Tab order
+	should be:  left, top, bottom, inner left, inner middle, inner right. This is not an ideal tab order. See below to use nested
+	layout containers to achieve a tab order which matches presentation and source code order.</p>
+	<div id="advanced" data-dojo-type="dijit/layout/LayoutContainer"
+		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
+	>
+		<div data-dojo-type="dijit/layout/ContentPane" id="leftcp_layout2" layoutAlign="left" style="background-color: #acb386; width: 100px; margin: 5px;" tabindex="0">
+			left
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" id="topcp_layout2" layoutAlign="top" style="background-color: #b39b86;  margin: 5px;" tabindex="0">
+			top bar
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" id="bottomcp_layout2" layoutAlign="bottom" style="background-color: #b39b86; margin: 5px;" tabindex="0">
+
+			bottom bar
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" id="centerLeftcp_layout2" layoutAlign="left" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
+			inner left
+		</div>
+
+		<div data-dojo-type="dijit/layout/ContentPane" id="centercp_layout2" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px; margin: 5px;" tabindex="0">
+			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+
+			(to check we're copying children around properly).<br />
+			<select data-dojo-type="dijit/form/FilteringSelect" aria-label="select">
+				<option value="1">foo</option>
+				<option value="2">bar</option>
+				<option value="3">baz</option>
+			</select>
+			Here's some text that comes AFTER the combo box.
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" id="centerRightcp_layout2" layoutAlign="right" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
+			inner right
+		</div>
+	</div>
+
+	<p>Advanced layout with nested containers.  Tabindex="0" added to content panes to show tab order. Order should be:
+	left, top, inner left, inner middle, inner right, bottom. This is the preferred tab order for this type of layout.</p>
+	<div data-dojo-type="dijit/layout/LayoutContainer"
+		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
+	>
+		<div data-dojo-type="dijit/layout/ContentPane" id="leftcp_layout3" layoutAlign="left" style="background-color: #acb386; width: 100px; margin: 5px;" tabindex="0">
+			left
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" layoutAlign="client" style="margin: 5px;" >
+			<div data-dojo-type="dijit/layout/LayoutContainer"	style="height:90%;border: 2px solid black;padding: 10px;">
+
+				<div data-dojo-type="dijit/layout/ContentPane" id="topcp_layout3" layoutAlign="top" style="background-color: #b39b86;  margin: 5px;" tabindex="0">
+					top bar
+				</div>
+				<div data-dojo-type="dijit/layout/ContentPane" layoutAlign="client" style="margin: 5px;">
+					<div data-dojo-type="dijit/layout/LayoutContainer"	style="height:80%;border: 2px solid black;padding: 10px;">
+						<div data-dojo-type="dijit/layout/ContentPane" id="centerLeftcp_layout3" layoutAlign="left" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
+							inner left
+						</div>
+						<div data-dojo-type="dijit/layout/ContentPane" id="centercp_layout3" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px; margin: 5px;" tabindex="0">
+							main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+							(to check we're copying children around properly).<br />
+							<select data-dojo-type="dijit/form/FilteringSelect" aria-label="select">
+								<option value="1">foo</option>
+								<option value="2">bar</option>
+								<option value="3">baz</option>
+							</select>
+							Here's some text that comes AFTER the combo box.
+						</div>
+						<div data-dojo-type="dijit/layout/ContentPane" id="centerRightcp_layout3" layoutAlign="right" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
+							inner right
+						</div>
+					</div>
+				</div>
+				<div data-dojo-type="dijit/layout/ContentPane" id="bottomcp_layout3" layoutAlign="bottom" style="background-color: #b39b86; margin: 5px;" tabindex="0"	>
+					bottom bar
+				</div>
+			</div>
+		</div>
+	</div>
+
+	<p>Goofy spiral layout.  Match of source code order to tab order can not be achieved with this type of layout.</p>
+	<div data-dojo-type="dijit/layout/LayoutContainer"
+		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
+	>
+		<div data-dojo-type="dijit/layout/ContentPane" layoutAlign="left" style="background-color: #663333; color: white; width: 100px;">
+			outer left
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" layoutAlign="top" style="background-color: #333366; color: white; height: 50px;">
+			outer top
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" layoutAlign="right" style="background-color: #663333; color: white; width: 100px;">
+			outer right
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" layoutAlign="bottom" style="background-color: #333366; color: white; height: 50px;">
+			outer bottom
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" layoutAlign="left" style="background-color: #99CC99; width: 100px;">
+			inner left
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" layoutAlign="top" style="background-color: #999966; height: 50px;">
+			inner top
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" layoutAlign="right" style="background-color: #99CC99; width: 100px;">
+			inner right
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" layoutAlign="bottom" style="background-color: #999966; height: 50px;">
+			inner bottom
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" layoutAlign="client" style="padding: 10px;">
+			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+			(to check we're copying children around properly).<br />
+			<select data-dojo-type="dijit/form/FilteringSelect" aria-label="select">
+				<option value="1">foo</option>
+				<option value="2">bar</option>
+				<option value="3">baz</option>
+			</select>
+			Here's some text that comes AFTER the combo box.
+		</div>
+	</div>
+
+</body>
+</html>
diff --git a/dijit/tests/layout/StackContainer.html b/dijit/tests/layout/StackContainer.html
index 71e4c69..9857190 100644
--- a/dijit/tests/layout/StackContainer.html
+++ b/dijit/tests/layout/StackContainer.html
@@ -1,116 +1,193 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>StackContainer Demo</title>
 
+	<script src="../boilerplate.js"></script>
+
 	<style>
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
 		.dijitStackController .dijitToggleButtonChecked button {
 			background-color: white;
 			background-image: none;
 		}
-		.dijit_a11y .dijitStackController .dijitToggleButtonChecked button {
-			border-style: dashed !important;
-		}
 		div.dijitStackContainer {
 			border: solid 1px black !important;	/* override .dijitStackContainer-child rule for no border */
 			padding: 3px;
 		}
 	</style>
 
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: false"></script>
-
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-	<script type="text/javascript" src="../helpers.js"></script>
-
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.StackContainer");
-		dojo.require("dijit.layout.StackController");
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.form.Button");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		dojo.require('doh.runner');
-
-		// Hash listing which objects have gotten a resize event
-		resizes = {};
-
-		dojo.ready(function(){
+		require([
+			"doh/runner",
+			"dojo/aspect",
+			"dojo/_base/declare",
+			"dojo/dom",
+			"dojo/dom-geometry",
+			"dojo/on",
+			"dojo/parser",
+			"dojo/query",
+			"dojo/topic",
+			"dijit/registry",
+			"dijit/form/Button",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/layout/_LayoutWidget",
+			"dijit/layout/StackContainer",
+			"dijit/layout/StackController",
+			"dijit/layout/TabContainer",
+			"dijit/tests/helpers",
+			"dojo/domReady!"
+		], function(doh, aspect, declare, dom, domGeom, on, parser, query, topic,
+					registry, Button, BorderContainer, ContentPane, _LayoutWidget, StackContainer, StackController, TabContainer,
+					helpers){
+
+
+			// Hash listing which objects have gotten a resize event
+			var resizesHash = {};
+
 			// track resize events
-			dojo.connect(dijit.layout._LayoutWidget.prototype, "resize", function(){
-				resizes[this.id] = arguments;
-			});
+			aspect.after(_LayoutWidget.prototype, "resize", function(){
+				console.log("resize of widget " + this.id);
+				resizesHash[this.id] = arguments;
+			}, true);
 
 			function click(/*String*/ id){
 				// Click dijit widget w/specified id
-				dijit.byId(id)._onClick({preventDefault: function(){}});
+				on.emit(dom.byId(id), "click", {bubbles: true, cancelable: true});
 			}
 
-			doh.register("setup", [
-				function parse(){
-					dojo.parser.parse();
-				},
-				function programmaticCreation(){
-					var container = new dijit.layout.StackContainer({ id: "sc" },"myStackContainer2");
-					container.addChild(new dijit.layout.ContentPane({
-							id: "page1Prog",
-							title: "Page 1",
-							content: "IT WAS the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period [...]
+			function selected(page){
+				console.debug("page selected " + page.id);
+				var widget=registry.byId("myStackContainer");
+				registry.byId("previous").set("disabled", page.isFirstChild);
+				registry.byId("next").set("disabled", page.isLastChild);
+				registry.byId("previous2").set("disabled", page.isFirstChild);
+				registry.byId("next2").set("disabled", page.isLastChild);
+			}
+			topic.subscribe("myStackContainer-selectChild", selected);
+
+			doh.register("programmatic", [
+				function create(){
+					container = new StackContainer({ id: "sc" }, "myStackContainer2");
+					container.addChild(new ContentPane({
+						id: "page1Prog",
+						title: "Page 1",
+						content: "IT WAS the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, [...]
 					}));
-					container.addChild(new dijit.layout.ContentPane({
-							id: "page2Prog",
-							title: "Page 2",
-							content: "There were a king with a large jaw and a queen with a plain face, on the throne of England; there were a king with a large jaw and a queen with a fair face, on the throne of France. In both countries it was clearer than crystal to the lords of the State preserves of loaves and fishes, that things in general were settled for ever."
+					container.addChild(new ContentPane({
+						id: "page2Prog",
+						title: "Page 2",
+						content: "There were a king with a large jaw and a queen with a plain face, on the throne of England; there were a king with a large jaw and a queen with a fair face, on the throne of France. In both countries it was clearer than crystal to the lords of the State preserves of loaves and fishes, that things in general were settled for ever."
+					}));
+					container.addChild(page3Prog = new ContentPane({
+						id: "page3Prog",
+						title: "Page 3",
+						content: "It was the year of Our Lord one thousand seven hundred and seventy- five. Spiritual revelations were conceded to England at that favoured period, as at this. Mrs. Southcott had recently attained her five-and- twentieth blessed birthday, of whom a prophetic private in the Life Guards had heralded the sublime appearance by announcing that arrangements were made for the swallowing up of London and Westminster. Even the Cock-lane ghost had been laid only a round dozen of year [...]
 					}));
-					container.addChild(new dijit.layout.ContentPane({
-							id: "page3Prog",
-							title: "Page 3",
-							content: "It was the year of Our Lord one thousand seven hundred and seventy- five. Spiritual revelations were conceded to England at that favoured period, as at this. Mrs. Southcott had recently attained her five-and- twentieth blessed birthday, of whom a prophetic private in the Life Guards had heralded the sublime appearance by announcing that arrangements were made for the swallowing up of London and Westminster. Even the Cock-lane ghost had been laid only a round dozen of yea [...]
+					container.addChild(new ContentPane({
+						id: "page4Prog",
+						title: "Page 4",
+						href: "tab1.html"
 					}));
 
 					// make the controller
-					var controller = new dijit.layout.StackController({containerId: "sc"}, "holder");
+					controller = new StackController({containerId: "sc"}, "holder");
 
 					// start 'em up
 					controller.startup();
 					container.startup();
+
+					doh.is(4, container.getChildren().length, "num children");
+
+					// Check aria roles and structure.
+					doh.is(4, query("> *", container.containerNode).length, "wrapper nodes around children");
+					doh.is(4, query("> *[role=tabpanel]", container.containerNode).length, "wrapper nodes have role=tabpanel");
+					doh.is("page1Prog page2Prog page3Prog page4Prog", query("> * > *", container.containerNode).map(function(node){
+						return registry.byNode(node).id;
+					}).join(" "), "children of wrapper divs");
+				},
+				function selectHref(){
+					var d = new doh.Deferred();
+					registry.byId("sc").selectChild(registry.byId("page4Prog")).then(d.getTestCallback(function(){
+						doh.t(helpers.isVisible(dom.byId("page4Prog")), "page4 visible");
+						doh.t(helpers.isHidden(dom.byId("page1Prog")), "page1 hidden");
+					}));
+					return d;
+				},
+				function selectPlain(){
+					var d = new doh.Deferred();
+					registry.byId("sc").selectChild(registry.byId("page1Prog")).then(d.getTestCallback(function(){
+						doh.t(helpers.isVisible(dom.byId("page1Prog")), "page1 visible");
+						doh.t(helpers.isHidden(dom.byId("page4Prog")), "page4 hidden");
+					}));
+					return d;
+				},
+				function selectCurrent(){
+					var d = new doh.Deferred();
+					registry.byId("sc").selectChild(registry.byId("page1Prog")).then(d.getTestCallback(function(){
+						doh.t(helpers.isVisible(dom.byId("page1Prog")), "page1 visible");
+						doh.t(helpers.isHidden(dom.byId("page4Prog")), "page4 hidden");
+					}));
+					return d;
+				},
+				function addChild(){
+					// make sure that child gets put in right place, with role=tabpanel wrapper <div> around it
+					var child = new ContentPane({
+						id: "page2.5Prog",
+						title: "Page 2.5",
+						href: "tab1.html"
+					});
+					container.addChild(child, 2);
+
+					doh.is(5, query("> *", container.containerNode).length, "wrapper nodes around children");
+					doh.is(5, query("> *[role=tabpanel]", container.containerNode).length, "wrapper nodes have role=tabpanel");
+					doh.is("page1Prog page2Prog page2.5Prog page3Prog page4Prog", query("> * > *", container.containerNode).map(function(node){
+						return registry.byNode(node).id;
+					}).join(" "), "children of wrapper divs");
+				},
+				function removeChild(){
+					// note the layout containers only support removeChild(widget), not removeChild(number)
+					container.removeChild(page3Prog);
+
+					doh.is(4, query("> *", container.containerNode).length, "wrapper nodes around children");
+					doh.is(4, query("> *[role=tabpanel]", container.containerNode).length, "wrapper nodes have role=tabpanel");
+					doh.is("page1Prog page2Prog page2.5Prog page4Prog", query("> * > *", container.containerNode).map(function(node){
+						return registry.byNode(node).id;
+					}).join(" "), "children of wrapper divs");
+				}
+			]);
+
+			doh.register("parse", [
+				function parse(){
+					return parser.parse();
 				}
 			]);
 
 			doh.register("basic operation", [
 				function forward(){
 					click("next");
-					doh.t(isHidden(dojo.byId("page1")), "page1 hidden");
-					doh.t(isVisible(dojo.byId("page2")), "page2 visible");
-					doh.t(isHidden(dojo.byId("page3")), "page3 hidden");
+					doh.t(helpers.isHidden(dom.byId("page1")), "page1 hidden");
+					doh.t(helpers.isVisible(dom.byId("page2")), "page2 visible");
+					doh.t(helpers.isHidden(dom.byId("page3")), "page3 hidden");
 				},
 				function previous(){
 					click("previous");
-					doh.t(dijit.byId("previous").disabled, "disabled");
-					doh.t(isVisible(dojo.byId("page1")), "page1 visible");
-					doh.t(isHidden(dojo.byId("page2")), "page2 hidden");
-					doh.t(isHidden(dojo.byId("page3")), "page3 hidden");
+					doh.t(registry.byId("previous").disabled, "disabled");
+					doh.t(helpers.isVisible(dom.byId("page1")), "page1 visible");
+					doh.t(helpers.isHidden(dom.byId("page2")), "page2 hidden");
+					doh.t(helpers.isHidden(dom.byId("page3")), "page3 hidden");
 				},
 				function clickPage2(){
 					click("dijit_layout_StackController_0_page2");
-					doh.t(isHidden(dojo.byId("page1")), "page1 hidden");
-					doh.t(isVisible(dojo.byId("page2")), "page2 visible");
-					doh.t(isHidden(dojo.byId("page3")), "page3 hidden");
+					doh.t(helpers.isHidden(dom.byId("page1")), "page1 hidden");
+					doh.t(helpers.isVisible(dom.byId("page2")), "page2 visible");
+					doh.t(helpers.isHidden(dom.byId("page3")), "page3 hidden");
 				},
 				function clickTwice(){
 					click("dijit_layout_StackController_0_page1");
 					click("dijit_layout_StackController_0_page1");
-					var button = dijit.byId("dijit_layout_StackController_0_page1");
+					var button = registry.byId("dijit_layout_StackController_0_page1");
 					doh.t(button.checked, "Page 1 button is still checked");
 				}
 			]);
@@ -118,57 +195,56 @@
 			doh.register("nested layout widgets", [
 				function nestedLayout(){
 					click("nextPR");
-					var bcPos = dojo.position("bc"),
-						tcPos = dojo.position("tc");
+					var bcPos = domGeom.position("bc"),
+						tcPos = domGeom.position("tc");
 
-					doh.t("bc" in resizes, "BorderContainer got resize");
-					doh.is(300, bcPos.w, "BorderContainer width");
+					doh.t("bc" in resizesHash, "BorderContainer got resize");
+					doh.is(300, Math.round(bcPos.w), "BorderContainer width");
 					doh.is(200, bcPos.h, "BorderContainer height");
 
-					doh.t("tc" in resizes, "TabContainer got resize");
-					doh.is(300, bcPos.w, "TabContainer width");
+					doh.t("tc" in resizesHash, "TabContainer got resize");
+					doh.is(300, Math.round(bcPos.w), "TabContainer width");
 					doh.is(200, bcPos.h, "TabContainer height");
 				}
 			]);
 
 			doh.register("nested stackcontainer w/doLayout=false", [
 				function resizeCalled(){
-					var resizes = dojo.global.resizes;
-					doh.t("stack1" in resizes, "stack1 resized");
-					doh.t("stack2" in resizes, "stack2 resized");
-					doh.t("stack3" in resizes, "stack3 resized");
-					doh.t("stack4" in resizes, "stack4 resized");
-					doh.t(isVisible(dojo.byId("stack4")), "stack4 visible");
+					doh.t("stack1" in resizesHash, "stack1 resized");
+					doh.t("stack2" in resizesHash, "stack2 resized");
+					doh.t("stack3" in resizesHash, "stack3 resized");
+					doh.t("stack4" in resizesHash, "stack4 resized");
+					doh.t(helpers.isVisible(dom.byId("stack4")), "stack4 visible");
 				}
 			]);
 
 			doh.register("removeChild", function removeChild(){
-				var container = new dijit.layout.StackContainer({ id: "sc2" });
-				container.addChild(new dijit.layout.ContentPane({
+				var container = new StackContainer({ id: "sc2","aria-label":"sc2" });
+				container.addChild(new ContentPane({
 						id: "rpage1Prog",
 						title: "Page 1",
 						content: "IT WAS the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period, [...]
 				}));
-				container.addChild(new dijit.layout.ContentPane({
+				container.addChild(new ContentPane({
 						id: "rpage2Prog",
 						title: "Page 2",
 						content: "There were a king with a large jaw and a queen with a plain face, on the throne of England; there were a king with a large jaw and a queen with a fair face, on the throne of France. In both countries it was clearer than crystal to the lords of the State preserves of loaves and fishes, that things in general were settled for ever."
 				}));
 				var page3;
-				container.addChild(page3 = new dijit.layout.ContentPane({
+				container.addChild(page3 = new ContentPane({
 						id: "rpage3Prog",
 						title: "Page 3",
 						content: "It was the year of Our Lord one thousand seven hundred and seventy- five. Spiritual revelations were conceded to England at that favoured period, as at this. Mrs. Southcott had recently attained her five-and- twentieth blessed birthday, of whom a prophetic private in the Life Guards had heralded the sublime appearance by announcing that arrangements were made for the swallowing up of London and Westminster. Even the Cock-lane ghost had been laid only a round dozen of year [...]
 				}));
 
-				container.placeAt(dojo.body());
+				container.placeAt(document.body);
 				container.startup();
 				container.selectChild(page3);
 
 				var resizes = 0;
-				dojo.connect(page3, "resize", function(){
+				aspect.after(page3, "resize", function(){
 					resizes++;
-				});
+				}, true);
 				container.removeChild(page3);
 				doh.is(0, resizes, "removing selected child doesn't call resize on it");
 				doh.is(2, container.getChildren().length, "2 children");
@@ -176,31 +252,31 @@
 
 			doh.register("childless startup", function childlessStartup(){
 				// make and start the container without children
-				var container = new dijit.layout.StackContainer({ id: "nssc" },"noChildrenStackContainer");
+				var container = new StackContainer({ id: "nssc", "aria-label":"nssc"},"noChildrenStackContainer");
 				container.startup();
 
 				// monitor _showChild() calls
 				var showChildCalls = {};
-				dojo.connect(container, "_showChild", function(child){
+				aspect.after(container, "_showChild", function(child){
 					showChildCalls[child.id] = (showChildCalls[child.id] || 0) + 1;
-				});
+				}, true);
 
 				// Create and add child
-				var child1 = new dijit.layout.ContentPane({
+				var child1 = new ContentPane({
 					id: "ncsc1",
 					title: "Page 1",
 					content: "IT WAS the best of times, it was the worst of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way -- in short, the period was so far like the present period,  [...]
 				});
 				var resizes = 0;
-				dojo.connect(child1, "resize", function(){
+				aspect.after(child1, "resize", function(){
 					resizes++;
-				});
+				}, true);
 				container.addChild(child1);
 				doh.is(1, resizes, "child1 resized when added");
 				doh.is(1, showChildCalls["ncsc1"], "StackContainer._showChild(child1) called when child added");
 
 				// Add another child
-				container.addChild(new dijit.layout.ContentPane({
+				container.addChild(new ContentPane({
 					id: "ncsc2",
 					title: "Page 2",
 					content: "There were a king with a large jaw and a queen with a plain face, on the throne of England; there were a king with a large jaw and a queen with a fair face, on the throne of France. In both countries it was clearer than crystal to the lords of the State preserves of loaves and fishes, that things in general were settled for ever."
@@ -218,62 +294,93 @@
 				doh.is(resizesBeforeContainerResize + 1, resizes, "child1 resized once more when StackContainer resized");
 				doh.is(1, showChildCalls["ncsc1"], "StackContainer._showChild(child1) not called when StackContainer resized");
 			});
+
+			doh.register("destroy", function destroy(){
+				// destroyRecursive() on a StackController used to get an exception
+				var oldNumWidgets = require("dijit/registry").length;
+				registry.byId("holder").destroyRecursive();
+				var newNumWidgets = require("dijit/registry").length;
+				doh.is(5, oldNumWidgets - newNumWidgets, newNumWidgets + "-" + oldNumWidgets + " destroyed");
+			});
+
+			doh.register("selectChild before startup", function selectBeforeStartup(){
+				var container = new StackContainer({ id: "sbs","aria-label":"sbs" });
+				container.addChild(new ContentPane({
+					id: "sbs1",
+					title: "Page 1",
+					content: "select before startup page 1"
+				}));
+				container.addChild(new ContentPane({
+					id: "sbs2",
+					title: "Page 2",
+					content: "select before startup page 2"
+				}));
+				var page3;
+				container.addChild(page3 = new ContentPane({
+					id: "sbs3",
+					title: "Page 3",
+					content: "select before startup page 3"
+				}));
+
+				container.selectChild(page3);
+				container.placeAt(document.body);
+				container.startup();
+
+				doh.t(helpers.isHidden(dom.byId("sbs1")), "page1 hidden");
+				doh.t(helpers.isHidden(dom.byId("sbs2")), "page2 hidden");
+				doh.t(helpers.isVisible(dom.byId("sbs3")), "page2 visible");
+			});
+
 			doh.run();
 		});
 
-		function selected(page){
-			console.debug("page selected " + page.id);
-			var widget=dijit.byId("myStackContainer");
-			dijit.byId("previous").set("disabled", page.isFirstChild);
-			dijit.byId("next").set("disabled", page.isLastChild);
-			dijit.byId("previous2").set("disabled", page.isFirstChild);
-			dijit.byId("next2").set("disabled", page.isLastChild);
-		}
-		dojo.subscribe("myStackContainer-selectChild", selected);
-
 	</script>
 </head>
 
-<body class="claro">
+<body class="claro" role="main">
+	<script type="dojo/require">
+		registry: "dijit/registry"
+	</script>
+
 	<h1 class="testTitle">A Tale Of Two Cities</h1>
 
-	<button id="previous" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("myStackContainer").back() }'><</button>
-	<span data-dojo-type="dijit.layout.StackController" data-dojo-props='containerId:"myStackContainer"'></span>
-	<button id="next" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("myStackContainer").forward() }'>></button>
+	<button id="previous" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("myStackContainer").back() }'><</button>
+	<span data-dojo-type="dijit/layout/StackController" data-dojo-props='containerId:"myStackContainer"'></span>
+	<button id="next" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("myStackContainer").forward() }'>></button>
 
-	<div id="myStackContainer" data-dojo-type="dijit.layout.StackContainer"
-		data-dojo-props='style:"width: 90%; border: 1px solid #9b9b9b; height: 20em; margin: 0.5em 0 0.5em 0; padding: 0.5em;"'>
-		<p id="page1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"page 1"'>IT WAS the best of times, it <input value="was the worst" /> of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we we [...]
-		<p id="page2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"page 2"'>There were a king with a large jaw and a queen with a plain face, on the throne of England; there were a king with a large jaw and a queen with a fair face, on the throne of <a href="http://www.france.com">France</a>. In both countries it was clearer than crystal to the lords of the State preserves of loaves and fishes, that things in general were settled for ever.</p>
-		<p id="page3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"page 3"'>It was the year of Our Lord one thousand seven hundred and seventy- five. Spiritual revelations were conceded to England at that favoured period, as at this. Mrs. Southcott had recently attained her five-and- twentieth blessed birthday, of whom a prophetic private in the Life Guards had heralded the sublime appearance by announcing that arrangements were made for the swallowing up of London and Wes [...]
+	<div id="myStackContainer" data-dojo-type="dijit/layout/StackContainer"
+		data-dojo-props='style:"width: 90%; border: 1px solid #9b9b9b; height: 20em; margin: 0.5em 0 0.5em 0; padding: 0.5em;","aria-label":"my stack container"'>
+		<p id="page1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"page 1","aria-label":"page1"'>IT WAS the best of times, it <input aria-label="input" value="was the worst" /> of times, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, w [...]
+		<p id="page2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"page 2"'>There were a king with a large jaw and a queen with a plain face, on the throne of England; there were a king with a large jaw and a queen with a fair face, on the throne of <a href="http://www.france.com">France</a>. In both countries it was clearer than crystal to the lords of the State preserves of loaves and fishes, that things in general were settled for ever.</p>
+		<p id="page3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"page 3"'>It was the year of Our Lord one thousand seven hundred and seventy- five. Spiritual revelations were conceded to England at that favoured period, as at this. Mrs. Southcott had recently attained her five-and- twentieth blessed birthday, of whom a prophetic private in the Life Guards had heralded the sublime appearance by announcing that arrangements were made for the swallowing up of London and Wes [...]
 	</div>
 
-	<button id="previous2" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("myStackContainer").back() }'><</button>
-	<span data-dojo-type="dijit.layout.StackController" data-dojo-props='containerId:"myStackContainer"'></span>
-	<button id="next2" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("myStackContainer").forward() }'>></button>
+	<button id="previous2" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("myStackContainer").back() }'><</button>
+	<span data-dojo-type="dijit/layout/StackController" data-dojo-props='containerId:"myStackContainer"'></span>
+	<button id="next2" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("myStackContainer").forward() }'>></button>
 
 
 	<h1 class="testTitle" style="margin-top: 3em;">Embedded layout widgets</h1>
 	<p>This tests having layout widgets embedded in the StackContainer, making sure they render on the hidden pane.</p>
 
-	<button id="previousPR" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("myStackContainerPR").back() }'><</button>
-	<span data-dojo-type="dijit.layout.StackController" data-dojo-props='containerId:"myStackContainerPR"'></span>
-	<button id="nextPR" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("myStackContainerPR").forward() }'>></button>
+	<button id="previousPR" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("myStackContainerPR").back() }'><</button>
+	<span data-dojo-type="dijit/layout/StackController" data-dojo-props='containerId:"myStackContainerPR"'></span>
+	<button id="nextPR" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("myStackContainerPR").forward() }'>></button>
 
-	<div id="myStackContainerPR" data-dojo-type="dijit.layout.StackContainer"
-		data-dojo-props='style:"width: 90%; border: 1px solid #9b9b9b; height: 20em; margin: 0.5em 0 0.5em 0; padding: 0.5em;"'>
-		<div id="page1PR" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"page 1"'>
+	<div id="myStackContainerPR" data-dojo-type="dijit/layout/StackContainer"
+		data-dojo-props='style:"width: 90%; border: 1px solid #9b9b9b; height: 20em; margin: 0.5em 0 0.5em 0; padding: 0.5em;","aria-label":"my stack container PR"'>
+		<div id="page1PR" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"page 1"'>
 			<p>
 				The next pane should have some text, plus two embedded layout widgets, which should
 				appear correctly even though the pane is initially hidden
 			</p>
 		</div>
-		<div id="page2PR" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"page 2", style:"padding: 1em;"'>
+		<div id="page2PR" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"page 2", style:"padding: 1em;"'>
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div id="bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
+			<div id="bc" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -288,7 +395,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -307,8 +414,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div id="tc" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
+			<div id="tc" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"height:200px; width:300px","aria-label":"tc"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -323,7 +430,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -344,16 +451,16 @@
 			</p>
 		</div>
 	</div>
-	<button id="previous2PR" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("myStackContainerPR").back() }'><</button>
-	<span data-dojo-type="dijit.layout.StackController" data-dojo-props='containerId:"myStackContainerPR"'></span>
-	<button id="next2PR" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("myStackContainerPR").forward() }'>></button>
+	<button id="previous2PR" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("myStackContainerPR").back() }'><</button>
+	<span data-dojo-type="dijit/layout/StackController" data-dojo-props='containerId:"myStackContainerPR"'></span>
+	<button id="next2PR" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("myStackContainerPR").forward() }'>></button>
 
 	<h1>Nested StackContainers w/doLayout=false</h1>
 	<p>"hello world" inner text should be visible</p>
-    <div id="stack1" dojoType="dijit.layout.StackContainer" doLayout="false">
-        <div id="stack2" dojoType="dijit.layout.StackContainer" doLayout="false">
-            <div id="stack3" dojoType="dijit.layout.StackContainer" doLayout="false">
-                <div id="stack4" dojoType="dijit.layout.StackContainer" doLayout="false">
+    <div id="stack1" aria-label="stack1" data-dojo-type="dijit/layout/StackContainer" doLayout="false">
+        <div id="stack2" aria-label="stack2" data-dojo-type="dijit/layout/StackContainer" doLayout="false">
+            <div id="stack3" aria-label="stack3" data-dojo-type="dijit/layout/StackContainer" doLayout="false">
+                <div id="stack4" aria-label="stack4" data-dojo-type="dijit/layout/StackContainer" doLayout="false">
                     hello world
                 </div>
             </div>
diff --git a/dijit/tests/layout/TabContainer.html b/dijit/tests/layout/TabContainer.html
index 9dfee31..8f65003 100644
--- a/dijit/tests/layout/TabContainer.html
+++ b/dijit/tests/layout/TabContainer.html
@@ -1,38 +1,34 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>TabContainer DOH Test</title>
 
-	<style>
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-	<script type="text/javascript" src="../helpers.js"></script>
-
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"doh/runner",
+			"dojo/_base/array",
+			"dojo/aspect",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/dom-geometry",
+			"dojo/json",
+			"dojo/_base/lang",
+			"dojo/parser",
+			"dojo/query",
+			"dijit/registry",
+			"dijit/layout/TabContainer",
+			"dijit/layout/ContentPane",
+			"dijit/tests/helpers",
+			"dojo/domReady!"
+		], function(doh, array, aspect, dom, domClass, domGeom, json, lang, parser, query,
+					registry, TabContainer, ContentPane, helpers){
 
-		// create a do nothing, only for test widget
-		dojo.ready(function(){
 
 			doh.register("parse", function(){
-				dojo.parser.parse();
+				return parser.parse();
 			});
 
 			doh.register("creationAndDestruction", [
@@ -43,14 +39,14 @@
 				{
 					name: 'destroyRecursive',
 					runTest: function(t){
-						var num = dijit.registry.length;
+						var num = registry.length;
 	
-						var cp1 = new dijit.layout.ContentPane({title: "test pane 1", closable: true})
-							cp2 = new dijit.layout.ContentPane({title: "test pane 2", href: "doc0.html"})
-							tc = new dijit.layout.TabContainer({
+						var cp1 = new ContentPane({title: "test pane 1", closable: true}),
+							cp2 = new ContentPane({title: "test pane 2", href: "doc0.html"}),
+							tc = new TabContainer({
 								id:"creationAndDestruction",
 								useMenu:true
-							}).placeAt(dojo.body());
+							}).placeAt(document.body);
 
 						var cp2selected = false;
 						cp2.watch("selected", function(){
@@ -63,7 +59,7 @@
 
 						tc.destroyRecursive();
 	
-						t.is(dijit.registry.length, num, "registry length");
+						t.is(registry.length, num, "registry length");
 						t.f(cp2selected, "second pane wasn't temporarily selected");
 					}
 				},
@@ -73,27 +69,27 @@
 				{
 					name: 'destroyDescendants',
 					runTest: function(t){
-						var cp1 = new dijit.layout.ContentPane({
+						var cp1 = new ContentPane({
 								id: "destroyDescendants_pane1",
 								title: "test pane 1",
 								closable: true
 							}),
-							cp2 = new dijit.layout.ContentPane({
+							cp2 = new ContentPane({
 								id: "destroyDescendants_pane2",
 								title: "test pane 2",
 								href: "doc0.html"
 							}),
-							tc = new dijit.layout.TabContainer({
+							tc = new TabContainer({
 								id:"destroyDescendants",
 								useMenu:true
-							}).placeAt(dojo.body());
+							}).placeAt(document.body);
 
 						var cp2selected = false;
 						cp2.watch("selected", function(){
 							cp2selected = true;
 						});
 						var downloadStarted = false;
-						dojo.connect(cp2, "onDownloadStart", function(){
+						cp2.on("downloadstart", function(){
 							downloadStarted = true;
 						});
 
@@ -113,7 +109,7 @@
 				{
 					name: 'checkTabLabels',
 					runTest: function(t){
-						var tabLabels = dojo.query("#tc1 .tabLabel");
+						var tabLabels = query("#tc1 .tabLabel");
 						t.is(4, tabLabels.length);
 					}
 				}
@@ -125,15 +121,15 @@
 				{
 					name: 'add new tab',
 					runTest: function(t){
-						var tc = dijit.byId("tc1");
-						var cp1 = new dijit.layout.ContentPane({
+						var tc = registry.byId("tc1");
+						var cp1 = new ContentPane({
 							id: "newTab1",
 							title: "newTab1",
 							content: "newTab1 content"
 						});
 						tc.addChild(cp1);
 						
-						var tabLabels = dijit.byId("tc1").getChildren();
+						var tabLabels = registry.byId("tc1").getChildren();
 						
 						t.is(5, tabLabels.length, "there are 5 tabs");
 					}
@@ -143,26 +139,26 @@
 				{
 					name: 'addTabsOverflowMenu',
 					runTest: function(t){
-						var tc = dijit.byId("tc1");
+						var tc = registry.byId("tc1");
 						
-						var cp2 = new dijit.layout.ContentPane({
+						var cp2 = new ContentPane({
 							id: "newTab2",
 							title: "newTab2",
 							content: "newTab2 content"
 						});
 						tc.addChild(cp2);
 						
-						var left = dojo.byId("tc1_tablist_leftBtn");
-						var right = dojo.byId("tc1_tablist_rightBtn");						
-						var menu = dojo.byId("tc1_tablist_menuBtn");
+						var left = dom.byId("tc1_tablist_leftBtn");
+						var right = dom.byId("tc1_tablist_rightBtn");
+						var menu = dom.byId("tc1_tablist_menuBtn");
 
 						t.t(left, "verify left scroll button exists");
 						t.t(right, "verify right scroll button exists");
 						t.t(menu, "verify dropdown menu button exists");
 							
-						t.t(isVisible(left), "left scroll button is displayed");
-						t.t(isVisible(right), "right scroll button is displayed");
-						t.t(isVisible(menu), "menu button is displayed");	
+						t.t(helpers.isVisible(left), "left scroll button is displayed");
+						t.t(helpers.isVisible(right), "right scroll button is displayed");
+						t.t(helpers.isVisible(menu), "menu button is displayed");	
 					}
 				}
 			]);
@@ -176,21 +172,21 @@
 					runTest: function(t){
 						var d = new doh.Deferred();
 						
-						var tc = dijit.byId("tc1");
-						var cp = dijit.byId("newTab1");
+						var tc = registry.byId("tc1");
+						var cp = registry.byId("newTab1");
 
 						tc.selectChild(cp);
 						
 						setTimeout(d.getTestCallback(function(){
-							var cpLeft = dojo.byId("tc1_tablist_leftBtn");
-							var left = dojo.position(cpLeft).x + dojo.position(cpLeft).w;
+							var cpLeft = dom.byId("tc1_tablist_leftBtn");
+							var left = domGeom.position(cpLeft).x + domGeom.position(cpLeft).w;
 
-							var cpRight = dojo.byId("tc1_tablist_rightBtn");
-							var right = dojo.position(cpRight).x;
+							var cpRight = dom.byId("tc1_tablist_rightBtn");
+							var right = domGeom.position(cpRight).x;
 
-							var tab = dijit.byId("tc1_tablist_newTab1");
-							var tabLeft = dojo.position(tab.domNode).x;
-							var tabRight = dojo.position(tab.domNode).x + dojo.position(tab.domNode).w;
+							var tab = registry.byId("tc1_tablist_newTab1");
+							var tabLeft = domGeom.position(tab.domNode).x;
+							var tabRight = domGeom.position(tab.domNode).x + domGeom.position(tab.domNode).w;
 								
 							var isTabVisible = ((tabLeft > left) && (tabRight < right));
 							doh.t(isTabVisible, "verify chosen tab is in viewable area");
@@ -205,7 +201,7 @@
 				{
 					name: "initialIcon",
 					runTest: function(t){
-						var cp = dijit.byId("cp4");
+						var cp = registry.byId("cp4");
 						
 						t.is('tab1', innerText(cp.controlButton.containerNode), "tab label");
 						t.is('plusIcon', cp.controlButton.iconClass, "tab icon");
@@ -214,7 +210,7 @@
 				{
 					name: "changeIcon",
 					runTest: function(t){
-						var cp = dijit.byId("cp4");
+						var cp = registry.byId("cp4");
 
 						cp.set({
 							"title": "note",
@@ -228,7 +224,7 @@
 				{
 					name: "noTitle",
 					runTest: function(t){
-						var cp = dijit.byId("cp7");
+						var cp = registry.byId("cp7");
 						t.f(cp.controlButton.showLabel, "an icon exists, but there is no text label");
 					}
 				}
@@ -238,10 +234,10 @@
 				{
 					name: 'changeName',
 					runTest: function(t){
-						var cp = dijit.byId('cpTitle');
+						var cp = registry.byId('cpTitle');
 						cp.set('title', 'newTitle');
 						
-						var title = dojo.query("#tc1_tablist_cpTitle span.tabLabel")[0];
+						var title = query("#tc1_tablist_cpTitle")[0];
 						
 						t.is('newTitle', innerText(title), "the tab's text label has changed");
 					}
@@ -254,15 +250,15 @@
 				{
 					name: 'deleteTab',
 					runTest: function(t){
-						var tc1 = dijit.byId("tc1");
-						var cp = dijit.byId("cpTitle");
+						var tc1 = registry.byId("tc1");
+						var cp = registry.byId("cpTitle");
 						
 
 						// track resizes to cp, removing it from tc1 shouldn't cause a resize call
 						var cpResizes = 0;
-						dojo.connect(cp, "resize", function(){
+						aspect.after(cp, "resize", function(){
 							cpResizes++;
-						});
+						}, true);
 						
 						tc1.removeChild(cp);
 
@@ -271,7 +267,7 @@
 						t.is(5, childPanes.length, "verify there are now only 4 tabs instead of 5");
 						t.t(cp.domNode, "verify that the deleted tab's content pane still exists on the page");
 
-						var label = dojo.byId("#tc1_tablist_cpTitle");
+						var label = dom.byId("#tc1_tablist_cpTitle");
 						t.f(label, "verify that deleted tab's label does not exist");
 
 						t.is(0, cpResizes, "no resize");
@@ -282,24 +278,24 @@
 				{
 					name: 'removedOverflowMenu',
 					runTest: function(t){
-						var tc = dijit.byId("tc3");
+						var tc = registry.byId("tc3");
 						
-						var cp = dijit.byId('cp10');
+						var cp = registry.byId('cp10');
 						tc.removeChild(cp);	
-						cp = dijit.byId('cp9');
+						cp = registry.byId('cp9');
 						tc.removeChild(cp);
-						cp = dijit.byId('cp8');
+						cp = registry.byId('cp8');
 						tc.removeChild(cp);
-						cp = dijit.byId('cp7');
+						cp = registry.byId('cp7');
 						tc.removeChild(cp);			
 						
-						var left = dijit.byId("tc3_tablist_leftBtn").domNode;
-						var right = dijit.byId("tc3_tablist_rightBtn").domNode;
-						var menu = dijit.byId("tc3_tablist_menuBtn").domNode;
+						var left = registry.byId("tc3_tablist_leftBtn").domNode;
+						var right = registry.byId("tc3_tablist_rightBtn").domNode;
+						var menu = registry.byId("tc3_tablist_menuBtn").domNode;
 						
-						t.t(isHidden(left), "left scroll is hidden");
-						t.t(isHidden(right), "right scroll is hidden");
-						t.t(isHidden(menu), "menu is hidden");
+						t.t(helpers.isHidden(left), "left scroll is hidden");
+						t.t(helpers.isHidden(right), "right scroll is hidden");
+						t.t(helpers.isHidden(menu), "menu is hidden");
 					}
 				}
 			]);
@@ -308,8 +304,8 @@
 				{
 					name: "closeTab",
 					runTest: function(t){
-						var cp = dijit.byId("cp6");
-						var cp2 = dijit.byId("cp5");
+						var cp = registry.byId("cp6");
+						var cp2 = registry.byId("cp5");
 						
 						t.t(cp.controlButton.closeButton, "close button is displayed");
 						t.f(cp2.controlButton.closeButton, "close button is not displayed");
@@ -320,7 +316,7 @@
 			doh.register("menu", {
 				name: "menu",
 				runTest: function(t){
-					var tc1 = dijit.byId("tc1"),
+					var tc1 = registry.byId("tc1"),
 						children = tc1.getChildren();
 				
 					// add an icon and change the title just for testing that the icon and label appear in the menu
@@ -329,17 +325,17 @@
 						iconClass: "noteIcon"
 					});
 						
-					var menuBtn = dijit.byId("tc1_tablist_menuBtn");
+					var menuBtn = registry.byId("tc1_tablist_menuBtn");
 					menuBtn.toggleDropDown();
 
-					var menu = dijit.byId("tc1_menu");
-					doh.t(isVisible(menu), "menu exists and is visible");
+					var menu = registry.byId("tc1_menu");
+					doh.t(helpers.isVisible(menu), "menu exists and is visible");
 					doh.is(menu.getChildren().length, children.length, "# of menu children");
 					doh.is("new title", innerText(menu.getChildren()[0].containerNode));
 					doh.is("noteIcon", menu.getChildren()[0].iconClass);
 				},
 				tearDown: function(){
-					var tc1 = dijit.byId("tc1"),
+					var tc1 = registry.byId("tc1"),
 						children = tc1.getChildren();
 
 					children[0].set({
@@ -347,7 +343,7 @@
 						iconClass: ""
 					});
 
-					var menuBtn = dijit.byId("tc1_tablist_menuBtn");
+					var menuBtn = registry.byId("tc1_tablist_menuBtn");
 					menuBtn.closeDropDown();
 				}
 			});
@@ -356,46 +352,46 @@
 				{
 					name: "tabPosition",
 					runTest: function(t){
-						var tc = dijit.byId("tc1");
+						var tc = registry.byId("tc1");
 
 						// top tabs above content
-						var topTabs = dojo.byId("tc1_tablist"),
-							topContent = dojo.query(".dijitTabPaneWrapper", "tc1")[0],
-							topTabsPos = dojo.position(topTabs),
-							topContentPos = dojo.position(topContent);
+						var topTabs = dom.byId("tc1_tablist"),
+							topContent = query(".dijitTabPaneWrapper", "tc1")[0],
+							topTabsPos = domGeom.position(topTabs),
+							topContentPos = domGeom.position(topContent);
 						t.t(topTabsPos.y + topTabsPos.h <= topContentPos.y, "top tabs above content " +
-							dojo.toJson(topTabsPos) + dojo.toJson(topContentPos));
+							json.stringify(topTabsPos) + json.stringify(topContentPos));
 
 						// left tabs to left of content
-						var leftTabs = dojo.byId("leftTabs_tablist"),
-							leftContent = dojo.query(".dijitTabPaneWrapper", "leftTabs")[0],
-							leftTabsPos = dojo.position(leftTabs),
-							leftContentPos = dojo.position(leftContent);
+						var leftTabs = dom.byId("leftTabs_tablist"),
+							leftContent = query(".dijitTabPaneWrapper", "leftTabs")[0],
+							leftTabsPos = domGeom.position(leftTabs),
+							leftContentPos = domGeom.position(leftContent);
 						t.t(leftTabsPos.x + Math.floor(leftTabsPos.w) <= leftContentPos.x, "left tabs before content " +
-							dojo.toJson(leftTabsPos) + dojo.toJson(leftContentPos));
+							json.stringify(leftTabsPos) + json.stringify(leftContentPos));
 
 						// right tabs to right of content
-						var rightTabs = dojo.byId("rightTabs_tablist"),
-							rightContent = dojo.query(".dijitTabPaneWrapper", "rightTabs")[0],
-							rightTabsPos = dojo.position(rightTabs),
-							rightContentPos = dojo.position(rightContent);
+						var rightTabs = dom.byId("rightTabs_tablist"),
+							rightContent = query(".dijitTabPaneWrapper", "rightTabs")[0],
+							rightTabsPos = domGeom.position(rightTabs),
+							rightContentPos = domGeom.position(rightContent);
 						t.t(rightTabsPos.x >= rightContentPos.x + rightContentPos.w, "right tabs after content " +
-							dojo.toJson(rightTabsPos) + dojo.toJson(rightContentPos));
+							json.stringify(rightTabsPos) + json.stringify(rightContentPos));
 
 						// bottom tabs below content
-						var bottomTabs = dojo.byId("bottomTabs_tablist"),
-							bottomContent = dojo.query(".dijitTabPaneWrapper", "bottomTabs")[0],
-							bottomTabsPos = dojo.position(bottomTabs),
-							bottomContentPos = dojo.position(bottomContent);
+						var bottomTabs = dom.byId("bottomTabs_tablist"),
+							bottomContent = query(".dijitTabPaneWrapper", "bottomTabs")[0],
+							bottomTabsPos = domGeom.position(bottomTabs),
+							bottomContentPos = domGeom.position(bottomContent);
 						t.t(bottomTabsPos.y >= bottomContentPos.y + bottomContentPos.h, "bottom tabs below content " +
-							dojo.toJson(bottomTabsPos) + dojo.toJson(bottomContentPos));
+							json.stringify(bottomTabsPos) + json.stringify(bottomContentPos));
 					}
 				},
 				{
 					name: "nested",
 					runTest: function(t){
-						var parent = dijit.byId("tcNestedParent"),
-							child = dijit.byId("tcNestedChild");
+						var parent = registry.byId("tcNestedParent"),
+							child = registry.byId("tcNestedChild");
 
 						t.f(parent.nested, "parent TabContainer is not nested");
 						
@@ -403,35 +399,35 @@
 						t.is(2, children.length, "parent TabContainer has multiple children");
 						
 						t.t(children[1].nested, "second child of parent TabContainer has nested tabs");
-						t.t(dojo.hasClass("tcNestedChild_tablist", "dijitTabContainerTabListNested"), "nested CSS applied");
+						t.t(domClass.contains("tcNestedChild_tablist", "dijitTabContainerTabListNested"), "nested CSS applied");
 						
 						// test that when TabButtons overflow to 2 rows, the content area is reduced
-						parent.selectChild(dijit.byId("tcNestedChild"));
-						var content = dojo.query(".dijitTabPaneWrapper", "tcNestedChild")[0],
-							height0 = dojo.position(content).h;
+						parent.selectChild(registry.byId("tcNestedChild"));
+						var content = query(".dijitTabPaneWrapper", "tcNestedChild")[0],
+							height0 = domGeom.position(content).h;
 
 						var newGrandchildren = [];
 						for(var i=0; i<10; i++){
-							var gc = new dijit.layout.ContentPane({
+							var gc = new ContentPane({
 								title: "additional child #" + i,
 								content: "hello world " + i
 							});
 							newGrandchildren.push(gc);
 							child.addChild(gc);
 						}
-						var height1 = dojo.position(content).h;
+						var height1 = domGeom.position(content).h;
 						doh.t(height1 < height0, "content area size reduced ", height1, height0);
 
 						// and that size increases back when children are removed
-						dojo.forEach(newGrandchildren, dojo.hitch(child, "removeChild"));
-						var height2 = dojo.position(content).h;
+						array.forEach(newGrandchildren, lang.hitch(child, "removeChild"));
+						var height2 = domGeom.position(content).h;
 						doh.is(height0, height2, "after deleting extra children height restored to original");
 					}
 				},
 				{
 					name: "doLayoutFalse",
 					runTest: function(t){
-						var tc = dijit.byId("tcNoLayout");
+						var tc = registry.byId("tcNoLayout");
 						var cps = tc.getChildren();
 
 						tc.selectChild(cps[0]);
@@ -448,7 +444,7 @@
 				{
 					name: "doLayoutTrue",
 					runTest: function(t){
-						var tc = dijit.byId("tc3");
+						var tc = registry.byId("tc3");
 						var cps = tc.getChildren();
 
 						tc.selectChild(cps[0]);
@@ -469,7 +465,7 @@
 	        function addTab(tc){
 				// summary:
 				//		Add a tab to specified TabContainer
-				var cp = new dijit.layout.ContentPane({
+				var cp = new ContentPane({
 					title: 'Tab' + tabId,
 					content: "Contents of Tab " + tabId++
 				});
@@ -478,22 +474,22 @@
 
 			doh.register("empty tab container",[
 				function createEmptyTabContainer(){
-					var emptyTC = new dijit.layout.TabContainer({id:"emptyTC", style:'height:200px;width:500px;'});
-					dojo.place(emptyTC.domNode, dojo.body());
+					var emptyTC = new TabContainer({id:"emptyTC", style:'height:200px;width:500px;'});
+					document.body.appendChild(emptyTC.domNode);
 					emptyTC.startup();
 
 					var children = emptyTC.getChildren();
 					doh.is(0, children.length);
-					doh.t(isVisible(emptyTC));
+					doh.t(helpers.isVisible(emptyTC));
 					
-					var pos = dojo.position(emptyTC.domNode);
+					var pos = domGeom.position(emptyTC.domNode);
 					var heightDiff = 200 - pos.h;
 					var widthDiff = 500 - pos.w;
 					doh.t(-0.01 < heightDiff && heightDiff < 0.01);
 					doh.t(-0.01 < widthDiff && widthDiff < 0.01);
 				},
 				function addTabToEmptyTabContainer(){
-					var tc = dijit.byId("emptyTC");
+					var tc = registry.byId("emptyTC");
 					addTab(tc);							
 
 					var children = tc.getChildren();
@@ -501,10 +497,10 @@
 					doh.is("Tab1", children[0].title);
 					doh.is("Contents of Tab 1", tc.selectedChildWidget.domNode.innerHTML);
 
-					doh.t(isVisible(tc.tablist.containerNode.childNodes[0]));
+					doh.t(helpers.isVisible(tc.tablist.containerNode.childNodes[0]));
 				},
 				function add2ndTabToEmptyTabContainer(){
-					var tc = dijit.byId("emptyTC");
+					var tc = registry.byId("emptyTC");
 					addTab(tc);							
 					tc.selectChild(tc.getChildren()[1]);							
 
@@ -513,10 +509,10 @@
 					doh.is("Tab2", children[1].title);
 					doh.is("Contents of Tab 2", tc.selectedChildWidget.domNode.innerHTML);
 					
-					doh.t(isVisible(tc.tablist.containerNode.childNodes[1]));
+					doh.t(helpers.isVisible(tc.tablist.containerNode.childNodes[1]));
 				},
 				function remove2ndTabToEmptyTabContainer(){
-					var tc = dijit.byId("emptyTC");
+					var tc = registry.byId("emptyTC");
 					tc.removeChild(tc.getChildren()[1]);							
 
 					var children = tc.getChildren();
@@ -529,9 +525,9 @@
 			doh.register("tab label scrolling", [
 				function initialScroll(){
 					// Make sure that tab labels are scrolled so that selected tab visible
-					var tc = dijit.byId("scroll"),
-						tcPos = dojo.position("scroll");
-						labelPos = dojo.position("scroll_tablist_nine");
+					var tc = registry.byId("scroll"),
+						tcPos = domGeom.position("scroll");
+						labelPos = domGeom.position("scroll_tablist_nine");
 					doh.t(tcPos.x < labelPos.x, "tcPos.x (" + tcPos.x + ") < labelPos.x (" + labelPos.x + ")");
 					doh.t(tcPos.x + tcPos.w > labelPos.x + labelPos.w,
 							"tcPos.x (" + tcPos.x + ") + tcPos.w (" + tcPos.w +
@@ -540,11 +536,11 @@
 				function selectATab(){
 					// Make sure that tab labels are scrolled so that selected tab visible
 					var d = new doh.Deferred();
-					var tc = dijit.byId("scroll");
-					tc.selectChild(dijit.byId("one"));
+					var tc = registry.byId("scroll");
+					tc.selectChild(registry.byId("one"));
 					setTimeout(d.getTestCallback(function(){
-						var tcPos = dojo.position("scroll");
-							labelPos = dojo.position("scroll_tablist_one");
+						var tcPos = domGeom.position("scroll");
+							labelPos = domGeom.position("scroll_tablist_one");
 						doh.t(tcPos.x < labelPos.x, "tcPos.x (" + tcPos.x + ") < labelPos.x (" + labelPos.x + ")");
 						doh.t(tcPos.x + tcPos.w > labelPos.x + labelPos.w,
 								"tcPos.x (" + tcPos.x + ") + tcPos.w (" + tcPos.w +
@@ -560,88 +556,88 @@
 	</script>
 
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Dijit layout.TabContainer DOH tests</h1>
 	
-	<div id="tc1" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 300px; height: 100px;" '>
-		<div id="cpTitle" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab1", selected:true'>
+	<div id="tc1" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 300px; height: 100px;","aria-label":"my super label" '>
+		<div id="cpTitle" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab1", selected:true'>
 			Lorem ipsum and all around...
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab2"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab2"'>
 			Lorem ipsum and all around - second...
 		</div>
-		<div id="t3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab3", closable:true'>
+		<div id="t3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab3", closable:true'>
 			Lorem ipsum and all around - third...
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab4", closable:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab4", closable:true'>
 			Lorem ipsum and all around - last...
 		</div>
 	</div>
 	
-	<div id="tc3" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 300px; height: 100px;" '>
-		<div id="cp4" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab1", selected:true, iconClass:"plusIcon"'>
+	<div id="tc3" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 300px; height: 100px;" '>
+		<div id="cp4" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab1", selected:true, iconClass:"plusIcon"'>
 			Lorem ipsum and all around...
 		</div>
-		<div id="cp5" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab2"'>
+		<div id="cp5" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab2"'>
 			 Lorem ipsum and all around - last...
 			<br />
 			<br />
 			<br />
 			Hmmm even more expanding tabs......
 		</div>
-		<div id="cp6" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab3", closable:true'>
+		<div id="cp6" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab3", closable:true'>
 			Lorem ipsum and all around - last...
 		</div>
-		<div id="cp7" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"plus", closable:true, iconClass:"plusIcon", showTitle:false'>
+		<div id="cp7" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"plus", closable:true, iconClass:"plusIcon", showTitle:false'>
 			Lorem ipsum and all around - last...
 		</div>
-		<div id="cp8" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab4", closable:true'>
+		<div id="cp8" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab4", closable:true'>
 			Lorem ipsum and all around - last...
 		</div>
-		<div id="cp9" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab5", closable:true'>
+		<div id="cp9" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab5", closable:true'>
 			Lorem ipsum and all around - last...
 		</div>
-		<div id="cp10" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab6", closable:true'>
+		<div id="cp10" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"tab6", closable:true'>
 			Lorem ipsum and all around - last...
 		</div>
 	</div>
 	
-	<div id="tcNestedParent" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 400px; height: 300px;" '>
-		<div id="tcNestedChild" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Tab 1", nested:true '>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first inner tab", selected:true'>
+	<div id="tcNestedParent" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 400px; height: 300px;" '>
+		<div id="tcNestedChild" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"Tab 1", nested:true '>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first inner tab", selected:true'>
 				Lorem ipsum and all around...
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second inner tab"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second inner tab"'>
 				Lorem ipsum and all around - second...
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last inner tab"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last inner tab"'>
 				Lorem ipsum and all around - last...
 			</div>
 		</div>
-		<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Tab 2", nested:true'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first inner tab", selected:true'>
+		<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"Tab 2", nested:true'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first inner tab", selected:true'>
 				Lorem ipsum and all around...
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second inner tab"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second inner tab"'>
 				Lorem ipsum and all around - second...
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last inner tab"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last inner tab"'>
 				Lorem ipsum and all around - last...
 			</div>
 		</div>
 	</div>
 	
-	<div id="tcNoLayout" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 100%;", doLayout:false'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first tab", selected:true'>
+	<div id="tcNoLayout" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 100%;", doLayout:false'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first tab", selected:true'>
 			Lorem ipsum and all around...
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second tab", closable:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second tab", closable:true'>
 			Lorem ipsum and all around - second...
 			<br />
 			Hmmm expanding tabs......
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last tab"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last tab"'>
 			Lorem ipsum and all around - last...
 			<br />
 			<br />
@@ -651,54 +647,54 @@
 	</div>
 	<br />
 
-	<div id="leftTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 500px; height: 200px;",  tabPosition:"left-h"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first tab", selected:true'>
+	<div id="leftTabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 500px; height: 200px;",  tabPosition:"left-h"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first tab", selected:true'>
 			Left tabs
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second tab", closable:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second tab", closable:true'>
 			Lorem ipsum and all around - second...
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last tab"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last tab"'>
 			Lorem ipsum and all around - last...
 		</div>
 	</div>
 	<br />
 
-	<div id="rightTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 500px; height: 200px;",  tabPosition:"right-h"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first tab", selected:true'>
+	<div id="rightTabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 500px; height: 200px;",  tabPosition:"right-h"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first tab", selected:true'>
 			Right tabs
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second tab", closable:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second tab", closable:true'>
 			Lorem ipsum and all around - second...
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last tab"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last tab"'>
 			Lorem ipsum and all around - last...
 		</div>
 	</div>
 	<br />
 
-	<div id="bottomTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 500px; height: 200px;",  tabPosition:"bottom"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first tab", selected:true'>
+	<div id="bottomTabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 500px; height: 200px;",  tabPosition:"bottom"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My first tab", selected:true'>
 			Bottom tabs
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second tab", closable:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My second tab", closable:true'>
 			Lorem ipsum and all around - second...
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last tab"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"My last tab"'>
 			Lorem ipsum and all around - last...
 		</div>
 	</div>
 
-	<div id="scroll" dojoType="dijit.layout.TabContainer" jsid="scroll" style="width: 300px; height:200px;">
-		<div dojoType="dijit.layout.ContentPane" title="One" jsid="one" id="one">One</div>
-		<div dojoType="dijit.layout.ContentPane" title="Two" jsid="two" id="two">Two</div>
-		<div dojoType="dijit.layout.ContentPane" title="Three" jsid="three" id="three">Three</div>
-		<div dojoType="dijit.layout.ContentPane" title="Four" jsid="four" id="four">Four</div>
-		<div dojoType="dijit.layout.ContentPane" title="Five" jsid="five" id="five">Five</div>
-		<div dojoType="dijit.layout.ContentPane" title="Six" jsid="six" id="six">Six</div>
-		<div dojoType="dijit.layout.ContentPane" title="Seven" jsid="seven" id="seven">Seven</div>
-		<div dojoType="dijit.layout.ContentPane" title="Eight" jsid="eight" id="eight">Eight</div>
-		<div dojoType="dijit.layout.ContentPane" selected="true" title="Nine" jsid="nine" id="nine">Nine</div>
+	<div id="scroll" data-dojo-type="dijit/layout/TabContainer" data-dojo-id="scroll" style="width: 300px; height:200px;">
+		<div data-dojo-type="dijit/layout/ContentPane" title="One" data-dojo-id="one" id="one">One</div>
+		<div data-dojo-type="dijit/layout/ContentPane" title="Two" data-dojo-id="two" id="two">Two</div>
+		<div data-dojo-type="dijit/layout/ContentPane" title="Three" data-dojo-id="three" id="three">Three</div>
+		<div data-dojo-type="dijit/layout/ContentPane" title="Four" data-dojo-id="four" id="four">Four</div>
+		<div data-dojo-type="dijit/layout/ContentPane" title="Five" data-dojo-id="five" id="five">Five</div>
+		<div data-dojo-type="dijit/layout/ContentPane" title="Six" data-dojo-id="six" id="six">Six</div>
+		<div data-dojo-type="dijit/layout/ContentPane" title="Seven" data-dojo-id="seven" id="seven">Seven</div>
+		<div data-dojo-type="dijit/layout/ContentPane" title="Eight" data-dojo-id="eight" id="eight">Eight</div>
+		<div data-dojo-type="dijit/layout/ContentPane" selected="true" title="Nine" data-dojo-id="nine" id="nine">Nine</div>
 	</div>
 
 </body>
diff --git a/dijit/tests/layout/TabContainerTitlePane.html b/dijit/tests/layout/TabContainerTitlePane.html
index 2cc6766..f0dcbb3 100644
--- a/dijit/tests/layout/TabContainerTitlePane.html
+++ b/dijit/tests/layout/TabContainerTitlePane.html
@@ -1,37 +1,33 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>TabContainer Nested TitlePane Test</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
+	<script src="../boilerplate.js"></script>
 
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: false"></script>
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/aspect",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/layout/TabContainer",
+			"dijit/layout/ContentPane",
+			"dijit/TitlePane",
+			"dojo/domReady!"
+		], function(doh, aspect, parser,
+					registry, TabContainer, ContentPane, TitlePane, helpers){
 
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
 
-	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.TitlePane");
+			var resized = {};
 
-		var resized = {};
 
-		dojo.ready(function(){
-			dojo.connect(dijit.layout.TabContainer.prototype, "resize", function(){
+			aspect.after(TabContainer.prototype, "resize", function(){
 				resized[this.id] = true;
 			});
-			dojo.parser.parse(dojo.body());
+
+			parser.parse();
 
 			// Tests that TabContainer.resize() (for the TabContainers nested in TitlePanes)
 			// is called at the right time.
@@ -49,7 +45,7 @@
 					name: "subtabs2",
 					runTest: function(t){
 						// Since TitlePane 2 is open, subtabs2 should get a resize when tab2 is selected
-						dijit.byId("mainTabContainer").selectChild(dijit.byId("tab2"));
+						registry.byId("mainTabContainer").selectChild(registry.byId("tab2"));
 						doh.t(resized["subtabs2"], "subtabs2");
 						doh.f(resized["subtabs3"], "subtabs3");
 					}
@@ -59,9 +55,9 @@
 					runTest: function(t){
 						// Since TitlePane 3 is closed, subtabs3 shouldn't get a resize until tab3 is selected
 						// and TitlePane is open
-						dijit.byId("mainTabContainer").selectChild(dijit.byId("tab3"));
+						registry.byId("mainTabContainer").selectChild(registry.byId("tab3"));
 						doh.f(resized["subtabs3"], "subtabs3 not sized yet");
-						dijit.byId("tp3").set("open", true);
+						registry.byId("tp3").set("open", true);
 						doh.t(resized["subtabs3"], "subtabs3 sized");
 					}
 				}
@@ -73,55 +69,55 @@
 	</script>
 
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Dijit layout.TabContainer nested TitlePane tests</h1>
 
-	<div id="mainTabContainer" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 100%; height: 150px;"'>
+	<div id="mainTabContainer" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 100%; height: 150px;"'>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id: "tab1", title:"Tab 1"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id: "tab1", title:"Tab 1"'>
 			<h1>I am tab 1</h1>
-			<div data-dojo-type="dijit.TitlePane" data-dojo-props='id: "tp1", title:"Title pane 1", style:{width:"300px"}'>
+			<div data-dojo-type="dijit/TitlePane" data-dojo-props='id: "tp1", title:"Title pane 1", style:{width:"300px"}'>
 				<p>This is a title pane, containing another tab container ...</p>
 				<p>
 					Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus pulvinar orci, sed vestibulum urna sem ut pede. More Ipsum...
 				</p>
-				<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='id: "subtabs1", style:"width: 100%; height: 150px;"'>
-					<div id="tab1_1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
-					<div id="tab1_2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+				<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='id: "subtabs1", style:"width: 100%; height: 150px;"'>
+					<div id="tab1_1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+					<div id="tab1_2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 				</div>
 			</div>
 		</div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id: "tab2", title:"Tab 2"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id: "tab2", title:"Tab 2"'>
 			<h1>I am tab 2</h1>
-			<div data-dojo-type="dijit.TitlePane" data-dojo-props='id: "tp2", title:"Title pane 2", style:{width:"300px"}'>
+			<div data-dojo-type="dijit/TitlePane" data-dojo-props='id: "tp2", title:"Title pane 2", style:{width:"300px"}'>
 				<p>This is a title pane, containing another tab container ...</p>
 				<p>
 					Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus pulvinar orci, sed vestibulum urna sem ut pede. More Ipsum...
 				</p>
-				<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='id: "subtabs2", style:"width: 100%; height: 150px;"'>
-					<div id="tab2_1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
-					<div id="tab2_2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+				<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='id: "subtabs2", style:"width: 100%; height: 150px;"'>
+					<div id="tab2_1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+					<div id="tab2_2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 				</div>
 			</div>
 		</div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id: "tab3", title:"Tab 3"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id: "tab3", title:"Tab 3"'>
 			<h1>I am tab 3</h1>
-			<div data-dojo-type="dijit.TitlePane" data-dojo-props='id: "tp3", title:"Title pane 3", style:{width:"300px"}, open: false'>
+			<div data-dojo-type="dijit/TitlePane" data-dojo-props='id: "tp3", title:"Title pane 3", style:{width:"300px"}, open: false'>
 				<p>This is a title pane, containing another tab container ...</p>
 				<p>
 					Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus pulvinar orci, sed vestibulum urna sem ut pede. More Ipsum...
 				</p>
-				<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='id: "subtabs3", style:"width: 100%; height: 150px;"'>
-					<div id="tab3_1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
-					<div id="tab3_2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+				<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='id: "subtabs3", style:"width: 100%; height: 150px;"'>
+					<div id="tab3_1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+					<div id="tab3_2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 				</div>
 			</div>
 		</div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id: "hrefTab", href:"tab2.html", title:"Href Tab"'></div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id: "hrefTab", href:"tab2.html", title:"Href Tab"'></div>
 	</div>
 
 	<h3>Rendering time</h3>
diff --git a/dijit/tests/layout/borderContainer.php b/dijit/tests/layout/borderContainer.php
index 661af12..c4774d1 100644
--- a/dijit/tests/layout/borderContainer.php
+++ b/dijit/tests/layout/borderContainer.php
@@ -7,7 +7,7 @@
 
 	// sized=true means that it will add a width/height to the BorderContainer
 ?>
-<div data-dojo-type="dijit.layout.BorderContainer"
+<div data-dojo-type="dijit/layout/BorderContainer"
 	id="<?php echo $id?>BorderContainer"
 	<?php
 		if($_GET['sized']){
@@ -15,20 +15,20 @@
 		}
 	?>
 >
-	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width: 200px;"'>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width: 200px;"'>
 		This file contains a single top-level BorderContainer layout widget.
 	</div>
-	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", onLoad:myOnLoad'>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center", onLoad:myOnLoad'>
 		But it also has some nested layout widgets, and when this file is loaded the TabContainer and
 		BorderContainer below should get resize() called on them
-		<div data-dojo-type="dijit.layout.TabContainer" id="<?php echo $id?>InnerTabContainer"
-			data-dojo-props='style:"width: 300px; height: 300px;"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'><?php echo $id?> tab1</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'><?php echo $id?> tab2</div>
+		<div data-dojo-type="dijit/layout/TabContainer" id="<?php echo $id?>InnerTabContainer"
+			data-dojo-props='style:"width: 300px; height: 300px;","aria-label":"<?php echo $id ?>"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'><?php echo $id?> tab1</div>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'><?php echo $id?> tab2</div>
 		</div>
-		<div data-dojo-type="dijit.layout.BorderContainer" id="<?php echo $id?>InnerBorderContainer"
-			data-dojo-props='style:"width: 300px; height: 300px;"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>inner border container</div>
+		<div data-dojo-type="dijit/layout/BorderContainer" id="<?php echo $id?>InnerBorderContainer"
+			data-dojo-props='style:"width: 300px; height: 300px;","aria-label":"<?php echo $id ?>"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>inner border container</div>
 		</div>
 	</div>
 </div>
diff --git a/dijit/tests/layout/combotab.html b/dijit/tests/layout/combotab.html
index 47fa563..7c4bf59 100644
--- a/dijit/tests/layout/combotab.html
+++ b/dijit/tests/layout/combotab.html
@@ -1,9 +1,9 @@
-<div data-dojo-id="stateStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"../_data/states.json"'></div>
+<div data-dojo-id="stateStore" data-dojo-type="dojo/data/ItemFileReadStore" data-dojo-props='url:"../_data/states.json"'></div>
 State:
-<span id="editable" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.ComboBox",
+<span id="editable" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/ComboBox",
 	editorParams:{value: "California", store: stateStore, searchAttr: "name", promptMessage: "Please enter a state"}'>
 	<script type="dojo/connect" data-dojo-event="onChange">
-		// connect to editable onChange event, Note that we dont need to disconnect
+		// connect to editable onChange event, Note that we don't need to disconnect
 		console.log('User selected:'+this.getValue());
 	</script>
 </span>
diff --git a/dijit/tests/layout/doc0.html b/dijit/tests/layout/doc0.html
index 6317194..f77bdc7 100644
--- a/dijit/tests/layout/doc0.html
+++ b/dijit/tests/layout/doc0.html
@@ -2,13 +2,13 @@
 This document has <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 (to check we're copying children around properly).<br />
 Plus some widgets and native fields:<br />
-<input value="native input"/>
-<select data-dojo-type="dijit.form.ComboBox">
+<input value="native input" aria-label="native input" />
+<select data-dojo-type="dijit/form/ComboBox" aria-label="select box doc 0">
 	<option value="1">dijit</option>
 	<option value="2">form</option>
 	<option value="3">ComboBox</option>
 </select>
 <button>native button</button>
-<button data-dojo-type="dijit.form.Button">dijit.Button</button><br>
+<button data-dojo-type="dijit/form/Button">dijit/form/Button</button><br>
 
 Here's some text that comes AFTER the button.
diff --git a/dijit/tests/layout/doc3.html b/dijit/tests/layout/doc3.html
new file mode 100644
index 0000000..32206d6
--- /dev/null
+++ b/dijit/tests/layout/doc3.html
@@ -0,0 +1,2 @@
+<!-- Used by ContentPane-auto-require.html -->
+<button type="button" data-dojo-type="dijit/form/Button" id="button1">Click Me!</button>
diff --git a/dijit/tests/layout/getResponse.php b/dijit/tests/layout/getResponse.php
index 2d3e0ad..ab79b4d 100644
--- a/dijit/tests/layout/getResponse.php
+++ b/dijit/tests/layout/getResponse.php
@@ -24,11 +24,11 @@
 				$delay = 2;
 				break;
 			case 1:
-				echo "<div data-dojo-type='dijit.TestWidget'>Testing attr('href', ...)</div>";
+				echo "<div data-dojo-type='TestWidget'>Testing attr('href', ...)</div>";
 				break;
 			case 2:
-				echo "<div data-dojo-type='dijit.TestWidget'>Delayed attr('href', ...) test</div>
-					  <div data-dojo-type='dijit.TestWidget'>Delayed by " . ($delay/1000000) . " sec.</div>";
+				echo "<div data-dojo-type='TestWidget'>Delayed attr('href', ...) test</div>
+					  <div data-dojo-type='TestWidget'>Delayed by " . ($delay/1000000) . " sec.</div>";
 				break;
 			case 3:
 				echo "IT WAS the best of times, it was the worst of <a id='timeref' href='http://www.timeanddate.com/worldclock/'>times</a>, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way [...]
diff --git a/dijit/tests/layout/mobile.html b/dijit/tests/layout/mobile.html
index de48775..a278659 100644
--- a/dijit/tests/layout/mobile.html
+++ b/dijit/tests/layout/mobile.html
@@ -1,5 +1,5 @@
 <!DOCTYPE>
-<html>
+<html lang="en">
 	<head>
 		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 		<meta name="apple-mobile-web-app-capable" content="yes" />
@@ -11,24 +11,24 @@
 
 		<script language="JavaScript" type="text/javascript">
 			require([
-				"dojo/_base/kernel",
-				"dijit",
 				"dojo/parser",
 
-				"dijit/layout/ContentPane",
+				// Modules that the parser will automatically pull in, but put here to avoid spurious exceptions
 				"dijit/layout/AccordionContainer",
 				"dijit/layout/BorderContainer",
+				"dijit/layout/ContentPane",
 				"dijit/layout/TabContainer",
+
 				"dojo/domReady!"
-			], function(dojo, dijit){
-				dojo.parser.parse();
+			], function(parser){
+				parser.parse();
 			});
 		</script>
 	</head>
-	<body class="claro">
+	<body class="claro" role="main">
 		<h1>Accordion</h1>
-		<div id="ac" data-dojo-type="dijit.layout.AccordionContainer" style="height: 300px">
-			<div id="acp1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true,
+		<div id="ac" data-dojo-type="dijit/layout/AccordionContainer" style="height: 300px">
+			<div id="acp1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='selected:true,
 				title:"Pane 1", iconClass:"dijitEditorIcon dijitEditorIconSave", tooltip:"tooltip for simple pane" '>
 				<p>
 					Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
@@ -41,10 +41,10 @@
 					quam.
 				</p>
 			</div>
-			<div id="acp2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='
+			<div id="acp2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='
 					title:"Pane 2", iconClass:"dijitEditorIcon dijitEditorIconSave", tooltip:"tooltip for simple pane" '>
 				<p>
-					Sed arcu magna, molestie at, <input value="fringilla in, sodales"/> fringilla in, sodales eu, elit.
+					Sed arcu magna, molestie at, <input aria-label="fringilla" value="fringilla in, sodales"/> fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
 					augue. Integer fermentum odio lobortis odio. Nullam mollis nisl non
@@ -63,8 +63,8 @@
 
 
 		<h1>BorderContainer</h1>
-		<div id="bc" data-dojo-type="dijit.layout.BorderContainer" style="height: 200px; width: 100%">
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:50%", splitter:true'>
+		<div id="bc" data-dojo-type="dijit/layout/BorderContainer" style="height: 200px; width: 100%">
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width:50%", splitter:true'>
 				1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -79,7 +79,7 @@
 				sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 				ut eros sit amet ante pharetra interdum.
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 				2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -97,8 +97,8 @@
 		</div>
 
 		<h1>TabContainer</h1>
-		<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
+		<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"height:200px"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'>
 				1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -113,7 +113,7 @@
 				sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 				ut eros sit amet ante pharetra interdum.
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>
 				2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -128,13 +128,13 @@
 				sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 				ut eros sit amet ante pharetra interdum.
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 3"' closable=true>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 3"' closable=true>
 				Tab 3 contents
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 4"' closable=true>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 4"' closable=true>
 				Tab 4 contents
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 5"' closable=true>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 5"' closable=true>
 				Tab 5 contents
 			</div>
 		</div>
diff --git a/dijit/tests/layout/module.js b/dijit/tests/layout/module.js
index 2fc2acc..8f0aaeb 100644
--- a/dijit/tests/layout/module.js
+++ b/dijit/tests/layout/module.js
@@ -1,34 +1,34 @@
-dojo.provide("dijit.tests.layout.module");
+define(["doh/main", "require"], function(doh, require){
 
-try{
-	doh.registerUrl("dijit.tests.layout.ContentPane", dojo.moduleUrl("dijit", "tests/layout/ContentPane.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.test_ContentPane", dojo.moduleUrl("dijit", "tests/layout/test_ContentPane.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.ContentPaneLayout", dojo.moduleUrl("dijit", "tests/layout/ContentPaneLayout.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.ContentPane-remote", dojo.moduleUrl("dijit","tests/layout/ContentPane-remote.html"), 999999);
+	doh.register("layout.ContentPane", require.toUrl("./ContentPane.html"), 999999);
+	doh.register("layout.test_ContentPane", require.toUrl("./test_ContentPane.html"), 999999);
+	doh.register("layout.ContentPaneLayout", require.toUrl("./ContentPaneLayout.html"), 999999);
+	doh.register("layout.ContentPane-remote", require.toUrl("./ContentPane-remote.html"), 999999);
+	doh.register("layout.ContentPane-auto-require", require.toUrl("./ContentPane-auto-require.html"), 999999);
 
-	doh.registerUrl("dijit.tests.layout.robot.GUI", dojo.moduleUrl("dijit","tests/layout/robot/GUI.html"), 999999);
+	doh.register("layout.robot.GUI", require.toUrl("./robot/GUI.html"), 999999);
 
-	doh.registerUrl("dijit.tests.layout.LayoutContainer", dojo.moduleUrl("dijit", "tests/layout/LayoutContainer.html"), 999999);
+	doh.register("layout.LayoutContainer_v1", require.toUrl("./LayoutContainer_v1.html"), 999999);
+	doh.register("layout.LayoutContainer", require.toUrl("./LayoutContainer.html"), 999999);
 
-	doh.registerUrl("dijit.tests.layout.StackContainer", dojo.moduleUrl("dijit", "tests/layout/StackContainer.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.NestedStackContainer", dojo.moduleUrl("dijit", "tests/layout/nestedStack.html"), 999999);
+	doh.register("layout.StackContainer", require.toUrl("./StackContainer.html"), 999999);
+	doh.register("layout.NestedStackContainer", require.toUrl("./nestedStack.html"), 999999);
 
-	doh.registerUrl("dijit.tests.layout.TabContainer", dojo.moduleUrl("dijit", "tests/layout/TabContainer.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.robot.TabContainer_a11y", dojo.moduleUrl("dijit","tests/layout/robot/TabContainer_a11y.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.robot.TabContainer_mouse", dojo.moduleUrl("dijit","tests/layout/robot/TabContainer_mouse.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.robot.TabContainer_noLayout", dojo.moduleUrl("dijit","tests/layout/robot/TabContainer_noLayout.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.TabContainerTitlePane", dojo.moduleUrl("dijit","tests/layout/TabContainerTitlePane.html"), 999999);
+	doh.register("layout.TabContainer", require.toUrl("./TabContainer.html"), 999999);
+	doh.register("layout.robot.TabContainer_a11y", require.toUrl("./robot/TabContainer_a11y.html"), 999999);
+	doh.register("layout.robot.TabContainer_mouse", require.toUrl("./robot/TabContainer_mouse.html"), 999999);
+	doh.register("layout.robot.TabContainer_noLayout", require.toUrl("./robot/TabContainer_noLayout.html"), 999999);
+	doh.register("layout.TabContainerTitlePane", require.toUrl("./TabContainerTitlePane.html"), 999999);
 	
-	doh.registerUrl("dijit.tests.layout.AccordionContainer", dojo.moduleUrl("dijit", "tests/layout/AccordionContainer.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.robot.AccordionContainer_a11y", dojo.moduleUrl("dijit","tests/layout/robot/AccordionContainer_a11y.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.robot.AccordionContainer_mouse", dojo.moduleUrl("dijit","tests/layout/robot/AccordionContainer_mouse.html"), 999999);
-
-	doh.registerUrl("dijit.tests.layout.BorderContainer", dojo.moduleUrl("dijit", "tests/layout/BorderContainer.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.robot.BorderContainer", dojo.moduleUrl("dijit", "tests/layout/robot/BorderContainer.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.robot.BorderContainer_full", dojo.moduleUrl("dijit", "tests/layout/robot/BorderContainer_full.html"), 999999);
-	doh.registerUrl("dijit.tests.layout.robot.BorderContainer_complex", dojo.moduleUrl("dijit", "tests/layout/robot/BorderContainer_complex.html"), 999999);
-
-	doh.registerUrl("dijit.tests.layout.robot.BorderContainer_nested", dojo.moduleUrl("dijit", "tests/layout/robot/BorderContainer_nested.html"), 999999);
-}catch(e){
-	doh.debug(e);
-}
+	doh.register("layout.AccordionContainer", require.toUrl("./AccordionContainer.html"), 999999);
+	doh.register("layout.robot.AccordionContainer_a11y", require.toUrl("./robot/AccordionContainer_a11y.html"), 999999);
+	doh.register("layout.robot.AccordionContainer_mouse", require.toUrl("./robot/AccordionContainer_mouse.html"), 999999);
+
+	doh.register("layout.BorderContainer", require.toUrl("./BorderContainer.html"), 999999);
+	doh.register("layout.robot.BorderContainer", require.toUrl("./robot/BorderContainer.html"), 999999);
+	doh.register("layout.robot.BorderContainer_full", require.toUrl("./robot/BorderContainer_full.html"), 999999);
+	doh.register("layout.robot.BorderContainer_complex", require.toUrl("./robot/BorderContainer_complex.html"), 999999);
+
+	doh.register("layout.robot.BorderContainer_nested", require.toUrl("./robot/BorderContainer_nested.html"), 999999);
+
+});
diff --git a/dijit/tests/layout/multipleLayoutWidgets.php b/dijit/tests/layout/multipleLayoutWidgets.php
index c899dd0..016832b 100644
--- a/dijit/tests/layout/multipleLayoutWidgets.php
+++ b/dijit/tests/layout/multipleLayoutWidgets.php
@@ -5,10 +5,10 @@
 ?>
 This file has some nested layout widgets, and when this file is loaded the TabContainer and
 BorderContainer below should get resize() called on them
-<div data-dojo-type="dijit.layout.TabContainer" id="<?php echo $id ?>TabContainer" data-dojo-props='style:"width: 300px; height: 300px;"'>
-	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>doc4 tab1</div>
-	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>doc4 tab2</div>
+<div data-dojo-type="dijit/layout/TabContainer" id="<?php echo $id ?>TabContainer" data-dojo-props='style:"width: 300px; height: 300px;","aria-label":"<?php echo $id ?>"'>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'>doc4 tab1</div>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>doc4 tab2</div>
 </div>
-<div data-dojo-type="dijit.layout.BorderContainer" id="<?php echo $id ?>BorderContainer" data-dojo-props='style:"width: 300px; height: 300px;"'>
-	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>inner border container</div>
+<div data-dojo-type="dijit/layout/BorderContainer" id="<?php echo $id ?>BorderContainer" data-dojo-props='style:"width: 300px; height: 300px;","aria-label":"<?php echo $id ?>"'>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>inner border container</div>
 </div>
diff --git a/dijit/tests/layout/nestedStack.html b/dijit/tests/layout/nestedStack.html
index 0f9f248..3bd12da 100644
--- a/dijit/tests/layout/nestedStack.html
+++ b/dijit/tests/layout/nestedStack.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
@@ -11,184 +11,188 @@
 			data-dojo-config="isDebug: true">
 	</script>
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojo.parser");
-		dojo.require("dijit.layout._LayoutWidget");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.StackContainer");
-		dojo.require("dijit.layout.StackController");
-		dojo.require("dijit.form.Button");
+		require([
+			"doh/runner",
+			"dojo/_base/declare",
+			"dojo/dom-geometry",
+			"dojo/dom-style",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/form/Button",
+			"dijit/layout/_LayoutWidget",
+			"dijit/layout/ContentPane",
+			"dijit/layout/StackContainer",
+			"dijit/layout/StackController",
+			"dijit/layout/TabContainer",
+			"dojo/domReady!"
+		], function(doh, declare, domGeom, domStyle, parser, registry, _LayoutWidget){
 
-		// This keeps track of which panes were resized, and their hidden/visible state
-		// when they were resized.
-		var resizeLog = {};
+			// This keeps track of which panes were resized, and their hidden/visible state
+			// when they were resized.
+			var resizeLog = {};
 
-		// This keeps track of how many times each pane was resized
-		var resizeCnt = {};
+			// This keeps track of how many times each pane was resized
+			var resizeCnt = {};
 
-		function onResize(widget){
-			// called when a ContentPane or TabContainer is resized
-			console.log("resize on " + widget.id + ", display is " + dojo.style(widget.domNode, "display"));
-			resizeLog[widget.id] = dojo.style(widget.domNode, "style");
-			resizeCnt[widget.id] = (resizeCnt[widget.id] || 0) + 1;
-		}
-	
-		dojo.ready(function(){
-			dojo.declare("dijit.TestLayoutContained",
-				dijit.layout._LayoutWidget, {
-					startup: function(){
-						this.inherited(arguments);
-						this._started = true;
-					},
-					resize: function(){
-						this.inherited(arguments);
-						this._contentBox = dojo.contentBox(this.domNode);
-						this._resized = true;
-					}
+			onResize = function(widget){
+				// called when a ContentPane or TabContainer is resized
+				console.log("resize on " + widget.id + ", display is " + domStyle.get(widget.domNode, "display"));
+				resizeLog[widget.id] = domStyle.get(widget.domNode, "style");
+				resizeCnt[widget.id] = (resizeCnt[widget.id] || 0) + 1;
+			};
+
+			declare("TestLayoutContained", _LayoutWidget, {
+				startup: function(){
+					this.inherited(arguments);
+					this._started = true;
+				},
+				resize: function(){
+					this.inherited(arguments);
+					this._contentBox = domGeom.getContentBox(this.domNode);
+					this._resized = true;
 				}
-			);
+			});
 
 			doh.register("parse", function(){
-				dojo.parser.parse();
+				parser.parse();
 			});
 
-			doh.registerGroup("after load",
-				[
-					{
-						name: "TabContainer 1 visible and resized",
-						runTest: function(t){
-							doh.is(1, resizeCnt["tab1"], "TabContainer 1 was resized once");
-							doh.is("block", dojo.style(dijit.byId("tab1").domNode, "display"), "TabContainer 1 is visible");
-							doh.t(resizeLog["tab1"] != "none", "TabContainer 1 was visible when it was resized");
-						}
-					},
-					{
-						name: "TabContainer 1 content pane 1 visible and resized",
-						runTest: function(t){
-							doh.is(1, resizeCnt["tab1cp1"], "Tab 1 was resized once");
-							doh.is("block", dojo.style(dijit.byId("tab1cp1").domNode, "display"), "TabContainer1 Tab 1 is visible");
-							doh.t(resizeLog["tab1cp1"] != "none", "Tab 1 was visible when it was resized");
-						}
-					},
-					{
-						name: "TabContainer 1 content pane 2 hidden",
-						runTest: function(t){
-							doh.f(!"tab1cp2" in resizeCnt, "tab 2 hasn't been resized");
-							doh.is("none", dojo.style(dijit.byId("tab1cp2").domNode, "display"), "TabContainer1 Tab 2 is hidden");
-						}
-					},
-					{
-						name: "TabContainer 2 hidden and unsized",
-						runTest: function(t){
-							doh.f(!"tab2" in resizeCnt, "TabContainer 2 hasn't been resized");
-							doh.is("none", dojo.style(dijit.byId("tab2").domNode, "display"), "TabContainer 2 is hidden");
-						}
-					},
-					{
-						name: "TabContainer 2 content pane 1 unsized",
-						runTest: function(t){
-							doh.f(!"tab2cp1" in resizeCnt, "TabContainer 2 tab 1 hasn't been resized");
-						}
+			doh.registerGroup("after load", [
+				{
+					name: "TabContainer 1 visible and resized",
+					runTest: function(t){
+						doh.is(1, resizeCnt["tab1"], "TabContainer 1 was resized once");
+						doh.is("block", domStyle.get(registry.byId("tab1").domNode, "display"), "TabContainer 1 is visible");
+						doh.t(resizeLog["tab1"] != "none", "TabContainer 1 was visible when it was resized");
+					}
+				},
+				{
+					name: "TabContainer 1 content pane 1 visible and resized",
+					runTest: function(t){
+						doh.is(1, resizeCnt["tab1cp1"], "Tab 1 was resized once");
+						doh.is("block", domStyle.get(registry.byId("tab1cp1").domNode, "display"), "TabContainer1 Tab 1 is visible");
+						doh.t(resizeLog["tab1cp1"] != "none", "Tab 1 was visible when it was resized");
+					}
+				},
+				{
+					name: "TabContainer 1 content pane 2 hidden",
+					runTest: function(t){
+						doh.f(!"tab1cp2" in resizeCnt, "tab 2 hasn't been resized");
+						doh.is("none", domStyle.get(registry.byId("tab1cp2").domNode.parentNode, "display"), "TabContainer1 Tab 2 is hidden");
 					}
-				]);
-			doh.registerGroup("selecting TabContainer 2",
-				[
-					function setUp(){
-						dijit.byId("myStackContainerPR").selectChild("tab2");
-					},
-					{
-						name: "TabContainer 1 hidden",
-						runTest: function(t){
-							doh.is("none", dojo.style(dijit.byId("tab1").domNode, "display"), "TabContainer1 is hidden");
-						}
-					},
-					{
-						name: "TabContainer 2 visible and resized",
-						runTest: function(t){
-							doh.is(1, resizeCnt["tab2"], "TabContainer 2 was resized once");
-							doh.is("block", dojo.style(dijit.byId("tab2").domNode, "display"), "TabContainer 2 is visible");
-							doh.t(resizeLog["tab2"] != "none", "TabContainer 2 was visible when it was resized");
-						}
-					},
-					{
-						name: "TabContainer 2 content pane 1 visible and resized",
-						runTest: function(t){
-							doh.is(1, resizeCnt["tab2cp1"], "Tab 2 was resized once");
-							doh.is("block", dojo.style(dijit.byId("tab2cp1").domNode, "display"), "TabContainer2 Tab 1 is visible");
-							doh.t(resizeLog["tab2cp1"] != "none", "Tab 2 was visible when it was resized");
-						}
+				},
+				{
+					name: "TabContainer 2 hidden and unsized",
+					runTest: function(t){
+						doh.f(!"tab2" in resizeCnt, "TabContainer 2 hasn't been resized");
+						doh.is("none", domStyle.get(registry.byId("tab2").domNode.parentNode, "display"), "TabContainer 2 is hidden");
 					}
-				]);
-			doh.registerGroup("resize of ContentPane contents",
-				[
-					{
-						name: "nested layout widgets haven't been resized yet",
-						runTest: function(t){
-							doh.f(deferredOne._resized, "nested layout widget not yet resized");
-						}
-					},
-					{
-						name: "select tab 2 of TabContainer 2",
-						runTest: function(t){
-							dijit.byId("tab2").selectChild("tab2cp2");
-						}
-					},
-					{
-						name: "resize was called on nested layout widgets after tab was made visible",
-						runTest: function(t){
-							doh.is(1, resizeCnt["tab2cp2"], "Tab 2 was resized once");
-							doh.t(deferredOne._resized, "deferredOne nested layout widget was resized");
+				},
+				{
+					name: "TabContainer 2 content pane 1 unsized",
+					runTest: function(t){
+						doh.f(!"tab2cp1" in resizeCnt, "TabContainer 2 tab 1 hasn't been resized");
+					}
+				}
+			]);
 
-							var sizeAtResize = deferredOne._contentBox;
-							doh.t(sizeAtResize.w > 50, "content box has measurable width of " + sizeAtResize.w);
-							doh.t(sizeAtResize.h > 10, "content box has measurable height of " + sizeAtResize.h);
-						}
+			doh.registerGroup("selecting TabContainer 2", [
+				function setUp(){
+					registry.byId("myStackContainerPR").selectChild("tab2");
+				},
+				{
+					name: "TabContainer 1 hidden",
+					runTest: function(t){
+						doh.is("none", domStyle.get(registry.byId("tab1").domNode.parentNode, "display"), "TabContainer1 is hidden");
+					}
+				},
+				{
+					name: "TabContainer 2 visible and resized",
+					runTest: function(t){
+						doh.is(1, resizeCnt["tab2"], "TabContainer 2 was resized once");
+						doh.is("block", domStyle.get(registry.byId("tab2").domNode.parentNode, "display"), "TabContainer 2 is visible");
+						doh.t(resizeLog["tab2"] != "none", "TabContainer 2 was visible when it was resized");
+					}
+				},
+				{
+					name: "TabContainer 2 content pane 1 visible and resized",
+					runTest: function(t){
+						doh.is(1, resizeCnt["tab2cp1"], "Tab 2 was resized once");
+						doh.is("block", domStyle.get(registry.byId("tab2cp1").domNode.parentNode, "display"), "TabContainer2 Tab 1 is visible");
+						doh.t(resizeLog["tab2cp1"] != "none", "Tab 2 was visible when it was resized");
 					}
-				]);
+				}
+			]);
+
+			doh.registerGroup("resize of ContentPane contents", [
+				{
+					name: "nested layout widgets haven't been resized yet",
+					runTest: function(t){
+						doh.f(deferredOne._resized, "nested layout widget not yet resized");
+					}
+				},
+				{
+					name: "select tab 2 of TabContainer 2",
+					runTest: function(t){
+						registry.byId("tab2").selectChild("tab2cp2");
+					}
+				},
+				{
+					name: "resize was called on nested layout widgets after tab was made visible",
+					runTest: function(t){
+						doh.is(1, resizeCnt["tab2cp2"], "Tab 2 was resized once");
+						doh.t(deferredOne._resized, "deferredOne nested layout widget was resized");
+
+						var sizeAtResize = deferredOne._contentBox;
+						doh.t(sizeAtResize.w > 50, "content box has measurable width of " + sizeAtResize.w);
+						doh.t(sizeAtResize.h > 10, "content box has measurable height of " + sizeAtResize.h);
+					}
+				}
+			]);
+
 			doh.run();
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1>Integration: TabContainer in StackContainer</h1>
 	<br>
-	<button id="previousPR" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("myStackContainerPR").back() }'><</button>
-	<span data-dojo-type="dijit.layout.StackController" data-dojo-props='containerId:"myStackContainerPR"'></span>
-	<button id="nextPR" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("myStackContainerPR").forward() }'>></button>
-	<div id="myStackContainerPR" data-dojo-type="dijit.layout.StackContainer"
+	<button id="previousPR" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("myStackContainerPR").back() }'><</button>
+	<span data-dojo-type="dijit/layout/StackController" data-dojo-props='containerId:"myStackContainerPR"'></span>
+	<button id="nextPR" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("myStackContainerPR").forward() }'>></button>
+	<div id="myStackContainerPR" data-dojo-type="dijit/layout/StackContainer"
 		data-dojo-props='style:"height:150px; width: 400px;"'>
-			<div id="tab1" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"tab container 1"'>
+			<div id="tab1" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"tab container 1"'>
 				<script type="dojo/connect" data-dojo-event="resize">
 					onResize(this);
 				</script>
-				<div id="tab1cp1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"TC1/tab1", href:"tab1.html"'>
+				<div id="tab1cp1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"TC1/tab1", href:"tab1.html"'>
 					<script type="dojo/connect" data-dojo-event="resize">
 						onResize(this);
 					</script>
 				</div>
-				<div id="tab1cp2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"TC1/tab2", href:"tab2.html"'>
+				<div id="tab1cp2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"TC1/tab2", href:"tab2.html"'>
 					<script type="dojo/connect" data-dojo-event="resize">
 						onResize(this);
 					</script>
 				</div>
 			</div>
-			<div id="tab2" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"tab container 2"'>
+			<div id="tab2" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"tab container 2"'>
 				<script type="dojo/connect" data-dojo-event="resize">
 					onResize(this);
 				</script>
-				<div id="tab2cp1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"TC2/tab 1", href:"tab1.html"'>
+				<div id="tab2cp1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"TC2/tab 1", href:"tab1.html"'>
 					<script type="dojo/connect" data-dojo-event="resize">
 						onResize(this);
 					</script>
 				</div>
-				<div id="tab2cp2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"TC2/tab 2"'>
+				<div id="tab2cp2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"TC2/tab 2"'>
 					<script type="dojo/connect" data-dojo-event="resize">
 						onResize(this);
 					</script>
 					<div><div>
-						<div data-dojo-id="deferredZero" data-dojo-type="dijit.TestLayoutContained">test nested layout widget</div>
-						<div data-dojo-id="deferredOne" data-dojo-type="dijit.TestLayoutContained">another test nested layout widget</div>
+						<div data-dojo-id="deferredZero" data-dojo-type="TestLayoutContained">test nested layout widget</div>
+						<div data-dojo-id="deferredOne" data-dojo-type="TestLayoutContained">another test nested layout widget</div>
 					</div></div>
 				</div>
 			</div>
diff --git a/dijit/tests/layout/robot/AccordionContainer_a11y.html b/dijit/tests/layout/robot/AccordionContainer_a11y.html
index 4e626b2..477cc91 100644
--- a/dijit/tests/layout/robot/AccordionContainer_a11y.html
+++ b/dijit/tests/layout/robot/AccordionContainer_a11y.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot AccordionContainer A11Y Test</title>
+		<title>robot AccordionContainer A11Y Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
@@ -10,57 +10,60 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx", "dojo/dom", "dojo/keys",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, dom, keys, helpers){
+
+				robot.initRobot('../test_AccordionContainer.html');
+
+				var registry, focus;
+
+				doh.register("setup", [
+					function setup(){
+						// get pointers to singletons loaded on test page
+						registry = robot.window.require("dijit/registry");
+						focus = robot.window.require("dijit/focus");
+					}
+				]);
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_AccordionContainer.html');
 				doh.register("Accordion A11Y tests", [
 					{
 						name: "basic operation",
 						timeout: 10000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							doh.robot.sequence(function(){
-								dojo.byId("beforeMarkupAccordion").focus();
+							robot.sequence(function(){
+								dom.byId("beforeMarkupAccordion").focus();
 							}, 500, 500);
 
 							// Tab into accordion, landing on title of first pane
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(/A Simple Pane/.test(innerText(dojo.global.dijit.focus.curNode)), "tabbed to first pane's title");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(/A Simple Pane/.test(helpers.innerText(focus.curNode)), "tabbed to first pane's title");
 							}), 500);
 
 							// Use down arrow to get to second pane's title
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.f(/A Simple Pane/.test(innerText(dojo.global.dijit.focus.curNode)), "moved away from first pane's title");
-								doh.t(/Lazy Load Pane/.test(innerText(dojo.global.dijit.focus.curNode)), "moved to second pane's title");
-								doh.is("lazyLoadPane", dojo.global.dijit.byId("markupAccordion").get("selectedChildWidget").id, "second pane is now selected");
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.sequence(d.getTestErrback(function(){
+								doh.f(/A Simple Pane/.test(helpers.innerText(focus.curNode)), "moved away from first pane's title");
+								doh.t(/Lazy Load Pane/.test(helpers.innerText(focus.curNode)), "moved to second pane's title");
+								doh.is("lazyLoadPane", registry.byId("markupAccordion").get("selectedChildWidget").id, "second pane is now selected");
 							}), 500);
 
-							// Workaround FF4 bug where overflow:auto panes get focus even when
-							// they don't have a scrollbar, remove when
-							// https://bugzilla.mozilla.org/show_bug.cgi?id=616594 fixed
-							if(dojo.isFF == 4){
-								dojo.query("#lazyLoadPane").style("overflow", "hidden");
-							}
-
 							// Tab into second pane's content area, landing on link inside pane
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("WebA11y", innerText(dojo.global.dijit.focus.curNode), "tabbed into second pane");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(function(){
+								doh.is("WebA11y", helpers.innerText(focus.curNode), "tabbed into second pane");
 							}), 500);
 
 							// tab out of AccordionContainer
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("afterMarkupAccordion", dojo.global.dijit.focus.curNode.id, "tabbed out of accordion");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("afterMarkupAccordion", focus.curNode.id, "tabbed out of accordion");
 							}), 500);
 
 							return d;
diff --git a/dijit/tests/layout/robot/AccordionContainer_mouse.html b/dijit/tests/layout/robot/AccordionContainer_mouse.html
index 9a93c73..d0bf94b 100644
--- a/dijit/tests/layout/robot/AccordionContainer_mouse.html
+++ b/dijit/tests/layout/robot/AccordionContainer_mouse.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot AccordionContainer Mouse Test</title>
+		<title>robot AccordionContainer Mouse Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
@@ -10,16 +10,24 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-			
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_AccordionContainer.html');
+			require([
+				"doh/runner", "dojo/robotx", "dojo/domReady!"
+			], function(doh, robot){
+
+				robot.initRobot('../test_AccordionContainer.html');
+
+				var registry;
+
+				doh.register("setup", [
+					function setup(){
+						// get pointers to singletons loaded on test page
+						registry = robot.window.require("dijit/registry");
+					}
+				]);
+
 				doh.register("Accordion Mouse tests",[
 					{
 						name: "basic operation",
@@ -28,17 +36,17 @@
 							var d = new doh.Deferred();
 
 							// Click open second pane
-							doh.robot.mouseMoveAt("lazyLoadPane_button_title", 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("lazyLoadPane", dojo.global.dijit.byId("markupAccordion").get("selectedChildWidget").id, "second pane is now selected");
+							robot.mouseMoveAt("lazyLoadPane_button_title", 500, 1);
+							robot.mouseClick({left: true}, 500);
+							robot.sequence(d.getTestErrback(function(){
+								doh.is("lazyLoadPane", registry.byId("markupAccordion").get("selectedChildWidget").id, "second pane is now selected");
 							}), 500);
 
 							// Click open fourth pane
-							doh.robot.mouseMoveAt("embeddedLayoutPane_button_title", 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("embeddedLayoutPane", dojo.global.dijit.byId("markupAccordion").get("selectedChildWidget").id, "fourth pane is now selected");
+							robot.mouseMoveAt("embeddedLayoutPane_button_title", 500, 1);
+							robot.mouseClick({left: true}, 500);
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("embeddedLayoutPane", registry.byId("markupAccordion").get("selectedChildWidget").id, "fourth pane is now selected");
 							}), 2000);
 
 							return d;
diff --git a/dijit/tests/layout/robot/BorderContainer.html b/dijit/tests/layout/robot/BorderContainer.html
index 1860e7a..04634b1 100644
--- a/dijit/tests/layout/robot/BorderContainer.html
+++ b/dijit/tests/layout/robot/BorderContainer.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot BorderContainer Test</title>
+		<title>robot BorderContainer Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
@@ -10,17 +10,24 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-		<script type="text/javascript" src="./borderContainerTestFunctions.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx", "dojo/dom", "dojo/dom-geometry", "dojo/keys",
+				"dijit/tests/helpers", "dijit/tests/layout/robot/borderContainerTestFunctions", "dojo/domReady!"
+			], function(doh, robot, dom, geom, keys, helpers, bcTest){
+
+				robot.initRobot('../test_BorderContainer.html');
+
+				var focus;
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_BorderContainer.html');
+				doh.register("setup", [
+					function setup(){
+						// get pointers to singletons loaded on test page
+						focus = robot.window.require("dijit/focus");
+					}
+				]);
 
 				doh.register("mouse", [
 					{
@@ -29,28 +36,28 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							var oTop = dojo.position(dojo.byId("border2-top")),
-								oCenter = dojo.position(dojo.byId("border2-center")),
-								oRight = dojo.position(dojo.byId("border2-trailing")),
-								oBottom = dojo.position(dojo.byId("border2-bottom"));
+							var oTop = geom.position(dom.byId("border2-top")),
+								oCenter = geom.position(dom.byId("border2-center")),
+								oRight = geom.position(dom.byId("border2-trailing")),
+								oBottom = geom.position(dom.byId("border2-bottom"));
 
 							// Drag slider to expand pane 
-							var size = dojo.position("border2-trailing_splitter");
-							doh.robot.mouseMoveAt("border2-trailing_splitter", 500);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("border2-trailing_splitter", 500, 100,
-								size.w/2 + (dojo._isBodyLtr() ? -100 : 100), size.h/2);
-							doh.robot.mouseRelease({left: true}, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
-								var nTop = dojo.position(dojo.byId("border2-top")),
-									nCenter = dojo.position(dojo.byId("border2-center")),
-									nRight = dojo.position(dojo.byId("border2-trailing")),
-									nBottom = dojo.position(dojo.byId("border2-bottom"));
+							var size = geom.position("border2-trailing_splitter");
+							robot.mouseMoveAt("border2-trailing_splitter", 500);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt("border2-trailing_splitter", 500, 100,
+								size.w/2 + (geom.isBodyLtr() ? -100 : 100), size.h/2);
+							robot.mouseRelease({left: true}, 500);
+							robot.sequence(d.getTestCallback(function(){
+								var nTop = geom.position(dom.byId("border2-top")),
+									nCenter = geom.position(dom.byId("border2-center")),
+									nRight = geom.position(dom.byId("border2-trailing")),
+									nBottom = geom.position(dom.byId("border2-bottom"));
 					
-								doh.t(within(oRight.w + 100, nRight.w, 10), "right width went from " + oRight.w + " to " + nRight.w);
-								doh.t(within(oTop.w - 100, nTop.w, 10), "top width went from " + oTop.w + " to " + nTop.w);
-								doh.t(within(oCenter.w - 100, nCenter.w, 10), "center width went from " + oCenter.w + " to " + nCenter.w);
-								doh.t(within(oBottom.w - 100, nBottom.w, 10), "bottom width went from " + nBottom.w + " to " + nBottom.w);
+								doh.t(bcTest.within(oRight.w + 100, nRight.w, 10), "right width went from " + oRight.w + " to " + nRight.w);
+								doh.t(bcTest.within(oTop.w - 100, nTop.w, 10), "top width went from " + oTop.w + " to " + nTop.w);
+								doh.t(bcTest.within(oCenter.w - 100, nCenter.w, 10), "center width went from " + oCenter.w + " to " + nCenter.w);
+								doh.t(bcTest.within(oBottom.w - 100, nBottom.w, 10), "bottom width went from " + nBottom.w + " to " + nBottom.w);
 							}), 500);
 
 							return d;
@@ -62,25 +69,25 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							var oTop = dojo.position(dojo.byId("border2-top")),
-								oCenter = dojo.position(dojo.byId("border2-center")),
-								oRight = dojo.position(dojo.byId("border2-trailing")),
-								oBottom = dojo.position(dojo.byId("border2-bottom"));
+							var oTop = geom.position(dom.byId("border2-top")),
+								oCenter = geom.position(dom.byId("border2-center")),
+								oRight = geom.position(dom.byId("border2-trailing")),
+								oBottom = geom.position(dom.byId("border2-bottom"));
 
 							// Drag slider to shrink pane 
-							var size = dojo.position("border2-bottom_splitter");
-							doh.robot.mouseMoveAt("border2-bottom_splitter", 500);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("border2-bottom_splitter", 500, 100, size.w/2, size.h/2 + 10);
-							doh.robot.mouseRelease({left: true}, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
-								var nTop = dojo.position(dojo.byId("border2-top")),
-									nCenter = dojo.position(dojo.byId("border2-center")),
-									nRight = dojo.position(dojo.byId("border2-trailing")),
-									nBottom = dojo.position(dojo.byId("border2-bottom"));
+							var size = geom.position("border2-bottom_splitter");
+							robot.mouseMoveAt("border2-bottom_splitter", 500);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt("border2-bottom_splitter", 500, 100, size.w/2, size.h/2 + 10);
+							robot.mouseRelease({left: true}, 500);
+							robot.sequence(d.getTestCallback(function(){
+								var nTop = geom.position(dom.byId("border2-top")),
+									nCenter = geom.position(dom.byId("border2-center")),
+									nRight = geom.position(dom.byId("border2-trailing")),
+									nBottom = geom.position(dom.byId("border2-bottom"));
 					
-								doh.t(within(oBottom.h - 10, nBottom.h, 10), "bottom height went from " + oBottom.h + " to " + nBottom.h);
-								doh.t(within(oCenter.h + 10, nCenter.h, 10), "center height went from " + oCenter.h + " to " + nCenter.h);
+								doh.t(bcTest.within(oBottom.h - 10, nBottom.h, 10), "bottom height went from " + oBottom.h + " to " + nBottom.h);
+								doh.t(bcTest.within(oCenter.h + 10, nCenter.h, 10), "center height went from " + oCenter.h + " to " + nCenter.h);
 							}), 500);
 
 							return d;
@@ -89,47 +96,38 @@
 				]);
 
 				doh.register("keyboard", [
-					function setup(){
-						// Workaround FF4 bug where overflow:auto panes get focus even when
-						// they don't have a scrollbar, remove when
-						// https://bugzilla.mozilla.org/show_bug.cgi?id=616594 fixed
-						if(dojo.isFF == 4){
-							dojo.query(".dijitContentPane").style("overflow", "hidden");
-						}
-					},
-
 					{
 						name: "tabIndex",
 						timeout: 10000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							doh.robot.sequence(function(){
-								dojo.byId("toggleLeftButton").focus();
+							robot.sequence(function(){
+								dom.byId("toggleLeftButton").focus();
 							}, 500, 500);
 
 							// Tab into second BorderContainer, landing on link
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("a link", innerText(dojo.global.dijit.focus.curNode), "tabbed to link");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(function(){
+								doh.is("a link", helpers.innerText(focus.curNode), "tabbed to link");
 							}), 500);
 
 							// Tab past ComboBox to get to splitter for bottom panel
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("border2-bottom_splitter", dojo.global.dijit.focus.curNode.id, "focus on bottom splitter");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(function(){
+								doh.is("border2-bottom_splitter", focus.curNode.id, "focus on bottom splitter");
 							}), 500);
 
 							// Tab to get to splitter for right panel
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("border2-trailing_splitter", dojo.global.dijit.focus.curNode.id, "focus on bottom splitter");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(function(){
+								doh.is("border2-trailing_splitter", focus.curNode.id, "focus on bottom splitter");
 							}), 500);
 
 							// tab out of BorderContainer, into the next one
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("a link", innerText(dojo.global.dijit.focus.curNode), "tabbed to link in next BC");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("a link", helpers.innerText(focus.curNode), "tabbed to link in next BC");
 							}), 500);
 
 							return d;
@@ -145,24 +143,24 @@
 							var oSize, nSize;
 
 							// contract bottom pane
-							doh.robot.sequence(function(){
-								dojo.byId("border2-bottom_splitter").focus();
-								oSize = dojo.position("border2-bottom");
+							robot.sequence(function(){
+								dom.byId("border2-bottom_splitter").focus();
+								oSize = geom.position("border2-bottom");
 							}, 500, 500);
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								nSize = dojo.position("border2-bottom");
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.sequence(d.getTestErrback(function(){
+								nSize = geom.position("border2-bottom");
 								doh.t(nSize.h < oSize.h, "contracted bottom pane");
 							}), 500);
 
 							// expand trailing pane
-							doh.robot.sequence(function(){
-								dojo.byId("border2-trailing_splitter").focus();
-								oSize = dojo.position("border2-trailing");
+							robot.sequence(function(){
+								dom.byId("border2-trailing_splitter").focus();
+								oSize = geom.position("border2-trailing");
 							}, 500, 500);
-							doh.robot.keyPress(dojo._isBodyLtr() ? dojo.keys.LEFT_ARROW : dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.sequence(d.getTestCallback(function(){
-								nSize = dojo.position("border2-trailing");
+							robot.keyPress(geom.isBodyLtr() ? keys.LEFT_ARROW : keys.RIGHT_ARROW, 500, {});
+							robot.sequence(d.getTestCallback(function(){
+								nSize = geom.position("border2-trailing");
 								doh.t(nSize.w > oSize.w, "expanded trailing pane");
 							}), 500);
 
diff --git a/dijit/tests/layout/robot/BorderContainer_complex.html b/dijit/tests/layout/robot/BorderContainer_complex.html
index 2132579..aa75a46 100644
--- a/dijit/tests/layout/robot/BorderContainer_complex.html
+++ b/dijit/tests/layout/robot/BorderContainer_complex.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot BorderContainer complex Test</title>
+		<title>robot BorderContainer complex Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
@@ -10,21 +10,29 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-		<script type="text/javascript" src="./borderContainerTestFunctions.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx", "dojo/aspect", "dojo/dom", "dojo/dom-geometry", "dojo/keys",
+				"dijit/tests/helpers", "dijit/tests/layout/robot/borderContainerTestFunctions", "dojo/domReady!"
+			], function(doh, robot, aspect, dom, geom, keys, helpers, bcTest){
+
+				robot.initRobot('../test_BorderContainer_complex.html');
+
+				var registry, focus;
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_BorderContainer_complex.html');
+				doh.register("setup", [
+					function setup(){
+						// get pointers to singletons loaded on test page
+						registry = robot.window.require("dijit/registry");
+						focus = robot.window.require("dijit/focus");
+					}
+				]);
 
 				doh.register("API", [
 					function initialConditions(){
-						checkBCpanes(dijit.byId("border1"));
+						bcTest.checkBCpanes(registry.byId("border1"));
 					}
 				]);
 
@@ -33,12 +41,12 @@
 					{
 						name: "tab2Selected",
 						runTest: function(t){
-							doh.t(dijit.byId("tab2").selected, "tab2 was not selected");
-							doh.f(dijit.byId("tab1").selected, "tab1 was selected");
-							doh.f(dijit.byId("tab3").selected, "tab3 was selected");
-							doh.f(dijit.byId("tab4").selected, "tab4 was selected");
-							doh.f(dijit.byId("tab5").selected, "tab5 was selected");
-							doh.f(dijit.byId("tab6").selected, "tab6 was selected");
+							doh.t(registry.byId("tab2").selected, "tab2 was not selected");
+							doh.f(registry.byId("tab1").selected, "tab1 was selected");
+							doh.f(registry.byId("tab3").selected, "tab3 was selected");
+							doh.f(registry.byId("tab4").selected, "tab4 was selected");
+							doh.f(registry.byId("tab5").selected, "tab5 was selected");
+							doh.f(registry.byId("tab6").selected, "tab6 was selected");
 						}
 					},
 					{
@@ -47,14 +55,14 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("mainTabContainer_tablist_tab1", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("mainTabContainer_tablist_tab1", 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab1", dojo.global.dijit.focus.curNode.id, "current focus was not tab1");
-								doh.is("tab1", dijit.byId("mainTabContainer").selectedChildWidget.id, "Tab1 pane is not the selected pane");
-								doh.t(isVisible(dijit.byId("tab1")), "Tab1 is hidden");
-								doh.t(isHidden(dijit.byId("tab2")), "Tab2 is visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("mainTabContainer_tablist_tab1", focus.curNode.id, "current focus was not tab1");
+								doh.is("tab1", registry.byId("mainTabContainer").selectedChildWidget.id, "Tab1 pane is not the selected pane");
+								doh.t(helpers.isVisible(registry.byId("tab1")), "Tab1 is hidden");
+								doh.t(helpers.isHidden(registry.byId("tab2")), "Tab2 is visible");
 							}), 1000);
 							
 							return d;
@@ -65,13 +73,13 @@
 						timeout: 3000,
 						runTest: function(t){
 							var d = new doh.Deferred();		
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
+							robot.keyPress(keys.RIGHT_ARROW, 1000, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab2", dojo.global.dijit.focus.curNode.id, "current focus was not tab2");
-								doh.is("tab2", dijit.byId("mainTabContainer").selectedChildWidget.id, "Tab2 pane is not the selected pane");
-								doh.t(isVisible(dijit.byId("tab2")), "Tab2 is hidden");
-								doh.t(isHidden(dijit.byId("tab1")), "Tab1 is visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("mainTabContainer_tablist_tab2", focus.curNode.id, "current focus was not tab2");
+								doh.is("tab2", registry.byId("mainTabContainer").selectedChildWidget.id, "Tab2 pane is not the selected pane");
+								doh.t(helpers.isVisible(registry.byId("tab2")), "Tab2 is hidden");
+								doh.t(helpers.isHidden(registry.byId("tab1")), "Tab1 is visible");
 							}), 1000);
 							
 							return d;
@@ -82,13 +90,13 @@
 						timeout: 3000,
 						runTest: function(t){
 							var d = new doh.Deferred();		
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
+							robot.keyPress(keys.RIGHT_ARROW, 1000, {});
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab3", dojo.global.dijit.focus.curNode.id, "current focus was not tab3");
-								doh.is("tab3", dijit.byId("mainTabContainer").selectedChildWidget.id, "Tab3 pane is not the selected pane");
-								doh.t(isVisible(dijit.byId("tab3")), "Tab3 is hidden");
-								doh.t(isHidden(dijit.byId("tab2")), "Tab2 is visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("mainTabContainer_tablist_tab3", focus.curNode.id, "current focus was not tab3");
+								doh.is("tab3", registry.byId("mainTabContainer").selectedChildWidget.id, "Tab3 pane is not the selected pane");
+								doh.t(helpers.isVisible(registry.byId("tab3")), "Tab3 is hidden");
+								doh.t(helpers.isHidden(registry.byId("tab2")), "Tab2 is visible");
 							}), 1000);
 							
 							return d;
@@ -99,13 +107,13 @@
 						timeout: 3000,
 						runTest: function(t){
 							var d = new doh.Deferred();		
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
+							robot.keyPress(keys.RIGHT_ARROW, 1000, {});
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab4", dojo.global.dijit.focus.curNode.id, "current focus was not tab4");
-								doh.is("tab4", dijit.byId("mainTabContainer").selectedChildWidget.id, "Tab4 pane is not the selected pane");
-								doh.t(isVisible(dijit.byId("tab4")), "Tab4 is hidden");
-								doh.t(isHidden(dijit.byId("tab3")), "Tab3 is visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("mainTabContainer_tablist_tab4", focus.curNode.id, "current focus was not tab4");
+								doh.is("tab4", registry.byId("mainTabContainer").selectedChildWidget.id, "Tab4 pane is not the selected pane");
+								doh.t(helpers.isVisible(registry.byId("tab4")), "Tab4 is hidden");
+								doh.t(helpers.isHidden(registry.byId("tab3")), "Tab3 is visible");
 							}), 1000);
 							
 							return d;
@@ -116,13 +124,13 @@
 						timeout: 3000,
 						runTest: function(t){
 							var d = new doh.Deferred();		
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
+							robot.keyPress(keys.RIGHT_ARROW, 1000, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab5", dojo.global.dijit.focus.curNode.id, "current focus was not tab5");
-								doh.is("tab5", dijit.byId("mainTabContainer").selectedChildWidget.id, "Tab5 pane is not the selected pane");
-								doh.t(isVisible(dijit.byId("tab5")), "Tab5 is hidden");
-								doh.t(isHidden(dijit.byId("tab4")), "Tab4 is visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("mainTabContainer_tablist_tab5", focus.curNode.id, "current focus was not tab5");
+								doh.is("tab5", registry.byId("mainTabContainer").selectedChildWidget.id, "Tab5 pane is not the selected pane");
+								doh.t(helpers.isVisible(registry.byId("tab5")), "Tab5 is hidden");
+								doh.t(helpers.isHidden(registry.byId("tab4")), "Tab4 is visible");
 							}), 1000);
 							
 							return d;
@@ -133,13 +141,13 @@
 						timeout: 3000,
 						runTest: function(t){
 							var d = new doh.Deferred();		
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
+							robot.keyPress(keys.RIGHT_ARROW, 1000, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("mainTabContainer_tablist_tab6", dojo.global.dijit.focus.curNode.id, "current focus was not tab6");
-								doh.is("tab6", dijit.byId("mainTabContainer").selectedChildWidget.id, "Tab6 pane is not the selected pane");
-								doh.t(isVisible(dijit.byId("tab6")), "Tab6 is hidden");
-								doh.t(isHidden(dijit.byId("tab5")), "Tab5 is visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("mainTabContainer_tablist_tab6", focus.curNode.id, "current focus was not tab6");
+								doh.is("tab6", registry.byId("mainTabContainer").selectedChildWidget.id, "Tab6 pane is not the selected pane");
+								doh.t(helpers.isVisible(registry.byId("tab6")), "Tab6 is hidden");
+								doh.t(helpers.isHidden(registry.byId("tab5")), "Tab5 is visible");
 							}), 1000);
 							
 							return d;
@@ -151,18 +159,18 @@
 					{
 						name: "pane1Selected",
 						runTest: function(t){
-							doh.t(dijit.byId("ap1").selected, "ap1 selected");
-							doh.f(dijit.byId("ap2").selected, "ap2 not selected");
-							doh.f(dijit.byId("ap3").selected, "ap3 not selected");
-							doh.t(isVisible(dijit.byId("ap1")), "ap1 is visible");
-							doh.t(isHidden(dijit.byId("ap2")), "ap2 is hidden");
-							doh.t(isHidden(dijit.byId("ap3")), "ap3 is hidden");
+							doh.t(registry.byId("ap1").selected, "ap1 selected");
+							doh.f(registry.byId("ap2").selected, "ap2 not selected");
+							doh.f(registry.byId("ap3").selected, "ap3 not selected");
+							doh.t(helpers.isVisible(registry.byId("ap1")), "ap1 is visible");
+							doh.t(helpers.isHidden(registry.byId("ap2")), "ap2 is hidden");
+							doh.t(helpers.isHidden(registry.byId("ap3")), "ap3 is hidden");
 						}
 					},
 					{
 						name: "focus ap1 title bar",
 						runTest: function(t){
-							dijit.byId("ap1_button").focusNode.focus();
+							registry.byId("ap1_button").focusNode.focus();
 						}
 					},
 					{
@@ -172,21 +180,21 @@
 							var d = new doh.Deferred();
 
 							// Connect to _hideChild() as a trick to tell when animation is finished
-							handle = dojo.connect(dijit.byId("ac1"), "_hideChild", function(){
+							handle = aspect.after(registry.byId("ac1"), "_hideChild", function(){
 								setTimeout(d.getTestCallback(function(){
-									doh.is("ap2_button", dojo.global.dijit.focus.curNode.parentNode.id, "current focus was not ap2");
-									doh.is("ap2", dijit.byId("ac1").selectedChildWidget.id, "ap2 is not the selected pane");
-									doh.t(isVisible(dijit.byId("ap2")), "ap2 is visible");
-									doh.t(isHidden(dijit.byId("ap1")), "ap1 is hidden");
+									doh.is("ap2_button", focus.curNode.parentNode.id, "current focus was not ap2");
+									doh.is("ap2", registry.byId("ac1").selectedChildWidget.id, "ap2 is not the selected pane");
+									doh.t(helpers.isVisible(registry.byId("ap2")), "ap2 is visible");
+									doh.t(helpers.isHidden(registry.byId("ap1")), "ap1 is hidden");
 								}), 0);
 							});
 							
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
+							robot.keyPress(keys.DOWN_ARROW, 1000, {});
 
 							return d;
 						},
 						tearDown: function(){
-							dojo.disconnect(handle);
+							handle.remove();
 						}
 					},
 					{
@@ -196,21 +204,21 @@
 							var d = new doh.Deferred();
 
 							// Connect to _hideChild() as a trick to tell when animation is finished
-							handle = dojo.connect(dijit.byId("ac1"), "_hideChild", function(){
+							handle = aspect.after(registry.byId("ac1"), "_hideChild", function(){
 								setTimeout(d.getTestCallback(function(){
-									doh.is("ap3_button", dojo.global.dijit.focus.curNode.parentNode.id, "current focus was not ap3");
-									doh.is("ap3", dijit.byId("ac1").selectedChildWidget.id, "ap3 is not the selected pane");
-									doh.t(isVisible(dijit.byId("ap3")), "ap3 is visible");
-									doh.t(isHidden(dijit.byId("ap2")), "ap2 is hidden");
+									doh.is("ap3_button", focus.curNode.parentNode.id, "current focus was not ap3");
+									doh.is("ap3", registry.byId("ac1").selectedChildWidget.id, "ap3 is not the selected pane");
+									doh.t(helpers.isVisible(registry.byId("ap3")), "ap3 is visible");
+									doh.t(helpers.isHidden(registry.byId("ap2")), "ap2 is hidden");
 								}), 0);
-							});
+							}, true);
 							
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
+							robot.keyPress(keys.DOWN_ARROW, 1000, {});
 
 							return d;
 						},
 						tearDown: function(){
-							dojo.disconnect(handle);
+							handle.remove();
 						}
 					},
 					{
@@ -219,35 +227,35 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							var accordion = dojo.position(dojo.byId("ac1"));
-							var centerPane = dojo.position(dojo.byId("mainCP"));
+							var accordion = geom.position(dom.byId("ac1"));
+							var centerPane = geom.position(dom.byId("mainCP"));
 							var centerPaneRight = centerPane.x + centerPane.w;
-							var filteringSelectWidth = dojo.position(dijit.byId("filteringSelect").domNode).w;
+							var filteringSelectWidth = geom.position(registry.byId("filteringSelect").domNode).w;
 							var move = filteringSelectWidth - centerPane.w + 30;
 
 							// Drag slider to shrink pane 
-							var size = dojo.position("ac1_splitter");
-							doh.robot.mouseMoveAt("ac1_splitter", 0, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("ac1_splitter", 500, 1, size.w/2-move, size.h/2);
-							doh.robot.sequence(function(){
-								var newCenterPane = dojo.position(dojo.byId("mainCP"));
+							var size = geom.position("ac1_splitter");
+							robot.mouseMoveAt("ac1_splitter", 0, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt("ac1_splitter", 500, 1, size.w/2-move, size.h/2);
+							robot.sequence(function(){
+								var newCenterPane = geom.position(dom.byId("mainCP"));
 								var newCenterPaneRight = newCenterPane.x + newCenterPane.w;
 								// center could overlap right pane
 								var move2 = centerPaneRight - newCenterPaneRight;
-								doh.robot.mouseMoveAt("ac1_splitter", 500, 1, size.w/2-move2, size.h/2);
+								robot.mouseMoveAt("ac1_splitter", 500, 1, size.w/2-move2, size.h/2);
 								move += move2;
 							
-								doh.robot.mouseRelease({left: true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
+								robot.mouseRelease({left: true}, 500);
+								robot.sequence(d.getTestCallback(function(){
 									// test that the margin box for the accordion pane grows the same size as the splitter moved
-									var newAccordion = dojo.position(dojo.byId("ac1"));
-									doh.is(newAccordion.w, accordion.w-move, 'old accordion w = ' + accordion.w + ', new w = ' + newAccordion.w);
+									var newAccordion = geom.position(dom.byId("ac1"));
+									doh.is(Math.round(newAccordion.w), Math.round(accordion.w-move), 'old accordion w = ' + accordion.w + ', new w = ' + newAccordion.w);
 									
 									// test that the center content got smaller by the same size that the splitter moved
-									var newCenterPane = dojo.position(dojo.byId("mainCP"));
+									var newCenterPane = geom.position(dom.byId("mainCP"));
 									var newCenterPaneRight = newCenterPane.x + newCenterPane.w;
-									doh.is(newCenterPane.w, centerPane.w+move-centerPaneRight+newCenterPaneRight, 'old center pane w = ' + centerPane.w + ', new w = ' + newCenterPane.w);
+									doh.is(Math.round(newCenterPane.w), Math.round(centerPane.w+move-centerPaneRight+newCenterPaneRight), 'old center pane w = ' + centerPane.w + ', new w = ' + newCenterPane.w);
 								}), 500);
 							}, 500);
 
@@ -264,21 +272,21 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							filteringSelect = dijit.byId("filteringSelect");
-							handler = filteringSelect.connect(filteringSelect, "onChange", function(e){
+							filteringSelect = registry.byId("filteringSelect");
+							handler = filteringSelect.on("change", function(e){
 								d.callback(true);
 							});
 							
 							filteringSelect.focus();
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							robot.keyPress(keys.DOWN_ARROW, 1000, {});
+							robot.keyPress(keys.DOWN_ARROW, 1000, {});
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
 							
 							return d;
 						},
 						tearDown: function(t){
-							filteringSelect.disconnect(handler);
+							handler.remove();
 						}
 					}
 				]); 
@@ -290,15 +298,15 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 														
-							doh.robot.sequence(function(){
-								var editor = dijit.byId("editor1");
+							robot.sequence(function(){
+								var editor = registry.byId("editor1");
 								editor.setValue("<div id='myDiv'>This is my new text</div>");
 							}, 1000); 
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								var myDiv = dijit.byId("editor1").editNode.childNodes[0];
-								doh.is("myDiv", myDiv.id, "myDiv was not the first child node as expectd");
-								doh.t(isVisible(myDiv), "myDiv is visible");
+							robot.sequence(d.getTestCallback(function(){
+								var myDiv = registry.byId("editor1").editNode.childNodes[0];
+								doh.is("myDiv", myDiv.id, "myDiv was not the first child node as expected");
+								doh.t(helpers.isVisible(myDiv), "myDiv is visible");
 							}), 1000);
 							
 							return d;
diff --git a/dijit/tests/layout/robot/BorderContainer_full.html b/dijit/tests/layout/robot/BorderContainer_full.html
index 770851c..4bdc8ca 100644
--- a/dijit/tests/layout/robot/BorderContainer_full.html
+++ b/dijit/tests/layout/robot/BorderContainer_full.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot BorderContainer full Test</title>
+		<title>robot BorderContainer full Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
@@ -10,28 +10,35 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-		<script type="text/javascript" src="./borderContainerTestFunctions.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx", "dojo/dom", "dojo/dom-geometry", "dojo/window",
+				"dijit/tests/helpers", "dijit/tests/layout/robot/borderContainerTestFunctions", "dojo/domReady!"
+			], function(doh, robot, dom, geom, window, helpers, bcTest){
+
+				robot.initRobot('../test_BorderContainer_full.html');
+
+				var registry;
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_BorderContainer_full.html');
+				doh.register("setup", [
+					function setup(){
+						// get pointers to singletons loaded on test page
+						registry = robot.window.require("dijit/registry");
+					}
+				]);
 
 				doh.register("API", [
 					function initialConditions(){
-						var bc = dijit.byId("main");
-						checkBCpanes(bc);
-						doh.t(bc.getChildren().length==5);
+						var bc = registry.byId("main");
+						bcTest.checkBCpanes(bc);
+						doh.t(5, bc.getChildren().length, "# of children");
 					},
 					
 					function testFullScreen(){
-						var borderContainerPos = dojo.position(dojo.byId("main"));
-						var view = dojo.window.getBox();
+						var borderContainerPos = geom.position(dom.byId("main"));
+						var view = window.getBox();
 						doh.t( borderContainerPos.h-view.h < 3);
 						doh.t( borderContainerPos.w-view.w < 3);
 					}
@@ -44,28 +51,28 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							var oTop = dojo.position(dojo.byId("main-top")),
-								oCenter = dojo.position(dojo.byId("main-center")),
-								oRight = dojo.position(dojo.byId("main-trailing")),
-								oBottom = dojo.position(dojo.byId("main-bottom"));
-
-							// Drag slider to expand pane 
-							var size = dojo.position("main-trailing_splitter");
-							doh.robot.mouseMoveAt("main-trailing_splitter", 500);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("main-trailing_splitter", 500, 100,
-								size.w/2 + (dojo._isBodyLtr() ? -100 : 100), size.h/2);
-							doh.robot.mouseRelease({left: true}, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
-								var nTop = dojo.position(dojo.byId("main-top")),
-									nCenter = dojo.position(dojo.byId("main-center")),
-									nRight = dojo.position(dojo.byId("main-trailing")),
-									nBottom = dojo.position(dojo.byId("main-bottom"));
-					
-								doh.t(within(oRight.w + 100, nRight.w, 10), "right width went from " + oRight.w + " to " + nRight.w);
-								doh.t(within(oTop.w - 100, nTop.w, 10), "top width went from " + oTop.w + " to " + nTop.w);
-								doh.t(within(oCenter.w - 100, nCenter.w, 10), "center width went from " + oCenter.w + " to " + nCenter.w);
-								doh.t(within(oBottom.w - 100, nBottom.w, 10), "bottom width went from " + nBottom.w + " to " + nBottom.w);
+							var oTop = geom.position(dom.byId("main-top")),
+								oCenter = geom.position(dom.byId("main-center")),
+								oRight = geom.position(dom.byId("main-trailing")),
+								oBottom = geom.position(dom.byId("main-bottom"));
+
+							// Drag slider to expand pane
+							var size = geom.position("main-trailing_splitter");
+							robot.mouseMoveAt("main-trailing_splitter", 500);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt("main-trailing_splitter", 500, 100,
+								size.w/2 + (geom.isBodyLtr() ? -100 : 100), size.h/2);
+							robot.mouseRelease({left: true}, 500);
+							robot.sequence(d.getTestCallback(function(){
+								var nTop = geom.position(dom.byId("main-top")),
+									nCenter = geom.position(dom.byId("main-center")),
+									nRight = geom.position(dom.byId("main-trailing")),
+									nBottom = geom.position(dom.byId("main-bottom"));
+
+								doh.t(bcTest.within(oRight.w + 100, nRight.w, 10), "right width went from " + oRight.w + " to " + nRight.w);
+								doh.t(bcTest.within(oTop.w - 100, nTop.w, 10), "top width went from " + oTop.w + " to " + nTop.w);
+								doh.t(bcTest.within(oCenter.w - 100, nCenter.w, 10), "center width went from " + oCenter.w + " to " + nCenter.w);
+								doh.t(bcTest.within(oBottom.w - 100, nBottom.w, 10), "bottom width went from " + nBottom.w + " to " + nBottom.w);
 							}), 500);
 
 							return d;
@@ -77,25 +84,25 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							var oTop = dojo.position(dojo.byId("main-top")),
-								oCenter = dojo.position(dojo.byId("main-center")),
-								oRight = dojo.position(dojo.byId("main-trailing")),
-								oBottom = dojo.position(dojo.byId("main-bottom"));
-
-							// Drag slider to shrink pane 
-							var size = dojo.position("main-bottom_splitter");
-							doh.robot.mouseMoveAt("main-bottom_splitter", 500);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("main-bottom_splitter", 500, 100, size.w/2, size.h/2 + 10);
-							doh.robot.mouseRelease({left: true}, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
-								var nTop = dojo.position(dojo.byId("main-top")),
-									nCenter = dojo.position(dojo.byId("main-center")),
-									nRight = dojo.position(dojo.byId("main-trailing")),
-									nBottom = dojo.position(dojo.byId("main-bottom"));
-					
-								doh.t(within(oBottom.h - 10, nBottom.h, 10), "bottom height went from " + oBottom.h + " to " + nBottom.h);
-								doh.t(within(oCenter.h + 10, nCenter.h, 10), "center height went from " + oCenter.h + " to " + nCenter.h);
+							var oTop = geom.position(dom.byId("main-top")),
+								oCenter = geom.position(dom.byId("main-center")),
+								oRight = geom.position(dom.byId("main-trailing")),
+								oBottom = geom.position(dom.byId("main-bottom"));
+
+							// Drag slider to shrink pane
+							var size = geom.position("main-bottom_splitter");
+							robot.mouseMoveAt("main-bottom_splitter", 500);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt("main-bottom_splitter", 500, 100, size.w/2, size.h/2 + 10);
+							robot.mouseRelease({left: true}, 500);
+							robot.sequence(d.getTestCallback(function(){
+								var nTop = geom.position(dom.byId("main-top")),
+									nCenter = geom.position(dom.byId("main-center")),
+									nRight = geom.position(dom.byId("main-trailing")),
+									nBottom = geom.position(dom.byId("main-bottom"));
+
+								doh.t(bcTest.within(oBottom.h - 10, nBottom.h, 10), "bottom height went from " + oBottom.h + " to " + nBottom.h);
+								doh.t(bcTest.within(oCenter.h + 10, nCenter.h, 10), "center height went from " + oCenter.h + " to " + nCenter.h);
 							}), 500);
 
 							return d;
diff --git a/dijit/tests/layout/robot/BorderContainer_nested.html b/dijit/tests/layout/robot/BorderContainer_nested.html
index a2779b3..55ca48e 100644
--- a/dijit/tests/layout/robot/BorderContainer_nested.html
+++ b/dijit/tests/layout/robot/BorderContainer_nested.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot BorderContainer nested Test</title>
+		<title>robot BorderContainer nested Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
@@ -10,58 +10,67 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-		<script type="text/javascript" src="./borderContainerTestFunctions.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			function checkLayoutPriorityBC(){
-				checkAbove("top bar above second top bar", "top1", "top2");
-				checkAbove("second top bar above inner top bar", "top2", "top3");
-				checkLeft("outer left vs. inner left", "left1", "left2");
-				checkLeft("inner left vs. inner top", "left2", "top3");
-				checkLeft("inner left vs. inner bottom", "left2", "bottom3");
-				checkAbove("inner top vs. center", "top3", "center");
-				checkAbove("center vs. inner bottom", "center", "bottom3");
-				checkLeft("inner right vs. inner top", "top3", "right2");
-				checkLeft("inner right vs. center", "center", "right2");
-				checkAbove("inner bottom bar above second bottom bar", "bottom3", "bottom2");
-				checkAbove("second bottom bar above bottom bar", "bottom2", "bottom1");
-			}
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_BorderContainer_nested.html');
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/_base/array", "dojo/dom", "dojo/dom-geometry", "dojo/keys",
+				"dijit/tests/helpers", "dijit/tests/layout/robot/borderContainerTestFunctions", "dojo/domReady!"
+			], function(doh, robot, array, dom, geom, keys, helpers, bcTest){
+
+				function checkLayoutPriorityBC(){
+					bcTest.checkAbove("top bar above second top bar", "top1", "top2");
+					bcTest.checkAbove("second top bar above inner top bar", "top2", "top3");
+					bcTest.checkLeft("outer left vs. inner left", "left1", "left2");
+					bcTest.checkLeft("inner left vs. inner top", "left2", "top3");
+					bcTest.checkLeft("inner left vs. inner bottom", "left2", "bottom3");
+					bcTest.checkAbove("inner top vs. center", "top3", "center");
+					bcTest.checkAbove("center vs. inner bottom", "center", "bottom3");
+					bcTest.checkLeft("inner right vs. inner top", "top3", "right2");
+					bcTest.checkLeft("inner right vs. center", "center", "right2");
+					bcTest.checkAbove("inner bottom bar above second bottom bar", "bottom3", "bottom2");
+					bcTest.checkAbove("second bottom bar above bottom bar", "bottom2", "bottom1");
+				}
+
+				robot.initRobot('../test_BorderContainer_nested.html');
+
+				var registry;
+
+				doh.register("setup", [
+					function setup(){
+						// get pointers to singletons loaded on test page
+						registry = robot.window.require("dijit/registry");
+					}
+				]);
 
 				doh.register("initial layout", [
 					function nestedBC(){
-						checkBCpanes(dijit.byId("nbc"));
-						doh.t(isVisible(dijit.byId("nbc")));
-						checkInside("nbc", "tc");
+						bcTest.checkBCpanes(registry.byId("nbc"));
+						doh.t(helpers.isVisible(registry.byId("nbc")));
+						bcTest.checkInside("nbc", "tc");
 					},
 					function layoutPriorityBC(){
-						dijit.byId("tc").selectChild(dijit.byId("pbc"));	
-						doh.t(isVisible(dijit.byId("pbc")), "second pane visible");
+						registry.byId("tc").selectChild(registry.byId("pbc"));	
+						doh.t(helpers.isVisible(registry.byId("pbc")), "second pane visible");
 
 						// Check layout of BorderContainer panes relative to each other
 						checkLayoutPriorityBC();
 
 						// Check that all panes within BC borders
-						var children = dijit.byId("pbc").getChildren();
+						var children = registry.byId("pbc").getChildren();
 						doh.is(11, children.length, "# of children");
-						dojo.forEach(children, function(child){
-							checkInside(child, dijit.byId("pbc"));
+						array.forEach(children, function(child){
+							bcTest.checkInside(child, registry.byId("pbc"));
 						});
 					}							
 				]);
 
 				// Verify that tab stops are as per original markup (i.e., children are still in the
-				// logical order specified in the original markup)
+				// logical order specified in the original markup).   The tabstops not listed here
+				// are for the splitters themselves.
 				doh.register("tabIndex", function tabstops(){
-					var tabstops = tabOrder(dijit.byId("pbc").domNode);
+					var tabstops = tabOrder(registry.byId("pbc").domNode);
 					doh.is(21, tabstops.length);
 					doh.is("tabstop #1", tabstops[0].value);
 					doh.is("tabstop #3", tabstops[2].value);
@@ -69,11 +78,11 @@
 					doh.is("tabstop #7", tabstops[6].value);
 					doh.is("tabstop #9", tabstops[8].value);
 					doh.is("tabstop #11", tabstops[10].value);
-					doh.is("tabstop #12", tabstops[11].value);
-					doh.is("tabstop #14", tabstops[13].value);
-					doh.is("tabstop #16", tabstops[15].value);
-					doh.is("tabstop #18", tabstops[17].value);
-					doh.is("tabstop #20", tabstops[19].value);
+					doh.is("tabstop #12", tabstops[12].value);
+					doh.is("tabstop #14", tabstops[14].value);
+					doh.is("tabstop #16", tabstops[16].value);
+					doh.is("tabstop #18", tabstops[18].value);
+					doh.is("tabstop #20", tabstops[20].value);
 				});
 
 				doh.register("keyboard", [
@@ -85,20 +94,20 @@
 
 							var top1Size, centerSize;
 
-							doh.robot.sequence(function(){
-								dojo.byId("top1_splitter").focus();
+							robot.sequence(function(){
+								dom.byId("top1_splitter").focus();
 								
-								top1Size = dojo.position("top1");
-								centerSize = dojo.position("center");
+								top1Size = geom.position("top1");
+								centerSize = geom.position("center");
 							}, 500, 500);
 
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(within(top1Size.h + 3, dojo.position("top1").h, 0.5), "top size increased");
-								doh.t(within(centerSize.h - 3, dojo.position("center").h, 0.5), "center size decreased");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(bcTest.within(top1Size.h + 3, geom.position("top1").h, 0.5), "top size increased");
+								doh.t(bcTest.within(centerSize.h - 3, geom.position("center").h, 0.5), "center size decreased");
 							}), 500);
 
 							return d;
@@ -112,28 +121,28 @@
 
 							var right1Size, centerSize, top2Size, bottom1Size;
 
-							doh.robot.sequence(function(){
-								dojo.byId("right1_splitter").focus();
+							robot.sequence(function(){
+								dom.byId("right1_splitter").focus();
 								
-								right1Size = dojo.position("right1");
-								centerSize = dojo.position("center");
-								top2Size = dojo.position("top2");
-								bottom1Size = dojo.position("bottom1");
+								right1Size = geom.position("right1");
+								centerSize = geom.position("center");
+								top2Size = geom.position("top2");
+								bottom1Size = geom.position("bottom1");
 							}, 500, 500);
 
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(within(right1Size.w + 3, dojo.position("right1").w, 0.5), "right size increased");
-								doh.t(within(centerSize.w - 3, dojo.position("center").w, 0.5), "center size decreased");
-								doh.t(within(centerSize.w - 3, dojo.position("top3").w, 0.5), "inner top size decreased");
-								doh.t(within(centerSize.w - 3, dojo.position("bottom3").w, 0.5), "inner bottom size decreased");
-								doh.t(within(top2Size.h, dojo.position("top2").h, 0.5), "top2 height unchanged");
-								doh.t(within(top2Size.w, dojo.position("top2").w, 0.5), "top2 width unchanged");
-								doh.t(within(bottom1Size.h, dojo.position("bottom1").h, 0.5), "bottom1 height unchanged");
-								doh.t(within(bottom1Size.w, dojo.position("bottom1").w, 0.5), "bottom1 width unchanged");
+							robot.keyPress(keys.LEFT_ARROW, 500, {});
+							robot.keyPress(keys.LEFT_ARROW, 500, {});
+							robot.keyPress(keys.LEFT_ARROW, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(bcTest.within(right1Size.w + 3, geom.position("right1").w, 0.5), "right size increased");
+								doh.t(bcTest.within(centerSize.w - 3, geom.position("center").w, 0.5), "center size decreased");
+								doh.t(bcTest.within(centerSize.w - 3, geom.position("top3").w, 0.5), "inner top size decreased");
+								doh.t(bcTest.within(centerSize.w - 3, geom.position("bottom3").w, 0.5), "inner bottom size decreased");
+								doh.t(bcTest.within(top2Size.h, geom.position("top2").h, 0.5), "top2 height unchanged");
+								doh.t(bcTest.within(top2Size.w, geom.position("top2").w, 0.5), "top2 width unchanged");
+								doh.t(bcTest.within(bottom1Size.h, geom.position("bottom1").h, 0.5), "bottom1 height unchanged");
+								doh.t(bcTest.within(bottom1Size.w, geom.position("bottom1").w, 0.5), "bottom1 width unchanged");
 							}), 500);
 
 							return d;
diff --git a/dijit/tests/layout/robot/GUI.html b/dijit/tests/layout/robot/GUI.html
index 5b5efc8..cf9b7df 100644
--- a/dijit/tests/layout/robot/GUI.html
+++ b/dijit/tests/layout/robot/GUI.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot GUI Test</title>
+		<title>robot GUI Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
@@ -10,29 +10,37 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-		<script type="text/javascript" src="./borderContainerTestFunctions.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom",
+				"dijit/tests/helpers", "dijit/tests/layout/robot/borderContainerTestFunctions", "dojo/domReady!"
+			], function(doh, robot, dom, helpers, bcTest){
+	
+				robot.initRobot('../test_Gui.html');
+
+				var registry;
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Gui.html');
+				doh.register("setup", [
+					function setup(){
+						// get pointers to singletons loaded on test page
+						registry = robot.window.require("dijit/registry");
+					}
+				]);
 
 				doh.register("API", [
 					function initialConditions(){
-						checkBCpanes(dijit.byId("main")); // This test will fail in opera because it thinks that the center content is taller than the border container.  However, it displays fine.
-						checkBCpanes(dijit.byId("mainSplit"));
-						checkBCpanes(dijit.byId("embeddedBC"));
-						checkBCpanes(dijit.byId("bottomSplit"));
-						checkInside(dijit.byId("topTabs1"), dijit.byId("centerSplit"));
-						doh.t(isVisible(dijit.byId("basdicFormTab").domNode));
+						bcTest.checkBCpanes(registry.byId("main"), "main checkBCpanes"); // This test will fail in opera because it thinks that the center content is taller than the border container.  However, it displays fine.
+						bcTest.checkBCpanes(registry.byId("mainSplit"), "mainSplit bcTest.checkBCpanes");
+						bcTest.checkBCpanes(registry.byId("embeddedBC"), "embeddedBC bcTest.checkBCpanes");
+						bcTest.checkBCpanes(registry.byId("bottomSplit"), "bottomSplit bcTest.checkBCpanes");
+						bcTest.checkInside(registry.byId("topTabs1"), registry.byId("centerSplit"), "topTabs1 inside centerSplit");
+						doh.t(helpers.isVisible(registry.byId("basicFormTab").domNode.parentNode), "basicFormTab visible");
 					}
 				]);
-				
+
 				doh.register("test_left_accordion", [
 					{
 						name: "open ac pane 2",
@@ -40,13 +48,13 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 														
-							doh.robot.mouseMoveAt("ac_pane2_button", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("ac_pane2_button", 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible(dijit.byId("leftAccordion").domNode), "Accordion container is not visible");
-								doh.t(isVisible(dijit.byId("ac_pane2").domNode), "accordion container pane2 is not visible");
-								doh.t(isHidden(dijit.byId("ac_pane3").domNode), "accordion container pane3 is not hidden");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden(registry.byId("ac_pane1").domNode), "pane1 hidden");
+								doh.t(helpers.isVisible(registry.byId("ac_pane2").domNode), "pane2 visible");
+								doh.t(helpers.isHidden(registry.byId("ac_pane3").domNode), "pane3 hidden");
 							}), 500);
 
 							return d;
@@ -62,19 +70,19 @@
 							var d = new doh.Deferred();
 							
 							//Drag splitter to the left to make more room for the tab container
-							doh.robot.mouseMoveAt("leftAccordion_splitter", 500, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("leftAccordion_splitter", 500, 100, -100, 100);
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mouseMoveAt("leftAccordion_splitter", 500, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt("leftAccordion_splitter", 500, 100, -100, 100);
+							robot.mouseRelease({left: true}, 500);
 							
-							doh.robot.mouseMoveAt("topTabs1_tablist_tabAccordion", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("dijit_layout_ContentPane_2_button", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("topTabs1_tablist_tabAccordion", 500, 1);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("dijit_layout_ContentPane_2_button", 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_2")), "Accordion tab 2 is not visible");
-								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_4").domNode), "Accordion tab 4 is not hidden");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible(registry.byId("dijit_layout_ContentPane_2")), "Accordion tab 2 is not visible");
+								doh.t(helpers.isHidden(registry.byId("dijit_layout_ContentPane_4").domNode), "Accordion tab 4 is not hidden");
 							}), 1000);
 
 							return d;
@@ -86,16 +94,16 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("topTabs1_tablist_textareaTab", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("dijit_layout_ContentPane_6_button", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("topTabs1_tablist_textareaTab", 500, 1);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("dijit_layout_ContentPane_6_button", 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible(dijit.byId("tabAccordionContainer").domNode), "Accordion container is not visible");
-								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_6")), "Accordion tab 4 is not visible");
-								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_7").domNode), "Accordion tab 3 is not hidden");
-								doh.t(isVisible(dijit.byId("bbtab1").domNode), "Nested tab1 is not visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible(registry.byId("tabAccordionContainer").domNode), "Accordion container is not visible");
+								doh.t(helpers.isVisible(registry.byId("dijit_layout_ContentPane_6")), "Accordion tab 4 is not visible");
+								doh.t(helpers.isHidden(registry.byId("dijit_layout_ContentPane_7").domNode), "Accordion tab 3 is not hidden");
+								doh.t(helpers.isVisible(registry.byId("bbtab1").domNode), "Nested tab1 is not visible");
 							}), 1000);
 
 							return d;
@@ -107,11 +115,11 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt(dijit.byId("accTabs_tablist_bbtab3").closeNode, 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt(registry.byId("accTabs_tablist_bbtab3").closeNode, 500, 1);
+							robot.mouseClick({left:true}, 500);
 														
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(undefined, dijit.byId("accTabs_tablist_bbtab3"));
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(undefined, registry.byId("accTabs_tablist_bbtab3"), "accTabs_tablist_bbtab3 undefined");
 							}), 1000);
 
 							return d;
@@ -123,13 +131,13 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("topTabs1_tablist_titlePaneCP", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("topTabs1_tablist_titlePaneCP", 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								var children = dijit.byId("titlePaneCP").domNode.childNodes;
-								doh.t(children.length == 3);
-								doh.t(isVisible(children[1]), "The title pane child node is not visible");
+							robot.sequence(d.getTestCallback(function(){
+								var children = registry.byId("titlePaneCP").domNode.childNodes;
+								doh.is(3, children.length);
+								doh.t(helpers.isVisible(children[1].parentNode), "The title pane child node is not visible");
 							}), 1000);
 
 							return d;
@@ -141,13 +149,13 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt(dijit.byId("tp").focusNode, 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt(registry.byId("tp").focusNode, 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								var titlePane = dijit.byId("tp");
+							robot.sequence(d.getTestCallback(function(){
+								var titlePane = registry.byId("tp");
 								doh.f(titlePane.open);
-								doh.t(isHidden(dojo.byId("tp_pane")), "Title pane is not hidden");
+								doh.t(helpers.isHidden(dom.byId("tp_pane").parentNode), "Title pane is not hidden");
 							}), 1000);
 
 							return d;
@@ -159,13 +167,13 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("topTabs1_tablist_tabContainerInTabCP", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("tabContainerInTabCP_tablist_basicFormTab2", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("topTabs1_tablist_tabContainerInTabCP", 500, 1);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("tabContainerInTabCP_tablist_basicFormTab2", 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible(dijit.byId("basicFormTab2").domNode), "The embedded tab content is not visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible(registry.byId("basicFormTab2").domNode.parentNode), "The embedded tab content is not visible");
 							}), 1000);
 
 							return d;
@@ -177,11 +185,11 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt(dijit.byId("topTabs1_tablist_tabContainerInTabCP").closeNode, 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt(registry.byId("topTabs1_tablist_tabContainerInTabCP").closeNode, 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(undefined, dijit.byId("topTabs1_tablist_tabContainerInTabCP"));
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(undefined, registry.byId("topTabs1_tablist_tabContainerInTabCP"), "topTabs1_tablist_tabContainerInTabCP undefined");
 							}), 1000);
 
 							return d;
@@ -192,24 +200,24 @@
 				doh.register("test_Center_tab_containers", [
 					{
 						name: "open tab 2",
-						timeout: 7000,
+						timeout: 10000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 														
 							//Drag splitter up to make more room for the tab container
-							doh.robot.mouseMoveAt("topTabs1_splitter", 500, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("topTabs1_splitter", 500, 100, 100, -200);
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mouseMoveAt("topTabs1_splitter", 500, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt("topTabs1_splitter", 500, 100, 100, -200);
+							robot.mouseRelease({left: true}, 500);
 							
-							doh.robot.mouseMoveAt("bottomTabs1_tablist_btabB", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("bottomTabs1_tablist_btabB", 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								checkInside(dijit.byId("bottomTabs1"), dijit.byId("embeddedBC"));
-								checkInside(dijit.byId("bottomTabs2"), dijit.byId("embeddedBC"));
-								doh.t(isVisible(dijit.byId("btabB").domNode), "Tab 2 is not visible");
-								doh.t(isHidden(dijit.byId("btabA").domNode), "Tab 1 is not hidden");
+							robot.sequence(d.getTestCallback(function(){
+								bcTest.checkInside(registry.byId("bottomTabs1"), registry.byId("embeddedBC"), "bottomTabs1 inside embeddedBC");
+								bcTest.checkInside(registry.byId("bottomTabs2"), registry.byId("embeddedBC"), "bottomTabs2 inside embeddedBC");
+								doh.t(helpers.isVisible(registry.byId("btabB").domNode), "Tab 2 is not visible");
+								doh.t(helpers.isHidden(registry.byId("btabA").domNode), "Tab 1 is not hidden");
 							}), 1000);
 
 							return d;
@@ -221,11 +229,11 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 														
-							doh.robot.mouseMoveAt(dijit.byId("bottomTabs1_tablist_btabC").closeNode, 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt(registry.byId("bottomTabs1_tablist_btabC").closeNode, 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(undefined, dijit.byId("bottomTabs1_tablist_btabC"));
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(undefined, registry.byId("bottomTabs1_tablist_btabC"), "bottomTabs1_tablist_btabC undefined");
 							}), 1000);
 
 							return d;
@@ -241,17 +249,17 @@
 							var d = new doh.Deferred();
 														
 							//Drag splitter up to make more room for the tab container
-							doh.robot.mouseMoveAt("bottomTabs_splitter", 500, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("bottomTabs_splitter", 500, 100, 100, -200);
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mouseMoveAt("bottomTabs_splitter", 500, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt("bottomTabs_splitter", 500, 100, 100, -200);
+							robot.mouseRelease({left: true}, 500);
 														
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_9").domNode));
-								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_9_splitter").domNode));
-								doh.t(isVisible(dijit.byId("btabAA").domNode));
-								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_10").domNode));
-								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_10_splitter").domNode));
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible(registry.byId("dijit_layout_ContentPane_9").domNode), "dijit_layout_ContentPane_9 visible");
+								doh.t(helpers.isVisible(registry.byId("dijit_layout_ContentPane_9_splitter").domNode), "dijit_layout_ContentPane_9_splitter visible");
+								doh.t(helpers.isVisible(registry.byId("btabAA").domNode), "btabAA visible");
+								doh.t(helpers.isVisible(registry.byId("dijit_layout_ContentPane_10").domNode), "dijit_layout_ContentPane_10 visible");
+								doh.t(helpers.isVisible(registry.byId("dijit_layout_ContentPane_10_splitter").domNode), "dijit_layout_ContentPane_10_splitter visible");
 							}), 1000);
 
 							return d;
@@ -263,16 +271,16 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("bottomTabs_tablist_btab2", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("bottomTabs_tablist_btab2", 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible(dijit.byId("btab2").domNode));
-								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_9").domNode));
-								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_9_splitter").domNode));
-								doh.t(isHidden(dijit.byId("btabAA").domNode));
-								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_10").domNode));
-								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_10_splitter").domNode));
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible(registry.byId("btab2").domNode), "btab2 visible");
+								doh.t(helpers.isHidden(registry.byId("dijit_layout_ContentPane_9").domNode), "dijit_layout_ContentPane_9 visible");
+								doh.t(helpers.isHidden(registry.byId("dijit_layout_ContentPane_9_splitter").domNode), "dijit_layout_ContentPane_9_splitter visible");
+								doh.t(helpers.isHidden(registry.byId("btabAA").domNode), "btabAA visible");
+								doh.t(helpers.isHidden(registry.byId("dijit_layout_ContentPane_10").domNode), "dijit_layout_ContentPane_10 visible");
+								doh.t(helpers.isHidden(registry.byId("dijit_layout_ContentPane_10_splitter").domNode), "dijit_layout_ContentPane_10_splitter visible");
 							}), 1000);
 
 							return d;
@@ -280,15 +288,15 @@
 					},
 					{
 						name: "test3",
-						timeout: 4000,
+						timeout: 6000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt(dijit.byId("bottomTabs_tablist_btab3").closeNode, 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt(registry.byId("bottomTabs_tablist_btab3").closeNode, 500, 1);
+							robot.mouseClick({left:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(undefined, dijit.byId("bottomTabs_tablist_btab3"));
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(undefined, registry.byId("bottomTabs_tablist_btab3"), "bottomTabs_tablist_btab3 undefined");
 							}), 1000);
 
 							return d;
diff --git a/dijit/tests/layout/robot/TabContainer_a11y.html b/dijit/tests/layout/robot/TabContainer_a11y.html
index f5ce433..2d47a5e 100644
--- a/dijit/tests/layout/robot/TabContainer_a11y.html
+++ b/dijit/tests/layout/robot/TabContainer_a11y.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot TabContainer A11Y Test</title>
+		<title>robot TabContainer A11Y Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
@@ -10,27 +10,80 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom", "dojo/keys", "dojo/query", "dojo/sniff", "dojo/window",
+				"dijit/tests/helpers"
+			], function(doh, robot, dom, keys, query, has, winUtils, helpers){
+	
+				robot.initRobot('../test_TabContainer.html');
+
+				var registry;
+
+				doh.register("setup", [
+					function setup(){
+						// get pointers to singletons loaded on test page
+						registry = robot.window.require("dijit/registry");
+					}
+				]);
+				
+				doh.register("aria", [
+					{
+						name: "tab container attributes",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							var tc = registry.byId("mainTabContainer");
+							
+							doh.is("tabpanel", tc.containerNode.children[0].getAttribute("role"), "containerNode child role");
+							doh.is("mainTabContainer_tablist_tab1", tc.containerNode.children[0].getAttribute("aria-labelledby"), "containerNode.child (the tabpanel) labelledby");
+							
+							var tablist = tc.tablist;
+							
+							// The tablist that stretches across the top
+							doh.is("tablist", tablist.containerNode.getAttribute("role"), "tablist role");
+							doh.is("tab", tablist.getChildren()[0].focusNode.getAttribute("role"), "tablist child's role should be tab");
+							
+							// Now the drop down button
+							doh.is("button", tablist._menuBtn.domNode.getAttribute("role"), "_menuBtn role");
+							doh.f(tablist._menuBtn.domNode.getAttribute("aria-expanded"), "aria-expanded should initially be absent");
+							doh.f(tablist._menuBtn.domNode.getAttribute("aria-owns"), "aria-owns should initially be absent");
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_TabContainer.html');
-				doh.register("basic navigation",[
+							// Now open the drop down to verify changes in aria-expanded, aria-owns, and aria-labelledby
+							tablist._menuBtn.focus();
+							robot.keyPress(keys.ENTER, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(tablist._menuBtn.domNode.getAttribute("aria-expanded"), "aria-expanded with open dropdown");
+								doh.is("mainTabContainer_menu", tablist._menuBtn.domNode.getAttribute("aria-owns"), "menuBtn should own the menu dropdown");
+								
+								var menu = registry.byId("mainTabContainer_menu");
+								doh.is("menu", menu.domNode.getAttribute("role"), "the dropdown role");
+								doh.is("mainTabContainer_tablist_menuBtn", menu.domNode.getAttribute("aria-labelledby"), "aria-labelledby on menu dropdown");
+							
+							}), 500);
+							
+							return d;
+						}
+					}
+				]);
+
+				doh.register("basic navigation", [
 					{
 						name: "focus on button before TabContainer",
 						timeout: 10000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							onFocus(d.getTestCallback(function(node){
+							// Note: for this to work, focus needs to start somewhere else; otherwise there will be no
+							// focus event.
+							helpers.onFocus(d.getTestCallback(function(node){
 							}));
 
-							dojo.query("button")[0].focus();							
+							query("button")[0].focus();							
 
 							return d;
 						}
@@ -41,11 +94,11 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							onFocus(d.getTestCallback(function(node){
+							helpers.onFocus(d.getTestCallback(function(node){
 								doh.is("mainTabContainer_tablist_tab2", node.id, "focus");
 							}));
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
 							return d;
 						}
@@ -56,13 +109,13 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							onFocus(d.getTestCallback(function(node){
-								var tc = dijit.byId("mainTabContainer");
+							helpers.onFocus(d.getTestCallback(function(node){
+								var tc = registry.byId("mainTabContainer");
 								doh.is('mainTabContainer_tablist_tab3', node.id, "currently chosen tab");
 								doh.is("tab3", tc.selectedChildWidget.id, "currently displayed pane");
 							}));
 							
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
 							
 							return d;
 						}
@@ -73,13 +126,13 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							var tc = dijit.byId("mainTabContainer");							
-							onFocus(d.getTestCallback(function(node){
+							var tc = registry.byId("mainTabContainer");							
+							helpers.onFocus(d.getTestCallback(function(node){
 								doh.is('mainTabContainer_tablist_tab2', node.id, "currently chosen tab");
 								doh.is("tab2", tc.selectedChildWidget.id, "currently chosen pane");
 							}));
 							
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							robot.keyPress(keys.LEFT_ARROW, 500, {});
 
 							return d;
 						}
@@ -91,10 +144,10 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							onFocus(d.getTestCallback(function(node){
+							helpers.onFocus(d.getTestCallback(function(node){
 							}));
 							
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
 							
 							return d;
 						}
@@ -105,10 +158,10 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							onFocus(d.getTestCallback(function(node){
+							helpers.onFocus(d.getTestCallback(function(node){
 							}));
 							
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
 							
 							return d;
 						}
@@ -120,11 +173,11 @@
 						runTest: function(t){
 								var d = new doh.Deferred();
 
-								onFocus(d.getTestCallback(function(node){
+								helpers.onFocus(d.getTestCallback(function(node){
 									doh.is('inlined_tablist_tab2href', node.id);
 								}));								
 								
-								doh.robot.keyPress(dojo.keys.TAB, 750);
+								robot.keyPress(keys.TAB, 750);
 
 								return d;
 						}
@@ -136,10 +189,10 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							onFocus(d.getTestCallback(function(node){
+							helpers.onFocus(d.getTestCallback(function(node){
 							}));
 							
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
 							
 							return d;
 						}
@@ -150,10 +203,10 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							onFocus(d.getTestCallback(function(node){
+							helpers.onFocus(d.getTestCallback(function(node){
 							}));
 
-							doh.robot.keyPress(dojo.keys.TAB, 750, {shift:true});
+							robot.keyPress(keys.TAB, 750, {shift:true});
 							
 							return d;
 						}
@@ -164,11 +217,11 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							onFocus(d.getTestCallback(function(node){
+							helpers.onFocus(d.getTestCallback(function(node){
 								doh.is('mainTabContainer_tablist_tab3', node.id);
 							}));
 
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							robot.keyPress(keys.LEFT_ARROW, 500, {});
 							
 							return d;
 						}
@@ -179,10 +232,10 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							onFocus(d.getTestCallback(function(node){
+							helpers.onFocus(d.getTestCallback(function(node){
 							}));
 
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
 							
 							return d;
 						}
@@ -194,11 +247,11 @@
 							var d = new doh.Deferred();
 							
 							//verify that the third nested tab is still selected
-							onFocus(d.getTestCallback(function(node){
+							helpers.onFocus(d.getTestCallback(function(node){
 								doh.is('inlined_tablist_subtab3', node.id);
 							}));
 
-							doh.robot.keyPress(dojo.keys.TAB, 750, {});	// give IE8 time to complete slide animation
+							robot.keyPress(keys.TAB, 750, {});	// give IE8 time to complete slide animation
 							
 							return d;
 						}
@@ -212,10 +265,12 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 
-							dijit.byId("mainTabContainer").selectChild(dijit.byId("tab3"), false);
+							registry.byId("mainTabContainer").selectChild(registry.byId("tab3"), false);
 
-							setTimeout(d.getTestCallback(function(){
-								dojo.byId("mainTabContainer_tablist_tab3href").focus();
+							setTimeout(d.getTestErrback(function(){
+								// on IE the focus event lands after control releases (after the NEXT test has set its focus handler) so do 0 timeout to let focus happen
+								dom.byId("mainTabContainer_tablist_tab3href").focus();
+								setTimeout(d.getTestCallback(function(){}),0);
 							}), 500);
 
 							return d;
@@ -227,11 +282,11 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 								
-							onFocus(d.getTestCallback(function(node){
+							helpers.onFocus(d.getTestCallback(function(node){
 								doh.is('mainTabContainer_tablist_tab1', node.id);
 							}));
 
-							doh.robot.keyPress(dojo.keys.HOME, 500, {});
+							robot.keyPress(keys.HOME, 500, {});
 
 							return d;
 						}
@@ -242,11 +297,11 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 								
-							onFocus(d.getTestCallback(function(node){
+							helpers.onFocus(d.getTestCallback(function(node){
 								doh.is('mainTabContainer_tablist_embedded', node.id);
 							}));
 
-							doh.robot.keyPress(dojo.keys.END, 500, {});
+							robot.keyPress(keys.END, 500, {});
 
 							return d;
 						}
@@ -257,36 +312,159 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 								
-							onFocus(d.getTestCallback(function(node){
+							helpers.onFocus(d.getTestCallback(function(node){
 								doh.is('mainTabContainer_tablist_tab4href', node.id);
 							}));
 
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							robot.keyPress(keys.LEFT_ARROW, 500, {});
 
 							return d;
 						}
 					}
 				]);
 
+				doh.register("disabled tabs",[
+					{
+						name: "setup",
+						runTest: function(){
+
+							// disable first, last, and middle tab
+							registry.byId("tab1").set("disabled", true);
+							registry.byId("tab3").set("disabled", true);
+							registry.byId("embedded").set("disabled", true);
+
+							// set second tab as selected
+							registry.byId("mainTabContainer").selectChild(registry.byId("tab2"));
+						}
+					},
+
+					{
+						name: "focus on button before TabContainer",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							helpers.onFocus(d.getTestCallback(function(node){
+							}));
+
+							query("button")[0].focus();
+
+							return d;
+						}
+					},
+					{
+						name: "tab into main TabContainer",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							helpers.onFocus(d.getTestCallback(function(node){
+								doh.is("mainTabContainer_tablist_tab2", node.id, "focus");
+							}));
+
+							robot.keyPress(keys.TAB, 500, {});
+
+							return d;
+						}
+					},
+					{
+						name: "skip over tab 3 with RIGHT arrow",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							helpers.onFocus(d.getTestCallback(function(node){
+								var tc = registry.byId("mainTabContainer");
+								doh.is('mainTabContainer_tablist_inlined', node.id, "currently chosen tab");
+								doh.is("inlined", tc.selectedChildWidget.id, "currently displayed pane");
+							}));
+
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
+
+							return d;
+						}
+					},
+					{
+						name: "skip over tab 3 with LEFT arrow",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							var tc = registry.byId("mainTabContainer");
+							helpers.onFocus(d.getTestCallback(function(node){
+								doh.is('mainTabContainer_tablist_tab2', node.id, "currently chosen tab");
+								doh.is("tab2", tc.selectedChildWidget.id, "currently chosen pane");
+							}));
+
+							robot.keyPress(keys.LEFT_ARROW, 500, {});
+
+							return d;
+						}
+					},
+					{
+						name: "end key should skip disabled tab",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							helpers.onFocus(d.getTestCallback(function(node){
+								doh.is('mainTabContainer_tablist_tab4href', node.id);
+							}));
+
+							robot.keyPress(keys.END, 500, {});
+
+							return d;
+						}
+					},
+					{
+						name: "home key should skip disabled tab",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							helpers.onFocus(d.getTestCallback(function(node){
+								doh.is('mainTabContainer_tablist_tab2', node.id);
+							}));
+
+							robot.keyPress(keys.HOME, 500, {});
+
+							return d;
+						}
+					},
+
+					{
+						name: "teardown",
+						runTest: function(){
+							// disable first, last, and middle tab
+							registry.byId("tab1").set("disabled", false);
+							registry.byId("tab3").set("disabled", false);
+							registry.byId("embedded").set("disabled", false);
+						}
+					}
+				]);
+
 				doh.register("closing tabs", [
 					{
 						name: "close tab with DELETE button",
 						timeout: 10000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							doh.robot.sequence(function(){
-								dojo.byId("mainTabContainer_tablist_inlined").focus();
-							}, 500, 500);
-							
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.DELETE, 750, {});
 
-							var tc = dijit.byId("mainTabContainer");
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(6, tc.getChildren().length);
+							var tc = registry.byId("mainTabContainer");
+
+							// Select "SplitContainer from href tab"
+							tc.selectChild("tab4href");
+
+							// Go to "Embedded layout widgets" tab, and close it.
+							// This puts focus back on "SplitContainer from href".
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.DELETE, 750, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(6, tc.getChildren().length, "six tabs left");
+								doh.is("tab4href", tc.selectedChildWidget.id, "selection moved to previous tab");
 							}), 500);
-							
+
 							return d;
 						}
 					},
@@ -295,23 +473,27 @@
 						timeout: 10000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							doh.robot.sequence(function(){
-								dojo.byId("mainTabContainer_tablist_tab1").focus();
-							}, 500, 500);
-							
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 750, {});
-							if(dojo.isChrome){
+
+							robot.sequence(function(){
+								dom.byId("mainTabContainer_tablist_tab1").focus();
+							}, 500);
+
+							// Go to "Tab 3", and close it.
+							// This puts the focus back on "Tab 2".
+							robot.keyPress(keys.LEFT_ARROW, 500, {});
+							robot.keyPress(keys.LEFT_ARROW, 750, {});
+							robot.keyPress(keys.LEFT_ARROW, 750, {});
+							if(has("chrome")){
 								// on chrome ctrl+w isn't trapped, and closes the whole browser!
-								doh.robot.keyPress(dojo.keys.DELETE, 750, {});
+								robot.keyPress(keys.DELETE, 750, {});
 							}else{
-								doh.robot.keyPress("w", 750, {ctrl:true});
+								robot.keyPress("w", 750, {ctrl:true});
 							}
-							
-							var tc = dijit.byId("mainTabContainer");
-							doh.robot.sequence(d.getTestCallback(function(){
+
+							var tc = registry.byId("mainTabContainer");
+							robot.sequence(d.getTestCallback(function(){
 								doh.is(5, tc.getChildren().length);
+								doh.is("tab2", tc.selectedChildWidget.id, "selection moved to previous tab");
 							}), 500);
 							return d;
 						}
@@ -322,35 +504,38 @@
 				//	- safari/mac where it doesn't work unless VoiceOver is turned on (#9927)
 				//	- webkit/win, where in suite mode (runTests.html), F10 triggers context menu
 				//		in both the iframe and the outer window
-				if(!dojo.isWebKit){
+				if(!has("webkit")){
 					doh.register("closing tabs via context menu", {
 						name: "close tab through context menu",
 						timeout: 10000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 750, {});
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 750, {});
-							
-							// open via keyboard
-							if(dojo.isMac){
-								doh.robot.keyPress(dojo.keys.SPACE, 500, {
+
+							var tc = registry.byId("ttabs");
+							winUtils.scrollIntoView(tc.domNode);
+
+							dom.byId("ttabs_tablist_ttab1").focus();
+
+							// Open context menu via keyboard
+							if(has("mac")){
+								robot.keyPress(keys.SPACE, 500, {
 									ctrl: true
 								});
 							}else{
-								doh.robot.keyPress(dojo.keys.F10, 500, {
+								robot.keyPress(keys.F10, 500, {
 									shift: true
 								});
 							}
-							
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-							
-							var tc = dijit.byId("mainTabContainer");
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(4, tc.getChildren().length);
+
+							// Close tab
+							robot.keyPress(keys.ENTER, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(2, tc.getChildren().length, "remaining tabs");
+								doh.is("ttab2", tc.selectedChildWidget.id,
+										"selection moved to next tab (since first tab was deleted)");
 							}), 500);
-							
+
 							return d;
 						}
 					});
@@ -362,16 +547,19 @@
 						timeout: 10000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							dojo.byId("ltabs_tablist_HanselGretel1").focus();
 
-							var tc = dijit.byId("ltabs");
-							onFocus(d.getTestCallback(function(node){
-								doh.is('ltabs_tablist_GreenTwigs1', node.id, "currently chosen tab");
-								doh.is("GreenTwigs1", tc.selectedChildWidget.id, "currently displayed pane");
-							}));
+							var tc = registry.byId("ltabs");
+							winUtils.scrollIntoView(tc.domNode);
+
+							dom.byId("ltabs_tablist_HanselGretel1").focus();
+							setTimeout(d.getTestErrback(function(){
+								helpers.onFocus(d.getTestCallback(function(node){
+									doh.is('ltabs_tablist_GreenTwigs1', node.id, "currently chosen tab");
+									doh.is("GreenTwigs1", tc.selectedChildWidget.id, "currently displayed pane");
+								}));
 
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+								robot.keyPress(keys.DOWN_ARROW, 500, {});
+							}), 0);
 
 							return d;
 						}
@@ -381,20 +569,20 @@
 						timeout: 10000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							var tc = dijit.byId("ltabs");							
-							onFocus(d.getTestCallback(function(node){
+
+							var tc = registry.byId("ltabs");
+							helpers.onFocus(d.getTestCallback(function(node){
 								doh.is('ltabs_tablist_HanselGretel1', node.id, "currently chosen tab");
 								doh.is("HanselGretel1", tc.selectedChildWidget.id, "currently chosen pane");
 							}));
 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 500, {});
-							
+							robot.keyPress(keys.UP_ARROW, 500, {});
+
 							return d;
 						}
 					}
 				]);
-				
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/layout/robot/TabContainer_mouse.html b/dijit/tests/layout/robot/TabContainer_mouse.html
index d65a113..bea298a 100644
--- a/dijit/tests/layout/robot/TabContainer_mouse.html
+++ b/dijit/tests/layout/robot/TabContainer_mouse.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot TabContainer Mouse Test</title>
+		<title>robot TabContainer Mouse Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
@@ -10,33 +10,46 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom", "dojo/dom-geometry", "dojo/on", "dojo/query",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, dom, geom, on, query, helpers){
+
+				robot.initRobot('../test_TabContainer.html');
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_TabContainer.html');
-				doh.register("mouse tests",[
-					
+				var registry, focus;
+
+				doh.register("setup", [
+					function setup(){
+						// get pointers to singletons loaded on test page
+						registry = robot.window.require("dijit/registry");
+						doh.t(!!registry, "got registry");
+					}
+				]);
+	
+				doh.register("general", [
 					{
 						name: "tab hover state",
-						timeout: 10000,
+						timeout: 5000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
 							// workaround DOH robot bug where iframe overlay not removed
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt('mainTabContainer_tablist_tab3', 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								var tabHover = dojo.query(".dijitTabHover #mainTabContainer_tablist_tab3");
-								doh.is(1, tabHover.length);
-							}), 500);
+							robot.mouseMoveAt('mainTabContainer_tablist_tab3', 500);
+
+							on.once(dom.byId('mainTabContainer_tablist_tab3'), "mouseover", function(){
+								setTimeout(d.getTestCallback(function(){
+									// Check that .dijitTabHover class was applied
+									var tabHover = query(".dijitTabHover #mainTabContainer_tablist_tab3");
+									doh.is(1, tabHover.length);
+								}), 0);
+							});
 							
 							return d;
 						}
@@ -47,20 +60,19 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt('mainTabContainer_tablist_tab3', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt('mainTabContainer_tablist_tab3', 500);
+							robot.mouseClick({left: true}, 500);
 							
-							var tc = dijit.byId("mainTabContainer");
+							var tc = registry.byId("mainTabContainer");
 							
-							doh.robot.sequence(d.getTestCallback(function(){
+							helpers.onFocus(d.getTestCallback(function(curNode){
 								// verify tab button is selected
-								doh.is('mainTabContainer_tablist_tab3', dojo.global.dijit.focus.curNode.id, "verify chosen tab is in its chosen state and focused");
+								doh.is('mainTabContainer_tablist_tab3', curNode.id, "verify chosen tab is in its chosen state and focused");
 
 								// verify pane is shown
 								doh.is("tab3", tc.selectedChildWidget.id, "verify that the appropiate contentpane is displayed");
-								doh.t(isVisible(dijit.byId("tab3")), "tab3 shown");
-								doh.t(isHidden(dijit.byId("tab2")), "tab2 hidden");
+								doh.t(helpers.isVisible(registry.byId("tab3")), "tab3 shown");
+								doh.t(helpers.isHidden(registry.byId("tab2")), "tab2 hidden");
 							}), 500);
 							
 							return d;
@@ -73,29 +85,29 @@
 							var d = new doh.Deferred();
 
 							// save original position of one of the tab labels
-							var pos0 = dojo.position("mainTabContainer_tablist_tab2").x,
+							var pos0 = geom.position("mainTabContainer_tablist_tab2").x,
 								pos1,
 								pos2;
 
 							// Initially scrolled all the way to the left, so left scroll button
 							// should be disabled
-							doh.t(dijit.byId("mainTabContainer_tablist_leftBtn").get("disabled"), "left scroll button disabled");
-							doh.f(dijit.byId("mainTabContainer_tablist_rightBtn").get("disabled"), "right scroll button enabled");
+							doh.t(registry.byId("mainTabContainer_tablist_leftBtn").get("disabled"), "left scroll button disabled");
+							doh.f(registry.byId("mainTabContainer_tablist_rightBtn").get("disabled"), "right scroll button enabled");
 
 							// Scroll to the right
-							doh.robot.mouseMoveAt('mainTabContainer_tablist_rightBtn', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.sequence(d.getTestErrback(function(){
-								pos1 = dojo.position("mainTabContainer_tablist_tab2").x;
+							robot.mouseMoveAt('mainTabContainer_tablist_rightBtn', 500);
+							robot.mouseClick({left: true}, 500);
+							robot.sequence(d.getTestErrback(function(){
+								pos1 = geom.position("mainTabContainer_tablist_tab2").x;
 								doh.t(pos1 < pos0, "scrolled to the right: " + pos1 + " < " + pos0);
-								doh.f(dijit.byId("mainTabContainer_tablist_leftBtn").get("disabled"), "left scroll button enabled");
+								doh.f(registry.byId("mainTabContainer_tablist_leftBtn").get("disabled"), "left scroll button enabled");
 							}), 500);
 							
 							// And then scroll back to the left
-							doh.robot.mouseMoveAt('mainTabContainer_tablist_leftBtn', 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
-								pos2 = dojo.position("mainTabContainer_tablist_tab2").x;
+							robot.mouseMoveAt('mainTabContainer_tablist_leftBtn', 500);
+							robot.mouseClick({left: true}, 500);
+							robot.sequence(d.getTestCallback(function(){
+								pos2 = geom.position("mainTabContainer_tablist_tab2").x;
 								doh.t(pos2 > pos1, "scrolled to the left: " + pos2 + " > " + pos1);
 							}), 500);
 							
@@ -107,13 +119,13 @@
 						timeout: 10000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseMoveAt(dojo.query('#mainTabContainer_tablist_tab3 span.dijitTabCloseButton')[0], 500);
+
+							robot.mouseMoveAt(query('.dijitTabCloseButton', registry.byId("mainTabContainer_tablist_tab3").domNode)[0], 500);
 							
 							// verify the close button is in its hover state
-							doh.robot.sequence(d.getTestCallback(function(){
-								var closeHover = dojo.query("#mainTabContainer_tablist_tab3 .dijitTabCloseButtonHover");
-								doh.is(1, closeHover.length);
+							robot.sequence(d.getTestCallback(function(){
+								var closeHover = query(".dijitTabCloseButtonHover", registry.byId("mainTabContainer_tablist_tab3").domNode);
+								doh.is(1, closeHover.length, "close button hover CSS");
 							}), 500);
 							
 							return d;
@@ -125,11 +137,11 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt(dojo.query('#mainTabContainer_tablist_tab3 span.dijitTabCloseButton')[0], 500);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt(query('.dijitTabCloseButton', registry.byId("mainTabContainer_tablist_tab3").domNode)[0], 500);
+							robot.mouseClick({left: true}, 500);
 							
-							var tc = dijit.byId("mainTabContainer");
-							doh.robot.sequence(d.getTestCallback(function(){
+							var tc = registry.byId("mainTabContainer");
+							robot.sequence(d.getTestCallback(function(){
 								doh.is(6, tc.getChildren().length);
 							}), 500);
 							
@@ -142,44 +154,188 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("mainTabContainer_tablist_menuBtn", 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseMoveAt("tab4href_stcMi", 500);
-							doh.robot.mouseClick({left: true}, 1000);
+							robot.mouseMoveAt("mainTabContainer_tablist_menuBtn", 500);
+							robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt("tab4href_stcMi", 500);
+							robot.mouseClick({left: true}, 1000);
 							
 							// verify SplitContainer tab is displayed (but it doesn't get focus, see #10727)
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// Check that tab button is scrolled correctly into view
 								// TODO: this check won't work in RTL mode
-								var tc = dijit.byId("mainTabContainer");
+								var tc = registry.byId("mainTabContainer");
 
-								var leftButton = dojo.byId("mainTabContainer_tablist_leftBtn");
-								var tablistLeft = dojo.position(leftButton).x + dojo.position(leftButton).w;
+								var leftButton = dom.byId("mainTabContainer_tablist_leftBtn");
+								var tablistLeft = geom.position(leftButton).x + geom.position(leftButton).w;
 	
-								var rightButton = dojo.byId("mainTabContainer_tablist_rightBtn");
-								var tablistRight = dojo.position(rightButton).x;
+								var rightButton = dom.byId("mainTabContainer_tablist_rightBtn");
+								var tablistRight = geom.position(rightButton).x;
 	
-								var tab = dijit.byId("mainTabContainer_tablist_tab4href");
+								var tab = registry.byId("mainTabContainer_tablist_tab4href");
 	
-								var tabLeft = dojo.position(tab.domNode).x;
-								var tabRight = dojo.position(tab.domNode).x + dojo.position(tab.domNode).w;
+								var tabLeft = geom.position(tab.domNode).x;
+								var tabRight = geom.position(tab.domNode).x + geom.position(tab.domNode).w;
 	
 								var isTabVisible = (tablistLeft < tabLeft && tablistRight > tabRight);
 
 								doh.t(isTabVisible, "verify tab is in display area");
 								
 								// And verify that pane is shown
-								doh.is("tab4href", tc.selectedChildWidget.id, "verify that the appropiate contentpane is displayed");
-								doh.t(isVisible(dijit.byId("tab4href")), "tab4 shown");
-								doh.t(isHidden(dijit.byId("tab1")), "tab1 hidden");
+								doh.is("tab4href", tc.selectedChildWidget.id, "verify that the appropriate contentpane is displayed");
+								doh.t(helpers.isVisible(registry.byId("tab4href")), "tab4 shown");
+								doh.t(helpers.isHidden(registry.byId("tab1")), "tab1 hidden");
 							}), 1000);
 							
 							return d;
 						}
 					}
 				]);
-				
-				
+
+				doh.register("disabled tabs", [
+					{
+						name: "setup",
+						runTest: function(){
+							tc = registry.byId("mainTabContainer");
+							tc.selectChild(registry.byId("tab1"));
+							registry.byId("tab2").set("closable", true);
+							registry.byId("tab2").set("disabled", true);
+						}
+					},
+					{
+						name: "click disabled tab",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							robot.mouseMoveAt('mainTabContainer_tablist_tab2', 500);
+							robot.mouseClick({left: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("tab1", tc.selectedChildWidget.id, "selected pane not changed");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "close disabled tab",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							var nChildren = tc.getChildren().length;
+							robot.mouseMoveAt(query('.dijitTabCloseButton', registry.byId("mainTabContainer_tablist_tab2").domNode)[0], 500);
+							robot.mouseClick({left: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(nChildren, tc.getChildren().length, "num children didn't change");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "choose disabled tab from TabContainer's menu",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							robot.mouseMoveAt("mainTabContainer_tablist_menuBtn", 500);
+							robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt("tab2_stcMi", 500);
+							robot.mouseClick({left: true}, 1000);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("tab1", tc.selectedChildWidget.id, "selected pane not changed");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "re-enable tab",
+						runTest: function(){
+							registry.byId("tab2").set("disabled", false);
+						}
+					},
+					{
+						name: "click enabled tab",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							robot.mouseMoveAt('mainTabContainer_tablist_tab2', 500);
+							robot.mouseClick({left: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("tab2", tc.selectedChildWidget.id, "selected pane changed");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "close enabled tab",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							var nChildren = tc.getChildren().length;
+							robot.mouseMoveAt(query('.dijitTabCloseButton', registry.byId("mainTabContainer_tablist_tab2").domNode)[0], 500);
+							robot.mouseClick({left: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(nChildren-1, tc.getChildren().length, "num children decreased");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("initially disabled tab", [
+					{
+						name: "setup",
+						runTest: function(){
+							tc = registry.byId("nomenu");
+							tc.selectChild(registry.byId("nomenu_tab2"));
+						}
+					},
+					{
+						name: "click disabled tab",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							robot.mouseMoveAt("nomenu_tablist_nomenu_tab3", 500);
+							robot.mouseClick({left: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("nomenu_tab2", tc.selectedChildWidget.id, "selected pane not changed");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "close disabled tab",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							var nChildren = tc.getChildren().length;
+							robot.mouseMoveAt(query('.dijitTabCloseButton', registry.byId("nomenu_tablist_nomenu_tab3").domNode)[0], 500);
+							robot.mouseClick({left: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(nChildren, tc.getChildren().length, "num children didn't change");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/layout/robot/TabContainer_noLayout.html b/dijit/tests/layout/robot/TabContainer_noLayout.html
index 83dfaf7..57b7fdb 100644
--- a/dijit/tests/layout/robot/TabContainer_noLayout.html
+++ b/dijit/tests/layout/robot/TabContainer_noLayout.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot TabContainer No Layout Test</title>
+		<title>robot TabContainer No Layout Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
@@ -10,58 +10,68 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-			
-			function checkInside(childDomNode, parentDomNode){
-				var cp = dojo.position(childDomNode, true),
-					pp = dojo.position(parentDomNode, true);
-
-				doh.t(
-					cp.y > pp.y && cp.y+cp.h < pp.y+pp.h &&
-					cp.x > pp.x && cp.x+cp.w < pp.x+pp.w,
-					childDomNode.id + "child not inside " + parentDomNode.id + dojo.toJson(cp) + dojo.toJson(pp)
-				);
-			}
-
-			var oldPos, tab, handler;
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/aspect", "dojo/dom", "dojo/dom-geometry", "dojo/json", "dojo/query",
+				"dijit/tests/helpers", "dijit/tests/layout/robot/borderContainerTestFunctions", "dojo/domReady!"
+			], function(doh, robot, aspect, dom, geom, json, query, helpers, bcTest){
+
+				function checkInside(childDomNode, parentDomNode){
+					var cp = geom.position(childDomNode, true),
+						pp = geom.position(parentDomNode, true);
+	
+					doh.t(
+						cp.y > pp.y && cp.y+cp.h < pp.y+pp.h &&
+						cp.x > pp.x && cp.x+cp.w < pp.x+pp.w,
+						childDomNode.id + "child not inside " + parentDomNode.id + json.stringify(cp) + json.stringify(pp)
+					);
+				}
+
+				var oldPos, tab, handler;
 			
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_TabContainer_noLayout.html');
+				robot.initRobot('../test_TabContainer_noLayout.html');
+
+				var registry;
+
+				doh.register("setup", [
+					function setup(){
+						// get pointers to singletons loaded on test page
+						registry = robot.window.require("dijit/registry");
+					}
+				]);
+
 				doh.register("plain TabContainer",[
 					{
 						name: "tab1",
-						timeout: 4000,
+						timeout: 8000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							tab = dijit.byId('tab1');
-							handler = tab.connect(tab, 'onDownloadEnd', function(){
+							tab = registry.byId('tab1');
+							handler = aspect.after(tab, 'onDownloadEnd', function(){
 								setTimeout(d.getTestCallback(function(){
-									var h1 = dojo.query('h1', dojo.byId('tab1'))[0];
-									var p1 = dojo.query('p', dojo.byId('tab1'))[0];
-									var div1 = dojo.query('div', dojo.byId('tab1'))[0];
+									var h1 = query('h1', dom.byId('tab1'))[0];
+									var p1 = query('p', dom.byId('tab1'))[0];
+									var div1 = query('div', dom.byId('tab1'))[0];
 								
-									checkInside(h1, dijit.byId("plainTabContainer").domNode);
-									checkInside(p1, dijit.byId("plainTabContainer").domNode);
-									checkInside(div1, dijit.byId("plainTabContainer").domNode);
+									checkInside(h1, registry.byId("plainTabContainer").domNode);
+									checkInside(p1, registry.byId("plainTabContainer").domNode);
+									checkInside(div1, registry.byId("plainTabContainer").domNode);
 								
-									oldPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
+									oldPos = geom.position(dom.byId("textAfterTabContainer1"), true);
 								}), 500);
 							});
 							
-							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab1', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt('plainTabContainer_tablist_tab1', 0, 1);
+							robot.mouseClick({left: true}, 500);
 							
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							handler.remove();
 						}
 					},
 					{
@@ -69,29 +79,29 @@
 						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							tab = dijit.byId('tab2');
-							handler = tab.connect(tab, 'onDownloadEnd', function(){
+
+							tab = registry.byId('tab2');
+							handler = aspect.after(tab, 'onDownloadEnd', function(){
 								setTimeout(d.getTestCallback(function(){
-									var h2 = dojo.query('h1', dojo.byId('tab2'))[0];
-									var p2 = dojo.query('p', dojo.byId('tab2'))[0];
+									var h2 = query('h1', dom.byId('tab2'))[0];
+									var p2 = query('p', dom.byId('tab2'))[0];
 								
-									checkInside(h2, dijit.byId("plainTabContainer").domNode);
-									checkInside(p2, dijit.byId("plainTabContainer").domNode);
+									checkInside(h2, registry.byId("plainTabContainer").domNode);
+									checkInside(p2, registry.byId("plainTabContainer").domNode);
 								
-									var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-									doh.f(oldPos.y == newPos.y);
+									var newPos = geom.position(dom.byId("textAfterTabContainer1"), true);
+									doh.isNot(oldPos.y, newPos.y, "oldpos y vs. newpos y");
 									oldPos = newPos;
 								}), 1000);
 							});
 							
-							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab2', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt('plainTabContainer_tablist_tab2', 0, 1);
+							robot.mouseClick({left: true}, 500);
 							
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							handler.remove();
 						}
 					},
 					{
@@ -100,70 +110,75 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							tab = dijit.byId('tab3');
-							handler = tab.connect(tab, '_onShow', function(){
+							tab = registry.byId('tab3');
+							handler = aspect.after(tab, '_onShow', function(){
 								setTimeout(d.getTestCallback(function(){
-									checkInside(dojo.byId("h3"), dijit.byId("plainTabContainer").domNode);
-									checkInside(dojo.byId("p3"), dijit.byId("plainTabContainer").domNode);
-									checkInside(dojo.byId("p4"), dijit.byId("plainTabContainer").domNode);
-									checkInside(dojo.byId("p5"), dijit.byId("plainTabContainer").domNode);
-									checkInside(dojo.byId("b3"), dijit.byId("plainTabContainer").domNode);
-									checkInside(dojo.byId("b4"), dijit.byId("plainTabContainer").domNode);
-									checkInside(dojo.byId("foo"), dijit.byId("plainTabContainer").domNode);
+									checkInside(dom.byId("h3"), registry.byId("plainTabContainer").domNode);
+									checkInside(dom.byId("p3"), registry.byId("plainTabContainer").domNode);
+									checkInside(dom.byId("p4"), registry.byId("plainTabContainer").domNode);
+									checkInside(dom.byId("p5"), registry.byId("plainTabContainer").domNode);
+									checkInside(dom.byId("b3"), registry.byId("plainTabContainer").domNode);
+									checkInside(dom.byId("b4"), registry.byId("plainTabContainer").domNode);
+									checkInside(dom.byId("foo"), registry.byId("plainTabContainer").domNode);
 								
-									var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-									doh.f(oldPos.y == newPos.y);
+									var newPos = geom.position(dom.byId("textAfterTabContainer1"), true);
+									doh.isNot(oldPos.y, newPos.y, "oldpos y vs. newpos y");
 									oldPos = newPos;
 								}), 1000);
 							});
 							
-							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab3', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt('plainTabContainer_tablist_tab3', 0, 1);
+							robot.mouseClick({left: true}, 500);
 							
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							handler.remove();
 						}
 					},
 					{
 						name: "tab4_innerTab1",
-						timeout: 6000,
+						timeout: 12000,
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							tab = dijit.byId('tab4');
-							handler = tab.connect(tab, '_onShow', function(){
-								tab.disconnect(handler);
-								setTimeout(function(){
-									tab = dijit.byId('dijit_layout_LinkPane_0');
-									handler = tab.connect(tab, '_onShow', function(){
+							tab = registry.byId('tab4');
+							handler = aspect.after(tab, '_onShow', function(){
+								handler.remove();
+								handler = null;
+								setTimeout(d.getTestErrback(function(){
+									tab = registry.byId('tab4a');
+									handler = aspect.after(tab, '_onShow', function(){
+										handler.remove();
+										handler = null;
 										setTimeout(d.getTestCallback(function(){
-											var h1 = dojo.query('h1', dojo.byId('dijit_layout_LinkPane_0'))[0];
-											var p1 = dojo.query('p', dojo.byId('dijit_layout_LinkPane_0'))[0];
-											var div1 = dojo.query('div', dojo.byId('dijit_layout_LinkPane_0'))[0];
+											var h1 = query('h1', dom.byId('tab4a'))[0];
+											var p1 = query('p', dom.byId('tab4a'))[0];
+											var div1 = query('div', dom.byId('tab4a'))[0];
 								
-											checkInside(h1, dijit.byId("plainTabContainer").domNode);
-											checkInside(p1, dijit.byId("plainTabContainer").domNode);
-											checkInside(div1, dijit.byId("plainTabContainer").domNode);
+											checkInside(h1, registry.byId("plainTabContainer").domNode);
+											checkInside(p1, registry.byId("plainTabContainer").domNode);
+											checkInside(div1, registry.byId("plainTabContainer").domNode);
 								
-											var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-											doh.f(oldPos.y == newPos.y);
+											var newPos = geom.position(dom.byId("textAfterTabContainer1"), true);
+											doh.isNot(oldPos.y, newPos.y, "oldpos y vs. newpos y");
 											oldPos = newPos;
 										}), 1000);
 									});
-									doh.robot.mouseMoveAt('tab4_tablist_dijit_layout_LinkPane_0', 0, 1);
-									doh.robot.mouseClick({left: true}, 500);
-								}, 1000);
+									robot.mouseMoveAt('tab4_tablist_tab4a', 0, 1);
+									robot.mouseClick({left: true}, 500);
+								}), 1000);
 							});
 
-							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab4', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt('plainTabContainer_tablist_tab4', 0, 1);
+							robot.mouseClick({left: true}, 500);
 							
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							if(handler){
+								handler.remove();
+							}
 						}
 					},
 					{
@@ -172,117 +187,59 @@
 						runTest: function(t){
 							var d = new doh.Deferred();
 							
-							tab = dijit.byId('dijit_layout_LinkPane_1');
-							handler = tab.connect(tab, '_onShow', function(){
+							tab = registry.byId('tab4b');
+							handler = aspect.after(tab, '_onShow', function(){
 								setTimeout(d.getTestCallback(function(){
-									var h2 = dojo.query('h1', dojo.byId('dijit_layout_LinkPane_1'))[0];
-									var p2 = dojo.query('p', dojo.byId('dijit_layout_LinkPane_1'))[0];
+									var h2 = query('h1', dom.byId('tab4b'))[0];
+									var p2 = query('p', dom.byId('tab4b'))[0];
 
-									checkInside(h2, dijit.byId("plainTabContainer").domNode);
-									checkInside(p2, dijit.byId("plainTabContainer").domNode);
-								
-									var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-									doh.f(oldPos.y == newPos.y);
-									oldPos = newPos;
-								}), 1000);
-							});
-							
-							doh.robot.mouseMoveAt('tab4_tablist_dijit_layout_LinkPane_1', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							return d;
-						},
-						tearDown: function(t){
-							tab.disconnect(handler);
-						}
-					},
-					{
-						name: "tab5_innerTab1",
-						timeout: 7000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-							
-							tab = dijit.byId('tab5');
-							handler = tab.connect(tab, 'onDownloadEnd', function(){
-								doh.robot.mouseMoveAt('dijit_layout_TabContainer_0_tablist_dijit_layout_ContentPane_0', 1000, 1);
-								doh.robot.mouseClick({left: true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									var p = dojo.query("p", dojo.byId('dijit_layout_ContentPane_0'))[0];
-									checkInside(p, dijit.byId("plainTabContainer").domNode);
-
-									var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-									doh.f(oldPos.y == newPos.y);
-									oldPos = newPos;
-								}), 1000);
-							});
-							doh.robot.mouseMoveAt('plainTabContainer_tablist_tab5', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							return d;
-						},
-						tearDown: function(t){
-							tab.disconnect(handler);
-						}
-					},
-					{
-						name: "tab5_innerTab2",
-						timeout: 4000,
-						runTest: function(t){
-							var d = new doh.Deferred();
-							
-							tab = dijit.byId('dijit_layout_ContentPane_1');
-							handler = tab.connect(tab, '_onShow', function(){
-								setTimeout(d.getTestCallback(function(){
-									var p1 = dojo.query("p", dojo.byId('dijit_layout_ContentPane_1'))[0];
-									var p2 = dojo.query("p", dojo.byId('dijit_layout_ContentPane_1'))[1];
-									var p3 = dojo.query("p", dojo.byId('dijit_layout_ContentPane_1'))[2];
-									checkInside(p1, dijit.byId("plainTabContainer").domNode);
-									checkInside(p2, dijit.byId("plainTabContainer").domNode);
-									checkInside(p3, dijit.byId("plainTabContainer").domNode);
+									checkInside(h2, registry.byId("plainTabContainer").domNode);
+									checkInside(p2, registry.byId("plainTabContainer").domNode);
 								
-									var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-									doh.f(oldPos.y == newPos.y);
+									var newPos = geom.position(dom.byId("textAfterTabContainer1"), true);
+									doh.isNot(oldPos.y, newPos.y, "oldpos y vs. newpos y");
 									oldPos = newPos;
 								}), 1000);
 							});
 							
-							doh.robot.mouseMoveAt('dijit_layout_TabContainer_0_tablist_dijit_layout_ContentPane_1', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt('tab4_tablist_tab4b', 0, 1);
+							robot.mouseClick({left: true}, 500);
 							
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							handler.remove();
 						}
 					},
+
 					{
 						name: "addTab",
 						timeout: 8000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							tab = dijit.byId('plainTabContainer');
-							handler = tab.connect(tab, 'addChild', function(){
+
+							tab = registry.byId('plainTabContainer');
+							handler = aspect.after(tab, 'addChild', function(){
 								setTimeout(function(){
-									doh.robot.mouseMoveAt('plainTabContainer_tablist_newTab6', 0, 1);
-									doh.robot.mouseClick({left: true}, 500);
-									doh.robot.sequence(d.getTestCallback(function(){
-										var newTab = dojo.byId("newTab6");
+									robot.mouseMoveAt('plainTabContainer_tablist_newTab6', 0, 1);
+									robot.mouseClick({left: true}, 500);
+									robot.sequence(d.getTestCallback(function(){
+										var newTab = dom.byId("newTab6");
 										doh.is("Contents of Tab 6", newTab.innerHTML);
-										checkInside(newTab, dijit.byId("plainTabContainer").domNode);
+										checkInside(newTab, registry.byId("plainTabContainer").domNode);
 
-										var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
-										doh.f(oldPos.y == newPos.y);
+										var newPos = geom.position(dom.byId("textAfterTabContainer1"), true);
+										doh.isNot(oldPos.y, newPos.y, "oldpos y vs. newpos y");
 									}), 1000);
 								}, 1000)
 							});
-							doh.robot.mouseMoveAt('addTab', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							
+							robot.mouseMoveAt('addTabButton', 0, 1);
+							robot.mouseClick({left: true}, 500);
+
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							handler.remove();
 						}
 					},
 					{
@@ -290,51 +247,53 @@
 						name: "destroy",
 						runTest: function(){
 							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt('destroyTabContainer', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
-								
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(undefined, dojo.byId("plainTabContainer"), 'widget was not removed');
+
+							robot.mouseMoveAt('destroyTabContainer', 0, 1);
+							robot.mouseClick({left: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(undefined, dom.byId("plainTabContainer"), 'widget was not removed');
 							}), 2000);
 							return d;
 						}
 					}
 				]);
-				
+
+				// Test commented out until #13411 fixed.
+				/*
 				doh.register("TabContainer in table",[
 					function width(){
 						// Make sure the scrolling tabs don't make the width of the table explode to 50,0000px
-						doh.is(400, dojo.position(dojo.byId("tableTabContainer")).w);
+						doh.is(400, geom.position(dom.byId("tableTabContainer")).w);
 					},
 					{
 						name: "tab1_t2",
 						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							tab = dijit.byId('atab1');
-							handler = tab.connect(tab, 'onDownloadEnd', function(){
+
+							tab = registry.byId('atab1');
+							handler = aspect.after(tab, 'onDownloadEnd', function(){
 								setTimeout(d.getTestCallback(function(){
-									var h1 = dojo.query('h1', dojo.byId('atab1'))[0];
-									var p1 = dojo.query('p', dojo.byId('atab1'))[0];
-									var div1 = dojo.query('div', dojo.byId('atab1'))[0];
-								
-									checkInside(h1, dijit.byId("tableTabContainer").domNode);
-									checkInside(p1, dijit.byId("tableTabContainer").domNode);
-									checkInside(div1, dijit.byId("tableTabContainer").domNode);
-								
-									oldPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
+									var h1 = query('h1', dom.byId('atab1'))[0];
+									var p1 = query('p', dom.byId('atab1'))[0];
+									var div1 = query('div', dom.byId('atab1'))[0];
+
+									checkInside(h1, registry.byId("tableTabContainer").domNode);
+									checkInside(p1, registry.byId("tableTabContainer").domNode);
+									checkInside(div1, registry.byId("tableTabContainer").domNode);
+
+									oldPos = geom.position(dom.byId("textAfterTabContainer2"), true);
 								}), 500);
 							});
-							
-							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab1', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							
+
+							robot.mouseMoveAt('tableTabContainer_tablist_atab1', 0, 1);
+							robot.mouseClick({left: true}, 500);
+
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							handler.remove();
 						}
 					},
 					{
@@ -342,29 +301,29 @@
 						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							tab = dijit.byId('atab2');
-							handler = tab.connect(tab, 'onDownloadEnd', function(){
+
+							tab = registry.byId('atab2');
+							handler = aspect.after(tab, 'onDownloadEnd', function(){
 								setTimeout(d.getTestCallback(function(){
-									var h2 = dojo.query('h1', dojo.byId('atab2'))[0];
-									var p2 = dojo.query('p', dojo.byId('atab2'))[0];
-								
-									checkInside(h2, dijit.byId("tableTabContainer").domNode);
-									checkInside(p2, dijit.byId("tableTabContainer").domNode);
-								
-									var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
-									doh.f(oldPos.y == newPos.y);
+									var h2 = query('h1', dom.byId('atab2'))[0];
+									var p2 = query('p', dom.byId('atab2'))[0];
+
+									checkInside(h2, registry.byId("tableTabContainer").domNode);
+									checkInside(p2, registry.byId("tableTabContainer").domNode);
+
+									var newPos = geom.position(dom.byId("textAfterTabContainer2"), true);
+									doh.isNot(oldPos.y, newPos.y, "oldpos y vs. newpos y");
 									oldPos = newPos;
 								}), 1000);
 							});
-							
-							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab2', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							
+
+							robot.mouseMoveAt('tableTabContainer_tablist_atab2', 0, 1);
+							robot.mouseClick({left: true}, 500);
+
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							handler.remove();
 						}
 					},
 					{
@@ -372,71 +331,76 @@
 						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							tab = dijit.byId('atab3');
-							handler = tab.connect(tab, '_onShow', function(){
+
+							tab = registry.byId('atab3');
+							handler = aspect.after(tab, '_onShow', function(){
 								setTimeout(d.getTestCallback(function(){
-									checkInside(dojo.byId("h4"), dijit.byId("tableTabContainer").domNode);
-									checkInside(dojo.byId("p6"), dijit.byId("tableTabContainer").domNode);
-									checkInside(dojo.byId("p7"), dijit.byId("tableTabContainer").domNode);
-									checkInside(dojo.byId("p8"), dijit.byId("tableTabContainer").domNode);
-									checkInside(dojo.byId("b5"), dijit.byId("tableTabContainer").domNode);
-									checkInside(dojo.byId("b6"), dijit.byId("tableTabContainer").domNode);
-									checkInside(dojo.byId("foo2"), dijit.byId("tableTabContainer").domNode);
-								
-									var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
-									doh.f(oldPos.y == newPos.y);
+									checkInside(dom.byId("h4"), registry.byId("tableTabContainer").domNode);
+									checkInside(dom.byId("p6"), registry.byId("tableTabContainer").domNode);
+									checkInside(dom.byId("p7"), registry.byId("tableTabContainer").domNode);
+									checkInside(dom.byId("p8"), registry.byId("tableTabContainer").domNode);
+									checkInside(dom.byId("b5"), registry.byId("tableTabContainer").domNode);
+									checkInside(dom.byId("b6"), registry.byId("tableTabContainer").domNode);
+									checkInside(dom.byId("foo2"), registry.byId("tableTabContainer").domNode);
+
+									var newPos = geom.position(dom.byId("textAfterTabContainer2"), true);
+									doh.isNot(oldPos.y, newPos.y, "oldpos y vs. newpos y");
 									oldPos = newPos;
 								}), 1000);
 							});
-							
-							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab3', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							
+
+							robot.mouseMoveAt('tableTabContainer_tablist_atab3', 0, 1);
+							robot.mouseClick({left: true}, 500);
+
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							handler.remove();
 						}
 					},
 					{
 						name: "tab4_innerTab1_t2",
-						timeout: 6000,
+						timeout: 12000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							tab = dijit.byId('atab4');
-							handler = tab.connect(tab, '_onShow', function(){
-								tab.disconnect(handler);
-								setTimeout(function(){
-									tab = dijit.byId('dijit_layout_LinkPane_2');
-									handler = tab.connect(tab, '_onShow', function(){
+
+							tab = registry.byId('atab4');
+							handler = aspect.after(tab, '_onShow', function(){
+								handler.remove();
+								handler = null;
+								setTimeout(d.getTestErrback(function(){
+									tab = registry.byId('atab4a');
+									handler = aspect.after(tab, '_onShow', function(){
+										handler.remove();
+										handler = null;
 										setTimeout(d.getTestCallback(function(){
-											var h1 = dojo.query('h1', dojo.byId('dijit_layout_LinkPane_2'))[0];
-											var p1 = dojo.query('p', dojo.byId('dijit_layout_LinkPane_2'))[0];
-											var div1 = dojo.query('div', dojo.byId('dijit_layout_LinkPane_2'))[0];
-								
-											checkInside(h1, dijit.byId("tableTabContainer").domNode);
-											checkInside(p1, dijit.byId("tableTabContainer").domNode);
-											checkInside(div1, dijit.byId("tableTabContainer").domNode);
-								
-											var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
-											doh.f(oldPos.y == newPos.y);
+											var h1 = query('h1', dom.byId('atab4a'))[0];
+											var p1 = query('p', dom.byId('atab4a'))[0];
+											var div1 = query('div', dom.byId('atab4a'))[0];
+
+											checkInside(h1, registry.byId("tableTabContainer").domNode);
+											checkInside(p1, registry.byId("tableTabContainer").domNode);
+											checkInside(div1, registry.byId("tableTabContainer").domNode);
+
+											var newPos = geom.position(dom.byId("textAfterTabContainer2"), true);
+											doh.isNot(oldPos.y, newPos.y, "oldpos y vs. newpos y");
 											oldPos = newPos;
 										}), 1000);
 									});
-									doh.robot.mouseMoveAt('atab4_tablist_dijit_layout_LinkPane_2', 0, 1);
-									doh.robot.mouseClick({left: true}, 500);
-								}, 1000);
+									robot.mouseMoveAt('atab4_tablist_atab4a', 0, 1);
+									robot.mouseClick({left: true}, 500);
+								}), 1000);
 							});
 
-							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab4', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							
+							robot.mouseMoveAt('tableTabContainer_tablist_atab4', 0, 1);
+							robot.mouseClick({left: true}, 500);
+
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							if(handler){
+								handler.remove();
+							}
 						}
 					},
 					{
@@ -444,29 +408,29 @@
 						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							tab = dijit.byId('dijit_layout_LinkPane_3');
-							handler = tab.connect(tab, '_onShow', function(){
+
+							tab = registry.byId('atab4b');
+							handler = aspect.after(tab, '_onShow', function(){
 								setTimeout(d.getTestCallback(function(){
-									var h2 = dojo.query('h1', dojo.byId('dijit_layout_LinkPane_3'))[0];
-									var p2 = dojo.query('p', dojo.byId('dijit_layout_LinkPane_3'))[0];
+									var h2 = query('h1', dom.byId('atab4b'))[0];
+									var p2 = query('p', dom.byId('atab4b'))[0];
 
-									checkInside(h2, dijit.byId("tableTabContainer").domNode);
-									checkInside(p2, dijit.byId("tableTabContainer").domNode);
-								
-									var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
-									doh.f(oldPos.y == newPos.y);
+									checkInside(h2, registry.byId("tableTabContainer").domNode);
+									checkInside(p2, registry.byId("tableTabContainer").domNode);
+
+									var newPos = geom.position(dom.byId("textAfterTabContainer2"), true);
+									doh.isNot(oldPos.y, newPos.y, "oldpos y vs. newpos y");
 									oldPos = newPos;
 								}), 1000);
 							});
-							
-							doh.robot.mouseMoveAt('atab4_tablist_dijit_layout_LinkPane_3', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							
+
+							robot.mouseMoveAt('atab4_tablist_atab4b', 0, 1);
+							robot.mouseClick({left: true}, 500);
+
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							handler.remove();
 						}
 					},
 					{
@@ -474,27 +438,27 @@
 						timeout: 7000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							tab = dijit.byId('atab5');
-							handler = tab.connect(tab, 'onDownloadEnd', function(){
-								doh.robot.mouseMoveAt('dijit_layout_TabContainer_1_tablist_dijit_layout_ContentPane_2', 1000, 1);
-								doh.robot.mouseClick({left: true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									var p = dojo.query("p", dojo.byId('dijit_layout_ContentPane_2'))[0];
-									checkInside(p, dijit.byId("tableTabContainer").domNode);
-
-									var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
-									doh.f(oldPos.y == newPos.y);
+
+							tab = registry.byId('atab5');
+							handler = aspect.after(tab, 'onDownloadEnd', function(){
+								robot.mouseMoveAt('tableTabContainer_tablist_atab4a', 1000, 1);
+								robot.mouseClick({left: true}, 500);
+								robot.sequence(d.getTestCallback(function(){
+									var p = query("p", dom.byId('atab4a'))[0];
+									checkInside(p, registry.byId("tableTabContainer").domNode);
+
+									var newPos = geom.position(dom.byId("textAfterTabContainer2"), true);
+									doh.isNot(oldPos.y, newPos.y, "oldpos y vs. newpos y");
 									oldPos = newPos;
 								}), 1000);
 							});
-							doh.robot.mouseMoveAt('tableTabContainer_tablist_atab5', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							
+							robot.mouseMoveAt('tableTabContainer_tablist_atab5', 0, 1);
+							robot.mouseClick({left: true}, 500);
+
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							handler.remove();
 						}
 					},
 					{
@@ -502,34 +466,34 @@
 						timeout: 4000,
 						runTest: function(t){
 							var d = new doh.Deferred();
-							
-							tab = dijit.byId('dijit_layout_ContentPane_3');
-							handler = tab.connect(tab, '_onShow', function(){
+
+							tab = registry.byId('atab4b');
+							handler = aspect.after(tab, '_onShow', function(){
 								setTimeout(d.getTestCallback(function(){
-									var p1 = dojo.query("p", dojo.byId('dijit_layout_ContentPane_3'))[0];
-									var p2 = dojo.query("p", dojo.byId('dijit_layout_ContentPane_3'))[1];
-									var p3 = dojo.query("p", dojo.byId('dijit_layout_ContentPane_3'))[2];
-									checkInside(p1, dijit.byId("tableTabContainer").domNode);
-									checkInside(p2, dijit.byId("tableTabContainer").domNode);
-									checkInside(p3, dijit.byId("tableTabContainer").domNode);
-								
-									var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
-									doh.f(oldPos.y == newPos.y);
+									var p1 = query("p", dom.byId('atab4b'))[0];
+									var p2 = query("p", dom.byId('atab4b'))[1];
+									var p3 = query("p", dom.byId('atab4b'))[2];
+									checkInside(p1, registry.byId("tableTabContainer").domNode);
+									checkInside(p2, registry.byId("tableTabContainer").domNode);
+									checkInside(p3, registry.byId("tableTabContainer").domNode);
+
+									var newPos = geom.position(dom.byId("textAfterTabContainer2"), true);
+									doh.isNot(oldPos.y, newPos.y, "oldpos y vs. newpos y");
 									oldPos = newPos;
 								}), 1000);
 							});
-							
-							doh.robot.mouseMoveAt('dijit_layout_TabContainer_1_tablist_dijit_layout_ContentPane_3', 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							
+
+							robot.mouseMoveAt('tableTabContainer_tablist_atab4b', 0, 1);
+							robot.mouseClick({left: true}, 500);
+
 							return d;
 						},
 						tearDown: function(t){
-							tab.disconnect(handler);
+							handler.remove();
 						}
 					}
 				]);
-				
+				*/
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/layout/robot/borderContainerTestFunctions.js b/dijit/tests/layout/robot/borderContainerTestFunctions.js
index 3e4a6d7..8a3e5f9 100644
--- a/dijit/tests/layout/robot/borderContainerTestFunctions.js
+++ b/dijit/tests/layout/robot/borderContainerTestFunctions.js
@@ -1,99 +1,112 @@
-			function checkInside(/*Widget*/ child, /*Widget*/ parent, /*String?*/ comment){
-				// summary:
-				//		Test that child is fully inside of parent
+define(["dojo/_base/kernel", "dojo/_base/array", "dojo/dom-geometry", "dojo/json"], function(dojo, array, geom, json){
 
-				child = dijit.byId(child);
-				parent = dijit.byId(parent);
+	function dijitById(id){
+		return dojo.global.require("dijit/registry").byId(id);
+	}
 
-				var cp = dojo.position(child.domNode, true),
-					pp = dojo.position(parent.domNode, true);
+	var exports = {
+		checkInside: function(/*Widget*/ child, /*Widget*/ parent, /*String?*/ comment){
+			// summary:
+			//		Test that child is fully inside of parent
+	
+			child = dijitById(child);
+			parent = dijitById(parent);
+	
+			var cp = geom.position(child.domNode, true),
+				pp = geom.position(parent.domNode, true);
+	
+			doh.t(
+				cp.y >= pp.y && cp.y+cp.h <= pp.y+pp.h &&
+				cp.x >= pp.x && cp.x+cp.w <= pp.x+pp.w,
+				(comment ? comment + ": " : "") + child.region + " inside " + parent.id + json.stringify(cp) + json.stringify(pp)
+			);
+		},
 
-				doh.t(
-					cp.y >= pp.y && cp.y+cp.h <= pp.y+pp.h &&
-					cp.x >= pp.x && cp.x+cp.w <= pp.x+pp.w,
-					(comment ? comment + ": " : "") + child.region + " inside " + parent.id + dojo.toJson(cp) + dojo.toJson(pp)
-				);
-			}
-			function checkAbove(/*String*/ comment, /*Widget*/ above, /*Widget*/ below){
-				// summary:
-				//		Test that child is fully above parent
+		checkAbove: function(/*String*/ comment, /*Widget*/ above, /*Widget*/ below){
+			// summary:
+			//		Test that child is fully above parent
+	
+			above = dijitById(above);
+			below = dijitById(below);
+	
+			var ap = geom.position(above.domNode, true),
+				bp = geom.position(below.domNode, true);
+	
+			doh.t(ap.y+ap.h < bp.y,
+				comment + " " + above.region + " above " + below.region + json.stringify(ap) + json.stringify(bp)
+			);
+		},
 
-				above = dijit.byId(above);
-				below = dijit.byId(below);
+		checkLeft: function(/*String*/ comment, /*Widget*/ left, /*Widget*/ right){
+			// summary:
+			//		Test that child is fully left of parent
+	
+			left = dijitById(left);
+			right = dijitById(right);
+	
+			var lp = geom.position(left.domNode, true),
+				rp = geom.position(right.domNode, true);
+	
+			doh.t(lp.x+lp.w < rp.x,
+				comment + " " + left.region + " to left of " + right.region + json.stringify(lp) + json.stringify(rp)
+			);
+		},
 
-				var ap = dojo.position(above.domNode, true),
-					bp = dojo.position(below.domNode, true);
+		checkBCpanes: function(/*BorderContainer*/ bc, /*String*/ comment){
+			// summary:
+			//		Check that all the panes in this BorderContainer are in sane
+			//		positions relative to each other.   Assumes at most one pane
+			//		in each region.
+			var children = bc.getChildren(),
+				regions = {};
+	
+			// Check all panes inside BorderContainer
+			array.forEach(children, function(child, comment){
+				exports.checkInside(child, bc, comment);
+				regions[child.region] = child;
+			});
+	
+			// Check pane positions relative to each other
+			array.forEach(children, function(child){
+				switch(child.region){
+					case "top":
+						array.forEach(bc.design == "sidebar" ? ["center", "bottom"] : ["left", "center", "right", "bottom"], function(region){
+							if(regions[region]){
+								exports.checkAbove(bc.id, child, regions[region], comment);
+							}
+						});
+						break;
+					case "bottom":
+						array.forEach(bc.design == "sidebar" ? ["center", "top"] : ["left", "center", "right", "top"], function(region){
+							if(regions[region]){
+								exports.checkAbove(bc.id, regions[region], child, comment);
+							}
+						});
+						break;
+					case "left":
+						array.forEach(bc.design == "sidebar" ? ["top", "center", "bottom", "right"] : ["right"], function(region){
+							if(regions[region]){
+								exports.checkLeft(bc.id, child, regions[region], comment);
+							}
+						});
+						break;
+					case "right":
+						array.forEach(bc.design == "sidebar" ? ["top", "center", "bottom", "left"] : ["left"], function(region){
+							if(regions[region]){
+								exports.checkLeft(bc.id, regions[region], child, comment);
+							}
+						});
+						break;
+				}
+			});
+		},
 
-				doh.t(ap.y+ap.h < bp.y,
-					comment + " " + above.region + " above " + below.region + dojo.toJson(ap) + dojo.toJson(bp)
-				);
-			}
-			function checkLeft(/*String*/ comment, /*Widget*/ left, /*Widget*/ right){
-				// summary:
-				//		Test that child is fully left of parent
+		within: function(/*Number*/ a, /*Number*/ b, /*Number*/ range){
+			// summary:
+			//		Returns true if a and b are within range
+			return Math.abs(a-b) <= range;
+		}
+	};
 
-				left = dijit.byId(left);
-				right = dijit.byId(right);
-
-				var lp = dojo.position(left.domNode, true),
-					rp = dojo.position(right.domNode, true);
-
-				doh.t(lp.x+lp.w < rp.x,
-					comment + " " + left.region + " to left of " + right.region + dojo.toJson(lp) + dojo.toJson(rp)
-				);
-			}
-
-			function checkBCpanes(/*BorderContainer*/ bc){
-				// summary:
-				//		Check that all the panes in this BorderContainer are in sane
-				//		positions relative to each other.   Assumes at most one pane
-				//		in each region.
-				var children = bc.getChildren(),
-					regions = {};
-
-				// Check all panes inside BorderContainer
-				dojo.forEach(children, function(child){
-					checkInside(child, bc);
-					regions[child.region] = child;
-				});
-
-				// Check pane positions relative to each other
-				dojo.forEach(children, function(child){
-					switch(child.region){
-						case "top":
-							dojo.forEach(bc.design == "sidebar" ? ["center", "bottom"] : ["left", "center", "right", "bottom"], function(region){
-								if(regions[region]){
-									checkAbove(bc.id, child, regions[region]);
-								}
-							});
-							break;
-						case "bottom":
-							dojo.forEach(bc.design == "sidebar" ? ["center", "top"] : ["left", "center", "right", "top"], function(region){
-								if(regions[region]){
-									checkAbove(bc.id, regions[region], child);
-								}
-							});
-							break;
-						case "left":
-							dojo.forEach(bc.design == "sidebar" ? ["top", "center", "bottom", "right"] : ["right"], function(region){
-								if(regions[region]){
-									checkLeft(bc.id, child, regions[region]);
-								}
-							});
-							break;
-						case "right":
-							dojo.forEach(bc.design == "sidebar" ? ["top", "center", "bottom", "left"] : ["left"], function(region){
-								if(regions[region]){
-									checkLeft(bc.id, regions[region], child);
-								}
-							});
-							break;
-					}
-				});
-			}
-			
-			function within(/*Number*/ a, /*Number*/ b, /*Number*/ range){
-				// summary:
-				//		Returns true if a and b are within range
-				return Math.abs(a-b) <= range;
-			}
+	return exports;
+});
\ No newline at end of file
diff --git a/dijit/tests/layout/runTests.html b/dijit/tests/layout/runTests.html
index 4f9559b..afed0fe 100644
--- a/dijit/tests/layout/runTests.html
+++ b/dijit/tests/layout/runTests.html
@@ -2,7 +2,7 @@
 <html>
 	<head>
 	<title>Dijit Unit Test Runner</title>
-	<meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dijit.tests.layout.module"></HEAD>
+	<meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dijit/tests/layout/module"></HEAD>
 	<BODY>
 		Redirecting to D.O.H runner.
 	</BODY>
diff --git a/dijit/tests/layout/tab3.html b/dijit/tests/layout/tab3.html
index 6340f5e..d3caa5d 100644
--- a/dijit/tests/layout/tab3.html
+++ b/dijit/tests/layout/tab3.html
@@ -1,8 +1,8 @@
-<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='nested:true'>
-	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Subtab #1"'>
+<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='nested:true'>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Subtab #1"'>
 		<p>This is a nested tab container BUT loaded via an href.</p>
 	</div>
-	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Subtab #2"'>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Subtab #2"'>
 		<p>
 		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
diff --git a/dijit/tests/layout/tab3_noLayout.html b/dijit/tests/layout/tab3_noLayout.html
index 421867b..f9bb61c 100644
--- a/dijit/tests/layout/tab3_noLayout.html
+++ b/dijit/tests/layout/tab3_noLayout.html
@@ -1,8 +1,8 @@
-<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='doLayout:false'>
-	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Subtab #1"'>
+<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='doLayout:false'>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Subtab #1"'>
 		<p>This is a nested tab container BUT loaded via an href.</p>
 	</div>
-	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Subtab #2"'>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Subtab #2"'>
 		<p>
 		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
diff --git a/dijit/tests/layout/tab4.html b/dijit/tests/layout/tab4.html
index ea422b0..c919ada 100644
--- a/dijit/tests/layout/tab4.html
+++ b/dijit/tests/layout/tab4.html
@@ -1,8 +1,8 @@
-<div data-dojo-type="dijit.layout.SplitContainer" data-dojo-props='orientation:"vertical"'>
-	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"split #1"'>
+<div data-dojo-type="dijit/layout/SplitContainer" data-dojo-props='orientation:"vertical"'>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"split #1"'>
 		<p>Top of split container loaded via an href.</p>
 	</div>
-	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"split #2"'>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"split #2"'>
 		<p>Bottom of split container loaded via an href.</p>
 		<p>
 		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
diff --git a/dijit/tests/layout/test_AccordionContainer.html b/dijit/tests/layout/test_AccordionContainer.html
index f2fbb42..64d977c 100644
--- a/dijit/tests/layout/test_AccordionContainer.html
+++ b/dijit/tests/layout/test_AccordionContainer.html
@@ -1,53 +1,34 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Accordion Widget Demo</title>
 
-	<!-- only needed for test files: -->
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+	<script src="../boilerplate.js"></script>
 
-	<!-- only needed for alternate theme testing: -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript">
+		require([
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/layout/AccordionContainer",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/layout/TabContainer",
+			"dojo/domReady!"
+		], function(parser, _registry){
+			parser.parse();
 
-	<!-- uncomment for profiling
-		<script type="text/javascript"
-			src="../../../dojo/_base/html.js"></script>
-		<script type="text/javascript"
-			src="../../base/Layout.js"></script>
-	-->
+			// Set up global, used in button onclick handlers
+			registry = _registry;
 
-	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.AccordionContainer");
-		dojo.require("dijit.layout.AccordionPane");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.form.ComboBox");
-	 	dojo.require("dijit.form.Button");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		dojo.ready(function(){
-			dojo.subscribe("focusNode", function(node){ console.log("focused on " + (node?(node.id||node.tagName):"nothing"));});
+			createAccordion = function(){
+				var html='<div data-dojo-type="dijit/layout/AccordionContainer" id="Accordion" style="height: 300px;">' +
+						'<div data-dojo-type="dijit/layout/ContentPane" title="first" id="first">first</div>' +
+						'<div data-dojo-type="dijit/layout/ContentPane" title="second" id="second">second</div>' +
+						'</div>';
+				registry.byId("accPane").set("content",html);
+			};
 		});
-		
-		function createAccordion(){
-			var html='<div data-dojo-type="dijit.layout.AccordionContainer" id="Accordion">' +
-				 	'<div data-dojo-type="dijit.layout.ContentPane" title="first" id="first">first</div>' +
-				 	'<div data-dojo-type="dijit.layout.ContentPane" title="second" id="second">second</div>' +
-					'</div>';
-			dijit.byId("accPane").set("content",html);
-		}
 	</script>
 
 	<style type="text/css">
@@ -59,17 +40,17 @@
 		}
 	</style>
 </head>
-<body class="claro" style="padding: 50px;">
+<body class="claro" style="padding: 50px;" role="main">
 
 	<h1 class="testTitle">AccordionContainer Tests</h1>
 
 	<h2>Accordion from markup:</h2>
 
-	<input id="beforeMarkupAccordion" value="for tabIndex testing"/>
-	<div id="markupAccordion" data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props='style:"width: 400px; height: 300px; overflow: hidden"'>
-		<div id="pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true,
+	<input id="beforeMarkupAccordion" aria-label="before markup" value="for tabIndex testing"/>
+	<div id="markupAccordion" data-dojo-type="dijit/layout/AccordionContainer" data-dojo-props='style:"width: 400px; height: 300px; overflow: hidden"'>
+		<div id="pane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='selected:true,
 			title:"A Simple Pane", iconClass:"dijitEditorIcon dijitEditorIconSave", tooltip:"tooltip for simple pane" '>
-				<select>
+				<select aria-label="select a color">
 					<option>red</option>
 					<option>blue</option>
 					<option>green</option>
@@ -85,7 +66,7 @@
 				quam.
 				</p>
 				<p>
-				Sed arcu magna, molestie at, <input value="fringilla in, sodales"/> fringilla in, sodales eu, elit.
+				Sed arcu magna, molestie at, <input aria-label="Lorem" value="fringilla in, sodales"/> fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
 				augue. Integer fermentum odio lobortis odio. Nullam mollis nisl non
@@ -102,11 +83,11 @@
 		</div>
 
 		<!-- test lazy loading.   margin style for testing size calculations. -->
-		<div id="lazyLoadPane" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Lazy Load Pane", iconClass:"dijitEditorIcon dijitEditorIconCopy", href:"tab1.html",
+		<div id="lazyLoadPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Lazy Load Pane", iconClass:"dijitEditorIcon dijitEditorIconCopy", href:"tab1.html",
 			style:"margin: 5px;"'></div>
 
-		<div id="borderContainerPane" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='title:"BorderContainer Pane", iconClass:"dijitEditorIcon dijitEditorIconPaste"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:50%", splitter:true'>
+		<div id="borderContainerPane" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='title:"BorderContainer Pane", iconClass:"dijitEditorIcon dijitEditorIconPaste"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width:50%", splitter:true'>
 			1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 			Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 			vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -121,7 +102,7 @@
 			sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 			ut eros sit amet ante pharetra interdum.
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 			2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 			Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 			vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -138,7 +119,7 @@
 			</div>
 		</div>
 
-		<div id="embeddedLayoutPane" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Embedded layout widgets", iconClass:"dijitEditorIcon dijitEditorIconCut"'>
+		<div id="embeddedLayoutPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Embedded layout widgets", iconClass:"dijitEditorIcon dijitEditorIconCut"'>
 			<p>
 				The pane has some text, plus two embedded layout widgets, which should
 				appear correctly even though the pane is initially hidden.
@@ -146,8 +127,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
+			<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -162,7 +143,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -181,8 +162,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
+			<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -197,7 +178,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -218,16 +199,16 @@
 			</p>
 		</div>
 	</div>
-	<input id="afterMarkupAccordion" value="for tabIndex testing"/>
-	<button onclick="dijit.byId('pane1').set('title', 'My First Pane');">Change title of first pane</button>
-	<button onclick="dijit.byId('pane1').set('iconClass', 'plusIcon');">Change icon of first pane</button>
-	<button onclick="dijit.byId('markupAccordion').removeChild(dijit.byId('lazyLoadPane'));">Remove lazy-load pane</button>
+	<input aria-label="after" id="afterMarkupAccordion" value="for tabIndex testing"/>
+	<button onclick="registry.byId('pane1').set('title', 'My First Pane');">Change title of first pane</button>
+	<button onclick="registry.byId('pane1').set('iconClass', 'plusIcon');">Change icon of first pane</button>
+	<button onclick="registry.byId('markupAccordion').removeChild(registry.byId('lazyLoadPane'));">Remove lazy-load pane</button>
 
 	<p></p>
 	<h2>Accordion with padding</h2>
-	<div data-dojo-type="dijit.layout.AccordionContainer"
+	<div data-dojo-type="dijit/layout/AccordionContainer"
 		data-dojo-props='style:"width: 400px; height: 300px; overflow: hidden"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"somePadding", title:"Some Padding"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"somePadding", title:"Some Padding"'>
 			<p>
 				Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
 				suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.
@@ -239,7 +220,7 @@
 				quam.
 			</p>
 			<p>
-				Sed arcu magna, molestie at, <input value="fringilla in, sodales"/> eu, elit.
+				Sed arcu magna, molestie at, <input aria-label="ipsum" value="fringilla in, sodales"/> eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
 				augue. Integer fermentum odio lobortis odio. Nullam mollis nisl non
@@ -254,7 +235,7 @@
 				ut eros sit amet ante pharetra interdum.
 			</p>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"No Padding"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"No Padding"'>
 			<p>
 				Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
 				suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.
@@ -266,7 +247,7 @@
 				quam.
 			</p>
 			<p>
-				Sed arcu magna, molestie at, <input value="fringilla in, sodales"/> eu, elit.
+				Sed arcu magna, molestie at, <input aria-label="fringill" value="fringilla in, sodales"/> eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
 				augue. Integer fermentum odio lobortis odio. Nullam mollis nisl non
@@ -281,8 +262,7 @@
 				ut eros sit amet ante pharetra interdum.
 			</p>
 		</div>
-		<div data-dojo-type="dijit.layout.AccordionPane" data-dojo-props='"class":"extremePadding", title:"AccordionPane w/ Extreme Padding"'>
-			<p>(Leaving one AccordionPane to test deprecation)</p>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"extremePadding", title:"ContentPane w/ Extreme Padding"'>
 			<p>
 				Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
 				suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.
@@ -294,7 +274,7 @@
 				quam.
 			</p>
 			<p>
-				Sed arcu magna, molestie at, <input value="fringilla in, sodales"/> eu, elit.
+				Sed arcu magna, molestie at, <input aria-label="fringilla" value="fringilla in, sodales"/> eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
 				augue. Integer fermentum odio lobortis odio. Nullam mollis nisl non
@@ -313,10 +293,10 @@
 	
 	<br><br>
 	<h2>Accordion container destroy</h2>
-	<div id="accPane" data-dojo-type="dijit.layout.ContentPane" >
+	<div id="accPane" data-dojo-type="dijit/layout/ContentPane" >
 	</div>
 	Click the button twice - it will work correctly unless there was a problem destroying the accordion, in which case the second time
 	the Accordion will not be created and you will see an error like <b>Tried to register widget with id==first_button but that id is already registered</b><br/>
-	<button type="button" onclick="createAccordion()">create Accordion</button>
+	<button type="button" onclick="createAccordion();">create Accordion</button>
 </body>
 </html>
diff --git a/dijit/tests/layout/test_BorderContainer.html b/dijit/tests/layout/test_BorderContainer.html
index 45a7678..761f1b0 100644
--- a/dijit/tests/layout/test_BorderContainer.html
+++ b/dijit/tests/layout/test_BorderContainer.html
@@ -1,14 +1,12 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>dijit.layout.BorderContainer Test</title>
+	<title>dijit/layout/BorderContainer Test</title>
 
-	<!-- only needed for test files: -->
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
+	<script src="../boilerplate.js"></script>
 
+	<style type="text/css">
 		/* styles for this test */
 		.dijitContentPane:focus { color: cyan; font-weight: bold }
 		body { margin-left: 20px }
@@ -27,80 +25,82 @@
 
 	</style>
 
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
-
-	<!-- only needed for alternate theme testing: -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.form.FilteringSelect");
+		var bc, cp1, cp2, cp3;
 
-		function togglePanel(button, id){
-			var leftPanel = dijit.byId(id);
-			if(leftPanel){
-				dijit.byId('border1').removeChild(leftPanel);
-				leftPanel.destroy();
-				button.innerHTML='Add left panel';
-			}else{
-				var container = dijit.byId('border1');
-				var div = dojo.doc.createElement('div');
-				div.innerHTML='left';
-				container.domNode.appendChild(div);
-				leftPanel = new dijit.layout.ContentPane({id: id, region:'left', style:'background-color: #acb386; width:200px', splitter:true, minSize:150, maxSize:250}, div);
-				dijit.byId('border1').addChild(leftPanel);
-				button.innerHTML='Remove left panel';
+		require([
+			"dojo/_base/array",
+			"dojo/aspect",
+			"dojo/dom",
+			"dojo/dom-style",
+			"dojo/json",
+			"dojo/on",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/form/FilteringSelect",
+			"dojo/domReady!"
+		], function(array, aspect, dom, domStyle, json, on, parser, registry, BorderContainer, ContentPane, FilteringSelect){
+
+			togglePanel = function(button, id){
+				var leftPanel = registry.byId(id);
+				if(leftPanel){
+					registry.byId('border1').removeChild(leftPanel);
+					leftPanel.destroy();
+					button.innerHTML='Add left panel';
+				}else{
+					var container = registry.byId('border1');
+					var div = document.createElement('div');
+					div.innerHTML='left';
+					container.domNode.appendChild(div);
+					leftPanel = new ContentPane({id: id, region:'left', style:'background-color: #acb386; width:200px', splitter:true, minSize:150, maxSize:250}, div);
+					registry.byId('border1').addChild(leftPanel);
+					button.innerHTML='Remove left panel';
+				}
+			};
+	
+			function watchSplitters(bc){
+				var out = dom.byId("watchedOutput");
+				var moveConnects = {};
+				array.forEach(["top", "left"], function(region){
+					var spl = bc.getSplitter(region);
+	
+					aspect.after(spl, "_startDrag", function(){
+	
+						domStyle.set(spl.child.domNode, "opacity", "0.4");
+						moveConnects[spl.widgetId] = on(spl.domNode, "mousemove", function(evt){
+	
+							out.innerHTML = spl.region + ": " + json.stringify({
+								x: !spl.horizontal ? spl.domNode.style[spl.region] : 0,
+								y: spl.horizontal ? spl.domNode.style[spl.region] : 0
+							});
+						})
+	
+					});
+					aspect.after(spl, "_stopDrag", function(evt){
+						domStyle.set(spl.child.domNode, "opacity", 1);
+						moveConnects[spl.widgetId].remove();
+						delete moveConnects[spl.widgetId];
+					});
+				})
 			}
-		}
-
-		function watchSplitters(bc){
-			var out = dojo.byId("watchedOutput");
-			var moveConnects = {};
-			dojo.forEach(["top", "left"], function(region){
-				var spl = bc.getSplitter(region);
-
-				dojo.connect(spl, "_startDrag", function(){
-
-					dojo.style(spl.child.domNode, "opacity", "0.4");
-					moveConnects[spl.widgetId] = dojo.connect(spl.domNode, "onmousemove", function(evt){
 
-						out.innerHTML = spl.region + ": " + dojo.toJson({
-							x: !spl.horizontal ? spl.domNode.style[spl.region] : 0,
-							y: spl.horizontal ? spl.domNode.style[spl.region] : 0
-						});
-					})
+			parser.parse();
 
-				});
-				dojo.connect(spl, "_stopDrag", function(evt){
-					dojo.style(spl.child.domNode, "opacity", 1);
-					dojo.disconnect(moveConnects[spl.widgetId]);
-					delete moveConnects[spl.widgetId];
-				});
-			})
-		}
-
-		var bc, cp1, cp2, cp3;
-        dojo.ready(function(){
-			watchSplitters( dijit.byId("watchedBC") );
+			watchSplitters( registry.byId("watchedBC") );
 				
-			bc = new dijit.layout.BorderContainer({style:'height:400px;width:500px;border:1px solid black'}, dojo.byId('main'));
+			bc = new BorderContainer({style:'height:400px;width:500px;border:1px solid black'}, dom.byId('main'));
 
-			cp1 = new dijit.layout.ContentPane({region:'top',style:'height:100px;background-color:red',splitter:true, id:"cp1"});
+			cp1 = new ContentPane({region:'top',style:'height:100px;background-color:red',splitter:true, id:"cp1"});
 			cp1.domNode.innerHTML = "top pane";
 			bc.addChild(cp1);
 
-			cp2 = new dijit.layout.ContentPane({region:'center',style:'background-color:green', id:'cp2'});
+			cp2 = new ContentPane({region:'center',style:'background-color:green', id:'cp2'});
 			cp2.domNode.innerHTML = "center pane";
 			bc.addChild(cp2);
 
-			cp3 = new dijit.layout.ContentPane({region:'left', splitter: true, style:'width: 100px;', id:'cp3'});
+			cp3 = new ContentPane({region:'left', splitter: true, style:'width: 100px;', id:'cp3'});
 			cp3.domNode.innerHTML = "left pane";
 			
 			bc.startup();
@@ -108,33 +108,32 @@
 
 	</script>
 </head>
-<body class="claro">
-
-	<h2 class="testTitle">dijit.layout.BorderContainer tests</h2>
+<body class="claro" role="region" aria-label="main">
+	<h2 class="testTitle">dijit/layout/BorderContainer tests</h2>
 	<p>Headline layout (default), left is constrained - min:150, max:250</p>
-	<div id="border1" data-dojo-type="dijit.layout.BorderContainer"
+	<div id="border1" data-dojo-type="dijit/layout/BorderContainer"
 		data-dojo-props='style:"width: 1000px; height: 300px; border: 2px solid blue;"'>
-		<div role="banner" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-top", region:"top", style:"background-color: #b39b86; border: 15px black solid; height: 50px;", splitter:true'>
+		<div role="banner" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border1-top", region:"top", style:"background-color: #b39b86; border: 15px black solid; height: 50px;", splitter:true'>
 			top bar (resizable)
 		</div>
-		<div role="navigation" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-left", region:"left", style:"background-color: #acb386; border: 10px green solid; width: 100px;",
+		<div role="navigation" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border1-left", region:"left", style:"background-color: #acb386; border: 10px green solid; width: 100px;",
 		splitter:true, minSize:150, maxSize:250'>
 			left (resizable b/w 150 → 250)
 		</div>
-		<div role="main" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-center", region:"center", style:"background-color: #f5ffbf; padding: 30px;"'>
+		<div role="main" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border1-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select data-dojo-type="dijit.form.FilteringSelect">
+			<select aria-label="select" data-dojo-type="dijit/form/FilteringSelect">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
 			</select>
 			Here's some text that comes AFTER the combo box.
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-right", region:"right", style:"background-color: #acb386; width: 100px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border1-right", region:"right", style:"background-color: #acb386; width: 100px;"'>
 			right (fixed size)
 		</div>
-		<div role="contentinfo" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-bottom", region:"bottom", style:"background-color: #b39b86; height: 50px;", splitter:true'>
+		<div role="contentinfo" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border1-bottom", region:"bottom", style:"background-color: #b39b86; height: 50px;", splitter:true'>
 			bottom bar (resizable)
 		</div>
 	</div>
@@ -143,79 +142,79 @@
 	<br />
 
 	<p>Sidebar layout, BiDi sensitive, liveSplitters: false</p>
-	<div id="border2" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar", liveSplitters:false,
+	<div id="border2" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='design:"sidebar", liveSplitters:false,
 		style:"border: 20px solid black; width: 1000px; height: 300px;"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-leading", region:"leading", style:"background-color: #acb386; width: 100px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border2-leading", region:"leading", style:"background-color: #acb386; width: 100px;"'>
 			leading (fixed size)
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-top", region:"top", style:"background-color: #b39b86; height: 80px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border2-top", region:"top", style:"background-color: #b39b86; height: 80px;"'>
 			top bar (fixed size)
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border2-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select data-dojo-type="dijit.form.FilteringSelect">
+			<select aria-label="select" data-dojo-type="dijit/form/FilteringSelect">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
 			</select>
 			Here's some text that comes AFTER the combo box.
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-bottom", region:"bottom", style:"background-color: #b39b86; height: 80px;", splitter:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border2-bottom", region:"bottom", style:"background-color: #b39b86; height: 80px;", splitter:true'>
 			bottom bar (resizable)
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-trailing", region:"trailing", style:"background-color: #acb386; width: 100px;", splitter:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"border2-trailing", region:"trailing", style:"background-color: #acb386; width: 100px;", splitter:true'>
 			trailing (resizable)
 		</div>
 	</div>
 
 	<p>gutters=false layout</p>
 
-	<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar", gutters:false,
+	<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='design:"sidebar", gutters:false,
 		style:"border: 20px solid black; width: 1000px; height: 300px;"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"leading", style:"background-color: #acb386; width: 100px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"leading", style:"background-color: #acb386; width: 100px;"'>
 			leading
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 80px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 80px;"'>
 			top bar
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select data-dojo-type="dijit.form.FilteringSelect">
+			<select aria-label="select" data-dojo-type="dijit/form/FilteringSelect">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
 			</select>
 			Here's some text that comes AFTER the combo box.
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 80px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 80px;"'>
 			bottom bar
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"trailing", style:"background-color: #acb386; width: 100px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"trailing", style:"background-color: #acb386; width: 100px;"'>
 			trailing
 		</div>
 	</div>
 
 	<p>Vertical panels only with splitters</p>
 
-	<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar",
+	<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='design:"sidebar",
 		style:"border: 2px solid black; width: 1000px; height: 300px; padding: 10px;"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 80px;", splitter:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 80px;", splitter:true'>
 			top bar
 		</div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select data-dojo-type="dijit.form.FilteringSelect">
+			<select aria-label="select" data-dojo-type="dijit/form/FilteringSelect">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
 			</select>
 			Here's some text that comes AFTER the combo box.
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 80px;", splitter:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 80px;", splitter:true'>
 			bottom bar
 		</div>
 	</div>
@@ -223,41 +222,42 @@
 	<br />
 	<p>More fun with layouts</p>
 
-	<div id="mondrian" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar", gutters:false, persist:true, style:"height: 300px; width: 400px;"'>
-		<div id="mondrian_top" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"height: 100px", splitter:true'>
-			<div id="mondrian_top_bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='persist:true, gutters:false, style:"height: 100px; width: 100%"'>
-				<div id="top_a" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"leading", style:"width: 125px", splitter:true'><span>top a</span></div>
-				<div id="top_b" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: yellow", splitter:true'><span>top b</span></div>
+	<div id="mondrian" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='design:"sidebar", gutters:false, persist:true, style:"height: 300px; width: 400px;"'>
+		<div id="mondrian_top" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", style:"height: 100px", splitter:true'>
+			<div id="mondrian_top_bc" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='persist:true, gutters:false, style:"height: 100px; width: 100%"'>
+				<div id="top_a" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"leading", style:"width: 125px", splitter:true'><span>top a</span></div>
+				<div id="top_b" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center", style:"background-color: yellow", splitter:true'><span>top b</span></div>
 			</div>
 		</div>
-		<div id="mondrian_bottom" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"height: 100px", splitter:true'>
-			<div id="mondrian_bottom_bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='persist:true, gutters:false, style:"height: 100px; width: 100%"'>
-				<div id="bottom_c" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"height: 40px", splitter:true'><span>bottom c</span></div>
-				<div id="bottom_d" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'><span>bottom d</span></div>
+		<div id="mondrian_bottom" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"bottom", style:"height: 100px", splitter:true'>
+			<div id="mondrian_bottom_bc" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='persist:true, gutters:false, style:"height: 100px; width: 100%"'>
+				<div id="bottom_c" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", style:"height: 40px; background-color: blue;", splitter:true'><span>bottom c</span></div>
+				<div id="bottom_d" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'><span>bottom d</span></div>
 			</div>
 		</div>
-		<div id="mondrian_leading" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"leading", style:"width: 100px", splitter:true'>
-			<div id="mondrian_leading_bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='persist:true, gutters:false, style:"height: 300px; width: 100%"'>
-				<div id="leading_e" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'><span>leading e</span></div>
-				<div id="leading_f" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"height: 100px; background-color: red", splitter:true'><span>leading f</span></div>
+		<div id="mondrian_leading" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"leading", style:"width: 100px", splitter:true'>
+			<div id="mondrian_leading_bc" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='persist:true, gutters:false, style:"height: 300px; width: 100%"'>
+				<div id="leading_e" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'><span>leading e</span></div>
+				<div id="leading_f" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"bottom", style:"height: 100px; background-color: red", splitter:true'><span>leading f</span></div>
 			</div>
 		</div>
-		<div id="trailing_g" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"trailing", style:"width: 100px", splitter:true'><span>trailing g</span></div>
+		<div id="trailing_g" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center", splitter:true'><span>trailing g</span></div>
+		<div id="trailing_h" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"trailing", style:"width: 100px", splitter:true'><span>trailing g</span></div>
 	</div>
 
 	<br />
 	<p>Watching the splitter events</p>
-	<div id="watchedBC" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='persist:false, gutters:false, style:"height: 200px; width: 100%"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", splitter:true, style:"background-color: #ccffcc; height: 50px;"'>Top:</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"background-color: #ccccff; width: 40px", splitter:true'><span>Bottom</span></div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: #ffffcc"'><span>Center</span></div>
+	<div id="watchedBC" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='persist:false, gutters:false, style:"height: 200px; width: 100%"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", splitter:true, style:"background-color: #ccffcc; height: 50px;"'>Top:</div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"background-color: #ccccff; width: 40px", splitter:true'><span>Left</span></div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center", style:"background-color: #ffffcc"'><span>Center</span></div>
 	</div>
 
 	<p>Splitter coords output:</p>
 	<div id="watchedOutput" style="border: 1px solid #999">nothing moving</div>
 
 	
-	<h2 class="testTitle">dijit.layout.BorderContainer programmatic test</h2>
+	<h2 class="testTitle">dijit/layout/BorderContainer programmatic test</h2>
 	<div id='main'></div>
 
 	<button id="addLeft" onclick="bc.addChild(cp3);">add left pane</button>
diff --git a/dijit/tests/layout/test_BorderContainer_complex.html b/dijit/tests/layout/test_BorderContainer_complex.html
index e1b7469..54efea9 100644
--- a/dijit/tests/layout/test_BorderContainer_complex.html
+++ b/dijit/tests/layout/test_BorderContainer_complex.html
@@ -1,50 +1,40 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>dijit.layout.BorderContainer Test - complex layout</title>
+	<title>dijit/layout/BorderContainer Test - complex layout</title>
 
-	<!-- only needed for test files: -->
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
-
-	<!-- only needed for alternate theme testing: -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit.layout.AccordionContainer");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.LinkPane");
-		dojo.require("dijit.Tooltip");
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.layout.SplitContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.form.FilteringSelect");
+		require([
+			"dojo/parser",
+			"dijit/layout/AccordionContainer",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/Editor",
+			"dijit/form/FilteringSelect",
+			"dijit/layout/SplitContainer",
+			"dijit/layout/TabContainer",
+			"dijit/Tooltip",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
-	<h1 class="testTitle">dijit.layout.BorderContainer complex layout test</h1>
+	<h1 class="testTitle">dijit/layout/BorderContainer complex layout test</h1>
 
-	<div id="border1" data-dojo-type="dijit.layout.BorderContainer"
+	<div id="border1" data-dojo-type="dijit/layout/BorderContainer"
 		data-dojo-props='style:"border: 2px solid black; width: 90%; height: 500px; padding: 10px;" '>
-		<div id="ac1" data-dojo-type="dijit.layout.AccordionContainer"
+		<div id="ac1" data-dojo-type="dijit/layout/AccordionContainer"
 			data-dojo-props='region:"left", style:"background-color: #acb386; width: 400px;", splitter:true'>
-			<div id="ap1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"a"'>
+			<div id="ap1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"a"'>
 				left bar
 			</div>
-			<div id="ap2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"b"'>
+			<div id="ap2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"b"'>
 				<p>
 					Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
 					suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.
@@ -71,17 +61,17 @@
 					ut eros sit amet ante pharetra interdum.
 				</p>
 			</div>
-			<div id="ap3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"c"'>
+			<div id="ap3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"c"'>
 				<p>The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.</p>
 			</div>
 		</div>
 
-		<div data-dojo-type="dijit.layout.AccordionContainer"
+		<div data-dojo-type="dijit/layout/AccordionContainer"
 			data-dojo-props='region:"right", style:"background-color: #acb386; width: 80px;"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"a"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"a"'>
 				right bar
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"b"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"b"'>
 				<p>
 					Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
 					suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.
@@ -108,26 +98,26 @@
 					ut eros sit amet ante pharetra interdum.
 				</p>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"c"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"c"'>
 				<p>The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.</p>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 150px;", splitter:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 150px;", splitter:true'>
 
-			<div id="mainTabContainer" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 100%; height: 20em;"'>
+			<div id="mainTabContainer" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 100%; height: 20em;"'>
 
-				<div id="tab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"../../../dijit/tests/layout/tab1.html", title:"Tab 1"'></div>
+				<div id="tab1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"../../../dijit/tests/layout/tab1.html", title:"Tab 1"'></div>
 
-				<div id="tab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"../../../dijit/tests/layout/tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+				<div id="tab2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"../../../dijit/tests/layout/tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-				<div id="tab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 3"'>
+				<div id="tab3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 3"'>
 					<h1>I am tab 3</h1>
 					<p>And I was already part of the page! That's cool, no?</p>
 					<p id="foo">tooltip on this paragraph</p>
-					<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo"]'>I'm a tooltip!</div>
-					<button data-dojo-type="dijit.form.Button">I'm a button </button>
+					<div data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["foo"]'>I'm a tooltip!</div>
+					<button data-dojo-type="dijit/form/Button">I'm a button </button>
 					<br>
-					<button data-dojo-type="dijit.form.Button">So am I!</button>
+					<button data-dojo-type="dijit/form/Button">So am I!</button>
 					<p>
 					Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 					semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -151,26 +141,26 @@
 					</p>
 				</div>
 
-				<div id="tab4" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Inlined Sub TabContainer"'>
-					<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"../../../dijit/tests/layout/tab1.html"'>SubTab 1</a>
-					<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"../../../dijit/tests/layout/tab2.html", selected:true'>SubTab 2</a>
+				<div id="tab4" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"Inlined Sub TabContainer"'>
+					<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"../../../dijit/tests/layout/tab1.html"' title="SubTab 1"></div>
+					<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"../../../dijit/tests/layout/tab2.html", selected:true' title="SubTab 2"></div>
 				</div>
 
-				<a id="tab5" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"../../../dijit/tests/layout/tab3.html"'>Sub TabContainer from href</a>
+				<div id="tab5" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"../../../dijit/tests/layout/tab3.html"' title="Sub TabContainer from href"></div>
 
-				<a id="tab6" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"../../../dijit/tests/layout/tab4.html"'>SplitContainer from href</a>
+				<div id="tab6" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"../../../dijit/tests/layout/tab4.html"' title="SplitContainer from href"></div>
 
 			</div>
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 150px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 150px;"'>
 			<div style="border: 1px solid black;">
-				<div id="editor1" data-dojo-type="dijit.Editor" ><p>bottom bar (edit me)</p></div>
+				<div id="editor1" aria-label="editor" data-dojo-type="dijit/Editor" ><p>bottom bar (edit me)</p></div>
 			</div>
 		</div>
-		<div id="mainCP" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+		<div id="mainCP" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select id="filteringSelect" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props='style:"width:4em;"'>
+			<select id="filteringSelect" aria-label="filtering select" data-dojo-type="dijit/form/FilteringSelect" data-dojo-props='style:"width:4em;"'>
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
diff --git a/dijit/tests/layout/test_BorderContainer_experimental.html b/dijit/tests/layout/test_BorderContainer_experimental.html
index 1422707..44e5b8d 100644
--- a/dijit/tests/layout/test_BorderContainer_experimental.html
+++ b/dijit/tests/layout/test_BorderContainer_experimental.html
@@ -1,13 +1,12 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
     <head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>BorderContainer Experiments | The Dojo Toolkit</title>
 
-		<!-- only needed for test files: -->
+		<script src="../boilerplate.js"></script>
+
 		<style type="text/css">
-			@import "../../themes/claro/document.css";
-			@import "../css/dijitTests.css";
 			#pane1 { background-color:red;
 			}
 			#pane2{
@@ -23,27 +22,28 @@
 			.bc { margin:10px; border:2px solid #ededed; }
 		</style>
 
-		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../dojo/dojo.js"
-			data-dojo-config="isDebug: true"></script>
+		<script type="text/javascript">
+			require([
+				"dojo/_base/array",
+				"dojo/_base/declare",
+				"dojo/dom",
+				"dojo/dom-construct",
+				"dojo/dom-style",
+				"dojo/parser",
+				"dojo/query",
+				"dijit/registry",
+				"dijit/layout/BorderContainer",
+				"dijit/form/Button",
+				"dijit/layout/ContentPane",
+				"dojo/domReady!"
+			], function(array, declare, dom, domConstruct, domStyle, parser, query,
+						registry, BorderContainer, Button, ContentPane){
 
-		<!-- only needed for alternate theme testing: -->
-		<script type="text/javascript" src="../_testCommon.js"></script>
+				var open = false;
 
-		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-			dojo.require("dijit.form.Button");
-			dojo.require("dijit.layout.ContentPane");
-			dojo.require("dijit.layout.BorderContainer");
 
-			var open = false;
+				declare("my.BorderContainer", BorderContainer,{
 
-			dojo.ready(function(){
-				dojo.declare("my.BorderContainer",dijit.layout.BorderContainer,{
-	
 					opts: {
 						// single pane view
 						"a":{
@@ -72,15 +72,15 @@
 								{ id: "pane3", hidden:true }
 							]
 						}
-	
+
 					},
-	
+
 					_clearSplitters: function(){
 						// cleanup all splitters on the page
-						dojo.query(".dijitSplitter",this.domNode).forEach(function(n){
-							dijit.byNode(n).destroy();
+						query(".dijitSplitter",this.domNode).forEach(function(n){
+							registry.byNode(n).destroy();
 						});
-						dojo.query(".dijitSplitterCover").forEach(dojo.destroy);
+						query(".dijitSplitterCover").forEach(domConstruct.destroy);
 						delete this._splitters;
 						this._splitters = {};
 					},
@@ -93,16 +93,16 @@
 							var struct = this.opts[lay] || false;
 							this._clearSplitters();
 	
-							dojo.forEach(struct.panes,function(pane,i){
+							array.forEach(struct.panes,function(pane,i){
 								// setup each pane
-								var d = dijit.byId(pane.id);
+								var d = registry.byId(pane.id);
 								d.region = pane.region || "center";
 								d.splitter = pane.sizeable;
 								if(pane.minSize){ d.minSize = pane.minSize; }
 								if(pane.maxSize){ d.maxSize = pane.maxSize; }
 								if(pane.hidden){
 									// reset this widget to our hidden holder node
-									this.extractChild(d,dojo.byId("holder"));
+									this.extractChild(d,dom.byId("holder"));
 									d.splitter = null;
 									d.region = null;
 									d.maxSize = null;
@@ -110,7 +110,7 @@
 								}else{
 									if(pane.style){
 										// object setter via style only in trunk:
-										dojo.style(d.domNode,pane.style);
+										domStyle.set(d.domNode, pane.style);
 									}
 									this.addChild(d,i);
 								}
@@ -119,14 +119,14 @@
 						this.layout();
 					},
 	
-					extractChild: function(/*dijit._Widget*/ child, /*DomNode*/ node){
+					extractChild: function(/*dijit/_WidgetBase*/ child, /*DomNode*/ node){
 						// a non-destructive cleanup for the bordercontainer.
 						// cleanup a widget, and append it's domNode to some
 						// other node in the dom
 						var region = child.region;
 						var splitter = this._splitters[region];
 						if(splitter){
-							dijit.byNode(splitter).destroy();
+							registry.byNode(splitter).destroy();
 							delete this._splitters[region];
 						}
 						delete this["_"+region];
@@ -138,19 +138,19 @@
 					}
 				});
 	
-				dojo.parser.parse();
+				parser.parse();
 
 				// make buttons
-				dojo.forEach(["a","av","ah"],function(n){
+				array.forEach(["a","av","ah"],function(n){
 
-					var but = new dijit.form.Button({
+					var but = new Button({
 						label: "Set "+n,
 						onClick: function(){
 							console.log(n);
 							layout.setLayoutENUM(n);
 						}
 					});
-					dojo.byId("buttons").appendChild(but.domNode);
+					dom.byId("buttons").appendChild(but.domNode);
 					but.startup();
 				})
 
@@ -158,7 +158,12 @@
 		</script>
 
     </head>
-    <body class="claro">
+    <body class="claro" role="main">
+
+		<script type="dojo/require">
+			fx: "dojo/_base/fx",
+			registry: "dijit/registry"
+		</script>
 
 		<h1>This is a test</h1>
 		<p>This is only a test. An experiment in dynamically altering a BorderContainer's layout
@@ -172,13 +177,13 @@
 		</div>
 
 		<div id="container" data-dojo-id="layout" data-dojo-type="my.BorderContainer" data-dojo-props='style:"width:600px; height:300px; border:3px solid #333;"'>
-			<div id="pane0" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center" '>
+			<div id="pane0" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center" '>
 				pane0
 			</div>
 		</div>
 
-		<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+		<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 				Sinlge pane - l1
 			</div>
 		</div>
@@ -187,23 +192,23 @@
 			<h3>two panes, vertical split:</h3>
 
 
-			<div id="animBC" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
-				<div id="sizing1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='style:"background-color:red", region:"left", splitter:true'>
+			<div id="animBC" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
+				<div id="sizing1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='style:"background-color:red", region:"left", splitter:true'>
 					Sinlge pane - left
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='region:"center"'>
+				<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='region:"center"'>
 					Sinlge pane - center
-					<button data-dojo-type="dijit.form.Button">
+					<button data-dojo-type="dijit/form/Button">
 					Size Me
 					<script type="dojo/method" data-dojo-event="onClick">
-						var n = dijit.byId("sizing1").domNode;
-						dojo.animateProperty({
+						var n = registry.byId("sizing1").domNode;
+						fx.animateProperty({
 							node:n,
 							duration:1000,
 							properties: { width: { end: (open ? "100" : "400"), units:"px" } },
 							onEnd: function(){
 								open = !open;
-								dijit.byId("animBC").layout();
+								registry.byId("animBC").layout();
 							}
 						}).play(1);
 					</script>
@@ -211,51 +216,51 @@
 				</div>
 			</div>
 
-			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", splitter:true'>
+			<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center", splitter:true'>
 					Single pane - center (splitter) (this is unsupported, and does not work)
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"right"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"right"'>
 					Single pane - right (no splitter)
 				</div>
 			</div>
 
-			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+			<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 					Single pane - center (no splitter)
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"right", splitter:true'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"right", splitter:true'>
 					Single pane - right (splitter)
 				</div>
 			</div>
 		</div>
 
-		<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"width:200px; height:400px;"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", splitter:true'>
+		<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='"class":"bc", style:"width:200px; height:400px;"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", splitter:true'>
 				Single pane - top (splitter)
 
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 				Single pane - center
 			</div>
 		</div>
 
-		<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"width:200px; height:400px;"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+		<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='"class":"bc", style:"width:200px; height:400px;"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 				Single pane - center
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", splitter:true'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"bottom", splitter:true'>
 				Single Pane Bottom (splitter)
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", splitter:true'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", splitter:true'>
 				Single Pane Top (splitter)
 			</div>
 		</div>
 
 		<div id="holder" style="visibility:hidden">
-			<div id="pane1" data-dojo-type="dijit.layout.ContentPane" >pane 1</div>
-			<div id="pane2" data-dojo-type="dijit.layout.ContentPane" >pane 2</div>
-			<div id="pane3" data-dojo-type="dijit.layout.ContentPane" >pane 3</div>
+			<div id="pane1" data-dojo-type="dijit/layout/ContentPane" >pane 1</div>
+			<div id="pane2" data-dojo-type="dijit/layout/ContentPane" >pane 2</div>
+			<div id="pane3" data-dojo-type="dijit/layout/ContentPane" >pane 3</div>
 		</div>
 
     </body>
diff --git a/dijit/tests/layout/test_BorderContainer_full.html b/dijit/tests/layout/test_BorderContainer_full.html
index fa27fbd..b4de990 100644
--- a/dijit/tests/layout/test_BorderContainer_full.html
+++ b/dijit/tests/layout/test_BorderContainer_full.html
@@ -1,13 +1,12 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>dijit.layout.BorderContainer Test - Full Screen</title>
+	<title>dijit/layout/BorderContainer Test - Full Screen</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
+	<script src="../boilerplate.js"></script>
 
+	<style type="text/css">
 		html, body, #main{
 			width: 100%;	/* make the body expand to fill the visible window */
 			height: 100%;
@@ -18,46 +17,34 @@
 		}
 	</style>
 
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
-
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.form.FilteringSelect");
+		require(["dojo/parser", "dojo/domReady!"], function(parser){
+			parser.parse();
+		});
 	</script>
-
 </head>
-<body class="claro">
-	<div id="main" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar" '>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"main-leading", region:"leading", style:"background-color: #acb386; width: 100px;"'>
+<body class="claro" role="main">
+	<div id="main" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='design:"sidebar" '>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"main-leading", region:"leading", style:"background-color: #acb386; width: 100px;"'>
 			leading
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"main-top", region:"top", style:"background-color: #b39b86; height: 100px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"main-top", region:"top", style:"background-color: #b39b86; height: 100px;"'>
 			top bar
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"main-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"main-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select data-dojo-type="dijit.form.FilteringSelect">
+			<select aria-label="select" data-dojo-type="dijit/form/FilteringSelect">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
 			</select>
 			Here's some text that comes AFTER the combo box.
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"main-bottom", region:"bottom", style:"background-color: #b39b86; height: 100px;", splitter:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"main-bottom", region:"bottom", style:"background-color: #b39b86; height: 100px;", splitter:true'>
 			bottom bar
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"main-trailing", region:"trailing", style:"background-color: #acb386; width: 100px;", splitter:true'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"main-trailing", region:"trailing", style:"background-color: #acb386; width: 100px;", splitter:true'>
 			trailing
 		</div>
 	</div>
diff --git a/dijit/tests/layout/test_BorderContainer_nested.html b/dijit/tests/layout/test_BorderContainer_nested.html
index e7a3d29..323bd17 100644
--- a/dijit/tests/layout/test_BorderContainer_nested.html
+++ b/dijit/tests/layout/test_BorderContainer_nested.html
@@ -1,35 +1,27 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>dijit.layout.BorderContainer Test</title>
+	<title>dijit/layout/BorderContainer Nested Test</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
-
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.form.FilteringSelect");
+		require([
+			"dojo/parser",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/form/FilteringSelect",
+			"dijit/layout/TabContainer",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
-	<h2 class="testTitle">dijit.layout.BorderContainer tests</h2>
+	<h2 class="testTitle">dijit/layout/BorderContainer Nested tests</h2>
 
 	<p>
 		The second tab holds a single BorderContainer but specifying layoutPriority on it's children to have multiple children
@@ -39,38 +31,38 @@
 		The first tab holds a BorderContainer which nests another BorderContainer, simulating multiple children in a single region.
 	</p>
 
-	<div id="tc" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width:800px;height:600px;"'>
-		<div id="nbc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='title:"Nested BC"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"background-color: #acb386; width: 100px;"'>
+	<div id="tc" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width:800px;height:600px;"'>
+		<div id="nbc" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='title:"Nested BC"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"background-color: #acb386; width: 100px;"'>
 				left
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"right", style:"background-color: #acb386; width: 100px;"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"right", style:"background-color: #acb386; width: 100px;"'>
 				right
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 100px;"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 100px;"'>
 				top bar
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 100px;"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 100px;"'>
 				bottom bar
 			</div>
 
-			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='region:"center", design:"sidebar"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"background-color: #acb386; width: 100px;"'>
+			<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='region:"center", design:"sidebar"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"background-color: #acb386; width: 100px;"'>
 					left inner
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"right", style:"background-color: #acb386; width: 100px;"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"right", style:"background-color: #acb386; width: 100px;"'>
 					right inner
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 100px;"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 100px;"'>
 					inner top bar
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 100px;"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 100px;"'>
 					inner bottom bar
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 					main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 					(to check we're copying children around properly).<br />
-					<select data-dojo-type="dijit.form.FilteringSelect">
+					<select aria-label="select" data-dojo-type="dijit/form/FilteringSelect">
 						<option value="1">foo</option>
 						<option value="2">bar</option>
 						<option value="3">baz</option>
@@ -80,49 +72,49 @@
 			</div>
 		</div>
 
-		<div id="pbc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='title:"layoutPriority BC"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"top1", region:"top", splitter:true, layoutPriority: 1, style:"background-color: #077; color: white; height: 50px;"'>
-				top bar (layoutPriority == 1)
+		<div id="pbc" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='title:"layoutPriority BC"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"top1", region:"top", splitter:true, layoutPriority: 1, style:"background-color: #077; color: white; height: 50px;"'>
+				<label for="top1_input">top bar (layoutPriority == 1)</label>
 				<input id="top1_input" value="tabstop #1"/>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"top2", region:"top", splitter:true, layoutPriority: 2, style:"background-color: #f5ffbf; height: 50px;"'>
-				second top bar (layoutPriority == 2)
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"top2", region:"top", splitter:true, layoutPriority: 2, style:"background-color: #f5ffbf; height: 50px;"'>
+				<label for="top2_input">second top bar (layoutPriority == 2)</label>
 				<input id="top2_input" value="tabstop #3"/>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"left1", region:"left", splitter:true, layoutPriority: 3, style:"background-color: #770; width: 100px;"'>
-				left (layoutPriority == 3)
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"left1", region:"left", splitter:true, layoutPriority: 3, style:"background-color: #770; width: 100px;"'>
+				<label for="left1_input">left (layoutPriority == 3)</label>
 				<input id="left1_input" value="tabstop #5"/>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"left2", region:"left", splitter:true, layoutPriority: 4, style:"background-color: #acb386; width: 100px;"'>
-				inner left (layoutPriority == 4)
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"left2", region:"left", splitter:true, layoutPriority: 4, style:"background-color: #acb386; width: 100px;"'>
+				<label for="left2_input">inner left (layoutPriority == 4)</label>
 				<input id="left2_input" value="tabstop #7"/>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"top3", region:"top", splitter:true, layoutPriority: 5, style:"background-color: #b39b86; height: 50px;"'>
-				inner top bar (layoutPriority == 5)
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"top3", region:"top", splitter:true, layoutPriority: 5, style:"background-color: #b39b86; height: 50px;"'>
+				<label for="top3_input">inner top bar (layoutPriority == 5)</label>
 				<input id="top3_input" value="tabstop #9"/>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
-				center
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+				<label for="center_input">center</label>
 				<input id="center_input" value="tabstop #11"/>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"bottom3", region:"bottom", splitter:true, layoutPriority: 5, style:"background-color: #b39b86; height: 50px;"'>
-				inner bottom bar (layoutPriority == 5)
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"bottom3", region:"bottom", splitter:true, layoutPriority: 5, style:"background-color: #b39b86; height: 50px;"'>
+				<label for="bottom3_input">inner bottom bar (layoutPriority == 5)</label>
 				<input id="bottom3_input" value="tabstop #12"/>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"right2", region:"right", splitter:true, layoutPriority: 4, style:"background-color: #acb386; width: 100px;"'>
-				inner right (layoutPriority == 4)
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"right2", region:"right", splitter:true, layoutPriority: 4, style:"background-color: #acb386; width: 100px;"'>
+				<label for="right2_input">inner right (layoutPriority == 4)</label>
 				<input id="right2_input" value="tabstop #14"/>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"right1", region:"right", splitter:true, layoutPriority: 3, style:"background-color: #770; width: 100px;"'>
-				right (layoutPriority == 3)
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"right1", region:"right", splitter:true, layoutPriority: 3, style:"background-color: #770; width: 100px;"'>
+				<label for="right1_input">right (layoutPriority == 3)</label>
 				<input id="right1_input" value="tabstop #16"/>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"bottom2", region:"bottom", splitter:true, layoutPriority: 2, style:"background-color: #f5ffbf; height: 50px;"'>
-				second bottom bar (layoutPriority == 2)
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"bottom2", region:"bottom", splitter:true, layoutPriority: 2, style:"background-color: #f5ffbf; height: 50px;"'>
+				<label for="bottom2_input">second bottom bar (layoutPriority == 2)</label>
 				<input id="bottom2_input" value="tabstop #18"/>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id: "bottom1", region:"bottom", splitter:true, layoutPriority: 1, style:"background-color: #077; color: white; height: 50px;"'>
-				bottom bar (layoutPriority == 1)
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id: "bottom1", region:"bottom", splitter:true, layoutPriority: 1, style:"background-color: #077; color: white; height: 50px;"'>
+				<label for="bottom1_input">bottom bar (layoutPriority == 1)</label>
 				<input id="bottom1_input" value="tabstop #20"/>
 			</div>
 		</div>
diff --git a/dijit/tests/layout/test_ContentPane.html b/dijit/tests/layout/test_ContentPane.html
index 76298e1..cac73ef 100644
--- a/dijit/tests/layout/test_ContentPane.html
+++ b/dijit/tests/layout/test_ContentPane.html
@@ -1,13 +1,12 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>ContentPane Test</title>
 
-	<style>
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
+	<style>
 		.box {
 			position: relative;
 			background-color: white;
@@ -17,170 +16,160 @@
 		}
 	</style>
 
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-
 	<script type="text/javascript">
-		dojo.require('doh.runner');
-
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		dojo.require("dojo.data.ItemFileReadStore");
-
-		dojo.require("dijit._Widget");
-		dojo.require("dijit._TemplatedMixin");
-		dojo.require("dijit.Dialog");
-		dojo.require("dijit.InlineEditBox");
-		dojo.require("dijit.form.ComboBox");
-		dojo.require("dijit.layout.ContentPane");
+		require([
+			"doh/runner",
+			"dojo/_base/declare",
+			"dojo/dom",
+			"dojo/dom-construct",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/_WidgetBase",
+			"dijit/_TemplatedMixin",
+			"dijit/layout/ContentPane",
+			"dijit/Dialog",
+			"dojo/domReady!"
+		], function(doh, declare, dom, domConstruct, parser,
+					registry, _WidgetBase, _TemplatedMixin){
 
-		dojo.ready(function(){
 
 			// create a do nothing, only for test widget
-			dojo.declare("dijit.TestWidget",
-				[dijit._Widget, dijit._TemplatedMixin], {
+			declare("TestWidget", [_WidgetBase, _TemplatedMixin], {
 				templateString: "<span class='dojoxTestWidget'></span>"
 			});
 
 			doh.register("parse", function(){
-				dojo.parser.parse();				
+				parser.parse();
 
-				pane1 = dijit.byId('parsedPane');
-				dialogCtrPane = dijit.byId("dialogContainer");
+				pane1 = registry.byId('parsedPane');
+				dialogCtrPane = registry.byId("dialogContainer");
 			});
 
 			doh.register("basicChecks", [
-			{
-				name: 'setContent',
-				runTest: function(t){
-					console.log("basicChecks: " + this.name);
-					var msg = "Simple Test";
-					pane1.set('content', msg);
-					t.assertEqual(msg, pane1.domNode.innerHTML);
+				{
+					name: 'setContent',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						var msg = "Simple Test";
+						pane1.set('content', msg);
+						t.is(msg, pane1.domNode.innerHTML);
+					}
+				},
+				{
+					name: 'parseInitialContent',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						var parserTest = registry.byId("parserTest");
+						t.t(parserTest);
+					}
+				},
+				{
+					name: 'parseNewContent',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						dialogCtrPane.set(
+							"content",
+							'<div data-dojo-type="dijit/Dialog" id="sacrificialDlg" title="Life is short for this fellow">'
+							+'	<p>This dialog should be cleanly destroyed when the unit tests run</p>'
+							+'</div>'
+						);
+
+						t.t(registry.byId("sacrificialDlg"));
+						t.f(registry.byId("parserTest"));
+					}
+				},
+				{
+					name: 'empty',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						t.t(registry.byId("sacrificialDlg"));
+
+						var dialog = registry.byId("sacrificialDlg");
+						// dialog is supposed to move its domNode to the body..
+						// we need to check it gets cleanly removed when we set content on the CP
+						t.t(dialog);
+						t.t(dialog.domNode.parentNode == document.body);
+
+						dialogCtrPane.set('content', "new content, no more dialog");
+						t.f(registry.byId("sacrificialDlg"));
+						t.f(dom.byId("sacrificialDlg"));
+					}
+				},
+				{
+					name: 'reuse',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						// do the same thing over again - we should be error free
+						dialogCtrPane.set(
+							"content",
+							'<div data-dojo-type="dijit/Dialog" id="sacrificialDlg" title="Life is short for this fellow">'
+							+'	<p>This dialog should be cleanly destroyed when the unit tests run</p>'
+							+'</div>'
+						);
+						var dialog = registry.byId("sacrificialDlg");
+						// dialog is supposed to move its domNode to the body..
+						// we need to check it gets cleanly removed when we set content on the CP
+						t.t(dialog);
+						t.t(dialog.domNode.parentNode == document.body);
+					}
+				},
+				{
+					name: 'destroy',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+
+						// manually stick a widget into the ContentPane
+						var manualWidget = new TestWidget({id: "destroyTestWidget"});
+						domConstruct.place(manualWidget.domNode, dialogCtrPane.domNode, "last");
+
+						// make sure widget created via get('content') and also the above widget are there
+						t.t(registry.byId("sacrificialDlg"), "dialog in dialogContainer still there");
+						t.t(registry.byId("destroyTestWidget"), "test widget in dialogContainer still there");
+
+						// when we kill the CP, it should also destroy any widgets created when we set content,
+						// and for backwards-compatibility reasons, any widgets that user stuck in there
+						// manually too
+						dialogCtrPane.destroyRecursive();
+
+						// make sure everything got deleted
+						t.f(registry.byId("dialogContainer"));
+						t.f(registry.byId("sacrificialDlg"), "dialog in dialogContainer was destroyed");
+						t.f(registry.byId("destroyTestWidget"), "test widget in dialogContainer was destroyed");
+						t.f(dom.byId("sacrificialDlg"));
+					}
 				}
-			},
-			{
-				name: 'parseInitialContent',
-				runTest: function(t){
-					console.log("basicChecks: " + this.name);
-					var parserTest = dijit.byId("parserTest");
-					t.assertTrue(parserTest);
-				}
-			},
-			{
-				name: 'parseNewContent',
-				runTest: function(t){
-					console.log("basicChecks: " + this.name);
-					dialogCtrPane.set(
-						"content",
-						'<div data-dojo-type="dijit.Dialog" id="sacrificialDlg" title="Life is short for this fellow">'
-						+'	<p>This dialog should be cleanly destroyed when the unit tests run</p>'
-						+'</div>'
-					);
-
-					t.assertTrue(dijit.byId("sacrificialDlg"));
-					t.assertFalse(dijit.byId("parserTest"));
-				}
-			},
-			{
-				name: 'empty',
-				runTest: function(t){
-					console.log("basicChecks: " + this.name);
-					t.assertTrue(dijit.byId("sacrificialDlg"));
-
-					var dialog = dijit.byId("sacrificialDlg");
-					// dialog is supposed to move its domNode to the body..
-					// we need to check it gets cleanly removed when we set content on the CP
-					t.assertTrue(dialog);
-					t.assertTrue(dialog.domNode.parentNode == dojo.body());
-
-					dialogCtrPane.set('content', "new content, no more dialog");
-					t.assertFalse(dijit.byId("sacrificialDlg"));
-					t.assertFalse(dojo.byId("sacrificialDlg"));
-				}
-			},
-			{
-				name: 'reuse',
-				runTest: function(t){
-					console.log("basicChecks: " + this.name);
-					// do the same thing over again - we should be error free
-					dialogCtrPane.set(
-						"content",
-						'<div data-dojo-type="dijit.Dialog" id="sacrificialDlg" title="Life is short for this fellow">'
-						+'	<p>This dialog should be cleanly destroyed when the unit tests run</p>'
-						+'</div>'
-					);
-					var dialog = dijit.byId("sacrificialDlg");
-					// dialog is supposed to move its domNode to the body..
-					// we need to check it gets cleanly removed when we set content on the CP
-					t.assertTrue(dialog);
-					t.assertTrue(dialog.domNode.parentNode == dojo.body());
-				}
-			},
-			{
-				name: 'destroy',
-				runTest: function(t){
-					console.log("basicChecks: " + this.name);
-
-					// manually stick a widget into the ContentPane
-					var manualWidget = new dijit.TestWidget({id: "destroyTestWidget"});
-					dojo.place(manualWidget.domNode, dialogCtrPane.domNode, "last");
-
-					// make sure widget created via get('content') and also the above widget are there
-					t.assertTrue(dijit.byId("sacrificialDlg"), "dialog in dialogContainer still there");
-					t.assertTrue(dijit.byId("destroyTestWidget"), "test widget in dialogContainer still there");
-
-					// when we kill the CP, it should also destroy any widgets created when we set content,
-					// and for backwards-compatibility reasons, any widgets that user stuck in there
-					// manually too
-					dialogCtrPane.destroyRecursive();
-
-					// make sure everything got deleted
-					t.assertFalse(dijit.byId("dialogContainer"));
-					t.assertFalse(dijit.byId("sacrificialDlg"), "dialog in dialogContainer was destroyed");
-					t.assertFalse(dijit.byId("destroyTestWidget"), "test widget in dialogContainer was destroyed");
-					t.assertFalse(dojo.byId("sacrificialDlg"));
-				}
-			}
 			]);
-			doh.run();
 
+			doh.run();
 		});
 	</script>
 
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Dijit layout.ContentPane tests</h1>
 		<p>pre-container paragraph</p>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"box"'>
 			some text (top-level container)
 
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"box"'>
 
 				text in the inner container (1)
 
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box", href:"tab2.html"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"box", href:"tab2.html"'>
 					hi
 				</div>
 
 				text in the inner container (2)
 
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"box"'>
 					inner-inner 2
 				</div>
 
 				text in the inner container (3)
 
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"box"'>
 					inner-inner 3
 				</div>
 
@@ -193,23 +182,23 @@
 
 		<p>mid-container paragraph</p>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"box"'>
 			2nd top-level container
 		</div>
 
 		<p>post-container paragraph</p>
 
-		<div id="test" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box", href:"combotab.html" '>
+		<div id="test" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"box", href:"combotab.html" '>
 			<p style='background-color:yellow;border:1px solid red;text-align:center;'>This text should automatically be replaced by downloaded content from combotab.html</p>
 		</div>
 
 		<hr/>
 		<p>ContentPanes used by the unit tests to verify functionality
-		<div id='parsedPane' data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box" '>
+		<div id='parsedPane' data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"box" '>
 			Some Content Here
 		</div>
-		<div id='dialogContainer' data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box" '>
-			<div id="parserTest" data-dojo-type="dijit.TestWidget" ></div>
+		<div id='dialogContainer' data-dojo-type="dijit/layout/ContentPane" data-dojo-props='"class":"box" '>
+			<div id="parserTest" data-dojo-type="TestWidget" ></div>
 		</div>
 	</body>
 </html>
diff --git a/dijit/tests/layout/test_Gui.html b/dijit/tests/layout/test_Gui.html
index 0014ba4..4dbda5a 100644
--- a/dijit/tests/layout/test_Gui.html
+++ b/dijit/tests/layout/test_Gui.html
@@ -1,14 +1,12 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dijit UI Tester</title>
 
-	<!-- required: a default theme -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
+	<script src="../boilerplate.js"></script>
 
+	<style type="text/css">
 		html, body {
 			height: 100%;
 			width: 100%;
@@ -34,117 +32,110 @@
 		}
 	</style>
 
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: false"></script>
-
-	<!-- do not use: only for debugging / testing themes -->
-	<script type="text/javascript" src="../../tests/_testCommon.js"></script>
-
 	<script type="text/javascript">
-		// dojo.requires()
-		dojo.require("dijit.dijit");
-		dojo.require("dijit.dijit-all");
-
-		// layouts used in page
-		dojo.require("dijit.layout.AccordionContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.TitlePane");
-
+		require([
+			"dojo/parser",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/AccordionContainer",
+			"dijit/layout/TabContainer",
+			"dijit/layout/ContentPane",
+			"dijit/TitlePane",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<!-- "main" BorderContainer just contains page title and another BorderContainer -->
-	<div id="main" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='gutters:true, style:"height:700px;"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", splitter:false'>This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
+	<div id="main" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='gutters:true, style:"height:700px;"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", splitter:false'>This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
 
 		<!-- "mainSplit" BorderContainer has all the real content -->
-		<div id="mainSplit" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='liveSplitters:false, design:"sidebar",
+		<div id="mainSplit" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='liveSplitters:false, design:"sidebar",
 			region:"center" '>
 
-			<div id="leftAccordion" data-dojo-type="dijit.layout.AccordionContainer"
+			<div id="leftAccordion" data-dojo-type="dijit/layout/AccordionContainer"
 				data-dojo-props='minSize:20, style:"width: 300px;", region:"leading", splitter:true'>
 
-				<div id="ac_pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Popups and Alerts"'>
+				<div id="ac_pane1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Popups and Alerts"'>
 				</div>
 
-				<div id="ac_pane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Dojo Tree from Store"'>
+				<div id="ac_pane2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Dojo Tree from Store"'>
 				</div>
 
-				<div id="ac_pane3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Calendar", selected:true'>
+				<div id="ac_pane3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Calendar", selected:true'>
 				</div>
 
-				<div id="ac_pane4" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Color Picker"'>
+				<div id="ac_pane4" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Color Picker"'>
 				</div>
 
 			</div><!-- end AccordionContainer -->
 
-			<div id="centerSplit" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='liveSplitters:false, region:"center"'>
+			<div id="centerSplit" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='liveSplitters:false, region:"center"'>
 				<!-- top tabs (marked as "center" to take up the main part of the BorderContainer) -->
-				<div id="topTabs1" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='region:"top", tabStrip:true, splitter:true, style:"height:200px;"'>
+				<div id="topTabs1" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='region:"top", tabStrip:true, splitter:true, style:"height:200px;"'>
 
-					<div id="basdicFormTab" data-dojo-type="dijit.layout.ContentPane"
+					<div id="basicFormTab" data-dojo-type="dijit/layout/ContentPane"
 						data-dojo-props='title:"Basic Form Widgets",
 						style:"padding:10px;display:none;"'>
 						Hi friends of dijit
 					</div> <!-- end of basic form widgets -->
-					<div id="tabAccordion" data-dojo-type="dijit.layout.AccordionContainer"
+					<div id="tabAccordion" data-dojo-type="dijit/layout/AccordionContainer"
 						data-dojo-props='title:"Accordion in Tab",
 						minSize:20,
 						style:"width: 100%;"'>
 
-						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Popups and Alerts"'>
+						<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Popups and Alerts"'>
 						</div>
 
-						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Dojo Tree from Store"'>
+						<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Dojo Tree from Store"'>
 						</div>
 
-						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Calendar", selected:true'>
+						<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Calendar", selected:true'>
 						</div>
 
-						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Color Picker"'>
+						<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Color Picker"'>
 						</div>
 
 					</div><!-- end AccordionContainer -->
 
-					<div id="textareaTab" data-dojo-type="dijit.layout.ContentPane"
+					<div id="textareaTab" data-dojo-type="dijit/layout/ContentPane"
 						data-dojo-props='
 						title:"Accordion in Content Tab"'>
 
-						<div id="tabAccordionContainer" data-dojo-type="dijit.layout.AccordionContainer"
+						<div id="tabAccordionContainer" data-dojo-type="dijit/layout/AccordionContainer"
 							data-dojo-props='minSize:20, style:"width: 100%;" '>
 
-							<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Popups and Alerts"'>
+							<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Popups and Alerts"'>
 							</div>
 
-							<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tabs in Accordion"'>
+							<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tabs in Accordion"'>
 								<!-- bottom right tabs -->
-								<div id="mainSplit1" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='liveSplitters:false, design:"sidebar",
+								<div id="mainSplit1" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='liveSplitters:false, design:"sidebar",
 									style:"padding: 0px;width: 300px; height: 100px"'>
 
-									<div id="accTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"top", region:"center"'>
+									<div id="accTabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabPosition:"top", region:"center"'>
 
 										<!-- btab 1 -->
-										<div id="bbtab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true, title:"Info", style:" padding:10px;"'>
+										<div id="bbtab1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='selected:true, title:"Info", style:" padding:10px;"'>
 										</div><!-- end:info btab1 -->
 
-										<div id="bbtab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
+										<div id="bbtab2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
 										</div><!-- btab2 -->
 
-										<div id="bbtab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
+										<div id="bbtab3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
 										</div><!-- btab3 -->
 
 									</div><!-- end Bottom TabContainer -->
 								</div>
 							</div>
 
-							<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Calendar", selected:true'>
+							<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Calendar", selected:true'>
 							</div>
 
-							<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Color Picker"'>
+							<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Color Picker"'>
 							</div>
 
 						</div><!-- end AccordionContainer -->
@@ -152,111 +143,111 @@
 					</div><!-- end of Textarea/Editor tab -->
 
 
-					<div id="titlePaneCP" data-dojo-type="dijit.layout.ContentPane"
+					<div id="titlePaneCP" data-dojo-type="dijit/layout/ContentPane"
 						data-dojo-props='title:"Title Pane in Content Pane",
 						doLayout:false,
 						style:"display:none;"'>
 
 						Here's some text, then a TitlePane:
-						<div id="tp" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Color Picker"'>
+						<div id="tp" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Color Picker"'>
 							Hi friends of dijit
 						</div>
 						... and some more text.
 					</div>
 
-					<div id="tabContainerInTabCP" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"TabContainer in Tab", nested:true, closable:true'>
-						<div id="basicFormTab1" data-dojo-type="dijit.layout.ContentPane"
+					<div id="tabContainerInTabCP" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"TabContainer in Tab", nested:true, closable:true'>
+						<div id="basicFormTab1" data-dojo-type="dijit/layout/ContentPane"
 							data-dojo-props='title:"Basic Form Widgets 1",
 							style:"padding:10px; display:none;"'>
 						    Hi friends of dijit
 						</div>
-						<div id="basicFormTab2" data-dojo-type="dijit.layout.ContentPane"
+						<div id="basicFormTab2" data-dojo-type="dijit/layout/ContentPane"
 							data-dojo-props='title:"Basic Form Widgets 2",
 							style:"padding:10px; display:none;"'>
 						    Tab 2 content
 						</div>
 					</div>
 
-					<div id="closableTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Closable ContentPane w/TabContainer",
+					<div id="closableTab" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Closable ContentPane w/TabContainer",
 						style:"display:none; padding:0px;", closable:true'>
 
-						<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Tab in Tab", nested:true'>
+						<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"Tab in Tab", nested:true'>
 
-							<div id="basicFormTab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Basic Form Widgets 3", style:"padding:10px;display:none;"'>
+							<div id="basicFormTab3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Basic Form Widgets 3", style:"padding:10px;display:none;"'>
 							    Hi friends of dijit
 							</div>
-							<div id="basicFormTab4" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Basic Form Widgets 4", style:"padding:10px;display:none;"'>
+							<div id="basicFormTab4" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Basic Form Widgets 4", style:"padding:10px;display:none;"'>
 							    Hi friends of dijit
 							</div>
 						</div>
 					</div>
 				</div><!-- end of region="center" TabContainer -->
-				<div id="embeddedBC" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='liveSplitters:false, region:"center"'>
-					<div id="bottomTabs1" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:true,
+				<div id="embeddedBC" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='liveSplitters:false, region:"center"'>
+					<div id="bottomTabs1" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabStrip:true,
 						tabPosition:"left-h", region:"top", style:"height: 50%;", splitter:true'>
 
 						<!-- btab 1 -->
-						<div id="btabA" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true, title:"Info", style:"padding:10px;"'>
+						<div id="btabA" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='selected:true, title:"Info", style:"padding:10px;"'>
 
 						</div><!-- end:info btabA -->
 
-						<div id="btabB" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
+						<div id="btabB" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
 
 						</div><!-- btabB -->
 
-						<div id="btabC" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
+						<div id="btabC" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
 
 						</div><!-- btabC -->
 
 					</div><!-- end Bottom TabContainer -->
-					<div id="bottomTabs2" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:true,
+					<div id="bottomTabs2" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabStrip:true,
 						tabPosition:"right-h", region:"center"'>
 
 						<!-- btab 1 -->
-						<div id="btabD" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true, title:"Info", style:"padding:10px;"'>
+						<div id="btabD" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='selected:true, title:"Info", style:"padding:10px;"'>
 
 						</div><!-- end:info btabD -->
 
-						<div id="btabE" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
+						<div id="btabE" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
 
 						</div><!-- btabE -->
 
-						<div id="btabF" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
+						<div id="btabF" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
 
 						</div><!-- btabF -->
 
 					</div><!-- end Bottom TabContainer -->
 				</div>
 				<!-- bottom right tabs -->
-				<div id="bottomTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:true,
+				<div id="bottomTabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabStrip:true,
 					tabPosition:"bottom", region:"bottom", splitter:true'>
 
 					<!-- btab 1 -->
-					<div id="bottomSplit" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='selected:true, liveSplitters:false, design:"sidebar",
+					<div id="bottomSplit" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='selected:true, liveSplitters:false, design:"sidebar",
 						region:"center", title:"BorderContainer in Tabs", style:"padding: 5px; width: 100%"'>
-						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", splitter:true'>This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
-						<div id="bottomTabs22" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"top", region:"center", splitter:true'>
+						<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"top", splitter:true'>This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
+						<div id="bottomTabs22" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabPosition:"top", region:"center", splitter:true'>
 
 							<!-- btab 1 -->
-							<div id="btabAA" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true, title:"Info", style:"padding:10px;"'>Hi</div>
+							<div id="btabAA" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='selected:true, title:"Info", style:"padding:10px;"'>Hi</div>
 						</div>
 
-						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", splitter:true'>This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
+						<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"bottom", splitter:true'>This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
 
 					</div>
 
-					<div id="btab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
+					<div id="btab2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
 
 					</div><!-- btab2 -->
 
-					<div id="btab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
+					<div id="btab3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
 
 					</div><!-- btab3 -->
 
 				</div><!-- end Bottom TabContainer -->
 			</div>
 		</div> <!-- end of "mainSplit" BorderContainer -->
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"trailing", splitter:true, style:"width: 10%;"'>Hi </div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"trailing", splitter:true, style:"width: 10%;"'>Hi </div>
 
 	</div><!-- end of "main" BorderContainer -->
 
diff --git a/dijit/tests/layout/test_SplitContainer.html b/dijit/tests/layout/test_SplitContainer.html
index 5ac84a3..c6c9d1f 100644
--- a/dijit/tests/layout/test_SplitContainer.html
+++ b/dijit/tests/layout/test_SplitContainer.html
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="en">
 <head>
 	<title>SplitContainer Widget Demo</title>
 
@@ -62,19 +62,28 @@
 		};
 		dojo.ready(programaticExample);
 
+		// for testing SplitContainer.addChild()
+		ctr = 1;
+		function addChild(parentId, position){
+			dijit.byId(parentId).addChild(new dijit.layout.ContentPane({
+				id: "ContentPane" + ctr,
+				innerHTML: "added child #" + ctr++
+			}), position);
+		}
 	</script>
 </head>
-<body>
+<body role="main">
 	<h1 class="testTitle">Dijit Split Container Test - DEPRECATED!</h1>
 	<p><strong>dijit.layout.SplitContainer is deprecated use
 	BorderContainer with splitter instead -- will be removed in version: 2</strong></p>
 	<p>HTML before</p>
 
 	<div dojoType="dijit.layout.SplitContainer"
+		id="split1"
 		orientation="vertical"
 		sizerWidth="7"
 		activeSizing="false"
-		style="border: 1px solid #bfbfbf; float: left; margin-right: 30px;  width: 400px; height: 300px;"
+		style="border: 1px solid #bfbfbf; width: 400px; height: 300px;"
 	>
 		<div dojoType="dijit.layout.ContentPane" sizeMin="10" sizeShare="50">
 			this box has three split panes
@@ -87,6 +96,11 @@
 			without active resizing
 		</div>
 	</div>
+	<button onclick="addChild('split1');">add child at end</button>
+	<button onclick="addChild('split1', 'first');">add child at beginning</button>
+	<button onclick="addChild('split1', 3);">addChild(child, 3)</button>
+	<button onclick="addChild('split1', dijit.byId('split1').getChildren().length-1);">addChild(child, getChildren().length-1)</button>
+	<br><br>
 
 	<div dojoType="dijit.layout.SplitContainer"
 		orientation="horizontal"
@@ -111,10 +125,10 @@ the following splitter contains two iframes, see whether the resizer works ok in
 	style="border: 2px solid black; float: left; width: 100%; height: 300px;"
 >
 	<div dojoType="dijit.layout.ContentPane" sizeMin="20" sizeShare="20">
-		<iframe style="width: 100%; height: 100%"></iframe>
+		<iframe style="width: 100%; height: 100%" title="iframe"></iframe>
 	</div>
 	<div dojoType="dijit.layout.ContentPane" sizeMin="50" sizeShare="50">
-		<iframe style="width: 100%; height: 100%"></iframe>
+		<iframe style="width: 100%; height: 100%" title="iframe2"></iframe>
 	</div>
 </div>
 
diff --git a/dijit/tests/layout/test_TabContainer.html b/dijit/tests/layout/test_TabContainer.html
index e6c771e..f1a1f61 100644
--- a/dijit/tests/layout/test_TabContainer.html
+++ b/dijit/tests/layout/test_TabContainer.html
@@ -1,71 +1,55 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>TabContainer Demo</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-
-		body {
-			font-family : sans-serif;
-			margin:20px;
-		}
-
-		/* add padding to each contentpane inside the tab container, and scrollbar if necessary */
-		.dojoTabPane {
-			padding : 10px 10px 10px 10px;
-			overflow: auto;
-		}
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
-
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.SplitContainer");
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.Tooltip");
-		dojo.require("dijit.layout.LinkPane");
-		dojo.require("dijit.form.Button");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
 		function testClose(pane,tab){
 		  return confirm("Please confirm that you want tab "+tab.title+" closed");
 		}
 
-		startTime = new Date();
-		dojo.ready(function(){
-			var elapsed = new Date().getTime() - startTime;
-			var p = document.createElement("p");
-			p.appendChild(document.createTextNode("Widgets loaded in " + elapsed + "ms"));
-			document.body.appendChild(p);
-		});
-
-		var progTabCounter = 1;
-		function makeTab(){
-			var tc = dijit.byId("mainTabContainer");
-			var cp = new dijit.layout.ContentPane({
-				title: 'Programmatically created tab ' + (progTabCounter++) ,
-				closable: true
+		require([
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/layout/ContentPane",
+
+			// widgets used by the parser, preloading so not included in the elapsed time measurement
+			"dijit/layout/BorderContainer",
+			"dijit/layout/TabContainer",
+			"dijit/Tooltip",
+			"dijit/form/Button",
+			"dojo/domReady!"
+		], function(parser, registry, ContentPane){
+			startTime = new Date();
+			parser.parse().then(function(){
+				var elapsed = new Date().getTime() - startTime;
+				var p = document.createElement("p");
+				p.appendChild(document.createTextNode("Widgets loaded in " + elapsed + "ms"));
+				document.body.appendChild(p);
 			});
-			cp.domNode.innerHTML = "I was created programmatically!";
-			tc.addChild(cp, 0);
-		}
+
+			var progTabCounter = 1;
+			makeTab = function(){
+				var tc = registry.byId("mainTabContainer");
+				var cp = new ContentPane({
+					title: 'Programmatically created tab ' + (progTabCounter++) ,
+					closable: true
+				});
+				cp.domNode.innerHTML = "I was created programmatically!";
+				tc.addChild(cp, 0);
+			};
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
+
+	<script type="dojo/require">
+		registry: "dijit/registry"
+	</script>
 
 	<h1 class="testTitle">Dijit layout.TabContainer tests</h1>
 
@@ -85,23 +69,23 @@
 
 	<br><br>
 
-	<div id="mainTabContainer" data-dojo-type="dijit.layout.TabContainer"
-				data-dojo-props='persist:false, tabStrip:true, style:"width: 400px;height: 20em;"'>
+	<div id="mainTabContainer" data-dojo-type="dijit/layout/TabContainer"
+				data-dojo-props='persist:false, tabStrip:true' style="width: 400px;height: 20em;">
 
-		<div id="tab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1", iconClass:"plusIcon",
+		<div id="tab1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1", iconClass:"plusIcon",
 			tooltip:"Tooltip for tab #1"'></div>
 
-		<div id="tab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", iconClass:"noteIcon", selected:true'></div>
+		<div id="tab2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", iconClass:"noteIcon", selected:true'></div>
 
-		<div id="tab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 3",
+		<div id="tab3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 3",
 				iconClass:"dijitEditorIcon dijitEditorIconSave", closable:true'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
 			<p id="foo">tooltip on this paragraph</p>
-			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo"]'>I'm a tooltip!</div>
-			<button data-dojo-type="dijit.form.Button">I'm a button </button>
+			<div data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["foo"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit/form/Button">I'm a button </button>
 			<br>
-			<button data-dojo-type="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit/form/Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -125,22 +109,22 @@
 			</p>
 		</div>
 
-		<div id="inlined" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Inlined Sub TabContainer", iconClass:"plusIcon", nested:true'>
-			<a id="tab1href" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }, iconClass:"plusIcon" '>SubTab 1</a>
-			<a id="tab2href" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true,  iconClass:"dijitEditorIcon dijitEditorIconSave"'>SubTab 2</a>
-			<div id="subtab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"SubTab 3",  iconClass:"dijitEditorIcon dijitEditorIconCut"'>
+		<div id="inlined" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"Inlined Sub TabContainer", iconClass:"plusIcon", nested:true'>
+			<div id="tab1href" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }, iconClass:"plusIcon" ' title="SubTab 1"></div>
+			<div id="tab2href" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", onLoad:function(){ console.log("load of SubTab 2"); }, selected:true,  iconClass:"dijitEditorIcon dijitEditorIconSave"' title="SubTab 2"></div>
+			<div id="subtab3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"SubTab 3",  iconClass:"dijitEditorIcon dijitEditorIconCut"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div id="subtab4" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"SubTab 4", iconClass:"dijitEditorIcon dijitEditorIconCopy"'>
+			<div id="subtab4" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"SubTab 4", iconClass:"dijitEditorIcon dijitEditorIconCopy"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a id="tab3href" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab3.html", refreshOnShow:true, closable:true,
-				style:"padding: 0", iconClass:"dijitEditorIcon dijitEditorIconSave"'>Sub TabContainer from href</a>
-		<a id="tab4href" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab4.html",
-				closable:true, iconClass:"dijitEditorIcon dijitEditorIconCut"'>SplitContainer from href</a>
-		<div id="embedded" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Embedded layout widgets",
+		<div id="tab3href" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab3.html", refreshOnShow:true, closable:true,
+				iconClass:"dijitEditorIcon dijitEditorIconSave"' title="Sub TabContainer from href" style="padding: 0"></div>
+		<div id="tab4href" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab4.html",
+				closable:true, iconClass:"dijitEditorIcon dijitEditorIconCut"' title="SplitContainer from href"></div>
+		<div id="embedded" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Embedded layout widgets",
 				closable:true, iconClass:"dijitEditorIcon dijitEditorIconCopy"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
@@ -149,8 +133,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div id="bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
+			<div id="bc" data-dojo-type="dijit/layout/BorderContainer" style="height:200px; width:300px">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", splitter:true' style="width: 100px">
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -165,7 +149,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -184,8 +168,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div id="embeddedTC" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div id="embeddedTab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
+			<div id="embeddedTC" data-dojo-type="dijit/layout/TabContainer" style="height:200px; width:300px">
+				<div id="embeddedTab1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -200,7 +184,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div id="embeddedTab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+				<div id="embeddedTab2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -222,29 +206,30 @@
 		</div>
 	</div>
 
-	<button onclick="dijit.byId('tab1').set('title', 'Tab 1 Renamed');">Rename Tab #1</button>
-	<button onclick="dijit.byId('tab2').set('title', 'Tab 2 Renamed To Something Very Long');">Rename Tab #2</button>
-	<button onclick="dijit.byId('tab1').set('closable', !dijit.byId('tab1').get('closable'));">Toggle Tab #1 closable</button>
+	<button onclick="registry.byId('tab1').set('title', 'Tab 1 Renamed');">Rename Tab #1</button>
+	<button onclick="registry.byId('tab2').set('title', 'Tab 2 Renamed To Something Very Long');">Rename Tab #2</button>
+	<button onclick="registry.byId('tab1').set('closable', !registry.byId('tab1').get('closable'));">Toggle Tab #1 closable</button>
+	<button onclick="registry.byId('tab3').set('disabled', !registry.byId('tab3').get('disabled'));">Toggle Tab #3 disabled</button>
+
 	<br/>
 	<p>
-		This tab container has the Menu function for selecting tabs disabled, using <b>useMenu="false"</b>
+		This tab container has the Menu function for selecting tabs disabled, using useMenu: false</b>.
+		Also, "Tab 3" is initially disabled.
 	</p>
+	<div data-dojo-type="dijit/layout/TabContainer" id="nomenu" data-dojo-props='useMenu:false,
+				persist:false, tabStrip:true' style="width: 400px;height: 20em;">
+		<div data-dojo-type="dijit/layout/ContentPane" id="nomenu_tab1" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
-	<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='useMenu:false,
-				persist:false, tabStrip:true, style:"width: 400px;height: 20em;"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
-
+		<div data-dojo-type="dijit/layout/ContentPane" id="nomenu_tab2" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
-
-		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"Tab 3", closable:true'>
+		<div data-dojo-type="dijit/layout/ContentPane"  id="nomenu_tab3" data-dojo-props='title:"Tab 3", closable:true, disabled: true'>
 			<h1>I am tab 3</h1>
-			<p>And I was already part of the page! That's cool, no?</p>
+			<p>I was initially a disabled tab (button below TabContainer can enable/disable me).</p>
 			<p id="foo2">tooltip on this paragraph</p>
-			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo2"]'>I'm a tooltip!</div>
-			<button data-dojo-type="dijit.form.Button">I'm a button </button>
+			<div data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["foo2"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit/form/Button">I'm a button </button>
 			<br>
-			<button data-dojo-type="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit/form/Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -268,22 +253,22 @@
 			</p>
 		</div>
 
-		<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
-			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
-			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
-			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 3"'>
+		<div data-dojo-type="dijit/layout/TabContainer"  data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }' title="SubTab 1"></div>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", onLoad:function(){ console.log("load of SubTab 2"); }, selected:true' title="SubTab 2"></div>
+			<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"SubTab 3"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 4"'>
+			<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"SubTab 4"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab3.html", closable:true, refreshOnShow:true, style:"padding: 0"'>Sub TabContainer from href</a>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab3.html", closable:true, refreshOnShow:true' style="padding: 0" title="Sub TabContainer from href"></div>
 
-		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='closable:true, href:"tab4.html"'>SplitContainer from href</a>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab4.html", closable:true' title="SplitContainer from href"></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='closable:true, title:"Embedded layout widgets"'>
+		<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='closable:true, title:"Embedded layout widgets"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
 				appear correctly even though the tab is initially hidden.
@@ -291,8 +276,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
+			<div data-dojo-type="dijit/layout/BorderContainer" style="height:200px; width:300px">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", splitter:true' style="width:100px">
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -307,7 +292,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -326,8 +311,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
+			<div data-dojo-type="dijit/layout/TabContainer" style="height:200px; width:300px">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -342,7 +327,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -363,36 +348,37 @@
 			</p>
 		</div>
 	</div>
+	<button onclick="registry.byId('nomenu_tab3').set('disabled', !registry.byId('nomenu_tab3').get('disabled'));">Toggle Tab #3 disabled</button>
 
 
 	<br/>
 
 	<p>Tabs w/only icons (except in high-contrast mode where labels display):</p>
-	<div id="iconTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"top", style:"width: 100%; height: 10em;"'>
-		<div id="iconTab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Cut", tooltip:"tooltip for cut button", showTitle:false, iconClass:"dijitEditorIcon dijitEditorIconCut"'>Cut icon tab</div>
-		<div id="iconTab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Copy", showTitle:false, iconClass:"dijitEditorIcon dijitEditorIconCopy"'>Copy icon tab</div>
-		<div id="iconTab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Paste", showTitle:false, iconClass:"dijitEditorIcon dijitEditorIconPaste"'>Paste icon tab</div>
+	<div id="iconTabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabPosition:"top"' style="width: 100%; height: 10em;">
+		<div id="iconTab1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Cut", tooltip:"tooltip for cut button", showTitle:false, iconClass:"dijitEditorIcon dijitEditorIconCut"'>Cut icon tab</div>
+		<div id="iconTab2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Copy", showTitle:false, iconClass:"dijitEditorIcon dijitEditorIconCopy"'>Copy icon tab</div>
+		<div id="iconTab3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Paste", showTitle:false, iconClass:"dijitEditorIcon dijitEditorIconPaste"'>Paste icon tab</div>
 	</div>
 
 
 	<p>
 		This tab container has the Slider function for selecting tabs disabled, using <b>useSlider="false"</b>
 	</p>
-	<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='useSlider:false,
-				persist:false, tabStrip:true, style:"width: 400px;height: 20em;"'>
+	<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='useSlider:false,
+				persist:false, tabStrip:true' style="width: 400px;height: 20em;">
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"Tab 3", closable:true'>
+		<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"Tab 3", closable:true'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
 			<p id="foo3">tooltip on this paragraph</p>
-			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo3"]'>I'm a tooltip!</div>
-			<button data-dojo-type="dijit.form.Button">I'm a button </button>
+			<div data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["foo3"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit/form/Button">I'm a button </button>
 			<br>
-			<button data-dojo-type="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit/form/Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -416,22 +402,23 @@
 			</p>
 		</div>
 
-		<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
-			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
-			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
-			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 3"'>
+		<div data-dojo-type="dijit/layout/TabContainer"  data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }' title="SubTab 1"></div>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", onLoad:function(){ console.log("load of SubTab 2"); }, selected:true' title="SubTab 2"></div>
+			<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"SubTab 3"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 4"'>
+			<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"SubTab 4"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab3.html", closable:true, refreshOnShow:true, style:"padding: 0"'>Sub TabContainer from href</a>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab3.html", closable:true, refreshOnShow:true'
+		   title="Sub TabContainer from href" style="padding: 0" ></div>
 
-		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='closable:true, href:"tab4.html"'>SplitContainer from href</a>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab4.html", closable:true' title="SplitContainer from href"></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='closable:true, title:"Embedded layout widgets"'>
+		<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='closable:true, title:"Embedded layout widgets"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
 				appear correctly even though the tab is initially hidden.
@@ -439,8 +426,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
+			<div data-dojo-type="dijit/layout/BorderContainer" style="height:200px; width:300px">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", splitter:true' style="width:100px" >
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -455,7 +442,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -474,8 +461,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
+			<div data-dojo-type="dijit/layout/TabContainer"  style="height:200px; width:300px">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -490,7 +477,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -513,23 +500,23 @@
 	</div>
 	<br/>
 	<p>
-		This tab container has the tab strip disabled, using <b>tabStrip="false"</b>
+		This tab container has the tab strip disabled, using <b>tabStrip:false</b>
 	</p>
-	<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:false,
-				persist:false, tabStrip:true, style:"width: 400px;height: 20em;"'>
+	<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabStrip:false,
+				persist:false' style="width: 400px;height: 20em;">
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"Tab 3", closable:true'>
+		<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"Tab 3", closable:true'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
 			<p id="foo4">tooltip on this paragraph</p>
-			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo4"]'>I'm a tooltip!</div>
-			<button data-dojo-type="dijit.form.Button">I'm a button </button>
+			<div data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["foo4"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit/form/Button">I'm a button </button>
 			<br>
-			<button data-dojo-type="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit/form/Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -553,22 +540,22 @@
 			</p>
 		</div>
 
-		<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
-			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
-			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
-			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 3"'>
+		<div data-dojo-type="dijit/layout/TabContainer"  data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }' title="SubTab 1"></div>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", onLoad:function(){ console.log("load of SubTab 2"); }, selected:true' title="SubTab 2"></div>
+			<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"SubTab 3"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 4"'>
+			<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"SubTab 4"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab3.html", closable:true, refreshOnShow:true, style:"padding: 0"'>Sub TabContainer from href</a>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab3.html", closable:true, refreshOnShow:true' style="padding: 0" title="Sub TabContainer from href"></div>
 
-		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='closable:true, href:"tab4.html"'>SplitContainer from href</a>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab4.html", closable:true' title="SplitContainer from href"></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='closable:true, title:"Embedded layout widgets"'>
+		<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='closable:true, title:"Embedded layout widgets"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
 				appear correctly even though the tab is initially hidden.
@@ -576,8 +563,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
+			<div data-dojo-type="dijit/layout/BorderContainer" style="height:200px; width:300px">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", splitter:true' style="width:100px">
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -592,7 +579,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -611,8 +598,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
+			<div data-dojo-type="dijit/layout/TabContainer" style="height:200px; width:300px">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -627,7 +614,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -655,21 +642,21 @@
 	and the tabPosition is "bottom"
 	</p>
 
-	<div id="mainTabContainerBottom" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"bottom",
-				persist:true, tabStrip:true, style:"width: 400px; height: 20em;"'>
+	<div id="mainTabContainerBottom" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabPosition:"bottom",
+				persist:true, tabStrip:true' style="width: 400px; height: 20em;">
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='closable:true, title:"Tab 3"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='closable:true, title:"Tab 3"'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
 			<p id="foo5">tooltip on this paragraph</p>
-			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo5"]'>I'm a tooltip!</div>
-			<button data-dojo-type="dijit.form.Button">I'm a button </button>
+			<div data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["foo5"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit/form/Button">I'm a button </button>
 			<br>
-			<button data-dojo-type="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit/form/Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -693,22 +680,22 @@
 			</p>
 		</div>
 
-		<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
-			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
-			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
-			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 3"'>
+		<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }' title="SubTab 1"></div>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true' title="SubTab 2"></div>
+			<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"SubTab 3"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 4"'>
+			<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"SubTab 4"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='closable:true, href:"tab3.html", refreshOnShow:true, style:"padding: 0"'>Sub TabContainer from href</a>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab3.html", closable:true, refreshOnShow:true' title="Sub TabContainer from href" style="padding:0"></div>
 
-		<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='closable:true, href:"tab4.html"'>SplitContainer from href</a>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab4.html", closable:true' title="SplitContainer from href"></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='closable:true, title:"Embedded layout widgets"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='closable:true, title:"Embedded layout widgets"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
 				appear correctly even though the tab is initially hidden.
@@ -716,8 +703,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
+			<div data-dojo-type="dijit/layout/BorderContainer" style="height:200px; width:300px">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", splitter:true' style="width:100px">
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -732,7 +719,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -751,8 +738,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
+			<div data-dojo-type="dijit/layout/TabContainer" style="height:200px; width:300px">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -767,7 +754,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -793,21 +780,21 @@
 		This tab container has its tabs at the bottom, and the tab strip disabled
 	</p>
 
-	<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"bottom",
-				persist:true, tabStrip:false, style:"width: 400px; height: 20em;"'>
+	<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabPosition:"bottom",
+				persist:true, tabStrip:false' style="width: 400px; height: 20em;">
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='closable:true, title:"Tab 3"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='closable:true, title:"Tab 3"'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
 			<p id="foo6">tooltip on this paragraph</p>
-			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo6"]'>I'm a tooltip!</div>
-			<button data-dojo-type="dijit.form.Button">I'm a button </button>
+			<div data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["foo6"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit/form/Button">I'm a button </button>
 			<br>
-			<button data-dojo-type="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit/form/Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -831,22 +818,22 @@
 			</p>
 		</div>
 
-		<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
-			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
-			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
-			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 3"'>
+		<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }' title="SubTab 1"></div>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true' title="SubTab 2"></div>
+			<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"SubTab 3"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 4"'>
+			<div data-dojo-type="dijit/layout/ContentPane"  data-dojo-props='title:"SubTab 4"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='closable:true, href:"tab3.html", refreshOnShow:true, style:"padding: 0"'>Sub TabContainer from href</a>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab3.html", closable:true, refreshOnShow:true' title="Sub TabContainer from href" style="padding: 0" ></div>
 
-		<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='closable:true, href:"tab4.html"'>SplitContainer from href</a>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab4.html", closable:true' title="SplitContainer from href"></div>
 
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='closable:true, title:"Embedded layout widgets"'>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='closable:true, title:"Embedded layout widgets"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
 				appear correctly even though the tab is initially hidden.
@@ -854,8 +841,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
+			<div data-dojo-type="dijit/layout/BorderContainer" style="height:200px; width:300px">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", splitter:true' style="width:100px" >
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -870,7 +857,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -889,8 +876,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
+			<div data-dojo-type="dijit/layout/TabContainer" style="height:200px; width:300px">
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -905,7 +892,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -932,13 +919,13 @@
 		Tab 1 and Tab 3 can be closed; Tab 3 has a confirm box.
 	</p>
 
-	<div id="ttabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"top", style:"width: 100%; height: 10em;",
+	<div id="ttabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabPosition:"top",
 		onFocus:function(){ console.log("user focus handler") },
 		onBlur:function(){ console.log("user blur handler") }
-	'>
-		<div id="ttab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"First", closable:true'></div>
-		<div id="ttab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Second"'></div>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Third", onClose:testClose, closable:true'>
+	' style="width: 100%; height: 10em;">
+		<div id="ttab1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"First", closable:true'></div>
+		<div id="ttab2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Second"'></div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Third", onClose:testClose, closable:true'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
 			<p>If you try to close me there should be a confirm dialog.</p>
@@ -947,27 +934,27 @@
 
 	<p>Tabs with titles on the bottom:</p>
 
-	<div id="btabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"bottom", style:"width: 100%; height: 10em;"'>
-		<div id="btab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1", closable:true'></div>
-		<div id="btab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, onLoad:function(){ console.debug("Tab2 onLoad"); }, title:"Tab 2"'></div>
+	<div id="btabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabPosition:"bottom"' style="width: 100%; height: 10em;">
+		<div id="btab1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1", closable:true'></div>
+		<div id="btab2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, onLoad:function(){ console.debug("Tab2 onLoad"); }, title:"Tab 2"'></div>
 	</div>
 
 	<p>Tabs with titles on the left and tabStrip="false":</p>
 
-	<div id="ltabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width:500px;height:100px", tabStrip:false, tabPosition:"left-h"'>
-		<div id="LittleRed1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Little Red Cap"'>
+	<div id="ltabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabStrip:false, tabPosition:"left-h"' style="width:500px;height:100px">
+		<div id="LittleRed1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Little Red Cap"'>
 			Once upon a time there was a dear little girl who was loved by
 			every one who looked at her, but most of all by her grandmother,
 			and there was nothing that she would not have given to the child.
 		</div>
-		<div id="HanselGretel1" data-dojo-type="dijit.layout.ContentPane"
+		<div id="HanselGretel1" data-dojo-type="dijit/layout/ContentPane"
 		     data-dojo-props='title:"Hansel and Gretel", closable:true, selected:true'>
 			Hard by a great forest dwelt a poor wood-cutter with his wife
 			and his two children. The boy was called Hansel and the girl Gretel.
 			He had little to bite and to break, and once when great dearth fell
 			on the land, he could no longer procure even daily bread.
 		</div>
-		<div id="GreenTwigs1" data-dojo-type="dijit.layout.ContentPane"
+		<div id="GreenTwigs1" data-dojo-type="dijit/layout/ContentPane"
 		 data-dojo-props='title:"The Three Green Twigs"'>
 			There was once upon a time a hermit who lived in a forest at the foot
 			of a mountain, and passed his time in prayer and good works,
@@ -978,20 +965,20 @@
 
 	<p>Tabs with titles on the left and tabStrip=true:</p>
 
-	<div id="ltabsStrip" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width:500px;height:100px", tabStrip:true, tabPosition:"left-h"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Little Red Cap"'>
+	<div id="ltabsStrip" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabStrip:true, tabPosition:"left-h"' style="width:500px;height:100px">
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Little Red Cap"'>
 			Once upon a time there was a dear little girl who was loved by
 			every one who looked at her, but most of all by her grandmother,
 			and there was nothing that she would not have given to the child.
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane"
+		<div data-dojo-type="dijit/layout/ContentPane"
 		     data-dojo-props='title:"Hansel and Gretel", closable:true, selected:true'>
 			Hard by a great forest dwelt a poor wood-cutter with his wife
 			and his two children. The boy was called Hansel and the girl Gretel.
 			He had little to bite and to break, and once when great dearth fell
 			on the land, he could no longer procure even daily bread.
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane"
+		<div data-dojo-type="dijit/layout/ContentPane"
 		 data-dojo-props='title:"The Three Green Twigs"'>
 			There was once upon a time a hermit who lived in a forest at the foot
 			of a mountain, and passed his time in prayer and good works,
@@ -1002,20 +989,20 @@
 
 	<p>Tabs with titles on the right and tabStrip=true:</p>
 
-	<div id="rtabsStrip" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:true, style:"width:500px;height:100px", tabPosition:"right-h"'>
-		<div id="LittleRed2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Little Red Cap"'>
+	<div id="rtabsStrip" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabStrip:true, tabPosition:"right-h"' style="width:500px;height:100px">
+		<div id="LittleRed2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Little Red Cap"'>
 			Once upon a time there was a dear little girl who was loved by
 			every one who looked at her, but most of all by her grandmother,
 			and there was nothing that she would not have given to the child.
 		</div>
-		<div id="HanselGretel2" data-dojo-type="dijit.layout.ContentPane"
+		<div id="HanselGretel2" data-dojo-type="dijit/layout/ContentPane"
 		     data-dojo-props='title:"Hansel and Gretel", closable:true, selected:true'>
 			Hard by a great forest dwelt a poor wood-cutter with his wife
 			and his two children. The boy was called Hansel and the girl Gretel.
 			He had little to bite and to break, and once when great dearth fell
 			on the land, he could no longer procure even daily bread.
 		</div>
-		<div id="GreenTwigs2" data-dojo-type="dijit.layout.ContentPane"
+		<div id="GreenTwigs2" data-dojo-type="dijit/layout/ContentPane"
 		 data-dojo-props='title:"The Three Green Twigs"'>
 			There was once upon a time a hermit who lived in a forest at the foot
 			of a mountain, and passed his time in prayer and good works,
@@ -1026,20 +1013,20 @@
 
 	<p>Tabs with titles on the right and tabStrip=false:</p>
 
-	<div id="rtabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:false, style:"width:500px;height:100px", tabPosition:"right-h"'>
-		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Little Red Cap"'>
+	<div id="rtabs" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='tabStrip:false, tabPosition:"right-h"' style="width:500px;height:100px">
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Little Red Cap"'>
 			Once upon a time there was a dear little girl who was loved by
 			every one who looked at her, but most of all by her grandmother,
 			and there was nothing that she would not have given to the child.
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane"
+		<div data-dojo-type="dijit/layout/ContentPane"
 		     data-dojo-props='title:"Hansel and Gretel", closable:true, selected:true'>
 			Hard by a great forest dwelt a poor wood-cutter with his wife
 			and his two children. The boy was called Hansel and the girl Gretel.
 			He had little to bite and to break, and once when great dearth fell
 			on the land, he could no longer procure even daily bread.
 		</div>
-		<div data-dojo-type="dijit.layout.ContentPane"
+		<div data-dojo-type="dijit/layout/ContentPane"
 		 data-dojo-props='title:"The Three Green Twigs"'>
 			There was once upon a time a hermit who lived in a forest at the foot
 			of a mountain, and passed his time in prayer and good works,
diff --git a/dijit/tests/layout/test_TabContainer_CSS.html b/dijit/tests/layout/test_TabContainer_CSS.html
new file mode 100644
index 0000000..b240e07
--- /dev/null
+++ b/dijit/tests/layout/test_TabContainer_CSS.html
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html dir="ltr" lang="en">
+    <head>
+		<title>TabContainer CSS Glitch Tests</title>
+
+		<script src="../boilerplate.js"></script>
+
+		<style>
+			#tabContainer1 {
+				height: 200px;
+				margin-bottom: 50px;
+			}
+		</style>
+
+		<script>
+			require([
+				"dojo/parser",
+				"dijit/registry",
+				"dijit/layout/TabContainer", "dijit/layout/ContentPane",
+				"dijit/form/DropDownButton", "dijit/TooltipDialog",
+				"dojo/domReady!"
+			], function(parser, registry, TabContainer, ContentPane){
+
+				parser.parse().then(function(){
+					var tabsPane1 = registry.byId('tabContainer1');
+					var tab1 = new ContentPane({title: "My tab 1", content: "border line to right of tab does not show  (now resize your browser and the border line will appear)"});
+					tabsPane1.addChild(tab1);
+				});
+			});
+		</script>
+    </head>
+
+    <body class="claro" role="main">
+		<h1>TabContainer CSS Glitch Tests</h1>
+		<p>
+			Collected tests for problems with missing borders for TabContainer,
+			in particular problems with the border between the tab buttons and the tab content.
+		</p>
+
+		<h2>Borders in TooltipDialog</h2>
+		<p>
+			Open TooltipDialog and make sure the horizontal border between tab buttons and content
+			don't extend past the edge of the TabContainer.   Also check that button for second tab
+			(unselected tab) is visible on IE6.
+		</p>
+		<div data-dojo-type="dijit/form/DropDownButton">
+			<span>Show Tooltip Dialog with TabContainer</span>
+			<div id="tabTooltip" data-dojo-type="dijit/TooltipDialog" data-dojo-props='title:"Tab Container Tooltip"'>
+				<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 400px; height: 300px;"'>
+					<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"First tab"'>
+						<p>
+							This is the first tab.
+						</p>
+						<p>
+						Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+						semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+						porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+						Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+						Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+						risus.
+						</p>
+					</div>
+					<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Second tab"'>
+						<p>
+							This is the second tab.
+						</p>
+						<p>
+						<a href="http://www.lipsum.com/">ipsum dolor sit amet</a>, consectetuer adipiscing elit. Aenean
+						semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+						porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+						Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+						Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+						risus.
+						</p>
+					</div>
+				</div>
+			</div>
+		</div>
+
+		<h2>Initial missing border</h2>
+		<p>
+			Make sure the TabContainers below show the border between tab buttons and tab content.
+			Previously it didn't show on initial page load, but showed after resize.
+		</p>
+        <div id='tabContainer1' data-dojo-type='dijit/layout/TabContainer' data-dojo-props="tabPosition: 'top'"></div>
+
+		<h2>Missing border on zoom</h2>
+		<p>
+			Make sure separating border doesn't disappear on zoom
+			(<i>not</i> text-size increase/decrease but zoom).
+			Problem used to occur on FF/windows and IE8.
+		</p>
+		<div id="myTC" data-dojo-type="dijit/layout/TabContainer" style="width: 400px; height: 200px;" tabPosition="left-h" tabStrip="false">
+			<div id="LittleRed1" data-dojo-type="dijit/layout/ContentPane" title="One" >
+				Once upon a time there was a dear little girl who was loved by
+				every one who looked at her, but most of all by her grandmother,
+				and there was nothing that she would not have given to the child.
+			</div>
+			<div id="HanselGretel1" data-dojo-type="dijit/layout/ContentPane" title="Two" selected="true" >
+				Some content here.
+			</div>
+			<div id="GreenTwigs1" data-dojo-type="dijit/layout/ContentPane" title="The Three Green Twigs" >
+				Yet more content.
+			</div>
+		</div>
+    </body>
+</html>
diff --git a/dijit/tests/layout/test_TabContainer_noLayout.html b/dijit/tests/layout/test_TabContainer_noLayout.html
index 51635c8..52c52fa 100644
--- a/dijit/tests/layout/test_TabContainer_noLayout.html
+++ b/dijit/tests/layout/test_TabContainer_noLayout.html
@@ -1,58 +1,42 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>TabContainer doLayout=false Demo</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-
-		body {
-			font-family : sans-serif;
-			margin:20px;
-		}
-
-		/* add padding to each contentpane inside the tab container, and scrollbar if necessary */
-		.dojoTabPane {
-			padding : 10px 10px 10px 10px;
-			overflow: auto;
-		}
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
-
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.Tooltip");
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.layout.LinkPane");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
 		function testClose(pane,tab){
-		  return confirm("Please confirm that you want tab "+tab.title+" closed");
+			return confirm("Please confirm that you want tab "+tab.title+" closed");
 		}
 
-		var tab = 6;
-
-        function addTab(){
-			cp = new dijit.layout.ContentPane({id: 'newTab' + tab, title: 'Tab' + tab, closable: true});
-			cp.domNode.innerHTML = "Contents of Tab " + tab++;
-			dijit.byId("plainTabContainer").addChild(cp);
-        }
+		require([
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/layout/ContentPane",
+			"dijit/layout/TabContainer",
+			"dijit/Tooltip",
+			"dojo/domReady!"
+		], function(parser, registry, ContentPane){
+
+			var tab = 6;
+
+			addTab = function(){
+				cp = new ContentPane({id: 'newTab' + tab, title: 'Tab' + tab, closable: true});
+				cp.domNode.innerHTML = "Contents of Tab " + tab++;
+				registry.byId("plainTabContainer").addChild(cp);
+			};
+
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
+
+	<script type="dojo/require">
+		registry: "dijit/registry"
+	</script>
 
 	<h1 class="testTitle">Dijit layout.TabContainer doLayout=false tests</h1>
 
@@ -64,23 +48,23 @@
 		With doLayout=false mode tabs only (the default) tabPosition=top is supported.
 	</p>
 
-	<button id="addTab" onclick="addTab();">add tab</button>
-	<button id="destroyTabContainer" onclick="dijit.byId('plainTabContainer').destroyRecursive();">destroy tab container</button>
+	<button id="addTabButton" onclick="addTab();">add tab</button>
+	<button id="destroyTabContainer" onclick="registry.byId('plainTabContainer').destroyRecursive();">destroy tab container</button>
 
-	<div id="plainTabContainer" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='doLayout:false, style:"width: 700px;"'>
+	<div id="plainTabContainer" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='doLayout:false, style:"width: 700px;"'>
 
-		<div id="tab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+		<div id="tab1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
-		<div id="tab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+		<div id="tab2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div id="tab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 3"'>
+		<div id="tab3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 3"'>
 			<h1 id="h3">I am tab 3</h1>
 			<p id="p3">And I was already part of the page! That's cool, no?</p>
 			<span id="foo">tooltip on this span</span>
-			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo"]'>I'm a tooltip!</div>
-			<button id="b3" data-dojo-type="dijit.form.Button">I'm a button </button>
+			<div data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["foo"]'>I'm a tooltip!</div>
+			<button id="b3" data-dojo-type="dijit/form/Button">I'm a button </button>
 			<br>
-			<button id="b4" data-dojo-type="dijit.form.Button">So am I!</button>
+			<button id="b4" data-dojo-type="dijit/form/Button">So am I!</button>
 			<p id="p4">
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -104,12 +88,12 @@
 			</p>
 		</div>
 
-		<div id="tab4" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Tab 4", doLayout:false, nested:true'>
-			<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab1.html"'>SubTab 1</a>
-			<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab2.html", selected:true'>SubTab 2</a>
+		<div id="tab4" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"Tab 4", doLayout:false, nested:true'>
+			<div id="tab4a" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html"' title="SubTab 1"></div>
+			<div id="tab4b" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", selected:true' title="SubTab 2"></div>
 		</div>
 
-		<a id="tab5" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab3_noLayout.html", doLayout:false'>Tab 5</a>
+		<div id="tab5" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab3_noLayout.html", doLayout:false' title="Tab 5"></div>
 	</div>
 
 	<p id="textAfterTabContainer1">
@@ -121,20 +105,20 @@
 	<table>
 		<tr>
 			<td style="width:400px; max-width:400px; border:1px solid red">
-				<div id="tableTabContainer" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='doLayout:false'>
+				<div id="tableTabContainer" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='doLayout:false'>
 			
-					<div id="atab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+					<div id="atab1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 			
-					<div id="atab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+					<div id="atab2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 			
-					<div id="atab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 3"'>
+					<div id="atab3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 3"'>
 						<h1 id="h4">I am tab 3</h1>
 						<p id="p6">And I was already part of the page! That's cool, no?</p>
 						<span id="foo2">tooltip on this span</span>
-						<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo2"]'>I'm a tooltip!</div>
-						<button id="b5" data-dojo-type="dijit.form.Button">I'm a button </button>
+						<div data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["foo2"]'>I'm a tooltip!</div>
+						<button id="b5" data-dojo-type="dijit/form/Button">I'm a button </button>
 						<br>
-						<button id="b6" data-dojo-type="dijit.form.Button">So am I!</button>
+						<button id="b6" data-dojo-type="dijit/form/Button">So am I!</button>
 						<p id="p7">
 						Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 						semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -158,12 +142,12 @@
 						</p>
 					</div>
 			
-					<div id="atab4" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Tab 4", nested:true, doLayout:false'>
-						<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab1.html"'>SubTab 1</a>
-						<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab2.html", selected:true'>SubTab 2</a>
+					<div id="atab4" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='title:"Tab 4", nested:true, doLayout:false'>
+						<div id="atab4a" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab1.html"' title="SubTab 1"></div>
+						<div id="atab4b" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab2.html", selected:true' title="SubTab 2"></div>
 					</div>
 			
-					<a id="atab5" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab3_noLayout.html", doLayout:false'>Tab 5</a>
+					<div id="atab5" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"tab3_noLayout.html", doLayout:false' title="Tab 5"></div>
 				</div>
 			</td>
 			</tr>
diff --git a/dijit/tests/loremIpsum.html b/dijit/tests/loremIpsum.html
new file mode 100644
index 0000000..2f2f4ff
--- /dev/null
+++ b/dijit/tests/loremIpsum.html
@@ -0,0 +1,99 @@
+<div>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+	<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus. </p>
+</div>
+
diff --git a/dijit/tests/mobile.html b/dijit/tests/mobile.html
index 5d1cc47..9cdef8e 100644
--- a/dijit/tests/mobile.html
+++ b/dijit/tests/mobile.html
@@ -10,9 +10,6 @@
 
 		<script language="JavaScript" type="text/javascript">
 			require([
-				"dojo/_base/kernel",
-				"dojo/_base/json",
-				"dijit",
 				"dojo/parser",
 
 				"dijit/MenuBar",
@@ -25,13 +22,8 @@
 
 				"dijit/Toolbar",
 				"dijit/ToolbarSeparator",
-				"dijit/form/Button",
-				"dijit/form/ComboButton",
-				"dijit/form/DropDownButton",
-				"dijit/form/ToggleButton",
 				"dijit/ColorPalette",
 				"dijit/TooltipDialog",
-				"dijit/form/TextBox",
 				"dijit/Dialog",
 
 				"dijit/ProgressBar",
@@ -41,122 +33,149 @@
 				"dijit/Tree",
 				"dojo/data/ItemFileReadStore",
 				"dijit/tree/ForestStoreModel",
+
+				"dijit/form/Button",
+				"dijit/form/DropDownButton",
+				"dijit/form/ComboButton",
+				"dijit/form/ToggleButton",
+				"dijit/form/TextBox",
+				"dijit/form/DateTextBox",
+				"dijit/form/TimeTextBox",
+
 				"dojo/domReady!"
-			], function(dojo, dijit){
-				dojo.parser.parse();
+			], function(parser){
+				parser.parse();
 			});
 		</script>
 	</head>
 	<body class="claro">
-		<div id="menubar" data-dojo-type="dijit.MenuBar">
-			<div id="file" data-dojo-type="dijit.PopupMenuBarItem" >
+		<div id="menubar" data-dojo-type="dijit/MenuBar">
+			<div id="file" data-dojo-type="dijit/PopupMenuBarItem" >
 				<span>File</span>
-				<div id="fileMenu" data-dojo-type="dijit.DropDownMenu" >
-					<div id="new" data-dojo-type="dijit.MenuItem" >New</div>
-					<div id="open" data-dojo-type="dijit.MenuItem" >Open</div>
-					<div id="separator" data-dojo-type="dijit.MenuSeparator" ></div>
-					<div id="save" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIconSave"'>Save</div>
-					<div id="saveas" data-dojo-type="dijit.MenuItem" >Save As...</div>
+				<div id="fileMenu" data-dojo-type="dijit/DropDownMenu" >
+					<div id="new" data-dojo-type="dijit/MenuItem" >New</div>
+					<div id="open" data-dojo-type="dijit/MenuItem" >Open</div>
+					<div id="separator" data-dojo-type="dijit/MenuSeparator" ></div>
+					<div id="save" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIconSave"'>Save</div>
+					<div id="saveas" data-dojo-type="dijit/MenuItem" >Save As...</div>
 				</div>
 			</div>
-			<div id="edit" data-dojo-type="dijit.PopupMenuBarItem" >
+			<div id="edit" data-dojo-type="dijit/PopupMenuBarItem" >
 				<span>Edit</span>
-				<div id="editMenu" data-dojo-type="dijit.DropDownMenu" >
-					<div id="cut" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+				<div id="editMenu" data-dojo-type="dijit/DropDownMenu" >
+					<div id="cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
 						onClick:function(){ console.log("not actually cutting anything, just a test!"); }, accelKey:"Ctrl+X"'>Cut</div>
-					<div id="copy" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+					<div id="copy" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
 						onClick:function(){ console.log("not actually copying anything, just a test!") }, accelKey:"Ctrl+C"'>Copy</div>
-					<div id="paste" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+					<div id="paste" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
 						onClick:function(){ console.log("not actually pasting anything, just a test!") }, accelKey:"Ctrl+V"'>Paste</div>
 				</div>
 			</div>
-			<div id="view" data-dojo-type="dijit.PopupMenuBarItem" >
+			<div id="view" data-dojo-type="dijit/PopupMenuBarItem" >
 				<span>View</span>
-				<div id="viewMenu" data-dojo-type="dijit.DropDownMenu" >
-					<div data-dojo-type="dijit.MenuItem">Normal</div>
-					<div data-dojo-type="dijit.MenuItem">Outline</div>
-					<div data-dojo-type="dijit.PopupMenuItem">
+				<div id="viewMenu" data-dojo-type="dijit/DropDownMenu" >
+					<div data-dojo-type="dijit/MenuItem">Normal</div>
+					<div data-dojo-type="dijit/MenuItem">Outline</div>
+					<div data-dojo-type="dijit/PopupMenuItem">
 						<span>Zoom</span>
-						<div id="zoomMenu" data-dojo-type="dijit.DropDownMenu" >
-							<div data-dojo-type="dijit.MenuItem">50%</div>
-							<div data-dojo-type="dijit.MenuItem">75%</div>
-							<div data-dojo-type="dijit.MenuItem">100%</div>
-							<div data-dojo-type="dijit.MenuItem">150%</div>
-							<div data-dojo-type="dijit.MenuItem">200%</div>
+						<div id="zoomMenu" data-dojo-type="dijit/DropDownMenu" >
+							<div data-dojo-type="dijit/MenuItem">50%</div>
+							<div data-dojo-type="dijit/MenuItem">75%</div>
+							<div data-dojo-type="dijit/MenuItem">100%</div>
+							<div data-dojo-type="dijit/MenuItem">150%</div>
+							<div data-dojo-type="dijit/MenuItem">200%</div>
 						</div>
 					</div>
 				</div>
 			</div>
 		</div>
 
-		<div id="toolbar1" data-dojo-type="dijit.Toolbar">
-			<div id="toolbar1.cut" data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</div>
-			<div id="toolbar1.bold" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBold", showLabel:false'>Bold2</div>
-			<span data-dojo-type="dijit.ToolbarSeparator"></span>
-			<div id="toolbar1.ttdialog" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"plusIcon", showLabel:true'>
+		<div id="toolbar1" data-dojo-type="dijit/Toolbar">
+			<div id="toolbar1.cut" data-dojo-type="dijit/form/Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</div>
+			<div id="toolbar1.bold" data-dojo-type="dijit/form/ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBold", showLabel:false'>Bold2</div>
+			<span data-dojo-type="dijit/ToolbarSeparator"></span>
+			<div id="toolbar1.ttdialog" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"plusIcon", showLabel:true'>
 				<span>TD</span>
-				<div id="tooltipDlg" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information",
-					execute:function(args){ console.log("submitted w/args:\n" + dojo.toJson(args, true)); }'>
+				<div id="tooltipDlg" data-dojo-type="dijit/TooltipDialog" data-dojo-props='title:"Enter Login information",
+					execute:function(args){ console.log("submitted w/args:\n" + JSON.stringify(args, true)); }'>
 					<table>
 						<tr>
 							<td><label for="user">User:</label></td>
-							<td><input id="user" data-dojo-type=dijit.form.TextBox data-dojo-props='type:"text", name:"user" '/></td>
+							<td><input id="user" data-dojo-type=dijit/form/TextBox data-dojo-props='type:"text", name:"user" '/></td>
 						</tr>
 						<tr>
 							<td><label for="password">Password:</label></td>
-							<td><input id="password" data-dojo-type=dijit.form.TextBox data-dojo-props='type:"password", name:"pwd"'/></td>
+							<td><input id="password" data-dojo-type=dijit/form/TextBox data-dojo-props='type:"password", name:"pwd"'/></td>
 						</tr>
 						<tr>
 							<td colspan="2" style="text-align:center;">
-								<button data-dojo-type=dijit.form.Button data-dojo-props='type:"submit", name:"submit"'>Login</button></td>
+								<button data-dojo-type=dijit/form/Button data-dojo-props='type:"submit", name:"submit"'>Login</button></td>
 						</tr>
 					</table>
 				</div
 			></div>
-			<div id="toolbar1.backcolor" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBackColor", showLabel:true'>
-				<span>CP�</span>
-				<div id="toolbar1.colorPalette" data-dojo-type="dijit.ColorPalette" data-dojo-props='style:"display: none", palette:"7x10", onChange:function(){ console.log(this.value); }'></div>
+			<div id="toolbar1.backcolor" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBackColor", showLabel:true'>
+				<span>CP</span>
+				<div id="toolbar1.colorPalette" data-dojo-type="dijit/ColorPalette" data-dojo-props='style:"display: none", palette:"7x10", onChange:function(){ console.log(this.value); }'></div>
 			</div
-			><div id="toolbar1.combo" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", iconClass:"plusIcon", showLabel:true,
+			><div id="toolbar1.combo" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"save options", iconClass:"plusIcon", showLabel:true,
 				onClick:function(){ console.log("clicked combo save") }'>
 				<span>Menu</span>
-				<div id="saveMenu" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
-					<div data-dojo-type="dijit.MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+				<div id="saveMenu" data-dojo-type="dijit/Menu" data-dojo-props='style:"display: none;"'>
+					<div data-dojo-type="dijit/MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
 						onClick:function(){ console.log("not actually saving anything, just a test!") }'>Save</div>
-					<div data-dojo-type="dijit.MenuItem"
+					<div data-dojo-type="dijit/MenuItem"
 						data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!") }'>Save As</div>
 				</div>
 			</div>
-			<div id="toolbar1.dialog" data-dojo-type="dijit.form.Button" onclick="dijit.byId('dialog').show();"
+			<div id="toolbar1.dialog" data-dojo-type="dijit/form/Button" onclick="dialog.show();"
 				 data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCreateLink"'>Dialog</div>
 		</div>
 
-		<div id="dialog" data-dojo-type="dijit.Dialog" data-dojo-props='title:"My Dialog",
+		<div data-dojo-id="dialog" data-dojo-type="dijit/Dialog" data-dojo-props='title:"My Dialog",
 				onExecute:function(){ console.log("OK button pressed") },
 				onCancel:function(){ console.log("Cancel button pressed") },
 				"aria-describedby":"intro",
-				execute:function(args){ console.log("submitted w/args:\n" + dojo.toJson(args, true)); }'>
+				execute:function(args){ console.log("submitted w/args:\n" + JSON.stringify(args, true)); }'>
 			<div class="dijitDialogPaneContentArea">
-				<table>
-					<tr>
-						<td><label for="user2">User:</label></td>
-						<td><input id="user2" style="width: 100px" data-dojo-type=dijit.form.TextBox data-dojo-props='type:"text", name:"user" '/></td>
-					</tr>
-					<tr>
-						<td><label for="password2">Password:</label></td>
-						<td><input id="password2" style="width: 100px" data-dojo-type=dijit.form.TextBox data-dojo-props='type:"password", name:"pwd"'/></td>
-					</tr>
-				</table>
+				<label for="fname">First: </label>
+				<br>
+				<input id="fname" name="fname" data-dojo-type="dijit/form/TextBox"/>
+				<br>
+
+				<label for="lname">Last: </label>
+				<br>
+				<input id="lname" name="lname" data-dojo-type="dijit/form/TextBox"/>
+				<br>
+
+				<label for="loc">Location: </label>
+				<br>
+				<input id="loc" name="loc" data-dojo-type="dijit/form/TextBox"/>
+				<br>
+
+				<label for="date">Date: </label>
+				<br>
+				<input id="date" name="date" data-dojo-type="dijit/form/DateTextBox"/>
+				<br>
+
+				<label>Time: </label>
+				<br>
+				<input id="time" name="time" data-dojo-type="dijit/form/TimeTextBox"/>
+				<br>
+
+				<label for="desc">Description: </label>
+				<br>
+				<input id="desc" name="desc" data-dojo-type="dijit/form/DateTextBox"/>
 			</div>
 			<div class="dijitDialogPaneActionBar">
-				<button id="dialogbutton1" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit" '>OK</button>
-				<button id="dialogbutton2" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ dijit.byId("dialog").onCancel(); }
+				<button id="dialogbutton1" data-dojo-type="dijit/form/Button" data-dojo-props='type:"submit" '>OK</button>
+				<button id="dialogbutton2" data-dojo-type="dijit/form/Button" data-dojo-props='type:"button", onClick:function(){ dialog.onCancel(); }
 						'>Cancel</button>
 			</div>
 		</div>
 
 		<br>
-		<div id="tp" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #2"'>
+		<div id="tp" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Title Pane #2"'>
 			<form>
 				<label for="age">Age: </label> <input id="age"/><br>
 				<label for="disc">Discount card </label><input id="disc" type="checkbox"/><br>
@@ -165,19 +184,19 @@
 		</div>
 
 		<br>
-		<div id="setTestBar" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:90%",
+		<div id="setTestBar" data-dojo-type="dijit/ProgressBar" data-dojo-props='style:"width:90%",
 			maximum:200, value:"20" '></div>
 
 		<br>
-		<div data-dojo-id="continentStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"_data/countries.json"'></div>
-		<div data-dojo-id="continentModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
+		<div data-dojo-id="continentStore" data-dojo-type="dojo/data/ItemFileReadStore" data-dojo-props='url:"_data/countries.json"'></div>
+		<div data-dojo-id="continentModel" data-dojo-type="dijit/tree/ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
 			rootId:"continentRoot", rootLabel:"Continents", childrenAttrs:["children"]'></div>
 
-		<div id="mytree" data-dojo-type="dijit.Tree" data-dojo-props='model:continentModel, openOnClick:true'>
+		<div id="mytree" data-dojo-type="dijit/Tree" data-dojo-props='model:continentModel, openOnClick:true'>
 		</div>
 
 		<br>
-		InlineEditBox: <span id="ieb" data-dojo-type="dijit.InlineEditBox" data-dojo-props='width:"200px", title:"recipient name"'></span>
+		InlineEditBox: <span id="ieb" data-dojo-type="dijit/InlineEditBox" data-dojo-props='width:"200px", title:"recipient name"'></span>
 
 	</body>
 </html>
diff --git a/dijit/tests/module.js b/dijit/tests/module.js
index 0a99dc2..cd71ef1 100644
--- a/dijit/tests/module.js
+++ b/dijit/tests/module.js
@@ -1,18 +1,14 @@
-dojo.provide("dijit.tests.module");
-
-try{
-	dojo.require("dijit.tests._base.module");
-	dojo.require("dijit.tests.infrastructure-module");
-
-	dojo.require("dijit.tests.general-module");
-	dojo.require("dijit.tests.tree.module");
-	dojo.require("dijit.tests.editor.module");
-	dojo.require("dijit.tests.form.module");
-	dojo.require("dijit.tests.layout.module");
-
-	dojo.require("dijit.tests._BidiSupport.module");
-}catch(e){
-	doh.debug(e);
-}
+define([
+	"./_base/module",
+	"./infrastructure-module",
+
+	"./general-module",
+	"./tree/module",
+	"./editor/module",
+	"./form/module",
+	"./layout/module",
+
+	"./_BidiSupport/module"
+], 1);
 
 
diff --git a/dijit/tests/place-clip.html b/dijit/tests/place-clip.html
new file mode 100644
index 0000000..b0002f9
--- /dev/null
+++ b/dijit/tests/place-clip.html
@@ -0,0 +1,267 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>dijit/place on clipped nodes unit test</title>
+
+	<script src="boilerplate.js"></script>
+
+	<style type="text/css">
+		html, body, div {
+			border: none;
+			margin: 0px;
+			padding: 0px;
+		}
+
+		.around {
+			/* the around-node (ex: a ComboBox or TextBox) */
+			color: white;
+			background: blue;
+		}
+
+		.clip {
+			/* ancestor of an around-node that clips the around-node */
+			display: inline-block;
+			#display: inline;
+			overflow: hidden;
+			background: gray;
+
+			padding: 10px 0px;
+			margin: 0px 100px;
+			width: 100px;
+		}
+
+		#popup {
+			position: absolute;
+			width: 25px;
+			background: red;
+			color: white;
+		}
+	</style>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/dom", "dojo/dom-geometry", "dojo/window",
+			"dijit/place", "dojo/parser", "dojo/domReady!"
+		], function(doh, dom, domGeometry, winUtils, place, parser){
+
+			parser.parse();
+
+			// The around nodes
+			var aroundOne = dom.byId("around1"),
+				aroundTwo = dom.byId("around2"),
+				aroundThree = dom.byId("around3"),
+				abs1 = dom.byId("absAround1"),
+				abs2 = dom.byId("absAround2"),
+				abs3 = dom.byId("absAround3");
+
+			// The popup (aka dropdown)
+			var popup = dom.byId("popup"),
+				pp,
+				ret;
+
+			doh.register("aroundOne", [
+				function plain(t){
+					ret = place.around(popup, aroundOne, [
+						"before-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(100, pp.x + pp.w, "popup hugs left side of clipping div");
+
+					ret = place.around(popup, aroundOne, [
+						"after-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(200, pp.x, "popup hugs right side of clipping div");
+				},
+				function aroundOneScrolled(t){
+					// Programatically scroll to the right
+					dom.byId("clip1").scrollLeft = 50;
+
+					// Same tests as before
+					ret = place.around(popup, aroundOne, [
+						"before-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(100, pp.x + pp.w, "popup hugs left side of clipping div");
+
+					ret = place.around(popup, aroundOne, [
+						"after-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(200, pp.x, "popup hugs right side of clipping div");
+				},
+				function aroundOneScrollbar(t){
+					// Show scroll bar
+					dom.byId("clip1").style.overflow = "scroll";
+
+					// Same tests as before
+					ret = place.around(popup, aroundOne, [
+						"before-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(100, pp.x + pp.w, "popup hugs left side of clipping div");
+
+					ret = place.around(popup, aroundOne, [
+						"after-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(200, pp.x, "popup hugs right side of clipping div");
+				}
+
+			]);
+
+			doh.register("aroundTwo", [
+				function plain(t){
+					ret = place.around(popup, aroundTwo, [
+						"before-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(100, pp.x + pp.w, "popup hugs left side of outer clipping div");
+
+					ret = place.around(popup, aroundTwo, [
+						"after-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(200, pp.x, "popup hugs right side of outer clipping div");
+				}
+			]);
+
+			doh.register("aroundThree", [
+				function plain(t){
+					ret = place.around(popup, aroundThree, [
+						"before-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(150, pp.x + pp.w, "popup hugs left side of inner clipping div");
+
+					ret = place.around(popup, aroundThree, [
+						"after-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(250, pp.x, "popup hugs right side of inner clipping div");
+				}
+			]);
+
+			doh.register("absolutely positioned nodes", [
+				function aroundNodeAbsolute(t){
+					ret = place.around(popup, abs1, [
+						"before-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(50, pp.x + pp.w, "popup hugs left side of absolutely positioned around node");
+
+					ret = place.around(popup, abs1, [
+						"after-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(350, pp.x, "popup hugs right side of absolutely positioned around node");
+				},
+				function aroundNodeParentAbsolute(t){
+					ret = place.around(popup, abs2, [
+						"before-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(60, pp.x + pp.w, "popup hugs left side of absolutely positioned around node wrapper");
+
+					ret = place.around(popup, abs2, [
+						"after-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(120, pp.x, "popup hugs right side of absolutely positioned around node wrapper");
+				},
+				function absoluteInRelative(t){
+					ret = place.around(popup, abs3, [
+						"before-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(110, pp.x + pp.w, "popup hugs left side of position:absolute parent");
+
+					ret = place.around(popup, abs3, [
+						"after-centered"
+					], true);
+
+					pp = domGeometry.position(popup);
+					doh.is(170, pp.x, "popup hugs right side of position:relative grandparent (which clips parent)");
+				}
+			]);
+			doh.run();
+		});
+
+	</script>
+</head>
+<body class="claro" dir="ltr">
+	<h1>Dijit Place Clipping Unit Test</h1>
+
+	<!-- the popup "widget" -->
+	<div id="popup">
+		p
+	</div>
+
+	<!-- around node one is clipped by surrounding div. -->
+	<div id="clip1" class="clip">
+		<div id="around1" class="around" style="width: 500px; height: 50px;">123456789abcdef</div>
+	</div>
+
+	<!-- around node one is clipped by clip2b, and even more by clip2a -->
+	<br/>
+	<div id="clip2a" class="clip">
+		<div id="clip2b" style="width: 200px; margin: 0px; background: white" class="clip">
+			<div id="noclip2">
+				<div id="around2" class="around" style="width: 500px; height: 50px;">123456789abcdef</div>
+			</div>
+		</div>
+	</div>
+
+	<!-- around node one is clipped by clip3b, but not by clip2a since that is bigger -->
+	<br/>
+	<div id="clip3a" style="width: 200px; background: yellow; padding: 10px 50px;" class="clip">
+		<div id="clip3b" style="margin: 0px" class="clip">
+			<div id="noclip3">
+				<div id="around3" class="around" style="width: 500px; height: 50px;">123456789abcdef</div>
+			</div>
+		</div>
+	</div>
+
+	<!-- position absolute around node is not affected by a parent with width set
+		(unless parent has position:relative or position:absolute) -->
+	<br/>
+	<div id="clip4" class="clip">
+		<div id="absAround1" class="around" style="width: 300px; height: 50px; position: absolute; left: 50px; top:500px;">absolute</div>
+	</div>
+
+	<!-- here the around node absAround2 is position:static, but it's parent clip5b is position:absolute,
+		so the grandparent clip5a is irrelevant -->
+	<br/>
+	<div id="clip5a" style="width: 50px; background: yellow; padding: 10px 50px;" class="clip">
+		<div id="clip5b" style="position: absolute; left: 60px; top: 600px; width: 60px; background: navy; margin: 0px;" class="clip">
+			<div id="absAround2" class="around" style="width: 500px; height: 50px;">parent absolute</div>
+		</div>
+	</div>
+
+	<!-- here the around node absAround3 is position:static, it's parent clip6b is position:absolute,
+		but the grandparent clip6a is position:relative, so it can clip -->
+	<br/>
+	<div id="clip6a" style="width: 70px; height: 70px; background: #adff2f; padding: 0px; position: relative;" class="clip">
+		<div id="clip6b" style="position: absolute; left: 10px; top: 0px; width: 150px; background: navy; margin: 0px;" class="clip">
+			<div id="absAround3" class="around" style="width: 500px; height: 50px;">grandparent relative</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dijit/tests/place-margin.html b/dijit/tests/place-margin.html
new file mode 100644
index 0000000..85e21dd
--- /dev/null
+++ b/dijit/tests/place-margin.html
@@ -0,0 +1,104 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>dijit/place with margin on body unit test</title>
+
+	<script src="boilerplate.js"></script>
+
+	<style type="text/css">
+		html {
+			overflow: hidden; /* ie6 needs this */
+		}
+		body {
+			height: 100%;
+			padding: 0;
+			border: 0;
+
+			/* testing for margin on <body>, see #16148 */
+			position: relative;
+			top: 0;
+			margin-top: 40px;
+			margin-left: 10px;
+			margin-right: 20px;
+		}
+
+		.aroundNode {
+			position: absolute;
+			width: 20px;
+			height: 20px;
+			background: yellow;
+		}
+
+		#popup {
+			position: absolute;
+			width: 75px;
+			background: blue;
+			color: white;
+		}
+	</style>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/dom", "dojo/dom-geometry", "dojo/window",
+			"dijit/place", "dojo/domReady!"
+		], function(doh, dom, domGeometry, winUtils, place){
+
+			// The around nodes
+			var aroundTop = dom.byId("aroundTop"),
+				aroundLeft = dom.byId("aroundLeft"),
+				aroundRight = dom.byId("aroundRight");
+
+			// The popup (aka dropdown)
+			var popup = dom.byId("popup");
+
+			doh.register("around with body margin", [
+				function aroundT(t){
+					// Dropdown from "aroundTop" node.
+					var ret = place.around(popup, aroundTop, [
+						"below"	// aroundTop's bottom-left corner with the popup's top-left corner
+					], true);
+
+					doh.is("20px", popup.style.top, "underneath around node");
+				},
+				function aroundL(t){
+					// middle left popup from "aroundLeft" node
+					var ret = place.around(popup, aroundLeft, [
+						"after-centered"	// aroundLeft's middle-right with the popup's middle-left
+					], true);
+
+					var popupPos = domGeometry.position(popup);
+					var aroundPos = domGeometry.position(aroundLeft);
+					doh.is(Math.round(aroundPos.x + aroundPos.w), Math.round(popupPos.x), "after around node");
+				},
+				function aroundR(t){
+					// This will put the drop-down to the left of the "aroundRight" node
+					var ret = place.around(popup, aroundRight, ["before-centered"], true);
+
+					var popupPos = domGeometry.position(popup);
+					var aroundPos = domGeometry.position(aroundRight);
+					doh.is(Math.round(popupPos.x + popupPos.w), Math.round(aroundPos.x),
+							"right aligned with around node");
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+<body style="position: relative; top: 0; margin-top: 40px;">
+	<h1>Dijit Place With Margin On BODY Unit Test</h1>
+	<div id="aroundTop" class="aroundNode" style="top: 0px; left: 50%">T</div>
+	<div id="aroundLeft" class="aroundNode" style="bottom: 30%; left: 0px;">L</div>
+	<div id="aroundRight" class="aroundNode" style="bottom: 30%; right: 0px;">R</div>
+
+	<div id="popup">
+		I'm a drop down, wider and taller than the around nodes I'm placed next to.
+	</div>
+	<div style="height: 200px">
+		<!-- spacer -->
+	</div>
+</body>
+</html>
diff --git a/dijit/tests/place.html b/dijit/tests/place.html
new file mode 100644
index 0000000..2ae1507
--- /dev/null
+++ b/dijit/tests/place.html
@@ -0,0 +1,251 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>dijit/place unit test</title>
+
+	<script src="boilerplate.js"></script>
+
+	<style type="text/css">
+		html {
+			overflow: hidden; /* ie6 needs this */
+		}
+		body {
+			height: 100%;
+			padding: 0;
+			margin: 10px; /* negative test for #16148; shouldn't affect placement unless body position relative/absolute */
+			border: 0;
+		}
+
+		.aroundNode {
+			position: absolute;
+			width: 20px;
+			height: 20px;
+			background: yellow;
+		}
+
+		#popup {
+			position: absolute;
+			width: 75px;
+			background: blue;
+			color: white;
+		}
+	</style>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/dom", "dojo/dom-geometry", "dojo/window",
+			"dijit/place", "dojo/domReady!"
+		], function(doh, dom, domGeometry, winUtils, place){
+
+			// The around nodes
+			var aroundTop = dom.byId("aroundTop"),
+				aroundBottom = dom.byId("aroundBottom"),
+				aroundLeft = dom.byId("aroundLeft"),
+				aroundRight = dom.byId("aroundRight");
+
+			// The popup (aka dropdown)
+			var popup = dom.byId("popup");
+
+			doh.register("at", [
+				function atTL(t){
+					// Place popup at (10,7)... place.at() should choose the top-left corner, because
+					// any of the other corner would make the popup go partially off the screen
+					var ret = place.at(popup, {x: 10, y:7}, ["TR", "BR", "BL", "TL"]);
+
+					doh.is("TL", ret.corner, "top left corner chosen");
+					doh.is("10px", popup.style.left, "x coord");
+					doh.is("7px", popup.style.top, "y coord");
+					doh.is(75, ret.w, "it's 75px wide");
+				},
+				function atTooltip(t){
+					// Same as above test except that shape of drop down changes depending on where it's positioned.
+					// Simulates tooltip placement (tooltip shape changes b/c of the arrow).
+
+					function layoutNode(node, aroundCorner, nodeCorner){
+						node.style.width = (nodeCorner == "TL" ? "80px" : "75px");
+					}
+					var ret = place.at(
+							popup,
+							{x: 10, y: 7},		// center of aroundNode
+							["TR", "BR", "BL", "TL"],
+							{x: 5, y: 5},		// half of width and height of aroundNode
+							layoutNode
+					);
+
+					doh.is("TL", ret.corner, "popup's corner");
+					doh.is("BR", ret.aroundCorner, "around corner");
+					doh.is("80px", popup.style.width, "layout node width");
+					popup.style.width = "75px";
+				},
+				function atTR(t){
+					// Place popup at top right... place.at() should choose the top-right corner, because
+					// any of the other corner would make the popup go partially off the screen
+					var viewport = winUtils.getBox(),
+						ret = place.at(popup, {x: viewport.w-10, y:7}, ["TL", "BR", "TR", "BL"]),
+						popupCoords = domGeometry.position(popup);
+
+					doh.is("TR", ret.corner, "top left corner chosen");
+					doh.is(viewport.w-10, popupCoords.x + popupCoords.w, "x coord");
+					doh.is("7px", popup.style.top, "y coord");
+					doh.is(75, ret.w, "it's 75px wide");
+				}
+			]);
+
+			doh.register("around", [
+				function aroundT(t){
+					// Dropdown from "aroundTop" node. Should pick the second choice, since the first
+					// goes off screen.
+					var ret = place.around(popup, aroundTop, [
+						"above",	// aroundTop's top-left corner with the popup's bottom-left corner (fails)
+						"below",	// aroundTop's bottom-left corner with the popup's top-left corner (works)
+						"below-alt"	// aroundTop's bottom-right corner with the popup's top-right corner (works)
+					], true);
+
+					doh.is("BL", ret.aroundCorner, "around corner");
+					doh.is("TL", ret.corner, "popup's corner");
+					doh.is("20px", popup.style.top, "underneath around node");
+					doh.is(Math.round(domGeometry.position(aroundTop).x), Math.round(popup.style.left.replace("px", "")),
+							"left sides aligned");
+				},
+				function aroundTooltip(t){
+					// Same as above test except that shape of drop down changes depending on where it's positioned.
+					// Simulates tooltip placement (tooltip shape changes b/c of the arrow).
+					// Should pick the third choice this time
+
+					function layoutNode(node, aroundCorner, nodeCorner){
+						node.style.width = (nodeCorner == "TL" ? "5000px" : "75px");
+					}
+					var ret = place.around(popup, aroundTop, [
+						"above",	// aroundTop's top-left corner with the popup's bottom-left corner (fails)
+						"below",	// aroundTop's bottom-left corner with the popup's top-left corner (works)
+						"below-alt"	// aroundTop's bottom-right corner with the popup's top-right corner (works)
+					], true, layoutNode);
+
+					doh.is("BR", ret.aroundCorner, "around corner");
+					doh.is("TR", ret.corner, "popup's corner");
+					doh.is("20px", popup.style.top, "underneath around node");
+					doh.is(Math.round(domGeometry.position(aroundTop).x+domGeometry.position(aroundTop).w),
+						Math.round(domGeometry.position(popup).x+domGeometry.position(popup).w),
+						"right sides aligned");
+				},
+				function aroundB(t){
+					// Dropdown from "aroundBottom" node. Should go above aroundNode so that
+					// popup doesn't go offscreen
+					var ret = place.around(popup, aroundBottom, [
+						"below",	// aroundBottom's bottom-left corner with the popup's top-left corner (fails)
+						"above",	// aroundBottom's top-left corner with the popup's bottom-left corner (works)
+						"below-alt"	// aroundBottom's bottom-right corner with the popup's top-right corner (fails)
+					], true);
+
+					doh.is("TL", ret.aroundCorner, "around corner");
+					doh.is("BL", ret.corner, "popup's corner");
+					doh.is(Math.round(domGeometry.position(aroundBottom).y),
+							Math.round(domGeometry.position(popup).y + domGeometry.position(popup).h), "above around node");
+				},
+				function aroundBM(t){
+					// bottom middle popup from "aroundBottom" node
+					var ret = place.around(popup, aroundBottom, [
+						"above-centered",	// aroundBottom's top-middle with the popup's bottom-middle (works)
+						"below-centered"	// aroundBottom's bottom-middle with the popup's top-middle (fails)
+					], true);
+
+					doh.is("TM", ret.aroundCorner, "around middle");
+					doh.is("BM", ret.corner, "popup's middle");
+					var popupPos = domGeometry.position(popup);
+					var aroundPos = domGeometry.position(aroundBottom);
+					doh.is(Math.round(aroundPos.y), Math.round(popupPos.y + popupPos.h), "above around node");
+					doh.t(aroundPos.x > popupPos.x, "starts before around node");
+					doh.t(aroundPos.x < (popupPos.x + popupPos.w), "ends after around node");
+				},
+				function aroundTM(t){
+					// top middle popup from "aroundTop" node
+					var ret = place.around(popup, aroundTop, [
+						"above-centered",	// aroundTop's top-middle with the popup's bottom-middle (fails)
+						"below-centered"	// aroundTop's bottom-middle with the popup's top-middle (works)
+					], true);
+
+					doh.is("BM", ret.aroundCorner, "around middle");
+					doh.is("TM", ret.corner, "popup's middle");
+					var popupPos = domGeometry.position(popup);
+					var aroundPos = domGeometry.position(aroundTop);
+					doh.is(Math.round(aroundPos.y + aroundPos.h), Math.round(popupPos.y), "below around node");
+					doh.t(aroundPos.x > popupPos.x, "starts before around node");
+					doh.t(aroundPos.x < (popupPos.x + popupPos.w), "ends after around node");
+				},
+				function aroundML(t){
+					// middle left popup from "aroundLeft" node
+					var ret = place.around(popup, aroundLeft, [
+						"after-centered",	// aroundLeft's middle-right with the popup's middle-left (works)
+						"before-centered"	// aroundLeft's middle-left with the popup's middle-right (fails)
+					], true);
+
+					doh.is("MR", ret.aroundCorner, "around middle");
+					doh.is("ML", ret.corner, "popup's middle");
+					var popupPos = domGeometry.position(popup);
+					var aroundPos = domGeometry.position(aroundLeft);
+					doh.is(Math.round(aroundPos.x + aroundPos.w), Math.round(popupPos.x), "after around node");
+					doh.t(aroundPos.y > popupPos.y, "starts before around node");
+					doh.t(aroundPos.y < (popupPos.y + popupPos.h), "ends after around node");
+				},
+				function aroundMR(t){
+					// middle left popup from "aroundRight" node
+					var ret = place.around(popup, aroundRight, [
+						"after-centered",	// aroundRight's middle-right with the popup's middle-left (fails)
+						"before-centered"	// aroundRight's middle-left with the popup's middle-right (works)
+					], true);
+
+					doh.is("ML", ret.aroundCorner, "around middle");
+					doh.is("MR", ret.corner, "popup's middle");
+					var popupPos = domGeometry.position(popup);
+					var aroundPos = domGeometry.position(aroundRight);
+					doh.is(Math.round(popupPos.x + popupPos.w), Math.round(aroundPos.x), "before around node");
+					doh.t(aroundPos.y > popupPos.y, "starts before around node");
+					doh.t(aroundPos.y < (popupPos.y + popupPos.h), "ends after around node");
+				},
+				function aroundMLB(t){
+					// This will put the drop-down below the "aroundLeft" node, first trying to right-align
+					// but since that doesn't work then trying to left-align.
+					var ret = place.around(popup, aroundLeft, ["below-alt"], true);
+
+					doh.is("BL", ret.aroundCorner, "around left");
+					doh.is("TL", ret.corner, "popup's left");
+					var popupPos = domGeometry.position(popup);
+					var aroundPos = domGeometry.position(aroundLeft);
+					doh.is(Math.round(aroundPos.y + aroundPos.h), Math.round(popupPos.y), "below around node");
+					doh.is(aroundPos.x, popupPos.x, "left aligned with around node");
+				},
+				function aroundMRT(t){
+					// This will put the drop-down above the "aroundRight" node, first trying to left-align
+					// but since that doesn't work then trying to right-align.
+					var ret = place.around(popup, aroundRight, ["above"], true);
+
+					doh.is("TR", ret.aroundCorner, "around right");
+					doh.is("BR", ret.corner, "popup's right");
+					var popupPos = domGeometry.position(popup);
+					var aroundPos = domGeometry.position(aroundRight);
+					doh.is(Math.round(popupPos.x + popupPos.w), Math.round(aroundPos.x + aroundPos.w),
+							"right aligned with around node");
+					doh.is(Math.round(popupPos.y + popupPos.h), Math.round(aroundPos.y),
+							"above around node");
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+<body>
+	<h1>Dijit Place Unit Test</h1>
+	<div id="aroundTop" class="aroundNode" style="top: 0; left: 50%">T</div>
+	<div id="aroundLeft" class="aroundNode" style="bottom: 30%; left: 0;">L</div>
+	<div id="aroundRight" class="aroundNode" style="bottom: 30%; right: 1px;">R</div>
+	<div id="aroundBottom" class="aroundNode" style="bottom: 5px; left: 50%;">B</div>
+
+	<div id="popup">
+		I'm a drop down, wider and taller than the around nodes I'm placed next to.
+	</div>
+</body>
+</html>
diff --git a/dijit/tests/popup.html b/dijit/tests/popup.html
new file mode 100644
index 0000000..147f98b
--- /dev/null
+++ b/dijit/tests/popup.html
@@ -0,0 +1,615 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+	<title>popup and BackgroundIFrame unit test</title>
+
+	<script src="boilerplate.js"></script>
+
+	<style type="text/css">
+		body {
+			height: 100%;
+			padding: 0;
+			margin: 0;
+		}
+
+		div {
+			background: white;
+			border: solid 1px gray;
+		}
+
+		/* the menu type test widgets */
+		.choice div {
+			width: 200px;
+			cursor: pointer;
+		}
+		.choice div:hover {
+			background: #ccc;
+		}
+	</style>
+
+	<script type="text/javascript">
+		function log(str){
+			console.log(str);
+		}
+
+		require([
+			"doh/runner",
+			"dojo/_base/declare",
+			"dojo/dom", "dojo/dom-construct", "dojo/dom-geometry", "dojo/dom-style",
+			"dojo/query", "dojo/sniff", "dojo/_base/window", "dojo/window",
+			"dijit/popup", "dijit/registry", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
+			"dijit/tests/helpers", "dojo/domReady!"
+		], function(doh, declare, dom, domConstruct, domGeometry, domStyle, query, has, win, winUtils,
+					popupUtil, registry, _WidgetBase, _TemplatedMixin){
+
+
+			declare("SimpleDropDownButton", [_WidgetBase, _TemplatedMixin], {
+				// summary:
+				//		A button that shows a popup.
+				//		Supply popup as parameter when instantiating this widget.
+
+				label: "show popup",
+				orient: ["below"],
+
+				templateString: "<button data-dojo-attach-event='onclick: openPopup'>${label}</button>",
+
+				openPopup: function(){
+					var self = this;
+
+					popupUtil.open({
+						popup: this.popup,
+						parent: this,
+						around: this.domNode,
+						orient: this.orient,
+						onCancel: function(){
+							log(self.id + ": cancel of child");
+						},
+						onExecute: function(){
+							log(self.id + ": execute of child");
+							popupUtil.close(self.popup);
+							self.open = false;
+						}
+					});
+
+					this.open = true;
+				},
+
+				closePopup: function(){
+					if(this.open){
+						log(this.id + ": close popup due to blur");
+						popupUtil.close(this.popup);
+						this.open = false;
+					}
+				},
+
+				_onBlur: function(){
+					// summary:
+					//		This is called from focus manager and when we get the signal we
+					//		need to close the drop down
+					this.closePopup();
+				}
+			});
+
+			declare("SimplePopup",  [_WidgetBase, _TemplatedMixin], {
+				// summary:
+				//		A trivial popup widget
+
+				templateString: "<span>i'm a popup</span>"
+			});
+
+			declare("Tooltip", [_WidgetBase, _TemplatedMixin], {
+				// summary:
+				//		A popup with an orient() method to adjust arrows
+
+				templateString: "<span>i'm a tooltip</span>",
+				constructor: function(){
+					this.orientCalls = [];
+				},
+				orient: function(node, aroundCorner, corner, spaceAvailable, aroundNodeCoords){
+					this.orientCalls.push({
+						node: node,
+						aroundCorner: aroundCorner,
+						corner: corner,
+						spaceAvailable: spaceAvailable,
+						aroundNodeCoords: aroundNodeCoords
+					});
+				},
+				onOpen: function(pos){
+					// should be called with pos.corner and pos.aroundCorner set
+					this.onOpenArg = pos;
+				}
+			});
+
+			declare("SimpleChoiceWidget",  [_WidgetBase, _TemplatedMixin], {
+				// summary:
+				//		A list of values; select a value by pressing an entry in the list.
+
+				choice1: "1",
+				choice2: "2",
+				choice3: "3",
+
+				templateString:
+					"<div class='choice'>" +
+						"<div data-dojo-attach-event='onclick: onClick'>${choice1}</div>" +
+						"<div data-dojo-attach-event='onclick: onClick'>${choice2}</div>" +
+						"<div data-dojo-attach-event='onclick: onClick'>${choice3}</div>" +
+					"</div>",
+
+				onClick: function(e){
+					this.onChange(e.target.innerHTML);
+				},
+
+				onChange: function(val){
+					// summary:
+					//		When this widget is used as a popup, popup monitors calls
+					//		to onChange and then closes the popup
+					log(this.id + ": selected " + val);
+				}
+			});
+
+			declare("LotsOfChoicesWidget",  [_WidgetBase], {
+				// summary:
+				//		A list of values; select a value by pressing an entry in the list.
+
+				length: 100,
+
+				postCreate: function(){
+					for(var i=0; i< this.length; i++){
+						domConstruct.place("<div>choice #" + i + "</div>", this.domNode);
+					}
+				}
+			});
+
+			// Create a button that displays a simple drop down
+			choiceDropDown = new SimpleChoiceWidget();
+			(choiceDropDownButton = new SimpleDropDownButton({
+				id: "choiceDropDownButton",
+				label: "show choice drop down",
+				popup: choiceDropDown
+			})).placeAt(dom.byId("widgets"));
+
+			// Create a tall drop down, should get scroll bar
+			tallChoiceDropDown = new LotsOfChoicesWidget({length: 100});
+			(tallChoiceDropDownButton = new SimpleDropDownButton({
+				id: "tallChoiceDropDownButton",
+				label: "show tall drop down",
+				popup: tallChoiceDropDown
+			})).placeAt(dom.byId("widgets"));
+
+			declare("DialogWithPopupWidget",  [_WidgetBase, _TemplatedMixin], {
+				// summary:
+				//		This is a dialog that contains a button that spawns a drop down.
+				//		Supply popup as an argument to this widget.
+
+				title: "I'm a dialog",
+				label: "click me",
+
+				templateString:
+					"<div style='width: 300px'>" +
+						"<div>${title}</div>" +
+						"<input><br>" +
+						"<button data-dojo-attach-point='button'>${label}</button><br>" +
+						"<button data-dojo-attach-event='onclick: onExecute'>OK</button>" +
+					"</div>",
+
+				postCreate: function(){
+					// Convert the plain button into a SimpleDropDownButton widget.
+					// Having it be a widget is important because that's how the popup
+					// code knows where a stack of nested popups (typically menus) ends.
+					// (In this case closing a stack of menus shouldn't close the dialog.)
+
+					new SimpleDropDownButton({
+						id: this.id + "PopupButton",
+						label: this.label,
+						popup: this.popup,
+						orient: ["after"]	// so popup doesn't cover OK button
+					}, this.button);
+				},
+
+				onExecute: function(){
+					// summary:
+					//		Called when OK button is pressed.
+					//		If this is used as a popup this signals to the parent that
+					//		Dialog can be closed.
+					console.log(this.id + ": executed");
+				}
+			});
+
+			// Create a button that displays a dialog that displays a choice widget
+			dialogDropDownButton = new SimpleDropDownButton({
+				id: "showSimpleDialogButton",
+				label: "show dialog",
+				popup: new DialogWithPopupWidget({
+					id: "simpleDialog",
+					label: 'show simple choice drop down',
+					popup: new SimpleChoiceWidget({
+						id: "choiceFromDialog"
+					})
+				})
+			}).placeAt(dom.byId("widgets"));
+
+			declare("NestedPopupOpener",  [_WidgetBase, _TemplatedMixin], {
+				// summary:
+				//		Clicking a value in this list will open a nested popup.
+				//		Specify popup1 and popup2 as parameters to this widget.
+
+				templateString:
+					"<div class='choice'>" +
+						"<div data-dojo-attach-event='onclick: onClick'>popup1</div>" +
+						"<div data-dojo-attach-event='onclick: onClick'>popup2</div>" +
+					"</div>",
+
+				onClick: function(e){
+					var id = this.id,
+						popup = this[e.target.innerHTML];
+					log(id + ": opening popup " + popup.id);
+					this.openPopup(popup);
+				},
+
+				openPopup: function(popup){
+					popupUtil.open({
+						popup: popup,
+						parent: this,
+						around: this.domNode,
+						orient: ["after", "before"],
+						onCancel: function(){
+							log(id + ": cancel of child " + popup.id);
+						},
+						onExecute: function(){
+							log(id + ": execute of child " + popup.id);
+							popupUtil.close(popup);
+						}
+					})
+				},
+
+				closePopup: function(popup){
+					popupUtil.close(popup);
+				}
+			});
+
+			// Create a button that displays a nested drop down.
+			nestedOpener = new NestedPopupOpener({
+				id: 'nestedPopupOpener',
+				popup1: (nestedChoice1 = new SimpleChoiceWidget({
+					id: "nestedChoice1"
+				})),
+				popup2: (nestedChoice2 = new SimpleChoiceWidget({
+					id: "nestedChoice2",
+					choice1: "4",
+					choice2: "5",
+					choice3: "6"
+				}))
+			});
+			nestedDropDownButton = new SimpleDropDownButton({
+				id: "showNestedMenuButton",
+				label: "show nested drop down",
+				popup: nestedOpener
+			}).placeAt(dom.byId("widgets"));
+
+			// Create a button that displays a dialog that displays a nested drop down
+			dialogNestedChoice1 = new SimpleChoiceWidget({
+				id: "dialogNestedChoice1"
+			});
+			dialogNestedChoice2 = new SimpleChoiceWidget({
+				id: "dialogNestedChoice2",
+				choice1: "4",
+				choice2: "5",
+				choice3: "6"
+			});
+			dialogNestedPopupOpener = new NestedPopupOpener({
+				id: "nestedPopupOpenerFromDialog",
+				popup1: dialogNestedChoice1,
+				popup2: dialogNestedChoice2
+			});
+			dialogWithNestedPopup = new DialogWithPopupWidget({
+				id: "buttonInComplexDialog",
+				label: 'show nested menu',
+				popup: dialogNestedPopupOpener
+			});
+			dialogDropDownButton = new SimpleDropDownButton({
+				id: "showComplexDialogButton",
+				label: "show dialog w/nested menu",
+				popup: dialogWithNestedPopup
+			}).placeAt(dom.byId("widgets"));
+
+			// For testing, create an unattached widget and unattached DOMNode
+			new SimplePopup({id: "spw"}).placeAt(win.body());
+			domConstruct.place("<span id='sdn'>simple dom node</span>", win.body());
+
+			doh.register("API", [
+					function repeatMoveOffScreen(){
+						// Previously, calling moveOffScreen twice would cause an exception
+						popupUtil.moveOffScreen(registry.byId("spw"));
+						popupUtil.moveOffScreen(registry.byId("spw"));
+					}
+			]);
+
+			doh.register("simple open and close", [
+				function initialConditions(t){
+					// If the popup code has cached any iframes, make sure they are hidden
+					query("iframe").forEach(function(node){
+						console.log("found iframe", node);
+						doh.is("none", node.style.display, "background iframe is hidden");
+					});
+				},
+
+				// Create popup on the edge of another widget
+				function openAround(){
+					var d = new doh.Deferred();
+
+					var around = choiceDropDownButton,
+						popup = choiceDropDown;
+
+					around.openPopup();
+
+					setTimeout(d.getTestCallback(function(){
+						doh.t(isVisible(popup.domNode), "popup is visible");
+
+						if(has("ie") <= 6){
+							// Test the BackgroundIFrame
+							var iframes = query("iframe");
+							doh.is(1, iframes.length, "one background iframe on IE6");
+
+							var popupCoords = domGeometry.position(popup.domNode),
+								iframeCoords = domGeometry.position(iframes[0]);
+							doh.is(popupCoords.x, iframeCoords.x, "x is same: " + popupCoords.x);
+							doh.is(popupCoords.y, iframeCoords.y, "y is same: " + popupCoords.y);
+							doh.is(popupCoords.w, iframeCoords.w, "w is same: " + popupCoords.w);
+							doh.is(popupCoords.h, iframeCoords.h, "h is same: " + popupCoords.h);
+							doh.is("", iframes[0].style.display, "not display:none");
+						}
+						// TODO: test stack
+					}), 500);
+
+					return d;
+				},
+
+				function closeAround(){
+					// Close the popup
+					var around = choiceDropDownButton,
+						popup = choiceDropDown;
+
+					around.closePopup();
+
+					// Make sure the popup is hidden
+					doh.is("none", popup.domNode.parentNode.style.display, "popup is hidden");
+				}
+			]);
+
+			doh.register("nested open and close", [
+				// Open first level
+				function openAround(){
+					var d = new doh.Deferred();
+
+					var around = nestedDropDownButton,
+						popup = nestedOpener,
+						nestedPopup = nestedChoice1;
+
+					around.openPopup();
+
+					setTimeout(d.getTestCallback(function(){
+						doh.t(isVisible(popup.domNode), "popup is visible");
+
+						if(has("ie") <= 6){
+							// Test the BackgroundIFrame
+							var iframes = query("iframe", popup.domNode.parentNode);
+							doh.is(1, iframes.length, "one background iframe on IE6");
+
+							var popupCoords = domGeometry.position(popup.domNode),
+								iframeCoords = domGeometry.position(iframes[0]);
+							doh.is(popupCoords.x, iframeCoords.x, "x is same: " + popupCoords.x);
+							doh.is(popupCoords.y, iframeCoords.y, "y is same: " + popupCoords.y);
+							doh.is(popupCoords.w, iframeCoords.w, "w is same: " + popupCoords.w);
+							doh.is(popupCoords.h, iframeCoords.h, "h is same: " + popupCoords.h);
+							doh.is("", iframes[0].style.display, "not display:none");
+						}
+						// TODO: test stack
+					}), 500);
+
+					return d;
+				},
+
+				function openNested(){
+					var d = new doh.Deferred();
+
+					var around = nestedDropDownButton,
+						popup = nestedOpener,
+						nestedPopup = nestedChoice1;
+
+					popup.openPopup(nestedPopup);
+
+					setTimeout(d.getTestCallback(function(){
+						doh.t(isVisible(nestedPopup.domNode), "nested popup is visible");
+
+						if(has("ie") <= 6){
+							// Test the BackgroundIFrame
+							var iframes = query("iframe", popup.domNode.parentNode);
+							doh.is(1, iframes.length, "one background iframe for popup");
+
+							iframes = query("iframe", nestedPopup.domNode.parentNode);
+							doh.is(1, iframes.length, "another background iframe for nested popup");
+
+							var popupCoords = domGeometry.position(nestedPopup.domNode),
+								iframeCoords = domGeometry.position(iframes[0]);
+							doh.is(popupCoords.x, iframeCoords.x, "x is same: " + popupCoords.x);
+							doh.is(popupCoords.y, iframeCoords.y, "y is same: " + popupCoords.y);
+							doh.is(popupCoords.w, iframeCoords.w, "w is same: " + popupCoords.w);
+							doh.is(popupCoords.h, iframeCoords.h, "h is same: " + popupCoords.h);
+							doh.is("", iframes[0].style.display, "not display:none");
+						}
+						// TODO: test stack
+					}), 500);
+
+					return d;
+				},
+
+				function closeAround(){
+					// Close the layer of popups
+					var around = nestedDropDownButton,
+						popup = nestedOpener,
+						nestedPopup = nestedChoice1;
+
+					around.closePopup();
+
+					// Make sure the popups are both hidden
+					// (in a future release this might change to display:none etc but currently it's visibility:hidden)
+					doh.is("none", popup.domNode.parentNode.style.display, "popup is hidden");
+					doh.is("none", nestedPopup.domNode.parentNode.style.display, "nested popup is hidden");
+				}
+			]);
+
+			// Make sure there are no hidden tab stops when popups are closed.
+			// This test doesn't work on safari (due to safari bugs) although there aren't any hidden tab stops.
+			doh.register("no hidden tab stops", function hiddenTabStops(){
+				var tabbable = tabOrder();
+				doh.is("inputAtStart", tabbable[0].id, "first tabbable node");
+				doh.is("inputAtEnd", tabbable[tabbable.length - 1].id, "last tabbable node");
+			});
+
+			doh.register("x/y placement", function xyPlacement(){
+				// Trivial test of x/y placement.    Could also test other orientations.
+				var popup = new SimpleChoiceWidget();
+
+				popupUtil.open({
+					popup: popup,
+					orient: "R",
+					x: 10,
+					y: 15
+				});
+
+				var popupCoords = domGeometry.position(popup.domNode);
+				doh.is(10, popupCoords.x, "popup x coord");
+				doh.is(15, popupCoords.y, "popup y coord");
+
+				popupUtil.close(popup);
+			});
+
+			doh.register("orientCallback", [
+				function setup(){
+					tooltip = new Tooltip({});
+					(tooltipDropDownButton = new SimpleDropDownButton({
+						id: "tooltipDropDownButton",
+						label: "show tooltip",
+						popup: tooltip
+					})).placeAt(dom.byId("widgets"));
+				},
+				function orientCallbackAround(){
+					// Test whether orient() is called correctly for popup around a node
+					tooltipDropDownButton.openPopup();
+					tooltipDropDownButton.closePopup();
+
+					// The final call to orient(), as well as the call to onOpen(), should have been for the final
+					// position of the node, where corner == TL and aroundCorner == BL
+					doh.t(tooltip.orientCalls.length, "orient was called");
+					var final = tooltip.orientCalls.pop();
+					doh.is("TL", final.corner, "popup corner");
+					doh.is("BL", final.aroundCorner, "aroundNode corner");
+
+					doh.t(tooltip.onOpenArg, "onOpen called");
+					doh.is("TL", tooltip.onOpenArg.corner, "popup corner");
+					doh.is("BL", tooltip.onOpenArg.aroundCorner, "aroundNode corner");
+				},
+				function orientCallbackAt(){
+					// Test whether orient() is called correctly for popup around a point
+					tooltip.orientCalls = [];
+					delete tooltip.onOpenArg;
+
+					popupUtil.open({
+						popup: tooltip,
+						orient: "R",
+						x: 10,
+						y: 15
+					});
+
+					// The final call to orient(), as well as the call to onOpen(), should have been for the final
+					// position of the node, where corner == TL and aroundCorner == BR (they are caddy-corner).
+					doh.t(tooltip.orientCalls.length, "orient was called");
+					var final = tooltip.orientCalls.pop();
+					doh.is("TL", final.corner, "popup corner");
+					doh.is("BR", final.aroundCorner, "aroundNode corner");
+
+					doh.t(tooltip.onOpenArg, "onOpen called");
+					doh.is("TL", tooltip.onOpenArg.corner, "popup corner");
+					doh.is("BR", tooltip.onOpenArg.aroundCorner, "aroundNode corner");
+				}
+			]);
+
+			// Test that onCancel goes back one level.
+			// Call nestedChoice2.onCancel() and that should trigger nestedChoice2 to close
+			// but nestedOpener stays open.
+			// (TODO)
+
+			// Test that onChange/onExecute goes back to top of popup chain.
+			// Call dialogNestedChoice2.onChange() and that should trigger dialogNestedChoice2
+			// and dialogNestedPopupOpener to close, but not dialogWithNestedPopup.
+			// (TODO)
+
+			// ---------------------
+			// a11y tests
+
+			// Test that ESC key closes one level of a popup chain.
+			// Focus nestedChoice2 and type ESC, and that should trigger nestedChoice2 to close
+			// but nestedOpener stays open.
+			// (TODO)
+
+			// Test that TAB key cancels back to top of popup chain.
+			// Focus nestedChoice2 and type TAB, and that should trigger dialogNestedChoice2
+			// and dialogNestedPopupOpener to close, but not dialogWithNestedPopup.
+			// (TODO)
+
+			doh.register("a11y tests", function ariaOnWrapper(){
+				var popup = new SimpleChoiceWidget({id: "scwPopup"});
+
+				popupUtil.open({
+					popup: popup,
+					orient: "R",
+					x: 10,
+					y: 15
+				});
+
+				var w = popup.domNode;
+				doh.is("region", w.parentNode.getAttribute("role"), "popup's wrapper node needs role=region");
+				doh.is("scwPopup", w.parentNode.getAttribute("aria-label"), "popup's wrapper node needs aria-label");
+			});
+
+			doh.register("scrollbar tests", [
+				function scrollbarAt(){
+					var popup = new LotsOfChoicesWidget({id: "tallPopup1"});
+
+					popupUtil.open({
+						popup: popup,
+						orient: "R",
+						x: 10,
+						y: 15
+					});
+
+					var w = popup.domNode;
+					doh.t(domStyle.get(w, "height") > winUtils.getBox().h, "popup is taller than the viewport");
+					doh.t(domStyle.get(w.parentNode, "height") < winUtils.getBox().h, "but wrapper " +
+							domStyle.get(w.parentNode, "height") + " is shorter than viewport " + winUtils.getBox().h);
+				},
+				function scrollbarAround(){
+					tallChoiceDropDownButton.openPopup();
+
+					var w = tallChoiceDropDown.domNode;
+					doh.t(domStyle.get(w, "height") > winUtils.getBox().h, "popup is taller than the viewport");
+					doh.t(domStyle.get(w.parentNode, "height") < winUtils.getBox().h, "but wrapper is shorter than viewport");
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body>
+	<h1>popup and BackgroundIFrame Unit Test</h1>
+	<label for="inputAtStart">label:</label><input id="inputAtStart">
+	<div style="height: 150px; overflow: auto; margin: 10px 0px;">
+		<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis cursus odio eu nisl ultrices dictum. Sed tincidunt metus et magna placerat eget vehicula dolor faucibus. Nunc nec augue ac mi rutrum congue. Donec at augue felis. Proin et lectus at mauris adipiscing pulvinar tempor vitae lacus. Aliquam erat volutpat. Sed eget sem eu turpis ultrices ullamcorper sed ut augue. Nunc in augue lectus. Curabitur ac posuere libero. Duis luctus dignissim nisl suscipit vehicula. Cras ut augue odio [...]
+		<span id="widgets"></span>
+		<p>Nunc sollicitudin nisl sed est porta vitae viverra nulla rutrum. Praesent erat tortor, scelerisque sit amet gravida a, sodales a libero. Pellentesque nec arcu nulla, id laoreet orci. Vivamus sit amet quam eu ante pulvinar rhoncus sit amet non ipsum. Sed mattis felis sed risus tincidunt in sagittis justo rhoncus. Praesent ut justo feugiat neque gravida convallis eget mattis felis. Vestibulum vitae velit ante, sed convallis sem. Curabitur gravida volutpat odio eget tincidunt. Mauris p [...]
+	</div>
+	<label for="inputAtEnd">label:</label><input id="inputAtEnd">
+</body>
+</html>
diff --git a/dijit/tests/registry.html b/dijit/tests/registry.html
new file mode 100644
index 0000000..b30dd42
--- /dev/null
+++ b/dijit/tests/registry.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>dijit/registry unit test</title>
+	<script type="text/javascript" src="../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/_base/array", "dojo/_base/declare", "dojo/dom", "dojo/parser", "dojo/_base/window",
+			"dijit/_WidgetBase", "dijit/registry",
+			"dojo/domReady!"
+		], function(doh, array, declare, dom, parser, win, _WidgetBase, registry){
+
+			declare("foo", _WidgetBase, {
+				name: "",
+				attr1: 0,
+				attr2: 0
+			});
+	
+			declare("bar", _WidgetBase, {
+				name: "",
+				attr1: 0,
+				attr2: 0
+			});
+	
+			declare("Baz", _WidgetBase, {
+				name: "",
+				attr1: 1,
+				attr2: 1
+			});
+
+			doh.register("parse", function(){
+				parser.parse();
+			});
+
+			doh.register("dijit/registry", [
+				function byId(){
+					doh.is(registry.byId("three").name, "your");
+					doh.f(registry.byId("nonexistant"));
+				},
+				function toArray(){
+					var wa = registry.toArray();
+
+					doh.is(4, wa.length, "length");
+
+					var wda = array.map(wa, function(w){
+						return w.domNode;
+					});
+
+					var w = registry.byNode(wda[0]);
+					doh.is(w.declaredClass, "foo");
+				},
+				function getEnclosingWidget(){
+					doh.is(registry.getEnclosingWidget(dom.byId("not-a-widget")), null);
+					doh.is(registry.getEnclosingWidget(dom.byId("three")).name, "your");
+					doh.is(registry.getEnclosingWidget(dom.byId("three.one")).name, "your");
+					doh.is(registry.getEnclosingWidget(dom.byId("three.one.one")).name, "your");
+				},
+				function findWidgets(){
+					doh.is(3, registry.findWidgets(win.body()).length);
+					doh.is(1, registry.findWidgets(dom.byId("threeWrapper")).length);
+				},
+				function destroy(){
+					registry.byId("two").destroy();
+					registry.byId("four").destroy();
+					var names = array.map(registry.toArray(), function(widget){ return widget.name; });
+					doh.is(names.join(" "), "bob your");
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+<body>
+	<h1>Dijit/registry Unit Test</h1>
+	<div id="one" data-dojo-type="foo" data-dojo-props='name:"bob", attr1:10, attr2:10'></div>
+	<div id="two" data-dojo-type="foo" data-dojo-props='name:"is", attr1:5, attr2:10'></div>
+	<div id="threeWrapper">
+		<div id="three" data-dojo-type="bar" data-dojo-props='name:"your", attr1:5, attr2:5'>
+			<div id="three.one">
+				<div id="three.one.one"></div>
+				<div id="four" data-dojo-type="bar" data-dojo-props='name:"uncle", attr1:10, attr2:5'></div>
+			</div>
+		</div>
+	</div>
+	<div id="not-a-widget"></div>
+</body>
+</html>
diff --git a/dijit/tests/resources/TestContextRequireWidget.js b/dijit/tests/resources/TestContextRequireWidget.js
new file mode 100644
index 0000000..223dc13
--- /dev/null
+++ b/dijit/tests/resources/TestContextRequireWidget.js
@@ -0,0 +1,17 @@
+define([
+	"require",
+	"dojo/_base/declare",
+	"dijit/_WidgetBase",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"./TestWidget"
+], function(require, declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin){
+
+	// This module requires utilises a relative MID in the template.  Because of the synchronous nature of the widget
+	// lifecycle, you need to require in any modules in the template into the parent module (as auto-require will not
+	// work) as well as require in the context require and pass it as part of the declare.
+	return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+		templateString: '<div><div data-dojo-type="./TestWidget" data-dojo-attach-point="fooNode"></div></div>',
+		contextRequire: require
+	});
+});
\ No newline at end of file
diff --git a/dijit/tests/resources/TestWidget.js b/dijit/tests/resources/TestWidget.js
new file mode 100644
index 0000000..4873302
--- /dev/null
+++ b/dijit/tests/resources/TestWidget.js
@@ -0,0 +1,10 @@
+define([
+	"dojo/_base/declare",
+	"dijit/_WidgetBase",
+	"dijit/_TemplatedMixin"
+], function(declare, _WidgetBase, _TemplatedMixin){
+	return declare([_WidgetBase, _TemplatedMixin], {
+		templateString: '<div data-dojo-attach-point="fooNode">TestWidget</div>',
+		foo: "bar"
+	});
+});
\ No newline at end of file
diff --git a/dijit/tests/robot/BgIframe.html b/dijit/tests/robot/BgIframe.html
index 105d1d6..24817a2 100644
--- a/dijit/tests/robot/BgIframe.html
+++ b/dijit/tests/robot/BgIframe.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot bgIframe Test</title>
+		<title>robot bgIframe Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,51 +10,59 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
-			
-		<script type="text/javascript" src="../helpers.js"></script>
-			
+
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/_base/array", "dojo/dom", "dojo/on", "dojo/sniff", "dojo/window",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, array, dom, on, has, winUtils, helpers){
+
+				robot.initRobot('../test_bgIframe.html');
+
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+				});
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_bgIframe.html');
-	
-				dojo.forEach(["applet", "xapp"], function(xId){
+				// Test for applets and flash, except on chrome where flash is still problematic
+				array.forEach(has("webkit") ? ["applet"] : ["applet", "xapp"], function(xId){
 					doh.register(xId, [
 					{
 						name: "dialog_" + xId,
 						timeout: 15000,
 						runTest: function(){
-							if(dojo.isWebKit){ return; }  // TODO: Remove skip-test for non-WebKit after #11822 is fixed
 							var d = new doh.Deferred();
 
+							winUtils.scrollIntoView(xId);
+
 							var wasClicked = false;
 							var connection;
 							
-							//Show the dialog
-							doh.robot.mouseMoveAt("showDialog", 500,  1);
-							doh.robot.mouseClick({left:true}, 500);
+							// show the dialog; show it programmatically because we may have just scrolled the "show
+							// dialog" button off the screen)
+							registry.byId("dialog").show();
 							
-							//drag the dialog on top of the applet
-							doh.robot.mouseMoveAt(dijit.byId("dialog").titleNode, 2000,  1);
-							doh.robot.mousePress({left:true}, 500);
-							doh.robot.mouseMoveAt(xId, 500,  1000);
-							doh.robot.mouseRelease({left:true}, 500);
+							// drag the dialog on top of the applet
+							robot.mouseMoveAt(registry.byId("dialog").titleNode, 2000,  1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(xId, 500,  1000);
+							robot.mouseRelease({left: true}, 500);
 							
-							doh.robot.sequence(function(){
-								connection = dojo.connect(dijit.byId("dialog").containerNode, "onclick", function(e){ wasClicked = true; });
+							robot.sequence(function(){
+								connection = on(registry.byId("dialog").containerNode, "click", function(e){ wasClicked = true; });
 							}, 500); 
 							
-							//Click on the dialog
-							doh.robot.mouseMoveAt(dijit.byId("dialog").containerNode, 1, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							// click on the dialog
+							robot.mouseMoveAt(registry.byId("dialog").containerNode, 1, 1);
+							robot.mouseClick({left: true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								dojo.disconnect(connection);
-								//verify the native select did not disappear
-								doh.t(isVisible(dojo.byId("dropDown_" + xId)), "The native select is not visible");
+							robot.sequence(d.getTestCallback(function(){
+								connection.remove();
+								// derify the native select did not disappear
+								doh.t(helpers.isVisible(dom.byId("dropDown_" + xId, robot.doc)), "The native select is not visible");
 								
-								dijit.byId("dialog").hide();
+								registry.byId("dialog").hide();
 								
 								doh.t(wasClicked, "Dialog was not visible because the onclick did not fire.");
 							}), 1000);
@@ -66,22 +74,21 @@
 						name: "tooltip_" + xId,
 						timeout: 8000,
 						runTest: function(){
-							if(!dojo.isIE){ return; }  // TODO: Remove skip-test for non-IE after #11822 is fixed
 							var d = new doh.Deferred();
 
 							var tooltipWasClicked = false;
 							var connection, oldHide;
 							
-							//Show the tooltip
-							doh.robot.mouseMoveAt("two_" + xId, 500, 1);
+							// dhow the tooltip
+							robot.mouseMoveAt("two_" + xId, 500, 1);
 							
-							doh.robot.sequence(function(){ 
-								var tooltip = dijit.byId("dijit__MasterTooltip_0");
+							robot.sequence(function(){ 
+								var tooltip = registry.byId("dijit__MasterTooltip_0");
 								oldHide = tooltip.hide;
 								tooltip.hide = function(aroundNode){
-									//don't allow the tooltip to be hidden							
+									// don't allow the tooltip to be hidden
 								};
-								connection = dojo.connect(tooltip.domNode, "onclick",
+								connection = on(tooltip.domNode, "click",
 									function(e){
 										tooltipWasClicked = true;
 										tooltip.hide = oldHide;
@@ -90,12 +97,12 @@
 								);
 							}, 2000); 
 							
-							//Click on the tooltip
-							doh.robot.mouseMoveAt("dijit__MasterTooltip_0", 1, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							// Click on the tooltip
+							robot.mouseMoveAt("dijit__MasterTooltip_0", 1, 1);
+							robot.mouseClick({left: true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								dojo.disconnect(connection);
+							robot.sequence(d.getTestCallback(function(){
+								connection.remove();
 								doh.t(tooltipWasClicked, "The tooltip is not visible because the onclick event was not fired.");
 							}), 1000);
 
@@ -106,26 +113,51 @@
 						name: "dateTextBox_" + xId,
 						timeout: 7000,
 						runTest: function(){
-							if(!dojo.isIE){ return; }  // TODO: Remove skip-test for non-IE after #11822 is fixed
 							var d = new doh.Deferred();
 
 							var wasClicked = false;
 							var connection;
 							
-							//Show the popup
-							doh.robot.mouseMoveAt("dateText_" + xId, 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
+							// Show the popup
+							var textbox = registry.byId("dateText_" + xId);
+							robot.mouseMoveAt(textbox._buttonNode, 500, 1);
+							robot.mouseClick({left: true}, 500);
 							
-							doh.robot.sequence(function(){
-								connection = dojo.connect(dijit.byId("dateText_"+xId+"_popup").domNode, "onclick", function(e){ wasClicked = true; });
+							robot.sequence(function(){
+								connection = on(registry.byId("dateText_"+xId+"_popup").domNode, "click", function(e){ wasClicked = true; });
 							}, 2000); 
 							
-							//Click on the popup
-							doh.robot.mouseMoveAt("dateText_"+xId+"_popup", 1, 1, 10, 10);
-							doh.robot.mouseClick({left:true}, 500);
+							// Click on the popup
+							robot.mouseMoveAt("dateText_"+xId+"_popup", 1, 1, 10, 10);
+							robot.mouseClick({left: true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(function(){
-								dojo.disconnect(connection);
+							robot.sequence(d.getTestCallback(function(){
+								connection.remove();
+								doh.t(wasClicked);
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "menu_" + xId,
+						timeout: 7000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var wasClicked = false;
+							registry.byId("copy_"+xId).onClick = function(e){ wasClicked = true; };
+
+							// Show the popup
+							var button = registry.byId("menuButton_" + xId);
+							robot.mouseMoveAt(button.domNode, 500, 1);
+							robot.mouseClick({left: true}, 500);
+
+							// Click on the popup
+							robot.mouseMoveAt("copy_"+xId);
+							robot.mouseClick({left: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
 								doh.t(wasClicked);
 							}), 1000);
 
@@ -134,6 +166,7 @@
 					}
 					]);
 				});
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/robot/Calendar_a11y.html b/dijit/tests/robot/Calendar_a11y.html
index 15e9a61..370b52f 100644
--- a/dijit/tests/robot/Calendar_a11y.html
+++ b/dijit/tests/robot/Calendar_a11y.html
@@ -10,124 +10,144 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.require("dijit.robotx");
-			dojo.require("dojo.date");
-			dojo.require("dojo.date.locale");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Calendar.html');
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/_base/array", "dojo/date", "dojo/date/locale", "dojo/dom", "dojo/keys", "dojo/_base/lang",
+				"dojo/query", "dojo/sniff",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, array, date, datelocale, dom, keys, lang, query, has, helpers){
+
+				robot.initRobot('../test_Calendar.html');
+
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+					dfocus = robot.window.require("dijit/focus");
+				});
 
-				// refs to Calendar widget
-				var cal1;
+				// refs to Calendar widgets
+				var cal1, cal5;
 
 				// log of calls to onChange handler
 				var changes = [];
 
-				doh.register("API",[
+				doh.register("API", [
 					function noValue(){
 						// refs to Calendar widget
-						cal1 = dijit.byId('calendar1');
+						cal1 = registry.byId('calendar1');
 
 						// Although Calendar and DateTextBox prototypes defined value as Date("")
 						// (so that the parser knows value is a Date rather than a string),
 						// the convention is to use null to represent a blank DateTextBox or Calendar w/no selection
-						doh.is(null, dijit.byId("calendar1").get("value"), 'initial get("value"), no selection');
+						doh.is(null, registry.byId("calendar1").get("value"), 'initial get("value"), no selection');
 
 						cal1.set("value", new Date(2009, 8, 16));
-						doh.is(0, dojo.date.compare(new Date(2009, 8, 16), cal1.get('value')), 'get("value") after set');
+						doh.is(0, date.compare(new Date(2009, 8, 16), cal1.get('value')), 'get("value") after set');
 
 						cal1.set("value", null);
 						doh.is(null, cal1.get("value"), 'get("value") after set to null');
+					},
+
+					function initialValue(){
+						cal5 = registry.byId("calendar5");
+
+						var selectedDate = query(".dijitCalendarSelectedDate", cal5.domNode);
+						doh.is(1, selectedDate.length, "date is selected");
+						doh.is("14", helpers.innerText(selectedDate[0]), "selected date");
+
+						var selectedMonth = query(".dijitCalendarCurrentMonthLabel", cal5.domNode);
+						doh.is(1, selectedMonth.length, "month is selected");
+						doh.is("March", helpers.innerText(selectedMonth[0]), "selected month");
+
+						var selectedYear = query(".dijitCalendarSelectedYear", cal5.domNode);
+						doh.is(1, selectedYear.length, "year is selected");
+						doh.is("2008", helpers.innerText(selectedYear[0]), "selected year");
 					}
 				]);
 				
 				// Test aria roles, etc.
 				doh.register("aria", function(){
-					//test all days are loaded correctly
-					var dateCells = dijit.byId("calendar1").dateCells;
-					dojo.forEach(dateCells, function(cellNode){
+					// test all days are loaded correctly
+					var dateCells = registry.byId("calendar1").dateCells;
+					array.forEach(dateCells, function(cellNode){
 						doh.is("false", cellNode.getAttribute("aria-selected"), "aria-selected should be false at startup");
 						doh.is(undefined, cellNode.getAttribute("aria-disabled should be undefined at startup"), "aria-disabled");
 					});
 										
-					//disable weekends
-					dijit.registry.forEach(function(c){
+					// disable weekends
+					array.forEach(registry.toArray(), function(c){
 						if(c.isDisabledDate){
-							c.isDisabledDate = dojo.date.locale.isWeekend;
+							c.isDisabledDate = datelocale.isWeekend;
 							c._populateGrid();
 						}
 					});
 					
-					//select a day
-					dijit.byId("calendar1").set("value",  new Date(2009, 8, 15));
+					// select a day
+					registry.byId("calendar1").set("value",  new Date(2009, 8, 15));
 					
-					dojo.forEach(dateCells, function(cellNode, index){
+					array.forEach(dateCells, function(cellNode, index){
 						var selected = cellNode.getAttribute("aria-selected");
 						var disabled = cellNode.getAttribute("aria-disabled");
-						innerText(cellNode)==="15" ? doh.is("true", selected, "aria-selected should be true: "+innerText(cellNode))
-											       : doh.is("false", selected, "aria-selected should still be true: "+innerText(cellNode));
+						helpers.innerText(cellNode)==="15" ? doh.is("true", selected, "aria-selected should be true: "+helpers.innerText(cellNode))
+											       : doh.is("false", selected, "aria-selected should still be true: "+helpers.innerText(cellNode));
 						(index%7==0) || (index%7==6) ? doh.is("true", disabled, "aria-disabled should be true for weekends: "+index)
 													 : doh.t((disabled==undefined || disabled=="" || disabled=="false"), "aria-disabled should still be undefined, 'false', or ''. Index was: "+index+" Value was: "+disabled);
 					});
 					
-					//enable all again
-					dijit.registry.forEach(function(c){
+					// enable all again
+					array.forEach(registry.toArray(), function(c){
 						if(c.isDisabledDate){
 							c.isDisabledDate = function(){return false;};
 							c._populateGrid();
 						}
 					});
 					
-					//select a different day
-					dijit.byId("calendar1").set("value",  new Date(2009, 8, 17));
+					// select a different day
+					registry.byId("calendar1").set("value",  new Date(2009, 8, 17));
 					
-					dojo.forEach(dateCells, function(cellNode, index){
+					array.forEach(dateCells, function(cellNode, index){
 						var selected = cellNode.getAttribute("aria-selected");
 						var disabled = cellNode.getAttribute("aria-disabled");
-						innerText(cellNode)==="17" ? doh.is("true", selected, "aria-selected should be true for day 17: "+innerText(cellNode))
-											       : doh.is("false", selected, "aria-selected should be false again: "+innerText(cellNode));
+						helpers.innerText(cellNode)==="17" ? doh.is("true", selected, "aria-selected should be true for day 17: "+helpers.innerText(cellNode))
+											       : doh.is("false", selected, "aria-selected should be false again: "+helpers.innerText(cellNode));
 						doh.t((disabled==undefined || disabled=="" || disabled=="false"), "aria-disabled should be undefined, 'false', or '' again");
 					});
 					
 				});
 
 				// Tabindex test makes sure that there's exactly one tab stop on the calendar at all times
-				doh.register("tabindex",[
+				doh.register("tabindex", [
 					{
 						name: "forward",
 						timeout: 10000,
 						setUp: function(){
 							cal1.set("value", new Date(2009, 8, 16));
 
-							dojo.byId("before").focus();
+							dom.byId("before").focus();
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							// Tab in
-							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is(16, innerText(dojo.global.dijit.focus.curNode), "first tab goes to selected day");
+							robot.keyPress(keys.TAB, 1000, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is(16, helpers.innerText(dfocus.curNode), "first tab goes to selected day");
 							})), 500);
 
 							// Move around some
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 0, {});
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is(24, innerText(dojo.global.dijit.focus.curNode), "move around some");
+							robot.keyPress(keys.RIGHT_ARROW, 0, {});
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is(24, helpers.innerText(dfocus.curNode), "move around some");
 							})), 500);
 
 							// Tab out
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is("after", dojo.global.dijit.focus.curNode.id, "next tab leaves calendar");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								doh.is("after", dfocus.curNode.id, "next tab leaves calendar");
 							})), 500);
 
 							return d;
@@ -140,15 +160,15 @@
 							var d = new doh.Deferred();
 
 							// shift-tab back into calendar, should go to previously focused day
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is(24, innerText(dojo.global.dijit.focus.curNode), "shift-tab returns to previously focused day");
+							robot.keyPress(keys.TAB, 500, {shift: true});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is(24, helpers.innerText(dfocus.curNode), "shift-tab returns to previously focused day");
 							})), 500);
 
 							// shift-tab out
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is("before", dojo.global.dijit.focus.curNode.id, "next shift-tab leaves calendar");
+							robot.keyPress(keys.TAB, 500, {shift: true});
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								doh.is("before", dfocus.curNode.id, "next shift-tab leaves calendar");
 							})), 500);
 
 							return d;
@@ -161,21 +181,21 @@
 							var d = new doh.Deferred();
 
 							// Tab in
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is(24, innerText(dojo.global.dijit.focus.curNode), "first tab goes to selected day");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is(24, helpers.innerText(dfocus.curNode), "first tab goes to selected day");
 							})), 500);
 
 							// Move to next month
-							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 0, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is(24, innerText(dojo.global.dijit.focus.curNode), "moved to same day, but new month");
+							robot.keyPress(keys.PAGE_DOWN, 0, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is(24, helpers.innerText(dfocus.curNode), "moved to same day, but new month");
 							})), 500);
 
 							// Tab out
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is("after", dojo.global.dijit.focus.curNode.id, "next tab leaves calendar");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								doh.is("after", dfocus.curNode.id, "next tab leaves calendar");
 							})), 500);
 
 							return d;
@@ -188,15 +208,15 @@
 							var d = new doh.Deferred();
 
 							// shift-tab back into calendar, should go to previously focused day
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is(24, innerText(dojo.global.dijit.focus.curNode), "shift-tab returns to previously focused day");
+							robot.keyPress(keys.TAB, 500, {shift: true});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is(24, helpers.innerText(dfocus.curNode), "shift-tab returns to previously focused day");
 							})), 500);
 
 							// shift-tab out
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is("before", dojo.global.dijit.focus.curNode.id, "next shift-tab leaves calendar");
+							robot.keyPress(keys.TAB, 500, {shift: true});
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								doh.is("before", dfocus.curNode.id, "next shift-tab leaves calendar");
 							})), 500);
 
 							return d;
@@ -205,17 +225,17 @@
 				]);
 
 				// Make sure that all the navigation and selection keystrokes work
-				doh.register("navigation",[
+				doh.register("navigation", [
 					{
 						name: "arrow navigation",
 						timeout: 10000,
 						setUp: function(){
 							// refs to Calendar widget
-						    	cal1 = dijit.byId('calendar1');
+						    	cal1 = registry.byId('calendar1');
 							cal1.set("value", new Date(2009, 8, 16));
 
 					    	// setup onChange handler to monitor onChange calls on cal1
-							dojo.connect(cal1, 'onChange', function(val){
+							cal1.on("change", function(val){
 								console.log('onchange w/value: ', val);
 								changes.push(val);
 							});
@@ -223,66 +243,66 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								// monitor onchange events
 								changes = [];
 								cal1.focus();
 							}, 500);
 
 							// Initial conditions
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
 								// 16th is selected
-								var selected = dojo.query(".dijitCalendarSelectedDate", cal1.domNode);
+								var selected = query(".dijitCalendarSelectedDate", cal1.domNode);
 								doh.is(1, selected.length, "one selected node");
-								doh.is("16", innerText(selected[0]));
+								doh.is("16", helpers.innerText(selected[0]));
 
 								// initial focus is on selected value
-								doh.is("16", innerText(dojo.global.dijit.focus.curNode));
+								doh.is("16", helpers.innerText(dfocus.curNode));
 
 								// and get("value") working
-								doh.is(0, dojo.date.compare(new Date(2009, 8, 16), cal1.get('value')), 'get("value")');
+								doh.is(0, date.compare(new Date(2009, 8, 16), cal1.get('value')), 'get("value")');
 							})), 1000);
 
 							// Mouse moves around focus without changing value
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
 								// focus moved from 16 to 17
-								doh.is(17, innerText(dojo.global.dijit.focus.curNode));
+								doh.is(17, helpers.innerText(dfocus.curNode));
 
-								doh.is(0, dojo.date.compare(new Date(2009, 8, 16), cal1.get('value')), 'value unchanged');
+								doh.is(0, date.compare(new Date(2009, 8, 16), cal1.get('value')), 'value unchanged');
 								
 								// 16th is still selected
-								var selected = dojo.query(".dijitCalendarSelectedDate", cal1.domNode);
+								var selected = query(".dijitCalendarSelectedDate", cal1.domNode);
 								doh.is(1, selected.length, "one selected node");
-								doh.is("16", innerText(selected[0]));								
+								doh.is("16", helpers.innerText(selected[0]));
 							})), 500);
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 0, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is(18, innerText(dojo.global.dijit.focus.curNode));
+							robot.keyPress(keys.RIGHT_ARROW, 0, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is(18, helpers.innerText(dfocus.curNode));
 							})), 500);
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 0, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is(25, innerText(dojo.global.dijit.focus.curNode));
+							robot.keyPress(keys.DOWN_ARROW, 0, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is(25, helpers.innerText(dfocus.curNode));
 							})), 500);
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 0, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is(24, innerText(dojo.global.dijit.focus.curNode));
+							robot.keyPress(keys.LEFT_ARROW, 0, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is(24, helpers.innerText(dfocus.curNode));
 							})), 500);
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 0, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is(17, innerText(dojo.global.dijit.focus.curNode));
+							robot.keyPress(keys.UP_ARROW, 0, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is(17, helpers.innerText(dfocus.curNode));
 							})), 500);
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 0, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is(10, innerText(dojo.global.dijit.focus.curNode));
+							robot.keyPress(keys.UP_ARROW, 0, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is(10, helpers.innerText(dfocus.curNode));
 							})), 500);
-							doh.robot.keyPress(dojo.keys.ENTER, 0, {});
+							robot.keyPress(keys.ENTER, 0, {});
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
 								var value = cal1.get('value');
-								doh.is(0, dojo.date.compare(new Date(2009, 8, 10), value), 'actual value is ' + value);
+								doh.is(0, date.compare(new Date(2009, 8, 10), value), 'actual value is ' + value);
 								doh.is(1, changes.length, 'onchange events');
-								doh.is(0, dojo.date.compare(new Date(2009, 8, 10), changes[0]),
+								doh.is(0, date.compare(new Date(2009, 8, 10), changes[0]),
 										'value reported by onchange: ' + changes[0] +
 										', should be ' + new Date(2009, 8, 10));
 							})), 1000);
@@ -294,49 +314,49 @@
 						timeout: 5000,
 						setUp: function(){
 							// refs to Calendar widget
-					   	 	cal1 = dijit.byId('calendar1');
+					   	 	cal1 = registry.byId('calendar1');
 							cal1.set("value", new Date(2008, 0, 31));
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								cal1.focus();
 							}, 500);
 
-							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 1000, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+							robot.keyPress(keys.PAGE_DOWN, 1000, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
 								// focus moved from jan 31 to feb 29
-								doh.is(29, innerText(dojo.global.dijit.focus.curNode));
+								doh.is(29, helpers.innerText(dfocus.curNode));
 
-								doh.is(0, dojo.date.compare(new Date(2008, 0, 31), cal1.get('value')), 'value unchanged (first page down)');
+								doh.is(0, date.compare(new Date(2008, 0, 31), cal1.get('value')), 'value unchanged (first page down)');
 
 								// month label should have changed
-								var monthLabel = dojo.query(".dijitCalendarCurrentMonthLabel", cal1.domNode);
+								var monthLabel = query(".dijitCalendarCurrentMonthLabel", cal1.domNode);
 								doh.is(1, monthLabel.length, "one month label");
-								doh.is("February", innerText(monthLabel[0]));
+								doh.is("February", helpers.innerText(monthLabel[0]));
 
 								// jan 31 from previous month still visible, should be shown as selected
-								var selected = dojo.query(".dijitCalendarSelectedDate", cal1.domNode);
+								var selected = query(".dijitCalendarSelectedDate", cal1.domNode);
 								doh.is(1, selected.length, "no selected node");
 							})), 500);
 
-							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+							robot.keyPress(keys.PAGE_DOWN, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
 								// focus moved from jan 31 to feb 29
-								doh.is(29, innerText(dojo.global.dijit.focus.curNode));
+								doh.is(29, helpers.innerText(dfocus.curNode));
 
-								doh.is(0, dojo.date.compare(new Date(2008, 0, 31), cal1.get('value')), 'value unchanged (second page down)');
+								doh.is(0, date.compare(new Date(2008, 0, 31), cal1.get('value')), 'value unchanged (second page down)');
 								
 								// since january no longer visible, no selected date should be visible
-								var selected = dojo.query(".dijitCalendarSelectedDate", cal1.domNode);
+								var selected = query(".dijitCalendarSelectedDate", cal1.domNode);
 								doh.is(0, selected.length, "no selected node");
 							})), 500);
 
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							robot.keyPress(keys.SPACE, 500, {});
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
 								var value = cal1.get('value');
-								doh.is(0, dojo.date.compare(new Date(2008, 2, 29), value), 'actual value is ' + value);
+								doh.is(0, date.compare(new Date(2008, 2, 29), value), 'actual value is ' + value);
 							})), 1000);
 
 							return d;
@@ -347,27 +367,27 @@
 						timeout: 5000,
 						setUp: function(){
 							// refs to Calendar widget
-						    	cal1 = dijit.byId('calendar1');
+						    	cal1 = registry.byId('calendar1');
 							cal1.set("value", new Date(2008, 1, 15));
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								cal1.focus();
 							}, 500);
 
-							doh.robot.keyPress(dojo.keys.END, 1000, {});
+							robot.keyPress(keys.END, 1000, {});
 							// Chrome switches tabs with ctrl+page up/down (not even a keydown is generated), yet not Safari.
 							// I don't see a way to do feature-detection since browser window focus is lost.
-							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 500, dojo.isChrome ? {alt:true} : {ctrl:true});
-							doh.robot.keyPress(dojo.keys.PAGE_UP, 500, dojo.isChrome ? {alt:true} : {ctrl:true});
-							doh.robot.keyPress(dojo.keys.PAGE_UP, 500, dojo.isChrome ? {alt:true} : {ctrl:true});
-							doh.robot.keyPress(dojo.keys.ENTER, 500);
+							robot.keyPress(keys.PAGE_DOWN, 500, has("chrome") ? {alt:true} : {ctrl:true});
+							robot.keyPress(keys.PAGE_UP, 500, has("chrome") ? {alt:true} : {ctrl:true});
+							robot.keyPress(keys.PAGE_UP, 500, has("chrome") ? {alt:true} : {ctrl:true});
+							robot.keyPress(keys.ENTER, 500);
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
 								var value = cal1.get('value');
-								doh.is(0, dojo.date.compare(new Date(2007, 1, 28), value), 'actual value is ' + value);
+								doh.is(0, date.compare(new Date(2007, 1, 28), value), 'actual value is ' + value);
 							})), 1000);
 
 							return d;
diff --git a/dijit/tests/robot/ColorPalette.html b/dijit/tests/robot/ColorPalette.html
index 465892e..f256f2f 100644
--- a/dijit/tests/robot/ColorPalette.html
+++ b/dijit/tests/robot/ColorPalette.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot ColorPalette Test</title>
+		<title>robot ColorPalette Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,41 +10,66 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom", "dojo/dom-class", "dojo/keys", "dojo/_base/lang", "dojo/query", "dojo/sniff",
+				"dojo/domReady!"
+			], function(doh, robot, dom, domClass, keys, lang, query, has){
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_ColorPalette.html');
+				robot.initRobot('../test_ColorPalette.html');
 
 				var big, small, prog;
 
 				// log of calls to onChange handler
 				var changes = [];
 
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+					dfocus = robot.window.require("dijit/focus");
+
+					// refs to ColorPalette widgets
+					big = registry.byId("big");
+					small = registry.byId("small");
+					prog = registry.byId("prog");
+
+					// setup onChange handler to monitor onChange calls
+					big.on("change", function(val){
+						console.log('onchange w/value: ', val);
+						changes.push(val);
+					});
+				});
+
 				doh.register("dijit.ColorPalette tests", [
 					{
 						name: "initial conditions",
-						setUp: function(){
-
-							// refs to ColorPalette widgets
-					    	big = dijit.byId("big");
-					    	small = dijit.byId("small");
-					    	prog = dijit.byId("prog");
-
-					    	// setup onChange handler to monitor onChange calls
-							dojo.connect(big, 'onChange', function(val){
-								console.log('onchange w/value: ', val);
-								changes.push(val);
-							});
-						},
 						runTest: function(){
 							doh.f(big.get('value'), "no value for big");
 							doh.f(small.get('value'), "no value for small");
 							doh.f(prog.get('value'), "no value for prog");
 						}
 					},
+					{
+						name: "accessibility roles and attributes",
+						runTest: function(){
+							doh.is(big.domNode.getAttribute("role"), "grid", "domNode role is grid");
+
+							var result = big.domNode.getAttribute("aria-label");
+							doh.t(!!result, "aria-label for big");
+
+							var table = query("table", big.domNode)[0];
+							doh.is(table.getAttribute("role"), "presentation", "table should be presentation");
+
+							var row = query("tr", table)[0];
+							doh.is(row.getAttribute("role"), "row", "tr should be role=row since domNode role=grid");
+
+							var td = query("td", row)[0];
+							doh.is(td.getAttribute("role"), "gridcell", "td role should be gridcell");
+						}
+					},
 					
 					// TODO: when attr() is implemented as a setter, add tests like big.set("value", "#ffc0cb")
 
@@ -56,16 +81,16 @@
 
 							big.focus();
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is(0, changes.length, "no onchange events yet");
 								
 								// test that focus is on top left cell
-								var focus = dojo.global.dijit.focus.curNode;
+								var focus = dfocus.curNode;
 								doh.t(focus, "something is focused");
 								var imgNode = focus.getElementsByTagName("img")[0];
 								doh.t(imgNode, "found image node");
-                                //
-                                var dye = big._getDye(focus);                                
+
+								var dye = big._getDye(focus);
 								doh.is("#ffffff", dye.getValue(), "focused on white");
 							}), 500);
 							
@@ -81,26 +106,26 @@
 								enterPressed = false;
 
 							// Move around some
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.keyPress(keys.LEFT_ARROW, 500, {});
 							
 							// Focus should follow the current position for the benefit of screen readers.
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								var focus = dojo.global.dijit.focus.curNode;
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								var focus = dfocus.curNode;
 								doh.t(focus, "something is focused");
 								
 								var imgNode = focus.getElementsByTagName("img")[0];
 								doh.t(imgNode, "found image node");
-                                //
-                                var dye = big._getDye(focus);
+
+								var dye = big._getDye(focus);
 								doh.is("#ffc0cb", dye.getValue(), "focused on right color");
 							})), 1000);
 
 							// Setup handler to catch onChange event from ENTER keypress below
-							handle = dojo.connect(big, "onChange", d.getTestCallback(dojo.hitch(this, function(val){
-								dojo.disconnect(handle);
+							handle = big.on("change", d.getTestCallback(lang.hitch(this, function(val){
+								handle.remove();
 								handle = null;
 
 								doh.is("#ffc0cb", val, "onChange() argument");
@@ -114,16 +139,16 @@
 							})));
 
 							// Select the current value
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								enterPressed = true;
 							}, 0);
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
 
 							return d;
 						},
 						tearDown: function(){
 							if(handle){
-								dojo.disconnect(handle);
+								handle.remove();
 							}
 						}
 					},
@@ -136,25 +161,25 @@
 							// tab stop associated w/the color picker
 							var d = new doh.Deferred();
 
-							dojo.byId("beforeBig").focus();
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("pink", dojo.global.dijit.focus.curNode.title, "tab into colorpalette, focus goes to pink (last focused cell)")
+							dom.byId("beforeBig").focus();
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(function(){
+								doh.is("pink", dfocus.curNode.title, "tab into colorpalette, focus goes to pink (last focused cell)")
 							}), 1000);
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("afterBig", dojo.global.dijit.focus.curNode.id, "another tab, went to input after ColorPalette")
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(function(){
+								doh.is("afterBig", dfocus.curNode.id, "another tab, went to input after ColorPalette")
 							}), 1000);
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("pink", dojo.global.dijit.focus.curNode.title, "shift-tab back into colorpalette")
+							robot.keyPress(keys.TAB, 500, {shift: true});
+							robot.sequence(d.getTestErrback(function(){
+								doh.is("pink", dfocus.curNode.title, "shift-tab back into colorpalette")
 							}), 1000);
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("beforeBig", dojo.global.dijit.focus.curNode.id, "another shift-tab, to input before ColorPalette")
+							robot.keyPress(keys.TAB, 500, {shift: true});
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("beforeBig", dfocus.curNode.id, "another shift-tab, to input before ColorPalette")
 							}), 1000);
 
 							return d;
@@ -167,15 +192,15 @@
 							var d = new doh.Deferred();
 
 							// go to small colorpalette
-							dojo.byId("beforeSmall").focus();
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							dom.byId("beforeSmall").focus();
+							robot.keyPress(keys.TAB, 500, {});
 
 							// select a value
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.SPACE, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								var value = small.get('value');
 								doh.is("#ffff00", value);
 							}), 1000);
@@ -191,43 +216,49 @@
 							var d = new doh.Deferred();
 
 							// Testing nls too...
-							var red = dojo.query("[title=rojo]", small.domNode);
+							var red = query("td[title=rojo]", small.domNode);
 							doh.is(1, red.length, "found rojo (red)");
 
-							doh.robot.mouseMoveAt(red[0], 500);
-							doh.robot.mouseClick({left: true}, 500);
-							if(dojo.isMoz){
+							robot.mouseMoveAt(red[0], 500);
+							robot.mouseClick({left: true}, 500);
+							if(has("mozilla")){
 								// workaround robot bug where first mouse click doesn't happen occasionally :-(
-								doh.robot.mouseClick({left: true}, 500);
+								robot.mouseClick({left: true}, 500);
 							}
 							
-							var green = dojo.query("[title=verde]", small.domNode);
+							var green = query("td[title=verde]", small.domNode);
 							doh.is(1, green.length, "found verde (green)");
 
-							doh.robot.mouseMoveAt(green[0], 500);
-							doh.robot.mouseClick({left: true}, 500);
-							if(dojo.isMoz){
+							// Make sure <img> alt and title are translated.  Not sure why they are being set at all though.
+							var greenImg = query("img", green[0]);
+							doh.is(1, greenImg.length, "found <img> inside of <td>");
+							doh.is("verde", greenImg[0].getAttribute("alt"), "img.alt");
+							doh.is("verde", greenImg[0].getAttribute("title"), "img.title");
+
+							robot.mouseMoveAt(green[0], 500);
+							robot.mouseClick({left: true}, 500);
+							if(has("mozilla")){
 								// workaround robot bug where first mouse click doesn't happen occasionally :-(
-								doh.robot.mouseClick({left: true}, 500);
+								robot.mouseClick({left: true}, 500);
 							}
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// test that value set
 								var value = small.get('value');
 								doh.is("#008000", value, "value");
 								
 								// test that focus also got set
-								var focus = dojo.global.dijit.focus.curNode;
+								var focus = dfocus.curNode;
 								doh.t(focus, "something is focused");
 								var imgNode = focus.getElementsByTagName("img")[0];
 								doh.t(imgNode, "found image node");
 								var dye = small._getDye(focus);
 								doh.is("#008000", dye.getValue(), "focused");
 								
-								//test that selected style was removed from previously selected cell and added to new selection
-								doh.f(dojo.hasClass(red[0], "dijitPaletteCellSelected"),
+								// test that selected style was removed from previously selected cell and added to new selection
+								doh.f(domClass.contains(red[0], "dijitPaletteCellSelected"),
 									"Red swatch should not have selected class, actual class is: " + red[0].className);
-								doh.t(dojo.hasClass(green[0], "dijitPaletteCellSelected"),
+								doh.t(domClass.contains(green[0], "dijitPaletteCellSelected"),
 									"Green swatch should have selected class, actual class is: " + green[0].className);
 							}), 1000);
 							
@@ -236,9 +267,9 @@
 						}
 					},
 					function valuePreselected(){
-						var cp = dijit.byId("valuePreselected");
+						var cp = registry.byId("valuePreselected");
 						doh.is("#0000ff", cp.get("value"), "get('value')");
-						doh.is("blue", dojo.query(".dijitPaletteCellSelected img", cp.domNode)[0].alt, "marked");
+						doh.is("blue", query(".dijitPaletteCellSelected img", cp.domNode)[0].alt, "marked");
 					}
 				]);
 
diff --git a/dijit/tests/robot/Dialog_a11y.html b/dijit/tests/robot/Dialog_a11y.html
index 3774837..1e85069 100644
--- a/dijit/tests/robot/Dialog_a11y.html
+++ b/dijit/tests/robot/Dialog_a11y.html
@@ -2,26 +2,34 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Dialog A11Y Test</title>
+		<title>robot Dialog A11Y Test</title>
 
 		<style>
+		<style>
 			@import "../../../util/doh/robot/robot.css";
 		</style>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Dialog.html');
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/aspect", "dojo/dom", "dojo/dom-class", "dojo/dom-style", "dojo/keys",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, aspect, dom, domClass, domStyle, keys, helpers){
+
+				robot.initRobot('../test_Dialog.html');
+
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+					dfocus = robot.window.require("dijit/focus");
+					DialogUnderlay = robot.window.require("dijit/DialogUnderlay");
+				});
 
-				doh.register("keyboard tests (cancel)",[
+				doh.register("keyboard tests (cancel)", [
 					{
 						name: "open dialog",
 						timeout: 10000,
@@ -31,13 +39,13 @@
 							// Click the button.  We do this manually rather than calling Dialog.show()
 							// so we can later test that focus is restored (to the previous position)
 							// when the dialog is closed
-							dojo.byId("dialog1button").focus();
-							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
-							doh.robot.typeKeys("Bill", 1000, 800);
+							dom.byId("dialog1button").focus();
+							robot.keyPress(keys.SPACE, 1000, {});
+							robot.typeKeys("Bill", 1000, 800);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("dialog1"), "dialog 1 has been made visible");
-								doh.is("name", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("dialog1"), "dialog 1 has been made visible");
+								doh.is("name", dfocus.curNode.id, "focus is on the first field");
 							}), 500);
 
 							return d;
@@ -50,12 +58,12 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.typeKeys("Japan", 1000, 1000);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.typeKeys("Japan", 1000, 1000);
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("date", dojo.global.dijit.focus.curNode.id, "focus is on the date field");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("date", dfocus.curNode.id, "focus is on the date field");
 							}), 1000);
 
 							return d;
@@ -68,12 +76,12 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.keyPress(keys.ESCAPE, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("date", dojo.global.dijit.focus.curNode.id, "focus is still on the date field");
-								doh.t(isVisible("dialog1"), "dialog 1 wasn't closed");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("date", dfocus.curNode.id, "focus is still on the date field");
+								doh.t(helpers.isVisible("dialog1"), "dialog 1 wasn't closed");
 							}), 1000);
 
 							return d;
@@ -86,13 +94,13 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("name", dojo.global.dijit.focus.curNode.id, "focus looped back to name field");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("name", dfocus.curNode.id, "focus looped back to name field");
 							}), 1000);
 
 							return d;
@@ -105,10 +113,10 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
+							robot.keyPress(keys.TAB, 500, {shift: true});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("ok", dojo.global.dijit.focus.curNode.id, "focus looped back to submit button");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("ok", dfocus.curNode.id, "focus looped back to submit button");
 							}), 1000);
 
 							return d;
@@ -121,11 +129,11 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
+							robot.keyPress(keys.ESCAPE, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("dialog1"), "dialog 1 was closed");
-								doh.is("dialog1button", dojo.global.dijit.focus.curNode.id, "focus returned to button");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("dialog1"), "dialog 1 was closed");
+								doh.is("dialog1button", dfocus.curNode.id, "focus returned to button");
 							}), 1000);
 
 							return d;
@@ -133,40 +141,40 @@
 					}
 				]);
 
-				doh.register("keyboard tests (submit)",[
+				doh.register("keyboard tests (submit)", [
 					{
 						name: "submit some data",
 						timeout: 15000,
 						setUp: function(){
-							dijit.byId("dialog1").reset();
+							registry.byId("dialog1").reset();
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							// Setup handler to catch submitted data
 							var data;
-							dojo.connect(dijit.byId("dialog1"), "execute", function(vals){
+							aspect.after(registry.byId("dialog1"), "execute", function(vals){
 								data = vals;
-							});
+							}, true);
 
 							// Open the dialog
-							dojo.byId("dialog1button").focus();
-							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
+							dom.byId("dialog1button").focus();
+							robot.keyPress(keys.SPACE, 1000, {});
 
 							// Enter some info
-							doh.robot.typeKeys("Ted", 2000, 600);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.typeKeys("America", 1000, 1400);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
-							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
-							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
+							robot.typeKeys("Ted", 2000, 600);
+							robot.keyPress(keys.TAB, 500, {});
+							robot.typeKeys("America", 1000, 1400);
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 1000, {});
+							robot.keyPress(keys.TAB, 1000, {});
+							robot.keyPress(keys.TAB, 1000, {});
 
 							// Submit
-							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
+							robot.keyPress(keys.SPACE, 1000, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("dialog1"), "dialog 1 was closed on submit");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("dialog1"), "dialog 1 was closed on submit");
 								doh.t(data, "got submit data");
 								doh.is("Ted", data.name, "Name");
 								doh.is("America", data.loc, "Location");
@@ -177,7 +185,7 @@
 					}
 				]);
 
-				doh.register("keyboard tests (cancel via Cancel button)",[
+				doh.register("keyboard tests (cancel via Cancel button)", [
 					{
 						name: "close Dialog via Cancel button",
 						timeout: 15000,
@@ -186,27 +194,27 @@
 
 							// Test which callbacks are called on cancel
 							var executed = false, canceled = false;
-							dojo.connect(dijit.byId("ABDlg1"), "execute", function(vals){
+							aspect.after(registry.byId("ABDlg1"), "execute", function(vals){
 								executed = true;
-							});
-							dojo.connect(dijit.byId("ABDlg1"), "onCancel", function(){
+							}, true);
+							registry.byId("ABDlg1").on("cancel", function(){
 								canceled = true;
 							});
 
 							// Open the dialog
-							dojo.byId("ABDlg1Btn").focus();
-							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
+							dom.byId("ABDlg1Btn").focus();
+							robot.keyPress(keys.SPACE, 1000, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("ABDlg1"), "dialog opened");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("ABDlg1"), "dialog opened");
 							}), 1000);
 
 							// Cancel
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.SPACE, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("ABDlg1"), "dialog closed on cancel");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("ABDlg1"), "dialog closed on cancel");
 								doh.t(canceled, "cancel callback was called");
 								doh.f(executed, "execute callback wasn't called");
 							}), 1000);
@@ -218,11 +226,11 @@
 
 				// Test aria roles, etc.
 				doh.register("aria", function(){
-					var dlog = dijit.byId("dialog1");
+					var dlog = registry.byId("dialog1");
 					doh.is("dialog", dlog.domNode.getAttribute("role"), "role");
 					doh.is("dialog1_title", dlog.domNode.getAttribute("aria-labelledby"), "aria-labelledby");
-					doh.isNot(undefined, dojo.byId("dialog1_title"), "label node exists");
-					doh.isNot("", innerText(dojo.byId("dialog1_title")), "label node has text");
+					doh.isNot(undefined, dom.byId("dialog1_title"), "label node exists");
+					doh.isNot("", helpers.innerText(dom.byId("dialog1_title")), "label node has text");
 					// dijit.Dialog does not implement aria-expanded as of this writing -- should it?
 				});
 
@@ -237,44 +245,44 @@
 							// Click the button.  We do this manually rather than calling Dialog.show()
 							// so we can later test that focus is restored (to the previous position)
 							// when the dialog is closed
-							dojo.byId("unmovablebutton").focus();
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							dom.byId("unmovablebutton").focus();
+							robot.keyPress(keys.SPACE, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "focus is somewhere #1");
-								doh.t(dojo.hasClass(dojo.global.dijit.focus.curNode, "dijitDialogCloseIcon"), "focus is on the close button #1");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(dfocus.curNode, "focus is somewhere #1");
+								doh.t(domClass.contains(dfocus.curNode, "dijitDialogCloseIcon"), "focus is on the close button #1");
 							}), 1000);
 
 							// Tab key shouldn't change the focus
-							doh.robot.keyPress(dojo.keys.TAB, 500);
+							robot.keyPress(keys.TAB, 500);
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "focus is somewhere #2");
-								doh.t(dojo.hasClass(dojo.global.dijit.focus.curNode, "dijitDialogCloseIcon"), "focus is on the close button #2");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(dfocus.curNode, "focus is somewhere #2");
+								doh.t(domClass.contains(dfocus.curNode, "dijitDialogCloseIcon"), "focus is on the close button #2");
 							}), 500);
 
 							// Space key should close the dialog
-							doh.robot.keyPress(dojo.keys.SPACE, 500);
+							robot.keyPress(keys.SPACE, 500);
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "focus is somewhere #3");
-								doh.is("unmovablebutton", dojo.global.dijit.focus.curNode.id, "focus is back on the button that opened the dialog #1");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(dfocus.curNode, "focus is somewhere #3");
+								doh.is("unmovablebutton", dfocus.curNode.id, "focus is back on the button that opened the dialog #1");
 							}), 500);
 
 							// Open the dialog again
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							robot.keyPress(keys.SPACE, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "focus is somewhere #4");
-								doh.t(dojo.hasClass(dojo.global.dijit.focus.curNode, "dijitDialogCloseIcon"), "focus is on the close button #4");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(dfocus.curNode, "focus is somewhere #4");
+								doh.t(domClass.contains(dfocus.curNode, "dijitDialogCloseIcon"), "focus is on the close button #4");
 							}), 500);
 
 							// Esc key should also close the dialog
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500);
+							robot.keyPress(keys.ESCAPE, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "focus is somewhere #5");
-								doh.is("unmovablebutton", dojo.global.dijit.focus.curNode.id, "focus is back on the button that opened the dialog #2");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(dfocus.curNode, "focus is somewhere #5");
+								doh.is("unmovablebutton", dfocus.curNode.id, "focus is back on the button that opened the dialog #2");
 							}), 500);
 
 							return d;
@@ -290,20 +298,20 @@
 							// Click the button.  We do this manually rather than calling Dialog.show()
 							// so we can later test that focus is restored (to the previous position)
 							// when the dialog is closed
-							dojo.byId("filebutton").focus();
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							dom.byId("filebutton").focus();
+							robot.keyPress(keys.SPACE, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "focus is somewhere #1");
-								doh.is("afile", dojo.global.dijit.focus.curNode.id, "focus is on the input type=file");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(dfocus.curNode, "focus is somewhere #1");
+								doh.is("afile", dfocus.curNode.id, "focus is on the input type=file");
 							}), 1000);
 
 							// Esc key should close the dialog
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500);
+							robot.keyPress(keys.ESCAPE, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "focus is somewhere #2");
-								doh.is("filebutton", dojo.global.dijit.focus.curNode.id, "focus is back on the button that opened the dialog");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(dfocus.curNode, "focus is somewhere #2");
+								doh.is("filebutton", dfocus.curNode.id, "focus is back on the button that opened the dialog");
 							}), 500);
 
 							return d;
@@ -319,28 +327,28 @@
 							// Click the button.  We do this manually rather than calling Dialog.show()
 							// so we can later test that focus is restored (to the previous position)
 							// when the dialog is closed
-							dojo.byId("RadioButtonDlgBtn").focus();
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							dom.byId("RadioButtonDlgBtn").focus();
+							robot.keyPress(keys.SPACE, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "focus is somewhere #1");
-								doh.is("textarea-radio-test", dojo.global.dijit.focus.curNode.id, "focus is on the textarea");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(dfocus.curNode, "focus is somewhere #1");
+								doh.is("textarea-radio-test", dfocus.curNode.id, "focus is on the textarea");
 							}), 1000);
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "focus is somewhere #2");
-								doh.is("textarea-radio-test", dojo.global.dijit.focus.curNode.id, "focus wraps around back to the textarea");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(dfocus.curNode, "focus is somewhere #2");
+								doh.is("textarea-radio-test", dfocus.curNode.id, "focus wraps around back to the textarea");
 							}), 500);
 
 							// Esc key should close the dialog
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500);
+							robot.keyPress(keys.ESCAPE, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "focus is somewhere #3");
-								doh.is("RadioButtonDlgBtn", dojo.global.dijit.focus.curNode.id, "focus is back on the button that opened the dialog");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(dfocus.curNode, "focus is somewhere #3");
+								doh.is("RadioButtonDlgBtn", dfocus.curNode.id, "focus is back on the button that opened the dialog");
 							}), 500);
 
 							return d;
@@ -348,12 +356,12 @@
 					}
 				]);
 
-				doh.register("keyboard tests (multiple dialogs)",[
+				doh.register("keyboard tests (multiple dialogs)", [
 					{
 						name: "open first dialog",
 						timeout: 10000,
 						setUp: function(){
-							dijit.byId("dialog1").reset();
+							registry.byId("dialog1").reset();
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
@@ -361,23 +369,23 @@
 							// Click the button.  We do this manually rather than calling Dialog.show()
 							// so we can later test that focus is restored (to the previous position)
 							// when the dialog is closed
-							dojo.byId("dialog1button").focus();
-							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
-							doh.robot.typeKeys("lower", 1000, 1000);
+							dom.byId("dialog1button").focus();
+							robot.keyPress(keys.SPACE, 1000, {});
+							robot.typeKeys("lower", 1000, 1000);
 
 							// Move focus to second field
-							doh.robot.keyPress(dojo.keys.TAB, 1000);
+							robot.keyPress(keys.TAB, 1000);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("dialog1"), "dialog 1 is visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("dialog1"), "dialog 1 is visible");
 
-								var dialog1Z = dojo.style(dijit.byId("dialog1").domNode, "zIndex"),
-									underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+								var dialog1Z = domStyle.get(registry.byId("dialog1").domNode, "zIndex"),
+									underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
 
 								doh.t(dialog1Z > underlayZ, "dialog1 (zIndex=" + dialog1Z +
 									") above underlay (zIndex=" + underlayZ + ")");
 
-								doh.is("loc", dojo.global.dijit.focus.curNode.id, "focus is on the second field");
+								doh.is("loc", dfocus.curNode.id, "focus is on the second field");
 							}), 1000);
 
 							return d;
@@ -390,15 +398,15 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							dijit.byId("tabDialog").show();
+							registry.byId("tabDialog").show();
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("tabDialog"), "tab dialog has been made visible");
-								doh.t(isVisible("dialog1"), "dialog 1 is still visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("tabDialog"), "tab dialog has been made visible");
+								doh.t(helpers.isVisible("dialog1"), "dialog 1 is still visible");
 
-								var tabDialogZ = dojo.style(dijit.byId("tabDialog").domNode, "zIndex"),
-									dialog1Z = dojo.style(dijit.byId("dialog1").domNode, "zIndex"),
-									underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+								var tabDialogZ = domStyle.get(registry.byId("tabDialog").domNode, "zIndex"),
+									dialog1Z = domStyle.get(registry.byId("dialog1").domNode, "zIndex"),
+									underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
 
 								doh.t(tabDialogZ > underlayZ, "tabDialog (zIndex=" + tabDialogZ +
 									") above underlay (zIndex=" + underlayZ + ")");
@@ -416,19 +424,19 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
+							robot.keyPress(keys.ESCAPE, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("tabDialog"), "tab dialog has been hidden");
-								doh.t(isVisible("dialog1"), "dialog 1 is still visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("tabDialog"), "tab dialog has been hidden");
+								doh.t(helpers.isVisible("dialog1"), "dialog 1 is still visible");
 
-								var dialog1Z = dojo.style(dijit.byId("dialog1").domNode, "zIndex"),
-									underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+								var dialog1Z = domStyle.get(registry.byId("dialog1").domNode, "zIndex"),
+									underlayZ = domStyle.get(DialogUnderlay._singleton.domNode, "zIndex");
 
 								doh.t(dialog1Z > underlayZ, "dialog1 (zIndex=" + dialog1Z +
 									") above underlay (zIndex=" + underlayZ + ")");
 
-								doh.is("loc", dojo.global.dijit.focus.curNode.id, "focus is on the second field");
+								doh.is("loc", dfocus.curNode.id, "focus is on the second field");
 							}), 2000);
 
 							return d;
@@ -441,11 +449,11 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
+							robot.keyPress(keys.ESCAPE, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("dialog1"), "dialog 1 was closed");
-								doh.is("dialog1button", dojo.global.dijit.focus.curNode.id, "focus returned to button");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("dialog1"), "dialog 1 was closed");
+								doh.is("dialog1button", dfocus.curNode.id, "focus returned to button");
 							}), 2000);
 
 							return d;
@@ -453,6 +461,159 @@
 					}
 				]);
 
+				// Testing if focus somehow gets shifted to an element behind the underlay, by (for example)
+				// access keys, or tabbing in from the URL bar, or clicking the underlay, thus focusing <body>.
+				doh.register("focus return", [
+					{
+						name: "open first",
+						timeout: 10000,
+						runTest: function(){
+							return registry.byId('dialog1').show();
+						}
+					},
+					{
+						name: "open second",
+						timeout: 10000,
+						runTest: function(){
+							var fifthDlg = registry.byId('fifthDlg');
+							return fifthDlg.show().then(function(){
+								return fifthDlg.onLoadDeferred;
+							});
+						}
+					},
+					{
+						name: "focus main page",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dom.byId("plainInput").focus();
+
+							setTimeout(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("fifthDlg"), "dialog 5 still visible");
+								doh.is("timeref", dfocus.curNode && dfocus.curNode.id,
+										"focus remains on / returned to dialog");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "close second",
+						timeout: 10000,
+						runTest: function(){
+							return registry.byId('fifthDlg').hide();
+						}
+					},
+					{
+						name: "focus main page again",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dom.byId("plainInput").focus();
+
+							setTimeout(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("dialog1"), "dialog 1 still visible");
+								doh.is("name", dfocus.curNode && dfocus.curNode.id,
+										"focus remains on / returned to dialog");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "close first",
+						timeout: 10000,
+						runTest: function(){
+							return registry.byId('dialog1').hide();
+						}
+					}
+				]);
+
+				// Negative test for "focus return".   If the execute() handler shifts focus somewhere,
+				// make sure it isn't automatically shifted back to the Dialog (which is fading out but
+				// not yet hidden).
+				doh.register("focus in execute", [
+					{
+						name: "use dialog",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Open the dialog
+							dom.byId("insertTextButton", robot.doc).focus();
+							robot.keyPress(keys.SPACE, 500, {});
+
+							// Enter some info
+							robot.typeKeys("Hello world", 2000, 600);
+
+							// Submit
+							robot.keyPress(keys.TAB, 1000, {});
+							robot.keyPress(keys.SPACE, 1000, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("editor", dfocus.curNode.id, "focus returned to editor");
+								doh.is("Hello world", dom.byId("editor", robot.doc).value, "text inserted");
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("closable", [
+					{
+						name: "open dialog",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dom.byId("unclosableButton").focus();
+							robot.keyPress(keys.SPACE, 1000, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("unclosable"), "visible");
+								doh.t(helpers.isHidden(registry.byId("unclosable").closeButtonNode), "close icon hidden");
+							}), 500);
+
+							return d;
+						}
+					},
+
+					{
+						name: "close via ESC",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.keyPress(keys.ESCAPE, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("unclosable"), "still visible");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "close via ENTER on OK button",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.keyPress(keys.ENTER, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("unclosable"), "hidden");
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/robot/Dialog_focusDestroy.html b/dijit/tests/robot/Dialog_focusDestroy.html
index cbd1f8c..4eec519 100644
--- a/dijit/tests/robot/Dialog_focusDestroy.html
+++ b/dijit/tests/robot/Dialog_focusDestroy.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot dialog focus destroy Test</title>
+		<title>robot dialog focus destroy Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,39 +10,40 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom", "dojo/keys", "dojo/_base/lang", "dojo/domReady!"
+			], function(doh, robot, dom, keys, lang){
+				robot.initRobot('../test_Dialog_focusDestroy.html');
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Dialog_focusDestroy.html');
-					
-				doh.register("TestDestroy",[
+				doh.register("TestDestroy", [
 					{
 						name: "destroy",
-						timeout: 11000,
+						timeout: 20000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("testInput", 500);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
-							doh.robot.keyPress("a", 1000);
-							doh.robot.mouseMoveAt("showDialog", 500);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.keyPress("a", 1000);
-							doh.robot.mouseMoveAt("destroyButton", 500);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("testInput", 500);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
-							doh.robot.keyPress("b", 1000);
+							robot.mouseMoveAt("testInput", 500);
+							robot.mouseClick({left:true}, 500);
+							robot.keyPress(keys.BACKSPACE, 500);
+							robot.keyPress(keys.BACKSPACE, 500);
+							robot.keyPress(keys.BACKSPACE, 500);
+							robot.keyPress("a", 1000);
+							robot.mouseMoveAt("showDialog", 500);
+							robot.mouseClick({left:true}, 500);
+							robot.keyPress("a", 1000);
+							robot.mouseMoveAt("destroyButton", 500);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("testInput", 500);
+							robot.mouseClick({left:true}, 500);
+							robot.keyPress(keys.BACKSPACE, 500);
+							robot.keyPress("b", 1000);
 							
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								var inputBox = dojo.byId("testInput");
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								var inputBox = dom.byId("testInput");
 								doh.is("b", inputBox.value);
 							})), 1000);
 
diff --git a/dijit/tests/robot/Dialog_mouse.html b/dijit/tests/robot/Dialog_mouse.html
index 93e8d0b..5f23e1c 100644
--- a/dijit/tests/robot/Dialog_mouse.html
+++ b/dijit/tests/robot/Dialog_mouse.html
@@ -1,255 +1,381 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
-	<head>
-		<title>doh.robot Dialog Mouse Test</title>
-
-		<style>
-			@import "../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Dialog.html');
-
-				doh.register("dijit.Dialog mouse tests (cancel)",[
-					{
-						name: "open dialog",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var oldOnClick = dijit.byId("dialog1button").onClick;
-							dijit.byId("dialog1button").onClick = function(){
-								dijit.byId("dialog1").show().then(d.getTestCallback(function(){
-									doh.t(isVisible("dialog1"), "dialog 1 has been made visible");
-									doh.is("name", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
-								}));
-								dijit.byId("dialog1button").onClick = oldOnClick;
-							};
-
-							// Open the dialog
-							doh.robot.mouseMoveAt("dialog1button", 1000);
-							doh.robot.mouseClick({left: true}, 1000);
-
-							return d;
-						}
-					},
-
-					{
-						name: "test that other controls on page can't be clicked",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("plainInput", 500);
-							doh.robot.mouseClick({left: true}, 1000);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("dialog1"), "dialog 1 still visible");
-								doh.isNot("plainInput", dojo.global.dijit.focus.curNode && dojo.global.dijit.focus.curNode.id, "plain input wasn't focused");
-							}), 1000);
-
-							return d;
-						}
-					},
-
-					{
-						name: "open date drop down",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							onFocus(function(){
-								// Focus might first go to input, then to calendar, so wait for that
-								setTimeout(d.getTestCallback(function(){
-									var calDomNode = dojo.query(".dijitCalendarContainer");
-									doh.t(calDomNode.length == 1 && isVisible(calDomNode[0]), "calendar is being shown");
-									doh.t(dojo.isDescendant(dojo.global.dijit.focus.curNode, calDomNode[0]), "focus is on the calendar ");
-								}), 500);
-							});
-
-							doh.robot.mouseMoveAt(function(){ return dojo.query(".dijitArrowButton", dijit.byId("date").domNode)[0]; }, 500);
-							doh.robot.mouseClick({left: true}, 1000);
-
-							return d;
-						}
-					},
-
-					{
-						name: "close date drop down",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMove(10, 10, 500);
-							doh.robot.mouseClick({left: true}, 1000);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								var calDomNode= dojo.query(".dijitCalendarContainer");
-								doh.t(calDomNode.length == 0 || isHidden(calDomNode[0]), "calendar has disappeared");
-								doh.t(isVisible("dialog1"), "dialog 1 wasn't closed");
-							}), 1000);
-
-							return d;
-						}
-					},
-
-					{
-						name: "cancel dialog",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							onFocus(d.getTestCallback(function(node){
-								doh.t(isHidden("dialog1"), "dialog 1 was closed");
-								doh.is("dialog1button", node.id, "focus returned to button");
-							}));
-
-							var button = dojo.query("#dialog1 .dijitDialogCloseIcon")[0];
-							doh.robot.mouseMoveAt(button, 500);
-							doh.robot.mouseClick({left: true}, 1000);
-
-							return d;
-						}
-					}
-				]);
-
-				doh.register("dijit.Dialog mouse tests (submit)",[
-					{
-						name: "submit some data",
-						timeout: 15000,
-						setUp: function(){
-							dijit.byId("dialog1").reset();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							// Setup handler to catch submitted data
-							var data;
-							dojo.connect(dijit.byId("dialog1"), "execute", function(vals){
-								data = vals;
-							});
-
-							// Open the dialog
-							doh.robot.mouseMoveAt("dialog1button", 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
-
-							// Enter some info
-							doh.robot.mouseMoveAt("name", 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.typeKeys("Ted", 500, 600);
-
-							doh.robot.mouseMoveAt("loc", 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.typeKeys("America", 500, 1400);
-
-							// Submit
-							doh.robot.mouseMoveAt("ok", 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("dialog1"), "dialog 1 was closed on submit");
-								doh.t(data, "got submit data");
-								doh.is("Ted", data.name, "Name");
-								doh.is("America", data.loc, "Location");
-							}), 1000);
-
-							return d;
-						}
-					}
-				]);
-
-				doh.register("dijit.Dialog mouse tests (unfocusable open button)", [
-					{
-						name: "open #1",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							// Open the dialog
-							doh.robot.mouseMoveAt("SelfDestructDlgBtn2", 1000);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dijit.byId("SelfDestructDlg"), "dialog created");
-								doh.t(isVisible("SelfDestructDlgBtn2"), "dialog has been made visible");
-								doh.is("SelfDestructDlgInput", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
-							}), 1000);
-
-							return d;
-						}
-					},
-					{
-						name: "close #1",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							// Close the dialog
-							doh.robot.mouseMoveAt(function(){
-								return dojo.query("#SelfDestructDlg .dijitDialogCloseIcon")[0];
-							}, 1000);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.f(dijit.byId("SelfDestructDlg"), "dialog destroyed");
-								doh.f(dojo.global.dijit.focus.curNode, "focus cleared");
-							}), 1000);
-
-							return d;
-						}
-					},
-					{
-						name: "open #2",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							// Open the dialog
-							doh.robot.mouseMoveAt("SelfDestructDlgBtn2", 1000);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dijit.byId("SelfDestructDlg"), "dialog created");
-								doh.t(isVisible("SelfDestructDlgBtn2"), "dialog has been made visible");
-								doh.is("SelfDestructDlgInput", dojo.global.dijit.focus.curNode.id, "focus is on the first field");
-							}), 1000);
-
-							return d;
-						}
-					},
-					{
-						name: "close #2",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							// Close the dialog
-							doh.robot.mouseMoveAt(function(){
-								return dojo.query("#SelfDestructDlg .dijitDialogCloseIcon")[0];
-							}, 1000);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.f(dijit.byId("SelfDestructDlg"), "dialog destroyed");
-								doh.f(dojo.global.dijit.focus.curNode, "focus cleared");
-							}), 1000);
-
-							return d;
-						}
-					}
-
-				]);
-
-				doh.run();
-			});
-		</script>
-	</head>
+<head>
+<title>robot Dialog Mouse Test</title>
+
+<style>
+	@import "../../../util/doh/robot/robot.css";
+</style>
+
+<!-- required: dojo.js -->
+<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true"></script>
+
+<script type="text/javascript">
+require([
+	"doh/runner", "dojo/robotx",
+	"dojo/aspect", "dojo/dom", "dojo/keys", "dojo/query",
+	"dijit/tests/helpers", "dojo/domReady!"
+], function(doh, robot, aspect, dom, keys, query, helpers){
+
+	robot.initRobot('../test_Dialog.html');
+
+	doh.register(function setup(){
+		// get pointer to registry in the iframe
+		registry = robot.window.require("dijit/registry");
+		dfocus = robot.window.require("dijit/focus");
+	});
+
+
+	doh.register("dijit.Dialog mouse tests (cancel)", [
+		{
+			name: "open dialog",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				var oldOnClick = registry.byId("dialog1button").onClick;
+				registry.byId("dialog1button").onClick = function(){
+					registry.byId("dialog1").show().then(d.getTestCallback(function(){
+						doh.t(helpers.isVisible("dialog1"), "dialog 1 has been made visible");
+						doh.is("name", dfocus.curNode.id, "focus is on the first field");
+					}));
+					registry.byId("dialog1button").onClick = oldOnClick;
+				};
+
+				// Open the dialog
+				robot.mouseMoveAt("dialog1button", 1000);
+				robot.mouseClick({left: true}, 1000);
+
+				return d;
+			}
+		},
+
+		{
+			name: "test that other controls on page can't be clicked",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				robot.mouseMoveAt("plainInput", 500);
+				robot.mouseClick({left: true}, 1000);
+
+				robot.sequence(d.getTestCallback(function(){
+					doh.t(helpers.isVisible("dialog1"), "dialog 1 still visible");
+					doh.isNot("plainInput", dfocus.curNode && dfocus.curNode.id,
+							"focus did not go to plain input");
+				}), 1000);
+
+				return d;
+			}
+		},
+
+		{
+			name: "open date drop down",
+			timeout: 10000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				helpers.onFocus(d.getTestCallback(function(){
+					var calDomNode = query(".dijitCalendarContainer");
+					doh.t(1, calDomNode.length, "found calendar");
+					doh.t(helpers.isVisible(calDomNode[0]), "calendar is being shown");
+					doh.t(dom.isDescendant(dfocus.curNode, calDomNode[0]), "focus is on the calendar");
+				}), 500);	// Focus might first go to input, then to calendar, so wait for that
+
+
+				robot.mouseMoveAt(function(){
+					return query(".dijitArrowButton", registry.byId("date").domNode)[0];
+				}, 500);
+				robot.mouseClick({left: true}, 1000);
+
+				return d;
+			}
+		},
+
+		{
+			name: "close date drop down",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				robot.mouseMove(10, 10, 500);
+				robot.mouseClick({left: true}, 1000);
+
+				robot.sequence(d.getTestCallback(function(){
+					var calDomNode = query(".dijitCalendarContainer");
+					doh.t(calDomNode.length == 0 || helpers.isHidden(calDomNode[0]), "calendar has disappeared");
+					doh.t(helpers.isVisible("dialog1"), "dialog 1 wasn't closed");
+				}), 1000);
+
+				return d;
+			}
+		},
+
+		{
+			name: "cancel dialog",
+			timeout: 5000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				var button = query("#dialog1 .dijitDialogCloseIcon")[0];
+				robot.mouseMoveAt(button, 500);
+				robot.mouseClick({left: true}, 500);
+
+				robot.sequence(d.getTestCallback(function(node){
+					doh.t(helpers.isHidden("dialog1"), "dialog 1 was closed");
+				}), 500);
+
+				return d;
+			}
+		}
+	]);
+
+	doh.register("dijit.Dialog mouse tests (submit)", [
+		{
+			name: "submit some data",
+			timeout: 15000,
+			setUp: function(){
+				registry.byId("dialog1").reset();
+			},
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				// Setup handler to catch submitted data
+				var data;
+				aspect.after(registry.byId("dialog1"), "execute", function(vals){
+					data = vals;
+				}, true);
+
+				// Open the dialog
+				robot.mouseMoveAt("dialog1button", 500, 1);
+				robot.mouseClick({left: true}, 500);
+
+				// Enter some info
+				robot.mouseMoveAt("name", 500, 1);
+				robot.mouseClick({left: true}, 500);
+				robot.typeKeys("Ted", 500, 600);
+
+				robot.mouseMoveAt("loc", 500, 1);
+				robot.mouseClick({left: true}, 500);
+				robot.typeKeys("America", 500, 1400);
+
+				// Submit
+				robot.mouseMoveAt("ok", 500, 1);
+				robot.mouseClick({left: true}, 500);
+
+				robot.sequence(d.getTestCallback(function(){
+					doh.t(helpers.isHidden("dialog1"), "dialog 1 was closed on submit");
+					doh.t(data, "got submit data");
+					doh.is("Ted", data.name, "Name");
+					doh.is("America", data.loc, "Location");
+				}), 1000);
+
+				return d;
+			}
+		}
+	]);
+
+	doh.register("dijit.Dialog mouse tests (unfocusable open button)", [
+		{
+			name: "open #1",
+			timeout: 10000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				// Open the dialog
+				robot.mouseMoveAt("SelfDestructDlgBtn2", 1000);
+				robot.mouseClick({left: true}, 1000);
+				robot.sequence(d.getTestCallback(function(){
+					doh.t(registry.byId("SelfDestructDlg"), "dialog created");
+					doh.t(helpers.isVisible("SelfDestructDlgBtn2"), "dialog has been made visible");
+					doh.is("SelfDestructDlgInput", dfocus.curNode.id, "focus is on the first field");
+				}), 1000);
+
+				return d;
+			}
+		},
+		{
+			name: "close #1",
+			timeout: 10000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				// Close the dialog
+				robot.mouseMoveAt(function(){
+					return query("#SelfDestructDlg .dijitDialogCloseIcon")[0];
+				}, 1000);
+				robot.mouseClick({left: true}, 1000);
+				robot.sequence(d.getTestCallback(function(){
+					doh.f(registry.byId("SelfDestructDlg"), "dialog destroyed");
+
+					var focus = dfocus.curNode;
+					doh.f(focus, "focus should have been cleared, but set to " +
+							focus + (focus && focus.tagName) + (focus && focus.id));
+				}), 1000);
+
+				return d;
+			}
+		},
+		{
+			name: "open #2",
+			timeout: 10000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				// Open the dialog
+				robot.mouseMoveAt("SelfDestructDlgBtn2", 1000);
+				robot.mouseClick({left: true}, 1000);
+				robot.sequence(d.getTestCallback(function(){
+					doh.t(registry.byId("SelfDestructDlg"), "dialog created");
+					doh.t(helpers.isVisible("SelfDestructDlgBtn2"), "dialog has been made visible");
+					doh.is("SelfDestructDlgInput", dfocus.curNode.id, "focus is on the first field");
+				}), 1000);
+
+				return d;
+			}
+		},
+		{
+			name: "close #2",
+			timeout: 10000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				// Close the dialog
+				robot.mouseMoveAt(function(){
+					return query("#SelfDestructDlg .dijitDialogCloseIcon")[0];
+				}, 1000);
+				robot.mouseClick({left: true}, 1000);
+				robot.sequence(d.getTestCallback(function(){
+					doh.f(registry.byId("SelfDestructDlg"), "dialog destroyed");
+
+					var focus = dfocus.curNode;
+					doh.f(focus, "focus should have been cleared, but set to " +
+							focus + (focus && focus.tagName) + (focus && focus.id));
+				}), 1000);
+
+				return d;
+			}
+		}
+	]);
+
+	// Opening a context menu shifts focus away from the Dialog but we shouldn't automatically shift focus back
+	doh.register("context menu", [
+		{
+			name: "open first",
+			timeout: 10000,
+			runTest: function(){
+				return registry.byId('dialog1').show();
+			}
+		},
+		{
+			name: "open context menu",
+			timeout: 10000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				robot.mouseMoveAt("dialog1", 500);
+				robot.mouseClick({right: true}, 1000);
+
+				robot.sequence(d.getTestCallback(function(){
+					doh.t(helpers.isVisible("dialog1"), "dialog 1 still visible");
+					doh.t(helpers.isVisible("dialog1ContextMenu"), "context menu visible");
+					doh.is("firstMenuItem", dfocus.curNode && dfocus.curNode.id,
+							"focus on Menu");
+				}), 1000);
+
+				return d;
+			}
+		},
+		{
+			name: "close first",
+			timeout: 10000,
+			runTest: function(){
+				return registry.byId('dialog1').hide();
+			}
+		}
+	]);
+
+	doh.register("ESC", [
+		{
+			name: "open dialog",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				// Open the dialog
+				robot.mouseMoveAt("dialog1button", 1000);
+				robot.mouseClick({left: true}, 1000);
+				robot.sequence(d.getTestCallback(function(){}));
+
+				return d;
+			}
+		},
+
+		{
+			name: "click background",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				robot.mouseMoveAt("plainInput", 500);
+				robot.mouseClick({left: true}, 1000);
+
+				robot.sequence(d.getTestCallback(function(){
+					doh.t(helpers.isVisible("dialog1"), "dialog 1 still visible");
+					doh.isNot("plainInput", dfocus.curNode && dfocus.curNode.id,
+							"focus did not go to plain input");
+				}), 1000);
+
+				return d;
+			}
+		},
+
+		{
+			name: "close via ESC",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				robot.keyPress(keys.ESCAPE, 500, {});
+
+				robot.sequence(d.getTestCallback(function(){
+					doh.t(helpers.isHidden("dialog1"), "dialog 1 was closed");
+				}), 1000);
+
+				return d;
+			}
+		}
+	]);
+
+	doh.register("dijit.Dialog InlineEditBox w/Editor tests", [
+		{
+			name: "#17225",
+			timeout: 10000,
+			runTest: function(){
+				var d = new doh.Deferred();
+
+				// Open the dialog
+				robot.mouseMoveAt("iebDialogBtn", 1000);
+				robot.mouseClick({left: true}, 1000);
+
+				// Open second InlineEditBox
+				robot.mouseMoveAt("inlineRTE2", 1000);
+				robot.mouseClick({left: true}, 1000);
+
+				// Test that editor didn't close immediately and focus move back to the first field
+				robot.sequence(d.getTestCallback(function(){
+					doh.t(helpers.isVisible("RTE2"), "editor 2 visible");
+				}), 1000);
+
+				return d;
+			}
+		}
+	]);
+
+	doh.run();
+});
+</script>
+</head>
 </html>
diff --git a/dijit/tests/robot/InlineEditBox.html b/dijit/tests/robot/InlineEditBox.html
index b1766fd..8fa482a 100644
--- a/dijit/tests/robot/InlineEditBox.html
+++ b/dijit/tests/robot/InlineEditBox.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot InlineEditBox Test</title>
+		<title>robot InlineEditBox Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,34 +10,37 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dojo.date.locale");
-			dojo.require("dijit.robotx");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_InlineEditBox.html');
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/_base/array", "dojo/aspect", "dojo/date/locale", "dojo/keys", "dojo/_base/lang", "dojo/query",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, array, aspect, datelocale, keys, lang, query, helpers){
+				robot.initRobot('../test_InlineEditBox.html');
 
 				function moveAndClick(node){
-					doh.robot.mouseMoveAt(node, 500, 1);
-					doh.robot.mouseClick({left: true}, 500);
+					robot.mouseMoveAt(node, 500, 1);
+					robot.mouseClick({left: true}, 500);
 				}
 
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+				});
+
 				doh.register("dijit.InlineEditBox autosave tests", [
 					{
 						name: "CurrencyTextBox invalid value: blur",
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("dollar_as");
+							var inlineBox = registry.byId("dollar_as");
 							moveAndClick(inlineBox.domNode);
-							doh.robot.typeKeys("dollar", 1000, 1200); // invalid
+							robot.typeKeys("dollar", 1000, 1200); // invalid
 							moveAndClick("predefined");
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								var currencyTextBox = inlineBox.wrapperWidget.editWidget;
 								doh.is('dollar', currencyTextBox.get("displayedValue"), "displayedValue");
 								doh.f(currencyTextBox.isValid(), "!isValid");
@@ -52,18 +55,18 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("dollar_as");
+							var inlineBox = registry.byId("dollar_as");
 							var displayedValue, isValid;
 							moveAndClick(inlineBox.domNode);
-							doh.robot.typeKeys("dollar", 1000, 1200); // invalid
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-							doh.robot.sequence(function(){
+							robot.typeKeys("dollar", 1000, 1200); // invalid
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.sequence(function(){
 								var currencyTextBox = inlineBox.wrapperWidget.editWidget;
 								displayedValue = currencyTextBox.get("displayedValue");
 								isValid = currencyTextBox.isValid();
 							}, 1000);
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.keyPress(keys.ESCAPE, 500, {});
+							robot.sequence(d.getTestCallback(function(){
 								doh.is('dollar', displayedValue, "displayedValue");
 								doh.f(isValid, "!isValid");
 								doh.is('', inlineBox.get("value"), "value");
@@ -76,11 +79,11 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("dollar_as");
+							var inlineBox = registry.byId("dollar_as");
 							moveAndClick(inlineBox.domNode);
-							doh.robot.typeKeys("123", 1000, 600);
+							robot.typeKeys("123", 1000, 600);
 							moveAndClick("predefined");
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is("$123.00", inlineBox.get("value"), "value");
 							}), 1000);
 							return d;
@@ -91,11 +94,11 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("dollar_as");
+							var inlineBox = registry.byId("dollar_as");
 							moveAndClick(inlineBox.domNode);
-							doh.robot.typeKeys("234", 1000, 600);
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.typeKeys("234", 1000, 600);
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.sequence(d.getTestCallback(function(){
 								doh.is('$234.00', inlineBox.get("value"), "value");
 							}), 1000);
 							return d;
@@ -106,11 +109,11 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("dollar_as");
+							var inlineBox = registry.byId("dollar_as");
 							moveAndClick(inlineBox.domNode);
-							doh.robot.typeKeys("345", 1000, 600);
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.typeKeys("345", 1000, 600);
+							robot.keyPress(keys.ESCAPE, 500, {});
+							robot.sequence(d.getTestCallback(function(){
 								doh.is("$234.00", inlineBox.get("value"), "value");
 							}), 1000);
 							return d;
@@ -121,11 +124,11 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("dollar_as");
+							var inlineBox = registry.byId("dollar_as");
 							moveAndClick(inlineBox.domNode);
-							doh.robot.typeKeys("456", 1000, 600);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.typeKeys("456", 1000, 600);
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestCallback(function(){
 								doh.is('$456.00', inlineBox.get("value"), "value");
 							}), 1000);
 							return d;
@@ -136,25 +139,25 @@
 						timeout: 15000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("editable");
+							var inlineBox = registry.byId("editable");
 							var initialOnChange = inlineBox._onChangeValue;
 							inlineBox.set("value", "");
-							moveAndClick(inlineBox.domNode);
-							doh.robot.typeKeys("editable", 1000, 1600);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 1500, {}); // wait more than 1 second to TAB
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-							doh.robot.typeKeys("567", 500, 600);
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true}); // do this fast
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true}); // do this fast
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {}); // quickly back to editable
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.typeKeys(" again", 1000, 1200);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestCallback(function(){
+							inlineBox.edit();
+							robot.typeKeys("editable", 1000, 1600);
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 1500, {}); // wait more than 1 second to TAB
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.typeKeys("567", 500, 600);
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.keyPress(keys.TAB, 500, {shift:true}); // do this fast
+							robot.keyPress(keys.TAB, 500, {shift:true}); // do this fast
+							robot.keyPress(keys.ENTER, 500, {}); // quickly back to editable
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
+							robot.typeKeys(" again", 1000, 1200);
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestCallback(function(){
 								doh.is(undefined, initialOnChange, "no onChange value");
-								doh.is('$567.00', dijit.byId("dollar_as").get("value"), "value");
+								doh.is('$567.00', registry.byId("dollar_as").get("value"), "value");
 								doh.is('editable again', inlineBox.get("value"), "value");
 								doh.is('editable again', inlineBox._onChangeValue, "onChange value");
 							}), 1000);
@@ -166,9 +169,9 @@
 						timeout: 2000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("editable");
+							var inlineBox = registry.byId("editable");
 							inlineBox.set("value", "programmatic value");
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is("programmatic value", inlineBox._onChangeValue, "programmatic set causes onChange");
 							}), 500);
 							return d;
@@ -179,11 +182,11 @@
 						timeout: 2000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("programmatic");
+							var inlineBox = registry.byId("programmatic");
 							inlineBox.edit();
 							inlineBox.wrapperWidget.editWidget.set('value', 'changed');
 							inlineBox.save();
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is("changed", inlineBox._onChangeValue, "editing causes onChange");
 							}), 500);
 							return d;
@@ -194,13 +197,13 @@
 						timeout: 15000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("textarea");
+							var inlineBox = registry.byId("textarea");
 							moveAndClick(inlineBox.domNode);
-							doh.robot.typeKeys("line 1", 1000, 1200);
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-							doh.robot.typeKeys("line 2", 500, 1200);
+							robot.typeKeys("line 1", 1000, 1200);
+							robot.keyPress(keys.ENTER, 500, {});
+							robot.typeKeys("line 2", 500, 1200);
 							moveAndClick("predefined");
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is('line 1\\nline 2', inlineBox.get("value").replace(/\n/g, "\\n"), "textarea programmatic value was " + inlineBox.get("value").replace(/\n/g, "\\n"));
 								doh.is('line 1<br>line 2', inlineBox.domNode.innerHTML.toLowerCase(), "textarea rendered value was " + inlineBox.domNode.innerHTML);
 							}), 1000);
@@ -213,43 +216,54 @@
 				// For example, in this markup:
 				//		<span dojoType="dijit.InlineEditBox" ...>01/05/2007</span>
 				// When the editor is clicked the calendar should open to that date.
-				dojo.forEach([
+				array.forEach([
 					{ widget: "CurrencyTextBox", id: "dollar", textValue: "$2,000", widgetValue: 2000 },
 					{ widget: "NumberTextBox", id: "quantity", textValue: "3", widgetValue: 3 },
 					{ widget: "ComboBox", id: "item", textValue: "refrigerators", widgetValue: "refrigerators" },
-					{ widget: "DateTextBox", id: "purchase", textValue: "01/05/2007", widgetValue: dojo.date.locale.parse("01/05/2007", {datePattern: 'MM/dd/yyyy', selector:'date'}) },
-					{ widget: "FilteringSelect", id: "state", textValue: "Pennsylvania", widgetValue: "PA" }
+					{ widget: "DateTextBox", id: "purchase", textValue: "01/05/2007", widgetValue: datelocale.parse("01/05/2007", {datePattern: 'MM/dd/yyyy', selector:'date'}) },
+					{ widget: "FilteringSelect", id: "state", textValue: "Pennsylvania", widgetValue: "PA" },
+					{ widget: "Select", id: "country", textValue: "United States of America", widgetValue: "US" }
 				], function(test){
 					doh.register("preDefinedValue " + test.widget, {
-						timeout: 5000,
- 						name: dojo.toJson(test.id),
+						timeout: 8000,
+ 						name: test.id,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId(test.id);
-							var handler = inlineBox.connect(inlineBox, 'edit', function(){
-								inlineBox.disconnect(handler);
+							var inlineBox = registry.byId(test.id);
+							var handler = aspect.after(inlineBox, 'edit', function(){
+								handler.remove();
 								var editWidget = inlineBox.wrapperWidget.editWidget;
-								handler = editWidget.connect(editWidget, '_onFocus', function(){
-									editWidget.disconnect(handler);
-									setTimeout(d.getTestErrback(function(){
-										doh.is(test.textValue, inlineBox.get("value"), "inline text value");
-										doh.t(isVisible(editWidget), "editor widget should visible");
-										var expected = test.widgetValue,
-											actual = editWidget.get("value");
-										doh.is(typeof expected, typeof actual, "editor value typeof");
-										doh.is(expected.toString(), actual.toString(), "editor widget value");
-										handler = inlineBox.connect(inlineBox, 'onCancel',
-											function(){
-												inlineBox.disconnect(handler);
-												setTimeout(d.getTestCallback(function(){
-													doh.t(isHidden(inlineBox.wrapperWidget), "editor widget should hidden");
-												}), 500);
-											});
-										var buttons = dojo.query(".cancelButton", inlineBox.domNode.parentNode);
+								handler = aspect.after(editWidget, '_onFocus', function(){
+									handler.remove();
+									robot.sequence(function(){
+										var
+										textValue = test.textValue,
+										value = inlineBox.get("value"),
+										visible = helpers.isVisible(editWidget),
+										expected = test.widgetValue,
+										actual = editWidget.get("value"),
+										showHandler = aspect.after(inlineBox, 'save', d.getTestCallback(function(){
+											cancelHandler.remove();
+											showHandler.remove();
+											doh.t(false, "Save was clicked");
+										}), true),
+										cancelHandler = aspect.after(inlineBox, 'onCancel', function(){
+											cancelHandler.remove();
+											showHandler.remove();
+											robot.sequence(d.getTestCallback(function(){
+												doh.is(textValue, value, "inline text value");
+												doh.t(visible, "editor widget should be visible");
+												doh.is(typeof expected, typeof actual, "editor value typeof");
+												doh.is(expected.toString(), actual.toString(), "editor widget value");
+												doh.t(helpers.isHidden(inlineBox.wrapperWidget), "editor widget should be hidden");
+											}), 500);
+										}, true),
+										buttons = query(".dijitButton", inlineBox.domNode.parentNode);
+										moveAndClick(buttons[buttons.length-2]); // Save should be disabled so nothing happens
 										moveAndClick(buttons[buttons.length-1]);
-									}), 1500);
-								});
-							});
+									}, 1500);
+								}, true);
+							}, true);
 							moveAndClick(inlineBox.domNode);
 							return d;
 						}
@@ -266,27 +280,27 @@
 							var d = new doh.Deferred();
 
 							// confirm initial displayed value
-							var inlineBox = dijit.byId("renderAsHtml_false");
-							doh.is("<B>not bold</B>&lt;input&gt;", dojo.trim(inlineBox.domNode.innerHTML),
+							var inlineBox = registry.byId("renderAsHtml_false");
+							doh.is("<B>not bold</B>&lt;input&gt;", lang.trim(inlineBox.domNode.innerHTML),
 								"confirm initial value (with special chars) wasn't modified");
 							doh.is("<B>not bold</B><input>", inlineBox.get("value"),
 								"confirm initial get('value')");
 
 							// launch editor, and make sure that special characters aren't mangled
 							moveAndClick(inlineBox.domNode);
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								var editor = inlineBox.wrapperWidget.editWidget;
 								doh.is("<B>not bold</B><input>", editor.get("value"), "initial editor value");
 							}), 1000);
 
 							// edit value and save		
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
-							doh.robot.typeKeys("end", 2000, 1000);
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 1000, {});
+							robot.typeKeys("end", 2000, 1000);
+							robot.keyPress(keys.ENTER, 500, {});
 
 							// check that display value didn't mangle special characters
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("<B>not bold</B>&lt;input&gt;end", dojo.trim(inlineBox.domNode.innerHTML),
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("<B>not bold</B>&lt;input&gt;end", lang.trim(inlineBox.domNode.innerHTML),
 									"displayed value after edit");
 								doh.is("<B>not bold</B><input>end", inlineBox.get("value"),
 									"get('value') after edit");
@@ -304,9 +318,9 @@
 							var d = new doh.Deferred();
 
 							// confirm initial displayed value
-							var inlineBox = dijit.byId("renderAsHtml_true");
+							var inlineBox = registry.byId("renderAsHtml_true");
 							doh.is("<b>not bold</b><b>bold</b>&lt;input&gt;",
-								dojo.trim(inlineBox.domNode.innerHTML).toLowerCase(),
+								lang.trim(inlineBox.domNode.innerHTML).toLowerCase(),
 								"confirm initial value (with special chars) wasn't modified");
 							doh.is("<b>not bold</b><b>bold</b>&lt;input&gt;",
 								inlineBox.get("value").toLowerCase(),
@@ -314,7 +328,7 @@
 
 							// launch editor, and make sure that value was passed to editor as HTML
 							moveAndClick(inlineBox.domNode);
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								var editor = inlineBox.wrapperWidget.editWidget;
 								doh.is("<b>not bold</b><b>bold</b>&lt;input&gt;",
 									editor.get("value").toLowerCase(),
@@ -322,14 +336,14 @@
 							}), 1000);
 
 							// edit value and save		
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
-							doh.robot.typeKeys("end", 2000, 1000);
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 1000, {});
+							robot.typeKeys("end", 2000, 1000);
+							robot.keyPress(keys.ENTER, 500, {});
 
 							// check that display value didn't mangle special characters
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is("<b>not bold</b><b>bold</b>&lt;input&gt;end",
-									dojo.trim(inlineBox.domNode.innerHTML).toLowerCase(),
+									lang.trim(inlineBox.domNode.innerHTML).toLowerCase(),
 									"displayed value after edit");
 								doh.is("<b>not bold</b><b>bold</b>&lt;input&gt;end",
 									inlineBox.get("value").toLowerCase(),
@@ -347,30 +361,45 @@
 						timeout: 7000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("inlineRTE");
-							var handler = inlineBox.connect(inlineBox, 'edit',
-								function(){
-									inlineBox.disconnect(handler);
-									setTimeout(function(){
-										handler = inlineBox.connect(inlineBox, 'save',
-											function(){
-												inlineBox.disconnect(handler);
-												setTimeout(d.getTestCallback(function(){
-													doh.t(isHidden(inlineBox.wrapperWidget), "editor widget should visible");
-													doh.t(inlineBox.get("value").indexOf('!start!') >= 0, "value changed");
-												}), 1000);
-											});
-										doh.robot.typeKeys("!start!", 1, 1400);
-										var buttons = dojo.query(".saveButton", inlineBox.domNode.parentNode);
-										moveAndClick(buttons[buttons.length-1]);
-									}, 1000);
+							var inlineBox = registry.byId("inlineRTE");
+							var handler = aspect.after(inlineBox, 'edit', function(){
+								handler.remove();
+								handler = aspect.after(inlineBox, 'save', function(){
+									handler.remove();
+									setTimeout(d.getTestCallback(function(){
+										doh.t(helpers.isHidden(inlineBox.wrapperWidget), "editor widget should be visible");
+										doh.t(inlineBox.get("value").indexOf('!start!') >= 0, "value changed");
+									}), 1000);
 								});
+								robot.typeKeys("!start!", 1, 1400);
+								var buttons = query(".saveButton", inlineBox.domNode.parentNode);
+								moveAndClick(buttons[buttons.length-1]);
+							});
 							moveAndClick(inlineBox.domNode);
 							return d;
 						}
 					}
 				]);
 
+				doh.register("positioning", [
+					{
+						name: "offscreen",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var inlineBox = registry.byId("areaEditable");
+							inlineBox.edit();
+							moveAndClick("disableAreaEditable");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(inlineBox.get("disabled"), "disabled");
+								inlineBox.set('disabled', false);
+								inlineBox.cancel();
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/robot/Menu_a11y.html b/dijit/tests/robot/Menu_a11y.html
index 832922e..fc70375 100644
--- a/dijit/tests/robot/Menu_a11y.html
+++ b/dijit/tests/robot/Menu_a11y.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Menu Keyboard Tests</title>
+		<title>robot Menu Keyboard Tests</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -11,16 +11,23 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Menu.html');
-
-				doh.register("dijit.MenuBar general keyboard tests",[
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom", "dojo/dom-class", "dojo/dom-geometry",
+				"dojo/keys", "dojo/query", "dojo/sniff",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, dom, domClass, domGeom, keys, query, has, helpers){
+
+				robot.initRobot('../test_Menu.html');
+
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+					dfocus = robot.window.require("dijit/focus");
+				});
+
+				doh.register("dijit.MenuBar general keyboard tests", [
 					{
 						name: "start focus on the link, outside of menubar",
 						timeout: 5000,
@@ -28,13 +35,13 @@
 							var d = new doh.Deferred();
 
 							// Start at the link
-							doh.robot.sequence(function(){
-								dijit.focus(dojo.byId("link"));
+							robot.sequence(function(){
+								dom.byId("link").focus();
 							}, 500, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "something has focus");
-								doh.is("random link", dojo.global.dijit.focus.curNode.innerHTML, "check that focus is on the link");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(dfocus.curNode, "something has focus");
+								doh.is("random link", dfocus.curNode.innerHTML, "focus on the link");
 							}), 1000);
 
 							return d;
@@ -48,11 +55,10 @@
 							var d = new doh.Deferred();
 
 							// tab to the MenuBar... then focus should automatically shift to "File" menu,
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("File", dojo.trim(dojo.global.dijit.focus.curNode.innerText || dojo.global.dijit.focus.curNode.textContent),
-										"check that focus is on File menu");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("File", helpers.innerText(dfocus.curNode), "focus on File menu");
 							}), 1000);
 
 							return d;
@@ -65,11 +71,10 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Edit", dojo.trim(dojo.global.dijit.focus.curNode.innerText || dojo.global.dijit.focus.curNode.textContent),
-										"check that focus is on Edit MenuItem");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("Edit", helpers.innerText(dfocus.curNode), "focus on Edit MenuItem");
 							}), 1000);
 
 							return d;
@@ -82,11 +87,11 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
+							robot.keyPress(keys.TAB, 500, {shift:true});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("random link", dojo.trim(dojo.global.dijit.focus.curNode.innerText || dojo.global.dijit.focus.curNode.textContent),
-										"check that focus is back on the link");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("random link", helpers.innerText(dfocus.curNode),
+										"focus back on the link");
 							}), 1000);
 
 							return d;
@@ -100,19 +105,27 @@
 							var d = new doh.Deferred();
 
 							// Start at the link
-							doh.robot.sequence(function(){
-								dijit.focus(dojo.byId("link"));
+							robot.sequence(function(){
+								dom.byId("link").focus();
 							}, 500, 500);
 
 							// tab to the MenuBar... then focus should automatically shift to "File" menu
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
 							// and then down arrow to menu... focus should go to "New"
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t((dojo.global.dijit.focus.curNode.innerText || dojo.global.dijit.focus.curNode.textContent).indexOf("New") >= 0,
-										"check that focus is on New menu item of the File menu (indirectly checks that menu is visible)");
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("New", helpers.innerText(dfocus.curNode).substr(0, 3),
+										"focus on New menu item of the File menu (indirectly checks that menu is visible)");
+
+								// Check aria-labelledby property
+								var menuNode;
+								for(var menuNode = dfocus.curNode; menuNode.getAttribute("role") != "menu";
+									menuNode = menuNode.parentNode){}
+								var menuLabelNode = dom.byId(menuNode.getAttribute("aria-labelledby"), robot.doc),
+									menuLabel = helpers.innerText(menuLabelNode);
+								doh.is("File", menuLabel, "label of menu");
 							}), 1000);
 
 							return d;
@@ -126,15 +139,15 @@
 							var d = new doh.Deferred();
 
 							var clicked = false;
-							dijit.byId("new").onClick = function(){ clicked = true; };
+							registry.byId("new").onClick = function(){ clicked = true; };
 
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.t(clicked, "new was clicked");
-								doh.t(isHidden("fileMenu"), "File menu disappeared");
-								doh.f(dojo.hasClass("file", "dijitMenuItemSelected"),
-									"File MenuBarItem should no longer have selected effect, actual class is: " + dojo.byId("edit").className);
+								doh.t(helpers.isHidden("fileMenu"), "File menu disappeared");
+								doh.f(domClass.contains("file", "dijitMenuItemSelected"),
+									"File MenuBarItem should no longer have selected effect, actual class is: " + dom.byId("file").className);
 							}), 1000);
 
 							return d;
@@ -148,30 +161,22 @@
 							var d = new doh.Deferred();
 
 							// Start at the link
-							doh.robot.sequence(function(){
-								dijit.focus(dojo.byId("link"));
+							robot.sequence(function(){
+								dom.byId("link").focus();
 							}, 500, 500);
 
 							// tab to the MenuBar... then focus should automatically shift to "File" menu item
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
 							// and then move to "View" menu item
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-
-							// open the menu
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							// go down to "Zoom" menu item
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-
-							// open the submenu (landing on first item)
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t( (dojo.global.dijit.focus.curNode.innerText || dojo.global.dijit.focus.curNode.textContent).indexOf("50%") >= 0,
-										"check that focus is on '50%'");
-								doh.robot.keyPress(dojo.keys.ENTER, 0, {}, true); // close popup menus
+							robot.typeKeys("v", 500, 200);
+
+							// open the Zoom submenu (landing on first item)
+							robot.typeKeys("z", 500, 200);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(/50%/.test(helpers.innerText(dfocus.curNode)), "focus on '50%'");
+								robot.keyPress(keys.ENTER, 0, {}, true); // close popup menus
 							}), 1000, 500);
 
 							return d;
@@ -179,8 +184,182 @@
 					}
 				]);
 
+				doh.register("dijit.MenuBar focus after execute", [
+					{
+						name: "open edit menu",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Start at the link
+							robot.sequence(function(){
+								dom.byId("link").focus();
+							}, 500, 500);
+
+							// tab to the MenuBar... then focus should automatically shift to "File" menu
+							robot.keyPress(keys.TAB, 500, {});
+
+							// arrow to edit menu
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
+
+							// and then down arrow to menu... focus should go to "Cut"
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("Cut", helpers.innerText(dfocus.curNode).substr(0, 3));
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "click 'cut' using enter key",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.keyPress(keys.ENTER, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								// Although "Edit" is not marked as selected, and although the MenuBar is in passive
+								// mode, focus should be back on "Edit"
+								doh.is("Edit", helpers.innerText(dfocus.curNode), "focus back on Edit in MenuBar")
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "right arrow to view",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// arrow to view MenuBarItem
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("View", helpers.innerText(dfocus.curNode));
+								doh.t(domClass.contains(dom.byId("view"), "dijitMenuItemSelected"),
+										"View MenuBarItem should have selected class, actual class is:" + dom.byId("view").className);
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("dijit.MenuBar repeat open keyboard tests", [
+					{
+						name: "start focus on the link, outside of menubar",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Start at the link
+							robot.sequence(function(){
+								dom.byId("link").focus();
+							}, 500, 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(dfocus.curNode, "something has focus");
+								doh.is("random link", dfocus.curNode.innerHTML, "focus on the link");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "tab to the menubar",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// tab to the MenuBar... then focus should automatically shift to "File" menu,
+							robot.keyPress(keys.TAB, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("File", helpers.innerText(dfocus.curNode), "focus on File menu");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "open file menu #1",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("New", helpers.innerText(dfocus.curNode).substr(0, 3),
+										"focus on New MenuItem");
+							}), 500);
+
+							return d;
+						}
+					},
+
+					{
+						name: "close file menu #1",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.keyPress(keys.ENTER, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("File", helpers.innerText(dfocus.curNode),
+										"focus on File MenuBarItem again");
+							}), 500);
+
+							return d;
+						}
+					},
+
+					{
+						name: "open file menu #2",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("New", helpers.innerText(dfocus.curNode).substr(0, 3),
+										"focus on New MenuItem again");
+							}), 750);
+
+							return d;
+						}
+					},
+
+					{
+						name: "close file menu #2",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.keyPress(keys.ENTER, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("File", helpers.innerText(dfocus.curNode),
+										"focus on File MenuBarItem yet again");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
 				// Using left-arrow to back up (#10437)
-				doh.register("dijit.MenuBar left arrow tests",[
+				doh.register("dijit.MenuBar left arrow tests", [
 					{
 						name: "start focus on the link, outside of menubar",
 						timeout: 5000,
@@ -188,13 +367,13 @@
 							var d = new doh.Deferred();
 
 							// Start at the link
-							doh.robot.sequence(function(){
-								dijit.focus(dojo.byId("link"));
+							robot.sequence(function(){
+								dom.byId("link").focus();
 							}, 500, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "something has focus");
-								doh.is("random link", dojo.global.dijit.focus.curNode.innerHTML, "check that focus is on the link");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(dfocus.curNode, "something has focus");
+								doh.is("random link", dfocus.curNode.innerHTML, "focus on the link");
 							}), 1000);
 
 							return d;
@@ -208,11 +387,11 @@
 							var d = new doh.Deferred();
 
 							// tab to the MenuBar... then focus should automatically shift to "File" menu,
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("File", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
-										"check that focus is on File MenuItem");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("{F}ile", registry.getEnclosingWidget(dfocus.curNode).label,
+										"focus on File MenuItem");
 							}), 1000);
 
 							return d;
@@ -225,12 +404,12 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("View", dojo.trim(dojo.global.dijit.focus.curNode.innerText || dojo.global.dijit.focus.curNode.textContent),
-										"check that focus is on View MenuItem");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("View", helpers.innerText(dfocus.curNode),
+										"focus on View MenuItem");
 							}), 1000);
 
 							return d;
@@ -243,30 +422,30 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});	// focuses "Normal", first menu item
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});	// focuses "Outline", second menu item
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});	// focuses "Zoom", third menu item
+							robot.keyPress(keys.DOWN_ARROW, 500, {});	// focuses "Normal", first menu item
+							robot.keyPress(keys.DOWN_ARROW, 500, {});	// focuses "Outline", second menu item
+							robot.keyPress(keys.DOWN_ARROW, 500, {});	// focuses "Zoom", third menu item
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Zoom", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
-										"check that focus is on Zoom MenuItem");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("{Z}oom", registry.getEnclosingWidget(dfocus.curNode).label,
+										"focus on Zoom MenuItem");
 							}), 1000);
 
 							return d;
 						}
 					},
-					
+
 					{
 						name: "open the zoom menu",
 						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("50%", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
-										"check that focus is on Zoom MenuItem");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("50%", registry.getEnclosingWidget(dfocus.curNode).label,
+										"focus on Zoom MenuItem");
 							}), 1000);
 
 							return d;
@@ -279,20 +458,20 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							robot.keyPress(keys.LEFT_ARROW, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("{Z}oom", registry.getEnclosingWidget(dfocus.curNode).label,
+										"focus on Zoom MenuItem");
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Zoom", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
-										"check that focus is on Zoom MenuItem");
-										
-								doh.is(0, dojo.query("#zoomMenu .dijitMenuItemSelected").length,
+								doh.is(0, query("#zoomMenu .dijitMenuItemSelected").length,
 									"dijitMenuItemSelected removed from Zoom Menu")
 							}), 1000);
 
 							return d;
 						}
 					},
-					
+
 					{
 						name: "close View menu, back to MenuBar",
 						timeout: 5000,
@@ -301,13 +480,13 @@
 
 							// This should move focus to "Edit" in the MenuBar, which then opens
 							// the drop down and focuses on the first item (Cut)
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							robot.keyPress(keys.LEFT_ARROW, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Cut", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
-										"check that focus is on first MenuItem in Edit Menu");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("C{u}t", registry.getEnclosingWidget(dfocus.curNode).label,
+										"focus on first MenuItem in Edit Menu");
 
-								doh.is(0, dojo.query("#viewMenu .dijitMenuItemSelected").length,
+								doh.is(0, query("#viewMenu .dijitMenuItemSelected").length,
 									"dijitMenuItemSelected removed from View Menu")
 							}), 1000);
 
@@ -316,7 +495,7 @@
 					}
 				]);
 
-				doh.register("dijit.MenuBar nested click focus test",[
+				doh.register("dijit.MenuBar nested click focus test", [
 					{
 						name: "start focus on the link, outside of menubar",
 						timeout: 5000,
@@ -324,13 +503,13 @@
 							var d = new doh.Deferred();
 
 							// Start at the link
-							doh.robot.sequence(function(){
-								dojo.byId("link").focus();
+							robot.sequence(function(){
+								dom.byId("link").focus();
 							}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.global.dijit.focus.curNode, "something has focus");
-								doh.is("random link", dojo.global.dijit.focus.curNode.innerHTML, "check that focus is on the link");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(dfocus.curNode, "something has focus");
+								doh.is("random link", dfocus.curNode.innerHTML, "focus on the link");
 							}), 1000);
 
 							return d;
@@ -344,11 +523,11 @@
 							var d = new doh.Deferred();
 
 							// tab to the MenuBar... then focus should automatically shift to "File" menu,
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("File", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
-										"check that focus is on File MenuItem");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("{F}ile", registry.getEnclosingWidget(dfocus.curNode).label,
+										"focus on File MenuItem");
 							}), 1000);
 
 							return d;
@@ -361,12 +540,11 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});		// TODO: use left arrow in RTL mode
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("View", dojo.trim(dojo.global.dijit.focus.curNode.innerText || dojo.global.dijit.focus.curNode.textContent),
-										"check that focus is on View MenuItem");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("View", helpers.innerText(dfocus.curNode), "focus on View MenuItem");
 							}), 1000);
 
 							return d;
@@ -379,14 +557,14 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});	// focuses "Normal", first menu item
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});	// focuses "Outline", second menu item
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});	// focuses "Zoom", third menu item
+							robot.keyPress(keys.DOWN_ARROW, 250, {});	// focuses "Normal", first menu item
+							robot.keyPress(keys.DOWN_ARROW, 250, {});	// focuses "Outline", second menu item
+							robot.keyPress(keys.DOWN_ARROW, 250, {});	// focuses "Zoom", third menu item
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Zoom", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
-										"check that focus is on Zoom MenuItem");
-							}), 1000);
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("{Z}oom", registry.getEnclosingWidget(dfocus.curNode).label,
+										"focus on Zoom MenuItem");
+							}), 250);
 
 							return d;
 						}
@@ -398,11 +576,11 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 250, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("50%", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
-										"check that focus is on Zoom MenuItem");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("50%", registry.getEnclosingWidget(dfocus.curNode).label,
+										"focus on Zoom MenuItem");
 							}), 1000);
 
 							return d;
@@ -417,11 +595,11 @@
 
 							// This should move focus to "Edit" in the MenuBar, which then opens
 							// the drop down and focuses on the first item (Cut)
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("View", dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode).label,
-										"check that focus is on first View item in MenuBar");
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("{V}iew", registry.getEnclosingWidget(dfocus.curNode).label,
+										"focus on first View item in MenuBar");
 							}), 1000);
 
 							return d;
@@ -429,9 +607,90 @@
 					}
 				]);
 
+				doh.register("dijit.MenuBar MenuBarItem tests", [
+					{
+						name: "navigate to MenuBarItem",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Start at the link
+							robot.sequence(function(){
+								dom.byId("link").focus();
+							}, 500, 500);
+
+							// tab to the MenuBar... then focus should automatically shift to "File" menu,
+							robot.keyPress(keys.TAB, 500, {});
+
+							// arrow six times gets to "Click me!"
+							for(var i=0; i<6; i++){
+								robot.keyPress(keys.RIGHT_ARROW, 250, {});		// TODO: use left arrow in RTL mode
+							}
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("Click me! (Z)", helpers.innerText(dfocus.curNode),
+										"focus on MenuBarItem");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "down arrow",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// down arrow... should have no effect since there's no menu
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("Click me! (Z)", helpers.innerText(dfocus.curNode),
+										"focus is still on MenuBarItem");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "click",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var clicked;
+							robot.window.noPopupMenuBarItem.on("click", function(){ clicked = true; });
+
+							robot.keyPress(keys.SPACE, 250, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(clicked, "clicked");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "right arrow",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// right arrow show go back to File menu
+							robot.keyPress(keys.RIGHT_ARROW, 250, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("File", helpers.innerText(dfocus.curNode), "focus moved to File menu");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
 				// Run test about opening context menu via keyboard, except on safari/mac where that isn't
 				// possible (#9927)
-				if(!dojo.isMac || !dojo.isWebKit){
+				if(!has("mac") || !has("webkit")){
 					doh.register("Context menu keyboard tests", [{
 						name: "open global context menu (keyboard)",
 						timeout: 5000,
@@ -439,34 +698,37 @@
 							var d = new doh.Deferred();
 
 							// Put focus on the link; this is just a random place on the screen to have focus
-							doh.robot.sequence(function(){
-								dijit.focus(dojo.byId("link"));
+							robot.sequence(function(){
+								dom.byId("link").focus();
 							}, 500, 500);
 
 							// open via keyboard
-							if(dojo.isMac){
-								doh.robot.keyPress(dojo.keys.SPACE, 500, {
+							if(has("mac")){
+								robot.keyPress(keys.SPACE, 500, {
 									ctrl: true
 								});
 							}else{
-								doh.robot.keyPress(dojo.keys.F10, 500, {
+								robot.keyPress(keys.F10, 500, {
 									shift: true
 								});
 							}
 
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								var menu = dijit.byId("windowContextMenu");
-								doh.t(isVisible(menu), "menu is now shown");
+							robot.sequence(d.getTestCallback(function(){
+								var menu = registry.byId("windowContextMenu");
+								doh.t(helpers.isVisible(menu), "menu is now shown");
 
-								var menuCoords = dojo.position(menu.domNode),
-									linkCoords = dojo.position("link");
+								var menuCoords = domGeom.position(menu.domNode),
+									linkCoords = domGeom.position("link");
 
 								doh.t(menuCoords.x < 100, "x < 100", "actual x: " + menuCoords.x);
 								doh.t(menuCoords.y < 50, "y < 50", "actual y: " + menuCoords.y);
 								doh.t(menuCoords.x >= 0, "x >= 0", "actual x: " + menuCoords.x);
 								doh.t(menuCoords.y >= 0, "y >= 0", "actual y: " + menuCoords.y);
-								doh.robot.keyPress(dojo.keys.ESCAPE, 0, {}, true); // close context menu
+								doh.t(domClass.contains("windowContextMenuFirstChoice", "dijitMenuItemSelected"),
+										"first choice selected");
+
+								robot.keyPress(keys.ESCAPE, 0, {}, true); // close context menu
 							}), 1000);
 
 							return d;
@@ -482,74 +744,283 @@
 							var d = new doh.Deferred();
 
 							// Start at the link
-							doh.robot.sequence(function(){
-								dijit.focus(dojo.byId("link"));
+							robot.sequence(function(){
+								dom.byId("link").focus();
 							}, 500, 500);
 
 							// tab to the MenuBar... then focus should automatically shift to "File" menu,
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {}); // open File menu
+							robot.keyPress(keys.DOWN_ARROW, 500, {}); // open File menu
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("fileMenu"), "File menu should be visible");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("fileMenu"), "File menu should be visible");
 							}), 1000);
 
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {}); // close File menu
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isHidden("fileMenu"), "File menu is hidden after cancel");
-								doh.t(dojo.hasClass("file", "dijitMenuItemSelected"),
-									"File MenuBarItem should have selected class, actual class is: " + dojo.byId("file").className);
+							robot.keyPress(keys.ESCAPE, 250, {}); // close File menu
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isHidden("fileMenu"), "File menu is hidden after cancel");
+								doh.t(domClass.contains("file", "dijitMenuItemSelected"),
+									"File MenuBarItem should have selected class, actual class is: " + dom.byId("file").className);
 							}), 1000);
 
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {}); // move to Edit menu
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.f(dojo.hasClass("file", "dijitMenuItemSelected"),
-									"File MenuBarItem should not have selected class, actual class is: " + dojo.byId("file").className);
-								doh.t(isHidden("editMenu"), "Edit menu is hidden after cancel and select");
-								doh.t(dojo.hasClass("edit", "dijitMenuItemSelected"),
-									"Edit MenuBarItem should have selected class, actual class is: " + dojo.byId("edit").className);
+							robot.keyPress(keys.RIGHT_ARROW, 250, {}); // move to Edit menu
+							robot.sequence(d.getTestErrback(function(){
+								doh.f(domClass.contains("file", "dijitMenuItemSelected"),
+									"File MenuBarItem should not have selected class, actual class is: " + dom.byId("file").className);
+								doh.t(helpers.isHidden("editMenu"), "Edit menu is hidden after cancel and select");
+								doh.t(domClass.contains("edit", "dijitMenuItemSelected"),
+									"Edit MenuBarItem should have selected class, actual class is: " + dom.byId("edit").className);
+							}), 500);
+
+							robot.typeKeys("e", 250, 1000); // open Edit menu
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("editMenu"), "edit menu appeared");
 							}), 1000);
 
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {}); // open Edit menu
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {}); // move to copy more slowly
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {}); // move to paste option
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {}); // click paste, closing edit menu
+							robot.typeKeys("p", 250, 300); // select paste
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isHidden("editMenu"), "edit menu disappeared");
-								dijit.focus(dojo.byId("link"));
-							}), 1000, 500);
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isHidden("editMenu"), "edit menu disappeared");
+							}), 1000);
 
-							// tab to the MenuBar... then focus should automatically shift to "File" menu,
-							doh.robot.keyPress(dojo.keys.TAB, 500, {}); // move to File
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isHidden("fileMenu"), "File menu should be hidden");
+							robot.typeKeys("f", 250, 300); // open File menu
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("fileMenu"), "File menu should be visible");
 							}), 1000);
 
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {}); // open File menu
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("fileMenu"), "File menu should be visible");
+							robot.keyPress(keys.RIGHT_ARROW, 75, {}); // #9846
+							robot.keyPress(keys.RIGHT_ARROW, 75, {}); // move to View menu
+							robot.keyPress(keys.LEFT_ARROW, 75, {}); // move to Edit menu
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("editMenu"), "Edit menu should be visible and File menu hidden");
+								doh.t(helpers.isHidden("fileMenu"), "File menu should be hidden and Edit menu visible");
 							}), 1000);
 
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 75, {}); // #9846
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 75, {}); // move to View menu
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 75, {}); // move to Edit menu
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("editMenu"), "Edit menu should be visible and File menu hidden");
-								doh.t(isHidden("fileMenu"), "File menu should be hidden and Edit menu visible");
+							robot.keyPress(keys.ESCAPE, 250, {}); // close Edit menu
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("editMenu"), "edit menu disappeared");
 							}), 1000);
 
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {}); // close Edit menu
+							return d;
+						}
+					}
+				]);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("editMenu"), "edit menu disappeared");
+				doh.register("CheckedMenuItem", [
+					{
+						name: "initial conditions",
+						runTest: function(){
+							doh.is("true", registry.byId("checked1").domNode.getAttribute("aria-checked"), "checked1 aria-checked");
+							doh.t(registry.byId("checked1").checked, "checked1 value");
+							doh.is("false", registry.byId("checked2").domNode.getAttribute("aria-checked"), "checked2 aria-checked");
+							doh.f(registry.byId("checked2").checked, "checked2 value");
+						}
+					},
+
+					{
+						name: "nav to checked1",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Start at the link
+							robot.sequence(function(){
+								dom.byId("link").focus();
+							}, 500, 500);
+
+							// tab to the MenuBar, then to the left hand menu
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+
+							// down arrow to "checked 1"
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("checked1", dfocus.curNode.getAttribute("id"), "focus on checked1");
 							}), 1000);
 
 							return d;
 						}
+					},
+
+					{
+						name: "click checked1",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.keyPress(keys.SPACE, 250, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.f(registry.byId("checked1").checked, "checked1 --> unchecked");
+							}), 500);
+
+							return d;
+						}
+					},
+
+					{
+						name: "nav to checked2",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("checked2", dfocus.curNode.getAttribute("id"), "focus on checked2");
+							}), 500);
+
+							return d;
+						}
+					},
+
+					{
+						name: "click checked2",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.keyPress(keys.SPACE, 250, {});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(registry.byId("checked2").checked, "checked2 --> checked");
+							}), 500);
+
+							return d;
+						}
 					}
 				]);
+
+				doh.register("keyboard search", [
+					{
+						name: "multi-char search failure",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							dom.byId("link").focus();
+
+							// tab to the MenuBar, then to the left hand menu
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+							robot.keyPress(keys.DOWN_ARROW, 250, {});
+							robot.keyPress(keys.RIGHT_ARROW, 250, {});
+							robot.typeKeys("sd", 500, 400); // multi-char letter search should fail
+
+							robot.sequence(d.getTestCallback(function(){
+								var menu = registry.byId("navMenuSub2");
+								doh.f(helpers.isVisible(menu), "sub-sub-menu is not shown");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "search with SPACE",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.typeKeys("submenu Item t", 600, 2000); // multi letter search should work
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("Submenu Item Two", registry.getEnclosingWidget(dfocus.curNode).label, "focus on second MenuItem in sub Menu");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "search with full text to make sure it's found",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.typeKeys("sUBMENU iTEM oNE", 600, 3000); // multi letter search should work
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("Submenu Item One", registry.getEnclosingWidget(dfocus.curNode).label, "focus on second MenuItem in sub Menu");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "search with full text to make sure it's moving",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.typeKeys("submenu item two", 600, 3000); // multi letter search should work
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("Submenu Item Two", registry.getEnclosingWidget(dfocus.curNode).label, "focus on second MenuItem in sub Menu");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "search again with the same full text to make sure it's not just picking the next item",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.typeKeys("submenu item two", 600, 3000); // multi letter search should work
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("Submenu Item Two", registry.getEnclosingWidget(dfocus.curNode).label, "focus on second MenuItem in sub Menu");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "search opens sub-menu",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.typeKeys("sds", 600, 3500); // single letter search should work after long delays
+
+							robot.sequence(d.getTestCallback(function(){
+								var menu = registry.byId("navMenuSub2");
+								doh.t(helpers.isVisible(menu), "sub-sub-menu is shown");
+								doh.is("Sub-sub-menu Item Two", registry.getEnclosingWidget(dfocus.curNode).label, "focus on second MenuItem in sub-sub Menu");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "SPACE closes menu after keyboard search",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.typeKeys(" ", 600, 300);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.f(helpers.isVisible(registry.byId("navMenuSub1")), "sub-menu is shown");
+								doh.f(helpers.isVisible(registry.byId("navMenuSub2")), "sub-sub-menu is shown");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/robot/Menu_iframe.html b/dijit/tests/robot/Menu_iframe.html
index f3a8b5a..dabfffc 100644
--- a/dijit/tests/robot/Menu_iframe.html
+++ b/dijit/tests/robot/Menu_iframe.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Menu iframe Test</title>
+		<title>robot Menu iframe Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,37 +10,42 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 			
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom", "dojo/dom-style", "dojo/keys", "dojo/_base/lang", "dojo/query",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, dom, domClass, keys, lang, query, helpers){
+
+				robot.initRobot('../test_Menu_iframe.html');
+
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+				});
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Menu_iframe.html');
-					
 				var handler, menu;
-				doh.register("TestMenuIFrame",[
+				doh.register("TestMenuIFrame", [
 					{
 						name: "detachMenu",
-						timeout: 4000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							menu = dijit.byId("menu");
+							menu = registry.byId("menu");
 							handler = menu.connect(menu, 'onOpen', function(){ d.errback(new doh._AssertFailure('user context menu should not have opened')); });
-							doh.robot.mouseMoveAt("detachMenu", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("iframe", 1000, 1);
-							doh.robot.sequence(function(){
-								doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
+							robot.mouseMoveAt("detachMenu", 500, 1);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("iframe", 1000, 1);
+							robot.sequence(function(){
+								robot.keyPress(keys.ESCAPE, 1000, {}, true);
 							}, 0);
-							doh.robot.mouseClick({right:true}, 500);
+							robot.mouseClick({right:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.f(isVisible(menu.domNode), "menu hidden");
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								doh.f(helpers.isVisible(menu.domNode), "menu hidden");
 							})), 1000);
 
 							return d;
@@ -51,21 +56,21 @@
 					},
 					{
 						name: "reattachMenu",
-						timeout: 5000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							dojo.global.scrollTo(0,0);
-							doh.robot.mouseMove(30, 30, 500);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("reattachMenu", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("iframe", 500, 1);
-							doh.robot.mouseClick({right:true}, 500);
+							robot.window.scrollTo(0,0);
+							robot.mouseMove(30, 30, 500);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("reattachMenu", 500, 1);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("iframe", 500, 1);
+							robot.mouseClick({right:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								var menu = dijit.byId("menu");
-								doh.t(isVisible(menu.domNode), "menu visible");
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								var menu = registry.byId("menu");
+								doh.t(helpers.isVisible(menu.domNode), "menu visible");
 							})), 1000);
 
 							return d;
@@ -73,22 +78,21 @@
 					},
 					{
 						name: "resetToDoc",
-						timeout: 4000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("resetToDoc", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("iframe", 500, 1);
-							doh.robot.mouseClick({right:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								var menu = dijit.byId("menu");
-								doh.t(isVisible(menu.domNode), "menu visible");
-
-								var iframe = dojo.byId("iframe");
-								var heading = dojo.withGlobal(iframe.contentWindow,'query', dojo, ["h1"])[0];
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("resetToDoc", 500, 1);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("iframe", 500, 1);
+							robot.mouseClick({right:true}, 500);
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								var menu = registry.byId("menu");
+								doh.t(helpers.isVisible(menu.domNode), "menu visible");
+
+								var iframe = dom.byId("iframe");
+								var heading = query("h1", iframe.contentWindow.document)[0];
 								doh.is("Document 0", heading.innerHTML, "heading.innerHTML");
 							})), 1000);
 
@@ -97,22 +101,22 @@
 					},
 					{
 						name: "detachMenu2",
-						timeout: 4000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							menu = dijit.byId("menu");
+							menu = registry.byId("menu");
 							handler = menu.connect(menu, 'onOpen', function(){ d.errback(new doh._AssertFailure('user context menu should not have opened')); });
-							doh.robot.mouseMoveAt("detachMenu", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("iframe", 1000, 1);
-							doh.robot.sequence(function(){
-								doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
+							robot.mouseMoveAt("detachMenu", 500, 1);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("iframe", 1000, 1);
+							robot.sequence(function(){
+								robot.keyPress(keys.ESCAPE, 1000, {}, true);
 							}, 0);
-							doh.robot.mouseClick({right:true}, 500);
+							robot.mouseClick({right:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.f(isVisible(menu.domNode), "menu hidden");
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								doh.f(helpers.isVisible(menu.domNode), "menu hidden");
 							})), 1000);
 
 							return d;
@@ -123,21 +127,21 @@
 					},
 					{
 						name: "reattachMenu2",
-						timeout: 5000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							dojo.global.scrollTo(0,0);
-							doh.robot.mouseMove(30, 30, 500);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("reattachMenu", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("iframe", 500, 1);
-							doh.robot.mouseClick({right:true}, 500);
+							robot.window.scrollTo(0,0);
+							robot.mouseMove(30, 30, 500);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("reattachMenu", 500, 1);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("iframe", 500, 1);
+							robot.mouseClick({right:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								var menu = dijit.byId("menu");
-								doh.t(isVisible(menu.domNode), "menu visible");
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								var menu = registry.byId("menu");
+								doh.t(helpers.isVisible(menu.domNode), "menu visible");
 							})), 1000);
 
 							return d;
@@ -145,22 +149,22 @@
 					},
 					{
 						name: "resetToBill",
-						timeout: 4000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("resetToBill", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("iframe", 500, 1);
-							doh.robot.mouseClick({right:true}, 500);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("resetToBill", 500, 1);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("iframe", 500, 1);
+							robot.mouseClick({right:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								var menu = dijit.byId("menu");
-								doh.t(isVisible(menu.domNode), "menu visible");
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								var menu = registry.byId("menu");
+								doh.t(helpers.isVisible(menu.domNode), "menu visible");
 
-								var iframe = dojo.byId("iframe");
-								var div = dojo.withGlobal(iframe.contentWindow,'query', dojo, ["div"])[0];
+								var iframe = dom.byId("iframe");
+								var div = query("div", iframe.contentWindow.document)[0];
 								doh.is("bill was here", div.innerHTML, "div.innerHTML");
 							})), 1000);
 
@@ -169,22 +173,22 @@
 					},
 					{
 						name: "detachMenu3",
-						timeout: 4000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							menu = dijit.byId("menu");
+							menu = registry.byId("menu");
 							handler = menu.connect(menu, 'onOpen', function(){ d.errback(new doh._AssertFailure('user context menu should not have opened')); });
-							doh.robot.mouseMoveAt("detachMenu", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("iframe", 1000, 1);
-							doh.robot.sequence(function(){
-								doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
+							robot.mouseMoveAt("detachMenu", 500, 1);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("iframe", 1000, 1);
+							robot.sequence(function(){
+								robot.keyPress(keys.ESCAPE, 1000, {}, true);
 							}, 0);
-							doh.robot.mouseClick({right:true}, 500);
+							robot.mouseClick({right:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.f(isVisible(menu.domNode), "menu hidden");
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								doh.f(helpers.isVisible(menu.domNode), "menu hidden");
 							})), 1000);
 
 							return d;
@@ -195,21 +199,21 @@
 					},
 					{
 						name: "reattachMenu3",
-						timeout: 5000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							dojo.global.scrollTo(0,0);
-							doh.robot.mouseMove(30, 30, 500);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("reattachMenu", 500, 1);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("iframe", 500, 1);
-							doh.robot.mouseClick({right:true}, 500);
+							robot.window.scrollTo(0,0);
+							robot.mouseMove(30, 30, 500);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("reattachMenu", 500, 1);
+							robot.mouseClick({left:true}, 500);
+							robot.mouseMoveAt("iframe", 500, 1);
+							robot.mouseClick({right:true}, 500);
 							
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								var menu = dijit.byId("menu");
-								doh.t(isVisible(menu.domNode), "menu visible");
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								var menu = registry.byId("menu");
+								doh.t(helpers.isVisible(menu.domNode), "menu visible");
 							})), 1000);
 
 							return d;
diff --git a/dijit/tests/robot/Menu_mouse.html b/dijit/tests/robot/Menu_mouse.html
index d989af6..160a836 100644
--- a/dijit/tests/robot/Menu_mouse.html
+++ b/dijit/tests/robot/Menu_mouse.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Menu Mouse Tests</title>
+		<title>robot Menu Mouse Tests</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -11,14 +11,19 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom", "dojo/dom-class", "dojo/dom-geometry", "dojo/keys",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, dom, domClass, domGeom, keys, helpers){
+
+				robot.initRobot('../test_Menu.html');
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Menu.html');
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+				});
 
 				doh.register("dijit.MenuBar mouse tests", [
 
@@ -29,20 +34,20 @@
 							var d = new doh.Deferred();
 
 							// Check initial conditions
-							doh.f(dojo.hasClass("file", "dijitMenuItemHover"), "File MenuBarItem doesn't have hover effect");
-							doh.t(isHidden("fileMenu"), "File menu is hidden");
+							doh.f(domClass.contains("file", "dijitMenuItemHover"), "File MenuBarItem doesn't have hover effect");
+							doh.t(helpers.isHidden("fileMenu"), "File menu is hidden");
 
 							// Move over the File MenuBarItem
-							doh.robot.mouseMoveAt("file", 500, 1000);
+							robot.mouseMoveAt("file", 500, 1000);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// The "File" MenuBarItem should be highlighted
-								doh.t(dojo.hasClass("file", "dijitMenuItemHover"),
-									"File MenuBarItem should have hover effect, actual class is: " + dojo.byId("file").className);
+								doh.t(domClass.contains("file", "dijitMenuItemHover"),
+									"File MenuBarItem should have hover effect, actual class is: " + dom.byId("file").className);
 
 								// However, just moving over the MenuBarItem shouldn't have opened the menu
-								doh.t(isHidden("fileMenu"), "File menu is hidden");
-							}), 1000);	// 1000ms == give IE time to make that backgroune iframe
+								doh.t(helpers.isHidden("fileMenu"), "File menu is hidden");
+							}), 1000);	// 1000ms == give IE time to make that background iframe
 
 							return d;
 						}
@@ -55,23 +60,23 @@
 							var d = new doh.Deferred();
 
 							// click the File MenuBarItem
-							doh.robot.mouseMoveAt("file", 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt("file", 500, 1);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// The "File" MenuBarItem should have the selected class in addition to the hover
 								// class
-								doh.t(dojo.hasClass("file", "dijitMenuItemHover"),
-									"File MenuBarItem should have hover effect, actual class is: " + dojo.byId("file").className);
-								doh.t(dojo.hasClass("file", "dijitMenuItemSelected"),
-									"File MenuBarItem should have selected class, actual class is: " + dojo.byId("file").className);
+								doh.t(domClass.contains("file", "dijitMenuItemHover"),
+									"File MenuBarItem should have hover effect, actual class is: " + dom.byId("file").className);
+								doh.t(domClass.contains("file", "dijitMenuItemSelected"),
+									"File MenuBarItem should have selected class, actual class is: " + dom.byId("file").className);
 
 								// And the file menu should be visible
-								doh.t(isVisible("fileMenu"), "File menu is visible");
+								doh.t(helpers.isVisible("fileMenu"), "File menu is visible");
 
-								// And the first item in the file menu should be selected
-								doh.t(dojo.hasClass("new", "dijitMenuItemSelected"),
-									"New MenuItem should have selected class, actual class is: " + dojo.byId("new").className);
+								// But the first item in the file menu should not be selected, since we opened via mouse not keyboard (#10716)
+								doh.f(domClass.contains("new", "dijitMenuItemSelected"),
+									"New MenuItem should not have selected class, actual class is: " + dom.byId("new").className);
 							}), 1000);
 
 							return d;
@@ -84,15 +89,15 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("edit", 500, 500);
+							robot.mouseMoveAt("edit", 500, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// Since we've already activated the MenuBar by clicking "File",
 								// hovering over "Edit" should automatically show the edit menu
-								doh.t(isVisible("editMenu"), "Edit menu is visible");
+								doh.t(helpers.isVisible("editMenu"), "Edit menu is visible");
 
 								// And also, the file menu should have disappeared
-								doh.t(isHidden("fileMenu"), "File menu is hidden");
+								doh.t(helpers.isHidden("fileMenu"), "File menu is hidden");
 							}), 500);
 
 							return d;
@@ -105,18 +110,18 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("copy", 500, 500);
+							robot.mouseMoveAt("copy", 500, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.f(dojo.hasClass("edit", "dijitMenuItemHover"),
-									"Edit MenuBarItem shouldn't have hover effect anymore, actual class is: " + dojo.byId("edit").className);
-								doh.t(dojo.hasClass("edit", "dijitMenuItemSelected"),
-									"Edit MenuBarItem should still have selected class, actual class is: " + dojo.byId("edit").className);
+							robot.sequence(d.getTestCallback(function(){
+								doh.f(domClass.contains("edit", "dijitMenuItemHover"),
+									"Edit MenuBarItem shouldn't have hover effect anymore, actual class is: " + dom.byId("edit").className);
+								doh.t(domClass.contains("edit", "dijitMenuItemSelected"),
+									"Edit MenuBarItem should still have selected class, actual class is: " + dom.byId("edit").className);
 
-								doh.t(dojo.hasClass("copy", "dijitMenuItemHover"),
-									"Copy Menu item should have hover effect, actual class is: " + dojo.byId("copy").className);
-								doh.t(dojo.hasClass("copy", "dijitMenuItemSelected"),
-									"Copy Menu item should have selected effect, actual class is: " + dojo.byId("copy").className);
+								doh.t(domClass.contains("copy", "dijitMenuItemHover"),
+									"Copy Menu item should have hover effect, actual class is: " + dom.byId("copy").className);
+								doh.t(domClass.contains("copy", "dijitMenuItemSelected"),
+									"Copy Menu item should have selected effect, actual class is: " + dom.byId("copy").className);
 							}), 500);
 
 							return d;
@@ -129,16 +134,16 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var w = dijit.byId("copy");
+							var w = registry.byId("copy");
 							var orig = w.onClick;
 							w.onClick = d.getTestCallback(function(){
 								w.onClick = orig;
-								doh.t(isHidden("editMenu"), "edit menu disappeared");
-								doh.f(dojo.hasClass("edit", "dijitMenuItemSelected"),
-									"Edit MenuBarItem should no longer have selected effect, actual class is: " + dojo.byId("edit").className);
+								doh.t(helpers.isHidden("editMenu"), "edit menu disappeared");
+								doh.f(domClass.contains("edit", "dijitMenuItemSelected"),
+									"Edit MenuBarItem should no longer have selected effect, actual class is: " + dom.byId("edit").className);
 							});
 
-							doh.robot.mouseClick({left: true}, 1);
+							robot.mouseClick({left: true}, 1);
 
 							return d;
 						}
@@ -151,24 +156,24 @@
 							var d = new doh.Deferred();
 
 							// Check initial conditions
-							doh.f(dojo.hasClass("file", "dijitMenuItemHover"), "File MenuBarItem doesn't have hover effect");
-							doh.t(isHidden("fileMenu"), "File menu is hidden");
+							doh.f(domClass.contains("file", "dijitMenuItemHover"), "File MenuBarItem doesn't have hover effect");
+							doh.t(helpers.isHidden("fileMenu"), "File menu is hidden");
 
 							// Move over the File MenuBarItem
-							doh.robot.mouseMoveAt("file", 500, 500);
+							robot.mouseMoveAt("file", 500, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// The "File" MenuBarItem should be highlighted
-								doh.t(dojo.hasClass("file", "dijitMenuItemHover"),
-									"File MenuBarItem should have hover effect, actual class is: " + dojo.byId("file").className);
+								doh.t(domClass.contains("file", "dijitMenuItemHover"),
+									"File MenuBarItem should have hover effect, actual class is: " + dom.byId("file").className);
 
 								// However, it shouldn't be "selected", and
 								// just moving over the MenuBarItem shouldn't have opened the menu,
 								// given that after clicking above, the MenuBar should have reverted to it's
 								// "dormant" state so that it needs to be clicked again before menus show up automatically
-								doh.f(dojo.hasClass("file", "dijitMenuItemSelected"),
-									"File MenuBarItem shouldn't have selected effect, actual class is: " + dojo.byId("file").className);
-								doh.t(isHidden("fileMenu"), "File menu is hidden");
+								doh.f(domClass.contains("file", "dijitMenuItemSelected"),
+									"File MenuBarItem shouldn't have selected effect, actual class is: " + dom.byId("file").className);
+								doh.t(helpers.isHidden("fileMenu"), "File menu is hidden");
 							}), 500);
 
 							return d;
@@ -186,18 +191,18 @@
 							var d = new doh.Deferred();
 
 							// Check initial conditions
-							doh.f(dojo.hasClass("navMenuPopupItem1", "dijitMenuItemHover"), "navMenuPopupItem1 MenuItem doesn't have hover effect");
-							doh.t(isHidden("navMenuSub1"), "sub menu is hidden");
+							doh.f(domClass.contains("navMenuPopupItem1", "dijitMenuItemHover"), "navMenuPopupItem1 MenuItem doesn't have hover effect");
+							doh.t(helpers.isHidden("navMenuSub1"), "sub menu is hidden");
 
-							doh.robot.mouseMoveAt("navMenuPopupItem1", 500, 500);
+							robot.mouseMoveAt("navMenuPopupItem1", 500, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// The "enabled submenu" MenuItem should be highlighted
-								doh.t(dojo.hasClass("navMenuPopupItem1", "dijitMenuItemHover"),
-									"'Enabled Submenu' MenuItem should have hover effect, actual class is: " + dojo.byId("navMenuPopupItem1").className);
+								doh.t(domClass.contains("navMenuPopupItem1", "dijitMenuItemHover"),
+									"'Enabled Submenu' MenuItem should have hover effect, actual class is: " + dom.byId("navMenuPopupItem1").className);
 
 								// However, just moving over the MenuItem shouldn't have opened the menu
-								doh.t(isHidden("navMenuSub1"), "sub menu is hidden");
+								doh.t(helpers.isHidden("navMenuSub1"), "sub menu is hidden");
 							}), 500);
 
 							return d;
@@ -210,20 +215,20 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dojo.hasClass("navMenuPopupItem1", "dijitMenuItemHover"),
-									"'Enabled Submenu' MenuItem should have hover effect, actual class is: " + dojo.byId("navMenuPopupItem1").className);
-								doh.t(dojo.hasClass("navMenuPopupItem1", "dijitMenuItemSelected"),
-									"'Enabled Submenu' MenuItem should have selected effect, actual class is: " + dojo.byId("navMenuPopupItem1").className);
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(domClass.contains("navMenuPopupItem1", "dijitMenuItemHover"),
+									"'Enabled Submenu' MenuItem should have hover effect, actual class is: " + dom.byId("navMenuPopupItem1").className);
+								doh.t(domClass.contains("navMenuPopupItem1", "dijitMenuItemSelected"),
+									"'Enabled Submenu' MenuItem should have selected effect, actual class is: " + dom.byId("navMenuPopupItem1").className);
 
 								// And the sub menu should be visible
-								doh.t(isVisible("navMenuSub1"), "sub menu is visible");
+								doh.t(helpers.isVisible("navMenuSub1"), "sub menu is visible");
 
-								// And the first item in the sub menu should be selected
-								doh.t(dojo.hasClass("navMenuSub1_item1", "dijitMenuItemSelected"),
-									"first item in sub menu should have selected class, actual class is: " + dojo.byId("new").className);
+								// But the first item in the sub menu should be selected, since opened by mouse, see #10716
+								doh.f(domClass.contains("navMenuSub1_item1", "dijitMenuItemSelected"),
+									"first item in sub menu should have selected class, actual class is: " + dom.byId("new").className);
 							}), 1000);
 
 							return d;
@@ -236,13 +241,13 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.f(dijit.byId("checked2").get('checked'), "not initially checked");
+							doh.f(registry.byId("checked2").get('checked'), "not initially checked");
 
-							doh.robot.mouseMoveAt("checked2", 500, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt("checked2", 500, 1);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dijit.byId("checked2").get('checked'), "now it's checked");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(registry.byId("checked2").get('checked'), "now it's checked");
 							}), 500);
 
 							return d;
@@ -257,24 +262,26 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var menu = dijit.byId("windowContextMenu");
+							var menu = registry.byId("windowContextMenu");
 
-							doh.t(isHidden(menu), "menu should be initially hidden");
+							doh.t(helpers.isHidden(menu), "menu should be initially hidden");
 
 							// click random point on screen
-							doh.robot.mouseMoveAt("link", 500, 500);
-							doh.robot.mouseClick({right: true}, 500);
+							robot.mouseMoveAt("link", 500, 500);
+							robot.mouseClick({right: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible(menu), "menu is now shown");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible(menu), "menu is now shown");
 
-								var linkCoords = dojo.position("link");
-									menuCoords = dojo.position(menu.domNode);
+								var linkCoords = domGeom.position("link");
+									menuCoords = domGeom.position(menu.domNode);
 
 								doh.t(menuCoords.x > linkCoords.x, "to right of link left edge");
 								doh.t(menuCoords.x < linkCoords.x + linkCoords.w, "to left of link right edge");
 								doh.t(menuCoords.y > linkCoords.y, "menu (" + menuCoords.y + ") starts below top of link (" + linkCoords.y + ")");
 								doh.t(menuCoords.y < linkCoords.y + linkCoords.h, "menu (" + menuCoords.y + ") starts above bottom of link (" + linkCoords.y + "+" + linkCoords.h + ")");
+
+								doh.f(domClass.contains("windowContextMenuFirstChoice", "dijitMenuItemSelected"), "first choice not marked as selected");
 							}), 1000);
 
 							return d;
@@ -287,14 +294,14 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var menu = dijit.byId("windowContextMenu");
+							var menu = registry.byId("windowContextMenu");
 
 							// close menu from above test
-							doh.robot.mouseMove(2, 2, 100);
-							doh.robot.mouseClick({left: true}, 100);
+							robot.mouseMove(2, 2, 100);
+							robot.mouseClick({left: true}, 100);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden(menu), "menu should be hidden again");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden(menu), "menu should be hidden again");
 							}), 500);
 
 							return d;
@@ -307,26 +314,30 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 	
-							var menu = dijit.byId("windowContextMenu");
+							var menu = registry.byId("windowContextMenu");
 	
-							doh.t(isHidden(menu), "menu should be initially hidden");
+							doh.t(helpers.isHidden(menu), "menu should be initially hidden");
 	
 							// right-click on form widget
-							doh.robot.mouseMoveAt("formwidget", 500, 1);
-							doh.robot.mouseClick({right: true}, 500);
-	
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible(menu), "menu is now shown");
-	
-								var widgetCoords = dojo.position("formwidget");
-									menuCoords = dojo.position(menu.domNode);
+							robot.mouseMoveAt("formwidget", 500, 1);
+							robot.mouseClick({right: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible(menu), "menu is now shown");
 	
+								var widgetCoords = domGeom.position("formwidget");
+									menuCoords = domGeom.position(menu.domNode);
+
 								doh.t(((menuCoords.x > widgetCoords.x) && (menuCoords.x < (widgetCoords.x + widgetCoords.w))) ||
 									(((menuCoords.x + menuCoords.w) > widgetCoords.x) && ((menuCoords.x + menuCoords.w) < (widgetCoords.x + widgetCoords.w))),
 									"begins or ends within the form widget horizontal boundaries");
 								doh.t(((menuCoords.y > widgetCoords.y) && (menuCoords.y < (widgetCoords.y + widgetCoords.h))) ||
 									(((menuCoords.y + menuCoords.h) > widgetCoords.y) && ((menuCoords.y + menuCoords.h) < (widgetCoords.y + widgetCoords.h))),
 									"begins or ends within the form widget vertical boundaries");
+
+								var cm = dom.byId("windowContextMenu");
+								doh.is("region", cm.parentNode.getAttribute("role"), "context menu's wrapper node needs role=region");
+                				doh.is("windowContextMenu", cm.parentNode.getAttribute("aria-label"), "menu's wrapper node needs aria-label");
 							}), 1000);
 	
 							return d;
@@ -339,14 +350,14 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var menu = dijit.byId("windowContextMenu");
+							var menu = registry.byId("windowContextMenu");
 
 							// close menu from above test
-							doh.robot.mouseMove(2, 2, 100);
-							doh.robot.mouseClick({left: true}, 100);
+							robot.mouseMove(2, 2, 100);
+							robot.mouseClick({left: true}, 100);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden(menu), "menu should be hidden again");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden(menu), "menu should be hidden again");
 							}), 1000);
 
 							return d;
@@ -361,83 +372,83 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("file", 500, 1000);
-							doh.robot.mouseClick({left: true}, 500); // click File
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("fileMenu"), "File menu should be visible #1");
+							robot.mouseMoveAt("file", 500, 1000);
+							robot.mouseClick({left: true}, 500); // click File
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("fileMenu"), "File menu should be visible #1");
 							}), 1000);
 
-							doh.robot.mouseClick({left: true}, 500); // close File menu
-							doh.robot.mouseMoveAt("edit", 500, 500);
+							robot.mouseClick({left: true}, 500); // close File menu
+							robot.mouseMoveAt("edit", 500, 500);
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isHidden("fileMenu"), "File menu is hidden #1");
-								doh.t(isHidden("editMenu"), "Edit menu is hidden #1");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isHidden("fileMenu"), "File menu is hidden #1");
+								doh.t(helpers.isHidden("editMenu"), "Edit menu is hidden #1");
 
-								doh.f(dojo.hasClass("file", "dijitMenuItemSelected"),
-									"File MenuBarItem should not have selected class, actual class is: " + dojo.byId("file").className);
-								doh.f(dojo.hasClass("file", "dijitMenuItemHover"),
-									"File MenuBarItem shouldn't have hover effect anymore, actual class is: " + dojo.byId("edit").className);
-								doh.t(dojo.hasClass("edit", "dijitMenuItemHover"),
-									"Edit MenuBarItem should have hover effect, actual class is: " + dojo.byId("edit").className);
+								doh.f(domClass.contains("file", "dijitMenuItemSelected"),
+									"File MenuBarItem should not have selected class, actual class is: " + dom.byId("file").className);
+								doh.f(domClass.contains("file", "dijitMenuItemHover"),
+									"File MenuBarItem shouldn't have hover effect anymore, actual class is: " + dom.byId("edit").className);
+								doh.t(domClass.contains("edit", "dijitMenuItemHover"),
+									"Edit MenuBarItem should have hover effect, actual class is: " + dom.byId("edit").className);
 							}), 1000);
 
-							doh.robot.mouseClick({left: true}, 500); // open edit menu
-							doh.robot.mouseMoveAt("paste", 1000, 1);
-							doh.robot.mouseClick({left: true}, 500); // click paste, closing edit menu
-							doh.robot.mouseMoveAt("edit", 1000, 500);
+							robot.mouseClick({left: true}, 500); // open edit menu
+							robot.mouseMoveAt("paste", 1000, 1);
+							robot.mouseClick({left: true}, 500); // click paste, closing edit menu
+							robot.mouseMoveAt("edit", 1000, 500);
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.hasClass("edit", "dijitMenuItemHover"),
-									"Edit MenuBarItem should still have hover effect, actual class is: " + dojo.byId("edit").className);
-								doh.t(isHidden("editMenu"), "edit menu disappeared #1");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(domClass.contains("edit", "dijitMenuItemHover"),
+									"Edit MenuBarItem should still have hover effect, actual class is: " + dom.byId("edit").className);
+								doh.t(helpers.isHidden("editMenu"), "edit menu disappeared #1");
 							}), 1000);
 
-							doh.robot.mouseMoveAt("file", 500, 500);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isHidden("fileMenu"), "File menu should be hidden #2");
+							robot.mouseMoveAt("file", 500, 500);
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isHidden("fileMenu"), "File menu should be hidden #2");
 							}), 500);
 
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								var
-								fileMenu = dijit.byId("fileMenu"),
-								editMenu = dijit.byId("editMenu"),
+								fileMenu = registry.byId("fileMenu"),
+								editMenu = registry.byId("editMenu"),
 								handler = fileMenu.connect(fileMenu, 'onOpen',
 									function(){
 										fileMenu.disconnect(handler);
 										setTimeout(d.getTestErrback(function(){
-											doh.t(isVisible(fileMenu), "File menu should be visible #2");
+											doh.t(helpers.isVisible(fileMenu), "File menu should be visible #2");
 											handler = fileMenu.connect(fileMenu, 'onClose',
 												function(){
 													fileMenu.disconnect(handler);
 													setTimeout(d.getTestErrback(function(){
-														doh.t(isHidden(fileMenu), "File menu should be hidden #3");
+														doh.t(helpers.isHidden(fileMenu), "File menu should be hidden #3");
 														handler = editMenu.connect(editMenu, 'onOpen',
 															function(){
 																editMenu.disconnect(handler);
 																setTimeout(d.getTestErrback(function(){
-																	doh.t(isVisible(editMenu), "Edit menu should be visible");
+																	doh.t(helpers.isVisible(editMenu), "Edit menu should be visible");
 																	handler = editMenu.connect(editMenu, 'onClose',
 																		function(){
 																			editMenu.disconnect(handler);
 																			setTimeout(d.getTestCallback(function(){
-																				doh.t(isHidden(editMenu), "Edit menu disappeared #2");
+																				doh.t(helpers.isHidden(editMenu), "Edit menu disappeared #2");
 																			}), 150);
 																		});
-																	var paste = dojo.position('paste');
-																	doh.robot._mouseMove(paste.x + (paste.w >> 1), paste.y + paste.h + 20, false, 1);
+																	var paste = domGeom.position('paste');
+																	robot._mouseMove(paste.x + (paste.w >> 1), paste.y + paste.h + 20, false, 1);
 																	// click point on screen under the Edit menu
-																	doh.robot.mouseClick({left: true}, 100);
+																	robot.mouseClick({left: true}, 100);
 																}), 150);
 															});
-														doh.robot.mouseMoveAt("edit", 0, 1);
+														robot.mouseMoveAt("edit", 0, 1);
 													}), 150);
 												});
-											doh.robot.mouseMoveAt("view", 0, 1); // #9846
+											robot.mouseMoveAt("view", 0, 1); // #9846
 										}), 150);
 									});
 							}, 1);
-							doh.robot.mouseClick({left: true}, 1); // click File that starts the event sequence above
+							robot.mouseClick({left: true}, 1); // click File that starts the event sequence above
 
 							return d;
 						}
@@ -450,41 +461,43 @@
 							var d = new doh.Deferred();
 
 							// click random point on screen
-							doh.robot.mouseMoveAt("link", 500, 500);
-							doh.robot.mouseClick({left: true}, 500); // click link to focus it
-
-							doh.robot.mouseMoveAt("view", 500, 500);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.hasClass("view", "dijitMenuItemHover"),
-									"View MenuBarItem should have hover effect, actual class is: " + dojo.byId("view").className);
-								doh.t(isHidden("viewMenu"), "View menu is hidden");
+							robot.mouseMoveAt("link", 500, 500);
+							robot.mouseClick({left: true}, 500); // click link to focus it
+
+							robot.mouseMoveAt("view", 500, 500);
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(domClass.contains("view", "dijitMenuItemHover"),
+									"View MenuBarItem should have hover effect, actual class is: " + dom.byId("view").className);
+								doh.t(helpers.isHidden("viewMenu"), "View menu is hidden");
 							}), 500);
 
 							// tab to the MenuBar... then focus should automatically shift to "File" menu,
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isHidden("fileMenu"), "File menu is hidden");
-								doh.t(dojo.hasClass("file", "dijitMenuItemSelected"),
-									"File MenuBarItem should have selected class, actual class is: " + dojo.byId("file").className);
-								doh.f(dojo.hasClass("view", "dijitMenuItemHover"),
-									"View MenuBarItem shouldn't have hover effect anymore, actual class is: " + dojo.byId("view").className);
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isHidden("fileMenu"), "File menu is hidden");
+								doh.t(domClass.contains("file", "dijitMenuItemSelected"),
+									"File MenuBarItem should have selected class, actual class is: " + dom.byId("file").className);
+								doh.f(domClass.contains("view", "dijitMenuItemHover"),
+									"View MenuBarItem shouldn't have hover effect anymore, actual class is: " + dom.byId("view").className);
 							}), 1000);
 
-							doh.robot.mouseMoveAt("edit", 500, 500);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(dojo.hasClass("edit", "dijitMenuItemHover"),
-									"Edit MenuBarItem should have hover effect, actual class is: " + dojo.byId("edit").className);
-								doh.t(isHidden("editMenu"), "View menu is hidden");
+							robot.mouseMoveAt("edit", 500, 500);
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(domClass.contains("edit", "dijitMenuItemHover"),
+									"Edit MenuBarItem should have hover effect, actual class is: " + dom.byId("edit").className);
+								doh.t(helpers.isHidden("editMenu"), "View menu is hidden");
 							}), 500);
 
-							// move to View item with keyboard
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000, {});
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("viewMenu"), "View menu is hidden");
-								doh.t(dojo.hasClass("view", "dijitMenuItemSelected"),
-									"View MenuBarItem should have selected class, actual class is: " + dojo.byId("file").className);
-								doh.f(dojo.hasClass("edit", "dijitMenuItemHover"),
-									"Edit MenuBarItem shouldn't have hover effect anymore, actual class is: " + dojo.byId("edit").className);
+							// Move to View item with keyboard.  Focus should still on "File".  Previously this test
+							// assumed that hovering "edit" would move focus there.
+							robot.keyPress(keys.RIGHT_ARROW, 1000, {});
+							robot.keyPress(keys.RIGHT_ARROW, 1000, {});
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("viewMenu"), "View menu is hidden");
+								doh.t(domClass.contains("view", "dijitMenuItemSelected"),
+									"View MenuBarItem should have selected class, actual class is: " + dom.byId("file").className);
+								doh.f(domClass.contains("edit", "dijitMenuItemHover"),
+									"Edit MenuBarItem shouldn't have hover effect anymore, actual class is: " + dom.byId("edit").className);
 							}), 1000);
 
 							return d;
@@ -499,50 +512,50 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("navMenuPopupItem1", 500, 500); // move to Enabled submenu
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isHidden("navMenuSub1"), "Enabled submenu should be hidden");
+							robot.mouseMoveAt("navMenuPopupItem1", 500, 500); // move to Enabled submenu
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isHidden("navMenuSub1"), "Enabled submenu should be hidden");
 							}), 500);
 
-							doh.robot.mouseClick({left: true}, 500); // click Enabled Submenu
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("navMenuSub1"), "Enabled submenu should be visible");
+							robot.mouseClick({left: true}, 500); // click Enabled Submenu
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("navMenuSub1"), "Enabled submenu should be visible");
 							}), 1000);
 
-							doh.robot.mouseMoveAt("navMenuDisabledItem", 500, 500);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isHidden("navMenuSub1"), "Enabled submenu should be hidden");
+							robot.mouseMoveAt("navMenuDisabledItem", 500, 500);
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isHidden("navMenuSub1"), "Enabled submenu should be hidden");
 							}), 1000); // linger long enough for menu to close
 
-							doh.robot.mouseMoveAt("navMenuPopupItem1", 500, 500); // move back to Enabled submenu
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("navMenuSub1"), "Enabled submenu should be visible");
+							robot.mouseMoveAt("navMenuPopupItem1", 500, 500); // move back to Enabled submenu
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("navMenuSub1"), "Enabled submenu should be visible");
 							}), 1000); // linger long enough for menu to open
 
-							doh.robot.mouseMoveAt("navMenuDisabledItem", 500, 50); // QUICKLY move to the next menu item
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.mouseMoveAt("navMenuDisabledItem", 500, 50); // QUICKLY move to the next menu item
+							robot.sequence(d.getTestErrback(function(){
 							}), 200, 50);
 
-							doh.robot.mouseMoveAt("navMenuSub1_item2", 0, 50); // QUICKLY move to the popup menu
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("navMenuSub1"), "Enabled submenu 1 should be visible");
-								doh.t(dojo.hasClass("navMenuSub1_item2", "dijitMenuItemHover"),
-									"Submenu 1, item 2 navigation MenuItem should have hover effect, actual class is: " + dojo.byId("navMenuDisabledItem").className);
-								doh.t(dojo.hasClass("navMenuPopupItem1", "dijitMenuItemSelected"),
-									"'Enabled Submenu' MenuItem should have selected effect, actual class is: " + dojo.byId("navMenuPopupItem1").className);
-								var popup = dojo.position('navMenuSub1_popup');
-								doh.robot._mouseMove(popup.x + (popup.w >> 1), popup.y + popup.h + 20, false, 500);
+							robot.mouseMoveAt("navMenuSub1_item2", 0, 50); // QUICKLY move to the popup menu
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("navMenuSub1"), "Enabled submenu 1 should be visible");
+								doh.t(domClass.contains("navMenuSub1_item2", "dijitMenuItemHover"),
+									"Submenu 1, item 2 navigation MenuItem should have hover effect, actual class is: " + dom.byId("navMenuDisabledItem").className);
+								doh.t(domClass.contains("navMenuPopupItem1", "dijitMenuItemSelected"),
+									"'Enabled Submenu' MenuItem should have selected effect, actual class is: " + dom.byId("navMenuPopupItem1").className);
+								var popup = domGeom.position('navMenuSub1_popup');
+								robot._mouseMove(popup.x + (popup.w >> 1), popup.y + popup.h + 20, false, 500);
 							}), 500, 1000);
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("navMenuSub1"), "Enabled submenu 1 menu still there");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("navMenuSub1"), "Enabled submenu 1 menu still there");
 							}), 1000);
 
 							// click point on screen under the menu
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("navMenuSub1"), "Enabled submenu 1 menu disappeared");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("navMenuSub1"), "Enabled submenu 1 menu disappeared");
 							}), 1000);
 
 							return d;
@@ -550,8 +563,77 @@
 					}
 				]);
 
+				doh.register("passivePopupDelay", [
+					function setup(){
+						registry.byId("menubar").set("passivePopupDelay", 300);
+					},
+					{
+						name: "mouse over file MenuBarItem",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Check initial conditions
+							doh.f(domClass.contains("file", "dijitMenuItemHover"), "File MenuBarItem doesn't have hover effect");
+							doh.t(helpers.isHidden("fileMenu"), "File menu is hidden");
+
+							// Move over the File MenuBarItem
+							robot.mouseMoveAt("file", 500, 1000);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("fileMenu"), "File menu is visible");
+								doh.f(domClass.contains("new", "dijitMenuItemSelected"),
+										"New MenuItem should not have selected class, actual class is: " + dom.byId("new").className);
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "hover edit menu item",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.mouseMoveAt("edit", 500, 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								// Since we've already activated the MenuBar by clicking "File",
+								// hovering over "Edit" should automatically show the edit menu
+								doh.t(helpers.isVisible("editMenu"), "Edit menu is visible");
+
+								// And also, the file menu should have disappeared
+								doh.t(helpers.isHidden("fileMenu"), "File menu is hidden");
+							}), 500);
+
+							return d;
+						}
+					},
+
+
+					{
+						name: "close menu by click",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.mouseMoveAt("link", 500, 500);
+							robot.mouseClick({left: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.f(helpers.isVisible("editMenu"), "Edit menu is hidden");
+							}), 500);
+
+							return d;
+						}
+					}
+
+				]);
+
+
 				doh.run();
 			});
 		</script>
 	</head>
-</html>
\ No newline at end of file
+</html>
diff --git a/dijit/tests/robot/TitlePane.html b/dijit/tests/robot/TitlePane.html
index b0bc360..b9edc6d 100644
--- a/dijit/tests/robot/TitlePane.html
+++ b/dijit/tests/robot/TitlePane.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot TitlePane Test</title>
+		<title>robot TitlePane Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,17 +10,22 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dojo.window");
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/aspect", "dojo/dom", "dojo/keys", "dojo/_base/lang", "dojo/query", "dojo/window",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, aspect, dom, keys, lang, query, winUtils, helpers){
+
+				robot.initRobot('../test_TitlePane.html');
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_TitlePane.html');
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+					dfocus = robot.window.require("dijit/focus");
+				});
 
 				var pane1, pane2, pane3, href1, href2;
 
@@ -28,23 +33,23 @@
 					{
 						name: "setup",
 						runTest: function(){
-					    	pane1 = dijit.byId("testPane1");
-					    	pane2 = dijit.byId("pane_2");
-					    	pane3 = dijit.byId("closed");		// initially closed
-							href1 = dijit.byId("href1");	// initially closed href, href load completes after expand
-							href2 = dijit.byId("href2");	// initially closed href, href load completes during expand
+					    	pane1 = registry.byId("testPane1");
+					    	pane2 = registry.byId("pane_2");
+					    	pane3 = registry.byId("closed");		// initially closed
+							href1 = registry.byId("href1");	// initially closed href, href load completes after expand
+							href2 = registry.byId("href2");	// initially closed href, href load completes during expand
 						}
 					},
 					{
 						name: "title",
 						runTest: function(){
 							doh.is("Title Pane #1", pane1.get("title"), "title attr");
-							doh.is("Title Pane #1", innerText(pane1.titleNode), "inner text");
+							doh.is("Title Pane #1", helpers.innerText(pane1.titleNode), "inner text");
 							
 							pane1.set("title", "modified title");
 
 							doh.is("modified title", pane1.get("title"), "title attr modified");
-							doh.is("modified title", innerText(pane1.titleNode), "inner text modified");
+							doh.is("modified title", helpers.innerText(pane1.titleNode), "inner text modified");
 						}
 					},
 
@@ -59,7 +64,7 @@
 
 							pane1.set("open", false);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.t(pane1.domNode.offsetHeight < 100, "pane 1 is closed");
 								doh.f(pane1.get("open"), "pane1.open is false");
 							}), 500);
@@ -76,27 +81,27 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							dijit.focus(dojo.byId("input"));
+							dom.byId("input").focus();
 
 							// should go to title bar
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is(pane1.focusNode, dojo.global.dijit.focus.curNode,"focused on pane1 title")
+							robot.sequence(d.getTestErrback(function(){
+								doh.is(pane1.focusNode, dfocus.curNode,"focused on pane1 title")
 							}), 500);
 
 							// should skip hidden content and go to button
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is(dojo.byId("titleButton"), dojo.global.dijit.focus.curNode,"focused on title button after pane")
+							robot.sequence(d.getTestErrback(function(){
+								doh.is(dom.byId("titleButton"), dfocus.curNode,"focused on title button after pane")
 							}), 500);
 
 							// go back to title bar
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
+							robot.keyPress(keys.TAB, 500, {shift: true});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(pane1.focusNode, dojo.global.dijit.focus.curNode,"focused on pane1 title")
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(pane1.focusNode, dfocus.curNode,"focused on pane1 title")
 							}), 500);
 
 							return d;
@@ -109,9 +114,9 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.SPACE, 500);
+							robot.keyPress(keys.SPACE, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.t(pane1.domNode.offsetHeight > 100, "pane 1 is open");
 								doh.t(pane1.get("open"), "pane1.open is true");
 							}), 500);
@@ -126,9 +131,9 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.ENTER, 500);
+							robot.keyPress(keys.ENTER, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.t(pane1.domNode.offsetHeight < 100, "pane 1 is closed");
 							}), 500);
 							
@@ -146,29 +151,29 @@
 
 							var height1, height2, height3;
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								pane1.set("open", true);
 							}), 500);
 
 							// Changing the content while open should change the height
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								height1 = pane1.domNode.offsetHeight;
 								pane1.set("content", pane1.get("content") + "<br>new line");
 							}), 500);
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								height2 = pane1.domNode.offsetHeight;
 								doh.t(height2 > height1,  "expected height increase, actually went from " + height1 + " to " + height2);
 							}), 500);
 
 							// Change the content while closed should also change the height (when it is next opened)
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								pane1.set("open", false);
 							}), 500);
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								pane1.set("content", pane1.get("content") + "<br>another new line");
 								pane1.set("open", true);
 							}), 500);
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								height3 = pane1.domNode.offsetHeight;
 								doh.t(height3 > height2, "expected height increase, actually went from " + height2 + " to " + height3);
 							}), 500);
@@ -183,21 +188,21 @@
 							var d = new doh.Deferred();
 
 							// Open the href pane, causing the href to load
-							dojo.window.scrollIntoView(dijit.byId("inner").domNode);
-							doh.robot.sequence(d.getTestErrback(function(){
+							winUtils.scrollIntoView(registry.byId("inner").domNode);
+							robot.sequence(d.getTestErrback(function(){
 								href1.set("open", true);
 							}), 1000);
 
 							// Initially it should display "Loading..." with a small height (enough for that one message)
 							var height1, height2;
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("Loading...", dojo.trim(innerText(href1.containerNode)));
+							robot.sequence(d.getTestErrback(function(){
+								doh.is("Loading...", lang.trim(helpers.innerText(href1.containerNode)));
 								height1 = href1.domNode.offsetHeight;
 							}), 1500);
 
 							// Then the real content should be loaded and height should change to accommodate it
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.isNot("Loading...", dojo.trim(innerText(href1.containerNode)), "actual content");
+							robot.sequence(d.getTestCallback(function(){
+								doh.isNot("Loading...", lang.trim(helpers.innerText(href1.containerNode)), "actual content");
 								height2 = href1.domNode.offsetHeight;
 								doh.t(height2 > height1, "expected height increase, actually went from " + height1 + " to " + height2);
 							}), 3000);
@@ -215,7 +220,7 @@
 							// will finish.   Make sure height shows full content
 							href2.set("open", true);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								var height = href2.domNode.offsetHeight;
 								doh.t(height > 100, "height for full content not just loading message: " + height);
 							}), 2000);
@@ -234,11 +239,11 @@
 
 							// The first time pane3 is opened the tab container should get a resize event
 							var resized = false;
-							dojo.connect(dijit.byId("tabContainer"), "resize", function(){ resized = true;});
+							aspect.after(registry.byId("tabContainer"), "resize", function(){ resized = true;}, true);
 
 							doh.f(pane3.get("open"), "pane3 is closed");
 							pane3.set("open", true);
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.t(resized, "tabcontainer was resized");
 							}), 500);
 							
@@ -253,10 +258,10 @@
 						runTest: function(){
 							// none of the TitlePane's inside of the AccordionContainer should have loaded
 							// their href, since they are closed
-					    	doh.f(dojo.global["actp1Loaded"], "closed TitlePane in open accordion pane not loaded");
-					    	doh.t(dojo.global["actp2Loaded"], "open TitlePane in open accordion pane loaded");
-					    	doh.f(dojo.global["actp3Loaded"], "first TitlePane in closed accordion pane not loaded");
-					    	doh.f(dojo.global["actp4Loaded"], "open TitlePane in closed accordion pane not loaded");
+					    	doh.f(robot.window["actp1Loaded"], "closed TitlePane in open accordion pane not loaded");
+					    	doh.t(robot.window["actp2Loaded"], "open TitlePane in open accordion pane loaded");
+					    	doh.f(robot.window["actp3Loaded"], "first TitlePane in closed accordion pane not loaded");
+					    	doh.f(robot.window["actp4Loaded"], "open TitlePane in closed accordion pane not loaded");
 						}
 					},
 
@@ -266,12 +271,12 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							dijit.byId("ac").selectChild(dijit.byId("accp2"));
+							registry.byId("ac").selectChild(registry.byId("accp2"));
 
 							setTimeout(d.getTestCallback(function(){
-						    	doh.f(dojo.global["actp1Loaded"], "closed TitlePane in newly closed accordion pane not loaded");
-						    	doh.f(dojo.global["actp3Loaded"], "closed TitlePane in newly opened accordion pane not loaded");
-						    	doh.t(dojo.global["actp4Loaded"], "opened TitlePane in newly opened accordion pane loaded");
+						    	doh.f(robot.window["actp1Loaded"], "closed TitlePane in newly closed accordion pane not loaded");
+						    	doh.f(robot.window["actp3Loaded"], "closed TitlePane in newly opened accordion pane not loaded");
+						    	doh.t(robot.window["actp4Loaded"], "opened TitlePane in newly opened accordion pane loaded");
 							}), 500);
 							
 							return d;
@@ -284,10 +289,10 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							dijit.byId("actp3").set("open", true);
+							registry.byId("actp3").set("open", true);
 
 							setTimeout(d.getTestCallback(function(){
-						    	doh.t(dojo.global["actp3Loaded"], "opening TitlePane causes href to load");
+						    	doh.t(robot.window["actp3Loaded"], "opening TitlePane causes href to load");
 							}), 500);
 							
 							return d;
diff --git a/dijit/tests/robot/Toolbar.html b/dijit/tests/robot/Toolbar.html
index 8a1dd8b..d3971b4 100644
--- a/dijit/tests/robot/Toolbar.html
+++ b/dijit/tests/robot/Toolbar.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Toolbar Test</title>
+		<title>robot Toolbar Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,27 +10,34 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Toolbar.html');
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/_base/array", "dojo/dom", "dojo/keys", "dojo/_base/lang", "dojo/query",
+				"dojo/domReady!"
+			], function(doh, robot, array, dom, keys, lang, query){
+				robot.initRobot('../test_Toolbar.html');
+
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+					dfocus = robot.window.require("dijit/focus");
+
+					toolbar1Before = dom.byId("toolbar1Before");
+					toolbar1 = registry.byId("toolbar1");
+					toolbar1After = dom.byId("toolbar1After");
+					toolbar2 = registry.byId("toolbar2");
+					toolbar3 = registry.byId("toolbar3");
+					toolbar4 = registry.byId("toolbar4");
+				});
 
 				var toolbar1Before, toolbar1After, toolbar1, toolbar2, toolbar3, toolbar4;
 
-				doh.register("initial conditions",[
+				doh.register("initial conditions", [
 					{
 						name: "creation",
-						setUp: function(){
-							toolbar1Before = dojo.byId("toolbar1Before");
-					    	toolbar1 = dijit.byId("toolbar1");
-							toolbar1After = dojo.byId("toolbar1After");
-					    	toolbar2 = dijit.byId("toolbar2");
-					    	toolbar3 = dijit.byId("toolbar3");
-					    	toolbar4 = dijit.byId("toolbar4");							
-						},
 						runTest: function(){
 							// make sure that all the toolbars exist
 							doh.t(toolbar1, "toolbar 1");
@@ -39,44 +46,44 @@
 							doh.t(toolbar4, "toolbar 4");
 							
 							// and that labels are shown except when showLabel==false
-							var cutText = dojo.query(".dijitButtonText", dojo.byId("toolbar1.cut"))[0];
+							var cutText = query(".dijitButtonText", dom.byId("toolbar1.cut"))[0];
 							doh.is(0, cutText.offsetWidth, "cut button - text hidden");						
 
-							var copyText = dojo.query(".dijitButtonText", dojo.byId("toolbar1.copy"))[0];
+							var copyText = query(".dijitButtonText", dom.byId("toolbar1.copy"))[0];
 							doh.t(copyText.offsetWidth > 0, "copy button - text shown");						
 						}
 					}
 				]);
 					
-				doh.register("keyboard",[
+				doh.register("keyboard", [
 					{
 						name: "tab in and out",
 						timeout: 20000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
 								toolbar1Before.focus();
 							})), 500);
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.cut", dojo.global.dijit.focus.curNode.id, "cut, first visit");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1.cut", dfocus.curNode.id, "cut, first visit");
 							})), 1000);
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1After", dojo.global.dijit.focus.curNode.id);
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1After", dfocus.curNode.id);
 							})), 1000);
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.cut", dojo.global.dijit.focus.curNode.id, "cut, second visit");
+							robot.keyPress(keys.TAB, 500, {shift: true});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1.cut", dfocus.curNode.id, "cut, second visit");
 							})), 1000);
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is("toolbar1Before", dojo.global.dijit.focus.curNode.id, "back before toolbar1");
+							robot.keyPress(keys.TAB, 500, {shift: true});
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								doh.is("toolbar1Before", dfocus.curNode.id, "back before toolbar1");
 							})), 1000);
 
 							return d;
@@ -92,36 +99,36 @@
 							// Disable a bunch of buttons to make sure that left/right arrow
 							// keys skip over disabled buttons, and also that initial focus
 							// goes to the first enabled button
-							dojo.forEach(["toolbar1.cut", "toolbar1.copy", "toolbar1.bold", "toolbar1.backcolor",
+							array.forEach(["toolbar1.cut", "toolbar1.copy", "toolbar1.bold", "toolbar1.backcolor",
 								"toolbar1.forecolor", "toolbar1.combo2"], function(widgetName){
-								dijit.byId(widgetName).set("disabled", true);
+								registry.byId(widgetName).set("disabled", true);
 							});
 
 							// Initial focus (upon tabbing into toolbar) should go to first enabled button
 							toolbar1Before.focus();
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.italic", dojo.global.dijit.focus.curNode.id, "italic, first visit");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1.italic", dfocus.curNode.id, "italic, first visit");
 							})), 1000);
 
 							// Remaining enabled positions that left/right arrow should navigate to (not including the initial leftmost button),
 							var focusPoints = ["toolbar1.dialog", "toolbar1.combo_button", "toolbar1.combo_arrow", "toolbar1.insertorderedlist"];
 
 							// Use right arrow key to visit every enabled button (and for combobutton to hit left and right sides)
-							dojo.forEach(focusPoints, function(str){
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-								doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-									doh.is(str, dojo.global.dijit.focus.curNode.id, str + ", first visit");
+							array.forEach(focusPoints, function(str){
+								robot.keyPress(keys.RIGHT_ARROW, 500, {});
+								robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+									doh.is(str, dfocus.curNode.id, str + ", first visit");
 								})), 1000);
 							});
 
 							// Now go backwards
 							focusPoints.reverse();
 							focusPoints.shift();
-							dojo.forEach(focusPoints, function(str){
-								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
-								doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-									doh.is(str, dojo.global.dijit.focus.curNode.id, str + ", second visit");
+							array.forEach(focusPoints, function(str){
+								robot.keyPress(keys.LEFT_ARROW, 500, {});
+								robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+									doh.is(str, dfocus.curNode.id, str + ", second visit");
 								})), 1000);
 							});
 
@@ -130,20 +137,20 @@
 							// is in the correct position in the tab order (ie, the position specified
 							// for the toolbar itself), and that there are no stray tabstops on the toolbar itself
 							// or on the other buttons. 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1After", dojo.global.dijit.focus.curNode.id, "first time past toolbar1");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1After", dfocus.curNode.id, "first time past toolbar1");
 							})), 1000);
 
 							// Make sure that we can still shift-tab back to before the toolbar too
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.italic", dojo.global.dijit.focus.curNode.id, "italic, after shift-tab back into toolbar");
+							robot.keyPress(keys.TAB, 500, {shift: true});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1.italic", dfocus.curNode.id, "italic, after shift-tab back into toolbar");
 							})), 1000);
 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is("toolbar1Before", dojo.global.dijit.focus.curNode.id, "back before toolbar1");
+							robot.keyPress(keys.TAB, 500, {shift: true});
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								doh.is("toolbar1Before", dfocus.curNode.id, "back before toolbar1");
 							})), 1000);
 
 							return d;
@@ -159,22 +166,22 @@
 							// Initial focus (upon tabbing into toolbar) should go to first enabled button,
 							// which is "italic", since "cut" and "copy" are disabled
 							toolbar1Before.focus();
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.italic", dojo.global.dijit.focus.curNode.id, "first button");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1.italic", dfocus.curNode.id, "first button");
 							})), 1000);
 
 							// End key should go to last button
-							doh.robot.keyPress(dojo.keys.END, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.insertorderedlist", dojo.global.dijit.focus.curNode.id, "last button");
+							robot.keyPress(keys.END, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1.insertorderedlist", dfocus.curNode.id, "last button");
 							})), 1000);
 
 							// Home key should go to first enabled button again
 							// which is "italic", since "cut" and "copy" are disabled
-							doh.robot.keyPress(dojo.keys.HOME, 500, {});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is("toolbar1.italic", dojo.global.dijit.focus.curNode.id, "first button again");
+							robot.keyPress(keys.HOME, 500, {});
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
+								doh.is("toolbar1.italic", dfocus.curNode.id, "first button again");
 							})), 1000);
 
 							return d;
@@ -190,79 +197,79 @@
 							var d = new doh.Deferred();
 
 							// Re-enable the ToolipDialog and ColorPalette drop down so that we can test it
-							dijit.byId("toolbar1.dialog").set("disabled", false);
-							dijit.byId("toolbar1.backcolor").set("disabled", false);
+							registry.byId("toolbar1.dialog").set("disabled", false);
+							registry.byId("toolbar1.backcolor").set("disabled", false);
 
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
 								toolbar1Before.focus();
 							})), 500);
 
 							// Tab into toolbar and move to tooltip dialog button
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.RIGHT_ARROW, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.dialog", dojo.global.dijit.focus.curNode.id, "dialog button, first visit");
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1.dialog", dfocus.curNode.id, "dialog button, first visit");
 							})), 1000);
 
 							// Open the dialog, focus should go to first input
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("user", dojo.global.dijit.focus.curNode.id);
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("user", dfocus.curNode.id);
 							})), 1000);
 
 							// ESC should restore focus to toolbar dialog button
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.dialog", dojo.global.dijit.focus.curNode.id, "dialog button, second visit");
+							robot.keyPress(keys.ESCAPE, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1.dialog", dfocus.curNode.id, "dialog button, second visit");
 							})), 1000);
 
 							// Open the dialog again
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("user", dojo.global.dijit.focus.curNode.id, "user, again");
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("user", dfocus.curNode.id, "user, again");
 							})), 1000);
 
 							// Submit should also restore focus to toolbar dialog button, assuming that it
 							// doesn't reset the focus somewhere else (like into the editor)
-							doh.robot.keyPress(dojo.keys.TAB, 500);
-							doh.robot.keyPress(dojo.keys.TAB, 500);
-							doh.robot.keyPress(dojo.keys.ENTER, 500);
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.dialog", dojo.global.dijit.focus.curNode.id, "dialog button, third visit");
+							robot.keyPress(keys.TAB, 500);
+							robot.keyPress(keys.TAB, 500);
+							robot.keyPress(keys.ENTER, 500);
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1.dialog", dfocus.curNode.id, "dialog button, third visit");
 							})), 1000);
 
 							// Try the ColorPalette
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500);
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.t(dojo.isDescendant(dojo.global.dijit.focus.curNode, dijit.byId("toolbar1.colorPalette").domNode),
-									"focus inside colorpalette, actual focus is: " + (dojo.global.dijit.focus.curNode ?
-										(dojo.global.dijit.focus.curNode.id||"no id") : "no focus"));
+							robot.keyPress(keys.RIGHT_ARROW, 500);
+							robot.keyPress(keys.DOWN_ARROW, 500);
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.t(dom.isDescendant(dfocus.curNode, registry.byId("toolbar1.colorPalette").domNode),
+									"focus inside colorpalette, actual focus is: " + (dfocus.curNode ?
+										(dfocus.curNode.id||"no id") : "no focus"));
 							})), 1000);
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500);	// navigation in the ColorPalette
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);	// navigation in the ColorPalette
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.t(dojo.isDescendant(dojo.global.dijit.focus.curNode, dijit.byId("toolbar1.colorPalette").domNode),
-									"focus still inside colorpalette, actual focus is: " + (dojo.global.dijit.focus.curNode ?
-										(dojo.global.dijit.focus.curNode.id||"no id") : "no focus"));
+							robot.keyPress(keys.RIGHT_ARROW, 500);	// navigation in the ColorPalette
+							robot.keyPress(keys.DOWN_ARROW, 500);	// navigation in the ColorPalette
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.t(dom.isDescendant(dfocus.curNode, registry.byId("toolbar1.colorPalette").domNode),
+									"focus still inside colorpalette, actual focus is: " + (dfocus.curNode ?
+										(dfocus.curNode.id||"no id") : "no focus"));
 							})), 1000);
 							
 							// pressing tab in the colorpalette should move focus back to the toolbar
-							doh.robot.keyPress(dojo.keys.TAB, 500);
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is("toolbar1.backcolor", dojo.global.dijit.focus.curNode.id, "back on colorpalette button");
+							robot.keyPress(keys.TAB, 500);
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
+								doh.is("toolbar1.backcolor", dfocus.curNode.id, "back on colorpalette button");
 							})), 1000);
 
 							// try the ComboButton
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500);
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500);
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+							robot.keyPress(keys.RIGHT_ARROW, 500);
+							robot.keyPress(keys.RIGHT_ARROW, 500);
+							robot.keyPress(keys.DOWN_ARROW, 500);
+							robot.sequence(d.getTestErrback(lang.hitch(this, function(){
 								// TODO: test that focus is on menu
 							})), 1000);
-							doh.robot.keyPress(dojo.keys.SPACE, 500);	// select first menu option
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							robot.keyPress(keys.SPACE, 500);	// select first menu option
+							robot.sequence(d.getTestCallback(lang.hitch(this, function(){
 								// TODO: test that focus is returned to button
 							})), 1000);
 
diff --git a/dijit/tests/robot/TooltipDialog_a11y.html b/dijit/tests/robot/TooltipDialog_a11y.html
index d44a3d1..94d901f 100644
--- a/dijit/tests/robot/TooltipDialog_a11y.html
+++ b/dijit/tests/robot/TooltipDialog_a11y.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot TooltipDialog A11y Test</title>
+		<title>robot TooltipDialog A11y Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,49 +10,93 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_TooltipDialog.html');
+			require([
+				"doh/runner", "dojo/robotx", "dojo/keys",
+				"dojo/domReady!"
+			], function(doh, robot, keys){
+				robot.initRobot('../test_TooltipDialog.html');
+
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+					dfocus = robot.window.require("dijit/focus");
+				});
 
 				doh.register("TooltipDialog normal operation", [
 					{
+						name: "aria roles and attributes",
+						timeout: 5000,
+						button: null,
+						runTest: function(){
+							var d = new doh.Deferred();
+							button = registry.byId("tooltipDlgButton");
+							
+							doh.is("button", button._popupStateNode.getAttribute("role"), "button _popupStateNode role");
+							doh.t(button._popupStateNode.getAttribute("aria-haspopup"), "aria-haspopup on button");
+							doh.is("tooltipDlgButton_label", button._popupStateNode.getAttribute("aria-labelledby"), "aria-labelledby");
+							doh.f(button._popupStateNode.getAttribute("aria-expanded"), "initially missing aria-expanded");
+							doh.f(button._popupStateNode.getAttribute("aria-owns"), "initally missing aria-owns");
+							
+							// now open the drop down
+							robot.sequence(function(){
+								button.focus();
+							}, 500, 500);
+							robot.keyPress(keys.SPACE, 500, {});
+
+							robot.sequence(d.getTestCallback(function(){								
+								doh.t(button._popupStateNode.getAttribute("aria-expanded"), "now aria-expanded should be true");
+								doh.is("tooltipDlg", button._popupStateNode.getAttribute("aria-owns"), "should aria-own the Dlg");
+
+								// Check roles and attributes on the dialog
+								var dlg = registry.byId("tooltipDlg");
+								doh.is("alertdialog", dlg.domNode.getAttribute("role"), "Dlg.domNode should have a role");
+								doh.is("tooltipDlgButton", dlg.domNode.getAttribute("aria-labelledby"), "aria-labelledby should point back to button");
+								
+								var dd = dlg.domNode;
+								doh.is("region", dd.parentNode.getAttribute("role"), "TooltipDialog's wrapper needs role=region since the node gets appended to the end");
+								doh.is("tooltipDlg", dd.parentNode.getAttribute("aria-label"), "TooltipDialog's wrapper needs aria-label since role=region");
+							}), 1000);
+						
+							return d;
+						},
+						tearDown: function(){
+							button.closeDropDown();
+						}
+					},
+					{
 						name: "basic navigation",
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var button = dijit.byId("tooltipDlgButton");
-							
+							var button = registry.byId("tooltipDlgButton");
+
 							// open TooltipDialog
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								button.focus();
 							}, 1000, 1000);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.keyPress(keys.SPACE, 500, {});
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should be showing");
 							}), 1000);
 
 							// shift-tab should loop around to last field
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("submit", dojo.global.dijit.focus.curNode.id, "focused on button");
+							robot.keyPress(keys.TAB, 500, {shift: true});
+							robot.sequence(d.getTestErrback(function(){
+								doh.is("submit", dfocus.curNode.id, "focused on button");
 							}), 1000);
 
 							// tab should loop around to first field
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("inline", dojo.global.dijit.focus.curNode.id, "focused on InlineEditBox");
+							robot.keyPress(keys.TAB, 500, {});
+							robot.sequence(d.getTestErrback(function(){
+								doh.is("inline", dfocus.curNode.id, "focused on InlineEditBox");
 							}), 1000);
 
 							// close TooltipDialog
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.keyPress(keys.ESCAPE, 500, {});
+							robot.sequence(d.getTestCallback(function(){
 								doh.f(button._opened, "TooltipDialog should not be showing after Esc");
 							}), 1000);
 							return d;
@@ -64,39 +108,39 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var button = dijit.byId("tooltipDlgButton"),
-								select = dijit.byId("combo");
-							
+							var button = registry.byId("tooltipDlgButton"),
+								select = registry.byId("combo");
+
 							// open TooltipDialog, advance to FilteringSelect
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								button.focus();
 							}, 500);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.SPACE, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should be showing");
-								doh.is("combo", dojo.global.dijit.focus.curNode.id, "focused on combo");
+								doh.is("combo", dfocus.curNode.id, "focused on combo");
 							}), 1000);
 
 							// pick second option
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 0, {});
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							robot.keyPress(keys.DOWN_ARROW, 0, {});
+							robot.keyPress(keys.DOWN_ARROW, 1000, {});
+							robot.keyPress(keys.DOWN_ARROW, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should still be showing");
 								doh.is("pepperoni", select.get("value"), "selected pepperoni");
 							}), 1000);
 
 							// close TooltipDialog
-							doh.robot.keyPress(dojo.keys.ESCAPE, 0, {});
+							robot.keyPress(keys.ESCAPE, 0, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.f(button._opened, "TooltipDialog closed");
 							}), 500);
 
@@ -112,45 +156,45 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var button = dijit.byId("tooltipDlgButton"),
-								inlineEditBox = dijit.byId("inline"),
+							var button = registry.byId("tooltipDlgButton"),
+								inlineEditBox = registry.byId("inline"),
 								initialValue = inlineEditBox.get("value");
-							
+
 							// open TooltipDialog
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								button.focus();
 							}, 500);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							robot.keyPress(keys.SPACE, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should be showing");
 								doh.f(inlineEditBox.editing, "InlineEditBox not in edit mode yet");
 							}), 1000);
 
 							// edit InlineEditBox
-							doh.robot.keyPress(dojo.keys.SPACE, 0, {});
+							robot.keyPress(keys.SPACE, 0, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should still be showing");
 								doh.t(inlineEditBox.editing, "InlineEditBox in edit mode");
 							}), 1000);
 
 							// type something
-							doh.robot.typeKeys("esc", 0, 600);
+							robot.typeKeys("esc", 0, 600);
 
 							// abort edit
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
+							robot.keyPress(keys.ESCAPE, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should still still be showing");
 								doh.f(inlineEditBox.editing, "Esc should have exited InlineEditBox edit mode");
 								doh.is(initialValue, inlineEditBox.get("value"), "initial value was inline");
 							}), 1000);
 
 							// close TooltipDialog
-							doh.robot.keyPress(dojo.keys.ESCAPE, 0, {});
+							robot.keyPress(keys.ESCAPE, 0, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.f(button._opened, "TooltipDialog closed");
 							}), 500);
 
@@ -163,44 +207,44 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var button = dijit.byId("tooltipDlgButton"),
-								inlineEditBox = dijit.byId("inline");
-							
+							var button = registry.byId("tooltipDlgButton"),
+								inlineEditBox = registry.byId("inline");
+
 							// open TooltipDialog
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								button.focus();
 							}, 500);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							robot.keyPress(keys.SPACE, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should be showing");
 								doh.f(inlineEditBox.editing, "InlineEditBox not in edit mode yet");
 							}), 1000);
 
 							// edit InlineEditBox
-							doh.robot.keyPress(dojo.keys.SPACE, 0, {});
+							robot.keyPress(keys.SPACE, 0, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should still be showing");
 								doh.t(inlineEditBox.editing, "InlineEditBox in edit mode");
 							}), 1000);
 
 							// type something
-							doh.robot.typeKeys("tab", 0, 600);
+							robot.typeKeys("tab", 0, 600);
 
 							// save edit
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should still still be showing");
 								doh.f(inlineEditBox.editing, "Tab should have exited InlineEditBox edit mode");
 								doh.is("tab", inlineEditBox.get("value"), "value changed to tab");
 							}), 1000);
 
 							// close TooltipDialog
-							doh.robot.keyPress(dojo.keys.ESCAPE, 0, {});
+							robot.keyPress(keys.ESCAPE, 0, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.f(button._opened, "TooltipDialog closed");
 							}), 500);
 
@@ -213,44 +257,44 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var button = dijit.byId("tooltipDlgButton"),
-								inlineEditBox = dijit.byId("inline");
-							
+							var button = registry.byId("tooltipDlgButton"),
+								inlineEditBox = registry.byId("inline");
+
 							// open TooltipDialog
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								button.focus();
 							}, 500);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							robot.keyPress(keys.SPACE, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should be showing");
 								doh.f(inlineEditBox.editing, "InlineEditBox not in edit mode yet");
 							}), 1000);
 
 							// edit InlineEditBox
-							doh.robot.keyPress(dojo.keys.SPACE, 0, {});
+							robot.keyPress(keys.SPACE, 0, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should still be showing");
 								doh.t(inlineEditBox.editing, "InlineEditBox in edit mode");
 							}), 1000);
 
 							// type something
-							doh.robot.typeKeys("enter", 0, 600);
+							robot.typeKeys("enter", 0, 600);
 
 							// save edit
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should still still be showing");
 								doh.f(inlineEditBox.editing, "Tab should have exited InlineEditBox edit mode");
 								doh.is("enter", inlineEditBox.get("value"), "value changed to enter");
 							}), 1000);
 
 							// close TooltipDialog
-							doh.robot.keyPress(dojo.keys.ESCAPE, 0, {});
+							robot.keyPress(keys.ESCAPE, 0, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.f(button._opened, "TooltipDialog closed");
 							}), 500);
 
@@ -262,25 +306,25 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var button = dijit.byId("tooltipDlgButton");
-								inlineEditBox = dijit.byId("inline");
+							var button = registry.byId("tooltipDlgButton");
+								inlineEditBox = registry.byId("inline");
 
 							// open TooltipDialog
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								button.focus();
 							}, 500);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.keyPress(keys.SPACE, 500, {});
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should be showing");
 							}), 1000);
 
 							// start editing
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
-	
+							robot.keyPress(keys.SPACE, 500, {});
+
 							// abort editing, then re-enter edit mode
-							doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {});
-							doh.robot.keyPress(dojo.keys.ENTER, 1000, {});
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.keyPress(keys.ESCAPE, 1000, {});
+							robot.keyPress(keys.ENTER, 1000, {});
+							robot.sequence(d.getTestCallback(function(){
 								doh.t(button._opened, "TooltipDialog should still be showing");
 								doh.t(inlineEditBox.editing, "Enter should have reentered edit mode");
 								inlineEditBox.cancel(true);
@@ -294,27 +338,27 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var button = dijit.byId("tooltipDlgButton"),
-								inlineEditBox = dijit.byId("inline");
+							var button = registry.byId("tooltipDlgButton"),
+								inlineEditBox = registry.byId("inline");
 
 							// open TooltipDialog
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								button.focus();
 							}, 1000, 1000);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.keyPress(keys.SPACE, 500, {});
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should be showing");
 							}), 1000);
 
 							// start editing
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
-							doh.robot.typeKeys("enter #2", 1000, 1000);
-							
+							robot.keyPress(keys.SPACE, 500, {});
+							robot.typeKeys("enter #2", 1000, 1000);
+
 							// save via ENTER key, the press ENTER again to re-edit
-							doh.robot.keyPress(dojo.keys.ENTER, 200, {});
-							doh.robot.keyPress(dojo.keys.ENTER, 1000, {});
+							robot.keyPress(keys.ENTER, 200, {});
+							robot.keyPress(keys.ENTER, 1000, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.t(button._opened, "TooltipDialog should still be showing");
 								doh.t(inlineEditBox.editing, "2nd Enter should have reentered edit mode");
 								inlineEditBox.cancel(true);
@@ -329,30 +373,30 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var button = dijit.byId("tooltipDlgButton"),
-								inlineEditBox = dijit.byId("inline");
+							var button = registry.byId("tooltipDlgButton"),
+								inlineEditBox = registry.byId("inline");
 
 							// open TooltipDialog
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								button.focus();
 							}, 1000, 1000);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.keyPress(keys.SPACE, 500, {});
+							robot.sequence(d.getTestErrback(function(){
 								doh.t(button._opened, "TooltipDialog should be showing");
 							}), 1000);
 
 							// start editing
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
-							doh.robot.typeKeys("tab", 1000, 600);
+							robot.keyPress(keys.SPACE, 500, {});
+							robot.typeKeys("tab", 1000, 600);
 
 							// tab forward, then back (first tab will cancel edit)
-							doh.robot.keyPress(dojo.keys.TAB, 100, {});	
-							doh.robot.keyPress(dojo.keys.TAB, 1000, {shift:true});
+							robot.keyPress(keys.TAB, 100, {});
+							robot.keyPress(keys.TAB, 1000, {shift:true});
 
 							// re-enter edit mode
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							robot.keyPress(keys.ENTER, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.t(button._opened, "TooltipDialog should still be showing");
 								doh.t(inlineEditBox.editing, "Enter after shift+Tab should have reentered edit mode");
 								inlineEditBox.cancel(true);
@@ -366,25 +410,33 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var button = dijit.byId("slowLoadButton"),
-								dialog = dijit.byId("slowLoad");
-
-							// open TooltipDialog
-							doh.robot.sequence(function(){
+							var button = registry.byId("slowLoadButton"),
+								dialog = registry.byId("slowLoad");
+
+							// Setup handler to continue test after dialog is opened and content loaded
+							dialog.onLoad = function(){
+								setTimeout(d.getTestErrback(function(){
+									doh.t(button._opened, "TooltipDialog should be showing");
+									doh.t(/Delayed by 0.5 sec/.test(dialog.domNode.innerHTML), "data was loaded");
+
+									// Close TooltipDialog
+									robot.keyPress(keys.ESCAPE, 500, {});
+									robot.sequence(d.getTestCallback(function(){
+										doh.f(button._opened, "TooltipDialog should not be showing after Esc");
+									}), 1000);
+								}), 0);
+							};
+
+							// Open TooltipDialog
+							robot.sequence(function(){
 								button.focus();
-							}, 1000, 1000);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(button._opened, "TooltipDialog should be showing");
-								doh.t(/Delayed by 0.5 sec/.test(dialog.domNode.innerHTML), "data was loaded")
-							}), 2000);
+							}, 0);
+							robot.keyPress(keys.SPACE, 500, {});
 
-							// close TooltipDialog
-							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.f(button._opened, "TooltipDialog should not be showing after Esc");
-							}), 1000);
 							return d;
+						},
+						tearDown: function(){
+							registry.byId("slowLoad").onLoad = function(){};
 						}
 					}
 				]);
diff --git a/dijit/tests/robot/TooltipDialog_mouse.html b/dijit/tests/robot/TooltipDialog_mouse.html
index c2592ce..02eb20e 100644
--- a/dijit/tests/robot/TooltipDialog_mouse.html
+++ b/dijit/tests/robot/TooltipDialog_mouse.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot TooltipDialog Mouse Test</title>
+		<title>robot TooltipDialog Mouse Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,16 +10,21 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_TooltipDialog.html');
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom", "dojo/query",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, dom, query, helpers){
+				robot.initRobot('../test_TooltipDialog.html');
+
+				doh.register("setup", function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+					dfocus = robot.window.require("dijit/focus");
+				});
 
 				doh.register("Select", [
 					{
@@ -28,12 +33,14 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("tooltipDlgButton", 1000);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog visible");
-								doh.is("inline", dojo.global.dijit.focus.curNode.id, "focus on InlineEditBox (first field in TooltipDialog)")
+							robot.mouseMoveAt("tooltipDlgButton", 1000);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog visible");
+								doh.is("inline", dfocus.curNode.id, "focus on InlineEditBox (first field in TooltipDialog)")
 							}), 1000);
+
+							return d;
 						}
 					},
 
@@ -42,25 +49,25 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								select = dijit.byId("select");
+								select = registry.byId("select");
 							
 							// open Select
-							doh.robot.mouseMoveAt("select", 0);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still be showing");
-								doh.t(isVisible("select_menu"), "Select Menu showing too");
+							robot.mouseMoveAt("select", 0);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog should still be showing");
+								doh.t(helpers.isVisible("select_menu"), "Select Menu showing too");
 							}), 1000);
 							
 							// pick second option
-							doh.robot.mouseMoveAt(function(){
-								return dojo.query("tr", dojo.byId("select_menu"))[1];
+							robot.mouseMoveAt(function(){
+								return query("tr", dom.byId("select_menu"))[1];
 							}, 0);
-							doh.robot.mouseClick({left: true}, 1000);
+							robot.mouseClick({left: true}, 1000);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("select_menu"), "Select Menu closed");
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still still be showing");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("select_menu"), "Select Menu closed");
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog should still still be showing");
 								doh.is("peppers", select.get("value"), "selected peppers");
 							}), 1000);
 
@@ -73,26 +80,26 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								select = dijit.byId("select");
+								select = registry.byId("select");
 							
 							// open Select
-							doh.robot.mouseMoveAt("select", 0);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still be showing");
-								doh.t(isVisible("select_menu"), "Select Menu showing too");
+							robot.mouseMoveAt("select", 0);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog should still be showing");
+								doh.t(helpers.isVisible("select_menu"), "Select Menu showing too");
 							}), 1000);
 							
 							// click unfocusable area of TooltipDialog to get select to close
 							// (but TooltipDialog itself should remain open)
-							doh.robot.mouseMoveAt(function(){
-								return dojo.query("label[for='select']", dojo.byId("tooltipDlg"))[0];
+							robot.mouseMoveAt(function(){
+								return query("label[for='select']", dom.byId("tooltipDlg"))[0];
 							}, 0);
-							doh.robot.mouseClick({left: true}, 1000);
+							robot.mouseClick({left: true}, 1000);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("select_menu"), "Select Menu closed");
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still still be showing");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("select_menu"), "Select Menu closed");
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog should still still be showing");
 							}), 1000);
 
 							return d;
@@ -103,25 +110,27 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								select = dijit.byId("select");
+								select = registry.byId("select");
 							
 							// open Select
-							doh.robot.mouseMoveAt("select", 0);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still be showing");
-								doh.t(isVisible("select_menu"), "Select Menu showing too");
+							robot.mouseMoveAt("select", 0);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog should still be showing");
+								doh.t(helpers.isVisible("select_menu"), "Select Menu showing too");
 							}), 1000);
 							
 							// click TextBox to get select to close
-							doh.robot.mouseMoveAt("text", 0);
-							doh.robot.mouseClick({left: true}, 1000);
+							robot.mouseMoveAt("text", 0);
+							robot.mouseClick({left: true}, 1000);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("select_menu"), "Select Menu closed");
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still still be showing");
-								doh.is("text", dijit.focus.curNode && dijit.focus.curNode.id, "focused on textbox")
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("select_menu"), "Select Menu closed");
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog should still still be showing");
+								doh.is("text", dfocus.curNode && dfocus.curNode.id, "focused on textbox")
 							}), 1000);
+
+							return d;
 						}
 					},
 
@@ -131,11 +140,11 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMove(10, 10, 0);
-							doh.robot.mouseClick({left: true}, 1000);
+							robot.mouseMove(10, 10, 0);
+							robot.mouseClick({left: true}, 1000);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("tooltipDlg"), "Tooltip dialog closed");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("tooltipDlg"), "Tooltip dialog closed");
 							}), 500);
 
 							return d;
@@ -149,41 +158,41 @@
 						timeout: 20000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								inlineEditBox = dijit.byId("inline");
+								inlineEditBox = registry.byId("inline");
 							
 							// open TooltipDialog
-							doh.robot.mouseMoveAt("tooltipDlgButton", 500);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog visible");
+							robot.mouseMoveAt("tooltipDlgButton", 500);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog visible");
 							}), 1000);
 
 							// start editing InlineEditBox
-							doh.robot.mouseMoveAt("inline", 0, 500, 10, 5);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still be showing");
+							robot.mouseMoveAt("inline", 0, 500, 10, 5);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog should still be showing");
 								doh.t(inlineEditBox.editing, "InlineEditBox in edit mode");
 							}), 1000);
 							
 							// type something
-							doh.robot.typeKeys("changed", 0, 600);
+							robot.typeKeys("changed", 0, 600);
 
 							// close InlineEditBox by clicking on blank area of TooltipDialog
-							doh.robot.mouseMoveAt("tooltipDlg", 0, 500, 10, 20);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.mouseMoveAt("tooltipDlg", 0, 500, 10, 20);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestErrback(function(){
 								doh.f(inlineEditBox.editing, "InlineEditBox no longer in edit mode");
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still still be showing");
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog should still still be showing");
 								doh.is("changed", inlineEditBox.get("value"), "value changed to changed");
 							}), 1000);
 
 							// close TooltipDialog
-							doh.robot.mouseMove(10, 10, 0);
-							doh.robot.mouseClick({left: true}, 1000);
+							robot.mouseMove(10, 10, 0);
+							robot.mouseClick({left: true}, 1000);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("tooltipDlg"), "Tooltip dialog closed");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("tooltipDlg"), "Tooltip dialog closed");
 							}), 500);
 
 							return d;
@@ -198,12 +207,14 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("tooltipDlgButton", 1000);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog visible");
-								doh.is("inline", dojo.global.dijit.focus.curNode.id, "focus on InlineEditBox (first field in TooltipDialog)")
+							robot.mouseMoveAt("tooltipDlgButton", 1000);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog visible");
+								doh.is("inline", dfocus.curNode.id, "focus on InlineEditBox (first field in TooltipDialog)")
 							}), 1000);
+
+							return d;
 						}
 					},
 
@@ -212,16 +223,16 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								date = dijit.byId("date2");
+								date = registry.byId("date2");
 
 							// click arrow to open
-							doh.robot.mouseMoveAt(function(){
-								return dojo.query(".dijitArrowButton", date.domNode)[0];
+							robot.mouseMoveAt(function(){
+								return query(".dijitArrowButton", date.domNode)[0];
 							}, 0);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still be showing");
-								doh.t(isVisible("date2_popup"), "Calendar showing too");
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog should still be showing");
+								doh.t(helpers.isVisible("date2_popup"), "Calendar showing too");
 							}), 1000);
 
 							return d;
@@ -233,17 +244,19 @@
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								date = dijit.byId("date2");
+								date = registry.byId("date2");
 
 							// click arrow to open
-							doh.robot.mouseMoveAt(function(){
-								return dojo.query(".dijitArrowButton", date.domNode)[0];
+							robot.mouseMoveAt(function(){
+								return query(".dijitArrowButton", date.domNode)[0];
 							}, 0);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still be showing");
-								doh.f(isVisible("date_popup"), "calendar closed");
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("tooltipDlg"), "TooltipDialog should still be showing");
+								doh.t(!dom.byId("date_popup") || helpers.isHidden("date_popup"), "calendar closed");
 							}), 1000);
+
+							return d;
 						}
 					},
 
@@ -253,11 +266,11 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMove(10, 10, 0);
-							doh.robot.mouseClick({left: true}, 1000);
+							robot.mouseMove(10, 10, 0);
+							robot.mouseClick({left: true}, 1000);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("tooltipDlg"), "Tooltip dialog closed");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("tooltipDlg"), "Tooltip dialog closed");
 							}), 500);
 
 							return d;
@@ -272,11 +285,13 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("outerDdBtn", 1000);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("outerTtDialog"), "Outer TooltipDialog visible");
+							robot.mouseMoveAt("outerDdBtn", 1000);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("outerTtDialog"), "Outer TooltipDialog visible");
 							}), 1000);
+
+							return d;
 						}
 					},
 					{
@@ -285,11 +300,13 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("innerDdBtn", 1000);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("innerTtDialog"), "Inner TooltipDialog visible");
+							robot.mouseMoveAt("innerDdBtn", 1000);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("innerTtDialog"), "Inner TooltipDialog visible");
 							}), 1000);
+
+							return d;
 						}
 					},
 
@@ -299,11 +316,11 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("popupMenuItem", 0);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("innerTtDialog"), "inner TooltipDialog should still be showing");
-								doh.t(isVisible("submenu"), "nested Menu showing too");
+							robot.mouseMoveAt("popupMenuItem", 0);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("innerTtDialog"), "inner TooltipDialog should still be showing");
+								doh.t(helpers.isVisible("submenu"), "nested Menu showing too");
 							}), 1000);
 
 							return d;
@@ -316,11 +333,11 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("plaintext", 0);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("innerTtDialog"), "Inner TooltipDialog should still be showing");
-								doh.t(isHidden("submenu"), "SubMenu was closed");
+							robot.mouseMoveAt("plaintext", 0);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("innerTtDialog"), "Inner TooltipDialog should still be showing");
+								doh.t(helpers.isHidden("submenu"), "SubMenu was closed");
 							}), 1000);
 
 							return d;
@@ -333,11 +350,11 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							doh.robot.mouseMoveAt("popupMenuItem", 0);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isVisible("innerTtDialog"), "inner TooltipDialog should still be showing");
-								doh.t(isVisible("submenu"), "nested Menu showing too");
+							robot.mouseMoveAt("popupMenuItem", 0);
+							robot.mouseClick({left: true}, 1000);
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isVisible("innerTtDialog"), "inner TooltipDialog should still be showing");
+								doh.t(helpers.isVisible("submenu"), "nested Menu showing too");
 							}), 1000);
 
 							return d;
@@ -351,14 +368,16 @@
 							var d = new doh.Deferred();
 							
 							// click TextBox to get submenu to close
-							doh.robot.mouseMoveAt("name", 0);
-							doh.robot.mouseClick({left: true}, 1000);
+							robot.mouseMoveAt("name", 0);
+							robot.mouseClick({left: true}, 1000);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("submenuu"), "submenu closed");
-								doh.t(isVisible("innerTtDialog"), "TooltipDialog should still still be showing");
-								doh.is("name", dijit.focus.curNode && dijit.focus.curNode.id, "focused on textbox")
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("submenu"), "submenu closed");
+								doh.t(helpers.isVisible("innerTtDialog"), "TooltipDialog should still still be showing");
+								doh.is("name", dfocus.curNode && dfocus.curNode.id, "focused on textbox")
 							}), 1000);
+
+							return d;
 						}
 					},
 
@@ -368,12 +387,12 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMove(10, 10, 0);
-							doh.robot.mouseClick({left: true}, 1000);
+							robot.mouseMove(10, 10, 0);
+							robot.mouseClick({left: true}, 1000);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("innerTtDialog"), "inner Tooltip dialog closed");
-								doh.t(isHidden("outerTtDialog"), "inner Tooltip dialog closed");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden("innerTtDialog"), "inner Tooltip dialog closed");
+								doh.t(helpers.isHidden("outerTtDialog"), "inner Tooltip dialog closed");
 							}), 500);
 
 							return d;
diff --git a/dijit/tests/robot/Tooltip_a11y.html b/dijit/tests/robot/Tooltip_a11y.html
index a68d4f6..ee73f6c 100644
--- a/dijit/tests/robot/Tooltip_a11y.html
+++ b/dijit/tests/robot/Tooltip_a11y.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Tooltip A11Y Test</title>
+		<title>robot Tooltip A11Y Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,58 +10,61 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dojo.window");
-			dojo.require("dijit.robotx");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Tooltip.html');
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom", "dojo/dom-geometry", "dojo/keys", "dojo/_base/lang", "dojo/_base/window", "dojo/window",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, dom, domGeom, keys, lang, win, winUtils, helpers){
 
-				// Pointer to master tooltip.  This gets set in the first test when the
-				// first tooltip is shown
-				var masterTT;
+				robot.initRobot('../test_Tooltip.html');
 
 				doh.register("setup", function(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+					Tooltip = robot.window.require("dijit/Tooltip");
+
 					// Avoid the page being scrolled when you run the test twice (via browser's refresh button)
-					dojo.body().parentNode.scrollTop = 0;	// works on FF
-					dojo.body().scrollTop = 0;	// works on safari
+					win.body().parentNode.scrollTop = 0;	// works on FF
+					win.body().scrollTop = 0;	// works on safari
 				});
 
+				// Pointer to master tooltip.  This gets set in the first test when the
+				// first tooltip is shown
+				var masterTT;
+
 				doh.register("dijit.Tooltip keyboard tests", [
 					{
 						name: "show on focus",
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								around = dojo.byId("four");
+								around = dom.byId("four");
 
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								around.focus();
-								masterTT = dojo.global.dijit._masterTT;
-								doh.t(!masterTT || isHidden(masterTT.domNode), "tooltip either hidden or doesn't exist yet");
+								masterTT = Tooltip._masterTT;
+								doh.t(!masterTT || helpers.isHidden(masterTT.domNode), "tooltip either hidden or doesn't exist yet");
 							}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// At this point the master tooltip should have been created, so save in
 								// global variable
-								masterTT = dojo.global.dijit._masterTT;
+								masterTT = Tooltip._masterTT;
 
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
 
 								// make sure tooltip is in right place (but note that it could be to the
 								// left of the right depending on page BIDI setting)
-								var aroundCoords = dojo.position(around),
-									tooltipCoords = dojo.position(masterTT.domNode);
+								var aroundCoords = domGeom.position(around),
+									tooltipCoords = domGeom.position(masterTT.domNode);
 								doh.t((aroundCoords.y + aroundCoords.h) <= (tooltipCoords.y + tooltipCoords.h), "lower aligned");
 								doh.t(aroundCoords.y  >= tooltipCoords.y, "upper aligned");
 
 								// Make sure it has right content
-								doh.is("tooltip on a button", dojo.trim(innerText(masterTT.domNode)), "tooltip text");
+								doh.is("tooltip on a button", lang.trim(helpers.innerText(masterTT.domNode)), "tooltip text");
 							}), 2000);
 
 							return d;
@@ -76,10 +79,10 @@
 
 							// Tab off of the "button w/tooltip" to the "remove button",
 							// which doesn't have a tooltip
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isHidden(masterTT.domNode), "tooltip hidden");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isHidden(masterTT.domNode), "tooltip hidden");
 							}), 2000);
 
 							return d;
@@ -91,18 +94,18 @@
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								around = dojo.byId("seven");
+								around = dom.byId("seven");
 
 							// Tab off of the "remove button" to the <select>
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							robot.keyPress(keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
 
 								// make sure tooltip is on the screen (in LTR mode it needs to go to the
 								// left of the <select>, not to the right like it usually does)
-								var viewportCoords = dojo.window.getBox(),
-									tooltipCoords = dojo.position(masterTT.domNode);
+								var viewportCoords = winUtils.getBox(),
+									tooltipCoords = domGeom.position(masterTT.domNode);
 								console.log("viewport coords: ", viewportCoords, "tooltip coords: ", tooltipCoords);
 								doh.t(tooltipCoords.x > 0, "x > 0");
 								doh.t(tooltipCoords.x + tooltipCoords.w <= viewportCoords.w, "t.x + t.w");
@@ -111,7 +114,7 @@
 
 								// Make sure it has the new content.
 								// There's a newline in this tooltip text, so to make comparison easier do substr()
-								doh.is("tooltip on a select", dojo.trim(innerText(masterTT.domNode)).substr(0, 19), "tooltip text");
+								doh.is("tooltip on a select", lang.trim(helpers.innerText(masterTT.domNode)).substr(0, 19), "tooltip text");
 							}), 2000);
 
 							return d;
@@ -128,28 +131,28 @@
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								around = dojo.byId("one");
+								around = dom.byId("one");
 
 							// Focus onto something w/out a tooltip to make currently displayed tooltip disappear
-							doh.robot.sequence(d.getTestErrback(function(){
-								dojo.byId("removeButton").focus();
+							robot.sequence(d.getTestErrback(function(){
+								dom.byId("removeButton").focus();
 							}), 50);
 
 							// Focus on a node w/a tooltip
-							doh.robot.sequence(d.getTestErrback(function(){
+							robot.sequence(d.getTestErrback(function(){
 								around.focus();
 							}), 500);
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isHidden(masterTT.domNode), "tooltip should be hidden on initial focus, but text shown is: " +
-										dojo.trim(innerText(masterTT.domNode)));
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(helpers.isHidden(masterTT.domNode), "tooltip should be hidden on initial focus, but text shown is: " +
+										lang.trim(helpers.innerText(masterTT.domNode)));
 							}), 50);
 
 							// But then tab away after 100ms, before tooltip is shown
-							doh.robot.keyPress(dojo.keys.TAB, 50, {shift: true});
+							robot.keyPress(keys.TAB, 50, {shift: true});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden(masterTT.domNode), "tooltip still hidden after tabbing away");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden(masterTT.domNode), "tooltip still hidden after tabbing away");
 							}), 1000);
 
 							return d;
@@ -171,7 +174,7 @@
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								tooltip = dijit.byId("t_tooltip");
+								tooltip = registry.byId("t_tooltip");
 
 							// While we are at it, test set('label', ...) too
 							tooltip.set('label', 'bill was here');
@@ -188,18 +191,18 @@
 						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								around = dojo.byId("t1");
+								around = dom.byId("t1");
 
-							doh.robot.sequence(function(){
-								dojo.window.scrollIntoView(around);
+							robot.sequence(function(){
+								winUtils.scrollIntoView(around);
 								around.focus();
 							}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
 
 								// Make sure it has right content
-								doh.is("bill was here", dojo.trim(innerText(masterTT.domNode)), "tooltip text");
+								doh.is("bill was here", lang.trim(helpers.innerText(masterTT.domNode)), "tooltip text");
 							}), 2000);
 
 							return d;
@@ -211,15 +214,15 @@
 						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								around = dojo.byId("t2");
+								around = dom.byId("t2");
 
-							doh.robot.sequence(function(){
-								dojo.window.scrollIntoView(around);
+							robot.sequence(function(){
+								winUtils.scrollIntoView(around);
 								around.focus();
 							}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isHidden(masterTT.domNode), "tooltip hidden");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isHidden(masterTT.domNode), "tooltip hidden");
 							}), 2000);
 
 							return d;
@@ -231,15 +234,15 @@
 						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								around = dojo.byId("t3");
+								around = dom.byId("t3");
 
-							doh.robot.sequence(function(){
-								dojo.window.scrollIntoView(around);
+							robot.sequence(function(){
+								winUtils.scrollIntoView(around);
 								around.focus();
 							}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip visible");
 							}), 2000);
 
 							return d;
@@ -251,8 +254,8 @@
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								tooltip = dijit.byId("t_tooltip"),
-								around = dojo.byId("t2");
+								tooltip = registry.byId("t_tooltip"),
+								around = dom.byId("t2");
 
 							tooltip.addTarget("t2");
 
@@ -263,11 +266,11 @@
 							doh.is("t2", connectIds[2]);
 
 							// Focus "t2 text" and make sure tooltip shows
-							dojo.window.scrollIntoView(around);
+							winUtils.scrollIntoView(around);
 							around.focus();
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
 							}), 2000);
 
 							return d;
@@ -279,8 +282,8 @@
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								tooltip = dijit.byId("t_tooltip"),
-								around = dojo.byId("t3");
+								tooltip = registry.byId("t_tooltip"),
+								around = dom.byId("t3");
 
 							tooltip.removeTarget("t3");
 							var connectIds = tooltip.get("connectId");
@@ -289,11 +292,11 @@
 							doh.is("t2", connectIds[1]);
 
 							// Focus "t3 text" and make sure tooltip doesn't show
-							dojo.window.scrollIntoView(around);
+							winUtils.scrollIntoView(around);
 							around.focus();
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isHidden(masterTT.domNode), "tooltip hidden");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isHidden(masterTT.domNode), "tooltip hidden");
 							}), 2000);
 
 							return d;
@@ -305,21 +308,21 @@
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								tooltip = dijit.byId("t_tooltip"),
-								around = dojo.byId("t2");
+								tooltip = registry.byId("t_tooltip"),
+								around = dom.byId("t2");
 
 							// Move focus somewhere out of the way
-							dojo.byId("t5").focus();
+							dom.byId("t5").focus();
 
 							// Disconnecting from "t2 text", and adding "t4 text"
 							tooltip.set("connectId", ["t3", "t4"]);
 
 							// Focus "t2 text" and make sure tooltip doesn't show anymore
-							dojo.window.scrollIntoView(around);
+							winUtils.scrollIntoView(around);
 							around.focus();
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isHidden(masterTT.domNode), "tooltip hidden");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isHidden(masterTT.domNode), "tooltip hidden");
 							}), 2000);
 
 							return d;
@@ -330,15 +333,15 @@
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								tooltip = dijit.byId("t_tooltip"),
-								around = dojo.byId("t4");
+								tooltip = registry.byId("t_tooltip"),
+								around = dom.byId("t4");
 
 							// Focus "t4 text" and make sure tooltip shows
-							dojo.window.scrollIntoView(around);
+							winUtils.scrollIntoView(around);
 							around.focus();
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip visible");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip visible");
 							}), 2000);
 
 							return d;
@@ -347,13 +350,39 @@
 
 					// Nominal tests for old dojoType syntax, remove in 2.0
 					function oldDojoTypeSyntax(){
-						var tooltip = dijit.byId("oldmulti1,oldmulti2_tooltip");
+						var tooltip = registry.byId("oldmulti1,oldmulti2_tooltip");
 						doh.is(2, tooltip.get("connectId").length);
 						doh.is("oldmulti1", tooltip.get("connectId")[0]);
 						doh.is("oldmulti2", tooltip.get("connectId")[1]);
 					}
 				]);
 
+				doh.register("Focus on nested element", [
+					{
+						name: "Focus on nested element",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Focus an input where the containing div has a tooltip.
+							// Should show a tooltip on the div.
+							dom.byId("nestedInput").focus();
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
+
+								var tooltipPos = domGeom.position(masterTT.domNode),
+									anchorPos = domGeom.position("nested");
+								doh.t(Math.round(tooltipPos.x) >= Math.round(anchorPos.x + anchorPos.w),
+										"tooltip pos " + tooltipPos.x + " > anchor right edge at " +
+												anchorPos.x + " + " + anchorPos.w);
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/robot/Tooltip_mouse.html b/dijit/tests/robot/Tooltip_mouse.html
index d71fd69..219f4d1 100644
--- a/dijit/tests/robot/Tooltip_mouse.html
+++ b/dijit/tests/robot/Tooltip_mouse.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Tooltip Mouse Test</title>
+		<title>robot Tooltip Mouse Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,37 +10,43 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Tooltip.html');
+		require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom", "dojo/dom-geometry", "dojo/_base/lang", "dojo/query", "dojo/window",
+				"dijit/tests/helpers", "dojo/domReady!"
+			], function(doh, robot, dom, domGeom, lang, query, winUtils, helpers){
+				robot.initRobot('../test_Tooltip.html');
 
 				// Pointer to master tooltip.  This gets set in the first test when the
 				// first tooltip is shown
 				var masterTT;
 
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+					dfocus = robot.window.require("dijit/focus");
+					Tooltip = robot.window.require("dijit/Tooltip");
+				});
+
 				doh.register("dijit.Tooltip mouse tests", [
 					{
 						name: "show on mouse over",
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								around = dojo.byId("four");
+								around = dom.byId("four");
 
-							doh.robot.mouseMoveAt("four", 500);
+							robot.mouseMoveAt("four", 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// At this point the master tooltip should have been created, so save in
 								// global variable
-								masterTT = dojo.global.dijit._masterTT;
+								masterTT = Tooltip._masterTT;
 
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
 							}), 2000);
 
 							return d;
@@ -54,10 +60,10 @@
 							var d = new doh.Deferred();
 
 							// Move off of the "button w/tooltip" to node which doesn't have a tooltip
-							doh.robot.mouseMoveAt(dojo.query("h1")[0], 500);
+							robot.mouseMoveAt(query("h1")[0], 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isHidden(masterTT.domNode), "tooltip hidden");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isHidden(masterTT.domNode), "tooltip hidden");
 							}), 2000);
 
 							return d;
@@ -70,19 +76,19 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("id1", 500);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt("id1", 500);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
-								doh.is("id1", dijit._curFocus && dijit._curFocus.id, "node is focused");
+							robot.sequence(d.getTestErrback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
+								doh.is("id1", dfocus.curNode && dfocus.curNode.id, "node is focused");
 							}), 2000);
 
 							// Move off of the focused node to node which doesn't have a tooltip
-							doh.robot.mouseMoveAt(dojo.query("h1")[0], 500);
+							robot.mouseMoveAt(query("h1")[0], 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isHidden(masterTT.domNode), "tooltip hidden");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isHidden(masterTT.domNode), "tooltip hidden");
 							}), 2000);
 
 							return d;
@@ -98,14 +104,14 @@
 							var d = new doh.Deferred();
 
 							// Click the DropDownButton to open the Menu
-							doh.robot.mouseMoveAt("ddb", 500);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt("ddb", 500);
+							robot.mouseClick({left: true}, 500);
 
 							// Move over the MenuItem to show the tooltip
-							doh.robot.mouseMoveAt("copy", 2000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
-								doh.is("tooltip for copy", dojo.trim(innerText(masterTT.domNode)), "tooltip text");
+							robot.mouseMoveAt("copy", 2000);
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
+								doh.is("tooltip for copy", lang.trim(helpers.innerText(masterTT.domNode)), "tooltip text");
 							}), 750);
 
 							return d;
@@ -119,11 +125,11 @@
 							var d = new doh.Deferred();
 
 							// Click the MenuItem to close the menu
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden(dijit.byId("ddm").domNode), "menu hidden");
-								doh.t(masterTT && isHidden(masterTT.domNode), "tooltip hidden");
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(helpers.isHidden(registry.byId("ddm").domNode), "menu hidden");
+								doh.t(masterTT && helpers.isHidden(masterTT.domNode), "tooltip hidden");
 							}), 500);
 
 							return d;
@@ -138,11 +144,137 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("tpTooltipTarget", 500);
+							robot.mouseMoveAt("tpTooltipTarget", 500);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
+								doh.is("tooltip on TitlePane span", lang.trim(helpers.innerText(masterTT.domNode)), "tooltip text");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("Mouse over nested div", [
+					{
+						name: "mouse over nested div",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Start with mouse to the left of the nested divs
+							robot.mouseMoveAt("nested", 500, 0, -50, 0);
+
+							// Then move to inner div.   The onmouseenter event will occur with evt.target == inner div
+							robot.mouseMoveAt("nested", 500, 0);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
+
+								var tooltipPos = domGeom.position(masterTT.domNode),
+									anchorPos = domGeom.position("nested");
+								doh.t(tooltipPos.x >= anchorPos.x + anchorPos.w,
+										"tooltip pos " + tooltipPos.x + " > anchor right edge at " +
+												anchorPos.x + " + " + anchorPos.w);
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("Delegation", [
+					function scrollIntoView(){
+						// Scroll the whole table into view to make tooltip position tests work correctly
+						winUtils.scrollIntoView("myTable");
+					},
+					{
+						name: "mouse over row 1",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.mouseMoveAt("myTable-row1", 500, 0);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
+								doh.is("Tooltip for row 1", lang.trim(helpers.innerText(masterTT.domNode)), "tooltip text");
+
+								var tooltipPos = domGeom.position(masterTT.domNode),
+									anchorPos = domGeom.position("myTable-row1");
+								doh.t(tooltipPos.y + tooltipPos.h/2 >= anchorPos.y,
+										"tooltip pos " + tooltipPos.y + " height " + tooltipPos.h +
+										"anchor " + anchorPos.y + " + height " + anchorPos.h);
+								doh.t(tooltipPos.y + tooltipPos.h/2 <= anchorPos.y + anchorPos.h,
+										"tooltip pos " + tooltipPos.y + " height " + tooltipPos.h +
+										"anchor " + anchorPos.y + " + height " + anchorPos.h);
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "mouse over row 3",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.mouseMoveAt("myTable-row3", 500, 0);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
+								doh.is("Tooltip for row 3", lang.trim(helpers.innerText(masterTT.domNode)), "tooltip text");
+
+								var tooltipPos = domGeom.position(masterTT.domNode),
+									anchorPos = domGeom.position("myTable-row3");
+								doh.t(tooltipPos.y + tooltipPos.h/2 >= anchorPos.y,
+										"tooltip pos " + tooltipPos.y + " height " + tooltipPos.h +
+										"anchor " + anchorPos.y + " + height " + anchorPos.h);
+								doh.t(tooltipPos.y + tooltipPos.h/2 <= anchorPos.y + anchorPos.h,
+										"tooltip pos " + tooltipPos.y + " height " + tooltipPos.h +
+										"anchor " + anchorPos.y + " + height " + anchorPos.h);
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "mouse over row 4",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.mouseMoveAt("myTable-row4", 500, 0);
+
+							robot.sequence(d.getTestCallback(function(){
+								// should be no tooltip for rows >= 4
+								doh.t(masterTT && helpers.isHidden(masterTT.domNode), "tooltip hidden");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "mouse over row 2",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							robot.mouseMoveAt("myTable-row2", 500, 0);
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.t(masterTT && helpers.isVisible(masterTT.domNode), "tooltip shown");
+								doh.is("Tooltip for row 2", lang.trim(helpers.innerText(masterTT.domNode)), "tooltip text");
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(masterTT && isVisible(masterTT.domNode), "tooltip shown");
-								doh.is("tooltip on TitlePane span", dojo.trim(innerText(masterTT.domNode)), "tooltip text");
+								var tooltipPos = domGeom.position(masterTT.domNode),
+									anchorPos = domGeom.position("myTable-row2");
+								doh.t(tooltipPos.y + tooltipPos.h/2 >= anchorPos.y,
+										"tooltip pos " + tooltipPos.y + " height " + tooltipPos.h +
+										"anchor " + anchorPos.y + " + height " + anchorPos.h);
+								doh.t(tooltipPos.y + tooltipPos.h/2 <= anchorPos.y + anchorPos.h,
+										"tooltip pos " + tooltipPos.y + " height " + tooltipPos.h +
+										"anchor " + anchorPos.y + " + height " + anchorPos.h);
 							}), 500);
 
 							return d;
diff --git a/dijit/tests/robot/Tooltip_mouse_quirks.html b/dijit/tests/robot/Tooltip_mouse_quirks.html
index c205b0b..c2a8765 100644
--- a/dijit/tests/robot/Tooltip_mouse_quirks.html
+++ b/dijit/tests/robot/Tooltip_mouse_quirks.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Tooltip Mouse Quirks Test</title>
+		<title>robot Tooltip Mouse Quirks Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -10,16 +10,21 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/query",
+				"dojo/domReady!"
+			], function(doh, robot, query){
+
+				robot.initRobot("../quirks.html?file=test_Tooltip.html");
 
-			dojo.ready(function(){
-				doh.robot.initRobot("../quirks.html?file=test_Tooltip.html");
+				doh.register(function setup(){
+					// get pointer to registry in the iframe
+					registry = robot.window.require("dijit/registry");
+				});
 
 				doh.register("dijit.Tooltip mouse quirks tests", [
 					// Test that BackgroundIFrame has right proportions; this used to fail in quirks mode
@@ -30,17 +35,17 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt(dojo.query(".dijitArrowButton", dijit.byId("dtb").domNode)[0], 500);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt(query(".dijitArrowButton", registry.byId("dtb").domNode)[0], 500);
+							robot.mouseClick({left: true}, 500);
 
 							// Click Dec 4, 2010
-							doh.robot.mouseMoveAt(function(){
-								return dojo.query(".dijitCalendarDateLabel", dijit.byId("dtb_popup").domNode)[6];
+							robot.mouseMoveAt(function(){
+								return query(".dijitCalendarDateLabel", registry.byId("dtb_popup").domNode)[6];
 							} , 1000);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("12/4/2010", dijit.byId("dtb").get("displayedValue"));
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("12/4/2010", registry.byId("dtb").get("displayedValue"));
 							}), 500);
 
 							return d;
diff --git a/dijit/tests/robot/_Widget-deferredConnect.html b/dijit/tests/robot/_Widget-deferredConnect.html
index 36c8342..422eeb6 100644
--- a/dijit/tests/robot/_Widget-deferredConnect.html
+++ b/dijit/tests/robot/_Widget-deferredConnect.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
-	<title>doh.robot deferred connect tests</title>
+	<title>robot deferred connect tests</title>
 
 	<style>
 		@import "../../../util/doh/robot/robot.css";
@@ -10,30 +10,25 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
-
-	<!-- functions to help test -->
-	<script type="text/javascript" src="../helpers.js"></script>
+		data-dojo-config="isDebug: true, async: true"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.robotx");
-
-		dojo.ready(function(){
-
-			doh.robot.initRobot('../_Widget-deferredConnect.html');
+		require([
+			"doh/runner", "dojo/robotx", "dojo/domReady!"
+		], function(doh, robot){
+			robot.initRobot('../_Widget-deferredConnect.html');
 
 			// Test that deferred connections get set up correctly when they need to be
 			// (_Widget only does the dojo.connect() for onmousemove if it needs to)
-			doh.register("deferredConnect",
-			[
+			doh.register("deferredConnect", [
 				{
 					name: "mouse move on widget where onmousemove overridden",
 					timeout: 5000,
 					runTest: function(){
 						var d = new doh.Deferred();
-						doh.robot.mouseMoveAt("overrode", 500);
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.t(dojo.global.overrodeMouseMoved, "overrode button event handler fired");
+						robot.mouseMoveAt("overrode", 500);
+						robot.sequence(d.getTestCallback(function(){
+							doh.t(robot.window.overrodeMouseMoved, "overrode button event handler fired");
 						}), 500);
 						return d;
 					}
@@ -43,10 +38,10 @@
 					timeout: 5000,
 					runTest: function(){
 						var d = new doh.Deferred();
-						doh.robot.mouseMoveAt("connect", 500);
+						robot.mouseMoveAt("connect", 500);
 
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.t(dojo.global.connectedMouseMoved, "connected button event handler fired");
+						robot.sequence(d.getTestCallback(function(){
+							doh.t(robot.window.connectedMouseMoved, "connected button event handler fired");
 						}), 500);
 						return d;
 					}
@@ -56,11 +51,11 @@
 					timeout: 5000,
 					runTest: function(){
 						var d = new doh.Deferred();
-						doh.robot.mouseMoveAt("both", 500);
+						robot.mouseMoveAt("both", 500);
 
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.t(dojo.global.bothOverrodeMouseMoved, "dojo/method handler fired");
-							doh.t(dojo.global.bothConnectedMouseMoved, "dojo/connect handler fired");
+						robot.sequence(d.getTestCallback(function(){
+							doh.t(robot.window.bothOverrodeMouseMoved, "dojo/method handler fired");
+							doh.t(robot.window.bothConnectedMouseMoved, "dojo/connect handler fired");
 						}), 500);
 						return d;
 					}
diff --git a/dijit/tests/robot/_Widget-ondijitclick_a11y.html b/dijit/tests/robot/_Widget-ondijitclick_a11y.html
index 9ab7420..92f60cb 100644
--- a/dijit/tests/robot/_Widget-ondijitclick_a11y.html
+++ b/dijit/tests/robot/_Widget-ondijitclick_a11y.html
@@ -5,30 +5,37 @@
 
 	<title>Test Dijit Internal Event: "ondijitclick"</title>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
 	<script type="text/javascript">
-		dojo.require("dijit.robotx");
+		require([
+			"doh/runner", "dojo/robotx",
+			"dojo/_base/array", "dojo/aspect", "dojo/dom", "dojo/keys", "dojo/on", "dojo/domReady!"
+		], function(doh, robot, array, aspect, dom, keys, on){
 
-		dojo.ready(function(){
-			doh.robot.initRobot('../_Widget-ondijitclick.html');
+			robot.initRobot('../_Widget-ondijitclick.html');
 
 			// Event monitoring
 			var widgetClicks = 0, buttonClicks = 0, button2Clicks = 0, thirdClicks = 0;
 			var w;
 
+			doh.register(function setup(){
+				// get pointer to registry in the iframe
+				registry = robot.window.require("dijit/registry");
+			});
+
 			doh.register("setup", function(){
-				doh.robot.sequence(function(){
-					w = dijit.byId("first");
-					dojo.connect(w, "_onClick", function(){
+				robot.sequence(function(){
+					w = registry.byId("first");
+					aspect.after(w, "_onClick", function(){
 						widgetClicks++;
-					});
-					dojo.connect(dojo.byId("plainbutton"), "onclick", function(){
+					}, true);
+					on(dom.byId("plainbutton", robot.doc), "click", function(){
 						buttonClicks++;
 					});
-					dojo.connect(dojo.byId("plainbutton2"), "onclick", function(){
+					on(dom.byId("plainbutton2", robot.doc), "click", function(){
 						button2Clicks++;
 					});
-					dojo.connect(dojo.byId("third"), "onclick", function(){
+					on(dom.byId("third", robot.doc), "click", function(){
 						thirdClicks++;
 					});
 				});
@@ -36,7 +43,7 @@
 
 			// Test ondijitclick on a <div> which refocuses onto a native <button> node.
 			// Make sure that the <button> doesn't get a spurious click event.
-			dojo.forEach(["SPACE", "ENTER"], function(key){
+			array.forEach(["SPACE", "ENTER"], function(key){
 
 				doh.register("ondijitclick by " + key, [
 					{
@@ -47,15 +54,15 @@
 							var d = new doh.Deferred();
 
 							// Keyboard-click the widget
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								w.domNode.focus();
 							}, 500);
-							doh.robot.keyDown(dojo.keys[key], 250, {});
-							doh.robot.keyUp(dojo.keys[key], 250, {});
+							robot.keyDown(keys[key], 250, {});
+							robot.keyUp(keys[key], 250, {});
 
 							// Check that ondijitclick fired but no spurious event
 							// on the widget that got focused in the ondijitclick handler
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is(1, widgetClicks, "ondijitclick handler fired");
 								doh.is(0, buttonClicks, "spurious button click event");
 							}), 500);
@@ -70,18 +77,24 @@
 							widgetClicks = buttonClicks = 0;
 							var d = new doh.Deferred();
 
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								w.domNode.focus();
 							}, 500);
 				
-							// Try shift-space/shift-enter just to make sure it doesn't do anything.
+							// Try shift-space/shift-enter.
 							// Don't try ctrl-space or meta-space since those keystrokes have special functions
-							// (like context menu) in various browsers
-							doh.robot.keyPress(dojo.keys[key], 100, {shift: true});
+							// (like context menu) in various browsers.
 
-							// Check that ondijitclick didn't fire
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(0, widgetClicks, "ondijitclick handler wasn't fired");
+							var shift;
+							aspect.after(w, "onClick", function(evt){
+								shift = evt.shiftKey;
+							}, true);
+
+							robot.keyPress(keys[key], 100, {shift: true});
+
+							robot.sequence(d.getTestCallback(function(){
+								doh.is(1, widgetClicks, "ondijitclick handler fired");
+								doh.t(shift, "shift flag was set");
 								doh.is(0, buttonClicks, "button click handler wasn't fired");
 							}), 500);
 
@@ -93,7 +106,7 @@
 
 			// Test ondijitclick on a <div> which refocuses onto a native <textarea> node.
 			// Tests that the keyboard event gets supressed so it doesn't modify the focused node.
-			dojo.forEach(["SPACE","ENTER"], function(key){
+			array.forEach(["SPACE","ENTER"], function(key){
 
 				doh.register("focus to textarea by " + key, [
 					{
@@ -101,17 +114,17 @@
 						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred(),
-								w = dijit.byId("second");
+								w = registry.byId("second");
 
 							// Keyboard-click the widget
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								w.domNode.focus();
 							}, 500);
-							doh.robot.keyPress(dojo.keys[key], 500, {});
+							robot.keyPress(keys[key], 500, {});
 
 							// Check that ondijitclick fired but that focused textarea didn't get the key
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("hello world", dojo.byId("textarea").value);
+							robot.sequence(d.getTestCallback(function(){
+								doh.is("hello world", dom.byId("textarea", robot.doc).value);
 							}), 500);
 
 							return d;
@@ -122,7 +135,7 @@
 
 			// Test onclick on a <button> which refocuses onto a <div> w/an ondijitclick handler.
 			// Make sure that the <div> doesn't get a spurious click event.
-			dojo.forEach(["SPACE", "ENTER" ], function(key){
+			array.forEach(["SPACE", "ENTER"], function(key){
 
 				doh.register("focus to ondijitclick-div by " + key, [
 					{
@@ -132,16 +145,16 @@
 							button2Clicks = thirdClicks = 0;
 
 							var d = new doh.Deferred(),
-								button = dojo.byId("plainbutton2");
+								button = dom.byId("plainbutton2", robot.doc);
 
 							// Keyboard-click the native button
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								button.focus();
 							}, 500);
-							doh.robot.keyPress(dojo.keys[key], 500, {});
+							robot.keyPress(keys[key], 500, {});
 
 							// Check that ondijitclick didn't fire
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is(1, button2Clicks, "button2 was clicked (and focus moved to ondijitclick-div)");
 								doh.is(0, thirdClicks, "ondijitclick-div didn't get a spurious click event");
 							}), 500);
@@ -154,7 +167,7 @@
 
 			// Test clicking on a <button> with an ondijitclick handler.
 			// The main danger is getting two click events because the browser natively handles space-->click
-			dojo.forEach(["SPACE", "ENTER" ], function(key){
+			array.forEach(["SPACE", "ENTER"], function(key){
 
 				doh.register("click ondijitclick button by " + key, [
 					{
@@ -163,19 +176,19 @@
 						runTest: function(){
 
 							var d = new doh.Deferred(),
-								buttonWidget = dijit.byId("widgetbutton"),
-								buttonNode = dojo.byId("widgetbutton");
+								buttonWidget = registry.byId("widgetbutton"),
+								buttonNode = dom.byId("widgetbutton", robot.doc);
 
 							buttonWidget.clickCount = 0;
 
 							// Keyboard-click the widget button
-							doh.robot.sequence(function(){
+							robot.sequence(function(){
 								buttonNode.focus();
 							}, 500);
-							doh.robot.keyPress(dojo.keys[key], 500, {});
+							robot.keyPress(keys[key], 500, {});
 
 							// Check that ondijitclick fired exactly once
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is(1, buttonWidget.clickCount, "one click event");
 							}), 500);
 
@@ -185,6 +198,40 @@
 				]);
 			});
 
+			doh.register("bubbling", [
+				{
+					name: "bubbling",
+					timeout: 5000,
+					runTest: function(){
+
+						var d = new doh.Deferred(),
+							outerDiv = dom.byId("outer", robot.doc),
+							buttonNode = dom.byId("bubbleTestWidget", robot.doc),
+							buttonWidget = registry.byId("bubbleTestWidget");
+
+						// Listen for click events on the outer DOMNode.
+						var clicks = 0;
+						on(outerDiv, "click", function(){
+							clicks++;
+						});
+
+						// Keyboard-click the widget button
+						robot.sequence(function(){
+							buttonNode.focus();
+						}, 500);
+						robot.keyPress(keys.ENTER, 500, {});
+
+						// Check that one click event bubbled
+						robot.sequence(d.getTestCallback(function(){
+							doh.is(1, buttonWidget.clickCount, "one click event");
+							doh.is(1, clicks, "one click event bubbled");
+						}), 500);
+
+						return d;
+					}
+				}
+			]);
+
 			doh.run();
 		});
 
diff --git a/dijit/tests/robot/_Widget-ondijitclick_mouse.html b/dijit/tests/robot/_Widget-ondijitclick_mouse.html
index 9ddaebe..62d4a41 100644
--- a/dijit/tests/robot/_Widget-ondijitclick_mouse.html
+++ b/dijit/tests/robot/_Widget-ondijitclick_mouse.html
@@ -5,38 +5,45 @@
 
 	<title>Test Dijit Internal Event: "ondijitclick"</title>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
-		dojo.require("dijit.robotx");
+		require([
+			"doh/runner", "dojo/robotx",
+			"dojo/aspect", "dojo/dom", "dojo/on", "dojo/domReady!"
+		], function(doh, robot, aspect, dom, on){
 
-		dojo.ready(function(){
-			doh.robot.initRobot('../_Widget-ondijitclick.html');
+			robot.initRobot('../_Widget-ondijitclick.html');
 
 			// Event monitoring
 			var widgetClicks = 0, buttonClicks = 0;
 			var w;
 
+			doh.register(function setup(){
+				// get pointer to registry in the iframe
+				registry = robot.window.require("dijit/registry");
+			});
+
 			doh.register("ondijitclick w/mouse", {
 				timeout:5000,
 				runTest:function(){
 					var d = new doh.Deferred();
 
-					doh.robot.sequence(function(){
-						w = dijit.byId("first");
-						dojo.connect(w, "_onClick", function(){
+					robot.sequence(function(){
+						w = registry.byId("first");
+						aspect.after(w, "_onClick", function(){
 							widgetClicks++;
-						}),
-								dojo.connect(dojo.byId("plainbutton"), "onclick", function(){
-									buttonClicks++;
-								});
+						}, true);
+						on(dom.byId("plainbutton", robot.doc), "click", function(){
+							buttonClicks++;
+						});
 						w.domNode.focus();
 					}, 100);
 
 					// click the widget
-					doh.robot.mouseMoveAt("first", 500);
-					doh.robot.mouseClick({left: true}, 500);
+					robot.mouseMoveAt("first", 500);
+					robot.mouseClick({left: true}, 500);
 
-					doh.robot.sequence(d.getTestCallback(function(){
+					robot.sequence(d.getTestCallback(function(){
 						doh.is(1, widgetClicks, "ondijitclick handler fired once");
 					}), 1000);
 
@@ -52,16 +59,48 @@
 					runTest: function(){
 
 						var d = new doh.Deferred(),
-							buttonWidget = dijit.byId("widgetbutton");
+							buttonWidget = registry.byId("widgetbutton");
 
 						buttonWidget.clickCount = 0;
 
-						doh.robot.mouseMoveAt("widgetbutton", 500);
-						doh.robot.mouseClick({left: true}, 500);
+						robot.mouseMoveAt("widgetbutton", 500);
+						robot.mouseClick({left: true}, 500);
 
 						// Check that ondijitclick fired exactly once
-						doh.robot.sequence(d.getTestCallback(function(){
+						robot.sequence(d.getTestCallback(function(){
+							doh.is(1, buttonWidget.clickCount, "one click event");
+						}), 500);
+
+						return d;
+					}
+				}
+			]);
+
+			doh.register("bubbling", [
+				{
+					name: "bubbling",
+					timeout: 5000,
+					runTest: function(){
+
+						var d = new doh.Deferred(),
+							outerDiv = dom.byId("outer", robot.doc),
+							buttonNode = dom.byId("bubbleTestWidget", robot.doc),
+							buttonWidget = registry.byId("bubbleTestWidget");
+
+						// Listen for click events on the outer DOMNode.
+						var clicks = 0;
+						on(outerDiv, "click", function(){
+							clicks++;
+						});
+
+						// click the widget button
+						robot.mouseMoveAt("bubbleTestWidget", 500);
+						robot.mouseClick({left: true}, 500);
+
+						// Check that one click event bubbled
+						robot.sequence(d.getTestCallback(function(){
 							doh.is(1, buttonWidget.clickCount, "one click event");
+							doh.is(1, clicks, "one click event bubbled");
 						}), 500);
 
 						return d;
diff --git a/dijit/tests/robot/typematic.html b/dijit/tests/robot/typematic.html
new file mode 100644
index 0000000..bd2746d
--- /dev/null
+++ b/dijit/tests/robot/typematic.html
@@ -0,0 +1,103 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>typematic DOH Robot test</title>
+
+	<style>
+		@import "../../../util/doh/robot/robot.css";
+	</style>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner", "dojo/robotx",
+			"dojo/dom", "dojo/keys",
+			"dojo/domReady!"
+		], function(doh, robot, dom, keys){
+			robot.initRobot('../test_typematic.html');
+
+			doh.register("press and hold test", [
+				{
+					name: "keyboard",
+					timeout: 9000,
+					runTest: function(){
+						var
+								d = new doh.Deferred(),
+								input = dom.byId("typematicInput"),
+								v;
+						input.value = "";
+						input.focus();
+
+						robot.keyDown(keys.CTRL, 1000);
+						robot.keyDown(keys.F11, 200);
+						robot.sequence(function(){
+							v = input.value; // get value before releasing key to reduce timing dependence on the robot
+						}, 2000);
+						robot.keyUp(keys.F11, 100);
+						robot.keyUp(keys.CTRL, 100);
+
+						robot.sequence(d.getTestCallback(function(){
+							// allow off by 1
+							doh.t(v == "aaaaaaaaaa" || v == "aaaaaaaaaaa" || v == "aaaaaaaaaaaa", "a letters typed " + v);
+						}), 500);
+
+						return d;
+					}
+				},
+				{
+					name: "mouse",
+					timeout: 5000,
+					runTest: function(){
+						var
+								d = new doh.Deferred(),
+								input = dom.byId("typematicInput"),
+								v;
+						input.value = "";
+
+						robot.mouseMoveAt("typematicButton", 500, 1);
+						robot.mousePress({left: true}, 500);
+						robot.sequence(function(){
+							v = input.value; // get value before releasing button to reduce timing dependence on the robot
+						}, 1000);
+						robot.mouseRelease({left: true}, 100);
+
+						robot.sequence(d.getTestCallback(function(){
+							// allow off by 1
+							doh.t(v == "bbbbbb" || v == "bbbbbbb" || v == "bbbbbbbb", "b letters typed " + v);
+						}), 500);
+
+						return d;
+					}
+				},
+				{
+					name: "double click",
+					timeout: 5000,
+					runTest: function(){
+						var
+								d = new doh.Deferred(),
+								input = dom.byId("typematicInput");
+						input.value = "";
+
+						robot.mouseMoveAt("typematicButton", 500, 1);
+						robot.mousePress({left: true}, 500);
+						robot.mouseRelease({left: true}, 100);
+						robot.mousePress({left: true}, 100);
+						robot.mouseRelease({left: true}, 100);
+
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("bb", input.value, "b letters typed " + input.value);
+						}), 500);
+
+						return d;
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+</html>
diff --git a/dijit/tests/test_Calendar.html b/dijit/tests/test_Calendar.html
index 2e4deb6..f60f03f 100644
--- a/dijit/tests/test_Calendar.html
+++ b/dijit/tests/test_Calendar.html
@@ -1,14 +1,10 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Calendar Widget Test</title>
 
-		<!-- for tests -->
-		<style type="text/css">
-			@import "../themes/claro/document.css";
-			@import "css/dijitTests.css";
-		</style>
+		<script type="text/javascript" src="boilerplate.js"></script>
 
 		<style>
 			#calendar5 .dijitCalendarDateTemplate { height: 50px; width: 50px; border: 1px solid #ccc; vertical-align: top }
@@ -16,42 +12,30 @@
 			#calendar5 .dijitCalendarDayLabel { font-weight: bold }
 			#calendar5 .dijitCalendarSelectedYear { font-size: 1.5em }
 			#calendar5 .dijitCalendarMonthLabel { font-family: serif; letter-spacing: 0.2em; font-size: 2em }
-			.blue { color: blue }
+			.blue { color: blue !important /* override claro rule */ }
 		</style>
 
-		<!-- required: a default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-		<!-- not needed, for testing alternate themes -->
-		<script type="text/javascript" src="_testCommon.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-			dojo.require("dijit.Calendar");
-			dojo.require("dojo.date.locale");
-			dojo.require("dojo.parser"); // scan page for widgets
-
-			dojo.ready(function(){
-				//Need to declare BigCalendar here in an addOnLoad block so that it works
-				//with xdomain loading, where the dojo.require for dijit.Calendar
-				//may load asynchronously. This also means we cannot have HTML
-				//markup in the body tag for BigCalendar, but instead inject it in this
-				//onload handler after BigCalendar is defined.
-				dojo.declare("BigCalendar", dijit.Calendar, {
-					templateString: dojo.cache("dijit.tests", "_altCalendar.html"),
-					isDisabledDate: dojo.date.locale.isWeekend,
+			require([
+				"dojo/_base/declare",
+				"dojo/date/locale",
+				"dojo/parser",
+				"dijit/Calendar",
+				"dojo/domReady!"
+			], function(declare, locale, parser, Calendar){
+				declare("BigCalendar", Calendar, {
+					isDisabledDate: locale.isWeekend,
 					getClassForDate: function(date){
 						if(!(date.getDate() % 10)){ return "blue"; } // apply special style to all days divisible by 10
 					}
 				});
 
-				var bigCalendar = dojo.byId("calendar5");
-				bigCalendar.setAttribute("data-dojo-type", "BigCalendar");
-				dojo.parser.parse(bigCalendar.parentNode);
+				parser.parse();
+
+				disableWeekends = function(){
+					calendar1.isDisabledDate = locale.isWeekend;
+					calendar1._populateGrid();
+				};
 			});
 
 			function myHandler(id,newValue){
@@ -59,28 +43,18 @@
 			}
 		</script>
 	</head>
-	<body class="claro">
+	<body class="claro" role="main">
 
 		<h1 class="testTitle">Dijit Calendar Test</h1>
 
-		<input value="input before" id="before"/>
-		<input id="calendar1" data-dojo-type="dijit.Calendar" data-dojo-props='onChange:function(v){ myHandler(this.id, v) }'/>
-		<input value="input after" id="after"/>
+		<label for="before">input before: </label><input id="before"/>
+		<input id="calendar1" data-dojo-id="calendar1" data-dojo-type="dijit/Calendar" summary="Small calendar" data-dojo-props='onChange:function(v){ myHandler(this.id, v) }'/>
+		<label for="after">input after: </label><input id="after"/>
 		<p>
-			<a href="#"
-			   onClick="dijit.registry.forEach(function(c){
-			   		if(c.isDisabledDate){
-						c.isDisabledDate = dojo.date.locale.isWeekend;
-						c._populateGrid();
-					}
-				});">disable weekends</a>
+			<a href="#" onclick="disableWeekends();">disable weekends</a>
 		</p>
 
-		<p>Customized template with "today" button</p>
-		<div>
-			<!-- Parent div used so we have a handle to use for dojo.parser.parse after BigCalendar gets defined. -->
-			<!-- The input below will be replaced by BigCalendar which is defined in a dojo.ready block. -->
-			<input id="calendar5" data-dojo-props='dayWidth:"abbr"' value="2008-03-14"/>
-		</div>
+		<p>Big Calendar</p>
+		<input id="calendar5" data-dojo-type="BigCalendar" data-dojo-props='dayWidth:"abbr"' value="2008-03-14"/>
 	</body>
 </html>
diff --git a/dijit/tests/test_CalendarLite.html b/dijit/tests/test_CalendarLite.html
deleted file mode 100644
index ab5eb65..0000000
--- a/dijit/tests/test_CalendarLite.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>CalendarLite Widget Test</title>
-
-		<!-- for tests -->
-		<style type="text/css">
-			@import "../themes/claro/document.css";
-			@import "css/dijitTests.css";
-		</style>
-
-		<!-- required: a default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../dojo/dojo.js"
-			data-dojo-config="isDebug: true"></script>
-
-		<!-- not needed, for testing alternate themes -->
-		<script type="text/javascript" src="_testCommon.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.CalendarLite");
-
-			dojo.ready(function(){
-				new dijit.CalendarLite({
-					onChange: function myHandler(id,newValue){
-						console.debug("onChange for id = " + id + ", value: " + newValue);
-					}
-				}, dojo.byId("calendar1"));
-			});
-		</script>
-	</head>
-	<body class="claro">
-
-		<h1 class="testTitle">Dijit CalendarLite Test</h1>
-
-		<input value="input before" id="before"/>
-		<input id="calendar1"/>
-		<input value="input after" id="after"/>
-	</body>
-</html>
diff --git a/dijit/tests/test_ColorPalette.html b/dijit/tests/test_ColorPalette.html
index e836756..4de8525 100644
--- a/dijit/tests/test_ColorPalette.html
+++ b/dijit/tests/test_ColorPalette.html
@@ -1,72 +1,52 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>ColorPalette Test</title>
 
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
-	</style>
+	<script src="boilerplate.js" data-dojo-config="extraLocale: ['en-us', 'es-mx']"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+	<script type="text/javascript">
+		require(["dojo/dom", "dojo/parser", "dijit/ColorPalette", "dojo/domReady!"],
+				function(dom, parser, ColorPalette){
 
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true, async:0, extraLocale: ['en-us', 'es-mx']"></script>
+			setColor = function(color){
+				var theSpan = dom.byId("outputSpan");
+				theSpan.style.color = color;
+				theSpan.innerHTML = color;
+			};
 
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
+			parser.parse();
 
-	<script type="text/javascript">
-		var palette;
-	
-		function programatic(){ 
 			var date0 = new Date();
-			palette = new dijit.ColorPalette({palette: "7x10", id: "prog"}, dojo.byId("programPalette"));
+			var palette = new ColorPalette({palette: "7x10", id: "prog", "aria-label": "programatic label"}, "programPalette");
 			console.log("creation time for 7x10 palette: " + (new Date() - date0) );
-		}
-
-		function setColor(color){
-			var theSpan = dojo.byId("outputSpan");
-			theSpan.style.color = color;
-			theSpan.innerHTML = color;
-		}
+		});
 
-		var async= 0;
-		if(async){
-			require(["dijit/dijit", "dijit/ColorPalette", "dojo/parser", "dojo/domReady!"], programatic);
-		}else{
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-			dojo.require("dijit.ColorPalette");
-			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-			dojo.ready(programatic);
-		}
 	</script>
 </head>
 
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">dijit.ColorPalette test:</h1>
 
 	<p>Large color palette (7x10), English tooltips:</p>
-	<input id="beforeBig" value="for tabIndex testing"/>
-	<div id="big" data-dojo-type="dijit.ColorPalette" data-dojo-props='onChange:function(){ setColor(this.value); }, lang:"en-us", summary:"This is the palette summary"'></div>
-	Test color is: <span id="outputSpan"></span>.
+	<label for="beforeBig">label:</label><input id="beforeBig" value="for tabIndex testing"/>
+	<div id="big" data-dojo-type="dijit/ColorPalette" data-dojo-props='onChange:function(){ setColor(this.value); }, lang:"en-us", "aria-label":"This is the palette label"'></div>
+	<label for="afterBig">Test color is:</label> <span id="outputSpan"></span>.
 	<input id="afterBig" value="for tabIndex testing"/>
 
 	<p>Small color palette (3x4), Spanish tooltips:</p>
-	<input id="beforeSmall" value="for tabIndex testing"/>
-	<div id="small" data-dojo-type="dijit.ColorPalette" data-dojo-props='palette:"3x4", lang:"es-mx"'></div>
-	<input id="afterSmall" value="for tabIndex testing"/>
+	<label for="beforeSmall">label:</label><input id="beforeSmall" value="for tabIndex testing"/>
+	<div id="small" data-dojo-type="dijit/ColorPalette" data-dojo-props='palette:"3x4", lang:"es-mx","aria-label":"Small color palette"'></div>
+	<label for="afterSmall">label:</label><input id="afterSmall" value="for tabIndex testing"/>
 
 	<p>Default color palette (7x10) created programatically:</p>
 	<div id="programPalette"></div>
 
 	<p>ColorPalette with value pre-selected, using old style parser parameters:</p>
-	<input id="beforeValuePreselected" value="for tabIndex testing"/>
-	<div id="valuePreselected" dojoType="dijit.ColorPalette" value="#0000ff"></div>
-	<input id="afterValuePreselected" value="for tabIndex testing"/>
+	<label for="beforeValuePreselected">label:"</label><input id="beforeValuePreselected" value="for tabIndex testing"/>
+	<label for="valuePreselected">label for color palette</label><div id="valuePreselected" dojoType="dijit.ColorPalette" value="#0000ff"></div>
+	<label for="afterValuePreselected">label:</label><input id="afterValuePreselected" value="for tabIndex testing"/>
 </body>
 </html>
diff --git a/dijit/tests/test_Declaration.html b/dijit/tests/test_Declaration.html
index 2a39802..174c618 100644
--- a/dijit/tests/test_Declaration.html
+++ b/dijit/tests/test_Declaration.html
@@ -5,34 +5,23 @@
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 
 	<title>Dojo Toolkit - Declaration test</title>
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
-	</style>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
+	<script type="text/javascript" src="boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Declaration");
-		dojo.require("dijit.ProgressBar");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		dojo.require("dojo.on");
-		dojo.require("doh.runner");
-
-		dojo.ready(function(){
+		require([
+			"doh/runner",
+			"dojo/on",
+			"dojo/parser",
+			"dijit/Declaration",
+			"dijit/ProgressBar",
+				"dojo/domReady!"
+		], function(doh, on, parser){
+
 			doh.register("dijit.Declaration", [
 				function parse(){
 					// run parser inside of DOH so we can tell if there are any exceptions
-					dojo.parser.parse();
+					parser.parse();
 
 					// test instantiation of dojo.Declaration widgets
 					doh.t(hideButtonA, "hideButtonA instantiated");
@@ -53,9 +42,13 @@
 					doh.is("blah", m1.foo, "m1.foo");
 					doh.is(73, m2.progress, "m2.progress");
 	
-					// test <script type="dojo/connect">
+					// test <script type="dojo/aspect">
 					doh.t(foo1, "foo1 exists");
-					doh.t(/modified by dojo\/connect event=startup/.test(foo1.domNode.innerHTML), "dojo/connect fired");
+					doh.t(/modified by dojo\/aspect method=startup/.test(foo1.domNode.innerHTML), "dojo/aspect fired");
+				},
+
+				function functions(){
+					doh.is(3, m1.plus(1, 2), "testing function definition with data-dojo-args")
 				},
 
 				function events(){
@@ -66,7 +59,7 @@
 					button1.on("ButtonClick", function(){
 						clicked = true;
 					});
-					dojo.on.emit(button1.domNode, "click", {});
+					on.emit(button1.domNode, "click", {});
 					doh.t(clicked, "clicked");
 				}
 			]);
@@ -79,7 +72,7 @@
 <body class="claro">
 	<h3>Simple macro:</h3>
 	<p>(Check to make sure that links contain employee number)
-	<div data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"Employee", defaults:{ empid: 123, name: "" }'>
+	<div data-dojo-type="dijit/Declaration" data-dojo-props='widgetClass:"Employee", defaults:{ empid: 123, name: "" }'>
 		<span>${name}</span>
 		<a href="update.php?id=${empid}">update</a>
 		<a href="delete.php?id=${empid}">delete</a>
@@ -89,7 +82,7 @@
 	<div data-dojo-type="Employee" data-dojo-props='empid:102, name:"Cathy Cameron"'></div>
 
 	<h3>Using data-dojo-attach-event, data-dojo-attach-point</h3>
-	<div data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"HideButton"'>
+	<div data-dojo-type="dijit/Declaration" data-dojo-props='widgetClass:"HideButton"'>
 		XXX<button data-dojo-attach-event="onclick: myHandler" data-dojo-attach-point="containerNode"></button>XXX
 		<script type='dojo/method' data-dojo-event='myHandler'>
 			this.domNode.style.display="none";
@@ -100,24 +93,27 @@
 
 	<h3>Extending another widget</h3>
 	<p>HideButton2 extends HideButton (above) and changes the template (but keeps the onclick handler).</p>
-	<span data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"HideButton2", mixins:["HideButton"]'>
+	<span data-dojo-type="dijit/Declaration" data-dojo-props='widgetClass:"HideButton2", mixins:["HideButton"]'>
 		YYY<button data-dojo-attach-event="onclick: myHandler" data-dojo-attach-point="containerNode"></button>YYY
 	</span>
 	<button data-dojo-id="hideButton2A" data-dojo-type="HideButton2" >Hide me extended</button>
 	<button data-dojo-id="hideButton2B" data-dojo-type="HideButton2" >Hide me extended #2</button>
 
 	<h3>Using dojo/method:</h3>
-	<div data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"m", defaults:{ foo: "thud", progress: 10 }'>
+	<div data-dojo-type="dijit/Declaration" data-dojo-props='widgetClass:"m", defaults:{ foo: "thud", progress: 10 }'>
 		<script type='dojo/method' data-dojo-event='postCreate'>
 			console.log("in postCreate ", this, arguments);
 			mPrototypeExecuted = true;
 			this.inherited(arguments);
 			this.baz.innerHTML += " (created via custom postCreate) ";
 		</script>
+		<script type='dojo/method' data-dojo-event='plus' data-dojo-args="a, b">
+			return a + b;
+		</script>
 
 		<p>thinger blah stuff ${foo}</p>
 
-		<div data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px", maximum:200,
+		<div data-dojo-type="dijit/ProgressBar" data-dojo-props='style:"width:400px", maximum:200,
 			progress:${progress}'></div>
 		<p data-dojo-attach-point='baz'>baz thud</p>
 	</div>
@@ -125,15 +121,15 @@
 	<div data-dojo-id="m1" data-dojo-type="m" data-dojo-props='foo:"blah", progress:50'></div>
 	<div data-dojo-id="m2" data-dojo-type="m" data-dojo-props='foo:"thinger", progress:73'></div>
 
-	<h3>Using dojo/connect:</h3>
-	<div data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"foo", defaults:{ foo: "thud", progress: 10 }'>
-		<script type='dojo/connect' data-dojo-event='startup'>
-			this.baz.innerHTML += " (modified by dojo/connect event=startup) ";
+	<h3>Using dojo/aspect:</h3>
+	<div data-dojo-type="dijit/Declaration" data-dojo-props='widgetClass:"foo", defaults:{ foo: "thud", progress: 10 }'>
+		<script type='dojo/aspect' data-dojo-method='startup'>
+			this.baz.innerHTML += " (modified by dojo/aspect method=startup) ";
 		</script>
 
 		<p>thinger blah stuff ${foo}</p>
 
-		<div data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px", maximum:200,
+		<div data-dojo-type="dijit/ProgressBar" data-dojo-props='style:"width:400px", maximum:200,
 			progress:${progress}'></div>
 		<p data-dojo-attach-point='baz'>baz thud</p>
 	</div>
@@ -142,7 +138,7 @@
 	<div data-dojo-id="foo2" data-dojo-type="foo" data-dojo-props='foo:"thinger", progress:73'></div>
 
 	<h3>data-dojo-attach-event on root node</h3>
-	<div data-dojo-type="dijit.Declaration"
+	<div data-dojo-type="dijit/Declaration"
 		 	data-dojo-props='widgetClass:"button"'
 			data-dojo-attach-event="onclick: onButtonClick">
 		<script type='dojo/method' data-dojo-event='onButtonClick'>
diff --git a/dijit/tests/test_Dialog.html b/dijit/tests/test_Dialog.html
index 133dfe7..88d21f7 100644
--- a/dijit/tests/test_Dialog.html
+++ b/dijit/tests/test_Dialog.html
@@ -1,124 +1,150 @@
 <!DOCTYPE html>
-<html>
+<html lang='en'>
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>Dialog Widget Dojo Tests</title>
+	<title>Dialog Widget Tests</title>
 
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
+	<script type="text/javascript" src="boilerplate.js"></script>
 
+	<style type="text/css">
 		form { margin-bottom : 0; }
 		table { border: none; }
 		#dialog3_underlay { background-color: #027 }
 		#fifthDlg_underlay { background-color: yellow; }
 	</style>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
-
-
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Dialog");
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dijit.form.DateTextBox");
-		dojo.require("dijit.form.TimeTextBox");
-		dojo.require("dijit.form.FilteringSelect");
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.InlineEditBox");
-		dojo.require("dijit.Menu");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-		// make dojo.toJson() print dates correctly (this feels a bit dirty)
-		Date.prototype.json = function(){ return dojo.date.stamp.toISOString(this, {selector: 'date'});};
-
-		var thirdDlg;
-		function createDialog(){
-			if(!thirdDlg){
-				var pane = dojo.byId('thirdDialog');
-				// should specify a width on dialogs with <p> tags, otherwise they get too wide
-				thirdDlg = new dijit.Dialog({
-					id: "dialog3",
-					title: "Programatic Dialog Creation",
-					style: {width: '300px'}
-				},pane);
-			}
-			setTimeout(function(){ thirdDlg.show(); },"3000");
-		}
-
-		function open2Dialogs(){
-			dijit.byId('dialog1').show();
-			setTimeout(dojo.hitch(dijit.byId('fifthDlg'), 'show'), 1000);
-		}
-		
-		function showSelfDestructDlg(){
-			//for testing #12436
-			var dlg = new dijit.Dialog({
-				id: 'SelfDestructDlg',
-				title: 'Self-Destruct Dialog',
-				content: 'This dialog will destroy itself onHide.<br/><input type="text" id="SelfDestructDlgInput" />',
-				onHide: function(){
-					this.destroyRecursive();
+		require([
+			"dojo/_base/lang",
+			"dojo/date/stamp",
+			"dojo/dom",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/Dialog",
+
+			// used by parser
+			"dijit/Editor",
+			"dijit/_editor/plugins/AlwaysShowToolbar",
+			"dijit/InlineEditBox",
+			"dijit/Menu",
+			"dijit/MenuItem",
+			"dijit/MenuSeparator",
+			"dijit/form/Button",
+			"dijit/form/TextBox",
+			"dijit/form/DateTextBox",
+			"dijit/form/TimeTextBox",
+			"dijit/form/FilteringSelect",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/layout/TabContainer",
+
+			"dojo/domReady!"
+		], function(lang, stamp, dom, parser, registry, Dialog){
+
+			var thirdDlg;
+			createDialog = function(){
+				if(!thirdDlg){
+					var pane = dom.byId('thirdDialog');
+					// should specify a width on dialogs with <p> tags, otherwise they get too wide
+					thirdDlg = new dijit.Dialog({
+						id: "dialog3",
+						title: "Programmatic Dialog Creation",
+						style: {width: '300px'}
+					},pane);
 				}
-			});
-			dlg.show();
-		}
+				setTimeout(function(){ thirdDlg.show(); },"3000");
+			};
+
+			open2Dialogs = function (){
+				registry.byId('dialog1').show();
+				setTimeout(lang.hitch(registry.byId('fifthDlg'), 'show'), 1000);
+			};
+
+			showSelfDestructDlg = function(){
+				//for testing #12436
+				var dlg = new Dialog({
+					id: 'SelfDestructDlg',
+					title: 'Self-Destruct Dialog',
+					content: 'This dialog will destroy itself onHide.<br/><input type="text" id="SelfDestructDlgInput" />',
+					onHide: function(){
+						// Use setTimeout() to avoid memory leak warning for sIEve
+						setTimeout(function(){
+							dlg.destroyRecursive();
+						}, 0);
+					}
+				});
+				dlg.show();
+			};
+
+			parser.parse();
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
+
+	<script type="dojo/require">
+		dom: "dojo/dom",
+		registry: "dijit/registry"
+	</script>
 
-	<h1 class="testTitle">Dijit layout.Dialog tests</h1>
-	<button id="dialog1button" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ dijit.byId("dialog1").show() }'>Show Dialog</button> |
+	<h1 class="testTitle">Dijit.Dialog tests</h1>
 
-	<div id="dialog1" data-dojo-type="dijit.Dialog" data-dojo-props='title:"First Dialog",
+	<h2>General Dialogs:</h2>
+	<button id="dialog1button" data-dojo-type="dijit/form/Button"  data-dojo-props='onClick:function(){ registry.byId("dialog1").show() }'>Show Dialog</button> |
+
+	<div id="dialog1" data-dojo-type="dijit/Dialog" data-dojo-props='title:"First Dialog",
 			"aria-describedby":"intro",
 			onFocus:function(){ console.log("user focus handler") },
 			onBlur:function(){ console.log("user blur handler") },
-			execute:function(args){ console.log("submitted w/args:\n" + dojo.toJson(args, true)); }'>
+			execute:function(args){ console.log("submitted w/args: ", args); }'>
 		<div id="intro" style="width:30em;">Introductory information spoken by screen reader if aria-describedby is
 		added to the declaration of dialog above with value equal to the id of the container element for this text. This technique
 		will work in Dojo 1.4. </div>
-		<table style="position:relative;">
+		<table style="position:relative;" role="presentation">
 			<tr>
 				<td><label for="name">Name: </label></td>
-				<td><input id="name" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"name" '/></td>
+				<td><input id="name" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"text", name:"name" '/></td>
 			</tr>
 			<tr>
 				<td><label for="loc">Location: </label></td>
-				<td><input id="loc" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"loc" '/></td>
+				<td><input id="loc" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"text", name:"loc" '/></td>
 			</tr>
 			<tr>
 				<td><label for="date">Date: </label></td>
-				<td><input id="date" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='type:"text", name:"date" '/></td>
+				<td><input id="date" data-dojo-type="dijit/form/DateTextBox" data-dojo-props='type:"text", name:"date" '/></td>
 			</tr>
 			<tr>
 				<td><label>Time: </label></td>
-				<td><div id="time" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.TimeTextBox", editorParams:{type:"text", name:"time"}, width:"100px", style:"width:100px;"'></div></td>
+				<td><div id="time" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/TimeTextBox", editorParams:{type:"text", name:"time"}, width:"100px", style:"width:100px;"'></div></td>
 			</tr>
 			<tr>
 				<td><label for="desc">Description: </label></td>
-				<td><input id="desc" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"desc" '/></td>
+				<td><input id="desc" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"text", name:"desc" '/></td>
 			</tr>
 			<tr>
 				<td colspan="2" style="text-align:center;">
-					<button id="ok" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit"'>OK</button></td>
+					<button id="ok" data-dojo-type="dijit/form/Button" type="submit">OK</button></td>
 			</tr>
 		</table>
 	</div>
 
+	<div id="dialog1ContextMenu" data-dojo-type="dijit/Menu" data-dojo-props='targetNodeIds:["dialog1"], style:"display: none;"'>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='disabled:true'
+				id="firstMenuItem">Dialog1 Menu</div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Hello world"); }'
+			 	id="enabledMenuItem">Enabled Item</div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='disabled:true'>Disabled Item</div>
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+			onClick:function(){ console.log("not actually cutting anything, just a test!") }'>Cut</div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+			onClick:function(){ console.log("not actually copying anything, just a test!") }'>Copy</div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+			onClick:function(){ console.log("not actually pasting anything, just a test!") }'>Paste</div>
+	</div>
+
 
-	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ createDialog() }, title:"shows after 3 second delay, with blue background"'>Programatic Dialog (3 second delay)</button> |
+	<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ createDialog(); }, title:"shows after 3 second delay, with blue background"'>Programatic Dialog (3 second delay)</button> |
 
 
 	<div id="thirdDialog" style="display: none;">
@@ -126,8 +152,8 @@
 		<input>
 		<br>
 		<button>hello</button>
-		<br>
-		<select>
+		<br><label for="select3">select label</label>
+		<select id="select3">
 			<option>Lorem</option>
 			<option>ipsum</option>
 			<option>dolor</option>
@@ -145,11 +171,11 @@
 		</p>
 	</div>
 
-	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("tabDialog").show() }'>Show TabContainer Dialog</button> |
+	<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("tabDialog").show() }'>Show TabContainer Dialog</button> |
 
-	<div id="tabDialog" data-dojo-type="dijit.Dialog" data-dojo-props='title:"TabContainer Dialog"'>
-		<div id="tc" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 400px; height: 400px;"'>
-			<div id="cp1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"First tab"'>
+	<div id="tabDialog" data-dojo-type="dijit/Dialog" data-dojo-props='title:"TabContainer Dialog"'>
+		<div id="tc" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 400px; height: 400px;"'>
+			<div id="cp1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"First tab"'>
 				<p>
 					This is the first tab.
 				</p>
@@ -162,7 +188,7 @@
 				risus.
 				</p>
 			</div>
-			<div id="cp2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Second tab"'>
+			<div id="cp2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Second tab"'>
 				<p>
 					This is the second tab.
 				</p>
@@ -194,38 +220,38 @@
 		</div>
 	</div>
 
-	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("fifthDlg").show(); }'>Test slow loading HREF Dialog</button> |
+	<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("fifthDlg").show(); }'>Test slow loading HREF Dialog</button> |
 
-	<div id="fifthDlg" data-dojo-type="dijit.Dialog" data-dojo-props='href:"layout/getResponse.php?delay=3000&messId=3",
+	<div id="fifthDlg" data-dojo-type="dijit/Dialog" data-dojo-props='href:"layout/getResponse.php?delay=3000&messId=3",
 		style:"width: 300px", title:"From HREF (slow network simulated)"'></div>
 
-	<button id="filebutton" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("file").show() }'>Show File Dialog</button>
+	<button id="filebutton" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("file").show() }'>Show File Dialog</button>
 
-	<div id="file" data-dojo-type="dijit.Dialog" data-dojo-props='title:"File Dialog",
+	<div id="file" data-dojo-type="dijit/Dialog" data-dojo-props='title:"File Dialog",
 			onFocus:function(){ console.log("user focus handler") },
 			onBlur:function(){ console.log("user blur handler") },
-			execute:function(args){ alert("submitted w/args:\n" + dojo.toJson(args, true)); }, style:"min-width: 350px"'>
+			execute:function(args){ console.log("submitted w/args: ", args); }, style:"min-width: 350px"'>
 		<!-- note: style="min-width: 350px" to workaround FF bug where width is too short, see http://bugs.dojotoolkit.org/ticket/5976 -->
 			<label for="afile">ID File: </label>
-			<input id="afile" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"file", name:"afile" '/>
+			<input id="afile" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"file", name:"afile" '/>
 	</div>
 
-	<button id="unmovablebutton" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("unmovable").show() }'>Show Unmovable</button>
+	<button id="unmovablebutton" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("unmovable").show() }'>Show Unmovable</button>
 
-	<div id="unmovable" data-dojo-type="dijit.Dialog" data-dojo-props='title:"unmovable", draggable:false'>
+	<div id="unmovable" data-dojo-type="dijit/Dialog" data-dojo-props='title:"unmovable", draggable:false'>
 		<p>You should not be able to <br /> drag this dialog</p>
 	</div>
 
-	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("preventer").show() }'>Show Close prevention</button>
+	<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("preventer").show() }'>Show Close prevention</button>
 
-	<div id="preventer" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Confirm Close"'>
+	<div id="preventer" data-dojo-type="dijit/Dialog" data-dojo-props='title:"Confirm Close"'>
 		I am done entering data:
-		<button id="preventerOK" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", onClick:function(){ return confirm("Are you sure?") }'>OK</button>
+		<button id="preventerOK" data-dojo-type="dijit/form/Button" type="submit" onClick='return confirm("Are you sure?");'>OK</button>
 	</div>
 
-	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("embedded").show() }'>Dialog w/embedded layout widgets</button> |
+	<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("embedded").show() }'>Dialog w/embedded layout widgets</button> |
 
-	<div id="embedded" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Embedded layout widgets",
+	<div id="embedded" data-dojo-type="dijit/Dialog" data-dojo-props='title:"Embedded layout widgets",
 		onShow:function(){ this.domNode.setAttribute("aria-describedby", "describe"); } '>
 		<p id="describe">
 			The pane has some text, plus two embedded layout widgets, which should
@@ -234,8 +260,8 @@
 		<p>
 			Here's a BorderContainer:
 		</p>
-		<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
+		<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 				1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -250,7 +276,7 @@
 				sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 				ut eros sit amet ante pharetra interdum.
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='region:"center"'>
 				2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -269,8 +295,8 @@
 		<p>
 			And a TabContainer:
 		</p>
-		<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
+		<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 1"'>
 				1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -285,7 +311,7 @@
 				sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 				ut eros sit amet ante pharetra interdum.
 			</div>
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tab 2"'>
 				2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -308,12 +334,12 @@
 	
 	
 	<!-- Action Bar test case -->
-	<button id="ABDlg1Btn" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ dijit.byId("ABDlg1").show() }'>Show Dialog With Action Buttons</button>
-	<div id="ABDlg1" data-dojo-type="dijit.Dialog" data-dojo-props='title:"ActionBar Dialog 1",
+	<button id="ABDlg1Btn" data-dojo-type="dijit/form/Button"  data-dojo-props='onClick:function(){ registry.byId("ABDlg1").show() }'>Show Dialog With Action Buttons</button>
+	<div id="ABDlg1" data-dojo-type="dijit/Dialog" data-dojo-props='title:"ActionBar Dialog 1",
 			onExecute:function(){ console.log("OK button pressed") },
 			onCancel:function(){ console.log("Cancel button pressed") },
 			"aria-describedby":"intro",
-			execute:function(args){ console.log("submitted w/args:\n" + dojo.toJson(args, true)); }'>
+			execute:function(args){ console.log("submitted w/args: ", args); }'>
 		<div class="dijitDialogPaneContentArea">
 			<div id="ABintro1" style="width:30em;">Introductory information spoken by screen reader if aria-describedby is
 			added to the declaration of dialog above with value equal to the id of the container element for this text. This technique
@@ -322,18 +348,18 @@
 		
 		
 		<div class="dijitDialogPaneActionBar">
-			<button id="ABdialog1button1" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit" '>OK</button>
-			<button id="ABdialog1button2" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ dijit.byId("ABDlg1").onCancel(); } 
+			<button id="ABdialog1button1" data-dojo-type="dijit/form/Button" type="submit">OK</button>
+			<button id="ABdialog1button2" data-dojo-type="dijit/form/Button" type="button" data-dojo-props='onClick:function(){ registry.byId("ABDlg1").onCancel(); }
 					'>Cancel</button>
 		</div>
 	</div>
 	
-	<button id="NABDlgBtn" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ dijit.byId("NABDlg").show() }'>Show Dialog With No Action Buttons</button>
-	<div id="NABDlg" data-dojo-type="dijit.Dialog" data-dojo-props='title:"No Action Bar Dialog",
+	<button id="NABDlgBtn" data-dojo-type="dijit/form/Button"  data-dojo-props='onClick:function(){ registry.byId("NABDlg").show() }'>Show Dialog With No Action Buttons</button>
+	<div id="NABDlg" data-dojo-type="dijit/Dialog" data-dojo-props='title:"No Action Bar Dialog",
 			"aria-describedby":"intro",
 			onFocus:function(){ console.log("user focus handler") },
 			onBlur:function(){ console.log("user blur handler") },
-			execute:function(args){ console.log("submitted w/args:\n" + dojo.toJson(args, true)); }'>
+			execute:function(args){ console.log("submitted w/args: ", args); }'>
 				
 		<div class="dijitDialogPaneContentArea">
 			<div id="NABintro" style="width:30em;">Introductory information spoken by screen reader if aria-describedby is
@@ -342,36 +368,36 @@
 			<table>
 				<tr>
 					<td><label for="NABname">Name: </label></td>
-					<td><input id="NABname" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"NABname" '/></td>
+					<td><input id="NABname" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"text", name:"NABname" '/></td>
 				</tr>
 				<tr>
 					<td><label for="NABloc">Location: </label></td>
-					<td><input id="NABloc" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"NABloc" '/></td>
+					<td><input id="NABloc" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"text", name:"NABloc" '/></td>
 				</tr>
 				<tr>
 					<td><label for="NABdate">Date: </label></td>
-					<td><input id="NABdate" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='type:"text", name:"NABdate" '/></td>
+					<td><input id="NABdate" data-dojo-type="dijit/form/DateTextBox" data-dojo-props='type:"text", name:"NABdate" '/></td>
 				</tr>
 				<tr>
 					<td><label for="NABdesc">Description: </label></td>
-					<td><input id="NABdesc" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"NABdesc" '/></td>
+					<td><input id="NABdesc" data-dojo-type="dijit/form/TextBox" data-dojo-props='type:"text", name:"NABdesc" '/></td>
 				</tr>
 			</table>
 		</div>
 	</div>
 
 
-	<button id="layeredDialogs" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:open2Dialogs'>Show 2 Dialogs</button>
+	<button id="layeredDialogs" data-dojo-type="dijit/form/Button"  data-dojo-props='onClick:open2Dialogs'>Show 2 Dialogs</button>
 
-	<button id="iframeDlg" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ dijit.byId("dlgFrame").show(); }'>Show iframe in dialog</button>
-	<div id="dlgFrame" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Search"'>
+	<button id="iframeDlg" data-dojo-type="dijit/form/Button"  data-dojo-props='onClick:function(){ registry.byId("dlgFrame").show(); }'>Show iframe in dialog</button>
+	<div id="dlgFrame" data-dojo-type="dijit/Dialog" data-dojo-props='title:"Search"'>
 		<iframe title="Test IFrame" src="layout/getResponse.php?delay=3000&messId=3" style="width:600px; height: 400px;">
 	</iframe>
 				
 	</div>
 
-	<button id="RadioButtonDlgBtn" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ dijit.byId("RadioButtonDlg").show() }'>Show Dialog With Radio Button at End</button>
-	<div id="RadioButtonDlg" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Radio Button Dialog"'>
+	<button id="RadioButtonDlgBtn" data-dojo-type="dijit/form/Button"  data-dojo-props='onClick:function(){ registry.byId("RadioButtonDlg").show() }'>Show Dialog With Radio Button at End</button>
+	<div id="RadioButtonDlg" data-dojo-type="dijit/Dialog" data-dojo-props='title:"Radio Button Dialog"'>
 	  <div class="dijitDialogPaneContentArea">
 	    <textarea id="textarea-radio-test" width="400" height="200"></textarea>
 	    <fieldset>
@@ -384,10 +410,74 @@
 	  </div>
 	</div>
 	
-	<button id="SelfDestructDlgBtn" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:showSelfDestructDlg'>Show Self-Destruct Dialog</button>
-	<div id="SelfDestructDlgBtn2" style="border: 1px solid black;" class="dijitInline" onclick="showSelfDestructDlg();">Show Self-Destruct Dialog (unfocusable div)</div>
+	<button id="SelfDestructDlgBtn" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:showSelfDestructDlg'>Show Self-Destruct Dialog</button>
+	<div id="SelfDestructDlgBtn2" style="border: 1px solid black;" class="dijitInline" onclick="showSelfDestructDlg();" role="button">Show Self-Destruct Dialog (unfocusable div)</div>
+
+	<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ createDialog() }, title:"shows after 3 second delay, with blue background"'>Programatic Dialog (3 second delay)</button> |
+
+	<button id="unclosableButton" data-dojo-type="dijit/form/Button"  data-dojo-props='onClick:function(){ registry.byId("unclosable").show() }'>Show Unclosable Dialog</button> |
+
+	<div id="unclosable" data-dojo-type="dijit/Dialog" title="Unclosable Dialog" data-dojo-props="closable:false">
+		<div class="dijitDialogPaneContentArea">
+			This dialog has no close icon and the ESCAPE key won't close it.  You need to use the buttons.
+		</div>
+		<div class="dijitDialogPaneActionBar">
+			<button id="unclosableSubmit" data-dojo-type="dijit/form/Button" type="submit">OK</button>
+			<button id="unclosableCancel" data-dojo-type="dijit/form/Button" type="button"
+					onClick='registry.byId("unclosable").onCancel();'>Cancel</button>
+		</div>
+	</div>
 
-	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ createDialog() }, title:"shows after 3 second delay, with blue background"'>Programatic Dialog (3 second delay)</button> |
+	<button id="iebDialogBtn" data-dojo-type="dijit/form/Button"
+			data-dojo-props='onClick:function(){ registry.byId("iebDialog").show(); }'>
+		Show Dialog With InlineEditBox Editors
+	</button> |
+	<div id="iebDialog" data-dojo-type="dijit/Dialog" title="Test Dialog with Autosave Inline Rich Text Editors">
+		<h2>Editor 1</h2>
+		<div id="inlineRTE1" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/Editor",
+            autoSave:true, renderAsHtml:true,
+            editorParams:{id: "RTE1", height: "", extraPlugins: ["dijit._editor.plugins.AlwaysShowToolbar"]}'>
+			first text
+		</div>
+
+		<h2>Editor 2</h2>
+		<div id="inlineRTE2" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/Editor",
+            autoSave:true, renderAsHtml:true,
+            editorParams:{id: "RTE2", height: "", extraPlugins: ["dijit._editor.plugins.AlwaysShowToolbar"]}'>
+			second text
+		</div>
+
+		<h2>Editor 3</h2>
+		<div id="inlineRTE3" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/Editor",
+            autoSave:true, renderAsHtml:true,
+            editorParams:{id: "RTE3", height: "", extraPlugins: ["dijit._editor.plugins.AlwaysShowToolbar"]}'>
+			third text
+		</div>
+
+	</div>
+
+	<h2>Simulated Editor with Dialog:</h2>
+	<div id="editorDialog" data-dojo-type="dijit/Dialog" title="Insert Text" data-dojo-props="refocus: false">
+		<script type="dojo/method" data-dojo-event="execute">
+			var editor = dom.byId("editor"), newVal = dom.byId("dialogTextarea").value;
+			console.log("focusing editor and setting value to " + newVal);
+			editor.focus();
+			editor.value = newVal;
+		</script>
+		<p>
+			Enter text then hit OK.
+			Focus will be shifted to "editor" below and text will be inserted.
+		</p>
+		<textarea id="dialogTextarea" style="width: 90%" placeholder="enter text here"></textarea>
+		<br>
+		<button data-dojo-type="dijit/form/Button" type="submit">OK</button>
+	</div>
+	<div style="background-color: #eee; border: solid gray 1px; width: 90%;">
+		<button id="insertTextButton" onclick="registry.byId('editorDialog').show();">insert text</button>
+	</div>
+	<textarea id="editor" style="width: 90%; border: solid gray 1px; border-top: none;">
+		The button above will open a Dialog to reset the text in this textarea.
+	</textarea>
 
 	<p><b><i>(scroll down to see more links to click, for testing positioning / scroll handling)</i></b></p>
 
@@ -397,11 +487,13 @@
 	</p>
 
 	<form>
+	<label for="plainInput">plainInput</label>
 	<input id="plainInput"/>
 	<br>
 	<button id="plainButton">hello</button>
 	<br>
-	<select>
+	<label for="plainButtonSelect">planeButton Select:</label>
+	<select id="plainButtonSelect">
 		<option>Lorem</option>
 		<option>ipsum</option>
 		<option>dolor</option>
@@ -437,7 +529,8 @@
 	</p>
 	<form>
 		<div style="text-align:center;">
-			<select>
+		  <label for="centerSelect">select:</label>
+			<select id="centerSelect">
 				<option>1</option>
 				<option>2</option>
 			</select>
@@ -492,7 +585,8 @@
 	</p>
 	<form>
 		<div style="text-align:center;">
-			<select>
+			<label for="twoOptionSelect">select:</label>
+			<select id="twoOptionSelect">
 				<option>1</option>
 				<option>2</option>
 			</select>
@@ -514,13 +608,13 @@
 	</p>
 
 	<p>
-	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("dialog1").show() }'>Show Dialog</button> |
+	<button data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ registry.byId("dialog1").show() }'>Show Dialog</button> |
 	<!-- showing a dialog from an anchor with inline onclick="" is a solution to page onUnLoad firing
 		but you must return false; alternatively, you can dojo.connect() to the anchor links, and
 		e.preventDefault() on the event object passed. using href="javascript:" inline causes onUnLoad
 		to destroy all widgets in IE6
 	-->
-	<a href="http://dojotoolkit.org" onclick="dijit.byId('dialog1').show(); return false; ">Show Dialog</a>
+	<a href="http://dojotoolkit.org" onclick="registry.byId('dialog1').show(); return false; ">Show Dialog</a>
 	</p>
 
 	<p>
diff --git a/dijit/tests/test_Dialog_focusDestroy.html b/dijit/tests/test_Dialog_focusDestroy.html
index 955023b..7fa0d21 100644
--- a/dijit/tests/test_Dialog_focusDestroy.html
+++ b/dijit/tests/test_Dialog_focusDestroy.html
@@ -1,63 +1,50 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dialog Widget Dojo Tests</title>
 
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
+	<script type="text/javascript" src="boilerplate.js"></script>
 
+	<style type="text/css">
 		body { font-family : sans-serif; }
 		form { margin-bottom : 0; }
 		table { border: none; }
 		#dialog3_underlay { background-color: #027 }
 	</style>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Dialog");
-		dojo.require("dijit.form.Button");
-
-    //-sie
-    //the dojo.required code might not be here yet!
-    dojo.ready(function(){
+		require(["dojo/parser", "dijit/Dialog", "dijit/form/Button", "dojo/domReady!"], function(parser, Dialog, Button){
 
-		// make dojo.toJson() print dates correctly (this feels a bit dirty)
-		createAndShow= function(){
-			var node = document.createElement("div");
-			dojo.body().appendChild(node);
-			var dlg = new dijit.Dialog({ title: "test input focus" }, node);
+			createAndShow = function(){
+				var node = document.createElement("div");
+				document.body.appendChild(node);
+				var dlg = new Dialog({ title: "test input focus" }, node);
 
-			var input = document.createElement("input");
-			dojo.attr(input,"tabIndex","0");
-			dlg.containerNode.appendChild(input);
+				var input = document.createElement("input");
+				input.tabIndex = 0;
+				dlg.containerNode.appendChild(input);
 
-			var btn = new dijit.form.Button({ id:"destroyButton", label: "Close" });
-			dlg.containerNode.appendChild(btn.domNode);
+				var btn = new Button({
+					id: "destroyButton",
+					label: "Close",
+					onClick: function(){
+						console.log("destroying, while visible");
+						dlg.destroy();
+					}
+				});
+				dlg.containerNode.appendChild(btn.domNode);
 
-			dojo.connect(btn, "onClick", function(){
-				console.log("destroying, while visible");
-				dlg.destroy();
+				dlg.show();
+			};
 
-			});
-			dlg.show();
-		}
+			parser.parse();
 
-    });
+		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Dijit layout.Dialog tests</h1>
 
@@ -65,9 +52,9 @@
 	when you destroy the visible dialog. refs <a href="http://trac.dojotoolkit.org/ticket/5351">#5351</a>
 	</p>
 
-	<input id="testInput" name="foo" value="bar" />
+	<label for="testInput">testInput:</label><input id="testInput" name="foo" value="bar" />
 
-	<button id="showDialog" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ createAndShow() }'>Show Dialog</button>
+	<button id="showDialog" data-dojo-type="dijit/form/Button" data-dojo-props='onClick:function(){ createAndShow() }'>Show Dialog</button>
 
 </body>
 </html>
diff --git a/dijit/tests/test_InlineEditBox.html b/dijit/tests/test_InlineEditBox.html
index f7ae1e9..72db296 100644
--- a/dijit/tests/test_InlineEditBox.html
+++ b/dijit/tests/test_InlineEditBox.html
@@ -4,10 +4,9 @@
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Inline Edit Box Test</title>
 
-		<style type="text/css">
-			@import "../themes/claro/document.css";
-			@import "css/dijitTests.css";
+		<script type="text/javascript" src="boilerplate.js"></script>
 
+		<style type="text/css">
 			.inlineEdit { background-color: #CCC76A; }
 
 			/* some style rules on nodes just to test that style gets copied to the edit widget */
@@ -16,33 +15,31 @@
 			h3 { font-family: helvetica; font-style: italic; }
 		</style>
 
-		<!-- required: a default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../dojo/dojo.js"
-			data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-		<!-- not needed, for testing alternate themes -->
-		<script type="text/javascript" src="_testCommon.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-			dojo.require("dojo.data.ItemFileReadStore");
-			dojo.require("dijit.InlineEditBox");
-			dojo.require("dijit.form.Textarea");
-			dojo.require("dijit.form.TextBox");
-			dojo.require("dijit.form.DateTextBox");
-			dojo.require("dijit.form.CurrencyTextBox");
-			dojo.require("dojo.currency");
-			dojo.require("dijit.form.ComboBox");
-			dojo.require("dijit.form.FilteringSelect");
-			dojo.require("dijit.form.NumberSpinner");
-
-			dojo.require("dijit.Editor");
-			dojo.require("dijit._editor.plugins.AlwaysShowToolbar");
-
-			dojo.require("dojo.parser");	  // scan page for widgets and instantiate them
+			require([
+				"dojo/parser",
+				"dijit/InlineEditBox",
+
+				// used by parser
+				"dojo/data/ItemFileReadStore",
+				"dijit/form/Textarea",
+				"dijit/form/TextBox",
+				"dijit/form/DateTextBox",
+				"dijit/form/CurrencyTextBox",
+				"dojo/currency",
+				"dijit/form/ComboBox",
+				"dijit/form/FilteringSelect",
+				"dijit/form/NumberSpinner",
+				"dijit/form/Select",
+				"dijit/Editor",
+				"dijit/_editor/plugins/AlwaysShowToolbar",
+				"dojo/domReady!"
+			], function(parser, InlineEditBox){
+				parser.parse();
+
+				// programmatic creation
+				new InlineEditBox({ renderAsHtml: true, onChange:myHandler }, 'programmatic');
+			});
 
 			function myHandler(newValue){
 				this._onChangeValue = newValue;	// used by robot test file
@@ -54,8 +51,9 @@
 
 		<h1 class="testTitle">Dijit InlineEditBox Test</h1>
 
-		<span data-dojo-id="stateStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"_data/states.json"'></span>
-		<span data-dojo-id="productStore" data-dojo-type="dojo.data.ItemFileReadStore" >
+		<span data-dojo-id="stateStore" data-dojo-type="dojo/data/ItemFileReadStore" data-dojo-props='url:"_data/states.json"'></span>
+		<span data-dojo-id="countryStore" data-dojo-type="dojo/data/ItemFileReadStore" data-dojo-props='url:"_data/countries.json"'></span>
+		<span data-dojo-id="productStore" data-dojo-type="dojo/data/ItemFileReadStore" >
 			<script type="dojo/method">
 				this._jsonData =
 					{ identifier: 'name',
@@ -71,48 +69,51 @@
 
 		<h2>Form Letter with blanks</h2>
 		<div class="letter">
-			<h3 id="editable" data-dojo-type="dijit.InlineEditBox" data-dojo-props='value:"markup value", onChange:myHandler, autoSave:true, title:"company name"'></h3>
+			<h3 id="editable" data-dojo-type="dijit/InlineEditBox" data-dojo-props='value:"markup value", onChange:myHandler, autoSave:true, title:"company name"'></h3>
 			<p>
-				Dear <span id="MrSmith" data-dojo-type="dijit.InlineEditBox" data-dojo-props='width:"200px", title:"recipient name"'></span>,
+				Dear <span id="MrSmith" data-dojo-type="dijit/InlineEditBox" data-dojo-props='width:"200px", title:"recipient name"'></span>,
 			</p>
 			<p class="letter">
 				Thank you for your recent order.
 				Please remit
-				<span id="dollar_as" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.CurrencyTextBox", editorParams:{currency: "USD"}, width:"100px", title:"dollar amount"'></span> for
+				<span id="dollar_as" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/CurrencyTextBox", editorParams:{currency: "USD"}, width:"100px", title:"dollar amount"'></span> for
 				your purchase of
-				<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.NumberSpinner", editorParams:{constraints: {places:0} }, width:"70px", title:"quantity"'></span> deluxe
-				<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.ComboBox", title:"item name",
+				<span data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/NumberSpinner", editorParams:{constraints: {places:0} }, width:"70px", title:"quantity"'></span> deluxe
+				<span data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/ComboBox", title:"item name",
 					editorParams:{searchAttr: "name", store: productStore, autocomplete: false, hasDownArrow: false},
 					 width:"200px"'></span> on
-				<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.DateTextBox", width:"200px", title:"purchase date as mm/dd/yy"'></span> in
-				<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.FilteringSelect",
+				<span data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/DateTextBox", width:"200px", title:"purchase date as mm/dd/yy"'></span> in
+				<span data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/FilteringSelect",
 					editorParams:{searchAttr: "name", keyAttr: "abbreviation", store: stateStore, autocomplete: true, hasDownArrow: true},
-					 width:"200px", title:"state of purchase"'></span>.
+					 width:"200px", title:"state of purchase"'></span> 
+				<nobr>(<span data-dojo-type="dijit/InlineEditBox"
+					data-dojo-props='editor:"dijit/form/Select", width:"200px", title:"country", editorParams:{ store: countryStore }'
+				></span>)</nobr>.
 			</p>
-			<p id="textarea" data-dojo-type="dijit.InlineEditBox" data-dojo-props='autoSave:true, editor:"dijit.form.Textarea", title:"additional details"'></p>
+			<p id="textarea" data-dojo-type="dijit/InlineEditBox" data-dojo-props='autoSave:true, editor:"dijit/form/Textarea", title:"additional details"'></p>
 			<p>
 				Sincerely,
 			</p>
-			<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='style:"margin-left: 2em; font-family: cursive;", width:"400px", title:"sender name"                                                                           '></span>
+			<span data-dojo-type="dijit/InlineEditBox" data-dojo-props='style:"margin-left: 2em; font-family: cursive;", width:"400px", title:"sender name"                                                                           '></span>
 		</div>
 		<hr style="margin-bottom: 1em;"/>
 
 		<h2>Form Letter with <span id="predefined">predefined values</span>, and no auto-save</h2>
 		<div class="letter">
-			<h3 id="editable2" data-dojo-type="dijit.InlineEditBox" data-dojo-props='onChange:myHandler, autoSave:false, title:"company name"'>
+			<h3 id="editable2" data-dojo-type="dijit/InlineEditBox" data-dojo-props='onChange:myHandler, autoSave:false, title:"company name"'>
 				Bob Vance Refrigeration
 			</h3>
 			<p>
-				Dear <span data-dojo-type="dijit.InlineEditBox" data-dojo-props='width:"200px", autoSave:false, title:"recipient name"'>John</span>,
+				Dear <span data-dojo-type="dijit/InlineEditBox" data-dojo-props='width:"200px", autoSave:false, title:"recipient name"'>John</span>,
 			</p>
 			<p class="letter">
 				Thank you for your recent order.
 				Please remit
-				<span id="dollar" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.CurrencyTextBox", editorParams:{currency: "USD"}, width:"100px", autoSave:false, title:"dollar amount"'>$2,000</span>
+				<span id="dollar" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/CurrencyTextBox", editorParams:{currency: "USD"}, width:"100px", autoSave:false, title:"dollar amount"'>$2,000</span>
 				for your purchase of
-				<span id="quantity" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.NumberSpinner", editorParams:{constraints: {places:0} }, width:"70px", autoSave:false, title:"quantity"'>3</span>
+				<span id="quantity" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/NumberSpinner", editorParams:{constraints: {places:0} }, width:"70px", autoSave:false, title:"quantity"'>3</span>
 				deluxe
-				<span id="item" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.ComboBox",
+				<span id="item" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/ComboBox",
 					editorParams:{searchAttr: "name", store: productStore, autocomplete: false, hasDownArrow: false},
 					 width:"200px", autoSave:false, title:"item name"'>refrigerators</span>
 				on
@@ -122,23 +123,27 @@
 					but since this test is static HTML, we instead hardcode the displayed value and use editorParams
 					to tell DateTextBox to expect that pattern regardless of the machine's locale
 				-->
-				<span id="purchase" data-dojo-type="dijit.InlineEditBox"
-					data-dojo-props='editor:"dijit.form.DateTextBox", editorParams:{constraints: {datePattern: "MM/dd/yyyy"}},
+				<span id="purchase" data-dojo-type="dijit/InlineEditBox"
+					data-dojo-props='editor:"dijit/form/DateTextBox", editorParams:{constraints: {datePattern: "MM/dd/yyyy"}},
 					width:"200px", autoSave:false, title:"purchase date as mm/dd/yy"'>01/05/2007</span>
 				in
-				<span id="state" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.FilteringSelect",
+				<span id="state" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/FilteringSelect",
 					editorParams:{searchAttr: "name", keyAttr: "abbreviation", store: stateStore, autocomplete: true, hasDownArrow: false},
 					 width:"200px", autoSave:false, title:"state of purchase"'>
 					 Pennsylvania
-				</span>.
+				</span> 
+				<nobr>(<span id="country" data-dojo-type="dijit/InlineEditBox"
+					data-dojo-props='editor:"dijit/form/Select", width:"200px", autoSave:false, title:"country",
+					editorParams:{ store: countryStore }'
+				>United States of America</span>)</nobr>.
 			</p>
-			<p data-dojo-type="dijit.InlineEditBox" data-dojo-props='autoSave:false, editor:"dijit.form.Textarea", title:"additional details"'>
+			<p data-dojo-type="dijit/InlineEditBox" data-dojo-props='autoSave:false, editor:"dijit/form/Textarea", title:"additional details"'>
 				We sincerely appreciate your business and hope we can do business again.
 			</p>
 			<p>
 				Sincerely,
 			</p>
-			<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='style:"margin-left: 2em; font-family: cursive;", width:"400px", autoSave:false, title:"sender name"'>Bob Vance</span>
+			<span data-dojo-type="dijit/InlineEditBox" data-dojo-props='style:"margin-left: 2em; font-family: cursive;", width:"400px", autoSave:false, title:"sender name"'>Bob Vance</span>
 		</div>
 		<hr style="margin-bottom: 1em;"/>
 
@@ -151,7 +156,7 @@
 		(before plain inline) <fieldset class="dijitInline"><div style="width: 400px;">hello world</div></fieldset> (after plain inline)
 		<br>
 		(before editable inline)
-		<fieldset class="dijitInline"><div data-dojo-type="dijit.InlineEditBox" data-dojo-props='onChange:myHandler, width:"400px", style:"width: 400px;"'>
+		<fieldset class="dijitInline"><div data-dojo-type="dijit/InlineEditBox" data-dojo-props='onChange:myHandler, width:"400px", style:"width: 400px;"'>
 			hello world
 		</div></fieldset>
 		(after editable inline)
@@ -174,7 +179,7 @@ pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit
 tortor pharetra congue. Suspendisse pulvinar.
 		</p>
 		(before editable paragraph.  the editable paragraph has Save/Cancel buttons when open.)
-		<p id="areaEditable" data-dojo-type="dijit.InlineEditBox" data-dojo-props='autoSave:false, editor:"dijit.form.Textarea"'>
+		<p id="areaEditable" data-dojo-type="dijit/InlineEditBox" data-dojo-props='autoSave:false, editor:"dijit/form/Textarea"'>
 			Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
 imperdiet. Fusce dignissim porta augue. Nulla vestibulum. Integer lorem
 nunc, ullamcorper a, commodo ac, malesuada sed, dolor. Aenean id mi in
@@ -189,13 +194,13 @@ pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit
 tortor pharetra congue. Suspendisse pulvinar.
 		</p>
 		These buttons will
-		<button onClick="dijit.byId('areaEditable').set('disabled', true)">disable</button> /
+		<button id="disableAreaEditable" onClick="dijit.byId('areaEditable').set('disabled', true)">disable</button> /
 		<button onClick="dijit.byId('areaEditable').set('disabled', false)">enable</button>
 		the InlineEditBox above.
 		<hr style="width:100%;"/>
 
 		<h2>Editor</h2>
-		<div id="inlineRTE" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.Editor",
+		<div id="inlineRTE" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit.Editor",
 			autoSave:false, renderAsHtml:true,
 			editorParams:{height: "", extraPlugins: ["dijit._editor.plugins.AlwaysShowToolbar"]}'>
 			<b>Aliquam</b> vitae enim. <i>Duis</i> scelerisque metus auctor est venenatis
@@ -219,7 +224,7 @@ tortor pharetra congue. Suspendisse pulvinar.
 
 		<h2>FilteringSelect (no down arrow, and save/cancel buttons):</h2>
 		before
-		<span id="filteringSelect2" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.FilteringSelect",
+		<span id="filteringSelect2" data-dojo-type="dijit/InlineEditBox" data-dojo-props='editor:"dijit/form/FilteringSelect",
 			editorParams:{searchAttr: "name", keyAttr: "abbreviation", store: stateStore, autocomplete: true, hasDownArrow: false},
 			 width:"200px", autoSave:false'>
 			Indiana
@@ -230,20 +235,15 @@ tortor pharetra congue. Suspendisse pulvinar.
 
 		<h2>Programmatically created:</h2>
 		before block<div style="display:block;" id="programmatic">Click here to edit a block programmatically created inline edit region</div>after
-		<script type="text/javascript">
-			// See if we can make a widget in script
-			dojo.ready(function(){
-				var inlineWidget = new dijit.InlineEditBox({ renderAsHtml: true, onChange:myHandler }, 'programmatic');
- 			});
-		</script>
+
 		<hr style="width:100%;"/>
 		<h2>Complex renderAsHtml="false"</h2>
-		<div id="renderAsHtml_false" data-dojo-type="dijit.InlineEditBox" data-dojo-props='renderAsHtml:false, width:"400px", style:"width:400px;"'>
+		<div id="renderAsHtml_false" data-dojo-type="dijit/InlineEditBox" data-dojo-props='renderAsHtml:false, width:"400px", style:"width:400px;"'>
 			<B>not bold</B>&lt;input&gt;
 		</div>
 		<hr style="width:100%;"/>
 		<h2>Complex renderAsHtml="true"</h2>
-		<div id="renderAsHtml_true" data-dojo-type="dijit.InlineEditBox" data-dojo-props='renderAsHtml:true, width:"400px", style:"width:400px;"'>
+		<div id="renderAsHtml_true" data-dojo-type="dijit/InlineEditBox" data-dojo-props='renderAsHtml:true, width:"400px", style:"width:400px;"'>
 			<B>not bold</B><B>bold</B>&lt;input&gt;
 		</div>
 	</body>
diff --git a/dijit/tests/test_Menu.html b/dijit/tests/test_Menu.html
index d74d7fb..e362e18 100644
--- a/dijit/tests/test_Menu.html
+++ b/dijit/tests/test_Menu.html
@@ -1,15 +1,14 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 
 	<title>Menu System Test</title>
 
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
+	<script type="text/javascript" src="boilerplate.js"></script>
 
+	<style type="text/css">
 		body { padding: 0; }
 
 		/* styling for left-hand-side navigation menu to become a column equal to length of page */
@@ -25,260 +24,258 @@
 		}
 	</style>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.MenuItem");
-		dojo.require("dijit.PopupMenuItem");
-		dojo.require("dijit.CheckedMenuItem");
-		dojo.require("dijit.MenuSeparator");
-
-		dojo.require("dijit.MenuBar");
-		dojo.require("dijit.MenuBarItem");
-		dojo.require("dijit.PopupMenuBarItem");
-
-		dojo.require("dijit.ColorPalette");
-		dojo.require("dijit.form.TextBox");
-
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-	</script>
-
-    <script type="text/javascript">
-        function createMenu(){
-            // create a menu programmatically
-            function fClick(){console.log("clicked!")}
-
-            pMenu = new dijit.Menu({targetNodeIds:["prog_menu"], id:"progMenu"});
-            pMenu.addChild(new dijit.MenuItem({label:"Programmatic Context Menu", disabled:true}));
-            pMenu.addChild(new dijit.MenuSeparator());
-            pMenu.addChild(new dijit.MenuItem({label:"Simple menu item", onClick:fClick, accelKey:"Shift+S"}));
-            pMenu.addChild(new dijit.MenuItem({label:"Another menu item", onClick:fClick, accelKey:"Ctrl+A"}));
-            pMenu.addChild(new dijit.MenuItem({label:"With an icon", iconClass:"dijitEditorIcon dijitEditorIconCut", onClick:fClick}));
-            var mItem = new dijit.MenuItem({label:"dojo.event clicking", accelKey: "Alt+D"});
-            dojo.connect(mItem, "onClick", function(){console.log("click! handler created via dojo.connect()")});
-            pMenu.addChild(mItem);
-
-            mItem = new dijit.CheckedMenuItem({label:"checkable menu item"});
-            pMenu.addChild(mItem);
-
-            var pSubMenu = new dijit.Menu({parentMenu:pMenu, id:"progSubMenu"});
-            pSubMenu.addChild(new dijit.MenuItem({label:"Submenu item", onClick:fClick}));
-            pSubMenu.addChild(new dijit.MenuItem({label:"Submenu item", onClick:fClick}));
-			
-            var pSubSubMenu = new dijit.Menu({parentMenu:pSubMenu, id:"progSubSubMenu"});
-            pSubSubMenu.addChild(new dijit.MenuItem({label:"SubSubmenu item", onClick:fClick}));
-            pSubSubMenu.addChild(new dijit.MenuItem({label:"SubSubmenu item", onClick:fClick}));
-            pSubMenu.addChild(new dijit.PopupMenuItem({label:"SubSubmenu", popup:pSubSubMenu, id:"progPopupMenuItem2"}));
-
-            pMenu.addChild(new dijit.PopupMenuItem({label:"Submenu", popup:pSubMenu, id:"progPopupMenuItem"}));
-
-            pMenu.startup();
-
-	    updateButtons(true);
-            dojo.byId("prog_menu").innerHTML="This div has a programmatic context menu on it that's different to the page menu.";
-
-            dojo.byId("createButton").disabled = true;
-            dojo.byId("destroyButton").disabled = false;
-        }
-
-        function destroyMenu(){
-        	pMenu.destroyRecursive();
-            updateButtons(false);
-        }
-
-	function updateButtons(created){
-            dojo.byId("prog_menu").innerHTML=created?"This div has a programmatic context menu on it that's different to the page menu.":"No programmatic menu on this div, should get page level menu.";
-            dojo.byId("createButton").disabled = created;
-            dojo.byId("destroyButton").disabled = !created;
-	}
-	dojo.ready(function(){
-		// need to explicitly update our buttons states, otherwise the
-		// browser will remember the last states of them before reloading
-		// (so a programmatic menu is created, reload, and "the create
-		// programmatic menu" button is still in disabled state)
-		updateButtons(false);
-	});
+
+		require([
+			"dojo/dom",
+			"dojo/parser",	// scan page for widgets and instantiate them
+	
+			"dijit/Menu",
+			"dijit/MenuItem",
+			"dijit/PopupMenuItem",
+			"dijit/CheckedMenuItem",
+			"dijit/RadioMenuItem",
+			"dijit/MenuSeparator",
+	
+			"dijit/MenuBar",
+			"dijit/MenuBarItem",
+			"dijit/PopupMenuBarItem",
+	
+			"dijit/ColorPalette",
+			"dijit/form/TextBox",
+					
+			"dojo/domReady!"
+		], function(dom, parser, Menu, MenuItem, PopupMenuItem, CheckedMenuItem, RadioMenuItem, MenuSeparator){
+
+			createMenu = function(){
+				// create a menu programmatically
+				function fClick(){console.log("clicked!")}
+	
+				pMenu = new Menu({targetNodeIds:["prog_menu"], id:"progMenu"});
+				pMenu.addChild(new MenuItem({label:"Programmatic Context Menu", disabled:true}));
+				pMenu.addChild(new MenuSeparator());
+				pMenu.addChild(new MenuItem({label:"Simple menu item", onClick:fClick, accelKey:"Shift+S"}));
+				pMenu.addChild(new MenuItem({label:"Another menu item", onClick:fClick, accelKey:"Ctrl+A"}));
+				pMenu.addChild(new MenuItem({label:"With an icon", iconClass:"dijitEditorIcon dijitEditorIconCut", onClick:fClick}));
+				var mItem = new MenuItem({label:"dojo.event clicking", accelKey: "Alt+D"});
+				mItem.on("click", function(){console.log("click! handler created via dojo.connect()")});
+				pMenu.addChild(mItem);
+	
+				mItem = new CheckedMenuItem({label:"checkable menu item"});
+				pMenu.addChild(mItem);
+	
+				var pSubMenu = new Menu({parentMenu:pMenu, id:"progSubMenu"});
+				pSubMenu.addChild(new MenuItem({label:"Submenu item", onClick:fClick}));
+				pSubMenu.addChild(new MenuItem({label:"Submenu item", onClick:fClick}));
+				
+				var pSubSubMenu = new Menu({parentMenu:pSubMenu, id:"progSubSubMenu"});
+				pSubSubMenu.addChild(new MenuItem({label:"SubSubmenu item", onClick:fClick}));
+				pSubSubMenu.addChild(new MenuItem({label:"SubSubmenu item", onClick:fClick}));
+				pSubMenu.addChild(new PopupMenuItem({label:"SubSubmenu", popup:pSubSubMenu, id:"progPopupMenuItem2"}));
+	
+				pMenu.addChild(new PopupMenuItem({label:"Submenu", popup:pSubMenu, id:"progPopupMenuItem"}));
+	
+				pMenu.startup();
+	
+				updateButtons(true);
+				dom.byId("prog_menu").innerHTML="This div has a programmatic context menu on it that's different to the page menu.";
+	
+				dom.byId("createButton").disabled = true;
+				dom.byId("destroyButton").disabled = false;
+			};
+
+			destroyMenu = function (){
+				pMenu.destroyRecursive();
+				updateButtons(false);
+			};
+
+			updateButtons = function (created){
+				dom.byId("prog_menu").innerHTML=created?"This div has a programmatic context menu on it that's different to the page menu.":"No programmatic menu on this div, should get page level menu.";
+				dom.byId("createButton").disabled = created;
+				dom.byId("destroyButton").disabled = !created;
+			};
+
+			// need to explicitly update our buttons states, otherwise the
+			// browser will remember the last states of them before reloading
+			// (so a programmatic menu is created, reload, and "the create
+			// programmatic menu" button is still in disabled state)
+			updateButtons(false);
+
+			parser.parse();
+		});
     </script>
 </head>
-<body class="claro">
-
-	<div id="windowContextMenu" data-dojo-type="dijit.Menu" data-dojo-props='contextMenuForWindow:true, style:"display: none;"'>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Hello world"); }'>Context Menu</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='disabled:true, onClick:function(){ alert("this should NOT appear"); }'>Disabled Item</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+<body class="claro" role="main">
+
+	<div id="windowContextMenu" data-dojo-type="dijit/Menu" data-dojo-props='contextMenuForWindow:true, style:"display: none;"'>
+		<div data-dojo-type="dijit/MenuItem" id="windowContextMenuFirstChoice"
+			 data-dojo-props='onClick:function(){ console.log("Hello world"); }'>Context Menu</div>
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='disabled:true, onClick:function(){ alert("this should NOT appear"); }'>Disabled Item</div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
 			onClick:function(){ console.log("not actually cutting anything, just a test!") }, accelKey:"Ctrl+X"'>Cut</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
 			onClick:function(){ console.log("not actually copying anything, just a test!") }, accelKey:"Ctrl+C"'>Copy</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
 			onClick:function(){ console.log("not actually pasting anything, just a test!") }, accelKey:"Ctrl+V"'>Paste</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div id="enabledSubmenu" data-dojo-type="dijit.PopupMenuItem" >
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div id="enabledSubmenu" data-dojo-type="dijit/PopupMenuItem" >
 			<span>Enabled Submenu</span>
-			<div id="submenu2" data-dojo-type="dijit.Menu" >
-				<div id="submenu2_item1" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
-				<div id="submenu2_item2" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
-				<div id="deeperSubmenu" data-dojo-type="dijit.PopupMenuItem" >
+			<div id="submenu2" data-dojo-type="dijit/Menu" >
+				<div id="submenu2_item1" data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+				<div id="submenu2_item2" data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
+				<div id="deeperSubmenu" data-dojo-type="dijit/PopupMenuItem" >
 					<span>Deeper Submenu</span>
-					<div id="submenu4" data-dojo-type="dijit.Menu" >
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</div>
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</div>
+					<div id="submenu4" data-dojo-type="dijit/Menu" >
+						<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</div>
+						<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</div>
 					</div>
 				</div>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.PopupMenuItem" data-dojo-props='disabled:true'>
+		<div data-dojo-type="dijit/PopupMenuItem" data-dojo-props='disabled:true'>
 			<span>Disabled Submenu</span>
-			<div id="submenu3" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
+			<div id="submenu3" data-dojo-type="dijit/Menu" data-dojo-props='style:"display: none;"'>
+				<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+				<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.PopupMenuItem">
+		<div data-dojo-type="dijit/PopupMenuItem">
 			<span>Different popup</span>
-			<div data-dojo-type="dijit.ColorPalette"></div>
+			<div data-dojo-type="dijit/ColorPalette"></div>
 		</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props='checked:true, onChange:function(val){ console.log("Now set to " + val); }'>Checked</div>
-		<div data-dojo-type="dijit.CheckedMenuItem">Not Checked</div>
-		<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props='checked:true, disabled:true'>Checked Disabled</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div data-dojo-type="dijit.PopupMenuItem">
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div data-dojo-type="dijit/CheckedMenuItem" data-dojo-props='checked:true, onChange:function(val){ console.log("Now set to " + val); }'>Checked</div>
+		<div data-dojo-type="dijit/CheckedMenuItem">Not Checked</div>
+		<div data-dojo-type="dijit/CheckedMenuItem" data-dojo-props='checked:true, disabled:true'>Checked Disabled</div>
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div data-dojo-type="dijit/PopupMenuItem">
 			<span>Bigger Submenu</span>
-			<div id="bigsubmenu" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
-				<div data-dojo-type="dijit.MenuItem">Item One</div>
-				<div data-dojo-type="dijit.MenuItem">Item Two</div>
-				<div data-dojo-type="dijit.MenuItem">Item Three</div>
-				<div data-dojo-type="dijit.MenuItem">Item Four</div>
-				<div data-dojo-type="dijit.MenuItem">Item Five</div>
-				<div data-dojo-type="dijit.MenuItem">Item Six</div>
-				<div data-dojo-type="dijit.MenuItem">Item Seven</div>
-				<div data-dojo-type="dijit.MenuItem">Item Eight</div>
-				<div data-dojo-type="dijit.MenuItem">Item Nine</div>
-				<div data-dojo-type="dijit.MenuItem">Item Ten</div>
+			<div id="bigsubmenu" data-dojo-type="dijit/Menu" data-dojo-props='style:"display: none;"'>
+				<div data-dojo-type="dijit/MenuItem">Item One</div>
+				<div data-dojo-type="dijit/MenuItem">Item Two</div>
+				<div data-dojo-type="dijit/MenuItem">Item Three</div>
+				<div data-dojo-type="dijit/MenuItem">Item Four</div>
+				<div data-dojo-type="dijit/MenuItem">Item Five</div>
+				<div data-dojo-type="dijit/MenuItem">Item Six</div>
+				<div data-dojo-type="dijit/MenuItem">Item Seven</div>
+				<div data-dojo-type="dijit/MenuItem">Item Eight</div>
+				<div data-dojo-type="dijit/MenuItem">Item Nine</div>
+				<div data-dojo-type="dijit/MenuItem">Item Ten</div>
 			</div>
 		</div>
 	</div>
 
-	<div id="leftClickContextMenu" data-dojo-type="dijit.Menu" data-dojo-props='leftClickToOpen:true, targetNodeIds:["input2"], style:"display: none;"'>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='disabled:true'>Left Click Menu</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Hello world"); }'>Enabled Item</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='disabled:true'>Disabled Item</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+	<div id="leftClickContextMenu" data-dojo-type="dijit/Menu" data-dojo-props='leftClickToOpen:true, targetNodeIds:["input2"], style:"display: none;"'>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='disabled:true'>Left Click Menu</div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Hello world"); }'>Enabled Item</div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='disabled:true'>Disabled Item</div>
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
 			onClick:function(){ console.log("not actually cutting anything, just a test!") }'>Cut</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
 			onClick:function(){ console.log("not actually copying anything, just a test!") }'>Copy</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
 			onClick:function(){ console.log("not actually pasting anything, just a test!") }'>Paste</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div data-dojo-type="dijit.PopupMenuItem">
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div data-dojo-type="dijit/PopupMenuItem">
 			<span>Enabled Submenu</span>
-			<div id="leftsubmenu2" data-dojo-type="dijit.Menu" >
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
-				<div data-dojo-type="dijit.PopupMenuItem">
+			<div id="leftsubmenu2" data-dojo-type="dijit/Menu" >
+				<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+				<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
+				<div data-dojo-type="dijit/PopupMenuItem">
 					<span>Deeper Submenu</span>
-					<div id="leftsubmenu4" data-dojo-type="dijit.Menu" >
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</div>
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</div>
+					<div id="leftsubmenu4" data-dojo-type="dijit/Menu" >
+						<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</div>
+						<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</div>
 					</div>
 				</div>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.PopupMenuItem" data-dojo-props='disabled:true'>
+		<div data-dojo-type="dijit/PopupMenuItem" data-dojo-props='disabled:true'>
 			<span>Disabled Submenu</span>
-			<div id="leftsubmenu3" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
+			<div id="leftsubmenu3" data-dojo-type="dijit/Menu" data-dojo-props='style:"display: none;"'>
+				<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+				<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.PopupMenuItem">
+		<div data-dojo-type="dijit/PopupMenuItem">
 			<span>Different popup</span>
-			<div data-dojo-type="dijit.ColorPalette"></div>
+			<div data-dojo-type="dijit/ColorPalette"></div>
 		</div>
 	</div>
 
-	<table id="formattingTable">
+	<table id="formattingTable" role="presentation">
 		<tr>
 			<td style="width:0;">
 				<!-- This is here for tabIndex testing.
 				     Use textarea since Chrome 1.0 likes it better for TABing and
 				     because it has innerText property and because it doesn't mess
 				     with the URL when clicked -->
-				<textarea id="link" tabIndex="0" readOnly class="dijitReset" style="font-family:monospace;font-size:12px;width:84px;text-decoration:underline;overflow:hidden;background-color:transparent;" rows=1>random link</textarea>
+				<textarea aria-label="random link" id="link" tabIndex="0" readOnly class="dijitReset" style="font-family:monospace;font-size:12px;width:84px;text-decoration:underline;overflow:hidden;background-color:transparent;" rows=1>random link</textarea>
 			</td>
 			<td id="menuBarContainer" style="width:100%;">
-				<div id="menubar" data-dojo-type="dijit.MenuBar">
-					<div id="file" data-dojo-type="dijit.PopupMenuBarItem" >
-						<span>File</span>
-						<div id="fileMenu" data-dojo-type="dijit.Menu" >
-							<div id="new" data-dojo-type="dijit.MenuItem" >New</div>
-							<div id="open" data-dojo-type="dijit.MenuItem" >Open</div>
-							<div id="separator" data-dojo-type="dijit.MenuSeparator" ></div>
-							<div id="save" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIconSave"'>Save</div>
-							<div id="saveas" data-dojo-type="dijit.MenuItem" >Save As...</div>
+				<div id="menubar" data-dojo-type="dijit/MenuBar">
+					<div id="file" data-dojo-type="dijit/PopupMenuBarItem" accessKey="F">
+						<span>{F}ile</span>
+						<div id="fileMenu" data-dojo-type="dijit/Menu" >
+							<div id="new" data-dojo-type="dijit/MenuItem">{N}ew</div>
+							<div id="open" data-dojo-type="dijit/MenuItem">{O}pen</div>
+							<div id="separator" data-dojo-type="dijit/MenuSeparator" ></div>
+							<div id="save" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIconSave"'>{S}ave</div>
+							<div id="saveas" data-dojo-type="dijit/MenuItem">Save {A}s...</div>
 						</div>
 					</div>
-					<div id="edit" data-dojo-type="dijit.PopupMenuBarItem" >
-						<span>Edit</span>
-						<div id="editMenu" data-dojo-type="dijit.Menu" >
-							<div id="cut" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
-								onClick:function(){ console.log("not actually cutting anything, just a test!"); }, accelKey:"Ctrl+X"'>Cut</div>
-							<div id="copy" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
-								onClick:function(){ console.log("not actually copying anything, just a test!") }, accelKey:"Ctrl+C"'>Copy</div>
-							<div id="paste" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
-								onClick:function(){ console.log("not actually pasting anything, just a test!") }, accelKey:"Ctrl+V"'>Paste</div>
+					<div id="edit" data-dojo-type="dijit/PopupMenuBarItem" accessKey="E">
+						<span>{E}dit</span>
+						<div id="editMenu" data-dojo-type="dijit/Menu" >
+							<div id="cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+								onClick:function(){ console.log("not actually cutting anything, just a test!"); }, accelKey:"Ctrl+X"'>C{u}t</div>
+							<div id="copy" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+								onClick:function(){ console.log("not actually copying anything, just a test!") }, accelKey:"Ctrl+C"'>{C}opy</div>
+							<div id="paste" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+								onClick:function(){ console.log("not actually pasting anything, just a test!") }, accelKey:"Ctrl+V"'>{P}aste</div>
 						</div>
 					</div>
-					<div id="view" data-dojo-type="dijit.PopupMenuBarItem" >
-						<span>View</span>
-						<div id="viewMenu" data-dojo-type="dijit.Menu" >
-							<div data-dojo-type="dijit.MenuItem">Normal</div>
-							<div data-dojo-type="dijit.MenuItem">Outline</div>
-							<div data-dojo-type="dijit.PopupMenuItem">
-								<span>Zoom</span>
-								<div id="zoomMenu" data-dojo-type="dijit.Menu" >
-									<div data-dojo-type="dijit.MenuItem">50%</div>
-									<div data-dojo-type="dijit.MenuItem">75%</div>
-									<div data-dojo-type="dijit.MenuItem">100%</div>
-									<div data-dojo-type="dijit.MenuItem">150%</div>
-									<div data-dojo-type="dijit.MenuItem">200%</div>
+					<div id="view" data-dojo-type="dijit/PopupMenuBarItem" accessKey="V">
+						<span>{V}iew</span>
+						<div id="viewMenu" data-dojo-type="dijit/Menu" >
+							<div data-dojo-type="dijit/MenuItem">Normal</div>
+							<div data-dojo-type="dijit/MenuItem">Outline</div>
+							<div data-dojo-type="dijit/PopupMenuItem">
+								<span>{Z}oom</span>
+								<div id="zoomMenu" data-dojo-type="dijit/Menu" >
+									<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'zoom'">50%</div>
+									<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'zoom'">75%</div>
+									<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'zoom', checked:true">100%</div>
+									<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'zoom'">150%</div>
+									<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'zoom'">200%</div>
 								</div>
 							</div>
 						</div>
 					</div>
-					<div id="help" data-dojo-type="dijit.PopupMenuBarItem" >
-						<span>Help</span>
-						<div id="helpMenu" data-dojo-type="dijit.Menu" >
-							<div data-dojo-type="dijit.MenuItem">Help Topics</div>
-							<div data-dojo-type="dijit.MenuItem">About Dijit</div>
+					<div id="help" data-dojo-type="dijit/PopupMenuBarItem" accessKey="H">
+						<span>{H}elp</span>
+						<div id="helpMenu" data-dojo-type="dijit/Menu" >
+							<div data-dojo-type="dijit/MenuItem">Help Topics</div>
+							<div data-dojo-type="dijit/MenuItem">About Dijit</div>
 						</div>
 					</div>
-					<div data-dojo-type="dijit.PopupMenuBarItem" data-dojo-props='disabled:true'>
-						<span>Disabled</span>
-						<div data-dojo-type="dijit.Menu">
-							<div data-dojo-type="dijit.MenuItem">You should not see this</div>
+					<div data-dojo-type="dijit/PopupMenuBarItem" data-dojo-props='disabled:true'>
+						<span>{D}isabled</span>
+						<div data-dojo-type="dijit/Menu">
+							<div data-dojo-type="dijit/MenuItem">You should not see this</div>
 						</div>
 					</div>
-					<div data-dojo-type="dijit.PopupMenuBarItem">
-						<span>Empty</span>
-						<div data-dojo-type="dijit.Menu">
+					<div data-dojo-type="dijit/PopupMenuBarItem" accessKey="M">
+						<span>E{m}pty</span>
+						<div data-dojo-type="dijit/Menu">
 						</div>
 					</div>
-					<div data-dojo-type="dijit.MenuBarItem" data-dojo-props='onClick:function(){ console.log("no submenu, just a clickable MenuItem"); }'>
-						Click me!
+					<div data-dojo-type="dijit/MenuBarItem" data-dojo-id="noPopupMenuBarItem" accessKey="Z"
+						 data-dojo-props='onClick:function(){ console.log("no submenu, just a clickable MenuItem"); }'>
+						Click me! ({Z})
 					</div>
 				</div>
 			</td>
@@ -287,45 +284,45 @@
 			<td id="navMenuContainer" class="dijitMenu" style="vertical-align:top; width:0;">
 
 				<h3 style="margin-bottom: 2em;">Navigation menu:</h3>
-				<div id="navMenu" data-dojo-type="dijit.Menu" >
-					<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+				<div id="navMenu" data-dojo-type="dijit/Menu" aria-label="navigation">
+					<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
 						onClick:function(){ console.log("drama!"); }'>Drama</div>
-					<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+					<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
 						onClick:function(){ console.log("comedy!") }'>Comedy</div>
-					<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+					<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
 						onClick:function(){ console.log("romance!") }'>Romance</div>
-					<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+					<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
 						onClick:function(){ console.log("documentary!") }'>Documentary</div>
-					<div data-dojo-type="dijit.MenuSeparator"></div>
-					<div id="navMenuPopupItem1" data-dojo-type="dijit.PopupMenuItem" >
-						<span>Enabled Submenu</span>
-						<div id="navMenuSub1" data-dojo-type="dijit.Menu" >
-							<div id="navMenuSub1_item1" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
-							<div id="navMenuSub1_item2" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
-							<div id="navMenuSub1_popup" data-dojo-type="dijit.PopupMenuItem" >
+					<div data-dojo-type="dijit/MenuSeparator"></div>
+					<div id="navMenuPopupItem1" data-dojo-type="dijit/PopupMenuItem" >
+						<span>{E}nabled Submenu</span>
+						<div id="navMenuSub1" data-dojo-type="dijit/Menu" >
+							<div id="navMenuSub1_item1" data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+							<div id="navMenuSub1_item2" data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
+							<div id="navMenuSub1_popup" data-dojo-type="dijit/PopupMenuItem" >
 								<span>Deeper Submenu</span>
-								<div id="navMenuSub2" data-dojo-type="dijit.Menu" >
-									<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</div>
-									<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</div>
+								<div id="navMenuSub2" data-dojo-type="dijit/Menu" >
+									<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</div>
+									<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</div>
 								</div>
 							</div>
 						</div>
 					</div>
-					<div id="navMenuDisabledItem" data-dojo-type="dijit.PopupMenuItem" data-dojo-props='disabled:true '>
+					<div id="navMenuDisabledItem" data-dojo-type="dijit/PopupMenuItem" data-dojo-props='disabled:true '>
 						<span>Disabled Submenu</span>
-						<div id="navMenuSub3" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
-							<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
-							<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
+						<div id="navMenuSub3" data-dojo-type="dijit/Menu" data-dojo-props='style:"display: none;"'>
+							<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+							<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
 						</div>
 					</div>
-					<div data-dojo-type="dijit.PopupMenuItem">
+					<div data-dojo-type="dijit/PopupMenuItem">
 						<span>Different popup</span>
-						<div data-dojo-type="dijit.ColorPalette"></div>
+						<div data-dojo-type="dijit/ColorPalette"></div>
 					</div>
-					<div data-dojo-type="dijit.MenuSeparator"></div>
-					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props='checked:true, onChange:function(val){ console.log("Now set to " + val); }'>Checked</div>
-					<div id="checked2" data-dojo-type="dijit.CheckedMenuItem" >Not Checked</div>
-					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props='checked:true, disabled:true'>Checked Disabled</div>
+					<div data-dojo-type="dijit/MenuSeparator"></div>
+					<div id="checked1" data-dojo-type="dijit/CheckedMenuItem" data-dojo-props='checked:true, onChange:function(val){ console.log("Now set to " + val); }'>Checked</div>
+					<div id="checked2" data-dojo-type="dijit/CheckedMenuItem" >Not Checked</div>
+					<div data-dojo-type="dijit/CheckedMenuItem" data-dojo-props='checked:true, disabled:true'>Checked Disabled</div>
 				</div>
 			</td>
 
@@ -353,17 +350,17 @@
 						the right menu by verifying the left<br/>
 						click one starts with "Left Click Menu"<br/>
 						at the very top.
-						<input id=input2 value="top-right"/>
+						<input aria-label="input2" id=input2 value="top-right"/>
 					</p>
-					<input id=input1 value="top-left"/>
-					<textarea id=textarea>hello there!</textarea><br>
-					<select>
+					<input aria-label="input1" id=input1 value="top-left"/>
+					<textarea aria-label="textara" id=textarea>hello there!</textarea><br>
+					<select aria-label="select">
 						<option>check if i</option>
 						<option>bleed through</option>
 						<option>on IE6</option>
 					</select>
 					<button id=button>push me</button><br>
-					<input data-dojo-type="dijit.form.TextBox" id="formwidget" data-dojo-props='style:"width:25em;", value:"dijit.form._FormWidget focus test"'/>
+					<input data-dojo-type="dijit/form/TextBox" aria-label="focus test" id="formwidget" data-dojo-props='style:"width:25em;", value:"dijit.form._FormWidget focus test"'/>
 				</form>
 
 			    <div id="prog_menu" style="clear: both; border:1px solid blue; padding:10px; margin:20px 0;">
@@ -376,8 +373,8 @@
 				<p>(this space intentionally left blank to aid testing with controls
 				at the bottom of the browser window)</p>
 				<div style="height:500px"></div>
-				<input id=input3 value="bottom-left"/>
-				<p style="text-align:right"><input id=input4 value="bottom-right"/></p>
+				<input id=input3 aria-label="input3" value="bottom-left"/>
+				<p style="text-align:right"><input aria-label="input4" id=input4 value="bottom-right"/></p>
 
 				<p>See also: <a href="form/test_Button.html">form/test_Button</a>
 				(PopupMenu is used with DropDownButton and ComboButton)</p>
@@ -387,7 +384,7 @@
 				<ul>
 					<li>Right click on the client area of the page (ctrl-click for Macintosh). Menu should open.</li>
 					<li>Right click on each of the form controls above. Menu should open.</li>
-					<li>Right click near the righthand window border. Menu should open to the left of the pointer.</li>
+					<li>Right click near the right hand window border. Menu should open to the left of the pointer.</li>
 					<li>Right click near the bottom window border. Menu should open above the pointer.</li>
 				</ul>
 
@@ -397,7 +394,7 @@
 				<ul>
 					<li>Hover over the first item with the pointer. Item should highlight and get focus.</li>
 					<li>Hover over the second (disabled) item. Item should highlight and get focus.</li>
-					<li>Seperator items should not highlight on hover - no items should highlight in this case.</li>
+					<li>Separator items should not highlight on hover - no items should highlight in this case.</li>
 				</ul>
 
 
diff --git a/dijit/tests/test_Menu_iframe.html b/dijit/tests/test_Menu_iframe.html
index 0e840cf..5ad0c63 100644
--- a/dijit/tests/test_Menu_iframe.html
+++ b/dijit/tests/test_Menu_iframe.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Menu iframe test</title>
@@ -22,14 +22,14 @@
 		}
 	</script>
 </head>
-<body class="claro">
-	<div id="menu" data-dojo-type="dijit.Menu" data-dojo-props='targetNodeIds:["iframe"], style:"display:none;"'>
-		<div data-dojo-type="dijit.MenuItem">context menu</div>
+<body class="claro" role="main">
+	<div id="menu" data-dojo-type="dijit/Menu" data-dojo-props='targetNodeIds:["iframe"], style:"display:none;"'>
+		<div data-dojo-type="dijit/MenuItem">context menu</div>
 	</div>
 	<div style="border: 1px solid gray; height: 150px;">filler div to offset iframe position (for testing)</div>
 	<div style="position: relative; border: 3px solid blue; padding: 10px;">
 		This is a position:relative div containing an iframe.
-		<iframe id="iframe"
+		<iframe title="iframe" id="iframe"
 			src="javascript:'<html><body style=\'margin: 3em;\'><div style=\'height:300px;border:1px solid red;\'>right click for menu</div><body></html>'"
 			style="height: 200px; margin: 30px; padding: 20px; border: solid dotted 10px;" onload="console.log('iframe onload');">
 		</iframe>
diff --git a/dijit/tests/test_TitlePane.html b/dijit/tests/test_TitlePane.html
index 2383a11..6fd4e8a 100644
--- a/dijit/tests/test_TitlePane.html
+++ b/dijit/tests/test_TitlePane.html
@@ -1,45 +1,35 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>TitlePane Test</title>
 
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
-	</style>
+	<script type="text/javascript" src="boilerplate.js"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/parser",
+			"dijit/TitlePane",
 
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: false, isDebug: true"></script>
+			// widgets used inside subpage loaded via href=
+			"dijit/form/Button",
+			"dijit/form/ComboBox",
+			"dijit/layout/TabContainer",
+			"dijit/layout/AccordionContainer",
+			"dijit/layout/ContentPane",
 
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
+			"dojo/domReady!"
+		], function(declare, parser, TitlePane){
+
+			randomMessageId = function(){
+				return Math.floor(Math.random() * 3) + 3;
+			};
 
-	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.TitlePane");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-		// widgets used inside subpage loaded via href=
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.form.ComboBox");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.AccordionContainer");
-		dojo.require("dijit.layout.LinkPane");
-
-		function randomMessageId(){
-			return Math.floor(Math.random() * 3) + 3;
-		}
-
-	    dojo.ready(function(){
 	
-			dojo.declare("dijit.TestTitlePane", dijit.TitlePane, {
+			declare("TestTitlePane", TitlePane, {
 				templateString: '<div class="dijitTitlePane">' +
-								'    <div class="dijitTitlePaneTitle" data-dojo-attach-point="titleBarNode" style="cursor: default;">' +
+								'    <div class="dijitTitlePaneTitle" data-dojo-attach-point="titleBarNode" style="cursor: default;" id="${id}_titleBarNode">' +
 								        '<span data-dojo-attach-event="onclick:toggle,onkeypress: _onTitleKey" tabindex="0"' +
 								                'role="button" data-dojo-attach-point="focusNode,arrowNode" style="cursor: pointer;">' +
 											'<img src="${_blankGif}" alt="" class="dijitArrowNode" role="presentation"/>' +
@@ -49,24 +39,24 @@
 								    '</div>' +
 								    '<div class="dijitTitlePaneContentOuter" data-dojo-attach-point="hideNode">' +
 								        '<div class="dijitReset" data-dojo-attach-point="wipeNode">' +
-								            '<div class="dijitTitlePaneContentInner" data-dojo-attach-point="containerNode" role="region" tabindex="-1">' +
+								            '<div class="dijitTitlePaneContentInner" data-dojo-attach-point="containerNode" id="${id}_pane" aria-labelledby="${id}_titleBarNode" role="region" tabindex="-1">' +
 								            '</div>' +
 								        '</div>' +
 								    '</div>' +
 								'</div>'
 			});
 	
-		    dojo.parser.parse();
+		    parser.parse();
 	    });
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1 class="testTitle">Dijit TitlePane Test</h1>
 
-	<input id="input" value="for tab testing"/>
+	<label for="input">input:</label><input id="input" value="for tab testing"/>
 
 	<h1>Test #1: plain title pane, width=300px</h1>
-	<div id="testPane1" data-dojo-id="pane1" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #1",
+	<div id="testPane1" data-dojo-id="pane1" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Title Pane #1",
 		tooltip:"I\"m the tooltip for Title Pane #1\"s title bar",
 		style:"width: 300px;" '>
 		Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
@@ -77,21 +67,21 @@
 		nec, malesuada eget, ornare a, libero. Lorem ipsum dolor sit amet,
 		consectetuer adipiscing elit.
 	</div>
-	<button id="titleButton" onclick="pane1.set('title', 'New Title')">change title</button>
-	<button id="closeButton" onclick="pane1.set('open', false)">close pane</button>
+	<button id="titleButton" type="button" onclick="pane1.set('title', 'New Title')">change title</button>
+	<button id="closeButton" type="button" onclick="pane1.set('open', false)">close pane</button>
 	<h1>Test #2: title pane with form, width=300px</h1>
 
-	<div id="pane_2" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #2", style:"width: 300px;"'>
+	<div id="pane_2" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Title Pane #2", style:"width: 300px;"'>
 		<form>
 			<label for="age">Age: </label> <input id="age"/><br>
-			<label for="disc">Discount card </label><input id="disc" type="checkbox"/><br>
+			<input id="disc" type="checkbox"/><label for="disc">Discount card </label><br>
 			<button>Submit</button><br>
 		</form>
 	</div>
 	<br>
 
 	<h1>Test #3: initially closed pane</h1>
-	<div id="closed" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Initially closed pane", open:false, style:"width:500px;"'>
+	<div id="closed" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Initially closed pane", open:false, style:"width:500px;"'>
 		<form>
 			<label for="age2">Age: </label><input id="age2"/><br>
 			<label for="discount">Discount card </label><input type="checkbox" id="discount"/><br>
@@ -99,16 +89,16 @@
 		</form>
 
 		<p>And a TabContainer, to make sure it lays out correctly:</p>
-		<div id="tabContainer" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 400px; height: 250px;"'>
-			<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"layout/tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
-			<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"layout/tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
+		<div id="tabContainer" data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 400px; height: 250px;"'>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"layout/tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }' title="SubTab 1"></div>
+			<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='href:"layout/tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true' title="SubTab 2"></div>
 		</div>
 	</div>
-	<button onclick="dijit.byId('closed').set('content', 'hello world! (' + new Date() + ')');">reset content</button>
+	<button type="button" onclick="dijit.byId('closed').set('content', 'hello world! (' + new Date() + ')');">reset content</button>
 
 	<h1>Test #4: title pane with href (initially closed)</h1>
 	<p>The pane should open to "Loading..." message and then 3 seconds later it should slide open more to show loaded data.</p>
-	<div id="href1" data-dojo-type="dijit.TitlePane" data-dojo-props='duration:1000, title:"Pane from href", open:false,
+	<div id="href1" data-dojo-type="dijit/TitlePane" data-dojo-props='duration:1000, title:"Pane from href", open:false,
 		href:"layout/getResponse.php?delay=3000&messId=3", preventCache:true,
 		style:"width: 400px;"'>
 		Loading...
@@ -116,19 +106,19 @@
 
 	<h1>Test #5: title pane with href (initially closed)</h1>
 	<p>The pane should start to open to "Loading..." but halfway through href data will be loaded, and it should expand correctly.</p>
-	<div id="href2" data-dojo-type="dijit.TitlePane" data-dojo-props='duration:1000, title:"Pane from href", open:false,
+	<div id="href2" data-dojo-type="dijit/TitlePane" data-dojo-props='duration:1000, title:"Pane from href", open:false,
 		href:"layout/getResponse.php?delay=500&messId=3", preventCache:true,
 		style:"width: 400px;"'>
 		Loading...
 	</div>
 
 	<h1>Test #6: nested title pane</h1>
-	<div id="outer" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Outer pane", style:"width:300px;"'>
+	<div id="outer" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Outer pane", style:"width:300px;"'>
 		<p>This is a title pane, containing another title pane ...
 		<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus pulvinar orci, sed vestibulum urna sem ut pede.
 More Ipsum...
 
-		<div id="inner" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Inner pane", style:"width:250px;"'>
+		<div id="inner" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Inner pane", style:"width:250px;"'>
 			<p>And this is the inner title pane...
 			<p>Sed sollicitudin suscipit risus. Nam ullamcorper. Sed nisl lectus, pellentesque nec, malesuada eget, ornare a, libero. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
 		</div>
@@ -137,7 +127,7 @@ More Ipsum...
 	</div>
 
 	<h1>Test #7: subclassed title pane (only arrow is selectable and focusable)</h1>
-	<div id="ttp" data-dojo-type="dijit.TestTitlePane" data-dojo-props='title:"Title Pane #7", style:"width: 300px;" '>
+	<div id="ttp" data-dojo-type="TestTitlePane" data-dojo-props='title:"Title Pane #7", style:"width: 300px;" '>
 		Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
 		iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing
 		orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus
@@ -155,7 +145,7 @@ More Ipsum...
 		</tr>
 	</table>
 	<h1>Test #8: locked open title pane</h1>
-	<div id="locked" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #8", style:"width: 300px;", toggleable:false '>
+	<div id="locked" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Title Pane #8", style:"width: 300px;", toggleable:false '>
 		Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
 		iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing
 		orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus
@@ -166,27 +156,32 @@ More Ipsum...
 	</div>
 
 	<h1>Test #9: TitlePane in AccordionContainer</h1>
-	<div id="ac" data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props='style:"width: 400px; height: 300px;" '>
-		<div id="accp1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"pane 1", selected:true'>
+	<div id="ac" data-dojo-type="dijit/layout/AccordionContainer" data-dojo-props='style:"width: 400px; height: 300px;" '>
+		<div id="accp1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"pane 1", selected:true'>
 			Here's a closed title pane:
-			<div id="actp1" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #9", style:"width: 300px;", open:false, 
+			<div id="actp1" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Title Pane #9", style:"width: 300px;", open:false,
 					href:"layout/tab1.html", onLoad:function(){ console.log("load of actp1"); actp1Loaded = true; }'>
 			</div>
 			and an open one:
-			<div id="actp2" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #10", style:"width: 300px;", open:true, 
+			<div id="actp2" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Title Pane #10", style:"width: 300px;", open:true,
 					href:"layout/tab2.html", onLoad:function(){ console.log("load of actp2"); actp2Loaded = true; }'>
 			</div>
 		</div>
-		<div id="accp2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"pane 2" '>
+		<div id="accp2" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"pane 2" '>
 			Here's a closed title pane:
-			<div id="actp3" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #11", style:"width: 300px;", open:false, 
+			<div id="actp3" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Title Pane #11", style:"width: 300px;", open:false,
 					href:"layout/tab1.html", onLoad:function(){ console.log("load of actp3"); actp3Loaded = true; }'>
 			</div>
 			and an open one:
-			<div id="actp4" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #12", style:"width: 300px;", open:true, 
+			<div id="actp4" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Title Pane #12", style:"width: 300px;", open:true,
 					href:"layout/tab2.html", onLoad:function(){ console.log("load of actp4"); actp4Loaded = true; }'>
 			</div>
 		</div>
+		<div id="accp3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"pane 3 (single child)" '>
+			<div id="actp5" data-dojo-type="dijit/TitlePane" data-dojo-props='title:"Title Pane #13"'>
+				hello world, my height should match this text, not the height of the containing ContentPane
+			</div>
+		</div>
 	</div>
 
 </body>
diff --git a/dijit/tests/test_Toolbar.html b/dijit/tests/test_Toolbar.html
index 3d780d8..d7ac4bb 100644
--- a/dijit/tests/test_Toolbar.html
+++ b/dijit/tests/test_Toolbar.html
@@ -4,48 +4,38 @@
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dojo Toolbar Widget Test</title>
 
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
+	<script type="text/javascript" src="boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-
-		dojo.require("dijit.Declaration");
-		dojo.require("dijit.Toolbar");
-		dojo.require("dijit.ToolbarSeparator");
-
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.form.DropDownButton");
-		dojo.require("dijit.form.ComboButton");
-		dojo.require("dijit.form.ToggleButton");
+		require([
+			"dojo/_base/array",
+			"dojo/dom",
+			"dojo/parser",
+	
+			"dijit/Toolbar",
+			"dijit/form/Button",
+
+			"dijit/ToolbarSeparator",
+			"dijit/Declaration",
+			"dijit/form/DropDownButton",
+			"dijit/form/ComboButton",
+			"dijit/form/ToggleButton",
+	
+			"dijit/ColorPalette",
+			"dijit/TooltipDialog",
+			"dijit/form/TextBox",
+	
+			"dijit/Menu",
+			"dijit/MenuItem",
+	
+			"dojo/domReady!"
+		], function(array, dom, parser, Toolbar, Button){
 
-		dojo.require("dijit.ColorPalette");
-		dojo.require("dijit.TooltipDialog");
-		dojo.require("dijit.form.TextBox");
-
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.MenuItem");
-
-		dojo.require("dojo.parser");
-
-		dojo.ready(function(){
 			// programatic creation
-			dojo.forEach(["toolbar2", "toolbar3", "toolbar4"], function(toolbarId){
-				var toolbar = new dijit.Toolbar({}, dojo.byId(toolbarId));
-				dojo.forEach(["Cut", "Copy", "Paste"], function(label){
-					var button = new dijit.form.Button({
+			array.forEach(["toolbar2", "toolbar3", "toolbar4"], function(toolbarId){
+				var toolbar = new Toolbar({}, dom.byId(toolbarId));
+				array.forEach(["Cut", "Copy", "Paste"], function(label){
+					var button = new Button({
                         id: toolbarId+"."+label,
                         // note: should always specify a label, for accessibility reasons.
                         // Just set showLabel=false if you don't want it to be displayed normally
@@ -56,43 +46,44 @@
                     toolbar.addChild(button);
 				});
 			});
-			
+
+			parser.parse();
 		});
 	</script>
 </head>
 <body class="claro">
 	<h1 class="testTitle">Toolbar test</h1>
 
-	<span data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"ToolbarSectionStart", defaults:{ label: "Label"}'>
-		<span data-dojo-type="dijit.ToolbarSeparator"></span><i>${label}:</i>
+	<span data-dojo-type="dijit/Declaration" data-dojo-props='widgetClass:"ToolbarSectionStart", defaults:{ label: "Label"}'>
+		<span data-dojo-type="dijit/ToolbarSeparator"></span><i>${label}:</i>
 	</span>
 
 	<h2>Toolbar from markup</h2>
 
 	<input id="toolbar1Before" value="input before toolbar1"/>
-	<div id="toolbar1" data-dojo-type="dijit.Toolbar"
+	<div id="toolbar1" data-dojo-type="dijit/Toolbar"
 			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Buttons"'></div
-			><div id="toolbar1.cut" data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</div
-			><div id="toolbar1.copy" data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy", showLabel:true'>Copy</div
+			><div id="toolbar1.cut" data-dojo-type="dijit/form/Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</div
+			><div id="toolbar1.copy" data-dojo-type="dijit/form/Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy", showLabel:true'>Copy</div
 
 			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Toggles"'></div
-			><div id="toolbar1.bold" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBold", showLabel:false'>Bold</div
-			><div id="toolbar1.italic" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconItalic", showLabel:true'>Italic</div
+			><div id="toolbar1.bold" data-dojo-type="dijit/form/ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBold", showLabel:false'>Bold</div
+			><div id="toolbar1.italic" data-dojo-type="dijit/form/ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconItalic", showLabel:true'>Italic</div
 
 ><!--
-			<span data-dojo-type="dijit.ToolbarSeparator"> </span>
+			<span data-dojo-type="dijit/ToolbarSeparator"> </span>
 
 			<span dojo:type="ToolbarButtonGroup" name="justify" defaultButton="justifyleft" preventDeselect="true" showLabel="false">
-				<div data-dojo-type="dijit.form.ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyLeft" name="justify" showLabel="false">Left</div>
-				<div data-dojo-type="dijit.form.ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyRight" name="justify" showLabel="false">Right</div>
-				<div data-dojo-type="dijit.form.ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyCenter" name="justify" showLabel="false">Center</div>
+				<div data-dojo-type="dijit/form/ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyLeft" name="justify" showLabel="false">Left</div>
+				<div data-dojo-type="dijit/form/ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyRight" name="justify" showLabel="false">Right</div>
+				<div data-dojo-type="dijit/form/ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyCenter" name="justify" showLabel="false">Center</div>
 			 </span>
 -->
 
 			<div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Dropdowns"'></div
-			><div id="toolbar1.dialog" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"plusIcon", showLabel:true'>
+			><div id="toolbar1.dialog" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"plusIcon", showLabel:true'>
 				<span>TooltipDialog</span>
-				<div id="tooltipDlg" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information",
+				<div id="tooltipDlg" data-dojo-type="dijit/TooltipDialog" data-dojo-props='title:"Enter Login information",
 					execute:function(args){ console.log("submitted w/args:\n" + dojo.toJson(args, true)); }'>
 					<table>
 						<tr>
@@ -110,39 +101,39 @@
 					</table>
 				</div
 			></div
-			><div id="toolbar1.backcolor" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBackColor", showLabel:true'>
+			><div id="toolbar1.backcolor" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBackColor", showLabel:true'>
 				<span>ColorPalette</span>
-				<div id="toolbar1.colorPalette" data-dojo-type="dijit.ColorPalette" data-dojo-props='style:"display: none", palette:"7x10", onChange:function(){ console.log(this.value); }'></div>
+				<div id="toolbar1.colorPalette" data-dojo-type="dijit/ColorPalette" data-dojo-props='style:"display: none", palette:"7x10", onChange:function(){ console.log(this.value); }'></div>
 			</div
-			><div id="toolbar1.forecolor" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconForeColor", showLabel:false'>
+			><div id="toolbar1.forecolor" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconForeColor", showLabel:false'>
 				<span>Foreground</span>
-				<div id="toolbar1.colorPalette2" data-dojo-type="dijit.ColorPalette" data-dojo-props='style:"display: none", palette:"3x4", onChange:function(){ console.log(this.value); }'></div>
+				<div id="toolbar1.colorPalette2" data-dojo-type="dijit/ColorPalette" data-dojo-props='style:"display: none", palette:"3x4", onChange:function(){ console.log(this.value); }'></div>
 			</div
 
 			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Combos"'></div
-			><div id="toolbar1.combo" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", iconClass:"plusIcon", showLabel:true,
+			><div id="toolbar1.combo" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"save options", iconClass:"plusIcon", showLabel:true,
 				onClick:function(){ console.log("clicked combo save") }'>
 				<span>Menu</span>
-				<div id="saveMenu" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
-					<div data-dojo-type="dijit.MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+				<div id="saveMenu" data-dojo-type="dijit/Menu" data-dojo-props='style:"display: none;"'>
+					<div data-dojo-type="dijit/MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
 						onClick:function(){ console.log("not actually saving anything, just a test!") }'>Save</div>
-					<div data-dojo-type="dijit.MenuItem"
+					<div data-dojo-type="dijit/MenuItem"
 						data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!") }'>Save As</div>
 				</div>
 			</div
-			><div id="toolbar1.combo2" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options2", iconClass:"plusIcon", showLabel:false,
+			><div id="toolbar1.combo2" data-dojo-type="dijit/form/ComboButton" data-dojo-props='optionsTitle:"save options2", iconClass:"plusIcon", showLabel:false,
 				onClick:function(){ console.log("clicked combo save") }'>
 				<span>Menu2</span>
-				<div id="saveMenu2" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
-					<div data-dojo-type="dijit.MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+				<div id="saveMenu2" data-dojo-type="dijit/Menu" data-dojo-props='style:"display: none;"'>
+					<div data-dojo-type="dijit/MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
 						onClick:function(){ console.log("not actually saving anything, just a test!") }'>Save</div>
-					<div data-dojo-type="dijit.MenuItem"
+					<div data-dojo-type="dijit/MenuItem"
 						data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!") }'>Save As</div>
 				</div>
 			</div
 
-			><span data-dojo-type="dijit.ToolbarSeparator"></span
-			><div id="toolbar1.insertorderedlist" data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconInsertOrderedList", showLabel:false'>Ordered list</div
+			><span data-dojo-type="dijit/ToolbarSeparator"></span
+			><div id="toolbar1.insertorderedlist" data-dojo-type="dijit/form/Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconInsertOrderedList", showLabel:false'>Ordered list</div
 	></div>
 	<input id="toolbar1After" value="input after toolbar1"/>
 
diff --git a/dijit/tests/test_Tooltip.html b/dijit/tests/test_Tooltip.html
index 88c84f3..0ada689 100644
--- a/dijit/tests/test_Tooltip.html
+++ b/dijit/tests/test_Tooltip.html
@@ -1,75 +1,73 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dojo Tooltip Widget Test</title>
 
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
+	<script type="text/javascript" src="boilerplate.js"></script>
 
-		td { padding: 20px; }
+	<style type="text/css">
+		#instructionTable.td { padding: 20px; }
 	</style>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
-
 	<script type="text/javascript">
-		dojo.require("dojo.parser");
+		require([
+			"dojo/dom",
+			"dojo/parser",
+			"dijit/registry",
+			"dijit/Tooltip",
+
+			"dijit/ColorPalette",
+			"dijit/form/DateTextBox",
+			"dijit/form/DropDownButton",
+			"dijit/DropDownMenu",
+			"dijit/MenuItem",
+			"dijit/TitlePane",
+				
+			"dojo/domReady!"
+		], function(dom, parser, registry, Tooltip){
+			updateDynamicIds = function(){
+				dom.byId("t_connected_id").innerHTML = "Tooltip connected with nodes: " + registry.byId("t_tooltip").get("connectId");
+			};
+			addDynamicTarget = function(id){
+				registry.byId("t_tooltip").addTarget(id);
+				updateDynamicIds();
+			};
+			removeDynamicTarget = function(id){
+				registry.byId("t_tooltip").removeTarget(id);
+				updateDynamicIds();
+			};
+	
+			setDefaultAlign = function(array){
+				Tooltip.defaultPosition = array;
+				dom.byId('current').innerHTML = "Current: " + array;
+			};
 
-		dojo.require("dijit.Tooltip");
-		dojo.require("dijit.ColorPalette");
-		dojo.require("dijit.form.DateTextBox");
-
-		dojo.require("dijit.form.DropDownButton");
-		dojo.require("dijit.DropDownMenu");
-		dojo.require("dijit.MenuItem");
-		dojo.require("dijit.TitlePane");
-
-		dojo.ready(function(){
 			console.log("on load func");
-			var tt = new dijit.Tooltip({label:"programmatically created tooltip", connectId:["programmaticTest"]});
+			var tt = new Tooltip({label:"programmatically created tooltip", connectId:["programmaticTest"]});
 			console.log("created", tt, tt.id);
 
-			dojo.connect(dijit.byId("t_tooltip"),"onShow",function(t, p){
+			parser.parse();
+
+			registry.byId("t_tooltip").on("show",function(t, p){
 				console.log("Dynamic target tooltip onShow", t, p);//To check correct order in event call
-				if(!p || !p.length){ p = dijit.Tooltip.defaultPosition; }
-				dojo.byId("t_shown").innerHTML = "Tooltip shown for node " + t.id + " at position " + p;
+				if(!p || !p.length){ p = Tooltip.defaultPosition; }
+				dom.byId("t_shown").innerHTML = "Tooltip shown for node " + t.id + " at position " + p;
 			});
-			dojo.connect(dijit.byId("t_tooltip"),"onHide",function(){
+			registry.byId("t_tooltip").on("hide", function(){
 				console.log("Dynamic target tooltip onHide");//To check correct order in event call
-				dojo.byId("t_shown").innerHTML = "Tooltip hidden";
+				dom.byId("t_shown").innerHTML = "Tooltip hidden";
 			});
 			updateDynamicIds();
 		});
-
-		function updateDynamicIds(){
-			dojo.byId("t_connected_id").innerHTML = "Tooltip connected with nodes: " + dijit.byId("t_tooltip").get("connectId");
-		}
-		function addDynamicTarget(id){
-			dijit.byId("t_tooltip").addTarget(id);
-			updateDynamicIds();
-		}
-		function removeDynamicTarget(id){
-			dijit.byId("t_tooltip").removeTarget(id);
-			updateDynamicIds();
-		}
-
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Tooltip test</h1>
 
 	<p>Mouse-over or focus the items below to test tooltips.</p>
-	<table>
+	<table id="instructionTable" role="presentation">
 		<tr>
 			<td>
 				Change tooltip positioning search list:
@@ -83,46 +81,50 @@
 		</tr>
 		<tr>
 			<td>
-				<button onclick="dijit.Tooltip.defaultPosition=['above-centered', 'below-centered']; dojo.byId('current').innerHTML='Current: ' + dijit.Tooltip.defaultPosition;">above, below</button>
-				<button onclick="dijit.Tooltip.defaultPosition=['after', 'before']; dojo.byId('current').innerHTML='Current: ' + dijit.Tooltip.defaultPosition;">after, before (default)</button>
+				<button onclick="setDefaultAlign(['above-centered', 'below-centered']);">above-centered, below-centered</button>
+				<button onclick="setDefaultAlign(['after-centered', 'before-centered']);">after-centered, before-centered</button>
+				<button onclick="setDefaultAlign(['above', 'below']);">above, below</button>
+				<!-- unsupported (and currently broken)
+				<button onclick="setDefaultAlign(['after', 'before']);">after, before</button>
+				-->
 				<div id=current>
 					Current: default (unchanged)
 				</div>
 			</td>
 			<td>
-				<div data-dojo-type="dijit.ColorPalette" data-dojo-props='onChange:function(val){ dojo.query("body").style("background", val); }'></div>
+				<div data-dojo-type="dijit/ColorPalette" data-dojo-props='onChange:function(val){ dojo.query("body").style("background", val); }'></div>
 			</td>
 			<td>
-				<input data-dojo-type="dijit.form.DateTextBox" data-dojo-props='id: "dtb", value: "2010-12-15", promptMessage: "Please Enter a date in dd/MM/yyyy format", style:"width: 8em;"'>				
+				<input data-dojo-type="dijit/form/DateTextBox"  aria-label="label" data-dojo-props='id: "dtb", value: "2010-12-15", promptMessage: "Please Enter a date in dd/MM/yyyy format", style:"width: 8em;"'>
 			</td>
 		</tr>
 	</table>
 
 	<label for="ddb">Drop down menu items have tooltips:</label>
-	<button id="ddb" data-dojo-type="dijit.form.DropDownButton">
+	<button id="ddb" data-dojo-type="dijit/form/DropDownButton">
 		<span>DropDown</span>
-		<span id="ddm" data-dojo-type="dijit.DropDownMenu">
-			<span id="cut" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+		<span id="ddm" data-dojo-type="dijit/DropDownMenu">
+			<span id="cut" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
 				onClick:function(){ console.log("not actually cutting anything, just a test!"); }'>Cut</span>
-			<span id="copy" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+			<span id="copy" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
 				onClick:function(){ console.log("not actually copying anything, just a test!"); }'>Copy</span>
-			<span id="paste" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+			<span id="paste" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
 				onClick:function(){ console.log("not actually pasting anything, just a test!"); }'>Paste</span>
 		</span>
 	</button>
-	<span id="cut_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["cut"]'>tooltip for cut</span>
-	<span id="copy_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["copy"]'>tooltip for copy</span>
-	<span id="paste_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["paste"]'>tooltip for paste</span>
+	<span id="cut_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["cut"]'>tooltip for cut</span>
+	<span id="copy_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["copy"]'>tooltip for copy</span>
+	<span id="paste_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["paste"]'>tooltip for paste</span>
 
 	<div id="tp2" dojoType="dijit.TitlePane" title="Tooltip on span in TitlePane" style="width: 300px;">
 		<span id="tpTooltipTarget">hover me for tooltip</span>
 		<span dojoType="dijit.Tooltip" connectId="tpTooltipTarget">tooltip on TitlePane span</span>
 	</div>
 
-	<input value="input, no tooltip"/>
+	<input value="input, no tooltip" aria-label="label" />
 	<div>
 		<span id="one" class="tt" tabindex="0"> focusable text </span>
-		<span id="one_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["one"]'>
+		<span id="one_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["one"]'>
 			<b>
 				<span style="color: blue;">rich formatting</span>
 				<span style="color: red; font-size: x-large;"><i>!</i></span>
@@ -130,30 +132,30 @@
 		</span>
 	</div>
 	<span id="oneA" class="tt"> plain text (not focusable) </span>
-	<span id="oneA_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["oneA"]'>
+	<span id="oneA_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["oneA"]'>
 		<span> keyboard users can not access this tooltip</span>
 	</span>
     <a id="three" href="#bogus">anchor</a>
-	<span id="three_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["three"]'>tooltip on a link </span>
+	<span id="three_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["three"]'>tooltip on a link </span>
 	<p></p>
 
 	<span id="programmaticTest">this text has a programmatically created tooltip</span>
 	<br>
 
 	<button id="four">button w/tooltip</button>
-	<span id="btnTt" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["four"]'>tooltip on a button</span>
-	<button id="removeButton" onclick="dijit.byId('btnTt').destroy()">Remove</button> tooltip from "button w/tooltip".
+	<span id="btnTt" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["four"]'>tooltip on a button</span>
+	<button id="removeButton" onclick="registry.byId('btnTt').destroy()">Remove</button> tooltip from "button w/tooltip".
 
 	<span style="float: right">
 		Test tooltip on right aligned element.  Tooltip should flow to the left -->
-		<select id="seven">
+		<select id="seven" aria-label="label">
 			<option value="alpha">Alpha</option>
 			<option value="beta">Beta</option>
 			<option value="gamma">Gamma</option>
 			<option value="delta">Delta</option>
 		</select>
 
-		<span id="seven_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["seven"]'>
+		<span id="seven_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["seven"]'>
 			tooltip on a select<br>
 			two line tooltip.
 		</span>
@@ -162,12 +164,12 @@
 	<p></p>
 
 	<form>
-		<input id="id1" value="#1"/><br>
-		<input id="id2" value="#2"/><br>
-		<input id="id3" value="#3"/><br>
-		<input id="id4" value="#4"/><br>
-   		<input id="id5" value="#5"/><br>
-		<input id="id6" value="#6"/><br>
+		<input id="id1" value="#1" aria-label="1" /><br>
+		<input id="id2" value="#2" aria-label="2"/><br>
+		<input id="id3" value="#3" aria-label="3"/><br>
+		<input id="id4" value="#4" aria-label="4"/><br>
+		<input id="id5" value="#5" aria-label="5"/><br>
+		<input id="id6" value="#6" aria-label="6"/><br>
 	</form>
 	<br>
 
@@ -179,27 +181,27 @@
 		<span id="s5">s5 text</span><br><br><br>
 	</div>
 
-	<span id="id1_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id1"]'>
+	<span id="id1_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id1"]'>
 
 	tooltip for #1<br>
 	long long long long long long long long long long long text<br>
 	make sure that this works properly with a really narrow window
 	</span>
 
-	<span id="id2_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id2"]'>tooltip for #2</span>
-	<span id="id3_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id3"]'>tooltip for #3</span>
-	<span id="id4_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id4"]'>tooltip for #4</span>
-	<span id="id5_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id5"]'>tooltip for #5</span>
-	<span id="id6_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id6"]'>tooltip for #6</span>
+	<span id="id2_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id2"]'>tooltip for #2</span>
+	<span id="id3_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id3"]'>tooltip for #3</span>
+	<span id="id4_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id4"]'>tooltip for #4</span>
+	<span id="id5_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id5"]'>tooltip for #5</span>
+	<span id="id6_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["id6"]'>tooltip for #6</span>
 
-	<span id="s1_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["s1"]'>s1 tooltip</span>
-	<span id="s2_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["s2"]'>s2 tooltip</span>
-	<span id="s3_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["s3"]'>s3 tooltip</span>
-	<span id="s4_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["s4"]'>s4 tooltip</span>
-	<span id="s5_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["s5"]'>s5 tooltip</span>
+	<span id="s1_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["s1"]'>s1 tooltip</span>
+	<span id="s2_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["s2"]'>s2 tooltip</span>
+	<span id="s3_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["s3"]'>s3 tooltip</span>
+	<span id="s4_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["s4"]'>s4 tooltip</span>
+	<span id="s5_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["s5"]'>s5 tooltip</span>
 
 	<h3>One Tooltip for multiple connect nodes</h3>
-	<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["multi1","multi2"], id:"multi1,multi2_tooltip", style:"display:none;"'>multi tooltip</span>
+	<span data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["multi1","multi2"], id:"multi1,multi2_tooltip", style:"display:none;"'>multi tooltip</span>
 	<a id="multi1" href="#bogus">multi1</a><br><a id="multi2" href="#bogus">multi2</a>
 
 	<h3>One Tooltip for multiple connect nodes w/ dojoType</h3>
@@ -228,6 +230,42 @@
 	<span id="t_connected_id"></span><br>
 	<span id="t_shown">Tooltip hidden (initial)</span>
 
-	<span id="t_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["t1","t3"]'>Dynamic target tooltip</span>
+	<span id="t_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["t1","t3"]'>Dynamic target tooltip</span>
+
+	<h3>Nested div test:</h3>
+	<div dir="ltr" style="margin: 0px 100px;">
+		<input id="inputBeforeNested" value="before" aria-label="label">
+		<div id="nested" style="width: 300px;background-color: yellow">
+			Mouse over the inner blue div should show the tooltip on this outer yellow div.
+			<div style="width: 100px; height: 100px; background-color: blue; color: white;">
+				inner blue div
+			</div>
+			Likewise, focusing the input should put the tooltip on the outer yellow div
+			<br>
+			<input id="nestedInput" value="focus me" aria-label="label">
+		</div>
+		<span id="nested_tooltip" data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:"nested"'>
+			Tooltip on yellow outer div
+		</span>
+	</div>
+
+	<h3>Delegation test:</h3>
+	<p>Tooltip should appear for first three rows of the table, customized per row.</p>
+	<span id="delegation_tooltip" data-dojo-type="dijit/Tooltip"
+		  data-dojo-props='connectId:"myTable", selector: "tr"'>
+		<script type="dojo/method" data-dojo-event="getContent" data-dojo-args="node">
+			var row = node.getAttribute("row");
+			return row <= 3 ? ("Tooltip for row " + row) : null;
+		</script>
+		This text will never appear; instead getContent() will run.
+	</span>
+	<table id="myTable">
+		<tr id="myTable-row1" row=1><td>row</td><td>1</td></tr>
+		<tr id="myTable-row2" row=2><td>row</td><td>2</td></tr>
+		<tr id="myTable-row3" row=3><td>row</td><td>3</td></tr>
+		<tr id="myTable-row4" row=4><td>row</td><td>4</td></tr>
+		<tr id="myTable-row5" row=5><td>row</td><td>5</td></tr>
+	</table>
+
 </body>
 </html>
diff --git a/dijit/tests/test_TooltipDialog.html b/dijit/tests/test_TooltipDialog.html
index af1f9c8..d90cff1 100644
--- a/dijit/tests/test_TooltipDialog.html
+++ b/dijit/tests/test_TooltipDialog.html
@@ -1,13 +1,12 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>TooltipDialog Widget Tests</title>
 
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
+	<script type="text/javascript" src="boilerplate.js"></script>
 
+	<style type="text/css">
 		body { font-family : sans-serif; }
 		form { margin-bottom : 0; }
 		table { border: none; }
@@ -30,70 +29,62 @@
 		}
 	</style>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
-
 	<script type="text/javascript">
-		dojo.require("dijit._Widget");
-		dojo.require("dijit._TemplatedMixin");
-
-		dojo.require("dijit.TooltipDialog");
-		dojo.require("dijit.form.DropDownButton");
-
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dijit.form.DateTextBox");
-		dojo.require("dijit.form.TimeTextBox");
-		dojo.require("dijit.form.FilteringSelect");
-		dojo.require("dijit.form.Select");
+		require([
+			"dojo/_base/declare",
+			"dojo/dom",
+			"dojo/date/stamp",
+			"dojo/parser",
+			"dijit/_WidgetBase",
+			"dijit/_TemplatedMixin",
+			"dijit/TooltipDialog",
+			"dijit/layout/ContentPane",
+			"dijit/form/DropDownButton",
+	
+			"dijit/form/Form",
+			"dijit/form/TextBox",
+			"dijit/form/DateTextBox",
+			"dijit/form/TimeTextBox",
+			"dijit/form/FilteringSelect",
+			"dijit/form/Select",
+	
+			"dijit/layout/TabContainer",
+			"dijit/InlineEditBox",
+	
+			"dijit/Menu",
+			"dijit/MenuItem",
+			"dijit/PopupMenuItem",
+			"dijit/MenuSeparator",
+				
+			"dojo/domReady!"
+		], function(declare, dom, stamp, parser, _WidgetBase, _TemplatedMixin, TooltipDialog, ContentPane, DropDownButton){
 
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.InlineEditBox");
-
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.MenuItem");
-		dojo.require("dijit.PopupMenuItem");
-		dojo.require("dijit.MenuSeparator");
-
-		dojo.require("dojo.parser");
-
-		// make dojo.toJson() print dates correctly (this feels a bit dirty)
-		Date.prototype.json = function(){ return dojo.date.stamp.toISOString(this, {selector: 'date'});};
-
-		dojo.ready(function(){
 			// create a do nothing, only for test widget
-			dojo.declare("dijit.TestWidget",
-				[dijit._Widget, dijit._TemplatedMixin], {
+			declare("TestWidget", [_WidgetBase, _TemplatedMixin], {
 				templateString: "<div style='margin: 10px; border: inset #700 4px; padding: 5px;' dojoAttachPoint='containerNode'></div>"
 			});
 
 			// scan page for widgets and instantiate them
-			dojo.parser.parse();
+			parser.parse();
 
 			// Nested TooltipDialog that contains a nested Menu
-			var innerTtDialog = new dijit.TooltipDialog({
+			var innerTtDialog = new TooltipDialog({
 				id: "innerTtDialog",
 				content:
-					'<div dojoType="dijit.Menu" id="navMenu"><div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCut" >Drama</div><div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCopy" >Comedy</div><div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste" >Romance</div><div dojoType="dijit.MenuSeparator"></div><div dojoType="dijit.PopupMenuItem" id="popupMenuItem"><span>Action</span><div dojoType="dijit.Menu" id="submenu"><div dojoType= [...]
-					+ '<label for="name">Name:</label> <input dojoType="dijit.form.TextBox" id="name" name="name"><br>' 
-					+ '<label for="hobby">Hobby:</label> <input dojoType="dijit.form.TextBox" id="hobby" name="hobby"><br>' 
-					+ '<button dojoType="dijit.form.Button" type="button">Save</button>'
+					'<div data-dojo-type="dijit/Menu" id="navMenu"><div data-dojo-type="dijit/MenuItem" iconClass="dijitEditorIcon dijitEditorIconCut" >Drama</div><div data-dojo-type="dijit/MenuItem" iconClass="dijitEditorIcon dijitEditorIconCopy" >Comedy</div><div data-dojo-type="dijit/MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste" >Romance</div><div data-dojo-type="dijit/MenuSeparator"></div><div data-dojo-type="dijit/PopupMenuItem" id="popupMenuItem"><span>Action</span><div data-dojo-typ [...]
+					+ '<label for="name">Name:</label><br><input data-dojo-type="dijit/form/TextBox" id="name" name="name"><br>'
+					+ '<label for="hobby">Hobby:</label><br><input data-dojo-type="dijit/form/TextBox" id="hobby" name="hobby"><br>'
+					+ '<button data-dojo-type="dijit/form/Button" type="button">Save</button>'
 					+ '<div id="plaintext">plain text</div>'
 			 });
 
-			var innerDdBtn = new dijit.form.DropDownButton({
+			var innerDdBtn = new DropDownButton({
 				id: "innerDdBtn",
 				label: "Inner TooltipDialog (innerTtDialog)",
 				dropDown: innerTtDialog
 			});
 
-			var ddDialogCp = new dijit.layout.ContentPane({
+			var ddDialogCp = new ContentPane({
 				id: "ddDialogCp",
 				title: '',
 				refreshOnShow: true
@@ -101,49 +92,48 @@
 			ddDialogCp.startup();
 			ddDialogCp.set("content", innerDdBtn);
 
-			var outerTtDialog = new dijit.TooltipDialog({
+			var outerTtDialog = new TooltipDialog({
 			   id: "outerTtDialog",
 			   content:ddDialogCp
 			});
 
-			var launcherBtn = new dijit.form.DropDownButton({
+			var launcherBtn = new DropDownButton({
 				id: "outerDdBtn",
 				label: "Nested TooltipDialog (ttDialog)",
 				dropDown: outerTtDialog
 			});
 
-			dojo.byId("dropdownButtonContainer").appendChild(launcherBtn.domNode);
+			dom.byId("dropdownButtonContainer").appendChild(launcherBtn.domNode);
 		});
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">dijit.TooltipDialog tests</h1>
-
-	<div id="tooltipDlgButton" data-dojo-type="dijit.form.DropDownButton" >
+	<div id="tooltipDlgButton" data-dojo-type="dijit/form/DropDownButton">
 		<span>Show Tooltip Dialog</span>
-		<div id="tooltipDlg" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information"'>
-			<table>
+		<div id="tooltipDlg" data-dojo-type="dijit/TooltipDialog" data-dojo-props='title:"Enter Login information"'>
+			<table role="presentation">
 				<tr>
 					<td><label>InlineEditBox:</label></td>
-					<td><div id="inline" data-dojo-type=dijit.InlineEditBox data-dojo-props='editorParams:{type:"text", name:"inline"}'>inline</div></td>
+					<td><div id="inline" data-dojo-type=dijit/InlineEditBox data-dojo-props='editorParams:{type:"text", name:"inline"}'>inline</div></td>
 				</tr>
 				<tr>
 					<td><label for="text">TextBox:</label></td>
-					<td><input id="text" data-dojo-type=dijit.form.TextBox data-dojo-props='name:"text" '/></td>
+					<td><input id="text" data-dojo-type=dijit/form/TextBox data-dojo-props='name:"text" '/></td>
 				</tr>
 				<tr>
 					<td><label for="date2">Date:</label></td>
-					<td><input id="date2" data-dojo-type=dijit.form.DateTextBox data-dojo-props='name:"date" '/></td>
+					<td><input id="date2" data-dojo-type=dijit/form/DateTextBox data-dojo-props='name:"date" '/></td>
 				</tr>
 				<tr>
 					<td><label for="time2">Time:</label></td>
-					<td><input id="time2" data-dojo-type=dijit.form.TimeTextBox data-dojo-props='name:"time" '/></td>
+					<td><input id="time2" data-dojo-type=dijit/form/TimeTextBox data-dojo-props='name:"time" '/></td>
 				</tr>
 				<tr>
 					<td><label for="combo">FilteringSelect:</label></td>
 					<td>
-						<select id="combo" data-dojo-type=dijit.form.FilteringSelect data-dojo-props='name:"combo", hasDownArrow:true'>
+						<select id="combo" data-dojo-type=dijit/form/FilteringSelect data-dojo-props='name:"combo", hasDownArrow:true'>
 							<option value="cheese">cheese</option>
 							<option value="pepperoni">pepperoni</option>
 							<option value="sausage">sausage</option>
@@ -153,7 +143,7 @@
 				<tr>
 					<td><label for="select">Select:</label></td>
 					<td>
-						<select id="select" data-dojo-type=dijit.form.Select data-dojo-props='name:"select" '>
+						<select id="select" data-dojo-type=dijit/form/Select data-dojo-props='name:"select" '>
 							<option value="olives">olives</option>
 							<option value="peppers">peppers</option>
 							<option value="tomatoes">tomatoes</option>
@@ -162,7 +152,7 @@
 				</tr>
 				<tr>
 					<td colspan="2" style="text-align:center;">
-						<button id="submit" data-dojo-type=dijit.form.Button data-dojo-props='type:"submit", name:"submit" '>Order</button>
+						<button id="submit" data-dojo-type=dijit/form/Button data-dojo-props='type:"submit", name:"submit" '>Order</button>
 					</td>
 				</tr>
 			</table>
@@ -170,11 +160,11 @@
 		</div>
 	</div> |
 
-	<div data-dojo-type="dijit.form.DropDownButton">
+	<div data-dojo-type="dijit/form/DropDownButton">
 		<span>Show Tooltip Dialog with TabContainer</span>
-		<div id="tabTooltip" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Tab Container Tooltip"'>
-			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 400px; height: 300px;"'>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"First tab"'>
+		<div id="tabTooltip" data-dojo-type="dijit/TooltipDialog" data-dojo-props='title:"Tab Container Tooltip"'>
+			<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props='style:"width: 400px; height: 300px;"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"First tab"'>
 					<p>
 						This is the first tab.
 					</p>
@@ -187,7 +177,7 @@
 					risus.
 					</p>
 				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Second tab"'>
+				<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Second tab"'>
 					<p>
 						This is the second tab.
 					</p>
@@ -204,36 +194,69 @@
 		</div>
 	</div> |
 
-	<div id="slowLoadButton" data-dojo-type="dijit.form.DropDownButton">
+	<div id="slowLoadButton" data-dojo-type="dijit/form/DropDownButton">
 		<span>Test slowloading HREF Tooltip Dialog</span>
-		<div id="slowLoad" data-dojo-type="dijit.TooltipDialog" data-dojo-props='href:"layout/getResponse.php?delay=500&messId=2",
+		<div id="slowLoad" data-dojo-type="dijit/TooltipDialog" data-dojo-props='href:"layout/getResponse.php?delay=500&messId=2",
 			title:"tooltip dialog with no focusable items"'></div>
 	</div> |
 
-<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props='"class":"tooltipLink"'>
-	<span>What is this?</span>
-	<div id="tooltipHelpDlg" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Test Dialog tooltip", style:"width:350px" '>
-		<div data-dojo-type="dijit.form.Button" data-dojo-props='"class":"buttonLink", style:"float:right;font-size:x-small", title:"close", tabIndex:"0" '>[close]
-			<script type="dojo/method" data-dojo-event="onClick">
-					dijit.byId('tooltipHelpDlg').onCancel();
-			</script>
-		</div>
-		<div role="alert" style="margin-top:1em">
-			<strong>Important!</strong> This is a tooltip dialog with just text! It could be used
-			to provide help. It will stay open until the user explicitly closes it via pressing escape, clicking [close] or by
-			clicking somewhere else on the page.  To make certain a screen reader will speak this text (at least in Firefox 3),
-			the div containing the text was given an
-			<a href="http://www.w3.org/WAI/PF/aria/">ARIA</a> role of alert. In the future the tooltip
-			dialog may be given a role of alertdialog.
-		</div>
+	<div data-dojo-type="dijit/form/DropDownButton" data-dojo-props='"class":"tooltipLink"'>
+		<span>What is this?</span>
+		<div data-dojo-id="tooltipHelpDlg" data-dojo-type="dijit/TooltipDialog" data-dojo-props='title:"Test Dialog tooltip", style:"width:350px" '>
+			<div data-dojo-type="dijit/form/Button" data-dojo-props='"class":"buttonLink", style:"float:right;font-size:x-small", title:"close", tabIndex:"0" '>[close]
+				<script type="dojo/method" data-dojo-event="onClick">
+						tooltipHelpDlg.onCancel();
+				</script>
+			</div>
+			<div role="alert" style="margin-top:1em">
+				<strong>Important!</strong> This is a tooltip dialog with just text! It could be used
+				to provide help. It will stay open until the user explicitly closes it via pressing escape, clicking [close] or by
+				clicking somewhere else on the page.  To make certain a screen reader will speak this text (at least in Firefox 3),
+				the div containing the text was given an
+				<a href="http://www.w3.org/WAI/PF/aria/">ARIA</a> role of alert. In the future the tooltip
+				dialog may be given a role of alertdialog.
+			</div>
 
+		</div>
 	</div>
-</div>
 
 	<span id="dropdownButtonContainer">
 		<!-- programatically created nested TooltipDialog will be placed here -->
 	</span>
 
+	<div data-dojo-type="dijit/form/DropDownButton">
+		<span>TooltipDialog w/ActionBar</span>
+		<div data-dojo-type="dijit/TooltipDialog" id="loginform" data-dojo-props="title: 'Login...'">
+			<form data-dojo-type="dijit/form/Form">
+				<table>
+					<tr><td><label for="username2">Username:</label></td><td><input type="text" id="username2" data-dojo-type="dijit/form/TextBox" /></td></tr>
+					<tr><td><label for="password2">Password:</label></td><td><input type="password" id="password2" data-dojo-type="dijit/form/TextBox" /></td></tr>
+				</table>
+				<div class="dijitDialogPaneActionBar">
+					<button data-dojo-type="dijit/form/Button" type="reset">Reset</button>
+					<button data-dojo-type="dijit/form/Button" type="submit">Login</button>
+				</div>
+			</form>
+		</div>
+	</div>
+
+	<div data-dojo-type="dijit/form/DropDownButton" data-dojo-props="dropDownPosition: ['below-centered', 'above-centered']">
+		<span>Centered TooltipDialog</span>
+		<div data-dojo-type="dijit/TooltipDialog" id="loginform3" data-dojo-props="title: 'Login...'">
+			<form data-dojo-type="dijit/form/Form">
+				<table>
+					<tr><td><label for="username3">Username:</label></td><td><input type="text" id="username3" data-dojo-type="dijit/form/TextBox" /></td></tr>
+					<tr><td><label for="password3">Password:</label></td><td><input type="password" id="password3" data-dojo-type="dijit/form/TextBox" /></td></tr>
+				</table>
+				<div class="dijitDialogPaneActionBar">
+					<button data-dojo-type="dijit/form/Button" type="reset">Reset</button>
+					<button data-dojo-type="dijit/form/Button" type="submit">Login</button>
+				</div>
+			</form>
+		</div>
+	</div>
+
+
 	<p><b><i>(scroll down to see more links to click, for testing positioning / scroll handling)</i></b></p>
 
 	<p>Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
@@ -262,7 +285,7 @@
 	</p>
 	<form>
 		<div style="text-align:center;">
-			<select>
+			<select aria-label="select">
 				<option>1</option>
 				<option>2</option>
 			</select>
@@ -282,9 +305,9 @@
 	turpis sed odio. Curabitur in est id nibh tempus ultrices. Aliquam
 	consectetuer dapibus eros. Aliquam nisl.
 	</p>
-	<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props='style:"float:right;clear:right;" '>
+	<div data-dojo-type="dijit/form/DropDownButton" data-dojo-props='style:"float:right;clear:right;" '>
 		<span>dropdown at right</span>
-	<div id="dialogright" data-dojo-type="dijit.TooltipDialog" >
+	<div id="dialogright" data-dojo-type="dijit/TooltipDialog" >
 			<div style="white-space:nowrap;">Aliquam vitae enim. Duis scelerisque metus auctor est venenatis</div>
 	</div>
 	</div>
@@ -310,9 +333,9 @@
 	tortor pharetra congue. Suspendisse pulvinar.
 	</p>
 
-	<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props='title:"Enter Login information2"'>
+	<div data-dojo-type="dijit/form/DropDownButton" data-dojo-props='title:"Enter Login information2"'>
 		<span>Show Tooltip Dialog pointing upwards, with links</span>
-		<div data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"General Information Dialog"'>
+		<div data-dojo-type="dijit/TooltipDialog" data-dojo-props='title:"General Information Dialog"'>
 			<p>Vestibulum convallis eros ac justo. Proin dolor. Etiam aliquam. Nam
 			ornare elit vel augue. Suspendisse potenti. Etiam sed mauris eu neque
 			nonummy mollis. <a href="http://www.lipsum.com/">Vestibulum</a> vel purus ac pede semper accumsan. Vivamus
@@ -341,7 +364,7 @@
 	</p>
 	<form>
 		<div style="text-align:center;">
-			<select>
+			<select aria-label="select">
 				<option>1</option>
 				<option>2</option>
 			</select>
diff --git a/dijit/tests/test_UIWindowIssue_main.html b/dijit/tests/test_UIWindowIssue_main.html
index e34f053..111302a 100644
--- a/dijit/tests/test_UIWindowIssue_main.html
+++ b/dijit/tests/test_UIWindowIssue_main.html
@@ -10,56 +10,56 @@
 <body class="claro">
 	<iframe style="width:100%;height:2em;" src="./test_UIWindowIssue_child.html"></iframe>
 
-	<div id="menu" data-dojo-type="dijit.Menu" data-dojo-props="contextMenuForWindow:true" style="display:none;">
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Hello world"); }'>Context Menu</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='disabled:true, onClick:function(){ alert("this should NOT appear"); }'>Disabled Item</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+	<div id="menu" data-dojo-type="dijit/Menu" data-dojo-props="contextMenuForWindow:true" style="display:none;">
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Hello world"); }'>Context Menu</div>
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='disabled:true, onClick:function(){ alert("this should NOT appear"); }'>Disabled Item</div>
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
 			onClick:function(){ console.log("not actually cutting anything, just a test!") }, accelKey:"Ctrl+X"'>Cut</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
 			onClick:function(){ console.log("not actually copying anything, just a test!") }, accelKey:"Ctrl+C"'>Copy</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+		<div data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
 			onClick:function(){ console.log("not actually pasting anything, just a test!") }, accelKey:"Ctrl+V"'>Paste</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div id="enabledSubmenu" data-dojo-type="dijit.PopupMenuItem" >
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div id="enabledSubmenu" data-dojo-type="dijit/PopupMenuItem" >
 			<span>Enabled Submenu</span>
-			<div id="submenu2" data-dojo-type="dijit.Menu" >
-				<div id="submenu2_item1" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
-				<div id="submenu2_item2" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
-				<div id="deeperSubmenu" data-dojo-type="dijit.PopupMenuItem" >
+			<div id="submenu2" data-dojo-type="dijit/Menu" >
+				<div id="submenu2_item1" data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+				<div id="submenu2_item2" data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
+				<div id="deeperSubmenu" data-dojo-type="dijit/PopupMenuItem" >
 					<span>Deeper Submenu</span>
-					<div id="submenu4" data-dojo-type="dijit.Menu" >
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</div>
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</div>
+					<div id="submenu4" data-dojo-type="dijit/Menu" >
+						<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</div>
+						<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</div>
 					</div>
 				</div>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.PopupMenuItem" data-dojo-props='disabled:true'>
+		<div data-dojo-type="dijit/PopupMenuItem" data-dojo-props='disabled:true'>
 			<span>Disabled Submenu</span>
-			<div id="submenu3" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
+			<div id="submenu3" data-dojo-type="dijit/Menu" data-dojo-props='style:"display: none;"'>
+				<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+				<div data-dojo-type="dijit/MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props='checked:true, onChange:function(val){ console.log("Now set to " + val); }'>Checked</div>
-		<div data-dojo-type="dijit.CheckedMenuItem">Not Checked</div>
-		<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props='checked:true, disabled:true'>Checked Disabled</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div data-dojo-type="dijit.PopupMenuItem">
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div data-dojo-type="dijit/CheckedMenuItem" data-dojo-props='checked:true, onChange:function(val){ console.log("Now set to " + val); }'>Checked</div>
+		<div data-dojo-type="dijit/CheckedMenuItem">Not Checked</div>
+		<div data-dojo-type="dijit/CheckedMenuItem" data-dojo-props='checked:true, disabled:true'>Checked Disabled</div>
+		<div data-dojo-type="dijit/MenuSeparator"></div>
+		<div data-dojo-type="dijit/PopupMenuItem">
 			<span>Bigger Submenu</span>
-			<div id="bigsubmenu" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
-				<div data-dojo-type="dijit.MenuItem">Item One</div>
-				<div data-dojo-type="dijit.MenuItem">Item Two</div>
-				<div data-dojo-type="dijit.MenuItem">Item Three</div>
-				<div data-dojo-type="dijit.MenuItem">Item Four</div>
-				<div data-dojo-type="dijit.MenuItem">Item Five</div>
-				<div data-dojo-type="dijit.MenuItem">Item Six</div>
-				<div data-dojo-type="dijit.MenuItem">Item Seven</div>
-				<div data-dojo-type="dijit.MenuItem">Item Eight</div>
-				<div data-dojo-type="dijit.MenuItem">Item Nine</div>
-				<div data-dojo-type="dijit.MenuItem">Item Ten</div>
+			<div id="bigsubmenu" data-dojo-type="dijit/Menu" data-dojo-props='style:"display: none;"'>
+				<div data-dojo-type="dijit/MenuItem">Item One</div>
+				<div data-dojo-type="dijit/MenuItem">Item Two</div>
+				<div data-dojo-type="dijit/MenuItem">Item Three</div>
+				<div data-dojo-type="dijit/MenuItem">Item Four</div>
+				<div data-dojo-type="dijit/MenuItem">Item Five</div>
+				<div data-dojo-type="dijit/MenuItem">Item Six</div>
+				<div data-dojo-type="dijit/MenuItem">Item Seven</div>
+				<div data-dojo-type="dijit/MenuItem">Item Eight</div>
+				<div data-dojo-type="dijit/MenuItem">Item Nine</div>
+				<div data-dojo-type="dijit/MenuItem">Item Ten</div>
 			</div>
 		</div>
 	</div>
diff --git a/dijit/tests/test_bgIframe.html b/dijit/tests/test_bgIframe.html
index c88754f..bf7fa96 100644
--- a/dijit/tests/test_bgIframe.html
+++ b/dijit/tests/test_bgIframe.html
@@ -5,45 +5,39 @@
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 
 	<title>Dojo Toolkit - Background Iframe test</title>
-	<style type="text/css">
-		@import "../themes/claro/document.css";
-		@import "css/dijitTests.css";
-	</style>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
+	<script type="text/javascript" src="boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Dialog");
-		dojo.require("dijit.form.DateTextBox");
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.Tooltip");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dijit/Dialog",
+			"dijit/DropDownMenu",
+			"dijit/MenuItem",
+			"dijit/form/DateTextBox",
+			"dijit/form/Button",
+			"dijit/Tooltip",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 
 </head>
 <body class="claro">
-	<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["one_applet"]'>
+	<span data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["one_applet"]'>
 		This is one tooltip.
 	</span>
-	<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["two_applet"]'>
+	<span data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["two_applet"]'>
 		This is another tooltip.  A little longer...
 	</span>
-	<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["one_xapp"]'>
+	<span data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["one_xapp"]'>
 		This is one tooltip.
 	</span>
-	<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["two_xapp"]'>
+	<span data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:["two_xapp"]'>
 		This is another tooltip.  A little longer...
 	</span>
-	<button id="showDialog" data-dojo-type="dijit.form.Button">
+	<button id="showDialog" data-dojo-type="dijit/form/Button">
 		Show Dialog
 		<script type="dojo/connect" data-dojo-event="onClick">
 			dialog.show();
@@ -53,7 +47,18 @@
 			<tr>
 				<td></td>
 				<td>
-					<input id="dateText_applet" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='type:"text" '/>
+					<input id="dateText_applet" data-dojo-type="dijit/form/DateTextBox" data-dojo-props='type:"text" '/>
+					<button id="menuButton_applet" title="edit title" value="Edit" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"noteIcon"'>
+						<span>Edit<b>!</b></span>
+						<span id="menu_applet" data-dojo-type="dijit/DropDownMenu" >
+							<span id="cut_applet" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+								onClick:function(){ console.log("not actually cutting anything, just a test!"); }'>Cut</span>
+							<span id="copy_applet" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+								onClick:function(){ console.log("not actually copying anything, just a test!"); }'>Copy</span>
+							<span id="paste_applet" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+								onClick:function(){ console.log("not actually pasting anything, just a test!"); }'>Paste</span>
+						</span>
+					</button>
 				</td>
 			</tr>
 			<tr>
@@ -88,7 +93,18 @@
 			<tr>
 				<td></td>
 				<td>
-					<input id="dateText_xapp" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='type:"text" '/>
+					<input id="dateText_xapp" data-dojo-type="dijit/form/DateTextBox" data-dojo-props='type:"text" '/>
+					<button id="menuButton_xapp" title="edit title" value="Edit" data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"noteIcon"'>
+						<span>Edit<b>!</b></span>
+						<span id="menu_xapp" data-dojo-type="dijit/DropDownMenu" >
+							<span id="cut_xapp" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+								onClick:function(){ console.log("not actually cutting anything, just a test!"); }'>Cut</span>
+							<span id="copy_xapp" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+								onClick:function(){ console.log("not actually copying anything, just a test!"); }'>Copy</span>
+							<span id="paste_xapp" data-dojo-type="dijit/MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+								onClick:function(){ console.log("not actually pasting anything, just a test!"); }'>Paste</span>
+						</span>
+					</button>
 				</td>
 			</tr>
 			<tr>
@@ -114,7 +130,7 @@
 				</td>
 			</tr>
 	</table>
-	<div id="dialog" data-dojo-id="dialog" data-dojo-type="dijit.Dialog">
+	<div id="dialog" data-dojo-id="dialog" data-dojo-type="dijit/Dialog">
 		Hello!
 	</div>
 </body>
diff --git a/dijit/tests/test_typematic.html b/dijit/tests/test_typematic.html
new file mode 100644
index 0000000..31c7e00
--- /dev/null
+++ b/dijit/tests/test_typematic.html
@@ -0,0 +1,68 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>Typematic Test</title>
+	<style type="text/css">
+		@import "../themes/claro/document.css";
+		@import "../themes/claro/claro.css";
+		@import "css/dijitTests.css";
+	</style>
+
+	<script type="text/javascript" src="../../dojo/dojo.js"
+			data-dojo-config="isDebug: true"></script>
+	<script type="text/javascript">
+		dojo.require("dijit.typematic");
+
+		var lastCount = 0;
+		function typematicCallBack(count, node, evt){
+			var inputNode = dojo.byId('typematicInput');
+			if(node == inputNode){
+				key = "a";
+			}else{
+				key = "b";
+			}
+			if(-1 == count){
+				console.debug((lastCount + 1) + ' ' + key + ' events');
+			}else{
+				lastCount = count;
+				inputNode.value += key;
+			}
+			inputNode.focus();
+		}
+		dojo.ready(function(){
+			var keyNode = dojo.byId('typematicInput');
+			var mouseNode = dojo.byId('typematicButton');
+			dijit.typematic.addKeyListener(keyNode,
+					{
+						keyCode: dojo.keys.F11,
+						shiftKey: false,
+						metaKey: false,
+						ctrlKey: true // ALT is optional since its unspecified
+					},
+					this, typematicCallBack, 200, 200);
+			dijit.typematic.addMouseListener(mouseNode,
+					this, typematicCallBack, 0.9, 200);
+
+			try{
+				// Focus the input so it's easier for user to start typing.
+				// Doesn't work well in IE6 though, when this test is loaded from robot/typematic.html,
+				// Apparently the robot code sets up a cover <div> over this page and IE doesn't want to focus
+				// the input since it's hidden.
+				keyNode.focus();
+			}catch(e){
+			}
+		});
+	</script>
+</head>
+<body class="claro">
+
+<h2>Dijit typematic tests</h2>
+Press and hold the <b>ctrl+F11</b> keys (ALT optional, but not Shift or Meta) to see a's typed (constant rate) in the
+input field,<br>
+or left-mouse click the button and hold down to see b's typed (increasing rate) in the input field.<br>
+<input id="typematicInput" size="500">
+<button id="typematicButton">to B or not to B</button>
+
+</body>
+</html>
diff --git a/dijit/tests/tree/CustomLabel.html b/dijit/tests/tree/CustomLabel.html
index c669260..e5cd266 100644
--- a/dijit/tests/tree/CustomLabel.html
+++ b/dijit/tests/tree/CustomLabel.html
@@ -1,91 +1,79 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dijit Tree Custom Label Test</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/parser",
+			"dojo/data/ItemFileReadStore",
+			"dijit/Tree",
+			"dijit/tree/ForestStoreModel",
+			"dojo/domReady!"
+		], function(doh, parser){
 
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+			doh.register("Test custom label", [
+				function parse(){
+					return parser.parse();
+				},
+				{
+					name: "testLabels",
+					timeout: 1000,
+					runTest: function(){
+						var d = new doh.Deferred();
 
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+						setTimeout(d.getTestCallback(function(){
+							var nameTree = dijit.byId("nameTree");
+							var nameChildren = nameTree.rootNode.getChildren();
+							doh.is("Arizona", nameChildren[3].label);
+							doh.is("Colorado", nameChildren[9].label);
 
-	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.data.ItemFileReadStore");
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.ForestStoreModel");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		
-		dojo.ready(function(){
-			doh.register("Test custom label",
-				[
-					{
-						name: "testLabels",
-						timeout: 1000,
-						runTest: function(){
-							var d = new doh.Deferred();
+							var codeTree = dijit.byId("codeTree");
+							var codeChildren = codeTree.rootNode.getChildren();
+							doh.is("AZ", codeChildren[3].label);
+							doh.is("CO", codeChildren[9].label);
 
-							setTimeout(d.getTestCallback(function(){
-								var nameTree = dijit.byId("nameTree");
-								var nameChildren = nameTree.rootNode.getChildren();
-								doh.is("Arizona", nameChildren[3].label);
-								doh.is("Colorado", nameChildren[9].label);
-								
-								var codeTree = dijit.byId("codeTree");
-								var codeChildren = codeTree.rootNode.getChildren();
-								doh.is("AZ", codeChildren[3].label);
-								doh.is("CO", codeChildren[9].label);
-								
-								var customTree = dijit.byId("customTree");
-								var customChildren = customTree.rootNode.getChildren();
-								doh.is("Arizona (AZ)", customChildren[3].label);
-								doh.is("Colorado (CO)", customChildren[9].label);
-							}), 500);
-							
-							return d;
-						}
+							var customTree = dijit.byId("customTree");
+							var customChildren = customTree.rootNode.getChildren();
+							doh.is("Arizona (AZ)", customChildren[3].label);
+							doh.is("Colorado (CO)", customChildren[9].label);
+						}), 500);
+
+						return d;
 					}
-				]
-			);
+				}
+			]);
 
 			doh.run();
 		});
-
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Dijit Tree Custom Label Test</h1>
 
-	<div data-dojo-id="store" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"../_data/states.json"'></div>
+	<div data-dojo-id="store" data-dojo-type="dojo/data/ItemFileReadStore" data-dojo-props='url:"../_data/states.json"'></div>
 
 	<h2>Standard label (state names)</h2>
-	<div data-dojo-id="nameModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:store, rootLabel:"States"'></div>
-	<div id="nameTree" data-dojo-type="dijit.Tree" data-dojo-props='model:nameModel, openOnClick:true'></div>
+	<div data-dojo-id="nameModel" data-dojo-type="dijit/tree/ForestStoreModel" data-dojo-props='store:store, rootLabel:"States"'></div>
+	<div id="nameTree" data-dojo-type="dijit/Tree" data-dojo-props='model:nameModel, openOnClick:true'></div>
 
 	<h2>LabelAttr (state abbreviation)</h2>
-	<div data-dojo-id="codeModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:store, rootLabel:"States", labelAttr:"abbreviation"'></div>
-	<div id="codeTree" data-dojo-type="dijit.Tree" data-dojo-props='model:codeModel, openOnClick:true'></div>
+	<div data-dojo-id="codeModel" data-dojo-type="dijit/tree/ForestStoreModel" data-dojo-props='store:store, rootLabel:"States", labelAttr:"abbreviation"'></div>
+	<div id="codeTree" data-dojo-type="dijit/Tree" data-dojo-props='model:codeModel, openOnClick:true'></div>
 
 	<h2>Custom label via callback</h2>
-	<div data-dojo-id="customModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:store'>
+	<div data-dojo-id="customModel" data-dojo-type="dijit/tree/ForestStoreModel" data-dojo-props='store:store'>
 		<script type="dojo/method" data-dojo-event="getLabel" data-dojo-args="item">
 			if(item.root){ return "States"; }
 			return (store.getLabel(item) + " (" + store.getIdentity(item) + ")");
 		</script>
 	</div>
-	<div id="customTree" data-dojo-type="dijit.Tree" data-dojo-props='model:customModel, openOnClick:true'></div>
+	<div id="customTree" data-dojo-type="dijit/Tree" data-dojo-props='model:customModel, openOnClick:true'></div>
 
 
 </body>
diff --git a/dijit/tests/tree/Tree.html b/dijit/tests/tree/Tree.html
deleted file mode 100644
index 410f282..0000000
--- a/dijit/tests/tree/Tree.html
+++ /dev/null
@@ -1,396 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>dijit.Tree Automatic Tests</title>
-
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../../../dojo/resources/dnd.css";
-		@import "../../../dojo/tests/dnd/dndDefault.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<script type="text/javascript" src="../helpers.js"></script>
-
-	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojo.parser");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.data.ItemFileWriteStore");
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.ForestStoreModel");
-		dojo.require("dijit.tree.TreeStoreModel");
-		dojo.require("dijit.tree.dndSource");
-		
-		function getRowClass(item, isExpanded){
-			if(!item
-					|| !treeStore.isItem(item)
-					|| treeStore.getValue(item, "type") != "header"){
-				return null;
-			}
-			return "headerRow";
-		}
-
-		dojo.ready(function(){
-			doh.register("parse", function(){
-				dojo.parser.parse();
-			});
-
-			doh.register("paths", [
-				function create(){
-					var d = new doh.Deferred();
-					myStore = new dojo.data.ItemFileWriteStore({url:'../_data/countries.json'});
-					doh.t(myStore, "store created");
-
-					myModel = new dijit.tree.ForestStoreModel({
-						store: myStore,
-						query: {type:'continent'},
-						rootId: "earth",
-						rootLabel: "Earth",
-						childrenAttrs: ["children"]
-					});
-					doh.t(myModel, "model created");
-
-					myTree = new dijit.Tree({
-						id: "myTree",
-						model: myModel,
-						persist: false,		// persist==true is too hard to test
-						dndController: "dijit.tree.dndSource"
-					});
-					doh.t(myTree, "tree created");
-
-					dojo.byId("container").appendChild(myTree.domNode);
-					myTree.startup();
-
-					setTimeout(d.getTestCallback(function(){
-						// Give the tree time to load, and the do checks that it
-						// loaded correctly
-						doh.t(myTree.rootNode, "root node exists");
-						doh.t(myTree.rootNode.isExpanded, "root node is expanded");
-
-						var children = myTree.rootNode.getChildren();
-						doh.is(6, children.length, "six children");
-						doh.is("Africa", children[0].label, "first child");
-						doh.f(children[0].isExpanded, "first child not expanded");
-						doh.is("South America", children[5].label, "last child");
-
-						// Last child has special CSS for drawing the grid lines
-						doh.f(dojo.hasClass(children[3].domNode, "dijitTreeIsLast"), "middle node doesn't have dijitTreeIsLast");
-						doh.t(dojo.hasClass(children[5].domNode, "dijitTreeIsLast"), "last node has dijitTreeIsLast");
-					}), 750);
-					return d;
-				},
-
-				{
-					name: "createWithPath",
-					timeout: 5000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						myTree2 = new dijit.Tree({
-							id: "myTree2",
-							model: myModel,
-							persist: false,		// persist==true is too hard to test
-							dndController: "dijit.tree.dndSource",
-							path: ["earth", "EU", "IT"]
-						});
-						doh.t(myTree2, "myTree2 created");
-
-						dojo.byId("container2").appendChild(myTree2.domNode);
-						myTree2.startup();
-
-						setTimeout(d.getTestCallback(function(){
-							doh.t(myTree2.rootNode, "root node exists");
-							doh.t(myTree2.rootNode.isExpanded, "root node is expanded");
-							doh.t(myTree2.rootNode.getChildren()[3].isExpanded, "europe node is expanded");
-							doh.is(myTree2.rootNode.getChildren()[3].getChildren()[3], myTree2.selectedNode, "selected correct node");
-						}), 2000);
-
-						return d;
-					}
-				},
-				function copyPath(){
-					var d = new doh.Deferred();
-
-					myTree.set("path", myTree2.get("path")).then(d.getTestCallback(function(){
-						doh.t(myTree.rootNode.isExpanded, "root node is expanded");
-						doh.t(myTree.rootNode.getChildren()[3].isExpanded, "europe node is expanded");
-						doh.is(myTree.rootNode.getChildren()[3].getChildren()[3], myTree.get("selectedNode"), "selected correct node");
-					}));
-
-					return d;
-				},
-
-				{
-					name: "copyPathByIds",
-					timeout: 5000,
-					runTest: function(){
-						var d = new doh.Deferred();
-
-						myTree.set("path", ["earth", "NA", "CA", "Ottawa"]).then(d.getTestErrback(function(){
-							var path = dojo.map(myTree.get("path"), function(item){ return myTree.model.getIdentity(item); });
-							doh.is(["earth", "NA", "CA", "Ottawa"], path, "path got set on myTree");
-
-							myTree2.set("path", path).then(d.getTestCallback(function(){
-								doh.t(myTree2.rootNode.isExpanded, "root node is expanded");
-								doh.t(myTree2.rootNode.getChildren()[4].isExpanded, "north america node is expanded");
-								doh.t(myTree2.rootNode.getChildren()[4].getChildren()[1].isExpanded, "canada node is expanded");
-								doh.is(myTree2.rootNode.getChildren()[4].getChildren()[1].getChildren()[0], myTree2.get("selectedNode"), "selected correct node");
-							}));
-						}));
-
-						return d;
-					}
-				},
-
-				function setPathToNull(){
-					var d = new doh.Deferred();
-
-					myTree2.set("path", []).addCallback(d.getTestCallback(function(){
-						doh.is(null, myTree2.get("selectedNode"), "no selected node");
-					}));
-					return d;
-				},
-
-				function setPathToRoot(){
-					var d = new doh.Deferred();
-
-					myTree2.set("path", ["earth"]).addCallback(d.getTestCallback(function(){
-						doh.is(myTree2.rootNode, myTree2.get("selectedNode"), "selected root node");
-					}));
-					return d;
-				},
-
-				function setPaths(){
-					var d = new doh.Deferred();
-
-					myTree2.set("paths", [["earth","AF","KE","Nairobi"],
-										  ["earth","NA","MX","Guadalajara"]]).addCallback(d.getTestCallback(function(){
-							  var ids = dojo.map(myTree2.selectedItems, function(x){return myTree2.model.getIdentity(x);}).sort();
-							  doh.is(["Guadalajara", "Nairobi"], ids);
-						  }));
-					return d;
-				}
-			]);
-
-			doh.register("data store", [
-				function itemUpdate(){
-					// Test that Tree noticed when data store items change, and updates accordingly
-
-					var item = myTree.rootNode.getChildren()[3].item;
-					myStore.setValue(item, "name", "EU");
-
-					doh.is("EU", innerText(myTree.rootNode.getChildren()[3].labelNode), "label changed");
-				},
-
-				function topLevelItemDelete(){
-					// Delete a top level item.   ForestStoreModel needs to realize that the top level
-					// children have changed and notify Tree
-
-					// Remove "South America"
-					var item = myTree.rootNode.getChildren()[5].item;
-					myStore.deleteItem(item);
-
-					var children = myTree.rootNode.getChildren();
-					doh.is(5, children.length, "five children");
-					doh.is("North America", children[4].label, "last child");
-					doh.t(dojo.hasClass(children[4].domNode, "dijitTreeIsLast"),
-							"North america has become the last node so it gets the CSS class for that");
-				},
-
-				function openANode(){
-					var d = new doh.Deferred();
-
-					var asia = myTree.rootNode.getChildren()[1];
-
-					doh.is(0, asia.getChildren().length, "no children loaded yet");
-
-					myTree._onExpandoClick({node: asia});
-
-					setTimeout(d.getTestCallback(function(){
-						// Give the tree time to load the children, and the do checks that it
-						// loaded correctly
-
-						var children = asia.getChildren();
-						doh.is(4, children.length, "four children");
-						doh.is("China", children[0].label, "first child");
-						doh.is("Mongolia", children[3].label, "last child");
-					}), 750);
-					return d;
-				},
-
-				function selectAnItem(){
-					myTree.set('selectedItem','CN');
-					doh.is('CN',myTree.model.getIdentity(myTree.get('selectedItem')));
-				},
-
-				function nestedItemDelete(){
-					// Delete a nested item
-
-					// Remove "China"
-					var asia = myTree.rootNode.getChildren()[1],
-						china = asia.getChildren()[0];
-					myStore.deleteItem(china.item);
-
-					var children = asia.getChildren();
-					doh.is(3, children.length, "three children");
-				},
-
-				function topLevelItemInsert(){
-					// Create a new top level item as last child.
-					// ForestStoreModel needs to realize that the top level children have changed and notify Tree.
-
-					myStore.newItem({
-						id: 'PA',
-						name:'Pacifica',
-						type:'continent',
-						children: []
-					});
-
-					var children = myTree.rootNode.getChildren();
-					doh.is(6, children.length, "six children");
-					doh.is("Pacifica", children[5].label, "last child");
-					doh.f(dojo.hasClass(children[4].domNode, "dijitTreeIsLast"),
-						"North America no longer last child");
-					doh.t(dojo.hasClass(children[5].domNode, "dijitTreeIsLast"),
-						"Pacifica is last child");
-				},
-
-				function topLevelItemModify(){
-					// Modify a top level item so it's no longer top level.
-					// ForestStoreModel needs to realize that the top level children have changed and notify Tree.
-
-					myStore.fetchItemByIdentity({
-						identity: 'PA',
-						onItem: function(item){
-							// in real life we would need to give the item a parent,
-							// but this is enough for testing
-							myStore.setValue(item, 'type', 'country');
-						}
-					});
-
-					var children = myTree.rootNode.getChildren();
-					doh.is(5, children.length, "five children again");
-				},
-
-				function nestedItemModify(){
-					// Modify a nested item so it matches the query for top level items in the tree.
-					// ForestStoreModel needs to realize that the top level children have changed and notify Tree.
-
-					myStore.fetchItemByIdentity({
-						identity: 'PA',
-						onItem: function(item){
-							// in real life we would need to give the item a parent,
-							// but this is enough for testing
-							myStore.setValue(item, 'type', 'continent');
-						}
-					});
-
-					var children = myTree.rootNode.getChildren();
-					doh.is(6, children.length, "six children again");
-				},
-
-				function destroyTree(){
-					// Just running this to make sure we don't get an exception
-					console.log("destroying tree");
-					myTree.destroy();
-					myTree2.destroy();
-				}
-			]);
-
-			doh.register("delete selected node", [
-				function create(){
-					var d = new doh.Deferred();
-
-					myTree = new dijit.Tree({
-						id: "myTree",
-						model: myModel,
-						persist: false,		// persist==true is too hard to test
-						path: ["earth", "EU", "IT"]
-					});
-					doh.t(myTree, "tree created");
-
-					dojo.byId("container").appendChild(myTree.domNode);
-					myTree.startup();
-
-					setTimeout(d.getTestCallback(function(){
-						doh.is("IT", myTree.get("selectedItem").id);
-					}), 500);
-					return d;
-				},
-
-				function deleteSelectedItem(){
-					myStore.deleteItem(myTree.get("selectedItem"));
-				},
-
-				function selectNewItem(){
-					myTree.set("path", ["earth", "EU", "FR"]);
-					doh.is("FR", myTree.get("selectedItem").id);
-				}
-			]);
-
-			doh.register("nobidi", [
-				// Make sure that Tree doesn't have spurious lang="" dir="" on nodes
-				function noLangDir(){
-					var d = new doh.Deferred();
-					myStore = new dojo.data.ItemFileWriteStore({url:'../_data/countries.json'});
-					doh.t(myStore, "store created");
-
-					myModel = new dijit.tree.ForestStoreModel({
-						store: myStore,
-						query: {type:'continent'},
-						rootId: "earth",
-						rootLabel: "Earth",
-						childrenAttrs: ["children"]
-					});
-					doh.t(myModel, "model created");
-
-					myTree = new dijit.Tree({
-						id: "noDirTree",
-						model: myModel,
-						persist: false,		// persist==true is too hard to test
-						dndController: "dijit.tree.dndSource"
-					});
-					doh.t(myTree, "tree created");
-
-					dojo.byId("container").appendChild(myTree.domNode);
-					myTree.startup();
-
-					setTimeout(d.getTestCallback(function(){
-						// Give the tree time to load, and the do checks that it
-						// loaded correctly
-						doh.t(myTree.rootNode, "root node exists");
-						doh.t(myTree.rootNode.isExpanded, "root node is expanded");
-						doh.f(dojo.hasAttr(myTree.rootNode, "lang"), "no (empty) lang attribute on root TreeNode");
-						doh.f(dojo.hasAttr(myTree.rootNode, "dir"), "no (empty) dir attribute on root TreeNode");
-
-						var children = myTree.rootNode.getChildren();
-						doh.f(dojo.hasAttr(children[2], "lang"), "no (empty) lang attribute on child TreeNode");
-						doh.f(dojo.hasAttr(children[2], "dir"), "no (empty) dir attribute on child TreeNode");
-					}), 750);
-					return d;
-				}
-			]);
-
-			doh.run();
-		});
-	</script>
-
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit.Tree automated tests</h1>
-	<div id="container"> <!--  tree will go here --></div>
-	<div id="container2"> <!--  tree2 will go here --></div>
-</body>
-</html>
diff --git a/dijit/tests/tree/Tree_ForestStoreModel.html b/dijit/tests/tree/Tree_ForestStoreModel.html
new file mode 100644
index 0000000..770ec11
--- /dev/null
+++ b/dijit/tests/tree/Tree_ForestStoreModel.html
@@ -0,0 +1,386 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+
+<!--
+	Test file for Tree against ForestStoreModel.
+	To be removed in 2.0 in favor of Tree_ObjectStoreModel.html
+	Put new tests in Tree_ObjectStoreModel.html
+--->
+
+<html lang="en">
+<head>
+	<title>dijit.Tree against dijit.tree.ForestStoreModel Automated Tests</title>
+
+	<style type="text/css">
+		@import "../../../dojo/resources/dnd.css";
+		@import "../../../dojo/tests/dnd/dndDefault.css";
+	</style>
+
+	<script type="text/javascript" src="../boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/data/ItemFileWriteStore",
+			"dojo/dom",
+			"dojo/dom-attr",
+			"dojo/dom-class",
+			"dijit/Tree",
+			"dijit/tree/ForestStoreModel",
+			"dijit/tree/TreeStoreModel",
+			"dijit/tree/dndSource",
+			"dijit/tests/helpers",
+			"dojo/domReady!"
+		], function(doh, ItemFileWriteStore, dom, domAttr, domClass, Tree, ForestStoreModel, TreeStoreModel, dndSource, helpers){
+
+			doh.register("setup", function(){
+				myStore = new ItemFileWriteStore({url:'../_data/countries.json'});
+				doh.t(myStore, "store created");
+
+				myModel = new ForestStoreModel({
+					store: myStore,
+					query: {type:'continent'},
+					rootId: "earth",
+					rootLabel: "Earth",
+					childrenAttrs: ["children"]
+				});
+				doh.t(myModel, "model created");
+			});
+			doh.register("paths", [
+				function create(){
+					var d = new doh.Deferred();
+
+					myTree = new Tree({
+						id: "myTree",
+						model: myModel,
+						persist: false,		// persist==true is too hard to test
+						dndController: dndSource
+					});
+					doh.t(myTree, "tree created");
+
+					dom.byId("container").appendChild(myTree.domNode);
+					myTree.startup();
+
+					myTree.onLoadDeferred.then(d.getTestCallback(function(){
+						// Give the tree time to load, and the do checks that it
+						// loaded correctly
+						doh.t(myTree.rootNode, "root node exists");
+						doh.t(myTree.rootNode.isExpanded, "root node is expanded");
+
+						var children = myTree.rootNode.getChildren();
+						doh.is(6, children.length, "six children");
+						doh.is("Africa", children[0].label, "first child");
+						doh.f(children[0].isExpanded, "first child not expanded");
+						doh.is("South America", children[5].label, "last child");
+
+						// Last child has special CSS for drawing the grid lines
+						doh.f(domClass.contains(children[3].domNode, "dijitTreeIsLast"), "middle node doesn't have dijitTreeIsLast");
+						doh.t(domClass.contains(children[5].domNode, "dijitTreeIsLast"), "last node has dijitTreeIsLast");
+					}));
+					return d;
+				},
+
+				{
+					name: "createWithPath",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						myTree2 = new Tree({
+							id: "myTree2",
+							model: myModel,
+							persist: false,		// persist==true is too hard to test
+							dndController: dndSource,
+							path: ["earth", "EU", "IT"]
+						});
+						doh.t(myTree2, "myTree2 created");
+
+						dom.byId("container2").appendChild(myTree2.domNode);
+						myTree2.startup();
+
+						myTree2.onLoadDeferred.then(d.getTestCallback(function(){
+							doh.t(myTree2.rootNode, "root node exists");
+							doh.t(myTree2.rootNode.isExpanded, "root node is expanded");
+							doh.t(myTree2.rootNode.getChildren()[3].isExpanded, "europe node is expanded");
+							doh.is(myTree2.rootNode.getChildren()[3].getChildren()[3], myTree2.selectedNode, "selected correct node");
+						}));
+
+						return d;
+					}
+				},
+				function copyPath(){
+					var d = new doh.Deferred();
+
+					myTree.set("path", myTree2.get("path")).then(d.getTestCallback(function(){
+						doh.t(myTree.rootNode.isExpanded, "root node is expanded");
+						doh.t(myTree.rootNode.getChildren()[3].isExpanded, "europe node is expanded");
+						doh.is(myTree.rootNode.getChildren()[3].getChildren()[3], myTree.get("selectedNode"), "selected correct node");
+					}));
+
+					return d;
+				},
+
+				{
+					name: "copyPathByIds",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						myTree.set("path", ["earth", "NA", "CA", "Ottawa"]).then(d.getTestErrback(function(){
+							var path = dojo.map(myTree.get("path"), function(item){ return myTree.model.getIdentity(item); });
+							doh.is(["earth", "NA", "CA", "Ottawa"], path, "path got set on myTree");
+
+							myTree2.set("path", path).then(d.getTestCallback(function(){
+								doh.t(myTree2.rootNode.isExpanded, "root node is expanded");
+								doh.t(myTree2.rootNode.getChildren()[4].isExpanded, "north america node is expanded");
+								doh.t(myTree2.rootNode.getChildren()[4].getChildren()[1].isExpanded, "canada node is expanded");
+								doh.is(myTree2.rootNode.getChildren()[4].getChildren()[1].getChildren()[0], myTree2.get("selectedNode"), "selected correct node");
+							}));
+						}));
+
+						return d;
+					}
+				},
+
+				function setPathToNull(){
+					var d = new doh.Deferred();
+
+					myTree2.set("path", []).then(d.getTestCallback(function(){
+						doh.is(null, myTree2.get("selectedNode"), "no selected node");
+					}));
+					return d;
+				},
+
+				function setPathToRoot(){
+					var d = new doh.Deferred();
+
+					myTree2.set("path", ["earth"]).then(d.getTestCallback(function(){
+						doh.is(myTree2.rootNode, myTree2.get("selectedNode"), "selected root node");
+					}));
+					return d;
+				},
+
+				function setPaths(){
+					var d = new doh.Deferred();
+
+					myTree2.set("paths", [["earth","AF","KE","Nairobi"],
+										  ["earth","NA","MX","Guadalajara"]]).then(d.getTestCallback(function(){
+						var ids = dojo.map(myTree2.selectedItems, function(x){return myTree2.model.getIdentity(x);}).sort();
+						doh.is(["Guadalajara", "Nairobi"], ids);
+				  	}));
+					return d;
+				}
+			]);
+
+			doh.register("data store", [
+				function itemUpdate(){
+					// Test that Tree noticed when data store items change, and updates accordingly
+
+					var item = myTree.rootNode.getChildren()[3].item;
+					myStore.setValue(item, "name", "EU");
+
+					doh.is("EU", helpers.innerText(myTree.rootNode.getChildren()[3].labelNode), "label changed");
+				},
+
+				function topLevelItemDelete(){
+					// Delete a top level item.   ForestStoreModel needs to realize that the top level
+					// children have changed and notify Tree
+
+					// Remove "South America"
+					var item = myTree.rootNode.getChildren()[5].item;
+					myStore.deleteItem(item);
+
+					var children = myTree.rootNode.getChildren();
+					doh.is(5, children.length, "five children");
+					doh.is("North America", children[4].label, "last child");
+					doh.t(domClass.contains(children[4].domNode, "dijitTreeIsLast"),
+							"North america has become the last node so it gets the CSS class for that");
+				},
+
+				function openANode(){
+					var d = new doh.Deferred();
+
+					var asia = myTree.rootNode.getChildren()[1];
+
+					doh.is(0, asia.getChildren().length, "no children loaded yet");
+
+					myTree._onExpandoClick({node: asia});
+
+					setTimeout(d.getTestCallback(function(){
+						// Give the tree time to load the children, and the do checks that it
+						// loaded correctly
+
+						var children = asia.getChildren();
+						doh.is(4, children.length, "four children");
+						doh.is("China", children[0].label, "first child");
+						doh.is("Mongolia", children[3].label, "last child");
+					}), 750);
+					return d;
+				},
+
+				function selectAnItem(){
+					myTree.set('selectedItem','CN');
+					doh.is('CN',myTree.model.getIdentity(myTree.get('selectedItem')));
+				},
+
+				function nestedItemDelete(){
+					// Delete a nested item
+
+					// Remove "China"
+					var asia = myTree.rootNode.getChildren()[1],
+						china = asia.getChildren()[0];
+					myStore.deleteItem(china.item);
+
+					var children = asia.getChildren();
+					doh.is(3, children.length, "three children");
+				},
+
+				function topLevelItemInsert(){
+					// Create a new top level item as last child.
+					// ForestStoreModel needs to realize that the top level children have changed and notify Tree.
+
+					myStore.newItem({
+						id: 'PA',
+						name:'Pacifica',
+						type:'continent',
+						children: []
+					});
+
+					var children = myTree.rootNode.getChildren();
+					doh.is(6, children.length, "six children");
+					doh.is("Pacifica", children[5].label, "last child");
+					doh.f(domClass.contains(children[4].domNode, "dijitTreeIsLast"),
+						"North America no longer last child");
+					doh.t(domClass.contains(children[5].domNode, "dijitTreeIsLast"),
+						"Pacifica is last child");
+				},
+
+				function topLevelItemModify(){
+					// Modify a top level item so it's no longer top level.
+					// ForestStoreModel needs to realize that the top level children have changed and notify Tree.
+
+					myStore.fetchItemByIdentity({
+						identity: 'PA',
+						onItem: function(item){
+							// in real life we would need to give the item a parent,
+							// but this is enough for testing
+							myStore.setValue(item, 'type', 'country');
+						}
+					});
+
+					var children = myTree.rootNode.getChildren();
+					doh.is(5, children.length, "five children again");
+				},
+
+				function nestedItemModify(){
+					// Modify a nested item so it matches the query for top level items in the tree.
+					// ForestStoreModel needs to realize that the top level children have changed and notify Tree.
+
+					myStore.fetchItemByIdentity({
+						identity: 'PA',
+						onItem: function(item){
+							// in real life we would need to give the item a parent,
+							// but this is enough for testing
+							myStore.setValue(item, 'type', 'continent');
+						}
+					});
+
+					var children = myTree.rootNode.getChildren();
+					doh.is(6, children.length, "six children again");
+				},
+
+				function destroyTree(){
+					// Just running this to make sure we don't get an exception
+					console.log("destroying tree");
+					myTree.destroy();
+					myTree2.destroy();
+				}
+			]);
+
+			doh.register("delete selected node", [
+				function create(){
+					var d = new doh.Deferred();
+
+					myTree = new Tree({
+						id: "myTree",
+						model: myModel,
+						persist: false,		// persist==true is too hard to test
+						path: ["earth", "EU", "IT"]
+					});
+					doh.t(myTree, "tree created");
+
+					dom.byId("container").appendChild(myTree.domNode);
+					myTree.startup();
+
+					myTree.onLoadDeferred.then(d.getTestCallback(function(){
+						var item = myTree.get("selectedItem");
+						doh.is("IT", myStore.getValue(item, "id"));
+					}));
+					return d;
+				},
+
+				function deleteSelectedItem(){
+					myStore.deleteItem(myTree.get("selectedItem"));
+				},
+
+				function selectNewItem(){
+					myTree.set("path", ["earth", "EU", "FR"]);
+					var item = myTree.get("selectedItem");
+					doh.is("FR", myStore.getValue(item, "id"));
+				}
+			]);
+
+			doh.register("nobidi", [
+				// Make sure that Tree doesn't have spurious lang="" dir="" on nodes
+				function noLangDir(){
+					var d = new doh.Deferred();
+					myStore = new dojo.data.ItemFileWriteStore({url:'../_data/countries.json'});
+					doh.t(myStore, "store created");
+
+					myModel = new ForestStoreModel({
+						store: myStore,
+						query: {type:'continent'},
+						rootId: "earth",
+						rootLabel: "Earth",
+						childrenAttrs: ["children"]
+					});
+					doh.t(myModel, "model created");
+
+					myTree = new Tree({
+						id: "noDirTree",
+						model: myModel,
+						persist: false,		// persist==true is too hard to test
+						dndController: dndSource
+					});
+					doh.t(myTree, "tree created");
+
+					dom.byId("container").appendChild(myTree.domNode);
+					myTree.startup();
+
+					myTree.onLoadDeferred.then(d.getTestCallback(function(){
+						// Give the tree time to load, and the do checks that it
+						// loaded correctly
+						doh.t(myTree.rootNode, "root node exists");
+						doh.t(myTree.rootNode.isExpanded, "root node is expanded");
+						doh.f(domAttr.has(myTree.rootNode, "lang"), "no (empty) lang attribute on root TreeNode");
+						doh.f(domAttr.has(myTree.rootNode, "dir"), "no (empty) dir attribute on root TreeNode");
+
+						var children = myTree.rootNode.getChildren();
+						doh.f(domAttr.has(children[2], "lang"), "no (empty) lang attribute on child TreeNode");
+						doh.f(domAttr.has(children[2], "dir"), "no (empty) dir attribute on child TreeNode");
+					}));
+					return d;
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+
+</head>
+<body class="claro" role="main">
+
+	<h1 class="testTitle">Dijit.Tree / dijit.tree.ForestStoreModel Automated Tests</h1>
+	<div id="container"> <!--  tree will go here --></div>
+	<div id="container2"> <!--  tree2 will go here --></div>
+</body>
+</html>
diff --git a/dijit/tests/tree/Tree_ObjectStoreModel.html b/dijit/tests/tree/Tree_ObjectStoreModel.html
new file mode 100644
index 0000000..548c22c
--- /dev/null
+++ b/dijit/tests/tree/Tree_ObjectStoreModel.html
@@ -0,0 +1,972 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>dijit.Tree / dijit.tree.ObjectStoreModel automated test</title>
+
+	<script type="text/javascript" src="../boilerplate.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/_base/array",
+			"dojo/aspect",
+			"dojo/cookie",
+			"dojo/dom-class",
+			"dojo/_base/lang",
+			"dojo/on",
+			"dojo/_base/window",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"dijit/Tree",
+			"dijit/tree/ObjectStoreModel",
+			"dijit/tree/dndSource",
+			"dijit/tests/_data/geography",
+			"dijit/tests/helpers",	// functions to help test
+			"dojo/domReady!"
+		], function(doh, array, aspect, cookie, domClass, lang, on, win, Memory, Observable,
+					registry, Tree, ObjectStoreModel, dndSource, data, helpers){
+
+			var myStore, myModel, myTree, myTree2;
+
+			// TreeNodes
+			var world, europe, asia, africa, kenya;
+
+			// Function to create / reset the data store and model
+			function setup(){
+				// Create test store.
+				myStore = new Memory({
+					data: data
+				});
+
+				// Since dojo.store.Memory doesn't have various store methods we need, we have to add them manually
+				myStore.getChildren = function(object){
+					// Add a getChildren() method to store for the data model where
+					// children objects point to their parent (aka relational model)
+					return this.query({parent: this.getIdentity(object)});
+				};
+
+				aspect.around(myStore, "put", function(originalPut){
+					// To support DnD, the store must support put(child, {parent: parent}).
+					// Since our store is relational, that just amounts to setting child.parent
+					// to the parent"s id.
+					return function(obj, options){
+						if(options && options.parent){
+							obj.parent = options.parent.id;
+						}
+						return originalPut.call(myStore, obj, options);
+					}
+				});
+
+				// Wrap the store in Observable so that updates to the store are reflected
+				myStore = new Observable(myStore);
+				doh.t(myStore, "store created");
+
+				// Create the model
+				myModel = new ObjectStoreModel({store: myStore, query: {id: "earth"}});
+				doh.t(myModel, "model created");
+			}
+
+			doh.register("setup", setup);
+
+			doh.register("basic", [
+				{
+					name: "create",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						myTree = new Tree({
+							id: "myTree",
+							model: myModel,
+							persist: false,		// persist==true is too hard to test
+							dndController: dndSource
+						}).placeAt(win.body());
+						doh.t(myTree, "tree created");
+
+						myTree.startup();
+
+						world = myTree.rootNode;
+
+						// Give the tree time to load, and the do checks that it
+						// loaded correctly
+						setTimeout(d.getTestCallback(function(){
+							doh.t(world, "root node exists");
+							doh.is("The earth", world.label, "world node label");
+							doh.t(world.isExpanded, "root node is expanded");
+
+							var children = world.getChildren();
+							doh.is(6, children.length, "six children");
+							doh.is("Africa", children[0].label, "first child");
+							doh.f(children[0].isExpanded, "first child not expanded");
+							doh.is("South America", children[5].label, "last child");
+
+							// Last child has special CSS for drawing the grid lines
+							doh.f(domClass.contains(children[3].domNode, "dijitTreeIsLast"), "middle node doesn't have dijitTreeIsLast");
+							doh.t(domClass.contains(children[5].domNode, "dijitTreeIsLast"), "last node has dijitTreeIsLast");
+						}), 750);
+						return d;
+					}
+				},
+
+				function openEurope(){
+					var d = new doh.Deferred();
+
+					europe = world.getChildren()[3];
+					doh.is("Europe", europe.label, "europe node label");
+					doh.t(europe, "europe node exists");
+
+					// Click on Europe to open it
+					on.emit(europe.expandoNode, "click", {bubbles: true});
+
+					// Give the children time to load, and the do checks that they
+					// loaded correctly
+					setTimeout(d.getTestCallback(function(){
+						doh.t(europe.isExpanded, "europe node is expanded");
+
+						var children = europe.getChildren();
+						doh.is(4, children.length, "children count");
+						doh.is("Germany", children[0].label, "first child");
+						doh.f(children[0].isExpanded, "first child not expanded");
+						doh.is("Italy", children[3].label, "last child");
+
+						// Last child has special CSS for drawing the grid lines
+						doh.f(domClass.contains(children[1].domNode, "dijitTreeIsLast"), "middle node doesn't have dijitTreeIsLast");
+						doh.t(domClass.contains(children[3].domNode, "dijitTreeIsLast"), "last node has dijitTreeIsLast");
+					}), 750);
+					return d;
+				},
+
+				function openAsia(){
+					var d = new doh.Deferred();
+
+					asia = world.getChildren()[1];
+					doh.is("Asia", asia.label, "asia node label");
+					doh.t(asia, "europe node exists");
+
+					// Click on Europe to open it
+					on.emit(asia.expandoNode, "click", {bubbles: true});
+
+					// Give the children time to load, and the do checks that they
+					// loaded correctly
+					setTimeout(d.getTestCallback(function(){
+						doh.t(asia.isExpanded, "asia node is expanded");
+
+						var children = asia.getChildren();
+						doh.is(4, children.length, "children count");
+						doh.is("China", children[0].label, "first child");
+						doh.is("Mongolia", children[3].label, "last child");
+					}), 750);
+					return d;
+				}
+			]);
+
+			doh.register("data store binding", [
+				function itemUpdate(){
+					// Test that Tree noticed when data store items change, and updates accordingly
+
+					myStore.put({ id: "ES", name:"España", type:"country", parent: "EU" });
+					doh.is("España", innerText(europe.getChildren()[2].labelNode), "label changed");
+				},
+
+				function topLevelItemDelete(){
+					// Delete a top level item.
+
+					// Remove "South America"
+					myStore.remove("SA");
+
+					var children = world.getChildren();
+					doh.is(5, children.length, "five children");
+					doh.is("North America", children[4].label, "last child");
+					doh.t(domClass.contains(children[4].domNode, "dijitTreeIsLast"),
+							"North america has become the last node so it gets the CSS class for that");
+				},
+
+				function nestedItemDelete(){
+					// Delete a nested item
+
+					// Remove "China"
+					myStore.remove("CN");
+
+					var children = asia.getChildren();
+					doh.is(3, children.length, "three children");
+				},
+
+				function topLevelItemInsert(){
+					// Create a new top level item as last child.
+					// ForestStoreModel needs to realize that the top level children have changed and notify Tree.
+
+					myStore.add({
+						id: "PA",
+						name:"Pacifica",
+						type:"continent",
+						parent: "earth"
+					});
+
+					var children = world.getChildren();
+					doh.is(6, children.length, "six children");
+					doh.is("Pacifica", children[5].label, "last child");
+					doh.f(domClass.contains(children[4].domNode, "dijitTreeIsLast"),
+						"North America no longer last child");
+					doh.t(domClass.contains(children[5].domNode, "dijitTreeIsLast"),
+						"Pacifica is last child");
+				},
+
+				function topLevelItemModify(){
+					// Modify a top level item so it's no longer top level.
+
+					myStore.put({
+						id: "PA",
+						name:"Pacifica",
+						type:"continent",
+						parent: "AS"
+					});
+
+					doh.is(5, world.getChildren().length, "world children");
+					doh.is(4, asia.getChildren().length, "asia children");
+				},
+
+				function nestedItemModify(){
+					// Modify a nested item so it matches the query for top level items in the tree.
+
+					myStore.put({
+						id: "PA",
+						name:"Pacifica",
+						type:"continent",
+						parent: "earth"
+					});
+
+					doh.is(6, world.getChildren().length, "world children");
+					doh.is(3, asia.getChildren().length, "asia children");
+				}
+			]);
+
+			doh.register("DnD", [
+				// Drag Germany from Europe to Asia
+				function dragGermanyToAsia(){
+					var asiaItem = myStore.get("AS"),
+						europeItem = myStore.get("EU"),
+						germanyItem = myStore.get("DE");
+					myModel.pasteItem(germanyItem, europeItem, asiaItem);
+					doh.is(3, europe.getChildren().length, "europe children");
+					doh.is(4, asia.getChildren().length, "asia children");
+					doh.is("Germany", asia.getChildren()[3].label, "last child of asia");
+				},
+
+				// Drag Germany from Asia to Europe
+				function dragGermanyToEurope(){
+					var asiaItem = myStore.get("AS"),
+						europeItem = myStore.get("EU"),
+						germanyItem = myStore.get("DE");
+					myModel.pasteItem(germanyItem, asiaItem, europeItem);
+					doh.is(3, asia.getChildren().length, "asia children");
+					doh.is(4, europe.getChildren().length, "europe children");
+					doh.is("Germany", europe.getChildren()[3].label, "last child of europe");
+				},
+
+				function openAfrica(){
+					var d = new doh.Deferred();
+
+					africa = world.getChildren()[0];
+					doh.is("Africa", africa.label, "africa node label");
+					doh.t(africa, "africa node exists");
+
+					// Click on Africa to open it
+					on.emit(africa.expandoNode, "click", {bubbles: true});
+
+					// Give the children time to load, and the do checks that they
+					// loaded correctly
+					setTimeout(d.getTestCallback(function(){
+						doh.t(africa.isExpanded, "node is expanded");
+
+						var children = africa.getChildren();
+						doh.is(3, children.length, "children count");
+					}), 750);
+					return d;
+				},
+
+				function openKenya(){
+					var d = new doh.Deferred();
+
+					kenya = africa.getChildren()[1];
+					doh.t(kenya, "kenya node exists");
+					doh.is("Kenya", kenya.label, "kenya node label");
+
+					// Click on Kenya to open it
+					on.emit(kenya.expandoNode, "click", {bubbles: true});
+
+					// Give the children time to load, and the do checks that they
+					// loaded correctly
+					setTimeout(d.getTestCallback(function(){
+						doh.t(kenya.isExpanded, "node is expanded");
+
+						var children = kenya.getChildren();
+						doh.is(2, children.length, "children count");
+					}), 750);
+					return d;
+				},
+
+				// Dragging open node to make sure it stays open.
+				function dragKenyaToAsia(){
+					var asiaItem = myStore.get("AS"),
+						africaItem = myStore.get("AF"),
+						kenyaItem = myStore.get("KE");
+					myModel.pasteItem(kenyaItem, africaItem, asiaItem);
+					doh.is(4, asia.getChildren().length, "asia children");
+					doh.is("Kenya", asia.getChildren()[3].label, "last child of asia");
+					doh.is(kenya, asia.getChildren()[3], "same TreeNode as before");
+					doh.t(kenya.isExpanded, "node is still expanded");
+					doh.is(2, kenya.getChildren().length, "same children count as before");
+				},
+
+				// Put Kenya back in Africa
+				function dragKenyaToAfrica(){
+					var asiaItem = myStore.get("AS"),
+						africaItem = myStore.get("AF"),
+						kenyaItem = myStore.get("KE");
+					myModel.pasteItem(kenyaItem, asiaItem, africaItem);
+					doh.is(3, asia.getChildren().length, "asia children");
+					doh.is(3, africa.getChildren().length, "africa children");
+				}
+
+			]);
+
+			doh.register("paths", [
+				function getPath(){
+					var france = europe.getChildren()[0];
+
+					// Select the node.   can't emit "click" because dndSelector listens for mousedown & mouseup.
+					// And before the mousedown, we need a mouseover event, so _dndContainer.js sets this.current.
+					on.emit(france.labelNode, navigator.msPointerEnabled ? "MSPointerOver" : "mouseover", {bubbles: true});
+					on.emit(france.labelNode, navigator.msPointerEnabled ? "MSPointerDown" : "mousedown", {button: dojo.mouseButtons.LEFT, bubbles: true});
+					on.emit(france.labelNode, navigator.msPointerEnabled ? "MSPointerUp" : "mouseup", {button: dojo.mouseButtons.LEFT, bubbles: true});
+
+					var path = myTree.get("path");
+					doh.is("earth, EU, FR",
+							array.map(myTree.get("path"), function(obj){ return obj.id; }).join(", "),
+							"serialized path");
+				},
+				{
+					name: "createWithPath",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						myTree2 = new Tree({
+							id: "myTree2",
+							model: myModel,
+							persist: false,		// persist==true is too hard to test
+							dndController: dndSource,
+							path: ["earth", "EU", "IT"]
+						}).placeAt(win.body());
+						doh.t(myTree2, "myTree2 created");
+
+						myTree2.startup();
+
+						setTimeout(d.getTestCallback(function(){
+							doh.t(myTree2.rootNode, "root node exists");
+							doh.t(myTree2.rootNode.isExpanded, "root node is expanded");
+							doh.t(myTree2.rootNode.getChildren()[3].isExpanded, "europe node is expanded");
+							doh.is("Italy", myTree2.selectedNode.label, "selected correct node");
+						}), 2000);
+
+						return d;
+					}
+				},
+				function copyPath(){
+					var d = new doh.Deferred();
+
+					myTree.set("path", myTree2.get("path")).then(d.getTestCallback(function(items){
+						doh.is("earth, EU, IT", array.map(items, function(item){ return item.id; }).join(", "));
+						doh.t(world.isExpanded, "root node is expanded");
+						doh.t(world.getChildren()[3].isExpanded, "europe node is expanded");
+						doh.is("Italy", myTree.get("selectedNode").label, "selected correct node");
+					}));
+
+					return d;
+				},
+
+				{
+					name: "copyPathByIds",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						myTree.set("path", ["earth", "NA", "CA", "Ottawa"]).then(d.getTestErrback(function(){
+							var path = array.map(myTree.get("path"), function(item){ return item.id; });
+							doh.is(["earth", "NA", "CA", "Ottawa"], path, "path got set on myTree");
+
+							myTree2.set("path", path).then(d.getTestCallback(function(){
+								doh.t(myTree2.rootNode.isExpanded, "root node is expanded");
+								doh.t(myTree2.rootNode.getChildren()[4].isExpanded, "north america node is expanded");
+								doh.t(myTree2.rootNode.getChildren()[4].getChildren()[1].isExpanded, "canada node is expanded");
+								doh.is("Ottawa", myTree2.get("selectedNode").label, "selected correct node");
+							}));
+						}));
+
+						return d;
+					}
+				},
+
+				function setPathToNull(){
+					var d = new doh.Deferred();
+
+					myTree2.set("path", []).then(d.getTestCallback(function(){
+						doh.is(null, myTree2.get("selectedNode"), "no selected node");
+					}));
+					return d;
+				},
+
+				function setPathToRoot(){
+					var d = new doh.Deferred();
+
+					myTree2.set("path", ["earth"]).then(d.getTestCallback(function(){
+						doh.is(myTree2.rootNode, myTree2.get("selectedNode"), "selected root node");
+					}));
+					return d;
+				},
+
+				function setPaths(){
+					var d = new doh.Deferred();
+
+					myTree2.set("paths", [["earth", "AF", "KE", "Nairobi"],
+										["earth", "NA", "MX", "Guadalajara"]]).then(d.getTestCallback(function(paths){
+						doh.is("earth, AF, KE, Nairobi", array.map(paths[0], function(item){ return item.id; }).join(", "));
+						doh.is("earth, NA, MX, Guadalajara", array.map(paths[1], function(item){ return item.id; }).join(", "));
+						var ids = array.map(myTree2.selectedItems, function(x){return myTree2.model.getIdentity(x);}).sort();
+						doh.is(["Guadalajara", "Nairobi"], ids);
+					}));
+					return d;
+				},
+				function setEmptyPath(){
+					var d = new doh.Deferred();
+
+					// setting an empty path is interpreted as selecting nothing
+					myTree2.set("path", []).then(
+						d.getTestCallback(function(){
+							doh.is(0, myTree2.get("selectedNodes").length, "no nodes selected");
+						}),
+						d.getTestCallback(function(e){
+							throw e;
+						})
+					);
+
+					return d;
+				},
+				function setInvalidPath(){
+					var d = new doh.Deferred();
+					myTree2.set("path", ["earth", "AF", "KE", "Narnia"]).then(
+						function(){
+							d.errback("Should have gotten error trying to set invalid path");
+						},
+						d.getTestCallback(function(e){
+							doh.t(e instanceof Tree.PathError, "got PathError");
+						})
+					);
+
+					return d;
+				}
+
+			]);
+
+			doh.register("destroy", [
+				function destroyTree(){
+					// Just running this to make sure we don"t get an exception
+					myTree.destroy();
+					myTree2.destroy();
+				}
+			]);
+
+			doh.register("delete selected node", [
+				{
+					name: "create",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						myTree = new Tree({
+							id: "myTree",
+							model: myModel,
+							persist: false,		// persist==true is too hard to test
+							path: ["earth", "EU", "IT"]
+						}).placeAt(win.body());
+						doh.t(myTree, "tree created");
+
+						myTree.startup();
+
+						myTree.onLoadDeferred.then(d.getTestCallback(function(){
+							doh.is("IT", myTree.get("selectedItem").id);
+						}));
+
+						return d;
+					}
+				},
+
+				function deleteSelectedItem(){
+					myStore.remove("IT");
+				},
+
+				function selectNewItem(){
+					// Since EU is already open this set("path", ...) should execute immediately
+					myTree.set("path", ["earth", "EU", "FR"]);
+					doh.is("FR", myTree.get("selectedItem").id);
+				}
+			]);
+
+
+			doh.register("nobidi", [
+				// Make sure that Tree doesn't have spurious lang="" dir="" on nodes
+				function noLangDir(){
+					doh.t(myTree.rootNode, "root node exists");
+					doh.t(myTree.rootNode.isExpanded, "root node is expanded");
+					doh.f(domClass.contains(myTree.rootNode, "lang"), "no (empty) lang attribute on root TreeNode");
+					doh.f(domClass.contains(myTree.rootNode, "dir"), "no (empty) dir attribute on root TreeNode");
+
+					var children = myTree.rootNode.getChildren();
+					doh.f(domClass.contains(children[2], "lang"), "no (empty) lang attribute on child TreeNode");
+					doh.f(domClass.contains(children[2], "dir"), "no (empty) dir attribute on child TreeNode");
+				}
+			]);
+
+			doh.register("expand/contract", [
+				{
+					name: "initiallyExpanded",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						myTree = new Tree({
+							id: "myTreeExpand",
+							model: myModel,
+							persist: false,		// persist==true is too hard to test
+							autoExpand: true
+						}).placeAt(win.body());
+						doh.t(myTree, "tree created");
+
+						myTree.startup();
+
+						world = myTree.rootNode;
+
+						myTree.onLoadDeferred.then(d.getTestCallback(function(){
+							doh.t(world, "root node exists");
+							doh.t(world.isExpanded, "root node is expanded");
+
+							var children = world.getChildren();
+							doh.is(6, children.length, "world children");
+							doh.t(children[0].isExpanded, "Africa expanded");
+							doh.t(children[0].getChildren()[2].isExpanded, "Kenya expanded too");
+							doh.is(2, children[0].getChildren()[2].getChildren().length, "Kenya children");
+							doh.t(children[4].isExpanded, "North America expanded");
+							doh.is(3, children[4].getChildren().length, "North America children");
+						}));
+
+						return d;
+					}
+				},
+				{
+					name: "collapseAll",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						myTree.collapseAll().then(d.getTestCallback(function(){
+							doh.t(world, "root node exists");
+							doh.f(world.isExpanded, "root node collapsed");
+
+							var children = world.getChildren();
+							doh.is(6, children.length, "world children");
+							doh.f(children[0].isExpanded, "Africa collapsed");
+							doh.f(children[0].getChildren()[2].iscollapsed, "Kenya collapsed too");
+							doh.is(2, children[0].getChildren()[2].getChildren().length, "Kenya children");
+							doh.f(children[4].isExpanded, "North America collapsed");
+							doh.is(3, children[4].getChildren().length, "North America children");
+						}));
+
+						return d;
+					}
+				},
+				{
+					name: "expandAll",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						myTree.destroy();
+
+						myTree = new Tree({
+							id: "myTreeExpand",
+							model: myModel,
+							persist: false,		// persist==true is too hard to test
+							autoExpand: false
+						}).placeAt(win.body());
+						doh.t(myTree, "tree created");
+
+						myTree.startup();
+
+						world = myTree.rootNode;
+
+						myTree.onLoadDeferred.then(d.getTestErrback(function(){
+							doh.t(world, "root node exists");
+							doh.t(world.isExpanded, "root node is expanded");
+
+							var children = world.getChildren();
+							doh.is(6, children.length, "world children");
+							doh.f(children[0].isExpanded, "Africa collapsed");
+
+							myTree.expandAll().then(d.getTestCallback(function(){
+								var children = world.getChildren();
+								doh.t(children[0].isExpanded, "Africa expanded");
+								doh.t(children[0].getChildren()[2].isExpanded, "Kenya expanded too");
+								doh.t(children[4].isExpanded, "North America expanded");
+								doh.is(3, children[4].getChildren().length, "North America children");
+							}));
+						}));
+
+						return d;
+					}
+				},
+				{
+					name: "collapseShowRootFalseTree",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						myTree.destroy();
+
+						myTree = new Tree({
+							id: "myTreeExpand",
+							model: myModel,
+							persist: false,		// persist==true is too hard to test
+							showRoot: false
+						}).placeAt(win.body());
+						doh.t(myTree, "tree created");
+
+						myTree.startup();
+
+						world = myTree.rootNode;
+
+						myTree.onLoadDeferred.then(d.getTestErrback(function(){
+							myTree._expandNode(myTree.rootNode.getChildren()[0]).then(d.getTestErrback(function(){
+								var children = world.getChildren();
+								doh.t(children[0].isExpanded, "Africa collapsed");
+
+								myTree.collapseAll().then(d.getTestCallback(function(){
+									doh.t(world, "root node exists");
+									doh.t(world.isExpanded, "root node expanded (because it's hidden");
+
+									doh.f(children[0].isExpanded, "Africa collapsed");
+									doh.t(helpers.isVisible(children[0]), "Africa node visible");
+								}));
+							}));
+						}));
+
+						return d;
+					}
+				}
+			]);
+
+			doh.register("persistence", [
+				// Reset the data to original values
+				setup,
+
+				{
+					name: "create",
+					timeout: 5000,
+					runTest: function(){
+						if(registry.byId("myTree")){
+							registry.byId("myTree").destroy();
+						}
+						cookie("myTreeSaveStateCookie", "");
+
+						myTree = new Tree({
+							id: "myTree",
+							model: myModel,
+							persist: true
+						}).placeAt(win.body());
+						doh.t(myTree, "tree created");
+
+						myTree.startup();
+
+						world = myTree.rootNode;
+
+						return myTree.onLoadDeferred;
+					}
+				},
+
+				{
+					name: "expand and contract",
+					timeout: 5000,
+					runTest: function(){
+
+						var d = new doh.Deferred();
+
+						na = world.getChildren()[4];
+						doh.is("North America", na.label, "North America node label");
+
+						// Click on North America to open it
+						on.emit(na.expandoNode, "click", {bubbles: true});
+
+						// Wait for animation to complete
+						setTimeout(d.getTestErrback(function(){
+							mx = na.getChildren()[0];
+							doh.is("Mexico", mx.label, "Mexico node label");
+
+							// Click on Mexico to open it
+							on.emit(mx.expandoNode, "click", {bubbles: true});
+
+							// Wait for animation to complete.
+							setTimeout(d.getTestErrback(function(){
+								// Click on North America again, to close it
+								on.emit(na.expandoNode, "click", {bubbles: true});
+								setTimeout(d.getTestCallback(function(){
+									// Wait for close animation to finish and then return success
+								}), 500);
+							}), 500);
+						}), 500);
+
+						return d;
+					}
+				},
+
+				{
+					name: "recreate tree",
+					timeout: 5000,
+					runTest: function(){
+						myTree.destroy();
+
+						myTree = new Tree({
+							id: "myTree",
+							model: myModel,
+							persist: true
+						}).placeAt(win.body());
+						doh.t(myTree, "tree created");
+
+						myTree.startup();
+
+						world = myTree.rootNode;
+
+						return myTree.onLoadDeferred;
+					}
+				},
+
+				{
+					name: "check tree state",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						na = world.getChildren()[4];
+						doh.is("North America", na.label, "North America node label");
+
+						doh.f(na.isExpanded, "North America collapsed");
+
+						// Click on North America to open it
+						on.emit(na.expandoNode, "click", {bubbles: true});
+
+						setTimeout(d.getTestCallback(function(){
+							doh.t(na.isExpanded, "North America expanded");
+							mx = na.getChildren()[0];
+							doh.is("Mexico", mx.label, "Mexico node label");
+							doh.t(mx.isExpanded, "Mexico expanded");
+						}), 500);
+
+						return d;
+					}
+				}
+			]);
+
+			// Tests that TreeNodes that are destroyed don't linger in selection, etc.
+			doh.register("destroyed nodes", [
+				// Reset the data to original values
+				setup,
+
+				{
+					name: "create",
+					timeout: 5000,
+					runTest: function(){
+						cookie("myDeleteTreeSaveStateCookie", "");
+						myTree = new Tree({
+							id: "myDeleteTree",
+							model: myModel,
+							persist: true
+						}).placeAt(win.body());
+						doh.t(myTree, "tree created");
+
+						myTree.startup();
+						doh.is("earth", cookie("myDeleteTreeSaveStateCookie"), "initial persistence cookie just earth");
+					}
+				},
+
+				function removedFromSelection(){
+					var d = new doh.Deferred();
+					// Select Mexico city
+					myTree.set("path", ["earth", "NA", "MX", "Mexico City"]).then(d.getTestErrback(function(){
+						doh.is(1, myTree.get("paths").length, "one selected node");
+						var selectedNode = myTree.get("selectedNode");
+
+						// Ancestors of the selected node should be expanded, and that should be saved
+						// in the cookie
+						doh.is("earth,earth/NA,earth/NA/MX", cookie("myDeleteTreeSaveStateCookie"),
+								"Earth, North America, Mexico should be listed as expanded");
+
+						// Remove selection's ancestor
+						myStore.remove("NA");
+
+						// use setTimeout() to give Tree time to realize this isn't a drag & drop, but that
+						// the North America subtree was truly deleted
+						setTimeout(d.getTestCallback(function(){
+							doh.t(selectedNode._destroyed, "the selected node was destroyed (along with it's ancestor)");
+							doh.is(0, myTree.get("paths").length, "no selected nodes");
+							doh.is("earth", cookie("myDeleteTreeSaveStateCookie"),
+									"North America and Mexico should have been removed from list of expanded nodes")
+						}), 10)
+					}));
+					return d;
+				},
+
+				{
+					name: "reinsert deleted descendants",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						myStore.put({ id: "NA", name:"North America", type:"continent", parent: "earth" });
+						myStore.put({ id: "MX", name:"Mexico", type:"country",  population:"108 million", area:"1,972,550 sq km",
+								parent: "NA" });
+						myStore.put({ id: "Mexico City", name:"Mexico City", type:"city", population:"19 million", timezone:"-6 UTC", parent: "MX"});
+						myStore.put({ id: "Guadalajara", name:"Guadalajara", type:"city", population:"4 million", timezone:"-6 UTC", parent: "MX" });
+
+						myTree.set("path", ["earth", "NA", "MX", "Mexico City"]).then(
+							d.getTestCallback(function(){
+								var node = myTree.get("selectedNode");
+								doh.isNot(null, node, "got a selected node");
+								doh.f(node._destroyed, "not destroyed");
+								doh.f(node.getParent()._destroyed, "parent not destroyed");
+								doh.f(node.getParent().getParent()._destroyed, "grandparent not destroyed");
+							}),
+							d.getTestErrback(function(err){
+								throw err;
+							})
+						);
+
+						return d;
+					}
+				}
+			]);
+
+			doh.register("HTML tree", {
+				name: "create",
+				timeout: 5000,
+				runTest: function(){
+					var d = new doh.Deferred();
+
+					// Create test store.
+					htmlData = array.map(data, function(o){
+						var n = lang.clone(o);
+						n.name = "<i>" + o.name + "</i>";
+						return n;
+					});
+					htmlStore = new Memory({
+						data: htmlData
+					});
+
+					// Since dojo.store.Memory doesn't have various store methods we need, we have to add them manually
+					htmlStore.getChildren = function(object){
+						// Add a getChildren() method to store for the data model where
+						// children objects point to their parent (aka relational model)
+						return this.query({parent: this.getIdentity(object)});
+					};
+
+					// Create the model
+					htmlModel = new ObjectStoreModel({
+						store: htmlStore,
+						labelType: "html",
+						query: {id: "earth"}
+					});
+					doh.t(htmlModel, "model created");
+
+					htmlTree = new Tree({
+						id: "htmlTree",
+						model: htmlModel
+					}).placeAt(win.body());
+					doh.t(htmlTree, "tree created");
+
+					htmlTree.startup();
+
+					world = htmlTree.rootNode;
+
+					return htmlTree.expandAll().then(function(){
+						doh.t(world, "root node exists");
+						doh.is("<i>The earth</i>", world.label, "world node label");
+						doh.is("<i>the earth</i>", world.labelNode.innerHTML.toLowerCase(), "world node labelNode.innerHTML");
+
+						var children = world.getChildren();
+						doh.is("<i>Africa</i>", children[0].label, "first child");
+						doh.is("<i>africa</i>", children[0].labelNode.innerHTML.toLowerCase(), "first child labelNode.innerHTML");
+					});
+				}
+			});
+
+			doh.register("plain text tree", {
+				name: "create",
+				timeout: 5000,
+				runTest: function(){
+					var d = new doh.Deferred();
+
+					// Create test store.
+					plainTextData = array.map(data, function(o){
+						var n = lang.clone(o);
+						n.name = "<>&" + o.name;
+						return n;
+					});
+					plainTextStore = new Memory({
+						data: plainTextData
+					});
+
+					// Since dojo.store.Memory doesn't have various store methods we need, we have to add them manually
+					plainTextStore.getChildren = function(object){
+						// Add a getChildren() method to store for the data model where
+						// children objects point to their parent (aka relational model)
+						return this.query({parent: this.getIdentity(object)});
+					};
+
+					// Create the model
+					plainTextModel = new ObjectStoreModel({
+						store: plainTextStore,
+						labelType: "text",
+						query: {id: "earth"}
+					});
+					doh.t(plainTextModel, "model created");
+
+					plainTextTree = new Tree({
+						id: "plainTextTree",
+						model: plainTextModel
+					}).placeAt(win.body());
+					doh.t(plainTextTree, "tree created");
+
+					plainTextTree.startup();
+
+					world = plainTextTree.rootNode;
+
+					return plainTextTree.expandAll().then(function(){
+						doh.t(world, "root node exists");
+						doh.is("<>&The earth", world.label, "world node label");
+						doh.is("<>&The earth", helpers.innerText(world.labelNode), "world node labelNode.innerText");
+
+						var children = world.getChildren();
+						doh.is("<>&Africa", helpers.innerText(children[0].labelNode), "first child");
+					});
+				}
+			});
+
+			doh.run();
+
+ 		});
+	</script>
+
+</head>
+<body class="claro" role="main">
+
+	<h1 class="testTitle">Tree using Tree.ObjectStore (against dojo.store) Automated Test</h1>
+
+</body>
+</html>
diff --git a/dijit/tests/tree/Tree_with_JRS.html b/dijit/tests/tree/Tree_with_JRS.html
index 39d7655..e2138ed 100644
--- a/dijit/tests/tree/Tree_with_JRS.html
+++ b/dijit/tests/tree/Tree_with_JRS.html
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="en">
 <head>
 	<title>dijit.Tree Automatic Tests</title>
 
@@ -16,13 +16,11 @@
 	
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 	
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
-	<script type="text/javascript" src="../helpers.js"></script>
-
 	<script type="text/javascript">
 		dojo.require("doh.runner");
 		dojo.require("dojo.parser");
@@ -31,6 +29,7 @@
 		dojo.require("dijit.Tree");
 		dojo.require("dijit.tree.ForestStoreModel");
 		dojo.require("dijit.tree.dndSource");
+		dojo.require("dijit.tests.helpers");	// functions to help test
 
 		dojo.ready(function(){
 			var handler, myTree;
@@ -123,7 +122,7 @@
 	</script>
 
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Dijit.Tree automated tests</h1>
 	<div id="container"> <!--  tree will go here --></div>
diff --git a/dijit/tests/tree/module.js b/dijit/tests/tree/module.js
index 44f1d38..a4d54e2 100644
--- a/dijit/tests/tree/module.js
+++ b/dijit/tests/tree/module.js
@@ -1,22 +1,21 @@
-dojo.provide("dijit.tests.tree.module");
+define(["doh/main", "require"], function(doh, require){
+	var test_robot = true;
 
-try{
-	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?"),
-		test_robot = true;
-
-	doh.registerUrl("dijit.tests.tree.CustomLabel", dojo.moduleUrl("dijit", "tests/tree/CustomLabel.html"), 999999);
-	doh.registerUrl("dijit.tests.tree.Tree", dojo.moduleUrl("dijit", "tests/tree/Tree.html"), 999999);
-	doh.registerUrl("dijit.tests.tree.Tree_with_JRS", dojo.moduleUrl("dijit", "tests/tree/Tree_with_JRS.html"), 999999);
+	doh.register("tree.CustomLabel", require.toUrl("./CustomLabel.html"), 999999);
+	doh.register("tree.Tree_ForestStoreModel", require.toUrl("./Tree_ForestStoreModel.html"), 999999);
+	doh.register("tree.Tree_with_JRS", require.toUrl("./Tree_with_JRS.html"), 999999);
+	doh.register("tree.Tree_ObjectStoreModel", require.toUrl("./Tree_ObjectStoreModel.html"), 999999);
 
 	if(test_robot){
-		doh.registerUrl("dijit.tests.tree.robot.Tree_a11y", dojo.moduleUrl("dijit","tests/tree/robot/Tree_a11y.html"+userArgs), 999999);
-		doh.registerUrl("dijit.tests.tree.robot.Tree_DnD", dojo.moduleUrl("dijit","tests/tree/robot/Tree_dnd.html"+userArgs), 999999);
-		doh.registerUrl("dijit.tests.tree.robot.Tree_selector", dojo.moduleUrl("dijit","tests/tree/robot/Tree_selector.html"+userArgs), 999999);
-		doh.registerUrl("dijit.tests.tree.robot.Tree_selector_only",
-			dojo.moduleUrl("dijit","tests/tree/robot/Tree_selector.html?controller=selector&"+userArgs.substr(1)), 999999);
-		doh.registerUrl("dijit.tests.tree/robot.Tree_DnD_multiParent", dojo.moduleUrl("dijit","tests/tree/robot/Tree_dnd_multiParent.html"+userArgs), 999999);
-		doh.registerUrl("dijit.tests.tree.robot.Tree_v1", dojo.moduleUrl("dijit","tests/tree/robot/Tree_v1.html"+userArgs), 999999);
+		doh.register("tree.robot.Tree_a11y", require.toUrl("./robot/Tree_a11y.html"), 999999);
+		doh.register("tree.robot.Tree_mouse", require.toUrl("./robot/Tree_mouse.html"), 999999);
+		doh.register("tree.robot.Tree_Custom_TreeNode", require.toUrl("./robot/Tree_Custom_TreeNode.html"), 999999);
+		doh.register("tree.robot.Tree_DnD", require.toUrl("./robot/Tree_dnd.html"), 999999);
+		doh.register("tree.robot.Tree_selector", require.toUrl("./robot/Tree_selector.html"), 999999);
+		doh.register("tree.robot.Tree_selector_only",
+			require.toUrl("./robot/Tree_selector.html?controller=selector"), 999999);
+		doh.register("tree/robot.Tree_DnD_multiParent", require.toUrl("./robot/Tree_dnd_multiParent.html"), 999999);
+		doh.register("tree.robot.Tree_v1", require.toUrl("./robot/Tree_v1.html"), 999999);
 	}
-}catch(e){
-	doh.debug(e);
-}
+
+});
diff --git a/dijit/tests/tree/places.json b/dijit/tests/tree/places.json
index 0ea6e7a..064a4e5 100644
--- a/dijit/tests/tree/places.json
+++ b/dijit/tests/tree/places.json
@@ -1,29 +1,29 @@
 {
-	identifier: 'id',
-	label: 'name',
-	items: [
-		{ id: 'root', children: [
-			{_reference: 'h0'},
-			{_reference: 'h1'},
-			{_reference: 'h2'},
-			{_reference: 'h3'},
-			{_reference: 'h4'} ]},
-		{ id: 'h0', name:'South Africa', type: 'header', children:[ {_reference: 'p0'}] },
-		{ id: 'h1', name:'Ireland', type: 'header', children:[ {_reference: 'p1'},  {_reference: 'p2'}] },
-		{ id: 'h2', name:'France', type: 'header',  children:[ {_reference: 'p3'},  {_reference: 'p4'}] },
-		{ id: 'h3', name:'Canada', type: 'header',
-				children:[ {_reference: 'p5'},  {_reference: 'p6'},  {_reference: 'p7'},  {_reference: 'p8'} ] },
-		{ id: 'h4', name:'Korea', type: 'header', children:[ {_reference: 'p9'}] },
+	"identifier": "id",
+	"label": "name",
+	"items": [
+		{ "id": "root", "children": [
+			{"_reference": "h0"},
+			{"_reference": "h1"},
+			{"_reference": "h2"},
+			{"_reference": "h3"},
+			{"_reference": "h4"} ]},
+		{ "id": "h0", "name":"South Africa", "type": "header", "children":[ {"_reference": "p0"}] },
+		{ "id": "h1", "name":"Ireland", "type": "header", "children":[ {"_reference": "p1"},  {"_reference": "p2"}] },
+		{ "id": "h2", "name":"France", "type": "header",  "children":[ {"_reference": "p3"},  {"_reference": "p4"}] },
+		{ "id": "h3", "name":"Canada", "type": "header",
+				"children":[ {"_reference": "p5"},  {"_reference": "p6"},  {"_reference": "p7"},  {"_reference": "p8"} ] },
+		{ "id": "h4", "name":"Korea", "type": "header", "children":[ {"_reference": "p9"}] },
 
-		{ id: 'p0', name:'Joburg', type: 'place'},
-		{ id: 'p1', name:'Knocknahilan', type: 'place'  },
-		{ id: 'p2', name:'Kinsale',  type: 'place' },
-		{ id: 'p3', name:'Lyon',  type: 'place' },
-		{ id: 'p4', name:'Nice', type: 'place' },
-		{ id: 'p5', name:'Toronto',  type: 'place'},
-		{ id: 'p6', name:'Hudson Bay', type: 'place'},
-		{ id: 'p7', name:'Quebec',  type: 'place' },
-		{ id: 'p8', name:'Polar Bear County', type: 'place' },
-		{ id: 'p9', name:'Jeonju', type: 'place' }
+		{ "id": "p0", "name":"Joburg", "type": "place"},
+		{ "id": "p1", "name":"Knocknahilan", "type": "place"  },
+		{ "id": "p2", "name":"Kinsale",  "type": "place" },
+		{ "id": "p3", "name":"Lyon",  "type": "place" },
+		{ "id": "p4", "name":"Nice", "type": "place" },
+		{ "id": "p5", "name":"Toronto",  "type": "place"},
+		{ "id": "p6", "name":"Hudson Bay", "type": "place"},
+		{ "id": "p7", "name":"Quebec",  "type": "place" },
+		{ "id": "p8", "name":"Polar Bear County", "type": "place" },
+		{ "id": "p9", "name":"Jeonju", "type": "place" }
 	]
 }
diff --git a/dijit/tests/tree/robot/Tree_Custom_TreeNode.html b/dijit/tests/tree/robot/Tree_Custom_TreeNode.html
new file mode 100644
index 0000000..7b440d5
--- /dev/null
+++ b/dijit/tests/tree/robot/Tree_Custom_TreeNode.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>robot Custom TreeNode Test</title>
+
+	<style>
+		@import "../../../../util/doh/robot/robot.css";
+	</style>
+
+	<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner", "dojo/robotx",
+			"dojo/keys", "dojo/query",
+			"dijit/tests/helpers","dojo/domReady!"
+		], function(doh, robot, keys, query, helpers){
+
+			var tree,registry;
+
+			robot.initRobot('../test_Custom_TreeNode.html');
+
+			doh.register("_setup", [
+				{
+					name: "wait for widgets to load",
+					timeout: 10000,
+					runTest: helpers.waitForLoad
+				},
+				function setVars(){
+					registry = robot.window.require("dijit/registry");
+					tree = dojo.global.tree;
+				}
+			]);
+
+			doh.register("arrow navigation", [
+				{
+					name: "right arrow, down arrow",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						var firstVisibleNode = query(".dijitTreeLabel", robot.doc)[1];
+						firstVisibleNode.focus();
+
+						robot.keyPress(keys.RIGHT_ARROW, 100);
+						robot.keyPress(keys.RIGHT_ARROW, 100);
+						robot.sequence(d.getTestCallback(function(){
+							var focus = dojo.global.dijit.focus.curNode;
+							doh.is("Child_0", helpers.innerText(focus), "focused on first child");
+						}), 500);
+
+						return d;
+					}
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+</html>
+
diff --git a/dijit/tests/tree/robot/Tree_a11y.html b/dijit/tests/tree/robot/Tree_a11y.html
index 824bf21..8bd75cf 100644
--- a/dijit/tests/tree/robot/Tree_a11y.html
+++ b/dijit/tests/tree/robot/Tree_a11y.html
@@ -2,544 +2,440 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
-	<title>doh.robot Tree Test</title>
+	<title>robot Tree A11y Test</title>
 
 	<style>
 		@import "../../../../util/doh/robot/robot.css";
 	</style>
 
-	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dijit.robotx");
-
-		var treeIds = ["mytree", "tree2"];
-
-		function treeTests(){
-			var that = {};
-
-			var forceLoadChildItems = function(/*dijit._TreeNode*/inNode, /*dijit.Tree*/inTree){
-				if(inTree.model.mayHaveChildren(inNode.item)){
-					if(inNode.getChildren().length > 0){
-						return;
-					}
-					var childItems = null;
-					inTree.model.getChildren(inNode.item, function(items){ childItems = items; });
-					inNode.setChildItems(childItems);
-					childItems = null;
-				}
-			};
-
-			that.testTreeItemRole = function(/*dijit._TreeNode*/inRoot, /*dijit.Tree*/inTree){
+		require([
+			"doh/runner", "dojo/robotx",
+			"dojo/_base/array", "dojo/dom", "dojo/keys", "dojo/query", "dojo/window",
+			"dijit/tests/helpers", "dojo/domReady!"
+		], function(doh, robot, array, dom, keys, query, winUtils, helpers){
+
+			var treeIds = ["mytree", "tree2"];
+	
+			function testTreeItemRole(/*dijit._TreeNode*/ inRoot, /*dijit.Tree*/ inTree){
 				if(inRoot){
 					var expectedrole = inTree.showRoot || inRoot!==inTree.rootNode ? 'treeitem' : 'presentation';
 					doh.is(expectedrole, inRoot.labelNode.getAttribute("role"), inRoot.label + "[" + inTree.id + "]: aria role (" + expectedrole + ")");
-					//recurse
-					forceLoadChildItems(inRoot, inTree);
+					// recurse
 					var children = inRoot.getChildren();
 					for(var i = 0; i < children.length; i++){
-						that.testTreeItemRole(children[i], inTree);
+						testTreeItemRole(children[i], inTree);
 					}
 				}
-			};
-
-			that.test1TreeItemExpandedState = function(/*dijit._TreeNode*/inItem, /*dijit.Tree*/inTree){
-				if(inItem){
-					if(inItem.isExpandable){
-						var wasExpanded = inItem.isExpanded;
-						inTree._expandNode(inItem);
-						var nowExpanded = inItem.labelNode.getAttribute("aria-expanded");
-						inTree._collapseNode(inItem);
-						var nowCollapsed = inItem.labelNode.getAttribute("aria-expanded");
-						if(wasExpanded){
-							inTree._expandNode(inItem);
-						}
-						doh.is("true", nowExpanded, inItem.label + "[" + inTree.id + "]: aria state expanded=true");
-						doh.is("false", nowCollapsed, inItem.label + "[" + inTree.id + "]: aria state expanded=false");
-					}else{
-						doh.is(null, inItem.labelNode.getAttribute("aria-expanded"), inItem.label + "[" + inTree.id + "]: aria state expanded=false");
-					}
-				}
-			};
+			}
+	
+			robot.initRobot('../test_Tree.html');
 
-			that.testTreeItemExpandedState = function(/*dijit._TreeNode*/inRoot, /*dijit.Tree*/inTree){
-				if(inRoot){
-					that.test1TreeItemExpandedState(inRoot, inTree);
-					//recurse
-					forceLoadChildItems(inRoot, inTree);
-					var children = inRoot.getChildren();
-					for(var i = 0; i < children.length; i++){
-						that.testTreeItemExpandedState(children[i], inTree);
-					}
-				}
-			};
-
-			// Tab focus test data and functions
-			var xtraParas = [];
-			var expectedBlurCount = 0;
-			var focusCount = 0;
-			var blurCount = 0;
-			var gotFocus = function(){
-				focusCount++;
-			};
-			var lostFocus = function(){
-				blurCount++;
-			};
-			that.focusConnect = null;
-			that.blurConnect = null;
-
-			var addTabNavFoci = function(inTree){
-				var aPara = dojo.doc.createElement("p");
-				dojo.attr(aPara, 'tabIndex', 0);
-				aPara.innerHTML = "Tab-focussable paragraph just above " + inTree.id;
-				dojo.place(aPara, inTree.domNode, "before");
-				xtraParas.push(aPara);
-				aPara = dojo.doc.createElement("p");
-				dojo.attr(aPara, 'tabIndex', 0);
-				aPara.innerHTML = "Tab-focussable paragraph just below  " + inTree.id;
-				dojo.place(aPara, inTree.domNode, "after");
-				xtraParas.push(aPara);
-			};
-
-			var walkTreeToLeaf = function(inTree, inRootNode, /*array, optional*/ioPath){
-				var leaf = inRootNode;
-				if(ioPath){ ioPath.push(inRootNode); }
-				if(inRootNode.isExpandable){
-					forceLoadChildItems(inRootNode, inTree);
-					inTree._expandNode(inRootNode);
-					var down = inRootNode.getChildren()[0];
-					if(down){
-						leaf = walkTreeToLeaf(inTree, down, ioPath);
-					}
-				}
-				return(leaf);
-			};
-
-			that.tabFocusSetup = function(inTreeId, /*boolean*/ leaf){
-				var tree = dijit.byId(inTreeId);
-				that.collapseAllButRoot(tree);
-				addTabNavFoci(tree);
-				// set up focus listener machinery
-				focusCount = blurCount = 0;
-				var focusThing;
-				if(leaf){
-					focusThing = walkTreeToLeaf(tree, tree.rootNode);
-				}else if(tree.showRoot){
-					focusThing = tree.rootNode;
-				}else{
-					focusThing = tree.rootNode.getChildren()[0];
-				}
-				that.focusConnect = tree.connect(focusThing.labelNode, "onfocus", gotFocus);
-				that.blurConnect = tree.connect(focusThing.labelNode, "onblur", lostFocus);
-				tree.focusNode(focusThing);
-			};
-
-			that.tabFocusA11yTest = function(inTreeId){
-				var d = new doh.Deferred();
-				var tree = dijit.byId(inTreeId);
-				// shift+tab away, tab back, tab away, shift+tab back
-				doh.robot.keyPress(dojo.keys.TAB, 1000, {shift:true});
-				doh.robot.keyPress(dojo.keys.TAB, 300);
-				doh.robot.keyPress(dojo.keys.TAB, 300);
-				doh.robot.keyPress(dojo.keys.TAB, 300, {shift:true});
-				var checkTabNav = function(){
-					tree.disconnect(that.focusConnect);
-					tree.disconnect(that.blurConnect);
-					doh.is(3, focusCount,  tree.id + ": # of times focussed");
-					doh.is(2, blurCount, tree.id + ": # of times lost focus");
-				};
-				doh.robot.sequence(d.getTestCallback(checkTabNav), 500);
-				return d;
-			};
-
-			that.tabFocusTearDown = function(){
-				dojo.forEach(xtraParas, function(item){
-					item.parentNode.removeChild(item);
-				});
-				xtraParas.length = 0;
-				that.focusCount = 0;
-				that.blurCount = 0;
-			};
-
-			// arrow key navigation, expand, and collapse tests.
-			that.collapseAllButRoot = function(inTree){
-				function collapse(node){
-					if(node){
-						var children = node.getChildren();
-						dojo.forEach(children, function(child){
-							if(child.isExpandable){
-								collapse(child);
-								inTree._collapseNode(child);
-							}
-						});
-					}
-				}
-				if(inTree){
-					collapse(inTree.rootNode);
-				}
-			};
-
-			that.openConnect = null;
-			that.closeConnect = null;
-			var openedLabels = [];
-			var closedLabels = [];
-
-			that.a11yNavExpandCollapseSetup = function(inTreeId){
-				var tree = dijit.byId(inTreeId);
-				that.collapseAllButRoot(tree);
-				var startingNode = tree.showRoot ? tree.rootNode : tree.rootNode.getChildren()[0];
-				tree.focusNode(startingNode);
-				var rootChilds = tree.rootNode.getChildren();
-				// down, right (open), left (close), down, left (open)
-				if(tree.showRoot){
-					openedLabels[0] = { expected: rootChilds[0].label };
-					openedLabels[1] = { expected: rootChilds[1].label };
-				}else{
-					openedLabels[0] = { expected: rootChilds[1].label };
-					openedLabels[1] = { expected: rootChilds[2].label };
-				}
-				closedLabels[0] = openedLabels[0];
-				var openIdx = 0;
-				var collectOpen = function(item, node){
-					openedLabels[openIdx].actual = node.label;
-				};
-				var collectClose = function(item, node){
-					closedLabels[openIdx].actual = node.label;
-					openIdx++;
-				};
-				that.openConnect = dojo.connect(tree, "onOpen", collectOpen);
-				that.closeConnect = dojo.connect(tree, "onClose", collectClose);
-			};
-
-			that.a11yNavExpandCollapseTest = function(inTreeId){
-				var d = new doh.Deferred();
-				// assume (1) collapaseAllButRoot(), and (2) focus is on first visible child.
-				doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);		// move down one
-				doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
-				doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse
-				doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down one
-				doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
-				var checkKeystrokes = function(){
-					for(var idx = 0; idx < openedLabels.length; idx++){
-						doh.is(openedLabels[idx].expected, openedLabels[idx].actual, "onOpen");
-					}
-					for(idx = 0; idx < closedLabels.length; idx++){
-						doh.is(closedLabels[idx].expected, closedLabels[idx].actual, "onClose");
-					}
-				};
-				doh.robot.sequence(d.getTestCallback(checkKeystrokes), 500);
-				return d;
-			};
-
-			that.a11yNavExpandCollapseTearDown = function(){
-				dojo.disconnect(that.openConnect);
-				dojo.disconnect(that.closeConnect);
-			};
-
-			var expectedNode;
-			var actualNode;
-			var arrowDownCount;
-			var arrowRightCount;
-
-			that.a11yNavToLeafSetup = function(inTreeId){
-				var tree = dijit.byId(inTreeId);
-				// randomly choose a top-level node to traverse.
-				arrowDownCount = Math.floor(Math.random() * tree.rootNode.getChildren().length);
-				var path = [];
-				expectedNode = walkTreeToLeaf(tree, tree.rootNode.getChildren()[arrowDownCount], path);
-				that.collapseAllButRoot(tree);
-				if(tree.showRoot){
-					tree.focusNode(tree.rootNode);
-					arrowDownCount++;
-				}else{
-					tree.focusNode(tree.rootNode.getChildren()[0]);
-				}
-				// 1 to open root node, 2 for every non-leaf, 1 to get to the leaf
-				arrowRightCount = 1 + (path.length - 2)*2 + 1;
-				that.focusConnect = tree.connect(expectedNode.labelNode, "onfocus", function(evt){
-					actualNode = evt.target;
-				});
-			};
-
-			that.a11yNavToLeaf = function(inTreeId){
-				var d = new doh.Deferred();
-				var tree = dijit.byId(inTreeId);
-				// assume (1) collapseAllButRoot(), and (2) focus is on a top level tree node.
-				for(var i = 0; i < arrowDownCount; i++){
-					doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
-				}
-				for(i = 0; i < arrowRightCount; i++){
-					doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);
-				}
-				var checkLeaf = function(){
-					tree.disconnect(that.focusConnect);
-					doh.is(expectedNode.labelNode, actualNode, "expected: " + expectedNode.label + ", actual: " + actualNode.innerHTML);
-				};
-				doh.robot.sequence(d.getTestCallback(checkLeaf), 500);
-				return d;
-			};
-
-			that.lastVisibleNode = function(inTree){
-				var node = inTree.rootNode;
-				while(node.isExpanded){
-					var c = node.getChildren();
-					node = c[c.length-1];
-				}
-				return node;
-			};
-
-			that.a11yHomeEndKeySetup = function(inTreeId, inKey){
-				// put focus on an random leaf.
-				var tree = dijit.byId(inTreeId);
-				that.collapseAllButRoot(tree);
-				var topLvl = Math.floor(Math.random() * tree.rootNode.getChildren().length);
-				var leaf = walkTreeToLeaf(tree, tree.rootNode.getChildren()[topLvl]);
-				tree.focusNode(leaf);
-				// determine the expected/actual home.
-				if(inKey == dojo.keys.HOME){
-					expectedNode = ( tree.showRoot ? tree.rootNode : tree.rootNode.getChildren()[0] );
-				}else{
-					expectedNode = that.lastVisibleNode(tree);
-				}
-				focusConnect = tree.connect(expectedNode.labelNode, "onfocus", function(evt){
-					actualNode = evt.target;
-				});
-			};
-
-			that.a11yHomeEndKeyTest = function(inTreeId, inKey){
-				var d = new doh.Deferred();
-				var tree = dijit.byId(inTreeId);
-				doh.robot.keyPress(inKey, 300);
-				var checkAtHomeEnd = function(){
-					tree.disconnect(focusConnect);
-					doh.is(expectedNode.label, actualNode.innerHTML);
-				};
-				doh.robot.sequence(d.getTestCallback(checkAtHomeEnd), 500);
-				return d;
-			};
-
-			return that;
-		}
+			var registry, focus, mytree;
 
-		dojo.ready(function(){
-			doh.robot.initRobot('../test_Tree.html');
-			var treeTest = treeTests();
-
-			doh.register("_setup",{
-				timeout:20000,
-				runTest:function(){
-					var d = new doh.Deferred();
-					var store = dijit.byId('mytree3').get('store');
-					store.fetch({query:{id:'*'}, onComplete:function(){
-						d.callback(true);
-					}});
-					return d;
+			doh.register("_setup", [
+				{
+					name: "wait for widgets to load",
+					timeout: 20000,
+					runTest: helpers.waitForLoad
+				},
+				function setVars(){
+					registry = robot.window.require("dijit/registry");
+					focus = robot.window.require("dijit/focus");
+					mytree = registry.byId("mytree");
 				}
-			});
+			]);
 
 			// aria role and properties tests.
-			doh.register("a11yAria",
-			[
+			doh.register("a11yAria", [
 				function ariaTreeRole(){
 					for(i=0; i<treeIds.length; i++){
-						var tree = dijit.byId(treeIds[i]), expectedrole = tree.showRoot?'tree':'presentation';
+						var tree = registry.byId(treeIds[i]), expectedrole = tree.showRoot?'tree': 'presentation';
 						doh.is(expectedrole, tree.domNode.getAttribute("role"), tree.id + ": aria role (" + expectedrole + ")");
 					}
+					doh.is("mytree", registry.byId("mytree").domNode.getAttribute("aria-label"), "aria-label on domNode of regular tree");
+					tree = registry.byId("tree2");  // the rootless tree
+					doh.is("tree", tree.rootNode.containerNode.getAttribute("role"), "rootless tree has role on containerNode");
+					doh.is("tree2label", tree.rootNode.containerNode.getAttribute("aria-label"), "rootless tree has aria-label on containerNode");
 				},
 
-				function ariaTreeStateExpanded(){
-					for(i=0; i<treeIds.length; i++){
-						var tree = dijit.byId(treeIds[i]);
-						var wasExpanded = tree.rootNode.isExpanded;
-						tree.rootNode.expand();
-						var nowExpanded = tree.domNode.getAttribute("aria-expanded");
-						tree.rootNode.collapse();
-						var nowCollapsed = tree.domNode.getAttribute("aria-expanded");
-						if(wasExpanded){
-							tree.rootNode.expand();
-						}
-						doh.is("true", nowExpanded, tree.id + ": aria state expanded=true");
-						doh.is("false", nowCollapsed, tree.id + ": aria state expanded=false ");
+				{
+					name: "ariaTreeItemStateExpanded",
+					timeout: 8000,
+					runTest: function(){
+						return mytree.expandAll().then(function(){
+							query('[widgetId]', mytree.containerNode).map(registry.byNode).forEach(function(/*TreeNode*/ inItem){
+								if(inItem.isExpandable){
+									doh.is("true", inItem.labelNode.getAttribute("aria-expanded"), inItem.label + "[" + mytree.id + "]: aria state expanded=true");
+								}else{
+									// On IE9 getAttribute("aria-expanded") returns "", on other browsers null
+									var attr = inItem.labelNode.getAttribute("aria-expanded");
+									doh.t(attr === null || attr === "", inItem.label + "[" + mytree.id + "]: aria state expanded=false");
+								}
+							});
+						});
 					}
 				},
 
 				function ariaTreeItemRole(){
 					for(i=0; i<treeIds.length; i++){
-						var tree = dijit.byId(treeIds[i]);
-						treeTest.testTreeItemRole(tree.rootNode, tree);
+						var tree = registry.byId(treeIds[i]);
+						testTreeItemRole(tree.rootNode, tree);
 					}
 				},
 
-				function ariaTreeItemStateExpanded(){
-					for(i=0; i<treeIds.length; i++){
-						var tree = dijit.byId(treeIds[i]);
-						treeTest.testTreeItemExpandedState(tree.rootNode, tree);
+				{
+					name: "ariaTreeItemStateCollapsed",
+					timeout: 8000,
+					runTest: function(){
+						return mytree.collapseAll().then(function(){
+							query('[widgetId]', mytree.containerNode).map(registry.byNode).forEach(function(/*TreeNode*/ inItem){
+								if(inItem.isExpandable){
+									doh.is("false", inItem.labelNode.getAttribute("aria-expanded"), inItem.label + "[" + mytree.id + "]: aria state expanded=false");
+								}else{
+									// On IE9 getAttribute("aria-expanded") returns "", on other browsers null
+									var attr = inItem.labelNode.getAttribute("aria-expanded");
+									doh.t(attr === null || attr === "", inItem.label + "[" + mytree.id + "]: aria state expanded=false");
+								}
+							});
+						});
 					}
 				}
 			]);
 
-			// Keyboard focus robot tests
-			doh.register("a11y tab navigation",
-			[
+			// Basic keyboard navigation:
+			//		- tabbing in/out of tree
+			//		- arrow keys
+			//		- home/end
+			//		- space/enter to select tree nodes (although this is also covered in Tree_selector.html)
+
+			function toggle(func, expanded){
+				return function(){
+					var d = new doh.Deferred();
+
+					var mytree = registry.byId("mytree");
+
+					doh.is(expanded, mytree.focusedChild.isExpanded, "original state");
+
+					func(mytree.focusedChild.click );
+
+					robot.sequence(d.getTestCallback(function(){
+						doh.is(!expanded, mytree.focusedChild.isExpanded, "after state");
+					}), 500);
+
+					return d;
+				};
+			}
+			doh.register("basic keyboard", [
 				{
-					name:"mytreeTabFocusTest",
-					timeout:4000,
-					setUp:function(){
-						treeTest.tabFocusSetup('mytree', false);
-					},
-					runTest:function(){
-						return treeTest.tabFocusA11yTest('mytree');
-					},
-					tearDown:function(){
-						treeTest.tabFocusTearDown();
+					name: "setup",
+					timeout: 8000,
+					runTest: function(){
+						// Close all tree nodes except for Africa and Sudan, South America, and the root node itself
+						return mytree.collapseAll().then(function(){
+							return mytree.set("paths", [
+								["continentRoot", "AF", "SD", "Khartoum"],
+								["continentRoot", "SA", "AR"]				// Argentina
+							]);
+						});
 					}
 				},
+
 				{
-					name:"tree2TabFocusTest",
-					timeout:4000,
-					setUp:function(){
-						treeTest.tabFocusSetup('tree2');
-					},
-					runTest:function(){
-						return treeTest.tabFocusA11yTest('tree2', false);
-					},
-					tearDown:function(){
-						treeTest.tabFocusTearDown();
+					name: "tab in",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						dom.byId("mytree_before", robot.doc).focus();
+
+						robot.keyPress(keys.TAB, 300);			// should go to Continents
+
+						robot.sequence(d.getTestCallback(function(){
+							var curNode = focus.curNode;
+							doh.is("Continents", curNode.innerHTML, "focused on continents");
+						}), 500);
+
+						return d;
 					}
 				},
+
 				{
-					name:"mytreeExpandedTabFocusTest",
-					timeout:4000,
-					setUp:function(){
-						treeTest.tabFocusSetup('mytree', true);
-					},
-					runTest:function(){
-						return treeTest.tabFocusA11yTest('mytree');
-					},
-					tearDown:function(){
-						treeTest.tabFocusTearDown();
+					name: "down arrow #1",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						robot.keyPress(keys.DOWN_ARROW, 300);		// move down to Africa
+
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("Africa", mytree.focusedChild.label, "Africa is focused");
+						}), 500);
+
+						return d;
 					}
 				},
+
 				{
-					name:"tree2ExpandedTabFocusTest",
-					timeout:4000,
-					setUp:function(){
-						treeTest.tabFocusSetup('tree2', true);
-					},
-					runTest:function(){
-						return treeTest.tabFocusA11yTest('tree2');
-					},
-					tearDown:function(){
-						treeTest.tabFocusTearDown();
+					name: "left arrow",
+					timeout: 6000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						doh.t(mytree.focusedChild.isExpanded, "initially expanded");
+
+						// first left arrow closes Africa, without moving focus
+						robot.keyPress(keys.LEFT_ARROW, 300);
+						robot.sequence(d.getTestErrback(function(){
+							doh.f(mytree.focusedChild.isExpanded, "now it's closed");
+							doh.is("Africa", mytree.focusedChild.label, "still on Africa");
+						}), 1000);
+
+						// second left arrow goes to Africa's parent
+						robot.keyPress(keys.LEFT_ARROW, 300);
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("Continents", mytree.focusedChild.label, "goes to parent");
+						}), 500);
+
+						return d;
 					}
-				}
-			]);
+				},
 
-			// Keyboard navigate/expand/collapse robot tests (arrow keys, and home/end)
-			doh.register("keyboard arrow navigation/expand/collapse",
-			[
 				{
-					name:"mytreeNavExpandCollpaseA11y",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yNavExpandCollapseSetup('mytree');
-					},
-					runTest:function(){
-						return treeTest.a11yNavExpandCollapseTest('mytree');
-					},
-					tearDown: function(){
-						treeTest.a11yNavExpandCollapseTearDown();
+					name: "right arrow",
+					timeout: 6000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						// move from Continents to Africa
+						robot.keyPress(keys.RIGHT_ARROW, 300);
+
+						robot.sequence(d.getTestErrback(function(){
+							doh.is("Africa", focus.curNode.innerHTML, "Africa is focused");
+						}), 500);
+
+						// expand Africa node, focus still on Africa
+						robot.keyPress(keys.RIGHT_ARROW, 300);
+
+						robot.sequence(d.getTestErrback(function(){
+							doh.t(mytree.focusedChild.isExpanded, "now it's expanded");
+							doh.is("Africa", focus.curNode.innerHTML, "Africa still focused");
+						}), 1000);
+
+						// next right arrow (or down arrow) will move to child
+						robot.keyPress(keys.RIGHT_ARROW, 300);
+
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("Egypt", mytree.focusedChild.label, "Egypt is focused");
+						}), 500);
+
+						return d;
 					}
 				},
+
 				{
-					name:"tree2NavExpandCollpaseA11y",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yNavExpandCollapseSetup('tree2');
-					},
-					runTest:function(){
-						return treeTest.a11yNavExpandCollapseTest('tree2');
-					},
-					tearDown: function(){
-						treeTest.a11yNavExpandCollapseTearDown();
+					name: "down arrow #2",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						// testing that down arrow goes through all visible nodes, popping up and down parent-child
+						// hierarchy
+
+						// Tests that down arrow goes to child, ie from Sudan to Khartoum
+						robot.keyPress(keys.DOWN_ARROW, 300);
+						robot.keyPress(keys.DOWN_ARROW, 300);
+						robot.keyPress(keys.DOWN_ARROW, 300);
+
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("Khartoum", mytree.focusedChild.label, "went down to child of Sudan");
+						}), 500);
+
+						return d;
 					}
 				},
+
+				{
+					name: "select Khartoum",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						robot.keyPress(keys.ENTER, 300);			// select it
+
+						robot.sequence(d.getTestCallback(function(){
+							var item = mytree.get("selectedItem"),
+									label = mytree.model.getLabel(item);
+							doh.is("Khartoum", label, "selected");
+							doh.is("Khartoum", mytree.focusedChild.label, "and still focused");
+						}), 500);
+
+						return d;
+					}
+				},
+
+				{
+					name: "down arrow #3",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						// Test that down arrow pops up two levels
+						robot.keyPress(keys.DOWN_ARROW, 300);
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("Asia", mytree.focusedChild.label, "popped up to great uncle of Khartoum");
+
+							var item = mytree.get("selectedItem"),
+									label = mytree.model.getLabel(item);
+							doh.is("Khartoum", label, "but Khartoum is still selected");
+						}), 500);
+
+						return d;
+					}
+				},
+
+				{
+					name: "ENTER to open",
+					timeout: 4000,
+					runTest: toggle(function(){
+						robot.keyPress(keys.ENTER, 300);        // since openOnClick==true, this opens the node
+					}, false)
+				},
+
 				{
-					name:"mytreeNavToLeaf",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yNavToLeafSetup('mytree');
-					},
-					runTest:function(){
-						return treeTest.a11yNavToLeaf('mytree');
+					name: "ENTER to close",
+					timeout: 4000,
+					runTest: toggle(function(){
+						robot.keyPress(keys.ENTER, 300);        // since openOnClick==true, this closes the node
+					}, true)
+				},
+
+				{
+					name: "up arrow",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						// up arrow should go to node visually above current node, not necessarily it's
+						// previous sibling
+						robot.keyPress(keys.UP_ARROW, 300);
+						robot.sequence(d.getTestErrback(function(){
+							doh.is("Khartoum", focus.curNode.innerHTML, "not Africa");
+						}), 500);
+
+
+						robot.keyPress(keys.UP_ARROW, 300);
+
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("Sudan", focus.curNode.innerHTML, "not Africa");
+						}), 500);
+
+						return d;
 					}
 				},
+
 				{
-					name:"tree2NavToLeaf",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yNavToLeafSetup('tree2');
-					},
-					runTest:function(){
-						return treeTest.a11yNavToLeaf('tree2');
+					name: "end",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						robot.keyPress(keys.END, 300);
+
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("Argentina", focus.curNode.innerHTML);
+						}), 500);
+
+						return d;
 					}
 				},
+
 				{
-					name:"mytreeNavToHome",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yHomeEndKeySetup('mytree', dojo.keys.HOME);
-					},
-					runTest:function(){
-						return treeTest.a11yHomeEndKeyTest('mytree', dojo.keys.HOME);
+					name: "home",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						robot.keyPress(keys.HOME, 300);			// go to Continents
+
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("Continents", focus.curNode.innerHTML, "Africa is focused");
+						}), 500);
+
+						return d;
 					}
 				},
+
 				{
-					name:"mytreeNavToEnd",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yHomeEndKeySetup('mytree', dojo.keys.END);
-					},
-					runTest:function(){
-						return treeTest.a11yHomeEndKeyTest('mytree', dojo.keys.END);
+					name: "tab out",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						robot.keyPress(keys.TAB, 300);
+
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("mytreeDestroyButton", focus.curNode.id);
+						}), 500);
+
+						return d;
 					}
 				},
+
 				{
-					name:"tree2NavToHome",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yHomeEndKeySetup('tree2', dojo.keys.HOME);
-					},
-					runTest:function(){
-						return treeTest.a11yHomeEndKeyTest('tree2', dojo.keys.HOME);
+					name: "shift-tab in",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						robot.keyPress(keys.TAB, 300, {shift: true});
+
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("Continents", focus.curNode.innerHTML, "focused on continents");
+						}), 500);
+
+						return d;
 					}
 				},
+
 				{
-					name:"tree2NavToEnd",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yHomeEndKeySetup('tree2', dojo.keys.END);
-					},
-					runTest:function(){
-						return treeTest.a11yHomeEndKeyTest('tree2', dojo.keys.END);
+					name: "shift-tab out",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						robot.keyPress(keys.TAB, 300, {shift: true});
+
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("mytree_before", focus.curNode.id, "focus went to input before tree");
+							query(".dijitTreeLabel", "mytree").every(function(node, idx){
+								var ti = node.getAttribute("tabindex");
+								doh.is("-1", ti, "-1 tab index on TreeNode" + idx);
+							});
+							doh.is(0, mytree.domNode.getAttribute("tabindex"), "0 tabindex on Tree.domNode itself");
+						}), 500);
+
+						return d;
 					}
 				}
 			]);
 
+			// TODO: tests on tree with showRoot=false
+
 			// Test for typing "a" to navigate to nodes that start with "a", etc.
-			doh.register("keyboard search tests",
-			[
+			doh.register("keyboard search tests", [
 				{
-					name:"Setup tree",
-					timeout:4000,
-					runTest:function(){
+					name: "Setup tree",
+					timeout: 4000,
+					runTest: function(){
 						var d = new doh.Deferred();
 
-						var tree = dijit.byId("mytree");
+						var tree = registry.byId("mytree");
 
 						// Close all tree nodes except for Asia and Oceania
-						dojo.forEach(tree.rootNode.getChildren(), function(child, idx){
+						array.forEach(tree.rootNode.getChildren(), function(child, idx){
 							if(child.label == "Asia" || child.label == "Oceania"){
 								console.log("expanding " + child.label);
 								if(!child.isExpanded){
@@ -553,7 +449,7 @@
 							}
 						});
 
-						doh.robot.sequence(d.getTestCallback(function(){
+						robot.sequence(d.getTestCallback(function(){
 							// Just waiting for animation to finish...
 						}), 500);
 
@@ -561,16 +457,15 @@
 					}
 				},
 				{
-					name:"Focus on Continents",
-					timeout:4000,
-					runTest:function(){
+					name: "Focus on Continents",
+					timeout: 4000,
+					runTest: function(){
 						var d = new doh.Deferred();
 
-						var tree = dijit.byId("mytree");
+						var tree = registry.byId("mytree");
 						tree.focusNode(tree.rootNode);
 
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dojo.global.dijit.focus.curNode;
+						robot.sequence(d.getTestCallback(function(){
 							doh.t(tree.rootNode.labelNode, "focused on continents");
 						}), 500);
 
@@ -578,196 +473,149 @@
 					}
 				},
 				{
-					name:"First 'A' key goes to Africa",
-					timeout:4000,
-					runTest:function(){
+					name: "First 'A' key goes to Africa",
+					timeout: 4000,
+					runTest: function(){
 						var d = new doh.Deferred();
 
 						// From Continents node, press "A".   Should go to Africa.
-						doh.robot.keyPress("a", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Africa", focus.label);
+						robot.keyPress("a", 100);
+						robot.sequence(d.getTestCallback(function(){
+							var focusedWidget = registry.getEnclosingWidget(focus.curNode);
+							doh.t(focusedWidget, "there is a focused widget");
+							doh.is("Africa", focusedWidget.label);
 						}), 500);
 
 						return d;
 					}
 				},
 				{
-					name:"Second 'A' key goes to Asia",
-					timeout:4000,
-					runTest:function(){
+					name: "Second 'A' key goes to Asia",
+					timeout: 4000,
+					runTest: function(){
 						var d = new doh.Deferred();
 
 						// From Africa node, press "A" again.   Should go to Asia.
-						doh.robot.keyPress("a", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Asia", focus.label);
+						robot.keyPress("a", 100);
+						robot.sequence(d.getTestCallback(function(){
+							var focusedWidget = registry.getEnclosingWidget(focus.curNode);
+							doh.t(focusedWidget, "there is a focused widget");
+							doh.is("Asia", focusedWidget.label);
 						}), 500);
 
 						return d;
 					}
 				},
 				{
-					name:"Third 'A' key goes to Australia (nested node)",
-					timeout:4000,
-					runTest:function(){
+					name: "Third 'A' key goes to Australia (nested node)",
+					timeout: 4000,
+					runTest: function(){
 						var d = new doh.Deferred();
 
-						var oceania = dijit.byId("mytree").rootNode.getChildren()[2];
+						var oceania = registry.byId("mytree").rootNode.getChildren()[2];
 						doh.t(oceania, "found Oceania node");
 						doh.t(oceania.isExpanded, "Oceania node is expanded");
 
-						doh.robot.keyPress("a", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Australia", focus.label);
+						robot.keyPress("a", 100);
+						robot.sequence(d.getTestCallback(function(){
+							var focusedWidget = registry.getEnclosingWidget(focus.curNode);
+							doh.t(focusedWidget, "there is a focused widget");
+							doh.is("Australia", focusedWidget.label);
 						}), 500);
 
 						return d;
 					}
 				},
 				{
-					name:"Fourth 'A' key loops back to Africa",
-					timeout:4000,
-					runTest:function(){
+					name: "Fourth 'A' key loops back to Africa",
+					timeout: 4000,
+					runTest: function(){
 						var d = new doh.Deferred();
 
-						doh.robot.keyPress("a", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Africa", focus.label);
+						robot.keyPress("a", 100);
+						robot.sequence(d.getTestCallback(function(){
+							var focusedWidget = registry.getEnclosingWidget(focus.curNode);
+							doh.t(focusedWidget, "there is a focused widget");
+							doh.is("Africa", focusedWidget.label);
 						}), 500);
 
 						return d;
 					}
 				},
 				{
-					name:"multi-key navigation",
-					timeout:4000,
-					runTest:function(){
+					name: "multi-key navigation (co)",
+					timeout: 4000,
+					runTest: function(){
 						var d = new doh.Deferred();
 
-						// Skip over China and go to Continents
-						doh.robot.typeKeys("co", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Continents", focus.label);
-						}), 500);
+						// After the 500ms delay above plus 750 delay here, character should start a new search.
+						// Skip over China and go to Continents.
+						robot.typeKeys("co", 750);
 
-						return d;
-					}
-				},
-				{
-					name:"multi-key navigation",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						// By typing AS should skip over Africa and go to Asia
-						doh.robot.typeKeys("as", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Asia", focus.label);
+						robot.sequence(d.getTestCallback(function(){
+							var focusedWidget = registry.getEnclosingWidget(focus.curNode);
+							doh.t(focusedWidget, "there is a focused widget");
+							doh.is("Continents", focusedWidget.label);
 						}), 500);
 
 						return d;
 					}
 				},
 				{
-					name:"multi-key navigation clears",
-					timeout:4000,
-					runTest:function(){
+					name: "multi-key navigation (as)",
+					timeout: 4000,
+					runTest: function(){
 						var d = new doh.Deferred();
 
-						// After the 500ms delay from above, typing a new character should
-						// start a new search
-						doh.robot.typeKeys("n", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit.focus.curNode);
-							doh.t(focus, "there is a focused widget");
-							doh.is("North America", focus.label);
-						}), 500);
+						// After the 500ms delay above plus 750 delay here, character should start a new search.
+						// By typing AS should skip over Africa and go to Asia.
+						robot.typeKeys("as", 750);
 
-						return d;
-					}
-				}
-			]);
-
-			doh.register("selection and focus",
-			[
-				{
-					name:"select Africa",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						var tree = dijit.byId("mytree");
-
-						doh.robot.keyPress(dojo.keys.HOME, 300);			// go to Continents
-						doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse tree, if it's open
-						doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
-						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down to Africa
-						doh.robot.keyPress(dojo.keys.ENTER, 300);			// select it
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is("Africa", tree.lastFocused.label, "Africa is focused");
-
-							var item = tree.get("selectedItem"),
-								label = tree.model.getLabel(item);
-							doh.is("Africa", label, "Africa is selected");
+						robot.sequence(d.getTestCallback(function(){
+							var focusedWidget = registry.getEnclosingWidget(focus.curNode);
+							doh.t(focusedWidget, "there is a focused widget");
+							doh.is("Asia", focusedWidget.label);
 						}), 500);
 
 						return d;
 					}
 				},
-
 				{
-					name:"focus Asia",
-					timeout:4000,
-					runTest:function(){
+					name: "multi-key navigation clears",
+					timeout: 4000,
+					runTest: function(){
 						var d = new doh.Deferred();
 
-						var tree = dijit.byId("mytree");
-
-						if(tree.lastFocused.isExpanded){
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse tree, if it's open
-						}
-						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down to Asia
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is("Asia", tree.lastFocused.label, "Asia is focused");
+						// After the 500ms delay above plus 750 delay here, character should start a new search
+						robot.typeKeys("n", 750);
 
-							var item = tree.get("selectedItem"),
-								label = tree.model.getLabel(item);
-							doh.is("Africa", label, "but Africa is still selected");
+						robot.sequence(d.getTestCallback(function(){
+							var focusedWidget = registry.getEnclosingWidget(focus.curNode);
+							doh.t(focusedWidget, "there is a focused widget");
+							doh.is("North America", focusedWidget.label);
 						}), 500);
 
 						return d;
 					}
-				},
+				}
+			]);
 
+			doh.register("keyboard on auto expand tree", [
 				{
-					name:"select Asia",
-					timeout:4000,
-					runTest:function(){
+					name: "end key",
+					timeout: 4000,
+					runTest: function(){
 						var d = new doh.Deferred();
 
-						var tree = dijit.byId("mytree");
+						var node = dom.byId("mytree3_before", robot.doc);
+						winUtils.scrollIntoView(node);
+						node.focus();
+
+						robot.keyPress(keys.TAB, 300);			// go to start of tree
+						robot.keyPress(keys.END, 300);			// go to end
 
-						doh.robot.keyPress(dojo.keys.ENTER, 300);			// select it
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							var item = tree.get("selectedItem"),
-								label = tree.model.getLabel(item);
-							doh.is("Asia", label, "after ENTER focus shifted from Africa to Asia");
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("Argentina", robot.window.require("dijit/focus").curNode.innerHTML, "end key went to this node");
 						}), 500);
 
 						return d;
diff --git a/dijit/tests/tree/robot/Tree_dnd.html b/dijit/tests/tree/robot/Tree_dnd.html
index ee6517b..ba4312b 100644
--- a/dijit/tests/tree/robot/Tree_dnd.html
+++ b/dijit/tests/tree/robot/Tree_dnd.html
@@ -2,27 +2,24 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Tree DnD Test</title>
+		<title>robot Tree DnD Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
 		</style>
 
-		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-		<script type="text/javascript" src="Tree_dnd.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.window");
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dom", "dojo/dom-class", "dojo/dom-geometry", "dojo/keys", "dojo/sniff", "dojo/window",
+				"dijit/tests/helpers", "./Tree_dnd", "dojo/domReady!"
+			], function(doh, robot, dom, domClass, domGeom, keys, has, winUtils, helpers, dndHelpers){
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Tree_DnD.html');
+				robot.initRobot('../test_Tree_DnD.html');
 
-				setup();
+				dndHelpers.setup();
 
 				// Dragging from an external source and dropping onto the Tree,
 				// creating a duplicate of the dragged item
@@ -33,28 +30,28 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								fruitsTreeNode = findTreeNode("itemTree", "Fruits");
+								fruitsTreeNode = dndHelpers.findTreeNode("itemTree", "Fruits");
 							doh.f(fruitsTreeNode.isExpanded, "fruitsTreeNode is initially closed");
 							doh.t(fruitsTreeNode.isExpandable, "but has (or may have) children");
 
 							// Check state of store too
-							var children = getNamesOfChildrenOfItem("Fruits");
+							var children = dndHelpers.getNamesOfChildrenOfItem("Fruits");
 							doh.is(1, children.categories.length, "one category child");
 							doh.is("Citrus", children.categories[0]);
 							doh.is(0, children.items.length, "no item children yet");
 
 							// (Try to) make sure drag source and drop source are both in viewport
-							dojo.window.scrollIntoView(fruitsTreeNode.domNode);
+							winUtils.scrollIntoView(fruitsTreeNode.domNode);
 
 							// Drag "Apple" onto Fruits.
-							doh.robot.mouseMoveAt("1001", 500, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(fruitsTreeNode.labelNode, 500, 2000);
+							robot.mouseMoveAt("1001", 500, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(fruitsTreeNode.labelNode, 500, 2000);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// TODO: check drag avatar shows drop is valid (ie, avatar is green)
-								doh.t(dojo.hasClass(fruitsTreeNode.rowNode, "dijitTreeRowHover"), "tree node has hover class");
-								doh.t(dojo.hasClass(fruitsTreeNode.rowNode, "dojoDndItemOver"), "tree node has DND drop class");
+								doh.t(domClass.contains(fruitsTreeNode.rowNode, "dijitTreeRowHover"), "tree node has hover class");
+								doh.t(domClass.contains(fruitsTreeNode.rowNode, "dojoDndItemOver"), "tree node has DND drop class");
 							}), 500);
 
 							return d;
@@ -66,24 +63,24 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mouseRelease({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// Check that new item was created and added to the store.
-								var children = getNamesOfChildrenOfItem("Fruits");
+								var children = dndHelpers.getNamesOfChildrenOfItem("Fruits");
 								doh.is(1, children.categories.length, "one category child");
 								doh.is("Citrus", children.categories[0]);
 								doh.is(1, children.items.length, "one item child");
 								doh.is("Apple", children.items[0]);
 
 								// Check that data store update was reflected in the tree
-								var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
+								var fruitsTreeNode = dndHelpers.findTreeNode("itemTree", "Fruits");
 
 								doh.t(fruitsTreeNode.isExpanded, "drop caused the node to expand");
 								var treeNodeChildren = fruitsTreeNode.getChildren();
 								doh.is(2, treeNodeChildren.length, "2 TreeNode children");
-								doh.is("Apple", innerText(treeNodeChildren[0].labelNode));
-								doh.is("Citrus", innerText(treeNodeChildren[1].labelNode));
+								doh.is("Apple", helpers.innerText(treeNodeChildren[0].labelNode));
+								doh.is("Citrus", helpers.innerText(treeNodeChildren[1].labelNode));
 							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node
 
 							return d;
@@ -99,44 +96,44 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								fruitsTreeNode = findTreeNode("itemTree", "Fruits"),
-								appleTreeNode = findTreeNode("itemTree", "Apple"),
-								citrusTreeNode = findTreeNode("itemTree", "Citrus");
-							dojo.window.scrollIntoView("itemTree");
+								fruitsTreeNode = dndHelpers.findTreeNode("itemTree", "Fruits"),
+								appleTreeNode = dndHelpers.findTreeNode("itemTree", "Apple"),
+								citrusTreeNode = dndHelpers.findTreeNode("itemTree", "Citrus");
+							winUtils.scrollIntoView("itemTree");
 							// Drag "Apple" into "Citrus".
-							doh.robot.mouseMoveAt(appleTreeNode.labelNode, 500, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(citrusTreeNode.labelNode, 500, 1000);
-							doh.robot.mouseMoveAt(citrusTreeNode.labelNode, 500, 1000);// If prev. mouseMove caused scroll, readjust
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mouseMoveAt(appleTreeNode.labelNode, 500, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(citrusTreeNode.labelNode, 500, 1000);
+							robot.mouseMoveAt(citrusTreeNode.labelNode, 500, 1000);// If prev. mouseMove caused scroll, readjust
+							robot.mouseRelease({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								var myStore = dojo.global.myStore;
+							robot.sequence(d.getTestCallback(function(){
+								var myStore = robot.window.myStore;
 
 								// Check that data store item was orphaned from Fruits
-								var fruitsItemChildren = getNamesOfChildrenOfItem("Fruits");
+								var fruitsItemChildren = dndHelpers.getNamesOfChildrenOfItem("Fruits");
 								doh.is(0, fruitsItemChildren.items.length, "no item children");
 
 								// Check that data store update was reflected in the tree
-								var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
+								var fruitsTreeNode = dndHelpers.findTreeNode("itemTree", "Fruits");
 
 								var fruitsTreeNodeChildren = fruitsTreeNode.getChildren();
 								doh.is(1, fruitsTreeNodeChildren.length, "1 TreeNode children");
-								doh.is("Citrus", innerText(fruitsTreeNodeChildren[0].labelNode));
+								doh.is("Citrus", helpers.innerText(fruitsTreeNodeChildren[0].labelNode));
 
 								// ... and parented to Citrus item
-								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								var citrusItemChildren = dndHelpers.getNamesOfChildrenOfItem("Citrus");
 								doh.is(2, citrusItemChildren.items.length, "two item children");
 								doh.is("Orange", citrusItemChildren.items[0]);
 								doh.is("Apple", citrusItemChildren.items[1]);
 
 								// Check that data store update was reflected in the tree
-								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
+								var citrusTreeNode = dndHelpers.findTreeNode("itemTree", "Citrus");
 
 								var citrusTreeNodeChildren = citrusTreeNode.getChildren();
 								doh.is(2, citrusTreeNodeChildren.length, "2 TreeNode children for Citrus");
-								doh.is("Orange", innerText(citrusTreeNodeChildren[0].labelNode), "child of Citrus TreeNode");
-								doh.is("Apple", innerText(citrusTreeNodeChildren[1].labelNode), "child of Citrus TreeNode");
+								doh.is("Orange", helpers.innerText(citrusTreeNodeChildren[0].labelNode), "child of Citrus TreeNode");
+								doh.is("Apple", helpers.innerText(citrusTreeNodeChildren[1].labelNode), "child of Citrus TreeNode");
 							}), 2000);
 
 							return d;
@@ -149,26 +146,26 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								vegetablesTreeNode = findTreeNode("collectionsTree", "Vegetables (0)"),
-								cerealsTreeNode = findTreeNode("collectionsTree", "Cereals (0)");
+								vegetablesTreeNode = dndHelpers.findTreeNode("collectionsTree", "Vegetables (0)"),
+								cerealsTreeNode = dndHelpers.findTreeNode("collectionsTree", "Cereals (0)");
 
 							// (Try to) make sure drag source and drop source are both in viewport
-							dojo.window.scrollIntoView(cerealsTreeNode.domNode);
+							winUtils.scrollIntoView(cerealsTreeNode.domNode);
 
 							// Drag 'Cereals' and drop near top edge of 'Vegetables'.
 							// It should become Vegetables' prior-sibling
 							// Note: if mousemove duration is too small itemTree doesn't get onmouseout event on IE6/7,
 							// causing subsequent JS exceptions
-							doh.robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 100);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1000, 50, 3);
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 100);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1000, 50, 3);
+							robot.mouseRelease({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								var myStore = dojo.global.myStore;
+							robot.sequence(d.getTestCallback(function(){
+								var myStore = robot.window.myStore;
 
 								// Check that order of children was changed
-								var foodsItemChildren = getNamesOfChildrenOfItem("Foods").categories;
+								var foodsItemChildren = dndHelpers.getNamesOfChildrenOfItem("Foods").categories;
 								doh.is(3, foodsItemChildren.length, "3 categories");
 								doh.is("Fruits", foodsItemChildren[0]);
 								doh.is("Cereals", foodsItemChildren[1]);
@@ -176,12 +173,12 @@
 
 								// Check that data store update was reflected in the tree
 								var
-									foodsTreeNode = findTreeNode("collectionsTree", "Foods (1)"),
+									foodsTreeNode = dndHelpers.findTreeNode("collectionsTree", "Foods (1)"),
 									foodsTreeNodeChildren = foodsTreeNode.getChildren();
 								doh.is(3, foodsTreeNodeChildren.length, "3 TreeNode children");
-								doh.is("Fruits (2)", innerText(foodsTreeNodeChildren[0].labelNode));
-								doh.is("Cereals (0)", innerText(foodsTreeNodeChildren[1].labelNode));
-								doh.is("Vegetables (0)", innerText(foodsTreeNodeChildren[2].labelNode));
+								doh.is("Fruits (2)", helpers.innerText(foodsTreeNodeChildren[0].labelNode));
+								doh.is("Cereals (0)", helpers.innerText(foodsTreeNodeChildren[1].labelNode));
+								doh.is("Vegetables (0)", helpers.innerText(foodsTreeNodeChildren[2].labelNode));
 							}), 2000);
 
 							return d;
@@ -197,11 +194,11 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								fruitsTreeNode = findTreeNode("collectionsTree", "Fruits (2)");
-							doh.robot.mouseMoveAt(fruitsTreeNode.expandoNode, 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
+								fruitsTreeNode = dndHelpers.findTreeNode("collectionsTree", "Fruits (2)");
+							robot.mouseMoveAt(fruitsTreeNode.expandoNode, 0, 1);
+							robot.mouseClick({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// This is just here to wait for the expand operation to take place,
 								// and then notify DOH that we are finished
 							}), 1000);
@@ -215,47 +212,47 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								vegetablesTreeNode = findTreeNode("collectionsTree", "Vegetables (0)"),
-								citrusTreeNode = findTreeNode("collectionsTree", "Citrus (1)"),
-								citrusTreeNodeSize = dojo.contentBox(citrusTreeNode.domNode);
+								vegetablesTreeNode = dndHelpers.findTreeNode("collectionsTree", "Vegetables (0)"),
+								citrusTreeNode = dndHelpers.findTreeNode("collectionsTree", "Citrus (1)"),
+								citrusTreeNodeSize = domGeom.getContentBox(citrusTreeNode.domNode);
 
 							// (Try to) make sure drag source and drop source are both in viewport
-							dojo.window.scrollIntoView(vegetablesTreeNode.domNode);
+							winUtils.scrollIntoView(vegetablesTreeNode.domNode);
 
 							// Drag 'Vegetables' and drop near bottom edge of 'Citrus'.
 							// It should become Citrus' prior-sibling
-							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(citrusTreeNode.domNode, 1000, 2000, 50, citrusTreeNodeSize.h - 2);
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(citrusTreeNode.domNode, 1000, 2000, 50, citrusTreeNodeSize.h - 2);
+							robot.mouseRelease({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								var myStore = dojo.global.myStore;
+							robot.sequence(d.getTestCallback(function(){
+								var myStore = robot.window.myStore;
 
 								// Check that order of children in data store was changed
-								var foodsItemChildren = getNamesOfChildrenOfItem("Foods").categories;
+								var foodsItemChildren = dndHelpers.getNamesOfChildrenOfItem("Foods").categories;
 								doh.is(2, foodsItemChildren.length, "2 categories under foods");
 								doh.is("Fruits", foodsItemChildren[0]);
 								doh.is("Cereals", foodsItemChildren[1]);
 
-								var fruitsItemChildren = getNamesOfChildrenOfItem("Fruits").categories;
+								var fruitsItemChildren = dndHelpers.getNamesOfChildrenOfItem("Fruits").categories;
 								doh.is(2, fruitsItemChildren.length, "2 categories under fruits");
 								doh.is("Citrus", fruitsItemChildren[0]);
 								doh.is("Vegetables", fruitsItemChildren[1]);
 
 								// Check that data store update was reflected in the tree
 								var
-									foodsTreeNode = findTreeNode("collectionsTree", "Foods (1)"),
+									foodsTreeNode = dndHelpers.findTreeNode("collectionsTree", "Foods (1)"),
 									foodsTreeNodeChildren = foodsTreeNode.getChildren();
 								doh.is(2, foodsTreeNodeChildren.length, "2 TreeNode children for foods");
-								doh.is("Fruits (2)", innerText(foodsTreeNodeChildren[0].labelNode));
-								doh.is("Cereals (0)", innerText(foodsTreeNodeChildren[1].labelNode));
+								doh.is("Fruits (2)", helpers.innerText(foodsTreeNodeChildren[0].labelNode));
+								doh.is("Cereals (0)", helpers.innerText(foodsTreeNodeChildren[1].labelNode));
 
-								var fruitsTreeNode = findTreeNode("collectionsTree", "Fruits (2)"),
+								var fruitsTreeNode = dndHelpers.findTreeNode("collectionsTree", "Fruits (2)"),
 								fruitsTreeNodeChildren = fruitsTreeNode.getChildren();
 								doh.is(2, fruitsTreeNodeChildren.length, "2 TreeNode children for fruits");
-								doh.is("Citrus (1)", innerText(fruitsTreeNodeChildren[0].labelNode));
-								doh.is("Vegetables (0)", innerText(fruitsTreeNodeChildren[1].labelNode));
+								doh.is("Citrus (1)", helpers.innerText(fruitsTreeNodeChildren[0].labelNode));
+								doh.is("Vegetables (0)", helpers.innerText(fruitsTreeNodeChildren[1].labelNode));
 							}), 500);
 
 							return d;
@@ -271,24 +268,24 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								vegetablesTreeNode = findTreeNode("collectionsTree", "Vegetables (0)"),
-								foodsTreeNode = dijit.byId("itemTree").rootNode;
+								vegetablesTreeNode = dndHelpers.findTreeNode("collectionsTree", "Vegetables (0)"),
+								foodsTreeNode = registry.byId("itemTree").rootNode;
 
-							doh.robot.mouseMoveAt(vegetablesTreeNode.labelNode, 0, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(foodsTreeNode.labelNode, 500, 1000);
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mouseMoveAt(vegetablesTreeNode.labelNode, 0, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(foodsTreeNode.labelNode, 500, 1000);
+							robot.mouseRelease({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								var myStore = dojo.global.myStore;
+							robot.sequence(d.getTestCallback(function(){
+								var myStore = robot.window.myStore;
 
 								// Check that data store item was orphaned from Fruits
-								var fruitsItemChildren = getNamesOfChildrenOfItem("Fruits");
+								var fruitsItemChildren = dndHelpers.getNamesOfChildrenOfItem("Fruits");
 								doh.is(1, fruitsItemChildren.categories.length, "one fruits child");
 								doh.is("Citrus", fruitsItemChildren.categories[0], "one fruits child");
 
 								// And added to Foods
-								var foodsItemChildren = getNamesOfChildrenOfItem("Foods");
+								var foodsItemChildren = dndHelpers.getNamesOfChildrenOfItem("Foods");
 								doh.is(3, foodsItemChildren.categories.length, "three foods children");
 								doh.is("Fruits", foodsItemChildren.categories[0], "food child");
 								doh.is("Cereals", foodsItemChildren.categories[1], "food child");
@@ -307,15 +304,15 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var orangeTreeNode = findTreeNode("itemTree", "Orange");
+							var orangeTreeNode = dndHelpers.findTreeNode("itemTree", "Orange");
 
-							doh.robot.mouseMoveAt(orangeTreeNode.labelNode, 0, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("itemTree", 500, 500, 5, 100);
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mouseMoveAt(orangeTreeNode.labelNode, 0, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt("itemTree", 500, 500, 5, 100);
+							robot.mouseRelease({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								var org = findTreeNode("itemTree", "Orange");
+							robot.sequence(d.getTestCallback(function(){
+								var org = dndHelpers.findTreeNode("itemTree", "Orange");
 								doh.t( org != null);
 							}), 1000);
 							return d;
@@ -326,26 +323,26 @@
 				// special function to allow dragging within a very short test window
 				function dragSourceToItemTree(srcId, destId, after){
 					var
-						child = dojo.global.dojo.byId(srcId),
+						child = dom.byId(srcId, robot.doc),
 						parent = child.parentNode,
-						childPos = dojo.position(child),
-						parentPos = dojo.position(parent),
-						destTreeNode = findTreeNode("itemTree", destId);
-					dojo.window.scrollIntoView(parent);
+						childPos = domGeom.position(child),
+						parentPos = domGeom.position(parent),
+						destTreeNode = dndHelpers.findTreeNode("itemTree", destId);
+					winUtils.scrollIntoView(parent);
 					parent.scrollTop += childPos.y + childPos.h - parentPos.y - parentPos.h;
-					doh.robot.mouseMoveAt(srcId, 500, 1);
-					doh.robot.mousePress({left: true}, 500);
-					doh.robot.mouseMoveAt(srcId, 1000, 500, (childPos.w >> 1) + 2, childPos.h >> 1); // start drag before scrolling to dest
-					doh.robot.sequence(function(){
-						dojo.window.scrollIntoView("itemTree");
+					robot.mouseMoveAt(srcId, 500, 1);
+					robot.mousePress({left: true}, 500);
+					robot.mouseMoveAt(srcId, 1000, 500, (childPos.w >> 1) + 2, childPos.h >> 1); // start drag before scrolling to dest
+					robot.sequence(function(){
+						winUtils.scrollIntoView("itemTree");
 					}, 0);
-					doh.robot.mouseMoveAt(destTreeNode.labelNode, 500, 1); // move to dest center
-					doh.robot.mouseMoveAt(destTreeNode.labelNode, 500, 500, 0,
+					robot.mouseMoveAt(destTreeNode.labelNode, 500, 1); // move to dest center
+					robot.mouseMoveAt(destTreeNode.labelNode, 500, 500, 0,
 						after
-							? (dojo.position(destTreeNode.domNode).h - dojo.position(destTreeNode.labelNode).y + dojo.position(destTreeNode.domNode).y - 1)
+							? (domGeom.position(destTreeNode.domNode).h - domGeom.position(destTreeNode.labelNode).y + domGeom.position(destTreeNode.domNode).y - 1)
 							: -2
 					);
-					doh.robot.mouseRelease({left: true}, 500);
+					robot.mouseRelease({left: true}, 500);
 				}
 
 				//=================
@@ -362,17 +359,17 @@
 							// Drag "Banana" before Orange.
 							dragSourceToItemTree("1003", "Orange", !"after");
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// Check that data store update was reflected in the tree
-								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
+								var citrusTreeNode = dndHelpers.findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
 								doh.is(3, treeNodeChildren.length, "3 TreeNode children");
-								doh.is("Banana", innerText(treeNodeChildren[0].labelNode));
-								doh.is("Orange", innerText(treeNodeChildren[1].labelNode));
-								doh.is("Apple",  innerText(treeNodeChildren[2].labelNode));
+								doh.is("Banana", helpers.innerText(treeNodeChildren[0].labelNode));
+								doh.is("Orange", helpers.innerText(treeNodeChildren[1].labelNode));
+								doh.is("Apple",  helpers.innerText(treeNodeChildren[2].labelNode));
 
 								// ... and parented to Citrus item
-								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								var citrusItemChildren = dndHelpers.getNamesOfChildrenOfItem("Citrus");
 								doh.is(3, citrusItemChildren.items.length, "three item children");
 								doh.is("Banana", citrusItemChildren.items[0]);
 								doh.is("Orange", citrusItemChildren.items[1]);
@@ -391,18 +388,18 @@
 							// Drag "Tomato" after Banana.
 							dragSourceToItemTree("1004", "Banana", "after");
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// Check that data store update was reflected in the tree
-								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
+								var citrusTreeNode = dndHelpers.findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
 								doh.is(4, treeNodeChildren.length, "4 TreeNode children");
-								doh.is("Banana", innerText(treeNodeChildren[0].labelNode));
-								doh.is("Tomato", innerText(treeNodeChildren[1].labelNode));
-								doh.is("Orange", innerText(treeNodeChildren[2].labelNode));
-								doh.is("Apple",  innerText(treeNodeChildren[3].labelNode));
+								doh.is("Banana", helpers.innerText(treeNodeChildren[0].labelNode));
+								doh.is("Tomato", helpers.innerText(treeNodeChildren[1].labelNode));
+								doh.is("Orange", helpers.innerText(treeNodeChildren[2].labelNode));
+								doh.is("Apple",  helpers.innerText(treeNodeChildren[3].labelNode));
 
 								// ... and parented to Citrus item
-								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								var citrusItemChildren = dndHelpers.getNamesOfChildrenOfItem("Citrus");
 								doh.is(4, citrusItemChildren.items.length, "four item children");
 								doh.is("Banana", citrusItemChildren.items[0]);
 								doh.is("Tomato", citrusItemChildren.items[1]);
@@ -422,19 +419,19 @@
 							// Drag "Pepper" before Orange.
 							dragSourceToItemTree("1005", "Orange", !"after");
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// Check that data store update was reflected in the tree
-								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
+								var citrusTreeNode = dndHelpers.findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
 								doh.is(5, treeNodeChildren.length, "5 TreeNode children");
-								doh.is("Banana", innerText(treeNodeChildren[0].labelNode));
-								doh.is("Tomato", innerText(treeNodeChildren[1].labelNode));
-								doh.is("Pepper", innerText(treeNodeChildren[2].labelNode));
-								doh.is("Orange", innerText(treeNodeChildren[3].labelNode));
-								doh.is("Apple",  innerText(treeNodeChildren[4].labelNode));
+								doh.is("Banana", helpers.innerText(treeNodeChildren[0].labelNode));
+								doh.is("Tomato", helpers.innerText(treeNodeChildren[1].labelNode));
+								doh.is("Pepper", helpers.innerText(treeNodeChildren[2].labelNode));
+								doh.is("Orange", helpers.innerText(treeNodeChildren[3].labelNode));
+								doh.is("Apple",  helpers.innerText(treeNodeChildren[4].labelNode));
 
 								// ... and parented to Citrus item
-								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								var citrusItemChildren = dndHelpers.getNamesOfChildrenOfItem("Citrus");
 								doh.is(5, citrusItemChildren.items.length, "five item children");
 								doh.is("Banana", citrusItemChildren.items[0]);
 								doh.is("Tomato", citrusItemChildren.items[1]);
@@ -455,20 +452,20 @@
 							// Drag "Wheat" after Orange.
 							dragSourceToItemTree("1006", "Orange", "after");
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// Check that data store update was reflected in the tree
-								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
+								var citrusTreeNode = dndHelpers.findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
 								doh.is(6, treeNodeChildren.length, "6 TreeNode children");
-								doh.is("Banana", innerText(treeNodeChildren[0].labelNode));
-								doh.is("Tomato", innerText(treeNodeChildren[1].labelNode));
-								doh.is("Pepper", innerText(treeNodeChildren[2].labelNode));
-								doh.is("Orange", innerText(treeNodeChildren[3].labelNode));
-								doh.is("Wheat",  innerText(treeNodeChildren[4].labelNode));
-								doh.is("Apple",  innerText(treeNodeChildren[5].labelNode));
+								doh.is("Banana", helpers.innerText(treeNodeChildren[0].labelNode));
+								doh.is("Tomato", helpers.innerText(treeNodeChildren[1].labelNode));
+								doh.is("Pepper", helpers.innerText(treeNodeChildren[2].labelNode));
+								doh.is("Orange", helpers.innerText(treeNodeChildren[3].labelNode));
+								doh.is("Wheat",  helpers.innerText(treeNodeChildren[4].labelNode));
+								doh.is("Apple",  helpers.innerText(treeNodeChildren[5].labelNode));
 
 								// ... and parented to Citrus item
-								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								var citrusItemChildren = dndHelpers.getNamesOfChildrenOfItem("Citrus");
 								doh.is(6, citrusItemChildren.items.length, "six item children");
 								doh.is("Banana", citrusItemChildren.items[0]);
 								doh.is("Tomato", citrusItemChildren.items[1]);
@@ -490,21 +487,21 @@
 							// Drag "Corn" before Apple.
 							dragSourceToItemTree("1007", "Apple", !"after");
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// Check that data store update was reflected in the tree
-								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
+								var citrusTreeNode = dndHelpers.findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
 								doh.is(7, treeNodeChildren.length, "7 TreeNode children");
-								doh.is("Banana", innerText(treeNodeChildren[0].labelNode));
-								doh.is("Tomato", innerText(treeNodeChildren[1].labelNode));
-								doh.is("Pepper", innerText(treeNodeChildren[2].labelNode));
-								doh.is("Orange", innerText(treeNodeChildren[3].labelNode));
-								doh.is("Wheat",  innerText(treeNodeChildren[4].labelNode));
-								doh.is("Corn",   innerText(treeNodeChildren[5].labelNode));
-								doh.is("Apple",  innerText(treeNodeChildren[6].labelNode));
+								doh.is("Banana", helpers.innerText(treeNodeChildren[0].labelNode));
+								doh.is("Tomato", helpers.innerText(treeNodeChildren[1].labelNode));
+								doh.is("Pepper", helpers.innerText(treeNodeChildren[2].labelNode));
+								doh.is("Orange", helpers.innerText(treeNodeChildren[3].labelNode));
+								doh.is("Wheat",  helpers.innerText(treeNodeChildren[4].labelNode));
+								doh.is("Corn",   helpers.innerText(treeNodeChildren[5].labelNode));
+								doh.is("Apple",  helpers.innerText(treeNodeChildren[6].labelNode));
 
 								// ... and parented to Citrus item
-								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								var citrusItemChildren = dndHelpers.getNamesOfChildrenOfItem("Citrus");
 								doh.is(7, citrusItemChildren.items.length, "seven item children");
 								doh.is("Banana", citrusItemChildren.items[0]);
 								doh.is("Tomato", citrusItemChildren.items[1]);
@@ -527,22 +524,22 @@
 							// Drag "Spinach" after Apple.
 							dragSourceToItemTree("1008", "Apple", "after");
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// Check that data store update was reflected in the tree
-								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
+								var citrusTreeNode = dndHelpers.findTreeNode("itemTree", "Citrus");
 								var treeNodeChildren = citrusTreeNode.getChildren();
 								doh.is(8, treeNodeChildren.length, "8 TreeNode children");
-								doh.is("Banana", innerText(treeNodeChildren[0].labelNode));
-								doh.is("Tomato", innerText(treeNodeChildren[1].labelNode));
-								doh.is("Pepper", innerText(treeNodeChildren[2].labelNode));
-								doh.is("Orange", innerText(treeNodeChildren[3].labelNode));
-								doh.is("Wheat",  innerText(treeNodeChildren[4].labelNode));
-								doh.is("Corn",   innerText(treeNodeChildren[5].labelNode));
-								doh.is("Apple",  innerText(treeNodeChildren[6].labelNode));
-								doh.is("Spinach",innerText(treeNodeChildren[7].labelNode));
+								doh.is("Banana", helpers.innerText(treeNodeChildren[0].labelNode));
+								doh.is("Tomato", helpers.innerText(treeNodeChildren[1].labelNode));
+								doh.is("Pepper", helpers.innerText(treeNodeChildren[2].labelNode));
+								doh.is("Orange", helpers.innerText(treeNodeChildren[3].labelNode));
+								doh.is("Wheat",  helpers.innerText(treeNodeChildren[4].labelNode));
+								doh.is("Corn",   helpers.innerText(treeNodeChildren[5].labelNode));
+								doh.is("Apple",  helpers.innerText(treeNodeChildren[6].labelNode));
+								doh.is("Spinach",helpers.innerText(treeNodeChildren[7].labelNode));
 
 								// ... and parented to Citrus item
-								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								var citrusItemChildren = dndHelpers.getNamesOfChildrenOfItem("Citrus");
 								doh.is(8, citrusItemChildren.items.length, "eight item children");
 								doh.is("Banana", citrusItemChildren.items[0]);
 								doh.is("Tomato", citrusItemChildren.items[1]);
@@ -566,20 +563,20 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								fruitsTreeNode = findTreeNode("itemTree", "Fruits"),
-								cerealsTreeNode = findTreeNode("itemTree", "Cereals"),
-								tree = dijit.byId("itemTree");
+								fruitsTreeNode = dndHelpers.findTreeNode("itemTree", "Fruits"),
+								cerealsTreeNode = dndHelpers.findTreeNode("itemTree", "Cereals"),
+								tree = registry.byId("itemTree");
 
 							// click fruit item
-							doh.robot.mouseMoveAt(fruitsTreeNode.rowNode, 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt(fruitsTreeNode.rowNode, 0, 1);
+							robot.mouseClick({left: true}, 500);
 
 							// drag cereal node to fruits node
-							doh.robot.mouseMoveAt(cerealsTreeNode.rowNode, 0, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(fruitsTreeNode.rowNode, 500, 1000);
-							doh.robot.mouseRelease({left: true}, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.mouseMoveAt(cerealsTreeNode.rowNode, 0, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(fruitsTreeNode.rowNode, 500, 1000);
+							robot.mouseRelease({left: true}, 500);
+							robot.sequence(d.getTestCallback(function(){
 								doh.t(fruitsTreeNode == cerealsTreeNode.getParent());
 							}), 1000);
 
@@ -592,30 +589,30 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								citrusTreeNode = findTreeNode("itemTree", "Citrus"), 
+								citrusTreeNode = dndHelpers.findTreeNode("itemTree", "Citrus"), 
 								citrusParent = citrusTreeNode.getParent(),
-								orangeTreeNode = findTreeNode("itemTree", "Orange"),
-								appleTreeNode = findTreeNode("itemTree", "Apple"),
-								tree = dijit.byId("itemTree");
+								orangeTreeNode = dndHelpers.findTreeNode("itemTree", "Orange"),
+								appleTreeNode = dndHelpers.findTreeNode("itemTree", "Apple"),
+								tree = registry.byId("itemTree");
 
 							doh.is(citrusTreeNode, orangeTreeNode.getParent(), 'orange is child of citrus');
 
 							// click Citrus item
-							doh.robot.mouseMoveAt(citrusTreeNode.rowNode, 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt(citrusTreeNode.rowNode, 0, 1);
+							robot.mouseClick({left: true}, 500);
 
 							// ctrl-click Orange item
-							doh.robot.mouseMoveAt(orangeTreeNode.rowNode, 0, 1);
-							doh.robot.keyDown(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.keyUp(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
+							robot.mouseMoveAt(orangeTreeNode.rowNode, 0, 1);
+							robot.keyDown(has("mac") ? keys.META : keys.CTRL, 500);
+							robot.mouseClick({left: true}, 500);
+							robot.keyUp(has("mac") ? keys.META : keys.CTRL, 500);
 
 							// drag to Apple Foods
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(appleTreeNode.rowNode, 500, 500);
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(appleTreeNode.rowNode, 500, 500);
+							robot.mouseRelease({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is(citrusParent, citrusTreeNode.getParent(), 'citrus parent should not change');
 								doh.is(citrusTreeNode, orangeTreeNode.getParent(), 'orange should still be under citrus');
 							}), 1000);
@@ -629,29 +626,29 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								citrusTreeNode = findTreeNode("itemTree", "Citrus"),
-								orangeTreeNode = findTreeNode("itemTree", "Orange"),
-								cerealsTreeNode = findTreeNode("itemTree", "Cereals"),
-								tree = dijit.byId("itemTree");
+								citrusTreeNode = dndHelpers.findTreeNode("itemTree", "Citrus"),
+								orangeTreeNode = dndHelpers.findTreeNode("itemTree", "Orange"),
+								cerealsTreeNode = dndHelpers.findTreeNode("itemTree", "Cereals"),
+								tree = registry.byId("itemTree");
 
 							doh.is(citrusTreeNode, orangeTreeNode.getParent(), 'orange is child of citrus');
 
 							// click Citrus category
-							doh.robot.mouseMoveAt(citrusTreeNode.rowNode, 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt(citrusTreeNode.rowNode, 0, 1);
+							robot.mouseClick({left: true}, 500);
 
 							// ctrl-click Orange item
-							doh.robot.mouseMoveAt(orangeTreeNode.rowNode, 0, 1);
-							doh.robot.keyDown(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.keyUp(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
+							robot.mouseMoveAt(orangeTreeNode.rowNode, 0, 1);
+							robot.keyDown(has("mac") ? keys.META : keys.CTRL, 500);
+							robot.mouseClick({left: true}, 500);
+							robot.keyUp(has("mac") ? keys.META : keys.CTRL, 500);
 
 							// drag to Cereals category
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(cerealsTreeNode.rowNode, 500, 500);
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(cerealsTreeNode.rowNode, 500, 500);
+							robot.mouseRelease({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is(cerealsTreeNode, citrusTreeNode.getParent(), 'citrus should be under cereals');
 								doh.is(citrusTreeNode, orangeTreeNode.getParent(), 'orange should still be under citrus');
 							}), 1000);
@@ -665,27 +662,27 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								vegetablesTreeNode = findTreeNode("itemTree", "Vegetables"),
-								cerealsTreeNode = findTreeNode("itemTree", "Cereals"),
-								foodsTreeNode = findTreeNode("itemTree", "Foods"),
-								tree = dijit.byId("itemTree");
+								vegetablesTreeNode = dndHelpers.findTreeNode("itemTree", "Vegetables"),
+								cerealsTreeNode = dndHelpers.findTreeNode("itemTree", "Cereals"),
+								foodsTreeNode = dndHelpers.findTreeNode("itemTree", "Foods"),
+								tree = registry.byId("itemTree");
 
 							// click Vegetables item
-							doh.robot.mouseMoveAt(vegetablesTreeNode.rowNode, 0, 1);
-							doh.robot.mouseClick({left: true}, 500);
+							robot.mouseMoveAt(vegetablesTreeNode.rowNode, 0, 1);
+							robot.mouseClick({left: true}, 500);
 
 							// ctrl-click cereals item
-							doh.robot.mouseMoveAt(cerealsTreeNode.rowNode, 0, 1);
-							doh.robot.keyDown(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.keyUp(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
+							robot.mouseMoveAt(cerealsTreeNode.rowNode, 0, 1);
+							robot.keyDown(has("mac") ? keys.META : keys.CTRL, 500);
+							robot.mouseClick({left: true}, 500);
+							robot.keyUp(has("mac") ? keys.META : keys.CTRL, 500);
 
 							// drag to root item Foods
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(foodsTreeNode.rowNode, 500, 500);
-							doh.robot.mouseRelease({left: true}, 500);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(foodsTreeNode.rowNode, 500, 500);
+							robot.mouseRelease({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								doh.is(foodsTreeNode, vegetablesTreeNode.getParent());
 								doh.is(foodsTreeNode, cerealsTreeNode.getParent());
 							}), 1000);
diff --git a/dijit/tests/tree/robot/Tree_dnd.js b/dijit/tests/tree/robot/Tree_dnd.js
index c4c1675..a238bed 100644
--- a/dijit/tests/tree/robot/Tree_dnd.js
+++ b/dijit/tests/tree/robot/Tree_dnd.js
@@ -2,130 +2,129 @@
  * Helper functions for Tree_dnd.html and Tree_dnd_multiParent.html tests
  */
 
-function setup(){
-	doh.register("setup screen", function(){		
-		// Hide boilerplate text so it's easier to drag on small screen
-		dojo.query("h1,h2,p").style("display", "none");
-	
-		// Disable auto-scrolling because otherwise the viewport scrolls as doh.robot.mouseMoveAt()
-		// moves the mouse, literally making the the drop target a moving target
-		// (and mouseMoveAt() doesn't take this possibility into account).
-		dojo.global.dojo.dnd.autoScrollNodes = function(){};
-	
-		// Scroll viewport to (try to) make sure that both tree and drag-source
-		// are simultaneously in view.
-		var scroll = dojo.position("1001").y;
-		dojo.body().parentNode.scrollTop = scroll;	// works on FF
-		dojo.body().scrollTop = scroll;	// works on safari
-	});
-
-	// Wait for trees to load
-	doh.register("wait for load", dojo.map(["collectionsTree", "itemTree"], function(id){
-		return {
-			name: id,
-			timeout: 10000,
-			runTest: function(){
-				var
-					tree = dijit.byId(id),
-					d, handler;
-				if(!tree.rootNode){
-					d = new doh.Deferred();
-					handler = tree.connect(tree, "onLoad",
-						function(){
-							tree.disconnect(handler);
-							d.callback(true);
-						}
-					);
-					return d;
+define([
+	"doh/runner", "dojo/robotx",
+	"dojo/_base/array", "dojo/dnd/autoscroll", "dojo/dom", "dojo/dom-geometry", "dojo/query", "dojo/_base/window",
+	"dijit/tests/helpers"
+], function(doh, robot, array, autoscroll, dom, domGeom, query, win, helpers){
+
+	var exports = {
+		setup: function setup(){
+			doh.register("setup screen", function(){
+				// Hide boilerplate text so it's easier to drag on small screen
+				query("h1,h2,p", robot.doc).style("display", "none");
+
+				// Disable auto-scrolling because otherwise the viewport scrolls as robot.mouseMoveAt()
+				// moves the mouse, literally making the the drop target a moving target
+				// (and mouseMoveAt() doesn't take this possibility into account).
+				autoscroll.autoScrollNodes = function(){};
+
+				// Scroll viewport to (try to) make sure that both tree and drag-source
+				// are simultaneously in view.
+				var scroll = domGeom.position(dom.byId("1001", robot.doc)).y;
+				win.body(robot.doc).parentNode.scrollTop = scroll;	// works on FF
+				win.body(robot.doc).scrollTop = scroll;	// works on safari
+			});
+
+			// Wait for trees to load
+			doh.register("wait for load",  {
+					name: "wait for load",
+					timeout: 10000,
+					runTest: helpers.waitForLoad
+			});
+			doh.register("setup vars", function(){
+				registry = robot.window.require("dijit/registry");
+			});
+		},
+
+		findTreeNode: function findTreeNode(/*String*/ treeId, /*String*/ label){
+			// summary:
+			//		Find the TreeNode with the specified label in the given tree.
+			//		Assumes that there's only one TreeNode w/that label (i.e. it
+			//		breaks if certain items have multiple parents and appear in the
+			//		tree multiple times)
+			var nodes = query(".dijitTreeLabel", dom.byId(treeId, robot.doc));
+			for(var i=0; i<nodes.length; i++){
+				if(helpers.innerText(nodes[i]) == label){
+					return registry.getEnclosingWidget(nodes[i]);	// TreeNode
 				}
 			}
-		};
-	}));
-}
-
-function findTreeNode(/*String*/ treeId, /*String*/ label){
-	// summary:
-	//		Find the TreeNode with the specified label in the given tree.
-	//		Assumes that there's only one TreeNode w/that label (i.e. it
-	//		breaks if certain items have multiple parents and appear in the
-	//		tree multiple times)
-	var nodes = dojo.query(".dijitTreeLabel", treeId);
-	for(var i=0; i<nodes.length; i++){
-		if(innerText(nodes[i]) == label){
-			return dijit.getEnclosingWidget(nodes[i]);	// TreeNode
-		}
-	}
-	return null;
-}
-
-function findTreeNodeByPath(/*String*/ treeId, /*String[] */ path){
-	// summary:
-	//		Find the TreeNode with the specified path (like ["Fruits", "Apple"] in a tree like:
-	//	|	* Foods
-	//	|		* Vegetbles
-	//	|		* Fruits
-	//	|			* Orange
-	//	|			* Apple
-	//		Path shouldn't include the root node.
-
-	var tree = dijit.byId(treeId);
-	for(var i=0, node=tree.rootNode; i<path.length; i++){
-		var pathElem = path[i], matchingChildNode;
-		for(var j=0, children=node.getChildren(); j < children.length; j++){
-			if(children[j].label == pathElem){
-				matchingChildNode = children[j];
-				break;
-			}
-		}
-		if(!matchingChildNode){
 			return null;
+		},
+
+		findTreeNodeByPath: function findTreeNodeByPath(/*String*/ treeId, /*String[] */ path){
+			// summary:
+			//		Find the TreeNode with the specified path (like ["Fruits", "Apple"] in a tree like:
+			//	|	* Foods
+			//	|		* Vegetables
+			//	|		* Fruits
+			//	|			* Orange
+			//	|			* Apple
+			//		Path shouldn't include the root node.
+
+			var tree = registry.byId(treeId);
+			for(var i=0, node=tree.rootNode; i<path.length; i++){
+				var pathElem = path[i], matchingChildNode;
+				for(var j=0, children=node.getChildren(); j < children.length; j++){
+					if(children[j].label == pathElem){
+						matchingChildNode = children[j];
+						break;
+					}
+				}
+				if(!matchingChildNode){
+					return null;
+				}
+				node = matchingChildNode;
+			}
+			return node;
+		},
+
+		getChildrenOfItem: function getChildrenOfItem(/*String*/ name){
+			// summary:
+			//		Return the children of the data store item w/the specified name
+			//		Note that test_Tree_Dnd.html splits the children up into the "children"
+			//		and "items" attributes.
+
+			// Get the parent item
+			// Note that the ItemFileWriteStore's callback will happen immediately.
+			var myStore = robot.window.myStore,
+				parentItem;
+			myStore.fetch({
+				query: {name: name},
+				onItem: function(item){ parentItem = item; }
+			});
+
+			// Get the children, which are stored in two separate attributes,
+			// categories (like 'Fruits') and items (ie, leaf nodes)  (like 'Apple')
+			return {
+				categories: myStore.getValues(parentItem, 'children'),
+				items: myStore.getValues(parentItem, 'items')
+			};
+		},
+
+		mapItemsToNames: function mapItemsToNames(ary){
+			// summary:
+			//		Convert an array of items into an array of names
+			var myStore = robot.window.myStore;
+			return array.map(ary, function(item){
+				return myStore.getValue(item, "name");
+			});
+		},
+
+		getNamesOfChildrenOfItem: function getNamesOfChildrenOfItem(/*String*/ name){
+			// summary:
+			//		Return the names of the (items that are) children of the item w/the specified name
+
+			// Get the parent item (according to
+			var obj = exports.getChildrenOfItem(name);
+			return {
+				categories: exports.mapItemsToNames(obj.categories),
+				items: exports.mapItemsToNames(obj.items)
+			};
 		}
-		node = matchingChildNode;
-	}
-	return node;
-}
-
-function getChildrenOfItem(/*String*/ name){
-	// summary:
-	//		Return the children of the data store item w/the specified name
-	//		Note that test_Tree_Dnd.html splits the children up into the "children"
-	//		and "items" attributes.
-
-	// Get the parent item
-	// Note that the ItemFileWriteStore's callback will happen immediately.
-	var myStore = dojo.global.myStore,
-		parentItem;
-	myStore.fetch({
-		query: {name: name},
-		onItem: function(item){ parentItem = item; }
-	});
-
-	// Get the children, which are stored in two separate attributes,
-	// categories (like 'Fruits') and items (ie, leaf nodes)  (like 'Apple')
-	return {
-		categories: myStore.getValues(parentItem, 'children'),
-		items: myStore.getValues(parentItem, 'items')
-	};
-}
-
-function mapItemsToNames(ary){
-	// summary:
-	//		Convert an array of items into an array of names
-	var myStore = dojo.global.myStore;
-	return dojo.map(ary, function(item){
-		return myStore.getValue(item, "name");
-	});
-}
-
-function getNamesOfChildrenOfItem(/*String*/ name){
-	// summary:
-	//		Return the names of the (items that are) children of the item w/the specified name
-
-	// Get the parent item (according to
-	var obj = getChildrenOfItem(name);
-	return {
-		categories: mapItemsToNames(obj.categories),
-		items: mapItemsToNames(obj.items)
 	};
-}
+
+	return exports;
+});
+
 
diff --git a/dijit/tests/tree/robot/Tree_dnd_multiParent.html b/dijit/tests/tree/robot/Tree_dnd_multiParent.html
index f3b6a81..b824716 100644
--- a/dijit/tests/tree/robot/Tree_dnd_multiParent.html
+++ b/dijit/tests/tree/robot/Tree_dnd_multiParent.html
@@ -2,27 +2,24 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Tree DnD Multi-parent Test</title>
+		<title>robot Tree DnD Multi-parent Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
 		</style>
 
-		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-		<script type="text/javascript" src="Tree_dnd.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.window");
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/dnd/common", "dojo/dom", "dojo/dom-class", "dojo/keys", "dojo/query", "dojo/sniff",
+				"dijit/tests/helpers", "./Tree_dnd", "dojo/domReady!"
+			], function(doh, robot, dndCommon, dom, domClass, keys, query, has, helpers, dndHelpers){
 
-			dojo.ready(function(){
-				doh.robot.initRobot('../test_Tree_DnD.html');
+				robot.initRobot('../test_Tree_DnD.html');
 
-				setup();
+				dndHelpers.setup();
 
 				doh.register("multi-parent tests", [
 					{
@@ -31,51 +28,51 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								vegetablesTreeNode = findTreeNodeByPath("collectionsTree", ["Vegetables (0)"]),	// the left tree
-								fruitsTreeNode = findTreeNodeByPath("itemTree", ["Fruits"]);	// right tree
+								vegetablesTreeNode = dndHelpers.findTreeNodeByPath("collectionsTree", ["Vegetables (0)"]),	// the left tree
+								fruitsTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits"]);	// right tree
 
-							doh.robot.mouseMoveAt("collectionsTree", 500, 1); // scroll source parent into view
-							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1);
+							robot.mouseMoveAt("collectionsTree", 500, 1); // scroll source parent into view
+							robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1);
 							// Drag and Drop, *copying* in order to add a parent rather than change
-							doh.robot.keyDown(dojo.keys.copyKey, 500);
-							if(dojo.isMac){
+							robot.keyDown(keys.copyKey, 500);
+							if(has("mac")){
 								// I can't get DOH robot to generate the mousePress event w/metaKey=true so
 								// hack it
-								doh.robot.sequence(function(){
-									realIsCopyKey = dojo.global.dojo.isCopyKey;
-									dojo.global.dojo.isCopyKey = function(){ return true; }
+								robot.sequence(function(){
+									realIsCopyKey = dndCommon.getCopyKeyState;
+									dndCommon.getCopyKeyState = function(){ return true; }
 								});
 							}
 
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("itemTree", 500, 500); // move to dest parent to scroll it into view
-							doh.robot.mouseMoveAt(fruitsTreeNode.labelNode, 0, 500);
-							doh.robot.mouseRelease({left: true}, 500);
-							doh.robot.keyUp(dojo.keys.copyKey, 500);
-							if(dojo.isMac){
-								// See if(dojo.isMac) above
-								doh.robot.sequence(function(){
-									dojo.global.dojo.isCopyKey = realIsCopyKey;
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt("itemTree", 500, 500); // move to dest parent to scroll it into view
+							robot.mouseMoveAt(fruitsTreeNode.labelNode, 0, 500);
+							robot.mouseRelease({left: true}, 500);
+							robot.keyUp(keys.copyKey, 500);
+							if(has("mac")){
+								// See if(has("mac")) above
+								robot.sequence(function(){
+									dndCommon.getCopyKeyState = realIsCopyKey;
 								});
 							}
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 								// Check that Vegetables remains a child of Foods
-								var children = getNamesOfChildrenOfItem("Foods");
+								var children = dndHelpers.getNamesOfChildrenOfItem("Foods");
 								doh.is(3, children.categories.length, "foods category child");
 								doh.is("Fruits", children.categories[0]);
 								doh.is("Vegetables", children.categories[1]);
 								doh.is("Cereals", children.categories[2]);
 
 								// Check that Vegetables added as child of Fruits
-								var children2 = getNamesOfChildrenOfItem("Fruits");
+								var children2 = dndHelpers.getNamesOfChildrenOfItem("Fruits");
 								doh.is(2, children2.categories.length, "foods category child");
 								doh.is("Citrus", children2.categories[0]);
 								doh.is("Vegetables", children2.categories[1]);
 
 								// Check that new item *wasn't* created
 								var items;
-								dojo.global.myStore.fetch({
+								robot.window.myStore.fetch({
 									onComplete: function(i){ items = i; }
 								});
 								doh.is(6, items.length, "# of items in store");
@@ -84,8 +81,8 @@
 								doh.t(fruitsTreeNode.isExpanded, "drop caused the node to expand");
 								var treeNodeChildren = fruitsTreeNode.getChildren();
 								doh.is(2, treeNodeChildren.length, "2 TreeNode children");
-								doh.is("Citrus", innerText(treeNodeChildren[0].labelNode));
-								doh.is("Vegetables", innerText(treeNodeChildren[1].labelNode));
+								doh.is("Citrus", helpers.innerText(treeNodeChildren[0].labelNode));
+								doh.is("Vegetables", helpers.innerText(treeNodeChildren[1].labelNode));
 							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node
 
 							return d;
@@ -97,41 +94,41 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								vegetablesTreeNode = findTreeNodeByPath("itemTree", ["Vegetables"]),
-								cerealsTreeNode = findTreeNodeByPath("itemTree", ["Cereals"]);
+								vegetablesTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Vegetables"]),
+								cerealsTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Cereals"]);
 
-							dojo.global.scrollTo(0, 9000); // scroll to bottom to try and prevent the DnD code from autoscrolling
+							robot.window.scrollTo(0, 9000); // scroll to bottom to try and prevent the DnD code from autoscrolling
 
 							// Drag and Drop
-							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1);
-							doh.robot.mouseClick({left: true}, 500); // helps prevent screen jitter
-							doh.robot.mousePress({left: true}, 1000);
-							doh.robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 500, 0, 0); // move mouse slightly to trigger DnD
-							doh.robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 100); // double move to allow for autoscrolling jitter
-							doh.robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 100);
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1);
+							robot.mouseClick({left: true}, 500); // helps prevent screen jitter
+							robot.mousePress({left: true}, 1000);
+							robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 500, 0, 0); // move mouse slightly to trigger DnD
+							robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 100); // double move to allow for autoscrolling jitter
+							robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 100);
+							robot.mouseRelease({left: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
 								// Check that Vegetables remains a child of Fruits
-								var children = getNamesOfChildrenOfItem("Fruits");
+								var children = dndHelpers.getNamesOfChildrenOfItem("Fruits");
 								doh.is(2, children.categories.length, "fruits category child");
 								doh.is("Citrus", children.categories[0]);
 								doh.is("Vegetables", children.categories[1]);
 
 								// Check that Vegetables added as child of Cereals
-								children = getNamesOfChildrenOfItem("Cereals");
+								children = dndHelpers.getNamesOfChildrenOfItem("Cereals");
 								doh.is(1, children.categories.length, "cereals category child");
 								doh.is("Vegetables", children.categories[0]);
 
 								// Check that Vegetables no longer a child of Foods
-								children = getNamesOfChildrenOfItem("Foods");
+								children = dndHelpers.getNamesOfChildrenOfItem("Foods");
 								doh.is(2, children.categories.length, "foods category child");
 								doh.is("Fruits", children.categories[0]);
 								doh.is("Cereals", children.categories[1]);
 
 								// Check that new item *wasn't* created
 								var items;
-								dojo.global.myStore.fetch({
+								robot.window.myStore.fetch({
 									onComplete: function(i){ items = i; }
 								});
 								doh.is(6, items.length, "# of items in store");
@@ -146,38 +143,38 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								vegetablesTreeNode = findTreeNodeByPath("itemTree", ["Fruits", "Vegetables"]),
-								citrusTreeNode = findTreeNodeByPath("itemTree", ["Fruits", "Citrus"]);
+								vegetablesTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits", "Vegetables"]),
+								citrusTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits", "Citrus"]);
 
 							// Drag and Drop
-							doh.robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 1);
-							doh.robot.mouseClick({left: true}, 500); // helps prevent screen jitter
-							doh.robot.mousePress({left: true}, 1000);
-							doh.robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 500, 0, 0); // move mouse slightly to trigger DnD
-							doh.robot.mouseMoveAt(citrusTreeNode.labelNode, 0, 500);
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 1);
+							robot.mouseClick({left: true}, 500); // helps prevent screen jitter
+							robot.mousePress({left: true}, 1000);
+							robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 500, 0, 0); // move mouse slightly to trigger DnD
+							robot.mouseMoveAt(citrusTreeNode.labelNode, 0, 500);
+							robot.mouseRelease({left: true}, 500);
+
+							robot.sequence(d.getTestCallback(function(){
 								// Check that Vegetables remains a child of Cereals
-								var children = getNamesOfChildrenOfItem("Cereals");
+								var children = dndHelpers.getNamesOfChildrenOfItem("Cereals");
 								doh.is(1, children.categories.length, "cereals category child");
 								doh.is("Vegetables", children.categories[0]);
 
 								// Check that Vegetables added as child of Citrus
-								children = getNamesOfChildrenOfItem("Citrus");
+								children = dndHelpers.getNamesOfChildrenOfItem("Citrus");
 								doh.is(1, children.categories.length, "citrus category child");
 								doh.is("Vegetables", children.categories[0]);
 								doh.is(1, children.items.length, "citrus item child");
 								doh.is("Orange", children.items[0]);
 
 								// Check that Vegetables removed as child of Fruits
-								children = getNamesOfChildrenOfItem("Fruits");
+								children = dndHelpers.getNamesOfChildrenOfItem("Fruits");
 								doh.is(1, children.categories.length, "fruits category child");
 								doh.is("Citrus", children.categories[0]);
 
 								// Check that new item *wasn't* created
 								var items;
-								dojo.global.myStore.fetch({
+								robot.window.myStore.fetch({
 									onComplete: function(i){ items = i; }
 								});
 								doh.is(6, items.length, "# of items in store");
@@ -195,24 +192,25 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								fruitsTreeNode = findTreeNodeByPath("itemTree", ["Fruits"]);	// right tree
+								fruitsTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits"]);	// right tree
 
-							doh.robot.mouseMoveAt(dojo.byId("1003").parentNode, 500, 1, 0, 0); // move to source parent node to help prevent DnD autoscrolling
-							doh.robot.mouseMoveAt(dojo.byId("1003"), 500, 1); // move to source banana node
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(dojo.byId("1003").parentNode, 500, 100); //  move just a little to start the DnD operation before scrolling
-							doh.robot.mouseMoveAt("itemTree", 500, 500); // go to target parent top to allow for better scrolling of the destination
-							doh.robot.mouseMoveAt(fruitsTreeNode.labelNode, 1000, 500);
-							doh.robot.mouseRelease({left: true}, 500);
+							var node = dom.byId("1003", robot.doc);
+							robot.mouseMoveAt(node.parentNode, 500, 1, 0, 0); // move to source parent node to help prevent DnD autoscrolling
+							robot.mouseMoveAt(node, 500, 1); // move to source banana node
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(node.parentNode, 500, 100); //  move just a little to start the DnD operation before scrolling
+							robot.mouseMoveAt("itemTree", 500, 500); // go to target parent top to allow for better scrolling of the destination
+							robot.mouseMoveAt(fruitsTreeNode.labelNode, 1000, 500);
+							robot.mouseRelease({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 
-								var children = getChildrenOfItem("Fruits");
+								var children = dndHelpers.getChildrenOfItem("Fruits");
 								doh.is(1, children.items.length, "new item added");
 								doh.is(1003, children.items[0].id, "id of new item came from dropped node");
 								doh.is("Banana", children.items[0].name, "name of new item came from dropped node");
 
-								dojo.global.myStore.fetch({
+								robot.window.myStore.fetch({
 									query: { name: "Banana" },
 									queryOptions: { deep: true },
 									onComplete: function(i){ items = i; }
@@ -229,29 +227,30 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								cerealsTreeNode = findTreeNodeByPath("itemTree", ["Cereals"]);					// right tree
+								cerealsTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Cereals"]);					// right tree
 
-							doh.robot.mouseMoveAt(dojo.byId("1003").parentNode, 500, 1, 0, 0); // move to source parent node to help prevent DnD autoscrolling
-							doh.robot.mouseMoveAt(dojo.byId("1003"), 500, 1); // move to source banana node
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(dojo.byId("1003").parentNode, 500, 100); //  move just a little to start the DnD operation before scrolling
-							doh.robot.mouseMoveAt("itemTree", 500, 100); // go to target parent top to allow for better scrolling of the destination
-							doh.robot.mouseMoveAt(cerealsTreeNode.labelNode, 1000, 500);
-							doh.robot.mouseRelease({left: true}, 500);
+							var node = dom.byId("1003", robot.doc);
+							robot.mouseMoveAt(node.parentNode, 500, 1, 0, 0); // move to source parent node to help prevent DnD autoscrolling
+							robot.mouseMoveAt(node, 500, 1); // move to source banana node
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(node.parentNode, 500, 100); //  move just a little to start the DnD operation before scrolling
+							robot.mouseMoveAt("itemTree", 500, 100); // go to target parent top to allow for better scrolling of the destination
+							robot.mouseMoveAt(cerealsTreeNode.labelNode, 1000, 500);
+							robot.mouseRelease({left: true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.sequence(d.getTestCallback(function(){
 
-								var children = getChildrenOfItem("Cereals");
+								var children = dndHelpers.getChildrenOfItem("Cereals");
 								doh.is(1, children.items.length, "banana is child of cereals");
 								doh.is(1003, children.items[0].id, "id of item came from dropped node");
 								doh.is("Banana", children.items[0].name, "name of new item came from dropped node");
 
-								var children2 = getChildrenOfItem("Fruits");
+								var children2 = dndHelpers.getChildrenOfItem("Fruits");
 								doh.is(1, children2.items.length, "banana still a child of fruits");
 								doh.is(1003, children2.items[0].id, "id of new item came from dropped node");
 								doh.is("Banana", children2.items[0].name, "name of new item came from dropped node");
 
-								dojo.global.myStore.fetch({
+								robot.window.myStore.fetch({
 									query: { name: "Banana" },
 									queryOptions: { deep: true },
 									onComplete: function(i){ items = i; }
@@ -272,36 +271,36 @@
 						runTest: function(){
 							var
 								d = new doh.Deferred(),
-								drag = findTreeNodeByPath("itemTree", ["Cereals", "Vegetables"]),
-								aboveDrop = findTreeNodeByPath("itemTree", ["Fruits", "Citrus"]);
-								drop = findTreeNodeByPath("itemTree", ["Fruits", "Citrus", "Vegetables"]);
+								drag = dndHelpers.findTreeNodeByPath("itemTree", ["Cereals", "Vegetables"]),
+								aboveDrop = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits", "Citrus"]);
+								drop = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits", "Citrus", "Vegetables"]);
 
 							doh.is(drop.item.id, drag.item.id, "both nodes point to same item");
 
 							// Drag bottom vegetables node over Citrus
-							doh.robot.mouseMoveAt(drag.domNode, 500, 1);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(aboveDrop.labelNode, 0, 500);
+							robot.mouseMoveAt(drag.domNode, 500, 1);
+							robot.mousePress({left: true}, 500);
+							robot.mouseMoveAt(aboveDrop.labelNode, 0, 500);
 
-							doh.robot.sequence(d.getTestErrback(function(){
-								var avatar = dojo.query(".dojoDndAvatar");
+							robot.sequence(d.getTestErrback(function(){
+								var avatar = query(".dojoDndAvatar", robot.doc);
 								doh.t(avatar && avatar[0], "avatar found");
-								doh.t(dojo.hasClass(avatar[0], "dojoDndAvatarCanDrop"), "can drop");
+								doh.t(domClass.contains(avatar[0], "dojoDndAvatarCanDrop"), "can drop");
 							}), 500);
 
 							// Now move it to over first Vegetables node.   Should be red icon indicating drop-unallowed
-							doh.robot.mouseMoveAt(drop.labelNode, 0, 500);
-							doh.robot.sequence(d.getTestErrback(function(){
-								var avatar = dojo.query(".dojoDndAvatar");
+							robot.mouseMoveAt(drop.labelNode, 0, 500);
+							robot.sequence(d.getTestErrback(function(){
+								var avatar = query(".dojoDndAvatar", robot.doc);
 								doh.t(avatar && avatar[0], "avatar found");
-								doh.f(dojo.hasClass(avatar[0], "dojoDndAvatarCanDrop"), "can't drop");
+								doh.f(domClass.contains(avatar[0], "dojoDndAvatarCanDrop"), "can't drop");
 							}), 500);
 
 							// Try to drop anyway, and make sure Tree structure doesn't change
-							doh.robot.mouseRelease({left: true}, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
+							robot.mouseRelease({left: true}, 500);
+							robot.sequence(d.getTestCallback(function(){
 								doh.is(0, drop.getChildren().length, "drop node has no children");
-								doh.t(drag == findTreeNodeByPath("itemTree", ["Cereals", "Vegetables"]),
+								doh.t(drag == dndHelpers.findTreeNodeByPath("itemTree", ["Cereals", "Vegetables"]),
 										"drag node still in same place");
 							}), 500);
 
diff --git a/dijit/tests/tree/robot/Tree_mouse.html b/dijit/tests/tree/robot/Tree_mouse.html
new file mode 100644
index 0000000..6607bc9
--- /dev/null
+++ b/dijit/tests/tree/robot/Tree_mouse.html
@@ -0,0 +1,103 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>robot Tree Mouse Test</title>
+
+	<style>
+		@import "../../../../util/doh/robot/robot.css";
+	</style>
+
+	<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner", "dojo/robotx",
+			"dojo/query",
+			"dijit/tests/helpers", "dojo/domReady!"
+		], function(doh, robot, query, helpers){
+
+			robot.initRobot('../test_Tree.html');
+
+			var registry, mytree, africa;
+
+			doh.register("_setup", [
+				{
+					name: "wait for widgets to load",
+					timeout: 20000,
+					runTest: helpers.waitForLoad
+				},
+				function setVars(){
+					registry = robot.window.require("dijit/registry");
+					mytree = registry.byId("mytree");
+
+					// find TreeNode for Africa
+					var node = query(".dijitTreeLabel")[1];
+					africa = registry.getEnclosingWidget(node);
+				}
+			]);
+
+			function toggle(func, expanded){
+				return function(){
+					var d = new doh.Deferred();
+
+					doh.is(expanded, africa.isExpanded, "original state");
+
+					func();
+
+					robot.sequence(d.getTestCallback(function(){
+						doh.is(!expanded, africa.isExpanded, "after state");
+					}), 500);
+
+					return d;
+				};
+			}
+
+			doh.register("label click", [
+				{
+					name: "click to open",
+					timeout: 8000,
+					runTest: toggle(function(){
+						robot.mouseMoveAt(africa.labelNode);
+						robot.mouseClick({left:true}, 100);
+					}, false)
+				},
+
+				{
+					name: "click to close",
+					timeout: 8000,
+					runTest: toggle(function(){
+						robot.mouseClick({left:true}, 100);
+					}, true)
+				},
+
+				{
+					name: "double click to open",
+					timeout: 8000,
+					setUp: function(){
+						mytree.openOnClick = false;
+						mytree.openOnDblClick = true;
+					},
+					runTest: toggle(function(){
+						robot.mouseClick({left:true}, 100);
+						robot.mouseClick({left:true}, 100);
+					}, false)
+				},
+
+				{
+					name: "double click to close",
+					timeout: 8000,
+					runTest: toggle(function(){
+						robot.mouseClick({left:true}, 100);
+						robot.mouseClick({left:true}, 100);
+					}, true)
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+</html>
+
diff --git a/dijit/tests/tree/robot/Tree_selector.html b/dijit/tests/tree/robot/Tree_selector.html
index b44b4a2..9e7fbba 100644
--- a/dijit/tests/tree/robot/Tree_selector.html
+++ b/dijit/tests/tree/robot/Tree_selector.html
@@ -2,204 +2,209 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Tree selector Test</title>
+		<title>robot Tree selector Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
 		</style>
 
-		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../helpers.js"></script>
-		<script type="text/javascript" src="Tree_dnd.js"></script>
-
 		<script type="text/javascript">
-			dojo.require("dojo.window");
-			dojo.require("dijit.robotx");
+			require([
+				"doh/runner", "dojo/robotx",
+				"dojo/_base/array", "dojo/dom", "dojo/dom-geometry", "dojo/keys", "dojo/sniff", "dojo/window",
+				"./Tree_dnd", "dojo/domReady!"
+			], function(doh, robot, array, dom, domGeom, keys, has, winUtils, dndHelpers){
 
-			function clickItem(modifiers){
-				var i;
-				for(i = 0; i < modifiers.length; i++){
-					doh.robot.keyDown(modifiers[i], 250);
-				}
-				doh.robot.mouseClick({left: true}, 250);
-				for(i = modifiers.length - 1; i >= 0; i--){
-					doh.robot.keyUp(modifiers[i], 250);
+				function clickItem(modifiers){
+					var i;
+					for(i = 0; i < modifiers.length; i++){
+						robot.keyDown(modifiers[i], 250);
+					}
+					robot.mouseClick({left: true}, 250);
+					for(i = modifiers.length - 1; i >= 0; i--){
+						robot.keyUp(modifiers[i], 250);
+					}
 				}
-			}
 
-			function pressEnter(modifiers){
-				var i;
-				for(i = 0; i < modifiers.length; i++){
-					doh.robot.keyDown(modifiers[i], 250);
-				}
-				
-				// Use ENTER on mac because meta-space controls the IME (switching input language),
-				// but SPACE on IE6 because ctrl-shift-ENTER doesn't do anything (although not sure
-				// why we are testing ctrl-shift combination anyway)
-				doh.robot.keyPress(dojo.isMac ? dojo.keys.ENTER : dojo.keys.SPACE, 250);
+				function pressEnter(modifiers){
+					var i;
+					for(i = 0; i < modifiers.length; i++){
+						robot.keyDown(modifiers[i], 250);
+					}
+
+					// Use ENTER on mac because meta-space controls the IME (switching input language),
+					// but SPACE on IE6 because ctrl-shift-ENTER doesn't do anything (although not sure
+					// why we are testing ctrl-shift combination anyway)
+					robot.keyPress(has("mac") ? keys.ENTER : keys.SPACE, 250);
 
-				for(i = modifiers.length - 1; i >= 0; i--){
-					doh.robot.keyUp(modifiers[i], 250);
+					for(i = modifiers.length - 1; i >= 0; i--){
+						robot.keyUp(modifiers[i], 250);
+					}
 				}
-			}
-			function mouseSelect(tree, item, modifiers, k){
-				doh.robot.mouseMoveAt(item.domNode, 250, 200);
-				clickItem(modifiers);
-				doh.robot.sequence(k);
-			}
-			function keyboardSelect(tree, item, modifiers, k){
-				var focused = dojo.query("#itemTree .dijitTreeLabelFocused");
-				if(!(focused.length > 0)){
-					doh.robot.keyPress(dojo.keys.TAB, 250);
-					doh.robot.sequence(function(){ keyboardSelect(tree, item, modifiers, k); }, 250);
-					return;
+				function mouseSelectExpendo(tree, item, modifiers, k){
+					robot.mouseMoveAt(item.expandoNode, 250);
+					clickItem(modifiers);
+					robot.sequence(k);
 				}
-				
-				focused_node = focused[0].parentNode.parentNode.parentNode;
-				var diff = dojo.position(item.domNode).y - dojo.position(focused_node).y;
-				if(diff != 0){
-					if(diff > 0){
-						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
+				function mouseSelect(tree, item, modifiers, k){
+					robot.mouseMoveAt(item.domNode, 250, 200);
+					clickItem(modifiers);
+					robot.sequence(k);
+				}
+				function keyboardSelect(tree, item, modifiers, k){
+					var curFocus = robot.window.require("dijit/focus").curNode,
+						focused = dom.isDescendant(curFocus, dom.byId("itemTree", robot.doc));
+					if(!focused){
+						robot.keyPress(keys.TAB, 250);
+						robot.sequence(function(){ keyboardSelect(tree, item, modifiers, k); }, 250);
+						return;
+					}
+
+					focused_node = curFocus.parentNode.parentNode.parentNode;
+					var diff = domGeom.position(item.domNode).y - domGeom.position(focused_node).y;
+					if(diff != 0){
+						if(diff > 0){
+							robot.keyPress(keys.DOWN_ARROW, 500);
+						}else{
+							robot.keyPress(keys.UP_ARROW, 500);
+						}
 					}else{
-						doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
+						pressEnter(modifiers);
+						robot.sequence(k);
+						return;
 					}
-				}else{
-					pressEnter(modifiers);
-					doh.robot.sequence(k);
-					return;
+					robot.sequence(function(){ keyboardSelect(tree, item, modifiers, k); }, 500);
 				}
-				doh.robot.sequence(function(){ keyboardSelect(tree, item, modifiers, k); }, 500);
-            }
-			
-			function getSelected(tree){
-				//in IE, for(var i in object) will not honor the order the properties are set
-				//(it's in the order properties are first set even delete a property won't 
-				//change it)
-				var selected = tree.dndController.getSelectedTreeNodes();
-				selected.sort(function(a, b){return a.item.id<b.item.id?-1:1});
-				return selected;
-			}
-			function testSingleItem(selector, clicker){
-				var d = new doh.Deferred();
-				
-				// Find the fruitsTreeNode category
-				var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
-				var tree = dijit.byId("itemTree");
-				
-				// select fruit item
-				selector(tree, fruitsTreeNode, [], function(){
-					doh.robot.sequence(d.getTestErrback(function(){
-						var selected = getSelected(tree);
-						
-						doh.is(1, selected.length);
-						doh.is(fruitsTreeNode, selected[0]);
-						
-						//ctrl-click the item to deselect it
-						clicker([dojo.isMac ? dojo.keys.META : dojo.keys.CTRL]);
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							var selected = getSelected(tree);
-							
-							doh.is(0, selected.length);
-						}), 500);
-					}), 500);
-				});
-				return d;
-			}
-			function testCtrlSelect(selector, clicker){
-				var d = new doh.Deferred();
-				
-				// Find the fruitsTreeNode category
-				var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
-				var tree = dijit.byId("itemTree");
-				
-				// select fruit item
-				selector(tree, fruitsTreeNode, [], function(){
-					doh.robot.sequence(function(){
-						dojo.window.scrollIntoView("itemTree");
-					}, 500);
-					
-					// ctrl-click Cereals item
-					var cerealsTreeNode = findTreeNode("itemTree", "Cereals");
-					selector(tree, cerealsTreeNode, 
-							 [dojo.isMac ? dojo.keys.META : dojo.keys.CTRL], function(){
-						 doh.robot.sequence(d.getTestCallback(function(){
-							 var selected = getSelected(tree);
-							 
-							 doh.is(2, selected.length);
-							 doh.is(fruitsTreeNode, selected[0]);
-							 doh.is(cerealsTreeNode, selected[1]);
-							 doh.is(cerealsTreeNode, tree.dndController.anchor, 'anchor should be the Cereals item');
-						 }), 500); });
-				});
-				return d;
-			}
-			function _getCtrlShiftTest(selector, keys){ 
-				return function(){
+
+				function getSelected(tree){
+					//in IE, for(var i in object) will not honor the order the properties are set
+					//(it's in the order properties are first set even delete a property won't
+					//change it)
+					var selected = tree.dndController.getSelectedTreeNodes();
+					selected.sort(function(a, b){return a.item.id<b.item.id?-1:1});
+					return selected;
+				}
+				function testSingleItem(selector, clicker, itemName){
 					var d = new doh.Deferred();
-					
+
 					// Find the fruitsTreeNode category
-					var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
-					var cerealsTreeNode = findTreeNode("itemTree", "Cereals");
-					var vegetablesTreeNode = findTreeNode("itemTree", "Vegetables");
-					var tree = dijit.byId("itemTree");
-					
-					// select fruit item (no modifiers)
-					selector(tree, fruitsTreeNode, [], atFruits);
-
-					function atFruits(){
-						// shift-select Cereals item
-                        selector(tree, cerealsTreeNode, keys, atCereals);
-					}
-					function atCereals(){ 
-						doh.robot.sequence(d.getTestErrback(function(){
-							var selected = getSelected(tree);
-						
-							doh.is(3, selected.length);
-							doh.is(fruitsTreeNode, selected[0]);
-							doh.is(vegetablesTreeNode, selected[1]);
-							doh.is(cerealsTreeNode, selected[2]);
-							doh.is(fruitsTreeNode, tree.dndController.anchor, 'anchor should not change 1');
-						
-							// shift-select Vegetables item
-                            keyboardSelect(tree, vegetablesTreeNode, keys, atVegetables);
-						}));
-					}
-									
-					function atVegetables(){
-						doh.robot.sequence(d.getTestCallback(function(){
+					var fruitsTreeNode = dndHelpers.findTreeNode("itemTree", itemName || "Fruits");
+					var tree = registry.byId("itemTree");
+
+					// select fruit item
+					selector(tree, fruitsTreeNode, [], function(){
+						robot.sequence(d.getTestErrback(function(){
 							var selected = getSelected(tree);
-							doh.is(2, selected.length);
+
+							doh.is(1, selected.length);
 							doh.is(fruitsTreeNode, selected[0]);
-							doh.is(vegetablesTreeNode, selected[1]);
-							doh.is(fruitsTreeNode, tree.dndController.anchor, 'anchor should not change 2'); 
-						}));
-					}
 
+							//ctrl-click the item to deselect it
+							clicker([has("mac") ? keys.META : keys.CTRL]);
+
+							robot.sequence(d.getTestCallback(function(){
+								var selected = getSelected(tree);
+
+								doh.is(0, selected.length);
+							}), 500);
+						}), 500);
+					});
+					return d;
+				}
+				function testCtrlSelect(selector, clicker){
+					var d = new doh.Deferred();
+
+					// Find the fruitsTreeNode category
+					var fruitsTreeNode = dndHelpers.findTreeNode("itemTree", "Fruits");
+					var tree = registry.byId("itemTree");
+
+					// select fruit item
+					selector(tree, fruitsTreeNode, [], function(){
+						robot.sequence(function(){
+							winUtils.scrollIntoView(dom.byId("itemTree", robot.doc));
+						}, 500);
+
+						// ctrl-click Cereals item
+						var cerealsTreeNode = dndHelpers.findTreeNode("itemTree", "Cereals");
+						selector(tree, cerealsTreeNode,
+								 [has("mac") ? keys.META : keys.CTRL], function(){
+							 robot.sequence(d.getTestCallback(function(){
+								 var selected = getSelected(tree);
+
+								 doh.is(2, selected.length);
+								 doh.is(fruitsTreeNode, selected[0]);
+								 doh.is(cerealsTreeNode, selected[1]);
+								 doh.is(cerealsTreeNode, tree.dndController.anchor, 'anchor should be the Cereals item');
+							 }), 500); });
+					});
 					return d;
-				};
-			}
-			dojo.ready(function(){
+				}
+				function _getCtrlShiftTest(selector, keys){
+					return function(){
+						var d = new doh.Deferred();
+
+						// Find the fruitsTreeNode category
+						var fruitsTreeNode = dndHelpers.findTreeNode("itemTree", "Fruits");
+						var cerealsTreeNode = dndHelpers.findTreeNode("itemTree", "Cereals");
+						var vegetablesTreeNode = dndHelpers.findTreeNode("itemTree", "Vegetables");
+						var tree = registry.byId("itemTree");
+
+						// select fruit item (no modifiers)
+						selector(tree, fruitsTreeNode, [], atFruits);
+
+						function atFruits(){
+							// shift-select Cereals item
+							selector(tree, cerealsTreeNode, keys, atCereals);
+						}
+						function atCereals(){
+							robot.sequence(d.getTestErrback(function(){
+								var selected = getSelected(tree);
+
+								doh.is(3, selected.length);
+								doh.is(fruitsTreeNode, selected[0]);
+								doh.is(vegetablesTreeNode, selected[1]);
+								doh.is(cerealsTreeNode, selected[2]);
+								doh.is(fruitsTreeNode, tree.dndController.anchor, 'anchor should not change 1');
+
+								// shift-select Vegetables item
+								keyboardSelect(tree, vegetablesTreeNode, keys, atVegetables);
+							}));
+						}
+
+						function atVegetables(){
+							robot.sequence(d.getTestCallback(function(){
+								var selected = getSelected(tree);
+								doh.is(2, selected.length);
+								doh.is(fruitsTreeNode, selected[0]);
+								doh.is(vegetablesTreeNode, selected[1]);
+								doh.is(fruitsTreeNode, tree.dndController.anchor, 'anchor should not change 2');
+							}));
+						}
+
+						return d;
+					};
+				}
+
 				var controller = '', ind=window.location.href.indexOf("?controller=");
 				
 				if(ind > -1){
 					controller = window.location.href.substr(ind + 12);
 					controller = controller.split('&')[0];
 				}
-				doh.robot.initRobot('../test_Tree_DnD.html?testController=' + controller);
+				robot.initRobot('../test_Tree_DnD.html?testController=' + controller);
 
-				setup();
+				dndHelpers.setup();
 
 				doh.register("focus page", {
 					name: "focus page",
 					timeout: 20000,
 					runTest: function(){
 						var d = new doh.Deferred();
-						doh.robot.mouseClick({left:true}, 100);
-						doh.robot.sequence(function(){
+						robot.mouseMove(10, 10, 100, 100);
+						robot.mouseClick({left:true}, 100);
+						robot.sequence(function(){
                             //Focus the page, so tabbing will work.
 							d.callback(true);
 						}, 250);
@@ -208,6 +213,21 @@
 				});
 				doh.register("item selection (keyboard)", itemSelection(keyboardSelect, pressEnter) );
 				doh.register("item selection (mouse)", itemSelection(mouseSelect, clickItem) );
+				doh.register({name:"item selection (mouse on expando)", timeout: 15000, runTest: function(){
+					return testSingleItem(mouseSelectExpendo, clickItem, 'Cereals');
+				}});
+
+				// Failsafe to clear pressed keys in case above tests timeout etc.
+				doh.register("clear pressed keys", function(){
+					var d = new doh.Deferred();
+					array.forEach([keys.META, keys.CTRL, keys.SHIFT], function(key){
+						robot.keyUp(key, 250);
+					});
+					robot.sequence(function(){
+						d.callback(true);
+					});
+					return d;
+				});
 
 				function itemSelection(selector, clicker){
 					return [
@@ -215,7 +235,7 @@
 							name: "select/deselect a single item",
 							timeout: 15000,
 							runTest: function(){ return testSingleItem(selector, clicker); }
-						}, 
+						},
 						{
 							name: "ctrl select",
 							timeout: 15000,
@@ -224,12 +244,12 @@
 						{
 							name: "shift select",
 							timeout: 15000,
-							runTest: _getCtrlShiftTest(selector, [dojo.keys.SHIFT])
+							runTest: _getCtrlShiftTest(selector, [keys.SHIFT])
 						},
 						{
 							name: "ctrl shift select",
 							timeout: 15000,
-							runTest: _getCtrlShiftTest(selector, [dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, dojo.keys.SHIFT])
+							runTest: _getCtrlShiftTest(selector, [has("mac") ? keys.META : keys.CTRL, keys.SHIFT])
 						}
 					];
 				}
diff --git a/dijit/tests/tree/robot/Tree_v1.html b/dijit/tests/tree/robot/Tree_v1.html
index 1512512..07d9717 100644
--- a/dijit/tests/tree/robot/Tree_v1.html
+++ b/dijit/tests/tree/robot/Tree_v1.html
@@ -11,26 +11,23 @@
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
-		<script type="text/javascript" src="../../helpers.js"></script>
-
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.ready(function(){
 				doh.robot.initRobot('../test_Tree_v1.html');
 
-				doh.register("setup",{
-					name: "setup",
-					timeout:20000,
-					runTest:function(){
-						var d = new doh.Deferred();
-						var store = dojo.global.dijit.byId('mytree').get('store');
-						store.fetch({query:{id:'*'}, onComplete:function(){
-							d.callback(true);
-						}});
-						return d;
+				doh.register("_setup", [
+					{
+						name: "wait for widgets to load",
+						timeout: 10000,
+						runTest: waitForLoad
+					},
+					function setVars(){
+						registry = dojo.global.require("dijit/registry");
 					}
-				});
+				]);
 							
 				doh.register("Test tree 1", [
 					{
@@ -39,7 +36,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 														
-							var myTree = dijit.byId("mytree");
+							var myTree = registry.byId("mytree");
 							var children = myTree.rootNode.getChildren();
 								
 							doh.robot.mouseMoveAt(children[0].contentNode, 500, 1);
@@ -60,7 +57,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							var myTree = dijit.byId("mytree");
+							var myTree = registry.byId("mytree");
 							var rootChildren = myTree.rootNode.getChildren();
 							var africaChildren = rootChildren[0].getChildren();
 							var naChildren = rootChildren[4].getChildren();
@@ -82,7 +79,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							var myTree = dijit.byId("mytree");
+							var myTree = registry.byId("mytree");
 							var rootChildren = myTree.rootNode.getChildren();
 							var naChildren = rootChildren[4].getChildren();
 							var mexicoChildren = naChildren[0].getChildren();
@@ -102,7 +99,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							var myTree = dijit.byId("mytree");
+							var myTree = registry.byId("mytree");
 							var rootChildren = myTree.rootNode.getChildren();
 							var naChildren = rootChildren[4].getChildren();
 							
@@ -127,9 +124,9 @@
 						name: "Destroy tree",
 						timeout: 4000,
 						runTest: function(){
-							dijit.byId("mytree").destroy();
+							registry.byId("mytree").destroy();
 
-							doh.is(undefined, dijit.byId("mytree"), "tree was not destroyed");
+							doh.is(undefined, registry.byId("mytree"), "tree was not destroyed");
 							doh.is(undefined, dojo.byId("mytree"), 'widget was removed');
 						}
 					}
@@ -142,7 +139,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							var myTree = dijit.byId("tree2");
+							var myTree = registry.byId("tree2");
 							var children = myTree.rootNode.getChildren();
 							
 							var ex = children[0].expandoNode;
@@ -165,7 +162,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							
-							var myTree = dijit.byId("tree2");
+							var myTree = registry.byId("tree2");
 							var rootChildren = myTree.rootNode.getChildren();
 														
 							doh.robot.mouseMoveAt(rootChildren[0].contentNode, 500, 1);
@@ -176,90 +173,7 @@
 							}), 1000);
 							return d;
 						}
-					},
-					{
-						name: "open context menu",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							var myTree = dijit.byId("tree2");
-							var children = myTree.rootNode.getChildren();
-							
-							doh.robot.mouseMoveAt(children[1].expandoNode, 500, 1);
-							doh.robot.mouseClick({right: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								var menu = dijit.byId("tree_menu");
-								doh.t(isVisible(menu.domNode), "Menu is not visible");
-								
-								menu = dijit.byId("submenu2");
-								doh.t(isHidden(menu.domNode), "Sub menu is not visible");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "open sub menu 1",
-						timeout: 3000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("popupSubMenu", 500, 1);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								var menu = dijit.byId("tree_menu");
-								doh.t(isVisible(menu.domNode), "Menu is not visible");
-								menu = dijit.byId("submenu2");
-								doh.t(isVisible(menu.domNode), "Sub menu is not visible");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "open deeper sub menu",
-						timeout: 3000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("deeperSubmenu", 500, 1);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								var menu = dijit.byId("tree_menu");
-								doh.t(isVisible(menu.domNode), "Menu is not visible");
-								menu = dijit.byId("submenu2");
-								doh.t(isVisible(menu.domNode), "Sub menu is not visible");
-								menu = dijit.byId("submenu4");
-								doh.t(isVisible(menu.domNode), "Deeper menu is not visible");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "close tree nodes",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							var myTree = dijit.byId("tree2");
-							var children = myTree.rootNode.getChildren();
-
-							// close deeper submenu, then submenu, then context menu
-							doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
-							doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
-							doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
-
-							// close africa node.   (2 mouse moves to work around robot bugs)
-							doh.robot.mouseMoveAt(children[0].expandoNode, 1000, 100);
-							doh.robot.mouseMoveAt(children[0].expandoNode, 1000, 1);
-							doh.robot.mouseClick({left: true}, 1000);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.f(children[0].isExpanded, "failed to close first node");
-							}), 1000);
-							return d;
-						}
-					}					
+					}
 				]);
 				
 				doh.run();
diff --git a/dijit/tests/tree/test_Custom_TreeNode.html b/dijit/tests/tree/test_Custom_TreeNode.html
new file mode 100644
index 0000000..452a4e0
--- /dev/null
+++ b/dijit/tests/tree/test_Custom_TreeNode.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML>
+<html lang="en">
+    <head>
+        <title>Custom TreeNode Test</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+		<script src="../boilerplate.js" type="text/javascript"></script>
+
+        <script type="text/javascript">
+			require([
+				"dojo/_base/declare", "dojo/data/ItemFileReadStore", "dojo/dom-construct",
+				"dijit/_WidgetBase", "dijit/Tree", "dijit/tree/ForestStoreModel",
+				"dojo/domReady!"
+			], function(declare, ItemFileReadStore, domConstruct,
+						_WidgetBase, Tree, ForestStoreModel){
+
+				declare("SuperSmartLink", _WidgetBase, {
+					buildRendering: function(){
+						this.domNode = document.createElement("A");
+						this.domNode.href = "http://ibm.com";
+						this.inherited(arguments);
+					}
+				});
+
+				declare("SuperSmartTreeNode", Tree._TreeNode, {
+					postCreate: function(){
+						this.inherited(arguments);
+						this._smartLink = new SuperSmartLink();
+						this.contentNode.appendChild(this._smartLink.domNode);
+						// in real application this is done by template modification tree node class
+						domConstruct.place(this.labelNode, this._smartLink.domNode, "first");
+					}
+				});
+
+				declare("SuperSmartTree", Tree, {
+					focusNode: function(node){
+						this.inherited(arguments);
+						this.dndController.setSelection([node]);
+					},
+
+					_createTreeNode: function(args){
+						return new SuperSmartTreeNode(args);
+					}
+				});
+
+				var getChildren  = function(depth, parent){
+					var classChildren = [];
+					for (var i = 0; i < 3; i++){
+						var child = {
+							id: parent+"_" + i,
+							name: parent+"_" + i
+						};
+						if (depth < 2 && i === 0){
+							child.children = getChildren(depth+1, child.id);
+						}
+						classChildren.push(child);
+					}
+					return classChildren;
+				};
+
+				var store = new ItemFileReadStore({
+					data: {
+						identifier: 'id',
+						label: 'name',
+						items: [
+							{id:"rrroot", name:"The Root", type:"", children: getChildren(0, "Child")}
+						]
+					}
+				});
+
+				var model = new ForestStoreModel({
+					store: store,
+					query:{type:'*'},
+					childrenAttrs: ["children"]
+				});
+
+				tree = new SuperSmartTree({
+					"model": model,
+					showRoot: false,
+					persist: false
+
+				}).placeAt("AAA");
+
+				tree.startup();
+			});
+        </script>
+    </head>
+    <body class="claro" role="main"> 
+        <h1 class="title">Please expand Continent node</h1>
+		<div id="AAA" style="overflow: auto; height: 1000px">
+		</div>
+		Footer is here
+    </body>	
+</html>
+
diff --git a/dijit/tests/tree/test_Tree.html b/dijit/tests/tree/test_Tree.html
index 3ecaeac..6adba5c 100644
--- a/dijit/tests/tree/test_Tree.html
+++ b/dijit/tests/tree/test_Tree.html
@@ -1,47 +1,34 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dijit Tree Test</title>
 
-	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("dojo.data.ItemFileReadStore");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.ForestStoreModel");
-
-		dojo.require("dijit.ColorPalette");
-
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.MenuItem");
-		dojo.require("dijit.PopupMenuItem");
-
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		require([
+			"dojo/parser",
+			"dojo/data/ItemFileWriteStore",
+			"dijit/Tree",
+			"dijit/tree/ForestStoreModel",
+			"dijit/ColorPalette",
+			"dijit/Menu",
+			"dijit/MenuItem",
+			"dijit/PopupMenuItem",
+			"dojo/domReady!"
+		], function(parser){
+			parser.parse();
+		});
 	</script>
 
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Dijit Tree Test</h1>
 
-	<div data-dojo-id="continentStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"../_data/countries.json"'></div>
-	<div data-dojo-id="continentModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
+	<div data-dojo-id="continentStore" data-dojo-type="dojo/data/ItemFileWriteStore" data-dojo-props='url:"../_data/countries.json"'></div>
+	<div data-dojo-id="continentModel" data-dojo-type="dijit/tree/ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
 		rootId:"continentRoot", rootLabel:"Continents", childrenAttrs:["children"]'></div>
 
 	<h2>Tree with hardcoded root node (not corresponding to any item in the store)</h2>
@@ -49,76 +36,26 @@
 		Clicking a folder node will open/close it (openOnclick==true),
 		and clicking a leaf node will log a message to the console.
 	</p>
-	<div id="mytree" data-dojo-type="dijit.Tree" data-dojo-props='model:continentModel, openOnClick:true, onLoad:function(){ console.log("loaded mytree (first tree)"); }'>
+	<label for="mytree_before">before:</label><input id="mytree_before"/>
+	<div id="mytree" data-dojo-type="dijit/Tree" aria-label="mytree" data-dojo-props='model:continentModel, openOnClick:true, onLoad:function(){ console.log("loaded mytree (first tree)"); }'>
 		<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="item">
 			console.log("Execute of node " + continentStore.getLabel(item)
 				+", population=" + continentStore.getValue(item, "population"));
 		</script>
 		<script type="dojo/method" data-dojo-event="onOpen" data-dojo-args="item">
-			console.log("Open of node " + continentStore.getLabel(item)||"root");
+			console.log("Open of node " + (continentStore.getLabel(item) || "root"));
 		</script>
 		<script type="dojo/method" data-dojo-event="onClose" data-dojo-args="item">
-			console.log("Close of node " + continentStore.getLabel(item)||"root");
+			console.log("Close of node " + (continentStore.getLabel(item) || "root"));
 		</script>
 	</div>
 
-	<button onclick="dijit.byId('mytree').destroyRecursive();">destroy</button>
+	<button id="mytreeDestroyButton" onclick="dijit.byId('mytree').destroyRecursive();">destroy</button>
 
 	<h2>A rootless tree (no "continents" node) with context menus, and custom icons</h2>
 
-	<ul id="tree_menu" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
-		<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Hello world"); }'>Enabled Item</li>
-		<li data-dojo-type="dijit.MenuItem" data-dojo-props='disabled:true'>Disabled Item</li>
-		<li data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
-			onClick:function(){ console.log("not actually cutting anything, just a test!") }'>Cut</li>
-		<li data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
-			onClick:function(){ console.log("not actually copying anything, just a test!") }'>Copy</li>
-		<li data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
-			onClick:function(){ console.log("not actually pasting anything, just a test!") }'>Paste</li>
-		<li data-dojo-type="dijit.PopupMenuItem">
-			<span>Enabled Submenu</span>
-			<ul id="submenu2" data-dojo-type="dijit.Menu" >
-				<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</li>
-				<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</li>
-				<li data-dojo-type="dijit.PopupMenuItem">
-					<span>Deeper Submenu</span>
-					<ul id="submenu4" data-dojo-type="dijit.Menu" >
-						<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</li>
-						<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</li>
-					</ul>
-				</li>
-			</ul>
-		</li>
-		<li data-dojo-type="dijit.PopupMenuItem" data-dojo-props='disabled:true'>
-			<span>Disabled Submenu</span>
-			<ul id="submenu3" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
-				<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</li>
-				<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</li>
-			</ul>
-		</li>
-	</ul>
-
-	<div id="tree2" data-dojo-type="dijit.Tree" data-dojo-props='model:continentModel, showRoot:false, openOnClick:true,onLoad:function(){ console.log("loaded tree2 (second tree)"); }'>
-
-		<script type="dojo/connect">
-			var menu = dijit.byId("tree_menu");
-			// when we right-click anywhere on the tree, make sure we open the menu
-			menu.bindDomNode(this.domNode);
-
-			dojo.connect(menu, "_openMyself", this, function(e){
-				// get a hold of, and log out, the tree node that was the source of this open event
-				var tn = dijit.getEnclosingWidget(e.target);
-				console.debug(tn);
-
-				// now inspect the data store item that backs the tree node:
-				console.debug(tn.item);
-
-				// contrived condition: if this tree node doesn't have any children, disable all of the menu items
-				dojo.forEach(menu.getChildren(), function(i){ i.set('disabled', !tn.item.children); });
-
-				// IMPLEMENT CUSTOM MENU BEHAVIOR HERE
-			});
-		</script>
+	<label for="tree2_before">before:</label><input id="tree2_before"/>
+	<div id="tree2" data-dojo-type="dijit/Tree" aria-label="tree2label" data-dojo-props='model:continentModel, showRoot:false, openOnClick:true,onLoad:function(){ console.log("loaded tree2 (second tree)"); }'>
 		<script type="dojo/method" data-dojo-event="getIconClass" data-dojo-args="item, opened">
            return (item == this.model.root || continentStore.getValue(item, "type") == "continent") ?
                    (opened ? "customFolderOpenedIcon" : "customFolderClosedIcon") :
@@ -128,14 +65,32 @@
 			console.log("Execute of node " + this.model.getLabel(item)
 				+", population=" + continentStore.getValue(item, "population"));
 		</script>
-</div>
+	</div>
+
+	<ul id="tree_menu" data-dojo-type="dijit/Menu"
+			data-dojo-props='style:"display: none;", targetNodeIds: ["tree2"], selector: ".dijitTreeNode"'>
+		<li data-dojo-type="dijit/MenuItem">
+			<script type="dojo/connect" data-dojo-event="onClick">
+				// get a hold of the dijit.TreeNode that was the source of this open event
+				var tn = dijit.byNode(this.getParent().currentTarget);
+
+				// now print the data store item that backs the tree node
+				console.debug("menu click for item: ", tn.item.name);
+			</script>
+			Click Me
+		</li>
+	</ul>
+
+	<button id="tree2ExpandAll" onclick="dijit.byId('tree2').expandAll();">expand all</button>
+	<button onclick="dijit.byId('tree2').collapseAll();">collapse all</button>
 
 	<h2>Double click, expand on load, direct style setting, tooltip test</h2>
 	<p>
 		Double-Clicking a folder node will open/close it (openOnDblClick==true),
 		and clicking or Double Clicking a leaf node will log a message to the console.
 	</p>
-	<div id="mytree3" data-dojo-type="dijit.Tree" data-dojo-props='store:continentStore, query:{type:"continent"},
+	<label for="mytree3_before">before:</label> <input id="mytree3_before"/>
+	<div id="mytree3" aria-label="mytree 3"  data-dojo-type="dijit/Tree" data-dojo-props='store:continentStore, query:{type:"continent"},
 		label:"Continents", openOnClick:false, openOnDblClick:true,
 		autoExpand:true, onLoad:function(){ console.log("loaded mytree3 (third tree)"); }'>
 		<script type="dojo/method" data-dojo-event="getLabelStyle" data-dojo-args="item,opened">
@@ -171,6 +126,37 @@
 		</script>
 	</div>
 
+	<h2>Tree w/horizontal scroll</h2>
+	<p>
+		For checking that selection and highlighting effect goes all the way to the right.
+	</p>
+	<p>
+		Expand North America and check highlighting for United States, plus shorter labels.
+		Then collapse North America and make sure horizontal scrollbar disappears.
+	</p>
+	<p>
+		Also check whether the Tree's initial display is correct.
+		Since the Tree persists, try refreshing the page when the tree is in an open state, and when it's in a closed
+		state.
+	</p>
+	<div id="thinTree" style="width: 170px; border: solid 1px #759dc0"
+		 data-dojo-type="dijit/Tree" aria-label="my thin tree"  data-dojo-props="model:continentModel">
+		<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="_adjustWidths">
+			console.log(this.id + ": adjusted widths of nodes");
+		</script>
+	</div>
+	<button onclick="dijit.byId('thinTree').expandAll();">expand all</button>
+	<button onclick="dijit.byId('thinTree').collapseAll();">collapse all</button>
+	<button onclick="dijit.byId('thinTree').set('paths', [['continentRoot','AF'],['continentRoot','NA','US']]);">
+		set paths to Africa, US
+	</button>
+	<button onclick="continentStore.fetchItemByIdentity({identity: 'US', onItem: function(item){ continentStore.setValue(item, 'name', 'A very very very long name for USA'); }});">
+		set long name for USA
+	</button>
+	<button onclick="continentStore.fetchItemByIdentity({identity: 'US', onItem: function(item){ continentStore.setValue(item, 'name', 'USA'); }});">
+		set short name for USA
+	</button>
+
 
 </body>
 </html>
diff --git a/dijit/tests/tree/test_Tree_DnD.html b/dijit/tests/tree/test_Tree_DnD.html
index b924716..cb45bad 100644
--- a/dijit/tests/tree/test_Tree_DnD.html
+++ b/dijit/tests/tree/test_Tree_DnD.html
@@ -1,129 +1,129 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dijit Tree Test</title>
 
 	<style type="text/css">
-		@import "../../themes/claro/document.css";
-		@import "../css/dijitTests.css";
 		@import "../../../dojo/resources/dnd.css";
 		@import "../../../dojo/tests/dnd/dndDefault.css";
-		
-		.dojoDndItemSelected,
-		.dojoDndItemAnchor{
-			background-color: #D8EDFF !important;
-		}
 	</style>
 
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+	<script type="text/javascript" src="../boilerplate.js"></script>
 
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		require([
+			"dojo/aspect",
+			"dojo/dnd/Source",
+			"dojo/data/ItemFileWriteStore",
+			"dojo/dom",
+			"dojo/parser",
+			"dojo/topic",
+			"dijit/registry",
+			"dijit/Tree",
+			"dijit/tree/TreeStoreModel",
+			/testController=selector/.test(window.location.search) ? "dijit/tree/_dndSelector" : "dijit/tree/dndSource",
+			"dijit/Menu",
+			"dijit/form/Button",
+			"dijit/focus",	// not used directly, but needed by robot test drivers, ex: Tree_Selector.html
+			"dojo/domReady!"
+		], function(aspect, Source, ItemFileWriteStore, dom, parser, topic,
+					registry, Tree, TreeStoreModel, testController){
+
+			myStore = new ItemFileWriteStore({
+				url: "../_data/categories.json"
+			});
 
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+			catModel = new TreeStoreModel({
+				store: myStore,
+				query: {id: "0"}
+			});
 
-	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.data.ItemFileWriteStore");
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.TreeStoreModel");
-		
-		var testController = dojo._getVar("testController", "")=="selector"?"dijit.tree._dndSelector":"dijit.tree.dndSource";
-
-		dijit.Tree.prototype.dndController = testController;
-		
-		dojo.require(testController);
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.form.Button");
-
-		dojo.require("dojo.dnd.common");
-		dojo.require("dojo.dnd.Source");
-
-		selected=[];
-
-		globalId=1000;
-		lastSelected=null;
-
-		dojo.ready(function(){
-
-			//record the selection from tree 1
-			dojo.subscribe("myTree", null, function(message){
-				if(message.event=="execute"){
-					console.log("Tree1 Select: ",dijit.byId("myTree").store.getLabel(message.item));
-					lastSelected=selected["myTree"]=message.item;
+			//create a custom label for tree one consisting of the label property pluss the value of the numberOfItems Column
+			catTreeCustomLabel = function(item){
+				var label = myStore.getLabel(item);
+				var num = myStore.hasAttribute(item, "numberOfItems") ? myStore.getValues(item,"numberOfItems") : "?";
+				return label + ' (' + num+ ')';
+			};
+
+			//on item tree , we want to drop on containers, the root node itself, or between items in the containers
+			itemTreeCheckItemAcceptance = function(node, source, position){
+				/*
+				 source.forInSelectedItems(function(item){
+				 console.log("testing to drop item of type " + item.type[0] + " and data " + item.data + ", position " + position);
+				 });
+				 */
+				var item = registry.getEnclosingWidget(node).item;
+				if(item && (item.root || myStore.hasAttribute(item,"numberOfItems"))){
+					return true;
+				}
+				return position != "over";
+			};
+
+			// on collection tree, only accept itself as the source tree
+			collectionTreeCheckItemAcceptance = function(node,source,position){
+				return source.tree && source.tree.id == "collectionsTree";
+			};
+
+			dndAccept = function(source, nodes){
+				return this.tree.id != "myTree";
+			};
+
+			getIcon = function(item){
+				if(!item || myStore.hasAttribute(item, "numberOfItems")){
+					return "myFolder";
+				}
+				return "myItem"
+			};
+
+			Tree.prototype.dndController = testController;
+
+			parser.parse();
+
+			selected = [];
+	
+			globalId = 1000;
+			lastSelected = null;
+	
+			// record the selection from tree 1
+			topic.subscribe("myTree", function(message){
+				if(message.event == "execute"){
+					// console.log("Tree1 Select: ",dijit.byId("myTree").store.getLabel(message.item));
+					lastSelected = selected["myTree"] = message.item;
 				}
 			});
 
-			//record the selection from tree 2
-			dojo.subscribe("myTree2", null, function(message){
-				if(message.event=="execute"){
-					console.log("Tree2 Select: ",dijit.byId("myTree2").store.getLabel(message.item));
-					lastSelected=selected["myTree2"]=message.item;
+			// record the selection from tree 2
+			topic.subscribe("myTree2", function(message){
+				if(message.event == "execute"){
+					// console.log("Tree2 Select: ",dijit.byId("myTree2").store.getLabel(message.item));
+					lastSelected = selected["myTree2"] = message.item;
 				}
 			});
 
-			//connect to the add button and have it add a new container to the store as necessary
-			dojo.connect(dijit.byId("addButton"), "onClick", function(){
+			// connect to the add button and have it add a new container to the store as necessary
+			registry.byId("addButton").on("click", function(){
 				var pInfo = {
 					parent: lastSelected,
 					attribute: "children"
 				};
 
-				//store.newItem({name: dojo.byId('newCat').value, id:globalId++, numberOfItems:dojo.byId('numItems').value}, pInfo);
-				myStore.newItem({name: dojo.byId('newCat').value, numberOfItems:0,id:globalId++}, pInfo);
+				myStore.newItem({
+					name: dom.byId('newCat').value,
+					numberOfItems:0,
+					id:globalId++
+				}, pInfo);
 			});
 
 			//since we don't have a server, we're going to connect to the store and do a few things the server/store combination would normal be taking care of for us
-			dojo.connect(myStore, "onNew", function(item, pInfo){
+			aspect.after(myStore, "onNew", function(item, pInfo){
 				var p = pInfo && pInfo.item;
 				if(p){
 					var currentTotal = myStore.getValues(p, "numberOfItems")[0];
 					myStore.setValue(p, "numberOfItems", ++currentTotal);
 				}
-
-			});
+			}, true);
 		});
-
-
-		//create a custom label for tree one consisting of the label property pluss the value of the numberOfItems Column
-		function catTreeCustomLabel(item){
-			var label = myStore.getLabel(item);
-			var num = myStore.hasAttribute(item, "numberOfItems") ? myStore.getValues(item,"numberOfItems") : "?";
-			return label + ' (' + num+ ')';
-		}
-
-		//on item tree , we want to drop on containers, the root node itself, or between items in the containers
-		function itemTreeCheckItemAcceptance(node,source,position){
-			source.forInSelectedItems(function(item){
-				console.log("testing to drop item of type " + item.type[0] + " and data " + item.data + ", position " + position);
-			});
-			var item = dijit.getEnclosingWidget(node).item;
-			if(item && (item.root || myStore.hasAttribute(item,"numberOfItems"))){
-				return true;
-			}
-			return position != "over";
-
-		}
-
-		//on collection tree, only accept itself as the source tree
-		function collectionTreeCheckItemAcceptance(node,source,position){
-			return source.tree && source.tree.id == "collectionsTree";
-		}
-
-		function dndAccept(source,nodes){
-			return this.tree.id != "myTree";
-		}
-
-		function getIcon(item){
-			if(!item || myStore.hasAttribute(item, "numberOfItems")){
-				return "myFolder";
-			}
-			return "myItem"
-		}
 	</script>
 
 	<style>
@@ -142,73 +142,61 @@
 	</style>
 
 </head>
-<body class="claro">
+<body class="claro" role="main">
 	<h1 class="testTitle">Dijit Tree Test - Drag And Drop Support</h1>
 
-	<div data-dojo-id="myStore" data-dojo-type="dojo.data.ItemFileWriteStore" data-dojo-props='url:"../_data/categories.json"'></div>
-
-	<table style="margin:5px; width:100%;" >
-
-	<tr style="width:100%">
-		<td style="width: 50%">
-			<h2>Custom</h2>
-			<p>Should add this category to the store.  The second parameter is the value for numberOfItems.</p>
-			<div class="container">
-				<input id="newCat" type="text" value="Pottedmeat" /><input id="numItems" type="text" value="0" size="3"/><div id="addButton" data-dojo-type="dijit.form.Button">Add Category</div>
-			</div>
-		</td>
-		<td>
-			<h2>Items: </h2>
-			<p>List of Items to be categorized<p>
-				<div data-dojo-id="c2" data-dojo-type="dojo.dnd.Source" class="container" style="height:100px; overflow:auto;">
-				<div class="dojoDndItem" id="1001">Apple</div>
-				<div class="dojoDndItem" id="1002">Orange</div>
-				<div class="dojoDndItem" id="1003">Banana</div>
-				<div class="dojoDndItem" id="1004">Tomato</div>
-				<div class="dojoDndItem" id="1005">Pepper</div>
-				<div class="dojoDndItem" id="1006">Wheat</div>
-				<div class="dojoDndItem" id="1007">Corn</div>
-				<div class="dojoDndItem" id="1008">Spinach</div>
-				<div class="dojoDndItem" id="1009">Cucumber</div>
-				<div class="dojoDndItem" id="1010">Carrot</div>
-				<div class="dojoDndItem" id="1011">Potato</div>
-				<div class="dojoDndItem" id="1012">Grape</div>
-				<div class="dojoDndItem" id="1013">Lemon</div>
-				<div class="dojoDndItem" id="1014">Lettuce</div>
-				<div class="dojoDndItem" id="1015">Peanut</div>
-			</div>
-		</td>
-	</tr>
-	<tr>
-		<td>
-			<h2>Collection Count Summary</h2>
-			<p>
-				You can't drop items onto this tree, but you can reorder categories. The between threshold
-				is set to 5, so if you are near the top or bottom of a node the drop will be above or below it.
-			</p>
-			<div data-dojo-id="catModel" data-dojo-type="dijit.tree.TreeStoreModel" data-dojo-props='store:myStore, query:{id: "0"}'></div>
-			<div id="collectionsTree" data-dojo-type="dijit.Tree" data-dojo-props='"class":"container", model:catModel,
-				getLabel:catTreeCustomLabel, betweenThreshold:5,
-				checkAcceptance:dndAccept, checkItemAcceptance:collectionTreeCheckItemAcceptance, getIconClass:getIcon,
-				persist:false'></div>
-		</td>
-		<td>
-			<h2>Collection</h2>
-			<p>
-				Drop items from above list onto this tree, only on to categories or between other items; should fail to let you drop on other items.
-				Can also move items within this tree. The drag threshold is set to 8, between threshold is set to 5, so you have a few pixels
-				of buffer before drag operations start.
-			</p>
-			<div data-dojo-id="itemModel" data-dojo-type="dijit.tree.TreeStoreModel" data-dojo-props='store:myStore, query:{id: "0"}, childrenAttrs:["items", "children"]'></div>
-			<div id="itemTree" data-dojo-type="dijit.Tree" data-dojo-props='"class":"container", model:itemModel,
-				checkAcceptance:dndAccept, checkItemAcceptance:itemTreeCheckItemAcceptance,
-				dragThreshold:8,
-				betweenThreshold:5,
-				getIconClass:getIcon,
-				persist:false'></div>
-		</td>
-	</tr>
-	</table>
+	<div role="presentation" style="float: left; width: 50%;">
+
+		<h2>Items: </h2>
+		<p>List of Items to be categorized<p>
+			<div data-dojo-id="c2" data-dojo-type="dojo/dnd/Source" class="container" style="height:100px; overflow:auto;">
+			<div class="dojoDndItem" id="1001">Apple</div>
+			<div class="dojoDndItem" id="1002">Orange</div>
+			<div class="dojoDndItem" id="1003">Banana</div>
+			<div class="dojoDndItem" id="1004">Tomato</div>
+			<div class="dojoDndItem" id="1005">Pepper</div>
+			<div class="dojoDndItem" id="1006">Wheat</div>
+			<div class="dojoDndItem" id="1007">Corn</div>
+			<div class="dojoDndItem" id="1008">Spinach</div>
+			<div class="dojoDndItem" id="1009">Cucumber</div>
+			<div class="dojoDndItem" id="1010">Carrot</div>
+			<div class="dojoDndItem" id="1011">Potato</div>
+			<div class="dojoDndItem" id="1012">Grape</div>
+			<div class="dojoDndItem" id="1013">Lemon</div>
+			<div class="dojoDndItem" id="1014">Lettuce</div>
+			<div class="dojoDndItem" id="1015">Peanut</div>
+		</div>
+
+		<h2>Collection Count Summary</h2>
+		<p>
+			You can't drop items onto this tree, but you can reorder categories. The between threshold
+			is set to 5, so if you are near the top or bottom of a node the drop will be above or below it.
+		</p>
+		<div id="collectionsTree" data-dojo-type="dijit/Tree" data-dojo-props='"class":"container", model:catModel,
+			getLabel:catTreeCustomLabel, betweenThreshold:5,
+			checkAcceptance:dndAccept, checkItemAcceptance:collectionTreeCheckItemAcceptance, getIconClass:getIcon,
+			persist:false'></div>
+
+		<h2>Custom</h2>
+		<p>Should add this category to the store.  The second parameter is the value for numberOfItems.</p>
+		<div class="container">
+			<label for="newCat">New category:</label><input id="newCat" type="text" value="Pottedmeat" /><label for="numItems">numberOfItems:</label><input id="numItems" type="text" value="0" size="3"/><div id="addButton" data-dojo-type="dijit/form/Button">Add Category</div>
+		</div>
+	</div>
+
+	<h2>Collection</h2>
+	<p>
+		Drop items from table on left onto this tree, only on to categories or between other items; should fail to let you drop on other items.
+		Can also move items within this tree. The drag threshold is set to 8, between threshold is set to 5, so you have a few pixels
+		of buffer before drag operations start.
+	</p>
+	<div data-dojo-id="itemModel" data-dojo-type="dijit/tree/TreeStoreModel" data-dojo-props='store:myStore, query:{id: "0"}, childrenAttrs:["items", "children"]'></div>
+	<div id="itemTree" data-dojo-type="dijit/Tree" data-dojo-props='"class":"container", model:itemModel,
+		checkAcceptance:dndAccept, checkItemAcceptance:itemTreeCheckItemAcceptance,
+		dragThreshold:8,
+		betweenThreshold:5,
+		getIconClass:getIcon,
+		persist:false'></div>
 
 	</body>
 </html>
diff --git a/dijit/tests/tree/test_Tree_v1.html b/dijit/tests/tree/test_Tree_v1.html
index 78a6fc7..62b1322 100644
--- a/dijit/tests/tree/test_Tree_v1.html
+++ b/dijit/tests/tree/test_Tree_v1.html
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="en">
 <head>
 	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dijit Tree V1 API Test</title>
@@ -25,13 +25,10 @@
 		dojo.require("dojo.data.ItemFileReadStore");
 		dojo.require("dijit.Tree");
 		dojo.require("dijit.ColorPalette");
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.MenuItem");
-		dojo.require("dijit.PopupMenuItem");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 
 	<h1 class="testTitle">Dijit Tree V1 API Test</h1>
 	<p>
@@ -54,60 +51,9 @@
 
 	<button onclick="dijit.byId('mytree').destroyRecursive();">destroy</button>
 
-	<h2>A rootless tree (no "continents" node) with context menus, and custom icons</h2>
-
-	<ul dojoType="dijit.Menu" id="tree_menu" style="display: none;">
-		<li dojoType="dijit.MenuItem" onClick="alert('Hello world');">Enabled Item</li>
-		<li dojoType="dijit.MenuItem" disabled="true">Disabled Item</li>
-		<li dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCut"
-			onClick="alert('not actually cutting anything, just a test!')">Cut</li>
-		<li dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCopy"
-			onClick="alert('not actually copying anything, just a test!')">Copy</li>
-		<li dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste"
-			onClick="alert('not actually pasting anything, just a test!')">Paste</li>
-		<li id="popupSubMenu" dojoType="dijit.PopupMenuItem">
-			<span>Enabled Submenu</span>
-			<ul dojoType="dijit.Menu" id="submenu2">
-				<li dojoType="dijit.MenuItem" onClick="alert('Submenu 1!')">Submenu Item One</li>
-				<li dojoType="dijit.MenuItem" onClick="alert('Submenu 2!')">Submenu Item Two</li>
-				<li id="deeperSubmenu" dojoType="dijit.PopupMenuItem">
-					<span>Deeper Submenu</span>
-					<ul dojoType="dijit.Menu" id="submenu4">
-						<li dojoType="dijit.MenuItem" onClick="alert('Sub-submenu 1!')">Sub-sub-menu Item One</li>
-						<li dojoType="dijit.MenuItem" onClick="alert('Sub-submenu 2!')">Sub-sub-menu Item Two</li>
-					</ul>
-				</li>
-			</ul>
-		</li>
-		<li dojoType="dijit.PopupMenuItem" disabled="true">
-			<span>Disabled Submenu</span>
-			<ul dojoType="dijit.Menu" id="submenu3" style="display: none;">
-				<li dojoType="dijit.MenuItem" onClick="alert('Submenu 1!')">Submenu Item One</li>
-				<li dojoType="dijit.MenuItem" onClick="alert('Submenu 2!')">Submenu Item Two</li>
-			</ul>
-		</li>
-	</ul>
+	<h2>A rootless tree (no "continents" node) with custom icons</h2>
 
 	<div dojoType="dijit.Tree" id="tree2" store="continentStore" query="{type:'continent'}" persist="false">
-		<script type="dojo/connect">
-			var menu = dijit.byId("tree_menu");
-			// when we right-click anywhere on the tree, make sure we open the menu
-			menu.bindDomNode(this.domNode);
-
-			dojo.connect(menu, "_openMyself", this, function(e){
-				// get a hold of, and log out, the tree node that was the source of this open event
-				var tn = dijit.getEnclosingWidget(e.target);
-				console.debug(tn);
-
-				// now inspect the data store item that backs the tree node:
-				console.debug(tn.item);
-
-				// contrived condition: if this tree node doesn't have any children, disable all of the menu items
-				dojo.forEach(menu.getChildren(), function(i){ i.set('disabled', !tn.item.children); });
-
-				// IMPLEMENT CUSTOM MENU BEHAVIOR HERE
-			});
-		</script>
 		<script type="dojo/method" event="getIconClass" args="item, opened">
            return (!item || continentStore.getValue(item, "type") == "continent") ?
                    (opened ? "customFolderOpenedIcon" : "customFolderClosedIcon") :
diff --git a/dijit/themes/claro/Calendar.css b/dijit/themes/claro/Calendar.css
index a0f9597..ad5163d 100644
--- a/dijit/themes/claro/Calendar.css
+++ b/dijit/themes/claro/Calendar.css
@@ -33,15 +33,18 @@
  */
 .claro .dijitCalendar {
   border: solid 1px #b5bcc7;
+  border-collapse: separate;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
   background-color: #cfe5fa;
-  background-image: url("images/calendarContainerImages.png");
-  background-position: 0 -448px;
+  background-image: url("images/calendar.png");
   background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0.4) 2px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0.4) 2px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0.4) 2px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0.4) 2px, rgba(255, 255, 255, 0) 100%);
   text-align: center;
   padding: 6px 5px 3px 5px;
-  -moz-border-radius: 4px;
-  border-radius: 4px;
-  border-collapse: separate;
 }
 .dj_ie6 .claro .dijitCalendar {
   background-image: none;
@@ -49,8 +52,10 @@
 .claro .dijitCalendar img {
   border: none;
 }
-.claro .dijitCalendarHover, .claro .dijitCalendar:hover, .claro .dijitCalendarActive {
-  /* treat dijitCalenderActive like hover since there's
+.claro .dijitCalendarHover,
+.claro .dijitCalendar:hover,
+.claro .dijitCalendarActive {
+  /* treat dijitCalendarActive like hover since there's
 	 * no concept of clicking a Calendar as a whole (although you can click things inside the calendar)
 	 */
 
@@ -80,16 +85,20 @@
 .claro .dijitCalendarIncrease {
   background-position: -18px 0;
 }
-.claro .dijitCalendarArrowHover .dijitCalendarDecrease, .claro .dijitCalendarArrow:hover .dijitCalendarDecrease {
+.claro .dijitCalendarArrowHover .dijitCalendarDecrease,
+.claro .dijitCalendarArrow:hover .dijitCalendarDecrease {
   background-position: -36px 0;
 }
-.claro .dijitCalendarArrowHover .dijitCalendarIncrease, .claro .dijitCalendarArrow:hover .dijitCalendarIncrease {
+.claro .dijitCalendarArrowHover .dijitCalendarIncrease,
+.claro .dijitCalendarArrow:hover .dijitCalendarIncrease {
   background-position: -55px 0;
 }
-.claro .dijitCalendarArrowActive .dijitCalendarDecrease, .claro .dijitCalendarArrow:active .dijitCalendarDecrease {
+.claro .dijitCalendarArrowActive .dijitCalendarDecrease,
+.claro .dijitCalendarArrow:active .dijitCalendarDecrease {
   background-position: -72px 0;
 }
-.claro .dijitCalendarArrowActive .dijitCalendarIncrease, .claro .dijitCalendarArrow:active .dijitCalendarIncrease {
+.claro .dijitCalendarArrowActive .dijitCalendarIncrease,
+.claro .dijitCalendarArrow:active .dijitCalendarIncrease {
   background-position: -91px 0;
 }
 .claro .dijitA11ySideArrow {
@@ -111,11 +120,7 @@
   color: #000000;
 }
 .claro .dijitCalendarDateTemplate {
-  text-align: center;
   background-color: #ffffff;
-  background-image: url("images/calendarContainerImages.png");
-  background-position: 0 0;
-  background-repeat: repeat-x;
   border-bottom: 1px solid #d3d3d3;
   padding-top: 0;
   font-size: 0.909em;
@@ -128,7 +133,8 @@
 .dj_ie6 .claro .dijitCalendarDateTemplate {
   background-image: none;
 }
-.claro .dijitCalendarPreviousMonth, .claro .dijitCalendarNextMonth {
+.claro .dijitCalendarPreviousMonth,
+.claro .dijitCalendarNextMonth {
   background-color: #e5f2fe;
   background-image: none;
   border-bottom: solid 1px #d3d3d3;
@@ -151,7 +157,8 @@
   -moz-transition-duration: 0.35s;
   transition-duration: 0.35s;
 }
-.claro .dijitCalendarPreviousMonth .dijitCalendarDateLabel, .claro .dijitCalendarNextMonth .dijitCalendarDateLabel {
+.claro .dijitCalendarPreviousMonth .dijitCalendarDateLabel,
+.claro .dijitCalendarNextMonth .dijitCalendarDateLabel {
   color: #759dc0;
   border-color: #e5f2fe;
   /* intentionally matches background-color, no visible border until hover/selection */
@@ -176,7 +183,8 @@
 .claro .dijitCalendarSelectedYear {
   padding: 0 3px;
 }
-.claro .dijitCalendarNextYear, .claro .dijitCalendarPreviousYear {
+.claro .dijitCalendarNextYear,
+.claro .dijitCalendarPreviousYear {
   padding: 1px 6px 1px 6px;
   font-size: 0.909em;
 }
@@ -186,7 +194,8 @@
 }
 /* End Normal Calendar Style */
 /* Hovered Calendar Style */
-.claro .dijitCalendarHoveredDate .dijitCalendarDateLabel, .claro .dijitCalendarEnabledDate:hover .dijitCalendarDateLabel {
+.claro .dijitCalendarHoveredDate .dijitCalendarDateLabel,
+.claro .dijitCalendarEnabledDate:hover .dijitCalendarDateLabel {
   background-color: #abd6ff;
   border: solid 1px #759dc0;
   color: #000000;
@@ -207,16 +216,17 @@
 }
 /* End Hovered Calendar Style */
 /* Active Calendar Style */
-.claro .dijitCalendarNextYearActive, .claro .dijitCalendarNextYear:active.claro .dijitCalendarPreviousYearActive, .claro .dijitCalendarPreviousYear:active {
+.claro .dijitCalendarNextYearActive,
+.claro .dijitCalendarNextYear:active .claro .dijitCalendarPreviousYearActive,
+.claro .dijitCalendarPreviousYear:active {
   border: solid 1px #759dc0;
   padding: 0 5px 0 5px;
   /* reduced by 1 to make room for border */
 
   background-color: #7dbdfa;
 }
-.claro .dijitCalendarActiveDate .dijitCalendarDateLabel, .claro .dijitCalendarEnabledDate:active .dijitCalendarDateLabel {
-  background-image: url("images/calendarContainerImages.png");
-  background-position: 0 -300px;
+.claro .dijitCalendarActiveDate .dijitCalendarDateLabel,
+.claro .dijitCalendarEnabledDate:active .dijitCalendarDateLabel {
   background-color: #7dbdfa;
   border: solid 1px #ffffff;
   -webkit-transition-duration: 0.1s;
@@ -249,15 +259,16 @@
   margin-right: -4px;
 }
 .claro .dijitCalendar .dijitDropDownButton .dijitButtonNode {
-  background-color: transparent;
-  background-image: none;
   padding: 0 3px 0 2px;
   border: solid 1px #b5bcc7;
   -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
   -moz-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
   box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+  background-color: transparent;
+  background-image: none;
 }
-.claro .dijitCalendar .dijitDropDownButtonHover .dijitButtonNode, .claro .dijitCalendar .dijitDropDownButton:hover .dijitButtonNode {
+.claro .dijitCalendar .dijitDropDownButtonHover .dijitButtonNode,
+.claro .dijitCalendar .dijitDropDownButton:hover .dijitButtonNode {
   background-color: #e5f2fe;
   border: solid 1px #ffffff;
 }
@@ -275,10 +286,14 @@
   border-bottom: solid 1px #ffffff;
   padding: 2px 0;
 }
-.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover, .claro .dijitCalendarMonthMenu .dijitCalendarMonthLabel:hover {
-  background-color: #abd6ff;
+.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover,
+.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabel:hover {
   border-color: #759dc0;
   border-width: 1px 0;
-  background-image: url("images/commonHighlight.png");
-  background-repeat: repeat-x;
+  background-color: #abd6ff;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0));
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0));
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0));
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0));
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr= #ffffff , endColorstr= #abd6ff );
 }
diff --git a/dijit/themes/claro/Calendar.less b/dijit/themes/claro/Calendar.less
index 55decd3..8b8f579 100644
--- a/dijit/themes/claro/Calendar.less
+++ b/dijit/themes/claro/Calendar.less
@@ -35,25 +35,28 @@
 @import "variables";
 
 .claro .dijitCalendar {
-	border:solid 1px @border-color;
+	border: solid 1px @border-color;
+	border-collapse: separate;	// in case user CSS has set border-collapse: collapse for tables
+	.border-radius(4px);
+
+	// Background color and alpha-gradient
 	background-color: @calendar-background-color;
-	background-image:url(@image-calendar-container);
-	background-position:0 -448px;
-	background-repeat:repeat-x;
+	background-image: url("images/calendar.png");	// fallback for browsers that don't support CSS gradients
+	background-repeat: repeat-x;	// so bottom of calendar isn't affected by gradient image repeating
+	.alpha-white-gradient(1, 0px, 0.4, 2px, 0, 100%);
+
 	text-align:center;
 	padding:6px 5px 3px 5px;
-	.border-radius(4px);
-	border-collapse: separate;	// in case user CSS has set border-collapse: collapse for tables
 }
 .dj_ie6 .claro .dijitCalendar {
-	background-image:none;
+	background-image:none;	// because on IE6 background-image overrides background-color
 }
 .claro .dijitCalendar img {
 	border:none;
 }
 .claro .dijitCalendarHover, .claro .dijitCalendar:hover,
 .claro .dijitCalendarActive {
-	/* treat dijitCalenderActive like hover since there's
+	/* treat dijitCalendarActive like hover since there's
 	 * no concept of clicking a Calendar as a whole (although you can click things inside the calendar)
 	 */
 	background-color: @hovered-background-color;
@@ -120,9 +123,6 @@
 .claro .dijitCalendarDateTemplate {
 	text-align:center;
 	background-color:@calendar-currentmonth-background-color;
-	background-image:url(@image-calendar-container);
-	background-position:0 0;
-	background-repeat:repeat-x;
 	border-bottom: 1px solid @minor-border-color;
 	padding-top:0;
 	font-size:0.909em;
@@ -209,8 +209,6 @@
 }
 .claro .dijitCalendarActiveDate .dijitCalendarDateLabel,
 .claro .dijitCalendarEnabledDate:active .dijitCalendarDateLabel {
-	background-image:url(@image-calendar-container);
-	background-position:0 -300px;
 	background-color: @calendar-date-pressed-background-color;
 	border:solid 1px @calendar-date-pressed-border-color;
 	.transition-duration(.1s);
@@ -244,11 +242,13 @@
 	margin-right:-4px;
 }
 .claro .dijitCalendar .dijitDropDownButton .dijitButtonNode {
-	background-color: transparent;
-	background-image: none;
 	padding: 0 3px 0 2px;
 	border:solid 1px @border-color;
 	.box-shadow(0 0 0 rgba(0,0,0,0));
+
+    // Override background settings from vanilla .dijitButtonNode.   We want to inherit background of Calendar.
+	background-color: transparent;
+	background-image: none;
 }
 .claro .dijitCalendar .dijitDropDownButtonHover .dijitButtonNode,
 .claro .dijitCalendar .dijitDropDownButton:hover .dijitButtonNode {
@@ -271,9 +271,7 @@
 }
 .claro .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover,
 .claro .dijitCalendarMonthMenu .dijitCalendarMonthLabel:hover {
-	background-color: @hovered-background-color;
 	border-color: @hovered-border-color;
 	border-width:1px 0;
-	background-image: url(@image-common-highlight);
-	background-repeat:repeat-x;
+	.gradient-and-filter(@hovered-background-color, 70, 0);
 }
diff --git a/dijit/themes/claro/ColorPalette.css b/dijit/themes/claro/ColorPalette.css
index a23b2df..6b95920 100644
--- a/dijit/themes/claro/ColorPalette.css
+++ b/dijit/themes/claro/ColorPalette.css
@@ -20,7 +20,7 @@
  *		.dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg
  *		adds border for active or selected state
  */
-.claro  .dijitColorPalette {
+.claro .dijitColorPalette {
   border: 1px solid #b5bcc7;
   background: #ffffff;
   -moz-border-radius: 0;
@@ -36,6 +36,7 @@
 .claro .dijitColorPalette .dijitPaletteCell:hover .dijitPaletteImg {
   border: 1px solid #000000;
 }
-.claro .dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg, .claro .dijitColorPalette .dijitPaletteTable .dijitPaletteCellSelected .dijitPaletteImg {
+.claro .dijitColorPalette .dijitPaletteCell:active .dijitPaletteImg,
+.claro .dijitColorPalette .dijitPaletteTable .dijitPaletteCellSelected .dijitPaletteImg {
   border: 2px solid #000000;
 }
diff --git a/dijit/themes/claro/Common.css b/dijit/themes/claro/Common.css
index 83f6128..ba9dcec 100644
--- a/dijit/themes/claro/Common.css
+++ b/dijit/themes/claro/Common.css
@@ -20,12 +20,46 @@
 
   outline: 1px dotted #494949;
 }
-/* Drag and Drop */
-.claro .dojoDndItemBefore, .claro .dojoDndItemAfter {
-  border-top: 1px solid #759dc0;
+/* Drag and Drop*/
+.claro .dojoDndItem {
+  border-color: rgba(0, 0, 0, 0);
+  -webkit-transition-duration: 0.25s;
+  -moz-transition-duration: 0.25s;
+  transition-duration: 0.25s;
+  -webkit-transition-property: background-color, border-color;
+  -moz-transition-property: background-color, border-color;
+  transition-property: background-color, border-color;
 }
 .claro .dojoDndItemOver {
-  cursor: pointer;
+  background-color: #abd6ff;
+  background-image: url("images/standardGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
+  padding: 1px;
+  border: solid 1px #759dc0;
+  color: #000000;
+}
+.claro .dojoDndItemAnchor,
+.claro .dojoDndItemSelected {
+  background-color: #cfe5fa;
+  background-image: url("images/standardGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
+  padding: 1px;
+  border: solid 1px #759dc0;
+  color: #000000;
+}
+.claro .dojoDndItemBefore,
+.claro .dojoDndItemAfter {
+  border-color: #759dc0;
 }
 .claro table.dojoDndAvatar {
   border: 1px solid #b5bcc7;
@@ -39,7 +73,8 @@
   height: 20px;
   padding-left: 21px;
 }
-.claro.dojoDndMove .dojoDndAvatarHeader, .claro.dojoDndCopy .dojoDndAvatarHeader {
+.claro.dojoDndMove .dojoDndAvatarHeader,
+.claro.dojoDndCopy .dojoDndAvatarHeader {
   background-image: url("images/dnd.png");
   background-repeat: no-repeat;
   background-position: 2px -122px;
diff --git a/dijit/themes/claro/Common.less b/dijit/themes/claro/Common.less
index 248fc1a..078d6fd 100644
--- a/dijit/themes/claro/Common.less
+++ b/dijit/themes/claro/Common.less
@@ -20,14 +20,36 @@
 	outline: 1px dotted @focus-outline-color;
 }
 
-/* Drag and Drop */
-.claro .dojoDndItemBefore,
-.claro .dojoDndItemAfter{
-	border-top: 1px solid @dnd-dropseparator-color;
+/* Drag and Drop*/
+.claro .dojoDndItem {
+	border-color: rgba(0,0,0,0);	// rgba() instead of none to prevent flash on hover fade-in
+	.transition-duration(.25s);
+	.transition-property(background-color, border-color)
 }
 .claro .dojoDndItemOver {
-	cursor:pointer;
-	}
+    // Hovered item.  Matches dijitTreeRowHover.
+	background-color:@hovered-background-color;
+	.standard-gradient;
+	padding: 1px;	// reduce from 2px in dijit.css
+	border:solid 1px @hovered-border-color;
+	color:@hovered-text-color;
+}
+.claro .dojoDndItemAnchor,
+.claro .dojoDndItemSelected {
+    // Selected items(s).   Matches dijitTreeRowSelected.
+	background-color:@selected-background-color;
+	.standard-gradient;
+	padding: 1px;	// reduce from 2px in dijit.css
+	border:solid 1px @selected-border-color;
+	color:@selected-text-color;
+}
+
+.claro .dojoDndItemBefore,
+.claro .dojoDndItemAfter {
+    // line to indicate that user is dropping before/after this dojoDndItem
+	border-color: @dnd-dropseparator-color;
+}
+
 .claro table.dojoDndAvatar {
 	border: 1px solid @border-color;
 	border-collapse: collapse;
diff --git a/dijit/themes/claro/Dialog.css b/dijit/themes/claro/Dialog.css
index ae0b18d..9ec83a6 100644
--- a/dijit/themes/claro/Dialog.css
+++ b/dijit/themes/claro/Dialog.css
@@ -56,6 +56,15 @@
   border-top: 1px solid #d3d3d3;
   margin: 10px -8px -10px;
 }
+.claro .dijitTooltipDialog .dijitDialogPaneActionBar {
+  -webkit-border-bottom-right-radius: 4px;
+  -webkit-border-bottom-left-radius: 4px;
+  border-bottom-right-radius: 4px;
+  border-bottom-left-radius: 4px;
+  -moz-border-radius-bottomright: 4px;
+  -moz-border-radius-bottomleft: 4px;
+  margin: 10px -10px -8px;
+}
 .claro .dijitDialogPaneActionBar .dijitButton {
   float: none;
 }
@@ -65,8 +74,13 @@
   border: 1px solid #ffffff;
   border-top: none;
   background-color: #abd6ff;
-  background-image: url("images/titlebar.png");
+  background-image: url("images/standardGradient.png");
   background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   padding: 5px 7px 4px 7px;
 }
 .claro .dijitDialogTitle {
@@ -96,7 +110,8 @@
   background-position: -42px;
 }
 /* Tooltip and TooltipDialog */
-.claro .dijitTooltip, .claro .dijitTooltipDialog {
+.claro .dijitTooltip,
+.claro .dijitTooltipDialog {
   /* the outermost dom node, holding the connector and container */
 
   background: transparent;
@@ -121,8 +136,10 @@
   /* the part with the text */
 
   background-color: #ffffff;
-  background-image: url("images/tooltipGradient.png");
-  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(bottom, rgba(207, 229, 250, 0.1) 0px, #ffffff 10px);
+  background-image: -webkit-linear-gradient(bottom, rgba(207, 229, 250, 0.1) 0px, #ffffff 10px);
+  background-image: -o-linear-gradient(bottom, rgba(207, 229, 250, 0.1) 0px, #ffffff 10px);
+  background-image: linear-gradient(bottom, rgba(207, 229, 250, 0.1) 0px, #ffffff 10px);
   background-position: bottom;
   border: 1px solid #759dc0;
   padding: 6px 8px;
@@ -134,9 +151,6 @@
   font-size: 1em;
   color: #000000;
 }
-.dj_ie6 .claro .dijitTooltipContainer {
-  background-image: none;
-}
 .claro .dijitTooltipConnector {
   /* the arrow piece */
 
@@ -150,13 +164,6 @@
 .dj_ie6 .claro .dijitTooltipConnector {
   background-image: url("images/tooltip8bit.png");
 }
-.claro .dijitTooltipABRight .dijitTooltipConnector {
-  /* above or below tooltip, but the arrow appears on the right,
-		and the right edges of target and tooltip are aligned rather than the left */
-
-  left: auto !important;
-  right: 3px;
-}
 .claro .dijitTooltipBelow .dijitTooltipConnector {
   /* the arrow piece for tooltips below an element */
 
@@ -175,9 +182,18 @@
   width: 16px;
   height: 14px;
 }
-.dj_ie7 .claro .dijitTooltipAbove .dijitTooltipConnector, .dj_ie6 .claro .dijitTooltipAbove .dijitTooltipConnector {
+.dj_ie7 .claro .dijitTooltipAbove .dijitTooltipConnector,
+.dj_ie6 .claro .dijitTooltipAbove .dijitTooltipConnector {
   bottom: -1px;
 }
+.claro .dijitTooltipABRight .dijitTooltipConnector {
+  /* above or below tooltip, but the arrow appears on the right,
+		and the right edges of target and tooltip are aligned rather than the left.
+		Override above rules for .dijitTooltipBelow, .dijitTooltipAbove */
+
+  left: auto;
+  right: 3px;
+}
 .claro .dijitTooltipLeft {
   padding-right: 14px;
 }
diff --git a/dijit/themes/claro/Dialog.less b/dijit/themes/claro/Dialog.less
index 5e74be7..d590f91 100644
--- a/dijit/themes/claro/Dialog.less
+++ b/dijit/themes/claro/Dialog.less
@@ -59,6 +59,15 @@
 	border-top: 1px solid @minor-border-color;
 	margin: 10px -8px -10px;
 }
+.claro .dijitTooltipDialog .dijitDialogPaneActionBar {
+  -webkit-border-bottom-right-radius: 4px;
+  -webkit-border-bottom-left-radius: 4px;
+  border-bottom-right-radius: 4px;
+  border-bottom-left-radius: 4px;
+  -moz-border-radius-bottomright: 4px;
+  -moz-border-radius-bottomleft: 4px;
+  margin: 10px -10px -8px;
+}
 .claro .dijitDialogPaneActionBar .dijitButton {
 	float: none;
 }
@@ -68,8 +77,7 @@
 	border: 1px solid @dialog-titlebar-border-color;
 	border-top:none;
 	background-color: @dialog-titlebar-background-color;
-	background-image: url(@image-titlebar);
-	background-repeat:repeat-x;
+	.standard-gradient;
 	padding: 5px 7px 4px 7px;
 }
 
@@ -123,8 +131,7 @@
 .claro .dijitTooltipContainer {
 	/* the part with the text */
 	background-color:@popup-background-color;
-	background-image:url(@image-tooltip-gradient);
-	background-repeat:repeat-x;
+	.linear-gradient(bottom, @tooltip-gradient-color 0px, @popup-background-color 10px);
 	background-position:bottom;
 	border:1px solid @popup-border-color;
 	padding:6px 8px;
@@ -134,9 +141,6 @@
 	color: @text-color;
 } 
 
-.dj_ie6 .claro .dijitTooltipContainer {
-	background-image: none;
-}
 .claro .dijitTooltipConnector {
 	/* the arrow piece */
 	border: 0;
@@ -149,12 +153,6 @@
 .dj_ie6 .claro .dijitTooltipConnector {
 	background-image:url(@image-tooltip-ie6);
 }
-.claro .dijitTooltipABRight .dijitTooltipConnector {
-	/* above or below tooltip, but the arrow appears on the right,
-		and the right edges of target and tooltip are aligned rather than the left */
-	left: auto !important;
-	right: 3px;
-}
 
 .claro .dijitTooltipBelow .dijitTooltipConnector {
 	/* the arrow piece for tooltips below an element */
@@ -178,6 +176,15 @@
 	bottom: -1px;
 }
 
+.claro .dijitTooltipABRight .dijitTooltipConnector {
+	/* above or below tooltip, but the arrow appears on the right,
+		and the right edges of target and tooltip are aligned rather than the left.
+		Override above rules for .dijitTooltipBelow, .dijitTooltipAbove */
+	left: auto;
+	right: 3px;
+}
+
+
 .claro .dijitTooltipLeft {
 	padding-right: 14px;
 }
diff --git a/dijit/themes/claro/Editor.css b/dijit/themes/claro/Editor.css
index 9f167f9..0d6f59c 100644
--- a/dijit/themes/claro/Editor.css
+++ b/dijit/themes/claro/Editor.css
@@ -25,26 +25,31 @@
 }
 .claro .dijitEditor .dijitEditorIFrameContainer {
   background-color: #ffffff;
-  background-image: url("form/images/textBox_back.png");
   background-repeat: repeat-x;
 }
-.dj_ie6 .claro .dijitEditor .dijitEditorIFrameContainer {
-  background-image: none;
-}
-.claro .dijitEditorHover .dijitEditorIFrameContainer, .claro .dijitEditorHover .dijitEditorIFrameContainer .dijitEditorIFrame {
+.claro .dijitEditorHover .dijitEditorIFrameContainer,
+.claro .dijitEditorHover .dijitEditorIFrameContainer .dijitEditorIFrame {
   background-color: #e5f2fe;
 }
-.claro .dijitEditorFocused .dijitEditorIFrameContainer, .claro .dijitEditorFocused .dijitEditorIFrameContainer .dijitEditorIFrame {
-  /* TODO: contradicts rule above, which background-color do you want? */
-
+.claro .dijitEditorFocused .dijitEditorIFrameContainer,
+.claro .dijitEditorFocused .dijitEditorIFrameContainer .dijitEditorIFrame {
   background-color: #ffffff;
 }
+.claro .dijitEditorHover .dijitEditorIFrameContainer,
+.claro .dijitEditorFocused .dijitEditorIFrameContainer {
+  background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: -o-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+}
 /* Disabled */
 .claro .dijitEditorDisabled {
   border: 1px solid #d3d3d3;
   color: #818181;
 }
-.claro .dijitDisabled .dijitEditorIFrame, .claro .dijitDisabled .dijitEditorIFrameContainer, .claro .dijitDisabled .dijitEditorIFrameContainer .dijitEditorIFrame {
+.claro .dijitDisabled .dijitEditorIFrame,
+.claro .dijitDisabled .dijitEditorIFrameContainer,
+.claro .dijitDisabled .dijitEditorIFrameContainer .dijitEditorIFrame {
   background-color: #efefef;
   background-image: none;
 }
diff --git a/dijit/themes/claro/Editor.less b/dijit/themes/claro/Editor.less
index f74a5d4..ddc59cc 100644
--- a/dijit/themes/claro/Editor.less
+++ b/dijit/themes/claro/Editor.less
@@ -28,22 +28,20 @@
 }
 .claro .dijitEditor .dijitEditorIFrameContainer{
 	background-color: @textbox-background-color;
-	background-image: url(@image-form-textbox-background);
 	background-repeat:repeat-x;
 }
-.dj_ie6 .claro .dijitEditor .dijitEditorIFrameContainer{
-	background-image: none;
-}
 .claro .dijitEditorHover .dijitEditorIFrameContainer,
 .claro .dijitEditorHover .dijitEditorIFrameContainer .dijitEditorIFrame{
 	background-color: @textbox-hovered-background-color;
 }
 .claro .dijitEditorFocused .dijitEditorIFrameContainer,
 .claro .dijitEditorFocused .dijitEditorIFrameContainer .dijitEditorIFrame{
-	/* TODO: contradicts rule above, which background-color do you want? */
 	background-color: @textbox-focused-background-color;
 }
-
+.claro .dijitEditorHover .dijitEditorIFrameContainer,
+.claro .dijitEditorFocused .dijitEditorIFrameContainer {
+	.textbox-background-image;
+}
 
 /* Disabled */
 .claro .dijitEditorDisabled {
diff --git a/dijit/themes/claro/Editor_rtl.css b/dijit/themes/claro/Editor_rtl.css
index f633558..01ae2e5 100644
--- a/dijit/themes/claro/Editor_rtl.css
+++ b/dijit/themes/claro/Editor_rtl.css
@@ -2,3 +2,10 @@
 .claro .dijitEditorRtl .dijitEditorIFrameContainer {
   padding: 3px 10px 1px 3px;
 }
+.dj_ie6 .claro .dijitEditorRtl .dijitEditorIFrameContainer,
+.dj_ie7 .claro .dijitEditorRtl .dijitEditorIFrameContainer,
+.dj_ie8 .claro .dijitEditorRtl .dijitEditorIFrameContainer {
+  padding: 3px 0px 1px 10px;
+  margin-right: 0px;
+  border: 0px solid #d3d3d3;
+}
diff --git a/dijit/themes/claro/Editor_rtl.less b/dijit/themes/claro/Editor_rtl.less
index 8ebc013..3d79db4 100644
--- a/dijit/themes/claro/Editor_rtl.less
+++ b/dijit/themes/claro/Editor_rtl.less
@@ -2,8 +2,15 @@
 
 @import "variables";
 
-.claro .dijitEditorRtl .dijitEditorIFrameContainer{
-	padding:3px 10px 1px 3px;
+.claro .dijitEditorRtl .dijitEditorIFrameContainer {
+	padding: 3px 10px 1px 3px;
 }
 
-
+.dj_ie6 .claro .dijitEditorRtl .dijitEditorIFrameContainer,
+.dj_ie7 .claro .dijitEditorRtl .dijitEditorIFrameContainer,
+.dj_ie8 .claro .dijitEditorRtl .dijitEditorIFrameContainer {
+	// remove excessive right margin (due to IE bug)
+	padding: 3px 0px 1px 10px;
+	margin-right: 0px;
+	border: 0px solid #d3d3d3;
+}
diff --git a/dijit/themes/claro/Menu.css b/dijit/themes/claro/Menu.css
index e1c1562..638719b 100644
--- a/dijit/themes/claro/Menu.css
+++ b/dijit/themes/claro/Menu.css
@@ -4,13 +4,13 @@ There are three areas of styling for the Menu:
  
  1. The menu 
  	There are three types of menus:
- 	i)Context Menu
- 	ii)Drop down Menu
+ 	i) Context Menu
+ 	ii) Drop down Menu
  	iii) Navigation Menu
  	All three types of menus are affected by the .dijitMenu class in which you can set the background-color, padding and border
  	.dijitMenu affects the drop down menu in TimeTextBox, Calendar, ComboBox and FilteringSelect
   .dijitMenuTable - for padding - also affects Select widget 	
-  	
+
  2. The menu bar
  	.dijitMenuBar - for border, margins, padding, background-color of the menu bar
  	.dijitMenuBar .dijitMenuItem - for padding, text color of menu items in the menu bar (overrides .dijitMenuItem) 
@@ -18,7 +18,7 @@ There are three areas of styling for the Menu:
  3. Menu items - items in the menu.  
  	.dijitMenuItem - for color
  	.dijitMenuItemHover, .dijitMenuItemSelected - for background-color, border, text color, padding of a menu item or menubar item that has been hovered over or selected	
- 	.dijitMenuItemActive - for bacgkround-color of an active (mousedown) menu item
+ 	.dijitMenuItemActive - for background-color of an active (mousedown) menu item
 	td.dijitMenuItemIconCell - for padding around a  menu item's icon
 	td.dijitMenuItemLabel - for padding around a menu item's label	
 	.dijitMenuSeparatorTop - for border, top border, of the separator
@@ -34,36 +34,29 @@ There are three areas of styling for the Menu:
   margin: 0;
   padding: 0;
   background-color: #efefef;
-  background-image: url("images/commonHighlight.png");
-  background-position: 0 0;
+  background-image: url("images/standardGradient.png");
   background-repeat: repeat-x;
-}
-.dj_ie6 .claro .dijitMenuBar {
-  background-image: none;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
 }
 .claro .dijitMenu {
-  background-repeat: repeat-y;
   background-color: #ffffff;
   border: 1px solid #759dc0;
-  /* so adjoining borders of MenuBar/ComboBox and Menu overlap, avoiding double border */
-
-  margin: -1px 0;
 }
-.dj_ie6 .claro .dijitMenu {
-  margin: 0;
-  /* above -1px makes top/bottom borders disappear on IE6 */
-
+.claro .dijitMenuItem {
+  color: #000000;
 }
 .claro .dijitMenuBar .dijitMenuItem {
   padding: 6px 10px 7px;
-  background-position: 0 100px;
   margin: -1px;
 }
-.claro .dijitMenuItem {
-  background-image: url("images/menuHighlight.png");
-  background-position: 0 -40px;
-  background-repeat: repeat-x;
-  color: #000000;
+.claro .dijitMenuBar .dijitMenuItemHover,
+.claro .dijitMenuBar .dijitMenuItemSelected {
+  border: solid 1px #759dc0;
+  padding: 5px 9px 6px;
 }
 /* this prevents jiggling upon hover of a menu item */
 .claro .dijitMenuTable {
@@ -71,30 +64,37 @@ There are three areas of styling for the Menu:
   border-spacing: 0 0;
   padding: 0;
 }
-.claro .dijitMenuItem td {
-  padding: 1px;
+.claro .dijitMenu .dijitMenuItem td,
+.claro .dijitComboBoxMenu .dijitMenuItem {
+  padding: 2px;
+  border-width: 1px 0 1px 0;
+  border-style: solid;
+  border-color: #ffffff;
 }
-/* hover over a MenuBarItem */
-.claro .dijitMenuPassive .dijitMenuItemHover, .claro .dijitMenuPassive .dijitMenuItemSelected {
+/* hover over a MenuItem or MenuBarItem */
+.claro .dijitMenu .dijitMenuItemHover td,
+.claro .dijitMenu .dijitMenuItemSelected td,
+.claro .dijitMenuItemHover,
+.claro .dijitComboBoxMenu .dijitMenuItemHover,
+.claro .dijitMenuItemSelected {
+  border-color: #759dc0;
   background-color: #abd6ff;
-  border: solid 1px #759dc0;
-  background-position: 0 0;
-  color: #000000;
-  padding: 5px 9px 6px;
-}
-.claro .dijitMenuPassive .dijitMenuItemActive {
-  background-position: 0 -177px;
-}
-.dj_ie6 .claro .dijitMenuItem, .dj_ie6 .claro .dijitMenuPassive .dijitMenuItem {
-  background-image: none;
+  background-image: url("images/standardGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
 }
-/* MenuBarItem that has been selected and menu drops down from it */
-.claro .dijitMenuActive .dijitMenuItemHover, .claro .dijitMenuActive .dijitMenuItemSelected {
-  border: solid 1px #759dc0;
-  padding: 5px 9px 6px;
-  background-color: #abd6ff;
-  background-position: 0 0;
-  color: #000000;
+.claro .dijitMenuItemActive {
+  background-image: url("images/activeGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
 }
 .dj_ie .claro .dijitMenuActive .dijitMenuItemHover,
 .dj_ie .claro .dijitMenuActive .dijitMenuItemSelected,
@@ -104,13 +104,6 @@ There are three areas of styling for the Menu:
   padding-bottom: 5px;
   margin-top: -3px;
 }
-.claro .dijitMenuActive .dijitMenuItemActive {
-  background-color: #7dbdfa;
-  background-position: 0 -177px;
-}
-.claro .dijitMenuItemActive {
-  background-position: 0 -177px;
-}
 .claro td.dijitMenuItemIconCell {
   padding: 2px;
   margin: 0 0 0 4px;
@@ -125,6 +118,7 @@ There are three areas of styling for the Menu:
   background-image: url("images/spriteArrows.png");
   background-position: -14px 0;
   margin-right: 3px;
+  margin-bottom: 4px;
 }
 .claro .dijitMenuItemDisabled .dijitMenuItemIconCell {
   opacity: 1;
@@ -141,50 +135,52 @@ There are three areas of styling for the Menu:
   margin-bottom: 1px;
 }
 /* the checked menu item */
-.claro .dijitCheckedMenuItemIconChar {
-  display: none;
-}
-.claro .dijitCheckedMenuItemIcon {
+.claro .dijitCheckedMenuItem .dijitMenuItemIcon,
+.claro .dijitRadioMenuItem .dijitMenuItemIcon {
   background-image: url("form/images/checkboxRadioButtonStates.png");
   background-repeat: no-repeat;
   background-position: -15px 50%;
+  /* unchecked checkbox */
+
   width: 15px;
   height: 16px;
 }
-.dj_ie6 .claro .dijitCheckedMenuItemIcon {
+.dj_ie6 .claro .dijitCheckedMenuItem .dijitMenuItemIcon,
+.dj_ie6 .claro .dijitRadioMenuItem .dijitMenuItemIcon {
   background-image: url("form/images/checkboxAndRadioButtons_IE6.png");
 }
 .claro .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
   background-position: 0 50%;
+  /* checked checkbox */
+
+}
+.claro .dijitRadioMenuItem .dijitMenuItemIcon {
+  background-position: -105px 50%;
+  /* unfilled circle */
+
+}
+.claro .dijitRadioMenuItemChecked .dijitMenuItemIcon {
+  background-position: -90px 50%;
+  /* filled circle */
+
 }
 /*ComboBox Menu*/
 .claro .dijitComboBoxMenu {
   margin-left: 0;
   background-image: none;
 }
-.claro .dijitComboBoxMenu .dijitMenuItem {
-  padding: 2px;
-  border-width: 1px 0 1px 0;
-  border-style: solid;
-  border-color: #ffffff;
-}
+.claro .dijitMenu .dijitMenuItemSelected td,
 .claro .dijitComboBoxMenu .dijitMenuItemSelected {
   color: #000000;
   border-color: #759dc0;
   background-color: #abd6ff;
 }
-.claro .dijitComboBoxMenu .dijitMenuItemHover {
-  color: #000000;
-  border-color: #769dc0;
-  background-color: #abd6ff;
-  background-position: 0 0;
-}
 .claro .dijitComboBoxMenuActive .dijitMenuItemSelected {
-  background-position: 0 -177px;
   background-color: #7dbdfa;
   /* TODO: why is this a different color than normal .dijitMenuItemSelected? */
 
 }
-.claro .dijitMenuPreviousButton, .claro .dijitMenuNextButton {
+.claro .dijitMenuPreviousButton,
+.claro .dijitMenuNextButton {
   font-style: italic;
 }
diff --git a/dijit/themes/claro/Menu.less b/dijit/themes/claro/Menu.less
index 80467a5..16e08bd 100644
--- a/dijit/themes/claro/Menu.less
+++ b/dijit/themes/claro/Menu.less
@@ -4,13 +4,13 @@ There are three areas of styling for the Menu:
  
  1. The menu 
  	There are three types of menus:
- 	i)Context Menu
- 	ii)Drop down Menu
+ 	i) Context Menu
+ 	ii) Drop down Menu
  	iii) Navigation Menu
  	All three types of menus are affected by the .dijitMenu class in which you can set the background-color, padding and border
  	.dijitMenu affects the drop down menu in TimeTextBox, Calendar, ComboBox and FilteringSelect
   .dijitMenuTable - for padding - also affects Select widget 	
-  	
+
  2. The menu bar
  	.dijitMenuBar - for border, margins, padding, background-color of the menu bar
  	.dijitMenuBar .dijitMenuItem - for padding, text color of menu items in the menu bar (overrides .dijitMenuItem) 
@@ -18,7 +18,7 @@ There are three areas of styling for the Menu:
  3. Menu items - items in the menu.  
  	.dijitMenuItem - for color
  	.dijitMenuItemHover, .dijitMenuItemSelected - for background-color, border, text color, padding of a menu item or menubar item that has been hovered over or selected	
- 	.dijitMenuItemActive - for bacgkround-color of an active (mousedown) menu item
+ 	.dijitMenuItemActive - for background-color of an active (mousedown) menu item
 	td.dijitMenuItemIconCell - for padding around a  menu item's icon
 	td.dijitMenuItemLabel - for padding around a menu item's label	
 	.dijitMenuSeparatorTop - for border, top border, of the separator
@@ -37,34 +37,26 @@ There are three areas of styling for the Menu:
 	margin: 0;
 	padding: 0;
 	background-color: @bar-background-color;
-	background-image: url(@image-common-highlight);
-	background-position:0 0;
-	background-repeat:repeat-x;
-}
-.dj_ie6 .claro .dijitMenuBar {
-	background-image:none;
+	.standard-gradient;
 }
+
 .claro .dijitMenu {
-	background-repeat:repeat-y;
 	background-color:@menu-background-color;
 	border: 1px solid @popup-border-color;
-
-	/* so adjoining borders of MenuBar/ComboBox and Menu overlap, avoiding double border */
-	margin: -1px 0;
 }
-.dj_ie6 .claro .dijitMenu {
-	margin: 0;	/* above -1px makes top/bottom borders disappear on IE6 */
+
+.claro .dijitMenuItem {
+	color: @text-color;
 }
-.claro .dijitMenuBar .dijitMenuItem {  
+.claro .dijitMenuBar .dijitMenuItem {
 	padding: 6px 10px 7px;
-	background-position:0 100px;
 	margin:-1px;
-}	
-.claro .dijitMenuItem {
-	background-image: url(@image-menu-highlight);
-	background-position:0 -40px;
-	background-repeat:repeat-x;
-	color: @text-color;
+}
+.claro .dijitMenuBar .dijitMenuItemHover,
+.claro .dijitMenuBar .dijitMenuItemSelected {
+	// on hover or selection of MenuBar item, add border and reduce padding to compensate
+	border:solid 1px @hovered-border-color;
+	padding: 5px 9px 6px;
 }
 
 /* this prevents jiggling upon hover of a menu item */
@@ -73,53 +65,48 @@ There are three areas of styling for the Menu:
 	border-spacing:0 0;
 	padding:0;
 }
-.claro .dijitMenuItem td{
-	padding:1px;
+
+.claro .dijitMenu .dijitMenuItem td,
+.claro .dijitComboBoxMenu .dijitMenuItem {
+	padding: @textbox-padding;	// Make drop down menu text line up with text in <input>.
+	border-width:1px 0 1px 0;
+	border-style:solid;
+	border-color: @select-dropdownitem-background-color;
 }
-/* hover over a MenuBarItem */
-.claro .dijitMenuPassive .dijitMenuItemHover,
-.claro .dijitMenuPassive .dijitMenuItemSelected {
+
+/* hover over a MenuItem or MenuBarItem */
+.claro .dijitMenu .dijitMenuItemHover td,
+.claro .dijitMenu .dijitMenuItemSelected td,
+.claro .dijitMenuItemHover,
+.claro .dijitComboBoxMenu .dijitMenuItemHover,
+.claro .dijitMenuItemSelected {
+	// note: seems like the selected MenuItem should use @pressed-background-color
+	// and .active-gradient, but claro didn't to that
+	border-color: @hovered-border-color;
 	background-color: @hovered-background-color;
-	border:solid 1px @hovered-border-color;
-	background-position:0 0;
-	color:@text-color;
-	padding: 5px 9px 6px;
-}
-.claro .dijitMenuPassive .dijitMenuItemActive{
-	background-position:0 -177px;
-}
-.dj_ie6 .claro .dijitMenuItem,
-.dj_ie6 .claro .dijitMenuPassive .dijitMenuItem {
-	background-image: none;
+	.standard-gradient;
 }
 
-/* MenuBarItem that has been selected and menu drops down from it */
-.claro .dijitMenuActive .dijitMenuItemHover,
-.claro .dijitMenuActive .dijitMenuItemSelected {
-	border:solid 1px @hovered-border-color;
-	padding: 5px 9px 6px;
-	background-color: @hovered-background-color;
-	background-position:0 0;
-	color:@hovered-text-color;
+.claro .dijitMenuItemActive {
+	// todo: seems like the selected MenuItem should come here
+	// todo: seems like should use @pressed-background-color
+	.active-gradient;
 }
 .dj_ie .claro .dijitMenuActive .dijitMenuItemHover,
 .dj_ie .claro .dijitMenuActive .dijitMenuItemSelected,
 .dj_ie .claro .dijitMenuPassive .dijitMenuItemHover,
 .dj_ie .claro .dijitMenuPassive .dijitMenuItemSelected {
+	// Selectivity set to override ComboBox rules below.
+	// If this rule isn't present, on IE6 hovering an item in the ComboBox drop down causes two
+	// items to be highlighted (except when hovering the first item in the list)
 	padding-top: 6px;
 	padding-bottom: 5px;
 	margin-top: -3px;
 }
-.claro .dijitMenuActive .dijitMenuItemActive{
-	background-color: @pressed-background-color;
-	background-position:0 -177px;
-}
-.claro .dijitMenuItemActive {
-	background-position:0 -177px;
-}
+
 .claro td.dijitMenuItemIconCell {
- padding: 2px;
- margin: 0 0 0 4px;
+	padding: 2px;
+	margin: 0 0 0 4px;
 }
 .claro td.dijitMenuItemLabel {
 	padding-top: 5px;
@@ -131,6 +118,7 @@ There are three areas of styling for the Menu:
 	background-image: url(@image-arrow-sprite);
 	background-position: -14px 0;
 	margin-right:3px;
+	margin-bottom: 4px;
 }
 .claro .dijitMenuItemDisabled .dijitMenuItemIconCell {
 	opacity:1;
@@ -145,21 +133,26 @@ There are three areas of styling for the Menu:
 	margin-bottom:1px;
 }
 /* the checked menu item */
-.claro .dijitCheckedMenuItemIconChar {
-	display: none;
-}
-.claro .dijitCheckedMenuItemIcon {
+.claro .dijitCheckedMenuItem .dijitMenuItemIcon,
+.claro .dijitRadioMenuItem .dijitMenuItemIcon {
 	background-image: url(@image-form-checkbox-and-radios);
 	background-repeat:no-repeat;
-	background-position: -15px 50%;
+	background-position: -15px 50%;	/* unchecked checkbox */
 	width:15px;
 	height:16px;
 }
-.dj_ie6 .claro .dijitCheckedMenuItemIcon {
+.dj_ie6 .claro .dijitCheckedMenuItem .dijitMenuItemIcon,
+.dj_ie6 .claro .dijitRadioMenuItem .dijitMenuItemIcon {
 	background-image: url(@image-form-checkbox-and-radios-ie6);
 }
 .claro .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
-	background-position: 0 50%;
+	background-position: 0 50%;	/* checked checkbox */
+}
+.claro .dijitRadioMenuItem .dijitMenuItemIcon {
+  background-position: -105px 50%;	/* unfilled circle */
+}
+.claro .dijitRadioMenuItemChecked .dijitMenuItemIcon {
+  background-position: -90px 50%;	/* filled circle */
 }
 
 /*ComboBox Menu*/
@@ -168,25 +161,17 @@ There are three areas of styling for the Menu:
 	background-image: none;
 }
 
-.claro .dijitComboBoxMenu .dijitMenuItem {
-	padding: @textbox-padding;	// Make drop down menu text line up with text in <input>.
-	border-width:1px 0 1px 0;
-	border-style:solid;
-	border-color: @select-dropdownitem-background-color;
-}
+.claro .dijitMenu .dijitMenuItemSelected td,
 .claro .dijitComboBoxMenu .dijitMenuItemSelected {
+	// TODO: combine with above rules for selected items?
+	// But the selected item in a Select drop down is different than when MenuBarItem "File" is highlighted
+	// because the user is on the file menu?
 	color:@selected-text-color;
 	border-color:@hovered-border-color;
 	background-color:@hovered-background-color;
 }
-.claro .dijitComboBoxMenu .dijitMenuItemHover {
-	color: #000000;
-	border-color: #769dc0;
-	background-color: #abd6ff;
-	background-position: 0 0;
-}
+
 .claro .dijitComboBoxMenuActive .dijitMenuItemSelected {
-	background-position:0 -177px;
 	background-color: @select-dropdownitem-hovered-background-color;	/* TODO: why is this a different color than normal .dijitMenuItemSelected? */
 }
 .claro .dijitMenuPreviousButton, .claro .dijitMenuNextButton {
diff --git a/dijit/themes/claro/ProgressBar.css b/dijit/themes/claro/ProgressBar.css
index 925021f..1b7cf67 100644
--- a/dijit/themes/claro/ProgressBar.css
+++ b/dijit/themes/claro/ProgressBar.css
@@ -30,19 +30,27 @@
 .claro .dijitProgressBarEmpty {
   /* outer container and background of the bar that's not finished yet*/
 
-  background: #ffffff url("images/progressBarEmpty.png") no-repeat left;
+  background-color: #ffffff;
   border-color: #759dc0;
 }
 .claro .dijitProgressBarTile {
   /* inner container for finished portion when in 'tile' (image) mode */
 
-  background: #abd6ff url("images/progressBarFull.png") repeat-x top;
+  background-color: #abd6ff;
+  background-image: url("images/progressBarFull.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
+  background-attachment: scroll;
 }
 .dj_ie6 .claro .dijitProgressBarTile {
   background-image: none;
 }
 .claro .dijitProgressBarFull {
-  border-right: 1px solid #759dc0;
+  border: 0px solid #759dc0;
+  border-right-width: 1px;
   -webkit-transition-property: width;
   -moz-transition-property: width;
   transition-property: width;
diff --git a/dijit/themes/claro/ProgressBar.less b/dijit/themes/claro/ProgressBar.less
index 8edf426..2bc2914 100644
--- a/dijit/themes/claro/ProgressBar.less
+++ b/dijit/themes/claro/ProgressBar.less
@@ -32,18 +32,25 @@
 }
 .claro .dijitProgressBarEmpty {
 	/* outer container and background of the bar that's not finished yet*/
-	background: @progressbar-empty-background-color url(@image-progressbar-empty) no-repeat left;
+	background-color: @progressbar-empty-background-color;
 	border-color: @progressbar-border-color;
 }
 .claro .dijitProgressBarTile {
 	/* inner container for finished portion when in 'tile' (image) mode */
-	background: @progressbar-full-background-color url(@image-progressbar-full) repeat-x top;	
+	background-color: @progressbar-full-background-color;
+
+	// gradient background using CSS gradient, with fallback to image for IE
+	background-image: url("images/progressBarFull.png");
+	background-repeat: repeat-x;
+	.alpha-white-gradient(0.93,0px, 0.41,1px, 0.7,2px, 0,100%);
+	background-attachment: scroll;	// override strange "fixed" setting from dijit.css
 }
 .dj_ie6 .claro .dijitProgressBarTile {
 	background-image: none;
 } 
 .claro .dijitProgressBarFull {
-	border-right:1px solid @progressbar-border-color;
+	border: 0px solid @progressbar-border-color;
+	border-right-width: 1px;
 	.transition-property(width);
 	.transition-duration(.25s);
 }
diff --git a/dijit/themes/claro/ProgressBar_rtl.css b/dijit/themes/claro/ProgressBar_rtl.css
new file mode 100644
index 0000000..f92a63f
--- /dev/null
+++ b/dijit/themes/claro/ProgressBar_rtl.css
@@ -0,0 +1,8 @@
+/* ProgressBar
+ * 
+ * Styling of the ProgressBar when RTL direction is specified
+ */
+.claro .dijitProgressBarRtl .dijitProgressBarFull {
+  border-left-width: 1px;
+  border-right-width: 0px;
+}
diff --git a/dijit/themes/claro/ProgressBar_rtl.less b/dijit/themes/claro/ProgressBar_rtl.less
new file mode 100644
index 0000000..30ec6fe
--- /dev/null
+++ b/dijit/themes/claro/ProgressBar_rtl.less
@@ -0,0 +1,11 @@
+/* ProgressBar
+ * 
+ * Styling of the ProgressBar when RTL direction is specified
+ */
+ 
+ at import "variables";
+ 
+.claro  .dijitProgressBarRtl .dijitProgressBarFull {
+	border-left-width: 1px;
+	border-right-width: 0px;
+}
diff --git a/dijit/themes/claro/README b/dijit/themes/claro/README
index 3b4b4aa..0a25462 100644
--- a/dijit/themes/claro/README
+++ b/dijit/themes/claro/README
@@ -1,41 +1,11 @@
 These are "less" files that compile into the CSS of claro.
 
----------
-Installing and running on Windows:
-
-1. Install node:
-    a) Go to https://github.com/ajaxorg/node-builds, press download button, and select "download zip"
-    b) unzip the file into C:\
-
-2. Add node environment variables:
-
-    a) open Control Panel --> click System icon --> select Advanced tab --> click Environment variables button
-    b) press "edit" on path
-    c) depending on what directory you unzipped to and the exact filenames, you will add something like
-
-	;C:\ajaxorg-node-builds-0fcee7d\win32
-
-4. To compile all the files:
-
-	C:\> cd C:\myworkspace\dijit\themes\claro
-	C:\> node compile.js
-
---------
-To install/run less version 2 on mac:
-
-1. Install Node.js
-	Download a built copy from https://github.com/ajaxorg/node-builds.
-	Alternately, go to http://nodejs.org/#download   (./configure, make, make install).
+1. Install node from http://nodejs.org/#download
 	
-2. Edit .bash_profile etc. to add node to your path
-
-	export PATH=$PATH:/opt/less/bin
-
-To compile all the files:
+2. To compile all the files:
 
   $ cd dijit/themes/claro
   $ node compile.js
 
------
 
 See http://lesscss.org/ and https://github.com/cloudhead/less.js/ for more information.
diff --git a/dijit/themes/claro/TimePicker.css b/dijit/themes/claro/TimePicker.css
index c8d6bb2..d1573b7 100644
--- a/dijit/themes/claro/TimePicker.css
+++ b/dijit/themes/claro/TimePicker.css
@@ -35,19 +35,17 @@
 .claro .dijitTimePickerItem {
   /* dijitTimePickerItem refers to both Tick's (minor values like 2:15, 2:30, 2:45) and Marker's (major values like 2PM, 3PM) */
 
-  background-image: url("images/commonHighlight.png");
-  background-position: 0 -1px;
+  background-image: url("images/standardGradient.png");
   background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   border-top: solid 1px #b5bcc7;
   border-bottom: solid 1px #b5bcc7;
-  margin-right: -1px;
-  margin-left: -1px;
   margin-top: -1px;
 }
-/* to make up for lack of alpha transparency in IE6 */
-.dj_ie6 .claro .dijitTimePickerItem {
-  background-image: none;
-}
 .claro .dijitTimePickerTick {
   /* minor value */
 
@@ -67,30 +65,12 @@
 .claro .dijitTimePickerMarkerSelected,
 .claro .dijitTimePickerTickSelected {
   background-color: #7dbdfa;
-  border: solid 1px #b5bcc7;
-  margin-left: -7px;
-  margin-right: -7px;
   color: #000000;
 }
-.claro .dijitTimePickerMarkerSelected, .claro .dijitTimePickerTickSelected {
+.claro .dijitTimePickerMarkerSelected,
+.claro .dijitTimePickerTickSelected {
   font-size: 1em;
 }
-.dj_ie .claro .dijitTimePickerTickHover,
-.dj_ie .claro .dijitTimePickerMarkerHover,
-.dj_ie .claro .dijitTimePickerMarkerSelected,
-.dj_ie .claro .dijitTimePickerTickSelected {
-  width: 114%;
-}
-.dj_ie6 .claro .dijitTimePickerTickHover,
-.dj_ie6 .claro .dijitTimePickerMarkerHover,
-.dj_ie6 .claro .dijitTimePickerMarkerSelected,
-.dj_ie6 .claro .dijitTimePickerTickSelected {
-  position: relative;
-  /* creates widening of element */
-  zoom: 1;
-  /* creates widening of element */
-
-}
 .claro .dijitTimePickerTick .dijitTimePickerItemInner {
   padding: 1px;
   margin: 0;
@@ -100,12 +80,13 @@
   border-right: none;
   border-color: #b5bcc7;
   background-color: #efefef;
-  background-image: url("images/commonHighlight.png");
-  background-position: 0 -1px;
+  background-image: url("images/standardGradient.png");
   background-repeat: repeat-x;
-}
-.dj_ie6 .claro .dijitTimePicker .dijitButtonNode {
-  background-image: none;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
 }
 .claro .dijitTimePicker .dijitArrowButtonInner {
   height: 100%;
@@ -119,7 +100,8 @@
   background-position: -35px 45%;
 }
 /* hover */
-.claro .dijitTimePicker .dijitUpArrowHover, .claro .dijitTimePicker .dijitDownArrowHover {
+.claro .dijitTimePicker .dijitUpArrowHover,
+.claro .dijitTimePicker .dijitDownArrowHover {
   background-color: #abd6ff;
 }
 .claro .dijitTimePicker .dijitUpArrowHover .dijitArrowButtonInner {
diff --git a/dijit/themes/claro/TimePicker.less b/dijit/themes/claro/TimePicker.less
index a6253f7..caacbe9 100644
--- a/dijit/themes/claro/TimePicker.less
+++ b/dijit/themes/claro/TimePicker.less
@@ -26,27 +26,19 @@
 	padding: 0 0;
 	.border-radius(0);
 }
-.claro .dijitTimePicker{
+.claro .dijitTimePicker {
 	border:1px @border-color solid;
 	border-top:none;
 	border-bottom:none;
 	background-color:#fff;	/* TODO: useless?   Appears to be overridden by settings on individual elements */
 }
-.claro .dijitTimePickerItem{
+.claro .dijitTimePickerItem {
 	/* dijitTimePickerItem refers to both Tick's (minor values like 2:15, 2:30, 2:45) and Marker's (major values like 2PM, 3PM) */
-	background-image: url(@image-common-highlight);
-	background-position:0 -1px;
-	background-repeat:repeat-x;
+	.standard-gradient;
 	border-top:solid 1px @border-color;
 	border-bottom:solid 1px @border-color;
-	margin-right:-1px;
-	margin-left:-1px;
 	margin-top:-1px;
 }
-/* to make up for lack of alpha transparency in IE6 */
-.dj_ie6 .claro .dijitTimePickerItem {
-	background-image: none;
-}
 .claro .dijitTimePickerTick {
 	/* minor value */
 	color:@timepicker-minorvalue-text-color;
@@ -64,28 +56,13 @@
 .claro .dijitTimePickerMarkerSelected,
 .claro .dijitTimePickerTickSelected {
 	background-color: @timepicker-value-hovered-background-color;
-	border:solid 1px @border-color;
-	margin-left:-7px;
-	margin-right:-7px;
 	color:@timepicker-value-hovered-text-color;
 }
 .claro .dijitTimePickerMarkerSelected,
 .claro .dijitTimePickerTickSelected {
 	font-size: 1em;
 }
-.dj_ie .claro .dijitTimePickerTickHover,
-.dj_ie .claro .dijitTimePickerMarkerHover,
-.dj_ie .claro .dijitTimePickerMarkerSelected,
-.dj_ie .claro .dijitTimePickerTickSelected  {
-	width: 114%;
-}
-.dj_ie6 .claro .dijitTimePickerTickHover,
-.dj_ie6 .claro .dijitTimePickerMarkerHover,
-.dj_ie6 .claro .dijitTimePickerMarkerSelected,
-.dj_ie6 .claro .dijitTimePickerTickSelected  {
-	position: relative; /* creates widening of element */	
-	zoom: 1; /* creates widening of element */
-}
+
 .claro .dijitTimePickerTick .dijitTimePickerItemInner {
 	padding:1px;
 	margin:0;
@@ -95,20 +72,15 @@
 	border-right:none;
 	border-color:@border-color;
 	background-color: @unselected-background-color;
-	background-image: url(@image-common-highlight);
-	background-position:0 -1px;
-	background-repeat:repeat-x;
-}
-.dj_ie6 .claro .dijitTimePicker .dijitButtonNode {
-	background-image: none;
+	.standard-gradient;
 }
-.claro .dijitTimePicker .dijitArrowButtonInner{
+.claro .dijitTimePicker .dijitArrowButtonInner {
 	height: 100%; /* hack claro.button.css */
 	background-image: url(@image-form-common-arrows);
 	background-repeat: no-repeat;
 	background-position:-140px 45%;
 }
-.claro .dijitTimePicker .dijitDownArrowButton .dijitArrowButtonInner{
+.claro .dijitTimePicker .dijitDownArrowButton .dijitArrowButtonInner {
 	background-position:-35px 45%;
 }
 /* hover */
@@ -122,3 +94,5 @@
 .claro .dijitTimePicker .dijitDownArrowHover .dijitArrowButtonInner {
 	background-position:-70px 45%;
 }
+
+// TODO: should have active rule, for clicking a .dijitTimePickerItem
\ No newline at end of file
diff --git a/dijit/themes/claro/TitlePane.css b/dijit/themes/claro/TitlePane.css
index 1415615..87d82a6 100644
--- a/dijit/themes/claro/TitlePane.css
+++ b/dijit/themes/claro/TitlePane.css
@@ -1,4 +1,4 @@
-/* TitlePane 
+/* TitlePane and Fieldset
  * 
  * Styling TitlePane means styling the TitlePane title and its content container  (dijitTitlePane)
  * 
@@ -19,14 +19,26 @@
  */
 .claro .dijitTitlePaneTitle {
   background-color: #efefef;
-  background-image: url("images/titlebar.png");
+  background-image: url("images/standardGradient.png");
   background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   border: 1px solid #b5bcc7;
   padding: 0 7px 3px 7px;
   min-height: 17px;
+  color: #494949;
 }
-.dj_ie6 .claro .dijitTitlePaneTitle {
-  background-image: none;
+.claro .dijitFieldset {
+  -moz-border-radius: 4px;
+  border-radius: 4px;
+}
+.claro .dijitTitlePaneTitleOpen,
+.claro .dijitTitlePaneTitleFixedOpen {
+  background-color: #cfe5fa;
+  color: #000000;
 }
 .claro .dijitTitlePaneTitleHover {
   background-color: #abd6ff;
@@ -35,27 +47,33 @@
 .claro .dijitTitlePaneTitleActive {
   background-color: #7dbdfa;
   border-color: #759dc0;
-  background-position: 0 -136px;
+  background-image: url("images/activeGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
 }
 .claro .dijitTitlePaneTitleFocus {
   margin-top: 3px;
   padding-bottom: 2px;
 }
-.claro .dijitTitlePane .dijitArrowNode {
+.claro .dijitTitlePane .dijitArrowNode,
+.claro .dijitFieldset .dijitArrowNode {
   background-image: url("images/spriteArrows.png");
   background-repeat: no-repeat;
   height: 8px;
   width: 7px;
 }
-.claro .dijitTitlePane .dijitOpen .dijitArrowNode {
+.claro .dijitTitlePaneTitleOpen .dijitArrowNode,
+.claro .dijitFieldsetTitleOpen .dijitArrowNode {
   background-position: 0 0;
 }
-.claro .dijitTitlePane .dijitClosed .dijitArrowNode {
+.claro .dijitTitlePaneTitleClosed .dijitArrowNode,
+.claro .dijitFieldsetTitleClosed .dijitArrowNode {
   background-position: -14px 0;
 }
-.claro .dijitTitlePane .dijitTitlePaneTextNode {
-  color: #000000;
-}
 .claro .dijitTitlePaneContentOuter {
   background: #ffffff;
   border: 1px solid #b5bcc7;
@@ -64,7 +82,11 @@
 .claro .dijitTitlePaneContentInner {
   padding: 10px;
 }
-.claro .dijitTitlePaneTextNode {
+.claro .dijitFieldsetContentInner {
+  padding: 4px;
+}
+.claro .dijitTitlePaneTextNode,
+.claro .dijitFieldsetLegendNode {
   margin-left: 4px;
   margin-right: 4px;
   vertical-align: text-top;
diff --git a/dijit/themes/claro/TitlePane.less b/dijit/themes/claro/TitlePane.less
index 89da9f3..833fccc 100644
--- a/dijit/themes/claro/TitlePane.less
+++ b/dijit/themes/claro/TitlePane.less
@@ -1,4 +1,4 @@
-/* TitlePane 
+/* TitlePane and Fieldset
  * 
  * Styling TitlePane means styling the TitlePane title and its content container  (dijitTitlePane)
  * 
@@ -21,15 +21,19 @@
 @import "variables";
 
 .claro .dijitTitlePaneTitle {
-	background-color: @unselected-background-color;	// TODO: Mailed Jason, shouldn't this toggle to @selected-background-color when pane opened?
-	background-image: url(@image-titlebar);
-	background-repeat:repeat-x;
+	background-color: @unselected-background-color;
+	.standard-gradient;
 	border:1px solid @border-color;
 	padding: 0 7px 3px 7px;
 	min-height:17px;
+	color: @unselected-text-color;
 }
-.dj_ie6 .claro .dijitTitlePaneTitle {
-	background-image: none;
+.claro .dijitFieldset {
+  .border-radius(4px);
+}
+.claro .dijitTitlePaneTitleOpen, .claro .dijitTitlePaneTitleFixedOpen {
+  background-color: @selected-background-color;
+  color: @text-color;
 }
 .claro .dijitTitlePaneTitleHover {
 	background-color: @hovered-background-color;
@@ -38,36 +42,36 @@
 .claro .dijitTitlePaneTitleActive {
 	background-color: @pressed-background-color;
 	border-color: @pressed-border-color;
-	background-position:0 -136px;
+	.active-gradient;
 }
 .claro .dijitTitlePaneTitleFocus {
 	margin-top:3px;
 	padding-bottom:2px;
 }
-.claro .dijitTitlePane .dijitArrowNode {
+.claro .dijitTitlePane .dijitArrowNode, .claro .dijitFieldset .dijitArrowNode {
 	background-image: url(@image-arrow-sprite);
 	background-repeat: no-repeat;
 	height: 8px;
 	width: 7px;
 }
-.claro .dijitTitlePane .dijitOpen .dijitArrowNode {
+.claro .dijitTitlePaneTitleOpen .dijitArrowNode,  .claro .dijitFieldsetTitleOpen .dijitArrowNode,{
 	background-position: 0 0;
 }
-.claro .dijitTitlePane .dijitClosed .dijitArrowNode {
+.claro .dijitTitlePaneTitleClosed .dijitArrowNode, .claro .dijitFieldsetTitleClosed .dijitArrowNode {
 	background-position: -14px 0;
 }
-.claro .dijitTitlePane .dijitTitlePaneTextNode {
-	color:@text-color;
-}
 .claro .dijitTitlePaneContentOuter {
 	background: @pane-background-color;
 	border:1px solid @border-color;
 	border-top:none;
 }
-.claro .dijitTitlePaneContentInner {
+.claro .dijitTitlePaneContentInner{
 	padding:10px;
 }
-.claro .dijitTitlePaneTextNode {
+.claro .dijitFieldsetContentInner {
+  padding: 4px;
+}
+.claro .dijitTitlePaneTextNode, .claro .dijitFieldsetLegendNode {
 	margin-left: 4px;
 	margin-right: 4px;
 	vertical-align:text-top;
diff --git a/dijit/themes/claro/TitlePane_rtl.css b/dijit/themes/claro/TitlePane_rtl.css
index 3f68ab3..12d21bd 100644
--- a/dijit/themes/claro/TitlePane_rtl.css
+++ b/dijit/themes/claro/TitlePane_rtl.css
@@ -1,4 +1,5 @@
 /* TitlePane */
-.claro .dijitTitlePaneRtl .dijitClosed .dijitArrowNode {
+.claro .dijitTitlePaneRtl .dijitClosed .dijitArrowNode,
+.claro .dijitFieldsetRtl .dijitFieldsetTitleClosed .dijitArrowNode {
   background-position: -7px 0;
 }
diff --git a/dijit/themes/claro/TitlePane_rtl.less b/dijit/themes/claro/TitlePane_rtl.less
index 693584f..4481d90 100644
--- a/dijit/themes/claro/TitlePane_rtl.less
+++ b/dijit/themes/claro/TitlePane_rtl.less
@@ -2,6 +2,6 @@
 
 @import "variables";
 
-.claro .dijitTitlePaneRtl .dijitClosed .dijitArrowNode {
+.claro .dijitTitlePaneRtl .dijitClosed .dijitArrowNode, .claro .dijitFieldsetRtl .dijitFieldsetTitleClosed .dijitArrowNode {
 	background-position: -7px 0;
 }
\ No newline at end of file
diff --git a/dijit/themes/claro/Toolbar.css b/dijit/themes/claro/Toolbar.css
index 18c605c..20ae6f2 100644
--- a/dijit/themes/claro/Toolbar.css
+++ b/dijit/themes/claro/Toolbar.css
@@ -20,9 +20,13 @@
 .claro .dijitToolbar {
   border-bottom: 1px solid #b5bcc7;
   background-color: #efefef;
-  background-image: url("images/commonHighlight.png");
-  background-position: 0 0;
+  background-image: url("images/standardGradient.png");
   background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   padding: 2px 0 2px 4px;
   zoom: 1;
 }
@@ -47,13 +51,13 @@
   -webkit-transition-property: background-color;
   -moz-transition-property: background-color;
   transition-property: background-color;
-  -webkit-transition-duration: 0.3s, 0.35s;
-  -moz-transition-duration: 0.3s, 0.35s;
-  transition-duration: 0.3s, 0.35s;
-  background-image: url("images/commonHighlight.png");
-  background-position: 0 -30px;
-  background-repeat: repeat-x;
+  -webkit-transition-duration: 0.3s;
+  -moz-transition-duration: 0.3s;
+  transition-duration: 0.3s;
   background-color: rgba(171, 214, 255, 0);
+  background-image: none;
+  /* cancel gradient for normal buttons, we don't want any gradient besides toolbar's on non-hovered buttons */
+
 }
 .dj_ie .claro .dijitToolbar .dijitButton .dijitButtonNode,
 .dj_ie .claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
@@ -64,15 +68,6 @@
   /* for IE, which doesn't understand rgba(...) */
 
 }
-.dj_ie6 .claro .dijitToolbar .dijitButton .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitComboButton .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitToggleButton .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitComboBox .dijitButtonNode {
-  background: none;
-  /* because background-color: transparent above doesn't work on IE*/
-
-}
 /* hover status */
 .dj_ie .claro .dijitToolbar .dijitButtonHover .dijitButtonNode,
 .dj_ie .claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
@@ -112,23 +107,38 @@
 .claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
 .claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode,
 .claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode {
-  background-position: 0 0;
   border-width: 1px;
   background-color: #abd6ff;
+  background-image: url("images/standardGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   padding: 1px;
 }
-.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode, .claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
-  background-position: 0 0;
+.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode,
+.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
   background-color: #f3ffff;
 }
-.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNodeHover, .claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButtonHover {
+.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNodeHover,
+.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButtonHover {
   background-color: #abd6ff;
 }
 /* active status */
-.claro .dijitToolbar .dijitButtonActive .dijitButtonNode, .claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode, .claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
+.claro .dijitToolbar .dijitButtonActive .dijitButtonNode,
+.claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode,
+.claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
   border-width: 1px;
   background-color: #7dbdfa;
-  background-position: 0 -177px;
+  background-image: url("images/activeGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   padding: 1px;
 }
 .claro .dijitToolbar .dijitComboButtonActive {
@@ -138,19 +148,34 @@
   border-width: 1px;
   padding: 0;
 }
-.claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode, .claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
+.claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode,
+.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
   background-color: #f3ffff;
-  background-position: 0 -177px;
   padding: 2px;
 }
 .claro .dijitToolbar .dijitComboButtonActive .dijitButtonNodeActive {
   background-color: #7dbdfa;
+  background-image: url("images/activeGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
 }
 .claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButtonActive {
   background-color: #7dbdfa;
+  background-image: url("images/activeGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
 }
 /* Avoid double border between button and arrow */
-.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton, .claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
+.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton,
+.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
   border-left-width: 0;
 }
 .claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
@@ -170,9 +195,6 @@
   background-color: #ffffff;
   padding: 1px;
 }
-.dj_ie6 .claro .dijitToolbar {
-  background-image: none;
-}
 .claro .dijitToolbarSeparator {
   /* separator icon in the editor sprite */
 
diff --git a/dijit/themes/claro/Toolbar.less b/dijit/themes/claro/Toolbar.less
index b61e819..90b9009 100644
--- a/dijit/themes/claro/Toolbar.less
+++ b/dijit/themes/claro/Toolbar.less
@@ -23,9 +23,7 @@
 .claro .dijitToolbar {
 	border-bottom: 1px solid @border-color;
 	background-color: @bar-background-color;
-	background-image: url(@image-common-highlight);
-	background-position:0 0;
-	background-repeat:repeat-x;
+	.standard-gradient;
 	padding: 2px 0 2px 4px;
 	zoom: 1;
 }
@@ -45,12 +43,10 @@
 	.border-radius(@toolbar-button-border-radius);
 	.box-shadow(none);
 	.transition-property(background-color);
-	.transition-duration(.3s, .35s);
+	.transition-duration(.3s);
 
-	background-image: url(@image-common-highlight);
-	background-position:0 -30px;
-	background-repeat:repeat-x;
 	background-color:rgba(171,214,255,0);
+	background-image: none;	/* cancel gradient for normal buttons, we don't want any gradient besides toolbar's on non-hovered buttons */
 }
 .dj_ie .claro .dijitToolbar .dijitButton .dijitButtonNode,
 .dj_ie .claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
@@ -59,13 +55,7 @@
 .dj_ie .claro .dijitToolbar .dijitComboBox .dijitButtonNode {
 	background-color: transparent;   /* for IE, which doesn't understand rgba(...) */
 }
-.dj_ie6 .claro .dijitToolbar .dijitButton .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitDropDownButton .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitComboButton .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitToggleButton .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitComboBox .dijitButtonNode {
-	background: none;	/* because background-color: transparent above doesn't work on IE*/
-}
+
 /* hover status */
 .dj_ie .claro .dijitToolbar .dijitButtonHover .dijitButtonNode,
 .dj_ie .claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
@@ -103,14 +93,13 @@
 .claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
 .claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode,
 .claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode {
-	background-position:0 0;
 	border-width:1px;
 	background-color: @hovered-background-color;
+	.standard-gradient;
 	padding: 1px;
 }
 .claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode,
 .claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
-	background-position:0 0;
 	background-color: @toolbar-combobutton-hovered-unhoveredsection-background-color;
 }
 .claro .dijitToolbar .dijitComboButtonHover .dijitButtonNodeHover,
@@ -124,7 +113,7 @@
 .claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
 	border-width: 1px;
 	background-color:@pressed-background-color;
-	background-position:0 -177px;
+	.active-gradient;
 	padding: 1px;
 }
 .claro .dijitToolbar .dijitComboButtonActive {
@@ -135,14 +124,15 @@
 .claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode,
 .claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
 	background-color: @toolbar-combobutton-hovered-unhoveredsection-background-color;
-	background-position:0 -177px;
 	padding: 2px;
 }
 .claro .dijitToolbar .dijitComboButtonActive .dijitButtonNodeActive {
 	background-color: @pressed-background-color;
+	.active-gradient;
 }
 .claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButtonActive {
 	background-color: @pressed-background-color;
+	.active-gradient;
 }
 
 /* Avoid double border between button and arrow */
@@ -165,10 +155,6 @@
 	padding: 1px;
 }
 
-.dj_ie6 .claro .dijitToolbar {
-	background-image: none;
-}
-
 .claro .dijitToolbarSeparator {
 	/* separator icon in the editor sprite */
 	background: url(@image-editor-icons-enabled);
diff --git a/dijit/themes/claro/Toolbar_rtl.css b/dijit/themes/claro/Toolbar_rtl.css
index 2fab1de..c54a34c 100644
--- a/dijit/themes/claro/Toolbar_rtl.css
+++ b/dijit/themes/claro/Toolbar_rtl.css
@@ -4,7 +4,8 @@
   border-width: 0;
   padding: 2px;
 }
-.claro .dijitToolbar .dijitComboButtonRtlHover .dijitButtonNode, .claro .dijitToolbar .dijitComboButtonRtlActive .dijitButtonNode {
+.claro .dijitToolbar .dijitComboButtonRtlHover .dijitButtonNode,
+.claro .dijitToolbar .dijitComboButtonRtlActive .dijitButtonNode {
   border-width: 1px;
   padding: 1px;
 }
@@ -20,7 +21,8 @@
   -moz-border-radius: 2px 0 0 2px;
   border-radius: 2px 0 0 2px;
 }
-.claro .dijitToolbar .dijitComboButtonRtlHover .dijitArrowButton, .claro .dijitToolbar .dijitComboButtonRtlActive .dijitArrowButton {
+.claro .dijitToolbar .dijitComboButtonRtlHover .dijitArrowButton,
+.claro .dijitToolbar .dijitComboButtonRtlActive .dijitArrowButton {
   /* border between button and arrow */
 
   border-left-width: 1px;
diff --git a/dijit/themes/claro/Tree.css b/dijit/themes/claro/Tree.css
index 738bb33..56bb01d 100644
--- a/dijit/themes/claro/Tree.css
+++ b/dijit/themes/claro/Tree.css
@@ -34,20 +34,18 @@
  * Also use this styling when dropping between items on the tree (in other words, don't
  * use hover effect)
  */
-.claro .dijitTreeRow, .claro .dijitTreeNode .dojoDndItemBefore, .claro .dijitTreeNode .dojoDndItemAfter {
+.claro .dijitTreeRow,
+.claro .dijitTreeNode .dojoDndItemBefore,
+.claro .dijitTreeNode .dojoDndItemAfter {
   /* so insert line shows up on IE when dropping after a target element */
 
-  padding: 4px 1px 2px 0;
-  margin: 0 1px;
-  /* replaced by border for selected/hovered row */
-
+  padding: 4px 0 2px 0;
   background-color: none;
   background-color: transparent;
   background-color: rgba(171, 214, 255, 0);
   background-position: 0 0;
   background-repeat: repeat-x;
-  border-color: rgba(118, 157, 192, 0);
-  border-width: 0;
+  border: solid 0 transparent;
   color: #000000;
   -webkit-transition-property: background-color, border-color;
   -moz-transition-property: background-color, border-color;
@@ -60,20 +58,31 @@
   transition-timing-function: ease-out;
 }
 .claro .dijitTreeRowSelected {
-  background-repeat: repeat-x;
   background-color: #cfe5fa;
-  background-image: url("images/commonHighlight.png");
+  background-image: url("images/standardGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   padding: 3px 0 1px;
-  margin: 0;
-  border: solid 1px #759dc0;
+  border-color: #759dc0;
+  border-width: 1px 0;
   color: #000000;
 }
 .claro .dijitTreeRowHover {
   background-color: #abd6ff;
-  background-image: url("images/commonHighlight.png");
+  background-image: url("images/standardGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   padding: 3px 0 1px;
-  margin: 0;
-  border: solid 1px #759dc0;
+  border-color: #759dc0;
+  border-width: 1px 0;
   color: #000000;
   -webkit-transition-duration: 0.25s;
   -moz-transition-duration: 0.25s;
@@ -81,16 +90,18 @@
 }
 .claro .dijitTreeRowActive {
   background-color: #7dbdfa;
-  background-image: url("images/commonHighlight.png");
-  background-position: 0 -177px;
+  background-image: url("images/activeGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   padding: 3px 0 1px;
-  margin-left: 0;
-  border: solid 1px #759dc0;
+  border-color: #759dc0;
+  border-width: 1px 0;
   color: #000000;
 }
-.dj_ie6 .claro .dijitTreeRow {
-  background-image: none;
-}
 .claro .dijitTreeRowFocused {
   background-repeat: repeat;
 }
@@ -115,7 +126,8 @@
 .claro .dijitTreeRowHover .dijitTreeExpandoClosed {
   background-position: -17px 0;
 }
-.claro .dijitTreeExpandoLeaf, .dj_ie6 .claro .dijitTreeExpandoLeaf {
+.claro .dijitTreeExpandoLeaf,
+.dj_ie6 .claro .dijitTreeExpandoLeaf {
   background-image: none;
 }
 .claro .dijitTreeExpandoLoading {
diff --git a/dijit/themes/claro/Tree.less b/dijit/themes/claro/Tree.less
index ff6cd5a..1b02776 100644
--- a/dijit/themes/claro/Tree.less
+++ b/dijit/themes/claro/Tree.less
@@ -40,8 +40,7 @@
 .claro .dijitTreeNode .dojoDndItemBefore,
 .claro .dijitTreeNode .dojoDndItemAfter {
 	/* so insert line shows up on IE when dropping after a target element */
-	padding: 4px 1px 2px 0;
-	margin: 0 1px;	/* replaced by border for selected/hovered row */
+	padding: 4px 0 2px 0;
 
 	background-color: none;	// IE6 doesn't understand rgba() or transparent below
 	background-color: transparent;	// IE8 doesn't understand rgba() below
@@ -49,8 +48,7 @@
 	background-position:0 0;
 	background-repeat:repeat-x;
 
-	border-color: rgba(118,157,192,0);	// rgba() instead of none to prevent flash on hover fade-in
-	border-width: 0;
+	border: solid 0 transparent;
 
 	color: @text-color;
 
@@ -60,34 +58,29 @@
 }
 
 .claro .dijitTreeRowSelected {
-	background-repeat:repeat-x;
-	background-color:@selected-background-color;
-	background-image: url(@image-common-highlight);
+	background-color: @selected-background-color;
+	.standard-gradient;
 	padding: 3px 0 1px;
-	margin: 0;
-	border:solid 1px @selected-border-color;
-	color:@selected-text-color;
+	border-color: @selected-border-color;
+	border-width: 1px 0;
+	color: @selected-text-color;
 }
 .claro .dijitTreeRowHover {
-	background-color:@hovered-background-color;
-	background-image: url(@image-common-highlight);
+	background-color: @hovered-background-color;
+	.standard-gradient;
 	padding: 3px 0 1px;
-	margin: 0;
-	border:solid 1px @hovered-border-color;
-	color:@hovered-text-color;
+	border-color: @hovered-border-color;
+	border-width: 1px 0;
+	color: @hovered-text-color;
 	.transition-duration(.25s);
 }
 .claro .dijitTreeRowActive {
 	background-color:@pressed-background-color;
-	background-image: url(@image-common-highlight);
-	background-position:0 -177px;
+	.active-gradient;
 	padding: 3px 0 1px;
-	margin-left: 0;
-	border:solid 1px @pressed-border-color;
-	color:@selected-text-color;
-}
-.dj_ie6 .claro .dijitTreeRow {
-	background-image: none;
+	border-color: @pressed-border-color;
+	border-width: 1px 0;
+	color: @selected-text-color;
 }
 .claro .dijitTreeRowFocused {
 	background-repeat: repeat;
diff --git a/dijit/themes/claro/claro_rtl.css b/dijit/themes/claro/claro_rtl.css
index 6f85707..fa1a519 100644
--- a/dijit/themes/claro/claro_rtl.css
+++ b/dijit/themes/claro/claro_rtl.css
@@ -4,7 +4,6 @@
 @import url("form/Button_rtl.css");
 @import url("layout/TabContainer_rtl.css");
 @import url("form/Slider_rtl.css");
- at import url("form/Select_rtl.css");
 @import url("Dialog_rtl.css");
 @import url("Editor_rtl.css");
 @import url("../../icons/editorIcons_rtl.css");/* RTL sprite for editor icons to be used by all themes*/
@@ -14,3 +13,5 @@
 @import url("Calendar_rtl.css");
 @import url("TimePicker_rtl.css");
 @import url("Toolbar_rtl.css");
+ at import url("ProgressBar_rtl.css");
+
diff --git a/dijit/themes/claro/compile.js b/dijit/themes/claro/compile.js
index 08e6375..a5765b4 100644
--- a/dijit/themes/claro/compile.js
+++ b/dijit/themes/claro/compile.js
@@ -5,7 +5,7 @@
 
 var fs = require('fs'),		// file system access
 	path = require('path'),	// get directory from file name
-	less = require('../../../util/less');	// less processor
+	less = require('../../../util/less/lib/less');	// less processor
 
 var options = {
 	compress: false,
diff --git a/dijit/themes/claro/document.css b/dijit/themes/claro/document.css
index 64e470c..ffaac44 100644
--- a/dijit/themes/claro/document.css
+++ b/dijit/themes/claro/document.css
@@ -29,13 +29,15 @@
   line-height: 1.3em;
 }
 /* pre and code */
-.claro pre, .claro code {
+.claro pre,
+.claro code {
   font-family: inherit;
   background-color: #efefef;
   border: 1px solid #d3d3d3;
 }
 /* tables */
-.claro table.dojoTabular thead, .claro table.dojoTabular tfoot {
+.claro table.dojoTabular thead,
+.claro table.dojoTabular tfoot {
   background-color: #efefef;
   border: 1px solid #d3d3d3;
 }
diff --git a/dijit/themes/claro/form/Button.css b/dijit/themes/claro/form/Button.css
index bc7c3dc..f7718c1 100644
--- a/dijit/themes/claro/form/Button.css
+++ b/dijit/themes/claro/form/Button.css
@@ -43,16 +43,20 @@
 
   border: 1px solid #759dc0;
   padding: 2px 4px 4px 4px;
-  background-image: url("../form/images/button.png");
-  background-position: center top;
-  background-repeat: repeat-x;
-  background-color: #e5f2fe;
   color: #000000;
   -moz-border-radius: 4px;
   border-radius: 4px;
   -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
   -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
   box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
+  background-color: #bcd8f4;
+  background-image: url("images/buttonEnabled.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0) 3px, rgba(255, 255, 255, 0.75) 100%);
+  background-image: -webkit-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0) 3px, rgba(255, 255, 255, 0.75) 100%);
+  background-image: -o-linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0) 3px, rgba(255, 255, 255, 0.75) 100%);
+  background-image: linear-gradient(#ffffff 0px, rgba(255, 255, 255, 0) 3px, rgba(255, 255, 255, 0.75) 100%);
+  _background-image: none;
 }
 .claro .dijitComboButton .dijitArrowButton {
   border-left-width: 0;
@@ -100,7 +104,7 @@
 .claro .dijitComboButton .dijitButtonNodeHover,
 .claro .dijitComboButton .dijitDownArrowButtonHover,
 .claro .dijitToggleButtonHover .dijitButtonNode {
-  background-color: #abd6ff;
+  background-color: #86bdf2;
   color: #000000;
   -webkit-transition-duration: 0.2s;
   -moz-transition-duration: 0.2s;
@@ -111,11 +115,11 @@
 .claro .dijitDropDownButtonActive .dijitButtonNode,
 .claro .dijitComboButtonActive .dijitButtonNode,
 .claro .dijitToggleButtonActive .dijitButtonNode,
-.claro .dijitStackController .dijitToggleButtonChecked .dijitButtonNode {
-  background-color: #abd6ff;
-  -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
-  -moz-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
-  box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+.claro .dijitToggleButtonChecked .dijitButtonNode {
+  background-color: #86bdf2;
+  -webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
+  box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
   -webkit-transition-duration: 0.1s;
   -moz-transition-duration: 0.1s;
   transition-duration: 0.1s;
@@ -132,13 +136,18 @@
 .claro .dijitDropDownButtonDisabled .dijitButtonNode,
 .claro .dijitComboButtonDisabled .dijitButtonNode,
 .claro .dijitToggleButtonDisabled .dijitButtonNode {
-  background-position: 0 -149px;
   background-color: #efefef;
   border: solid 1px #d3d3d3;
   color: #818181;
   -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
   -moz-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
   box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+  background-image: url("images/buttonDisabled.png");
+  background-image: -moz-linear-gradient(#ffffff 0%, rgba(255, 255, 255, 0) 40%);
+  background-image: -webkit-linear-gradient(#ffffff 0%, rgba(255, 255, 255, 0) 40%);
+  background-image: -o-linear-gradient(#ffffff 0%, rgba(255, 255, 255, 0) 40%);
+  background-image: linear-gradient(#ffffff 0%, rgba(255, 255, 255, 0) 40%);
+  _background-image: none;
 }
 .claro .dijitComboButtonDisabled .dijitArrowButton {
   border-left-width: 0;
@@ -149,9 +158,6 @@
   /* override dijit.css so that ComboBox rounded corners work */
 
 }
-.dj_ie6 .claro .dijitButtonNode {
-  background-image: none;
-}
 .claro .dijitComboButton .dijitStretch {
   -moz-border-radius: 4px 0 0 4px;
   border-radius: 4px 0 0 4px;
diff --git a/dijit/themes/claro/form/Button.less b/dijit/themes/claro/form/Button.less
index 208e4de..5d59532 100644
--- a/dijit/themes/claro/form/Button.less
+++ b/dijit/themes/claro/form/Button.less
@@ -40,16 +40,22 @@
 .claro .dijitToggleButton .dijitButtonNode {
 	/* rules for the dijit.form.*Button widgets (see also ComboButton section below) */
 	border: 1px solid @button-border-color;
-	padding:2px 4px 4px 4px;
-	background-image: url("../@{image-form-button}");
-	background-position: center top;
-	background-repeat: repeat-x;
-	background-color: @button-background-color;
+	padding: 2px 4px 4px 4px;
 	color: @text-color;
 	.border-radius(@button-border-radius);
 	.box-shadow(0 1px 1px rgba(0,0,0,0.15));
+
+	background-color: desaturate(darken(@button-background-color, 10), 20);
+
+	// Alpha transparency layer to add gradient to above background color.
+	// Use CSS gradient with fallback to image for IE.
+	background-image: url("images/buttonEnabled.png");
+	background-repeat: repeat-x;
+	.alpha-white-gradient(1, 0px, 0, 3px, 0.75, 100%);
+	_background-image: none;	// IE6 can't handle background-color and background-image at once.
 }
 
+
 .claro .dijitComboButton .dijitArrowButton {
 	border-left-width: 0;
 	padding: 4px 2px 4px 2px;	/* TODO: still needed? */
@@ -101,7 +107,7 @@
 .claro .dijitComboButton .dijitButtonNodeHover, 
 .claro .dijitComboButton .dijitDownArrowButtonHover,
 .claro .dijitToggleButtonHover .dijitButtonNode {
-	background-color: @button-hovered-background-color;
+	background-color: desaturate(darken(@button-hovered-background-color, 10), 20);
 	color:@text-color;
  	.transition-duration(.2s);
 }
@@ -111,9 +117,9 @@
 .claro .dijitDropDownButtonActive .dijitButtonNode,
 .claro .dijitComboButtonActive .dijitButtonNode,
 .claro .dijitToggleButtonActive .dijitButtonNode,
-.claro .dijitStackController .dijitToggleButtonChecked .dijitButtonNode {
-	background-color: @button-pressed-background-color;
-	.box-shadow(0 0 0 rgba(0,0,0,0));
+.claro .dijitToggleButtonChecked .dijitButtonNode {
+	background-color: desaturate(darken(@button-pressed-background-color, 10), 20);
+	.box-shadow(inset 0px 1px 1px rgba(0, 0, 0, 0.2));
  	.transition-duration(.1s);
 }
 
@@ -129,13 +135,19 @@
 .claro .dijitButtonDisabled .dijitButtonNode,
 .claro .dijitDropDownButtonDisabled .dijitButtonNode,
 .claro .dijitComboButtonDisabled .dijitButtonNode,
-.claro .dijitToggleButtonDisabled .dijitButtonNode { 
-	background-position:0 -149px;
+.claro .dijitToggleButtonDisabled .dijitButtonNode {
 	background-color: @disabled-background-color;
 	border: solid 1px @disabled-border-color;
 	color: @disabled-text-color;
 	.box-shadow(0 0 0 rgba(0,0,0,0));
+
+	// Change the gradient from light to dark.
+	// Again using CSS gradient with fallback to image for IE.
+	background-image: url("images/buttonDisabled.png");
+	.alpha-white-gradient(1, 0%, 0, 40%);
+	_background-image: none;	// IE6 can't handle background-color and background-image at once.
 }
+
 .claro .dijitComboButtonDisabled .dijitArrowButton{ 
 	border-left-width: 0;
 }
@@ -144,10 +156,6 @@
 	border-collapse: separate;	/* override dijit.css so that ComboBox rounded corners work */
 }
 
-.dj_ie6 .claro .dijitButtonNode {
-	background-image: none;
-}
-
 .claro .dijitComboButton .dijitStretch {
 	.border-radius(@button-border-radius 0 0 @button-border-radius);
 }
diff --git a/dijit/themes/claro/form/Checkbox.css b/dijit/themes/claro/form/Checkbox.css
index 1c1a3c4..fb4e726 100644
--- a/dijit/themes/claro/form/Checkbox.css
+++ b/dijit/themes/claro/form/Checkbox.css
@@ -24,7 +24,8 @@
 .dj_ie6 .claro .dijitToggleButton .dijitCheckBoxIcon {
   background-image: url("../images/checkmarkNoBorder.gif");
 }
-.claro .dijitCheckBox, .claro .dijitCheckBoxIcon {
+.claro .dijitCheckBox,
+.claro .dijitCheckBoxIcon {
   background-image: url("../form/images/checkboxRadioButtonStates.png");
   /* checkbox sprite image */
 
@@ -34,17 +35,20 @@
   margin: 0 2px 0 0;
   padding: 0;
 }
-.dj_ie6 .claro .dijitCheckBox, .dj_ie6 .claro .dijitCheckBoxIcon {
+.dj_ie6 .claro .dijitCheckBox,
+.dj_ie6 .claro .dijitCheckBoxIcon {
   background-image: url("../form/images/checkboxAndRadioButtons_IE6.png");
   /* checkbox sprite image */
 
 }
-.claro .dijitCheckBox, .claro .dijitToggleButton .dijitCheckBoxIcon {
+.claro .dijitCheckBox,
+.claro .dijitToggleButton .dijitCheckBoxIcon {
   /* unchecked */
 
   background-position: -15px;
 }
-.claro .dijitCheckBoxChecked, .claro .dijitToggleButtonChecked .dijitCheckBoxIcon {
+.claro .dijitCheckBoxChecked,
+.claro .dijitToggleButtonChecked .dijitCheckBoxIcon {
   /* checked */
 
   background-position: 0;
diff --git a/dijit/themes/claro/form/Common.css b/dijit/themes/claro/form/Common.css
index ce108c1..a5306b0 100644
--- a/dijit/themes/claro/form/Common.css
+++ b/dijit/themes/claro/form/Common.css
@@ -1,20 +1,23 @@
 /* claro/form/Common.css */
 /*========================= common css =========================*/
 /* 'dijitTextBox' refers to 'dijit(TextBox|DateTextBox|CurrencyTextBox|...)' */
-.claro .dijitTextBox, .claro .dijitInputInner {
+.claro .dijitTextBox,
+.claro .dijitInputInner {
   color: #000000;
 }
-.claro .dijitTextBoxError .dijitValidationContainer {
+.claro .dijitValidationTextBoxError .dijitValidationContainer {
   background-color: #d46464;
   background-image: url("../form/images/error.png");
   background-position: top center;
   border: solid #d46464 0;
-  border-left-width: 1px;
   width: 9px;
 }
-.claro .dijitTextBoxError .dijitValidationIcon {
+.claro .dijitTextBoxError .dijitValidationContainer {
+  border-left-width: 1px;
+}
+.claro .dijitValidationTextBoxError .dijitValidationIcon {
   width: 0;
-  background-color: transparent !important;
+  background-color: transparent;
   /* so the INPUT doesn't obscure the border in rtl+a11y */
 
 }
@@ -23,16 +26,22 @@
  * dijitPlaceHolder is absolutely positioned, so padding set on dijitInputField
  * won't affect it
  */
-.claro .dijitTextArea, .claro .dijitInputField .dijitPlaceHolder {
+.claro .dijitTextArea,
+.claro .dijitInputField .dijitPlaceHolder {
   padding: 2px;
 }
+.claro .dijitSelect .dijitInputField,
 .claro .dijitTextBox .dijitInputField {
   padding: 1px 2px;
 }
-.dj_gecko .claro .dijitTextBox .dijitInputInner, .dj_webkit .claro .dijitTextBox .dijitInputInner {
+.dj_gecko .claro .dijitTextBox .dijitInputInner,
+.dj_webkit .claro .dijitTextBox .dijitInputInner {
   padding: 1px;
 }
-.claro .dijitTextBox, .claro .dijitTextBox .dijitButtonNode {
+.claro .dijitSelect,
+.claro .dijitSelect .dijitButtonContents,
+.claro .dijitTextBox,
+.claro .dijitTextBox .dijitButtonNode {
   /* color for (outer) border on *TextBox widgets, and border between input and buttons on ComboBox and Spinner */
 
   border-color: #b5bcc7;
@@ -43,11 +52,15 @@
   -moz-transition-duration: 0.35s;
   transition-duration: 0.35s;
 }
+.claro .dijitSelect,
 .claro .dijitTextBox {
   background-color: #ffffff;
 }
 /* hover */
-.claro .dijitTextBoxHover, .claro .dijitTextBoxHover .dijitButtonNode {
+.claro .dijitSelectHover,
+.claro .dijitSelectHover .dijitButtonContents,
+.claro .dijitTextBoxHover,
+.claro .dijitTextBoxHover .dijitButtonNode {
   border-color: #759dc0;
   -webkit-transition-duration: 0.25s;
   -moz-transition-duration: 0.25s;
@@ -55,18 +68,23 @@
 }
 .claro .dijitTextBoxHover {
   background-color: #e5f2fe;
-  background-image: url("../form/images/textBox_back.png");
-  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: -o-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
 }
 /* error state */
-.claro .dijitTextBoxError, .claro .dijitTextBoxError .dijitButtonNode {
+.claro .dijitSelectError,
+.claro .dijitSelectError .dijitButtonContents,
+.claro .dijitTextBoxError,
+.claro .dijitTextBoxError .dijitButtonNode {
   border-color: #d46464;
 }
-.claro .dijitTextBoxError, .claro .dijitTextBoxError .dijitInputContainer {
-  background-color: #ffffff;
-}
 /* focused state */
-.claro .dijitTextBoxFocused, .claro .dijitTextBoxFocused .dijitButtonNode {
+.claro .dijitSelectFocused,
+.claro .dijitSelectFocused .dijitButtonContents,
+.claro .dijitTextBoxFocused,
+.claro .dijitTextBoxFocused .dijitButtonNode {
   border-color: #759dc0;
   -webkit-transition-duration: 0.1s;
   -moz-transition-duration: 0.1s;
@@ -74,27 +92,39 @@
 }
 .claro .dijitTextBoxFocused {
   background-color: #ffffff;
-  background-image: url("../form/images/textBox_back.png");
-  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: -o-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
 }
 .claro .dijitTextBoxFocused .dijitInputContainer {
   background: #ffffff;
 }
-.claro .dijitTextBoxErrorFocused, .claro .dijitTextBoxErrorFocused .dijitButtonNode {
+.claro .dijitSelectErrorFocused,
+.claro .dijitSelectErrorFocused .dijitButtonContents,
+.claro .dijitTextBoxErrorFocused,
+.claro .dijitTextBoxErrorFocused .dijitButtonNode {
   border-color: #ce5050;
 }
 /* disabled state */
-.claro .dijitTextBoxDisabled, .claro .dijitTextBoxDisabled .dijitButtonNode {
+.claro .dijitSelectDisabled,
+.claro .dijitSelectDisabled .dijitButtonContents,
+.claro .dijitTextBoxDisabled,
+.claro .dijitTextBoxDisabled .dijitButtonNode {
   border-color: #d3d3d3;
 }
-.claro .dijitTextBoxDisabled, .claro .dijitTextBoxDisabled .dijitInputContainer {
+.claro .dijitSelectDisabled,
+.claro .dijitTextBoxDisabled,
+.claro .dijitTextBoxDisabled .dijitInputContainer {
   background-color: #efefef;
   background-image: none;
 }
-.claro .dijitTextBoxDisabled, .claro .dijitTextBoxDisabled .dijitInputInner {
+.claro .dijitSelectDisabled,
+.claro .dijitTextBoxDisabled,
+.claro .dijitTextBoxDisabled .dijitInputInner {
   color: #818181;
 }
-.dj_webkit .claro .dijitTextBoxDisabled input {
+.dj_webkit .claro .dijitDisabled input {
   /* because WebKit lightens disabled input/textarea no matter what color you specify */
 
   color: #757575;
@@ -106,12 +136,15 @@
 }
 /*========================= for special widgets =========================*/
 /* Input boxes with an arrow (for a drop down) */
+.claro .dijitSelect .dijitArrowButtonInner,
 .claro .dijitComboBox .dijitArrowButtonInner {
   background-image: url("../form/images/commonFormArrows.png");
   background-position: -35px 53%;
   background-repeat: no-repeat;
   margin: 0;
   width: 16px;
+}
+.claro .dijitComboBox .dijitArrowButtonInner {
   border: 1px solid #ffffff;
 }
 .claro .dijitToolbar .dijitComboBox .dijitArrowButtonInner {
@@ -122,31 +155,50 @@
 }
 /* Add 1px vertical padding to the <input> where user types and the validation icon,
    to match the 1px border on arrow button */
-.claro .dijitTextBox .dijitInputInner, .claro .dijitTextBox .dijitValidationContainer {
+.claro .dijitSelectLabel,
+.claro .dijitTextBox .dijitInputInner,
+.claro .dijitValidationTextBox .dijitValidationContainer {
   padding: 1px 0;
 }
 .claro .dijitComboBox .dijitButtonNode {
   background-color: #efefef;
-  background-image: url("../form/images/formHighlight.png");
+  background-image: url("../images/standardGradient.png");
   background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
 }
 /* Arrow "hover" effect:
  * The arrow button should change color whenever the mouse is in a position such that clicking it
  * will toggle the drop down.   That's either (1) anywhere over the ComboBox or (2) over the arrow
  * button, depending on the openOnClick setting for the widget.
  */
-.claro .dijitComboBoxOpenOnClickHover .dijitButtonNode, .claro .dijitComboBox .dijitDownArrowButtonHover {
+.claro .dijitComboBoxOpenOnClickHover .dijitButtonNode,
+.claro .dijitComboBox .dijitDownArrowButtonHover,
+.claro .dijitComboBoxFocused .dijitArrowButton {
   background-color: #abd6ff;
 }
-.claro .dijitComboBoxOpenOnClickHover .dijitArrowButtonInner, .claro .dijitComboBox .dijitDownArrowButtonHover .dijitArrowButtonInner {
+.claro .dijitComboBoxOpenOnClickHover .dijitArrowButtonInner,
+.claro .dijitComboBox .dijitDownArrowButtonHover .dijitArrowButtonInner {
   background-position: -70px 53%;
 }
 /* Arrow Button change when drop down is open */
 .claro .dijitComboBox .dijitHasDropDownOpen {
   background-color: #7dbdfa;
-  background-position: 0 -177px;
+  background-image: url("../images/activeGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   padding: 1px;
 }
+.dj_iequirks .claro .dijitComboBox .dijitHasDropDownOpen {
+  padding: 1px 0;
+}
 .claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
   background-position: -70px 53%;
   border: 0 none;
@@ -166,10 +218,6 @@
   height: 0;
   width: 0;
 }
-/* ie6 doesn't support transparent background img */
-.dj_ie6 .claro .dijitTextBox, .dj_ie6 .claro .dijitComboBox .dijitButtonNode {
-  background-image: none;
-}
 .dj_borderbox .claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
   width: 18px;
 }
diff --git a/dijit/themes/claro/form/Common.less b/dijit/themes/claro/form/Common.less
index 742a43f..6bd55a0 100644
--- a/dijit/themes/claro/form/Common.less
+++ b/dijit/themes/claro/form/Common.less
@@ -13,17 +13,21 @@
 	color: @text-color;
 }
 
-.claro .dijitTextBoxError .dijitValidationContainer {
+.claro .dijitValidationTextBoxError .dijitValidationContainer {
 	background-color: @erroricon-background-color;
 	background-image: url("../@{image-form-error}");
 	background-position: top center;
 	border: solid @erroricon-background-color 0;
-	border-left-width: 1px;
 	width: 9px;
 }
-.claro .dijitTextBoxError .dijitValidationIcon {
+
+.claro .dijitTextBoxError .dijitValidationContainer {
+	border-left-width: 1px;
+}
+
+.claro .dijitValidationTextBoxError .dijitValidationIcon {
 	width: 0;
-	background-color: transparent !important; /* so the INPUT doesn't obscure the border in rtl+a11y */
+	background-color: transparent; /* so the INPUT doesn't obscure the border in rtl+a11y */
 }
 
 /* Padding for the input area of TextBox based widgets, and corresponding padding for the
@@ -35,12 +39,15 @@
 .claro .dijitInputField .dijitPlaceHolder {
 	padding: @textbox-padding;
 }
+
+.claro .dijitSelect .dijitInputField,
 .claro .dijitTextBox .dijitInputField {
 	// Subtract 1px from top/bottom because we add 1px to other nodes, see rules below.
 	// Although we are theoretically only adding 1px to top/bottom browsers seem to pad inputs by 1px on left/right,
 	// although that varies by so compensate for that too.
 	padding: @textbox-padding - 1px  @textbox-padding;
 }
+
 .dj_gecko .claro .dijitTextBox .dijitInputInner,
 .dj_webkit .claro .dijitTextBox .dijitInputInner {
 	// Although we are theoretically only adding 1px to top/bottom, some browsers seem to pad inputs by 1px on left/right,
@@ -48,6 +55,8 @@
 	padding: @textbox-padding - 1px;
 }
 
+.claro .dijitSelect,
+.claro .dijitSelect .dijitButtonContents,
 .claro .dijitTextBox,
 .claro .dijitTextBox .dijitButtonNode {
 	/* color for (outer) border on *TextBox widgets, and border between input and buttons on ComboBox and Spinner */
@@ -55,70 +64,84 @@
 	.transition-property(background-color, border);
  	.transition-duration(.35s);
 }
+
+.claro .dijitSelect,
 .claro .dijitTextBox {
 	background-color: @textbox-background-color;
 }
 
 /* hover */
+.claro .dijitSelectHover,
+.claro .dijitSelectHover .dijitButtonContents,
 .claro .dijitTextBoxHover,
 .claro .dijitTextBoxHover .dijitButtonNode {
 	border-color: @hovered-border-color;
  	.transition-duration(.25s);
 }
+
 .claro .dijitTextBoxHover {
 	background-color: @textbox-hovered-background-color;
-	background-image: url("../@{image-form-textbox-background}");
-	background-repeat: repeat-x;
+	.textbox-background-image;
 }
 
 /* error state */
+.claro .dijitSelectError,
+.claro .dijitSelectError .dijitButtonContents,
 .claro .dijitTextBoxError,
 .claro .dijitTextBoxError .dijitButtonNode {
 	border-color: @error-border-color;
 }
-.claro .dijitTextBoxError,
-.claro .dijitTextBoxError .dijitInputContainer {
-	background-color: @textbox-error-background-color;
-}
 
 /* focused state */
+.claro .dijitSelectFocused,
+.claro .dijitSelectFocused .dijitButtonContents,
 .claro .dijitTextBoxFocused,
 .claro .dijitTextBoxFocused .dijitButtonNode {
 	border-color:@focused-border-color;
  	.transition-duration(.1s);
 }
+
 .claro .dijitTextBoxFocused {
 	background-color: @textbox-focused-background-color;
-	background-image: url("../@{image-form-textbox-background}");
-	background-repeat: repeat-x;
+	.textbox-background-image;
 }
 .claro .dijitTextBoxFocused .dijitInputContainer {
 	background: @textbox-focused-background-color;
 }
 
+.claro .dijitSelectErrorFocused,
+.claro .dijitSelectErrorFocused .dijitButtonContents,
 .claro .dijitTextBoxErrorFocused,
 .claro .dijitTextBoxErrorFocused .dijitButtonNode {
 	border-color: @error-focused-border-color;
 }
 
 /* disabled state */
+.claro .dijitSelectDisabled,
+.claro .dijitSelectDisabled .dijitButtonContents,
 .claro .dijitTextBoxDisabled,
 .claro .dijitTextBoxDisabled .dijitButtonNode {
 	border-color: @disabled-border-color;
 }
+
+.claro .dijitSelectDisabled,
 .claro .dijitTextBoxDisabled,
 .claro .dijitTextBoxDisabled .dijitInputContainer {
 	background-color: @textbox-disabled-background-color;
 	background-image: none;
 }
+
+.claro .dijitSelectDisabled,
 .claro .dijitTextBoxDisabled,
 .claro .dijitTextBoxDisabled .dijitInputInner {
 	color: @disabled-text-color;
 }
-.dj_webkit .claro .dijitTextBoxDisabled input {
+
+.dj_webkit .claro .dijitDisabled input {
     /* because WebKit lightens disabled input/textarea no matter what color you specify */
 	color: darken(@disabled-text-color, 5%)
 }
+
 .dj_webkit .claro textarea.dijitTextAreaDisabled {
     /* because WebKit lightens disabled input/textarea no matter what color you specify */
 	color: darken(@disabled-text-color, 40%)
@@ -128,12 +151,16 @@
 
 /* Input boxes with an arrow (for a drop down) */
 
+.claro .dijitSelect .dijitArrowButtonInner,
 .claro .dijitComboBox .dijitArrowButtonInner {
 	background-image: url("../@{image-form-common-arrows}");
 	background-position:-35px 53%;
 	background-repeat: no-repeat;
 	margin: 0;
 	width:16px;
+}
+
+.claro .dijitComboBox .dijitArrowButtonInner {
 	border: 1px solid @arrowbutton-inner-border-color;	// white gutter around the arrow button
 }
 
@@ -147,15 +174,15 @@
 
 /* Add 1px vertical padding to the <input> where user types and the validation icon,
    to match the 1px border on arrow button */
+.claro .dijitSelectLabel,
 .claro .dijitTextBox .dijitInputInner,
-.claro .dijitTextBox .dijitValidationContainer {
+.claro .dijitValidationTextBox .dijitValidationContainer {
 	padding: 1px 0;
 }
 
 .claro .dijitComboBox .dijitButtonNode {
 	background-color: @arrowbutton-background-color;
-	background-image: url("../@{image-form-highlight}");
-	background-repeat:repeat-x;
+	.standard-gradient("../");
 }
 
 /* Arrow "hover" effect:
@@ -164,9 +191,11 @@
  * button, depending on the openOnClick setting for the widget.
  */
 .claro .dijitComboBoxOpenOnClickHover .dijitButtonNode,
-.claro .dijitComboBox .dijitDownArrowButtonHover {
+.claro .dijitComboBox .dijitDownArrowButtonHover,
+.claro .dijitComboBoxFocused .dijitArrowButton {
 	background-color:@arrowbutton-hovered-background-color;
 }
+
 .claro .dijitComboBoxOpenOnClickHover .dijitArrowButtonInner,
 .claro .dijitComboBox .dijitDownArrowButtonHover .dijitArrowButtonInner {
 	background-position:-70px 53%;
@@ -175,9 +204,14 @@
 /* Arrow Button change when drop down is open */
 .claro .dijitComboBox .dijitHasDropDownOpen {	// .dijitHasDropDown is on dijitArrowButton node
 	background-color: @pressed-background-color;
-	background-position:0 -177px;
+	.active-gradient("../");
 	padding: 1px;		// Since no border on arrow button (see rule below)
 }	
+
+.dj_iequirks .claro .dijitComboBox .dijitHasDropDownOpen {
+	padding: 1px 0;
+}
+
 .claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
 	background-position:-70px 53%;
 	border: 0 none;
@@ -199,14 +233,10 @@
 	width: 0;
 }
 
-/* ie6 doesn't support transparent background img */
-.dj_ie6 .claro .dijitTextBox,
-.dj_ie6 .claro .dijitComboBox .dijitButtonNode {
-	background-image: none;
-}
 .dj_borderbox .claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
 	width:18px;				// quirks mode means border-box sizing, so 18px with the border (same as 16px without border)
 }
+
 .dj_borderbox .claro .dijitComboBoxFocused .dijitHasDropDownOpen .dijitArrowButtonInner {
 	width:16px;				// when no border, then back to 16px just like content-box sizing
 }
diff --git a/dijit/themes/claro/form/Common_rtl.css b/dijit/themes/claro/form/Common_rtl.css
index 74827c1..62e7be5 100644
--- a/dijit/themes/claro/form/Common_rtl.css
+++ b/dijit/themes/claro/form/Common_rtl.css
@@ -1,9 +1,4 @@
 /* claro/form/Common_rtl.css */
-/*claro should not have the icon on the container
-.claro .dijitTextBoxRtlError .dijitValidationIcon {
-	border-left-width: 0;
-	border-right-width: 1px;
-}*/
 .claro .dijitTextBoxRtlError .dijitValidationContainer {
   border-left-width: 0;
   border-right-width: 1px;
diff --git a/dijit/themes/claro/form/Common_rtl.less b/dijit/themes/claro/form/Common_rtl.less
index fd4975a..342ad46 100644
--- a/dijit/themes/claro/form/Common_rtl.less
+++ b/dijit/themes/claro/form/Common_rtl.less
@@ -2,11 +2,6 @@
 
 @import "../variables";
 
-/*claro should not have the icon on the container
-.claro .dijitTextBoxRtlError .dijitValidationIcon {
-	border-left-width: 0;
-	border-right-width: 1px;
-}*/
 .claro .dijitTextBoxRtlError .dijitValidationContainer {
 	border-left-width: 0;
 	border-right-width: 1px;
diff --git a/dijit/themes/claro/form/NumberSpinner.css b/dijit/themes/claro/form/NumberSpinner.css
index fcc8049..94a3e50 100644
--- a/dijit/themes/claro/form/NumberSpinner.css
+++ b/dijit/themes/claro/form/NumberSpinner.css
@@ -35,9 +35,13 @@
 .claro .dijitSpinner .dijitArrowButton {
   width: auto;
   background-color: #efefef;
-  background-image: url("../form/images/formHighlight.png");
-  background-position: 0 0;
+  background-image: url("../images/standardGradient.png");
   background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   overflow: hidden;
 }
 .dj_iequirks .claro .dijitSpinner .dijitArrowButton {
@@ -70,7 +74,10 @@
   /* compensate for inner border */
 
 }
-.dj_ie6 .claro .dijitSpinner .dijitArrowButtonInner, .dj_ie7 .claro .dijitSpinner .dijitArrowButtonInner {
+.dj_iequirks .claro .dijitSpinner .dijitArrowButtonInner,
+.dj_ie6 .claro .dijitSpinner .dijitArrowButtonInner,
+.dj_ie7 .claro .dijitSpinner .dijitArrowButtonInner,
+.dj_ie8 .claro .dijitSpinner .dijitArrowButtonInner {
   margin-top: 0;
   /* since its bottom aligned */
 
@@ -85,10 +92,13 @@
   padding: 0;
 }
 /** hover & focused status **/
-.claro .dijitUpArrowButtonActive, .claro .dijitDownArrowButtonActive {
+.claro .dijitUpArrowButtonActive,
+.claro .dijitDownArrowButtonActive {
   background-color: #abd6ff;
 }
-.claro .dijitSpinner .dijitUpArrowButtonHover, .claro .dijitSpinner .dijitDownArrowButtonHover, .claro .dijitSpinnerFocused .dijitArrowButton {
+.claro .dijitSpinner .dijitUpArrowButtonHover,
+.claro .dijitSpinner .dijitDownArrowButtonHover,
+.claro .dijitSpinnerFocused .dijitArrowButton {
   background-color: #abd6ff;
 }
 .claro .dijitSpinner .dijitUpArrowButtonHover .dijitArrowButtonInner {
@@ -102,11 +112,19 @@
   background-image: none;
 }
 /* mouse down status */
-.claro .dijitSpinner .dijitDownArrowButtonActive, .claro .dijitSpinner .dijitUpArrowButtonActive {
+.claro .dijitSpinner .dijitDownArrowButtonActive,
+.claro .dijitSpinner .dijitUpArrowButtonActive {
   background-color: #7dbefa;
-  background-position: 0 -177px;
+  background-image: url("../images/activeGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
 }
-.claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner, .claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
+.claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner,
+.claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
   /* hide inner border while button is depressed */
 
   border: 0;
diff --git a/dijit/themes/claro/form/NumberSpinner.less b/dijit/themes/claro/form/NumberSpinner.less
index 1c79d3a..e15c782 100644
--- a/dijit/themes/claro/form/NumberSpinner.less
+++ b/dijit/themes/claro/form/NumberSpinner.less
@@ -37,9 +37,7 @@
 .claro .dijitSpinner .dijitArrowButton {
 	width:auto;
 	background-color: @arrowbutton-background-color;
-	background-image: url("../@{image-form-highlight}");
-	background-position:0 0;
-	background-repeat:repeat-x;
+	.standard-gradient("../");
 	overflow: hidden;
 }
 .dj_iequirks .claro .dijitSpinner .dijitArrowButton {
@@ -68,8 +66,10 @@
 	margin: -1px 0 -1px 0;	/* compensate for inner border */
 }
 
+.dj_iequirks .claro .dijitSpinner .dijitArrowButtonInner,
 .dj_ie6 .claro .dijitSpinner .dijitArrowButtonInner,
-.dj_ie7 .claro .dijitSpinner .dijitArrowButtonInner {
+.dj_ie7 .claro .dijitSpinner .dijitArrowButtonInner,
+.dj_ie8 .claro .dijitSpinner .dijitArrowButtonInner {
 	margin-top: 0; /* since its bottom aligned */
 }
 
@@ -112,7 +112,7 @@
 .claro .dijitSpinner .dijitDownArrowButtonActive,
 .claro .dijitSpinner .dijitUpArrowButtonActive {
 	background-color: #7dbefa;		// TODO.  Mailed Jason about inconsistent ComboBox/Spinner behavior.
-	background-position:0 -177px;
+	.active-gradient("../");
 }
 .claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner,
 .claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
diff --git a/dijit/themes/claro/form/RadioButton.css b/dijit/themes/claro/form/RadioButton.css
index bad1854..063e1db 100644
--- a/dijit/themes/claro/form/RadioButton.css
+++ b/dijit/themes/claro/form/RadioButton.css
@@ -18,13 +18,16 @@
  * 5. Disabled state
  * 		.dijitRadioDisabled|.dijitRadioCheckedDisabled - for background image
  */
-.claro .dijitToggleButton .dijitRadio, .claro .dijitToggleButton .dijitRadioIcon {
+.claro .dijitToggleButton .dijitRadio,
+.claro .dijitToggleButton .dijitRadioIcon {
   background-image: url("../form/images/checkboxRadioButtonStates.png");
 }
-.dj_ie6 .claro .dijitToggleButton .dijitRadio, .dj_ie6 .claro .dijitToggleButton .dijitRadioIcon {
+.dj_ie6 .claro .dijitToggleButton .dijitRadio,
+.dj_ie6 .claro .dijitToggleButton .dijitRadioIcon {
   background-image: url("../form/images/checkboxAndRadioButtons_IE6.png");
 }
-.claro .dijitRadio, .claro .dijitRadioIcon {
+.claro .dijitRadio,
+.claro .dijitRadioIcon {
   /* inside a toggle button */
 
   background-image: url("../form/images/checkboxRadioButtonStates.png");
@@ -36,7 +39,8 @@
   margin: 0 2px 0 0;
   padding: 0;
 }
-.dj_ie6 .claro .dijitRadio, .dj_ie6 .claro .dijitRadioIcon {
+.dj_ie6 .claro .dijitRadio,
+.dj_ie6 .claro .dijitRadioIcon {
   /* inside a toggle button */
 
   background-image: url("../form/images/checkboxAndRadioButtons_IE6.png");
diff --git a/dijit/themes/claro/form/Select.css b/dijit/themes/claro/form/Select.css
index bfbca4e..3ed970f 100644
--- a/dijit/themes/claro/form/Select.css
+++ b/dijit/themes/claro/form/Select.css
@@ -16,85 +16,70 @@
  * 4. Various states
  * 		.dijitSelectHover|.dijitSelectFocused|.dijitSelectDisabled .* - for border, padding and background-color|image 
  */
-.claro .dijitSelect .dijitButtonText {
-  padding: 2px;
-}
 /* normal status */
-.claro .dijitSelect {
-  border: 1px solid #b5bcc7;
-  background-color: #ffffff;
-  border-collapse: separate;
-}
-.dj_ie6 .claro .dijitSelect, .dj_ie6 .claro .dijitSelect .dijitButtonNode {
-  background-image: none;
-}
-.claro .dijitSelect .dijitButtonContents {
-  border: 0 solid #b5bcc7;
-  border-right-width: 1px;
+.claro .dijitSelect .dijitArrowButtonContainer {
+  border: 1px solid #ffffff;
 }
 .claro .dijitSelect .dijitArrowButton {
   padding: 0;
-  border: 1px solid #ffffff;
-  border-top: none;
   background-color: #efefef;
-  background-image: url("../form/images/formHighlight.png");
+  background-image: url("../images/standardGradient.png");
   background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
 }
 .claro .dijitSelect .dijitArrowButton .dijitArrowButtonInner {
-  background-image: url("../form/images/commonFormArrows.png");
-  background-position: -35px 70%;
-  background-repeat: no-repeat;
-  width: 16px;
   height: 16px;
 }
 /* hover status */
 .claro .dijitSelectHover {
-  border: 1px solid #759dc0;
   background-color: #e5f2fe;
-  background-image: url("../form/images/textBox_back.png");
+  background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: -o-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+  background-image: linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
   background-repeat: repeat-x;
 }
-.claro .dijitSelectHover .dijitButtonContents {
-  border-color: #759dc0;
-}
 .claro .dijitSelectHover .dijitArrowButton {
   background-color: #abd6ff;
 }
 .claro .dijitSelectHover .dijitArrowButton .dijitArrowButtonInner {
-  background-position: -70px 70%;
+  background-position: -70px 53%;
 }
 /* focused status */
-.claro .dijitSelectFocused {
-  border: 1px solid #759dc0;
-}
-.claro .dijitSelectFocused .dijitButtonContents {
-  border-color: #759dc0;
-}
 .claro .dijitSelectFocused .dijitArrowButton {
   background-color: #7dbefa;
-  background-position: 0 -177px;
+  background-image: url("../images/activeGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
+}
+.claro .dijitSelectFocused .dijitArrowButton {
   border: none;
-  padding: 0 1px;
+  padding: 1px;
 }
 .claro .dijitSelectFocused .dijitArrowButton .dijitArrowButtonInner {
-  background-position: -70px 70%;
-  margin-bottom: 1px;
+  background-position: -70px 53%;
 }
 /* disable status */
 .claro .dijitSelectDisabled {
-  border: 1px solid #d3d3d3;
+  border-color: #d3d3d3;
   background-color: #efefef;
   background-image: none;
   color: #818181;
 }
-.claro .dijitSelectDisabled .dijitArrowButton {
-  background-color: #efefef;
-}
 .claro .dijitSelectDisabled .dijitArrowButton .dijitArrowButtonInner {
-  background-position: 0 70%;
+  background-position: 0 53%;
 }
 /* Dropdown menu style for select */
-.claro .dijitSelectMenu td.dijitMenuItemIconCell, .claro .dijitSelectMenu td.dijitMenuArrowCell {
+.claro .dijitSelectMenu td.dijitMenuItemIconCell,
+.claro .dijitSelectMenu td.dijitMenuArrowCell {
   /* so that arrow and icon cells from MenuItem are not displayed */
 
   display: none;
diff --git a/dijit/themes/claro/form/Select.less b/dijit/themes/claro/form/Select.less
index 0e74261..72e1534 100644
--- a/dijit/themes/claro/form/Select.less
+++ b/dijit/themes/claro/form/Select.less
@@ -19,101 +19,70 @@
 
 @import "../variables";
 
-.claro .dijitSelect .dijitButtonText {
-	padding: @textbox-padding;
-}
-
 /* normal status */
-.claro .dijitSelect {
-	border: 1px solid @border-color;
-	background-color: @textbox-background-color;
-	border-collapse: separate;
-}
-.dj_ie6 .claro .dijitSelect,
-.dj_ie6 .claro .dijitSelect .dijitButtonNode {
-	background-image:none;
-}
-
-.claro .dijitSelect .dijitButtonContents {
-	border: 0 solid @border-color;
-	border-right-width: 1px;
+.claro .dijitSelect .dijitArrowButtonContainer {
+	border: 1px solid @arrowbutton-inner-border-color;
 }
 
 .claro .dijitSelect .dijitArrowButton {
 	padding: 0;
-	border: 1px solid @arrowbutton-inner-border-color;
-	border-top:none;
 	background-color: @arrowbutton-background-color;
-	background-image: url("../@{image-form-highlight}");
-	background-repeat:repeat-x;
+	.standard-gradient("../");
 }
 
 .claro .dijitSelect .dijitArrowButton .dijitArrowButtonInner {
-	background-image: url("../@{image-form-common-arrows}");
-	background-position:-35px 70%;
-	background-repeat: no-repeat;
-	width:16px;
 	height:16px;
 }
 
 /* hover status */
 .claro .dijitSelectHover {
-	border: 1px solid @hovered-border-color;
 	background-color: @textbox-hovered-background-color;
-	background-image: url("../@{image-form-textbox-background}");
+	.textbox-background-image;
 	background-repeat: repeat-x;
 }
 
-.claro .dijitSelectHover .dijitButtonContents {
-	border-color:@hovered-border-color;
-}
-
 .claro .dijitSelectHover .dijitArrowButton {
 	background-color:@arrowbutton-hovered-background-color;
 }
+
 .claro .dijitSelectHover .dijitArrowButton .dijitArrowButtonInner {
-	background-position:-70px 70%;
+	background-position:-70px 53%;
 }
 
 /* focused status */
-.claro .dijitSelectFocused {
-	border: 1px solid @focused-border-color;
-}
-.claro .dijitSelectFocused .dijitButtonContents {
-	border-color:@focused-border-color;
-}
 .claro .dijitSelectFocused .dijitArrowButton {
 	background-color:#7dbefa;		// TODO.  Mailed Jason about inconsistent ComboBox/Spinner behavior.
-	background-position:0 -177px;
+	.active-gradient("../");
+}
+
+.claro .dijitSelectFocused .dijitArrowButton {
 	border: none;
-	padding: 0 1px;
+	padding: 1px;
 }
+
 .claro .dijitSelectFocused .dijitArrowButton .dijitArrowButtonInner {
-	background-position:-70px 70%;
-	margin-bottom: 1px;
+	background-position:-70px 53%;
 }
 
 /* disable status */
 .claro .dijitSelectDisabled {
-	border: 1px solid @disabled-border-color;
+	border-color: @disabled-border-color;
 	background-color: @disabled-background-color;
 	background-image: none;
 	color: @disabled-text-color;
 }
-.claro .dijitSelectDisabled .dijitArrowButton { 
-	background-color: @disabled-background-color;
-}
+
 .claro .dijitSelectDisabled .dijitArrowButton .dijitArrowButtonInner {
-	background-position:0 70%
+	background-position:0 53%
 }
 
 /* Dropdown menu style for select */
-
 .claro .dijitSelectMenu td.dijitMenuItemIconCell,
 .claro .dijitSelectMenu td.dijitMenuArrowCell { 
 	/* so that arrow and icon cells from MenuItem are not displayed */
 	display: none;  
 }
+
 .claro .dijitSelectMenu td.dijitMenuItemLabel {
 	/* line up menu text with text in select box (in LTR and RTL modes) */
 	padding: @textbox-padding;
diff --git a/dijit/themes/claro/form/Select_rtl.css b/dijit/themes/claro/form/Select_rtl.css
deleted file mode 100644
index a14d4ec..0000000
--- a/dijit/themes/claro/form/Select_rtl.css
+++ /dev/null
@@ -1,4 +0,0 @@
-.claro .dijitSelectRtl .dijitButtonContents {
-  border-right-width: 0;
-  border-left-width: 1px;
-}
diff --git a/dijit/themes/claro/form/Select_rtl.less b/dijit/themes/claro/form/Select_rtl.less
deleted file mode 100644
index ffa40dc..0000000
--- a/dijit/themes/claro/form/Select_rtl.less
+++ /dev/null
@@ -1,6 +0,0 @@
- at import "../variables";
-
-.claro .dijitSelectRtl .dijitButtonContents {
-	border-right-width: 0;
-	border-left-width: 1px;
-}
diff --git a/dijit/themes/claro/form/Slider.css b/dijit/themes/claro/form/Slider.css
index eb82e17..3ffcda1 100644
--- a/dijit/themes/claro/form/Slider.css
+++ b/dijit/themes/claro/form/Slider.css
@@ -63,24 +63,24 @@
   background-image: none;
   border-color: #d3d3d3;
 }
-.claro .dijitRuleLabel {
+.claro .dijitRuleLabelsContainer {
   color: #000000;
 }
 /* Horizontal Slider */
 .claro .dijitRuleLabelsContainerH {
   padding: 2px 0;
 }
-.claro .dijitSlider .dijitSliderProgressBarH, .claro .dijitSlider .dijitSliderLeftBumper {
-  background-image: url("../form/images/sliderHorizontal.png");
-  background-repeat: repeat-x;
-  background-position: 0 -20px;
+.claro .dijitSlider .dijitSliderProgressBarH,
+.claro .dijitSlider .dijitSliderLeftBumper {
   border-color: #b5bcc7;
   background-color: #cfe5fa;
+  background-image: -moz-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px);
+  background-image: -webkit-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px);
+  background-image: -o-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px);
+  background-image: linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px);
 }
-.claro .dijitSlider .dijitSliderRemainingBarH, .claro .dijitSlider .dijitSliderRightBumper {
-  background-image: url("../form/images/sliderHorizontal.png");
-  background-repeat: repeat-x;
-  background-position: 0 -11px;
+.claro .dijitSlider .dijitSliderRemainingBarH,
+.claro .dijitSlider .dijitSliderRightBumper {
   border-color: #b5bcc7;
   background-color: #ffffff;
 }
@@ -90,50 +90,58 @@
 .claro .dijitSliderLeftBumper {
   border-left: solid 1px #b5bcc7;
 }
-.claro .dijitSliderHover .dijitSliderProgressBarH, .claro .dijitSliderHover .dijitSliderLeftBumper {
-  background-position: 0 -20px;
+.claro .dijitSliderHover .dijitSliderProgressBarH,
+.claro .dijitSliderHover .dijitSliderLeftBumper {
   background-color: #abd6ff;
   border-color: #759dc0;
 }
-.claro .dijitSliderHover .dijitSliderRemainingBarH, .claro .dijitSliderHover .dijitSliderRightBumper {
-  background-position: 0 0;
+.claro .dijitSliderHover .dijitSliderRemainingBarH,
+.claro .dijitSliderHover .dijitSliderRightBumper {
   background-color: #ffffff;
   border-color: #759dc0;
 }
-.claro .dijitSliderFocused .dijitSliderProgressBarH, .claro .dijitSliderFocused .dijitSliderLeftBumper {
-  background-position: 0 -30px;
+.claro .dijitSliderFocused .dijitSliderProgressBarH,
+.claro .dijitSliderFocused .dijitSliderLeftBumper {
   background-color: #abd6ff;
   border-color: #759dc0;
+  -webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
+  box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
 }
-.claro .dijitSliderFocused .dijitSliderRemainingBarH, .claro .dijitSliderFocused .dijitSliderRightBumper {
-  background-position: 0 -9px;
+.claro .dijitSliderFocused .dijitSliderRemainingBarH,
+.claro .dijitSliderFocused .dijitSliderRightBumper {
   background-color: #ffffff;
   border-color: #759dc0;
+  -webkit-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
+  box-shadow: inset 0px 1px 1px rgba(0, 0, 0, 0.2);
 }
-.claro .dijitSliderDisabled .dijitSliderProgressBarH, .claro .dijitSliderDisabled .dijitSliderLeftBumper {
+.claro .dijitSliderDisabled .dijitSliderProgressBarH,
+.claro .dijitSliderDisabled .dijitSliderLeftBumper {
   background-color: #d3d3d3;
   /* left side of slider, fill matches border */
 
   background-image: none;
 }
-.claro .dijitSliderDisabled .dijitSliderRemainingBarH, .claro .dijitSliderDisabled .dijitSliderRightBumper {
+.claro .dijitSliderDisabled .dijitSliderRemainingBarH,
+.claro .dijitSliderDisabled .dijitSliderRightBumper {
   background-color: #efefef;
 }
 /* Vertical Slider */
 .claro .dijitRuleLabelsContainerV {
   padding: 0 2px;
 }
-.claro .dijitSlider .dijitSliderProgressBarV, .claro .dijitSlider .dijitSliderBottomBumper {
-  background-image: url("../form/images/sliderVertical.png");
-  background-repeat: repeat-y;
-  background-position: -36px 0;
+.claro .dijitSlider .dijitSliderProgressBarV,
+.claro .dijitSlider .dijitSliderBottomBumper {
   border-color: #b5bcc7;
   background-color: #cfe5fa;
+  background-image: -moz-linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 1px);
+  background-image: -webkit-linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 1px);
+  background-image: -o-linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 1px);
+  background-image: linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 1px);
 }
-.claro .dijitSlider .dijitSliderRemainingBarV, .claro .dijitSlider .dijitSliderTopBumper {
-  background-image: url("../form/images/sliderVertical.png");
-  background-repeat: repeat-y;
-  background-position: -3px 0;
+.claro .dijitSlider .dijitSliderRemainingBarV,
+.claro .dijitSlider .dijitSliderTopBumper {
   border-color: #b5bcc7;
   background-color: #ffffff;
 }
@@ -143,28 +151,40 @@
 .claro .dijitSliderTopBumper {
   border-top: solid 1px #b5bcc7;
 }
-.claro .dijitSliderHover .dijitSliderProgressBarV, .claro .dijitSliderHover .dijitSliderBottomBumper {
-  background-position: -36px 0;
+.claro .dijitSliderHover .dijitSliderProgressBarV,
+.claro .dijitSliderHover .dijitSliderBottomBumper {
   background-color: #abd6ff;
+  border-color: #759dc0;
 }
-.claro .dijitSliderHover .dijitSliderRemainingBarV, .claro .dijitSliderHover .dijitSliderTopBumper {
-  background-position: 0 0;
+.claro .dijitSliderHover .dijitSliderRemainingBarV,
+.claro .dijitSliderHover .dijitSliderTopBumper {
   background-color: #ffffff;
+  border-color: #759dc0;
 }
-.claro .dijitSliderFocused .dijitSliderProgressBarV, .claro .dijitSliderFocused .dijitSliderBottomBumper {
-  background-position: -56px 0;
+.claro .dijitSliderFocused .dijitSliderProgressBarV,
+.claro .dijitSliderFocused .dijitSliderBottomBumper {
   background-color: #abd6ff;
+  border-color: #759dc0;
+  -webkit-box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
+  box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
 }
-.claro .dijitSliderFocused .dijitSliderRemainingBarV, .claro .dijitSliderFocused .dijitSliderTopBumper {
-  background-position: -18px 0;
+.claro .dijitSliderFocused .dijitSliderRemainingBarV,
+.claro .dijitSliderFocused .dijitSliderTopBumper {
   background-color: #ffffff;
+  border-color: #759dc0;
+  -webkit-box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
+  -moz-box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
+  box-shadow: inset 1px 0px 1px rgba(0, 0, 0, 0.2);
 }
-.claro .dijitSliderDisabled .dijitSliderProgressBarV, .claro .dijitSliderDisabled .dijitSliderBottomBumper {
+.claro .dijitSliderDisabled .dijitSliderProgressBarV,
+.claro .dijitSliderDisabled .dijitSliderBottomBumper {
   background-color: #d3d3d3;
   /* bottom side of slider, fill matches border */
 
 }
-.claro .dijitSliderDisabled .dijitSliderRemainingBarV, .claro .dijitSliderDisabled .dijitSliderTopBumper {
+.claro .dijitSliderDisabled .dijitSliderRemainingBarV,
+.claro .dijitSliderDisabled .dijitSliderTopBumper {
   background-color: #efefef;
 }
 /* ------- Thumbs ------- */
@@ -188,7 +208,8 @@
 .claro .dijitSliderProgressBarH .dijitSliderThumbActive {
   background-position: -36px 0;
 }
-.claro .dijitSliderReadOnly .dijitSliderImageHandleH, .claro .dijitSliderDisabled .dijitSliderImageHandleH {
+.claro .dijitSliderReadOnly .dijitSliderImageHandleH,
+.claro .dijitSliderDisabled .dijitSliderImageHandleH {
   background-position: -54px 0;
 }
 .claro .dijitSliderImageHandleV {
@@ -211,7 +232,8 @@
 .claro .dijitSliderProgressBarV .dijitSliderThumbActive {
   background-position: -325px 0;
 }
-.claro .dijitSliderReadOnly .dijitSliderImageHandleV, .claro .dijitSliderDisabled .dijitSliderImageHandleV {
+.claro .dijitSliderReadOnly .dijitSliderImageHandleV,
+.claro .dijitSliderDisabled .dijitSliderImageHandleV {
   background-position: -343px 0;
 }
 /* ---- Increment/Decrement Buttons ---- */
@@ -233,11 +255,13 @@
   border: solid 1px #b5bcc7;
   font-size: 1px;
 }
-.claro .dijitSliderDecrementIconH, .claro .dijitSliderIncrementIconH {
+.claro .dijitSliderDecrementIconH,
+.claro .dijitSliderIncrementIconH {
   height: 12px;
   width: 9px;
 }
-.claro .dijitSliderDecrementIconV, .claro .dijitSliderIncrementIconV {
+.claro .dijitSliderDecrementIconV,
+.claro .dijitSliderIncrementIconV {
   height: 9px;
   width: 12px;
 }
@@ -257,25 +281,25 @@
 .claro .dijitSliderDecrementIconH {
   background-position: -357px 50%;
 }
-.claro .dijitSliderActive .dijitSliderDecrementIconH.claro .dijitSliderHover .dijitSliderDecrementIconH {
+.claro .dijitSliderActive .dijitSliderDecrementIconH .claro .dijitSliderHover .dijitSliderDecrementIconH {
   background-position: -393px 50%;
 }
 .claro .dijitSliderIncrementIconH {
   background-position: -251px 50%;
 }
-.claro .dijitSliderActive .dijitSliderIncrementIconH.claro .dijitSliderHover .dijitSliderIncrementIconH {
+.claro .dijitSliderActive .dijitSliderIncrementIconH .claro .dijitSliderHover .dijitSliderIncrementIconH {
   background-position: -283px 50%;
 }
 .claro .dijitSliderDecrementIconV {
   background-position: -38px 50%;
 }
-.claro .dijitSliderActive .dijitSliderDecrementIconV.claro .dijitSliderHover .dijitSliderDecrementIconV {
+.claro .dijitSliderActive .dijitSliderDecrementIconV .claro .dijitSliderHover .dijitSliderDecrementIconV {
   background-position: -73px 50%;
 }
 .claro .dijitSliderIncrementIconV {
   background-position: -143px 49%;
 }
-.claro .dijitSliderActive .dijitSliderIncrementIconV.claro .dijitSliderHover .dijitSliderIncrementIconV {
+.claro .dijitSliderActive .dijitSliderIncrementIconV .claro .dijitSliderHover .dijitSliderIncrementIconV {
   background-position: -178px 49%;
 }
 .claro .dijitSliderButtonContainerV .dijitSliderDecrementButtonHover,
@@ -297,33 +321,28 @@
 .claro .dijitSliderDisabled .dijitSliderBar {
   border-color: #d3d3d3;
 }
-.claro .dijitSliderReadOnly *, .claro .dijitSliderDisabled * {
+.claro .dijitSliderReadOnly *,
+.claro .dijitSliderDisabled * {
   border-color: #d3d3d3;
   color: #818181;
 }
-.claro .dijitSliderReadOnly .dijitSliderDecrementIconH, .claro .dijitSliderDisabled .dijitSliderDecrementIconH {
+.claro .dijitSliderReadOnly .dijitSliderDecrementIconH,
+.claro .dijitSliderDisabled .dijitSliderDecrementIconH {
   background-position: -321px 50%;
   background-color: #efefef;
 }
-.claro .dijitSliderReadOnly .dijitSliderIncrementIconH, .claro .dijitSliderDisabled .dijitSliderIncrementIconH {
+.claro .dijitSliderReadOnly .dijitSliderIncrementIconH,
+.claro .dijitSliderDisabled .dijitSliderIncrementIconH {
   background-position: -215px 50%;
   background-color: #efefef;
 }
-.claro .dijitSliderReadOnly .dijitSliderDecrementIconV, .claro .dijitSliderDisabled .dijitSliderDecrementIconV {
+.claro .dijitSliderReadOnly .dijitSliderDecrementIconV,
+.claro .dijitSliderDisabled .dijitSliderDecrementIconV {
   background-position: -3px 49%;
   background-color: #efefef;
 }
-.claro .dijitSliderReadOnly .dijitSliderIncrementIconV, .claro .dijitSliderDisabled .dijitSliderIncrementIconV {
+.claro .dijitSliderReadOnly .dijitSliderIncrementIconV,
+.claro .dijitSliderDisabled .dijitSliderIncrementIconV {
   background-position: -107px 49%;
   background-color: #efefef;
 }
-.dj_ie6 .claro .dijitSlider .dijitSliderProgressBarH,
-.dj_ie6 .claro .dijitSlider .dijitSliderLeftBumper,
-.dj_ie6 .claro .dijitSlider .dijitSliderRemainingBarH,
-.dj_ie6 .claro .dijitSlider .dijitSliderRightBumper,
-.dj_ie6 .claro .dijitSlider .dijitSliderProgressBarV,
-.dj_ie6 .claro .dijitSlider .dijitSliderTopBumper,
-.dj_ie6 .claro .dijitSlider .dijitSliderRemainingBarV,
-.dj_ie6 .claro .dijitSlider .dijitSliderBottomBumper {
-  background-image: none;
-}
diff --git a/dijit/themes/claro/form/Slider.less b/dijit/themes/claro/form/Slider.less
index db0f8cb..2c5bfe9 100644
--- a/dijit/themes/claro/form/Slider.less
+++ b/dijit/themes/claro/form/Slider.less
@@ -66,7 +66,7 @@
 	background-image: none;
 	border-color: @disabled-border-color;
 }
-.claro .dijitRuleLabel {
+.claro .dijitRuleLabelsContainer {
 	color: @text-color;
 }
 
@@ -77,17 +77,12 @@
 }
 .claro .dijitSlider .dijitSliderProgressBarH,
 .claro .dijitSlider .dijitSliderLeftBumper{
-	background-image: url("../@{image-form-slider-horizontal}");
-	background-repeat:repeat-x;
-	background-position:0 -20px;
 	border-color: @border-color;
 	background-color: @slider-fullbar-background-color;
+	.alpha-white-gradient (top, 1,0px, 1,1px, 0,2px);
 }
 .claro .dijitSlider .dijitSliderRemainingBarH,
 .claro .dijitSlider .dijitSliderRightBumper{
-	background-image: url("../@{image-form-slider-horizontal}");
-	background-repeat:repeat-x;
-	background-position:0 -11px;
 	border-color: @border-color;
 	background-color: @slider-remainingbar-background-color;
 }
@@ -99,27 +94,25 @@
 }
 .claro .dijitSliderHover .dijitSliderProgressBarH,
 .claro .dijitSliderHover .dijitSliderLeftBumper{
-	background-position:0 -20px;
 	background-color: @slider-hovered-fullbar-background-color;
 	border-color: @hovered-border-color;
 }
 .claro .dijitSliderHover .dijitSliderRemainingBarH,
 .claro .dijitSliderHover .dijitSliderRightBumper{
-	background-position:0 0;
 	background-color: @slider-hovered-remainingbar-background-color;
 	border-color: @hovered-border-color;
 }
 .claro .dijitSliderFocused .dijitSliderProgressBarH,
 .claro .dijitSliderFocused .dijitSliderLeftBumper{
-	background-position:0 -30px;
 	background-color: @slider-focused-fullbar-background-color;
 	border-color: @focused-border-color;
+	.box-shadow(inset 0px 1px 1px rgba(0, 0, 0, 0.2));
 }
 .claro .dijitSliderFocused .dijitSliderRemainingBarH,
 .claro .dijitSliderFocused .dijitSliderRightBumper{
-	background-position:0 -9px;
 	background-color: @slider-focused-remainingbar-background-color;
 	border-color: @focused-border-color;
+	.box-shadow(inset 0px 1px 1px rgba(0, 0, 0, 0.2));
 }
 .claro .dijitSliderDisabled .dijitSliderProgressBarH,
 .claro .dijitSliderDisabled .dijitSliderLeftBumper{
@@ -138,17 +131,12 @@
 }
 .claro .dijitSlider .dijitSliderProgressBarV,
 .claro .dijitSlider .dijitSliderBottomBumper{
-	background-image: url("../@{image-form-slider-vertical}");
-	background-repeat:repeat-y;
-	background-position:-36px 0;
 	border-color: @border-color;
 	background-color: @slider-fullbar-background-color;
+	.alpha-white-gradient (left, 1,0px, 0,1px);
 }
 .claro .dijitSlider .dijitSliderRemainingBarV,
 .claro .dijitSlider .dijitSliderTopBumper{
-	background-image: url("../@{image-form-slider-vertical}");
-	background-repeat:repeat-y;
-	background-position:-3px 0;
 	border-color: @border-color;
 	background-color: @slider-remainingbar-background-color;
 }
@@ -160,23 +148,25 @@
 }
 .claro .dijitSliderHover .dijitSliderProgressBarV,
 .claro .dijitSliderHover .dijitSliderBottomBumper{
-	background-position:-36px 0;
 	background-color: @slider-hovered-fullbar-background-color;
+	border-color: @hovered-border-color;
 }
 .claro .dijitSliderHover .dijitSliderRemainingBarV,
 .claro .dijitSliderHover .dijitSliderTopBumper{
-	background-position:0 0;
 	background-color: @slider-hovered-remainingbar-background-color;
+	border-color: @hovered-border-color;
 }
 .claro .dijitSliderFocused .dijitSliderProgressBarV,
 .claro .dijitSliderFocused .dijitSliderBottomBumper{
-	background-position:-56px 0;
 	background-color: @slider-focused-fullbar-background-color;
+	border-color: @focused-border-color;
+	.box-shadow(inset 1px 0px 1px rgba(0, 0, 0, 0.2));
 }
 .claro .dijitSliderFocused .dijitSliderRemainingBarV,
 .claro .dijitSliderFocused .dijitSliderTopBumper{
-	background-position:-18px 0;
 	background-color: @slider-focused-remainingbar-background-color;
+	border-color: @focused-border-color;
+	.box-shadow(inset 1px 0px 1px rgba(0, 0, 0, 0.2));
 }
 .claro .dijitSliderDisabled .dijitSliderProgressBarV,
 .claro .dijitSliderDisabled .dijitSliderBottomBumper{
@@ -352,14 +342,3 @@
 	background-position:-107px 49%;
 	background-color:@disabled-background-color;
 }
-
-.dj_ie6 .claro .dijitSlider .dijitSliderProgressBarH,
-.dj_ie6 .claro .dijitSlider .dijitSliderLeftBumper,
-.dj_ie6 .claro .dijitSlider .dijitSliderRemainingBarH,
-.dj_ie6 .claro .dijitSlider .dijitSliderRightBumper,
-.dj_ie6 .claro .dijitSlider .dijitSliderProgressBarV,
-.dj_ie6 .claro .dijitSlider .dijitSliderTopBumper,
-.dj_ie6 .claro .dijitSlider .dijitSliderRemainingBarV,
-.dj_ie6 .claro .dijitSlider .dijitSliderBottomBumper {
-	background-image:none;
-}
diff --git a/dijit/themes/claro/form/Slider_rtl.css b/dijit/themes/claro/form/Slider_rtl.css
index 97e078b..0f39093 100644
--- a/dijit/themes/claro/form/Slider_rtl.css
+++ b/dijit/themes/claro/form/Slider_rtl.css
@@ -5,7 +5,9 @@
 .claro .dijitSliderRtl .dijitSliderTopBumper {
   background-position: top right;
 }
-.claro .dijitSliderRtl .dijitSliderProgressBarV, .claro .dijitSliderRtl .dijitSliderRemainingBarV, .claro .dijitSliderRtl .dijitSliderBottomBumper {
+.claro .dijitSliderRtl .dijitSliderProgressBarV,
+.claro .dijitSliderRtl .dijitSliderRemainingBarV,
+.claro .dijitSliderRtl .dijitSliderBottomBumper {
   background-position: bottom right;
 }
 .claro .dijitSliderRtl .dijitSliderLeftBumper {
diff --git a/dijit/themes/claro/form/images/button.png b/dijit/themes/claro/form/images/button.png
deleted file mode 100644
index cb787cb..0000000
Binary files a/dijit/themes/claro/form/images/button.png and /dev/null differ
diff --git a/dijit/themes/claro/form/images/buttonDisabled.png b/dijit/themes/claro/form/images/buttonDisabled.png
new file mode 100644
index 0000000..faf57ba
Binary files /dev/null and b/dijit/themes/claro/form/images/buttonDisabled.png differ
diff --git a/dijit/themes/claro/form/images/buttonDisabled.svg b/dijit/themes/claro/form/images/buttonDisabled.svg
new file mode 100644
index 0000000..72a51a0
--- /dev/null
+++ b/dijit/themes/claro/form/images/buttonDisabled.svg
@@ -0,0 +1,23 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for buttonDisabled.png, which is used by IE7-9 for Button gradients.
+	Compile to png with batik, gimp, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match gradients defined in Button.css.  It is however an approximation, since generated
+	output has a constant height, rather than matching the height of each button.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="1px" height="18px" viewBox="0 0 1 18" preserveAspectRatio="none">
+
+	<defs>
+		<linearGradient id="disabled" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="0%" y2="100%">
+			<stop offset="0%" stop-color="#ffffff" stop-opacity="1"/>
+			<stop offset="50%" stop-color="#ffffff" stop-opacity="0"/>
+		</linearGradient>
+	</defs>
+
+	<!--
+		Swatch for disabled buttons.   It will only fill the top part of the disabled buttons.
+		The bottom of disabled buttons are pure background-color
+	-->
+	<rect x="0" y="0" width="1" height="18" fill="url(#disabled)"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/form/images/buttonEnabled.png b/dijit/themes/claro/form/images/buttonEnabled.png
new file mode 100644
index 0000000..0932a99
Binary files /dev/null and b/dijit/themes/claro/form/images/buttonEnabled.png differ
diff --git a/dijit/themes/claro/form/images/buttonEnabled.svg b/dijit/themes/claro/form/images/buttonEnabled.svg
new file mode 100644
index 0000000..d9e564a
--- /dev/null
+++ b/dijit/themes/claro/form/images/buttonEnabled.svg
@@ -0,0 +1,24 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for buttonEnabled.png, which is used by IE7-9 for Button gradients.
+	Compile to png with batik, gimp, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match gradients defined in Button.css.  It is however an approximation, since generated
+	output has a constant height, rather than matching the height of each button.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="1px" height="149px" viewBox="0 0 1 149" preserveAspectRatio="none">
+
+	<defs>
+		<linearGradient id="enabled" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="0%" y2="100%">
+			<stop offset="0%" stop-color="#ffffff" stop-opacity="1"/>
+			<stop offset="2%" stop-color="#ffffff" stop-opacity="0"/>
+			<stop offset="15%" stop-color="#ffffff" stop-opacity="0.7"/> <!-- near bottom of average height buttons -->
+		</linearGradient>
+	</defs>
+
+	<!--
+		Swatch for enabled buttons.   It's 149px tall to account for tall buttons, but usually
+		only the top will be visible.
+	-->
+	<rect x="0" y="0" width="1" height="149" fill="url(#enabled)"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/form/images/button_grad_d.png b/dijit/themes/claro/form/images/button_grad_d.png
deleted file mode 100644
index 3a71a46..0000000
Binary files a/dijit/themes/claro/form/images/button_grad_d.png and /dev/null differ
diff --git a/dijit/themes/claro/form/images/formHighlight.png b/dijit/themes/claro/form/images/formHighlight.png
deleted file mode 100644
index f90eb25..0000000
Binary files a/dijit/themes/claro/form/images/formHighlight.png and /dev/null differ
diff --git a/dijit/themes/claro/form/images/shadow.png b/dijit/themes/claro/form/images/shadow.png
deleted file mode 100644
index 72d60e6..0000000
Binary files a/dijit/themes/claro/form/images/shadow.png and /dev/null differ
diff --git a/dijit/themes/claro/form/images/sliderHorizontal.png b/dijit/themes/claro/form/images/sliderHorizontal.png
deleted file mode 100644
index d769a64..0000000
Binary files a/dijit/themes/claro/form/images/sliderHorizontal.png and /dev/null differ
diff --git a/dijit/themes/claro/form/images/sliderVertical.png b/dijit/themes/claro/form/images/sliderVertical.png
deleted file mode 100644
index 9d69d04..0000000
Binary files a/dijit/themes/claro/form/images/sliderVertical.png and /dev/null differ
diff --git a/dijit/themes/claro/form/images/textBox_back.png b/dijit/themes/claro/form/images/textBox_back.png
deleted file mode 100644
index dfc752a..0000000
Binary files a/dijit/themes/claro/form/images/textBox_back.png and /dev/null differ
diff --git a/dijit/themes/claro/images/activeGradient.png b/dijit/themes/claro/images/activeGradient.png
new file mode 100644
index 0000000..e70daaa
Binary files /dev/null and b/dijit/themes/claro/images/activeGradient.png differ
diff --git a/dijit/themes/claro/images/activeGradient.svg b/dijit/themes/claro/images/activeGradient.svg
new file mode 100644
index 0000000..8ab6ce9
--- /dev/null
+++ b/dijit/themes/claro/images/activeGradient.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for standardGradient.png, which is used by IE7-9 for light-to-dark gradient of many widgets.
+	Compile to png with batik, gimp, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match CSS gradient from .standard-gradient() mixin in variables.css.
+	It is however an approximation, since generated
+	output has a constant height, rather than matching the height of each node.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="1px" height="16px" viewBox="0 0 1 1" preserveAspectRatio="none">
+	<defs>
+		<linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="0%" y2="100%">
+			<stop offset="0%" stop-color="rgb(190,190,190)" stop-opacity="0.98"/>
+			<stop offset="20%" stop-color="#ffffff" stop-opacity="0.65"/>
+			<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
+		</linearGradient>
+	</defs>
+	<rect x="0" y="0" width="1" height="1" fill="url(#gradient)"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/images/calendar.png b/dijit/themes/claro/images/calendar.png
new file mode 100644
index 0000000..d892e49
Binary files /dev/null and b/dijit/themes/claro/images/calendar.png differ
diff --git a/dijit/themes/claro/images/calendarArrows.png b/dijit/themes/claro/images/calendarArrows.png
index 3f6faa5..73333ad 100644
Binary files a/dijit/themes/claro/images/calendarArrows.png and b/dijit/themes/claro/images/calendarArrows.png differ
diff --git a/dijit/themes/claro/images/calendarArrows8bit.png b/dijit/themes/claro/images/calendarArrows8bit.png
index ab9d66c..c865260 100644
Binary files a/dijit/themes/claro/images/calendarArrows8bit.png and b/dijit/themes/claro/images/calendarArrows8bit.png differ
diff --git a/dijit/themes/claro/images/calendarContainerImages.png b/dijit/themes/claro/images/calendarContainerImages.png
deleted file mode 100644
index 44fa088..0000000
Binary files a/dijit/themes/claro/images/calendarContainerImages.png and /dev/null differ
diff --git a/dijit/themes/claro/images/checkmarkNoBorder.png b/dijit/themes/claro/images/checkmarkNoBorder.png
index 9cec0c0..ae3271a 100644
Binary files a/dijit/themes/claro/images/checkmarkNoBorder.png and b/dijit/themes/claro/images/checkmarkNoBorder.png differ
diff --git a/dijit/themes/claro/images/commonHighlight.png b/dijit/themes/claro/images/commonHighlight.png
deleted file mode 100644
index f90eb25..0000000
Binary files a/dijit/themes/claro/images/commonHighlight.png and /dev/null differ
diff --git a/dijit/themes/claro/images/dialogCloseIcon.png b/dijit/themes/claro/images/dialogCloseIcon.png
index a605c71..f69a1e7 100644
Binary files a/dijit/themes/claro/images/dialogCloseIcon.png and b/dijit/themes/claro/images/dialogCloseIcon.png differ
diff --git a/dijit/themes/claro/images/dialogCloseIcon8bit.png b/dijit/themes/claro/images/dialogCloseIcon8bit.png
index d2b063b..200c0af 100644
Binary files a/dijit/themes/claro/images/dialogCloseIcon8bit.png and b/dijit/themes/claro/images/dialogCloseIcon8bit.png differ
diff --git a/dijit/themes/claro/images/dnd.png b/dijit/themes/claro/images/dnd.png
index 8cb04aa..6e1d899 100644
Binary files a/dijit/themes/claro/images/dnd.png and b/dijit/themes/claro/images/dnd.png differ
diff --git a/dijit/themes/claro/images/loadingAnimation.gif b/dijit/themes/claro/images/loadingAnimation.gif
index d76e4cd..694e2cb 100644
Binary files a/dijit/themes/claro/images/loadingAnimation.gif and b/dijit/themes/claro/images/loadingAnimation.gif differ
diff --git a/dijit/themes/claro/images/menuHighlight.png b/dijit/themes/claro/images/menuHighlight.png
deleted file mode 100644
index 22328a7..0000000
Binary files a/dijit/themes/claro/images/menuHighlight.png and /dev/null differ
diff --git a/dijit/themes/claro/images/progressBarEmpty.png b/dijit/themes/claro/images/progressBarEmpty.png
deleted file mode 100644
index e0a6856..0000000
Binary files a/dijit/themes/claro/images/progressBarEmpty.png and /dev/null differ
diff --git a/dijit/themes/claro/images/progressBarFull.png b/dijit/themes/claro/images/progressBarFull.png
index 280f51d..90c9eaa 100644
Binary files a/dijit/themes/claro/images/progressBarFull.png and b/dijit/themes/claro/images/progressBarFull.png differ
diff --git a/dijit/themes/claro/images/spriteArrows.png b/dijit/themes/claro/images/spriteArrows.png
index 608f4c7..e9d99ab 100644
Binary files a/dijit/themes/claro/images/spriteArrows.png and b/dijit/themes/claro/images/spriteArrows.png differ
diff --git a/dijit/themes/claro/images/standardGradient.png b/dijit/themes/claro/images/standardGradient.png
new file mode 100644
index 0000000..72241f1
Binary files /dev/null and b/dijit/themes/claro/images/standardGradient.png differ
diff --git a/dijit/themes/claro/images/standardGradient.svg b/dijit/themes/claro/images/standardGradient.svg
new file mode 100644
index 0000000..807c3c7
--- /dev/null
+++ b/dijit/themes/claro/images/standardGradient.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for standardGradient.png, which is used by IE7-9 for light-to-dark gradient of many widgets.
+	Compile to png with batik, gimp, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match CSS gradient from .standard-gradient() mixin in variables.css.
+	It is however an approximation, since generated
+	output has a constant height, rather than matching the height of each node.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="16px" height="16px" viewBox="0 0 1 1" preserveAspectRatio="none">
+	<defs>
+		<linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="0%" y2="100%">
+			<stop offset="0%" stop-color="#ffffff" stop-opacity="0.7"/>
+			<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
+		</linearGradient>
+	</defs>
+	<rect x="0" y="0" width="1" height="1" fill="url(#gradient)"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/images/tooltip.png b/dijit/themes/claro/images/tooltip.png
index 2b22273..9d279cd 100644
Binary files a/dijit/themes/claro/images/tooltip.png and b/dijit/themes/claro/images/tooltip.png differ
diff --git a/dijit/themes/claro/images/tooltip8bit.png b/dijit/themes/claro/images/tooltip8bit.png
index 51f65f1..0035072 100644
Binary files a/dijit/themes/claro/images/tooltip8bit.png and b/dijit/themes/claro/images/tooltip8bit.png differ
diff --git a/dijit/themes/claro/images/tooltipGradient.png b/dijit/themes/claro/images/tooltipGradient.png
deleted file mode 100644
index ce4860e..0000000
Binary files a/dijit/themes/claro/images/tooltipGradient.png and /dev/null differ
diff --git a/dijit/themes/claro/images/treeExpandImages.png b/dijit/themes/claro/images/treeExpandImages.png
index 75cf385..350a1dd 100644
Binary files a/dijit/themes/claro/images/treeExpandImages.png and b/dijit/themes/claro/images/treeExpandImages.png differ
diff --git a/dijit/themes/claro/images/treeExpandImages8bit.png b/dijit/themes/claro/images/treeExpandImages8bit.png
index 290b2e1..294ce7a 100644
Binary files a/dijit/themes/claro/images/treeExpandImages8bit.png and b/dijit/themes/claro/images/treeExpandImages8bit.png differ
diff --git a/dijit/themes/claro/images/treeExpand_loading.gif b/dijit/themes/claro/images/treeExpand_loading.gif
deleted file mode 100644
index 424d376..0000000
Binary files a/dijit/themes/claro/images/treeExpand_loading.gif and /dev/null differ
diff --git a/dijit/themes/claro/layout/AccordionContainer.css b/dijit/themes/claro/layout/AccordionContainer.css
index 3483176..be0c851 100644
--- a/dijit/themes/claro/layout/AccordionContainer.css
+++ b/dijit/themes/claro/layout/AccordionContainer.css
@@ -50,16 +50,17 @@
   background-color: transparent;
   /* pick up color from dijitAccordionInnerContainer */
 
-  background-image: url("../layout/images/accordion.png");
-  background-position: 0 0;
+  background-image: url("../images/standardGradient.png");
   background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   padding: 5px 7px 2px 7px;
   min-height: 17px;
   color: #494949;
 }
-.dj_ie6 .claro .dijitAccordionTitle {
-  background-image: none;
-}
 .claro .dijitAccordionContainer .dijitAccordionChildWrapper {
   /* this extends the blue trim styling of the title bar to wrapping around the node.
 	 * done by setting margin
@@ -74,6 +75,17 @@
 
   padding: 9px;
 }
+/* Hover state for closed pane */
+.claro .dijitAccordionInnerContainerHover {
+  border: 1px solid #759dc0;
+  background-color: #abd6ff;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.claro .dijitAccordionInnerContainerHover .dijitAccordionTitle {
+  color: #000000;
+}
 /* Active state for closed pane */
 .claro .dijitAccordionInnerContainerActive {
   border: 1px solid #759dc0;
@@ -83,7 +95,13 @@
   transition-duration: 0.1s;
 }
 .claro .dijitAccordionInnerContainerActive .dijitAccordionTitle {
-  background-position: 0 -136px;
+  background-image: url("../images/activeGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(190, 190, 190, 0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   color: #000000;
 }
 /* Open (a.k.a. selected) pane */
@@ -93,29 +111,13 @@
 }
 .claro .dijitAccordionInnerContainerSelected .dijitAccordionTitle {
   color: #000000;
-  background-position: 0 0;
+  background-image: url("../images/standardGradient.png");
+  background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+  _background-image: none;
   /* avoid effect when clicking the title of the open pane */
 
 }
-/* Hovering open or closed pane */
-.claro .dijitAccordionInnerContainerHover .dijitAccordionTitle {
-  /* both open and closed */
-
-  color: #000000;
-}
-.claro .dijitAccordionInnerContainerHover, .claro .dijitAccordionInnerContainerSelectedActive {
-  /* note: clicking the currently selected Accordion pane should have no effect, so treating same as hover. */
-
-  border: 1px solid #759dc0;
-  background-color: #abd6ff;
-  -webkit-transition-duration: 0.2s;
-  -moz-transition-duration: 0.2s;
-  transition-duration: 0.2s;
-}
-.claro .dijitAccordionInnerContainerSelectedHover .dijitAccordionChildWrapper, .claro .dijitAccordionInnerContainerSelectedActive .dijitAccordionChildWrapper {
-  background-color: #ffffff;
-  border: 1px solid #759dc0 !important;
-  -webkit-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.25);
-  -moz-box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.25);
-  box-shadow: inset 0 0 3px rgba(0, 0, 0, 0.25);
-}
diff --git a/dijit/themes/claro/layout/AccordionContainer.less b/dijit/themes/claro/layout/AccordionContainer.less
index b3aa622..f0668a2 100644
--- a/dijit/themes/claro/layout/AccordionContainer.less
+++ b/dijit/themes/claro/layout/AccordionContainer.less
@@ -43,16 +43,12 @@
 }
 .claro .dijitAccordionTitle {
 	background-color: transparent;	/* pick up color from dijitAccordionInnerContainer */
-	background-image: url("../@{image-layout-accordion}");
-	background-position:0 0;
-	background-repeat:repeat-x;
+	.standard-gradient("../");
 	padding: 5px 7px 2px 7px;
 	min-height:17px;
 	color:@unselected-text-color;
 }
-.dj_ie6 .claro .dijitAccordionTitle {
-	background-image: none;
-}
+
 .claro .dijitAccordionContainer .dijitAccordionChildWrapper {
 	/* this extends the blue trim styling of the title bar to wrapping around the node.
 	 * done by setting margin
@@ -67,6 +63,18 @@
 	padding: 9px;
 }
 
+/* Hover state for closed pane */
+
+.claro .dijitAccordionInnerContainerHover {
+	border:1px solid @hovered-border-color;
+	background-color:@hovered-background-color;
+	.transition-duration(.2s);
+}
+
+.claro .dijitAccordionInnerContainerHover .dijitAccordionTitle {
+	color:@hovered-text-color;
+}
+
 /* Active state for closed pane */
 
 .claro .dijitAccordionInnerContainerActive {
@@ -75,7 +83,7 @@
 	.transition-duration(.1s);
 }
 .claro .dijitAccordionInnerContainerActive .dijitAccordionTitle {
-	background-position:0 -136px;
+	.active-gradient("../");
 	color:@selected-text-color;
 }
 
@@ -87,27 +95,6 @@
 }
 .claro .dijitAccordionInnerContainerSelected .dijitAccordionTitle {
 	color:@selected-text-color;
-	background-position: 0 0;	/* avoid effect when clicking the title of the open pane */
+	.standard-gradient("../");	/* avoid effect when clicking the title of the open pane */
 }
 
-/* Hovering open or closed pane */
-
-.claro .dijitAccordionInnerContainerHover .dijitAccordionTitle {
-	/* both open and closed */
-	color:@hovered-text-color;
-}
-
-.claro .dijitAccordionInnerContainerHover,
-.claro .dijitAccordionInnerContainerSelectedActive {
-	/* note: clicking the currently selected Accordion pane should have no effect, so treating same as hover. */
-	border:1px solid @hovered-border-color;
-	background-color:@hovered-background-color;
-	.transition-duration(.2s);
-}
-
-.claro .dijitAccordionInnerContainerSelectedHover .dijitAccordionChildWrapper,
-.claro .dijitAccordionInnerContainerSelectedActive .dijitAccordionChildWrapper {
-	background-color:@pane-background-color;
-	border:1px solid @hovered-border-color !important;
-	.box-shadow(inset 0 0 3px rgba(0, 0, 0, .25));
-}
diff --git a/dijit/themes/claro/layout/BorderContainer.css b/dijit/themes/claro/layout/BorderContainer.css
index 8c0a5fa..ede0b50 100644
--- a/dijit/themes/claro/layout/BorderContainer.css
+++ b/dijit/themes/claro/layout/BorderContainer.css
@@ -34,7 +34,8 @@ Splitters and gutters:
 
   padding: 5px;
 }
-.claro .dijitSplitContainer-child, .claro .dijitBorderContainer-child {
+.claro .dijitSplitContainer-child,
+.claro .dijitBorderContainer-child {
   /* By default put borders on all children of BorderContainer,
 	 *  to give illusion of borders on the splitters themselves.
 	 */
@@ -59,23 +60,37 @@ Splitters and gutters:
   padding: 0;
 }
 /* Splitters and gutters */
-.claro .dijitSplitterH, .claro .dijitGutterH {
+.claro .dijitSplitterH,
+.claro .dijitGutterH {
   background: none;
   border: 0;
   height: 5px;
 }
+.dj_ios .claro .dijitSplitterH,
+.dj_android .claro .dijitSplitterH {
+  height: 11px;
+}
 .claro .dijitSplitterH .dijitSplitterThumb {
   background: #b5bcc7 none;
   height: 1px;
   top: 2px;
   width: 19px;
 }
-.claro .dijitSplitterV, .claro .dijitGutterV {
+.dj_ios .claro .dijitSplitterH .dijitSplitterThumb,
+.dj_android .claro .dijitSplitterH .dijitSplitterThumb {
+  top: 5px;
+}
+.claro .dijitSplitterV,
+.claro .dijitGutterV {
   background: none;
   border: 0;
   width: 5px;
   margin: 0;
 }
+.dj_ios .claro .dijitSplitterV,
+.dj_android .claro .dijitSplitterV {
+  width: 11px;
+}
 .claro .dijitSplitterV .dijitSplitterThumb {
   background: #b5bcc7 none;
   height: 19px;
@@ -83,27 +98,36 @@ Splitters and gutters:
   width: 1px;
   margin: 0;
 }
+.dj_ios .claro .dijitSplitterV .dijitSplitterThumb,
+.dj_android .claro .dijitSplitterV .dijitSplitterThumb {
+  left: 5px;
+}
 /* hovered splitter */
-.claro .dijitSplitterHHover {
+.claro .dijitSplitterHHover,
+.claro .dijitSplitterVHover {
   font-size: 1px;
-  background: url("../layout/images/splitterHorizontalHover.png") no-repeat center top;
+  background-color: #cfe5fa;
 }
-.claro .dijitSplitterHHover .dijitSplitterThumb {
-  background: #759dc0 none;
+.claro .dijitSplitterHHover {
+  background-image: -moz-linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 50%, #ffffff 100%);
+  background-image: -webkit-linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 50%, #ffffff 100%);
+  background-image: -o-linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 50%, #ffffff 100%);
+  background-image: linear-gradient(left, #ffffff 0px, rgba(255, 255, 255, 0) 50%, #ffffff 100%);
 }
 .claro .dijitSplitterVHover {
-  font-size: 1px;
-  background: url("../layout/images/splitterVerticalHover.png") no-repeat center left;
+  background-image: -moz-linear-gradient(top, #ffffff 0px, rgba(255, 255, 255, 0) 50%, #ffffff 100%);
+  background-image: -webkit-linear-gradient(top, #ffffff 0px, rgba(255, 255, 255, 0) 50%, #ffffff 100%);
+  background-image: -o-linear-gradient(top, #ffffff 0px, rgba(255, 255, 255, 0) 50%, #ffffff 100%);
+  background-image: linear-gradient(top, #ffffff 0px, rgba(255, 255, 255, 0) 50%, #ffffff 100%);
 }
+.claro .dijitSplitterHHover .dijitSplitterThumb,
 .claro .dijitSplitterVHover .dijitSplitterThumb {
   background: #759dc0 none;
 }
-.dj_ie6 .dijitSplitterHHover, .dj_ie6 .claro .dijitSplitterVHover {
-  background-color: #cfe5fa;
-  background-image: none;
-}
 /* active splitter */
-.claro .dijitSplitterHActive, .claro .dijitSplitterVActive {
+.claro .dijitSplitterHActive,
+.claro .dijitSplitterVActive {
   font-size: 1px;
   background-color: #abd6ff;
+  background-image: none;
 }
diff --git a/dijit/themes/claro/layout/BorderContainer.less b/dijit/themes/claro/layout/BorderContainer.less
index b7c672e..194daf2 100644
--- a/dijit/themes/claro/layout/BorderContainer.less
+++ b/dijit/themes/claro/layout/BorderContainer.less
@@ -70,6 +70,9 @@ Splitters and gutters:
 	border:0;
 	height:5px;
 }
+.dj_ios .claro .dijitSplitterH, .dj_android .claro .dijitSplitterH {
+  height: 11px;
+}
 
 .claro .dijitSplitterH .dijitSplitterThumb {
 	background:@border-color none;
@@ -77,7 +80,9 @@ Splitters and gutters:
 	top:2px;
 	width:19px;
 }
-
+.dj_ios .claro .dijitSplitterH .dijitSplitterThumb, .dj_android .claro .dijitSplitterH .dijitSplitterThumb{
+  top:5px;
+}
 .claro .dijitSplitterV,
 .claro .dijitGutterV {
 	background:none;
@@ -85,6 +90,9 @@ Splitters and gutters:
 	width:5px;
 	margin: 0;
 }
+.dj_ios .claro .dijitSplitterV, .dj_android .claro .dijitSplitterV {
+  width: 11px;
+}
 
 .claro .dijitSplitterV .dijitSplitterThumb {
 	background:@border-color none;
@@ -93,36 +101,35 @@ Splitters and gutters:
 	width:1px;
 	margin: 0;
 }
+.dj_ios .claro .dijitSplitterV .dijitSplitterThumb, .dj_android .claro .dijitSplitterV .dijitSplitterThumb{
+  left:5px;
+}
 
 /* hovered splitter */
-.claro .dijitSplitterHHover {
+.claro .dijitSplitterHHover,
+.claro .dijitSplitterVHover {
 	font-size: 1px;
-	background: url("../@{image-layout-splitter-horizontal-hover}") no-repeat center top;
+	background-color: @splitter-hovered-background-color;
 }
 
-
-.claro .dijitSplitterHHover .dijitSplitterThumb {
-	background:@hovered-border-color none;
+.claro .dijitSplitterHHover {
+	.alpha-white-gradient (left, 1,0px,  0,50%, 1,100%);
 }
 
 .claro .dijitSplitterVHover {
-	font-size: 1px;
-	background: url("../@{image-layout-splitter-vertical-hover}") no-repeat center left;
+	.alpha-white-gradient (top, 1,0px,  0,50%, 1,100%);
 }
 
+.claro .dijitSplitterHHover .dijitSplitterThumb,
 .claro .dijitSplitterVHover .dijitSplitterThumb {
 	background:@hovered-border-color none;
 }
 
-.dj_ie6 .dijitSplitterHHover,
-.dj_ie6 .claro .dijitSplitterVHover {
-	background-color: @splitter-hovered-background-color;
-	background-image:none;
-}
 
 /* active splitter */
 .claro .dijitSplitterHActive,
 .claro .dijitSplitterVActive {
 	font-size: 1px;
 	background-color:@splitter-dragged-background-color;
+	background-image: none;		// color all the way across, not gradient like in hover mode
 }
diff --git a/dijit/themes/claro/layout/ContentPane.css b/dijit/themes/claro/layout/ContentPane.css
index a7753de..7499a53 100644
--- a/dijit/themes/claro/layout/ContentPane.css
+++ b/dijit/themes/claro/layout/ContentPane.css
@@ -32,7 +32,8 @@
   background-color: #ffffff;
   padding: 8px;
 }
-.claro .dijitSplitContainer-dijitContentPane, .claro .dijitBorderContainer-dijitContentPane {
+.claro .dijitSplitContainer-dijitContentPane,
+.claro .dijitBorderContainer-dijitContentPane {
   background-color: #ffffff;
   padding: 8px;
 }
diff --git a/dijit/themes/claro/layout/TabContainer.css b/dijit/themes/claro/layout/TabContainer.css
index 641b921..50ac4ad 100644
--- a/dijit/themes/claro/layout/TabContainer.css
+++ b/dijit/themes/claro/layout/TabContainer.css
@@ -17,18 +17,18 @@
  * 		.tabStripButtonDisabled - styles for disabled tab strip buttons
  * 
  * Tab Button:
- * 		.dijitTabContainerTop-tabs .dijitTabInnerDiv/.dijitTabContent     - styles for top tab button container
- * 		.dijitTabContainerBottom-tabs .dijitTabInnerDiv/.dijitTabContent  - styles for bottom tab button container
- * 		.dijitTabContainerLeft-tabs .dijitTabInnerDiv/.dijitTabContent    - styles for left tab button container
- * 		.dijitTabContainerRight-tabs .dijitTabInnerDiv/.dijitTabContent   - styles for right tab button container
+ * 		.dijitTabContainerTop-tabs .dijitTab     - styles for top tab button container
+ * 		.dijitTabContainerBottom-tabs .dijitTab  - styles for bottom tab button container
+ * 		.dijitTabContainerLeft-tabs .dijitTab    - styles for left tab button container
+ * 		.dijitTabContainerRight-tabs .dijitTab   - styles for right tab button container
  * 
- * 		.dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv/.dijitTabContent    
+ * 		.dijitTabContainerTop-tabs .dijitTabChecked .dijitTab
  * 				- styles for selected status of top tab button
  * 		same to Bottom, Left, Right Tabs
  * 
- * 		.dijitTabHover .dijitTabInnerDiv   - styles when mouse hover on tab buttons
- * 		.dijitTabActive .dijitTabInnerDiv  - styles when mouse down on tab buttons
- * 		.dijitTabChecked .dijitTabInnerDiv  - styles when on buttons of selected tab		
+ * 		.dijitTabHover .dijitTab   - styles when mouse hover on tab buttons
+ * 		.dijitTabActive .dijitTab  - styles when mouse down on tab buttons
+ * 		.dijitTabChecked .dijitTab  - styles when on buttons of selected tab
  * 
  * 		.dijitTabCloseButton - the close action buttons lie at the right top of each tab button on closable tabs
  * 		.dijitTabCloseButtonHover - styles when mouse hover on close action button
@@ -77,7 +77,8 @@
 
   display: none;
 }
-.claro .dijitTabInnerDiv {
+.claro .dijitTab {
+  border: 1px solid #b5bcc7;
   background-color: #efefef;
   -webkit-transition-property: background-color, border;
   -moz-transition-property: background-color, border;
@@ -87,132 +88,104 @@
   transition-duration: 0.35s;
   color: #494949;
 }
-.claro .dijitTabHover .dijitTabInnerDiv {
+.claro .dijitTabHover {
+  border-color: #759dc0;
   background-color: #abd6ff;
   -webkit-transition-duration: 0.25s;
   -moz-transition-duration: 0.25s;
   transition-duration: 0.25s;
   color: #000000;
 }
-.claro .dijitTabActive .dijitTabInnerDiv {
+.claro .dijitTabActive {
+  border-color: #759dc0;
   background-color: #7dbdfa;
   color: #000000;
   -webkit-transition-duration: 0.1s;
   -moz-transition-duration: 0.1s;
   transition-duration: 0.1s;
 }
-.claro .dijitTabChecked .dijitTabInnerDiv {
+.claro .dijitTabChecked {
+  border-color: #b5bcc7;
   background-color: #cfe5fa;
   color: #000000;
 }
-.claro .dijitTabContent {
-  border: 1px solid #b5bcc7;
-}
-.claro .dijitTabHover .dijitTabContent {
-  border-color: #759dc0;
-}
-.claro .dijitTabActive .dijitTabContent {
-  border-color: #759dc0;
-}
-.claro .dijitTabChecked .dijitTabContent {
-  color: #000000;
-  border-color: #b5bcc7;
+.claro .dijitTabDisabled {
+  background-color: #d3d3d3;
 }
-.claro .tabStripButton .dijitTabInnerDiv {
+.claro .tabStripButton {
   background-color: transparent;
-}
-.claro .tabStripButton .dijitTabContent {
   border: none;
 }
 /*** end common ***/
 /*************** top tab ***************/
 .claro .dijitTabContainerTop-tabs .dijitTab {
+  /* unselected (and not hovered/pressed) tab */
+
   top: 1px;
   /* used for overlap */
 
   margin-right: 1px;
-  padding-top: 3px;
-}
-.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTab {
-  top: 3px;
-}
-/* for top tab padding. change height when status changes */
-.claro .dijitTabContainerTop-tabs .dijitTabContent {
   padding: 3px 6px;
   border-bottom-width: 0;
-  background-image: url("../layout/images/tabTop.png");
-  background-position: 0 0;
-  background-repeat: repeat-x;
   min-width: 60px;
   text-align: center;
-}
-.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabContent {
-  padding-bottom: 4px;
-  padding-top: 6px;
-}
-/* normal status */
-.claro .dijitTabContainerTop-tabs .dijitTabInnerDiv {
-  background-image: url("../layout/images/tabTop.png");
-  background-position: 0 -248px;
-  background-position: bottom;
+  background-image: url("images/tabTopUnselected.png");
   background-repeat: repeat-x;
+  background-image: -moz-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
   -webkit-box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.04);
   -moz-box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.04);
   box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.04);
 }
-/* checked status */
-.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv {
-  background-image: none;
+.claro .dijitTabContainerTop-tabs .dijitTabChecked {
+  /* selected tab */
+
+  padding-bottom: 4px;
+  padding-top: 9px;
+  background-image: url("images/tabTopSelected.png");
+  background-image: -moz-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px, #ffffff 7px);
+  background-image: -webkit-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px, #ffffff 7px);
+  background-image: -o-linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px, #ffffff 7px);
+  background-image: linear-gradient(top, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px, #ffffff 7px);
   -webkit-box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.05);
   -moz-box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.05);
   box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.05);
 }
-.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabContent {
-  background-position: 0 -102px;
-  background-repeat: repeat-x;
-}
 /** end top tab **/
 /*************** bottom tab ***************/
 .claro .dijitTabContainerBottom-tabs .dijitTab {
+  /* unselected (and not hovered/pressed) tab */
+
   top: -1px;
   /* used for overlap */
 
   margin-right: 1px;
-}
-/* calculate the position and size */
-.claro .dijitTabContainerBottom-tabs .dijitTabContent {
   padding: 3px 6px;
   border-top-width: 0;
-  background-image: url("../layout/images/tabBottom.png");
-  background-position: 0 -249px;
-  background-repeat: repeat-x;
-  background-position: bottom;
   min-width: 60px;
   text-align: center;
-}
-.claro .dijitTabContainerBottom-tabs .dijitTab {
-  padding-bottom: 3px;
-}
-/* normal status */
-.claro .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
-  background-image: url("../layout/images/tabBottom.png");
-  background-position: top;
+  background-image: url("images/tabBottomUnselected.png");
   background-repeat: repeat-x;
+  background-position: bottom;
+  background-image: -moz-linear-gradient(bottom, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(bottom, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(bottom, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(bottom, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
   -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
   -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
   box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
 }
-/* checked status */
-.claro .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabContent {
-  padding-bottom: 7px;
-  padding-top: 4px;
-  background-position: 0 -119px;
-}
+/* selected tab */
 .claro .dijitTabContainerBottom-tabs .dijitTabChecked {
-  padding-bottom: 0;
-}
-.claro .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv {
-  background-image: none;
+  padding-bottom: 9px;
+  padding-top: 4px;
+  background-image: url("images/tabBottomSelected.png");
+  background-image: -moz-linear-gradient(bottom, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px, #ffffff 7px);
+  background-image: -webkit-linear-gradient(bottom, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px, #ffffff 7px);
+  background-image: -o-linear-gradient(bottom, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px, #ffffff 7px);
+  background-image: linear-gradient(bottom, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0) 2px, #ffffff 7px);
   -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
   -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
   box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
@@ -220,33 +193,29 @@
 /** end bottom tab **/
 /*************** left tab ***************/
 .claro .dijitTabContainerLeft-tabs .dijitTab {
-  border-right-width: 0;
+  /* unselected (and not hovered/pressed) tab */
+
   left: 1px;
   /* used for overlap */
 
   margin-bottom: 1px;
-}
-/* normal status */
-.claro .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
-  background-image: url("../layout/images/tabLeft.png");
-  background-position: -347px -340px;
-  background-repeat: repeat-y;
-}
-.claro .dijitTabContainerLeft-tabs .dijitTabContent {
   padding: 3px 8px 4px 4px;
-  background-image: url("../layout/images/tabLeft.png");
+  background-image: url("images/tabLeftUnselected.png");
   background-repeat: repeat-y;
-  background-position: 0 0;
+  background-image: -moz-linear-gradient(left, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(left, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(left, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(left, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
 }
-/* checked status */
-.claro .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabContent {
+/* selected tab */
+.claro .dijitTabContainerLeft-tabs .dijitTabChecked {
+  border-right-width: 0;
   padding-right: 9px;
-  border-right: none;
-  background-image: none;
-}
-.claro .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv {
-  background-position: 0 -179px;
-  background-repeat: repeat-y;
+  background-image: url("images/tabLeftSelected.png");
+  background-image: -moz-linear-gradient(left, rgba(255, 255, 255, 0.5) 0px, #ffffff 30px);
+  background-image: -webkit-linear-gradient(left, rgba(255, 255, 255, 0.5) 0px, #ffffff 30px);
+  background-image: -o-linear-gradient(left, rgba(255, 255, 255, 0.5) 0px, #ffffff 30px);
+  background-image: linear-gradient(left, rgba(255, 255, 255, 0.5) 0px, #ffffff 30px);
   -webkit-box-shadow: -1px 0 2px rgba(0, 0, 0, 0.05);
   -moz-box-shadow: -1px 0 2px rgba(0, 0, 0, 0.05);
   box-shadow: -1px 0 2px rgba(0, 0, 0, 0.05);
@@ -254,51 +223,50 @@
 /** end left tab **/
 /*************** right tab ***************/
 .claro .dijitTabContainerRight-tabs .dijitTab {
-  border-left-width: 0;
+  /* unselected (and not hovered/pressed) tab */
+
   left: -1px;
   /* used for overlap */
 
   margin-bottom: 1px;
-}
-/* normal status */
-.claro .dijitTabContainerRight-tabs .dijitTabInnerDiv {
-  background-image: url("../layout/images/tabRight.png");
-  background-repeat: repeat-y;
-  background-position: -1px -347px;
-}
-.claro .dijitTabContainerRight-tabs .dijitTabContent {
   padding: 3px 8px 4px 4px;
-  background-image: url("../layout/images/tabRight.png");
-  background-position: right top;
+  background-image: url("images/tabRightUnselected.png");
   background-repeat: repeat-y;
-}
-/* checked status */
-.claro .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabContent {
+  background-position: right;
+  background-image: -moz-linear-gradient(right, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(right, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(right, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(right, #ffffff 0px, #ffffff 1px, rgba(255, 255, 255, 0.1) 2px, rgba(255, 255, 255, 0.6) 7px, rgba(255, 255, 255, 0) 100%);
+}
+.claro .dijitTabContainerRight-tabs .dijitTabChecked {
+  /* selected tab */
+
   padding-left: 5px;
-  border-left: none;
-  background-image: none;
-}
-.claro .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabInnerDiv {
-  background-position: -348px -179px;
+  border-left-width: 0;
+  background-image: url("images/tabRightSelected.png");
+  background-image: -moz-linear-gradient(right, rgba(255, 255, 255, 0.5) 0px, #ffffff 30px);
+  background-image: -webkit-linear-gradient(right, rgba(255, 255, 255, 0.5) 0px, #ffffff 30px);
+  background-image: -o-linear-gradient(right, rgba(255, 255, 255, 0.5) 0px, #ffffff 30px);
+  background-image: linear-gradient(right, rgba(255, 255, 255, 0.5) 0px, #ffffff 30px);
   -webkit-box-shadow: 1px 0 2px rgba(0, 0, 0, 0.07);
   -moz-box-shadow: 1px 0 2px rgba(0, 0, 0, 0.07);
   box-shadow: 1px 0 2px rgba(0, 0, 0, 0.07);
 }
 /** end right tab **/
 /** round corner **/
-.claro .dijitTabContainerTop-tabs .dijitTabInnerDiv, .claro .dijitTabContainerTop-tabs .dijitTabContent {
+.claro .dijitTabContainerTop-tabs .dijitTab {
   -moz-border-radius: 2px 2px 0 0;
   border-radius: 2px 2px 0 0;
 }
-.claro .dijitTabContainerBottom-tabs .dijitTabInnerDiv, .claro .dijitTabContainerBottom-tabs .dijitTabContent {
+.claro .dijitTabContainerBottom-tabs .dijitTab {
   -moz-border-radius: 0 0 2px 2px;
   border-radius: 0 0 2px 2px;
 }
-.claro .dijitTabContainerLeft-tabs .dijitTabInnerDiv, .claro .dijitTabContainerLeft-tabs .dijitTabContent {
+.claro .dijitTabContainerLeft-tabs .dijitTab {
   -moz-border-radius: 2px 0 0 2px;
   border-radius: 2px 0 0 2px;
 }
-.claro .dijitTabContainerRight-tabs .dijitTabInnerDiv, .claro .dijitTabContainerRight-tabs .dijitTabContent {
+.claro .dijitTabContainerRight-tabs .dijitTab {
   -moz-border-radius: 0 2px 2px 0;
   border-radius: 0 2px 2px 0;
 }
@@ -310,15 +278,18 @@
 .claro .dijitTabListContainer-top .tabStripButton {
   padding: 4px 3px;
   margin-top: 7px;
-  background-image: url("../layout/images/tabTop.png");
-  background-position: 0 0;
+  background-image: -moz-linear-gradient(top, #ffffff 0px, rgba(255, 255, 255, 0.1) 1px, rgba(255, 255, 255, 0.6) 6px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(top, #ffffff 0px, rgba(255, 255, 255, 0.1) 1px, rgba(255, 255, 255, 0.6) 6px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(top, #ffffff 0px, rgba(255, 255, 255, 0.1) 1px, rgba(255, 255, 255, 0.6) 6px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(top, #ffffff 0px, rgba(255, 255, 255, 0.1) 1px, rgba(255, 255, 255, 0.6) 6px, rgba(255, 255, 255, 0) 100%);
 }
 .claro .dijitTabListContainer-bottom .tabStripButton {
-  padding: 5px 3px;
-  margin-bottom: 4px;
-  background-image: url("../layout/images/tabTop.png");
-  background-position: 0 -248px;
-  background-position: bottom;
+  padding: 4px 3px;
+  margin-bottom: 7px;
+  background-image: -moz-linear-gradient(bottom, #ffffff 0px, rgba(255, 255, 255, 0.1) 1px, rgba(255, 255, 255, 0.6) 6px, rgba(255, 255, 255, 0) 100%);
+  background-image: -webkit-linear-gradient(bottom, #ffffff 0px, rgba(255, 255, 255, 0.1) 1px, rgba(255, 255, 255, 0.6) 6px, rgba(255, 255, 255, 0) 100%);
+  background-image: -o-linear-gradient(bottom, #ffffff 0px, rgba(255, 255, 255, 0.1) 1px, rgba(255, 255, 255, 0.6) 6px, rgba(255, 255, 255, 0) 100%);
+  background-image: linear-gradient(bottom, #ffffff 0px, rgba(255, 255, 255, 0.1) 1px, rgba(255, 255, 255, 0.6) 6px, rgba(255, 255, 255, 0) 100%);
 }
 .claro .tabStripButtonHover {
   background-color: #abd6ff;
@@ -340,7 +311,8 @@
   background-position: -51px 50%;
 }
 /*disabled styles for tab strip buttons*/
-.claro .dijitTabListContainer-top .tabStripButtonDisabled, .claro .dijitTabListContainer-bottom .tabStripButtonDisabled {
+.claro .dijitTabListContainer-top .tabStripButtonDisabled,
+.claro .dijitTabListContainer-bottom .tabStripButtonDisabled {
   background-color: #d3d3d3;
   border: 1px solid #b5bcc7;
   /* to match border of TabContainer itself */
@@ -361,11 +333,10 @@
 }
 .claro .dijitTabContainerNested .dijitTabContainerTop-tabs {
   border-bottom: solid 1px #b5bcc7;
-  padding: 1px 2px 4px;
-  margin-top: -2px;
+  padding: 2px 2px 4px;
 }
-.claro .dijitTabContainerTabListNested .dijitTabContent {
-  background: rgba(255, 255, 255, 0) none repeat scroll 0 0;
+.claro .dijitTabContainerTabListNested .dijitTab {
+  background-color: rgba(255, 255, 255, 0);
   border: none;
   padding: 4px;
   border-color: rgba(118, 157, 192, 0);
@@ -377,22 +348,19 @@
   transition-duration: 0.3s;
   -moz-border-radius: 2px;
   border-radius: 2px;
-}
-.claro .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv {
-  /* 4 element selector to override box-shadow setting from above rule:
-	 *		.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv { ... }
-	 */
-
-  background: none;
-  border: none;
   top: 0;
   /* to override top: 1px/-1px for normal tabs */
 
   -webkit-box-shadow: none;
   -moz-box-shadow: none;
   box-shadow: none;
+  background-image: url("images/tabNested.png") repeat-x;
+  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.61) 0%, rgba(255, 255, 255, 0) 17%, rgba(255, 255, 255, 0) 83%, rgba(255, 255, 255, 0.61) 100%);
+  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.61) 0%, rgba(255, 255, 255, 0) 17%, rgba(255, 255, 255, 0) 83%, rgba(255, 255, 255, 0.61) 100%);
+  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.61) 0%, rgba(255, 255, 255, 0) 17%, rgba(255, 255, 255, 0) 83%, rgba(255, 255, 255, 0.61) 100%);
+  background-image: linear-gradient(rgba(255, 255, 255, 0.61) 0%, rgba(255, 255, 255, 0) 17%, rgba(255, 255, 255, 0) 83%, rgba(255, 255, 255, 0.61) 100%);
 }
-.claro .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent {
+.claro .dijitTabContainerTabListNested .dijitTabHover {
   background-color: #e5f2fe;
   border: solid 1px #cfe5fa;
   padding: 3px;
@@ -403,18 +371,16 @@
 .claro .dijitTabContainerTabListNested .dijitTabHover .tabLabel {
   text-decoration: none;
 }
-.claro .dijitTabContainerTabListNested .dijitTabActive .dijitTabContent {
+.claro .dijitTabContainerTabListNested .dijitTabActive {
   border: solid 1px #759dc0;
   padding: 3px;
-  background: #abd6ff url("../layout/images/tabNested.png") repeat-x;
   -webkit-transition-duration: 0.1s;
   -moz-transition-duration: 0.1s;
   transition-duration: 0.1s;
 }
-.claro .dijitTabContainerTabListNested .dijitTabChecked .dijitTabContent {
+.claro .dijitTabContainerTabListNested .dijitTabChecked {
   padding: 3px;
   border: solid 1px #759dc0;
-  background-position: 0 105px;
   background-color: #cfe5fa;
 }
 .claro .dijitTabContainerTabListNested .dijitTabChecked .tabLabel {
@@ -426,9 +392,7 @@
   /* prevent double border */
 
 }
-.dj_ie6 .claro .dijitTabContent,
-.dj_ie6 .claro .dijitTabInnerDiv,
-.dj_ie6 .dijitTabListContainer-top .tabStripButton,
-.dj_ie6 .dijitTabListContainer-bottom .tabStripButton {
-  background-image: none;
+.claro .dijitTabContainer .dijitTab,
+.claro .dijitTabContainer .tabStripButton {
+  _background-image: none;
 }
diff --git a/dijit/themes/claro/layout/TabContainer.less b/dijit/themes/claro/layout/TabContainer.less
index 16947ff..daa067d 100644
--- a/dijit/themes/claro/layout/TabContainer.less
+++ b/dijit/themes/claro/layout/TabContainer.less
@@ -17,18 +17,18 @@
  * 		.tabStripButtonDisabled - styles for disabled tab strip buttons
  * 
  * Tab Button:
- * 		.dijitTabContainerTop-tabs .dijitTabInnerDiv/.dijitTabContent     - styles for top tab button container
- * 		.dijitTabContainerBottom-tabs .dijitTabInnerDiv/.dijitTabContent  - styles for bottom tab button container
- * 		.dijitTabContainerLeft-tabs .dijitTabInnerDiv/.dijitTabContent    - styles for left tab button container
- * 		.dijitTabContainerRight-tabs .dijitTabInnerDiv/.dijitTabContent   - styles for right tab button container
+ * 		.dijitTabContainerTop-tabs .dijitTab     - styles for top tab button container
+ * 		.dijitTabContainerBottom-tabs .dijitTab  - styles for bottom tab button container
+ * 		.dijitTabContainerLeft-tabs .dijitTab    - styles for left tab button container
+ * 		.dijitTabContainerRight-tabs .dijitTab   - styles for right tab button container
  * 
- * 		.dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv/.dijitTabContent    
+ * 		.dijitTabContainerTop-tabs .dijitTabChecked .dijitTab
  * 				- styles for selected status of top tab button
  * 		same to Bottom, Left, Right Tabs
  * 
- * 		.dijitTabHover .dijitTabInnerDiv   - styles when mouse hover on tab buttons
- * 		.dijitTabActive .dijitTabInnerDiv  - styles when mouse down on tab buttons
- * 		.dijitTabChecked .dijitTabInnerDiv  - styles when on buttons of selected tab		
+ * 		.dijitTabHover .dijitTab   - styles when mouse hover on tab buttons
+ * 		.dijitTabActive .dijitTab  - styles when mouse down on tab buttons
+ * 		.dijitTabChecked .dijitTab  - styles when on buttons of selected tab
  * 
  * 		.dijitTabCloseButton - the close action buttons lie at the right top of each tab button on closable tabs
  * 		.dijitTabCloseButtonHover - styles when mouse hover on close action button
@@ -49,6 +49,13 @@
 
 @import "../variables";
 
+.unselected-tab-gradient (@direction) {
+    // white line, dark line, then fade from light to dark
+	.alpha-white-gradient (@direction, 1,0px, 1,1px, 0.1,2px, 0.6,7px, 0,100%);
+}
+.topBottom-selected-tab-gradient (@direction) {
+	.alpha-white-gradient (@direction, 1,0px,  1,1px, 0,2px, 1,7px);	// white line, blue line, remainder white
+}
 /*** some common features ***/
 .claro .dijitTabPaneWrapper {
 	background:@pane-background-color;
@@ -78,45 +85,37 @@
 	/* set the spacer invisible.  note that height:0 doesn't work on IE/quirks, it's still 10px. */
 	display: none;
 }
-.claro .dijitTabInnerDiv {
+.claro .dijitTab {
+	border: 1px solid @border-color;
 	background-color:@unselected-background-color;
 	.transition-property(background-color, border);
  	.transition-duration(.35s);
 	color:@unselected-text-color;
 }
-.claro .dijitTabHover .dijitTabInnerDiv {
+.claro .dijitTabHover {
+	border-color: @hovered-border-color;
 	background-color:@hovered-background-color;
  	.transition-duration(.25s);
 	color:@hovered-text-color;
 }
-.claro .dijitTabActive .dijitTabInnerDiv {
+.claro .dijitTabActive {
+	border-color: @pressed-border-color;
 	background-color:@pressed-background-color;
 	color:@selected-text-color;
 	.transition-duration(.1s);
 }
-.claro .dijitTabChecked .dijitTabInnerDiv {
-	background-color:@selected-background-color;
-	color:@selected-text-color;
-}
-
-.claro .dijitTabContent {
-	border: 1px solid @border-color;
-}
-.claro .dijitTabHover .dijitTabContent {
-	border-color: @hovered-border-color;
-}
-.claro .dijitTabActive .dijitTabContent {
-	border-color: @pressed-border-color;
-}
-.claro .dijitTabChecked .dijitTabContent {
-	color:@selected-text-color;			// todo: redundant with .claro .dijitTabChecked .dijitTabInnerDiv above?
+.claro .dijitTabChecked {
+    // selected tab
 	border-color: @border-color;			// don't use @selected-border-color because need to match border of TabContainer
+	background-color: @selected-background-color;
+	color: @selected-text-color;
+}
+.claro .dijitTabDisabled {
+	background-color: @tab-disabled-background-color;
 }
 
-.claro .tabStripButton .dijitTabInnerDiv {
+.claro .tabStripButton {
 	background-color: transparent;
-}
-.claro .tabStripButton .dijitTabContent {
 	border: none;
 }
 /*** end common ***/
@@ -124,169 +123,133 @@
 
 /*************** top tab ***************/
 .claro .dijitTabContainerTop-tabs .dijitTab {
+    /* unselected (and not hovered/pressed) tab */
 	top: 1px;	/* used for overlap */
 	margin-right: 1px;
-	padding-top: 3px;
-}
-.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTab {
-	top: 3px;
-}
-/* for top tab padding. change height when status changes */
-.claro .dijitTabContainerTop-tabs .dijitTabContent {
 	padding:3px 6px;
 	border-bottom-width: 0;
-	background-image:url("../@{image-layout-tab-top}");
-	background-position:0 0;
-	background-repeat:repeat-x;
 	min-width: 60px;
 	text-align: center;
+
+	// gradient (CSS gradient, with backup image for IE6-9)
+	background-image: url("images/tabTopUnselected.png");
+	background-repeat: repeat-x;
+	.unselected-tab-gradient(top);
+
+ 	.box-shadow(0 -1px 1px rgba(0, 0, 0, 0.04));
 }
-.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabContent {
+
+.claro .dijitTabContainerTop-tabs .dijitTabChecked {
+	/* selected tab */
 	padding-bottom: 4px;
-	padding-top: 6px;
-}
+	padding-top: 9px;
 
-/* normal status */
-.claro .dijitTabContainerTop-tabs .dijitTabInnerDiv {
-	background-image:url("../@{image-layout-tab-top}");
-	background-position:0 -248px;
-	background-position:bottom;
-	background-repeat:repeat-x;
-	.box-shadow(0 -1px 1px rgba(0, 0, 0, 0.04));
-}
+	// gradient (CSS gradient, with backup image for IE6-9)
+	background-image: url("images/tabTopSelected.png");
+	.topBottom-selected-tab-gradient (top);
 
-/* checked status */
-.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv {
-	background-image:none;
 	.box-shadow(0 -1px 2px rgba(0, 0, 0, 0.05));
 }
-.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabContent {
-	background-position:0 -102px;
-	background-repeat:repeat-x;
-}
+
 /** end top tab **/
 
 
 /*************** bottom tab ***************/
 .claro .dijitTabContainerBottom-tabs .dijitTab {
+	/* unselected (and not hovered/pressed) tab */
 	top: -1px;	/* used for overlap */
 	margin-right: 1px;
-}
-/* calculate the position and size */
-.claro .dijitTabContainerBottom-tabs .dijitTabContent {
 	padding:3px 6px;
 	border-top-width: 0;
-	background-image: url("../@{image-layout-tab-bottom}");
-	background-position:0 -249px;
-	background-repeat: repeat-x;
-	background-position:bottom;
 	min-width: 60px;
 	text-align: center;
-}
-.claro .dijitTabContainerBottom-tabs .dijitTab {
-	padding-bottom: 3px;
-}
-/* normal status */
-.claro .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
-	background-image: url("../@{image-layout-tab-bottom}");
-	background-position: top;
+
+	// gradient (CSS gradient, with backup image for IE6-9)
+	background-image: url("images/tabBottomUnselected.png");
 	background-repeat: repeat-x;
+	background-position: bottom;
+	.unselected-tab-gradient(bottom);
+
 	.box-shadow(0 1px 1px rgba(0, 0, 0, 0.04));
-	
 }
 
-/* checked status */
-.claro .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabContent {
-	padding-bottom: 7px;
-	padding-top: 4px;
-	background-position:0 -119px;
-}
+/* selected tab */
 .claro .dijitTabContainerBottom-tabs .dijitTabChecked {
-	padding-bottom: 0;
-}
-.claro .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv {
-	background-image:none;
+	padding-bottom: 9px;
+	padding-top: 4px;
+
+	// gradient (CSS gradient, with backup image for IE6-9)
+	background-image: url("images/tabBottomSelected.png");
+	.topBottom-selected-tab-gradient (bottom);
+
 	.box-shadow(0 1px 2px rgba(0, 0, 0, 0.05));
 }
 /** end bottom tab **/
 
 /*************** left tab ***************/
 .claro .dijitTabContainerLeft-tabs .dijitTab {
-	border-right-width: 0;
+	/* unselected (and not hovered/pressed) tab */
 	left: 1px;	/* used for overlap */
 	margin-bottom: 1px;
-}
-/* normal status */
-.claro .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
-	background-image: url("../@{image-layout-tab-left}");
-	background-position: -347px -340px;
-	background-repeat: repeat-y;
-}
-.claro .dijitTabContainerLeft-tabs .dijitTabContent {
 	padding:3px 8px 4px 4px;
-	background-image: url("../@{image-layout-tab-left}");
+
+	// gradient (CSS gradient, with backup image for IE6-9)
+	background-image: url("images/tabLeftUnselected.png");
 	background-repeat: repeat-y;
-	background-position:0 0;
+	.unselected-tab-gradient(left);
 }
-/* checked status */
-.claro .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabContent {
+
+/* selected tab */
+.claro .dijitTabContainerLeft-tabs .dijitTabChecked {
+	border-right-width: 0;
 	padding-right: 9px;
-	border-right: none;
-	background-image: none;
-}
-.claro .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv {
-	background-position:0 -179px;
-	background-repeat:repeat-y;
+
+	// gradient (CSS gradient, with backup image for IE6-9)
+	background-image: url("images/tabLeftSelected.png");
+	.alpha-white-gradient (left, 0.5,0px, 1,30px);  // 1/2 inch blue gradient, remainder white
+
 	.box-shadow(-1px 0 2px rgba(0, 0, 0, .05));
 }
 /** end left tab **/
 
 /*************** right tab ***************/
 .claro .dijitTabContainerRight-tabs .dijitTab {
-	border-left-width: 0;
+	/* unselected (and not hovered/pressed) tab */
 	left: -1px;	/* used for overlap */
 	margin-bottom: 1px;
-}
-/* normal status */
-.claro .dijitTabContainerRight-tabs .dijitTabInnerDiv {
-	background-image: url("../@{image-layout-tab-right}");
-	background-repeat: repeat-y;
-	background-position: -1px -347px;
-}
-.claro .dijitTabContainerRight-tabs .dijitTabContent {
 	padding:3px 8px 4px 4px;
-	background-image: url("../@{image-layout-tab-right}");
-	background-position:right top;
+
+	// gradient (CSS gradient, with backup image for IE6-9)
+	background-image: url("images/tabRightUnselected.png");
 	background-repeat: repeat-y;
+	background-position: right;
+	.unselected-tab-gradient(right);
 }
-/* checked status */
-.claro .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabContent {
+.claro .dijitTabContainerRight-tabs .dijitTabChecked {
+	/* selected tab */
 	padding-left: 5px;
-	border-left: none;
-	background-image: none;
-}
-.claro .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabInnerDiv {
-	background-position:-348px -179px;
+	border-left-width: 0;
+
+	// gradient (CSS gradient, with backup image for IE6-9)
+	background-image: url("images/tabRightSelected.png");
+	.alpha-white-gradient (right, 0.5,0px, 1,30px);	// 1/2 inch blue gradient, remainder white
+
 	.box-shadow(1px 0 2px rgba(0, 0, 0, 0.07));
 }
 /** end right tab **/
 
 /** round corner **/
-.claro .dijitTabContainerTop-tabs .dijitTabInnerDiv,
-.claro .dijitTabContainerTop-tabs .dijitTabContent {
+.claro .dijitTabContainerTop-tabs .dijitTab {
 	.border-radius(2px 2px 0 0);
 }
-.claro .dijitTabContainerBottom-tabs .dijitTabInnerDiv,
-.claro .dijitTabContainerBottom-tabs .dijitTabContent{
+.claro .dijitTabContainerBottom-tabs .dijitTab {
 	.border-radius(0 0 2px 2px);
 }
-.claro .dijitTabContainerLeft-tabs .dijitTabInnerDiv,
-.claro .dijitTabContainerLeft-tabs .dijitTabContent{
+.claro .dijitTabContainerLeft-tabs .dijitTab {
 	.border-radius(2px 0 0 2px);
 }
 
-.claro .dijitTabContainerRight-tabs .dijitTabInnerDiv,
-.claro .dijitTabContainerRight-tabs .dijitTabContent{
+.claro .dijitTabContainerRight-tabs .dijitTab {
 	.border-radius(0 2px 2px 0);
 }
 
@@ -298,15 +261,12 @@
 .claro .dijitTabListContainer-top .tabStripButton {
 	padding: 4px 3px;
 	margin-top:7px;
-	background-image: url("../@{image-layout-tab-top}");
-	background-position:0 0;
+	.alpha-white-gradient (top, 1,0px, 0.1,1px, 0.6,6px, 0,100%);	// to match unselected tab, but had to tweak numbers
 }
 .claro .dijitTabListContainer-bottom .tabStripButton {
-	padding:5px 3px;
-	margin-bottom:4px;
-	background-image: url("../@{image-layout-tab-top}");
-	background-position:0 -248px;
-	background-position:bottom;
+	padding:4px 3px;
+	margin-bottom:7px;
+	.alpha-white-gradient (bottom, 1,0px, 0.1,1px, 0.6,6px, 0,100%);	// to match unselected tab, but had to tweak numbers
 }
 .claro .tabStripButtonHover {
 	background-color:@hovered-background-color;
@@ -349,46 +309,40 @@
 }
 .claro .dijitTabContainerNested .dijitTabContainerTop-tabs {
 	border-bottom:solid 1px @border-color;
-	padding:1px 2px 4px;
-	margin-top:-2px;
+	padding:2px 2px 4px;
 }
-.claro .dijitTabContainerTabListNested .dijitTabContent {
-	background:rgba(255, 255, 255, 0) none repeat scroll 0 0;
+.claro .dijitTabContainerTabListNested .dijitTab {
+	background-color:rgba(255, 255, 255, 0);
 	border: none;
 	padding: 4px;
 	border-color: rgba(118,157,192,0);
 	.transition-property(background-color, border-color);
  	.transition-duration(.3s);
 	.border-radius(2px);
-}
-.claro .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv {
-	/* 4 element selector to override box-shadow setting from above rule:
-	 *		.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv { ... }
-	 */
-	background: none;
-	border: none;
 	top: 0;/* to override top: 1px/-1px for normal tabs */
 	.box-shadow(none);
+
+	// CSS gradient with fallback to image for IE
+	background-image: url("images/tabNested.png") repeat-x;
+	.alpha-white-gradient (0.61,0%, 0,17%, 0,83%, 0.61,100%);
 }
-.claro .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent {
+.claro .dijitTabContainerTabListNested .dijitTabHover {
 	background-color: @nestedtab-hovered-background-color;
 	border:solid 1px @nestedtab-hovered-border-color;
-	padding: 3px;
+	padding: 3px;	// 4px above padding - 1px compensation for border
 	.transition-duration(.2s);
 }
 .claro .dijitTabContainerTabListNested .dijitTabHover .tabLabel {
 	text-decoration: none;
 }
-.claro .dijitTabContainerTabListNested .dijitTabActive .dijitTabContent {
+.claro .dijitTabContainerTabListNested .dijitTabActive {
 	border:solid 1px @nestedtab-selected-border-color;
 	padding: 3px;
-	background: @nestedtab-selected-background-color url("../@{image-layout-tab-nested}") repeat-x;
 	.transition-duration(.1s);
 }
-.claro .dijitTabContainerTabListNested .dijitTabChecked .dijitTabContent {
+.claro .dijitTabContainerTabListNested .dijitTabChecked {
 	padding: 3px;
 	border:solid 1px @selected-border-color;
-	background-position: 0 105px;
 	background-color:@selected-background-color;
 }
 .claro .dijitTabContainerTabListNested .dijitTabChecked .tabLabel {
@@ -399,10 +353,8 @@
 	border: none;/* prevent double border */
 }
 
-
-.dj_ie6 .claro .dijitTabContent,
-.dj_ie6 .claro .dijitTabInnerDiv,
-.dj_ie6 .dijitTabListContainer-top .tabStripButton,
-.dj_ie6 .dijitTabListContainer-bottom .tabStripButton{
-	background-image: none;
+.claro .dijitTabContainer .dijitTab,
+.claro .dijitTabContainer .tabStripButton {
+    // IE6 can't handle background-image and background-color on same node
+	_background-image: none;
 }
diff --git a/dijit/themes/claro/layout/TabContainer_rtl.css b/dijit/themes/claro/layout/TabContainer_rtl.css
index 89fdff0..130dc13 100644
--- a/dijit/themes/claro/layout/TabContainer_rtl.css
+++ b/dijit/themes/claro/layout/TabContainer_rtl.css
@@ -1,67 +1,5 @@
-.claro .dijitTabContainerTop-tabs .dijitTabRtl, .claro .dijitTabContainerBottom-tabs .dijitTabRtl {
+.claro .dijitTabContainerTop-tabs .dijitTabRtl,
+.claro .dijitTabContainerBottom-tabs .dijitTabRtl {
   margin-right: 0;
   margin-left: 1px;
 }
-.claro .dijitTabRtl {
-  -moz-box-orient: horizontal;
-  text-align: right;
-}
-.dj_ie7 .claro .dijitTabRtl .dijitTabContent {
-  display: block;
-  left: 0;
-}
-.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabRtl, .dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabCheckedRtl {
-  top: 1px;
-}
-.dj_ie7 .claro .tabStripButtonRtl .dijitButtonContents,
-.dj_ie8 .claro .tabStripButtonRtl .dijitButtonContents,
-.dj_ie6 .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_ie6 .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_ie7 .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_iequirks .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_iequirks .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv {
-  float: left;
-}
-.dj_ie6 .claro .dijitTabRtl .tabLabel,
-.dj_ie6 .claro .dijitTabContainerRight-tabs .dijitTabRtl,
-.dj_ie6 .claro .dijitTabContainerLeft-tabs .dijitTabRtl,
-.dj_ie7 .claro .dijitTabContainerRight-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_ie7 .claro .dijitTabContainerLeft-tabs .dijitTabRtl .dijitTabInnerDiv {
-  /*Make the .tablabel have width in ie6 with haslayout property, fix Close icon position bug*/
-
-  zoom: 1;
-}
-.dj_ie6 .claro .dijitTabRtl .dijitTabCloseButton, .dj_ie7 .claro .dijitTabRtl .dijitTabCloseButton, .dj_iequirks .claro .dijitTabRtl .dijitTabCloseButton {
-  margin-right: 5px;
-}
-.dj_ie6 .claro .dijitTabContainerRightRtl .dijitTabContainerRight-tabs, .dj_ie6 .claro .dijitTabContainerLeftRtl .dijitTabContainerLeft-tabs {
-  width: 1%;
-}
-.dj_ie6 .dijitTabContainerTopStrip, .dj_ie6 .dijitTabContainerBottomStrip {
-  position: absolute;
-}
-.dj_iequirks .claro .dijitTabContainerTopRtl .dijitTabContainerTopStrip {
-  padding-top: 10px;
-}
-.dj_ie7 .claro .dijitTabContainerRight-tabs .dijitTabRtlChecked .dijitTabInnerDiv {
-  background-position: -341px -179px;
-}
-.dj_ie6 .dijitTabContainerTopRtl .dijitTabStripIcon, .dj_ie6 .dijitTabContainerBottomRtl .dijitTabStripIcon {
-  position: relative;
-}
-.dj_ie6-rtl .claro .dijitTabContainerTop-tabs {
-  /* this strange rule prevents IE6 bug in themeTester.html?dir=rtl upon closing
-	 * "Closable" tab, where the other tabs disappear
-	 */
-
-  padding-left: 3px;
-}
-.dj_iequirks-rtl .claro .dijitTabListWrapper {
-  /* this strange rule prevents IE6 bug in themeTesterQuirk.html?dir=rtl upon closing
-	 * "Closable" tab, where the other tabs disappear
-	 */
-
-  border-left: 1px solid #ffffff;
-  border-right: 1px solid #ffffff;
-}
diff --git a/dijit/themes/claro/layout/TabContainer_rtl.less b/dijit/themes/claro/layout/TabContainer_rtl.less
index eaada0d..c6cec49 100644
--- a/dijit/themes/claro/layout/TabContainer_rtl.less
+++ b/dijit/themes/claro/layout/TabContainer_rtl.less
@@ -5,77 +5,3 @@
 	margin-right: 0;
 	margin-left: 1px;
 }
-.claro .dijitTabRtl {
-	-moz-box-orient:horizontal;
-	text-align: right;
-}
-.dj_ie7 .claro .dijitTabRtl .dijitTabContent {
-	display: block;
-	left: 0;
-}
-.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabRtl,
-.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabCheckedRtl {
-	top: 1px;
-}
-
-// Note that .tabStripButtonRtl .dijitButtonContents needed for IE8 quirks but breaks IE6 quirks
-.dj_ie7 .claro .tabStripButtonRtl .dijitButtonContents,
-.dj_ie8 .claro .tabStripButtonRtl .dijitButtonContents,
-.dj_ie6 .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_ie6 .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_ie7 .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_iequirks .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_iequirks .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv {
-	float:left;
-}
-.dj_ie6 .claro .dijitTabRtl .tabLabel,
-.dj_ie6 .claro .dijitTabContainerRight-tabs .dijitTabRtl,
-.dj_ie6 .claro .dijitTabContainerLeft-tabs .dijitTabRtl,
-.dj_ie7 .claro .dijitTabContainerRight-tabs .dijitTabRtl .dijitTabInnerDiv,
-.dj_ie7 .claro .dijitTabContainerLeft-tabs .dijitTabRtl .dijitTabInnerDiv {
-	/*Make the .tablabel have width in ie6 with haslayout property, fix Close icon position bug*/
-	zoom:1;
-}
-.dj_ie6 .claro .dijitTabRtl .dijitTabCloseButton,
-.dj_ie7 .claro .dijitTabRtl .dijitTabCloseButton,
-.dj_iequirks .claro .dijitTabRtl .dijitTabCloseButton {
-	margin-right:5px;
-}
-
-.dj_ie6 .claro .dijitTabContainerRightRtl .dijitTabContainerRight-tabs,
-.dj_ie6 .claro .dijitTabContainerLeftRtl .dijitTabContainerLeft-tabs {
-	width:1%;
-}
-
-.dj_ie6 .dijitTabContainerTopStrip,
-.dj_ie6 .dijitTabContainerBottomStrip {
-	position:absolute;
-}
-.dj_iequirks .claro .dijitTabContainerTopRtl .dijitTabContainerTopStrip {
-	padding-top: 10px;
-}
-.dj_ie7 .claro .dijitTabContainerRight-tabs .dijitTabRtlChecked .dijitTabInnerDiv {
-	background-position:-341px -179px;
-}
-
-.dj_ie6 .dijitTabContainerTopRtl .dijitTabStripIcon,
-.dj_ie6 .dijitTabContainerBottomRtl .dijitTabStripIcon {
-   position: relative;
-}
-
-
-.dj_ie6-rtl .claro .dijitTabContainerTop-tabs {	
-	/* this strange rule prevents IE6 bug in themeTester.html?dir=rtl upon closing
-	 * "Closable" tab, where the other tabs disappear
-	 */
-	padding-left: 3px;
-}
-
-.dj_iequirks-rtl .claro .dijitTabListWrapper {
-	/* this strange rule prevents IE6 bug in themeTesterQuirk.html?dir=rtl upon closing
-	 * "Closable" tab, where the other tabs disappear
-	 */
-	border-left: 1px solid @pane-background-color;
-	border-right: 1px solid @pane-background-color;
-}
diff --git a/dijit/themes/claro/layout/images/accordion.png b/dijit/themes/claro/layout/images/accordion.png
deleted file mode 100644
index 4818103..0000000
Binary files a/dijit/themes/claro/layout/images/accordion.png and /dev/null differ
diff --git a/dijit/themes/claro/layout/images/splitterHorizontalHover.png b/dijit/themes/claro/layout/images/splitterHorizontalHover.png
deleted file mode 100644
index 0f5b691..0000000
Binary files a/dijit/themes/claro/layout/images/splitterHorizontalHover.png and /dev/null differ
diff --git a/dijit/themes/claro/layout/images/splitterVerticalHover.png b/dijit/themes/claro/layout/images/splitterVerticalHover.png
deleted file mode 100644
index 2c3c696..0000000
Binary files a/dijit/themes/claro/layout/images/splitterVerticalHover.png and /dev/null differ
diff --git a/dijit/themes/claro/layout/images/tabBottom.png b/dijit/themes/claro/layout/images/tabBottom.png
deleted file mode 100644
index dbcfc85..0000000
Binary files a/dijit/themes/claro/layout/images/tabBottom.png and /dev/null differ
diff --git a/dijit/themes/claro/layout/images/tabBottomSelected.png b/dijit/themes/claro/layout/images/tabBottomSelected.png
new file mode 100644
index 0000000..f92b05f
Binary files /dev/null and b/dijit/themes/claro/layout/images/tabBottomSelected.png differ
diff --git a/dijit/themes/claro/layout/images/tabBottomSelected.svg b/dijit/themes/claro/layout/images/tabBottomSelected.svg
new file mode 100644
index 0000000..4e6ff6d
--- /dev/null
+++ b/dijit/themes/claro/layout/images/tabBottomSelected.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for tabBottomSelected.png, which is used by IE7-9 for selected tabs.
+	Compile to png with batik, gimp, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match CSS gradient from .topBottom-selected-tab-gradient() from TabContainer.less.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="1px" height="250px" viewBox="0 0 1 250" preserveAspectRatio="none">
+	<defs>
+		<linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="0%" y2="100%">
+			<stop offset="0%" stop-color="#ffffff" stop-opacity="1"/>
+			<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
+		</linearGradient>
+	</defs>
+	<rect x="0" y="0" width="1" height="242" fill="white"/>
+	<rect x="0" y="242" width="1" height="6" fill="url(#gradient)"/>
+	<rect x="0" y="248" width="1" height="2" fill="white"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/layout/images/tabBottomUnselected.png b/dijit/themes/claro/layout/images/tabBottomUnselected.png
new file mode 100644
index 0000000..7815d9c
Binary files /dev/null and b/dijit/themes/claro/layout/images/tabBottomUnselected.png differ
diff --git a/dijit/themes/claro/layout/images/tabBottomUnselected.svg b/dijit/themes/claro/layout/images/tabBottomUnselected.svg
new file mode 100644
index 0000000..4193238
--- /dev/null
+++ b/dijit/themes/claro/layout/images/tabBottomUnselected.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for tabBottomUnselected.png, which is used by IE7-9 for the selected tabs.
+	Compile to png with batik, gimp, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match CSS gradient from TabContainer.less.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="1px" height="16px" viewBox="0 0 1 16" preserveAspectRatio="none">
+	<defs>
+		<linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="0%" y1="100%" x2="0%" y2="0%">
+			<stop offset="0%" stop-color="#ffffff" stop-opacity="1"/>
+			<stop offset="6%" stop-color="#ffffff" stop-opacity="1"/>
+			<stop offset="13%" stop-color="#ffffff" stop-opacity="0.2"/>
+			<stop offset="43%" stop-color="#ffffff" stop-opacity="0.6"/>
+			<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
+		</linearGradient>
+	</defs>
+	<rect x="0" y="0" width="1" height="16" fill="url(#gradient)"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/layout/images/tabLeft.png b/dijit/themes/claro/layout/images/tabLeft.png
deleted file mode 100644
index 8e9fcba..0000000
Binary files a/dijit/themes/claro/layout/images/tabLeft.png and /dev/null differ
diff --git a/dijit/themes/claro/layout/images/tabLeftSelected.png b/dijit/themes/claro/layout/images/tabLeftSelected.png
new file mode 100644
index 0000000..9700afb
Binary files /dev/null and b/dijit/themes/claro/layout/images/tabLeftSelected.png differ
diff --git a/dijit/themes/claro/layout/images/tabLeftSelected.svg b/dijit/themes/claro/layout/images/tabLeftSelected.svg
new file mode 100644
index 0000000..12e7d8a
--- /dev/null
+++ b/dijit/themes/claro/layout/images/tabLeftSelected.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for tabLeftSelected.png, which is used by IE7-9 for selected tabs.
+	Compile to png with batik, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match CSS gradient from TabContainer.less.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="1000px" height="1px" viewBox="0 0 1000 1" preserveAspectRatio="none">
+	<defs>
+		<linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="100%" y2="0%">
+			<stop offset="0%" stop-color="#ffffff" stop-opacity="0.5"/>
+			<stop offset="100%" stop-color="#ffffff" stop-opacity="1"/>
+		</linearGradient>
+	</defs>
+	<rect x="0" y="0" width="30" height="1" fill="url(#gradient)"/>
+	<rect x="30" y="0" width="970" height="1" fill="white"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/layout/images/tabLeftUnselected.png b/dijit/themes/claro/layout/images/tabLeftUnselected.png
new file mode 100644
index 0000000..412390e
Binary files /dev/null and b/dijit/themes/claro/layout/images/tabLeftUnselected.png differ
diff --git a/dijit/themes/claro/layout/images/tabLeftUnselected.svg b/dijit/themes/claro/layout/images/tabLeftUnselected.svg
new file mode 100644
index 0000000..e31c211
--- /dev/null
+++ b/dijit/themes/claro/layout/images/tabLeftUnselected.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for tabLeftUnselected.png, which is used by IE7-9 for the selected tabs.
+	Compile to png with batik, gimp, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match CSS gradient from TabContainer.less.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="150px" height="1px" viewBox="0 0 100 1" preserveAspectRatio="none">
+	<defs>
+		<linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="100%" y2="0%">
+			<stop offset="0%" stop-color="#ffffff" stop-opacity="0.5"/>
+			<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
+		</linearGradient>
+	</defs>
+	<rect x="0" y="0" width="150" height="1" fill="url(#gradient)"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/layout/images/tabRight.png b/dijit/themes/claro/layout/images/tabRight.png
deleted file mode 100644
index 0aaae53..0000000
Binary files a/dijit/themes/claro/layout/images/tabRight.png and /dev/null differ
diff --git a/dijit/themes/claro/layout/images/tabRightSelected.png b/dijit/themes/claro/layout/images/tabRightSelected.png
new file mode 100644
index 0000000..1a28434
Binary files /dev/null and b/dijit/themes/claro/layout/images/tabRightSelected.png differ
diff --git a/dijit/themes/claro/layout/images/tabRightSelected.svg b/dijit/themes/claro/layout/images/tabRightSelected.svg
new file mode 100644
index 0000000..d8d3d67
--- /dev/null
+++ b/dijit/themes/claro/layout/images/tabRightSelected.svg
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for tabRightSelected.png, which is used by IE7-9 for selected tabs.
+	Compile to png with batik, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match CSS gradient from TabContainer.less.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="1000px" height="1px" viewBox="0 0 1000 1" preserveAspectRatio="none">
+	<defs>
+		<linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="100%" y1="0%" x2="0%" y2="0%">
+			<stop offset="0%" stop-color="#ffffff" stop-opacity="0.5"/>
+			<stop offset="100%" stop-color="#ffffff" stop-opacity="1"/>
+		</linearGradient>
+	</defs>
+	<rect x="0" y="0" width="970" height="1" fill="white"/>
+	<rect x="970" y="0" width="30" height="1" fill="url(#gradient)"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/layout/images/tabRightUnselected.png b/dijit/themes/claro/layout/images/tabRightUnselected.png
new file mode 100644
index 0000000..2bdd00e
Binary files /dev/null and b/dijit/themes/claro/layout/images/tabRightUnselected.png differ
diff --git a/dijit/themes/claro/layout/images/tabRightUnselected.svg b/dijit/themes/claro/layout/images/tabRightUnselected.svg
new file mode 100644
index 0000000..d1379a7
--- /dev/null
+++ b/dijit/themes/claro/layout/images/tabRightUnselected.svg
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for tabRightUnselected.png, which is used by IE7-9 for the selected tabs.
+	Compile to png with batik, gimp, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match CSS gradient from TabContainer.less.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="150px" height="1px" viewBox="0 0 100 1" preserveAspectRatio="none">
+	<defs>
+		<linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="100%" y1="0%" x2="0%" y2="0%">
+			<stop offset="0%" stop-color="#ffffff" stop-opacity="0.5"/>
+			<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
+		</linearGradient>
+	</defs>
+	<rect x="0" y="0" width="150" height="1" fill="url(#gradient)"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/layout/images/tabTop.png b/dijit/themes/claro/layout/images/tabTop.png
deleted file mode 100644
index 2822487..0000000
Binary files a/dijit/themes/claro/layout/images/tabTop.png and /dev/null differ
diff --git a/dijit/themes/claro/layout/images/tabTopSelected.png b/dijit/themes/claro/layout/images/tabTopSelected.png
new file mode 100644
index 0000000..f4d5772
Binary files /dev/null and b/dijit/themes/claro/layout/images/tabTopSelected.png differ
diff --git a/dijit/themes/claro/layout/images/tabTopSelected.svg b/dijit/themes/claro/layout/images/tabTopSelected.svg
new file mode 100644
index 0000000..d06e646
--- /dev/null
+++ b/dijit/themes/claro/layout/images/tabTopSelected.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for tabTopSelected.png, which is used by IE7-9 for the selected tabs.
+	Compile to png with batik, gimp, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match CSS gradient from .topBottom-selected-tab-gradient() from TabContainer.less.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="1px" height="250px" viewBox="0 0 1 250" preserveAspectRatio="none">
+	<defs>
+		<linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="0%" y2="100%">
+			<stop offset="0%" stop-color="#ffffff" stop-opacity="0"/>
+			<stop offset="100%" stop-color="#ffffff" stop-opacity="1"/>
+		</linearGradient>
+	</defs>
+	<rect x="0" y="0" width="1" height="2" fill="white"/>
+	<rect x="0" y="2" width="1" height="6" fill="url(#gradient)"/>
+	<rect x="0" y="8" width="1" height="242" fill="white"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/layout/images/tabTopUnselected.png b/dijit/themes/claro/layout/images/tabTopUnselected.png
new file mode 100644
index 0000000..8c34545
Binary files /dev/null and b/dijit/themes/claro/layout/images/tabTopUnselected.png differ
diff --git a/dijit/themes/claro/layout/images/tabTopUnselected.svg b/dijit/themes/claro/layout/images/tabTopUnselected.svg
new file mode 100644
index 0000000..c55e925
--- /dev/null
+++ b/dijit/themes/claro/layout/images/tabTopUnselected.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>
+<!--
+	Source file for tabTopUnSelected.png, which is used by IE7-9 for the selected tabs.
+	Compile to png with batik, gimp, or online tool ex: http://www.fileformat.info/convert/image/svg2raster.htm
+
+	Output should match CSS gradient from TabContainer.less.
+-->
+<svg xmlns="http://www.w3.org/2000/svg" width="1px" height="16px" viewBox="0 0 1 16" preserveAspectRatio="none">
+	<defs>
+		<linearGradient id="gradient" gradientUnits="objectBoundingBox" x1="0%" y1="0%" x2="0%" y2="100%">
+			<stop offset="0%" stop-color="#ffffff" stop-opacity="1"/>
+			<stop offset="6%" stop-color="#ffffff" stop-opacity="1"/>
+			<stop offset="13%" stop-color="#ffffff" stop-opacity="0.2"/>
+			<stop offset="43%" stop-color="#ffffff" stop-opacity="0.6"/>
+			<stop offset="100%" stop-color="#ffffff" stop-opacity="0"/>
+		</linearGradient>
+	</defs>
+	<rect x="0" y="0" width="1" height="16" fill="url(#gradient)"/>
+</svg>
\ No newline at end of file
diff --git a/dijit/themes/claro/variables.less b/dijit/themes/claro/variables.less
index ca7d677..ac21a5f 100644
--- a/dijit/themes/claro/variables.less
+++ b/dijit/themes/claro/variables.less
@@ -6,7 +6,7 @@
 @disabled-color: #d3d3d3;												// Base for disabled backgrounds and borders
 @error-color: #d46464;
 
- at container-background-color:#fff;										// Backgrounds for various content areas such as TitlePane, ContentPane and Inputs
+ at container-background-color:#fff;										// Backgrounds for various content areas such as TitlePane, ContentPane and Inputs (if changed, adjust selected tab to match)
 
 @minor-selected-color: spin(saturate(darken(@primary-color, 6), 19), 0);						// Color for various arrows and buttons
 @base-border-color: spin(desaturate(darken(@primary-color, 29), 44), -1);		// Augmented and used directly by variables to create border colors for various widgets
@@ -136,6 +136,9 @@
 @dialog-titlebar-border-color: @container-background-color;	// Inner border around the title sectionof a Dialog, inside the main border of the Dialog and the border between title and content
 @dialog-titlebar-background-color: @minor-selected-color;
 
+// Tooltip
+ at tooltip-gradient-color: fade(@primary-color,10%);		// a little swath of color at the bottom of tooltips
+
 // BorderContainer
 @splitter-hovered-background-color: @primary-color;	// Color of splitter when user hovers it, before mouse down
 @splitter-dragged-background-color: @minor-selected-color;	// Color of splitter while it's being dragged
@@ -156,49 +159,29 @@
 @document-shadedsection-background-color: @bar-background-color;// background color used for <pre>, <code>, and table header rows
 @document-border-color: @disabled-color;								// Border for <pre>, <code>, tables, etc.
 
-// Images
+// Icons, arrows, etc.
 @image-arrow-sprite: "images/spriteArrows.png";
- at image-calendar-container: "images/calendarContainerImages.png";
 @image-calendar-arrows: "images/calendarArrows.png";
 @image-calendar-arrows-ie6: "images/calendarArrows8bit.png";
 @image-checkmark: "images/checkmarkNoBorder.png";
 @image-checkmark-ie6: "images/checkmarkNoBorder.gif";
- at image-common-highlight: "images/commonHighlight.png";
 @image-dialog-close: "images/dialogCloseIcon.png";
 @image-dialog-close-ie6: "images/dialogCloseIcon8bit.png";
 @image-dnd: "images/dnd.png";
 @image-editor-icons-enabled: "../../icons/images/editorIconsEnabled.png";
- at image-form-button: "form/images/button.png";
 @image-form-button-arrows: "form/images/buttonArrows.png";
 @image-form-checkbox-and-radios: "form/images/checkboxRadioButtonStates.png";
 @image-form-checkbox-and-radios-ie6: "form/images/checkboxAndRadioButtons_IE6.png";
 @image-form-common-arrows: "form/images/commonFormArrows.png";
 @image-form-error: "form/images/error.png";
- at image-form-highlight: "form/images/formHighlight.png";
- at image-form-slider-horizontal: "form/images/sliderHorizontal.png";
 @image-form-slider-thumbs: "form/images/sliderThumbs.png";
- at image-form-slider-vertical: "form/images/sliderVertical.png";
- at image-form-textbox-background: "form/images/textBox_back.png";
- at image-layout-accordion: "layout/images/accordion.png";
- at image-layout-splitter-horizontal-hover: "layout/images/splitterHorizontalHover.png";
- at image-layout-splitter-vertical-hover: "layout/images/splitterVerticalHover.png";
- at image-layout-tab-bottom: "layout/images/tabBottom.png";
- at image-layout-tab-close: "layout/images/tabClose.png";
- at image-layout-tab-left: "layout/images/tabLeft.png";
- at image-layout-tab-nested: "layout/images/tabNested.png";
- at image-layout-tab-right: "layout/images/tabRight.png";
- at image-layout-tab-top: "layout/images/tabTop.png";
+ at image-layout-tab-close: "layout/images/tabClose.png";	// [x] icon to close a tab
 @image-loading-animation: "images/loadingAnimation.gif";
- at image-menu-highlight: "images/menuHighlight.png";
- at image-progressbar-empty: "images/progressBarEmpty.png";
- at image-progressbar-full: "images/progressBarFull.png";
- at image-progressbar-anim: "images/progressBarAnim.gif";
- at image-titlebar: "images/titlebar.png";
- at image-tooltip: "images/tooltip.png";
- at image-tooltip-ie6: "images/tooltip8bit.png";
- at image-tooltip-gradient: "images/tooltipGradient.png";
+ at image-tooltip: "images/tooltip.png";	// arrow connectors
+ at image-tooltip-ie6: "images/tooltip8bit.png";	// arrow connectors (8 bit)
 @image-tree-expand: "images/treeExpandImages.png";
 @image-tree-expand-ie6: "images/treeExpandImages8bit.png";
+ at image-progressbar-anim: "images/progressBarAnim.gif";
 
 // Mixins
 
@@ -242,3 +225,154 @@
 	-moz-transition-timing-function: @value;
 	transition-timing-function: @value;
 }
+
+.linear-gradient (@value1, @value2) {
+	// summary:
+	//		Expands to browser specific background-image specifications for a linear-gradient (2 stops)
+ 	background-image: -moz-linear-gradient(@value1, @value2); // FF3.6 - FF15 (FF16+ supports linear-gradient)
+ 	background-image: -webkit-linear-gradient(@value1, @value2); // Chrome10+, Safari5.1+
+ 	background-image: -o-linear-gradient(@value1, @value2); // Opera 11.10+
+ 	background-image: linear-gradient(@value1, @value2);
+}
+.linear-gradient (@value1, @value2, @value3) {
+ 	background-image: -moz-linear-gradient(@value1, @value2, @value3); // FF3.6 - FF15 (FF16+ supports linear-gradient)
+ 	background-image: -webkit-linear-gradient(@value1, @value2, @value3); // Chrome10+, Safari5.1+
+ 	background-image: -o-linear-gradient(@value1, @value2, @value3); // Opera 11.10+
+ 	background-image: linear-gradient(@value1, @value2, @value3);
+}
+.linear-gradient (@value1, @value2, @value3, @value4) {
+ 	background-image: -moz-linear-gradient(@value1, @value2, @value3, @value4); // FF3.6 - FF15 (FF16+ supports linear-gradient)
+ 	background-image: -webkit-linear-gradient(@value1, @value2, @value3, @value4); // Chrome10+, Safari5.1+
+ 	background-image: -o-linear-gradient(@value1, @value2, @value3, @value4); // Opera 11.10+
+ 	background-image: linear-gradient(@value1, @value2, @value3, @value4);
+}
+.linear-gradient (@value1, @value2, @value3, @value4, @value5) {
+ 	background-image: -moz-linear-gradient(@value1, @value2, @value3, @value4, @value5); // FF3.6 - FF15 (FF16+ supports linear-gradient)
+ 	background-image: -webkit-linear-gradient(@value1, @value2, @value3, @value4, @value5); // Chrome10+, Safari5.1+
+ 	background-image: -o-linear-gradient(@value1, @value2, @value3, @value4, @value5); // Opera 11.10+
+ 	background-image: linear-gradient(@value1, @value2, @value3, @value4, @value5);
+}
+.linear-gradient (@value1, @value2, @value3, @value4, @value5, @value6) {
+ 	background-image: -moz-linear-gradient(@value1, @value2, @value3, @value4, @value5, @value6); // FF3.6 - FF15 (FF16+ supports linear-gradient)
+ 	background-image: -webkit-linear-gradient(@value1, @value2, @value3, @value4, @value5, @value6); // Chrome10+, Safari5.1+
+ 	background-image: -o-linear-gradient(@value1, @value2, @value3, @value4, @value5, @value6); // Opera 11.10+
+ 	background-image: linear-gradient(@value1, @value2, @value3, @value4, @value5, @value6);
+}
+.linear-gradient (@value1, @value2, @value3, @value4, @value5, @value6, @value7) {
+ 	background-image: -moz-linear-gradient(@value1, @value2, @value3, @value4, @value5, @value6, @value7); // FF3.6 - FF15 (FF16+ supports linear-gradient)
+ 	background-image: -webkit-linear-gradient(@value1, @value2, @value3, @value4, @value5, @value6, @value7); // Chrome10+, Safari5.1+
+ 	background-image: -o-linear-gradient(@value1, @value2, @value3, @value4, @value5, @value6, @value7); // Opera 11.10+
+ 	background-image: linear-gradient(@value1, @value2, @value3, @value4, @value5, @value6, @value7);
+}
+
+.alpha-white-gradient (@opacity1, @stop1, @opacity2, @stop2) {
+	// summary:
+	//		For setting up white background-image with variable transparency.
+	// example:
+	//		Gradient starts at top (0%) with 30% opacity, and then ends at bottom (100%) with full transparency
+	//		|	.alpha-white-gradient(0.3, 0%, 0, 100%)
+	//
+	.linear-gradient(rgba(255,255,255, at opacity1) @stop1, rgba(255,255,255, at opacity2) @stop2);
+}
+.alpha-white-gradient (@start, @opacity1, @stop1, @opacity2, @stop2) {
+	.linear-gradient(@start, rgba(255,255,255, at opacity1) @stop1, rgba(255,255,255, at opacity2) @stop2);
+}
+.alpha-white-gradient (@opacity1, @stop1, @opacity2, @stop2, @opacity3, @stop3) {
+	.linear-gradient(rgba(255,255,255, at opacity1) @stop1, rgba(255,255,255, at opacity2) @stop2, rgba(255,255,255, @opacity3) @stop3);
+}
+.alpha-white-gradient (@start, @opacity1, @stop1, @opacity2, @stop2, @opacity3, @stop3) {
+	.linear-gradient(@start, rgba(255,255,255, at opacity1) @stop1, rgba(255,255,255, at opacity2) @stop2, rgba(255,255,255, @opacity3) @stop3);
+}
+.alpha-white-gradient (@opacity1, @stop1, @opacity2, @stop2, @opacity3, @stop3, @opacity4, @stop4) {
+	.linear-gradient(rgba(255,255,255, at opacity1) @stop1, rgba(255,255,255, at opacity2) @stop2, rgba(255,255,255, @opacity3) @stop3, rgba(255,255,255, @opacity4) @stop4);
+}
+.alpha-white-gradient (@start, @opacity1, @stop1, @opacity2, @stop2, @opacity3, @stop3, @opacity4, @stop4) {
+	.linear-gradient(@start, rgba(255,255,255, at opacity1) @stop1, rgba(255,255,255, at opacity2) @stop2, rgba(255,255,255, @opacity3) @stop3, rgba(255,255,255, @opacity4) @stop4);
+}
+.alpha-white-gradient (@start, @opacity1, @stop1, @opacity2, @stop2, @opacity3, @stop3, @opacity4, @stop4, @opacity5, @stop5) {
+	.linear-gradient(@start, rgba(255,255,255, at opacity1) @stop1, rgba(255,255,255, at opacity2) @stop2, rgba(255,255,255, @opacity3) @stop3, rgba(255,255,255, @opacity4) @stop4, rgba(255,255,255, @opacity5) @stop5);
+}
+.alpha-white-gradient (@start, @opacity1, @stop1, @opacity2, @stop2, @opacity3, @stop3, @opacity4, @stop4, @opacity5, @stop5, @opacity6, @stop6) {
+	.linear-gradient(@start, rgba(255,255,255, at opacity1) @stop1, rgba(255,255,255, at opacity2) @stop2, rgba(255,255,255, @opacity3) @stop3, rgba(255,255,255, @opacity4) @stop4, rgba(255,255,255, @opacity5) @stop5, rgba(255,255,255, @opacity6) @stop6);
+}
+
+.gradient-and-filter (@color, @fade1, @fade2) {
+	// summary:
+	//		Sets up a background color with a vertical gradient.
+	//		In order to make transitions work properly on mozilla and webkit, this is done by combining
+	//		a background-color which will be changed based on state (ex: hover) with a constant
+	//		white alpha-transparency background-image.  On IE it creates a DXImageTransform filter.
+	// @color:
+	//		The color
+	// @fade1:
+	//		The percent to fade at the top
+	// @fade2:
+	//		The percent to fade at the bottom
+	background-color: @color; // the base color
+	.linear-gradient(fadeout(#fff, 100- at fade1), fadeout(#fff, 100- at fade2));
+	filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorstr="lighten(@color, @fade1)~", endColorstr="lighten(@color, @fade2)~")"; // IE
+}
+.horizontal-gradient-and-filter (@color, @fade1, @fade2) {
+	// summary:
+	//		Sets up a background color with a horizontal gradient.
+	//		In order to make transitions work properly on mozilla and webkit, this is done by combining
+	//		a background-color which will be changed based on state (ex: hover) with a constant
+	//		white alpha-transparency background-image.  On IE it creates a DXImageTransform filter.
+	// @color:
+	//		The color
+	// @fade1:
+	//		The percent to fade at the top
+	// @fade2:
+	//		The percent to fade at the bottom
+	background-color: @color; // the base color
+	.linear-gradient(left, fadeout(#fff, 100- at fade1), fadeout(#fff, 100- at fade2));
+	filter: ~"progid:DXImageTransform.Microsoft.gradient(startColorstr="lighten(@color, @fade1)~", endColorstr="lighten(@color, @fade2)~"gradientType=1)"; // IE
+}
+
+
+// Mixins defining gradients
+
+.textbox-background-image () {
+	// summary:
+	//		Background image used for hovered TextBoxes and similar controls.
+	//		It's just a small inset shadow below the top border (inside of the TextBox).
+	.linear-gradient(rgba(127,127,127,0.2) 0%, rgba(127,127,127,0) 2px);
+}
+
+.standard-gradient (@pathToRoot: "") {
+	// summary:
+	//		Light to dark background-image used by widgets with short height (~16px) including:
+	//			- MenuBar, and hovered MenuItem/MenuBarItem
+	//			- arrow icon wrapper for Select, ComboBox, Spinner
+	//			- Toolbar and hovered Toolbar buttons
+	//			- TitlePane title bar, AccordionContainer title bar, Dialog title bar
+
+	// Fallback for IE
+	background-image: url("@{pathToRoot}images/standardGradient.png");
+	background-repeat: repeat-x;
+
+	// CSS gradient for other browsers
+	.alpha-white-gradient(0.7, 0%, 0, 100%);
+
+	// IE6 can't handle a background-image with transparency and a background-color; the color is blocked out
+	_background-image: none;
+}
+.active-gradient (@pathToRoot: "") {
+	// summary:
+	//		Light to dark background-image with an inset gray shadow at the top,
+	//		used by widgets when they are active (ie: mousedown) or selected, including:
+	//			- active MenuItem/MenuBarItem
+	//			- arrow icon wrapper for Select, ComboBox, Spinner when active or drop down is open
+	//			- active Toolbar buttons
+	//			- active TitlePane title bar, AccordionContainer title bar
+
+	// Fallback for IE
+	background-image: url("@{pathToRoot}images/activeGradient.png");
+	background-repeat: repeat-x;
+
+	// CSS gradient for other browsers
+	.linear-gradient(rgba(190,190,190,0.98) 0px, rgba(255, 255, 255, 0.65) 3px, rgba(255, 255, 255, 0) 100%);
+
+	// IE6 can't handle a background-image with transparency and a background-color; the color is blocked out
+	_background-image: none;
+}
diff --git a/dijit/themes/dijit.css b/dijit/themes/dijit.css
index 4c60bf3..996ec0f 100644
--- a/dijit/themes/dijit.css
+++ b/dijit/themes/dijit.css
@@ -17,11 +17,11 @@
 	margin:0;
 	border:0;
 	padding:0;
-	line-height:normal;
 	font: inherit;
+	line-height:normal;
 	color: inherit;
 }
-.dijit_a11y .dijitReset {
+.dj_a11y .dijitReset {
 	-moz-appearance: none; /* remove predefined high-contrast styling in Firefox */
 }
 
@@ -56,32 +56,46 @@ table.dijitInline {
 	position: relative;			/* to support setting width/height, see #2033 */
 }
 
+.dj_ie6 .dijitComboBox .dijitInputContainer,
 .dijitInputContainer {
 	/* for positioning of placeHolder */
 	#zoom: 1;
 	overflow: hidden;
-	float: none !important; /* needed by FF to squeeze the INPUT in */
+	float: none !important; /* needed to squeeze the INPUT in */
 	position: relative;
-	vertical-align: middle;
-	#display: inline;
+}
+.dj_ie7 .dijitInputContainer {
+	float: left !important; /* needed by IE to squeeze the INPUT in */
+	clear: left;
+	display: inline-block !important; /* to fix wrong text alignment in textdir=rtl text box */
 }
 
+.dj_ie .dijitSelect input,
 .dj_ie input.dijitTextBox,
 .dj_ie .dijitTextBox input {
 	font-size: 100%;
 }
+.dijitSelect .dijitButtonText {
+	float: left;
+	vertical-align: top;
+}
+TABLE.dijitSelect {
+	padding: 0 !important; /* messes up border alignment */
+	border-collapse: separate; /* so jsfiddle works with Normalized CSS checked */
+}
 .dijitTextBox .dijitSpinnerButtonContainer,
 .dijitTextBox .dijitArrowButtonContainer,
-.dijitTextBox .dijitValidationContainer {
+.dijitValidationTextBox .dijitValidationContainer {
 	float: right;
 	text-align: center;
 }
+.dijitSelect input.dijitInputField,
 .dijitTextBox input.dijitInputField {
 	/* override unreasonable user styling of buttons and icons */
 	padding-left: 0 !important;
 	padding-right: 0 !important;
 }
-.dijitTextBox .dijitValidationContainer {
+.dijitValidationTextBox .dijitValidationContainer {
 	display: none;
 }
 
@@ -90,10 +104,10 @@ table.dijitInline {
 	line-height:1px;
 }
 
-.dijitOffScreen {
-	position: absolute;
-	left: 50%;
-	top: -10000px;
+.dijitOffScreen { /* these class attributes should supercede any inline positioning style */
+	position: absolute !important;
+	left: -10000px !important;
+	top: -10000px !important;
 }
 
 /*
@@ -106,6 +120,7 @@ table.dijitInline {
 	margin: 0;
 	border: 0;
 	padding: 0;
+	-webkit-overflow-scrolling: touch;
 }
 
 .dijitPositionOnly {
@@ -152,12 +167,12 @@ table.dijitInline {
 /****
 		A11Y
  ****/
-.dijit_a11y .dijitIcon,
-.dijit_a11y div.dijitArrowButtonInner, /* is this only for Spinner?  if so, it should be deleted */
-.dijit_a11y span.dijitArrowButtonInner,
-.dijit_a11y img.dijitArrowButtonInner,
-.dijit_a11y .dijitCalendarIncrementControl,
-.dijit_a11y .dijitTreeExpando {
+.dj_a11y .dijitIcon,
+.dj_a11y div.dijitArrowButtonInner, /* is this only for Spinner?  if so, it should be deleted */
+.dj_a11y span.dijitArrowButtonInner,
+.dj_a11y img.dijitArrowButtonInner,
+.dj_a11y .dijitCalendarIncrementControl,
+.dj_a11y .dijitTreeExpando {
 	/* hide icon nodes in high contrast mode; when necessary they will be replaced by character equivalents
 	 * exception for input.dijitArrowButtonInner, because the icon and character are controlled by the same node */
 	display: none;
@@ -166,7 +181,7 @@ table.dijitInline {
 	display: block; /* override previous rule */
 }
 
-.dijit_a11y .dijitA11ySideArrow {
+.dj_a11y .dijitA11ySideArrow {
 	display: inline !important; /* display text instead */
 	cursor: pointer;
 }
@@ -177,20 +192,20 @@ table.dijitInline {
  * Avoid screen jitter when switching selected date by compensating for the selected node's
  * border w/padding on other nodes.
  */
-.dijit_a11y .dijitCalendarDateLabel {
+.dj_a11y .dijitCalendarDateLabel {
 	padding: 1px;
 	border: 0px !important;
 }
-.dijit_a11y .dijitCalendarSelectedDate .dijitCalendarDateLabel {
+.dj_a11y .dijitCalendarSelectedDate .dijitCalendarDateLabel {
 	border-style: solid !important;
 	border-width: 1px !important;
 	padding: 0;
 }
-.dijit_a11y .dijitCalendarDateTemplate {
+.dj_a11y .dijitCalendarDateTemplate {
 	padding-bottom: 0.1em !important;	/* otherwise bottom border doesn't appear on IE */
 	border: 0px !important;
 }
-.dijit_a11y .dijitButtonNode {
+.dj_a11y .dijitButtonNode {
 	border: black outset medium !important;
 
 	/* In claro, hovering a toolbar button reduces padding and adds a border.
@@ -198,13 +213,16 @@ table.dijitInline {
 	 */
 	padding: 0 !important;
 }
+.dj_a11y .dijitArrowButton {
+	padding: 0 !important;
+}
 
-.dijit_a11y .dijitButtonContents{
+.dj_a11y .dijitButtonContents {
 	margin: 0.15em; /* Margin needed to make focus outline visible */
 }
 
-.dijit_a11y .dijitTextBoxReadOnly .dijitInputField,
-.dijit_a11y .dijitTextBoxReadOnly .dijitButtonNode {
+.dj_a11y .dijitTextBoxReadOnly .dijitInputField,
+.dj_a11y .dijitTextBoxReadOnly .dijitButtonNode {
 	border-style: outset!important;
 	border-width: medium!important;
 	border-color: #999 !important;
@@ -215,6 +233,7 @@ table.dijitInline {
 .dijitButtonNode * {
 	vertical-align: middle;
 }
+.dijitSelect .dijitArrowButtonInner,
 .dijitButtonNode .dijitArrowButtonInner {
 	/* the arrow icon node */
 	background: no-repeat center;
@@ -248,7 +267,7 @@ table.dijitInline {
 }
 
 /* Buttons */
-.dj_gecko .dijit_a11y .dijitButtonDisabled .dijitButtonNode {
+.dj_gecko .dj_a11y .dijitButtonDisabled .dijitButtonNode {
 	opacity: 0.5;
 }
 
@@ -299,6 +318,9 @@ td.dijitButtonContents {
 	padding:0;
 }
 
+.dijitSelect {
+	border:1px solid gray;
+}
 .dijitButtonNode {
 	/* Node that is acting as a button -- may or may not be a BUTTON element */
 	border:1px solid gray;
@@ -318,9 +340,12 @@ td.dijitButtonContents {
 	border-width: 0;
 }
 
+.dijitSelect,
+.dijitSelect *,
 .dijitButtonNode,
 .dijitButtonNode * {
 	cursor: pointer;
+	-webkit-tap-highlight-color: transparent;
 }
 
 .dj_ie .dijitButtonNode {
@@ -356,11 +381,11 @@ div.dijitArrowButton {
 .dijitTextBoxDisabled {
 	color: gray;
 }
-.dj_webkit .dijitTextBoxDisabled input {
-	color: #eee; /* because WebKit lightens disabled input/textarea no matter what color you specify */
+.dj_safari .dijitTextBoxDisabled input {
+	color: #B0B0B0; /* because Safari lightens disabled input/textarea no matter what color you specify */
 }
-.dj_webkit textarea.dijitTextAreaDisabled {
-	color: #333; /* because WebKit lightens disabled input/textarea no matter what color you specify */
+.dj_safari textarea.dijitTextAreaDisabled {
+	color: #333; /* because Safari lightens disabled input/textarea no matter what color you specify */
 }
 .dj_gecko .dijitTextBoxReadOnly input.dijitInputField, /* disable arrow and validation presentation inputs but allow real input for text selection */
 .dj_gecko .dijitTextBoxDisabled input {
@@ -389,13 +414,17 @@ div.dijitArrowButton {
 	outline: 5px -webkit-focus-ring-color;
 }
 
+.dijitSelect input,
 .dijitTextBox input {
 	float: left; /* needed by IE to remove secret margin */
 }
+.dj_ie6 input.dijitTextBox,
+.dj_ie6 .dijitTextBox input {
+	float: none;
+}
 .dijitInputInner {
 	/* for when an <input> is embedded inside an inline-block <div> with a size and border */
 	border:0 !important;
-	vertical-align:middle !important;
 	background-color:transparent !important;
 	width:100% !important;
 	/* IE dislikes horizontal tweaking combined with width:100% so punish everyone for consistency */
@@ -404,15 +433,16 @@ div.dijitArrowButton {
 	margin-left: 0 !important;
 	margin-right: 0 !important;
 }
-.dijit_a11y .dijitTextBox input {
+.dj_a11y .dijitTextBox input {
 	margin: 0 !important;
 }
-.dijitTextBoxError input.dijitValidationInner,
+.dijitValidationTextBoxError input.dijitValidationInner,
+.dijitSelect input,
 .dijitTextBox input.dijitArrowButtonInner {
 	/* <input> used to display arrow icon/validation icon, or in arrow character in high contrast mode.
 	 * The css below is a trick to hide the character in non-high-contrast mode
 	 */
-	text-indent: -1em !important;
+	text-indent: -2em !important;
 	direction: ltr !important;
 	text-align: left !important;
 	height: auto !important;
@@ -420,15 +450,26 @@ div.dijitArrowButton {
 	#letter-spacing: -5em !important;
 	#text-align: right !important;
 }
+.dj_ie .dijitSelect input,
 .dj_ie .dijitTextBox input,
 .dj_ie input.dijitTextBox {
 	overflow-y: visible; /* inputs need help expanding when padding is added or line-height is adjusted */
 	line-height: normal; /* strict mode */
 }
-.dj_ie7 .dijitTextBox input.dijitValidationInner,
-.dj_ie7 .dijitTextBox input.dijitArrowButtonInner {
-	line-height: 86%; /* IE7 problem where the icon is vertically too low w/o this - real input stays at normal */
+.dijitSelect .dijitSelectLabel span {
+	line-height: 100%;
 }
+.dj_ie .dijitSelect .dijitSelectLabel {
+	line-height: normal;
+}
+.dj_ie6 .dijitSelect .dijitSelectLabel,
+.dj_ie7 .dijitSelect .dijitSelectLabel,
+.dj_ie8 .dijitSelect .dijitSelectLabel,
+.dj_iequirks .dijitSelect .dijitSelectLabel,
+.dijitSelect td,
+.dj_ie6 .dijitSelect input,
+.dj_iequirks .dijitSelect input,
+.dj_ie6 .dijitSelect .dijitValidationContainer,
 .dj_ie6 .dijitTextBox input,
 .dj_ie6 input.dijitTextBox,
 .dj_iequirks .dijitTextBox input.dijitValidationInner,
@@ -438,14 +479,15 @@ div.dijitArrowButton {
 .dj_iequirks input.dijitTextBox {
 	line-height: 100%; /* IE7 problem where the icon is vertically way too low w/o this */
 }
-.dijit_a11y input.dijitValidationInner,
-.dijit_a11y input.dijitArrowButtonInner {
+.dj_a11y input.dijitValidationInner,
+.dj_a11y input.dijitArrowButtonInner {
 	/* (in high contrast mode) revert rules from above so character displays */
 	text-indent: 0 !important;
 	width: 1em !important;
 	#text-align: left !important;
+	color: black !important;
 }
-.dijitTextBoxError .dijitValidationContainer {
+.dijitValidationTextBoxError .dijitValidationContainer {
 	display: inline;
 	cursor: default;
 }
@@ -457,6 +499,7 @@ div.dijitArrowButton {
 	/* dividing line between input area and up/down button(s) for ComboBox and Spinner */
 	border-width: 0 0 0 1px !important; /* !important needed due to wayward ".theme .dijitButtonNode" rules */
 }
+.dj_a11y .dijitSelect .dijitArrowButtonContainer,
 .dijitToolbar .dijitComboBox .dijitArrowButtonContainer {
 	/* overrides above rule plus mirror-image rule in dijit_rtl.css to have no divider when ComboBox in Toolbar */
 	border-width: 0 !important;
@@ -470,7 +513,7 @@ div.dijitArrowButton {
 	/* dividing line between input area and up/down button(s) for ComboBox and Spinner */
 	border-width: 0;
 }
-.dj_ie .dijit_a11y .dijitSpinner .dijitSpinnerButtonContainer .dijitButtonNode {
+.dj_ie .dj_a11y .dijitSpinner .dijitSpinnerButtonContainer .dijitButtonNode {
 	clear: both; /* IE workaround */
 }
 
@@ -495,35 +538,36 @@ div.dijitArrowButton {
 .dijitSpinnerButtonContainer .dijitButtonNode {
 	border-width: 0;
 }
-.dijit_a11y .dijitSpinnerButtonContainer .dijitButtonNode {
-	border: 0 none !important;
+.dj_a11y .dijitSpinnerButtonContainer .dijitButtonNode {
+	border-width: 0px !important;
+	border-style: solid !important;
 }
-.dijit_a11y .dijitTextBox .dijitSpinnerButtonContainer,
-.dijit_a11y .dijitSpinner .dijitArrowButtonInner,
-.dijit_a11y .dijitSpinnerButtonContainer input {
+.dj_a11y .dijitTextBox .dijitSpinnerButtonContainer,
+.dj_a11y .dijitSpinner .dijitArrowButtonInner,
+.dj_a11y .dijitSpinnerButtonContainer input {
 	width: 1em !important;
 }
-.dijit_a11y .dijitSpinner .dijitArrowButtonInner {
+.dj_a11y .dijitSpinner .dijitArrowButtonInner {
 	margin: 0 auto !important; /* should auto-center */
 }
-.dj_ie .dijit_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
+.dj_ie .dj_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
 	padding-left: 0.3em !important;
 	padding-right: 0.3em !important;
 	margin-left: 0.3em !important;
 	margin-right: 0.3em !important;
 	width: 1.4em !important;
 }
-.dj_ie7 .dijit_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
+.dj_ie7 .dj_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
 	padding-left: 0 !important; /* manually center INPUT: character is .5em and total width = 1em */
 	padding-right: 0 !important;
 	width: 1em !important;
 }
-.dj_ie6 .dijit_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
+.dj_ie6 .dj_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
 	margin-left: 0.1em !important;
 	margin-right: 0.1em !important;
 	width: 1em !important;
 }
-.dj_iequirks .dijit_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
+.dj_iequirks .dj_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
 	margin-left: 0 !important;
 	margin-right: 0 !important;
 	width: 2em !important;
@@ -545,7 +589,7 @@ div.dijitArrowButton {
 .dj_iequirks .dijitSpinner .dijitSpinnerButtonContainer .dijitArrowButton {
 	width: auto;
 }
-.dijit_a11y .dijitSpinnerButtonContainer .dijitArrowButton {
+.dj_a11y .dijitSpinnerButtonContainer .dijitArrowButton {
 	overflow: visible !important;
 }
 .dijitSpinner .dijitSpinnerButtonContainer .dijitDownArrowButton {
@@ -578,6 +622,7 @@ div.dijitArrowButton {
 	padding-left: 0 !important;
 	padding-right: 0 !important;
 	width: 100%;
+	visibility: hidden;
 }
 .dj_ie .dijitSpinner .dijitArrowButtonInner .dijitInputField {
 	zoom: 50%; /* emulate transform: scale(0.5) */
@@ -586,26 +631,19 @@ div.dijitArrowButton {
 	overflow: hidden;
 }
 
-.dijit_a11y .dijitSpinner .dijitSpinnerButtonContainer .dijitArrowButton {
+.dj_a11y .dijitSpinner .dijitSpinnerButtonContainer .dijitArrowButton {
 	width: 100%;
 }
-.dj_iequirks .dijit_a11y .dijitSpinner .dijitSpinnerButtonContainer .dijitArrowButton {
-	width: 1em; /* matches .dijit_a11y .dijitTextBox .dijitSpinnerButtonContainer rule - 100% is the whole screen width in quirks */
-}
-.dijitSpinner .dijitArrowButtonInner .dijitInputField {
-	visibility: hidden;
+.dj_iequirks .dj_a11y .dijitSpinner .dijitSpinnerButtonContainer .dijitArrowButton {
+	width: 1em; /* matches .dj_a11y .dijitTextBox .dijitSpinnerButtonContainer rule - 100% is the whole screen width in quirks */
 }
-.dijit_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
+.dj_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
 	vertical-align:top;
 	visibility: visible;
 }
-.dijit_a11y .dijitSpinnerButtonContainer {
+.dj_a11y .dijitSpinnerButtonContainer {
 	width: 1em;
 }
-.dijit_a11y .dijitSpinnerButtonContainer .dijitButtonNode {
-	border-width: 1px 0 0 0;
-	border-style: solid !important;
-}
 
 /****
 		dijit.form.CheckBox
@@ -641,20 +679,20 @@ div.dijitArrowButton {
 	filter: alpha(opacity=0);
 }
 
-.dijit_a11y .dijitCheckBox,
-.dijit_a11y .dijitRadio {
+.dj_a11y .dijitCheckBox,
+.dj_a11y .dijitRadio {
 	/* in a11y mode we display the native checkbox (not the icon), so don't restrict the size */
 	width: auto !important;
 	height: auto !important;
 }
-.dijit_a11y .dijitCheckBoxInput {
+.dj_a11y .dijitCheckBoxInput {
 	opacity: 1;
 	filter: none;
 	width: auto;
 	height: auto;
 }
 
-.dijit_a11y .dijitFocusedLabel {
+.dj_a11y .dijitFocusedLabel {
 	/* for checkboxes or radio buttons in high contrast mode, use border rather than outline to indicate focus (outline does not work in FF)*/
 	border: 1px dotted;
 	outline: 0px !important;
@@ -664,6 +702,9 @@ div.dijitArrowButton {
 		dijit.ProgressBar
  ****/
 
+.dijitProgressBar {
+    z-index: 0; /* so z-index settings below have no effect outside of the ProgressBar */
+}
 .dijitProgressBarEmpty {
 	/* outer container and background of the bar that's not finished yet*/
 	position:relative;overflow:hidden;
@@ -699,7 +740,7 @@ div.dijitArrowButton {
 	background-attachment: fixed;
 }
 
-.dijit_a11y .dijitProgressBarTile {
+.dj_a11y .dijitProgressBarTile {
 	/* a11y:  The border provides visibility in high-contrast mode */
 	border-width:2px;
 	border-style:solid;
@@ -721,7 +762,7 @@ div.dijitArrowButton {
 	display:none;
 }
 
-.dijit_a11y .dijitProgressBarIndeterminate .dijitProgressBarIndeterminateHighContrastImage {
+.dj_a11y .dijitProgressBarIndeterminate .dijitProgressBarIndeterminateHighContrastImage {
 	display:block;
 	position:absolute;
 	top:0;
@@ -768,7 +809,7 @@ div.dijitArrowButton {
 .dijitTooltipConnector {
 	position: absolute;
 }
-.dijit_a11y .dijitTooltipConnector {
+.dj_a11y .dijitTooltipConnector {
 	display: none;	/* won't show b/c it's background-image; hide to avoid border gap */
 }
 
@@ -804,6 +845,7 @@ body .dijitAlignClient { position: absolute; }
 .dijitBorderContainer, .dijitBorderContainerNoGutter {
 	position:relative;
 	overflow: hidden;
+    z-index: 0; /* so z-index settings below have no effect outside of the BorderContainer */
 }
 
 .dijitBorderContainerPane,
@@ -863,6 +905,11 @@ body .dijitAlignClient { position: absolute; }
 /* #6945: stop mouse events */
 .dj_ie .dijitSplitterCover {
 	background: white;
+	opacity: 0;
+}
+.dj_ie6 .dijitSplitterCover,
+.dj_ie7 .dijitSplitterCover,
+.dj_ie8 .dijitSplitterCover {
 	filter: alpha(opacity=0);
 }
 
@@ -871,22 +918,20 @@ body .dijitAlignClient { position: absolute; }
 	border-top:1px;
 	border-bottom:1px;
 	cursor: row-resize;
+	-webkit-tap-highlight-color: transparent;
 }
 .dijitSplitterV {
 	width: 7px;
 	border-left:1px;
 	border-right:1px;
 	cursor: col-resize;
+	-webkit-tap-highlight-color: transparent;
 }
 .dijitSplitContainer {
 	position: relative;
 	overflow: hidden;
 	display: block;
 }
-.dj_ff3 .dijit_a11y div.dijitSplitter:focus {
-	outline-style:dotted;
-	outline-width: 2px;
-}
 
 .dijitSplitPane {
 	position: absolute;
@@ -932,11 +977,11 @@ body .dijitAlignClient { position: absolute; }
 	cursor: row-resize;
 }
 
-.dijit_a11y .dijitSplitterH {
+.dj_a11y .dijitSplitterH {
 	border-top:1px solid #d3d3d3 !important;
 	border-bottom:1px solid #d3d3d3 !important;
 }
-.dijit_a11y .dijitSplitterV {
+.dj_a11y .dijitSplitterV {
 	border-left:1px solid #d3d3d3 !important;
 	border-right:1px solid #d3d3d3 !important;
 }
@@ -946,6 +991,7 @@ body .dijitAlignClient { position: absolute; }
 .dijitContentPane {
 	display: block;
 	overflow: auto;	/* if we don't have this (or overflow:hidden), then Widget.resizeTo() doesn't make sense for ContentPane */
+	-webkit-overflow-scrolling: touch;
 }
 
 .dijitContentPaneSingleChild {
@@ -961,33 +1007,43 @@ body .dijitAlignClient { position: absolute; }
 	margin-right: 9px;
 }
 
-/* TitlePane */
+/* TitlePane and Fieldset */
 
 .dijitTitlePane {
 	display: block;
 	overflow: hidden;
 }
-.dijitTitlePaneTitle {
+.dijitFieldset {
+	border: 1px solid gray;
+}
+.dijitTitlePaneTitle, .dijitFieldset legend {
 	cursor: pointer;
+	-webkit-tap-highlight-color: transparent;
 }
 .dijitFixedOpen, .dijitFixedClosed {
 	/* TitlePane that cannot be toggled */
 	cursor: default;
 }
+.dijitFixedOpen .dijitArrowNode, .dijitFixedOpen .dijitArrowNodeInner,
+.dijitFixedClosed .dijitArrowNode, .dijitFixedClosed .dijitArrowNodeInner{
+	/* don't show the open close icon, it makes the user think the pane is closable*/
+	display: none;
+}
+
 .dijitTitlePaneTitle * {
 	vertical-align: middle;
 }
-.dijitTitlePane .dijitArrowNodeInner {
+.dijitTitlePane .dijitArrowNodeInner, .dijitFieldset .dijitArrowNodeInner {
 	/* normally, hide arrow text in favor of icon */
 	display: none;
 }
-.dijit_a11y .dijitTitlePane .dijitArrowNodeInner {
+.dj_a11y .dijitTitlePane .dijitArrowNodeInner, .dj_a11y .dijitFieldset .dijitArrowNodeInner {
 	/* ... except in a11y mode, then show text arrow */
 	display:inline !important;
 	font-family: monospace;		/* because - and + are different widths */
 }
-.dijit_a11y .dijitTitlePane .dijitArrowNode {
-	/* ... and hide icon */
+.dj_a11y .dijitTitlePane .dijitArrowNode, .dj_a11y .dijitFieldset .dijitArrowNode {
+	/* ... and hide icon (TODO: just point dijitIcon class on the icon, and it hides automatically) */
 	display:none;
 }
 
@@ -1066,8 +1122,8 @@ body .dijitAlignClient { position: absolute; }
 }
 
 
-.dijit_a11y .dijitColorPalette .dijitPaletteTable,
-.dijit_a11y .dijitColorPalette .dijitPaletteTable * {
+.dj_a11y .dijitColorPalette .dijitPaletteTable,
+.dj_a11y .dijitColorPalette .dijitPaletteTable * {
 	/* table cells are to catch events, but the swatches are in the PaletteImg behind the table */
 	background-color: transparent !important;
 }
@@ -1080,6 +1136,7 @@ body .dijitAlignClient { position: absolute; }
 }
 .dijitAccordionTitle {
 	cursor: pointer;
+	-webkit-tap-highlight-color: transparent;
 }
 .dijitAccordionTitleSelected {
 	cursor: default;
@@ -1093,12 +1150,12 @@ body .dijitAlignClient { position: absolute; }
 	font-weight: normal !important;
 }
 
-.dijit_a11y .dijitAccordionTitle .arrowTextUp,
-.dijit_a11y .dijitAccordionTitleSelected .arrowTextDown {
+.dj_a11y .dijitAccordionTitle .arrowTextUp,
+.dj_a11y .dijitAccordionTitleSelected .arrowTextDown {
 	display: inline;
 }
 
-.dijit_a11y .dijitAccordionTitleSelected .arrowTextUp {
+.dj_a11y .dijitAccordionTitleSelected .arrowTextUp {
 	display: none;
 }
 
@@ -1139,6 +1196,7 @@ body .dijitAlignClient { position: absolute; }
 .dijitCalendarPreviousYear,
 .dijitCalendarNextYear {
 	cursor: pointer;
+	-webkit-tap-highlight-color: transparent;
 }
 
 .dijitCalendarDisabledDate {
@@ -1183,6 +1241,16 @@ body .dijitAlignClient { position: absolute; }
 	white-space: nowrap;
 	padding:.1em .2em;
 	cursor:pointer;
+	-webkit-tap-highlight-color: transparent;
+}
+
+/*
+No need to show a focus border since it's obvious from the shading, and there's a .dj_a11y .dijitMenuItemSelected
+rule below that handles the high contrast case when there's no shading.
+Hiding the focus border also works around webkit bug https://code.google.com/p/chromium/issues/detail?id=125779.
+*/
+.dijitMenuItem:focus {
+	outline: none
 }
 
 .dijitMenuPassive .dijitMenuItemHover,
@@ -1207,11 +1275,10 @@ body .dijitAlignClient { position: absolute; }
 	opacity:0.5;
 	cursor:default;
 }
-.dj_ie .dijit_a11y .dijitMenuItemDisabled,
-.dj_ie .dijit_a11y .dijitMenuItemDisabled td,
-.dj_ie .dijitMenuItemDisabled *,
-.dj_ie .dijitMenuItemDisabled td {
-	color:gray !important;
+.dj_ie .dj_a11y .dijitMenuItemDisabled,
+.dj_ie .dj_a11y .dijitMenuItemDisabled *,
+.dj_ie .dijitMenuItemDisabled * {
+	color: gray;
 	filter: alpha(opacity=35);
 }
 
@@ -1220,25 +1287,22 @@ body .dijitAlignClient { position: absolute; }
 	vertical-align: middle;
 }
 
-.dijit_a11y .dijitMenuItemSelected {
-	border: 1px dotted black !important;
-}
-.dj_ff3 .dijit_a11y .dijitMenuItem td {
-	padding: 0 !important;
-	background:none !important;
+.dj_a11y .dijitMenuItemSelected {
+	border: 1px dotted black !important;	/* for 2.0 use outline instead, to prevent jitter */
 }
-.dijit_a11y .dijitMenuItemSelected .dijitMenuItemLabel {
+
+.dj_a11y .dijitMenuItemSelected .dijitMenuItemLabel {
 	border-width: 1px;
 	border-style: solid;
 }
-.dj_ie8 .dijit_a11y .dijitMenuItemLabel {
+.dj_ie8 .dj_a11y .dijitMenuItemLabel {
 	position:static;
 }
 
 .dijitMenuExpandA11y {
 	display: none;
 }
-.dijit_a11y .dijitMenuExpandA11y {
+.dj_a11y .dijitMenuExpandA11y {
 	display: inline;
 }
 
@@ -1262,21 +1326,19 @@ body .dijitAlignClient { position: absolute; }
 	font-size: 1px;
 }
 
-/* the checked menu item */
-.dijitCheckedMenuItemIconChar {
-	vertical-align: middle;
-	visibility:hidden;
-}
-.dijitCheckedMenuItemChecked .dijitCheckedMenuItemIconChar {
-	visibility: visible;
+/* CheckedMenuItem and RadioMenuItem */
+.dijitMenuItemIconChar {
+	display: none;		/* don't display except in high contrast mode */
+	visibility: hidden;	/* for high contrast mode when menuitem is unchecked: leave space for when it is checked */
 }
-.dijit_a11y .dijitCheckedMenuItemIconChar {
-	display:inline !important;
+.dj_a11y .dijitMenuItemIconChar {
+	display: inline;	/* display character in high contrast mode, since icon doesn't show */
 }
-.dijit_a11y .dijitCheckedMenuItemIcon {
-	display: none;
+.dijitCheckedMenuItemChecked .dijitMenuItemIconChar,
+.dijitRadioMenuItemChecked .dijitMenuItemIconChar {
+	visibility: visible; /* menuitem is checked */
 }
-.dj_ie .dijit_a11y .dijitMenuBar .dijitMenuItem {
+.dj_ie .dj_a11y .dijitMenuBar .dijitMenuItem {
 	/* so bottom border of MenuBar appears on IE7 in high-contrast mode */
 	margin: 0;
 }
@@ -1287,8 +1349,27 @@ body .dijitAlignClient { position: absolute; }
 	cursor: default;	/* because pressing it has no effect */
 }
 
-/* TabContainer */
+/***
+TabContainer
+
+Main class hierarchy:
+
+.dijitTabContainer - the whole TabContainer
+   .dijitTabController / .dijitTabListContainer-top - wrapper for tab buttons, scroll buttons
+	 .dijitTabListWrapper / .dijitTabContainerTopStrip - outer wrapper for tab buttons (normal width)
+		.nowrapTabStrip / .dijitTabContainerTop-tabs - inner wrapper for tab buttons (50K width)
+   .dijitTabPaneWrapper - wrapper for content panes, has all borders except the one between content and tabs
+***/
 
+.dijitTabContainer {
+    z-index: 0; /* so z-index settings below have no effect outside of the TabContainer */
+    overflow: visible; /* prevent off-by-one-pixel errors from hiding bottom border (opposite tab labels) */
+}
+.dj_ie6 .dijitTabContainer {
+    /* workaround IE6 problem when tall content overflows TabContainer, see editor/test_FullScreen.html */
+   overflow: hidden;
+
+}
 .dijitTabContainerNoLayout {
 	width: 100%;	/* otherwise ScrollingTabController goes to 50K pixels wide */
 }
@@ -1297,9 +1378,13 @@ body .dijitAlignClient { position: absolute; }
 .dijitTabContainerTop-tabs,
 .dijitTabContainerLeft-tabs,
 .dijitTabContainerRight-tabs {
+    z-index: 1;
 	overflow: visible !important;  /* so tabs can cover up border adjacent to container */
 }
 
+.dijitTabController {
+    z-index: 1;
+}
 .dijitTabContainerBottom-container,
 .dijitTabContainerTop-container,
 .dijitTabContainerLeft-container,
@@ -1313,12 +1398,14 @@ body .dijitAlignClient { position: absolute; }
 	display: block;
 	position: relative;
     text-align: left;  /* just in case ancestor has non-standard setting */
+    z-index: 1;
 }
 .dijitTabListWrapper {
 	overflow: hidden;
+    z-index: 1;
 }
 
-.dijit_a11y .tabStripButton img {
+.dj_a11y .tabStripButton img {
 	/* hide the icons (or rather the empty space where they normally appear) because text will appear instead */
 	display: none;
 }
@@ -1332,7 +1419,7 @@ body .dijitAlignClient { position: absolute; }
 
 .dijitTabContainerLeft-tabs {
 	border-right: 1px solid black;
-	float: left;
+	float: left;    /* needed for IE7 RTL mode */
 }
 .dijitTabContainerLeft-container {
 	border-left: 0;
@@ -1347,7 +1434,7 @@ body .dijitAlignClient { position: absolute; }
 
 .dijitTabContainerRight-tabs {
 	border-left: 1px solid black;
-	float: left;
+	float: left;    /* needed for IE7 RTL mode */
 }
 .dijitTabContainerRight-container {
 	border-right: 0;
@@ -1360,6 +1447,7 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 .dijitTab {
 	position:relative;
 	cursor:pointer;
+	-webkit-tap-highlight-color: transparent;
 	white-space:nowrap;
 	z-index:3;
 }
@@ -1393,11 +1481,6 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	#display:inline; /* don't use .dj_ie since that increases the priority */
 }
 
-.dijitTabInnerDiv {
-	position:relative;
-}
-
-
 .tabStripButton {
 	z-index: 12;
 }
@@ -1435,13 +1518,13 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 
 /* images off, high-contrast mode styles */
 
-.dijit_a11y .dijitTabCloseButton {
+.dj_a11y .dijitTabCloseButton {
 	background-image: none !important;
 	width: auto !important;
 	height: auto !important;
 }
 
-.dijit_a11y .dijitTabCloseText {
+.dj_a11y .dijitTabCloseText {
 	display: inline;
 }
 
@@ -1460,14 +1543,14 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	cursor: text;
 }
 
-.dijit_a11y .dijitInlineEditBoxDisplayMode,
+.dj_a11y .dijitInlineEditBoxDisplayMode,
 .dj_ie6 .dijitInlineEditBoxDisplayMode {
 	/* except that IE6 doesn't support transparent borders, nor does high contrast mode */
 	border: none;
 }
 
 .dijitInlineEditBoxDisplayModeHover,
-.dijit_a11y .dijitInlineEditBoxDisplayModeHover,
+.dj_a11y .dijitInlineEditBoxDisplayModeHover,
 .dj_ie6 .dijitInlineEditBoxDisplayModeHover {
 	/* An InlineEditBox in view mode (click this to edit the text) */
 	background-color: #e2ebf2;
@@ -1481,6 +1564,11 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 /* Tree */
 .dijitTree {
 	overflow: auto;	/* for scrollbars when Tree has a height setting, and to prevent wrapping around float elements, see #11491 */
+	-webkit-tap-highlight-color: transparent;
+}
+
+.dijitTreeContainer {
+	float: left;	/* for correct highlighting during horizontal scroll, see #16132 */
 }
 
 .dijitTreeIndent {
@@ -1492,6 +1580,11 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	white-space: nowrap;
 }
 
+.dj_ie .dijitTreeLabel:focus {
+	/* workaround IE9 behavior where down arrowing through TreeNodes doesn't show focus outline */
+	outline: 1px dotted black;
+}
+
 .dijitTreeRow img {
 	/* make the expando and folder icons line up with the label */
 	vertical-align: middle;
@@ -1505,7 +1598,7 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	display: none;
 }
 
-.dijit_a11y .dijitExpandoText {
+.dj_a11y .dijitExpandoText {
 	display: inline;
 	padding-left: 10px;
 	padding-right: 10px;
@@ -1524,7 +1617,7 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 .dijitDialog {
 	position: absolute;
 	z-index: 999;
-	overflow: hidden;       /* override overflow: auto; from ContentPane to make dragging smoother */
+	overflow: hidden;	/* override overflow: auto; from ContentPane to make dragging smoother */
 }
 
 .dijitDialogTitleBar {
@@ -1535,6 +1628,10 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 }
 .dijitDialogCloseIcon {
 	cursor: pointer;
+	-webkit-tap-highlight-color: transparent;
+}
+.dijitDialogPaneContent {
+	-webkit-overflow-scrolling: touch;
 }
 .dijitDialogUnderlayWrapper {
 	position: absolute;
@@ -1555,8 +1652,8 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 }
 
 /* images off, high-contrast mode styles */
-.dijit_a11y .dijitSpinnerButtonContainer,
-.dijit_a11y .dijitDialog {
+.dj_a11y .dijitSpinnerButtonContainer,
+.dj_a11y .dijitDialog {
 	opacity: 1 !important;
 	background-color: white !important;
 }
@@ -1567,7 +1664,7 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	position:absolute;
 }
 
-.dijit_a11y .dijitDialog .closeText {
+.dj_a11y .dijitDialog .closeText {
 	display:inline;
 }
 
@@ -1587,7 +1684,7 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	right:50%;
 }
 
-.dijit_a11y div.dijitSliderImageHandle,
+.dj_a11y div.dijitSliderImageHandle,
 .dijitSliderImageHandle {
 	margin:0;
 	padding:0;
@@ -1596,17 +1693,18 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	width:0;
 	height:0;
 	cursor: pointer;
+	-webkit-tap-highlight-color: transparent;
 }
-.dj_iequirks .dijit_a11y .dijitSliderImageHandle {
+.dj_iequirks .dj_a11y .dijitSliderImageHandle {
 	font-size: 0;
 }
 .dj_ie7 .dijitSliderImageHandle {
 	overflow: hidden; /* IE7 workaround to make slider handle VISIBLE in non-a11y mode */
 }
-.dj_ie7 .dijit_a11y .dijitSliderImageHandle {
+.dj_ie7 .dj_a11y .dijitSliderImageHandle {
 	overflow: visible; /* IE7 workaround to make slider handle VISIBLE in a11y mode */
 }
-.dijit_a11y .dijitSliderFocused .dijitSliderImageHandle {
+.dj_a11y .dijitSliderFocused .dijitSliderImageHandle {
 	border:4px solid #000;
 	height:8px;
 	width:8px;
@@ -1627,6 +1725,7 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	border-style:solid;
 	border-color:black;
 	cursor: pointer;
+	-webkit-tap-highlight-color: transparent;
 }
 
 .dijitSliderBarContainerV {
@@ -1727,6 +1826,7 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 
 .dijitSliderDecorationV {
 	height: 100%;
+	white-space: nowrap;
 }
 
 .dijitSliderButton {
@@ -1736,7 +1836,7 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	display:block;
 }
 
-.dijit_a11y .dijitSliderButtonInner {
+.dj_a11y .dijitSliderButtonInner {
 	visibility:visible !important;
 }
 
@@ -1746,6 +1846,7 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 }
 .dijitSliderButtonContainer * {
 	cursor: pointer;
+	-webkit-tap-highlight-color: transparent;
 }
 
 .dijitSlider .dijitButtonNode {
@@ -1825,17 +1926,17 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	margin-top:-.55em;
 }
 
-.dijit_a11y .dijitSliderReadOnly,
-.dijit_a11y .dijitSliderDisabled {
+.dj_a11y .dijitSliderReadOnly,
+.dj_a11y .dijitSliderDisabled {
 	opacity:0.6;
 }
-.dj_ie .dijit_a11y .dijitSliderReadOnly .dijitSliderBar,
-.dj_ie .dijit_a11y .dijitSliderDisabled .dijitSliderBar {
+.dj_ie .dj_a11y .dijitSliderReadOnly .dijitSliderBar,
+.dj_ie .dj_a11y .dijitSliderDisabled .dijitSliderBar {
 	filter: alpha(opacity=40);
 }
 
 /* + and - Slider buttons: override theme settings to display icons */
-.dijit_a11y .dijitSlider .dijitSliderButtonContainer div {
+.dj_a11y .dijitSlider .dijitSliderButtonContainer div {
 	font-family: monospace; /* otherwise hyphen is larger and more vertically centered */
 	font-size: 1em;
 	line-height: 1em;
@@ -1845,10 +1946,13 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 }
 
 /* Icon-only buttons (often in toolbars) still display the text in high-contrast mode */
-.dijit_a11y .dijitButtonContents .dijitButtonText,
-.dijit_a11y .dijitTab .tabLabel {
+.dj_a11y .dijitButtonContents .dijitButtonText,
+.dj_a11y .dijitTab .tabLabel {
 	display: inline !important;
 }
+.dj_a11y .dijitSelect .dijitButtonText {
+	display: inline-block !important;
+}
 
 /* TextArea, SimpleTextArea */
 .dijitTextArea {
@@ -1897,6 +2001,27 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 
 /* TimePicker */
 
+.dijitTimePicker {
+	background-color: white;
+}
+.dijitTimePickerItem {
+	cursor:pointer;
+	-webkit-tap-highlight-color: transparent;
+}
+.dijitTimePickerItemHover {
+	background-color:gray;
+	color:white;
+}
+.dijitTimePickerItemSelected {
+	font-weight:bold;
+	color:#333;
+	background-color:#b7cdee;
+}
+.dijitTimePickerItemDisabled {
+	color:gray;
+	text-decoration:line-through;
+}
+
 .dijitTimePickerItemInner {
 	text-align:center;
 	border:0;
@@ -1921,21 +2046,10 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	background-color:#CCC;
 }
 
-.dijitTimePickerItemSelected {
-	font-weight:bold;
-	color:#333;
-	background-color:#b7cdee;
-}
-
-.dijitTimePickerItemHover {
-	background-color:gray;
-	color:white;
-	cursor:pointer;
-}
-.dijit_a11y .dijitTimePickerItemSelected .dijitTimePickerItemInner {
+.dj_a11y .dijitTimePickerItemSelected .dijitTimePickerItemInner {
 	border: solid 4px black;
 }
-.dijit_a11y .dijitTimePickerItemHover .dijitTimePickerItemInner {
+.dj_a11y .dijitTimePickerItemHover .dijitTimePickerItemInner {
 	border: dashed 4px black;
 }
 
@@ -1944,60 +2058,72 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	/* character (instead of icon) to show that ToggleButton is checked */
 	display:none !important;
 }
-.dijit_a11y .dijitToggleButton .dijitToggleButtonIconChar {
+.dj_a11y .dijitToggleButton .dijitToggleButtonIconChar {
 	display:inline !important;
 	visibility:hidden;
 }
 .dj_ie6 .dijitToggleButtonIconChar, .dj_ie6 .tabStripButton .dijitButtonText {
 	font-family: "Arial Unicode MS";	/* otherwise the a11y character (checkmark, arrow, etc.) appears as a box */
 }
-.dijit_a11y .dijitToggleButtonChecked .dijitToggleButtonIconChar {
+.dj_a11y .dijitToggleButtonChecked .dijitToggleButtonIconChar {
 	display: inline !important; /* In high contrast mode, display the check symbol */
 	visibility:visible !important;
 }
 
 .dijitArrowButtonChar {
-        display:none !important;
+	display:none !important;
 }
-.dijit_a11y .dijitArrowButtonChar {
-        display:inline !important;
+.dj_a11y .dijitArrowButtonChar {
+	display:inline !important;
 }
 
-.dijit_a11y .dijitDropDownButton .dijitArrowButtonInner,
-.dijit_a11y .dijitComboButton .dijitArrowButtonInner {
+.dj_a11y .dijitDropDownButton .dijitArrowButtonInner,
+.dj_a11y .dijitComboButton .dijitArrowButtonInner {
 	display:none !important;
 }
 
 /* Select */
-.dijitSelect {
-	margin: 0.2em;
-	border-collapse: collapse;
+.dj_a11y .dijitSelect {
+	border-collapse: separate !important;
+	border-width: 1px;
+	border-style: solid;
 }
-.dj_ie .dijitSelect,
-.dj_ie7 .dijitSelect,
-.dj_iequirks .dijitSelect {
+.dj_ie .dijitSelect {
 	vertical-align: middle; /* Set this back for what we hack in dijit inline */
 }
+.dj_ie6 .dijitSelect .dijitValidationContainer,
 .dj_ie8 .dijitSelect .dijitButtonText {
 	vertical-align: top;
 }
+.dj_ie6 .dijitTextBox .dijitInputContainer,
+.dj_iequirks .dijitTextBox .dijitInputContainer,
+.dj_ie6 .dijitTextBox .dijitArrowButtonInner,
+.dj_ie6 .dijitSpinner .dijitSpinnerButtonInner,
+.dijitSelect .dijitSelectLabel {
+	vertical-align: baseline;
+}
+
+.dijitNumberTextBox {
+	text-align: left;
+	direction: ltr;
+}
+
+.dijitNumberTextBox .dijitInputInner {
+	text-align: inherit; /* input */
+}
+
 .dijitToolbar .dijitSelect {
 	margin: 0;
 }
 .dj_webkit .dijitToolbar .dijitSelect {
 	padding-left: 0.3em;
 }
-.dijit_a11y .dijitSelectDisabled .dijitButtonNode {
-	border-style: outset!important;
-	border-width: medium!important;
-	border-color: #999 !important;
-	color:#999 !important;
-}
 .dijitSelect .dijitButtonContents {
 	padding: 0;
-	background: transparent none;
 	white-space: nowrap;
 	text-align: left;
+	border-style: none solid none none;
+	border-width: 1px;
 }
 .dijitSelectFixedWidth .dijitButtonContents {
 	width: 100%;
@@ -2029,13 +2155,6 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	border-width: 1px;
 }
 
-/* Style the different areas of the button to look like a "real" dropdown */
-/* Remove margins on the sub-table */
-.dijitSelectMenu .dijitMenuTable {
-	margin: 0;
-	background-color: transparent;
-}
-
 /* Used in cases, such as FullScreen plugin, when we need to force stuff to static positioning. */
 .dijitForceStatic {
 	position: static !important;
@@ -2049,3 +2168,49 @@ div.dijitTabDisabled, .dj_ie div.dijitTabDisabled {
 	/* a region the user would be able to click on, but it's disabled */
 	cursor: default;
 }
+
+/* Drag and Drop */
+.dojoDndItem {
+    padding: 2px;  /* will be replaced by border during drag over (dojoDndItemBefore, dojoDndItemAfter) */
+
+	/* Prevent magnifying-glass text selection icon to appear on mobile webkit as it causes a touchout event */
+	-webkit-touch-callout: none;
+	-webkit-user-select: none; /* Disable selection/Copy of UIWebView */
+}
+.dojoDndHorizontal .dojoDndItem {
+    /* make contents of horizontal container be side by side, rather than vertical */
+    #display: inline;
+    display: inline-block;
+}
+
+.dojoDndItemBefore,
+.dojoDndItemAfter {
+	border: 0px solid #369;
+}
+.dojoDndItemBefore {
+    border-width: 2px 0 0 0;
+    padding: 0 2px 2px 2px;
+}
+.dojoDndItemAfter {
+    border-width: 0 0 2px 0;
+    padding: 2px 2px 0 2px;
+}
+.dojoDndHorizontal .dojoDndItemBefore {
+    border-width: 0 0 0 2px;
+    padding: 2px 2px 2px 0;
+}
+.dojoDndHorizontal .dojoDndItemAfter {
+    border-width: 0 2px 0 0;
+    padding: 2px 0 2px 2px;
+}
+
+.dojoDndItemOver {
+	cursor:pointer;
+}
+.dj_gecko .dijitArrowButtonInner INPUT,
+.dj_gecko INPUT.dijitArrowButtonInner {
+	-moz-user-focus:ignore;
+}
+.dijitFocused .dijitMenuItemShortcutKey {
+	text-decoration: underline;
+}
diff --git a/dijit/themes/dijit_rtl.css b/dijit/themes/dijit_rtl.css
index 9c1b69c..881d31a 100644
--- a/dijit/themes/dijit_rtl.css
+++ b/dijit/themes/dijit_rtl.css
@@ -1,3 +1,9 @@
+.dijitRtl .dijitOffScreen {
+	/* align on the right side rather than the left so no horizontal scroll bar shown */
+	left: auto !important;
+	right: -10000px !important;
+}
+
 .dijitRtl .dijitPlaceHolder {
 	left: auto;
 	right: 0;
@@ -15,6 +21,9 @@
 	/* workaround bug where label invisible (themeTesterQuirk.html?dir=rtl) */
 	float:left;
 }
+.dj_ie .dijitTextBoxRtl .dijitInputContainer {
+	clear: right;
+}
 
 /* TextBox, ComboBox, Spinner */
 
@@ -31,17 +40,20 @@
 	left: auto;
 }
 
-.dj_ie7 .dijitInputContainer {
-	/* to fix wrong text alignment in rtl text box in IE */
-	display: inline-block;
+.dijitSelectRtl .dijitButtonText {
+	float: right;
 }
 
 .dijitTextBoxRtl .dijitSpinnerButtonContainer,
-.dijitTextBoxRtl .dijitValidationContainer,
+.dijitValidationTextBoxRtl .dijitValidationContainer,
 .dijitTextBoxRtl .dijitArrowButtonContainer {
 	float: left;
 }
 
+div.dijitNumberTextBoxRtl {
+	text-align: right;
+}
+
 /* Calendar */
 
 .dijitCalendarRtl .dijitCalendarNextYear {
@@ -108,6 +120,23 @@
 	margin-left: 0;
 	margin-right: 1em;
 }
+.dj_ie6 .dijitTabRtl .tabLabel,
+.dj_ie6 .dijitTabContainerRight-tabs .dijitTabRtl,
+.dj_ie6 .dijitTabContainerLeft-tabs .dijitTabRtl,
+.dj_ie7 .dijitTabContainerRight-tabs .dijitTabRtl,
+.dj_ie7 .dijitTabContainerLeft-tabs .dijitTabRtl {
+	zoom: 1;
+}
+.dj_ie6 .dijitTabContainerRight-tabs .dijitTabRtl,
+.dj_ie7 .dijitTabContainerRight-tabs .dijitTabRtl {
+    left: 0;
+}
+
+.dj_ie6 .dijitTabContainerRightRtl .dijitTabContainerRight-tabs,
+.dj_ie6 .dijitTabContainerLeftRtl .dijitTabContainerLeft-tabs {
+    /* otherwise tab labels invisible */
+	width: 1%;
+}
 
 /* TimePicker */
 .dj_ie .dijitTimePickerRtl .dijitTimePickerItem {
@@ -124,5 +153,25 @@
 
 /* Select */
 .dijitSelectRtl .dijitButtonContents {
+	border-style: none none none solid;
 	text-align: right;
 }
+
+/* Tree */
+
+.dijitTreeRtl .dijitTreeContainer {
+	float: right;	/* for correct highlighting during horizontal scroll, see #16132 */
+}
+
+/* DnD
+ * These rules should apply for containers that are dir=rtl (either set directly, or inherited)
+ * but seems the best we can do is look for .dijitRtl on an ancestor node.
+ */
+.dijitRtl .dojoDndHorizontal .dojoDndItemBefore {
+    border-width: 0 2px 0 0;
+    padding: 2px 0 2px 2px;
+}
+.dijitRtl .dojoDndHorizontal .dojoDndItemAfter {
+    border-width: 0 0 0 2px;
+    padding: 2px 2px 2px 0;
+}
diff --git a/dijit/themes/nihilo/Common.css b/dijit/themes/nihilo/Common.css
index 4986990..1a1c7f9 100644
--- a/dijit/themes/nihilo/Common.css
+++ b/dijit/themes/nihilo/Common.css
@@ -1,17 +1,9 @@
-/* DnD avatar-specific settings */
-/* For now it uses a default set of rules. Some other DnD classes can be modified as well. */
-.nihilo .dojoDndItemBefore {
-	border-top: 2px solid #369;
-}
-
-.nihilo .dojoDndItemAfter {
-	border-bottom: 2px solid #369;
-}
-
 .nihilo .dojoDndItemOver {
-	cursor:pointer;
+	background-image: url(images/treeHover.png);
 }
 
+/* DnD avatar-specific settings */
+/* For now it uses a default set of rules. Some other DnD classes can be modified as well. */
 .nihilo table.dojoDndAvatar { -moz-border-radius: 0; border: 1px solid #ccc; border-collapse: collapse; background-color: #fff; font-size: 75%; color: black;}
 .nihilo .dojoDndAvatar td	{ border: none; }
 .nihilo .dojoDndAvatar tr	{ border: none; }
diff --git a/dijit/themes/nihilo/Dialog.css b/dijit/themes/nihilo/Dialog.css
index 4affeb8..2482604 100644
--- a/dijit/themes/nihilo/Dialog.css
+++ b/dijit/themes/nihilo/Dialog.css
@@ -67,15 +67,7 @@
 }
 
 .nihilo .dijitTooltipContainer {
-	/*
-		The part with the text.
-
-		NOTE:
-			FF doesn't clip images used as CSS bgs if you specify a border
-			radius. If you use a solid color, it does. Webkit gets it right.
-			Sigh.
-		background: #ffffff url("images/popupMenuBg.gif") repeat-x bottom left;
-	*/
+	/* The part with the text. */
 	background-color: #fff;
 	border:1px solid #d3d3d3;
 	padding:0.45em;
diff --git a/dijit/themes/nihilo/Menu.css b/dijit/themes/nihilo/Menu.css
index cad4698..8d247f3 100644
--- a/dijit/themes/nihilo/Menu.css
+++ b/dijit/themes/nihilo/Menu.css
@@ -29,6 +29,7 @@
 }
 
 .nihilo .dijitMenuPassive .dijitMenuItemHover,
+.nihilo .dijitComboBoxMenu .dijitMenuItemHover,
 .nihilo .dijitMenuItemSelected {
 	background-color: #ffe284; /* #95a0b0; #555555; #aaaaaa; #646464;  #60a1ea; #848484; */
 	color: #243C5F;
@@ -63,15 +64,17 @@
 }
 
 /* the checked menu item */
-.nihilo .dijitCheckedMenuItemIconChar {
-	display: none;
-}
-
-.nihilo .dijitCheckedMenuItemIcon {
+.nihilo .dijitCheckedMenuItem .dijitMenuItemIcon  {
 	background-image: url('images/spriteCheckbox.gif');
 	background-position: -80px;
 }
-
-.nihilo .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
+.nihilo .dijitCheckedMenuItemChecked .dijitMenuItemIcon {
+	background-position: -64px;
+}
+.nihilo .dijitRadioMenuItem .dijitMenuItemIcon {
+	background-image: url('images/spriteRadio.gif');
+	background-position: -80px;
+}
+.nihilo .dijitRadioMenuItemChecked .dijitMenuItemIcon {
 	background-position: -64px;
 }
\ No newline at end of file
diff --git a/dijit/themes/nihilo/ProgressBar.css b/dijit/themes/nihilo/ProgressBar.css
index 6c50a7e..99d94f1 100644
--- a/dijit/themes/nihilo/ProgressBar.css
+++ b/dijit/themes/nihilo/ProgressBar.css
@@ -19,7 +19,8 @@
 }
 
 .nihilo .dijitProgressBarFull {
-	border-right:1px solid #f8d582;
+	border: 0px solid #f8d582;
+	border-right-width: 1px;
 }
 
 .nihilo .dijitProgressBarLabel {
diff --git a/dijit/themes/nihilo/ProgressBar_rtl.css b/dijit/themes/nihilo/ProgressBar_rtl.css
new file mode 100644
index 0000000..cde3031
--- /dev/null
+++ b/dijit/themes/nihilo/ProgressBar_rtl.css
@@ -0,0 +1,12 @@
+
+/****
+		dijit.ProgressBar
+ ****/
+
+.nihilo .dijitProgressBarRtl .dijitProgressBarFull {
+	border-left-width: 1px;
+	border-right: 0px;
+}
+
+
+
diff --git a/dijit/themes/nihilo/TimePicker.css b/dijit/themes/nihilo/TimePicker.css
index cffdbf5..6054e6b 100644
--- a/dijit/themes/nihilo/TimePicker.css
+++ b/dijit/themes/nihilo/TimePicker.css
@@ -5,7 +5,7 @@
 }
 
 .nihilo .dijitTimePickerTick {
-	color:white;
+	color: gray;
 }
 
 .nihilo .dijitTimePickerMarker {
@@ -24,28 +24,10 @@
 	color:black;
 }
 
-.nihilo .dijitTimePickerItemHover,
-.nihilo .dijitTimePickerItemSelected {
-	position: relative;
-	z-index: 10;
-}
-
 .nihilo .dijitTimePickerTick .dijitTimePickerItemInner {
-	font-size:0.4em;
+	font-size: 0.8em;
 }
 
-.nihilo .dijitTimePickerItemHover .dijitTimePickerItemInner,
 .nihilo .dijitTimePickerItemSelected .dijitTimePickerItemInner {
-	font-size:1em;
+	font-size: 1em;
 }
-
-.nihilo .dijitTimePickerMarkerHover {
-	border-top: 1px solid #eeeeee;
-}
-
-.nihilo .dijitTimePickerTickHover,
-.nihilo .dijitTimePickerTickSelected {
-	margin-top:-0.3em;
-	margin-bottom:-0.3em;
-	border-bottom: none;
-}
\ No newline at end of file
diff --git a/dijit/themes/nihilo/TitlePane.css b/dijit/themes/nihilo/TitlePane.css
index 6d16ff9..f690929 100644
--- a/dijit/themes/nihilo/TitlePane.css
+++ b/dijit/themes/nihilo/TitlePane.css
@@ -1,5 +1,5 @@
 /**
- * dijit.TitlePane
+ * dijit.TitlePane and dijit.Fieldset
  *
  */
 
@@ -16,8 +16,8 @@
 	background: #f9f9f9 url("images/accordionItemActive.png") top repeat-x;
 }
 
-.nihilo .dijitTitlePane .dijitOpen .dijitArrowNode,
-.nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+.nihilo .dijitTitlePane .dijitArrowNode,
+.nihilo .dijitFieldset .dijitArrowNode {
 	width:15px;
 	height:15px;
 }
@@ -26,16 +26,16 @@
 	color: #243C5F;
 }
 
-.nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+.nihilo .dijitTitlePane .dijitClosed .dijitArrowNode, .nihilo .dijitFieldset .dijitFieldsetTitleClosed .dijitArrowNode {
 	background: url('images/spriteRoundedIconsSmall.png') no-repeat -30px top;
 }
-.dj_ie6 .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+.dj_ie6 .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode, .dj_ie6 .nihilo .dijitFieldset .dijitFieldsetTitleClosed .dijitArrowNode {
 	background:url('images/spriteRoundedIconsSmall.gif') no-repeat -30px top;
 }
-.nihilo .dijitTitlePane .dijitOpen .dijitArrowNode {
+.nihilo .dijitTitlePane .dijitOpen .dijitArrowNode, .nihilo .dijitFieldset .dijitFieldsetTitleOpen .dijitArrowNode {
 	background:url('images/spriteRoundedIconsSmall.png') no-repeat -15px top;
 }
-.dj_ie6 .nihilo .dijitTitlePane .dijitOpen .dijitArrowNode {
+.dj_ie6 .nihilo .dijitTitlePane .dijitOpen .dijitArrowNode, .dj_ie6 .nihilo .dijitFieldset .dijitFieldsetTitleClosed .dijitArrowNode {
 	background:url('images/spriteRoundedIconsSmall.gif') no-repeat -15px top;
 }
 
diff --git a/dijit/themes/nihilo/TitlePane_rtl.css b/dijit/themes/nihilo/TitlePane_rtl.css
index 7b3ba21..9af4446 100644
--- a/dijit/themes/nihilo/TitlePane_rtl.css
+++ b/dijit/themes/nihilo/TitlePane_rtl.css
@@ -1,6 +1,3 @@
-.dijitRtl .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
-	background-position: 0 top;
-}
-.dj_ie6-rtl .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
+.nihilo .dijitTitlePaneRtl .dijitClosed .dijitArrowNode, .nihilo .dijitFieldsetRtl .dijitFieldsetTitleClosed .dijitArrowNode {
 	background-position: 0 top;
 }
\ No newline at end of file
diff --git a/dijit/themes/nihilo/form/Button.css b/dijit/themes/nihilo/form/Button.css
index 90e1ee2..83c719b 100644
--- a/dijit/themes/nihilo/form/Button.css
+++ b/dijit/themes/nihilo/form/Button.css
@@ -16,14 +16,13 @@
 	background: #fff url("../images/buttonEnabled.png") repeat-x top left;
 }
 
-.nihilo .dijitSelect .dijitButtonContents {
-	border-right: none;
-}
-
 .nihilo .dijitButtonText {
 	text-align: center;
 	padding: 0 0.3em;
 }
+.nihilo .dijitInputField {
+	padding: 0; /* set padding:0 for .nihilo .dijitSelect .dijitButtonText but with a low priority rule that can be easily trumped by the user */
+}
 
 .nihilo .dijitComboBox .dijitButtonNode {
 	border-width: 0 0 0 1px;
diff --git a/dijit/themes/nihilo/form/Button_rtl.css b/dijit/themes/nihilo/form/Button_rtl.css
index 60d4c4d..07886d0 100644
--- a/dijit/themes/nihilo/form/Button_rtl.css
+++ b/dijit/themes/nihilo/form/Button_rtl.css
@@ -1,8 +1,4 @@
-.dijitRtl .nihilo .dijitComboBox .dijitButtonNode {
+.nihilo .dijitComboBoxRtl .dijitButtonNode {
 	border-width: 0 0 0 1px;
 }
-.dijitRtl .nihilo .dijitSelect .dijitButtonContents {
-	border-left: none;
-	border-right-width: 1px;
-}
 
diff --git a/dijit/themes/nihilo/form/Common.css b/dijit/themes/nihilo/form/Common.css
index b67195f..31bf95e 100644
--- a/dijit/themes/nihilo/form/Common.css
+++ b/dijit/themes/nihilo/form/Common.css
@@ -10,11 +10,12 @@
 		dijit.form.ComboBox (partial)
  ****/
 
-.nihilo .dijitInputContainer input,
-.nihilo .dijitTextBox {
+.nihilo .dijitInputContainer input {
 	margin: 0 0.1em;
 }
 
+.nihilo .dijitSelect .dijitButtonContents,
+.nihilo .dijitSelect,
 .nihilo .dijitTextBox,
 .nihilo .dijitTextArea {
 	/* 	For all except dijit.form.NumberSpinner:  the actual input element.
@@ -23,26 +24,34 @@
 	*/
 	background:#fff url("../images/validationInputBg.png") repeat-x top left;
 	#background:#fff url('../images/validationInputBg.gif') repeat-x top left;
+}
+.nihilo .dijitSelect,
+.nihilo .dijitTextBox,
+.nihilo .dijitTextArea {
 	border:1px solid #d3d3d3;
 }
 
+.nihilo .dijitSelect .dijitArrowButton,
 .nihilo .dijitComboBox .dijitButtonNode {
-	padding: 0 0.2em !important;
+	padding: 0 0.2em;
 }
+.nihilo .dijitSelect .dijitButtonContents,
 .nihilo .dijitTextBox .dijitButtonNode {
 	/* line between the input area and the drop down button */
 	border-color: #d3d3d3;
 }
 
+.nihilo .dijitSelectFocused,
 .nihilo .dijitTextBoxFocused,
 .nihilo .dijitTextAreaFocused {
 	/* input field when focused (ie: typing affects it) */
 	border-color:#b3b3b3;
 }
+.nihilo .dijitSelectFocused TD,
 .nihilo .dijitTextBoxFocused .dijitButtonNode,
 .nihilo .dijitSpinner .dijitUpArrowButtonActive,
 .nihilo .dijitSpinner .dijitDownArrowButtonActive {
-	border-left-color:#d3d3d3;
+	border-color:#d3d3d3;
 }
 .nihilo .dijitSpinnerFocused .dijitDownArrowButton,
 .nihilo .dijitSpinner .dijitUpArrowButtonActive,
@@ -62,7 +71,7 @@
 }
 
 /* Validation errors  */
-.nihilo .dijitValidationIcon {
+.nihilo .dijitValidationTextBoxError .dijitValidationIcon {
 	/* prevent height change when widget goes from valid to invalid state */
 	width: 16px;
 	background: transparent url('../images/warning.png') no-repeat center center;
diff --git a/dijit/themes/nihilo/form/Select.css b/dijit/themes/nihilo/form/Select.css
index 61967e5..6e6a9c4 100644
--- a/dijit/themes/nihilo/form/Select.css
+++ b/dijit/themes/nihilo/form/Select.css
@@ -1,45 +1,38 @@
-.nihilo .dijitSelect .dijitButtonNode {
-	padding: 0;
-}
-
-/* Make unselected "look" more like a text box and less like a button */
-.nihilo .dijitSelect .dijitButtonContents {
-	padding-top: 1px;
-    background:#fff url("../images/validationInputBg.png") repeat-x top left;
-    #background:#fff url('../images/validationInputBg.gif') repeat-x top left;
-}
-.nihilo .dijitSelectHover .dijitButtonContents,
-.nihilo .dijitSelectActive .dijitButtonContents,
-.nihilo .dijitSelectOpened .dijitButtonContents,
-.nihilo .dijitSelectDisabled .dijitButtonContents,
-.nihilo .dijitSelectReadOnly .dijitButtonContents{
+.nihilo .dijitSelectError .dijitButtonContents,
+.nihilo .dijitSelectHover .dijitArrowButton,
+.nihilo .dijitSelectActive .dijitArrowButton,
+.nihilo .dijitSelectOpened .dijitArrowButton,
+.nihilo .dijitSelectDisabled .dijitArrowButton,
+.nihilo .dijitSelectReadOnly .dijitArrowButton {
 	background: transparent none;
 }
-.dj_ie .nihilo .dijitSelect .dijitButtonContents {
-	padding-top: 0;
-}
 
 .nihilo .dijitSelect .dijitArrowButton {
-	padding: 0 2px;
+	background: #bcd5f0 url("../images/buttonEnabled.png") repeat-x top left;
+	border-width: 0;
 }
 
 /* Mirror DropDownButton */
-.nihilo .dijitSelectDisabled .dijitButtonNode {
-    border-color: #dedede;
+.nihilo .dijitSelectDisabled,
+.nihilo .dijitSelectDisabled TD {
+    border-color: #dedede !important;
     background:#fafafa url("../images/buttonDisabled.png") top repeat-x;
 }
-.dj_ie .nihilo .dijitSelectDisabled  .dijitButtonNode * {
+.dj_ie .nihilo .dijitSelectDisabled  TD * {
 	filter: gray() alpha(opacity=50);
 }
 
-.nihilo .dijitSelectHover .dijitButtonNode {
+.nihilo .dijitSelectHover,
+.nihilo .dijitSelectHover TD {
     color:#000;
     background:#fcfcfc url("../images/buttonHover.png") repeat-x top left;
 }
 
-.nihilo .dijitSelectActive .dijitButtonNode,
-.nihilo .dijitSelectOpened .dijitButtonNode {
-    border-color:#dedede;
+.nihilo .dijitSelectActive,
+.nihilo .dijitSelectOpened,
+.nihilo .dijitSelectActive TD,
+.nihilo .dijitSelectOpened TD {
+    border-color:#dedede !important;
     background: #f5f5f5 url("../images/buttonActive.png") top left repeat-x;
 }
 
@@ -51,4 +44,3 @@
 .nihilo .dijitSelectMenu .dijitMenuArrowCell {
 	padding: 0.1em 0.2em;
 }
-
diff --git a/dijit/themes/nihilo/form/TimeTextBox.css b/dijit/themes/nihilo/form/TimeTextBox.css
index bf67b66..d450925 100644
--- a/dijit/themes/nihilo/form/TimeTextBox.css
+++ b/dijit/themes/nihilo/form/TimeTextBox.css
@@ -1 +1 @@
- at CHARSET "UTF-8";
\ No newline at end of file
+ at CHARSET "UTF-8";
diff --git a/dijit/themes/nihilo/images/accordionItemActive.png b/dijit/themes/nihilo/images/accordionItemActive.png
index 58f3cf9..8657115 100644
Binary files a/dijit/themes/nihilo/images/accordionItemActive.png and b/dijit/themes/nihilo/images/accordionItemActive.png differ
diff --git a/dijit/themes/nihilo/images/buttonActive.png b/dijit/themes/nihilo/images/buttonActive.png
index e2f2fda..fe551bc 100644
Binary files a/dijit/themes/nihilo/images/buttonActive.png and b/dijit/themes/nihilo/images/buttonActive.png differ
diff --git a/dijit/themes/nihilo/images/buttonDisabled.png b/dijit/themes/nihilo/images/buttonDisabled.png
index b76af42..eb4d238 100644
Binary files a/dijit/themes/nihilo/images/buttonDisabled.png and b/dijit/themes/nihilo/images/buttonDisabled.png differ
diff --git a/dijit/themes/nihilo/images/buttonEnabled.png b/dijit/themes/nihilo/images/buttonEnabled.png
index d4fd306..456d62d 100644
Binary files a/dijit/themes/nihilo/images/buttonEnabled.png and b/dijit/themes/nihilo/images/buttonEnabled.png differ
diff --git a/dijit/themes/nihilo/images/buttonHover.png b/dijit/themes/nihilo/images/buttonHover.png
index 1af7e83..c11b5d1 100644
Binary files a/dijit/themes/nihilo/images/buttonHover.png and b/dijit/themes/nihilo/images/buttonHover.png differ
diff --git a/dijit/themes/nihilo/images/dndCopy.png b/dijit/themes/nihilo/images/dndCopy.png
index baecd7c..6a8b998 100644
Binary files a/dijit/themes/nihilo/images/dndCopy.png and b/dijit/themes/nihilo/images/dndCopy.png differ
diff --git a/dijit/themes/nihilo/images/dndMove.png b/dijit/themes/nihilo/images/dndMove.png
index 07f878c..8443d30 100644
Binary files a/dijit/themes/nihilo/images/dndMove.png and b/dijit/themes/nihilo/images/dndMove.png differ
diff --git a/dijit/themes/nihilo/images/dndNoCopy.png b/dijit/themes/nihilo/images/dndNoCopy.png
index 9bf9c33..64bf88b 100644
Binary files a/dijit/themes/nihilo/images/dndNoCopy.png and b/dijit/themes/nihilo/images/dndNoCopy.png differ
diff --git a/dijit/themes/nihilo/images/dndNoMove.png b/dijit/themes/nihilo/images/dndNoMove.png
index cb8bd8b..682ea10 100644
Binary files a/dijit/themes/nihilo/images/dndNoMove.png and b/dijit/themes/nihilo/images/dndNoMove.png differ
diff --git a/dijit/themes/nihilo/images/preciseSliderThumb.png b/dijit/themes/nihilo/images/preciseSliderThumb.png
index 045bf35..d6dc079 100644
Binary files a/dijit/themes/nihilo/images/preciseSliderThumb.png and b/dijit/themes/nihilo/images/preciseSliderThumb.png differ
diff --git a/dijit/themes/nihilo/images/preciseSliderThumbFocus.png b/dijit/themes/nihilo/images/preciseSliderThumbFocus.png
index c235849..939f253 100644
Binary files a/dijit/themes/nihilo/images/preciseSliderThumbFocus.png and b/dijit/themes/nihilo/images/preciseSliderThumbFocus.png differ
diff --git a/dijit/themes/nihilo/images/progressBarEmpty.png b/dijit/themes/nihilo/images/progressBarEmpty.png
index c2d3695..5500b1b 100644
Binary files a/dijit/themes/nihilo/images/progressBarEmpty.png and b/dijit/themes/nihilo/images/progressBarEmpty.png differ
diff --git a/dijit/themes/nihilo/images/progressBarFull.png b/dijit/themes/nihilo/images/progressBarFull.png
index a8f3865..1228e90 100644
Binary files a/dijit/themes/nihilo/images/progressBarFull.png and b/dijit/themes/nihilo/images/progressBarFull.png differ
diff --git a/dijit/themes/nihilo/images/sliderEmpty.png b/dijit/themes/nihilo/images/sliderEmpty.png
index 99fbd72..bdd9ae9 100644
Binary files a/dijit/themes/nihilo/images/sliderEmpty.png and b/dijit/themes/nihilo/images/sliderEmpty.png differ
diff --git a/dijit/themes/nihilo/images/sliderEmptyVertical.png b/dijit/themes/nihilo/images/sliderEmptyVertical.png
index 2d497e3..7b5036a 100644
Binary files a/dijit/themes/nihilo/images/sliderEmptyVertical.png and b/dijit/themes/nihilo/images/sliderEmptyVertical.png differ
diff --git a/dijit/themes/nihilo/images/sliderFull.png b/dijit/themes/nihilo/images/sliderFull.png
index 9adb254..fbfb2a8 100644
Binary files a/dijit/themes/nihilo/images/sliderFull.png and b/dijit/themes/nihilo/images/sliderFull.png differ
diff --git a/dijit/themes/nihilo/images/sliderFullFocus.png b/dijit/themes/nihilo/images/sliderFullFocus.png
index 3d75cae..d07f00c 100644
Binary files a/dijit/themes/nihilo/images/sliderFullFocus.png and b/dijit/themes/nihilo/images/sliderFullFocus.png differ
diff --git a/dijit/themes/nihilo/images/sliderFullVertical.png b/dijit/themes/nihilo/images/sliderFullVertical.png
index 27e9752..195580f 100644
Binary files a/dijit/themes/nihilo/images/sliderFullVertical.png and b/dijit/themes/nihilo/images/sliderFullVertical.png differ
diff --git a/dijit/themes/nihilo/images/sliderFullVerticalFocus.png b/dijit/themes/nihilo/images/sliderFullVerticalFocus.png
index cca6184..4e9bfff 100644
Binary files a/dijit/themes/nihilo/images/sliderFullVerticalFocus.png and b/dijit/themes/nihilo/images/sliderFullVerticalFocus.png differ
diff --git a/dijit/themes/nihilo/images/sliderThumb.png b/dijit/themes/nihilo/images/sliderThumb.png
index b6abbd2..6abb200 100644
Binary files a/dijit/themes/nihilo/images/sliderThumb.png and b/dijit/themes/nihilo/images/sliderThumb.png differ
diff --git a/dijit/themes/nihilo/images/sliderThumbFocus.png b/dijit/themes/nihilo/images/sliderThumbFocus.png
index 73ee705..c4d261e 100644
Binary files a/dijit/themes/nihilo/images/sliderThumbFocus.png and b/dijit/themes/nihilo/images/sliderThumbFocus.png differ
diff --git a/dijit/themes/nihilo/images/splitContainerSizerH-thumb.png b/dijit/themes/nihilo/images/splitContainerSizerH-thumb.png
index e7bc204..4b1fff8 100644
Binary files a/dijit/themes/nihilo/images/splitContainerSizerH-thumb.png and b/dijit/themes/nihilo/images/splitContainerSizerH-thumb.png differ
diff --git a/dijit/themes/nihilo/images/splitContainerSizerH.png b/dijit/themes/nihilo/images/splitContainerSizerH.png
index 5f5b0e9..a92cf66 100644
Binary files a/dijit/themes/nihilo/images/splitContainerSizerH.png and b/dijit/themes/nihilo/images/splitContainerSizerH.png differ
diff --git a/dijit/themes/nihilo/images/splitContainerSizerV-thumb.png b/dijit/themes/nihilo/images/splitContainerSizerV-thumb.png
index 410a0a7..75676d5 100644
Binary files a/dijit/themes/nihilo/images/splitContainerSizerV-thumb.png and b/dijit/themes/nihilo/images/splitContainerSizerV-thumb.png differ
diff --git a/dijit/themes/nihilo/images/splitContainerSizerV.png b/dijit/themes/nihilo/images/splitContainerSizerV.png
index 064bc18..721cc7d 100644
Binary files a/dijit/themes/nihilo/images/splitContainerSizerV.png and b/dijit/themes/nihilo/images/splitContainerSizerV.png differ
diff --git a/dijit/themes/nihilo/images/spriteArrows.png b/dijit/themes/nihilo/images/spriteArrows.png
index 73aa700..80bb45a 100644
Binary files a/dijit/themes/nihilo/images/spriteArrows.png and b/dijit/themes/nihilo/images/spriteArrows.png differ
diff --git a/dijit/themes/nihilo/images/spriteCheckbox.png b/dijit/themes/nihilo/images/spriteCheckbox.png
index e992330..03d1aa9 100644
Binary files a/dijit/themes/nihilo/images/spriteCheckbox.png and b/dijit/themes/nihilo/images/spriteCheckbox.png differ
diff --git a/dijit/themes/nihilo/images/spriteDivIcons.png b/dijit/themes/nihilo/images/spriteDivIcons.png
index 413098a..4e9ac30 100644
Binary files a/dijit/themes/nihilo/images/spriteDivIcons.png and b/dijit/themes/nihilo/images/spriteDivIcons.png differ
diff --git a/dijit/themes/nihilo/images/spriteRadio.png b/dijit/themes/nihilo/images/spriteRadio.png
index 14c1080..eef7ab4 100644
Binary files a/dijit/themes/nihilo/images/spriteRadio.png and b/dijit/themes/nihilo/images/spriteRadio.png differ
diff --git a/dijit/themes/nihilo/images/spriteRoundedIconsSmall.png b/dijit/themes/nihilo/images/spriteRoundedIconsSmall.png
index e81ba07..baea73d 100644
Binary files a/dijit/themes/nihilo/images/spriteRoundedIconsSmall.png and b/dijit/themes/nihilo/images/spriteRoundedIconsSmall.png differ
diff --git a/dijit/themes/nihilo/images/spriteTree.png b/dijit/themes/nihilo/images/spriteTree.png
index 33ae07b..4e63248 100644
Binary files a/dijit/themes/nihilo/images/spriteTree.png and b/dijit/themes/nihilo/images/spriteTree.png differ
diff --git a/dijit/themes/nihilo/images/spriteTree_rtl.png b/dijit/themes/nihilo/images/spriteTree_rtl.png
index b06afdb..6c30c35 100644
Binary files a/dijit/themes/nihilo/images/spriteTree_rtl.png and b/dijit/themes/nihilo/images/spriteTree_rtl.png differ
diff --git a/dijit/themes/nihilo/images/tabBottomActiveSpriteLR.gif b/dijit/themes/nihilo/images/tabBottomActiveSpriteLR.gif
deleted file mode 100644
index 6803db4..0000000
Binary files a/dijit/themes/nihilo/images/tabBottomActiveSpriteLR.gif and /dev/null differ
diff --git a/dijit/themes/nihilo/images/tabBottomEnabledSpriteLR.gif b/dijit/themes/nihilo/images/tabBottomEnabledSpriteLR.gif
deleted file mode 100644
index b6b08ce..0000000
Binary files a/dijit/themes/nihilo/images/tabBottomEnabledSpriteLR.gif and /dev/null differ
diff --git a/dijit/themes/nihilo/images/tabBottomHoverSpriteLR.gif b/dijit/themes/nihilo/images/tabBottomHoverSpriteLR.gif
deleted file mode 100644
index 010b08a..0000000
Binary files a/dijit/themes/nihilo/images/tabBottomHoverSpriteLR.gif and /dev/null differ
diff --git a/dijit/themes/nihilo/images/tabLeftChecked.gif b/dijit/themes/nihilo/images/tabLeftChecked.gif
deleted file mode 100644
index d59fd4a..0000000
Binary files a/dijit/themes/nihilo/images/tabLeftChecked.gif and /dev/null differ
diff --git a/dijit/themes/nihilo/images/tabRightChecked.gif b/dijit/themes/nihilo/images/tabRightChecked.gif
deleted file mode 100644
index d32f44e..0000000
Binary files a/dijit/themes/nihilo/images/tabRightChecked.gif and /dev/null differ
diff --git a/dijit/themes/nihilo/images/tabStripe.gif b/dijit/themes/nihilo/images/tabStripe.gif
deleted file mode 100644
index a934675..0000000
Binary files a/dijit/themes/nihilo/images/tabStripe.gif and /dev/null differ
diff --git a/dijit/themes/nihilo/images/tabStripeBottom.gif b/dijit/themes/nihilo/images/tabStripeBottom.gif
deleted file mode 100644
index 64c3376..0000000
Binary files a/dijit/themes/nihilo/images/tabStripeBottom.gif and /dev/null differ
diff --git a/dijit/themes/nihilo/images/tabStripeLeft.gif b/dijit/themes/nihilo/images/tabStripeLeft.gif
deleted file mode 100644
index d607a45..0000000
Binary files a/dijit/themes/nihilo/images/tabStripeLeft.gif and /dev/null differ
diff --git a/dijit/themes/nihilo/images/tabStripeRight.gif b/dijit/themes/nihilo/images/tabStripeRight.gif
deleted file mode 100644
index 9778ced..0000000
Binary files a/dijit/themes/nihilo/images/tabStripeRight.gif and /dev/null differ
diff --git a/dijit/themes/nihilo/images/titleBar.png b/dijit/themes/nihilo/images/titleBar.png
index 06ea21c..1e01962 100644
Binary files a/dijit/themes/nihilo/images/titleBar.png and b/dijit/themes/nihilo/images/titleBar.png differ
diff --git a/dijit/themes/nihilo/images/titleBarActive.png b/dijit/themes/nihilo/images/titleBarActive.png
index fe6c7a4..661bf59 100644
Binary files a/dijit/themes/nihilo/images/titleBarActive.png and b/dijit/themes/nihilo/images/titleBarActive.png differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorDown.png b/dijit/themes/nihilo/images/tooltipConnectorDown.png
index d75af71..7783f90 100644
Binary files a/dijit/themes/nihilo/images/tooltipConnectorDown.png and b/dijit/themes/nihilo/images/tooltipConnectorDown.png differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorLeft.png b/dijit/themes/nihilo/images/tooltipConnectorLeft.png
index f3de66a..ae16d36 100644
Binary files a/dijit/themes/nihilo/images/tooltipConnectorLeft.png and b/dijit/themes/nihilo/images/tooltipConnectorLeft.png differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorRight.png b/dijit/themes/nihilo/images/tooltipConnectorRight.png
index 3d62dcd..9532b17 100644
Binary files a/dijit/themes/nihilo/images/tooltipConnectorRight.png and b/dijit/themes/nihilo/images/tooltipConnectorRight.png differ
diff --git a/dijit/themes/nihilo/images/tooltipConnectorUp.png b/dijit/themes/nihilo/images/tooltipConnectorUp.png
index 7f7a5d8..2dc5b31 100644
Binary files a/dijit/themes/nihilo/images/tooltipConnectorUp.png and b/dijit/themes/nihilo/images/tooltipConnectorUp.png differ
diff --git a/dijit/themes/nihilo/images/treeHover.png b/dijit/themes/nihilo/images/treeHover.png
index ca80cd2..6a9e091 100644
Binary files a/dijit/themes/nihilo/images/treeHover.png and b/dijit/themes/nihilo/images/treeHover.png differ
diff --git a/dijit/themes/nihilo/images/validationInputBg.png b/dijit/themes/nihilo/images/validationInputBg.png
index f3039f9..ca0f890 100644
Binary files a/dijit/themes/nihilo/images/validationInputBg.png and b/dijit/themes/nihilo/images/validationInputBg.png differ
diff --git a/dijit/themes/nihilo/images/warning.png b/dijit/themes/nihilo/images/warning.png
index c52f83d..07cabea 100644
Binary files a/dijit/themes/nihilo/images/warning.png and b/dijit/themes/nihilo/images/warning.png differ
diff --git a/dijit/themes/nihilo/layout/TabContainer.css b/dijit/themes/nihilo/layout/TabContainer.css
index 2126657..dba38c3 100644
--- a/dijit/themes/nihilo/layout/TabContainer.css
+++ b/dijit/themes/nihilo/layout/TabContainer.css
@@ -1,9 +1,5 @@
 /**
  * dijit.layout.TabContainer
- *
- * To style TabContainer with rounded corners
- * you can use these classes: .dijitTab (left), .dijitTabContent (center), dijitTabInnerDiv (right)
- * For tabs aligned to top you can style a stripe div right underneath the tabs using .dijitTabStripe
  */
 @import url("../Menu.css");
 
@@ -28,54 +24,25 @@
 	padding: 0;
 }
 
-.nihilo .dijitTabInnerDiv {
-	padding:0 3px 0 0;
-	margin: 0 0 0 4px;
-	background: url("../images/tabContainerSprite.gif") no-repeat;
-	background-position: right -400px;
-}
-
 .nihilo .dijitTab {
+    padding:3px 6px 3px 4px;
+    background: url("../images/tabContainerSprite.gif") repeat-x 0 -350px;
+    position: relative;
 	line-height:normal;
-	margin:0 2px 0 0;	/* space between one tab and the next in top/bottom mode */
-	padding:0;
-	background: url("../images/tabContainerSprite.gif") no-repeat 0 -300px;
+	margin: 0 1px;	/* space between one tab and the next in top/bottom mode */
 	color: #6d6d6d;
+    border: 1px #dedede solid;
 	border-bottom: 1px #ccc solid;
 }
 
-.nihilo .dijitTabInnerDiv .dijitTabContent {
-	padding:3px 3px 3px 4px;
-	background: url("../images/tabContainerSprite.gif") repeat-x 0 -350px;
-	position: relative;
-}
-
 /* hovered tab */
 .nihilo .dijitTabHover {
 	color: #243C5F;
-	background: url("../images/tabContainerSprite.gif") no-repeat 0 -150px;
-}
-
-.nihilo .dijitTabHover .dijitTabInnerDiv {
-	background: url("../images/tabContainerSprite.gif") no-repeat right -250px;
-}
-
-.nihilo .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
 	background: url("../images/tabContainerSprite.gif") repeat-x 0 -200px;
 }
 
-/* checked tab*/
-.nihilo .dijitTabChecked
-{
-	/* the selected tab (with or without hover) */
-	background: url("../images/tabContainerSprite.gif") no-repeat 0 -0;
-}
-
-.nihilo .dijitTabChecked .dijitTabInnerDiv {
-	background: url("../images/tabContainerSprite.gif") no-repeat right -100px;
-}
-
-.nihilo .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
+/* selected tab */
+.nihilo .dijitTabChecked {
 	background: url("../images/tabContainerSprite.gif") repeat-x 0 -50px;
 	color: #243C5F !important;
 }
@@ -95,11 +62,7 @@
 	border: none;
 	top: 0;	/* override top:1px setting of top-level tabs */
 }
-.nihilo .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv,
-.nihilo .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
-	background: none;
-}
-.nihilo .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent .tabLabel {
+.nihilo .dijitTabContainerTabListNested .dijitTabHover .tabLabel {
 	text-decoration: underline;
 }
 .nihilo .dijitTabContainerTabListNested .dijitTabChecked .tabLabel {
@@ -142,6 +105,10 @@
 	background-position: bottom;
 	padding-left: 3px;
 }
+.nihilo .dijitTabContainerTop-tabs .dijitTab {
+    border-radius: 4px 4px 0 0;
+    -moz-border-radius: 4px 4px 0 0;
+}
 
 .dj_ie6 .nihilo .dijitTabListContainer-top,
 .dj_ie7 .nihilo .dijitTabListContainer-top {
@@ -163,7 +130,7 @@
 	border-top: none;
 }
 
-/* checked tabs */
+/* selected tab */
 .nihilo .dijitTabContainerTop-tabs .dijitTabChecked {
 	border-bottom-color: #f8f8f8;
 }
@@ -187,68 +154,43 @@
 	background-position: top;
 	padding-left: 3px;
 }
-
-.dj_ie6 .nihilo .dijitTabListContainer-bottom,
-.dj_ie7 .nihilo .dijitTabListContainer-bottom {
-	z-index: 3;
-}
-
-.dj_ie6 .nihilo .dijitTabContainerBottom-tabs,
-.dj_ie7 .nihilo .dijitTabContainerBottom-tabs {
-	border-top: 1px solid #ccc;
-	margin-top: -1px;
-}
-
-/* bottom container */
-.nihilo .dijitTabContainerBottom-container {
-	border-bottom: none;
-}
-
 .nihilo .dijitTabContainerBottom-tabs .dijitTab {
-	border-bottom: none;
-	border-top: 1px solid #ccc;
-	background: url("../images/tabBottomEnabledSpriteLR.gif") no-repeat bottom left;
-}
-
-/* checked tabs */
-.nihilo .dijitTabContainerBottom-tabs .dijitTabChecked {
-	border-top-color: #f8f8f8;
-}
-
-.nihilo .dijitTabContainerBottom-tabs .dijitTabInnerDiv .dijitTabContent {
-	padding-top: 3px;
-	padding-bottom: 3px;
-	background: url("../images/tabBottomEnabledC.gif") repeat-x bottom left;
+    border-radius: 0 0 4px 4px;
+    -moz-border-radius: 0 0 4px 4px;
+    border-bottom: none;
+    border-top: 1px solid #ccc;
+    padding-top: 3px;
+    padding-bottom: 3px;
+    background: url("../images/tabBottomEnabledC.gif") repeat-x bottom left;
 }
 
-.nihilo .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
-	background: url("../images/tabBottomEnabledSpriteLR.gif") no-repeat bottom right;
-}
 
 .nihilo .dijitTabContainerBottom-tabs .dijitTabHover {
 	color: #243C5F;
-	background: url("../images/tabBottomHoverSpriteLR.gif") no-repeat bottom left;
-}
-
-.nihilo .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv {
-	background: url("../images/tabBottomHoverSpriteLR.gif") no-repeat bottom right;
-}
-
-.nihilo .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
 	background: url("../images/tabBottomHoverC.gif") repeat-x bottom left;
 }
 
 .nihilo .dijitTabContainerBottom-tabs .dijitTabChecked {
 	/* the selected tab (with or without hover) */
-	background: url("../images/tabBottomActiveSpriteLR.gif") no-repeat bottom left;
+    border-top-color: #f8f8f8;
+	background: url("../images/tabBottomActiveC.gif") repeat-x bottom left;
 }
 
-.nihilo .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv {
-	background: url("../images/tabBottomActiveSpriteLR.gif") no-repeat bottom right;
+
+.dj_ie6 .nihilo .dijitTabListContainer-bottom,
+.dj_ie7 .nihilo .dijitTabListContainer-bottom {
+	z-index: 3;
 }
 
-.nihilo .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
-	background: url("../images/tabBottomActiveC.gif") repeat-x bottom left;
+.dj_ie6 .nihilo .dijitTabContainerBottom-tabs,
+.dj_ie7 .nihilo .dijitTabContainerBottom-tabs {
+	border-top: 1px solid #ccc;
+	margin-top: -1px;
+}
+
+/* bottom container */
+.nihilo .dijitTabContainerBottom-container {
+	border-bottom: none;
 }
 
 /* strip */
@@ -264,14 +206,15 @@
 .nihilo .dijitTabContainerTop-spacer {
 	height: 2px;
 	border: 1px solid #ccc;
-	background: #f8f8f8;
 }
 
 .nihilo  .dijitTabContainerTop-spacer {
 	margin-top: -1px;
+    background: #f3f3f3;
 }
 .nihilo .dijitTabContainerBottom-spacer {
 	margin-bottom: -1px;
+    background: #f8f8f8;
 }
 
 
@@ -281,49 +224,42 @@
 	border-color: #ccc;
 	padding-top: 3px;
 }
+.nihilo .dijitTabContainerRight-tabs .dijitTab {
+    border-radius: 0 4px 4px 0;
+    -moz-border-radius: 0 4px 4px 0;
+    border-left: 1px solid #ccc;
+    border-bottom: 1px solid #dedede !important;
+}
+
 .nihilo .dijitTabContainerRight .dijitTabListWrapper {
 	padding-right: 3px;
 }
+.nihilo .dijitTabContainerRight-tabs .dijitTabChecked {
+	border-left: 1px solid #f8f8f8;
+}
+
 
 /* right container */
 .nihilo .dijitTabContainerRight-container {
 	border-right: none;
 }
 
-.nihilo .dijitTabContainerRight-tabs .dijitTab {
-	border-bottom: none;
-	border-left: 1px solid #ccc;
-	border-bottom: 1px solid #dedede !important;
-}
-
-
-/* some odd ie bug when borders dissapear when setting a bottom margin, this sortof helps */
-.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTabInnerDiv {
+/* some odd ie bug when borders disappear when setting a bottom margin, this sort of helps */
+.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTab {
 	border-bottom: solid #fff 1px;
 }
 
-/* checked tabs */
+/* selected tab */
 .nihilo .dijitTabContainerRight-tabs .dijitTabChecked {
 	border-left-color: #f8f8f8;
 }
 
-.nihilo .dijitTabContainerRight-tabs .dijitTabChecked {
-	background: url("../images/tabRightChecked.gif") no-repeat left top !important;
-}
-
-/* some odd ie bug when borders dissapear when setting a bottom margin, this sortof helps */
-.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabInnerDiv,
-.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+/* some odd ie bug when borders disappear when setting a bottom margin, this sort of helps */
+.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTabChecked,
+.dj_ie .nihilo .dijitTabContainerRight-tabs .dijitTabCheckedHover {
 	border-bottom: solid #efefef 1px;
 }
 
-.nihilo .dijitTabContainerRight-tabs .dijitTab {
-	background: url("../images/tabContainerSprite.gif") no-repeat left -350px;
-}
-.nihilo .dijitTabContainerRight-tabs .dijitTabHover .dijitTab {
-	background: url("../images/tabContainerSprite.gif") no-repeat left -200px;
-}
-
 /* strip */
 .nihilo .dijitTabContainerRightStrip {
 	padding-right: 2px;
@@ -338,35 +274,26 @@
 	border-color: #ccc;
 	padding-top: 3px;
 }
-
-/* left conatiner */
-.nihilo .dijitTabContainerLeft-container {
-	border-left: none;
-}
-
 .nihilo .dijitTabContainerLeft-tabs .dijitTab {
-	border-right: 1px solid #ccc;
-	border-bottom: 1px solid #dedede;
+    border-radius: 4px 0 0 4px;
+    -moz-border-radius: 4px 0 0 4px;
+    border-right: 1px solid #ccc;
+    border-bottom: 1px solid #dedede;
 }
 
-/* checked tabs */
+/* selected tab */
 .nihilo .dijitTabContainerLeft-tabs .dijitTabChecked {
 	border-right: 1px solid #f8f8f8;
 }
 
-.nihilo .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
-	background: url("../images/tabContainerSprite.gif") no-repeat right -350px;
-}
-.nihilo .dijitTabContainerLeft-tabs .dijitTabHover .dijitTabInnerDiv {
-	background: url("../images/tabContainerSprite.gif") no-repeat right -200px;
-}
-.nihilo .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
-.nihilo .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
-	background: url("../images/tabLeftChecked.gif") no-repeat right top;
+/* left container */
+.nihilo .dijitTabContainerLeft-container {
+	border-left: none;
 }
 
-.dj_ie .nihilo .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
-.dj_ie .nihilo .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+
+.dj_ie .nihilo .dijitTabContainerLeft-tabs .dijitTabChecked,
+.dj_ie .nihilo .dijitTabContainerLeft-tabs .dijitTabCheckedHover {
 	border-bottom: solid #efefef 1px;
 }
 
@@ -389,8 +316,7 @@
 /* left/right tabs */
 .nihilo .dijitTabContainerLeft-tabs .dijitTab,
 .nihilo .dijitTabContainerRight-tabs .dijitTab {
-	margin-right:auto;
-	margin-bottom:2px;	/* space between one tab and the next in left/right mode */
+	margin: 1px 0;	/* space between one tab and the next in left/right mode */
 }
 
 /* left/right tabstrip */
@@ -419,7 +345,7 @@
 
 /* ================================ */
 
-/* this resets the tabcontainer stripe when within a contentpane */
+/* this resets the tabcontainer strip when within a contentpane */
 .nihilo .dijitTabContainerTop-dijitContentPane .dijitTabContainerTop-tabs {
 	border-left: 0 solid #ccc;
 	border-top: 0 solid #ccc;
@@ -433,10 +359,7 @@
 /* Menu and slider control styles */
 .nihilo .dijitTabContainer .tabStripButton {
 	margin-right: 0;
-}
-
-.nihilo .tabStripButton .dijitTabInnerDiv .dijitTabContent {
-	padding: 5px 0 6px;
+	padding: 5px 3px 6px 0px;
 }
 
 .dj_ie6 .nihilo .tabStripButton .dijitTabInnerDiv .dijitTabContent,
@@ -445,10 +368,6 @@
 	padding-bottom: 7px;
 }
 
-.nihilo .tabStrip-disabled .tabStripButton .dijitTabInnerDiv .dijitTabContent {
-	padding: 3px 0 5px;
-}
-
 .dj_ie6 .nihilo .tabStrip-disabled .tabStripButton .dijitTabInnerDiv .dijitTabContent,
 .dj_ie7 .nihilo .tabStrip-disabled .tabStripButton .dijitTabInnerDiv .dijitTabContent,
 .dj_opera .nihilo .tabStrip-disabled .tabStripButton .dijitTabInnerDiv .dijitTabContent {
@@ -482,15 +401,6 @@
 }
 
 .nihilo .dijitTabContainer .tabStripButton-bottom {
-	background: transparent url(../images/tabBottomEnabledSpriteLR.gif) no-repeat scroll left bottom;
 	border-bottom: medium none;
 	border-top: 1px solid #CCCCCC;
 }
-
-.nihilo .dijitTabContainer .tabStripButton-bottom .dijitTabInnerDiv {
-	background: transparent url(../images/tabBottomEnabledSpriteLR.gif) no-repeat scroll right bottom;
-}
-
-.nihilo .dijitTabContainer .tabStripButton-bottom .dijitTabContent {
-	background: transparent;
-}
\ No newline at end of file
diff --git a/dijit/themes/nihilo/nihilo_rtl.css b/dijit/themes/nihilo/nihilo_rtl.css
index 1e9a6af..5c32ade 100644
--- a/dijit/themes/nihilo/nihilo_rtl.css
+++ b/dijit/themes/nihilo/nihilo_rtl.css
@@ -24,6 +24,7 @@
 @import url("Calendar_rtl.css");
 @import url("TimePicker_rtl.css");
 @import url("Dialog_rtl.css");
+ at import url("ProgressBar_rtl.css");
 @import url("Menu_rtl.css");
 @import url("Editor_rtl.css");
 @import url("../../icons/editorIcons_rtl.css");/* RTL sprite for editor icons to be used by all themes*/
\ No newline at end of file
diff --git a/dijit/themes/soria/Common.css b/dijit/themes/soria/Common.css
index d5a7c9d..93efae7 100644
--- a/dijit/themes/soria/Common.css
+++ b/dijit/themes/soria/Common.css
@@ -1,16 +1,15 @@
-/* DnD avatar-specific settings */
-/* For now it uses a default set of rules. Some other DnD classes can be modified as well. */
-.soria .dojoDndItemBefore {
-	border-top: 2px solid #369;
+/* DnD hovered and selected node(s) */
+.soria .dojoDndItemOver {
+	background-image: url(images/treeHover.png);
 }
-
-.soria .dojoDndItemAfter {
-	border-bottom: 2px solid #369;
+.soria .dojoDndItemAnchor,
+.soria .dojoDndItemSelected {
+	background-color: #B8CBEC;
 }
 
-.soria .dojoDndItemOver {
-	cursor:pointer;
-}
+
+/* DnD avatar-specific settings */
+/* For now it uses a default set of rules. Some other DnD classes can be modified as well. */
 
 .soria table.dojoDndAvatar { -moz-border-radius: 0; border: 1px solid #ccc; border-collapse: collapse; background-color: #fff; font-size: 75%; color: black;}
 .soria .dojoDndAvatar td	{ border: none; }
diff --git a/dijit/themes/soria/Dialog.css b/dijit/themes/soria/Dialog.css
index 1e0503a..956df8d 100644
--- a/dijit/themes/soria/Dialog.css
+++ b/dijit/themes/soria/Dialog.css
@@ -67,15 +67,7 @@
 }
 
 .soria .dijitTooltipContainer {
-	/*
-		The part with the text.
-
-		NOTE:
-			FF doesn't clip images used as CSS bgs if you specify a border
-			radius. If you use a solid color, it does. Webkit gets it right.
-			Sigh.
-		background: #ffffff url("images/popupMenuBg.gif") repeat-x bottom left;
-	*/
+	/* The part with the text. */
 	background-color: #fff;
 	border:1px solid #cbcbcb;
 	padding:0.45em;
diff --git a/dijit/themes/soria/Menu.css b/dijit/themes/soria/Menu.css
index 4d9d068..d2dffd2 100644
--- a/dijit/themes/soria/Menu.css
+++ b/dijit/themes/soria/Menu.css
@@ -29,6 +29,7 @@
 }
 
 .soria .dijitMenuPassive .dijitMenuItemHover,
+.soria .dijitComboBoxMenu .dijitMenuItemHover,
 .soria .dijitMenuItemSelected {
 	background-color: #d9e6f9; /* #95a0b0; #555555; #aaaaaa; #646464;  #60a1ea; #848484; */
 	color: #243C5F;
@@ -63,15 +64,17 @@
 }
 
 /* the checked menu item */
-.soria .dijitCheckedMenuItemIconChar {
-	display: none;
-}
-
-.soria .dijitCheckedMenuItemIcon {
+.soria .dijitCheckedMenuItem .dijitMenuItemIcon  {
 	background-image: url('images/spriteCheckbox.gif');
 	background-position: -80px;
 }
-
-.soria .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
+.soria .dijitCheckedMenuItemChecked .dijitMenuItemIcon {
+	background-position: -64px;
+}
+.soria .dijitRadioMenuItem .dijitMenuItemIcon {
+	background-image: url('images/spriteRadio.gif');
+	background-position: -80px;
+}
+.soria .dijitRadioMenuItemChecked .dijitMenuItemIcon {
 	background-position: -64px;
 }
\ No newline at end of file
diff --git a/dijit/themes/soria/ProgressBar.css b/dijit/themes/soria/ProgressBar.css
index b2f6d1f..19ad2fa 100644
--- a/dijit/themes/soria/ProgressBar.css
+++ b/dijit/themes/soria/ProgressBar.css
@@ -19,7 +19,8 @@
 }
 
 .soria .dijitProgressBarFull {
-	border-right:1px solid #8ba0bd;
+	border: 0px solid #8ba0bd;
+	border-right-width: 1px;
 }
 
 .soria .dijitProgressBarLabel {
diff --git a/dijit/themes/soria/ProgressBar_rtl.css b/dijit/themes/soria/ProgressBar_rtl.css
new file mode 100644
index 0000000..f432a8f
--- /dev/null
+++ b/dijit/themes/soria/ProgressBar_rtl.css
@@ -0,0 +1,9 @@
+
+/****
+		dijit.ProgressBar
+ ****/
+
+.soria  .dijitProgressBarRtl .dijitProgressBarFull {
+	border-left-width: 1px;
+	border-right: 0px;
+}
diff --git a/dijit/themes/soria/TimePicker.css b/dijit/themes/soria/TimePicker.css
index 757d746..e2f827c 100644
--- a/dijit/themes/soria/TimePicker.css
+++ b/dijit/themes/soria/TimePicker.css
@@ -5,7 +5,7 @@
 }
 
 .soria .dijitTimePickerTick {
-	color:white;
+	color: gray;
 }
 
 .soria .dijitTimePickerMarker {
@@ -24,28 +24,10 @@
 	color:white;
 }
 
-.soria .dijitTimePickerItemHover,
-.soria .dijitTimePickerItemSelected {
-	position: relative;
-	z-index: 10;
-}
-
 .soria .dijitTimePickerTick .dijitTimePickerItemInner {
-	font-size:0.4em;
+	font-size: 0.8em;
 }
 
-.soria .dijitTimePickerItemHover .dijitTimePickerItemInner,
 .soria .dijitTimePickerItemSelected .dijitTimePickerItemInner {
-	font-size:1em;
-}
-
-.soria .dijitTimePickerMarkerHover {
-	border-top: 1px solid #94b9ef;
-}
-
-.soria .dijitTimePickerTickHover,
-.soria .dijitTimePickerTickSelected {
-	margin-top:-0.3em;
-	margin-bottom:-0.3em;
-	border-bottom: none;
-}
+	font-size: 1em;
+}
\ No newline at end of file
diff --git a/dijit/themes/soria/TitlePane.css b/dijit/themes/soria/TitlePane.css
index 7e1042e..ad7f4e9 100644
--- a/dijit/themes/soria/TitlePane.css
+++ b/dijit/themes/soria/TitlePane.css
@@ -1,5 +1,5 @@
 /**
- * dijit.TitlePane
+ * dijit.TitlePane and dijit.Fieldset
  *
  */
 
@@ -20,8 +20,8 @@
 	vertical-align: middle;
 }
 
-.soria .dijitTitlePane .dijitOpen .dijitArrowNode,
-.soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+.soria .dijitTitlePane .dijitArrowNode,
+.soria .dijitFieldset .dijitArrowNode {
 	width:15px;
 	height:15px;
 }
@@ -30,16 +30,16 @@
 	color: #243C5F;
 }
 
-.soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+.soria .dijitTitlePane .dijitClosed .dijitArrowNode, .soria .dijitFieldset .dijitFieldsetTitleClosed .dijitArrowNode {
 	background: url('images/spriteRoundedIconsSmall.png') no-repeat -30px top;
 }
-.dj_ie6 .soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+.dj_ie6 .soria .dijitTitlePane .dijitClosed .dijitArrowNode, .dj_ie6 .soria .dijitFieldset .dijitFieldsetTitleClosed .dijitArrowNode {
 	background:url('images/spriteRoundedIconsSmall.gif') no-repeat -30px top;
 }
-.soria .dijitTitlePane .dijitOpen .dijitArrowNode {
+.soria .dijitTitlePane .dijitOpen .dijitArrowNode, .soria .dijitFieldset .dijitFieldsetTitleOpen .dijitArrowNode {
 	background:url('images/spriteRoundedIconsSmall.png') no-repeat -15px top;
 }
-.dj_ie6 .soria .dijitTitlePane .dijitOpen .dijitArrowNode {
+.dj_ie6 .soria .dijitTitlePane .dijitOpen .dijitArrowNode, .dj_ie6 .soria .dijitFieldset .dijitFieldsetTitleClosed .dijitArrowNode {
 	background:url('images/spriteRoundedIconsSmall.gif') no-repeat -15px top;
 }
 
diff --git a/dijit/themes/soria/TitlePane_rtl.css b/dijit/themes/soria/TitlePane_rtl.css
index 8a1b73d..5252264 100644
--- a/dijit/themes/soria/TitlePane_rtl.css
+++ b/dijit/themes/soria/TitlePane_rtl.css
@@ -1,6 +1,3 @@
-.dijitRtl .soria .dijitTitlePane .dijitClosed .dijitArrowNode {
-	background-position: 0 top;
-}
-.dj_ie6-rtl .soria .dijitTitlePane .dijitClosed .dijitArrowNode {
+.soria .dijitTitlePaneRtl .dijitClosed .dijitArrowNode, .soria .dijitFieldsetRtl .dijitFieldsetTitleClosed .dijitArrowNode {
 	background-position: 0 top;
 }
\ No newline at end of file
diff --git a/dijit/themes/soria/form/Button.css b/dijit/themes/soria/form/Button.css
index 9efe7ea..e00c48f 100644
--- a/dijit/themes/soria/form/Button.css
+++ b/dijit/themes/soria/form/Button.css
@@ -14,14 +14,14 @@
 	padding: 0.1em 0.2em 0.2em 0.2em;
 	background: #bcd5f0 url("../images/buttonEnabled.png") repeat-x top left;
 }
-.soria .dijitSelect .dijitButtonContents {
-	border-right: none;
-}
 
 .soria .dijitButtonText {
 	text-align: center;
 	padding: 0 0.3em;
 }
+.soria .dijitInputField {
+	padding: 0; /* set padding:0 for .soria .dijitSelect .dijitButtonText but with a low priority rule that can be easily trumped by the user */
+}
 
 .soria .dijitArrowButton {
 	color: #111;
diff --git a/dijit/themes/soria/form/Button_rtl.css b/dijit/themes/soria/form/Button_rtl.css
index e2f3728..cf47470 100644
--- a/dijit/themes/soria/form/Button_rtl.css
+++ b/dijit/themes/soria/form/Button_rtl.css
@@ -1,7 +1,3 @@
-.dijitRtl .soria .dijitComboBox .dijitButtonNode {
+.soria .dijitComboBoxRtl .dijitButtonNode {
 	border-width: 0 0 0 1px;
 }
-.dijitRtl .soria .dijitSelect .dijitButtonContents {
-	border-left: none;
-	border-right-width: 1px;
-}
diff --git a/dijit/themes/soria/form/Common.css b/dijit/themes/soria/form/Common.css
index 42dfefa..d6ea6e2 100644
--- a/dijit/themes/soria/form/Common.css
+++ b/dijit/themes/soria/form/Common.css
@@ -10,11 +10,12 @@
 		dijit.form.ComboBox (partial)
  ****/
 
-.soria .dijitInputContainer input,
-.soria .dijitTextBox {
+.soria .dijitInputContainer input {
 	margin: 0 0.1em;
 }
 
+.soria .dijitSelect .dijitButtonContents,
+.soria .dijitSelect,
 .soria .dijitTextBox,
 .soria .dijitTextArea {
 	/* 	For all except dijit.form.NumberSpinner:  the actual input element.
@@ -23,26 +24,35 @@
 	*/
 	background:#fff url("../images/validationInputBg.png") repeat-x top left;
 	#background:#fff url('../images/validationInputBg.gif') repeat-x top left;
+}
+.soria .dijitSelect,
+.soria .dijitTextBox,
+.soria .dijitTextArea {
 	border:1px solid #8ba0bd;
 }
 
+.soria .dijitSelect .dijitArrowButton,
 .soria .dijitComboBox .dijitButtonNode {
 	padding: 0 0.2em;
 }
+
+.soria .dijitSelect .dijitButtonContents,
 .soria .dijitTextBox .dijitButtonNode {
 	/* line between the input area and the drop down button */
 	border-color: #8ba0bd;
 }
 
+.soria .dijitSelectFocused,
 .soria .dijitTextBoxFocused,
 .soria .dijitTextAreaFocused {
 	/* input field when focused (ie: typing affects it) */
 	border-color:#406b9b;
 }
+.soria .dijitSelectFocused TD,
 .soria .dijitTextBoxFocused .dijitButtonNode,
 .soria .dijitSpinner .dijitUpArrowButtonActive,
 .soria .dijitSpinner .dijitDownArrowButtonActive {
-	border-left-color:#8ba0bd;
+	border-color:#8ba0bd;
 }
 .soria .dijitSpinnerFocused .dijitDownArrowButton,
 .soria .dijitSpinner .dijitUpArrowButtonActive,
@@ -62,7 +72,7 @@
 }
 
 /* Validation errors  */
-.soria .dijitValidationIcon {
+.soria .dijitValidationTextBoxError .dijitValidationIcon {
 	/* prevent height change when widget goes from valid to invalid state */
 	width: 16px;
 	background: transparent url('../images/warning.png') no-repeat center center;
diff --git a/dijit/themes/soria/form/Select.css b/dijit/themes/soria/form/Select.css
index 1856772..895ab7e 100644
--- a/dijit/themes/soria/form/Select.css
+++ b/dijit/themes/soria/form/Select.css
@@ -1,46 +1,40 @@
-.soria .dijitSelect .dijitButtonNode {
-	padding: 0;
-}
-
 /* Make unselected "look" more like a text box and less like a button */
-.soria .dijitSelect .dijitButtonContents {
-	padding-top: 1px;
-    background:#fff url("../images/validationInputBg.png") repeat-x top left;
-    #background:#fff url('../images/validationInputBg.gif') repeat-x top left;
-}
-.soria .dijitSelectHover .dijitButtonContents,
-.soria .dijitSelectActive .dijitButtonContents,
-.soria .dijitSelectOpened .dijitButtonContents,
-.soria .dijitSelectDisabled .dijitButtonContents,
-.soria .dijitSelectReadOnly .dijitButtonContents{
+.soria .dijitSelectError .dijitButtonContents,
+.soria .dijitSelectHover .dijitArrowButton,
+.soria .dijitSelectActive .dijitArrowButton,
+.soria .dijitSelectOpened .dijitArrowButton,
+.soria .dijitSelectDisabled .dijitArrowButton,
+.soria .dijitSelectReadOnly .dijitArrowButton {
 	background: transparent none;
 }
-.dj_ie .soria .dijitSelect .dijitButtonContents {
-	padding-top: 0;
-}
-
 .soria .dijitSelect .dijitArrowButton {
-	padding: 0 2px;
+	background: #bcd5f0 url("../images/buttonEnabled.png") repeat-x top left;
+	border-width: 0;
 }
 
 /* Mirror DropDownButton */
-.soria .dijitSelectDisabled .dijitButtonNode {
-    border-color: #b9bbdd #b9bbdd #b9bbdd #b9bbdd;
-    background:#c3d3e5 url("../images/buttonDisabled.png") top repeat-x;
+.soria .dijitSelectDisabled,
+.soria .dijitSelectDisabled TD {
+	border-color: #b9bbdd !important;
+	background:#c3d3e5 url("../images/buttonDisabled.png") top repeat-x;
 }
-.dj_ie .soria .dijitSelectDisabled  .dijitButtonNode * {
+.dj_ie .soria .dijitSelectDisabled TD * {
 	filter: gray() alpha(opacity=50);
 }
 
-.soria .dijitSelectHover .dijitButtonNode {
-    color:#000;
-    background:#acc5e2 url("../images/buttonHover.png") repeat-x top left;
+.soria .dijitSelectHover,
+.soria .dijitSelectHover TD {
+	border-color:#a5beda #5c7590 #5c7590 #a5beda !important;
+	color:#000;
+	background:#acc5e2 url("../images/buttonHover.png") repeat-x top left;
 }
 
-.soria .dijitSelectActive .dijitButtonNode,
-.soria .dijitSelectOpened .dijitButtonNode {
-    border-color:#657c9c;
-    background: #91b4e5 url("../images/buttonActive.png") top left repeat-x;
+.soria .dijitSelectActive,
+.soria .dijitSelectOpened,
+.soria .dijitSelectActive TD,
+.soria .dijitSelectOpened TD {
+	border-color:#657c9c !important;
+	background: #91b4e5 url("../images/buttonActive.png") top left repeat-x;
 }
 
 /* Make the menu look more combobox-like */
@@ -51,4 +45,3 @@
 .soria .dijitSelectMenu .dijitMenuArrowCell {
 	padding: 0.1em 0.2em;
 }
-
diff --git a/dijit/themes/soria/form/TimeTextBox.css b/dijit/themes/soria/form/TimeTextBox.css
index bf67b66..d450925 100644
--- a/dijit/themes/soria/form/TimeTextBox.css
+++ b/dijit/themes/soria/form/TimeTextBox.css
@@ -1 +1 @@
- at CHARSET "UTF-8";
\ No newline at end of file
+ at CHARSET "UTF-8";
diff --git a/dijit/themes/soria/images/accordionItemActive.png b/dijit/themes/soria/images/accordionItemActive.png
index 92c7431..789bcfa 100644
Binary files a/dijit/themes/soria/images/accordionItemActive.png and b/dijit/themes/soria/images/accordionItemActive.png differ
diff --git a/dijit/themes/soria/images/buttonActive.png b/dijit/themes/soria/images/buttonActive.png
index f815983..4f318a6 100644
Binary files a/dijit/themes/soria/images/buttonActive.png and b/dijit/themes/soria/images/buttonActive.png differ
diff --git a/dijit/themes/soria/images/buttonDisabled.png b/dijit/themes/soria/images/buttonDisabled.png
index f76e4ab..e1e9cd4 100644
Binary files a/dijit/themes/soria/images/buttonDisabled.png and b/dijit/themes/soria/images/buttonDisabled.png differ
diff --git a/dijit/themes/soria/images/buttonEnabled.png b/dijit/themes/soria/images/buttonEnabled.png
index 3c55c83..51ac91e 100644
Binary files a/dijit/themes/soria/images/buttonEnabled.png and b/dijit/themes/soria/images/buttonEnabled.png differ
diff --git a/dijit/themes/soria/images/buttonHover.png b/dijit/themes/soria/images/buttonHover.png
index a22ebda..61a6cd6 100644
Binary files a/dijit/themes/soria/images/buttonHover.png and b/dijit/themes/soria/images/buttonHover.png differ
diff --git a/dijit/themes/soria/images/dndCopy.png b/dijit/themes/soria/images/dndCopy.png
index baecd7c..6a8b998 100644
Binary files a/dijit/themes/soria/images/dndCopy.png and b/dijit/themes/soria/images/dndCopy.png differ
diff --git a/dijit/themes/soria/images/dndMove.png b/dijit/themes/soria/images/dndMove.png
index 07f878c..8443d30 100644
Binary files a/dijit/themes/soria/images/dndMove.png and b/dijit/themes/soria/images/dndMove.png differ
diff --git a/dijit/themes/soria/images/dndNoCopy.png b/dijit/themes/soria/images/dndNoCopy.png
index 9bf9c33..64bf88b 100644
Binary files a/dijit/themes/soria/images/dndNoCopy.png and b/dijit/themes/soria/images/dndNoCopy.png differ
diff --git a/dijit/themes/soria/images/dndNoMove.png b/dijit/themes/soria/images/dndNoMove.png
index cb8bd8b..682ea10 100644
Binary files a/dijit/themes/soria/images/dndNoMove.png and b/dijit/themes/soria/images/dndNoMove.png differ
diff --git a/dijit/themes/soria/images/preciseSliderThumb.png b/dijit/themes/soria/images/preciseSliderThumb.png
index 045bf35..d6dc079 100644
Binary files a/dijit/themes/soria/images/preciseSliderThumb.png and b/dijit/themes/soria/images/preciseSliderThumb.png differ
diff --git a/dijit/themes/soria/images/preciseSliderThumbFocus.png b/dijit/themes/soria/images/preciseSliderThumbFocus.png
index c235849..939f253 100644
Binary files a/dijit/themes/soria/images/preciseSliderThumbFocus.png and b/dijit/themes/soria/images/preciseSliderThumbFocus.png differ
diff --git a/dijit/themes/soria/images/progressBarEmpty.png b/dijit/themes/soria/images/progressBarEmpty.png
index 04d81df..c6090e0 100644
Binary files a/dijit/themes/soria/images/progressBarEmpty.png and b/dijit/themes/soria/images/progressBarEmpty.png differ
diff --git a/dijit/themes/soria/images/progressBarFull.png b/dijit/themes/soria/images/progressBarFull.png
index bed17b3..0cedfe3 100644
Binary files a/dijit/themes/soria/images/progressBarFull.png and b/dijit/themes/soria/images/progressBarFull.png differ
diff --git a/dijit/themes/soria/images/sliderEmpty.png b/dijit/themes/soria/images/sliderEmpty.png
index 99fbd72..bdd9ae9 100644
Binary files a/dijit/themes/soria/images/sliderEmpty.png and b/dijit/themes/soria/images/sliderEmpty.png differ
diff --git a/dijit/themes/soria/images/sliderEmptyVertical.png b/dijit/themes/soria/images/sliderEmptyVertical.png
index 2d497e3..7b5036a 100644
Binary files a/dijit/themes/soria/images/sliderEmptyVertical.png and b/dijit/themes/soria/images/sliderEmptyVertical.png differ
diff --git a/dijit/themes/soria/images/sliderFull.png b/dijit/themes/soria/images/sliderFull.png
index 171eb54..d969658 100644
Binary files a/dijit/themes/soria/images/sliderFull.png and b/dijit/themes/soria/images/sliderFull.png differ
diff --git a/dijit/themes/soria/images/sliderFullFocus.png b/dijit/themes/soria/images/sliderFullFocus.png
index 0956a72..99326af 100644
Binary files a/dijit/themes/soria/images/sliderFullFocus.png and b/dijit/themes/soria/images/sliderFullFocus.png differ
diff --git a/dijit/themes/soria/images/sliderFullVertical.png b/dijit/themes/soria/images/sliderFullVertical.png
index 35845da..14cacba 100644
Binary files a/dijit/themes/soria/images/sliderFullVertical.png and b/dijit/themes/soria/images/sliderFullVertical.png differ
diff --git a/dijit/themes/soria/images/sliderFullVerticalFocus.png b/dijit/themes/soria/images/sliderFullVerticalFocus.png
index 9b158bb..0316b79 100644
Binary files a/dijit/themes/soria/images/sliderFullVerticalFocus.png and b/dijit/themes/soria/images/sliderFullVerticalFocus.png differ
diff --git a/dijit/themes/soria/images/sliderThumb.png b/dijit/themes/soria/images/sliderThumb.png
index b6abbd2..6abb200 100644
Binary files a/dijit/themes/soria/images/sliderThumb.png and b/dijit/themes/soria/images/sliderThumb.png differ
diff --git a/dijit/themes/soria/images/sliderThumbFocus.png b/dijit/themes/soria/images/sliderThumbFocus.png
index 73ee705..c4d261e 100644
Binary files a/dijit/themes/soria/images/sliderThumbFocus.png and b/dijit/themes/soria/images/sliderThumbFocus.png differ
diff --git a/dijit/themes/soria/images/splitContainerSizerH-thumb.png b/dijit/themes/soria/images/splitContainerSizerH-thumb.png
index 0e8f397..65b5e03 100644
Binary files a/dijit/themes/soria/images/splitContainerSizerH-thumb.png and b/dijit/themes/soria/images/splitContainerSizerH-thumb.png differ
diff --git a/dijit/themes/soria/images/splitContainerSizerH.png b/dijit/themes/soria/images/splitContainerSizerH.png
index 7cdf79a..6030e0f 100644
Binary files a/dijit/themes/soria/images/splitContainerSizerH.png and b/dijit/themes/soria/images/splitContainerSizerH.png differ
diff --git a/dijit/themes/soria/images/splitContainerSizerV-thumb.png b/dijit/themes/soria/images/splitContainerSizerV-thumb.png
index 7f12fed..848400f 100644
Binary files a/dijit/themes/soria/images/splitContainerSizerV-thumb.png and b/dijit/themes/soria/images/splitContainerSizerV-thumb.png differ
diff --git a/dijit/themes/soria/images/splitContainerSizerV.png b/dijit/themes/soria/images/splitContainerSizerV.png
index 9ff14d6..1cfba5f 100644
Binary files a/dijit/themes/soria/images/splitContainerSizerV.png and b/dijit/themes/soria/images/splitContainerSizerV.png differ
diff --git a/dijit/themes/soria/images/spriteArrows.png b/dijit/themes/soria/images/spriteArrows.png
index 73aa700..80bb45a 100644
Binary files a/dijit/themes/soria/images/spriteArrows.png and b/dijit/themes/soria/images/spriteArrows.png differ
diff --git a/dijit/themes/soria/images/spriteCheckbox.png b/dijit/themes/soria/images/spriteCheckbox.png
index e992330..03d1aa9 100644
Binary files a/dijit/themes/soria/images/spriteCheckbox.png and b/dijit/themes/soria/images/spriteCheckbox.png differ
diff --git a/dijit/themes/soria/images/spriteDivIcons.png b/dijit/themes/soria/images/spriteDivIcons.png
index d76325f..043882e 100644
Binary files a/dijit/themes/soria/images/spriteDivIcons.png and b/dijit/themes/soria/images/spriteDivIcons.png differ
diff --git a/dijit/themes/soria/images/spriteRadio.png b/dijit/themes/soria/images/spriteRadio.png
index 14c1080..eef7ab4 100644
Binary files a/dijit/themes/soria/images/spriteRadio.png and b/dijit/themes/soria/images/spriteRadio.png differ
diff --git a/dijit/themes/soria/images/spriteRoundedIconsSmall.png b/dijit/themes/soria/images/spriteRoundedIconsSmall.png
index 10c0d13..7eda875 100644
Binary files a/dijit/themes/soria/images/spriteRoundedIconsSmall.png and b/dijit/themes/soria/images/spriteRoundedIconsSmall.png differ
diff --git a/dijit/themes/soria/images/spriteRoundedIconsSmallBl.png b/dijit/themes/soria/images/spriteRoundedIconsSmallBl.png
index 2c9f51a..74b8c93 100644
Binary files a/dijit/themes/soria/images/spriteRoundedIconsSmallBl.png and b/dijit/themes/soria/images/spriteRoundedIconsSmallBl.png differ
diff --git a/dijit/themes/soria/images/spriteTree.png b/dijit/themes/soria/images/spriteTree.png
index 33ae07b..4e63248 100644
Binary files a/dijit/themes/soria/images/spriteTree.png and b/dijit/themes/soria/images/spriteTree.png differ
diff --git a/dijit/themes/soria/images/spriteTree_rtl.png b/dijit/themes/soria/images/spriteTree_rtl.png
index b06afdb..6c30c35 100644
Binary files a/dijit/themes/soria/images/spriteTree_rtl.png and b/dijit/themes/soria/images/spriteTree_rtl.png differ
diff --git a/dijit/themes/soria/images/tabBottomActiveSpriteLR.gif b/dijit/themes/soria/images/tabBottomActiveSpriteLR.gif
deleted file mode 100644
index 7c2ed86..0000000
Binary files a/dijit/themes/soria/images/tabBottomActiveSpriteLR.gif and /dev/null differ
diff --git a/dijit/themes/soria/images/tabBottomHoverSpriteLR.gif b/dijit/themes/soria/images/tabBottomHoverSpriteLR.gif
deleted file mode 100644
index 59f3edd..0000000
Binary files a/dijit/themes/soria/images/tabBottomHoverSpriteLR.gif and /dev/null differ
diff --git a/dijit/themes/soria/images/tabLeftChecked.gif b/dijit/themes/soria/images/tabLeftChecked.gif
index 3e7475a..439aa6b 100644
Binary files a/dijit/themes/soria/images/tabLeftChecked.gif and b/dijit/themes/soria/images/tabLeftChecked.gif differ
diff --git a/dijit/themes/soria/images/tabRightChecked.gif b/dijit/themes/soria/images/tabRightChecked.gif
index ec4b659..cfffd1e 100644
Binary files a/dijit/themes/soria/images/tabRightChecked.gif and b/dijit/themes/soria/images/tabRightChecked.gif differ
diff --git a/dijit/themes/soria/images/tabStripe.gif b/dijit/themes/soria/images/tabStripe.gif
deleted file mode 100644
index 51a2d40..0000000
Binary files a/dijit/themes/soria/images/tabStripe.gif and /dev/null differ
diff --git a/dijit/themes/soria/images/tabStripeBottom.gif b/dijit/themes/soria/images/tabStripeBottom.gif
deleted file mode 100644
index 41b1ac0..0000000
Binary files a/dijit/themes/soria/images/tabStripeBottom.gif and /dev/null differ
diff --git a/dijit/themes/soria/images/tabStripeLeft.gif b/dijit/themes/soria/images/tabStripeLeft.gif
deleted file mode 100644
index b2214fa..0000000
Binary files a/dijit/themes/soria/images/tabStripeLeft.gif and /dev/null differ
diff --git a/dijit/themes/soria/images/tabStripeRight.gif b/dijit/themes/soria/images/tabStripeRight.gif
deleted file mode 100644
index bff3115..0000000
Binary files a/dijit/themes/soria/images/tabStripeRight.gif and /dev/null differ
diff --git a/dijit/themes/soria/images/titleBar.png b/dijit/themes/soria/images/titleBar.png
index 93c4146..c9121ea 100644
Binary files a/dijit/themes/soria/images/titleBar.png and b/dijit/themes/soria/images/titleBar.png differ
diff --git a/dijit/themes/soria/images/titleBarActive.png b/dijit/themes/soria/images/titleBarActive.png
index fb8a2e6..4db116b 100644
Binary files a/dijit/themes/soria/images/titleBarActive.png and b/dijit/themes/soria/images/titleBarActive.png differ
diff --git a/dijit/themes/soria/images/tooltipConnectorDown.png b/dijit/themes/soria/images/tooltipConnectorDown.png
index d75af71..7783f90 100644
Binary files a/dijit/themes/soria/images/tooltipConnectorDown.png and b/dijit/themes/soria/images/tooltipConnectorDown.png differ
diff --git a/dijit/themes/soria/images/tooltipConnectorLeft.png b/dijit/themes/soria/images/tooltipConnectorLeft.png
index f3de66a..ae16d36 100644
Binary files a/dijit/themes/soria/images/tooltipConnectorLeft.png and b/dijit/themes/soria/images/tooltipConnectorLeft.png differ
diff --git a/dijit/themes/soria/images/tooltipConnectorRight.png b/dijit/themes/soria/images/tooltipConnectorRight.png
index 3d62dcd..9532b17 100644
Binary files a/dijit/themes/soria/images/tooltipConnectorRight.png and b/dijit/themes/soria/images/tooltipConnectorRight.png differ
diff --git a/dijit/themes/soria/images/tooltipConnectorUp.png b/dijit/themes/soria/images/tooltipConnectorUp.png
index 7f7a5d8..2dc5b31 100644
Binary files a/dijit/themes/soria/images/tooltipConnectorUp.png and b/dijit/themes/soria/images/tooltipConnectorUp.png differ
diff --git a/dijit/themes/soria/images/treeHover.png b/dijit/themes/soria/images/treeHover.png
index cd6d28b..e4d5d57 100644
Binary files a/dijit/themes/soria/images/treeHover.png and b/dijit/themes/soria/images/treeHover.png differ
diff --git a/dijit/themes/soria/images/validationInputBg.png b/dijit/themes/soria/images/validationInputBg.png
index f3039f9..ca0f890 100644
Binary files a/dijit/themes/soria/images/validationInputBg.png and b/dijit/themes/soria/images/validationInputBg.png differ
diff --git a/dijit/themes/soria/images/warning.png b/dijit/themes/soria/images/warning.png
index c52f83d..07cabea 100644
Binary files a/dijit/themes/soria/images/warning.png and b/dijit/themes/soria/images/warning.png differ
diff --git a/dijit/themes/soria/layout/TabContainer.css b/dijit/themes/soria/layout/TabContainer.css
index b96d169..38a1a77 100644
--- a/dijit/themes/soria/layout/TabContainer.css
+++ b/dijit/themes/soria/layout/TabContainer.css
@@ -1,9 +1,5 @@
 /**
  * dijit.layout.TabContainer
- *
- * To style TabContainer with rounded corners
- * you can use these classes: .dijitTab (left), .dijitTabContent (center), dijitTabInnerDiv (right)
- * For tabs aligned to top you can style a stripe div right underneath the tabs using .dijitTabStripe
  */
 
 /* Classes for all types of tabs (top/bottom/left/right) */
@@ -32,68 +28,39 @@
 	padding-left: 0;
 }
 
-.soria .dijitTabInnerDiv {
-	padding:0 3px 0 0;
-	margin: 0 0 0 4px;
-	background: url("../images/tabContainerSprite.gif") no-repeat;
-	background-position: right -400px;
-}
-
 .soria .dijitTab {
+    padding:4px 6px 2px 4px;
+    background: url("../images/tabContainerSprite.gif") repeat-x 0 -351px;
+    position: relative;
 	line-height:normal;
 	margin:0 2px 0 0;	/* space between one tab and the next in top/bottom mode */
-	padding:0;
-	background: url("../images/tabContainerSprite.gif") no-repeat 0 -300px;
 	color: #243C5F;
+    border: 1px #8BA0BD solid;
 	border-bottom: 1px #B1BADF solid;
 }
 
-.soria .dijitTabInnerDiv .dijitTabContent {
-	padding:4px 3px 2px 4px;
-	background: url("../images/tabContainerSprite.gif") repeat-x 0 -350px;
-	position: relative;
-}
-
-
-
-.soria .dijitTabListWrapper {
-	z-index: 10;
-}
-
 /* hovered tab */
 .soria .dijitTabHover {
 	color: #243C5F;
-	background: url("../images/tabContainerSprite.gif") no-repeat 0 -150px;
-}
-
-.soria .dijitTabHover .dijitTabInnerDiv {
-	background: url("../images/tabContainerSprite.gif") no-repeat right -250px;
+	background: url("../images/tabContainerSprite.gif") repeat-x 0 -201px;
 }
 
-.soria .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
-	background: url("../images/tabContainerSprite.gif") repeat-x 0 -200px;
-}
-
-/* checked tab*/
+/* selected tab*/
 .soria .dijitTabChecked
 {
-	/* the selected tab (with or without hover) */
-	background: url("../images/tabContainerSprite.gif") no-repeat 0 -0;
+	background: url("../images/tabContainerSprite.gif") repeat-x 0 -51px;
+	color: #243C5F !important;
 }
 
-.soria .dijitTabChecked .dijitTabInnerDiv {
-	background: url("../images/tabContainerSprite.gif") no-repeat right -100px;
-}
 
-.soria .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
-	background: url("../images/tabContainerSprite.gif") repeat-x 0 -50px;
-	color: #243C5F !important;
+.soria .dijitTabListWrapper {
+	z-index: 10;
 }
 
+
 /* Nested Tabs */
 
 .soria .dijitTabContainerTabListNested {
-	background: #F0F4FC;
 	background: #D9E9F9;
 	border: none;
 }
@@ -102,11 +69,7 @@
 	border: none;
 	top: 0;	/* override top:1px setting of top-level tabs */
 }
-.soria .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv,
-.soria .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
-	background: none;
-}
-.soria .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent .tabLabel {
+.soria .dijitTabContainerTabListNested .dijitTabHover .tabLabel {
 	text-decoration: underline;
 }
 .soria .dijitTabContainerTabListNested .dijitTabChecked .tabLabel {
@@ -146,6 +109,10 @@
 	border-color: #B1BADF;
 	padding-left: 3px;
 }
+.soria .dijitTabContainerTop-tabs .dijitTab {
+    border-radius: 4px 4px 0 0;
+    -moz-border-radius: 4px 4px 0 0;
+}
 
 .soria .dijitTabContainerTopNoStrip {
 	padding-top: 3px;
@@ -160,12 +127,12 @@
 	border-bottom: none;
 }
 
-/*non-checked tabs */
+/*unselected tabs */
 .soria .dijitTabContainerTop-tabs .dijitTab {
 	top: 1px;
 }
 
-/* checked tabs */
+/* selected tabs */
 .soria .dijitTabContainerTop-tabs .dijitTabChecked {
 	border-bottom-color: #94b4e6;
 }
@@ -202,59 +169,32 @@
 	float: left;
 }
 
-/* bottom container */
-.soria .dijitTabContainerBottom-container {
-	border-bottom: none;
-}
-
 .soria .dijitTabContainerBottom-tabs .dijitTab {
-	border-bottom: none;
-	border-top: 1px solid #B1BADF;
-	background: url("../images/tabBottomEnabledSpriteLR.gif") no-repeat bottom left;
-}
-
-/* checked tabs */
-.soria .dijitTabContainerBottom-tabs .dijitTabChecked {
-	border-top-color:#94b4e6;
-}
-
-
-.soria .dijitTabContainerBottom-tabs .dijitTabInnerDiv .dijitTabContent {
-	padding-top: 3px;
-	padding-bottom: 3px;
-	background: url("../images/tabBottomEnabledC.gif") repeat-x bottom left;
-}
-
-.soria .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
-	background: url("../images/tabBottomEnabledSpriteLR.gif") no-repeat bottom right;
+    border-bottom: none;
+    border-top: 1px solid #B1BADF;
+    border-radius: 0 0 4px 4px;
+    -moz-border-radius: 0 0 4px 4px;
+    padding-top: 3px;
+    padding-bottom: 3px;
+    background: url("../images/tabBottomEnabledC.gif") repeat-x bottom left;
 }
 
 .soria .dijitTabContainerBottom-tabs .dijitTabHover {
-	color: #243C5F;
-	background: url("../images/tabBottomHoverSpriteLR.gif") no-repeat bottom left;
-}
-
-.soria .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv {
-	background: url("../images/tabBottomHoverSpriteLR.gif") no-repeat bottom right;
-}
-
-.soria .dijitTabContainerBottom-tabs .dijitTabHover .dijitTabInnerDiv .dijitTabContent {
 	background: url("../images/tabBottomHoverC.gif") repeat-x bottom left;
 }
 
-.soria .dijitTabContainerBottom-tabs .dijitTabChecked {
-	/* the selected tab (with or without hover) */
-	background: url("../images/tabBottomActiveSpriteLR.gif") no-repeat bottom left;
+.soria .dijitTabContainerBottom-tabs .dijitTabChecked  {
+    border-top-color:#94b4e6;
+	background: url("../images/tabBottomActiveC.gif") repeat-x bottom left;
 }
 
-.soria .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv {
-	background: url("../images/tabBottomActiveSpriteLR.gif") no-repeat bottom right;
-}
 
-.soria .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv .dijitTabContent {
-	background: url("../images/tabBottomActiveC.gif") repeat-x bottom left;
+/* bottom container */
+.soria .dijitTabContainerBottom-container {
+	border-bottom: none;
 }
 
+
 /* strip */
 .soria .dijitTabContainerBottomStrip {
 	padding-bottom: 2px;
@@ -288,51 +228,44 @@
 	border-color: #ccc;
 	padding-top: 3px;
 }
+.soria .dijitTabContainerRight-tabs .dijitTab {
+    border-radius: 0 4px 4px 0;
+    -moz-border-radius: 0 4px 4px 0;
+    border-bottom: none;
+    border-left: 1px solid #B1BADF;
+    border-bottom: 1px solid #B1BADF !important;
+    padding:  4px 6px 2px 8px;
+}
+
+.soria .dijitTabContainerRight-tabs .dijitTabChecked {
+	border-left-color: #94b4e6;
+    background: url("../images/tabRightChecked.gif") no-repeat left top !important;
+}
+
 
 /* right container */
 .soria .dijitTabContainerRight-container {
 	border-right: none;
 }
 
-.soria .dijitTabContainerRight-tabs .dijitTab {
-	border-bottom: none;
-	border-left: 1px solid #B1BADF;
-	border-bottom: 1px solid #B1BADF !important;
-}
 
-
-/* some odd ie bug when borders dissapear when setting a bottom margin, this sortof helps */
-.dj_ie6 .soria .dijitTabContainerRight-tabs .dijitTabInnerDiv,
-.dj_ie7 .soria .dijitTabContainerRight-tabs .dijitTabInnerDiv {
+/* some odd ie bug when borders disappear when setting a bottom margin, this sort of helps */
+.dj_ie6 .soria .dijitTabContainerRight-tabs .dijitTab,
+.dj_ie7 .soria .dijitTabContainerRight-tabs .dijitTab {
 	border-bottom: solid #B1BADF 1px;
 	margin-bottom: -1px;
 }
 
-/* checked tabs */
-.soria .dijitTabContainerRight-tabs .dijitTabChecked {
-	border-left-color: #94b4e6;
-}
-
-.soria .dijitTabContainerRight-tabs .dijitTabChecked {
-	background: url("../images/tabRightChecked.gif") no-repeat left top !important;
-}
 
-/* some odd ie bug when borders dissapear when setting a bottom margin, this sortof helps */
-.dj_ie6 .soria .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabInnerDiv,
-.dj_ie7 .soria .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabInnerDiv,
-.dj_ie6 .soria .dijitTabContainerRight-tabs .dijitTabCheckedHover .dijitTabInnerDiv,
-.dj_ie7 .soria .dijitTabContainerRight-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+/* some odd ie bug when borders disappear when setting a bottom margin, this sort of helps */
+.dj_ie6 .soria .dijitTabContainerRight-tabs .dijitTabChecked,
+.dj_ie7 .soria .dijitTabContainerRight-tabs .dijitTabChecked,
+.dj_ie6 .soria .dijitTabContainerRight-tabs .dijitTabCheckedHover,
+.dj_ie7 .soria .dijitTabContainerRight-tabs .dijitTabCheckedHover {
 	border-bottom: solid #94b4e6 1px;
 	margin-bottom: -1px;
 }
 
-.soria .dijitTabContainerRight-tabs .dijitTab {
-	background: url("../images/tabContainerSprite.gif") no-repeat left -350px;
-}
-.soria .dijitTabContainerRight-tabs .dijitTabHover .dijitTab {
-	background: url("../images/tabContainerSprite.gif") no-repeat left -200px;
-}
-
 /* strip */
 .soria .dijitTabContainerRightStrip {
 	padding-right: 2px;
@@ -348,43 +281,34 @@
 	padding-top: 3px;
 	height: 100%;
 }
-
-/* left conatiner */
-.soria .dijitTabContainerLeft-container {
-	border-left: none;
-}
-
 .soria .dijitTabContainerLeft-tabs .dijitTab {
-	border-right: 1px solid #B1BADF;
-	border-bottom: 1px solid #B1BADF;
+    border-radius: 4px 0 0 4px;
+    -moz-border-radius: 4px 0 0 4px;
+    border-right: 1px solid #B1BADF;
+    border-bottom: 1px solid #B1BADF;
 }
 
-/* checked tabs */
 .soria .dijitTabContainerLeft-tabs .dijitTabChecked {
 	border-right: 1px solid #94b4e6;
+    background: url("../images/tabLeftChecked.gif") no-repeat right top;
 }
 
-.soria .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
-	background: url("../images/tabContainerSprite.gif") no-repeat right -350px;
-}
-.soria .dijitTabContainerLeft-tabs .dijitTabHover .dijitTabInnerDiv {
-	background: url("../images/tabContainerSprite.gif") no-repeat right -200px;
-}
-.soria .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
-.soria .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
-	background: url("../images/tabLeftChecked.gif") no-repeat right top;
+/* left container */
+.soria .dijitTabContainerLeft-container {
+	border-left: none;
 }
 
-.dj_ie6 .soria .dijitTabContainerLeft-tabs .dijitTabInnerDiv,
-.dj_ie7 .soria .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
+
+.dj_ie6 .soria .dijitTabContainerLeft-tabs .dijitTab,
+.dj_ie7 .soria .dijitTabContainerLeft-tabs .dijitTab {
 	border-bottom: solid #B1BADF 1px;
 	margin-bottom: -1px;
 }
 
-.dj_ie6 .soria .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
-.dj_ie7 .soria .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv,
-.dj_ie6 .soria .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv,
-.dj_ie7 .soria .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTabInnerDiv {
+.dj_ie6 .soria .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTab,
+.dj_ie7 .soria .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTab,
+.dj_ie6 .soria .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTab,
+.dj_ie7 .soria .dijitTabContainerLeft-tabs .dijitTabCheckedHover .dijitTab {
 	border-bottom: solid #94b4e6 1px;
 	margin-bottom: -1px;
 }
@@ -401,8 +325,7 @@
 /* left/right tabs */
 .soria .dijitTabContainerLeft-tabs .dijitTab,
 .soria .dijitTabContainerRight-tabs .dijitTab {
-	margin-right:auto;
-	margin-bottom:2px;	/* space between one tab and the next in left/right mode */
+    margin: 1px 0;	/* space between one tab and the next in left/right mode */
 }
 
 /* left/right tabstrip */
@@ -421,7 +344,7 @@
 }
 /* ================================ */
 
-/* this resets the tabcontainer stripe when within a contentpane */
+/* this resets the tabcontainer strip when within a contentpane */
 .soria .dijitTabContainerTop-dijitContentPane .dijitTabContainerTop-tabs {
 	border-left: 0 solid #ccc;
 	border-top: 0 solid #ccc;
@@ -441,19 +364,11 @@
 	margin-top: 1px;
 }
 
-.soria .tabStripButton .dijitTabContent{
-	padding: 6px 0 5px 0;
-}
-
 .dj_ie6 .soria .tabStripButton .dijitTabContent,
 .dj_ie7 .soria .tabStripButton .dijitTabContent {
 	padding-top: 7px;
 }
 
-.soria .tabStrip-disabled .tabStripButton .dijitTabContent {
-	padding: 5px 0 3px 0;
-}
-
 .dj_ie6 .soria .tabStrip-disabled .tabStripButton .dijitTabContent,
 .dj_ie7 .soria .tabStrip-disabled .tabStripButton .dijitTabContent {
 	padding-top: 6px;
@@ -465,14 +380,10 @@
 	border-top: 1px solid #B1BADF;
 }
 
-.soria .dijitTabContainer .tabStripButton-bottom .dijitTabInnerDiv {
+.soria .dijitTabContainer .tabStripButton-bottom .dijitTab {
 	background: transparent url(../images/tabBottomEnabledSpriteLR.gif) no-repeat scroll right bottom;
 }
 
-.soria .dijitTabContainer .tabStripButton-bottom .dijitTabContent {
-	background: transparent;
-}
-
 .soria .dijitTabStripIcon {
 	height: 14px;
 	width: 14px;
diff --git a/dijit/themes/soria/soria_rtl.css b/dijit/themes/soria/soria_rtl.css
index b804011..895f822 100644
--- a/dijit/themes/soria/soria_rtl.css
+++ b/dijit/themes/soria/soria_rtl.css
@@ -24,6 +24,7 @@
 @import url("Calendar_rtl.css");
 @import url("TimePicker_rtl.css");
 @import url("Dialog_rtl.css");
+ at import url("ProgressBar_rtl.css");
 @import url("Menu_rtl.css");
 @import url("Editor_rtl.css");
 @import url("../../icons/editorIcons_rtl.css"); /*sprite for editor icons to be used by all themes*/
\ No newline at end of file
diff --git a/dijit/themes/themeTester-orig.html b/dijit/themes/themeTester-orig.html
index ece749f..457ee25 100644
--- a/dijit/themes/themeTester-orig.html
+++ b/dijit/themes/themeTester-orig.html
@@ -103,6 +103,7 @@
 		dojo.require("dijit.form.Textarea");
 		dojo.require("dijit.form.SimpleTextarea");
 		dojo.require("dijit.form.FilteringSelect");
+		dojo.require("dijit.form.Select");
 		dojo.require("dijit.form.TextBox");
 		dojo.require("dijit.form.DateTextBox");
 		dojo.require("dijit.form.TimeTextBox");
diff --git a/dijit/themes/themeTester.html b/dijit/themes/themeTester.html
index 7bfa6bb..d61e304 100644
--- a/dijit/themes/themeTester.html
+++ b/dijit/themes/themeTester.html
@@ -2,1063 +2,1378 @@
 <html>
 <head>
 
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-
-	<title>Dijit Theme Tester</title>
-
-	<script>
-		var startTime = new Date();
-	</script>
-
-	<!-- required: a default theme -->
-	<link rel="stylesheet" href="../themes/claro/document.css"/>
-	<link rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
-	<link rel="stylesheet" href="../tests/css/dijitTests.css"/>
-
-	<style type="text/css">
-		html, body { height: 100%; width: 100%; padding: 0; border: 0; }
-		#main { height: 100%; width: 100%; border: 0; }
-		#header { margin: 0; }
-		#leftAccordion { width: 25%; }
-		#bottomTabs { height: 40%; }
-		#hs-1width {
-			width:400px;
-			height:40px;
-		}
-		/* pre-loader specific stuff to prevent unsightly flash of unstyled content */
-		#loader {
-			padding:0;
-			margin:0;
-			position:absolute;
-			top:0; left:0;
-			width:100%; height:100%;
-			background:#ededed;
-			z-index:999;
-			vertical-align:middle;
-		}
-		#loaderInner {
-			padding:5px;
-			position:relative;
-			left:0;
-			top:0;
-			width:175px;
-			background:#3c3;
-			color:#fff;
-		}
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
+<title>Dijit Theme Tester</title>
+
+<script>
+	var startTime = new Date();
+</script>
+
+<!-- required: a default theme -->
+<link rel="stylesheet" href="../themes/claro/document.css"/>
+<link rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+<link rel="stylesheet" href="../tests/css/dijitTests.css"/>
+
+<style type="text/css">
+	html, body {
+		height: 100%;
+		width: 100%;
+		padding: 0;
+		border: 0;
+	}
+
+	#main {
+		height: 100%;
+		width: 100%;
+		border: 0;
+	}
+
+/***
+	Uncomment this rule to test border-box sizing
+	* {
+		-moz-box-sizing: border-box;
+		box-sizing: border-box;
+	}
+***/
+
+	#header {
+		margin: 0;
+	}
+
+	#leftAccordion {
+		width: 25%;
+	}
+
+	#bottomTabs {
+		height: 40%;
+	}
+
+	#hs-1width {
+		width: 400px;
+		height: 40px;
+	}
 
-		#indTestBar,
-		#setTestBar {
-			width:400px;
-		}
-		
-		hr.spacer { border:0; background-color:#ededed; width:80%; height:1px; }
+		/* pre-loader specific stuff to prevent unsightly flash of unstyled content */
+	#loader {
+		padding: 0;
+		margin: 0;
+		position: absolute;
+		top: 0;
+		left: 0;
+		width: 100%;
+		height: 100%;
+		background: #ededed;
+		z-index: 999;
+		vertical-align: middle;
+	}
+
+	#loaderInner {
+		padding: 5px;
+		position: relative;
+		left: 0;
+		top: 0;
+		width: 175px;
+		background: #3c3;
+		color: #fff;
+	}
+
+	#indTestBar,
+	#setTestBar {
+		width: 400px;
+	}
+
+	hr.spacer {
+		border: 0;
+		background-color: #ededed;
+		width: 80%;
+		height: 1px;
+	}
 
 		/* rules used to test custom setting of TextBox padding */
-		.inputPadding0 .dijitInputField { padding: 0 !important; }
-		.inputPadding1 .dijitInputField { padding: 1px !important; }
-		.inputPadding2 .dijitInputField { padding: 2px !important; }
-		.inputPadding3 .dijitInputField { padding: 3px !important; }
-		.inputPadding4 .dijitInputField { padding: 4px !important; }
-		.inputPadding5 .dijitInputField { padding: 5px !important; }
-	</style>
-
-	<!-- a check for stray globals: not needed! -->
-	<script type="text/javascript">
-		window.__globalList = { dojo: true, dijit: true, dojox: true, dojoConfig:true };
-		for(var i in window){
-			window.__globalList[i] = true;
-		}
-	</script>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
+	.inputPadding0 .dijitInputField {
+		padding: 0 !important;
+	}
+
+	.inputPadding1 .dijitInputField {
+		padding: 1px !important;
+	}
+
+	.inputPadding2 .dijitInputField {
+		padding: 2px !important;
+	}
+
+	.inputPadding3 .dijitInputField {
+		padding: 3px !important;
+	}
+
+	.inputPadding4 .dijitInputField {
+		padding: 4px !important;
+	}
+
+	.inputPadding5 .dijitInputField {
+		padding: 5px !important;
+	}
+</style>
+
+<!-- a check for stray globals: not needed! -->
+<script type="text/javascript">
+	window.__globalList = { dojo: true, dijit: true, dojox: true, dojoConfig: true };
+	for(var i in window){
+		window.__globalList[i] = true;
+	}
+</script>
+
+<!-- required: dojo.js -->
+<script type="text/javascript" src="../../dojo/dojo.js"
 		data-dojo-config="parseOnLoad: false, async:true"></script>
 
-	<!-- only needed for alternate theme testing: -->
-	<script type="text/javascript" src="../tests/_testCommon.js"></script>
-
-	<script type="text/javascript">
-		require([
-			"dojo",
-			"dijit/dijit",
-			"dijit/dijit-all",
-			"dojo/parser",
-			"dojo/date/locale",
-			"dojo/data/ItemFileReadStore",
-			"dojo/dnd/Source"], function(dojo, dijit){
-				// various function ripped out of inline script type=dojo/* blocks
-				showDialog = function(){
-					var dlg = dijit.byId('dialog1');
-					dlg.show();
-					// avoid (trying to) restore focus to a closed menu, go to MenuBar instead
-					dlg._savedFocus = dojo.byId("header");
-				};
-				
-				showDialogAb = function(){
-					var dlg = dijit.byId('dialogAB');
-					dlg.show();
-					// avoid (trying to) restore focus to a closed menu, go to MenuBar instead
-					dlg._savedFocus = dojo.byId("header");
-				};
-
-				//var setTextBoxPadding;
-				// current setting (if there is one) to override theme default padding on TextBox based widgets
-				var currentInputPadding = "";
-				
-				setTextBoxPadding = function(){
-					// summary:
-					//		Handler for when a MenuItem is clicked to set non-default padding for
-					//		TextBox widgets
-
-					// Effectively ignore clicks on the	 currently checked MenuItem
-					if(!this.get("checked")){
-						this.set("checked", true);
-					}
+<!-- only needed for alternate theme testing: -->
+<script type="text/javascript" src="../tests/_testCommon.js"></script>
 
-					// val will be "theme default", "0px", "1px", ..., "5px"
-					var val = this.get("label");
+<script type="text/javascript">
+	require([
+		"dojo/_base/array", "dojo/_base/fx", "dojo/dom", "dojo/dom-class", "dojo/dom-geometry", "dojo/dom-style",
+		"dojo/hccss", "dojo/date/locale", "dojo/parser", "dojo/store/Memory",
+		"dijit/registry", "dijit/tree/ObjectStoreModel",
 
-					// Set class on body to get requested padding, and remove any previously set class
-					if(currentInputPadding){
-						dojo.removeClass(dojo.body(), currentInputPadding);
-						currentInputPadding = "";
-					}
-					if(val != "theme default"){
-						currentInputPadding = "inputPadding" + val.replace("px", "");
-						dojo.addClass(dojo.body(), currentInputPadding);
-					}
+		"dijit/CheckedMenuItem", "dijit/RadioMenuItem", "dijit/MenuSeparator",
+
+		// Editors used by InlineEditBox.  Must be pre-loaded.
+		"dijit/form/Textarea", "dijit/form/DateTextBox", "dijit/form/TimeTextBox", "dijit/form/FilteringSelect",
+
+		// These plugins are used by the Editor, and need to be pre-loaded
+		"dijit/_editor/plugins/LinkDialog", // for createLink
+		"dijit/_editor/plugins/FontChoice", // for fontName
 
-					// Clear previously checked MenuItem (radio-button effect).
-					dojo.forEach(this.getParent().getChildren(), function(mi){
-						if(mi != this){
-							mi.set("checked", false);
-						}
-					}, this);
-				};
-
-				logStrayGlobals = function(){
-					// summary:
-					//		Print all the global variables that we've created [by mistake] inside of dojo
-					var strayGlobals = [];
-					for(var i in window){
-						if(!window.__globalList[i]){
-							strayGlobals.push(i);
-						}
+		// Don't call the parser until the DOM has finished loading
+		"dojo/domReady!"
+	], function(array, baseFx, dom, domClass, domGeom, domStyle, has, locale, parser, Memory, registry, ObjectStoreModel,
+			CheckedMenuItem, RadioMenuItem, MenuSeparator){
+		// If you are doing box-model sizing then need to tell dom-geometry, see #15104
+		if(domStyle.get(document.body, "boxSizing") == "border-box" ||
+				domStyle.get(document.body, "MozBoxSizing") == "border-box"){
+			domGeom.boxModel = "border-box";
+		}
+
+		// various function ripped out of inline script type=dojo/* blocks
+		showDialog = function(){
+			var dlg = registry.byId('dialog1');
+			dlg.show();
+			// avoid (trying to) restore focus to a closed menu, go to MenuBar instead
+			dlg._savedFocus = dom.byId("header");
+		};
+
+		showDialogAb = function(){
+			var dlg = registry.byId('dialogAB');
+			dlg.show();
+			// avoid (trying to) restore focus to a closed menu, go to MenuBar instead
+			dlg._savedFocus = dom.byId("header");
+		};
+
+		//var setTextBoxPadding;
+		// current setting (if there is one) to override theme default padding on TextBox based widgets
+		var currentInputPadding = "";
+
+		setTextBoxPadding = function(){
+			// summary:
+			//		Handler for when a MenuItem is clicked to set non-default padding for
+			//		TextBox widgets
+
+			// Effectively ignore clicks on the	 currently checked MenuItem
+			if(!this.get("checked")){
+				this.set("checked", true);
+			}
+
+			// val will be "theme default", "0px", "1px", ..., "5px"
+			var val = this.get("label");
+
+			// Set class on body to get requested padding, and remove any previously set class
+			if(currentInputPadding){
+				domClass.remove(dojo.body(), currentInputPadding);
+				currentInputPadding = "";
+			}
+			if(val != "theme default"){
+				currentInputPadding = "inputPadding" + val.replace("px", "");
+				domClass.add(dojo.body(), currentInputPadding);
+			}
+
+			// Clear previously checked MenuItem (radio-button effect).
+			array.forEach(this.getParent().getChildren(), function(mi){
+				if(mi != this){
+					mi.set("checked", false);
+				}
+			}, this);
+		};
+
+		logStrayGlobals = function(){
+			// summary:
+			//		Print all the global variables that we've created [by mistake] inside of dojo
+			var strayGlobals = [];
+			for(var i in window){
+				if(!window.__globalList[i]){
+					strayGlobals.push(i);
+				}
+			}
+			if(strayGlobals.length){
+				console.warn("Stray globals: " + strayGlobals.join(", "));
+			}
+		};
+
+		logWidgets = function(){
+			// summary:
+			//		Print all the widgets to console
+			console.log("Widgets in registry:");
+			registry.forEach(function(w){
+				console.log(w);
+			});
+		};
+
+		tearDown = function(){
+			// summary:
+			//		Destroy all widgets, top down, and then check for any orphaned widgets
+			registry._destroyAll();
+			logWidgets();
+		};
+
+		// Data for Tree, ComboBox, InlineEditBox
+		var data = [
+			{ id: "earth", name: "The earth", type: "planet", population: "6 billion"},
+			{ id: "AF", name: "Africa", type: "continent", population: "900 million", area: "30,221,532 sq km",
+				timezone: "-1 UTC to +4 UTC", parent: "earth"},
+			{ id: "EG", name: "Egypt", type: "country", parent: "AF" },
+			{ id: "KE", name: "Kenya", type: "country", parent: "AF" },
+			{ id: "Nairobi", name: "Nairobi", type: "city", parent: "KE" },
+			{ id: "Mombasa", name: "Mombasa", type: "city", parent: "KE" },
+			{ id: "SD", name: "Sudan", type: "country", parent: "AF" },
+			{ id: "Khartoum", name: "Khartoum", type: "city", parent: "SD" },
+			{ id: "AS", name: "Asia", type: "continent", parent: "earth" },
+			{ id: "CN", name: "China", type: "country", parent: "AS" },
+			{ id: "IN", name: "India", type: "country", parent: "AS" },
+			{ id: "RU", name: "Russia", type: "country", parent: "AS" },
+			{ id: "MN", name: "Mongolia", type: "country", parent: "AS" },
+			{ id: "OC", name: "Oceania", type: "continent", population: "21 million", parent: "earth"},
+			{ id: "AU", name: "Australia", type: "country", population: "21 million", parent: "OC"},
+			{ id: "EU", name: "Europe", type: "continent", parent: "earth" },
+			{ id: "DE", name: "Germany", type: "country", parent: "EU" },
+			{ id: "FR", name: "France", type: "country", parent: "EU" },
+			{ id: "ES", name: "Spain", type: "country", parent: "EU" },
+			{ id: "IT", name: "Italy", type: "country", parent: "EU" },
+			{ id: "NA", name: "North America", type: "continent", parent: "earth" },
+			{ id: "MX", name: "Mexico", type: "country", population: "108 million", area: "1,972,550 sq km",
+				parent: "NA" },
+			{ id: "Mexico City", name: "Mexico City", type: "city", population: "19 million", timezone: "-6 UTC", parent: "MX"},
+			{ id: "Guadalajara", name: "Guadalajara", type: "city", population: "4 million", timezone: "-6 UTC", parent: "MX" },
+			{ id: "CA", name: "Canada", type: "country", population: "33 million", area: "9,984,670 sq km", parent: "NA" },
+			{ id: "Ottawa", name: "Ottawa", type: "city", population: "0.9 million", timezone: "-5 UTC", parent: "CA"},
+			{ id: "Toronto", name: "Toronto", type: "city", population: "2.5 million", timezone: "-5 UTC", parent: "CA" },
+			{ id: "US", name: "United States of America", type: "country", parent: "NA" },
+			{ id: "SA", name: "South America", type: "continent", parent: "earth" },
+			{ id: "BR", name: "Brazil", type: "country", population: "186 million", parent: "SA" },
+			{ id: "AR", name: "Argentina", type: "country", population: "40 million", parent: "SA" }
+		];
+
+		// Create test store.
+		continentStore = new Memory({
+			data: data
+		});
+
+		// Since dojo.store.Memory doesn't have various store methods we need, we have to add them manually
+		continentStore.getChildren = function(object){
+			// Add a getChildren() method to store for the data model where
+			// children objects point to their parent (aka relational model)
+			return this.query({parent: this.getIdentity(object)});
+		};
+
+		// Create the model for the Tree
+		continentModel = new ObjectStoreModel({store: continentStore, query: {id: "earth"}});
+
+		var loadCompleteTime = +new Date();
+		console.log("Total load time: " + (loadCompleteTime - startTime) + "ms");
+
+		parser.parse(dom.byId('container')).then(function(){
+			console.info("Total parse time: " + (+new Date() - loadCompleteTime) + "ms");
+
+			dom.byId('loaderInner').innerHTML += " done.";
+			setTimeout(function hideLoader(){
+				baseFx.fadeOut({
+					node: 'loader',
+					duration: 500,
+					onEnd: function(n){
+						n.style.display = "none";
 					}
-					if(strayGlobals.length){
-						console.warn("Stray globals: " + strayGlobals.join(", "));
+				}).play();
+			}, 250);
+
+			logStrayGlobals();
+
+			// availableThemes[] is just a list of 'official' dijit themes, you can use ?theme=String
+			// for 'un-supported' themes, too. (eg: yours)
+			var availableThemes = [
+				{ theme: "claro", author: "Dojo", baseUri: "../themes/" },
+				{ theme: "tundra", author: "Dojo", baseUri: "../themes/" },
+				{ theme: "soria", author: "nikolai", baseUri: "../themes/" },
+				{ theme: "nihilo", author: "nikolai", baseUri: "../themes/" }
+			];
+
+			// Get current theme, a11y, and dir setting for page
+			var curTheme = location.search.replace(/.*theme=([a-z]+).*/, "$1") || "claro",
+				a11y = has("highcontrast") || /a11y=true/.test(location.search),
+				rtl = document.body.parentNode.dir == "rtl";
+			console.log("Theme: " + curTheme + ", high contrast = " + a11y + ", dir = " + (rtl ? "rtl" : "ltr"));
+
+			function setUrl(theme, rtl, a11y){
+				// Function to reload page with specified theme, rtl, and a11y settings
+				location.search = "?theme=" + theme + (rtl ? "&dir=rtl" : "") + (a11y ? "&a11y=true" : "");
+			}
+
+			// Create menu choices and links to test other themes
+			var tmpString = '';
+			array.forEach(availableThemes, function(theme){
+				if(theme != curTheme){
+					tmpString +=
+							'<a href="?theme=' + theme.theme + '">' + theme.theme + '</' + 'a> (' +
+									'<a href="?theme=' + theme.theme + '&dir=rtl">RTL</' + 'a> ' +
+									'<a href="?theme=' + theme.theme + '&a11y=true">high-contrast</' + 'a> ' +
+									'<a href="?theme=' + theme.theme + '&dir=rtl&a11y=true">RTL+high-contrast</' + 'a> )' +
+									' - by: ' + theme.author + ' <br>';
+				}
+			});
+			dom.byId('themeData').innerHTML = tmpString;
+
+			// Create menu choices to test other themes
+			array.forEach(availableThemes, function(theme){
+				registry.byId('themeMenu').addChild(new RadioMenuItem({
+					id: theme.theme + "_radio",
+					label: theme.theme,
+					group: "theme",
+					checked: theme.theme == curTheme,
+					onClick: function(){
+						// Change theme, keep current a11y and rtl settings
+						setUrl(theme.theme, a11y, rtl);
 					}
-				};
-		
-				logWidgets = function(){
-					// summary:
-					//		Print all the widgets to console
-					console.log("Widgets in registry:");
-					dijit.registry.forEach(function(w){
-						console.log(w);
-					});
-				};
-		
-				tearDown = function(){
-					// summary:
-					//		Destroy all widgets, top down, and then check for any orphaned widgets
-					dijit._destroyAll();
-					logWidgets();
-				};
-		
-				dojo.ready(function(){
-					var loadCompleteTime = +new Date();
-					console.log("Total load time: " + (loadCompleteTime - startTime) + "ms");
-		
-					dojo.parser.parse(dojo.byId('container'));
-					console.info("Total parse time: " + (+new Date() - loadCompleteTime) + "ms");
-		
-					dojo.byId('loaderInner').innerHTML += " done.";
-					setTimeout(function hideLoader(){
-						dojo.fadeOut({ 
-							node: 'loader', 
-							duration:500,
-							onEnd: function(n){
-								n.style.display = "none";
-							}
-						}).play();
-					}, 250);
-		
-					logStrayGlobals();
-		
-					// Fill in menu/links to get to other themes.		
-					// availableThemes[] is just a list of 'official' dijit themes, you can use ?theme=String
-					// for 'un-supported' themes, too. (eg: yours)
-					var availableThemes = [
-						{ theme:"claro", author:"Dojo", baseUri:"../themes/" },
-						{ theme:"tundra", author:"Dojo", baseUri:"../themes/" },
-						{ theme:"soria", author:"nikolai", baseUri:"../themes/" },
-						{ theme:"nihilo", author:"nikolai", baseUri:"../themes/" }
-					];
-		
-					var tmpString='';
-					dojo.forEach(availableThemes,function(theme){
-						tmpString += 
-							'<a href="?theme='+theme.theme+'">'+theme.theme+'</'+'a> (' +
-							'<a href="?theme='+theme.theme+'&dir=rtl">RTL</'+'a> ' +
-							'<a href="?theme='+theme.theme+'&a11y=true">high-contrast</'+'a> ' +
-							'<a href="?theme='+theme.theme+'&dir=rtl&a11y=true">RTL+high-contrast</'+'a> )' +
-							' - by: '+theme.author+' <br>';
-						dijit.byId('themeMenu').addChild(new dijit.MenuItem({
-							label: theme.theme,
-							onClick: function(){ location.search = "?theme=" + theme.theme; }
-						}))
-					});
-					dojo.byId('themeData').innerHTML = tmpString;
-				});
-		
-				dojo.ready(function(){
-					// It's the server's responsibility to localize the date displayed in the (non-edit) version of an InlineEditBox,
-					// but since we don't have a server we'll hack it in the client
-					dijit.byId("backgroundArea").set('value', dojo.date.locale.format(new Date(2005, 11, 30), { selector: 'date' }));
-		
-					var nineAm = new Date(0);
-					nineAm.setHours(9);
-					dijit.byId("timePicker").set('value', dojo.date.locale.format(nineAm, { selector: 'time' }));
-				});
-		
-				/***
-				dojo.ready(function(){
-					// use "before advice" to print log message each time resize is called on a layout widget
-					var origResize = dijit.layout._LayoutWidget.prototype.resize;
-					dijit.layout._LayoutWidget.prototype.resize = function(mb){
-						console.log(this + ": resize({w:"+ mb.w + ", h:" + mb.h + "})");
-						origResize.apply(this, arguments);
-					};
-		
-					// content pane has no children so just use dojo's builtin after advice
-					dojo.connect(dijit.layout.ContentPane.prototype, "resize", function(mb){
-						console.log(this + ": resize({w:"+ mb.w + ", h:" + mb.h + "})");
-					});
-				});
-				***/
+				}));
 			});
-	</script>
+			registry.byId('themeMenu').addChild(new MenuSeparator({}));
+			registry.byId('themeMenu').addChild(new CheckedMenuItem({
+				label: "RTL",
+				checked: rtl,
+				onChange: function(val){
+					// Keep current theme and a11y setting, but use new dir setting
+					setUrl(curTheme, val, a11y);
+				}
+			}));
+			registry.byId('themeMenu').addChild(new CheckedMenuItem({
+				label: "high contrast",
+				checked: a11y,
+				onChange: function(val){
+					// Keep current theme and dir setting, but use high-contrast (or not-high-contrast) setting
+					setUrl(curTheme, rtl, val);
+				}
+			}));
+
+			// It's the server's responsibility to localize the date displayed in the (non-edit) version of an InlineEditBox,
+			// but since we don't have a server we'll hack it in the client
+			registry.byId("backgroundArea").set('value', locale.format(new Date(2005, 11, 30), { selector: 'date' }));
+
+			var nineAm = new Date(0);
+			nineAm.setHours(9);
+			registry.byId("timePicker").set('value', locale.format(nineAm, { selector: 'time' }));
+		});
+	});
+</script>
 </head>
 <body class="claro">
-	<!-- basic preloader: -->
-	<div id="loader"><div id="loaderInner" style="direction:ltr;">Loading themeTester ... </div></div>
-
-	<!-- data for tree and combobox -->
-	<div data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-id="continentStore"
-		data-dojo-props="url:'../tests/_data/countries.json'"></div>
-	<div data-dojo-id="continentModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
-		rootId:"continentRoot", rootLabel:"Continents", childrenAttrs:["children"]'></div>
-	<div data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-id="stateStore"
-		data-dojo-props="url:'../tests/_data/states.json'"></div>
-	<!-- contentMenu popup -->												<!-- redundant display:none required here? -->
-	<div data-dojo-type="dijit.Menu" id="submenu1" data-dojo-props='contextMenuForWindow:true, style:"display:none"' style="display: none;">
-		<div data-dojo-type="dijit.MenuItem" 
-			data-dojo-props="onClick:function(){ alert('Hello world'); }">Enabled Item</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props="disabled:true">Disabled Item</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass:'dijitIconCut', onClick: function(){ alert('not actually cutting anything. Just a test!'); }">Cut</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass:'dijitIconCopy', onClick:function(){ alert('not actually copying anything, just a test!'); }">Copy</div>
-		<div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass:'dijitIconPaste', onClick: function(){ alert('not actually pasting anything, just a test!'); }">Paste</div>
-		<div data-dojo-type="dijit.MenuSeparator"></div>
-		<div data-dojo-type="dijit.PopupMenuItem">
-			<span>Enabled Submenu</span>
-			<div data-dojo-type="dijit.Menu" id="submenu2">
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: function(){ alert('Submenu 1!') }">Submenu Item One</div>
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: function(){ alert('Submenu 2!') }">Submenu Item Two</div>
-				<div data-dojo-type="dijit.PopupMenuItem">
-					<span>Deeper Submenu</span>
-					<div data-dojo-type="dijit.Menu" id="submenu4">
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick:function(){alert('Sub-submenu 1!')}">Sub-sub-menu Item One</div>
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick:function(){alert('Sub-submenu 2!')}">Sub-sub-menu Item Two</div>
+<!-- basic preloader: -->
+<div id="loader">
+	<div id="loaderInner" style="direction:ltr;">Loading themeTester ...</div>
+</div>
+
+<script type="dojo/require">
+	dom: "dojo/dom",
+	registry: "dijit/registry"
+</script>
+
+<!-- contentMenu popup -->                                                <!-- redundant display:none required here? -->
+<div data-dojo-type="dijit/Menu" id="submenu1" data-dojo-props='contextMenuForWindow:true, style:"display:none"'
+	 style="display: none;">
+	<div data-dojo-type="dijit/MenuItem"
+		 data-dojo-props="onClick:function(){ alert('Hello world'); }">Enabled Item
+	</div>
+	<div data-dojo-type="dijit/MenuItem" data-dojo-props="disabled:true">Disabled Item</div>
+	<div data-dojo-type="dijit/MenuSeparator"></div>
+	<div data-dojo-type="dijit/MenuItem"
+		 data-dojo-props="iconClass:'dijitIconCut', onClick: function(){ alert('not actually cutting anything. Just a test!'); }">
+		Cut
+	</div>
+	<div data-dojo-type="dijit/MenuItem"
+		 data-dojo-props="iconClass:'dijitIconCopy', onClick:function(){ alert('not actually copying anything, just a test!'); }">
+		Copy
+	</div>
+	<div data-dojo-type="dijit/MenuItem"
+		 data-dojo-props="iconClass:'dijitIconPaste', onClick: function(){ alert('not actually pasting anything, just a test!'); }">
+		Paste
+	</div>
+	<div data-dojo-type="dijit/MenuSeparator"></div>
+	<div data-dojo-type="dijit/PopupMenuItem">
+		<span>Enabled Submenu</span>
+
+		<div data-dojo-type="dijit/Menu" id="submenu2">
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="onClick: function(){ alert('Submenu 1!') }">Submenu
+				Item One
+			</div>
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="onClick: function(){ alert('Submenu 2!') }">Submenu
+				Item Two
+			</div>
+			<div data-dojo-type="dijit/PopupMenuItem">
+				<span>Deeper Submenu</span>
+
+				<div data-dojo-type="dijit/Menu" id="submenu4">
+					<div data-dojo-type="dijit/MenuItem" data-dojo-props="onClick:function(){alert('Sub-submenu 1!')}">
+						Sub-sub-menu Item One
+					</div>
+					<div data-dojo-type="dijit/MenuItem" data-dojo-props="onClick:function(){alert('Sub-submenu 2!')}">
+						Sub-sub-menu Item Two
 					</div>
 				</div>
 			</div>
 		</div>
-		<div data-dojo-type="dijit.PopupMenuItem" data-dojo-props="disabled:true">
-			<span>Disabled Submenu</span>
-			<div data-dojo-type="dijit.Menu" id="submenu3" style="display: none;">
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick:function(){alert('Submenu 1!')}">Submenu Item One</div>
-				<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick:function(){alert('Submenu 2!')}">Submenu Item Two</div>
+	</div>
+	<div data-dojo-type="dijit/PopupMenuItem" data-dojo-props="disabled:true">
+		<span>Disabled Submenu</span>
+
+		<div data-dojo-type="dijit/Menu" id="submenu3" style="display: none;">
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="onClick:function(){alert('Submenu 1!')}">Submenu Item
+				One
+			</div>
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="onClick:function(){alert('Submenu 2!')}">Submenu Item
+				Two
 			</div>
-		</div>
-		<div data-dojo-type="dijit.PopupMenuItem">
-			<span>Different popup</span>
-			<div data-dojo-type="dijit.ColorPalette"></div>
-		</div>
-		<div data-dojo-type="dijit.PopupMenuItem">
-			<span>Different popup</span>
-			<div data-dojo-type="dijit.Calendar"></div>
 		</div>
 	</div>
-	<!-- end contextMenu -->
+	<div data-dojo-type="dijit/PopupMenuItem">
+		<span>Different popup</span>
 
-	<div id="main" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="liveSplitters:false, design:'sidebar'">
+		<div data-dojo-type="dijit/ColorPalette"></div>
+	</div>
+	<div data-dojo-type="dijit/PopupMenuItem">
+		<span>Different popup</span>
 
-		<div id="header" data-dojo-type="dijit.MenuBar" data-dojo-props="region:'top'">
-			<div data-dojo-type="dijit.PopupMenuBarItem" id="file">
-				<span>File</span>
-				<div data-dojo-type="dijit.Menu" id="fileMenu">
-					<div data-dojo-type="dijit.MenuItem" id="globals" data-dojo-props="onClick: logStrayGlobals">Log globals</div>
-					<div data-dojo-type="dijit.MenuItem" id="widgets" data-dojo-props="onClick: logWidgets">Log widgets</div>
-					<div data-dojo-type="dijit.MenuItem" id="destroy" data-dojo-props="iconClass:'dijitIconDelete', onClick:tearDown">Destroy All</div>
-				</div>
+		<div data-dojo-type="dijit/Calendar"></div>
+	</div>
+</div>
+<!-- end contextMenu -->
+
+<div id="main" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="liveSplitters:false, design:'sidebar'">
+
+<div id="header" data-dojo-type="dijit/MenuBar" data-dojo-props="region:'top'">
+	<div data-dojo-type="dijit/PopupMenuBarItem" id="file">
+		<span>File</span>
+
+		<div data-dojo-type="dijit/Menu" id="fileMenu">
+			<div data-dojo-type="dijit/MenuItem" id="globals" data-dojo-props="onClick: logStrayGlobals">Log globals
+			</div>
+			<div data-dojo-type="dijit/MenuItem" id="widgets" data-dojo-props="onClick: logWidgets">Log widgets</div>
+			<div data-dojo-type="dijit/MenuItem" id="destroy"
+				 data-dojo-props="iconClass:'dijitIconDelete', onClick:tearDown">Destroy All
 			</div>
-			<div data-dojo-type="dijit.PopupMenuBarItem" id="edit">
-				<span>Edit</span>
-				<div data-dojo-type="dijit.Menu" id="editMenu">
-					<div data-dojo-type="dijit.MenuItem" id="cut" data-dojo-props="
+		</div>
+	</div>
+	<div data-dojo-type="dijit/PopupMenuBarItem" id="edit">
+		<span>Edit</span>
+
+		<div data-dojo-type="dijit/Menu" id="editMenu">
+			<div data-dojo-type="dijit/MenuItem" id="cut" data-dojo-props="
 						iconClass:'dijitIconCut',
 						onClick:function(){ console.log('not actually cutting anything, just a test!') }
-					">Cut</div>
-					<div data-dojo-type="dijit.MenuItem" id="copy" data-dojo-props="
+					">Cut
+			</div>
+			<div data-dojo-type="dijit/MenuItem" id="copy" data-dojo-props="
 						iconClass:'dijitIconCopy',
 						onClick: function(){ console.log('not actually copying anything, just a test!') }
-					">Copy</div>
-					<div data-dojo-type="dijit.MenuItem" id="paste" data-dojo-props="iconClass:'dijitIconPaste',
-						onClick: function(){ console.log('not actually pasting anything, just a test!') }">Paste</div>
-					<div data-dojo-type="dijit.MenuSeparator" id="separator"></div>
-					<div data-dojo-type="dijit.MenuItem" id="undo" data-dojo-props="iconClass:'dijitIconUndo'">Undo</div>
-				</div>
-			</div>
-			<div data-dojo-type="dijit.PopupMenuBarItem" id="view">
-				<span>View</span>
-				<div data-dojo-type="dijit.Menu" id="viewMenu">
-					<div data-dojo-type="dijit.MenuItem">Normal</div>
-					<div data-dojo-type="dijit.MenuItem">Outline</div>
-					<div data-dojo-type="dijit.PopupMenuItem">
-						<span>Zoom</span>
-						<div data-dojo-type="dijit.Menu" id="zoomMenu">
-							<div data-dojo-type="dijit.MenuItem">50%</div>
-							<div data-dojo-type="dijit.MenuItem">75%</div>
-							<div data-dojo-type="dijit.MenuItem">100%</div>
-							<div data-dojo-type="dijit.MenuItem">150%</div>
-							<div data-dojo-type="dijit.MenuItem">200%</div>
-						</div>
-					</div>
-				</div>
-			</div>
-			<div data-dojo-type="dijit.PopupMenuBarItem" id="themes">
-				<span>Themes</span>
-				<div data-dojo-type="dijit.Menu" id="themeMenu"></div>
+					">Copy
 			</div>
-			<div data-dojo-type="dijit.PopupMenuBarItem" id="dialogs">
-				<span>Dialogs</span>
-				<div data-dojo-type="dijit.Menu" id="dialogMenu">
-					<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: showDialog">slow loading</div>
-					<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: showDialogAb">action bar</div>
-				</div>
-			</div>
-			<div data-dojo-type="dijit.PopupMenuBarItem" id="inputPadding">
-				<span>TextBox Padding</span>
-				<div data-dojo-type="dijit.Menu" id="inputPaddingMenu">
-					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding, checked:true">theme default</div>
-					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">0px</div>
-					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">1px</div>
-					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">2px</div>
-					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">3px</div>
-					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">4px</div>
-					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">5px</div>
-				</div>
+			<div data-dojo-type="dijit/MenuItem" id="paste" data-dojo-props="iconClass:'dijitIconPaste',
+						onClick: function(){ console.log('not actually pasting anything, just a test!') }">Paste
 			</div>
-			<div data-dojo-type="dijit.PopupMenuBarItem" id="help">
-				<span>Help</span>
-				<div data-dojo-type="dijit.Menu" id="helpMenu">
-					<div data-dojo-type="dijit.MenuItem">Help Topics</div>
-					<div data-dojo-type="dijit.MenuItem">About Dijit</div>
-				</div>
-			</div>
-			<div data-dojo-type="dijit.PopupMenuBarItem" data-dojo-props="disabled:true">
-				<span>Disabled</span>
-				<div data-dojo-type="dijit.Menu">
-					<div data-dojo-type="dijit.MenuItem">You should not see this</div>
+			<div data-dojo-type="dijit/MenuSeparator" id="separator"></div>
+			<div data-dojo-type="dijit/MenuItem" id="undo" data-dojo-props="iconClass:'dijitIconUndo'">Undo</div>
+		</div>
+	</div>
+	<div data-dojo-type="dijit/PopupMenuBarItem" id="view">
+		<span>View</span>
+
+		<div data-dojo-type="dijit/Menu" id="viewMenu">
+			<div data-dojo-type="dijit/MenuItem">Normal</div>
+			<div data-dojo-type="dijit/MenuItem">Outline</div>
+			<div data-dojo-type="dijit/PopupMenuItem">
+				<span>Zoom</span>
+
+				<div data-dojo-type="dijit/Menu" id="zoomMenu">
+					<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'zoom'">50%</div>
+					<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'zoom'">75%</div>
+					<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'zoom', checked:true">100%</div>
+					<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'zoom'">150%</div>
+					<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'zoom'">200%</div>
 				</div>
 			</div>
-			<div data-dojo-type="dijit.MenuBarItem" data-dojo-props="onclick: function(){ alert('no submenu, just a clickable MenuItem'); }">
-				Click me!
+		</div>
+	</div>
+	<div data-dojo-type="dijit/PopupMenuBarItem" id="themes">
+		<span>Themes</span>
+
+		<div data-dojo-type="dijit/Menu" id="themeMenu"></div>
+	</div>
+	<div data-dojo-type="dijit/PopupMenuBarItem" id="dialogs">
+		<span>Dialogs</span>
+
+		<div data-dojo-type="dijit/Menu" id="dialogMenu">
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="onClick: showDialog">slow loading</div>
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="onClick: showDialogAb">action bar</div>
+		</div>
+	</div>
+	<div data-dojo-type="dijit/PopupMenuBarItem" id="inputPadding">
+		<span>TextBox Padding</span>
+
+		<div data-dojo-type="dijit/Menu" id="inputPaddingMenu">
+			<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'padding', onClick:setTextBoxPadding, checked:true">theme
+				default
 			</div>
+			<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'padding', onClick:setTextBoxPadding">0px</div>
+			<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'padding', onClick:setTextBoxPadding">1px</div>
+			<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'padding', onClick:setTextBoxPadding">2px</div>
+			<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'padding', onClick:setTextBoxPadding">3px</div>
+			<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'padding', onClick:setTextBoxPadding">4px</div>
+			<div data-dojo-type="dijit/RadioMenuItem" data-dojo-props="group:'padding', onClick:setTextBoxPadding">5px</div>
 		</div>
+	</div>
+	<div data-dojo-type="dijit/PopupMenuBarItem" id="help">
+		<span>Help</span>
 
-		<div data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props="region:'leading', splitter:true, minSize:20"
-			style="width: 300px;" id="leftAccordion">
+		<div data-dojo-type="dijit/Menu" id="helpMenu">
+			<div data-dojo-type="dijit/MenuItem">Help Topics</div>
+			<div data-dojo-type="dijit/MenuItem">About Dijit</div>
+		</div>
+	</div>
+	<div data-dojo-type="dijit/PopupMenuBarItem" data-dojo-props="disabled:true">
+		<span>Disabled</span>
+
+		<div data-dojo-type="dijit/Menu">
+			<div data-dojo-type="dijit/MenuItem">You should not see this</div>
+		</div>
+	</div>
+</div>
+
+<div data-dojo-type="dijit/layout/AccordionContainer" data-dojo-props="region:'leading', splitter:true, minSize:20"
+	 style="width: 300px;" id="leftAccordion">
 
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Popups and Alerts"'><div style="padding:8px">
-				<h2>Tooltips</h2>
-				<ul>
-					<li>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Popups and Alerts"'>
+		<div style="padding:8px">
+			<h2>Tooltips</h2>
+			<ul>
+				<li>
 					<span id="ttRich"><b>rich</b> <i>text</i> tooltip</span>
-					<span data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttRich'" style="display:none;">
-						Embedded <b>bold</b> <i>RICH</i> text <span style="color:#309; font-size:x-large;">weirdness!</span>
+					<span data-dojo-type="dijit/Tooltip" data-dojo-props="connectId:'ttRich'" style="display:none;">
+						Embedded <b>bold</b> <i>RICH</i> text <span
+							style="color:#309; font-size:x-large;">weirdness!</span>
 					</span>
-					</li>
-
-					<li><a id="ttOne" href='#bogus'>anchor tooltip</a>
-					<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:"ttOne"' style="display:none;">tooltip on anchor</span>
-					</li>
-				</ul>
-
-				<table style="width: 100%;">
-					<tr>
-						<td></td>
-						<td>
-							<div id="ttBelow">tooltip below</div>
-							<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttBelow', position:['below']" style="display:none; width: 100px;">I'm <i>below</i>!</div>
-						</td>
-						<td></td>
-					</tr>
-					<tr>
-						<td>
-							<div id="ttRight">tooltip after</div>
-							<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttRight', position:['after']" style="display:none;">I'm on the <i>right</i>!<br>(or left on RTL systems)</div>
-						</td>
-						<td></td>
-						<td>
-							<div id="ttLeft">tooltip before</div>
-							<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttLeft', position:['before','after']" style="display:none;">I'm on the <i>left</i>!<br>(or right on RTL systems)</div>
-						</td>
-					</tr>
-					<tr>
-						<td></td>
-						<td>
-							<div id="ttAbove">tooltip above</div>
-							<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttAbove', position:['above']" style="display:none;">I'm <i>above</i>!</div>
-						</td>
-						<td></td>
-					</tr>
-				</table>
-
-				<hr class="spacer">
-
-				<h2>Dialogs</h2>
-				<ul>
-					<li><a href="#" onclick="dijit.byId('dialog1').show()">slow loading modal dialog</a></li>
-					<li><a href="#" onclick="dijit.byId('dialogAB').show()">modal dialog w/action bar</a></li>
-				</ul>
-
-				<div data-dojo-type="dijit.form.DropDownButton">
-					<span>Show Tooltip Dialog</span>
-					<div data-dojo-type="dijit.TooltipDialog" id="tooltipDlg" data-dojo-props='
+				</li>
+
+				<li><a id="ttOne" href='#bogus'>anchor tooltip</a>
+					<span data-dojo-type="dijit/Tooltip" data-dojo-props='connectId:"ttOne"' style="display:none;">tooltip on anchor</span>
+				</li>
+			</ul>
+
+			<table style="width: 100%;">
+				<tr>
+					<td></td>
+					<td>
+						<div id="ttBelow">tooltip below</div>
+						<div data-dojo-type="dijit/Tooltip"
+							 data-dojo-props="connectId:'ttBelow', position:['below-centered']"
+							 style="display:none; width: 100px;">I'm <i>below</i>!
+						</div>
+					</td>
+					<td></td>
+				</tr>
+				<tr>
+					<td>
+						<div id="ttRight">tooltip after</div>
+						<div data-dojo-type="dijit/Tooltip"
+							 data-dojo-props="connectId:'ttRight', position:['after-centered']" style="display:none;">
+							I'm on the <i>right</i>!<br>(or left on RTL systems)
+						</div>
+					</td>
+					<td></td>
+					<td>
+						<div id="ttLeft">tooltip before</div>
+						<div data-dojo-type="dijit/Tooltip"
+							 data-dojo-props="connectId:'ttLeft', position:['before-centered','after-centered']"
+							 style="display:none;">I'm on the <i>left</i>!<br>(or right on RTL systems)
+						</div>
+					</td>
+				</tr>
+				<tr>
+					<td></td>
+					<td>
+						<div id="ttAbove">tooltip above</div>
+						<div data-dojo-type="dijit/Tooltip"
+							 data-dojo-props="connectId:'ttAbove', position:['above-centered']" style="display:none;">
+							I'm <i>above</i>!
+						</div>
+					</td>
+					<td></td>
+				</tr>
+			</table>
+
+			<hr class="spacer">
+
+			<h2>Dialogs</h2>
+			<ul>
+				<li><a href="#" onclick="registry.byId('dialog1').show()">slow loading modal dialog</a></li>
+				<li><a href="#" onclick="registry.byId('dialogAB').show()">modal dialog w/action bar</a></li>
+			</ul>
+
+			<div data-dojo-type="dijit/form/DropDownButton">
+				<span>Show Tooltip Dialog</span>
+
+				<div data-dojo-type="dijit/TooltipDialog" id="tooltipDlg" data-dojo-props='
 						title:"Enter Login information",
 						execute: function(){ alert("submitted w/args:\n" + dojo.toJson(arguments[0], true)); }
 					'>
-						<table>
-							<tr>
-								<td><label for="user">User:</label></td>
-								<td><input data-dojo-type="dijit.form.TextBox" type="text" id="user" name="user" ></td>
-							</tr>
-							<tr>
-								<td><label for="pwd">Password:</label></td>
-								<td><input data-dojo-type="dijit.form.TextBox" type="password" id="pwd" name="pwd"></td>
-							</tr>
-							<tr>
-								<td colspan="2">
-									<button data-dojo-type="dijit.form.Button" type="submit" name="submit">Login</button>
-							</tr>
-						</table>
-					</div>
+					<table>
+						<tr>
+							<td><label for="user">User:</label></td>
+							<td><input data-dojo-type="dijit/form/TextBox" type="text" id="user" name="user"></td>
+						</tr>
+						<tr>
+							<td><label for="pwd">Password:</label></td>
+							<td><input data-dojo-type="dijit/form/TextBox" type="password" id="pwd" name="pwd"></td>
+						</tr>
+						<tr>
+							<td colspan="2">
+								<button data-dojo-type="dijit/form/Button" type="submit" name="submit">Login</button>
+						</tr>
+					</table>
 				</div>
 			</div>
-			</div>
+		</div>
+	</div>
 
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tree"'>
-				<!-- tree widget -->
-				<div data-dojo-type="dijit.Tree" 
-					data-dojo-props="model: continentModel, query:{ type:'continent'}, label:'Continents', openOnClick:true"
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Tree"'>
+		<!-- tree widget -->
+		<div data-dojo-type="dijit/Tree"
+			 data-dojo-props="model: continentModel, query:{ type:'continent'}, label:'Continents', openOnClick:true"
 				></div>
-			</div>
+	</div>
 
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Rootless Tree'">
-				<div id="rootlessTree" data-dojo-type="dijit.Tree" data-dojo-props="
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="title:'Rootless Tree'">
+		<div id="rootlessTree" data-dojo-type="dijit/Tree" data-dojo-props="
 					model:continentModel,
 					query:{ type:'continent' },
 					showRoot: false,
 					openOnClick:true
 				"></div>
-			</div>
+	</div>
 
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true, title:"Calendar"'>
-				<!-- calendar widget pane -->
-				<input id="calendar1" data-dojo-type="dijit.Calendar">
-			</div>
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='selected:true, title:"Calendar"'>
+		<!-- calendar widget pane -->
+		<input id="calendar1" data-dojo-type="dijit/Calendar">
+	</div>
 
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Color Picker"'>
-				<p>
-					Selecting a color will change the background color of the page.
-					Use this to test how tooltips and drop downs appear with different backgrounds.
-				</p>
-				<h2 class="testHeader">3x4</h2>
-				<script>
-					function setBackground(color){
-						dojo.query('.dijitAccordionBody').style('background', color);
-						dojo.query('.dijitTabPaneWrapper').style('background', color);
-					}
-				</script>
-				<div data-dojo-type="dijit.ColorPalette" data-dojo-props="palette:'3x4', onChange:setBackground"></div>
-				<h2 class="testHeader">7x10</h2>
-				<div data-dojo-type="dijit.ColorPalette" data-dojo-props="onChange:setBackground"></div>
-			</div>
-		</div><!-- end AccordionContainer -->
+	<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Color Picker"'>
+		<p>
+			Selecting a color will change the background color of the page.
+			Use this to test how tooltips and drop downs appear with different backgrounds.
+		</p>
+
+		<h2 class="testHeader">3x4</h2>
+		<script>
+			function setBackground(color){
+				dojo.query('.dijitAccordionBody').style('background', color);
+				dojo.query('.dijitTabPaneWrapper').style('background', color);
+			}
+		</script>
+		<div data-dojo-type="dijit/ColorPalette" data-dojo-props="palette:'3x4', onChange:setBackground"></div>
+		<h2 class="testHeader">7x10</h2>
+
+		<div data-dojo-type="dijit/ColorPalette" data-dojo-props="onChange:setBackground"></div>
+	</div>
+</div>
+<!-- end AccordionContainer -->
+
+<!-- top tabs (marked as "center" to take up the main part of the BorderContainer) -->
+<div data-dojo-type="dijit/layout/TabContainer" data-dojo-props="region:'center', tabStrip:true" id="topTabs">
 
-		<!-- top tabs (marked as "center" to take up the main part of the BorderContainer) -->
-		<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props="region:'center', tabStrip:true" id="topTabs">
+<div id="basicFormTab" data-dojo-type="dijit/layout/ContentPane"
+	 data-dojo-props="title:'Basic Form Widgets', style:'padding:10px;display:none;'">
 
-			<div id="basicFormTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Basic Form Widgets', style:'padding:10px;display:none;'">
+	<h2>Buttons</h2>
 
-				<h2>Buttons</h2>
-				<p>Buttons can do an action, display a menu, or both:</p>
+	<p>Buttons can do an action, display a menu, or both:</p>
 
-				Enabled:
+	Enabled:
 
-				<button data-dojo-type="dijit.form.Button" data-dojo-props="iconClass:'dijitIconTask', onClick:function(){ console.debug('clicked simple') }">
-					Simple
-				</button>
+	<button data-dojo-type="dijit/form/Button"
+			data-dojo-props="iconClass:'dijitIconTask', onClick:function(){ console.debug('clicked simple') }">
+		Simple
+	</button>
 
-				<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props="iconClass:'dijitIconEdit'">
-					<span>Drop Down</span>
-					<div data-dojo-type="dijit.Menu" id="editMenu1" style="display: none;">
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+	<div data-dojo-type="dijit/form/DropDownButton" data-dojo-props="iconClass:'dijitIconEdit'">
+		<span>Drop Down</span>
+
+		<div data-dojo-type="dijit/Menu" id="editMenu1" style="display: none;">
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="
 							iconClass:'dijitIconCut',
 							onClick:function(){ console.debug('not actually cutting anything, just a test!') }
-						">Cut</div>
+						">Cut
+			</div>
 
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="
 							iconClass:'dijitIconCopy',
 							onClick:function(){ console.debug('not actually copying anyything, just a test!'); }
-						">Copy</div>
+						">Copy
+			</div>
 
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="
 							iconClass:'dijitIconPaste',
 							onClick:function(){ console.debug('not actually pasting anyything, just a test!'); }
-						">Paste</div>
-					</div>
-				</div>
+						">Paste
+			</div>
+		</div>
+	</div>
+
+	<div data-dojo-type="dijit/form/ComboButton"
+		 data-dojo-props='iconClass:"dijitIconSave", optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); }'>
+		<span>Combo</span>
 
-				<div data-dojo-type="dijit.form.ComboButton" data-dojo-props='iconClass:"dijitIconSave", optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); }'>
-					<span>Combo</span>
-					<div data-dojo-type="dijit.Menu" id="saveMenu1" style="display: none;">
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+		<div data-dojo-type="dijit/Menu" id="saveMenu1" style="display: none;">
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="
 							iconClass:'dijitIconSave',
 							onClick: function(){ console.debug('not actually saving anything, just a test!') }
-						">Save</div>
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+						">Save
+			</div>
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="
 							onClick: function(){ console.debug('not actually saving anything, just a test!') }
-						">Save As</div>
-					</div>
-				</div>
+						">Save As
+			</div>
+		</div>
+	</div>
 
-				<div data-dojo-type="dijit.form.ToggleButton" data-dojo-props="
+	<div data-dojo-type="dijit/form/ToggleButton" data-dojo-props="
 					checked:true, 
 					onChange: function(a){ console.log('toggle button checked=' + a); }, iconClass:'dijitCheckBoxIcon'
-				"> Toggle </div>
+				"> Toggle
+	</div>
 
-				<hr class="spacer">
+	<hr class="spacer">
 
-				Disabled:
+	Disabled:
 
-				<button data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitIconTask", disabled:true' disabled>
-					Simple
-				</button>
+	<button data-dojo-type="dijit/form/Button" data-dojo-props='iconClass:"dijitIconTask", disabled:true' disabled>
+		Simple
+	</button>
 
-				<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitIconEdit", disabled:true'>
-					<span>Drop Down</span>
-					<ul data-dojo-type="dijit.Menu" id="editMenu2" style="display: none;">
-						<li data-dojo-type="dijit.MenuItem" data-dojo-props="
+	<div data-dojo-type="dijit/form/DropDownButton" data-dojo-props='iconClass:"dijitIconEdit", disabled:true'>
+		<span>Drop Down</span>
+		<ul data-dojo-type="dijit/Menu" id="editMenu2" style="display: none;">
+			<li data-dojo-type="dijit/MenuItem" data-dojo-props="
 							iconClass:'dijitIconCut',
 							onClick: function(){ console.debug('not actually cutting anything, just a test!') }
-						">Cut</li>
+						">Cut
+			</li>
 
-						<li data-dojo-type="dijit.MenuItem" data-dojo-props="
+			<li data-dojo-type="dijit/MenuItem" data-dojo-props="
 							iconClass:'dijitIconCopy',
 							onClick: function(){ console.debug('not actually copying anything, just a test!') }
-						">Copy</li>
+						">Copy
+			</li>
 
-						<li data-dojo-type="dijit.MenuItem" data-dojo-props="
+			<li data-dojo-type="dijit/MenuItem" data-dojo-props="
 							iconClass:'dijitIconPaste',
 							onClick: function(){ console.debug('not actually pasting anything, just a test!') }
-						">Paste</li>
-					</ul>
-				</div>
+						">Paste
+			</li>
+		</ul>
+	</div>
+
+	<div data-dojo-type="dijit/form/ComboButton"
+		 data-dojo-props="iconClass:'dijitIconSave', optionsTitle:'save options', disabled:true">
+		<span>Combo</span>
 
-				<div data-dojo-type="dijit.form.ComboButton" data-dojo-props="iconClass:'dijitIconSave', optionsTitle:'save options', disabled:true">
-					<span>Combo</span>
-					<div data-dojo-type="dijit.Menu" id="saveMenu2" style="display: none;">
-						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+		<div data-dojo-type="dijit/Menu" id="saveMenu2" style="display: none;">
+			<div data-dojo-type="dijit/MenuItem" data-dojo-props="
 							iconCLass:'dijitIconSave',
 							onClick:function(){ console.log('not actually saving anything, just a test!' ); }
-						">Save</div>
-						<div data-dojo-type="dijit.MenuItem"
-							onClick="console.debug('not actually saving anything, just a test!')">
-							Save As
-						</div>
-					</div>
-				</div>
+						">Save
+			</div>
+			<div data-dojo-type="dijit/MenuItem"
+				 onClick="console.debug('not actually saving anything, just a test!')">
+				Save As
+			</div>
+		</div>
+	</div>
 
-				<button data-dojo-type="dijit.form.ToggleButton" data-dojo-props="checked:true, disabled:true, iconClass:'dijitCheckBoxIcon'">
-					Toggle
-				</button>
-
-				<hr class="spacer">
-
-				<h2>CheckBox</h2>
-				<fieldset>
-					<input id="check1" type="checkBox" data-dojo-type="dijit.form.CheckBox">
-					<label for="check1">unchecked</label>
-
-					<input id="check2" type="checkBox" data-dojo-type="dijit.form.CheckBox" data-dojo-props="checked:true" checked="checked">
-					<label for="check2">checked</label>
-
-					<input id="check3" type="checkBox" data-dojo-type="dijit.form.CheckBox" data-dojo-props='disabled:true' disabled>
-					<label for="check3">disabled</label>
-
-					<input id="check4" type="checkBox" data-dojo-type="dijit.form.CheckBox"	 data-dojo-props='disabled:true, checked:true' checked="checked" disabled>
-					<label for="check4">disabled and checked</label>
-				</fieldset>
-
-				<h2>Radio Buttons</h2>
-				<fieldset>
-					<input type="radio" name="g1" id="g1rb1" value="news" data-dojo-type="dijit.form.RadioButton">
-					<label for="g1rb1">news</label>
-					<input type="radio" name="g1" id="g1rb2" value="talk" data-dojo-type="dijit.form.RadioButton"  data-dojo-props='checked:true' checked>
-					<label for="g1rb2">talk</label>
-					<input type="radio" name="g1" id="g1rb3" value="weather" data-dojo-type="dijit.form.RadioButton"  data-dojo-props='disabled:true' disabled>
-					<label for="g1rb3">weather (disabled)</label>
-				</fieldset>
-			</div> <!-- end of basic form widgets -->
-
-			<div id="textboxTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Text Input Widgets", style:"padding:10px;display:none;"'>
-
-				<h2>dijit.form.DateTextBox</h2>
-				<label for="date1">Enabled w/placeHolder:</label>
-				<input id="date1" name="date1" type="text" data-dojo-type="dijit.form.DateTextBox" data-dojo-props="placeHolder:'Birthday'">
-				<label for="date2">Disabled w/placeHolder:</label>
-				<input id="date2" name="date2" type="text" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='placeHolder:"Birthday", disabled:true'>
-				<label for="date2">Disabled w/value:</label>
-				<input id="date3" name="date3" type="text" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='value:"2008-12-25", disabled:true'>
-
-				<h2>dijit.form.TimeTextBox</h2>
-				<label for="time1">Enabled:</label>
-				<input id="time1" name="time1" type="text" data-dojo-type="dijit.form.TimeTextBox" value="T17:45:00">
-				<label for="time2">Disabled:</label>
-				<input id="time2" name="time2" type="text" data-dojo-type="dijit.form.TimeTextBox" value="T17:45:00"  data-dojo-props='disabled:true' disabled>
-
-				<h2>dijit.form.CurrencyTextBox</h2>
-				<label for="currency1">Enabled:</label>
-				<input id="currency1" type="text" name="income1" value="54775.53" data-dojo-type="dijit.form.CurrencyTextBox"
-					data-dojo-props="
+	<button data-dojo-type="dijit/form/ToggleButton"
+			data-dojo-props="checked:true, disabled:true, iconClass:'dijitCheckBoxIcon'">
+		Toggle
+	</button>
+
+	<hr class="spacer">
+
+	<h2>CheckBox</h2>
+	<fieldset>
+		<input id="check1" type="checkBox" data-dojo-type="dijit/form/CheckBox">
+		<label for="check1">unchecked</label>
+
+		<input id="check2" type="checkBox" data-dojo-type="dijit/form/CheckBox" data-dojo-props="checked:true"
+			   checked="checked">
+		<label for="check2">checked</label>
+
+		<input id="check3" type="checkBox" data-dojo-type="dijit/form/CheckBox" data-dojo-props='disabled:true'
+			   disabled>
+		<label for="check3">disabled</label>
+
+		<input id="check4" type="checkBox" data-dojo-type="dijit/form/CheckBox"
+			   data-dojo-props='disabled:true, checked:true' checked="checked" disabled>
+		<label for="check4">disabled and checked</label>
+	</fieldset>
+
+	<h2>Radio Buttons</h2>
+	<fieldset>
+		<input type="radio" name="g1" id="g1rb1" value="news" data-dojo-type="dijit/form/RadioButton">
+		<label for="g1rb1">news</label>
+		<input type="radio" name="g1" id="g1rb2" value="talk" data-dojo-type="dijit/form/RadioButton"
+			   data-dojo-props='checked:true' checked>
+		<label for="g1rb2">talk</label>
+		<input type="radio" name="g1" id="g1rb3" value="weather" data-dojo-type="dijit/form/RadioButton"
+			   data-dojo-props='disabled:true' disabled>
+		<label for="g1rb3">weather <span dir="ltr">(disabled)</span></label>
+	</fieldset>
+</div>
+<!-- end of basic form widgets -->
+
+<div id="textboxTab" data-dojo-type="dijit/layout/ContentPane"
+	 data-dojo-props='title:"Text Input Widgets", style:"padding:10px;display:none;"'>
+
+	<h2>dijit/form/DateTextBox</h2>
+	<label for="date1">Enabled w/placeHolder:</label>
+	<input id="date1" name="date1" type="text" data-dojo-type="dijit/form/DateTextBox"
+		   data-dojo-props="placeHolder:'Birthday'">
+	<label for="date2">Disabled w/placeHolder:</label>
+	<input id="date2" name="date2" type="text" data-dojo-type="dijit/form/DateTextBox"
+		   data-dojo-props='placeHolder:"Birthday", disabled:true'>
+	<label for="date2">Disabled w/value:</label>
+	<input id="date3" name="date3" type="text" data-dojo-type="dijit/form/DateTextBox"
+		   data-dojo-props='value:"2008-12-25", disabled:true'>
+
+	<h2>dijit/form/TimeTextBox</h2>
+	<label for="time1">Enabled:</label>
+	<input id="time1" name="time1" type="text" data-dojo-type="dijit/form/TimeTextBox" value="T17:45:00">
+	<label for="time2">Disabled:</label>
+	<input id="time2" name="time2" type="text" data-dojo-type="dijit/form/TimeTextBox" value="T17:45:00"
+		   data-dojo-props='disabled:true' disabled>
+
+	<h2>dijit/form/CurrencyTextBox</h2>
+	<label for="currency1">Enabled:</label>
+	<input id="currency1" type="text" name="income1" value="54775.53" data-dojo-type="dijit/form/CurrencyTextBox"
+		   data-dojo-props="
 						required:true, constraints:{ fractional:true }, currency:'USD',
 						value:54775.53,
 						invalidMessage:'Invalid amount.	 Include dollar sign, commas, and cents.  Cents are mandatory.'
 				">
-				<label for="currency2">Disabled:</label>
-				<input id="currency2" type="text" name="income1" value="54775.53"
-					data-dojo-type="dijit.form.CurrencyTextBox" data-dojo-props="required:true, constraints:{ fractional:true },
+	<label for="currency2">Disabled:</label>
+	<input id="currency2" type="text" name="income1" value="54775.53"
+		   data-dojo-type="dijit/form/CurrencyTextBox" data-dojo-props="required:true, constraints:{ fractional:true },
 						currency:'USD', invalidMessage:'Invalid amount.	 Include dollar sign, commas, and cents.  Cents are mandatory.',
 						disabled:true
 				">
-				
-				<hr class="spacer">
-
-				<h2>dijit.form.NumberSpinner max=100</h2>
-				<label for="spinner1">Enabled: </label>
-				<input data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='constraints:{max:100,places:0}, value:10' id="spinner1">
-				<label for="spinner2">Disabled: </label>
-				<input data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='constraints:{max:100,places:0}, value:10, disabled:true' id="spinner2">
 
-			</div>
+	<hr class="spacer">
+
+	<h2>dijit/form/NumberSpinner max=100</h2>
+	<label for="spinner1">Enabled: </label>
+	<input data-dojo-type="dijit/form/NumberSpinner" data-dojo-props='constraints:{max:100,places:0}, value:10'
+		   id="spinner1">
+	<label for="spinner2">Disabled: </label>
+	<input data-dojo-type="dijit/form/NumberSpinner"
+		   data-dojo-props='constraints:{max:100,places:0}, value:10, disabled:true' id="spinner2">
+
+</div>
+
+<div id="selectTab" data-dojo-type="dijit/layout/ContentPane"
+	 data-dojo-props="title:'Select Widgets', style:'padding:10px;display:none;'">
+
+	<h2>dijit/form/Select</h2>
+	<!-- fixme: <label for=""> but target a form element like input select etc -->
+	<label>Enabled:</label>
+
+	<div id="selectEnabled" data-dojo-type="dijit/form/Select" data-dojo-props="value:'AK'">
+		<span data-dojo-value="AL"><b>Alabama</b></span>
+		<span data-dojo-value="AK"><span style="color:red">A</span><span style="color:orange">l</span><span
+				style="color:yellow">a</span><span style="color:green">s</span><span style="color:blue">k</span><span
+				style="color:purple">a</span></span>
+		<span data-dojo-value="AZ"><i>Arizona</i></span>
+		<span data-dojo-value="AR"><span class="ark">Arkansas</span></span>
+		<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span
+				style="font-size:75%">l</span><span style="font-size:90%">i</span><span
+				style="font-size:100%">f</span><span style="font-size:125%">o</span><span
+				style="font-size:133%">r</span><span style="font-size:150%">n</span><span
+				style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
+		<span data-dojo-value="NM">New<br>  Mexico</span>
+	</div>
 
-			<div id="selectTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Select Widgets', style:'padding:10px;display:none;'">
-
-				<h2>dijit.form.Select</h2>
-				<!-- fixme: <label for=""> but target a form element like input select etc -->
-				<label>Enabled:</label>
-				<div id="selectEnabled" data-dojo-type="dijit.form.Select" data-dojo-props="value:'AK'">
-					<span data-dojo-value="AL"><b>Alabama</b></span>
-					<span data-dojo-value="AK"><span style="color:red">A</span><span style="color:orange">l</span><span style="color:yellow">a</span><span style="color:green">s</span><span style="color:blue">k</span><span style="color:purple">a</span></span>
-					<span data-dojo-value="AZ"><i>Arizona</i></span>
-					<span data-dojo-value="AR"><span class="ark">Arkansas</span></span>
-					<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
-					<span data-dojo-value="NM">New<br>  Mexico</span>
-				</div>
-	
-				<label>Disabled: </label>
-				<div id="selectDisabled" data-dojo-props="value:'AK', disabled:true" data-dojo-type="dijit.form.Select">
-					<span data-dojo-value="AL"><b>Alabama</b></span>
-					<span data-dojo-value="AK"><span style="color:red">A</span><span style="color:orange">l</span><span style="color:yellow">a</span><span style="color:green">s</span><span style="color:blue">k</span><span style="color:purple">a</span></span>
-					<span data-dojo-value="AZ"><i>Arizona</i></span>
-					<span data-dojo-value="AR"><span class="ark">Arkansas</span></span>
-					<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
-					<span data-dojo-value="NM">New<br>  Mexico</span>
-				</div>
+	<label>Disabled: </label>
+
+	<div id="selectDisabled" data-dojo-props="value:'AK', disabled:true" data-dojo-type="dijit/form/Select">
+		<span data-dojo-value="AL"><b>Alabama</b></span>
+		<span data-dojo-value="AK"><span style="color:red">A</span><span style="color:orange">l</span><span
+				style="color:yellow">a</span><span style="color:green">s</span><span style="color:blue">k</span><span
+				style="color:purple">a</span></span>
+		<span data-dojo-value="AZ"><i>Arizona</i></span>
+		<span data-dojo-value="AR"><span class="ark">Arkansas</span></span>
+		<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span
+				style="font-size:75%">l</span><span style="font-size:90%">i</span><span
+				style="font-size:100%">f</span><span style="font-size:125%">o</span><span
+				style="font-size:133%">r</span><span style="font-size:150%">n</span><span
+				style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
+		<span data-dojo-value="NM">New<br>  Mexico</span>
+	</div>
 
-				<hr class="spacer">
+	<hr class="spacer">
 
-				<h2>dijit.form.FilteringSelect</h2>
-				<label for="filteringSelect">Enabled w/placeHolder: </label>
-				<input id="filteringSelect" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props="
-					placeHolder:'State',
-					store:stateStore,
+	<h2>dijit/form/FilteringSelect</h2>
+	<label for="filteringSelect">Enabled w/placeHolder: </label>
+	<input id="filteringSelect" data-dojo-type="dijit/form/FilteringSelect" data-dojo-props="
+					placeHolder:'place',
+					store:continentStore,
 					searchAttr:'name',
 					name:'state2'
 				">
 
-				<label for="filteringSelect2">Disabled w/placeHolder: </label>
-				<input id="filteringSelect2" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props="
-					disabled:true, store:stateStore, name:'state2', searchAttr:'name'
+	<label for="filteringSelect2">Disabled w/placeHolder: </label>
+	<input id="filteringSelect2" data-dojo-type="dijit/form/FilteringSelect" data-dojo-props="
+					disabled:true, store:continentStore, name:'state2', searchAttr:'name'
 				">
-				
-				<label for="filteringSelect3">Disabled w/value: </label>
-				<input id="filteringSelect3" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props="
-					store: stateStore, searchAttr:'name', disabled:true, value:'CA'
+
+	<label for="filteringSelect3">Disabled w/value: </label>
+	<input id="filteringSelect3" data-dojo-type="dijit/form/FilteringSelect" data-dojo-props="
+					store: continentStore, searchAttr:'name', disabled:true, value:'CA'
 				">
 
-			</div>
+</div>
+
+<div id="textareaTab" data-dojo-type="dijit/layout/ContentPane"
+	 data-dojo-props='title:"Textarea", style:"padding:10px;"'>
+
+	<!--	‪ and ‬ are inserted solely for testing purposes to mark the beginning and end of left-to-right text so that
+		cogniscent browsers don't render garbled punctuation nor exhibit strange home/end key behavior while in right-to-left mode -->
+	<h2>dijit/form/Textarea</h2>
+
+	<p>Enabled:</p>
+	<textarea data-dojo-type="dijit/form/Textarea" data-dojo-props='name:"areText"' name="areText">This text area will
+		expand and contract as you type ‪text.‬
+
+		Lorem ipsum dolor sit ‪amet,‬
+		consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
+		dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
+		tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo ‪consequat.‬
+	</textarea>
+
+	<br>
+
+	<p>Disabled:</p>
+	<textarea data-dojo-type="dijit/form/Textarea" data-dojo-props="disabled: true">This text
+		area is disabled and you shouldn't be able to type in ‪it.‬
+	</textarea>
+
+
+	<h2>dijit/form/SimpleTextarea</h2>
+
+	<p></p>
+
+	<p>Enabled:</p>
+	<textarea data-dojo-type="dijit/form/SimpleTextarea">This text area has a constant height and displays a scrollbar
+		when ‪necessary.‬
+
+		Lorem ipsum dolor sit ‪amet,‬
+		consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
+		dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
+		tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis
+		autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie ‪consequat,‬
+		vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
+		dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait
+		nulla ‪facilisi.‬
+	</textarea>
+
+	<p>Disabled:</p>
+	<textarea data-dojo-type="dijit/form/SimpleTextarea" data-dojo-props="disabled: true">Lorem ipsum dolor sit ‪amet,‬
+		consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
+		dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
+		tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis
+		autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie ‪consequat,‬
+		vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
+		dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait
+		nulla ‪facilisi.‬
+	</textarea>
+</div>
+<!-- end of Textarea tab -->
+
+<div id="editorTab" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Editor", style:"padding:10px;"'>
+	<p>Enabled:</p>
+	<!-- FIXME:
+		set height on this node to size the whole editor, but causes the tab to not scroll
+		until you select another tab and come back. alternative is no height: here, but that
+		causes editor to become VERY tall, and size to a normal height when selected (like the
+		dijit/form/TextArea in "Form Feel" Tab), but in reverse. refs #3980 and is maybe new bug?
+	-->
+	<div data-dojo-type="dijit/Editor"
+		 data-dojo-props="height:175, extraPlugins:['|', 'createLink', 'fontName'], styleSheets:'../themes/claro/document.css'">
+		<ul>
+			<li>Lorem <a href="http://dojotoolkit.org">and a link</a>, what do you think?</li>
+			<li>This is the Editor with a Toolbar attached.</li>
+		</ul>
+	</div>
+	<p>Disabled:</p>
+
+	<div data-dojo-type="dijit/Editor"
+		 data-dojo-props="height:175, extraPlugins:['|', 'createLink', 'fontName'], styleSheets:'../themes/claro/document.css', disabled:true">
+		<ul>
+			<li>Lorem <a href="http://dojotoolkit.org">and a link</a>, what do you think?</li>
+			<li>This is the Editor with a Toolbar attached.</li>
+		</ul>
+	</div>
+</div>
+<!-- end of Editor tab -->
 
-			<div id="textareaTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Textarea", style:"padding:10px;"'>
-
-				<!--	‪ and ‬ are inserted solely for testing purposes to mark the beginning and end of left-to-right text so that
-					cogniscent browsers don't render garbled punctuation nor exhibit strange home/end key behavior while in right-to-left mode -->
-				<h2>dijit.form.Textarea</h2>
-				<p>Enabled:</p>
-				<textarea data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"areText"' name="areText">This text area will expand and contract as you type ‪text.‬
-
-Lorem ipsum dolor sit ‪amet,‬
-consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
-dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
-tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo ‪consequat.‬
-				</textarea>
-
-				<br>
-				<p>Disabled:</p>
-				<textarea data-dojo-type="dijit.form.Textarea" data-dojo-props="disabled: true">This text
-				area is disabled and you shouldn't be able to type in ‪it.‬
-				</textarea>
-
-
-				<h2>dijit.form.SimpleTextarea</h2>
-				<p></p>
-				<p>Enabled:</p>
-				<textarea data-dojo-type="dijit.form.SimpleTextarea">This text area has a constant height and displays a scrollbar when ‪necessary.‬
-
-Lorem ipsum dolor sit ‪amet,‬
-consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
-dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
-tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis
-autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie ‪consequat,‬
-vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
-dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait
-nulla ‪facilisi.‬
-				</textarea>
-
-				<p>Disabled:</p>
-				<textarea data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props="disabled: true">Lorem ipsum dolor sit ‪amet,‬
-				consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
-				dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
-				tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis
-				autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie ‪consequat,‬
-				vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
-				dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait
-				nulla ‪facilisi.‬
-				</textarea>
-			</div><!-- end of Textarea tab -->
-
-			<div id="editorTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Editor", style:"padding:10px;"'>
-				<p>Enabled:</p>
-				<!-- FIXME:
-					set height on this node to size the whole editor, but causes the tab to not scroll
-					until you select another tab and come back. alternative is no height: here, but that
-					causes editor to become VERY tall, and size to a normal height when selected (like the
-					dijit.form.TextArea in "Form Feel" Tab), but in reverse. refs #3980 and is maybe new bug?
-				-->
-				<div data-dojo-type="dijit.Editor" data-dojo-props="height:175, extraPlugins:['|', 'createLink', 'fontName'], styleSheets:'../themes/claro/document.css'">
-					<ul>
-						<li>Lorem <a href="http://dojotoolkit.org">and a link</a>, what do you think?</li>
-						<li>This is the Editor with a Toolbar attached.</li>
-					</ul>
-				</div>
-				<p>Disabled:</p>
-				<div data-dojo-type="dijit.Editor" data-dojo-props="height:175, extraPlugins:['|', 'createLink', 'fontName'], styleSheets:'../themes/claro/document.css', disabled:true">
-					<ul>
-						<li>Lorem <a href="http://dojotoolkit.org">and a link</a>, what do you think?</li>
-						<li>This is the Editor with a Toolbar attached.</li>
-					</ul>
-				</div>
-			</div><!-- end of Editor tab -->
 
+<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="title:'Sliders', style:'padding:10px;display:none;'">
 
-			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Sliders', style:'padding:10px;display:none;'">
-				
-				<!-- Sliders: -->
-				
-				<h2>Enabled</h2>
-				<div style="float:right;">
-					<div id='slider2' data-dojo-type="dijit.form.VerticalSlider" data-dojo-props="
-						onChange: function(a){ dojo.byId('slider2input').value = a; },
+	<!-- Sliders: -->
+
+	<h2>Enabled</h2>
+
+	<div style="float:right;">
+		<div id='slider2' data-dojo-type="dijit/form/VerticalSlider" data-dojo-props="
+						onChange: function(a){ dom.byId('slider2input').value = a; },
 						value:10, maximum:100, minimum:0, discreetValues:11, style:'height:176px; clear:both'
 					">
-						<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props="container:'leftDecoration', style:'width:2em;', labelStyle:'right:0px;'">
-							<li>0
-							<li>100
-						</ol>
-
-						<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props="container:'leftDecoration', style:'width:5px;', count:11"></div>
-						<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props="container:'rightDecoration', style:'width:5px;', count:11"></div>
-						<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props="container:'rightDecoration', style:'width:2em;', maximum:100, count:6, numericMargin:1, constraints:{ pattern:'#' }"></ol>
-					</div>
-					<br> Slider2 Value:<input disabled id="slider2input" size="3" value="10" autocomplete="off">
-				</div>
+			<ol data-dojo-type="dijit/form/VerticalRuleLabels"
+				data-dojo-props="container:'leftDecoration', style:'width:2em;', labelStyle:'right:0px;'">
+				<li>0
+				<li>100
+			</ol>
+
+			<div data-dojo-type="dijit/form/VerticalRule"
+				 data-dojo-props="container:'leftDecoration', style:'width:5px;', count:11"></div>
+			<div data-dojo-type="dijit/form/VerticalRule"
+				 data-dojo-props="container:'rightDecoration', style:'width:5px;', count:11"></div>
+			<ol data-dojo-type="dijit/form/VerticalRuleLabels"
+				data-dojo-props="container:'rightDecoration', style:'width:2em;', maximum:100, count:6, numericMargin:1, constraints:{ pattern:'#' }"></ol>
+		</div>
+		<br> Slider2 Value:<input disabled id="slider2input" size="3" value="10" autocomplete="off">
+	</div>
 
-				<div id="horizontal1" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props="
+	<div id="horizontal1" data-dojo-type="dijit/form/HorizontalSlider" data-dojo-props="
 					value:10, maximum:100, minimum:0, showButtons:false, intermediateChanges:true, style:'width:50%; height:20px',
-					onChange: function(a){ dojo.byId('slider1input').value = dojo.number.format(a / 100, { places:1, pattern:'#%' }) }
+					onChange: function(a){ dom.byId('slider1input').value = dojo.number.format(a / 100, { places:1, pattern:'#%' }) }
 				">
-					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:"height:1.2em;font-size:75%;", numericMargin:1, count:6'></ol>
-					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"topDecoration", count:11, style:"height:5px;"'></div>
-					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:"height:5px;"'></div>
-					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
-						<li>lowest
-						<li>normal
-						<li>highest
-					</ol>
-				</div>
-				<br>Value: <input disabled id="slider1input" size="5" value="10.0%" autocomplete="off">
+		<ol data-dojo-type="dijit/form/HorizontalRuleLabels"
+			data-dojo-props='container:"topDecoration", style:"height:1.2em;font-size:75%;", numericMargin:1, count:6'></ol>
+		<div data-dojo-type="dijit/form/HorizontalRule"
+			 data-dojo-props='container:"topDecoration", count:11, style:"height:5px;"'></div>
+		<div data-dojo-type="dijit/form/HorizontalRule"
+			 data-dojo-props='container:"bottomDecoration", count:5, style:"height:5px;"'></div>
+		<ol data-dojo-type="dijit/form/HorizontalRuleLabels"
+			data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
+			<li>lowest
+			<li>normal
+			<li>highest
+		</ol>
+	</div>
+	<br>Value: <input disabled id="slider1input" size="5" value="10.0%" autocomplete="off">
 
-				<div id="horizontal2" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props="
+	<div id="horizontal2" data-dojo-type="dijit/form/HorizontalSlider" data-dojo-props="
 					minimum:1, value:2, maximum:3, discreteValues:3, showButtons:false, intermediateChanges:true,
 					style:'width:300px; height:40px'
 				">
-					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:3, style:"height:5px;"'></div>
-					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
-						<li><img width=10 height=10 src="../tests/images/note.gif"><br><span style="font-size: small">small</span>
-						<li><img width=15 height=15 src="../tests/images/note.gif"><br><span style="font-size: medium">medium</span>
-						<li><img width=20 height=20 src="../tests/images/note.gif"><br><span style="font-size: large">large</span>
-					</ol>
-				</div>
+		<div data-dojo-type="dijit/form/HorizontalRule"
+			 data-dojo-props='container:"bottomDecoration", count:3, style:"height:5px;"'></div>
+		<ol data-dojo-type="dijit/form/HorizontalRuleLabels"
+			data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
+			<li><img width=10 height=10 src="../tests/images/note.gif"><br><span style="font-size: small">small</span>
+			<li><img width=15 height=15 src="../tests/images/note.gif"><br><span style="font-size: medium">medium</span>
+			<li><img width=20 height=20 src="../tests/images/note.gif"><br><span style="font-size: large">large</span>
+		</ol>
+	</div>
+
+	<h2 style="clear:both">Disabled</h2>
 
-				<h2 style="clear:both">Disabled</h2>
-				<div style="float:right;">
-					<div data-dojo-type="dijit.form.VerticalSlider" data-dojo-props="
+	<div style="float:right;">
+		<div data-dojo-type="dijit/form/VerticalSlider" data-dojo-props="
 						value:10, maximum:100, minimum:0, discreteValues:11, 
 						style:'height:175px; clear:both', disabled:true
 					">
-						<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props='container:"leftDecoration", style:"width:2em;", labelStyle:"right:0px;"'>
-							<li>0
-							<li>100
-						</ol>
-
-						<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props='container:"leftDecoration", count:11, style:"width:5px;"'></div>
-						<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props='container:"rightDecoration", count:11, style:"width:5px;"'></div>
-						<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props='container:"rightDecoration", style:"width:2em;", maximum:100, count:6, numericMargin:1, constraints:{ pattern:"#"}'></ol>
-					</div>
-				</div>
-				
-				<div data-dojo-type="dijit.form.HorizontalSlider" id="hs-1width" data-dojo-props="
+			<ol data-dojo-type="dijit/form/VerticalRuleLabels"
+				data-dojo-props='container:"leftDecoration", style:"width:2em;", labelStyle:"right:0px;"'>
+				<li>0
+				<li>100
+			</ol>
+
+			<div data-dojo-type="dijit/form/VerticalRule"
+				 data-dojo-props='container:"leftDecoration", count:11, style:"width:5px;"'></div>
+			<div data-dojo-type="dijit/form/VerticalRule"
+				 data-dojo-props='container:"rightDecoration", count:11, style:"width:5px;"'></div>
+			<ol data-dojo-type="dijit/form/VerticalRuleLabels"
+				data-dojo-props='container:"rightDecoration", style:"width:2em;", maximum:100, count:6, numericMargin:1, constraints:{ pattern:"#"}'></ol>
+		</div>
+	</div>
+
+	<div data-dojo-type="dijit/form/HorizontalSlider" id="hs-1width" data-dojo-props="
 					value:10, maximum:100, minimum:0, showButtons:false, intermediateChanges:true, disabled:true
 				">
-					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:"height:1.2em;font-size:75%;", numericMargin:1, count:6'></ol>
-					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"topDecoration", count:11, style:"height:5px;"'></div>
-					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:"height:5px;"'></div>
-					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
-						<li>lowest
-						<li>normal
-						<li>highest
-					</ol>
-				</div>
+		<ol data-dojo-type="dijit/form/HorizontalRuleLabels"
+			data-dojo-props='container:"topDecoration", style:"height:1.2em;font-size:75%;", numericMargin:1, count:6'></ol>
+		<div data-dojo-type="dijit/form/HorizontalRule"
+			 data-dojo-props='container:"topDecoration", count:11, style:"height:5px;"'></div>
+		<div data-dojo-type="dijit/form/HorizontalRule"
+			 data-dojo-props='container:"bottomDecoration", count:5, style:"height:5px;"'></div>
+		<ol data-dojo-type="dijit/form/HorizontalRuleLabels"
+			data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
+			<li>lowest
+			<li>normal
+			<li>highest
+		</ol>
+	</div>
 
-				<div data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props="
+	<div data-dojo-type="dijit/form/HorizontalSlider" data-dojo-props="
 					minimum:1, value:2, maximum:3, discreteValues:3, showButtons:false, intermediateChanges:true,
 					style:'width:300px; height:40px', disabled:true
 				">
-					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:3, style:"height:5px;"'></div>
-					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
-						<li><img width=10 height=10 src="../tests/images/note.gif"><br><span style="font-size: small">small</span>
-						<li><img width=15 height=15 src="../tests/images/note.gif"><br><span style="font-size: medium">medium</span>
-						<li><img width=20 height=20 src="../tests/images/note.gif"><br><span style="font-size: large">large</span>
-					</ol>
-				</div>
-			</div>
+		<div data-dojo-type="dijit/form/HorizontalRule"
+			 data-dojo-props='container:"bottomDecoration", count:3, style:"height:5px;"'></div>
+		<ol data-dojo-type="dijit/form/HorizontalRuleLabels"
+			data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
+			<li><img width=10 height=10 src="../tests/images/note.gif"><br><span style="font-size: small">small</span>
+			<li><img width=15 height=15 src="../tests/images/note.gif"><br><span style="font-size: medium">medium</span>
+			<li><img width=20 height=20 src="../tests/images/note.gif"><br><span style="font-size: large">large</span>
+		</ol>
+	</div>
+</div>
+
+<div id="variousTab" data-dojo-type="dijit/layout/ContentPane"
+	 data-dojo-props='title:"Various Dijits", style:"padding:10px; display:none;"'>
 
-			<div id="variousTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Various Dijits", style:"padding:10px; display:none;"'>
+	<h2>TitlePane</h2>
 
-				<h2>TitlePane</h2>
-				<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'my pane', width:275">
-					<p>This is a title pane.  It can be expanded and collapsed.</p>
+	<div data-dojo-type="dijit/TitlePane" data-dojo-props="title:'my pane', width:275">
+		<p>This is a title pane. It can be expanded and collapsed.</p>
 
-					<p>Sed sollicitudin suscipit risus. Nam
-					ullamcorper. Sed nisl lectus, pellentesque nec,
-					malesuada eget, ornare a, libero. Lorem ipsum dolor
-					sit amet, consectetuer adipiscing elit.</p>
+		<p>Sed sollicitudin suscipit risus. Nam
+			ullamcorper. Sed nisl lectus, pellentesque nec,
+			malesuada eget, ornare a, libero. Lorem ipsum dolor
+			sit amet, consectetuer adipiscing elit.</p>
 
-				</div><!-- end title pane -->
+	</div>
+	<!-- end title pane -->
+
+	<hr class="spacer">
 
-				<hr class="spacer">
+	<h2>ProgressBar</h2>
 
-				<h2>ProgressBar</h2>
-				<div data-dojo-props="maximum:200, value:20" id="setTestBar" data-dojo-type="dijit.ProgressBar"></div>
+	<div data-dojo-props="maximum:200, value:20" id="setTestBar" data-dojo-type="dijit/ProgressBar"></div>
 
-				Indeterminate:
-				<div id="indTestBar" data-dojo-props="indeterminate:true" data-dojo-type="dijit.ProgressBar"></div>
+	Indeterminate:
+	<div id="indTestBar" data-dojo-props="indeterminate:true" data-dojo-type="dijit/ProgressBar"></div>
 
-			</div><!-- end:various dijits upper tab -->
+</div>
+<!-- end:various dijits upper tab -->
 
-			<div id="InlineEditBoxTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"InlineEditBox", style:"padding:10px;"'>
+<div id="InlineEditBoxTab" data-dojo-type="dijit/layout/ContentPane"
+	 data-dojo-props='title:"InlineEditBox", style:"padding:10px;"'>
 
-				<h2 class="testTitle">dijit.InlineEditBox + dijit.form.TextBox on <h3></h2>
+	<h2 class="testTitle">dijit/InlineEditBox + dijit/form/TextBox on <h3></h2>
 
-				(HTML before)
-				<h3 id="editable" style="font-size:larger;" data-dojo-type="dijit.InlineEditBox">
-					Edit me - I trigger the onChange callback
-				</h3>
-				(HTML after)
+	(HTML before)
+	<h3 id="editable" style="font-size:larger;" data-dojo-type="dijit/InlineEditBox">
+		Edit me - I trigger the onChange callback
+	</h3>
+	(HTML after)
 
-				<hr class="spacer">
+	<hr class="spacer">
 
-				<h2>dijit.InlineEditBox + dijit.form.Textarea</h2>
+	<h2>dijit/InlineEditBox + dijit/form/Textarea</h2>
 
-				(HTML before)
-				<p id="areaEditable" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor: dijit.form.Textarea, autoSave:false'>
-					I'm one big ‪paragraph.‬  Go ahead and edit ‪me.‬  I dare ‪you.‬
-					The quick brown fox jumped over the lazy ‪dog.‬	 Blah blah blah blah blah blah ‪blah ...‬
-				</p>
-				(HTML after)
+	(HTML before)
+	<p id="areaEditable" data-dojo-type="dijit/InlineEditBox"
+	   data-dojo-props='editor: "dijit/form/Textarea", autoSave:false'>
+		I'm one big ‪paragraph.‬ Go ahead and edit ‪me.‬ I dare ‪you.‬
+		The quick brown fox jumped over the lazy ‪dog.‬ Blah blah blah blah blah blah ‪blah ...‬
+	</p>
+	(HTML after)
 
-				<p>
-					These links will
-					<a href="#" onclick="dijit.byId('areaEditable').set('disabled', true)">disable</a> /
-					<a href="#" onclick="dijit.byId('areaEditable').set('disabled', false)">enable</a>
-					the text area above.
-				</p>
+	<p>
+		These links will
+		<a href="#" onclick="registry.byId('areaEditable').set('disabled', true)">disable</a> /
+		<a href="#" onclick="registry.byId('areaEditable').set('disabled', false)">enable</a>
+		the text area above.
+	</p>
 
-				<hr class="spacer">
+	<hr class="spacer">
 
-				<h2>dijit.form.DateTextBox</h2>
+	<h2>dijit/form/DateTextBox</h2>
 
-				(HTML inline before)
-				<!-- set programmatically to match locale; a server might generate this content also. -->
-				<span id="backgroundArea" data-dojo-type="dijit.InlineEditBox" data-dojo-props="editor: dijit.form.DateTextBox, width:'170px'"></span>
-				(HTML after)
-				<hr class="spacer">
+	(HTML inline before)
+	<!-- set programmatically to match locale; a server might generate this content also. -->
+	<span id="backgroundArea" data-dojo-type="dijit/InlineEditBox"
+		  data-dojo-props="editor: 'dijit/form/DateTextBox', width:'170px'"></span>
+	(HTML after)
+	<hr class="spacer">
 
-				<h2>dijit.form.TimeTextBox</h2>
+	<h2>dijit/form/TimeTextBox</h2>
 
-				(HTML inline before)
-				<!-- set programmatically to match locale; a server might generate this content also. -->
-				<span id="timePicker" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:dijit.form.TimeTextBox, width:"150px"'></span>
-				(HTML after)
+	(HTML inline before)
+	<!-- set programmatically to match (; a server might generate this content also. -->
+	<span id="timePicker" data-dojo-type="dijit/InlineEditBox"
+		  data-dojo-props='editor: "dijit/form/TimeTextBox", width:"150px"'></span>
+	(HTML after)
 
-				<hr class="spacer">
+	<hr class="spacer">
 
 
-				<h2>dijit.form.FilteringSelect + Inline + remote data store</h2>
-				(HTML inline before)
-				<span id="backgroundArea2" data-dojo-type="dijit.InlineEditBox" data-dojo-props='
-					editor: dijit.form.FilteringSelect,
-					editorParams:{ store: stateStore, autoComplete: true, promptMessage: "Please enter a state"},
+	<h2>dijit/form/FilteringSelect + Inline + remote data store</h2>
+	(HTML inline before)
+				<span id="backgroundArea2" data-dojo-type="dijit/InlineEditBox" data-dojo-props='
+					editor: "dijit/form/FilteringSelect",
+					editorParams:{ store: continentStore, autoComplete: true, promptMessage: "Please enter a place"},
 					width:"300px"
-				'>Indiana</span>
-				(HTML after)
-
-			</div><!-- end InlineEditBox tab -->
-
-			<div id="dndTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"DnD", style:"padding:10px; display:none;"'>
-				<div style="float:left; margin:5px;">
-					<h3>Source 1</h3>
-					<div data-dojo-type="dojo.dnd.Source" style="border:3px solid #ccc; padding: 1em 3em; ">
-						<div class="dojoDndItem">Item <strong>X</strong></div>
-						<div class="dojoDndItem">Item <strong>Y</strong></div>
-						<div class="dojoDndItem">Item <strong>Z</strong></div>
-					</div>
-				</div>
-				<div style="float:left; margin:5px; ">
-					<h3>Source 2</h3>
-					<div data-dojo-type="dojo.dnd.Source" style="border:3px solid #ccc; padding: 1em 3em; ">
-						<div class="dojoDndItem">Item <strong>1</strong></div>
-						<div class="dojoDndItem">Item <strong>2</strong></div>
-						<div class="dojoDndItem">Item <strong>3</strong></div>
-					</div>
-				</div>
-			</div><!-- end DnD tab -->
+				'>The earth</span>
+	(HTML after)
 
-			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props="closable:true, title:'Nested TabContainer', nested:true" id="inlined">
-				<a data-dojo-type="dijit.layout.LinkPane" id="tab1href" data-dojo-props="href:'../tests/layout/tab1.html', onLoad:function(){ console.log('load of SubTab 1'); }">SubTab 1</a>
-				<a data-dojo-type="dijit.layout.LinkPane" id="tab2href" data-dojo-props="href:'../tests/layout/tab2.html', onLoad:function(){ console.log('load of SubTab 2'); }, selected:true">SubTab 2</a>
-				<div data-dojo-type="dijit.layout.ContentPane" id="subtab3" data-dojo-props='title:"SubTab 3"'>
-					<h1>I am tab 3, inlined.</h1>
-				</div>
-				<div data-dojo-type="dijit.layout.ContentPane" id="subtab4" data-dojo-props='title:"SubTab 4"'>
-					<h1>I am tab 4, inlined.</h1>
-				</div>
-			</div>
+</div>
+<!-- end InlineEditBox tab -->
 
-			<div id="closableTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Closable", 
-				style:"display:none; padding:10px;", closable:true'>
-				This pane is closable, just for the icon ...
-			</div>
-		</div><!-- end of region="center" TabContainer -->
+<div id="dndTab" data-dojo-type="dijit/layout/ContentPane"
+	 data-dojo-props='title:"DnD", style:"padding:10px; display:none;"'>
+	<div style="float:left; margin:5px;">
+		<h3>Vertical Source</h3>
+
+		<div data-dojo-type="dojo/dnd/Source" style="border:3px solid #ccc; padding: 1em 3em; ">
+			<div class="dojoDndItem">Item <strong>X</strong></div>
+			<div class="dojoDndItem">Item <strong>Y</strong></div>
+			<div class="dojoDndItem">Item <strong>Z</strong></div>
+		</div>
+	</div>
+	<div style="float:left; margin:5px; ">
+		<h3>Horizontal</h3>
+
+		<div data-dojo-type="dojo/dnd/Source" data-dojo-props="horizontal: true"
+			 style="border:3px solid #ccc; padding: 1em 3em; ">
+			<div class="dojoDndItem">Item <strong>1</strong></div>
+			<div class="dojoDndItem">Item <strong>2</strong></div>
+			<div class="dojoDndItem">Item <strong>3</strong></div>
+		</div>
+	</div>
+</div>
+<!-- end DnD tab -->
+
+<div data-dojo-type="dijit/layout/TabContainer"
+	 data-dojo-props="closable:true, title:'Nested TabContainer', nested:true" id="inlined">
+	<a data-dojo-type="dijit/layout/LinkPane" id="tab1href"
+	   data-dojo-props="href:'../tests/layout/tab1.html', onLoad:function(){ console.log('load of SubTab 1'); }">SubTab
+		1</a>
+	<a data-dojo-type="dijit/layout/LinkPane" id="tab2href"
+	   data-dojo-props="href:'../tests/layout/tab2.html', onLoad:function(){ console.log('load of SubTab 2'); }, selected:true">SubTab
+		2</a>
+
+	<div data-dojo-type="dijit/layout/ContentPane" id="subtab3" data-dojo-props='title:"SubTab 3"'>
+		<h1>I am tab 3, inlined.</h1>
+	</div>
+	<div data-dojo-type="dijit/layout/ContentPane" id="subtab4" data-dojo-props='title:"SubTab 4"'>
+		<h1>I am tab 4, inlined.</h1>
+	</div>
+</div>
 
-		<!-- bottom right tabs -->
-		<div data-dojo-type="dijit.layout.TabContainer" id="bottomTabs"
-			data-dojo-props="
+<div id="closableTab" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Closable",
+				style:"display:none; padding:10px;", closable:true'>
+	This pane is closable, just for the icon ...
+</div>
+</div>
+<!-- end of region="center" TabContainer -->
+
+<!-- bottom right tabs -->
+<div data-dojo-type="dijit/layout/TabContainer" id="bottomTabs"
+	 data-dojo-props="
 				tabPosition:'bottom', selectedchild:'btab1', region:'bottom',
 				splitter:true, tabStrip:true
 			">
-			<!-- btab 1 -->
-			<div id="btab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Info", style:" padding:10px; "'>
-				<p>You can explore this single page after applying a Theme
-				for use in creation of your own theme.</p>
-
-				<p>I am whole slew of Widgets on a page. Jump to <a href="../tests/">dijit tests</a> to
-				test individual components.</p>
-
-				<p>There is a right-click [context] pop-up menu here, as well.</p>
-			</div><!-- end:info btab1 -->
-
-			<div id="btab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
-				<span id="themeData"></span>
-			</div><!-- btab2 -->
-
-			<div id="btab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
-				<p>I am the last Tab</p>
-				<div id="dialog2" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Encased Dialog", style:"display:none;"'>
-				I am the second dialog. I am
-				parented by the Low Tab Pane #3
-				</div>
-			</div><!-- btab3 -->
+	<!-- btab 1 -->
+	<div id="btab1" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Info", style:" padding:10px; "'>
+		<p>You can explore this single page after applying a Theme
+			for use in creation of your own theme.</p>
+
+		<p>I am whole slew of Widgets on a page. Jump to <a href="../tests/">dijit tests</a> to
+			test individual components.</p>
 
-		</div><!-- end Bottom TabContainer -->
+		<p>There is a right-click [context] pop-up menu here, as well.</p>
+	</div>
+	<!-- end:info btab1 -->
+
+	<div id="btab2" data-dojo-type="dijit/layout/ContentPane"
+		 data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
+		<span id="themeData"></span>
+	</div>
+	<!-- btab2 -->
+
+	<div id="btab3" data-dojo-type="dijit/layout/ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
+		<p>I am the last Tab</p>
+
+		<div id="dialog2" data-dojo-type="dijit/Dialog" data-dojo-props='title:"Encased Dialog", style:"display:none;"'>
+			I am the second dialog. I am
+			parented by the Low Tab Pane #3
+		</div>
+	</div>
+	<!-- btab3 -->
 
-	</div><!-- end of BorderContainer -->
+</div>
+<!-- end Bottom TabContainer -->
 
-	<!-- dialog in body -->
-	<div id="dialog1" data-dojo-type="dijit.Dialog" style="display:none;" data-dojo-props="
+</div>
+<!-- end of BorderContainer -->
+
+<!-- dialog in body -->
+<div id="dialog1" data-dojo-type="dijit/Dialog" style="display:none;" data-dojo-props="
 		title:'Floating Modal Dialog from href',
 		href:'../tests/layout/getResponse.php?delay=3000&messId=3',
 		style: 'width: 400px;',
 		refreshOnShow:true
 	"></div>
-	<div id="dialogAB" data-dojo-type="dijit.Dialog" data-dojo-props="title:'Floating Modal Dialog'" style="display:none;">
-		<div class="dijitDialogPaneContentArea">
-			<table>
-				<tr>
-					<td><label for="name">Name: </label></td>
-					<td><input data-dojo-type="dijit.form.TextBox" type="text" name="name" id="name"></td>
-				</tr>
-				<tr>
-					<td><label for="loc">Location: </label></td>
-					<td><input data-dojo-type="dijit.form.TextBox" type="text" name="loc" id="loc"></td>
-				</tr>
-				<tr>
-					<td><label for="date">Date: </label></td>
-					<td><input data-dojo-type="dijit.form.DateTextBox" type="text" name="date" id="date"></td>
-				</tr>
-			</table>
-		</div>
-		
-		<div class="dijitDialogPaneActionBar">
-			<button data-dojo-type="dijit.form.Button" type="submit" id="ABdialog1button1">OK</button>
-			<button data-dojo-type="dijit.form.Button" type="button" data-dojo-props="onClick:function(){ dijit.byId('dialogAB').onCancel(); }" 
-					id="ABdialog1button2">Cancel</button>
-		</div>
+<div id="dialogAB" data-dojo-type="dijit/Dialog" data-dojo-props="title:'Floating Modal Dialog'" style="display:none;">
+	<div class="dijitDialogPaneContentArea">
+		<table>
+			<tr>
+				<td><label for="name">Name: </label></td>
+				<td><input data-dojo-type="dijit/form/TextBox" type="text" name="name" id="name"></td>
+			</tr>
+			<tr>
+				<td><label for="loc">Location: </label></td>
+				<td><input data-dojo-type="dijit/form/TextBox" type="text" name="loc" id="loc"></td>
+			</tr>
+			<tr>
+				<td><label for="date">Date: </label></td>
+				<td><input data-dojo-type="dijit/form/DateTextBox" type="text" name="date" id="date"></td>
+			</tr>
+		</table>
+	</div>
+
+	<div class="dijitDialogPaneActionBar">
+		<button data-dojo-type="dijit/form/Button" type="submit" id="ABdialog1button1">OK</button>
+		<button data-dojo-type="dijit/form/Button" type="button"
+				data-dojo-props="onClick:function(){ registry.byId('dialogAB').onCancel(); }"
+				id="ABdialog1button2">Cancel
+		</button>
 	</div>
+</div>
 
 </body>
 </html>
diff --git a/dijit/themes/tundra/Common.css b/dijit/themes/tundra/Common.css
index eb3e341..82a133b 100644
--- a/dijit/themes/tundra/Common.css
+++ b/dijit/themes/tundra/Common.css
@@ -1,16 +1,14 @@
-/* DnD avatar-specific settings */
-/* For now it uses a default set of rules. Some other DnD classes can be modified as well. */
-.tundra .dojoDndItemBefore {
-	border-top: 2px solid #369;
+/* DnD hovered and selected node(s) */
+.tundra .dojoDndItemOver {
+	background-image: url(images/treeHover.png);
 }
-
-.tundra .dojoDndItemAfter {
-	border-bottom: 2px solid #369;
+.tundra .dojoDndItemAnchor,
+.tundra .dojoDndItemSelected {
+	background-color: #E2EBFE;
 }
 
-.tundra .dojoDndItemOver {
-	cursor:pointer;
-}
+/* DnD avatar-specific settings */
+/* For now it uses a default set of rules. Some other DnD classes can be modified as well. */
 
 .tundra table.dojoDndAvatar { -moz-border-radius: 0; border: 1px solid #ccc; border-collapse: collapse; background-color: #fff; font-size: 75%; color: black;}
 .tundra .dojoDndAvatar td	{ border: none; }
diff --git a/dijit/themes/tundra/Menu.css b/dijit/themes/tundra/Menu.css
index 6229b17..bcc60c4 100644
--- a/dijit/themes/tundra/Menu.css
+++ b/dijit/themes/tundra/Menu.css
@@ -27,6 +27,7 @@
 }
 
 .tundra .dijitMenuPassive .dijitMenuItemHover,
+.tundra .dijitComboBoxMenu .dijitMenuItemHover,
 .tundra .dijitMenuItemSelected {
 	background-color: #3559ac;
 	color:#fff;
@@ -58,19 +59,24 @@
 }
 
 /* the checked menu item */
-.tundra .dijitCheckedMenuItemIconChar {
-	display: none;
-}
-
-.tundra .dijitCheckedMenuItemIcon {
+.tundra .dijitCheckedMenuItem .dijitMenuItemIcon,
+.tundra .dijitRadioMenuItem .dijitMenuItemIcon {
 	background-image: url('images/checkmark.png');
 	background-position: -80px;
 }
 
-.dj_ie6 .tundra .dijitCheckedMenuItemIcon {
+.dj_ie6 .tundra .dijitCheckedMenuItem .dijitMenuItemIcon,
+.dj_ie6 .tundra .dijitRadioMenuItem .dijitMenuItemIcon {
 	background-image: url('images/checkmark.gif');
 }
 
-.tundra .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
+.tundra .dijitCheckedMenuItemChecked .dijitMenuItemIcon {
 	background-position: -64px;
+}
+
+.tundra .dijitRadioMenuItem .dijitMenuItemIcon {
+	background-position: -110px; /* 15px * 8 */
+}
+.tundra .dijitRadioMenuItemChecked .dijitMenuItemIcon {
+	background-position: -95px;	/* 15px * 7 */
 }
\ No newline at end of file
diff --git a/dijit/themes/tundra/ProgressBar.css b/dijit/themes/tundra/ProgressBar.css
index 2d70e28..5a9a786 100644
--- a/dijit/themes/tundra/ProgressBar.css
+++ b/dijit/themes/tundra/ProgressBar.css
@@ -14,7 +14,8 @@
 }
 
 .tundra .dijitProgressBarFull {
-	border-right:1px solid #b8b8b8;
+	border: 0px solid #b8b8b8;
+	border-right-width: 1px;
 }
 
 .tundra .dijitProgressBarLabel {
diff --git a/dijit/themes/tundra/ProgressBar_rtl.css b/dijit/themes/tundra/ProgressBar_rtl.css
new file mode 100644
index 0000000..59833f5
--- /dev/null
+++ b/dijit/themes/tundra/ProgressBar_rtl.css
@@ -0,0 +1,5 @@
+.tundra .dijitProgressBarRtl .dijitProgressBarFull {
+	border-left-width: 1px;
+	border-right: 0px;
+}
+
diff --git a/dijit/themes/tundra/TimePicker.css b/dijit/themes/tundra/TimePicker.css
index 13dc7f8..33fc5ae 100644
--- a/dijit/themes/tundra/TimePicker.css
+++ b/dijit/themes/tundra/TimePicker.css
@@ -5,13 +5,12 @@
 }
 
 .tundra .dijitTimePickerTick {
-	color:white;
+	color:gray;
 }
 
 .tundra .dijitTimePickerMarker {
 	background:#d3d3d3 url("images/titleBar.png") repeat-x top;
 	color:#293a4b;
-	font-weight: bold;
 }
 
 .tundra .dijitTimePickerItemSelected {
@@ -23,30 +22,3 @@
 	background: #60a1ea none;
 	color:white;
 }
-
-.tundra .dijitTimePickerItemHover,
-.tundra .dijitTimePickerItemSelected {
-	position: relative;
-	z-index: 10;
-}
-
-.tundra .dijitTimePickerTick .dijitTimePickerItemInner {
-	font-size:0.4em;
-}
-
-.tundra .dijitTimePickerItemHover .dijitTimePickerItemInner,
-.tundra .dijitTimePickerItemSelected .dijitTimePickerItemInner {
-	font-size:1em;
-}
-
-.tundra .dijitTimePickerMarkerHover {
-	border-top: 1px solid #ccc;
-}
-
-.tundra .dijitTimePickerTickHover,
-.tundra .dijitTimePickerTickSelected {
-	margin-top:-0.3em;
-	margin-bottom:-0.3em;
-	border-bottom: none;
-}
-
diff --git a/dijit/themes/tundra/TimePicker_rtl.css b/dijit/themes/tundra/TimePicker_rtl.css
index 7a4d5e5..e9e8c74 100644
--- a/dijit/themes/tundra/TimePicker_rtl.css
+++ b/dijit/themes/tundra/TimePicker_rtl.css
@@ -1,4 +1,4 @@
- .dj_ie6 .tundra .dijitTimePickerRtl .dijitTimePickerMarkerHover,
+.dj_ie6 .tundra .dijitTimePickerRtl .dijitTimePickerMarkerHover,
 .dj_ie7 .tundra .dijitTimePickerRtl .dijitTimePickerMarkerHover {
         border-top: 0; /* IE6/7 bug causes mouseover/out event storm */
 }
diff --git a/dijit/themes/tundra/TitlePane.css b/dijit/themes/tundra/TitlePane.css
index e964bf8..2393e69 100644
--- a/dijit/themes/tundra/TitlePane.css
+++ b/dijit/themes/tundra/TitlePane.css
@@ -8,18 +8,18 @@
 	background: #f8fafd url("images/accordionItemHover.gif") bottom repeat-x;
 }
 
-.tundra .dijitTitlePane .dijitArrowNode {
+.tundra .dijitTitlePane .dijitArrowNode, .tundra .dijitFieldset .dijitArrowNode {
 	background-image: url('images/spriteArrows.png');
 	background-repeat: no-repeat;
 	background-position: 0 0;
 	height: 7px;
 	width: 7px;
 }
-.dj_ie6 .tundra .dijitTitlePane .dijitArrowNode {
+.dj_ie6 .tundra .dijitTitlePane .dijitArrowNode, .dj_ie6 .tundra .dijitFieldset .dijitArrowNode {
 	background-image: url('images/spriteArrows.gif');
 }
 
-.tundra .dijitTitlePane .dijitClosed .dijitArrowNode {
+.tundra .dijitTitlePane .dijitClosed .dijitArrowNode, .tundra .dijitFieldset .dijitClosed .dijitArrowNode {
 	background-position: -14px 0;
 }
 
@@ -32,7 +32,7 @@
 	padding:10px;
 }
 
-.tundra .dijitTitlePaneTextNode {
+.tundra .dijitTitlePaneTextNode, .tundra .dijitFieldsetLegendNode {
 	margin-left: 4px;
 	margin-right: 4px;
 }
\ No newline at end of file
diff --git a/dijit/themes/tundra/TitlePane_rtl.css b/dijit/themes/tundra/TitlePane_rtl.css
index 5f63a03..bb11f4a 100644
--- a/dijit/themes/tundra/TitlePane_rtl.css
+++ b/dijit/themes/tundra/TitlePane_rtl.css
@@ -1,3 +1,3 @@
-.tundra .dijitTitlePaneRtl .dijitClosed .dijitArrowNode {
+.tundra .dijitTitlePaneRtl .dijitClosed .dijitArrowNode, .tundra .dijitFieldsetRtl .dijitFieldsetTitleClosed .dijitArrowNode {
 	background-position: -7px 0;
 }
\ No newline at end of file
diff --git a/dijit/themes/tundra/form/Button.css b/dijit/themes/tundra/form/Button.css
index 2c68aef..d274745 100644
--- a/dijit/themes/tundra/form/Button.css
+++ b/dijit/themes/tundra/form/Button.css
@@ -18,6 +18,9 @@
 	text-align: center;
 	padding: 0 0.3em;
 }
+.tundra .dijitInputField {
+	padding: 0; /* set padding:0 for .tundra .dijitSelect .dijitButtonText but with a low priority rule that can be easily trumped by the user */
+}
 
 .tundra .dijitDisabled .dijitButtonText {
 	color: #7F7F7F;
@@ -112,12 +115,11 @@
 .tundra .dijitDisabled .dijitUpArrowButton .dijitArrowButtonInner {
 	background-position: -49px center;
 }
-.dj_webkit .tundra .dijitSpinner .dijitUpArrowButton .dijitArrowButtonInner {
-	margin-top: -1px; /* image has too many blank pixels on top */
-}
 .dj_ie .tundra .dijitSpinner .dijitDownArrowButton .dijitArrowButtonInner {
 	margin-top: -2px; /* image has too many blank pixels on top */
 }
+.dj_webkit .tundra .dijitSpinner .dijitUpArrowButton .dijitArrowButtonInner,
+.dj_iequirks .tundra .dijitSpinner .dijitDownArrowButton .dijitArrowButtonInner,
 .dj_ie8 .tundra .dijitSpinner .dijitDownArrowButton .dijitArrowButtonInner {
 	margin-top: -1px; /* image has too many blank pixels on top */
 }
diff --git a/dijit/themes/tundra/form/Common.css b/dijit/themes/tundra/form/Common.css
index 96899e1..2122184 100644
--- a/dijit/themes/tundra/form/Common.css
+++ b/dijit/themes/tundra/form/Common.css
@@ -10,8 +10,7 @@
 		dijit.form.ComboBox (partial)
  ****/
 
-.tundra .dijitInputContainer input,
-.tundra .dijitTextBox {
+.tundra .dijitInputContainer input {
 	margin: 0 0.1em;
 }
 
@@ -19,6 +18,8 @@
 	padding: 3px;
 }
 
+.tundra .dijitSelect .dijitButtonContents,
+.tundra .dijitSelect,
 .tundra .dijitTextBox {
 	/* 	For all except dijit.form.NumberSpinner:  the actual input element.
 		For TextBox, ComboBox, Spinner: the div that contains the input.
@@ -26,13 +27,17 @@
 	*/
 	background:#fff url("../images/validationInputBg.png") repeat-x top left;
 	#background:#fff url('../images/validationInputBg.gif') repeat-x top left;
+}
+.tundra .dijitSelect,
+.tundra .dijitTextBox {
 	border:1px solid #b3b3b3;
 }
 
-/* ComboBox specific rules*/
+.tundra .dijitSelect .dijitArrowButton,
 .tundra .dijitComboBox .dijitButtonNode {
 	padding: 0 0.2em;
 }
+.tundra .dijitSelect .dijitButtonContents,
 .tundra .dijitTextBox .dijitButtonNode {
 	/* line between the input area and the drop down button, and also between
 	 * the up and down buttons of a spinner
@@ -40,10 +45,12 @@
 	border-color: #9b9b9b;
 }
 
+.tundra .dijitSelectFocused,
 .tundra .dijitTextBoxFocused {
 	/* input field when focused (ie: typing affects it) */
 	border-color:#406b9b;
 }
+.tundra .dijitSelectFocused TD,
 .tundra .dijitTextBoxFocused .dijitButtonNode {
 	border-color:#366dba;
 }
@@ -59,7 +66,7 @@
 }
 
 /* Validation errors  */
-.tundra .dijitValidationIcon {
+.tundra .dijitValidationTextBoxError .dijitValidationIcon {
 	/* prevent height change when widget goes from valid to invalid state */
 	width: 16px;
 	background: transparent url('../images/warning.png') no-repeat center center;
diff --git a/dijit/themes/tundra/form/Select.css b/dijit/themes/tundra/form/Select.css
index b029016..3e0e77e 100644
--- a/dijit/themes/tundra/form/Select.css
+++ b/dijit/themes/tundra/form/Select.css
@@ -1,47 +1,39 @@
-.tundra .dijitSelect .dijitButtonNode {
-	padding: 0;
-}
-.tundra .dijitSelect .dijitButtonNode .dijitArrowButtonInner {
-	margin: 0 4px 0 5px;
-}
-
 /* Make unselected content portion "look" more like a text box and less like a button */
-.tundra .dijitSelect .dijitButtonContents {
-	padding-top: 1px;
-	background:#fff url("../images/validationInputBg.png") repeat-x top left;
-	#background:#fff url('../images/validationInputBg.gif') repeat-x top left;
-}
-.tundra .dijitSelectHover .dijitButtonContents,
-.tundra .dijitSelectActive .dijitButtonContents,
-.tundra .dijitSelectOpened .dijitButtonContents,
-.tundra .dijitSelectDisabled .dijitButtonContents,
-.tundra .dijitSelectReadOnly .dijitButtonContents{
+.tundra .dijitSelectError .dijitButtonContents,
+.tundra .dijitSelectHover .dijitArrowButton,
+.tundra .dijitSelectActive .dijitArrowButton,
+.tundra .dijitSelectOpened .dijitArrowButton,
+.tundra .dijitSelectDisabled .dijitArrowButton,
+.tundra .dijitSelectReadOnly .dijitArrowButton {
 	background: transparent none;
 }
-.dj_ie .tundra .dijitSelect .dijitButtonContents {
-	padding-top: 0;
+.tundra .dijitSelect .dijitArrowButton {
+	background: #fff url("../images/buttonEnabled.png") repeat-x bottom left;
+	border-width: 0;
 }
 
 /* Mirror DropDownButton */
-.tundra .dijitSelectDisabled .dijitButtonNode {
-	border-color: #d5d5d5 #bdbdbd #bdbdbd #d5d5d5;
+.tundra .dijitSelectDisabled,
+.tundra .dijitSelectDisabled TD {
+	border-color: #d5d5d5 #bdbdbd #bdbdbd #d5d5d5 !important;
 	background:#e4e4e4 url("../images/buttonDisabled.png") top repeat-x;
 }
-.dj_ie .tundra .dijitSelectDisabled  .dijitButtonNode * {
+.dj_ie .tundra .dijitSelectDisabled TD * {
 	filter: gray() alpha(opacity=50);
 }
 
-.tundra .dijitSelectHover .dijitButtonNode {
-	border-color:#a5beda;
-	border-bottom-color:#5c7590;
-	border-right-color:#5c7590;
+.tundra .dijitSelectHover,
+.tundra .dijitSelectHover TD {
+	border-color:#a5beda #5c7590 #5c7590 #a5beda !important;
 	color:#243C5F;
 	background:#fcfdff url("../images/buttonHover.png") repeat-x bottom;
 }
 
-.tundra .dijitSelectActive .dijitButtonNode,
-.tundra .dijitSelectOpened .dijitButtonNode {
-	border-color:#366dba;
+.tundra .dijitSelectActive,
+.tundra .dijitSelectOpened,
+.tundra .dijitSelectActive TD,
+.tundra .dijitSelectOpened TD {
+	border-color:#366dba !important;
 	background: #ededed url("../images/buttonActive.png") bottom repeat-x;
 }
 
@@ -53,5 +45,3 @@
 .tundra .dijitSelectMenu .dijitMenuArrowCell {
 	padding: 0.1em 0.2em;
 }
-
-
diff --git a/dijit/themes/tundra/images/buttonActive.png b/dijit/themes/tundra/images/buttonActive.png
index 09417b1..3345c7e 100644
Binary files a/dijit/themes/tundra/images/buttonActive.png and b/dijit/themes/tundra/images/buttonActive.png differ
diff --git a/dijit/themes/tundra/images/buttonDisabled.png b/dijit/themes/tundra/images/buttonDisabled.png
index 70766f4..3cf82db 100644
Binary files a/dijit/themes/tundra/images/buttonDisabled.png and b/dijit/themes/tundra/images/buttonDisabled.png differ
diff --git a/dijit/themes/tundra/images/buttonEnabled.png b/dijit/themes/tundra/images/buttonEnabled.png
index cf0eb20..d4afbf0 100644
Binary files a/dijit/themes/tundra/images/buttonEnabled.png and b/dijit/themes/tundra/images/buttonEnabled.png differ
diff --git a/dijit/themes/tundra/images/buttonHover.png b/dijit/themes/tundra/images/buttonHover.png
index b074e4e..9f1e46e 100644
Binary files a/dijit/themes/tundra/images/buttonHover.png and b/dijit/themes/tundra/images/buttonHover.png differ
diff --git a/dijit/themes/tundra/images/calendarDayLabel.png b/dijit/themes/tundra/images/calendarDayLabel.png
index c1a1553..ebc0819 100644
Binary files a/dijit/themes/tundra/images/calendarDayLabel.png and b/dijit/themes/tundra/images/calendarDayLabel.png differ
diff --git a/dijit/themes/tundra/images/calendarMonthLabel.png b/dijit/themes/tundra/images/calendarMonthLabel.png
index fd2cf0a..dca79c7 100644
Binary files a/dijit/themes/tundra/images/calendarMonthLabel.png and b/dijit/themes/tundra/images/calendarMonthLabel.png differ
diff --git a/dijit/themes/tundra/images/calendarYearLabel.png b/dijit/themes/tundra/images/calendarYearLabel.png
index dd344f5..8c0d959 100644
Binary files a/dijit/themes/tundra/images/calendarYearLabel.png and b/dijit/themes/tundra/images/calendarYearLabel.png differ
diff --git a/dijit/themes/tundra/images/checkmark.png b/dijit/themes/tundra/images/checkmark.png
index 0307109..3c4b831 100644
Binary files a/dijit/themes/tundra/images/checkmark.png and b/dijit/themes/tundra/images/checkmark.png differ
diff --git a/dijit/themes/tundra/images/checkmarkNoBorder.png b/dijit/themes/tundra/images/checkmarkNoBorder.png
index 9cec0c0..ae3271a 100755
Binary files a/dijit/themes/tundra/images/checkmarkNoBorder.png and b/dijit/themes/tundra/images/checkmarkNoBorder.png differ
diff --git a/dijit/themes/tundra/images/circleIcon.png b/dijit/themes/tundra/images/circleIcon.png
index 6f059e6..e414a89 100755
Binary files a/dijit/themes/tundra/images/circleIcon.png and b/dijit/themes/tundra/images/circleIcon.png differ
diff --git a/dijit/themes/tundra/images/dndCopy.png b/dijit/themes/tundra/images/dndCopy.png
index baecd7c..6a8b998 100644
Binary files a/dijit/themes/tundra/images/dndCopy.png and b/dijit/themes/tundra/images/dndCopy.png differ
diff --git a/dijit/themes/tundra/images/dndMove.png b/dijit/themes/tundra/images/dndMove.png
index 07f878c..8443d30 100644
Binary files a/dijit/themes/tundra/images/dndMove.png and b/dijit/themes/tundra/images/dndMove.png differ
diff --git a/dijit/themes/tundra/images/dndNoCopy.png b/dijit/themes/tundra/images/dndNoCopy.png
index 9bf9c33..64bf88b 100644
Binary files a/dijit/themes/tundra/images/dndNoCopy.png and b/dijit/themes/tundra/images/dndNoCopy.png differ
diff --git a/dijit/themes/tundra/images/dndNoMove.png b/dijit/themes/tundra/images/dndNoMove.png
index cb8bd8b..682ea10 100644
Binary files a/dijit/themes/tundra/images/dndNoMove.png and b/dijit/themes/tundra/images/dndNoMove.png differ
diff --git a/dijit/themes/tundra/images/dojoTundraGradientBg.png b/dijit/themes/tundra/images/dojoTundraGradientBg.png
index ac118dd..577ca8a 100644
Binary files a/dijit/themes/tundra/images/dojoTundraGradientBg.png and b/dijit/themes/tundra/images/dojoTundraGradientBg.png differ
diff --git a/dijit/themes/tundra/images/doubleArrowDown.png b/dijit/themes/tundra/images/doubleArrowDown.png
index 92678d2..c50d096 100644
Binary files a/dijit/themes/tundra/images/doubleArrowDown.png and b/dijit/themes/tundra/images/doubleArrowDown.png differ
diff --git a/dijit/themes/tundra/images/doubleArrowUp.png b/dijit/themes/tundra/images/doubleArrowUp.png
index bba30fe..b33768f 100644
Binary files a/dijit/themes/tundra/images/doubleArrowUp.png and b/dijit/themes/tundra/images/doubleArrowUp.png differ
diff --git a/dijit/themes/tundra/images/loading.gif b/dijit/themes/tundra/images/loading.gif
index 6e7c8e5..a42980f 100755
Binary files a/dijit/themes/tundra/images/loading.gif and b/dijit/themes/tundra/images/loading.gif differ
diff --git a/dijit/themes/tundra/images/menu.png b/dijit/themes/tundra/images/menu.png
index f5b93d1..8a6e08b 100644
Binary files a/dijit/themes/tundra/images/menu.png and b/dijit/themes/tundra/images/menu.png differ
diff --git a/dijit/themes/tundra/images/preciseSliderThumb.png b/dijit/themes/tundra/images/preciseSliderThumb.png
index f2fc338..94b7fea 100644
Binary files a/dijit/themes/tundra/images/preciseSliderThumb.png and b/dijit/themes/tundra/images/preciseSliderThumb.png differ
diff --git a/dijit/themes/tundra/images/preciseSliderThumbFocus.png b/dijit/themes/tundra/images/preciseSliderThumbFocus.png
index fb06323..c5d24ae 100644
Binary files a/dijit/themes/tundra/images/preciseSliderThumbFocus.png and b/dijit/themes/tundra/images/preciseSliderThumbFocus.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-1.png b/dijit/themes/tundra/images/progressBarAnim-1.png
index cfc3fd2..f0a6374 100644
Binary files a/dijit/themes/tundra/images/progressBarAnim-1.png and b/dijit/themes/tundra/images/progressBarAnim-1.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-2.png b/dijit/themes/tundra/images/progressBarAnim-2.png
index d27981d..5b57a54 100644
Binary files a/dijit/themes/tundra/images/progressBarAnim-2.png and b/dijit/themes/tundra/images/progressBarAnim-2.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-3.png b/dijit/themes/tundra/images/progressBarAnim-3.png
index 3b92a7d..ea034dc 100644
Binary files a/dijit/themes/tundra/images/progressBarAnim-3.png and b/dijit/themes/tundra/images/progressBarAnim-3.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-4.png b/dijit/themes/tundra/images/progressBarAnim-4.png
index 61e4276..f151405 100644
Binary files a/dijit/themes/tundra/images/progressBarAnim-4.png and b/dijit/themes/tundra/images/progressBarAnim-4.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-5.png b/dijit/themes/tundra/images/progressBarAnim-5.png
index 48b189a..49c2851 100644
Binary files a/dijit/themes/tundra/images/progressBarAnim-5.png and b/dijit/themes/tundra/images/progressBarAnim-5.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-6.png b/dijit/themes/tundra/images/progressBarAnim-6.png
index af50c4d..ee20a82 100644
Binary files a/dijit/themes/tundra/images/progressBarAnim-6.png and b/dijit/themes/tundra/images/progressBarAnim-6.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-7.png b/dijit/themes/tundra/images/progressBarAnim-7.png
index a4fffa3..0092fc3 100644
Binary files a/dijit/themes/tundra/images/progressBarAnim-7.png and b/dijit/themes/tundra/images/progressBarAnim-7.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-8.png b/dijit/themes/tundra/images/progressBarAnim-8.png
index b4c92f3..e971938 100644
Binary files a/dijit/themes/tundra/images/progressBarAnim-8.png and b/dijit/themes/tundra/images/progressBarAnim-8.png differ
diff --git a/dijit/themes/tundra/images/progressBarAnim-9.png b/dijit/themes/tundra/images/progressBarAnim-9.png
index d8bff13..6e60dc8 100644
Binary files a/dijit/themes/tundra/images/progressBarAnim-9.png and b/dijit/themes/tundra/images/progressBarAnim-9.png differ
diff --git a/dijit/themes/tundra/images/progressBarEmpty.png b/dijit/themes/tundra/images/progressBarEmpty.png
index 07f4c91..690c74d 100644
Binary files a/dijit/themes/tundra/images/progressBarEmpty.png and b/dijit/themes/tundra/images/progressBarEmpty.png differ
diff --git a/dijit/themes/tundra/images/progressBarFull.png b/dijit/themes/tundra/images/progressBarFull.png
index 0ce60f5..2a30708 100644
Binary files a/dijit/themes/tundra/images/progressBarFull.png and b/dijit/themes/tundra/images/progressBarFull.png differ
diff --git a/dijit/themes/tundra/images/radioButtonActive.png b/dijit/themes/tundra/images/radioButtonActive.png
index 60840c7..4090fb8 100644
Binary files a/dijit/themes/tundra/images/radioButtonActive.png and b/dijit/themes/tundra/images/radioButtonActive.png differ
diff --git a/dijit/themes/tundra/images/radioButtonActiveDisabled.png b/dijit/themes/tundra/images/radioButtonActiveDisabled.png
index b49724e..981ffb0 100644
Binary files a/dijit/themes/tundra/images/radioButtonActiveDisabled.png and b/dijit/themes/tundra/images/radioButtonActiveDisabled.png differ
diff --git a/dijit/themes/tundra/images/radioButtonActiveHover.png b/dijit/themes/tundra/images/radioButtonActiveHover.png
index f21d4e5..387c496 100644
Binary files a/dijit/themes/tundra/images/radioButtonActiveHover.png and b/dijit/themes/tundra/images/radioButtonActiveHover.png differ
diff --git a/dijit/themes/tundra/images/radioButtonDisabled.png b/dijit/themes/tundra/images/radioButtonDisabled.png
index 8da7e78..f4d2b48 100644
Binary files a/dijit/themes/tundra/images/radioButtonDisabled.png and b/dijit/themes/tundra/images/radioButtonDisabled.png differ
diff --git a/dijit/themes/tundra/images/radioButtonEnabled.png b/dijit/themes/tundra/images/radioButtonEnabled.png
index 4342fea..dd5acde 100644
Binary files a/dijit/themes/tundra/images/radioButtonEnabled.png and b/dijit/themes/tundra/images/radioButtonEnabled.png differ
diff --git a/dijit/themes/tundra/images/radioButtonHover.png b/dijit/themes/tundra/images/radioButtonHover.png
index fcb697f..9160aed 100644
Binary files a/dijit/themes/tundra/images/radioButtonHover.png and b/dijit/themes/tundra/images/radioButtonHover.png differ
diff --git a/dijit/themes/tundra/images/sliderEmpty.png b/dijit/themes/tundra/images/sliderEmpty.png
index 070c12f..0187122 100644
Binary files a/dijit/themes/tundra/images/sliderEmpty.png and b/dijit/themes/tundra/images/sliderEmpty.png differ
diff --git a/dijit/themes/tundra/images/sliderEmptyVertical.png b/dijit/themes/tundra/images/sliderEmptyVertical.png
index 45aceb7..98e5cd7 100644
Binary files a/dijit/themes/tundra/images/sliderEmptyVertical.png and b/dijit/themes/tundra/images/sliderEmptyVertical.png differ
diff --git a/dijit/themes/tundra/images/sliderFull.png b/dijit/themes/tundra/images/sliderFull.png
index 4b3fcbb..032dba6 100644
Binary files a/dijit/themes/tundra/images/sliderFull.png and b/dijit/themes/tundra/images/sliderFull.png differ
diff --git a/dijit/themes/tundra/images/sliderFullFocus.png b/dijit/themes/tundra/images/sliderFullFocus.png
index ee19356..018590d 100755
Binary files a/dijit/themes/tundra/images/sliderFullFocus.png and b/dijit/themes/tundra/images/sliderFullFocus.png differ
diff --git a/dijit/themes/tundra/images/sliderFullVertical.png b/dijit/themes/tundra/images/sliderFullVertical.png
index e7618e8..63edc75 100644
Binary files a/dijit/themes/tundra/images/sliderFullVertical.png and b/dijit/themes/tundra/images/sliderFullVertical.png differ
diff --git a/dijit/themes/tundra/images/sliderFullVerticalFocus.png b/dijit/themes/tundra/images/sliderFullVerticalFocus.png
index 3ab37e6..806399c 100755
Binary files a/dijit/themes/tundra/images/sliderFullVerticalFocus.png and b/dijit/themes/tundra/images/sliderFullVerticalFocus.png differ
diff --git a/dijit/themes/tundra/images/sliderThumb.png b/dijit/themes/tundra/images/sliderThumb.png
index fe33583..b790c44 100644
Binary files a/dijit/themes/tundra/images/sliderThumb.png and b/dijit/themes/tundra/images/sliderThumb.png differ
diff --git a/dijit/themes/tundra/images/sliderThumbFocus.png b/dijit/themes/tundra/images/sliderThumbFocus.png
index fe9763a..a253b09 100644
Binary files a/dijit/themes/tundra/images/sliderThumbFocus.png and b/dijit/themes/tundra/images/sliderThumbFocus.png differ
diff --git a/dijit/themes/tundra/images/smallArrowDown.png b/dijit/themes/tundra/images/smallArrowDown.png
index cabd01c..8b92a81 100644
Binary files a/dijit/themes/tundra/images/smallArrowDown.png and b/dijit/themes/tundra/images/smallArrowDown.png differ
diff --git a/dijit/themes/tundra/images/smallArrowUp.png b/dijit/themes/tundra/images/smallArrowUp.png
index a4dd670..4412e7c 100644
Binary files a/dijit/themes/tundra/images/smallArrowUp.png and b/dijit/themes/tundra/images/smallArrowUp.png differ
diff --git a/dijit/themes/tundra/images/splitContainerSizerH-thumb.png b/dijit/themes/tundra/images/splitContainerSizerH-thumb.png
index e7bc204..4b1fff8 100644
Binary files a/dijit/themes/tundra/images/splitContainerSizerH-thumb.png and b/dijit/themes/tundra/images/splitContainerSizerH-thumb.png differ
diff --git a/dijit/themes/tundra/images/splitContainerSizerH.png b/dijit/themes/tundra/images/splitContainerSizerH.png
index 0e5e471..a1d05ea 100644
Binary files a/dijit/themes/tundra/images/splitContainerSizerH.png and b/dijit/themes/tundra/images/splitContainerSizerH.png differ
diff --git a/dijit/themes/tundra/images/splitContainerSizerV-thumb.png b/dijit/themes/tundra/images/splitContainerSizerV-thumb.png
index 410a0a7..75676d5 100644
Binary files a/dijit/themes/tundra/images/splitContainerSizerV-thumb.png and b/dijit/themes/tundra/images/splitContainerSizerV-thumb.png differ
diff --git a/dijit/themes/tundra/images/splitContainerSizerV.png b/dijit/themes/tundra/images/splitContainerSizerV.png
index 6781f0e..c03ac37 100644
Binary files a/dijit/themes/tundra/images/splitContainerSizerV.png and b/dijit/themes/tundra/images/splitContainerSizerV.png differ
diff --git a/dijit/themes/tundra/images/spriteArrows.png b/dijit/themes/tundra/images/spriteArrows.png
index e0229c9..3ad3498 100644
Binary files a/dijit/themes/tundra/images/spriteArrows.png and b/dijit/themes/tundra/images/spriteArrows.png differ
diff --git a/dijit/themes/tundra/images/spriteRoundedIconsSmall.png b/dijit/themes/tundra/images/spriteRoundedIconsSmall.png
index e81ba07..baea73d 100644
Binary files a/dijit/themes/tundra/images/spriteRoundedIconsSmall.png and b/dijit/themes/tundra/images/spriteRoundedIconsSmall.png differ
diff --git a/dijit/themes/tundra/images/tabActive.png b/dijit/themes/tundra/images/tabActive.png
index eaf1ed4..935db38 100644
Binary files a/dijit/themes/tundra/images/tabActive.png and b/dijit/themes/tundra/images/tabActive.png differ
diff --git a/dijit/themes/tundra/images/tabClose.png b/dijit/themes/tundra/images/tabClose.png
index 136cd22..56578b8 100644
Binary files a/dijit/themes/tundra/images/tabClose.png and b/dijit/themes/tundra/images/tabClose.png differ
diff --git a/dijit/themes/tundra/images/tabCloseHover.png b/dijit/themes/tundra/images/tabCloseHover.png
index 290e77f..b034608 100644
Binary files a/dijit/themes/tundra/images/tabCloseHover.png and b/dijit/themes/tundra/images/tabCloseHover.png differ
diff --git a/dijit/themes/tundra/images/tabDisabled.png b/dijit/themes/tundra/images/tabDisabled.png
index ea0f617..2ba3bf5 100644
Binary files a/dijit/themes/tundra/images/tabDisabled.png and b/dijit/themes/tundra/images/tabDisabled.png differ
diff --git a/dijit/themes/tundra/images/tabEnabled.png b/dijit/themes/tundra/images/tabEnabled.png
index d40cf45..ac44db0 100644
Binary files a/dijit/themes/tundra/images/tabEnabled.png and b/dijit/themes/tundra/images/tabEnabled.png differ
diff --git a/dijit/themes/tundra/images/tabHover.png b/dijit/themes/tundra/images/tabHover.png
index 16487f1..4a38f5d 100644
Binary files a/dijit/themes/tundra/images/tabHover.png and b/dijit/themes/tundra/images/tabHover.png differ
diff --git a/dijit/themes/tundra/images/titleBar.png b/dijit/themes/tundra/images/titleBar.png
index b2609f3..f4de748 100644
Binary files a/dijit/themes/tundra/images/titleBar.png and b/dijit/themes/tundra/images/titleBar.png differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorDown.png b/dijit/themes/tundra/images/tooltipConnectorDown.png
index 1aff5a3..074b031 100644
Binary files a/dijit/themes/tundra/images/tooltipConnectorDown.png and b/dijit/themes/tundra/images/tooltipConnectorDown.png differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorLeft.png b/dijit/themes/tundra/images/tooltipConnectorLeft.png
index e68fec3..abd7ff6 100644
Binary files a/dijit/themes/tundra/images/tooltipConnectorLeft.png and b/dijit/themes/tundra/images/tooltipConnectorLeft.png differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorRight.png b/dijit/themes/tundra/images/tooltipConnectorRight.png
index dc2434a..9015f6b 100644
Binary files a/dijit/themes/tundra/images/tooltipConnectorRight.png and b/dijit/themes/tundra/images/tooltipConnectorRight.png differ
diff --git a/dijit/themes/tundra/images/tooltipConnectorUp.png b/dijit/themes/tundra/images/tooltipConnectorUp.png
index 55a378b..b54760f 100644
Binary files a/dijit/themes/tundra/images/tooltipConnectorUp.png and b/dijit/themes/tundra/images/tooltipConnectorUp.png differ
diff --git a/dijit/themes/tundra/images/treeExpand_loading.gif b/dijit/themes/tundra/images/treeExpand_loading.gif
index 424d376..4254ecf 100644
Binary files a/dijit/themes/tundra/images/treeExpand_loading.gif and b/dijit/themes/tundra/images/treeExpand_loading.gif differ
diff --git a/dijit/themes/tundra/images/treeHover.png b/dijit/themes/tundra/images/treeHover.png
index cd6d28b..e4d5d57 100644
Binary files a/dijit/themes/tundra/images/treeHover.png and b/dijit/themes/tundra/images/treeHover.png differ
diff --git a/dijit/themes/tundra/images/validationInputBg.png b/dijit/themes/tundra/images/validationInputBg.png
index d222fb4..47b236f 100644
Binary files a/dijit/themes/tundra/images/validationInputBg.png and b/dijit/themes/tundra/images/validationInputBg.png differ
diff --git a/dijit/themes/tundra/images/warning.png b/dijit/themes/tundra/images/warning.png
index c52f83d..07cabea 100644
Binary files a/dijit/themes/tundra/images/warning.png and b/dijit/themes/tundra/images/warning.png differ
diff --git a/dijit/themes/tundra/layout/TabContainer.css b/dijit/themes/tundra/layout/TabContainer.css
index 667da4a..a6676c6 100644
--- a/dijit/themes/tundra/layout/TabContainer.css
+++ b/dijit/themes/tundra/layout/TabContainer.css
@@ -9,15 +9,11 @@
 .tundra .dijitTab {
 	line-height:normal;
 	margin-right:4px;	/* space between one tab and the next in top/bottom mode */
-	padding:0;
+    padding:2px 8px 2px 9px;
 	border:1px solid #ccc;
 	background:#e2e2e2 url("../images/tabEnabled.png") repeat-x;
 }
 
-.tundra .dijitTabInnerDiv {
-	padding:2px 8px 2px 9px;
-}
-
 .tundra .dijitTabSpacer {
 	display: none;
 }
@@ -37,7 +33,7 @@
 	bottom: 2px;
 }
 
-/* checked tab*/
+/* selected tab */
 .tundra .dijitTabChecked {
 	/* the selected tab (with or without hover) */
 	background-color:#fff;
@@ -98,12 +94,11 @@
 	border: none;
 	top: 0;		/* to override top: 1px/-1px for normal tabs */
 }
-.tundra .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
-}
-.tundra .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent .tabLabel {
+
+.tundra .dijitTabContainerTabListNested .dijitTabHover .tabLabel {
 	text-decoration: underline;
 }
-.tundra .dijitTabContainerTabListNested .dijitTabChecked .dijitTabContent .tabLabel {
+.tundra .dijitTabContainerTabListNested .dijitTabChecked .tabLabel {
 	text-decoration: underline;
 	font-weight: bold;
 	/*background:#f3f3f3;*/
@@ -149,7 +144,7 @@
 	border-top: none;
 }
 
-/* checked tabs */
+/* selected tab */
 .tundra .dijitTabContainerTop-tabs .dijitTabChecked {
 	border-bottom-color:white;
 }
@@ -192,7 +187,7 @@
 	border-bottom: none;
 }
 
-/* checked tabs */
+/* selected tab */
 .tundra .dijitTabContainerBottom-tabs .dijitTabChecked {
 	border-top-color:white;
 }
@@ -222,7 +217,7 @@
 	border-right: none;
 }
 
-/* checked tabs */
+/* selected tab */
 .tundra .dijitTabContainerRight-tabs .dijitTabChecked {
 	border-left-color:white;
 }
@@ -245,12 +240,12 @@
 	height: 100%;
 }
 
-/* left conatiner */
+/* left container */
 .tundra .dijitTabContainerLeft-container {
 	border-left: none;
 }
 
-/* checked tabs */
+/* selected tab */
 .tundra .dijitTabContainerLeft-tabs .dijitTabChecked {
 	border-right-color:white;
 }
@@ -292,29 +287,18 @@
 }
 
 .tundra .dijitTabContainerBottom .tabStripButton {
-	padding-top: 2px;
+	padding-top: 3px;
 }
 
-.tundra .tabStrip-disabled .tabStripButton .dijitTabInnerDiv {
+.tundra .tabStrip-disabled .tabStripButton {
 	padding-bottom: 3px;
 	padding-top: 1px;
 }
 
-.tundra .tabStripButton .dijitTabInnerDiv {
+.tundra .tabStripButton {
 	padding: 3px 2px 4px 2px;
 }
 
-.dj_ie6 .tundra .tabStripButton .dijitTabInnerDiv,
-.dj_ie7 .tundra .tabStripButton .dijitTabInnerDiv,
-.dj_opera .tundra .tabStripButton .dijitTabInnerDiv {
-	padding-bottom: 5px;
-}
-.dj_ie6 .tundra .tabStrip-disabled .tabStripButton .dijitTabInnerDiv,
-.dj_ie7 .tundra .tabStrip-disabled .tabStripButton .dijitTabInnerDiv,
-.dj_opera .tundra .tabStrip-disabled .tabStripButton .dijitTabInnerDiv {
-	padding-bottom: 4px;
-}
-
 .tundra .dijitTabStripIcon {
 	height: 14px;
 	width: 14px;
diff --git a/dijit/themes/tundra/layout/TabContainer_rtl.css b/dijit/themes/tundra/layout/TabContainer_rtl.css
index fb8e28e..6e5ba75 100644
--- a/dijit/themes/tundra/layout/TabContainer_rtl.css
+++ b/dijit/themes/tundra/layout/TabContainer_rtl.css
@@ -1,51 +1,3 @@
 .tundra .dijitTabRtl {
-	-moz-box-orient:horizontal;
-	text-align: right;
-}
-
-.tundra .dijitTabRtl .dijitTabInnerDiv {
 	padding:2px 9px 2px 8px;
 }
-
-.tundra .tabStrip-disabled .tabStripButtonRtl .dijitTabInnerDiv {
-	/* this is not special for RTL mode, but just here to override rule above (for enabled tabstrip) */
-	padding-bottom: 3px;
-	padding-top: 1px;
-}
-
-.tundra .tabStripButtonRtl .dijitTabInnerDiv {
-	padding: 3px 2px 4px 2px;
-}
-
-.tundra .dijitTabPaneWrapper {
-	#zoom: 1;
-}
-
-.dj_ie-rtl .tundra .dijitTabContainerLeft-tabs {
-	margin-left: 1px !important;
-}
-
-.dj_ie-rtl .tundra .dijitTabContainerRight-tabs {
-	margin-right: 1px !important;
-}
-
-.tundra .dijitTabContainerLeft-tabs .dijitTabRtl,
-.tundra .dijitTabContainerRight-tabs .dijitTabRtl {
-	margin-left:0;
-}
-
-.dj_ie .tundra .dijitTabRtl .dijitTabInnerDiv {
-	/* without this the tab label and icon become invisible, as though they were set to visibility:hidden */
-	width : 0.1% !important;
-}
-
-
-
-.dj_iequirks-rtl .tundra .dijitTabContainerTopNone,
-.dj_iequirks-rtl .tundra .dijitTabContainerBottomNone {
-	/* this strange rule prevents IE6 bug in themeTesterQuirk.html?dir=rtl upon closing
-	 * "Closable" tab, where the other tabs disappear
-	 */
-	border-left: 1px solid #fff;
-	border-right: 1px solid #fff;
-}
diff --git a/dijit/themes/tundra/tundra_rtl.css b/dijit/themes/tundra/tundra_rtl.css
index 58b7541..04372e3 100644
--- a/dijit/themes/tundra/tundra_rtl.css
+++ b/dijit/themes/tundra/tundra_rtl.css
@@ -22,6 +22,7 @@
 @import url("../../icons/editorIcons_rtl.css");/* RTL sprite for editor icons to be used by all themes*/
 @import url("Menu_rtl.css");
 @import url("Tree_rtl.css");
+ at import url("ProgressBar_rtl.css");
 @import url("TitlePane_rtl.css");
 @import url("layout/TabContainer_rtl.css");
 @import url("form/Slider_rtl.css");
diff --git a/dijit/tree/ForestStoreModel.js b/dijit/tree/ForestStoreModel.js
index ca96361..0096ce4 100644
--- a/dijit/tree/ForestStoreModel.js
+++ b/dijit/tree/ForestStoreModel.js
@@ -1,27 +1,20 @@
 define([
 	"dojo/_base/array", // array.indexOf array.some
 	"dojo/_base/declare", // declare
+	"dojo/_base/kernel", // global
 	"dojo/_base/lang", // lang.hitch
-	"dojo/_base/window", // win.global
 	"./TreeStoreModel"
-], function(array, declare, lang, win, TreeStoreModel){
-
-/*=====
-var TreeStoreModel = dijit.tree.TreeStoreModel;
-=====*/
+], function(array, declare, kernel, lang, TreeStoreModel){
 
 // module:
 //		dijit/tree/ForestStoreModel
-// summary:
-//		Interface between a dijit.Tree and a dojo.data store that doesn't have a root item,
-//		a.k.a. a store that has multiple "top level" items.
 
 return declare("dijit.tree.ForestStoreModel", TreeStoreModel, {
 	// summary:
 	//		Interface between a dijit.Tree and a dojo.data store that doesn't have a root item,
 	//		a.k.a. a store that has multiple "top level" items.
 	//
-	// description
+	// description:
 	//		Use this class to wrap a dojo.data store, making all the items matching the specified query
 	//		appear as children of a fabricated "root item".  If no query is specified then all the
 	//		items returned by fetch() on the underlying store become children of the root item.
@@ -29,11 +22,12 @@ return declare("dijit.tree.ForestStoreModel", TreeStoreModel, {
 	//
 	//		When using this class the developer must override a number of methods according to their app and
 	//		data, including:
-	//			- onNewRootItem
-	//			- onAddToRoot
-	//			- onLeaveRoot
-	//			- onNewItem
-	//			- onSetItem
+	//
+	//		- onNewRootItem
+	//		- onAddToRoot
+	//		- onLeaveRoot
+	//		- onNewItem
+	//		- onSetItem
 
 	// Parameters to constructor
 
@@ -72,7 +66,7 @@ return declare("dijit.tree.ForestStoreModel", TreeStoreModel, {
 	// =======================================================================
 	// Methods for traversing hierarchy
 
-	mayHaveChildren: function(/*dojo.data.Item*/ item){
+	mayHaveChildren: function(/*dojo/data/Item*/ item){
 		// summary:
 		//		Tells if an item has or may have children.  Implementing logic here
 		//		avoids showing +/- expando icon for nodes that we know don't have children.
@@ -83,9 +77,9 @@ return declare("dijit.tree.ForestStoreModel", TreeStoreModel, {
 		return item === this.root || this.inherited(arguments);
 	},
 
-	getChildren: function(/*dojo.data.Item*/ parentItem, /*function(items)*/ callback, /*function*/ onError){
+	getChildren: function(/*dojo/data/Item*/ parentItem, /*function(items)*/ callback, /*function*/ onError){
 		// summary:
-		// 		Calls onComplete() with array of child items of given parent item, all loaded.
+		//		Calls onComplete() with array of child items of given parent item, all loaded.
 		if(parentItem === this.root){
 			if(this.root.children){
 				// already loaded, just return
@@ -114,7 +108,7 @@ return declare("dijit.tree.ForestStoreModel", TreeStoreModel, {
 
 	fetchItemByIdentity: function(/* object */ keywordArgs){
 		if(keywordArgs.identity == this.root.id){
-			var scope = keywordArgs.scope?keywordArgs.scope:win.global;
+			var scope = keywordArgs.scope || kernel.global;
 			if(keywordArgs.onItem){
 				keywordArgs.onItem.call(scope, this.root);
 			}
@@ -134,9 +128,9 @@ return declare("dijit.tree.ForestStoreModel", TreeStoreModel, {
 	// =======================================================================
 	// Write interface
 
-	newItem: function(/* dojo.dnd.Item */ args, /*Item*/ parent, /*int?*/ insertIndex){
+	newItem: function(/* dijit/tree/dndSource.__Item */ args, /*Item*/ parent, /*int?*/ insertIndex){
 		// summary:
-		//		Creates a new item.   See dojo.data.api.Write for details on args.
+		//		Creates a new item.   See dojo/data/api/Write for details on args.
 		//		Used in drag & drop when item from external source dropped onto tree.
 		if(parent === this.root){
 			this.onNewRootItem(args);
@@ -146,7 +140,7 @@ return declare("dijit.tree.ForestStoreModel", TreeStoreModel, {
 		}
 	},
 
-	onNewRootItem: function(/* dojo.dnd.Item */ /*===== args =====*/){
+	onNewRootItem: function(/* dijit/tree/dndSource.__Item */ /*===== args =====*/){
 		// summary:
 		//		User can override this method to modify a new element that's being
 		//		added to the root of the tree, for example to add a flag like root=true
@@ -197,7 +191,7 @@ return declare("dijit.tree.ForestStoreModel", TreeStoreModel, {
 		//		Called when item removed from root of tree; user must override this method
 		//		to modify the item so it doesn't match the query for top level items
 		// example:
-		// 	|	store.unsetAttribute(item, "root");
+		//	|	store.unsetAttribute(item, "root");
 		// tags:
 		//		extension
 		console.log(this, ": item ", item, " removed from root");
@@ -224,7 +218,7 @@ return declare("dijit.tree.ForestStoreModel", TreeStoreModel, {
 		});
 	},
 
-	onNewItem: function(/* dojo.data.Item */ item, /* Object */ parentInfo){
+	onNewItem: function(/* dojo/data/api/Item */ item, /* Object */ parentInfo){
 		// summary:
 		//		Handler for when new items appear in the store.  Developers should override this
 		//		method to be more efficient based on their app/data.
@@ -259,8 +253,8 @@ return declare("dijit.tree.ForestStoreModel", TreeStoreModel, {
 
 	onSetItem: function(/* item */ item,
 					/* attribute-name-string */ attribute,
-					/* object | array */ oldValue,
-					/* object | array */ newValue){
+					/* Object|Array */ oldValue,
+					/* Object|Array */ newValue){
 		// summary:
 		//		Updates the tree view according to changes to an item in the data store.
 		//		Developers should override this method to be more efficient based on their app/data.
diff --git a/dijit/tree/ObjectStoreModel.js b/dijit/tree/ObjectStoreModel.js
new file mode 100644
index 0000000..6e30ddc
--- /dev/null
+++ b/dijit/tree/ObjectStoreModel.js
@@ -0,0 +1,253 @@
+define([
+	"dojo/_base/array", // array.filter array.forEach array.indexOf array.some
+	"dojo/aspect", // aspect.before, aspect.after
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.hitch
+	"dojo/when"
+], function(array, aspect, declare, lang, when){
+
+	// module:
+	//		dijit/tree/ObjectStoreModel
+
+	return declare("dijit.tree.ObjectStoreModel", null, {
+		// summary:
+		//		Implements dijit/tree/model connecting dijit/Tree to a dojo/store/api/Store that implements
+		//		getChildren().
+		//
+		//		If getChildren() returns an array with an observe() method, then it will be leveraged to reflect
+		//		store updates to the tree.   So, this class will work best when:
+		//
+		//			1. the store implements dojo/store/Observable
+		//			2. getChildren() is implemented as a query to the server (i.e. it calls store.query())
+		//
+		//		Drag and Drop: To support drag and drop, besides implementing getChildren()
+		//		and dojo/store/Observable, the store must support the parent option to put().
+		//		And in order to have child elements ordered according to how the user dropped them,
+		//		put() must support the before option.
+
+		// store: dojo/store/api/Store
+		//		Underlying store
+		store: null,
+
+		// labelAttr: String
+		//		Get label for tree node from this attribute
+		labelAttr: "name",
+
+		// labelType: [const] String
+		//		Specifies how to interpret the labelAttr in the data store items.
+		//		Can be "html" or "text".
+		labelType: "text",
+
+		// root: [readonly] Object
+		//		Pointer to the root item from the dojo/store/api/Store (read only, not a parameter)
+		root: null,
+
+		// query: anything
+		//		Specifies datastore query to return the root item for the tree.
+		//		Must only return a single item.   Alternately can just pass in pointer
+		//		to root item.
+		// example:
+		//	|	{id:'ROOT'}
+		query: null,
+
+		constructor: function(/* Object */ args){
+			// summary:
+			//		Passed the arguments listed above (store, etc)
+			// tags:
+			//		private
+
+			lang.mixin(this, args);
+
+			this.childrenCache = {};	// map from id to array of children
+		},
+
+		destroy: function(){
+			// TODO: should cancel any in-progress processing of getRoot(), getChildren()
+			for(var id in this.childrenCache){
+				this.childrenCache[id].close && this.childrenCache[id].close();
+			}
+		},
+
+		// =======================================================================
+		// Methods for traversing hierarchy
+
+		getRoot: function(onItem, onError){
+			// summary:
+			//		Calls onItem with the root item for the tree, possibly a fabricated item.
+			//		Calls onError on error.
+			if(this.root){
+				onItem(this.root);
+			}else{
+				var res;
+				when(res = this.store.query(this.query),
+					lang.hitch(this, function(items){
+						//console.log("queried root: ", res);
+						if(items.length != 1){
+							throw new Error("dijit.tree.ObjectStoreModel: root query returned " + items.length +
+								" items, but must return exactly one");
+						}
+						this.root = items[0];
+						onItem(this.root);
+
+						// Setup listener to detect if root item changes
+						if(res.observe){
+							res.observe(lang.hitch(this, function(obj){
+								// Presumably removedFrom == insertedInto == 1, and this call indicates item has changed.
+								//console.log("root changed: ", obj);
+								this.onChange(obj);
+							}), true);	// true to listen for updates to obj
+						}
+					}),
+					onError
+				);
+			}
+		},
+
+		mayHaveChildren: function(/*===== item =====*/){
+			// summary:
+			//		Tells if an item has or might have children.  Implementing logic here
+			//		avoids showing +/- expando icon for nodes that we know won't have children.
+			//		(For efficiency reasons we may not want to check if an element actually
+			//		has children until user clicks the expando node).
+			//
+			//		Application code should override this method based on the data, for example
+			//		it could be `return item.leaf == true;`.
+			//
+			//		Note that mayHaveChildren() must return true for an item if it could possibly
+			//		have children in the future, due to drag-an-drop or some other data store update.
+			//		Also note that it may return true if it's just too expensive to check during tree
+			//		creation whether or not the item has children.
+			// item: Object
+			//		Item from the dojo/store
+			return true;
+		},
+
+		getChildren: function(/*Object*/ parentItem, /*function(items)*/ onComplete, /*function*/ onError){
+			// summary:
+			//		Calls onComplete() with array of child items of given parent item.
+			// parentItem:
+			//		Item from the dojo/store
+
+			var id = this.store.getIdentity(parentItem);
+			if(this.childrenCache[id]){
+				when(this.childrenCache[id], onComplete, onError);
+				return;
+			}
+
+			var res = this.childrenCache[id] = this.store.getChildren(parentItem);
+
+			// User callback
+			when(res, onComplete, onError);
+
+			// Setup listener in case children list changes, or the item(s) in the children list are
+			// updated in some way.
+			if(res.observe){
+				res.observe(lang.hitch(this, function(obj, removedFrom, insertedInto){
+					//console.log("observe on children of ", id, ": ", obj, removedFrom, insertedInto);
+
+					// If removedFrom == insertedInto, this call indicates that the item has changed.
+					// Even if removedFrom != insertedInto, the item may have changed.
+					this.onChange(obj);
+
+					if(removedFrom != insertedInto){
+						// Indicates an item was added, removed, or re-parented.  The children[] array (returned from
+						// res.then(...)) has already been updated (like a live collection), so just use it.
+						when(res, lang.hitch(this, "onChildrenChange", parentItem));
+					}
+				}), true);	// true means to notify on item changes
+			}
+		},
+
+		// =======================================================================
+		// Inspecting items
+
+		isItem: function(/*===== something =====*/){
+			return true;	// Boolean
+		},
+
+		getIdentity: function(/* item */ item){
+			return this.store.getIdentity(item);	// Object
+		},
+
+		getLabel: function(/*dojo/data/Item*/ item){
+			// summary:
+			//		Get the label for an item
+			return item[this.labelAttr];	// String
+		},
+
+		// =======================================================================
+		// Write interface, for DnD
+
+		newItem: function(/* dijit/tree/dndSource.__Item */ args, /*Item*/ parent, /*int?*/ insertIndex, /*Item*/ before){
+			// summary:
+			//		Creates a new item.   See `dojo/data/api/Write` for details on args.
+			//		Used in drag & drop when item from external source dropped onto tree.
+
+			return this.store.put(args, {
+				parent: parent,
+				before: before
+			});
+		},
+
+		pasteItem: function(/*Item*/ childItem, /*Item*/ oldParentItem, /*Item*/ newParentItem,
+					/*Boolean*/ bCopy, /*int?*/ insertIndex, /*Item*/ before){
+			// summary:
+			//		Move or copy an item from one parent item to another.
+			//		Used in drag & drop
+
+			if(!bCopy){
+				// In order for DnD moves to work correctly, childItem needs to be orphaned from oldParentItem
+				// before being adopted by newParentItem.   That way, the TreeNode is moved rather than
+				// an additional TreeNode being created, and the old TreeNode subsequently being deleted.
+				// The latter loses information such as selection and opened/closed children TreeNodes.
+				// Unfortunately simply calling this.store.put() will send notifications in a random order, based
+				// on when the TreeNodes in question originally appeared, and not based on the drag-from
+				// TreeNode vs. the drop-onto TreeNode.
+
+				var oldParentChildren = [].concat(this.childrenCache[this.getIdentity(oldParentItem)]), // concat to make copy
+					index = array.indexOf(oldParentChildren, childItem);
+				oldParentChildren.splice(index, 1);
+				this.onChildrenChange(oldParentItem, oldParentChildren);
+			}
+
+			return this.store.put(childItem, {
+				overwrite: true,
+				parent: newParentItem,
+				before: before
+			});
+		},
+
+		// =======================================================================
+		// Callbacks
+
+		onChange: function(/*dojo/data/Item*/ /*===== item =====*/){
+			// summary:
+			//		Callback whenever an item has changed, so that Tree
+			//		can update the label, icon, etc.   Note that changes
+			//		to an item's children or parent(s) will trigger an
+			//		onChildrenChange() so you can ignore those changes here.
+			// tags:
+			//		callback
+		},
+
+		onChildrenChange: function(/*===== parent, newChildrenList =====*/){
+			// summary:
+			//		Callback to do notifications about new, updated, or deleted items.
+			// parent: dojo/data/Item
+			// newChildrenList: Object[]
+			//		Items from the store
+			// tags:
+			//		callback
+		},
+
+		onDelete: function(/*dojo/data/Item*/ /*===== item =====*/){
+			// summary:
+			//		Callback when an item has been deleted.
+			//		Actually we have no way of knowing this with the new dojo.store API,
+			//		so this method is never called (but it's left here since Tree connects
+			//		to it).
+			// tags:
+			//		callback
+		}
+	});
+});
diff --git a/dijit/tree/TreeStoreModel.js b/dijit/tree/TreeStoreModel.js
index ca08cf7..36556dd 100644
--- a/dijit/tree/TreeStoreModel.js
+++ b/dijit/tree/TreeStoreModel.js
@@ -2,23 +2,19 @@ define([
 	"dojo/_base/array", // array.filter array.forEach array.indexOf array.some
 	"dojo/aspect", // aspect.after
 	"dojo/_base/declare", // declare
-	"dojo/_base/json", // json.stringify
 	"dojo/_base/lang" // lang.hitch
-], function(array, aspect, declare, json, lang){
+], function(array, aspect, declare, lang){
 
 	// module:
 	//		dijit/tree/TreeStoreModel
-	// summary:
-	//		Implements dijit.Tree.model connecting to a dojo.data store with a single
-	//		root item.
 
 	return declare("dijit.tree.TreeStoreModel", null, {
 		// summary:
-		//		Implements dijit.Tree.model connecting to a dojo.data store with a single
+		//		Implements dijit/Tree/model connecting to a dojo.data store with a single
 		//		root item.  Any methods passed into the constructor will override
 		//		the ones defined here.
 
-		// store: dojo.data.Store
+		// store: dojo/data/api/Read
 		//		Underlying store
 		store: null,
 
@@ -41,7 +37,7 @@ define([
 		//		than by calling store.getLabel()
 		labelAttr: "",
 
-	 	// root: [readonly] dojo.data.Item
+		// root: [readonly] dojo/data/Item
 		//		Pointer to the root item (read only, not a parameter)
 		root: null,
 
@@ -55,11 +51,11 @@ define([
 
 		// deferItemLoadingUntilExpand: Boolean
 		//		Setting this to true will cause the TreeStoreModel to defer calling loadItem on nodes
-		// 		until they are expanded. This allows for lazying loading where only one
+		//		until they are expanded. This allows for lazying loading where only one
 		//		loadItem (and generally one network call, consequently) per expansion
-		// 		(rather than one for each child).
-		// 		This relies on partial loading of the children items; each children item of a
-		// 		fully loaded item should contain the label and info about having children.
+		//		(rather than one for each child).
+		//		This relies on partial loading of the children items; each children item of a
+		//		fully loaded item should contain the label and info about having children.
 		deferItemLoadingUntilExpand: false,
 
 		constructor: function(/* Object */ args){
@@ -74,7 +70,7 @@ define([
 
 			var store = this.store;
 			if(!store.getFeatures()['dojo.data.api.Identity']){
-				throw new Error("dijit.Tree: store must support dojo.data.Identity");
+				throw new Error("dijit.tree.TreeStoreModel: store must support dojo.data.Identity");
 			}
 
 			// if the store supports Notification, subscribe to the notification events
@@ -107,8 +103,8 @@ define([
 					query: this.query,
 					onComplete: lang.hitch(this, function(items){
 						if(items.length != 1){
-							throw new Error(this.declaredClass + ": query " + json.stringify(this.query) + " returned " + items.length +
-							 	" items, but must return exactly one item");
+							throw new Error("dijit.tree.TreeStoreModel: root query returned " + items.length +
+								" items, but must return exactly one");
 						}
 						this.root = items[0];
 						onItem(this.root);
@@ -118,7 +114,7 @@ define([
 			}
 		},
 
-		mayHaveChildren: function(/*dojo.data.Item*/ item){
+		mayHaveChildren: function(/*dojo/data/Item*/ item){
 			// summary:
 			//		Tells if an item has or may have children.  Implementing logic here
 			//		avoids showing +/- expando icon for nodes that we know don't have children.
@@ -129,9 +125,9 @@ define([
 			}, this);
 		},
 
-		getChildren: function(/*dojo.data.Item*/ parentItem, /*function(items)*/ onComplete, /*function*/ onError){
+		getChildren: function(/*dojo/data/Item*/ parentItem, /*function(items)*/ onComplete, /*function*/ onError){
 			// summary:
-			// 		Calls onComplete() with array of child items of given parent item, all loaded.
+			//		Calls onComplete() with array of child items of given parent item, all loaded.
 
 			var store = this.store;
 			if(!store.isItemLoaded(parentItem)){
@@ -192,6 +188,14 @@ define([
 		},
 
 		fetchItemByIdentity: function(/* object */ keywordArgs){
+			// summary:
+			//		Given the identity of an item, this method returns the item that has
+			//		that identity through the onItem callback.  Conforming implementations
+			//		should return null if there is no item with the given identity.
+			//		Implementations of fetchItemByIdentity() may sometimes return an item
+			//		from a local cache and may sometimes fetch an item from a remote server.
+			// tags:
+			//		extension
 			this.store.fetchItemByIdentity(keywordArgs);
 		},
 
@@ -199,7 +203,7 @@ define([
 			return this.store.getIdentity(item);	// Object
 		},
 
-		getLabel: function(/*dojo.data.Item*/ item){
+		getLabel: function(/*dojo/data/Item*/ item){
 			// summary:
 			//		Get the label for an item
 			if(this.labelAttr){
@@ -212,9 +216,9 @@ define([
 		// =======================================================================
 		// Write interface
 
-		newItem: function(/* dojo.dnd.Item */ args, /*Item*/ parent, /*int?*/ insertIndex){
+		newItem: function(/* dijit/tree/dndSource.__Item */ args, /*dojo/data/api/Item*/ parent, /*int?*/ insertIndex){
 			// summary:
-			//		Creates a new item.   See `dojo.data.api.Write` for details on args.
+			//		Creates a new item.   See `dojo/data/api/Write` for details on args.
 			//		Used in drag & drop when item from external source dropped onto tree.
 			// description:
 			//		Developers will need to override this method if new items get added
@@ -287,7 +291,7 @@ define([
 		// =======================================================================
 		// Callbacks
 
-		onChange: function(/*dojo.data.Item*/ /*===== item =====*/){
+		onChange: function(/*dojo/data/Item*/ /*===== item =====*/){
 			// summary:
 			//		Callback whenever an item has changed, so that Tree
 			//		can update the label, icon, etc.   Note that changes
@@ -300,13 +304,13 @@ define([
 		onChildrenChange: function(/*===== parent, newChildrenList =====*/){
 			// summary:
 			//		Callback to do notifications about new, updated, or deleted items.
-			// parent: dojo.data.Item
-			// newChildrenList: dojo.data.Item[]
+			// parent: dojo/data/Item
+			// newChildrenList: dojo/data/Item[]
 			// tags:
 			//		callback
 		},
 
-		onDelete: function(/*dojo.data.Item*/ /*===== item =====*/){
+		onDelete: function(/*dojo/data/Item*/ /*===== item =====*/){
 			// summary:
 			//		Callback when an item has been deleted.
 			// description:
@@ -319,7 +323,7 @@ define([
 		// =======================================================================
 		// Events from data store
 
-		onNewItem: function(/* dojo.data.Item */ item, /* Object */ parentInfo){
+		onNewItem: function(/* dojo/data/Item */ item, /* Object */ parentInfo){
 			// summary:
 			//		Handler for when new items appear in the store, either from a drop operation
 			//		or some other way.   Updates the tree view (if necessary).
@@ -363,8 +367,8 @@ define([
 			//		See `onNewItem` for more details on handling updates to an item's children.
 			// item: Item
 			// attribute: attribute-name-string
-			// oldValue: object | array
-			// newValue: object | array
+			// oldValue: Object|Array
+			// newValue: Object|Array
 			// tags:
 			//		extension
 
diff --git a/dijit/tree/_dndContainer.js b/dijit/tree/_dndContainer.js
index c5c0157..4492074 100644
--- a/dijit/tree/_dndContainer.js
+++ b/dijit/tree/_dndContainer.js
@@ -1,40 +1,53 @@
 define([
-	"dojo/aspect",	// aspect.after
+	"dojo/aspect", // aspect.after
 	"dojo/_base/declare", // declare
 	"dojo/dom-class", // domClass.add domClass.remove domClass.replace
-	"dojo/_base/event",	// event.stop
-	"dojo/_base/lang", // lang.getObject lang.mixin lang.hitch
-	"dojo/mouse",	// mouse.enter, mouse.leave
-	"dojo/on"
-], function(aspect, declare, domClass, event, lang, mouse, on){
+	"dojo/_base/lang", // lang.mixin lang.hitch
+	"dojo/on",
+	"dojo/touch"
+], function(aspect, declare, domClass, lang, on, touch){
 
 	// module:
 	//		dijit/tree/_dndContainer
-	// summary:
-	//		This is a base class for `dijit.tree._dndSelector`, and isn't meant to be used directly.
-	//		It's modeled after `dojo.dnd.Container`.
+
+	/*=====
+	 var __Args = {
+	 // summary:
+	 //		A dict of parameters for Tree source configuration.
+	 // isSource: Boolean?
+	 //		Can be used as a DnD source. Defaults to true.
+	 // accept: String[]
+	 //		List of accepted types (text strings) for a target; defaults to
+	 //		["text", "treeNode"]
+	 // copyOnly: Boolean?
+	 //		Copy items, if true, use a state of Ctrl key otherwise,
+	 // dragThreshold: Number
+	 //		The move delay in pixels before detecting a drag; 0 by default
+	 // betweenThreshold: Integer
+	 //		Distance from upper/lower edge of node to allow drop to reorder nodes
+	 };
+	 =====*/
 
 	return declare("dijit.tree._dndContainer", null, {
 
 		// summary:
-		//		This is a base class for `dijit.tree._dndSelector`, and isn't meant to be used directly.
-		//		It's modeled after `dojo.dnd.Container`.
+		//		This is a base class for `dijit/tree/_dndSelector`, and isn't meant to be used directly.
+		//		It's modeled after `dojo/dnd/Container`.
 		// tags:
 		//		protected
 
 		/*=====
-		// current: DomNode
-		//		The currently hovered TreeNode.rowNode (which is the DOM node
-		//		associated w/a given node in the tree, excluding it's descendants)
-		current: null,
-		=====*/
+		 // current: TreeNode
+		 //		The currently hovered TreeNode.  Not set to anything for keyboard operation.  (TODO: change?)
+		 current: null,
+		 =====*/
 
 		constructor: function(tree, params){
 			// summary:
 			//		A constructor of the Container
 			// tree: Node
 			//		Node or node's id to build the container on
-			// params: dijit.tree.__SourceArgs
+			// params: __Args
 			//		A dict of parameters, which gets mixed into the object
 			// tags:
 			//		private
@@ -42,26 +55,24 @@ define([
 			this.node = tree.domNode;	// TODO: rename; it's not a TreeNode but the whole Tree
 			lang.mixin(this, params);
 
-			// class-specific variables
-			this.current = null;	// current TreeNode's DOM node
-
 			// states
 			this.containerState = "";
 			domClass.add(this.node, "dojoDndContainer");
 
 			// set up events
 			this.events = [
-				// container level events
-				on(this.node, mouse.enter, lang.hitch(this, "onOverEvent")),
-				on(this.node, mouse.leave,	lang.hitch(this, "onOutEvent")),
+				// Mouse (or touch) enter/leave on Tree itself
+				on(this.node, touch.enter, lang.hitch(this, "onOverEvent")),
+				on(this.node, touch.leave, lang.hitch(this, "onOutEvent")),
 
 				// switching between TreeNodes
 				aspect.after(this.tree, "_onNodeMouseEnter", lang.hitch(this, "onMouseOver"), true),
 				aspect.after(this.tree, "_onNodeMouseLeave", lang.hitch(this, "onMouseOut"), true),
 
 				// cancel text selection and text dragging
-				on(this.node, "dragstart", lang.hitch(event, "stop")),
-				on(this.node, "selectstart", lang.hitch(event, "stop"))
+				on(this.node, "dragstart, selectstart", function(evt){
+					evt.preventDefault();
+				})
 			];
 		},
 
@@ -70,7 +81,9 @@ define([
 			//		Prepares this object to be garbage-collected
 
 			var h;
-			while(h = this.events.pop()){ h.remove(); }
+			while(h = this.events.pop()){
+				h.remove();
+			}
 
 			// this.clearItems();
 			this.node = this.parent = null;
diff --git a/dijit/tree/_dndSelector.js b/dijit/tree/_dndSelector.js
index 99fc52e..5bc340a 100644
--- a/dijit/tree/_dndSelector.js
+++ b/dijit/tree/_dndSelector.js
@@ -2,31 +2,29 @@ define([
 	"dojo/_base/array", // array.filter array.forEach array.map
 	"dojo/_base/connect", // connect.isCopyKey
 	"dojo/_base/declare", // declare
+	"dojo/_base/kernel",	// global
 	"dojo/_base/lang", // lang.hitch
+	"dojo/dom", // isDescendant
 	"dojo/mouse", // mouse.isLeft
 	"dojo/on",
 	"dojo/touch",
-	"dojo/_base/window", // win.global
+	"../a11yclick",
 	"./_dndContainer"
-], function(array, connect, declare, lang, mouse, on, touch, win, _dndContainer){
+], function(array, connect, declare, kernel, lang, dom, mouse, on, touch, a11yclick, _dndContainer){
 
 	// module:
 	//		dijit/tree/_dndSelector
-	// summary:
-	//		This is a base class for `dijit.tree.dndSource` , and isn't meant to be used directly.
-	//		It's based on `dojo.dnd.Selector`.
-
 
 	return declare("dijit.tree._dndSelector", _dndContainer, {
 		// summary:
-		//		This is a base class for `dijit.tree.dndSource` , and isn't meant to be used directly.
-		//		It's based on `dojo.dnd.Selector`.
+		//		This is a base class for `dijit/tree/dndSource`, and isn't meant to be used directly.
+		//		It's based on `dojo/dnd/Selector`.
 		// tags:
 		//		protected
 
 		/*=====
-		// selection: Hash<String, DomNode>
-		//		(id, DomNode) map for every TreeNode that's currently selected.
+		// selection: Object
+		//		(id to DomNode) map for every TreeNode that's currently selected.
 		//		The DOMNode is the TreeNode.rowNode.
 		selection: {},
 		=====*/
@@ -40,16 +38,19 @@ define([
 			this.selection={};
 			this.anchor = null;
 
-			this.tree.domNode.setAttribute("aria-multiselect", !this.singular);
-
 			this.events.push(
+				// listeners setup here but no longer used (left for backwards compatibility
 				on(this.tree.domNode, touch.press, lang.hitch(this,"onMouseDown")),
 				on(this.tree.domNode, touch.release, lang.hitch(this,"onMouseUp")),
-				on(this.tree.domNode, touch.move, lang.hitch(this,"onMouseMove"))
+
+				// listeners used in this module
+				on(this.tree.domNode, touch.move, lang.hitch(this,"onMouseMove")),
+				on(this.tree.domNode, a11yclick.press, lang.hitch(this,"onClickPress")),
+				on(this.tree.domNode, a11yclick.release, lang.hitch(this,"onClickRelease"))
 			);
 		},
 
-		//	singular: Boolean
+		// singular: Boolean
 		//		Allows selection of only one element, if true.
 		//		Tree hasn't been tested in singular=true mode, unclear if it works.
 		singular: false,
@@ -84,7 +85,7 @@ define([
 			this.inherited(arguments);
 			this.selection = this.anchor = null;
 		},
-		addTreeNode: function(/*dijit._TreeNode*/node, /*Boolean?*/isAnchor){
+		addTreeNode: function(/*dijit/Tree._TreeNode*/ node, /*Boolean?*/isAnchor){
 			// summary:
 			//		add node to current selection
 			// node: Node
@@ -96,15 +97,18 @@ define([
 			if(isAnchor){ this.anchor = node; }
 			return node;
 		},
-		removeTreeNode: function(/*dijit._TreeNode*/node){
+		removeTreeNode: function(/*dijit/Tree._TreeNode*/ node){
 			// summary:
-			//		remove node from current selection
+			//		remove node and it's descendants from current selection
 			// node: Node
 			//		node to remove
-			this.setSelection(this._setDifference(this.getSelectedTreeNodes(), [node]));
+			var newSelection = array.filter(this.getSelectedTreeNodes(), function(selectedNode){
+				return !dom.isDescendant(selectedNode.domNode, node.domNode); // also matches when selectedNode == node
+			});
+			this.setSelection(newSelection);
 			return node;
 		},
-		isTreeNodeSelected: function(/*dijit._TreeNode*/node){
+		isTreeNodeSelected: function(/*dijit/Tree._TreeNode*/ node){
 			// summary:
 			//		return true if node is currently selected
 			// node: Node
@@ -112,7 +116,7 @@ define([
 
 			return node.id && !!this.selection[node.id];
 		},
-		setSelection: function(/*dijit._treeNode[]*/ newSelection){
+		setSelection: function(/*dijit/Tree._TreeNode[]*/ newSelection){
 			// summary:
 			//		set the list of selected nodes to be exactly newSelection. All changes to the
 			//		selection should be passed through this function, which ensures that derived
@@ -154,11 +158,16 @@ define([
 			//		path[s], selectedItem[s], selectedNode[s]
 
 			var selected = this.getSelectedTreeNodes();
-			var paths = [], nodes = [];
+			var paths = [], nodes = [], selects = [];
 			array.forEach(selected, function(node){
+				var ary = node.getTreePath(), model = this.tree.model;
 				nodes.push(node);
-				paths.push(node.getTreePath());
-			});
+				paths.push(ary);
+				ary = array.map(ary, function(item){
+					return model.getIdentity(item);
+				}, this);
+				selects.push(ary.join("/"))
+			}, this);
 			var items = array.map(nodes,function(node){ return node.item; });
 			this.tree._set("paths", paths);
 			this.tree._set("path", paths[0] || []);
@@ -167,24 +176,34 @@ define([
 			this.tree._set("selectedItems", items);
 			this.tree._set("selectedItem", items[0] || null);
 		},
-		// mouse events
-		onMouseDown: function(e){
+
+		// selection related events
+		onClickPress: function(e){
 			// summary:
-			//		Event processor for onmousedown/ontouchstart
+			//		Event processor for onmousedown/ontouchstart/onkeydown corresponding to a click event
 			// e: Event
-			//		onmousedown/ontouchstart event
+			//		onmousedown/ontouchstart/onkeydown event
 			// tags:
 			//		protected
 
-			// ignore click on expando node
-			if(!this.current || this.tree.isExpandoNode(e.target, this.current)){ return; }
+			// ignore mouse or touch on expando node
+			if(this.current && this.current.isExpandable && this.tree.isExpandoNode(e.target, this.current)){ return; }
 
-			if(!mouse.isLeft(e)){ return; } // ignore right-click
+			if(mouse.isLeft(e)){
+				// Prevent text selection while dragging on desktop, see #16328.   But don't call preventDefault()
+				// for mobile because it will break things completely, see #15838.
+				e.preventDefault();
+			}
+
+			var treeNode = e.type == "keydown" ? this.tree.focusedChild : this.current;
 
-			e.preventDefault();
+			if(!treeNode){
+				// Click must be on the Tree but not on a TreeNode, happens especially when Tree is stretched to fill
+				// a pane of a BorderContainer, etc.
+				return;
+			}
 
-			var treeNode = this.current,
-			  copy = connect.isCopyKey(e), id = treeNode.id;
+			var copy = connect.isCopyKey(e), id = treeNode.id;
 
 			// if shift key is not pressed, and the node is already in the selection,
 			// delay deselection until onmouseup so in the case of DND, deselection
@@ -198,22 +217,22 @@ define([
 			this.userSelect(treeNode, copy, e.shiftKey);
 		},
 
-		onMouseUp: function(e){
+		onClickRelease: function(e){
 			// summary:
-			//		Event processor for onmouseup/ontouchend
+			//		Event processor for onmouseup/ontouchend/onkeyup corresponding to a click event
 			// e: Event
-			//		onmouseup/ontouchend event
+			//		onmouseup/ontouchend/onkeyup event
 			// tags:
 			//		protected
 
 			// _doDeselect is the flag to indicate that the user wants to either ctrl+click on
-			// a already selected item (to deselect the item), or click on a not-yet selected item
+			// an already selected item (to deselect the item), or click on a not-yet selected item
 			// (which should remove all current selection, and add the clicked item). This can not
 			// be done in onMouseDown, because the user may start a drag after mousedown. By moving
-			// the deselection logic here, the user can drags an already selected item.
+			// the deselection logic here, the user can drag an already selected item.
 			if(!this._doDeselect){ return; }
 			this._doDeselect = false;
-			this.userSelect(this.current, connect.isCopyKey(e), e.shiftKey);
+			this.userSelect(e.type == "keyup" ? this.tree.focusedChild : this.current, connect.isCopyKey(e), e.shiftKey);
 		},
 		onMouseMove: function(/*===== e =====*/){
 			// summary:
@@ -223,6 +242,24 @@ define([
 			this._doDeselect = false;
 		},
 
+		// mouse/touch events that are no longer used
+		onMouseDown: function(){
+			// summary:
+			//		Event processor for onmousedown/ontouchstart
+			// e: Event
+			//		onmousedown/ontouchstart event
+			// tags:
+			//		protected
+		},
+		onMouseUp: function(){
+			// summary:
+			//		Event processor for onmouseup/ontouchend
+			// e: Event
+			//		onmouseup/ontouchend event
+			// tags:
+			//		protected
+		},
+
 		_compareNodes: function(n1, n2){
 			if(n1 === n2){
 				return 0;
@@ -280,7 +317,7 @@ define([
 					//add everything betweeen begin and end inclusively
 					while(begin != end){
 						nodes.push(begin);
-						begin = this.tree._getNextNode(begin);
+						begin = this.tree._getNext(begin);
 					}
 					nodes.push(end);
 
@@ -300,8 +337,8 @@ define([
 
 		getItem: function(/*String*/ key){
 			// summary:
-			//		Returns the dojo.dnd.Item (representing a dragged node) by it's key (id).
-			//		Called by dojo.dnd.Source.checkAcceptance().
+			//		Returns the dojo/dnd/Container._Item (representing a dragged node) by it's key (id).
+			//		Called by dojo/dnd/Source.checkAcceptance().
 			// tags:
 			//		protected
 
@@ -309,14 +346,14 @@ define([
 			return {
 				data: widget,
 				type: ["treeNode"]
-			}; // dojo.dnd.Item
+			}; // dojo/dnd/Container._Item
 		},
 
 		forInSelectedItems: function(/*Function*/ f, /*Object?*/ o){
 			// summary:
 			//		Iterates over selected items;
-			//		see `dojo.dnd.Container.forInItems()` for details
-			o = o || win.global;
+			//		see `dojo/dnd/Container.forInItems()` for details
+			o = o || kernel.global;
 			for(var id in this.selection){
 				// console.log("selected item id: " + id);
 				f.call(o, this.getItem(id), id, this);
diff --git a/dijit/tree/dndSource.js b/dijit/tree/dndSource.js
index 2e10e2e..05aee3e 100644
--- a/dijit/tree/dndSource.js
+++ b/dijit/tree/dndSource.js
@@ -12,553 +12,561 @@ define([
 	"./_dndSelector"
 ], function(array, connect, declare, domClass, domGeometry, lang, on, touch, topic, DNDManager, _dndSelector){
 
-// module:
-//		dijit/tree/dndSource
-// summary:
-//		Handles drag and drop operations (as a source or a target) for `dijit.Tree`
-
-/*=====
-dijit.tree.__SourceArgs = function(){
-	// summary:
-	//		A dict of parameters for Tree source configuration.
-	// isSource: Boolean?
-	//		Can be used as a DnD source. Defaults to true.
-	// accept: String[]
-	//		List of accepted types (text strings) for a target; defaults to
-	//		["text", "treeNode"]
-	// copyOnly: Boolean?
-	//		Copy items, if true, use a state of Ctrl key otherwise,
-	// dragThreshold: Number
-	//		The move delay in pixels before detecting a drag; 0 by default
-	// betweenThreshold: Integer
-	//		Distance from upper/lower edge of node to allow drop to reorder nodes
-	this.isSource = isSource;
-	this.accept = accept;
-	this.autoSync = autoSync;
-	this.copyOnly = copyOnly;
-	this.dragThreshold = dragThreshold;
-	this.betweenThreshold = betweenThreshold;
-}
-=====*/
-
-return declare("dijit.tree.dndSource", _dndSelector, {
-	// summary:
-	//		Handles drag and drop operations (as a source or a target) for `dijit.Tree`
-
-	// isSource: [private] Boolean
-	//		Can be used as a DnD source.
-	isSource: true,
-
-	// accept: String[]
-	//		List of accepted types (text strings) for the Tree; defaults to
-	//		["text"]
-	accept: ["text", "treeNode"],
-
-	// copyOnly: [private] Boolean
-	//		Copy items, if true, use a state of Ctrl key otherwise
-	copyOnly: false,
-
-	// dragThreshold: Number
-	//		The move delay in pixels before detecting a drag; 5 by default
-	dragThreshold: 5,
-
-	// betweenThreshold: Integer
-	//		Distance from upper/lower edge of node to allow drop to reorder nodes
-	betweenThreshold: 0,
-
-	constructor: function(/*dijit.Tree*/ tree, /*dijit.tree.__SourceArgs*/ params){
-		// summary:
-		//		a constructor of the Tree DnD Source
-		// tags:
-		//		private
-		if(!params){ params = {}; }
-		lang.mixin(this, params);
-		this.isSource = typeof params.isSource == "undefined" ? true : params.isSource;
-		var type = params.accept instanceof Array ? params.accept : ["text", "treeNode"];
-		this.accept = null;
-		if(type.length){
-			this.accept = {};
-			for(var i = 0; i < type.length; ++i){
-				this.accept[type[i]] = 1;
-			}
-		}
+	// module:
+	//		dijit/tree/dndSource
 
-		// class-specific variables
-		this.isDragging = false;
-		this.mouseDown = false;
-		this.targetAnchor = null;	// DOMNode corresponding to the currently moused over TreeNode
-		this.targetBox = null;	// coordinates of this.targetAnchor
-		this.dropPosition = "";	// whether mouse is over/after/before this.targetAnchor
-		this._lastX = 0;
-		this._lastY = 0;
-
-		// states
-		this.sourceState = "";
-		if(this.isSource){
-			domClass.add(this.node, "dojoDndSource");
-		}
-		this.targetState = "";
-		if(this.accept){
-			domClass.add(this.node, "dojoDndTarget");
-		}
-
-		// set up events
-		this.topics = [
-			topic.subscribe("/dnd/source/over", lang.hitch(this, "onDndSourceOver")),
-			topic.subscribe("/dnd/start", lang.hitch(this, "onDndStart")),
-			topic.subscribe("/dnd/drop", lang.hitch(this, "onDndDrop")),
-			topic.subscribe("/dnd/cancel", lang.hitch(this, "onDndCancel"))
-		];
-	},
-
-	// methods
-	checkAcceptance: function(/*===== source, nodes =====*/){
-		// summary:
-		//		Checks if the target can accept nodes from this source
-		// source: dijit.tree.dndSource
-		//		The source which provides items
-		// nodes: DOMNode[]
-		//		Array of DOM nodes corresponding to nodes being dropped, dijitTreeRow nodes if
-		//		source is a dijit.Tree.
-		// tags:
-		//		extension
-		return true;	// Boolean
-	},
-
-	copyState: function(keyPressed){
+	/*=====
+	var __Item = {
 		// summary:
-		//		Returns true, if we need to copy items, false to move.
-		//		It is separated to be overwritten dynamically, if needed.
-		// keyPressed: Boolean
-		//		The "copy" control key was pressed
-		// tags:
-		//		protected
-		return this.copyOnly || keyPressed;	// Boolean
-	},
-	destroy: function(){
+		//		New item to be added to the Tree, like:
+		// id: Anything
+		id: "",
+		// name: String
+		name: ""
+	};
+	=====*/
+
+	var dndSource = declare("dijit.tree.dndSource", _dndSelector, {
 		// summary:
-		//		Prepares the object to be garbage-collected.
-		this.inherited(arguments);
-		var h;
-		while(h = this.topics.pop()){ h.remove(); }
-		this.targetAnchor = null;
-	},
-
-	_onDragMouse: function(e){
-		// summary:
-		//		Helper method for processing onmousemove/onmouseover events while drag is in progress.
-		//		Keeps track of current drop target.
-
-		var m = DNDManager.manager(),
-			oldTarget = this.targetAnchor,			// the TreeNode corresponding to TreeNode mouse was previously over
-			newTarget = this.current,				// TreeNode corresponding to TreeNode mouse is currently over
-			oldDropPosition = this.dropPosition;	// the previous drop position (over/before/after)
-
-		// calculate if user is indicating to drop the dragged node before, after, or over
-		// (i.e., to become a child of) the target node
-		var newDropPosition = "Over";
-		if(newTarget && this.betweenThreshold > 0){
-			// If mouse is over a new TreeNode, then get new TreeNode's position and size
-			if(!this.targetBox || oldTarget != newTarget){
-				this.targetBox = domGeometry.position(newTarget.rowNode, true);
+		//		Handles drag and drop operations (as a source or a target) for `dijit.Tree`
+
+		// isSource: Boolean
+		//		Can be used as a DnD source.
+		isSource: true,
+
+		// accept: String[]
+		//		List of accepted types (text strings) for the Tree; defaults to
+		//		["text"]
+		accept: ["text", "treeNode"],
+
+		// copyOnly: [private] Boolean
+		//		Copy items, if true, use a state of Ctrl key otherwise
+		copyOnly: false,
+
+		// dragThreshold: Number
+		//		The move delay in pixels before detecting a drag; 5 by default
+		dragThreshold: 5,
+
+		// betweenThreshold: Integer
+		//		Distance from upper/lower edge of node to allow drop to reorder nodes
+		betweenThreshold: 0,
+
+		// Flag used by Avatar.js to signal to generate text node when dragging
+		generateText: true,
+
+		constructor: function(/*dijit/Tree*/ tree, /*dijit/tree/dndSource*/ params){
+			// summary:
+			//		a constructor of the Tree DnD Source
+			// tags:
+			//		private
+			if(!params){
+				params = {};
 			}
-			if((e.pageY - this.targetBox.y) <= this.betweenThreshold){
-				newDropPosition = "Before";
-			}else if((e.pageY - this.targetBox.y) >= (this.targetBox.h - this.betweenThreshold)){
-				newDropPosition = "After";
+			lang.mixin(this, params);
+			var type = params.accept instanceof Array ? params.accept : ["text", "treeNode"];
+			this.accept = null;
+			if(type.length){
+				this.accept = {};
+				for(var i = 0; i < type.length; ++i){
+					this.accept[type[i]] = 1;
+				}
 			}
-		}
 
-		if(newTarget != oldTarget || newDropPosition != oldDropPosition){
-			if(oldTarget){
-				this._removeItemClass(oldTarget.rowNode, oldDropPosition);
+			// class-specific variables
+			this.isDragging = false;
+			this.mouseDown = false;
+			this.targetAnchor = null;	// DOMNode corresponding to the currently moused over TreeNode
+			this.targetBox = null;	// coordinates of this.targetAnchor
+			this.dropPosition = "";	// whether mouse is over/after/before this.targetAnchor
+			this._lastX = 0;
+			this._lastY = 0;
+
+			// states
+			this.sourceState = "";
+			if(this.isSource){
+				domClass.add(this.node, "dojoDndSource");
 			}
-			if(newTarget){
-				this._addItemClass(newTarget.rowNode, newDropPosition);
+			this.targetState = "";
+			if(this.accept){
+				domClass.add(this.node, "dojoDndTarget");
 			}
 
-			// Check if it's ok to drop the dragged node on/before/after the target node.
-			if(!newTarget){
-				m.canDrop(false);
-			}else if(newTarget == this.tree.rootNode && newDropPosition != "Over"){
-				// Can't drop before or after tree's root node; the dropped node would just disappear (at least visually)
-				m.canDrop(false);
-			}else{
-				// Guard against dropping onto yourself (TODO: guard against dropping onto your descendant, #7140)
-				var model = this.tree.model,
-					sameId = false;
-				if(m.source == this){
-					for(var dragId in this.selection){
-						var dragNode = this.selection[dragId];
-						if(dragNode.item === newTarget.item){
-							sameId = true;
-							break;
-						}
-					}
+			// set up events
+			this.topics = [
+				topic.subscribe("/dnd/source/over", lang.hitch(this, "onDndSourceOver")),
+				topic.subscribe("/dnd/start", lang.hitch(this, "onDndStart")),
+				topic.subscribe("/dnd/drop", lang.hitch(this, "onDndDrop")),
+				topic.subscribe("/dnd/cancel", lang.hitch(this, "onDndCancel"))
+			];
+		},
+
+		// methods
+		checkAcceptance: function(/*===== source, nodes =====*/){
+			// summary:
+			//		Checks if the target can accept nodes from this source
+			// source: dijit/tree/dndSource
+			//		The source which provides items
+			// nodes: DOMNode[]
+			//		Array of DOM nodes corresponding to nodes being dropped, dijitTreeRow nodes if
+			//		source is a dijit/Tree.
+			// tags:
+			//		extension
+			return true;	// Boolean
+		},
+
+		copyState: function(keyPressed){
+			// summary:
+			//		Returns true, if we need to copy items, false to move.
+			//		It is separated to be overwritten dynamically, if needed.
+			// keyPressed: Boolean
+			//		The "copy" control key was pressed
+			// tags:
+			//		protected
+			return this.copyOnly || keyPressed;	// Boolean
+		},
+		destroy: function(){
+			// summary:
+			//		Prepares the object to be garbage-collected.
+			this.inherited(arguments);
+			var h;
+			while(h = this.topics.pop()){
+				h.remove();
+			}
+			this.targetAnchor = null;
+		},
+
+		_onDragMouse: function(e, firstTime){
+			// summary:
+			//		Helper method for processing onmousemove/onmouseover events while drag is in progress.
+			//		Keeps track of current drop target.
+			// e: Event
+			//		The mousemove event.
+			// firstTime: Boolean?
+			//		If this flag is set, this is the first mouse move event of the drag, so call m.canDrop() etc.
+			//		even if newTarget == null because the user quickly dragged a node in the Tree to a position
+			//		over Tree.containerNode but not over any TreeNode (#7971)
+
+			var m = DNDManager.manager(),
+				oldTarget = this.targetAnchor, // the TreeNode corresponding to TreeNode mouse was previously over
+				newTarget = this.current, // TreeNode corresponding to TreeNode mouse is currently over
+				oldDropPosition = this.dropPosition;	// the previous drop position (over/before/after)
+
+			// calculate if user is indicating to drop the dragged node before, after, or over
+			// (i.e., to become a child of) the target node
+			var newDropPosition = "Over";
+			if(newTarget && this.betweenThreshold > 0){
+				// If mouse is over a new TreeNode, then get new TreeNode's position and size
+				if(!this.targetBox || oldTarget != newTarget){
+					this.targetBox = domGeometry.position(newTarget.rowNode, true);
 				}
-				if(sameId){
-					m.canDrop(false);
-				}else if(this.checkItemAcceptance(newTarget.rowNode, m.source, newDropPosition.toLowerCase())
-						&& !this._isParentChildDrop(m.source, newTarget.rowNode)){
-					m.canDrop(true);
-				}else{
-					m.canDrop(false);
+				if((e.pageY - this.targetBox.y) <= this.betweenThreshold){
+					newDropPosition = "Before";
+				}else if((e.pageY - this.targetBox.y) >= (this.targetBox.h - this.betweenThreshold)){
+					newDropPosition = "After";
 				}
 			}
 
-			this.targetAnchor = newTarget;
-			this.dropPosition = newDropPosition;
-		}
-	},
+			if(firstTime || newTarget != oldTarget || newDropPosition != oldDropPosition){
+				if(oldTarget){
+					this._removeItemClass(oldTarget.rowNode, oldDropPosition);
+				}
+				if(newTarget){
+					this._addItemClass(newTarget.rowNode, newDropPosition);
+				}
 
-	onMouseMove: function(e){
-		// summary:
-		//		Called for any onmousemove/ontouchmove events over the Tree
-		// e: Event
-		//		onmousemouse/ontouchmove event
-		// tags:
-		//		private
-		if(this.isDragging && this.targetState == "Disabled"){ return; }
-		this.inherited(arguments);
-		var m = DNDManager.manager();
-		if(this.isDragging){
-			this._onDragMouse(e);
-		}else{
-			if(this.mouseDown && this.isSource &&
-				 (Math.abs(e.pageX-this._lastX)>=this.dragThreshold || Math.abs(e.pageY-this._lastY)>=this.dragThreshold)){
-				var nodes = this.getSelectedTreeNodes();
-				if(nodes.length){
-					if(nodes.length > 1){
-						//filter out all selected items which has one of their ancestor selected as well
-						var seen = this.selection, i = 0, r = [], n, p;
-						nextitem: while((n = nodes[i++])){
-							for(p = n.getParent(); p && p !== this.tree; p = p.getParent()){
-								if(seen[p.id]){ //parent is already selected, skip this node
-									continue nextitem;
+				// Check if it's ok to drop the dragged node on/before/after the target node.
+				if(!newTarget){
+					m.canDrop(false);
+				}else if(newTarget == this.tree.rootNode && newDropPosition != "Over"){
+					// Can't drop before or after tree's root node; the dropped node would just disappear (at least visually)
+					m.canDrop(false);
+				}else{
+					// Guard against dropping onto yourself (TODO: guard against dropping onto your descendant, #7140)
+					var sameId = false;
+					if(m.source == this){
+						for(var dragId in this.selection){
+							var dragNode = this.selection[dragId];
+							if(dragNode.item === newTarget.item){
+								sameId = true;
+								break;
+							}
+						}
+					}
+					if(sameId){
+						m.canDrop(false);
+					}else if(this.checkItemAcceptance(newTarget.rowNode, m.source, newDropPosition.toLowerCase())
+						&& !this._isParentChildDrop(m.source, newTarget.rowNode)){
+						m.canDrop(true);
+					}else{
+						m.canDrop(false);
+					}
+				}
+
+				this.targetAnchor = newTarget;
+				this.dropPosition = newDropPosition;
+			}
+		},
+
+		onMouseMove: function(e){
+			// summary:
+			//		Called for any onmousemove/ontouchmove events over the Tree
+			// e: Event
+			//		onmousemouse/ontouchmove event
+			// tags:
+			//		private
+			if(this.isDragging && this.targetState == "Disabled"){
+				return;
+			}
+			this.inherited(arguments);
+			var m = DNDManager.manager();
+			if(this.isDragging){
+				this._onDragMouse(e);
+			}else{
+				if(this.mouseDown && this.isSource &&
+					(Math.abs(e.pageX - this._lastX) >= this.dragThreshold || Math.abs(e.pageY - this._lastY) >= this.dragThreshold)){
+					var nodes = this.getSelectedTreeNodes();
+					if(nodes.length){
+						if(nodes.length > 1){
+							//filter out all selected items which has one of their ancestor selected as well
+							var seen = this.selection, i = 0, r = [], n, p;
+							nextitem: while((n = nodes[i++])){
+								for(p = n.getParent(); p && p !== this.tree; p = p.getParent()){
+									if(seen[p.id]){ //parent is already selected, skip this node
+										continue nextitem;
+									}
 								}
+								//this node does not have any ancestors selected, add it
+								r.push(n);
 							}
-							//this node does not have any ancestors selected, add it
-							r.push(n);
+							nodes = r;
 						}
-						nodes = r;
+						nodes = array.map(nodes, function(n){
+							return n.domNode
+						});
+						m.startDrag(this, nodes, this.copyState(connect.isCopyKey(e)));
+						this._onDragMouse(e, true);	// because this may be the only mousemove event we get before the drop
 					}
-					nodes = array.map(nodes, function(n){return n.domNode});
-					m.startDrag(this, nodes, this.copyState(connect.isCopyKey(e)));
 				}
 			}
-		}
-	},
-
-	onMouseDown: function(e){
-		// summary:
-		//		Event processor for onmousedown/ontouchstart
-		// e: Event
-		//		onmousedown/ontouchend event
-		// tags:
-		//		private
-		this.mouseDown = true;
-		this.mouseButton = e.button;
-		this._lastX = e.pageX;
-		this._lastY = e.pageY;
-		this.inherited(arguments);
-	},
-
-	onMouseUp: function(e){
-		// summary:
-		//		Event processor for onmouseup/ontouchend
-		// e: Event
-		//		onmouseup/ontouchend event
-		// tags:
-		//		private
-		if(this.mouseDown){
-			this.mouseDown = false;
+		},
+
+		onMouseDown: function(e){
+			// summary:
+			//		Event processor for onmousedown/ontouchstart
+			// e: Event
+			//		onmousedown/ontouchend event
+			// tags:
+			//		private
+			this.mouseDown = true;
+			this.mouseButton = e.button;
+			this._lastX = e.pageX;
+			this._lastY = e.pageY;
 			this.inherited(arguments);
-		}
-	},
+		},
+
+		onMouseUp: function(e){
+			// summary:
+			//		Event processor for onmouseup/ontouchend
+			// e: Event
+			//		onmouseup/ontouchend event
+			// tags:
+			//		private
+			if(this.mouseDown){
+				this.mouseDown = false;
+				this.inherited(arguments);
+			}
+		},
 
-	onMouseOut: function(){
-		// summary:
-		//		Event processor for when mouse is moved away from a TreeNode
-		// tags:
-		//		private
-		this.inherited(arguments);
-		this._unmarkTargetAnchor();
-	},
-
-	checkItemAcceptance: function(/*===== target, source, position =====*/){
-		// summary:
-		//		Stub function to be overridden if one wants to check for the ability to drop at the node/item level
-		// description:
-		//		In the base case, this is called to check if target can become a child of source.
-		//		When betweenThreshold is set, position="before" or "after" means that we
-		//		are asking if the source node can be dropped before/after the target node.
-		// target: DOMNode
-		//		The dijitTreeRoot DOM node inside of the TreeNode that we are dropping on to
-		//		Use dijit.getEnclosingWidget(target) to get the TreeNode.
-		// source: dijit.tree.dndSource
-		//		The (set of) nodes we are dropping
-		// position: String
-		//		"over", "before", or "after"
-		// tags:
-		//		extension
-		return true;
-	},
-
-	// topic event processors
-	onDndSourceOver: function(source){
-		// summary:
-		//		Topic event processor for /dnd/source/over, called when detected a current source.
-		// source: Object
-		//		The dijit.tree.dndSource / dojo.dnd.Source which has the mouse over it
-		// tags:
-		//		private
-		if(this != source){
-			this.mouseDown = false;
+		onMouseOut: function(){
+			// summary:
+			//		Event processor for when mouse is moved away from a TreeNode
+			// tags:
+			//		private
+			this.inherited(arguments);
 			this._unmarkTargetAnchor();
-		}else if(this.isDragging){
-			var m = DNDManager.manager();
-			m.canDrop(false);
-		}
-	},
-	onDndStart: function(source, nodes, copy){
-		// summary:
-		//		Topic event processor for /dnd/start, called to initiate the DnD operation
-		// source: Object
-		//		The dijit.tree.dndSource / dojo.dnd.Source which is providing the items
-		// nodes: DomNode[]
-		//		The list of transferred items, dndTreeNode nodes if dragging from a Tree
-		// copy: Boolean
-		//		Copy items, if true, move items otherwise
-		// tags:
-		//		private
-
-		if(this.isSource){
-			this._changeState("Source", this == source ? (copy ? "Copied" : "Moved") : "");
-		}
-		var accepted = this.checkAcceptance(source, nodes);
-
-		this._changeState("Target", accepted ? "" : "Disabled");
-
-		if(this == source){
-			DNDManager.manager().overSource(this);
-		}
-
-		this.isDragging = true;
-	},
-
-	itemCreator: function(nodes /*===== , target, source =====*/){
-		// summary:
-		//		Returns objects passed to `Tree.model.newItem()` based on DnD nodes
-		//		dropped onto the tree.   Developer must override this method to enable
-		// 		dropping from external sources onto this Tree, unless the Tree.model's items
-		//		happen to look like {id: 123, name: "Apple" } with no other attributes.
-		// description:
-		//		For each node in nodes[], which came from source, create a hash of name/value
-		//		pairs to be passed to Tree.model.newItem().  Returns array of those hashes.
-		// nodes: DomNode[]
-		// target: DomNode
-		// source: dojo.dnd.Source
-		// returns: Object[]
-		//		Array of name/value hashes for each new item to be added to the Tree, like:
-		// |	[
-		// |		{ id: 123, label: "apple", foo: "bar" },
-		// |		{ id: 456, label: "pear", zaz: "bam" }
-		// |	]
-		// tags:
-		//		extension
-
-		// TODO: for 2.0 refactor so itemCreator() is called once per drag node, and
-		// make signature itemCreator(sourceItem, node, target) (or similar).
-
-		return array.map(nodes, function(node){
-			return {
-				"id": node.id,
-				"name": node.textContent || node.innerText || ""
-			};
-		}); // Object[]
-	},
-
-	onDndDrop: function(source, nodes, copy){
-		// summary:
-		//		Topic event processor for /dnd/drop, called to finish the DnD operation.
-		// description:
-		//		Updates data store items according to where node was dragged from and dropped
-		//		to.   The tree will then respond to those data store updates and redraw itself.
-		// source: Object
-		//		The dijit.tree.dndSource / dojo.dnd.Source which is providing the items
-		// nodes: DomNode[]
-		//		The list of transferred items, dndTreeNode nodes if dragging from a Tree
-		// copy: Boolean
-		//		Copy items, if true, move items otherwise
-		// tags:
-		//		protected
-		if(this.containerState == "Over"){
-			var tree = this.tree,
-				model = tree.model,
-				target = this.targetAnchor;
+		},
+
+		checkItemAcceptance: function(/*===== target, source, position =====*/){
+			// summary:
+			//		Stub function to be overridden if one wants to check for the ability to drop at the node/item level
+			// description:
+			//		In the base case, this is called to check if target can become a child of source.
+			//		When betweenThreshold is set, position="before" or "after" means that we
+			//		are asking if the source node can be dropped before/after the target node.
+			// target: DOMNode
+			//		The dijitTreeRoot DOM node inside of the TreeNode that we are dropping on to
+			//		Use dijit.getEnclosingWidget(target) to get the TreeNode.
+			// source: dijit/tree/dndSource
+			//		The (set of) nodes we are dropping
+			// position: String
+			//		"over", "before", or "after"
+			// tags:
+			//		extension
+			return true;
+		},
+
+		// topic event processors
+		onDndSourceOver: function(source){
+			// summary:
+			//		Topic event processor for /dnd/source/over, called when detected a current source.
+			// source: Object
+			//		The dijit/tree/dndSource / dojo/dnd/Source which has the mouse over it
+			// tags:
+			//		private
+			if(this != source){
+				this.mouseDown = false;
+				this._unmarkTargetAnchor();
+			}else if(this.isDragging){
+				var m = DNDManager.manager();
+				m.canDrop(false);
+			}
+		},
+		onDndStart: function(source, nodes, copy){
+			// summary:
+			//		Topic event processor for /dnd/start, called to initiate the DnD operation
+			// source: Object
+			//		The dijit/tree/dndSource / dojo/dnd/Source which is providing the items
+			// nodes: DomNode[]
+			//		The list of transferred items, dndTreeNode nodes if dragging from a Tree
+			// copy: Boolean
+			//		Copy items, if true, move items otherwise
+			// tags:
+			//		private
+
+			if(this.isSource){
+				this._changeState("Source", this == source ? (copy ? "Copied" : "Moved") : "");
+			}
+			var accepted = this.checkAcceptance(source, nodes);
 
-			this.isDragging = false;
+			this._changeState("Target", accepted ? "" : "Disabled");
 
-			// Compute the new parent item
-			var newParentItem;
-			var insertIndex;
-			newParentItem = (target && target.item) || tree.item;
-			if(this.dropPosition == "Before" || this.dropPosition == "After"){
-				// TODO: if there is no parent item then disallow the drop.
-				// Actually this should be checked during onMouseMove too, to make the drag icon red.
-				newParentItem = (target.getParent() && target.getParent().item) || tree.item;
-				// Compute the insert index for reordering
-				insertIndex = target.getIndexInParent();
-				if(this.dropPosition == "After"){
-					insertIndex = target.getIndexInParent() + 1;
-				}
-			}else{
-				newParentItem = (target && target.item) || tree.item;
+			if(this == source){
+				DNDManager.manager().overSource(this);
 			}
 
-			// If necessary, use this variable to hold array of hashes to pass to model.newItem()
-			// (one entry in the array for each dragged node).
-			var newItemsParams;
-
-			array.forEach(nodes, function(node, idx){
-				// dojo.dnd.Item representing the thing being dropped.
-				// Don't confuse the use of item here (meaning a DnD item) with the
-				// uses below where item means dojo.data item.
-				var sourceItem = source.getItem(node.id);
-
-				// Information that's available if the source is another Tree
-				// (possibly but not necessarily this tree, possibly but not
-				// necessarily the same model as this Tree)
-				if(array.indexOf(sourceItem.type, "treeNode") != -1){
-					var childTreeNode = sourceItem.data,
-						childItem = childTreeNode.item,
-						oldParentItem = childTreeNode.getParent().item;
+			this.isDragging = true;
+		},
+
+		itemCreator: function(nodes /*===== , target, source =====*/){
+			// summary:
+			//		Returns objects passed to `Tree.model.newItem()` based on DnD nodes
+			//		dropped onto the tree.   Developer must override this method to enable
+			//		dropping from external sources onto this Tree, unless the Tree.model's items
+			//		happen to look like {id: 123, name: "Apple" } with no other attributes.
+			// description:
+			//		For each node in nodes[], which came from source, create a hash of name/value
+			//		pairs to be passed to Tree.model.newItem().  Returns array of those hashes.
+			// nodes: DomNode[]
+			// target: DomNode
+			// source: dojo/dnd/Source
+			// returns: __Item[]
+			//		Array of name/value hashes for each new item to be added to the Tree
+			// tags:
+			//		extension
+
+			// TODO: for 2.0 refactor so itemCreator() is called once per drag node, and
+			// make signature itemCreator(sourceItem, node, target) (or similar).
+
+			return array.map(nodes, function(node){
+				return {
+					"id": node.id,
+					"name": node.textContent || node.innerText || ""
+				};
+			}); // Object[]
+		},
+
+		onDndDrop: function(source, nodes, copy){
+			// summary:
+			//		Topic event processor for /dnd/drop, called to finish the DnD operation.
+			// description:
+			//		Updates data store items according to where node was dragged from and dropped
+			//		to.   The tree will then respond to those data store updates and redraw itself.
+			// source: Object
+			//		The dijit/tree/dndSource / dojo/dnd/Source which is providing the items
+			// nodes: DomNode[]
+			//		The list of transferred items, dndTreeNode nodes if dragging from a Tree
+			// copy: Boolean
+			//		Copy items, if true, move items otherwise
+			// tags:
+			//		protected
+			if(this.containerState == "Over"){
+				var tree = this.tree,
+					model = tree.model,
+					target = this.targetAnchor;
+
+				this.isDragging = false;
+
+				// Compute the new parent item
+				var newParentItem;
+				var insertIndex;
+				var before;		// drop source before (aka previous sibling) of target
+				newParentItem = (target && target.item) || tree.item;
+				if(this.dropPosition == "Before" || this.dropPosition == "After"){
+					// TODO: if there is no parent item then disallow the drop.
+					// Actually this should be checked during onMouseMove too, to make the drag icon red.
+					newParentItem = (target.getParent() && target.getParent().item) || tree.item;
+					// Compute the insert index for reordering
+					insertIndex = target.getIndexInParent();
+					if(this.dropPosition == "After"){
+						insertIndex = target.getIndexInParent() + 1;
+						before = target.getNextSibling() && target.getNextSibling().item;
+					}else{
+						before = target.item;
+					}
+				}else{
+					newParentItem = (target && target.item) || tree.item;
 				}
 
-				if(source == this){
-					// This is a node from my own tree, and we are moving it, not copying.
-					// Remove item from old parent's children attribute.
-					// TODO: dijit.tree.dndSelector should implement deleteSelectedNodes()
-					// and this code should go there.
+				// If necessary, use this variable to hold array of hashes to pass to model.newItem()
+				// (one entry in the array for each dragged node).
+				var newItemsParams;
+
+				array.forEach(nodes, function(node, idx){
+					// dojo/dnd/Item representing the thing being dropped.
+					// Don't confuse the use of item here (meaning a DnD item) with the
+					// uses below where item means dojo.data item.
+					var sourceItem = source.getItem(node.id);
+
+					// Information that's available if the source is another Tree
+					// (possibly but not necessarily this tree, possibly but not
+					// necessarily the same model as this Tree)
+					if(array.indexOf(sourceItem.type, "treeNode") != -1){
+						var childTreeNode = sourceItem.data,
+							childItem = childTreeNode.item,
+							oldParentItem = childTreeNode.getParent().item;
+					}
+
+					if(source == this){
+						// This is a node from my own tree, and we are moving it, not copying.
+						// Remove item from old parent's children attribute.
+						// TODO: dijit/tree/dndSelector should implement deleteSelectedNodes()
+						// and this code should go there.
 
-					if(typeof insertIndex == "number"){
-						if(newParentItem == oldParentItem && childTreeNode.getIndexInParent() < insertIndex){
-							insertIndex -= 1;
+						if(typeof insertIndex == "number"){
+							if(newParentItem == oldParentItem && childTreeNode.getIndexInParent() < insertIndex){
+								insertIndex -= 1;
+							}
+						}
+						model.pasteItem(childItem, oldParentItem, newParentItem, copy, insertIndex, before);
+					}else if(model.isItem(childItem)){
+						// Item from same model
+						// (maybe we should only do this branch if the source is a tree?)
+						model.pasteItem(childItem, oldParentItem, newParentItem, copy, insertIndex, before);
+					}else{
+						// Get the hash to pass to model.newItem().  A single call to
+						// itemCreator() returns an array of hashes, one for each drag source node.
+						if(!newItemsParams){
+							newItemsParams = this.itemCreator(nodes, target.rowNode, source);
 						}
-					}
-					model.pasteItem(childItem, oldParentItem, newParentItem, copy, insertIndex);
-				}else if(model.isItem(childItem)){
-					// Item from same model
-					// (maybe we should only do this branch if the source is a tree?)
-					model.pasteItem(childItem, oldParentItem, newParentItem, copy, insertIndex);
-				}else{
-					// Get the hash to pass to model.newItem().  A single call to
-					// itemCreator() returns an array of hashes, one for each drag source node.
-					if(!newItemsParams){
-						newItemsParams = this.itemCreator(nodes, target.rowNode, source);
-					}
 
-					// Create new item in the tree, based on the drag source.
-					model.newItem(newItemsParams[idx], newParentItem, insertIndex);
-				}
-			}, this);
+						// Create new item in the tree, based on the drag source.
+						model.newItem(newItemsParams[idx], newParentItem, insertIndex, before);
+					}
+				}, this);
 
-			// Expand the target node (if it's currently collapsed) so the user can see
-			// where their node was dropped.   In particular since that node is still selected.
-			this.tree._expandNode(target);
-		}
-		this.onDndCancel();
-	},
+				// Expand the target node (if it's currently collapsed) so the user can see
+				// where their node was dropped.   In particular since that node is still selected.
+				this.tree._expandNode(target);
+			}
+			this.onDndCancel();
+		},
+
+		onDndCancel: function(){
+			// summary:
+			//		Topic event processor for /dnd/cancel, called to cancel the DnD operation
+			// tags:
+			//		private
+			this._unmarkTargetAnchor();
+			this.isDragging = false;
+			this.mouseDown = false;
+			delete this.mouseButton;
+			this._changeState("Source", "");
+			this._changeState("Target", "");
+		},
+
+		// When focus moves in/out of the entire Tree
+		onOverEvent: function(){
+			// summary:
+			//		This method is called when mouse is moved over our container (like onmouseenter)
+			// tags:
+			//		private
+			this.inherited(arguments);
+			DNDManager.manager().overSource(this);
+		},
+		onOutEvent: function(){
+			// summary:
+			//		This method is called when mouse is moved out of our container (like onmouseleave)
+			// tags:
+			//		private
+			this._unmarkTargetAnchor();
+			var m = DNDManager.manager();
+			if(this.isDragging){
+				m.canDrop(false);
+			}
+			m.outSource(this);
 
-	onDndCancel: function(){
-		// summary:
-		//		Topic event processor for /dnd/cancel, called to cancel the DnD operation
-		// tags:
-		//		private
-		this._unmarkTargetAnchor();
-		this.isDragging = false;
-		this.mouseDown = false;
-		delete this.mouseButton;
-		this._changeState("Source", "");
-		this._changeState("Target", "");
-	},
-
-	// When focus moves in/out of the entire Tree
-	onOverEvent: function(){
-		// summary:
-		//		This method is called when mouse is moved over our container (like onmouseenter)
-		// tags:
-		//		private
-		this.inherited(arguments);
-		DNDManager.manager().overSource(this);
-	},
-	onOutEvent: function(){
-		// summary:
-		//		This method is called when mouse is moved out of our container (like onmouseleave)
-		// tags:
-		//		private
-		this._unmarkTargetAnchor();
-		var m = DNDManager.manager();
-		if(this.isDragging){
-			m.canDrop(false);
-		}
-		m.outSource(this);
+			this.inherited(arguments);
+		},
+
+		_isParentChildDrop: function(source, targetRow){
+			// summary:
+			//		Checks whether the dragged items are parent rows in the tree which are being
+			//		dragged into their own children.
+			//
+			// source:
+			//		The DragSource object.
+			//
+			// targetRow:
+			//		The tree row onto which the dragged nodes are being dropped.
+			//
+			// tags:
+			//		private
+
+			// If the dragged object is not coming from the tree this widget belongs to,
+			// it cannot be invalid.
+			if(!source.tree || source.tree != this.tree){
+				return false;
+			}
 
-		this.inherited(arguments);
-	},
 
-	_isParentChildDrop: function(source, targetRow){
-		// summary:
-		//		Checks whether the dragged items are parent rows in the tree which are being
-		//		dragged into their own children.
-		//
-		// source:
-		//		The DragSource object.
-		//
-		// targetRow:
-		//		The tree row onto which the dragged nodes are being dropped.
-		//
-		// tags:
-		//		private
-
-		// If the dragged object is not coming from the tree this widget belongs to,
-		// it cannot be invalid.
-		if(!source.tree || source.tree != this.tree){
-			return false;
-		}
+			var root = source.tree.domNode;
+			var ids = source.selection;
 
+			var node = targetRow.parentNode;
 
-		var root = source.tree.domNode;
-		var ids = source.selection;
+			// Iterate up the DOM hierarchy from the target drop row,
+			// checking of any of the dragged nodes have the same ID.
+			while(node != root && !ids[node.id]){
+				node = node.parentNode;
+			}
 
-		var node = targetRow.parentNode;
+			return node.id && ids[node.id];
+		},
 
-		// Iterate up the DOM hierarchy from the target drop row,
-		// checking of any of the dragged nodes have the same ID.
-		while(node != root && !ids[node.id]){
-			node = node.parentNode;
+		_unmarkTargetAnchor: function(){
+			// summary:
+			//		Removes hover class of the current target anchor
+			// tags:
+			//		private
+			if(!this.targetAnchor){
+				return;
+			}
+			this._removeItemClass(this.targetAnchor.rowNode, this.dropPosition);
+			this.targetAnchor = null;
+			this.targetBox = null;
+			this.dropPosition = null;
+		},
+
+		_markDndStatus: function(copy){
+			// summary:
+			//		Changes source's state based on "copy" status
+			this._changeState("Source", copy ? "Copied" : "Moved");
 		}
+	});
 
-		return node.id && ids[node.id];
-	},
-
-	_unmarkTargetAnchor: function(){
-		// summary:
-		//		Removes hover class of the current target anchor
-		// tags:
-		//		private
-		if(!this.targetAnchor){ return; }
-		this._removeItemClass(this.targetAnchor.rowNode, this.dropPosition);
-		this.targetAnchor = null;
-		this.targetBox = null;
-		this.dropPosition = null;
-	},
-
-	_markDndStatus: function(copy){
-		// summary:
-		//		Changes source's state based on "copy" status
-		this._changeState("Source", copy ? "Copied" : "Moved");
-	}
-});
+	/*=====
+	dndSource.__Item = __Item;
+	=====*/
 
+	return dndSource;
 });
diff --git a/dijit/tree/model.js b/dijit/tree/model.js
index 9345825..ac488fb 100644
--- a/dijit/tree/model.js
+++ b/dijit/tree/model.js
@@ -1,142 +1,135 @@
+define(["dojo/_base/declare"], function(declare){
 
-/*=====
-declare(
-	"dijit.tree.model",
-	null,
-{
-	// summary:
-	//		Contract for any data provider object for the tree.
-	// description:
-	//		Tree passes in values to the constructor to specify the callbacks.
-	//		"item" is typically a dojo.data.Item but it's just a black box so
-	//		it could be anything.
-	//
-	//		This (like `dojo.data.api.Read`) is just documentation, and not meant to be used.
-
-	destroy: function(){
+	return declare("dijit.tree.model", null, {
 		// summary:
-		//		Destroys this object, releasing connections to the store
-		// tags:
-		//		extension
-	},
-
-	// =======================================================================
-	// Methods for traversing hierarchy
-
-	getRoot: function(onItem){
-		// summary:
-		//		Calls onItem with the root item for the tree, possibly a fabricated item.
-		//		Throws exception on error.
-		// tags:
-		//		extension
-	},
-
-	mayHaveChildren: function(item){
-		// summary:
-		//		Tells if an item has or may have children.  Implementing logic here
-		//		avoids showing +/- expando icon for nodes that we know don't have children.
-		//		(For efficiency reasons we may not want to check if an element actually
-		//		has children until user clicks the expando node)
-		// item: dojo.data.Item
-		// tags:
-		//		extension
-	},
-
-	getChildren: function(parentItem, onComplete){
-		// summary:
-		// 		Calls onComplete() with array of child items of given parent item, all loaded.
-		//		Throws exception on error.
-		// parentItem: dojo.data.Item
-		// onComplete: function(items)
-		// tags:
-		//		extension
-	},
-
-	// =======================================================================
-	// Inspecting items
-
-	isItem: function(something){
-		// summary:
-		//		Returns true if *something* is an item and came from this model instance.
-		//		Returns false if *something* is a literal, an item from another model instance,
-		//		or is any object other than an item.
-		// tags:
-		//		extension
-	},
-
-	fetchItemByIdentity: function(keywordArgs){
-		// summary:
-		//		Given the identity of an item, this method returns the item that has
-		//		that identity through the onItem callback.  Conforming implementations
-		//		should return null if there is no item with the given identity.
-		//		Implementations of fetchItemByIdentity() may sometimes return an item
-		//		from a local cache and may sometimes fetch an item from a remote server.
-		// tags:
-		//		extension
-	},
-
-	getIdentity: function(item){
-		// summary:
-		//		Returns identity for an item
-		// tags:
-		//		extension
-	},
-
-	getLabel: function(item){
-		// summary:
-		//		Get the label for an item
-		// tags:
-		//		extension
-	},
-
-	// =======================================================================
-	// Write interface
-
-	newItem: function(args, parent, insertIndex){
-		// summary:
-		//		Creates a new item.   See `dojo.data.api.Write` for details on args.
-		// args: dojo.dnd.Item
-		// parent: Item
-		// insertIndex: int?
-		// tags:
-		//		extension
-	},
-
-	pasteItem: function(childItem, oldParentItem, newParentItem, bCopy){
-		// summary:
-		//		Move or copy an item from one parent item to another.
-		//		Used in drag & drop.
-		//		If oldParentItem is specified and bCopy is false, childItem is removed from oldParentItem.
-		//		If newParentItem is specified, childItem is attached to newParentItem.
-		// childItem: Item
-		// oldParentItem: Item
-		// newParentItem: Item
-		// bCopy: Boolean
-		// tags:
-		//		extension
-	},
-
-	// =======================================================================
-	// Callbacks
-
-	onChange: function(item){
-		// summary:
-		//		Callback whenever an item has changed, so that Tree
-		//		can update the label, icon, etc.   Note that changes
-		//		to an item's children or parent(s) will trigger an
-		//		onChildrenChange() so you can ignore those changes here.
-		// item: dojo.data.Item
-		// tags:
-		//		callback
-	},
-
-	onChildrenChange: function(parent, newChildrenList){
-		// summary:
-		//		Callback to do notifications about new, updated, or deleted items.
-		// parent: dojo.data.Item
-		// newChildrenList: dojo.data.Item[]
-		// tags:
-		//		callback
-	}
-});
-=====*/
\ No newline at end of file
+		//		Contract for any data provider object for the tree.
+		// description:
+		//		Tree passes in values to the constructor to specify the callbacks.
+		//		"item" is typically a dojo/data/Item but it's just a black box so
+		//		it could be anything.
+		//
+		//		This (like `dojo/data/api/Read`) is just documentation, and not meant to be used.
+
+		destroy: function(){
+			// summary:
+			//		Destroys this object, releasing connections to the store
+			// tags:
+			//		extension
+		},
+
+		// =======================================================================
+		// Methods for traversing hierarchy
+
+		getRoot: function(onItem){
+			// summary:
+			//		Calls onItem with the root item for the tree, possibly a fabricated item.
+			//		Throws exception on error.
+			// tags:
+			//		extension
+		},
+
+		mayHaveChildren: function(item){
+			// summary:
+			//		Tells if an item has or may have children.  Implementing logic here
+			//		avoids showing +/- expando icon for nodes that we know don't have children.
+			//		(For efficiency reasons we may not want to check if an element actually
+			//		has children until user clicks the expando node)
+			// item: dojo/data/Item
+			// tags:
+			//		extension
+		},
+
+		getChildren: function(parentItem, onComplete){
+			// summary:
+			//		Calls onComplete() with array of child items of given parent item, all loaded.
+			//		Throws exception on error.
+			// parentItem: dojo/data/Item
+			// onComplete: function(items)
+			// tags:
+			//		extension
+		},
+
+		// =======================================================================
+		// Inspecting items
+
+		isItem: function(something){
+			// summary:
+			//		Returns true if *something* is an item and came from this model instance.
+			//		Returns false if *something* is a literal, an item from another model instance,
+			//		or is any object other than an item.
+			// tags:
+			//		extension
+		},
+
+		getIdentity: function(item){
+			// summary:
+			//		Returns identity for an item
+			// tags:
+			//		extension
+		},
+
+		getLabel: function(item){
+			// summary:
+			//		Get the label for an item
+			// tags:
+			//		extension
+		},
+
+		// =======================================================================
+		// Write interface
+
+		newItem: function(args, parent, insertIndex, before){
+			// summary:
+			//		Creates a new item.   See `dojo/data/api/Write` for details on args.
+			// args: dijit/tree/dndSource.__Item
+			// parent: Item
+			// insertIndex: int?
+			//		Allows to insert the new item as the n'th child of `parent`.
+			// before: Item?
+			//		Insert the new item as the previous sibling of this item.  `before` must be a child of `parent`.
+			// tags:
+			//		extension
+		},
+
+		pasteItem: function(childItem, oldParentItem, newParentItem, bCopy, insertIndex, before){
+			// summary:
+			//		Move or copy an item from one parent item to another.
+			//		Used in drag & drop.
+			//		If oldParentItem is specified and bCopy is false, childItem is removed from oldParentItem.
+			//		If newParentItem is specified, childItem is attached to newParentItem.
+			// childItem: Item
+			// oldParentItem: Item
+			// newParentItem: Item
+			// bCopy: Boolean
+			// insertIndex: int?
+			//		Allows to insert the new item as the n'th child of `parent`.
+			// before: Item?
+			//		Insert the new item as the previous sibling of this item.  `before` must be a child of `parent`.
+			// tags:
+			//		extension
+		},
+
+		// =======================================================================
+		// Callbacks
+
+		onChange: function(item){
+			// summary:
+			//		Callback whenever an item has changed, so that Tree
+			//		can update the label, icon, etc.   Note that changes
+			//		to an item's children or parent(s) will trigger an
+			//		onChildrenChange() so you can ignore those changes here.
+			// item: dojo/data/Item
+			// tags:
+			//		callback
+		},
+
+		onChildrenChange: function(parent, newChildrenList){
+			// summary:
+			//		Callback to do notifications about new, updated, or deleted items.
+			// parent: dojo/data/Item
+			// newChildrenList: dojo/data/Item[]
+			// tags:
+			//		callback
+		}
+	});
+});
\ No newline at end of file
diff --git a/dijit/typematic.js b/dijit/typematic.js
index 504ba26..09a159a 100644
--- a/dijit/typematic.js
+++ b/dijit/typematic.js
@@ -1,206 +1,211 @@
 define([
 	"dojo/_base/array", // array.forEach
-	"dojo/_base/connect", // connect.connect
-	"dojo/_base/event", // event.stop
-	"dojo/_base/kernel", // kernel.deprecated
+	"dojo/_base/connect", // connect._keyPress
 	"dojo/_base/lang", // lang.mixin, lang.hitch
 	"dojo/on",
-	"dojo/_base/sniff", // has("ie")
-	"."		// setting dijit.typematic global
-], function(array, connect, event, kernel, lang, on, has, dijit){
+	"dojo/sniff", // has("ie")
+	"./main"        // setting dijit.typematic global
+], function(array, connect, lang, on, has, dijit){
 
-// module:
-//		dijit/typematic
-// summary:
-//		These functions are used to repetitively call a user specified callback
-//		method when a specific key or mouse click over a specific DOM node is
-//		held down for a specific amount of time.
-//		Only 1 such event is allowed to occur on the browser page at 1 time.
+	// module:
+	//		dijit/typematic
 
-var typematic = (dijit.typematic = {
-	// summary:
-	//		These functions are used to repetitively call a user specified callback
-	//		method when a specific key or mouse click over a specific DOM node is
-	//		held down for a specific amount of time.
-	//		Only 1 such event is allowed to occur on the browser page at 1 time.
-
-	_fireEventAndReload: function(){
-		this._timer = null;
-		this._callback(++this._count, this._node, this._evt);
-
-		// Schedule next event, timer is at most minDelay (default 10ms) to avoid
-		// browser overload (particularly avoiding starving DOH robot so it never gets to send a mouseup)
-		this._currentTimeout = Math.max(
-			this._currentTimeout < 0 ? this._initialDelay :
-				(this._subsequentDelay > 1 ? this._subsequentDelay : Math.round(this._currentTimeout * this._subsequentDelay)),
-			this._minDelay);
-		this._timer = setTimeout(lang.hitch(this, "_fireEventAndReload"), this._currentTimeout);
-	},
-
-	trigger: function(/*Event*/ evt, /*Object*/ _this, /*DOMNode*/ node, /*Function*/ callback, /*Object*/ obj, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+	var typematic = (dijit.typematic = {
 		// summary:
-		//		Start a timed, repeating callback sequence.
-		//		If already started, the function call is ignored.
-		//		This method is not normally called by the user but can be
-		//		when the normal listener code is insufficient.
-		// evt:
-		//		key or mouse event object to pass to the user callback
-		// _this:
-		//		pointer to the user's widget space.
-		// node:
-		//		the DOM node object to pass the the callback function
-		// callback:
-		//		function to call until the sequence is stopped called with 3 parameters:
-		// count:
-		//		integer representing number of repeated calls (0..n) with -1 indicating the iteration has stopped
-		// node:
-		//		the DOM node object passed in
-		// evt:
-		//		key or mouse event object
-		// obj:
-		//		user space object used to uniquely identify each typematic sequence
-		// subsequentDelay (optional):
-		//		if > 1, the number of milliseconds until the 3->n events occur
-		//		or else the fractional time multiplier for the next event's delay, default=0.9
-		// initialDelay (optional):
-		//		the number of milliseconds until the 2nd event occurs, default=500ms
-		// minDelay (optional):
-		//		the maximum delay in milliseconds for event to fire, default=10ms
-		if(obj != this._obj){
-			this.stop();
-			this._initialDelay = initialDelay || 500;
-			this._subsequentDelay = subsequentDelay || 0.90;
-			this._minDelay = minDelay || 10;
-			this._obj = obj;
-			this._evt = evt;
-			this._node = node;
-			this._currentTimeout = -1;
-			this._count = -1;
-			this._callback = lang.hitch(_this, callback);
-			this._fireEventAndReload();
-			this._evt = lang.mixin({faux: true}, evt);
-		}
-	},
+		//		These functions are used to repetitively call a user specified callback
+		//		method when a specific key or mouse click over a specific DOM node is
+		//		held down for a specific amount of time.
+		//		Only 1 such event is allowed to occur on the browser page at 1 time.
 
-	stop: function(){
-		// summary:
-		//		Stop an ongoing timed, repeating callback sequence.
-		if(this._timer){
-			clearTimeout(this._timer);
+		_fireEventAndReload: function(){
 			this._timer = null;
-		}
-		if(this._obj){
-			this._callback(-1, this._node, this._evt);
-			this._obj = null;
-		}
-	},
+			this._callback(++this._count, this._node, this._evt);
 
-	addKeyListener: function(/*DOMNode*/ node, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
-		// summary:
-		//		Start listening for a specific typematic key.
-		//		See also the trigger method for other parameters.
-		// keyObject:
-		//		an object defining the key to listen for:
-		// 		charOrCode:
-		//			the printable character (string) or keyCode (number) to listen for.
-		// 		keyCode:
-		//			(deprecated - use charOrCode) the keyCode (number) to listen for (implies charCode = 0).
-		// 		charCode:
-		//			(deprecated - use charOrCode) the charCode (number) to listen for.
-		// 		ctrlKey:
-		//			desired ctrl key state to initiate the callback sequence:
-		//			- pressed (true)
-		//			- released (false)
-		//			- either (unspecified)
-		// 		altKey:
-		//			same as ctrlKey but for the alt key
-		// 		shiftKey:
-		//			same as ctrlKey but for the shift key
-		// returns:
-		//		a connection handle
-		if(keyObject.keyCode){
-			keyObject.charOrCode = keyObject.keyCode;
-			kernel.deprecated("keyCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
-		}else if(keyObject.charCode){
-			keyObject.charOrCode = String.fromCharCode(keyObject.charCode);
-			kernel.deprecated("charCode attribute parameter for dijit.typematic.addKeyListener is deprecated. Use charOrCode instead.", "", "2.0");
-		}
-		var handles = [
-			on(node, connect._keypress, lang.hitch(this, function(evt){
-				if(evt.charOrCode == keyObject.charOrCode &&
-				(keyObject.ctrlKey === undefined || keyObject.ctrlKey == evt.ctrlKey) &&
-				(keyObject.altKey === undefined || keyObject.altKey == evt.altKey) &&
-				(keyObject.metaKey === undefined || keyObject.metaKey == (evt.metaKey || false)) && // IE doesn't even set metaKey
-				(keyObject.shiftKey === undefined || keyObject.shiftKey == evt.shiftKey)){
-					event.stop(evt);
-					typematic.trigger(evt, _this, node, callback, keyObject, subsequentDelay, initialDelay, minDelay);
-				}else if(typematic._obj == keyObject){
-					typematic.stop();
-				}
-			})),
-			on(node, "keyup", lang.hitch(this, function(){
-				if(typematic._obj == keyObject){
-					typematic.stop();
-				}
-			}))
-		];
-		return { remove: function(){ array.forEach(handles, function(h){ h.remove(); }); } };
-	},
+			// Schedule next event, timer is at most minDelay (default 10ms) to avoid
+			// browser overload (particularly avoiding starving DOH robot so it never gets to send a mouseup)
+			this._currentTimeout = Math.max(
+				this._currentTimeout < 0 ? this._initialDelay :
+					(this._subsequentDelay > 1 ? this._subsequentDelay : Math.round(this._currentTimeout * this._subsequentDelay)),
+				this._minDelay);
+			this._timer = setTimeout(lang.hitch(this, "_fireEventAndReload"), this._currentTimeout);
+		},
 
-	addMouseListener: function(/*DOMNode*/ node, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
-		// summary:
-		//		Start listening for a typematic mouse click.
-		//		See the trigger method for other parameters.
-		// returns:
-		//		a connection handle
-		var handles =  [
-			on(node, "mousedown", lang.hitch(this, function(evt){
-				event.stop(evt);
-				typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
-			})),
-			on(node, "mouseup", lang.hitch(this, function(evt){
-				if(this._obj){
-					event.stop(evt);
-				}
-				typematic.stop();
-			})),
-			on(node, "mouseout", lang.hitch(this, function(evt){
-				event.stop(evt);
-				typematic.stop();
-			})),
-			on(node, "mousemove", lang.hitch(this, function(evt){
-				evt.preventDefault();
-			})),
-			on(node, "dblclick", lang.hitch(this, function(evt){
-				event.stop(evt);
-				if(has("ie")){
-					typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
-					setTimeout(lang.hitch(this, typematic.stop), 50);
+		trigger: function(/*Event*/ evt, /*Object*/ _this, /*DOMNode*/ node, /*Function*/ callback, /*Object*/ obj, /*Number?*/ subsequentDelay, /*Number?*/ initialDelay, /*Number?*/ minDelay){
+			// summary:
+			//		Start a timed, repeating callback sequence.
+			//		If already started, the function call is ignored.
+			//		This method is not normally called by the user but can be
+			//		when the normal listener code is insufficient.
+			// evt:
+			//		key or mouse event object to pass to the user callback
+			// _this:
+			//		pointer to the user's widget space.
+			// node:
+			//		the DOM node object to pass the the callback function
+			// callback:
+			//		function to call until the sequence is stopped called with 3 parameters:
+			// count:
+			//		integer representing number of repeated calls (0..n) with -1 indicating the iteration has stopped
+			// node:
+			//		the DOM node object passed in
+			// evt:
+			//		key or mouse event object
+			// obj:
+			//		user space object used to uniquely identify each typematic sequence
+			// subsequentDelay:
+			//		if > 1, the number of milliseconds until the 3->n events occur
+			//		or else the fractional time multiplier for the next event's delay, default=0.9
+			// initialDelay:
+			//		the number of milliseconds until the 2nd event occurs, default=500ms
+			// minDelay:
+			//		the maximum delay in milliseconds for event to fire, default=10ms
+			if(obj != this._obj){
+				this.stop();
+				this._initialDelay = initialDelay || 500;
+				this._subsequentDelay = subsequentDelay || 0.90;
+				this._minDelay = minDelay || 10;
+				this._obj = obj;
+				this._node = node;
+				this._currentTimeout = -1;
+				this._count = -1;
+				this._callback = lang.hitch(_this, callback);
+				this._evt = { faux: true };
+				for(var attr in evt){
+					if(attr != "layerX" && attr != "layerY"){ // prevent WebKit warnings
+						var v = evt[attr];
+						if(typeof v != "function" && typeof v != "undefined"){
+							this._evt[attr] = v
+						}
+					}
 				}
-			}))
-		];
-		return { remove: function(){ array.forEach(handles, function(h){ h.remove(); }); } };
-	},
+				this._fireEventAndReload();
+			}
+		},
 
-	addListener: function(/*Node*/ mouseNode, /*Node*/ keyNode, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
-		// summary:
-		//		Start listening for a specific typematic key and mouseclick.
-		//		This is a thin wrapper to addKeyListener and addMouseListener.
-		//		See the addMouseListener and addKeyListener methods for other parameters.
-		// mouseNode:
-		//		the DOM node object to listen on for mouse events.
-		// keyNode:
-		//		the DOM node object to listen on for key events.
-		// returns:
-		//		a connection handle
-		var handles = [
-			this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay, minDelay),
-			this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay, minDelay)
-		];
-		return { remove: function(){ array.forEach(handles, function(h){ h.remove(); }); } };
-	}
-});
+		stop: function(){
+			// summary:
+			//		Stop an ongoing timed, repeating callback sequence.
+			if(this._timer){
+				clearTimeout(this._timer);
+				this._timer = null;
+			}
+			if(this._obj){
+				this._callback(-1, this._node, this._evt);
+				this._obj = null;
+			}
+		},
+
+		addKeyListener: function(/*DOMNode*/ node, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+			// summary:
+			//		Start listening for a specific typematic key.
+			//		See also the trigger method for other parameters.
+			// keyObject:
+			//		an object defining the key to listen for:
+			//
+			//		- keyCode: the keyCode (number) to listen for, used for non-printable keys
+			//		- charCode: the charCode (number) to listen for, used for printable keys
+			//		- charOrCode: deprecated, use keyCode or charCode
+			//		- ctrlKey: desired ctrl key state to initiate the callback sequence:
+			//			- pressed (true)
+			//			- released (false)
+			//			- either (unspecified)
+			//		- altKey: same as ctrlKey but for the alt key
+			//		- shiftKey: same as ctrlKey but for the shift key
+			// returns:
+			//		a connection handle
+
+			// Setup keydown or keypress listener depending on whether keyCode or charCode was specified.
+			// If charOrCode is specified use deprecated connect._keypress synthetic event (remove for 2.0)
+			var type = "keyCode" in keyObject ? "keydown" : "charCode" in keyObject ? "keypress" : connect._keypress,
+				attr = "keyCode" in keyObject ? "keyCode" : "charCode" in keyObject ? "charCode" : "charOrCode";
 
-return typematic;
+			var handles = [
+				on(node, type, lang.hitch(this, function(evt){
+					if(evt[attr] == keyObject[attr] &&
+						(keyObject.ctrlKey === undefined || keyObject.ctrlKey == evt.ctrlKey) &&
+						(keyObject.altKey === undefined || keyObject.altKey == evt.altKey) &&
+						(keyObject.metaKey === undefined || keyObject.metaKey == (evt.metaKey || false)) && // IE doesn't even set metaKey
+						(keyObject.shiftKey === undefined || keyObject.shiftKey == evt.shiftKey)){
+						evt.stopPropagation();
+						evt.preventDefault();
+						typematic.trigger(evt, _this, node, callback, keyObject, subsequentDelay, initialDelay, minDelay);
+					}else if(typematic._obj == keyObject){
+						typematic.stop();
+					}
+				})),
+				on(node, "keyup", lang.hitch(this, function(){
+					if(typematic._obj == keyObject){
+						typematic.stop();
+					}
+				}))
+			];
+			return { remove: function(){
+				array.forEach(handles, function(h){
+					h.remove();
+				});
+			} };
+		},
+
+		addMouseListener: function(/*DOMNode*/ node, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+			// summary:
+			//		Start listening for a typematic mouse click.
+			//		See the trigger method for other parameters.
+			// returns:
+			//		a connection handle
+			var handles = [
+				on(node, "mousedown", lang.hitch(this, function(evt){
+					evt.preventDefault();
+					typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
+				})),
+				on(node, "mouseup", lang.hitch(this, function(evt){
+					if(this._obj){
+						evt.preventDefault();
+					}
+					typematic.stop();
+				})),
+				on(node, "mouseout", lang.hitch(this, function(evt){
+					if(this._obj){
+						evt.preventDefault();
+					}
+					typematic.stop();
+				})),
+				on(node, "dblclick", lang.hitch(this, function(evt){
+					evt.preventDefault();
+					if(has("ie") < 9){
+						typematic.trigger(evt, _this, node, callback, node, subsequentDelay, initialDelay, minDelay);
+						setTimeout(lang.hitch(this, typematic.stop), 50);
+					}
+				}))
+			];
+			return { remove: function(){
+				array.forEach(handles, function(h){
+					h.remove();
+				});
+			} };
+		},
+
+		addListener: function(/*Node*/ mouseNode, /*Node*/ keyNode, /*Object*/ keyObject, /*Object*/ _this, /*Function*/ callback, /*Number*/ subsequentDelay, /*Number*/ initialDelay, /*Number?*/ minDelay){
+			// summary:
+			//		Start listening for a specific typematic key and mouseclick.
+			//		This is a thin wrapper to addKeyListener and addMouseListener.
+			//		See the addMouseListener and addKeyListener methods for other parameters.
+			// mouseNode:
+			//		the DOM node object to listen on for mouse events.
+			// keyNode:
+			//		the DOM node object to listen on for key events.
+			// returns:
+			//		a connection handle
+			var handles = [
+				this.addKeyListener(keyNode, keyObject, _this, callback, subsequentDelay, initialDelay, minDelay),
+				this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay, minDelay)
+			];
+			return { remove: function(){
+				array.forEach(handles, function(h){
+					h.remove();
+				});
+			} };
+		}
+	});
 
+	return typematic;
 });
diff --git a/dojo/AdapterRegistry.js b/dojo/AdapterRegistry.js
index b82adee..cc70163 100644
--- a/dojo/AdapterRegistry.js
+++ b/dojo/AdapterRegistry.js
@@ -1,18 +1,16 @@
-define(["./_base/kernel", "./_base/lang"], function(dojo, lang) {
-	// module:
-	//		dojo/AdapterRegistry
-	// summary:
-	//		TODOC
+define(["./_base/kernel", "./_base/lang"], function(dojo, lang){
+// module:
+//		dojo/AdapterRegistry
 
 var AdapterRegistry = dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
-	//	summary:
+	// summary:
 	//		A registry to make contextual calling/searching easier.
-	//	description:
+	// description:
 	//		Objects of this class keep list of arrays in the form [name, check,
 	//		wrap, directReturn] that are used to determine what the contextual
 	//		result of a set of checked arguments is. All check/wrap functions
 	//		in this registry should be of the same arity.
-	//	example:
+	// example:
 	//	|	// create a new registry
 	//	|	var reg = new dojo.AdapterRegistry();
 	//	|	reg.register("handleString",
@@ -37,30 +35,25 @@ var AdapterRegistry = dojo.AdapterRegistry = function(/*Boolean?*/ returnWrapper
 	this.returnWrappers = returnWrappers || false; // Boolean
 };
 
-/*=====
-// doc alias helpers:
-AdapterRegistry = dojo.AdapterRegistry;
-=====*/
-
 lang.extend(AdapterRegistry, {
 	register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
-		//	summary:
+		// summary:
 		//		register a check function to determine if the wrap function or
 		//		object gets selected
-		//	name:
+		// name:
 		//		a way to identify this matcher.
-		//	check:
+		// check:
 		//		a function that arguments are passed to from the adapter's
 		//		match() function.  The check function should return true if the
 		//		given arguments are appropriate for the wrap function.
-		//	directReturn:
+		// directReturn:
 		//		If directReturn is true, the value passed in for wrap will be
 		//		returned instead of being called. Alternately, the
 		//		AdapterRegistry can be set globally to "return not call" using
 		//		the returnWrappers property. Either way, this behavior allows
 		//		the registry to act as a "search" function instead of a
 		//		function interception library.
-		//	override:
+		// override:
 		//		If override is given and true, the check function will be given
 		//		highest priority. Otherwise, it will be the lowest priority
 		//		adapter.
diff --git a/dojo/Deferred.js b/dojo/Deferred.js
new file mode 100644
index 0000000..79d61f7
--- /dev/null
+++ b/dojo/Deferred.js
@@ -0,0 +1,320 @@
+define([
+	"./has",
+	"./_base/lang",
+	"./errors/CancelError",
+	"./promise/Promise",
+	"./has!config-deferredInstrumentation?./promise/instrumentation"
+], function(has, lang, CancelError, Promise, instrumentation){
+	"use strict";
+
+	// module:
+	//		dojo/Deferred
+
+	var PROGRESS = 0,
+			RESOLVED = 1,
+			REJECTED = 2;
+	var FULFILLED_ERROR_MESSAGE = "This deferred has already been fulfilled.";
+
+	var freezeObject = Object.freeze || function(){};
+
+	var signalWaiting = function(waiting, type, result, rejection, deferred){
+		if(has("config-deferredInstrumentation")){
+			if(type === REJECTED && Deferred.instrumentRejected && waiting.length === 0){
+				Deferred.instrumentRejected(result, false, rejection, deferred);
+			}
+		}
+
+		for(var i = 0; i < waiting.length; i++){
+			signalListener(waiting[i], type, result, rejection);
+		}
+	};
+
+	var signalListener = function(listener, type, result, rejection){
+		var func = listener[type];
+		var deferred = listener.deferred;
+		if(func){
+			try{
+				var newResult = func(result);
+				if(type === PROGRESS){
+					if(typeof newResult !== "undefined"){
+						signalDeferred(deferred, type, newResult);
+					}
+				}else{
+					if(newResult && typeof newResult.then === "function"){
+						listener.cancel = newResult.cancel;
+						newResult.then(
+								// Only make resolvers if they're actually going to be used
+								makeDeferredSignaler(deferred, RESOLVED),
+								makeDeferredSignaler(deferred, REJECTED),
+								makeDeferredSignaler(deferred, PROGRESS));
+						return;
+					}
+					signalDeferred(deferred, RESOLVED, newResult);
+				}
+			}catch(error){
+				signalDeferred(deferred, REJECTED, error);
+			}
+		}else{
+			signalDeferred(deferred, type, result);
+		}
+
+		if(has("config-deferredInstrumentation")){
+			if(type === REJECTED && Deferred.instrumentRejected){
+				Deferred.instrumentRejected(result, !!func, rejection, deferred.promise);
+			}
+		}
+	};
+
+	var makeDeferredSignaler = function(deferred, type){
+		return function(value){
+			signalDeferred(deferred, type, value);
+		};
+	};
+
+	var signalDeferred = function(deferred, type, result){
+		if(!deferred.isCanceled()){
+			switch(type){
+				case PROGRESS:
+					deferred.progress(result);
+					break;
+				case RESOLVED:
+					deferred.resolve(result);
+					break;
+				case REJECTED:
+					deferred.reject(result);
+					break;
+			}
+		}
+	};
+
+	var Deferred = function(canceler){
+		// summary:
+		//		Creates a new deferred. This API is preferred over
+		//		`dojo/_base/Deferred`.
+		// description:
+		//		Creates a new deferred, as an abstraction over (primarily)
+		//		asynchronous operations. The deferred is the private interface
+		//		that should not be returned to calling code. That's what the
+		//		`promise` is for. See `dojo/promise/Promise`.
+		// canceler: Function?
+		//		Will be invoked if the deferred is canceled. The canceler
+		//		receives the reason the deferred was canceled as its argument.
+		//		The deferred is rejected with its return value, or a new
+		//		`dojo/errors/CancelError` instance.
+
+		// promise: dojo/promise/Promise
+		//		The public promise object that clients can add callbacks to. 
+		var promise = this.promise = new Promise();
+
+		var deferred = this;
+		var fulfilled, result, rejection;
+		var canceled = false;
+		var waiting = [];
+
+		if(has("config-deferredInstrumentation") && Error.captureStackTrace){
+			Error.captureStackTrace(deferred, Deferred);
+			Error.captureStackTrace(promise, Deferred);
+		}
+
+		this.isResolved = promise.isResolved = function(){
+			// summary:
+			//		Checks whether the deferred has been resolved.
+			// returns: Boolean
+
+			return fulfilled === RESOLVED;
+		};
+
+		this.isRejected = promise.isRejected = function(){
+			// summary:
+			//		Checks whether the deferred has been rejected.
+			// returns: Boolean
+
+			return fulfilled === REJECTED;
+		};
+
+		this.isFulfilled = promise.isFulfilled = function(){
+			// summary:
+			//		Checks whether the deferred has been resolved or rejected.
+			// returns: Boolean
+
+			return !!fulfilled;
+		};
+
+		this.isCanceled = promise.isCanceled = function(){
+			// summary:
+			//		Checks whether the deferred has been canceled.
+			// returns: Boolean
+
+			return canceled;
+		};
+
+		this.progress = function(update, strict){
+			// summary:
+			//		Emit a progress update on the deferred.
+			// description:
+			//		Emit a progress update on the deferred. Progress updates
+			//		can be used to communicate updates about the asynchronous
+			//		operation before it has finished.
+			// update: any
+			//		The progress update. Passed to progbacks.
+			// strict: Boolean?
+			//		If strict, will throw an error if the deferred has already
+			//		been fulfilled and consequently no progress can be emitted.
+			// returns: dojo/promise/Promise
+			//		Returns the original promise for the deferred.
+
+			if(!fulfilled){
+				signalWaiting(waiting, PROGRESS, update, null, deferred);
+				return promise;
+			}else if(strict === true){
+				throw new Error(FULFILLED_ERROR_MESSAGE);
+			}else{
+				return promise;
+			}
+		};
+
+		this.resolve = function(value, strict){
+			// summary:
+			//		Resolve the deferred.
+			// description:
+			//		Resolve the deferred, putting it in a success state.
+			// value: any
+			//		The result of the deferred. Passed to callbacks.
+			// strict: Boolean?
+			//		If strict, will throw an error if the deferred has already
+			//		been fulfilled and consequently cannot be resolved.
+			// returns: dojo/promise/Promise
+			//		Returns the original promise for the deferred.
+
+			if(!fulfilled){
+				// Set fulfilled, store value. After signaling waiting listeners unset
+				// waiting.
+				signalWaiting(waiting, fulfilled = RESOLVED, result = value, null, deferred);
+				waiting = null;
+				return promise;
+			}else if(strict === true){
+				throw new Error(FULFILLED_ERROR_MESSAGE);
+			}else{
+				return promise;
+			}
+		};
+
+		var reject = this.reject = function(error, strict){
+			// summary:
+			//		Reject the deferred.
+			// description:
+			//		Reject the deferred, putting it in an error state.
+			// error: any
+			//		The error result of the deferred. Passed to errbacks.
+			// strict: Boolean?
+			//		If strict, will throw an error if the deferred has already
+			//		been fulfilled and consequently cannot be rejected.
+			// returns: dojo/promise/Promise
+			//		Returns the original promise for the deferred.
+
+			if(!fulfilled){
+				if(has("config-deferredInstrumentation") && Error.captureStackTrace){
+					Error.captureStackTrace(rejection = {}, reject);
+				}
+				signalWaiting(waiting, fulfilled = REJECTED, result = error, rejection, deferred);
+				waiting = null;
+				return promise;
+			}else if(strict === true){
+				throw new Error(FULFILLED_ERROR_MESSAGE);
+			}else{
+				return promise;
+			}
+		};
+
+		this.then = promise.then = function(callback, errback, progback){
+			// summary:
+			//		Add new callbacks to the deferred.
+			// description:
+			//		Add new callbacks to the deferred. Callbacks can be added
+			//		before or after the deferred is fulfilled.
+			// callback: Function?
+			//		Callback to be invoked when the promise is resolved.
+			//		Receives the resolution value.
+			// errback: Function?
+			//		Callback to be invoked when the promise is rejected.
+			//		Receives the rejection error.
+			// progback: Function?
+			//		Callback to be invoked when the promise emits a progress
+			//		update. Receives the progress update.
+			// returns: dojo/promise/Promise
+			//		Returns a new promise for the result of the callback(s).
+			//		This can be used for chaining many asynchronous operations.
+
+			var listener = [progback, callback, errback];
+			// Ensure we cancel the promise we're waiting for, or if callback/errback
+			// have returned a promise, cancel that one.
+			listener.cancel = promise.cancel;
+			listener.deferred = new Deferred(function(reason){
+				// Check whether cancel is really available, returned promises are not
+				// required to expose `cancel`
+				return listener.cancel && listener.cancel(reason);
+			});
+			if(fulfilled && !waiting){
+				signalListener(listener, fulfilled, result, rejection);
+			}else{
+				waiting.push(listener);
+			}
+			return listener.deferred.promise;
+		};
+
+		this.cancel = promise.cancel = function(reason, strict){
+			// summary:
+			//		Inform the deferred it may cancel its asynchronous operation.
+			// description:
+			//		Inform the deferred it may cancel its asynchronous operation.
+			//		The deferred's (optional) canceler is invoked and the
+			//		deferred will be left in a rejected state. Can affect other
+			//		promises that originate with the same deferred.
+			// reason: any
+			//		A message that may be sent to the deferred's canceler,
+			//		explaining why it's being canceled.
+			// strict: Boolean?
+			//		If strict, will throw an error if the deferred has already
+			//		been fulfilled and consequently cannot be canceled.
+			// returns: any
+			//		Returns the rejection reason if the deferred was canceled
+			//		normally.
+
+			if(!fulfilled){
+				// Cancel can be called even after the deferred is fulfilled
+				if(canceler){
+					var returnedReason = canceler(reason);
+					reason = typeof returnedReason === "undefined" ? reason : returnedReason;
+				}
+				canceled = true;
+				if(!fulfilled){
+					// Allow canceler to provide its own reason, but fall back to a CancelError
+					if(typeof reason === "undefined"){
+						reason = new CancelError();
+					}
+					reject(reason);
+					return reason;
+				}else if(fulfilled === REJECTED && result === reason){
+					return reason;
+				}
+			}else if(strict === true){
+				throw new Error(FULFILLED_ERROR_MESSAGE);
+			}
+		};
+
+		freezeObject(promise);
+	};
+
+	Deferred.prototype.toString = function(){
+		// returns: String
+		//		Returns `[object Deferred]`.
+
+		return "[object Deferred]";
+	};
+
+	if(instrumentation){
+		instrumentation(Deferred);
+	}
+
+	return Deferred;
+});
diff --git a/dojo/DeferredList.js b/dojo/DeferredList.js
index 5071dfc..0c3e950 100644
--- a/dojo/DeferredList.js
+++ b/dojo/DeferredList.js
@@ -1,19 +1,17 @@
-define(["./_base/kernel", "./_base/Deferred", "./_base/array"], function(dojo, Deferred, darray) {
+define(["./_base/kernel", "./_base/Deferred", "./_base/array"], function(dojo, Deferred, darray){
 	// module:
 	//		dojo/DeferredList
-	// summary:
-	//		TODOC
 
 
 dojo.DeferredList = function(/*Array*/ list, /*Boolean?*/ fireOnOneCallback, /*Boolean?*/ fireOnOneErrback, /*Boolean?*/ consumeErrors, /*Function?*/ canceller){
 	// summary:
+	//		Deprecated, use dojo/promise/all instead.
 	//		Provides event handling for a group of Deferred objects.
 	// description:
 	//		DeferredList takes an array of existing deferreds and returns a new deferred of its own
 	//		this new deferred will typically have its callback fired when all of the deferreds in
 	//		the given list have fired their own deferreds.  The parameters `fireOnOneCallback` and
 	//		fireOnOneErrback, will fire before all the deferreds as appropriate
-	//
 	// list:
 	//		The list of deferreds to be synchronizied with this DeferredList
 	// fireOnOneCallback:
@@ -65,9 +63,9 @@ dojo.DeferredList.prototype.gatherResults = function(deferredList){
 	// summary:
 	//		Gathers the results of the deferreds for packaging
 	//		as the parameters to the Deferred Lists' callback
-	// deferredList: dojo.DeferredList
+	// deferredList: dojo/DeferredList
 	//		The deferred list from which this function gathers results.
-	// returns: dojo.DeferredList
+	// returns: dojo/DeferredList
 	//		The newly created deferred list which packs results as
 	//		parameters to its callback.
 
diff --git a/dojo/Evented.js b/dojo/Evented.js
index 420dfca..661b6d2 100644
--- a/dojo/Evented.js
+++ b/dojo/Evented.js
@@ -1,20 +1,23 @@
 define(["./aspect", "./on"], function(aspect, on){
-	// summary:
-	//		The export of this module is a class that can be used as a mixin or base class, 
-	// 		to add on() and emit() methods to a class
-	// 		for listening for events and emiting events:
-	// 		|define(["dojo/Evented"], function(Evented){
-	// 		|	var EventedWidget = dojo.declare([Evented, dijit._Widget], {...});
-	//		|	widget = new EventedWidget();
-	//		|	widget.on("open", function(event){
-	//		|	... do something with event
-	//		|	 });
-	//		|
-	//		|	widget.emit("open", {name:"some event", ...});
+	// module:
+	//		dojo/Evented
 
  	"use strict";
  	var after = aspect.after;
 	function Evented(){
+		// summary:
+		//		A class that can be used as a mixin or base class,
+		//		to add on() and emit() methods to a class
+		//		for listening for events and emitting events:
+		//
+		//		|	define(["dojo/Evented"], function(Evented){
+		//		|		var EventedWidget = dojo.declare([Evented, dijit._Widget], {...});
+		//		|		widget = new EventedWidget();
+		//		|		widget.on("open", function(event){
+		//		|		... do something with event
+		//		|	 });
+		//		|
+		//		|	widget.emit("open", {name:"some event", ...});
 	}
 	Evented.prototype = {
 		on: function(type, listener){
diff --git a/dojo/LICENSE b/dojo/LICENSE
index aa6b39f..b1ddd34 100644
--- a/dojo/LICENSE
+++ b/dojo/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2011, The Dojo Foundation
+Copyright (c) 2005-2013, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/dojo/NodeList-data.js b/dojo/NodeList-data.js
index 2df736d..c731a35 100644
--- a/dojo/NodeList-data.js
+++ b/dojo/NodeList-data.js
@@ -1,77 +1,23 @@
 define([
 	"./_base/kernel", "./query", "./_base/lang", "./_base/array", "./dom-attr"
-], function(dojo, query, lang, array, attr) {
+], function(dojo, query, lang, array, attr){
+
 	// module:
 	//		dojo/NodeList-data
-	// summary:
-	//		TODOC
-
-var NodeList = query.NodeList;
-/*=====
-// doc alias helpers:
-var NodeList = dojo.NodeList;
 
-	dojo.NodeList.prototype.data = function(key, value){
-		// summary: stash or get some arbitrary data on/from these nodes.
-		//
-		// description:
-		//		Stash or get some arbirtrary data on/from these nodes. This private _data function is
-		//		exposed publicly on `dojo.NodeList`, eg: as the result of a `dojo.query` call.
-		//		DIFFERS from jQuery.data in that when used as a getter, the entire list is ALWAYS
-		//		returned. EVEN WHEN THE LIST IS length == 1.
-		//
-		//		A single-node version of this function is provided as `dojo._nodeData`, which follows
-		//		the same signature, though expects a String ID or DomNode reference in the first
-		//		position, before key/value arguments.
-		//
-		// node: String|DomNode
-		//		The node to associate data with
-		//
-		// key: Object?|String?
-		//		If an object, act as a setter and iterate over said object setting data items as defined.
-		//		If a string, and `value` present, set the data for defined `key` to `value`
-		//		If a string, and `value` absent, act as a getter, returning the data associated with said `key`
-		//
-		// value: Anything?
-		//		The value to set for said `key`, provided `key` is a string (and not an object)
-		//
-		// example:
-		//		Set a key `bar` to some data, then retrieve it.
-		//	|	dojo.query(".foo").data("bar", "touched");
-		//	|	var touched = dojo.query(".foo").data("bar");
-		//	|	if(touched[0] == "touched"){ alert('win'); }
-		//
-		// example:
-		//		Get all the data items for a given node.
-		//	|	var list = dojo.query(".foo").data();
-		//	|	var first = list[0];
-		//
-		// example:
-		//		Set the data to a complex hash. Overwrites existing keys with new value
-		//	|	dojo.query(".foo").data({ bar:"baz", foo:"bar" });
-		//		Then get some random key:
-		//	|	dojo.query(".foo").data("foo"); // returns [`bar`]
-		//
-		//	returns: Object|Anything|Nothing
-		//		When used as a setter via `dojo.NodeList`, a NodeList instance is returned
-		//		for further chaning. When used as a getter via `dojo.NodeList` an ARRAY
-		//		of items is returned. The items in the array correspond to the elements
-		//		in the original list. This is true even when the list length is 1, eg:
-		//		when looking up a node by ID (#foo)
+	/*=====
+	return function(){
+		// summary:
+		//		Adds data() and removeData() methods to NodeList, and returns NodeList constructor.
 	};
+	=====*/
 
-	dojo.NodeList.prototype.removeData = function(key){
-		// summary: Remove the data associated with these nodes.
-		// key: String?
-		//		If ommitted, clean all data for this node.
-		//		If passed, remove the data item found at `key`
-	};
-
-=====*/
+	var NodeList = query.NodeList;
 
 	var dataCache = {}, x = 0, dataattr = "data-dojo-dataid",
 		dopid = function(node){
-			// summary: Return a uniqueish ID for the passed node reference
+			// summary:
+			//		Return a uniqueish ID for the passed node reference
 			var pid = attr.get(node, dataattr);
 			if(!pid){
 				pid = "pid" + (x++);
@@ -85,17 +31,18 @@ var NodeList = dojo.NodeList;
 	// An alias to the private dataCache for NodeList-data. NEVER USE THIS!
 	// This private is only exposed for the benefit of unit testing, and is
 	// removed during the build process.
-	dojo._nodeDataCache = dataCache;
+	NodeList._nodeDataCache = dojo._nodeDataCache = dataCache;
 	//>>excludeEnd("debugging");
 
 	var dodata = dojo._nodeData = function(node, key, value){
-		// summary: Private helper for dojo.NodeList.data for single node data access. Refer to NodeList.data 
+		// summary:
+		//		Private helper for dojo/NodeList.data for single node data access. Refer to NodeList.data
 		//		documentation for more information.
 		//
 		// node: String|DomNode
 		//		The node to associate data with
 		//
-		// key: Object?|String?
+		// key: Object|String?
 		//		If an object, act as a setter and iterate over said object setting data items as defined.
 		//		If a string, and `value` present, set the data for defined `key` to `value`
 		//		If a string, and `value` absent, act as a getter, returning the data associated with said `key`
@@ -125,7 +72,8 @@ var NodeList = dojo.NodeList;
 	};
 
 	var removeData = dojo._removeNodeData = function(node, key){
-		// summary: Remove some data from this node
+		// summary:
+		//		Remove some data from this node
 		// node: String|DomNode
 		//		The node reference to remove data from
 		// key: String?
@@ -141,13 +89,14 @@ var NodeList = dojo.NodeList;
 		}
 	};
 
-	dojo._gcNodeData = function(){
-		// summary: super expensive: GC all data in the data for nodes that no longer exist in the dom.
+	NodeList._gcNodeData = dojo._gcNodeData = function(){
+		// summary:
+		//		super expensive: GC all data in the data for nodes that no longer exist in the dom.
 		// description:
 		//		super expensive: GC all data in the data for nodes that no longer exist in the dom.
 		//		MUCH safer to do this yourself, manually, on a per-node basis (via `NodeList.removeData()`)
 		//		provided as a stop-gap for exceptionally large/complex applications with constantly changing
-		//		content regions (eg: a dijit.layout.ContentPane with replacing data)
+		//		content regions (eg: a dijit/layout/ContentPane with replacing data)
 		//		There is NO automatic GC going on. If you dojo.destroy() a node, you should _removeNodeData
 		//		prior to destruction.
 		var livePids = query("[" + dataattr + "]").map(dopid);
@@ -156,7 +105,7 @@ var NodeList = dojo.NodeList;
 		}
 	};
 
-	// make nodeData and removeNodeData public on dojo.NodeList:
+	// make nodeData and removeNodeData public on dojo/NodeList:
 	lang.extend(NodeList, {
 		data: NodeList._adaptWithCondition(dodata, function(a){
 			return a.length === 0 || a.length == 1 && (typeof a[0] == "string");
@@ -164,8 +113,70 @@ var NodeList = dojo.NodeList;
 		removeData: NodeList._adaptAsForEach(removeData)
 	});
 
-// TODO: this is the basic implemetation of adaptWithCondtionAndWhenMappedConsiderLength, for lack of a better API name
-// it conflicts with the the `dojo.NodeList` way: always always return an arrayLike thinger. Consider for 2.0:
+	/*=====
+	 lang.extend(NodeList, {
+		 data: function(key, value){
+			 // summary:
+			 //		stash or get some arbitrary data on/from these nodes.
+			 //
+			 // description:
+			 //		Stash or get some arbitrary data on/from these nodes. This private _data function is
+			 //		exposed publicly on `dojo/NodeList`, eg: as the result of a `dojo.query` call.
+			 //		DIFFERS from jQuery.data in that when used as a getter, the entire list is ALWAYS
+			 //		returned. EVEN WHEN THE LIST IS length == 1.
+			 //
+			 //		A single-node version of this function is provided as `dojo._nodeData`, which follows
+			 //		the same signature, though expects a String ID or DomNode reference in the first
+			 //		position, before key/value arguments.
+			 //
+			 // node: String|DomNode
+			 //		The node to associate data with
+			 //
+			 // key: Object|String?
+			 //		If an object, act as a setter and iterate over said object setting data items as defined.
+			 //		If a string, and `value` present, set the data for defined `key` to `value`
+			 //		If a string, and `value` absent, act as a getter, returning the data associated with said `key`
+			 //
+			 // value: Anything?
+			 //		The value to set for said `key`, provided `key` is a string (and not an object)
+			 //
+			 // example:
+			 //		Set a key `bar` to some data, then retrieve it.
+			 //	|	dojo.query(".foo").data("bar", "touched");
+			 //	|	var touched = dojo.query(".foo").data("bar");
+			 //	|	if(touched[0] == "touched"){ alert('win'); }
+			 //
+			 // example:
+			 //		Get all the data items for a given node.
+			 //	|	var list = dojo.query(".foo").data();
+			 //	|	var first = list[0];
+			 //
+			 // example:
+			 //		Set the data to a complex hash. Overwrites existing keys with new value
+			 //	|	dojo.query(".foo").data({ bar:"baz", foo:"bar" });
+			 //		Then get some random key:
+			 //	|	dojo.query(".foo").data("foo"); // returns [`bar`]
+			 //
+			 // returns: Object|Anything|Nothing
+			 //		When used as a setter via `dojo/NodeList`, a NodeList instance is returned
+			 //		for further chaining. When used as a getter via `dojo/NodeList` an ARRAY
+			 //		of items is returned. The items in the array correspond to the elements
+			 //		in the original list. This is true even when the list length is 1, eg:
+			 //		when looking up a node by ID (#foo)
+		 },
+
+		 removeData: function(key){
+			 // summary:
+			 //		Remove the data associated with these nodes.
+			 // key: String?
+			 //		If omitted, clean all data for this node.
+			 //		If passed, remove the data item found at `key`
+		 }
+	 });
+	 =====*/
+
+// TODO: this is the basic implementation of adaptWithConditionAndWhenMappedConsiderLength, for lack of a better API name
+// it conflicts with the the `dojo/NodeList` way: always always return an arrayLike thinger. Consider for 2.0:
 //
 //	NodeList.prototype.data = function(key, value){
 //		var a = arguments, r;
@@ -179,7 +190,7 @@ var NodeList = dojo.NodeList;
 //				d._data(node, key, value);
 //			});
 //		}
-//		return r; // dojo.NodeList|Array|SingleItem
+//		return r; // NodeList|Array|SingleItem
 //	};
 
 	return NodeList;
diff --git a/dojo/NodeList-dom.js b/dojo/NodeList-dom.js
index fdf11c7..87ee7b7 100644
--- a/dojo/NodeList-dom.js
+++ b/dojo/NodeList-dom.js
@@ -1,5 +1,15 @@
 define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-class", "./dom-construct", "./dom-geometry", "./dom-attr", "./dom-style"], function(dojo, query, array, lang, domCls, domCtr, domGeom, domAttr, domStyle){
-	/*===== var NodeList = dojo.NodeList; =====*/
+
+	// module:
+	//		dojo/NodeList-dom.js
+
+	/*=====
+	 return function(){
+		 // summary:
+		 //		Adds DOM related methods to NodeList, and returns NodeList constructor.
+	 };
+	 =====*/
+
 	var magicGuard = function(a){
 		// summary:
 		//		the guard function for dojo.attr() and dojo.style()
@@ -38,9 +48,9 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 			// description:
 			//		If content is an object, it can have special properties "template" and
 			//		"parse". If "template" is defined, then the template value is run through
-			//		dojo.string.substitute (if dojo.string.substitute has been dojo.required elsewhere),
+			//		dojo.string.substitute (if dojo/string.substitute() has been dojo.required elsewhere),
 			//		or if templateFunc is a function on the content, that function will be used to
-			//		transform the template into a final string to be used for for passing to dojo._toDom.
+			//		transform the template into a final string to be used for for passing to dojo/dom-construct.toDom().
 			//		If content.parse is true, then it is remembered for later, for when the content
 			//		nodes are inserted into the DOM. At that point, the nodes will be parsed for widgets
 			//		(if dojo.parser has been dojo.required elsewhere).
@@ -86,7 +96,7 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 		_cloneNode: function(/*DOMNode*/ node){
 			// summary:
 			//		private utility to clone a node. Not very interesting in the vanilla
-			//		dojo.NodeList case, but delegates could do interesting things like
+			//		dojo/NodeList case, but delegates could do interesting things like
 			//		clone event handlers if that is derivable from the node.
 			return node.cloneNode(true);
 		},
@@ -134,6 +144,8 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 			}
 		},
 
+
+		position: aam(domGeom.position),
 		/*=====
 		position: function(){
 			// summary:
@@ -143,7 +155,10 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 
 			return dojo.map(this, dojo.position); // Array
 		},
+		=====*/
 
+		attr: awc(getSet(domAttr), magicGuard),
+		/*=====
 		attr: function(property, value){
 			// summary:
 			//		gets or sets the DOM attribute for every element in the
@@ -165,10 +180,12 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 			//		innerHTML can be assigned or retrieved as well:
 			//	|	// get the innerHTML (as an array) for each list item
 			//	|	var ih = dojo.query("li.replaceable").attr("innerHTML");
-			return; // dojo.NodeList
-			return; // Array
+			return; // dojo/NodeList|Array
 		},
+		=====*/
 
+		style: awc(getSet(domStyle), magicGuard),
+		/*=====
 		style: function(property, value){
 			// summary:
 			//		gets or sets the CSS property for every element in the NodeList
@@ -180,19 +197,25 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 			// returns:
 			//		if no value is passed, the result is an array of strings.
 			//		If a value is passed, the return is this NodeList
-			return; // dojo.NodeList
+			return; // dojo/NodeList
 			return; // Array
 		},
+		=====*/
 
+		addClass: aafe(domCls.add),
+		/*=====
 		addClass: function(className){
 			// summary:
 			//		adds the specified class to every node in the list
 			// className: String|Array
 			//		A String class name to add, or several space-separated class names,
 			//		or an array of class names.
-			return; // dojo.NodeList
+			return; // dojo/NodeList
 		},
+		=====*/
 
+		removeClass: aafe(domCls.remove),
+		/*=====
 		removeClass: function(className){
 			// summary:
 			//		removes the specified class from every node in the list
@@ -201,10 +224,13 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 			//		class names, or an array of class names. If omitted, all class names
 			//		will be deleted.
 			// returns:
-			//		dojo.NodeList, this list
-			return; // dojo.NodeList
+			//		this list
+			return; // dojo/NodeList
 		},
+		=====*/
 
+		toggleClass: aafe(domCls.toggle),
+		/*=====
 		toggleClass: function(className, condition){
 			// summary:
 			//		Adds a class to node if not present, or removes if present.
@@ -213,33 +239,57 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 			//		If passed, true means to add the class, false means to remove.
 			// className: String
 			//		the CSS class to add
-			return; // dojo.NodeList
+			return; // dojo/NodeList
 		},
+		=====*/
 
+		replaceClass: aafe(domCls.replace),
+		/*=====
+		replaceClass: function(addClassStr, removeClassStr){
+			// summary:
+			//		Replaces one or more classes on a node if not present.
+			//		Operates more quickly than calling `removeClass()` and `addClass()`
+			// addClassStr: String|Array
+			//		A String class name to add, or several space-separated class names,
+			//		or an array of class names.
+			// removeClassStr: String|Array?
+			//		A String class name to remove, or several space-separated class names,
+			//		or an array of class names.
+			return; // dojo/NodeList
+		 },
+		 =====*/
+
+		empty: aafe(domCtr.empty),
+		/*=====
 		empty: function(){
 			// summary:
 			//		clears all content from each node in the list. Effectively
 			//		equivalent to removing all child nodes from every item in
 			//		the list.
-			return this.forEach("item.innerHTML='';"); // dojo.NodeList
+			return this.forEach("item.innerHTML='';"); // dojo/NodeList
 			// FIXME: should we be checking for and/or disposing of widgets below these nodes?
 		},
 		=====*/
 
-		// useful html methods
-		attr: awc(getSet(domAttr), magicGuard),
-		style: awc(getSet(domStyle), magicGuard),
-
-		addClass: aafe(domCls.add),
-		removeClass: aafe(domCls.remove),
-		replaceClass: aafe(domCls.replace),
-		toggleClass: aafe(domCls.toggle),
-
-		empty: aafe(domCtr.empty),
 		removeAttr: aafe(domAttr.remove),
+		/*=====
+		 removeAttr: function(name){
+			// summary:
+			//		Removes an attribute from each node in the list.
+			// name: String
+			//		the name of the attribute to remove
+			return;		// dojo/NodeList
+		},
+		=====*/
 
-		position: aam(domGeom.position),
 		marginBox: aam(domGeom.getMarginBox),
+		/*=====
+		marginBox: function(){
+			// summary:
+			//		Returns margin-box size of nodes
+		 	return; // dojo/NodeList
+		 },
+		 =====*/
 
 		// FIXME: connectPublisher()? connectRunOnce()?
 
@@ -262,15 +312,17 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 			//		for relative positioning.
 			// position:
 			//		can be one of:
-			//		|	"last" (default)
-			//		|	"first"
-			//		|	"before"
-			//		|	"after"
-			//		|	"only"
-			//		|	"replace"
+			//
+			//		-	"last" (default)
+			//		-	"first"
+			//		-	"before"
+			//		-	"after"
+			//		-	"only"
+			//		-	"replace"
+			//
 			//		or an offset in the childNodes property
 			var item = query(queryOrNode)[0];
-			return this.forEach(function(node){ domCtr.place(node, item, position); }); // dojo.NodeList
+			return this.forEach(function(node){ domCtr.place(node, item, position); }); // dojo/NodeList
 		},
 
 		orphan: function(/*String?*/ filter){
@@ -280,29 +332,31 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 			// filter:
 			//		CSS selector like ".foo" or "div > span"
 			// returns:
-			//		`dojo.NodeList` containing the orphaned elements
-			return (filter ? query._filterResult(this, filter) : this).forEach(orphan); // dojo.NodeList
+			//		NodeList containing the orphaned elements
+			return (filter ? query._filterResult(this, filter) : this).forEach(orphan); // dojo/NodeList
 		},
 
 		adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
 			// summary:
 			//		places any/all elements in queryOrListOrNode at a
 			//		position relative to the first element in this list.
-			//		Returns a dojo.NodeList of the adopted elements.
+			//		Returns a dojo/NodeList of the adopted elements.
 			// queryOrListOrNode:
 			//		a DOM node or a query string or a query result.
 			//		Represents the nodes to be adopted relative to the
 			//		first element of this NodeList.
 			// position:
 			//		can be one of:
-			//		|	"last" (default)
-			//		|	"first"
-			//		|	"before"
-			//		|	"after"
-			//		|	"only"
-			//		|	"replace"
+			//
+			//		-	"last" (default)
+			//		-	"first"
+			//		-	"before"
+			//		-	"after"
+			//		-	"only"
+			//		-	"replace"
+			//
 			//		or an offset in the childNodes property
-			return query(queryOrListOrNode).place(this[0], position)._stash(this);	// dojo.NodeList
+			return query(queryOrListOrNode).place(this[0], position)._stash(this);	// dojo/NodeList
 		},
 
 		// FIXME: do we need this?
@@ -322,7 +376,7 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 			//	|		<p>great comedians may not be funny <span>in person</span></p>
 			//	|	</div>
 			//		If we are presented with the following definition for a NodeList:
-			//	|	var l = new dojo.NodeList(dojo.byId("foo"), dojo.byId("bar"));
+			//	|	var l = new NodeList(dojo.byId("foo"), dojo.byId("bar"));
 			//		it's possible to find all span elements under paragraphs
 			//		contained by these elements with this sub-query:
 			//	|	var spans = l.query("p span");
@@ -338,7 +392,7 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 					}
 				});
 			});
-			return ret._stash(this);	// dojo.NodeList
+			return ret._stash(this);	// dojo/NodeList
 		},
 
 		filter: function(/*String|Function*/ filter){
@@ -364,12 +418,12 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 				items = query._filterResult(this, a[0]);
 				if(a.length == 1){
 					// if we only got a string query, pass back the filtered results
-					return items._stash(this); // dojo.NodeList
+					return items._stash(this); // dojo/NodeList
 				}
 				// if we got a callback, run it over the filtered items
 				start = 1;
 			}
-			return this._wrap(array.filter(items, a[start], a[start + 1]), this);	// dojo.NodeList
+			return this._wrap(array.filter(items, a[start], a[start + 1]), this);	// dojo/NodeList
 		},
 
 		/*
@@ -381,7 +435,7 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 		},
 		*/
 
-		addContent: function(/*String||DomNode||Object||dojo.NodeList*/ content, /*String||Integer?*/ position){
+		addContent: function(/*String||DomNode||Object||dojo/NodeList*/ content, /*String||Integer?*/ position){
 			// summary:
 			//		add a node, NodeList or some HTML as a string to every item in the
 			//		list.  Returns the original list.
@@ -403,12 +457,14 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 			//		should be used to transform the "template".
 			// position:
 			//		can be one of:
-			//		|	"last"||"end" (default)
-			//		|	"first||"start"
-			//		|	"before"
-			//		|	"after"
-			//		|	"replace" (replaces nodes in this NodeList with new content)
-			//		|	"only" (removes other children of the nodes so new content is the only child)
+			//
+			//		-	"last"||"end" (default)
+			//		-	"first||"start"
+			//		-	"before"
+			//		-	"after"
+			//		-	"replace" (replaces nodes in this NodeList with new content)
+			//		-	"only" (removes other children of the nodes so new content is the only child)
+			//
 			//		or an offset in the childNodes property
 			// example:
 			//		appends content to the end if the position is omitted
@@ -426,29 +482,33 @@ define(["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-cla
 			//	|	dojo.query(".note").addContent(dojo.byId("foo"));
 			// example:
 			//		Append nodes from a templatized string.
-			//		dojo.require("dojo.string");
-			//		dojo.query(".note").addContent({
-			//			template: '<b>${id}: </b><span>${name}</span>',
-			//			id: "user332",
-			//			name: "Mr. Anderson"
-			//		});
+			// |	dojo.require("dojo.string");
+			// |	dojo.query(".note").addContent({
+			// |		template: '<b>${id}: </b><span>${name}</span>',
+			// |		id: "user332",
+			// |		name: "Mr. Anderson"
+			// |	});
 			// example:
 			//		Append nodes from a templatized string that also has widgets parsed.
-			//		dojo.require("dojo.string");
-			//		dojo.require("dojo.parser");
-			//		var notes = dojo.query(".note").addContent({
-			//			template: '<button dojoType="dijit.form.Button">${text}</button>',
-			//			parse: true,
-			//			text: "Send"
-			//		});
+			// |	dojo.require("dojo.string");
+			// |	dojo.require("dojo.parser");
+			// |	var notes = dojo.query(".note").addContent({
+			// |		template: '<button dojoType="dijit/form/Button">${text}</button>',
+			// |		parse: true,
+			// |		text: "Send"
+			// |	});
 			content = this._normalize(content, this[0]);
 			for(var i = 0, node; (node = this[i]); i++){
-				this._place(content, node, position, i > 0);
+				if(content.length){
+					this._place(content, node, position, i > 0);
+				}else{
+					// if it is an empty array, we empty the target node
+					domCtr.empty(node);
+				}
 			}
-			return this; //dojo.NodeList
+			return this; // dojo/NodeList
 		}
 	});
 
-	/*===== return dojo.NodeList; =====*/
 	return NodeList;
 });
diff --git a/dojo/NodeList-fx.js b/dojo/NodeList-fx.js
index 2a50df3..882aa3d 100644
--- a/dojo/NodeList-fx.js
+++ b/dojo/NodeList-fx.js
@@ -1,20 +1,19 @@
-define(["dojo/_base/NodeList", "./_base/lang", "./_base/connect", "./_base/fx", "./fx"], 
-  function(NodeList, lang, connectLib, baseFx, coreFx) {
-	// module:
-	//		dojo/NodeList-fx
-	// summary:
-	//		TODOC
+define(["./query", "./_base/lang", "./aspect", "./_base/fx", "./fx"],
+function(query, lang, aspect, baseFx, coreFx){
+
+// module:
+//		dojo/NodeList-fx
 
 /*=====
-dojo["NodeList-fx"] = {
-	// summary: Adds dojo.fx animation support to dojo.query() by extending the NodeList class
+return function(){
+	// summary:
+	//		Adds dojo.fx animation support to dojo.query() by extending the NodeList class
 	//		with additional FX functions.  NodeList is the array-like object used to hold query results.
 };
-
-// doc alias helpers:
-NodeList = dojo.NodeList;
 =====*/
 
+var NodeList = query.NodeList;
+
 lang.extend(NodeList, {
 	_anim: function(obj, method, args){
 		args = args||{};
@@ -25,21 +24,21 @@ lang.extend(NodeList, {
 				return obj[method](tmpArgs);
 			})
 		);
-		return args.auto ? a.play() && this : a; // dojo.Animation|dojo.NodeList
+		return args.auto ? a.play() && this : a; // dojo/_base/fx.Animation|dojo/NodeList
 	},
 
 	wipeIn: function(args){
 		// summary:
-		//		wipe in all elements of this NodeList via `dojo.fx.wipeIn`
+		//		wipe in all elements of this NodeList via `dojo/fx.wipeIn()`
 		//
 		// args: Object?
-		//		Additional dojo.Animation arguments to mix into this set with the addition of
+		//		Additional dojo/_base/fx.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
-		// returns: dojo.Animation|dojo.NodeList
+		// returns: dojo/_base/fx.Animation|dojo/NodeList
 		//		A special args member `auto` can be passed to automatically play the animation.
-		//		If args.auto is present, the original dojo.NodeList will be returned for further
-		//		chaining. Otherwise the dojo.Animation instance is returned and must be .play()'ed
+		//		If args.auto is present, the original dojo/NodeList will be returned for further
+		//		chaining. Otherwise the dojo/_base/fx.Animation instance is returned and must be .play()'ed
 		//
 		// example:
 		//		Fade in all tables with class "blah":
@@ -49,40 +48,40 @@ lang.extend(NodeList, {
 		//		Utilizing `auto` to get the NodeList back:
 		//		|	dojo.query(".titles").wipeIn({ auto:true }).onclick(someFunction);
 		//
-		return this._anim(coreFx, "wipeIn", args); // dojo.Animation|dojo.NodeList
+		return this._anim(coreFx, "wipeIn", args); // dojo/_base/fx.Animation|dojo/NodeList
 	},
 
 	wipeOut: function(args){
 		// summary:
-		//		wipe out all elements of this NodeList via `dojo.fx.wipeOut`
+		//		wipe out all elements of this NodeList via `dojo/fx.wipeOut()`
 		//
 		// args: Object?
-		//		Additional dojo.Animation arguments to mix into this set with the addition of
+		//		Additional dojo/_base/fx.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
-		// returns: dojo.Animation|dojo.NodeList
+		// returns: dojo/_base/fx.Animation|dojo/NodeList
 		//		A special args member `auto` can be passed to automatically play the animation.
-		//		If args.auto is present, the original dojo.NodeList will be returned for further
-		//		chaining. Otherwise the dojo.Animation instance is returned and must be .play()'ed
+		//		If args.auto is present, the original dojo/NodeList will be returned for further
+		//		chaining. Otherwise the dojo/_base/fx.Animation instance is returned and must be .play()'ed
 		//
 		// example:
 		//		Wipe out all tables with class "blah":
 		//		|	dojo.query("table.blah").wipeOut().play();
-		return this._anim(coreFx, "wipeOut", args); // dojo.Animation|dojo.NodeList
+		return this._anim(coreFx, "wipeOut", args); // dojo/_base/fx.Animation|dojo/NodeList
 	},
 
 	slideTo: function(args){
 		// summary:
-		//		slide all elements of the node list to the specified place via `dojo.fx.slideTo`
+		//		slide all elements of the node list to the specified place via `dojo/fx.slideTo()`
 		//
 		// args: Object?
-		//		Additional dojo.Animation arguments to mix into this set with the addition of
+		//		Additional dojo/_base/fx.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
-		// returns: dojo.Animation|dojo.NodeList
+		// returns: dojo/_base/fx.Animation|dojo/NodeList
 		//		A special args member `auto` can be passed to automatically play the animation.
-		//		If args.auto is present, the original dojo.NodeList will be returned for further
-		//		chaining. Otherwise the dojo.Animation instance is returned and must be .play()'ed
+		//		If args.auto is present, the original dojo/NodeList will be returned for further
+		//		chaining. Otherwise the dojo/_base/fx.Animation instance is returned and must be .play()'ed
 		//
 		// example:
 		//		|	Move all tables with class "blah" to 300/300:
@@ -90,7 +89,7 @@ lang.extend(NodeList, {
 		//		|		left: 40,
 		//		|		top: 50
 		//		|	}).play();
-		return this._anim(coreFx, "slideTo", args); // dojo.Animation|dojo.NodeList
+		return this._anim(coreFx, "slideTo", args); // dojo/_base/fx.Animation|dojo/NodeList
 	},
 
 
@@ -99,18 +98,18 @@ lang.extend(NodeList, {
 		//		fade in all elements of this NodeList via `dojo.fadeIn`
 		//
 		// args: Object?
-		//		Additional dojo.Animation arguments to mix into this set with the addition of
+		//		Additional dojo/_base/fx.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
-		// returns: dojo.Animation|dojo.NodeList
+		// returns: dojo/_base/fx.Animation|dojo/NodeList
 		//		A special args member `auto` can be passed to automatically play the animation.
-		//		If args.auto is present, the original dojo.NodeList will be returned for further
-		//		chaining. Otherwise the dojo.Animation instance is returned and must be .play()'ed
+		//		If args.auto is present, the original dojo/NodeList will be returned for further
+		//		chaining. Otherwise the dojo/_base/fx.Animation instance is returned and must be .play()'ed
 		//
 		// example:
 		//		Fade in all tables with class "blah":
 		//		|	dojo.query("table.blah").fadeIn().play();
-		return this._anim(baseFx, "fadeIn", args); // dojo.Animation|dojo.NodeList
+		return this._anim(baseFx, "fadeIn", args); // dojo/_base/fx.Animation|dojo/NodeList
 	},
 
 	fadeOut: function(args){
@@ -118,13 +117,13 @@ lang.extend(NodeList, {
 		//		fade out all elements of this NodeList via `dojo.fadeOut`
 		//
 		// args: Object?
-		//		Additional dojo.Animation arguments to mix into this set with the addition of
+		//		Additional dojo/_base/fx.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
-		// returns: dojo.Animation|dojo.NodeList
+		// returns: dojo/_base/fx.Animation|dojo/NodeList
 		//		A special args member `auto` can be passed to automatically play the animation.
-		//		If args.auto is present, the original dojo.NodeList will be returned for further
-		//		chaining. Otherwise the dojo.Animation instance is returned and must be .play()'ed
+		//		If args.auto is present, the original dojo/NodeList will be returned for further
+		//		chaining. Otherwise the dojo/_base/fx.Animation instance is returned and must be .play()'ed
 		//
 		// example:
 		//		Fade out all elements with class "zork":
@@ -132,13 +131,13 @@ lang.extend(NodeList, {
 		// example:
 		//		Fade them on a delay and do something at the end:
 		//		|	var fo = dojo.query(".zork").fadeOut();
-		//		|	dojo.connect(fo, "onEnd", function(){ /*...*/ });
+		//		|	aspect.after(fo, "onEnd", function(){ /*...*/ }, true);
 		//		|	fo.play();
 		// example:
 		//		Using `auto`:
 		//		|	dojo.query("li").fadeOut({ auto:true }).filter(filterFn).forEach(doit);
 		//
-		return this._anim(baseFx, "fadeOut", args); // dojo.Animation|dojo.NodeList
+		return this._anim(baseFx, "fadeOut", args); // dojo/_base/fx.Animation|dojo/NodeList
 	},
 
 	animateProperty: function(args){
@@ -147,13 +146,13 @@ lang.extend(NodeList, {
 		//		syntax identical to `dojo.animateProperty`
 		//
 		// args: Object?
-		//		Additional dojo.Animation arguments to mix into this set with the addition of
+		//		Additional dojo/_base/fx.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
-		// returns: dojo.Animation|dojo.NodeList
+		// returns: dojo/_base/fx.Animation|dojo/NodeList
 		//		A special args member `auto` can be passed to automatically play the animation.
-		//		If args.auto is present, the original dojo.NodeList will be returned for further
-		//		chaining. Otherwise the dojo.Animation instance is returned and must be .play()'ed
+		//		If args.auto is present, the original dojo/NodeList will be returned for further
+		//		chaining. Otherwise the dojo/_base/fx.Animation instance is returned and must be .play()'ed
 		//
 		// example:
 		//	|	dojo.query(".zork").animateProperty({
@@ -164,14 +163,14 @@ lang.extend(NodeList, {
 		//	|		}
 		//	|	}).play();
 		//
-		//	example:
+		// example:
 		//	|	dojo.query(".grue").animateProperty({
 		//	|		auto:true,
 		//	|		properties: {
 		//	|			height:240
 		//	|		}
 		//	|	}).onclick(handler);
-		return this._anim(baseFx, "animateProperty", args); // dojo.Animation|dojo.NodeList
+		return this._anim(baseFx, "animateProperty", args); // dojo/_base/fx.Animation|dojo/NodeList
 	},
 
 	anim: function( /*Object*/			properties,
@@ -212,9 +211,9 @@ lang.extend(NodeList, {
 			})
 		);
 		if(onEnd){
-			connectLib.connect(canim, "onEnd", onEnd);
+			aspect.after(canim, "onEnd", onEnd, true);
 		}
-		return canim.play(delay||0); // dojo.Animation
+		return canim.play(delay||0); // dojo/_base/fx.Animation
 	}
 });
 
diff --git a/dojo/NodeList-html.js b/dojo/NodeList-html.js
index 3c841da..bc5cc3d 100644
--- a/dojo/NodeList-html.js
+++ b/dojo/NodeList-html.js
@@ -1,38 +1,36 @@
-define(["./query", "./_base/lang", "./html"], function(query, lang, html) {
-	// module:
-	//		dojo/NodeList-html
-	// summary:
-	//		TODOC
+define(["./query", "./_base/lang", "./html"], function(query, lang, html){
 
-var NodeList = query.NodeList;
+// module:
+//		dojo/NodeList-html
 
 /*=====
-dojo["NodeList-html"] = {
-	// summary: Adds a chainable html method to dojo.query() / Nodelist instances for setting/replacing node content
+return function(){
+	// summary:
+	//		Adds a chainable html method to dojo.query() / NodeList instances for setting/replacing node content
 };
-
-// doc helper aliases:
-NodeList = dojo.NodeList;
 =====*/
 
+var NodeList = query.NodeList;
+
+
 lang.extend(NodeList, {
 	html: function(/* String|DomNode|NodeList? */ content, /* Object? */params){
-		//	summary:
-		//		see `dojo.html.set()`. Set the content of all elements of this NodeList
+		// summary:
+		//		see `dojo/html.set()`. Set the content of all elements of this NodeList
 		//
-		//	content:
+		// content:
 		//		An html string, node or enumerable list of nodes for insertion into the dom
 		//
-		//	params:
-		//		Optional flags/properties to configure the content-setting. See dojo.html._ContentSetter
+		// params:
+		//		Optional flags/properties to configure the content-setting. See dojo/html._ContentSetter
 		//
-		//	description:
-		//		Based around `dojo.html.set()`, set the content of the Elements in a
+		// description:
+		//		Based around `dojo/html.set()`, set the content of the Elements in a
 		//		NodeList to the given content (string/node/nodelist), with optional arguments
 		//		to further tune the set content behavior.
 		//
-		//	example:
-		//	| dojo.query(".thingList").html("<li dojoType='dojo.dnd.Moveable'>1</li><li dojoType='dojo.dnd.Moveable'>2</li><li dojoType='dojo.dnd.Moveable'>3</li>",
+		// example:
+		//	| query(".thingList").html("<li data-dojo-type='dojo/dnd/Moveable'>1</li><li data-dojo-type='dojo/dnd/Moveable'>2</li><li data-dojo-type='dojo/dnd/Moveable'>3</li>",
 		//	| {
 		//	| 	parseContent: true,
 		//	| 	onBegin: function(){
@@ -47,7 +45,7 @@ lang.extend(NodeList, {
 			dhs.set(content);
 			dhs.tearDown();
 		});
-		return this; // dojo.NodeList
+		return this; // dojo/NodeList
 	}
 });
 
diff --git a/dojo/NodeList-manipulate.js b/dojo/NodeList-manipulate.js
index 42f6dc7..eb36ccb 100644
--- a/dojo/NodeList-manipulate.js
+++ b/dojo/NodeList-manipulate.js
@@ -1,29 +1,25 @@
-define(["./query", "./_base/lang", "./_base/array", "./dom-construct", "./NodeList-dom"], function(dquery, lang, array, construct) {
+define(["./query", "./_base/lang", "./_base/array", "./dom-construct", "./NodeList-dom"], function(dquery, lang, array, construct){
 	// module:
 	//		dojo/NodeList-manipulate
-	// summary:
-	//		TODOC
 
-var NodeList = dquery.NodeList;
-
-/*=====
-dojo["NodeList-manipulate"] = {
-	// summary: Adds a chainable methods to dojo.query() / Nodelist instances for manipulating HTML
-	// and DOM nodes and their properties.
-};
+	/*=====
+	return function(){
+		// summary:
+		//		Adds chainable methods to dojo.query() / NodeList instances for manipulating HTML
+		//		and DOM nodes and their properties.
+	};
+	=====*/
 
-// doc alias helpers:
-NodeList = dojo.NodeList;
-=====*/
+	var NodeList = dquery.NodeList;
 
-//TODO: add a way to parse for widgets in the injected markup?
+	//TODO: add a way to parse for widgets in the injected markup?
 
 	function getText(/*DOMNode*/node){
 		// summary:
-		// 		recursion method for text() to use. Gets text value for a node.
+		//		recursion method for text() to use. Gets text value for a node.
 		// description:
-		// 		Juse uses nodedValue so things like <br/> tags do not end up in
-		// 		the text as any sort of line return.
+		//		Juse uses nodedValue so things like <br/> tags do not end up in
+		//		the text as any sort of line return.
 		var text = "", ch = node.childNodes;
 		for(var i = 0, n; n = ch[i]; i++){
 			//Skip comments.
@@ -40,7 +36,7 @@ NodeList = dojo.NodeList;
 
 	function getWrapInsertion(/*DOMNode*/node){
 		// summary:
-		// 		finds the innermost element to use for wrap insertion.
+		//		finds the innermost element to use for wrap insertion.
 
 		//Make it easy, assume single nesting, no siblings.
 		while(node.childNodes[0] && node.childNodes[0].nodeType == 1){
@@ -51,7 +47,7 @@ NodeList = dojo.NodeList;
 
 	function makeWrapNode(/*DOMNode||String*/html, /*DOMNode*/refNode){
 		// summary:
-		// 		convert HTML into nodes if it is not already a node.
+		//		convert HTML into nodes if it is not already a node.
 		if(typeof html == "string"){
 			html = construct.toDom(html, (refNode && refNode.ownerDocument));
 			if(html.nodeType == 11){
@@ -68,9 +64,9 @@ NodeList = dojo.NodeList;
 	lang.extend(NodeList, {
 		_placeMultiple: function(/*String||Node||NodeList*/query, /*String*/position){
 			// summary:
-			// 		private method for inserting queried nodes into all nodes in this NodeList
-			// 		at different positions. Differs from NodeList.place because it will clone
-			// 		the nodes in this NodeList if the query matches more than one element.
+			//		private method for inserting queried nodes into all nodes in this NodeList
+			//		at different positions. Differs from NodeList.place because it will clone
+			//		the nodes in this NodeList if the query matches more than one element.
 			var nl2 = typeof query == "string" || query.nodeType ? dquery(query) : query;
 			var toAdd = [];
 			for(var i = 0; i < nl2.length; i++){
@@ -102,42 +98,42 @@ NodeList = dojo.NodeList;
 				Array.prototype.splice.apply(this, toAdd);
 			}
 
-			return this; //dojo.NodeList
+			return this; // dojo/NodeList
 		},
 
-		innerHTML: function(/*String?||DOMNode?|NodeList?*/value){
+		innerHTML: function(/*String|DOMNode|NodeList?*/ value){
 			// summary:
-			// 		allows setting the innerHTML of each node in the NodeList,
-			// 		if there is a value passed in, otherwise, reads the innerHTML value of the first node.
+			//		allows setting the innerHTML of each node in the NodeList,
+			//		if there is a value passed in, otherwise, reads the innerHTML value of the first node.
 			// description:
-			// 		This method is simpler than the dojo.NodeList.html() method provided by
-			// 		`dojo.NodeList-html`. This method just does proper innerHTML insertion of HTML fragments,
-			// 		and it allows for the innerHTML to be read for the first node in the node list.
-			// 		Since dojo.NodeList-html already took the "html" name, this method is called
-			// 		"innerHTML". However, if dojo.NodeList-html has not been loaded yet, this
-			// 		module will define an "html" method that can be used instead. Be careful if you
-			// 		are working in an environment where it is possible that dojo.NodeList-html could
-			// 		have been loaded, since its definition of "html" will take precedence.
-			// 		The nodes represented by the value argument will be cloned if more than one
-			// 		node is in this NodeList. The nodes in this NodeList are returned in the "set"
-			// 		usage of this method, not the HTML that was inserted.
-			//	returns:
+			//		This method is simpler than the dojo/NodeList.html() method provided by
+			//		`dojo/NodeList-html`. This method just does proper innerHTML insertion of HTML fragments,
+			//		and it allows for the innerHTML to be read for the first node in the node list.
+			//		Since dojo/NodeList-html already took the "html" name, this method is called
+			//		"innerHTML". However, if dojo/NodeList-html has not been loaded yet, this
+			//		module will define an "html" method that can be used instead. Be careful if you
+			//		are working in an environment where it is possible that dojo/NodeList-html could
+			//		have been loaded, since its definition of "html" will take precedence.
+			//		The nodes represented by the value argument will be cloned if more than one
+			//		node is in this NodeList. The nodes in this NodeList are returned in the "set"
+			//		usage of this method, not the HTML that was inserted.
+			// returns:
 			//		if no value is passed, the result is String, the innerHTML of the first node.
-			//		If a value is passed, the return is this dojo.NodeList
-			//	example:
+			//		If a value is passed, the return is this dojo/NodeList
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div id="foo"></div>
 			//	|	<div id="bar"></div>
-			//		This code inserts <p>Hello World</p> into both divs:
+			//		This code inserts `<p>Hello World</p>` into both divs:
 			//	|	dojo.query("div").innerHTML("<p>Hello World</p>");
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div id="foo"><p>Hello Mars</p></div>
 			//	|	<div id="bar"><p>Hello World</p></div>
-			//		This code returns "<p>Hello Mars</p>":
+			//		This code returns `<p>Hello Mars</p>`:
 			//	|	var message = dojo.query("div").innerHTML();
 			if(arguments.length){
-				return this.addContent(value, "only"); //dojo.NodeList
+				return this.addContent(value, "only"); // dojo/NodeList
 			}else{
 				return this[0].innerHTML; //String
 			}
@@ -147,44 +143,43 @@ NodeList = dojo.NodeList;
 		html: function(value){
 			// summary:
 			//		see the information for "innerHTML". "html" is an alias for "innerHTML", but is
-			// 		only defined if dojo.NodeList-html has not been loaded.
+			//		only defined if dojo/NodeList-html has not been loaded.
 			// description:
-			// 		An alias for the "innerHTML" method, but only defined if there is not an existing
-			// 		"html" method on dojo.NodeList. Be careful if you are working in an environment
-			// 		where it is possible that dojo.NodeList-html could have been loaded, since its
-			// 		definition of "html" will take precedence. If you are not sure if dojo.NodeList-html
-			// 		could be loaded, use the "innerHTML" method.
-			//	value: String?||DOMNode?||NodeList?
-			//		optional. The HTML fragment to use as innerHTML. If value is not passed, then the innerHTML
-			// 		of the first element in this NodeList is returned.
-			//	returns:
+			//		An alias for the "innerHTML" method, but only defined if there is not an existing
+			//		"html" method on dojo/NodeList. Be careful if you are working in an environment
+			//		where it is possible that dojo/NodeList-html could have been loaded, since its
+			//		definition of "html" will take precedence. If you are not sure if dojo/NodeList-html
+			//		could be loaded, use the "innerHTML" method.
+			// value: String|DOMNode|NodeList?
+			//		The HTML fragment to use as innerHTML. If value is not passed, then the innerHTML
+			//		of the first element in this NodeList is returned.
+			// returns:
 			//		if no value is passed, the result is String, the innerHTML of the first node.
-			//		If a value is passed, the return is this dojo.NodeList
-			return; // dojo.NodeList
-			return; // String
+			//		If a value is passed, the return is this dojo/NodeList
+			return; // dojo/NodeList|String
 		},
 		=====*/
 
 		text: function(/*String*/value){
 			// summary:
-			// 		allows setting the text value of each node in the NodeList,
-			// 		if there is a value passed in, otherwise, returns the text value for all the
-			// 		nodes in the NodeList in one string.
-			//	example:
+			//		allows setting the text value of each node in the NodeList,
+			//		if there is a value passed in, otherwise, returns the text value for all the
+			//		nodes in the NodeList in one string.
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div id="foo"></div>
 			//	|	<div id="bar"></div>
 			//		This code inserts "Hello World" into both divs:
 			//	|	dojo.query("div").text("Hello World");
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div id="foo"><p>Hello Mars <span>today</span></p></div>
 			//	|	<div id="bar"><p>Hello World</p></div>
 			//		This code returns "Hello Mars today":
 			//	|	var message = dojo.query("div").text();
-			//	returns:
+			// returns:
 			//		if no value is passed, the result is String, the text value of the first node.
-			//		If a value is passed, the return is this dojo.NodeList
+			//		If a value is passed, the return is this dojo/NodeList
 			if(arguments.length){
 				for(var i = 0, node; node = this[i]; i++){
 					if(node.nodeType == 1){
@@ -192,7 +187,7 @@ NodeList = dojo.NodeList;
 						node.appendChild(node.ownerDocument.createTextNode(value));
 					}
 				}
-				return this; //dojo.NodeList
+				return this; // dojo/NodeList
 			}else{
 				var result = "";
 				for(i = 0; node = this[i]; i++){
@@ -204,15 +199,15 @@ NodeList = dojo.NodeList;
 
 		val: function(/*String||Array*/value){
 			// summary:
-			// 		If a value is passed, allows seting the value property of form elements in this
-			// 		NodeList, or properly selecting/checking the right value for radio/checkbox/select
-			// 		elements. If no value is passed, the value of the first node in this NodeList
-			// 		is returned.
-			//	returns:
+			//		If a value is passed, allows seting the value property of form elements in this
+			//		NodeList, or properly selecting/checking the right value for radio/checkbox/select
+			//		elements. If no value is passed, the value of the first node in this NodeList
+			//		is returned.
+			// returns:
 			//		if no value is passed, the result is String or an Array, for the value of the
 			//		first node.
-			//		If a value is passed, the return is this dojo.NodeList
-			//	example:
+			//		If a value is passed, the return is this dojo/NodeList
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<input type="text" value="foo">
 			//	|	<select multiple>
@@ -250,7 +245,7 @@ NodeList = dojo.NodeList;
 						node.value = newValue;
 					}
 				}
-				return this; //dojo.NodeList
+				return this; // dojo/NodeList
 			}else{
 				//node already declared above.
 				node = this[0];
@@ -281,15 +276,15 @@ NodeList = dojo.NodeList;
 
 		append: function(/*String||DOMNode||NodeList*/content){
 			// summary:
-			// 		appends the content to every node in the NodeList.
+			//		appends the content to every node in the NodeList.
 			// description:
-			// 		The content will be cloned if the length of NodeList
-			// 		is greater than 1. Only the DOM nodes are cloned, not
-			// 		any attached event handlers.
+			//		The content will be cloned if the length of NodeList
+			//		is greater than 1. Only the DOM nodes are cloned, not
+			//		any attached event handlers.
 			// returns:
-			//		dojo.NodeList, the nodes currently in this NodeList will be returned,
+			//		dojo/NodeList, the nodes currently in this NodeList will be returned,
 			//		not the appended content.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div id="foo"><p>Hello Mars</p></div>
 			//	|	<div id="bar"><p>Hello World</p></div>
@@ -298,21 +293,21 @@ NodeList = dojo.NodeList;
 			//		Results in this DOM structure:
 			//	|	<div id="foo"><p>Hello Mars</p><span>append</span></div>
 			//	|	<div id="bar"><p>Hello World</p><span>append</span></div>
-			return this.addContent(content, "last"); //dojo.NodeList
+			return this.addContent(content, "last"); // dojo/NodeList
 		},
 
 		appendTo: function(/*String*/query){
 			// summary:
-			// 		appends nodes in this NodeList to the nodes matched by
-			// 		the query passed to appendTo.
+			//		appends nodes in this NodeList to the nodes matched by
+			//		the query passed to appendTo.
 			// description:
-			// 		The nodes in this NodeList will be cloned if the query
-			// 		matches more than one element. Only the DOM nodes are cloned, not
-			// 		any attached event handlers.
+			//		The nodes in this NodeList will be cloned if the query
+			//		matches more than one element. Only the DOM nodes are cloned, not
+			//		any attached event handlers.
 			// returns:
-			//		dojo.NodeList, the nodes currently in this NodeList will be returned,
+			//		dojo/NodeList, the nodes currently in this NodeList will be returned,
 			//		not the matched nodes from the query.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<span>append</span>
 			//	|	<p>Hello Mars</p>
@@ -322,18 +317,18 @@ NodeList = dojo.NodeList;
 			//		Results in this DOM structure:
 			//	|	<p>Hello Mars<span>append</span></p>
 			//	|	<p>Hello World<span>append</span></p>
-			return this._placeMultiple(query, "last"); //dojo.NodeList
+			return this._placeMultiple(query, "last"); // dojo/NodeList
 		},
 
 		prepend: function(/*String||DOMNode||NodeList*/content){
 			// summary:
-			// 		prepends the content to every node in the NodeList.
+			//		prepends the content to every node in the NodeList.
 			// description:
-			// 		The content will be cloned if the length of NodeList
-			// 		is greater than 1. Only the DOM nodes are cloned, not
-			// 		any attached event handlers.
+			//		The content will be cloned if the length of NodeList
+			//		is greater than 1. Only the DOM nodes are cloned, not
+			//		any attached event handlers.
 			// returns:
-			//		dojo.NodeList, the nodes currently in this NodeList will be returned,
+			//		dojo/NodeList, the nodes currently in this NodeList will be returned,
 			//		not the appended content.
 			//		assume a DOM created by this markup:
 			//	|	<div id="foo"><p>Hello Mars</p></div>
@@ -343,21 +338,21 @@ NodeList = dojo.NodeList;
 			//		Results in this DOM structure:
 			//	|	<div id="foo"><span>prepend</span><p>Hello Mars</p></div>
 			//	|	<div id="bar"><span>prepend</span><p>Hello World</p></div>
-			return this.addContent(content, "first"); //dojo.NodeList
+			return this.addContent(content, "first"); // dojo/NodeList
 		},
 
 		prependTo: function(/*String*/query){
 			// summary:
-			// 		prepends nodes in this NodeList to the nodes matched by
-			// 		the query passed to prependTo.
+			//		prepends nodes in this NodeList to the nodes matched by
+			//		the query passed to prependTo.
 			// description:
-			// 		The nodes in this NodeList will be cloned if the query
-			// 		matches more than one element. Only the DOM nodes are cloned, not
-			// 		any attached event handlers.
+			//		The nodes in this NodeList will be cloned if the query
+			//		matches more than one element. Only the DOM nodes are cloned, not
+			//		any attached event handlers.
 			// returns:
-			//		dojo.NodeList, the nodes currently in this NodeList will be returned,
+			//		dojo/NodeList, the nodes currently in this NodeList will be returned,
 			//		not the matched nodes from the query.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<span>prepend</span>
 			//	|	<p>Hello Mars</p>
@@ -367,20 +362,20 @@ NodeList = dojo.NodeList;
 			//		Results in this DOM structure:
 			//	|	<p><span>prepend</span>Hello Mars</p>
 			//	|	<p><span>prepend</span>Hello World</p>
-			return this._placeMultiple(query, "first"); //dojo.NodeList
+			return this._placeMultiple(query, "first"); // dojo/NodeList
 		},
 
 		after: function(/*String||Element||NodeList*/content){
 			// summary:
-			// 		Places the content after every node in the NodeList.
+			//		Places the content after every node in the NodeList.
 			// description:
-			// 		The content will be cloned if the length of NodeList
-			// 		is greater than 1. Only the DOM nodes are cloned, not
-			// 		any attached event handlers.
+			//		The content will be cloned if the length of NodeList
+			//		is greater than 1. Only the DOM nodes are cloned, not
+			//		any attached event handlers.
 			// returns:
-			//		dojo.NodeList, the nodes currently in this NodeList will be returned,
+			//		dojo/NodeList, the nodes currently in this NodeList will be returned,
 			//		not the appended content.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div id="foo"><p>Hello Mars</p></div>
 			//	|	<div id="bar"><p>Hello World</p></div>
@@ -389,21 +384,21 @@ NodeList = dojo.NodeList;
 			//		Results in this DOM structure:
 			//	|	<div id="foo"><p>Hello Mars</p></div><span>after</span>
 			//	|	<div id="bar"><p>Hello World</p></div><span>after</span>
-			return this.addContent(content, "after"); //dojo.NodeList
+			return this.addContent(content, "after"); // dojo/NodeList
 		},
 
 		insertAfter: function(/*String*/query){
 			// summary:
-			// 		The nodes in this NodeList will be placed after the nodes
-			// 		matched by the query passed to insertAfter.
+			//		The nodes in this NodeList will be placed after the nodes
+			//		matched by the query passed to insertAfter.
 			// description:
-			// 		The nodes in this NodeList will be cloned if the query
-			// 		matches more than one element. Only the DOM nodes are cloned, not
-			// 		any attached event handlers.
+			//		The nodes in this NodeList will be cloned if the query
+			//		matches more than one element. Only the DOM nodes are cloned, not
+			//		any attached event handlers.
 			// returns:
-			//		dojo.NodeList, the nodes currently in this NodeList will be returned,
+			//		dojo/NodeList, the nodes currently in this NodeList will be returned,
 			//		not the matched nodes from the query.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<span>after</span>
 			//	|	<p>Hello Mars</p>
@@ -413,20 +408,20 @@ NodeList = dojo.NodeList;
 			//		Results in this DOM structure:
 			//	|	<p>Hello Mars</p><span>after</span>
 			//	|	<p>Hello World</p><span>after</span>
-			return this._placeMultiple(query, "after"); //dojo.NodeList
+			return this._placeMultiple(query, "after"); // dojo/NodeList
 		},
 
 		before: function(/*String||DOMNode||NodeList*/content){
 			// summary:
-			// 		Places the content before every node in the NodeList.
+			//		Places the content before every node in the NodeList.
 			// description:
-			// 		The content will be cloned if the length of NodeList
-			// 		is greater than 1. Only the DOM nodes are cloned, not
-			// 		any attached event handlers.
+			//		The content will be cloned if the length of NodeList
+			//		is greater than 1. Only the DOM nodes are cloned, not
+			//		any attached event handlers.
 			// returns:
-			//		dojo.NodeList, the nodes currently in this NodeList will be returned,
+			//		dojo/NodeList, the nodes currently in this NodeList will be returned,
 			//		not the appended content.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div id="foo"><p>Hello Mars</p></div>
 			//	|	<div id="bar"><p>Hello World</p></div>
@@ -435,21 +430,21 @@ NodeList = dojo.NodeList;
 			//		Results in this DOM structure:
 			//	|	<span>before</span><div id="foo"><p>Hello Mars</p></div>
 			//	|	<span>before</span><div id="bar"><p>Hello World</p></div>
-			return this.addContent(content, "before"); //dojo.NodeList
+			return this.addContent(content, "before"); // dojo/NodeList
 		},
 
 		insertBefore: function(/*String*/query){
 			// summary:
-			// 		The nodes in this NodeList will be placed after the nodes
-			// 		matched by the query passed to insertAfter.
+			//		The nodes in this NodeList will be placed after the nodes
+			//		matched by the query passed to insertAfter.
 			// description:
-			// 		The nodes in this NodeList will be cloned if the query
-			// 		matches more than one element. Only the DOM nodes are cloned, not
-			// 		any attached event handlers.
+			//		The nodes in this NodeList will be cloned if the query
+			//		matches more than one element. Only the DOM nodes are cloned, not
+			//		any attached event handlers.
 			// returns:
-			//		dojo.NodeList, the nodes currently in this NodeList will be returned,
+			//		dojo/NodeList, the nodes currently in this NodeList will be returned,
 			//		not the matched nodes from the query.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<span>before</span>
 			//	|	<p>Hello Mars</p>
@@ -459,38 +454,37 @@ NodeList = dojo.NodeList;
 			//		Results in this DOM structure:
 			//	|	<span>before</span><p>Hello Mars</p>
 			//	|	<span>before</span><p>Hello World</p>
-			return this._placeMultiple(query, "before"); //dojo.NodeList
+			return this._placeMultiple(query, "before"); // dojo/NodeList
 		},
 
 		/*=====
 		remove: function(simpleFilter){
-			//	summary:
-			//		alias for dojo.NodeList's orphan method. Removes elements
-			// 		in this list that match the simple filter from their parents
-			// 		and returns them as a new NodeList.
-			//	simpleFilter: String
+			// summary:
+			//		alias for dojo/NodeList's orphan method. Removes elements
+			//		in this list that match the simple filter from their parents
+			//		and returns them as a new NodeList.
+			// simpleFilter: String
 			//		single-expression CSS rule. For example, ".thinger" or
 			//		"#someId[attrName='value']" but not "div > span". In short,
 			//		anything which does not invoke a descent to evaluate but
 			//		can instead be used to test a single node is acceptable.
-			//	returns:
-			//		dojo.NodeList
-			return; // dojo.NodeList
+
+			return; // dojo/NodeList
 		},
 		=====*/
 		remove: NodeList.prototype.orphan,
 
 		wrap: function(/*String||DOMNode*/html){
 			// summary:
-			// 		Wrap each node in the NodeList with html passed to wrap.
+			//		Wrap each node in the NodeList with html passed to wrap.
 			// description:
-			// 		html will be cloned if the NodeList has more than one
-			// 		element. Only DOM nodes are cloned, not any attached
-			// 		event handlers.
+			//		html will be cloned if the NodeList has more than one
+			//		element. Only DOM nodes are cloned, not any attached
+			//		event handlers.
 			// returns:
-			//		dojo.NodeList, the nodes in the current NodeList will be returned,
+			//		the nodes in the current NodeList will be returned,
 			//		not the nodes from html argument.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<b>one</b>
 			//	|	<b>two</b>
@@ -516,17 +510,17 @@ NodeList = dojo.NodeList;
 					insertion.appendChild(node);
 				}
 			}
-			return this; //dojo.NodeList
+			return this; // dojo/NodeList
 		},
 
 		wrapAll: function(/*String||DOMNode*/html){
 			// summary:
-			// 		Insert html where the first node in this NodeList lives, then place all
-			// 		nodes in this NodeList as the child of the html.
+			//		Insert html where the first node in this NodeList lives, then place all
+			//		nodes in this NodeList as the child of the html.
 			// returns:
-			//		dojo.NodeList, the nodes in the current NodeList will be returned,
+			//		the nodes in the current NodeList will be returned,
 			//		not the nodes from html argument.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div class="container">
 			// 	|		<div class="red">Red One</div>
@@ -558,20 +552,20 @@ NodeList = dojo.NodeList;
 					insertion.appendChild(node);
 				}
 			}
-			return this; //dojo.NodeList
+			return this; // dojo/NodeList
 		},
 
 		wrapInner: function(/*String||DOMNode*/html){
 			// summary:
-			// 		For each node in the NodeList, wrap all its children with the passed in html.
+			//		For each node in the NodeList, wrap all its children with the passed in html.
 			// description:
-			// 		html will be cloned if the NodeList has more than one
-			// 		element. Only DOM nodes are cloned, not any attached
-			// 		event handlers.
+			//		html will be cloned if the NodeList has more than one
+			//		element. Only DOM nodes are cloned, not any attached
+			//		event handlers.
 			// returns:
-			//		dojo.NodeList, the nodes in the current NodeList will be returned,
+			//		the nodes in the current NodeList will be returned,
 			//		not the nodes from html argument.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div class="container">
 			// 	|		<div class="red">Red One</div>
@@ -601,20 +595,20 @@ NodeList = dojo.NodeList;
 					this._wrap(lang._toArray(this[i].childNodes), null, this._NodeListCtor).wrapAll(clone);
 				}
 			}
-			return this; //dojo.NodeList
+			return this; // dojo/NodeList
 		},
 
 		replaceWith: function(/*String||DOMNode||NodeList*/content){
 			// summary:
-			// 		Replaces each node in ths NodeList with the content passed to replaceWith.
+			//		Replaces each node in ths NodeList with the content passed to replaceWith.
 			// description:
-			// 		The content will be cloned if the length of NodeList
-			// 		is greater than 1. Only the DOM nodes are cloned, not
-			// 		any attached event handlers.
+			//		The content will be cloned if the length of NodeList
+			//		is greater than 1. Only the DOM nodes are cloned, not
+			//		any attached event handlers.
 			// returns:
 			//		The nodes currently in this NodeList will be returned, not the replacing content.
 			//		Note that the returned nodes have been removed from the DOM.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div class="container">
 			// 	|		<div class="red">Red One</div>
@@ -636,22 +630,22 @@ NodeList = dojo.NodeList;
 				this._place(content, node, "before", i > 0);
 				node.parentNode.removeChild(node);
 			}
-			return this; //dojo.NodeList
+			return this; // dojo/NodeList
 		},
 
 		replaceAll: function(/*String*/query){
 			// summary:
-			// 		replaces nodes matched by the query passed to replaceAll with the nodes
-			// 		in this NodeList.
+			//		replaces nodes matched by the query passed to replaceAll with the nodes
+			//		in this NodeList.
 			// description:
-			// 		The nodes in this NodeList will be cloned if the query
-			// 		matches more than one element. Only the DOM nodes are cloned, not
-			// 		any attached event handlers.
+			//		The nodes in this NodeList will be cloned if the query
+			//		matches more than one element. Only the DOM nodes are cloned, not
+			//		any attached event handlers.
 			// returns:
 			//		The nodes currently in this NodeList will be returned, not the matched nodes
 			//		from the query. The nodes currently in this NodeLIst could have
 			//		been cloned, so the returned NodeList will include the cloned nodes.
-			//	example:
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div class="container">
 			// 	|		<div class="spacer">___</div>
@@ -682,17 +676,17 @@ NodeList = dojo.NodeList;
 				this._place(content, node, "before", i > 0);
 				node.parentNode.removeChild(node);
 			}
-			return this; //dojo.NodeList
+			return this; // dojo/NodeList
 		},
 
 		clone: function(){
 			// summary:
-			// 		Clones all the nodes in this NodeList and returns them as a new NodeList.
+			//		Clones all the nodes in this NodeList and returns them as a new NodeList.
 			// description:
-			// 		Only the DOM nodes are cloned, not any attached event handlers.
+			//		Only the DOM nodes are cloned, not any attached event handlers.
 			// returns:
-			//		dojo.NodeList, a cloned set of the original nodes.
-			//	example:
+			//		a cloned set of the original nodes.
+			// example:
 			//		assume a DOM created by this markup:
 			//	|	<div class="container">
 			// 	|		<div class="red">Red One</div>
@@ -717,7 +711,7 @@ NodeList = dojo.NodeList;
 			for(var i = 0; i < this.length; i++){
 				ary.push(this._cloneNode(this[i]));
 			}
-			return this._wrap(ary, this, this._NodeListCtor); //dojo.NodeList
+			return this._wrap(ary, this, this._NodeListCtor); // dojo/NodeList
 		}
 	});
 
@@ -726,5 +720,5 @@ NodeList = dojo.NodeList;
 		NodeList.prototype.html = NodeList.prototype.innerHTML;
 	}
 
-return NodeList;
+	return NodeList;
 });
diff --git a/dojo/NodeList-traverse.js b/dojo/NodeList-traverse.js
index c609849..bf36ae9 100644
--- a/dojo/NodeList-traverse.js
+++ b/dojo/NodeList-traverse.js
@@ -1,26 +1,23 @@
-define(["./query", "./_base/lang", "./_base/array"], function(dquery, lang, array) {
-	// module:
-	//		dojo/NodeList-traverse
-	// summary:
-	//		TODOC
+define(["./query", "./_base/lang", "./_base/array"], function(dquery, lang, array){
 
-var NodeList = dquery.NodeList;
+// module:
+//		dojo/NodeList-traverse
 
 /*=====
-dojo["NodeList-traverse"] = {
-	// summary: Adds a chainable methods to dojo.query() / Nodelist instances for traversing the DOM
+return function(){
+	// summary:
+	//		Adds chainable methods to dojo.query() / NodeList instances for traversing the DOM
 };
-
-// doc alias helpers:
-NodeList = dojo.NodeList;
 =====*/
 
+var NodeList = dquery.NodeList;
+
 lang.extend(NodeList, {
-	_buildArrayFromCallback: function(/*Function*/callback){
+	_buildArrayFromCallback: function(/*Function*/ callback){
 		// summary:
-		// 		builds a new array of possibly differing size based on the input list.
-		// 		Since the returned array is likely of different size than the input array,
-		// 		the array's map function cannot be used.
+		//		builds a new array of possibly differing size based on the input list.
+		//		Since the returned array is likely of different size than the input array,
+		//		the array's map function cannot be used.
 		var ary = [];
 		for(var i = 0; i < this.length; i++){
 			var items = callback.call(this[i], this[i], ary);
@@ -33,9 +30,9 @@ lang.extend(NodeList, {
 
 	_getUniqueAsNodeList: function(/*Array*/ nodes){
 		// summary:
-		// 		given a list of nodes, make sure only unique
-		// 		elements are returned as our NodeList object.
-		// 		Does not call _stash().
+		//		given a list of nodes, make sure only unique
+		//		elements are returned as our NodeList object.
+		//		Does not call _stash().
 		var ary = [];
 		//Using for loop for better speed.
 		for(var i = 0, node; node = nodes[i]; i++){
@@ -46,39 +43,39 @@ lang.extend(NodeList, {
 				ary.push(node);
 			}
 		}
-		return this._wrap(ary, null, this._NodeListCtor);	 //dojo.NodeList
+		return this._wrap(ary, null, this._NodeListCtor);	 // dojo/NodeList
 	},
 
 	_getUniqueNodeListWithParent: function(/*Array*/ nodes, /*String*/ query){
 		// summary:
-		// 		gets unique element nodes, filters them further
-		// 		with an optional query and then calls _stash to track parent NodeList.
+		//		gets unique element nodes, filters them further
+		//		with an optional query and then calls _stash to track parent NodeList.
 		var ary = this._getUniqueAsNodeList(nodes);
 		ary = (query ? dquery._filterResult(ary, query) : ary);
-		return ary._stash(this);  //dojo.NodeList
+		return ary._stash(this);  // dojo/NodeList
 	},
 
 	_getRelatedUniqueNodes: function(/*String?*/ query, /*Function*/ callback){
 		// summary:
-		// 		cycles over all the nodes and calls a callback
-		// 		to collect nodes for a possible inclusion in a result.
-		// 		The callback will get two args: callback(node, ary),
-		// 		where ary is the array being used to collect the nodes.
-		return this._getUniqueNodeListWithParent(this._buildArrayFromCallback(callback), query);  //dojo.NodeList
+		//		cycles over all the nodes and calls a callback
+		//		to collect nodes for a possible inclusion in a result.
+		//		The callback will get two args: callback(node, ary),
+		//		where ary is the array being used to collect the nodes.
+		return this._getUniqueNodeListWithParent(this._buildArrayFromCallback(callback), query);  // dojo/NodeList
 	},
 
 	children: function(/*String?*/ query){
 		// summary:
-		// 		Returns all immediate child elements for nodes in this dojo.NodeList.
-		// 		Optionally takes a query to filter the child elements.
+		//		Returns all immediate child elements for nodes in this dojo/NodeList.
+		//		Optionally takes a query to filter the child elements.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
 		// query:
 		//		a CSS selector.
 		// returns:
-		//		dojo.NodeList, all immediate child elements for the nodes in this dojo.NodeList.
-		//	example:
+		//		all immediate child elements for the nodes in this dojo/NodeList.
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="red">Red One</div>
@@ -95,23 +92,23 @@ lang.extend(NodeList, {
 		//		returns the two divs that have the class "red".
 		return this._getRelatedUniqueNodes(query, function(node, ary){
 			return lang._toArray(node.childNodes);
-		}); //dojo.NodeList
+		}); // dojo/NodeList
 	},
 
 	closest: function(/*String*/ query, /*String|DOMNode?*/ root){
 		// summary:
-		// 		Returns closest parent that matches query, including current node in this
-		// 		dojo.NodeList if it matches the query.
+		//		Returns closest parent that matches query, including current node in this
+		//		dojo/NodeList if it matches the query.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
 		// query:
 		//		a CSS selector.
 		// root:
 		//		If specified, query is relative to "root" rather than document body.
 		// returns:
-		//		dojo.NodeList, the closest parent that matches the query, including the current
-		//		node in this dojo.NodeList if it matches the query.
+		//		the closest parent that matches the query, including the current
+		//		node in this dojo/NodeList if it matches the query.
 		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
@@ -131,21 +128,21 @@ lang.extend(NodeList, {
 				}
 			}while(node != root && (node = node.parentNode) && node.nodeType == 1);
 			return null; //To make rhino strict checking happy.
-		}); //dojo.NodeList
+		}); // dojo/NodeList
 	},
 
 	parent: function(/*String?*/ query){
 		// summary:
-		// 		Returns immediate parent elements for nodes in this dojo.NodeList.
-		// 		Optionally takes a query to filter the parent elements.
+		//		Returns immediate parent elements for nodes in this dojo/NodeList.
+		//		Optionally takes a query to filter the parent elements.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
-		//	query:
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
+		// query:
 		//		a CSS selector.
 		// returns:
-		//		dojo.NodeList, immediate parent elements for nodes in this dojo.NodeList.
-		//	example:
+		//		immediate parent elements for nodes in this dojo/NodeList.
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="red">Red One</div>
@@ -161,21 +158,21 @@ lang.extend(NodeList, {
 		//		returns the one div with class "blue" and "first".
 		return this._getRelatedUniqueNodes(query, function(node, ary){
 			return node.parentNode;
-		}); //dojo.NodeList
+		}); // dojo/NodeList
 	},
 
 	parents: function(/*String?*/ query){
 		// summary:
-		// 		Returns all parent elements for nodes in this dojo.NodeList.
-		// 		Optionally takes a query to filter the child elements.
+		//		Returns all parent elements for nodes in this dojo/NodeList.
+		//		Optionally takes a query to filter the child elements.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
-		//	query:
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
+		// query:
 		//		a CSS selector.
 		// returns:
-		//		dojo.NodeList, all parent elements for nodes in this dojo.NodeList.
-		//	example:
+		//		all parent elements for nodes in this dojo/NodeList.
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="red">Red One</div>
@@ -197,21 +194,21 @@ lang.extend(NodeList, {
 				pary.push(node);
 			}
 			return pary;
-		}); //dojo.NodeList
+		}); // dojo/NodeList
 	},
 
 	siblings: function(/*String?*/ query){
 		// summary:
-		// 		Returns all sibling elements for nodes in this dojo.NodeList.
-		// 		Optionally takes a query to filter the sibling elements.
+		//		Returns all sibling elements for nodes in this dojo/NodeList.
+		//		Optionally takes a query to filter the sibling elements.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
-		//	query:
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
+		// query:
 		//		a CSS selector.
 		// returns:
-		//		dojo.NodeList, all sibling elements for nodes in this dojo.NodeList.
-		//	example:
+		//		all sibling elements for nodes in this dojo/NodeList.
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="red">Red One</div>
@@ -236,21 +233,21 @@ lang.extend(NodeList, {
 				}
 			}
 			return pary;
-		}); //dojo.NodeList
+		}); // dojo/NodeList
 	},
 
 	next: function(/*String?*/ query){
 		// summary:
-		// 		Returns the next element for nodes in this dojo.NodeList.
-		// 		Optionally takes a query to filter the next elements.
+		//		Returns the next element for nodes in this dojo/NodeList.
+		//		Optionally takes a query to filter the next elements.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
-		//	query:
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
+		// query:
 		//		a CSS selector.
 		// returns:
-		//		dojo.NodeList, the next element for nodes in this dojo.NodeList.
-		//	example:
+		//		the next element for nodes in this dojo/NodeList.
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="red">Red One</div>
@@ -271,21 +268,21 @@ lang.extend(NodeList, {
 				next = next.nextSibling;
 			}
 			return next;
-		}); //dojo.NodeList
+		}); // dojo/NodeList
 	},
 
 	nextAll: function(/*String?*/ query){
 		// summary:
-		// 		Returns all sibling elements that come after the nodes in this dojo.NodeList.
-		// 		Optionally takes a query to filter the sibling elements.
+		//		Returns all sibling elements that come after the nodes in this dojo/NodeList.
+		//		Optionally takes a query to filter the sibling elements.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
-		//	query:
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
+		// query:
 		//		a CSS selector.
 		// returns:
-		//		dojo.NodeList, all sibling elements that come after the nodes in this dojo.NodeList.
-		//	example:
+		//		all sibling elements that come after the nodes in this dojo/NodeList.
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="red">Red One</div>
@@ -309,21 +306,21 @@ lang.extend(NodeList, {
 				}
 			}
 			return pary;
-		}); //dojo.NodeList
+		}); // dojo/NodeList
 	},
 
 	prev: function(/*String?*/ query){
 		// summary:
-		// 		Returns the previous element for nodes in this dojo.NodeList.
-		// 		Optionally takes a query to filter the previous elements.
+		//		Returns the previous element for nodes in this dojo/NodeList.
+		//		Optionally takes a query to filter the previous elements.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
-		//	query:
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
+		// query:
 		//		a CSS selector.
 		// returns:
-		//		dojo.NodeList, the previous element for nodes in this dojo.NodeList.
-		//	example:
+		//		the previous element for nodes in this dojo/NodeList.
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="red">Red One</div>
@@ -344,23 +341,23 @@ lang.extend(NodeList, {
 				prev = prev.previousSibling;
 			}
 			return prev;
-		}); //dojo.NodeList
+		}); // dojo/NodeList
 	},
 
 	prevAll: function(/*String?*/ query){
 		// summary:
-		// 		Returns all sibling elements that come before the nodes in this dojo.NodeList.
-		// 		Optionally takes a query to filter the sibling elements.
+		//		Returns all sibling elements that come before the nodes in this dojo/NodeList.
+		//		Optionally takes a query to filter the sibling elements.
 		// description:
-		// 		The returned nodes will be in reverse DOM order -- the first node in the list will
-		// 		be the node closest to the original node/NodeList.
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
-		//	query:
+		//		The returned nodes will be in reverse DOM order -- the first node in the list will
+		//		be the node closest to the original node/NodeList.
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
+		// query:
 		//		a CSS selector.
 		// returns:
-		//		dojo.NodeList, all sibling elements that come before the nodes in this dojo.NodeList.
-		//	example:
+		//		all sibling elements that come before the nodes in this dojo/NodeList.
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="red prev">Red One</div>
@@ -384,18 +381,16 @@ lang.extend(NodeList, {
 				}
 			}
 			return pary;
-		}); //dojo.NodeList
+		}); // dojo/NodeList
 	},
 
 	andSelf: function(){
 		// summary:
-		// 		Adds the nodes from the previous dojo.NodeList to the current dojo.NodeList.
+		//		Adds the nodes from the previous dojo/NodeList to the current dojo/NodeList.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
-		// returns:
-		//		dojo.NodeList
-		//	example:
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="red prev">Red One</div>
@@ -407,19 +402,19 @@ lang.extend(NodeList, {
 		//		Running this code:
 		//	|	dojo.query(".second").prevAll().andSelf();
 		//		returns the two divs with class of "prev", as well as the div with class "second".
-		return this.concat(this._parent);	//dojo.NodeList
+		return this.concat(this._parent);	// dojo/NodeList
 	},
 
 	//Alternate methods for the :first/:last/:even/:odd pseudos.
 	first: function(){
 		// summary:
-		// 		Returns the first node in this dojo.NodeList as a dojo.NodeList.
+		//		Returns the first node in this dojo/NodeList as a dojo/NodeList.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
 		// returns:
-		//		dojo.NodeList, with the first node in this dojo.NodeList
-		//	example:
+		//		the first node in this dojo/NodeList
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="red">Red One</div>
@@ -430,18 +425,18 @@ lang.extend(NodeList, {
 		//		Running this code:
 		//	|	dojo.query(".blue").first();
 		//		returns the div with class "blue" and "first".
-		return this._wrap(((this[0] && [this[0]]) || []), this); //dojo.NodeList
+		return this._wrap(((this[0] && [this[0]]) || []), this); // dojo/NodeList
 	},
 
 	last: function(){
 		// summary:
-		// 		Returns the last node in this dojo.NodeList as a dojo.NodeList.
+		//		Returns the last node in this dojo/NodeList as a dojo/NodeList.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
 		// returns:
-		//		dojo.NodeList, with the last node in this dojo.NodeList
-		//	example:
+		//		the last node in this dojo/NodeList
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="red">Red One</div>
@@ -452,18 +447,18 @@ lang.extend(NodeList, {
 		//		Running this code:
 		//	|	dojo.query(".blue").last();
 		//		returns the last div with class "blue",
-		return this._wrap((this.length ? [this[this.length - 1]] : []), this); //dojo.NodeList
+		return this._wrap((this.length ? [this[this.length - 1]] : []), this); // dojo/NodeList
 	},
 
 	even: function(){
 		// summary:
-		// 		Returns the even nodes in this dojo.NodeList as a dojo.NodeList.
+		//		Returns the even nodes in this dojo/NodeList as a dojo/NodeList.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
 		// returns:
-		//		dojo.NodeList, with the even nodes in this dojo.NodeList
-		//	example:
+		//		the even nodes in this dojo/NodeList
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="interior red">Red One</div>
@@ -476,18 +471,18 @@ lang.extend(NodeList, {
 		//		returns the two divs with class "blue"
 		return this.filter(function(item, i){
 			return i % 2 != 0;
-		}); //dojo.NodeList
+		}); // dojo/NodeList
 	},
 
 	odd: function(){
 		// summary:
-		// 		Returns the odd nodes in this dojo.NodeList as a dojo.NodeList.
+		//		Returns the odd nodes in this dojo/NodeList as a dojo/NodeList.
 		// description:
-		// 		.end() can be used on the returned dojo.NodeList to get back to the
-		// 		original dojo.NodeList.
+		//		.end() can be used on the returned dojo/NodeList to get back to the
+		//		original dojo/NodeList.
 		// returns:
-		//		dojo.NodeList, with the odd nodes in this dojo.NodeList
-		//	example:
+		//		the odd nodes in this dojo/NodeList
+		// example:
 		//		assume a DOM created by this markup:
 		//	|	<div class="container">
 		// 	|		<div class="interior red">Red One</div>
@@ -500,7 +495,7 @@ lang.extend(NodeList, {
 		//		returns the two divs with class "red"
 		return this.filter(function(item, i){
 			return i % 2 == 0;
-		}); //dojo.NodeList
+		}); // dojo/NodeList
 	}
 });
 
diff --git a/dojo/NodeList.js b/dojo/NodeList.js
new file mode 100644
index 0000000..1f6d256
--- /dev/null
+++ b/dojo/NodeList.js
@@ -0,0 +1,6 @@
+define(["./query"], function(query){
+	// This class is just for documentation purposes, so NodeList shows up well in the API viewer,
+	// and to simplify writing API doc for all the methods that take NodeList as a parameter, or return a NodeList.
+	return query.NodeList;
+});
+
diff --git a/dojo/OpenAjax.js b/dojo/OpenAjax.js
index 0733641..0b3c891 100644
--- a/dojo/OpenAjax.js
+++ b/dojo/OpenAjax.js
@@ -21,13 +21,12 @@
 // prevent re-definition of the OpenAjax object
 if(!window["OpenAjax"]){
 	OpenAjax = new function(){
-		// summary: the OpenAjax hub
-		// description: see http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification
+		// summary:
+		//		the OpenAjax hub
+		// description:
+		//		see http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification
 
-		var t = true;
-		var f = false;
-		var g = window;
-		var libs;
+		var libs = {};
 		var ooh = "org.openajax.hub.";
 
 		var h = {};
@@ -36,7 +35,6 @@ if(!window["OpenAjax"]){
 		h.implVersion = "0.6";
 		h.specVersion = "0.6";
 		h.implExtraData = {};
-		var libs = {};
 		h.libraries = libs;
 
 		h.registerLibrary = function(prefix, nsURL, version, extra){
@@ -99,10 +97,8 @@ if(!window["OpenAjax"]){
 				}
 				if(typeof tree.c[token] == "undefined"){
 					tree.c[token] = { c: {}, s: [] };
-					this._subscribe(tree.c[token], path, index + 1, sub);
-				}else{
-					this._subscribe(tree.c[token], path, index + 1, sub);
 				}
+				this._subscribe(tree.c[token], path, index + 1, sub);
 			}
 		};
 
@@ -158,7 +154,7 @@ if(!window["OpenAjax"]){
 				else{
 					var callbacks = tree.s;
 					var max = callbacks.length;
-					for(var i = 0; i < max; i++)
+					for(var i = 0; i < max; i++){
 						if(sid == callbacks[i].sid){
 							if(this._pubDepth > 0){
 								callbacks[i].cb = null;
@@ -168,14 +164,15 @@ if(!window["OpenAjax"]){
 								callbacks.splice(i, 1);
 							return;
 						}
+					}
 				}
 			}
 		};
+
 		// The following function is provided for automatic testing purposes.
 		// It is not expected to be deployed in run-time OpenAjax Hub implementations.
-		h.reinit = function()
-		{
-			for (var lib in OpenAjax.hub.libraries) {
+		h.reinit = function(){
+			for (var lib in OpenAjax.hub.libraries){
 				delete OpenAjax.hub.libraries[lib];
 			}
 			OpenAjax.hub.registerLibrary("OpenAjax", "http://openajax.org/hub", "0.6", {});
@@ -186,8 +183,9 @@ if(!window["OpenAjax"]){
 			OpenAjax._cleanup = [];
 			OpenAjax._subIndex = 0;
 			OpenAjax._pubDepth = 0;
-		}
+		};
 	};
+
 	// Register the OpenAjax Hub itself as a library.
 	OpenAjax.hub.registerLibrary("OpenAjax", "http://openajax.org/hub", "0.6", {});
 
diff --git a/dojo/Stateful.js b/dojo/Stateful.js
index eb5afa9..b839a86 100644
--- a/dojo/Stateful.js
+++ b/dojo/Stateful.js
@@ -1,56 +1,89 @@
-define(["./_base/kernel", "./_base/declare", "./_base/lang", "./_base/array"], function(dojo, declare, lang, array) {
+define(["./_base/declare", "./_base/lang", "./_base/array", "./when"], function(declare, lang, array, when){
 	// module:
 	//		dojo/Stateful
-	// summary:
-	//		TODOC
 
-return dojo.declare("dojo.Stateful", null, {
+return declare("dojo.Stateful", null, {
 	// summary:
 	//		Base class for objects that provide named properties with optional getter/setter
 	//		control and the ability to watch for property changes
+	//
+	//		The class also provides the functionality to auto-magically manage getters
+	//		and setters for object attributes/properties.
+	//		
+	//		Getters and Setters should follow the format of _xxxGetter or _xxxSetter where 
+	//		the xxx is a name of the attribute to handle.  So an attribute of "foo" 
+	//		would have a custom getter of _fooGetter and a custom setter of _fooSetter.
+	//
 	// example:
 	//	|	var obj = new dojo.Stateful();
 	//	|	obj.watch("foo", function(){
 	//	|		console.log("foo changed to " + this.get("foo"));
 	//	|	});
 	//	|	obj.set("foo","bar");
-	postscript: function(mixin){
-		if(mixin){
-			lang.mixin(this, mixin);
-		}
+
+	// _attrPairNames: Hash
+	//		Used across all instances a hash to cache attribute names and their getter 
+	//		and setter names.
+	_attrPairNames: {},
+
+	_getAttrNames: function(name){
+		// summary:
+		//		Helper function for get() and set().
+		//		Caches attribute name values so we don't do the string ops every time.
+		// tags:
+		//		private
+
+		var apn = this._attrPairNames;
+		if(apn[name]){ return apn[name]; }
+		return (apn[name] = {
+			s: "_" + name + "Setter",
+			g: "_" + name + "Getter"
+		});
+	},
+
+	postscript: function(/*Object?*/ params){
+		// Automatic setting of params during construction
+		if (params){ this.set(params); }
 	},
 
+	_get: function(name, names){
+		// summary:
+		//		Private function that does a get based off a hash of names
+		// names:
+		//		Hash of names of custom attributes
+		return typeof this[names.g] === "function" ? this[names.g]() : this[name];
+	},
 	get: function(/*String*/name){
 		// summary:
 		//		Get a property on a Stateful instance.
-		//	name:
+		// name:
 		//		The property to get.
-		//	returns:
+		// returns:
 		//		The property value on this Stateful instance.
 		// description:
 		//		Get a named property on a Stateful object. The property may
 		//		potentially be retrieved via a getter method in subclasses. In the base class
-		// 		this just retrieves the object's property.
-		// 		For example:
+		//		this just retrieves the object's property.
+		//		For example:
 		//	|	stateful = new dojo.Stateful({foo: 3});
 		//	|	stateful.get("foo") // returns 3
 		//	|	stateful.foo // returns 3
 
-		return this[name]; //Any
+		return this._get(name, this._getAttrNames(name)); //Any
 	},
 	set: function(/*String*/name, /*Object*/value){
 		// summary:
 		//		Set a property on a Stateful instance
-		//	name:
+		// name:
 		//		The property to set.
-		//	value:
+		// value:
 		//		The value to set in the property.
-		//	returns:
+		// returns:
 		//		The function returns this dojo.Stateful instance.
 		// description:
 		//		Sets named properties on a stateful object and notifies any watchers of
-		// 		the property. A programmatic setter may be defined in subclasses.
-		// 		For example:
+		//		the property. A programmatic setter may be defined in subclasses.
+		//		For example:
 		//	|	stateful = new dojo.Stateful();
 		//	|	stateful.watch(function(name, oldValue, value){
 		//	|		// this will be called on the set below
@@ -63,35 +96,75 @@ return dojo.declare("dojo.Stateful", null, {
 		//	|		bar: 3
 		//	|	})
 		//	This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
+
+		// If an object is used, iterate through object
 		if(typeof name === "object"){
 			for(var x in name){
-				this.set(x, name[x]);
+				if(name.hasOwnProperty(x) && x !="_watchCallbacks"){
+					this.set(x, name[x]);
+				}
 			}
 			return this;
 		}
-		var oldValue = this[name];
+
+		var names = this._getAttrNames(name),
+			oldValue = this._get(name, names),
+			setter = this[names.s],
+			result;
+		if(typeof setter === "function"){
+			// use the explicit setter
+			result = setter.apply(this, Array.prototype.slice.call(arguments, 1));
+		}else{
+			// no setter so set attribute directly
+			this[name] = value;
+		}
+		if(this._watchCallbacks){
+			var self = this;
+			// If setter returned a promise, wait for it to complete, otherwise call watches immediatly
+			when(result, function(){
+				self._watchCallbacks(name, oldValue, value);
+			});
+		}
+		return this; // dojo/Stateful
+	},
+	_changeAttrValue: function(name, value){
+		// summary:
+		//		Internal helper for directly changing an attribute value.
+		//
+		// name: String
+		//		The property to set.
+		// value: Mixed
+		//		The value to set in the property.
+		//
+		// description:
+		//		Directly change the value of an attribute on an object, bypassing any 
+		//		accessor setter.  Also handles the calling of watch and emitting events. 
+		//		It is designed to be used by descendent class when there are two values 
+		//		of attributes that are linked, but calling .set() is not appropriate.
+
+		var oldValue = this.get(name);
 		this[name] = value;
 		if(this._watchCallbacks){
 			this._watchCallbacks(name, oldValue, value);
 		}
-		return this; //dojo.Stateful
+		return this; // dojo/Stateful
 	},
 	watch: function(/*String?*/name, /*Function*/callback){
 		// summary:
 		//		Watches a property for changes
-		//	name:
+		// name:
 		//		Indicates the property to watch. This is optional (the callback may be the
-		// 		only parameter), and if omitted, all the properties will be watched
+		//		only parameter), and if omitted, all the properties will be watched
 		// returns:
 		//		An object handle for the watch. The unwatch method of this object
-		// 		can be used to discontinue watching this property:
+		//		can be used to discontinue watching this property:
 		//		|	var watchHandle = obj.watch("foo", callback);
 		//		|	watchHandle.unwatch(); // callback won't be called now
-		//	callback:
+		// callback:
 		//		The function to execute when the property changes. This will be called after
 		//		the property has been changed. The callback will be called with the |this|
 		//		set to the instance, the first argument as the name of the property, the
-		// 		second argument as the old value and the third argument as the new value.
+		//		second argument as the old value and the third argument as the new value.
 
 		var callbacks = this._watchCallbacks;
 		if(!callbacks){
@@ -99,13 +172,9 @@ return dojo.declare("dojo.Stateful", null, {
 			callbacks = this._watchCallbacks = function(name, oldValue, value, ignoreCatchall){
 				var notify = function(propertyCallbacks){
 					if(propertyCallbacks){
-                        propertyCallbacks = propertyCallbacks.slice();
+						propertyCallbacks = propertyCallbacks.slice();
 						for(var i = 0, l = propertyCallbacks.length; i < l; i++){
-							try{
-								propertyCallbacks[i].call(self, name, oldValue, value);
-							}catch(e){
-								console.error(e);
-							}
+							propertyCallbacks[i].call(self, name, oldValue, value);
 						}
 					}
 				};
@@ -127,11 +196,16 @@ return dojo.declare("dojo.Stateful", null, {
 			propertyCallbacks = callbacks[name] = [];
 		}
 		propertyCallbacks.push(callback);
-		return {
-			unwatch: function(){
-				propertyCallbacks.splice(array.indexOf(propertyCallbacks, callback), 1);
+
+		// TODO: Remove unwatch in 2.0
+		var handle = {};
+		handle.unwatch = handle.remove = function(){
+			var index = array.indexOf(propertyCallbacks, callback);
+			if(index > -1){
+				propertyCallbacks.splice(index, 1);
 			}
-		}; //Object
+		};
+		return handle; //Object
 	}
 
 });
diff --git a/dojo/_base/Color.js b/dojo/_base/Color.js
index d20db59..6f416e5 100644
--- a/dojo/_base/Color.js
+++ b/dojo/_base/Color.js
@@ -3,37 +3,31 @@ define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, Array
 	var Color = dojo.Color = function(/*Array|String|Object*/ color){
 		// summary:
 		//		Takes a named string, hex string, array of rgb or rgba values,
-		//		an object with r, g, b, and a properties, or another `dojo.Color` object
+		//		an object with r, g, b, and a properties, or another `Color` object
 		//		and creates a new Color instance to work from.
 		//
 		// example:
 		//		Work with a Color instance:
-		//	 | var c = new dojo.Color();
+		//	 | var c = new Color();
 		//	 | c.setColor([0,0,0]); // black
 		//	 | var hex = c.toHex(); // #000000
 		//
 		// example:
 		//		Work with a node's color:
 		//	 | var color = dojo.style("someNode", "backgroundColor");
-		//	 | var n = new dojo.Color(color);
+		//	 | var n = new Color(color);
 		//	 | // adjust the color some
 		//	 | n.r *= .5;
 		//	 | console.log(n.toString()); // rgb(128, 255, 255);
 		if(color){ this.setColor(color); }
 	};
 
-	/*=====
-	lang.mixin(dojo.Color,{
-		named:{
-			// summary: Dictionary list of all CSS named colors, by name. Values are 3-item arrays with corresponding RG and B values.
-		}
-	});
-	=====*/
-
 	// FIXME:
 	// there's got to be a more space-efficient way to encode or discover
 	// these!! Use hex?
 	Color.named = {
+		// summary:
+		//		Dictionary list of all CSS named colors, by name. Values are 3-item arrays with corresponding RG and B values.
 		"black":  [0,0,0],
 		"silver": [192,192,192],
 		"gray":	  [128,128,128],
@@ -61,11 +55,11 @@ define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, Array
 		setColor: function(/*Array|String|Object*/ color){
 			// summary:
 			//		Takes a named string, hex string, array of rgb or rgba values,
-			//		an object with r, g, b, and a properties, or another `dojo.Color` object
+			//		an object with r, g, b, and a properties, or another `Color` object
 			//		and sets this color instance to that value.
 			//
 			// example:
-			//	|	var c = new dojo.Color(); // no color
+			//	|	var c = new Color(); // no color
 			//	|	c.setColor("#ededed"); // greyish
 			if(lang.isString(color)){
 				Color.fromString(color, this);
@@ -75,7 +69,7 @@ define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, Array
 				this._set(color.r, color.g, color.b, color.a);
 				if(!(color instanceof Color)){ this.sanitize(); }
 			}
-			return this;	// dojo.Color
+			return this;	// Color
 		},
 		sanitize: function(){
 			// summary:
@@ -83,13 +77,13 @@ define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, Array
 			// description:
 			//		the default implementation does nothing, include dojo.colors to
 			//		augment it with real checks
-			return this;	// dojo.Color
+			return this;	// Color
 		},
 		toRgb: function(){
 			// summary:
 			//		Returns 3 component array of rgb values
 			// example:
-			//	|	var c = new dojo.Color("#000000");
+			//	|	var c = new Color("#000000");
 			//	|	console.log(c.toRgb()); // [0,0,0]
 			var t = this;
 			return [t.r, t.g, t.b]; // Array
@@ -105,7 +99,7 @@ define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, Array
 			// summary:
 			//		Returns a CSS color string in hexadecimal representation
 			// example:
-			//	|	console.log(new dojo.Color([0,0,0]).toHex()); // #000000
+			//	|	console.log(new Color([0,0,0]).toHex()); // #000000
 			var arr = ArrayUtil.map(["r", "g", "b"], function(x){
 				var s = this[x].toString(16);
 				return s.length < 2 ? "0" + s : s;
@@ -116,7 +110,7 @@ define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, Array
 			// summary:
 			//		Returns a css color string in rgb(a) representation
 			// example:
-			//	|	var c = new dojo.Color("#FFF").toCss();
+			//	|	var c = new Color("#FFF").toCss();
 			//	|	console.log(c); // rgb('255','255','255')
 			var t = this, rgb = t.r + ", " + t.g + ", " + t.b;
 			return (includeAlpha ? "rgba(" + rgb + ", " + t.a : "rgb(" + rgb) + ")";	// String
@@ -129,42 +123,42 @@ define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, Array
 	});
 
 	Color.blendColors = dojo.blendColors = function(
-		/*dojo.Color*/ start,
-		/*dojo.Color*/ end,
+		/*Color*/ start,
+		/*Color*/ end,
 		/*Number*/ weight,
-		/*dojo.Color?*/ obj
+		/*Color?*/ obj
 	){
 		// summary:
 		//		Blend colors end and start with weight from 0 to 1, 0.5 being a 50/50 blend,
-		//		can reuse a previously allocated dojo.Color object for the result
+		//		can reuse a previously allocated Color object for the result
 		var t = obj || new Color();
 		ArrayUtil.forEach(["r", "g", "b", "a"], function(x){
 			t[x] = start[x] + (end[x] - start[x]) * weight;
 			if(x != "a"){ t[x] = Math.round(t[x]); }
 		});
-		return t.sanitize();	// dojo.Color
+		return t.sanitize();	// Color
 	};
 
-	Color.fromRgb = dojo.colorFromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
+	Color.fromRgb = dojo.colorFromRgb = function(/*String*/ color, /*Color?*/ obj){
 		// summary:
-		//		Returns a `dojo.Color` instance from a string of the form
-		//		"rgb(...)" or "rgba(...)". Optionally accepts a `dojo.Color`
+		//		Returns a `Color` instance from a string of the form
+		//		"rgb(...)" or "rgba(...)". Optionally accepts a `Color`
 		//		object to update with the parsed value and return instead of
 		//		creating a new object.
 		// returns:
-		//		A dojo.Color object. If obj is passed, it will be the return value.
+		//		A Color object. If obj is passed, it will be the return value.
 		var m = color.toLowerCase().match(/^rgba?\(([\s\.,0-9]+)\)/);
-		return m && Color.fromArray(m[1].split(/\s*,\s*/), obj);	// dojo.Color
+		return m && Color.fromArray(m[1].split(/\s*,\s*/), obj);	// Color
 	};
 
-	Color.fromHex = dojo.colorFromHex = function(/*String*/ color, /*dojo.Color?*/ obj){
+	Color.fromHex = dojo.colorFromHex = function(/*String*/ color, /*Color?*/ obj){
 		// summary:
 		//		Converts a hex string with a '#' prefix to a color object.
 		//		Supports 12-bit #rgb shorthand. Optionally accepts a
-		//		`dojo.Color` object to update with the parsed value.
+		//		`Color` object to update with the parsed value.
 		//
 		// returns:
-		//		A dojo.Color object. If obj is passed, it will be the return value.
+		//		A Color object. If obj is passed, it will be the return value.
 		//
 		// example:
 		//	 | var thing = dojo.colorFromHex("#ededed"); // grey, longhand
@@ -176,7 +170,7 @@ define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, Array
 			mask = (1 << bits) - 1;
 		color = Number("0x" + color.substr(1));
 		if(isNaN(color)){
-			return null; // dojo.Color
+			return null; // Color
 		}
 		ArrayUtil.forEach(["b", "g", "r"], function(x){
 			var c = color & mask;
@@ -184,24 +178,24 @@ define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, Array
 			t[x] = bits == 4 ? 17 * c : c;
 		});
 		t.a = 1;
-		return t;	// dojo.Color
+		return t;	// Color
 	};
 
-	Color.fromArray = dojo.colorFromArray = function(/*Array*/ a, /*dojo.Color?*/ obj){
+	Color.fromArray = dojo.colorFromArray = function(/*Array*/ a, /*Color?*/ obj){
 		// summary:
-		//		Builds a `dojo.Color` from a 3 or 4 element array, mapping each
+		//		Builds a `Color` from a 3 or 4 element array, mapping each
 		//		element in sequence to the rgb(a) values of the color.
 		// example:
 		//		| var myColor = dojo.colorFromArray([237,237,237,0.5]); // grey, 50% alpha
 		// returns:
-		//		A dojo.Color object. If obj is passed, it will be the return value.
+		//		A Color object. If obj is passed, it will be the return value.
 		var t = obj || new Color();
 		t._set(Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3]));
 		if(isNaN(t.a)){ t.a = 1; }
-		return t.sanitize();	// dojo.Color
+		return t.sanitize();	// Color
 	};
 
-	Color.fromString = dojo.colorFromString = function(/*String*/ str, /*dojo.Color?*/ obj){
+	Color.fromString = dojo.colorFromString = function(/*String*/ str, /*Color?*/ obj){
 		// summary:
 		//		Parses `str` for a color value. Accepts hex, rgb, and rgba
 		//		style color values.
@@ -211,9 +205,9 @@ define(["./kernel", "./lang", "./array", "./config"], function(dojo, lang, Array
 		//		rgb or rgba strings such as "rgb(133, 200, 16)" or "rgba(10, 10,
 		//		10, 50)"
 		// returns:
-		//		A dojo.Color object. If obj is passed, it will be the return value.
+		//		A Color object. If obj is passed, it will be the return value.
 		var a = Color.named[str];
-		return a && Color.fromArray(a, obj) || Color.fromRgb(str, obj) || Color.fromHex(str, obj);	// dojo.Color
+		return a && Color.fromArray(a, obj) || Color.fromRgb(str, obj) || Color.fromHex(str, obj);	// Color
 	};
 
 	return Color;
diff --git a/dojo/_base/Deferred.js b/dojo/_base/Deferred.js
index 81a074e..ed857ee 100644
--- a/dojo/_base/Deferred.js
+++ b/dojo/_base/Deferred.js
@@ -1,18 +1,24 @@
-define(["./kernel", "./lang"], function(dojo, lang){
+define([
+	"./kernel",
+	"../Deferred",
+	"../promise/Promise",
+	"../errors/CancelError",
+	"../has",
+	"./lang",
+	"../when"
+], function(dojo, NewDeferred, Promise, CancelError, has, lang, when){
 	// module:
 	//		dojo/_base/Deferred
-	// summary:
-	//		This module defines dojo.Deferred.
 
 	var mutator = function(){};
 	var freeze = Object.freeze || function(){};
 	// A deferred provides an API for creating and resolving a promise.
-	dojo.Deferred = function(/*Function?*/ canceller){
+	var Deferred = dojo.Deferred = function(/*Function?*/ canceller){
 		// summary:
-		//		Deferreds provide a generic means for encapsulating an asynchronous
-		//		operation and notifying users of the completion and result of the operation.
+		//		Deprecated.   This module defines the legacy dojo/_base/Deferred API.
+		//		New code should use dojo/Deferred instead.
 		// description:
-		//		The dojo.Deferred API is based on the concept of promises that provide a
+		//		The Deferred API is based on the concept of promises that provide a
 		//		generic interface into the eventual completion of an asynchronous action.
 		//		The motivation for promises fundamentally is about creating a
 		//		separation of concerns that allows one to achieve the same type of
@@ -26,7 +32,7 @@ define(["./kernel", "./lang"], function(dojo, lang){
 		//		separated from the concerns of asynchronous interaction (which are
 		//		handled by the promise).
 		//
-		//		The dojo.Deferred is a type of promise that provides methods for fulfilling the
+		//		The Deferred is a type of promise that provides methods for fulfilling the
 		//		promise with a successful result or an error. The most important method for
 		//		working with Dojo's promises is the then() method, which follows the
 		//		CommonJS proposed promise API. An example of using a Dojo promise:
@@ -41,12 +47,12 @@ define(["./kernel", "./lang"], function(dojo, lang){
 		//		The .then() call returns a new promise that represents the result of the
 		//		execution of the callback. The callbacks will never affect the original promises value.
 		//
-		//		The dojo.Deferred instances also provide the following functions for backwards compatibility:
+		//		The Deferred instances also provide the following functions for backwards compatibility:
 		//
-		//			* addCallback(handler)
-		//			* addErrback(handler)
-		//			* callback(result)
-		//			* errback(result)
+		//		- addCallback(handler)
+		//		- addErrback(handler)
+		//		- callback(result)
+		//		- errback(result)
 		//
 		//		Callbacks are allowed to return promises themselves, so
 		//		you can build complicated sequences of events with ease.
@@ -59,7 +65,7 @@ define(["./kernel", "./lang"], function(dojo, lang){
 		//		another kind of error), so the errbacks should be prepared to
 		//		handle that error for cancellable Deferreds.
 		// example:
-		//	|	var deferred = new dojo.Deferred();
+		//	|	var deferred = new Deferred();
 		//	|	setTimeout(function(){ deferred.callback({success: true}); }, 1000);
 		//	|	return deferred;
 		// example:
@@ -102,7 +108,7 @@ define(["./kernel", "./lang"], function(dojo, lang){
 		//
 		//		|	// Deferred style:
 		//		|	function renderLotsOfData(data){
-		//		|		var d = new dojo.Deferred();
+		//		|		var d = new Deferred();
 		//		|		try{
 		//		|			for(var x in data){
 		//		|				renderDataitem(data[x]);
@@ -128,7 +134,7 @@ define(["./kernel", "./lang"], function(dojo, lang){
 		//
 		//		|	// Deferred style and async func
 		//		|	function renderLotsOfData(data){
-		//		|		var d = new dojo.Deferred();
+		//		|		var d = new Deferred();
 		//		|		setTimeout(function(){
 		//		|			try{
 		//		|				for(var x in data){
@@ -150,8 +156,8 @@ define(["./kernel", "./lang"], function(dojo, lang){
 		//		Note that the caller doesn't have to change his code at all to
 		//		handle the asynchronous case.
 
-		var result, finished, isError, head, nextListener;
-		var promise = (this.promise = {});
+		var result, finished, canceled, fired, isError, head, nextListener;
+		var promise = (this.promise = new Promise());
 
 		function complete(value){
 			if(finished){
@@ -169,7 +175,13 @@ define(["./kernel", "./lang"], function(dojo, lang){
 				if((mutated = (listener.progress == mutator))){ // assignment and check
 					finished = false;
 				}
+
 				var func = (isError ? listener.error : listener.resolved);
+				if(has("config-useDeferredInstrumentation")){
+					if(isError && NewDeferred.instrumentRejected){
+						NewDeferred.instrumentRejected(result, !!func);
+					}
+				}
 				if(func){
 					try{
 						var newResult = func(result);
@@ -194,11 +206,44 @@ define(["./kernel", "./lang"], function(dojo, lang){
 				}
 			}
 		}
+
+		this.isResolved = promise.isResolved = function(){
+			// summary:
+			//		Checks whether the deferred has been resolved.
+			// returns: Boolean
+
+			return fired == 0;
+		};
+
+		this.isRejected = promise.isRejected = function(){
+			// summary:
+			//		Checks whether the deferred has been rejected.
+			// returns: Boolean
+
+			return fired == 1;
+		};
+
+		this.isFulfilled = promise.isFulfilled = function(){
+			// summary:
+			//		Checks whether the deferred has been resolved or rejected.
+			// returns: Boolean
+
+			return fired >= 0;
+		};
+
+		this.isCanceled = promise.isCanceled = function(){
+			// summary:
+			//		Checks whether the deferred has been canceled.
+			// returns: Boolean
+
+			return canceled;
+		};
+
 		// calling resolve will resolve the promise
 		this.resolve = this.callback = function(value){
 			// summary:
 			//		Fulfills the Deferred instance successfully with the provide value
-			this.fired = 0;
+			this.fired = fired = 0;
 			this.results = [value, null];
 			complete(value);
 		};
@@ -209,12 +254,14 @@ define(["./kernel", "./lang"], function(dojo, lang){
 			// summary:
 			//		Fulfills the Deferred instance as an error with the provided error
 			isError = true;
-			this.fired = 1;
+			this.fired = fired = 1;
+			if(has("config-useDeferredInstrumentation")){
+				if(NewDeferred.instrumentRejected){
+					NewDeferred.instrumentRejected(error, !!nextListener);
+				}
+			}
 			complete(error);
 			this.results = [null, error];
-			if(!error || error.log !== false){
-				(dojo.config.deferredOnError || function(x){ console.error(x); })(error);
-			}
 		};
 		// call progress to provide updates on the progress on the completion of the promise
 		this.progress = function(update){
@@ -231,13 +278,13 @@ define(["./kernel", "./lang"], function(dojo, lang){
 			// summary:
 			//		Adds callback and error callback for this deferred instance.
 			// callback: Function?
-			// 		The callback attached to this deferred object.
+			//		The callback attached to this deferred object.
 			// errback: Function?
-			// 		The error callback attached to this deferred object.
+			//		The error callback attached to this deferred object.
 			// returns:
-			// 		Returns this deferred object.
+			//		Returns this deferred object.
 			this.then(callback, errback, mutator);
-			return this;	// dojo.Deferred
+			return this;	// Deferred
 		};
 		// provide the implementation of the promise
 		promise.then = this.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){
@@ -256,7 +303,7 @@ define(["./kernel", "./lang"], function(dojo, lang){
 			//		handler is the fulfillment value for the returned promise. If the callback
 			//		throws an error, the returned promise will be moved to failed state.
 			//
-			// returns: 
+			// returns:
 			//		Returns a new promise that represents the result of the
 			//		execution of the callback. The callbacks will never affect the original promises value.
 			// example:
@@ -266,7 +313,7 @@ define(["./kernel", "./lang"], function(dojo, lang){
 			//		|		then(printResult, onError);
 			//		|	>44
 			//
-			var returnDeferred = progressCallback == mutator ? this : new dojo.Deferred(promise.cancel);
+			var returnDeferred = progressCallback == mutator ? this : new Deferred(promise.cancel);
 			var listener = {
 				resolved: resolvedCallback,
 				error: errorCallback,
@@ -285,82 +332,52 @@ define(["./kernel", "./lang"], function(dojo, lang){
 			return returnDeferred.promise; // Promise
 		};
 		var deferred = this;
-		promise.cancel = this.cancel = function (){
+		promise.cancel = this.cancel = function(){
 			// summary:
 			//		Cancels the asynchronous operation
 			if(!finished){
 				var error = canceller && canceller(deferred);
 				if(!finished){
 					if (!(error instanceof Error)){
-						error = new Error(error);
+						error = new CancelError(error);
 					}
 					error.log = false;
 					deferred.reject(error);
 				}
 			}
+			canceled = true;
 		};
 		freeze(promise);
 	};
-	lang.extend(dojo.Deferred, {
-		addCallback: function (/*Function*/ callback){
+	lang.extend(Deferred, {
+		addCallback: function(/*Function*/ callback){
 			// summary:
-			// 		Adds successful callback for this deferred instance.
+			//		Adds successful callback for this deferred instance.
 			// returns:
-			// 		Returns this deferred object.
-			return this.addCallbacks(lang.hitch.apply(dojo, arguments));	// dojo.Deferred
+			//		Returns this deferred object.
+			return this.addCallbacks(lang.hitch.apply(dojo, arguments));	// Deferred
 		},
 
-		addErrback: function (/*Function*/ errback){
+		addErrback: function(/*Function*/ errback){
 			// summary:
-			// 		Adds error callback for this deferred instance.
+			//		Adds error callback for this deferred instance.
 			// returns:
-			// 		Returns this deferred object.
-			return this.addCallbacks(null, lang.hitch.apply(dojo, arguments));	// dojo.Deferred
+			//		Returns this deferred object.
+			return this.addCallbacks(null, lang.hitch.apply(dojo, arguments));	// Deferred
 		},
 
-		addBoth: function (/*Function*/ callback){
+		addBoth: function(/*Function*/ callback){
 			// summary:
-			// 		Add handler as both successful callback and error callback for this deferred instance.
+			//		Add handler as both successful callback and error callback for this deferred instance.
 			// returns:
-			// 		Returns this deferred object.
+			//		Returns this deferred object.
 			var enclosed = lang.hitch.apply(dojo, arguments);
-			return this.addCallbacks(enclosed, enclosed);	// dojo.Deferred
+			return this.addCallbacks(enclosed, enclosed);	// Deferred
 		},
 		fired: -1
 	});
 
-	dojo.Deferred.when = dojo.when = function(promiseOrValue, /*Function?*/ callback, /*Function?*/ errback, /*Function?*/ progressHandler){
-		// summary:
-		//		This provides normalization between normal synchronous values and
-		//		asynchronous promises, so you can interact with them in a common way
-		// returns:
-		// 		Returns a new promise that represents the result of the execution of callback 
-		// 		when parameter "promiseOrValue" is promise.
-		// 		Returns the execution result of callback when parameter "promiseOrValue" is value.
-		// example:
-		//		|	function printFirstAndLast(items){
-		//		|		dojo.when(findFirst(items), console.log);
-		//		|		dojo.when(findLast(items), console.log);
-		//		|	}
-		//		|	function findFirst(items){
-		//		|		return dojo.when(items, function(items){
-		//		|			return items[0];
-		//		|		});
-		//		|	}
-		//		|	function findLast(items){
-		//		|		return dojo.when(items, function(items){
-		//		|			return items[items.length - 1];
-		//		|		});
-		//		|	}
-		//		And now all three of his functions can be used sync or async.
-		//		|	printFirstAndLast([1,2,3,4]) will work just as well as
-		//		|	printFirstAndLast(dojo.xhrGet(...));
-
-		if(promiseOrValue && typeof promiseOrValue.then === "function"){
-			return promiseOrValue.then(callback, errback, progressHandler);
-		}
-		return callback ? callback(promiseOrValue) : promiseOrValue;	// Promise
-	};
+	Deferred.when = dojo.when = when;
 
-	return dojo.Deferred;
+	return Deferred;
 });
diff --git a/dojo/_base/NodeList.js b/dojo/_base/NodeList.js
index abf8219..10a173c 100644
--- a/dojo/_base/NodeList.js
+++ b/dojo/_base/NodeList.js
@@ -1,59 +1,69 @@
 define(["./kernel", "../query", "./array", "./html", "../NodeList-dom"], function(dojo, query, array){
-  //  module:
-  //    dojo/_base/NodeList
-  //  summary:
-  //    This module defines dojo.NodeList.
- 
-var NodeList = query.NodeList;
+	// module:
+	//		dojo/_base/NodeList
 
 	/*=====
-	dojo.extend(dojo.NodeList, {
-		connect: function(methodName, objOrFunc, funcName){
-			// summary:
-			//		attach event handlers to every item of the NodeList. Uses dojo.connect()
-			//		so event properties are normalized
-			// methodName: String
-			//		the name of the method to attach to. For DOM events, this should be
-			//		the lower-case name of the event
-			// objOrFunc: Object|Function|String
-			//		if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
-			//		reference a function or be the name of the function in the global
-			//		namespace to attach. If 3 arguments are provided
-			//		(methodName, objOrFunc, funcName), objOrFunc must be the scope to
-			//		locate the bound function in
-			// funcName: String?
-			//		optional. A string naming the function in objOrFunc to bind to the
-			//		event. May also be a function reference.
-			// example:
-			//		add an onclick handler to every button on the page
-			//		|	dojo.query("div:nth-child(odd)").connect("onclick", function(e){
-			//		|		console.log("clicked!");
-			//		|	});
-			// example:
-			//		attach foo.bar() to every odd div's onmouseover
-			//		|	dojo.query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
-		},
-		coords: function(){
-			// summary:
-			//		Deprecated: Use position() for border-box x/y/w/h
-			//		or marginBox() for margin-box w/h/l/t.
-			//		Returns the box objects of all elements in a node list as
-			//		an Array (*not* a NodeList). Acts like `dojo.coords`, though assumes
-			//		the node passed is each node in this list.
-
-			return dojo.map(this, dojo.coords); // Array
-		}
-	 });
-
-	 var NodeList = dojo.NodeList;
+	return {
+		// summary:
+		//		This module extends dojo/NodeList with the legacy connect(), coords(),
+		//		blur(), focus(), change(), click(), error(), keydown(), keypress(),
+		//		keyup(), load(), mousedown(), mouseenter(), mouseleave(), mousemove(),
+		//		mouseout(), mouseover(), mouseup(), and submit() methods.
+	};
 	=====*/
-	var nlp = NodeList.prototype;
+ 
+	var NodeList = query.NodeList,
+		nlp = NodeList.prototype;
 
-	// don't bind early to dojo.connect since we no longer explicitly depend on it
 	nlp.connect = NodeList._adaptAsForEach(function(){
+		// don't bind early to dojo.connect since we no longer explicitly depend on it
 		return dojo.connect.apply(this, arguments);
 	});
+	/*=====
+	nlp.connect = function(methodName, objOrFunc, funcName){
+		// summary:
+		//		Attach event handlers to every item of the NodeList. Uses dojo.connect()
+		//		so event properties are normalized.
+		//
+		//		Application must manually require() "dojo/_base/connect" before using this method.
+		// methodName: String
+		//		the name of the method to attach to. For DOM events, this should be
+		//		the lower-case name of the event
+		// objOrFunc: Object|Function|String
+		//		if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
+		//		reference a function or be the name of the function in the global
+		//		namespace to attach. If 3 arguments are provided
+		//		(methodName, objOrFunc, funcName), objOrFunc must be the scope to
+		//		locate the bound function in
+		// funcName: String?
+		//		optional. A string naming the function in objOrFunc to bind to the
+		//		event. May also be a function reference.
+		// example:
+		//		add an onclick handler to every button on the page
+		//		|	query("div:nth-child(odd)").connect("onclick", function(e){
+		//		|		console.log("clicked!");
+		//		|	});
+		// example:
+		//		attach foo.bar() to every odd div's onmouseover
+		//		|	query("div:nth-child(odd)").connect("onmouseover", foo, "bar");
+
+		return null;	// NodeList
+	};
+	=====*/
+
 	nlp.coords = NodeList._adaptAsMap(dojo.coords);
+	/*=====
+	nlp.coords = function(){
+		// summary:
+		//		Deprecated: Use position() for border-box x/y/w/h
+		//		or marginBox() for margin-box w/h/l/t.
+		//		Returns the box objects of all elements in a node list as
+		//		an Array (*not* a NodeList). Acts like `domGeom.coords`, though assumes
+		//		the node passed is each node in this list.
+
+		return []; // Array
+	};
+	=====*/
 
 	NodeList.events = [
 		// summary:
@@ -96,5 +106,5 @@ var NodeList = query.NodeList;
 	);
 
 	dojo.NodeList = NodeList;
-	return dojo.NodeList;
+	return NodeList;
 });
diff --git a/dojo/_base/array.js b/dojo/_base/array.js
index dc27094..fd9fc71 100644
--- a/dojo/_base/array.js
+++ b/dojo/_base/array.js
@@ -1,205 +1,9 @@
 define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 	// module:
 	//		dojo/_base/array
-	// summary:
-	//		This module defines the Javascript v1.6 array extensions.
-
-	/*=====
-	dojo.indexOf = function(arr, value, fromIndex, findLast){
-		// summary:
-		//		locates the first index of the provided value in the
-		//		passed array. If the value is not found, -1 is returned.
-		// description:
-		//		This method corresponds to the JavaScript 1.6 Array.indexOf method, with one difference: when
-		//		run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
-		//		1.6's indexOf skips the holes in the sparse array.
-		//		For details on this method, see:
-		//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
-		// arr: Array
-		// value: Object
-		// fromIndex: Integer?
-		// findLast: Boolean?
-		// returns: Number
-	};
-	dojo.lastIndexOf = function(arr, value, fromIndex){
-		// summary:
-		//		locates the last index of the provided value in the passed
-		//		array. If the value is not found, -1 is returned.
-		// description:
-		//		This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with one difference: when
-		//		run over sparse arrays, the Dojo function invokes the callback for every index whereas JavaScript
-		//		1.6's lastIndexOf skips the holes in the sparse array.
-		//		For details on this method, see:
-		//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
-		//	arr: Array,
-		//	value: Object,
-		//	fromIndex: Integer?
-		//	returns: Number
-	};
-	dojo.forEach = function(arr, callback, thisObject){
-		//	summary:
-		//		for every item in arr, callback is invoked. Return values are ignored.
-		//		If you want to break out of the loop, consider using dojo.every() or dojo.some().
-		//		forEach does not allow breaking out of the loop over the items in arr.
-		//	arr:
-		//		the array to iterate over. If a string, operates on individual characters.
-		//	callback:
-		//		a function is invoked with three arguments: item, index, and array
-		//	thisObject:
-		//		may be used to scope the call to callback
-		//	description:
-		//		This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
-		//		run over sparse arrays, this implementation passes the "holes" in the sparse array to
-		//		the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
-		//		For more details, see:
-		//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
-		//	example:
-		//	| // log out all members of the array:
-		//	| dojo.forEach(
-		//	|		[ "thinger", "blah", "howdy", 10 ],
-		//	|		function(item){
-		//	|			console.log(item);
-		//	|		}
-		//	| );
-		//	example:
-		//	| // log out the members and their indexes
-		//	| dojo.forEach(
-		//	|		[ "thinger", "blah", "howdy", 10 ],
-		//	|		function(item, idx, arr){
-		//	|			console.log(item, "at index:", idx);
-		//	|		}
-		//	| );
-		//	example:
-		//	| // use a scoped object member as the callback
-		//	|
-		//	| var obj = {
-		//	|		prefix: "logged via obj.callback:",
-		//	|		callback: function(item){
-		//	|			console.log(this.prefix, item);
-		//	|		}
-		//	| };
-		//	|
-		//	| // specifying the scope function executes the callback in that scope
-		//	| dojo.forEach(
-		//	|		[ "thinger", "blah", "howdy", 10 ],
-		//	|		obj.callback,
-		//	|		obj
-		//	| );
-		//	|
-		//	| // alternately, we can accomplish the same thing with dojo.hitch()
-		//	| dojo.forEach(
-		//	|		[ "thinger", "blah", "howdy", 10 ],
-		//	|		dojo.hitch(obj, "callback")
-		//	| );
-		//	arr: Array|String
-		//	callback: Function|String
-		//	thisObject: Object?
-	};
-	dojo.every = function(arr, callback, thisObject){
-		// summary:
-		//		Determines whether or not every item in arr satisfies the
-		//		condition implemented by callback.
-		// arr: Array|String
-		//		the array to iterate on. If a string, operates on individual characters.
-		// callback: Function|String
-		//		a function is invoked with three arguments: item, index,
-		//		and array and returns true if the condition is met.
-		// thisObject: Object?
-		//		may be used to scope the call to callback
-		// returns: Boolean
-		// description:
-		//		This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
-		//		run over sparse arrays, this implementation passes the "holes" in the sparse array to
-		//		the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
-		//		For more details, see:
-		//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
-		// example:
-		//	| // returns false
-		//	| dojo.every([1, 2, 3, 4], function(item){ return item>1; });
-		// example:
-		//	| // returns true
-		//	| dojo.every([1, 2, 3, 4], function(item){ return item>0; });
-	};
-	dojo.some = function(arr, callback, thisObject){
-		// summary:
-		//		Determines whether or not any item in arr satisfies the
-		//		condition implemented by callback.
-		// arr: Array|String
-		//		the array to iterate over. If a string, operates on individual characters.
-		// callback: Function|String
-		//		a function is invoked with three arguments: item, index,
-		//		and array and returns true if the condition is met.
-		// thisObject: Object?
-		//		may be used to scope the call to callback
-		// returns: Boolean
-		// description:
-		//		This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
-		//		run over sparse arrays, this implementation passes the "holes" in the sparse array to
-		//		the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
-		//		For more details, see:
-		//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
-		// example:
-		//	| // is true
-		//	| dojo.some([1, 2, 3, 4], function(item){ return item>1; });
-		// example:
-		//	| // is false
-		//	| dojo.some([1, 2, 3, 4], function(item){ return item<1; });
-	};
-	dojo.map = function(arr, callback, thisObject){
-		// summary:
-		//		applies callback to each element of arr and returns
-		//		an Array with the results
-		// arr: Array|String
-		//		the array to iterate on. If a string, operates on
-		//		individual characters.
-		// callback: Function|String
-		//		a function is invoked with three arguments, (item, index,
-		//		array),	 and returns a value
-		// thisObject: Object?
-		//		may be used to scope the call to callback
-		// returns: Array
-		// description:
-		//		This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
-		//		run over sparse arrays, this implementation passes the "holes" in the sparse array to
-		//		the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
-		//		For more details, see:
-		//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
-		// example:
-		//	| // returns [2, 3, 4, 5]
-		//	| dojo.map([1, 2, 3, 4], function(item){ return item+1 });
-	};
-	dojo.filter = function(arr, callback, thisObject){
-		// summary:
-		//		Returns a new Array with those items from arr that match the
-		//		condition implemented by callback.
-		// arr: Array
-		//		the array to iterate over.
-		// callback: Function|String
-		//		a function that is invoked with three arguments (item,
-		//		index, array). The return of this function is expected to
-		//		be a boolean which determines whether the passed-in item
-		//		will be included in the returned array.
-		// thisObject: Object?
-		//		may be used to scope the call to callback
-		// returns: Array
-		// description:
-		//		This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
-		//		run over sparse arrays, this implementation passes the "holes" in the sparse array to
-		//		the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
-		//		For more details, see:
-		//			https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
-		// example:
-		//	| // returns [2, 3, 4]
-		//	| dojo.filter([1, 2, 3, 4], function(item){ return item>1; });
-	};
-	=====*/
 
 	// our old simple function builder stuff
-	var cache = {}, u, array; // the export object
-
-	function clearCache(){
-		cache = {};
-	}
+	var cache = {}, u;
 
 	function buildFn(fn){
 		return cache[fn] = new Function("item", "index", "array", fn); // Function
@@ -230,9 +34,8 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 				}
 			}
 			return every; // Boolean
-		}
+		};
 	}
-	// var every = everyOrSome(false), some = everyOrSome(true);
 
 	// indexOf, lastIndexOf
 
@@ -266,78 +69,282 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 				}
 			}
 			return -1; // Number
-		}
+		};
 	}
-	// var indexOf = index(true), lastIndexOf = index(false);
 
-	function forEach(a, fn, o){
-		var i = 0, l = a && a.length || 0;
-		if(l && typeof a == "string") a = a.split("");
-		if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
-		if(o){
-			for(; i < l; ++i){
-				fn.call(o, a[i], i, a);
-			}
-		}else{
-			for(; i < l; ++i){
-				fn(a[i], i, a);
-			}
-		}
-	}
+	var array = {
+		// summary:
+		//		The Javascript v1.6 array extensions.
 
-	function map(a, fn, o, Ctr){
-		// TODO: why do we have a non-standard signature here? do we need "Ctr"?
-		var i = 0, l = a && a.length || 0, out = new (Ctr || Array)(l);
-		if(l && typeof a == "string") a = a.split("");
-		if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
-		if(o){
-			for(; i < l; ++i){
-				out[i] = fn.call(o, a[i], i, a);
-			}
-		}else{
-			for(; i < l; ++i){
-				out[i] = fn(a[i], i, a);
+		every: everyOrSome(false),
+		/*=====
+		 every: function(arr, callback, thisObject){
+			 // summary:
+			 //		Determines whether or not every item in arr satisfies the
+			 //		condition implemented by callback.
+			 // arr: Array|String
+			 //		the array to iterate on. If a string, operates on individual characters.
+			 // callback: Function|String
+			 //		a function is invoked with three arguments: item, index,
+			 //		and array and returns true if the condition is met.
+			 // thisObject: Object?
+			 //		may be used to scope the call to callback
+			 // returns: Boolean
+			 // description:
+			 //		This function corresponds to the JavaScript 1.6 Array.every() method, with one difference: when
+			 //		run over sparse arrays, this implementation passes the "holes" in the sparse array to
+			 //		the callback function with a value of undefined. JavaScript 1.6's every skips the holes in the sparse array.
+			 //		For more details, see:
+			 //		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/every
+			 // example:
+			 //	|	// returns false
+			 //	|	array.every([1, 2, 3, 4], function(item){ return item>1; });
+			 // example:
+			 //	|	// returns true
+			 //	|	array.every([1, 2, 3, 4], function(item){ return item>0; });
+		 },
+		 =====*/
+
+		some: everyOrSome(true),
+		/*=====
+		some: function(arr, callback, thisObject){
+			// summary:
+			//		Determines whether or not any item in arr satisfies the
+			//		condition implemented by callback.
+			// arr: Array|String
+			//		the array to iterate over. If a string, operates on individual characters.
+			// callback: Function|String
+			//		a function is invoked with three arguments: item, index,
+			//		and array and returns true if the condition is met.
+			// thisObject: Object?
+			//		may be used to scope the call to callback
+			// returns: Boolean
+			// description:
+			//		This function corresponds to the JavaScript 1.6 Array.some() method, with one difference: when
+			//		run over sparse arrays, this implementation passes the "holes" in the sparse array to
+			//		the callback function with a value of undefined. JavaScript 1.6's some skips the holes in the sparse array.
+			//		For more details, see:
+			//		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/some
+			// example:
+			//	| // is true
+			//	| array.some([1, 2, 3, 4], function(item){ return item>1; });
+			// example:
+			//	| // is false
+			//	| array.some([1, 2, 3, 4], function(item){ return item<1; });
+		},
+		=====*/
+
+		indexOf: index(true),
+		/*=====
+		indexOf: function(arr, value, fromIndex, findLast){
+			// summary:
+			//		locates the first index of the provided value in the
+			//		passed array. If the value is not found, -1 is returned.
+			// description:
+			//		This method corresponds to the JavaScript 1.6 Array.indexOf method, with two differences:
+			//
+			//		1. when run over sparse arrays, the Dojo function invokes the callback for every index
+			//		   whereas JavaScript 1.6's indexOf skips the holes in the sparse array.
+			//		2. uses equality (==) rather than strict equality (===)
+			//
+			//		For details on this method, see:
+			//		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/indexOf
+			// arr: Array
+			// value: Object
+			// fromIndex: Integer?
+			// findLast: Boolean?
+			//		Makes indexOf() work like lastIndexOf().  Used internally; not meant for external usage.
+			// returns: Number
+		},
+		=====*/
+
+		lastIndexOf: index(false),
+		/*=====
+		lastIndexOf: function(arr, value, fromIndex){
+			// summary:
+			//		locates the last index of the provided value in the passed
+			//		array. If the value is not found, -1 is returned.
+			// description:
+		 	//		This method corresponds to the JavaScript 1.6 Array.lastIndexOf method, with two differences:
+		 	//
+		 	//		1. when run over sparse arrays, the Dojo function invokes the callback for every index
+		 	//		   whereas JavaScript 1.6's lasIndexOf skips the holes in the sparse array.
+		 	//		2. uses equality (==) rather than strict equality (===)
+		 	//
+		 	//		For details on this method, see:
+		 	//		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/lastIndexOf
+			// arr: Array,
+			// value: Object,
+			// fromIndex: Integer?
+			// returns: Number
+		},
+		=====*/
+
+		forEach: function(arr, callback, thisObject){
+			// summary:
+			//		for every item in arr, callback is invoked. Return values are ignored.
+			//		If you want to break out of the loop, consider using array.every() or array.some().
+			//		forEach does not allow breaking out of the loop over the items in arr.
+			// arr:
+			//		the array to iterate over. If a string, operates on individual characters.
+			// callback:
+			//		a function is invoked with three arguments: item, index, and array
+			// thisObject:
+			//		may be used to scope the call to callback
+			// description:
+			//		This function corresponds to the JavaScript 1.6 Array.forEach() method, with one difference: when
+			//		run over sparse arrays, this implementation passes the "holes" in the sparse array to
+			//		the callback function with a value of undefined. JavaScript 1.6's forEach skips the holes in the sparse array.
+			//		For more details, see:
+			//		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/forEach
+			// example:
+			//	| // log out all members of the array:
+			//	| array.forEach(
+			//	|		[ "thinger", "blah", "howdy", 10 ],
+			//	|		function(item){
+			//	|			console.log(item);
+			//	|		}
+			//	| );
+			// example:
+			//	| // log out the members and their indexes
+			//	| array.forEach(
+			//	|		[ "thinger", "blah", "howdy", 10 ],
+			//	|		function(item, idx, arr){
+			//	|			console.log(item, "at index:", idx);
+			//	|		}
+			//	| );
+			// example:
+			//	| // use a scoped object member as the callback
+			//	|
+			//	| var obj = {
+			//	|		prefix: "logged via obj.callback:",
+			//	|		callback: function(item){
+			//	|			console.log(this.prefix, item);
+			//	|		}
+			//	| };
+			//	|
+			//	| // specifying the scope function executes the callback in that scope
+			//	| array.forEach(
+			//	|		[ "thinger", "blah", "howdy", 10 ],
+			//	|		obj.callback,
+			//	|		obj
+			//	| );
+			//	|
+			//	| // alternately, we can accomplish the same thing with lang.hitch()
+			//	| array.forEach(
+			//	|		[ "thinger", "blah", "howdy", 10 ],
+			//	|		lang.hitch(obj, "callback")
+			//	| );
+			// arr: Array|String
+			// callback: Function|String
+			// thisObject: Object?
+
+			var i = 0, l = arr && arr.length || 0;
+			if(l && typeof arr == "string") arr = arr.split("");
+			if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
+			if(thisObject){
+				for(; i < l; ++i){
+					callback.call(thisObject, arr[i], i, arr);
+				}
+			}else{
+				for(; i < l; ++i){
+					callback(arr[i], i, arr);
+				}
 			}
-		}
-		return out; // Array
-	}
+		},
 
-	function filter(a, fn, o){
-		// TODO: do we need "Ctr" here like in map()?
-		var i = 0, l = a && a.length || 0, out = [], value;
-		if(l && typeof a == "string") a = a.split("");
-		if(typeof fn == "string") fn = cache[fn] || buildFn(fn);
-		if(o){
-			for(; i < l; ++i){
-				value = a[i];
-				if(fn.call(o, value, i, a)){
-					out.push(value);
+		map: function(arr, callback, thisObject, Ctr){
+			// summary:
+			//		applies callback to each element of arr and returns
+			//		an Array with the results
+			// arr: Array|String
+			//		the array to iterate on. If a string, operates on
+			//		individual characters.
+			// callback: Function|String
+			//		a function is invoked with three arguments, (item, index,
+			//		array),	 and returns a value
+			// thisObject: Object?
+			//		may be used to scope the call to callback
+			// returns: Array
+			// description:
+			//		This function corresponds to the JavaScript 1.6 Array.map() method, with one difference: when
+			//		run over sparse arrays, this implementation passes the "holes" in the sparse array to
+			//		the callback function with a value of undefined. JavaScript 1.6's map skips the holes in the sparse array.
+			//		For more details, see:
+			//		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
+			// example:
+			//	| // returns [2, 3, 4, 5]
+			//	| array.map([1, 2, 3, 4], function(item){ return item+1 });
+
+			// TODO: why do we have a non-standard signature here? do we need "Ctr"?
+			var i = 0, l = arr && arr.length || 0, out = new (Ctr || Array)(l);
+			if(l && typeof arr == "string") arr = arr.split("");
+			if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
+			if(thisObject){
+				for(; i < l; ++i){
+					out[i] = callback.call(thisObject, arr[i], i, arr);
+				}
+			}else{
+				for(; i < l; ++i){
+					out[i] = callback(arr[i], i, arr);
 				}
 			}
-		}else{
-			for(; i < l; ++i){
-				value = a[i];
-				if(fn(value, i, a)){
-					out.push(value);
+			return out; // Array
+		},
+
+		filter: function(arr, callback, thisObject){
+			// summary:
+			//		Returns a new Array with those items from arr that match the
+			//		condition implemented by callback.
+			// arr: Array
+			//		the array to iterate over.
+			// callback: Function|String
+			//		a function that is invoked with three arguments (item,
+			//		index, array). The return of this function is expected to
+			//		be a boolean which determines whether the passed-in item
+			//		will be included in the returned array.
+			// thisObject: Object?
+			//		may be used to scope the call to callback
+			// returns: Array
+			// description:
+			//		This function corresponds to the JavaScript 1.6 Array.filter() method, with one difference: when
+			//		run over sparse arrays, this implementation passes the "holes" in the sparse array to
+			//		the callback function with a value of undefined. JavaScript 1.6's filter skips the holes in the sparse array.
+			//		For more details, see:
+			//		https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
+			// example:
+			//	| // returns [2, 3, 4]
+			//	| array.filter([1, 2, 3, 4], function(item){ return item>1; });
+
+			// TODO: do we need "Ctr" here like in map()?
+			var i = 0, l = arr && arr.length || 0, out = [], value;
+			if(l && typeof arr == "string") arr = arr.split("");
+			if(typeof callback == "string") callback = cache[callback] || buildFn(callback);
+			if(thisObject){
+				for(; i < l; ++i){
+					value = arr[i];
+					if(callback.call(thisObject, value, i, arr)){
+						out.push(value);
+					}
+				}
+			}else{
+				for(; i < l; ++i){
+					value = arr[i];
+					if(callback(value, i, arr)){
+						out.push(value);
+					}
 				}
 			}
-		}
-		return out; // Array
-	}
+			return out; // Array
+		},
 
-	array = {
-		every:       everyOrSome(false),
-		some:        everyOrSome(true),
-		indexOf:     index(true),
-		lastIndexOf: index(false),
-		forEach:     forEach,
-		map:         map,
-		filter:      filter,
-		clearCache:  clearCache
+		clearCache: function(){
+			cache = {};
+		}
 	};
 
+
 	has("extend-dojo") && lang.mixin(dojo, array);
 
-	/*===== return dojo.array; =====*/
 	return array;
 });
diff --git a/dojo/_base/browser.js b/dojo/_base/browser.js
index c367db7..68ab363 100644
--- a/dojo/_base/browser.js
+++ b/dojo/_base/browser.js
@@ -12,10 +12,17 @@ define([
 	"./NodeList",
 	"../query",
 	"./xhr",
-	"./fx"], function(dojo) {
+	"./fx"], function(dojo){
+
 	// module:
 	//		dojo/_base/browser
-	// summary:
-	//		This module causes the browser-only base modules to be loaded.
+
+	/*=====
+	return {
+		// summary:
+		//		This module causes the browser-only base modules to be loaded.
+	};
+	=====*/
+
 	return dojo;
 });
diff --git a/dojo/_base/config.js b/dojo/_base/config.js
index aa0cb9b..d94d9c8 100644
--- a/dojo/_base/config.js
+++ b/dojo/_base/config.js
@@ -1,23 +1,26 @@
 define(["../has", "require"], function(has, require){
 	// module:
 	//		dojo/_base/config
+
+/*=====
+return {
 	// summary:
 	//		This module defines the user configuration during bootstrap.
 	// description:
 	//		By defining user configuration as a module value, an entire configuration can be specified in a build,
-    //		thereby eliminating the need for sniffing and or explicitly setting in the global variable dojoConfig.
-    //		Also, when multiple instances of dojo exist in a single application, each will necessarily be located
+	//		thereby eliminating the need for sniffing and or explicitly setting in the global variable dojoConfig.
+	//		Also, when multiple instances of dojo exist in a single application, each will necessarily be located
 	//		at an unique absolute module identifier as given by the package configuration. Implementing configuration
 	//		as a module allows for specifying unique, per-instance configurations.
 	// example:
-	//		Create a second instance of dojo with a different, instance-uniqe configuration (assume the loader and
+	//		Create a second instance of dojo with a different, instance-unique configuration (assume the loader and
 	//		dojo.js are already loaded).
 	//		|	// specify a configuration that creates a new instance of dojo at the absolute module identifier "myDojo"
 	//		|	require({
 	//		|		packages:[{
 	//		|			name:"myDojo",
 	//		|			location:".", //assume baseUrl points to dojo.js
-	//		|	    }]
+	//		|		}]
 	//		|	});
 	//		|
 	//		|	// specify a configuration for the myDojo instance
@@ -27,49 +30,11 @@ define(["../has", "require"], function(has, require){
 	//		|	});
 	//		|
 	//		|	// load and use the new instance of dojo
-	//		|	require(["myDojo"], function(dojo) {
+	//		|	require(["myDojo"], function(dojo){
 	//		|		// dojo is the new instance of dojo
 	//		|		// use as required
 	//		|	});
 
-	var result = {};
-	if(has("dojo-config-api")){
-		// must be the dojo loader; take a shallow copy of require.rawConfig
-		var src = require.rawConfig, p;
-		for(p in src){
-			result[p] = src[p];
-		}
-	}else{
-		var adviseHas = function(featureSet, prefix, booting){
-			for(p in featureSet){
-				p!="has" && has.add(prefix + p, featureSet[p], 0, booting);
-			}
-		};
-		result = has("dojo-loader") ?
-			// must be a built version of the dojo loader; all config stuffed in require.rawConfig
-			require.rawConfig :
-			// a foreign loader
-			this.dojoConfig || this.djConfig || {};
-		adviseHas(result, "config", 1);
-		adviseHas(result.has, "", 1);
-	}
-	return result;
-
-/*=====
-// note:
-//		'dojoConfig' does not exist under 'dojo.*' so that it can be set before the
-//		'dojo' variable exists.
-// note:
-//		Setting any of these variables *after* the library has loaded does
-//		nothing at all.
-
-// FIXME: can we document these on dojo.config object and explain they must be set via djConfig/dojoConfig global prior to loading dojo.js
-
-dojoConfig = {
-	// summary:
-	//		Application code can set the global 'dojoConfig' prior to loading
-	//		the library to control certain global settings for how dojo works.
-	//
 	// isDebug: Boolean
 	//		Defaults to `false`. If set to `true`, ensures that Dojo provides
 	//		extended debugging feedback via Firebug. If Firebug is not available
@@ -81,6 +46,7 @@ dojoConfig = {
 	//		`isDebug` is false and you are on a platform without Firebug, these
 	//		methods will be defined as no-ops.
 	isDebug: false,
+
 	// locale: String
 	//		The locale to assume for loading localized resources in this page,
 	//		specified according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt).
@@ -90,11 +56,13 @@ dojoConfig = {
 	//		Dojo assumes the locale of the user agent, according to `navigator.userLanguage`
 	//		or `navigator.language` properties.
 	locale: undefined,
+
 	// extraLocale: Array
 	//		No default value. Specifies additional locales whose
 	//		resources should also be loaded alongside the default locale when
 	//		calls to `dojo.requireLocalization()` are processed.
 	extraLocale: undefined,
+
 	// baseUrl: String
 	//		The directory in which `dojo.js` is located. Under normal
 	//		conditions, Dojo auto-detects the correct location from which it
@@ -105,70 +73,121 @@ dojoConfig = {
 	//		auto-detected root if not. Other modules are located relative to
 	//		this path. The path should end in a slash.
 	baseUrl: undefined,
-	// modulePaths: Object
+
+	// modulePaths: [deprecated] Object
 	//		A map of module names to paths relative to `dojo.baseUrl`. The
 	//		key/value pairs correspond directly to the arguments which
-	//		`dojo.registerModulePath` accepts. Specifiying
+	//		`dojo.registerModulePath` accepts. Specifying
 	//		`djConfig.modulePaths = { "foo": "../../bar" }` is the equivalent
 	//		of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
 	//		modules may be configured via `djConfig.modulePaths`.
 	modulePaths: {},
-	// afterOnLoad: Boolean
-	//		Indicates Dojo was added to the page after the page load. In this case
-	//		Dojo will not wait for the page DOMContentLoad/load events and fire
-	//		its dojo.addOnLoad callbacks after making sure all outstanding
-	//		dojo.required modules have loaded. Only works with a built dojo.js,
-	//		it does not work the dojo.js directly from source control.
-	afterOnLoad: false,
-	// addOnLoad: Function or Array
-	//		Adds a callback via dojo.addOnLoad. Useful when Dojo is added after
+
+	// addOnLoad: Function|Array
+	//		Adds a callback via dojo/ready. Useful when Dojo is added after
 	//		the page loads and djConfig.afterOnLoad is true. Supports the same
-	//		arguments as dojo.addOnLoad. When using a function reference, use
+	//		arguments as dojo/ready. When using a function reference, use
 	//		`djConfig.addOnLoad = function(){};`. For object with function name use
 	//		`djConfig.addOnLoad = [myObject, "functionName"];` and for object with
 	//		function reference use
 	//		`djConfig.addOnLoad = [myObject, function(){}];`
 	addOnLoad: null,
-	// require: Array
+
+	// parseOnLoad: Boolean
+	//		Run the parser after the page is loaded
+	parseOnLoad: false,
+
+	// require: String[]
 	//		An array of module names to be loaded immediately after dojo.js has been included
 	//		in a page.
 	require: [],
-	// defaultDuration: Array
+
+	// defaultDuration: Number
 	//		Default duration, in milliseconds, for wipe and fade animations within dijits.
 	//		Assigned to dijit.defaultDuration.
 	defaultDuration: 200,
+
 	// dojoBlankHtmlUrl: String
-	//		Used by some modules to configure an empty iframe. Used by dojo.io.iframe and
-	//		dojo.back, and dijit popup support in IE where an iframe is needed to make sure native
+	//		Used by some modules to configure an empty iframe. Used by dojo/io/iframe and
+	//		dojo/back, and dijit/popup support in IE where an iframe is needed to make sure native
 	//		controls do not bleed through the popups. Normally this configuration variable
 	//		does not need to be set, except when using cross-domain/CDN Dojo builds.
 	//		Save dojo/resources/blank.html to your domain and set `djConfig.dojoBlankHtmlUrl`
 	//		to the path on your domain your copy of blank.html.
 	dojoBlankHtmlUrl: undefined,
-	//	ioPublish: Boolean?
+
+	// ioPublish: Boolean?
 	//		Set this to true to enable publishing of topics for the different phases of
-	//		IO operations. Publishing is done via dojo.publish. See dojo.__IoPublish for a list
+	//		IO operations. Publishing is done via dojo/topic.publish(). See dojo/main.__IoPublish for a list
 	//		of topics that are published.
 	ioPublish: false,
-	//	useCustomLogger: Anything?
+
+	// useCustomLogger: Anything?
 	//		If set to a value that evaluates to true such as a string or array and
 	//		isDebug is true and Firebug is not available or running, then it bypasses
 	//		the creation of Firebug Lite allowing you to define your own console object.
 	useCustomLogger: undefined,
+
 	// transparentColor: Array
 	//		Array containing the r, g, b components used as transparent color in dojo.Color;
 	//		if undefined, [255,255,255] (white) will be used.
 	transparentColor: undefined,
-	// skipIeDomLoaded: Boolean
-	//		For IE only, skip the DOMContentLoaded hack used. Sometimes it can cause an Operation
-	//		Aborted error if the rest of the page triggers script defers before the DOM is ready.
-	//		If this is config value is set to true, then dojo.addOnLoad callbacks will not be
-	//		triggered until the page load event, which is after images and iframes load. If you
-	//		want to trigger the callbacks sooner, you can put a script block in the bottom of
-	//		your HTML that calls dojo._loadInit();. If you are using multiversion support, change
-	//		"dojo." to the appropriate scope name for dojo.
-	skipIeDomLoaded: false
-}
+	
+	// deps: Function|Array
+	//		Defines dependencies to be used before the loader has been loaded.
+	//		When provided, they cause the loader to execute require(deps, callback) 
+	//		once it has finished loading. Should be used with callback.
+	deps: undefined,
+	
+	// callback: Function|Array
+	//		Defines a callback to be used when dependencies are defined before 
+	//		the loader has been loaded. When provided, they cause the loader to 
+	//		execute require(deps, callback) once it has finished loading. 
+	//		Should be used with deps.
+	callback: undefined,
+	
+	// deferredInstrumentation: Boolean
+	//		Whether deferred instrumentation should be loaded or included
+	//		in builds.
+	deferredInstrumentation: true,
+
+	// useDeferredInstrumentation: Boolean|String
+	//		Whether the deferred instrumentation should be used.
+	//
+	//		* `"report-rejections"`: report each rejection as it occurs.
+	//		* `true` or `1` or `"report-unhandled-rejections"`: wait 1 second
+	//			in an attempt to detect unhandled rejections.
+	useDeferredInstrumentation: "report-unhandled-rejections"
+};
 =====*/
+
+	var result = {};
+	if(has("dojo-config-api")){
+		// must be the dojo loader; take a shallow copy of require.rawConfig
+		var src = require.rawConfig, p;
+		for(p in src){
+			result[p] = src[p];
+		}
+	}else{
+		var adviseHas = function(featureSet, prefix, booting){
+			for(p in featureSet){
+				p!="has" && has.add(prefix + p, featureSet[p], 0, booting);
+			}
+		};
+		result = has("dojo-loader") ?
+			// must be a built version of the dojo loader; all config stuffed in require.rawConfig
+			require.rawConfig :
+			// a foreign loader
+			this.dojoConfig || this.djConfig || {};
+		adviseHas(result, "config", 1);
+		adviseHas(result.has, "", 1);
+	}
+
+	if(!result.locale && typeof navigator != "undefined"){
+		// Default locale for browsers.
+		result.locale = (navigator.language || navigator.userLanguage).toLowerCase();
+	}
+
+	return result;
 });
 
diff --git a/dojo/_base/configFirefoxExtension.js b/dojo/_base/configFirefoxExtension.js
index ce30c91..4115c61 100644
--- a/dojo/_base/configFirefoxExtension.js
+++ b/dojo/_base/configFirefoxExtension.js
@@ -78,14 +78,16 @@ if(typeof window != 'undefined'){
 		var hasBase = false;
 
 		dojo._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
-			// summary: Read the contents of the specified uri and return those contents.
+			// summary:
+			//		Read the contents of the specified uri and return those contents.
 			// uri:
 			//		A relative or absolute uri. If absolute, it still must be in
 			//		the same "domain" as we are.
 			// fail_ok:
 			//		Default false. If fail_ok and loading fails, return null
 			//		instead of throwing.
-			// returns: The response text. null is returned when there is a
+			// returns:
+			//		The response text. null is returned when there is a
 			//		failure and failure is okay (an exception otherwise)
 
 			// alert("_getText: " + uri);
@@ -178,12 +180,12 @@ if(typeof window != 'undefined'){
 		dojo._defaultContext = [ window, document ];
 
 		dojo.pushContext = function(/*Object|String?*/g, /*MDocumentElement?*/d){
-			//	summary:
+			// summary:
 			//		causes subsequent calls to Dojo methods to assume the
 			//		passed object and, optionally, document as the default
 			//		scopes to use. A 2-element array of the previous global and
 			//		document are returned.
-			//	description:
+			// description:
 			//		dojo.pushContext treats contexts as a stack. The
 			//		auto-detected contexts which are initially provided using
 			//		dojo.setContext() require authors to keep state in order to
@@ -199,10 +201,10 @@ if(typeof window != 'undefined'){
 			//		the context to push. This means that iframes can be given
 			//		an ID and code can be executed in the scope of the iframe's
 			//		document in subsequent calls easily.
-			//	g:
+			// g:
 			//		The global context. If a string, the id of the frame to
 			//		search for a context and document.
-			//	d:
+			// d:
 			//		The document element to execute subsequent code with.
 			var old = [dojo.global, dojo.doc];
 			contexts.push(old);
@@ -224,7 +226,7 @@ if(typeof window != 'undefined'){
 		};
 
 		dojo.popContext = function(){
-			//	summary:
+			// summary:
 			//		If the context stack contains elements, ensure that
 			//		subsequent code executes in the *previous* context to the
 			//		current context. The current context set ([global,
@@ -286,17 +288,17 @@ if(typeof window != 'undefined'){
 		};
 		// FIXME: PORT
 		// FIXME: dojo.unloaded requires dojo scope, so using anon function wrapper.
-		_handleNodeEvent("onbeforeunload", function() { dojo.unloaded(); });
-		_handleNodeEvent("onunload", function() { dojo.windowUnloaded(); });
+		_handleNodeEvent("onbeforeunload", function(){ dojo.unloaded(); });
+		_handleNodeEvent("onunload", function(){ dojo.windowUnloaded(); });
 	})();
 	*/
 
 
 	//	FIXME: PORTME
-	// 		this event fires a lot, namely for all plugin XUL overlays and for
-	// 		all iframes (in addition to window navigations). We only want
-	// 		Dojo's to fire once..but we might care if pages navigate. We'll
-	// 		probably need an extension-specific API
+	//		this event fires a lot, namely for all plugin XUL overlays and for
+	//		all iframes (in addition to window navigations). We only want
+	//		Dojo's to fire once..but we might care if pages navigate. We'll
+	//		probably need an extension-specific API
 	if(!dojo.config.afterOnLoad){
 		window.addEventListener("DOMContentLoaded", function(e){
 			dojo._loadInit(e);
diff --git a/dojo/_base/configNode.js b/dojo/_base/configNode.js
index 7cd6f14..1866795 100644
--- a/dojo/_base/configNode.js
+++ b/dojo/_base/configNode.js
@@ -1,5 +1,5 @@
 exports.config = function(config){
-	//	summary:
+	// summary:
 	//		This module provides bootstrap configuration for running dojo in node.js
 
 	// any command line arguments with the load flag are pushed into deps
@@ -15,7 +15,7 @@ exports.config = function(config){
 	var fs = require("fs");
 
 	// make sure global require exists
-	//if (typeof global.require=="undefined") {
+	//if (typeof global.require=="undefined"){
 	//	global.require= {};
 	//}
 
@@ -40,12 +40,12 @@ exports.config = function(config){
 		config.hasCache[p] = hasCache[p];
 	}
 
-	var vm = require('vm');
-
+	var vm = require('vm'),
+		path = require('path');
 
 	// reset some configuration switches with node-appropriate values
 	var nodeConfig = {
-		baseUrl: __dirname.match(/(.+)[\/\\]_base$/)[1],
+		baseUrl: path.dirname(process.argv[1]),
 		commandLineArgs:args,
 		deps:deps,
 		timeout:0,
diff --git a/dojo/_base/configRhino.js b/dojo/_base/configRhino.js
index ec64759..2cbbf88 100644
--- a/dojo/_base/configRhino.js
+++ b/dojo/_base/configRhino.js
@@ -1,5 +1,5 @@
 function rhinoDojoConfig(config, baseUrl, rhinoArgs){
-	//	summary:
+	// summary:
 	//		This module provides bootstrap configuration for running dojo in rhino.
 
 	// TODO: v1.6 tries to set dojo.doc and dojo.body in rhino; why?
diff --git a/dojo/_base/configSpidermonkey.js b/dojo/_base/configSpidermonkey.js
index 0da0d71..af16fda 100644
--- a/dojo/_base/configSpidermonkey.js
+++ b/dojo/_base/configSpidermonkey.js
@@ -1,9 +1,9 @@
 // TODO: this file needs to be converted to the v1.7 loader
 
-
-/*
- * SpiderMonkey host environment
- */
+// module:
+//		configSpidermonkey
+// summary:
+//		 SpiderMonkey host environment
 
 if(dojo.config["baseUrl"]){
 	dojo.baseUrl = dojo.config["baseUrl"];
@@ -13,11 +13,7 @@ if(dojo.config["baseUrl"]){
 
 dojo._name = 'spidermonkey';
 
-/*=====
-dojo.isSpidermonkey = {
-	// summary: Detect spidermonkey
-};
-=====*/
+
 
 dojo.isSpidermonkey = true;
 dojo.exit = function(exitcode){
diff --git a/dojo/_base/connect.js b/dojo/_base/connect.js
index fba6770..0f08bf2 100644
--- a/dojo/_base/connect.js
+++ b/dojo/_base/connect.js
@@ -1,14 +1,7 @@
-define(["./kernel", "../on", "../topic", "../aspect", "./event", "../mouse", "./sniff", "./lang", "../keys"], function(kernel, on, hub, aspect, eventModule, mouse, has, lang){
-//  module:
-//    dojo/_base/connect
-//  summary:
-//    This module defines the dojo.connect API.
-//		This modules also provides keyboard event handling helpers.
-//		This module exports an extension event for emulating Firefox's keypress handling.
-//		However, this extension event exists primarily for backwards compatibility and
-//		is not recommended. WebKit and IE uses an alternate keypress handling (only
-//		firing for printable characters, to distinguish from keydown events), and most
-//		consider the WebKit/IE behavior more desirable.
+define(["./kernel", "../on", "../topic", "../aspect", "./event", "../mouse", "./sniff", "./lang", "../keys"], function(dojo, on, hub, aspect, eventModule, mouse, has, lang){
+// module:
+//		dojo/_base/connect
+
 has.add("events-keypress-typed", function(){ // keypresses should only occur a printable character is hit
 	var testKeyEvent = {charCode: 0};
 	try{
@@ -23,13 +16,13 @@ function connect_(obj, event, context, method, dontFix){
 	if(!obj || !(obj.addEventListener || obj.attachEvent)){
 		// it is a not a DOM node and we are using the dojo.connect style of treating a
 		// method like an event, must go right to aspect
-		return aspect.after(obj || kernel.global, event, method, true);
+		return aspect.after(obj || dojo.global, event, method, true);
 	}
 	if(typeof event == "string" && event.substring(0, 2) == "on"){
 		event = event.substring(2);
 	}
 	if(!obj){
-		obj = kernel.global;
+		obj = dojo.global;
 	}
 	if(!dontFix){
 		switch(event){
@@ -99,7 +92,7 @@ if(has("events-keypress-typed")){
 			var k=evt.keyCode;
 			// These are Windows Virtual Key Codes
 			// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/VirtualKeyCodes.asp
-			var unprintable = (k!=13 || (has("ie") >= 9 && !has("quirks"))) && k!=32 && (k!=27||!has("ie")) && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222) && k!=229;
+			var unprintable = (k!=13) && k!=32 && (k!=27||!has("ie")) && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222) && k!=229;
 			// synthesize keypress for most unprintables and CTRL-keys
 			if(unprintable||evt.ctrlKey){
 				var c = unprintable ? 0 : k;
@@ -164,9 +157,115 @@ if(has("events-keypress-typed")){
 }
 
 var connect = {
+	// summary:
+	//		This module defines the dojo.connect API.
+	//		This modules also provides keyboard event handling helpers.
+	//		This module exports an extension event for emulating Firefox's keypress handling.
+	//		However, this extension event exists primarily for backwards compatibility and
+	//		is not recommended. WebKit and IE uses an alternate keypress handling (only
+	//		firing for printable characters, to distinguish from keydown events), and most
+	//		consider the WebKit/IE behavior more desirable.
+
 	_keypress:keypress,
 
 	connect:function(obj, event, context, method, dontFix){
+		// summary:
+		//		`dojo.connect` is a deprecated event handling and delegation method in
+		//		Dojo. It allows one function to "listen in" on the execution of
+		//		any other, triggering the second whenever the first is called. Many
+		//		listeners may be attached to a function, and source functions may
+		//		be either regular function calls or DOM events.
+		//
+		// description:
+		//		Connects listeners to actions, so that after event fires, a
+		//		listener is called with the same arguments passed to the original
+		//		function.
+		//
+		//		Since `dojo.connect` allows the source of events to be either a
+		//		"regular" JavaScript function or a DOM event, it provides a uniform
+		//		interface for listening to all the types of events that an
+		//		application is likely to deal with though a single, unified
+		//		interface. DOM programmers may want to think of it as
+		//		"addEventListener for everything and anything".
+		//
+		//		When setting up a connection, the `event` parameter must be a
+		//		string that is the name of the method/event to be listened for. If
+		//		`obj` is null, `kernel.global` is assumed, meaning that connections
+		//		to global methods are supported but also that you may inadvertently
+		//		connect to a global by passing an incorrect object name or invalid
+		//		reference.
+		//
+		//		`dojo.connect` generally is forgiving. If you pass the name of a
+		//		function or method that does not yet exist on `obj`, connect will
+		//		not fail, but will instead set up a stub method. Similarly, null
+		//		arguments may simply be omitted such that fewer than 4 arguments
+		//		may be required to set up a connection See the examples for details.
+		//
+		//		The return value is a handle that is needed to
+		//		remove this connection with `dojo.disconnect`.
+		//
+		// obj: Object?
+		//		The source object for the event function.
+		//		Defaults to `kernel.global` if null.
+		//		If obj is a DOM node, the connection is delegated
+		//		to the DOM event manager (unless dontFix is true).
+		//
+		// event: String
+		//		String name of the event function in obj.
+		//		I.e. identifies a property `obj[event]`.
+		//
+		// context: Object|null
+		//		The object that method will receive as "this".
+		//
+		//		If context is null and method is a function, then method
+		//		inherits the context of event.
+		//
+		//		If method is a string then context must be the source
+		//		object object for method (context[method]). If context is null,
+		//		kernel.global is used.
+		//
+		// method: String|Function
+		//		A function reference, or name of a function in context.
+		//		The function identified by method fires after event does.
+		//		method receives the same arguments as the event.
+		//		See context argument comments for information on method's scope.
+		//
+		// dontFix: Boolean?
+		//		If obj is a DOM node, set dontFix to true to prevent delegation
+		//		of this connection to the DOM event manager.
+		//
+		// example:
+		//		When obj.onchange(), do ui.update():
+		//	|	dojo.connect(obj, "onchange", ui, "update");
+		//	|	dojo.connect(obj, "onchange", ui, ui.update); // same
+		//
+		// example:
+		//		Using return value for disconnect:
+		//	|	var link = dojo.connect(obj, "onchange", ui, "update");
+		//	|	...
+		//	|	dojo.disconnect(link);
+		//
+		// example:
+		//		When onglobalevent executes, watcher.handler is invoked:
+		//	|	dojo.connect(null, "onglobalevent", watcher, "handler");
+		//
+		// example:
+		//		When ob.onCustomEvent executes, customEventHandler is invoked:
+		//	|	dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
+		//	|	dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
+		//
+		// example:
+		//		When ob.onCustomEvent executes, customEventHandler is invoked
+		//		with the same scope (this):
+		//	|	dojo.connect(ob, "onCustomEvent", null, customEventHandler);
+		//	|	dojo.connect(ob, "onCustomEvent", customEventHandler); // same
+		//
+		// example:
+		//		When globalEvent executes, globalHandler is invoked
+		//		with the same scope (this):
+		//	|	dojo.connect(null, "globalEvent", null, globalHandler);
+		//	|	dojo.connect("globalEvent", globalHandler); // same
+
 		// normalize arguments
 		var a=arguments, args=[], i=0;
 		// if a[0] is a String, obj was omitted
@@ -180,220 +279,95 @@ var connect = {
 	},
 
 	disconnect:function(handle){
+		// summary:
+		//		Remove a link created by dojo.connect.
+		// description:
+		//		Removes the connection between event and the method referenced by handle.
+		// handle: Handle
+		//		the return value of the dojo.connect call that created the connection.
+
 		if(handle){
 			handle.remove();
 		}
 	},
 
 	subscribe:function(topic, context, method){
+		// summary:
+		//		Attach a listener to a named topic. The listener function is invoked whenever the
+		//		named topic is published (see: dojo.publish).
+		//		Returns a handle which is needed to unsubscribe this listener.
+		// topic: String
+		//		The topic to which to subscribe.
+		// context: Object?
+		//		Scope in which method will be invoked, or null for default scope.
+		// method: String|Function
+		//		The name of a function in context, or a function reference. This is the function that
+		//		is invoked when topic is published.
+		// example:
+		//	|	dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
+		//	|	dojo.publish("alerts", [ "read this", "hello world" ]);
 		return hub.subscribe(topic, lang.hitch(context, method));
 	},
 
 	publish:function(topic, args){
+		// summary:
+		//		Invoke all listener method subscribed to topic.
+		// topic: String
+		//		The name of the topic to publish.
+		// args: Array?
+		//		An array of arguments. The arguments will be applied
+		//		to each topic subscriber (as first class parameters, via apply).
+		// example:
+		//	|	dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
+		//	|	dojo.publish("alerts", [ "read this", "hello world" ]);
 		return hub.publish.apply(hub, [topic].concat(args));
 	},
 
 	connectPublisher:function(topic, obj, event){
+		// summary:
+		//		Ensure that every time obj.event() is called, a message is published
+		//		on the topic. Returns a handle which can be passed to
+		//		dojo.disconnect() to disable subsequent automatic publication on
+		//		the topic.
+		// topic: String
+		//		The name of the topic to publish.
+		// obj: Object?
+		//		The source object for the event function. Defaults to kernel.global
+		//		if null.
+		// event: String
+		//		The name of the event function in obj.
+		//		I.e. identifies a property obj[event].
+		// example:
+		//	|	dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
 		var pf = function(){ connect.publish(topic, arguments); };
 		return event ? connect.connect(obj, event, pf) : connect.connect(obj, pf); //Handle
 	},
 
 	isCopyKey: function(e){
+		// summary:
+		//		Checks an event for the copy key (meta on Mac, and ctrl anywhere else)
+		// e: Event
+		//		Event object to examine
 		return e[evtCopyKey];	// Boolean
 	}
 };
-connect.unsubscribe = connect.disconnect;
-
-has("extend-dojo") && lang.mixin(kernel, connect);
-return connect;
-
-/*=====
-dojo.connect = function(obj, event, context, method, dontFix){
-	// summary:
-	//		`dojo.connect` is the core event handling and delegation method in
-	//		Dojo. It allows one function to "listen in" on the execution of
-	//		any other, triggering the second whenever the first is called. Many
-	//		listeners may be attached to a function, and source functions may
-	//		be either regular function calls or DOM events.
-	//
-	// description:
-	//		Connects listeners to actions, so that after event fires, a
-	//		listener is called with the same arguments passed to the original
-	//		function.
-	//
-	//		Since `dojo.connect` allows the source of events to be either a
-	//		"regular" JavaScript function or a DOM event, it provides a uniform
-	//		interface for listening to all the types of events that an
-	//		application is likely to deal with though a single, unified
-	//		interface. DOM programmers may want to think of it as
-	//		"addEventListener for everything and anything".
-	//
-	//		When setting up a connection, the `event` parameter must be a
-	//		string that is the name of the method/event to be listened for. If
-	//		`obj` is null, `kernel.global` is assumed, meaning that connections
-	//		to global methods are supported but also that you may inadvertently
-	//		connect to a global by passing an incorrect object name or invalid
-	//		reference.
-	//
-	//		`dojo.connect` generally is forgiving. If you pass the name of a
-	//		function or method that does not yet exist on `obj`, connect will
-	//		not fail, but will instead set up a stub method. Similarly, null
-	//		arguments may simply be omitted such that fewer than 4 arguments
-	//		may be required to set up a connection See the examples for details.
-	//
-	//		The return value is a handle that is needed to
-	//		remove this connection with `dojo.disconnect`.
-	//
-	// obj: Object|null:
-	//		The source object for the event function.
-	//		Defaults to `kernel.global` if null.
-	//		If obj is a DOM node, the connection is delegated
-	//		to the DOM event manager (unless dontFix is true).
-	//
-	// event: String:
-	//		String name of the event function in obj.
-	//		I.e. identifies a property `obj[event]`.
-	//
-	// context: Object|null
-	//		The object that method will receive as "this".
-	//
-	//		If context is null and method is a function, then method
-	//		inherits the context of event.
-	//
-	//		If method is a string then context must be the source
-	//		object object for method (context[method]). If context is null,
-	//		kernel.global is used.
-	//
-	// method: String|Function:
-	//		A function reference, or name of a function in context.
-	//		The function identified by method fires after event does.
-	//		method receives the same arguments as the event.
-	//		See context argument comments for information on method's scope.
-	//
-	// dontFix: Boolean?
-	//		If obj is a DOM node, set dontFix to true to prevent delegation
-	//		of this connection to the DOM event manager.
-	//
-	// example:
-	//		When obj.onchange(), do ui.update():
-	//	|	dojo.connect(obj, "onchange", ui, "update");
-	//	|	dojo.connect(obj, "onchange", ui, ui.update); // same
-	//
-	// example:
-	//		Using return value for disconnect:
-	//	|	var link = dojo.connect(obj, "onchange", ui, "update");
-	//	|	...
-	//	|	dojo.disconnect(link);
-	//
-	// example:
-	//		When onglobalevent executes, watcher.handler is invoked:
-	//	|	dojo.connect(null, "onglobalevent", watcher, "handler");
-	//
-	// example:
-	//		When ob.onCustomEvent executes, customEventHandler is invoked:
-	//	|	dojo.connect(ob, "onCustomEvent", null, "customEventHandler");
-	//	|	dojo.connect(ob, "onCustomEvent", "customEventHandler"); // same
-	//
-	// example:
-	//		When ob.onCustomEvent executes, customEventHandler is invoked
-	//		with the same scope (this):
-	//	|	dojo.connect(ob, "onCustomEvent", null, customEventHandler);
-	//	|	dojo.connect(ob, "onCustomEvent", customEventHandler); // same
-	//
-	// example:
-	//		When globalEvent executes, globalHandler is invoked
-	//		with the same scope (this):
-	//	|	dojo.connect(null, "globalEvent", null, globalHandler);
-	//	|	dojo.connect("globalEvent", globalHandler); // same
-}
-=====*/
-
-/*=====
-dojo.disconnect = function(handle){
-	// summary:
-	//		Remove a link created by dojo.connect.
-	// description:
-	//		Removes the connection between event and the method referenced by handle.
-	// handle: Handle:
-	//		the return value of the dojo.connect call that created the connection.
-}
-=====*/
-
-/*=====
-dojo.subscribe = function(topic, context, method){
-	//	summary:
-	//		Attach a listener to a named topic. The listener function is invoked whenever the
-	//		named topic is published (see: dojo.publish).
-	//		Returns a handle which is needed to unsubscribe this listener.
-	//	topic: String:
-	//		The topic to which to subscribe.
-	//	context: Object|null:
-	//		Scope in which method will be invoked, or null for default scope.
-	//	method: String|Function:
-	//		The name of a function in context, or a function reference. This is the function that
-	//		is invoked when topic is published.
-	//	example:
-	//	|	dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
-	//	|	dojo.publish("alerts", [ "read this", "hello world" ]);
-}
-=====*/
-
-/*=====
-dojo.unsubscribe = function(handle){
-	//	summary:
-	//		Remove a topic listener.
-	//	handle: Handle
-	//		The handle returned from a call to subscribe.
-	//	example:
-	//	|	var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
-	//	|	...
-	//	|	dojo.unsubscribe(alerter);
-}
-=====*/
-
-/*=====
-dojo.publish = function(topic, args){
-	//	summary:
-	//		Invoke all listener method subscribed to topic.
-	//	topic: String:
-	//		The name of the topic to publish.
-	//	args: Array?
-	//		An array of arguments. The arguments will be applied
-	//		to each topic subscriber (as first class parameters, via apply).
-	//	example:
-	//	|	dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
-	//	|	dojo.publish("alerts", [ "read this", "hello world" ]);
-}
-=====*/
 
+connect.unsubscribe = connect.disconnect;
 /*=====
-dojo.connectPublisher = function(topic, obj, event){
-	//	summary:
-	//		Ensure that every time obj.event() is called, a message is published
-	//		on the topic. Returns a handle which can be passed to
-	//		dojo.disconnect() to disable subsequent automatic publication on
-	//		the topic.
-	//	topic: String:
-	//		The name of the topic to publish.
-	//	obj: Object|null:
-	//		The source object for the event function. Defaults to kernel.global
-	//		if null.
-	//	event: String:
-	//		The name of the event function in obj.
-	//		I.e. identifies a property obj[event].
-	//	example:
-	//	|	dojo.connectPublisher("/ajax/start", dojo, "xhrGet");
-}
-=====*/
+ connect.unsubscribe = function(handle){
+	 // summary:
+	 //		Remove a topic listener.
+	 // handle: Handle
+	 //		The handle returned from a call to subscribe.
+	 // example:
+	 //	|	var alerter = dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); };
+	 //	|	...
+	 //	|	dojo.unsubscribe(alerter);
+ };
+ =====*/
 
-/*=====
-dojo.isCopyKey = function(e){
-	// summary:
-	//		Checks an event for the copy key (meta on Mac, and ctrl anywhere else)
-	// e: Event
-	//		Event object to examine
-}
-=====*/
+has("extend-dojo") && lang.mixin(dojo, connect);
+return connect;
 
 });
 
diff --git a/dojo/_base/declare.js b/dojo/_base/declare.js
index 91cc265..72748c0 100644
--- a/dojo/_base/declare.js
+++ b/dojo/_base/declare.js
@@ -1,8 +1,6 @@
 define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 	// module:
 	//		dojo/_base/declare
-	// summary:
-	//		This module defines dojo.declare.
 
 	var mix = lang.mixin, op = Object.prototype, opts = op.toString,
 		xtor = new Function, counter = 0, cname = "constructor";
@@ -238,6 +236,63 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 
 	// implementation of safe mixin function
 	function safeMixin(target, source){
+		// summary:
+		//		Mix in properties skipping a constructor and decorating functions
+		//		like it is done by declare().
+		// target: Object
+		//		Target object to accept new properties.
+		// source: Object
+		//		Source object for new properties.
+		// description:
+		//		This function is used to mix in properties like lang.mixin does,
+		//		but it skips a constructor property and decorates functions like
+		//		declare() does.
+		//
+		//		It is meant to be used with classes and objects produced with
+		//		declare. Functions mixed in with dojo.safeMixin can use
+		//		this.inherited() like normal methods.
+		//
+		//		This function is used to implement extend() method of a constructor
+		//		produced with declare().
+		//
+		// example:
+		//	|	var A = declare(null, {
+		//	|		m1: function(){
+		//	|			console.log("A.m1");
+		//	|		},
+		//	|		m2: function(){
+		//	|			console.log("A.m2");
+		//	|		}
+		//	|	});
+		//	|	var B = declare(A, {
+		//	|		m1: function(){
+		//	|			this.inherited(arguments);
+		//	|			console.log("B.m1");
+		//	|		}
+		//	|	});
+		//	|	B.extend({
+		//	|		m2: function(){
+		//	|			this.inherited(arguments);
+		//	|			console.log("B.m2");
+		//	|		}
+		//	|	});
+		//	|	var x = new B();
+		//	|	dojo.safeMixin(x, {
+		//	|		m1: function(){
+		//	|			this.inherited(arguments);
+		//	|			console.log("X.m1");
+		//	|		},
+		//	|		m2: function(){
+		//	|			this.inherited(arguments);
+		//	|			console.log("X.m2");
+		//	|		}
+		//	|	});
+		//	|	x.m2();
+		//	|	// prints:
+		//	|	// A.m1
+		//	|	// B.m1
+		//	|	// X.m1
+
 		var name, t;
 		// add props adding metadata for incoming functions skipping a constructor
 		for(name in source){
@@ -271,7 +326,11 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 		return this;
 	}
 
-	// chained constructor compatible with the legacy dojo.declare()
+	function createSubclass(mixins, props){
+		return declare([this].concat(mixins), props || {});
+	}
+
+	// chained constructor compatible with the legacy declare()
 	function chainedConstructor(bases, ctorSpecial){
 		return function(){
 			var a = arguments, args = a, a0 = a[0], f, i, m,
@@ -283,7 +342,7 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 			}
 
 			//this._inherited = {};
-			// perform the shaman's rituals of the original dojo.declare()
+			// perform the shaman's rituals of the original declare()
 			// 1) call two types of the preamble
 			if(ctorSpecial && (a0 && a0.preamble || this.preamble)){
 				// full blown ritual
@@ -334,7 +393,7 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 	}
 
 
-	// chained constructor compatible with the legacy dojo.declare()
+	// chained constructor compatible with the legacy declare()
 	function singleConstructor(ctor, ctorSpecial){
 		return function(){
 			var a = arguments, t = a, a0 = a[0], f;
@@ -345,7 +404,7 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 			}
 
 			//this._inherited = {};
-			// perform the shaman's rituals of the original dojo.declare()
+			// perform the shaman's rituals of the original declare()
 			// 1) call two types of the preamble
 			if(ctorSpecial){
 				// full blown ritual
@@ -390,7 +449,7 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 			}
 
 			//this._inherited = {};
-			// perform the shaman's rituals of the original dojo.declare()
+			// perform the shaman's rituals of the original declare()
 			// 1) do not call the preamble
 			// 2) call the top constructor (it can use this.inherited())
 			for(; f = bases[i]; ++i){ // intentional assignment
@@ -451,134 +510,23 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 	}
 
 	function declare(className, superclass, props){
-		// crack parameters
-		if(typeof className != "string"){
-			props = superclass;
-			superclass = className;
-			className = "";
-		}
-		props = props || {};
-
-		var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;
-
-		// build a prototype
-		if(opts.call(superclass) == "[object Array]"){
-			// C3 MRO
-			bases = c3mro(superclass, className);
-			t = bases[0];
-			mixins = bases.length - t;
-			superclass = bases[mixins];
-		}else{
-			bases = [0];
-			if(superclass){
-				if(opts.call(superclass) == "[object Function]"){
-					t = superclass._meta;
-					bases = bases.concat(t ? t.bases : superclass);
-				}else{
-					err("base class is not a callable constructor.", className);
-				}
-			}else if(superclass !== null){
-				err("unknown base class. Did you use dojo.require to pull it in?", className);
-			}
-		}
-		if(superclass){
-			for(i = mixins - 1;; --i){
-				proto = forceNew(superclass);
-				if(!i){
-					// stop if nothing to add (the last base)
-					break;
-				}
-				// mix in properties
-				t = bases[i];
-				(t._meta ? mixOwn : mix)(proto, t.prototype);
-				// chain in new constructor
-				ctor = new Function;
-				ctor.superclass = superclass;
-				ctor.prototype = proto;
-				superclass = proto.constructor = ctor;
-			}
-		}else{
-			proto = {};
-		}
-		// add all properties
-		declare.safeMixin(proto, props);
-		// add constructor
-		t = props.constructor;
-		if(t !== op.constructor){
-			t.nom = cname;
-			proto.constructor = t;
-		}
-
-		// collect chains and flags
-		for(i = mixins - 1; i; --i){ // intentional assignment
-			t = bases[i]._meta;
-			if(t && t.chains){
-				chains = mix(chains || {}, t.chains);
-			}
-		}
-		if(proto["-chains-"]){
-			chains = mix(chains || {}, proto["-chains-"]);
-		}
-
-		// build ctor
-		t = !chains || !chains.hasOwnProperty(cname);
-		bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
-			(bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));
-
-		// add meta information to the constructor
-		ctor._meta  = {bases: bases, hidden: props, chains: chains,
-			parents: parents, ctor: props.constructor};
-		ctor.superclass = superclass && superclass.prototype;
-		ctor.extend = extend;
-		ctor.prototype = proto;
-		proto.constructor = ctor;
-
-		// add "standard" methods to the prototype
-		proto.getInherited = getInherited;
-		proto.isInstanceOf = isInstanceOf;
-		proto.inherited    = inheritedImpl;
-		proto.__inherited  = inherited;
-
-		// add name if specified
-		if(className){
-			proto.declaredClass = className;
-			lang.setObject(className, ctor);
-		}
-
-		// build chains and add them to the prototype
-		if(chains){
-			for(name in chains){
-				if(proto[name] && typeof chains[name] == "string" && name != cname){
-					t = proto[name] = chain(name, bases, chains[name] === "after");
-					t.nom = name;
-				}
-			}
-		}
-		// chained methods do not return values
-		// no need to chain "invisible" functions
-
-		return ctor;	// Function
-	}
-
-	/*=====
-	dojo.declare = function(className, superclass, props){
-		//	summary:
+		// summary:
 		//		Create a feature-rich constructor from compact notation.
-		//	className: String?:
+		// className: String?
 		//		The optional name of the constructor (loosely, a "class")
 		//		stored in the "declaredClass" property in the created prototype.
 		//		It will be used as a global name for a created constructor.
-		//	superclass: Function|Function[]:
+		// superclass: Function|Function[]
 		//		May be null, a Function, or an Array of Functions. This argument
 		//		specifies a list of bases (the left-most one is the most deepest
 		//		base).
-		//	props: Object:
+		// props: Object
 		//		An object whose properties are copied to the created prototype.
 		//		Add an instance-initialization function by making it a property
 		//		named "constructor".
-		//	returns:
+		// returns: dojo/_base/declare.__DeclareCreatedObject
 		//		New constructor function.
-		//	description:
+		// description:
 		//		Create a constructor using a compact notation for inheritance and
 		//		prototype extension.
 		//
@@ -588,7 +536,7 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 		//		they have been mixed in.
 		//
 		//		Ancestors can be compound classes created by this version of
-		//		dojo.declare. In complex cases all base classes are going to be
+		//		declare(). In complex cases all base classes are going to be
 		//		linearized according to C3 MRO algorithm
 		//		(see http://www.python.org/download/releases/2.3/mro/ for more
 		//		details).
@@ -605,7 +553,7 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 		//		cases.
 		//
 		//		It is possible to use constructors created "manually" (without
-		//		dojo.declare) as bases. They will be called as usual during the
+		//		declare()) as bases. They will be called as usual during the
 		//		creation of an instance, their methods will be chained, and even
 		//		called by "this.inherited()".
 		//
@@ -645,8 +593,8 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 		//		"before". Note that chaining assumes that chained methods do not
 		//		return any value: any returned value will be discarded.
 		//
-		//	example:
-		//	|	dojo.declare("my.classes.bar", my.classes.foo, {
+		// example:
+		//	|	declare("my.classes.bar", my.classes.foo, {
 		//	|		// properties to be added to the class prototype
 		//	|		someValue: 2,
 		//	|		// initialization function
@@ -659,30 +607,30 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 		//	|		}
 		//	|	});
 		//
-		//	example:
-		//	|	var MyBase = dojo.declare(null, {
+		// example:
+		//	|	var MyBase = declare(null, {
 		//	|		// constructor, properties, and methods go here
 		//	|		// ...
 		//	|	});
-		//	|	var MyClass1 = dojo.declare(MyBase, {
+		//	|	var MyClass1 = declare(MyBase, {
 		//	|		// constructor, properties, and methods go here
 		//	|		// ...
 		//	|	});
-		//	|	var MyClass2 = dojo.declare(MyBase, {
+		//	|	var MyClass2 = declare(MyBase, {
 		//	|		// constructor, properties, and methods go here
 		//	|		// ...
 		//	|	});
-		//	|	var MyDiamond = dojo.declare([MyClass1, MyClass2], {
+		//	|	var MyDiamond = declare([MyClass1, MyClass2], {
 		//	|		// constructor, properties, and methods go here
 		//	|		// ...
 		//	|	});
 		//
-		//	example:
+		// example:
 		//	|	var F = function(){ console.log("raw constructor"); };
 		//	|	F.prototype.method = function(){
 		//	|		console.log("raw method");
 		//	|	};
-		//	|	var A = dojo.declare(F, {
+		//	|	var A = declare(F, {
 		//	|		constructor: function(){
 		//	|			console.log("A.constructor");
 		//	|		},
@@ -700,13 +648,13 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 		//	|	// raw method
 		//	|	// ...back in A
 		//
-		//	example:
-		//	|	var A = dojo.declare(null, {
+		// example:
+		//	|	var A = declare(null, {
 		//	|		"-chains-": {
 		//	|			destroy: "before"
 		//	|		}
 		//	|	});
-		//	|	var B = dojo.declare(A, {
+		//	|	var B = declare(A, {
 		//	|		constructor: function(){
 		//	|			console.log("B.constructor");
 		//	|		},
@@ -714,7 +662,7 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 		//	|			console.log("B.destroy");
 		//	|		}
 		//	|	});
-		//	|	var C = dojo.declare(B, {
+		//	|	var C = declare(B, {
 		//	|		constructor: function(){
 		//	|			console.log("C.constructor");
 		//	|		},
@@ -729,13 +677,13 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 		//	|	// C.destroy
 		//	|	// B.destroy
 		//
-		//	example:
-		//	|	var A = dojo.declare(null, {
+		// example:
+		//	|	var A = declare(null, {
 		//	|		"-chains-": {
 		//	|			constructor: "manual"
 		//	|		}
 		//	|	});
-		//	|	var B = dojo.declare(A, {
+		//	|	var B = declare(A, {
 		//	|		constructor: function(){
 		//	|			// ...
 		//	|			// call the base constructor with new parameters
@@ -744,8 +692,8 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 		//	|		}
 		//	|	});
 		//
-		//	example:
-		//	|	var A = dojo.declare(null, {
+		// example:
+		//	|	var A = declare(null, {
 		//	|		"-chains-": {
 		//	|			m1: "before"
 		//	|		},
@@ -756,7 +704,7 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 		//	|			console.log("A.m2");
 		//	|		}
 		//	|	});
-		//	|	var B = dojo.declare(A, {
+		//	|	var B = declare(A, {
 		//	|		"-chains-": {
 		//	|			m2: "after"
 		//	|		},
@@ -776,273 +724,364 @@ define(["./kernel", "../has", "./lang"], function(dojo, has, lang){
 		//	|	// prints:
 		//	|	// A.m2
 		//	|	// B.m2
-		return new Function(); // Function
-	};
-	=====*/
 
-	/*=====
-	dojo.safeMixin = function(target, source){
-		//	summary:
-		//		Mix in properties skipping a constructor and decorating functions
-		//		like it is done by dojo.declare.
-		//	target: Object
-		//		Target object to accept new properties.
-		//	source: Object
-		//		Source object for new properties.
-		//	description:
-		//		This function is used to mix in properties like lang.mixin does,
-		//		but it skips a constructor property and decorates functions like
-		//		dojo.declare does.
-		//
-		//		It is meant to be used with classes and objects produced with
-		//		dojo.declare. Functions mixed in with dojo.safeMixin can use
-		//		this.inherited() like normal methods.
-		//
-		//		This function is used to implement extend() method of a constructor
-		//		produced with dojo.declare().
-		//
-		//	example:
-		//	|	var A = dojo.declare(null, {
-		//	|		m1: function(){
-		//	|			console.log("A.m1");
-		//	|		},
-		//	|		m2: function(){
-		//	|			console.log("A.m2");
-		//	|		}
-		//	|	});
-		//	|	var B = dojo.declare(A, {
-		//	|		m1: function(){
-		//	|			this.inherited(arguments);
-		//	|			console.log("B.m1");
-		//	|		}
-		//	|	});
-		//	|	B.extend({
-		//	|		m2: function(){
-		//	|			this.inherited(arguments);
-		//	|			console.log("B.m2");
-		//	|		}
-		//	|	});
-		//	|	var x = new B();
-		//	|	dojo.safeMixin(x, {
-		//	|		m1: function(){
-		//	|			this.inherited(arguments);
-		//	|			console.log("X.m1");
-		//	|		},
-		//	|		m2: function(){
-		//	|			this.inherited(arguments);
-		//	|			console.log("X.m2");
-		//	|		}
-		//	|	});
-		//	|	x.m2();
-		//	|	// prints:
-		//	|	// A.m1
-		//	|	// B.m1
-		//	|	// X.m1
-	};
-	=====*/
+		// crack parameters
+		if(typeof className != "string"){
+			props = superclass;
+			superclass = className;
+			className = "";
+		}
+		props = props || {};
 
-	/*=====
-	Object.inherited = function(name, args, newArgs){
-		//	summary:
-		//		Calls a super method.
-		//	name: String?
-		//		The optional method name. Should be the same as the caller's
-		//		name. Usually "name" is specified in complex dynamic cases, when
-		//		the calling method was dynamically added, undecorated by
-		//		dojo.declare, and it cannot be determined.
-		//	args: Arguments
-		//		The caller supply this argument, which should be the original
-		//		"arguments".
-		//	newArgs: Object?
-		//		If "true", the found function will be returned without
-		//		executing it.
-		//		If Array, it will be used to call a super method. Otherwise
-		//		"args" will be used.
-		//	returns:
-		//		Whatever is returned by a super method, or a super method itself,
-		//		if "true" was specified as newArgs.
-		//	description:
-		//		This method is used inside method of classes produced with
-		//		dojo.declare to call a super method (next in the chain). It is
-		//		used for manually controlled chaining. Consider using the regular
-		//		chaining, because it is faster. Use "this.inherited()" only in
-		//		complex cases.
-		//
-		//		This method cannot me called from automatically chained
-		//		constructors including the case of a special (legacy)
-		//		constructor chaining. It cannot be called from chained methods.
-		//
-		//		If "this.inherited()" cannot find the next-in-chain method, it
-		//		does nothing and returns "undefined". The last method in chain
-		//		can be a default method implemented in Object, which will be
-		//		called last.
-		//
-		//		If "name" is specified, it is assumed that the method that
-		//		received "args" is the parent method for this call. It is looked
-		//		up in the chain list and if it is found the next-in-chain method
-		//		is called. If it is not found, the first-in-chain method is
-		//		called.
-		//
-		//		If "name" is not specified, it will be derived from the calling
-		//		method (using a methoid property "nom").
-		//
-		//	example:
-		//	|	var B = dojo.declare(A, {
-		//	|		method1: function(a, b, c){
-		//	|			this.inherited(arguments);
-		//	|		},
-		//	|		method2: function(a, b){
-		//	|			return this.inherited(arguments, [a + b]);
-		//	|		}
-		//	|	});
-		//	|	// next method is not in the chain list because it is added
-		//	|	// manually after the class was created.
-		//	|	B.prototype.method3 = function(){
-		//	|		console.log("This is a dynamically-added method.");
-		//	|		this.inherited("method3", arguments);
-		//	|	};
-		//	example:
-		//	|	var B = dojo.declare(A, {
-		//	|		method: function(a, b){
-		//	|			var super = this.inherited(arguments, true);
-		//	|			// ...
-		//	|			if(!super){
-		//	|				console.log("there is no super method");
-		//	|				return 0;
-		//	|			}
-		//	|			return super.apply(this, arguments);
-		//	|		}
-		//	|	});
-		return	{};	// Object
-	}
-	=====*/
+		var proto, i, t, ctor, name, bases, chains, mixins = 1, parents = superclass;
 
-	/*=====
-	Object.getInherited = function(name, args){
-		//	summary:
-		//		Returns a super method.
-		//	name: String?
-		//		The optional method name. Should be the same as the caller's
-		//		name. Usually "name" is specified in complex dynamic cases, when
-		//		the calling method was dynamically added, undecorated by
-		//		dojo.declare, and it cannot be determined.
-		//	args: Arguments
-		//		The caller supply this argument, which should be the original
-		//		"arguments".
-		//	returns:
-		//		Returns a super method (Function) or "undefined".
-		//	description:
-		//		This method is a convenience method for "this.inherited()".
-		//		It uses the same algorithm but instead of executing a super
-		//		method, it returns it, or "undefined" if not found.
-		//
-		//	example:
-		//	|	var B = dojo.declare(A, {
-		//	|		method: function(a, b){
-		//	|			var super = this.getInherited(arguments);
-		//	|			// ...
-		//	|			if(!super){
-		//	|				console.log("there is no super method");
-		//	|				return 0;
-		//	|			}
-		//	|			return super.apply(this, arguments);
-		//	|		}
-		//	|	});
-		return	{};	// Object
-	}
-	=====*/
+		// build a prototype
+		if(opts.call(superclass) == "[object Array]"){
+			// C3 MRO
+			bases = c3mro(superclass, className);
+			t = bases[0];
+			mixins = bases.length - t;
+			superclass = bases[mixins];
+		}else{
+			bases = [0];
+			if(superclass){
+				if(opts.call(superclass) == "[object Function]"){
+					t = superclass._meta;
+					bases = bases.concat(t ? t.bases : superclass);
+				}else{
+					err("base class is not a callable constructor.", className);
+				}
+			}else if(superclass !== null){
+				err("unknown base class. Did you use dojo.require to pull it in?", className);
+			}
+		}
+		if(superclass){
+			for(i = mixins - 1;; --i){
+				proto = forceNew(superclass);
+				if(!i){
+					// stop if nothing to add (the last base)
+					break;
+				}
+				// mix in properties
+				t = bases[i];
+				(t._meta ? mixOwn : mix)(proto, t.prototype);
+				// chain in new constructor
+				ctor = new Function;
+				ctor.superclass = superclass;
+				ctor.prototype = proto;
+				superclass = proto.constructor = ctor;
+			}
+		}else{
+			proto = {};
+		}
+		// add all properties
+		declare.safeMixin(proto, props);
+		// add constructor
+		t = props.constructor;
+		if(t !== op.constructor){
+			t.nom = cname;
+			proto.constructor = t;
+		}
 
-	/*=====
-	Object.isInstanceOf = function(cls){
-		//	summary:
-		//		Checks the inheritance chain to see if it is inherited from this
-		//		class.
-		//	cls: Function
-		//		Class constructor.
-		//	returns:
-		//		"true", if this object is inherited from this class, "false"
-		//		otherwise.
-		//	description:
-		//		This method is used with instances of classes produced with
-		//		dojo.declare to determine of they support a certain interface or
-		//		not. It models "instanceof" operator.
-		//
-		//	example:
-		//	|	var A = dojo.declare(null, {
-		//	|		// constructor, properties, and methods go here
-		//	|		// ...
-		//	|	});
-		//	|	var B = dojo.declare(null, {
-		//	|		// constructor, properties, and methods go here
-		//	|		// ...
-		//	|	});
-		//	|	var C = dojo.declare([A, B], {
-		//	|		// constructor, properties, and methods go here
-		//	|		// ...
-		//	|	});
-		//	|	var D = dojo.declare(A, {
-		//	|		// constructor, properties, and methods go here
-		//	|		// ...
-		//	|	});
-		//	|
-		//	|	var a = new A(), b = new B(), c = new C(), d = new D();
-		//	|
-		//	|	console.log(a.isInstanceOf(A)); // true
-		//	|	console.log(b.isInstanceOf(A)); // false
-		//	|	console.log(c.isInstanceOf(A)); // true
-		//	|	console.log(d.isInstanceOf(A)); // true
-		//	|
-		//	|	console.log(a.isInstanceOf(B)); // false
-		//	|	console.log(b.isInstanceOf(B)); // true
-		//	|	console.log(c.isInstanceOf(B)); // true
-		//	|	console.log(d.isInstanceOf(B)); // false
-		//	|
-		//	|	console.log(a.isInstanceOf(C)); // false
-		//	|	console.log(b.isInstanceOf(C)); // false
-		//	|	console.log(c.isInstanceOf(C)); // true
-		//	|	console.log(d.isInstanceOf(C)); // false
-		//	|
-		//	|	console.log(a.isInstanceOf(D)); // false
-		//	|	console.log(b.isInstanceOf(D)); // false
-		//	|	console.log(c.isInstanceOf(D)); // false
-		//	|	console.log(d.isInstanceOf(D)); // true
-		return	{};	// Object
+		// collect chains and flags
+		for(i = mixins - 1; i; --i){ // intentional assignment
+			t = bases[i]._meta;
+			if(t && t.chains){
+				chains = mix(chains || {}, t.chains);
+			}
+		}
+		if(proto["-chains-"]){
+			chains = mix(chains || {}, proto["-chains-"]);
+		}
+
+		// build ctor
+		t = !chains || !chains.hasOwnProperty(cname);
+		bases[0] = ctor = (chains && chains.constructor === "manual") ? simpleConstructor(bases) :
+			(bases.length == 1 ? singleConstructor(props.constructor, t) : chainedConstructor(bases, t));
+
+		// add meta information to the constructor
+		ctor._meta  = {bases: bases, hidden: props, chains: chains,
+			parents: parents, ctor: props.constructor};
+		ctor.superclass = superclass && superclass.prototype;
+		ctor.extend = extend;
+		ctor.createSubclass = createSubclass;
+		ctor.prototype = proto;
+		proto.constructor = ctor;
+
+		// add "standard" methods to the prototype
+		proto.getInherited = getInherited;
+		proto.isInstanceOf = isInstanceOf;
+		proto.inherited    = inheritedImpl;
+		proto.__inherited  = inherited;
+
+		// add name if specified
+		if(className){
+			proto.declaredClass = className;
+			lang.setObject(className, ctor);
+		}
+
+		// build chains and add them to the prototype
+		if(chains){
+			for(name in chains){
+				if(proto[name] && typeof chains[name] == "string" && name != cname){
+					t = proto[name] = chain(name, bases, chains[name] === "after");
+					t.nom = name;
+				}
+			}
+		}
+		// chained methods do not return values
+		// no need to chain "invisible" functions
+
+		return ctor;	// Function
 	}
-	=====*/
 
 	/*=====
-	Object.extend = function(source){
-		//	summary:
-		//		Adds all properties and methods of source to constructor's
-		//		prototype, making them available to all instances created with
-		//		constructor. This method is specific to constructors created with
-		//		dojo.declare.
-		//	source: Object
-		//		Source object which properties are going to be copied to the
-		//		constructor's prototype.
-		//	description:
-		//		Adds source properties to the constructor's prototype. It can
-		//		override existing properties.
-		//
-		//		This method is similar to dojo.extend function, but it is specific
-		//		to constructors produced by dojo.declare. It is implemented
-		//		using dojo.safeMixin, and it skips a constructor property,
-		//		and properly decorates copied functions.
-		//
-		//	example:
-		//	|	var A = dojo.declare(null, {
-		//	|		m1: function(){},
-		//	|		s1: "Popokatepetl"
-		//	|	});
-		//	|	A.extend({
-		//	|		m1: function(){},
-		//	|		m2: function(){},
-		//	|		f1: true,
-		//	|		d1: 42
-		//	|	});
+	declare.__DeclareCreatedObject = {
+		// summary:
+		//		dojo/_base/declare() returns a constructor `C`.   `new C()` returns an Object with the following
+		//		methods, in addition to the methods and properties specified via the arguments passed to declare().
+
+		inherited: function(name, args, newArgs){
+			// summary:
+			//		Calls a super method.
+			// name: String?
+			//		The optional method name. Should be the same as the caller's
+			//		name. Usually "name" is specified in complex dynamic cases, when
+			//		the calling method was dynamically added, undecorated by
+			//		declare(), and it cannot be determined.
+			// args: Arguments
+			//		The caller supply this argument, which should be the original
+			//		"arguments".
+			// newArgs: Object?
+			//		If "true", the found function will be returned without
+			//		executing it.
+			//		If Array, it will be used to call a super method. Otherwise
+			//		"args" will be used.
+			// returns:
+			//		Whatever is returned by a super method, or a super method itself,
+			//		if "true" was specified as newArgs.
+			// description:
+			//		This method is used inside method of classes produced with
+			//		declare() to call a super method (next in the chain). It is
+			//		used for manually controlled chaining. Consider using the regular
+			//		chaining, because it is faster. Use "this.inherited()" only in
+			//		complex cases.
+			//
+			//		This method cannot me called from automatically chained
+			//		constructors including the case of a special (legacy)
+			//		constructor chaining. It cannot be called from chained methods.
+			//
+			//		If "this.inherited()" cannot find the next-in-chain method, it
+			//		does nothing and returns "undefined". The last method in chain
+			//		can be a default method implemented in Object, which will be
+			//		called last.
+			//
+			//		If "name" is specified, it is assumed that the method that
+			//		received "args" is the parent method for this call. It is looked
+			//		up in the chain list and if it is found the next-in-chain method
+			//		is called. If it is not found, the first-in-chain method is
+			//		called.
+			//
+			//		If "name" is not specified, it will be derived from the calling
+			//		method (using a methoid property "nom").
+			//
+			// example:
+			//	|	var B = declare(A, {
+			//	|		method1: function(a, b, c){
+			//	|			this.inherited(arguments);
+			//	|		},
+			//	|		method2: function(a, b){
+			//	|			return this.inherited(arguments, [a + b]);
+			//	|		}
+			//	|	});
+			//	|	// next method is not in the chain list because it is added
+			//	|	// manually after the class was created.
+			//	|	B.prototype.method3 = function(){
+			//	|		console.log("This is a dynamically-added method.");
+			//	|		this.inherited("method3", arguments);
+			//	|	};
+			// example:
+			//	|	var B = declare(A, {
+			//	|		method: function(a, b){
+			//	|			var super = this.inherited(arguments, true);
+			//	|			// ...
+			//	|			if(!super){
+			//	|				console.log("there is no super method");
+			//	|				return 0;
+			//	|			}
+			//	|			return super.apply(this, arguments);
+			//	|		}
+			//	|	});
+			return	{};	// Object
+		},
+
+		getInherited: function(name, args){
+			// summary:
+			//		Returns a super method.
+			// name: String?
+			//		The optional method name. Should be the same as the caller's
+			//		name. Usually "name" is specified in complex dynamic cases, when
+			//		the calling method was dynamically added, undecorated by
+			//		declare(), and it cannot be determined.
+			// args: Arguments
+			//		The caller supply this argument, which should be the original
+			//		"arguments".
+			// returns:
+			//		Returns a super method (Function) or "undefined".
+			// description:
+			//		This method is a convenience method for "this.inherited()".
+			//		It uses the same algorithm but instead of executing a super
+			//		method, it returns it, or "undefined" if not found.
+			//
+			// example:
+			//	|	var B = declare(A, {
+			//	|		method: function(a, b){
+			//	|			var super = this.getInherited(arguments);
+			//	|			// ...
+			//	|			if(!super){
+			//	|				console.log("there is no super method");
+			//	|				return 0;
+			//	|			}
+			//	|			return super.apply(this, arguments);
+			//	|		}
+			//	|	});
+			return	{};	// Object
+		},
+
+		isInstanceOf: function(cls){
+			// summary:
+			//		Checks the inheritance chain to see if it is inherited from this
+			//		class.
+			// cls: Function
+			//		Class constructor.
+			// returns:
+			//		"true", if this object is inherited from this class, "false"
+			//		otherwise.
+			// description:
+			//		This method is used with instances of classes produced with
+			//		declare() to determine of they support a certain interface or
+			//		not. It models "instanceof" operator.
+			//
+			// example:
+			//	|	var A = declare(null, {
+			//	|		// constructor, properties, and methods go here
+			//	|		// ...
+			//	|	});
+			//	|	var B = declare(null, {
+			//	|		// constructor, properties, and methods go here
+			//	|		// ...
+			//	|	});
+			//	|	var C = declare([A, B], {
+			//	|		// constructor, properties, and methods go here
+			//	|		// ...
+			//	|	});
+			//	|	var D = declare(A, {
+			//	|		// constructor, properties, and methods go here
+			//	|		// ...
+			//	|	});
+			//	|
+			//	|	var a = new A(), b = new B(), c = new C(), d = new D();
+			//	|
+			//	|	console.log(a.isInstanceOf(A)); // true
+			//	|	console.log(b.isInstanceOf(A)); // false
+			//	|	console.log(c.isInstanceOf(A)); // true
+			//	|	console.log(d.isInstanceOf(A)); // true
+			//	|
+			//	|	console.log(a.isInstanceOf(B)); // false
+			//	|	console.log(b.isInstanceOf(B)); // true
+			//	|	console.log(c.isInstanceOf(B)); // true
+			//	|	console.log(d.isInstanceOf(B)); // false
+			//	|
+			//	|	console.log(a.isInstanceOf(C)); // false
+			//	|	console.log(b.isInstanceOf(C)); // false
+			//	|	console.log(c.isInstanceOf(C)); // true
+			//	|	console.log(d.isInstanceOf(C)); // false
+			//	|
+			//	|	console.log(a.isInstanceOf(D)); // false
+			//	|	console.log(b.isInstanceOf(D)); // false
+			//	|	console.log(c.isInstanceOf(D)); // false
+			//	|	console.log(d.isInstanceOf(D)); // true
+			return	{};	// Object
+		},
+
+		extend: function(source){
+			// summary:
+			//		Adds all properties and methods of source to constructor's
+			//		prototype, making them available to all instances created with
+			//		constructor. This method is specific to constructors created with
+			//		declare().
+			// source: Object
+			//		Source object which properties are going to be copied to the
+			//		constructor's prototype.
+			// description:
+			//		Adds source properties to the constructor's prototype. It can
+			//		override existing properties.
+			//
+			//		This method is similar to dojo.extend function, but it is specific
+			//		to constructors produced by declare(). It is implemented
+			//		using dojo.safeMixin, and it skips a constructor property,
+			//		and properly decorates copied functions.
+			//
+			// example:
+			//	|	var A = declare(null, {
+			//	|		m1: function(){},
+			//	|		s1: "Popokatepetl"
+			//	|	});
+			//	|	A.extend({
+			//	|		m1: function(){},
+			//	|		m2: function(){},
+			//	|		f1: true,
+			//	|		d1: 42
+			//	|	});
+		},
+		
+		createSubclass: function(mixins, props){
+			// summary:
+			//		Create a subclass of the declared class from a list of base classes.
+			// mixins: Function[]
+			//		Specifies a list of bases (the left-most one is the most deepest
+			//		base).
+			// props: Object?
+			//		An optional object whose properties are copied to the created prototype.
+			// returns: dojo/_base/declare.__DeclareCreatedObject
+			//		New constructor function.
+			// description:
+			//		Create a constructor using a compact notation for inheritance and
+			//		prototype extension.
+			//
+			//		Mixin ancestors provide a type of multiple inheritance.
+			//		Prototypes of mixin ancestors are copied to the new class:
+			//		changes to mixin prototypes will not affect classes to which
+			//		they have been mixed in.
+			//
+			// example:
+			//	|	var A = declare(null, {
+			//	|		m1: function(){},
+			//	|		s1: "bar"
+			//	|	});
+			//	|	var B = declare(null, {
+			//	|		m2: function(){},
+			//	|		s2: "foo"
+			//	|	});
+			//	|	var C = declare(null, {
+			//	|	});
+			//	|	var D1 = A.createSubclass([B, C], {
+			//	|		m1: function(){},
+			//	|		d1: 42
+			//	|	});
+			//	|	var d1 = new D1();
+			//	|
+			//	|	// this is equivalent to:
+			//	|	var D2 = declare([A, B, C], {
+			//	|		m1: function(){},
+			//	|		d1: 42
+			//	|	});
+			//	|	var d2 = new D2();
+		}
 	};
 	=====*/
 
+	// For back-compat, remove for 2.0
 	dojo.safeMixin = declare.safeMixin = safeMixin;
 	dojo.declare = declare;
 
diff --git a/dojo/_base/event.js b/dojo/_base/event.js
index 1447679..3056d07 100644
--- a/dojo/_base/event.js
+++ b/dojo/_base/event.js
@@ -1,8 +1,7 @@
 define(["./kernel", "../on", "../has", "../dom-geometry"], function(dojo, on, has, dom){
-  //  module:
-  //    dojo/_base/event
-  //  summary:
-  //    This module defines dojo DOM event API.
+	// module:
+	//		dojo/_base/event
+
 	if(on._fixEvent){
 		var fixEvent = on._fixEvent;
 		on._fixEvent = function(evt, se){
@@ -14,38 +13,47 @@ define(["./kernel", "../on", "../has", "../dom-geometry"], function(dojo, on, ha
 			return evt;
 		};		
 	}
-	dojo.fixEvent = function(/*Event*/ evt, /*DOMNode*/ sender){
-		// summary:
-		//		normalizes properties on the event object including event
-		//		bubbling methods, keystroke normalization, and x/y positions
-		// evt: Event
-		//		native event object
-		// sender: DOMNode
-		//		node to treat as "currentTarget"
-		if(on._fixEvent){
-			return on._fixEvent(evt, sender);
-		}
-		return evt;	// Event
-	};
 	
-	dojo.stopEvent = function(/*Event*/ evt){
+	var ret = {
 		// summary:
-		//		prevents propagation and clobbers the default action of the
-		//		passed event
-		// evt: Event
-		//		The event object. If omitted, window.event is used on IE.
-		if(has("dom-addeventlistener") || (evt && evt.preventDefault)){
-			evt.preventDefault();
-			evt.stopPropagation();
-		}else{
-			evt = evt || window.event;
-			evt.cancelBubble = true;
-			on._preventDefault.call(evt);
+		//		This module defines dojo DOM event API.   Usually you should use dojo/on, and evt.stopPropagation() +
+		//		evt.preventDefault(), rather than this module.
+
+		fix: function(/*Event*/ evt, /*DOMNode*/ sender){
+			// summary:
+			//		normalizes properties on the event object including event
+			//		bubbling methods, keystroke normalization, and x/y positions
+			// evt: Event
+			//		native event object
+			// sender: DOMNode
+			//		node to treat as "currentTarget"
+			if(on._fixEvent){
+				return on._fixEvent(evt, sender);
+			}
+			return evt;	// Event
+		},
+	
+		stop: function(/*Event*/ evt){
+			// summary:
+			//		prevents propagation and clobbers the default action of the
+			//		passed event
+			// evt: Event
+			//		The event object. If omitted, window.event is used on IE.
+			if(has("dom-addeventlistener") || (evt && evt.preventDefault)){
+				evt.preventDefault();
+				evt.stopPropagation();
+			}else{
+				evt = evt || window.event;
+				evt.cancelBubble = true;
+				on._preventDefault.call(evt);
+			}
 		}
 	};
 
-	return {
-		fix: dojo.fixEvent,
-		stop: dojo.stopEvent
-	};
+	if(has("extend-dojo")){
+		dojo.fixEvent = ret.fix;
+		dojo.stopEvent = ret.stop;
+	}
+
+	return ret;
 });
diff --git a/dojo/_base/fx.js b/dojo/_base/fx.js
index b8a25d4..a17b236 100644
--- a/dojo/_base/fx.js
+++ b/dojo/_base/fx.js
@@ -1,42 +1,48 @@
-define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "../dom", "../dom-style"], function(dojo, lang, Evented, Color, connect, has, dom, style){
+define(["./kernel", "./config", /*===== "./declare", =====*/ "./lang", "../Evented", "./Color", "../aspect", "../sniff", "../dom", "../dom-style"],
+	function(dojo, config, /*===== declare, =====*/ lang, Evented, Color, aspect, has, dom, style){
 	// module:
 	//		dojo/_base/fx
-	// summary:
-	//		This module defines the base dojo.fx implementation.
 	// notes:
 	//		Animation loosely package based on Dan Pupius' work, contributed under CLA; see
 	//		http://pupius.co.uk/js/Toolkit.Drawing.js
 
 	var _mixin = lang.mixin;
 
-	dojo._Line = function(/*int*/ start, /*int*/ end){
-		//	summary:
-		//		dojo._Line is the object used to generate values from a start value
-		//		to an end value
-		//	start: int
+	// Module export
+	var basefx = {
+		// summary:
+		//		This module defines the base dojo/_base/fx implementation.
+	};
+
+	var _Line = basefx._Line = function(/*int*/ start, /*int*/ end){
+		// summary:
+		//		Object used to generate values from a start value to an end value
+		// start: int
 		//		Beginning value for range
-		//	end: int
+		// end: int
 		//		Ending value for range
 		this.start = start;
 		this.end = end;
 	};
 
-	dojo._Line.prototype.getValue = function(/*float*/ n){
-		//	summary: Returns the point on the line
-		//	n: a floating point number greater than 0 and less than 1
+	_Line.prototype.getValue = function(/*float*/ n){
+		// summary:
+		//		Returns the point on the line
+		// n:
+		//		a floating point number greater than 0 and less than 1
 		return ((this.end - this.start) * n) + this.start; // Decimal
 	};
 
-	dojo.Animation = function(args){
-		//	summary:
+	var Animation = basefx.Animation = function(args){
+		// summary:
 		//		A generic animation class that fires callbacks into its handlers
 		//		object at various states.
-		//	description:
+		// description:
 		//		A generic animation class that fires callbacks into its handlers
 		//		object at various states. Nearly all dojo animation functions
 		//		return an instance of this method, usually without calling the
 		//		.play() method beforehand. Therefore, you will likely need to
-		//		call .play() on instances of `dojo.Animation` when one is
+		//		call .play() on instances of `Animation` when one is
 		//		returned.
 		// args: Object
 		//		The 'magic argument', mixing all the properties into this
@@ -44,28 +50,26 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 
 		_mixin(this, args);
 		if(lang.isArray(this.curve)){
-			this.curve = new dojo._Line(this.curve[0], this.curve[1]);
+			this.curve = new _Line(this.curve[0], this.curve[1]);
 		}
 
 	};
-	dojo.Animation.prototype = new Evented();
-	// Alias to drop come 2.0:
-	dojo._Animation = dojo.Animation;
+	Animation.prototype = new Evented();
 
-	lang.extend(dojo.Animation, {
+	lang.extend(Animation, {
 		// duration: Integer
-		//		The time in milliseonds the animation will take to run
+		//		The time in milliseconds the animation will take to run
 		duration: 350,
 
 	/*=====
-		// curve: dojo._Line|Array
-		//		A two element array of start and end values, or a `dojo._Line` instance to be
+		// curve: _Line|Array
+		//		A two element array of start and end values, or a `_Line` instance to be
 		//		used in the Animation.
 		curve: null,
 
 		// easing: Function?
 		//		A Function to adjust the acceleration (or deceleration) of the progress
-		//		across a dojo._Line
+		//		across a _Line
 		easing: null,
 	=====*/
 
@@ -85,31 +89,31 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 		delay: null,
 
 		// beforeBegin: Event?
-		//		Synthetic event fired before a dojo.Animation begins playing (synchronous)
+		//		Synthetic event fired before a Animation begins playing (synchronous)
 		beforeBegin: null,
 
 		// onBegin: Event?
-		//		Synthetic event fired as a dojo.Animation begins playing (useful?)
+		//		Synthetic event fired as a Animation begins playing (useful?)
 		onBegin: null,
 
 		// onAnimate: Event?
-		//		Synthetic event fired at each interval of a `dojo.Animation`
+		//		Synthetic event fired at each interval of the Animation
 		onAnimate: null,
 
 		// onEnd: Event?
-		//		Synthetic event fired after the final frame of a `dojo.Animation`
+		//		Synthetic event fired after the final frame of the Animation
 		onEnd: null,
 
 		// onPlay: Event?
-		//		Synthetic event fired any time a `dojo.Animation` is play()'ed
+		//		Synthetic event fired any time the Animation is play()'ed
 		onPlay: null,
 
 		// onPause: Event?
-		//		Synthetic event fired when a `dojo.Animation` is paused
+		//		Synthetic event fired when the Animation is paused
 		onPause: null,
 
 		// onStop: Event
-		//		Synthetic event fires when a `dojo.Animation` is stopped
+		//		Synthetic event fires when the Animation is stopped
 		onStop: null,
 
 	=====*/
@@ -124,21 +128,21 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 			return _e ? _e(_p) : _p;
 		},
 		_fire: function(/*Event*/ evt, /*Array?*/ args){
-			//	summary:
+			// summary:
 			//		Convenience function.  Fire event "evt" and pass it the
 			//		arguments specified in "args".
-			//	description:
+			// description:
 			//		Convenience function.  Fire event "evt" and pass it the
 			//		arguments specified in "args".
-			//		Fires the callback in the scope of the `dojo.Animation`
+			//		Fires the callback in the scope of this Animation
 			//		instance.
-			//	evt:
+			// evt:
 			//		The event to fire.
-			//	args:
+			// args:
 			//		The arguments to pass to the event.
 			var a = args||[];
 			if(this[evt]){
-				if(dojo.config.debugAtAllCosts){
+				if(config.debugAtAllCosts){
 					this[evt].apply(this, a);
 				}else{
 					try{
@@ -154,7 +158,7 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 					}
 				}
 			}
-			return this; // dojo.Animation
+			return this; // Animation
 		},
 
 		play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
@@ -165,7 +169,7 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 			// gotoStart:
 			//		If true, starts the animation from the beginning; otherwise,
 			//		starts it from its current position.
-			// returns: dojo.Animation
+			// returns: Animation
 			//		The instance to allow chaining.
 
 			var _t = this;
@@ -188,7 +192,7 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 				return _t;
 			}
 			_p();
-			return _t;	// dojo.Animation
+			return _t;	// Animation
 		},
 
 		_play: function(gotoStart){
@@ -212,48 +216,51 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 			_t._fire("onPlay", [value]);
 
 			_t._cycle();
-			return _t; // dojo.Animation
+			return _t; // Animation
 		},
 
 		pause: function(){
-			// summary: Pauses a running animation.
+			// summary:
+			//		Pauses a running animation.
 			var _t = this;
 			if(_t._delayTimer){ _t._clearTimer(); }
 			_t._stopTimer();
-			if(!_t._active){ return _t; /*dojo.Animation*/ }
+			if(!_t._active){ return _t; /*Animation*/ }
 			_t._paused = true;
 			_t._fire("onPause", [_t.curve.getValue(_t._getStep())]);
-			return _t; // dojo.Animation
+			return _t; // Animation
 		},
 
 		gotoPercent: function(/*Decimal*/ percent, /*Boolean?*/ andPlay){
-			//	summary:
+			// summary:
 			//		Sets the progress of the animation.
-			//	percent:
+			// percent:
 			//		A percentage in decimal notation (between and including 0.0 and 1.0).
-			//	andPlay:
+			// andPlay:
 			//		If true, play the animation after setting the progress.
 			var _t = this;
 			_t._stopTimer();
 			_t._active = _t._paused = true;
 			_t._percent = percent;
 			if(andPlay){ _t.play(); }
-			return _t; // dojo.Animation
+			return _t; // Animation
 		},
 
 		stop: function(/*boolean?*/ gotoEnd){
-			// summary: Stops a running animation.
-			// gotoEnd: If true, the animation will end.
+			// summary:
+			//		Stops a running animation.
+			// gotoEnd:
+			//		If true, the animation will end.
 			var _t = this;
 			if(_t._delayTimer){ _t._clearTimer(); }
-			if(!_t._timer){ return _t; /* dojo.Animation */ }
+			if(!_t._timer){ return _t; /* Animation */ }
 			_t._stopTimer();
 			if(gotoEnd){
 				_t._percent = 1;
 			}
 			_t._fire("onStop", [_t.curve.getValue(_t._getStep())]);
 			_t._active = _t._paused = false;
-			return _t; // dojo.Animation
+			return _t; // Animation
 		},
 
 		status: function(){
@@ -270,7 +277,8 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 			var _t = this;
 			if(_t._active){
 				var curr = new Date().valueOf();
-				var step = (curr - _t._startTime) / (_t.duration);
+				// Allow durations of 0 (instant) by setting step to 1 - see #13798
+				var step = _t.duration === 0 ? 1 : (curr - _t._startTime) / (_t.duration);
 
 				if(step >= 1){
 					step = 1;
@@ -305,11 +313,12 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 					!_t.repeat && _t._stopTimer();
 				}
 			}
-			return _t; // dojo.Animation
+			return _t; // Animation
 		},
 
 		_clearTimer: function(){
-			// summary: Clear the play delay timer
+			// summary:
+			//		Clear the play delay timer
 			clearTimeout(this._delayTimer);
 			delete this._delayTimer;
 		}
@@ -323,11 +332,11 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 			run: function(){}
 		};
 
-	lang.extend(dojo.Animation, {
+	lang.extend(Animation, {
 
 		_startTimer: function(){
 			if(!this._timer){
-				this._timer = connect.connect(runner, "run", this, "_cycle");
+				this._timer = aspect.after(runner, "run", lang.hitch(this, "_cycle"), true);
 				ctr++;
 			}
 			if(!timer){
@@ -337,7 +346,7 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 
 		_stopTimer: function(){
 			if(this._timer){
-				connect.disconnect(this._timer);
+				this._timer.remove();
 				this._timer = null;
 				ctr--;
 			}
@@ -351,7 +360,6 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 	});
 
 	var _makeFadeable =
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 		has("ie") ? function(node){
 			// only set the zoom if the "tickle" value would be the same as the
 			// default
@@ -362,11 +370,10 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 				ns.width = "auto";
 			}
 		} :
-		//>>excludeEnd("webkitMobile");
 		function(){};
 
-	dojo._fade = function(/*Object*/ args){
-		//	summary:
+	basefx._fade = function(/*Object*/ args){
+		// summary:
 		//		Returns an animation that will fade the node defined by
 		//		args.node from the start to end values passed (args.start
 		//		args.end) (end is mandatory, start is optional)
@@ -381,42 +388,40 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 			} : fArgs.start;
 		props.end = fArgs.end;
 
-		var anim = dojo.animateProperty(fArgs);
-		connect.connect(anim, "beforeBegin", lang.partial(_makeFadeable, fArgs.node));
+		var anim = basefx.animateProperty(fArgs);
+		aspect.after(anim, "beforeBegin", lang.partial(_makeFadeable, fArgs.node), true);
 
-		return anim; // dojo.Animation
+		return anim; // Animation
 	};
 
 	/*=====
-	dojo.__FadeArgs = function(node, duration, easing){
-		//	node: DOMNode|String
+	var __FadeArgs = declare(null, {
+		// node: DOMNode|String
 		//		The node referenced in the animation
-		//	duration: Integer?
+		// duration: Integer?
 		//		Duration of the animation in milliseconds.
-		//	easing: Function?
+		// easing: Function?
 		//		An easing function.
-		this.node = node;
-		this.duration = duration;
-		this.easing = easing;
-	}
+	});
 	=====*/
 
-	dojo.fadeIn = function(/*dojo.__FadeArgs*/ args){
+	basefx.fadeIn = function(/*__FadeArgs*/ args){
 		// summary:
 		//		Returns an animation that will fade node defined in 'args' from
 		//		its current opacity to fully opaque.
-		return dojo._fade(_mixin({ end: 1 }, args)); // dojo.Animation
+		return basefx._fade(_mixin({ end: 1 }, args)); // Animation
 	};
 
-	dojo.fadeOut = function(/*dojo.__FadeArgs*/ args){
+	basefx.fadeOut = function(/*__FadeArgs*/ args){
 		// summary:
 		//		Returns an animation that will fade node defined in 'args'
 		//		from its current opacity to fully transparent.
-		return dojo._fade(_mixin({ end: 0 }, args)); // dojo.Animation
+		return basefx._fade(_mixin({ end: 0 }, args)); // Animation
 	};
 
-	dojo._defaultEasing = function(/*Decimal?*/ n){
-		// summary: The default easing function for dojo.Animation(s)
+	basefx._defaultEasing = function(/*Decimal?*/ n){
+		// summary:
+		//		The default easing function for Animation(s)
 		return 0.5 + ((Math.sin((n + 1.5) * Math.PI)) / 2);	// Decimal
 	};
 
@@ -450,43 +455,43 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 	};
 
 	/*=====
-	dojo.declare("dojo.__AnimArgs", [dojo.__FadeArgs], {
-		// Properties: Object?
-		//	A hash map of style properties to Objects describing the transition,
-		//	such as the properties of dojo._Line with an additional 'units' property
+	var __AnimArgs = declare(__FadeArgs, {
+		// properties: Object?
+		//		A hash map of style properties to Objects describing the transition,
+		//		such as the properties of _Line with an additional 'units' property
 		properties: {}
 
 		//TODOC: add event callbacks
 	});
 	=====*/
 
-	dojo.animateProperty = function(/*dojo.__AnimArgs*/ args){
+	basefx.animateProperty = function(/*__AnimArgs*/ args){
 		// summary:
 		//		Returns an animation that will transition the properties of
 		//		node defined in `args` depending how they are defined in
 		//		`args.properties`
 		//
 		// description:
-		//		`dojo.animateProperty` is the foundation of most `dojo.fx`
+		//		Foundation of most `dojo/_base/fx`
 		//		animations. It takes an object of "properties" corresponding to
 		//		style properties, and animates them in parallel over a set
 		//		duration.
 		//
 		// example:
 		//		A simple animation that changes the width of the specified node.
-		//	|	dojo.animateProperty({
+		//	|	basefx.animateProperty({
 		//	|		node: "nodeId",
 		//	|		properties: { width: 400 },
 		//	|	}).play();
 		//		Dojo figures out the start value for the width and converts the
 		//		integer specified for the width to the more expressive but
 		//		verbose form `{ width: { end: '400', units: 'px' } }` which you
-		//		can also specify directly. Defaults to 'px' if ommitted.
+		//		can also specify directly. Defaults to 'px' if omitted.
 		//
 		// example:
 		//		Animate width, height, and padding over 2 seconds... the
 		//		pedantic way:
-		//	|	dojo.animateProperty({ node: node, duration:2000,
+		//	|	basefx.animateProperty({ node: node, duration:2000,
 		//	|		properties: {
 		//	|			width: { start: '200', end: '400', units:"px" },
 		//	|			height: { start:'200', end: '400', units:"px" },
@@ -501,7 +506,7 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 		//		when the animation ends. Easing functions accept values between
 		//		zero and one and return a value on that basis. In this case, an
 		//		exponential-in curve.
-		//	|	dojo.animateProperty({
+		//	|	basefx.animateProperty({
 		//	|		node: "nodeId",
 		//	|		// dojo figures out the start value
 		//	|		properties: { width: { end: 400 } },
@@ -515,31 +520,31 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 		//	|	}).play(500); // delay playing half a second
 		//
 		// example:
-		//		Like all `dojo.Animation`s, animateProperty returns a handle to the
-		//		Animation instance, which fires the events common to Dojo FX. Use `dojo.connect`
-		//		to access these events outside of the Animation definiton:
-		//	|	var anim = dojo.animateProperty({
+		//		Like all `Animation`s, animateProperty returns a handle to the
+		//		Animation instance, which fires the events common to Dojo FX. Use `aspect.after`
+		//		to access these events outside of the Animation definition:
+		//	|	var anim = basefx.animateProperty({
 		//	|		node:"someId",
 		//	|		properties:{
 		//	|			width:400, height:500
 		//	|		}
 		//	|	});
-		//	|	dojo.connect(anim,"onEnd", function(){
+		//	|	aspect.after(anim, "onEnd", function(){
 		//	|		console.log("animation ended");
-		//	|	});
+		//	|	}, true);
 		//	|	// play the animation now:
 		//	|	anim.play();
 		//
 		// example:
 		//		Each property can be a function whose return value is substituted along.
 		//		Additionally, each measurement (eg: start, end) can be a function. The node
-		//		reference is passed direcly to callbacks.
-		//	|	dojo.animateProperty({
+		//		reference is passed directly to callbacks.
+		//	|	basefx.animateProperty({
 		//	|		node:"mine",
 		//	|		properties:{
 		//	|			height:function(node){
 		//	|				// shrink this node by 50%
-		//	|				return dojo.position(node).h / 2
+		//	|				return domGeom.position(node).h / 2
 		//	|			},
 		//	|			width:{
 		//	|				start:function(node){ return 100; },
@@ -552,8 +557,8 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 		var n = args.node = dom.byId(args.node);
 		if(!args.easing){ args.easing = dojo._defaultEasing; }
 
-		var anim = new dojo.Animation(args);
-		connect.connect(anim, "beforeBegin", anim, function(){
+		var anim = new Animation(args);
+		aspect.after(anim, "beforeBegin", lang.hitch(anim, function(){
 			var pm = {};
 			for(var p in this.properties){
 				// Make shallow copy of properties into pm because we overwrite
@@ -577,7 +582,7 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 				}
 				var isColor = (p.toLowerCase().indexOf("color") >= 0);
 				function getStyle(node, p){
-					// dojo.style(node, "height") can return "auto" or "" on IE; this is more reliable:
+					// domStyle.get(node, "height") can return "auto" or "" on IE; this is more reliable:
 					var v = { height: node.offsetHeight, width: node.offsetWidth }[p];
 					if(v !== undefined){ return v; }
 					v = style.get(node, p);
@@ -597,72 +602,69 @@ define(["./kernel", "./lang", "../Evented", "./Color", "./connect", "./sniff", "
 				}
 			}
 			this.curve = new PropLine(pm);
-		});
-		connect.connect(anim, "onAnimate", lang.hitch(style, "set", anim.node));
-		return anim; // dojo.Animation
+		}), true);
+		aspect.after(anim, "onAnimate", lang.hitch(style, "set", anim.node), true);
+		return anim; // Animation
 	};
 
-	dojo.anim = function(	/*DOMNode|String*/	node,
+	basefx.anim = function(	/*DOMNode|String*/	node,
 							/*Object*/			properties,
 							/*Integer?*/		duration,
 							/*Function?*/		easing,
 							/*Function?*/		onEnd,
 							/*Integer?*/		delay){
-		//	summary:
-		//		A simpler interface to `dojo.animateProperty()`, also returns
-		//		an instance of `dojo.Animation` but begins the animation
+		// summary:
+		//		A simpler interface to `animateProperty()`, also returns
+		//		an instance of `Animation` but begins the animation
 		//		immediately, unlike nearly every other Dojo animation API.
-		//	description:
-		//		`dojo.anim` is a simpler (but somewhat less powerful) version
-		//		of `dojo.animateProperty`.  It uses defaults for many basic properties
+		// description:
+		//		Simpler (but somewhat less powerful) version
+		//		of `animateProperty`.  It uses defaults for many basic properties
 		//		and allows for positional parameters to be used in place of the
 		//		packed "property bag" which is used for other Dojo animation
 		//		methods.
 		//
-		//		The `dojo.Animation` object returned from `dojo.anim` will be
-		//		already playing when it is returned from this function, so
+		//		The `Animation` object returned will be already playing, so
 		//		calling play() on it again is (usually) a no-op.
-		//	node:
+		// node:
 		//		a DOM node or the id of a node to animate CSS properties on
-		//	duration:
+		// duration:
 		//		The number of milliseconds over which the animation
 		//		should run. Defaults to the global animation default duration
 		//		(350ms).
-		//	easing:
+		// easing:
 		//		An easing function over which to calculate acceleration
 		//		and deceleration of the animation through its duration.
 		//		A default easing algorithm is provided, but you may
 		//		plug in any you wish. A large selection of easing algorithms
-		//		are available in `dojo.fx.easing`.
-		//	onEnd:
+		//		are available in `dojo/fx/easing`.
+		// onEnd:
 		//		A function to be called when the animation finishes
 		//		running.
-		//	delay:
+		// delay:
 		//		The number of milliseconds to delay beginning the
 		//		animation by. The default is 0.
-		//	example:
+		// example:
 		//		Fade out a node
-		//	|	dojo.anim("id", { opacity: 0 });
-		//	example:
+		//	|	basefx.anim("id", { opacity: 0 });
+		// example:
 		//		Fade out a node over a full second
-		//	|	dojo.anim("id", { opacity: 0 }, 1000);
-		return dojo.animateProperty({ // dojo.Animation
+		//	|	basefx.anim("id", { opacity: 0 }, 1000);
+		return basefx.animateProperty({ // Animation
 			node: node,
-			duration: duration || dojo.Animation.prototype.duration,
+			duration: duration || Animation.prototype.duration,
 			properties: properties,
 			easing: easing,
 			onEnd: onEnd
 		}).play(delay || 0);
 	};
 
-	return {
-		_Line: dojo._Line,
-		Animation: dojo.Animation,
-		_fade: dojo._fade,
-		fadeIn: dojo.fadeIn,
-		fadeOut: dojo.fadeOut,
-		_defaultEasing: dojo._defaultEasing,
-		animateProperty: dojo.animateProperty,
-		anim: dojo.anim
-	};
+
+	if(has("extend-dojo")){
+		_mixin(dojo, basefx);
+		// Alias to drop come 2.0:
+		dojo._Animation = Animation;
+	}
+
+	return basefx;
 });
diff --git a/dojo/_base/html.js b/dojo/_base/html.js
index 3fe6adc..c6a703a 100644
--- a/dojo/_base/html.js
+++ b/dojo/_base/html.js
@@ -1,8 +1,13 @@
 define(["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../dom-class", "../dom-construct", "../dom-geometry"], function(dojo, dom, style, attr, prop, cls, ctr, geom){
 	// module:
 	//		dojo/dom
-	// summary:
-	//		This module is a stub for the core dojo DOM API.
+
+	/*=====
+	return {
+		// summary:
+		//		This module is a stub for the core dojo DOM API.
+	};
+	=====*/
 
 	// mix-in dom
 	dojo.byId = dom.byId;
@@ -140,7 +145,7 @@ define(["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../
 		//		Getter/setter for the margin-box of node.
 		//		Returns an object in the expected format of box (regardless
 		//		if box is passed). The object might look like:
-		//			`{ l: 50, t: 200, w: 300: h: 150 }`
+		//		`{ l: 50, t: 200, w: 300: h: 150 }`
 		//		for a node offset from its parent 50px to the left, 200px from
 		//		the top with a margin width of 300px and a margin-height of
 		//		150px.
@@ -168,7 +173,7 @@ define(["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../
 		// description:
 		//		Returns an object in the expected format of box (regardless if box is passed).
 		//		The object might look like:
-		//			`{ l: 50, t: 200, w: 300: h: 150 }`
+		//		`{ l: 50, t: 200, w: 300: h: 150 }`
 		//		for a node offset from its parent 50px to the left, 200px from
 		//		the top with a content width of 300px and a content-height of
 		//		150px. Note that the content box may have a much larger border
@@ -190,9 +195,7 @@ define(["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../
 		// summary:
 		//		Deprecated: Use position() for border-box x/y/w/h
 		//		or marginBox() for margin-box w/h/l/t.
-		//		Returns an object representing a node's size and position.
 		//
-		// description:
 		//		Returns an object that measures margin-box (w)idth/(h)eight
 		//		and absolute position x/y of the border-box. Also returned
 		//		is computed (l)eft and (t)op values in pixels from the
@@ -279,7 +282,7 @@ define(["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../
 		//	|	});
 		//
 		// example:
-		//	Style is s special case: Only set with an object hash of styles
+		//		Style is s special case: Only set with an object hash of styles
 		//	|	dojo.prop("someNode",{
 		//	|		id:"bar",
 		//	|		style:{
@@ -288,7 +291,7 @@ define(["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../
 		//	|	});
 		//
 		// example:
-		//	Again, only set style as an object hash of styles:
+		//		Again, only set style as an object hash of styles:
 		//	|	var obj = { color:"#fff", backgroundColor:"#000" };
 		//	|	dojo.prop("someNode", "style", obj);
 		//	|
@@ -323,7 +326,7 @@ define(["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../
 		//		`dojo.contentBox()` or `dojo.position()`.
 		// node: DOMNode|String
 		//		id or reference to node to get/set style for
-		// name: String?|Object?
+		// name: String|Object?
 		//		the style property to set in DOM-accessor format
 		//		("borderWidth", not "border-width") or an object with key/value
 		//		pairs suitable for setting each property.
@@ -366,8 +369,8 @@ define(["./kernel", "../dom", "../dom-style", "../dom-attr", "../dom-prop", "../
 		//	|	});
 		//
 		// example:
-		//		dojo.NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
-		//		dojo.style() on every element of the list. See: `dojo.query()` and `dojo.NodeList()`
+		//		dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
+		//		dojo.style() on every element of the list. See: `dojo/query` and `dojo/NodeList`
 		//	|	dojo.query(".someClassName").style("visibility","hidden");
 		//	|	// or
 		//	|	dojo.query("#baz > div").style({
diff --git a/dojo/_base/json.js b/dojo/_base/json.js
index 4a35bb8..176ae36 100644
--- a/dojo/_base/json.js
+++ b/dojo/_base/json.js
@@ -1,8 +1,14 @@
 define(["./kernel", "../json"], function(dojo, json){
-  // module:
-  //    dojo/_base/json
-  // summary:
-  //    This module defines the dojo JSON API.
+
+// module:
+//		dojo/_base/json
+
+/*=====
+return {
+	// summary:
+	//		This module defines the dojo JSON API.
+};
+=====*/
 
 dojo.fromJson = function(/*String*/ js){
 	// summary:
@@ -15,7 +21,7 @@ dojo.fromJson = function(/*String*/ js){
 	//		implementation uses the (faster) native JSON parse when available.
 	// js:
 	//		a string literal of a JavaScript expression, for instance:
-	//			`'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
+	//		`'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
 
 	return eval("(" + js + ")"); // Object
 };
@@ -55,7 +61,7 @@ dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint){
 	//		Note that if native JSON support is available, it will be used for serialization,
 	//		and native implementations vary on the exact spacing used in pretty printing.
 	// returns:
-	// 		A JSON string serialization of the passed-in object.
+	//		A JSON string serialization of the passed-in object.
 	// example:
 	//		simple serialization of a trivial object
 	//		|	var jsonStr = dojo.toJson({ howdy: "stranger!", isStrange: true });
diff --git a/dojo/_base/kernel.js b/dojo/_base/kernel.js
index 277675c..43d1520 100644
--- a/dojo/_base/kernel.js
+++ b/dojo/_base/kernel.js
@@ -1,8 +1,9 @@
 define(["../has", "./config", "require", "module"], function(has, config, require, module){
 	// module:
 	//		dojo/_base/kernel
-	// summary:
-	//		This module is the foundational module of the dojo boot sequence; it defines the dojo object.
+
+	// This module is the foundational module of the dojo boot sequence; it defines the dojo object.
+
 	var
 		// loop variables for this module
 		i, p,
@@ -12,6 +13,9 @@ define(["../has", "./config", "require", "module"], function(has, config, requir
 		dijit = {},
 		dojox = {},
 		dojo = {
+			// summary:
+			//		This module is the foundational module of the dojo boot sequence; it defines the dojo object.
+
 			// notice dojo takes ownership of the value of the config module
 			config:config,
 			global:this,
@@ -27,8 +31,8 @@ define(["../has", "./config", "require", "module"], function(has, config, requir
 	// Built, legacy modules use the scope map to allow those modules to be expressed as if dojo, dijit, and dojox,
 	// where global when in fact they are either global under different names or not global at all. In v1.6-, the
 	// config variable "scopeMap" was used to map names as used within a module to global names. This has been
-	// subsumed by the dojo packageMap configuration variable which relocates packages to different names. See
-	// http://livedocs.dojotoolkit.org/developer/design/loader#legacy-cross-domain-mode for details.
+	// subsumed by the AMD map configuration variable which can relocate packages to different names. For backcompat,
+	// only the "*" mapping is supported. See http://livedocs.dojotoolkit.org/developer/design/loader#legacy-cross-domain-mode for details.
 	//
 	// The following computations contort the packageMap for this dojo instance into a scopeMap.
 	var scopeMap =
@@ -42,10 +46,11 @@ define(["../has", "./config", "require", "module"], function(has, config, requir
 
 		packageMap =
 			// the package map for this dojo instance; note, a foreign loader or no pacakgeMap results in the above default config
-			(require.packs && require.packs[module.id.match(/[^\/]+/)[0]].packageMap) || {},
+			(require.map && require.map[module.id.match(/[^\/]+/)[0]]),
 
 		item;
 
+
 	// process all mapped top-level names for this instance of dojo
 	for(p in packageMap){
 		if(scopeMap[p]){
@@ -67,35 +72,27 @@ define(["../has", "./config", "require", "module"], function(has, config, requir
 	}
 	dojo.scopeMap = scopeMap;
 
+	/*===== dojo.__docParserConfigureScopeMap(scopeMap); =====*/
+
 	// FIXME: dojo.baseUrl and dojo.config.baseUrl should be deprecated
 	dojo.baseUrl = dojo.config.baseUrl = require.baseUrl;
 	dojo.isAsync = !has("dojo-loader") || require.async;
 	dojo.locale = config.locale;
 
-	/*=====
-		dojo.version = function(){
-			// summary:
-			//		Version number of the Dojo Toolkit
-			// major: Integer
-			//		Major version. If total version is "1.2.0beta1", will be 1
-			// minor: Integer
-			//		Minor version. If total version is "1.2.0beta1", will be 2
-			// patch: Integer
-			//		Patch version. If total version is "1.2.0beta1", will be 0
-			// flag: String
-			//		Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
-			// revision: Number
-			//		The SVN rev from which dojo was pulled
-			this.major = 0;
-			this.minor = 0;
-			this.patch = 0;
-			this.flag = "";
-			this.revision = 0;
-		}
-	=====*/
-	var rev = "$Rev: 27913 $".match(/\d+/);
+	var rev = "$Rev: 43d05c6 $".match(/\d+/);
 	dojo.version = {
-		major: 1, minor: 7, patch: 2, flag: "",
+		// summary:
+		//		Version number of the Dojo Toolkit
+		// description:
+		//		Hash about the version, including
+		//
+		//		- major: Integer: Major version. If total version is "1.2.0beta1", will be 1
+		//		- minor: Integer: Minor version. If total version is "1.2.0beta1", will be 2
+		//		- patch: Integer: Patch version. If total version is "1.2.0beta1", will be 0
+		//		- flag: String: Descriptor flag. If total version is "1.2.0beta1", will be "beta1"
+		//		- revision: Number: The SVN rev from which dojo was pulled
+
+		major: 1, minor: 9, patch: 1, flag: "",
 		revision: rev ? +rev[0] : NaN,
 		toString: function(){
 			var v = dojo.version;
@@ -103,7 +100,6 @@ define(["../has", "./config", "require", "module"], function(has, config, requir
 		}
 	};
 
-
 	// If has("extend-dojo") is truthy, then as a dojo module is defined it should push it's definitions
 	// into the dojo object, and conversely. In 2.0, it will likely be unusual to augment another object
 	// as a result of defining a module. This has feature gives a way to force 2.0 behavior as the code
@@ -111,11 +107,13 @@ define(["../has", "./config", "require", "module"], function(has, config, requir
 	has.add("extend-dojo", 1);
 
 
+	(Function("d", "d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo);
+	/*=====
 	dojo.eval = function(scriptText){
-		//	summary:
+		// summary:
 		//		A legacy method created for use exclusively by internal Dojo methods. Do not use this method
 		//		directly unless you understand its possibly-different implications on the platforms your are targeting.
-		//	description:
+		// description:
 		//		Makes an attempt to evaluate scriptText in the global scope. The function works correctly for browsers
 		//		that support indirect eval.
 		//
@@ -130,20 +128,19 @@ define(["../has", "./config", "require", "module"], function(has, config, requir
 		//		to define a global variable using dojo.eval, write something like
 		//
 		//		dojo.eval("window.pi = 3.14;")
-		//	scriptText:
+		// scriptText:
 		//		The text to evaluation.
-		//	returns:
+		// returns:
 		//		The result of the evaluation. Often `undefined`
 	};
-
-	(Function("d", "d.eval = function(){return d.global.eval ? d.global.eval(arguments[0]) : eval(arguments[0]);}"))(dojo);
+	=====*/
 
 
 	if(has("host-rhino")){
 		dojo.exit = function(exitcode){
 			quit(exitcode);
 		};
-	} else{
+	}else{
 		dojo.exit = function(){
 		};
 	}
@@ -181,22 +178,23 @@ define(["../has", "./config", "require", "module"], function(has, config, requir
 		// include dojo.deprecated/dojo.experimental implementations
 		!!config.isDebug
 	);
+	dojo.deprecated = dojo.experimental =  function(){};
 	if(has("dojo-debug-messages")){
 		dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ removal){
-			//	summary:
+			// summary:
 			//		Log a debug message to indicate that a behavior has been
 			//		deprecated.
-			//	behaviour: String
+			// behaviour: String
 			//		The API or behavior being deprecated. Usually in the form
 			//		of "myApp.someFunction()".
-			//	extra: String?
+			// extra: String?
 			//		Text to append to the message. Often provides advice on a
 			//		new function or facility to achieve the same goal during
 			//		the deprecation period.
-			//	removal: String?
+			// removal: String?
 			//		Text to indicate when in the future the behavior will be
 			//		removed. Usually a version number.
-			//	example:
+			// example:
 			//	| dojo.deprecated("myApp.getTemp()", "use myApp.getLocaleTemp() instead", "1.0");
 
 			var message = "DEPRECATED: " + behaviour;
@@ -206,29 +204,28 @@ define(["../has", "./config", "require", "module"], function(has, config, requir
 		};
 
 		dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
-			//	summary: Marks code as experimental.
-			//	description:
+			// summary:
+			//		Marks code as experimental.
+			// description:
 			//		This can be used to mark a function, file, or module as
 			//		experimental.	 Experimental code is not ready to be used, and the
 			//		APIs are subject to change without notice.	Experimental code may be
 			//		completed deleted without going through the normal deprecation
 			//		process.
-			//	moduleName: String
+			// moduleName: String
 			//		The name of a module, or the name of a module file or a specific
 			//		function
-			//	extra: String?
+			// extra: String?
 			//		some additional message for the user
-			//	example:
+			// example:
 			//	| dojo.experimental("dojo.data.Result");
-			//	example:
+			// example:
 			//	| dojo.experimental("dojo.weather.toKelvin()", "PENDING approval from NOAA");
 
 			var message = "EXPERIMENTAL: " + moduleName + " -- APIs subject to change without notice.";
 			if(extra){ message += " " + extra; }
 			console.warn(message);
 		};
-	}else{
-		dojo.deprecated = dojo.experimental =  function(){};
 	}
 
 	has.add("dojo-modulePaths",
@@ -254,9 +251,9 @@ define(["../has", "./config", "require", "module"], function(has, config, requir
 	);
 	if(has("dojo-moduleUrl")){
 		dojo.moduleUrl = function(/*String*/module, /*String?*/url){
-			//	summary:
+			// summary:
 			//		Returns a URL relative to a module.
-			//	example:
+			// example:
 			//	|	var pngPath = dojo.moduleUrl("acme","images/small.png");
 			//	|	console.dir(pngPath); // list the object properties
 			//	|	// create an image and set it's source to pngPath's value:
@@ -264,7 +261,7 @@ define(["../has", "./config", "require", "module"], function(has, config, requir
 			//	|	img.src = pngPath;
 			//	|	// add our image to the document
 			//	|	dojo.body().appendChild(img);
-			//	example:
+			// example:
 			//		you may de-reference as far as you like down the package
 			//		hierarchy.  This is sometimes handy to avoid lenghty relative
 			//		urls or for building portable sub-packages. In this example,
diff --git a/dojo/_base/lang.js b/dojo/_base/lang.js
index a71c556..48a9c43 100644
--- a/dojo/_base/lang.js
+++ b/dojo/_base/lang.js
@@ -1,24 +1,75 @@
-define(["./kernel", "../has", "./sniff"], function(dojo, has){
-	//	module:
+define(["./kernel", "../has", "../sniff"], function(dojo, has){
+	// module:
 	//		dojo/_base/lang
-	//	summary:
-	//		This module defines Javascript language extensions.
 
 	has.add("bug-for-in-skips-shadowed", function(){
-		// if true, the for-in interator skips object properties that exist in Object's prototype (IE 6 - ?)
+		// if true, the for-in iterator skips object properties that exist in Object's prototype (IE 6 - ?)
 		for(var i in {toString: 1}){
 			return 0;
 		}
 		return 1;
 	});
 
+	// Helper methods
 	var _extraNames =
 			has("bug-for-in-skips-shadowed") ?
 				"hasOwnProperty.valueOf.isPrototypeOf.propertyIsEnumerable.toLocaleString.toString.constructor".split(".") : [],
 
 		_extraLen = _extraNames.length,
 
-		_mixin = function(dest, source, copyFunc){
+		getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
+			var p, i = 0, dojoGlobal = dojo.global;
+			if(!context){
+				if(!parts.length){
+					return dojoGlobal;
+				}else{
+					p = parts[i++];
+					try{
+						context = dojo.scopeMap[p] && dojo.scopeMap[p][1];
+					}catch(e){}
+					context = context || (p in dojoGlobal ? dojoGlobal[p] : (create ? dojoGlobal[p] = {} : undefined));
+				}
+			}
+			while(context && (p = parts[i++])){
+				context = (p in context ? context[p] : (create ? context[p] = {} : undefined));
+			}
+			return context; // mixed
+		},
+
+		opts = Object.prototype.toString,
+
+		efficient = function(obj, offset, startWith){
+			return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
+		},
+
+		_pattern = /\{([^\}]+)\}/g;
+
+	// Module export
+	var lang = {
+		// summary:
+		//		This module defines Javascript language extensions.
+
+		// _extraNames: String[]
+		//		Lists property names that must be explicitly processed during for-in iteration
+		//		in environments that have has("bug-for-in-skips-shadowed") true.
+		_extraNames:_extraNames,
+
+		_mixin: function(dest, source, copyFunc){
+			// summary:
+			//		Copies/adds all properties of source to dest; returns dest.
+			// dest: Object
+			//		The object to which to copy/add all properties contained in source.
+			// source: Object
+			//		The object from which to draw all properties to copy into dest.
+			// copyFunc: Function?
+			//		The process used to copy/add a property in source; defaults to the Javascript assignment operator.
+			// returns:
+			//		dest, as modified
+			// description:
+			//		All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
+			//		found in Object.prototype, are copied/added to dest. Copying/adding each particular property is
+			//		delegated to copyFunc (if any); copyFunc defaults to the Javascript assignment operator if not provided.
+			//		Notice that by default, _mixin executes a so-called "shallow copy" and aggregate types are copied/added by reference.
 			var name, s, i, empty = {};
 			for(name in source){
 				// the (!(name in empty) || empty[name] !== s) condition avoids copying properties in "source"
@@ -45,7 +96,61 @@ define(["./kernel", "../has", "./sniff"], function(dojo, has){
 			return dest; // Object
 		},
 
-		mixin = function(dest, sources){
+		mixin: function(dest, sources){
+			// summary:
+			//		Copies/adds all properties of one or more sources to dest; returns dest.
+			// dest: Object
+			//		The object to which to copy/add all properties contained in source. If dest is falsy, then
+			//		a new object is manufactured before copying/adding properties begins.
+			// sources: Object...
+			//		One of more objects from which to draw all properties to copy into dest. sources are processed
+			//		left-to-right and if more than one of these objects contain the same property name, the right-most
+			//		value "wins".
+			// returns: Object
+			//		dest, as modified
+			// description:
+			//		All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
+			//		found in Object.prototype, are copied/added from sources to dest. sources are processed left to right.
+			//		The Javascript assignment operator is used to copy/add each property; therefore, by default, mixin
+			//		executes a so-called "shallow copy" and aggregate types are copied/added by reference.
+			// example:
+			//		make a shallow copy of an object
+			//	|	var copy = lang.mixin({}, source);
+			// example:
+			//		many class constructors often take an object which specifies
+			//		values to be configured on the object. In this case, it is
+			//		often simplest to call `lang.mixin` on the `this` object:
+			//	|	declare("acme.Base", null, {
+			//	|		constructor: function(properties){
+			//	|			// property configuration:
+			//	|			lang.mixin(this, properties);
+			//	|
+			//	|			console.log(this.quip);
+			//	|			//	...
+			//	|		},
+			//	|		quip: "I wasn't born yesterday, you know - I've seen movies.",
+			//	|		// ...
+			//	|	});
+			//	|
+			//	|	// create an instance of the class and configure it
+			//	|	var b = new acme.Base({quip: "That's what it does!" });
+			// example:
+			//		copy in properties from multiple objects
+			//	|	var flattened = lang.mixin(
+			//	|		{
+			//	|			name: "Frylock",
+			//	|			braces: true
+			//	|		},
+			//	|		{
+			//	|			name: "Carl Brutanananadilewski"
+			//	|		}
+			//	|	);
+			//	|
+			//	|	// will print "Carl Brutanananadilewski"
+			//	|	console.log(flattened.name);
+			//	|	// will print "true"
+			//	|	console.log(flattened.braces);
+
 			if(!dest){ dest = {}; }
 			for(var i = 1, l = arguments.length; i < l; i++){
 				lang._mixin(dest, arguments[i]);
@@ -53,60 +158,133 @@ define(["./kernel", "../has", "./sniff"], function(dojo, has){
 			return dest; // Object
 		},
 
-		getProp = function(/*Array*/parts, /*Boolean*/create, /*Object*/context){
-			var p, i = 0, dojoGlobal = dojo.global;
-			if(!context){
-				if(!parts.length){
-					return dojoGlobal;
-				}else{
-					p = parts[i++];
-					try{
-						context = dojo.scopeMap[p] && dojo.scopeMap[p][1];
-					}catch(e){}
-					context = context || (p in dojoGlobal ? dojoGlobal[p] : (create ? dojoGlobal[p] = {} : undefined));
-				}
-			}
-			while(context && (p = parts[i++])){
-				context = (p in context ? context[p] : (create ? context[p] = {} : undefined));
-			}
-			return context; // mixed
-		},
+		setObject: function(name, value, context){
+			// summary:
+			//		Set a property from a dot-separated string, such as "A.B.C"
+			// description:
+			//		Useful for longer api chains where you have to test each object in
+			//		the chain, or when you have an object reference in string format.
+			//		Objects are created as needed along `path`. Returns the passed
+			//		value if setting is successful or `undefined` if not.
+			// name: String
+			//		Path to a property, in the form "A.B.C".
+			// value: anything
+			//		value or object to place at location given by name
+			// context: Object?
+			//		Optional. Object to use as root of path. Defaults to
+			//		`dojo.global`.
+			// example:
+			//		set the value of `foo.bar.baz`, regardless of whether
+			//		intermediate objects already exist:
+			//	| lang.setObject("foo.bar.baz", value);
+			// example:
+			//		without `lang.setObject`, we often see code like this:
+			//	| // ensure that intermediate objects are available
+			//	| if(!obj["parent"]){ obj.parent = {}; }
+			//	| if(!obj.parent["child"]){ obj.parent.child = {}; }
+			//	| // now we can safely set the property
+			//	| obj.parent.child.prop = "some value";
+			//		whereas with `lang.setObject`, we can shorten that to:
+			//	| lang.setObject("parent.child.prop", "some value", obj);
 
-		setObject = function(name, value, context){
 			var parts = name.split("."), p = parts.pop(), obj = getProp(parts, true, context);
 			return obj && p ? (obj[p] = value) : undefined; // Object
 		},
 
-		getObject = function(name, create, context){
+		getObject: function(name, create, context){
+			// summary:
+			//		Get a property from a dot-separated string, such as "A.B.C"
+			// description:
+			//		Useful for longer api chains where you have to test each object in
+			//		the chain, or when you have an object reference in string format.
+			// name: String
+			//		Path to an property, in the form "A.B.C".
+			// create: Boolean?
+			//		Optional. Defaults to `false`. If `true`, Objects will be
+			//		created at any point along the 'path' that is undefined.
+			// context: Object?
+			//		Optional. Object to use as root of path. Defaults to
+			//		'dojo.global'. Null may be passed.
 			return getProp(name.split("."), create, context); // Object
 		},
 
-		exists = function(name, obj){
+		exists: function(name, obj){
+			// summary:
+			//		determine if an object supports a given method
+			// description:
+			//		useful for longer api chains where you have to test each object in
+			//		the chain. Useful for object and method detection.
+			// name: String
+			//		Path to an object, in the form "A.B.C".
+			// obj: Object?
+			//		Object to use as root of path. Defaults to
+			//		'dojo.global'. Null may be passed.
+			// example:
+			//	| // define an object
+			//	| var foo = {
+			//	|		bar: { }
+			//	| };
+			//	|
+			//	| // search the global scope
+			//	| lang.exists("foo.bar"); // true
+			//	| lang.exists("foo.bar.baz"); // false
+			//	|
+			//	| // search from a particular scope
+			//	| lang.exists("bar", foo); // true
+			//	| lang.exists("bar.baz", foo); // false
 			return lang.getObject(name, false, obj) !== undefined; // Boolean
 		},
 
-		opts = Object.prototype.toString,
-
 		// Crockford (ish) functions
 
-		isString = function(it){
+		isString: function(it){
+			// summary:
+			//		Return true if it is a String
+			// it: anything
+			//		Item to test.
 			return (typeof it == "string" || it instanceof String); // Boolean
 		},
 
-		isArray = function(it){
+		isArray: function(it){
+			// summary:
+			//		Return true if it is an Array.
+			//		Does not work on Arrays created in other windows.
+			// it: anything
+			//		Item to test.
 			return it && (it instanceof Array || typeof it == "array"); // Boolean
 		},
 
-		isFunction = function(it){
+		isFunction: function(it){
+			// summary:
+			//		Return true if it is a Function
+			// it: anything
+			//		Item to test.
 			return opts.call(it) === "[object Function]";
 		},
 
-		isObject = function(it){
+		isObject: function(it){
+			// summary:
+			//		Returns true if it is a JavaScript object (or an Array, a Function
+			//		or null)
+			// it: anything
+			//		Item to test.
 			return it !== undefined &&
 				(it === null || typeof it == "object" || lang.isArray(it) || lang.isFunction(it)); // Boolean
 		},
 
-		isArrayLike = function(it){
+		isArrayLike: function(it){
+			// summary:
+			//		similar to isArray() but more permissive
+			// it: anything
+			//		Item to test.
+			// returns:
+			//		If it walks like a duck and quacks like a duck, return `true`
+			// description:
+			//		Doesn't strongly test for "arrayness".  Instead, settles for "isn't
+			//		a string or number and has a length property". Arguments objects
+			//		and DOM collections will return true when passed to
+			//		isArrayLike(), but will return false when passed to
+			//		isArray().
 			return it && it !== undefined && // Boolean
 				// keep out built-in constructors (Number, String, ...) which have length
 				// properties
@@ -115,23 +293,34 @@ define(["./kernel", "../has", "./sniff"], function(dojo, has){
 				(lang.isArray(it) || isFinite(it.length));
 		},
 
-		isAlien = function(it){
+		isAlien: function(it){
+			// summary:
+			//		Returns true if it is a built-in function or some other kind of
+			//		oddball that *should* report as a function but doesn't
 			return it && !lang.isFunction(it) && /\{\s*\[native code\]\s*\}/.test(String(it)); // Boolean
 		},
 
-		extend = function(constructor, props){
+		extend: function(ctor, props){
+			// summary:
+			//		Adds all properties and methods of props to constructor's
+			//		prototype, making them available to all instances created with
+			//		constructor.
+			// ctor: Object
+			//		Target constructor to extend.
+			// props: Object
+			//		One or more objects to mix into ctor.prototype
 			for(var i=1, l=arguments.length; i<l; i++){
-				lang._mixin(constructor.prototype, arguments[i]);
+				lang._mixin(ctor.prototype, arguments[i]);
 			}
-			return constructor; // Object
+			return ctor; // Object
 		},
 
-		_hitchArgs = function(scope, method){
-			var pre = _toArray(arguments, 2);
+		_hitchArgs: function(scope, method){
+			var pre = lang._toArray(arguments, 2);
 			var named = lang.isString(method);
 			return function(){
 				// arrayify arguments
-				var args = _toArray(arguments);
+				var args = lang._toArray(arguments);
 				// locate our method
 				var f = named ? (scope||dojo.global)[method] : method;
 				// invoke with collected args
@@ -139,7 +328,38 @@ define(["./kernel", "../has", "./sniff"], function(dojo, has){
 			}; // Function
 		},
 
-		hitch = function(scope, method){
+		hitch: function(scope, method){
+			// summary:
+			//		Returns a function that will only ever execute in the a given scope.
+			//		This allows for easy use of object member functions
+			//		in callbacks and other places in which the "this" keyword may
+			//		otherwise not reference the expected scope.
+			//		Any number of default positional arguments may be passed as parameters
+			//		beyond "method".
+			//		Each of these values will be used to "placehold" (similar to curry)
+			//		for the hitched function.
+			// scope: Object
+			//		The scope to use when method executes. If method is a string,
+			//		scope is also the object containing method.
+			// method: Function|String...
+			//		A function to be hitched to scope, or the name of the method in
+			//		scope to be hitched.
+			// example:
+			//	|	lang.hitch(foo, "bar")();
+			//		runs foo.bar() in the scope of foo
+			// example:
+			//	|	lang.hitch(foo, myFunction);
+			//		returns a function that runs myFunction in the scope of foo
+			// example:
+			//		Expansion on the default positional arguments passed along from
+			//		hitch. Passed args are mixed first, additional args after.
+			//	|	var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
+			//	|	var fn = lang.hitch(foo, "bar", 1, 2);
+			//	|	fn(3); // logs "1, 2, 3"
+			// example:
+			//	|	var foo = { bar: 2 };
+			//	|	lang.hitch(foo, function(){ this.bar = 10; })();
+			//		execute an anonymous function in scope of foo
 			if(arguments.length > 2){
 				return lang._hitchArgs.apply(dojo, arguments); // Function
 			}
@@ -149,13 +369,13 @@ define(["./kernel", "../has", "./sniff"], function(dojo, has){
 			}
 			if(lang.isString(method)){
 				scope = scope || dojo.global;
-				if(!scope[method]){ throw(['dojo.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
+				if(!scope[method]){ throw(['lang.hitch: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
 				return function(){ return scope[method].apply(scope, arguments || []); }; // Function
 			}
 			return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
 		},
 
-		delegate = (function(){
+		delegate: (function(){
 			// boodman/crockford delegation w/ cornford optimization
 			function TMP(){}
 			return function(obj, props){
@@ -168,32 +388,88 @@ define(["./kernel", "../has", "./sniff"], function(dojo, has){
 				return tmp; // Object
 			};
 		})(),
-
-		efficient = function(obj, offset, startWith){
-			return (startWith||[]).concat(Array.prototype.slice.call(obj, offset||0));
+		/*=====
+		delegate: function(obj, props){
+			// summary:
+			//		Returns a new object which "looks" to obj for properties which it
+			//		does not have a value for. Optionally takes a bag of properties to
+			//		seed the returned object with initially.
+			// description:
+			//		This is a small implementation of the Boodman/Crockford delegation
+			//		pattern in JavaScript. An intermediate object constructor mediates
+			//		the prototype chain for the returned object, using it to delegate
+			//		down to obj for property lookup when object-local lookup fails.
+			//		This can be thought of similarly to ES4's "wrap", save that it does
+			//		not act on types but rather on pure objects.
+			// obj: Object
+			//		The object to delegate to for properties not found directly on the
+			//		return object or in props.
+			// props: Object...
+			//		an object containing properties to assign to the returned object
+			// returns:
+			//		an Object of anonymous type
+			// example:
+			//	|	var foo = { bar: "baz" };
+			//	|	var thinger = lang.delegate(foo, { thud: "xyzzy"});
+			//	|	thinger.bar == "baz"; // delegated to foo
+			//	|	foo.thud == undefined; // by definition
+			//	|	thinger.thud == "xyzzy"; // mixed in from props
+			//	|	foo.bar = "thonk";
+			//	|	thinger.bar == "thonk"; // still delegated to foo's bar
 		},
-
-		_toArray =
-			has("ie") ?
-				(function(){
-					function slow(obj, offset, startWith){
-						var arr = startWith||[];
-						for(var x = offset || 0; x < obj.length; x++){
-							arr.push(obj[x]);
-						}
-						return arr;
+		=====*/
+
+		_toArray: has("ie") ?
+			(function(){
+				function slow(obj, offset, startWith){
+					var arr = startWith||[];
+					for(var x = offset || 0; x < obj.length; x++){
+						arr.push(obj[x]);
 					}
-					return function(obj){
-						return ((obj.item) ? slow : efficient).apply(this, arguments);
-					};
-				})() : efficient,
-
-		partial = function(/*Function|String*/method /*, ...*/){
+					return arr;
+				}
+				return function(obj){
+					return ((obj.item) ? slow : efficient).apply(this, arguments);
+				};
+			})() : efficient,
+		/*=====
+		 _toArray: function(obj, offset, startWith){
+			 // summary:
+			 //		Converts an array-like object (i.e. arguments, DOMCollection) to an
+			 //		array. Returns a new Array with the elements of obj.
+			 // obj: Object
+			 //		the object to "arrayify". We expect the object to have, at a
+			 //		minimum, a length property which corresponds to integer-indexed
+			 //		properties.
+			 // offset: Number?
+			 //		the location in obj to start iterating from. Defaults to 0.
+			 //		Optional.
+			 // startWith: Array?
+			 //		An array to pack with the properties of obj. If provided,
+			 //		properties in obj are appended at the end of startWith and
+			 //		startWith is the returned array.
+		 },
+		 =====*/
+
+		partial: function(/*Function|String*/ method /*, ...*/){
+			// summary:
+			//		similar to hitch() except that the scope object is left to be
+			//		whatever the execution context eventually becomes.
+			// description:
+			//		Calling lang.partial is the functional equivalent of calling:
+			//		|	lang.hitch(null, funcName, ...);
+			// method:
+			//		The function to "wrap"
 			var arr = [ null ];
 			return lang.hitch.apply(dojo, arr.concat(lang._toArray(arguments))); // Function
 		},
 
-		clone = function(/*anything*/ src){
+		clone: function(/*anything*/ src){
+			// summary:
+			//		Clones objects (including DOM nodes) and all children.
+			//		Warning: do not clone cyclic structures.
+			// src:
+			//		The object to clone
 			if(!src || typeof src != "object" || lang.isFunction(src)){
 				// null, undefined, any non-object, or function
 				return src;	// anything
@@ -216,492 +492,114 @@ define(["./kernel", "../has", "./sniff"], function(dojo, has){
 				r = [];
 				for(i = 0, l = src.length; i < l; ++i){
 					if(i in src){
-						r.push(clone(src[i]));
+						r.push(lang.clone(src[i]));
 					}
 				}
-	// we don't clone functions for performance reasons
-	//		}else if(d.isFunction(src)){
-	//			// function
-	//			r = function(){ return src.apply(this, arguments); };
+				// we don't clone functions for performance reasons
+				//		}else if(d.isFunction(src)){
+				//			// function
+				//			r = function(){ return src.apply(this, arguments); };
 			}else{
 				// generic objects
 				r = src.constructor ? new src.constructor() : {};
 			}
-			return lang._mixin(r, src, clone);
+			return lang._mixin(r, src, lang.clone);
 		},
 
 
-		trim = String.prototype.trim ?
+		trim: String.prototype.trim ?
 			function(str){ return str.trim(); } :
 			function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); },
+		/*=====
+		 trim: function(str){
+			 // summary:
+			 //		Trims whitespace from both sides of the string
+			 // str: String
+			 //		String to be trimmed
+			 // returns: String
+			 //		Returns the trimmed string
+			 // description:
+			 //		This version of trim() was selected for inclusion into the base due
+			 //		to its compact size and relatively good performance
+			 //		(see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
+			 //		Uses String.prototype.trim instead, if available.
+			 //		The fastest but longest version of this function is located at
+			 //		lang.string.trim()
+		 },
+		 =====*/
+
+		replace: function(tmpl, map, pattern){
+			// summary:
+			//		Performs parameterized substitutions on a string. Throws an
+			//		exception if any parameter is unmatched.
+			// tmpl: String
+			//		String to be used as a template.
+			// map: Object|Function
+			//		If an object, it is used as a dictionary to look up substitutions.
+			//		If a function, it is called for every substitution with following parameters:
+			//		a whole match, a name, an offset, and the whole template
+			//		string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
+			//		for more details).
+			// pattern: RegEx?
+			//		Optional regular expression objects that overrides the default pattern.
+			//		Must be global and match one item. The default is: /\{([^\}]+)\}/g,
+			//		which matches patterns like that: "{xxx}", where "xxx" is any sequence
+			//		of characters, which doesn't include "}".
+			// returns: String
+			//		Returns the substituted string.
+			// example:
+			//	|	// uses a dictionary for substitutions:
+			//	|	lang.replace("Hello, {name.first} {name.last} AKA {nick}!",
+			//	|		{
+			//	|			nick: "Bob",
+			//	|			name: {
+			//	|				first:	"Robert",
+			//	|				middle: "X",
+			//	|				last:		"Cringely"
+			//	|			}
+			//	|		});
+			//	|	// returns: Hello, Robert Cringely AKA Bob!
+			// example:
+			//	|	// uses an array for substitutions:
+			//	|	lang.replace("Hello, {0} {2}!",
+			//	|		["Robert", "X", "Cringely"]);
+			//	|	// returns: Hello, Robert Cringely!
+			// example:
+			//	|	// uses a function for substitutions:
+			//	|	function sum(a){
+			//	|		var t = 0;
+			//	|		arrayforEach(a, function(x){ t += x; });
+			//	|		return t;
+			//	|	}
+			//	|	lang.replace(
+			//	|		"{count} payments averaging {avg} USD per payment.",
+			//	|		lang.hitch(
+			//	|			{ payments: [11, 16, 12] },
+			//	|			function(_, key){
+			//	|				switch(key){
+			//	|					case "count": return this.payments.length;
+			//	|					case "min":		return Math.min.apply(Math, this.payments);
+			//	|					case "max":		return Math.max.apply(Math, this.payments);
+			//	|					case "sum":		return sum(this.payments);
+			//	|					case "avg":		return sum(this.payments) / this.payments.length;
+			//	|				}
+			//	|			}
+			//	|		)
+			//	|	);
+			//	|	// prints: 3 payments averaging 13 USD per payment.
+			// example:
+			//	|	// uses an alternative PHP-like pattern for substitutions:
+			//	|	lang.replace("Hello, ${0} ${2}!",
+			//	|		["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
+			//	|	// returns: Hello, Robert Cringely!
 
-
-		_pattern = /\{([^\}]+)\}/g,
-
-		replace = function(tmpl, map, pattern){
 			return tmpl.replace(pattern || _pattern, lang.isFunction(map) ?
-				map : function(_, k){ return getObject(k, false, map); });
-		},
+				map : function(_, k){ return lang.getObject(k, false, map); });
+		}
+	};
 
-		lang = {
-			_extraNames:_extraNames,
-			_mixin:_mixin,
-			mixin:mixin,
-			setObject:setObject,
-			getObject:getObject,
-			exists:exists,
-			isString:isString,
-			isArray:isArray,
-			isFunction:isFunction,
-			isObject:isObject,
-			isArrayLike:isArrayLike,
-			isAlien:isAlien,
-			extend:extend,
-			_hitchArgs:_hitchArgs,
-			hitch:hitch,
-			delegate:delegate,
-			_toArray:_toArray,
-			partial:partial,
-			clone:clone,
-			trim:trim,
-			replace:replace
-		};
-
-	has("extend-dojo") && mixin(dojo, lang);
-	return lang;
+	has("extend-dojo") && lang.mixin(dojo, lang);
 
-	/*=====
-	dojo._extraNames
-	// summary:
-	//		Array of strings. Lists property names that must be explicitly processed during for-in interation
-	//		in environments that have has("bug-for-in-skips-shadowed") true.
-	=====*/
-
-	/*=====
-	dojo._mixin = function(dest, source, copyFunc){
-		//	summary:
-		//		Copies/adds all properties of source to dest; returns dest.
-		//	dest: Object:
-		//		The object to which to copy/add all properties contained in source.
-		//	source: Object:
-		//		The object from which to draw all properties to copy into dest.
-		//	copyFunc: Function?:
-		//		The process used to copy/add a property in source; defaults to the Javascript assignment operator.
-		//	returns:
-		//		dest, as modified
-		//	description:
-		//		All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
-		//		found in Object.prototype, are copied/added to dest. Copying/adding each particular property is
-		//		delegated to copyFunc (if any); copyFunc defaults to the Javascript assignment operator if not provided.
-		//		Notice that by default, _mixin executes a so-called "shallow copy" and aggregate types are copied/added by reference.
-	}
-	=====*/
-
-	/*=====
-	dojo.mixin = function(dest, sources){
-	//	summary:
-	//		Copies/adds all properties of one or more sources to dest; returns dest.
-	//	dest: Object
-	//		The object to which to copy/add all properties contained in source. If dest is falsy, then
-	//		a new object is manufactured before copying/adding properties begins.
-	//	sources: Object...
-	//		One of more objects from which to draw all properties to copy into dest. sources are processed
-	//		left-to-right and if more than one of these objects contain the same property name, the right-most
-	//		value "wins".
-	//	returns: Object
-	//		dest, as modified
-	//	description:
-	//		All properties, including functions (sometimes termed "methods"), excluding any non-standard extensions
-	//		found in Object.prototype, are copied/added from sources to dest. sources are processed left to right.
-	//		The Javascript assignment operator is used to copy/add each property; therefore, by default, mixin
-	//		executes a so-called "shallow copy" and aggregate types are copied/added by reference.
-	//	example:
-	//		make a shallow copy of an object
-	//	| var copy = lang.mixin({}, source);
-	//	example:
-	//		many class constructors often take an object which specifies
-	//		values to be configured on the object. In this case, it is
-	//		often simplest to call `lang.mixin` on the `this` object:
-	//	| dojo.declare("acme.Base", null, {
-	//	|		constructor: function(properties){
-	//	|			// property configuration:
-	//	|			lang.mixin(this, properties);
-	//	|
-	//	|			console.log(this.quip);
-	//	|			//	...
-	//	|		},
-	//	|		quip: "I wasn't born yesterday, you know - I've seen movies.",
-	//	|		// ...
-	//	| });
-	//	|
-	//	| // create an instance of the class and configure it
-	//	| var b = new acme.Base({quip: "That's what it does!" });
-	//	example:
-	//		copy in properties from multiple objects
-	//	| var flattened = lang.mixin(
-	//	|		{
-	//	|			name: "Frylock",
-	//	|			braces: true
-	//	|		},
-	//	|		{
-	//	|			name: "Carl Brutanananadilewski"
-	//	|		}
-	//	| );
-	//	|
-	//	| // will print "Carl Brutanananadilewski"
-	//	| console.log(flattened.name);
-	//	| // will print "true"
-	//	| console.log(flattened.braces);
-	}
-	=====*/
-
-	/*=====
-	dojo.setObject = function(name, value, context){
-	// summary:
-	//		Set a property from a dot-separated string, such as "A.B.C"
-	//	description:
-	//		Useful for longer api chains where you have to test each object in
-	//		the chain, or when you have an object reference in string format.
-	//		Objects are created as needed along `path`. Returns the passed
-	//		value if setting is successful or `undefined` if not.
-	//	name: String
-	//		Path to a property, in the form "A.B.C".
-	//	value: anything
-	//		value or object to place at location given by name
-	//	context: Object?
-	//		Optional. Object to use as root of path. Defaults to
-	//		`dojo.global`.
-	//	example:
-	//		set the value of `foo.bar.baz`, regardless of whether
-	//		intermediate objects already exist:
-	//	| lang.setObject("foo.bar.baz", value);
-	//	example:
-	//		without `lang.setObject`, we often see code like this:
-	//	| // ensure that intermediate objects are available
-	//	| if(!obj["parent"]){ obj.parent = {}; }
-	//	| if(!obj.parent["child"]){ obj.parent.child = {}; }
-	//	| // now we can safely set the property
-	//	| obj.parent.child.prop = "some value";
-	//		whereas with `lang.setObject`, we can shorten that to:
-	//	| lang.setObject("parent.child.prop", "some value", obj);
-	}
-	=====*/
-
-	/*=====
-	dojo.getObject = function(name, create, context){
-	// summary:
-	//		Get a property from a dot-separated string, such as "A.B.C"
-	//	description:
-	//		Useful for longer api chains where you have to test each object in
-	//		the chain, or when you have an object reference in string format.
-	//	name: String
-	//		Path to an property, in the form "A.B.C".
-	//	create: Boolean?
-	//		Optional. Defaults to `false`. If `true`, Objects will be
-	//		created at any point along the 'path' that is undefined.
-	//	context: Object?
-	//		Optional. Object to use as root of path. Defaults to
-	//		'dojo.global'. Null may be passed.
-	}
-	=====*/
-
-	/*=====
-	dojo.exists = function(name, obj){
-	//	summary:
-	//		determine if an object supports a given method
-	//	description:
-	//		useful for longer api chains where you have to test each object in
-	//		the chain. Useful for object and method detection.
-	//	name: String
-	//		Path to an object, in the form "A.B.C".
-	//	obj: Object?
-	//		Object to use as root of path. Defaults to
-	//		'dojo.global'. Null may be passed.
-	//	example:
-	//	| // define an object
-	//	| var foo = {
-	//	|		bar: { }
-	//	| };
-	//	|
-	//	| // search the global scope
-	//	| lang.exists("foo.bar"); // true
-	//	| lang.exists("foo.bar.baz"); // false
-	//	|
-	//	| // search from a particular scope
-	//	| lang.exists("bar", foo); // true
-	//	| lang.exists("bar.baz", foo); // false
-	}
-	=====*/
-
-	/*=====
-	dojo.isString = function(it){
-	//	summary:
-	//		Return true if it is a String
-	//	it: anything
-	//		Item to test.
-	}
-	=====*/
-
-	/*=====
-	dojo.isArray = function(it){
-	//	summary:
-	//		Return true if it is an Array.
-	//		Does not work on Arrays created in other windows.
-	//	it: anything
-	//		Item to test.
-	}
-	=====*/
-
-	/*=====
-	dojo.isFunction = function(it){
-	// summary:
-	//		Return true if it is a Function
-	//	it: anything
-	//		Item to test.
-	}
-	=====*/
-
-	/*=====
-	dojo.isObject = function(it){
-	// summary:
-	//		Returns true if it is a JavaScript object (or an Array, a Function
-	//		or null)
-	//	it: anything
-	//		Item to test.
-	}
-	=====*/
-
-	/*=====
-	dojo.isArrayLike = function(it){
-	//	summary:
-	//		similar to dojo.isArray() but more permissive
-	//	it: anything
-	//		Item to test.
-	//	returns:
-	//		If it walks like a duck and quacks like a duck, return `true`
-	//	description:
-	//		Doesn't strongly test for "arrayness".  Instead, settles for "isn't
-	//		a string or number and has a length property". Arguments objects
-	//		and DOM collections will return true when passed to
-	//		dojo.isArrayLike(), but will return false when passed to
-	//		dojo.isArray().
-	}
-	=====*/
-
-	/*=====
-	dojo.isAlien = function(it){
-	// summary:
-	//		Returns true if it is a built-in function or some other kind of
-	//		oddball that *should* report as a function but doesn't
-	}
-	=====*/
-
-	/*=====
-	dojo.extend = function(constructor, props){
-	// summary:
-	//		Adds all properties and methods of props to constructor's
-	//		prototype, making them available to all instances created with
-	//		constructor.
-	//	constructor: Object
-	//		Target constructor to extend.
-	//	props: Object...
-	//		One or more objects to mix into constructor.prototype
-	}
-	=====*/
-
-	/*=====
-	dojo.hitch = function(scope, method){
-	//	summary:
-	//		Returns a function that will only ever execute in the a given scope.
-	//		This allows for easy use of object member functions
-	//		in callbacks and other places in which the "this" keyword may
-	//		otherwise not reference the expected scope.
-	//		Any number of default positional arguments may be passed as parameters
-	//		beyond "method".
-	//		Each of these values will be used to "placehold" (similar to curry)
-	//		for the hitched function.
-	//	scope: Object
-	//		The scope to use when method executes. If method is a string,
-	//		scope is also the object containing method.
-	//	method: Function|String...
-	//		A function to be hitched to scope, or the name of the method in
-	//		scope to be hitched.
-	//	example:
-	//	|	dojo.hitch(foo, "bar")();
-	//		runs foo.bar() in the scope of foo
-	//	example:
-	//	|	dojo.hitch(foo, myFunction);
-	//		returns a function that runs myFunction in the scope of foo
-	//	example:
-	//		Expansion on the default positional arguments passed along from
-	//		hitch. Passed args are mixed first, additional args after.
-	//	|	var foo = { bar: function(a, b, c){ console.log(a, b, c); } };
-	//	|	var fn = dojo.hitch(foo, "bar", 1, 2);
-	//	|	fn(3); // logs "1, 2, 3"
-	//	example:
-	//	|	var foo = { bar: 2 };
-	//	|	dojo.hitch(foo, function(){ this.bar = 10; })();
-	//		execute an anonymous function in scope of foo
-	}
-	=====*/
-
-	/*=====
-	dojo.delegate = function(obj, props){
-		//	summary:
-		//		Returns a new object which "looks" to obj for properties which it
-		//		does not have a value for. Optionally takes a bag of properties to
-		//		seed the returned object with initially.
-		//	description:
-		//		This is a small implementaton of the Boodman/Crockford delegation
-		//		pattern in JavaScript. An intermediate object constructor mediates
-		//		the prototype chain for the returned object, using it to delegate
-		//		down to obj for property lookup when object-local lookup fails.
-		//		This can be thought of similarly to ES4's "wrap", save that it does
-		//		not act on types but rather on pure objects.
-		//	obj: Object
-		//		The object to delegate to for properties not found directly on the
-		//		return object or in props.
-		//	props: Object...
-		//		an object containing properties to assign to the returned object
-		//	returns:
-		//		an Object of anonymous type
-		//	example:
-		//	|	var foo = { bar: "baz" };
-		//	|	var thinger = dojo.delegate(foo, { thud: "xyzzy"});
-		//	|	thinger.bar == "baz"; // delegated to foo
-		//	|	foo.thud == undefined; // by definition
-		//	|	thinger.thud == "xyzzy"; // mixed in from props
-		//	|	foo.bar = "thonk";
-		//	|	thinger.bar == "thonk"; // still delegated to foo's bar
-	}
-	=====*/
-
-	/*=====
-	dojo.partial = function(method){
-	//	summary:
-	//		similar to hitch() except that the scope object is left to be
-	//		whatever the execution context eventually becomes.
-	//	method: Function|String
-	//	description:
-	//		Calling dojo.partial is the functional equivalent of calling:
-	//		|	dojo.hitch(null, funcName, ...);
-	}
-	=====*/
-
-	/*=====
-	dojo.trim = function(str){
-		//	summary:
-		//		Trims whitespace from both sides of the string
-		//	str: String
-		//		String to be trimmed
-		//	returns: String
-		//		Returns the trimmed string
-		//	description:
-		//		This version of trim() was selected for inclusion into the base due
-		//		to its compact size and relatively good performance
-		//		(see [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript)
-		//		Uses String.prototype.trim instead, if available.
-		//		The fastest but longest version of this function is located at
-		//		dojo.string.trim()
-	}
-	=====*/
-
-	/*=====
-	dojo.clone = function(src){
-	// summary:
-	//		Clones objects (including DOM nodes) and all children.
-	//		Warning: do not clone cyclic structures.
-	//	src:
-	//		The object to clone
-	}
-	=====*/
-
-	/*=====
-	dojo._toArray = function(obj, offset, startWith){
-		//	summary:
-		//		Converts an array-like object (i.e. arguments, DOMCollection) to an
-		//		array. Returns a new Array with the elements of obj.
-		//	obj: Object
-		//		the object to "arrayify". We expect the object to have, at a
-		//		minimum, a length property which corresponds to integer-indexed
-		//		properties.
-		//	offset: Number?
-		//		the location in obj to start iterating from. Defaults to 0.
-		//		Optional.
-		//	startWith: Array?
-		//		An array to pack with the properties of obj. If provided,
-		//		properties in obj are appended at the end of startWith and
-		//		startWith is the returned array.
-	}
-	=====*/
-
-	/*=====
-	dojo.replace = function(tmpl, map, pattern){
-		//	summary:
-		//		Performs parameterized substitutions on a string. Throws an
-		//		exception if any parameter is unmatched.
-		//	tmpl: String
-		//		String to be used as a template.
-		//	map: Object|Function
-		//		If an object, it is used as a dictionary to look up substitutions.
-		//		If a function, it is called for every substitution with following
-		//		parameters: a whole match, a name, an offset, and the whole template
-		//		string (see https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/String/replace
-		//		for more details).
-		//	pattern: RegEx?
-		//		Optional regular expression objects that overrides the default pattern.
-		//		Must be global and match one item. The default is: /\{([^\}]+)\}/g,
-		//		which matches patterns like that: "{xxx}", where "xxx" is any sequence
-		//		of characters, which doesn't include "}".
-		//	returns: String
-		//		Returns the substituted string.
-		//	example:
-		//	|	// uses a dictionary for substitutions:
-		//	|	dojo.replace("Hello, {name.first} {name.last} AKA {nick}!",
-		//	|		{
-		//	|			nick: "Bob",
-		//	|			name: {
-		//	|				first:	"Robert",
-		//	|				middle: "X",
-		//	|				last:		"Cringely"
-		//	|			}
-		//	|		});
-		//	|	// returns: Hello, Robert Cringely AKA Bob!
-		//	example:
-		//	|	// uses an array for substitutions:
-		//	|	dojo.replace("Hello, {0} {2}!",
-		//	|		["Robert", "X", "Cringely"]);
-		//	|	// returns: Hello, Robert Cringely!
-		//	example:
-		//	|	// uses a function for substitutions:
-		//	|	function sum(a){
-		//	|		var t = 0;
-		//	|		dojo.forEach(a, function(x){ t += x; });
-		//	|		return t;
-		//	|	}
-		//	|	dojo.replace(
-		//	|		"{count} payments averaging {avg} USD per payment.",
-		//	|		dojo.hitch(
-		//	|			{ payments: [11, 16, 12] },
-		//	|			function(_, key){
-		//	|				switch(key){
-		//	|					case "count": return this.payments.length;
-		//	|					case "min":		return Math.min.apply(Math, this.payments);
-		//	|					case "max":		return Math.max.apply(Math, this.payments);
-		//	|					case "sum":		return sum(this.payments);
-		//	|					case "avg":		return sum(this.payments) / this.payments.length;
-		//	|				}
-		//	|			}
-		//	|		)
-		//	|	);
-		//	|	// prints: 3 payments averaging 13 USD per payment.
-		//	example:
-		//	|	// uses an alternative PHP-like pattern for substitutions:
-		//	|	dojo.replace("Hello, ${0} ${2}!",
-		//	|		["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
-		//	|	// returns: Hello, Robert Cringely!
-		return "";	// String
-	}
-	=====*/
+	return lang;
 });
 
diff --git a/dojo/_base/loader.js b/dojo/_base/loader.js
index be64ab1..e46a715 100644
--- a/dojo/_base/loader.js
+++ b/dojo/_base/loader.js
@@ -1,7 +1,7 @@
-define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
+define(["./kernel", "../has", "require", "module", "../json", "./lang", "./array"], function(dojo, has, require, thisModule, json, lang, array) {
 	// module:
-	//		dojo/_base/lader
-	// summary:
+	//		dojo/_base/loader
+
 	//		This module defines the v1.x synchronous loader API.
 
 	// signal the loader in sync mode...
@@ -12,6 +12,9 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 		return 0;
 	}
 
+	has.add("dojo-fast-sync-require", 1);
+
+
 	var makeErrorToken = function(id){
 			return {src:thisModule.id, id:id};
 		},
@@ -35,49 +38,128 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 			checkDojoRequirePlugin();
 		},
 
-		touched,
+		checkDojoRequirePlugin = (has("dojo-fast-sync-require") ?
+			// This version of checkDojoRequirePlugin makes the observation that all dojoRequireCallbacks can be released
+			// when all *non-dojo/require!, dojo/loadInit!* modules are either executed, not requested, or arrived. This is
+			// the case since there are no more modules the loader is waiting for, therefore, dojo/require! must have
+			// everything it needs on board.
+			//
+			// The potential weakness of this algorithm is that dojo/require will not execute callbacks until *all* dependency
+			// trees are ready. It is possible that some trees may be ready earlier than others, and this extra wait is non-optimal.
+			// Still, for big projects, this seems better than the original algorithm below that proved slow in some cases.
+			// Note, however, the original algorithm had the potential to execute partial trees,  but that potential was never enabled.
+			// There are also other optimization available with the original algorithm that have not been explored.
+			function(){
+				var module, mid;
+				for(mid in modules){
+					module = modules[mid];
+					if(module.noReqPluginCheck===undefined){
+						// tag the module as either a loadInit or require plugin or not for future reference
+						module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0;
+					}
+					if(!module.executed && !module.noReqPluginCheck && module.injected==requested){
+						return;
+					}
+				}
+
+				guardCheckComplete(function(){
+					var oldCallbacks = dojoRequireCallbacks;
+					dojoRequireCallbacks = [];
+					array.forEach(oldCallbacks, function(cb){cb(1);});
+				});
+		} : (function(){
+			// Note: this is the original checkDojoRequirePlugin that is much slower than the algorithm above. However, we know it
+			// works, so we leave it here in case the algorithm above fails in some corner case.
+			//
+			// checkDojoRequirePlugin inspects all of the modules demanded by a dojo/require!<module-list> dependency
+			// to see if they have arrived. The loader does not release *any* of these modules to be instantiated
+			// until *all* of these modules are on board, thereby preventing the evaluation of a module with dojo.require's
+			// that reference modules that are not available.
+			//
+			// The algorithm works by traversing the dependency graphs (remember, there can be cycles so they are not trees)
+			// of each module in the dojoRequireModuleStack array (which contains the list of modules demanded by dojo/require!).
+			// The moment a single module is discovered that is missing, the algorithm gives up and indicates that not all
+			// modules are on board. dojo/loadInit! and dojo/require! are ignored because there dependencies are inserted
+			// directly in dojoRequireModuleStack. For example, if "your/module" module depends on "dojo/require!my/module", then
+			// *both* "dojo/require!my/module" and "my/module" will be in dojoRequireModuleStack. Obviously, if "my/module"
+			// is on board, then "dojo/require!my/module" is also satisfied, so the algorithm doesn't check for "dojo/require!my/module".
+			//
+			// Note: inserting a dojo/require!<some-module-list> dependency in the dojoRequireModuleStack achieves nothing
+			// with the current algorithm; however, having such modules present makes it possible to optimize the algorithm
+			//
+			// Note: prior versions of this algorithm had an optimization that signaled loaded on dojo/require! dependencies
+			// individually (rather than waiting for them all to be resolved). The implementation proved problematic with cycles
+			// and plugins. However, it is possible to reattach that strategy in the future.
+
+			// a set from module-id to {undefined | 1 | 0}, where...
+			//	 undefined => the module has not been inspected
+			//	 0 => the module or at least one of its dependencies has not arrived
+			//	 1 => the module is a loadInit! or require! plugin resource, or is currently being traversed (therefore, assume
+			//		  OK until proven otherwise), or has been completely traversed and all dependencies have arrived
+
+			var touched,
+			traverse = function(m){
+				touched[m.mid] = 1;
+				for(var t, module, deps = m.deps || [], i= 0; i<deps.length; i++){
+					module = deps[i];
+					if(!(t = touched[module.mid])){
+						if(t===0 || !traverse(module)){
+							touched[m.mid] = 0;
+							return false;
+						}
+					}
+				}
+				return true;
+			};
 
-		traverse = function(m){
-			if(touched[m.mid] || /loadInit\!/.test(m.mid)){
-				// loadInit plugin modules are dependencies of modules in dojoRequireModuleStack...
+			return function(){
+				// initialize the touched hash with easy-to-compute values that help short circuit recursive algorithm;
+				// recall loadInit/require plugin modules are dependencies of modules in dojoRequireModuleStack...
 				// which would cause a circular dependency chain that would never be resolved if checked here
-				// notice all dependencies of any particular loadInit plugin module will already
+				// notice all dependencies of any particular loadInit/require plugin module will already
 				// be checked since those are pushed into dojoRequireModuleStack explicitly by the
 				// plugin...so if a particular loadInitPlugin module's dependencies are not really
 				// on board, that *will* be detected elsewhere in the traversal.
-				return true;
-			}
-		    touched[m.mid] = 1;
-			if(m.injected!==arrived && !m.executed){
-				return false;
-			}
-			for(var deps = m.deps || [], i= 0; i<deps.length; i++){
-				if(!traverse(deps[i])){
-					return false;
+				var module, mid;
+				touched = {};
+				for(mid in modules){
+					module = modules[mid];
+					if(module.executed || module.noReqPluginCheck){
+						touched[mid] = 1;
+					}else{
+						if(module.noReqPluginCheck!==0){
+							// tag the module as either a loadInit or require plugin or not for future reference
+							module.noReqPluginCheck = /loadInit\!/.test(mid) || /require\!/.test(mid) ? 1 : 0;
+						}
+						if(module.noReqPluginCheck){
+							touched[mid] = 1;
+						}else if(module.injected!==arrived){
+							// not executed, has not arrived, and is not a loadInit or require plugin resource
+							touched[mid] = 0;
+						}// else, leave undefined and we'll traverse the dependencies
+					}
 				}
-			}
-			return true;
-		},
-
-		checkDojoRequirePlugin = function(){
-			touched = {};
-			dojoRequireModuleStack = array.filter(dojoRequireModuleStack, function(module){
-				return !traverse(module);
-			});
-			if(!dojoRequireModuleStack.length){
-				loaderVars.holdIdle();
-				var oldCallbacks = dojoRequireCallbacks;
-				dojoRequireCallbacks = [];
-				array.forEach(oldCallbacks, function(cb){cb(1);});
-				loaderVars.releaseIdle();
-			}
-		},
+				for(var t, i = 0, end = dojoRequireModuleStack.length; i<end; i++){
+					module = dojoRequireModuleStack[i];
+					if(!(t = touched[module.mid])){
+						if(t===0 || !traverse(module)){
+							return;
+						}
+					}
+				}
+				guardCheckComplete(function(){
+					var oldCallbacks = dojoRequireCallbacks;
+					dojoRequireCallbacks = [];
+					array.forEach(oldCallbacks, function(cb){cb(1);});
+				});
+			};
+		})()),
 
 		dojoLoadInitPlugin = function(mid, require, loaded){
 			// mid names a module that defines a "dojo load init" bundle, an object with two properties:
 			//
-			//   * names: a vector of module ids that give top-level names to define in the lexical scope of def
-			//   * def: a function that contains some some legacy loader API applications
+			//	 * names: a vector of module ids that give top-level names to define in the lexical scope of def
+			//	 * def: a function that contains some some legacy loader API applications
 			//
 			// The point of def is to possibly cause some modules to be loaded (but not executed) by dojo/require! where the module
 			// ids are possibly-determined at runtime. For example, here is dojox.gfx from v1.6 expressed as an AMD module using the dojo/loadInit
@@ -85,37 +167,37 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 			//
 			// // dojox/gfx:
 			//
-			//   define("*loadInit_12, {
-			//     names:["dojo", "dijit", "dojox"],
-			//     def: function(){
-			//       dojo.loadInit(function(){
-			//         var gfx = lang.getObject("dojox.gfx", true);
+			//	 define("*loadInit_12, {
+			//	   names:["dojo", "dijit", "dojox"],
+			//	   def: function(){
+			//		 dojo.loadInit(function(){
+			//		   var gfx = lang.getObject("dojox.gfx", true);
 			//
-			//         //
-			//         // code required to set gfx properties ommitted...
-			//         //
+			//		   //
+			//		   // code required to set gfx properties ommitted...
+			//		   //
 			//
-			//         // now use the calculations to include the runtime-dependent module
-			//         dojo.require("dojox.gfx." + gfx.renderer);
-			//       });
+			//		   // now use the calculations to include the runtime-dependent module
+			//		   dojo.require("dojox.gfx." + gfx.renderer);
+			//		 });
 			//	   }
-			//   });
+			//	 });
 			//
-			//   define(["dojo", "dojo/loadInit!" + id].concat("dojo/require!dojox/gfx/matric,dojox/gfx/_base"), function(dojo){
-			//     // when this AMD factory function is executed, the following modules are guaranteed downloaded but not executed:
-			//     //   "dojox.gfx." + gfx.renderer
-			//     //   dojox.gfx.matrix
-			//     //   dojox.gfx._base
-			//     dojo.provide("dojo.gfx");
-			//     dojo.require("dojox.gfx.matrix");
-			//     dojo.require("dojox.gfx._base");
-			//     dojo.require("dojox.gfx." + gfx.renderer);
-			//     return lang.getObject("dojo.gfx");
-			//   });
-			//  })();
+			//	 define(["dojo", "dojo/loadInit!" + id].concat("dojo/require!dojox/gfx/matric,dojox/gfx/_base"), function(dojo){
+			//	   // when this AMD factory function is executed, the following modules are guaranteed downloaded but not executed:
+			//	   //	"dojox.gfx." + gfx.renderer
+			//	   //	dojox.gfx.matrix
+			//	   //	dojox.gfx._base
+			//	   dojo.provide("dojo.gfx");
+			//	   dojo.require("dojox.gfx.matrix");
+			//	   dojo.require("dojox.gfx._base");
+			//	   dojo.require("dojox.gfx." + gfx.renderer);
+			//	   return lang.getObject("dojo.gfx");
+			//	 });
+			//	})();
 			//
 			// The idea is to run the legacy loader API with global variables shadowed, which allows these variables to
-			// be relocated. For example, dojox and dojo could be relocated to different names by giving a packageMap and the code above will
+			// be relocated. For example, dojox and dojo could be relocated to different names by giving a map and the code above will
 			// execute properly (because the plugin below resolves the load init bundle.names module with respect to the module that demanded
 			// the plugin resource).
 			//
@@ -135,10 +217,12 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 					eval(scopeText);
 
 					var callingModule = require.module,
-						deps = [],
-						hold = {},
+						// the list of modules that need to be downloaded but not executed before the callingModule can be executed
 						requireList = [],
-						p,
+
+						// the list of i18n bundles that are xdomain; undefined if none
+						i18nDeps,
+
 						syncLoaderApi = {
 							provide:function(moduleName){
 								// mark modules that arrive consequent to multiple provides in this module as arrived since they can't be injected
@@ -154,20 +238,27 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 								requireList.push(moduleName);
 							},
 							requireLocalization:function(moduleName, bundleName, locale){
-								// since we're going to need dojo/i8n, add it to deps if not already there
-								deps.length || (deps = ["dojo/i18n"]);
+								// since we're going to need dojo/i8n, add it to i18nDeps if not already there
+								if(!i18nDeps){
+									// don't have to map since that will occur when the dependency is resolved
+									i18nDeps = ["dojo/i18n"];
+								}
 
-								// figure out if the bundle is xdomain; if so, add it to the depsSet
+								// figure out if the bundle is xdomain; if so, add it to the i18nDepsSet
 								locale = (locale || dojo.locale).toLowerCase();
 								moduleName = slashName(moduleName) + "/nls/" + (/root/i.test(locale) ? "" : locale + "/") + slashName(bundleName);
 								if(getModule(moduleName, callingModule).isXd){
-									deps.push("dojo/i18n!" + moduleName);
+									// don't have to map since that will occur when the dependency is resolved
+									i18nDeps.push("dojo/i18n!" + moduleName);
 								}// else the bundle will be loaded synchronously when the module is evaluated
 							},
 							loadInit:function(f){
 								f();
 							}
-						};
+						},
+
+						hold = {},
+						p;
 
 					// hijack the correct dojo and apply bundle.def
 					try{
@@ -184,23 +275,22 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 						}
 					}
 
-					// requireList is the list of modules that need to be downloaded but not executed before the callingModule can be executed
-					requireList.length && deps.push("dojo/require!" + requireList.join(","));
+					if(i18nDeps){
+						requireList = requireList.concat(i18nDeps);
+					}
 
-					dojoRequireCallbacks.push(loaded);
-					array.forEach(requireList, function(mid){
-						var module = getModule(mid, require.module);
-						dojoRequireModuleStack.push(module);
-						injectModule(module);
-					});
-					checkDojoRequirePlugin();
+					if(requireList.length){
+						dojoRequirePlugin(requireList.join(","), require, loaded);
+					}else{
+						loaded();
+					}
 				});
 			});
 		},
 
 		extractApplication = function(
-			text,             // the text to search
-			startSearch,      // the position in text to start looking for the closing paren
+			text,			  // the text to search
+			startSearch,	  // the position in text to start looking for the closing paren
 			startApplication  // the position in text where the function application expression starts
 		){
 			// find end of the call by finding the matching end paren
@@ -231,7 +321,7 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 		// the following regex is taken from 1.6. It is a very poor technique to remove comments and
 		// will fail in some cases; for example, consider the code...
 		//
-		//    var message = "Category-1 */* Category-2";
+		//	  var message = "Category-1 */* Category-2";
 		//
 		// The regex that follows will see a /* comment and trash the code accordingly. In fact, there are all
 		// kinds of cases like this with strings and regexs that will cause this design to fail miserably.
@@ -252,11 +342,11 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 			// to otherApplications string. If no applications were found, return 0, signalling an AMD module. Otherwise, return
 			// loadInitApplications + otherApplications. Fixup text by replacing
 			//
-			//   dojo.loadInit(// etc...
+			//	 dojo.loadInit(// etc...
 			//
 			// with
 			//
-			//   \n 0 && dojo.loadInit(// etc...
+			//	 \n 0 && dojo.loadInit(// etc...
 			//
 			// Which results in the dojo.loadInit from *not* being applied. This design goes a long way towards protecting the
 			// code from an over-agressive removeCommentRe. However...
@@ -280,7 +370,7 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 			// find and extract all dojo.loadInit applications
 			while((match = syncLoaderApiRe.exec(noCommentText))){
 				startSearch = syncLoaderApiRe.lastIndex;
-				startApplication = startSearch  - match[0].length;
+				startApplication = startSearch	- match[0].length;
 				application = extractApplication(noCommentText, startSearch, startApplication);
 				if(match[2]=="loadInit"){
 					loadInitApplications.push(application[0]);
@@ -304,12 +394,12 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 			// module in terms of AMD define instead of creating the dojo proprietary xdomain module expression.
 			// The module could have originated from several sources:
 			//
-			//   * amd require() a module, e.g., require(["my/module"])
-			//   * amd require() a nonmodule, e.g., require(["my/resource.js"')
-			//   * amd define() deps vector (always a module)
-			//   * dojo.require() a module, e.g. dojo.require("my.module")
-			//   * dojo.require() a nonmodule, e.g., dojo.require("my.module", true)
-			//   * dojo.requireIf/requireAfterIf/platformRequire a module
+			//	 * amd require() a module, e.g., require(["my/module"])
+			//	 * amd require() a nonmodule, e.g., require(["my/resource.js"')
+			//	 * amd define() deps vector (always a module)
+			//	 * dojo.require() a module, e.g. dojo.require("my.module")
+			//	 * dojo.require() a nonmodule, e.g., dojo.require("my.module", true)
+			//	 * dojo.requireIf/requireAfterIf/platformRequire a module
 			//
 			// The module is scanned for legacy loader API applications; if none are found, then assume the module is an
 			// AMD module and return 0. Otherwise, a synthetic dojo/loadInit plugin resource is created and the module text
@@ -320,6 +410,8 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 			// when the dojo/loadInit plugin reports it has been loaded, all modules required by the given module are guaranteed
 			// loaded (but not executed). This then allows the module to execute it's code path without interupts, thereby
 			// following the synchronous code path.
+			//
+			// Notice that this function behaves the same whether or not it happens to be in a mapped dojo/loader module.
 
 			var extractResult, id, names = [], namesAsStrings = [];
 			if(buildDetectRe.test(text) || !(extractResult = extractLegacyApiApplications(text))){
@@ -340,12 +432,13 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 			}
 
 			// rewrite the module as a synthetic dojo/loadInit plugin resource + the module expressed as an AMD module that depends on this synthetic resource
-			return "// xdomain rewrite of " + module.path + "\n" +
+			// don't have to map dojo/init since that will occur when the dependency is resolved
+			return "// xdomain rewrite of " + module.mid + "\n" +
 				"define('" + id + "',{\n" +
-				"\tnames:" + dojo.toJson(names) + ",\n" +
+				"\tnames:" + json.stringify(names) + ",\n" +
 				"\tdef:function(" + names.join(",") + "){" + extractResult[1] + "}" +
 				"});\n\n" +
-			    "define(" + dojo.toJson(names.concat(["dojo/loadInit!"+id])) + ", function(" + names.join(",") + "){\n" + extractResult[0] + "});";
+				"define(" + json.stringify(names.concat(["dojo/loadInit!"+id])) + ", function(" + names.join(",") + "){\n" + extractResult[0] + "});";
 		},
 
 		loaderVars = require.initSyncLoader(dojoRequirePlugin, checkDojoRequirePlugin, transformToAmd),
@@ -353,8 +446,8 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 		sync =
 			loaderVars.sync,
 
-		xd =
-			loaderVars.xd,
+		requested =
+			loaderVars.requested,
 
 		arrived =
 			loaderVars.arrived,
@@ -396,7 +489,13 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 			loaderVars.execModule,
 
 		getLegacyMode =
-			loaderVars.getLegacyMode;
+			loaderVars.getLegacyMode,
+
+		guardCheckComplete =
+			loaderVars.guardCheckComplete;
+
+	// there is exactly one dojoRequirePlugin among possibly-many dojo/_base/loader's (owing to mapping)
+	dojoRequirePlugin = loaderVars.dojoRequirePlugin;
 
 	dojo.provide = function(mid){
 		var executingModule = syncExecStack[0],
@@ -418,17 +517,17 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 	has.add("config-publishRequireResult", 1, 0, 0);
 
 	dojo.require = function(moduleName, omitModuleCheck) {
-		//	summary:
+		// summary:
 		//		loads a Javascript module from the appropriate URI
 		//
-		//	moduleName: String
+		// moduleName: String
 		//		module name to load, using periods for separators,
 		//		 e.g. "dojo.date.locale".  Module paths are de-referenced by dojo's
 		//		internal mapping of locations to names and are disambiguated by
 		//		longest prefix. See `dojo.registerModulePath()` for details on
 		//		registering new modules.
 		//
-		//	omitModuleCheck: Boolean?
+		// omitModuleCheck: Boolean?
 		//		if `true`, omitModuleCheck skips the step of ensuring that the
 		//		loaded file actually defines the symbol it is referenced by.
 		//		For example if it called as `dojo.require("a.b.c")` and the
@@ -436,40 +535,40 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 		//		and exception will be throws whereas no exception is raised
 		//		when called as `dojo.require("a.b.c", true)`
 		//
-		//	description:
-		// 		Modules are loaded via dojo.require by using one of two loaders: the normal loader
-		// 		and the xdomain loader. The xdomain loader is used when dojo was built with a
-		// 		custom build that specified loader=xdomain and the module lives on a modulePath
-		// 		that is a whole URL, with protocol and a domain. The versions of Dojo that are on
-		// 		the Google and AOL CDNs use the xdomain loader.
+		// description:
+		//		Modules are loaded via dojo.require by using one of two loaders: the normal loader
+		//		and the xdomain loader. The xdomain loader is used when dojo was built with a
+		//		custom build that specified loader=xdomain and the module lives on a modulePath
+		//		that is a whole URL, with protocol and a domain. The versions of Dojo that are on
+		//		the Google and AOL CDNs use the xdomain loader.
 		//
-		// 		If the module is loaded via the xdomain loader, it is an asynchronous load, since
-		// 		the module is added via a dynamically created script tag. This
-		// 		means that dojo.require() can return before the module has loaded. However, this
-		// 		should only happen in the case where you do dojo.require calls in the top-level
-		// 		HTML page, or if you purposely avoid the loader checking for dojo.require
-		// 		dependencies in your module by using a syntax like dojo["require"] to load the module.
+		//		If the module is loaded via the xdomain loader, it is an asynchronous load, since
+		//		the module is added via a dynamically created script tag. This
+		//		means that dojo.require() can return before the module has loaded. However, this
+		//		should only happen in the case where you do dojo.require calls in the top-level
+		//		HTML page, or if you purposely avoid the loader checking for dojo.require
+		//		dependencies in your module by using a syntax like dojo["require"] to load the module.
 		//
-		// 		Sometimes it is useful to not have the loader detect the dojo.require calls in the
-		// 		module so that you can dynamically load the modules as a result of an action on the
-		// 		page, instead of right at module load time.
+		//		Sometimes it is useful to not have the loader detect the dojo.require calls in the
+		//		module so that you can dynamically load the modules as a result of an action on the
+		//		page, instead of right at module load time.
 		//
-		// 		Also, for script blocks in an HTML page, the loader does not pre-process them, so
-		// 		it does not know to download the modules before the dojo.require calls occur.
+		//		Also, for script blocks in an HTML page, the loader does not pre-process them, so
+		//		it does not know to download the modules before the dojo.require calls occur.
 		//
-		// 		So, in those two cases, when you want on-the-fly module loading or for script blocks
-		// 		in the HTML page, special care must be taken if the dojo.required code is loaded
-		// 		asynchronously. To make sure you can execute code that depends on the dojo.required
-		// 		modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
-		// 		callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
-		// 		executing.
+		//		So, in those two cases, when you want on-the-fly module loading or for script blocks
+		//		in the HTML page, special care must be taken if the dojo.required code is loaded
+		//		asynchronously. To make sure you can execute code that depends on the dojo.required
+		//		modules, be sure to add the code that depends on the modules in a dojo.addOnLoad()
+		//		callback. dojo.addOnLoad waits for all outstanding modules to finish loading before
+		//		executing.
 		//
-		// 		This type of syntax works with both xdomain and normal loaders, so it is good
-		// 		practice to always use this idiom for on-the-fly code loading and in HTML script
-		// 		blocks. If at some point you change loaders and where the code is loaded from,
-		// 		it will all still work.
+		//		This type of syntax works with both xdomain and normal loaders, so it is good
+		//		practice to always use this idiom for on-the-fly code loading and in HTML script
+		//		blocks. If at some point you change loaders and where the code is loaded from,
+		//		it will all still work.
 		//
-		// 		More on how dojo.require
+		//		More on how dojo.require
 		//		`dojo.require("A.B")` first checks to see if symbol A.B is
 		//		defined. If it is, it is simply returned (nothing to do).
 		//
@@ -480,22 +579,22 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 		//		to load, or if the symbol `A.B` is not defined after loading.
 		//
 		//		It returns the object `A.B`, but note the caveats above about on-the-fly loading and
-		// 		HTML script blocks when the xdomain loader is loading a module.
+		//		HTML script blocks when the xdomain loader is loading a module.
 		//
 		//		`dojo.require()` does nothing about importing symbols into
-		//		the current namespace.  It is presumed that the caller will
+		//		the current namespace.	It is presumed that the caller will
 		//		take care of that.
 		//
-		// 	example:
-		// 		To use dojo.require in conjunction with dojo.ready:
+		// example:
+		//		To use dojo.require in conjunction with dojo.ready:
 		//
 		//		|	dojo.require("foo");
 		//		|	dojo.require("bar");
-		//	   	|	dojo.addOnLoad(function(){
-		//	   	|		//you can now safely do something with foo and bar
-		//	   	|	});
+		//		|	dojo.addOnLoad(function(){
+		//		|		//you can now safely do something with foo and bar
+		//		|	});
 		//
-		//	example:
+		// example:
 		//		For example, to import all symbols into a local block, you might write:
 		//
 		//		|	with (dojo.require("A.B")) {
@@ -505,9 +604,9 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 		//		And to import just the leaf symbol to a local variable:
 		//
 		//		|	var B = dojo.require("A.B");
-		//	   	|	...
+		//		|	...
 		//
-		//	returns:
+		// returns:
 		//		the required namespace object
 		function doRequire(mid, omitModuleCheck){
 			var module = getModule(slashName(mid), require.module);
@@ -524,6 +623,7 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 			}
 			omitModuleCheck && (module.result = nonmodule);
 
+			// rcg...why here and in two lines??
 			var currentMode = getLegacyMode();
 
 			// recall, in sync mode to inject is to *eval* the module text
@@ -537,9 +637,10 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 			if(module.executed!==executed && module.injected===arrived){
 				// the module was already here before injectModule was called probably finishing up a xdomain
 				// load, but maybe a module given to the loader directly rather than having the loader retrieve it
-				loaderVars.holdIdle();
-				execModule(module);
-				loaderVars.releaseIdle();
+
+				loaderVars.guardCheckComplete(function(){
+					execModule(module);
+				});
 			}
 			if(module.executed){
 				return module.result;
@@ -547,8 +648,8 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 
 			if(currentMode==sync){
 				// the only way to get here is in sync mode and dojo.required a module that
-				//   * was loaded async in the injectModule application a few lines up
-				//   * was an AMD module that had deps that are being loaded async and therefore couldn't execute
+				//	 * was loaded async in the injectModule application a few lines up
+				//	 * was an AMD module that had deps that are being loaded async and therefore couldn't execute
 				if(module.cjs){
 					// the module was an AMD module; unshift, not push, which causes the current traversal to be reattempted from the top
 					execQ.unshift(module);
@@ -561,6 +662,7 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 				// the module value synchronously; make sure it gets executed though
 				execQ.push(module);
 			}
+
 			return undefined;
 		}
 
@@ -576,14 +678,14 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 	};
 
 	dojo.registerModulePath = function(/*String*/moduleName, /*String*/prefix){
-		//	summary:
+		// summary:
 		//		Maps a module name to a path
-		//	description:
+		// description:
 		//		An unregistered module is given the default path of ../[module],
 		//		relative to Dojo root. For example, module acme is mapped to
 		//		../acme.  If you want to use a different module name, use
 		//		dojo.registerModulePath.
-		//	example:
+		// example:
 		//		If your dojo.js is located at this location in the web root:
 		//	|	/myapp/js/dojo/dojo/dojo.js
 		//		and your modules are located at:
@@ -610,10 +712,10 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 	};
 
 	dojo.platformRequire = function(/*Object*/modMap){
-		//	summary:
+		// summary:
 		//		require one or more modules based on which host environment
 		//		Dojo is currently operating in
-		//	description:
+		// description:
 		//		This method takes a "map" of arrays which one can use to
 		//		optionally load dojo modules. The map is indexed by the
 		//		possible dojo.name_ values, with two additional values:
@@ -622,8 +724,8 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 		//		dojo.name_, set by your host environment. The items in the
 		//		"common" array will *always* be loaded, regardless of which
 		//		list is chosen.
-		//	example:
- 		//		|	dojo.platformRequire({
+		// example:
+		//		|	dojo.platformRequire({
 		//		|		browser: [
 		//		|			"foo.sample", // simple module
 		//		|			"foo.test",
@@ -664,8 +766,11 @@ define(["./kernel", "../has", "require", "module", "./json", "./lang", "./array"
 	};
 
 	return {
+		// summary:
+		//		This module defines the v1.x synchronous loader API.
+
 		extractLegacyApiApplications:extractLegacyApiApplications,
-		require:loaderVars.dojoRequirePlugin,
+		require:dojoRequirePlugin,
 		loadInit:dojoLoadInitPlugin
 	};
 });
diff --git a/dojo/_base/query.js b/dojo/_base/query.js
index 0520710..9e5516a 100644
--- a/dojo/_base/query.js
+++ b/dojo/_base/query.js
@@ -1,3 +1,13 @@
-define(["./kernel", "../query", "./NodeList"], function(dojo){
-	return dojo.query;
+define(["../query", "./NodeList"], function(query){
+	// module:
+	//		dojo/_base/query
+
+	/*=====
+	return {
+		// summary:
+		//		Deprecated.   Use dojo/query instead.
+	};
+	=====*/
+
+	return query;
 });
diff --git a/dojo/_base/sniff.js b/dojo/_base/sniff.js
index 948efbf..979c1e7 100644
--- a/dojo/_base/sniff.js
+++ b/dojo/_base/sniff.js
@@ -1,187 +1,93 @@
-define(["./kernel", "../has"], function(dojo, has){
+define(["./kernel", "./lang", "../sniff"], function(dojo, lang, has){
 	// module:
-	//		dojo/sniff
-	// summary:
-	//		This module populates the dojo browser version sniffing properties.
+	//		dojo/_base/sniff
+
+	/*=====
+	return {
+		// summary:
+		//		Deprecated.   New code should use dojo/sniff.
+		//		This module populates the dojo browser version sniffing properties like dojo.isIE.
+	};
+	=====*/
 
 	if(!has("host-browser")){
 		return has;
 	}
 
-	dojo.isBrowser = true,
+	// no idea what this is for, or if it's used
 	dojo._name = "browser";
 
-	var hasAdd = has.add,
-		n = navigator,
-		dua = n.userAgent,
-		dav = n.appVersion,
-		tv = parseFloat(dav),
-		isOpera,
-		isAIR,
-		isKhtml,
-		isWebKit,
-		isChrome,
-		isMac,
-		isSafari,
-		isMozilla ,
-		isMoz,
-		isIE,
-		isFF,
-		isQuirks,
-		isIos,
-		isAndroid,
-		isWii;
-
-	/*=====
-	dojo.isBrowser = {
-		//	example:
-		//	| if(dojo.isBrowser){ ... }
-	};
-
-	dojo.isFF = {
-		//	example:
-		//	| if(dojo.isFF > 1){ ... }
-	};
-
-	dojo.isIE = {
-		// example:
-		//	| if(dojo.isIE > 6){
-		//	|		// we are IE7
-		//	| }
-	};
-
-	dojo.isSafari = {
-		//	example:
-		//	| if(dojo.isSafari){ ... }
-		//	example:
-		//		Detect iPhone:
-		//	| if(dojo.isSafari && navigator.userAgent.indexOf("iPhone") != -1){
-		//	|		// we are iPhone. Note, iPod touch reports "iPod" above and fails this test.
-		//	| }
-	};
-
-	dojo.mixin(dojo, {
+	lang.mixin(dojo, {
 		// isBrowser: Boolean
 		//		True if the client is a web-browser
 		isBrowser: true,
-		//	isFF: Number | undefined
+
+		// isFF: Number|undefined
 		//		Version as a Number if client is FireFox. undefined otherwise. Corresponds to
 		//		major detected FireFox version (1.5, 2, 3, etc.)
-		isFF: 2,
-		//	isIE: Number | undefined
+		isFF: has("ff"),
+
+		// isIE: Number|undefined
 		//		Version as a Number if client is MSIE(PC). undefined otherwise. Corresponds to
 		//		major detected IE version (6, 7, 8, etc.)
-		isIE: 6,
-		//	isKhtml: Number | undefined
+		isIE: has("ie"),
+
+		// isKhtml: Number|undefined
 		//		Version as a Number if client is a KHTML browser. undefined otherwise. Corresponds to major
 		//		detected version.
-		isKhtml: 0,
-		//	isWebKit: Number | undefined
+		isKhtml: has("khtml"),
+
+		// isWebKit: Number|undefined
 		//		Version as a Number if client is a WebKit-derived browser (Konqueror,
 		//		Safari, Chrome, etc.). undefined otherwise.
-		isWebKit: 0,
-		//	isMozilla: Number | undefined
+		isWebKit: has("webkit"),
+
+		// isMozilla: Number|undefined
 		//		Version as a Number if client is a Mozilla-based browser (Firefox,
 		//		SeaMonkey). undefined otherwise. Corresponds to major detected version.
-		isMozilla: 0,
-		//	isOpera: Number | undefined
+		isMozilla: has("mozilla"),
+		// isMoz: Number|undefined
+		//		Version as a Number if client is a Mozilla-based browser (Firefox,
+		//		SeaMonkey). undefined otherwise. Corresponds to major detected version.
+		isMoz: has("mozilla"),
+
+		// isOpera: Number|undefined
 		//		Version as a Number if client is Opera. undefined otherwise. Corresponds to
 		//		major detected version.
-		isOpera: 0,
-		//	isSafari: Number | undefined
+		isOpera: has("opera"),
+
+		// isSafari: Number|undefined
 		//		Version as a Number if client is Safari or iPhone. undefined otherwise.
-		isSafari: 0,
-		//	isChrome: Number | undefined
+		isSafari: has("safari"),
+
+		// isChrome: Number|undefined
 		//		Version as a Number if client is Chrome browser. undefined otherwise.
-		isChrome: 0,
-		//	isMac: Boolean
+		isChrome: has("chrome"),
+
+		// isMac: Boolean
 		//		True if the client runs on Mac
-		isMac: 0,
-		// isIos: Boolean
-		//		True if client is iPhone, iPod, or iPad
-		isIos: 0,
-		// isAndroid: Number | undefined
+		isMac: has("mac"),
+
+		// isIos: Number|undefined
+		//		Version as a Number if client is iPhone, iPod, or iPad. undefined otherwise.
+		isIos: has("ios"),
+
+		// isAndroid: Number|undefined
 		//		Version as a Number if client is android browser. undefined otherwise.
-		isAndroid: 0,
+		isAndroid: has("android"),
+
 		// isWii: Boolean
 		//		True if client is Wii
-		isWii: 0
-	});
-	=====*/
+		isWii: has("wii"),
 
-	// fill in the rendering support information in dojo.render.*
-	if(dua.indexOf("AdobeAIR") >= 0){ isAIR = 1; }
-	isKhtml = (dav.indexOf("Konqueror") >= 0) ? tv : 0;
-	isWebKit = parseFloat(dua.split("WebKit/")[1]) || undefined;
-	isChrome = parseFloat(dua.split("Chrome/")[1]) || undefined;
-	isMac = dav.indexOf("Macintosh") >= 0;
-	isIos = /iPhone|iPod|iPad/.test(dua);
-	isAndroid = parseFloat(dua.split("Android ")[1]) || undefined;
-	isWii = typeof opera != "undefined" && opera.wiiremote;
-
-	// safari detection derived from:
-	//		http://developer.apple.com/internet/safari/faq.html#anchor2
-	//		http://developer.apple.com/internet/safari/uamatrix.html
-	var index = Math.max(dav.indexOf("WebKit"), dav.indexOf("Safari"), 0);
-	if(index && !isChrome){
-		// try to grab the explicit Safari version first. If we don't get
-		// one, look for less than 419.3 as the indication that we're on something
-		// "Safari 2-ish".
-		isSafari = parseFloat(dav.split("Version/")[1]);
-		if(!isSafari || parseFloat(dav.substr(index + 7)) <= 419.3){
-			isSafari = 2;
-		}
-	}
-
-	if (!has("dojo-webkit")) {
-		if(dua.indexOf("Opera") >= 0){
-			isOpera = tv;
-			// see http://dev.opera.com/articles/view/opera-ua-string-changes and http://www.useragentstring.com/pages/Opera/
-			// 9.8 has both styles; <9.8, 9.9 only old style
-			if(isOpera >= 9.8){
-				isOpera = parseFloat(dua.split("Version/")[1]) || tv;
-			}
-		}
-
-		if(dua.indexOf("Gecko") >= 0 && !isKhtml && !isWebKit){
-			isMozilla = isMoz = tv;
-		}
-		if(isMoz){
-			//We really need to get away from this. Consider a sane isGecko approach for the future.
-			isFF = parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined;
-		}
-		if(document.all && !isOpera){
-			isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
-			//In cases where the page has an HTTP header or META tag with
-			//X-UA-Compatible, then it is in emulation mode.
-			//Make sure isIE reflects the desired version.
-			//document.documentMode of 5 means quirks mode.
-			//Only switch the value if documentMode's major version
-			//is different from isIE's major version.
-			var mode = document.documentMode;
-			if(mode && mode != 5 && Math.floor(isIE) != mode){
-				isIE = mode;
-			}
-		}
-	}
+		// isQuirks: Boolean
+		//		Page is in quirks mode.
+		isQuirks: has("quirks"),
 
-	isQuirks = document.compatMode == "BackCompat";
-
-	hasAdd("opera", dojo.isOpera = isOpera);
-	hasAdd("air", dojo.isAIR = isAIR);
-	hasAdd("khtml", dojo.isKhtml = isKhtml);
-	hasAdd("webkit", dojo.isWebKit = isWebKit);
-	hasAdd("chrome", dojo.isChrome = isChrome);
-	hasAdd("mac", dojo.isMac = isMac );
-	hasAdd("safari", dojo.isSafari = isSafari);
-	hasAdd("mozilla", dojo.isMozilla = dojo.isMoz = isMozilla );
-	hasAdd("ie", dojo.isIE = isIE );
-	hasAdd("ff", dojo.isFF = isFF);
-	hasAdd("quirks", dojo.isQuirks = isQuirks);
-	hasAdd("ios", dojo.isIos = isIos);
-	hasAdd("android", dojo.isAndroid = isAndroid);
-
-	dojo.locale = dojo.locale || (isIE ? n.userLanguage : n.language).toLowerCase();
+		// isAir: Boolean
+		//		True if client is Adobe Air
+		isAir: has("air")
+	});
 
 	return has;
 });
diff --git a/dojo/_base/unload.js b/dojo/_base/unload.js
index 26f00df..60a9a7e 100644
--- a/dojo/_base/unload.js
+++ b/dojo/_base/unload.js
@@ -1,60 +1,59 @@
-define(["./kernel", "./connect"], function(dojo, connect) {
-	// module:
-	//		dojo/unload
-	// summary:
-	//		This module contains the document and window unload detection API.
+define(["./kernel", "./lang", "../on"], function(dojo, lang, on){
 
-	var win = window;
+// module:
+//		dojo/unload
 
-	/*=====
-		dojo.windowUnloaded = function(){
-			// summary:
-			//		signal fired by impending window destruction. You may use
-			//		dojo.addOnWindowUnload() to register a listener for this
-			//		event. NOTE: if you wish to dojo.connect() to this method
-			//		to perform page/application cleanup, be aware that this
-			//		event WILL NOT fire if no handler has been registered with
-			//		dojo.addOnWindowUnload. This behavior started in Dojo 1.3.
-			//		Previous versions always triggered dojo.windowUnloaded. See
-			//		dojo.addOnWindowUnload for more info.
-		};
-	=====*/
+var win = window;
 
-	dojo.addOnWindowUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
+var unload = {
+	// summary:
+	//		This module contains the document and window unload detection API.
+
+	addOnWindowUnload: function(/*Object|Function?*/ obj, /*String|Function?*/ functionName){
 		// summary:
 		//		registers a function to be triggered when window.onunload
 		//		fires.
-		//	description:
+		// description:
 		//		The first time that addOnWindowUnload is called Dojo
 		//		will register a page listener to trigger your unload
 		//		handler with. Note that registering these handlers may
-		//		destory "fastback" page caching in browsers that support
+		//		destroy "fastback" page caching in browsers that support
 		//		it. Be careful trying to modify the DOM or access
 		//		JavaScript properties during this phase of page unloading:
 		//		they may not always be available. Consider
-		//		dojo.addOnUnload() if you need to modify the DOM or do
-		//		heavy JavaScript work since it fires at the eqivalent of
+		//		addOnUnload() if you need to modify the DOM or do
+		//		heavy JavaScript work since it fires at the equivalent of
 		//		the page's "onbeforeunload" event.
 		// example:
-		//	| dojo.addOnWindowUnload(functionPointer)
-		//	| dojo.addOnWindowUnload(object, "functionName");
-		//	| dojo.addOnWindowUnload(object, function(){ /* ... */});
+		//	|	unload.addOnWindowUnload(functionPointer)
+		//	|	unload.addOnWindowUnload(object, "functionName");
+		//	|	unload.addOnWindowUnload(object, function(){ /* ... */});
 
-		if (!dojo.windowUnloaded) {
-			connect.connect(win, "unload", (dojo.windowUnloaded= function(){}));
+		if (!dojo.windowUnloaded){
+			on(win, "unload", (dojo.windowUnloaded = function(){
+				// summary:
+				//		signal fired by impending window destruction. You may use
+				//		dojo.addOnWindowUnload() to register a listener for this
+				//		event. NOTE: if you wish to dojo.connect() to this method
+				//		to perform page/application cleanup, be aware that this
+				//		event WILL NOT fire if no handler has been registered with
+				//		addOnWindowUnload(). This behavior started in Dojo 1.3.
+				//		Previous versions always triggered windowUnloaded(). See
+				//		addOnWindowUnload for more info.
+			}));
 		}
-		connect.connect(win, "unload", obj, functionName);
-	};
+		on(win, "unload", lang.hitch(obj, functionName));
+	},
 
-	dojo.addOnUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
+	addOnUnload: function(/*Object?|Function?*/ obj, /*String|Function?*/ functionName){
 		// summary:
 		//		registers a function to be triggered when the page unloads.
-		//	description:
+		// description:
 		//		The first time that addOnUnload is called Dojo will
 		//		register a page listener to trigger your unload handler
 		//		with.
 		//
-		//		In a browser enviroment, the functions will be triggered
+		//		In a browser environment, the functions will be triggered
 		//		during the window.onbeforeunload event. Be careful of doing
 		//		too much work in an unload handler. onbeforeunload can be
 		//		triggered if a link to download a file is clicked, or if
@@ -67,15 +66,17 @@ define(["./kernel", "./connect"], function(dojo, connect) {
 		//		browsers from using a "fast back" cache to make page
 		//		loading via back button instantaneous.
 		// example:
-		//	| dojo.addOnUnload(functionPointer)
-		//	| dojo.addOnUnload(object, "functionName")
-		//	| dojo.addOnUnload(object, function(){ /* ... */});
+		//	|	dojo.addOnUnload(functionPointer)
+		//	|	dojo.addOnUnload(object, "functionName")
+		//	|	dojo.addOnUnload(object, function(){ /* ... */});
+
+		on(win, "beforeunload", lang.hitch(obj, functionName));
+	}
+};
+
+dojo.addOnWindowUnload = unload.addOnWindowUnload;
+dojo.addOnUnload = unload.addOnUnload;
 
-		connect.connect(win, "beforeunload", obj, functionName);
-	};
+return unload;
 
-	return {
-		addOnWindowUnload: dojo.addOnWindowUnload,
-		addOnUnload: dojo.addOnUnload
-	};
 });
diff --git a/dojo/_base/url.js b/dojo/_base/url.js
index 74ada72..b358b6a 100644
--- a/dojo/_base/url.js
+++ b/dojo/_base/url.js
@@ -1,8 +1,6 @@
-define(["./kernel"], function(dojo) {
+define(["./kernel"], function(dojo){
 	// module:
 	//		dojo/url
-	// summary:
-	//		This module contains dojo._Url
 
 	var
 		ore = new RegExp("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$"),
diff --git a/dojo/_base/window.js b/dojo/_base/window.js
index 06092e8..df479b1 100644
--- a/dojo/_base/window.js
+++ b/dojo/_base/window.js
@@ -1,125 +1,133 @@
-define(["./kernel", "../has", "./sniff"], function(dojo, has){
-	// module:
-	//		dojo/window
-	// summary:
-	//		This module provides an API to save/set/restore the global/document scope.
+define(["./kernel", "./lang", "../sniff"], function(dojo, lang, has){
+// module:
+//		dojo/_base/window
 
-/*=====
-dojo.doc = {
-	// summary:
-	//		Alias for the current document. 'dojo.doc' can be modified
-	//		for temporary context shifting. Also see dojo.withDoc().
-	// description:
-	//		Refer to dojo.doc rather
-	//		than referring to 'window.document' to ensure your code runs
-	//		correctly in managed contexts.
-	// example:
-	//	|	n.appendChild(dojo.doc.createElement('div'));
-}
-=====*/
-dojo.doc = this["document"] || null;
-
-dojo.body = function(){
+var ret = {
 	// summary:
-	//		Return the body element of the document
-	//		return the body object associated with dojo.doc
-	// example:
-	//	|	dojo.body().appendChild(dojo.doc.createElement('div'));
-
-	// Note: document.body is not defined for a strict xhtml document
-	// Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
-	return dojo.doc.body || dojo.doc.getElementsByTagName("body")[0]; // Node
-};
+	//		API to save/set/restore the global/document scope.
 
-dojo.setContext = function(/*Object*/globalObject, /*DocumentElement*/globalDocument){
-	// summary:
-	//		changes the behavior of many core Dojo functions that deal with
-	//		namespace and DOM lookup, changing them to work in a new global
-	//		context (e.g., an iframe). The varibles dojo.global and dojo.doc
-	//		are modified as a result of calling this function and the result of
-	//		`dojo.body()` likewise differs.
-	dojo.global = ret.global = globalObject;
-	dojo.doc = ret.doc = globalDocument;
-};
+	global: dojo.global,
+	/*=====
+	 global: {
+		 // summary:
+		 //		Alias for the current window. 'global' can be modified
+		 //		for temporary context shifting. See also withGlobal().
+		 // description:
+		 //		Use this rather than referring to 'window' to ensure your code runs
+		 //		correctly in managed contexts.
+	 },
+	 =====*/
 
-dojo.withGlobal = function(	/*Object*/globalObject,
-							/*Function*/callback,
-							/*Object?*/thisObject,
-							/*Array?*/cbArguments){
-	// summary:
-	//		Invoke callback with globalObject as dojo.global and
-	//		globalObject.document as dojo.doc.
-	// description:
-	//		Invoke callback with globalObject as dojo.global and
-	//		globalObject.document as dojo.doc. If provided, globalObject
-	//		will be executed in the context of object thisObject
-	//		When callback() returns or throws an error, the dojo.global
-	//		and dojo.doc will be restored to its previous state.
-
-	var oldGlob = dojo.global;
-	try{
+	doc: this["document"] || null,
+	/*=====
+	doc: {
+		// summary:
+		//		Alias for the current document. 'doc' can be modified
+		//		for temporary context shifting. See also withDoc().
+		// description:
+		//		Use this rather than referring to 'window.document' to ensure your code runs
+		//		correctly in managed contexts.
+		// example:
+		//	|	n.appendChild(dojo.doc.createElement('div'));
+	},
+	=====*/
+
+	body: function(/*Document?*/ doc){
+		// summary:
+		//		Return the body element of the specified document or of dojo/_base/window::doc.
+		// example:
+		//	|	win.body().appendChild(dojo.doc.createElement('div'));
+
+		// Note: document.body is not defined for a strict xhtml document
+		// Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
+		doc = doc || dojo.doc;
+		return doc.body || doc.getElementsByTagName("body")[0]; // Node
+	},
+
+	setContext: function(/*Object*/ globalObject, /*DocumentElement*/ globalDocument){
+		// summary:
+		//		changes the behavior of many core Dojo functions that deal with
+		//		namespace and DOM lookup, changing them to work in a new global
+		//		context (e.g., an iframe). The varibles dojo.global and dojo.doc
+		//		are modified as a result of calling this function and the result of
+		//		`dojo.body()` likewise differs.
 		dojo.global = ret.global = globalObject;
-		return dojo.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments);
-	}finally{
-		dojo.global = ret.global = oldGlob;
-	}
-};
+		dojo.doc = ret.doc = globalDocument;
+	},
 
-dojo.withDoc = function(	/*DocumentElement*/documentObject,
-							/*Function*/callback,
-							/*Object?*/thisObject,
-							/*Array?*/cbArguments){
-	// summary:
-	//		Invoke callback with documentObject as dojo.doc.
-	// description:
-	//		Invoke callback with documentObject as dojo.doc. If provided,
-	//		callback will be executed in the context of object thisObject
-	//		When callback() returns or throws an error, the dojo.doc will
-	//		be restored to its previous state.
-
-	var oldDoc = dojo.doc,
-		oldQ = dojo.isQuirks,
-		oldIE = dojo.isIE, isIE, mode, pwin;
-
-	try{
-		dojo.doc = ret.doc = documentObject;
-		// update dojo.isQuirks and the value of the has feature "quirks"
-		dojo.isQuirks = has.add("quirks", dojo.doc.compatMode == "BackCompat", true, true); // no need to check for QuirksMode which was Opera 7 only
-
-		if(has("ie")){
-			if((pwin = documentObject.parentWindow) && pwin.navigator){
-				// re-run IE detection logic and update dojo.isIE / has("ie")
-				// (the only time parentWindow/navigator wouldn't exist is if we were not
-				// passed an actual legitimate document object)
-				isIE = parseFloat(pwin.navigator.appVersion.split("MSIE ")[1]) || undefined;
-				mode = documentObject.documentMode;
-				if(mode && mode != 5 && Math.floor(isIE) != mode){
-					isIE = mode;
+	withGlobal: function(	/*Object*/ globalObject,
+							/*Function*/ callback,
+							/*Object?*/ thisObject,
+							/*Array?*/ cbArguments){
+		// summary:
+		//		Invoke callback with globalObject as dojo.global and
+		//		globalObject.document as dojo.doc.
+		// description:
+		//		Invoke callback with globalObject as dojo.global and
+		//		globalObject.document as dojo.doc. If provided, globalObject
+		//		will be executed in the context of object thisObject
+		//		When callback() returns or throws an error, the dojo.global
+		//		and dojo.doc will be restored to its previous state.
+
+		var oldGlob = dojo.global;
+		try{
+			dojo.global = ret.global = globalObject;
+			return ret.withDoc.call(null, globalObject.document, callback, thisObject, cbArguments);
+		}finally{
+			dojo.global = ret.global = oldGlob;
+		}
+	},
+
+	withDoc: function(	/*DocumentElement*/ documentObject,
+						/*Function*/ callback,
+						/*Object?*/ thisObject,
+						/*Array?*/ cbArguments){
+		// summary:
+		//		Invoke callback with documentObject as dojo/_base/window::doc.
+		// description:
+		//		Invoke callback with documentObject as dojo/_base/window::doc. If provided,
+		//		callback will be executed in the context of object thisObject
+		//		When callback() returns or throws an error, the dojo/_base/window::doc will
+		//		be restored to its previous state.
+
+		var oldDoc = ret.doc,
+			oldQ = has("quirks"),
+			oldIE = has("ie"), isIE, mode, pwin;
+
+		try{
+			dojo.doc = ret.doc = documentObject;
+			// update dojo.isQuirks and the value of the has feature "quirks".
+			// remove setting dojo.isQuirks and dojo.isIE for 2.0
+			dojo.isQuirks = has.add("quirks", dojo.doc.compatMode == "BackCompat", true, true); // no need to check for QuirksMode which was Opera 7 only
+
+			if(has("ie")){
+				if((pwin = documentObject.parentWindow) && pwin.navigator){
+					// re-run IE detection logic and update dojo.isIE / has("ie")
+					// (the only time parentWindow/navigator wouldn't exist is if we were not
+					// passed an actual legitimate document object)
+					isIE = parseFloat(pwin.navigator.appVersion.split("MSIE ")[1]) || undefined;
+					mode = documentObject.documentMode;
+					if(mode && mode != 5 && Math.floor(isIE) != mode){
+						isIE = mode;
+					}
+					dojo.isIE = has.add("ie", isIE, true, true);
 				}
-				dojo.isIE = has.add("ie", isIE, true, true);
 			}
-		}
 
-		if(thisObject && typeof callback == "string"){
-			callback = thisObject[callback];
-		}
+			if(thisObject && typeof callback == "string"){
+				callback = thisObject[callback];
+			}
 
-		return callback.apply(thisObject, cbArguments || []);
-	}finally{
-		dojo.doc = ret.doc = oldDoc;
-		dojo.isQuirks = has.add("quirks", oldQ, true, true);
-		dojo.isIE = has.add("ie", oldIE, true, true);
+			return callback.apply(thisObject, cbArguments || []);
+		}finally{
+			dojo.doc = ret.doc = oldDoc;
+			dojo.isQuirks = has.add("quirks", oldQ, true, true);
+			dojo.isIE = has.add("ie", oldIE, true, true);
+		}
 	}
 };
 
-var ret = {
-	global: dojo.global,
-	doc: dojo.doc,
-	body: dojo.body,
-	setContext: dojo.setContext,
-	withGlobal: dojo.withGlobal,
-	withDoc: dojo.withDoc
-};
+has("extend-dojo") && lang.mixin(dojo, ret);
 
 return ret;
 
diff --git a/dojo/_base/xhr.js b/dojo/_base/xhr.js
index 8a8a8ad..0d0db8e 100644
--- a/dojo/_base/xhr.js
+++ b/dojo/_base/xhr.js
@@ -1,47 +1,32 @@
 define([
-	"./kernel", "./sniff", "require", "../io-query", "../dom", "../dom-form", "./Deferred", "./json", "./lang", "./array", "../on"
-], function(dojo, has, require, ioq, dom, domForm, deferred, json, lang, array, on){
-	//	module:
-	//		dojo/_base.xhr
-	// summary:
-	//		This modules defines the dojo.xhr* API.
-
-	has.add("native-xhr", function() {
-		// if true, the environment has a native XHR implementation
-		return typeof XMLHttpRequest !== 'undefined';
-	});
+	"./kernel",
+	"./sniff",
+	"require",
+	"../io-query",
+	/*===== "./declare", =====*/
+	"../dom",
+	"../dom-form",
+	"./Deferred",
+	"./config",
+	"./json",
+	"./lang",
+	"./array",
+	"../on",
+	"../aspect",
+	"../request/watch",
+	"../request/xhr",
+	"../request/util"
+], function(dojo, has, require, ioq, /*===== declare, =====*/ dom, domForm, Deferred, config, json, lang, array, on, aspect, watch, _xhr, util){
+	// module:
+	//		dojo/_base/xhr
 
-	if(has("dojo-xhr-factory")){
-		dojo._xhrObj = require.getXhr;
-	}else if (has("native-xhr")){
-		dojo._xhrObj = function(){
-			// summary:
-			//		does the work of portably generating a new XMLHTTPRequest object.
-			try{
-				return new XMLHttpRequest();
-			}catch(e){
-				throw new Error("XMLHTTP not available: "+e);
-			}
-		};
-	}else{
-		// PROGIDs are in order of decreasing likelihood; this will change in time.
-		for(var XMLHTTP_PROGIDS = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progid, i = 0; i < 3;){
-			try{
-				progid = XMLHTTP_PROGIDS[i++];
-				if (new ActiveXObject(progid)) {
-					// this progid works; therefore, use it from now on
-					break;
-				}
-			}catch(e){
-				// squelch; we're just trying to find a good ActiveX PROGID
-				// if they all fail, then progid ends up as the last attempt and that will signal the error
-				// the first time the client actually tries to exec an xhr
-			}
-		}
-		dojo._xhrObj= function() {
-			return new ActiveXObject(progid);
-		};
-	}
+	/*=====
+	dojo._xhrObj = function(){
+		// summary:
+		//		does the work of portably generating a new XMLHTTPRequest object.
+	};
+	=====*/
+	dojo._xhrObj = _xhr._create;
 
 	var cfg = dojo.config;
 
@@ -62,19 +47,17 @@ define([
 	// MOW: remove dojo._contentHandlers alias in 2.0
 	var handlers = dojo._contentHandlers = dojo.contentHandlers = {
 		// summary:
-		//		A map of availble XHR transport handle types. Name matches the
+		//		A map of available XHR transport handle types. Name matches the
 		//		`handleAs` attribute passed to XHR calls.
-		//
 		// description:
-		//		A map of availble XHR transport handle types. Name matches the
+		//		A map of available XHR transport handle types. Name matches the
 		//		`handleAs` attribute passed to XHR calls. Each contentHandler is
 		//		called, passing the xhr object for manipulation. The return value
 		//		from the contentHandler will be passed to the `load` or `handle`
 		//		functions defined in the original xhr call.
-		//
 		// example:
 		//		Creating a custom content-handler:
-		//	|	dojo.contentHandlers.makeCaps = function(xhr){
+		//	|	xhr.contentHandlers.makeCaps = function(xhr){
 		//	|		return xhr.responseText.toUpperCase();
 		//	|	}
 		//	|	// and later:
@@ -85,15 +68,18 @@ define([
 		//	|	});
 
 		"text": function(xhr){
-			// summary: A contentHandler which simply returns the plaintext response data
+			// summary:
+			//		A contentHandler which simply returns the plaintext response data
 			return xhr.responseText;
 		},
 		"json": function(xhr){
-			// summary: A contentHandler which returns a JavaScript object created from the response data
+			// summary:
+			//		A contentHandler which returns a JavaScript object created from the response data
 			return json.fromJson(xhr.responseText || null);
 		},
 		"json-comment-filtered": function(xhr){
-			// summary: A contentHandler which expects comment-filtered JSON.
+			// summary:
+			//		A contentHandler which expects comment-filtered JSON.
 			// description:
 			//		A contentHandler which expects comment-filtered JSON.
 			//		the json-comment-filtered option was implemented to prevent
@@ -105,7 +91,7 @@ define([
 			//		use the standard `json` contentHandler, and prefix your "JSON" with: {}&&
 			//
 			//		use djConfig.useCommentedJson = true to turn off the notice
-			if(!dojo.config.useCommentedJson){
+			if(!config.useCommentedJson){
 				console.warn("Consider using the standard mimetype:application/json."
 					+ " json-commenting can introduce security issues. To"
 					+ " decrease the chances of hijacking, use the standard the 'json' handler and"
@@ -122,15 +108,25 @@ define([
 			return json.fromJson(value.substring(cStartIdx+2, cEndIdx));
 		},
 		"javascript": function(xhr){
-			// summary: A contentHandler which evaluates the response data, expecting it to be valid JavaScript
+			// summary:
+			//		A contentHandler which evaluates the response data, expecting it to be valid JavaScript
 
 			// FIXME: try Moz and IE specific eval variants?
 			return dojo.eval(xhr.responseText);
 		},
 		"xml": function(xhr){
-			// summary: A contentHandler returning an XML Document parsed from the response data
+			// summary:
+			//		A contentHandler returning an XML Document parsed from the response data
 			var result = xhr.responseXML;
 
+			if(result && has("dom-qsa2.1") && !result.querySelectorAll && has("dom-parser")){
+				// http://bugs.dojotoolkit.org/ticket/15631
+				// IE9 supports a CSS3 querySelectorAll implementation, but the DOM implementation 
+				// returned by IE9 xhr.responseXML does not. Manually create the XML DOM to gain 
+				// the fuller-featured implementation and avoid bugs caused by the inconsistency
+				result = new DOMParser().parseFromString(xhr.responseText, "application/xml");
+			}
+
 			if(has("ie")){
 				if((!result || !result.documentElement)){
 					//WARNING: this branch used by the xml handling in dojo.io.iframe,
@@ -147,11 +143,12 @@ define([
 						return true;
 					});
 				}
-		 }
+			}
 			return result; // DOMDocument
 		},
 		"json-comment-optional": function(xhr){
-			// summary: A contentHandler which checks the presence of comment-filtered JSON and
+			// summary:
+			//		A contentHandler which checks the presence of comment-filtered JSON and
 			//		alternates between the `json` and `json-comment-filtered` contentHandlers.
 			if(xhr.responseText && /^[^{\[]*\/\*/.test(xhr.responseText)){
 				return handlers["json-comment-filtered"](xhr);
@@ -162,194 +159,175 @@ define([
 	};
 
 	/*=====
-	dojo.__IoArgs = function(){
-		//	url: String
+
+	// kwargs function parameter definitions.   Assigning to dojo namespace rather than making them local variables
+	// because they are used by dojo/io modules too
+
+	dojo.__IoArgs = declare(null, {
+		// url: String
 		//		URL to server endpoint.
-		//	content: Object?
+		// content: Object?
 		//		Contains properties with string values. These
 		//		properties will be serialized as name1=value2 and
 		//		passed in the request.
-		//	timeout: Integer?
+		// timeout: Integer?
 		//		Milliseconds to wait for the response. If this time
 		//		passes, the then error callbacks are called.
-		//	form: DOMNode?
+		// form: DOMNode?
 		//		DOM node for a form. Used to extract the form values
 		//		and send to the server.
-		//	preventCache: Boolean?
+		// preventCache: Boolean?
 		//		Default is false. If true, then a
 		//		"dojo.preventCache" parameter is sent in the request
 		//		with a value that changes with each request
 		//		(timestamp). Useful only with GET-type requests.
-		//	handleAs: String?
+		// handleAs: String?
 		//		Acceptable values depend on the type of IO
 		//		transport (see specific IO calls for more information).
-		//	rawBody: String?
+		// rawBody: String?
 		//		Sets the raw body for an HTTP request. If this is used, then the content
 		//		property is ignored. This is mostly useful for HTTP methods that have
 		//		a body to their requests, like PUT or POST. This property can be used instead
-		//		of postData and putData for dojo.rawXhrPost and dojo.rawXhrPut respectively.
-		//	ioPublish: Boolean?
+		//		of postData and putData for dojo/_base/xhr.rawXhrPost and dojo/_base/xhr.rawXhrPut respectively.
+		// ioPublish: Boolean?
 		//		Set this explicitly to false to prevent publishing of topics related to
 		//		IO operations. Otherwise, if djConfig.ioPublish is set to true, topics
-		//		will be published via dojo.publish for different phases of an IO operation.
-		//		See dojo.__IoPublish for a list of topics that are published.
-		//	load: Function?
-		//		This function will be
-		//		called on a successful HTTP response code.
-		//	error: Function?
-		//		This function will
-		//		be called when the request fails due to a network or server error, the url
-		//		is invalid, etc. It will also be called if the load or handle callback throws an
-		//		exception, unless djConfig.debugAtAllCosts is true.	 This allows deployed applications
-		//		to continue to run even when a logic error happens in the callback, while making
-		//		it easier to troubleshoot while in debug mode.
-		//	handle: Function?
-		//		This function will
-		//		be called at the end of every request, whether or not an error occurs.
-		this.url = url;
-		this.content = content;
-		this.timeout = timeout;
-		this.form = form;
-		this.preventCache = preventCache;
-		this.handleAs = handleAs;
-		this.ioPublish = ioPublish;
-		this.load = function(response, ioArgs){
-			// ioArgs: dojo.__IoCallbackArgs
+		//		will be published via dojo/topic.publish() for different phases of an IO operation.
+		//		See dojo/main.__IoPublish for a list of topics that are published.
+
+		load: function(response, ioArgs){
+			// summary:
+			//		This function will be
+			//		called on a successful HTTP response code.
+	 		// ioArgs: dojo/main.__IoCallbackArgs
 			//		Provides additional information about the request.
 			// response: Object
 			//		The response in the format as defined with handleAs.
-		}
-		this.error = function(response, ioArgs){
-			// ioArgs: dojo.__IoCallbackArgs
+		},
+
+		error: function(response, ioArgs){
+			// summary:
+			//		This function will
+			//		be called when the request fails due to a network or server error, the url
+			//		is invalid, etc. It will also be called if the load or handle callback throws an
+			//		exception, unless djConfig.debugAtAllCosts is true.	 This allows deployed applications
+			//		to continue to run even when a logic error happens in the callback, while making
+			//		it easier to troubleshoot while in debug mode.
+			// ioArgs: dojo/main.__IoCallbackArgs
 			//		Provides additional information about the request.
 			// response: Object
 			//		The response in the format as defined with handleAs.
-		}
-		this.handle = function(loadOrError, response, ioArgs){
+		},
+
+		handle: function(loadOrError, response, ioArgs){
+			// summary:
+	 		//		This function will
+	 		//		be called at the end of every request, whether or not an error occurs.
 			// loadOrError: String
 			//		Provides a string that tells you whether this function
 			//		was called because of success (load) or failure (error).
 			// response: Object
 			//		The response in the format as defined with handleAs.
-			// ioArgs: dojo.__IoCallbackArgs
+			// ioArgs: dojo/main.__IoCallbackArgs
 			//		Provides additional information about the request.
 		}
-	}
-	=====*/
+	});
 
-	/*=====
-	dojo.__IoCallbackArgs = function(args, xhr, url, query, handleAs, id, canDelete, json){
-		//	args: Object
+	dojo.__IoCallbackArgs = declare(null, {
+		// args: Object
 		//		the original object argument to the IO call.
-		//	xhr: XMLHttpRequest
+		// xhr: XMLHttpRequest
 		//		For XMLHttpRequest calls only, the
 		//		XMLHttpRequest object that was used for the
 		//		request.
-		//	url: String
+		// url: String
 		//		The final URL used for the call. Many times it
 		//		will be different than the original args.url
 		//		value.
-		//	query: String
+		// query: String
 		//		For non-GET requests, the
 		//		name1=value1&name2=value2 parameters sent up in
 		//		the request.
-		//	handleAs: String
+		// handleAs: String
 		//		The final indicator on how the response will be
 		//		handled.
-		//	id: String
-		//		For dojo.io.script calls only, the internal
+		// id: String
+		//		For dojo/io/script calls only, the internal
 		//		script ID used for the request.
-		//	canDelete: Boolean
-		//		For dojo.io.script calls only, indicates
+		// canDelete: Boolean
+		//		For dojo/io/script calls only, indicates
 		//		whether the script tag that represents the
 		//		request can be deleted after callbacks have
 		//		been called. Used internally to know when
 		//		cleanup can happen on JSONP-type requests.
-		//	json: Object
-		//		For dojo.io.script calls only: holds the JSON
+		// json: Object
+		//		For dojo/io/script calls only: holds the JSON
 		//		response for JSONP-type requests. Used
 		//		internally to hold on to the JSON responses.
 		//		You should not need to access it directly --
 		//		the same object should be passed to the success
 		//		callbacks directly.
-		this.args = args;
-		this.xhr = xhr;
-		this.url = url;
-		this.query = query;
-		this.handleAs = handleAs;
-		this.id = id;
-		this.canDelete = canDelete;
-		this.json = json;
-	}
-	=====*/
-
+	});
 
-	/*=====
-	dojo.__IoPublish = function(){
-		//	summary:
+	dojo.__IoPublish = declare(null, {
+		// summary:
 		//		This is a list of IO topics that can be published
 		//		if djConfig.ioPublish is set to true. IO topics can be
 		//		published for any Input/Output, network operation. So,
 		//		dojo.xhr, dojo.io.script and dojo.io.iframe can all
 		//		trigger these topics to be published.
-		//	start: String
+		// start: String
 		//		"/dojo/io/start" is sent when there are no outstanding IO
 		//		requests, and a new IO request is started. No arguments
 		//		are passed with this topic.
-		//	send: String
+		// send: String
 		//		"/dojo/io/send" is sent whenever a new IO request is started.
 		//		It passes the dojo.Deferred for the request with the topic.
-		//	load: String
+		// load: String
 		//		"/dojo/io/load" is sent whenever an IO request has loaded
 		//		successfully. It passes the response and the dojo.Deferred
 		//		for the request with the topic.
-		//	error: String
+		// error: String
 		//		"/dojo/io/error" is sent whenever an IO request has errored.
 		//		It passes the error and the dojo.Deferred
 		//		for the request with the topic.
-		//	done: String
+		// done: String
 		//		"/dojo/io/done" is sent whenever an IO request has completed,
 		//		either by loading or by erroring. It passes the error and
 		//		the dojo.Deferred for the request with the topic.
-		//	stop: String
+		// stop: String
 		//		"/dojo/io/stop" is sent when all outstanding IO requests have
 		//		finished. No arguments are passed with this topic.
-		this.start = "/dojo/io/start";
-		this.send = "/dojo/io/send";
-		this.load = "/dojo/io/load";
-		this.error = "/dojo/io/error";
-		this.done = "/dojo/io/done";
-		this.stop = "/dojo/io/stop";
-	}
+	});
 	=====*/
 
 
-	dojo._ioSetArgs = function(/*dojo.__IoArgs*/args,
+	dojo._ioSetArgs = function(/*dojo/main.__IoArgs*/args,
 			/*Function*/canceller,
 			/*Function*/okHandler,
 			/*Function*/errHandler){
-		//	summary:
+		// summary:
 		//		sets up the Deferred and ioArgs property on the Deferred so it
 		//		can be used in an io call.
-		//	args:
+		// args:
 		//		The args object passed into the public io call. Recognized properties on
 		//		the args object are:
-		//	canceller:
+		// canceller:
 		//		The canceller function used for the Deferred object. The function
 		//		will receive one argument, the Deferred object that is related to the
 		//		canceller.
-		//	okHandler:
+		// okHandler:
 		//		The first OK callback to be registered with Deferred. It has the opportunity
 		//		to transform the OK response. It will receive one argument -- the Deferred
 		//		object returned from this function.
-		//	errHandler:
+		// errHandler:
 		//		The first error callback to be registered with Deferred. It has the opportunity
 		//		to do cleanup on an error. It will receive two arguments: error (the
 		//		Error object) and dfd, the Deferred object returned from this function.
 
 		var ioArgs = {args: args, url: args.url};
 
-		//Get values from form if requestd.
+		//Get values from form if requested.
 		var formObject = null;
 		if(args.form){
 			var form = dom.byId(args.form);
@@ -378,10 +356,19 @@ define([
 
 		// .. and the real work of getting the deferred in order, etc.
 		ioArgs.handleAs = args.handleAs || "text";
-		var d = new deferred(canceller);
-		d.addCallbacks(okHandler, function(error){
-			return errHandler(error, d);
+		var d = new Deferred(function(dfd){
+			dfd.canceled = true;
+			canceller && canceller(dfd);
+
+			var err = dfd.ioArgs.error;
+			if(!err){
+				err = new Error("request cancelled");
+				err.dojoType="cancel";
+				dfd.ioArgs.error = err;
+			}
+			return err;
 		});
+		d.addCallback(okHandler);
 
 		//Support specifying load, error and handle callback functions from the args.
 		//For those callbacks, the "this" object will be the args object.
@@ -406,6 +393,13 @@ define([
 			});
 		}
 
+		// Attach error handler last (not including topic publishing)
+		// to catch any errors that may have been generated from load
+		// or handle functions.
+		d.addErrback(function(error){
+			return errHandler(error, d);
+		});
+
 		//Plug in topic publishing, if dojo.publish is loaded.
 		if(cfg.ioPublish && dojo.publish && ioArgs.args.ioPublish !== false){
 			d.addCallbacks(
@@ -427,34 +421,20 @@ define([
 		d.ioArgs = ioArgs;
 
 		// FIXME: need to wire up the xhr object's abort method to something
-		// analagous in the Deferred
+		// analogous in the Deferred
 		return d;
 	};
 
-	var _deferredCancel = function(/*Deferred*/dfd){
-		// summary: canceller function for dojo._ioSetArgs call.
-
-		dfd.canceled = true;
-		var xhr = dfd.ioArgs.xhr;
-		var _at = typeof xhr.abort;
-		if(_at == "function" || _at == "object" || _at == "unknown"){
-			xhr.abort();
-		}
-		var err = dfd.ioArgs.error;
-		if(!err){
-			err = new Error("xhr cancelled");
-			err.dojoType="cancel";
-		}
-		return err;
-	};
 	var _deferredOk = function(/*Deferred*/dfd){
-		// summary: okHandler function for dojo._ioSetArgs call.
+		// summary:
+		//		okHandler function for dojo._ioSetArgs call.
 
 		var ret = handlers[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);
 		return ret === undefined ? null : ret;
 	};
 	var _deferError = function(/*Error*/error, /*Deferred*/dfd){
-		// summary: errHandler function for dojo._ioSetArgs call.
+		// summary:
+		//		errHandler function for dojo._ioSetArgs call.
 
 		if(!dfd.ioArgs.args.failOk){
 			console.error(error);
@@ -462,18 +442,7 @@ define([
 		return error;
 	};
 
-	// avoid setting a timer per request. It degrades performance on IE
-	// something fierece if we don't use unified loops.
-	var _inFlightIntvl = null;
-	var _inFlight = [];
-
-
 	//Use a separate count for knowing if we are starting/stopping io calls.
-	//Cannot use _inFlight.length since it can change at a different time than
-	//when we want to do this kind of test. We only want to decrement the count
-	//after a callback/errback has finished, since the callback/errback should be
-	//considered as part of finishing a request.
-	var _pubCount = 0;
 	var _checkPubCount = function(dfd){
 		if(_pubCount <= 0){
 			_pubCount = 0;
@@ -483,85 +452,27 @@ define([
 		}
 	};
 
-	var _watchInFlight = function(){
-		//summary:
-		//		internal method that checks each inflight XMLHttpRequest to see
-		//		if it has completed or if the timeout situation applies.
-
-		var now = (new Date()).getTime();
-		// make sure sync calls stay thread safe, if this callback is called
-		// during a sync call and this results in another sync call before the
-		// first sync call ends the browser hangs
-		if(!dojo._blockAsync){
-			// we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
-			// note: the second clause is an assigment on purpose, lint may complain
-			for(var i = 0, tif; i < _inFlight.length && (tif = _inFlight[i]); i++){
-				var dfd = tif.dfd;
-				var func = function(){
-					if(!dfd || dfd.canceled || !tif.validCheck(dfd)){
-						_inFlight.splice(i--, 1);
-						_pubCount -= 1;
-					}else if(tif.ioCheck(dfd)){
-						_inFlight.splice(i--, 1);
-						tif.resHandle(dfd);
-						_pubCount -= 1;
-					}else if(dfd.startTime){
-						//did we timeout?
-						if(dfd.startTime + (dfd.ioArgs.args.timeout || 0) < now){
-							_inFlight.splice(i--, 1);
-							var err = new Error("timeout exceeded");
-							err.dojoType = "timeout";
-							dfd.errback(err);
-							//Cancel the request so the io module can do appropriate cleanup.
-							dfd.cancel();
-							_pubCount -= 1;
-						}
-					}
-				};
-				if(dojo.config.debugAtAllCosts){
-					func.call(this);
-				}else{
-//					try{
-						func.call(this);
-	/*				}catch(e){
-						dfd.errback(e);
-					}*/
-				}
-			}
-		}
-
-		_checkPubCount(dfd);
-
-		if(!_inFlight.length){
-			clearInterval(_inFlightIntvl);
-			_inFlightIntvl = null;
-		}
-	};
+	var _pubCount = 0;
+	aspect.after(watch, "_onAction", function(){
+		_pubCount -= 1;
+	});
+	aspect.after(watch, "_onInFlight", _checkPubCount);
 
+	dojo._ioCancelAll = watch.cancelAll;
+	/*=====
 	dojo._ioCancelAll = function(){
-		//summary: Cancels all pending IO requests, regardless of IO type
-		//(xhr, script, iframe).
-		try{
-			array.forEach(_inFlight, function(i){
-				try{
-					i.dfd.cancel();
-				}catch(e){/*squelch*/}
-			});
-		}catch(e){/*squelch*/}
+		// summary:
+		//		Cancels all pending IO requests, regardless of IO type
+		//		(xhr, script, iframe).
 	};
-
-	//Automatically call cancel all io calls on unload
-	//in IE for trac issue #2357.
-	if(has("ie")){
-		on(window, "unload", dojo._ioCancelAll);
-	}
+	=====*/
 
 	dojo._ioNotifyStart = function(/*Deferred*/dfd){
 		// summary:
 		//		If dojo.publish is available, publish topics
 		//		about the start of a request queue and/or the
 		//		the beginning of request.
-		// description:
+		//
 		//		Used by IO transports. An IO transport should
 		//		call this method before making the network connection.
 		if(cfg.ioPublish && dojo.publish && dfd.ioArgs.args.ioPublish !== false){
@@ -587,49 +498,31 @@ define([
 		// resHandle: Function
 		//		Function used to process response. Gets the dfd
 		//		object as its only argument.
-		var args = dfd.ioArgs.args;
-		if(args.timeout){
-			dfd.startTime = (new Date()).getTime();
-		}
 
-		_inFlight.push({dfd: dfd, validCheck: validCheck, ioCheck: ioCheck, resHandle: resHandle});
-		if(!_inFlightIntvl){
-			_inFlightIntvl = setInterval(_watchInFlight, 50);
-		}
-		// handle sync requests
-		//A weakness: async calls in flight
-		//could have their handlers called as part of the
-		//_watchInFlight call, before the sync's callbacks
-		// are called.
-		if(args.sync){
-			_watchInFlight();
-		}
+		var args = dfd.ioArgs.options = dfd.ioArgs.args;
+		lang.mixin(dfd, {
+			response: dfd.ioArgs,
+			isValid: function(response){
+				return validCheck(dfd);
+			},
+			isReady: function(response){
+				return ioCheck(dfd);
+			},
+			handleResponse: function(response){
+				return resHandle(dfd);
+			}
+		});
+		watch(dfd);
+
+		_checkPubCount(dfd);
 	};
 
 	var _defaultContentType = "application/x-www-form-urlencoded";
 
-	var _validCheck = function(/*Deferred*/dfd){
-		return dfd.ioArgs.xhr.readyState; //boolean
-	};
-	var _ioCheck = function(/*Deferred*/dfd){
-		return 4 == dfd.ioArgs.xhr.readyState; //boolean
-	};
-	var _resHandle = function(/*Deferred*/dfd){
-		var xhr = dfd.ioArgs.xhr;
-		if(dojo._isDocumentOk(xhr)){
-			dfd.callback(dfd);
-		}else{
-			var err = new Error("Unable to load " + dfd.ioArgs.url + " status:" + xhr.status);
-			err.status = xhr.status;
-			err.responseText = xhr.responseText;
-			err.xhr = xhr;
-			dfd.errback(err);
-		}
-	};
-
 	dojo._ioAddQueryToUrl = function(/*dojo.__IoCallbackArgs*/ioArgs){
-		//summary: Adds query params discovered by the io deferred construction to the URL.
-		//Only use this for operations which are fundamentally GET-type operations.
+		// summary:
+		//		Adds query params discovered by the io deferred construction to the URL.
+		//		Only use this for operations which are fundamentally GET-type operations.
 		if(ioArgs.query.length){
 			ioArgs.url += (ioArgs.url.indexOf("?") == -1 ? "?" : "&") + ioArgs.query;
 			ioArgs.query = null;
@@ -637,61 +530,49 @@ define([
 	};
 
 	/*=====
-	dojo.declare("dojo.__XhrArgs", dojo.__IoArgs, {
-		constructor: function(){
-			//	summary:
-			//		In addition to the properties listed for the dojo._IoArgs type,
-			//		the following properties are allowed for dojo.xhr* methods.
-			//	handleAs: String?
-			//		Acceptable values are: text (default), json, json-comment-optional,
-			//		json-comment-filtered, javascript, xml. See `dojo.contentHandlers`
-			//	sync: Boolean?
-			//		false is default. Indicates whether the request should
-			//		be a synchronous (blocking) request.
-			//	headers: Object?
-			//		Additional HTTP headers to send in the request.
-			//	failOk: Boolean?
-			//		false is default. Indicates whether a request should be
-			//		allowed to fail (and therefore no console error message in
-			//		the event of a failure)
-			//	contentType: String|Boolean
-			//		"application/x-www-form-urlencoded" is default. Set to false to
-			//		prevent a Content-Type header from being sent, or to a string
-			//		to send a different Content-Type.
-			this.handleAs = handleAs;
-			this.sync = sync;
-			this.headers = headers;
-			this.failOk = failOk;
-		}
-	});
+	dojo.__XhrArgs = declare(dojo.__IoArgs, {
+		// summary:
+		//		In addition to the properties listed for the dojo._IoArgs type,
+		//		the following properties are allowed for dojo.xhr* methods.
+		// handleAs: String?
+		//		Acceptable values are: text (default), json, json-comment-optional,
+		//		json-comment-filtered, javascript, xml. See `dojo/_base/xhr.contentHandlers`
+	 	// sync: Boolean?
+		//		false is default. Indicates whether the request should
+		//		be a synchronous (blocking) request.
+		// headers: Object?
+		//		Additional HTTP headers to send in the request.
+		// failOk: Boolean?
+		//		false is default. Indicates whether a request should be
+		//		allowed to fail (and therefore no console error message in
+		//		the event of a failure)
+		// contentType: String|Boolean
+		//		"application/x-www-form-urlencoded" is default. Set to false to
+		//		prevent a Content-Type header from being sent, or to a string
+		//		to send a different Content-Type.
+	 });
 	=====*/
 
 	dojo.xhr = function(/*String*/ method, /*dojo.__XhrArgs*/ args, /*Boolean?*/ hasBody){
-		//	summary:
-		//		Sends an HTTP request with the given method.
-		//	description:
+		// summary:
+		//		Deprecated.   Use dojo/request instead.
+		// description:
 		//		Sends an HTTP request with the given method.
 		//		See also dojo.xhrGet(), xhrPost(), xhrPut() and dojo.xhrDelete() for shortcuts
 		//		for those HTTP methods. There are also methods for "raw" PUT and POST methods
 		//		via dojo.rawXhrPut() and dojo.rawXhrPost() respectively.
-		//	method:
+		// method:
 		//		HTTP method to be used, such as GET, POST, PUT, DELETE. Should be uppercase.
-		//	hasBody:
+		// hasBody:
 		//		If the request has an HTTP body, then pass true for hasBody.
 
+		var rDfd;
 		//Make the Deferred object for this xhr request.
-		var dfd = dojo._ioSetArgs(args, _deferredCancel, _deferredOk, _deferError);
+		var dfd = dojo._ioSetArgs(args, function(dfd){
+			rDfd && rDfd.cancel();
+		}, _deferredOk, _deferError);
 		var ioArgs = dfd.ioArgs;
 
-		//Pass the args to _xhrObj, to allow alternate XHR calls based specific calls, like
-		//the one used for iframe proxies.
-		var xhr = ioArgs.xhr = dojo._xhrObj(ioArgs.args);
-		//If XHR factory fails, cancel the deferred.
-		if(!xhr){
-			dfd.cancel();
-			return dfd;
-		}
-
 		//Allow for specifying the HTTP body completely.
 		if("postData" in args){
 			ioArgs.query = args.postData;
@@ -699,83 +580,96 @@ define([
 			ioArgs.query = args.putData;
 		}else if("rawBody" in args){
 			ioArgs.query = args.rawBody;
-		}else if((arguments.length > 2 && !hasBody) || "POST|PUT".indexOf(method.toUpperCase()) == -1){
+		}else if((arguments.length > 2 && !hasBody) || "POST|PUT".indexOf(method.toUpperCase()) === -1){
 			//Check for hasBody being passed. If no hasBody,
 			//then only append query string if not a POST or PUT request.
 			dojo._ioAddQueryToUrl(ioArgs);
 		}
 
-		// IE 6 is a steaming pile. It won't let you call apply() on the native function (xhr.open).
-		// workaround for IE6's apply() "issues"
-		xhr.open(method, ioArgs.url, args.sync !== true, args.user || undefined, args.password || undefined);
-		if(args.headers){
-			for(var hdr in args.headers){
-				if(hdr.toLowerCase() === "content-type" && !args.contentType){
-					args.contentType = args.headers[hdr];
-				}else if(args.headers[hdr]){
-					//Only add header if it has a value. This allows for instnace, skipping
-					//insertion of X-Requested-With by specifying empty value.
-					xhr.setRequestHeader(hdr, args.headers[hdr]);
-				}
+		var options = {
+			method: method,
+			handleAs: "text",
+			timeout: args.timeout,
+			withCredentials: args.withCredentials,
+			ioArgs: ioArgs
+		};
+
+		if(typeof args.headers !== 'undefined'){
+			options.headers = args.headers;
+		}
+		if(typeof args.contentType !== 'undefined'){
+			if(!options.headers){
+				options.headers = {};
 			}
+			options.headers['Content-Type'] = args.contentType;
 		}
-		// FIXME: is this appropriate for all content types?
-		if(args.contentType !== false){
-			xhr.setRequestHeader("Content-Type", args.contentType || _defaultContentType);
+		if(typeof ioArgs.query !== 'undefined'){
+			options.data = ioArgs.query;
 		}
-		if(!args.headers || !("X-Requested-With" in args.headers)){
-			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+		if(typeof args.sync !== 'undefined'){
+			options.sync = args.sync;
 		}
-		// FIXME: set other headers here!
+
 		dojo._ioNotifyStart(dfd);
-		if(dojo.config.debugAtAllCosts){
-			xhr.send(ioArgs.query);
-		}else{
-			try{
-				xhr.send(ioArgs.query);
-			}catch(e){
-				ioArgs.error = e;
-				dfd.cancel();
-			}
+		try{
+			rDfd = _xhr(ioArgs.url, options, true);
+		}catch(e){
+			// If XHR creation fails, dojo/request/xhr throws
+			// When this happens, cancel the deferred
+			dfd.cancel();
+			return dfd;
 		}
-		dojo._ioWatch(dfd, _validCheck, _ioCheck, _resHandle);
-		xhr = null;
-		return dfd; // dojo.Deferred
+
+		// sync ioArgs
+		dfd.ioArgs.xhr = rDfd.response.xhr;
+
+		rDfd.then(function(){
+			dfd.resolve(dfd);
+		}).otherwise(function(error){
+			ioArgs.error = error;
+			if(error.response){
+				error.status = error.response.status;
+				error.responseText = error.response.text;
+				error.xhr = error.response.xhr;
+			}
+			dfd.reject(error);
+		});
+		return dfd; // dojo/_base/Deferred
 	};
 
 	dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){
-		//	summary:
+		// summary:
 		//		Sends an HTTP GET request to the server.
-		return dojo.xhr("GET", args); // dojo.Deferred
+		return dojo.xhr("GET", args); // dojo/_base/Deferred
 	};
 
 	dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){
-		//	summary:
-		//		Sends an HTTP POST request to the server. In addtion to the properties
+		// summary:
+		//		Sends an HTTP POST request to the server. In addition to the properties
 		//		listed for the dojo.__XhrArgs type, the following property is allowed:
-		//	postData:
+		// postData:
 		//		String. Send raw data in the body of the POST request.
-		return dojo.xhr("POST", args, true); // dojo.Deferred
+		return dojo.xhr("POST", args, true); // dojo/_base/Deferred
 	};
 
 	dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){
-		//	summary:
-		//		Sends an HTTP PUT request to the server. In addtion to the properties
+		// summary:
+		//		Sends an HTTP PUT request to the server. In addition to the properties
 		//		listed for the dojo.__XhrArgs type, the following property is allowed:
-		//	putData:
+		// putData:
 		//		String. Send raw data in the body of the PUT request.
-		return dojo.xhr("PUT", args, true); // dojo.Deferred
+		return dojo.xhr("PUT", args, true); // dojo/_base/Deferred
 	};
 
 	dojo.xhrDelete = function(/*dojo.__XhrArgs*/ args){
-		//	summary:
+		// summary:
 		//		Sends an HTTP DELETE request to the server.
-		return dojo.xhr("DELETE", args); //dojo.Deferred
+		return dojo.xhr("DELETE", args); // dojo/_base/Deferred
 	};
 
 	/*
 	dojo.wrapForm = function(formNode){
-		//summary:
+		// summary:
 		//		A replacement for FormBind, but not implemented yet.
 
 		// FIXME: need to think harder about what extensions to this we might
@@ -785,14 +679,8 @@ define([
 	}
 	*/
 
-	dojo._isDocumentOk = function(http){
-		var stat = http.status || 0;
-		stat =
-			(stat >= 200 && stat < 300) || // allow any 2XX response code
-			stat == 304 ||                 // or, get it out of the cache
-			stat == 1223 ||                // or, Internet Explorer mangled the status code
-			!stat;                         // or, we're Titanium/browser chrome/chrome extension requesting a local file
-		return stat; // Boolean
+	dojo._isDocumentOk = function(x){
+		return util.checkStatus(x.status);
 	};
 
 	dojo._getText = function(url){
diff --git a/dojo/_firebug/firebug.js b/dojo/_firebug/firebug.js
index 0934498..21b164d 100644
--- a/dojo/_firebug/firebug.js
+++ b/dojo/_firebug/firebug.js
@@ -1,32 +1,42 @@
-define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_base/array", "../_base/lang", "../_base/event", "../_base/unload"], function(dojo, require) {
+define([
+	"../_base/kernel",
+	"require",
+	"../_base/html",
+	"../sniff",
+	"../_base/array",
+	"../_base/lang",
+	"../_base/event",
+	"../_base/unload"], function(dojo, require, html, has){
+
 	// module:
 	//		dojo/_firebug/firebug
 	// summary:
-
-// FIREBUG LITE
-	// summary: Firebug Lite, the baby brother to Joe Hewitt's Firebug for Mozilla Firefox
+	//		Firebug Lite, the baby brother to Joe Hewitt's Firebug for Mozilla Firefox
 	// description:
 	//		Opens a console for logging, debugging, and error messages.
 	//		Contains partial functionality to Firebug. See function list below.
-	//	NOTE:
-	//			Firebug is a Firefox extension created by Joe Hewitt (see license). You do not need Dojo to run Firebug.
-	//			Firebug Lite is included in Dojo by permission from Joe Hewitt
-	//			If you are new to Firebug, or used to the Dojo 0.4 dojo.debug, you can learn Firebug
-	//				functionality by reading the function comments below or visiting http://www.getfirebug.com/docs.html
-	//	NOTE:
+	//
+	//		NOTE:
+	//		Firebug is a Firefox extension created by Joe Hewitt (see license). You do not need Dojo to run Firebug.
+	//		Firebug Lite is included in Dojo by permission from Joe Hewitt
+	//		If you are new to Firebug, or used to the Dojo 0.4 dojo.debug, you can learn Firebug
+	//		functionality by reading the function comments below or visiting http://www.getfirebug.com/docs.html
+	//
+	//		NOTE:
 	//		To test Firebug Lite in Firefox:
-	//			FF2: set "console = null" before loading dojo and set djConfig.isDebug=true
-	//			FF3: disable Firebug and set djConfig.isDebug=true
+	//
+	//		- FF2: set "console = null" before loading dojo and set djConfig.isDebug=true
+	//		- FF3: disable Firebug and set djConfig.isDebug=true
 	//
 	// example:
 	//		Supports inline objects in object inspector window (only simple trace of dom nodes, however)
-	//		|	console.log("my object", {foo:"bar"})
+	//	|	console.log("my object", {foo:"bar"})
 	// example:
 	//		Option for console to open in popup window
-	//		|	var djConfig = {isDebug: true, popup:true };
+	//	|	var djConfig = {isDebug: true, popup:true };
 	// example:
 	//		Option for console height (ignored for popup)
-	//		|	var djConfig = {isDebug: true, debugHeight:100 }
+	//	|	var djConfig = {isDebug: true, debugHeight:100 }
 
 
 	var isNewIE = (/Trident/.test(window.navigator.userAgent));
@@ -55,14 +65,14 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 	}
 
 	if(
-		dojo.isFF ||								// Firefox has Firebug
-		dojo.isChrome ||							// Chrome 3+ has a console
-		dojo.isSafari ||							// Safari 4 has a console
+		has("ff") ||								// Firefox has Firebug
+		has("chrome") ||							// Chrome 3+ has a console
+		has("safari") ||							// Safari 4 has a console
 		isNewIE ||									// Has the new IE console
 		window.firebug ||							// Testing for mozilla firebug lite
 		(typeof console != "undefined" && console.firebug) || //The firebug console
 		dojo.config.useCustomLogger ||				// Allow custom loggers
-		dojo.isAIR									// isDebug triggers AIRInsector, not Firebug
+		has("air")									// isDebug triggers AIRInsector, not Firebug
 	){
 		return;
 	}
@@ -142,7 +152,7 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 		error: function(){
 			// summary:
 			//		Sends error arguments (object) to console, highlighted with (X) icon and yellow style
-			//			NEW: error object now displays in object inspector
+			//		NEW: error object now displays in object inspector
 			logFormatted(arguments, "error");
 		},
 
@@ -168,8 +178,6 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 		},
 
 		dirxml: function(node){
-			// summary:
-			//
 			var html = [];
 			appendNode(node, html);
 			logRow(html, "dirxml");
@@ -178,7 +186,7 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 		group: function(){
 			// summary:
 			//		collects log messages into a group, starting with this call and ending with
-			//			groupEnd(). Missing collapse functionality
+			//		groupEnd(). Missing collapse functionality
 			logRow(arguments, "group", pushGroup);
 		},
 
@@ -191,7 +199,7 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 		time: function(name){
 			// summary:
 			//		Starts timers assigned to name given in argument. Timer stops and displays on timeEnd(title);
-			//	example:
+			// example:
 			//	|	console.time("load");
 			//	|	console.time("myFunction");
 			//	|	console.timeEnd("load");
@@ -224,7 +232,7 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 			for(var i=0;i<stackAmt;i++){
 				var func = f.toString();
 				var args=[];
-				for (var a = 0; a < f.arguments.length; a++) {
+				for (var a = 0; a < f.arguments.length; a++){
 					args.push(f.arguments[a]);
 				}
 				if(f.arguments.length){
@@ -332,13 +340,12 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 			console._closeDomInspector();
 		},
 		recss: function(){
-			// http://turtle.dojotoolkit.org/~david/recss.html
 			// this is placed in dojo since the console is most likely
 			// in another window and dojo is easilly accessible
 			var i,a,s;a=document.getElementsByTagName('link');
 			for(i=0;i<a.length;i++){
 				s=a[i];
-				if(s.rel.toLowerCase().indexOf('stylesheet')>=0&&s.href) {
+				if(s.rel.toLowerCase().indexOf('stylesheet')>=0&&s.href){
 					var h=s.href.replace(/(&|%5C?)forceReload=\d+/,'');
 					s.href=h+(h.indexOf('?')>=0?'&':'?')+'forceReload='+new Date().valueOf();
 				}
@@ -466,7 +473,7 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 		if(!styleParent){
 			styleParent = _firebugDoc.getElementsByTagName("html")[0];
 		}
-		if(dojo.isIE){
+		if(has("ie")){
 			window.setTimeout(function(){ styleParent.appendChild(styleElement); }, 0);
 		}else{
 			styleParent.appendChild(styleElement);
@@ -480,6 +487,7 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 			_firebugDoc.body.appendChild(consoleFrame);
 		}
 		consoleFrame.className += " firebug";
+		consoleFrame.id = "firebug";
 		consoleFrame.style.height = containerHeight;
 		consoleFrame.style.display = (frameVisible ? "block" : "none");
 
@@ -511,7 +519,7 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 		commandLine = _firebugDoc.getElementById("firebugCommandLine");
 		addEvent(commandLine, "keydown", onCommandLineKeyDown);
 
-		addEvent(_firebugDoc, dojo.isIE || dojo.isSafari ? "keydown" : "keypress", onKeyDown);
+		addEvent(_firebugDoc, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
 
 		consoleBody = _firebugDoc.getElementById("firebugLog");
 		consoleObjectInspector = _firebugDoc.getElementById("objectLog");
@@ -1165,7 +1173,7 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 
 	//window.onerror = onError;
 
-	addEvent(document, dojo.isIE || dojo.isSafari ? "keydown" : "keypress", onKeyDown);
+	addEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
 
 	if(	(document.documentElement.getAttribute("debug") == "true")||
 		(dojo.config.isDebug)
@@ -1175,7 +1183,7 @@ define(["../_base/kernel", "require", "../_base/html", "../_base/sniff", "../_ba
 
 	dojo.addOnWindowUnload(function(){
 		// Erase the globals and event handlers I created, to prevent spurious leak warnings
-		removeEvent(document, dojo.isIE || dojo.isSafari ? "keydown" : "keypress", onKeyDown);
+		removeEvent(document, has("ie") || has("safari") ? "keydown" : "keypress", onKeyDown);
 		window.onFirebugResize = null;
 		window.console = null;
 	});
diff --git a/dojo/aspect.js b/dojo/aspect.js
index 38be8bd..391f166 100644
--- a/dojo/aspect.js
+++ b/dojo/aspect.js
@@ -1,101 +1,10 @@
 define([], function(){
 
-// TODOC: after/before/around return object
-// TODOC: after/before/around param types. 
-
-/*=====
-	dojo.aspect = {
-		// summary: provides aspect oriented programming functionality, allowing for
-		//		one to add before, around, or after advice on existing methods.
-		//
-		// example:
-		//	|	define(["dojo/aspect"], function(aspect){
-		//	|		var signal = aspect.after(targetObject, "methodName", function(someArgument){
-		//	|			this will be called when targetObject.methodName() is called, after the original function is called
-		//	|		});
-		//
-		// example:
-		//	The returned signal object can be used to cancel the advice.
-		//	|	signal.remove(); // this will stop the advice from being executed anymore
-		//	|	aspect.before(targetObject, "methodName", function(someArgument){
-		//	|		// this will be called when targetObject.methodName() is called, before the original function is called
-		//	|	 });
-		
-		after: function(target, methodName, advice, receiveArguments){
-			// summary: The "after" export of the aspect module is a function that can be used to attach
-			//		"after" advice to a method. This function will be executed after the original method
-			//		is executed. By default the function will be called with a single argument, the return
-			//		value of the original method, or the the return value of the last executed advice (if a previous one exists).
-			//		The fourth (optional) argument can be set to true to so the function receives the original
-			//		arguments (from when the original method was called) rather than the return value.
-			//		If there are multiple "after" advisors, they are executed in the order they were registered.
-			// target: Object
-			//		This is the target object
-			// methodName: String
-			//		This is the name of the method to attach to.
-			// advice: Function
-			//		This is function to be called after the original method
-			// receiveArguments: Boolean?
-			//		If this is set to true, the advice function receives the original arguments (from when the original mehtod
-			//		was called) rather than the return value of the original/previous method.
-			// returns:
-			//		A signal object that can be used to cancel the advice. If remove() is called on this signal object, it will
-			//		stop the advice function from being executed.
-		},
-		
-		before: function(target, methodName, advice){
-			// summary: The "before" export of the aspect module is a function that can be used to attach
-			//		"before" advice to a method. This function will be executed before the original method
-			//		is executed. This function will be called with the arguments used to call the method.
-			//		This function may optionally return an array as the new arguments to use to call
-			//		the original method (or the previous, next-to-execute before advice, if one exists).
-			//		If the before method doesn't return anything (returns undefined) the original arguments
-			//		will be preserved.
-			//		If there are multiple "before" advisors, they are executed in the reverse order they were registered.
-			//
-			// target: Object
-			//		This is the target object
-			// methodName: String
-			//		This is the name of the method to attach to.
-			// advice: Function
-			//		This is function to be called before the original method	 
-		},
-
-		around: function(target, methodName, advice){
-			// summary: The "around" export of the aspect module is a function that can be used to attach
-			//		"around" advice to a method. The advisor function is immediately executed when
-			//		the around() is called, is passed a single argument that is a function that can be
-			//		called to continue execution of the original method (or the next around advisor).
-			//		The advisor function should return a function, and this function will be called whenever
-			//		the method is called. It will be called with the arguments used to call the method.
-			//		Whatever this function returns will be returned as the result of the method call (unless after advise changes it).
-			//
-			// example:
-			//		If there are multiple "around" advisors, the most recent one is executed first,
-			//		which can then delegate to the next one and so on. For example:
-			//		|	around(obj, "foo", function(originalFoo){
-			//		|		return function(){
-			//		|			var start = new Date().getTime();
-			//		|			var results = originalFoo.apply(this, arguments); // call the original
-			//		|			var end = new Date().getTime();
-			//		|			console.log("foo execution took " + (end - start) + " ms");
-			//		|			return results;
-			//		|		};
-			//		|	});
-			//
-			// target: Object
-			//		This is the target object
-			// methodName: String
-			//		This is the name of the method to attach to.
-			// advice: Function
-			//		This is function to be called around the original method
-		}
-
-	};
-=====*/
+	// module:
+	//		dojo/aspect
 
 	"use strict";
-	var nextId = 0;
+	var undefined, nextId = 0;
 	function advise(dispatcher, type, advice, receiveArguments){
 		var previous = dispatcher[type];
 		var around = type == "around";
@@ -106,31 +15,38 @@ define([], function(){
 			});
 			signal = {
 				remove: function(){
-					signal.cancelled = true;
+					if(advised){
+						advised = dispatcher = advice = null;
+					}
 				},
 				advice: function(target, args){
-					return signal.cancelled ?
-						previous.advice(target, args) : // cancelled, skip to next one
-						advised.apply(target, args);	// called the advised function
+					return advised ?
+						advised.apply(target, args) :  // called the advised function
+						previous.advice(target, args); // cancelled, skip to next one
 				}
 			};
 		}else{
 			// create the remove handler
 			signal = {
 				remove: function(){
-					var previous = signal.previous;
-					var next = signal.next;
-					if(!next && !previous){
-						delete dispatcher[type];
-					}else{
-						if(previous){
-							previous.next = next;
+					if(signal.advice){
+						var previous = signal.previous;
+						var next = signal.next;
+						if(!next && !previous){
+							delete dispatcher[type];
 						}else{
-							dispatcher[type] = next;
-						}
-						if(next){
-							next.previous = previous;
+							if(previous){
+								previous.next = next;
+							}else{
+								dispatcher[type] = next;
+							}
+							if(next){
+								next.previous = previous;
+							}
 						}
+
+						// remove the advice to signal that this signal has been removed
+						dispatcher = advice = signal.advice = null;
 					}
 				},
 				id: nextId++,
@@ -141,11 +57,8 @@ define([], function(){
 		if(previous && !around){
 			if(type == "after"){
 				// add the listener to the end of the list
-				var next = previous;
-				while(next){
-					previous = next;
-					next = next.next;
-				}
+				// note that we had to change this loop a little bit to workaround a bizarre IE10 JIT bug
+				while(previous.next && (previous = previous.next)){}
 				previous.next = signal;
 				signal.previous = previous;
 			}else if(type == "before"){
@@ -181,8 +94,13 @@ define([], function(){
 					// after advice
 					var after = dispatcher.after;
 					while(after && after.id < executionId){
-						results = after.receiveArguments ? after.advice.apply(this, args) || results :
-								after.advice.call(this, results);
+						if(after.receiveArguments){
+							var newResults = after.advice.apply(this, args);
+							// change the return value only if a new value was returned
+							results = newResults === undefined ? results : newResults;
+						}else{
+							results = after.advice.call(this, results, args);
+						}
 						after = after.next;
 					}
 					return results;
@@ -199,9 +117,107 @@ define([], function(){
 			return results;
 		};
 	}
+
+	// TODOC: after/before/around return object
+
+	var after = aspect("after");
+	/*=====
+	after = function(target, methodName, advice, receiveArguments){
+		// summary:
+		//		The "after" export of the aspect module is a function that can be used to attach
+		//		"after" advice to a method. This function will be executed after the original method
+		//		is executed. By default the function will be called with a single argument, the return
+		//		value of the original method, or the the return value of the last executed advice (if a previous one exists).
+		//		The fourth (optional) argument can be set to true to so the function receives the original
+		//		arguments (from when the original method was called) rather than the return value.
+		//		If there are multiple "after" advisors, they are executed in the order they were registered.
+		// target: Object
+		//		This is the target object
+		// methodName: String
+		//		This is the name of the method to attach to.
+		// advice: Function
+		//		This is function to be called after the original method
+		// receiveArguments: Boolean?
+		//		If this is set to true, the advice function receives the original arguments (from when the original mehtod
+		//		was called) rather than the return value of the original/previous method.
+		// returns:
+		//		A signal object that can be used to cancel the advice. If remove() is called on this signal object, it will
+		//		stop the advice function from being executed.
+	};
+	=====*/
+
+	var before = aspect("before");
+	/*=====
+	before = function(target, methodName, advice){
+		// summary:
+		//		The "before" export of the aspect module is a function that can be used to attach
+		//		"before" advice to a method. This function will be executed before the original method
+		//		is executed. This function will be called with the arguments used to call the method.
+		//		This function may optionally return an array as the new arguments to use to call
+		//		the original method (or the previous, next-to-execute before advice, if one exists).
+		//		If the before method doesn't return anything (returns undefined) the original arguments
+		//		will be preserved.
+		//		If there are multiple "before" advisors, they are executed in the reverse order they were registered.
+		// target: Object
+		//		This is the target object
+		// methodName: String
+		//		This is the name of the method to attach to.
+		// advice: Function
+		//		This is function to be called before the original method
+	};
+	=====*/
+
+	var around = aspect("around");
+	/*=====
+	 around = function(target, methodName, advice){
+		// summary:
+		//		The "around" export of the aspect module is a function that can be used to attach
+		//		"around" advice to a method. The advisor function is immediately executed when
+		//		the around() is called, is passed a single argument that is a function that can be
+		//		called to continue execution of the original method (or the next around advisor).
+		//		The advisor function should return a function, and this function will be called whenever
+		//		the method is called. It will be called with the arguments used to call the method.
+		//		Whatever this function returns will be returned as the result of the method call (unless after advise changes it).
+		// example:
+		//		If there are multiple "around" advisors, the most recent one is executed first,
+		//		which can then delegate to the next one and so on. For example:
+		//		|	around(obj, "foo", function(originalFoo){
+		//		|		return function(){
+		//		|			var start = new Date().getTime();
+		//		|			var results = originalFoo.apply(this, arguments); // call the original
+		//		|			var end = new Date().getTime();
+		//		|			console.log("foo execution took " + (end - start) + " ms");
+		//		|			return results;
+		//		|		};
+		//		|	});
+		// target: Object
+		//		This is the target object
+		// methodName: String
+		//		This is the name of the method to attach to.
+		// advice: Function
+		//		This is function to be called around the original method
+	};
+	=====*/
+
 	return {
-		before: aspect("before"),
-		around: aspect("around"),
-		after: aspect("after")
+		// summary:
+		//		provides aspect oriented programming functionality, allowing for
+		//		one to add before, around, or after advice on existing methods.
+		// example:
+		//	|	define(["dojo/aspect"], function(aspect){
+		//	|		var signal = aspect.after(targetObject, "methodName", function(someArgument){
+		//	|			this will be called when targetObject.methodName() is called, after the original function is called
+		//	|		});
+		//
+		// example:
+		//	The returned signal object can be used to cancel the advice.
+		//	|	signal.remove(); // this will stop the advice from being executed anymore
+		//	|	aspect.before(targetObject, "methodName", function(someArgument){
+		//	|		// this will be called when targetObject.methodName() is called, before the original function is called
+		//	|	 });
+
+		before: before,
+		around: around,
+		after: after
 	};
 });
diff --git a/dojo/back.js b/dojo/back.js
index f4ca4f7..75a2e8d 100644
--- a/dojo/back.js
+++ b/dojo/back.js
@@ -1,25 +1,20 @@
-define(["./_base/kernel", "./_base/lang", "./_base/sniff", "./dom", "./dom-construct", "./_base/window", "require"], function(dojo, lang, sniff, dom, domConstruct, baseWindow, require) {
+define(["./_base/config", "./_base/lang", "./sniff", "./dom", "./dom-construct", "./_base/window", "require"],
+	function(config, lang, has, dom, domConstruct, baseWindow, require){
 	// module:
 	//		dojo/back
-	// summary:
-	//		TODOC
 
-	lang.getObject("back", true, dojo);
-
-/*=====
-dojo.back = {
-	// summary: Browser history management resources
-};
-=====*/
-
-	var back = dojo.back,
+	var back = {
+		// summary:
+		//		Browser history management resources
+	};
+	has("extend-dojo") && lang.setObject("dojo.back", back);
 
 	// everyone deals with encoding the hash slightly differently
 
-	getHash = back.getHash = function(){
+	var getHash = back.getHash = function(){
 		var h = window.location.hash;
 		if(h.charAt(0) == "#"){ h = h.substring(1); }
-		return sniff("mozilla") ? h : decodeURIComponent(h);
+		return has("mozilla") ? h : decodeURIComponent(h);
 	},
 
 	setHash = back.setHash = function(h){
@@ -42,7 +37,8 @@ dojo.back = {
 	var historyCounter;
 
 	function handleBackButton(){
-		//summary: private method. Do not call this directly.
+		// summary:
+		//		private method. Do not call this directly.
 
 		//The "current" page is always at the top of the history stack.
 		var current = historyStack.pop();
@@ -66,7 +62,8 @@ dojo.back = {
 	back.goBack = handleBackButton;
 
 	function handleForwardButton(){
-		//summary: private method. Do not call this directly.
+		// summary:
+		//		private method. Do not call this directly.
 		var last = forwardStack.pop();
 		if(!last){ return; }
 		if(last.kwArgs["forward"]){
@@ -82,12 +79,14 @@ dojo.back = {
 	back.goForward = handleForwardButton;
 
 	function createState(url, args, hash){
-		//summary: private method. Do not call this directly.
+		// summary:
+		//		private method. Do not call this directly.
 		return {"url": url, "kwArgs": args, "urlHash": hash};	//Object
 	}
 
 	function getUrlQuery(url){
-		//summary: private method. Do not call this directly.
+		// summary:
+		//		private method. Do not call this directly.
 		var segments = url.split("?");
 		if(segments.length < 2){
 			return null; //null
@@ -98,13 +97,14 @@ dojo.back = {
 	}
 
 	function loadIframeHistory(){
-		//summary: private method. Do not call this directly.
-		var url = (dojo.config["dojoIframeHistoryUrl"] || require.toUrl("./resources/iframe_history.html")) + "?" + (new Date()).getTime();
+		// summary:
+		//		private method. Do not call this directly.
+		var url = (config["dojoIframeHistoryUrl"] || require.toUrl("./resources/iframe_history.html")) + "?" + (new Date()).getTime();
 		moveForward = true;
 		if(historyIframe){
-			sniff("webkit") ? historyIframe.location = url : window.frames[historyIframe.name].location = url;
+			has("webkit") ? historyIframe.location = url : window.frames[historyIframe.name].location = url;
 		}else{
-			//console.warn("dojo.back: Not initialised. You need to call dojo.back.init() from a <script> block that lives inside the <body> tag.");
+			//console.warn("dojo/back: Not initialised. You need to call back.init() from a <script> block that lives inside the <body> tag.");
 		}
 		return url; //String
 	}
@@ -142,34 +142,34 @@ dojo.back = {
 	}
 
 	back.init = function(){
-		//summary: Initializes the undo stack. This must be called from a <script>
-		//		   block that lives inside the <body> tag to prevent bugs on IE.
-		// description:
+		// summary:
+		//		Initializes the undo stack. This must be called from a <script>
+		//		block that lives inside the `<body>` tag to prevent bugs on IE.
+		//
 		//		Only call this method before the page's DOM is finished loading. Otherwise
 		//		it will not work. Be careful with xdomain loading or djConfig.debugAtAllCosts scenarios,
-		//		in order for this method to work, dojo.back will need to be part of a build layer.
+		//		in order for this method to work, dojo/back will need to be part of a build layer.
 
 		// prevent reinit
 		if(dom.byId("dj_history")){ return; } 
 
-		var src = dojo.config["dojoIframeHistoryUrl"] || require.toUrl("./resources/iframe_history.html");
-		if (dojo._postLoad) {
-			console.error("dojo.back.init() must be called before the DOM has loaded. "
-						+ "If using xdomain loading or djConfig.debugAtAllCosts, include dojo.back "
-						+ "in a build layer.");
-		} else {
+		var src = config["dojoIframeHistoryUrl"] || require.toUrl("./resources/iframe_history.html");
+		if (config.afterOnLoad){
+			console.error("dojo/back::init() must be called before the DOM has loaded. "
+						+ "Include dojo/back in a build layer.");
+		}else{
 			document.write('<iframe style="border:0;width:1px;height:1px;position:absolute;visibility:hidden;bottom:0;right:0;" name="dj_history" id="dj_history" src="' + src + '"></iframe>');
 		}
 	};
 
 	back.setInitialState = function(/*Object*/args){
-		//summary:
+		// summary:
 		//		Sets the state object and back callback for the very first page
 		//		that is loaded.
-		//description:
+		//
 		//		It is recommended that you call this method as part of an event
-		//		listener that is registered via dojo.addOnLoad().
-		//args: Object
+		//		listener that is registered via dojo/ready.
+		// args: Object
 		//		See the addToHistory() function for the list of valid args properties.
 		initialState = createState(initialHref, args, initialHash);
 	};
@@ -181,27 +181,27 @@ dojo.back = {
 
 
 	/*=====
-	dojo.__backArgs = function(kwArgs){
+	var __backArgs = {
 		// back: Function?
 		//		A function to be called when this state is reached via the user
 		//		clicking the back button.
-		//	forward: Function?
+		// forward: Function?
 		//		Upon return to this state from the "back, forward" combination
 		//		of navigation steps, this function will be called. Somewhat
-		//		analgous to the semantic of an "onRedo" event handler.
-		//	changeUrl: Boolean?|String?
+		//		analogous to the semantic of an "onRedo" event handler.
+		// changeUrl: Boolean|String?
 		//		Boolean indicating whether or not to create a unique hash for
 		//		this state. If a string is passed instead, it is used as the
 		//		hash.
-	}
+	};
 	=====*/
 
-	back.addToHistory = function(/*dojo.__backArgs*/ args){
-		//	summary:
+	back.addToHistory = function(args){
+		// summary:
 		//		adds a state object (args) to the history list.
-		//	args: dojo.__backArgs
+		// args: __backArgs
 		//		The state object that will be added to the history list.
-		//	description:
+		// description:
 		//		To support getting back button notifications, the object
 		//		argument should implement a function called either "back",
 		//		"backButton", or "handle". The string "back" will be passed as
@@ -218,15 +218,15 @@ dojo.back = {
 		//		not evaluate to false, that value will be used as the fragment identifier. For example,
 		//		if changeUrl: 'page1', then the URL will look like: http://some.domain.com/path#page1
 		//
-		//		There are problems with using dojo.back with semantically-named fragment identifiers
-		//		("hash values" on an URL). In most browsers it will be hard for dojo.back to know
+		//		There are problems with using dojo/back with semantically-named fragment identifiers
+		//		("hash values" on an URL). In most browsers it will be hard for dojo/back to know
 		//		distinguish a back from a forward event in those cases. For back/forward support to
 		//		work best, the fragment ID should always be a unique value (something using new Date().getTime()
 		//		for example). If you want to detect hash changes using semantic fragment IDs, then
-		//		consider using dojo.hash instead (in Dojo 1.4+).
+		//		consider using dojo/hash instead (in Dojo 1.4+).
 		//
-		//	example:
-		//		|	dojo.back.addToHistory({
+		// example:
+		//		|	back.addToHistory({
 		//		|		back: function(){ console.log('back pressed'); },
 		//		|		forward: function(){ console.log('forward pressed'); },
 		//		|		changeUrl: true
@@ -267,8 +267,8 @@ dojo.back = {
 		var hash = null;
 		var url = null;
 		if(!historyIframe){
-			if(dojo.config["useXDomain"] && !dojo.config["dojoIframeHistoryUrl"]){
-				console.warn("dojo.back: When using cross-domain Dojo builds,"
+			if(config["useXDomain"] && !config["dojoIframeHistoryUrl"]){
+				console.warn("dojo/back: When using cross-domain Dojo builds,"
 					+ " please save iframe_history.html to your domain and set djConfig.dojoIframeHistoryUrl"
 					+ " to the path on your domain to iframe_history.html");
 			}
@@ -286,7 +286,7 @@ dojo.back = {
 			//item no matter how many times you click on the same #hash link, at least in Firefox
 			//and Safari, and there is no reliable way in those browsers to know if a #hash link
 			//has been clicked on multiple times. So making this the standard behavior in all browsers
-			//so that dojo.back's behavior is the same in all browsers.
+			//so that dojo/back's behavior is the same in all browsers.
 			if(historyStack.length == 0 && initialState.urlHash == hash){
 				initialState = createState(url, args, hash);
 				return;
@@ -296,13 +296,13 @@ dojo.back = {
 			}
 
 			changingUrl = true;
-			setTimeout(function() {
+			setTimeout(function(){
 					setHash(hash);
 					changingUrl = false;
 				}, 1);
 			bookmarkAnchor.href = hash;
 
-			if(sniff("ie")){
+			if(has("ie")){
 				url = loadIframeHistory();
 
 				var oldCB = args["back"]||args["backButton"]||args["handle"];
@@ -312,7 +312,7 @@ dojo.back = {
 				//we will need to pass the handle name to handle.
 				var tcb = function(handleName){
 					if(getHash() != ""){
-						setTimeout(function() { setHash(hash); }, 1);
+						setTimeout(function(){ setHash(hash); }, 1);
 					}
 					//Use apply to set "this" to args, and to try to avoid memory leaks.
 					oldCB.apply(this, [handleName]);
@@ -351,7 +351,7 @@ dojo.back = {
 					args.handle = tfw;
 				}
 
-			}else if(!sniff("ie")){
+			}else if(!has("ie")){
 				// start the timer
 				if(!locationTimer){
 					locationTimer = setInterval(checkLocation, 200);
@@ -366,7 +366,7 @@ dojo.back = {
 	};
 
 	back._iframeLoaded = function(evt, ifrLoc){
-		//summary:
+		// summary:
 		//		private method. Do not call this directly.
 		var query = getUrlQuery(ifrLoc.href);
 		if(query == null){
@@ -392,6 +392,6 @@ dojo.back = {
 		}
 	};
 
-	return dojo.back;
+	return back;
 	
 });
diff --git a/dojo/behavior.js b/dojo/behavior.js
index 8312408..62c46de 100644
--- a/dojo/behavior.js
+++ b/dojo/behavior.js
@@ -1,27 +1,26 @@
-define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/connect", "./query", "./ready"], function(dojo, lang, darray, connect, query, ready) {
-	// module:
-	//		dojo/behavior
-	// summary:
-	//		TODOC
+define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/connect", "./query", "./domReady"],
+function(dojo, lang, darray, connect, query, domReady){
+
+// module:
+//		dojo/behavior
 
+dojo.deprecated("dojo.behavior", "Use dojo/on with event delegation (on.selector())");
 
-dojo.behavior = new function(){
+var Behavior = function(){
 	// summary:
-	//		Utility for unobtrusive/progressive event binding, DOM traversal,
-	//		and manipulation.
-	//
+	//		Deprecated.   dojo/behavior's functionality can be achieved using event delegation using dojo/on
+	//		and on.selector().
 	// description:
-	//
 	//		A very simple, lightweight mechanism for applying code to
-	//		existing documents, based around `dojo.query` (CSS3 selectors) for node selection,
-	//		and a simple two-command API: `dojo.behavior.add()` and `dojo.behavior.apply()`;
+	//		existing documents, based around `dojo/query` (CSS3 selectors) for node selection,
+	//		and a simple two-command API: `add()` and `apply()`;
 	//
 	//		Behaviors apply to a given page, and are registered following the syntax
-	//		options described by `dojo.behavior.add` to match nodes to actions, or "behaviors".
+	//		options described by `add()` to match nodes to actions, or "behaviors".
 	//
 	//		Added behaviors are applied to the current DOM when .apply() is called,
 	//		matching only new nodes found since .apply() was last called.
-	//
+
 	function arrIn(obj, name){
 		if(!obj[name]){ obj[name] = []; }
 		return obj[name];
@@ -68,8 +67,8 @@ dojo.behavior = new function(){
 		//		If the value corresponding to the ID key is a function and not a
 		//		list, it's treated as though it was the value of "found".
 		//
-		// 		dojo.behavior.add() can be called any number of times before
-		//		the DOM is ready. `dojo.behavior.apply()` is called automatically
+		//		dojo/behavior.add() can be called any number of times before
+		//		the DOM is ready. `dojo/behavior.apply()` is called automatically
 		//		by `dojo.addOnLoad`, though can be called to re-apply previously added
 		//		behaviors anytime the DOM changes.
 		//
@@ -79,7 +78,7 @@ dojo.behavior = new function(){
 		//		Simple list of properties. "found" is special. "Found" is assumed if
 		//		no property object for a given selector, and property is a function.
 		//
-		//	|	dojo.behavior.add({
+		//	|	behavior.add({
 		//	|		"#id": {
 		//	|			"found": function(element){
 		//	|				// node match found
@@ -96,15 +95,15 @@ dojo.behavior = new function(){
 		// example:
 		//		 If property is a string, a dojo.publish will be issued on the channel:
 		//
-		//	|	dojo.behavior.add({
-		//	|		// dojo.publish() whenever class="noclick" found on anchors
+		//	|	behavior.add({
+		//	|		// topic.publish() whenever class="noclick" found on anchors
 		//	|		"a.noclick": "/got/newAnchor",
 		//	|		"div.wrapper": {
 		//	|			"onclick": "/node/wasClicked"
 		//	|		}
 		//	|	});
-		//	|	dojo.subscribe("/got/newAnchor", function(node){
-		//	|		// handle node finding when dojo.behavior.apply() is called,
+		//	|	topic.subscribe("/got/newAnchor", function(node){
+		//	|		// handle node finding when dojo/behavior.apply() is called,
 		//	|		// provided a newly matched node is found.
 		//	|	});
 		//
@@ -112,7 +111,7 @@ dojo.behavior = new function(){
 		//		Scoping can be accomplished by passing an object as a property to
 		//		a connection handle (on*):
 		//
-		//	|	dojo.behavior.add({
+		//	|	behavior.add({
 		//	|		 	"#id": {
 		//	|				// like calling dojo.hitch(foo,"bar"). execute foo.bar() in scope of foo
 		//	|				"onmouseenter": { targetObj: foo, targetFunc: "bar" },
@@ -121,9 +120,9 @@ dojo.behavior = new function(){
 		//	|	});
 		//
 		// example:
-		//		Bahaviors match on CSS3 Selectors, powered by dojo.query. Example selectors:
+		//		Behaviors match on CSS3 Selectors, powered by dojo/query. Example selectors:
 		//
-		//	|	dojo.behavior.add({
+		//	|	behavior.add({
 		//	|		// match all direct descendants
 		//	|		"#id4 > *": function(element){
 		//	|			// ...
@@ -203,7 +202,7 @@ dojo.behavior = new function(){
 		//		will be added to the nodes.
 		//
 		//		apply() is called once automatically by `dojo.addOnLoad`, so
-		//		registering behaviors with `dojo.behavior.add` before the DOM is
+		//		registering behaviors with `dojo/behavior.add()` before the DOM is
 		//		ready is acceptable, provided the dojo.behavior module is ready.
 		//
 		//		Calling appy() manually after manipulating the DOM is required
@@ -242,7 +241,9 @@ dojo.behavior = new function(){
 	};
 };
 
-ready(dojo.behavior, "apply"); // FIXME: should this use a priority? before/after parser priority?
+dojo.behavior = new Behavior();
+
+domReady( function(){ dojo.behavior.apply(); } );
 
 return dojo.behavior;
 });
diff --git a/dojo/cache.js b/dojo/cache.js
index 3f839f5..60928b7 100644
--- a/dojo/cache.js
+++ b/dojo/cache.js
@@ -1,9 +1,7 @@
-define(["./_base/kernel", "./text"], function(dojo, text){
+define(["./_base/kernel", "./text"], function(dojo){
 	// module:
 	//		dojo/cache
-	// summary:
-	//		The module defines dojo.cache by loading dojo/text.
 
-	//dojo.cache is defined in dojo/text
+	// dojo.cache is defined in dojo/text
 	return dojo.cache;
 });
diff --git a/dojo/cldr/monetary.js b/dojo/cldr/monetary.js
index d3bf17a..49551d2 100644
--- a/dojo/cldr/monetary.js
+++ b/dojo/cldr/monetary.js
@@ -1,16 +1,21 @@
-define(["../main"], function(dojo) {
-	// module:
-	//		dojo/cldr/monetary
+define(["../_base/kernel", "../_base/lang"], function(dojo, lang){
+
+// module:
+//		dojo/cldr/monetary
+
+var monetary = {
 	// summary:
 	//		TODOC
+};
+lang.setObject("dojo.cldr.monetary", monetary);
 
-dojo.getObject("cldr.monetary", true, dojo);
-
-dojo.cldr.monetary.getData = function(/*String*/code){
-// summary: A mapping of currency code to currency-specific formatting information. Returns a unique object with properties: places, round.
-// code: an [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) currency code
+monetary.getData = function(/*String*/ code){
+	// summary:
+	//		A mapping of currency code to currency-specific formatting information. Returns a unique object with properties: places, round.
+	// code:
+	//		an [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) currency code
 
-// from http://www.unicode.org/cldr/data/common/supplemental/supplementalData.xml:supplementalData/currencyData/fractions
+	// from http://www.unicode.org/cldr/data/common/supplemental/supplementalData.xml:supplementalData/currencyData/fractions
 
 	var placesData = {
 		ADP:0,AFN:0,ALL:0,AMD:0,BHD:3,BIF:0,BYR:0,CLF:0,CLP:0,
@@ -22,7 +27,7 @@ dojo.cldr.monetary.getData = function(/*String*/code){
 		XAF:0,XOF:0,XPF:0,YER:0,ZMK:0,ZWD:0
 	};
 
-	var roundingData = {CHF:5};
+	var roundingData = {};
 
 	var places = placesData[code], round = roundingData[code];
 	if(typeof places == "undefined"){ places = 2; }
@@ -31,5 +36,5 @@ dojo.cldr.monetary.getData = function(/*String*/code){
 	return {places: places, round: round}; // Object
 };
 
-return dojo.cldr.monetary;
+return monetary;
 });
diff --git a/dojo/cldr/nls/ar/buddhist.js b/dojo/cldr/nls/ar/buddhist.js
index 67b0f65..823405c 100644
--- a/dojo/cldr/nls/ar/buddhist.js
+++ b/dojo/cldr/nls/ar/buddhist.js
@@ -1,82 +1,37 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M‏/y G",
-	"dateFormatItem-yQ": "yyyy Q",
-	"dayPeriods-format-wide-pm": "م",
-	"eraNames": [
-		"التقويم البوذي"
-	],
-	"dateFormatItem-MMMEd": "E d MMM",
-	"dateFormatItem-MMdd": "dd‏/MM",
-	"dateFormatItem-MMM": "LLL",
-	"months-standAlone-narrow": [
-		"ي",
-		"ف",
-		"م",
-		"أ",
-		"و",
-		"ن",
-		"ل",
-		"غ",
-		"س",
-		"ك",
-		"ب",
-		"د"
-	],
-	"dayPeriods-format-wide-am": "ص",
-	"dateFormatItem-y": "y G",
-	"timeFormat-full": "zzzz h:mm:ss a",
-	"dateFormatItem-Ed": "E، d",
-	"dateFormatItem-yMMM": "MMM y G",
-	"days-standAlone-narrow": [
-		"ح",
-		"ن",
-		"ث",
-		"ر",
-		"خ",
-		"ج",
-		"س"
-	],
-	"eraAbbr": [
-		"التقويم البوذي"
+	"days-standAlone-short": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
 	],
-	"dateFormatItem-yyyyMM": "MM‏/y G",
-	"dateFormatItem-yyyyMMMM": "MMMM، y G",
-	"dateFormat-long": "d MMMM، y G",
-	"timeFormat-medium": "h:mm:ss a",
-	"dateFormatItem-Hm": "HH:mm",
-	"dateFormat-medium": "dd‏/MM‏/y G",
-	"dateFormatItem-yMd": "d/‏M/‏y G",
-	"dateFormatItem-yMMMM": "MMMM y G",
-	"dateFormatItem-ms": "mm:ss",
 	"quarters-standAlone-narrow": [
 		"١",
 		"٢",
 		"٣",
 		"٤"
 	],
-	"dateFormatItem-MMMMEd": "E d MMMM",
-	"dateFormatItem-MMMd": "d MMM",
-	"timeFormat-long": "z h:mm:ss a",
-	"timeFormat-short": "h:mm a",
-	"dateFormatItem-MMMMd": "d MMMM",
-	"days-format-abbr": [
-		"أحد",
-		"إثنين",
-		"ثلاثاء",
-		"أربعاء",
-		"خميس",
-		"جمعة",
-		"سبت"
-	],
-	"dateFormatItem-M": "L",
-	"dateFormatItem-yMMMd": "d MMMM y G",
-	"dateFormat-short": "d‏/M‏/y G",
-	"dateFormatItem-yMMMEd": "EEE، d MMMM y G",
-	"dateFormat-full": "EEEE، d MMMM، y G",
-	"dateFormatItem-Md": "d/‏M",
-	"dateFormatItem-yMEd": "EEE، d/‏M/‏y G",
+	"field-weekday": "اليوم",
+	"dateFormatItem-GyMMMEd": "E، d MMM، y G",
+	"dateFormatItem-MMMEd": "E، d MMM",
+	"eraNarrow": [
+		"التقويم البوذي"
+	],
+	"days-format-short": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"dateFormat-long": "d MMMM، y G",
 	"months-format-wide": [
 		"يناير",
 		"فبراير",
@@ -91,25 +46,175 @@ define(
 		"نوفمبر",
 		"ديسمبر"
 	],
-	"dateFormatItem-d": "d",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dayPeriods-format-wide-pm": "م",
+	"dateFormat-full": "EEEE، d MMMM، y G",
+	"dateFormatItem-yyyyMEd": "E، d/M/y G",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "العصر",
+	"months-standAlone-wide": [
+		"يناير",
+		"فبراير",
+		"مارس",
+		"أبريل",
+		"مايو",
+		"يونيو",
+		"يوليو",
+		"أغسطس",
+		"سبتمبر",
+		"أكتوبر",
+		"نوفمبر",
+		"ديسمبر"
+	],
+	"timeFormat-short": "h:mm a",
 	"quarters-format-wide": [
 		"الربع الأول",
 		"الربع الثاني",
 		"الربع الثالث",
 		"الربع الرابع"
 	],
-	"eraNarrow": [
+	"timeFormat-long": "h:mm:ss a z",
+	"field-year": "السنة",
+	"field-hour": "الساعات",
+	"months-format-abbr": [
+		"يناير",
+		"فبراير",
+		"مارس",
+		"أبريل",
+		"مايو",
+		"يونيو",
+		"يوليو",
+		"أغسطس",
+		"سبتمبر",
+		"أكتوبر",
+		"نوفمبر",
+		"ديسمبر"
+	],
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"field-day-relative+0": "اليوم",
+	"field-day-relative+1": "غدًا",
+	"dateFormatItem-GyMMMd": "d MMM، y G",
+	"field-day-relative+2": "بعد الغد",
+	"months-standAlone-abbr": [
+		"يناير",
+		"فبراير",
+		"مارس",
+		"أبريل",
+		"مايو",
+		"يونيو",
+		"يوليو",
+		"أغسطس",
+		"سبتمبر",
+		"أكتوبر",
+		"نوفمبر",
+		"ديسمبر"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E، d MMM، y G",
+	"days-standAlone-wide": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d MMM، y G",
+	"timeFormat-medium": "h:mm:ss a",
+	"eraAbbr": [
 		"التقويم البوذي"
 	],
+	"field-minute": "الدقائق",
+	"field-dayperiod": "ص/م",
+	"days-standAlone-abbr": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"quarters-format-narrow": [
+		"١",
+		"٢",
+		"٣",
+		"٤"
+	],
+	"field-day-relative+-1": "أمس",
+	"field-day-relative+-2": "أول أمس",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E، d/M",
+	"field-day": "يوم",
 	"days-format-wide": [
 		"الأحد",
-		"الإثنين",
+		"الاثنين",
 		"الثلاثاء",
 		"الأربعاء",
 		"الخميس",
 		"الجمعة",
 		"السبت"
-	]
+	],
+	"field-zone": "التوقيت",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"ي",
+		"ف",
+		"م",
+		"أ",
+		"و",
+		"ن",
+		"ل",
+		"غ",
+		"س",
+		"ك",
+		"ب",
+		"د"
+	],
+	"field-year-relative+-1": "السنة الماضية",
+	"field-month-relative+-1": "الشهر الماضي",
+	"days-format-abbr": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"eraNames": [
+		"التقويم البوذي"
+	],
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"field-month": "الشهر",
+	"days-standAlone-narrow": [
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
+		"س"
+	],
+	"dayPeriods-format-wide-am": "ص",
+	"dateFormat-short": "d/M/y GGGGG",
+	"field-second": "الثواني",
+	"field-month-relative+0": "هذا الشهر",
+	"field-month-relative+1": "الشهر التالي",
+	"dateFormatItem-Ed": "E، d",
+	"field-week": "الأسبوع",
+	"dateFormat-medium": "dd/MM/y G",
+	"field-year-relative+0": "هذه السنة",
+	"field-week-relative+-1": "الأسبوع الماضي",
+	"dateFormatItem-yyyyM": "M/y G",
+	"field-year-relative+1": "السنة التالية",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "هذا الأسبوع",
+	"field-week-relative+1": "الأسبوع التالي"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/coptic.js b/dojo/cldr/nls/ar/coptic.js
new file mode 100644
index 0000000..6a12b60
--- /dev/null
+++ b/dojo/cldr/nls/ar/coptic.js
@@ -0,0 +1,76 @@
+define(
+//begin v1.x content
+{
+	"field-second": "الثواني",
+	"field-year-relative+-1": "السنة الماضية",
+	"field-week": "الأسبوع",
+	"field-month-relative+-1": "الشهر الماضي",
+	"field-day-relative+-1": "أمس",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "أول أمس",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-year": "السنة",
+	"field-week-relative+0": "هذا الأسبوع",
+	"field-week-relative+1": "الأسبوع التالي",
+	"field-minute": "الدقائق",
+	"field-week-relative+-1": "الأسبوع الماضي",
+	"field-day-relative+0": "اليوم",
+	"field-hour": "الساعات",
+	"field-day-relative+1": "غدًا",
+	"field-day-relative+2": "بعد الغد",
+	"field-day": "يوم",
+	"field-month-relative+0": "هذا الشهر",
+	"field-month-relative+1": "الشهر التالي",
+	"field-dayperiod": "ص/م",
+	"field-month": "الشهر",
+	"months-format-wide": [
+		"توت",
+		"بابه",
+		"هاتور",
+		"كيهك",
+		"طوبة",
+		"أمشير",
+		"برمهات",
+		"برمودة",
+		"بشنس",
+		"بؤونة",
+		"أبيب",
+		"مسرى",
+		"نسيئ"
+	],
+	"field-era": "العصر",
+	"field-year-relative+0": "هذه السنة",
+	"field-year-relative+1": "السنة التالية",
+	"field-weekday": "اليوم",
+	"field-zone": "التوقيت"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/currency.js b/dojo/cldr/nls/ar/currency.js
index 6ea7d6b..c965aa6 100644
--- a/dojo/cldr/nls/ar/currency.js
+++ b/dojo/cldr/nls/ar/currency.js
@@ -3,13 +3,20 @@ define(
 {
 	"HKD_displayName": "دولار هونج كونج",
 	"CHF_displayName": "فرنك سويسري",
+	"JPY_symbol": "JP¥",
 	"CAD_displayName": "دولار كندي",
+	"HKD_symbol": "HK$",
 	"CNY_displayName": "يوان صيني",
+	"USD_symbol": "US$",
 	"AUD_displayName": "دولار أسترالي",
 	"JPY_displayName": "ين ياباني",
+	"CAD_symbol": "CA$",
 	"USD_displayName": "دولار أمريكي",
+	"EUR_symbol": "€",
 	"CNY_symbol": "ي.ص",
 	"GBP_displayName": "جنيه إسترليني",
+	"GBP_symbol": "£",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "يورو"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/ar/ethiopic.js b/dojo/cldr/nls/ar/ethiopic.js
new file mode 100644
index 0000000..889d361
--- /dev/null
+++ b/dojo/cldr/nls/ar/ethiopic.js
@@ -0,0 +1,46 @@
+define(
+//begin v1.x content
+{
+	"field-second": "الثواني",
+	"field-year-relative+-1": "السنة الماضية",
+	"field-week": "الأسبوع",
+	"field-month-relative+-1": "الشهر الماضي",
+	"field-day-relative+-1": "أمس",
+	"field-day-relative+-2": "أول أمس",
+	"field-year": "السنة",
+	"field-week-relative+0": "هذا الأسبوع",
+	"field-week-relative+1": "الأسبوع التالي",
+	"field-minute": "الدقائق",
+	"field-week-relative+-1": "الأسبوع الماضي",
+	"field-day-relative+0": "اليوم",
+	"field-hour": "الساعات",
+	"field-day-relative+1": "غدًا",
+	"field-day-relative+2": "بعد الغد",
+	"field-day": "يوم",
+	"field-month-relative+0": "هذا الشهر",
+	"field-month-relative+1": "الشهر التالي",
+	"field-dayperiod": "ص/م",
+	"field-month": "الشهر",
+	"months-format-wide": [
+		"مسكريم",
+		"تكمت",
+		"هدار",
+		"تهساس",
+		"تر",
+		"يكتت",
+		"مجابيت",
+		"ميازيا",
+		"جنبت",
+		"سين",
+		"هامل",
+		"نهاس",
+		"باجمن"
+	],
+	"field-era": "العصر",
+	"field-year-relative+0": "هذه السنة",
+	"field-year-relative+1": "السنة التالية",
+	"field-weekday": "اليوم",
+	"field-zone": "التوقيت"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/generic.js b/dojo/cldr/nls/ar/generic.js
new file mode 100644
index 0000000..7051b3f
--- /dev/null
+++ b/dojo/cldr/nls/ar/generic.js
@@ -0,0 +1,69 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E، d MMM، y G",
+	"field-dayperiod": "ص/م",
+	"field-minute": "الدقائق",
+	"dateFormatItem-MMMEd": "E، d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "أمس",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "أول أمس",
+	"field-weekday": "اليوم",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "العصر",
+	"field-hour": "الساعات",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E، d",
+	"field-day-relative+0": "اليوم",
+	"field-day-relative+1": "غدًا",
+	"field-day-relative+2": "بعد الغد",
+	"dateFormatItem-GyMMMd": "d MMM، y G",
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormat-long": "d MMMM، y G",
+	"field-zone": "التوقيت",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "الأسبوع الماضي",
+	"dateFormat-medium": "dd‏/MM‏/y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "هذه السنة",
+	"field-year-relative+1": "السنة التالية",
+	"field-year-relative+-1": "السنة الماضية",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-year": "السنة",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "الأسبوع",
+	"dateFormatItem-yyyyMd": "d‏/M‏/y G",
+	"dateFormatItem-yyyyMMMd": "d MMM، y G",
+	"dateFormatItem-yyyyMEd": "E، d/‏M/‏y G",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "هذا الأسبوع",
+	"field-week-relative+1": "الأسبوع التالي",
+	"field-month-relative+0": "هذا الشهر",
+	"dateFormatItem-H": "HH",
+	"field-month": "الشهر",
+	"field-month-relative+1": "الشهر التالي",
+	"dateFormatItem-M": "L",
+	"field-second": "الثواني",
+	"dateFormatItem-GyMMMEd": "E، d MMM، y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "يوم",
+	"dateFormatItem-MEd": "E، d/M",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "d‏/M‏/y GGGGG",
+	"dateFormatItem-yyyyM": "M‏/y G",
+	"dateFormat-full": "EEEE، d MMMM، y G",
+	"dateFormatItem-Md": "d/‏M",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "الشهر الماضي",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/gregorian.js b/dojo/cldr/nls/ar/gregorian.js
index 5c6eb62..356d0e4 100644
--- a/dojo/cldr/nls/ar/gregorian.js
+++ b/dojo/cldr/nls/ar/gregorian.js
@@ -1,31 +1,16 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M‏/yyyy",
-	"field-dayperiod": "ص/م",
-	"dateFormatItem-yQ": "yyyy Q",
-	"dayPeriods-format-wide-pm": "م",
-	"field-minute": "الدقائق",
-	"eraNames": [
-		"قبل الميلاد",
-		"ميلادي"
-	],
-	"dateFormatItem-MMMEd": "E d MMM",
-	"field-day-relative+-1": "أمس",
-	"field-weekday": "اليوم",
-	"dateFormatItem-yQQQ": "y QQQ",
-	"dateFormatItem-MMdd": "dd‏/MM",
-	"days-standAlone-wide": [
+	"days-standAlone-short": [
 		"الأحد",
-		"الإثنين",
+		"الاثنين",
 		"الثلاثاء",
 		"الأربعاء",
 		"الخميس",
 		"الجمعة",
 		"السبت"
 	],
-	"dateFormatItem-MMM": "LLL",
-	"months-standAlone-narrow": [
+	"months-format-narrow": [
 		"ي",
 		"ف",
 		"م",
@@ -39,18 +24,33 @@ define(
 		"ب",
 		"د"
 	],
-	"field-era": "العصر",
-	"field-hour": "الساعات",
-	"dayPeriods-format-wide-am": "ص",
-	"quarters-standAlone-abbr": [
-		"الربع الأول",
-		"الربع الثاني",
-		"الربع الثالث",
-		"الربع الرابع"
+	"quarters-standAlone-narrow": [
+		"١",
+		"٢",
+		"٣",
+		"٤"
 	],
-	"dateFormatItem-y": "y",
-	"timeFormat-full": "zzzz h:mm:ss a",
-	"months-standAlone-abbr": [
+	"field-weekday": "اليوم",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "E، d/‏M/‏y",
+	"dateFormatItem-GyMMMEd": "E، d MMM، y G",
+	"dateFormatItem-MMMEd": "E، d MMM",
+	"eraNarrow": [
+		"ق.م",
+		"م"
+	],
+	"dateFormatItem-yMM": "MM‏/y",
+	"days-format-short": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"dateFormat-long": "d MMMM، y",
+	"months-format-wide": [
 		"يناير",
 		"فبراير",
 		"مارس",
@@ -64,48 +64,41 @@ define(
 		"نوفمبر",
 		"ديسمبر"
 	],
-	"dateFormatItem-Ed": "E، d",
-	"dateFormatItem-yMMM": "MMM y",
-	"field-day-relative+0": "اليوم",
-	"field-day-relative+1": "غدًا",
-	"days-standAlone-narrow": [
-		"ح",
-		"ن",
-		"ث",
-		"ر",
-		"خ",
-		"ج",
-		"س"
-	],
-	"eraAbbr": [
-		"ق.م",
-		"م"
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "م",
+	"dateFormat-full": "EEEE، d MMMM، y",
+	"dateFormatItem-Md": "d/‏M",
+	"dateFormatItem-yMd": "d‏/M‏/y",
+	"field-era": "العصر",
+	"dateFormatItem-yM": "M‏/y",
+	"months-standAlone-wide": [
+		"يناير",
+		"فبراير",
+		"مارس",
+		"أبريل",
+		"مايو",
+		"يونيو",
+		"يوليو",
+		"أغسطس",
+		"سبتمبر",
+		"أكتوبر",
+		"نوفمبر",
+		"ديسمبر"
 	],
-	"field-day-relative+2": "بعد الغد",
-	"dateFormatItem-yyyyMM": "MM‏/yyyy",
-	"dateFormatItem-yyyyMMMM": "MMMM، y",
-	"dateFormat-long": "d MMMM، y",
-	"timeFormat-medium": "h:mm:ss a",
-	"field-zone": "التوقيت",
-	"dateFormatItem-Hm": "HH:mm",
-	"dateFormat-medium": "dd‏/MM‏/yyyy",
-	"quarters-standAlone-wide": [
+	"timeFormat-short": "h:mm a",
+	"quarters-format-wide": [
 		"الربع الأول",
 		"الربع الثاني",
 		"الربع الثالث",
 		"الربع الرابع"
 	],
-	"dateFormatItem-yMMMM": "MMMM y",
-	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yQQQQ": "QQQQ y",
+	"timeFormat-long": "h:mm:ss a z",
 	"field-year": "السنة",
-	"quarters-standAlone-narrow": [
-		"١",
-		"٢",
-		"٣",
-		"٤"
-	],
-	"field-week": "الأسبوع",
-	"months-standAlone-wide": [
+	"dateFormatItem-yMMM": "MMM y",
+	"field-hour": "الساعات",
+	"dateFormatItem-MMdd": "dd‏/MM",
+	"months-format-abbr": [
 		"يناير",
 		"فبراير",
 		"مارس",
@@ -119,17 +112,13 @@ define(
 		"نوفمبر",
 		"ديسمبر"
 	],
-	"dateFormatItem-MMMMEd": "E d MMMM",
-	"dateFormatItem-MMMd": "d MMM",
-	"quarters-format-narrow": [
-		"١",
-		"٢",
-		"٣",
-		"٤"
-	],
-	"dateFormatItem-yyQ": "Q yy",
-	"timeFormat-long": "z h:mm:ss a",
-	"months-format-abbr": [
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"field-day-relative+0": "اليوم",
+	"field-day-relative+1": "غدًا",
+	"dateFormatItem-GyMMMd": "d MMM، y G",
+	"field-day-relative+2": "بعد الغد",
+	"dateFormatItem-H": "HH",
+	"months-standAlone-abbr": [
 		"يناير",
 		"فبراير",
 		"مارس",
@@ -143,37 +132,82 @@ define(
 		"نوفمبر",
 		"ديسمبر"
 	],
-	"timeFormat-short": "h:mm a",
-	"field-month": "الشهر",
-	"dateFormatItem-MMMMd": "d MMMM",
 	"quarters-format-abbr": [
 		"الربع الأول",
 		"الربع الثاني",
 		"الربع الثالث",
 		"الربع الرابع"
 	],
-	"days-format-abbr": [
-		"أحد",
-		"إثنين",
-		"ثلاثاء",
-		"أربعاء",
-		"خميس",
-		"جمعة",
-		"سبت"
+	"quarters-standAlone-wide": [
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
+		"الربع الرابع"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
-	"days-format-narrow": [
-		"ح",
-		"ن",
-		"ث",
-		"ر",
-		"خ",
-		"ج",
-		"س"
+	"days-standAlone-wide": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
 	],
-	"field-second": "الثواني",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormatItem-Hm": "HH:mm",
+	"quarters-standAlone-abbr": [
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
+		"الربع الرابع"
+	],
+	"eraAbbr": [
+		"ق.م",
+		"م"
+	],
+	"field-minute": "الدقائق",
+	"field-dayperiod": "ص/م",
+	"days-standAlone-abbr": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"١",
+		"٢",
+		"٣",
+		"٤"
+	],
+	"field-day-relative+-1": "أمس",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-day-relative+-2": "أول أمس",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E، d/M",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-yMMMM": "MMMM y",
 	"field-day": "يوم",
-	"months-format-narrow": [
+	"days-format-wide": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"field-zone": "التوقيت",
+	"dateFormatItem-y": "y",
+	"months-standAlone-narrow": [
 		"ي",
 		"ف",
 		"م",
@@ -187,54 +221,62 @@ define(
 		"ب",
 		"د"
 	],
-	"days-standAlone-abbr": [
-		"أحد",
-		"إثنين",
-		"ثلاثاء",
-		"أربعاء",
-		"خميس",
-		"جمعة",
-		"سبت"
-	],
-	"dateFormat-short": "d‏/M‏/yyyy",
-	"dateFormatItem-yMMMEd": "EEE، d MMMM y",
-	"dateFormat-full": "EEEE، d MMMM، y",
-	"dateFormatItem-Md": "d/‏M",
-	"dateFormatItem-yMEd": "EEE، d/‏M/‏yyyy",
-	"months-format-wide": [
-		"يناير",
-		"فبراير",
-		"مارس",
-		"أبريل",
-		"مايو",
-		"يونيو",
-		"يوليو",
-		"أغسطس",
-		"سبتمبر",
-		"أكتوبر",
-		"نوفمبر",
-		"ديسمبر"
-	],
-	"dateFormatItem-d": "d",
-	"quarters-format-wide": [
-		"الربع الأول",
-		"الربع الثاني",
-		"الربع الثالث",
-		"الربع الرابع"
-	],
-	"days-format-wide": [
+	"field-year-relative+-1": "السنة الماضية",
+	"field-month-relative+-1": "الشهر الماضي",
+	"dateFormatItem-hm": "h:mm a",
+	"days-format-abbr": [
 		"الأحد",
-		"الإثنين",
+		"الاثنين",
 		"الثلاثاء",
 		"الأربعاء",
 		"الخميس",
 		"الجمعة",
 		"السبت"
 	],
-	"eraNarrow": [
-		"ق.م",
-		"م"
-	]
+	"dateFormatItem-yMMMd": "d MMM، y",
+	"eraNames": [
+		"قبل الميلاد",
+		"ميلادي"
+	],
+	"days-format-narrow": [
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
+		"س"
+	],
+	"field-month": "الشهر",
+	"days-standAlone-narrow": [
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
+		"س"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "ص",
+	"dateFormatItem-MMMMEd": "E، d MMMM",
+	"dateFormat-short": "d‏/M‏/y",
+	"field-second": "الثواني",
+	"dateFormatItem-yMMMEd": "E، d MMM، y",
+	"field-month-relative+0": "هذا الشهر",
+	"field-month-relative+1": "الشهر التالي",
+	"dateFormatItem-Ed": "E، d",
+	"field-week": "الأسبوع",
+	"dateFormat-medium": "dd‏/MM‏/y",
+	"field-year-relative+0": "هذه السنة",
+	"field-week-relative+-1": "الأسبوع الماضي",
+	"field-year-relative+1": "السنة التالية",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "هذا الأسبوع",
+	"field-week-relative+1": "الأسبوع التالي"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/hebrew.js b/dojo/cldr/nls/ar/hebrew.js
index e82dd6c..7de43bd 100644
--- a/dojo/cldr/nls/ar/hebrew.js
+++ b/dojo/cldr/nls/ar/hebrew.js
@@ -1,12 +1,38 @@
 define(
 //begin v1.x content
 {
-	"dateFormat-medium": "dd/MM/yyyy",
-	"dateFormatItem-MMMEd": "E d MMM",
-	"dateFormatItem-yMEd": "EEE، d/M/yyyy",
-	"timeFormat-full": "zzzz h:mm:ss a",
-	"dateFormatItem-Md": "d/M",
-	"months-standAlone-wide": [
+	"days-standAlone-short": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"quarters-standAlone-narrow": [
+		"١",
+		"٢",
+		"٣",
+		"٤"
+	],
+	"field-weekday": "اليوم",
+	"dateFormatItem-GyMMMEd": "E، d MMM، y G",
+	"dateFormatItem-MMMEd": "E، d MMM",
+	"eraNarrow": [
+		"ص"
+	],
+	"days-format-short": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"dateFormat-long": "d MMMM، y G",
+	"months-format-wide": [
 		"تشري",
 		"مرحشوان",
 		"كيسلو",
@@ -21,18 +47,13 @@ define(
 		"آب",
 		"أيلول"
 	],
-	"months-format-wide-leap": "آذار الثاني",
-	"days-standAlone-narrow": [
-		"ح",
-		"ن",
-		"ث",
-		"ر",
-		"خ",
-		"ج",
-		"س"
-	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
 	"dayPeriods-format-wide-pm": "م",
-	"months-standAlone-abbr": [
+	"dateFormat-full": "EEEE، d MMMM، y G",
+	"dateFormatItem-yyyyMEd": "E، d/M/y G",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "العصر",
+	"months-standAlone-wide": [
 		"تشري",
 		"مرحشوان",
 		"كيسلو",
@@ -47,18 +68,17 @@ define(
 		"آب",
 		"أيلول"
 	],
-	"dayPeriods-format-wide-am": "ص",
-	"quarters-standAlone-narrow": [
-		"١",
-		"٢",
-		"٣",
-		"٤"
+	"timeFormat-short": "h:mm a",
+	"quarters-format-wide": [
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
+		"الربع الرابع"
 	],
-	"timeFormat-medium": "h:mm:ss a",
-	"dateFormat-long": "d MMMM، y",
-	"dateFormat-short": "d/M/yyyy",
-	"dateFormatItem-yMMMEd": "EEE، d MMMM y",
-	"months-format-wide": [
+	"timeFormat-long": "h:mm:ss a z",
+	"field-year": "السنة",
+	"field-hour": "الساعات",
+	"months-format-abbr": [
 		"تشري",
 		"مرحشوان",
 		"كيسلو",
@@ -73,9 +93,12 @@ define(
 		"آب",
 		"أيلول"
 	],
-	"dateFormatItem-yM": "M/yyyy",
-	"timeFormat-short": "h:mm a",
-	"months-format-abbr": [
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"field-day-relative+0": "اليوم",
+	"field-day-relative+1": "غدًا",
+	"dateFormatItem-GyMMMd": "d MMM، y G",
+	"field-day-relative+2": "بعد الغد",
+	"months-standAlone-abbr": [
 		"تشري",
 		"مرحشوان",
 		"كيسلو",
@@ -90,35 +113,99 @@ define(
 		"آب",
 		"أيلول"
 	],
-	"timeFormat-long": "z h:mm:ss a",
-	"days-format-wide": [
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E، d MMM، y G",
+	"days-standAlone-wide": [
 		"الأحد",
-		"الإثنين",
+		"الاثنين",
 		"الثلاثاء",
 		"الأربعاء",
 		"الخميس",
 		"الجمعة",
 		"السبت"
 	],
-	"dateFormatItem-yQ": "yyyy Q",
-	"dateFormatItem-yMMM": "MMM y",
-	"quarters-format-wide": [
-		"الربع الأول",
-		"الربع الثاني",
-		"الربع الثالث",
-		"الربع الرابع"
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d MMM، y G",
+	"timeFormat-medium": "h:mm:ss a",
+	"eraAbbr": [
+		"ص"
 	],
-	"dateFormat-full": "EEEE، d MMMM، y",
+	"field-minute": "الدقائق",
+	"field-dayperiod": "ص/م",
+	"days-standAlone-abbr": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"quarters-format-narrow": [
+		"١",
+		"٢",
+		"٣",
+		"٤"
+	],
+	"field-day-relative+-1": "أمس",
+	"field-day-relative+-2": "أول أمس",
 	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E، d/M",
+	"field-day": "يوم",
+	"days-format-wide": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"field-zone": "التوقيت",
+	"dateFormatItem-y": "y G",
+	"field-year-relative+-1": "السنة الماضية",
+	"field-month-relative+-1": "الشهر الماضي",
 	"days-format-abbr": [
-		"أحد",
-		"إثنين",
-		"ثلاثاء",
-		"أربعاء",
-		"خميس",
-		"جمعة",
-		"سبت"
-	]
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"eraNames": [
+		"ص"
+	],
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"field-month": "الشهر",
+	"days-standAlone-narrow": [
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
+		"س"
+	],
+	"dayPeriods-format-wide-am": "ص",
+	"dateFormat-short": "d/M/y GGGGG",
+	"field-second": "الثواني",
+	"field-month-relative+0": "هذا الشهر",
+	"field-month-relative+1": "الشهر التالي",
+	"dateFormatItem-Ed": "E، d",
+	"field-week": "الأسبوع",
+	"dateFormat-medium": "dd/MM/y G",
+	"field-year-relative+0": "هذه السنة",
+	"field-week-relative+-1": "الأسبوع الماضي",
+	"dateFormatItem-yyyyM": "M/y G",
+	"field-year-relative+1": "السنة التالية",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"months-format-wide-leap": "آذار الثاني",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "هذا الأسبوع",
+	"field-week-relative+1": "الأسبوع التالي"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/islamic.js b/dojo/cldr/nls/ar/islamic.js
index c1b55f3..8f2f573 100644
--- a/dojo/cldr/nls/ar/islamic.js
+++ b/dojo/cldr/nls/ar/islamic.js
@@ -1,43 +1,52 @@
 define(
 //begin v1.x content
 {
-	"dateFormat-medium": "dd/MM/yyyy",
-	"dateFormatItem-MMMEd": "E d MMM",
-	"dateFormatItem-yMEd": "EEE، d/M/yyyy",
-	"eraNarrow": [
-		"هـ"
+	"days-standAlone-short": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
 	],
 	"months-format-narrow": [
-		"م",
-		"ص",
-		"ر",
-		"ر",
-		"ج",
-		"ج",
-		"ر",
-		"ش",
-		"ر",
-		"ش",
-		"ذ",
-		"ذ"
+		"١",
+		"٢",
+		"٣",
+		"٤",
+		"٥",
+		"٦",
+		"٧",
+		"٨",
+		"٩",
+		"١٠",
+		"١١",
+		"١٢"
 	],
-	"timeFormat-full": "zzzz h:mm:ss a",
-	"dateFormatItem-Md": "d/M",
-	"months-standAlone-narrow": [
-		"م",
-		"ص",
-		"ر",
-		"ر",
-		"ج",
-		"ج",
-		"ر",
-		"ش",
-		"ر",
-		"ش",
-		"ذ",
-		"ذ"
+	"quarters-standAlone-narrow": [
+		"١",
+		"٢",
+		"٣",
+		"٤"
 	],
-	"months-standAlone-wide": [
+	"field-weekday": "اليوم",
+	"dateFormatItem-GyMMMEd": "E، d MMM، y G",
+	"dateFormatItem-MMMEd": "E، d MMM",
+	"eraNarrow": [
+		"هـ"
+	],
+	"days-format-short": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"dateFormat-long": "d MMMM y G",
+	"months-format-wide": [
 		"محرم",
 		"صفر",
 		"ربيع الأول",
@@ -51,20 +60,13 @@ define(
 		"ذو القعدة",
 		"ذو الحجة"
 	],
-	"eraNames": [
-		"هـ"
-	],
-	"days-standAlone-narrow": [
-		"ح",
-		"ن",
-		"ث",
-		"ر",
-		"خ",
-		"ج",
-		"س"
-	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
 	"dayPeriods-format-wide-pm": "م",
-	"months-standAlone-abbr": [
+	"dateFormat-full": "EEEE، d MMMM y G",
+	"dateFormatItem-yyyyMEd": "E، d/M/y G",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "العصر",
+	"months-standAlone-wide": [
 		"محرم",
 		"صفر",
 		"ربيع الأول",
@@ -78,18 +80,17 @@ define(
 		"ذو القعدة",
 		"ذو الحجة"
 	],
-	"dayPeriods-format-wide-am": "ص",
-	"quarters-standAlone-narrow": [
-		"١",
-		"٢",
-		"٣",
-		"٤"
+	"timeFormat-short": "h:mm a",
+	"quarters-format-wide": [
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
+		"الربع الرابع"
 	],
-	"timeFormat-medium": "h:mm:ss a",
-	"dateFormat-long": "d MMMM، y",
-	"dateFormat-short": "d/M/yyyy",
-	"dateFormatItem-yMMMEd": "EEE، d MMMM y",
-	"months-format-wide": [
+	"timeFormat-long": "h:mm:ss a z",
+	"field-year": "السنة",
+	"field-hour": "الساعات",
+	"months-format-abbr": [
 		"محرم",
 		"صفر",
 		"ربيع الأول",
@@ -103,9 +104,12 @@ define(
 		"ذو القعدة",
 		"ذو الحجة"
 	],
-	"dateFormatItem-yM": "M/yyyy",
-	"timeFormat-short": "h:mm a",
-	"months-format-abbr": [
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"field-day-relative+0": "اليوم",
+	"field-day-relative+1": "غدًا",
+	"dateFormatItem-GyMMMd": "d MMM، y G",
+	"field-day-relative+2": "بعد الغد",
+	"months-standAlone-abbr": [
 		"محرم",
 		"صفر",
 		"ربيع الأول",
@@ -119,38 +123,112 @@ define(
 		"ذو القعدة",
 		"ذو الحجة"
 	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E، d MMM، y G",
+	"days-standAlone-wide": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d MMM، y G",
+	"timeFormat-medium": "h:mm:ss a",
 	"eraAbbr": [
 		"هـ"
 	],
-	"timeFormat-long": "z h:mm:ss a",
-	"days-format-wide": [
+	"field-minute": "الدقائق",
+	"field-dayperiod": "ص/م",
+	"days-standAlone-abbr": [
 		"الأحد",
-		"الإثنين",
+		"الاثنين",
 		"الثلاثاء",
 		"الأربعاء",
 		"الخميس",
 		"الجمعة",
 		"السبت"
 	],
-	"dateFormatItem-yQ": "yyyy Q",
-	"dateFormatItem-yMMM": "MMM y",
-	"quarters-format-wide": [
-		"الربع الأول",
-		"الربع الثاني",
-		"الربع الثالث",
-		"الربع الرابع"
+	"quarters-format-narrow": [
+		"١",
+		"٢",
+		"٣",
+		"٤"
 	],
-	"dateFormat-full": "EEEE، d MMMM، y",
+	"field-day-relative+-1": "أمس",
+	"field-day-relative+-2": "أول أمس",
 	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E، d/M",
+	"field-day": "يوم",
+	"days-format-wide": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"field-zone": "التوقيت",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"١",
+		"٢",
+		"٣",
+		"4",
+		"٥",
+		"٦",
+		"٧",
+		"٨",
+		"٩",
+		"١٠",
+		"١١",
+		"١٢"
+	],
+	"field-year-relative+-1": "السنة الماضية",
+	"field-month-relative+-1": "الشهر الماضي",
 	"days-format-abbr": [
-		"أحد",
-		"إثنين",
-		"ثلاثاء",
-		"أربعاء",
-		"خميس",
-		"جمعة",
-		"سبت"
-	]
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"eraNames": [
+		"هـ"
+	],
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"field-month": "الشهر",
+	"days-standAlone-narrow": [
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
+		"س"
+	],
+	"dayPeriods-format-wide-am": "ص",
+	"dateFormat-short": "d‏/M‏/y GGGGG",
+	"field-second": "الثواني",
+	"field-month-relative+0": "هذا الشهر",
+	"field-month-relative+1": "الشهر التالي",
+	"dateFormatItem-Ed": "E، d",
+	"field-week": "الأسبوع",
+	"dateFormat-medium": "d MMM، y G",
+	"field-year-relative+0": "هذه السنة",
+	"field-week-relative+-1": "الأسبوع الماضي",
+	"dateFormatItem-yyyyM": "M/y G",
+	"field-year-relative+1": "السنة التالية",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "هذا الأسبوع",
+	"field-week-relative+1": "الأسبوع التالي"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/japanese.js b/dojo/cldr/nls/ar/japanese.js
new file mode 100644
index 0000000..90992e9
--- /dev/null
+++ b/dojo/cldr/nls/ar/japanese.js
@@ -0,0 +1,269 @@
+define(
+//begin v1.x content
+{
+	"field-second": "الثواني",
+	"field-year-relative+-1": "السنة الماضية",
+	"field-week": "الأسبوع",
+	"field-month-relative+-1": "الشهر الماضي",
+	"field-day-relative+-1": "أمس",
+	"field-day-relative+-2": "أول أمس",
+	"field-year": "السنة",
+	"field-week-relative+0": "هذا الأسبوع",
+	"field-week-relative+1": "الأسبوع التالي",
+	"field-minute": "الدقائق",
+	"field-week-relative+-1": "الأسبوع الماضي",
+	"field-day-relative+0": "اليوم",
+	"field-hour": "الساعات",
+	"field-day-relative+1": "غدًا",
+	"field-day-relative+2": "بعد الغد",
+	"field-day": "يوم",
+	"field-month-relative+0": "هذا الشهر",
+	"field-month-relative+1": "الشهر التالي",
+	"field-dayperiod": "ص/م",
+	"field-month": "الشهر",
+	"field-era": "العصر",
+	"field-year-relative+0": "هذه السنة",
+	"field-year-relative+1": "السنة التالية",
+	"eraAbbr": [
+		"تيكا",
+		"هاكتشي",
+		"هاكهو",
+		"شتشو",
+		"تيهو",
+		"كيين",
+		"وادو",
+		"رييكي",
+		"يورو",
+		"جينكي",
+		"تمبيو",
+		"تمبيو-كامبو",
+		"تمبيو-شوهو",
+		"تمبيو-هوجي",
+		"تمفو-جينجو",
+		"جينجو-كيين",
+		"هوكي",
+		"تن-أو",
+		"إنرياكو",
+		"ديدو",
+		"كونين",
+		"تنتشو",
+		"شووا (٨٣٤–٨٤٨)‏",
+		"كاجو",
+		"نينجو",
+		"سيكو",
+		"تنان",
+		"جوجان",
+		"جينكيي",
+		"نينا",
+		"كامبيو",
+		"شوتاي",
+		"انجي",
+		"انتشو",
+		"شوهيي",
+		"تنجيو",
+		"تنرياكو",
+		"تنتوكو",
+		"أووا",
+		"كوهو",
+		"آنا",
+		"تينروكو",
+		"تن-ان",
+		"جوجن",
+		"تنجن",
+		"إيكان",
+		"كانا",
+		"اي-ان",
+		"ايسو",
+		"شورياكو (٩٩٠–٩٩٥)‏",
+		"تشوتوكو",
+		"تشوهو",
+		"كانكو",
+		"تشووا",
+		"كانين",
+		"جاين",
+		"مانجو",
+		"تشوجين",
+		"تشورياكو",
+		"تشوكيو (١٠٤٠–١٠٤٤)‏",
+		"كانتوكو",
+		"ايشو (١٠٤٦–١٠٥٣)‏",
+		"تينجي",
+		"كوهيي",
+		"جيرياكو",
+		"انكيو (١٠٦٩–١٠٧٤)‏",
+		"شوهو (١٠٧٤–١٠٧٧)‏",
+		"شورياكو (١٠٧٧–١٠٨١)‏",
+		"ايهو",
+		"أوتوكو",
+		"كانجي",
+		"كاهو",
+		"ايتشو",
+		"شوتوكو",
+		"كووا (١٠٩٩–١١٠٤)‏",
+		"تشوجي",
+		"كاشو",
+		"تنين",
+		"تن-اي",
+		"ايكيو (١١١٣–١١١٨)‏",
+		"جن-اي",
+		"هوان",
+		"تنجي",
+		"ديجي",
+		"تنشو (١١٣١–١١٣٢)‏",
+		"تشوشو",
+		"هوين",
+		"ايجي",
+		"كوجي (١١٤٢–١١٤٤)‏",
+		"تنيو",
+		"كيوان",
+		"نينبيي",
+		"كيوجو",
+		"هجين",
+		"هيجي",
+		"ايرياكو",
+		"أوهو",
+		"تشوكان",
+		"ايمان",
+		"نين-ان",
+		"كاو",
+		"شون",
+		"أنجين",
+		"جيشو",
+		"يووا",
+		"جيي",
+		"جنريوكو",
+		"بنجي",
+		"كنكيو",
+		"شوجي",
+		"كنين",
+		"جنكيو (١٢٠٤–١٢٠٦)‏",
+		"كن-اي",
+		"شوجن (١٢٠٧–١٢١١)‏",
+		"كنرياكو",
+		"كنبو (١٢١٣–١٢١٩)‏",
+		"شوكيو",
+		"جو",
+		"جيننين",
+		"كروكو",
+		"أنتيي",
+		"كنكي",
+		"جويي",
+		"تمبكو",
+		"بنرياكو",
+		"كاتيي",
+		"رياكنين",
+		"ان-أو",
+		"نينجي",
+		"كنجين",
+		"هوجي",
+		"كنتشو",
+		"كوجن",
+		"شوكا",
+		"شوجن (١٢٥٩–١٢٦٠)‏",
+		"بن-أو",
+		"كوتشو",
+		"بن-اي",
+		"كنجي",
+		"كوان",
+		"شوو (١٢٨٨–١٢٩٣)‏",
+		"اينين",
+		"شوان",
+		"كنجن",
+		"كجن",
+		"توكجي",
+		"انكي",
+		"أوتشو",
+		"شووا (١٣١٢–١٣١٧)‏",
+		"بنبو",
+		"جنو",
+		"جنكيو (١٣٢١–١٣٢٤)‏",
+		"شوتشو (١٣٢٤–١٣٢٦)‏",
+		"كريكي",
+		"جنتكو",
+		"جنكو",
+		"كمو",
+		"إنجن",
+		"كوككو",
+		"شوهي",
+		"كنتكو",
+		"بنتشو",
+		"تنجو",
+		"كورياكو",
+		"كووا (١٣٨١–١٣٨٤)‏",
+		"جنتشو",
+		"مييتكو (١٣٨٤–١٣٨٧)‏",
+		"كاكي",
+		"كو",
+		"مييتكو (١٣٩٠–١٣٩٤)‏",
+		"أويي",
+		"شوتشو (١٤٢٨–١٤٢٩)‏",
+		"ايكيو (١٤٢٩–١٤٤١)‏",
+		"ككيتسو",
+		"بن-أن",
+		"هوتكو",
+		"كيوتكو",
+		"كوشو",
+		"تشوركو",
+		"كنشو",
+		"بنشو",
+		"أونين",
+		"بنمي",
+		"تشوكيو (١٤٨٧–١٤٨٩)‏",
+		"انتكو",
+		"ميو",
+		"بنكي",
+		"ايشو (١٥٠٤–١٥٢١)‏",
+		"تييي",
+		"كيوركو",
+		"تنمن",
+		"كوجي (١٥٥٥–١٥٥٨)‏",
+		"ايركو",
+		"جنكي",
+		"تنشو (١٥٧٣–١٥٩٢)‏",
+		"بنركو",
+		"كيتشو",
+		"جنوا",
+		"كان-اي",
+		"شوهو (١٦٤٤–١٦٤٨)‏",
+		"كيان",
+		"شوو (١٦٥٢–١٦٥٥)‏",
+		"ميرياكو",
+		"منجي",
+		"كنبن",
+		"انبو",
+		"تنوا",
+		"جوكيو",
+		"جنركو",
+		"هويي",
+		"شوتكو",
+		"كيوهو",
+		"جنبن",
+		"كنبو (١٧٤١–١٧٤٤)‏",
+		"انكيو (١٧٤٤–١٧٤٨)‏",
+		"كان-ان",
+		"هورياكو",
+		"مييوا",
+		"ان-اي",
+		"تنمي",
+		"كنسي",
+		"كيووا",
+		"بنكا",
+		"بنسي",
+		"تنبو",
+		"كوكا",
+		"كاي",
+		"أنسي",
+		"من-ان",
+		"بنكيو",
+		"جنجي",
+		"كيو",
+		"ميجي",
+		"تيشو",
+		"شووا",
+		"هيسي"
+	],
+	"field-weekday": "اليوم",
+	"field-zone": "التوقيت"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/number.js b/dojo/cldr/nls/ar/number.js
index 9c1f41f..ec5ef66 100644
--- a/dojo/cldr/nls/ar/number.js
+++ b/dojo/cldr/nls/ar/number.js
@@ -1,18 +1,22 @@
 define(
 //begin v1.x content
 {
-	"group": "٬",
-	"percentSign": "٪",
-	"exponential": "اس",
-	"list": "؛",
+	"group": ",",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
 	"infinity": "∞",
 	"minusSign": "-",
-	"decimal": "٫",
-	"nan": "ليس رقم",
-	"perMille": "؉",
+	"decimal": ".",
+	"nan": "NaN",
+	"perMille": "‰",
 	"decimalFormat": "#,##0.###;#,##0.###-",
 	"currencyFormat": "¤ #,##0.00;¤ #,##0.00-",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 تريليون",
+	"decimalFormat-short": "000 ترليو"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/persian.js b/dojo/cldr/nls/ar/persian.js
new file mode 100644
index 0000000..75990a4
--- /dev/null
+++ b/dojo/cldr/nls/ar/persian.js
@@ -0,0 +1,220 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"quarters-standAlone-narrow": [
+		"١",
+		"٢",
+		"٣",
+		"٤"
+	],
+	"field-weekday": "اليوم",
+	"dateFormatItem-GyMMMEd": "E، d MMM، y G",
+	"dateFormatItem-MMMEd": "E، d MMM",
+	"eraNarrow": [
+		"ه.ش"
+	],
+	"days-format-short": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"dateFormat-long": "d MMMM، y G",
+	"months-format-wide": [
+		"فرفردن",
+		"أذربيهشت",
+		"خرداد",
+		"تار",
+		"مرداد",
+		"شهرفار",
+		"مهر",
+		"آيان",
+		"آذر",
+		"دي",
+		"بهمن",
+		"اسفندار"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dayPeriods-format-wide-pm": "م",
+	"dateFormat-full": "EEEE، d MMMM، y G",
+	"dateFormatItem-yyyyMEd": "E، d/M/y G",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "العصر",
+	"months-standAlone-wide": [
+		"فرفردن",
+		"أذربيهشت",
+		"خرداد",
+		"تار",
+		"مرداد",
+		"شهرفار",
+		"مهر",
+		"آيان",
+		"آذر",
+		"دي",
+		"بهمن",
+		"اسفندار"
+	],
+	"timeFormat-short": "h:mm a",
+	"quarters-format-wide": [
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
+		"الربع الرابع"
+	],
+	"timeFormat-long": "h:mm:ss a z",
+	"field-year": "السنة",
+	"field-hour": "الساعات",
+	"months-format-abbr": [
+		"فرفردن",
+		"أذربيهشت",
+		"خرداد",
+		"تار",
+		"مرداد",
+		"شهرفار",
+		"مهر",
+		"آيان",
+		"آذر",
+		"دي",
+		"بهمن",
+		"اسفندار"
+	],
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"field-day-relative+0": "اليوم",
+	"field-day-relative+1": "غدًا",
+	"dateFormatItem-GyMMMd": "d MMM، y G",
+	"field-day-relative+2": "بعد الغد",
+	"months-standAlone-abbr": [
+		"فرفردن",
+		"أذربيهشت",
+		"خرداد",
+		"تار",
+		"مرداد",
+		"شهرفار",
+		"مهر",
+		"آيان",
+		"آذر",
+		"دي",
+		"بهمن",
+		"اسفندار"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E، d MMM، y G",
+	"days-standAlone-wide": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d MMM، y G",
+	"timeFormat-medium": "h:mm:ss a",
+	"eraAbbr": [
+		"ه.ش"
+	],
+	"field-minute": "الدقائق",
+	"field-dayperiod": "ص/م",
+	"days-standAlone-abbr": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"quarters-format-narrow": [
+		"١",
+		"٢",
+		"٣",
+		"٤"
+	],
+	"field-day-relative+-1": "أمس",
+	"field-day-relative+-2": "أول أمس",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E، d/M",
+	"field-day": "يوم",
+	"days-format-wide": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"field-zone": "التوقيت",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"ي",
+		"ف",
+		"م",
+		"أ",
+		"و",
+		"ن",
+		"ل",
+		"غ",
+		"س",
+		"ك",
+		"ب",
+		"د"
+	],
+	"field-year-relative+-1": "السنة الماضية",
+	"field-month-relative+-1": "الشهر الماضي",
+	"days-format-abbr": [
+		"الأحد",
+		"الاثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	],
+	"eraNames": [
+		"ه.ش"
+	],
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"field-month": "الشهر",
+	"days-standAlone-narrow": [
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
+		"س"
+	],
+	"dayPeriods-format-wide-am": "ص",
+	"dateFormat-short": "d/M/y GGGGG",
+	"field-second": "الثواني",
+	"field-month-relative+0": "هذا الشهر",
+	"field-month-relative+1": "الشهر التالي",
+	"dateFormatItem-Ed": "E، d",
+	"field-week": "الأسبوع",
+	"dateFormat-medium": "dd/MM/y G",
+	"field-year-relative+0": "هذه السنة",
+	"field-week-relative+-1": "الأسبوع الماضي",
+	"dateFormatItem-yyyyM": "M/y G",
+	"field-year-relative+1": "السنة التالية",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "هذا الأسبوع",
+	"field-week-relative+1": "الأسبوع التالي"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/roc.js b/dojo/cldr/nls/ar/roc.js
new file mode 100644
index 0000000..0be4223
--- /dev/null
+++ b/dojo/cldr/nls/ar/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "الثواني",
+	"field-year-relative+-1": "السنة الماضية",
+	"field-week": "الأسبوع",
+	"field-month-relative+-1": "الشهر الماضي",
+	"field-day-relative+-1": "أمس",
+	"field-day-relative+-2": "أول أمس",
+	"field-year": "السنة",
+	"field-week-relative+0": "هذا الأسبوع",
+	"field-week-relative+1": "الأسبوع التالي",
+	"field-minute": "الدقائق",
+	"field-week-relative+-1": "الأسبوع الماضي",
+	"field-day-relative+0": "اليوم",
+	"field-hour": "الساعات",
+	"field-day-relative+1": "غدًا",
+	"field-day-relative+2": "بعد الغد",
+	"field-day": "يوم",
+	"field-month-relative+0": "هذا الشهر",
+	"field-month-relative+1": "الشهر التالي",
+	"field-dayperiod": "ص/م",
+	"field-month": "الشهر",
+	"field-era": "العصر",
+	"field-year-relative+0": "هذه السنة",
+	"field-year-relative+1": "السنة التالية",
+	"eraAbbr": [
+		"Before R.O.C.",
+		"جمهورية الصي"
+	],
+	"field-weekday": "اليوم",
+	"field-zone": "التوقيت"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/buddhist.js b/dojo/cldr/nls/buddhist.js
index d5d193a..74464ee 100644
--- a/dojo/cldr/nls/buddhist.js
+++ b/dojo/cldr/nls/buddhist.js
@@ -2,6 +2,15 @@ define({ root:
 
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
 	"months-format-narrow": [
 		"1",
 		"2",
@@ -22,49 +31,59 @@ define({ root:
 		"3",
 		"4"
 	],
-	"dateFormatItem-yQQQ": "y QQQ",
-	"dateFormatItem-yMEd": "EEE, y-M-d",
-	"dateFormatItem-MMMEd": "E MMM d",
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
 	"eraNarrow": [
 		"BE"
 	],
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
 	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
-	"dateFormat-long": "MMMM d, y G",
+	"dateFormat-long": "G y MMMM d",
 	"months-format-wide": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
 	],
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
 	"dateTimeFormat-medium": "{1} {0}",
-	"dateFormatItem-EEEd": "d EEE",
 	"dayPeriods-format-wide-pm": "PM",
-	"dateFormat-full": "EEEE, MMMM d, y G",
-	"dateFormatItem-Md": "M-d",
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"dateFormatItem-Md": "MM-dd",
 	"dayPeriods-format-abbr-am": "AM",
 	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
-	"dateFormatItem-yM": "y-M",
+	"field-era": "Era",
 	"months-standAlone-wide": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
 	],
 	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
@@ -74,39 +93,42 @@ define({ root:
 		"Q4"
 	],
 	"timeFormat-long": "HH:mm:ss z",
-	"dateFormatItem-yMMM": "y MMM",
-	"dateFormatItem-yQ": "y Q",
-	"dateTimeFormats-appendItem-Era": "{0} {1}",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
 	"months-format-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
 	],
 	"timeFormat-full": "HH:mm:ss zzzz",
 	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
 	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
 	],
 	"quarters-format-abbr": [
 		"Q1",
@@ -120,16 +142,20 @@ define({ root:
 		"Q3",
 		"Q4"
 	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -141,14 +167,16 @@ define({ root:
 	"eraAbbr": [
 		"BE"
 	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
 	"days-standAlone-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
@@ -158,23 +186,26 @@ define({ root:
 		"3",
 		"4"
 	],
+	"field-day-relative+-1": "Yesterday",
 	"dateFormatItem-h": "h a",
 	"dateTimeFormat-long": "{1} {0}",
 	"dayPeriods-format-narrow-am": "AM",
 	"dateFormatItem-MMMd": "MMM d",
-	"dateFormatItem-MEd": "E, M-d",
+	"dateFormatItem-MEd": "MM-dd, E",
 	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "Day",
 	"days-format-wide": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
+	"field-zone": "Zone",
 	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
-	"dateFormatItem-y": "y",
+	"dateFormatItem-y": "G y",
 	"months-standAlone-narrow": [
 		"1",
 		"2",
@@ -190,61 +221,70 @@ define({ root:
 		"12"
 	],
 	"dateFormatItem-hm": "h:mm a",
-	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
 	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
 	"dayPeriods-format-abbr-pm": "PM",
 	"days-format-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
 	"eraNames": [
 		"BE"
 	],
 	"days-format-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
 	],
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
 	"days-standAlone-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
 	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
 	"dayPeriods-format-wide-am": "AM",
 	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
 	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
-	"dateFormat-short": "M/d/yyyy",
-	"dateFormatItem-yMMMEd": "EEE, y MMM d",
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"field-second": "Second",
+	"dateFormatItem-Ed": "d, E",
 	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
-	"dateFormat-medium": "MMM d, y G",
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
 	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
 	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-hms": "h:mm:ss a"
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "G y MMM",
+	"dateFormatItem-yyyy": "G y"
 }
 //end v1.x content
 ,
 	"ar": true,
+	"ca": true,
+	"cs": true,
 	"da": true,
 	"de": true,
 	"el": true,
 	"en": true,
-	"en-gb": true,
 	"es": true,
 	"fi": true,
 	"fr": true,
diff --git a/dojo/cldr/nls/ca/buddhist.js b/dojo/cldr/nls/ca/buddhist.js
new file mode 100644
index 0000000..485f2b2
--- /dev/null
+++ b/dojo/cldr/nls/ca/buddhist.js
@@ -0,0 +1,254 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"dg.",
+		"dl.",
+		"dm.",
+		"dc.",
+		"dj.",
+		"dv.",
+		"ds."
+	],
+	"months-format-narrow": [
+		"G",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-weekday": "dia de la setmana",
+	"dateFormatItem-yQQQ": "QQQ y GGGGG",
+	"dateFormatItem-yMEd": "E, dd/MM/y GGGGG",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"eraNarrow": [
+		"eB"
+	],
+	"days-format-short": [
+		"dg.",
+		"dl.",
+		"dt.",
+		"dc.",
+		"dj.",
+		"dv.",
+		"ds."
+	],
+	"dateFormat-long": "d MMMM y G",
+	"months-format-wide": [
+		"de gener",
+		"de febrer",
+		"de març",
+		"d’abril",
+		"de maig",
+		"de juny",
+		"de juliol",
+		"d’agost",
+		"de setembre",
+		"d’octubre",
+		"de novembre",
+		"de desembre"
+	],
+	"dayPeriods-format-wide-pm": "p.m.",
+	"dateFormat-full": "EEEE, dd MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "era",
+	"dateFormatItem-yM": "MM/y GGGGG",
+	"months-standAlone-wide": [
+		"gener",
+		"febrer",
+		"març",
+		"abril",
+		"maig",
+		"juny",
+		"juliol",
+		"agost",
+		"setembre",
+		"octubre",
+		"novembre",
+		"desembre"
+	],
+	"timeFormat-short": "H.mm",
+	"quarters-format-wide": [
+		"1r trimestre",
+		"2n trimestre",
+		"3r trimestre",
+		"4t trimestre"
+	],
+	"dateFormatItem-yQQQQ": "QQQQ y G",
+	"timeFormat-long": "H.mm.ss z",
+	"field-year": "any",
+	"dateFormatItem-yMMM": "MMM y G",
+	"field-hour": "hora",
+	"months-format-abbr": [
+		"de gen.",
+		"de febr.",
+		"de març",
+		"d’abr.",
+		"de maig",
+		"de juny",
+		"de jul.",
+		"d’ag.",
+		"de set.",
+		"d’oct.",
+		"de nov.",
+		"de des."
+	],
+	"timeFormat-full": "H.mm.ss zzzz",
+	"field-day-relative+0": "avui",
+	"field-day-relative+1": "demà",
+	"field-day-relative+2": "demà passat",
+	"dateFormatItem-H": "HH",
+	"months-standAlone-abbr": [
+		"gen.",
+		"febr.",
+		"març",
+		"abr.",
+		"maig",
+		"juny",
+		"jul.",
+		"ag.",
+		"set.",
+		"oct.",
+		"nov.",
+		"des."
+	],
+	"quarters-format-abbr": [
+		"1T",
+		"2T",
+		"3T",
+		"4T"
+	],
+	"quarters-standAlone-wide": [
+		"1r trimestre",
+		"2n trimestre",
+		"3r trimestre",
+		"4t trimestre"
+	],
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"Diumenge",
+		"Dilluns",
+		"Dimarts",
+		"Dimecres",
+		"Dijous",
+		"Divendres",
+		"Dissabte"
+	],
+	"timeFormat-medium": "H.mm.ss",
+	"dateFormatItem-Hm": "HH:mm",
+	"quarters-standAlone-abbr": [
+		"1T",
+		"2T",
+		"3T",
+		"4T"
+	],
+	"eraAbbr": [
+		"eB"
+	],
+	"field-minute": "minut",
+	"field-dayperiod": "a.m./p.m.",
+	"days-standAlone-abbr": [
+		"dg",
+		"dl",
+		"dt",
+		"dc",
+		"dj",
+		"dv",
+		"ds"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "ahir",
+	"dateFormatItem-h": "h a",
+	"dayPeriods-format-narrow-am": "a.m.",
+	"field-day-relative+-2": "abans d'ahir",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d/M",
+	"field-day": "dia",
+	"days-format-wide": [
+		"diumenge",
+		"dilluns",
+		"dimarts",
+		"dimecres",
+		"dijous",
+		"divendres",
+		"dissabte"
+	],
+	"field-zone": "zona",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"g",
+		"f",
+		"m",
+		"a",
+		"m",
+		"j",
+		"j",
+		"a",
+		"s",
+		"o",
+		"n",
+		"d"
+	],
+	"field-year-relative+-1": "Últim any",
+	"field-month-relative+-1": "Últim mes",
+	"dateFormatItem-hm": "h:mm a",
+	"days-format-abbr": [
+		"dg.",
+		"dl.",
+		"dt.",
+		"dc.",
+		"dj.",
+		"dv.",
+		"ds."
+	],
+	"eraNames": [
+		"eB"
+	],
+	"days-format-narrow": [
+		"dg",
+		"dl",
+		"dt",
+		"dc",
+		"dj",
+		"dv",
+		"ds"
+	],
+	"field-month": "mes",
+	"days-standAlone-narrow": [
+		"dg",
+		"dl",
+		"dt",
+		"dc",
+		"dj",
+		"dv",
+		"ds"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "a.m.",
+	"dateFormat-short": "dd/MM/y GGGGG",
+	"field-second": "segon",
+	"dateFormatItem-yMMMEd": "E, d MMM y G",
+	"field-month-relative+0": "Aquest mes",
+	"field-month-relative+1": "Mes següent",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "setmana",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Aquest any",
+	"field-week-relative+-1": "Última setmana",
+	"field-year-relative+1": "Any següent",
+	"dayPeriods-format-narrow-pm": "p.m.",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-week-relative+0": "Aquesta setmana",
+	"field-week-relative+1": "Setmana següent"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ca/chinese.js b/dojo/cldr/nls/ca/chinese.js
new file mode 100644
index 0000000..3c65cab
--- /dev/null
+++ b/dojo/cldr/nls/ca/chinese.js
@@ -0,0 +1,119 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d MMM U",
+	"field-second": "segon",
+	"field-year-relative+-1": "Últim any",
+	"field-week": "setmana",
+	"field-month-relative+-1": "Últim mes",
+	"field-day-relative+-1": "ahir",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "abans d'ahir",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"months-standAlone-wide": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year": "any",
+	"field-week-relative+0": "Aquesta setmana",
+	"months-standAlone-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-week-relative+1": "Setmana següent",
+	"field-minute": "minut",
+	"field-week-relative+-1": "Última setmana",
+	"field-day-relative+0": "avui",
+	"field-hour": "hora",
+	"field-day-relative+1": "demà",
+	"dateFormat-long": "d MMMM U",
+	"field-day-relative+2": "demà passat",
+	"field-day": "dia",
+	"field-month-relative+0": "Aquest mes",
+	"field-month-relative+1": "Mes següent",
+	"field-dayperiod": "a.m./p.m.",
+	"field-month": "mes",
+	"dateFormat-short": "d/M/y",
+	"months-format-wide": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-era": "era",
+	"field-year-relative+0": "Aquest any",
+	"field-year-relative+1": "Any següent",
+	"months-format-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormat-full": "EEEE, dd MMMM UU",
+	"field-weekday": "dia de la setmana",
+	"field-zone": "zona"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ca/currency.js b/dojo/cldr/nls/ca/currency.js
index bfce5de..660aa71 100644
--- a/dojo/cldr/nls/ca/currency.js
+++ b/dojo/cldr/nls/ca/currency.js
@@ -3,12 +3,20 @@ define(
 {
 	"HKD_displayName": "dòlar de Hong Kong",
 	"CHF_displayName": "franc suís",
+	"JPY_symbol": "JP¥",
 	"CAD_displayName": "dòlar canadenc",
+	"HKD_symbol": "HK$",
 	"CNY_displayName": "iuan renmimbi xinès",
+	"USD_symbol": "US$",
 	"AUD_displayName": "dòlar australià",
 	"JPY_displayName": "ien japonès",
+	"CAD_symbol": "CA$",
 	"USD_displayName": "dòlar dels Estats Units",
+	"EUR_symbol": "€",
+	"CNY_symbol": "¥",
 	"GBP_displayName": "lliura esterlina britànica",
+	"GBP_symbol": "£",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/ca/generic.js b/dojo/cldr/nls/ca/generic.js
new file mode 100644
index 0000000..080ae62
--- /dev/null
+++ b/dojo/cldr/nls/ca/generic.js
@@ -0,0 +1,68 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M/y",
+	"field-dayperiod": "a.m./p.m.",
+	"field-minute": "minut",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "ahir",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"field-day-relative+-2": "abans d'ahir",
+	"field-weekday": "dia de la setmana",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "era",
+	"field-hour": "hora",
+	"dateFormatItem-y": "y",
+	"dateFormatItem-yMM": "MM/y",
+	"dateFormatItem-Ed": "E d",
+	"dateFormatItem-yMMM": "LLL y",
+	"field-day-relative+0": "avui",
+	"field-day-relative+1": "demà",
+	"field-day-relative+2": "demà passat",
+	"dateFormat-long": "d MMMM 'de' y G",
+	"field-zone": "zona",
+	"dateFormatItem-Hm": "H.mm",
+	"field-week-relative+-1": "Última setmana",
+	"dateFormat-medium": "dd/MM/y G",
+	"dateFormatItem-Hms": "H.mm.ss",
+	"field-year-relative+0": "Aquest any",
+	"field-year-relative+1": "Any següent",
+	"dateFormatItem-yMd": "d/M/y",
+	"field-year-relative+-1": "Últim any",
+	"dateFormatItem-yMMMM": "LLLL 'de' y",
+	"dateFormatItem-ms": "mm.ss",
+	"field-year": "any",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "setmana",
+	"dateFormatItem-MMMMEd": "E d MMMM",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Aquesta setmana",
+	"field-week-relative+1": "Setmana següent",
+	"dateFormatItem-yQQQQ": "QQQQ y",
+	"field-month-relative+0": "Aquest mes",
+	"dateFormatItem-H": "H",
+	"field-month": "mes",
+	"field-month-relative+1": "Mes següent",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateFormatItem-M": "L",
+	"dateFormatItem-yMMMd": "d MMM y",
+	"field-second": "segon",
+	"field-day": "dia",
+	"dateFormatItem-MEd": "E d/M",
+	"dateFormatItem-hm": "h.mm a",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yMMMEd": "E, d MMM, y",
+	"dateFormat-full": "EEEE d MMMM 'de' y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMEd": "E, d.M.y",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Últim mes",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ca/gregorian.js b/dojo/cldr/nls/ca/gregorian.js
index c84fc3a..2fa735e 100644
--- a/dojo/cldr/nls/ca/gregorian.js
+++ b/dojo/cldr/nls/ca/gregorian.js
@@ -1,28 +1,53 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"dg.",
+		"dl.",
+		"dm.",
+		"dc.",
+		"dj.",
+		"dv.",
+		"ds."
+	],
 	"months-format-narrow": [
-		"g",
-		"f",
-		"m",
-		"a",
-		"m",
-		"j",
-		"j",
-		"a",
-		"s",
-		"o",
-		"n",
-		"d"
+		"G",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
 	],
 	"field-weekday": "dia de la setmana",
 	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "E d/M/yyyy",
+	"dateFormatItem-yMEd": "E, d.M.y",
 	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
 		"aC",
 		"dC"
 	],
+	"dateFormatItem-yMM": "MM/y",
+	"days-format-short": [
+		"dg.",
+		"dl.",
+		"dt.",
+		"dc.",
+		"dj.",
+		"dv.",
+		"ds."
+	],
 	"dateFormat-long": "d MMMM 'de' y",
 	"months-format-wide": [
 		"de gener",
@@ -38,12 +63,13 @@ define(
 		"de novembre",
 		"de desembre"
 	],
-	"dateFormatItem-EEEd": "EEE d",
+	"dateTimeFormat-medium": "{1} {0}",
 	"dayPeriods-format-wide-pm": "p.m.",
 	"dateFormat-full": "EEEE d MMMM 'de' y",
 	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMd": "d/M/y",
 	"field-era": "era",
-	"dateFormatItem-yM": "M/yyyy",
+	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
 		"gener",
 		"febrer",
@@ -58,17 +84,17 @@ define(
 		"novembre",
 		"desembre"
 	],
-	"timeFormat-short": "H:mm",
+	"timeFormat-short": "H.mm",
 	"quarters-format-wide": [
 		"1r trimestre",
 		"2n trimestre",
 		"3r trimestre",
 		"4t trimestre"
 	],
-	"timeFormat-long": "H:mm:ss z",
+	"dateFormatItem-yQQQQ": "QQQQ y",
+	"timeFormat-long": "H.mm.ss z",
 	"field-year": "any",
 	"dateFormatItem-yMMM": "LLL y",
-	"dateFormatItem-yQ": "Q yyyy",
 	"field-hour": "hora",
 	"months-format-abbr": [
 		"de gen.",
@@ -84,13 +110,11 @@ define(
 		"de nov.",
 		"de des."
 	],
-	"dateFormatItem-yyQ": "Q yy",
-	"timeFormat-full": "H:mm:ss zzzz",
+	"timeFormat-full": "H.mm.ss zzzz",
 	"field-day-relative+0": "avui",
 	"field-day-relative+1": "demà",
 	"field-day-relative+2": "demà passat",
 	"dateFormatItem-H": "H",
-	"field-day-relative+3": "d'aquí a tres dies",
 	"months-standAlone-abbr": [
 		"gen.",
 		"febr.",
@@ -119,17 +143,17 @@ define(
 	],
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"diumenge",
-		"dilluns",
-		"dimarts",
-		"dimecres",
-		"dijous",
-		"divendres",
-		"dissabte"
+		"Diumenge",
+		"Dilluns",
+		"Dimarts",
+		"Dimecres",
+		"Dijous",
+		"Divendres",
+		"Dissabte"
 	],
 	"dateFormatItem-MMMMd": "d MMMM",
-	"timeFormat-medium": "H:mm:ss",
-	"dateFormatItem-Hm": "H:mm",
+	"timeFormat-medium": "H.mm.ss",
+	"dateFormatItem-Hm": "H.mm",
 	"quarters-standAlone-abbr": [
 		"1T",
 		"2T",
@@ -152,13 +176,22 @@ define(
 		"ds"
 	],
 	"dateFormatItem-d": "d",
-	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-ms": "mm.ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "ahir",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "a.m.",
 	"field-day-relative+-2": "abans d'ahir",
-	"field-day-relative+-3": "fa tres dies",
 	"dateFormatItem-MMMd": "d MMM",
 	"dateFormatItem-MEd": "E d/M",
-	"dateFormatItem-yMMMM": "LLLL 'del' y",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-yMMMM": "LLLL 'de' y",
 	"field-day": "dia",
 	"days-format-wide": [
 		"diumenge",
@@ -170,7 +203,6 @@ define(
 		"dissabte"
 	],
 	"field-zone": "zona",
-	"dateFormatItem-yyyyMM": "MM/yyyy",
 	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
 		"g",
@@ -186,7 +218,9 @@ define(
 		"n",
 		"d"
 	],
-	"dateFormatItem-hm": "h:mm a",
+	"field-year-relative+-1": "Últim any",
+	"field-month-relative+-1": "Últim mes",
+	"dateFormatItem-hm": "h.mm a",
 	"days-format-abbr": [
 		"dg.",
 		"dl.",
@@ -196,40 +230,51 @@ define(
 		"dv.",
 		"ds."
 	],
+	"dateFormatItem-yMMMd": "d MMM y",
 	"eraNames": [
-		"aC",
-		"dC"
+		"abans de Crist",
+		"després de Crist"
 	],
 	"days-format-narrow": [
-		"g",
-		"l",
-		"t",
-		"c",
-		"j",
-		"v",
-		"s"
+		"dg",
+		"dl",
+		"dt",
+		"dc",
+		"dj",
+		"dv",
+		"ds"
 	],
-	"field-month": "mes",
 	"days-standAlone-narrow": [
-		"g",
-		"l",
-		"t",
-		"c",
-		"j",
-		"v",
-		"s"
+		"dg",
+		"dl",
+		"dt",
+		"dc",
+		"dj",
+		"dv",
+		"ds"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "mes",
 	"dayPeriods-format-wide-am": "a.m.",
 	"dateFormatItem-MMMMEd": "E d MMMM",
 	"dateFormat-short": "dd/MM/yy",
 	"field-second": "segon",
-	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"dateFormatItem-yMMMEd": "E, d MMM, y",
+	"field-month-relative+0": "Aquest mes",
+	"field-month-relative+1": "Mes següent",
+	"dateFormatItem-Ed": "E d",
 	"field-week": "setmana",
-	"dateFormat-medium": "dd/MM/yyyy",
+	"dateFormat-medium": "dd/MM/y",
+	"field-year-relative+0": "Aquest any",
+	"field-week-relative+-1": "Última setmana",
+	"field-year-relative+1": "Any següent",
 	"dateFormatItem-mmss": "mm:ss",
-	"dateFormatItem-Hms": "H:mm:ss",
-	"dateFormatItem-hms": "h:mm:ss a"
+	"dayPeriods-format-narrow-pm": "p.m.",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "H.mm.ss",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"field-week-relative+0": "Aquesta setmana",
+	"field-week-relative+1": "Setmana següent"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ca/number.js b/dojo/cldr/nls/ca/number.js
index c6539c1..a4063cd 100644
--- a/dojo/cldr/nls/ca/number.js
+++ b/dojo/cldr/nls/ca/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0%",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
-	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"currencyFormat": "¤#,##0.00;(¤#,##0.00)",
+	"plusSign": "+",
+	"decimalFormat-long": "000 bilions",
+	"decimalFormat-short": "000 B"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ca/roc.js b/dojo/cldr/nls/ca/roc.js
new file mode 100644
index 0000000..dfa66d9
--- /dev/null
+++ b/dojo/cldr/nls/ca/roc.js
@@ -0,0 +1,31 @@
+define(
+//begin v1.x content
+{
+	"field-second": "segon",
+	"field-year-relative+-1": "Últim any",
+	"field-week": "setmana",
+	"field-month-relative+-1": "Últim mes",
+	"field-day-relative+-1": "ahir",
+	"field-day-relative+-2": "abans d'ahir",
+	"field-year": "any",
+	"field-week-relative+0": "Aquesta setmana",
+	"field-week-relative+1": "Setmana següent",
+	"field-minute": "minut",
+	"field-week-relative+-1": "Última setmana",
+	"field-day-relative+0": "avui",
+	"field-hour": "hora",
+	"field-day-relative+1": "demà",
+	"field-day-relative+2": "demà passat",
+	"field-day": "dia",
+	"field-month-relative+0": "Aquest mes",
+	"field-month-relative+1": "Mes següent",
+	"field-dayperiod": "a.m./p.m.",
+	"field-month": "mes",
+	"field-era": "era",
+	"field-year-relative+0": "Aquest any",
+	"field-year-relative+1": "Any següent",
+	"field-weekday": "dia de la setmana",
+	"field-zone": "zona"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/chinese.js b/dojo/cldr/nls/chinese.js
new file mode 100644
index 0000000..9325af9
--- /dev/null
+++ b/dojo/cldr/nls/chinese.js
@@ -0,0 +1,414 @@
+define({ root:
+
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-GyMMMEd": "U MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
+	"months-standAlone-wide at localeAlias40": {
+		"bundle": "chinese",
+		"target": "months-format-wide"
+	},
+	"months-format-abbr at localeAlias36": {
+		"bundle": "chinese",
+		"target": "months-format-wide"
+	},
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"days-format-narrow at localeAlias43": {
+		"bundle": "gregorian",
+		"target": "days-standAlone-narrow"
+	},
+	"dateFormat-long": "U MMMM d",
+	"months-format-wide": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"dateFormatItem-yyyyQQQ": "U QQQ",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "U MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "y-MM-dd, E",
+	"dateFormatItem-Md": "MM-dd",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"dateFormatItem-yMd": "y-MM-dd",
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
+	"months-format-abbr": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"days-standAlone-wide at localeAlias51": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "U MMM d",
+	"months-standAlone-abbr": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"dateFormatItem-H": "HH",
+	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Gy": "U",
+	"months-standAlone-abbr at localeAlias38": {
+		"bundle": "chinese",
+		"target": "months-format-abbr"
+	},
+	"dateFormatItem-yyyyMMMEd": "U MMM d, E",
+	"months-standAlone-abbr at localeAlias39": {
+		"bundle": "chinese",
+		"target": "months-format-wide"
+	},
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-yyyyMMM": "U MMM",
+	"dateFormatItem-yyyyMMMd": "U MMM d",
+	"dayPeriods-format-abbr at localeAlias59": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"months-format-narrow at localeAlias37": {
+		"bundle": "chinese",
+		"target": "months-standAlone-narrow"
+	},
+	"timeFormat-medium": "HH:mm:ss",
+	"days-standAlone-abbr at localeAlias46": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-standAlone-abbr at localeAlias47": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Hm": "HH:mm",
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Yesterday",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "AM",
+	"quarters-standAlone-wide at localeAlias57": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateFormatItem-h": "h a",
+	"dayPeriods-format-abbr at localeAlias62": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "MM-dd, E",
+	"dateTimeFormat-full": "{1} {0}",
+	"quarters at localeAlias52": {
+		"bundle": "gregorian",
+		"target": "quarters"
+	},
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"field-zone": "Zone",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-y": "U",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"days at localeAlias41": {
+		"bundle": "gregorian",
+		"target": "days"
+	},
+	"dayPeriods-format-narrow at localeAlias60": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias61": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"timeFormat at localeAlias65": {
+		"bundle": "gregorian",
+		"target": "timeFormat"
+	},
+	"dayPeriods-format-narrow at localeAlias63": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias64": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"days-standAlone-short at localeAlias48": {
+		"bundle": "gregorian",
+		"target": "days-format-short"
+	},
+	"days-standAlone-short at localeAlias49": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-yyyyMd": "y-MM-dd",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"days-format-abbr at localeAlias42": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"days-standAlone-short at localeAlias50": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"quarters-format-abbr at localeAlias53": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"days-format-short at localeAlias44": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-format-short at localeAlias45": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormat-short": "y-MM-dd",
+	"quarters-standAlone-abbr at localeAlias55": {
+		"bundle": "gregorian",
+		"target": "quarters-format-abbr"
+	},
+	"quarters-standAlone-abbr at localeAlias56": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"field-second": "Second",
+	"dayPeriods at localeAlias58": {
+		"bundle": "gregorian",
+		"target": "dayPeriods"
+	},
+	"quarters-format-narrow at localeAlias54": {
+		"bundle": "gregorian",
+		"target": "quarters-standAlone-narrow"
+	},
+	"dateFormatItem-Ed": "d, E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "U MMM d",
+	"dateFormatItem-yyyyM": "y-MM",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "U QQQQ",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "U MMM",
+	"dateFormatItem-yyyy": "U"
+}
+//end v1.x content
+,
+	"ca": true,
+	"cs": true,
+	"de": true,
+	"en": true,
+	"en-au": true,
+	"en-gb": true,
+	"es": true,
+	"fi": true,
+	"fr": true,
+	"hu": true,
+	"it": true,
+	"ja": true,
+	"ko": true,
+	"nl": true,
+	"pl": true,
+	"pt": true,
+	"ro": true,
+	"ru": true,
+	"th": true,
+	"zh": true,
+	"zh-hant": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/coptic.js b/dojo/cldr/nls/coptic.js
new file mode 100644
index 0000000..c2f2a05
--- /dev/null
+++ b/dojo/cldr/nls/coptic.js
@@ -0,0 +1,439 @@
+define({ root:
+
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-weekday": "Day of the Week",
+	"quarters at localeAlias82": {
+		"bundle": "gregorian",
+		"target": "quarters"
+	},
+	"days at localeAlias71": {
+		"bundle": "gregorian",
+		"target": "days"
+	},
+	"dayPeriods-format-narrow at localeAlias90": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
+	"dayPeriods-format-narrow at localeAlias91": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"eraNarrow": [
+		"ERA0",
+		"ERA1"
+	],
+	"dayPeriods-format-narrow at localeAlias93": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias94": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"timeFormat at localeAlias98": {
+		"bundle": "gregorian",
+		"target": "timeFormat"
+	},
+	"days-standAlone-short at localeAlias78": {
+		"bundle": "gregorian",
+		"target": "days-format-short"
+	},
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"days-standAlone-short at localeAlias79": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "G y MMMM d",
+	"months-format-wide": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"dateFormatItem-Md": "MM-dd",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"days-format-abbr at localeAlias72": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"timeFormat-short": "HH:mm",
+	"days-standAlone-short at localeAlias80": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"quarters-format-abbr at localeAlias83": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"days-format-short at localeAlias74": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"quarters-format-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"days-format-short at localeAlias75": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
+	"months-format-abbr": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
+	"months-standAlone-abbr": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"dateFormatItem-H": "HH",
+	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-abbr at localeAlias85": {
+		"bundle": "gregorian",
+		"target": "quarters-format-abbr"
+	},
+	"dateFormatItem-Gy": "G y",
+	"quarters-standAlone-abbr at localeAlias86": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
+	"eraNarrow at localeAlias96": {
+		"bundle": "coptic",
+		"target": "eraAbbr"
+	},
+	"dateFormatItem-M": "L",
+	"dateFormat at localeAlias97": {
+		"bundle": "generic",
+		"target": "dateFormat"
+	},
+	"dayPeriods at localeAlias88": {
+		"bundle": "gregorian",
+		"target": "dayPeriods"
+	},
+	"days-standAlone-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
+	"quarters-format-narrow at localeAlias84": {
+		"bundle": "gregorian",
+		"target": "quarters-standAlone-narrow"
+	},
+	"timeFormat-medium": "HH:mm:ss",
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Hm": "HH:mm",
+	"eraAbbr": [
+		"ERA0",
+		"ERA1"
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Yesterday",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateTimeFormat-long": "{1} {0}",
+	"dateFormatItem-h": "h a",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "MM-dd, E",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateTime at localeAlias99": {
+		"bundle": "generic",
+		"target": "dateTime"
+	},
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"field-zone": "Zone",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"dateFormatItem-y": "G y",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"months-standAlone-wide at localeAlias70": {
+		"bundle": "coptic",
+		"target": "months-format-wide"
+	},
+	"months-format-abbr at localeAlias66": {
+		"bundle": "coptic",
+		"target": "months-format-wide"
+	},
+	"days-format-narrow at localeAlias73": {
+		"bundle": "gregorian",
+		"target": "days-standAlone-narrow"
+	},
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"eraNames": [
+		"ERA0",
+		"ERA1"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"eraNames at localeAlias95": {
+		"bundle": "coptic",
+		"target": "eraAbbr"
+	},
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"days-standAlone-wide at localeAlias81": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"months-standAlone-abbr at localeAlias68": {
+		"bundle": "coptic",
+		"target": "months-format-abbr"
+	},
+	"months-standAlone-abbr at localeAlias69": {
+		"bundle": "coptic",
+		"target": "months-format-wide"
+	},
+	"dayPeriods-format-abbr at localeAlias89": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"field-second": "Second",
+	"months-format-narrow at localeAlias67": {
+		"bundle": "coptic",
+		"target": "months-standAlone-narrow"
+	},
+	"dateFormatItem-Ed": "d, E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"days-standAlone-abbr at localeAlias76": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-standAlone-abbr at localeAlias77": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "G y MMM",
+	"quarters-standAlone-wide at localeAlias87": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dayPeriods-format-abbr at localeAlias92": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormatItem-yyyy": "G y"
+}
+//end v1.x content
+,
+	"ar": true,
+	"fr": true,
+	"hu": true,
+	"ja": true,
+	"pl": true,
+	"pt": true,
+	"ro": true,
+	"ru": true,
+	"sv": true,
+	"th": true,
+	"tr": true,
+	"zh": true,
+	"zh-hant": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/buddhist.js b/dojo/cldr/nls/cs/buddhist.js
new file mode 100644
index 0000000..8bdace5
--- /dev/null
+++ b/dojo/cldr/nls/cs/buddhist.js
@@ -0,0 +1,223 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Ne",
+		"Po",
+		"Út",
+		"St",
+		"Čt",
+		"Pá",
+		"So"
+	],
+	"field-weekday": "Den v týdnu",
+	"dateFormatItem-GyMMMEd": "E, d. M. y G",
+	"dateFormatItem-MMMEd": "E, d. M.",
+	"days-format-short": [
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
+		"so"
+	],
+	"dateFormat-long": "d. MMMM y G",
+	"months-format-wide": [
+		"ledna",
+		"února",
+		"března",
+		"dubna",
+		"května",
+		"června",
+		"července",
+		"srpna",
+		"září",
+		"října",
+		"listopadu",
+		"prosince"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dayPeriods-format-wide-pm": "odp.",
+	"dateFormat-full": "EEEE, d. MMMM y G",
+	"dateFormatItem-yyyyMEd": "E, d. M. y GGGGG",
+	"dateFormatItem-Md": "d. M.",
+	"field-era": "Letopočet",
+	"months-standAlone-wide": [
+		"leden",
+		"únor",
+		"březen",
+		"duben",
+		"květen",
+		"červen",
+		"červenec",
+		"srpen",
+		"září",
+		"říjen",
+		"listopad",
+		"prosinec"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"1. čtvrtletí",
+		"2. čtvrtletí",
+		"3. čtvrtletí",
+		"4. čtvrtletí"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "Rok",
+	"field-hour": "Hodina",
+	"months-format-abbr": [
+		"led",
+		"úno",
+		"bře",
+		"dub",
+		"kvě",
+		"čvn",
+		"čvc",
+		"srp",
+		"zář",
+		"říj",
+		"lis",
+		"pro"
+	],
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "Dnes",
+	"field-day-relative+1": "Zítra",
+	"dateFormatItem-GyMMMd": "d. M. y G",
+	"field-day-relative+2": "Pozítří",
+	"dateFormatItem-H": "H",
+	"months-standAlone-abbr": [
+		"led",
+		"úno",
+		"bře",
+		"dub",
+		"kvě",
+		"čvn",
+		"čvc",
+		"srp",
+		"zář",
+		"říj",
+		"lis",
+		"pro"
+	],
+	"quarters-standAlone-wide": [
+		"1. čtvrtletí",
+		"2. čtvrtletí",
+		"3. čtvrtletí",
+		"4. čtvrtletí"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E, d. M. y G",
+	"days-standAlone-wide": [
+		"neděle",
+		"pondělí",
+		"úterý",
+		"středa",
+		"čtvrtek",
+		"pátek",
+		"sobota"
+	],
+	"dateFormatItem-yyyyMMM": "LLLL y G",
+	"dateFormatItem-yyyyMMMd": "d. M. y G",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"eraAbbr": [
+		"BE"
+	],
+	"field-minute": "Minuta",
+	"field-dayperiod": "AM/PM",
+	"days-standAlone-abbr": [
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
+		"so"
+	],
+	"dateFormatItem-d": "d.",
+	"field-day-relative+-1": "Včera",
+	"dayPeriods-format-narrow-am": "dop.",
+	"field-day-relative+-2": "Předevčírem",
+	"dateFormatItem-MMMd": "d. M.",
+	"dateFormatItem-MEd": "E, d. M.",
+	"field-day": "Den",
+	"days-format-wide": [
+		"neděle",
+		"pondělí",
+		"úterý",
+		"středa",
+		"čtvrtek",
+		"pátek",
+		"sobota"
+	],
+	"field-zone": "Časové pásmo",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"l",
+		"ú",
+		"b",
+		"d",
+		"k",
+		"č",
+		"č",
+		"s",
+		"z",
+		"ř",
+		"l",
+		"p"
+	],
+	"field-year-relative+-1": "Minulý rok",
+	"field-month-relative+-1": "Minulý měsíc",
+	"days-format-abbr": [
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
+		"so"
+	],
+	"days-format-narrow": [
+		"N",
+		"P",
+		"Ú",
+		"S",
+		"Č",
+		"P",
+		"S"
+	],
+	"dateFormatItem-yyyyMd": "d. M. y GGGGG",
+	"field-month": "Měsíc",
+	"days-standAlone-narrow": [
+		"N",
+		"P",
+		"Ú",
+		"S",
+		"Č",
+		"P",
+		"S"
+	],
+	"dayPeriods-format-wide-am": "dop.",
+	"dateFormat-short": "dd.MM.yy GGGGG",
+	"field-second": "Sekunda",
+	"field-month-relative+0": "Tento měsíc",
+	"field-month-relative+1": "Příští měsíc",
+	"dateFormatItem-Ed": "E, d.",
+	"field-week": "Týden",
+	"dateFormat-medium": "d. M. y G",
+	"field-year-relative+0": "Tento rok",
+	"field-week-relative+-1": "Minulý týden",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"field-year-relative+1": "Příští rok",
+	"dayPeriods-format-narrow-pm": "odp.",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-GyMMM": "LLLL y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "Tento týden",
+	"field-week-relative+1": "Příští týden"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/chinese.js b/dojo/cldr/nls/cs/chinese.js
new file mode 100644
index 0000000..9ee1cf5
--- /dev/null
+++ b/dojo/cldr/nls/cs/chinese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d. M. y",
+	"field-second": "Sekunda",
+	"field-year-relative+-1": "Minulý rok",
+	"field-week": "Týden",
+	"field-month-relative+-1": "Minulý měsíc",
+	"field-day-relative+-1": "Včera",
+	"field-day-relative+-2": "Předevčírem",
+	"field-year": "Rok",
+	"field-week-relative+0": "Tento týden",
+	"field-week-relative+1": "Příští týden",
+	"field-minute": "Minuta",
+	"field-week-relative+-1": "Minulý týden",
+	"field-day-relative+0": "Dnes",
+	"field-hour": "Hodina",
+	"field-day-relative+1": "Zítra",
+	"dateFormat-long": "d. M. y",
+	"field-day-relative+2": "Pozítří",
+	"field-day": "Den",
+	"field-month-relative+0": "Tento měsíc",
+	"field-month-relative+1": "Příští měsíc",
+	"field-dayperiod": "AM/PM",
+	"field-month": "Měsíc",
+	"dateFormat-short": "d. M. y",
+	"field-era": "Letopočet",
+	"field-year-relative+0": "Tento rok",
+	"field-year-relative+1": "Příští rok",
+	"dateFormat-full": "EEEE, d. M. y",
+	"field-weekday": "Den v týdnu",
+	"field-zone": "Časové pásmo"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/currency.js b/dojo/cldr/nls/cs/currency.js
index 6ee7cb6..70254dc 100644
--- a/dojo/cldr/nls/cs/currency.js
+++ b/dojo/cldr/nls/cs/currency.js
@@ -1,15 +1,23 @@
 define(
 //begin v1.x content
 {
-	"HKD_displayName": "Dolar hongkongský",
-	"CHF_displayName": "Frank švýcarský",
-	"CAD_displayName": "Dolar kanadský",
-	"CNY_displayName": "Juan renminbi",
-	"AUD_displayName": "Dolar australský",
-	"JPY_displayName": "Jen",
-	"USD_displayName": "Dolar americký",
-	"GBP_displayName": "Libra šterlinků",
-	"EUR_displayName": "Euro"
+	"HKD_displayName": "hongkongský dolar",
+	"CHF_displayName": "švýcarský frank",
+	"JPY_symbol": "JP¥",
+	"CAD_displayName": "kanadský dolar",
+	"HKD_symbol": "HK$",
+	"CNY_displayName": "čínský jüan",
+	"USD_symbol": "US$",
+	"AUD_displayName": "australský dolar",
+	"JPY_displayName": "japonský jen",
+	"CAD_symbol": "CA$",
+	"USD_displayName": "americký dolar",
+	"EUR_symbol": "€",
+	"CNY_symbol": "CN¥",
+	"GBP_displayName": "britská libra",
+	"GBP_symbol": "£",
+	"AUD_symbol": "AU$",
+	"EUR_displayName": "euro"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/generic.js b/dojo/cldr/nls/cs/generic.js
new file mode 100644
index 0000000..e39a4b7
--- /dev/null
+++ b/dojo/cldr/nls/cs/generic.js
@@ -0,0 +1,69 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d. M. y G",
+	"field-dayperiod": "AM/PM",
+	"field-minute": "Minuta",
+	"dateFormatItem-MMMEd": "E, d. M.",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "Včera",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "Předevčírem",
+	"field-weekday": "Den v týdnu",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "Letopočet",
+	"field-hour": "Hodina",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E, d.",
+	"field-day-relative+0": "Dnes",
+	"field-day-relative+1": "Zítra",
+	"field-day-relative+2": "Pozítří",
+	"dateFormatItem-GyMMMd": "d. M. y G",
+	"dateFormatItem-yyyyMMMM": "LLLL y G",
+	"dateFormat-long": "d. MMMM y G",
+	"field-zone": "Časové pásmo",
+	"dateFormatItem-Hm": "H:mm",
+	"field-week-relative+-1": "Minulý týden",
+	"dateFormat-medium": "d. M. y G",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"field-year-relative+0": "Tento rok",
+	"field-year-relative+1": "Příští rok",
+	"field-year-relative+-1": "Minulý rok",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-year": "Rok",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "Týden",
+	"dateFormatItem-yyyyMd": "d. M. y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d. M. y G",
+	"dateFormatItem-yyyyMEd": "E, d. M. y GGGGG",
+	"dateFormatItem-MMMd": "d. M.",
+	"field-week-relative+0": "Tento týden",
+	"field-week-relative+1": "Příští týden",
+	"field-month-relative+0": "Tento měsíc",
+	"dateFormatItem-H": "H",
+	"field-month": "Měsíc",
+	"field-month-relative+1": "Příští měsíc",
+	"dateFormatItem-M": "L",
+	"field-second": "Sekunda",
+	"dateFormatItem-GyMMMEd": "E, d. M. y G",
+	"dateFormatItem-GyMMM": "LLLL y G",
+	"field-day": "Den",
+	"dateFormatItem-MEd": "E, d. M.",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd.MM.yy GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE, d. MMMM y G",
+	"dateFormatItem-Md": "d. M.",
+	"dateFormatItem-yyyyMMM": "LLLL y G",
+	"dateFormatItem-d": "d.",
+	"field-month-relative+-1": "Minulý měsíc",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/gregorian.js b/dojo/cldr/nls/cs/gregorian.js
index 4e6351d..0fa1f56 100644
--- a/dojo/cldr/nls/cs/gregorian.js
+++ b/dojo/cldr/nls/cs/gregorian.js
@@ -1,94 +1,75 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M.y",
-	"dateFormatItem-yQ": "Q yyyy",
-	"dayPeriods-format-wide-pm": "odp.",
-	"eraNames": [
-		"př.Kr.",
-		"po Kr."
+	"days-standAlone-short": [
+		"Ne",
+		"Po",
+		"Út",
+		"St",
+		"Čt",
+		"Pá",
+		"So"
 	],
-	"dateFormatItem-MMMEd": "E, d. MMM",
-	"field-day-relative+-1": "Včera",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"field-day-relative+-2": "Předevčírem",
-	"days-standAlone-wide": [
-		"neděle",
-		"pondělí",
-		"úterý",
-		"středa",
-		"čtvrtek",
-		"pátek",
-		"sobota"
-	],
-	"months-standAlone-narrow": [
-		"l",
-		"ú",
-		"b",
-		"d",
-		"k",
-		"č",
-		"č",
-		"s",
-		"z",
-		"ř",
-		"l",
-		"p"
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
 	],
-	"dayPeriods-format-wide-am": "dop.",
-	"quarters-standAlone-abbr": [
-		"1. čtvrtletí",
-		"2. čtvrtletí",
-		"3. čtvrtletí",
-		"4. čtvrtletí"
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
 	],
-	"timeFormat-full": "H:mm:ss zzzz",
-	"dateFormatItem-yyyy": "y",
-	"months-standAlone-abbr": [
-		"1.",
-		"2.",
-		"3.",
-		"4.",
-		"5.",
-		"6.",
-		"7.",
-		"8.",
-		"9.",
-		"10.",
-		"11.",
-		"12."
-	],
-	"dateFormatItem-yMMM": "LLL y",
-	"field-day-relative+0": "Dnes",
-	"field-day-relative+1": "Zítra",
-	"days-standAlone-narrow": [
-		"N",
-		"P",
-		"Ú",
-		"S",
-		"Č",
-		"P",
-		"S"
+	"field-weekday": "Den v týdnu",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "E, d. M. y",
+	"dateFormatItem-GyMMMEd": "E, d. M. y G",
+	"dateFormatItem-MMMEd": "E, d. M.",
+	"eraNarrow": [
+		"př.n.l.",
+		"n. l."
 	],
-	"eraAbbr": [
-		"př.Kr.",
-		"po Kr."
+	"days-format-short": [
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
+		"so"
 	],
-	"field-day-relative+2": "Pozítří",
-	"dateFormatItem-yyyyMMMM": "LLLL y",
 	"dateFormat-long": "d. MMMM y",
-	"timeFormat-medium": "H:mm:ss",
-	"dateFormatItem-EEEd": "EEE, d.",
-	"dateFormatItem-Hm": "H:mm",
-	"dateFormat-medium": "d.M.yyyy",
-	"dateFormatItem-Hms": "H:mm:ss",
-	"dateFormatItem-yMd": "d.M.y",
-	"quarters-standAlone-wide": [
-		"1. čtvrtletí",
-		"2. čtvrtletí",
-		"3. čtvrtletí",
-		"4. čtvrtletí"
+	"months-format-wide": [
+		"ledna",
+		"února",
+		"března",
+		"dubna",
+		"května",
+		"června",
+		"července",
+		"srpna",
+		"září",
+		"října",
+		"listopadu",
+		"prosince"
 	],
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "odp.",
+	"dateFormat-full": "EEEE, d. MMMM y",
+	"dateFormatItem-Md": "d. M.",
+	"dateFormatItem-yMd": "d. M. y",
+	"field-era": "Letopočet",
+	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
 		"leden",
 		"únor",
@@ -103,32 +84,90 @@ define(
 		"listopad",
 		"prosinec"
 	],
-	"dateFormatItem-MMMd": "d. MMM",
-	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"1. čtvrtletí",
+		"2. čtvrtletí",
+		"3. čtvrtletí",
+		"4. čtvrtletí"
+	],
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-long": "H:mm:ss z",
+	"field-year": "Rok",
+	"dateFormatItem-yMMM": "LLLL y",
+	"field-hour": "Hodina",
 	"months-format-abbr": [
-		"ledna",
-		"února",
-		"března",
-		"dubna",
-		"května",
-		"června",
-		"července",
-		"srpna",
-		"září",
-		"října",
-		"listopadu",
-		"prosince"
+		"led",
+		"úno",
+		"bře",
+		"dub",
+		"kvě",
+		"čvn",
+		"čvc",
+		"srp",
+		"zář",
+		"říj",
+		"lis",
+		"pro"
 	],
-	"timeFormat-short": "H:mm",
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "Dnes",
+	"field-day-relative+1": "Zítra",
+	"dateFormatItem-GyMMMd": "d. M. y G",
+	"field-day-relative+2": "Pozítří",
 	"dateFormatItem-H": "H",
+	"months-standAlone-abbr": [
+		"led",
+		"úno",
+		"bře",
+		"dub",
+		"kvě",
+		"čvn",
+		"čvc",
+		"srp",
+		"zář",
+		"říj",
+		"lis",
+		"pro"
+	],
 	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
 		"1. čtvrtletí",
 		"2. čtvrtletí",
 		"3. čtvrtletí",
 		"4. čtvrtletí"
 	],
-	"days-format-abbr": [
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"neděle",
+		"pondělí",
+		"úterý",
+		"středa",
+		"čtvrtek",
+		"pátek",
+		"sobota"
+	],
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"eraAbbr": [
+		"př. n. l.",
+		"n. l."
+	],
+	"field-minute": "Minuta",
+	"field-dayperiod": "AM/PM",
+	"days-standAlone-abbr": [
 		"ne",
 		"po",
 		"út",
@@ -137,17 +176,36 @@ define(
 		"pá",
 		"so"
 	],
-	"days-format-narrow": [
-		"N",
-		"P",
-		"Ú",
-		"S",
-		"Č",
-		"P",
-		"S"
+	"dateFormatItem-d": "d.",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
 	],
-	"dateFormatItem-MEd": "E, d.M",
-	"months-format-narrow": [
+	"field-day-relative+-1": "Včera",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "dop.",
+	"field-day-relative+-2": "Předevčírem",
+	"dateFormatItem-MMMd": "d. M.",
+	"dateFormatItem-MEd": "E, d. M.",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-yMMMM": "LLLL y",
+	"field-day": "Den",
+	"days-format-wide": [
+		"neděle",
+		"pondělí",
+		"úterý",
+		"středa",
+		"čtvrtek",
+		"pátek",
+		"sobota"
+	],
+	"field-zone": "Časové pásmo",
+	"dateFormatItem-y": "y",
+	"months-standAlone-narrow": [
 		"l",
 		"ú",
 		"b",
@@ -161,7 +219,10 @@ define(
 		"l",
 		"p"
 	],
-	"days-standAlone-abbr": [
+	"field-year-relative+-1": "Minulý rok",
+	"field-month-relative+-1": "Minulý měsíc",
+	"dateFormatItem-hm": "h:mm a",
+	"days-format-abbr": [
 		"ne",
 		"po",
 		"út",
@@ -170,46 +231,50 @@ define(
 		"pá",
 		"so"
 	],
-	"dateFormat-short": "d.M.yy",
-	"dateFormatItem-yyyyM": "M.yyyy",
-	"dateFormatItem-yMMMEd": "EEE, d. MMM y",
-	"dateFormat-full": "EEEE, d. MMMM y",
-	"dateFormatItem-Md": "d.M",
-	"dateFormatItem-yMEd": "EEE, d.M.y",
-	"months-format-wide": [
-		"ledna",
-		"února",
-		"března",
-		"dubna",
-		"května",
-		"června",
-		"července",
-		"srpna",
-		"září",
-		"října",
-		"listopadu",
-		"prosince"
+	"dateFormatItem-yMMMd": "d. M. y",
+	"eraNames": [
+		"př. n. l.",
+		"n. l."
 	],
-	"dateFormatItem-d": "d.",
-	"quarters-format-wide": [
-		"1. čtvrtletí",
-		"2. čtvrtletí",
-		"3. čtvrtletí",
-		"4. čtvrtletí"
+	"days-format-narrow": [
+		"N",
+		"P",
+		"Ú",
+		"S",
+		"Č",
+		"P",
+		"S"
 	],
-	"days-format-wide": [
-		"neděle",
-		"pondělí",
-		"úterý",
-		"středa",
-		"čtvrtek",
-		"pátek",
-		"sobota"
+	"days-standAlone-narrow": [
+		"N",
+		"P",
+		"Ú",
+		"S",
+		"Č",
+		"P",
+		"S"
 	],
-	"eraNarrow": [
-		"př.Kr.",
-		"po Kr."
-	]
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Měsíc",
+	"dayPeriods-format-wide-am": "dop.",
+	"dateFormat-short": "dd.MM.yy",
+	"field-second": "Sekunda",
+	"dateFormatItem-yMMMEd": "E, d. M. y",
+	"field-month-relative+0": "Tento měsíc",
+	"field-month-relative+1": "Příští měsíc",
+	"dateFormatItem-Ed": "E, d.",
+	"field-week": "Týden",
+	"dateFormat-medium": "d. M. y",
+	"field-year-relative+0": "Tento rok",
+	"field-week-relative+-1": "Minulý týden",
+	"field-year-relative+1": "Příští rok",
+	"dayPeriods-format-narrow-pm": "odp.",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "LLLL y G",
+	"field-week-relative+0": "Tento týden",
+	"field-week-relative+1": "Příští týden"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/hebrew.js b/dojo/cldr/nls/cs/hebrew.js
new file mode 100644
index 0000000..d1b284b
--- /dev/null
+++ b/dojo/cldr/nls/cs/hebrew.js
@@ -0,0 +1,153 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-yyyyMMMEd": "E, d. M. y G",
+	"dayPeriods-format-wide-pm": "odp.",
+	"field-minute": "Minuta",
+	"dateFormatItem-MMMEd": "E, d. M.",
+	"field-day-relative+-1": "Včera",
+	"field-weekday": "Den v týdnu",
+	"field-day-relative+-2": "Předevčírem",
+	"days-standAlone-wide": [
+		"neděle",
+		"pondělí",
+		"úterý",
+		"středa",
+		"čtvrtek",
+		"pátek",
+		"sobota"
+	],
+	"field-era": "Letopočet",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Hodina",
+	"dayPeriods-format-wide-am": "dop.",
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "H:mm:ss zzzz",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E, d.",
+	"field-day-relative+0": "Dnes",
+	"field-day-relative+1": "Zítra",
+	"days-standAlone-narrow": [
+		"N",
+		"P",
+		"Ú",
+		"S",
+		"Č",
+		"P",
+		"S"
+	],
+	"eraAbbr": [
+		"AM"
+	],
+	"field-day-relative+2": "Pozítří",
+	"dateFormatItem-GyMMMd": "d. M. y G",
+	"dateFormat-long": "d. MMMM y G",
+	"timeFormat-medium": "H:mm:ss",
+	"field-zone": "Časové pásmo",
+	"dateFormatItem-Hm": "H:mm",
+	"field-week-relative+-1": "Minulý týden",
+	"dateFormat-medium": "d. M. y G",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dayPeriods-format-narrow-pm": "odp.",
+	"field-year-relative+0": "Tento rok",
+	"field-year-relative+1": "Příští rok",
+	"quarters-standAlone-wide": [
+		"1. čtvrtletí",
+		"2. čtvrtletí",
+		"3. čtvrtletí",
+		"4. čtvrtletí"
+	],
+	"field-year-relative+-1": "Minulý rok",
+	"field-year": "Rok",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dayPeriods-format-narrow-am": "dop.",
+	"field-week": "Týden",
+	"dateFormatItem-yyyyMd": "d. M. y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d. M. y G",
+	"dateFormatItem-yyyyMEd": "E, d. M. y GGGGG",
+	"dateFormatItem-MMMd": "d. M.",
+	"field-week-relative+0": "Tento týden",
+	"field-week-relative+1": "Příští týden",
+	"timeFormat-long": "H:mm:ss z",
+	"field-month-relative+0": "Tento měsíc",
+	"field-month": "Měsíc",
+	"field-month-relative+1": "Příští měsíc",
+	"dateFormatItem-H": "H",
+	"timeFormat-short": "H:mm",
+	"days-format-abbr": [
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
+		"so"
+	],
+	"days-format-narrow": [
+		"N",
+		"P",
+		"Ú",
+		"S",
+		"Č",
+		"P",
+		"S"
+	],
+	"field-second": "Sekunda",
+	"dateFormatItem-GyMMMEd": "E, d. M. y G",
+	"dateFormatItem-GyMMM": "LLLL y G",
+	"field-day": "Den",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E, d. M.",
+	"days-standAlone-short": [
+		"Ne",
+		"Po",
+		"Út",
+		"St",
+		"Čt",
+		"Pá",
+		"So"
+	],
+	"days-standAlone-abbr": [
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
+		"so"
+	],
+	"dateFormat-short": "dd.MM.yy GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormatItem-Md": "d. M.",
+	"dateFormat-full": "EEEE, d. MMMM y G",
+	"days-format-short": [
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
+		"so"
+	],
+	"dateFormatItem-yyyyMMM": "LLLL y G",
+	"dateFormatItem-d": "d.",
+	"field-month-relative+-1": "Minulý měsíc",
+	"quarters-format-wide": [
+		"1. čtvrtletí",
+		"2. čtvrtletí",
+		"3. čtvrtletí",
+		"4. čtvrtletí"
+	],
+	"days-format-wide": [
+		"neděle",
+		"pondělí",
+		"úterý",
+		"středa",
+		"čtvrtek",
+		"pátek",
+		"sobota"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/islamic.js b/dojo/cldr/nls/cs/islamic.js
new file mode 100644
index 0000000..cbdc2ea
--- /dev/null
+++ b/dojo/cldr/nls/cs/islamic.js
@@ -0,0 +1,153 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-yyyyMMMEd": "E, d. M. y G",
+	"dayPeriods-format-wide-pm": "odp.",
+	"field-minute": "Minuta",
+	"dateFormatItem-MMMEd": "E, d. M.",
+	"field-day-relative+-1": "Včera",
+	"field-weekday": "Den v týdnu",
+	"field-day-relative+-2": "Předevčírem",
+	"days-standAlone-wide": [
+		"neděle",
+		"pondělí",
+		"úterý",
+		"středa",
+		"čtvrtek",
+		"pátek",
+		"sobota"
+	],
+	"field-era": "Letopočet",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Hodina",
+	"dayPeriods-format-wide-am": "dop.",
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "H:mm:ss zzzz",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E, d.",
+	"field-day-relative+0": "Dnes",
+	"field-day-relative+1": "Zítra",
+	"days-standAlone-narrow": [
+		"N",
+		"P",
+		"Ú",
+		"S",
+		"Č",
+		"P",
+		"S"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"field-day-relative+2": "Pozítří",
+	"dateFormatItem-GyMMMd": "d. M. y G",
+	"dateFormat-long": "d. MMMM y G",
+	"timeFormat-medium": "H:mm:ss",
+	"field-zone": "Časové pásmo",
+	"dateFormatItem-Hm": "H:mm",
+	"field-week-relative+-1": "Minulý týden",
+	"dateFormat-medium": "d. M. y G",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dayPeriods-format-narrow-pm": "odp.",
+	"field-year-relative+0": "Tento rok",
+	"field-year-relative+1": "Příští rok",
+	"quarters-standAlone-wide": [
+		"1. čtvrtletí",
+		"2. čtvrtletí",
+		"3. čtvrtletí",
+		"4. čtvrtletí"
+	],
+	"field-year-relative+-1": "Minulý rok",
+	"field-year": "Rok",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dayPeriods-format-narrow-am": "dop.",
+	"field-week": "Týden",
+	"dateFormatItem-yyyyMMMd": "d. M. y G",
+	"dateFormatItem-yyyyMd": "d. M. y GGGGG",
+	"dateFormatItem-yyyyMEd": "E, d. M. y GGGGG",
+	"field-week-relative+0": "Tento týden",
+	"dateFormatItem-MMMd": "d. M.",
+	"field-week-relative+1": "Příští týden",
+	"timeFormat-long": "H:mm:ss z",
+	"field-month-relative+0": "Tento měsíc",
+	"field-month": "Měsíc",
+	"field-month-relative+1": "Příští měsíc",
+	"dateFormatItem-H": "H",
+	"timeFormat-short": "H:mm",
+	"days-format-abbr": [
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
+		"so"
+	],
+	"days-format-narrow": [
+		"N",
+		"P",
+		"Ú",
+		"S",
+		"Č",
+		"P",
+		"S"
+	],
+	"field-second": "Sekunda",
+	"dateFormatItem-GyMMMEd": "E, d. M. y G",
+	"dateFormatItem-GyMMM": "LLLL y G",
+	"field-day": "Den",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E, d. M.",
+	"days-standAlone-short": [
+		"Ne",
+		"Po",
+		"Út",
+		"St",
+		"Čt",
+		"Pá",
+		"So"
+	],
+	"days-standAlone-abbr": [
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
+		"so"
+	],
+	"dateFormat-short": "dd.MM.yy GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE, d. MMMM y G",
+	"dateFormatItem-Md": "d. M.",
+	"days-format-short": [
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
+		"so"
+	],
+	"dateFormatItem-yyyyMMM": "LLLL y G",
+	"dateFormatItem-d": "d.",
+	"field-month-relative+-1": "Minulý měsíc",
+	"quarters-format-wide": [
+		"1. čtvrtletí",
+		"2. čtvrtletí",
+		"3. čtvrtletí",
+		"4. čtvrtletí"
+	],
+	"days-format-wide": [
+		"neděle",
+		"pondělí",
+		"úterý",
+		"středa",
+		"čtvrtek",
+		"pátek",
+		"sobota"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/japanese.js b/dojo/cldr/nls/cs/japanese.js
new file mode 100644
index 0000000..95a2195
--- /dev/null
+++ b/dojo/cldr/nls/cs/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d. M. y G",
+	"field-second": "Sekunda",
+	"field-year-relative+-1": "Minulý rok",
+	"field-week": "Týden",
+	"field-month-relative+-1": "Minulý měsíc",
+	"field-day-relative+-1": "Včera",
+	"field-day-relative+-2": "Předevčírem",
+	"field-year": "Rok",
+	"field-week-relative+0": "Tento týden",
+	"field-week-relative+1": "Příští týden",
+	"field-minute": "Minuta",
+	"field-week-relative+-1": "Minulý týden",
+	"field-day-relative+0": "Dnes",
+	"field-hour": "Hodina",
+	"field-day-relative+1": "Zítra",
+	"dateFormat-long": "d. MMMM y G",
+	"field-day-relative+2": "Pozítří",
+	"field-day": "Den",
+	"field-month-relative+0": "Tento měsíc",
+	"field-month-relative+1": "Příští měsíc",
+	"field-dayperiod": "AM/PM",
+	"field-month": "Měsíc",
+	"dateFormat-short": "dd.MM.yy GGGGG",
+	"field-era": "Letopočet",
+	"field-year-relative+0": "Tento rok",
+	"field-year-relative+1": "Příští rok",
+	"dateFormat-full": "EEEE, d. MMMM y G",
+	"field-weekday": "Den v týdnu",
+	"field-zone": "Časové pásmo"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/number.js b/dojo/cldr/nls/cs/number.js
index be5c98c..f50a3d8 100644
--- a/dojo/cldr/nls/cs/number.js
+++ b/dojo/cldr/nls/cs/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0 %",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 bilionů",
+	"decimalFormat-short": "000 bil'.'"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/roc.js b/dojo/cldr/nls/cs/roc.js
new file mode 100644
index 0000000..36db3d2
--- /dev/null
+++ b/dojo/cldr/nls/cs/roc.js
@@ -0,0 +1,34 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Sekunda",
+	"field-year-relative+-1": "Minulý rok",
+	"field-week": "Týden",
+	"field-month-relative+-1": "Minulý měsíc",
+	"field-day-relative+-1": "Včera",
+	"field-day-relative+-2": "Předevčírem",
+	"field-year": "Rok",
+	"field-week-relative+0": "Tento týden",
+	"field-week-relative+1": "Příští týden",
+	"field-minute": "Minuta",
+	"field-week-relative+-1": "Minulý týden",
+	"field-day-relative+0": "Dnes",
+	"field-hour": "Hodina",
+	"field-day-relative+1": "Zítra",
+	"field-day-relative+2": "Pozítří",
+	"field-day": "Den",
+	"field-month-relative+0": "Tento měsíc",
+	"field-month-relative+1": "Příští měsíc",
+	"field-dayperiod": "AM/PM",
+	"field-month": "Měsíc",
+	"field-era": "Letopočet",
+	"field-year-relative+0": "Tento rok",
+	"field-year-relative+1": "Příští rok",
+	"eraAbbr": [
+		"Před R. O. C."
+	],
+	"field-weekday": "Den v týdnu",
+	"field-zone": "Časové pásmo"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/currency.js b/dojo/cldr/nls/currency.js
index f00cb7a..85c1001 100644
--- a/dojo/cldr/nls/currency.js
+++ b/dojo/cldr/nls/currency.js
@@ -7,7 +7,7 @@ define({ root:
 	"GBP_symbol": "£",
 	"HKD_symbol": "HK$",
 	"JPY_symbol": "JP¥",
-	"AUD_symbol": "AU$",
+	"AUD_symbol": "A$",
 	"CNY_symbol": "CN¥",
 	"EUR_symbol": "€"
 }
@@ -22,9 +22,11 @@ define({ root:
 	"en": true,
 	"en-au": true,
 	"en-ca": true,
+	"en-gb": true,
 	"es": true,
 	"fi": true,
 	"fr": true,
+	"fr-ch": true,
 	"he": true,
 	"hu": true,
 	"it": true,
@@ -34,6 +36,7 @@ define({ root:
 	"nl": true,
 	"pl": true,
 	"pt": true,
+	"pt-pt": true,
 	"ro": true,
 	"ru": true,
 	"sk": true,
diff --git a/dojo/cldr/nls/da/buddhist.js b/dojo/cldr/nls/da/buddhist.js
index 48d308b..b977ddc 100644
--- a/dojo/cldr/nls/da/buddhist.js
+++ b/dojo/cldr/nls/da/buddhist.js
@@ -1,15 +1,16 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M/y G",
-	"dateFormatItem-yQ": "Q y G",
-	"dayPeriods-format-wide-pm": "e.m.",
-	"dateFormatItem-MMMEd": "E d. MMM",
-	"dateFormatItem-hms": "h.mm.ss a",
-	"dateFormatItem-yQQQ": "QQQ y G",
-	"dateFormatItem-MMdd": "dd/MM",
-	"dateFormatItem-MMM": "MMM",
-	"months-standAlone-narrow": [
+	"days-standAlone-short": [
+		"sø",
+		"ma",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lø"
+	],
+	"months-format-narrow": [
 		"J",
 		"F",
 		"M",
@@ -23,49 +24,62 @@ define(
 		"N",
 		"D"
 	],
-	"dayPeriods-format-wide-am": "f.m.",
-	"dateFormatItem-y": "y G",
-	"timeFormat-full": "HH.mm.ss zzzz",
-	"dateFormatItem-yyyy": "y G",
-	"months-standAlone-abbr": [
-		"jan",
-		"feb",
-		"mar",
-		"apr",
+	"field-weekday": "ugedag",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"days-format-short": [
+		"sø",
+		"ma",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lø"
+	],
+	"dateFormat-long": "d. MMMM y G",
+	"months-format-wide": [
+		"januar",
+		"februar",
+		"marts",
+		"april",
 		"maj",
-		"jun",
-		"jul",
-		"aug",
-		"sep",
-		"okt",
-		"nov",
-		"dec"
+		"juni",
+		"juli",
+		"august",
+		"september",
+		"oktober",
+		"november",
+		"december"
 	],
-	"dateFormatItem-Ed": "E d.",
-	"dateFormatItem-yMMM": "MMM y G",
-	"days-standAlone-narrow": [
-		"S",
-		"M",
-		"T",
-		"O",
-		"T",
-		"F",
-		"L"
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dateFormatItem-yyyyMEd": "E d/M/y G",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "æra",
+	"months-standAlone-wide": [
+		"januar",
+		"februar",
+		"marts",
+		"april",
+		"maj",
+		"juni",
+		"juli",
+		"august",
+		"september",
+		"oktober",
+		"november",
+		"december"
+	],
+	"timeFormat-short": "HH.mm",
+	"quarters-format-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
 	],
-	"dateFormatItem-yyyyMM": "MM/y G",
-	"dateFormat-long": "d. MMMM y G",
-	"timeFormat-medium": "HH.mm.ss",
-	"dateFormatItem-Hm": "HH.mm",
-	"dateFormatItem-yyMM": "MM/y G",
-	"dateFormat-medium": "d. MMM y G",
-	"dateFormatItem-Hms": "HH.mm.ss",
-	"dateFormatItem-yyMMM": "MMM y G",
-	"dateFormatItem-yMd": "d/M/y G",
-	"dateFormatItem-ms": "mm.ss",
-	"dateFormatItem-MMMMEd": "E, d. MMMM",
-	"dateFormatItem-MMMd": "d. MMM",
-	"dateFormatItem-yyQ": "Q. 'kvartal' y G",
 	"timeFormat-long": "HH.mm.ss z",
+	"field-year": "år",
+	"field-hour": "time",
 	"months-format-abbr": [
 		"jan.",
 		"feb.",
@@ -80,15 +94,65 @@ define(
 		"nov.",
 		"dec."
 	],
-	"timeFormat-short": "HH.mm",
-	"dateFormatItem-H": "HH",
+	"timeFormat-full": "HH.mm.ss zzzz",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"field-day-relative+2": "i overmorgen",
+	"months-standAlone-abbr": [
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"maj",
+		"jun",
+		"jul",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
+		"dec"
+	],
 	"quarters-format-abbr": [
 		"K1",
 		"K2",
 		"K3",
 		"K4"
 	],
-	"days-format-abbr": [
+	"quarters-standAlone-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"dateFormatItem-M": "M",
+	"days-standAlone-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"timeFormat-medium": "HH.mm.ss",
+	"dateFormatItem-Hm": "HH.mm",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"eraAbbr": [
+		"BE"
+	],
+	"field-minute": "minut",
+	"field-dayperiod": "dagtid",
+	"days-standAlone-abbr": [
 		"søn",
 		"man",
 		"tir",
@@ -97,36 +161,13 @@ define(
 		"fre",
 		"lør"
 	],
-	"dateFormatItem-M": "M",
-	"dateFormatItem-MEd": "E. d/M",
-	"dateFormatItem-hm": "h.mm a",
-	"dateFormat-short": "d/M/yyyy",
-	"dateFormatItem-yMMMEd": "EEE. d. MMM y G",
-	"dateFormat-full": "EEEE d. MMMM y G",
-	"dateFormatItem-Md": "d/M",
-	"dateFormatItem-yMEd": "EEE. d/M/y G",
-	"months-format-wide": [
-		"januar",
-		"februar",
-		"marts",
-		"april",
-		"maj",
-		"juni",
-		"juli",
-		"august",
-		"september",
-		"oktober",
-		"november",
-		"december"
-	],
-	"dateFormatItem-yyyyMMM": "MMM y G",
 	"dateFormatItem-d": "d.",
-	"quarters-format-wide": [
-		"1. kvartal",
-		"2. kvartal",
-		"3. kvartal",
-		"4. kvartal"
-	],
+	"dateFormatItem-ms": "mm.ss",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i forgårs",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-MEd": "E d/M",
+	"field-day": "dag",
 	"days-format-wide": [
 		"søndag",
 		"mandag",
@@ -135,7 +176,74 @@ define(
 		"torsdag",
 		"fredag",
 		"lørdag"
-	]
+	],
+	"field-zone": "tidszone",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-year-relative+-1": "sidste år",
+	"field-month-relative+-1": "sidste måned",
+	"dateFormatItem-hm": "h.mm a",
+	"days-format-abbr": [
+		"søn.",
+		"man.",
+		"tir.",
+		"ons.",
+		"tor.",
+		"fre.",
+		"lør."
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"field-month": "måned",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormatItem-MMM": "MMM",
+	"dateFormat-short": "d/M/y",
+	"field-second": "sekund",
+	"field-month-relative+0": "denne måned",
+	"field-month-relative+1": "næste måned",
+	"dateFormatItem-Ed": "E 'd'. d.",
+	"field-week": "uge",
+	"dateFormat-medium": "d. MMM y G",
+	"field-year-relative+0": "i år",
+	"field-week-relative+-1": "sidste uge",
+	"dateFormatItem-yyyyM": "M/y G",
+	"field-year-relative+1": "næste år",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-Hms": "HH.mm.ss",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "denne uge",
+	"field-week-relative+1": "næste uge"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/currency.js b/dojo/cldr/nls/da/currency.js
index 0b69b27..4ed5e7f 100644
--- a/dojo/cldr/nls/da/currency.js
+++ b/dojo/cldr/nls/da/currency.js
@@ -3,13 +3,20 @@ define(
 {
 	"HKD_displayName": "Hongkong dollar",
 	"CHF_displayName": "Schweizisk franc",
+	"JPY_symbol": "JP¥",
 	"CAD_displayName": "Canadisk dollar",
+	"HKD_symbol": "HK$",
 	"CNY_displayName": "Kinesisk yuan renminbi",
 	"USD_symbol": "$",
 	"AUD_displayName": "Australsk dollar",
 	"JPY_displayName": "Japansk yen",
+	"CAD_symbol": "CA$",
 	"USD_displayName": "Amerikansk dollar",
+	"EUR_symbol": "€",
+	"CNY_symbol": "CN¥",
 	"GBP_displayName": "Britisk pund",
+	"GBP_symbol": "£",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "Euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/da/generic.js b/dojo/cldr/nls/da/generic.js
new file mode 100644
index 0000000..315b5a6
--- /dev/null
+++ b/dojo/cldr/nls/da/generic.js
@@ -0,0 +1,69 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"field-dayperiod": "dagtid",
+	"field-minute": "minut",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "i går",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"field-day-relative+-2": "i forgårs",
+	"field-weekday": "ugedag",
+	"dateFormatItem-MMM": "MMM",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "æra",
+	"field-hour": "time",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E 'd'. d.",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgen",
+	"field-day-relative+2": "i overmorgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"dateFormat-long": "d. MMMM y G",
+	"field-zone": "tidszone",
+	"dateFormatItem-Hm": "HH.mm",
+	"field-week-relative+-1": "sidste uge",
+	"dateFormat-medium": "d. MMM y G",
+	"dateFormatItem-Hms": "HH.mm.ss",
+	"field-year-relative+0": "i år",
+	"field-year-relative+1": "næste år",
+	"field-year-relative+-1": "sidste år",
+	"dateFormatItem-ms": "mm.ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-year": "år",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "uge",
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"dateFormatItem-MMMMEd": "E d. MMMM",
+	"dateFormatItem-yyyyMEd": "E d/M/y G",
+	"dateFormatItem-MMMd": "d. MMM",
+	"field-week-relative+0": "denne uge",
+	"field-week-relative+1": "næste uge",
+	"field-month-relative+0": "denne måned",
+	"dateFormatItem-H": "HH",
+	"field-month": "måned",
+	"field-month-relative+1": "næste måned",
+	"dateFormatItem-M": "M",
+	"field-second": "sekund",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "dag",
+	"dateFormatItem-MEd": "E d/M",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "h.mm a",
+	"dateFormat-short": "d/M/y",
+	"dateFormatItem-yyyyM": "M/y G",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d.",
+	"field-month-relative+-1": "sidste måned",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/gregorian.js b/dojo/cldr/nls/da/gregorian.js
index 5735714..9cc8e6c 100644
--- a/dojo/cldr/nls/da/gregorian.js
+++ b/dojo/cldr/nls/da/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"sø",
+		"ma",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lø"
+	],
 	"months-format-narrow": [
 		"J",
 		"F",
@@ -15,14 +24,31 @@ define(
 		"N",
 		"D"
 	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "ugedag",
 	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "EEE. d/M/y",
-	"dateFormatItem-MMMEd": "E d MMM",
+	"dateFormatItem-yMEd": "E d/M/y",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-MMMEd": "E d. MMM",
 	"eraNarrow": [
 		"f.Kr.",
 		"e.Kr."
 	],
+	"dateFormatItem-yMM": "MM/y",
+	"days-format-short": [
+		"sø",
+		"ma",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lø"
+	],
 	"dateFormat-long": "d. MMM y",
 	"months-format-wide": [
 		"januar",
@@ -38,9 +64,12 @@ define(
 		"november",
 		"december"
 	],
-	"dayPeriods-format-wide-pm": "e.m.",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
 	"dateFormat-full": "EEEE 'den' d. MMMM y",
 	"dateFormatItem-Md": "d/M",
+	"dayPeriods-format-wide-noon": "middag",
+	"dateFormatItem-yMd": "d/M/y",
 	"field-era": "æra",
 	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
@@ -64,10 +93,10 @@ define(
 		"3. kvartal",
 		"4. kvartal"
 	],
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-long": "HH.mm.ss z",
 	"field-year": "år",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "Q yyyy",
 	"field-hour": "time",
 	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
@@ -84,13 +113,12 @@ define(
 		"nov.",
 		"dec."
 	],
-	"dateFormatItem-yyQ": "Q. 'kvartal' yy",
 	"timeFormat-full": "HH.mm.ss zzzz",
 	"field-day-relative+0": "i dag",
 	"field-day-relative+1": "i morgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
 	"field-day-relative+2": "i overmorgen",
 	"dateFormatItem-H": "HH",
-	"field-day-relative+3": "i overovermorgen",
 	"months-standAlone-abbr": [
 		"jan",
 		"feb",
@@ -117,6 +145,7 @@ define(
 		"3. kvartal",
 		"4. kvartal"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "M",
 	"days-standAlone-wide": [
 		"søndag",
@@ -127,8 +156,7 @@ define(
 		"fredag",
 		"lørdag"
 	],
-	"dateFormatItem-yyyyMMM": "MMM y",
-	"dateFormatItem-yyMMM": "MMM yy",
+	"dayPeriods-format-abbr-noon": "middag",
 	"timeFormat-medium": "HH.mm.ss",
 	"dateFormatItem-Hm": "HH.mm",
 	"quarters-standAlone-abbr": [
@@ -154,11 +182,19 @@ define(
 	],
 	"dateFormatItem-d": "d.",
 	"dateFormatItem-ms": "mm.ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "i går",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
 	"field-day-relative+-2": "i forgårs",
-	"field-day-relative+-3": "i forforgårs",
 	"dateFormatItem-MMMd": "d. MMM",
-	"dateFormatItem-MEd": "E. d/M",
+	"dateFormatItem-MEd": "E d/M",
+	"dateTimeFormat-full": "{1} {0}",
 	"field-day": "dag",
 	"days-format-wide": [
 		"søndag",
@@ -169,8 +205,7 @@ define(
 		"fredag",
 		"lørdag"
 	],
-	"field-zone": "zone",
-	"dateFormatItem-yyyyMM": "MM/yyyy",
+	"field-zone": "tidszone",
 	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
 		"J",
@@ -186,17 +221,19 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-yyMM": "MM/yy",
+	"field-year-relative+-1": "sidste år",
+	"field-month-relative+-1": "sidste måned",
 	"dateFormatItem-hm": "h.mm a",
 	"days-format-abbr": [
-		"søn",
-		"man",
-		"tir",
-		"ons",
-		"tor",
-		"fre",
-		"lør"
+		"søn.",
+		"man.",
+		"tir.",
+		"ons.",
+		"tor.",
+		"fre.",
+		"lør."
 	],
+	"dateFormatItem-yMMMd": "d. MMM y",
 	"eraNames": [
 		"f.Kr.",
 		"e.Kr."
@@ -210,7 +247,6 @@ define(
 		"F",
 		"L"
 	],
-	"field-month": "måned",
 	"days-standAlone-narrow": [
 		"S",
 		"M",
@@ -221,17 +257,27 @@ define(
 		"L"
 	],
 	"dateFormatItem-MMM": "MMM",
-	"dayPeriods-format-wide-am": "f.m.",
-	"dateFormatItem-MMMMEd": "E, d. MMMM",
+	"field-month": "måned",
+	"dayPeriods-format-wide-am": "AM",
+	"dateFormatItem-MMMMEd": "E d. MMMM",
 	"dateFormat-short": "dd/MM/yy",
+	"dayPeriods-format-narrow-noon": "middag",
 	"field-second": "sekund",
-	"dateFormatItem-yMMMEd": "EEE. d. MMM y",
-	"dateFormatItem-Ed": "E d.",
+	"dateFormatItem-yMMMEd": "E d. MMM y",
+	"field-month-relative+0": "denne måned",
+	"field-month-relative+1": "næste måned",
+	"dateFormatItem-Ed": "E 'd'. d.",
 	"field-week": "uge",
-	"dateFormat-medium": "dd/MM/yyyy",
+	"dateFormat-medium": "dd/MM/y",
+	"field-year-relative+0": "i år",
+	"field-week-relative+-1": "sidste uge",
+	"field-year-relative+1": "næste år",
+	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "HH.mm.ss",
 	"dateFormatItem-hms": "h.mm.ss a",
-	"dateFormatItem-yyyy": "y"
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "denne uge",
+	"field-week-relative+1": "næste uge"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/hebrew.js b/dojo/cldr/nls/da/hebrew.js
new file mode 100644
index 0000000..62b3eda
--- /dev/null
+++ b/dojo/cldr/nls/da/hebrew.js
@@ -0,0 +1,165 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"sø",
+		"ma",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lø"
+	],
+	"field-weekday": "ugedag",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"days-format-short": [
+		"sø",
+		"ma",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lø"
+	],
+	"dateFormat-long": "d. MMMM y G",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dateFormatItem-yyyyMEd": "E d/M/y G",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "æra",
+	"timeFormat-short": "HH.mm",
+	"quarters-format-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"timeFormat-long": "HH.mm.ss z",
+	"field-year": "år",
+	"field-hour": "time",
+	"timeFormat-full": "HH.mm.ss zzzz",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"field-day-relative+2": "i overmorgen",
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"quarters-standAlone-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"dateFormatItem-M": "M",
+	"days-standAlone-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"timeFormat-medium": "HH.mm.ss",
+	"dateFormatItem-Hm": "HH.mm",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"eraAbbr": [
+		"AM"
+	],
+	"field-minute": "minut",
+	"field-dayperiod": "dagtid",
+	"days-standAlone-abbr": [
+		"søn",
+		"man",
+		"tir",
+		"ons",
+		"tor",
+		"fre",
+		"lør"
+	],
+	"dateFormatItem-d": "d.",
+	"dateFormatItem-ms": "mm.ss",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i forgårs",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-MEd": "E d/M",
+	"field-day": "dag",
+	"days-format-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	],
+	"field-zone": "tidszone",
+	"dateFormatItem-y": "y G",
+	"field-year-relative+-1": "sidste år",
+	"field-month-relative+-1": "sidste måned",
+	"dateFormatItem-hm": "h.mm a",
+	"days-format-abbr": [
+		"søn.",
+		"man.",
+		"tir.",
+		"ons.",
+		"tor.",
+		"fre.",
+		"lør."
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"field-month": "måned",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormatItem-MMM": "MMM",
+	"dateFormat-short": "d/M/y",
+	"field-second": "sekund",
+	"field-month-relative+0": "denne måned",
+	"field-month-relative+1": "næste måned",
+	"dateFormatItem-Ed": "E 'd'. d.",
+	"field-week": "uge",
+	"dateFormat-medium": "d. MMM y G",
+	"field-year-relative+0": "i år",
+	"field-week-relative+-1": "sidste uge",
+	"dateFormatItem-yyyyM": "M/y G",
+	"field-year-relative+1": "næste år",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-Hms": "HH.mm.ss",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "denne uge",
+	"field-week-relative+1": "næste uge"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/islamic.js b/dojo/cldr/nls/da/islamic.js
index 64cb44f..808b890 100644
--- a/dojo/cldr/nls/da/islamic.js
+++ b/dojo/cldr/nls/da/islamic.js
@@ -1,51 +1,88 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M/y",
-	"dateFormatItem-yyyyMMMEd": "EEE. d. MMM y G",
-	"dateFormatItem-yQ": "Q yyyy",
-	"dayPeriods-format-wide-pm": "e.m.",
+	"days-standAlone-short": [
+		"sø",
+		"ma",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lø"
+	],
+	"field-weekday": "ugedag",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
 	"dateFormatItem-MMMEd": "E d. MMM",
-	"dateFormatItem-hms": "h.mm.ss a",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-MMdd": "dd/MM",
-	"dateFormatItem-MMM": "MMM",
-	"dayPeriods-format-wide-am": "f.m.",
-	"timeFormat-full": "HH.mm.ss zzzz",
-	"dateFormatItem-yyyy": "y G",
-	"dateFormatItem-Ed": "E d.",
-	"dateFormatItem-yMMM": "MMM y",
-	"days-standAlone-narrow": [
-		"S",
-		"M",
-		"T",
-		"O",
-		"T",
-		"F",
-		"L"
+	"days-format-short": [
+		"sø",
+		"ma",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lø"
 	],
 	"dateFormat-long": "d. MMMM y G",
-	"timeFormat-medium": "HH.mm.ss",
-	"dateFormatItem-Hm": "HH.mm",
-	"dateFormatItem-yyMM": "MM/y G",
-	"dateFormat-medium": "d. MMM y G",
-	"dateFormatItem-Hms": "HH.mm.ss",
-	"dateFormatItem-yyMMM": "MMM y G",
-	"dateFormatItem-ms": "mm.ss",
-	"dateFormatItem-MMMMEd": "E, d. MMMM",
-	"dateFormatItem-yyyyMEd": "EEE. d/M/y G",
-	"dateFormatItem-MMMd": "d. MMM",
-	"dateFormatItem-yyQ": "Q. 'kvartal' y G",
-	"timeFormat-long": "HH.mm.ss z",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dateFormatItem-yyyyMEd": "E d/M/y G",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "æra",
 	"timeFormat-short": "HH.mm",
-	"dateFormatItem-H": "HH",
+	"quarters-format-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"timeFormat-long": "HH.mm.ss z",
+	"field-year": "år",
+	"field-hour": "time",
+	"timeFormat-full": "HH.mm.ss zzzz",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"field-day-relative+2": "i overmorgen",
 	"quarters-format-abbr": [
 		"K1",
 		"K2",
 		"K3",
 		"K4"
 	],
-	"days-format-abbr": [
+	"quarters-standAlone-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"dateFormatItem-M": "M",
+	"days-standAlone-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"timeFormat-medium": "HH.mm.ss",
+	"dateFormatItem-Hm": "HH.mm",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"field-minute": "minut",
+	"field-dayperiod": "dagtid",
+	"days-standAlone-abbr": [
 		"søn",
 		"man",
 		"tir",
@@ -54,25 +91,13 @@ define(
 		"fre",
 		"lør"
 	],
-	"dateFormatItem-M": "M",
-	"dateFormatItem-yyyyQQQ": "QQQ y G",
-	"dateFormatItem-MEd": "E. d/M",
-	"dateFormatItem-hm": "h.mm a",
-	"dateFormat-short": "d/M/y G",
-	"dateFormatItem-yyyyM": "M/y G",
-	"dateFormatItem-yMMMEd": "EEE. d. MMM y",
-	"dateFormat-full": "EEEE d. MMMM y G",
-	"dateFormatItem-Md": "d/M",
-	"dateFormatItem-yyyyQ": "Q y G",
-	"dateFormatItem-yMEd": "EEE. d/M/y",
-	"dateFormatItem-yyyyMMM": "MMM y G",
 	"dateFormatItem-d": "d.",
-	"quarters-format-wide": [
-		"1. kvartal",
-		"2. kvartal",
-		"3. kvartal",
-		"4. kvartal"
-	],
+	"dateFormatItem-ms": "mm.ss",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i forgårs",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-MEd": "E d/M",
+	"field-day": "dag",
 	"days-format-wide": [
 		"søndag",
 		"mandag",
@@ -81,7 +106,60 @@ define(
 		"torsdag",
 		"fredag",
 		"lørdag"
-	]
+	],
+	"field-zone": "tidszone",
+	"dateFormatItem-y": "y G",
+	"field-year-relative+-1": "sidste år",
+	"field-month-relative+-1": "sidste måned",
+	"dateFormatItem-hm": "h.mm a",
+	"days-format-abbr": [
+		"søn.",
+		"man.",
+		"tir.",
+		"ons.",
+		"tor.",
+		"fre.",
+		"lør."
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"field-month": "måned",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormatItem-MMM": "MMM",
+	"dateFormat-short": "d/M/y",
+	"field-second": "sekund",
+	"field-month-relative+0": "denne måned",
+	"field-month-relative+1": "næste måned",
+	"dateFormatItem-Ed": "E 'd'. d.",
+	"field-week": "uge",
+	"dateFormat-medium": "d. MMM y G",
+	"field-year-relative+0": "i år",
+	"field-week-relative+-1": "sidste uge",
+	"dateFormatItem-yyyyM": "M/y G",
+	"field-year-relative+1": "næste år",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-Hms": "HH.mm.ss",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "denne uge",
+	"field-week-relative+1": "næste uge"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/japanese.js b/dojo/cldr/nls/da/japanese.js
new file mode 100644
index 0000000..52dd9a0
--- /dev/null
+++ b/dojo/cldr/nls/da/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d. MMM y G",
+	"field-second": "sekund",
+	"field-year-relative+-1": "sidste år",
+	"field-week": "uge",
+	"field-month-relative+-1": "sidste måned",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i forgårs",
+	"field-year": "år",
+	"field-week-relative+0": "denne uge",
+	"field-week-relative+1": "næste uge",
+	"field-minute": "minut",
+	"field-week-relative+-1": "sidste uge",
+	"field-day-relative+0": "i dag",
+	"field-hour": "time",
+	"field-day-relative+1": "i morgen",
+	"dateFormat-long": "d. MMMM y G",
+	"field-day-relative+2": "i overmorgen",
+	"field-day": "dag",
+	"field-month-relative+0": "denne måned",
+	"field-month-relative+1": "næste måned",
+	"field-dayperiod": "dagtid",
+	"field-month": "måned",
+	"dateFormat-short": "d/M/y",
+	"field-era": "æra",
+	"field-year-relative+0": "i år",
+	"field-year-relative+1": "næste år",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"field-weekday": "ugedag",
+	"field-zone": "tidszone"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/number.js b/dojo/cldr/nls/da/number.js
index 36148ce..a82eb10 100644
--- a/dojo/cldr/nls/da/number.js
+++ b/dojo/cldr/nls/da/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0 %",
 	"list": ",",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 billioner",
+	"decimalFormat-short": "000 bill"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/roc.js b/dojo/cldr/nls/da/roc.js
new file mode 100644
index 0000000..324b4c0
--- /dev/null
+++ b/dojo/cldr/nls/da/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "sekund",
+	"field-year-relative+-1": "sidste år",
+	"field-week": "uge",
+	"field-month-relative+-1": "sidste måned",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i forgårs",
+	"field-year": "år",
+	"field-week-relative+0": "denne uge",
+	"field-week-relative+1": "næste uge",
+	"field-minute": "minut",
+	"field-week-relative+-1": "sidste uge",
+	"field-day-relative+0": "i dag",
+	"field-hour": "time",
+	"field-day-relative+1": "i morgen",
+	"field-day-relative+2": "i overmorgen",
+	"field-day": "dag",
+	"field-month-relative+0": "denne måned",
+	"field-month-relative+1": "næste måned",
+	"field-dayperiod": "dagtid",
+	"field-month": "måned",
+	"field-era": "æra",
+	"field-year-relative+0": "i år",
+	"field-year-relative+1": "næste år",
+	"eraAbbr": [
+		"Before R.O.C.",
+		"Minguo"
+	],
+	"field-weekday": "ugedag",
+	"field-zone": "tidszone"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/dangi.js b/dojo/cldr/nls/dangi.js
new file mode 100644
index 0000000..91cd7b2
--- /dev/null
+++ b/dojo/cldr/nls/dangi.js
@@ -0,0 +1,420 @@
+define({ root:
+
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-weekday": "Day of the Week",
+	"dayPeriods-format-abbr at localeAlias130": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"quarters at localeAlias118": {
+		"bundle": "chinese",
+		"target": "quarters"
+	},
+	"quarters at localeAlias119": {
+		"bundle": "gregorian",
+		"target": "quarters"
+	},
+	"dateFormatItem-GyMMMEd": "U MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "U MMMM d",
+	"months-format-wide": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"dateFormatItem-yyyyQQQ": "U QQQ",
+	"dateTimeFormat-medium": "{1} {0}",
+	"months-format-narrow at localeAlias102": {
+		"bundle": "chinese",
+		"target": "months-standAlone-narrow"
+	},
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "U MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "y-MM-dd, E",
+	"dateFormatItem-Md": "MM-dd",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"dateFormatItem-yMd": "y-MM-dd",
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
+	"months-format-abbr": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "U MMM d",
+	"months-standAlone-abbr": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"dateFormatItem-H": "HH",
+	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Gy": "U",
+	"days-standAlone-wide at localeAlias117": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateFormatItem-yyyyMMMEd": "U MMM d, E",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-yyyyMMM": "U MMM",
+	"dateFormatItem-yyyyMMMd": "U MMM d",
+	"days-format-short at localeAlias110": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-format-short at localeAlias111": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateFormat at localeAlias133": {
+		"bundle": "chinese",
+		"target": "dateFormat"
+	},
+	"timeFormat-medium": "HH:mm:ss",
+	"dayPeriods-format-narrow at localeAlias128": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias129": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Hm": "HH:mm",
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"timeFormat at localeAlias134": {
+		"bundle": "chinese",
+		"target": "timeFormat"
+	},
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"timeFormat at localeAlias135": {
+		"bundle": "gregorian",
+		"target": "timeFormat"
+	},
+	"field-day-relative+-1": "Yesterday",
+	"days-standAlone-abbr at localeAlias112": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"dayPeriods-format-narrow-am": "AM",
+	"dateTimeFormat-long": "{1} {0}",
+	"dateFormatItem-h": "h a",
+	"days-standAlone-abbr at localeAlias113": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-standAlone-short at localeAlias114": {
+		"bundle": "gregorian",
+		"target": "days-format-short"
+	},
+	"days-standAlone-short at localeAlias115": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-standAlone-short at localeAlias116": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-format-abbr at localeAlias108": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateFormatItem-MMMd": "MMM d",
+	"dayPeriods-format-narrow at localeAlias131": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dateFormatItem-MEd": "MM-dd, E",
+	"dayPeriods-format-narrow at localeAlias132": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"days-format-narrow at localeAlias109": {
+		"bundle": "gregorian",
+		"target": "days-standAlone-narrow"
+	},
+	"dayPeriods at localeAlias125": {
+		"bundle": "chinese",
+		"target": "dayPeriods"
+	},
+	"field-zone": "Zone",
+	"dayPeriods at localeAlias126": {
+		"bundle": "gregorian",
+		"target": "dayPeriods"
+	},
+	"days at localeAlias106": {
+		"bundle": "chinese",
+		"target": "days"
+	},
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-y": "U",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"days at localeAlias107": {
+		"bundle": "gregorian",
+		"target": "days"
+	},
+	"quarters-standAlone-wide at localeAlias124": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months at localeAlias100": {
+		"bundle": "chinese",
+		"target": "months"
+	},
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-yyyyMd": "y-MM-dd",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormat-short": "y-MM-dd",
+	"months-standAlone-wide at localeAlias105": {
+		"bundle": "chinese",
+		"target": "months-format-wide"
+	},
+	"field-second": "Second",
+	"quarters-standAlone-abbr at localeAlias122": {
+		"bundle": "gregorian",
+		"target": "quarters-format-abbr"
+	},
+	"quarters-standAlone-abbr at localeAlias123": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateFormatItem-Ed": "d, E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"dateTime at localeAlias136": {
+		"bundle": "chinese",
+		"target": "dateTime"
+	},
+	"field-week": "Week",
+	"dateFormat-medium": "U MMM d",
+	"quarters-format-narrow at localeAlias121": {
+		"bundle": "gregorian",
+		"target": "quarters-standAlone-narrow"
+	},
+	"quarters-format-abbr at localeAlias120": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateFormatItem-yyyyM": "y-MM",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dayPeriods-format-abbr at localeAlias127": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormatItem-yyyyQQQQ": "U QQQQ",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "U MMM",
+	"months-standAlone-abbr at localeAlias103": {
+		"bundle": "chinese",
+		"target": "months-format-abbr"
+	},
+	"dateFormatItem-yyyy": "U",
+	"months-standAlone-abbr at localeAlias104": {
+		"bundle": "chinese",
+		"target": "months-format-wide"
+	},
+	"months-format-abbr at localeAlias101": {
+		"bundle": "chinese",
+		"target": "months-format-wide"
+	}
+}
+//end v1.x content
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/buddhist.js b/dojo/cldr/nls/de/buddhist.js
index 3202129..10b8f7d 100644
--- a/dojo/cldr/nls/de/buddhist.js
+++ b/dojo/cldr/nls/de/buddhist.js
@@ -1,14 +1,23 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M.y G",
-	"dateFormatItem-yyMMdd": "dd.MM.y G",
-	"dateFormatItem-yQ": "Q y G",
+	"field-dayperiod": "Tageshälfte",
+	"dateFormatItem-yyyyMMMEd": "E, d. MMM y G",
 	"dayPeriods-format-wide-pm": "nachm.",
+	"field-minute": "Minute",
 	"dateFormatItem-MMMEd": "E, d. MMM",
-	"dateFormatItem-yQQQ": "QQQ y G",
-	"dateFormatItem-MMdd": "dd.MM.",
-	"dateFormatItem-MMM": "LLL",
+	"field-day-relative+-1": "Gestern",
+	"field-weekday": "Wochentag",
+	"field-day-relative+-2": "Vorgestern",
+	"days-standAlone-wide": [
+		"Sonntag",
+		"Montag",
+		"Dienstag",
+		"Mittwoch",
+		"Donnerstag",
+		"Freitag",
+		"Samstag"
+	],
 	"months-standAlone-narrow": [
 		"J",
 		"F",
@@ -23,6 +32,9 @@ define(
 		"N",
 		"D"
 	],
+	"field-era": "Epoche",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Stunde",
 	"dayPeriods-format-wide-am": "vorm.",
 	"dateFormatItem-y": "y G",
 	"dateFormatItem-yyyy": "y G",
@@ -40,8 +52,9 @@ define(
 		"Nov",
 		"Dez"
 	],
-	"dateFormatItem-Ed": "E d.",
-	"dateFormatItem-yMMM": "MMM y G",
+	"dateFormatItem-Ed": "E, d.",
+	"field-day-relative+0": "Heute",
+	"field-day-relative+1": "Morgen",
 	"days-standAlone-narrow": [
 		"S",
 		"M",
@@ -51,32 +64,64 @@ define(
 		"F",
 		"S"
 	],
-	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"eraAbbr": [
+		"BE"
+	],
+	"field-day-relative+2": "Übermorgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
 	"dateFormat-long": "d. MMMM y G",
-	"dateFormatItem-Hm": "HH:mm",
-	"dateFormatItem-MMd": "d.MM.",
-	"dateFormatItem-yyMM": "MM.y G",
-	"dateFormat-medium": "d. MMM y G",
-	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-yyMMM": "MMM y G",
-	"dateFormatItem-yyQQQQ": "QQQQ y G",
-	"dateFormatItem-ms": "mm:ss",
+	"field-zone": "Zone",
+	"field-week-relative+-1": "Letzte Woche",
+	"dateFormat-medium": "dd.MM.y G",
+	"field-year-relative+0": "Dieses Jahr",
+	"field-year-relative+1": "Nächstes Jahr",
+	"quarters-standAlone-wide": [
+		"1. Quartal",
+		"2. Quartal",
+		"3. Quartal",
+		"4. Quartal"
+	],
+	"field-year-relative+-1": "Letztes Jahr",
+	"field-year": "Jahr",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-week": "Woche",
+	"months-standAlone-wide": [
+		"Januar",
+		"Februar",
+		"März",
+		"April",
+		"Mai",
+		"Juni",
+		"Juli",
+		"August",
+		"September",
+		"Oktober",
+		"November",
+		"Dezember"
+	],
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"dateFormatItem-yyyyMd": "d.M.y GGGGG",
+	"dateFormatItem-yyyyMEd": "E, d.M.y GGGGG",
+	"field-week-relative+0": "Diese Woche",
 	"dateFormatItem-MMMd": "d. MMM",
-	"dateFormatItem-yyQ": "Q y G",
+	"field-week-relative+1": "Nächste Woche",
 	"months-format-abbr": [
-		"Jan",
-		"Feb",
-		"Mär",
-		"Apr",
+		"Jan.",
+		"Feb.",
+		"Mär.",
+		"Apr.",
 		"Mai",
-		"Jun",
-		"Jul",
-		"Aug",
-		"Sep",
-		"Okt",
-		"Nov",
-		"Dez"
+		"Juni",
+		"Juli",
+		"Aug.",
+		"Sep.",
+		"Okt.",
+		"Nov.",
+		"Dez."
 	],
+	"field-month-relative+0": "Dieser Monat",
+	"field-month": "Monat",
+	"field-month-relative+1": "Nächster Monat",
 	"dateFormatItem-H": "HH 'Uhr'",
 	"days-format-abbr": [
 		"So.",
@@ -87,14 +132,57 @@ define(
 		"Fr.",
 		"Sa."
 	],
-	"dateFormatItem-MMMMdd": "dd. MMMM",
-	"dateFormatItem-M": "L",
+	"days-format-narrow": [
+		"S",
+		"M",
+		"D",
+		"M",
+		"D",
+		"F",
+		"S"
+	],
+	"field-second": "Sekunde",
+	"dateFormatItem-GyMMMEd": "E, d. MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Tag",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
 	"dateFormatItem-MEd": "E, d.M.",
-	"dateFormat-short": "d.M.yyyy",
-	"dateFormatItem-yMMMEd": "EEE, d. MMM y G",
-	"dateFormat-full": "EEEE d. MMMM y G",
+	"months-format-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"days-standAlone-short": [
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
+		"Sa."
+	],
+	"days-standAlone-abbr": [
+		"So",
+		"Mo",
+		"Di",
+		"Mi",
+		"Do",
+		"Fr",
+		"Sa"
+	],
+	"dateFormat-short": "dd.MM.yy GGGGG",
+	"dateFormatItem-yyyyM": "M.y GGGGG",
+	"dateFormat-full": "EEEE, d. MMMM y G",
 	"dateFormatItem-Md": "d.M.",
-	"dateFormatItem-yMEd": "EEE, d.M.y G",
 	"months-format-wide": [
 		"Januar",
 		"Februar",
@@ -109,7 +197,17 @@ define(
 		"November",
 		"Dezember"
 	],
-	"dateFormatItem-d": "d",
+	"days-format-short": [
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
+		"Sa."
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "Letzter Monat",
 	"quarters-format-wide": [
 		"1. Quartal",
 		"2. Quartal",
diff --git a/dojo/cldr/nls/de/chinese.js b/dojo/cldr/nls/de/chinese.js
new file mode 100644
index 0000000..9e55c64
--- /dev/null
+++ b/dojo/cldr/nls/de/chinese.js
@@ -0,0 +1,65 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d. MMM U",
+	"field-dayperiod": "Tageshälfte",
+	"field-minute": "Minute",
+	"dateFormatItem-MMMEd": "E, d. MMM",
+	"field-day-relative+-1": "Gestern",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "Vorgestern",
+	"field-weekday": "Wochentag",
+	"dateFormatItem-MMM": "LLL",
+	"field-era": "Epoche",
+	"dateFormatItem-Gy": "U",
+	"field-hour": "Stunde",
+	"dateFormatItem-y": "U",
+	"dateFormatItem-yyyy": "U",
+	"dateFormatItem-Ed": "E, d.",
+	"field-day-relative+0": "Heute",
+	"field-day-relative+1": "Morgen",
+	"field-day-relative+2": "Übermorgen",
+	"dateFormatItem-yyyyMMMM": "MMMM U",
+	"dateFormatItem-GyMMMd": "d. MMM U",
+	"dateFormat-long": "d. MMMM U",
+	"field-zone": "Zone",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Letzte Woche",
+	"dateFormat-medium": "dd.MM U",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Dieses Jahr",
+	"field-year-relative+1": "Nächstes Jahr",
+	"field-year-relative+-1": "Letztes Jahr",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ U",
+	"field-year": "Jahr",
+	"field-week": "Woche",
+	"dateFormatItem-yyyyMd": "d.M.y",
+	"dateFormatItem-yyyyMMMd": "d. MMM U",
+	"dateFormatItem-yyyyMEd": "E, d.M.y",
+	"dateFormatItem-MMMd": "d. MMM",
+	"field-week-relative+0": "Diese Woche",
+	"field-week-relative+1": "Nächste Woche",
+	"field-month-relative+0": "Dieser Monat",
+	"dateFormatItem-H": "HH 'Uhr'",
+	"field-month": "Monat",
+	"field-month-relative+1": "Nächster Monat",
+	"dateFormatItem-M": "L",
+	"field-second": "Sekunde",
+	"dateFormatItem-GyMMMEd": "E, d. MMM U",
+	"dateFormatItem-GyMMM": "MMM U",
+	"field-day": "Tag",
+	"dateFormatItem-yyyyQQQ": "QQQ U",
+	"dateFormatItem-MEd": "E, d.M.",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd.MM.yy",
+	"dateFormatItem-yyyyM": "M.y",
+	"dateFormat-full": "EEEE, d. MMMM U",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yyyyMMM": "MMM U",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Letzter Monat",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/currency.js b/dojo/cldr/nls/de/currency.js
index 225e1ab..d28f390 100644
--- a/dojo/cldr/nls/de/currency.js
+++ b/dojo/cldr/nls/de/currency.js
@@ -5,12 +5,18 @@ define(
 	"CHF_displayName": "Schweizer Franken",
 	"JPY_symbol": "¥",
 	"CAD_displayName": "Kanadischer Dollar",
+	"HKD_symbol": "HK$",
 	"CNY_displayName": "Renminbi Yuan",
 	"USD_symbol": "$",
 	"AUD_displayName": "Australischer Dollar",
-	"JPY_displayName": "Yen",
+	"JPY_displayName": "Japanische Yen",
+	"CAD_symbol": "CA$",
 	"USD_displayName": "US-Dollar",
-	"GBP_displayName": "Pfund Sterling",
+	"EUR_symbol": "€",
+	"CNY_symbol": "CN¥",
+	"GBP_displayName": "Britisches Pfund Sterling",
+	"GBP_symbol": "£",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "Euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/de/generic.js b/dojo/cldr/nls/de/generic.js
new file mode 100644
index 0000000..4a8578f
--- /dev/null
+++ b/dojo/cldr/nls/de/generic.js
@@ -0,0 +1,69 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d. MMM y G",
+	"field-dayperiod": "Tageshälfte",
+	"field-minute": "Minute",
+	"dateFormatItem-MMMEd": "E, d. MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "Gestern",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "Vorgestern",
+	"field-weekday": "Wochentag",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "Epoche",
+	"field-hour": "Stunde",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E, d.",
+	"field-day-relative+0": "Heute",
+	"field-day-relative+1": "Morgen",
+	"field-day-relative+2": "Übermorgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormat-long": "d. MMMM y G",
+	"field-zone": "Zone",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Letzte Woche",
+	"dateFormat-medium": "dd.MM.y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Dieses Jahr",
+	"field-year-relative+1": "Nächstes Jahr",
+	"field-year-relative+-1": "Letztes Jahr",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-year": "Jahr",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "Woche",
+	"dateFormatItem-yyyyMd": "d.M.y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"dateFormatItem-yyyyMEd": "E, d.M.y GGGGG",
+	"dateFormatItem-MMMd": "d. MMM",
+	"field-week-relative+0": "Diese Woche",
+	"field-week-relative+1": "Nächste Woche",
+	"field-month-relative+0": "Dieser Monat",
+	"dateFormatItem-H": "HH 'Uhr'",
+	"field-month": "Monat",
+	"field-month-relative+1": "Nächster Monat",
+	"dateFormatItem-M": "L",
+	"field-second": "Sekunde",
+	"dateFormatItem-GyMMMEd": "E, d. MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Tag",
+	"dateFormatItem-MEd": "E, d.M.",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd.MM.yy GGGGG",
+	"dateFormatItem-yyyyM": "M.y GGGGG",
+	"dateFormat-full": "EEEE, d. MMMM y G",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Letzter Monat",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/gregorian.js b/dojo/cldr/nls/de/gregorian.js
index 22997c3..099a91c 100644
--- a/dojo/cldr/nls/de/gregorian.js
+++ b/dojo/cldr/nls/de/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
+		"Sa."
+	],
 	"months-format-narrow": [
 		"J",
 		"F",
@@ -15,17 +24,33 @@ define(
 		"N",
 		"D"
 	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "Wochentag",
-	"dateFormatItem-yyQQQQ": "QQQQ yy",
 	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "EEE, d.M.y",
+	"dateFormatItem-yMEd": "E, d.M.y",
+	"dateFormatItem-GyMMMEd": "E, d. MMM y G",
 	"dateFormatItem-MMMEd": "E, d. MMM",
 	"eraNarrow": [
 		"v. Chr.",
 		"n. Chr."
 	],
+	"dateFormatItem-yMM": "MM.y",
 	"dayPeriods-format-wide-earlyMorning": "morgens",
 	"dayPeriods-format-wide-morning": "vormittags",
+	"days-format-short": [
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
+		"Sa."
+	],
 	"dateFormat-long": "d. MMMM y",
 	"months-format-wide": [
 		"Januar",
@@ -42,11 +67,12 @@ define(
 		"Dezember"
 	],
 	"dayPeriods-format-wide-evening": "abends",
+	"dateTimeFormat-medium": "{1} {0}",
 	"dayPeriods-format-wide-pm": "nachm.",
 	"dateFormat-full": "EEEE, d. MMMM y",
 	"dateFormatItem-Md": "d.M.",
-	"dateFormatItem-yyMMdd": "dd.MM.yy",
 	"dayPeriods-format-wide-noon": "Mittag",
+	"dateFormatItem-yMd": "d.M.y",
 	"field-era": "Epoche",
 	"dateFormatItem-yM": "M.y",
 	"months-standAlone-wide": [
@@ -70,34 +96,32 @@ define(
 		"3. Quartal",
 		"4. Quartal"
 	],
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-long": "HH:mm:ss z",
 	"field-year": "Jahr",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "Q y",
-	"dateFormatItem-yyyyMMMM": "MMMM y",
 	"field-hour": "Stunde",
 	"dateFormatItem-MMdd": "dd.MM.",
 	"months-format-abbr": [
-		"Jan",
-		"Feb",
-		"Mär",
-		"Apr",
+		"Jan.",
+		"Feb.",
+		"Mär.",
+		"Apr.",
 		"Mai",
-		"Jun",
-		"Jul",
-		"Aug",
-		"Sep",
-		"Okt",
-		"Nov",
-		"Dez"
+		"Juni",
+		"Juli",
+		"Aug.",
+		"Sep.",
+		"Okt.",
+		"Nov.",
+		"Dez."
 	],
-	"dateFormatItem-yyQ": "Q yy",
 	"timeFormat-full": "HH:mm:ss zzzz",
-	"field-day-relative+0": "heute",
-	"field-day-relative+1": "morgen",
-	"field-day-relative+2": "übermorgen",
+	"field-day-relative+0": "Heute",
+	"field-day-relative+1": "Morgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"field-day-relative+2": "Übermorgen",
 	"dateFormatItem-H": "HH 'Uhr'",
-	"field-day-relative+3": "überübermorgen",
 	"months-standAlone-abbr": [
 		"Jan",
 		"Feb",
@@ -124,6 +148,7 @@ define(
 		"3. Quartal",
 		"4. Quartal"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
 		"Sonntag",
@@ -134,9 +159,15 @@ define(
 		"Freitag",
 		"Samstag"
 	],
-	"dateFormatItem-yyMMM": "MMM yy",
 	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-yMMdd": "dd.MM.y",
 	"dateFormatItem-Hm": "HH:mm",
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
 	"eraAbbr": [
 		"v. Chr.",
 		"n. Chr."
@@ -144,22 +175,31 @@ define(
 	"field-minute": "Minute",
 	"field-dayperiod": "Tageshälfte",
 	"days-standAlone-abbr": [
-		"So.",
-		"Mo.",
-		"Di.",
-		"Mi.",
-		"Do.",
-		"Fr.",
-		"Sa."
+		"So",
+		"Mo",
+		"Di",
+		"Mi",
+		"Do",
+		"Fr",
+		"Sa"
 	],
 	"dayPeriods-format-wide-night": "nachts",
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
-	"field-day-relative+-1": "gestern",
-	"field-day-relative+-2": "vorgestern",
-	"field-day-relative+-3": "vorvorgestern",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Gestern",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-day-relative+-2": "Vorgestern",
 	"dateFormatItem-MMMd": "d. MMM",
 	"dateFormatItem-MEd": "E, d.M.",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-yMMMM": "MMMM y",
 	"field-day": "Tag",
 	"days-format-wide": [
 		"Sonntag",
@@ -186,7 +226,9 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-yyMM": "MM.yy",
+	"field-year-relative+-1": "Letztes Jahr",
+	"field-month-relative+-1": "Letzter Monat",
+	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
 		"So.",
 		"Mo.",
@@ -200,6 +242,7 @@ define(
 		"v. Chr.",
 		"n. Chr."
 	],
+	"dateFormatItem-yMMMd": "d. MMM y",
 	"days-format-narrow": [
 		"S",
 		"M",
@@ -209,7 +252,6 @@ define(
 		"F",
 		"S"
 	],
-	"field-month": "Monat",
 	"days-standAlone-narrow": [
 		"S",
 		"M",
@@ -220,18 +262,29 @@ define(
 		"S"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "Monat",
 	"dayPeriods-format-wide-am": "vorm.",
+	"dateFormatItem-MMMMEd": "E, d. MMMM",
 	"dateFormatItem-MMMMdd": "dd. MMMM",
 	"dateFormat-short": "dd.MM.yy",
 	"dateFormatItem-MMd": "d.MM.",
 	"dayPeriods-format-wide-afternoon": "nachmittags",
 	"field-second": "Sekunde",
-	"dateFormatItem-yMMMEd": "EEE, d. MMM y",
+	"dateFormatItem-yMMMEd": "E, d. MMM y",
+	"field-month-relative+0": "Dieser Monat",
+	"field-month-relative+1": "Nächster Monat",
 	"dateFormatItem-Ed": "E, d.",
 	"field-week": "Woche",
-	"dateFormat-medium": "dd.MM.yyyy",
+	"dateFormat-medium": "dd.MM.y",
+	"field-year-relative+0": "Dieses Jahr",
+	"field-week-relative+-1": "Letzte Woche",
+	"field-year-relative+1": "Nächstes Jahr",
+	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-yyyy": "y"
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "Diese Woche",
+	"field-week-relative+1": "Nächste Woche"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/hebrew.js b/dojo/cldr/nls/de/hebrew.js
new file mode 100644
index 0000000..277687d
--- /dev/null
+++ b/dojo/cldr/nls/de/hebrew.js
@@ -0,0 +1,144 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "Tageshälfte",
+	"dateFormatItem-yyyyMMMEd": "E, d. MMM y G",
+	"dayPeriods-format-wide-pm": "nachm.",
+	"field-minute": "Minute",
+	"dateFormatItem-MMMEd": "E, d. MMM",
+	"field-day-relative+-1": "Gestern",
+	"field-weekday": "Wochentag",
+	"field-day-relative+-2": "Vorgestern",
+	"days-standAlone-wide": [
+		"Sonntag",
+		"Montag",
+		"Dienstag",
+		"Mittwoch",
+		"Donnerstag",
+		"Freitag",
+		"Samstag"
+	],
+	"field-era": "Epoche",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Stunde",
+	"dayPeriods-format-wide-am": "vorm.",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E, d.",
+	"field-day-relative+0": "Heute",
+	"field-day-relative+1": "Morgen",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"D",
+		"M",
+		"D",
+		"F",
+		"S"
+	],
+	"eraAbbr": [
+		"AM"
+	],
+	"field-day-relative+2": "Übermorgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"dateFormat-long": "d. MMMM y G",
+	"field-zone": "Zone",
+	"field-week-relative+-1": "Letzte Woche",
+	"dateFormat-medium": "dd.MM.y G",
+	"field-year-relative+0": "Dieses Jahr",
+	"field-year-relative+1": "Nächstes Jahr",
+	"quarters-standAlone-wide": [
+		"1. Quartal",
+		"2. Quartal",
+		"3. Quartal",
+		"4. Quartal"
+	],
+	"field-year-relative+-1": "Letztes Jahr",
+	"field-year": "Jahr",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-week": "Woche",
+	"dateFormatItem-yyyyMd": "d.M.y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"dateFormatItem-yyyyMEd": "E, d.M.y GGGGG",
+	"dateFormatItem-MMMd": "d. MMM",
+	"field-week-relative+0": "Diese Woche",
+	"field-week-relative+1": "Nächste Woche",
+	"field-month-relative+0": "Dieser Monat",
+	"field-month": "Monat",
+	"field-month-relative+1": "Nächster Monat",
+	"dateFormatItem-H": "HH 'Uhr'",
+	"days-format-abbr": [
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
+		"Sa."
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"D",
+		"M",
+		"D",
+		"F",
+		"S"
+	],
+	"field-second": "Sekunde",
+	"dateFormatItem-GyMMMEd": "E, d. MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Tag",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E, d.M.",
+	"days-standAlone-short": [
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
+		"Sa."
+	],
+	"days-standAlone-abbr": [
+		"So",
+		"Mo",
+		"Di",
+		"Mi",
+		"Do",
+		"Fr",
+		"Sa"
+	],
+	"dateFormat-short": "dd.MM.yy GGGGG",
+	"dateFormatItem-yyyyM": "M.y GGGGG",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormat-full": "EEEE, d. MMMM y G",
+	"days-format-short": [
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
+		"Sa."
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "Letzter Monat",
+	"quarters-format-wide": [
+		"1. Quartal",
+		"2. Quartal",
+		"3. Quartal",
+		"4. Quartal"
+	],
+	"days-format-wide": [
+		"Sonntag",
+		"Montag",
+		"Dienstag",
+		"Mittwoch",
+		"Donnerstag",
+		"Freitag",
+		"Samstag"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/islamic.js b/dojo/cldr/nls/de/islamic.js
index 07b9110..bce443a 100644
--- a/dojo/cldr/nls/de/islamic.js
+++ b/dojo/cldr/nls/de/islamic.js
@@ -1,50 +1,32 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M.y",
-	"dateFormatItem-yyyyMMMEd": "EEE, d. MMM y G",
-	"dateFormatItem-yyMMdd": "dd.MM.y G",
-	"dateFormatItem-yQ": "Q y",
+	"field-dayperiod": "Tageshälfte",
+	"dateFormatItem-yyyyMMMEd": "E, d. MMM y G",
 	"dayPeriods-format-wide-pm": "nachm.",
-	"eraNames": [
-		"AH"
-	],
+	"field-minute": "Minute",
 	"dateFormatItem-MMMEd": "E, d. MMM",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-MMdd": "dd.MM.",
-	"dateFormatItem-MMM": "LLL",
-	"months-standAlone-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+	"field-day-relative+-1": "Gestern",
+	"field-weekday": "Wochentag",
+	"field-day-relative+-2": "Vorgestern",
+	"days-standAlone-wide": [
+		"Sonntag",
+		"Montag",
+		"Dienstag",
+		"Mittwoch",
+		"Donnerstag",
+		"Freitag",
+		"Samstag"
 	],
+	"field-era": "Epoche",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Stunde",
 	"dayPeriods-format-wide-am": "vorm.",
+	"dateFormatItem-y": "y G",
 	"dateFormatItem-yyyy": "y G",
-	"months-standAlone-abbr": [
-		"Muh.",
-		"Saf.",
-		"Rab. I",
-		"Rab. II",
-		"Jum. I",
-		"Jum. II",
-		"Raj.",
-		"Sha.",
-		"Ram.",
-		"Shaw.",
-		"Dhuʻl-Q.",
-		"Dhuʻl-H."
-	],
-	"dateFormatItem-Ed": "E d.",
-	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-Ed": "E, d.",
+	"field-day-relative+0": "Heute",
+	"field-day-relative+1": "Morgen",
 	"days-standAlone-narrow": [
 		"S",
 		"M",
@@ -57,49 +39,34 @@ define(
 	"eraAbbr": [
 		"AH"
 	],
-	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"field-day-relative+2": "Übermorgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
 	"dateFormat-long": "d. MMMM y G",
-	"dateFormatItem-Hm": "HH:mm",
-	"dateFormatItem-MMd": "d.MM.",
-	"dateFormatItem-yyMM": "MM.y G",
-	"dateFormat-medium": "d. MMM y G",
-	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-yyMMM": "MMM y G",
-	"dateFormatItem-yyQQQQ": "QQQQ y G",
-	"dateFormatItem-ms": "mm:ss",
-	"months-standAlone-wide": [
-		"Muharram",
-		"Safar",
-		"Rabiʻ I",
-		"Rabiʻ II",
-		"Jumada I",
-		"Jumada II",
-		"Rajab",
-		"Shaʻban",
-		"Ramadan",
-		"Shawwal",
-		"Dhuʻl-Qiʻdah",
-		"Dhuʻl-Hijjah"
+	"field-zone": "Zone",
+	"field-week-relative+-1": "Letzte Woche",
+	"dateFormat-medium": "dd.MM.y G",
+	"field-year-relative+0": "Dieses Jahr",
+	"field-year-relative+1": "Nächstes Jahr",
+	"quarters-standAlone-wide": [
+		"1. Quartal",
+		"2. Quartal",
+		"3. Quartal",
+		"4. Quartal"
 	],
-	"dateFormatItem-yyyyMEd": "EEE, d.M.y G",
+	"field-year-relative+-1": "Letztes Jahr",
+	"field-year": "Jahr",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-week": "Woche",
+	"dateFormatItem-yyyyMd": "d.M.y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"dateFormatItem-yyyyMEd": "E, d.M.y GGGGG",
+	"field-week-relative+0": "Diese Woche",
 	"dateFormatItem-MMMd": "d. MMM",
-	"dateFormatItem-yyQ": "Q y G",
-	"months-format-abbr": [
-		"Muh.",
-		"Saf.",
-		"Rab. I",
-		"Rab. II",
-		"Jum. I",
-		"Jum. II",
-		"Raj.",
-		"Sha.",
-		"Ram.",
-		"Shaw.",
-		"Dhuʻl-Q.",
-		"Dhuʻl-H."
-	],
+	"field-week-relative+1": "Nächste Woche",
+	"field-month-relative+0": "Dieser Monat",
+	"field-month": "Monat",
+	"field-month-relative+1": "Nächster Monat",
 	"dateFormatItem-H": "HH 'Uhr'",
-	"dateFormatItem-MMMMdd": "dd. MMMM",
 	"days-format-abbr": [
 		"So.",
 		"Mo.",
@@ -109,55 +76,60 @@ define(
 		"Fr.",
 		"Sa."
 	],
-	"dateFormatItem-M": "L",
-	"dateFormatItem-MEd": "E, d.M.",
+	"days-format-narrow": [
+		"S",
+		"M",
+		"D",
+		"M",
+		"D",
+		"F",
+		"S"
+	],
+	"field-second": "Sekunde",
+	"dateFormatItem-GyMMMEd": "E, d. MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Tag",
 	"dateFormatItem-yyyyQQQ": "QQQ y G",
-	"months-format-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+	"dateFormatItem-MEd": "E, d.M.",
+	"days-standAlone-short": [
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
+		"Sa."
 	],
-	"dateFormat-short": "d.M.y G",
-	"dateFormatItem-yyyyM": "M.y G",
-	"dateFormatItem-yMMMEd": "EEE, d. MMM y",
-	"dateFormat-full": "EEEE d. MMMM y G",
+	"days-standAlone-abbr": [
+		"So",
+		"Mo",
+		"Di",
+		"Mi",
+		"Do",
+		"Fr",
+		"Sa"
+	],
+	"dateFormat-short": "dd.MM.yy GGGGG",
+	"dateFormatItem-yyyyM": "M.y GGGGG",
+	"dateFormat-full": "EEEE, d. MMMM y G",
 	"dateFormatItem-Md": "d.M.",
-	"dateFormatItem-yyyyQ": "Q y G",
-	"dateFormatItem-yMEd": "EEE, d.M.y",
-	"months-format-wide": [
-		"Muharram",
-		"Safar",
-		"Rabiʻ I",
-		"Rabiʻ II",
-		"Jumada I",
-		"Jumada II",
-		"Rajab",
-		"Shaʻban",
-		"Ramadan",
-		"Shawwal",
-		"Dhuʻl-Qiʻdah",
-		"Dhuʻl-Hijjah"
+	"days-format-short": [
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
+		"Sa."
 	],
 	"dateFormatItem-yyyyMMM": "MMM y G",
-	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Letzter Monat",
 	"quarters-format-wide": [
 		"1. Quartal",
 		"2. Quartal",
 		"3. Quartal",
 		"4. Quartal"
 	],
-	"eraNarrow": [
-		"AH"
-	],
 	"days-format-wide": [
 		"Sonntag",
 		"Montag",
diff --git a/dojo/cldr/nls/de/japanese.js b/dojo/cldr/nls/de/japanese.js
new file mode 100644
index 0000000..b85ad90
--- /dev/null
+++ b/dojo/cldr/nls/de/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "dd.MM.y G",
+	"field-second": "Sekunde",
+	"field-year-relative+-1": "Letztes Jahr",
+	"field-week": "Woche",
+	"field-month-relative+-1": "Letzter Monat",
+	"field-day-relative+-1": "Gestern",
+	"field-day-relative+-2": "Vorgestern",
+	"field-year": "Jahr",
+	"field-week-relative+0": "Diese Woche",
+	"field-week-relative+1": "Nächste Woche",
+	"field-minute": "Minute",
+	"field-week-relative+-1": "Letzte Woche",
+	"field-day-relative+0": "Heute",
+	"field-hour": "Stunde",
+	"field-day-relative+1": "Morgen",
+	"dateFormat-long": "d. MMMM y G",
+	"field-day-relative+2": "Übermorgen",
+	"field-day": "Tag",
+	"field-month-relative+0": "Dieser Monat",
+	"field-month-relative+1": "Nächster Monat",
+	"field-dayperiod": "Tageshälfte",
+	"field-month": "Monat",
+	"dateFormat-short": "dd.MM.yy GGGGG",
+	"field-era": "Epoche",
+	"field-year-relative+0": "Dieses Jahr",
+	"field-year-relative+1": "Nächstes Jahr",
+	"dateFormat-full": "EEEE, d. MMMM y G",
+	"field-weekday": "Wochentag",
+	"field-zone": "Zone"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/number.js b/dojo/cldr/nls/de/number.js
index 5634e80..c2d93ae 100644
--- a/dojo/cldr/nls/de/number.js
+++ b/dojo/cldr/nls/de/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0 %",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 Billionen",
+	"decimalFormat-short": "000 Bio"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/roc.js b/dojo/cldr/nls/de/roc.js
new file mode 100644
index 0000000..debceb7
--- /dev/null
+++ b/dojo/cldr/nls/de/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Sekunde",
+	"field-year-relative+-1": "Letztes Jahr",
+	"field-week": "Woche",
+	"field-month-relative+-1": "Letzter Monat",
+	"field-day-relative+-1": "Gestern",
+	"field-day-relative+-2": "Vorgestern",
+	"field-year": "Jahr",
+	"field-week-relative+0": "Diese Woche",
+	"field-week-relative+1": "Nächste Woche",
+	"field-minute": "Minute",
+	"field-week-relative+-1": "Letzte Woche",
+	"field-day-relative+0": "Heute",
+	"field-hour": "Stunde",
+	"field-day-relative+1": "Morgen",
+	"field-day-relative+2": "Übermorgen",
+	"field-day": "Tag",
+	"field-month-relative+0": "Dieser Monat",
+	"field-month-relative+1": "Nächster Monat",
+	"field-dayperiod": "Tageshälfte",
+	"field-month": "Monat",
+	"field-era": "Epoche",
+	"field-year-relative+0": "Dieses Jahr",
+	"field-year-relative+1": "Nächstes Jahr",
+	"eraAbbr": [
+		"Before R.O.C.",
+		"Minguo"
+	],
+	"field-weekday": "Wochentag",
+	"field-zone": "Zone"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/buddhist.js b/dojo/cldr/nls/el/buddhist.js
index bc2fcfb..addf542 100644
--- a/dojo/cldr/nls/el/buddhist.js
+++ b/dojo/cldr/nls/el/buddhist.js
@@ -1,18 +1,25 @@
 define(
 //begin v1.x content
 {
-	"quarters-format-abbr": [
-		"Τ1",
-		"Τ2",
-		"Τ3",
-		"Τ4"
-	],
-	"dateFormat-medium": "d MMM, y G",
+	"dateFormatItem-yM": "M/y",
+	"field-dayperiod": "π.μ./μ.μ.",
+	"dayPeriods-format-wide-pm": "μ.μ.",
+	"field-minute": "Λεπτό",
 	"dateFormatItem-MMMEd": "E, d MMM",
-	"dateFormatItem-MEd": "E, d/M",
-	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
-	"timeFormat-full": "h:mm:ss a zzzz",
-	"dateFormatItem-Md": "d/M",
+	"dateTimeFormat-full": "{1} - {0}",
+	"field-day-relative+-1": "Χτες",
+	"field-weekday": "Ημέρα εβδομάδας",
+	"field-day-relative+-2": "Προχτές",
+	"days-standAlone-wide": [
+		"Κυριακή",
+		"Δευτέρα",
+		"Τρίτη",
+		"Τετάρτη",
+		"Πέμπτη",
+		"Παρασκευή",
+		"Σάββατο"
+	],
+	"dateFormatItem-MMM": "LLL",
 	"months-standAlone-narrow": [
 		"Ι",
 		"Φ",
@@ -27,6 +34,66 @@ define(
 		"Ν",
 		"Δ"
 	],
+	"dateTimeFormat-short": "{1} - {0}",
+	"field-era": "Περίοδος",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Ώρα",
+	"dayPeriods-format-wide-am": "π.μ.",
+	"dateTimeFormat-medium": "{1} - {0}",
+	"quarters-standAlone-abbr": [
+		"Τ1",
+		"Τ2",
+		"Τ3",
+		"Τ4"
+	],
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"months-standAlone-abbr": [
+		"Ιαν",
+		"Φεβ",
+		"Μάρ",
+		"Απρ",
+		"Μάι",
+		"Ιούν",
+		"Ιούλ",
+		"Αύγ",
+		"Σεπ",
+		"Οκτ",
+		"Νοέ",
+		"Δεκ"
+	],
+	"dateFormatItem-Ed": "E d",
+	"dateFormatItem-yMMM": "LLL, y G",
+	"field-day-relative+0": "Σήμερα",
+	"field-day-relative+1": "Αύριο",
+	"days-standAlone-narrow": [
+		"Κ",
+		"Δ",
+		"Τ",
+		"Τ",
+		"Π",
+		"Π",
+		"Σ"
+	],
+	"field-day-relative+2": "Μεθαύριο",
+	"dateFormat-long": "d MMMM, y G",
+	"timeFormat-medium": "h:mm:ss a",
+	"field-zone": "Ζώνη",
+	"field-week-relative+-1": "Προηγούμενη εβδομάδα",
+	"dateFormat-medium": "d MMM, y G",
+	"field-year-relative+0": "Φέτος",
+	"field-year-relative+1": "Επόμενο έτος",
+	"dateFormatItem-yMd": "d/M/y",
+	"quarters-standAlone-wide": [
+		"1ο τρίμηνο",
+		"2ο τρίμηνο",
+		"3ο τρίμηνο",
+		"4ο τρίμηνο"
+	],
+	"field-year-relative+-1": "Προηγούμενο έτος",
+	"field-year": "Έτος",
+	"dateTimeFormat-long": "{1} - {0}",
+	"field-week": "Εβδομάδα",
 	"months-standAlone-wide": [
 		"Ιανουάριος",
 		"Φεβρουάριος",
@@ -41,8 +108,44 @@ define(
 		"Νοέμβριος",
 		"Δεκέμβριος"
 	],
-	"dateFormatItem-EEEd": "EEE d",
-	"days-standAlone-narrow": [
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Αυτήν την εβδομάδα",
+	"field-week-relative+1": "Επόμενη εβδομάδα",
+	"timeFormat-long": "h:mm:ss a z",
+	"months-format-abbr": [
+		"Ιαν",
+		"Φεβ",
+		"Μαρ",
+		"Απρ",
+		"Μαϊ",
+		"Ιουν",
+		"Ιουλ",
+		"Αυγ",
+		"Σεπ",
+		"Οκτ",
+		"Νοε",
+		"Δεκ"
+	],
+	"field-month-relative+0": "Τρέχων μήνας",
+	"field-month": "Μήνας",
+	"field-month-relative+1": "Επόμενος μήνας",
+	"timeFormat-short": "h:mm a",
+	"quarters-format-abbr": [
+		"Τ1",
+		"Τ2",
+		"Τ3",
+		"Τ4"
+	],
+	"days-format-abbr": [
+		"Κυρ",
+		"Δευ",
+		"Τρί",
+		"Τετ",
+		"Πέμ",
+		"Παρ",
+		"Σάβ"
+	],
+	"days-format-narrow": [
 		"Κ",
 		"Δ",
 		"Τ",
@@ -51,12 +154,47 @@ define(
 		"Π",
 		"Σ"
 	],
-	"dayPeriods-format-wide-pm": "μ.μ.",
-	"dayPeriods-format-wide-am": "π.μ.",
-	"timeFormat-medium": "h:mm:ss a",
-	"dateFormat-long": "d MMMM, y G",
-	"dateFormat-short": "d/M/yyyy",
-	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"dateFormatItem-yMMMd": "d MMM, y G",
+	"field-second": "Δευτερόλεπτο",
+	"field-day": "Ημέρα",
+	"dateFormatItem-MEd": "E, d/M",
+	"months-format-narrow": [
+		"Ι",
+		"Φ",
+		"Μ",
+		"Α",
+		"Μ",
+		"Ι",
+		"Ι",
+		"Α",
+		"Σ",
+		"Ο",
+		"Ν",
+		"Δ"
+	],
+	"days-standAlone-short": [
+		"Κυ",
+		"Δε",
+		"Τρ",
+		"Τε",
+		"Πε",
+		"Πα",
+		"Σα"
+	],
+	"days-standAlone-abbr": [
+		"Κυρ",
+		"Δευ",
+		"Τρί",
+		"Τετ",
+		"Πέμ",
+		"Παρ",
+		"Σάβ"
+	],
+	"dateFormat-short": "d/M/y",
+	"dateFormatItem-yMMMEd": "E, d MMM, y G",
+	"dateFormat-full": "EEEE, d MMMM, y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMEd": "E, d/M/y",
 	"months-format-wide": [
 		"Ιανουαρίου",
 		"Φεβρουαρίου",
@@ -71,23 +209,22 @@ define(
 		"Νοεμβρίου",
 		"Δεκεμβρίου"
 	],
-	"dateFormatItem-yM": "M/yyyy",
-	"timeFormat-short": "h:mm a",
-	"months-format-abbr": [
-		"Ιαν",
-		"Φεβ",
-		"Μαρ",
-		"Απρ",
-		"Μαϊ",
-		"Ιουν",
-		"Ιουλ",
-		"Αυγ",
-		"Σεπ",
-		"Οκτ",
-		"Νοε",
-		"Δεκ"
+	"days-format-short": [
+		"Κυ",
+		"Δε",
+		"Τρ",
+		"Τε",
+		"Πε",
+		"Πα",
+		"Σα"
+	],
+	"field-month-relative+-1": "Προηγούμενος μήνας",
+	"quarters-format-wide": [
+		"1ο τρίμηνο",
+		"2ο τρίμηνο",
+		"3ο τρίμηνο",
+		"4ο τρίμηνο"
 	],
-	"timeFormat-long": "h:mm:ss a z",
 	"days-format-wide": [
 		"Κυριακή",
 		"Δευτέρα",
@@ -96,24 +233,6 @@ define(
 		"Πέμπτη",
 		"Παρασκευή",
 		"Σάββατο"
-	],
-	"dateFormatItem-yMMM": "LLL y",
-	"quarters-format-wide": [
-		"1ο τρίμηνο",
-		"2ο τρίμηνο",
-		"3ο τρίμηνο",
-		"4ο τρίμηνο"
-	],
-	"dateFormat-full": "EEEE, d MMMM, y G",
-	"dateFormatItem-MMMd": "d MMM",
-	"days-format-abbr": [
-		"Κυρ",
-		"Δευ",
-		"Τρι",
-		"Τετ",
-		"Πεμ",
-		"Παρ",
-		"Σαβ"
 	]
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/el/currency.js b/dojo/cldr/nls/el/currency.js
index 454ab1a..4d61d01 100644
--- a/dojo/cldr/nls/el/currency.js
+++ b/dojo/cldr/nls/el/currency.js
@@ -5,6 +5,7 @@ define(
 	"CHF_displayName": "Φράγκο Ελβετίας",
 	"CAD_displayName": "Δολάριο Καναδά",
 	"CNY_displayName": "Γιουάν Ρενμίμπι Κίνας",
+	"USD_symbol": "$",
 	"AUD_displayName": "Δολάριο Αυστραλίας",
 	"JPY_displayName": "Γιεν Ιαπωνίας",
 	"USD_displayName": "Δολάριο ΗΠΑ",
diff --git a/dojo/cldr/nls/el/generic.js b/dojo/cldr/nls/el/generic.js
new file mode 100644
index 0000000..65aa368
--- /dev/null
+++ b/dojo/cldr/nls/el/generic.js
@@ -0,0 +1,72 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M/y",
+	"field-dayperiod": "π.μ./μ.μ.",
+	"field-minute": "Λεπτό",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"dateTimeFormat-full": "{1} - {0}",
+	"field-day-relative+-1": "Χτες",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-MMdd": "dd/MM",
+	"dateFormatItem-yQQQ": "y QQQ",
+	"field-day-relative+-2": "Προχτές",
+	"field-weekday": "Ημέρα εβδομάδας",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} - {0}",
+	"dateTimeFormat-medium": "{1} - {0}",
+	"field-era": "Περίοδος",
+	"field-hour": "Ώρα",
+	"dateFormatItem-y": "y",
+	"dateFormatItem-yMM": "MM/y",
+	"dateFormatItem-Ed": "E d",
+	"dateFormatItem-yMMM": "LLL y",
+	"field-day-relative+0": "Σήμερα",
+	"field-day-relative+1": "Αύριο",
+	"field-day-relative+2": "Μεθαύριο",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Ζώνη",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Προηγούμενη εβδομάδα",
+	"dateFormat-medium": "d MMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Φέτος",
+	"field-year-relative+1": "Επόμενο έτος",
+	"dateFormatItem-yMd": "d/M/y",
+	"field-year-relative+-1": "Προηγούμενο έτος",
+	"dateFormatItem-yMMMM": "LLLL y",
+	"dateFormatItem-ms": "mm:ss",
+	"field-year": "Έτος",
+	"dateTimeFormat-long": "{1} - {0}",
+	"dateFormatItem-HHmmss": "HH:mm:ss",
+	"field-week": "Εβδομάδα",
+	"dateFormatItem-MMMMEd": "E, d MMMM",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Αυτήν την εβδομάδα",
+	"dateFormatItem-HHmm": "HH:mm",
+	"field-week-relative+1": "Επόμενη εβδομάδα",
+	"dateFormatItem-yQQQQ": "y QQQQ",
+	"field-month-relative+0": "Τρέχων μήνας",
+	"dateFormatItem-H": "HH",
+	"field-month": "Μήνας",
+	"field-month-relative+1": "Επόμενος μήνας",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-MMMMdd": "dd MMMM",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateFormatItem-M": "L",
+	"dateFormatItem-yMMMd": "d MMM y",
+	"field-second": "Δευτερόλεπτο",
+	"field-day": "Ημέρα",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "d/M/yy GGGGG",
+	"dateFormatItem-yMMMEd": "E, d MMM y",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMEd": "E, d/M/y",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Προηγούμενος μήνας",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/gregorian.js b/dojo/cldr/nls/el/gregorian.js
index 8e86c15..2cf2ccf 100644
--- a/dojo/cldr/nls/el/gregorian.js
+++ b/dojo/cldr/nls/el/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"Κυ",
+		"Δε",
+		"Τρ",
+		"Τε",
+		"Πε",
+		"Πα",
+		"Σα"
+	],
 	"months-format-narrow": [
 		"Ι",
 		"Φ",
@@ -15,15 +24,30 @@ define(
 		"Ν",
 		"Δ"
 	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "Ημέρα εβδομάδας",
-	"dateFormatItem-yyQQQQ": "QQQQ yy",
 	"dateFormatItem-yQQQ": "y QQQ",
-	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
+	"dateFormatItem-yMEd": "E, d/M/y",
 	"dateFormatItem-MMMEd": "E, d MMM",
 	"eraNarrow": [
 		"π.Χ.",
 		"μ.Χ."
 	],
+	"dateFormatItem-yMM": "MM/y",
+	"days-format-short": [
+		"Κυ",
+		"Δε",
+		"Τρ",
+		"Τε",
+		"Πε",
+		"Πα",
+		"Σα"
+	],
 	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
 		"Ιανουαρίου",
@@ -39,12 +63,13 @@ define(
 		"Νοεμβρίου",
 		"Δεκεμβρίου"
 	],
-	"dateFormatItem-EEEd": "EEE d",
+	"dateTimeFormat-medium": "{1} - {0}",
 	"dayPeriods-format-wide-pm": "μ.μ.",
 	"dateFormat-full": "EEEE, d MMMM y",
 	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMd": "d/M/y",
 	"field-era": "Περίοδος",
-	"dateFormatItem-yM": "M/yyyy",
+	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
 		"Ιανουάριος",
 		"Φεβρουάριος",
@@ -66,11 +91,10 @@ define(
 		"3ο τρίμηνο",
 		"4ο τρίμηνο"
 	],
+	"dateFormatItem-yQQQQ": "y QQQQ",
 	"timeFormat-long": "h:mm:ss a z",
 	"field-year": "Έτος",
 	"dateFormatItem-yMMM": "LLL y",
-	"dateFormatItem-yQ": "y Q",
-	"dateFormatItem-yyyyMMMM": "LLLL y",
 	"field-hour": "Ώρα",
 	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
@@ -87,25 +111,23 @@ define(
 		"Νοε",
 		"Δεκ"
 	],
-	"dateFormatItem-yyQ": "Q yy",
 	"timeFormat-full": "h:mm:ss a zzzz",
 	"field-day-relative+0": "Σήμερα",
 	"field-day-relative+1": "Αύριο",
 	"field-day-relative+2": "Μεθαύριο",
 	"dateFormatItem-H": "HH",
-	"field-day-relative+3": "Σε τρεις ημέρες από τώρα",
 	"months-standAlone-abbr": [
 		"Ιαν",
 		"Φεβ",
-		"Μαρ",
+		"Μάρ",
 		"Απρ",
-		"Μαϊ",
-		"Ιουν",
-		"Ιουλ",
-		"Αυγ",
+		"Μάι",
+		"Ιούν",
+		"Ιούλ",
+		"Αύγ",
 		"Σεπ",
 		"Οκτ",
-		"Νοε",
+		"Νοέ",
 		"Δεκ"
 	],
 	"quarters-format-abbr": [
@@ -132,7 +154,6 @@ define(
 		"Σάββατο"
 	],
 	"dateFormatItem-MMMMd": "d MMMM",
-	"dateFormatItem-yyMMM": "LLL yy",
 	"timeFormat-medium": "h:mm:ss a",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -150,19 +171,28 @@ define(
 	"days-standAlone-abbr": [
 		"Κυρ",
 		"Δευ",
-		"Τρι",
+		"Τρί",
 		"Τετ",
-		"Πεμ",
+		"Πέμ",
 		"Παρ",
-		"Σαβ"
+		"Σάβ"
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
-	"field-day-relative+-1": "Χθες",
-	"field-day-relative+-2": "Προχθές",
-	"field-day-relative+-3": "Πριν από τρεις ημέρες",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Χτες",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} - {0}",
+	"field-day-relative+-2": "Προχτές",
 	"dateFormatItem-MMMd": "d MMM",
 	"dateFormatItem-MEd": "E, d/M",
+	"dateTimeFormat-full": "{1} - {0}",
+	"dateFormatItem-yMMMM": "LLLL y",
 	"field-day": "Ημέρα",
 	"days-format-wide": [
 		"Κυριακή",
@@ -174,7 +204,6 @@ define(
 		"Σάββατο"
 	],
 	"field-zone": "Ζώνη",
-	"dateFormatItem-yyyyMM": "MM/yyyy",
 	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
 		"Ι",
@@ -190,16 +219,19 @@ define(
 		"Ν",
 		"Δ"
 	],
-	"dateFormatItem-yyMM": "MM/yy",
+	"field-year-relative+-1": "Προηγούμενο έτος",
+	"field-month-relative+-1": "Προηγούμενος μήνας",
+	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
 		"Κυρ",
 		"Δευ",
-		"Τρι",
+		"Τρί",
 		"Τετ",
-		"Πεμ",
+		"Πέμ",
 		"Παρ",
-		"Σαβ"
+		"Σάβ"
 	],
+	"dateFormatItem-yMMMd": "d MMM y",
 	"eraNames": [
 		"π.Χ.",
 		"μ.Χ."
@@ -213,7 +245,6 @@ define(
 		"Π",
 		"Σ"
 	],
-	"field-month": "Μήνας",
 	"days-standAlone-narrow": [
 		"Κ",
 		"Δ",
@@ -224,18 +255,28 @@ define(
 		"Σ"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "Μήνας",
 	"dateFormatItem-HHmm": "HH:mm",
 	"dayPeriods-format-wide-am": "π.μ.",
 	"dateFormatItem-MMMMEd": "E, d MMMM",
 	"dateFormatItem-MMMMdd": "dd MMMM",
 	"dateFormat-short": "d/M/yy",
 	"field-second": "Δευτερόλεπτο",
-	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"dateFormatItem-yMMMEd": "E, d MMM y",
+	"field-month-relative+0": "Τρέχων μήνας",
+	"field-month-relative+1": "Επόμενος μήνας",
 	"dateFormatItem-Ed": "E d",
 	"field-week": "Εβδομάδα",
 	"dateFormat-medium": "d MMM y",
+	"field-year-relative+0": "Φέτος",
+	"field-week-relative+-1": "Προηγούμενη εβδομάδα",
+	"field-year-relative+1": "Επόμενο έτος",
 	"dateFormatItem-mmss": "mm:ss",
-	"dateFormatItem-yyyy": "y"
+	"dateTimeFormat-short": "{1} - {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-week-relative+0": "Αυτήν την εβδομάδα",
+	"field-week-relative+1": "Επόμενη εβδομάδα"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/hebrew.js b/dojo/cldr/nls/el/hebrew.js
index f5dea6c..9310de5 100644
--- a/dojo/cldr/nls/el/hebrew.js
+++ b/dojo/cldr/nls/el/hebrew.js
@@ -1,25 +1,42 @@
 define(
 //begin v1.x content
 {
-	"quarters-format-abbr": [
+	"field-dayperiod": "π.μ./μ.μ.",
+	"dayPeriods-format-wide-pm": "μ.μ.",
+	"field-minute": "Λεπτό",
+	"eraNames": [
+		"π.μ."
+	],
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"dateTimeFormat-full": "{1} - {0}",
+	"field-day-relative+-1": "Χτες",
+	"field-weekday": "Ημέρα εβδομάδας",
+	"field-day-relative+-2": "Προχτές",
+	"days-standAlone-wide": [
+		"Κυριακή",
+		"Δευτέρα",
+		"Τρίτη",
+		"Τετάρτη",
+		"Πέμπτη",
+		"Παρασκευή",
+		"Σάββατο"
+	],
+	"dateTimeFormat-short": "{1} - {0}",
+	"field-era": "Περίοδος",
+	"field-hour": "Ώρα",
+	"dayPeriods-format-wide-am": "π.μ.",
+	"dateTimeFormat-medium": "{1} - {0}",
+	"quarters-standAlone-abbr": [
 		"Τ1",
 		"Τ2",
 		"Τ3",
 		"Τ4"
 	],
-	"dateFormat-medium": "d MMM y",
-	"dateFormatItem-MMMEd": "E, d MMM",
-	"dateFormatItem-MEd": "E, d/M",
-	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
-	"eraNarrow": [
-		"π.μ."
-	],
+	"dateFormatItem-y": "y",
 	"timeFormat-full": "h:mm:ss a zzzz",
-	"dateFormatItem-Md": "d/M",
-	"dateFormatItem-EEEd": "EEE d",
-	"eraNames": [
-		"π.μ."
-	],
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "Σήμερα",
+	"field-day-relative+1": "Αύριο",
 	"days-standAlone-narrow": [
 		"Κ",
 		"Δ",
@@ -29,44 +46,110 @@ define(
 		"Π",
 		"Σ"
 	],
-	"dayPeriods-format-wide-pm": "μ.μ.",
-	"dayPeriods-format-wide-am": "π.μ.",
-	"timeFormat-medium": "h:mm:ss a",
-	"dateFormat-long": "d MMMM y",
-	"dateFormat-short": "d/M/yy",
-	"dateFormatItem-yMMMEd": "EEE, d MMM y",
-	"dateFormatItem-yM": "M/yyyy",
-	"timeFormat-short": "h:mm a",
 	"eraAbbr": [
 		"π.μ."
 	],
-	"timeFormat-long": "h:mm:ss a z",
-	"days-format-wide": [
-		"Κυριακή",
-		"Δευτέρα",
-		"Τρίτη",
-		"Τετάρτη",
-		"Πέμπτη",
-		"Παρασκευή",
-		"Σάββατο"
-	],
-	"dateFormatItem-yMMM": "LLL y",
-	"quarters-format-wide": [
+	"field-day-relative+2": "Μεθαύριο",
+	"dateFormat-long": "d MMMM y G",
+	"timeFormat-medium": "h:mm:ss a",
+	"field-zone": "Ζώνη",
+	"field-week-relative+-1": "Προηγούμενη εβδομάδα",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Φέτος",
+	"field-year-relative+1": "Επόμενο έτος",
+	"quarters-standAlone-wide": [
 		"1ο τρίμηνο",
 		"2ο τρίμηνο",
 		"3ο τρίμηνο",
 		"4ο τρίμηνο"
 	],
-	"dateFormat-full": "EEEE, d MMMM y",
+	"field-year-relative+-1": "Προηγούμενο έτος",
+	"field-year": "Έτος",
+	"dateTimeFormat-long": "{1} - {0}",
+	"field-week": "Εβδομάδα",
 	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Αυτήν την εβδομάδα",
+	"field-week-relative+1": "Επόμενη εβδομάδα",
+	"timeFormat-long": "h:mm:ss a z",
+	"field-month-relative+0": "Τρέχων μήνας",
+	"field-month": "Μήνας",
+	"field-month-relative+1": "Επόμενος μήνας",
+	"timeFormat-short": "h:mm a",
+	"quarters-format-abbr": [
+		"Τ1",
+		"Τ2",
+		"Τ3",
+		"Τ4"
+	],
 	"days-format-abbr": [
 		"Κυρ",
 		"Δευ",
-		"Τρι",
+		"Τρί",
+		"Τετ",
+		"Πέμ",
+		"Παρ",
+		"Σάβ"
+	],
+	"days-format-narrow": [
+		"Κ",
+		"Δ",
+		"Τ",
+		"Τ",
+		"Π",
+		"Π",
+		"Σ"
+	],
+	"field-second": "Δευτερόλεπτο",
+	"field-day": "Ημέρα",
+	"dateFormatItem-MEd": "E, d/M",
+	"days-standAlone-short": [
+		"Κυ",
+		"Δε",
+		"Τρ",
+		"Τε",
+		"Πε",
+		"Πα",
+		"Σα"
+	],
+	"days-standAlone-abbr": [
+		"Κυρ",
+		"Δευ",
+		"Τρί",
 		"Τετ",
-		"Πεμ",
+		"Πέμ",
 		"Παρ",
-		"Σαβ"
+		"Σάβ"
+	],
+	"dateFormat-short": "d/M/yy GGGGG",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"days-format-short": [
+		"Κυ",
+		"Δε",
+		"Τρ",
+		"Τε",
+		"Πε",
+		"Πα",
+		"Σα"
+	],
+	"field-month-relative+-1": "Προηγούμενος μήνας",
+	"quarters-format-wide": [
+		"1ο τρίμηνο",
+		"2ο τρίμηνο",
+		"3ο τρίμηνο",
+		"4ο τρίμηνο"
+	],
+	"eraNarrow": [
+		"π.μ."
+	],
+	"days-format-wide": [
+		"Κυριακή",
+		"Δευτέρα",
+		"Τρίτη",
+		"Τετάρτη",
+		"Πέμπτη",
+		"Παρασκευή",
+		"Σάββατο"
 	]
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/el/japanese.js b/dojo/cldr/nls/el/japanese.js
new file mode 100644
index 0000000..ef277a5
--- /dev/null
+++ b/dojo/cldr/nls/el/japanese.js
@@ -0,0 +1,50 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "MM/y GGGGG",
+	"field-dayperiod": "π.μ./μ.μ.",
+	"field-minute": "Λεπτό",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"field-day-relative+-1": "Χτες",
+	"dateFormatItem-yQQQ": "y GGGGG QQQ",
+	"field-day-relative+-2": "Προχτές",
+	"field-weekday": "Ημέρα εβδομάδας",
+	"dateFormatItem-MMM": "LLL",
+	"field-era": "Περίοδος",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Ώρα",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-Ed": "E d",
+	"dateFormatItem-yMMM": "LLL y GGGGG",
+	"field-day-relative+0": "Σήμερα",
+	"field-day-relative+1": "Αύριο",
+	"field-day-relative+2": "Μεθαύριο",
+	"dateFormat-long": "d MMMM, y G",
+	"field-zone": "Ζώνη",
+	"field-week-relative+-1": "Προηγούμενη εβδομάδα",
+	"dateFormat-medium": "d MMM, y G",
+	"field-year-relative+0": "Φέτος",
+	"field-year-relative+1": "Επόμενο έτος",
+	"dateFormatItem-yMd": "dd/MM/y GGGGG",
+	"field-year-relative+-1": "Προηγούμενο έτος",
+	"field-year": "Έτος",
+	"field-week": "Εβδομάδα",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Αυτήν την εβδομάδα",
+	"field-week-relative+1": "Επόμενη εβδομάδα",
+	"field-month-relative+0": "Τρέχων μήνας",
+	"field-month": "Μήνας",
+	"field-month-relative+1": "Επόμενος μήνας",
+	"dateFormatItem-yMMMd": "d MMM, y G",
+	"field-second": "Δευτερόλεπτο",
+	"field-day": "Ημέρα",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormat-short": "d/M/yy",
+	"dateFormatItem-yMMMEd": "E, d MMM, y G",
+	"dateFormat-full": "EEEE, d MMMM, y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMEd": "E, dd/MM/y GGGGG",
+	"field-month-relative+-1": "Προηγούμενος μήνας"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/number.js b/dojo/cldr/nls/el/number.js
index e8ef918..084e9e3 100644
--- a/dojo/cldr/nls/el/number.js
+++ b/dojo/cldr/nls/el/number.js
@@ -7,14 +7,15 @@ define(
 	"percentFormat": "#,##0%",
 	"list": ",",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
 	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 τρισεκατομμύρια",
+	"decimalFormat-short": "000 τρις"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/roc.js b/dojo/cldr/nls/el/roc.js
new file mode 100644
index 0000000..1ee45fe
--- /dev/null
+++ b/dojo/cldr/nls/el/roc.js
@@ -0,0 +1,55 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M/y G",
+	"field-dayperiod": "π.μ./μ.μ.",
+	"field-minute": "Λεπτό",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"field-day-relative+-1": "Χτες",
+	"dateFormatItem-yQQQ": "y G QQQ",
+	"field-day-relative+-2": "Προχτές",
+	"field-weekday": "Ημέρα εβδομάδας",
+	"dateFormatItem-MMM": "LLL",
+	"field-era": "Περίοδος",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Ώρα",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-Ed": "E d",
+	"dateFormatItem-yMMM": "LLL, y G",
+	"field-day-relative+0": "Σήμερα",
+	"field-day-relative+1": "Αύριο",
+	"eraAbbr": [
+		"Πριν R.O.C.",
+		"R.O.C."
+	],
+	"field-day-relative+2": "Μεθαύριο",
+	"dateFormat-long": "d MMMM, y G",
+	"field-zone": "Ζώνη",
+	"field-week-relative+-1": "Προηγούμενη εβδομάδα",
+	"dateFormat-medium": "d MMM, y G",
+	"field-year-relative+0": "Φέτος",
+	"field-year-relative+1": "Επόμενο έτος",
+	"dateFormatItem-yMd": "d/M/y G",
+	"field-year-relative+-1": "Προηγούμενο έτος",
+	"field-year": "Έτος",
+	"field-week": "Εβδομάδα",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Αυτήν την εβδομάδα",
+	"field-week-relative+1": "Επόμενη εβδομάδα",
+	"dateFormatItem-yQQQQ": "QQQQ y G",
+	"field-month-relative+0": "Τρέχων μήνας",
+	"field-month": "Μήνας",
+	"field-month-relative+1": "Επόμενος μήνας",
+	"dateFormatItem-yMMMd": "d MMM, y G",
+	"field-second": "Δευτερόλεπτο",
+	"field-day": "Ημέρα",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormat-short": "d/M/y G",
+	"dateFormatItem-yMMMEd": "E, d MMM, y G",
+	"dateFormat-full": "EEEE, d MMMM, y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMEd": "E, d/M/y G",
+	"field-month-relative+-1": "Προηγούμενος μήνας"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-au/chinese.js b/dojo/cldr/nls/en-au/chinese.js
new file mode 100644
index 0000000..f8ca576
--- /dev/null
+++ b/dojo/cldr/nls/en-au/chinese.js
@@ -0,0 +1,10 @@
+define(
+//begin v1.x content
+{
+	"timeFormat-long": "h:mm:ss a z",
+	"timeFormat-medium": "h:mm:ss a",
+	"timeFormat-short": "h:mm a",
+	"timeFormat-full": "h:mm:ss a zzzz"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-au/generic.js b/dojo/cldr/nls/en-au/generic.js
new file mode 100644
index 0000000..99e542e
--- /dev/null
+++ b/dojo/cldr/nls/en-au/generic.js
@@ -0,0 +1,18 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yMEd": "E, d/M/y",
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormat-medium": "dd/MM/y G",
+	"dateFormatItem-yMd": "d/M/y",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"timeFormat-long": "h:mm:ss a z",
+	"timeFormat-short": "h:mm a",
+	"dateFormat-short": "d/MM/yy GGGGG",
+	"dateFormat-long": "d MMMM y G",
+	"dateFormatItem-MMMEd": "E, d MMM"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-au/gregorian.js b/dojo/cldr/nls/en-au/gregorian.js
index f980e6a..979bd7c 100644
--- a/dojo/cldr/nls/en-au/gregorian.js
+++ b/dojo/cldr/nls/en-au/gregorian.js
@@ -1,14 +1,15 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yMEd": "EEE, d/M/y",
-	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"dateFormatItem-yMEd": "E, d/M/y",
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"timeFormat-medium": "h:mm:ss a",
 	"dateFormatItem-MEd": "E, d/M",
-	"dateFormat-medium": "dd/MM/yyyy",
-	"dateFormatItem-MMdd": "dd/MM",
-	"dateFormatItem-yyyyMM": "MM/yyyy",
+	"dateFormat-medium": "dd/MM/y",
+	"dateFormatItem-yMd": "d/M/y",
 	"dateFormat-full": "EEEE, d MMMM y",
-	"dateFormatItem-MMMMd": "d MMMM",
+	"timeFormat-long": "h:mm:ss a z",
+	"timeFormat-short": "h:mm a",
 	"dateFormat-short": "d/MM/yy",
 	"dateFormat-long": "d MMMM y",
 	"dateFormatItem-MMMEd": "E, d MMM"
diff --git a/dojo/cldr/nls/en-au/japanese.js b/dojo/cldr/nls/en-au/japanese.js
new file mode 100644
index 0000000..474957b
--- /dev/null
+++ b/dojo/cldr/nls/en-au/japanese.js
@@ -0,0 +1,10 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-short": "d/MM/yy GGGGG",
+	"dateFormat-medium": "dd/MM/y G",
+	"dateFormat-long": "d MMMM y G",
+	"dateFormat-full": "EEEE, d MMMM y G"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-au/number.js b/dojo/cldr/nls/en-au/number.js
deleted file mode 100644
index 376cdeb..0000000
--- a/dojo/cldr/nls/en-au/number.js
+++ /dev/null
@@ -1,7 +0,0 @@
-define(
-//begin v1.x content
-{
-	"currencyFormat": "¤#,##0.00"
-}
-//end v1.x content
-);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-ca/gregorian.js b/dojo/cldr/nls/en-ca/gregorian.js
deleted file mode 100644
index 5b4b77d..0000000
--- a/dojo/cldr/nls/en-ca/gregorian.js
+++ /dev/null
@@ -1,20 +0,0 @@
-define(
-//begin v1.x content
-{
-	"dateFormatItem-yMMMEd": "EEE, d MMM, y",
-	"dateFormatItem-yyMMM": "MMM-yy",
-	"dateFormatItem-Md": "M-d",
-	"dateFormatItem-yMEd": "EEE, y-M-d",
-	"dateFormatItem-MEd": "E, M-d",
-	"dateFormatItem-MMMMEd": "E, d MMMM",
-	"dateFormat-medium": "yyyy-MM-dd",
-	"dateFormatItem-MMMd": "d MMM",
-	"dateFormatItem-MMdd": "MM-dd",
-	"dateFormat-full": "EEEE, d MMMM, y",
-	"dateFormat-short": "yy-MM-dd",
-	"dateFormatItem-MMMMd": "d MMMM",
-	"dateFormat-long": "d MMMM, y",
-	"dateFormatItem-MMMEd": "E, d MMM"
-}
-//end v1.x content
-);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/buddhist.js b/dojo/cldr/nls/en-gb/buddhist.js
deleted file mode 100644
index e75d023..0000000
--- a/dojo/cldr/nls/en-gb/buddhist.js
+++ /dev/null
@@ -1,101 +0,0 @@
-define(
-//begin v1.x content
-{
-	"dateFormat-medium": "d MMM y G",
-	"dateFormatItem-MMMEd": "E d MMM",
-	"dateFormatItem-MMdd": "dd/MM",
-	"dateFormatItem-MEd": "E, d/M",
-	"dateFormatItem-yMEd": "EEE, d/M/y G",
-	"dateFormatItem-yyMMM": "MMM y G",
-	"dateFormatItem-y": "y",
-	"dateFormatItem-Md": "d/M",
-	"months-standAlone-narrow": [
-		"J",
-		"F",
-		"M",
-		"A",
-		"M",
-		"J",
-		"J",
-		"A",
-		"S",
-		"O",
-		"N",
-		"D"
-	],
-	"days-standAlone-narrow": [
-		"S",
-		"M",
-		"T",
-		"W",
-		"T",
-		"F",
-		"S"
-	],
-	"dateFormatItem-yyyyMMMM": "MMMM y G",
-	"dateFormatItem-MMMMd": "d MMMM",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yyyyMM": "MM/y G",
-	"dateFormat-long": "d MMMM y G",
-	"dateFormat-short": "dd/MM/y G",
-	"dateFormatItem-yMMMEd": "EEE, MMM d, y",
-	"months-format-wide": [
-		"January",
-		"February",
-		"March",
-		"April",
-		"May",
-		"June",
-		"July",
-		"August",
-		"September",
-		"October",
-		"November",
-		"December"
-	],
-	"dateFormatItem-yM": "M/y",
-	"months-format-abbr": [
-		"Jan",
-		"Feb",
-		"Mar",
-		"Apr",
-		"May",
-		"Jun",
-		"Jul",
-		"Aug",
-		"Sep",
-		"Oct",
-		"Nov",
-		"Dec"
-	],
-	"days-format-wide": [
-		"Sunday",
-		"Monday",
-		"Tuesday",
-		"Wednesday",
-		"Thursday",
-		"Friday",
-		"Saturday"
-	],
-	"dateFormatItem-yQ": "Q y",
-	"dateFormatItem-yMMM": "MMM y",
-	"quarters-format-wide": [
-		"1st quarter",
-		"2nd quarter",
-		"3rd quarter",
-		"4th quarter"
-	],
-	"dateFormat-full": "EEEE, d MMMM y G",
-	"dateFormatItem-yyyyMd": "d/M/y G",
-	"days-format-abbr": [
-		"Sun",
-		"Mon",
-		"Tue",
-		"Wed",
-		"Thu",
-		"Fri",
-		"Sat"
-	]
-}
-//end v1.x content
-);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/chinese.js b/dojo/cldr/nls/en-gb/chinese.js
new file mode 100644
index 0000000..1fffdef
--- /dev/null
+++ b/dojo/cldr/nls/en-gb/chinese.js
@@ -0,0 +1,131 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d MMM U",
+	"field-dayperiod": "am/pm",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-MMM": "LLL",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "U",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dateFormatItem-y": "U",
+	"dateFormatItem-yyyy": "U",
+	"months-standAlone-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-Ed": "E d",
+	"dateFormatItem-GyMMMd": "d MMM U",
+	"dateFormatItem-yyyyMMMM": "MMMM U",
+	"dateFormat-long": "d MMMM U",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormat-medium": "d MMM U",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-yMd": "dd/MM/y",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ U",
+	"dateTimeFormat-long": "{1} {0}",
+	"months-standAlone-wide": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-yyyyMd": "dd/MM/y",
+	"dateFormatItem-yyyyMMMd": "d MMM U",
+	"dateFormatItem-yyyyMEd": "E, dd/MM/y",
+	"dateFormatItem-MMMd": "d MMM",
+	"months-format-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-H": "HH",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-M": "LL",
+	"dateFormatItem-GyMMMEd": "E, d MMM U",
+	"dateFormatItem-GyMMM": "MMM U",
+	"dateFormatItem-MEd": "E dd/MM",
+	"dateFormatItem-yyyyQQQ": "QQQ U",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd/MM/yy",
+	"dateFormatItem-yyyyM": "MM/y",
+	"dateFormat-full": "EEEE, d MMMM U",
+	"dateFormatItem-Md": "dd/MM",
+	"months-format-wide": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-yyyyMMM": "MMM U",
+	"dateFormatItem-d": "d",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/currency.js b/dojo/cldr/nls/en-gb/currency.js
new file mode 100644
index 0000000..fe35dbc
--- /dev/null
+++ b/dojo/cldr/nls/en-gb/currency.js
@@ -0,0 +1,14 @@
+define(
+//begin v1.x content
+{
+	"CAD_symbol": "CA$",
+	"EUR_displayName": "Euro",
+	"GBP_displayName": "British Pound",
+	"GBP_symbol": "£",
+	"HKD_symbol": "HK$",
+	"AUD_symbol": "AU$",
+	"CNY_symbol": "CN¥",
+	"EUR_symbol": "€"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/generic.js b/dojo/cldr/nls/en-gb/generic.js
new file mode 100644
index 0000000..c8dffc8
--- /dev/null
+++ b/dojo/cldr/nls/en-gb/generic.js
@@ -0,0 +1,46 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d MMM y G",
+	"field-dayperiod": "am/pm",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormat-medium": "d MMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateTimeFormat-long": "{1} {0}",
+	"dateFormatItem-yyyyMd": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMEd": "E, dd/MM/y GGGGG",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-H": "HH",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-M": "LL",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-MEd": "E dd/MM",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyM": "MM/y GGGGG",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormatItem-Md": "dd/MM",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/gregorian.js b/dojo/cldr/nls/en-gb/gregorian.js
index 9dd92d2..cfdc654 100644
--- a/dojo/cldr/nls/en-gb/gregorian.js
+++ b/dojo/cldr/nls/en-gb/gregorian.js
@@ -1,23 +1,52 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yyMMM": "MMM yy",
-	"dateFormatItem-Md": "d/M",
-	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
+	"dateFormatItem-yM": "MM/y",
+	"field-dayperiod": "am/pm",
+	"dayPeriods-format-wide-pm": "pm",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-MMdd": "dd/MM",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dayPeriods-format-wide-am": "am",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dateFormatItem-y": "y",
 	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateFormatItem-Ed": "E d",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "d MMMM y",
 	"timeFormat-medium": "HH:mm:ss",
-	"dateFormatItem-yyyyMMMM": "MMMM y",
-	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-Hm": "HH:mm",
 	"dateFormat-medium": "d MMM y",
-	"dateFormatItem-MMdd": "dd/MM",
-	"dateFormatItem-yyyyMM": "MM/yyyy",
-	"dateFormat-full": "EEEE, d MMMM y",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-yMd": "dd/MM/y",
+	"dateFormatItem-yMMMM": "MMMM y",
+	"dateFormatItem-ms": "mm:ss",
+	"dateTimeFormat-long": "{1} {0}",
+	"dateFormatItem-MMMd": "d MMM",
 	"timeFormat-long": "HH:mm:ss z",
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-short": "HH:mm",
-	"dateFormat-short": "dd/MM/yyyy",
+	"dateFormatItem-H": "HH",
 	"dateFormatItem-MMMMd": "d MMMM",
-	"dateFormat-long": "d MMMM y",
-	"dateFormatItem-MMMEd": "E d MMM"
+	"dateFormatItem-M": "LL",
+	"dateFormatItem-yMMMd": "d MMM y",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-MEd": "E dd/MM",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd/MM/y",
+	"dateFormatItem-yMMMEd": "E, d MMM y",
+	"dateFormat-full": "EEEE, d MMMM y",
+	"dateFormatItem-Md": "dd/MM",
+	"dateFormatItem-yMEd": "E, dd/MM/y",
+	"dateFormatItem-d": "d",
+	"dateFormatItem-h": "h a"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/indian.js b/dojo/cldr/nls/en-gb/indian.js
new file mode 100644
index 0000000..0808efb
--- /dev/null
+++ b/dojo/cldr/nls/en-gb/indian.js
@@ -0,0 +1,94 @@
+define(
+//begin v1.x content
+{
+	"months-format-abbr": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"months-format-wide": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"eraAbbr": [
+		"SAKA"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"months-standAlone-abbr": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"months-standAlone-wide": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"field-dayperiod": "am/pm",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/islamic.js b/dojo/cldr/nls/en-gb/islamic.js
deleted file mode 100644
index f0dceb9..0000000
--- a/dojo/cldr/nls/en-gb/islamic.js
+++ /dev/null
@@ -1,153 +0,0 @@
-define(
-//begin v1.x content
-{
-	"dateFormat-medium": "d MMM y G",
-	"dateFormatItem-MMMEd": "E d MMM",
-	"dateFormatItem-MMdd": "dd/MM",
-	"dateFormatItem-MEd": "E, d/M",
-	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
-	"dateFormatItem-yyyyMMM": "MMM y G",
-	"eraNarrow": [
-		"AH"
-	],
-	"months-format-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
-	],
-	"dateFormatItem-yyMMM": "MMM y G",
-	"dateFormatItem-Md": "d/M",
-	"months-standAlone-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
-	],
-	"months-standAlone-wide": [
-		"Muharram",
-		"Safar",
-		"Rabiʻ I",
-		"Rabiʻ II",
-		"Jumada I",
-		"Jumada II",
-		"Rajab",
-		"Shaʻban",
-		"Ramadan",
-		"Shawwal",
-		"Dhuʻl-Qiʻdah",
-		"Dhuʻl-Hijjah"
-	],
-	"eraNames": [
-		"AH"
-	],
-	"days-standAlone-narrow": [
-		"S",
-		"M",
-		"T",
-		"W",
-		"T",
-		"F",
-		"S"
-	],
-	"dateFormatItem-yyyyMEd": "EEE, d/M/y G",
-	"dateFormatItem-yyyyMMMM": "MMMM y G",
-	"dateFormatItem-MMMMd": "d MMMM",
-	"months-standAlone-abbr": [
-		"Muh.",
-		"Saf.",
-		"Rab. I",
-		"Rab. II",
-		"Jum. I",
-		"Jum. II",
-		"Raj.",
-		"Sha.",
-		"Ram.",
-		"Shaw.",
-		"Dhuʻl-Q.",
-		"Dhuʻl-H."
-	],
-	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yyyyMM": "MM/y G",
-	"dateFormat-long": "d MMMM y G",
-	"dateFormat-short": "dd/MM/y G",
-	"dateFormatItem-yMMMEd": "EEE, MMM d, y",
-	"months-format-wide": [
-		"Muharram",
-		"Safar",
-		"Rabiʻ I",
-		"Rabiʻ II",
-		"Jumada I",
-		"Jumada II",
-		"Rajab",
-		"Shaʻban",
-		"Ramadan",
-		"Shawwal",
-		"Dhuʻl-Qiʻdah",
-		"Dhuʻl-Hijjah"
-	],
-	"dateFormatItem-yM": "M/y",
-	"months-format-abbr": [
-		"Muh.",
-		"Saf.",
-		"Rab. I",
-		"Rab. II",
-		"Jum. I",
-		"Jum. II",
-		"Raj.",
-		"Sha.",
-		"Ram.",
-		"Shaw.",
-		"Dhuʻl-Q.",
-		"Dhuʻl-H."
-	],
-	"eraAbbr": [
-		"AH"
-	],
-	"days-format-wide": [
-		"Sunday",
-		"Monday",
-		"Tuesday",
-		"Wednesday",
-		"Thursday",
-		"Friday",
-		"Saturday"
-	],
-	"dateFormatItem-yQ": "Q y",
-	"dateFormatItem-yMMM": "MMM y",
-	"quarters-format-wide": [
-		"1st quarter",
-		"2nd quarter",
-		"3rd quarter",
-		"4th quarter"
-	],
-	"dateFormatItem-yyyyMd": "d/M/y G",
-	"dateFormat-full": "EEEE, d MMMM y G",
-	"days-format-abbr": [
-		"Sun",
-		"Mon",
-		"Tue",
-		"Wed",
-		"Thu",
-		"Fri",
-		"Sat"
-	]
-}
-//end v1.x content
-);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/japanese.js b/dojo/cldr/nls/en-gb/japanese.js
new file mode 100644
index 0000000..a9d00a5
--- /dev/null
+++ b/dojo/cldr/nls/en-gb/japanese.js
@@ -0,0 +1,11 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-short": "dd/MM/y GGGGG",
+	"dateFormat-medium": "d MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-dayperiod": "am/pm",
+	"dateFormat-full": "EEEE, d MMMM y G"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/buddhist.js b/dojo/cldr/nls/en/buddhist.js
index 98d6067..47be09e 100644
--- a/dojo/cldr/nls/en/buddhist.js
+++ b/dojo/cldr/nls/en/buddhist.js
@@ -1,15 +1,13 @@
 define(
 //begin v1.x content
 {
-	"dateFormat-medium": "MMM d, y G",
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-yyyyMMMEd": "E, MMM d, y G",
+	"field-minute": "Minute",
 	"dateFormatItem-MMMEd": "E, MMM d",
-	"dateFormatItem-MEd": "E, M/d",
-	"dateFormatItem-yMEd": "EEE, M/d/y G",
-	"dateFormatItem-Hm": "HH:mm",
-	"dateFormatItem-y": "y G",
-	"timeFormat-full": "h:mm:ss a zzzz",
-	"dateFormatItem-hm": "h:mm a",
-	"dateFormatItem-Md": "M/d",
+	"dateTimeFormat-full": "{1} 'at' {0}",
+	"field-day-relative+-1": "Yesterday",
+	"field-weekday": "Day of the Week",
 	"months-standAlone-narrow": [
 		"J",
 		"F",
@@ -24,24 +22,70 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-EEEd": "d EEE",
-	"dateFormatItem-M": "L",
-	"days-standAlone-narrow": [
-		"S",
-		"M",
-		"T",
-		"W",
-		"T",
-		"F",
-		"S"
+	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormat-short": "{1}, {0}",
+	"field-era": "Era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Hour",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "d E",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"eraAbbr": [
+		"BE"
 	],
-	"dateFormatItem-yQQQ": "QQQ y G",
-	"timeFormat-medium": "h:mm:ss a",
-	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-GyMMMd": "MMM d, y G",
 	"dateFormat-long": "MMMM d, y G",
-	"dateFormatItem-ms": "mm:ss",
-	"dateFormat-short": "M/d/yy G",
-	"dateFormatItem-yMMMEd": "EEE, MMM d, y G",
+	"timeFormat-medium": "h:mm:ss a",
+	"field-zone": "Time Zone",
+	"field-week-relative+-1": "Last week",
+	"dateFormat-medium": "MMM d, y G",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "This year",
+	"field-year-relative+1": "Next year",
+	"field-year-relative+-1": "Last year",
+	"field-year": "Year",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dayPeriods-format-narrow-am": "a",
+	"dateTimeFormat-long": "{1} 'at' {0}",
+	"field-week": "Week",
+	"dateFormatItem-yyyyMMMd": "MMM d, y G",
+	"dateFormatItem-yyyyMd": "M/d/y GGGGG",
+	"dateFormatItem-yyyyMEd": "E, M/d/y GGGGG",
+	"field-week-relative+0": "This week",
+	"field-week-relative+1": "Next week",
+	"timeFormat-long": "h:mm:ss a z",
+	"months-format-abbr": [
+		"Jan",
+		"Feb",
+		"Mar",
+		"Apr",
+		"May",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Oct",
+		"Nov",
+		"Dec"
+	],
+	"field-month-relative+0": "This month",
+	"field-month": "Month",
+	"field-month-relative+1": "Next month",
+	"timeFormat-short": "h:mm a",
+	"field-second": "Second",
+	"dateFormatItem-GyMMMEd": "E, MMM d, y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Day",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E, M/d",
+	"dateFormat-short": "M/d/y GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE, MMMM d, y G",
+	"dateFormatItem-Md": "M/d",
 	"months-format-wide": [
 		"January",
 		"February",
@@ -56,24 +100,24 @@ define(
 		"November",
 		"December"
 	],
-	"dateFormatItem-d": "d",
-	"dateFormatItem-yM": "M/y G",
-	"timeFormat-short": "h:mm a",
-	"months-format-abbr": [
-		"Jan",
-		"Feb",
-		"Mar",
-		"Apr",
-		"May",
-		"Jun",
-		"Jul",
-		"Aug",
-		"Sep",
-		"Oct",
-		"Nov",
-		"Dec"
+	"days-format-short": [
+		"Su",
+		"Mo",
+		"Tu",
+		"We",
+		"Th",
+		"Fr",
+		"Sa"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateTimeFormats-appendItem-Era": "{0} {1}",
+	"field-month-relative+-1": "Last month",
+	"quarters-format-wide": [
+		"1st quarter",
+		"2nd quarter",
+		"3rd quarter",
+		"4th quarter"
 	],
-	"timeFormat-long": "h:mm:ss a z",
 	"days-format-wide": [
 		"Sunday",
 		"Monday",
@@ -82,27 +126,6 @@ define(
 		"Thursday",
 		"Friday",
 		"Saturday"
-	],
-	"dateFormatItem-hms": "h:mm:ss a",
-	"dateFormatItem-yQ": "Q y G",
-	"dateFormatItem-MMM": "LLL",
-	"dateFormatItem-yMMM": "MMM y G",
-	"quarters-format-wide": [
-		"1st quarter",
-		"2nd quarter",
-		"3rd quarter",
-		"4th quarter"
-	],
-	"dateFormat-full": "EEEE, MMMM d, y G",
-	"dateFormatItem-MMMd": "MMM d",
-	"days-format-abbr": [
-		"Sun",
-		"Mon",
-		"Tue",
-		"Wed",
-		"Thu",
-		"Fri",
-		"Sat"
 	]
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/en/chinese.js b/dojo/cldr/nls/en/chinese.js
new file mode 100644
index 0000000..d7b262d
--- /dev/null
+++ b/dojo/cldr/nls/en/chinese.js
@@ -0,0 +1,99 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, MMM d, U",
+	"field-dayperiod": "AM/PM",
+	"field-minute": "Minute",
+	"dateFormatItem-MMMEd": "E, MMM d",
+	"dateTimeFormat-full": "{1} 'at' {0}",
+	"field-day-relative+-1": "Yesterday",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Gy": "U",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"field-era": "Era",
+	"field-hour": "Hour",
+	"dateFormatItem-y": "U",
+	"dateFormatItem-yyyy": "U",
+	"dateFormatItem-Ed": "d E",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "MMM d, U",
+	"dateFormat-long": "MMMM d, U",
+	"dateFormatItem-Ehm": "E h:mm a",
+	"field-zone": "Time Zone",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Last week",
+	"dateFormat-medium": "MMM d, U",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "This year",
+	"field-year-relative+1": "Next year",
+	"dateFormatItem-yMd": "M/d/y",
+	"field-year-relative+-1": "Last year",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ U",
+	"field-year": "Year",
+	"dateTimeFormat-long": "{1} 'at' {0}",
+	"field-week": "Week",
+	"dateFormatItem-yyyyMd": "M/d/y",
+	"dateFormatItem-yyyyMMMd": "MMM d, U",
+	"dateFormatItem-yyyyMEd": "E, M/d/y",
+	"dateFormatItem-MMMd": "MMM d",
+	"field-week-relative+0": "This week",
+	"dateFormatItem-Ehms": "E h:mm:ss a",
+	"field-week-relative+1": "Next week",
+	"months-format-abbr": [
+		"Mo1",
+		"Mo2",
+		"Mo3",
+		"Mo4",
+		"Mo5",
+		"Mo6",
+		"Mo7",
+		"Mo8",
+		"Mo9",
+		"Mo10",
+		"Mo11",
+		"Mo12"
+	],
+	"field-month-relative+0": "This month",
+	"dateFormatItem-H": "HH",
+	"field-month": "Month",
+	"field-month-relative+1": "Next month",
+	"dateFormatItem-M": "L",
+	"field-second": "Second",
+	"dateFormatItem-GyMMMEd": "E, MMM d, U",
+	"dateFormatItem-GyMMM": "MMM U",
+	"field-day": "Day",
+	"dateFormatItem-MEd": "E, M/d",
+	"dateFormatItem-yyyyQQQ": "QQQ U",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "M/d/yy",
+	"dateFormatItem-yyyyM": "M/y",
+	"dateFormat-full": "EEEE, MMMM d, U",
+	"dateFormatItem-EHms": "E HH:mm:ss",
+	"dateFormatItem-Md": "M/d",
+	"dateFormatItem-EHm": "E HH:mm",
+	"months-format-wide": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"dateFormatItem-yyyyMMM": "MMM U",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Last month",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/generic.js b/dojo/cldr/nls/en/generic.js
new file mode 100644
index 0000000..7f242a6
--- /dev/null
+++ b/dojo/cldr/nls/en/generic.js
@@ -0,0 +1,81 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-Ehm": "E h:mm a",
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-GyMMMEd": "E, MMM d, y G",
+	"dateFormatItem-MMMEd": "E, MMM d",
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "MMMM d, y G",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dateFormat-full": "EEEE, MMMM d, y G",
+	"dateFormatItem-yyyyMEd": "E, M/d/y GGGGG",
+	"dateFormatItem-Md": "M/d",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"field-era": "Era",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{0} {1}",
+	"field-hour": "Hour",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "MMM d, y G",
+	"dateFormatItem-H": "HH",
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E, MMM d, y G",
+	"dateFormatItem-M": "L",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "MMM d, y G",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-minute": "Minute",
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "Yesterday",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} 'at' {0}",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "E, M/d",
+	"dateTimeFormat-full": "{1} 'at' {0}",
+	"field-day": "Day",
+	"field-zone": "Time Zone",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dateFormatItem-y": "y G",
+	"field-year-relative+-1": "Last year",
+	"field-month-relative+-1": "Last month",
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dateFormatItem-yyyyMd": "M/d/y GGGGG",
+	"field-month": "Month",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormatItem-EHm": "E HH:mm",
+	"dateFormat-short": "M/d/y GGGGG",
+	"dateFormatItem-EHms": "E HH:mm:ss",
+	"dateFormatItem-Ehms": "E h:mm:ss a",
+	"field-second": "Second",
+	"field-month-relative+0": "This month",
+	"field-month-relative+1": "Next month",
+	"dateFormatItem-Ed": "d E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "MMM d, y G",
+	"field-year-relative+0": "This year",
+	"field-week-relative+-1": "Last week",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"field-year-relative+1": "Next year",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "This week",
+	"field-week-relative+1": "Next week"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/gregorian.js b/dojo/cldr/nls/en/gregorian.js
index b1e5f4b..c1629cd 100644
--- a/dojo/cldr/nls/en/gregorian.js
+++ b/dojo/cldr/nls/en/gregorian.js
@@ -1,32 +1,17 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M/y",
-	"field-dayperiod": "AM/PM",
-	"dateFormatItem-yQ": "Q y",
-	"dayPeriods-format-wide-pm": "PM",
-	"field-minute": "Minute",
-	"eraNames": [
-		"Before Christ",
-		"Anno Domini"
+	"dateFormatItem-Ehm": "E h:mm a",
+	"days-standAlone-short": [
+		"Su",
+		"Mo",
+		"Tu",
+		"We",
+		"Th",
+		"Fr",
+		"Sa"
 	],
-	"dateFormatItem-MMMEd": "E, MMM d",
-	"dateTimeFormat-full": "{1} {0}",
-	"field-day-relative+-1": "Yesterday",
-	"field-weekday": "Day of the Week",
-	"dateFormatItem-hms": "h:mm:ss a",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"days-standAlone-wide": [
-		"Sunday",
-		"Monday",
-		"Tuesday",
-		"Wednesday",
-		"Thursday",
-		"Friday",
-		"Saturday"
-	],
-	"dateFormatItem-MMM": "LLL",
-	"months-standAlone-narrow": [
+	"months-format-narrow": [
 		"J",
 		"F",
 		"M",
@@ -40,66 +25,55 @@ define(
 		"N",
 		"D"
 	],
-	"dateTimeFormat-short": "{1} {0}",
-	"field-era": "Era",
-	"field-hour": "Hour",
-	"dayPeriods-format-wide-am": "AM",
-	"dateTimeFormat-medium": "{1} {0}",
-	"dateFormatItem-y": "y",
-	"timeFormat-full": "h:mm:ss a zzzz",
-	"months-standAlone-abbr": [
-		"Jan",
-		"Feb",
-		"Mar",
-		"Apr",
-		"May",
-		"Jun",
-		"Jul",
-		"Aug",
-		"Sep",
-		"Oct",
-		"Nov",
-		"Dec"
-	],
-	"dateFormatItem-yMMM": "MMM y",
-	"field-day-relative+0": "Today",
-	"field-day-relative+1": "Tomorrow",
-	"days-standAlone-narrow": [
-		"S",
-		"M",
-		"T",
-		"W",
-		"T",
-		"F",
-		"S"
-	],
-	"eraAbbr": [
-		"BC",
-		"AD"
-	],
-	"dateFormat-long": "MMMM d, y",
-	"timeFormat-medium": "h:mm:ss a",
-	"dateFormatItem-EEEd": "d EEE",
-	"field-zone": "Zone",
-	"dateFormatItem-Hm": "HH:mm",
-	"dateFormat-medium": "MMM d, y",
-	"dateFormatItem-Hms": "HH:mm:ss",
-	"quarters-standAlone-wide": [
-		"1st quarter",
-		"2nd quarter",
-		"3rd quarter",
-		"4th quarter"
-	],
-	"dateFormatItem-ms": "mm:ss",
-	"field-year": "Year",
 	"quarters-standAlone-narrow": [
 		"1",
 		"2",
 		"3",
 		"4"
 	],
-	"dateTimeFormat-long": "{1} {0}",
-	"field-week": "Week",
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "E, M/d/y",
+	"dateFormatItem-GyMMMEd": "E, MMM d, y G",
+	"dateFormatItem-MMMEd": "E, MMM d",
+	"eraNarrow": [
+		"B",
+		"A"
+	],
+	"days-format-short": [
+		"Su",
+		"Mo",
+		"Tu",
+		"We",
+		"Th",
+		"Fr",
+		"Sa"
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "MMMM d, y",
+	"months-format-wide": [
+		"January",
+		"February",
+		"March",
+		"April",
+		"May",
+		"June",
+		"July",
+		"August",
+		"September",
+		"October",
+		"November",
+		"December"
+	],
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "EEEE, MMMM d, y",
+	"dateFormatItem-Md": "M/d",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-noon": "noon",
+	"dateFormatItem-yMd": "M/d/y",
+	"field-era": "Era",
+	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
 		"January",
 		"February",
@@ -114,8 +88,19 @@ define(
 		"November",
 		"December"
 	],
-	"dateFormatItem-MMMd": "MMM d",
+	"timeFormat-short": "h:mm a",
+	"quarters-format-wide": [
+		"1st quarter",
+		"2nd quarter",
+		"3rd quarter",
+		"4th quarter"
+	],
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-long": "h:mm:ss a z",
+	"field-year": "Year",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateTimeFormats-appendItem-Era": "{0} {1}",
+	"field-hour": "Hour",
 	"months-format-abbr": [
 		"Jan",
 		"Feb",
@@ -130,38 +115,80 @@ define(
 		"Nov",
 		"Dec"
 	],
-	"dayPeriods-format-wide-noon": "noon",
-	"timeFormat-short": "h:mm a",
-	"field-month": "Month",
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "MMM d, y G",
+	"dateFormatItem-H": "HH",
+	"months-standAlone-abbr": [
+		"Jan",
+		"Feb",
+		"Mar",
+		"Apr",
+		"May",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Oct",
+		"Nov",
+		"Dec"
+	],
 	"quarters-format-abbr": [
 		"Q1",
 		"Q2",
 		"Q3",
 		"Q4"
 	],
-	"days-format-abbr": [
-		"Sun",
-		"Mon",
-		"Tue",
-		"Wed",
-		"Thu",
-		"Fri",
-		"Sat"
+	"quarters-standAlone-wide": [
+		"1st quarter",
+		"2nd quarter",
+		"3rd quarter",
+		"4th quarter"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
-	"days-format-narrow": [
-		"S",
-		"M",
-		"T",
-		"W",
-		"T",
-		"F",
-		"S"
+	"days-standAlone-wide": [
+		"Sunday",
+		"Monday",
+		"Tuesday",
+		"Wednesday",
+		"Thursday",
+		"Friday",
+		"Saturday"
 	],
-	"field-second": "Second",
-	"field-day": "Day",
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormatItem-Hm": "HH:mm",
+	"eraAbbr": [
+		"BC",
+		"AD"
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "Yesterday",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} 'at' {0}",
+	"dayPeriods-format-narrow-am": "a",
+	"dateFormatItem-MMMd": "MMM d",
 	"dateFormatItem-MEd": "E, M/d",
-	"months-format-narrow": [
+	"dateTimeFormat-full": "{1} 'at' {0}",
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sunday",
+		"Monday",
+		"Tuesday",
+		"Wednesday",
+		"Thursday",
+		"Friday",
+		"Saturday"
+	],
+	"field-zone": "Time Zone",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dateFormatItem-y": "y",
+	"months-standAlone-narrow": [
 		"J",
 		"F",
 		"M",
@@ -175,8 +202,12 @@ define(
 		"N",
 		"D"
 	],
+	"field-year-relative+-1": "Last year",
+	"field-month-relative+-1": "Last month",
 	"dateFormatItem-hm": "h:mm a",
-	"days-standAlone-abbr": [
+	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"days-format-abbr": [
 		"Sun",
 		"Mon",
 		"Tue",
@@ -185,45 +216,49 @@ define(
 		"Fri",
 		"Sat"
 	],
-	"dateFormat-short": "M/d/yy",
-	"dateFormatItem-yMMMEd": "EEE, MMM d, y",
-	"dateFormat-full": "EEEE, MMMM d, y",
-	"dateFormatItem-Md": "M/d",
-	"dateFormatItem-yMEd": "EEE, M/d/y",
-	"months-format-wide": [
-		"January",
-		"February",
-		"March",
-		"April",
-		"May",
-		"June",
-		"July",
-		"August",
-		"September",
-		"October",
-		"November",
-		"December"
-	],
-	"dateFormatItem-d": "d",
-	"quarters-format-wide": [
-		"1st quarter",
-		"2nd quarter",
-		"3rd quarter",
-		"4th quarter"
+	"dateFormatItem-yMMMd": "MMM d, y",
+	"eraNames": [
+		"Before Christ",
+		"Anno Domini"
 	],
-	"days-format-wide": [
-		"Sunday",
-		"Monday",
-		"Tuesday",
-		"Wednesday",
-		"Thursday",
-		"Friday",
-		"Saturday"
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
 	],
-	"eraNarrow": [
-		"B",
-		"A"
-	]
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormatItem-EHm": "E HH:mm",
+	"dateFormat-short": "M/d/yy",
+	"dateFormatItem-EHms": "E HH:mm:ss",
+	"dateFormatItem-Ehms": "E h:mm:ss a",
+	"dayPeriods-format-narrow-noon": "n",
+	"field-second": "Second",
+	"dateFormatItem-yMMMEd": "E, MMM d, y",
+	"field-month-relative+0": "This month",
+	"field-month-relative+1": "Next month",
+	"dateFormatItem-Ed": "d E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "MMM d, y",
+	"field-year-relative+0": "This year",
+	"field-week-relative+-1": "Last week",
+	"field-year-relative+1": "Next year",
+	"dayPeriods-format-narrow-pm": "p",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "This week",
+	"field-week-relative+1": "Next week"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/hebrew.js b/dojo/cldr/nls/en/hebrew.js
new file mode 100644
index 0000000..9f4c2a5
--- /dev/null
+++ b/dojo/cldr/nls/en/hebrew.js
@@ -0,0 +1,90 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-yyyyMMMEd": "E, MMM d, y G",
+	"field-minute": "Minute",
+	"dateFormatItem-MMMEd": "E, MMM d",
+	"dateTimeFormat-full": "{1} 'at' {0}",
+	"field-day-relative+-1": "Yesterday",
+	"field-weekday": "Day of the Week",
+	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormat-short": "{1}, {0}",
+	"field-era": "Era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Hour",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "d E",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"eraAbbr": [
+		"AM"
+	],
+	"dateFormatItem-GyMMMd": "MMM d, y G",
+	"dateFormat-long": "MMMM d, y G",
+	"timeFormat-medium": "h:mm:ss a",
+	"field-zone": "Time Zone",
+	"field-week-relative+-1": "Last week",
+	"dateFormat-medium": "MMM d, y G",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "This year",
+	"field-year-relative+1": "Next year",
+	"field-year-relative+-1": "Last year",
+	"field-year": "Year",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dayPeriods-format-narrow-am": "a",
+	"dateTimeFormat-long": "{1} 'at' {0}",
+	"field-week": "Week",
+	"dateFormatItem-yyyyMMMd": "MMM d, y G",
+	"dateFormatItem-yyyyMd": "M/d/y GGGGG",
+	"dateFormatItem-yyyyMEd": "E, M/d/y GGGGG",
+	"field-week-relative+0": "This week",
+	"field-week-relative+1": "Next week",
+	"timeFormat-long": "h:mm:ss a z",
+	"field-month-relative+0": "This month",
+	"field-month": "Month",
+	"field-month-relative+1": "Next month",
+	"timeFormat-short": "h:mm a",
+	"field-second": "Second",
+	"dateFormatItem-GyMMMEd": "E, MMM d, y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Day",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E, M/d",
+	"dateFormat-short": "M/d/y GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE, MMMM d, y G",
+	"dateFormatItem-Md": "M/d",
+	"days-format-short": [
+		"Su",
+		"Mo",
+		"Tu",
+		"We",
+		"Th",
+		"Fr",
+		"Sa"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateTimeFormats-appendItem-Era": "{0} {1}",
+	"field-month-relative+-1": "Last month",
+	"quarters-format-wide": [
+		"1st quarter",
+		"2nd quarter",
+		"3rd quarter",
+		"4th quarter"
+	],
+	"days-format-wide": [
+		"Sunday",
+		"Monday",
+		"Tuesday",
+		"Wednesday",
+		"Thursday",
+		"Friday",
+		"Saturday"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/islamic.js b/dojo/cldr/nls/en/islamic.js
index f61fafb..4de7b86 100644
--- a/dojo/cldr/nls/en/islamic.js
+++ b/dojo/cldr/nls/en/islamic.js
@@ -1,157 +1,81 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M/y",
-	"dateFormatItem-yyyyMMMEd": "EEE, MMM d, y G",
-	"dateFormatItem-yQ": "Q y",
-	"eraNames": [
-		"AH"
-	],
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-yyyyMMMEd": "E, MMM d, y G",
+	"field-minute": "Minute",
 	"dateFormatItem-MMMEd": "E, MMM d",
-	"dateFormatItem-hms": "h:mm:ss a",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-MMM": "LLL",
-	"months-standAlone-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
-	],
+	"dateTimeFormat-full": "{1} 'at' {0}",
+	"field-day-relative+-1": "Yesterday",
+	"field-weekday": "Day of the Week",
+	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormat-short": "{1}, {0}",
+	"field-era": "Era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Hour",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dateFormatItem-y": "y G",
 	"timeFormat-full": "h:mm:ss a zzzz",
 	"dateFormatItem-yyyy": "y G",
-	"months-standAlone-abbr": [
-		"Muh.",
-		"Saf.",
-		"Rab. I",
-		"Rab. II",
-		"Jum. I",
-		"Jum. II",
-		"Raj.",
-		"Sha.",
-		"Ram.",
-		"Shaw.",
-		"Dhuʻl-Q.",
-		"Dhuʻl-H."
-	],
-	"dateFormatItem-yMMM": "MMM y",
-	"days-standAlone-narrow": [
-		"S",
-		"M",
-		"T",
-		"W",
-		"T",
-		"F",
-		"S"
-	],
+	"dateFormatItem-Ed": "d E",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
 	"eraAbbr": [
 		"AH"
 	],
+	"dateFormatItem-GyMMMd": "MMM d, y G",
 	"dateFormat-long": "MMMM d, y G",
 	"timeFormat-medium": "h:mm:ss a",
-	"dateFormatItem-EEEd": "d EEE",
-	"dateFormatItem-Hm": "HH:mm",
+	"field-zone": "Time Zone",
+	"field-week-relative+-1": "Last week",
 	"dateFormat-medium": "MMM d, y G",
-	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-ms": "mm:ss",
-	"months-standAlone-wide": [
-		"Muharram",
-		"Safar",
-		"Rabiʻ I",
-		"Rabiʻ II",
-		"Jumada I",
-		"Jumada II",
-		"Rajab",
-		"Shaʻban",
-		"Ramadan",
-		"Shawwal",
-		"Dhuʻl-Qiʻdah",
-		"Dhuʻl-Hijjah"
-	],
-	"dateFormatItem-yyyyMEd": "EEE, M/d/y G",
-	"dateFormatItem-MMMd": "MMM d",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "This year",
+	"field-year-relative+1": "Next year",
+	"field-year-relative+-1": "Last year",
+	"field-year": "Year",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dayPeriods-format-narrow-am": "a",
+	"dateTimeFormat-long": "{1} 'at' {0}",
+	"field-week": "Week",
+	"dateFormatItem-yyyyMMMd": "MMM d, y G",
+	"dateFormatItem-yyyyMd": "M/d/y GGGGG",
+	"dateFormatItem-yyyyMEd": "E, M/d/y GGGGG",
+	"field-week-relative+0": "This week",
+	"field-week-relative+1": "Next week",
 	"timeFormat-long": "h:mm:ss a z",
-	"months-format-abbr": [
-		"Muh.",
-		"Saf.",
-		"Rab. I",
-		"Rab. II",
-		"Jum. I",
-		"Jum. II",
-		"Raj.",
-		"Sha.",
-		"Ram.",
-		"Shaw.",
-		"Dhuʻl-Q.",
-		"Dhuʻl-H."
-	],
+	"field-month-relative+0": "This month",
+	"field-month": "Month",
+	"field-month-relative+1": "Next month",
 	"timeFormat-short": "h:mm a",
-	"days-format-abbr": [
-		"Sun",
-		"Mon",
-		"Tue",
-		"Wed",
-		"Thu",
-		"Fri",
-		"Sat"
-	],
-	"dateFormatItem-M": "L",
+	"field-second": "Second",
+	"dateFormatItem-GyMMMEd": "E, MMM d, y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Day",
 	"dateFormatItem-yyyyQQQ": "QQQ y G",
 	"dateFormatItem-MEd": "E, M/d",
-	"months-format-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
-	],
-	"dateFormatItem-hm": "h:mm a",
-	"dateFormat-short": "M/d/yy G",
-	"dateFormatItem-yyyyM": "M/y G",
-	"dateFormatItem-yMMMEd": "EEE, MMM d, y",
+	"dateFormat-short": "M/d/y GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
 	"dateFormat-full": "EEEE, MMMM d, y G",
 	"dateFormatItem-Md": "M/d",
-	"dateFormatItem-yyyyQ": "Q y G",
-	"dateFormatItem-yMEd": "EEE, M/d/y",
-	"months-format-wide": [
-		"Muharram",
-		"Safar",
-		"Rabiʻ I",
-		"Rabiʻ II",
-		"Jumada I",
-		"Jumada II",
-		"Rajab",
-		"Shaʻban",
-		"Ramadan",
-		"Shawwal",
-		"Dhuʻl-Qiʻdah",
-		"Dhuʻl-Hijjah"
+	"days-format-short": [
+		"Su",
+		"Mo",
+		"Tu",
+		"We",
+		"Th",
+		"Fr",
+		"Sa"
 	],
 	"dateFormatItem-yyyyMMM": "MMM y G",
-	"dateFormatItem-d": "d",
+	"dateTimeFormats-appendItem-Era": "{0} {1}",
+	"field-month-relative+-1": "Last month",
 	"quarters-format-wide": [
 		"1st quarter",
 		"2nd quarter",
 		"3rd quarter",
 		"4th quarter"
 	],
-	"eraNarrow": [
-		"AH"
-	],
 	"days-format-wide": [
 		"Sunday",
 		"Monday",
diff --git a/dojo/cldr/nls/en/japanese.js b/dojo/cldr/nls/en/japanese.js
new file mode 100644
index 0000000..d7c688c
--- /dev/null
+++ b/dojo/cldr/nls/en/japanese.js
@@ -0,0 +1,33 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "MMM d, y G",
+	"field-second": "Second",
+	"field-year-relative+-1": "Last year",
+	"field-week": "Week",
+	"field-month-relative+-1": "Last month",
+	"field-day-relative+-1": "Yesterday",
+	"field-year": "Year",
+	"field-week-relative+0": "This week",
+	"field-week-relative+1": "Next week",
+	"field-minute": "Minute",
+	"field-week-relative+-1": "Last week",
+	"field-day-relative+0": "Today",
+	"field-hour": "Hour",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormat-long": "MMMM d, y G",
+	"field-day": "Day",
+	"field-month-relative+0": "This month",
+	"field-month-relative+1": "Next month",
+	"field-dayperiod": "AM/PM",
+	"field-month": "Month",
+	"dateFormat-short": "M/d/y GGGGG",
+	"field-era": "Era",
+	"field-year-relative+0": "This year",
+	"field-year-relative+1": "Next year",
+	"dateFormat-full": "EEEE, MMMM d, y G",
+	"field-weekday": "Day of the Week",
+	"field-zone": "Time Zone"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/number.js b/dojo/cldr/nls/en/number.js
index 3f94169..f589589 100644
--- a/dojo/cldr/nls/en/number.js
+++ b/dojo/cldr/nls/en/number.js
@@ -8,15 +8,14 @@ define(
 	"percentFormat": "#,##0%",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ".",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "¤#,##0.00;(¤#,##0.00)",
 	"plusSign": "+",
+	"decimalFormat-long": "000 trillion",
 	"decimalFormat-short": "000T"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/en/roc.js b/dojo/cldr/nls/en/roc.js
new file mode 100644
index 0000000..fad283c
--- /dev/null
+++ b/dojo/cldr/nls/en/roc.js
@@ -0,0 +1,33 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Second",
+	"field-year-relative+-1": "Last year",
+	"field-week": "Week",
+	"field-month-relative+-1": "Last month",
+	"field-day-relative+-1": "Yesterday",
+	"field-year": "Year",
+	"field-week-relative+0": "This week",
+	"field-week-relative+1": "Next week",
+	"field-minute": "Minute",
+	"field-week-relative+-1": "Last week",
+	"field-day-relative+0": "Today",
+	"field-hour": "Hour",
+	"field-day-relative+1": "Tomorrow",
+	"field-day": "Day",
+	"field-month-relative+0": "This month",
+	"field-month-relative+1": "Next month",
+	"field-dayperiod": "AM/PM",
+	"field-month": "Month",
+	"field-era": "Era",
+	"field-year-relative+0": "This year",
+	"field-year-relative+1": "Next year",
+	"eraAbbr": [
+		"Before R.O.C.",
+		"Minguo"
+	],
+	"field-weekday": "Day of the Week",
+	"field-zone": "Time Zone"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/buddhist.js b/dojo/cldr/nls/es/buddhist.js
index 426c223..b3d5145 100644
--- a/dojo/cldr/nls/es/buddhist.js
+++ b/dojo/cldr/nls/es/buddhist.js
@@ -1,13 +1,15 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M/y G",
-	"dateFormatItem-yQ": "Q y G",
+	"field-dayperiod": "periodo del día",
+	"dateFormatItem-yyyyMMMEd": "E, d 'de' MMMM 'de' y G",
 	"dayPeriods-format-wide-pm": "p.m.",
+	"field-minute": "minuto",
 	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "ayer",
+	"field-weekday": "día de la semana",
 	"dateFormatItem-hms": "hh:mm:ss a",
-	"dateFormatItem-yQQQ": "QQQ y G",
-	"dateFormatItem-MMM": "LLL",
+	"field-day-relative+-2": "antes de ayer",
 	"months-standAlone-narrow": [
 		"E",
 		"F",
@@ -22,34 +24,77 @@ define(
 		"N",
 		"D"
 	],
+	"field-era": "era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "hora",
 	"dayPeriods-format-wide-am": "a.m.",
 	"dateFormatItem-y": "y G",
-	"dateFormatItem-MMMdd": "dd-MMM",
-	"dateFormatItem-yMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"ene",
+		"feb",
+		"mar",
+		"abr",
+		"mayo",
+		"jun",
+		"jul",
+		"ago",
+		"sep",
+		"oct",
+		"nov",
+		"dic"
+	],
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "hoy",
+	"field-day-relative+1": "mañana",
 	"days-standAlone-narrow": [
 		"D",
 		"L",
 		"M",
-		"M",
+		"X",
 		"J",
 		"V",
 		"S"
 	],
-	"dateFormatItem-yyyyMM": "MM/y G",
+	"eraAbbr": [
+		"BE"
+	],
+	"field-day-relative+2": "pasado mañana",
+	"dateFormatItem-GyMMMd": "d MMM y G",
 	"dateFormat-long": "d 'de' MMMM 'de' y G",
-	"dateFormatItem-EEEd": "EEE d",
-	"dateFormatItem-Hm": "HH:mm",
-	"dateFormatItem-MMd": "d/MM",
-	"dateFormatItem-yyMM": "MM/y G",
+	"field-zone": "zona",
+	"field-week-relative+-1": "la semana pasada",
 	"dateFormat-medium": "dd/MM/y G",
-	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-yyMMM": "MMM-y G",
-	"dateFormatItem-yyQQQQ": "QQQQ 'de' y G",
-	"dateFormatItem-yMd": "d/M/y G",
-	"dateFormatItem-yMMMM": "MMMM 'de' y G",
-	"dateFormatItem-ms": "mm:ss",
+	"field-year-relative+0": "este año",
+	"field-year-relative+1": "el próximo año",
+	"quarters-standAlone-wide": [
+		"1.er trimestre",
+		"2.º trimestre",
+		"3.er trimestre",
+		"4.º trimestre"
+	],
+	"field-year-relative+-1": "el año pasado",
+	"field-year": "año",
+	"dateFormatItem-yyyyQQQQ": "QQQQ 'de' y G",
+	"quarters-standAlone-narrow": [
+		"1T",
+		"2T",
+		"3T",
+		"4T"
+	],
+	"field-week": "semana",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"dateFormatItem-yyyyMEd": "E, d/M/y GGGGG",
+	"field-week-relative+0": "esta semana",
 	"dateFormatItem-MMMd": "d MMM",
-	"dateFormatItem-yyQ": "Q y G",
+	"quarters-format-narrow": [
+		"1T",
+		"2T",
+		"3T",
+		"4T"
+	],
+	"field-week-relative+1": "la próxima semana",
 	"months-format-abbr": [
 		"ene",
 		"feb",
@@ -64,7 +109,9 @@ define(
 		"nov",
 		"dic"
 	],
-	"dateFormatItem-MMMMd": "d 'de' MMMM",
+	"field-month-relative+0": "este mes",
+	"field-month": "mes",
+	"field-month-relative+1": "el próximo mes",
 	"quarters-format-abbr": [
 		"T1",
 		"T2",
@@ -80,15 +127,26 @@ define(
 		"vie",
 		"sáb"
 	],
-	"dateFormatItem-M": "L",
-	"dateFormatItem-yMMMd": "d MMM y G",
+	"field-second": "segundo",
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "día",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
 	"dateFormatItem-MEd": "E, d/M",
+	"days-standAlone-short": [
+		"D",
+		"L",
+		"M",
+		"X",
+		"J",
+		"V",
+		"S"
+	],
 	"dateFormatItem-hm": "hh:mm a",
-	"dateFormat-short": "dd/MM/y G",
-	"dateFormatItem-yMMMEd": "EEE, d MMM y G",
-	"dateFormat-full": "EEEE d 'de' MMMM 'de' y G",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
 	"dateFormatItem-Md": "d/M",
-	"dateFormatItem-yMEd": "EEE d/M/y G",
 	"months-format-wide": [
 		"enero",
 		"febrero",
@@ -103,7 +161,17 @@ define(
 		"noviembre",
 		"diciembre"
 	],
-	"dateFormatItem-d": "d",
+	"days-format-short": [
+		"D",
+		"L",
+		"M",
+		"X",
+		"J",
+		"V",
+		"S"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "el mes pasado",
 	"quarters-format-wide": [
 		"1er trimestre",
 		"2º trimestre",
diff --git a/dojo/cldr/nls/es/chinese.js b/dojo/cldr/nls/es/chinese.js
new file mode 100644
index 0000000..1a913ce
--- /dev/null
+++ b/dojo/cldr/nls/es/chinese.js
@@ -0,0 +1,65 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d-M-y",
+	"field-dayperiod": "periodo del día",
+	"field-minute": "minuto",
+	"dateFormatItem-MMMEd": "E d-M",
+	"field-day-relative+-1": "ayer",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"field-day-relative+-2": "antes de ayer",
+	"field-weekday": "día de la semana",
+	"dateFormatItem-MMM": "L",
+	"field-era": "era",
+	"dateFormatItem-Gy": "y",
+	"field-hour": "hora",
+	"dateFormatItem-y": "y",
+	"dateFormatItem-yyyy": "y",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "hoy",
+	"field-day-relative+1": "mañana",
+	"field-day-relative+2": "pasado mañana",
+	"dateFormatItem-yyyyMMMM": "M-y",
+	"dateFormatItem-GyMMMd": "d-M-y",
+	"dateFormat-long": "d-M-y",
+	"field-zone": "zona",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "la semana pasada",
+	"dateFormat-medium": "d-M-y",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "este año",
+	"field-year-relative+1": "el próximo año",
+	"field-year-relative+-1": "el año pasado",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y",
+	"field-year": "año",
+	"field-week": "semana",
+	"dateFormatItem-yyyyMd": "d-M-y",
+	"dateFormatItem-yyyyMMMd": "d-M-y",
+	"dateFormatItem-yyyyMEd": "E, d-M-y",
+	"dateFormatItem-MMMd": "d-M",
+	"field-week-relative+0": "esta semana",
+	"field-week-relative+1": "la próxima semana",
+	"field-month-relative+0": "este mes",
+	"dateFormatItem-H": "HH",
+	"field-month": "mes",
+	"field-month-relative+1": "el próximo mes",
+	"dateFormatItem-M": "L",
+	"field-second": "segundo",
+	"dateFormatItem-GyMMMEd": "E, d-M-y",
+	"dateFormatItem-GyMMM": "M-y",
+	"field-day": "día",
+	"dateFormatItem-yyyyQQQ": "QQQ y",
+	"dateFormatItem-MEd": "E, d-M",
+	"dateFormatItem-hm": "hh:mm a",
+	"dateFormat-short": "d-M-y",
+	"dateFormatItem-yyyyM": "M-y",
+	"dateFormat-full": "EEEE, d-M-y",
+	"dateFormatItem-Md": "d-M",
+	"dateFormatItem-yyyyMMM": "M-y",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "el mes pasado",
+	"dateFormatItem-h": "hh a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/currency.js b/dojo/cldr/nls/es/currency.js
index 1498e01..99e2c45 100644
--- a/dojo/cldr/nls/es/currency.js
+++ b/dojo/cldr/nls/es/currency.js
@@ -4,11 +4,12 @@ define(
 	"HKD_displayName": "dólar de Hong Kong",
 	"CHF_displayName": "franco suizo",
 	"CAD_displayName": "dólar canadiense",
-	"CNY_displayName": "yuan renminbi chino",
+	"CNY_displayName": "yuan chino",
 	"AUD_displayName": "dólar australiano",
 	"JPY_displayName": "yen japonés",
 	"USD_displayName": "dólar estadounidense",
 	"GBP_displayName": "libra esterlina británica",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/es/generic.js b/dojo/cldr/nls/es/generic.js
new file mode 100644
index 0000000..42fa682
--- /dev/null
+++ b/dojo/cldr/nls/es/generic.js
@@ -0,0 +1,71 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d 'de' MMMM 'de' y G",
+	"field-dayperiod": "periodo del día",
+	"field-minute": "minuto",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "ayer",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"field-day-relative+-2": "antes de ayer",
+	"field-weekday": "día de la semana",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "era",
+	"field-hour": "hora",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-MMMdd": "dd-MMM",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "hoy",
+	"field-day-relative+1": "mañana",
+	"field-day-relative+2": "pasado mañana",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMMMM": "MMMM 'de' y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-zone": "zona",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "la semana pasada",
+	"dateFormat-medium": "dd/MM/y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "este año",
+	"field-year-relative+1": "el próximo año",
+	"field-year-relative+-1": "el año pasado",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ 'de' y G",
+	"field-year": "año",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "semana",
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMEd": "E, d/M/y GGGGG",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "esta semana",
+	"field-week-relative+1": "la próxima semana",
+	"field-month-relative+0": "este mes",
+	"dateFormatItem-H": "HH",
+	"field-month": "mes",
+	"field-month-relative+1": "el próximo mes",
+	"dateFormatItem-MMMMd": "d 'de' MMMM",
+	"dateFormatItem-M": "L",
+	"field-second": "segundo",
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "día",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "hh:mm a",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "el mes pasado",
+	"dateFormatItem-h": "hh a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/gregorian.js b/dojo/cldr/nls/es/gregorian.js
index d9b5c74..5882ae4 100644
--- a/dojo/cldr/nls/es/gregorian.js
+++ b/dojo/cldr/nls/es/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"D",
+		"L",
+		"M",
+		"X",
+		"J",
+		"V",
+		"S"
+	],
 	"months-format-narrow": [
 		"E",
 		"F",
@@ -15,16 +24,32 @@ define(
 		"N",
 		"D"
 	],
+	"quarters-standAlone-narrow": [
+		"1T",
+		"2T",
+		"3T",
+		"4T"
+	],
 	"field-weekday": "día de la semana",
-	"dateFormatItem-yyQQQQ": "QQQQ 'de' yy",
 	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "EEE d/M/y",
+	"dateFormatItem-yMEd": "EEE, d/M/y",
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMMM 'de' y G",
 	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
 		"a.C.",
 		"d.C."
 	],
+	"dateFormatItem-yMM": "MM/y",
 	"dateFormatItem-MMMdd": "dd-MMM",
+	"days-format-short": [
+		"D",
+		"L",
+		"M",
+		"X",
+		"J",
+		"V",
+		"S"
+	],
 	"dateFormat-long": "d 'de' MMMM 'de' y",
 	"months-format-wide": [
 		"enero",
@@ -40,10 +65,11 @@ define(
 		"noviembre",
 		"diciembre"
 	],
-	"dateFormatItem-EEEd": "EEE d",
+	"dateTimeFormat-medium": "{1} {0}",
 	"dayPeriods-format-wide-pm": "p.m.",
-	"dateFormat-full": "EEEE d 'de' MMMM 'de' y",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y",
 	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMd": "d/M/y",
 	"field-era": "era",
 	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
@@ -67,11 +93,12 @@ define(
 		"3er trimestre",
 		"4º trimestre"
 	],
+	"dateFormatItem-yQQQQ": "QQQQ 'de' y",
 	"timeFormat-long": "HH:mm:ss z",
 	"field-year": "año",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "Q y",
 	"field-hour": "hora",
+	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
 		"ene",
 		"feb",
@@ -86,18 +113,18 @@ define(
 		"nov",
 		"dic"
 	],
-	"dateFormatItem-yyQ": "Q yy",
 	"timeFormat-full": "HH:mm:ss zzzz",
 	"field-day-relative+0": "hoy",
 	"field-day-relative+1": "mañana",
+	"dateFormatItem-GyMMMd": "d MMM y G",
 	"field-day-relative+2": "pasado mañana",
-	"field-day-relative+3": "Dentro de tres días",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
 		"ene",
 		"feb",
 		"mar",
 		"abr",
-		"may",
+		"mayo",
 		"jun",
 		"jul",
 		"ago",
@@ -113,11 +140,12 @@ define(
 		"T4"
 	],
 	"quarters-standAlone-wide": [
-		"1er trimestre",
-		"2º trimestre",
-		"3er trimestre",
-		"4º trimestre"
+		"1.er trimestre",
+		"2.º trimestre",
+		"3.er trimestre",
+		"4.º trimestre"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
 		"domingo",
@@ -129,7 +157,6 @@ define(
 		"sábado"
 	],
 	"dateFormatItem-MMMMd": "d 'de' MMMM",
-	"dateFormatItem-yyMMM": "MMM-yy",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -155,12 +182,19 @@ define(
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1T",
+		"2T",
+		"3T",
+		"4T"
+	],
 	"field-day-relative+-1": "ayer",
 	"dateFormatItem-h": "hh a",
+	"dateTimeFormat-long": "{1} {0}",
 	"field-day-relative+-2": "antes de ayer",
-	"field-day-relative+-3": "Hace tres días",
 	"dateFormatItem-MMMd": "d MMM",
 	"dateFormatItem-MEd": "E, d/M",
+	"dateTimeFormat-full": "{1} {0}",
 	"dateFormatItem-yMMMM": "MMMM 'de' y",
 	"field-day": "día",
 	"days-format-wide": [
@@ -173,7 +207,6 @@ define(
 		"sábado"
 	],
 	"field-zone": "zona",
-	"dateFormatItem-yyyyMM": "MM/yyyy",
 	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
 		"E",
@@ -189,7 +222,8 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-yyMM": "MM/yy",
+	"field-year-relative+-1": "el año pasado",
+	"field-month-relative+-1": "el mes pasado",
 	"dateFormatItem-hm": "hh:mm a",
 	"days-format-abbr": [
 		"dom",
@@ -200,6 +234,7 @@ define(
 		"vie",
 		"sáb"
 	],
+	"dateFormatItem-yMMMd": "d MMM y",
 	"eraNames": [
 		"antes de Cristo",
 		"anno Dómini"
@@ -208,7 +243,7 @@ define(
 		"D",
 		"L",
 		"M",
-		"M",
+		"X",
 		"J",
 		"V",
 		"S"
@@ -218,7 +253,7 @@ define(
 		"D",
 		"L",
 		"M",
-		"M",
+		"X",
 		"J",
 		"V",
 		"S"
@@ -228,11 +263,21 @@ define(
 	"dateFormat-short": "dd/MM/yy",
 	"dateFormatItem-MMd": "d/MM",
 	"field-second": "segundo",
-	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"dateFormatItem-yMMMEd": "EEE, d 'de' MMMM 'de' y",
+	"field-month-relative+0": "este mes",
+	"field-month-relative+1": "el próximo mes",
+	"dateFormatItem-Ed": "E d",
 	"field-week": "semana",
-	"dateFormat-medium": "dd/MM/yyyy",
+	"dateFormat-medium": "dd/MM/y",
+	"field-year-relative+0": "este año",
+	"field-week-relative+-1": "la semana pasada",
+	"field-year-relative+1": "el próximo año",
+	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-hms": "hh:mm:ss a"
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "esta semana",
+	"field-week-relative+1": "la próxima semana"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/hebrew.js b/dojo/cldr/nls/es/hebrew.js
new file mode 100644
index 0000000..9ef1af0
--- /dev/null
+++ b/dojo/cldr/nls/es/hebrew.js
@@ -0,0 +1,137 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "periodo del día",
+	"dateFormatItem-yyyyMMMEd": "E, d 'de' MMMM 'de' y G",
+	"dayPeriods-format-wide-pm": "p.m.",
+	"field-minute": "minuto",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "ayer",
+	"field-weekday": "día de la semana",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"field-day-relative+-2": "antes de ayer",
+	"field-era": "era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "hora",
+	"dayPeriods-format-wide-am": "a.m.",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "hoy",
+	"field-day-relative+1": "mañana",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"X",
+		"J",
+		"V",
+		"S"
+	],
+	"eraAbbr": [
+		"AM"
+	],
+	"field-day-relative+2": "pasado mañana",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-zone": "zona",
+	"field-week-relative+-1": "la semana pasada",
+	"dateFormat-medium": "dd/MM/y G",
+	"field-year-relative+0": "este año",
+	"field-year-relative+1": "el próximo año",
+	"quarters-standAlone-wide": [
+		"1.er trimestre",
+		"2.º trimestre",
+		"3.er trimestre",
+		"4.º trimestre"
+	],
+	"field-year-relative+-1": "el año pasado",
+	"field-year": "año",
+	"dateFormatItem-yyyyQQQQ": "QQQQ 'de' y G",
+	"quarters-standAlone-narrow": [
+		"1T",
+		"2T",
+		"3T",
+		"4T"
+	],
+	"field-week": "semana",
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMEd": "E, d/M/y GGGGG",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "esta semana",
+	"quarters-format-narrow": [
+		"1T",
+		"2T",
+		"3T",
+		"4T"
+	],
+	"field-week-relative+1": "la próxima semana",
+	"field-month-relative+0": "este mes",
+	"field-month": "mes",
+	"field-month-relative+1": "el próximo mes",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"lun",
+		"mar",
+		"mié",
+		"jue",
+		"vie",
+		"sáb"
+	],
+	"field-second": "segundo",
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "día",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E, d/M",
+	"days-standAlone-short": [
+		"D",
+		"L",
+		"M",
+		"X",
+		"J",
+		"V",
+		"S"
+	],
+	"dateFormatItem-hm": "hh:mm a",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormatItem-Md": "d/M",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"days-format-short": [
+		"D",
+		"L",
+		"M",
+		"X",
+		"J",
+		"V",
+		"S"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "el mes pasado",
+	"quarters-format-wide": [
+		"1er trimestre",
+		"2º trimestre",
+		"3er trimestre",
+		"4º trimestre"
+	],
+	"days-format-wide": [
+		"domingo",
+		"lunes",
+		"martes",
+		"miércoles",
+		"jueves",
+		"viernes",
+		"sábado"
+	],
+	"dateFormatItem-h": "hh a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/islamic.js b/dojo/cldr/nls/es/islamic.js
index 8d6f3dd..5712c8a 100644
--- a/dojo/cldr/nls/es/islamic.js
+++ b/dojo/cldr/nls/es/islamic.js
@@ -1,54 +1,29 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M/y",
-	"dateFormatItem-yyyyMMMEd": "EEE, d MMM y G",
-	"dateFormatItem-yQ": "Q y",
+	"field-dayperiod": "periodo del día",
+	"dateFormatItem-yyyyMMMEd": "E, d 'de' MMMM 'de' y G",
 	"dayPeriods-format-wide-pm": "p.m.",
-	"eraNames": [
-		"AH"
-	],
+	"field-minute": "minuto",
 	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "ayer",
+	"field-weekday": "día de la semana",
 	"dateFormatItem-hms": "hh:mm:ss a",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-MMM": "LLL",
-	"months-standAlone-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
-	],
+	"field-day-relative+-2": "antes de ayer",
+	"field-era": "era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "hora",
 	"dayPeriods-format-wide-am": "a.m.",
-	"dateFormatItem-MMMdd": "dd-MMM",
+	"dateFormatItem-y": "y G",
 	"dateFormatItem-yyyy": "y G",
-	"months-standAlone-abbr": [
-		"Muh.",
-		"Saf.",
-		"Rab. I",
-		"Rab. II",
-		"Jum. I",
-		"Jum. II",
-		"Raj.",
-		"Sha.",
-		"Ram.",
-		"Shaw.",
-		"Dhuʻl-Q.",
-		"Dhuʻl-H."
-	],
-	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "hoy",
+	"field-day-relative+1": "mañana",
 	"days-standAlone-narrow": [
 		"D",
 		"L",
 		"M",
-		"M",
+		"X",
 		"J",
 		"V",
 		"S"
@@ -56,49 +31,45 @@ define(
 	"eraAbbr": [
 		"AH"
 	],
-	"dateFormatItem-yyyyMMMM": "MMMM 'de' y G",
+	"field-day-relative+2": "pasado mañana",
+	"dateFormatItem-GyMMMd": "d MMM y G",
 	"dateFormat-long": "d 'de' MMMM 'de' y G",
-	"dateFormatItem-EEEd": "EEE d",
-	"dateFormatItem-Hm": "HH:mm",
-	"dateFormatItem-MMd": "d/MM",
-	"dateFormatItem-yyMM": "MM/y G",
+	"field-zone": "zona",
+	"field-week-relative+-1": "la semana pasada",
 	"dateFormat-medium": "dd/MM/y G",
-	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-yyMMM": "MMM-y G",
-	"dateFormatItem-yyQQQQ": "QQQQ 'de' y G",
-	"dateFormatItem-ms": "mm:ss",
-	"months-standAlone-wide": [
-		"Muharram",
-		"Safar",
-		"Rabiʻ I",
-		"Rabiʻ II",
-		"Jumada I",
-		"Jumada II",
-		"Rajab",
-		"Shaʻban",
-		"Ramadan",
-		"Shawwal",
-		"Dhuʻl-Qiʻdah",
-		"Dhuʻl-Hijjah"
+	"field-year-relative+0": "este año",
+	"field-year-relative+1": "el próximo año",
+	"quarters-standAlone-wide": [
+		"1.er trimestre",
+		"2.º trimestre",
+		"3.er trimestre",
+		"4.º trimestre"
+	],
+	"field-year-relative+-1": "el año pasado",
+	"field-year": "año",
+	"dateFormatItem-yyyyQQQQ": "QQQQ 'de' y G",
+	"quarters-standAlone-narrow": [
+		"1T",
+		"2T",
+		"3T",
+		"4T"
 	],
-	"dateFormatItem-yyyyMEd": "EEE d/M/y G",
+	"field-week": "semana",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"dateFormatItem-yyyyMEd": "E, d/M/y GGGGG",
+	"field-week-relative+0": "esta semana",
 	"dateFormatItem-MMMd": "d MMM",
-	"dateFormatItem-yyQ": "Q y G",
-	"months-format-abbr": [
-		"Muh.",
-		"Saf.",
-		"Rab. I",
-		"Rab. II",
-		"Jum. I",
-		"Jum. II",
-		"Raj.",
-		"Sha.",
-		"Ram.",
-		"Shaw.",
-		"Dhuʻl-Q.",
-		"Dhuʻl-H."
+	"quarters-format-narrow": [
+		"1T",
+		"2T",
+		"3T",
+		"4T"
 	],
-	"dateFormatItem-MMMMd": "d 'de' MMMM",
+	"field-week-relative+1": "la próxima semana",
+	"field-month-relative+0": "este mes",
+	"field-month": "mes",
+	"field-month-relative+1": "el próximo mes",
 	"quarters-format-abbr": [
 		"T1",
 		"T2",
@@ -114,56 +85,43 @@ define(
 		"vie",
 		"sáb"
 	],
-	"dateFormatItem-M": "L",
-	"dateFormatItem-MEd": "E, d/M",
+	"field-second": "segundo",
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "día",
 	"dateFormatItem-yyyyQQQ": "QQQ y G",
-	"months-format-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+	"dateFormatItem-MEd": "E, d/M",
+	"days-standAlone-short": [
+		"D",
+		"L",
+		"M",
+		"X",
+		"J",
+		"V",
+		"S"
 	],
 	"dateFormatItem-hm": "hh:mm a",
-	"dateFormat-short": "dd/MM/y G",
-	"dateFormatItem-yyyyM": "M/y G",
-	"dateFormatItem-yMMMEd": "EEE, d MMM y",
-	"dateFormat-full": "EEEE d 'de' MMMM 'de' y G",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
 	"dateFormatItem-Md": "d/M",
-	"dateFormatItem-yyyyQ": "Q y G",
-	"dateFormatItem-yMEd": "EEE d/M/y",
-	"months-format-wide": [
-		"Muharram",
-		"Safar",
-		"Rabiʻ I",
-		"Rabiʻ II",
-		"Jumada I",
-		"Jumada II",
-		"Rajab",
-		"Shaʻban",
-		"Ramadan",
-		"Shawwal",
-		"Dhuʻl-Qiʻdah",
-		"Dhuʻl-Hijjah"
+	"days-format-short": [
+		"D",
+		"L",
+		"M",
+		"X",
+		"J",
+		"V",
+		"S"
 	],
 	"dateFormatItem-yyyyMMM": "MMM y G",
-	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "el mes pasado",
 	"quarters-format-wide": [
 		"1er trimestre",
 		"2º trimestre",
 		"3er trimestre",
 		"4º trimestre"
 	],
-	"eraNarrow": [
-		"AH"
-	],
 	"days-format-wide": [
 		"domingo",
 		"lunes",
diff --git a/dojo/cldr/nls/es/japanese.js b/dojo/cldr/nls/es/japanese.js
new file mode 100644
index 0000000..d5e662b
--- /dev/null
+++ b/dojo/cldr/nls/es/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "dd/MM/y G",
+	"field-second": "segundo",
+	"field-year-relative+-1": "el año pasado",
+	"field-week": "semana",
+	"field-month-relative+-1": "el mes pasado",
+	"field-day-relative+-1": "ayer",
+	"field-day-relative+-2": "antes de ayer",
+	"field-year": "año",
+	"field-week-relative+0": "esta semana",
+	"field-week-relative+1": "la próxima semana",
+	"field-minute": "minuto",
+	"field-week-relative+-1": "la semana pasada",
+	"field-day-relative+0": "hoy",
+	"field-hour": "hora",
+	"field-day-relative+1": "mañana",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-day-relative+2": "pasado mañana",
+	"field-day": "día",
+	"field-month-relative+0": "este mes",
+	"field-month-relative+1": "el próximo mes",
+	"field-dayperiod": "periodo del día",
+	"field-month": "mes",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"field-era": "era",
+	"field-year-relative+0": "este año",
+	"field-year-relative+1": "el próximo año",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"field-weekday": "día de la semana",
+	"field-zone": "zona"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/number.js b/dojo/cldr/nls/es/number.js
index 06a3f68..f24bc01 100644
--- a/dojo/cldr/nls/es/number.js
+++ b/dojo/cldr/nls/es/number.js
@@ -11,11 +11,12 @@ define(
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
-	"currencyFormat": "¤ #,##0.00",
-	"plusSign": "+"
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+",
+	"decimalFormat-long": "000 billones",
+	"decimalFormat-short": "000 B"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/roc.js b/dojo/cldr/nls/es/roc.js
new file mode 100644
index 0000000..8aceb84
--- /dev/null
+++ b/dojo/cldr/nls/es/roc.js
@@ -0,0 +1,34 @@
+define(
+//begin v1.x content
+{
+	"field-second": "segundo",
+	"field-year-relative+-1": "el año pasado",
+	"field-week": "semana",
+	"field-month-relative+-1": "el mes pasado",
+	"field-day-relative+-1": "ayer",
+	"field-day-relative+-2": "antes de ayer",
+	"field-year": "año",
+	"field-week-relative+0": "esta semana",
+	"field-week-relative+1": "la próxima semana",
+	"field-minute": "minuto",
+	"field-week-relative+-1": "la semana pasada",
+	"field-day-relative+0": "hoy",
+	"field-hour": "hora",
+	"field-day-relative+1": "mañana",
+	"field-day-relative+2": "pasado mañana",
+	"field-day": "día",
+	"field-month-relative+0": "este mes",
+	"field-month-relative+1": "el próximo mes",
+	"field-dayperiod": "periodo del día",
+	"field-month": "mes",
+	"field-era": "era",
+	"field-year-relative+0": "este año",
+	"field-year-relative+1": "el próximo año",
+	"eraAbbr": [
+		"antes de R.O.C."
+	],
+	"field-weekday": "día de la semana",
+	"field-zone": "zona"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ethiopic-amete-alem.js b/dojo/cldr/nls/ethiopic-amete-alem.js
new file mode 100644
index 0000000..89efbfb
--- /dev/null
+++ b/dojo/cldr/nls/ethiopic-amete-alem.js
@@ -0,0 +1,450 @@
+define({ root:
+
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-weekday": "Day of the Week",
+	"quarters-standAlone-abbr at localeAlias193": {
+		"bundle": "gregorian",
+		"target": "quarters-format-abbr"
+	},
+	"timeFormat at localeAlias208": {
+		"bundle": "ethiopic",
+		"target": "timeFormat"
+	},
+	"quarters-standAlone-abbr at localeAlias194": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"timeFormat at localeAlias209": {
+		"bundle": "gregorian",
+		"target": "timeFormat"
+	},
+	"quarters-format-abbr at localeAlias191": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"quarters-format-narrow at localeAlias192": {
+		"bundle": "gregorian",
+		"target": "quarters-standAlone-narrow"
+	},
+	"dayPeriods-format-abbr at localeAlias198": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dayPeriods-format-narrow at localeAlias200": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
+	"dayPeriods-format-narrow at localeAlias202": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias203": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"eraNarrow": [
+		"ERA0"
+	],
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"months-standAlone-abbr at localeAlias174": {
+		"bundle": "ethiopic",
+		"target": "months-format-abbr"
+	},
+	"dateFormat-long": "G y MMMM d",
+	"months-standAlone-abbr at localeAlias175": {
+		"bundle": "ethiopic",
+		"target": "months-format-wide"
+	},
+	"months-format-abbr at localeAlias172": {
+		"bundle": "ethiopic",
+		"target": "months-format-wide"
+	},
+	"months-format-wide": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"dateFormatItem-Md": "MM-dd",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"quarters at localeAlias189": {
+		"bundle": "ethiopic",
+		"target": "quarters"
+	},
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
+	"months-format-abbr": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"months-format-narrow at localeAlias173": {
+		"bundle": "ethiopic",
+		"target": "months-standAlone-narrow"
+	},
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
+	"months-standAlone-abbr": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"dateFormatItem-H": "HH",
+	"quarters at localeAlias190": {
+		"bundle": "gregorian",
+		"target": "quarters"
+	},
+	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
+	"timeFormat-medium": "HH:mm:ss",
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Hm": "HH:mm",
+	"eraAbbr": [
+		"ERA0"
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"eraNarrow at localeAlias205": {
+		"bundle": "ethiopic-amete-alem",
+		"target": "eraAbbr"
+	},
+	"days-standAlone-wide at localeAlias188": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"field-day-relative+-1": "Yesterday",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateTimeFormat-long": "{1} {0}",
+	"dateFormatItem-h": "h a",
+	"days-format-short at localeAlias181": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"dateFormatItem-MMMd": "MMM d",
+	"days-format-short at localeAlias182": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateFormatItem-MEd": "MM-dd, E",
+	"dateTimeFormat-full": "{1} {0}",
+	"dayPeriods-format-narrow at localeAlias199": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"field-zone": "Zone",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"dateTime at localeAlias210": {
+		"bundle": "ethiopic",
+		"target": "dateTime"
+	},
+	"dateFormatItem-y": "G y",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dateTime at localeAlias211": {
+		"bundle": "generic",
+		"target": "dateTime"
+	},
+	"dayPeriods-format-abbr at localeAlias201": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
+	"days-standAlone-abbr at localeAlias183": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"days-standAlone-abbr at localeAlias184": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-standAlone-short at localeAlias185": {
+		"bundle": "gregorian",
+		"target": "days-format-short"
+	},
+	"dayPeriods-format-abbr-pm": "PM",
+	"days-standAlone-short at localeAlias186": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-format-abbr at localeAlias179": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-standAlone-short at localeAlias187": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"eraNames": [
+		"ERA0"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
+	"dayPeriods at localeAlias196": {
+		"bundle": "ethiopic",
+		"target": "dayPeriods"
+	},
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"dayPeriods at localeAlias197": {
+		"bundle": "gregorian",
+		"target": "dayPeriods"
+	},
+	"days at localeAlias177": {
+		"bundle": "ethiopic",
+		"target": "days"
+	},
+	"days at localeAlias178": {
+		"bundle": "gregorian",
+		"target": "days"
+	},
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"quarters-standAlone-wide at localeAlias195": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"months at localeAlias171": {
+		"bundle": "ethiopic",
+		"target": "months"
+	},
+	"days-format-narrow at localeAlias180": {
+		"bundle": "gregorian",
+		"target": "days-standAlone-narrow"
+	},
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"field-second": "Second",
+	"dateFormatItem-Ed": "d, E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"dateTimeFormat-short": "{1} {0}",
+	"eraNames at localeAlias204": {
+		"bundle": "ethiopic-amete-alem",
+		"target": "eraAbbr"
+	},
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormat at localeAlias206": {
+		"bundle": "ethiopic",
+		"target": "dateFormat"
+	},
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormat at localeAlias207": {
+		"bundle": "generic",
+		"target": "dateFormat"
+	},
+	"months-standAlone-wide at localeAlias176": {
+		"bundle": "ethiopic",
+		"target": "months-format-wide"
+	},
+	"dateFormatItem-GyMMM": "G y MMM",
+	"dateFormatItem-yyyy": "G y"
+}
+//end v1.x content
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/ethiopic.js b/dojo/cldr/nls/ethiopic.js
new file mode 100644
index 0000000..339cc8d
--- /dev/null
+++ b/dojo/cldr/nls/ethiopic.js
@@ -0,0 +1,439 @@
+define({ root:
+
+//begin v1.x content
+{
+	"days-standAlone-abbr at localeAlias148": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-standAlone-short at localeAlias149": {
+		"bundle": "gregorian",
+		"target": "days-format-short"
+	},
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"dayPeriods-format-narrow at localeAlias161": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias162": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-weekday": "Day of the Week",
+	"dayPeriods-format-narrow at localeAlias164": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias165": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dayPeriods at localeAlias159": {
+		"bundle": "gregorian",
+		"target": "dayPeriods"
+	},
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
+	"eraNarrow": [
+		"ERA0",
+		"ERA1"
+	],
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"days-standAlone-short at localeAlias150": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"quarters-standAlone-wide at localeAlias158": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"days-standAlone-short at localeAlias151": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-format-abbr at localeAlias143": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateFormat-long": "G y MMMM d",
+	"months-format-wide": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"days-format-narrow at localeAlias144": {
+		"bundle": "gregorian",
+		"target": "days-standAlone-narrow"
+	},
+	"dateFormatItem-Md": "MM-dd",
+	"dayPeriods-format-abbr-am": "AM",
+	"days at localeAlias142": {
+		"bundle": "gregorian",
+		"target": "days"
+	},
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
+	"months-format-abbr": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
+	"months-standAlone-abbr": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"dateFormatItem-H": "HH",
+	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
+	"quarters-standAlone-abbr at localeAlias156": {
+		"bundle": "gregorian",
+		"target": "quarters-format-abbr"
+	},
+	"timeFormat-medium": "HH:mm:ss",
+	"quarters-standAlone-abbr at localeAlias157": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"quarters-format-narrow at localeAlias155": {
+		"bundle": "gregorian",
+		"target": "quarters-standAlone-narrow"
+	},
+	"quarters-format-abbr at localeAlias154": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Hm": "HH:mm",
+	"eraNarrow at localeAlias167": {
+		"bundle": "ethiopic",
+		"target": "eraAbbr"
+	},
+	"eraAbbr": [
+		"ERA0",
+		"ERA1"
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-standAlone-wide at localeAlias141": {
+		"bundle": "ethiopic",
+		"target": "months-format-wide"
+	},
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Yesterday",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateTimeFormat-long": "{1} {0}",
+	"dateFormatItem-h": "h a",
+	"months-standAlone-abbr at localeAlias139": {
+		"bundle": "ethiopic",
+		"target": "months-format-abbr"
+	},
+	"dateFormatItem-MMMd": "MMM d",
+	"dateTime at localeAlias170": {
+		"bundle": "generic",
+		"target": "dateTime"
+	},
+	"months-format-abbr at localeAlias137": {
+		"bundle": "ethiopic",
+		"target": "months-format-wide"
+	},
+	"dateFormatItem-MEd": "MM-dd, E",
+	"dayPeriods-format-abbr at localeAlias160": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateTimeFormat-full": "{1} {0}",
+	"dayPeriods-format-abbr at localeAlias163": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"field-zone": "Zone",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"dateFormatItem-y": "G y",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"months-standAlone-abbr at localeAlias140": {
+		"bundle": "ethiopic",
+		"target": "months-format-wide"
+	},
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"eraNames": [
+		"ERA0",
+		"ERA1"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"months-format-narrow at localeAlias138": {
+		"bundle": "ethiopic",
+		"target": "months-standAlone-narrow"
+	},
+	"quarters at localeAlias153": {
+		"bundle": "gregorian",
+		"target": "quarters"
+	},
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"field-second": "Second",
+	"days-format-short at localeAlias145": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-format-short at localeAlias146": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"eraNames at localeAlias166": {
+		"bundle": "ethiopic",
+		"target": "eraAbbr"
+	},
+	"dateFormatItem-Ed": "d, E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"dateFormat at localeAlias168": {
+		"bundle": "generic",
+		"target": "dateFormat"
+	},
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"days-standAlone-wide at localeAlias152": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateFormatItem-GyMMM": "G y MMM",
+	"timeFormat at localeAlias169": {
+		"bundle": "gregorian",
+		"target": "timeFormat"
+	},
+	"dateFormatItem-yyyy": "G y",
+	"days-standAlone-abbr at localeAlias147": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	}
+}
+//end v1.x content
+,
+	"ar": true,
+	"fr": true,
+	"hu": true,
+	"ja": true,
+	"pl": true,
+	"pt": true,
+	"ro": true,
+	"ru": true,
+	"sv": true,
+	"th": true,
+	"tr": true,
+	"zh": true,
+	"zh-hant": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/buddhist.js b/dojo/cldr/nls/fi/buddhist.js
index 5c70514..ffecf7c 100644
--- a/dojo/cldr/nls/fi/buddhist.js
+++ b/dojo/cldr/nls/fi/buddhist.js
@@ -1,24 +1,16 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "L.y G",
-	"dateFormatItem-yMMMMccccd": "cccc, d. MMMM y G",
-	"dateFormatItem-yQ": "Q/y G",
-	"dayPeriods-format-wide-pm": "ip.",
-	"dateFormatItem-MMMEd": "E d. MMM",
-	"dateFormatItem-hms": "h.mm.ss a",
-	"dateFormatItem-yQQQ": "QQQ y G",
-	"days-standAlone-wide": [
-		"sunnuntai",
-		"maanantai",
-		"tiistai",
-		"keskiviikko",
-		"torstai",
-		"perjantai",
-		"lauantai"
+	"days-standAlone-short": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
 	],
-	"dateFormatItem-MMM": "LLL",
-	"months-standAlone-narrow": [
+	"months-format-narrow": [
 		"T",
 		"H",
 		"M",
@@ -32,46 +24,40 @@ define(
 		"M",
 		"J"
 	],
-	"dateFormatItem-Gy": "y G",
-	"dayPeriods-format-wide-am": "ap.",
-	"dateFormatItem-y": "y G",
-	"timeFormat-full": "H.mm.ss zzzz",
-	"months-standAlone-abbr": [
-		"tammi",
-		"helmi",
-		"maalis",
-		"huhti",
-		"touko",
-		"kesä",
-		"heinä",
-		"elo",
-		"syys",
-		"loka",
-		"marras",
-		"joulu"
-	],
-	"dateFormatItem-Ed": "ccc d.",
-	"dateFormatItem-yMMM": "LLLL y G",
-	"days-standAlone-narrow": [
-		"S",
-		"M",
-		"T",
-		"K",
-		"T",
-		"P",
-		"L"
+	"field-weekday": "viikonpäivä",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-MMMEd": "ccc d. MMM",
+	"days-format-short": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
 	],
-	"dateFormatItem-yyyyMMMM": "LLLL y G",
 	"dateFormat-long": "d. MMMM y G",
-	"timeFormat-medium": "H.mm.ss",
-	"dateFormatItem-Hm": "H.mm",
-	"dateFormatItem-yyyyMEEEd": "EEE d.M.y G",
-	"dateFormatItem-yyMM": "M.y G",
-	"dateFormat-medium": "d.M.y G",
-	"dateFormatItem-Hms": "H.mm.ss",
-	"dateFormatItem-yyMMM": "LLLL y G",
-	"dateFormatItem-ms": "mm.ss",
-	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"months-format-wide": [
+		"tammikuuta",
+		"helmikuuta",
+		"maaliskuuta",
+		"huhtikuuta",
+		"toukokuuta",
+		"kesäkuuta",
+		"heinäkuuta",
+		"elokuuta",
+		"syyskuuta",
+		"lokakuuta",
+		"marraskuuta",
+		"joulukuuta"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dayPeriods-format-wide-pm": "ip.",
+	"dateFormat-full": "cccc d. MMMM y G",
+	"dateFormatItem-yyyyMEd": "E d.M.y G",
+	"dateFormatItem-Md": "d.M.",
+	"dayPeriods-format-abbr-am": "ap.",
+	"field-era": "aikakausi",
 	"months-standAlone-wide": [
 		"tammikuu",
 		"helmikuu",
@@ -86,9 +72,16 @@ define(
 		"marraskuu",
 		"joulukuu"
 	],
-	"dateFormatItem-MMMd": "d. MMM",
-	"dateFormatItem-yyQ": "Q/y G",
+	"timeFormat-short": "H.mm",
+	"quarters-format-wide": [
+		"1. neljännes",
+		"2. neljännes",
+		"3. neljännes",
+		"4. neljännes"
+	],
 	"timeFormat-long": "H.mm.ss z",
+	"field-year": "vuosi",
+	"field-hour": "tunti",
 	"months-format-abbr": [
 		"tammikuuta",
 		"helmikuuta",
@@ -103,15 +96,65 @@ define(
 		"marraskuuta",
 		"joulukuuta"
 	],
+	"timeFormat-full": "H.mm.ss zzzz",
+	"field-day-relative+0": "tänään",
+	"field-day-relative+1": "huomenna",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"field-day-relative+2": "ylihuomenna",
 	"dateFormatItem-H": "H",
-	"timeFormat-short": "H.mm",
+	"months-standAlone-abbr": [
+		"tammi",
+		"helmi",
+		"maalis",
+		"huhti",
+		"touko",
+		"kesä",
+		"heinä",
+		"elo",
+		"syys",
+		"loka",
+		"marras",
+		"joulu"
+	],
 	"quarters-format-abbr": [
 		"1. nelj.",
 		"2. nelj.",
 		"3. nelj.",
 		"4. nelj."
 	],
-	"days-format-abbr": [
+	"quarters-standAlone-wide": [
+		"1. neljännes",
+		"2. neljännes",
+		"3. neljännes",
+		"4. neljännes"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"days-standAlone-wide": [
+		"sunnuntai",
+		"maanantai",
+		"tiistai",
+		"keskiviikko",
+		"torstai",
+		"perjantai",
+		"lauantai"
+	],
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"timeFormat-medium": "H.mm.ss",
+	"dateFormatItem-Hm": "H.mm",
+	"quarters-standAlone-abbr": [
+		"1. nelj.",
+		"2. nelj.",
+		"3. nelj.",
+		"4. nelj."
+	],
+	"eraAbbr": [
+		"BE"
+	],
+	"field-minute": "minuutti",
+	"field-dayperiod": "vuorokaudenaika",
+	"days-standAlone-abbr": [
 		"su",
 		"ma",
 		"ti",
@@ -120,38 +163,13 @@ define(
 		"pe",
 		"la"
 	],
-	"dateFormatItem-M": "L",
+	"dateFormatItem-ms": "mm.ss",
+	"field-day-relative+-1": "eilen",
+	"dayPeriods-format-narrow-am": "ap.",
+	"field-day-relative+-2": "toissapäivänä",
+	"dateFormatItem-MMMd": "d. MMM",
 	"dateFormatItem-MEd": "E d.M.",
-	"dateFormatItem-hm": "h.mm a",
-	"dayPeriods-format-abbr-pm": "ip.",
-	"dateFormat-short": "d.M.y G",
-	"dateFormatItem-yyyyM": "M.y G",
-	"dateFormatItem-yMMMEd": "EEE d. MMM y G",
-	"dateFormat-full": "cccc d. MMMM y G",
-	"dateFormatItem-Md": "d.M.",
-	"dateFormatItem-yMEd": "EEE d.M.y G",
-	"months-format-wide": [
-		"tammikuuta",
-		"helmikuuta",
-		"maaliskuuta",
-		"huhtikuuta",
-		"toukokuuta",
-		"kesäkuuta",
-		"heinäkuuta",
-		"elokuuta",
-		"syyskuuta",
-		"lokakuuta",
-		"marraskuuta",
-		"joulukuuta"
-	],
-	"dayPeriods-format-abbr-am": "ap.",
-	"dateFormatItem-d": "d",
-	"quarters-format-wide": [
-		"1. neljännes",
-		"2. neljännes",
-		"3. neljännes",
-		"4. neljännes"
-	],
+	"field-day": "päivä",
 	"days-format-wide": [
 		"sunnuntaina",
 		"maanantaina",
@@ -160,7 +178,76 @@ define(
 		"torstaina",
 		"perjantaina",
 		"lauantaina"
-	]
+	],
+	"field-zone": "aikavyöhyke",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"T",
+		"H",
+		"M",
+		"H",
+		"T",
+		"K",
+		"H",
+		"E",
+		"S",
+		"L",
+		"M",
+		"J"
+	],
+	"field-year-relative+-1": "viime vuonna",
+	"field-month-relative+-1": "viime kuussa",
+	"dateFormatItem-hm": "h.mm a",
+	"dayPeriods-format-abbr-pm": "ip.",
+	"days-format-abbr": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"K",
+		"T",
+		"P",
+		"L"
+	],
+	"dateFormatItem-yyyyMd": "d.M.y G",
+	"field-month": "kuukausi",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"K",
+		"T",
+		"P",
+		"L"
+	],
+	"dayPeriods-format-wide-am": "ap.",
+	"dateFormat-short": "d.M.y GGGGG",
+	"field-second": "sekunti",
+	"field-month-relative+0": "tässä kuussa",
+	"field-month-relative+1": "ensi kuussa",
+	"dateFormatItem-Ed": "E d.",
+	"field-week": "viikko",
+	"dateFormat-medium": "d.M.y G",
+	"field-year-relative+0": "tänä vuonna",
+	"field-week-relative+-1": "viime viikolla",
+	"dateFormatItem-yyyyM": "L.y G",
+	"field-year-relative+1": "ensi vuonna",
+	"dayPeriods-format-narrow-pm": "ip.",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-Hms": "H.mm.ss",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "tällä viikolla",
+	"field-week-relative+1": "ensi viikolla"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/chinese.js b/dojo/cldr/nls/fi/chinese.js
new file mode 100644
index 0000000..6455aec
--- /dev/null
+++ b/dojo/cldr/nls/fi/chinese.js
@@ -0,0 +1,51 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d.M.y",
+	"field-dayperiod": "vuorokaudenaika",
+	"field-minute": "minuutti",
+	"dateFormatItem-MMMEd": "E d.M.",
+	"field-day-relative+-1": "eilen",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"field-day-relative+-2": "toissapäivänä",
+	"field-weekday": "viikonpäivä",
+	"field-era": "aikakausi",
+	"field-hour": "tunti",
+	"dateFormatItem-y": "y",
+	"dateFormatItem-yyyy": "y",
+	"field-day-relative+0": "tänään",
+	"field-day-relative+1": "huomenna",
+	"field-day-relative+2": "ylihuomenna",
+	"dateFormat-long": "d.M.y",
+	"field-zone": "aikavyöhyke",
+	"dateFormatItem-Hm": "H.mm",
+	"field-week-relative+-1": "viime viikolla",
+	"dateFormat-medium": "d.M.y",
+	"dateFormatItem-Hms": "H.mm.ss",
+	"field-year-relative+0": "tänä vuonna",
+	"field-year-relative+1": "ensi vuonna",
+	"field-year-relative+-1": "viime vuonna",
+	"dateFormatItem-ms": "mm.ss",
+	"field-year": "vuosi",
+	"field-week": "viikko",
+	"dateFormatItem-yyyyMd": "d.M.y",
+	"dateFormatItem-yyyyMMMd": "d.M.y",
+	"dateFormatItem-yyyyMEd": "E d.M.y",
+	"dateFormatItem-MMMd": "d.M.",
+	"field-week-relative+0": "tällä viikolla",
+	"field-week-relative+1": "ensi viikolla",
+	"field-month-relative+0": "tässä kuussa",
+	"field-month": "kuukausi",
+	"field-month-relative+1": "ensi kuussa",
+	"dateFormatItem-H": "H",
+	"field-second": "sekunti",
+	"field-day": "päivä",
+	"dateFormatItem-MEd": "E d.M.",
+	"dateFormatItem-hm": "h.mm a",
+	"dateFormat-short": "d.M.y",
+	"dateFormat-full": "cccc d.M.y",
+	"dateFormatItem-Md": "d.M.",
+	"field-month-relative+-1": "viime kuussa"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/currency.js b/dojo/cldr/nls/fi/currency.js
index a343a24..933b18a 100644
--- a/dojo/cldr/nls/fi/currency.js
+++ b/dojo/cldr/nls/fi/currency.js
@@ -3,7 +3,6 @@ define(
 {
 	"HKD_displayName": "Hongkongin dollari",
 	"CHF_displayName": "Sveitsin frangi",
-	"CHF_symbol": "CHF",
 	"JPY_symbol": "¥",
 	"CAD_displayName": "Kanadan dollari",
 	"HKD_symbol": "HKD",
@@ -13,8 +12,10 @@ define(
 	"JPY_displayName": "Japanin jeni",
 	"CAD_symbol": "CAD",
 	"USD_displayName": "Yhdysvaltain dollari",
+	"EUR_symbol": "€",
 	"CNY_symbol": "CNY",
 	"GBP_displayName": "Englannin punta",
+	"GBP_symbol": "£",
 	"AUD_symbol": "AUD",
 	"EUR_displayName": "euro"
 }
diff --git a/dojo/cldr/nls/fi/generic.js b/dojo/cldr/nls/fi/generic.js
new file mode 100644
index 0000000..d455246
--- /dev/null
+++ b/dojo/cldr/nls/fi/generic.js
@@ -0,0 +1,71 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"field-dayperiod": "vuorokaudenaika",
+	"field-minute": "minuutti",
+	"dateFormatItem-MMMEd": "ccc d. MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "eilen",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"field-day-relative+-2": "toissapäivänä",
+	"field-weekday": "viikonpäivä",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "aikakausi",
+	"field-hour": "tunti",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d.",
+	"field-day-relative+0": "tänään",
+	"field-day-relative+1": "huomenna",
+	"field-day-relative+2": "ylihuomenna",
+	"dateFormatItem-yyyyMM": "M.y G",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"dateFormatItem-yyyyMMMM": "LLLL y G",
+	"dateFormatItem-yyyyMMMMccccd": "cccc d. MMMM y G",
+	"dateFormat-long": "d. MMMM y G",
+	"field-zone": "aikavyöhyke",
+	"dateFormatItem-Hm": "H.mm",
+	"field-week-relative+-1": "viime viikolla",
+	"dateFormat-medium": "d.M.y G",
+	"dateFormatItem-Hms": "H.mm.ss",
+	"field-year-relative+0": "tänä vuonna",
+	"field-year-relative+1": "ensi vuonna",
+	"field-year-relative+-1": "viime vuonna",
+	"dateFormatItem-ms": "mm.ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-year": "vuosi",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "viikko",
+	"dateFormatItem-yyyyMd": "d.M.y G",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"dateFormatItem-yyyyMEd": "E d.M.y G",
+	"dateFormatItem-MMMd": "d. MMM",
+	"field-week-relative+0": "tällä viikolla",
+	"field-week-relative+1": "ensi viikolla",
+	"field-month-relative+0": "tässä kuussa",
+	"dateFormatItem-H": "H",
+	"field-month": "kuukausi",
+	"field-month-relative+1": "ensi kuussa",
+	"dateFormatItem-M": "L",
+	"field-second": "sekunti",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"field-day": "päivä",
+	"dateFormatItem-MEd": "E d.M.",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "h.mm a",
+	"dateFormat-short": "d.M.y GGGGG",
+	"dateFormatItem-yyyyM": "L.y G",
+	"dateFormat-full": "cccc d. MMMM y G",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "viime kuussa",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/gregorian.js b/dojo/cldr/nls/fi/gregorian.js
index cff5051..07d7b9a 100644
--- a/dojo/cldr/nls/fi/gregorian.js
+++ b/dojo/cldr/nls/fi/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
+	],
 	"months-format-narrow": [
 		"T",
 		"H",
@@ -15,13 +24,30 @@ define(
 		"M",
 		"J"
 	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "viikonpäivä",
 	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "EEE d.M.yyyy",
-	"dateFormatItem-MMMEd": "E d. MMM",
+	"dateFormatItem-yMEd": "E d.M.y",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-MMMEd": "ccc d. MMM",
 	"eraNarrow": [
-		"eKr.",
-		"jKr."
+		"eK",
+		"jK"
+	],
+	"dateFormatItem-yMM": "M.y",
+	"days-format-short": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
 	],
 	"dateFormat-long": "d. MMMM y",
 	"months-format-wide": [
@@ -38,13 +64,15 @@ define(
 		"marraskuuta",
 		"joulukuuta"
 	],
+	"dateTimeFormat-medium": "{1} {0}",
 	"dayPeriods-format-wide-pm": "ip.",
 	"dateFormat-full": "cccc d. MMMM y",
 	"dateFormatItem-Md": "d.M.",
 	"dayPeriods-standAlone-wide-pm": "ip.",
 	"dayPeriods-format-abbr-am": "ap.",
+	"dateFormatItem-yMd": "d.M.y",
+	"dateFormatItem-yM": "L.y",
 	"field-era": "aikakausi",
-	"dateFormatItem-yM": "L.yyyy",
 	"months-standAlone-wide": [
 		"tammikuu",
 		"helmikuu",
@@ -67,10 +95,9 @@ define(
 		"4. neljännes"
 	],
 	"timeFormat-long": "H.mm.ss z",
-	"field-year": "vuosi",
 	"dateFormatItem-yMMM": "LLL y",
-	"dateFormatItem-yQ": "Q/yyyy",
-	"dateFormatItem-yyyyMMMM": "LLLL y",
+	"dateFormatItem-yQQQQ": "QQQQ y",
+	"field-year": "vuosi",
 	"field-hour": "tunti",
 	"months-format-abbr": [
 		"tammikuuta",
@@ -86,11 +113,10 @@ define(
 		"marraskuuta",
 		"joulukuuta"
 	],
-	"dateFormatItem-yyQ": "Q/yy",
 	"timeFormat-full": "H.mm.ss zzzz",
-	"dateFormatItem-yyyyMEEEd": "EEE d.M.yyyy",
 	"field-day-relative+0": "tänään",
 	"field-day-relative+1": "huomenna",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
 	"field-day-relative+2": "ylihuomenna",
 	"dateFormatItem-H": "H",
 	"months-standAlone-abbr": [
@@ -119,6 +145,7 @@ define(
 		"3. neljännes",
 		"4. neljännes"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
 		"sunnuntai",
@@ -129,7 +156,6 @@ define(
 		"perjantai",
 		"lauantai"
 	],
-	"dateFormatItem-yyMMM": "LLLL yy",
 	"timeFormat-medium": "H.mm.ss",
 	"dateFormatItem-Hm": "H.mm",
 	"quarters-standAlone-abbr": [
@@ -143,7 +169,7 @@ define(
 		"jKr."
 	],
 	"field-minute": "minuutti",
-	"field-dayperiod": "ap./ip.",
+	"field-dayperiod": "vuorokaudenaika",
 	"days-standAlone-abbr": [
 		"su",
 		"ma",
@@ -155,12 +181,23 @@ define(
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm.ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "eilen",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "ap.",
 	"field-day-relative+-2": "toissapäivänä",
 	"dateFormatItem-MMMd": "d. MMM",
 	"dateFormatItem-MEd": "E d.M.",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-yMMMM": "LLLL y",
+	"dateFormatItem-yMMMMccccd": "cccc d. MMMM y",
 	"field-day": "päivä",
-	"dateFormatItem-yMMMMccccd": "cccc, d. MMMM y",
 	"days-format-wide": [
 		"sunnuntaina",
 		"maanantaina",
@@ -186,7 +223,8 @@ define(
 		"M",
 		"J"
 	],
-	"dateFormatItem-yyMM": "M/yy",
+	"field-year-relative+-1": "viime vuonna",
+	"field-month-relative+-1": "viime kuussa",
 	"dateFormatItem-hm": "h.mm a",
 	"dayPeriods-format-abbr-pm": "ip.",
 	"days-format-abbr": [
@@ -198,6 +236,7 @@ define(
 		"pe",
 		"la"
 	],
+	"dateFormatItem-yMMMd": "d. MMM y",
 	"eraNames": [
 		"ennen Kristuksen syntymää",
 		"jälkeen Kristuksen syntymän"
@@ -211,7 +250,6 @@ define(
 		"P",
 		"L"
 	],
-	"field-month": "kuukausi",
 	"days-standAlone-narrow": [
 		"S",
 		"M",
@@ -222,18 +260,27 @@ define(
 		"L"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "kuukausi",
 	"dayPeriods-format-wide-am": "ap.",
 	"dayPeriods-standAlone-wide-am": "ap.",
-	"dateFormat-short": "d.M.yyyy",
+	"dateFormat-short": "d.M.y",
 	"field-second": "sekunti",
-	"dateFormatItem-yMMMEd": "EEE d. MMM y",
-	"dateFormatItem-Ed": "ccc d.",
+	"dateFormatItem-yMMMEd": "E d. MMM y",
+	"field-month-relative+0": "tässä kuussa",
+	"field-month-relative+1": "ensi kuussa",
+	"dateFormatItem-Ed": "E d.",
 	"field-week": "viikko",
-	"dateFormat-medium": "d.M.yyyy",
-	"dateFormatItem-yyyyM": "M/yyyy",
-	"dateFormatItem-yyyyQQQQ": "QQQQ y",
+	"dateFormat-medium": "d.M.y",
+	"field-year-relative+0": "tänä vuonna",
+	"field-week-relative+-1": "viime viikolla",
+	"field-year-relative+1": "ensi vuonna",
+	"dayPeriods-format-narrow-pm": "ip.",
+	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "H.mm.ss",
-	"dateFormatItem-hms": "h.mm.ss a"
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"field-week-relative+0": "tällä viikolla",
+	"field-week-relative+1": "ensi viikolla"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/hebrew.js b/dojo/cldr/nls/fi/hebrew.js
index 7c60e23..b99c282 100644
--- a/dojo/cldr/nls/fi/hebrew.js
+++ b/dojo/cldr/nls/fi/hebrew.js
@@ -1,23 +1,16 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "L.yyyy",
-	"dateFormatItem-yQ": "Q/yyyy",
-	"months-standAlone-abbr-leap": "adár II",
-	"dayPeriods-format-wide-pm": "ip.",
-	"dateFormatItem-MMMEd": "E d. MMM",
-	"dateFormatItem-hms": "h.mm.ss a",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"days-standAlone-wide": [
-		"sunnuntai",
-		"maanantai",
-		"tiistai",
-		"keskiviikko",
-		"torstai",
-		"perjantai",
-		"lauantai"
+	"days-standAlone-short": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
 	],
-	"months-standAlone-narrow": [
+	"months-format-narrow": [
 		"T",
 		"H",
 		"K",
@@ -32,40 +25,42 @@ define(
 		"A",
 		"E"
 	],
-	"dayPeriods-format-wide-am": "ap.",
-	"timeFormat-full": "H.mm.ss zzzz",
+	"field-weekday": "viikonpäivä",
 	"months-standAlone-narrow-leap": "A",
-	"months-standAlone-abbr": [
-		"tišrí",
-		"hešván",
-		"kislév",
-		"tevét",
-		"ševát",
-		"adár I",
-		"adár",
-		"nisán",
-		"ijjár",
-		"siván",
-		"tammúz",
-		"ab",
-		"elúl"
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-MMMEd": "ccc d. MMM",
+	"days-format-short": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
 	],
-	"dateFormatItem-yMMM": "LLL y",
-	"days-standAlone-narrow": [
-		"S",
-		"M",
-		"T",
-		"K",
-		"T",
-		"P",
-		"L"
+	"dateFormat-long": "d. MMMM y G",
+	"months-format-wide": [
+		"tišríkuuta",
+		"hešvánkuuta",
+		"kislévkuuta",
+		"tevétkuuta",
+		"ševátkuuta",
+		"adárkuuta I",
+		"adárkuuta",
+		"nisánkuuta",
+		"ijjárkuuta",
+		"sivánkuuta",
+		"tammúzkuuta",
+		"abkuuta",
+		"elúlkuuta"
 	],
-	"dateFormat-long": "d. MMMM y",
-	"timeFormat-medium": "H.mm.ss",
-	"dateFormatItem-Hm": "H.mm",
-	"dateFormat-medium": "d.M.yyyy",
-	"dateFormatItem-Hms": "H.mm.ss",
-	"dateFormatItem-ms": "mm.ss",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dayPeriods-format-wide-pm": "ip.",
+	"dateFormat-full": "cccc d. MMMM y G",
+	"dateFormatItem-yyyyMEd": "E d.M.y G",
+	"dateFormatItem-Md": "d.M.",
+	"dayPeriods-format-abbr-am": "ap.",
+	"field-era": "aikakausi",
 	"months-standAlone-wide": [
 		"tišríkuu",
 		"hešvánkuu",
@@ -81,8 +76,16 @@ define(
 		"abkuu",
 		"elúlkuu"
 	],
-	"dateFormatItem-MMMd": "d. MMM",
+	"timeFormat-short": "H.mm",
+	"quarters-format-wide": [
+		"1. neljännes",
+		"2. neljännes",
+		"3. neljännes",
+		"4. neljännes"
+	],
 	"timeFormat-long": "H.mm.ss z",
+	"field-year": "vuosi",
+	"field-hour": "tunti",
 	"months-format-abbr": [
 		"tišríkuuta",
 		"hešvánkuuta",
@@ -98,15 +101,64 @@ define(
 		"abkuuta",
 		"elúlkuuta"
 	],
-	"timeFormat-short": "H.mm",
+	"timeFormat-full": "H.mm.ss zzzz",
+	"field-day-relative+0": "tänään",
+	"field-day-relative+1": "huomenna",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"field-day-relative+2": "ylihuomenna",
 	"dateFormatItem-H": "H",
+	"months-standAlone-abbr": [
+		"tišrí",
+		"hešván",
+		"kislév",
+		"tevét",
+		"ševát",
+		"adár I",
+		"adár",
+		"nisán",
+		"ijjár",
+		"siván",
+		"tammúz",
+		"ab",
+		"elúl"
+	],
 	"quarters-format-abbr": [
 		"1. nelj.",
 		"2. nelj.",
 		"3. nelj.",
 		"4. nelj."
 	],
-	"days-format-abbr": [
+	"quarters-standAlone-wide": [
+		"1. neljännes",
+		"2. neljännes",
+		"3. neljännes",
+		"4. neljännes"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"days-standAlone-wide": [
+		"sunnuntai",
+		"maanantai",
+		"tiistai",
+		"keskiviikko",
+		"torstai",
+		"perjantai",
+		"lauantai"
+	],
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"months-standAlone-wide-leap": "adárkuu II",
+	"timeFormat-medium": "H.mm.ss",
+	"dateFormatItem-Hm": "H.mm",
+	"quarters-standAlone-abbr": [
+		"1. nelj.",
+		"2. nelj.",
+		"3. nelj.",
+		"4. nelj."
+	],
+	"field-minute": "minuutti",
+	"field-dayperiod": "vuorokaudenaika",
+	"days-standAlone-abbr": [
 		"su",
 		"ma",
 		"ti",
@@ -115,8 +167,26 @@ define(
 		"pe",
 		"la"
 	],
+	"dateFormatItem-ms": "mm.ss",
+	"field-day-relative+-1": "eilen",
+	"dayPeriods-format-narrow-am": "ap.",
+	"field-day-relative+-2": "toissapäivänä",
+	"dateFormatItem-MMMd": "d. MMM",
 	"dateFormatItem-MEd": "E d.M.",
-	"months-format-narrow": [
+	"field-day": "päivä",
+	"days-format-wide": [
+		"sunnuntaina",
+		"maanantaina",
+		"tiistaina",
+		"keskiviikkona",
+		"torstaina",
+		"perjantaina",
+		"lauantaina"
+	],
+	"field-zone": "aikavyöhyke",
+	"months-standAlone-abbr-leap": "adár II",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
 		"T",
 		"H",
 		"K",
@@ -131,46 +201,60 @@ define(
 		"A",
 		"E"
 	],
+	"field-year-relative+-1": "viime vuonna",
+	"field-month-relative+-1": "viime kuussa",
 	"dateFormatItem-hm": "h.mm a",
-	"months-standAlone-wide-leap": "adárkuu II",
 	"dayPeriods-format-abbr-pm": "ip.",
-	"dateFormat-short": "d.M.yyyy",
-	"dateFormatItem-yMMMEd": "EEE d. MMM y",
-	"dateFormat-full": "cccc d. MMMM y",
-	"dateFormatItem-Md": "d.M.",
-	"dateFormatItem-yMEd": "EEE d.M.yyyy",
-	"months-format-wide": [
-		"tišríkuuta",
-		"hešvánkuuta",
-		"kislévkuuta",
-		"tevétkuuta",
-		"ševátkuuta",
-		"adárkuuta I",
-		"adárkuuta",
-		"nisánkuuta",
-		"ijjárkuuta",
-		"sivánkuuta",
-		"tammúzkuuta",
-		"abkuuta",
-		"elúlkuuta"
+	"days-format-abbr": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
 	],
-	"dayPeriods-format-abbr-am": "ap.",
-	"quarters-format-wide": [
-		"1. neljännes",
-		"2. neljännes",
-		"3. neljännes",
-		"4. neljännes"
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"K",
+		"T",
+		"P",
+		"L"
+	],
+	"dateFormatItem-yyyyMd": "d.M.y G",
+	"field-month": "kuukausi",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"K",
+		"T",
+		"P",
+		"L"
 	],
+	"dayPeriods-format-wide-am": "ap.",
+	"dateFormat-short": "d.M.y GGGGG",
+	"field-second": "sekunti",
+	"field-month-relative+0": "tässä kuussa",
+	"field-month-relative+1": "ensi kuussa",
+	"dateFormatItem-Ed": "E d.",
+	"field-week": "viikko",
+	"dateFormat-medium": "d.M.y G",
+	"field-year-relative+0": "tänä vuonna",
+	"field-week-relative+-1": "viime viikolla",
+	"dateFormatItem-yyyyM": "L.y G",
+	"field-year-relative+1": "ensi vuonna",
+	"dayPeriods-format-narrow-pm": "ip.",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-Hms": "H.mm.ss",
+	"dateFormatItem-hms": "h.mm.ss a",
 	"months-format-wide-leap": "adárkuuta II",
-	"days-format-wide": [
-		"sunnuntaina",
-		"maanantaina",
-		"tiistaina",
-		"keskiviikkona",
-		"torstaina",
-		"perjantaina",
-		"lauantaina"
-	]
+	"dateFormatItem-GyMMM": "LLL y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "tällä viikolla",
+	"field-week-relative+1": "ensi viikolla"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/islamic.js b/dojo/cldr/nls/fi/islamic.js
index a8a8686..bb8042e 100644
--- a/dojo/cldr/nls/fi/islamic.js
+++ b/dojo/cldr/nls/fi/islamic.js
@@ -1,29 +1,29 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "L.yyyy",
-	"dateFormatItem-yyyyMMMEd": "EEE d. MMM y G",
-	"dateFormatItem-yQ": "Q/yyyy",
-	"dayPeriods-format-wide-pm": "ip.",
-	"dateFormatItem-MMMEd": "E d. MMM",
-	"dateFormatItem-hms": "h.mm.ss a",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"days-standAlone-wide": [
-		"sunnuntai",
-		"maanantai",
-		"tiistai",
-		"keskiviikko",
-		"torstai",
-		"perjantai",
-		"lauantai"
+	"days-standAlone-short": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
 	],
-	"dateFormatItem-MMM": "LLL",
-	"dateFormatItem-Gy": "y G",
-	"dayPeriods-format-wide-am": "ap.",
-	"dateFormatItem-y": "y G",
-	"timeFormat-full": "H.mm.ss zzzz",
-	"dateFormatItem-yyyy": "y G",
-	"months-standAlone-abbr": [
+	"field-weekday": "viikonpäivä",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-MMMEd": "ccc d. MMM",
+	"days-format-short": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
+	],
+	"dateFormat-long": "d. MMMM y G",
+	"months-format-wide": [
 		"muharram",
 		"safar",
 		"rabi’ al-awwal",
@@ -37,27 +37,13 @@ define(
 		"dhu-l-qa’da",
 		"dhu-l-hiddža"
 	],
-	"dateFormatItem-Ed": "ccc d.",
-	"dateFormatItem-yMMM": "LLL y",
-	"days-standAlone-narrow": [
-		"S",
-		"M",
-		"T",
-		"K",
-		"T",
-		"P",
-		"L"
-	],
-	"dateFormatItem-yyyyMMMMccccd": "cccc, d. MMMM y G",
-	"dateFormatItem-yyyyMM": "M.y G",
-	"dateFormatItem-yyyyMMMM": "LLLL y G",
-	"dateFormat-long": "d. MMMM y G",
-	"timeFormat-medium": "H.mm.ss",
-	"dateFormatItem-Hm": "H.mm",
-	"dateFormat-medium": "d.M.y G",
-	"dateFormatItem-Hms": "H.mm.ss",
-	"dateFormatItem-ms": "mm.ss",
-	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dayPeriods-format-wide-pm": "ip.",
+	"dateFormat-full": "cccc d. MMMM y G",
+	"dateFormatItem-yyyyMEd": "E d.M.y G",
+	"dateFormatItem-Md": "d.M.",
+	"dayPeriods-format-abbr-am": "ap.",
+	"field-era": "aikakausi",
 	"months-standAlone-wide": [
 		"muharram",
 		"safar",
@@ -72,9 +58,16 @@ define(
 		"dhu-l-qa’da",
 		"dhu-l-hiddža"
 	],
-	"dateFormatItem-yyyyMEd": "EEE d.M.y G",
-	"dateFormatItem-MMMd": "d. MMM",
+	"timeFormat-short": "H.mm",
+	"quarters-format-wide": [
+		"1. neljännes",
+		"2. neljännes",
+		"3. neljännes",
+		"4. neljännes"
+	],
 	"timeFormat-long": "H.mm.ss z",
+	"field-year": "vuosi",
+	"field-hour": "tunti",
 	"months-format-abbr": [
 		"muharram",
 		"safar",
@@ -89,36 +82,13 @@ define(
 		"dhu-l-qa’da",
 		"dhu-l-hiddža"
 	],
-	"timeFormat-short": "H.mm",
+	"timeFormat-full": "H.mm.ss zzzz",
+	"field-day-relative+0": "tänään",
+	"field-day-relative+1": "huomenna",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"field-day-relative+2": "ylihuomenna",
 	"dateFormatItem-H": "H",
-	"quarters-format-abbr": [
-		"1. nelj.",
-		"2. nelj.",
-		"3. nelj.",
-		"4. nelj."
-	],
-	"days-format-abbr": [
-		"su",
-		"ma",
-		"ti",
-		"ke",
-		"to",
-		"pe",
-		"la"
-	],
-	"dateFormatItem-M": "L",
-	"dateFormatItem-yyyyQQQ": "QQQ y G",
-	"dateFormatItem-MEd": "E d.M.",
-	"dateFormatItem-hm": "h.mm a",
-	"dayPeriods-format-abbr-pm": "ip.",
-	"dateFormat-short": "d.M.y G",
-	"dateFormatItem-yyyyM": "M.y G",
-	"dateFormatItem-yMMMEd": "EEE d. MMM y",
-	"dateFormat-full": "cccc d. MMMM y G",
-	"dateFormatItem-Md": "d.M.",
-	"dateFormatItem-yyyyQ": "Q/y G",
-	"dateFormatItem-yMEd": "EEE d.M.yyyy",
-	"months-format-wide": [
+	"months-standAlone-abbr": [
 		"muharram",
 		"safar",
 		"rabi’ al-awwal",
@@ -132,15 +102,57 @@ define(
 		"dhu-l-qa’da",
 		"dhu-l-hiddža"
 	],
-	"dayPeriods-format-abbr-am": "ap.",
-	"dateFormatItem-yyyyMMM": "LLLL y G",
-	"dateFormatItem-d": "d",
-	"quarters-format-wide": [
+	"quarters-format-abbr": [
+		"1. nelj.",
+		"2. nelj.",
+		"3. nelj.",
+		"4. nelj."
+	],
+	"quarters-standAlone-wide": [
 		"1. neljännes",
 		"2. neljännes",
 		"3. neljännes",
 		"4. neljännes"
 	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"days-standAlone-wide": [
+		"sunnuntai",
+		"maanantai",
+		"tiistai",
+		"keskiviikko",
+		"torstai",
+		"perjantai",
+		"lauantai"
+	],
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"timeFormat-medium": "H.mm.ss",
+	"dateFormatItem-Hm": "H.mm",
+	"quarters-standAlone-abbr": [
+		"1. nelj.",
+		"2. nelj.",
+		"3. nelj.",
+		"4. nelj."
+	],
+	"field-minute": "minuutti",
+	"field-dayperiod": "vuorokaudenaika",
+	"days-standAlone-abbr": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
+	],
+	"dateFormatItem-ms": "mm.ss",
+	"field-day-relative+-1": "eilen",
+	"dayPeriods-format-narrow-am": "ap.",
+	"field-day-relative+-2": "toissapäivänä",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-MEd": "E d.M.",
+	"field-day": "päivä",
 	"days-format-wide": [
 		"sunnuntaina",
 		"maanantaina",
@@ -149,7 +161,62 @@ define(
 		"torstaina",
 		"perjantaina",
 		"lauantaina"
-	]
+	],
+	"field-zone": "aikavyöhyke",
+	"dateFormatItem-y": "y G",
+	"field-year-relative+-1": "viime vuonna",
+	"field-month-relative+-1": "viime kuussa",
+	"dateFormatItem-hm": "h.mm a",
+	"dayPeriods-format-abbr-pm": "ip.",
+	"days-format-abbr": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"K",
+		"T",
+		"P",
+		"L"
+	],
+	"dateFormatItem-yyyyMd": "d.M.y G",
+	"field-month": "kuukausi",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"K",
+		"T",
+		"P",
+		"L"
+	],
+	"dayPeriods-format-wide-am": "ap.",
+	"dateFormat-short": "d.M.y GGGGG",
+	"field-second": "sekunti",
+	"field-month-relative+0": "tässä kuussa",
+	"field-month-relative+1": "ensi kuussa",
+	"dateFormatItem-Ed": "E d.",
+	"field-week": "viikko",
+	"dateFormat-medium": "d.M.y G",
+	"field-year-relative+0": "tänä vuonna",
+	"field-week-relative+-1": "viime viikolla",
+	"dateFormatItem-yyyyM": "L.y G",
+	"field-year-relative+1": "ensi vuonna",
+	"dayPeriods-format-narrow-pm": "ip.",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-Hms": "H.mm.ss",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "tällä viikolla",
+	"field-week-relative+1": "ensi viikolla"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/japanese.js b/dojo/cldr/nls/fi/japanese.js
new file mode 100644
index 0000000..6d4bf02
--- /dev/null
+++ b/dojo/cldr/nls/fi/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d.M.y G",
+	"field-second": "sekunti",
+	"field-year-relative+-1": "viime vuonna",
+	"field-week": "viikko",
+	"field-month-relative+-1": "viime kuussa",
+	"field-day-relative+-1": "eilen",
+	"field-day-relative+-2": "toissapäivänä",
+	"field-year": "vuosi",
+	"field-week-relative+0": "tällä viikolla",
+	"field-week-relative+1": "ensi viikolla",
+	"field-minute": "minuutti",
+	"field-week-relative+-1": "viime viikolla",
+	"field-day-relative+0": "tänään",
+	"field-hour": "tunti",
+	"field-day-relative+1": "huomenna",
+	"dateFormat-long": "d. MMMM y G",
+	"field-day-relative+2": "ylihuomenna",
+	"field-day": "päivä",
+	"field-month-relative+0": "tässä kuussa",
+	"field-month-relative+1": "ensi kuussa",
+	"field-dayperiod": "vuorokaudenaika",
+	"field-month": "kuukausi",
+	"dateFormat-short": "d.M.y GGGGG",
+	"field-era": "aikakausi",
+	"field-year-relative+0": "tänä vuonna",
+	"field-year-relative+1": "ensi vuonna",
+	"dateFormat-full": "cccc d. MMMM y G",
+	"field-weekday": "viikonpäivä",
+	"field-zone": "aikavyöhyke"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/number.js b/dojo/cldr/nls/fi/number.js
index 1d0eda5..d077262 100644
--- a/dojo/cldr/nls/fi/number.js
+++ b/dojo/cldr/nls/fi/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0 %",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "epäluku",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 biljoonaa",
+	"decimalFormat-short": "000 bilj'.'"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/roc.js b/dojo/cldr/nls/fi/roc.js
new file mode 100644
index 0000000..7228a16
--- /dev/null
+++ b/dojo/cldr/nls/fi/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "sekunti",
+	"field-year-relative+-1": "viime vuonna",
+	"field-week": "viikko",
+	"field-month-relative+-1": "viime kuussa",
+	"field-day-relative+-1": "eilen",
+	"field-day-relative+-2": "toissapäivänä",
+	"field-year": "vuosi",
+	"field-week-relative+0": "tällä viikolla",
+	"field-week-relative+1": "ensi viikolla",
+	"field-minute": "minuutti",
+	"field-week-relative+-1": "viime viikolla",
+	"field-day-relative+0": "tänään",
+	"field-hour": "tunti",
+	"field-day-relative+1": "huomenna",
+	"field-day-relative+2": "ylihuomenna",
+	"field-day": "päivä",
+	"field-month-relative+0": "tässä kuussa",
+	"field-month-relative+1": "ensi kuussa",
+	"field-dayperiod": "vuorokaudenaika",
+	"field-month": "kuukausi",
+	"field-era": "aikakausi",
+	"field-year-relative+0": "tänä vuonna",
+	"field-year-relative+1": "ensi vuonna",
+	"eraAbbr": [
+		"Before R.O.C.",
+		"Minguo"
+	],
+	"field-weekday": "viikonpäivä",
+	"field-zone": "aikavyöhyke"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr-ch/currency.js b/dojo/cldr/nls/fr-ch/currency.js
new file mode 100644
index 0000000..1b66d5d
--- /dev/null
+++ b/dojo/cldr/nls/fr-ch/currency.js
@@ -0,0 +1,7 @@
+define(
+//begin v1.x content
+{
+	"CHF_symbol": "CHF"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr-ch/generic.js b/dojo/cldr/nls/fr-ch/generic.js
new file mode 100644
index 0000000..8ed2024
--- /dev/null
+++ b/dojo/cldr/nls/fr-ch/generic.js
@@ -0,0 +1,8 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormat-short": "dd.MM.yy GGGGG"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/buddhist.js b/dojo/cldr/nls/fr/buddhist.js
new file mode 100644
index 0000000..fd63ecb
--- /dev/null
+++ b/dojo/cldr/nls/fr/buddhist.js
@@ -0,0 +1,242 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "cadran",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-minute": "minute",
+	"eraNames": [
+		"ère bouddhiste"
+	],
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "hier",
+	"field-weekday": "jour de la semaine",
+	"field-day-relative+-2": "avant-hier",
+	"days-standAlone-wide": [
+		"dimanche",
+		"lundi",
+		"mardi",
+		"mercredi",
+		"jeudi",
+		"vendredi",
+		"samedi"
+	],
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-era": "ère",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "heure",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"janv.",
+		"févr.",
+		"mars",
+		"avr.",
+		"mai",
+		"juin",
+		"juil.",
+		"août",
+		"sept.",
+		"oct.",
+		"nov.",
+		"déc."
+	],
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "aujourd’hui",
+	"field-day-relative+1": "demain",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"eraAbbr": [
+		"ère b."
+	],
+	"field-day-relative+2": "après-demain",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "fuseau horaire",
+	"field-week-relative+-1": "la semaine dernière",
+	"dateFormat-medium": "d MMM y G",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "cette année",
+	"field-year-relative+1": "l’année prochaine",
+	"quarters-standAlone-wide": [
+		"1er trimestre",
+		"2e trimestre",
+		"3e trimestre",
+		"4e trimestre"
+	],
+	"field-year-relative+-1": "l’année dernière",
+	"field-year": "année",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-week": "semaine",
+	"months-standAlone-wide": [
+		"janvier",
+		"février",
+		"mars",
+		"avril",
+		"mai",
+		"juin",
+		"juillet",
+		"août",
+		"septembre",
+		"octobre",
+		"novembre",
+		"décembre"
+	],
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"dateFormatItem-yyyyMEd": "E d/M/y GGGGG",
+	"field-week-relative+0": "cette semaine",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+1": "la semaine prochaine",
+	"months-format-abbr": [
+		"janv.",
+		"févr.",
+		"mars",
+		"avr.",
+		"mai",
+		"juin",
+		"juil.",
+		"août",
+		"sept.",
+		"oct.",
+		"nov.",
+		"déc."
+	],
+	"field-month-relative+0": "ce mois-ci",
+	"field-month": "mois",
+	"field-month-relative+1": "le mois prochain",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
+		"sam."
+	],
+	"days-format-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"field-second": "seconde",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "jour",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E d/M",
+	"months-format-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"days-standAlone-short": [
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
+		"sam."
+	],
+	"days-standAlone-abbr": [
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
+		"sam."
+	],
+	"dateFormat-short": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"months-format-wide": [
+		"janvier",
+		"février",
+		"mars",
+		"avril",
+		"mai",
+		"juin",
+		"juillet",
+		"août",
+		"septembre",
+		"octobre",
+		"novembre",
+		"décembre"
+	],
+	"days-format-short": [
+		"di",
+		"lu",
+		"ma",
+		"me",
+		"je",
+		"ve",
+		"sa"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "le mois dernier",
+	"quarters-format-wide": [
+		"1er trimestre",
+		"2e trimestre",
+		"3e trimestre",
+		"4e trimestre"
+	],
+	"eraNarrow": "E.B.",
+	"days-format-wide": [
+		"dimanche",
+		"lundi",
+		"mardi",
+		"mercredi",
+		"jeudi",
+		"vendredi",
+		"samedi"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/chinese.js b/dojo/cldr/nls/fr/chinese.js
new file mode 100644
index 0000000..2186162
--- /dev/null
+++ b/dojo/cldr/nls/fr/chinese.js
@@ -0,0 +1,85 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d MMM U",
+	"field-dayperiod": "cadran",
+	"field-minute": "minute",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "hier",
+	"field-day-relative+-2": "avant-hier",
+	"field-weekday": "jour de la semaine",
+	"dateFormatItem-MMM": "LLL",
+	"field-era": "ère",
+	"dateFormatItem-Gy": "U",
+	"field-hour": "heure",
+	"dateFormatItem-y": "U",
+	"dateFormatItem-yyyy": "U",
+	"field-day-relative+0": "aujourd’hui",
+	"field-day-relative+1": "demain",
+	"field-day-relative+2": "après-demain",
+	"dateFormatItem-GyMMMd": "d MMM U",
+	"dateFormat-long": "d MMMM U",
+	"field-zone": "fuseau horaire",
+	"field-week-relative+-1": "la semaine dernière",
+	"dateFormat-medium": "d MMM U",
+	"field-year-relative+0": "cette année",
+	"field-year-relative+1": "l’année prochaine",
+	"dateFormatItem-yMd": "d/M/y",
+	"field-year-relative+-1": "l’année dernière",
+	"dateFormatItem-ms": "mm:ss",
+	"field-year": "année",
+	"dateFormatItem-yyyyQQQQ": "QQQQ U",
+	"field-week": "semaine",
+	"dateFormatItem-yyyyMd": "d/M/y",
+	"dateFormatItem-yyyyMMMd": "d MMM U",
+	"dateFormatItem-yyyyMEd": "E d/M/y",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "cette semaine",
+	"field-week-relative+1": "la semaine prochaine",
+	"months-format-abbr": [
+		"1yuè",
+		"2yuè",
+		"3yuè",
+		"4yuè",
+		"5yuè",
+		"6yuè",
+		"7yuè",
+		"8yuè",
+		"9yuè",
+		"10yuè",
+		"11yuè",
+		"12yuè"
+	],
+	"field-month-relative+0": "ce mois-ci",
+	"field-month": "mois",
+	"field-month-relative+1": "le mois prochain",
+	"dateFormatItem-M": "L",
+	"field-second": "seconde",
+	"dateFormatItem-GyMMMEd": "E d MMM U",
+	"dateFormatItem-GyMMM": "MMM U",
+	"field-day": "jour",
+	"dateFormatItem-yyyyQQQ": "QQQ U",
+	"dateFormatItem-MEd": "E d/M",
+	"dateFormat-short": "d/M/y",
+	"dateFormatItem-yyyyM": "M/y",
+	"dateFormat-full": "EEEE d MMMM U",
+	"dateFormatItem-Md": "d/M",
+	"months-format-wide": [
+		"zhēngyuè",
+		"èryuè",
+		"sānyuè",
+		"sìyuè",
+		"wǔyuè",
+		"liùyuè",
+		"qīyuè",
+		"bāyuè",
+		"jiǔyuè",
+		"shíyuè",
+		"shíyīyuè",
+		"shí’èryuè"
+	],
+	"dateFormatItem-yyyyMMM": "MMM U",
+	"field-month-relative+-1": "le mois dernier"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/coptic.js b/dojo/cldr/nls/fr/coptic.js
new file mode 100644
index 0000000..e38da0f
--- /dev/null
+++ b/dojo/cldr/nls/fr/coptic.js
@@ -0,0 +1,31 @@
+define(
+//begin v1.x content
+{
+	"field-second": "seconde",
+	"field-year-relative+-1": "l’année dernière",
+	"field-week": "semaine",
+	"field-month-relative+-1": "le mois dernier",
+	"field-day-relative+-1": "hier",
+	"field-day-relative+-2": "avant-hier",
+	"field-year": "année",
+	"field-week-relative+0": "cette semaine",
+	"field-week-relative+1": "la semaine prochaine",
+	"field-minute": "minute",
+	"field-week-relative+-1": "la semaine dernière",
+	"field-day-relative+0": "aujourd’hui",
+	"field-hour": "heure",
+	"field-day-relative+1": "demain",
+	"field-day-relative+2": "après-demain",
+	"field-day": "jour",
+	"field-month-relative+0": "ce mois-ci",
+	"field-month-relative+1": "le mois prochain",
+	"field-dayperiod": "cadran",
+	"field-month": "mois",
+	"field-era": "ère",
+	"field-year-relative+0": "cette année",
+	"field-year-relative+1": "l’année prochaine",
+	"field-weekday": "jour de la semaine",
+	"field-zone": "fuseau horaire"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/currency.js b/dojo/cldr/nls/fr/currency.js
index e454a0b..bfdd768 100644
--- a/dojo/cldr/nls/fr/currency.js
+++ b/dojo/cldr/nls/fr/currency.js
@@ -3,7 +3,6 @@ define(
 {
 	"HKD_displayName": "dollar de Hong Kong",
 	"CHF_displayName": "franc suisse",
-	"CHF_symbol": "CHF",
 	"JPY_symbol": "¥JP",
 	"CAD_displayName": "dollar canadien",
 	"HKD_symbol": "$HK",
@@ -13,7 +12,8 @@ define(
 	"JPY_displayName": "yen japonais",
 	"CAD_symbol": "$CA",
 	"USD_displayName": "dollar des États-Unis",
-	"CNY_symbol": "Ұ",
+	"EUR_symbol": "€",
+	"CNY_symbol": "¥CN",
 	"GBP_displayName": "livre sterling",
 	"GBP_symbol": "£UK",
 	"AUD_symbol": "$AU",
diff --git a/dojo/cldr/nls/fr/ethiopic.js b/dojo/cldr/nls/fr/ethiopic.js
new file mode 100644
index 0000000..e38da0f
--- /dev/null
+++ b/dojo/cldr/nls/fr/ethiopic.js
@@ -0,0 +1,31 @@
+define(
+//begin v1.x content
+{
+	"field-second": "seconde",
+	"field-year-relative+-1": "l’année dernière",
+	"field-week": "semaine",
+	"field-month-relative+-1": "le mois dernier",
+	"field-day-relative+-1": "hier",
+	"field-day-relative+-2": "avant-hier",
+	"field-year": "année",
+	"field-week-relative+0": "cette semaine",
+	"field-week-relative+1": "la semaine prochaine",
+	"field-minute": "minute",
+	"field-week-relative+-1": "la semaine dernière",
+	"field-day-relative+0": "aujourd’hui",
+	"field-hour": "heure",
+	"field-day-relative+1": "demain",
+	"field-day-relative+2": "après-demain",
+	"field-day": "jour",
+	"field-month-relative+0": "ce mois-ci",
+	"field-month-relative+1": "le mois prochain",
+	"field-dayperiod": "cadran",
+	"field-month": "mois",
+	"field-era": "ère",
+	"field-year-relative+0": "cette année",
+	"field-year-relative+1": "l’année prochaine",
+	"field-weekday": "jour de la semaine",
+	"field-zone": "fuseau horaire"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/generic.js b/dojo/cldr/nls/fr/generic.js
new file mode 100644
index 0000000..5709c1a
--- /dev/null
+++ b/dojo/cldr/nls/fr/generic.js
@@ -0,0 +1,69 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-dayperiod": "cadran",
+	"field-minute": "minute",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "hier",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "avant-hier",
+	"field-weekday": "jour de la semaine",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "ère",
+	"field-hour": "heure",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "aujourd’hui",
+	"field-day-relative+1": "demain",
+	"field-day-relative+2": "après-demain",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "fuseau horaire",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "la semaine dernière",
+	"dateFormat-medium": "d MMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "cette année",
+	"field-year-relative+1": "l’année prochaine",
+	"field-year-relative+-1": "l’année dernière",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-year": "année",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "semaine",
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMEd": "E d/M/y GGGGG",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "cette semaine",
+	"field-week-relative+1": "la semaine prochaine",
+	"field-month-relative+0": "ce mois-ci",
+	"dateFormatItem-H": "HH",
+	"field-month": "mois",
+	"field-month-relative+1": "le mois prochain",
+	"dateFormatItem-M": "L",
+	"field-second": "seconde",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "jour",
+	"dateFormatItem-MEd": "E d/M",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "le mois dernier",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/gregorian.js b/dojo/cldr/nls/fr/gregorian.js
index ec37fb2..6ab4cc8 100644
--- a/dojo/cldr/nls/fr/gregorian.js
+++ b/dojo/cldr/nls/fr/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
+		"sam."
+	],
 	"months-format-narrow": [
 		"J",
 		"F",
@@ -15,17 +24,31 @@ define(
 		"N",
 		"D"
 	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "jour de la semaine",
-	"dateFormatItem-yyQQQQ": "QQQQ yy",
 	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "EEE d/M/yyyy",
+	"dateFormatItem-yMEd": "E d/M/y",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
 	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
 		"av. J.-C.",
 		"ap. J.-C."
 	],
 	"dayPeriods-format-wide-morning": "matin",
-	"dateFormatItem-MMMdd": "dd MMM",
+	"days-format-short": [
+		"di",
+		"lu",
+		"ma",
+		"me",
+		"je",
+		"ve",
+		"sa"
+	],
 	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
 		"janvier",
@@ -41,12 +64,15 @@ define(
 		"novembre",
 		"décembre"
 	],
+	"dateTimeFormat-medium": "{1} {0}",
 	"dayPeriods-format-wide-pm": "PM",
 	"dateFormat-full": "EEEE d MMMM y",
 	"dateFormatItem-Md": "d/M",
+	"dayPeriods-format-abbr-am": "AM",
 	"dayPeriods-format-wide-noon": "midi",
+	"dateFormatItem-yMd": "d/M/y",
 	"field-era": "ère",
-	"dateFormatItem-yM": "M/yyyy",
+	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
 		"janvier",
 		"février",
@@ -68,13 +94,11 @@ define(
 		"3e trimestre",
 		"4e trimestre"
 	],
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-long": "HH:mm:ss z",
 	"field-year": "année",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "'T'Q y",
-	"dateFormatItem-yyyyMMMM": "MMMM y",
 	"field-hour": "heure",
-	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
 		"janv.",
 		"févr.",
@@ -89,12 +113,13 @@ define(
 		"nov.",
 		"déc."
 	],
-	"dateFormatItem-yyQ": "'T'Q yy",
 	"timeFormat-full": "HH:mm:ss zzzz",
+	"dayPeriods-format-narrow-morning": "matin",
 	"field-day-relative+0": "aujourd’hui",
 	"field-day-relative+1": "demain",
+	"dateFormatItem-GyMMMd": "d MMM y G",
 	"field-day-relative+2": "après-demain",
-	"field-day-relative+3": "après-après-demain",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
 		"janv.",
 		"févr.",
@@ -121,6 +146,7 @@ define(
 		"3e trimestre",
 		"4e trimestre"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
 		"dimanche",
@@ -131,8 +157,6 @@ define(
 		"vendredi",
 		"samedi"
 	],
-	"dateFormatItem-yyMMMEEEd": "EEE d MMM yy",
-	"dateFormatItem-yyMMM": "MMM yy",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -157,20 +181,22 @@ define(
 		"sam."
 	],
 	"dayPeriods-format-wide-night": "soir",
-	"dateFormatItem-yyMMMd": "d MMM yy",
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
 	"quarters-format-narrow": [
-		"T1",
-		"T2",
-		"T3",
-		"T4"
+		"1",
+		"2",
+		"3",
+		"4"
 	],
 	"field-day-relative+-1": "hier",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
 	"field-day-relative+-2": "avant-hier",
-	"field-day-relative+-3": "avant-avant-hier",
 	"dateFormatItem-MMMd": "d MMM",
-	"dateFormatItem-MEd": "EEE d/M",
+	"dateFormatItem-MEd": "E d/M",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-yMMMM": "MMMM y",
 	"field-day": "jour",
 	"days-format-wide": [
 		"dimanche",
@@ -197,7 +223,11 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-yyMM": "MM/yy",
+	"field-year-relative+-1": "l’année dernière",
+	"dayPeriods-format-narrow-night": "soir",
+	"field-month-relative+-1": "le mois dernier",
+	"dateFormatItem-hm": "h:mm a",
+	"dayPeriods-format-abbr-pm": "PM",
 	"days-format-abbr": [
 		"dim.",
 		"lun.",
@@ -207,6 +237,7 @@ define(
 		"ven.",
 		"sam."
 	],
+	"dateFormatItem-yMMMd": "d MMM y",
 	"eraNames": [
 		"avant Jésus-Christ",
 		"après Jésus-Christ"
@@ -220,7 +251,6 @@ define(
 		"V",
 		"S"
 	],
-	"field-month": "mois",
 	"days-standAlone-narrow": [
 		"D",
 		"L",
@@ -231,17 +261,28 @@ define(
 		"S"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "mois",
 	"dayPeriods-format-wide-am": "AM",
-	"dateFormatItem-MMMMEd": "EEE d MMMM",
-	"dateFormat-short": "dd/MM/yy",
-	"dateFormatItem-MMd": "d/MM",
+	"dateFormat-short": "dd/MM/y",
 	"dayPeriods-format-wide-afternoon": "après-midi",
+	"dayPeriods-format-narrow-noon": "midi",
 	"field-second": "seconde",
-	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"dateFormatItem-yMMMEd": "E d MMM y",
+	"field-month-relative+0": "ce mois-ci",
+	"field-month-relative+1": "le mois prochain",
 	"dateFormatItem-Ed": "E d",
 	"field-week": "semaine",
 	"dateFormat-medium": "d MMM y",
-	"dateFormatItem-Hms": "HH:mm:ss"
+	"field-year-relative+0": "cette année",
+	"field-week-relative+-1": "la semaine dernière",
+	"field-year-relative+1": "l’année prochaine",
+	"dayPeriods-format-narrow-pm": "p",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "cette semaine",
+	"field-week-relative+1": "la semaine prochaine"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/hebrew.js b/dojo/cldr/nls/fr/hebrew.js
new file mode 100644
index 0000000..68e02ea
--- /dev/null
+++ b/dojo/cldr/nls/fr/hebrew.js
@@ -0,0 +1,212 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "cadran",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-minute": "minute",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "hier",
+	"field-weekday": "jour de la semaine",
+	"field-day-relative+-2": "avant-hier",
+	"days-standAlone-wide": [
+		"dimanche",
+		"lundi",
+		"mardi",
+		"mercredi",
+		"jeudi",
+		"vendredi",
+		"samedi"
+	],
+	"field-era": "ère",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "heure",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Tisseri",
+		"Hesvan",
+		"Kislev",
+		"Tébeth",
+		"Schébat",
+		"Adar I",
+		"Adar",
+		"Nissan",
+		"Iyar",
+		"Sivan",
+		"Tamouz",
+		"Ab",
+		"Elloul"
+	],
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "aujourd’hui",
+	"field-day-relative+1": "demain",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"field-day-relative+2": "après-demain",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "fuseau horaire",
+	"field-week-relative+-1": "la semaine dernière",
+	"dateFormat-medium": "d MMM y G",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "cette année",
+	"field-year-relative+1": "l’année prochaine",
+	"quarters-standAlone-wide": [
+		"1er trimestre",
+		"2e trimestre",
+		"3e trimestre",
+		"4e trimestre"
+	],
+	"field-year-relative+-1": "l’année dernière",
+	"field-year": "année",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"months-standAlone-wide": [
+		"Tisseri",
+		"Hesvan",
+		"Kislev",
+		"Tébeth",
+		"Schébat",
+		"Adar I",
+		"Adar",
+		"Nissan",
+		"Iyar",
+		"Sivan",
+		"Tamouz",
+		"Ab",
+		"Elloul"
+	],
+	"field-week": "semaine",
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMEd": "E d/M/y GGGGG",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "cette semaine",
+	"field-week-relative+1": "la semaine prochaine",
+	"months-format-abbr": [
+		"Tisseri",
+		"Hesvan",
+		"Kislev",
+		"Tébeth",
+		"Schébat",
+		"Adar I",
+		"Adar",
+		"Nissan",
+		"Iyar",
+		"Sivan",
+		"Tamouz",
+		"Ab",
+		"Elloul"
+	],
+	"field-month-relative+0": "ce mois-ci",
+	"field-month": "mois",
+	"field-month-relative+1": "le mois prochain",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
+		"sam."
+	],
+	"days-format-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"field-second": "seconde",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "jour",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E d/M",
+	"days-standAlone-short": [
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
+		"sam."
+	],
+	"days-standAlone-abbr": [
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
+		"sam."
+	],
+	"dateFormat-short": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormatItem-Md": "d/M",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"months-format-wide": [
+		"Tisseri",
+		"Hesvan",
+		"Kislev",
+		"Tébeth",
+		"Schébat",
+		"Adar I",
+		"Adar",
+		"Nissan",
+		"Iyar",
+		"Sivan",
+		"Tamouz",
+		"Ab",
+		"Elloul"
+	],
+	"days-format-short": [
+		"di",
+		"lu",
+		"ma",
+		"me",
+		"je",
+		"ve",
+		"sa"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"months-format-wide-leap": "Adar II",
+	"field-month-relative+-1": "le mois dernier",
+	"quarters-format-wide": [
+		"1er trimestre",
+		"2e trimestre",
+		"3e trimestre",
+		"4e trimestre"
+	],
+	"days-format-wide": [
+		"dimanche",
+		"lundi",
+		"mardi",
+		"mercredi",
+		"jeudi",
+		"vendredi",
+		"samedi"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/indian.js b/dojo/cldr/nls/fr/indian.js
new file mode 100644
index 0000000..e38da0f
--- /dev/null
+++ b/dojo/cldr/nls/fr/indian.js
@@ -0,0 +1,31 @@
+define(
+//begin v1.x content
+{
+	"field-second": "seconde",
+	"field-year-relative+-1": "l’année dernière",
+	"field-week": "semaine",
+	"field-month-relative+-1": "le mois dernier",
+	"field-day-relative+-1": "hier",
+	"field-day-relative+-2": "avant-hier",
+	"field-year": "année",
+	"field-week-relative+0": "cette semaine",
+	"field-week-relative+1": "la semaine prochaine",
+	"field-minute": "minute",
+	"field-week-relative+-1": "la semaine dernière",
+	"field-day-relative+0": "aujourd’hui",
+	"field-hour": "heure",
+	"field-day-relative+1": "demain",
+	"field-day-relative+2": "après-demain",
+	"field-day": "jour",
+	"field-month-relative+0": "ce mois-ci",
+	"field-month-relative+1": "le mois prochain",
+	"field-dayperiod": "cadran",
+	"field-month": "mois",
+	"field-era": "ère",
+	"field-year-relative+0": "cette année",
+	"field-year-relative+1": "l’année prochaine",
+	"field-weekday": "jour de la semaine",
+	"field-zone": "fuseau horaire"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/islamic.js b/dojo/cldr/nls/fr/islamic.js
new file mode 100644
index 0000000..2cfe26d
--- /dev/null
+++ b/dojo/cldr/nls/fr/islamic.js
@@ -0,0 +1,238 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "cadran",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-minute": "minute",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "hier",
+	"field-weekday": "jour de la semaine",
+	"field-day-relative+-2": "avant-hier",
+	"days-standAlone-wide": [
+		"dimanche",
+		"lundi",
+		"mardi",
+		"mercredi",
+		"jeudi",
+		"vendredi",
+		"samedi"
+	],
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-era": "ère",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "heure",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"mouh.",
+		"saf.",
+		"rab.aw.",
+		"rab.th.",
+		"joum.ou.",
+		"joum.th.",
+		"raj.",
+		"chaa.",
+		"ram.",
+		"chaw.",
+		"dhou.qi.",
+		"dhou.hi."
+	],
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "aujourd’hui",
+	"field-day-relative+1": "demain",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"field-day-relative+2": "après-demain",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "fuseau horaire",
+	"field-week-relative+-1": "la semaine dernière",
+	"dateFormat-medium": "d MMM y G",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "cette année",
+	"field-year-relative+1": "l’année prochaine",
+	"quarters-standAlone-wide": [
+		"1er trimestre",
+		"2e trimestre",
+		"3e trimestre",
+		"4e trimestre"
+	],
+	"field-year-relative+-1": "l’année dernière",
+	"field-year": "année",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"months-standAlone-wide": [
+		"mouharram",
+		"safar",
+		"rabia al awal",
+		"rabia ath-thani",
+		"joumada al oula",
+		"joumada ath-thania",
+		"rajab",
+		"chaabane",
+		"ramadan",
+		"chawwal",
+		"dhou al qi`da",
+		"dhou al-hijja"
+	],
+	"field-week": "semaine",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"dateFormatItem-yyyyMEd": "E d/M/y GGGGG",
+	"field-week-relative+0": "cette semaine",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+1": "la semaine prochaine",
+	"months-format-abbr": [
+		"mouh.",
+		"saf.",
+		"rab.aw.",
+		"rab.th.",
+		"joum.oul.",
+		"joum.tha.",
+		"raj.",
+		"chaa.",
+		"ram.",
+		"chaw.",
+		"dhou.q.",
+		"dhou.h."
+	],
+	"field-month-relative+0": "ce mois-ci",
+	"field-month": "mois",
+	"field-month-relative+1": "le mois prochain",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
+		"sam."
+	],
+	"days-format-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"field-second": "seconde",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "jour",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E d/M",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"days-standAlone-short": [
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
+		"sam."
+	],
+	"days-standAlone-abbr": [
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
+		"sam."
+	],
+	"dateFormat-short": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"months-format-wide": [
+		"mouharram",
+		"safar",
+		"rabia al awal",
+		"rabia ath-thani",
+		"joumada al oula",
+		"joumada ath-thania",
+		"rajab",
+		"chaabane",
+		"ramadan",
+		"chawwal",
+		"dhou al qi`da",
+		"dhou al-hijja"
+	],
+	"days-format-short": [
+		"di",
+		"lu",
+		"ma",
+		"me",
+		"je",
+		"ve",
+		"sa"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "le mois dernier",
+	"quarters-format-wide": [
+		"1er trimestre",
+		"2e trimestre",
+		"3e trimestre",
+		"4e trimestre"
+	],
+	"days-format-wide": [
+		"dimanche",
+		"lundi",
+		"mardi",
+		"mercredi",
+		"jeudi",
+		"vendredi",
+		"samedi"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/japanese.js b/dojo/cldr/nls/fr/japanese.js
new file mode 100644
index 0000000..e287391
--- /dev/null
+++ b/dojo/cldr/nls/fr/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d MMM y G",
+	"field-second": "seconde",
+	"field-year-relative+-1": "l’année dernière",
+	"field-week": "semaine",
+	"field-month-relative+-1": "le mois dernier",
+	"field-day-relative+-1": "hier",
+	"field-day-relative+-2": "avant-hier",
+	"field-year": "année",
+	"field-week-relative+0": "cette semaine",
+	"field-week-relative+1": "la semaine prochaine",
+	"field-minute": "minute",
+	"field-week-relative+-1": "la semaine dernière",
+	"field-day-relative+0": "aujourd’hui",
+	"field-hour": "heure",
+	"field-day-relative+1": "demain",
+	"dateFormat-long": "d MMMM y G",
+	"field-day-relative+2": "après-demain",
+	"field-day": "jour",
+	"field-month-relative+0": "ce mois-ci",
+	"field-month-relative+1": "le mois prochain",
+	"field-dayperiod": "cadran",
+	"field-month": "mois",
+	"dateFormat-short": "dd/MM/y GGGGG",
+	"field-era": "ère",
+	"field-year-relative+0": "cette année",
+	"field-year-relative+1": "l’année prochaine",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"field-weekday": "jour de la semaine",
+	"field-zone": "fuseau horaire"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/number.js b/dojo/cldr/nls/fr/number.js
index be5c98c..7b703b5 100644
--- a/dojo/cldr/nls/fr/number.js
+++ b/dojo/cldr/nls/fr/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0 %",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
-	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"currencyFormat": "#,##0.00 ¤;(#,##0.00 ¤)",
+	"plusSign": "+",
+	"decimalFormat-long": "000 billions",
+	"decimalFormat-short": "000 Bn"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/roc.js b/dojo/cldr/nls/fr/roc.js
new file mode 100644
index 0000000..73644cf
--- /dev/null
+++ b/dojo/cldr/nls/fr/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "seconde",
+	"field-year-relative+-1": "l’année dernière",
+	"field-week": "semaine",
+	"field-month-relative+-1": "le mois dernier",
+	"field-day-relative+-1": "hier",
+	"field-day-relative+-2": "avant-hier",
+	"field-year": "année",
+	"field-week-relative+0": "cette semaine",
+	"field-week-relative+1": "la semaine prochaine",
+	"field-minute": "minute",
+	"field-week-relative+-1": "la semaine dernière",
+	"field-day-relative+0": "aujourd’hui",
+	"field-hour": "heure",
+	"field-day-relative+1": "demain",
+	"field-day-relative+2": "après-demain",
+	"field-day": "jour",
+	"field-month-relative+0": "ce mois-ci",
+	"field-month-relative+1": "le mois prochain",
+	"field-dayperiod": "cadran",
+	"field-month": "mois",
+	"field-era": "ère",
+	"field-year-relative+0": "cette année",
+	"field-year-relative+1": "l’année prochaine",
+	"eraAbbr": [
+		"avant RdC",
+		"RdC"
+	],
+	"field-weekday": "jour de la semaine",
+	"field-zone": "fuseau horaire"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/generic.js b/dojo/cldr/nls/generic.js
new file mode 100644
index 0000000..3ffed74
--- /dev/null
+++ b/dojo/cldr/nls/generic.js
@@ -0,0 +1,444 @@
+define({ root:
+
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"months-standAlone-wide at localeAlias216": {
+		"bundle": "generic",
+		"target": "months-format-wide"
+	},
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
+	"quarters-standAlone-abbr at localeAlias231": {
+		"bundle": "gregorian",
+		"target": "quarters-format-abbr"
+	},
+	"quarters-standAlone-abbr at localeAlias232": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"eraNarrow": [
+		"ERA0",
+		"ERA1"
+	],
+	"dayPeriods-format-abbr at localeAlias235": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"quarters-format-narrow at localeAlias230": {
+		"bundle": "gregorian",
+		"target": "quarters-standAlone-narrow"
+	},
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"eraNarrow at localeAlias242": {
+		"bundle": "generic",
+		"target": "eraAbbr"
+	},
+	"dayPeriods-format-abbr at localeAlias238": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormat-long": "G y MMMM d",
+	"months-format-wide": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"months-standAlone-abbr at localeAlias214": {
+		"bundle": "generic",
+		"target": "months-format-abbr"
+	},
+	"months-standAlone-abbr at localeAlias215": {
+		"bundle": "generic",
+		"target": "months-format-wide"
+	},
+	"dateFormatItem-Md": "MM-dd",
+	"months-format-abbr at localeAlias212": {
+		"bundle": "generic",
+		"target": "months-format-wide"
+	},
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
+	"months-format-abbr": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"quarters at localeAlias228": {
+		"bundle": "gregorian",
+		"target": "quarters"
+	},
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
+	"months-standAlone-abbr": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"dateFormatItem-H": "HH",
+	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
+	"months-format-narrow at localeAlias213": {
+		"bundle": "generic",
+		"target": "months-standAlone-narrow"
+	},
+	"timeFormat-medium": "HH:mm:ss",
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Hm": "HH:mm",
+	"eraAbbr": [
+		"ERA0",
+		"ERA1"
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Yesterday",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateFormatItem-h": "h a",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "MM-dd, E",
+	"days-standAlone-wide at localeAlias227": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"days-format-short at localeAlias220": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-format-short at localeAlias221": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"field-zone": "Zone",
+	"eraNames at localeAlias241": {
+		"bundle": "generic",
+		"target": "eraAbbr"
+	},
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-y": "G y",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dayPeriods-format-narrow at localeAlias236": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias237": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dayPeriods-format-narrow at localeAlias239": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"timeFormat at localeAlias243": {
+		"bundle": "gregorian",
+		"target": "timeFormat"
+	},
+	"eraNames": [
+		"ERA0",
+		"ERA1"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"days-standAlone-abbr at localeAlias222": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-standAlone-abbr at localeAlias223": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-standAlone-short at localeAlias224": {
+		"bundle": "gregorian",
+		"target": "days-format-short"
+	},
+	"days-standAlone-short at localeAlias225": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
+	"days-standAlone-short at localeAlias226": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-format-abbr at localeAlias218": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"dayPeriods-format-narrow at localeAlias240": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dayPeriods at localeAlias234": {
+		"bundle": "gregorian",
+		"target": "dayPeriods"
+	},
+	"days-format-narrow at localeAlias219": {
+		"bundle": "gregorian",
+		"target": "days-standAlone-narrow"
+	},
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"days at localeAlias217": {
+		"bundle": "gregorian",
+		"target": "days"
+	},
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"quarters-standAlone-wide at localeAlias233": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"field-second": "Second",
+	"dateFormatItem-Ed": "d, E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "G y MMM",
+	"dateFormatItem-yyyy": "G y",
+	"quarters-format-abbr at localeAlias229": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	}
+}
+//end v1.x content
+,
+	"ar": true,
+	"ca": true,
+	"cs": true,
+	"da": true,
+	"de": true,
+	"el": true,
+	"en": true,
+	"en-au": true,
+	"en-gb": true,
+	"es": true,
+	"fi": true,
+	"fr": true,
+	"fr-ch": true,
+	"he": true,
+	"hu": true,
+	"it": true,
+	"ja": true,
+	"ko": true,
+	"nb": true,
+	"nl": true,
+	"pl": true,
+	"pt": true,
+	"pt-pt": true,
+	"ro": true,
+	"ru": true,
+	"sk": true,
+	"sl": true,
+	"sv": true,
+	"th": true,
+	"tr": true,
+	"zh": true,
+	"zh-hant": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/gregorian.js b/dojo/cldr/nls/gregorian.js
index 45e7fc2..3ac527b 100644
--- a/dojo/cldr/nls/gregorian.js
+++ b/dojo/cldr/nls/gregorian.js
@@ -2,6 +2,15 @@ define({ root:
 
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
 	"months-format-narrow": [
 		"1",
 		"2",
@@ -24,50 +33,60 @@ define({ root:
 	],
 	"field-weekday": "Day of the Week",
 	"dateFormatItem-yQQQ": "y QQQ",
-	"dateFormatItem-yMEd": "EEE, y-M-d",
-	"dateFormatItem-MMMEd": "E MMM d",
+	"dateFormatItem-yMEd": "y-MM-dd, E",
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
 	"eraNarrow": [
 		"BCE",
 		"CE"
 	],
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
 	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
 	"dateFormat-long": "y MMMM d",
 	"months-format-wide": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
 	],
 	"dateTimeFormat-medium": "{1} {0}",
-	"dateFormatItem-EEEd": "d EEE",
 	"dayPeriods-format-wide-pm": "PM",
-	"dateFormat-full": "EEEE, y MMMM dd",
-	"dateFormatItem-Md": "M-d",
+	"dateFormat-full": "y MMMM d, EEEE",
+	"dateFormatItem-Md": "MM-dd",
 	"dayPeriods-format-abbr-am": "AM",
 	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"dateFormatItem-yMd": "y-MM-dd",
 	"field-era": "Era",
-	"dateFormatItem-yM": "y-M",
+	"dateFormatItem-yM": "y-MM",
 	"months-standAlone-wide": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
 	],
 	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
@@ -76,44 +95,45 @@ define({ root:
 		"Q3",
 		"Q4"
 	],
+	"dateFormatItem-yQQQQ": "y QQQQ",
 	"timeFormat-long": "HH:mm:ss z",
 	"field-year": "Year",
 	"dateFormatItem-yMMM": "y MMM",
-	"dateFormatItem-yQ": "y Q",
-	"dateTimeFormats-appendItem-Era": "{0} {1}",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
 	"field-hour": "Hour",
 	"months-format-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
 	],
 	"timeFormat-full": "HH:mm:ss zzzz",
 	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
 	"field-day-relative+0": "Today",
 	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
 	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
 	],
 	"quarters-format-abbr": [
 		"Q1",
@@ -127,15 +147,16 @@ define({ root:
 		"Q3",
 		"Q4"
 	],
+	"dateFormatItem-Gy": "G y",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
@@ -152,13 +173,13 @@ define({ root:
 	"field-minute": "Minute",
 	"field-dayperiod": "Dayperiod",
 	"days-standAlone-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
@@ -173,17 +194,17 @@ define({ root:
 	"dateTimeFormat-long": "{1} {0}",
 	"dayPeriods-format-narrow-am": "AM",
 	"dateFormatItem-MMMd": "MMM d",
-	"dateFormatItem-MEd": "E, M-d",
+	"dateFormatItem-MEd": "MM-dd, E",
 	"dateTimeFormat-full": "{1} {0}",
 	"field-day": "Day",
 	"days-format-wide": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
 	"field-zone": "Zone",
 	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
@@ -203,39 +224,40 @@ define({ root:
 		"12"
 	],
 	"dateFormatItem-hm": "h:mm a",
-	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
 	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
 	"dayPeriods-format-abbr-pm": "PM",
 	"days-format-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
 	"eraNames": [
 		"BCE",
 		"CE"
 	],
+	"dateFormatItem-yMMMd": "y MMM d",
 	"days-format-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
 	],
 	"days-standAlone-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
 	],
 	"dateFormatItem-MMM": "LLL",
 	"field-month": "Month",
@@ -243,16 +265,18 @@ define({ root:
 	"dayPeriods-format-wide-am": "AM",
 	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
 	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
-	"dateFormat-short": "yyyy-MM-dd",
+	"dateFormat-short": "y-MM-dd",
 	"field-second": "Second",
-	"dateFormatItem-yMMMEd": "EEE, y MMM d",
+	"dateFormatItem-yMMMEd": "y MMM d, E",
+	"dateFormatItem-Ed": "d, E",
 	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
 	"field-week": "Week",
 	"dateFormat-medium": "y MMM d",
 	"dayPeriods-format-narrow-pm": "PM",
 	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-hms": "h:mm:ss a"
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "G y MMM"
 }
 //end v1.x content
 ,
@@ -264,7 +288,6 @@ define({ root:
 	"el": true,
 	"en": true,
 	"en-au": true,
-	"en-ca": true,
 	"en-gb": true,
 	"es": true,
 	"fi": true,
diff --git a/dojo/cldr/nls/he/generic.js b/dojo/cldr/nls/he/generic.js
new file mode 100644
index 0000000..bdfa521
--- /dev/null
+++ b/dojo/cldr/nls/he/generic.js
@@ -0,0 +1,67 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d בMMM y G",
+	"field-dayperiod": "לפה״צ/אחה״צ",
+	"field-minute": "דקה",
+	"dateFormatItem-MMMEd": "E, d בMMM",
+	"field-day-relative+-1": "אתמול",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "שלשום",
+	"field-weekday": "יום בשבוע",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"field-era": "תקופה",
+	"field-hour": "שעה",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E ה-d",
+	"field-day-relative+0": "היום",
+	"field-day-relative+1": "מחר",
+	"field-day-relative+2": "מחרתיים",
+	"dateFormatItem-yyyyMM": "MM/y G",
+	"dateFormatItem-GyMMMd": "d בMMM y G",
+	"dateFormat-long": "d בMMMM y G",
+	"field-zone": "אזור",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "שבוע שעבר",
+	"dateFormat-medium": "d בMMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "השנה",
+	"field-year-relative+1": "שנה הבאה",
+	"field-year-relative+-1": "שנה שעברה",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"field-year": "שנה",
+	"field-week": "שבוע",
+	"dateFormatItem-yyyyMd": "d.M.y G",
+	"dateFormatItem-yyyyMMMd": "d בMMM y G",
+	"dateFormatItem-yyyyMEd": "E, d/M/y G",
+	"dateFormatItem-MMMd": "d בMMM",
+	"field-week-relative+0": "השבוע",
+	"field-week-relative+1": "שבוע הבא",
+	"field-month-relative+0": "החודש",
+	"dateFormatItem-H": "HH",
+	"field-month": "חודש",
+	"field-month-relative+1": "חודש הבא",
+	"dateFormatItem-M": "L",
+	"field-second": "שנייה",
+	"dateFormatItem-GyMMMEd": "E, d בMMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "יום",
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "M.y G",
+	"dateFormat-full": "EEEE, d בMMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "חודש שעבר",
+	"dateFormatItem-h": "‏h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/gregorian.js b/dojo/cldr/nls/he/gregorian.js
index 2643bfd..8e346a5 100644
--- a/dojo/cldr/nls/he/gregorian.js
+++ b/dojo/cldr/nls/he/gregorian.js
@@ -1,19 +1,59 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"א'",
+		"ב'",
+		"ג'",
+		"ד'",
+		"ה'",
+		"ו'",
+		"ש'"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"ר1",
+		"ר2",
+		"ר3",
+		"ר4"
+	],
 	"field-weekday": "יום בשבוע",
 	"dateFormatItem-yQQQ": "y QQQ",
-	"dateFormatItem-yMEd": "EEE, d.M.yyyy",
+	"dateFormatItem-yMEd": "E, d/M/y",
+	"dateFormatItem-GyMMMEd": "E, d בMMM y G",
 	"dateFormatItem-MMMEd": "E, d בMMM",
 	"eraNarrow": [
 		"לפנה״ס",
 		"לסה״נ"
 	],
+	"dateFormatItem-yMM": "MM/y",
+	"days-format-short": [
+		"א'",
+		"ב'",
+		"ג'",
+		"ד'",
+		"ה'",
+		"ו'",
+		"ש'"
+	],
 	"dateFormat-long": "d בMMMM y",
 	"months-format-wide": [
 		"ינואר",
 		"פברואר",
-		"מרס",
+		"מרץ",
 		"אפריל",
 		"מאי",
 		"יוני",
@@ -24,16 +64,17 @@ define(
 		"נובמבר",
 		"דצמבר"
 	],
-	"dateFormatItem-EEEd": "EEE ה-d",
+	"dateTimeFormat-medium": "{1}, {0}",
 	"dayPeriods-format-wide-pm": "אחה״צ",
 	"dateFormat-full": "EEEE, d בMMMM y",
 	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMd": "d.M.y",
 	"field-era": "תקופה",
-	"dateFormatItem-yM": "M.yyyy",
+	"dateFormatItem-yM": "M.y",
 	"months-standAlone-wide": [
 		"ינואר",
 		"פברואר",
-		"מרס",
+		"מרץ",
 		"אפריל",
 		"מאי",
 		"יוני",
@@ -51,17 +92,15 @@ define(
 		"רבעון 3",
 		"רבעון 4"
 	],
+	"dateFormatItem-yQQQQ": "y QQQQ",
 	"timeFormat-long": "HH:mm:ss z",
 	"field-year": "שנה",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "yyyy Q",
-	"dateFormatItem-yyyyMMMM": "MMMM y",
 	"field-hour": "שעה",
-	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
 		"ינו",
 		"פבר",
-		"מרס",
+		"מרץ",
 		"אפר",
 		"מאי",
 		"יונ",
@@ -72,17 +111,16 @@ define(
 		"נוב",
 		"דצמ"
 	],
-	"dateFormatItem-yyQ": "Q yy",
 	"timeFormat-full": "HH:mm:ss zzzz",
 	"field-day-relative+0": "היום",
 	"field-day-relative+1": "מחר",
+	"dateFormatItem-GyMMMd": "d בMMM y G",
 	"field-day-relative+2": "מחרתיים",
 	"dateFormatItem-H": "HH",
-	"field-day-relative+3": "בעוד שלושה ימים",
 	"months-standAlone-abbr": [
 		"ינו׳",
 		"פבר׳",
-		"מרס",
+		"מרץ",
 		"אפר׳",
 		"מאי",
 		"יונ׳",
@@ -105,6 +143,7 @@ define(
 		"רבעון 3",
 		"רבעון 4"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
 		"יום ראשון",
@@ -115,8 +154,6 @@ define(
 		"יום שישי",
 		"יום שבת"
 	],
-	"dateFormatItem-MMMMd": "d בMMMM",
-	"dateFormatItem-yyMMM": "MMM yyyy",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -142,11 +179,17 @@ define(
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "אתמול",
+	"dateFormatItem-h": "‏h a",
 	"field-day-relative+-2": "שלשום",
-	"field-day-relative+-3": "לפני שלושה ימים",
 	"dateFormatItem-MMMd": "d בMMM",
-	"dateFormatItem-MEd": "E, M-d",
+	"dateFormatItem-MEd": "E, d/M",
 	"dateFormatItem-yMMMM": "MMMM y",
 	"field-day": "יום",
 	"days-format-wide": [
@@ -159,9 +202,23 @@ define(
 		"יום שבת"
 	],
 	"field-zone": "אזור",
-	"dateFormatItem-yyyyMM": "MM/yyyy",
 	"dateFormatItem-y": "y",
-	"dateFormatItem-yyMM": "MM/yy",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year-relative+-1": "שנה שעברה",
+	"field-month-relative+-1": "חודש שעבר",
 	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
 		"יום א׳",
@@ -172,42 +229,49 @@ define(
 		"יום ו׳",
 		"שבת"
 	],
+	"dateFormatItem-yMMMd": "d בMMM y",
 	"eraNames": [
 		"לפני הספירה",
 		"לספירה"
 	],
 	"days-format-narrow": [
-		"א",
-		"ב",
-		"ג",
-		"ד",
-		"ה",
-		"ו",
-		"ש"
+		"א'",
+		"ב'",
+		"ג'",
+		"ד'",
+		"ה'",
+		"ו׳",
+		"ש׳"
 	],
 	"field-month": "חודש",
 	"days-standAlone-narrow": [
-		"א",
-		"ב",
-		"ג",
-		"ד",
-		"ה",
+		"א׳",
+		"ב׳",
+		"ג׳",
+		"ד׳",
+		"ה׳",
 		"ו",
 		"ש"
 	],
 	"dateFormatItem-MMM": "LLL",
 	"dayPeriods-format-wide-am": "לפנה״צ",
-	"dateFormatItem-MMMMEd": "E, d בMMMM",
 	"dateFormat-short": "dd/MM/yy",
 	"field-second": "שנייה",
-	"dateFormatItem-yMMMEd": "EEE, d בMMM y",
+	"dateFormatItem-yMMMEd": "E, d בMMM y",
+	"field-month-relative+0": "החודש",
+	"field-month-relative+1": "חודש הבא",
 	"dateFormatItem-Ed": "E ה-d",
 	"field-week": "שבוע",
-	"dateFormat-medium": "d בMMM yyyy",
-	"dateFormatItem-mmss": "mm:ss",
+	"dateFormat-medium": "d בMMM y",
+	"field-year-relative+0": "השנה",
+	"field-week-relative+-1": "שבוע שעבר",
+	"field-year-relative+1": "שנה הבאה",
+	"dateTimeFormat-short": "{1}, {0}",
 	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "h:mm:ss a",
-	"dateFormatItem-yyyy": "y"
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "השבוע",
+	"field-week-relative+1": "שבוע הבא"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/hebrew.js b/dojo/cldr/nls/he/hebrew.js
index e11a97e..8312829 100644
--- a/dojo/cldr/nls/he/hebrew.js
+++ b/dojo/cldr/nls/he/hebrew.js
@@ -1,16 +1,56 @@
 define(
 //begin v1.x content
 {
-	"dateFormat-medium": "dd/MM/yyyy",
-	"dateFormatItem-MMMEd": "E, d בMMM",
-	"dateFormatItem-yMEd": "EEE, d.M.yyyy",
+	"days-standAlone-short": [
+		"א'",
+		"ב'",
+		"ג'",
+		"ד'",
+		"ה'",
+		"ו'",
+		"ש'"
+	],
+	"months-format-narrow": [
+		"תש",
+		"חש",
+		"כס",
+		"טב",
+		"שב",
+		"אא",
+		"אד",
+		"ני",
+		"אי",
+		"סי",
+		"תמ",
+		"אב",
+		"אל"
+	],
+	"quarters-standAlone-narrow": [
+		"ר1",
+		"ר2",
+		"ר3",
+		"ר4"
+	],
+	"field-weekday": "יום בשבוע",
+	"months-standAlone-narrow-leap": "א2",
+	"dateFormatItem-GyMMMEd": "E, d MMMM y G",
+	"dateFormatItem-MMMEd": "E, d בMMMM",
 	"eraNarrow": [
 		"לבה״ע"
 	],
-	"dateFormatItem-Md": "d/M",
-	"months-standAlone-wide": [
+	"days-format-short": [
+		"א'",
+		"ב'",
+		"ג'",
+		"ד'",
+		"ה'",
+		"ו'",
+		"ש'"
+	],
+	"dateFormat-long": "d בMMMM y",
+	"months-format-wide": [
 		"תשרי",
-		"חשון",
+		"חשוון",
 		"כסלו",
 		"טבת",
 		"שבט",
@@ -23,23 +63,13 @@ define(
 		"אב",
 		"אלול"
 	],
-	"months-format-wide-leap": "אדר ב׳",
-	"dateFormatItem-EEEd": "EEE ה-d",
-	"eraNames": [
-		"לבה״ע"
-	],
-	"days-standAlone-narrow": [
-		"א",
-		"ב",
-		"ג",
-		"ד",
-		"ה",
-		"ו",
-		"ש"
-	],
-	"dateFormatItem-MMMMEd": "E, d בMMMM",
+	"dateTimeFormat-medium": "{1}, {0}",
 	"dayPeriods-format-wide-pm": "אחה״צ",
-	"months-standAlone-abbr": [
+	"dateFormat-full": "EEEE, d בMMMM y",
+	"dateFormatItem-yyyyMEd": "E, d בMMMM y",
+	"dateFormatItem-Md": "d בMMMM",
+	"field-era": "תקופה",
+	"months-standAlone-wide": [
 		"תשרי",
 		"חשון",
 		"כסלו",
@@ -54,13 +84,19 @@ define(
 		"אב",
 		"אלול"
 	],
-	"dayPeriods-format-wide-am": "לפנה״צ",
-	"dateFormat-long": "d בMMMM y",
-	"dateFormat-short": "dd/MM/yy",
-	"dateFormatItem-yMMMEd": "EEE, d בMMM y",
-	"months-format-wide": [
+	"quarters-format-wide": [
+		"רבעון 1",
+		"רבעון 2",
+		"רבעון 3",
+		"רבעון 4"
+	],
+	"field-year": "שנה",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"field-hour": "שעה",
+	"months-format-abbr-leap": "אדר ב׳",
+	"months-format-abbr": [
 		"תשרי",
-		"חשון",
+		"חשוון",
 		"כסלו",
 		"טבת",
 		"שבט",
@@ -73,10 +109,13 @@ define(
 		"אב",
 		"אלול"
 	],
-	"dateFormatItem-yM": "M.yyyy",
-	"months-format-abbr": [
+	"field-day-relative+0": "היום",
+	"field-day-relative+1": "מחר",
+	"dateFormatItem-GyMMMd": "d MMMM y G",
+	"field-day-relative+2": "מחרתיים",
+	"months-standAlone-abbr": [
 		"תשרי",
-		"חשון",
+		"חשוון",
 		"כסלו",
 		"טבת",
 		"שבט",
@@ -84,14 +123,29 @@ define(
 		"אדר",
 		"ניסן",
 		"אייר",
-		"סיון",
+		"סיוון",
 		"תמוז",
 		"אב",
 		"אלול"
 	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E, d בMMMM y",
+	"dateFormatItem-M": "MMMM",
+	"dateFormatItem-yyyyMMM": "MMMM y",
+	"dateFormatItem-yyyyMMMd": "d בMMMM y",
+	"dateFormatItem-MMMMd": "d בMMMM",
+	"months-standAlone-wide-leap": "אדר ב׳",
+	"months-format-narrow-leap": "א2",
 	"eraAbbr": [
 		"לבה״ע"
 	],
+	"field-minute": "דקה",
+	"field-dayperiod": "לפה״צ/אחה״צ",
+	"field-day-relative+-1": "אתמול",
+	"field-day-relative+-2": "שלשום",
+	"dateFormatItem-MMMd": "d בMMMM",
+	"dateFormatItem-MEd": "E, d בMMMM",
+	"field-day": "יום",
 	"days-format-wide": [
 		"יום ראשון",
 		"יום שני",
@@ -101,16 +155,26 @@ define(
 		"יום שישי",
 		"יום שבת"
 	],
-	"dateFormatItem-yQ": "yyyy Q",
-	"dateFormatItem-yMMM": "MMM y",
-	"quarters-format-wide": [
-		"רבעון 1",
-		"רבעון 2",
-		"רבעון 3",
-		"רבעון 4"
+	"field-zone": "אזור",
+	"months-standAlone-abbr-leap": "אדר ב׳",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"תש",
+		"חש",
+		"כס",
+		"טב",
+		"שב",
+		"אא",
+		"אד",
+		"ני",
+		"אי",
+		"סי",
+		"תמ",
+		"אב",
+		"אל"
 	],
-	"dateFormat-full": "EEEE, d בMMMM y",
-	"dateFormatItem-MMMd": "d בMMM",
+	"field-year-relative+-1": "שנה שעברה",
+	"field-month-relative+-1": "חודש שעבר",
 	"days-format-abbr": [
 		"יום א׳",
 		"יום ב׳",
@@ -119,7 +183,50 @@ define(
 		"יום ה׳",
 		"יום ו׳",
 		"שבת"
-	]
+	],
+	"eraNames": [
+		"לבה״ע"
+	],
+	"days-format-narrow": [
+		"א'",
+		"ב'",
+		"ג'",
+		"ד'",
+		"ה'",
+		"ו׳",
+		"ש׳"
+	],
+	"dateFormatItem-yyyyMd": "d בMMMM y",
+	"field-month": "חודש",
+	"days-standAlone-narrow": [
+		"א׳",
+		"ב׳",
+		"ג׳",
+		"ד׳",
+		"ה׳",
+		"ו",
+		"ש"
+	],
+	"dateFormatItem-MMM": "MMMM",
+	"dayPeriods-format-wide-am": "לפנה״צ",
+	"dateFormatItem-MMMMEd": "E, d בMMMM",
+	"dateFormat-short": "d בMMMM y",
+	"field-second": "שנייה",
+	"field-month-relative+0": "החודש",
+	"field-month-relative+1": "חודש הבא",
+	"dateFormatItem-Ed": "E ה-d",
+	"field-week": "שבוע",
+	"dateFormat-medium": "d בMMMM y",
+	"field-year-relative+0": "השנה",
+	"field-week-relative+-1": "שבוע שעבר",
+	"dateFormatItem-yyyyM": "MMMM y",
+	"field-year-relative+1": "שנה הבאה",
+	"dateTimeFormat-short": "{1}, {0}",
+	"months-format-wide-leap": "אדר ב׳",
+	"dateFormatItem-GyMMM": "MMMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "השבוע",
+	"field-week-relative+1": "שבוע הבא"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/islamic.js b/dojo/cldr/nls/he/islamic.js
index a34fe99..d617830 100644
--- a/dojo/cldr/nls/he/islamic.js
+++ b/dojo/cldr/nls/he/islamic.js
@@ -1,91 +1,129 @@
 define(
 //begin v1.x content
 {
-	"dateFormat-medium": "d בMMM yyyy",
+	"days-standAlone-short": [
+		"א'",
+		"ב'",
+		"ג'",
+		"ד'",
+		"ה'",
+		"ו'",
+		"ש'"
+	],
+	"quarters-standAlone-narrow": [
+		"ר1",
+		"ר2",
+		"ר3",
+		"ר4"
+	],
+	"field-weekday": "יום בשבוע",
+	"dateFormatItem-GyMMMEd": "E, d בMMM y G",
 	"dateFormatItem-MMMEd": "E, d בMMM",
-	"dateFormatItem-yMEd": "EEE, d.M.yyyy",
 	"eraNarrow": [
 		"שנת היג׳רה"
 	],
-	"dateFormatItem-Md": "d/M",
-	"months-standAlone-wide": [
+	"days-format-short": [
+		"א'",
+		"ב'",
+		"ג'",
+		"ד'",
+		"ה'",
+		"ו'",
+		"ש'"
+	],
+	"dateFormat-long": "d בMMMM y G",
+	"months-format-wide": [
 		"מוחרם",
-		"ספר",
-		"רביע אל-אוואל",
-		"רביע אל-תני",
-		"ג׳ומדה אל-אוואל",
-		"ג׳ומדה אל-תני",
-		"רג׳אב",
+		"צפר",
+		"רביע אל-אוול",
+		"רביע א-ת׳אני",
+		"ג׳ומאדא אל-אולא",
+		"ג׳ומאדא א-ת׳אניה",
+		"רג׳ב",
 		"שעבאן",
-		"ראמדן",
+		"רמדאן",
 		"שוואל",
-		"זו אל-QI'DAH",
-		"זו אל-חיג׳ה"
-	],
-	"dateFormatItem-EEEd": "EEE ה-d",
-	"eraNames": [
-		"שנת היג׳רה"
-	],
-	"days-standAlone-narrow": [
-		"א",
-		"ב",
-		"ג",
-		"ד",
-		"ה",
-		"ו",
-		"ש"
+		"ד׳ו אל-קעדה",
+		"ד׳ו אל-חיג׳ה"
 	],
+	"dateFormatItem-yyyyQQQ": "QQQ y",
+	"dateTimeFormat-medium": "{1}, {0}",
 	"dayPeriods-format-wide-pm": "אחה״צ",
-	"months-standAlone-abbr": [
+	"dateFormat-full": "EEEE, d בMMMM y G",
+	"dateFormatItem-yyyyMEd": "E, d.M.y",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "תקופה",
+	"months-standAlone-wide": [
 		"מוחרם",
-		"ספר",
-		"רביע אל-אוואל",
-		"רביע אל-תני",
-		"ג׳ומדה אל-אוואל",
-		"ג׳ומדה אל-תני",
-		"רג׳אב",
+		"צפר",
+		"רביע אל-אוול",
+		"רביע א-ת׳אני",
+		"ג׳ומאדא אל-אולא",
+		"ג׳ומאדא א-ת׳אניה",
+		"רג׳ב",
 		"שעבאן",
-		"ראמדן",
+		"רמדאן",
 		"שוואל",
-		"זו אל-QI'DAH",
-		"זו אל-חיג׳ה"
+		"ד׳ו אל-קעדה",
+		"ד׳ו אל-חיג׳ה"
 	],
-	"dayPeriods-format-wide-am": "לפנה״צ",
-	"dateFormat-long": "d בMMMM y",
-	"dateFormat-short": "dd/MM/yy",
-	"dateFormatItem-yMMMEd": "EEE, d בMMM y",
-	"months-format-wide": [
+	"quarters-format-wide": [
+		"רבעון 1",
+		"רבעון 2",
+		"רבעון 3",
+		"רבעון 4"
+	],
+	"field-year": "שנה",
+	"field-hour": "שעה",
+	"months-format-abbr": [
 		"מוחרם",
-		"ספר",
-		"רביע אל-אוואל",
-		"רביע אל-תני",
-		"ג׳ומדה אל-אוואל",
-		"ג׳ומדה אל-תני",
-		"רג׳אב",
+		"צפר",
+		"רביע א׳",
+		"רביע ב׳",
+		"ג׳ומאדא א׳",
+		"ג׳ומאדא ב׳",
+		"רג׳ב",
 		"שעבאן",
-		"ראמדן",
+		"רמדאן",
 		"שוואל",
-		"זו אל-QI'DAH",
-		"זו אל-חיג׳ה"
+		"ד׳ו אל-קעדה",
+		"ד׳ו אל-חיג׳ה"
 	],
-	"dateFormatItem-yM": "M.yyyy",
-	"months-format-abbr": [
+	"field-day-relative+0": "היום",
+	"field-day-relative+1": "מחר",
+	"dateFormatItem-GyMMMd": "d בMMM y G",
+	"field-day-relative+2": "מחרתיים",
+	"months-standAlone-abbr": [
 		"מוחרם",
-		"ספר",
-		"רביע אל-אוואל",
-		"רביע אל-תני",
-		"ג׳ומדה אל-אוואל",
-		"ג׳ומדה אל-תני",
-		"רג׳אב",
+		"צפר",
+		"רביע א׳",
+		"רביע ב׳",
+		"ג׳ומאדא א׳",
+		"ג׳ומאדא ב׳",
+		"רג׳ב",
 		"שעבאן",
-		"ראמדן",
+		"רמדאן",
 		"שוואל",
-		"זו אל-QI'DAH",
-		"זו אל-חיג׳ה"
+		"ד׳ו אל-קעדה",
+		"ד׳ו אל-חיג׳ה"
 	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E, d בMMM y",
+	"dateFormatItem-yyyyMMM": "MMM y",
+	"dateFormatItem-yyyyMMMd": "d בMMM y",
+	"dateFormatItem-Hm": "HH:mm",
 	"eraAbbr": [
 		"שנת היג׳רה"
 	],
+	"field-minute": "דקה",
+	"field-dayperiod": "לפה״צ/אחה״צ",
+	"dateFormatItem-d": "d",
+	"field-day-relative+-1": "אתמול",
+	"dateFormatItem-h": "h a",
+	"field-day-relative+-2": "שלשום",
+	"dateFormatItem-MMMd": "d בMMM",
+	"dateFormatItem-MEd": "E, d/M",
+	"field-day": "יום",
 	"days-format-wide": [
 		"יום ראשון",
 		"יום שני",
@@ -95,16 +133,25 @@ define(
 		"יום שישי",
 		"יום שבת"
 	],
-	"dateFormatItem-yQ": "yyyy Q",
-	"dateFormatItem-yMMM": "MMM y",
-	"quarters-format-wide": [
-		"רבעון 1",
-		"רבעון 2",
-		"רבעון 3",
-		"רבעון 4"
+	"field-zone": "אזור",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
 	],
-	"dateFormat-full": "EEEE, d בMMMM y",
-	"dateFormatItem-MMMd": "d בMMM",
+	"field-year-relative+-1": "שנה שעברה",
+	"field-month-relative+-1": "חודש שעבר",
+	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
 		"יום א׳",
 		"יום ב׳",
@@ -113,7 +160,50 @@ define(
 		"יום ה׳",
 		"יום ו׳",
 		"שבת"
-	]
+	],
+	"eraNames": [
+		"שנת היג׳רה"
+	],
+	"days-format-narrow": [
+		"א'",
+		"ב'",
+		"ג'",
+		"ד'",
+		"ה'",
+		"ו׳",
+		"ש׳"
+	],
+	"dateFormatItem-yyyyMd": "d.M.y G",
+	"field-month": "חודש",
+	"days-standAlone-narrow": [
+		"א׳",
+		"ב׳",
+		"ג׳",
+		"ד׳",
+		"ה׳",
+		"ו",
+		"ש"
+	],
+	"dayPeriods-format-wide-am": "לפנה״צ",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"field-second": "שנייה",
+	"field-month-relative+0": "החודש",
+	"field-month-relative+1": "חודש הבא",
+	"dateFormatItem-Ed": "E ה-d",
+	"field-week": "שבוע",
+	"dateFormat-medium": "d בMMM y G",
+	"field-year-relative+0": "השנה",
+	"field-week-relative+-1": "שבוע שעבר",
+	"dateFormatItem-yyyyM": "M/y",
+	"field-year-relative+1": "שנה הבאה",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "השבוע",
+	"field-week-relative+1": "שבוע הבא"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/japanese.js b/dojo/cldr/nls/he/japanese.js
new file mode 100644
index 0000000..8ae3006
--- /dev/null
+++ b/dojo/cldr/nls/he/japanese.js
@@ -0,0 +1,107 @@
+define(
+//begin v1.x content
+{
+	"field-second": "שנייה",
+	"field-year-relative+-1": "שנה שעברה",
+	"field-week": "שבוע",
+	"field-month-relative+-1": "חודש שעבר",
+	"field-day-relative+-1": "אתמול",
+	"field-day-relative+-2": "שלשום",
+	"field-year": "שנה",
+	"field-week-relative+0": "השבוע",
+	"field-week-relative+1": "שבוע הבא",
+	"field-minute": "דקה",
+	"field-week-relative+-1": "שבוע שעבר",
+	"field-day-relative+0": "היום",
+	"field-hour": "שעה",
+	"field-day-relative+1": "מחר",
+	"field-day-relative+2": "מחרתיים",
+	"field-day": "יום",
+	"field-month-relative+0": "החודש",
+	"field-month-relative+1": "חודש הבא",
+	"field-dayperiod": "לפה״צ/אחה״צ",
+	"field-month": "חודש",
+	"field-era": "תקופה",
+	"field-year-relative+0": "השנה",
+	"field-year-relative+1": "שנה הבאה",
+	"eraAbbr": [
+		"טאיקה",
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		"נינג׳ו",
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		null,
+		"שוטוקו"
+	],
+	"field-weekday": "יום בשבוע",
+	"field-zone": "אזור"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/number.js b/dojo/cldr/nls/he/number.js
index 7dedbd9..eb8dc99 100644
--- a/dojo/cldr/nls/he/number.js
+++ b/dojo/cldr/nls/he/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0%",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ".",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "‏000 טריליון",
+	"decimalFormat-short": "000T"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/hebrew.js b/dojo/cldr/nls/hebrew.js
index 29ae041..e246664 100644
--- a/dojo/cldr/nls/hebrew.js
+++ b/dojo/cldr/nls/hebrew.js
@@ -2,20 +2,29 @@ define({ root:
 
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
 	"months-format-narrow": [
-		"Tishri",
-		"Heshvan",
-		"Kislev",
-		"Tevet",
-		"Shevat",
-		"Adar I",
-		"Adar",
-		"Nisan",
-		"Iyar",
-		"Sivan",
-		"Tamuz",
-		"Av",
-		"Elul"
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
 	],
 	"quarters-standAlone-narrow": [
 		"1",
@@ -23,15 +32,23 @@ define({ root:
 		"3",
 		"4"
 	],
-	"dateFormatItem-yQQQ": "y QQQ",
-	"months-standAlone-narrow-leap": "Adar II",
-	"dateFormatItem-yMEd": "EEE, y-M-d",
-	"dateFormatItem-MMMEd": "E MMM d",
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
 	"eraNarrow": [
 		"AM"
 	],
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
 	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
-	"dateFormat-long": "y MMMM d",
+	"dateFormat-long": "G y MMMM d",
 	"months-format-wide": [
 		"Tishri",
 		"Heshvan",
@@ -47,14 +64,15 @@ define({ root:
 		"Av",
 		"Elul"
 	],
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
 	"dateTimeFormat-medium": "{1} {0}",
-	"dateFormatItem-EEEd": "d EEE",
 	"dayPeriods-format-wide-pm": "PM",
-	"dateFormat-full": "EEEE, y MMMM dd",
-	"dateFormatItem-Md": "M-d",
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"dateFormatItem-Md": "MM-dd",
 	"dayPeriods-format-abbr-am": "AM",
 	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
-	"dateFormatItem-yM": "y-M",
+	"field-era": "Era",
 	"months-standAlone-wide": [
 		"Tishri",
 		"Heshvan",
@@ -78,9 +96,9 @@ define({ root:
 		"Q4"
 	],
 	"timeFormat-long": "HH:mm:ss z",
-	"dateFormatItem-yMMM": "y MMM",
-	"dateFormatItem-yQ": "y Q",
-	"dateTimeFormats-appendItem-Era": "{0} {1}",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
 	"months-format-abbr-leap": "Adar II",
 	"months-format-abbr": [
 		"Tishri",
@@ -99,6 +117,9 @@ define({ root:
 	],
 	"timeFormat-full": "HH:mm:ss zzzz",
 	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
 	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
 		"Tishri",
@@ -127,16 +148,20 @@ define({ root:
 		"Q3",
 		"Q4"
 	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
 	"months-standAlone-wide-leap": "Adar II",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
@@ -146,18 +171,19 @@ define({ root:
 		"Q3",
 		"Q4"
 	],
-	"months-format-narrow-leap": "Adar II",
 	"eraAbbr": [
 		"AM"
 	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
 	"days-standAlone-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
@@ -167,99 +193,125 @@ define({ root:
 		"3",
 		"4"
 	],
+	"field-day-relative+-1": "Yesterday",
 	"dateFormatItem-h": "h a",
 	"dateTimeFormat-long": "{1} {0}",
 	"dayPeriods-format-narrow-am": "AM",
 	"dateFormatItem-MMMd": "MMM d",
-	"dateFormatItem-MEd": "E, M-d",
+	"dateFormatItem-MEd": "MM-dd, E",
 	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "Day",
 	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"field-zone": "Zone",
+	"months-standAlone-abbr-leap": "Adar II",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dateFormatItem-y": "G y",
+	"months-standAlone-narrow": [
 		"1",
 		"2",
 		"3",
 		"4",
 		"5",
 		"6",
-		"7"
-	],
-	"months-standAlone-abbr-leap": "Adar II",
-	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
-	"dateFormatItem-y": "y",
-	"months-standAlone-narrow": [
-		"Tishri",
-		"Heshvan",
-		"Kislev",
-		"Tevet",
-		"Shevat",
-		"Adar I",
-		"Adar",
-		"Nisan",
-		"Iyar",
-		"Sivan",
-		"Tamuz",
-		"Av",
-		"Elul"
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
 	],
 	"dateFormatItem-hm": "h:mm a",
-	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
 	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
 	"dayPeriods-format-abbr-pm": "PM",
 	"days-format-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
 	"eraNames": [
 		"AM"
 	],
 	"days-format-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
 	],
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
 	"days-standAlone-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
 	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
 	"dayPeriods-format-wide-am": "AM",
 	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
 	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
-	"dateFormat-short": "yyyy-MM-dd",
-	"dateFormatItem-yMMMEd": "EEE, y MMM d",
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"field-second": "Second",
+	"dateFormatItem-Ed": "d, E",
 	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
-	"dateFormat-medium": "y MMM d",
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
 	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
 	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "h:mm:ss a",
-	"months-format-wide-leap": "Adar II"
+	"months-format-wide-leap": "Adar II",
+	"dateFormatItem-GyMMM": "G y MMM",
+	"dateFormatItem-yyyy": "G y"
 }
 //end v1.x content
 ,
 	"ar": true,
+	"cs": true,
+	"da": true,
+	"de": true,
 	"el": true,
+	"en": true,
+	"es": true,
 	"fi": true,
 	"fr": true,
 	"he": true,
 	"hu": true,
+	"it": true,
+	"ja": true,
+	"ko": true,
+	"nb": true,
 	"nl": true,
+	"pl": true,
+	"pt": true,
+	"pt-pt": true,
+	"ro": true,
 	"ru": true,
 	"sv": true,
 	"th": true,
-	"tr": true
+	"tr": true,
+	"zh": true,
+	"zh-hant": true
 });
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/buddhist.js b/dojo/cldr/nls/hu/buddhist.js
new file mode 100644
index 0000000..15a72cd
--- /dev/null
+++ b/dojo/cldr/nls/hu/buddhist.js
@@ -0,0 +1,251 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"months-format-narrow": [
+		"J",
+		"F",
+		"M",
+		"Á",
+		"M",
+		"J",
+		"J",
+		"Á",
+		"Sz",
+		"O",
+		"N",
+		"D"
+	],
+	"quarters-standAlone-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"field-weekday": "hét napja",
+	"dateFormatItem-GyMMMEd": "G y. MMM d., E",
+	"dateFormatItem-MMMEd": "MMM d., E",
+	"eraNarrow": [
+		"BK"
+	],
+	"dateFormat-long": "G y. MMMM d.",
+	"months-format-wide": [
+		"január",
+		"február",
+		"március",
+		"április",
+		"május",
+		"június",
+		"július",
+		"augusztus",
+		"szeptember",
+		"október",
+		"november",
+		"december"
+	],
+	"dateFormatItem-yyyyQQQ": "G y. QQQ",
+	"dayPeriods-format-wide-pm": "du.",
+	"dateFormat-full": "G y. MMMM d., EEEE",
+	"dateFormatItem-yyyyMEd": "G y.MM.dd., E",
+	"dateFormatItem-Md": "M. d.",
+	"field-era": "éra",
+	"months-standAlone-wide": [
+		"január",
+		"február",
+		"március",
+		"április",
+		"május",
+		"június",
+		"július",
+		"augusztus",
+		"szeptember",
+		"október",
+		"november",
+		"december"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"I. negyedév",
+		"II. negyedév",
+		"III. negyedév",
+		"IV. negyedév"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "év",
+	"field-hour": "óra",
+	"months-format-abbr": [
+		"jan.",
+		"febr.",
+		"márc.",
+		"ápr.",
+		"máj.",
+		"jún.",
+		"júl.",
+		"aug.",
+		"szept.",
+		"okt.",
+		"nov.",
+		"dec."
+	],
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "ma",
+	"field-day-relative+1": "holnap",
+	"dateFormatItem-GyMMMd": "G y. MMM d.",
+	"field-day-relative+2": "holnapután",
+	"dateFormatItem-H": "H",
+	"months-standAlone-abbr": [
+		"jan.",
+		"febr.",
+		"márc.",
+		"ápr.",
+		"máj.",
+		"jún.",
+		"júl.",
+		"aug.",
+		"szept.",
+		"okt.",
+		"nov.",
+		"dec."
+	],
+	"quarters-format-abbr": [
+		"N1",
+		"N2",
+		"N3",
+		"N4"
+	],
+	"quarters-standAlone-wide": [
+		"1. negyedév",
+		"2. negyedév",
+		"3. negyedév",
+		"4. negyedév"
+	],
+	"dateFormatItem-yyyyMMMEd": "G y. MMM d., E",
+	"days-standAlone-wide": [
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
+		"szombat"
+	],
+	"dateFormatItem-yyyyMMM": "G y. MMM",
+	"dateFormatItem-yyyyMMMd": "G y. MMM d.",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"N1",
+		"N2",
+		"N3",
+		"N4"
+	],
+	"eraAbbr": [
+		"BK"
+	],
+	"field-minute": "perc",
+	"field-dayperiod": "napszak",
+	"days-standAlone-abbr": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"field-day-relative+-1": "tegnap",
+	"dateFormatItem-h": "a h",
+	"dayPeriods-format-narrow-am": "de.",
+	"field-day-relative+-2": "tegnapelőtt",
+	"dateFormatItem-MMMd": "MMM d.",
+	"dateFormatItem-MEd": "M. d., E",
+	"field-day": "nap",
+	"days-format-wide": [
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
+		"szombat"
+	],
+	"field-zone": "időzóna",
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"Á",
+		"M",
+		"J",
+		"J",
+		"A",
+		"Sz",
+		"O",
+		"N",
+		"D"
+	],
+	"field-year-relative+-1": "Előző év",
+	"field-month-relative+-1": "Előző hónap",
+	"dateFormatItem-hm": "a h:mm",
+	"days-format-abbr": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"eraNames": [
+		"BK"
+	],
+	"days-format-narrow": [
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
+		"Sz"
+	],
+	"dateFormatItem-yyyyMd": "G y.MM.dd.",
+	"field-month": "hónap",
+	"days-standAlone-narrow": [
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
+		"Sz"
+	],
+	"dayPeriods-format-wide-am": "de.",
+	"dateFormat-short": "GGGGG y.MM.dd.",
+	"field-second": "másodperc",
+	"field-month-relative+0": "Ez a hónap",
+	"field-month-relative+1": "Következő hónap",
+	"dateFormatItem-Ed": "d., E",
+	"field-week": "hét",
+	"dateFormat-medium": "G y.MM.dd.",
+	"field-year-relative+0": "Ez az év",
+	"field-week-relative+-1": "Előző hét",
+	"dateFormatItem-yyyyM": "G y.M.",
+	"field-year-relative+1": "Következő év",
+	"dayPeriods-format-narrow-pm": "du.",
+	"dateFormatItem-yyyyQQQQ": "G y. QQQQ",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "a h:mm:ss",
+	"dateFormatItem-GyMMM": "G y. MMM",
+	"field-week-relative+0": "Ez a hét",
+	"field-week-relative+1": "Következő hét"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/chinese.js b/dojo/cldr/nls/hu/chinese.js
new file mode 100644
index 0000000..231c520
--- /dev/null
+++ b/dojo/cldr/nls/hu/chinese.js
@@ -0,0 +1,87 @@
+define(
+//begin v1.x content
+{
+	"field-second": "másodperc",
+	"field-year-relative+-1": "Előző év",
+	"field-week": "hét",
+	"field-month-relative+-1": "Előző hónap",
+	"field-day-relative+-1": "tegnap",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "tegnapelőtt",
+	"months-standAlone-wide": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year": "év",
+	"field-week-relative+0": "Ez a hét",
+	"months-standAlone-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-week-relative+1": "Következő hét",
+	"field-minute": "perc",
+	"field-week-relative+-1": "Előző hét",
+	"field-day-relative+0": "ma",
+	"field-hour": "óra",
+	"field-day-relative+1": "holnap",
+	"field-day-relative+2": "holnapután",
+	"field-day": "nap",
+	"field-month-relative+0": "Ez a hónap",
+	"field-month-relative+1": "Következő hónap",
+	"field-dayperiod": "napszak",
+	"field-month": "hónap",
+	"field-era": "éra",
+	"field-year-relative+0": "Ez az év",
+	"field-year-relative+1": "Következő év",
+	"months-format-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "hét napja",
+	"field-zone": "időzóna"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/coptic.js b/dojo/cldr/nls/hu/coptic.js
new file mode 100644
index 0000000..a7cf23c
--- /dev/null
+++ b/dojo/cldr/nls/hu/coptic.js
@@ -0,0 +1,91 @@
+define(
+//begin v1.x content
+{
+	"field-second": "másodperc",
+	"field-year-relative+-1": "Előző év",
+	"field-week": "hét",
+	"field-month-relative+-1": "Előző hónap",
+	"field-day-relative+-1": "tegnap",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "tegnapelőtt",
+	"months-standAlone-wide": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"field-year": "év",
+	"field-week-relative+0": "Ez a hét",
+	"months-standAlone-abbr": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"field-week-relative+1": "Következő hét",
+	"field-minute": "perc",
+	"field-week-relative+-1": "Előző hét",
+	"field-day-relative+0": "ma",
+	"field-hour": "óra",
+	"field-day-relative+1": "holnap",
+	"field-day-relative+2": "holnapután",
+	"field-day": "nap",
+	"field-month-relative+0": "Ez a hónap",
+	"field-month-relative+1": "Következő hónap",
+	"field-dayperiod": "napszak",
+	"field-month": "hónap",
+	"field-era": "éra",
+	"field-year-relative+0": "Ez az év",
+	"field-year-relative+1": "Következő év",
+	"months-format-abbr": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"field-weekday": "hét napja",
+	"field-zone": "időzóna"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/currency.js b/dojo/cldr/nls/hu/currency.js
index 73da330..a580182 100644
--- a/dojo/cldr/nls/hu/currency.js
+++ b/dojo/cldr/nls/hu/currency.js
@@ -5,12 +5,18 @@ define(
 	"CHF_displayName": "Svájci frank",
 	"JPY_symbol": "¥",
 	"CAD_displayName": "Kanadai dollár",
+	"HKD_symbol": "HKD",
 	"CNY_displayName": "Kínai jüan renminbi",
 	"USD_symbol": "$",
 	"AUD_displayName": "Ausztrál dollár",
 	"JPY_displayName": "Japán jen",
+	"CAD_symbol": "CAD",
 	"USD_displayName": "USA dollár",
+	"EUR_symbol": "EUR",
+	"CNY_symbol": "CNY",
 	"GBP_displayName": "Brit font sterling",
+	"GBP_symbol": "GBP",
+	"AUD_symbol": "AUD",
 	"EUR_displayName": "Euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/hu/ethiopic.js b/dojo/cldr/nls/hu/ethiopic.js
new file mode 100644
index 0000000..a41d031
--- /dev/null
+++ b/dojo/cldr/nls/hu/ethiopic.js
@@ -0,0 +1,91 @@
+define(
+//begin v1.x content
+{
+	"field-second": "másodperc",
+	"field-year-relative+-1": "Előző év",
+	"field-week": "hét",
+	"field-month-relative+-1": "Előző hónap",
+	"field-day-relative+-1": "tegnap",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "tegnapelőtt",
+	"months-standAlone-wide": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"field-year": "év",
+	"field-week-relative+0": "Ez a hét",
+	"months-standAlone-abbr": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"field-week-relative+1": "Következő hét",
+	"field-minute": "perc",
+	"field-week-relative+-1": "Előző hét",
+	"field-day-relative+0": "ma",
+	"field-hour": "óra",
+	"field-day-relative+1": "holnap",
+	"field-day-relative+2": "holnapután",
+	"field-day": "nap",
+	"field-month-relative+0": "Ez a hónap",
+	"field-month-relative+1": "Következő hónap",
+	"field-dayperiod": "napszak",
+	"field-month": "hónap",
+	"field-era": "éra",
+	"field-year-relative+0": "Ez az év",
+	"field-year-relative+1": "Következő év",
+	"months-format-abbr": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"field-weekday": "hét napja",
+	"field-zone": "időzóna"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/generic.js b/dojo/cldr/nls/hu/generic.js
new file mode 100644
index 0000000..0124d89
--- /dev/null
+++ b/dojo/cldr/nls/hu/generic.js
@@ -0,0 +1,66 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "G y. MMM d., E",
+	"field-dayperiod": "napszak",
+	"field-minute": "perc",
+	"dateFormatItem-MMMEd": "MMM d., E",
+	"field-day-relative+-1": "tegnap",
+	"dateFormatItem-hms": "a h:mm:ss",
+	"field-day-relative+-2": "tegnapelőtt",
+	"field-weekday": "hét napja",
+	"dateFormatItem-MMM": "LLL",
+	"dateFormatItem-Gy": "G y",
+	"field-era": "éra",
+	"field-hour": "óra",
+	"dateFormatItem-y": "G y",
+	"dateFormatItem-yyyy": "G y",
+	"dateFormatItem-Ed": "d., E",
+	"field-day-relative+0": "ma",
+	"field-day-relative+1": "holnap",
+	"field-day-relative+2": "holnapután",
+	"dateFormatItem-yyyyMMMM": "G y. MMMM",
+	"dateFormatItem-GyMMMd": "G y. MMM d.",
+	"dateFormat-long": "G y. MMMM d.",
+	"field-zone": "időzóna",
+	"dateFormatItem-Hm": "H:mm",
+	"field-week-relative+-1": "Előző hét",
+	"dateFormat-medium": "G y.MM.dd.",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"field-year-relative+0": "Ez az év",
+	"field-year-relative+1": "Következő év",
+	"field-year-relative+-1": "Előző év",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "G y. QQQQ",
+	"field-year": "év",
+	"field-week": "hét",
+	"dateFormatItem-yyyyMd": "G y.MM.dd.",
+	"dateFormatItem-yyyyMMMd": "G y. MMM d.",
+	"dateFormatItem-yyyyMEd": "G y.MM.dd., E",
+	"dateFormatItem-MMMd": "MMM d.",
+	"field-week-relative+0": "Ez a hét",
+	"field-week-relative+1": "Következő hét",
+	"field-month-relative+0": "Ez a hónap",
+	"dateFormatItem-H": "H",
+	"field-month": "hónap",
+	"field-month-relative+1": "Következő hónap",
+	"dateFormatItem-MMMMd": "MMMM d.",
+	"dateFormatItem-M": "L",
+	"field-second": "másodperc",
+	"dateFormatItem-GyMMMEd": "G y. MMM d., E",
+	"dateFormatItem-GyMMM": "G y. MMM",
+	"field-day": "nap",
+	"dateFormatItem-yyyyQQQ": "G y. QQQ",
+	"dateFormatItem-MEd": "M. d., E",
+	"dateFormatItem-hm": "a h:mm",
+	"dateFormat-short": "GGGGG y.MM.dd.",
+	"dateFormatItem-yyyyM": "G y.M.",
+	"dateFormat-full": "G y. MMMM d., EEEE",
+	"dateFormatItem-Md": "M. d.",
+	"dateFormatItem-yyyyMMM": "G y. MMM",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Előző hónap",
+	"dateFormatItem-h": "a h"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/gregorian.js b/dojo/cldr/nls/hu/gregorian.js
index 040c862..0dbbeed 100644
--- a/dojo/cldr/nls/hu/gregorian.js
+++ b/dojo/cldr/nls/hu/gregorian.js
@@ -1,30 +1,16 @@
 define(
 //begin v1.x content
 {
-	"field-dayperiod": "napszak",
-	"dayPeriods-format-wide-pm": "du.",
-	"field-minute": "perc",
-	"eraNames": [
-		"időszámításunk előtt",
-		"időszámításunk szerint"
-	],
-	"dateFormatItem-MMMEd": "MMM d., E",
-	"field-day-relative+-1": "tegnap",
-	"field-weekday": "hét napja",
-	"field-day-relative+-2": "tegnapelőtt",
-	"dateFormatItem-MMdd": "MM.dd.",
-	"field-day-relative+-3": "három nappal ezelőtt",
-	"days-standAlone-wide": [
-		"vasárnap",
-		"hétfő",
-		"kedd",
-		"szerda",
-		"csütörtök",
-		"péntek",
-		"szombat"
+	"days-standAlone-short": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
 	],
-	"dateFormatItem-MMM": "LLL",
-	"months-standAlone-narrow": [
+	"months-format-narrow": [
 		"J",
 		"F",
 		"M",
@@ -32,70 +18,57 @@ define(
 		"M",
 		"J",
 		"J",
-		"A",
+		"Á",
 		"Sz",
 		"O",
 		"N",
 		"D"
 	],
-	"field-era": "éra",
-	"field-hour": "óra",
-	"dayPeriods-format-wide-am": "de.",
-	"quarters-standAlone-abbr": [
-		"N1",
-		"N2",
-		"N3",
-		"N4"
+	"quarters-standAlone-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
 	],
-	"timeFormat-full": "H:mm:ss zzzz",
-	"months-standAlone-abbr": [
-		"jan.",
-		"febr.",
-		"márc.",
-		"ápr.",
-		"máj.",
-		"jún.",
-		"júl.",
-		"aug.",
-		"szept.",
-		"okt.",
-		"nov.",
-		"dec."
+	"field-weekday": "hét napja",
+	"dateFormatItem-yQQQ": "y. QQQ",
+	"dateFormatItem-yMEd": "y.MM.dd., E",
+	"dateFormatItem-GyMMMEd": "G y. MMM d., E",
+	"dateFormatItem-MMMEd": "MMM d., E",
+	"eraNarrow": [
+		"ie.",
+		"isz."
 	],
-	"dateFormatItem-Ed": "d., E",
-	"field-day-relative+0": "ma",
-	"field-day-relative+1": "holnap",
-	"days-standAlone-narrow": [
+	"days-format-short": [
 		"V",
 		"H",
 		"K",
-		"Sz",
+		"Sze",
 		"Cs",
 		"P",
-		"Sz"
-	],
-	"eraAbbr": [
-		"i. e.",
-		"i. sz."
+		"Szo"
 	],
-	"field-day-relative+2": "holnapután",
-	"field-day-relative+3": "három nap múlva",
-	"dateFormatItem-yyyyMM": "yyyy.MM",
-	"dateFormatItem-yyyyMMMM": "y. MMMM",
 	"dateFormat-long": "y. MMMM d.",
-	"timeFormat-medium": "H:mm:ss",
-	"field-zone": "zóna",
-	"dateFormatItem-Hm": "H:mm",
-	"dateFormat-medium": "yyyy.MM.dd.",
-	"dateFormatItem-Hms": "H:mm:ss",
-	"quarters-standAlone-wide": [
-		"I. negyedév",
-		"II. negyedév",
-		"III. negyedév",
-		"IV. negyedév"
+	"months-format-wide": [
+		"január",
+		"február",
+		"március",
+		"április",
+		"május",
+		"június",
+		"július",
+		"augusztus",
+		"szeptember",
+		"október",
+		"november",
+		"december"
 	],
-	"field-year": "év",
-	"field-week": "hét",
+	"dayPeriods-format-wide-pm": "du.",
+	"dateFormat-full": "y. MMMM d., EEEE",
+	"dateFormatItem-Md": "M. d.",
+	"dateFormatItem-yMd": "y.MM.dd.",
+	"field-era": "éra",
+	"dateFormatItem-yM": "y.M.",
 	"months-standAlone-wide": [
 		"január",
 		"február",
@@ -110,9 +83,18 @@ define(
 		"november",
 		"december"
 	],
-	"dateFormatItem-MMMd": "MMM d.",
-	"dateFormatItem-yyQ": "yy/Q",
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"I. negyedév",
+		"II. negyedév",
+		"III. negyedév",
+		"IV. negyedév"
+	],
+	"dateFormatItem-yQQQQ": "y. QQQQ",
 	"timeFormat-long": "H:mm:ss z",
+	"field-year": "év",
+	"dateFormatItem-yMMM": "y. MMM",
+	"field-hour": "óra",
 	"months-format-abbr": [
 		"jan.",
 		"febr.",
@@ -127,17 +109,65 @@ define(
 		"nov.",
 		"dec."
 	],
-	"timeFormat-short": "H:mm",
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "ma",
+	"field-day-relative+1": "holnap",
+	"dateFormatItem-GyMMMd": "G y. MMM d.",
+	"field-day-relative+2": "holnapután",
 	"dateFormatItem-H": "H",
-	"field-month": "hónap",
-	"dateFormatItem-MMMMd": "MMMM d.",
+	"months-standAlone-abbr": [
+		"jan.",
+		"febr.",
+		"márc.",
+		"ápr.",
+		"máj.",
+		"jún.",
+		"júl.",
+		"aug.",
+		"szept.",
+		"okt.",
+		"nov.",
+		"dec."
+	],
 	"quarters-format-abbr": [
 		"N1",
 		"N2",
 		"N3",
 		"N4"
 	],
-	"days-format-abbr": [
+	"quarters-standAlone-wide": [
+		"1. negyedév",
+		"2. negyedév",
+		"3. negyedév",
+		"4. negyedév"
+	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
+		"szombat"
+	],
+	"dateFormatItem-MMMMd": "MMMM d.",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"N1",
+		"N2",
+		"N3",
+		"N4"
+	],
+	"eraAbbr": [
+		"i. e.",
+		"i. sz."
+	],
+	"field-minute": "perc",
+	"field-dayperiod": "napszak",
+	"days-standAlone-abbr": [
 		"V",
 		"H",
 		"K",
@@ -146,21 +176,33 @@ define(
 		"P",
 		"Szo"
 	],
-	"dateFormatItem-mmss": "mm:ss",
-	"dateFormatItem-M": "L",
-	"days-format-narrow": [
-		"V",
-		"H",
-		"K",
-		"Sz",
-		"Cs",
-		"P",
-		"Sz"
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
 	],
-	"field-second": "másodperc",
-	"field-day": "nap",
+	"field-day-relative+-1": "tegnap",
+	"dateFormatItem-h": "a h",
+	"dayPeriods-format-narrow-am": "de.",
+	"field-day-relative+-2": "tegnapelőtt",
+	"dateFormatItem-MMMd": "MMM d.",
 	"dateFormatItem-MEd": "M. d., E",
-	"months-format-narrow": [
+	"dateFormatItem-yMMMM": "y. MMMM",
+	"field-day": "nap",
+	"days-format-wide": [
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
+		"szombat"
+	],
+	"field-zone": "időzóna",
+	"months-standAlone-narrow": [
 		"J",
 		"F",
 		"M",
@@ -174,7 +216,10 @@ define(
 		"N",
 		"D"
 	],
-	"days-standAlone-abbr": [
+	"field-year-relative+-1": "Előző év",
+	"field-month-relative+-1": "Előző hónap",
+	"dateFormatItem-hm": "a h:mm",
+	"days-format-abbr": [
 		"V",
 		"H",
 		"K",
@@ -183,45 +228,50 @@ define(
 		"P",
 		"Szo"
 	],
-	"dateFormat-short": "yyyy.MM.dd.",
-	"dateFormatItem-yMMMEd": "y. MMM d., E",
-	"dateFormat-full": "y. MMMM d., EEEE",
-	"dateFormatItem-Md": "M. d.",
-	"dateFormatItem-yMEd": "yyyy.MM.dd., E",
-	"months-format-wide": [
-		"január",
-		"február",
-		"március",
-		"április",
-		"május",
-		"június",
-		"július",
-		"augusztus",
-		"szeptember",
-		"október",
-		"november",
-		"december"
+	"dateFormatItem-yMMMd": "y. MMM d.",
+	"eraNames": [
+		"időszámításunk előtt",
+		"időszámításunk szerint"
 	],
-	"dateFormatItem-d": "d",
-	"quarters-format-wide": [
-		"I. negyedév",
-		"II. negyedév",
-		"III. negyedév",
-		"IV. negyedév"
+	"days-format-narrow": [
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
+		"Sz"
 	],
-	"days-format-wide": [
-		"vasárnap",
-		"hétfő",
-		"kedd",
-		"szerda",
-		"csütörtök",
-		"péntek",
-		"szombat"
+	"field-month": "hónap",
+	"days-standAlone-narrow": [
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
+		"Sz"
 	],
-	"eraNarrow": [
-		"i. e.",
-		"i. sz."
-	]
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "de.",
+	"dateFormat-short": "y.MM.dd.",
+	"field-second": "másodperc",
+	"dateFormatItem-yMMMEd": "y. MMM d., E",
+	"field-month-relative+0": "Ez a hónap",
+	"field-month-relative+1": "Következő hónap",
+	"dateFormatItem-Ed": "d., E",
+	"field-week": "hét",
+	"dateFormat-medium": "y.MM.dd.",
+	"field-year-relative+0": "Ez az év",
+	"field-week-relative+-1": "Előző hét",
+	"field-year-relative+1": "Következő év",
+	"dateFormatItem-mmss": "mm:ss",
+	"dayPeriods-format-narrow-pm": "du.",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "a h:mm:ss",
+	"dateFormatItem-GyMMM": "G y. MMM",
+	"field-week-relative+0": "Ez a hét",
+	"field-week-relative+1": "Következő hét"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/hebrew.js b/dojo/cldr/nls/hu/hebrew.js
new file mode 100644
index 0000000..fed31e4
--- /dev/null
+++ b/dojo/cldr/nls/hu/hebrew.js
@@ -0,0 +1,231 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"quarters-standAlone-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"field-weekday": "hét napja",
+	"dateFormatItem-GyMMMEd": "G y. MMM d., E",
+	"dateFormatItem-MMMEd": "MMM d., E",
+	"eraNarrow": [
+		"TÉ"
+	],
+	"dateFormat-long": "G y. MMMM d.",
+	"months-format-wide": [
+		"Tisri",
+		"Hesván",
+		"Kiszlév",
+		"Tévész",
+		"Svát",
+		"Ádár risón",
+		"Ádár",
+		"Niszán",
+		"Ijár",
+		"Sziván",
+		"Tamuz",
+		"Áv",
+		"Elul"
+	],
+	"dateFormatItem-yyyyQQQ": "G y. QQQ",
+	"dayPeriods-format-wide-pm": "du.",
+	"dateFormat-full": "G y. MMMM d., EEEE",
+	"dateFormatItem-yyyyMEd": "G y.MM.dd., E",
+	"dateFormatItem-Md": "M. d.",
+	"field-era": "éra",
+	"months-standAlone-wide": [
+		"Tisri",
+		"Hesván",
+		"Kiszlév",
+		"Tévész",
+		"Svát",
+		"Ádár risón",
+		"Ádár",
+		"Niszán",
+		"Ijár",
+		"Sziván",
+		"Tamuz",
+		"Áv",
+		"Elul"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"I. negyedév",
+		"II. negyedév",
+		"III. negyedév",
+		"IV. negyedév"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "év",
+	"field-hour": "óra",
+	"months-format-abbr-leap": "Ádár II",
+	"months-format-abbr": [
+		"Tisri",
+		"Hesván",
+		"Kiszlév",
+		"Tévész",
+		"Svát",
+		"Ádár I",
+		"Ádár",
+		"Niszán",
+		"Ijár",
+		"Sziván",
+		"Tamuz",
+		"Áv",
+		"Elul"
+	],
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "ma",
+	"field-day-relative+1": "holnap",
+	"dateFormatItem-GyMMMd": "G y. MMM d.",
+	"field-day-relative+2": "holnapután",
+	"dateFormatItem-H": "H",
+	"months-standAlone-abbr": [
+		"Tisri",
+		"Hesván",
+		"Kiszlév",
+		"Tévész",
+		"Svát",
+		"Ádár risón",
+		"Ádár",
+		"Niszán",
+		"Ijár",
+		"Sziván",
+		"Tamuz",
+		"Áv",
+		"Elul"
+	],
+	"quarters-format-abbr": [
+		"N1",
+		"N2",
+		"N3",
+		"N4"
+	],
+	"quarters-standAlone-wide": [
+		"1. negyedév",
+		"2. negyedév",
+		"3. negyedév",
+		"4. negyedév"
+	],
+	"dateFormatItem-yyyyMMMEd": "G y. MMM d., E",
+	"days-standAlone-wide": [
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
+		"szombat"
+	],
+	"dateFormatItem-yyyyMMM": "G y. MMM",
+	"dateFormatItem-yyyyMMMd": "G y. MMM d.",
+	"months-standAlone-wide-leap": "Ádár II",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"N1",
+		"N2",
+		"N3",
+		"N4"
+	],
+	"eraAbbr": [
+		"TÉ"
+	],
+	"field-minute": "perc",
+	"field-dayperiod": "napszak",
+	"days-standAlone-abbr": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"field-day-relative+-1": "tegnap",
+	"dateFormatItem-h": "a h",
+	"dayPeriods-format-narrow-am": "de.",
+	"field-day-relative+-2": "tegnapelőtt",
+	"dateFormatItem-MMMd": "MMM d.",
+	"dateFormatItem-MEd": "M. d., E",
+	"field-day": "nap",
+	"days-format-wide": [
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
+		"szombat"
+	],
+	"field-zone": "időzóna",
+	"months-standAlone-abbr-leap": "Ádár II",
+	"field-year-relative+-1": "Előző év",
+	"field-month-relative+-1": "Előző hónap",
+	"dateFormatItem-hm": "a h:mm",
+	"days-format-abbr": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"eraNames": [
+		"TÉ"
+	],
+	"days-format-narrow": [
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
+		"Sz"
+	],
+	"dateFormatItem-yyyyMd": "G y.MM.dd.",
+	"field-month": "hónap",
+	"days-standAlone-narrow": [
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
+		"Sz"
+	],
+	"dayPeriods-format-wide-am": "de.",
+	"dateFormat-short": "GGGGG y.MM.dd.",
+	"field-second": "másodperc",
+	"field-month-relative+0": "Ez a hónap",
+	"field-month-relative+1": "Következő hónap",
+	"dateFormatItem-Ed": "d., E",
+	"field-week": "hét",
+	"dateFormat-medium": "G y.MM.dd.",
+	"field-year-relative+0": "Ez az év",
+	"field-week-relative+-1": "Előző hét",
+	"dateFormatItem-yyyyM": "G y.M.",
+	"field-year-relative+1": "Következő év",
+	"dayPeriods-format-narrow-pm": "du.",
+	"dateFormatItem-yyyyQQQQ": "G y. QQQQ",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "a h:mm:ss",
+	"months-format-wide-leap": "Ádár séni",
+	"dateFormatItem-GyMMM": "G y. MMM",
+	"field-week-relative+0": "Ez a hét",
+	"field-week-relative+1": "Következő hét"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/indian.js b/dojo/cldr/nls/hu/indian.js
new file mode 100644
index 0000000..f0ef740
--- /dev/null
+++ b/dojo/cldr/nls/hu/indian.js
@@ -0,0 +1,87 @@
+define(
+//begin v1.x content
+{
+	"field-second": "másodperc",
+	"field-year-relative+-1": "Előző év",
+	"field-week": "hét",
+	"field-month-relative+-1": "Előző hónap",
+	"field-day-relative+-1": "tegnap",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "tegnapelőtt",
+	"months-standAlone-wide": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"field-year": "év",
+	"field-week-relative+0": "Ez a hét",
+	"months-standAlone-abbr": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"field-week-relative+1": "Következő hét",
+	"field-minute": "perc",
+	"field-week-relative+-1": "Előző hét",
+	"field-day-relative+0": "ma",
+	"field-hour": "óra",
+	"field-day-relative+1": "holnap",
+	"field-day-relative+2": "holnapután",
+	"field-day": "nap",
+	"field-month-relative+0": "Ez a hónap",
+	"field-month-relative+1": "Következő hónap",
+	"field-dayperiod": "napszak",
+	"field-month": "hónap",
+	"field-era": "éra",
+	"field-year-relative+0": "Ez az év",
+	"field-year-relative+1": "Következő év",
+	"months-format-abbr": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"field-weekday": "hét napja",
+	"field-zone": "időzóna"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/islamic.js b/dojo/cldr/nls/hu/islamic.js
new file mode 100644
index 0000000..f2126ea
--- /dev/null
+++ b/dojo/cldr/nls/hu/islamic.js
@@ -0,0 +1,237 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"quarters-standAlone-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"field-weekday": "hét napja",
+	"dateFormatItem-GyMMMEd": "G y. MMM d., E",
+	"dateFormatItem-MMMEd": "MMM d., E",
+	"eraNarrow": [
+		"MF"
+	],
+	"dateFormat-long": "G y. MMMM d.",
+	"months-format-wide": [
+		"Moharrem",
+		"Safar",
+		"Rébi el avvel",
+		"Rébi el accher",
+		"Dsemádi el avvel",
+		"Dsemádi el accher",
+		"Redseb",
+		"Sabán",
+		"Ramadán",
+		"Sevvál",
+		"Dsül kade",
+		"Dsül hedse"
+	],
+	"dateFormatItem-yyyyQQQ": "G y. QQQ",
+	"dayPeriods-format-wide-pm": "du.",
+	"dateFormat-full": "G y. MMMM d., EEEE",
+	"dateFormatItem-yyyyMEd": "G y.MM.dd., E",
+	"dateFormatItem-Md": "M. d.",
+	"field-era": "éra",
+	"months-standAlone-wide": [
+		"Moharrem",
+		"Safar",
+		"Rébi I",
+		"Rébi II",
+		"Dsemádi I",
+		"Dsemádi II",
+		"Redseb",
+		"Sabán",
+		"Ramadán",
+		"Sevvál",
+		"Dsül kade",
+		"Dsül hedse"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"I. negyedév",
+		"II. negyedév",
+		"III. negyedév",
+		"IV. negyedév"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "év",
+	"field-hour": "óra",
+	"months-format-abbr": [
+		"Moh.",
+		"Saf.",
+		"Rébi I",
+		"Rébi II",
+		"Dsem. I",
+		"Dsem. II",
+		"Red.",
+		"Sab.",
+		"Ram.",
+		"Sev.",
+		"Dsül k.",
+		"Dsül h."
+	],
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "ma",
+	"field-day-relative+1": "holnap",
+	"dateFormatItem-GyMMMd": "G y. MMM d.",
+	"field-day-relative+2": "holnapután",
+	"dateFormatItem-H": "H",
+	"months-standAlone-abbr": [
+		"Moh.",
+		"Saf.",
+		"Rébi I",
+		"Rébi II",
+		"Dsem. I",
+		"Dsem. II",
+		"Red.",
+		"Sab.",
+		"Ram.",
+		"Sev.",
+		"Dsül k.",
+		"Dsül h."
+	],
+	"quarters-format-abbr": [
+		"N1",
+		"N2",
+		"N3",
+		"N4"
+	],
+	"quarters-standAlone-wide": [
+		"1. negyedév",
+		"2. negyedév",
+		"3. negyedév",
+		"4. negyedév"
+	],
+	"dateFormatItem-yyyyMMMEd": "G y. MMM d., E",
+	"days-standAlone-wide": [
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
+		"szombat"
+	],
+	"dateFormatItem-yyyyMMM": "G y. MMM",
+	"dateFormatItem-yyyyMMMd": "G y. MMM d.",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"N1",
+		"N2",
+		"N3",
+		"N4"
+	],
+	"eraAbbr": [
+		"MF"
+	],
+	"field-minute": "perc",
+	"field-dayperiod": "napszak",
+	"days-standAlone-abbr": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"field-day-relative+-1": "tegnap",
+	"dateFormatItem-h": "a h",
+	"dayPeriods-format-narrow-am": "de.",
+	"field-day-relative+-2": "tegnapelőtt",
+	"dateFormatItem-MMMd": "MMM d.",
+	"dateFormatItem-MEd": "M. d., E",
+	"field-day": "nap",
+	"days-format-wide": [
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
+		"szombat"
+	],
+	"field-zone": "időzóna",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year-relative+-1": "Előző év",
+	"field-month-relative+-1": "Előző hónap",
+	"dateFormatItem-hm": "a h:mm",
+	"days-format-abbr": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"eraNames": [
+		"MF"
+	],
+	"days-format-narrow": [
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
+		"Sz"
+	],
+	"dateFormatItem-yyyyMd": "G y.MM.dd.",
+	"field-month": "hónap",
+	"days-standAlone-narrow": [
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
+		"Sz"
+	],
+	"dayPeriods-format-wide-am": "de.",
+	"dateFormat-short": "GGGGG y.MM.dd.",
+	"field-second": "másodperc",
+	"field-month-relative+0": "Ez a hónap",
+	"field-month-relative+1": "Következő hónap",
+	"dateFormatItem-Ed": "d., E",
+	"field-week": "hét",
+	"dateFormat-medium": "G y.MM.dd.",
+	"field-year-relative+0": "Ez az év",
+	"field-week-relative+-1": "Előző hét",
+	"dateFormatItem-yyyyM": "G y.M.",
+	"field-year-relative+1": "Következő év",
+	"dayPeriods-format-narrow-pm": "du.",
+	"dateFormatItem-yyyyQQQQ": "G y. QQQQ",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "a h:mm:ss",
+	"dateFormatItem-GyMMM": "G y. MMM",
+	"field-week-relative+0": "Ez a hét",
+	"field-week-relative+1": "Következő hét"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/japanese.js b/dojo/cldr/nls/hu/japanese.js
new file mode 100644
index 0000000..8bfcb0a
--- /dev/null
+++ b/dojo/cldr/nls/hu/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "G y.MM.dd.",
+	"field-second": "másodperc",
+	"field-year-relative+-1": "Előző év",
+	"field-week": "hét",
+	"field-month-relative+-1": "Előző hónap",
+	"field-day-relative+-1": "tegnap",
+	"field-day-relative+-2": "tegnapelőtt",
+	"field-year": "év",
+	"field-week-relative+0": "Ez a hét",
+	"field-week-relative+1": "Következő hét",
+	"field-minute": "perc",
+	"field-week-relative+-1": "Előző hét",
+	"field-day-relative+0": "ma",
+	"field-hour": "óra",
+	"field-day-relative+1": "holnap",
+	"dateFormat-long": "G y. MMMM d.",
+	"field-day-relative+2": "holnapután",
+	"field-day": "nap",
+	"field-month-relative+0": "Ez a hónap",
+	"field-month-relative+1": "Következő hónap",
+	"field-dayperiod": "napszak",
+	"field-month": "hónap",
+	"dateFormat-short": "GGGGG y.MM.dd.",
+	"field-era": "éra",
+	"field-year-relative+0": "Ez az év",
+	"field-year-relative+1": "Következő év",
+	"dateFormat-full": "G y. MMMM d., EEEE",
+	"field-weekday": "hét napja",
+	"field-zone": "időzóna"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/number.js b/dojo/cldr/nls/hu/number.js
index 7400fec..de850a3 100644
--- a/dojo/cldr/nls/hu/number.js
+++ b/dojo/cldr/nls/hu/number.js
@@ -5,17 +5,18 @@ define(
 	"percentSign": "%",
 	"exponential": "E",
 	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 billió",
+	"decimalFormat-short": "000 B"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/persian.js b/dojo/cldr/nls/hu/persian.js
new file mode 100644
index 0000000..a90ac97
--- /dev/null
+++ b/dojo/cldr/nls/hu/persian.js
@@ -0,0 +1,242 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"field-weekday": "hét napja",
+	"dateFormatItem-GyMMMEd": "G y. MMM d., E",
+	"dateFormatItem-MMMEd": "MMM d., E",
+	"dateFormat-long": "G y. MMMM d.",
+	"months-format-wide": [
+		"január",
+		"február",
+		"március",
+		"április",
+		"május",
+		"június",
+		"július",
+		"augusztus",
+		"szeptember",
+		"október",
+		"november",
+		"december"
+	],
+	"dateFormatItem-yyyyQQQ": "G y. QQQ",
+	"dayPeriods-format-wide-pm": "du.",
+	"dateFormat-full": "G y. MMMM d., EEEE",
+	"dateFormatItem-yyyyMEd": "G y.MM.dd., E",
+	"dateFormatItem-Md": "M. d.",
+	"field-era": "éra",
+	"months-standAlone-wide": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordad",
+		"Tir",
+		"Mordad",
+		"Shahrivar",
+		"Mehr",
+		"Aban",
+		"Azar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"I. negyedév",
+		"II. negyedév",
+		"III. negyedév",
+		"IV. negyedév"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "év",
+	"field-hour": "óra",
+	"months-format-abbr": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordad",
+		"Tir",
+		"Mordad",
+		"Shahrivar",
+		"Mehr",
+		"Aban",
+		"Azar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "ma",
+	"field-day-relative+1": "holnap",
+	"dateFormatItem-GyMMMd": "G y. MMM d.",
+	"field-day-relative+2": "holnapután",
+	"dateFormatItem-H": "H",
+	"months-standAlone-abbr": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordad",
+		"Tir",
+		"Mordad",
+		"Shahrivar",
+		"Mehr",
+		"Aban",
+		"Azar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"quarters-format-abbr": [
+		"N1",
+		"N2",
+		"N3",
+		"N4"
+	],
+	"quarters-standAlone-wide": [
+		"1. negyedév",
+		"2. negyedév",
+		"3. negyedév",
+		"4. negyedév"
+	],
+	"dateFormatItem-yyyyMMMEd": "G y. MMM d., E",
+	"days-standAlone-wide": [
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
+		"szombat"
+	],
+	"dateFormatItem-yyyyMMM": "G y. MMM",
+	"dateFormatItem-yyyyMMMd": "G y. MMM d.",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"N1",
+		"N2",
+		"N3",
+		"N4"
+	],
+	"field-minute": "perc",
+	"field-dayperiod": "napszak",
+	"days-standAlone-abbr": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"field-day-relative+-1": "tegnap",
+	"dateFormatItem-h": "a h",
+	"dayPeriods-format-narrow-am": "de.",
+	"field-day-relative+-2": "tegnapelőtt",
+	"dateFormatItem-MMMd": "MMM d.",
+	"dateFormatItem-MEd": "M. d., E",
+	"field-day": "nap",
+	"days-format-wide": [
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
+		"szombat"
+	],
+	"field-zone": "időzóna",
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"Á",
+		"M",
+		"J",
+		"J",
+		"A",
+		"Sz",
+		"O",
+		"N",
+		"D"
+	],
+	"field-year-relative+-1": "Előző év",
+	"field-month-relative+-1": "Előző hónap",
+	"dateFormatItem-hm": "a h:mm",
+	"days-format-abbr": [
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
+		"Szo"
+	],
+	"days-format-narrow": [
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
+		"Sz"
+	],
+	"dateFormatItem-yyyyMd": "G y.MM.dd.",
+	"field-month": "hónap",
+	"days-standAlone-narrow": [
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
+		"Sz"
+	],
+	"dayPeriods-format-wide-am": "de.",
+	"dateFormat-short": "GGGGG y.MM.dd.",
+	"field-second": "másodperc",
+	"field-month-relative+0": "Ez a hónap",
+	"field-month-relative+1": "Következő hónap",
+	"dateFormatItem-Ed": "d., E",
+	"field-week": "hét",
+	"dateFormat-medium": "G y.MM.dd.",
+	"field-year-relative+0": "Ez az év",
+	"field-week-relative+-1": "Előző hét",
+	"dateFormatItem-yyyyM": "G y.M.",
+	"field-year-relative+1": "Következő év",
+	"dayPeriods-format-narrow-pm": "du.",
+	"dateFormatItem-yyyyQQQQ": "G y. QQQQ",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "a h:mm:ss",
+	"dateFormatItem-GyMMM": "G y. MMM",
+	"field-week-relative+0": "Ez a hét",
+	"field-week-relative+1": "Következő hét"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/roc.js b/dojo/cldr/nls/hu/roc.js
new file mode 100644
index 0000000..fa9bdfb
--- /dev/null
+++ b/dojo/cldr/nls/hu/roc.js
@@ -0,0 +1,34 @@
+define(
+//begin v1.x content
+{
+	"field-second": "másodperc",
+	"field-year-relative+-1": "Előző év",
+	"field-week": "hét",
+	"field-month-relative+-1": "Előző hónap",
+	"field-day-relative+-1": "tegnap",
+	"field-day-relative+-2": "tegnapelőtt",
+	"field-year": "év",
+	"field-week-relative+0": "Ez a hét",
+	"field-week-relative+1": "Következő hét",
+	"field-minute": "perc",
+	"field-week-relative+-1": "Előző hét",
+	"field-day-relative+0": "ma",
+	"field-hour": "óra",
+	"field-day-relative+1": "holnap",
+	"field-day-relative+2": "holnapután",
+	"field-day": "nap",
+	"field-month-relative+0": "Ez a hónap",
+	"field-month-relative+1": "Következő hónap",
+	"field-dayperiod": "napszak",
+	"field-month": "hónap",
+	"field-era": "éra",
+	"field-year-relative+0": "Ez az év",
+	"field-year-relative+1": "Következő év",
+	"eraAbbr": [
+		"R.O.C. előtt"
+	],
+	"field-weekday": "hét napja",
+	"field-zone": "időzóna"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/indian.js b/dojo/cldr/nls/indian.js
new file mode 100644
index 0000000..19be5ce
--- /dev/null
+++ b/dojo/cldr/nls/indian.js
@@ -0,0 +1,428 @@
+define({ root:
+
+//begin v1.x content
+{
+	"eraNarrow at localeAlias336": {
+		"bundle": "indian",
+		"target": "eraAbbr"
+	},
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"months-standAlone-wide at localeAlias310": {
+		"bundle": "indian",
+		"target": "months-format-wide"
+	},
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
+	"months-standAlone-abbr at localeAlias308": {
+		"bundle": "indian",
+		"target": "months-format-abbr"
+	},
+	"months-standAlone-abbr at localeAlias309": {
+		"bundle": "indian",
+		"target": "months-format-wide"
+	},
+	"eraNarrow": [
+		"SAKA"
+	],
+	"months-format-abbr at localeAlias306": {
+		"bundle": "indian",
+		"target": "months-format-wide"
+	},
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dayPeriods-format-abbr at localeAlias332": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormat-long": "G y MMMM d",
+	"months-format-wide": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"dateFormatItem-Md": "MM-dd",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
+	"months-format-abbr": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"months-format-narrow at localeAlias307": {
+		"bundle": "indian",
+		"target": "months-standAlone-narrow"
+	},
+	"quarters at localeAlias322": {
+		"bundle": "gregorian",
+		"target": "quarters"
+	},
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
+	"months-standAlone-abbr": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"dateFormatItem-H": "HH",
+	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
+	"timeFormat-medium": "HH:mm:ss",
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Hm": "HH:mm",
+	"eraAbbr": [
+		"SAKA"
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"days-format-short at localeAlias314": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-format-short at localeAlias315": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"eraNames at localeAlias335": {
+		"bundle": "indian",
+		"target": "eraAbbr"
+	},
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormat at localeAlias337": {
+		"bundle": "generic",
+		"target": "dateFormat"
+	},
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Yesterday",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateTimeFormat-long": "{1} {0}",
+	"dateFormatItem-h": "h a",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "MM-dd, E",
+	"days-standAlone-wide at localeAlias321": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"timeFormat at localeAlias338": {
+		"bundle": "gregorian",
+		"target": "timeFormat"
+	},
+	"field-zone": "Zone",
+	"days-standAlone-abbr at localeAlias316": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-standAlone-short at localeAlias318": {
+		"bundle": "gregorian",
+		"target": "days-format-short"
+	},
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"days-standAlone-abbr at localeAlias317": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateFormatItem-y": "G y",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"days-standAlone-short at localeAlias319": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias330": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias331": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dayPeriods-format-narrow at localeAlias333": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias334": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
+	"dayPeriods at localeAlias328": {
+		"bundle": "gregorian",
+		"target": "dayPeriods"
+	},
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"eraNames": [
+		"SAKA"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"quarters-standAlone-wide at localeAlias327": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
+	"days-standAlone-short at localeAlias320": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-format-abbr at localeAlias312": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"days-format-narrow at localeAlias313": {
+		"bundle": "gregorian",
+		"target": "days-standAlone-narrow"
+	},
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"days at localeAlias311": {
+		"bundle": "gregorian",
+		"target": "days"
+	},
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"field-second": "Second",
+	"dateFormatItem-Ed": "d, E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"quarters-standAlone-abbr at localeAlias325": {
+		"bundle": "gregorian",
+		"target": "quarters-format-abbr"
+	},
+	"dateFormatItem-GyMMM": "G y MMM",
+	"quarters-standAlone-abbr at localeAlias326": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateTime at localeAlias339": {
+		"bundle": "generic",
+		"target": "dateTime"
+	},
+	"dateFormatItem-yyyy": "G y",
+	"dayPeriods-format-abbr at localeAlias329": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"quarters-format-abbr at localeAlias323": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"quarters-format-narrow at localeAlias324": {
+		"bundle": "gregorian",
+		"target": "quarters-standAlone-narrow"
+	}
+}
+//end v1.x content
+,
+	"en-gb": true,
+	"fr": true,
+	"hu": true,
+	"ja": true,
+	"pl": true,
+	"pt": true,
+	"ru": true,
+	"sv": true,
+	"th": true,
+	"zh": true,
+	"zh-hant": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/islamic-civil.js b/dojo/cldr/nls/islamic-civil.js
new file mode 100644
index 0000000..4b71c99
--- /dev/null
+++ b/dojo/cldr/nls/islamic-civil.js
@@ -0,0 +1,280 @@
+define({ root:
+
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
+	"eraNarrow": [
+		"AH"
+	],
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "G y MMMM d",
+	"months-format-wide": [
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
+		"Dhuʻl-Hijjah"
+	],
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"dateFormatItem-Md": "MM-dd",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
+		"Dhuʻl-Hijjah"
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
+	"months-format-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
+		"Dhuʻl-H."
+	],
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
+	"dateFormatItem-H": "HH",
+	"months-standAlone-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
+		"Dhuʻl-H."
+	],
+	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Yesterday",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "MM-dd, E",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"field-zone": "Zone",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dateFormatItem-y": "G y",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"eraNames": [
+		"AH"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"field-second": "Second",
+	"dateFormatItem-Ed": "d, E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "G y MMM",
+	"dateFormatItem-yyyy": "G y"
+}
+//end v1.x content
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/islamic.js b/dojo/cldr/nls/islamic.js
index 0c0c3ee..22459e6 100644
--- a/dojo/cldr/nls/islamic.js
+++ b/dojo/cldr/nls/islamic.js
@@ -2,6 +2,15 @@ define({ root:
 
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
 	"months-format-narrow": [
 		"1",
 		"2",
@@ -22,14 +31,23 @@ define({ root:
 		"3",
 		"4"
 	],
-	"dateFormatItem-yQQQ": "y QQQ",
-	"dateFormatItem-yMEd": "EEE, y-M-d",
-	"dateFormatItem-MMMEd": "E MMM d",
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
 	"eraNarrow": [
 		"AH"
 	],
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
 	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
-	"dateFormat-long": "y MMMM d",
+	"dateFormat-long": "G y MMMM d",
 	"months-format-wide": [
 		"Muharram",
 		"Safar",
@@ -44,14 +62,15 @@ define({ root:
 		"Dhuʻl-Qiʻdah",
 		"Dhuʻl-Hijjah"
 	],
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
 	"dateTimeFormat-medium": "{1} {0}",
-	"dateFormatItem-EEEd": "d EEE",
 	"dayPeriods-format-wide-pm": "PM",
-	"dateFormat-full": "EEEE, y MMMM dd",
-	"dateFormatItem-Md": "M-d",
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"dateFormatItem-Md": "MM-dd",
 	"dayPeriods-format-abbr-am": "AM",
 	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
-	"dateFormatItem-yM": "y-M",
+	"field-era": "Era",
 	"months-standAlone-wide": [
 		"Muharram",
 		"Safar",
@@ -74,9 +93,9 @@ define({ root:
 		"Q4"
 	],
 	"timeFormat-long": "HH:mm:ss z",
-	"dateFormatItem-yMMM": "y MMM",
-	"dateFormatItem-yQ": "y Q",
-	"dateTimeFormats-appendItem-Era": "{0} {1}",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
 	"months-format-abbr": [
 		"Muh.",
 		"Saf.",
@@ -93,6 +112,9 @@ define({ root:
 	],
 	"timeFormat-full": "HH:mm:ss zzzz",
 	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
 	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
 		"Muh.",
@@ -120,16 +142,20 @@ define({ root:
 		"Q3",
 		"Q4"
 	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -141,14 +167,16 @@ define({ root:
 	"eraAbbr": [
 		"AH"
 	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
 	"days-standAlone-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
@@ -158,23 +186,26 @@ define({ root:
 		"3",
 		"4"
 	],
+	"field-day-relative+-1": "Yesterday",
 	"dateFormatItem-h": "h a",
 	"dateTimeFormat-long": "{1} {0}",
 	"dayPeriods-format-narrow-am": "AM",
 	"dateFormatItem-MMMd": "MMM d",
-	"dateFormatItem-MEd": "E, M-d",
+	"dateFormatItem-MEd": "MM-dd, E",
 	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "Day",
 	"days-format-wide": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
+	"field-zone": "Zone",
 	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
-	"dateFormatItem-y": "y",
+	"dateFormatItem-y": "G y",
 	"months-standAlone-narrow": [
 		"1",
 		"2",
@@ -190,71 +221,82 @@ define({ root:
 		"12"
 	],
 	"dateFormatItem-hm": "h:mm a",
-	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
 	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
 	"dayPeriods-format-abbr-pm": "PM",
 	"days-format-abbr": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
 	],
 	"eraNames": [
 		"AH"
 	],
 	"days-format-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
 	],
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
 	"days-standAlone-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7"
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
 	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
 	"dayPeriods-format-wide-am": "AM",
 	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
 	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
-	"dateFormat-short": "yyyy-MM-dd",
-	"dateFormatItem-yMMMEd": "EEE, y MMM d",
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"field-second": "Second",
+	"dateFormatItem-Ed": "d, E",
 	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
-	"dateFormat-medium": "y MMM d",
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
 	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
 	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-hms": "h:mm:ss a"
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "G y MMM",
+	"dateFormatItem-yyyy": "G y"
 }
 //end v1.x content
 ,
 	"ar": true,
+	"cs": true,
 	"da": true,
 	"de": true,
 	"en": true,
-	"en-gb": true,
 	"es": true,
 	"fi": true,
 	"fr": true,
 	"he": true,
 	"hu": true,
 	"it": true,
+	"ja": true,
+	"ko": true,
 	"nb": true,
 	"nl": true,
 	"pl": true,
 	"pt": true,
 	"pt-pt": true,
+	"ro": true,
 	"ru": true,
 	"sv": true,
 	"th": true,
diff --git a/dojo/cldr/nls/it/buddhist.js b/dojo/cldr/nls/it/buddhist.js
new file mode 100644
index 0000000..b48d3ee
--- /dev/null
+++ b/dojo/cldr/nls/it/buddhist.js
@@ -0,0 +1,230 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
+		"sab"
+	],
+	"months-format-narrow": [
+		"G",
+		"F",
+		"M",
+		"A",
+		"M",
+		"G",
+		"L",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-weekday": "giorno della settimana",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"eraNarrow": [
+		"EB"
+	],
+	"days-format-short": [
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
+		"sab"
+	],
+	"dateFormat-long": "dd MMMM y G",
+	"months-format-wide": [
+		"gennaio",
+		"febbraio",
+		"marzo",
+		"aprile",
+		"maggio",
+		"giugno",
+		"luglio",
+		"agosto",
+		"settembre",
+		"ottobre",
+		"novembre",
+		"dicembre"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-yyyyMEd": "E d/M/y GGGGG",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "era",
+	"months-standAlone-wide": [
+		"Gennaio",
+		"Febbraio",
+		"Marzo",
+		"Aprile",
+		"Maggio",
+		"Giugno",
+		"Luglio",
+		"Agosto",
+		"Settembre",
+		"Ottobre",
+		"Novembre",
+		"Dicembre"
+	],
+	"quarters-format-wide": [
+		"1o trimestre",
+		"2o trimestre",
+		"3o trimestre",
+		"4o trimestre"
+	],
+	"field-year": "anno",
+	"field-hour": "ora",
+	"months-format-abbr": [
+		"gen",
+		"feb",
+		"mar",
+		"apr",
+		"mag",
+		"giu",
+		"lug",
+		"ago",
+		"set",
+		"ott",
+		"nov",
+		"dic"
+	],
+	"field-day-relative+0": "oggi",
+	"field-day-relative+1": "domani",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "dopodomani",
+	"months-standAlone-abbr": [
+		"gen",
+		"feb",
+		"mar",
+		"apr",
+		"mag",
+		"giu",
+		"lug",
+		"ago",
+		"set",
+		"ott",
+		"nov",
+		"dic"
+	],
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"quarters-standAlone-wide": [
+		"Primo trimestre",
+		"Secondo trimestre",
+		"Terzo trimestre",
+		"Quarto trimestre"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"days-standAlone-wide": [
+		"Domenica",
+		"Lunedì",
+		"Martedì",
+		"Mercoledì",
+		"Giovedì",
+		"Venerdì",
+		"Sabato"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"eraAbbr": [
+		"EB"
+	],
+	"field-minute": "minuto",
+	"field-dayperiod": "periodo del giorno",
+	"field-day-relative+-1": "ieri",
+	"dateFormatItem-h": "hh a",
+	"dayPeriods-format-narrow-am": "m.",
+	"field-day-relative+-2": "l'altro ieri",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E d/M",
+	"field-day": "giorno",
+	"days-format-wide": [
+		"domenica",
+		"lunedì",
+		"martedì",
+		"mercoledì",
+		"giovedì",
+		"venerdì",
+		"sabato"
+	],
+	"field-zone": "zona",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"G",
+		"F",
+		"M",
+		"A",
+		"M",
+		"G",
+		"L",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-year-relative+-1": "Anno scorso",
+	"field-month-relative+-1": "Mese scorso",
+	"dateFormatItem-hm": "hh:mm a",
+	"days-format-abbr": [
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
+		"sab"
+	],
+	"eraNames": [
+		"EB"
+	],
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"field-month": "mese",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"G",
+		"V",
+		"S"
+	],
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"field-second": "secondo",
+	"field-month-relative+0": "Questo mese",
+	"field-month-relative+1": "Mese prossimo",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "settimana",
+	"dateFormat-medium": "dd/MMM/y G",
+	"field-year-relative+0": "Questo anno",
+	"field-week-relative+-1": "Settimana scorsa",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"field-year-relative+1": "Anno prossimo",
+	"dayPeriods-format-narrow-pm": "p.",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "Questa settimana",
+	"field-week-relative+1": "Settimana prossima"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/chinese.js b/dojo/cldr/nls/it/chinese.js
new file mode 100644
index 0000000..027fe02
--- /dev/null
+++ b/dojo/cldr/nls/it/chinese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "dd/MMM U",
+	"field-second": "secondo",
+	"field-year-relative+-1": "Anno scorso",
+	"field-week": "settimana",
+	"field-month-relative+-1": "Mese scorso",
+	"field-day-relative+-1": "ieri",
+	"field-day-relative+-2": "l'altro ieri",
+	"field-year": "anno",
+	"field-week-relative+0": "Questa settimana",
+	"field-week-relative+1": "Settimana prossima",
+	"field-minute": "minuto",
+	"field-week-relative+-1": "Settimana scorsa",
+	"field-day-relative+0": "oggi",
+	"field-hour": "ora",
+	"field-day-relative+1": "domani",
+	"dateFormat-long": "dd MMMM U",
+	"field-day-relative+2": "dopodomani",
+	"field-day": "giorno",
+	"field-month-relative+0": "Questo mese",
+	"field-month-relative+1": "Mese prossimo",
+	"field-dayperiod": "periodo del giorno",
+	"field-month": "mese",
+	"dateFormat-short": "dd/MM/yy",
+	"field-era": "era",
+	"field-year-relative+0": "Questo anno",
+	"field-year-relative+1": "Anno prossimo",
+	"dateFormat-full": "EEEE d MMMM U",
+	"field-weekday": "giorno della settimana",
+	"field-zone": "zona"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/currency.js b/dojo/cldr/nls/it/currency.js
index 520a731..a18ba25 100644
--- a/dojo/cldr/nls/it/currency.js
+++ b/dojo/cldr/nls/it/currency.js
@@ -5,8 +5,10 @@ define(
 	"CHF_displayName": "Franco Svizzero",
 	"CAD_displayName": "Dollaro Canadese",
 	"CNY_displayName": "Renmimbi Cinese",
+	"USD_symbol": "US$",
 	"AUD_displayName": "Dollaro Australiano",
 	"JPY_displayName": "Yen Giapponese",
+	"CAD_symbol": "CA$",
 	"USD_displayName": "Dollaro Statunitense",
 	"GBP_displayName": "Sterlina Inglese",
 	"EUR_displayName": "Euro"
diff --git a/dojo/cldr/nls/it/generic.js b/dojo/cldr/nls/it/generic.js
new file mode 100644
index 0000000..98b66c2
--- /dev/null
+++ b/dojo/cldr/nls/it/generic.js
@@ -0,0 +1,69 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-dayperiod": "periodo del giorno",
+	"field-minute": "minuto",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "ieri",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"field-day-relative+-2": "l'altro ieri",
+	"field-weekday": "giorno della settimana",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "era",
+	"field-hour": "ora",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "oggi",
+	"field-day-relative+1": "domani",
+	"field-day-relative+2": "dopodomani",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormat-long": "dd MMMM y G",
+	"field-zone": "zona",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Settimana scorsa",
+	"dateFormat-medium": "dd/MMM/y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Questo anno",
+	"field-year-relative+1": "Anno prossimo",
+	"field-year-relative+-1": "Anno scorso",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-year": "anno",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "settimana",
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMEd": "E d/M/y GGGGG",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Questa settimana",
+	"field-week-relative+1": "Settimana prossima",
+	"field-month-relative+0": "Questo mese",
+	"dateFormatItem-H": "HH",
+	"field-month": "mese",
+	"field-month-relative+1": "Mese prossimo",
+	"dateFormatItem-M": "L",
+	"field-second": "secondo",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "giorno",
+	"dateFormatItem-MEd": "E d/M",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "hh:mm a",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Mese scorso",
+	"dateFormatItem-h": "hh a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/gregorian.js b/dojo/cldr/nls/it/gregorian.js
index c10ef3c..72a83da 100644
--- a/dojo/cldr/nls/it/gregorian.js
+++ b/dojo/cldr/nls/it/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
+		"sab"
+	],
 	"months-format-narrow": [
 		"G",
 		"F",
@@ -15,15 +24,30 @@ define(
 		"N",
 		"D"
 	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "giorno della settimana",
-	"dateFormatItem-yyQQQQ": "QQQQ yy",
 	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "EEE, d/M/y",
-	"dateFormatItem-MMMEd": "EEE d MMM",
+	"dateFormatItem-yMEd": "E d/M/y",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
 		"aC",
 		"dC"
 	],
+	"days-format-short": [
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
+		"sab"
+	],
 	"dateFormat-long": "dd MMMM y",
 	"months-format-wide": [
 		"gennaio",
@@ -39,9 +63,11 @@ define(
 		"novembre",
 		"dicembre"
 	],
-	"dayPeriods-format-wide-pm": "p.",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
 	"dateFormat-full": "EEEE d MMMM y",
 	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMd": "d/M/y",
 	"field-era": "era",
 	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
@@ -65,13 +91,11 @@ define(
 		"3o trimestre",
 		"4o trimestre"
 	],
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-long": "HH:mm:ss z",
 	"field-year": "anno",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "Q-yyyy",
-	"dateFormatItem-yyyyMMMM": "MMMM y",
 	"field-hour": "ora",
-	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
 		"gen",
 		"feb",
@@ -86,12 +110,12 @@ define(
 		"nov",
 		"dic"
 	],
-	"dateFormatItem-yyQ": "Q yy",
 	"timeFormat-full": "HH:mm:ss zzzz",
 	"field-day-relative+0": "oggi",
 	"field-day-relative+1": "domani",
+	"dateFormatItem-GyMMMd": "d MMM y G",
 	"field-day-relative+2": "dopodomani",
-	"field-day-relative+3": "tra tre giorni",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
 		"gen",
 		"feb",
@@ -113,11 +137,12 @@ define(
 		"T4"
 	],
 	"quarters-standAlone-wide": [
-		"1o trimestre",
-		"2o trimestre",
-		"3o trimestre",
-		"4o trimestre"
+		"Primo trimestre",
+		"Secondo trimestre",
+		"Terzo trimestre",
+		"Quarto trimestre"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
 		"Domenica",
@@ -153,12 +178,21 @@ define(
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "ieri",
 	"dateFormatItem-h": "hh a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "m.",
 	"field-day-relative+-2": "l'altro ieri",
-	"field-day-relative+-3": "tre giorni fa",
 	"dateFormatItem-MMMd": "d MMM",
-	"dateFormatItem-MEd": "EEE d/M",
+	"dateFormatItem-MEd": "E d/M",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-yMMMM": "MMMM y",
 	"field-day": "giorno",
 	"days-format-wide": [
 		"domenica",
@@ -185,7 +219,8 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-yyMM": "MM/yy",
+	"field-year-relative+-1": "Anno scorso",
+	"field-month-relative+-1": "Mese scorso",
 	"dateFormatItem-hm": "hh:mm a",
 	"days-format-abbr": [
 		"dom",
@@ -196,6 +231,7 @@ define(
 		"ven",
 		"sab"
 	],
+	"dateFormatItem-yMMMd": "d MMM y",
 	"eraNames": [
 		"a.C.",
 		"d.C"
@@ -220,16 +256,25 @@ define(
 		"S"
 	],
 	"dateFormatItem-MMM": "LLL",
-	"dayPeriods-format-wide-am": "m.",
-	"dateFormatItem-MMMMdd": "dd MMMM",
+	"dayPeriods-format-wide-am": "AM",
 	"dateFormat-short": "dd/MM/yy",
 	"field-second": "secondo",
-	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"dateFormatItem-yMMMEd": "E d MMM y",
+	"field-month-relative+0": "Questo mese",
+	"field-month-relative+1": "Mese prossimo",
 	"dateFormatItem-Ed": "E d",
 	"field-week": "settimana",
 	"dateFormat-medium": "dd/MMM/y",
+	"field-year-relative+0": "Questo anno",
+	"field-week-relative+-1": "Settimana scorsa",
+	"field-year-relative+1": "Anno prossimo",
+	"dayPeriods-format-narrow-pm": "p.",
+	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-hms": "hh:mm:ss a"
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "Questa settimana",
+	"field-week-relative+1": "Settimana prossima"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/hebrew.js b/dojo/cldr/nls/it/hebrew.js
new file mode 100644
index 0000000..9d5aa62
--- /dev/null
+++ b/dojo/cldr/nls/it/hebrew.js
@@ -0,0 +1,140 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "periodo del giorno",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-minute": "minuto",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "ieri",
+	"field-weekday": "giorno della settimana",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"field-day-relative+-2": "l'altro ieri",
+	"days-standAlone-wide": [
+		"Domenica",
+		"Lunedì",
+		"Martedì",
+		"Mercoledì",
+		"Giovedì",
+		"Venerdì",
+		"Sabato"
+	],
+	"field-era": "era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "ora",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "oggi",
+	"field-day-relative+1": "domani",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"G",
+		"V",
+		"S"
+	],
+	"eraAbbr": [
+		"AM"
+	],
+	"field-day-relative+2": "dopodomani",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "dd MMMM y G",
+	"field-zone": "zona",
+	"field-week-relative+-1": "Settimana scorsa",
+	"dateFormat-medium": "dd/MMM/y G",
+	"dayPeriods-format-narrow-pm": "p.",
+	"field-year-relative+0": "Questo anno",
+	"field-year-relative+1": "Anno prossimo",
+	"quarters-standAlone-wide": [
+		"Primo trimestre",
+		"Secondo trimestre",
+		"Terzo trimestre",
+		"Quarto trimestre"
+	],
+	"field-year-relative+-1": "Anno scorso",
+	"field-year": "anno",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dayPeriods-format-narrow-am": "m.",
+	"field-week": "settimana",
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMEd": "E d/M/y GGGGG",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Questa settimana",
+	"field-week-relative+1": "Settimana prossima",
+	"field-month-relative+0": "Questo mese",
+	"field-month": "mese",
+	"field-month-relative+1": "Mese prossimo",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
+		"sab"
+	],
+	"field-second": "secondo",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "giorno",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E d/M",
+	"days-standAlone-short": [
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
+		"sab"
+	],
+	"dateFormatItem-hm": "hh:mm a",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormatItem-Md": "d/M",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"days-format-short": [
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
+		"sab"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "Mese scorso",
+	"quarters-format-wide": [
+		"1o trimestre",
+		"2o trimestre",
+		"3o trimestre",
+		"4o trimestre"
+	],
+	"days-format-wide": [
+		"domenica",
+		"lunedì",
+		"martedì",
+		"mercoledì",
+		"giovedì",
+		"venerdì",
+		"sabato"
+	],
+	"dateFormatItem-h": "hh a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/islamic.js b/dojo/cldr/nls/it/islamic.js
new file mode 100644
index 0000000..3caf841
--- /dev/null
+++ b/dojo/cldr/nls/it/islamic.js
@@ -0,0 +1,140 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "periodo del giorno",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-minute": "minuto",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "ieri",
+	"field-weekday": "giorno della settimana",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"field-day-relative+-2": "l'altro ieri",
+	"days-standAlone-wide": [
+		"Domenica",
+		"Lunedì",
+		"Martedì",
+		"Mercoledì",
+		"Giovedì",
+		"Venerdì",
+		"Sabato"
+	],
+	"field-era": "era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "ora",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "oggi",
+	"field-day-relative+1": "domani",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"G",
+		"V",
+		"S"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"field-day-relative+2": "dopodomani",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "dd MMMM y G",
+	"field-zone": "zona",
+	"field-week-relative+-1": "Settimana scorsa",
+	"dateFormat-medium": "dd/MMM/y G",
+	"dayPeriods-format-narrow-pm": "p.",
+	"field-year-relative+0": "Questo anno",
+	"field-year-relative+1": "Anno prossimo",
+	"quarters-standAlone-wide": [
+		"Primo trimestre",
+		"Secondo trimestre",
+		"Terzo trimestre",
+		"Quarto trimestre"
+	],
+	"field-year-relative+-1": "Anno scorso",
+	"field-year": "anno",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dayPeriods-format-narrow-am": "m.",
+	"field-week": "settimana",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMd": "d/M/y GGGGG",
+	"dateFormatItem-yyyyMEd": "E d/M/y GGGGG",
+	"field-week-relative+0": "Questa settimana",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+1": "Settimana prossima",
+	"field-month-relative+0": "Questo mese",
+	"field-month": "mese",
+	"field-month-relative+1": "Mese prossimo",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
+		"sab"
+	],
+	"field-second": "secondo",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "giorno",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E d/M",
+	"days-standAlone-short": [
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
+		"sab"
+	],
+	"dateFormatItem-hm": "hh:mm a",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "M/y GGGGG",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"days-format-short": [
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
+		"sab"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "Mese scorso",
+	"quarters-format-wide": [
+		"1o trimestre",
+		"2o trimestre",
+		"3o trimestre",
+		"4o trimestre"
+	],
+	"days-format-wide": [
+		"domenica",
+		"lunedì",
+		"martedì",
+		"mercoledì",
+		"giovedì",
+		"venerdì",
+		"sabato"
+	],
+	"dateFormatItem-h": "hh a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/japanese.js b/dojo/cldr/nls/it/japanese.js
new file mode 100644
index 0000000..3e79d61
--- /dev/null
+++ b/dojo/cldr/nls/it/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "dd/MMM/y G",
+	"field-second": "secondo",
+	"field-year-relative+-1": "Anno scorso",
+	"field-week": "settimana",
+	"field-month-relative+-1": "Mese scorso",
+	"field-day-relative+-1": "ieri",
+	"field-day-relative+-2": "l'altro ieri",
+	"field-year": "anno",
+	"field-week-relative+0": "Questa settimana",
+	"field-week-relative+1": "Settimana prossima",
+	"field-minute": "minuto",
+	"field-week-relative+-1": "Settimana scorsa",
+	"field-day-relative+0": "oggi",
+	"field-hour": "ora",
+	"field-day-relative+1": "domani",
+	"dateFormat-long": "dd MMMM y G",
+	"field-day-relative+2": "dopodomani",
+	"field-day": "giorno",
+	"field-month-relative+0": "Questo mese",
+	"field-month-relative+1": "Mese prossimo",
+	"field-dayperiod": "periodo del giorno",
+	"field-month": "mese",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"field-era": "era",
+	"field-year-relative+0": "Questo anno",
+	"field-year-relative+1": "Anno prossimo",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"field-weekday": "giorno della settimana",
+	"field-zone": "zona"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/number.js b/dojo/cldr/nls/it/number.js
index 370261f..2c4456d 100644
--- a/dojo/cldr/nls/it/number.js
+++ b/dojo/cldr/nls/it/number.js
@@ -1,12 +1,22 @@
 define(
 //begin v1.x content
 {
-	"decimalFormat": "#,##0.###",
 	"group": ".",
+	"percentSign": "%",
+	"exponential": "E",
 	"scientificFormat": "#E0",
 	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
 	"currencyFormat": "¤ #,##0.00",
-	"decimal": ","
+	"plusSign": "+",
+	"decimalFormat-long": "000 bilioni",
+	"decimalFormat-short": "000 Bln"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/roc.js b/dojo/cldr/nls/it/roc.js
new file mode 100644
index 0000000..9ca35b9
--- /dev/null
+++ b/dojo/cldr/nls/it/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "secondo",
+	"field-year-relative+-1": "Anno scorso",
+	"field-week": "settimana",
+	"field-month-relative+-1": "Mese scorso",
+	"field-day-relative+-1": "ieri",
+	"field-day-relative+-2": "l'altro ieri",
+	"field-year": "anno",
+	"field-week-relative+0": "Questa settimana",
+	"field-week-relative+1": "Settimana prossima",
+	"field-minute": "minuto",
+	"field-week-relative+-1": "Settimana scorsa",
+	"field-day-relative+0": "oggi",
+	"field-hour": "ora",
+	"field-day-relative+1": "domani",
+	"field-day-relative+2": "dopodomani",
+	"field-day": "giorno",
+	"field-month-relative+0": "Questo mese",
+	"field-month-relative+1": "Mese prossimo",
+	"field-dayperiod": "periodo del giorno",
+	"field-month": "mese",
+	"field-era": "era",
+	"field-year-relative+0": "Questo anno",
+	"field-year-relative+1": "Anno prossimo",
+	"eraAbbr": [
+		"Prima della R.O.C.",
+		"Minguo"
+	],
+	"field-weekday": "giorno della settimana",
+	"field-zone": "zona"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/buddhist.js b/dojo/cldr/nls/ja/buddhist.js
new file mode 100644
index 0000000..0cb4a0f
--- /dev/null
+++ b/dojo/cldr/nls/ja/buddhist.js
@@ -0,0 +1,155 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"field-weekday": "曜日",
+	"dateFormatItem-GyMd": "GGGGy年M月d日",
+	"dateFormatItem-GyMMMEd": "GGGGy年M月d日(E)",
+	"dateFormatItem-MMMEd": "M月d日(E)",
+	"days-format-short": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"dateFormat-long": "GGGGy年M月d日",
+	"months-format-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"dateFormatItem-yyyyQQQ": "GGGGy QQQ",
+	"dayPeriods-format-wide-pm": "午後",
+	"dateFormat-full": "GGGGy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGy年M/d(E)",
+	"dateFormatItem-Md": "M/d",
+	"field-era": "時代",
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"第1四半期",
+		"第2四半期",
+		"第3四半期",
+		"第4四半期"
+	],
+	"dateFormatItem-MEEEEd": "M/dEEEE",
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "年",
+	"field-hour": "時",
+	"timeFormat-full": "H時mm分ss秒 zzzz",
+	"field-day-relative+0": "今日",
+	"field-day-relative+1": "明日",
+	"dateFormatItem-GyMMMd": "GGGGy年M月d日",
+	"field-day-relative+2": "明後日",
+	"dateFormatItem-H": "H時",
+	"quarters-format-abbr": [
+		"1Q",
+		"2Q",
+		"3Q",
+		"4Q"
+	],
+	"dateFormatItem-Gy": "GGGGy年",
+	"dateFormatItem-yyyyMMMEd": "GGGGy年M月d日(E)",
+	"dateFormatItem-M": "M月",
+	"dateFormatItem-yyyyMMM": "GGGGy年M月",
+	"dateFormatItem-yyyyMMMd": "GGGGy年M月d日",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"eraAbbr": [
+		"BE"
+	],
+	"field-minute": "分",
+	"field-dayperiod": "午前/午後",
+	"dateFormatItem-d": "d日",
+	"dateFormatItem-yyyyMEEEEd": "GGGGy年M/dEEEE",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "昨日",
+	"dateFormatItem-h": "aK時",
+	"field-day-relative+-2": "一昨日",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-EEEEd": "d日EEEE",
+	"dateFormatItem-MEd": "M/d(E)",
+	"field-day": "日",
+	"days-format-wide": [
+		"日曜日",
+		"月曜日",
+		"火曜日",
+		"水曜日",
+		"木曜日",
+		"金曜日",
+		"土曜日"
+	],
+	"field-zone": "タイムゾーン",
+	"dateFormatItem-yyyyMM": "Gy/MM",
+	"dateFormatItem-y": "GGGGy年",
+	"field-year-relative+-1": "昨年",
+	"field-month-relative+-1": "先月",
+	"dateFormatItem-hm": "aK:mm",
+	"dateFormatItem-GyMMMEEEEd": "GGGGy年M月d日EEEE",
+	"days-format-abbr": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"eraNames": [
+		"仏暦"
+	],
+	"dateFormatItem-yyyyMMMEEEEd": "GGGGy年M月d日EEEE",
+	"dateFormatItem-MMMEEEEd": "M月d日EEEE",
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"dateFormatItem-MMM": "M月",
+	"dayPeriods-format-wide-am": "午前",
+	"dateFormat-short": "Gy/MM/dd",
+	"field-second": "秒",
+	"field-month-relative+0": "今月",
+	"field-month-relative+1": "翌月",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-week": "週",
+	"dateFormat-medium": "Gy/MM/dd",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "先週",
+	"dateFormatItem-yyyyM": "GGGGy年M月",
+	"field-year-relative+1": "翌年",
+	"dateFormatItem-yyyyQQQQ": "GGGGy第Q四半期",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "aK:mm:ss",
+	"dateFormatItem-GyMMM": "GGGGy年M月",
+	"dateFormatItem-yyyy": "GGGGy年",
+	"field-week-relative+0": "今週",
+	"field-week-relative+1": "翌週"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/chinese.js b/dojo/cldr/nls/ja/chinese.js
new file mode 100644
index 0000000..1286c5d
--- /dev/null
+++ b/dojo/cldr/nls/ja/chinese.js
@@ -0,0 +1,111 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "U年MMMd日(E)",
+	"field-dayperiod": "午前/午後",
+	"field-minute": "分",
+	"dateFormatItem-MMMEd": "MMMd日(E)",
+	"field-day-relative+-1": "昨日",
+	"dateFormatItem-hms": "aK:mm:ss",
+	"field-day-relative+-2": "一昨日",
+	"field-weekday": "曜日",
+	"months-standAlone-narrow": [
+		"正",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六",
+		"七",
+		"八",
+		"九",
+		"十",
+		"十一",
+		"十二"
+	],
+	"dateFormatItem-Gy": "U年",
+	"field-era": "時代",
+	"field-hour": "時",
+	"dateFormatItem-y": "U年",
+	"dateFormatItem-yyyy": "U年",
+	"dateFormatItem-yyyyMMMEEEEd": "U年MMMd日EEEE",
+	"dateFormatItem-EEEEd": "d日EEEE",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-day-relative+0": "今日",
+	"field-day-relative+1": "明日",
+	"field-day-relative+2": "明後日",
+	"dateFormatItem-GyMMMd": "U年MMMd日",
+	"dateFormat-long": "U年MMMd日",
+	"field-zone": "タイムゾーン",
+	"dateFormatItem-Hm": "H:mm",
+	"dateFormatItem-MMMEEEEd": "MMMd日EEEE",
+	"field-week-relative+-1": "先週",
+	"dateFormat-medium": "U年MMMd日",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "翌年",
+	"dateFormatItem-yMd": "U年M月d日",
+	"field-year-relative+-1": "昨年",
+	"dateFormatItem-yyyyQQQQ": "UQQQQ",
+	"field-year": "年",
+	"dateFormatItem-GyMMMEEEEd": "U年MMMd日EEEE",
+	"field-week": "週",
+	"dateFormatItem-yyyyMd": "U年M月d日",
+	"dateFormatItem-yyyyMMMd": "U年MMMd日",
+	"dateFormatItem-yyyyMEd": "U年M月d日(E)",
+	"dateFormatItem-yyyyMEEEEd": "U年M月d日EEEE",
+	"dateFormatItem-MMMd": "MMMd日",
+	"field-week-relative+0": "今週",
+	"field-week-relative+1": "翌週",
+	"field-month-relative+0": "今月",
+	"dateFormatItem-H": "H時",
+	"field-month": "月",
+	"field-month-relative+1": "翌月",
+	"dateFormatItem-M": "MMM",
+	"field-second": "秒",
+	"dateFormatItem-GyMMMEd": "U年MMMd日(E)",
+	"dateFormatItem-GyMMM": "U年MMM",
+	"dateFormatItem-MEEEEd": "M/dEEEE",
+	"field-day": "日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateFormatItem-yyyyQQQ": "U/QQQ",
+	"months-format-narrow": [
+		"正",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六",
+		"七",
+		"八",
+		"九",
+		"十",
+		"十一",
+		"十二"
+	],
+	"dateFormatItem-hm": "aK:mm",
+	"dateFormat-short": "U-M-d",
+	"dateFormatItem-yyyyM": "U年M月",
+	"dateFormat-full": "U年MMMd日EEEE",
+	"dateFormatItem-Md": "M/d",
+	"months-format-wide": [
+		"正月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"dateFormatItem-yyyyMMM": "U年MMM",
+	"dateFormatItem-d": "d日",
+	"field-month-relative+-1": "先月",
+	"dateFormatItem-h": "aK時"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/coptic.js b/dojo/cldr/nls/ja/coptic.js
new file mode 100644
index 0000000..bce05b2
--- /dev/null
+++ b/dojo/cldr/nls/ja/coptic.js
@@ -0,0 +1,121 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒",
+	"field-year-relative+-1": "昨年",
+	"field-week": "週",
+	"field-month-relative+-1": "先月",
+	"field-day-relative+-1": "昨日",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "一昨日",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"months-standAlone-wide": [
+		"トウト",
+		"ババ",
+		"ハトール",
+		"キアック",
+		"トーバ",
+		"アムシール",
+		"バラムハート",
+		"バラモウダ",
+		"バシャンス",
+		"パオーナ",
+		"エペープ",
+		"メスラ",
+		"ナシエ"
+	],
+	"field-year": "年",
+	"field-week-relative+0": "今週",
+	"months-standAlone-abbr": [
+		"トウト",
+		"ババ",
+		"ハトール",
+		"キアック",
+		"トーバ",
+		"アムシール",
+		"バラムハート",
+		"バラモウダ",
+		"バシャンス",
+		"パオーナ",
+		"エペープ",
+		"メスラ",
+		"ナシエ"
+	],
+	"field-week-relative+1": "翌週",
+	"field-minute": "分",
+	"field-week-relative+-1": "先週",
+	"field-day-relative+0": "今日",
+	"field-hour": "時",
+	"field-day-relative+1": "明日",
+	"field-day-relative+2": "明後日",
+	"field-day": "日",
+	"field-month-relative+0": "今月",
+	"field-month-relative+1": "翌月",
+	"field-dayperiod": "午前/午後",
+	"field-month": "月",
+	"months-format-wide": [
+		"トウト",
+		"ババ",
+		"ハトール",
+		"キアック",
+		"トーバ",
+		"アムシール",
+		"バラムハート",
+		"バラモウダ",
+		"バシャンス",
+		"パオーナ",
+		"エペープ",
+		"メスラ",
+		"ナシエ"
+	],
+	"field-era": "時代",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "翌年",
+	"months-format-abbr": [
+		"トウト",
+		"ババ",
+		"ハトール",
+		"キアック",
+		"トーバ",
+		"アムシール",
+		"バラムハート",
+		"バラモウダ",
+		"バシャンス",
+		"パオーナ",
+		"エペープ",
+		"メスラ",
+		"ナシエ"
+	],
+	"field-weekday": "曜日",
+	"field-zone": "タイムゾーン"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/currency.js b/dojo/cldr/nls/ja/currency.js
index 4955625..757b5cb 100644
--- a/dojo/cldr/nls/ja/currency.js
+++ b/dojo/cldr/nls/ja/currency.js
@@ -5,13 +5,18 @@ define(
 	"CHF_displayName": "スイス フラン",
 	"JPY_symbol": "¥",
 	"CAD_displayName": "カナダ ドル",
+	"HKD_symbol": "HK$",
 	"CNY_displayName": "中国人民元",
 	"USD_symbol": "$",
 	"AUD_displayName": "オーストラリア ドル",
 	"JPY_displayName": "日本円",
+	"CAD_symbol": "CA$",
 	"USD_displayName": "米ドル",
+	"EUR_symbol": "€",
 	"CNY_symbol": "元",
 	"GBP_displayName": "英国ポンド",
+	"GBP_symbol": "£",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "ユーロ"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/ja/ethiopic.js b/dojo/cldr/nls/ja/ethiopic.js
new file mode 100644
index 0000000..be0caa5
--- /dev/null
+++ b/dojo/cldr/nls/ja/ethiopic.js
@@ -0,0 +1,121 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒",
+	"field-year-relative+-1": "昨年",
+	"field-week": "週",
+	"field-month-relative+-1": "先月",
+	"field-day-relative+-1": "昨日",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "一昨日",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"months-standAlone-wide": [
+		"メスケレム",
+		"テケムト",
+		"ヘダル",
+		"ターサス",
+		"テル",
+		"イェカティト",
+		"メガビト",
+		"ミアジア",
+		"ゲンボト",
+		"セネ",
+		"ハムレ",
+		"ネハッセ",
+		"パグメン"
+	],
+	"field-year": "年",
+	"field-week-relative+0": "今週",
+	"months-standAlone-abbr": [
+		"メスケレム",
+		"テケムト",
+		"ヘダル",
+		"ターサス",
+		"テル",
+		"イェカティト",
+		"メガビト",
+		"ミアジア",
+		"ゲンボト",
+		"セネ",
+		"ハムレ",
+		"ネハッセ",
+		"パグメン"
+	],
+	"field-week-relative+1": "翌週",
+	"field-minute": "分",
+	"field-week-relative+-1": "先週",
+	"field-day-relative+0": "今日",
+	"field-hour": "時",
+	"field-day-relative+1": "明日",
+	"field-day-relative+2": "明後日",
+	"field-day": "日",
+	"field-month-relative+0": "今月",
+	"field-month-relative+1": "翌月",
+	"field-dayperiod": "午前/午後",
+	"field-month": "月",
+	"months-format-wide": [
+		"メスケレム",
+		"テケムト",
+		"ヘダル",
+		"ターサス",
+		"テル",
+		"イェカティト",
+		"メガビト",
+		"ミアジア",
+		"ゲンボト",
+		"セネ",
+		"ハムレ",
+		"ネハッセ",
+		"パグメン"
+	],
+	"field-era": "時代",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "翌年",
+	"months-format-abbr": [
+		"メスケレム",
+		"テケムト",
+		"ヘダル",
+		"ターサス",
+		"テル",
+		"イェカティト",
+		"メガビト",
+		"ミアジア",
+		"ゲンボト",
+		"セネ",
+		"ハムレ",
+		"ネハッセ",
+		"パグメン"
+	],
+	"field-weekday": "曜日",
+	"field-zone": "タイムゾーン"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/generic.js b/dojo/cldr/nls/ja/generic.js
new file mode 100644
index 0000000..e5038cf
--- /dev/null
+++ b/dojo/cldr/nls/ja/generic.js
@@ -0,0 +1,74 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日(E)",
+	"field-dayperiod": "午前/午後",
+	"field-minute": "分",
+	"dateFormatItem-MMMEd": "M月d日(E)",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "昨日",
+	"dateFormatItem-hms": "aK:mm:ss",
+	"field-day-relative+-2": "一昨日",
+	"field-weekday": "曜日",
+	"dateFormatItem-MMM": "M月",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "Gy年",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "時代",
+	"field-hour": "時",
+	"dateFormatItem-y": "Gy年",
+	"dateFormatItem-yyyy": "Gy年",
+	"dateFormatItem-yyyyMMMEEEEd": "Gy年M月d日EEEE",
+	"dateFormatItem-EEEEd": "d日EEEE",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-day-relative+0": "今日",
+	"field-day-relative+1": "明日",
+	"field-day-relative+2": "明後日",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"dateFormat-long": "Gy年M月d日",
+	"field-zone": "タイムゾーン",
+	"dateFormatItem-Hm": "H:mm",
+	"dateFormatItem-MMMEEEEd": "M月d日EEEE",
+	"field-week-relative+-1": "先週",
+	"dateFormat-medium": "Gy/MM/dd",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "翌年",
+	"field-year-relative+-1": "昨年",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "GyQQQQ",
+	"field-year": "年",
+	"dateFormatItem-GyMMMEEEEd": "Gy年M月d日EEEE",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "週",
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"dateFormatItem-yyyyMEd": "Gy/M/d(E)",
+	"dateFormatItem-yyyyMEEEEd": "Gy/M/dEEEE",
+	"dateFormatItem-MMMd": "M月d日",
+	"field-week-relative+0": "今週",
+	"field-week-relative+1": "翌週",
+	"field-month-relative+0": "今月",
+	"dateFormatItem-H": "H時",
+	"field-month": "月",
+	"field-month-relative+1": "翌月",
+	"dateFormatItem-M": "M月",
+	"field-second": "秒",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日(E)",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-MEEEEd": "M/dEEEE",
+	"field-day": "日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateFormatItem-yyyyQQQ": "Gy/QQQ",
+	"dateFormatItem-hm": "aK:mm",
+	"dateFormat-short": "Gy/MM/dd",
+	"dateFormatItem-yyyyM": "Gy/M",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-Md": "M/d",
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-d": "d日",
+	"field-month-relative+-1": "先月",
+	"dateFormatItem-h": "aK時"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/gregorian.js b/dojo/cldr/nls/ja/gregorian.js
index 241c82b..f27e6dd 100644
--- a/dojo/cldr/nls/ja/gregorian.js
+++ b/dojo/cldr/nls/ja/gregorian.js
@@ -1,14 +1,40 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "曜日",
-	"dateFormatItem-yQQQ": "yQQQ",
-	"dateFormatItem-yMEd": "y/M/d(EEE)",
+	"dateFormatItem-yQQQ": "y/QQQ",
+	"dateFormatItem-yMEd": "y/M/d(E)",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日(E)",
 	"dateFormatItem-MMMEd": "M月d日(E)",
 	"eraNarrow": [
 		"BC",
 		"AD"
 	],
+	"dateFormatItem-yMM": "y/MM",
+	"days-format-short": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
 	"dateFormat-long": "y年M月d日",
 	"months-format-wide": [
 		"1月",
@@ -28,6 +54,7 @@ define(
 	"dayPeriods-format-wide-pm": "午後",
 	"dateFormat-full": "y年M月d日EEEE",
 	"dateFormatItem-Md": "M/d",
+	"dayPeriods-format-wide-noon": "正午",
 	"dateFormatItem-yMd": "y/M/d",
 	"field-era": "時代",
 	"dateFormatItem-yM": "y/M",
@@ -52,12 +79,12 @@ define(
 		"第3四半期",
 		"第4四半期"
 	],
+	"dateFormatItem-MEEEEd": "M/dEEEE",
+	"dateFormatItem-yQQQQ": "yQQQQ",
 	"timeFormat-long": "H:mm:ss z",
 	"field-year": "年",
 	"dateFormatItem-yMMM": "y年M月",
-	"dateFormatItem-yQ": "y/Q",
 	"field-hour": "時",
-	"dateFormatItem-MMdd": "MM/dd",
 	"months-format-abbr": [
 		"1月",
 		"2月",
@@ -72,13 +99,13 @@ define(
 		"11月",
 		"12月"
 	],
-	"dateFormatItem-yyQ": "yy/Q",
+	"dateFormatItem-yMEEEEd": "y/M/dEEEE",
 	"timeFormat-full": "H時mm分ss秒 zzzz",
 	"field-day-relative+0": "今日",
 	"field-day-relative+1": "明日",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
 	"field-day-relative+2": "明後日",
 	"dateFormatItem-H": "H時",
-	"field-day-relative+3": "3日後",
 	"months-standAlone-abbr": [
 		"1月",
 		"2月",
@@ -94,10 +121,10 @@ define(
 		"12月"
 	],
 	"quarters-format-abbr": [
-		"Q1",
-		"Q2",
-		"Q3",
-		"Q4"
+		"1Q",
+		"2Q",
+		"3Q",
+		"4Q"
 	],
 	"quarters-standAlone-wide": [
 		"第1四半期",
@@ -105,6 +132,7 @@ define(
 		"第3四半期",
 		"第4四半期"
 	],
+	"dateFormatItem-Gy": "Gy年",
 	"dateFormatItem-M": "M月",
 	"days-standAlone-wide": [
 		"日曜日",
@@ -115,12 +143,18 @@ define(
 		"金曜日",
 		"土曜日"
 	],
-	"dateFormatItem-yyMMM": "y年M月",
+	"dateFormatItem-yMMMEEEEd": "y年M月d日EEEE",
 	"timeFormat-medium": "H:mm:ss",
 	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
 	"eraAbbr": [
-		"BC",
-		"AD"
+		"紀元前",
+		"西暦"
 	],
 	"field-minute": "分",
 	"field-dayperiod": "午前/午後",
@@ -135,14 +169,20 @@ define(
 	],
 	"dateFormatItem-d": "d日",
 	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "昨日",
-	"dateFormatItem-h": "ah時",
-	"dateTimeFormat-long": "{1}{0}",
+	"dateFormatItem-h": "aK時",
+	"dateTimeFormat-long": "{1} {0}",
 	"field-day-relative+-2": "一昨日",
-	"field-day-relative+-3": "3日前",
 	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-EEEEd": "d日EEEE",
 	"dateFormatItem-MEd": "M/d(E)",
-	"dateTimeFormat-full": "{1}{0}",
+	"dateTimeFormat-full": "{1} {0}",
 	"field-day": "日",
 	"days-format-wide": [
 		"日曜日",
@@ -154,7 +194,6 @@ define(
 		"土曜日"
 	],
 	"field-zone": "タイムゾーン",
-	"dateFormatItem-yyyyMM": "yyyy/MM",
 	"dateFormatItem-y": "y年",
 	"months-standAlone-narrow": [
 		"1",
@@ -170,8 +209,10 @@ define(
 		"11",
 		"12"
 	],
-	"dateFormatItem-hm": "ah:mm",
-	"dateFormatItem-GGGGyMd": "GGGGy年M月d日",
+	"field-year-relative+-1": "昨年",
+	"field-month-relative+-1": "先月",
+	"dateFormatItem-hm": "aK:mm",
+	"dateFormatItem-GyMMMEEEEd": "Gy年M月d日EEEE",
 	"days-format-abbr": [
 		"日",
 		"月",
@@ -195,6 +236,7 @@ define(
 		"金",
 		"土"
 	],
+	"dateFormatItem-MMMEEEEd": "M月d日EEEE",
 	"field-month": "月",
 	"days-standAlone-narrow": [
 		"日",
@@ -205,18 +247,25 @@ define(
 		"金",
 		"土"
 	],
-	"dateFormatItem-MMM": "LLL",
+	"dateFormatItem-MMM": "M月",
 	"dayPeriods-format-wide-am": "午前",
-	"dateFormat-short": "yy/MM/dd",
+	"dateFormat-short": "y/MM/dd",
 	"field-second": "秒",
-	"dateFormatItem-yMMMEd": "y年M月d日(EEE)",
-	"dateFormatItem-Ed": "d日(EEE)",
+	"dateFormatItem-yMMMEd": "y年M月d日(E)",
+	"field-month-relative+0": "今月",
+	"field-month-relative+1": "翌月",
+	"dateFormatItem-Ed": "d日(E)",
 	"field-week": "週",
-	"dateFormat-medium": "yyyy/MM/dd",
+	"dateFormat-medium": "y/MM/dd",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "先週",
+	"field-year-relative+1": "翌年",
 	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "H:mm:ss",
-	"dateFormatItem-hms": "ah:mm:ss",
-	"dateFormatItem-yyyy": "y年"
+	"dateFormatItem-hms": "aK:mm:ss",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"field-week-relative+0": "今週",
+	"field-week-relative+1": "翌週"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/hebrew.js b/dojo/cldr/nls/ja/hebrew.js
new file mode 100644
index 0000000..32c65a1
--- /dev/null
+++ b/dojo/cldr/nls/ja/hebrew.js
@@ -0,0 +1,225 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-weekday": "曜日",
+	"months-standAlone-narrow-leap": "7",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日(E)",
+	"dateFormatItem-MMMEd": "M月d日(E)",
+	"days-format-short": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"dateFormat-long": "Gy年M月d日",
+	"months-format-wide": [
+		"ティスレ",
+		"へシボン",
+		"キスレブ",
+		"テベット",
+		"シバット",
+		"アダル I",
+		"アダル",
+		"ニサン",
+		"イヤル",
+		"シバン",
+		"タムズ",
+		"アヴ",
+		"エルル"
+	],
+	"dateFormatItem-yyyyQQQ": "Gy/QQQ",
+	"dayPeriods-format-wide-pm": "午後",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "Gy/M/d(E)",
+	"dateFormatItem-Md": "M/d",
+	"field-era": "時代",
+	"months-standAlone-wide": [
+		"ティスレ",
+		"へシボン",
+		"キスレブ",
+		"テベット",
+		"シバット",
+		"アダル I",
+		"アダル",
+		"ニサン",
+		"イヤル",
+		"シバン",
+		"タムズ",
+		"アヴ",
+		"エルル"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"第1四半期",
+		"第2四半期",
+		"第3四半期",
+		"第4四半期"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "年",
+	"field-hour": "時",
+	"months-format-abbr-leap": "アダル II",
+	"months-format-abbr": [
+		"ティスレ",
+		"へシボン",
+		"キスレブ",
+		"テベット",
+		"シバット",
+		"アダル I",
+		"アダル",
+		"ニサン",
+		"イヤル",
+		"シバン",
+		"タムズ",
+		"アヴ",
+		"エルル"
+	],
+	"timeFormat-full": "H時mm分ss秒 zzzz",
+	"field-day-relative+0": "今日",
+	"field-day-relative+1": "明日",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-day-relative+2": "明後日",
+	"dateFormatItem-H": "H時",
+	"months-standAlone-abbr": [
+		"ティスレ",
+		"へシボン",
+		"キスレブ",
+		"テベット",
+		"シバット",
+		"アダル I",
+		"アダル",
+		"ニサン",
+		"イヤル",
+		"シバン",
+		"タムズ",
+		"アヴ",
+		"エルル"
+	],
+	"quarters-format-abbr": [
+		"1Q",
+		"2Q",
+		"3Q",
+		"4Q"
+	],
+	"dateFormatItem-Gy": "Gy年",
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日(E)",
+	"dateFormatItem-M": "M月",
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"months-standAlone-wide-leap": "アダル II",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"months-format-narrow-leap": "7",
+	"eraAbbr": [
+		"AM"
+	],
+	"field-minute": "分",
+	"field-dayperiod": "午前/午後",
+	"dateFormatItem-d": "d日",
+	"field-day-relative+-1": "昨日",
+	"dateFormatItem-h": "aK時",
+	"field-day-relative+-2": "一昨日",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"field-day": "日",
+	"days-format-wide": [
+		"日曜日",
+		"月曜日",
+		"火曜日",
+		"水曜日",
+		"木曜日",
+		"金曜日",
+		"土曜日"
+	],
+	"field-zone": "タイムゾーン",
+	"months-standAlone-abbr-leap": "アダル II",
+	"dateFormatItem-y": "Gy年",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-year-relative+-1": "昨年",
+	"field-month-relative+-1": "先月",
+	"dateFormatItem-hm": "aK:mm",
+	"days-format-abbr": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"dateFormatItem-MMM": "M月",
+	"dayPeriods-format-wide-am": "午前",
+	"dateFormat-short": "Gy/MM/dd",
+	"field-second": "秒",
+	"field-month-relative+0": "今月",
+	"field-month-relative+1": "翌月",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-week": "週",
+	"dateFormat-medium": "Gy/MM/dd",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "先週",
+	"dateFormatItem-yyyyM": "Gy/M",
+	"field-year-relative+1": "翌年",
+	"dateFormatItem-yyyyQQQQ": "GyQQQQ",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "aK:mm:ss",
+	"months-format-wide-leap": "アダル II",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-yyyy": "Gy年",
+	"field-week-relative+0": "今週",
+	"field-week-relative+1": "翌週"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/indian.js b/dojo/cldr/nls/ja/indian.js
new file mode 100644
index 0000000..adf94be
--- /dev/null
+++ b/dojo/cldr/nls/ja/indian.js
@@ -0,0 +1,118 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒",
+	"field-year-relative+-1": "昨年",
+	"field-week": "週",
+	"field-month-relative+-1": "先月",
+	"field-day-relative+-1": "昨日",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "一昨日",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"months-standAlone-wide": [
+		"カイトラ",
+		"ヴァイサカ",
+		"ジャイスタ",
+		"アーサダ",
+		"スラバナ",
+		"バードラ",
+		"アスビナ",
+		"カルディカ",
+		"アヴラハヤナ",
+		"パウサ",
+		"マーガ",
+		"パルグナ"
+	],
+	"field-year": "年",
+	"field-week-relative+0": "今週",
+	"months-standAlone-abbr": [
+		"カイトラ",
+		"ヴァイサカ",
+		"ジャイスタ",
+		"アーサダ",
+		"スラバナ",
+		"バードラ",
+		"アスビナ",
+		"カルディカ",
+		"アヴラハヤナ",
+		"パウサ",
+		"マーガ",
+		"パルグナ"
+	],
+	"field-week-relative+1": "翌週",
+	"field-minute": "分",
+	"field-week-relative+-1": "先週",
+	"field-day-relative+0": "今日",
+	"field-hour": "時",
+	"field-day-relative+1": "明日",
+	"field-day-relative+2": "明後日",
+	"field-day": "日",
+	"field-month-relative+0": "今月",
+	"field-month-relative+1": "翌月",
+	"field-dayperiod": "午前/午後",
+	"field-month": "月",
+	"months-format-wide": [
+		"カイトラ",
+		"ヴァイサカ",
+		"ジャイスタ",
+		"アーサダ",
+		"スラバナ",
+		"バードラ",
+		"アスビナ",
+		"カルディカ",
+		"アヴラハヤナ",
+		"パウサ",
+		"マーガ",
+		"パルグナ"
+	],
+	"field-era": "時代",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "翌年",
+	"months-format-abbr": [
+		"カイトラ",
+		"ヴァイサカ",
+		"ジャイスタ",
+		"アーサダ",
+		"スラバナ",
+		"バードラ",
+		"アスビナ",
+		"カルディカ",
+		"アヴラハヤナ",
+		"パウサ",
+		"マーガ",
+		"パルグナ"
+	],
+	"eraAbbr": [
+		"サカ"
+	],
+	"field-weekday": "曜日",
+	"field-zone": "タイムゾーン"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/islamic.js b/dojo/cldr/nls/ja/islamic.js
new file mode 100644
index 0000000..df42d71
--- /dev/null
+++ b/dojo/cldr/nls/ja/islamic.js
@@ -0,0 +1,213 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "曜日",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日(E)",
+	"dateFormatItem-MMMEd": "M月d日(E)",
+	"days-format-short": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"dateFormat-long": "Gy年M月d日",
+	"months-format-wide": [
+		"ムハッラム",
+		"サフアル",
+		"ラビー・ウル・アウワル",
+		"ラビー・ウッ・サーニー",
+		"ジュマーダル・アウワル",
+		"ジュマーダッサーニー",
+		"ラジャブ",
+		"シャアバーン",
+		"ラマダーン",
+		"シャウワール",
+		"ズル・カイダ",
+		"ズル・ヒッジャ"
+	],
+	"dateFormatItem-yyyyQQQ": "Gy/QQQ",
+	"dayPeriods-format-wide-pm": "午後",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "Gy/M/d(E)",
+	"dateFormatItem-Md": "M/d",
+	"field-era": "時代",
+	"months-standAlone-wide": [
+		"ムハッラム",
+		"サフアル",
+		"ラビー・ウル・アウワル",
+		"ラビー・ウッ・サーニー",
+		"ジュマーダル・アウワル",
+		"ジュマーダッサーニー",
+		"ラジャブ",
+		"シャアバーン",
+		"ラマダーン",
+		"シャウワール",
+		"ズル・カイダ",
+		"ズル・ヒッジャ"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"第1四半期",
+		"第2四半期",
+		"第3四半期",
+		"第4四半期"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "年",
+	"field-hour": "時",
+	"months-format-abbr": [
+		"ムハッラム",
+		"サフアル",
+		"ラビー・ウル・アウワル",
+		"ラビー・ウッ・サーニー",
+		"ジュマーダル・アウワル",
+		"ジュマーダッサーニー",
+		"ラジャブ",
+		"シャアバーン",
+		"ラマダーン",
+		"シャウワール",
+		"ズル・カイダ",
+		"ズル・ヒッジャ"
+	],
+	"timeFormat-full": "H時mm分ss秒 zzzz",
+	"field-day-relative+0": "今日",
+	"field-day-relative+1": "明日",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-day-relative+2": "明後日",
+	"dateFormatItem-H": "H時",
+	"months-standAlone-abbr": [
+		"ムハッラム",
+		"サフアル",
+		"ラビー・ウル・アウワル",
+		"ラビー・ウッ・サーニー",
+		"ジュマーダル・アウワル",
+		"ジュマーダッサーニー",
+		"ラジャブ",
+		"シャアバーン",
+		"ラマダーン",
+		"シャウワール",
+		"ズル・カイダ",
+		"ズル・ヒッジャ"
+	],
+	"quarters-format-abbr": [
+		"1Q",
+		"2Q",
+		"3Q",
+		"4Q"
+	],
+	"dateFormatItem-Gy": "Gy年",
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日(E)",
+	"dateFormatItem-M": "M月",
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"eraAbbr": [
+		"AH"
+	],
+	"field-minute": "分",
+	"field-dayperiod": "午前/午後",
+	"dateFormatItem-d": "d日",
+	"field-day-relative+-1": "昨日",
+	"dateFormatItem-h": "aK時",
+	"field-day-relative+-2": "一昨日",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"field-day": "日",
+	"days-format-wide": [
+		"日曜日",
+		"月曜日",
+		"火曜日",
+		"水曜日",
+		"木曜日",
+		"金曜日",
+		"土曜日"
+	],
+	"field-zone": "タイムゾーン",
+	"dateFormatItem-y": "Gy年",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year-relative+-1": "昨年",
+	"field-month-relative+-1": "先月",
+	"dateFormatItem-hm": "aK:mm",
+	"days-format-abbr": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"dateFormatItem-MMM": "M月",
+	"dayPeriods-format-wide-am": "午前",
+	"dateFormat-short": "Gy/MM/dd",
+	"field-second": "秒",
+	"field-month-relative+0": "今月",
+	"field-month-relative+1": "翌月",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-week": "週",
+	"dateFormat-medium": "Gy/MM/dd",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "先週",
+	"dateFormatItem-yyyyM": "Gy/M",
+	"field-year-relative+1": "翌年",
+	"dateFormatItem-yyyyQQQQ": "GyQQQQ",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "aK:mm:ss",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-yyyy": "Gy年",
+	"field-week-relative+0": "今週",
+	"field-week-relative+1": "翌週"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/japanese.js b/dojo/cldr/nls/ja/japanese.js
new file mode 100644
index 0000000..a690dc5
--- /dev/null
+++ b/dojo/cldr/nls/ja/japanese.js
@@ -0,0 +1,550 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日(E)",
+	"field-dayperiod": "午前/午後",
+	"field-minute": "分",
+	"dateFormatItem-MMMEd": "M月d日(E)",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "昨日",
+	"dateFormatItem-hms": "aK:mm:ss",
+	"field-day-relative+-2": "一昨日",
+	"field-weekday": "曜日",
+	"dateFormatItem-MMM": "M月",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "Gy年",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "時代",
+	"field-hour": "時",
+	"dateFormatItem-y": "Gy年",
+	"dateFormatItem-yyyy": "Gy年",
+	"dateFormatItem-yyyyMMMEEEEd": "Gy年M月d日EEEE",
+	"dateFormatItem-EEEEd": "d日EEEE",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-day-relative+0": "今日",
+	"field-day-relative+1": "明日",
+	"eraAbbr": [
+		"大化",
+		"白雉",
+		"白鳯",
+		"朱鳥",
+		"大宝",
+		"慶雲",
+		"和銅",
+		"霊亀",
+		"養老",
+		"神亀",
+		"天平",
+		"天平感宝",
+		"天平勝宝",
+		"天平宝字",
+		"天平神護",
+		"神護景雲",
+		"宝亀",
+		"天応",
+		"延暦",
+		"大同",
+		"弘仁",
+		"天長",
+		"承和",
+		"嘉祥",
+		"仁寿",
+		"斉衡",
+		"天安",
+		"貞観",
+		"元慶",
+		"仁和",
+		"寛平",
+		"昌泰",
+		"延喜",
+		"延長",
+		"承平",
+		"天慶",
+		"天暦",
+		"天徳",
+		"応和",
+		"康保",
+		"安和",
+		"天禄",
+		"天延",
+		"貞元",
+		"天元",
+		"永観",
+		"寛和",
+		"永延",
+		"永祚",
+		"正暦",
+		"長徳",
+		"長保",
+		"寛弘",
+		"長和",
+		"寛仁",
+		"治安",
+		"万寿",
+		"長元",
+		"長暦",
+		"長久",
+		"寛徳",
+		"永承",
+		"天喜",
+		"康平",
+		"治暦",
+		"延久",
+		"承保",
+		"承暦",
+		"永保",
+		"応徳",
+		"寛治",
+		"嘉保",
+		"永長",
+		"承徳",
+		"康和",
+		"長治",
+		"嘉承",
+		"天仁",
+		"天永",
+		"永久",
+		"元永",
+		"保安",
+		"天治",
+		"大治",
+		"天承",
+		"長承",
+		"保延",
+		"永治",
+		"康治",
+		"天養",
+		"久安",
+		"仁平",
+		"久寿",
+		"保元",
+		"平治",
+		"永暦",
+		"応保",
+		"長寛",
+		"永万",
+		"仁安",
+		"嘉応",
+		"承安",
+		"安元",
+		"治承",
+		"養和",
+		"寿永",
+		"元暦",
+		"文治",
+		"建久",
+		"正治",
+		"建仁",
+		"元久",
+		"建永",
+		"承元",
+		"建暦",
+		"建保",
+		"承久",
+		"貞応",
+		"元仁",
+		"嘉禄",
+		"安貞",
+		"寛喜",
+		"貞永",
+		"天福",
+		"文暦",
+		"嘉禎",
+		"暦仁",
+		"延応",
+		"仁治",
+		"寛元",
+		"宝治",
+		"建長",
+		"康元",
+		"正嘉",
+		"正元",
+		"文応",
+		"弘長",
+		"文永",
+		"建治",
+		"弘安",
+		"正応",
+		"永仁",
+		"正安",
+		"乾元",
+		"嘉元",
+		"徳治",
+		"延慶",
+		"応長",
+		"正和",
+		"文保",
+		"元応",
+		"元亨",
+		"正中",
+		"嘉暦",
+		"元徳",
+		"元弘",
+		"建武",
+		"延元",
+		"興国",
+		"正平",
+		"建徳",
+		"文中",
+		"天授",
+		"康暦",
+		"弘和",
+		"元中",
+		"至徳",
+		"嘉慶",
+		"康応",
+		"明徳",
+		"応永",
+		"正長",
+		"永享",
+		"嘉吉",
+		"文安",
+		"宝徳",
+		"享徳",
+		"康正",
+		"長禄",
+		"寛正",
+		"文正",
+		"応仁",
+		"文明",
+		"長享",
+		"延徳",
+		"明応",
+		"文亀",
+		"永正",
+		"大永",
+		"享禄",
+		"天文",
+		"弘治",
+		"永禄",
+		"元亀",
+		"天正",
+		"文禄",
+		"慶長",
+		"元和",
+		"寛永",
+		"正保",
+		"慶安",
+		"承応",
+		"明暦",
+		"万治",
+		"寛文",
+		"延宝",
+		"天和",
+		"貞享",
+		"元禄",
+		"宝永",
+		"正徳",
+		"享保",
+		"元文",
+		"寛保",
+		"延享",
+		"寛延",
+		"宝暦",
+		"明和",
+		"安永",
+		"天明",
+		"寛政",
+		"享和",
+		"文化",
+		"文政",
+		"天保",
+		"弘化",
+		"嘉永",
+		"安政",
+		"万延",
+		"文久",
+		"元治",
+		"慶応",
+		"明治",
+		"大正",
+		"昭和",
+		"平成"
+	],
+	"field-day-relative+2": "明後日",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"dateFormatItem-yyyyMM": "Gy/MM",
+	"dateFormat-long": "Gy年M月d日",
+	"field-zone": "タイムゾーン",
+	"dateFormatItem-Hm": "H:mm",
+	"dateFormatItem-MMMEEEEd": "M月d日EEEE",
+	"field-week-relative+-1": "先週",
+	"dateFormat-medium": "Gy年M月d日",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "翌年",
+	"field-year-relative+-1": "昨年",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "GyQQQQ",
+	"field-year": "年",
+	"dateFormatItem-GyMMMEEEEd": "Gy年M月d日EEEE",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "週",
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"dateFormatItem-yyyyMEd": "Gy/M/d(E)",
+	"dateFormatItem-yyyyMEEEEd": "Gy/M/dEEEE",
+	"dateFormatItem-MMMd": "M月d日",
+	"field-week-relative+0": "今週",
+	"field-week-relative+1": "翌週",
+	"field-month-relative+0": "今月",
+	"dateFormatItem-H": "H時",
+	"field-month": "月",
+	"field-month-relative+1": "翌月",
+	"dateFormatItem-M": "M月",
+	"field-second": "秒",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日(E)",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-MEEEEd": "M/dEEEE",
+	"field-day": "日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateFormatItem-yyyyQQQ": "Gy/QQQ",
+	"dateFormatItem-hm": "aK:mm",
+	"dateFormat-short": "Gyy/MM/dd",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-Md": "M/d",
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-d": "d日",
+	"field-month-relative+-1": "先月",
+	"eraNarrow": [
+		"大化",
+		"白雉",
+		"白鳯",
+		"朱鳥",
+		"大宝",
+		"慶雲",
+		"和銅",
+		"霊亀",
+		"養老",
+		"神亀",
+		"天平",
+		"天平感宝",
+		"天平勝宝",
+		"天平宝字",
+		"天平神護",
+		"神護景雲",
+		"宝亀",
+		"天応",
+		"延暦",
+		"大同",
+		"弘仁",
+		"天長",
+		"承和",
+		"嘉祥",
+		"仁寿",
+		"斉衡",
+		"天安",
+		"貞観",
+		"元慶",
+		"仁和",
+		"寛平",
+		"昌泰",
+		"延喜",
+		"延長",
+		"承平",
+		"天慶",
+		"天暦",
+		"天徳",
+		"応和",
+		"康保",
+		"安和",
+		"天禄",
+		"天延",
+		"貞元",
+		"天元",
+		"永観",
+		"寛和",
+		"永延",
+		"永祚",
+		"正暦",
+		"長徳",
+		"長保",
+		"寛弘",
+		"長和",
+		"寛仁",
+		"治安",
+		"万寿",
+		"長元",
+		"長暦",
+		"長久",
+		"寛徳",
+		"永承",
+		"天喜",
+		"康平",
+		"治暦",
+		"延久",
+		"承保",
+		"承暦",
+		"永保",
+		"応徳",
+		"寛治",
+		"嘉保",
+		"永長",
+		"承徳",
+		"康和",
+		"長治",
+		"嘉承",
+		"天仁",
+		"天永",
+		"永久",
+		"元永",
+		"保安",
+		"天治",
+		"大治",
+		"天承",
+		"長承",
+		"保延",
+		"永治",
+		"康治",
+		"天養",
+		"久安",
+		"仁平",
+		"久寿",
+		"保元",
+		"平治",
+		"永暦",
+		"応保",
+		"長寛",
+		"永万",
+		"仁安",
+		"嘉応",
+		"承安",
+		"安元",
+		"治承",
+		"養和",
+		"寿永",
+		"元暦",
+		"文治",
+		"建久",
+		"正治",
+		"建仁",
+		"元久",
+		"建永",
+		"承元",
+		"建暦",
+		"建保",
+		"承久",
+		"貞応",
+		"元仁",
+		"嘉禄",
+		"安貞",
+		"寛喜",
+		"貞永",
+		"天福",
+		"文暦",
+		"嘉禎",
+		"暦仁",
+		"延応",
+		"仁治",
+		"寛元",
+		"宝治",
+		"建長",
+		"康元",
+		"正嘉",
+		"正元",
+		"文応",
+		"弘長",
+		"文永",
+		"建治",
+		"弘安",
+		"正応",
+		"永仁",
+		"正安",
+		"乾元",
+		"嘉元",
+		"徳治",
+		"延慶",
+		"応長",
+		"正和",
+		"文保",
+		"元応",
+		"元亨",
+		"正中",
+		"嘉暦",
+		"元徳",
+		"元弘",
+		"建武",
+		"延元",
+		"興国",
+		"正平",
+		"建徳",
+		"文中",
+		"天授",
+		"康暦",
+		"弘和",
+		"元中",
+		"至徳",
+		"嘉慶",
+		"康応",
+		"明徳",
+		"応永",
+		"正長",
+		"永享",
+		"嘉吉",
+		"文安",
+		"宝徳",
+		"享徳",
+		"康正",
+		"長禄",
+		"寛正",
+		"文正",
+		"応仁",
+		"文明",
+		"長享",
+		"延徳",
+		"明応",
+		"文亀",
+		"永正",
+		"大永",
+		"享禄",
+		"天文",
+		"弘治",
+		"永禄",
+		"元亀",
+		"天正",
+		"文禄",
+		"慶長",
+		"元和",
+		"寛永",
+		"正保",
+		"慶安",
+		"承応",
+		"明暦",
+		"万治",
+		"寛文",
+		"延宝",
+		"天和",
+		"貞享",
+		"元禄",
+		"宝永",
+		"正徳",
+		"享保",
+		"元文",
+		"寛保",
+		"延享",
+		"寛延",
+		"宝暦",
+		"明和",
+		"安永",
+		"天明",
+		"寛政",
+		"享和",
+		"文化",
+		"文政",
+		"天保",
+		"弘化",
+		"嘉永",
+		"安政",
+		"万延",
+		"文久",
+		"元治",
+		"慶応",
+		"明",
+		"大",
+		"昭",
+		"平"
+	],
+	"dateFormatItem-h": "aK時"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/number.js b/dojo/cldr/nls/ja/number.js
index afbe6ca..9678ce6 100644
--- a/dojo/cldr/nls/ja/number.js
+++ b/dojo/cldr/nls/ja/number.js
@@ -1,12 +1,22 @@
 define(
 //begin v1.x content
 {
-	"decimalFormat": "#,##0.###",
 	"group": ",",
+	"percentSign": "%",
+	"exponential": "E",
 	"scientificFormat": "#E0",
 	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"minusSign": "-",
+	"decimal": ".",
+	"nan": "NaN",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
 	"currencyFormat": "¤#,##0.00",
-	"decimal": "."
+	"plusSign": "+",
+	"decimalFormat-long": "000兆",
+	"decimalFormat-short": "000兆"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/persian.js b/dojo/cldr/nls/ja/persian.js
new file mode 100644
index 0000000..88615c3
--- /dev/null
+++ b/dojo/cldr/nls/ja/persian.js
@@ -0,0 +1,213 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "曜日",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日(E)",
+	"dateFormatItem-MMMEd": "M月d日(E)",
+	"days-format-short": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"dateFormat-long": "Gy年M月d日",
+	"months-format-wide": [
+		"ファルヴァルディーン",
+		"オルディーベヘシュト",
+		"ホルダード",
+		"ティール",
+		"モルダード",
+		"シャハリーヴァル",
+		"メフル",
+		"アーバーン",
+		"アーザル",
+		"デイ",
+		"バフマン",
+		"エスファンド"
+	],
+	"dateFormatItem-yyyyQQQ": "Gy/QQQ",
+	"dayPeriods-format-wide-pm": "午後",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "Gy/M/d(E)",
+	"dateFormatItem-Md": "M/d",
+	"field-era": "時代",
+	"months-standAlone-wide": [
+		"ファルヴァルディーン",
+		"オルディーベヘシュト",
+		"ホルダード",
+		"ティール",
+		"モルダード",
+		"シャハリーヴァル",
+		"メフル",
+		"アーバーン",
+		"アーザル",
+		"デイ",
+		"バフマン",
+		"エスファンド"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"第1四半期",
+		"第2四半期",
+		"第3四半期",
+		"第4四半期"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "年",
+	"field-hour": "時",
+	"months-format-abbr": [
+		"ファルヴァルディーン",
+		"オルディーベヘシュト",
+		"ホルダード",
+		"ティール",
+		"モルダード",
+		"シャハリーヴァル",
+		"メフル",
+		"アーバーン",
+		"アーザル",
+		"デイ",
+		"バフマン",
+		"エスファンド"
+	],
+	"timeFormat-full": "H時mm分ss秒 zzzz",
+	"field-day-relative+0": "今日",
+	"field-day-relative+1": "明日",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-day-relative+2": "明後日",
+	"dateFormatItem-H": "H時",
+	"months-standAlone-abbr": [
+		"ファルヴァルディーン",
+		"オルディーベヘシュト",
+		"ホルダード",
+		"ティール",
+		"モルダード",
+		"シャハリーヴァル",
+		"メフル",
+		"アーバーン",
+		"アーザル",
+		"デイ",
+		"バフマン",
+		"エスファンド"
+	],
+	"quarters-format-abbr": [
+		"1Q",
+		"2Q",
+		"3Q",
+		"4Q"
+	],
+	"dateFormatItem-Gy": "Gy年",
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日(E)",
+	"dateFormatItem-M": "M月",
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"eraAbbr": [
+		"AP"
+	],
+	"field-minute": "分",
+	"field-dayperiod": "午前/午後",
+	"dateFormatItem-d": "d日",
+	"field-day-relative+-1": "昨日",
+	"dateFormatItem-h": "aK時",
+	"field-day-relative+-2": "一昨日",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"field-day": "日",
+	"days-format-wide": [
+		"日曜日",
+		"月曜日",
+		"火曜日",
+		"水曜日",
+		"木曜日",
+		"金曜日",
+		"土曜日"
+	],
+	"field-zone": "タイムゾーン",
+	"dateFormatItem-y": "Gy年",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year-relative+-1": "昨年",
+	"field-month-relative+-1": "先月",
+	"dateFormatItem-hm": "aK:mm",
+	"days-format-abbr": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
+		"土"
+	],
+	"dateFormatItem-MMM": "M月",
+	"dayPeriods-format-wide-am": "午前",
+	"dateFormat-short": "Gy/MM/dd",
+	"field-second": "秒",
+	"field-month-relative+0": "今月",
+	"field-month-relative+1": "翌月",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-week": "週",
+	"dateFormat-medium": "Gy/MM/dd",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "先週",
+	"dateFormatItem-yyyyM": "Gy/M",
+	"field-year-relative+1": "翌年",
+	"dateFormatItem-yyyyQQQQ": "GyQQQQ",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "aK:mm:ss",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-yyyy": "Gy年",
+	"field-week-relative+0": "今週",
+	"field-week-relative+1": "翌週"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/roc.js b/dojo/cldr/nls/ja/roc.js
new file mode 100644
index 0000000..9b357ce
--- /dev/null
+++ b/dojo/cldr/nls/ja/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒",
+	"field-year-relative+-1": "昨年",
+	"field-week": "週",
+	"field-month-relative+-1": "先月",
+	"field-day-relative+-1": "昨日",
+	"field-day-relative+-2": "一昨日",
+	"field-year": "年",
+	"field-week-relative+0": "今週",
+	"field-week-relative+1": "翌週",
+	"field-minute": "分",
+	"field-week-relative+-1": "先週",
+	"field-day-relative+0": "今日",
+	"field-hour": "時",
+	"field-day-relative+1": "明日",
+	"field-day-relative+2": "明後日",
+	"field-day": "日",
+	"field-month-relative+0": "今月",
+	"field-month-relative+1": "翌月",
+	"field-dayperiod": "午前/午後",
+	"field-month": "月",
+	"field-era": "時代",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "翌年",
+	"eraAbbr": [
+		"民国前",
+		"民国"
+	],
+	"field-weekday": "曜日",
+	"field-zone": "タイムゾーン"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/japanese.js b/dojo/cldr/nls/japanese.js
new file mode 100644
index 0000000..f949831
--- /dev/null
+++ b/dojo/cldr/nls/japanese.js
@@ -0,0 +1,1149 @@
+define({ root:
+
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
+	"eraNarrow": [
+		"Taika (645-650)",
+		"Hakuchi (650-671)",
+		"Hakuhō (672-686)",
+		"Shuchō (686-701)",
+		"Taihō (701-704)",
+		"Keiun (704-708)",
+		"Wadō (708-715)",
+		"Reiki (715-717)",
+		"Yōrō (717-724)",
+		"Jinki (724-729)",
+		"Tempyō (729-749)",
+		"Tempyō-kampō (749-749)",
+		"Tempyō-shōhō (749-757)",
+		"Tempyō-hōji (757-765)",
+		"Temphō-jingo (765-767)",
+		"Jingo-keiun (767-770)",
+		"Hōki (770-780)",
+		"Ten-ō (781-782)",
+		"Enryaku (782-806)",
+		"Daidō (806-810)",
+		"Kōnin (810-824)",
+		"Tenchō (824-834)",
+		"Jōwa (834-848)",
+		"Kajō (848-851)",
+		"Ninju (851-854)",
+		"Saiko (854-857)",
+		"Tennan (857-859)",
+		"Jōgan (859-877)",
+		"Genkei (877-885)",
+		"Ninna (885-889)",
+		"Kampyō (889-898)",
+		"Shōtai (898-901)",
+		"Engi (901-923)",
+		"Enchō (923-931)",
+		"Shōhei (931-938)",
+		"Tengyō (938-947)",
+		"Tenryaku (947-957)",
+		"Tentoku (957-961)",
+		"Ōwa (961-964)",
+		"Kōhō (964-968)",
+		"Anna (968-970)",
+		"Tenroku (970-973)",
+		"Ten-en (973-976)",
+		"Jōgen (976-978)",
+		"Tengen (978-983)",
+		"Eikan (983-985)",
+		"Kanna (985-987)",
+		"Ei-en (987-989)",
+		"Eiso (989-990)",
+		"Shōryaku (990-995)",
+		"Chōtoku (995-999)",
+		"Chōhō (999-1004)",
+		"Kankō (1004-1012)",
+		"Chōwa (1012-1017)",
+		"Kannin (1017-1021)",
+		"Jian (1021-1024)",
+		"Manju (1024-1028)",
+		"Chōgen (1028-1037)",
+		"Chōryaku (1037-1040)",
+		"Chōkyū (1040-1044)",
+		"Kantoku (1044-1046)",
+		"Eishō (1046-1053)",
+		"Tengi (1053-1058)",
+		"Kōhei (1058-1065)",
+		"Jiryaku (1065-1069)",
+		"Enkyū (1069-1074)",
+		"Shōho (1074-1077)",
+		"Shōryaku (1077-1081)",
+		"Eiho (1081-1084)",
+		"Ōtoku (1084-1087)",
+		"Kanji (1087-1094)",
+		"Kaho (1094-1096)",
+		"Eichō (1096-1097)",
+		"Shōtoku (1097-1099)",
+		"Kōwa (1099-1104)",
+		"Chōji (1104-1106)",
+		"Kashō (1106-1108)",
+		"Tennin (1108-1110)",
+		"Ten-ei (1110-1113)",
+		"Eikyū (1113-1118)",
+		"Gen-ei (1118-1120)",
+		"Hoan (1120-1124)",
+		"Tenji (1124-1126)",
+		"Daiji (1126-1131)",
+		"Tenshō (1131-1132)",
+		"Chōshō (1132-1135)",
+		"Hoen (1135-1141)",
+		"Eiji (1141-1142)",
+		"Kōji (1142-1144)",
+		"Tenyō (1144-1145)",
+		"Kyūan (1145-1151)",
+		"Ninpei (1151-1154)",
+		"Kyūju (1154-1156)",
+		"Hogen (1156-1159)",
+		"Heiji (1159-1160)",
+		"Eiryaku (1160-1161)",
+		"Ōho (1161-1163)",
+		"Chōkan (1163-1165)",
+		"Eiman (1165-1166)",
+		"Nin-an (1166-1169)",
+		"Kaō (1169-1171)",
+		"Shōan (1171-1175)",
+		"Angen (1175-1177)",
+		"Jishō (1177-1181)",
+		"Yōwa (1181-1182)",
+		"Juei (1182-1184)",
+		"Genryuku (1184-1185)",
+		"Bunji (1185-1190)",
+		"Kenkyū (1190-1199)",
+		"Shōji (1199-1201)",
+		"Kennin (1201-1204)",
+		"Genkyū (1204-1206)",
+		"Ken-ei (1206-1207)",
+		"Shōgen (1207-1211)",
+		"Kenryaku (1211-1213)",
+		"Kenpō (1213-1219)",
+		"Shōkyū (1219-1222)",
+		"Jōō (1222-1224)",
+		"Gennin (1224-1225)",
+		"Karoku (1225-1227)",
+		"Antei (1227-1229)",
+		"Kanki (1229-1232)",
+		"Jōei (1232-1233)",
+		"Tempuku (1233-1234)",
+		"Bunryaku (1234-1235)",
+		"Katei (1235-1238)",
+		"Ryakunin (1238-1239)",
+		"En-ō (1239-1240)",
+		"Ninji (1240-1243)",
+		"Kangen (1243-1247)",
+		"Hōji (1247-1249)",
+		"Kenchō (1249-1256)",
+		"Kōgen (1256-1257)",
+		"Shōka (1257-1259)",
+		"Shōgen (1259-1260)",
+		"Bun-ō (1260-1261)",
+		"Kōchō (1261-1264)",
+		"Bun-ei (1264-1275)",
+		"Kenji (1275-1278)",
+		"Kōan (1278-1288)",
+		"Shōō (1288-1293)",
+		"Einin (1293-1299)",
+		"Shōan (1299-1302)",
+		"Kengen (1302-1303)",
+		"Kagen (1303-1306)",
+		"Tokuji (1306-1308)",
+		"Enkei (1308-1311)",
+		"Ōchō (1311-1312)",
+		"Shōwa (1312-1317)",
+		"Bunpō (1317-1319)",
+		"Genō (1319-1321)",
+		"Genkyō (1321-1324)",
+		"Shōchū (1324-1326)",
+		"Kareki (1326-1329)",
+		"Gentoku (1329-1331)",
+		"Genkō (1331-1334)",
+		"Kemmu (1334-1336)",
+		"Engen (1336-1340)",
+		"Kōkoku (1340-1346)",
+		"Shōhei (1346-1370)",
+		"Kentoku (1370-1372)",
+		"Bunchũ (1372-1375)",
+		"Tenju (1375-1379)",
+		"Kōryaku (1379-1381)",
+		"Kōwa (1381-1384)",
+		"Genchũ (1384-1392)",
+		"Meitoku (1384-1387)",
+		"Kakei (1387-1389)",
+		"Kōō (1389-1390)",
+		"Meitoku (1390-1394)",
+		"Ōei (1394-1428)",
+		"Shōchō (1428-1429)",
+		"Eikyō (1429-1441)",
+		"Kakitsu (1441-1444)",
+		"Bun-an (1444-1449)",
+		"Hōtoku (1449-1452)",
+		"Kyōtoku (1452-1455)",
+		"Kōshō (1455-1457)",
+		"Chōroku (1457-1460)",
+		"Kanshō (1460-1466)",
+		"Bunshō (1466-1467)",
+		"Ōnin (1467-1469)",
+		"Bunmei (1469-1487)",
+		"Chōkyō (1487-1489)",
+		"Entoku (1489-1492)",
+		"Meiō (1492-1501)",
+		"Bunki (1501-1504)",
+		"Eishō (1504-1521)",
+		"Taiei (1521-1528)",
+		"Kyōroku (1528-1532)",
+		"Tenmon (1532-1555)",
+		"Kōji (1555-1558)",
+		"Eiroku (1558-1570)",
+		"Genki (1570-1573)",
+		"Tenshō (1573-1592)",
+		"Bunroku (1592-1596)",
+		"Keichō (1596-1615)",
+		"Genwa (1615-1624)",
+		"Kan-ei (1624-1644)",
+		"Shōho (1644-1648)",
+		"Keian (1648-1652)",
+		"Shōō (1652-1655)",
+		"Meiryaku (1655-1658)",
+		"Manji (1658-1661)",
+		"Kanbun (1661-1673)",
+		"Enpō (1673-1681)",
+		"Tenwa (1681-1684)",
+		"Jōkyō (1684-1688)",
+		"Genroku (1688-1704)",
+		"Hōei (1704-1711)",
+		"Shōtoku (1711-1716)",
+		"Kyōhō (1716-1736)",
+		"Genbun (1736-1741)",
+		"Kanpō (1741-1744)",
+		"Enkyō (1744-1748)",
+		"Kan-en (1748-1751)",
+		"Hōryaku (1751-1764)",
+		"Meiwa (1764-1772)",
+		"An-ei (1772-1781)",
+		"Tenmei (1781-1789)",
+		"Kansei (1789-1801)",
+		"Kyōwa (1801-1804)",
+		"Bunka (1804-1818)",
+		"Bunsei (1818-1830)",
+		"Tenpō (1830-1844)",
+		"Kōka (1844-1848)",
+		"Kaei (1848-1854)",
+		"Ansei (1854-1860)",
+		"Man-en (1860-1861)",
+		"Bunkyū (1861-1864)",
+		"Genji (1864-1865)",
+		"Keiō (1865-1868)",
+		"M",
+		"T",
+		"S",
+		"H"
+	],
+	"months-standAlone-wide at localeAlias417": {
+		"bundle": "gregorian",
+		"target": "months-format-wide"
+	},
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "G y MMMM d",
+	"quarters-standAlone-abbr at localeAlias432": {
+		"bundle": "gregorian",
+		"target": "quarters-format-abbr"
+	},
+	"months-format-wide": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"quarters-standAlone-abbr at localeAlias433": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateTime at localeAlias445": {
+		"bundle": "generic",
+		"target": "dateTime"
+	},
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateTimeFormat-medium": "{1} {0}",
+	"quarters-format-abbr at localeAlias430": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"quarters-format-narrow at localeAlias431": {
+		"bundle": "gregorian",
+		"target": "quarters-standAlone-narrow"
+	},
+	"dayPeriods-format-wide-pm": "PM",
+	"dayPeriods-format-abbr at localeAlias436": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"dayPeriods-format-abbr at localeAlias439": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormatItem-Md": "MM-dd",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
+	"months-format-abbr": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"months-standAlone-abbr at localeAlias415": {
+		"bundle": "gregorian",
+		"target": "months-format-abbr"
+	},
+	"months-standAlone-abbr at localeAlias416": {
+		"bundle": "gregorian",
+		"target": "months-format-wide"
+	},
+	"months-format-abbr at localeAlias413": {
+		"bundle": "gregorian",
+		"target": "months-format-wide"
+	},
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
+	"months-standAlone-abbr": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"dateFormatItem-H": "HH",
+	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters at localeAlias429": {
+		"bundle": "gregorian",
+		"target": "quarters"
+	},
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
+	"timeFormat-medium": "HH:mm:ss",
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Hm": "HH:mm",
+	"months-format-narrow at localeAlias414": {
+		"bundle": "gregorian",
+		"target": "months-standAlone-narrow"
+	},
+	"eraAbbr": [
+		"Taika (645-650)",
+		"Hakuchi (650-671)",
+		"Hakuhō (672-686)",
+		"Shuchō (686-701)",
+		"Taihō (701-704)",
+		"Keiun (704-708)",
+		"Wadō (708-715)",
+		"Reiki (715-717)",
+		"Yōrō (717-724)",
+		"Jinki (724-729)",
+		"Tempyō (729-749)",
+		"Tempyō-kampō (749-749)",
+		"Tempyō-shōhō (749-757)",
+		"Tempyō-hōji (757-765)",
+		"Temphō-jingo (765-767)",
+		"Jingo-keiun (767-770)",
+		"Hōki (770-780)",
+		"Ten-ō (781-782)",
+		"Enryaku (782-806)",
+		"Daidō (806-810)",
+		"Kōnin (810-824)",
+		"Tenchō (824-834)",
+		"Jōwa (834-848)",
+		"Kajō (848-851)",
+		"Ninju (851-854)",
+		"Saiko (854-857)",
+		"Tennan (857-859)",
+		"Jōgan (859-877)",
+		"Genkei (877-885)",
+		"Ninna (885-889)",
+		"Kampyō (889-898)",
+		"Shōtai (898-901)",
+		"Engi (901-923)",
+		"Enchō (923-931)",
+		"Shōhei (931-938)",
+		"Tengyō (938-947)",
+		"Tenryaku (947-957)",
+		"Tentoku (957-961)",
+		"Ōwa (961-964)",
+		"Kōhō (964-968)",
+		"Anna (968-970)",
+		"Tenroku (970-973)",
+		"Ten-en (973-976)",
+		"Jōgen (976-978)",
+		"Tengen (978-983)",
+		"Eikan (983-985)",
+		"Kanna (985-987)",
+		"Ei-en (987-989)",
+		"Eiso (989-990)",
+		"Shōryaku (990-995)",
+		"Chōtoku (995-999)",
+		"Chōhō (999-1004)",
+		"Kankō (1004-1012)",
+		"Chōwa (1012-1017)",
+		"Kannin (1017-1021)",
+		"Jian (1021-1024)",
+		"Manju (1024-1028)",
+		"Chōgen (1028-1037)",
+		"Chōryaku (1037-1040)",
+		"Chōkyū (1040-1044)",
+		"Kantoku (1044-1046)",
+		"Eishō (1046-1053)",
+		"Tengi (1053-1058)",
+		"Kōhei (1058-1065)",
+		"Jiryaku (1065-1069)",
+		"Enkyū (1069-1074)",
+		"Shōho (1074-1077)",
+		"Shōryaku (1077-1081)",
+		"Eiho (1081-1084)",
+		"Ōtoku (1084-1087)",
+		"Kanji (1087-1094)",
+		"Kaho (1094-1096)",
+		"Eichō (1096-1097)",
+		"Shōtoku (1097-1099)",
+		"Kōwa (1099-1104)",
+		"Chōji (1104-1106)",
+		"Kashō (1106-1108)",
+		"Tennin (1108-1110)",
+		"Ten-ei (1110-1113)",
+		"Eikyū (1113-1118)",
+		"Gen-ei (1118-1120)",
+		"Hoan (1120-1124)",
+		"Tenji (1124-1126)",
+		"Daiji (1126-1131)",
+		"Tenshō (1131-1132)",
+		"Chōshō (1132-1135)",
+		"Hoen (1135-1141)",
+		"Eiji (1141-1142)",
+		"Kōji (1142-1144)",
+		"Tenyō (1144-1145)",
+		"Kyūan (1145-1151)",
+		"Ninpei (1151-1154)",
+		"Kyūju (1154-1156)",
+		"Hogen (1156-1159)",
+		"Heiji (1159-1160)",
+		"Eiryaku (1160-1161)",
+		"Ōho (1161-1163)",
+		"Chōkan (1163-1165)",
+		"Eiman (1165-1166)",
+		"Nin-an (1166-1169)",
+		"Kaō (1169-1171)",
+		"Shōan (1171-1175)",
+		"Angen (1175-1177)",
+		"Jishō (1177-1181)",
+		"Yōwa (1181-1182)",
+		"Juei (1182-1184)",
+		"Genryuku (1184-1185)",
+		"Bunji (1185-1190)",
+		"Kenkyū (1190-1199)",
+		"Shōji (1199-1201)",
+		"Kennin (1201-1204)",
+		"Genkyū (1204-1206)",
+		"Ken-ei (1206-1207)",
+		"Shōgen (1207-1211)",
+		"Kenryaku (1211-1213)",
+		"Kenpō (1213-1219)",
+		"Shōkyū (1219-1222)",
+		"Jōō (1222-1224)",
+		"Gennin (1224-1225)",
+		"Karoku (1225-1227)",
+		"Antei (1227-1229)",
+		"Kanki (1229-1232)",
+		"Jōei (1232-1233)",
+		"Tempuku (1233-1234)",
+		"Bunryaku (1234-1235)",
+		"Katei (1235-1238)",
+		"Ryakunin (1238-1239)",
+		"En-ō (1239-1240)",
+		"Ninji (1240-1243)",
+		"Kangen (1243-1247)",
+		"Hōji (1247-1249)",
+		"Kenchō (1249-1256)",
+		"Kōgen (1256-1257)",
+		"Shōka (1257-1259)",
+		"Shōgen (1259-1260)",
+		"Bun-ō (1260-1261)",
+		"Kōchō (1261-1264)",
+		"Bun-ei (1264-1275)",
+		"Kenji (1275-1278)",
+		"Kōan (1278-1288)",
+		"Shōō (1288-1293)",
+		"Einin (1293-1299)",
+		"Shōan (1299-1302)",
+		"Kengen (1302-1303)",
+		"Kagen (1303-1306)",
+		"Tokuji (1306-1308)",
+		"Enkei (1308-1311)",
+		"Ōchō (1311-1312)",
+		"Shōwa (1312-1317)",
+		"Bunpō (1317-1319)",
+		"Genō (1319-1321)",
+		"Genkyō (1321-1324)",
+		"Shōchū (1324-1326)",
+		"Kareki (1326-1329)",
+		"Gentoku (1329-1331)",
+		"Genkō (1331-1334)",
+		"Kemmu (1334-1336)",
+		"Engen (1336-1340)",
+		"Kōkoku (1340-1346)",
+		"Shōhei (1346-1370)",
+		"Kentoku (1370-1372)",
+		"Bunchū (1372-1375)",
+		"Tenju (1375-1379)",
+		"Kōryaku (1379-1381)",
+		"Kōwa (1381-1384)",
+		"Genchū (1384-1392)",
+		"Meitoku (1384-1387)",
+		"Kakei (1387-1389)",
+		"Kōō (1389-1390)",
+		"Meitoku (1390-1394)",
+		"Ōei (1394-1428)",
+		"Shōchō (1428-1429)",
+		"Eikyō (1429-1441)",
+		"Kakitsu (1441-1444)",
+		"Bun-an (1444-1449)",
+		"Hōtoku (1449-1452)",
+		"Kyōtoku (1452-1455)",
+		"Kōshō (1455-1457)",
+		"Chōroku (1457-1460)",
+		"Kanshō (1460-1466)",
+		"Bunshō (1466-1467)",
+		"Ōnin (1467-1469)",
+		"Bunmei (1469-1487)",
+		"Chōkyō (1487-1489)",
+		"Entoku (1489-1492)",
+		"Meiō (1492-1501)",
+		"Bunki (1501-1504)",
+		"Eishō (1504-1521)",
+		"Taiei (1521-1528)",
+		"Kyōroku (1528-1532)",
+		"Tenmon (1532-1555)",
+		"Kōji (1555-1558)",
+		"Eiroku (1558-1570)",
+		"Genki (1570-1573)",
+		"Tenshō (1573-1592)",
+		"Bunroku (1592-1596)",
+		"Keichō (1596-1615)",
+		"Genwa (1615-1624)",
+		"Kan-ei (1624-1644)",
+		"Shōho (1644-1648)",
+		"Keian (1648-1652)",
+		"Shōō (1652-1655)",
+		"Meiryaku (1655-1658)",
+		"Manji (1658-1661)",
+		"Kanbun (1661-1673)",
+		"Enpō (1673-1681)",
+		"Tenwa (1681-1684)",
+		"Jōkyō (1684-1688)",
+		"Genroku (1688-1704)",
+		"Hōei (1704-1711)",
+		"Shōtoku (1711-1716)",
+		"Kyōhō (1716-1736)",
+		"Genbun (1736-1741)",
+		"Kanpō (1741-1744)",
+		"Enkyō (1744-1748)",
+		"Kan-en (1748-1751)",
+		"Hōryaku (1751-1764)",
+		"Meiwa (1764-1772)",
+		"An-ei (1772-1781)",
+		"Tenmei (1781-1789)",
+		"Kansei (1789-1801)",
+		"Kyōwa (1801-1804)",
+		"Bunka (1804-1818)",
+		"Bunsei (1818-1830)",
+		"Tenpō (1830-1844)",
+		"Kōka (1844-1848)",
+		"Kaei (1848-1854)",
+		"Ansei (1854-1860)",
+		"Man-en (1860-1861)",
+		"Bunkyū (1861-1864)",
+		"Genji (1864-1865)",
+		"Keiō (1865-1868)",
+		"Meiji",
+		"Taishō",
+		"Shōwa",
+		"Heisei"
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Yesterday",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateTimeFormat-long": "{1} {0}",
+	"dateFormatItem-h": "h a",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "MM-dd, E",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"field-zone": "Zone",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-y": "G y",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"days-standAlone-wide at localeAlias428": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
+	"days-format-short at localeAlias421": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"days-format-short at localeAlias422": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dayPeriods-format-abbr-pm": "PM",
+	"eraNames at localeAlias442": {
+		"bundle": "japanese",
+		"target": "eraAbbr"
+	},
+	"dateFormat at localeAlias443": {
+		"bundle": "generic",
+		"target": "dateFormat"
+	},
+	"dayPeriods-format-narrow at localeAlias437": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dayPeriods-format-narrow at localeAlias438": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"eraNames": [
+		"Taika (645-650)",
+		"Hakuchi (650-671)",
+		"Hakuhō (672-686)",
+		"Shuchō (686-701)",
+		"Taihō (701-704)",
+		"Keiun (704-708)",
+		"Wadō (708-715)",
+		"Reiki (715-717)",
+		"Yōrō (717-724)",
+		"Jinki (724-729)",
+		"Tempyō (729-749)",
+		"Tempyō-kampō (749-749)",
+		"Tempyō-shōhō (749-757)",
+		"Tempyō-hōji (757-765)",
+		"Temphō-jingo (765-767)",
+		"Jingo-keiun (767-770)",
+		"Hōki (770-780)",
+		"Ten-ō (781-782)",
+		"Enryaku (782-806)",
+		"Daidō (806-810)",
+		"Kōnin (810-824)",
+		"Tenchō (824-834)",
+		"Jōwa (834-848)",
+		"Kajō (848-851)",
+		"Ninju (851-854)",
+		"Saiko (854-857)",
+		"Tennan (857-859)",
+		"Jōgan (859-877)",
+		"Genkei (877-885)",
+		"Ninna (885-889)",
+		"Kampyō (889-898)",
+		"Shōtai (898-901)",
+		"Engi (901-923)",
+		"Enchō (923-931)",
+		"Shōhei (931-938)",
+		"Tengyō (938-947)",
+		"Tenryaku (947-957)",
+		"Tentoku (957-961)",
+		"Ōwa (961-964)",
+		"Kōhō (964-968)",
+		"Anna (968-970)",
+		"Tenroku (970-973)",
+		"Ten-en (973-976)",
+		"Jōgen (976-978)",
+		"Tengen (978-983)",
+		"Eikan (983-985)",
+		"Kanna (985-987)",
+		"Ei-en (987-989)",
+		"Eiso (989-990)",
+		"Shōryaku (990-995)",
+		"Chōtoku (995-999)",
+		"Chōhō (999-1004)",
+		"Kankō (1004-1012)",
+		"Chōwa (1012-1017)",
+		"Kannin (1017-1021)",
+		"Jian (1021-1024)",
+		"Manju (1024-1028)",
+		"Chōgen (1028-1037)",
+		"Chōryaku (1037-1040)",
+		"Chōkyū (1040-1044)",
+		"Kantoku (1044-1046)",
+		"Eishō (1046-1053)",
+		"Tengi (1053-1058)",
+		"Kōhei (1058-1065)",
+		"Jiryaku (1065-1069)",
+		"Enkyū (1069-1074)",
+		"Shōho (1074-1077)",
+		"Shōryaku (1077-1081)",
+		"Eiho (1081-1084)",
+		"Ōtoku (1084-1087)",
+		"Kanji (1087-1094)",
+		"Kaho (1094-1096)",
+		"Eichō (1096-1097)",
+		"Shōtoku (1097-1099)",
+		"Kōwa (1099-1104)",
+		"Chōji (1104-1106)",
+		"Kashō (1106-1108)",
+		"Tennin (1108-1110)",
+		"Ten-ei (1110-1113)",
+		"Eikyū (1113-1118)",
+		"Gen-ei (1118-1120)",
+		"Hoan (1120-1124)",
+		"Tenji (1124-1126)",
+		"Daiji (1126-1131)",
+		"Tenshō (1131-1132)",
+		"Chōshō (1132-1135)",
+		"Hoen (1135-1141)",
+		"Eiji (1141-1142)",
+		"Kōji (1142-1144)",
+		"Tenyō (1144-1145)",
+		"Kyūan (1145-1151)",
+		"Ninpei (1151-1154)",
+		"Kyūju (1154-1156)",
+		"Hogen (1156-1159)",
+		"Heiji (1159-1160)",
+		"Eiryaku (1160-1161)",
+		"Ōho (1161-1163)",
+		"Chōkan (1163-1165)",
+		"Eiman (1165-1166)",
+		"Nin-an (1166-1169)",
+		"Kaō (1169-1171)",
+		"Shōan (1171-1175)",
+		"Angen (1175-1177)",
+		"Jishō (1177-1181)",
+		"Yōwa (1181-1182)",
+		"Juei (1182-1184)",
+		"Genryuku (1184-1185)",
+		"Bunji (1185-1190)",
+		"Kenkyū (1190-1199)",
+		"Shōji (1199-1201)",
+		"Kennin (1201-1204)",
+		"Genkyū (1204-1206)",
+		"Ken-ei (1206-1207)",
+		"Shōgen (1207-1211)",
+		"Kenryaku (1211-1213)",
+		"Kenpō (1213-1219)",
+		"Shōkyū (1219-1222)",
+		"Jōō (1222-1224)",
+		"Gennin (1224-1225)",
+		"Karoku (1225-1227)",
+		"Antei (1227-1229)",
+		"Kanki (1229-1232)",
+		"Jōei (1232-1233)",
+		"Tempuku (1233-1234)",
+		"Bunryaku (1234-1235)",
+		"Katei (1235-1238)",
+		"Ryakunin (1238-1239)",
+		"En-ō (1239-1240)",
+		"Ninji (1240-1243)",
+		"Kangen (1243-1247)",
+		"Hōji (1247-1249)",
+		"Kenchō (1249-1256)",
+		"Kōgen (1256-1257)",
+		"Shōka (1257-1259)",
+		"Shōgen (1259-1260)",
+		"Bun-ō (1260-1261)",
+		"Kōchō (1261-1264)",
+		"Bun-ei (1264-1275)",
+		"Kenji (1275-1278)",
+		"Kōan (1278-1288)",
+		"Shōō (1288-1293)",
+		"Einin (1293-1299)",
+		"Shōan (1299-1302)",
+		"Kengen (1302-1303)",
+		"Kagen (1303-1306)",
+		"Tokuji (1306-1308)",
+		"Enkei (1308-1311)",
+		"Ōchō (1311-1312)",
+		"Shōwa (1312-1317)",
+		"Bunpō (1317-1319)",
+		"Genō (1319-1321)",
+		"Genkyō (1321-1324)",
+		"Shōchū (1324-1326)",
+		"Kareki (1326-1329)",
+		"Gentoku (1329-1331)",
+		"Genkō (1331-1334)",
+		"Kemmu (1334-1336)",
+		"Engen (1336-1340)",
+		"Kōkoku (1340-1346)",
+		"Shōhei (1346-1370)",
+		"Kentoku (1370-1372)",
+		"Bunchū (1372-1375)",
+		"Tenju (1375-1379)",
+		"Kōryaku (1379-1381)",
+		"Kōwa (1381-1384)",
+		"Genchū (1384-1392)",
+		"Meitoku (1384-1387)",
+		"Kakei (1387-1389)",
+		"Kōō (1389-1390)",
+		"Meitoku (1390-1394)",
+		"Ōei (1394-1428)",
+		"Shōchō (1428-1429)",
+		"Eikyō (1429-1441)",
+		"Kakitsu (1441-1444)",
+		"Bun-an (1444-1449)",
+		"Hōtoku (1449-1452)",
+		"Kyōtoku (1452-1455)",
+		"Kōshō (1455-1457)",
+		"Chōroku (1457-1460)",
+		"Kanshō (1460-1466)",
+		"Bunshō (1466-1467)",
+		"Ōnin (1467-1469)",
+		"Bunmei (1469-1487)",
+		"Chōkyō (1487-1489)",
+		"Entoku (1489-1492)",
+		"Meiō (1492-1501)",
+		"Bunki (1501-1504)",
+		"Eishō (1504-1521)",
+		"Taiei (1521-1528)",
+		"Kyōroku (1528-1532)",
+		"Tenmon (1532-1555)",
+		"Kōji (1555-1558)",
+		"Eiroku (1558-1570)",
+		"Genki (1570-1573)",
+		"Tenshō (1573-1592)",
+		"Bunroku (1592-1596)",
+		"Keichō (1596-1615)",
+		"Genwa (1615-1624)",
+		"Kan-ei (1624-1644)",
+		"Shōho (1644-1648)",
+		"Keian (1648-1652)",
+		"Shōō (1652-1655)",
+		"Meiryaku (1655-1658)",
+		"Manji (1658-1661)",
+		"Kanbun (1661-1673)",
+		"Enpō (1673-1681)",
+		"Tenwa (1681-1684)",
+		"Jōkyō (1684-1688)",
+		"Genroku (1688-1704)",
+		"Hōei (1704-1711)",
+		"Shōtoku (1711-1716)",
+		"Kyōhō (1716-1736)",
+		"Genbun (1736-1741)",
+		"Kanpō (1741-1744)",
+		"Enkyō (1744-1748)",
+		"Kan-en (1748-1751)",
+		"Hōryaku (1751-1764)",
+		"Meiwa (1764-1772)",
+		"An-ei (1772-1781)",
+		"Tenmei (1781-1789)",
+		"Kansei (1789-1801)",
+		"Kyōwa (1801-1804)",
+		"Bunka (1804-1818)",
+		"Bunsei (1818-1830)",
+		"Tenpō (1830-1844)",
+		"Kōka (1844-1848)",
+		"Kaei (1848-1854)",
+		"Ansei (1854-1860)",
+		"Man-en (1860-1861)",
+		"Bunkyū (1861-1864)",
+		"Genji (1864-1865)",
+		"Keiō (1865-1868)",
+		"Meiji",
+		"Taishō",
+		"Shōwa",
+		"Heisei"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"timeFormat at localeAlias444": {
+		"bundle": "gregorian",
+		"target": "timeFormat"
+	},
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"days-standAlone-abbr at localeAlias423": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-standAlone-abbr at localeAlias424": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-standAlone-short at localeAlias425": {
+		"bundle": "gregorian",
+		"target": "days-format-short"
+	},
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"days-standAlone-short at localeAlias426": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-standAlone-short at localeAlias427": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-format-abbr at localeAlias419": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dayPeriods-format-narrow at localeAlias440": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dayPeriods-format-narrow at localeAlias441": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dayPeriods at localeAlias435": {
+		"bundle": "gregorian",
+		"target": "dayPeriods"
+	},
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"days at localeAlias418": {
+		"bundle": "gregorian",
+		"target": "days"
+	},
+	"field-second": "Second",
+	"quarters-standAlone-wide at localeAlias434": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateFormatItem-Ed": "d, E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
+	"dayPeriods-format-narrow-pm": "PM",
+	"months at localeAlias412": {
+		"bundle": "gregorian",
+		"target": "months"
+	},
+	"days-format-narrow at localeAlias420": {
+		"bundle": "gregorian",
+		"target": "days-standAlone-narrow"
+	},
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "G y MMM",
+	"dateFormatItem-yyyy": "G y"
+}
+//end v1.x content
+,
+	"ar": true,
+	"cs": true,
+	"da": true,
+	"de": true,
+	"el": true,
+	"en": true,
+	"en-au": true,
+	"en-gb": true,
+	"es": true,
+	"fi": true,
+	"fr": true,
+	"he": true,
+	"hu": true,
+	"it": true,
+	"ja": true,
+	"ko": true,
+	"nb": true,
+	"nl": true,
+	"pl": true,
+	"pt": true,
+	"pt-pt": true,
+	"ru": true,
+	"sv": true,
+	"th": true,
+	"tr": true,
+	"zh": true,
+	"zh-hant": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/buddhist.js b/dojo/cldr/nls/ko/buddhist.js
new file mode 100644
index 0000000..9941673
--- /dev/null
+++ b/dojo/cldr/nls/ko/buddhist.js
@@ -0,0 +1,161 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"field-weekday": "요일",
+	"dateFormatItem-GyMMMEd": "G y년 MMM d일 (E)",
+	"dateFormatItem-MMMEd": "MMM d일 (E)",
+	"eraNarrow": [
+		"불기"
+	],
+	"days-format-short": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"dateFormat-long": "G y년 M월 d일",
+	"months-format-wide": [
+		"1월",
+		"2월",
+		"3월",
+		"4월",
+		"5월",
+		"6월",
+		"7월",
+		"8월",
+		"9월",
+		"10월",
+		"11월",
+		"12월"
+	],
+	"dateFormatItem-yyyyQQQ": "G y년 QQQ",
+	"dayPeriods-format-wide-pm": "오후",
+	"dateFormat-full": "G y년 M월 d일 EEEE",
+	"dateFormatItem-yyyyMEd": "G y. M. d. (E)",
+	"dateFormatItem-Md": "M. d.",
+	"field-era": "연호",
+	"timeFormat-short": "a h:mm",
+	"quarters-format-wide": [
+		"제 1/4분기",
+		"제 2/4분기",
+		"제 3/4분기",
+		"제 4/4분기"
+	],
+	"timeFormat-long": "a h시 m분 s초 z",
+	"field-year": "년",
+	"field-hour": "시",
+	"timeFormat-full": "a h시 m분 s초 zzzz",
+	"field-day-relative+0": "오늘",
+	"field-day-relative+1": "내일",
+	"dateFormatItem-GyMMMd": "G y년 MMM d일",
+	"field-day-relative+2": "모레",
+	"dateFormatItem-H": "H시",
+	"quarters-format-abbr": [
+		"1분기",
+		"2분기",
+		"3분기",
+		"4분기"
+	],
+	"dateFormatItem-Gy": "G y년",
+	"dateFormatItem-yyyyMMMEd": "G y년 MMM d일 (E)",
+	"dateFormatItem-M": "M월",
+	"dateFormatItem-yyyyMMM": "G y년 MMM",
+	"dateFormatItem-yyyyMMMd": "G y년 MMM d일",
+	"timeFormat-medium": "a h:mm:ss",
+	"eraAbbr": [
+		"불기"
+	],
+	"field-minute": "분",
+	"field-dayperiod": "오전/오후",
+	"dateFormatItem-d": "d일",
+	"field-day-relative+-1": "어제",
+	"dateFormatItem-h": "a h시",
+	"field-day-relative+-2": "그저께",
+	"dateFormatItem-MMMd": "MMM d일",
+	"dateFormatItem-MEd": "M. d. (E)",
+	"field-day": "일",
+	"days-format-wide": [
+		"일요일",
+		"월요일",
+		"화요일",
+		"수요일",
+		"목요일",
+		"금요일",
+		"토요일"
+	],
+	"field-zone": "시간대",
+	"dateFormatItem-y": "G y년",
+	"months-standAlone-narrow": [
+		"1월",
+		"2월",
+		"3월",
+		"4월",
+		"5월",
+		"6월",
+		"7월",
+		"8월",
+		"9월",
+		"10월",
+		"11월",
+		"12월"
+	],
+	"field-year-relative+-1": "지난해",
+	"field-month-relative+-1": "지난달",
+	"dateFormatItem-hm": "a h:mm",
+	"days-format-abbr": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"eraNames": [
+		"불기"
+	],
+	"dateFormatItem-yyyyMd": "G y. M. d.",
+	"field-month": "월",
+	"days-standAlone-narrow": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"dayPeriods-format-wide-am": "오전",
+	"dateFormat-short": "G y. M. d.",
+	"field-second": "초",
+	"field-month-relative+0": "이번 달",
+	"field-month-relative+1": "다음 달",
+	"dateFormatItem-Ed": "d일 (E)",
+	"field-week": "주",
+	"dateFormat-medium": "G y. M. d.",
+	"field-year-relative+0": "올해",
+	"field-week-relative+-1": "지난주",
+	"dateFormatItem-yyyyM": "G y. M.",
+	"field-year-relative+1": "내년",
+	"dateFormatItem-yyyyQQQQ": "G y년 QQQQ",
+	"dateFormatItem-Hms": "H시 m분 s초",
+	"dateFormatItem-hms": "a h:mm:ss",
+	"dateFormatItem-GyMMM": "G y년 MMM",
+	"dateFormatItem-yyyy": "G y년",
+	"field-week-relative+0": "이번 주",
+	"field-week-relative+1": "다음 주"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/chinese.js b/dojo/cldr/nls/ko/chinese.js
new file mode 100644
index 0000000..b181448
--- /dev/null
+++ b/dojo/cldr/nls/ko/chinese.js
@@ -0,0 +1,69 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "U년 MMM d일 (E)",
+	"field-dayperiod": "오전/오후",
+	"field-minute": "분",
+	"dateFormatItem-MMMEd": "MMM d일 (E)",
+	"field-day-relative+-1": "어제",
+	"dateFormatItem-hms": "a h:mm:ss",
+	"field-day-relative+-2": "그저께",
+	"field-weekday": "요일",
+	"dateFormatItem-MMM": "LLL",
+	"dateFormatItem-Gy": "U년",
+	"field-era": "연호",
+	"field-hour": "시",
+	"dateFormatItem-y": "U년",
+	"dateFormatItem-yyyy": "U년",
+	"dateFormatItem-yyyyMMMEEEEd": "U년 MMM d일 EEEE",
+	"dateFormatItem-EEEEd": "d일 EEEE",
+	"dateFormatItem-Ed": "d일 (E)",
+	"field-day-relative+0": "오늘",
+	"field-day-relative+1": "내일",
+	"field-day-relative+2": "모레",
+	"dateFormatItem-GyMMMd": "U년 MMM d일",
+	"dateFormat-long": "U년 M월 d일",
+	"field-zone": "시간대",
+	"dateFormatItem-MMMEEEEd": "MMM d일 EEEE",
+	"field-week-relative+-1": "지난주",
+	"dateFormat-medium": "y. M. d.",
+	"dateFormatItem-Hms": "H시 m분 s초",
+	"field-year-relative+0": "올해",
+	"field-year-relative+1": "내년",
+	"dateFormatItem-yMd": "U. M. d.",
+	"field-year-relative+-1": "지난해",
+	"dateFormatItem-yyyyQQQQ": "U년 QQQQ",
+	"field-year": "년",
+	"dateFormatItem-GyMMMEEEEd": "U년 MMM d일 EEEE",
+	"field-week": "주",
+	"dateFormatItem-yyyyMd": "U. M. d.",
+	"dateFormatItem-yyyyMMMd": "U년 MMM d일",
+	"dateFormatItem-yyyyMEd": "U. M. d. (E)",
+	"dateFormatItem-yyyyMEEEEd": "U. M. d. EEEE",
+	"dateFormatItem-MMMd": "MMM d일",
+	"field-week-relative+0": "이번 주",
+	"field-week-relative+1": "다음 주",
+	"field-month-relative+0": "이번 달",
+	"dateFormatItem-H": "H시",
+	"field-month": "월",
+	"field-month-relative+1": "다음 달",
+	"dateFormatItem-M": "M월",
+	"field-second": "초",
+	"dateFormatItem-GyMMMEd": "U년 MMM d일 (E)",
+	"dateFormatItem-GyMMM": "U년 MMM",
+	"dateFormatItem-MEEEEd": "M. d. EEEE",
+	"field-day": "일",
+	"dateFormatItem-MEd": "M. d. (E)",
+	"dateFormatItem-yyyyQQQ": "U년 QQQ",
+	"dateFormatItem-hm": "a h:mm",
+	"dateFormat-short": "y. M. d.",
+	"dateFormatItem-yyyyM": "U. M.",
+	"dateFormat-full": "U년 M월 d일 EEEE",
+	"dateFormatItem-Md": "M. d.",
+	"dateFormatItem-yyyyMMM": "U년 MMM",
+	"dateFormatItem-d": "d일",
+	"field-month-relative+-1": "지난달",
+	"dateFormatItem-h": "a h시"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/currency.js b/dojo/cldr/nls/ko/currency.js
index 41d6247..53f7de5 100644
--- a/dojo/cldr/nls/ko/currency.js
+++ b/dojo/cldr/nls/ko/currency.js
@@ -9,6 +9,7 @@ define(
 	"JPY_displayName": "일본 엔화",
 	"USD_displayName": "미국 달러",
 	"GBP_displayName": "영국령 파운드 스털링",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "유로화"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/ko/generic.js b/dojo/cldr/nls/ko/generic.js
new file mode 100644
index 0000000..cdb4b07
--- /dev/null
+++ b/dojo/cldr/nls/ko/generic.js
@@ -0,0 +1,75 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "G y년 MMM d일 (E)",
+	"field-dayperiod": "오전/오후",
+	"field-minute": "분",
+	"dateFormatItem-MMMEd": "MMM d일 (E)",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "어제",
+	"dateFormatItem-hms": "a h:mm:ss",
+	"field-day-relative+-2": "그저께",
+	"field-weekday": "요일",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "G y년",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "연호",
+	"field-hour": "시",
+	"dateFormatItem-y": "G y년",
+	"dateFormatItem-yyyy": "G y년",
+	"dateFormatItem-yyyyMMMEEEEd": "G y년 MMM d일 EEEE",
+	"dateFormatItem-EEEEd": "d일 EEEE",
+	"dateFormatItem-Ed": "d일 (E)",
+	"field-day-relative+0": "오늘",
+	"field-day-relative+1": "내일",
+	"field-day-relative+2": "모레",
+	"dateFormatItem-GyMMMd": "G y년 MMM d일",
+	"dateFormat-long": "G y년 M월 d일",
+	"field-zone": "시간대",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormatItem-MMMEEEEd": "MMM d일 EEEE",
+	"field-week-relative+-1": "지난주",
+	"dateFormat-medium": "G y. M. d.",
+	"dateFormatItem-Hms": "H시 m분 s초",
+	"field-year-relative+0": "올해",
+	"field-year-relative+1": "내년",
+	"field-year-relative+-1": "지난해",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "G y년 QQQQ",
+	"field-year": "년",
+	"dateFormatItem-GyMMMEEEEd": "G y년 MMM d일 EEEE",
+	"dateTimeFormat-long": "{1} {0}",
+	"dateFormatItem-HHmmss": "HH:mm:ss",
+	"field-week": "주",
+	"dateFormatItem-yyyyMd": "G y. M. d.",
+	"dateFormatItem-yyyyMMMd": "G y년 MMM d일",
+	"dateFormatItem-yyyyMEd": "G y. M. d. (E)",
+	"dateFormatItem-yyyyMEEEEd": "G y. M. d. EEEE",
+	"dateFormatItem-MMMd": "MMM d일",
+	"field-week-relative+0": "이번 주",
+	"field-week-relative+1": "다음 주",
+	"field-month-relative+0": "이번 달",
+	"dateFormatItem-H": "H시",
+	"field-month": "월",
+	"field-month-relative+1": "다음 달",
+	"dateFormatItem-M": "M월",
+	"field-second": "초",
+	"dateFormatItem-GyMMMEd": "G y년 MMM d일 (E)",
+	"dateFormatItem-GyMMM": "G y년 MMM",
+	"dateFormatItem-MEEEEd": "M. d. EEEE",
+	"field-day": "일",
+	"dateFormatItem-MEd": "M. d. (E)",
+	"dateFormatItem-yyyyQQQ": "G y년 QQQ",
+	"dateFormatItem-hm": "a h:mm",
+	"dateFormat-short": "G y. M. d.",
+	"dateFormatItem-yyyyM": "G y. M.",
+	"dateFormat-full": "G y년 M월 d일 EEEE",
+	"dateFormatItem-Md": "M. d.",
+	"dateFormatItem-yyyyMMM": "G y년 MMM",
+	"dateFormatItem-d": "d일",
+	"field-month-relative+-1": "지난달",
+	"dateFormatItem-h": "a h시"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/gregorian.js b/dojo/cldr/nls/ko/gregorian.js
index ee950b9..87ad8d9 100644
--- a/dojo/cldr/nls/ko/gregorian.js
+++ b/dojo/cldr/nls/ko/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
 	"months-format-narrow": [
 		"1월",
 		"2월",
@@ -15,14 +24,31 @@ define(
 		"11월",
 		"12월"
 	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "요일",
 	"dateFormatItem-yQQQ": "y년 QQQ",
-	"dateFormatItem-yMEd": "yyyy. M. d. EEE",
+	"dateFormatItem-yMEd": "y. M. d. (E)",
+	"dateFormatItem-GyMMMEd": "G y년 MMM d일 (E)",
 	"dateFormatItem-MMMEd": "MMM d일 (E)",
 	"eraNarrow": [
 		"기원전",
 		"서기"
 	],
+	"dateFormatItem-yMM": "y. M.",
+	"days-format-short": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
 	"dateFormat-long": "y년 M월 d일",
 	"months-format-wide": [
 		"1월",
@@ -39,12 +65,12 @@ define(
 		"12월"
 	],
 	"dateTimeFormat-medium": "{1} {0}",
-	"dateFormatItem-EEEd": "d일 EEE",
 	"dayPeriods-format-wide-pm": "오후",
 	"dateFormat-full": "y년 M월 d일 EEEE",
 	"dateFormatItem-Md": "M. d.",
+	"dateFormatItem-yMd": "y. M. d.",
 	"field-era": "연호",
-	"dateFormatItem-yM": "yyyy. M.",
+	"dateFormatItem-yM": "y. M.",
 	"months-standAlone-wide": [
 		"1월",
 		"2월",
@@ -66,12 +92,12 @@ define(
 		"제 3/4분기",
 		"제 4/4분기"
 	],
+	"dateFormatItem-MEEEEd": "M. d. EEEE",
+	"dateFormatItem-yQQQQ": "y년 QQQQ",
 	"timeFormat-long": "a h시 m분 s초 z",
 	"field-year": "년",
 	"dateFormatItem-yMMM": "y년 MMM",
-	"dateFormatItem-yQ": "y년 Q분기",
 	"field-hour": "시",
-	"dateFormatItem-MMdd": "MM. dd",
 	"months-format-abbr": [
 		"1월",
 		"2월",
@@ -86,13 +112,13 @@ define(
 		"11월",
 		"12월"
 	],
-	"dateFormatItem-yyQ": "yy년 Q분기",
+	"dateFormatItem-yMEEEEd": "y. M. d. EEEE",
 	"timeFormat-full": "a h시 m분 s초 zzzz",
 	"field-day-relative+0": "오늘",
 	"field-day-relative+1": "내일",
+	"dateFormatItem-GyMMMd": "G y년 MMM d일",
 	"field-day-relative+2": "모레",
 	"dateFormatItem-H": "H시",
-	"field-day-relative+3": "3일후",
 	"months-standAlone-abbr": [
 		"1월",
 		"2월",
@@ -119,6 +145,7 @@ define(
 		"제 3/4분기",
 		"제 4/4분기"
 	],
+	"dateFormatItem-Gy": "G y년",
 	"dateFormatItem-HHmmss": "HH:mm:ss",
 	"dateFormatItem-M": "M월",
 	"days-standAlone-wide": [
@@ -130,7 +157,7 @@ define(
 		"금요일",
 		"토요일"
 	],
-	"dateFormatItem-yyMMM": "yy년 MMM",
+	"dateFormatItem-yMMMEEEEd": "y년 MMM d일 EEEE",
 	"timeFormat-medium": "a h:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -156,12 +183,18 @@ define(
 	],
 	"dateFormatItem-d": "d일",
 	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "어제",
 	"dateFormatItem-h": "a h시",
 	"dateTimeFormat-long": "{1} {0}",
 	"field-day-relative+-2": "그저께",
-	"field-day-relative+-3": "그끄제",
 	"dateFormatItem-MMMd": "MMM d일",
+	"dateFormatItem-EEEEd": "d일 EEEE",
 	"dateFormatItem-MEd": "M. d. (E)",
 	"dateTimeFormat-full": "{1} {0}",
 	"field-day": "일",
@@ -175,7 +208,6 @@ define(
 		"토요일"
 	],
 	"field-zone": "시간대",
-	"dateFormatItem-yyyyMM": "yyyy. MM",
 	"dateFormatItem-y": "y년",
 	"months-standAlone-narrow": [
 		"1월",
@@ -191,8 +223,10 @@ define(
 		"11월",
 		"12월"
 	],
-	"dateFormatItem-yyMM": "YY. M.",
+	"field-year-relative+-1": "지난해",
+	"field-month-relative+-1": "지난달",
 	"dateFormatItem-hm": "a h:mm",
+	"dateFormatItem-GyMMMEEEEd": "G y년 MMM d일 EEEE",
 	"days-format-abbr": [
 		"일",
 		"월",
@@ -216,6 +250,7 @@ define(
 		"금",
 		"토"
 	],
+	"dateFormatItem-MMMEEEEd": "MMM d일 EEEE",
 	"field-month": "월",
 	"days-standAlone-narrow": [
 		"일",
@@ -230,14 +265,22 @@ define(
 	"dayPeriods-format-wide-am": "오전",
 	"dateFormat-short": "yy. M. d.",
 	"field-second": "초",
-	"dateFormatItem-yMMMEd": "y년 MMM d일 EEE",
+	"dateFormatItem-yMMMEd": "y년 MMM d일 (E)",
+	"field-month-relative+0": "이번 달",
+	"field-month-relative+1": "다음 달",
 	"dateFormatItem-Ed": "d일 (E)",
 	"field-week": "주",
-	"dateFormat-medium": "yyyy. M. d.",
+	"dateFormat-medium": "y. M. d.",
+	"field-year-relative+0": "올해",
+	"field-week-relative+-1": "지난주",
+	"field-year-relative+1": "내년",
 	"dateFormatItem-mmss": "mm:ss",
 	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "H시 m분 s초",
-	"dateFormatItem-hms": "a h:mm:ss"
+	"dateFormatItem-hms": "a h:mm:ss",
+	"dateFormatItem-GyMMM": "G y년 MMM",
+	"field-week-relative+0": "이번 주",
+	"field-week-relative+1": "다음 주"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/hebrew.js b/dojo/cldr/nls/ko/hebrew.js
new file mode 100644
index 0000000..3d605d2
--- /dev/null
+++ b/dojo/cldr/nls/ko/hebrew.js
@@ -0,0 +1,127 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "오전/오후",
+	"dateFormatItem-yyyyMMMEd": "G y년 MMM d일 (E)",
+	"dayPeriods-format-wide-pm": "오후",
+	"field-minute": "분",
+	"dateFormatItem-MMMEd": "MMM d일 (E)",
+	"field-day-relative+-1": "어제",
+	"field-weekday": "요일",
+	"dateFormatItem-hms": "a h:mm:ss",
+	"field-day-relative+-2": "그저께",
+	"field-era": "연호",
+	"dateFormatItem-Gy": "G y년",
+	"field-hour": "시",
+	"dayPeriods-format-wide-am": "오전",
+	"dateFormatItem-y": "G y년",
+	"timeFormat-full": "a h시 m분 s초 zzzz",
+	"dateFormatItem-yyyy": "G y년",
+	"dateFormatItem-Ed": "d일 (E)",
+	"field-day-relative+0": "오늘",
+	"field-day-relative+1": "내일",
+	"days-standAlone-narrow": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"eraAbbr": [
+		"AM"
+	],
+	"field-day-relative+2": "모레",
+	"dateFormatItem-GyMMMd": "G y년 MMM d일",
+	"dateFormat-long": "G y년 M월 d일",
+	"timeFormat-medium": "a h:mm:ss",
+	"field-zone": "시간대",
+	"field-week-relative+-1": "지난주",
+	"dateFormat-medium": "G y. M. d.",
+	"dateFormatItem-Hms": "H시 m분 s초",
+	"field-year-relative+0": "올해",
+	"field-year-relative+1": "내년",
+	"field-year-relative+-1": "지난해",
+	"field-year": "년",
+	"dateFormatItem-yyyyQQQQ": "G y년 QQQQ",
+	"field-week": "주",
+	"dateFormatItem-yyyyMd": "G y. M. d.",
+	"dateFormatItem-yyyyMMMd": "G y년 MMM d일",
+	"dateFormatItem-yyyyMEd": "G y. M. d. (E)",
+	"dateFormatItem-MMMd": "MMM d일",
+	"field-week-relative+0": "이번 주",
+	"field-week-relative+1": "다음 주",
+	"timeFormat-long": "a h시 m분 s초 z",
+	"field-month-relative+0": "이번 달",
+	"field-month": "월",
+	"field-month-relative+1": "다음 달",
+	"dateFormatItem-H": "H시",
+	"timeFormat-short": "a h:mm",
+	"quarters-format-abbr": [
+		"1분기",
+		"2분기",
+		"3분기",
+		"4분기"
+	],
+	"days-format-abbr": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"dateFormatItem-M": "M월",
+	"field-second": "초",
+	"dateFormatItem-GyMMMEd": "G y년 MMM d일 (E)",
+	"dateFormatItem-GyMMM": "G y년 MMM",
+	"field-day": "일",
+	"dateFormatItem-yyyyQQQ": "G y년 QQQ",
+	"dateFormatItem-MEd": "M. d. (E)",
+	"days-standAlone-short": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"dateFormatItem-hm": "a h:mm",
+	"dateFormat-short": "G y. M. d.",
+	"dateFormatItem-yyyyM": "G y. M.",
+	"dateFormatItem-Md": "M. d.",
+	"dateFormat-full": "G y년 M월 d일 EEEE",
+	"days-format-short": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"dateFormatItem-yyyyMMM": "G y년 MMM",
+	"dateFormatItem-d": "d일",
+	"field-month-relative+-1": "지난달",
+	"quarters-format-wide": [
+		"제 1/4분기",
+		"제 2/4분기",
+		"제 3/4분기",
+		"제 4/4분기"
+	],
+	"days-format-wide": [
+		"일요일",
+		"월요일",
+		"화요일",
+		"수요일",
+		"목요일",
+		"금요일",
+		"토요일"
+	],
+	"dateFormatItem-h": "a h시"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/islamic.js b/dojo/cldr/nls/ko/islamic.js
new file mode 100644
index 0000000..2d91c8e
--- /dev/null
+++ b/dojo/cldr/nls/ko/islamic.js
@@ -0,0 +1,127 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "오전/오후",
+	"dateFormatItem-yyyyMMMEd": "G y년 MMM d일 (E)",
+	"dayPeriods-format-wide-pm": "오후",
+	"field-minute": "분",
+	"dateFormatItem-MMMEd": "MMM d일 (E)",
+	"field-day-relative+-1": "어제",
+	"field-weekday": "요일",
+	"dateFormatItem-hms": "a h:mm:ss",
+	"field-day-relative+-2": "그저께",
+	"field-era": "연호",
+	"dateFormatItem-Gy": "G y년",
+	"field-hour": "시",
+	"dayPeriods-format-wide-am": "오전",
+	"dateFormatItem-y": "G y년",
+	"timeFormat-full": "a h시 m분 s초 zzzz",
+	"dateFormatItem-yyyy": "G y년",
+	"dateFormatItem-Ed": "d일 (E)",
+	"field-day-relative+0": "오늘",
+	"field-day-relative+1": "내일",
+	"days-standAlone-narrow": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"field-day-relative+2": "모레",
+	"dateFormatItem-GyMMMd": "G y년 MMM d일",
+	"dateFormat-long": "G y년 M월 d일",
+	"timeFormat-medium": "a h:mm:ss",
+	"field-zone": "시간대",
+	"field-week-relative+-1": "지난주",
+	"dateFormat-medium": "G y. M. d.",
+	"dateFormatItem-Hms": "H시 m분 s초",
+	"field-year-relative+0": "올해",
+	"field-year-relative+1": "내년",
+	"field-year-relative+-1": "지난해",
+	"field-year": "년",
+	"dateFormatItem-yyyyQQQQ": "G y년 QQQQ",
+	"field-week": "주",
+	"dateFormatItem-yyyyMMMd": "G y년 MMM d일",
+	"dateFormatItem-yyyyMd": "G y. M. d.",
+	"dateFormatItem-yyyyMEd": "G y. M. d. (E)",
+	"field-week-relative+0": "이번 주",
+	"dateFormatItem-MMMd": "MMM d일",
+	"field-week-relative+1": "다음 주",
+	"timeFormat-long": "a h시 m분 s초 z",
+	"field-month-relative+0": "이번 달",
+	"field-month": "월",
+	"field-month-relative+1": "다음 달",
+	"dateFormatItem-H": "H시",
+	"timeFormat-short": "a h:mm",
+	"quarters-format-abbr": [
+		"1분기",
+		"2분기",
+		"3분기",
+		"4분기"
+	],
+	"days-format-abbr": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"dateFormatItem-M": "M월",
+	"field-second": "초",
+	"dateFormatItem-GyMMMEd": "G y년 MMM d일 (E)",
+	"dateFormatItem-GyMMM": "G y년 MMM",
+	"field-day": "일",
+	"dateFormatItem-yyyyQQQ": "G y년 QQQ",
+	"dateFormatItem-MEd": "M. d. (E)",
+	"days-standAlone-short": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"dateFormatItem-hm": "a h:mm",
+	"dateFormat-short": "G y. M. d.",
+	"dateFormatItem-yyyyM": "G y. M.",
+	"dateFormat-full": "G y년 M월 d일 EEEE",
+	"dateFormatItem-Md": "M. d.",
+	"days-format-short": [
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
+		"토"
+	],
+	"dateFormatItem-yyyyMMM": "G y년 MMM",
+	"dateFormatItem-d": "d일",
+	"field-month-relative+-1": "지난달",
+	"quarters-format-wide": [
+		"제 1/4분기",
+		"제 2/4분기",
+		"제 3/4분기",
+		"제 4/4분기"
+	],
+	"days-format-wide": [
+		"일요일",
+		"월요일",
+		"화요일",
+		"수요일",
+		"목요일",
+		"금요일",
+		"토요일"
+	],
+	"dateFormatItem-h": "a h시"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/japanese.js b/dojo/cldr/nls/ko/japanese.js
new file mode 100644
index 0000000..a85b3b2
--- /dev/null
+++ b/dojo/cldr/nls/ko/japanese.js
@@ -0,0 +1,269 @@
+define(
+//begin v1.x content
+{
+	"field-second": "초",
+	"field-year-relative+-1": "지난해",
+	"field-week": "주",
+	"field-month-relative+-1": "지난달",
+	"field-day-relative+-1": "어제",
+	"field-day-relative+-2": "그저께",
+	"field-year": "년",
+	"field-week-relative+0": "이번 주",
+	"field-week-relative+1": "다음 주",
+	"field-minute": "분",
+	"field-week-relative+-1": "지난주",
+	"field-day-relative+0": "오늘",
+	"field-hour": "시",
+	"field-day-relative+1": "내일",
+	"field-day-relative+2": "모레",
+	"field-day": "일",
+	"field-month-relative+0": "이번 달",
+	"field-month-relative+1": "다음 달",
+	"field-dayperiod": "오전/오후",
+	"field-month": "월",
+	"field-era": "연호",
+	"field-year-relative+0": "올해",
+	"field-year-relative+1": "내년",
+	"eraAbbr": [
+		"다이카 (645 ~ 650)",
+		"하쿠치 (650 ~ 671)",
+		"하쿠호 (672 ~ 686)",
+		"슈초 (686 ~ 701)",
+		"다이호 (701 ~ 704)",
+		"게이운 (704 ~ 708)",
+		"와도 (708 ~ 715)",
+		"레이키 (715 ~ 717)",
+		"요로 (717 ~ 724)",
+		"진키 (724 ~ 729)",
+		"덴표 (729 ~ 749)",
+		"덴표칸포 (749 ~ 749)",
+		"덴표쇼호 (749 ~ 757)",
+		"덴표호지 (757 ~ 765)",
+		"덴표진고 (765 ~ 767)",
+		"진고케이운 (767 ~ 770)",
+		"호키 (770 ~ 780)",
+		"덴오 (781 ~ 782)",
+		"엔랴쿠 (782 ~ 806)",
+		"다이도 (806 ~ 810)",
+		"고닌 (810 ~ 824)",
+		"덴초 (824 ~ 834)",
+		"조와 (834 ~ 848)",
+		"가쇼 (848 ~ 851)",
+		"닌주 (851 ~ 854)",
+		"사이코 (854 ~ 857)",
+		"덴난 (857 ~ 859)",
+		"조간 (859 ~ 877)",
+		"간교 (877 ~ 885)",
+		"닌나 (885 ~ 889)",
+		"간표 (889 ~ 898)",
+		"쇼타이 (898 ~ 901)",
+		"엔기 (901 ~ 923)",
+		"엔초 (923 ~ 931)",
+		"조헤이 (931 ~ 938)",
+		"덴교 (938 ~ 947)",
+		"덴랴쿠 (947 ~ 957)",
+		"덴토쿠 (957 ~ 961)",
+		"오와 (961 ~ 964)",
+		"고호 (964 ~ 968)",
+		"안나 (968 ~ 970)",
+		"덴로쿠 (970 ~ 973)",
+		"덴엔 (973 ~ 976)",
+		"조겐 (976 ~ 978)",
+		"덴겐 (978 ~ 983)",
+		"에이간 (983 ~ 985)",
+		"간나 (985 ~ 987)",
+		"에이엔 (987 ~ 989)",
+		"에이소 (989 ~ 990)",
+		"쇼랴쿠 (990 ~ 995)",
+		"조토쿠 (995 ~ 999)",
+		"조호 (999 ~ 1004)",
+		"간코 (1004 ~ 1012)",
+		"조와 (1012 ~ 1017)",
+		"간닌 (1017 ~ 1021)",
+		"지안 (1021 ~ 1024)",
+		"만주 (1024 ~ 1028)",
+		"조겐 (1028 ~ 1037)",
+		"조랴쿠 (1037 ~ 1040)",
+		"조큐 (1040 ~ 1044)",
+		"간토쿠 (1044 ~ 1046)",
+		"에이쇼 (1046 ~ 1053)",
+		"덴기 (1053 ~ 1058)",
+		"고헤이 (1058 ~ 1065)",
+		"지랴쿠 (1065 ~ 1069)",
+		"엔큐 (1069 ~ 1074)",
+		"조호 (1074 ~ 1077)",
+		"쇼랴쿠 (1077 ~ 1081)",
+		"에이호 (1081 ~ 1084)",
+		"오토쿠 (1084 ~ 1087)",
+		"간지 (1087 ~ 1094)",
+		"가호 (1094 ~ 1096)",
+		"에이초 (1096 ~ 1097)",
+		"조토쿠 (1097 ~ 1099)",
+		"고와 (1099 ~ 1104)",
+		"조지 (1104 ~ 1106)",
+		"가쇼 (1106 ~ 1108)",
+		"덴닌 (1108 ~ 1110)",
+		"덴에이 (1110 ~ 1113)",
+		"에이큐 (1113 ~ 1118)",
+		"겐에이 (1118 ~ 1120)",
+		"호안 (1120 ~ 1124)",
+		"덴지 (1124 ~ 1126)",
+		"다이지 (1126 ~ 1131)",
+		"덴쇼 (1131 ~ 1132)",
+		"조쇼 (1132 ~ 1135)",
+		"호엔 (1135 ~ 1141)",
+		"에이지 (1141 ~ 1142)",
+		"고지 (1142 ~ 1144)",
+		"덴요 (1144 ~ 1145)",
+		"규안 (1145 ~ 1151)",
+		"닌페이 (1151 ~ 1154)",
+		"규주 (1154 ~ 1156)",
+		"호겐 (1156 ~ 1159)",
+		"헤이지 (1159 ~ 1160)",
+		"에이랴쿠 (1160 ~ 1161)",
+		"오호 (1161 ~ 1163)",
+		"조칸 (1163 ~ 1165)",
+		"에이만 (1165 ~ 1166)",
+		"닌난 (1166 ~ 1169)",
+		"가오 (1169 ~ 1171)",
+		"조안 (1171 ~ 1175)",
+		"안겐 (1175 ~ 1177)",
+		"지쇼 (1177 ~ 1181)",
+		"요와 (1181 ~ 1182)",
+		"주에이 (1182 ~ 1184)",
+		"겐랴쿠 (1184 ~ 1185)",
+		"분지 (1185 ~ 1190)",
+		"겐큐 (1190 ~ 1199)",
+		"쇼지 (1199 ~ 1201)",
+		"겐닌 (1201 ~ 1204)",
+		"겐큐 (1204 ~ 1206)",
+		"겐에이 (1206 ~ 1207)",
+		"조겐 (1207 ~ 1211)",
+		"겐랴쿠 (1211 ~ 1213)",
+		"겐포 (1213 ~ 1219)",
+		"조큐 (1219 ~ 1222)",
+		"조오 (1222 ~ 1224)",
+		"겐닌 (1224 ~ 1225)",
+		"가로쿠 (1225 ~ 1227)",
+		"안테이 (1227 ~ 1229)",
+		"간키 (1229 ~ 1232)",
+		"조에이 (1232 ~ 1233)",
+		"덴푸쿠 (1233 ~ 1234)",
+		"분랴쿠 (1234 ~ 1235)",
+		"가테이 (1235 ~ 1238)",
+		"랴쿠닌 (1238 ~ 1239)",
+		"엔오 (1239 ~ 1240)",
+		"닌지 (1240 ~ 1243)",
+		"간겐 (1243 ~ 1247)",
+		"호지 (1247 ~ 1249)",
+		"겐초 (1249 ~ 1256)",
+		"고겐 (1256 ~ 1257)",
+		"쇼카 (1257 ~ 1259)",
+		"쇼겐 (1259 ~ 1260)",
+		"분오 (1260 ~ 1261)",
+		"고초 (1261 ~ 1264)",
+		"분에이 (1264 ~ 1275)",
+		"겐지 (1275 ~ 1278)",
+		"고안 (1278 ~ 1288)",
+		"쇼오 (1288 ~ 1293)",
+		"에이닌 (1293 ~ 1299)",
+		"쇼안 (1299 ~ 1302)",
+		"겐겐 (1302 ~ 1303)",
+		"가겐 (1303 ~ 1306)",
+		"도쿠지 (1306 ~ 1308)",
+		"엔쿄 (1308 ~ 1311)",
+		"오초 (1311 ~ 1312)",
+		"쇼와 (1312 ~ 1317)",
+		"분포 (1317 ~ 1319)",
+		"겐오 (1319 ~ 1321)",
+		"겐코 (1321 ~ 1324)",
+		"쇼추 (1324 ~ 1326)",
+		"가랴쿠 (1326 ~ 1329)",
+		"겐토쿠 (1329 ~ 1331)",
+		"겐코 (1331 ~ 1334)",
+		"겐무 (1334 ~ 1336)",
+		"엔겐 (1336 ~ 1340)",
+		"고코쿠 (1340 ~ 1346)",
+		"쇼헤이 (1346 ~ 1370)",
+		"겐토쿠 (1370 ~ 1372)",
+		"분추 (1372 ~ 1375)",
+		"덴주 (1375 ~ 1379)",
+		"고랴쿠 (1379 ~ 1381)",
+		"고와 (1381 ~ 1384)",
+		"겐추 (1384 ~ 1392)",
+		"메이토쿠 (1384 ~ 1387)",
+		"가쿄 (1387 ~ 1389)",
+		"고오 (1389 ~ 1390)",
+		"메이토쿠 (1390 ~ 1394)",
+		"오에이 (1394 ~ 1428)",
+		"쇼초 (1428 ~ 1429)",
+		"에이쿄 (1429 ~ 1441)",
+		"가키쓰 (1441 ~ 1444)",
+		"분안 (1444 ~ 1449)",
+		"호토쿠 (1449 ~ 1452)",
+		"교토쿠 (1452 ~ 1455)",
+		"고쇼 (1455 ~ 1457)",
+		"조로쿠 (1457 ~ 1460)",
+		"간쇼 (1460 ~ 1466)",
+		"분쇼 (1466 ~ 1467)",
+		"오닌 (1467 ~ 1469)",
+		"분메이 (1469 ~ 1487)",
+		"조쿄 (1487 ~ 1489)<",
+		"엔토쿠 (1489 ~ 1492)",
+		"메이오 (1492 ~ 1501)",
+		"분키 (1501 ~ 1504)",
+		"에이쇼 (1504 ~ 1521)",
+		"다이에이 (1521 ~ 1528)",
+		"교로쿠 (1528 ~ 1532)",
+		"덴분 (1532 ~ 1555)",
+		"고지 (1555 ~ 1558)",
+		"에이로쿠 (1558 ~ 1570)",
+		"겐키 (1570 ~ 1573)",
+		"덴쇼 (1573 ~ 1592)",
+		"분로쿠 (1592 ~ 1596)",
+		"게이초 (1596 ~ 1615)",
+		"겐나 (1615 ~ 1624)",
+		"간에이 (1624 ~ 1644)",
+		"쇼호 (1644 ~ 1648)",
+		"게이안 (1648 ~ 1652)",
+		"조오 (1652 ~ 1655)",
+		"메이레키 (1655 ~ 1658)",
+		"만지 (1658 ~ 1661)",
+		"간분 (1661 ~ 1673)",
+		"엔포 (1673 ~ 1681)",
+		"덴나 (1681 ~ 1684)",
+		"조쿄 (1684 ~ 1688)",
+		"겐로쿠 (1688 ~ 1704)",
+		"호에이 (1704 ~ 1711)",
+		"쇼토쿠 (1711 ~ 1716)",
+		"교호 (1716 ~ 1736)",
+		"겐분 (1736 ~ 1741)",
+		"간포 (1741 ~ 1744)",
+		"엔쿄 (1744 ~ 1748)",
+		"간엔 (1748 ~ 1751)",
+		"호레키 (1751 ~ 1764)",
+		"메이와 (1764 ~ 1772)",
+		"안에이 (1772 ~ 1781)",
+		"덴메이 (1781 ~ 1789)",
+		"간세이 (1789 ~ 1801)",
+		"교와 (1801 ~ 1804)",
+		"분카 (1804 ~ 1818)",
+		"분세이 (1818 ~ 1830)",
+		"덴포 (1830 ~ 1844)",
+		"고카 (1844 ~ 1848)",
+		"가에이 (1848 ~ 1854)",
+		"안세이 (1854 ~ 1860)",
+		"만엔 (1860 ~ 1861)",
+		"분큐 (1861 ~ 1864)",
+		"겐지 (1864 ~ 1865)",
+		"게이오 (1865 ~ 1868)",
+		"메이지",
+		"다이쇼",
+		"쇼와",
+		"헤이세이"
+	],
+	"field-weekday": "요일",
+	"field-zone": "시간대"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/number.js b/dojo/cldr/nls/ko/number.js
index 7305f35..2ed1f76 100644
--- a/dojo/cldr/nls/ko/number.js
+++ b/dojo/cldr/nls/ko/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0%",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ".",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
-	"currencyFormat": "¤#,##0.00",
-	"plusSign": "+"
+	"currencyFormat": "¤#,##0.00;(¤#,##0.00)",
+	"plusSign": "+",
+	"decimalFormat-long": "000조",
+	"decimalFormat-short": "000조"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/roc.js b/dojo/cldr/nls/ko/roc.js
new file mode 100644
index 0000000..25e6875
--- /dev/null
+++ b/dojo/cldr/nls/ko/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "초",
+	"field-year-relative+-1": "지난해",
+	"field-week": "주",
+	"field-month-relative+-1": "지난달",
+	"field-day-relative+-1": "어제",
+	"field-day-relative+-2": "그저께",
+	"field-year": "년",
+	"field-week-relative+0": "이번 주",
+	"field-week-relative+1": "다음 주",
+	"field-minute": "분",
+	"field-week-relative+-1": "지난주",
+	"field-day-relative+0": "오늘",
+	"field-hour": "시",
+	"field-day-relative+1": "내일",
+	"field-day-relative+2": "모레",
+	"field-day": "일",
+	"field-month-relative+0": "이번 달",
+	"field-month-relative+1": "다음 달",
+	"field-dayperiod": "오전/오후",
+	"field-month": "월",
+	"field-era": "연호",
+	"field-year-relative+0": "올해",
+	"field-year-relative+1": "내년",
+	"eraAbbr": [
+		"중화민국전",
+		"중화민국"
+	],
+	"field-weekday": "요일",
+	"field-zone": "시간대"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/buddhist.js b/dojo/cldr/nls/nb/buddhist.js
new file mode 100644
index 0000000..5eb9e17
--- /dev/null
+++ b/dojo/cldr/nls/nb/buddhist.js
@@ -0,0 +1,247 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
+	],
+	"months-format-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-weekday": "ukedag",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"days-format-short": [
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
+	],
+	"dateFormat-long": "d. MMMM y G",
+	"months-format-wide": [
+		"januar",
+		"februar",
+		"mars",
+		"april",
+		"mai",
+		"juni",
+		"juli",
+		"august",
+		"september",
+		"oktober",
+		"november",
+		"desember"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateTimeFormat-medium": "{0} {1}",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dateFormatItem-yyyyMEd": "E d.MM.y G",
+	"dateFormatItem-Md": "d.M.",
+	"dayPeriods-format-abbr-am": "a.m.",
+	"field-era": "tidsalder",
+	"months-standAlone-wide": [
+		"januar",
+		"februar",
+		"mars",
+		"april",
+		"mai",
+		"juni",
+		"juli",
+		"august",
+		"september",
+		"oktober",
+		"november",
+		"desember"
+	],
+	"quarters-format-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"field-year": "år",
+	"field-hour": "time",
+	"months-format-abbr": [
+		"jan.",
+		"feb.",
+		"mars",
+		"apr.",
+		"mai",
+		"juni",
+		"juli",
+		"aug.",
+		"sep.",
+		"okt.",
+		"nov.",
+		"des."
+	],
+	"timeFormat-full": "'kl'. HH:mm:ss zzzz",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"field-day-relative+2": "i overmorgen",
+	"months-standAlone-abbr": [
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"mai",
+		"jun",
+		"jul",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
+		"des"
+	],
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"quarters-standAlone-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"days-standAlone-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"eraAbbr": [
+		"BE"
+	],
+	"field-minute": "minutt",
+	"field-dayperiod": "AM/PM",
+	"days-standAlone-abbr": [
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
+	],
+	"dateFormatItem-d": "d.",
+	"field-day-relative+-1": "i går",
+	"dateTimeFormat-long": "{0} {1}",
+	"dayPeriods-format-narrow-am": "a",
+	"field-day-relative+-2": "i forgårs",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-MEd": "E d.M",
+	"dateTimeFormat-full": "{0} {1}",
+	"field-day": "dag",
+	"days-format-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	],
+	"field-zone": "sone",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-year-relative+-1": "I fjor",
+	"field-month-relative+-1": "Sist måned",
+	"dayPeriods-format-abbr-pm": "p.m.",
+	"days-format-abbr": [
+		"søn.",
+		"man.",
+		"tir.",
+		"ons.",
+		"tor.",
+		"fre.",
+		"lør."
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormatItem-yyyyMd": "d.M.y G",
+	"field-month": "måned",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormat-short": "d.M y G",
+	"field-second": "sekund",
+	"field-month-relative+0": "Denne måneden",
+	"field-month-relative+1": "Neste måned",
+	"dateFormatItem-Ed": "E d.",
+	"field-week": "uke",
+	"dateFormat-medium": "d. MMM y G",
+	"field-year-relative+0": "Dette året",
+	"field-week-relative+-1": "Sist uke",
+	"dateFormatItem-yyyyM": "M y G",
+	"field-year-relative+1": "Neste år",
+	"dayPeriods-format-narrow-pm": "p",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateTimeFormat-short": "{0} {1}",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "Denne uken",
+	"field-week-relative+1": "Neste uke"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/currency.js b/dojo/cldr/nls/nb/currency.js
index 2f3d646..ce9eac8 100644
--- a/dojo/cldr/nls/nb/currency.js
+++ b/dojo/cldr/nls/nb/currency.js
@@ -3,20 +3,14 @@ define(
 {
 	"HKD_displayName": "Hongkong-dollar",
 	"CHF_displayName": "sveitsiske franc",
-	"CHF_symbol": "CHF",
-	"JPY_symbol": "JPY",
 	"CAD_displayName": "kanadiske dollar",
-	"CNY_displayName": "kinesiske yuan renminbi",
-	"USD_symbol": "USD",
+	"CNY_displayName": "kinesiske yuan",
 	"AUD_displayName": "australske dollar",
 	"JPY_displayName": "japanske yen",
-	"CAD_symbol": "CAD",
 	"USD_displayName": "amerikanske dollar",
-	"EUR_symbol": "EUR",
-	"CNY_symbol": "CNY",
+	"EUR_symbol": "€",
 	"GBP_displayName": "britiske pund sterling",
-	"GBP_symbol": "GBP",
-	"AUD_symbol": "AUD",
+	"GBP_symbol": "£",
 	"EUR_displayName": "euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/nb/generic.js b/dojo/cldr/nls/nb/generic.js
new file mode 100644
index 0000000..55ef403
--- /dev/null
+++ b/dojo/cldr/nls/nb/generic.js
@@ -0,0 +1,71 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"field-dayperiod": "AM/PM",
+	"field-minute": "minutt",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"dateTimeFormat-full": "{0} {1}",
+	"field-day-relative+-1": "i går",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-MMdd": "d.M.",
+	"field-day-relative+-2": "i forgårs",
+	"field-weekday": "ukedag",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{0} {1}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{0} {1}",
+	"field-era": "tidsalder",
+	"field-hour": "time",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d.",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgen",
+	"field-day-relative+2": "i overmorgen",
+	"dateFormatItem-yyyyMM": "MM.y G",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormat-long": "d. MMMM y G",
+	"field-zone": "sone",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Sist uke",
+	"dateFormat-medium": "d. MMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Dette året",
+	"field-year-relative+1": "Neste år",
+	"field-year-relative+-1": "I fjor",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-year": "år",
+	"dateTimeFormat-long": "{0} {1}",
+	"field-week": "uke",
+	"dateFormatItem-yyyyMd": "d.M.y G",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"dateFormatItem-yyyyMEd": "E d.MM.y G",
+	"dateFormatItem-MMMd": "d. MMM",
+	"field-week-relative+0": "Denne uken",
+	"field-week-relative+1": "Neste uke",
+	"field-month-relative+0": "Denne måneden",
+	"dateFormatItem-H": "HH",
+	"field-month": "måned",
+	"field-month-relative+1": "Neste måned",
+	"dateFormatItem-M": "L",
+	"field-second": "sekund",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "dag",
+	"dateFormatItem-MEd": "E d.M",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "d.M y G",
+	"dateFormatItem-yyyyM": "M y G",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d.",
+	"field-month-relative+-1": "Sist måned",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/gregorian.js b/dojo/cldr/nls/nb/gregorian.js
index 662c95a..da362f7 100644
--- a/dojo/cldr/nls/nb/gregorian.js
+++ b/dojo/cldr/nls/nb/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
+	],
 	"months-format-narrow": [
 		"J",
 		"F",
@@ -15,15 +24,31 @@ define(
 		"N",
 		"D"
 	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "ukedag",
-	"dateFormatItem-yyQQQQ": "QQQQ yy",
 	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "EEE d.M.yyyy",
+	"dateFormatItem-yMEd": "E d.MM.y",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
 	"dateFormatItem-MMMEd": "E d. MMM",
 	"eraNarrow": [
 		"f.Kr.",
 		"e.Kr."
 	],
+	"dateFormatItem-yMM": "MM.y",
+	"days-format-short": [
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
+	],
 	"dateFormat-long": "d. MMMM y",
 	"months-format-wide": [
 		"januar",
@@ -39,12 +64,14 @@ define(
 		"november",
 		"desember"
 	],
-	"dateFormatItem-EEEd": "EEE d.",
+	"dateTimeFormat-medium": "{0} {1}",
 	"dayPeriods-format-wide-pm": "PM",
 	"dateFormat-full": "EEEE d. MMMM y",
 	"dateFormatItem-Md": "d.M.",
-	"field-era": "tidsalder",
+	"dayPeriods-format-abbr-am": "a.m.",
+	"dateFormatItem-yMd": "d.M.y",
 	"dateFormatItem-yM": "M y",
+	"field-era": "tidsalder",
 	"months-standAlone-wide": [
 		"januar",
 		"februar",
@@ -67,12 +94,11 @@ define(
 		"4. kvartal"
 	],
 	"timeFormat-long": "HH:mm:ss z",
-	"field-year": "år",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "Q yyyy",
-	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"dateFormatItem-yQQQQ": "QQQQ y",
+	"field-year": "år",
+	"dateFormatItem-MMdd": "d.M.",
 	"field-hour": "time",
-	"dateFormatItem-MMdd": "dd.MM",
 	"months-format-abbr": [
 		"jan.",
 		"feb.",
@@ -87,25 +113,25 @@ define(
 		"nov.",
 		"des."
 	],
-	"dateFormatItem-yyQ": "Q yy",
 	"timeFormat-full": "'kl'. HH:mm:ss zzzz",
 	"field-day-relative+0": "i dag",
 	"field-day-relative+1": "i morgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
 	"field-day-relative+2": "i overmorgen",
-	"field-day-relative+3": "i overovermorgen",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
-		"jan.",
-		"feb.",
-		"mars",
-		"apr.",
+		"jan",
+		"feb",
+		"mar",
+		"apr",
 		"mai",
-		"juni",
-		"juli",
-		"aug.",
-		"sep.",
-		"okt.",
-		"nov.",
-		"des."
+		"jun",
+		"jul",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
+		"des"
 	],
 	"quarters-format-abbr": [
 		"K1",
@@ -119,6 +145,7 @@ define(
 		"3. kvartal",
 		"4. kvartal"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
 		"søndag",
@@ -129,7 +156,6 @@ define(
 		"fredag",
 		"lørdag"
 	],
-	"dateFormatItem-yyMMM": "MMM yy",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -145,21 +171,31 @@ define(
 	"field-minute": "minutt",
 	"field-dayperiod": "AM/PM",
 	"days-standAlone-abbr": [
-		"søn.",
-		"man.",
-		"tir.",
-		"ons.",
-		"tor.",
-		"fre.",
-		"lør."
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
 	],
 	"dateFormatItem-d": "d.",
-	"dateFormatItem-ms": "mm.ss",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "i går",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{0} {1}",
+	"dayPeriods-format-narrow-am": "a",
 	"field-day-relative+-2": "i forgårs",
-	"field-day-relative+-3": "i forforgårs",
 	"dateFormatItem-MMMd": "d. MMM",
 	"dateFormatItem-MEd": "E d.M",
+	"dateTimeFormat-full": "{0} {1}",
+	"dateFormatItem-yMMMM": "MMMM y",
 	"field-day": "dag",
 	"days-format-wide": [
 		"søndag",
@@ -186,8 +222,10 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-yyMM": "MM.yy",
+	"field-year-relative+-1": "I fjor",
+	"field-month-relative+-1": "Sist måned",
 	"dateFormatItem-hm": "h:mm a",
+	"dayPeriods-format-abbr-pm": "p.m.",
 	"days-format-abbr": [
 		"søn.",
 		"man.",
@@ -197,6 +235,7 @@ define(
 		"fre.",
 		"lør."
 	],
+	"dateFormatItem-yMMMd": "d. MMM y",
 	"eraNames": [
 		"f.Kr.",
 		"e.Kr."
@@ -210,7 +249,6 @@ define(
 		"F",
 		"L"
 	],
-	"field-month": "måned",
 	"days-standAlone-narrow": [
 		"S",
 		"M",
@@ -221,14 +259,26 @@ define(
 		"L"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "måned",
 	"dayPeriods-format-wide-am": "AM",
 	"dateFormat-short": "dd.MM.yy",
 	"field-second": "sekund",
-	"dateFormatItem-yMMMEd": "EEE d. MMM y",
+	"dateFormatItem-yMMMEd": "E d. MMM y",
+	"field-month-relative+0": "Denne måneden",
+	"field-month-relative+1": "Neste måned",
+	"dateFormatItem-Ed": "E d.",
 	"field-week": "uke",
 	"dateFormat-medium": "d. MMM y",
+	"field-year-relative+0": "Dette året",
+	"field-week-relative+-1": "Sist uke",
+	"field-year-relative+1": "Neste år",
+	"dayPeriods-format-narrow-pm": "p",
+	"dateTimeFormat-short": "{0} {1}",
 	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-hms": "h:mm:ss a"
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "Denne uken",
+	"field-week-relative+1": "Neste uke"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/hebrew.js b/dojo/cldr/nls/nb/hebrew.js
new file mode 100644
index 0000000..46e23ab
--- /dev/null
+++ b/dojo/cldr/nls/nb/hebrew.js
@@ -0,0 +1,163 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"field-minute": "minutt",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"dateTimeFormat-full": "{0} {1}",
+	"field-day-relative+-1": "i går",
+	"field-weekday": "ukedag",
+	"field-day-relative+-2": "i forgårs",
+	"days-standAlone-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	],
+	"dateTimeFormat-short": "{0} {1}",
+	"field-era": "tidsalder",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "time",
+	"dateTimeFormat-medium": "{0} {1}",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "'kl'. HH:mm:ss zzzz",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d.",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgen",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"eraAbbr": [
+		"AM"
+	],
+	"field-day-relative+2": "i overmorgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"dateFormat-long": "d. MMMM y G",
+	"field-zone": "sone",
+	"field-week-relative+-1": "Sist uke",
+	"dateFormat-medium": "d. MMM y G",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "Dette året",
+	"field-year-relative+1": "Neste år",
+	"quarters-standAlone-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"field-year-relative+-1": "I fjor",
+	"field-year": "år",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dayPeriods-format-narrow-am": "a",
+	"dateTimeFormat-long": "{0} {1}",
+	"field-week": "uke",
+	"dateFormatItem-yyyyMd": "d.M.y G",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"dateFormatItem-yyyyMEd": "E d.MM.y G",
+	"dateFormatItem-MMMd": "d. MMM",
+	"field-week-relative+0": "Denne uken",
+	"field-week-relative+1": "Neste uke",
+	"field-month-relative+0": "Denne måneden",
+	"field-month": "måned",
+	"field-month-relative+1": "Neste måned",
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"days-format-abbr": [
+		"søn.",
+		"man.",
+		"tir.",
+		"ons.",
+		"tor.",
+		"fre.",
+		"lør."
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"field-second": "sekund",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "dag",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E d.M",
+	"days-standAlone-short": [
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
+	],
+	"days-standAlone-abbr": [
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
+	],
+	"dayPeriods-format-abbr-pm": "p.m.",
+	"dateFormat-short": "d.M y G",
+	"dateFormatItem-yyyyM": "M y G",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dayPeriods-format-abbr-am": "a.m.",
+	"days-format-short": [
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d.",
+	"field-month-relative+-1": "Sist måned",
+	"quarters-format-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"days-format-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/islamic.js b/dojo/cldr/nls/nb/islamic.js
new file mode 100644
index 0000000..dda6e8e
--- /dev/null
+++ b/dojo/cldr/nls/nb/islamic.js
@@ -0,0 +1,163 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-yyyyMMMEd": "E d. MMM y G",
+	"field-minute": "minutt",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"dateTimeFormat-full": "{0} {1}",
+	"field-day-relative+-1": "i går",
+	"field-weekday": "ukedag",
+	"field-day-relative+-2": "i forgårs",
+	"days-standAlone-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	],
+	"dateTimeFormat-short": "{0} {1}",
+	"field-era": "tidsalder",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "time",
+	"dateTimeFormat-medium": "{0} {1}",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "'kl'. HH:mm:ss zzzz",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d.",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgen",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"field-day-relative+2": "i overmorgen",
+	"dateFormatItem-GyMMMd": "d. MMM y G",
+	"dateFormat-long": "d. MMMM y G",
+	"field-zone": "sone",
+	"field-week-relative+-1": "Sist uke",
+	"dateFormat-medium": "d. MMM y G",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "Dette året",
+	"field-year-relative+1": "Neste år",
+	"quarters-standAlone-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"field-year-relative+-1": "I fjor",
+	"field-year": "år",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dayPeriods-format-narrow-am": "a",
+	"dateTimeFormat-long": "{0} {1}",
+	"field-week": "uke",
+	"dateFormatItem-yyyyMMMd": "d. MMM y G",
+	"dateFormatItem-yyyyMd": "d.M.y G",
+	"dateFormatItem-yyyyMEd": "E d.MM.y G",
+	"field-week-relative+0": "Denne uken",
+	"dateFormatItem-MMMd": "d. MMM",
+	"field-week-relative+1": "Neste uke",
+	"field-month-relative+0": "Denne måneden",
+	"field-month": "måned",
+	"field-month-relative+1": "Neste måned",
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"days-format-abbr": [
+		"søn.",
+		"man.",
+		"tir.",
+		"ons.",
+		"tor.",
+		"fre.",
+		"lør."
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"field-second": "sekund",
+	"dateFormatItem-GyMMMEd": "E d. MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "dag",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E d.M",
+	"days-standAlone-short": [
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
+	],
+	"days-standAlone-abbr": [
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
+	],
+	"dayPeriods-format-abbr-pm": "p.m.",
+	"dateFormat-short": "d.M y G",
+	"dateFormatItem-yyyyM": "M y G",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dateFormatItem-Md": "d.M.",
+	"dayPeriods-format-abbr-am": "a.m.",
+	"days-format-short": [
+		"sø.",
+		"ma.",
+		"ti.",
+		"on.",
+		"to.",
+		"fr.",
+		"lø."
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d.",
+	"field-month-relative+-1": "Sist måned",
+	"quarters-format-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"days-format-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/japanese.js b/dojo/cldr/nls/nb/japanese.js
new file mode 100644
index 0000000..3343d59
--- /dev/null
+++ b/dojo/cldr/nls/nb/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d. MMM y G",
+	"field-second": "sekund",
+	"field-year-relative+-1": "I fjor",
+	"field-week": "uke",
+	"field-month-relative+-1": "Sist måned",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i forgårs",
+	"field-year": "år",
+	"field-week-relative+0": "Denne uken",
+	"field-week-relative+1": "Neste uke",
+	"field-minute": "minutt",
+	"field-week-relative+-1": "Sist uke",
+	"field-day-relative+0": "i dag",
+	"field-hour": "time",
+	"field-day-relative+1": "i morgen",
+	"dateFormat-long": "d. MMMM y G",
+	"field-day-relative+2": "i overmorgen",
+	"field-day": "dag",
+	"field-month-relative+0": "Denne måneden",
+	"field-month-relative+1": "Neste måned",
+	"field-dayperiod": "AM/PM",
+	"field-month": "måned",
+	"dateFormat-short": "d.M y G",
+	"field-era": "tidsalder",
+	"field-year-relative+0": "Dette året",
+	"field-year-relative+1": "Neste år",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"field-weekday": "ukedag",
+	"field-zone": "sone"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/number.js b/dojo/cldr/nls/nb/number.js
index b44260a..1dab5d5 100644
--- a/dojo/cldr/nls/nb/number.js
+++ b/dojo/cldr/nls/nb/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0 %",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "¤ #,##0.00",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 billioner",
+	"decimalFormat-short": "000 bill"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/roc.js b/dojo/cldr/nls/nb/roc.js
new file mode 100644
index 0000000..340ad01
--- /dev/null
+++ b/dojo/cldr/nls/nb/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "sekund",
+	"field-year-relative+-1": "I fjor",
+	"field-week": "uke",
+	"field-month-relative+-1": "Sist måned",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i forgårs",
+	"field-year": "år",
+	"field-week-relative+0": "Denne uken",
+	"field-week-relative+1": "Neste uke",
+	"field-minute": "minutt",
+	"field-week-relative+-1": "Sist uke",
+	"field-day-relative+0": "i dag",
+	"field-hour": "time",
+	"field-day-relative+1": "i morgen",
+	"field-day-relative+2": "i overmorgen",
+	"field-day": "dag",
+	"field-month-relative+0": "Denne måneden",
+	"field-month-relative+1": "Neste måned",
+	"field-dayperiod": "AM/PM",
+	"field-month": "måned",
+	"field-era": "tidsalder",
+	"field-year-relative+0": "Dette året",
+	"field-year-relative+1": "Neste år",
+	"eraAbbr": [
+		"Before R.O.C.",
+		"Minguo"
+	],
+	"field-weekday": "ukedag",
+	"field-zone": "sone"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/buddhist.js b/dojo/cldr/nls/nl/buddhist.js
new file mode 100644
index 0000000..200d540
--- /dev/null
+++ b/dojo/cldr/nls/nl/buddhist.js
@@ -0,0 +1,237 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-minute": "Minuut",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "Gisteren",
+	"field-weekday": "Dag van de week",
+	"field-day-relative+-2": "Eergisteren",
+	"days-standAlone-wide": [
+		"zondag",
+		"maandag",
+		"dinsdag",
+		"woensdag",
+		"donderdag",
+		"vrijdag",
+		"zaterdag"
+	],
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-era": "Tijdperk",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Uur",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"jan",
+		"feb",
+		"mrt",
+		"apr",
+		"mei",
+		"jun",
+		"jul",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
+		"dec"
+	],
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "Vandaag",
+	"field-day-relative+1": "Morgen",
+	"days-standAlone-narrow": [
+		"Z",
+		"M",
+		"D",
+		"W",
+		"D",
+		"V",
+		"Z"
+	],
+	"eraAbbr": [
+		"BE"
+	],
+	"field-day-relative+2": "Overmorgen",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Zone",
+	"field-week-relative+-1": "Vorige week",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Dit jaar",
+	"field-year-relative+1": "Volgend jaar",
+	"quarters-standAlone-wide": [
+		"1e kwartaal",
+		"2e kwartaal",
+		"3e kwartaal",
+		"4e kwartaal"
+	],
+	"field-year-relative+-1": "Vorig jaar",
+	"field-year": "Jaar",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"months-standAlone-wide": [
+		"januari",
+		"februari",
+		"maart",
+		"april",
+		"mei",
+		"juni",
+		"juli",
+		"augustus",
+		"september",
+		"oktober",
+		"november",
+		"december"
+	],
+	"field-week": "week",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMd": "d-M-y GGGGG",
+	"dateFormatItem-yyyyMEd": "E d-M-y GGGGG",
+	"field-week-relative+0": "Deze week",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+1": "Volgende week",
+	"months-format-abbr": [
+		"jan.",
+		"feb.",
+		"mrt.",
+		"apr.",
+		"mei",
+		"jun.",
+		"jul.",
+		"aug.",
+		"sep.",
+		"okt.",
+		"nov.",
+		"dec."
+	],
+	"field-month-relative+0": "Deze maand",
+	"field-month": "Maand",
+	"field-month-relative+1": "Volgende maand",
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"days-format-abbr": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"days-format-narrow": [
+		"Z",
+		"M",
+		"D",
+		"W",
+		"D",
+		"V",
+		"Z"
+	],
+	"field-second": "Seconde",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Dag",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E d-M",
+	"months-format-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"days-standAlone-short": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"days-standAlone-abbr": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"dateFormat-short": "dd-MM-yy GGGGG",
+	"dateFormatItem-yyyyM": "M-y GGGGG",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-Md": "d-M",
+	"months-format-wide": [
+		"januari",
+		"februari",
+		"maart",
+		"april",
+		"mei",
+		"juni",
+		"juli",
+		"augustus",
+		"september",
+		"oktober",
+		"november",
+		"december"
+	],
+	"days-format-short": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "Vorige maand",
+	"quarters-format-wide": [
+		"1e kwartaal",
+		"2e kwartaal",
+		"3e kwartaal",
+		"4e kwartaal"
+	],
+	"days-format-wide": [
+		"zondag",
+		"maandag",
+		"dinsdag",
+		"woensdag",
+		"donderdag",
+		"vrijdag",
+		"zaterdag"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/chinese.js b/dojo/cldr/nls/nl/chinese.js
new file mode 100644
index 0000000..56fdb9d
--- /dev/null
+++ b/dojo/cldr/nls/nl/chinese.js
@@ -0,0 +1,66 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d MMM U",
+	"field-dayperiod": "AM/PM",
+	"field-minute": "Minuut",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "Gisteren",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "Eergisteren",
+	"field-weekday": "Dag van de week",
+	"dateFormatItem-MMM": "LLL",
+	"dateFormatItem-Gy": "U",
+	"field-era": "Tijdperk",
+	"field-hour": "Uur",
+	"dateFormatItem-y": "U",
+	"dateFormatItem-yyyy": "U",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "Vandaag",
+	"field-day-relative+1": "Morgen",
+	"field-day-relative+2": "Overmorgen",
+	"dateFormatItem-yyyyMMMM": "MMMM U",
+	"dateFormatItem-GyMMMd": "d MMM U",
+	"dateFormat-long": "d MMMM U",
+	"field-zone": "Zone",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Vorige week",
+	"dateFormat-medium": "d MMM U",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Dit jaar",
+	"field-year-relative+1": "Volgend jaar",
+	"field-year-relative+-1": "Vorig jaar",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ U",
+	"field-year": "Jaar",
+	"field-week": "week",
+	"dateFormatItem-yyyyMd": "d-M-y",
+	"dateFormatItem-yyyyMMMd": "d MMM U",
+	"dateFormatItem-yyyyMEd": "E d-M-y",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Deze week",
+	"field-week-relative+1": "Volgende week",
+	"field-month-relative+0": "Deze maand",
+	"dateFormatItem-H": "HH",
+	"field-month": "Maand",
+	"field-month-relative+1": "Volgende maand",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-M": "L",
+	"field-second": "Seconde",
+	"dateFormatItem-GyMMMEd": "E d MMM U",
+	"dateFormatItem-GyMMM": "MMM U",
+	"field-day": "Dag",
+	"dateFormatItem-yyyyQQQ": "QQQ U",
+	"dateFormatItem-MEd": "E d-M",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd-MM-yy",
+	"dateFormatItem-yyyyM": "M-y",
+	"dateFormat-full": "EEEE d MMMM U",
+	"dateFormatItem-Md": "d-M",
+	"dateFormatItem-yyyyMMM": "MMM U",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Vorige maand",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/currency.js b/dojo/cldr/nls/nl/currency.js
index 7cb9e68..c424091 100644
--- a/dojo/cldr/nls/nl/currency.js
+++ b/dojo/cldr/nls/nl/currency.js
@@ -2,13 +2,20 @@ define(
 //begin v1.x content
 {
 	"HKD_displayName": "Hongkongse dollar",
-	"CHF_displayName": "Zwitserse franc",
+	"CHF_displayName": "Zwitserse frank",
+	"JPY_symbol": "JP¥",
 	"CAD_displayName": "Canadese dollar",
+	"HKD_symbol": "HK$",
 	"CNY_displayName": "Chinese yuan renminbi",
+	"USD_symbol": "US$",
 	"AUD_displayName": "Australische dollar",
 	"JPY_displayName": "Japanse yen",
+	"CAD_symbol": "C$",
 	"USD_displayName": "Amerikaanse dollar",
+	"EUR_symbol": "€",
+	"CNY_symbol": "CN¥",
 	"GBP_displayName": "Brits pond sterling",
+	"AUD_symbol": "AU $",
 	"EUR_displayName": "Euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/nl/generic.js b/dojo/cldr/nls/nl/generic.js
new file mode 100644
index 0000000..10d9301
--- /dev/null
+++ b/dojo/cldr/nls/nl/generic.js
@@ -0,0 +1,70 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-dayperiod": "AM/PM",
+	"field-minute": "Minuut",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "Gisteren",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "Eergisteren",
+	"field-weekday": "Dag van de week",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "Tijdperk",
+	"field-hour": "Uur",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "Vandaag",
+	"field-day-relative+1": "Morgen",
+	"field-day-relative+2": "Overmorgen",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Zone",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Vorige week",
+	"dateFormat-medium": "d MMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Dit jaar",
+	"field-year-relative+1": "Volgend jaar",
+	"field-year-relative+-1": "Vorig jaar",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-year": "Jaar",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "week",
+	"dateFormatItem-yyyyMd": "d-M-y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMEd": "E d-M-y GGGGG",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Deze week",
+	"field-week-relative+1": "Volgende week",
+	"field-month-relative+0": "Deze maand",
+	"dateFormatItem-H": "HH",
+	"field-month": "Maand",
+	"field-month-relative+1": "Volgende maand",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-M": "L",
+	"field-second": "Seconde",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Dag",
+	"dateFormatItem-MEd": "E d-M",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd-MM-yy GGGGG",
+	"dateFormatItem-yyyyM": "M-y GGGGG",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-Md": "d-M",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Vorige maand",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/gregorian.js b/dojo/cldr/nls/nl/gregorian.js
index a3cde89..c5c5f30 100644
--- a/dojo/cldr/nls/nl/gregorian.js
+++ b/dojo/cldr/nls/nl/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
 	"months-format-narrow": [
 		"J",
 		"F",
@@ -15,14 +24,29 @@ define(
 		"N",
 		"D"
 	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "Dag van de week",
-	"dateFormatItem-yyQQQQ": "QQQQ yy",
 	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "EEE d-M-y",
+	"dateFormatItem-yMEd": "E d-M-y",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
 	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
-		"v. Chr.",
-		"n. Chr."
+		"v.Chr.",
+		"n.Chr."
+	],
+	"days-format-short": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
 	],
 	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
@@ -39,9 +63,12 @@ define(
 		"november",
 		"december"
 	],
+	"dateTimeFormat-medium": "{1} {0}",
 	"dayPeriods-format-wide-pm": "PM",
 	"dateFormat-full": "EEEE d MMMM y",
 	"dateFormatItem-Md": "d-M",
+	"dayPeriods-format-wide-noon": "12 uur 's middags",
+	"dateFormatItem-yMd": "d-M-y",
 	"field-era": "Tijdperk",
 	"dateFormatItem-yM": "M-y",
 	"months-standAlone-wide": [
@@ -65,13 +92,11 @@ define(
 		"3e kwartaal",
 		"4e kwartaal"
 	],
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-long": "HH:mm:ss z",
 	"field-year": "Jaar",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "Q yyyy",
-	"dateFormatItem-yyyyMMMM": "MMMM y",
 	"field-hour": "Uur",
-	"dateFormatItem-MMdd": "dd-MM",
 	"months-format-abbr": [
 		"jan.",
 		"feb.",
@@ -86,25 +111,25 @@ define(
 		"nov.",
 		"dec."
 	],
-	"dateFormatItem-yyQ": "Q yy",
 	"timeFormat-full": "HH:mm:ss zzzz",
-	"field-day-relative+0": "vandaag",
-	"field-day-relative+1": "morgen",
-	"field-day-relative+2": "overmorgen",
-	"field-day-relative+3": "overovermorgen",
+	"field-day-relative+0": "Vandaag",
+	"field-day-relative+1": "Morgen",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "Overmorgen",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
-		"jan.",
-		"feb.",
-		"mrt.",
-		"apr.",
+		"jan",
+		"feb",
+		"mrt",
+		"apr",
 		"mei",
-		"jun.",
-		"jul.",
-		"aug.",
-		"sep.",
-		"okt.",
-		"nov.",
-		"dec."
+		"jun",
+		"jul",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
+		"dec"
 	],
 	"quarters-format-abbr": [
 		"K1",
@@ -118,6 +143,7 @@ define(
 		"3e kwartaal",
 		"4e kwartaal"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
 		"zondag",
@@ -129,7 +155,7 @@ define(
 		"zaterdag"
 	],
 	"dateFormatItem-MMMMd": "d MMMM",
-	"dateFormatItem-yyMMM": "MMM yy",
+	"dayPeriods-format-abbr-noon": "12 uur 's middags",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -139,8 +165,8 @@ define(
 		"K4"
 	],
 	"eraAbbr": [
-		"v. Chr.",
-		"n. Chr."
+		"v.Chr.",
+		"n.Chr."
 	],
 	"field-minute": "Minuut",
 	"field-dayperiod": "AM/PM",
@@ -155,11 +181,20 @@ define(
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
-	"field-day-relative+-1": "gisteren",
-	"field-day-relative+-2": "eergisteren",
-	"field-day-relative+-3": "eereergisteren",
-	"dateFormatItem-MMMd": "d-MMM",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Gisteren",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-day-relative+-2": "Eergisteren",
+	"dateFormatItem-MMMd": "d MMM",
 	"dateFormatItem-MEd": "E d-M",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-yMMMM": "MMMM y",
 	"field-day": "Dag",
 	"days-format-wide": [
 		"zondag",
@@ -186,7 +221,9 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-yyMM": "MM-yy",
+	"field-year-relative+-1": "Vorig jaar",
+	"field-month-relative+-1": "Vorige maand",
+	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
 		"zo",
 		"ma",
@@ -196,6 +233,7 @@ define(
 		"vr",
 		"za"
 	],
+	"dateFormatItem-yMMMd": "d MMM y",
 	"eraNames": [
 		"Voor Christus",
 		"na Christus"
@@ -209,7 +247,6 @@ define(
 		"V",
 		"Z"
 	],
-	"field-month": "Maand",
 	"days-standAlone-narrow": [
 		"Z",
 		"M",
@@ -220,14 +257,26 @@ define(
 		"Z"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "Maand",
 	"dayPeriods-format-wide-am": "AM",
 	"dateFormat-short": "dd-MM-yy",
-	"dateFormatItem-MMd": "d-MM",
+	"dayPeriods-format-narrow-noon": "n",
 	"field-second": "Seconde",
-	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"dateFormatItem-yMMMEd": "E d MMM y",
+	"field-month-relative+0": "Deze maand",
+	"field-month-relative+1": "Volgende maand",
 	"dateFormatItem-Ed": "E d",
-	"field-week": "Week",
-	"dateFormat-medium": "d MMM y"
+	"field-week": "week",
+	"dateFormat-medium": "d MMM y",
+	"field-year-relative+0": "Dit jaar",
+	"field-week-relative+-1": "Vorige week",
+	"field-year-relative+1": "Volgend jaar",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "Deze week",
+	"field-week-relative+1": "Volgende week"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/hebrew.js b/dojo/cldr/nls/nl/hebrew.js
new file mode 100644
index 0000000..671787a
--- /dev/null
+++ b/dojo/cldr/nls/nl/hebrew.js
@@ -0,0 +1,211 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-minute": "Minuut",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "Gisteren",
+	"field-weekday": "Dag van de week",
+	"field-day-relative+-2": "Eergisteren",
+	"days-standAlone-wide": [
+		"zondag",
+		"maandag",
+		"dinsdag",
+		"woensdag",
+		"donderdag",
+		"vrijdag",
+		"zaterdag"
+	],
+	"field-era": "Tijdperk",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Uur",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Tisjrie",
+		"Chesjwan",
+		"Kislev",
+		"Tevet",
+		"Sjevat",
+		"Adar A",
+		"Adar",
+		"Nisan",
+		"Ijar",
+		"Sivan",
+		"Tammoez",
+		"Av",
+		"Elloel"
+	],
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "Vandaag",
+	"field-day-relative+1": "Morgen",
+	"days-standAlone-narrow": [
+		"Z",
+		"M",
+		"D",
+		"W",
+		"D",
+		"V",
+		"Z"
+	],
+	"field-day-relative+2": "Overmorgen",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Zone",
+	"field-week-relative+-1": "Vorige week",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Dit jaar",
+	"field-year-relative+1": "Volgend jaar",
+	"quarters-standAlone-wide": [
+		"1e kwartaal",
+		"2e kwartaal",
+		"3e kwartaal",
+		"4e kwartaal"
+	],
+	"field-year-relative+-1": "Vorig jaar",
+	"field-year": "Jaar",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"months-standAlone-wide": [
+		"Tisjrie",
+		"Chesjwan",
+		"Kislev",
+		"Tevet",
+		"Sjevat",
+		"Adar A",
+		"Adar",
+		"Nisan",
+		"Ijar",
+		"Sivan",
+		"Tammoez",
+		"Av",
+		"Elloel"
+	],
+	"field-week": "week",
+	"dateFormatItem-yyyyMd": "d-M-y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMEd": "E d-M-y GGGGG",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Deze week",
+	"field-week-relative+1": "Volgende week",
+	"months-format-abbr": [
+		"Tisjrie",
+		"Chesjwan",
+		"Kislev",
+		"Tevet",
+		"Sjevat",
+		"Adar A",
+		"Adar",
+		"Nisan",
+		"Ijar",
+		"Sivan",
+		"Tammoez",
+		"Av",
+		"Elloel"
+	],
+	"field-month-relative+0": "Deze maand",
+	"field-month": "Maand",
+	"field-month-relative+1": "Volgende maand",
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"days-format-abbr": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"days-format-narrow": [
+		"Z",
+		"M",
+		"D",
+		"W",
+		"D",
+		"V",
+		"Z"
+	],
+	"field-second": "Seconde",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Dag",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E d-M",
+	"days-standAlone-short": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"days-standAlone-abbr": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"dateFormat-short": "dd-MM-yy GGGGG",
+	"dateFormatItem-yyyyM": "M-y GGGGG",
+	"dateFormatItem-Md": "d-M",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"months-format-wide": [
+		"Tisjrie",
+		"Chesjwan",
+		"Kislev",
+		"Tevet",
+		"Sjevat",
+		"Adar A",
+		"Adar",
+		"Nisan",
+		"Ijar",
+		"Sivan",
+		"Tammoez",
+		"Av",
+		"Elloel"
+	],
+	"days-format-short": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"months-format-wide-leap": "Adar B",
+	"field-month-relative+-1": "Vorige maand",
+	"quarters-format-wide": [
+		"1e kwartaal",
+		"2e kwartaal",
+		"3e kwartaal",
+		"4e kwartaal"
+	],
+	"days-format-wide": [
+		"zondag",
+		"maandag",
+		"dinsdag",
+		"woensdag",
+		"donderdag",
+		"vrijdag",
+		"zaterdag"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/islamic.js b/dojo/cldr/nls/nl/islamic.js
new file mode 100644
index 0000000..35449c7
--- /dev/null
+++ b/dojo/cldr/nls/nl/islamic.js
@@ -0,0 +1,229 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-minute": "Minuut",
+	"eraNames": [
+		"Saʻna Hizjria"
+	],
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "Gisteren",
+	"field-weekday": "Dag van de week",
+	"field-day-relative+-2": "Eergisteren",
+	"days-standAlone-wide": [
+		"zondag",
+		"maandag",
+		"dinsdag",
+		"woensdag",
+		"donderdag",
+		"vrijdag",
+		"zaterdag"
+	],
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-era": "Tijdperk",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Uur",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Moeh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Joem. I",
+		"Joem. II",
+		"Raj.",
+		"Sja.",
+		"Ram.",
+		"Sjaw.",
+		"Doe al k.",
+		"Doe al h."
+	],
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "Vandaag",
+	"field-day-relative+1": "Morgen",
+	"days-standAlone-narrow": [
+		"Z",
+		"M",
+		"D",
+		"W",
+		"D",
+		"V",
+		"Z"
+	],
+	"eraAbbr": [
+		"Saʻna Hizjria"
+	],
+	"field-day-relative+2": "Overmorgen",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Zone",
+	"field-week-relative+-1": "Vorige week",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Dit jaar",
+	"field-year-relative+1": "Volgend jaar",
+	"quarters-standAlone-wide": [
+		"1e kwartaal",
+		"2e kwartaal",
+		"3e kwartaal",
+		"4e kwartaal"
+	],
+	"field-year-relative+-1": "Vorig jaar",
+	"field-year": "Jaar",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"months-standAlone-wide": [
+		"Moeharram",
+		"Safar",
+		"Rabiʻa al awal",
+		"Rabiʻa al thani",
+		"Joemadʻal awal",
+		"Joemadʻal thani",
+		"Rajab",
+		"Sjaʻaban",
+		"Ramadan",
+		"Sjawal",
+		"Doe al kaʻaba",
+		"Doe al hizja"
+	],
+	"field-week": "week",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMd": "d-M-y GGGGG",
+	"dateFormatItem-yyyyMEd": "E d-M-y GGGGG",
+	"field-week-relative+0": "Deze week",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+1": "Volgende week",
+	"months-format-abbr": [
+		"Moeh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Joem. I",
+		"Joem. II",
+		"Raj.",
+		"Sja.",
+		"Ram.",
+		"Sjaw.",
+		"Doe al k.",
+		"Doe al h."
+	],
+	"field-month-relative+0": "Deze maand",
+	"field-month": "Maand",
+	"field-month-relative+1": "Volgende maand",
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"days-format-abbr": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"days-format-narrow": [
+		"Z",
+		"M",
+		"D",
+		"W",
+		"D",
+		"V",
+		"Z"
+	],
+	"field-second": "Seconde",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Dag",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E d-M",
+	"days-standAlone-short": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"days-standAlone-abbr": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"dateFormat-short": "dd-MM-yy GGGGG",
+	"dateFormatItem-yyyyM": "M-y GGGGG",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-Md": "d-M",
+	"months-format-wide": [
+		"Moeharram",
+		"Safar",
+		"Rabiʻa al awal",
+		"Rabiʻa al thani",
+		"Joemadʻal awal",
+		"Joemadʻal thani",
+		"Rajab",
+		"Sjaʻaban",
+		"Ramadan",
+		"Sjawal",
+		"Doe al kaʻaba",
+		"Doe al hizja"
+	],
+	"days-format-short": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "Vorige maand",
+	"quarters-format-wide": [
+		"1e kwartaal",
+		"2e kwartaal",
+		"3e kwartaal",
+		"4e kwartaal"
+	],
+	"eraNarrow": [
+		"Saʻna Hizjria"
+	],
+	"days-format-wide": [
+		"zondag",
+		"maandag",
+		"dinsdag",
+		"woensdag",
+		"donderdag",
+		"vrijdag",
+		"zaterdag"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/japanese.js b/dojo/cldr/nls/nl/japanese.js
new file mode 100644
index 0000000..7580473
--- /dev/null
+++ b/dojo/cldr/nls/nl/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d MMM y G",
+	"field-second": "Seconde",
+	"field-year-relative+-1": "Vorig jaar",
+	"field-week": "week",
+	"field-month-relative+-1": "Vorige maand",
+	"field-day-relative+-1": "Gisteren",
+	"field-day-relative+-2": "Eergisteren",
+	"field-year": "Jaar",
+	"field-week-relative+0": "Deze week",
+	"field-week-relative+1": "Volgende week",
+	"field-minute": "Minuut",
+	"field-week-relative+-1": "Vorige week",
+	"field-day-relative+0": "Vandaag",
+	"field-hour": "Uur",
+	"field-day-relative+1": "Morgen",
+	"dateFormat-long": "d MMMM y G",
+	"field-day-relative+2": "Overmorgen",
+	"field-day": "Dag",
+	"field-month-relative+0": "Deze maand",
+	"field-month-relative+1": "Volgende maand",
+	"field-dayperiod": "AM/PM",
+	"field-month": "Maand",
+	"dateFormat-short": "dd-MM-yy GGGGG",
+	"field-era": "Tijdperk",
+	"field-year-relative+0": "Dit jaar",
+	"field-year-relative+1": "Volgend jaar",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"field-weekday": "Dag van de week",
+	"field-zone": "Zone"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/number.js b/dojo/cldr/nls/nl/number.js
index 1aac8f7..4898ad8 100644
--- a/dojo/cldr/nls/nl/number.js
+++ b/dojo/cldr/nls/nl/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0%",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "¤ #,##0.00;¤ #,##0.00-",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 biljoen",
+	"decimalFormat-short": "000 bln'.'"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/roc.js b/dojo/cldr/nls/nl/roc.js
new file mode 100644
index 0000000..9e05fc0
--- /dev/null
+++ b/dojo/cldr/nls/nl/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Seconde",
+	"field-year-relative+-1": "Vorig jaar",
+	"field-week": "week",
+	"field-month-relative+-1": "Vorige maand",
+	"field-day-relative+-1": "Gisteren",
+	"field-day-relative+-2": "Eergisteren",
+	"field-year": "Jaar",
+	"field-week-relative+0": "Deze week",
+	"field-week-relative+1": "Volgende week",
+	"field-minute": "Minuut",
+	"field-week-relative+-1": "Vorige week",
+	"field-day-relative+0": "Vandaag",
+	"field-hour": "Uur",
+	"field-day-relative+1": "Morgen",
+	"field-day-relative+2": "Overmorgen",
+	"field-day": "Dag",
+	"field-month-relative+0": "Deze maand",
+	"field-month-relative+1": "Volgende maand",
+	"field-dayperiod": "AM/PM",
+	"field-month": "Maand",
+	"field-era": "Tijdperk",
+	"field-year-relative+0": "Dit jaar",
+	"field-year-relative+1": "Volgend jaar",
+	"eraAbbr": [
+		"Before R.O.C.",
+		"Minguo"
+	],
+	"field-weekday": "Dag van de week",
+	"field-zone": "Zone"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/number.js b/dojo/cldr/nls/number.js
index f62a3d1..0a57abe 100644
--- a/dojo/cldr/nls/number.js
+++ b/dojo/cldr/nls/number.js
@@ -3,7 +3,7 @@ define({ root:
 //begin v1.x content
 {
 	"scientificFormat": "#E0",
-	"currencySpacing-afterCurrency-currencyMatch": "[:letter:]",
+	"currencySpacing-afterCurrency-currencyMatch": "[:^S:]",
 	"infinity": "∞",
 	"list": ";",
 	"percentSign": "%",
@@ -12,17 +12,16 @@ define({ root:
 	"decimalFormat-short": "000T",
 	"currencySpacing-afterCurrency-insertBetween": " ",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"plusSign": "+",
 	"currencySpacing-afterCurrency-surroundingMatch": "[:digit:]",
-	"currencySpacing-beforeCurrency-currencyMatch": "[:letter:]",
+	"currencySpacing-beforeCurrency-currencyMatch": "[:^S:]",
 	"currencyFormat": "¤ #,##0.00",
 	"perMille": "‰",
 	"group": ",",
 	"percentFormat": "#,##0%",
+	"decimalFormat-long": "000T",
 	"decimalFormat": "#,##0.###",
 	"decimal": ".",
-	"patternDigit": "#",
 	"currencySpacing-beforeCurrency-insertBetween": " ",
 	"exponential": "E"
 }
@@ -35,7 +34,6 @@ define({ root:
 	"de": true,
 	"el": true,
 	"en": true,
-	"en-au": true,
 	"en-gb": true,
 	"es": true,
 	"fi": true,
@@ -60,5 +58,6 @@ define({ root:
 	"tr": true,
 	"zh": true,
 	"zh-hant": true,
-	"zh-hk": true
+	"zh-hk": true,
+	"zh-tw": true
 });
\ No newline at end of file
diff --git a/dojo/cldr/nls/persian.js b/dojo/cldr/nls/persian.js
new file mode 100644
index 0000000..c847f89
--- /dev/null
+++ b/dojo/cldr/nls/persian.js
@@ -0,0 +1,292 @@
+define({ root:
+
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
+	"eraNarrow": [
+		"AP"
+	],
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "G y MMMM d",
+	"months-format-wide": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordad",
+		"Tir",
+		"Mordad",
+		"Shahrivar",
+		"Mehr",
+		"Aban",
+		"Azar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"dateFormatItem-Md": "MM-dd",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordad",
+		"Tir",
+		"Mordad",
+		"Shahrivar",
+		"Mehr",
+		"Aban",
+		"Azar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
+	"months-format-abbr": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordad",
+		"Tir",
+		"Mordad",
+		"Shahrivar",
+		"Mehr",
+		"Aban",
+		"Azar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
+	"dateFormatItem-H": "HH",
+	"months-standAlone-abbr": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordad",
+		"Tir",
+		"Mordad",
+		"Shahrivar",
+		"Mehr",
+		"Aban",
+		"Azar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"eraAbbr": [
+		"AP"
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Yesterday",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "MM-dd, E",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"field-zone": "Zone",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dateFormatItem-y": "G y",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"eraNames": [
+		"AP"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"field-second": "Second",
+	"dateFormatItem-Ed": "d, E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "G y MMM",
+	"dateFormatItem-yyyy": "G y"
+}
+//end v1.x content
+,
+	"ar": true,
+	"hu": true,
+	"ja": true,
+	"pl": true,
+	"pt": true,
+	"ru": true,
+	"sv": true,
+	"th": true,
+	"tr": true,
+	"zh": true,
+	"zh-hant": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/buddhist.js b/dojo/cldr/nls/pl/buddhist.js
new file mode 100644
index 0000000..c6d99e6
--- /dev/null
+++ b/dojo/cldr/nls/pl/buddhist.js
@@ -0,0 +1,248 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"months-format-narrow": [
+		"s",
+		"l",
+		"m",
+		"k",
+		"m",
+		"c",
+		"l",
+		"s",
+		"w",
+		"p",
+		"l",
+		"g"
+	],
+	"quarters-standAlone-narrow": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"field-weekday": "Dzień tygodnia",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"days-format-short": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"dateFormat-long": "d MMMM y G",
+	"months-format-wide": [
+		"stycznia",
+		"lutego",
+		"marca",
+		"kwietnia",
+		"maja",
+		"czerwca",
+		"lipca",
+		"sierpnia",
+		"września",
+		"października",
+		"listopada",
+		"grudnia"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormatItem-yyyyMEd": "E, d.MM.y G",
+	"dateFormatItem-Md": "d.MM",
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"styczeń",
+		"luty",
+		"marzec",
+		"kwiecień",
+		"maj",
+		"czerwiec",
+		"lipiec",
+		"sierpień",
+		"wrzesień",
+		"październik",
+		"listopad",
+		"grudzień"
+	],
+	"quarters-format-wide": [
+		"I kwartał",
+		"II kwartał",
+		"III kwartał",
+		"IV kwartał"
+	],
+	"field-year": "Rok",
+	"field-hour": "Godzina",
+	"months-format-abbr": [
+		"sty",
+		"lut",
+		"mar",
+		"kwi",
+		"maj",
+		"cze",
+		"lip",
+		"sie",
+		"wrz",
+		"paź",
+		"lis",
+		"gru"
+	],
+	"field-day-relative+0": "Dzisiaj",
+	"field-day-relative+1": "Jutro",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "Pojutrze",
+	"months-standAlone-abbr": [
+		"sty",
+		"lut",
+		"mar",
+		"kwi",
+		"maj",
+		"cze",
+		"lip",
+		"sie",
+		"wrz",
+		"paź",
+		"lis",
+		"gru"
+	],
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"quarters-standAlone-wide": [
+		"I kwartał",
+		"II kwartał",
+		"III kwartał",
+		"IV kwartał"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E, d MMM y G",
+	"days-standAlone-wide": [
+		"niedziela",
+		"poniedziałek",
+		"wtorek",
+		"środa",
+		"czwartek",
+		"piątek",
+		"sobota"
+	],
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"quarters-standAlone-abbr": [
+		"1 kw.",
+		"2 kw.",
+		"3 kw.",
+		"4 kw."
+	],
+	"eraAbbr": [
+		"BE"
+	],
+	"field-minute": "Minuta",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"field-day-relative+-1": "Wczoraj",
+	"dateFormatItem-h": "hh a",
+	"field-day-relative+-2": "Przedwczoraj",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d.MM",
+	"field-day": "Dzień",
+	"days-format-wide": [
+		"niedziela",
+		"poniedziałek",
+		"wtorek",
+		"środa",
+		"czwartek",
+		"piątek",
+		"sobota"
+	],
+	"field-zone": "Strefa",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"s",
+		"l",
+		"m",
+		"k",
+		"m",
+		"c",
+		"l",
+		"s",
+		"w",
+		"p",
+		"l",
+		"g"
+	],
+	"field-year-relative+-1": "Zeszły rok",
+	"field-month-relative+-1": "Zeszły miesiąc",
+	"dateFormatItem-hm": "hh:mm a",
+	"days-format-abbr": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"days-format-narrow": [
+		"N",
+		"P",
+		"W",
+		"Ś",
+		"C",
+		"P",
+		"S"
+	],
+	"dateFormatItem-yyyyMd": "d.MM.y G",
+	"field-month": "Miesiąc",
+	"days-standAlone-narrow": [
+		"N",
+		"P",
+		"W",
+		"Ś",
+		"C",
+		"P",
+		"S"
+	],
+	"dateFormat-short": "dd.MM.y G",
+	"field-second": "Sekunda",
+	"field-month-relative+0": "Bieżący miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
+	"dateFormatItem-Ed": "E, d",
+	"field-week": "Tydzień",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Bieżący rok",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"field-year-relative+1": "Przyszły rok",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "Bieżący tydzień",
+	"field-week-relative+1": "Przyszły tydzień"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/chinese.js b/dojo/cldr/nls/pl/chinese.js
new file mode 100644
index 0000000..5226ef2
--- /dev/null
+++ b/dojo/cldr/nls/pl/chinese.js
@@ -0,0 +1,91 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d MMM U",
+	"field-second": "Sekunda",
+	"field-year-relative+-1": "Zeszły rok",
+	"field-week": "Tydzień",
+	"field-month-relative+-1": "Zeszły miesiąc",
+	"field-day-relative+-1": "Wczoraj",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "Przedwczoraj",
+	"months-standAlone-wide": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year": "Rok",
+	"field-week-relative+0": "Bieżący tydzień",
+	"months-standAlone-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-week-relative+1": "Przyszły tydzień",
+	"field-minute": "Minuta",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"field-day-relative+0": "Dzisiaj",
+	"field-hour": "Godzina",
+	"field-day-relative+1": "Jutro",
+	"dateFormat-long": "d MMMM U",
+	"field-day-relative+2": "Pojutrze",
+	"field-day": "Dzień",
+	"field-month-relative+0": "Bieżący miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
+	"field-dayperiod": "Dayperiod",
+	"field-month": "Miesiąc",
+	"dateFormat-short": "dd.MM.y",
+	"field-era": "Era",
+	"field-year-relative+0": "Bieżący rok",
+	"field-year-relative+1": "Przyszły rok",
+	"months-format-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormat-full": "EEEE, d MMMM U",
+	"field-weekday": "Dzień tygodnia",
+	"field-zone": "Strefa"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/coptic.js b/dojo/cldr/nls/pl/coptic.js
new file mode 100644
index 0000000..b91acc9
--- /dev/null
+++ b/dojo/cldr/nls/pl/coptic.js
@@ -0,0 +1,91 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Sekunda",
+	"field-year-relative+-1": "Zeszły rok",
+	"field-week": "Tydzień",
+	"field-month-relative+-1": "Zeszły miesiąc",
+	"field-day-relative+-1": "Wczoraj",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "Przedwczoraj",
+	"months-standAlone-wide": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"field-year": "Rok",
+	"field-week-relative+0": "Bieżący tydzień",
+	"months-standAlone-abbr": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"field-week-relative+1": "Przyszły tydzień",
+	"field-minute": "Minuta",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"field-day-relative+0": "Dzisiaj",
+	"field-hour": "Godzina",
+	"field-day-relative+1": "Jutro",
+	"field-day-relative+2": "Pojutrze",
+	"field-day": "Dzień",
+	"field-month-relative+0": "Bieżący miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
+	"field-dayperiod": "Dayperiod",
+	"field-month": "Miesiąc",
+	"field-era": "Era",
+	"field-year-relative+0": "Bieżący rok",
+	"field-year-relative+1": "Przyszły rok",
+	"months-format-abbr": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"field-weekday": "Dzień tygodnia",
+	"field-zone": "Strefa"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/currency.js b/dojo/cldr/nls/pl/currency.js
index 2393e22..c2850b0 100644
--- a/dojo/cldr/nls/pl/currency.js
+++ b/dojo/cldr/nls/pl/currency.js
@@ -7,8 +7,9 @@ define(
 	"CNY_displayName": "juan renminbi",
 	"AUD_displayName": "dolar australijski",
 	"JPY_displayName": "jen japoński",
-	"USD_displayName": "dolar amerykański ",
+	"USD_displayName": "dolar amerykański",
 	"GBP_displayName": "funt szterling",
+	"AUD_symbol": "A$",
 	"EUR_displayName": "euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/pl/ethiopic.js b/dojo/cldr/nls/pl/ethiopic.js
new file mode 100644
index 0000000..c25cc0f
--- /dev/null
+++ b/dojo/cldr/nls/pl/ethiopic.js
@@ -0,0 +1,91 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Sekunda",
+	"field-year-relative+-1": "Zeszły rok",
+	"field-week": "Tydzień",
+	"field-month-relative+-1": "Zeszły miesiąc",
+	"field-day-relative+-1": "Wczoraj",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "Przedwczoraj",
+	"months-standAlone-wide": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"field-year": "Rok",
+	"field-week-relative+0": "Bieżący tydzień",
+	"months-standAlone-abbr": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"field-week-relative+1": "Przyszły tydzień",
+	"field-minute": "Minuta",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"field-day-relative+0": "Dzisiaj",
+	"field-hour": "Godzina",
+	"field-day-relative+1": "Jutro",
+	"field-day-relative+2": "Pojutrze",
+	"field-day": "Dzień",
+	"field-month-relative+0": "Bieżący miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
+	"field-dayperiod": "Dayperiod",
+	"field-month": "Miesiąc",
+	"field-era": "Era",
+	"field-year-relative+0": "Bieżący rok",
+	"field-year-relative+1": "Przyszły rok",
+	"months-format-abbr": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"field-weekday": "Dzień tygodnia",
+	"field-zone": "Strefa"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/generic.js b/dojo/cldr/nls/pl/generic.js
new file mode 100644
index 0000000..6743e93
--- /dev/null
+++ b/dojo/cldr/nls/pl/generic.js
@@ -0,0 +1,72 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d MMM y G",
+	"field-dayperiod": "Dayperiod",
+	"field-minute": "Minuta",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "Wczoraj",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"dateFormatItem-MMdd": "d.MM",
+	"field-day-relative+-2": "Przedwczoraj",
+	"field-weekday": "Dzień tygodnia",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"field-era": "Era",
+	"field-hour": "Godzina",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E, d",
+	"field-day-relative+0": "Dzisiaj",
+	"field-day-relative+1": "Jutro",
+	"field-day-relative+2": "Pojutrze",
+	"dateFormatItem-yyyyMM": "MM.y G",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMMMM": "LLLL y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Strefa",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"dateFormat-medium": "d MMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Bieżący rok",
+	"field-year-relative+1": "Przyszły rok",
+	"field-year-relative+-1": "Zeszły rok",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"field-year": "Rok",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "Tydzień",
+	"dateFormatItem-yyyyMd": "d.MM.y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMEd": "E, d.MM.y G",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Bieżący tydzień",
+	"field-week-relative+1": "Przyszły tydzień",
+	"field-month-relative+0": "Bieżący miesiąc",
+	"dateFormatItem-H": "HH",
+	"field-month": "Miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-M": "L",
+	"field-second": "Sekunda",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"field-day": "Dzień",
+	"dateFormatItem-MEd": "E, d.MM",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "hh:mm a",
+	"dateFormat-short": "dd.MM.y G",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormatItem-Md": "d.MM",
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Zeszły miesiąc",
+	"dateFormatItem-h": "hh a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/gregorian.js b/dojo/cldr/nls/pl/gregorian.js
index d87be4c..0084749 100644
--- a/dojo/cldr/nls/pl/gregorian.js
+++ b/dojo/cldr/nls/pl/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
 	"months-format-narrow": [
 		"s",
 		"l",
@@ -15,16 +24,32 @@ define(
 		"l",
 		"g"
 	],
+	"quarters-standAlone-narrow": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
 	"field-weekday": "Dzień tygodnia",
-	"dateFormatItem-yQQQ": "y QQQ",
-	"dateFormatItem-yMEd": "EEE, d.MM.yyyy",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "E, d.MM.y",
 	"dateFormatItem-MMMEd": "E, d MMM",
 	"eraNarrow": [
 		"p.n.e.",
 		"n.e."
 	],
+	"dateFormatItem-yMM": "MM.y",
 	"dayPeriods-format-wide-earlyMorning": "nad ranem",
 	"dayPeriods-format-wide-morning": "rano",
+	"days-format-short": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
 	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
 		"stycznia",
@@ -41,12 +66,14 @@ define(
 		"grudnia"
 	],
 	"dayPeriods-format-wide-evening": "wieczorem",
+	"dateTimeFormat-medium": "{1}, {0}",
 	"dayPeriods-format-wide-pm": "PM",
 	"dateFormat-full": "EEEE, d MMMM y",
 	"dateFormatItem-Md": "d.MM",
 	"dayPeriods-format-wide-noon": "w południe",
+	"dateFormatItem-yMd": "d.MM.y",
 	"field-era": "Era",
-	"dateFormatItem-yM": "MM.yyyy",
+	"dateFormatItem-yM": "MM.y",
 	"months-standAlone-wide": [
 		"styczeń",
 		"luty",
@@ -68,10 +95,10 @@ define(
 		"III kwartał",
 		"IV kwartał"
 	],
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-long": "HH:mm:ss z",
 	"field-year": "Rok",
-	"dateFormatItem-yQ": "yyyy Q",
-	"dateFormatItem-yyyyMMMM": "LLLL y",
+	"dateFormatItem-yMMM": "LLL y",
 	"field-hour": "Godzina",
 	"dateFormatItem-MMdd": "d.MM",
 	"months-format-abbr": [
@@ -88,12 +115,11 @@ define(
 		"lis",
 		"gru"
 	],
-	"dateFormatItem-yyQ": "Q yy",
 	"timeFormat-full": "HH:mm:ss zzzz",
 	"field-day-relative+0": "Dzisiaj",
 	"field-day-relative+1": "Jutro",
 	"field-day-relative+2": "Pojutrze",
-	"field-day-relative+3": "Za trzy dni",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
 		"sty",
 		"lut",
@@ -131,7 +157,6 @@ define(
 		"sobota"
 	],
 	"dateFormatItem-MMMMd": "d MMMM",
-	"dateFormatItem-yyMMM": "MMM yy",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -158,13 +183,20 @@ define(
 	"dayPeriods-format-wide-night": "w nocy",
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "Wczoraj",
 	"dateFormatItem-h": "hh a",
+	"dateTimeFormat-long": "{1} {0}",
 	"field-day-relative+-2": "Przedwczoraj",
-	"field-day-relative+-3": "Trzy dni temu",
 	"dateFormatItem-MMMd": "d MMM",
 	"dateFormatItem-MEd": "E, d.MM",
 	"dayPeriods-format-wide-lateMorning": "przed południem",
+	"dateTimeFormat-full": "{1} {0}",
 	"dateFormatItem-yMMMM": "LLLL y",
 	"field-day": "Dzień",
 	"days-format-wide": [
@@ -177,7 +209,6 @@ define(
 		"sobota"
 	],
 	"field-zone": "Strefa",
-	"dateFormatItem-yyyyMM": "MM.yyyy",
 	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
 		"s",
@@ -193,6 +224,8 @@ define(
 		"l",
 		"g"
 	],
+	"field-year-relative+-1": "Zeszły rok",
+	"field-month-relative+-1": "Zeszły miesiąc",
 	"dateFormatItem-hm": "hh:mm a",
 	"days-format-abbr": [
 		"niedz.",
@@ -203,6 +236,7 @@ define(
 		"pt.",
 		"sob."
 	],
+	"dateFormatItem-yMMMd": "d MMM y",
 	"eraNames": [
 		"p.n.e.",
 		"n.e."
@@ -216,7 +250,6 @@ define(
 		"P",
 		"S"
 	],
-	"field-month": "Miesiąc",
 	"days-standAlone-narrow": [
 		"N",
 		"P",
@@ -227,16 +260,25 @@ define(
 		"S"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "Miesiąc",
 	"dayPeriods-format-wide-am": "AM",
-	"dateFormat-short": "dd.MM.yyyy",
+	"dateFormat-short": "dd.MM.y",
 	"dayPeriods-format-wide-afternoon": "po południu",
 	"field-second": "Sekunda",
-	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"dateFormatItem-yMMMEd": "E, d MMM y",
+	"field-month-relative+0": "Bieżący miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
 	"dateFormatItem-Ed": "E, d",
 	"field-week": "Tydzień",
 	"dateFormat-medium": "d MMM y",
+	"field-year-relative+0": "Bieżący rok",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"field-year-relative+1": "Przyszły rok",
+	"dateTimeFormat-short": "{1}, {0}",
 	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-hms": "hh:mm:ss a"
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"field-week-relative+0": "Bieżący tydzień",
+	"field-week-relative+1": "Przyszły tydzień"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/hebrew.js b/dojo/cldr/nls/pl/hebrew.js
new file mode 100644
index 0000000..560e852
--- /dev/null
+++ b/dojo/cldr/nls/pl/hebrew.js
@@ -0,0 +1,224 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"quarters-standAlone-narrow": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"field-weekday": "Dzień tygodnia",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"days-format-short": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"dateFormat-long": "d MMMM y G",
+	"months-format-wide": [
+		"Tiszri",
+		"Cheszwan",
+		"Kislew",
+		"Tewet",
+		"Szwat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Ijar",
+		"Siwan",
+		"Tamuz",
+		"Aw",
+		"Elul"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormatItem-yyyyMEd": "E, d.MM.y G",
+	"dateFormatItem-Md": "d.MM",
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Tiszri",
+		"Cheszwan",
+		"Kislew",
+		"Tewet",
+		"Szwat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Ijar",
+		"Siwan",
+		"Tamuz",
+		"Aw",
+		"Elul"
+	],
+	"quarters-format-wide": [
+		"I kwartał",
+		"II kwartał",
+		"III kwartał",
+		"IV kwartał"
+	],
+	"field-year": "Rok",
+	"field-hour": "Godzina",
+	"months-format-abbr-leap": "Adar II",
+	"months-format-abbr": [
+		"Tiszri",
+		"Cheszwan",
+		"Kislew",
+		"Tewet",
+		"Szwat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Ijar",
+		"Siwan",
+		"Tamuz",
+		"Aw",
+		"Elul"
+	],
+	"field-day-relative+0": "Dzisiaj",
+	"field-day-relative+1": "Jutro",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "Pojutrze",
+	"months-standAlone-abbr": [
+		"Tiszri",
+		"Cheszwan",
+		"Kislew",
+		"Tewet",
+		"Szwat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Ijar",
+		"Siwan",
+		"Tamuz",
+		"Aw",
+		"Elul"
+	],
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"quarters-standAlone-wide": [
+		"I kwartał",
+		"II kwartał",
+		"III kwartał",
+		"IV kwartał"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E, d MMM y G",
+	"days-standAlone-wide": [
+		"niedziela",
+		"poniedziałek",
+		"wtorek",
+		"środa",
+		"czwartek",
+		"piątek",
+		"sobota"
+	],
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"months-standAlone-wide-leap": "Adar II",
+	"quarters-standAlone-abbr": [
+		"1 kw.",
+		"2 kw.",
+		"3 kw.",
+		"4 kw."
+	],
+	"field-minute": "Minuta",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"field-day-relative+-1": "Wczoraj",
+	"dateFormatItem-h": "hh a",
+	"field-day-relative+-2": "Przedwczoraj",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d.MM",
+	"field-day": "Dzień",
+	"days-format-wide": [
+		"niedziela",
+		"poniedziałek",
+		"wtorek",
+		"środa",
+		"czwartek",
+		"piątek",
+		"sobota"
+	],
+	"field-zone": "Strefa",
+	"dateFormatItem-y": "y G",
+	"field-year-relative+-1": "Zeszły rok",
+	"field-month-relative+-1": "Zeszły miesiąc",
+	"dateFormatItem-hm": "hh:mm a",
+	"days-format-abbr": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"days-format-narrow": [
+		"N",
+		"P",
+		"W",
+		"Ś",
+		"C",
+		"P",
+		"S"
+	],
+	"dateFormatItem-yyyyMd": "d.MM.y G",
+	"field-month": "Miesiąc",
+	"days-standAlone-narrow": [
+		"N",
+		"P",
+		"W",
+		"Ś",
+		"C",
+		"P",
+		"S"
+	],
+	"dateFormat-short": "dd.MM.y G",
+	"field-second": "Sekunda",
+	"field-month-relative+0": "Bieżący miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
+	"dateFormatItem-Ed": "E, d",
+	"field-week": "Tydzień",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Bieżący rok",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"field-year-relative+1": "Przyszły rok",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"months-format-wide-leap": "Adar II",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "Bieżący tydzień",
+	"field-week-relative+1": "Przyszły tydzień"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/indian.js b/dojo/cldr/nls/pl/indian.js
new file mode 100644
index 0000000..80af78a
--- /dev/null
+++ b/dojo/cldr/nls/pl/indian.js
@@ -0,0 +1,87 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Sekunda",
+	"field-year-relative+-1": "Zeszły rok",
+	"field-week": "Tydzień",
+	"field-month-relative+-1": "Zeszły miesiąc",
+	"field-day-relative+-1": "Wczoraj",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "Przedwczoraj",
+	"months-standAlone-wide": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"field-year": "Rok",
+	"field-week-relative+0": "Bieżący tydzień",
+	"months-standAlone-abbr": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"field-week-relative+1": "Przyszły tydzień",
+	"field-minute": "Minuta",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"field-day-relative+0": "Dzisiaj",
+	"field-hour": "Godzina",
+	"field-day-relative+1": "Jutro",
+	"field-day-relative+2": "Pojutrze",
+	"field-day": "Dzień",
+	"field-month-relative+0": "Bieżący miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
+	"field-dayperiod": "Dayperiod",
+	"field-month": "Miesiąc",
+	"field-era": "Era",
+	"field-year-relative+0": "Bieżący rok",
+	"field-year-relative+1": "Przyszły rok",
+	"months-format-abbr": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"field-weekday": "Dzień tygodnia",
+	"field-zone": "Strefa"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/islamic.js b/dojo/cldr/nls/pl/islamic.js
new file mode 100644
index 0000000..2054ef7
--- /dev/null
+++ b/dojo/cldr/nls/pl/islamic.js
@@ -0,0 +1,231 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "Dayperiod",
+	"dateFormatItem-yyyyMMMEd": "E, d MMM y G",
+	"field-minute": "Minuta",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"field-day-relative+-1": "Wczoraj",
+	"field-weekday": "Dzień tygodnia",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"field-day-relative+-2": "Przedwczoraj",
+	"days-standAlone-wide": [
+		"niedziela",
+		"poniedziałek",
+		"wtorek",
+		"środa",
+		"czwartek",
+		"piątek",
+		"sobota"
+	],
+	"dateTimeFormat-short": "{1}, {0}",
+	"field-era": "Era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Godzina",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"quarters-standAlone-abbr": [
+		"1 kw.",
+		"2 kw.",
+		"3 kw.",
+		"4 kw."
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Dżu. I",
+		"Dżu. II",
+		"Ra.",
+		"Sza.",
+		"Ram.",
+		"Szaw.",
+		"Zu al-k.",
+		"Zu al-h."
+	],
+	"dateFormatItem-Ed": "E, d",
+	"field-day-relative+0": "Dzisiaj",
+	"field-day-relative+1": "Jutro",
+	"days-standAlone-narrow": [
+		"N",
+		"P",
+		"W",
+		"Ś",
+		"C",
+		"P",
+		"S"
+	],
+	"field-day-relative+2": "Pojutrze",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Strefa",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Bieżący rok",
+	"field-year-relative+1": "Przyszły rok",
+	"quarters-standAlone-wide": [
+		"I kwartał",
+		"II kwartał",
+		"III kwartał",
+		"IV kwartał"
+	],
+	"field-year-relative+-1": "Zeszły rok",
+	"field-year": "Rok",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"quarters-standAlone-narrow": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"months-standAlone-wide": [
+		"Muharram",
+		"Safar",
+		"Rabi I",
+		"Rabi II",
+		"Dżumada I",
+		"Dżumada II",
+		"Radżab",
+		"Szaban",
+		"Ramadan",
+		"Szawwal",
+		"Zu al-kada",
+		"Zu al-hidżdża"
+	],
+	"field-week": "Tydzień",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMd": "d.MM.y G",
+	"dateFormatItem-yyyyMEd": "E, d.MM.y G",
+	"field-week-relative+0": "Bieżący tydzień",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+1": "Przyszły tydzień",
+	"months-format-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Dżu. I",
+		"Dżu. II",
+		"Ra.",
+		"Sza.",
+		"Ram.",
+		"Szaw.",
+		"Zu al-k.",
+		"Zu al-h."
+	],
+	"field-month-relative+0": "Bieżący miesiąc",
+	"field-month": "Miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"days-format-abbr": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"days-format-narrow": [
+		"N",
+		"P",
+		"W",
+		"Ś",
+		"C",
+		"P",
+		"S"
+	],
+	"field-second": "Sekunda",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"field-day": "Dzień",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E, d.MM",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"days-standAlone-short": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"dateFormatItem-hm": "hh:mm a",
+	"days-standAlone-abbr": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"dateFormat-short": "dd.MM.y G",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormatItem-Md": "d.MM",
+	"months-format-wide": [
+		"Muharram",
+		"Safar",
+		"Rabi I",
+		"Rabi II",
+		"Dżumada I",
+		"Dżumada II",
+		"Radżab",
+		"Szaban",
+		"Ramadan",
+		"Szawwal",
+		"Zu al-kada",
+		"Zu al-hidżdża"
+	],
+	"days-format-short": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"field-month-relative+-1": "Zeszły miesiąc",
+	"quarters-format-wide": [
+		"I kwartał",
+		"II kwartał",
+		"III kwartał",
+		"IV kwartał"
+	],
+	"days-format-wide": [
+		"niedziela",
+		"poniedziałek",
+		"wtorek",
+		"środa",
+		"czwartek",
+		"piątek",
+		"sobota"
+	],
+	"dateFormatItem-h": "hh a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/japanese.js b/dojo/cldr/nls/pl/japanese.js
new file mode 100644
index 0000000..9a53590
--- /dev/null
+++ b/dojo/cldr/nls/pl/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d MMM y G",
+	"field-second": "Sekunda",
+	"field-year-relative+-1": "Zeszły rok",
+	"field-week": "Tydzień",
+	"field-month-relative+-1": "Zeszły miesiąc",
+	"field-day-relative+-1": "Wczoraj",
+	"field-day-relative+-2": "Przedwczoraj",
+	"field-year": "Rok",
+	"field-week-relative+0": "Bieżący tydzień",
+	"field-week-relative+1": "Przyszły tydzień",
+	"field-minute": "Minuta",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"field-day-relative+0": "Dzisiaj",
+	"field-hour": "Godzina",
+	"field-day-relative+1": "Jutro",
+	"dateFormat-long": "d MMMM y G",
+	"field-day-relative+2": "Pojutrze",
+	"field-day": "Dzień",
+	"field-month-relative+0": "Bieżący miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
+	"field-dayperiod": "Dayperiod",
+	"field-month": "Miesiąc",
+	"dateFormat-short": "dd.MM.y G",
+	"field-era": "Era",
+	"field-year-relative+0": "Bieżący rok",
+	"field-year-relative+1": "Przyszły rok",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"field-weekday": "Dzień tygodnia",
+	"field-zone": "Strefa"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/number.js b/dojo/cldr/nls/pl/number.js
index f16715c..d0be6d7 100644
--- a/dojo/cldr/nls/pl/number.js
+++ b/dojo/cldr/nls/pl/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0%",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
-	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"currencyFormat": "#,##0.00 ¤;(#,##0.00 ¤)",
+	"plusSign": "+",
+	"decimalFormat-long": "000 biliona",
+	"decimalFormat-short": "000 bln"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/persian.js b/dojo/cldr/nls/pl/persian.js
new file mode 100644
index 0000000..f896513
--- /dev/null
+++ b/dojo/cldr/nls/pl/persian.js
@@ -0,0 +1,245 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"field-weekday": "Dzień tygodnia",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"days-format-short": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"dateFormat-long": "d MMMM y G",
+	"months-format-wide": [
+		"Farwardin",
+		"Ordibeheszt",
+		"Chordād",
+		"Tir",
+		"Mordād",
+		"Szahriwar",
+		"Mehr",
+		"Ābān",
+		"Āsar",
+		"Déi",
+		"Bahman",
+		"Esfand"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormatItem-yyyyMEd": "E, d.MM.y G",
+	"dateFormatItem-Md": "d.MM",
+	"field-era": "Era",
+	"months-standAlone-wide": [
+		"Farwardin",
+		"Ordibeheszt",
+		"Chordād",
+		"Tir",
+		"Mordād",
+		"Szahriwar",
+		"Mehr",
+		"Ābān",
+		"Āsar",
+		"Déi",
+		"Bahman",
+		"Esfand"
+	],
+	"quarters-format-wide": [
+		"I kwartał",
+		"II kwartał",
+		"III kwartał",
+		"IV kwartał"
+	],
+	"field-year": "Rok",
+	"field-hour": "Godzina",
+	"months-format-abbr": [
+		"Farwardin",
+		"Ordibeheszt",
+		"Chordād",
+		"Tir",
+		"Mordād",
+		"Szahriwar",
+		"Mehr",
+		"Ābān",
+		"Āsar",
+		"Déi",
+		"Bahman",
+		"Esfand"
+	],
+	"field-day-relative+0": "Dzisiaj",
+	"field-day-relative+1": "Jutro",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "Pojutrze",
+	"months-standAlone-abbr": [
+		"Farwardin",
+		"Ordibeheszt",
+		"Chordād",
+		"Tir",
+		"Mordād",
+		"Szahriwar",
+		"Mehr",
+		"Ābān",
+		"Āsar",
+		"Déi",
+		"Bahman",
+		"Esfand"
+	],
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"quarters-standAlone-wide": [
+		"I kwartał",
+		"II kwartał",
+		"III kwartał",
+		"IV kwartał"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E, d MMM y G",
+	"days-standAlone-wide": [
+		"niedziela",
+		"poniedziałek",
+		"wtorek",
+		"środa",
+		"czwartek",
+		"piątek",
+		"sobota"
+	],
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"quarters-standAlone-abbr": [
+		"1 kw.",
+		"2 kw.",
+		"3 kw.",
+		"4 kw."
+	],
+	"field-minute": "Minuta",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"field-day-relative+-1": "Wczoraj",
+	"dateFormatItem-h": "hh a",
+	"field-day-relative+-2": "Przedwczoraj",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d.MM",
+	"field-day": "Dzień",
+	"days-format-wide": [
+		"niedziela",
+		"poniedziałek",
+		"wtorek",
+		"środa",
+		"czwartek",
+		"piątek",
+		"sobota"
+	],
+	"field-zone": "Strefa",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"s",
+		"l",
+		"m",
+		"k",
+		"m",
+		"c",
+		"l",
+		"s",
+		"w",
+		"p",
+		"l",
+		"g"
+	],
+	"field-year-relative+-1": "Zeszły rok",
+	"field-month-relative+-1": "Zeszły miesiąc",
+	"dateFormatItem-hm": "hh:mm a",
+	"days-format-abbr": [
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
+		"sob."
+	],
+	"days-format-narrow": [
+		"N",
+		"P",
+		"W",
+		"Ś",
+		"C",
+		"P",
+		"S"
+	],
+	"dateFormatItem-yyyyMd": "d.MM.y G",
+	"field-month": "Miesiąc",
+	"days-standAlone-narrow": [
+		"N",
+		"P",
+		"W",
+		"Ś",
+		"C",
+		"P",
+		"S"
+	],
+	"dateFormat-short": "dd.MM.y G",
+	"field-second": "Sekunda",
+	"field-month-relative+0": "Bieżący miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
+	"dateFormatItem-Ed": "E, d",
+	"field-week": "Tydzień",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Bieżący rok",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"field-year-relative+1": "Przyszły rok",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "Bieżący tydzień",
+	"field-week-relative+1": "Przyszły tydzień"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/roc.js b/dojo/cldr/nls/pl/roc.js
new file mode 100644
index 0000000..2613aed
--- /dev/null
+++ b/dojo/cldr/nls/pl/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Sekunda",
+	"field-year-relative+-1": "Zeszły rok",
+	"field-week": "Tydzień",
+	"field-month-relative+-1": "Zeszły miesiąc",
+	"field-day-relative+-1": "Wczoraj",
+	"field-day-relative+-2": "Przedwczoraj",
+	"field-year": "Rok",
+	"field-week-relative+0": "Bieżący tydzień",
+	"field-week-relative+1": "Przyszły tydzień",
+	"field-minute": "Minuta",
+	"field-week-relative+-1": "Zeszły tydzień",
+	"field-day-relative+0": "Dzisiaj",
+	"field-hour": "Godzina",
+	"field-day-relative+1": "Jutro",
+	"field-day-relative+2": "Pojutrze",
+	"field-day": "Dzień",
+	"field-month-relative+0": "Bieżący miesiąc",
+	"field-month-relative+1": "Przyszły miesiąc",
+	"field-dayperiod": "Dayperiod",
+	"field-month": "Miesiąc",
+	"field-era": "Era",
+	"field-year-relative+0": "Bieżący rok",
+	"field-year-relative+1": "Przyszły rok",
+	"eraAbbr": [
+		"Przed ROC",
+		"ROC"
+	],
+	"field-weekday": "Dzień tygodnia",
+	"field-zone": "Strefa"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/buddhist.js b/dojo/cldr/nls/pt-pt/buddhist.js
new file mode 100644
index 0000000..b6973fa
--- /dev/null
+++ b/dojo/cldr/nls/pt-pt/buddhist.js
@@ -0,0 +1,218 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d/MM/y G",
+	"dateFormatItem-MMMEd": "E, d/MM",
+	"dateTimeFormat-full": "{1} 'às' {0}",
+	"days-standAlone-wide": [
+		"Domingo",
+		"Segunda-feira",
+		"Terça-feira",
+		"Quarta-feira",
+		"Quinta-feira",
+		"Sexta-feira",
+		"Sábado"
+	],
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Jan",
+		"Fev",
+		"Mar",
+		"Abr",
+		"Mai",
+		"Jun",
+		"Jul",
+		"Ago",
+		"Set",
+		"Out",
+		"Nov",
+		"Dez"
+	],
+	"dateFormatItem-Ed": "E, d",
+	"days-standAlone-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"dateFormatItem-GyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-zone": "Fuso horário",
+	"dateFormat-medium": "dd/MM/y G",
+	"dayPeriods-format-narrow-pm": "p.m.",
+	"quarters-standAlone-wide": [
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
+		"4º trimestre"
+	],
+	"dateFormatItem-yyyyQQQQ": "QQQQ 'de' y G",
+	"dayPeriods-format-narrow-am": "a.m.",
+	"dateTimeFormat-long": "{1} 'às' {0}",
+	"months-standAlone-wide": [
+		"Janeiro",
+		"Fevereiro",
+		"Março",
+		"Abril",
+		"Maio",
+		"Junho",
+		"Julho",
+		"Agosto",
+		"Setembro",
+		"Outubro",
+		"Novembro",
+		"Dezembro"
+	],
+	"dateFormatItem-yyyyMd": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d/MM/y G",
+	"dateFormatItem-yyyyMEd": "E, dd/MM/y GGGGG",
+	"dateFormatItem-MMMd": "d/MM",
+	"months-format-abbr": [
+		"Jan",
+		"Fev",
+		"Mar",
+		"Abr",
+		"Mai",
+		"Jun",
+		"Jul",
+		"Ago",
+		"Set",
+		"Out",
+		"Nov",
+		"Dez"
+	],
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-format-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM 'de' y G",
+	"dateFormatItem-yyyyQQQ": "QQQQ 'de' y G",
+	"dateFormatItem-MEd": "E, dd/MM",
+	"months-format-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"days-standAlone-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-standAlone-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"dayPeriods-format-abbr-pm": "p.m.",
+	"dateFormat-short": "d/M/y G",
+	"dateFormatItem-yyyyM": "MM/y GGGGG",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"dateFormatItem-Md": "d/M",
+	"months-format-wide": [
+		"Janeiro",
+		"Fevereiro",
+		"Março",
+		"Abril",
+		"Maio",
+		"Junho",
+		"Julho",
+		"Agosto",
+		"Setembro",
+		"Outubro",
+		"Novembro",
+		"Dezembro"
+	],
+	"dayPeriods-format-abbr-am": "a.m.",
+	"days-format-short": [
+		"Do",
+		"Sg",
+		"Te",
+		"Qu",
+		"Qi",
+		"Sx",
+		"Sb"
+	],
+	"dateFormatItem-yyyyMMM": "MM/y G",
+	"quarters-format-wide": [
+		"1.º trimestre",
+		"2.º trimestre",
+		"3.º trimestre",
+		"4.º trimestre"
+	],
+	"days-format-wide": [
+		"Domingo",
+		"Segunda-feira",
+		"Terça-feira",
+		"Quarta-feira",
+		"Quinta-feira",
+		"Sexta-feira",
+		"Sábado"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/currency.js b/dojo/cldr/nls/pt-pt/currency.js
new file mode 100644
index 0000000..dd588dc
--- /dev/null
+++ b/dojo/cldr/nls/pt-pt/currency.js
@@ -0,0 +1,8 @@
+define(
+//begin v1.x content
+{
+	"CAD_displayName": "Dólar canadiano",
+	"USD_displayName": "Dólar dos Estados Unidos"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/generic.js b/dojo/cldr/nls/pt-pt/generic.js
new file mode 100644
index 0000000..c526c00
--- /dev/null
+++ b/dojo/cldr/nls/pt-pt/generic.js
@@ -0,0 +1,25 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEEEEd": "EEEE, d/MM/y",
+	"dateFormatItem-MMMEd": "E, d/MM",
+	"dateFormatItem-yyyyMMM": "MM/y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dateFormatItem-yyyyQQQQ": "QQQQ 'de' y G",
+	"dateFormatItem-yyyyMMMEd": "E, d/MM/y G",
+	"dateFormatItem-MMMMEd": "E, d 'de' MMMM",
+	"dateFormatItem-yyyyMMMM": "MMMM 'de' y G",
+	"dateFormatItem-MMMMd": "d 'de' MMMM",
+	"dateTimeFormat-long": "{1} 'às' {0}",
+	"dateFormatItem-yyyyMMMMd": "d 'de' MMMM 'de' y G",
+	"dateFormatItem-yyyyQQQ": "QQQQ 'de' y G",
+	"dateFormatItem-yyyyMMMMEd": "E, d 'de' MMMM 'de' y G",
+	"dateFormat-short": "d/M/y G",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateTimeFormat-full": "{1} 'às' {0}",
+	"dateFormatItem-yyyyMMMd": "d/MM/y G",
+	"dateFormatItem-MMMd": "d/MM",
+	"field-zone": "Fuso horário"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/gregorian.js b/dojo/cldr/nls/pt-pt/gregorian.js
index 7152396..ac28fe4 100644
--- a/dojo/cldr/nls/pt-pt/gregorian.js
+++ b/dojo/cldr/nls/pt-pt/gregorian.js
@@ -1,46 +1,30 @@
 define(
 //begin v1.x content
 {
-	"quarters-standAlone-wide": [
-		"1.º trimestre",
-		"2.º trimestre",
-		"3.º trimestre",
-		"4.º trimestre"
-	],
-	"quarters-format-abbr": [
-		"1.º trimestre",
-		"2.º trimestre",
-		"3.º trimestre",
-		"4.º trimestre"
+	"dayPeriods-format-wide-pm": "PM",
+	"dayPeriods-standAlone-abbr-pm": "p.m.",
+	"dateFormatItem-MMMEd": "E, d/MM",
+	"dateTimeFormat-full": "{1} 'às' {0}",
+	"dateFormatItem-yQQQ": "QQQQ 'de' y",
+	"days-standAlone-wide": [
+		"Domingo",
+		"Segunda-feira",
+		"Terça-feira",
+		"Quarta-feira",
+		"Quinta-feira",
+		"Sexta-feira",
+		"Sábado"
 	],
-	"dayPeriods-standAlone-wide-am": "a.m.",
-	"dateFormat-medium": "d 'de' MMM 'de' yyyy",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dayPeriods-standAlone-abbr-am": "a.m.",
 	"quarters-standAlone-abbr": [
 		"1.º trimestre",
 		"2.º trimestre",
 		"3.º trimestre",
 		"4.º trimestre"
 	],
-	"dateFormatItem-Hm": "HH:mm",
-	"dayPeriods-standAlone-abbr-pm": "p.m.",
-	"dateFormatItem-HHmmss": "HH:mm:ss",
-	"dateFormatItem-hm": "h:mm a",
-	"months-standAlone-wide": [
-		"Janeiro",
-		"Fevereiro",
-		"Março",
-		"Abril",
-		"Maio",
-		"Junho",
-		"Julho",
-		"Agosto",
-		"Setembro",
-		"Outubro",
-		"Novembro",
-		"Dezembro"
-	],
-	"dayPeriods-standAlone-abbr-am": "a.m.",
-	"dayPeriods-format-wide-pm": "Depois do meio-dia",
 	"months-standAlone-abbr": [
 		"Jan",
 		"Fev",
@@ -55,14 +39,24 @@ define(
 		"Nov",
 		"Dez"
 	],
-	"dateFormatItem-yQQQ": "QQQ 'de' y",
-	"dayPeriods-format-wide-am": "Antes do meio-dia",
-	"dateFormatItem-Hms": "HH:mm:ss",
-	"dayPeriods-format-abbr-pm": "p.m.",
-	"dateFormatItem-yyQ": "QQQ 'de' yy",
-	"dateFormatItem-ms": "mm:ss",
-	"dayPeriods-format-abbr-am": "a.m.",
-	"months-format-wide": [
+	"dayPeriods-standAlone-wide-pm": "p.m.",
+	"dateFormatItem-yMMM": "MM/y",
+	"dateFormatItem-yMMMMEd": "E, d 'de' MMMM 'de' y",
+	"field-zone": "Fuso horário",
+	"dayPeriods-standAlone-wide-am": "a.m.",
+	"dayPeriods-format-narrow-pm": "p.m.",
+	"dateFormatItem-yMMMEEEEd": "EEEE, d/MM/y",
+	"quarters-standAlone-wide": [
+		"1.º trimestre",
+		"2.º trimestre",
+		"3.º trimestre",
+		"4.º trimestre"
+	],
+	"dateFormatItem-yMMMM": "MMMM 'de' y",
+	"dateFormatItem-yMMMMd": "d 'de' MMMM 'de' y",
+	"dayPeriods-format-narrow-am": "a.m.",
+	"dateTimeFormat-long": "{1} 'às' {0}",
+	"months-standAlone-wide": [
 		"Janeiro",
 		"Fevereiro",
 		"Março",
@@ -76,16 +70,8 @@ define(
 		"Novembro",
 		"Dezembro"
 	],
-	"days-standAlone-wide": [
-		"Domingo",
-		"Segunda-feira",
-		"Terça-feira",
-		"Quarta-feira",
-		"Quinta-feira",
-		"Sexta-feira",
-		"Sábado"
-	],
-	"dateFormatItem-HHmm": "HH:mm",
+	"dateFormatItem-MMMMEd": "E, d 'de' MMMM",
+	"dateFormatItem-MMMd": "d/MM",
 	"months-format-abbr": [
 		"Jan",
 		"Fev",
@@ -100,7 +86,15 @@ define(
 		"Nov",
 		"Dez"
 	],
-	"days-standAlone-abbr": [
+	"dateFormatItem-yQQQQ": "QQQQ 'de' y",
+	"dateFormatItem-MMMMd": "d 'de' MMMM",
+	"quarters-format-abbr": [
+		"1.º trimestre",
+		"2.º trimestre",
+		"3.º trimestre",
+		"4.º trimestre"
+	],
+	"days-format-abbr": [
 		"Domingo",
 		"Segunda-feira",
 		"Terça-feira",
@@ -109,7 +103,17 @@ define(
 		"Sexta-feira",
 		"Sábado"
 	],
-	"days-format-wide": [
+	"dateFormatItem-yMMMd": "d/MM/y",
+	"days-standAlone-short": [
+		"Do",
+		"Sg",
+		"Te",
+		"Qu",
+		"Qi",
+		"Sx",
+		"Sb"
+	],
+	"days-standAlone-abbr": [
 		"Domingo",
 		"Segunda-feira",
 		"Terça-feira",
@@ -118,16 +122,39 @@ define(
 		"Sexta-feira",
 		"Sábado"
 	],
-	"dateFormatItem-hms": "h:mm:ss a",
-	"dateFormatItem-yQ": "QQQ 'de' yyyy",
+	"dayPeriods-format-abbr-pm": "p.m.",
+	"dateFormatItem-yMMMEd": "E, d/MM/y",
+	"months-format-wide": [
+		"Janeiro",
+		"Fevereiro",
+		"Março",
+		"Abril",
+		"Maio",
+		"Junho",
+		"Julho",
+		"Agosto",
+		"Setembro",
+		"Outubro",
+		"Novembro",
+		"Dezembro"
+	],
+	"dayPeriods-format-abbr-am": "a.m.",
+	"days-format-short": [
+		"Do",
+		"Sg",
+		"Te",
+		"Qu",
+		"Qi",
+		"Sx",
+		"Sb"
+	],
 	"quarters-format-wide": [
 		"1.º trimestre",
 		"2.º trimestre",
 		"3.º trimestre",
 		"4.º trimestre"
 	],
-	"dayPeriods-standAlone-wide-pm": "p.m.",
-	"days-format-abbr": [
+	"days-format-wide": [
 		"Domingo",
 		"Segunda-feira",
 		"Terça-feira",
diff --git a/dojo/cldr/nls/pt-pt/hebrew.js b/dojo/cldr/nls/pt-pt/hebrew.js
new file mode 100644
index 0000000..3825c7a
--- /dev/null
+++ b/dojo/cldr/nls/pt-pt/hebrew.js
@@ -0,0 +1,134 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d/MM/y G",
+	"dateFormatItem-MMMEd": "E, d/MM",
+	"dateTimeFormat-full": "{1} 'às' {0}",
+	"days-standAlone-wide": [
+		"Domingo",
+		"Segunda-feira",
+		"Terça-feira",
+		"Quarta-feira",
+		"Quinta-feira",
+		"Sexta-feira",
+		"Sábado"
+	],
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E, d",
+	"days-standAlone-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"dateFormatItem-GyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-zone": "Fuso horário",
+	"dateFormat-medium": "dd/MM/y G",
+	"dayPeriods-format-narrow-pm": "p.m.",
+	"quarters-standAlone-wide": [
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
+		"4º trimestre"
+	],
+	"dateFormatItem-yyyyQQQQ": "QQQQ 'de' y G",
+	"dayPeriods-format-narrow-am": "a.m.",
+	"dateTimeFormat-long": "{1} 'às' {0}",
+	"dateFormatItem-yyyyMd": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d/MM/y G",
+	"dateFormatItem-yyyyMEd": "E, dd/MM/y GGGGG",
+	"dateFormatItem-MMMd": "d/MM",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-format-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM 'de' y G",
+	"dateFormatItem-yyyyQQQ": "QQQQ 'de' y G",
+	"dateFormatItem-MEd": "E, dd/MM",
+	"days-standAlone-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-standAlone-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"dayPeriods-format-abbr-pm": "p.m.",
+	"dateFormat-short": "d/M/y G",
+	"dateFormatItem-yyyyM": "MM/y GGGGG",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"dateFormatItem-Md": "d/M",
+	"dayPeriods-format-abbr-am": "a.m.",
+	"days-format-short": [
+		"Do",
+		"Sg",
+		"Te",
+		"Qu",
+		"Qi",
+		"Sx",
+		"Sb"
+	],
+	"dateFormatItem-yyyyMMM": "MM/y G",
+	"quarters-format-wide": [
+		"1.º trimestre",
+		"2.º trimestre",
+		"3.º trimestre",
+		"4.º trimestre"
+	],
+	"days-format-wide": [
+		"Domingo",
+		"Segunda-feira",
+		"Terça-feira",
+		"Quarta-feira",
+		"Quinta-feira",
+		"Sexta-feira",
+		"Sábado"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/islamic.js b/dojo/cldr/nls/pt-pt/islamic.js
new file mode 100644
index 0000000..3825c7a
--- /dev/null
+++ b/dojo/cldr/nls/pt-pt/islamic.js
@@ -0,0 +1,134 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d/MM/y G",
+	"dateFormatItem-MMMEd": "E, d/MM",
+	"dateTimeFormat-full": "{1} 'às' {0}",
+	"days-standAlone-wide": [
+		"Domingo",
+		"Segunda-feira",
+		"Terça-feira",
+		"Quarta-feira",
+		"Quinta-feira",
+		"Sexta-feira",
+		"Sábado"
+	],
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E, d",
+	"days-standAlone-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"dateFormatItem-GyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-zone": "Fuso horário",
+	"dateFormat-medium": "dd/MM/y G",
+	"dayPeriods-format-narrow-pm": "p.m.",
+	"quarters-standAlone-wide": [
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
+		"4º trimestre"
+	],
+	"dateFormatItem-yyyyQQQQ": "QQQQ 'de' y G",
+	"dayPeriods-format-narrow-am": "a.m.",
+	"dateTimeFormat-long": "{1} 'às' {0}",
+	"dateFormatItem-yyyyMd": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d/MM/y G",
+	"dateFormatItem-yyyyMEd": "E, dd/MM/y GGGGG",
+	"dateFormatItem-MMMd": "d/MM",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-format-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM 'de' y G",
+	"dateFormatItem-yyyyQQQ": "QQQQ 'de' y G",
+	"dateFormatItem-MEd": "E, dd/MM",
+	"days-standAlone-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-standAlone-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"dayPeriods-format-abbr-pm": "p.m.",
+	"dateFormat-short": "d/M/y G",
+	"dateFormatItem-yyyyM": "MM/y GGGGG",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"dateFormatItem-Md": "d/M",
+	"dayPeriods-format-abbr-am": "a.m.",
+	"days-format-short": [
+		"Do",
+		"Sg",
+		"Te",
+		"Qu",
+		"Qi",
+		"Sx",
+		"Sb"
+	],
+	"dateFormatItem-yyyyMMM": "MM/y G",
+	"quarters-format-wide": [
+		"1.º trimestre",
+		"2.º trimestre",
+		"3.º trimestre",
+		"4.º trimestre"
+	],
+	"days-format-wide": [
+		"Domingo",
+		"Segunda-feira",
+		"Terça-feira",
+		"Quarta-feira",
+		"Quinta-feira",
+		"Sexta-feira",
+		"Sábado"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/japanese.js b/dojo/cldr/nls/pt-pt/japanese.js
new file mode 100644
index 0000000..4adf6ce
--- /dev/null
+++ b/dojo/cldr/nls/pt-pt/japanese.js
@@ -0,0 +1,8 @@
+define(
+//begin v1.x content
+{
+	"field-zone": "Fuso horário",
+	"dateFormat-short": "d/M/y G"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/number.js b/dojo/cldr/nls/pt-pt/number.js
index d9ed12d..e57de63 100644
--- a/dojo/cldr/nls/pt-pt/number.js
+++ b/dojo/cldr/nls/pt-pt/number.js
@@ -1,8 +1,11 @@
 define(
 //begin v1.x content
 {
+	"group": " ",
+	"decimalFormat-long": "000 biliões",
 	"currencyFormat": "#,##0.00 ¤",
-	"group": " "
+	"decimalFormat-short": "000 Bi",
+	"decimal": ","
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/roc.js b/dojo/cldr/nls/pt-pt/roc.js
new file mode 100644
index 0000000..4adf6ce
--- /dev/null
+++ b/dojo/cldr/nls/pt-pt/roc.js
@@ -0,0 +1,8 @@
+define(
+//begin v1.x content
+{
+	"field-zone": "Fuso horário",
+	"dateFormat-short": "d/M/y G"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/buddhist.js b/dojo/cldr/nls/pt/buddhist.js
new file mode 100644
index 0000000..80d8e4e
--- /dev/null
+++ b/dojo/cldr/nls/pt/buddhist.js
@@ -0,0 +1,237 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "Período do dia",
+	"dateFormatItem-yyyyMMMEd": "E, d 'de' MMM 'de' y G",
+	"field-minute": "Minuto",
+	"dateFormatItem-MMMEd": "E, d 'de' MMM",
+	"field-day-relative+-1": "Ontem",
+	"field-weekday": "Dia da semana",
+	"field-day-relative+-2": "Anteontem",
+	"days-standAlone-wide": [
+		"domingo",
+		"segunda-feira",
+		"terça-feira",
+		"quarta-feira",
+		"quinta-feira",
+		"sexta-feira",
+		"sábado"
+	],
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-era": "Era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Hora",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"jan",
+		"fev",
+		"mar",
+		"abr",
+		"mai",
+		"jun",
+		"jul",
+		"ago",
+		"set",
+		"out",
+		"nov",
+		"dez"
+	],
+	"dateFormatItem-Ed": "E, d",
+	"field-day-relative+0": "Hoje",
+	"field-day-relative+1": "Amanhã",
+	"days-standAlone-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"eraAbbr": [
+		"BE"
+	],
+	"field-day-relative+2": "Depois de amanhã",
+	"dateFormatItem-GyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-zone": "Fuso",
+	"field-week-relative+-1": "Semana passada",
+	"dateFormat-medium": "dd/MM/y G",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "Este ano",
+	"field-year-relative+1": "Próximo ano",
+	"quarters-standAlone-wide": [
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
+		"4º trimestre"
+	],
+	"field-year-relative+-1": "Ano passado",
+	"field-year": "Ano",
+	"dayPeriods-format-narrow-am": "a",
+	"field-week": "Semana",
+	"months-standAlone-wide": [
+		"janeiro",
+		"fevereiro",
+		"março",
+		"abril",
+		"maio",
+		"junho",
+		"julho",
+		"agosto",
+		"setembro",
+		"outubro",
+		"novembro",
+		"dezembro"
+	],
+	"dateFormatItem-yyyyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormatItem-yyyyMd": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyMEd": "E, dd/MM/y GGGGG",
+	"field-week-relative+0": "Esta semana",
+	"dateFormatItem-MMMd": "d 'de' MMM",
+	"field-week-relative+1": "Próxima semana",
+	"months-format-abbr": [
+		"jan",
+		"fev",
+		"mar",
+		"abr",
+		"mai",
+		"jun",
+		"jul",
+		"ago",
+		"set",
+		"out",
+		"nov",
+		"dez"
+	],
+	"field-month-relative+0": "Este mês",
+	"field-month": "Mês",
+	"field-month-relative+1": "Próximo mês",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-format-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"field-second": "Segundo",
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM 'de' y G",
+	"field-day": "Dia",
+	"dateFormatItem-MEd": "E, dd/MM",
+	"months-format-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"days-standAlone-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-standAlone-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "MM/y GGGGG",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"dateFormatItem-Md": "d/M",
+	"months-format-wide": [
+		"janeiro",
+		"fevereiro",
+		"março",
+		"abril",
+		"maio",
+		"junho",
+		"julho",
+		"agosto",
+		"setembro",
+		"outubro",
+		"novembro",
+		"dezembro"
+	],
+	"days-format-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"dateFormatItem-yyyyMMM": "MMM 'de' y G",
+	"field-month-relative+-1": "Mês passado",
+	"quarters-format-wide": [
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
+		"4º trimestre"
+	],
+	"days-format-wide": [
+		"domingo",
+		"segunda-feira",
+		"terça-feira",
+		"quarta-feira",
+		"quinta-feira",
+		"sexta-feira",
+		"sábado"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/chinese.js b/dojo/cldr/nls/pt/chinese.js
new file mode 100644
index 0000000..654ae3c
--- /dev/null
+++ b/dojo/cldr/nls/pt/chinese.js
@@ -0,0 +1,91 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "dd/MM U",
+	"field-second": "Segundo",
+	"field-year-relative+-1": "Ano passado",
+	"field-week": "Semana",
+	"field-month-relative+-1": "Mês passado",
+	"field-day-relative+-1": "Ontem",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "Anteontem",
+	"months-standAlone-wide": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year": "Ano",
+	"field-week-relative+0": "Esta semana",
+	"months-standAlone-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-week-relative+1": "Próxima semana",
+	"field-minute": "Minuto",
+	"field-week-relative+-1": "Semana passada",
+	"field-day-relative+0": "Hoje",
+	"field-hour": "Hora",
+	"field-day-relative+1": "Amanhã",
+	"dateFormat-long": "d 'de' MMMM 'de' U",
+	"field-day-relative+2": "Depois de amanhã",
+	"field-day": "Dia",
+	"field-month-relative+0": "Este mês",
+	"field-month-relative+1": "Próximo mês",
+	"field-dayperiod": "Período do dia",
+	"field-month": "Mês",
+	"dateFormat-short": "dd/MM/yy",
+	"field-era": "Era",
+	"field-year-relative+0": "Este ano",
+	"field-year-relative+1": "Próximo ano",
+	"months-format-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' U",
+	"field-weekday": "Dia da semana",
+	"field-zone": "Fuso"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/coptic.js b/dojo/cldr/nls/pt/coptic.js
new file mode 100644
index 0000000..6b8da74
--- /dev/null
+++ b/dojo/cldr/nls/pt/coptic.js
@@ -0,0 +1,91 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Segundo",
+	"field-year-relative+-1": "Ano passado",
+	"field-week": "Semana",
+	"field-month-relative+-1": "Mês passado",
+	"field-day-relative+-1": "Ontem",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "Anteontem",
+	"months-standAlone-wide": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"field-year": "Ano",
+	"field-week-relative+0": "Esta semana",
+	"months-standAlone-abbr": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"field-week-relative+1": "Próxima semana",
+	"field-minute": "Minuto",
+	"field-week-relative+-1": "Semana passada",
+	"field-day-relative+0": "Hoje",
+	"field-hour": "Hora",
+	"field-day-relative+1": "Amanhã",
+	"field-day-relative+2": "Depois de amanhã",
+	"field-day": "Dia",
+	"field-month-relative+0": "Este mês",
+	"field-month-relative+1": "Próximo mês",
+	"field-dayperiod": "Período do dia",
+	"field-month": "Mês",
+	"field-era": "Era",
+	"field-year-relative+0": "Este ano",
+	"field-year-relative+1": "Próximo ano",
+	"months-format-abbr": [
+		"Tout",
+		"Baba",
+		"Hator",
+		"Kiahk",
+		"Toba",
+		"Amshir",
+		"Baramhat",
+		"Baramouda",
+		"Bashans",
+		"Paona",
+		"Epep",
+		"Mesra",
+		"Nasie"
+	],
+	"field-weekday": "Dia da semana",
+	"field-zone": "Fuso"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/currency.js b/dojo/cldr/nls/pt/currency.js
index 5bd918c..074bf8b 100644
--- a/dojo/cldr/nls/pt/currency.js
+++ b/dojo/cldr/nls/pt/currency.js
@@ -3,12 +3,20 @@ define(
 {
 	"HKD_displayName": "Dólar de Hong Kong",
 	"CHF_displayName": "Franco suíço",
+	"JPY_symbol": "JP¥",
 	"CAD_displayName": "Dólar canadense",
-	"CNY_displayName": "Yuan Renminbi chinês",
+	"HKD_symbol": "HK$",
+	"CNY_displayName": "Yuan chinês",
+	"USD_symbol": "US$",
 	"AUD_displayName": "Dólar australiano",
 	"JPY_displayName": "Iene japonês",
+	"CAD_symbol": "CA$",
 	"USD_displayName": "Dólar norte-americano",
+	"EUR_symbol": "€",
+	"CNY_symbol": "CN¥",
 	"GBP_displayName": "Libra esterlina britânica",
+	"GBP_symbol": "£",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "Euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/pt/ethiopic.js b/dojo/cldr/nls/pt/ethiopic.js
new file mode 100644
index 0000000..1b5d2d0
--- /dev/null
+++ b/dojo/cldr/nls/pt/ethiopic.js
@@ -0,0 +1,91 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Segundo",
+	"field-year-relative+-1": "Ano passado",
+	"field-week": "Semana",
+	"field-month-relative+-1": "Mês passado",
+	"field-day-relative+-1": "Ontem",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "Anteontem",
+	"months-standAlone-wide": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"field-year": "Ano",
+	"field-week-relative+0": "Esta semana",
+	"months-standAlone-abbr": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"field-week-relative+1": "Próxima semana",
+	"field-minute": "Minuto",
+	"field-week-relative+-1": "Semana passada",
+	"field-day-relative+0": "Hoje",
+	"field-hour": "Hora",
+	"field-day-relative+1": "Amanhã",
+	"field-day-relative+2": "Depois de amanhã",
+	"field-day": "Dia",
+	"field-month-relative+0": "Este mês",
+	"field-month-relative+1": "Próximo mês",
+	"field-dayperiod": "Período do dia",
+	"field-month": "Mês",
+	"field-era": "Era",
+	"field-year-relative+0": "Este ano",
+	"field-year-relative+1": "Próximo ano",
+	"months-format-abbr": [
+		"Meskerem",
+		"Tekemt",
+		"Hedar",
+		"Tahsas",
+		"Ter",
+		"Yekatit",
+		"Megabit",
+		"Miazia",
+		"Genbot",
+		"Sene",
+		"Hamle",
+		"Nehasse",
+		"Pagumen"
+	],
+	"field-weekday": "Dia da semana",
+	"field-zone": "Fuso"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/generic.js b/dojo/cldr/nls/pt/generic.js
new file mode 100644
index 0000000..7a3e7cb
--- /dev/null
+++ b/dojo/cldr/nls/pt/generic.js
@@ -0,0 +1,68 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d 'de' MMM 'de' y G",
+	"field-dayperiod": "Período do dia",
+	"field-minute": "Minuto",
+	"dateFormatItem-MMMEd": "E, d 'de' MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "Ontem",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "Anteontem",
+	"field-weekday": "Dia da semana",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "Era",
+	"field-hour": "Hora",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E, d",
+	"field-day-relative+0": "Hoje",
+	"field-day-relative+1": "Amanhã",
+	"field-day-relative+2": "Depois de amanhã",
+	"dateFormatItem-GyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-zone": "Fuso",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Semana passada",
+	"dateFormat-medium": "dd/MM/y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Este ano",
+	"field-year-relative+1": "Próximo ano",
+	"field-year-relative+-1": "Ano passado",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"field-year": "Ano",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "Semana",
+	"dateFormatItem-yyyyMd": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormatItem-yyyyMEd": "E, dd/MM/y GGGGG",
+	"dateFormatItem-MMMd": "d 'de' MMM",
+	"field-week-relative+0": "Esta semana",
+	"field-week-relative+1": "Próxima semana",
+	"field-month-relative+0": "Este mês",
+	"dateFormatItem-H": "HH",
+	"field-month": "Mês",
+	"field-month-relative+1": "Próximo mês",
+	"dateFormatItem-M": "L",
+	"field-second": "Segundo",
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM 'de' y G",
+	"field-day": "Dia",
+	"dateFormatItem-MEd": "E, dd/MM",
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "MM/y GGGGG",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyMMM": "MMM 'de' y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Mês passado",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/gregorian.js b/dojo/cldr/nls/pt/gregorian.js
index 20ed629..8a0a4a8 100644
--- a/dojo/cldr/nls/pt/gregorian.js
+++ b/dojo/cldr/nls/pt/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
 	"months-format-narrow": [
 		"J",
 		"F",
@@ -15,15 +24,32 @@ define(
 		"N",
 		"D"
 	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "Dia da semana",
 	"dateFormatItem-yQQQ": "y QQQ",
-	"dateFormatItem-yMEd": "EEE, dd/MM/yyyy",
-	"dateFormatItem-MMMEd": "EEE, d 'de' MMM",
+	"dateFormatItem-yMEd": "E, dd/MM/y",
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMM 'de' y G",
+	"dateFormatItem-MMMEd": "E, d 'de' MMM",
 	"eraNarrow": [
 		"a.C.",
 		"d.C."
 	],
+	"dateFormatItem-yMM": "MM/y",
 	"dayPeriods-format-wide-morning": "manhã",
+	"days-format-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
 	"dateFormat-long": "d 'de' MMMM 'de' y",
 	"months-format-wide": [
 		"janeiro",
@@ -39,12 +65,15 @@ define(
 		"novembro",
 		"dezembro"
 	],
-	"dateFormatItem-EEEd": "EEE, d",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
 	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y",
 	"dateFormatItem-Md": "d/M",
+	"dayPeriods-format-abbr-am": "AM",
 	"dayPeriods-format-wide-noon": "meio-dia",
+	"dateFormatItem-yMd": "dd/MM/y",
 	"field-era": "Era",
-	"dateFormatItem-yM": "MM/yyyy",
+	"dateFormatItem-yM": "MM/y",
 	"months-standAlone-wide": [
 		"janeiro",
 		"fevereiro",
@@ -66,10 +95,10 @@ define(
 		"3º trimestre",
 		"4º trimestre"
 	],
-	"timeFormat-long": "HH'h'mm'min'ss's' z",
+	"dateFormatItem-yQQQQ": "y QQQQ",
+	"timeFormat-long": "HH:mm:ss z",
 	"field-year": "Ano",
 	"dateFormatItem-yMMM": "MMM 'de' y",
-	"dateFormatItem-yQ": "yyyy Q",
 	"field-hour": "Hora",
 	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
@@ -86,12 +115,12 @@ define(
 		"nov",
 		"dez"
 	],
-	"dateFormatItem-yyQ": "Q yy",
-	"timeFormat-full": "HH'h'mm'min'ss's' zzzz",
+	"timeFormat-full": "HH:mm:ss zzzz",
 	"field-day-relative+0": "Hoje",
 	"field-day-relative+1": "Amanhã",
+	"dateFormatItem-GyMMMd": "d 'de' MMM 'de' y G",
 	"field-day-relative+2": "Depois de amanhã",
-	"field-day-relative+3": "Daqui a três dias",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
 		"jan",
 		"fev",
@@ -118,7 +147,8 @@ define(
 		"3º trimestre",
 		"4º trimestre"
 	],
-	"dateFormatItem-HHmmss": "HH'h'mm'min'ss's'",
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-HHmmss": "HH:mm:ss",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
 		"domingo",
@@ -129,11 +159,8 @@ define(
 		"sexta-feira",
 		"sábado"
 	],
-	"dateFormatItem-yyyyMMM": "MMM 'de' y",
-	"dateFormatItem-yyMMMEEEd": "EEE, d 'de' MMM 'de' yy",
-	"dateFormatItem-yyMMM": "MMM 'de' yy",
 	"timeFormat-medium": "HH:mm:ss",
-	"dateFormatItem-Hm": "HH'h'mm",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
 		"T1",
 		"T2",
@@ -156,14 +183,22 @@ define(
 		"sáb"
 	],
 	"dayPeriods-format-wide-night": "noite",
-	"dateFormatItem-yyMMMd": "d 'de' MMM 'de' yy",
 	"dateFormatItem-d": "d",
-	"dateFormatItem-ms": "mm'min'ss's'",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "Ontem",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "a",
 	"field-day-relative+-2": "Anteontem",
-	"field-day-relative+-3": "Há três dias",
 	"dateFormatItem-MMMd": "d 'de' MMM",
-	"dateFormatItem-MEd": "EEE, dd/MM",
+	"dateFormatItem-MEd": "E, dd/MM",
+	"dateTimeFormat-full": "{1} {0}",
 	"field-day": "Dia",
 	"days-format-wide": [
 		"domingo",
@@ -175,7 +210,6 @@ define(
 		"sábado"
 	],
 	"field-zone": "Fuso",
-	"dateFormatItem-yyyyMM": "MM/yyyy",
 	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
 		"J",
@@ -191,7 +225,10 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-yyMM": "MM/yy",
+	"field-year-relative+-1": "Ano passado",
+	"field-month-relative+-1": "Mês passado",
+	"dateFormatItem-hm": "h:mm a",
+	"dayPeriods-format-abbr-pm": "PM",
 	"days-format-abbr": [
 		"dom",
 		"seg",
@@ -205,6 +242,7 @@ define(
 		"Antes de Cristo",
 		"Ano do Senhor"
 	],
+	"dateFormatItem-yMMMd": "d 'de' MMM 'de' y",
 	"days-format-narrow": [
 		"D",
 		"S",
@@ -214,7 +252,6 @@ define(
 		"S",
 		"S"
 	],
-	"field-month": "Mês",
 	"days-standAlone-narrow": [
 		"D",
 		"S",
@@ -225,13 +262,28 @@ define(
 		"S"
 	],
 	"dateFormatItem-MMM": "LLL",
-	"dateFormatItem-HHmm": "HH'h'mm",
+	"field-month": "Mês",
+	"dateFormatItem-HHmm": "HH:mm",
+	"dayPeriods-format-wide-am": "AM",
 	"dateFormat-short": "dd/MM/yy",
 	"dayPeriods-format-wide-afternoon": "tarde",
 	"field-second": "Segundo",
-	"dateFormatItem-yMMMEd": "EEE, d 'de' MMM 'de' y",
+	"dateFormatItem-yMMMEd": "E, d 'de' MMM 'de' y",
+	"field-month-relative+0": "Este mês",
+	"field-month-relative+1": "Próximo mês",
+	"dateFormatItem-Ed": "E, d",
 	"field-week": "Semana",
-	"dateFormat-medium": "dd/MM/yyyy"
+	"dateFormat-medium": "dd/MM/y",
+	"field-year-relative+0": "Este ano",
+	"field-week-relative+-1": "Semana passada",
+	"field-year-relative+1": "Próximo ano",
+	"dayPeriods-format-narrow-pm": "p",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM 'de' y G",
+	"field-week-relative+0": "Esta semana",
+	"field-week-relative+1": "Próxima semana"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/hebrew.js b/dojo/cldr/nls/pt/hebrew.js
new file mode 100644
index 0000000..42fe73f
--- /dev/null
+++ b/dojo/cldr/nls/pt/hebrew.js
@@ -0,0 +1,214 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "Período do dia",
+	"dateFormatItem-yyyyMMMEd": "E, d 'de' MMM 'de' y G",
+	"months-standAlone-abbr-leap": "Adar II",
+	"field-minute": "Minuto",
+	"dateFormatItem-MMMEd": "E, d 'de' MMM",
+	"field-day-relative+-1": "Ontem",
+	"field-weekday": "Dia da semana",
+	"field-day-relative+-2": "Anteontem",
+	"days-standAlone-wide": [
+		"domingo",
+		"segunda-feira",
+		"terça-feira",
+		"quarta-feira",
+		"quinta-feira",
+		"sexta-feira",
+		"sábado"
+	],
+	"field-era": "Era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Hora",
+	"months-format-abbr-leap": "Adar II",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Tishri",
+		"Heshvan",
+		"Kislev",
+		"Tevet",
+		"Shevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
+		"Elul"
+	],
+	"dateFormatItem-Ed": "E, d",
+	"field-day-relative+0": "Hoje",
+	"field-day-relative+1": "Amanhã",
+	"days-standAlone-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"field-day-relative+2": "Depois de amanhã",
+	"dateFormatItem-GyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-zone": "Fuso",
+	"field-week-relative+-1": "Semana passada",
+	"dateFormat-medium": "dd/MM/y G",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "Este ano",
+	"field-year-relative+1": "Próximo ano",
+	"quarters-standAlone-wide": [
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
+		"4º trimestre"
+	],
+	"field-year-relative+-1": "Ano passado",
+	"field-year": "Ano",
+	"dayPeriods-format-narrow-am": "a",
+	"months-standAlone-wide": [
+		"Tishri",
+		"Heshvan",
+		"Kislev",
+		"Tevet",
+		"Shevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
+		"Elul"
+	],
+	"field-week": "Semana",
+	"dateFormatItem-yyyyMd": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormatItem-yyyyMEd": "E, dd/MM/y GGGGG",
+	"dateFormatItem-MMMd": "d 'de' MMM",
+	"field-week-relative+0": "Esta semana",
+	"field-week-relative+1": "Próxima semana",
+	"months-format-abbr": [
+		"Tishri",
+		"Heshvan",
+		"Kislev",
+		"Tevet",
+		"Shevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
+		"Elul"
+	],
+	"field-month-relative+0": "Este mês",
+	"field-month": "Mês",
+	"field-month-relative+1": "Próximo mês",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-format-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"field-second": "Segundo",
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM 'de' y G",
+	"field-day": "Dia",
+	"dateFormatItem-MEd": "E, dd/MM",
+	"days-standAlone-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-standAlone-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"months-standAlone-wide-leap": "Adar II",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "MM/y GGGGG",
+	"dateFormatItem-Md": "d/M",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"months-format-wide": [
+		"Tishri",
+		"Heshvan",
+		"Kislev",
+		"Tevet",
+		"Shevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
+		"Elul"
+	],
+	"days-format-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"dateFormatItem-yyyyMMM": "MMM 'de' y G",
+	"months-format-wide-leap": "Adar II",
+	"field-month-relative+-1": "Mês passado",
+	"quarters-format-wide": [
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
+		"4º trimestre"
+	],
+	"days-format-wide": [
+		"domingo",
+		"segunda-feira",
+		"terça-feira",
+		"quarta-feira",
+		"quinta-feira",
+		"sexta-feira",
+		"sábado"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/indian.js b/dojo/cldr/nls/pt/indian.js
new file mode 100644
index 0000000..f525ccf
--- /dev/null
+++ b/dojo/cldr/nls/pt/indian.js
@@ -0,0 +1,87 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Segundo",
+	"field-year-relative+-1": "Ano passado",
+	"field-week": "Semana",
+	"field-month-relative+-1": "Mês passado",
+	"field-day-relative+-1": "Ontem",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "Anteontem",
+	"months-standAlone-wide": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"field-year": "Ano",
+	"field-week-relative+0": "Esta semana",
+	"months-standAlone-abbr": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"field-week-relative+1": "Próxima semana",
+	"field-minute": "Minuto",
+	"field-week-relative+-1": "Semana passada",
+	"field-day-relative+0": "Hoje",
+	"field-hour": "Hora",
+	"field-day-relative+1": "Amanhã",
+	"field-day-relative+2": "Depois de amanhã",
+	"field-day": "Dia",
+	"field-month-relative+0": "Este mês",
+	"field-month-relative+1": "Próximo mês",
+	"field-dayperiod": "Período do dia",
+	"field-month": "Mês",
+	"field-era": "Era",
+	"field-year-relative+0": "Este ano",
+	"field-year-relative+1": "Próximo ano",
+	"months-format-abbr": [
+		"Chaitra",
+		"Vaisakha",
+		"Jyaistha",
+		"Asadha",
+		"Sravana",
+		"Bhadra",
+		"Asvina",
+		"Kartika",
+		"Agrahayana",
+		"Pausa",
+		"Magha",
+		"Phalguna"
+	],
+	"field-weekday": "Dia da semana",
+	"field-zone": "Fuso"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/islamic.js b/dojo/cldr/nls/pt/islamic.js
new file mode 100644
index 0000000..5a365d5
--- /dev/null
+++ b/dojo/cldr/nls/pt/islamic.js
@@ -0,0 +1,153 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "Período do dia",
+	"dateFormatItem-yyyyMMMEd": "E, d 'de' MMM 'de' y G",
+	"field-minute": "Minuto",
+	"dateFormatItem-MMMEd": "E, d 'de' MMM",
+	"field-day-relative+-1": "Ontem",
+	"field-weekday": "Dia da semana",
+	"field-day-relative+-2": "Anteontem",
+	"days-standAlone-wide": [
+		"domingo",
+		"segunda-feira",
+		"terça-feira",
+		"quarta-feira",
+		"quinta-feira",
+		"sexta-feira",
+		"sábado"
+	],
+	"field-era": "Era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Hora",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E, d",
+	"field-day-relative+0": "Hoje",
+	"field-day-relative+1": "Amanhã",
+	"days-standAlone-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"field-day-relative+2": "Depois de amanhã",
+	"dateFormatItem-GyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-zone": "Fuso",
+	"field-week-relative+-1": "Semana passada",
+	"dateFormat-medium": "dd/MM/y G",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "Este ano",
+	"field-year-relative+1": "Próximo ano",
+	"quarters-standAlone-wide": [
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
+		"4º trimestre"
+	],
+	"field-year-relative+-1": "Ano passado",
+	"field-year": "Ano",
+	"dayPeriods-format-narrow-am": "a",
+	"field-week": "Semana",
+	"dateFormatItem-yyyyMd": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormatItem-yyyyMEd": "E, dd/MM/y GGGGG",
+	"field-week-relative+0": "Esta semana",
+	"dateFormatItem-MMMd": "d 'de' MMM",
+	"field-week-relative+1": "Próxima semana",
+	"field-month-relative+0": "Este mês",
+	"field-month": "Mês",
+	"field-month-relative+1": "Próximo mês",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-format-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"field-second": "Segundo",
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM 'de' y G",
+	"field-day": "Dia",
+	"dateFormatItem-MEd": "E, dd/MM",
+	"days-standAlone-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-standAlone-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "MM/y GGGGG",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"dateFormatItem-Md": "d/M",
+	"days-format-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"dateFormatItem-yyyyMMM": "MMM 'de' y G",
+	"field-month-relative+-1": "Mês passado",
+	"quarters-format-wide": [
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
+		"4º trimestre"
+	],
+	"days-format-wide": [
+		"domingo",
+		"segunda-feira",
+		"terça-feira",
+		"quarta-feira",
+		"quinta-feira",
+		"sexta-feira",
+		"sábado"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/japanese.js b/dojo/cldr/nls/pt/japanese.js
new file mode 100644
index 0000000..3da0ebe
--- /dev/null
+++ b/dojo/cldr/nls/pt/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "dd/MM/y G",
+	"field-second": "Segundo",
+	"field-year-relative+-1": "Ano passado",
+	"field-week": "Semana",
+	"field-month-relative+-1": "Mês passado",
+	"field-day-relative+-1": "Ontem",
+	"field-day-relative+-2": "Anteontem",
+	"field-year": "Ano",
+	"field-week-relative+0": "Esta semana",
+	"field-week-relative+1": "Próxima semana",
+	"field-minute": "Minuto",
+	"field-week-relative+-1": "Semana passada",
+	"field-day-relative+0": "Hoje",
+	"field-hour": "Hora",
+	"field-day-relative+1": "Amanhã",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-day-relative+2": "Depois de amanhã",
+	"field-day": "Dia",
+	"field-month-relative+0": "Este mês",
+	"field-month-relative+1": "Próximo mês",
+	"field-dayperiod": "Período do dia",
+	"field-month": "Mês",
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"field-era": "Era",
+	"field-year-relative+0": "Este ano",
+	"field-year-relative+1": "Próximo ano",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"field-weekday": "Dia da semana",
+	"field-zone": "Fuso"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/number.js b/dojo/cldr/nls/pt/number.js
index fe2d142..5698aa3 100644
--- a/dojo/cldr/nls/pt/number.js
+++ b/dojo/cldr/nls/pt/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0%",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "¤#,##0.00;(¤#,##0.00)",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 trilhões",
+	"decimalFormat-short": "000 tri"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/persian.js b/dojo/cldr/nls/pt/persian.js
new file mode 100644
index 0000000..1301310
--- /dev/null
+++ b/dojo/cldr/nls/pt/persian.js
@@ -0,0 +1,234 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "Período do dia",
+	"dateFormatItem-yyyyMMMEd": "E, d 'de' MMM 'de' y G",
+	"field-minute": "Minuto",
+	"dateFormatItem-MMMEd": "E, d 'de' MMM",
+	"field-day-relative+-1": "Ontem",
+	"field-weekday": "Dia da semana",
+	"field-day-relative+-2": "Anteontem",
+	"days-standAlone-wide": [
+		"domingo",
+		"segunda-feira",
+		"terça-feira",
+		"quarta-feira",
+		"quinta-feira",
+		"sexta-feira",
+		"sábado"
+	],
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-era": "Era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Hora",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordad",
+		"Tir",
+		"Mordad",
+		"Shahrivar",
+		"Mehr",
+		"Aban",
+		"Azar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"dateFormatItem-Ed": "E, d",
+	"field-day-relative+0": "Hoje",
+	"field-day-relative+1": "Amanhã",
+	"days-standAlone-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"field-day-relative+2": "Depois de amanhã",
+	"dateFormatItem-GyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"field-zone": "Fuso",
+	"field-week-relative+-1": "Semana passada",
+	"dateFormat-medium": "dd/MM/y G",
+	"dayPeriods-format-narrow-pm": "p",
+	"field-year-relative+0": "Este ano",
+	"field-year-relative+1": "Próximo ano",
+	"quarters-standAlone-wide": [
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
+		"4º trimestre"
+	],
+	"field-year-relative+-1": "Ano passado",
+	"field-year": "Ano",
+	"dayPeriods-format-narrow-am": "a",
+	"months-standAlone-wide": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordad",
+		"Tir",
+		"Mordad",
+		"Shahrivar",
+		"Mehr",
+		"Aban",
+		"Azar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"field-week": "Semana",
+	"dateFormatItem-yyyyMMMd": "d 'de' MMM 'de' y G",
+	"dateFormatItem-yyyyMd": "dd/MM/y GGGGG",
+	"dateFormatItem-yyyyMEd": "E, dd/MM/y GGGGG",
+	"field-week-relative+0": "Esta semana",
+	"dateFormatItem-MMMd": "d 'de' MMM",
+	"field-week-relative+1": "Próxima semana",
+	"months-format-abbr": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordad",
+		"Tir",
+		"Mordad",
+		"Shahrivar",
+		"Mehr",
+		"Aban",
+		"Azar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"field-month-relative+0": "Este mês",
+	"field-month": "Mês",
+	"field-month-relative+1": "Próximo mês",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-format-narrow": [
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
+		"S"
+	],
+	"field-second": "Segundo",
+	"dateFormatItem-GyMMMEd": "E, d 'de' MMM 'de' y G",
+	"dateFormatItem-GyMMM": "MMM 'de' y G",
+	"field-day": "Dia",
+	"dateFormatItem-MEd": "E, dd/MM",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"days-standAlone-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"days-standAlone-abbr": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"dateFormat-short": "dd/MM/yy GGGGG",
+	"dateFormatItem-yyyyM": "MM/y GGGGG",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y G",
+	"dateFormatItem-Md": "d/M",
+	"months-format-wide": [
+		"janeiro",
+		"fevereiro",
+		"março",
+		"abril",
+		"maio",
+		"junho",
+		"julho",
+		"agosto",
+		"setembro",
+		"outubro",
+		"novembro",
+		"dezembro"
+	],
+	"days-format-short": [
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
+		"sáb"
+	],
+	"dateFormatItem-yyyyMMM": "MMM 'de' y G",
+	"field-month-relative+-1": "Mês passado",
+	"quarters-format-wide": [
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
+		"4º trimestre"
+	],
+	"days-format-wide": [
+		"domingo",
+		"segunda-feira",
+		"terça-feira",
+		"quarta-feira",
+		"quinta-feira",
+		"sexta-feira",
+		"sábado"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/roc.js b/dojo/cldr/nls/pt/roc.js
new file mode 100644
index 0000000..ae71c8b
--- /dev/null
+++ b/dojo/cldr/nls/pt/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Segundo",
+	"field-year-relative+-1": "Ano passado",
+	"field-week": "Semana",
+	"field-month-relative+-1": "Mês passado",
+	"field-day-relative+-1": "Ontem",
+	"field-day-relative+-2": "Anteontem",
+	"field-year": "Ano",
+	"field-week-relative+0": "Esta semana",
+	"field-week-relative+1": "Próxima semana",
+	"field-minute": "Minuto",
+	"field-week-relative+-1": "Semana passada",
+	"field-day-relative+0": "Hoje",
+	"field-hour": "Hora",
+	"field-day-relative+1": "Amanhã",
+	"field-day-relative+2": "Depois de amanhã",
+	"field-day": "Dia",
+	"field-month-relative+0": "Este mês",
+	"field-month-relative+1": "Próximo mês",
+	"field-dayperiod": "Período do dia",
+	"field-month": "Mês",
+	"field-era": "Era",
+	"field-year-relative+0": "Este ano",
+	"field-year-relative+1": "Próximo ano",
+	"eraAbbr": [
+		"Antes de R.O.C.",
+		"R.O.C."
+	],
+	"field-weekday": "Dia da semana",
+	"field-zone": "Fuso"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/buddhist.js b/dojo/cldr/nls/ro/buddhist.js
index a8c8769..0a84fa6 100644
--- a/dojo/cldr/nls/ro/buddhist.js
+++ b/dojo/cldr/nls/ro/buddhist.js
@@ -1,21 +1,25 @@
 define(
 //begin v1.x content
 {
-	"quarters-format-abbr": [
-		"trim. I",
-		"trim. II",
-		"trim. III",
-		"trim. IV"
+	"field-dayperiod": "perioada zilei",
+	"field-minute": "minut",
+	"eraNames": [
+		"era budistă"
 	],
-	"dateFormat-medium": "d MMM y G",
-	"dateFormatItem-MMMEd": "E, d MMM",
-	"dateFormatItem-MEd": "E, d MMM",
-	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
-	"eraNarrow": [
-		"e.b."
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day-relative+-1": "ieri",
+	"field-weekday": "zi a săptămânii",
+	"field-day-relative+-2": "alaltăieri",
+	"days-standAlone-wide": [
+		"duminică",
+		"luni",
+		"marți",
+		"miercuri",
+		"joi",
+		"vineri",
+		"sâmbătă"
 	],
-	"dateTimeFormat-medium": "{1}, {0}",
-	"dateFormatItem-Md": "d.M",
 	"months-standAlone-narrow": [
 		"I",
 		"F",
@@ -30,10 +34,34 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-EEEd": "EEE d",
-	"eraNames": [
-		"era budistă"
+	"dateTimeFormat-short": "{1}, {0}",
+	"field-era": "eră",
+	"field-hour": "oră",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y",
+	"months-standAlone-abbr": [
+		"ian.",
+		"feb.",
+		"mar.",
+		"apr.",
+		"mai",
+		"iun.",
+		"iul.",
+		"aug.",
+		"sept.",
+		"oct.",
+		"nov.",
+		"dec."
 	],
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "azi",
+	"field-day-relative+1": "mâine",
 	"days-standAlone-narrow": [
 		"D",
 		"L",
@@ -43,19 +71,33 @@ define(
 		"V",
 		"S"
 	],
-	"dateTimeFormat-long": "{1}, {0}",
-	"dateFormatItem-yQQQ": "QQQ y",
+	"eraAbbr": [
+		"e.b."
+	],
+	"field-day-relative+2": "poimâine",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "zonă",
+	"field-week-relative+-1": "Săptămâna trecută",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Anul acesta",
+	"field-year-relative+1": "Anul viitor",
+	"quarters-standAlone-wide": [
+		"trimestrul I",
+		"trimestrul al II-lea",
+		"trimestrul al III-lea",
+		"trimestrul al IV-lea"
+	],
+	"field-year-relative+-1": "Anul trecut",
+	"field-year": "an",
 	"quarters-standAlone-narrow": [
 		"T1",
 		"T2",
 		"T3",
 		"T4"
 	],
-	"dateFormat-long": "d MMMM y G",
-	"dateFormat-short": "d/M/yyyy",
-	"dateFormatItem-yMMMEd": "EEE, d MMM y",
-	"dateTimeFormat-short": "{1}, {0}",
-	"months-format-wide": [
+	"dateTimeFormat-long": "{1}, {0}",
+	"field-week": "săptămână",
+	"months-standAlone-wide": [
 		"ianuarie",
 		"februarie",
 		"martie",
@@ -69,8 +111,15 @@ define(
 		"noiembrie",
 		"decembrie"
 	],
-	"dateTimeFormat-full": "{1}, {0}",
-	"dateFormatItem-yM": "M.yyyy",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Săptămâna aceasta",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"T4"
+	],
+	"field-week-relative+1": "Săptămâna viitoare",
 	"months-format-abbr": [
 		"ian.",
 		"feb.",
@@ -85,29 +134,86 @@ define(
 		"nov.",
 		"dec."
 	],
-	"eraAbbr": [
-		"e.b."
+	"field-month-relative+0": "Luna aceasta",
+	"field-month": "lună",
+	"field-month-relative+1": "Luna viitoare",
+	"quarters-format-abbr": [
+		"trim. I",
+		"trim. II",
+		"trim. III",
+		"trim. IV"
 	],
-	"days-format-wide": [
-		"duminică",
-		"luni",
-		"marți",
-		"miercuri",
-		"joi",
-		"vineri",
-		"sâmbătă"
+	"days-format-abbr": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
 	],
-	"dateFormatItem-yQ": "'trimestrul' Q y",
-	"dateFormatItem-yMMM": "MMM y",
-	"quarters-format-wide": [
-		"trimestrul I",
-		"trimestrul al II-lea",
-		"trimestrul al III-lea",
-		"trimestrul al IV-lea"
+	"days-format-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"field-second": "secundă",
+	"field-day": "zi",
+	"dateFormatItem-MEd": "E, dd.MM",
+	"months-format-narrow": [
+		"I",
+		"F",
+		"M",
+		"A",
+		"M",
+		"I",
+		"I",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"days-standAlone-short": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
+	"days-standAlone-abbr": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
 	],
+	"dateFormat-short": "d/M/y",
 	"dateFormat-full": "EEEE, d MMMM, y G",
-	"dateFormatItem-MMMd": "d MMM",
-	"days-format-abbr": [
+	"dateFormatItem-Md": "dd.MM",
+	"months-format-wide": [
+		"ianuarie",
+		"februarie",
+		"martie",
+		"aprilie",
+		"mai",
+		"iunie",
+		"iulie",
+		"august",
+		"septembrie",
+		"octombrie",
+		"noiembrie",
+		"decembrie"
+	],
+	"days-format-short": [
 		"Du",
 		"Lu",
 		"Ma",
@@ -115,6 +221,25 @@ define(
 		"Jo",
 		"Vi",
 		"Sâ"
+	],
+	"field-month-relative+-1": "Luna trecută",
+	"quarters-format-wide": [
+		"trimestrul I",
+		"trimestrul al II-lea",
+		"trimestrul al III-lea",
+		"trimestrul al IV-lea"
+	],
+	"eraNarrow": [
+		"e.b."
+	],
+	"days-format-wide": [
+		"duminică",
+		"luni",
+		"marți",
+		"miercuri",
+		"joi",
+		"vineri",
+		"sâmbătă"
 	]
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/ro/chinese.js b/dojo/cldr/nls/ro/chinese.js
new file mode 100644
index 0000000..89db0c9
--- /dev/null
+++ b/dojo/cldr/nls/ro/chinese.js
@@ -0,0 +1,87 @@
+define(
+//begin v1.x content
+{
+	"field-second": "secundă",
+	"field-year-relative+-1": "Anul trecut",
+	"field-week": "săptămână",
+	"field-month-relative+-1": "Luna trecută",
+	"field-day-relative+-1": "ieri",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "alaltăieri",
+	"months-standAlone-wide": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year": "an",
+	"field-week-relative+0": "Săptămâna aceasta",
+	"months-standAlone-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-week-relative+1": "Săptămâna viitoare",
+	"field-minute": "minut",
+	"field-week-relative+-1": "Săptămâna trecută",
+	"field-day-relative+0": "azi",
+	"field-hour": "oră",
+	"field-day-relative+1": "mâine",
+	"field-day-relative+2": "poimâine",
+	"field-day": "zi",
+	"field-month-relative+0": "Luna aceasta",
+	"field-month-relative+1": "Luna viitoare",
+	"field-dayperiod": "perioada zilei",
+	"field-month": "lună",
+	"field-era": "eră",
+	"field-year-relative+0": "Anul acesta",
+	"field-year-relative+1": "Anul viitor",
+	"months-format-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "zi a săptămânii",
+	"field-zone": "zonă"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/coptic.js b/dojo/cldr/nls/ro/coptic.js
new file mode 100644
index 0000000..67c42e1
--- /dev/null
+++ b/dojo/cldr/nls/ro/coptic.js
@@ -0,0 +1,31 @@
+define(
+//begin v1.x content
+{
+	"field-second": "secundă",
+	"field-year-relative+-1": "Anul trecut",
+	"field-week": "săptămână",
+	"field-month-relative+-1": "Luna trecută",
+	"field-day-relative+-1": "ieri",
+	"field-day-relative+-2": "alaltăieri",
+	"field-year": "an",
+	"field-week-relative+0": "Săptămâna aceasta",
+	"field-week-relative+1": "Săptămâna viitoare",
+	"field-minute": "minut",
+	"field-week-relative+-1": "Săptămâna trecută",
+	"field-day-relative+0": "azi",
+	"field-hour": "oră",
+	"field-day-relative+1": "mâine",
+	"field-day-relative+2": "poimâine",
+	"field-day": "zi",
+	"field-month-relative+0": "Luna aceasta",
+	"field-month-relative+1": "Luna viitoare",
+	"field-dayperiod": "perioada zilei",
+	"field-month": "lună",
+	"field-era": "eră",
+	"field-year-relative+0": "Anul acesta",
+	"field-year-relative+1": "Anul viitor",
+	"field-weekday": "zi a săptămânii",
+	"field-zone": "zonă"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/currency.js b/dojo/cldr/nls/ro/currency.js
index da2ff10..e0eb410 100644
--- a/dojo/cldr/nls/ro/currency.js
+++ b/dojo/cldr/nls/ro/currency.js
@@ -5,6 +5,7 @@ define(
 	"CHF_displayName": "franc elvețian",
 	"CAD_displayName": "dolar canadian",
 	"CNY_displayName": "yuan renminbi chinezesc",
+	"USD_symbol": "$",
 	"AUD_displayName": "dolar australian",
 	"JPY_displayName": "yen japonez",
 	"USD_displayName": "dolar american",
diff --git a/dojo/cldr/nls/ro/ethiopic.js b/dojo/cldr/nls/ro/ethiopic.js
new file mode 100644
index 0000000..67c42e1
--- /dev/null
+++ b/dojo/cldr/nls/ro/ethiopic.js
@@ -0,0 +1,31 @@
+define(
+//begin v1.x content
+{
+	"field-second": "secundă",
+	"field-year-relative+-1": "Anul trecut",
+	"field-week": "săptămână",
+	"field-month-relative+-1": "Luna trecută",
+	"field-day-relative+-1": "ieri",
+	"field-day-relative+-2": "alaltăieri",
+	"field-year": "an",
+	"field-week-relative+0": "Săptămâna aceasta",
+	"field-week-relative+1": "Săptămâna viitoare",
+	"field-minute": "minut",
+	"field-week-relative+-1": "Săptămâna trecută",
+	"field-day-relative+0": "azi",
+	"field-hour": "oră",
+	"field-day-relative+1": "mâine",
+	"field-day-relative+2": "poimâine",
+	"field-day": "zi",
+	"field-month-relative+0": "Luna aceasta",
+	"field-month-relative+1": "Luna viitoare",
+	"field-dayperiod": "perioada zilei",
+	"field-month": "lună",
+	"field-era": "eră",
+	"field-year-relative+0": "Anul acesta",
+	"field-year-relative+1": "Anul viitor",
+	"field-weekday": "zi a săptămânii",
+	"field-zone": "zonă"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/generic.js b/dojo/cldr/nls/ro/generic.js
new file mode 100644
index 0000000..849e7bd
--- /dev/null
+++ b/dojo/cldr/nls/ro/generic.js
@@ -0,0 +1,67 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "MM.y",
+	"field-dayperiod": "perioada zilei",
+	"field-minute": "minut",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day-relative+-1": "ieri",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-MMdd": "dd.MM",
+	"field-day-relative+-2": "alaltăieri",
+	"field-weekday": "zi a săptămânii",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"field-era": "eră",
+	"field-hour": "oră",
+	"dateFormatItem-y": "y",
+	"dateFormatItem-yMM": "MM.y",
+	"dateFormatItem-Ed": "E d",
+	"dateFormatItem-yMMM": "MMM y",
+	"field-day-relative+0": "azi",
+	"field-day-relative+1": "mâine",
+	"field-day-relative+2": "poimâine",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "zonă",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Săptămâna trecută",
+	"dateFormat-medium": "dd.MM.y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Anul acesta",
+	"field-year-relative+1": "Anul viitor",
+	"dateFormatItem-yMd": "dd.MM.y",
+	"field-year-relative+-1": "Anul trecut",
+	"dateFormatItem-yMMMM": "MMMM y",
+	"dateFormatItem-ms": "mm:ss",
+	"field-year": "an",
+	"dateTimeFormat-long": "{1}, {0}",
+	"field-week": "săptămână",
+	"dateFormatItem-MMMMEd": "E, d MMMM",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Săptămâna aceasta",
+	"field-week-relative+1": "Săptămâna viitoare",
+	"dateFormatItem-yQQQQ": "QQQQ y",
+	"field-month-relative+0": "Luna aceasta",
+	"dateFormatItem-H": "HH",
+	"field-month": "lună",
+	"field-month-relative+1": "Luna viitoare",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-M": "L",
+	"dateFormatItem-yMMMd": "d MMM y",
+	"field-second": "secundă",
+	"field-day": "zi",
+	"dateFormatItem-MEd": "E, dd.MM",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd.MM.y GGGGG",
+	"dateFormatItem-yMMMEd": "E, d MMM y",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormatItem-Md": "dd.MM",
+	"dateFormatItem-yMEd": "E, dd.MM.y",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Luna trecută"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/gregorian.js b/dojo/cldr/nls/ro/gregorian.js
index 9485520..e06ec9a 100644
--- a/dojo/cldr/nls/ro/gregorian.js
+++ b/dojo/cldr/nls/ro/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
 	"months-format-narrow": [
 		"I",
 		"F",
@@ -23,12 +32,22 @@ define(
 	],
 	"field-weekday": "zi a săptămânii",
 	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
+	"dateFormatItem-yMEd": "E, dd.MM.y",
 	"dateFormatItem-MMMEd": "E, d MMM",
 	"eraNarrow": [
 		"î.Hr.",
 		"d.Hr."
 	],
+	"dateFormatItem-yMM": "MM.y",
+	"days-format-short": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
 	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
 		"ianuarie",
@@ -45,12 +64,12 @@ define(
 		"decembrie"
 	],
 	"dateTimeFormat-medium": "{1}, {0}",
-	"dateFormatItem-EEEd": "EEE d",
 	"dayPeriods-format-wide-pm": "PM",
 	"dateFormat-full": "EEEE, d MMMM y",
-	"dateFormatItem-Md": "d.M",
+	"dateFormatItem-Md": "dd.MM",
+	"dateFormatItem-yMd": "dd.MM.y",
 	"field-era": "eră",
-	"dateFormatItem-yM": "M.yyyy",
+	"dateFormatItem-yM": "MM.y",
 	"months-standAlone-wide": [
 		"ianuarie",
 		"februarie",
@@ -72,11 +91,10 @@ define(
 		"trimestrul al III-lea",
 		"trimestrul al IV-lea"
 	],
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-long": "HH:mm:ss z",
 	"field-year": "an",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "'trimestrul' Q y",
-	"dateFormatItem-yyyyMMMM": "MMMM y",
 	"field-hour": "oră",
 	"dateFormatItem-MMdd": "dd.MM",
 	"months-format-abbr": [
@@ -93,12 +111,11 @@ define(
 		"nov.",
 		"dec."
 	],
-	"dateFormatItem-yyQ": "Q yy",
 	"timeFormat-full": "HH:mm:ss zzzz",
 	"field-day-relative+0": "azi",
 	"field-day-relative+1": "mâine",
 	"field-day-relative+2": "poimâine",
-	"field-day-relative+3": "răspoimâine",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
 		"ian.",
 		"feb.",
@@ -136,14 +153,13 @@ define(
 		"sâmbătă"
 	],
 	"dateFormatItem-MMMMd": "d MMMM",
-	"dateFormatItem-yyMMM": "MMM yy",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"trim. I",
-		"trim. II",
-		"trim. III",
-		"trim. IV"
+		"T1",
+		"T2",
+		"T3",
+		"T4"
 	],
 	"eraAbbr": [
 		"î.Hr.",
@@ -163,17 +179,16 @@ define(
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
 	"quarters-format-narrow": [
-		"T1",
-		"T2",
-		"T3",
+		"1",
+		"2",
+		"3",
 		"T4"
 	],
 	"field-day-relative+-1": "ieri",
 	"dateTimeFormat-long": "{1}, {0}",
 	"field-day-relative+-2": "alaltăieri",
-	"field-day-relative+-3": "răsalaltăieri",
 	"dateFormatItem-MMMd": "d MMM",
-	"dateFormatItem-MEd": "E, d MMM",
+	"dateFormatItem-MEd": "E, dd.MM",
 	"dateTimeFormat-full": "{1}, {0}",
 	"dateFormatItem-yMMMM": "MMMM y",
 	"field-day": "zi",
@@ -187,7 +202,6 @@ define(
 		"sâmbătă"
 	],
 	"field-zone": "zonă",
-	"dateFormatItem-yyyyMM": "MM.yyyy",
 	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
 		"I",
@@ -203,7 +217,9 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-yyMM": "MM.yy",
+	"field-year-relative+-1": "Anul trecut",
+	"field-month-relative+-1": "Luna trecută",
+	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
 		"Du",
 		"Lu",
@@ -213,6 +229,7 @@ define(
 		"Vi",
 		"Sâ"
 	],
+	"dateFormatItem-yMMMd": "d MMM y",
 	"eraNames": [
 		"înainte de Hristos",
 		"după Hristos"
@@ -239,13 +256,22 @@ define(
 	"dateFormatItem-MMM": "LLL",
 	"dayPeriods-format-wide-am": "AM",
 	"dateFormatItem-MMMMEd": "E, d MMMM",
-	"dateFormat-short": "dd.MM.yyyy",
+	"dateFormat-short": "dd.MM.y",
 	"field-second": "secundă",
-	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"dateFormatItem-yMMMEd": "E, d MMM y",
+	"field-month-relative+0": "Luna aceasta",
+	"field-month-relative+1": "Luna viitoare",
+	"dateFormatItem-Ed": "E d",
 	"field-week": "săptămână",
-	"dateFormat-medium": "dd.MM.yyyy",
+	"dateFormat-medium": "dd.MM.y",
+	"field-year-relative+0": "Anul acesta",
+	"field-week-relative+-1": "Săptămâna trecută",
+	"field-year-relative+1": "Anul viitor",
 	"dateTimeFormat-short": "{1}, {0}",
-	"dateFormatItem-MMMEEEd": "EEE, d MMM"
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-week-relative+0": "Săptămâna aceasta",
+	"field-week-relative+1": "Săptămâna viitoare"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/hebrew.js b/dojo/cldr/nls/ro/hebrew.js
new file mode 100644
index 0000000..5faa178
--- /dev/null
+++ b/dojo/cldr/nls/ro/hebrew.js
@@ -0,0 +1,217 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "perioada zilei",
+	"months-standAlone-abbr-leap": "Adar II",
+	"field-minute": "minut",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day-relative+-1": "ieri",
+	"field-weekday": "zi a săptămânii",
+	"field-day-relative+-2": "alaltăieri",
+	"days-standAlone-wide": [
+		"duminică",
+		"luni",
+		"marți",
+		"miercuri",
+		"joi",
+		"vineri",
+		"sâmbătă"
+	],
+	"dateTimeFormat-short": "{1}, {0}",
+	"field-era": "eră",
+	"field-hour": "oră",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"months-format-abbr-leap": "Adar II",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y",
+	"months-standAlone-abbr": [
+		"Tișrei",
+		"Heșvan",
+		"Kislev",
+		"Tevet",
+		"Șevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tammuz",
+		"Av",
+		"Elul"
+	],
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "azi",
+	"field-day-relative+1": "mâine",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"field-day-relative+2": "poimâine",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "zonă",
+	"field-week-relative+-1": "Săptămâna trecută",
+	"dateFormat-medium": "dd.MM.y G",
+	"field-year-relative+0": "Anul acesta",
+	"field-year-relative+1": "Anul viitor",
+	"quarters-standAlone-wide": [
+		"trimestrul I",
+		"trimestrul al II-lea",
+		"trimestrul al III-lea",
+		"trimestrul al IV-lea"
+	],
+	"field-year-relative+-1": "Anul trecut",
+	"field-year": "an",
+	"quarters-standAlone-narrow": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateTimeFormat-long": "{1}, {0}",
+	"months-standAlone-wide": [
+		"Tișrei",
+		"Heșvan",
+		"Kislev",
+		"Tevet",
+		"Șevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tammuz",
+		"Av",
+		"Elul"
+	],
+	"field-week": "săptămână",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Săptămâna aceasta",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"T4"
+	],
+	"field-week-relative+1": "Săptămâna viitoare",
+	"months-format-abbr": [
+		"Tișrei",
+		"Heșvan",
+		"Kislev",
+		"Tevet",
+		"Șevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tammuz",
+		"Av",
+		"Elul"
+	],
+	"field-month-relative+0": "Luna aceasta",
+	"field-month": "lună",
+	"field-month-relative+1": "Luna viitoare",
+	"quarters-format-abbr": [
+		"trim. I",
+		"trim. II",
+		"trim. III",
+		"trim. IV"
+	],
+	"days-format-abbr": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
+	"days-format-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"field-second": "secundă",
+	"field-day": "zi",
+	"dateFormatItem-MEd": "E, dd.MM",
+	"days-standAlone-short": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
+	"days-standAlone-abbr": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
+	"months-standAlone-wide-leap": "Adar II",
+	"dateFormat-short": "dd.MM.y GGGGG",
+	"dateFormatItem-Md": "dd.MM",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"months-format-wide": [
+		"Tișrei",
+		"Heșvan",
+		"Kislev",
+		"Tevet",
+		"Șevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tammuz",
+		"Av",
+		"Elul"
+	],
+	"days-format-short": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
+	"months-format-wide-leap": "Adar II",
+	"field-month-relative+-1": "Luna trecută",
+	"quarters-format-wide": [
+		"trimestrul I",
+		"trimestrul al II-lea",
+		"trimestrul al III-lea",
+		"trimestrul al IV-lea"
+	],
+	"days-format-wide": [
+		"duminică",
+		"luni",
+		"marți",
+		"miercuri",
+		"joi",
+		"vineri",
+		"sâmbătă"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/islamic.js b/dojo/cldr/nls/ro/islamic.js
new file mode 100644
index 0000000..33fa550
--- /dev/null
+++ b/dojo/cldr/nls/ro/islamic.js
@@ -0,0 +1,154 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "perioada zilei",
+	"field-minute": "minut",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day-relative+-1": "ieri",
+	"field-weekday": "zi a săptămânii",
+	"field-day-relative+-2": "alaltăieri",
+	"days-standAlone-wide": [
+		"duminică",
+		"luni",
+		"marți",
+		"miercuri",
+		"joi",
+		"vineri",
+		"sâmbătă"
+	],
+	"dateTimeFormat-short": "{1}, {0}",
+	"field-era": "eră",
+	"field-hour": "oră",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"quarters-standAlone-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormatItem-y": "y",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "azi",
+	"field-day-relative+1": "mâine",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"field-day-relative+2": "poimâine",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "zonă",
+	"field-week-relative+-1": "Săptămâna trecută",
+	"dateFormat-medium": "dd.MM.y G",
+	"field-year-relative+0": "Anul acesta",
+	"field-year-relative+1": "Anul viitor",
+	"quarters-standAlone-wide": [
+		"trimestrul I",
+		"trimestrul al II-lea",
+		"trimestrul al III-lea",
+		"trimestrul al IV-lea"
+	],
+	"field-year-relative+-1": "Anul trecut",
+	"field-year": "an",
+	"quarters-standAlone-narrow": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateTimeFormat-long": "{1}, {0}",
+	"field-week": "săptămână",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "Săptămâna aceasta",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"T4"
+	],
+	"field-week-relative+1": "Săptămâna viitoare",
+	"field-month-relative+0": "Luna aceasta",
+	"field-month": "lună",
+	"field-month-relative+1": "Luna viitoare",
+	"quarters-format-abbr": [
+		"trim. I",
+		"trim. II",
+		"trim. III",
+		"trim. IV"
+	],
+	"days-format-abbr": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
+	"days-format-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"field-second": "secundă",
+	"field-day": "zi",
+	"dateFormatItem-MEd": "E, dd.MM",
+	"days-standAlone-short": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
+	"days-standAlone-abbr": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
+	"dateFormat-short": "dd.MM.y GGGGG",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormatItem-Md": "dd.MM",
+	"dateFormatItem-yMEd": "E, dd.MM.y",
+	"days-format-short": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
+	"field-month-relative+-1": "Luna trecută",
+	"quarters-format-wide": [
+		"trimestrul I",
+		"trimestrul al II-lea",
+		"trimestrul al III-lea",
+		"trimestrul al IV-lea"
+	],
+	"days-format-wide": [
+		"duminică",
+		"luni",
+		"marți",
+		"miercuri",
+		"joi",
+		"vineri",
+		"sâmbătă"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/number.js b/dojo/cldr/nls/ro/number.js
index c6539c1..353371e 100644
--- a/dojo/cldr/nls/ro/number.js
+++ b/dojo/cldr/nls/ro/number.js
@@ -5,18 +5,18 @@ define(
 	"percentSign": "%",
 	"exponential": "E",
 	"scientificFormat": "#E0",
-	"percentFormat": "#,##0%",
+	"percentFormat": "#,##0 %",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 de trilioane",
+	"decimalFormat-short": "000 T"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/roc.js b/dojo/cldr/nls/roc.js
new file mode 100644
index 0000000..259e14b
--- /dev/null
+++ b/dojo/cldr/nls/roc.js
@@ -0,0 +1,449 @@
+define({ root:
+
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-weekday": "Day of the Week",
+	"months at localeAlias480": {
+		"bundle": "gregorian",
+		"target": "months"
+	},
+	"dateFormatItem-GyMMMEd": "G y MMM d, E",
+	"dateFormatItem-MMMEd": "MMM d, E",
+	"eraNarrow": [
+		"Before R.O.C.",
+		"R.O.C."
+	],
+	"days-format-short": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "G y MMMM d",
+	"months-format-wide": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "G y MMMM d, EEEE",
+	"eraNames at localeAlias510": {
+		"bundle": "roc",
+		"target": "eraAbbr"
+	},
+	"dateFormatItem-yyyyMEd": "GGGGG y-MM-dd, E",
+	"dateFormat at localeAlias512": {
+		"bundle": "generic",
+		"target": "dateFormat"
+	},
+	"quarters-format-abbr at localeAlias498": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"quarters-format-narrow at localeAlias499": {
+		"bundle": "gregorian",
+		"target": "quarters-standAlone-narrow"
+	},
+	"dayPeriods-format-narrow at localeAlias505": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dayPeriods-format-narrow at localeAlias506": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormatItem-Md": "MM-dd",
+	"dayPeriods-format-abbr-am": "AM",
+	"dayPeriods-format-narrow at localeAlias508": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-abbr"
+	},
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"dayPeriods-format-narrow at localeAlias509": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"field-era": "Era",
+	"months-standAlone-wide at localeAlias485": {
+		"bundle": "gregorian",
+		"target": "months-format-wide"
+	},
+	"months-standAlone-wide": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Year",
+	"dateTimeFormats-appendItem-Era": "{1} {0}",
+	"field-hour": "Hour",
+	"months-format-abbr": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"timeFormat at localeAlias513": {
+		"bundle": "gregorian",
+		"target": "timeFormat"
+	},
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-GyMMMd": "G y MMM d",
+	"months-standAlone-abbr": [
+		"Month1",
+		"Month2",
+		"Month3",
+		"Month4",
+		"Month5",
+		"Month6",
+		"Month7",
+		"Month8",
+		"Month9",
+		"Month10",
+		"Month11",
+		"Month12"
+	],
+	"dateFormatItem-H": "HH",
+	"quarters-format-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"quarters-standAlone-wide": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "G y MMM d, E",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dayPeriods at localeAlias503": {
+		"bundle": "gregorian",
+		"target": "dayPeriods"
+	},
+	"dateFormatItem-yyyyMMM": "G y MMM",
+	"dateFormatItem-yyyyMMMd": "G y MMM d",
+	"months-standAlone-abbr at localeAlias483": {
+		"bundle": "gregorian",
+		"target": "months-format-abbr"
+	},
+	"months-standAlone-abbr at localeAlias484": {
+		"bundle": "gregorian",
+		"target": "months-format-wide"
+	},
+	"months-format-abbr at localeAlias481": {
+		"bundle": "gregorian",
+		"target": "months-format-wide"
+	},
+	"timeFormat-medium": "HH:mm:ss",
+	"quarters-standAlone-wide at localeAlias502": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"quarters-standAlone-abbr": [
+		"Q1",
+		"Q2",
+		"Q3",
+		"Q4"
+	],
+	"dateFormatItem-Hm": "HH:mm",
+	"eraAbbr": [
+		"Before R.O.C.",
+		"R.O.C."
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
+	"days-standAlone-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"quarters at localeAlias497": {
+		"bundle": "gregorian",
+		"target": "quarters"
+	},
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
+	"field-day-relative+-1": "Yesterday",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateTimeFormat-long": "{1} {0}",
+	"dateFormatItem-h": "h a",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "MM-dd, E",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "Day",
+	"days-format-wide": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"months-format-narrow at localeAlias482": {
+		"bundle": "gregorian",
+		"target": "months-standAlone-narrow"
+	},
+	"field-zone": "Zone",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-y": "G y",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{1} {0}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
+	"days-format-short at localeAlias489": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"eraNames": [
+		"Before R.O.C.",
+		"R.O.C."
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"quarters-standAlone-abbr at localeAlias500": {
+		"bundle": "gregorian",
+		"target": "quarters-format-abbr"
+	},
+	"quarters-standAlone-abbr at localeAlias501": {
+		"bundle": "gregorian",
+		"target": "quarters-format-wide"
+	},
+	"dateTime at localeAlias514": {
+		"bundle": "generic",
+		"target": "dateTime"
+	},
+	"dateFormatItem-yyyyMd": "GGGGG y-MM-dd",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dayPeriods-format-abbr at localeAlias504": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"eraNarrow at localeAlias511": {
+		"bundle": "roc",
+		"target": "eraAbbr"
+	},
+	"dayPeriods-format-abbr at localeAlias507": {
+		"bundle": "gregorian",
+		"target": "dayPeriods-format-wide"
+	},
+	"days-standAlone-wide at localeAlias496": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"days-format-short at localeAlias490": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormat-short": "GGGGG y-MM-dd",
+	"field-second": "Second",
+	"days-standAlone-abbr at localeAlias491": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-standAlone-abbr at localeAlias492": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-standAlone-short at localeAlias493": {
+		"bundle": "gregorian",
+		"target": "days-format-short"
+	},
+	"days-standAlone-short at localeAlias494": {
+		"bundle": "gregorian",
+		"target": "days-format-abbr"
+	},
+	"days-standAlone-short at localeAlias495": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"days-format-abbr at localeAlias487": {
+		"bundle": "gregorian",
+		"target": "days-format-wide"
+	},
+	"dateFormatItem-Ed": "d, E",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "G y MMM d",
+	"dateFormatItem-yyyyM": "GGGGG y-MM",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"days-format-narrow at localeAlias488": {
+		"bundle": "gregorian",
+		"target": "days-standAlone-narrow"
+	},
+	"dateFormatItem-hms": "h:mm:ss a",
+	"days at localeAlias486": {
+		"bundle": "gregorian",
+		"target": "days"
+	},
+	"dateFormatItem-GyMMM": "G y MMM",
+	"dateFormatItem-yyyy": "G y"
+}
+//end v1.x content
+,
+	"ar": true,
+	"ca": true,
+	"cs": true,
+	"da": true,
+	"de": true,
+	"el": true,
+	"en": true,
+	"es": true,
+	"fi": true,
+	"fr": true,
+	"hu": true,
+	"it": true,
+	"ja": true,
+	"ko": true,
+	"nb": true,
+	"nl": true,
+	"pl": true,
+	"pt": true,
+	"pt-pt": true,
+	"ru": true,
+	"sv": true,
+	"th": true,
+	"tr": true,
+	"zh": true,
+	"zh-hant": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/buddhist.js b/dojo/cldr/nls/ru/buddhist.js
new file mode 100644
index 0000000..9f05ce2
--- /dev/null
+++ b/dojo/cldr/nls/ru/buddhist.js
@@ -0,0 +1,254 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"months-format-narrow": [
+		"Я",
+		"Ф",
+		"М",
+		"А",
+		"М",
+		"И",
+		"И",
+		"А",
+		"С",
+		"О",
+		"Н",
+		"Д"
+	],
+	"field-weekday": "День недели",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-MMMEd": "ccc, d MMM",
+	"days-format-short": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"dateFormat-long": "d MMMM y 'г'. G",
+	"months-format-wide": [
+		"января",
+		"февраля",
+		"марта",
+		"апреля",
+		"мая",
+		"июня",
+		"июля",
+		"августа",
+		"сентября",
+		"октября",
+		"ноября",
+		"декабря"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dayPeriods-format-wide-pm": "после полудня",
+	"dateFormat-full": "EEEE, d MMMM y 'г'. G",
+	"dateFormatItem-yyyyMEd": "E, dd.MM.y G",
+	"dateFormatItem-Md": "dd.MM",
+	"dayPeriods-format-abbr-am": "до полудня",
+	"field-era": "Эра",
+	"months-standAlone-wide": [
+		"Январь",
+		"Февраль",
+		"Март",
+		"Апрель",
+		"Май",
+		"Июнь",
+		"Июль",
+		"Август",
+		"Сентябрь",
+		"Октябрь",
+		"Ноябрь",
+		"Декабрь"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
+		"4-й квартал"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "Год",
+	"field-hour": "Час",
+	"months-format-abbr": [
+		"янв.",
+		"февр.",
+		"марта",
+		"апр.",
+		"мая",
+		"июня",
+		"июля",
+		"авг.",
+		"сент.",
+		"окт.",
+		"нояб.",
+		"дек."
+	],
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "Сегодня",
+	"field-day-relative+1": "Завтра",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "Послезавтра",
+	"dateFormatItem-H": "H",
+	"months-standAlone-abbr": [
+		"Янв.",
+		"Февр.",
+		"Март",
+		"Апр.",
+		"Май",
+		"Июнь",
+		"Июль",
+		"Авг.",
+		"Сент.",
+		"Окт.",
+		"Нояб.",
+		"Дек."
+	],
+	"quarters-format-abbr": [
+		"1-й кв.",
+		"2-й кв.",
+		"3-й кв.",
+		"4-й кв."
+	],
+	"quarters-standAlone-wide": [
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
+		"4-й квартал"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E, d MMM y G",
+	"days-standAlone-wide": [
+		"Воскресенье",
+		"Понедельник",
+		"Вторник",
+		"Среда",
+		"Четверг",
+		"Пятница",
+		"Суббота"
+	],
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"1-й кв.",
+		"2-й кв.",
+		"3-й кв.",
+		"4-й кв."
+	],
+	"eraAbbr": [
+		"BE"
+	],
+	"field-minute": "Минута",
+	"field-dayperiod": "ДП/ПП",
+	"days-standAlone-abbr": [
+		"Вс",
+		"Пн",
+		"Вт",
+		"Ср",
+		"Чт",
+		"Пт",
+		"Сб"
+	],
+	"field-day-relative+-1": "Вчера",
+	"dateTimeFormat-long": "{1}, {0}",
+	"dayPeriods-format-narrow-am": "дп",
+	"field-day-relative+-2": "Позавчера",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, dd.MM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day": "День",
+	"days-format-wide": [
+		"воскресенье",
+		"понедельник",
+		"вторник",
+		"среда",
+		"четверг",
+		"пятница",
+		"суббота"
+	],
+	"field-zone": "Часовой пояс",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"Я",
+		"Ф",
+		"М",
+		"А",
+		"М",
+		"И",
+		"И",
+		"А",
+		"С",
+		"О",
+		"Н",
+		"Д"
+	],
+	"field-year-relative+-1": "В прошлом году",
+	"field-month-relative+-1": "В прошлом месяце",
+	"dayPeriods-format-abbr-pm": "после полудня",
+	"days-format-abbr": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"days-format-narrow": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"dateFormatItem-yyyyMd": "dd.MM.y G",
+	"field-month": "Месяц",
+	"days-standAlone-narrow": [
+		"В",
+		"П",
+		"В",
+		"С",
+		"Ч",
+		"П",
+		"С"
+	],
+	"dayPeriods-format-wide-am": "до полудня",
+	"dateFormat-short": "dd.MM.y G",
+	"field-second": "Секунда",
+	"field-month-relative+0": "В этом месяце",
+	"field-month-relative+1": "В следующем месяце",
+	"dateFormatItem-Ed": "E, d",
+	"field-week": "Неделя",
+	"dateFormat-medium": "dd.MM.y G",
+	"field-year-relative+0": "В этом году",
+	"field-week-relative+-1": "На прошлой неделе",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"field-year-relative+1": "В следующем году",
+	"dayPeriods-format-narrow-pm": "пп",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y 'г'. G",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "На этой неделе",
+	"field-week-relative+1": "На следующей неделе"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/chinese.js b/dojo/cldr/nls/ru/chinese.js
new file mode 100644
index 0000000..9a43687
--- /dev/null
+++ b/dojo/cldr/nls/ru/chinese.js
@@ -0,0 +1,122 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d MMM U",
+	"field-dayperiod": "ДП/ПП",
+	"field-minute": "Минута",
+	"dateFormatItem-MMMEd": "ccc, d MMM",
+	"field-day-relative+-1": "Вчера",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "Позавчера",
+	"field-weekday": "День недели",
+	"dateFormatItem-MMM": "LLL",
+	"dateFormatItem-Gy": "U",
+	"field-era": "Эра",
+	"field-hour": "Час",
+	"dateFormatItem-y": "U",
+	"dateFormatItem-yyyy": "U",
+	"months-standAlone-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-Ed": "E, d",
+	"field-day-relative+0": "Сегодня",
+	"field-day-relative+1": "Завтра",
+	"field-day-relative+2": "Послезавтра",
+	"dateFormatItem-GyMMMd": "d MMM U",
+	"dateFormatItem-yyyyMMMM": "LLLL U",
+	"dateFormat-long": "d MMMM U",
+	"field-zone": "Часовой пояс",
+	"dateFormatItem-Hm": "H:mm",
+	"field-week-relative+-1": "На прошлой неделе",
+	"dateFormat-medium": "dd.MM U",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"field-year-relative+0": "В этом году",
+	"field-year-relative+1": "В следующем году",
+	"field-year-relative+-1": "В прошлом году",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ U",
+	"field-year": "Год",
+	"months-standAlone-wide": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-week": "Неделя",
+	"dateFormatItem-yyyyMd": "dd.MM.y",
+	"dateFormatItem-yyyyMMMd": "d MMM U",
+	"dateFormatItem-yyyyMEd": "E, dd.MM.y",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "На этой неделе",
+	"field-week-relative+1": "На следующей неделе",
+	"months-format-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-E": "ccc",
+	"field-month-relative+0": "В этом месяце",
+	"dateFormatItem-H": "H",
+	"field-month": "Месяц",
+	"field-month-relative+1": "В следующем месяце",
+	"dateFormatItem-M": "L",
+	"field-second": "Секунда",
+	"dateFormatItem-GyMMMEd": "E, d MMM U",
+	"dateFormatItem-GyMMM": "LLL U",
+	"field-day": "День",
+	"dateFormatItem-MEd": "E, dd.MM",
+	"dateFormatItem-yyyyQQQ": "QQQ U",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd.MM.y",
+	"dateFormatItem-yyyyM": "MM.y",
+	"dateFormat-full": "EEEE, d MMMM U",
+	"dateFormatItem-Md": "dd.MM",
+	"dateFormatItem-yyyyMMM": "LLL U",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "В прошлом месяце",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/coptic.js b/dojo/cldr/nls/ru/coptic.js
new file mode 100644
index 0000000..8d32883
--- /dev/null
+++ b/dojo/cldr/nls/ru/coptic.js
@@ -0,0 +1,106 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Секунда",
+	"field-year-relative+-1": "В прошлом году",
+	"field-week": "Неделя",
+	"field-month-relative+-1": "В прошлом месяце",
+	"field-day-relative+-1": "Вчера",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "Позавчера",
+	"months-standAlone-wide": [
+		"Тот",
+		"Бабэ",
+		"Хатур",
+		"Кихак",
+		"Тубэ",
+		"Амшир",
+		"Барамхат",
+		"Бармуда",
+		"Башнас",
+		"Бауна",
+		"Абиб",
+		"Мисра",
+		"Наси"
+	],
+	"field-year": "Год",
+	"field-week-relative+0": "На этой неделе",
+	"months-standAlone-abbr": [
+		"Тот",
+		"Бабэ",
+		"Хатур",
+		"Кихак",
+		"Тубэ",
+		"Амшир",
+		"Барамхат",
+		"Бармуда",
+		"Башнас",
+		"Бауна",
+		"Абиб",
+		"Мисра",
+		"Наси"
+	],
+	"field-week-relative+1": "На следующей неделе",
+	"field-minute": "Минута",
+	"field-week-relative+-1": "На прошлой неделе",
+	"field-day-relative+0": "Сегодня",
+	"field-hour": "Час",
+	"field-day-relative+1": "Завтра",
+	"field-day-relative+2": "Послезавтра",
+	"field-day": "День",
+	"field-month-relative+0": "В этом месяце",
+	"field-month-relative+1": "В следующем месяце",
+	"field-dayperiod": "ДП/ПП",
+	"field-month": "Месяц",
+	"months-format-wide": [
+		"Тот",
+		"Бабэ",
+		"Хатур",
+		"Кихак",
+		"Тубэ",
+		"Амшир",
+		"Барамхат",
+		"Бармуда",
+		"Башнас",
+		"Бауна",
+		"Абиб",
+		"Мисра",
+		"Наси"
+	],
+	"field-era": "Эра",
+	"field-year-relative+0": "В этом году",
+	"field-year-relative+1": "В следующем году",
+	"months-format-abbr": [
+		"Тот",
+		"Бабэ",
+		"Хатур",
+		"Кихак",
+		"Тубэ",
+		"Амшир",
+		"Барамхат",
+		"Бармуда",
+		"Башнас",
+		"Бауна",
+		"Абиб",
+		"Мисра",
+		"Наси"
+	],
+	"field-weekday": "День недели",
+	"field-zone": "Часовой пояс"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/currency.js b/dojo/cldr/nls/ru/currency.js
index e5b2b20..8f0e51a 100644
--- a/dojo/cldr/nls/ru/currency.js
+++ b/dojo/cldr/nls/ru/currency.js
@@ -3,6 +3,7 @@ define(
 {
 	"HKD_displayName": "Гонконгский доллар",
 	"CHF_displayName": "Швейцарский франк",
+	"JPY_symbol": "¥",
 	"CAD_displayName": "Канадский доллар",
 	"CNY_displayName": "Юань Ренминби",
 	"USD_symbol": "$",
diff --git a/dojo/cldr/nls/ru/ethiopic.js b/dojo/cldr/nls/ru/ethiopic.js
new file mode 100644
index 0000000..6e131b6
--- /dev/null
+++ b/dojo/cldr/nls/ru/ethiopic.js
@@ -0,0 +1,106 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Секунда",
+	"field-year-relative+-1": "В прошлом году",
+	"field-week": "Неделя",
+	"field-month-relative+-1": "В прошлом месяце",
+	"field-day-relative+-1": "Вчера",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "Позавчера",
+	"months-standAlone-wide": [
+		"Мескерем",
+		"Текемт",
+		"Хедар",
+		"Тахсас",
+		"Тер",
+		"Якатит",
+		"Магабит",
+		"Миазия",
+		"Генбот",
+		"Сэнэ",
+		"Хамлэ",
+		"Нахасэ",
+		"Эпагомен"
+	],
+	"field-year": "Год",
+	"field-week-relative+0": "На этой неделе",
+	"months-standAlone-abbr": [
+		"Мескерем",
+		"Текемт",
+		"Хедар",
+		"Тахсас",
+		"Тер",
+		"Якатит",
+		"Магабит",
+		"Миазия",
+		"Генбот",
+		"Сэнэ",
+		"Хамлэ",
+		"Нахасэ",
+		"Эпагомен"
+	],
+	"field-week-relative+1": "На следующей неделе",
+	"field-minute": "Минута",
+	"field-week-relative+-1": "На прошлой неделе",
+	"field-day-relative+0": "Сегодня",
+	"field-hour": "Час",
+	"field-day-relative+1": "Завтра",
+	"field-day-relative+2": "Послезавтра",
+	"field-day": "День",
+	"field-month-relative+0": "В этом месяце",
+	"field-month-relative+1": "В следующем месяце",
+	"field-dayperiod": "ДП/ПП",
+	"field-month": "Месяц",
+	"months-format-wide": [
+		"Мескерем",
+		"Текемт",
+		"Хедар",
+		"Тахсас",
+		"Тер",
+		"Якатит",
+		"Магабит",
+		"Миазия",
+		"Генбот",
+		"Сэнэ",
+		"Хамлэ",
+		"Нахасэ",
+		"Эпагомен"
+	],
+	"field-era": "Эра",
+	"field-year-relative+0": "В этом году",
+	"field-year-relative+1": "В следующем году",
+	"months-format-abbr": [
+		"Мескерем",
+		"Текемт",
+		"Хедар",
+		"Тахсас",
+		"Тер",
+		"Якатит",
+		"Магабит",
+		"Миазия",
+		"Генбот",
+		"Сэнэ",
+		"Хамлэ",
+		"Нахасэ",
+		"Эпагомен"
+	],
+	"field-weekday": "День недели",
+	"field-zone": "Часовой пояс"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/generic.js b/dojo/cldr/nls/ru/generic.js
new file mode 100644
index 0000000..4979629
--- /dev/null
+++ b/dojo/cldr/nls/ru/generic.js
@@ -0,0 +1,70 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E, d MMM y G",
+	"field-dayperiod": "ДП/ПП",
+	"field-minute": "Минута",
+	"dateFormatItem-MMMEd": "ccc, d MMM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day-relative+-1": "Вчера",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "Позавчера",
+	"field-weekday": "День недели",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"field-era": "Эра",
+	"field-hour": "Час",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E, d",
+	"field-day-relative+0": "Сегодня",
+	"field-day-relative+1": "Завтра",
+	"field-day-relative+2": "Послезавтра",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMMMM": "LLLL y G",
+	"dateFormat-long": "d MMMM y 'г'. G",
+	"field-zone": "Часовой пояс",
+	"dateFormatItem-Hm": "H:mm",
+	"field-week-relative+-1": "На прошлой неделе",
+	"dateFormat-medium": "dd.MM.y G",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"field-year-relative+0": "В этом году",
+	"field-year-relative+1": "В следующем году",
+	"field-year-relative+-1": "В прошлом году",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y 'г'. G",
+	"field-year": "Год",
+	"dateTimeFormat-long": "{1}, {0}",
+	"field-week": "Неделя",
+	"dateFormatItem-yyyyMd": "dd.MM.y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMEd": "E, dd.MM.y G",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "На этой неделе",
+	"field-week-relative+1": "На следующей неделе",
+	"dateFormatItem-E": "ccc",
+	"field-month-relative+0": "В этом месяце",
+	"dateFormatItem-H": "H",
+	"field-month": "Месяц",
+	"field-month-relative+1": "В следующем месяце",
+	"dateFormatItem-M": "L",
+	"field-second": "Секунда",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"field-day": "День",
+	"dateFormatItem-MEd": "E, dd.MM",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "dd.MM.y G",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"dateFormat-full": "EEEE, d MMMM y 'г'. G",
+	"dateFormatItem-Md": "dd.MM",
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "В прошлом месяце",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/gregorian.js b/dojo/cldr/nls/ru/gregorian.js
index 83db44d..db6a822 100644
--- a/dojo/cldr/nls/ru/gregorian.js
+++ b/dojo/cldr/nls/ru/gregorian.js
@@ -1,30 +1,16 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M.y",
-	"field-dayperiod": "AM/PM",
-	"field-minute": "Минута",
-	"eraNames": [
-		"до н.э.",
-		"н.э."
-	],
-	"dateFormatItem-MMMEd": "ccc, d MMM",
-	"field-day-relative+-1": "Вчера",
-	"field-weekday": "День недели",
-	"dateFormatItem-yQQQ": "y QQQ",
-	"field-day-relative+-2": "Позавчера",
-	"dateFormatItem-MMdd": "dd.MM",
-	"days-standAlone-wide": [
-		"Воскресенье",
-		"Понедельник",
-		"Вторник",
-		"Среда",
-		"Четверг",
-		"Пятница",
-		"Суббота"
+	"days-standAlone-short": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
 	],
-	"dateFormatItem-MMM": "LLL",
-	"months-standAlone-narrow": [
+	"months-format-narrow": [
 		"Я",
 		"Ф",
 		"М",
@@ -38,70 +24,48 @@ define(
 		"Н",
 		"Д"
 	],
-	"field-era": "Эра",
-	"field-hour": "Час",
-	"quarters-standAlone-abbr": [
-		"1-й кв.",
-		"2-й кв.",
-		"3-й кв.",
-		"4-й кв."
-	],
-	"dateFormatItem-yyMMMEEEd": "EEE, d MMM yy",
-	"dateFormatItem-y": "y",
-	"timeFormat-full": "H:mm:ss zzzz",
-	"dateFormatItem-yyyy": "y",
-	"months-standAlone-abbr": [
-		"янв.",
-		"февр.",
-		"март",
-		"апр.",
-		"май",
-		"июнь",
-		"июль",
-		"авг.",
-		"сент.",
-		"окт.",
-		"нояб.",
-		"дек."
-	],
-	"dateFormatItem-Ed": "E, d",
-	"dateFormatItem-yMMM": "LLL y",
-	"field-day-relative+0": "Сегодня",
-	"dateFormatItem-yyyyLLLL": "LLLL y",
-	"field-day-relative+1": "Завтра",
-	"days-standAlone-narrow": [
-		"В",
-		"П",
-		"В",
-		"С",
-		"Ч",
-		"П",
-		"С"
-	],
-	"eraAbbr": [
+	"field-weekday": "День недели",
+	"dateFormatItem-yQQQ": "QQQ y 'г'.",
+	"dateFormatItem-yMEd": "ccc, d.MM.y 'г'.",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-MMMEd": "ccc, d MMM",
+	"eraNarrow": [
 		"до н.э.",
 		"н.э."
 	],
-	"field-day-relative+2": "Послезавтра",
-	"dateFormatItem-yyyyMM": "MM.yyyy",
-	"dateFormatItem-yyyyMMMM": "LLLL y",
-	"dateFormat-long": "d MMMM y 'г'.",
-	"timeFormat-medium": "H:mm:ss",
-	"field-zone": "Часовой пояс",
-	"dateFormatItem-Hm": "H:mm",
-	"dateFormat-medium": "dd.MM.yyyy",
-	"dateFormatItem-yyMM": "MM.yy",
-	"dateFormatItem-Hms": "H:mm:ss",
-	"dateFormatItem-yyMMM": "LLL yy",
-	"quarters-standAlone-wide": [
-		"1-й квартал",
-		"2-й квартал",
-		"3-й квартал",
-		"4-й квартал"
+	"dateFormatItem-yMM": "MM.y",
+	"days-format-short": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
 	],
-	"dateFormatItem-ms": "mm:ss",
-	"dateFormatItem-yyyyQQQQ": "QQQQ y 'г'.",
-	"field-year": "Год",
+	"dateFormat-long": "d MMMM y 'г'.",
+	"months-format-wide": [
+		"января",
+		"февраля",
+		"марта",
+		"апреля",
+		"мая",
+		"июня",
+		"июля",
+		"августа",
+		"сентября",
+		"октября",
+		"ноября",
+		"декабря"
+	],
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dayPeriods-format-wide-pm": "после полудня",
+	"dateFormat-full": "EEEE, d MMMM y 'г'.",
+	"dateFormatItem-Md": "dd.MM",
+	"dayPeriods-format-abbr-am": "до полудня",
+	"dateFormatItem-yMd": "dd.MM.y",
+	"dateFormatItem-yM": "MM.y",
+	"field-era": "Эра",
 	"months-standAlone-wide": [
 		"Январь",
 		"Февраль",
@@ -116,10 +80,19 @@ define(
 		"Ноябрь",
 		"Декабрь"
 	],
-	"field-week": "Неделя",
-	"dateFormatItem-MMMd": "d MMM",
-	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
+		"4-й квартал"
+	],
 	"timeFormat-long": "H:mm:ss z",
+	"dateFormatItem-yMMM": "LLL y",
+	"dateFormatItem-yQQQQ": "QQQQ y 'г'.",
+	"field-year": "Год",
+	"dateFormatItem-MMdd": "dd.MM",
+	"field-hour": "Час",
 	"months-format-abbr": [
 		"янв.",
 		"февр.",
@@ -134,51 +107,65 @@ define(
 		"нояб.",
 		"дек."
 	],
-	"timeFormat-short": "H:mm",
+	"timeFormat-full": "H:mm:ss zzzz",
+	"dateFormatItem-E": "ccc",
+	"field-day-relative+0": "Сегодня",
+	"field-day-relative+1": "Завтра",
+	"dateFormatItem-GyMMMd": "d MMM y 'г'. G",
+	"field-day-relative+2": "Послезавтра",
 	"dateFormatItem-H": "H",
-	"field-month": "Месяц",
+	"months-standAlone-abbr": [
+		"Янв.",
+		"Февр.",
+		"Март",
+		"Апр.",
+		"Май",
+		"Июнь",
+		"Июль",
+		"Авг.",
+		"Сент.",
+		"Окт.",
+		"Нояб.",
+		"Дек."
+	],
 	"quarters-format-abbr": [
 		"1-й кв.",
 		"2-й кв.",
 		"3-й кв.",
 		"4-й кв."
 	],
-	"days-format-abbr": [
-		"вс",
-		"пн",
-		"вт",
-		"ср",
-		"чт",
-		"пт",
-		"сб"
+	"quarters-standAlone-wide": [
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
+		"4-й квартал"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
-	"days-format-narrow": [
-		"В",
-		"П",
-		"В",
-		"С",
-		"Ч",
-		"П",
-		"С"
+	"days-standAlone-wide": [
+		"Воскресенье",
+		"Понедельник",
+		"Вторник",
+		"Среда",
+		"Четверг",
+		"Пятница",
+		"Суббота"
 	],
-	"field-second": "Секунда",
-	"field-day": "День",
-	"dateFormatItem-MEd": "E, d.M",
-	"months-format-narrow": [
-		"Я",
-		"Ф",
-		"М",
-		"А",
-		"М",
-		"И",
-		"И",
-		"А",
-		"С",
-		"О",
-		"Н",
-		"Д"
+	"dateFormatItem-yLLLL": "LLLL y",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"1-й кв.",
+		"2-й кв.",
+		"3-й кв.",
+		"4-й кв."
+	],
+	"eraAbbr": [
+		"до н.э.",
+		"н.э."
 	],
+	"field-minute": "Минута",
+	"field-dayperiod": "ДП/ПП",
 	"days-standAlone-abbr": [
 		"Вс",
 		"Пн",
@@ -188,32 +175,24 @@ define(
 		"Пт",
 		"Сб"
 	],
-	"dateFormat-short": "dd.MM.yy",
-	"dateFormatItem-yMMMEd": "E, d MMM y",
-	"dateFormat-full": "EEEE, d MMMM y 'г'.",
-	"dateFormatItem-Md": "d.M",
-	"dateFormatItem-yMEd": "EEE, d.M.y",
-	"months-format-wide": [
-		"января",
-		"февраля",
-		"марта",
-		"апреля",
-		"мая",
-		"июня",
-		"июля",
-		"августа",
-		"сентября",
-		"октября",
-		"ноября",
-		"декабря"
-	],
 	"dateFormatItem-d": "d",
-	"quarters-format-wide": [
-		"1-й квартал",
-		"2-й квартал",
-		"3-й квартал",
-		"4-й квартал"
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
 	],
+	"field-day-relative+-1": "Вчера",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1}, {0}",
+	"dayPeriods-format-narrow-am": "дп",
+	"field-day-relative+-2": "Позавчера",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, dd.MM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"dateFormatItem-yMMMM": "LLLL y",
+	"field-day": "День",
 	"days-format-wide": [
 		"воскресенье",
 		"понедельник",
@@ -223,10 +202,79 @@ define(
 		"пятница",
 		"суббота"
 	],
-	"eraNarrow": [
+	"field-zone": "Часовой пояс",
+	"dateFormatItem-y": "y",
+	"months-standAlone-narrow": [
+		"Я",
+		"Ф",
+		"М",
+		"А",
+		"М",
+		"И",
+		"И",
+		"А",
+		"С",
+		"О",
+		"Н",
+		"Д"
+	],
+	"field-year-relative+-1": "В прошлом году",
+	"field-month-relative+-1": "В прошлом месяце",
+	"dateFormatItem-hm": "h:mm a",
+	"dayPeriods-format-abbr-pm": "после полудня",
+	"days-format-abbr": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"dateFormatItem-yMMMd": "d MMM y 'г'.",
+	"eraNames": [
 		"до н.э.",
 		"н.э."
-	]
+	],
+	"days-format-narrow": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"days-standAlone-narrow": [
+		"В",
+		"П",
+		"В",
+		"С",
+		"Ч",
+		"П",
+		"С"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Месяц",
+	"dayPeriods-format-wide-am": "до полудня",
+	"dateFormat-short": "dd.MM.yy",
+	"field-second": "Секунда",
+	"dateFormatItem-yMMMEd": "E, d MMM y",
+	"field-month-relative+0": "В этом месяце",
+	"field-month-relative+1": "В следующем месяце",
+	"dateFormatItem-Ed": "ccc, d",
+	"field-week": "Неделя",
+	"dateFormat-medium": "dd MMM y 'г'.",
+	"field-year-relative+0": "В этом году",
+	"field-week-relative+-1": "На прошлой неделе",
+	"field-year-relative+1": "В следующем году",
+	"dayPeriods-format-narrow-pm": "пп",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"field-week-relative+0": "На этой неделе",
+	"field-week-relative+1": "На следующей неделе"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/hebrew.js b/dojo/cldr/nls/ru/hebrew.js
new file mode 100644
index 0000000..8c58ebb
--- /dev/null
+++ b/dojo/cldr/nls/ru/hebrew.js
@@ -0,0 +1,231 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"field-weekday": "День недели",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-MMMEd": "ccc, d MMM",
+	"days-format-short": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"dateFormat-long": "d MMMM y 'г'. G",
+	"months-format-wide": [
+		"Тишрей",
+		"Хешван",
+		"Кислев",
+		"Тевет",
+		"Шеват",
+		"Адар I",
+		"Адар",
+		"Нисан",
+		"Ияр",
+		"Сиван",
+		"Таммуз",
+		"Ав",
+		"Элул"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dayPeriods-format-wide-pm": "после полудня",
+	"dateFormat-full": "EEEE, d MMMM y 'г'. G",
+	"dateFormatItem-yyyyMEd": "E, dd.MM.y G",
+	"dateFormatItem-Md": "dd.MM",
+	"dayPeriods-format-abbr-am": "до полудня",
+	"field-era": "Эра",
+	"months-standAlone-wide": [
+		"Тишрей",
+		"Хешван",
+		"Кислев",
+		"Тевет",
+		"Шеват",
+		"Адар I",
+		"Адар",
+		"Нисан",
+		"Ияр",
+		"Сиван",
+		"Таммуз",
+		"Ав",
+		"Элул"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
+		"4-й квартал"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "Год",
+	"field-hour": "Час",
+	"months-format-abbr-leap": "Адар II",
+	"months-format-abbr": [
+		"Тишрей",
+		"Хешван",
+		"Кислев",
+		"Тевет",
+		"Шеват",
+		"Адар I",
+		"Адар",
+		"Нисан",
+		"Ияр",
+		"Сиван",
+		"Таммуз",
+		"Ав",
+		"Элул"
+	],
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "Сегодня",
+	"field-day-relative+1": "Завтра",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "Послезавтра",
+	"dateFormatItem-H": "H",
+	"months-standAlone-abbr": [
+		"Тишрей",
+		"Хешван",
+		"Кислев",
+		"Тевет",
+		"Шеват",
+		"Адар I",
+		"Адар",
+		"Нисан",
+		"Ияр",
+		"Сиван",
+		"Таммуз",
+		"Ав",
+		"Элул"
+	],
+	"quarters-format-abbr": [
+		"1-й кв.",
+		"2-й кв.",
+		"3-й кв.",
+		"4-й кв."
+	],
+	"quarters-standAlone-wide": [
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
+		"4-й квартал"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E, d MMM y G",
+	"days-standAlone-wide": [
+		"Воскресенье",
+		"Понедельник",
+		"Вторник",
+		"Среда",
+		"Четверг",
+		"Пятница",
+		"Суббота"
+	],
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"months-standAlone-wide-leap": "Адар II",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"1-й кв.",
+		"2-й кв.",
+		"3-й кв.",
+		"4-й кв."
+	],
+	"field-minute": "Минута",
+	"field-dayperiod": "ДП/ПП",
+	"days-standAlone-abbr": [
+		"Вс",
+		"Пн",
+		"Вт",
+		"Ср",
+		"Чт",
+		"Пт",
+		"Сб"
+	],
+	"field-day-relative+-1": "Вчера",
+	"dateTimeFormat-long": "{1}, {0}",
+	"dayPeriods-format-narrow-am": "дп",
+	"field-day-relative+-2": "Позавчера",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, dd.MM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day": "День",
+	"days-format-wide": [
+		"воскресенье",
+		"понедельник",
+		"вторник",
+		"среда",
+		"четверг",
+		"пятница",
+		"суббота"
+	],
+	"field-zone": "Часовой пояс",
+	"months-standAlone-abbr-leap": "Адар II",
+	"dateFormatItem-y": "y G",
+	"field-year-relative+-1": "В прошлом году",
+	"field-month-relative+-1": "В прошлом месяце",
+	"dayPeriods-format-abbr-pm": "после полудня",
+	"days-format-abbr": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"days-format-narrow": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"dateFormatItem-yyyyMd": "dd.MM.y G",
+	"field-month": "Месяц",
+	"days-standAlone-narrow": [
+		"В",
+		"П",
+		"В",
+		"С",
+		"Ч",
+		"П",
+		"С"
+	],
+	"dayPeriods-format-wide-am": "до полудня",
+	"dateFormat-short": "dd.MM.y G",
+	"field-second": "Секунда",
+	"field-month-relative+0": "В этом месяце",
+	"field-month-relative+1": "В следующем месяце",
+	"dateFormatItem-Ed": "E, d",
+	"field-week": "Неделя",
+	"dateFormat-medium": "dd.MM.y G",
+	"field-year-relative+0": "В этом году",
+	"field-week-relative+-1": "На прошлой неделе",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"field-year-relative+1": "В следующем году",
+	"dayPeriods-format-narrow-pm": "пп",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y 'г'. G",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"months-format-wide-leap": "Адар II",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "На этой неделе",
+	"field-week-relative+1": "На следующей неделе"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/indian.js b/dojo/cldr/nls/ru/indian.js
new file mode 100644
index 0000000..0a4bb47
--- /dev/null
+++ b/dojo/cldr/nls/ru/indian.js
@@ -0,0 +1,101 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Секунда",
+	"field-year-relative+-1": "В прошлом году",
+	"field-week": "Неделя",
+	"field-month-relative+-1": "В прошлом месяце",
+	"field-day-relative+-1": "Вчера",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "Позавчера",
+	"months-standAlone-wide": [
+		"Чайтра",
+		"Ваисакха",
+		"Джанштха",
+		"Асадха",
+		"Сравана",
+		"Бхадра",
+		"Азвина",
+		"Картика",
+		"Аграхайана",
+		"Пауза",
+		"Магха",
+		"Пхалгуна"
+	],
+	"field-year": "Год",
+	"field-week-relative+0": "На этой неделе",
+	"months-standAlone-abbr": [
+		"Чайтра",
+		"Ваисакха",
+		"Джанштха",
+		"Асадха",
+		"Сравана",
+		"Бхадра",
+		"Азвина",
+		"Картика",
+		"Аграхайана",
+		"Пауза",
+		"Магха",
+		"Пхалгуна"
+	],
+	"field-week-relative+1": "На следующей неделе",
+	"field-minute": "Минута",
+	"field-week-relative+-1": "На прошлой неделе",
+	"field-day-relative+0": "Сегодня",
+	"field-hour": "Час",
+	"field-day-relative+1": "Завтра",
+	"field-day-relative+2": "Послезавтра",
+	"field-day": "День",
+	"field-month-relative+0": "В этом месяце",
+	"field-month-relative+1": "В следующем месяце",
+	"field-dayperiod": "ДП/ПП",
+	"field-month": "Месяц",
+	"months-format-wide": [
+		"Чайтра",
+		"Ваисакха",
+		"Джанштха",
+		"Асадха",
+		"Сравана",
+		"Бхадра",
+		"Азвина",
+		"Картика",
+		"Аграхайана",
+		"Пауза",
+		"Магха",
+		"Пхалгуна"
+	],
+	"field-era": "Эра",
+	"field-year-relative+0": "В этом году",
+	"field-year-relative+1": "В следующем году",
+	"months-format-abbr": [
+		"Чайтра",
+		"Ваисакха",
+		"Джанштха",
+		"Асадха",
+		"Сравана",
+		"Бхадра",
+		"Азвина",
+		"Картика",
+		"Аграхайана",
+		"Пауза",
+		"Магха",
+		"Пхалгуна"
+	],
+	"field-weekday": "День недели",
+	"field-zone": "Часовой пояс"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/islamic.js b/dojo/cldr/nls/ru/islamic.js
new file mode 100644
index 0000000..acaea90
--- /dev/null
+++ b/dojo/cldr/nls/ru/islamic.js
@@ -0,0 +1,237 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "День недели",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-MMMEd": "ccc, d MMM",
+	"days-format-short": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"dateFormat-long": "d MMMM y 'г'. G",
+	"months-format-wide": [
+		"Мухаррам",
+		"Сафар",
+		"Раби-уль-авваль",
+		"Раби-уль-ахир",
+		"Джумад-уль-авваль",
+		"Джумад-уль-ахир",
+		"Раджаб",
+		"Шаабан",
+		"Рамадан",
+		"Шавваль",
+		"Зуль-Каада",
+		"Зуль-Хиджжа"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dayPeriods-format-wide-pm": "после полудня",
+	"dateFormat-full": "EEEE, d MMMM y 'г'. G",
+	"dateFormatItem-yyyyMEd": "E, dd.MM.y G",
+	"dateFormatItem-Md": "dd.MM",
+	"dayPeriods-format-abbr-am": "до полудня",
+	"field-era": "Эра",
+	"months-standAlone-wide": [
+		"Мухаррам",
+		"Сафар",
+		"Раби-уль-авваль",
+		"Раби-уль-ахир",
+		"Джумад-уль-авваль",
+		"Джумад-уль-ахир",
+		"Раджаб",
+		"Шаабан",
+		"Рамадан",
+		"Шавваль",
+		"Зуль-Каада",
+		"Зуль-Хиджжа"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
+		"4-й квартал"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "Год",
+	"field-hour": "Час",
+	"months-format-abbr": [
+		"Мухаррам",
+		"Сафар",
+		"Раби-уль-авваль",
+		"Раби-уль-ахир",
+		"Джумад-уль-авваль",
+		"Джумад-уль-ахир",
+		"Раджаб",
+		"Шаабан",
+		"Рамадан",
+		"Шавваль",
+		"Зуль-Каада",
+		"Зуль-Хиджжа"
+	],
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "Сегодня",
+	"field-day-relative+1": "Завтра",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "Послезавтра",
+	"dateFormatItem-H": "H",
+	"months-standAlone-abbr": [
+		"Мухаррам",
+		"Сафар",
+		"Раби-уль-авваль",
+		"Раби-уль-ахир",
+		"Джумад-уль-авваль",
+		"Джумад-уль-ахир",
+		"Раджаб",
+		"Шаабан",
+		"Рамадан",
+		"Шавваль",
+		"Зуль-Каада",
+		"Зуль-Хиджжа"
+	],
+	"quarters-format-abbr": [
+		"1-й кв.",
+		"2-й кв.",
+		"3-й кв.",
+		"4-й кв."
+	],
+	"quarters-standAlone-wide": [
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
+		"4-й квартал"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E, d MMM y G",
+	"days-standAlone-wide": [
+		"Воскресенье",
+		"Понедельник",
+		"Вторник",
+		"Среда",
+		"Четверг",
+		"Пятница",
+		"Суббота"
+	],
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"1-й кв.",
+		"2-й кв.",
+		"3-й кв.",
+		"4-й кв."
+	],
+	"field-minute": "Минута",
+	"field-dayperiod": "ДП/ПП",
+	"days-standAlone-abbr": [
+		"Вс",
+		"Пн",
+		"Вт",
+		"Ср",
+		"Чт",
+		"Пт",
+		"Сб"
+	],
+	"field-day-relative+-1": "Вчера",
+	"dateTimeFormat-long": "{1}, {0}",
+	"dayPeriods-format-narrow-am": "дп",
+	"field-day-relative+-2": "Позавчера",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, dd.MM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day": "День",
+	"days-format-wide": [
+		"воскресенье",
+		"понедельник",
+		"вторник",
+		"среда",
+		"четверг",
+		"пятница",
+		"суббота"
+	],
+	"field-zone": "Часовой пояс",
+	"dateFormatItem-y": "y G",
+	"field-year-relative+-1": "В прошлом году",
+	"field-month-relative+-1": "В прошлом месяце",
+	"dayPeriods-format-abbr-pm": "после полудня",
+	"days-format-abbr": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"days-format-narrow": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"dateFormatItem-yyyyMd": "dd.MM.y G",
+	"field-month": "Месяц",
+	"days-standAlone-narrow": [
+		"В",
+		"П",
+		"В",
+		"С",
+		"Ч",
+		"П",
+		"С"
+	],
+	"dayPeriods-format-wide-am": "до полудня",
+	"dateFormat-short": "dd.MM.y G",
+	"field-second": "Секунда",
+	"field-month-relative+0": "В этом месяце",
+	"field-month-relative+1": "В следующем месяце",
+	"dateFormatItem-Ed": "E, d",
+	"field-week": "Неделя",
+	"dateFormat-medium": "dd.MM.y G",
+	"field-year-relative+0": "В этом году",
+	"field-week-relative+-1": "На прошлой неделе",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"field-year-relative+1": "В следующем году",
+	"dayPeriods-format-narrow-pm": "пп",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y 'г'. G",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "На этой неделе",
+	"field-week-relative+1": "На следующей неделе"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/japanese.js b/dojo/cldr/nls/ru/japanese.js
new file mode 100644
index 0000000..d00eb2b
--- /dev/null
+++ b/dojo/cldr/nls/ru/japanese.js
@@ -0,0 +1,269 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Секунда",
+	"field-year-relative+-1": "В прошлом году",
+	"field-week": "Неделя",
+	"field-month-relative+-1": "В прошлом месяце",
+	"field-day-relative+-1": "Вчера",
+	"field-day-relative+-2": "Позавчера",
+	"field-year": "Год",
+	"field-week-relative+0": "На этой неделе",
+	"field-week-relative+1": "На следующей неделе",
+	"field-minute": "Минута",
+	"field-week-relative+-1": "На прошлой неделе",
+	"field-day-relative+0": "Сегодня",
+	"field-hour": "Час",
+	"field-day-relative+1": "Завтра",
+	"field-day-relative+2": "Послезавтра",
+	"field-day": "День",
+	"field-month-relative+0": "В этом месяце",
+	"field-month-relative+1": "В следующем месяце",
+	"field-dayperiod": "ДП/ПП",
+	"field-month": "Месяц",
+	"field-era": "Эра",
+	"field-year-relative+0": "В этом году",
+	"field-year-relative+1": "В следующем году",
+	"eraAbbr": [
+		"Эпоха Тайка (645-650)",
+		"Эпоха Хакути (650-671)",
+		"Эпоха Хакухо (672-686)",
+		"Эпоха Сючё (686-701)",
+		"Эпоха Тайхо (701-704)",
+		"Эпоха Кёюн (704-708)",
+		"Эпоха Вадо (708-715)",
+		"Эпоха Рэйки (715-717)",
+		"Эпоха Ёро (717-724)",
+		"Эпоха Дзинки (724-729)",
+		"Эпоха Темпьё (729-749)",
+		"Эпоха Темпьё (749-749)",
+		"Эпоха Темпьё-Сьохо (749-757)",
+		"Эпоха Темпьё-Ходзи (757-765)",
+		"Эпоха Темпьё-Ходзи (765-767)",
+		"Эпоха Джинго-Кёюн (767-770)",
+		"Эпоха Хоки (770-780)",
+		"Эпоха Теньё (781-782)",
+		"Эпоха Енряку (782-806)",
+		"Эпоха Дайдо (806-810)",
+		"Эпоха Конин (810-824)",
+		"Эпоха Тентьо (824-834)",
+		"Эпоха Шова (834-848)",
+		"Эпоха Кайо (848-851)",
+		"Эпоха Ниндзю (851-854)",
+		"Эпоха Сайко (854-857)",
+		"Эпоха Теннан (857-859)",
+		"Эпоха Йоган (859-877)",
+		"Эпоха Генкей (877-885)",
+		"Эпоха Нинна (885-889)",
+		"Эпоха Кампьё (889-898)",
+		"Эпоха Сьотай (898-901)",
+		"Эпоха Энги (901-923)",
+		"Эпоха Ентьо (923-931)",
+		"Эпоха Сьёхэй (931-938)",
+		"Эпоха Тенгьо (938-947)",
+		"Эпоха Тенрияку (947-957)",
+		"Эпоха Тентоку (957-961)",
+		"Эпоха Ова (961-964)",
+		"Эпоха Кохо (964-968)",
+		"Эпоха Анна (968-970)",
+		"Эпоха Тенроку (970-973)",
+		"Эпоха Теньен (973-976)",
+		"Эпоха Дзьоген (976-978)",
+		"Эпоха Тенген (978-983)",
+		"Эпоха Ейкан (983-985)",
+		"Эпоха Канна (985-987)",
+		"Эпоха Ейен (987-989)",
+		"Эпоха Ейсо (989-990)",
+		"Эпоха Сёряку (990-995)",
+		"Эпоха Тётоку (995-999)",
+		"Эпоха Тёхо (999-1004)",
+		"Эпоха Канко (1004-1012)",
+		"Эпоха Тёва (1012-1017)",
+		"Эпоха Каннин (1017-1021)",
+		"Эпоха Дзиан (1021-1024)",
+		"Эпоха Мандзю (1024-1028)",
+		"Эпоха Тёгэн (1028-1037)",
+		"Эпоха Тёряку (1037-1040)",
+		"Эпоха Тёкю (1040-1044)",
+		"Эпоха Катоку (1044-1046)",
+		"Эпоха Эйсо (1046-1053)",
+		"Эпоха Тэнги (1053-1058)",
+		"Эпоха Кохэй (1058-1065)",
+		"Эпоха Дзиряку (1065-1069)",
+		"Эпоха Энкю (1069-1074)",
+		"Эпоха Сёхо (1074-1077)",
+		"Эпоха Сёряку (1077-1081)",
+		"Эпоха Эйхо (1081-1084)",
+		"Эпоха Отоку (1084-1087)",
+		"Эпоха Кандзи (1087-1094)",
+		"Эпоха Кахо (1094-1096)",
+		"Эпоха Эйтё (1096-1097)",
+		"Эпоха Сётоку (1097-1099)",
+		"Эпоха Кова (1099-1104)",
+		"Эпоха Тёдзи (1104-1106)",
+		"Эпоха Касё (1106-1108)",
+		"Эпоха Тэннин (1108-1110)",
+		"Эпоха Тэнъэй (1110-1113)",
+		"Эпоха Эйкю (1113-1118)",
+		"Эпоха Гэнъэй (1118-1120)",
+		"Эпоха Хоан (1120-1124)",
+		"Эпоха Тэндзи (1124-1126)",
+		"Эпоха Дайдзи (1126-1131)",
+		"Эпоха Тэнсё (1131-1132)",
+		"Эпоха Тёсё (1132-1135)",
+		"Эпоха Хоэн (1135-1141)",
+		"Эпоха Эйдзи (1141-1142)",
+		"Эпоха Кодзи (1142-1144)",
+		"Эпоха Тэнё (1144-1145)",
+		"Эпоха Кюан (1145-1151)",
+		"Эпоха Нимпэй (1151-1154)",
+		"Эпоха Кюдзю (1154-1156)",
+		"Эпоха Хогэн (1156-1159)",
+		"Эпоха Хэйдзи (1159-1160)",
+		"Эпоха Эйряку (1160-1161)",
+		"Эпоха Охо (1161-1163)",
+		"Эпоха Тёкан (1163-1165)",
+		"Эпоха Эйман (1165-1166)",
+		"Эпоха Нинъан (1166-1169)",
+		"Эпоха Као (1169-1171)",
+		"Эпоха Сёан (1171-1175)",
+		"Эпоха Ангэн (1175-1177)",
+		"Эпоха Дзисё (1177-1181)",
+		"Эпоха Ёва (1181-1182)",
+		"Эпоха Дзюэй (1182-1184)",
+		"Эпоха Гэнрюку (1184-1185)",
+		"Эпоха Бундзи (1185-1190)",
+		"Эпоха Кэнкю (1190-1199)",
+		"Эпоха Сёдзи (1199-1201)",
+		"Эпоха Кэннин (1201-1204)",
+		"Эпоха Гэнкю (1204-1206)",
+		"Эпоха Кэнъэй (1206-1207)",
+		"Эпоха Сёгэн (1207-1211)",
+		"Эпоха Кэнряку (1211-1213)",
+		"Эпоха Кэмпо (1213-1219)",
+		"Эпоха Сёкю (1219-1222)",
+		"Эпоха Дзёо (1222-1224)",
+		"Эпоха Гэннин (1224-1225)",
+		"Эпоха Кароку (1225-1227)",
+		"Эпоха Антэй (1227-1229)",
+		"Эпоха Канки (1229-1232)",
+		"Эпоха Дзёэй (1232-1233)",
+		"Эпоха Тэмпуку (1233-1234)",
+		"Эпоха Бунряку (1234-1235)",
+		"Эпоха Катэй (1235-1238)",
+		"Эпоха Рякунин (1238-1239)",
+		"Эпоха Энъо (1239-1240)",
+		"Эпоха Ниндзи (1240-1243)",
+		"Эпоха Кангэн (1243-1247)",
+		"Эпоха Ходзи (1247-1249)",
+		"Эпоха Кэнтё (1249-1256)",
+		"Эпоха Когэн (1256-1257)",
+		"Эпоха Сёка (1257-1259)",
+		"Эпоха Сёгэн (1259-1260)",
+		"Эпоха Бунъо (1260-1261)",
+		"Эпоха Котё (1261-1264)",
+		"Эпоха Бунъэй (1264-1275)",
+		"Эпоха Кэндзи (1275-1278)",
+		"Эпоха Коан (1278-1288)",
+		"Эпоха Сёо (1288-1293)",
+		"Эпоха Эйнин (1293-1299)",
+		"Эпоха Сёан (1299-1302)",
+		"Эпоха Кэнгэн (1302-1303)",
+		"Эпоха Кагэн (1303-1306)",
+		"Эпоха Токудзи (1306-1308)",
+		"Эпоха Энкэй (1308-1311)",
+		"Эпоха Отё (1311-1312)",
+		"Эпоха Сёва (1312-1317)",
+		"Эпоха Бумпо (1317-1319)",
+		"Эпоха Гэно (1319-1321)",
+		"Эпоха Гэнкё (1321-1324)",
+		"Эпоха Сётю (1324-1326)",
+		"Эпоха Карэки (1326-1329)",
+		"Эпоха Гэнтоку (1329-1331)",
+		"Эпоха Гэнко (1331-1334)",
+		"Эпоха Кэмму (1334-1336)",
+		"Эпоха Энгэн (1336-1340)",
+		"Эпоха Кококу (1340-1346)",
+		"Эпоха Сёхэй (1346-1370)",
+		"Эпоха Кэнтоку (1370-1372)",
+		"Эпоха Бунтю (1372-1375)",
+		"Эпоха Иэндзю (1375-1379)",
+		"Эпоха Коряку (1379-1381)",
+		"Эпоха Кова (1381-1384)",
+		"Эпоха Гэнтю (1384-1392)",
+		"Эпоха Мэйтоку (1384-1387)",
+		"Эпоха Какэй (1387-1389)",
+		"Эпоха Коо (1389-1390)",
+		"Эпоха Мэйтоку (1390-1394)",
+		"Эпоха Оэй (1394-1428)",
+		"Эпоха Сётё (1428-1429)",
+		"Эпоха Эйкё (1429-1441)",
+		"Эпоха Какицу (1441-1444)",
+		"Эпоха Банъан (1444-1449)",
+		"Эпоха Хотоку (1449-1452)",
+		"Эпоха Кётоку (1452-1455)",
+		"Эпоха Косё (1455-1457)",
+		"Эпоха Тёроку (1457-1460)",
+		"Эпоха Кансё (1460-1466)",
+		"Эпоха Бунсё (1466-1467)",
+		"Эпоха Онин (1467-1469)",
+		"Эпоха Буммэй (1469-1487)",
+		"Эпоха Тёкё (1487-1489)",
+		"Эпоха Энтоку (1489-1492)",
+		"Эпоха Мэйо (1492-1501)",
+		"Эпоха Бунки (1501-1504)",
+		"Эпоха Эйсё (1504-1521)",
+		"Эпоха Тайэй (1521-1528)",
+		"Эпоха Кёроку (1528-1532)",
+		"Эпоха Тэммон (1532-1555)",
+		"Эпоха Кодзи (1555-1558)",
+		"Эпоха Эйроку (1558-1570)",
+		"Эпоха Гэнки (1570-1573)",
+		"Эпоха Тэнсё (1573-1592)",
+		"Эпоха Бунроку (1592-1596)",
+		"Эпоха Кэйтё (1596-1615)",
+		"Эпоха Гэнва (1615-1624)",
+		"Эпоха Канъэй (1624-1644)",
+		"Эпоха Сёхо (1644-1648)",
+		"Эпоха Кэйан (1648-1652)",
+		"Эпоха Сё (1652-1655)",
+		"Эпоха Мэйряку (1655-1658)",
+		"Эпоха Мандзи (1658-1661)",
+		"Эпоха Камбун (1661-1673)",
+		"Эпоха Эмпо (1673-1681)",
+		"Эпоха Тэнва (1681-1684)",
+		"Эпоха Дзёкё (1684-1688)",
+		"Эпоха Гэнроку (1688-1704)",
+		"Эпоха Хоэй (1704-1711)",
+		"Эпоха Сётоку (1711-1716)",
+		"Эпоха Кёхо (1716-1736)",
+		"Эпоха Гэмбун (1736-1741)",
+		"Эпоха Кампо (1741-1744)",
+		"Эпоха Энкё (1744-1748)",
+		"Эпоха Канъэн (1748-1751)",
+		"Эпоха Хоряку (1751-1764)",
+		"Эпоха Мэйва (1764-1772)",
+		"Эпоха Анъэй (1772-1781)",
+		"Эпоха Тэммэй (1781-1789)",
+		"Эпоха Кансэй (1789-1801)",
+		"Эпоха Кёва (1801-1804)",
+		"Эпоха Бунка (1804-1818)",
+		"Эпоха Бунсэй (1818-1830)",
+		"Эпоха Тэмпо (1830-1844)",
+		"Эпоха Кока (1844-1848)",
+		"Эпоха Каэй (1848-1854)",
+		"Эпоха Ансэй (1854-1860)",
+		"Эпоха Манъэн (1860-1861)",
+		"Эпоха Бункю (1861-1864)",
+		"Эпоха Гендзи (1864-1865)",
+		"Эпоха Кейо (1865-1868)",
+		"Эпоха Мэйдзи",
+		"Эпоха Тайсьо",
+		"Сьова",
+		"Эпоха Хэйсэй"
+	],
+	"field-weekday": "День недели",
+	"field-zone": "Часовой пояс"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/number.js b/dojo/cldr/nls/ru/number.js
index 18182dd..bde6564 100644
--- a/dojo/cldr/nls/ru/number.js
+++ b/dojo/cldr/nls/ru/number.js
@@ -8,14 +8,15 @@ define(
 	"percentFormat": "#,##0 %",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
-	"nativeZeroDigit": "0",
+	"nan": "не число",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 триллиона",
+	"decimalFormat-short": "000 трлн"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/persian.js b/dojo/cldr/nls/ru/persian.js
new file mode 100644
index 0000000..5a05096
--- /dev/null
+++ b/dojo/cldr/nls/ru/persian.js
@@ -0,0 +1,251 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "День недели",
+	"dateFormatItem-GyMMMEd": "E, d MMM y G",
+	"dateFormatItem-MMMEd": "ccc, d MMM",
+	"days-format-short": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"dateFormat-long": "d MMMM y 'г'. G",
+	"months-format-wide": [
+		"Фарвардин",
+		"Ордибехешт",
+		"Хордад",
+		"Тир",
+		"Мордад",
+		"Шахривер",
+		"Мехр",
+		"Абан",
+		"Азер",
+		"Дей",
+		"Бахман",
+		"Эсфанд"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dayPeriods-format-wide-pm": "после полудня",
+	"dateFormat-full": "EEEE, d MMMM y 'г'. G",
+	"dateFormatItem-yyyyMEd": "E, dd.MM.y G",
+	"dateFormatItem-Md": "dd.MM",
+	"dayPeriods-format-abbr-am": "до полудня",
+	"field-era": "Эра",
+	"months-standAlone-wide": [
+		"Фарвардин",
+		"Ордибехешт",
+		"Хордад",
+		"Тир",
+		"Мордад",
+		"Шахривер",
+		"Мехр",
+		"Абан",
+		"Азер",
+		"Дей",
+		"Бахман",
+		"Эсфанд"
+	],
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
+		"4-й квартал"
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "Год",
+	"field-hour": "Час",
+	"months-format-abbr": [
+		"Фарвардин",
+		"Ордибехешт",
+		"Хордад",
+		"Тир",
+		"Мордад",
+		"Шахривер",
+		"Мехр",
+		"Абан",
+		"Азер",
+		"Дей",
+		"Бахман",
+		"Эсфанд"
+	],
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "Сегодня",
+	"field-day-relative+1": "Завтра",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "Послезавтра",
+	"dateFormatItem-H": "H",
+	"months-standAlone-abbr": [
+		"Фарвардин",
+		"Ордибехешт",
+		"Хордад",
+		"Тир",
+		"Мордад",
+		"Шахривер",
+		"Мехр",
+		"Абан",
+		"Азер",
+		"Дей",
+		"Бахман",
+		"Эсфанд"
+	],
+	"quarters-format-abbr": [
+		"1-й кв.",
+		"2-й кв.",
+		"3-й кв.",
+		"4-й кв."
+	],
+	"quarters-standAlone-wide": [
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
+		"4-й квартал"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E, d MMM y G",
+	"days-standAlone-wide": [
+		"Воскресенье",
+		"Понедельник",
+		"Вторник",
+		"Среда",
+		"Четверг",
+		"Пятница",
+		"Суббота"
+	],
+	"dateFormatItem-yyyyMMM": "LLL y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"1-й кв.",
+		"2-й кв.",
+		"3-й кв.",
+		"4-й кв."
+	],
+	"field-minute": "Минута",
+	"field-dayperiod": "ДП/ПП",
+	"days-standAlone-abbr": [
+		"Вс",
+		"Пн",
+		"Вт",
+		"Ср",
+		"Чт",
+		"Пт",
+		"Сб"
+	],
+	"field-day-relative+-1": "Вчера",
+	"dateTimeFormat-long": "{1}, {0}",
+	"dayPeriods-format-narrow-am": "дп",
+	"field-day-relative+-2": "Позавчера",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, dd.MM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day": "День",
+	"days-format-wide": [
+		"воскресенье",
+		"понедельник",
+		"вторник",
+		"среда",
+		"четверг",
+		"пятница",
+		"суббота"
+	],
+	"field-zone": "Часовой пояс",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"Я",
+		"Ф",
+		"М",
+		"А",
+		"М",
+		"И",
+		"И",
+		"А",
+		"С",
+		"О",
+		"Н",
+		"Д"
+	],
+	"field-year-relative+-1": "В прошлом году",
+	"field-month-relative+-1": "В прошлом месяце",
+	"dayPeriods-format-abbr-pm": "после полудня",
+	"days-format-abbr": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"days-format-narrow": [
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"dateFormatItem-yyyyMd": "dd.MM.y G",
+	"field-month": "Месяц",
+	"days-standAlone-narrow": [
+		"В",
+		"П",
+		"В",
+		"С",
+		"Ч",
+		"П",
+		"С"
+	],
+	"dayPeriods-format-wide-am": "до полудня",
+	"dateFormat-short": "dd.MM.y G",
+	"field-second": "Секунда",
+	"field-month-relative+0": "В этом месяце",
+	"field-month-relative+1": "В следующем месяце",
+	"dateFormatItem-Ed": "E, d",
+	"field-week": "Неделя",
+	"dateFormat-medium": "dd.MM.y G",
+	"field-year-relative+0": "В этом году",
+	"field-week-relative+-1": "На прошлой неделе",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"field-year-relative+1": "В следующем году",
+	"dayPeriods-format-narrow-pm": "пп",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y 'г'. G",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-GyMMM": "LLL y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "На этой неделе",
+	"field-week-relative+1": "На следующей неделе"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/roc.js b/dojo/cldr/nls/ru/roc.js
new file mode 100644
index 0000000..de7d7d6
--- /dev/null
+++ b/dojo/cldr/nls/ru/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Секунда",
+	"field-year-relative+-1": "В прошлом году",
+	"field-week": "Неделя",
+	"field-month-relative+-1": "В прошлом месяце",
+	"field-day-relative+-1": "Вчера",
+	"field-day-relative+-2": "Позавчера",
+	"field-year": "Год",
+	"field-week-relative+0": "На этой неделе",
+	"field-week-relative+1": "На следующей неделе",
+	"field-minute": "Минута",
+	"field-week-relative+-1": "На прошлой неделе",
+	"field-day-relative+0": "Сегодня",
+	"field-hour": "Час",
+	"field-day-relative+1": "Завтра",
+	"field-day-relative+2": "Послезавтра",
+	"field-day": "День",
+	"field-month-relative+0": "В этом месяце",
+	"field-month-relative+1": "В следующем месяце",
+	"field-dayperiod": "ДП/ПП",
+	"field-month": "Месяц",
+	"field-era": "Эра",
+	"field-year-relative+0": "В этом году",
+	"field-year-relative+1": "В следующем году",
+	"eraAbbr": [
+		"Before R.O.C.",
+		"Minguo"
+	],
+	"field-weekday": "День недели",
+	"field-zone": "Часовой пояс"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sk/currency.js b/dojo/cldr/nls/sk/currency.js
index 9e01d3c..d8d40fa 100644
--- a/dojo/cldr/nls/sk/currency.js
+++ b/dojo/cldr/nls/sk/currency.js
@@ -1,14 +1,21 @@
 define(
 //begin v1.x content
 {
-	"HKD_displayName": "Hong Kongský dolár",
+	"HKD_displayName": "Hongkongský dolár",
 	"CHF_displayName": "Švajčiarský frank",
+	"JPY_symbol": "JPY",
 	"CAD_displayName": "Kanadský dolár",
-	"CNY_displayName": "Čínsky Yuan Renminbi",
+	"HKD_symbol": "HKD",
+	"CNY_displayName": "Čínsky jüan",
+	"USD_symbol": "USD",
 	"AUD_displayName": "Austrálsky dolár",
-	"JPY_displayName": "Japonský yen",
-	"USD_displayName": "US dolár",
+	"JPY_displayName": "Japonský jen",
+	"CAD_symbol": "CAD",
+	"USD_displayName": "Americký dolár",
+	"CNY_symbol": "CNY",
 	"GBP_displayName": "Britská libra",
+	"GBP_symbol": "GBP",
+	"AUD_symbol": "AUD",
 	"EUR_displayName": "Euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/sk/generic.js b/dojo/cldr/nls/sk/generic.js
new file mode 100644
index 0000000..d617152
--- /dev/null
+++ b/dojo/cldr/nls/sk/generic.js
@@ -0,0 +1,67 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M.y",
+	"field-dayperiod": "Časť dňa",
+	"field-minute": "Minúta",
+	"dateFormatItem-MMMEd": "E, d. MMM.",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "Včera",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"field-day-relative+-2": "Predvčerom",
+	"field-weekday": "Deň v týždni",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "Éra",
+	"field-hour": "Hodina",
+	"dateFormatItem-y": "y",
+	"dateFormatItem-Ed": "E d.",
+	"dateFormatItem-yMMM": "LLL y",
+	"field-day-relative+0": "Dnes",
+	"field-day-relative+1": "Zajtra",
+	"field-day-relative+2": "Pozajtra",
+	"dateFormat-long": "d. MMMM y G",
+	"field-zone": "Časové pásmo",
+	"dateFormatItem-Hm": "H:mm",
+	"field-week-relative+-1": "Minulý týždeň",
+	"dateFormat-medium": "d.M.y G",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"field-year-relative+0": "Tento rok",
+	"field-year-relative+1": "Budúci rok",
+	"dateFormatItem-yMd": "d.M.y",
+	"field-year-relative+-1": "Minulý rok",
+	"dateFormatItem-yMMMM": "LLLL y",
+	"dateFormatItem-ms": "mm:ss",
+	"field-year": "Rok",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "Týždeň",
+	"dateFormatItem-MMMMEd": "E, d. MMMM",
+	"dateFormatItem-MMMd": "d. MMM.",
+	"field-week-relative+0": "Tento týždeň",
+	"field-week-relative+1": "Budúci týždeň",
+	"dateFormatItem-yQQQQ": "QQQQ y",
+	"field-month-relative+0": "Tento mesiac",
+	"dateFormatItem-H": "H",
+	"field-month": "Mesiac",
+	"field-month-relative+1": "Budúci mesiac",
+	"dateFormatItem-MMMMd": "d. MMMM",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateFormatItem-M": "L.",
+	"dateFormatItem-yMMMd": "d.M.y",
+	"field-second": "Sekunda",
+	"field-day": "Deň",
+	"dateFormatItem-MEd": "E, d.M.",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "d.M.y GGGGG",
+	"dateFormatItem-yMMMEd": "E, d. MMM y",
+	"dateFormat-full": "EEEE, d. MMMM y G",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yMEd": "E d. M. y",
+	"dateFormatItem-d": "d.",
+	"field-month-relative+-1": "Posledný mesiac",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sk/gregorian.js b/dojo/cldr/nls/sk/gregorian.js
index 8d6b3e7..f9ef7eb 100644
--- a/dojo/cldr/nls/sk/gregorian.js
+++ b/dojo/cldr/nls/sk/gregorian.js
@@ -1,30 +1,16 @@
 define(
 //begin v1.x content
 {
-	"field-dayperiod": "Časť dňa",
-	"dateFormatItem-yQ": "Q yyyy",
-	"dayPeriods-format-wide-pm": "popoludní",
-	"field-minute": "Minúta",
-	"eraNames": [
-		"pred n.l.",
-		"n.l."
+	"days-standAlone-short": [
+		"Ne",
+		"Po",
+		"Ut",
+		"St",
+		"Št",
+		"Pi",
+		"So"
 	],
-	"dateFormatItem-MMMEd": "E, d. MMM",
-	"field-day-relative+-1": "Včera",
-	"field-weekday": "Deň v týždni",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"field-day-relative+-2": "Predvčerom",
-	"field-day-relative+-3": "Pred tromi dňami",
-	"days-standAlone-wide": [
-		"nedeľa",
-		"pondelok",
-		"utorok",
-		"streda",
-		"štvrtok",
-		"piatok",
-		"sobota"
-	],
-	"months-standAlone-narrow": [
+	"months-format-narrow": [
 		"j",
 		"f",
 		"m",
@@ -38,60 +24,51 @@ define(
 		"n",
 		"d"
 	],
-	"field-era": "Éra",
-	"field-hour": "Hodina",
-	"dayPeriods-format-wide-am": "dopoludnia",
-	"timeFormat-full": "H:mm:ss zzzz",
-	"months-standAlone-abbr": [
-		"jan",
-		"feb",
-		"mar",
-		"apr",
-		"máj",
-		"jún",
-		"júl",
-		"aug",
-		"sep",
-		"okt",
-		"nov",
-		"dec"
-	],
-	"dateFormatItem-yMMM": "LLL y",
-	"field-day-relative+0": "Dnes",
-	"field-day-relative+1": "Zajtra",
-	"days-standAlone-narrow": [
-		"N",
-		"P",
-		"U",
-		"S",
-		"Š",
-		"P",
-		"S"
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
 	],
-	"eraAbbr": [
+	"field-weekday": "Deň v týždni",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "E d. M. y",
+	"dateFormatItem-MMMEd": "E, d. MMM.",
+	"eraNarrow": [
 		"pred n.l.",
 		"n.l."
 	],
-	"field-day-relative+2": "Pozajtra",
-	"field-day-relative+3": "O tri dni",
-	"dateFormatItem-yyyyMMMM": "LLLL y",
+	"days-format-short": [
+		"Ne",
+		"Po",
+		"Ut",
+		"St",
+		"Št",
+		"Pi",
+		"So"
+	],
 	"dateFormat-long": "d. MMMM y",
-	"timeFormat-medium": "H:mm:ss",
-	"dateFormatItem-EEEd": "EEE, d.",
-	"field-zone": "Pásmo",
-	"dateFormatItem-Hm": "H:mm",
-	"dateFormat-medium": "d.M.yyyy",
-	"dateFormatItem-Hms": "H:mm:ss",
-	"dateFormatItem-yyQQQQ": "QQQQ yy",
-	"quarters-standAlone-wide": [
-		"1. štvrťrok",
-		"2. štvrťrok",
-		"3. štvrťrok",
-		"4. štvrťrok"
+	"months-format-wide": [
+		"januára",
+		"februára",
+		"marca",
+		"apríla",
+		"mája",
+		"júna",
+		"júla",
+		"augusta",
+		"septembra",
+		"októbra",
+		"novembra",
+		"decembra"
 	],
-	"dateFormatItem-yMMMM": "LLLL y",
-	"dateFormatItem-ms": "mm:ss",
-	"field-year": "Rok",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "popoludní",
+	"dateFormat-full": "EEEE, d. MMMM y",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yMd": "d.M.y",
+	"field-era": "Éra",
+	"dateFormatItem-yM": "M.y",
 	"months-standAlone-wide": [
 		"január",
 		"február",
@@ -106,11 +83,18 @@ define(
 		"november",
 		"december"
 	],
-	"field-week": "Týždeň",
-	"dateFormatItem-MMMMEd": "E, d. MMMM",
-	"dateFormatItem-MMMd": "d. MMM",
-	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-short": "H:mm",
+	"quarters-format-wide": [
+		"1. štvrťrok",
+		"2. štvrťrok",
+		"3. štvrťrok",
+		"4. štvrťrok"
+	],
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-long": "H:mm:ss z",
+	"field-year": "Rok",
+	"dateFormatItem-yMMM": "LLL y",
+	"field-hour": "Hodina",
 	"months-format-abbr": [
 		"jan",
 		"feb",
@@ -125,17 +109,63 @@ define(
 		"nov",
 		"dec"
 	],
-	"timeFormat-short": "H:mm",
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "Dnes",
+	"field-day-relative+1": "Zajtra",
+	"field-day-relative+2": "Pozajtra",
 	"dateFormatItem-H": "H",
-	"field-month": "Mesiac",
-	"dateFormatItem-MMMMd": "d. MMMM",
+	"months-standAlone-abbr": [
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"máj",
+		"jún",
+		"júl",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
+		"dec"
+	],
 	"quarters-format-abbr": [
 		"Q1",
 		"Q2",
 		"Q3",
 		"Q4"
 	],
-	"days-format-abbr": [
+	"quarters-standAlone-wide": [
+		"1. štvrťrok",
+		"2. štvrťrok",
+		"3. štvrťrok",
+		"4. štvrťrok"
+	],
+	"dateFormatItem-M": "L.",
+	"days-standAlone-wide": [
+		"nedeľa",
+		"pondelok",
+		"utorok",
+		"streda",
+		"štvrtok",
+		"piatok",
+		"sobota"
+	],
+	"dateFormatItem-MMMMd": "d. MMMM",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"1Q",
+		"2Q",
+		"3Q",
+		"4Q"
+	],
+	"eraAbbr": [
+		"pred n.l.",
+		"n.l."
+	],
+	"field-minute": "Minúta",
+	"field-dayperiod": "Časť dňa",
+	"days-standAlone-abbr": [
 		"ne",
 		"po",
 		"ut",
@@ -144,20 +174,35 @@ define(
 		"pi",
 		"so"
 	],
-	"dateFormatItem-mmss": "mm:ss",
-	"days-format-narrow": [
-		"N",
-		"P",
-		"U",
-		"S",
-		"Š",
-		"P",
-		"S"
+	"dateFormatItem-d": "d.",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
 	],
-	"field-second": "Sekunda",
-	"field-day": "Deň",
+	"field-day-relative+-1": "Včera",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-day-relative+-2": "Predvčerom",
+	"dateFormatItem-MMMd": "d. MMM.",
 	"dateFormatItem-MEd": "E, d.M.",
-	"months-format-narrow": [
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-yMMMM": "LLLL y",
+	"field-day": "Deň",
+	"days-format-wide": [
+		"nedeľa",
+		"pondelok",
+		"utorok",
+		"streda",
+		"štvrtok",
+		"piatok",
+		"sobota"
+	],
+	"field-zone": "Časové pásmo",
+	"dateFormatItem-y": "y",
+	"months-standAlone-narrow": [
 		"j",
 		"f",
 		"m",
@@ -171,7 +216,10 @@ define(
 		"n",
 		"d"
 	],
-	"days-standAlone-abbr": [
+	"field-year-relative+-1": "Minulý rok",
+	"field-month-relative+-1": "Posledný mesiac",
+	"dateFormatItem-hm": "h:mm a",
+	"days-format-abbr": [
 		"ne",
 		"po",
 		"ut",
@@ -180,46 +228,50 @@ define(
 		"pi",
 		"so"
 	],
-	"dateFormat-short": "d.M.yyyy",
-	"dateFormatItem-yyyyM": "M.yyyy",
-	"dateFormatItem-yMMMEd": "EEE, d. MMM y",
-	"dateFormat-full": "EEEE, d. MMMM y",
-	"dateFormatItem-Md": "d.M.",
-	"dateFormatItem-yMEd": "EEE, d.M.yyyy",
-	"months-format-wide": [
-		"januára",
-		"februára",
-		"marca",
-		"apríla",
-		"mája",
-		"júna",
-		"júla",
-		"augusta",
-		"septembra",
-		"októbra",
-		"novembra",
-		"decembra"
+	"dateFormatItem-yMMMd": "d.M.y",
+	"eraNames": [
+		"pred n.l.",
+		"n.l."
 	],
-	"dateFormatItem-d": "d.",
-	"quarters-format-wide": [
-		"1. štvrťrok",
-		"2. štvrťrok",
-		"3. štvrťrok",
-		"4. štvrťrok"
+	"days-format-narrow": [
+		"N",
+		"P",
+		"U",
+		"S",
+		"Š",
+		"P",
+		"S"
 	],
-	"days-format-wide": [
-		"nedeľa",
-		"pondelok",
-		"utorok",
-		"streda",
-		"štvrtok",
-		"piatok",
-		"sobota"
+	"field-month": "Mesiac",
+	"days-standAlone-narrow": [
+		"N",
+		"P",
+		"U",
+		"S",
+		"Š",
+		"P",
+		"S"
 	],
-	"eraNarrow": [
-		"pred n.l.",
-		"n.l."
-	]
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "dopoludnia",
+	"dateFormatItem-MMMMEd": "E, d. MMMM",
+	"dateFormat-short": "d.M.y",
+	"field-second": "Sekunda",
+	"dateFormatItem-yMMMEd": "E, d. MMM y",
+	"field-month-relative+0": "Tento mesiac",
+	"field-month-relative+1": "Budúci mesiac",
+	"dateFormatItem-Ed": "E d.",
+	"field-week": "Týždeň",
+	"dateFormat-medium": "d.M.y",
+	"field-year-relative+0": "Tento rok",
+	"field-week-relative+-1": "Minulý týždeň",
+	"field-year-relative+1": "Budúci rok",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-week-relative+0": "Tento týždeň",
+	"field-week-relative+1": "Budúci týždeň"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/sk/number.js b/dojo/cldr/nls/sk/number.js
index 2d80075..4c3dc2b 100644
--- a/dojo/cldr/nls/sk/number.js
+++ b/dojo/cldr/nls/sk/number.js
@@ -1,9 +1,22 @@
 define(
 //begin v1.x content
 {
-	"currencyFormat": "#,##0.00 ¤",
 	"group": " ",
-	"decimal": ","
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0 %",
+	"list": ";",
+	"infinity": "∞",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+",
+	"decimalFormat-long": "000 biliónov",
+	"decimalFormat-short": "000 bil'.'"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/sl/generic.js b/dojo/cldr/nls/sl/generic.js
new file mode 100644
index 0000000..4d1bd04
--- /dev/null
+++ b/dojo/cldr/nls/sl/generic.js
@@ -0,0 +1,65 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M/y",
+	"field-dayperiod": "Čas dneva",
+	"field-minute": "Minuta",
+	"dateFormatItem-MMMEd": "E, d. MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "Včeraj",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"field-day-relative+-2": "Predvčerajšnjim",
+	"field-weekday": "Dan v tednu",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"field-era": "Doba",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-hour": "Ura",
+	"dateFormatItem-y": "y",
+	"dateFormatItem-Ed": "E, d.",
+	"dateFormatItem-yMMM": "MMM y",
+	"field-day-relative+0": "Danes",
+	"field-day-relative+1": "Jutri",
+	"field-day-relative+2": "Pojutrišnjem",
+	"dateFormat-long": "dd. MMMM y G",
+	"field-zone": "Območje",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Prejšnji teden",
+	"dateFormat-medium": "d. MMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Letos",
+	"field-year-relative+1": "Naslednje leto",
+	"dateFormatItem-yMd": "d. M. y",
+	"field-year-relative+-1": "Lani",
+	"dateFormatItem-yMMMM": "MMMM y",
+	"dateFormatItem-ms": "mm:ss",
+	"field-year": "Leto",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "Teden",
+	"dateFormatItem-MMMd": "d. MMM",
+	"field-week-relative+0": "Ta teden",
+	"field-week-relative+1": "Naslednji teden",
+	"dateFormatItem-yQQQQ": "QQQQ y",
+	"field-month-relative+0": "Ta mesec",
+	"dateFormatItem-H": "HH",
+	"field-month": "Mesec",
+	"field-month-relative+1": "Naslednji mesec",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateFormatItem-M": "L",
+	"dateFormatItem-yMMMd": "d. MMM y",
+	"field-second": "Sekunda",
+	"field-day": "Dan",
+	"dateFormatItem-MEd": "E, d. MM.",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "d. MM. yy GGGGG",
+	"dateFormatItem-yMMMEd": "E, d. MMM y",
+	"dateFormat-full": "EEEE, dd. MMMM y G",
+	"dateFormatItem-Md": "d. M.",
+	"dateFormatItem-yMEd": "E, d. M. y",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Prejšnji mesec",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sl/gregorian.js b/dojo/cldr/nls/sl/gregorian.js
index 8344c00..a901a96 100644
--- a/dojo/cldr/nls/sl/gregorian.js
+++ b/dojo/cldr/nls/sl/gregorian.js
@@ -1,28 +1,16 @@
 define(
 //begin v1.x content
 {
-	"field-dayperiod": "Čas dneva",
-	"dayPeriods-format-wide-pm": "pop.",
-	"field-minute": "Minuta",
-	"eraNames": [
-		"pred našim štetjem",
-		"naše štetje"
-	],
-	"dateFormatItem-MMMEd": "E., d. MMM",
-	"field-day-relative+-1": "Včeraj",
-	"field-weekday": "Dan v tednu",
-	"field-day-relative+-2": "Predvčerajšnjim",
-	"field-day-relative+-3": "Pred tremi dnevi",
-	"days-standAlone-wide": [
-		"nedelja",
-		"ponedeljek",
-		"torek",
-		"sreda",
-		"četrtek",
-		"petek",
-		"sobota"
+	"days-standAlone-short": [
+		"ned.",
+		"pon.",
+		"tor.",
+		"sre.",
+		"čet.",
+		"pet.",
+		"sob."
 	],
-	"months-standAlone-narrow": [
+	"months-format-narrow": [
 		"j",
 		"f",
 		"m",
@@ -36,60 +24,51 @@ define(
 		"n",
 		"d"
 	],
-	"field-era": "Doba",
-	"field-hour": "Ura",
-	"dayPeriods-format-wide-am": "dop.",
-	"dateFormatItem-y": "y",
-	"timeFormat-full": "HH:mm:ss zzzz",
-	"months-standAlone-abbr": [
-		"jan",
-		"feb",
-		"mar",
-		"apr",
-		"maj",
-		"jun",
-		"jul",
-		"avg",
-		"sep",
-		"okt",
-		"nov",
-		"dec"
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
 	],
-	"dateFormatItem-Ed": "E., d.",
-	"dateFormatItem-yMMM": "MMM y",
-	"field-day-relative+0": "Danes",
-	"field-day-relative+1": "Jutri",
-	"days-standAlone-narrow": [
-		"n",
-		"p",
-		"t",
-		"s",
-		"č",
-		"p",
-		"s"
-	],
-	"eraAbbr": [
+	"field-weekday": "Dan v tednu",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "E, d. M. y",
+	"dateFormatItem-MMMEd": "E, d. MMM",
+	"eraNarrow": [
 		"pr. n. št.",
 		"po Kr."
 	],
-	"field-day-relative+2": "Pojutrišnjem",
-	"field-day-relative+3": "Čez tri dni",
-	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"days-format-short": [
+		"ned.",
+		"pon.",
+		"tor.",
+		"sre.",
+		"čet.",
+		"pet.",
+		"sob."
+	],
 	"dateFormat-long": "dd. MMMM y",
-	"timeFormat-medium": "HH:mm:ss",
-	"field-zone": "Območje",
-	"dateFormatItem-Hm": "HH:mm",
-	"dateFormat-medium": "d. MMM yyyy",
-	"dateFormatItem-Hms": "HH:mm:ss",
-	"quarters-standAlone-wide": [
-		"1. četrtletje",
-		"2. četrtletje",
-		"3. četrtletje",
-		"4. četrtletje"
+	"months-format-wide": [
+		"januar",
+		"februar",
+		"marec",
+		"april",
+		"maj",
+		"junij",
+		"julij",
+		"avgust",
+		"september",
+		"oktober",
+		"november",
+		"december"
 	],
-	"dateFormatItem-ms": "mm:ss",
-	"field-year": "Leto",
-	"field-week": "Teden",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "pop.",
+	"dateFormat-full": "EEEE, dd. MMMM y",
+	"dateFormatItem-Md": "d. M.",
+	"dateFormatItem-yMd": "d. M. y",
+	"field-era": "Doba",
+	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
 		"januar",
 		"februar",
@@ -104,9 +83,18 @@ define(
 		"november",
 		"december"
 	],
-	"dateFormatItem-MMMd": "d. MMM",
-	"dateFormatItem-yyQ": "Q/yy",
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"1. četrtletje",
+		"2. četrtletje",
+		"3. četrtletje",
+		"4. četrtletje"
+	],
+	"dateFormatItem-yQQQQ": "QQQQ y",
 	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Leto",
+	"dateFormatItem-yMMM": "MMM y",
+	"field-hour": "Ura",
 	"months-format-abbr": [
 		"jan.",
 		"feb.",
@@ -121,15 +109,56 @@ define(
 		"nov.",
 		"dec."
 	],
-	"timeFormat-short": "HH:mm",
-	"field-month": "Mesec",
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"field-day-relative+0": "Danes",
+	"field-day-relative+1": "Jutri",
+	"field-day-relative+2": "Pojutrišnjem",
+	"dateFormatItem-H": "HH",
+	"months-standAlone-abbr": [
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"maj",
+		"jun",
+		"jul",
+		"avg",
+		"sep",
+		"okt",
+		"nov",
+		"dec"
+	],
 	"quarters-format-abbr": [
 		"Q1",
 		"Q2",
 		"Q3",
 		"Q4"
 	],
-	"days-format-abbr": [
+	"quarters-standAlone-wide": [
+		"1. četrtletje",
+		"2. četrtletje",
+		"3. četrtletje",
+		"4. četrtletje"
+	],
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"nedelja",
+		"ponedeljek",
+		"torek",
+		"sreda",
+		"četrtek",
+		"petek",
+		"sobota"
+	],
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
+	"eraAbbr": [
+		"pr. n. št.",
+		"po Kr."
+	],
+	"field-minute": "Minuta",
+	"field-dayperiod": "Čas dneva",
+	"days-standAlone-abbr": [
 		"ned",
 		"pon",
 		"tor",
@@ -138,20 +167,35 @@ define(
 		"pet",
 		"sob"
 	],
-	"dateFormatItem-mmss": "mm:ss",
-	"days-format-narrow": [
-		"n",
-		"p",
-		"t",
-		"s",
-		"č",
-		"p",
-		"s"
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
 	],
-	"field-second": "Sekunda",
+	"field-day-relative+-1": "Včeraj",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-day-relative+-2": "Predvčerajšnjim",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-MEd": "E, d. MM.",
+	"dateTimeFormat-full": "{1} {0}",
+	"dateFormatItem-yMMMM": "MMMM y",
 	"field-day": "Dan",
-	"dateFormatItem-MEd": "E., d. MM.",
-	"months-format-narrow": [
+	"days-format-wide": [
+		"nedelja",
+		"ponedeljek",
+		"torek",
+		"sreda",
+		"četrtek",
+		"petek",
+		"sobota"
+	],
+	"field-zone": "Območje",
+	"dateFormatItem-y": "y",
+	"months-standAlone-narrow": [
 		"j",
 		"f",
 		"m",
@@ -165,54 +209,61 @@ define(
 		"n",
 		"d"
 	],
-	"days-standAlone-abbr": [
-		"ned",
-		"pon",
-		"tor",
-		"sre",
-		"čet",
-		"pet",
-		"sob"
+	"field-year-relative+-1": "Lani",
+	"field-month-relative+-1": "Prejšnji mesec",
+	"dateFormatItem-hm": "h:mm a",
+	"days-format-abbr": [
+		"ned.",
+		"pon.",
+		"tor.",
+		"sre.",
+		"čet.",
+		"pet.",
+		"sob."
 	],
-	"dateFormat-short": "d. MM. yy",
-	"dateFormatItem-yyyyM": "M/yyyy",
-	"dateFormatItem-yMMMEd": "E., d. MMM y",
-	"dateFormat-full": "EEEE, dd. MMMM y",
-	"dateFormatItem-Md": "d. M.",
-	"dateFormatItem-yMEd": "E., d. M. y",
-	"months-format-wide": [
-		"januar",
-		"februar",
-		"marec",
-		"april",
-		"maj",
-		"junij",
-		"julij",
-		"avgust",
-		"september",
-		"oktober",
-		"november",
-		"december"
+	"dateFormatItem-yMMMd": "d. MMM y",
+	"eraNames": [
+		"pred našim štetjem",
+		"naše štetje"
 	],
-	"quarters-format-wide": [
-		"1. četrtletje",
-		"2. četrtletje",
-		"3. četrtletje",
-		"4. četrtletje"
+	"days-format-narrow": [
+		"n",
+		"p",
+		"t",
+		"s",
+		"č",
+		"p",
+		"s"
 	],
-	"days-format-wide": [
-		"nedelja",
-		"ponedeljek",
-		"torek",
-		"sreda",
-		"četrtek",
-		"petek",
-		"sobota"
+	"field-month": "Mesec",
+	"days-standAlone-narrow": [
+		"n",
+		"p",
+		"t",
+		"s",
+		"č",
+		"p",
+		"s"
 	],
-	"eraNarrow": [
-		"pr. n. št.",
-		"po Kr."
-	]
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "dop.",
+	"dateFormat-short": "d. MM. yy",
+	"field-second": "Sekunda",
+	"dateFormatItem-yMMMEd": "E, d. MMM y",
+	"field-month-relative+0": "Ta mesec",
+	"field-month-relative+1": "Naslednji mesec",
+	"dateFormatItem-Ed": "E, d.",
+	"field-week": "Teden",
+	"dateFormat-medium": "d. MMM y",
+	"field-year-relative+0": "Letos",
+	"field-week-relative+-1": "Prejšnji teden",
+	"field-year-relative+1": "Naslednje leto",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-week-relative+0": "Ta teden",
+	"field-week-relative+1": "Naslednji teden"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/sl/number.js b/dojo/cldr/nls/sl/number.js
index c6d268d..aeeddd7 100644
--- a/dojo/cldr/nls/sl/number.js
+++ b/dojo/cldr/nls/sl/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0%",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
-	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"currencyFormat": "¤#,##0.00;(¤#,##0.00)",
+	"plusSign": "+",
+	"decimalFormat-long": "000 bilijonov",
+	"decimalFormat-short": "000 bil'.'"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/buddhist.js b/dojo/cldr/nls/sv/buddhist.js
new file mode 100644
index 0000000..4363a04
--- /dev/null
+++ b/dojo/cldr/nls/sv/buddhist.js
@@ -0,0 +1,242 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sö",
+		"Må",
+		"Ti",
+		"On",
+		"To",
+		"Fr",
+		"Lö"
+	],
+	"months-format-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-weekday": "veckodag",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"days-format-short": [
+		"sö",
+		"må",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lö"
+	],
+	"dateFormat-long": "d MMMM y G",
+	"months-format-wide": [
+		"januari",
+		"februari",
+		"mars",
+		"april",
+		"maj",
+		"juni",
+		"juli",
+		"augusti",
+		"september",
+		"oktober",
+		"november",
+		"december"
+	],
+	"dayPeriods-format-wide-pm": "em",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-yyyyMEd": "E, y-MM-dd G",
+	"dateFormatItem-Md": "d/M",
+	"dayPeriods-format-abbr-am": "FM",
+	"field-era": "era",
+	"months-standAlone-wide": [
+		"Januari",
+		"Februari",
+		"Mars",
+		"April",
+		"Maj",
+		"Juni",
+		"Juli",
+		"Augusti",
+		"September",
+		"Oktober",
+		"November",
+		"December"
+	],
+	"quarters-format-wide": [
+		"1:a kvartalet",
+		"2:a kvartalet",
+		"3:e kvartalet",
+		"4:e kvartalet"
+	],
+	"field-year": "år",
+	"field-hour": "timme",
+	"months-format-abbr": [
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"maj",
+		"jun",
+		"jul",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
+		"dec"
+	],
+	"timeFormat-full": "'kl'. HH:mm:ss zzzz",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgon",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "i övermorgon",
+	"months-standAlone-abbr": [
+		"Jan",
+		"Feb",
+		"Mar",
+		"Apr",
+		"Maj",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Okt",
+		"Nov",
+		"Dec"
+	],
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"quarters-standAlone-wide": [
+		"1:a kvartalet",
+		"2:a kvartalet",
+		"3:e kvartalet",
+		"4:e kvartalet"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"days-standAlone-wide": [
+		"Söndag",
+		"Måndag",
+		"Tisdag",
+		"Onsdag",
+		"Torsdag",
+		"Fredag",
+		"Lördag"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"eraAbbr": [
+		"BE"
+	],
+	"field-minute": "minut",
+	"field-dayperiod": "fm/em",
+	"days-standAlone-abbr": [
+		"Sön",
+		"Mån",
+		"Tis",
+		"Ons",
+		"Tor",
+		"Fre",
+		"Lör"
+	],
+	"field-day-relative+-1": "i går",
+	"dayPeriods-format-narrow-am": "f",
+	"field-day-relative+-2": "i förrgår",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E d/M",
+	"field-day": "dag",
+	"days-format-wide": [
+		"söndag",
+		"måndag",
+		"tisdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lördag"
+	],
+	"field-zone": "tidszon",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-year-relative+-1": "i fjol",
+	"field-month-relative+-1": "förra månaden",
+	"dayPeriods-format-abbr-pm": "EM",
+	"days-format-abbr": [
+		"sön",
+		"mån",
+		"tis",
+		"ons",
+		"tors",
+		"fre",
+		"lör"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormatItem-yyyyMd": "G y-MM-dd",
+	"field-month": "månad",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dayPeriods-format-wide-am": "fm",
+	"dateFormat-short": "G y-MM-dd",
+	"field-second": "sekund",
+	"field-month-relative+0": "denna månad",
+	"field-month-relative+1": "nästa månad",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "vecka",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "i år",
+	"field-week-relative+-1": "förra veckan",
+	"dateFormatItem-yyyyM": "G y-MM",
+	"field-year-relative+1": "nästa år",
+	"dayPeriods-format-narrow-pm": "e",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "denna vecka",
+	"field-week-relative+1": "nästa vecka"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/coptic.js b/dojo/cldr/nls/sv/coptic.js
new file mode 100644
index 0000000..82c9e4d
--- /dev/null
+++ b/dojo/cldr/nls/sv/coptic.js
@@ -0,0 +1,91 @@
+define(
+//begin v1.x content
+{
+	"field-second": "sekund",
+	"field-year-relative+-1": "i fjol",
+	"field-week": "vecka",
+	"field-month-relative+-1": "förra månaden",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i förrgår",
+	"months-standAlone-wide": [
+		"Tout",
+		"Bâbâ",
+		"Hâtour",
+		"Kiahk",
+		"Toubah",
+		"Amshîr",
+		"Barmahât",
+		"Barmoudah",
+		"Bashans",
+		"Ba’ounah",
+		"Abîb",
+		"Misra",
+		"Al-nasi"
+	],
+	"field-year": "år",
+	"field-week-relative+0": "denna vecka",
+	"months-standAlone-abbr": [
+		"Tout",
+		"Bâbâ",
+		"Hâtour",
+		"Kiahk",
+		"Toubah",
+		"Amshîr",
+		"Barmahât",
+		"Barmoudah",
+		"Bashans",
+		"Ba’ounah",
+		"Abîb",
+		"Misra",
+		"Al-nasi"
+	],
+	"field-week-relative+1": "nästa vecka",
+	"field-minute": "minut",
+	"field-week-relative+-1": "förra veckan",
+	"field-day-relative+0": "i dag",
+	"field-hour": "timme",
+	"field-day-relative+1": "i morgon",
+	"field-day-relative+2": "i övermorgon",
+	"field-day": "dag",
+	"field-month-relative+0": "denna månad",
+	"field-month-relative+1": "nästa månad",
+	"field-dayperiod": "fm/em",
+	"field-month": "månad",
+	"months-format-wide": [
+		"tout",
+		"bâbâ",
+		"hâtour",
+		"kiahk",
+		"toubah",
+		"amshîr",
+		"barmahât",
+		"barmoudah",
+		"bashans",
+		"ba’ounah",
+		"abîb",
+		"misra",
+		"al-nasi"
+	],
+	"field-era": "era",
+	"field-year-relative+0": "i år",
+	"field-year-relative+1": "nästa år",
+	"months-format-abbr": [
+		"tout",
+		"bâbâ",
+		"hâtour",
+		"kiahk",
+		"toubah",
+		"amshîr",
+		"barmahât",
+		"barmoudah",
+		"bashans",
+		"ba’ounah",
+		"abîb",
+		"misra",
+		"al-nasi"
+	],
+	"field-weekday": "veckodag",
+	"field-zone": "tidszon"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/currency.js b/dojo/cldr/nls/sv/currency.js
index 54f152e..00c7c36 100644
--- a/dojo/cldr/nls/sv/currency.js
+++ b/dojo/cldr/nls/sv/currency.js
@@ -3,15 +3,20 @@ define(
 {
 	"HKD_displayName": "Hongkong-dollar",
 	"CHF_displayName": "schweizisk franc",
-	"CHF_symbol": "CHF",
+	"JPY_symbol": "JP¥",
 	"CAD_displayName": "kanadensisk dollar",
+	"HKD_symbol": "HK$",
 	"CNY_displayName": "kinesisk yuan renminbi",
+	"USD_symbol": "US$",
 	"AUD_displayName": "australisk dollar",
 	"JPY_displayName": "japansk yen",
-	"CAD_symbol": "CAD",
+	"CAD_symbol": "CAN$",
 	"USD_displayName": "US-dollar",
-	"CNY_symbol": "CNY",
+	"EUR_symbol": "€",
+	"CNY_symbol": "CN¥",
 	"GBP_displayName": "brittiskt pund sterling",
+	"GBP_symbol": "GB£",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/sv/ethiopic.js b/dojo/cldr/nls/sv/ethiopic.js
new file mode 100644
index 0000000..3a5791d
--- /dev/null
+++ b/dojo/cldr/nls/sv/ethiopic.js
@@ -0,0 +1,91 @@
+define(
+//begin v1.x content
+{
+	"field-second": "sekund",
+	"field-year-relative+-1": "i fjol",
+	"field-week": "vecka",
+	"field-month-relative+-1": "förra månaden",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i förrgår",
+	"months-standAlone-wide": [
+		"Mäskäräm",
+		"Teqemt",
+		"Hedar",
+		"Tahesas",
+		"Ter",
+		"Yäkatit",
+		"Mägabit",
+		"Miyazya",
+		"Guenbot",
+		"Säné",
+		"Hamlé",
+		"Nähasé",
+		"Pagumén"
+	],
+	"field-year": "år",
+	"field-week-relative+0": "denna vecka",
+	"months-standAlone-abbr": [
+		"Mäskäräm",
+		"Teqemt",
+		"Hedar",
+		"Tahesas",
+		"Ter",
+		"Yäkatit",
+		"Mägabit",
+		"Miyazya",
+		"Guenbot",
+		"Säné",
+		"Hamlé",
+		"Nähasé",
+		"Pagumén"
+	],
+	"field-week-relative+1": "nästa vecka",
+	"field-minute": "minut",
+	"field-week-relative+-1": "förra veckan",
+	"field-day-relative+0": "i dag",
+	"field-hour": "timme",
+	"field-day-relative+1": "i morgon",
+	"field-day-relative+2": "i övermorgon",
+	"field-day": "dag",
+	"field-month-relative+0": "denna månad",
+	"field-month-relative+1": "nästa månad",
+	"field-dayperiod": "fm/em",
+	"field-month": "månad",
+	"months-format-wide": [
+		"mäskäräm",
+		"teqemt",
+		"hedar",
+		"tahesas",
+		"ter",
+		"yäkatit",
+		"mägabit",
+		"miyazya",
+		"guenbot",
+		"säné",
+		"hamlé",
+		"nähasé",
+		"pagumén"
+	],
+	"field-era": "era",
+	"field-year-relative+0": "i år",
+	"field-year-relative+1": "nästa år",
+	"months-format-abbr": [
+		"mäskäräm",
+		"teqemt",
+		"hedar",
+		"tahesas",
+		"ter",
+		"yäkatit",
+		"mägabit",
+		"miyazya",
+		"guenbot",
+		"säné",
+		"hamlé",
+		"nähasé",
+		"pagumén"
+	],
+	"field-weekday": "veckodag",
+	"field-zone": "tidszon"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/generic.js b/dojo/cldr/nls/sv/generic.js
new file mode 100644
index 0000000..34daabb
--- /dev/null
+++ b/dojo/cldr/nls/sv/generic.js
@@ -0,0 +1,73 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"field-dayperiod": "fm/em",
+	"field-minute": "minut",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "i går",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-MMdd": "dd/MM",
+	"field-day-relative+-2": "i förrgår",
+	"field-weekday": "veckodag",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "era",
+	"field-hour": "timme",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgon",
+	"field-day-relative+2": "i övermorgon",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMM": "G y-MM",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "tidszon",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormatItem-MMd": "d/M",
+	"field-week-relative+-1": "förra veckan",
+	"dateFormat-medium": "d MMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "i år",
+	"field-year-relative+1": "nästa år",
+	"field-year-relative+-1": "i fjol",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "G y QQQQ",
+	"field-year": "år",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "vecka",
+	"dateFormatItem-yyyyMd": "G y-MM-dd",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-MMMMEd": "E d:'e' MMMM",
+	"dateFormatItem-yyyyMEd": "E, y-MM-dd G",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "denna vecka",
+	"field-week-relative+1": "nästa vecka",
+	"field-month-relative+0": "denna månad",
+	"dateFormatItem-H": "HH",
+	"field-month": "månad",
+	"field-month-relative+1": "nästa månad",
+	"dateFormatItem-MMMMd": "d:'e' MMMM",
+	"dateFormatItem-M": "L",
+	"field-second": "sekund",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "dag",
+	"dateFormatItem-MEd": "E d/M",
+	"dateFormatItem-yyyyQQQ": "G y QQQ",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "G y-MM-dd",
+	"dateFormatItem-yyyyM": "G y-MM",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "förra månaden",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/gregorian.js b/dojo/cldr/nls/sv/gregorian.js
index a616dfe..46bcf94 100644
--- a/dojo/cldr/nls/sv/gregorian.js
+++ b/dojo/cldr/nls/sv/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"Sö",
+		"Må",
+		"Ti",
+		"On",
+		"To",
+		"Fr",
+		"Lö"
+	],
 	"months-format-narrow": [
 		"J",
 		"F",
@@ -23,12 +32,23 @@ define(
 	],
 	"field-weekday": "veckodag",
 	"dateFormatItem-yQQQ": "y QQQ",
-	"dateFormatItem-yMEd": "EEE, yyyy-MM-dd",
+	"dateFormatItem-yMEd": "E, y-MM-dd",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
 	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
 		"f.Kr.",
 		"e.Kr."
 	],
+	"dateFormatItem-yMM": "y-MM",
+	"days-format-short": [
+		"sö",
+		"må",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lö"
+	],
 	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
 		"januari",
@@ -44,26 +64,27 @@ define(
 		"november",
 		"december"
 	],
-	"dateFormatItem-EEEd": "EEE d",
+	"dateTimeFormat-medium": "{1} {0}",
 	"dayPeriods-format-wide-pm": "em",
 	"dateFormat-full": "EEEE'en' 'den' d:'e' MMMM y",
 	"dateFormatItem-Md": "d/M",
-	"dateFormatItem-MMMMEEEd": "EEE d MMMM",
+	"dayPeriods-format-abbr-am": "FM",
+	"dateFormatItem-yMd": "y-MM-dd",
+	"dateFormatItem-yM": "y-MM",
 	"field-era": "era",
-	"dateFormatItem-yM": "yyyy-MM",
 	"months-standAlone-wide": [
-		"januari",
-		"februari",
-		"mars",
-		"april",
-		"maj",
-		"juni",
-		"juli",
-		"augusti",
-		"september",
-		"oktober",
-		"november",
-		"december"
+		"Januari",
+		"Februari",
+		"Mars",
+		"April",
+		"Maj",
+		"Juni",
+		"Juli",
+		"Augusti",
+		"September",
+		"Oktober",
+		"November",
+		"December"
 	],
 	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
@@ -73,11 +94,11 @@ define(
 		"4:e kvartalet"
 	],
 	"timeFormat-long": "HH:mm:ss z",
-	"field-year": "år",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "yyyy Q",
-	"field-hour": "timme",
+	"dateFormatItem-yQQQQ": "y QQQQ",
+	"field-year": "år",
 	"dateFormatItem-MMdd": "dd/MM",
+	"field-hour": "timme",
 	"months-format-abbr": [
 		"jan",
 		"feb",
@@ -92,25 +113,25 @@ define(
 		"nov",
 		"dec"
 	],
-	"dateFormatItem-yyQ": "Q yy",
 	"timeFormat-full": "'kl'. HH:mm:ss zzzz",
 	"field-day-relative+0": "i dag",
 	"field-day-relative+1": "i morgon",
+	"dateFormatItem-GyMMMd": "d MMM y G",
 	"field-day-relative+2": "i övermorgon",
-	"field-day-relative+3": "i överövermorgon",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
-		"jan",
-		"feb",
-		"mar",
-		"apr",
-		"maj",
-		"jun",
-		"jul",
-		"aug",
-		"sep",
-		"okt",
-		"nov",
-		"dec"
+		"Jan",
+		"Feb",
+		"Mar",
+		"Apr",
+		"Maj",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Okt",
+		"Nov",
+		"Dec"
 	],
 	"quarters-format-abbr": [
 		"K1",
@@ -124,19 +145,18 @@ define(
 		"3:e kvartalet",
 		"4:e kvartalet"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"söndag",
-		"måndag",
-		"tisdag",
-		"onsdag",
-		"torsdag",
-		"fredag",
-		"lördag"
+		"Söndag",
+		"Måndag",
+		"Tisdag",
+		"Onsdag",
+		"Torsdag",
+		"Fredag",
+		"Lördag"
 	],
-	"dateFormatItem-yyyyMMM": "MMM y",
 	"dateFormatItem-MMMMd": "d:'e' MMMM",
-	"dateFormatItem-yyMMM": "MMM -yy",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -152,21 +172,30 @@ define(
 	"field-minute": "minut",
 	"field-dayperiod": "fm/em",
 	"days-standAlone-abbr": [
-		"sön",
-		"mån",
-		"tis",
-		"ons",
-		"tors",
-		"fre",
-		"lör"
+		"Sön",
+		"Mån",
+		"Tis",
+		"Ons",
+		"Tor",
+		"Fre",
+		"Lör"
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "i går",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "f",
 	"field-day-relative+-2": "i förrgår",
-	"field-day-relative+-3": "i förrförrgår",
 	"dateFormatItem-MMMd": "d MMM",
 	"dateFormatItem-MEd": "E d/M",
+	"dateTimeFormat-full": "{1} {0}",
 	"field-day": "dag",
 	"days-format-wide": [
 		"söndag",
@@ -178,7 +207,6 @@ define(
 		"lördag"
 	],
 	"field-zone": "tidszon",
-	"dateFormatItem-yyyyMM": "yyyy-MM",
 	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
 		"J",
@@ -194,8 +222,10 @@ define(
 		"N",
 		"D"
 	],
-	"dateFormatItem-yyMM": "yy-MM",
+	"field-year-relative+-1": "i fjol",
+	"field-month-relative+-1": "förra månaden",
 	"dateFormatItem-hm": "h:mm a",
+	"dayPeriods-format-abbr-pm": "EM",
 	"days-format-abbr": [
 		"sön",
 		"mån",
@@ -205,6 +235,7 @@ define(
 		"fre",
 		"lör"
 	],
+	"dateFormatItem-yMMMd": "d MMM y",
 	"eraNames": [
 		"före Kristus",
 		"efter Kristus"
@@ -218,7 +249,6 @@ define(
 		"F",
 		"L"
 	],
-	"field-month": "månad",
 	"days-standAlone-narrow": [
 		"S",
 		"M",
@@ -229,17 +259,28 @@ define(
 		"L"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "månad",
 	"dayPeriods-format-wide-am": "fm",
 	"dateFormatItem-MMMMEd": "E d:'e' MMMM",
-	"dateFormat-short": "yyyy-MM-dd",
+	"dateFormat-short": "y-MM-dd",
 	"dateFormatItem-MMd": "d/M",
 	"field-second": "sekund",
-	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"dateFormatItem-yMMMEd": "E d MMM y",
+	"field-month-relative+0": "denna månad",
+	"field-month-relative+1": "nästa månad",
+	"dateFormatItem-Ed": "E d",
 	"field-week": "vecka",
 	"dateFormat-medium": "d MMM y",
-	"dateFormatItem-yyyyQQQQ": "QQQQ y",
+	"field-year-relative+0": "i år",
+	"field-week-relative+-1": "förra veckan",
+	"field-year-relative+1": "nästa år",
+	"dayPeriods-format-narrow-pm": "e",
+	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "HH:mm:ss",
-	"dateFormatItem-hms": "h:mm:ss a"
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "denna vecka",
+	"field-week-relative+1": "nästa vecka"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/hebrew.js b/dojo/cldr/nls/sv/hebrew.js
new file mode 100644
index 0000000..440dd82
--- /dev/null
+++ b/dojo/cldr/nls/sv/hebrew.js
@@ -0,0 +1,221 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sö",
+		"Må",
+		"Ti",
+		"On",
+		"To",
+		"Fr",
+		"Lö"
+	],
+	"field-weekday": "veckodag",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"days-format-short": [
+		"sö",
+		"må",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lö"
+	],
+	"dateFormat-long": "d MMMM y G",
+	"months-format-wide": [
+		"tishrí",
+		"heshván",
+		"kislév",
+		"tevét",
+		"shevát",
+		"adár I",
+		"adár",
+		"nisán",
+		"ijjár",
+		"siván",
+		"tammúz",
+		"ab",
+		"elúl"
+	],
+	"dayPeriods-format-wide-pm": "em",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-yyyyMEd": "E, y-MM-dd G",
+	"dateFormatItem-Md": "d/M",
+	"dayPeriods-format-abbr-am": "FM",
+	"field-era": "era",
+	"months-standAlone-wide": [
+		"Tishrí",
+		"Heshván",
+		"Kislév",
+		"Tevét",
+		"Shevát",
+		"Adár I",
+		"Adár",
+		"Nisán",
+		"Ijjár",
+		"Siván",
+		"Tammúz",
+		"Ab",
+		"Elúl"
+	],
+	"quarters-format-wide": [
+		"1:a kvartalet",
+		"2:a kvartalet",
+		"3:e kvartalet",
+		"4:e kvartalet"
+	],
+	"field-year": "år",
+	"field-hour": "timme",
+	"months-format-abbr": [
+		"tishrí",
+		"heshván",
+		"kislév",
+		"tevét",
+		"shevát",
+		"adár I",
+		"adár",
+		"nisán",
+		"ijjár",
+		"siván",
+		"tammúz",
+		"ab",
+		"elúl"
+	],
+	"timeFormat-full": "'kl'. HH:mm:ss zzzz",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgon",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "i övermorgon",
+	"months-standAlone-abbr": [
+		"Tishrí",
+		"Heshván",
+		"Kislév",
+		"Tevét",
+		"Shevát",
+		"Adár I",
+		"Adár",
+		"Nisán",
+		"Ijjár",
+		"Siván",
+		"Tammúz",
+		"Ab",
+		"Elúl"
+	],
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"quarters-standAlone-wide": [
+		"1:a kvartalet",
+		"2:a kvartalet",
+		"3:e kvartalet",
+		"4:e kvartalet"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"days-standAlone-wide": [
+		"Söndag",
+		"Måndag",
+		"Tisdag",
+		"Onsdag",
+		"Torsdag",
+		"Fredag",
+		"Lördag"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"months-standAlone-wide-leap": "Adár II",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"eraAbbr": [
+		"AM"
+	],
+	"field-minute": "minut",
+	"field-dayperiod": "fm/em",
+	"days-standAlone-abbr": [
+		"Sön",
+		"Mån",
+		"Tis",
+		"Ons",
+		"Tor",
+		"Fre",
+		"Lör"
+	],
+	"field-day-relative+-1": "i går",
+	"dayPeriods-format-narrow-am": "f",
+	"field-day-relative+-2": "i förrgår",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E d/M",
+	"field-day": "dag",
+	"days-format-wide": [
+		"söndag",
+		"måndag",
+		"tisdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lördag"
+	],
+	"field-zone": "tidszon",
+	"months-standAlone-abbr-leap": "Adár II",
+	"dateFormatItem-y": "y G",
+	"field-year-relative+-1": "i fjol",
+	"field-month-relative+-1": "förra månaden",
+	"dayPeriods-format-abbr-pm": "EM",
+	"days-format-abbr": [
+		"sön",
+		"mån",
+		"tis",
+		"ons",
+		"tors",
+		"fre",
+		"lör"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormatItem-yyyyMd": "G y-MM-dd",
+	"field-month": "månad",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dayPeriods-format-wide-am": "fm",
+	"dateFormat-short": "G y-MM-dd",
+	"field-second": "sekund",
+	"field-month-relative+0": "denna månad",
+	"field-month-relative+1": "nästa månad",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "vecka",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "i år",
+	"field-week-relative+-1": "förra veckan",
+	"dateFormatItem-yyyyM": "G y-MM",
+	"field-year-relative+1": "nästa år",
+	"dayPeriods-format-narrow-pm": "e",
+	"months-format-wide-leap": "adár II",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "denna vecka",
+	"field-week-relative+1": "nästa vecka"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/indian.js b/dojo/cldr/nls/sv/indian.js
new file mode 100644
index 0000000..bf1ffd2
--- /dev/null
+++ b/dojo/cldr/nls/sv/indian.js
@@ -0,0 +1,90 @@
+define(
+//begin v1.x content
+{
+	"field-second": "sekund",
+	"field-year-relative+-1": "i fjol",
+	"field-week": "vecka",
+	"field-month-relative+-1": "förra månaden",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i förrgår",
+	"months-standAlone-wide": [
+		"Chaitra",
+		"Vaishākh",
+		"Jyaishtha",
+		"Āshādha",
+		"Shrāvana",
+		"Bhādrapad",
+		"Āshwin",
+		"Kārtik",
+		"Mārgashīrsha",
+		"Paush",
+		"Māgh",
+		"Phālgun"
+	],
+	"field-year": "år",
+	"field-week-relative+0": "denna vecka",
+	"months-standAlone-abbr": [
+		"Chaitra",
+		"Vaishākh",
+		"Jyaishtha",
+		"Āshādha",
+		"Shrāvana",
+		"Bhādrapad",
+		"Āshwin",
+		"Kārtik",
+		"Mārgashīrsha",
+		"Paush",
+		"Māgh",
+		"Phālgun"
+	],
+	"field-week-relative+1": "nästa vecka",
+	"field-minute": "minut",
+	"field-week-relative+-1": "förra veckan",
+	"field-day-relative+0": "i dag",
+	"field-hour": "timme",
+	"field-day-relative+1": "i morgon",
+	"field-day-relative+2": "i övermorgon",
+	"field-day": "dag",
+	"field-month-relative+0": "denna månad",
+	"field-month-relative+1": "nästa månad",
+	"field-dayperiod": "fm/em",
+	"field-month": "månad",
+	"months-format-wide": [
+		"chaitra",
+		"vaishākh",
+		"jyaishtha",
+		"āshādha",
+		"shrāvana",
+		"bhādrapad",
+		"āshwin",
+		"kārtik",
+		"mārgashīrsha",
+		"paush",
+		"māgh",
+		"phālgun"
+	],
+	"field-era": "era",
+	"field-year-relative+0": "i år",
+	"field-year-relative+1": "nästa år",
+	"months-format-abbr": [
+		"chaitra",
+		"vaishākh",
+		"jyaishtha",
+		"āshādha",
+		"shrāvana",
+		"bhādrapad",
+		"āshwin",
+		"kārtik",
+		"mārgashīrsha",
+		"paush",
+		"māgh",
+		"phālgun"
+	],
+	"eraAbbr": [
+		"SAKA"
+	],
+	"field-weekday": "veckodag",
+	"field-zone": "tidszon"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/islamic.js b/dojo/cldr/nls/sv/islamic.js
new file mode 100644
index 0000000..d852453
--- /dev/null
+++ b/dojo/cldr/nls/sv/islamic.js
@@ -0,0 +1,214 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "fm/em",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"dayPeriods-format-wide-pm": "em",
+	"field-minute": "minut",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "i går",
+	"field-weekday": "veckodag",
+	"field-day-relative+-2": "i förrgår",
+	"days-standAlone-wide": [
+		"Söndag",
+		"Måndag",
+		"Tisdag",
+		"Onsdag",
+		"Torsdag",
+		"Fredag",
+		"Lördag"
+	],
+	"field-era": "era",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "timme",
+	"dayPeriods-format-wide-am": "fm",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "'kl'. HH:mm:ss zzzz",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"muharram",
+		"safar",
+		"rabi’ al-awwal",
+		"rabi’ al-akhir",
+		"jumada-l-ula",
+		"jumada-l-akhira",
+		"rajab",
+		"sha’ban",
+		"ramadan",
+		"shawwal",
+		"dhu-l-ga’da",
+		"dhu-l-hijja"
+	],
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgon",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"field-day-relative+2": "i övermorgon",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "tidszon",
+	"field-week-relative+-1": "förra veckan",
+	"dateFormat-medium": "d MMM y G",
+	"dayPeriods-format-narrow-pm": "e",
+	"field-year-relative+0": "i år",
+	"field-year-relative+1": "nästa år",
+	"quarters-standAlone-wide": [
+		"1:a kvartalet",
+		"2:a kvartalet",
+		"3:e kvartalet",
+		"4:e kvartalet"
+	],
+	"field-year-relative+-1": "i fjol",
+	"field-year": "år",
+	"dayPeriods-format-narrow-am": "f",
+	"months-standAlone-wide": [
+		"Muharram",
+		"Safar",
+		"Rabi’ al-awwal",
+		"Rabi’ al-akhir",
+		"Jumada-l-ula",
+		"Jumada-l-akhira",
+		"Rajab",
+		"Sha’ban",
+		"Ramadan",
+		"Shawwal",
+		"Dhu-l-ga’da",
+		"Dhu-l-hijja"
+	],
+	"field-week": "vecka",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"dateFormatItem-yyyyMd": "G y-MM-dd",
+	"dateFormatItem-yyyyMEd": "E, y-MM-dd G",
+	"field-week-relative+0": "denna vecka",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+1": "nästa vecka",
+	"months-format-abbr": [
+		"muharram",
+		"safar",
+		"rabi’ al-awwal",
+		"rabi’ al-akhir",
+		"jumada-l-ula",
+		"jumada-l-akhira",
+		"rajab",
+		"sha’ban",
+		"ramadan",
+		"shawwal",
+		"dhu-l-ga’da",
+		"dhu-l-hijja"
+	],
+	"field-month-relative+0": "denna månad",
+	"field-month": "månad",
+	"field-month-relative+1": "nästa månad",
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"days-format-abbr": [
+		"sön",
+		"mån",
+		"tis",
+		"ons",
+		"tors",
+		"fre",
+		"lör"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"field-second": "sekund",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "dag",
+	"dateFormatItem-MEd": "E d/M",
+	"days-standAlone-short": [
+		"Sö",
+		"Må",
+		"Ti",
+		"On",
+		"To",
+		"Fr",
+		"Lö"
+	],
+	"days-standAlone-abbr": [
+		"Sön",
+		"Mån",
+		"Tis",
+		"Ons",
+		"Tor",
+		"Fre",
+		"Lör"
+	],
+	"dayPeriods-format-abbr-pm": "EM",
+	"dateFormat-short": "G y-MM-dd",
+	"dateFormatItem-yyyyM": "G y-MM",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"months-format-wide": [
+		"muharram",
+		"safar",
+		"rabi’ al-awwal",
+		"rabi’ al-akhir",
+		"jumada-l-ula",
+		"jumada-l-akhira",
+		"rajab",
+		"sha’ban",
+		"ramadan",
+		"shawwal",
+		"dhu-l-ga’da",
+		"dhu-l-hijja"
+	],
+	"dayPeriods-format-abbr-am": "FM",
+	"days-format-short": [
+		"sö",
+		"må",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lö"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "förra månaden",
+	"quarters-format-wide": [
+		"1:a kvartalet",
+		"2:a kvartalet",
+		"3:e kvartalet",
+		"4:e kvartalet"
+	],
+	"days-format-wide": [
+		"söndag",
+		"måndag",
+		"tisdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lördag"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/japanese.js b/dojo/cldr/nls/sv/japanese.js
new file mode 100644
index 0000000..af32ea5
--- /dev/null
+++ b/dojo/cldr/nls/sv/japanese.js
@@ -0,0 +1,269 @@
+define(
+//begin v1.x content
+{
+	"field-second": "sekund",
+	"field-year-relative+-1": "i fjol",
+	"field-week": "vecka",
+	"field-month-relative+-1": "förra månaden",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i förrgår",
+	"field-year": "år",
+	"field-week-relative+0": "denna vecka",
+	"field-week-relative+1": "nästa vecka",
+	"field-minute": "minut",
+	"field-week-relative+-1": "förra veckan",
+	"field-day-relative+0": "i dag",
+	"field-hour": "timme",
+	"field-day-relative+1": "i morgon",
+	"field-day-relative+2": "i övermorgon",
+	"field-day": "dag",
+	"field-month-relative+0": "denna månad",
+	"field-month-relative+1": "nästa månad",
+	"field-dayperiod": "fm/em",
+	"field-month": "månad",
+	"field-era": "era",
+	"field-year-relative+0": "i år",
+	"field-year-relative+1": "nästa år",
+	"eraAbbr": [
+		"Taika (645–650)",
+		"Hakuchi (650–671)",
+		"Hakuhō (672–686)",
+		"Shuchō (686–701)",
+		"Taihō (701–704)",
+		"Keiun (704–708)",
+		"Wadō (708–715)",
+		"Reiki (715–717)",
+		"Yōrō (717–724)",
+		"Jinki (724–729)",
+		"Tempyō (729–749)",
+		"Tempyō-kampō (749–749)",
+		"Tempyō-shōhō (749–757)",
+		"Tempyō-hōji (757–765)",
+		"Temphō-jingo (765–767)",
+		"Jingo-keiun (767–770)",
+		"Hōki (770–780)",
+		"Ten-ō (781–782)",
+		"Enryaku (782–806)",
+		"Daidō (806–810)",
+		"Kōnin (810–824)",
+		"Tenchō (824–834)",
+		"Jōwa (834–848)",
+		"Kajō (848–851)",
+		"Ninju (851–854)",
+		"Saiko (854–857)",
+		"Tennan (857–859)",
+		"Jōgan (859–877)",
+		"Genkei (877–885)",
+		"Ninna (885–889)",
+		"Kampyō (889–898)",
+		"Shōtai (898–901)",
+		"Engi (901–923)",
+		"Enchō (923–931)",
+		"Shōhei (931–938)",
+		"Tengyō (938–947)",
+		"Tenryaku (947–957)",
+		"Tentoku (957–961)",
+		"Ōwa (961–964)",
+		"Kōhō (964–968)",
+		"Anna (968–970)",
+		"Tenroku (970–973)",
+		"Ten-en (973–976)",
+		"Jōgen (976–978)",
+		"Tengen (978–983)",
+		"Eikan (983–985)",
+		"Kanna (985–987)",
+		"Ei-en (987–989)",
+		"Eiso (989–990)",
+		"Shōryaku (990–995)",
+		"Chōtoku (995–999)",
+		"Chōhō (999–1004)",
+		"Kankō (1004–1012)",
+		"Chōwa (1012–1017)",
+		"Kannin (1017–1021)",
+		"Jian (1021–1024)",
+		"Manju (1024–1028)",
+		"Chōgen (1028–1037)",
+		"Chōryaku (1037–1040)",
+		"Chōkyū (1040–1044)",
+		"Kantoku (1044–1046)",
+		"Eishō (1046–1053)",
+		"Tengi (1053–1058)",
+		"Kōhei (1058–1065)",
+		"Jiryaku (1065–1069)",
+		"Enkyū (1069–1074)",
+		"Shōho (1074–1077)",
+		"Shōryaku (1077–1081)",
+		"Eiho (1081–1084)",
+		"Ōtoku (1084–1087)",
+		"Kanji (1087–1094)",
+		"Kaho (1094–1096)",
+		"Eichō (1096–1097)",
+		"Shōtoku (1097–1099)",
+		"Kōwa (1099–1104)",
+		"Chōji (1104–1106)",
+		"Kashō (1106–1108)",
+		"Tennin (1108–1110)",
+		"Ten-ei (1110–1113)",
+		"Eikyū (1113–1118)",
+		"Gen-ei (1118–1120)",
+		"Hoan (1120–1124)",
+		"Tenji (1124–1126)",
+		"Daiji (1126–1131)",
+		"Tenshō (1131–1132)",
+		"Chōshō (1132–1135)",
+		"Hoen (1135–1141)",
+		"Eiji (1141–1142)",
+		"Kōji (1142–1144)",
+		"Tenyō (1144–1145)",
+		"Kyūan (1145–1151)",
+		"Ninpei (1151–1154)",
+		"Kyūju (1154–1156)",
+		"Hogen (1156–1159)",
+		"Heiji (1159–1160)",
+		"Eiryaku (1160–1161)",
+		"Ōho (1161–1163)",
+		"Chōkan (1163–1165)",
+		"Eiman (1165–1166)",
+		"Nin-an (1166–1169)",
+		"Kaō (1169–1171)",
+		"Shōan (1171–1175)",
+		"Angen (1175–1177)",
+		"Jishō (1177–1181)",
+		"Yōwa (1181–1182)",
+		"Juei (1182–1184)",
+		"Genryuku (1184–1185)",
+		"Bunji (1185–1190)",
+		"Kenkyū (1190–1199)",
+		"Shōji (1199–1201)",
+		"Kennin (1201–1204)",
+		"Genkyū (1204–1206)",
+		"Ken-ei (1206–1207)",
+		"Shōgen (1207–1211)",
+		"Kenryaku (1211–1213)",
+		"Kenpō (1213–1219)",
+		"Shōkyū (1219–1222)",
+		"Jōō (1222–1224)",
+		"Gennin (1224–1225)",
+		"Karoku (1225–1227)",
+		"Antei (1227–1229)",
+		"Kanki (1229–1232)",
+		"Jōei (1232–1233)",
+		"Tempuku (1233–1234)",
+		"Bunryaku (1234–1235)",
+		"Katei (1235–1238)",
+		"Ryakunin (1238–1239)",
+		"En-ō (1239–1240)",
+		"Ninji (1240–1243)",
+		"Kangen (1243–1247)",
+		"Hōji (1247–1249)",
+		"Kenchō (1249–1256)",
+		"Kōgen (1256–1257)",
+		"Shōka (1257–1259)",
+		"Shōgen (1259–1260)",
+		"Bun-ō (1260–1261)",
+		"Kōchō (1261–1264)",
+		"Bun-ei (1264–1275)",
+		"Kenji (1275–1278)",
+		"Kōan (1278–1288)",
+		"Shōō (1288–1293)",
+		"Einin (1293–1299)",
+		"Shōan (1299–1302)",
+		"Kengen (1302–1303)",
+		"Kagen (1303–1306)",
+		"Tokuji (1306–1308)",
+		"Enkei (1308–1311)",
+		"Ōchō (1311–1312)",
+		"Shōwa (1312–1317)",
+		"Bunpō (1317–1319)",
+		"Genō (1319–1321)",
+		"Genkyō (1321–1324)",
+		"Shōchū (1324–1326)",
+		"Kareki (1326–1329)",
+		"Gentoku (1329–1331)",
+		"Genkō (1331–1334)",
+		"Kemmu (1334–1336)",
+		"Engen (1336–1340)",
+		"Kōkoku (1340–1346)",
+		"Shōhei (1346–1370)",
+		"Kentoku (1370–1372)",
+		"Bunchū (1372–1375)",
+		"Tenju (1375–1379)",
+		"Kōryaku (1379–1381)",
+		"Kōwa (1381–1384)",
+		"Genchū (1384–1392)",
+		"Meitoku (1384–1387)",
+		"Kakei (1387–1389)",
+		"Kōō (1389–1390)",
+		"Meitoku (1390–1394)",
+		"Ōei (1394–1428)",
+		"Shōchō (1428–1429)",
+		"Eikyō (1429–1441)",
+		"Kakitsu (1441–1444)",
+		"Bun-an (1444–1449)",
+		"Hōtoku (1449–1452)",
+		"Kyōtoku (1452–1455)",
+		"Kōshō (1455–1457)",
+		"Chōroku (1457–1460)",
+		"Kanshō (1460–1466)",
+		"Bunshō (1466–1467)",
+		"Ōnin (1467–1469)",
+		"Bunmei (1469–1487)",
+		"Chōkyō (1487–1489)",
+		"Entoku (1489–1492)",
+		"Meiō (1492–1501)",
+		"Bunki (1501–1504)",
+		"Eishō (1504–1521)",
+		"Taiei (1521–1528)",
+		"Kyōroku (1528–1532)",
+		"Tenmon (1532–1555)",
+		"Kōji (1555–1558)",
+		"Eiroku (1558–1570)",
+		"Genki (1570–1573)",
+		"Tenshō (1573–1592)",
+		"Bunroku (1592–1596)",
+		"Keichō (1596–1615)",
+		"Genwa (1615–1624)",
+		"Kan-ei (1624–1644)",
+		"Shōho (1644–1648)",
+		"Keian (1648–1652)",
+		"Shōō (1652–1655)",
+		"Meiryaku (1655–1658)",
+		"Manji (1658–1661)",
+		"Kanbun (1661–1673)",
+		"Enpō (1673–1681)",
+		"Tenwa (1681–1684)",
+		"Jōkyō (1684–1688)",
+		"Genroku (1688–1704)",
+		"Hōei (1704–1711)",
+		"Shōtoku (1711–1716)",
+		"Kyōhō (1716–1736)",
+		"Genbun (1736–1741)",
+		"Kanpō (1741–1744)",
+		"Enkyō (1744–1748)",
+		"Kan-en (1748–1751)",
+		"Hōryaku (1751–1764)",
+		"Meiwa (1764–1772)",
+		"An-ei (1772–1781)",
+		"Tenmei (1781–1789)",
+		"Kansei (1789–1801)",
+		"Kyōwa (1801–1804)",
+		"Bunka (1804–1818)",
+		"Bunsei (1818–1830)",
+		"Tenpō (1830–1844)",
+		"Kōka (1844–1848)",
+		"Kaei (1848–1854)",
+		"Ansei (1854–1860)",
+		"Man-en (1860–1861)",
+		"Bunkyū (1861–1864)",
+		"Genji (1864–1865)",
+		"Keiō (1865–1868)",
+		"Meiji",
+		"Taishō",
+		"Shōwa",
+		"Heisei"
+	],
+	"field-weekday": "veckodag",
+	"field-zone": "tidszon"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/number.js b/dojo/cldr/nls/sv/number.js
index 675248a..1220934 100644
--- a/dojo/cldr/nls/sv/number.js
+++ b/dojo/cldr/nls/sv/number.js
@@ -8,15 +8,16 @@ define(
 	"percentFormat": "#,##0 %",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "−",
 	"decimal": ",",
 	"nan": "¤¤¤",
-	"nativeZeroDigit": "0",
+	"currencyDecimal": ":",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
 	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"plusSign": "+",
+	"decimalFormat-long": "000 biljoner",
+	"decimalFormat-short": "000 bn"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/persian.js b/dojo/cldr/nls/sv/persian.js
new file mode 100644
index 0000000..9dd3a27
--- /dev/null
+++ b/dojo/cldr/nls/sv/persian.js
@@ -0,0 +1,242 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"Sö",
+		"Må",
+		"Ti",
+		"On",
+		"To",
+		"Fr",
+		"Lö"
+	],
+	"months-format-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-weekday": "veckodag",
+	"dateFormatItem-GyMMMEd": "E d MMM y G",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"days-format-short": [
+		"sö",
+		"må",
+		"ti",
+		"on",
+		"to",
+		"fr",
+		"lö"
+	],
+	"dateFormat-long": "d MMMM y G",
+	"months-format-wide": [
+		"farvardin",
+		"ordibehesht",
+		"khordād",
+		"tir",
+		"mordād",
+		"shahrivar",
+		"mehr",
+		"ābān",
+		"āzar",
+		"dey",
+		"bahman",
+		"esfand"
+	],
+	"dayPeriods-format-wide-pm": "em",
+	"dateFormat-full": "EEEE d MMMM y G",
+	"dateFormatItem-yyyyMEd": "E, y-MM-dd G",
+	"dateFormatItem-Md": "d/M",
+	"dayPeriods-format-abbr-am": "FM",
+	"field-era": "era",
+	"months-standAlone-wide": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordād",
+		"Tir",
+		"Mordād",
+		"Shahrivar",
+		"Mehr",
+		"Ābān",
+		"Āzar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"quarters-format-wide": [
+		"1:a kvartalet",
+		"2:a kvartalet",
+		"3:e kvartalet",
+		"4:e kvartalet"
+	],
+	"field-year": "år",
+	"field-hour": "timme",
+	"months-format-abbr": [
+		"farvardin",
+		"ordibehesht",
+		"khordād",
+		"tir",
+		"mordād",
+		"shahrivar",
+		"mehr",
+		"ābān",
+		"āzar",
+		"dey",
+		"bahman",
+		"esfand"
+	],
+	"timeFormat-full": "'kl'. HH:mm:ss zzzz",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgon",
+	"dateFormatItem-GyMMMd": "d MMM y G",
+	"field-day-relative+2": "i övermorgon",
+	"months-standAlone-abbr": [
+		"Farvardin",
+		"Ordibehesht",
+		"Khordād",
+		"Tir",
+		"Mordād",
+		"Shahrivar",
+		"Mehr",
+		"Ābān",
+		"Āzar",
+		"Dey",
+		"Bahman",
+		"Esfand"
+	],
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"quarters-standAlone-wide": [
+		"1:a kvartalet",
+		"2:a kvartalet",
+		"3:e kvartalet",
+		"4:e kvartalet"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y G",
+	"days-standAlone-wide": [
+		"Söndag",
+		"Måndag",
+		"Tisdag",
+		"Onsdag",
+		"Torsdag",
+		"Fredag",
+		"Lördag"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-yyyyMMMd": "d MMM y G",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"eraAbbr": [
+		"AP"
+	],
+	"field-minute": "minut",
+	"field-dayperiod": "fm/em",
+	"days-standAlone-abbr": [
+		"Sön",
+		"Mån",
+		"Tis",
+		"Ons",
+		"Tor",
+		"Fre",
+		"Lör"
+	],
+	"field-day-relative+-1": "i går",
+	"dayPeriods-format-narrow-am": "f",
+	"field-day-relative+-2": "i förrgår",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E d/M",
+	"field-day": "dag",
+	"days-format-wide": [
+		"söndag",
+		"måndag",
+		"tisdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lördag"
+	],
+	"field-zone": "tidszon",
+	"dateFormatItem-y": "y G",
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"field-year-relative+-1": "i fjol",
+	"field-month-relative+-1": "förra månaden",
+	"dayPeriods-format-abbr-pm": "EM",
+	"days-format-abbr": [
+		"sön",
+		"mån",
+		"tis",
+		"ons",
+		"tors",
+		"fre",
+		"lör"
+	],
+	"days-format-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormatItem-yyyyMd": "G y-MM-dd",
+	"field-month": "månad",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dayPeriods-format-wide-am": "fm",
+	"dateFormat-short": "G y-MM-dd",
+	"field-second": "sekund",
+	"field-month-relative+0": "denna månad",
+	"field-month-relative+1": "nästa månad",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "vecka",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "i år",
+	"field-week-relative+-1": "förra veckan",
+	"dateFormatItem-yyyyM": "G y-MM",
+	"field-year-relative+1": "nästa år",
+	"dayPeriods-format-narrow-pm": "e",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"dateFormatItem-yyyy": "y G",
+	"field-week-relative+0": "denna vecka",
+	"field-week-relative+1": "nästa vecka"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/roc.js b/dojo/cldr/nls/sv/roc.js
new file mode 100644
index 0000000..b0afae2
--- /dev/null
+++ b/dojo/cldr/nls/sv/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "sekund",
+	"field-year-relative+-1": "i fjol",
+	"field-week": "vecka",
+	"field-month-relative+-1": "förra månaden",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i förrgår",
+	"field-year": "år",
+	"field-week-relative+0": "denna vecka",
+	"field-week-relative+1": "nästa vecka",
+	"field-minute": "minut",
+	"field-week-relative+-1": "förra veckan",
+	"field-day-relative+0": "i dag",
+	"field-hour": "timme",
+	"field-day-relative+1": "i morgon",
+	"field-day-relative+2": "i övermorgon",
+	"field-day": "dag",
+	"field-month-relative+0": "denna månad",
+	"field-month-relative+1": "nästa månad",
+	"field-dayperiod": "fm/em",
+	"field-month": "månad",
+	"field-era": "era",
+	"field-year-relative+0": "i år",
+	"field-year-relative+1": "nästa år",
+	"eraAbbr": [
+		"före R.K.",
+		"R.K."
+	],
+	"field-weekday": "veckodag",
+	"field-zone": "tidszon"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/buddhist.js b/dojo/cldr/nls/th/buddhist.js
index 3475261..4567d36 100644
--- a/dojo/cldr/nls/th/buddhist.js
+++ b/dojo/cldr/nls/th/buddhist.js
@@ -1,22 +1,22 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "M/yyyy",
-	"dateFormatItem-yQ": "Q yyyy",
-	"dayPeriods-format-wide-pm": "หลังเที่ยง",
-	"eraNames": [
-		"พุทธศักราช"
+	"days-standAlone-short": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
 	],
-	"dateFormatItem-MMMEd": "E d MMM",
-	"dateTimeFormat-full": "{1}, {0}",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"months-standAlone-narrow": [
+	"months-format-narrow": [
 		"ม.ค.",
 		"ก.พ.",
 		"มี.ค.",
 		"เม.ย.",
 		"พ.ค.",
-		"มิ.ย.",
+		"มิ.ย",
 		"ก.ค.",
 		"ส.ค.",
 		"ก.ย.",
@@ -24,49 +24,13 @@ define(
 		"พ.ย.",
 		"ธ.ค."
 	],
-	"dateTimeFormat-short": "{1}, {0}",
-	"dayPeriods-format-wide-am": "ก่อนเที่ยง",
-	"dateTimeFormat-medium": "{1}, {0}",
-	"timeFormat-full": "H นาฬิกา m นาที ss วินาที zzzz",
-	"dateFormatItem-yMMM": "MMM y",
-	"days-standAlone-narrow": [
-		"อ",
-		"จ",
-		"อ",
-		"พ",
-		"พ",
-		"ศ",
-		"ส"
-	],
-	"eraAbbr": [
+	"field-weekday": "วันในสัปดาห์",
+	"dateFormatItem-GyMMMEd": "E d MMM G y",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"eraNarrow": [
 		"พ.ศ."
 	],
-	"dateFormat-long": "d MMMM y",
-	"timeFormat-medium": "H:mm:ss",
-	"dateFormatItem-EEEd": "EEE d",
-	"dateFormatItem-Hm": "H:mm",
-	"dateFormat-medium": "d MMM y",
-	"dateFormatItem-Hms": "H:mm:ss",
-	"dateTimeFormat-long": "{1}, {0}",
-	"dateFormatItem-MMMd": "d MMM",
-	"timeFormat-long": "H นาฬิกา m นาที ss วินาที z",
-	"months-format-abbr": [
-		"ม.ค.",
-		"ก.พ.",
-		"มี.ค.",
-		"เม.ย.",
-		"พ.ค.",
-		"มิ.ย.",
-		"ก.ค.",
-		"ส.ค.",
-		"ก.ย.",
-		"ต.ค.",
-		"พ.ย.",
-		"ธ.ค."
-	],
-	"timeFormat-short": "H:mm",
-	"dateFormatItem-H": "H",
-	"days-format-abbr": [
+	"days-format-short": [
 		"อา.",
 		"จ.",
 		"อ.",
@@ -75,13 +39,29 @@ define(
 		"ศ.",
 		"ส."
 	],
-	"dateFormatItem-MEd": "E, d/M",
-	"dateFormat-short": "d/M/yyyy",
-	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"dateFormat-long": "d MMMM y",
+	"months-format-wide": [
+		"มกราคม",
+		"กุมภาพันธ์",
+		"มีนาคม",
+		"เมษายน",
+		"พฤษภาคม",
+		"มิถุนายน",
+		"กรกฎาคม",
+		"สิงหาคม",
+		"กันยายน",
+		"ตุลาคม",
+		"พฤศจิกายน",
+		"ธันวาคม"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ y",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dayPeriods-format-wide-pm": "หลังเที่ยง",
 	"dateFormat-full": "EEEEที่ d MMMM G y",
+	"dateFormatItem-yyyyMEd": "E d/M/y",
 	"dateFormatItem-Md": "d/M",
-	"dateFormatItem-yMEd": "EEE d/M/yyyy",
-	"months-format-wide": [
+	"field-era": "สมัย",
+	"months-standAlone-wide": [
 		"มกราคม",
 		"กุมภาพันธ์",
 		"มีนาคม",
@@ -101,7 +81,60 @@ define(
 		"ไตรมาส 3",
 		"ไตรมาส 4"
 	],
-	"days-format-wide": [
+	"timeFormat-long": "H นาฬิกา mm นาที ss วินาที z",
+	"field-year": "ปี",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"field-hour": "ชั่วโมง",
+	"months-format-abbr": [
+		"ม.ค.",
+		"ก.พ.",
+		"มี.ค.",
+		"เม.ย.",
+		"พ.ค.",
+		"มิ.ย.",
+		"ก.ค.",
+		"ส.ค.",
+		"ก.ย.",
+		"ต.ค.",
+		"พ.ย.",
+		"ธ.ค."
+	],
+	"timeFormat-full": "H นาฬิกา mm นาที ss วินาที zzzz",
+	"field-day-relative+0": "วันนี้",
+	"field-day-relative+1": "พรุ่งนี้",
+	"dateFormatItem-GyMMMd": "d MMM G y",
+	"field-day-relative+2": "มะรืนนี้",
+	"dateFormatItem-H": "HH",
+	"months-standAlone-abbr": [
+		"ม.ค.",
+		"ก.พ.",
+		"มี.ค.",
+		"เม.ย.",
+		"พ.ค.",
+		"มิ.ย.",
+		"ก.ค.",
+		"ส.ค.",
+		"ก.ย.",
+		"ต.ค.",
+		"พ.ย.",
+		"ธ.ค."
+	],
+	"quarters-format-abbr": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"quarters-standAlone-wide": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"dateFormatItem-Gy": "G y",
+	"dateFormatItem-yyyyMMMEd": "E d MMM y",
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
 		"วันอาทิตย์",
 		"วันจันทร์",
 		"วันอังคาร",
@@ -110,9 +143,125 @@ define(
 		"วันศุกร์",
 		"วันเสาร์"
 	],
-	"eraNarrow": [
+	"dateFormatItem-yyyyMMM": "MMM y",
+	"dateFormatItem-yyyyMMMd": "d MMM y",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-Hm": "HH:mm",
+	"quarters-standAlone-abbr": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"eraAbbr": [
 		"พ.ศ."
-	]
+	],
+	"field-minute": "นาที",
+	"field-dayperiod": "ช่วงวัน",
+	"days-standAlone-abbr": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "เมื่อวาน",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1}, {0}",
+	"dayPeriods-format-narrow-am": "ก่อนเที่ยง",
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day": "วัน",
+	"days-format-wide": [
+		"วันอาทิตย์",
+		"วันจันทร์",
+		"วันอังคาร",
+		"วันพุธ",
+		"วันพฤหัสบดี",
+		"วันศุกร์",
+		"วันเสาร์"
+	],
+	"field-zone": "เขต",
+	"dateFormatItem-y": "G y",
+	"months-standAlone-narrow": [
+		"ม.ค.",
+		"ก.พ.",
+		"มี.ค.",
+		"เม.ย.",
+		"พ.ค.",
+		"มิ.ย.",
+		"ก.ค.",
+		"ส.ค.",
+		"ก.ย.",
+		"ต.ค.",
+		"พ.ย.",
+		"ธ.ค."
+	],
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"dateFormatItem-hm": "h:mm a",
+	"days-format-abbr": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"eraNames": [
+		"พุทธศักราช"
+	],
+	"days-format-narrow": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dateFormatItem-yyyyMd": "d/M/y",
+	"field-month": "เดือน",
+	"days-standAlone-narrow": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "ก่อนเที่ยง",
+	"dateFormatItem-MMMMEd": "E d MMMM",
+	"dateFormat-short": "d/M/yy",
+	"field-second": "วินาที",
+	"field-month-relative+0": "เดือนนี้",
+	"field-month-relative+1": "เดือนหน้า",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "สัปดาห์",
+	"dateFormat-medium": "d MMM y",
+	"field-year-relative+0": "ปีนี้",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"dateFormatItem-yyyyM": "M/y",
+	"field-year-relative+1": "ปีหน้า",
+	"dateFormatItem-mmss": "mm:ss",
+	"dayPeriods-format-narrow-pm": "หลังเที่ยง",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM G y",
+	"dateFormatItem-yyyy": "G y",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"field-week-relative+1": "สัปดาห์หน้า"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/chinese.js b/dojo/cldr/nls/th/chinese.js
new file mode 100644
index 0000000..9c9c3dd
--- /dev/null
+++ b/dojo/cldr/nls/th/chinese.js
@@ -0,0 +1,119 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "U MMM d",
+	"field-second": "วินาที",
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"field-week": "สัปดาห์",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"field-day-relative+-1": "เมื่อวาน",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"months-standAlone-wide": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year": "ปี",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"months-standAlone-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-week-relative+1": "สัปดาห์หน้า",
+	"field-minute": "นาที",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"field-day-relative+0": "วันนี้",
+	"field-hour": "ชั่วโมง",
+	"field-day-relative+1": "พรุ่งนี้",
+	"dateFormat-long": "U MMMM d",
+	"field-day-relative+2": "มะรืนนี้",
+	"field-day": "วัน",
+	"field-month-relative+0": "เดือนนี้",
+	"field-month-relative+1": "เดือนหน้า",
+	"field-dayperiod": "ช่วงวัน",
+	"field-month": "เดือน",
+	"dateFormat-short": "y-M-d",
+	"months-format-wide": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-era": "สมัย",
+	"field-year-relative+0": "ปีนี้",
+	"field-year-relative+1": "ปีหน้า",
+	"months-format-abbr": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormat-full": "EEEE, U MMMM d",
+	"field-weekday": "วันในสัปดาห์",
+	"field-zone": "เขต"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/coptic.js b/dojo/cldr/nls/th/coptic.js
new file mode 100644
index 0000000..4b32ee9
--- /dev/null
+++ b/dojo/cldr/nls/th/coptic.js
@@ -0,0 +1,121 @@
+define(
+//begin v1.x content
+{
+	"field-second": "วินาที",
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"field-week": "สัปดาห์",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"field-day-relative+-1": "เมื่อวาน",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"months-standAlone-wide": [
+		"เทาท์",
+		"บาบา",
+		"ฮาเทอร์",
+		"เคียฟ",
+		"โทบา",
+		"อัมเชอร์",
+		"บารัมฮัท",
+		"บาราเมาดา",
+		"บาชันส์",
+		"พาโอนา",
+		"อีเปป",
+		"เมสรา",
+		"นาซี"
+	],
+	"field-year": "ปี",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"months-standAlone-abbr": [
+		"เทาท์",
+		"บาบา",
+		"ฮาเทอร์",
+		"เคียฟ",
+		"โทบา",
+		"อัมเชอร์",
+		"บารัมฮัท",
+		"บาราเมาดา",
+		"บาชันส์",
+		"พาโอนา",
+		"อีเปป",
+		"เมสรา",
+		"นาซี"
+	],
+	"field-week-relative+1": "สัปดาห์หน้า",
+	"field-minute": "นาที",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"field-day-relative+0": "วันนี้",
+	"field-hour": "ชั่วโมง",
+	"field-day-relative+1": "พรุ่งนี้",
+	"field-day-relative+2": "มะรืนนี้",
+	"field-day": "วัน",
+	"field-month-relative+0": "เดือนนี้",
+	"field-month-relative+1": "เดือนหน้า",
+	"field-dayperiod": "ช่วงวัน",
+	"field-month": "เดือน",
+	"months-format-wide": [
+		"เทาท์",
+		"บาบา",
+		"ฮาเทอร์",
+		"เคียฟ",
+		"โทบา",
+		"อัมเชอร์",
+		"บารัมฮัท",
+		"บาราเมาดา",
+		"บาชันส์",
+		"พาโอนา",
+		"อีเปป",
+		"เมสรา",
+		"นาซี"
+	],
+	"field-era": "สมัย",
+	"field-year-relative+0": "ปีนี้",
+	"field-year-relative+1": "ปีหน้า",
+	"months-format-abbr": [
+		"เทาท์",
+		"บาบา",
+		"ฮาเทอร์",
+		"เคียฟ",
+		"โทบา",
+		"อัมเชอร์",
+		"บารัมฮัท",
+		"บาราเมาดา",
+		"บาชันส์",
+		"พาโอนา",
+		"อีเปป",
+		"เมสรา",
+		"นาซี"
+	],
+	"field-weekday": "วันในสัปดาห์",
+	"field-zone": "เขต"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/currency.js b/dojo/cldr/nls/th/currency.js
index 2991077..14f141d 100644
--- a/dojo/cldr/nls/th/currency.js
+++ b/dojo/cldr/nls/th/currency.js
@@ -5,11 +5,18 @@ define(
 	"CHF_displayName": "ฟรังก์สวิส",
 	"JPY_symbol": "¥",
 	"CAD_displayName": "ดอลลาร์แคนาดา",
-	"CNY_displayName": "หยวนเหรินหมินปี้ (สาธารณรัฐประชาชนจีน)",
+	"HKD_symbol": "HK$",
+	"CNY_displayName": "หยวนจีน",
+	"USD_symbol": "US$",
 	"AUD_displayName": "ดอลลาร์ออสเตรเลีย",
 	"JPY_displayName": "เยนญี่ปุ่น",
+	"CAD_symbol": "CA$",
 	"USD_displayName": "ดอลลาร์สหรัฐ",
+	"EUR_symbol": "€",
+	"CNY_symbol": "CN¥",
 	"GBP_displayName": "ปอนด์สเตอร์ลิง (สหราชอาณาจักร)",
+	"GBP_symbol": "£",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "ยูโร"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/th/ethiopic.js b/dojo/cldr/nls/th/ethiopic.js
new file mode 100644
index 0000000..1052fc3
--- /dev/null
+++ b/dojo/cldr/nls/th/ethiopic.js
@@ -0,0 +1,121 @@
+define(
+//begin v1.x content
+{
+	"field-second": "วินาที",
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"field-week": "สัปดาห์",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"field-day-relative+-1": "เมื่อวาน",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"months-standAlone-wide": [
+		"เมสเคอเรม",
+		"เตเกมท",
+		"เฮดาร์",
+		"ทาฮ์ซัส",
+		"เทอร์",
+		"เยคาทิท",
+		"เมกาบิต",
+		"เมียเซีย",
+		"เจนบอต",
+		"เซเน",
+		"ฮัมเล",
+		"เนแฮซ",
+		"พากูเมน"
+	],
+	"field-year": "ปี",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"months-standAlone-abbr": [
+		"เมสเคอเรม",
+		"เตเกมท",
+		"เฮดาร์",
+		"ทาฮ์ซัส",
+		"เทอร์",
+		"เยคาทิท",
+		"เมกาบิต",
+		"เมียเซีย",
+		"เจนบอต",
+		"เซเน",
+		"ฮัมเล",
+		"เนแฮซ",
+		"พากูเมน"
+	],
+	"field-week-relative+1": "สัปดาห์หน้า",
+	"field-minute": "นาที",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"field-day-relative+0": "วันนี้",
+	"field-hour": "ชั่วโมง",
+	"field-day-relative+1": "พรุ่งนี้",
+	"field-day-relative+2": "มะรืนนี้",
+	"field-day": "วัน",
+	"field-month-relative+0": "เดือนนี้",
+	"field-month-relative+1": "เดือนหน้า",
+	"field-dayperiod": "ช่วงวัน",
+	"field-month": "เดือน",
+	"months-format-wide": [
+		"เมสเคอเรม",
+		"เตเกมท",
+		"เฮดาร์",
+		"ทาฮ์ซัส",
+		"เทอร์",
+		"เยคาทิท",
+		"เมกาบิต",
+		"เมียเซีย",
+		"เจนบอต",
+		"เซเน",
+		"ฮัมเล",
+		"เนแฮซ",
+		"พากูเมน"
+	],
+	"field-era": "สมัย",
+	"field-year-relative+0": "ปีนี้",
+	"field-year-relative+1": "ปีหน้า",
+	"months-format-abbr": [
+		"เมสเคอเรม",
+		"เตเกมท",
+		"เฮดาร์",
+		"ทาฮ์ซัส",
+		"เทอร์",
+		"เยคาทิท",
+		"เมกาบิต",
+		"เมียเซีย",
+		"เจนบอต",
+		"เซเน",
+		"ฮัมเล",
+		"เนแฮซ",
+		"พากูเมน"
+	],
+	"field-weekday": "วันในสัปดาห์",
+	"field-zone": "เขต"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/generic.js b/dojo/cldr/nls/th/generic.js
new file mode 100644
index 0000000..d129291
--- /dev/null
+++ b/dojo/cldr/nls/th/generic.js
@@ -0,0 +1,68 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d MMM G y",
+	"field-dayperiod": "ช่วงวัน",
+	"field-minute": "นาที",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day-relative+-1": "เมื่อวาน",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"field-weekday": "วันในสัปดาห์",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-Gy": "G y",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"field-era": "สมัย",
+	"field-hour": "ชั่วโมง",
+	"dateFormatItem-y": "G y",
+	"dateFormatItem-yyyy": "G y",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "วันนี้",
+	"field-day-relative+1": "พรุ่งนี้",
+	"field-day-relative+2": "มะรืนนี้",
+	"dateFormatItem-GyMMMd": "d MMM G y",
+	"dateFormat-long": "d MMMM G y",
+	"field-zone": "เขต",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"dateFormat-medium": "d MMM G y",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "ปีนี้",
+	"field-year-relative+1": "ปีหน้า",
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ G y",
+	"field-year": "ปี",
+	"dateTimeFormat-long": "{1}, {0}",
+	"field-week": "สัปดาห์",
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"dateFormatItem-yyyyMMMd": "d MMM G y",
+	"dateFormatItem-yyyyMEd": "E d/M/y G",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"field-week-relative+1": "สัปดาห์หน้า",
+	"field-month-relative+0": "เดือนนี้",
+	"dateFormatItem-H": "HH",
+	"field-month": "เดือน",
+	"field-month-relative+1": "เดือนหน้า",
+	"dateFormatItem-M": "L",
+	"field-second": "วินาที",
+	"dateFormatItem-GyMMMEd": "E d MMM G y",
+	"dateFormatItem-GyMMM": "MMM G y",
+	"field-day": "วัน",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-yyyyQQQ": "QQQ G y",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "d/M/y G",
+	"dateFormatItem-yyyyM": "M/y G",
+	"dateFormat-full": "EEEEที่ d MMMM G y",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyMMM": "MMM G y",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/gregorian.js b/dojo/cldr/nls/th/gregorian.js
index f104297..7f8d451 100644
--- a/dojo/cldr/nls/th/gregorian.js
+++ b/dojo/cldr/nls/th/gregorian.js
@@ -1,13 +1,22 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
 	"months-format-narrow": [
 		"ม.ค.",
 		"ก.พ.",
 		"มี.ค.",
 		"เม.ย.",
 		"พ.ค.",
-		"มิ.ย.",
+		"มิ.ย",
 		"ก.ค.",
 		"ส.ค.",
 		"ก.ย.",
@@ -15,14 +24,30 @@ define(
 		"พ.ย.",
 		"ธ.ค."
 	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "วันในสัปดาห์",
 	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "EEE d/M/yyyy",
+	"dateFormatItem-yMEd": "E d/M/y",
+	"dateFormatItem-GyMMMEd": "E d MMM G y",
 	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
 		"ก่อน ค.ศ.",
 		"ค.ศ."
 	],
+	"days-format-short": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
 	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
 		"มกราคม",
@@ -39,12 +64,12 @@ define(
 		"ธันวาคม"
 	],
 	"dateTimeFormat-medium": "{1}, {0}",
-	"dateFormatItem-EEEd": "EEE d",
 	"dayPeriods-format-wide-pm": "หลังเที่ยง",
 	"dateFormat-full": "EEEEที่ d MMMM G y",
 	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMd": "d/M/y",
+	"dateFormatItem-yM": "M/y",
 	"field-era": "สมัย",
-	"dateFormatItem-yM": "M/yyyy",
 	"months-standAlone-wide": [
 		"มกราคม",
 		"กุมภาพันธ์",
@@ -59,18 +84,17 @@ define(
 		"พฤศจิกายน",
 		"ธันวาคม"
 	],
-	"timeFormat-short": "H:mm",
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
 		"ไตรมาส 1",
 		"ไตรมาส 2",
 		"ไตรมาส 3",
 		"ไตรมาส 4"
 	],
-	"timeFormat-long": "H นาฬิกา m นาที ss วินาที z",
-	"field-year": "ปี",
+	"dateFormatItem-yQQQQ": "QQQQ y",
+	"timeFormat-long": "H นาฬิกา mm นาที ss วินาที z",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "Q yyyy",
-	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"field-year": "ปี",
 	"field-hour": "ชั่วโมง",
 	"months-format-abbr": [
 		"ม.ค.",
@@ -86,13 +110,12 @@ define(
 		"พ.ย.",
 		"ธ.ค."
 	],
-	"dateFormatItem-yyQ": "Q yy",
-	"timeFormat-full": "H นาฬิกา m นาที ss วินาที zzzz",
+	"timeFormat-full": "H นาฬิกา mm นาที ss วินาที zzzz",
 	"field-day-relative+0": "วันนี้",
 	"field-day-relative+1": "พรุ่งนี้",
+	"dateFormatItem-GyMMMd": "d MMM G y",
 	"field-day-relative+2": "มะรืนนี้",
-	"dateFormatItem-H": "H",
-	"field-day-relative+3": "สามวันต่อจากนี้",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
 		"ม.ค.",
 		"ก.พ.",
@@ -108,10 +131,10 @@ define(
 		"ธ.ค."
 	],
 	"quarters-format-abbr": [
-		"Q1",
-		"Q2",
-		"Q3",
-		"Q4"
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
 	],
 	"quarters-standAlone-wide": [
 		"ไตรมาส 1",
@@ -119,6 +142,7 @@ define(
 		"ไตรมาส 3",
 		"ไตรมาส 4"
 	],
+	"dateFormatItem-Gy": "G y",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
 		"วันอาทิตย์",
@@ -130,8 +154,14 @@ define(
 		"วันเสาร์"
 	],
 	"dateFormatItem-MMMMd": "d MMMM",
-	"timeFormat-medium": "H:mm:ss",
-	"dateFormatItem-Hm": "H:mm",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
+	"quarters-standAlone-abbr": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
 	"eraAbbr": [
 		"ปีก่อน ค.ศ.",
 		"ค.ศ."
@@ -149,10 +179,17 @@ define(
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "เมื่อวาน",
+	"dateFormatItem-h": "h a",
 	"dateTimeFormat-long": "{1}, {0}",
+	"dayPeriods-format-narrow-am": "ก่อนเที่ยง",
 	"field-day-relative+-2": "เมื่อวานซืน",
-	"field-day-relative+-3": "สามวันก่อน",
 	"dateFormatItem-MMMd": "d MMM",
 	"dateFormatItem-MEd": "E, d/M",
 	"dateTimeFormat-full": "{1}, {0}",
@@ -183,6 +220,9 @@ define(
 		"พ.ย.",
 		"ธ.ค."
 	],
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
 		"อา.",
 		"จ.",
@@ -192,41 +232,52 @@ define(
 		"ศ.",
 		"ส."
 	],
+	"dateFormatItem-yMMMd": "d MMM y",
 	"eraNames": [
 		"ปีก่อนคริสต์ศักราช",
 		"คริสต์ศักราช"
 	],
 	"days-format-narrow": [
-		"อ",
-		"จ",
-		"อ",
-		"พ",
-		"พ",
-		"ศ",
-		"ส"
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
 	],
-	"field-month": "เดือน",
 	"days-standAlone-narrow": [
-		"อ",
-		"จ",
-		"อ",
-		"พ",
-		"พ",
-		"ศ",
-		"ส"
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "เดือน",
 	"dayPeriods-format-wide-am": "ก่อนเที่ยง",
 	"dateFormatItem-MMMMEd": "E d MMMM",
-	"dateFormat-short": "d/M/yyyy",
+	"dateFormat-short": "d/M/yy",
 	"field-second": "วินาที",
-	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"dateFormatItem-yMMMEd": "E d MMM y",
+	"field-month-relative+0": "เดือนนี้",
+	"field-month-relative+1": "เดือนหน้า",
+	"dateFormatItem-Ed": "E d",
 	"field-week": "สัปดาห์",
 	"dateFormat-medium": "d MMM y",
-	"dateFormatItem-yyyyM": "M/yyyy",
+	"field-year-relative+0": "ปีนี้",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"field-year-relative+1": "ปีหน้า",
 	"dateFormatItem-mmss": "mm:ss",
+	"dayPeriods-format-narrow-pm": "หลังเที่ยง",
 	"dateTimeFormat-short": "{1}, {0}",
-	"dateFormatItem-Hms": "H:mm:ss"
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-GyMMM": "MMM G y",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"field-week-relative+1": "สัปดาห์หน้า"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/hebrew.js b/dojo/cldr/nls/th/hebrew.js
new file mode 100644
index 0000000..67006d9
--- /dev/null
+++ b/dojo/cldr/nls/th/hebrew.js
@@ -0,0 +1,230 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"field-weekday": "วันในสัปดาห์",
+	"dateFormatItem-GyMMMEd": "E d MMM G y",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"eraNarrow": [
+		"ย.ศ."
+	],
+	"days-format-short": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dateFormat-long": "d MMMM G y",
+	"months-format-wide": [
+		"ทิชรี",
+		"เฮวาน",
+		"กีสเลฟ",
+		"เตเวต",
+		"เชวัต",
+		"อาดาร์ I",
+		"อาดาร์",
+		"นิสซาน",
+		"อิยาร์",
+		"สีวัน",
+		"ตามูซ",
+		"อัฟ",
+		"เอลอุล"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ G y",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dayPeriods-format-wide-pm": "หลังเที่ยง",
+	"dateFormat-full": "EEEEที่ d MMMM G y",
+	"dateFormatItem-yyyyMEd": "E d/M/y G",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "สมัย",
+	"months-standAlone-wide": [
+		"ทิชรี",
+		"เฮวาน",
+		"กีสเลฟ",
+		"เตเวต",
+		"เชวัต",
+		"อาดาร์ I",
+		"อาดาร์",
+		"นิสซาน",
+		"อิยาร์",
+		"สีวัน",
+		"ตามูซ",
+		"อัฟ",
+		"เอลอุล"
+	],
+	"quarters-format-wide": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"timeFormat-long": "H นาฬิกา mm นาที ss วินาที z",
+	"field-year": "ปี",
+	"field-hour": "ชั่วโมง",
+	"months-format-abbr-leap": "อาดาร์ II",
+	"months-format-abbr": [
+		"ทิชรี",
+		"เฮวาน",
+		"กีสเลฟ",
+		"เตเวต",
+		"เชวัต",
+		"อาดาร์ I",
+		"อาดาร์",
+		"นิสซาน",
+		"อิยาร์",
+		"สีวัน",
+		"ตามูซ",
+		"อัฟ",
+		"เอลอุล"
+	],
+	"timeFormat-full": "H นาฬิกา mm นาที ss วินาที zzzz",
+	"field-day-relative+0": "วันนี้",
+	"field-day-relative+1": "พรุ่งนี้",
+	"dateFormatItem-GyMMMd": "d MMM G y",
+	"field-day-relative+2": "มะรืนนี้",
+	"months-standAlone-abbr": [
+		"ทิชรี",
+		"เฮวาน",
+		"กีสเลฟ",
+		"เตเวต",
+		"เชวัต",
+		"อาดาร์ I",
+		"อาดาร์",
+		"นิสซาน",
+		"อิยาร์",
+		"สีวัน",
+		"ตามูซ",
+		"อัฟ",
+		"เอลอุล"
+	],
+	"quarters-format-abbr": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"quarters-standAlone-wide": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"dateFormatItem-yyyyMMMEd": "E d MMM G y",
+	"days-standAlone-wide": [
+		"วันอาทิตย์",
+		"วันจันทร์",
+		"วันอังคาร",
+		"วันพุธ",
+		"วันพฤหัสบดี",
+		"วันศุกร์",
+		"วันเสาร์"
+	],
+	"dateFormatItem-yyyyMMM": "MMM G y",
+	"dateFormatItem-yyyyMMMd": "d MMM G y",
+	"months-standAlone-wide-leap": "อาดาร์ II",
+	"quarters-standAlone-abbr": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"eraAbbr": [
+		"ย.ศ."
+	],
+	"field-minute": "นาที",
+	"field-dayperiod": "ช่วงวัน",
+	"days-standAlone-abbr": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"field-day-relative+-1": "เมื่อวาน",
+	"dateTimeFormat-long": "{1}, {0}",
+	"dayPeriods-format-narrow-am": "ก่อนเที่ยง",
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day": "วัน",
+	"days-format-wide": [
+		"วันอาทิตย์",
+		"วันจันทร์",
+		"วันอังคาร",
+		"วันพุธ",
+		"วันพฤหัสบดี",
+		"วันศุกร์",
+		"วันเสาร์"
+	],
+	"field-zone": "เขต",
+	"months-standAlone-abbr-leap": "อาดาร์ II",
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"days-format-abbr": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"eraNames": [
+		"ย.ศ."
+	],
+	"days-format-narrow": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"field-month": "เดือน",
+	"days-standAlone-narrow": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dayPeriods-format-wide-am": "ก่อนเที่ยง",
+	"dateFormat-short": "d/M/y G",
+	"field-second": "วินาที",
+	"field-month-relative+0": "เดือนนี้",
+	"field-month-relative+1": "เดือนหน้า",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "สัปดาห์",
+	"dateFormat-medium": "d MMM G y",
+	"field-year-relative+0": "ปีนี้",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"dateFormatItem-yyyyM": "M/y G",
+	"field-year-relative+1": "ปีหน้า",
+	"dayPeriods-format-narrow-pm": "หลังเที่ยง",
+	"dateFormatItem-yyyyQQQQ": "QQQQ G y",
+	"dateTimeFormat-short": "{1}, {0}",
+	"months-format-wide-leap": "อาดาร์ II",
+	"dateFormatItem-GyMMM": "MMM G y",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"field-week-relative+1": "สัปดาห์หน้า"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/indian.js b/dojo/cldr/nls/th/indian.js
new file mode 100644
index 0000000..e22510d
--- /dev/null
+++ b/dojo/cldr/nls/th/indian.js
@@ -0,0 +1,118 @@
+define(
+//begin v1.x content
+{
+	"field-second": "วินาที",
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"field-week": "สัปดาห์",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"field-day-relative+-1": "เมื่อวาน",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"months-standAlone-wide": [
+		"จิตรา",
+		"วิสาขา",
+		"เชษฐา",
+		"อัษฎา",
+		"ศรวณา",
+		"พัตรา",
+		"อัศวิชา",
+		"การติกา",
+		"มฤคศิรา",
+		"ปุษยา",
+		"มาฆะ",
+		"ผลคุณี"
+	],
+	"field-year": "ปี",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"months-standAlone-abbr": [
+		"จิตรา",
+		"วิสาขา",
+		"เชษฐา",
+		"อัษฎา",
+		"ศรวณา",
+		"พัตรา",
+		"อัศวิชา",
+		"การติกา",
+		"มฤคศิรา",
+		"ปุษยา",
+		"มาฆะ",
+		"ผลคุณี"
+	],
+	"field-week-relative+1": "สัปดาห์หน้า",
+	"field-minute": "นาที",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"field-day-relative+0": "วันนี้",
+	"field-hour": "ชั่วโมง",
+	"field-day-relative+1": "พรุ่งนี้",
+	"field-day-relative+2": "มะรืนนี้",
+	"field-day": "วัน",
+	"field-month-relative+0": "เดือนนี้",
+	"field-month-relative+1": "เดือนหน้า",
+	"field-dayperiod": "ช่วงวัน",
+	"field-month": "เดือน",
+	"months-format-wide": [
+		"จิตรา",
+		"วิสาขา",
+		"เชษฐา",
+		"อัษฎา",
+		"ศรวณา",
+		"พัตรา",
+		"อัศวิชา",
+		"การติกา",
+		"มฤคศิรา",
+		"ปุษยา",
+		"มาฆะ",
+		"ผลคุณี"
+	],
+	"field-era": "สมัย",
+	"field-year-relative+0": "ปีนี้",
+	"field-year-relative+1": "ปีหน้า",
+	"months-format-abbr": [
+		"จิตรา",
+		"วิสาขา",
+		"เชษฐา",
+		"อัษฎา",
+		"ศรวณา",
+		"พัตรา",
+		"อัศวิชา",
+		"การติกา",
+		"มฤคศิรา",
+		"ปุษยา",
+		"มาฆะ",
+		"ผลคุณี"
+	],
+	"eraAbbr": [
+		"ม.ศ."
+	],
+	"field-weekday": "วันในสัปดาห์",
+	"field-zone": "เขต"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/islamic.js b/dojo/cldr/nls/th/islamic.js
new file mode 100644
index 0000000..ac9d49c
--- /dev/null
+++ b/dojo/cldr/nls/th/islamic.js
@@ -0,0 +1,250 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "วันในสัปดาห์",
+	"dateFormatItem-GyMMMEd": "E d MMM G y",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"eraNarrow": [
+		"ฮ.ศ."
+	],
+	"days-format-short": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dateFormat-long": "d MMMM G y",
+	"months-format-wide": [
+		"มุฮะร์รอม",
+		"ซอฟาร์",
+		"รอบี I",
+		"รอบี II",
+		"จุมาดา I",
+		"จุมาดา II",
+		"รอจับ",
+		"ชะอะบาน",
+		"รอมะดอน",
+		"เชาวัล",
+		"ดฮุุอัลกิดะห์",
+		"ดฮุอัลฮิจจะห์"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ G y",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dayPeriods-format-wide-pm": "หลังเที่ยง",
+	"dateFormat-full": "EEEEที่ d MMMM G y",
+	"dateFormatItem-yyyyMEd": "E d/M/y G",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "สมัย",
+	"months-standAlone-wide": [
+		"มุฮะร์รอม",
+		"ซอฟาร์",
+		"รอบี I",
+		"รอบี II",
+		"จุมาดา I",
+		"จุมาดา II",
+		"รอจับ",
+		"ชะอะบาน",
+		"รอมะดอน",
+		"เชาวัล",
+		"ดฮุุอัลกิดะห์",
+		"ดฮุอัลฮิจจะห์"
+	],
+	"quarters-format-wide": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"timeFormat-long": "H นาฬิกา mm นาที ss วินาที z",
+	"field-year": "ปี",
+	"field-hour": "ชั่วโมง",
+	"months-format-abbr": [
+		"มุฮัร.",
+		"เศาะ.",
+		"รอบี 1",
+		"รอบี 2",
+		"ญุมา 1",
+		"ญุมา 2",
+		"เราะ.",
+		"ชะอ์.",
+		"เราะมะ.",
+		"เชาว.",
+		"ซุลกิอฺ.",
+		"ซุลหิจ."
+	],
+	"timeFormat-full": "H นาฬิกา mm นาที ss วินาที zzzz",
+	"field-day-relative+0": "วันนี้",
+	"field-day-relative+1": "พรุ่งนี้",
+	"dateFormatItem-GyMMMd": "d MMM G y",
+	"field-day-relative+2": "มะรืนนี้",
+	"months-standAlone-abbr": [
+		"มุฮัร.",
+		"เศาะ.",
+		"รอบี 1",
+		"รอบี 2",
+		"ญุมา 1",
+		"ญุมา 2",
+		"เราะ.",
+		"ชะอ์.",
+		"เราะมะ.",
+		"เชาว.",
+		"ซุลกิอฺ.",
+		"ซุลหิจ."
+	],
+	"quarters-format-abbr": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"quarters-standAlone-wide": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"dateFormatItem-yyyyMMMEd": "E d MMM G y",
+	"days-standAlone-wide": [
+		"วันอาทิตย์",
+		"วันจันทร์",
+		"วันอังคาร",
+		"วันพุธ",
+		"วันพฤหัสบดี",
+		"วันศุกร์",
+		"วันเสาร์"
+	],
+	"dateFormatItem-yyyyMMM": "MMM G y",
+	"dateFormatItem-yyyyMMMd": "d MMM G y",
+	"quarters-standAlone-abbr": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"eraAbbr": [
+		"ฮ.ศ."
+	],
+	"field-minute": "นาที",
+	"field-dayperiod": "ช่วงวัน",
+	"days-standAlone-abbr": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"field-day-relative+-1": "เมื่อวาน",
+	"dateTimeFormat-long": "{1}, {0}",
+	"dayPeriods-format-narrow-am": "ก่อนเที่ยง",
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day": "วัน",
+	"days-format-wide": [
+		"วันอาทิตย์",
+		"วันจันทร์",
+		"วันอังคาร",
+		"วันพุธ",
+		"วันพฤหัสบดี",
+		"วันศุกร์",
+		"วันเสาร์"
+	],
+	"field-zone": "เขต",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"days-format-abbr": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"eraNames": [
+		"ฮิจเราะห์ศักราช"
+	],
+	"days-format-narrow": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"field-month": "เดือน",
+	"days-standAlone-narrow": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dayPeriods-format-wide-am": "ก่อนเที่ยง",
+	"dateFormat-short": "d/M/y G",
+	"field-second": "วินาที",
+	"field-month-relative+0": "เดือนนี้",
+	"field-month-relative+1": "เดือนหน้า",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "สัปดาห์",
+	"dateFormat-medium": "d MMM G y",
+	"field-year-relative+0": "ปีนี้",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"dateFormatItem-yyyyM": "M/y G",
+	"field-year-relative+1": "ปีหน้า",
+	"dayPeriods-format-narrow-pm": "หลังเที่ยง",
+	"dateFormatItem-yyyyQQQQ": "QQQQ G y",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-GyMMM": "MMM G y",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"field-week-relative+1": "สัปดาห์หน้า"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/japanese.js b/dojo/cldr/nls/th/japanese.js
new file mode 100644
index 0000000..024dfca
--- /dev/null
+++ b/dojo/cldr/nls/th/japanese.js
@@ -0,0 +1,306 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d MMM G y",
+	"field-dayperiod": "ช่วงวัน",
+	"field-minute": "นาที",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "เมื่อวาน",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"field-weekday": "วันในสัปดาห์",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "G y",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "สมัย",
+	"field-hour": "ชั่วโมง",
+	"dateFormatItem-y": "G y",
+	"dateFormatItem-yyyy": "G y",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "วันนี้",
+	"field-day-relative+1": "พรุ่งนี้",
+	"eraAbbr": [
+		"ทะอิกะ (645-650)",
+		"ฮะกุชิ (650-671)",
+		"ฮากุโฮ (672-686)",
+		"ชุโช (686-701)",
+		"ทะอิโฮ (701-704)",
+		"เคอุง (704-708)",
+		"วะโด (708-715)",
+		"เรกิ (715-717)",
+		"โยโร (717-724)",
+		"จิงกิ (724-729)",
+		"เท็มเพียว (729-749)",
+		"เท็มเพียว-คัมโป (749-749)",
+		"เท็มเพียว-โชโฮ (749-757)",
+		"เท็มเพียว-โฮจิ (757-765)",
+		"เท็มเพียว-จิงโงะ (765-767)",
+		"จิงโงะ-เคอุง (767-770)",
+		"โฮกิ (770-780)",
+		"เท็นโอ (781-782)",
+		"เอ็นเรียะกุ (782-806)",
+		"ดะอิโด (806-810)",
+		"โคนิง (810-824)",
+		"เท็นโช (824-834)",
+		"โชวะ (834-848)",
+		"คะโจ (848-851)",
+		"นินจุ (851-854)",
+		"ซะอิโกะ (854-857)",
+		"เท็นนัง (857-859)",
+		"โจงัง (859-877)",
+		"เก็งเก (877-885)",
+		"นินนะ (885-889)",
+		"คัมเพียว (889-898)",
+		"โชตะอิ (898-901)",
+		"เอ็งงิ (901-923)",
+		"เอ็นโช (923-931)",
+		"โชเฮ (931-938)",
+		"เท็งเงียว (938-947)",
+		"เท็นเรียะกุ (947-957)",
+		"เท็นโตะกุ (957-961)",
+		"โอวะ (961-964)",
+		"โคโฮ (964-968)",
+		"อันนะ (968-970)",
+		"เท็นโระกุ (970-973)",
+		"เท็นเอ็ง (973-976)",
+		"โจเง็ง (976-978)",
+		"เท็งเง็ง (978-983)",
+		"เอกัง (983-985)",
+		"คันนะ (985-987)",
+		"เอเอ็ง (987-989)",
+		"เอโซ (989-990)",
+		"โชเรียะกุ (990-995)",
+		"โชโตะกุ (995-999)",
+		"โชโฮ (999-1004)",
+		"คันโก (1004-1012)",
+		"โชวะ (1012-1017)",
+		"คันนิง (1017-1021)",
+		"จิอัง (1021-1024)",
+		"มันจุ (1024-1028)",
+		"โชเง็ง (1028-1037)",
+		"โชเรียะกุ (1037-1040)",
+		"โชคีว (1040-1044)",
+		"คันโตะกุ (1044-1046)",
+		"เอโช (1046-1053)",
+		"เท็งงิ (1053-1058)",
+		"โคเฮ (1058-1065)",
+		"จิเรียะกุ (1065-1069)",
+		"เอ็งคีว (1069-1074)",
+		"โชโฮ (1074-1077)",
+		"โชเรียะกุ (1077-1081)",
+		"เอโฮะ (1081-1084)",
+		"โอโตะกุ (1084-1087)",
+		"คันจิ (1087-1094)",
+		"คะโฮะ (1094-1096)",
+		"เอโช (1096-1097)",
+		"โชโตะกุ (1097-1099)",
+		"โควะ (1099-1104)",
+		"โชจิ (1104-1106)",
+		"คะโช (1106-1108)",
+		"เท็นนิง (1108-1110)",
+		"เท็นเอ (1110-1113)",
+		"เอกีว (1113-1118)",
+		"เก็นเอ (1118-1120)",
+		"โฮะอัง (1120-1124)",
+		"เท็นจิ (1124-1126)",
+		"ดะอิจิ (1126-1131)",
+		"เท็นโช (1131-1132)",
+		"โชโช (1132-1135)",
+		"โฮะเอ็ง (1135-1141)",
+		"เอจิ (1141-1142)",
+		"โคจิ (1142-1144)",
+		"เท็นโย (1144-1145)",
+		"คีวอัง (1145-1151)",
+		"นิมเป (1151-1154)",
+		"คีวจุ (1154-1156)",
+		"โฮะเง็ง (1156-1159)",
+		"เฮจิ (1159-1160)",
+		"เอเรียะกุ (1160-1161)",
+		"โอโฮ (1161-1163)",
+		"โชกัง (1163-1165)",
+		"เอมัง (1165-1166)",
+		"นินอัง (1166-1169)",
+		"คะโอ (1169-1171)",
+		"โชอัง (1171-1175)",
+		"อังเง็ง (1175-1177)",
+		"จิโช (1177-1181)",
+		"โยวะ (1181-1182)",
+		"จุเอ (1182-1184)",
+		"เก็นเรียะกุ (1184-1185)",
+		"บุนจิ (1185-1190)",
+		"เค็งกีว (1190-1199)",
+		"โชจิ (1199-1201)",
+		"เค็นนิง (1201-1204)",
+		"เก็งกีว (1204-1206)",
+		"เค็นเอ (1206-1207)",
+		"โชเก็ง (1207-1211)",
+		"เค็นเรียะกุ (1211-1213)",
+		"เค็มโป (1213-1219)",
+		"โชกีว (1219-1222)",
+		"โจโอ (1222-1224)",
+		"เก็นนิง (1224-1225)",
+		"คะโระกุ (1225-1227)",
+		"อันเต (1227-1229)",
+		"คังกิ (1229-1232)",
+		"โจเอ (1232-1233)",
+		"เท็มปุกุ (1233-1234)",
+		"บุนเรียะกุ (1234-1235)",
+		"คะเต (1235-1238)",
+		"เรียะกุนิง (1238-1239)",
+		"เอ็นโอ (1239-1240)",
+		"นินจิ (1240-1243)",
+		"คังเง็ง (1243-1247)",
+		"โฮจิ (1247-1249)",
+		"เค็นโช (1249-1256)",
+		"โคเง็ง (1256-1257)",
+		"โชกะ (1257-1259)",
+		"โชเง็ง (1259-1260)",
+		"บุนโอ (1260-1261)",
+		"โคโช (1261-1264)",
+		"บุนเอ (1264-1275)",
+		"เค็นจิ (1275-1278)",
+		"โคอัง (1278-1288)",
+		"โชโอ (1288-1293)",
+		"เอนิง (1293-1299)",
+		"โชอัง (1299-1302)",
+		"เค็งเง็ง (1302-1303)",
+		"คะเง็ง (1303-1306)",
+		"โทะกุจิ (1306-1308)",
+		"เอ็งเก (1308-1311)",
+		"โอโช (1311-1312)",
+		"โชวะ (1312-1317)",
+		"บุมโป (1317-1319)",
+		"เก็นโอ (1319-1321)",
+		"เก็งเกียว (1321-1324)",
+		"โชชู (1324-1326)",
+		"คะเระกิ (1326-1329)",
+		"เก็นโตะกุ (1329-1331)",
+		"เก็งโก (1331-1334)",
+		"เค็มมุ (1334-1336)",
+		"เอ็งเง็ง (1336-1340)",
+		"โคโกะกุ (1340-1346)",
+		"โชเฮ (1346-1370)",
+		"เค็นโตะกุ (1370-1372)",
+		"บุนชู (1372-1375)",
+		"เท็นจุ (1375-1379)",
+		"โคเรียะกุ (1379-1381)",
+		"โควะ (1381-1384)",
+		"เก็นชู (1384-1392)",
+		"เมโตะกุ (1384-1387)",
+		"คะเค (1387-1389)",
+		"โคโอ (1389-1390)",
+		"เมโตะกุ (1390-1394)",
+		"โอเอ (1394-1428)",
+		"โชโช (1428-1429)",
+		"เอเกียว (1429-1441)",
+		"คะกิสึ (1441-1444)",
+		"บุนอัง (1444-1449)",
+		"โฮโตะกุ (1449-1452)",
+		"เคียวโตะกุ (1452-1455)",
+		"โคโช (1455-1457)",
+		"โชโระกุ (1457-1460)",
+		"คันโช (1460-1466)",
+		"บุนโช (1466-1467)",
+		"โอนิง (1467-1469)",
+		"บุมเม (1469-1487)",
+		"โชเกียว (1487-1489)",
+		"เอ็นโตะกุ (1489-1492)",
+		"เมโอ (1492-1501)",
+		"บุงกิ (1501-1504)",
+		"เอโช (1504-1521)",
+		"ทะอิเอ (1521-1528)",
+		"เคียวโระกุ (1528-1532)",
+		"เท็มมน (1532-1555)",
+		"โคจิ (1555-1558)",
+		"เอโระกุ (1558-1570)",
+		"เก็งกิ (1570-1573)",
+		"เท็นโช (1573-1592)",
+		"บุนโระกุ (1592-1596)",
+		"เคโช (1596-1615)",
+		"เก็งวะ (1615-1624)",
+		"คันเอ (1624-1644)",
+		"โชโฮ (1644-1648)",
+		"เคอัง (1648-1652)",
+		"โชโอ (1652-1655)",
+		"เมเรียะกุ (1655-1658)",
+		"มันจิ (1658-1661)",
+		"คัมบุง (1661-1673)",
+		"เอ็มโป (1673-1681)",
+		"เท็นวะ (1681-1684)",
+		"โจเกียว (1684-1688)",
+		"เก็นโระกุ (1688-1704)",
+		"โฮเอ (1704-1711)",
+		"โชโตะกุ (1711-1716)",
+		"เคียวโฮ (1716-1736)",
+		"เก็มบุง (1736-1741)",
+		"คัมโป (1741-1744)",
+		"เอ็งเกียว (1744-1748)",
+		"คันเอ็ง (1748-1751)",
+		"โฮเรียะกุ (1751-1764)",
+		"เมวะ (1764-1772)",
+		"อันเอ (1772-1781)",
+		"เท็มเม (1781-1789)",
+		"คันเซ (1789-1801)",
+		"เคียววะ (1801-1804)",
+		"บุงกะ (1804-1818)",
+		"บุนเซ (1818-1830)",
+		"เท็มโป (1830-1844)",
+		"โคกะ (1844-1848)",
+		"คะเอ (1848-1854)",
+		"อันเซ (1854-1860)",
+		"มันเอ็ง (1860-1861)",
+		"บุงกีว (1861-1864)",
+		"เก็นจิ (1864-1865)",
+		"เคโอ (1865-1868)",
+		"เมจิ",
+		"ทะอิโช",
+		"โชวะ",
+		"เฮเซ"
+	],
+	"field-day-relative+2": "มะรืนนี้",
+	"dateFormatItem-GyMMMd": "d MMM G y",
+	"dateFormat-long": "d MMMM ปีG y",
+	"field-zone": "เขต",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"dateFormat-medium": "d MMM G y",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "ปีนี้",
+	"field-year-relative+1": "ปีหน้า",
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ G y",
+	"field-year": "ปี",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "สัปดาห์",
+	"dateFormatItem-yyyyMd": "d/M/GGGGG y",
+	"dateFormatItem-yyyyMMMd": "d MMM G y",
+	"dateFormatItem-yyyyMEd": "E d/M/GGGGG y",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"field-week-relative+1": "สัปดาห์หน้า",
+	"field-month-relative+0": "เดือนนี้",
+	"dateFormatItem-H": "HH",
+	"field-month": "เดือน",
+	"field-month-relative+1": "เดือนหน้า",
+	"dateFormatItem-M": "L",
+	"field-second": "วินาที",
+	"dateFormatItem-GyMMMEd": "E d MMM G y",
+	"dateFormatItem-GyMMM": "MMM G y",
+	"field-day": "วัน",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-yyyyQQQ": "QQQ G y",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "d/M/yy G",
+	"dateFormatItem-yyyyM": "M/GGGGG y",
+	"dateFormat-full": "EEEEที่ d MMMM ปีGที่ y",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyMMM": "MMM G y",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/number.js b/dojo/cldr/nls/th/number.js
index ba17d2c..9b35025 100644
--- a/dojo/cldr/nls/th/number.js
+++ b/dojo/cldr/nls/th/number.js
@@ -8,15 +8,15 @@ define(
 	"percentFormat": "#,##0%",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ".",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
-	"currencyFormat": "¤#,##0.00;¤-#,##0.00",
-	"plusSign": "+"
+	"currencyFormat": "¤#,##0.00;(¤#,##0.00)",
+	"plusSign": "+",
+	"decimalFormat-long": "000 ล้านล้าน",
+	"decimalFormat-short": "000 ล'.'ล'.'"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/persian.js b/dojo/cldr/nls/th/persian.js
new file mode 100644
index 0000000..b34de39
--- /dev/null
+++ b/dojo/cldr/nls/th/persian.js
@@ -0,0 +1,250 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "วันในสัปดาห์",
+	"dateFormatItem-GyMMMEd": "E d MMM G y",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"eraNarrow": [
+		"ปีเปอร์เซีย"
+	],
+	"days-format-short": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dateFormat-long": "d MMMM G y",
+	"months-format-wide": [
+		"ฟาร์วาร์ดิน",
+		"ออร์ดิเบเฮชต์",
+		"คอร์แดด",
+		"เตอร์",
+		"มอร์แดด",
+		"ชาหริวาร์",
+		"เมฮร์",
+		"อะบาน",
+		"อะซาร์",
+		"เดย์",
+		"บาฮ์มาน",
+		"เอสฟานด์"
+	],
+	"dateFormatItem-yyyyQQQ": "QQQ G y",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dayPeriods-format-wide-pm": "หลังเที่ยง",
+	"dateFormat-full": "EEEEที่ d MMMM G y",
+	"dateFormatItem-yyyyMEd": "E d/M/y G",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "สมัย",
+	"months-standAlone-wide": [
+		"ฟาร์วาร์ดิน",
+		"ออร์ดิเบเฮชต์",
+		"คอร์แดด",
+		"เตอร์",
+		"มอร์แดด",
+		"ชาหริวาร์",
+		"เมฮร์",
+		"อะบาน",
+		"อะซาร์",
+		"เดย์",
+		"บาฮ์มาน",
+		"เอสฟานด์"
+	],
+	"quarters-format-wide": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"timeFormat-long": "H นาฬิกา mm นาที ss วินาที z",
+	"field-year": "ปี",
+	"field-hour": "ชั่วโมง",
+	"months-format-abbr": [
+		"ฟาร์วาร์ดิน",
+		"ออร์ดิเบเฮชต์",
+		"คอร์แดด",
+		"เตอร์",
+		"มอร์แดด",
+		"ชาหริวาร์",
+		"เมฮร์",
+		"อะบาน",
+		"อะซาร์",
+		"เดย์",
+		"บาฮ์มาน",
+		"เอสฟานด์"
+	],
+	"timeFormat-full": "H นาฬิกา mm นาที ss วินาที zzzz",
+	"field-day-relative+0": "วันนี้",
+	"field-day-relative+1": "พรุ่งนี้",
+	"dateFormatItem-GyMMMd": "d MMM G y",
+	"field-day-relative+2": "มะรืนนี้",
+	"months-standAlone-abbr": [
+		"ฟาร์วาร์ดิน",
+		"ออร์ดิเบเฮชต์",
+		"คอร์แดด",
+		"เตอร์",
+		"มอร์แดด",
+		"ชาหริวาร์",
+		"เมฮร์",
+		"อะบาน",
+		"อะซาร์",
+		"เดย์",
+		"บาฮ์มาน",
+		"เอสฟานด์"
+	],
+	"quarters-format-abbr": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"quarters-standAlone-wide": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"dateFormatItem-yyyyMMMEd": "E d MMM G y",
+	"days-standAlone-wide": [
+		"วันอาทิตย์",
+		"วันจันทร์",
+		"วันอังคาร",
+		"วันพุธ",
+		"วันพฤหัสบดี",
+		"วันศุกร์",
+		"วันเสาร์"
+	],
+	"dateFormatItem-yyyyMMM": "MMM G y",
+	"dateFormatItem-yyyyMMMd": "d MMM G y",
+	"quarters-standAlone-abbr": [
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
+		"ไตรมาส 4"
+	],
+	"eraAbbr": [
+		"ปีเปอร์เซีย"
+	],
+	"field-minute": "นาที",
+	"field-dayperiod": "ช่วงวัน",
+	"days-standAlone-abbr": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"field-day-relative+-1": "เมื่อวาน",
+	"dateTimeFormat-long": "{1}, {0}",
+	"dayPeriods-format-narrow-am": "ก่อนเที่ยง",
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateTimeFormat-full": "{1}, {0}",
+	"field-day": "วัน",
+	"days-format-wide": [
+		"วันอาทิตย์",
+		"วันจันทร์",
+		"วันอังคาร",
+		"วันพุธ",
+		"วันพฤหัสบดี",
+		"วันศุกร์",
+		"วันเสาร์"
+	],
+	"field-zone": "เขต",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"days-format-abbr": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"eraNames": [
+		"ปีเปอร์เซีย"
+	],
+	"days-format-narrow": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"field-month": "เดือน",
+	"days-standAlone-narrow": [
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
+		"ส."
+	],
+	"dayPeriods-format-wide-am": "ก่อนเที่ยง",
+	"dateFormat-short": "d/M/y G",
+	"field-second": "วินาที",
+	"field-month-relative+0": "เดือนนี้",
+	"field-month-relative+1": "เดือนหน้า",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "สัปดาห์",
+	"dateFormat-medium": "d MMM G y",
+	"field-year-relative+0": "ปีนี้",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"dateFormatItem-yyyyM": "M/y G",
+	"field-year-relative+1": "ปีหน้า",
+	"dayPeriods-format-narrow-pm": "หลังเที่ยง",
+	"dateFormatItem-yyyyQQQQ": "QQQQ G y",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-GyMMM": "MMM G y",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"field-week-relative+1": "สัปดาห์หน้า"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/roc.js b/dojo/cldr/nls/th/roc.js
new file mode 100644
index 0000000..13895d7
--- /dev/null
+++ b/dojo/cldr/nls/th/roc.js
@@ -0,0 +1,67 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "E d MMM G y",
+	"field-dayperiod": "ช่วงวัน",
+	"field-minute": "นาที",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "เมื่อวาน",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"field-weekday": "วันในสัปดาห์",
+	"dateFormatItem-MMM": "LLL",
+	"field-era": "สมัย",
+	"dateFormatItem-Gy": "ปีGที่ y",
+	"field-hour": "ชั่วโมง",
+	"dateFormatItem-y": "ปีGที่ y",
+	"dateFormatItem-yyyy": "ปีGที่ y",
+	"dateFormatItem-Ed": "E d",
+	"field-day-relative+0": "วันนี้",
+	"field-day-relative+1": "พรุ่งนี้",
+	"eraAbbr": [
+		"ปีก่อนไต้หวัน",
+		"ไต้หวัน"
+	],
+	"field-day-relative+2": "มะรืนนี้",
+	"dateFormatItem-GyMMMd": "d MMM G y",
+	"dateFormat-long": "d MMMM ปีG y",
+	"field-zone": "เขต",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "สัปดาห์ที่แล้ว",
+	"dateFormat-medium": "d MMM G y",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "ปีนี้",
+	"field-year-relative+1": "ปีหน้า",
+	"field-year-relative+-1": "ปีที่แล้ว",
+	"dateFormatItem-ms": "mm:ss",
+	"field-year": "ปี",
+	"field-week": "สัปดาห์",
+	"dateFormatItem-yyyyMd": "d/M/GGGGG y",
+	"dateFormatItem-yyyyMMMd": "d MMM G y",
+	"dateFormatItem-yyyyMEd": "E d/M/GGGGG y",
+	"dateFormatItem-MMMd": "d MMM",
+	"field-week-relative+0": "สัปดาห์นี้",
+	"field-week-relative+1": "สัปดาห์หน้า",
+	"field-month-relative+0": "เดือนนี้",
+	"dateFormatItem-H": "HH",
+	"field-month": "เดือน",
+	"field-month-relative+1": "เดือนหน้า",
+	"dateFormatItem-M": "L",
+	"field-second": "วินาที",
+	"dateFormatItem-GyMMMEd": "E d MMM G y",
+	"dateFormatItem-GyMMM": "MMM G y",
+	"field-day": "วัน",
+	"dateFormatItem-yyyyQQQ": "QQQ G y",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "d/M/yy",
+	"dateFormatItem-yyyyM": "M/GGGGG y",
+	"dateFormat-full": "EEEEที่ d MMMM ปีGที่ y",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyMMM": "MMM G y",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "เดือนที่แล้ว",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/buddhist.js b/dojo/cldr/nls/tr/buddhist.js
new file mode 100644
index 0000000..36c6033
--- /dev/null
+++ b/dojo/cldr/nls/tr/buddhist.js
@@ -0,0 +1,251 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "ÖÖ/ÖS",
+	"dateFormatItem-yyyyMMMEd": "d MMM y G E",
+	"dayPeriods-format-wide-pm": "ÖS",
+	"field-minute": "Dakika",
+	"dateFormatItem-MMMEd": "d MMMM E",
+	"field-day-relative+-1": "Dün",
+	"field-weekday": "Haftanın Günü",
+	"field-day-relative+-2": "Evvelsi gün",
+	"days-standAlone-wide": [
+		"Pazar",
+		"Pazartesi",
+		"Salı",
+		"Çarşamba",
+		"Perşembe",
+		"Cuma",
+		"Cumartesi"
+	],
+	"months-standAlone-narrow": [
+		"O",
+		"Ş",
+		"M",
+		"N",
+		"M",
+		"H",
+		"T",
+		"A",
+		"E",
+		"E",
+		"K",
+		"A"
+	],
+	"field-era": "Miladi Dönem",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Saat",
+	"dayPeriods-format-wide-am": "ÖÖ",
+	"quarters-standAlone-abbr": [
+		"Ç1",
+		"Ç2",
+		"Ç3",
+		"Ç4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Oca",
+		"Şub",
+		"Mar",
+		"Nis",
+		"May",
+		"Haz",
+		"Tem",
+		"Ağu",
+		"Eyl",
+		"Eki",
+		"Kas",
+		"Ara"
+	],
+	"dateFormatItem-Ed": "d E",
+	"field-day-relative+0": "Bugün",
+	"field-day-relative+1": "Yarın",
+	"days-standAlone-narrow": [
+		"P",
+		"P",
+		"S",
+		"Ç",
+		"P",
+		"C",
+		"C"
+	],
+	"eraAbbr": [
+		"BE"
+	],
+	"field-day-relative+2": "Öbür gün",
+	"dateFormatItem-GyMMMd": "dd MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Saat Dilimi",
+	"field-week-relative+-1": "Geçen hafta",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Bu yıl",
+	"field-year-relative+1": "Gelecek yıl",
+	"quarters-standAlone-wide": [
+		"1. çeyrek",
+		"2. çeyrek",
+		"3. çeyrek",
+		"4. çeyrek"
+	],
+	"field-year-relative+-1": "Geçen yıl",
+	"field-year": "Yıl",
+	"dateFormatItem-yyyyQQQQ": "G y/QQQQ",
+	"quarters-standAlone-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"field-week": "Hafta",
+	"months-standAlone-wide": [
+		"Ocak",
+		"Şubat",
+		"Mart",
+		"Nisan",
+		"Mayıs",
+		"Haziran",
+		"Temmuz",
+		"Ağustos",
+		"Eylül",
+		"Ekim",
+		"Kasım",
+		"Aralık"
+	],
+	"dateFormatItem-yyyyMMMd": "dd MMM y G",
+	"dateFormatItem-yyyyMd": "dd.MM.y G",
+	"dateFormatItem-yyyyMEd": "dd.MM.y G E",
+	"field-week-relative+0": "Bu hafta",
+	"dateFormatItem-MMMd": "d MMMM",
+	"quarters-format-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"field-week-relative+1": "Gelecek hafta",
+	"months-format-abbr": [
+		"Oca",
+		"Şub",
+		"Mar",
+		"Nis",
+		"May",
+		"Haz",
+		"Tem",
+		"Ağu",
+		"Eyl",
+		"Eki",
+		"Kas",
+		"Ara"
+	],
+	"field-month-relative+0": "Bu ay",
+	"field-month": "Ay",
+	"field-month-relative+1": "Gelecek ay",
+	"quarters-format-abbr": [
+		"Ç1",
+		"Ç2",
+		"Ç3",
+		"Ç4"
+	],
+	"days-format-abbr": [
+		"Paz",
+		"Pzt",
+		"Sal",
+		"Çar",
+		"Per",
+		"Cum",
+		"Cmt"
+	],
+	"days-format-narrow": [
+		"P",
+		"P",
+		"S",
+		"Ç",
+		"P",
+		"C",
+		"C"
+	],
+	"field-second": "Saniye",
+	"dateFormatItem-GyMMMEd": "d MMM y G E",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Gün",
+	"dateFormatItem-yyyyQQQ": "G y/QQQ",
+	"dateFormatItem-MEd": "dd.MM E",
+	"months-format-narrow": [
+		"O",
+		"Ş",
+		"M",
+		"N",
+		"M",
+		"H",
+		"T",
+		"A",
+		"E",
+		"E",
+		"K",
+		"A"
+	],
+	"days-standAlone-short": [
+		"Pa",
+		"Pt",
+		"Sa",
+		"Ça",
+		"Pe",
+		"Cu",
+		"Ct"
+	],
+	"days-standAlone-abbr": [
+		"Paz",
+		"Pzt",
+		"Sal",
+		"Çar",
+		"Per",
+		"Cum",
+		"Cmt"
+	],
+	"dateFormat-short": "d.MM.y G",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"dateFormat-full": "d MMMM y G EEEE",
+	"dateFormatItem-Md": "dd.MM",
+	"months-format-wide": [
+		"Ocak",
+		"Şubat",
+		"Mart",
+		"Nisan",
+		"Mayıs",
+		"Haziran",
+		"Temmuz",
+		"Ağustos",
+		"Eylül",
+		"Ekim",
+		"Kasım",
+		"Aralık"
+	],
+	"days-format-short": [
+		"Pa",
+		"Pt",
+		"Sa",
+		"Ça",
+		"Pe",
+		"Cu",
+		"Ct"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "Geçen ay",
+	"quarters-format-wide": [
+		"1. çeyrek",
+		"2. çeyrek",
+		"3. çeyrek",
+		"4. çeyrek"
+	],
+	"days-format-wide": [
+		"Pazar",
+		"Pazartesi",
+		"Salı",
+		"Çarşamba",
+		"Perşembe",
+		"Cuma",
+		"Cumartesi"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/coptic.js b/dojo/cldr/nls/tr/coptic.js
new file mode 100644
index 0000000..6dd2e82
--- /dev/null
+++ b/dojo/cldr/nls/tr/coptic.js
@@ -0,0 +1,46 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Saniye",
+	"field-year-relative+-1": "Geçen yıl",
+	"field-week": "Hafta",
+	"field-month-relative+-1": "Geçen ay",
+	"field-day-relative+-1": "Dün",
+	"field-day-relative+-2": "Evvelsi gün",
+	"field-year": "Yıl",
+	"field-week-relative+0": "Bu hafta",
+	"field-week-relative+1": "Gelecek hafta",
+	"field-minute": "Dakika",
+	"field-week-relative+-1": "Geçen hafta",
+	"field-day-relative+0": "Bugün",
+	"field-hour": "Saat",
+	"field-day-relative+1": "Yarın",
+	"field-day-relative+2": "Öbür gün",
+	"field-day": "Gün",
+	"field-month-relative+0": "Bu ay",
+	"field-month-relative+1": "Gelecek ay",
+	"field-dayperiod": "ÖÖ/ÖS",
+	"field-month": "Ay",
+	"months-format-wide": [
+		"Tût",
+		"Bâbe",
+		"Hatur",
+		"Keyhek",
+		"Tûbe",
+		"Imşir",
+		"Bermuhat",
+		"Bermude",
+		"Peyştes",
+		"Bune",
+		"Ebip",
+		"Mısrî",
+		"Nesî"
+	],
+	"field-era": "Miladi Dönem",
+	"field-year-relative+0": "Bu yıl",
+	"field-year-relative+1": "Gelecek yıl",
+	"field-weekday": "Haftanın Günü",
+	"field-zone": "Saat Dilimi"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/currency.js b/dojo/cldr/nls/tr/currency.js
index 786cbe0..9349997 100644
--- a/dojo/cldr/nls/tr/currency.js
+++ b/dojo/cldr/nls/tr/currency.js
@@ -5,12 +5,18 @@ define(
 	"CHF_displayName": "İsviçre Frangı",
 	"JPY_symbol": "¥",
 	"CAD_displayName": "Kanada Doları",
-	"CNY_displayName": "Çin Yuanı Renminbi",
+	"HKD_symbol": "HK$",
+	"CNY_displayName": "Çin Yuanı",
 	"USD_symbol": "$",
 	"AUD_displayName": "Avustralya Doları",
 	"JPY_displayName": "Japon Yeni",
+	"CAD_symbol": "CA$",
 	"USD_displayName": "ABD Doları",
+	"EUR_symbol": "€",
+	"CNY_symbol": "CN¥",
 	"GBP_displayName": "İngiliz Sterlini",
+	"GBP_symbol": "£",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "Euro"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/tr/ethiopic.js b/dojo/cldr/nls/tr/ethiopic.js
new file mode 100644
index 0000000..3984f29
--- /dev/null
+++ b/dojo/cldr/nls/tr/ethiopic.js
@@ -0,0 +1,46 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Saniye",
+	"field-year-relative+-1": "Geçen yıl",
+	"field-week": "Hafta",
+	"field-month-relative+-1": "Geçen ay",
+	"field-day-relative+-1": "Dün",
+	"field-day-relative+-2": "Evvelsi gün",
+	"field-year": "Yıl",
+	"field-week-relative+0": "Bu hafta",
+	"field-week-relative+1": "Gelecek hafta",
+	"field-minute": "Dakika",
+	"field-week-relative+-1": "Geçen hafta",
+	"field-day-relative+0": "Bugün",
+	"field-hour": "Saat",
+	"field-day-relative+1": "Yarın",
+	"field-day-relative+2": "Öbür gün",
+	"field-day": "Gün",
+	"field-month-relative+0": "Bu ay",
+	"field-month-relative+1": "Gelecek ay",
+	"field-dayperiod": "ÖÖ/ÖS",
+	"field-month": "Ay",
+	"months-format-wide": [
+		"Meskerem",
+		"Tikimt",
+		"Hidar",
+		"Tahsas",
+		"Tir",
+		"Yakatit",
+		"Magabit",
+		"Miyazya",
+		"Ginbot",
+		"Sene",
+		"Hamle",
+		"Nehasa",
+		"Pagumiene"
+	],
+	"field-era": "Miladi Dönem",
+	"field-year-relative+0": "Bu yıl",
+	"field-year-relative+1": "Gelecek yıl",
+	"field-weekday": "Haftanın Günü",
+	"field-zone": "Saat Dilimi"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/generic.js b/dojo/cldr/nls/tr/generic.js
new file mode 100644
index 0000000..09a1bdd
--- /dev/null
+++ b/dojo/cldr/nls/tr/generic.js
@@ -0,0 +1,73 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "d MMM y G E",
+	"field-dayperiod": "ÖÖ/ÖS",
+	"field-minute": "Dakika",
+	"dateFormatItem-MMMEd": "d MMMM E",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "Dün",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"field-day-relative+-2": "Evvelsi gün",
+	"field-weekday": "Haftanın Günü",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "y G",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "Miladi Dönem",
+	"field-hour": "Saat",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "d E",
+	"field-day-relative+0": "Bugün",
+	"field-day-relative+1": "Yarın",
+	"field-day-relative+2": "Öbür gün",
+	"dateFormatItem-GyMMMd": "dd MMM y G",
+	"dateFormatItem-yyyyMM": "MM.y G",
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Saat Dilimi",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "Geçen hafta",
+	"dateFormat-medium": "d MMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "Bu yıl",
+	"field-year-relative+1": "Gelecek yıl",
+	"field-year-relative+-1": "Geçen yıl",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "G y/QQQQ",
+	"field-year": "Yıl",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "Hafta",
+	"dateFormatItem-yyyyMd": "dd.MM.y G",
+	"dateFormatItem-yyyyMMMd": "dd MMM y G",
+	"dateFormatItem-MMMMEd": "dd MMMM E",
+	"dateFormatItem-yyyyMEd": "dd.MM.y G E",
+	"dateFormatItem-MMMd": "d MMMM",
+	"field-week-relative+0": "Bu hafta",
+	"field-week-relative+1": "Gelecek hafta",
+	"field-month-relative+0": "Bu ay",
+	"dateFormatItem-H": "HH",
+	"field-month": "Ay",
+	"field-month-relative+1": "Gelecek ay",
+	"dateFormatItem-MMMMd": "dd MMMM",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateFormatItem-M": "L",
+	"field-second": "Saniye",
+	"dateFormatItem-GyMMMEd": "d MMM y G E",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Gün",
+	"dateFormatItem-MEd": "dd.MM E",
+	"dateFormatItem-yyyyQQQ": "G y/QQQ",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "d.MM.y G",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"dateFormat-full": "d MMMM y G EEEE",
+	"dateFormatItem-Md": "dd.MM",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"field-month-relative+-1": "Geçen ay",
+	"dateFormatItem-h": "h a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/gregorian.js b/dojo/cldr/nls/tr/gregorian.js
index b23088f..d683c52 100644
--- a/dojo/cldr/nls/tr/gregorian.js
+++ b/dojo/cldr/nls/tr/gregorian.js
@@ -1,6 +1,15 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"Pa",
+		"Pt",
+		"Sa",
+		"Ça",
+		"Pe",
+		"Cu",
+		"Ct"
+	],
 	"months-format-narrow": [
 		"O",
 		"Ş",
@@ -15,16 +24,32 @@ define(
 		"K",
 		"A"
 	],
+	"quarters-standAlone-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
 	"field-weekday": "Haftanın Günü",
-	"dateFormatItem-yyQQQQ": "QQQQ yy",
-	"dateFormatItem-yQQQ": "QQQ y",
-	"dateFormatItem-yMEd": "dd.MM.yyyy EEE",
-	"dateFormatItem-MMMEd": "dd MMM E",
+	"dateFormatItem-yQQQ": "y/QQQ",
+	"dateFormatItem-yMEd": "dd.MM.y E",
+	"dateFormatItem-GyMMMEd": "d MMM y G E",
+	"dateFormatItem-MMMEd": "d MMMM E",
 	"eraNarrow": [
 		"MÖ",
 		"MS"
 	],
-	"dateFormat-long": "dd MMMM y",
+	"dateFormatItem-yMM": "MM.y",
+	"days-format-short": [
+		"Pa",
+		"Pt",
+		"Sa",
+		"Ça",
+		"Pe",
+		"Cu",
+		"Ct"
+	],
+	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
 		"Ocak",
 		"Şubat",
@@ -39,12 +64,13 @@ define(
 		"Kasım",
 		"Aralık"
 	],
-	"dateFormatItem-EEEd": "d EEE",
-	"dayPeriods-format-wide-pm": "PM",
-	"dateFormat-full": "dd MMMM y EEEE",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "ÖS",
+	"dateFormat-full": "d MMMM y EEEE",
 	"dateFormatItem-Md": "dd/MM",
+	"dateFormatItem-yMd": "dd.MM.y",
 	"field-era": "Miladi Dönem",
-	"dateFormatItem-yM": "M/yyyy",
+	"dateFormatItem-yM": "MM/y",
 	"months-standAlone-wide": [
 		"Ocak",
 		"Şubat",
@@ -66,10 +92,10 @@ define(
 		"3. çeyrek",
 		"4. çeyrek"
 	],
+	"dateFormatItem-yQQQQ": "y/QQQQ",
 	"timeFormat-long": "HH:mm:ss z",
 	"field-year": "Yıl",
 	"dateFormatItem-yMMM": "MMM y",
-	"dateFormatItem-yQ": "Q yyyy",
 	"field-hour": "Saat",
 	"months-format-abbr": [
 		"Oca",
@@ -85,13 +111,12 @@ define(
 		"Kas",
 		"Ara"
 	],
-	"dateFormatItem-yyQ": "Q yy",
 	"timeFormat-full": "HH:mm:ss zzzz",
 	"field-day-relative+0": "Bugün",
 	"field-day-relative+1": "Yarın",
-	"field-day-relative+2": "Yarından sonraki gün",
+	"dateFormatItem-GyMMMd": "dd MMM y G",
+	"field-day-relative+2": "Öbür gün",
 	"dateFormatItem-H": "HH",
-	"field-day-relative+3": "Üç gün sonra",
 	"months-standAlone-abbr": [
 		"Oca",
 		"Şub",
@@ -118,6 +143,7 @@ define(
 		"3. çeyrek",
 		"4. çeyrek"
 	],
+	"dateFormatItem-Gy": "y G",
 	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
 		"Pazar",
@@ -129,7 +155,6 @@ define(
 		"Cumartesi"
 	],
 	"dateFormatItem-MMMMd": "dd MMMM",
-	"dateFormatItem-yyMMM": "MMM yy",
 	"timeFormat-medium": "HH:mm:ss",
 	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
@@ -143,7 +168,7 @@ define(
 		"MS"
 	],
 	"field-minute": "Dakika",
-	"field-dayperiod": "AM/PM",
+	"field-dayperiod": "ÖÖ/ÖS",
 	"days-standAlone-abbr": [
 		"Paz",
 		"Pzt",
@@ -155,11 +180,19 @@ define(
 	],
 	"dateFormatItem-d": "d",
 	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
 	"field-day-relative+-1": "Dün",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
 	"field-day-relative+-2": "Evvelsi gün",
-	"field-day-relative+-3": "Üç gün önce",
-	"dateFormatItem-MMMd": "dd MMM",
+	"dateFormatItem-MMMd": "d MMMM",
 	"dateFormatItem-MEd": "dd/MM E",
+	"dateTimeFormat-full": "{1} {0}",
 	"dateFormatItem-yMMMM": "MMMM y",
 	"field-day": "Gün",
 	"days-format-wide": [
@@ -187,7 +220,8 @@ define(
 		"K",
 		"A"
 	],
-	"dateFormatItem-yyMM": "MM/yy",
+	"field-year-relative+-1": "Geçen yıl",
+	"field-month-relative+-1": "Geçen ay",
 	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
 		"Paz",
@@ -198,6 +232,7 @@ define(
 		"Cum",
 		"Cmt"
 	],
+	"dateFormatItem-yMMMd": "dd MMM y",
 	"eraNames": [
 		"Milattan Önce",
 		"Milattan Sonra"
@@ -211,7 +246,6 @@ define(
 		"C",
 		"C"
 	],
-	"field-month": "Ay",
 	"days-standAlone-narrow": [
 		"P",
 		"P",
@@ -222,18 +256,27 @@ define(
 		"C"
 	],
 	"dateFormatItem-MMM": "LLL",
-	"dayPeriods-format-wide-am": "AM",
+	"field-month": "Ay",
+	"dayPeriods-format-wide-am": "ÖÖ",
 	"dateFormatItem-MMMMEd": "dd MMMM E",
-	"dateFormat-short": "dd.MM.yyyy",
+	"dateFormat-short": "d.MM.y",
 	"field-second": "Saniye",
-	"dateFormatItem-yMMMEd": "dd MMM y EEE",
+	"dateFormatItem-yMMMEd": "d MMM y E",
+	"field-month-relative+0": "Bu ay",
+	"field-month-relative+1": "Gelecek ay",
 	"dateFormatItem-Ed": "d E",
 	"field-week": "Hafta",
-	"dateFormat-medium": "dd MMM y",
+	"dateFormat-medium": "d MMM y",
+	"field-year-relative+0": "Bu yıl",
+	"field-week-relative+-1": "Geçen hafta",
+	"field-year-relative+1": "Gelecek yıl",
 	"dateFormatItem-mmss": "mm:ss",
+	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "h:mm:ss a",
-	"dateFormatItem-yyyy": "y"
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-week-relative+0": "Bu hafta",
+	"field-week-relative+1": "Gelecek hafta"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/hebrew.js b/dojo/cldr/nls/tr/hebrew.js
new file mode 100644
index 0000000..83da9a8
--- /dev/null
+++ b/dojo/cldr/nls/tr/hebrew.js
@@ -0,0 +1,225 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "ÖÖ/ÖS",
+	"dateFormatItem-yyyyMMMEd": "d MMM y G E",
+	"dayPeriods-format-wide-pm": "ÖS",
+	"field-minute": "Dakika",
+	"dateFormatItem-MMMEd": "d MMMM E",
+	"field-day-relative+-1": "Dün",
+	"field-weekday": "Haftanın Günü",
+	"field-day-relative+-2": "Evvelsi gün",
+	"days-standAlone-wide": [
+		"Pazar",
+		"Pazartesi",
+		"Salı",
+		"Çarşamba",
+		"Perşembe",
+		"Cuma",
+		"Cumartesi"
+	],
+	"field-era": "Miladi Dönem",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Saat",
+	"dayPeriods-format-wide-am": "ÖÖ",
+	"quarters-standAlone-abbr": [
+		"Ç1",
+		"Ç2",
+		"Ç3",
+		"Ç4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Tişri",
+		"Heşvan",
+		"Kislev",
+		"Tevet",
+		"Şevat",
+		"Veadar",
+		"Adar",
+		"Nisan",
+		"İyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
+		"Elul"
+	],
+	"dateFormatItem-Ed": "d E",
+	"field-day-relative+0": "Bugün",
+	"field-day-relative+1": "Yarın",
+	"days-standAlone-narrow": [
+		"P",
+		"P",
+		"S",
+		"Ç",
+		"P",
+		"C",
+		"C"
+	],
+	"field-day-relative+2": "Öbür gün",
+	"dateFormatItem-GyMMMd": "dd MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Saat Dilimi",
+	"field-week-relative+-1": "Geçen hafta",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Bu yıl",
+	"field-year-relative+1": "Gelecek yıl",
+	"quarters-standAlone-wide": [
+		"1. çeyrek",
+		"2. çeyrek",
+		"3. çeyrek",
+		"4. çeyrek"
+	],
+	"field-year-relative+-1": "Geçen yıl",
+	"field-year": "Yıl",
+	"dateFormatItem-yyyyQQQQ": "G y/QQQQ",
+	"quarters-standAlone-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"months-standAlone-wide": [
+		"Tişri",
+		"Heşvan",
+		"Kislev",
+		"Tevet",
+		"Şevat",
+		"Veadar",
+		"Adar",
+		"Nisan",
+		"İyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
+		"Elul"
+	],
+	"field-week": "Hafta",
+	"dateFormatItem-yyyyMd": "dd.MM.y G",
+	"dateFormatItem-yyyyMMMd": "dd MMM y G",
+	"dateFormatItem-yyyyMEd": "dd.MM.y G E",
+	"dateFormatItem-MMMd": "d MMMM",
+	"field-week-relative+0": "Bu hafta",
+	"quarters-format-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"field-week-relative+1": "Gelecek hafta",
+	"months-format-abbr": [
+		"Tişri",
+		"Heşvan",
+		"Kislev",
+		"Tevet",
+		"Şevat",
+		"Veadar",
+		"Adar",
+		"Nisan",
+		"İyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
+		"Elul"
+	],
+	"field-month-relative+0": "Bu ay",
+	"field-month": "Ay",
+	"field-month-relative+1": "Gelecek ay",
+	"quarters-format-abbr": [
+		"Ç1",
+		"Ç2",
+		"Ç3",
+		"Ç4"
+	],
+	"days-format-abbr": [
+		"Paz",
+		"Pzt",
+		"Sal",
+		"Çar",
+		"Per",
+		"Cum",
+		"Cmt"
+	],
+	"days-format-narrow": [
+		"P",
+		"P",
+		"S",
+		"Ç",
+		"P",
+		"C",
+		"C"
+	],
+	"field-second": "Saniye",
+	"dateFormatItem-GyMMMEd": "d MMM y G E",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Gün",
+	"dateFormatItem-yyyyQQQ": "G y/QQQ",
+	"dateFormatItem-MEd": "dd.MM E",
+	"days-standAlone-short": [
+		"Pa",
+		"Pt",
+		"Sa",
+		"Ça",
+		"Pe",
+		"Cu",
+		"Ct"
+	],
+	"days-standAlone-abbr": [
+		"Paz",
+		"Pzt",
+		"Sal",
+		"Çar",
+		"Per",
+		"Cum",
+		"Cmt"
+	],
+	"dateFormat-short": "d.MM.y G",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"dateFormatItem-Md": "dd.MM",
+	"dateFormat-full": "d MMMM y G EEEE",
+	"months-format-wide": [
+		"Tişri",
+		"Heşvan",
+		"Kislev",
+		"Tevet",
+		"Şevat",
+		"Veadar",
+		"Adar",
+		"Nisan",
+		"İyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
+		"Elul"
+	],
+	"days-format-short": [
+		"Pa",
+		"Pt",
+		"Sa",
+		"Ça",
+		"Pe",
+		"Cu",
+		"Ct"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"months-format-wide-leap": "Adar II",
+	"field-month-relative+-1": "Geçen ay",
+	"quarters-format-wide": [
+		"1. çeyrek",
+		"2. çeyrek",
+		"3. çeyrek",
+		"4. çeyrek"
+	],
+	"days-format-wide": [
+		"Pazar",
+		"Pazartesi",
+		"Salı",
+		"Çarşamba",
+		"Perşembe",
+		"Cuma",
+		"Cumartesi"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/islamic.js b/dojo/cldr/nls/tr/islamic.js
new file mode 100644
index 0000000..c40d07b
--- /dev/null
+++ b/dojo/cldr/nls/tr/islamic.js
@@ -0,0 +1,234 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "ÖÖ/ÖS",
+	"dateFormatItem-yyyyMMMEd": "d MMM y G E",
+	"dayPeriods-format-wide-pm": "ÖS",
+	"field-minute": "Dakika",
+	"dateFormatItem-MMMEd": "d MMMM E",
+	"field-day-relative+-1": "Dün",
+	"field-weekday": "Haftanın Günü",
+	"field-day-relative+-2": "Evvelsi gün",
+	"days-standAlone-wide": [
+		"Pazar",
+		"Pazartesi",
+		"Salı",
+		"Çarşamba",
+		"Perşembe",
+		"Cuma",
+		"Cumartesi"
+	],
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-era": "Miladi Dönem",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Saat",
+	"dayPeriods-format-wide-am": "ÖÖ",
+	"quarters-standAlone-abbr": [
+		"Ç1",
+		"Ç2",
+		"Ç3",
+		"Ç4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Muharrem",
+		"Safer",
+		"Rebiülevvel",
+		"Rebiülahir",
+		"Cemaziyelevvel",
+		"Cemaziyelahir",
+		"Recep",
+		"Şaban",
+		"Ramazan",
+		"Şevval",
+		"Zilkade",
+		"Zilhicce"
+	],
+	"dateFormatItem-Ed": "d E",
+	"field-day-relative+0": "Bugün",
+	"field-day-relative+1": "Yarın",
+	"days-standAlone-narrow": [
+		"P",
+		"P",
+		"S",
+		"Ç",
+		"P",
+		"C",
+		"C"
+	],
+	"field-day-relative+2": "Öbür gün",
+	"dateFormatItem-GyMMMd": "dd MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Saat Dilimi",
+	"field-week-relative+-1": "Geçen hafta",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Bu yıl",
+	"field-year-relative+1": "Gelecek yıl",
+	"quarters-standAlone-wide": [
+		"1. çeyrek",
+		"2. çeyrek",
+		"3. çeyrek",
+		"4. çeyrek"
+	],
+	"field-year-relative+-1": "Geçen yıl",
+	"field-year": "Yıl",
+	"dateFormatItem-yyyyQQQQ": "G y/QQQQ",
+	"quarters-standAlone-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"months-standAlone-wide": [
+		"Muharrem",
+		"Safer",
+		"Rebiülevvel",
+		"Rebiülahir",
+		"Cemaziyelevvel",
+		"Cemaziyelahir",
+		"Recep",
+		"Şaban",
+		"Ramazan",
+		"Şevval",
+		"Zilkade",
+		"Zilhicce"
+	],
+	"field-week": "Hafta",
+	"dateFormatItem-yyyyMMMd": "dd MMM y G",
+	"dateFormatItem-yyyyMd": "dd.MM.y G",
+	"dateFormatItem-yyyyMEd": "dd.MM.y G E",
+	"field-week-relative+0": "Bu hafta",
+	"dateFormatItem-MMMd": "d MMMM",
+	"quarters-format-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"field-week-relative+1": "Gelecek hafta",
+	"months-format-abbr": [
+		"Muharrem",
+		"Safer",
+		"Rebiülevvel",
+		"Rebiülahir",
+		"Cemaziyelevvel",
+		"Cemaziyelahir",
+		"Recep",
+		"Şaban",
+		"Ramazan",
+		"Şevval",
+		"Zilkade",
+		"Zilhicce"
+	],
+	"field-month-relative+0": "Bu ay",
+	"field-month": "Ay",
+	"field-month-relative+1": "Gelecek ay",
+	"quarters-format-abbr": [
+		"Ç1",
+		"Ç2",
+		"Ç3",
+		"Ç4"
+	],
+	"days-format-abbr": [
+		"Paz",
+		"Pzt",
+		"Sal",
+		"Çar",
+		"Per",
+		"Cum",
+		"Cmt"
+	],
+	"days-format-narrow": [
+		"P",
+		"P",
+		"S",
+		"Ç",
+		"P",
+		"C",
+		"C"
+	],
+	"field-second": "Saniye",
+	"dateFormatItem-GyMMMEd": "d MMM y G E",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Gün",
+	"dateFormatItem-yyyyQQQ": "G y/QQQ",
+	"dateFormatItem-MEd": "dd.MM E",
+	"days-standAlone-short": [
+		"Pa",
+		"Pt",
+		"Sa",
+		"Ça",
+		"Pe",
+		"Cu",
+		"Ct"
+	],
+	"days-standAlone-abbr": [
+		"Paz",
+		"Pzt",
+		"Sal",
+		"Çar",
+		"Per",
+		"Cum",
+		"Cmt"
+	],
+	"dateFormat-short": "d.MM.y G",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"dateFormat-full": "d MMMM y G EEEE",
+	"dateFormatItem-Md": "dd.MM",
+	"months-format-wide": [
+		"Muharrem",
+		"Safer",
+		"Rebiülevvel",
+		"Rebiülahir",
+		"Cemaziyelevvel",
+		"Cemaziyelahir",
+		"Recep",
+		"Şaban",
+		"Ramazan",
+		"Şevval",
+		"Zilkade",
+		"Zilhicce"
+	],
+	"days-format-short": [
+		"Pa",
+		"Pt",
+		"Sa",
+		"Ça",
+		"Pe",
+		"Cu",
+		"Ct"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "Geçen ay",
+	"quarters-format-wide": [
+		"1. çeyrek",
+		"2. çeyrek",
+		"3. çeyrek",
+		"4. çeyrek"
+	],
+	"days-format-wide": [
+		"Pazar",
+		"Pazartesi",
+		"Salı",
+		"Çarşamba",
+		"Perşembe",
+		"Cuma",
+		"Cumartesi"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/japanese.js b/dojo/cldr/nls/tr/japanese.js
new file mode 100644
index 0000000..afc71f4
--- /dev/null
+++ b/dojo/cldr/nls/tr/japanese.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d MMM y G",
+	"field-second": "Saniye",
+	"field-year-relative+-1": "Geçen yıl",
+	"field-week": "Hafta",
+	"field-month-relative+-1": "Geçen ay",
+	"field-day-relative+-1": "Dün",
+	"field-day-relative+-2": "Evvelsi gün",
+	"field-year": "Yıl",
+	"field-week-relative+0": "Bu hafta",
+	"field-week-relative+1": "Gelecek hafta",
+	"field-minute": "Dakika",
+	"field-week-relative+-1": "Geçen hafta",
+	"field-day-relative+0": "Bugün",
+	"field-hour": "Saat",
+	"field-day-relative+1": "Yarın",
+	"dateFormat-long": "d MMMM y G",
+	"field-day-relative+2": "Öbür gün",
+	"field-day": "Gün",
+	"field-month-relative+0": "Bu ay",
+	"field-month-relative+1": "Gelecek ay",
+	"field-dayperiod": "ÖÖ/ÖS",
+	"field-month": "Ay",
+	"dateFormat-short": "d.MM.y G",
+	"field-era": "Miladi Dönem",
+	"field-year-relative+0": "Bu yıl",
+	"field-year-relative+1": "Gelecek yıl",
+	"dateFormat-full": "d MMMM y G EEEE",
+	"field-weekday": "Haftanın Günü",
+	"field-zone": "Saat Dilimi"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/number.js b/dojo/cldr/nls/tr/number.js
index 1b20f28..92d3755 100644
--- a/dojo/cldr/nls/tr/number.js
+++ b/dojo/cldr/nls/tr/number.js
@@ -5,18 +5,18 @@ define(
 	"percentSign": "%",
 	"exponential": "E",
 	"scientificFormat": "#E0",
-	"percentFormat": "% #,##0",
+	"percentFormat": "%#,##0",
 	"list": ";",
 	"infinity": "∞",
-	"patternDigit": "#",
 	"minusSign": "-",
 	"decimal": ",",
 	"nan": "NaN",
-	"nativeZeroDigit": "0",
 	"perMille": "‰",
 	"decimalFormat": "#,##0.###",
-	"currencyFormat": "#,##0.00 ¤",
-	"plusSign": "+"
+	"currencyFormat": "#,##0.00 ¤;(#,##0.00 ¤)",
+	"plusSign": "+",
+	"decimalFormat-long": "000 trilyon",
+	"decimalFormat-short": "000 Tn"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/persian.js b/dojo/cldr/nls/tr/persian.js
new file mode 100644
index 0000000..a2ee3d0
--- /dev/null
+++ b/dojo/cldr/nls/tr/persian.js
@@ -0,0 +1,248 @@
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "ÖÖ/ÖS",
+	"dateFormatItem-yyyyMMMEd": "d MMM y G E",
+	"dayPeriods-format-wide-pm": "ÖS",
+	"field-minute": "Dakika",
+	"dateFormatItem-MMMEd": "d MMMM E",
+	"field-day-relative+-1": "Dün",
+	"field-weekday": "Haftanın Günü",
+	"field-day-relative+-2": "Evvelsi gün",
+	"days-standAlone-wide": [
+		"Pazar",
+		"Pazartesi",
+		"Salı",
+		"Çarşamba",
+		"Perşembe",
+		"Cuma",
+		"Cumartesi"
+	],
+	"months-standAlone-narrow": [
+		"O",
+		"Ş",
+		"M",
+		"N",
+		"M",
+		"H",
+		"T",
+		"A",
+		"E",
+		"E",
+		"K",
+		"A"
+	],
+	"field-era": "Miladi Dönem",
+	"dateFormatItem-Gy": "y G",
+	"field-hour": "Saat",
+	"dayPeriods-format-wide-am": "ÖÖ",
+	"quarters-standAlone-abbr": [
+		"Ç1",
+		"Ç2",
+		"Ç3",
+		"Ç4"
+	],
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Ferverdin",
+		"Ordibeheşt",
+		"Hordad",
+		"Tir",
+		"Mordad",
+		"Şehriver",
+		"Mehr",
+		"Aban",
+		"Azer",
+		"Dey",
+		"Behmen",
+		"Esfend"
+	],
+	"dateFormatItem-Ed": "d E",
+	"field-day-relative+0": "Bugün",
+	"field-day-relative+1": "Yarın",
+	"days-standAlone-narrow": [
+		"P",
+		"P",
+		"S",
+		"Ç",
+		"P",
+		"C",
+		"C"
+	],
+	"field-day-relative+2": "Öbür gün",
+	"dateFormatItem-GyMMMd": "dd MMM y G",
+	"dateFormat-long": "d MMMM y G",
+	"field-zone": "Saat Dilimi",
+	"field-week-relative+-1": "Geçen hafta",
+	"dateFormat-medium": "d MMM y G",
+	"field-year-relative+0": "Bu yıl",
+	"field-year-relative+1": "Gelecek yıl",
+	"quarters-standAlone-wide": [
+		"1. çeyrek",
+		"2. çeyrek",
+		"3. çeyrek",
+		"4. çeyrek"
+	],
+	"field-year-relative+-1": "Geçen yıl",
+	"field-year": "Yıl",
+	"dateFormatItem-yyyyQQQQ": "G y/QQQQ",
+	"quarters-standAlone-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"months-standAlone-wide": [
+		"Ferverdin",
+		"Ordibeheşt",
+		"Hordad",
+		"Tir",
+		"Mordad",
+		"Şehriver",
+		"Mehr",
+		"Aban",
+		"Azer",
+		"Dey",
+		"Behmen",
+		"Esfend"
+	],
+	"field-week": "Hafta",
+	"dateFormatItem-yyyyMMMd": "dd MMM y G",
+	"dateFormatItem-yyyyMd": "dd.MM.y G",
+	"dateFormatItem-yyyyMEd": "dd.MM.y G E",
+	"field-week-relative+0": "Bu hafta",
+	"dateFormatItem-MMMd": "d MMMM",
+	"quarters-format-narrow": [
+		"1.",
+		"2.",
+		"3.",
+		"4."
+	],
+	"field-week-relative+1": "Gelecek hafta",
+	"months-format-abbr": [
+		"Ferverdin",
+		"Ordibeheşt",
+		"Hordad",
+		"Tir",
+		"Mordad",
+		"Şehriver",
+		"Mehr",
+		"Aban",
+		"Azer",
+		"Dey",
+		"Behmen",
+		"Esfend"
+	],
+	"field-month-relative+0": "Bu ay",
+	"field-month": "Ay",
+	"field-month-relative+1": "Gelecek ay",
+	"quarters-format-abbr": [
+		"Ç1",
+		"Ç2",
+		"Ç3",
+		"Ç4"
+	],
+	"days-format-abbr": [
+		"Paz",
+		"Pzt",
+		"Sal",
+		"Çar",
+		"Per",
+		"Cum",
+		"Cmt"
+	],
+	"days-format-narrow": [
+		"P",
+		"P",
+		"S",
+		"Ç",
+		"P",
+		"C",
+		"C"
+	],
+	"field-second": "Saniye",
+	"dateFormatItem-GyMMMEd": "d MMM y G E",
+	"dateFormatItem-GyMMM": "MMM y G",
+	"field-day": "Gün",
+	"dateFormatItem-yyyyQQQ": "G y/QQQ",
+	"dateFormatItem-MEd": "dd.MM E",
+	"months-format-narrow": [
+		"O",
+		"Ş",
+		"M",
+		"N",
+		"M",
+		"H",
+		"T",
+		"A",
+		"E",
+		"E",
+		"K",
+		"A"
+	],
+	"days-standAlone-short": [
+		"Pa",
+		"Pt",
+		"Sa",
+		"Ça",
+		"Pe",
+		"Cu",
+		"Ct"
+	],
+	"days-standAlone-abbr": [
+		"Paz",
+		"Pzt",
+		"Sal",
+		"Çar",
+		"Per",
+		"Cum",
+		"Cmt"
+	],
+	"dateFormat-short": "d.MM.y G",
+	"dateFormatItem-yyyyM": "MM.y G",
+	"dateFormat-full": "d MMMM y G EEEE",
+	"dateFormatItem-Md": "dd.MM",
+	"months-format-wide": [
+		"Ferverdin",
+		"Ordibeheşt",
+		"Hordad",
+		"Tir",
+		"Mordad",
+		"Şehriver",
+		"Mehr",
+		"Aban",
+		"Azer",
+		"Dey",
+		"Behmen",
+		"Esfend"
+	],
+	"days-format-short": [
+		"Pa",
+		"Pt",
+		"Sa",
+		"Ça",
+		"Pe",
+		"Cu",
+		"Ct"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"field-month-relative+-1": "Geçen ay",
+	"quarters-format-wide": [
+		"1. çeyrek",
+		"2. çeyrek",
+		"3. çeyrek",
+		"4. çeyrek"
+	],
+	"days-format-wide": [
+		"Pazar",
+		"Pazartesi",
+		"Salı",
+		"Çarşamba",
+		"Perşembe",
+		"Cuma",
+		"Cumartesi"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/roc.js b/dojo/cldr/nls/tr/roc.js
new file mode 100644
index 0000000..112f18c
--- /dev/null
+++ b/dojo/cldr/nls/tr/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "Saniye",
+	"field-year-relative+-1": "Geçen yıl",
+	"field-week": "Hafta",
+	"field-month-relative+-1": "Geçen ay",
+	"field-day-relative+-1": "Dün",
+	"field-day-relative+-2": "Evvelsi gün",
+	"field-year": "Yıl",
+	"field-week-relative+0": "Bu hafta",
+	"field-week-relative+1": "Gelecek hafta",
+	"field-minute": "Dakika",
+	"field-week-relative+-1": "Geçen hafta",
+	"field-day-relative+0": "Bugün",
+	"field-hour": "Saat",
+	"field-day-relative+1": "Yarın",
+	"field-day-relative+2": "Öbür gün",
+	"field-day": "Gün",
+	"field-month-relative+0": "Bu ay",
+	"field-month-relative+1": "Gelecek ay",
+	"field-dayperiod": "ÖÖ/ÖS",
+	"field-month": "Ay",
+	"field-era": "Miladi Dönem",
+	"field-year-relative+0": "Bu yıl",
+	"field-year-relative+1": "Gelecek yıl",
+	"eraAbbr": [
+		"Before R.O.C.",
+		"Minguo"
+	],
+	"field-weekday": "Haftanın Günü",
+	"field-zone": "Saat Dilimi"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/buddhist.js b/dojo/cldr/nls/zh-hant/buddhist.js
index 57d9aa7..9db507b 100644
--- a/dojo/cldr/nls/zh-hant/buddhist.js
+++ b/dojo/cldr/nls/zh-hant/buddhist.js
@@ -1,36 +1,22 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "Gy/M",
-	"dateFormatItem-yQ": "Gy年QQQ",
-	"dayPeriods-format-wide-pm": "下午",
-	"dateFormatItem-MMMEd": "MMMd日E",
-	"dateTimeFormat-full": "{1}{0}",
-	"dateFormatItem-hms": "ah:mm:ss",
-	"dateFormatItem-yQQQ": "Gy年QQQ",
-	"dateFormatItem-MMdd": "MM/dd",
-	"dateFormatItem-MMM": "LLL",
-	"dayPeriods-format-wide-am": "上午",
-	"dateFormatItem-y": "Gy年",
-	"timeFormat-full": "zzzzah時mm分ss秒",
-	"dateFormatItem-yyyy": "y年",
-	"months-standAlone-abbr": [
-		"一月",
-		"二月",
-		"三月",
-		"四月",
-		"五月",
-		"六月",
-		"七月",
-		"八月",
-		"九月",
-		"十月",
-		"十一月",
-		"十二月"
+	"days-standAlone-short": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
 	],
-	"dateFormatItem-Ed": "d日(E)",
-	"dateFormatItem-yMMM": "Gy年M月",
-	"days-standAlone-narrow": [
+	"field-weekday": "週天",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"eraNarrow": [
+		"佛曆"
+	],
+	"days-format-short": [
 		"日",
 		"一",
 		"二",
@@ -39,18 +25,27 @@ define(
 		"五",
 		"六"
 	],
-	"dateFormatItem-yyyyMMMM": "y年MMMM",
 	"dateFormat-long": "Gy年M月d日",
-	"timeFormat-medium": "ah:mm:ss",
-	"dateFormatItem-EEEd": "d EEE",
-	"dateFormatItem-Hm": "H:mm",
-	"dateFormatItem-yyMM": "Gyy/MM",
-	"dateFormat-medium": "Gy/M/d",
-	"dateFormatItem-Hms": "H:mm:ss",
-	"dateFormatItem-yyMMM": "Gyy年MMM",
-	"dateFormatItem-yMd": "Gy/M/d",
-	"dateFormatItem-ms": "mm:ss",
-	"dateTimeFormat-long": "{1}{0}",
+	"months-format-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"dateFormatItem-yyyyQQQ": "Gy年QQQ",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "Gy/M/d(E)",
+	"dateFormatItem-Md": "M/d",
+	"field-era": "年代",
 	"months-standAlone-wide": [
 		"一月",
 		"二月",
@@ -65,9 +60,16 @@ define(
 		"十一月",
 		"十二月"
 	],
-	"dateFormatItem-MMMd": "MMMd日",
-	"dateFormatItem-yyQ": "Gyy年第Q季度",
+	"timeFormat-short": "ah:mm",
+	"quarters-format-wide": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
 	"timeFormat-long": "zah時mm分ss秒",
+	"field-year": "年",
+	"field-hour": "小時",
 	"months-format-abbr": [
 		"1月",
 		"2月",
@@ -82,35 +84,13 @@ define(
 		"11月",
 		"12月"
 	],
+	"timeFormat-full": "zzzzah時mm分ss秒",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-day-relative+2": "後天",
 	"dateFormatItem-H": "H時",
-	"timeFormat-short": "ah:mm",
-	"quarters-format-abbr": [
-		"1季",
-		"2季",
-		"3季",
-		"4季"
-	],
-	"dateFormatItem-MMMMdd": "MMMMdd日",
-	"days-format-abbr": [
-		"週日",
-		"週一",
-		"週二",
-		"週三",
-		"週四",
-		"週五",
-		"週六"
-	],
-	"dateFormatItem-M": "M月",
-	"dateFormatItem-yMMMd": "Gy年MMMd日",
-	"dateFormatItem-MEd": "M/d(E)",
-	"dateFormatItem-hm": "ah:mm",
-	"dateFormat-short": "Gy/M/d",
-	"dateFormatItem-yyyyM": "y年M月",
-	"dateFormatItem-yMMMEd": "Gy年M月d日EEE",
-	"dateFormat-full": "Gy年M月d日EEEE",
-	"dateFormatItem-Md": "M/d",
-	"dateFormatItem-yMEd": "Gy/M/d(EEE)",
-	"months-format-wide": [
+	"months-standAlone-abbr": [
 		"1月",
 		"2月",
 		"3月",
@@ -124,13 +104,64 @@ define(
 		"11月",
 		"12月"
 	],
-	"dateFormatItem-d": "d日",
-	"quarters-format-wide": [
-		"第1季",
-		"第2季",
-		"第3季",
-		"第4季"
+	"quarters-format-abbr": [
+		"1季",
+		"2季",
+		"3季",
+		"4季"
+	],
+	"quarters-standAlone-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
+	],
+	"dateFormatItem-Gy": "Gy年",
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-M": "M月",
+	"days-standAlone-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"timeFormat-medium": "ah:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
 	],
+	"eraAbbr": [
+		"佛曆"
+	],
+	"field-minute": "分鐘",
+	"field-dayperiod": "上午/下午",
+	"days-standAlone-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormatItem-d": "d日",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-h": "ah時",
+	"dateTimeFormat-long": "{1}{0}",
+	"dayPeriods-format-narrow-am": "上午",
+	"field-day-relative+-2": "前天",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day": "日",
 	"days-format-wide": [
 		"星期日",
 		"星期一",
@@ -140,7 +171,63 @@ define(
 		"星期五",
 		"星期六"
 	],
-	"dateFormatItem-h": "ah時"
+	"field-zone": "時區",
+	"dateFormatItem-y": "Gy年",
+	"field-year-relative+-1": "去年",
+	"field-month-relative+-1": "上個月",
+	"dateFormatItem-hm": "ah:mm",
+	"days-format-abbr": [
+		"週日",
+		"週一",
+		"週二",
+		"週三",
+		"週四",
+		"週五",
+		"週六"
+	],
+	"eraNames": [
+		"佛曆"
+	],
+	"days-format-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormat-short": "Gy/M/d",
+	"field-second": "秒",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下個月",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-week": "週",
+	"dateFormat-medium": "Gy/M/d",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "上週",
+	"dateFormatItem-yyyyM": "Gy/M",
+	"field-year-relative+1": "明年",
+	"dayPeriods-format-narrow-pm": "下午",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-yyyy": "Gy年",
+	"field-week-relative+0": "本週",
+	"field-week-relative+1": "下週"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/chinese.js b/dojo/cldr/nls/zh-hant/chinese.js
new file mode 100644
index 0000000..288d7b4
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/chinese.js
@@ -0,0 +1,85 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "U年MMMd日E",
+	"field-dayperiod": "上午/下午",
+	"field-minute": "分鐘",
+	"dateFormatItem-MMMEd": "MMMd日E",
+	"field-day-relative+-1": "昨天",
+	"field-day-relative+-2": "前天",
+	"field-weekday": "週天",
+	"months-standAlone-narrow": [
+		"正",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六",
+		"七",
+		"八",
+		"九",
+		"十",
+		"十一",
+		"十二"
+	],
+	"field-era": "年代",
+	"dateFormatItem-Gy": "U年",
+	"field-hour": "小時",
+	"dateFormatItem-y": "U年",
+	"dateFormatItem-yyyy": "U年",
+	"dateFormatItem-Ed": "d日E",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "後天",
+	"dateFormatItem-GyMMMd": "U年MMMd日",
+	"dateFormat-long": "U年MMMd日",
+	"field-zone": "時區",
+	"field-week-relative+-1": "上週",
+	"dateFormat-medium": "U年MMMd日",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"dateFormatItem-yMd": "U年M月d日",
+	"field-year-relative+-1": "去年",
+	"field-year": "年",
+	"dateFormatItem-yyyyQQQQ": "U年QQQQ",
+	"field-week": "週",
+	"dateFormatItem-yyyyMd": "U年M月d日",
+	"dateFormatItem-yyyyMMMd": "U年MMMd日",
+	"dateFormatItem-yyyyMEd": "U年M月d日,E",
+	"dateFormatItem-MMMd": "MMMd日",
+	"field-week-relative+0": "本週",
+	"field-week-relative+1": "下週",
+	"field-month-relative+0": "本月",
+	"field-month": "月",
+	"field-month-relative+1": "下個月",
+	"dateFormatItem-M": "MMM",
+	"field-second": "秒",
+	"dateFormatItem-GyMMMEd": "U年MMMd日E",
+	"dateFormatItem-GyMMM": "U年MMM",
+	"field-day": "日",
+	"dateFormatItem-yyyyQQQ": "U年QQQQ",
+	"dateFormatItem-MEd": "M/dE",
+	"dateFormat-short": "U/M/d",
+	"dateFormatItem-yyyyM": "U年M月",
+	"dateFormat-full": "U年MMMd日EEEE",
+	"dateFormatItem-Md": "M/d",
+	"months-format-wide": [
+		"正月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"dateFormatItem-yyyyMMM": "U年MMM",
+	"dateFormatItem-d": "d日",
+	"field-month-relative+-1": "上個月"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/coptic.js b/dojo/cldr/nls/zh-hant/coptic.js
new file mode 100644
index 0000000..c56dd46
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/coptic.js
@@ -0,0 +1,121 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒",
+	"field-year-relative+-1": "去年",
+	"field-week": "週",
+	"field-month-relative+-1": "上個月",
+	"field-day-relative+-1": "昨天",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "前天",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"months-standAlone-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-year": "年",
+	"field-week-relative+0": "本週",
+	"months-standAlone-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-week-relative+1": "下週",
+	"field-minute": "分鐘",
+	"field-week-relative+-1": "上週",
+	"field-day-relative+0": "今天",
+	"field-hour": "小時",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "後天",
+	"field-day": "日",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下個月",
+	"field-dayperiod": "上午/下午",
+	"field-month": "月",
+	"months-format-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-era": "年代",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-weekday": "週天",
+	"field-zone": "時區"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/currency.js b/dojo/cldr/nls/zh-hant/currency.js
index 4dc8c57..1d69cf6 100644
--- a/dojo/cldr/nls/zh-hant/currency.js
+++ b/dojo/cldr/nls/zh-hant/currency.js
@@ -3,13 +3,20 @@ define(
 {
 	"HKD_displayName": "港幣",
 	"CHF_displayName": "瑞士法郎",
+	"JPY_symbol": "¥",
 	"CAD_displayName": "加幣",
+	"HKD_symbol": "HK$",
 	"CNY_displayName": "人民幣",
 	"USD_symbol": "$",
 	"AUD_displayName": "澳幣",
 	"JPY_displayName": "日圓",
+	"CAD_symbol": "CA$",
+	"USD_displayName": "美金",
+	"EUR_symbol": "€",
 	"CNY_symbol": "¥",
 	"GBP_displayName": "英鎊",
+	"GBP_symbol": "£",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "歐元"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/zh-hant/ethiopic.js b/dojo/cldr/nls/zh-hant/ethiopic.js
new file mode 100644
index 0000000..c56dd46
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/ethiopic.js
@@ -0,0 +1,121 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒",
+	"field-year-relative+-1": "去年",
+	"field-week": "週",
+	"field-month-relative+-1": "上個月",
+	"field-day-relative+-1": "昨天",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "前天",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"months-standAlone-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-year": "年",
+	"field-week-relative+0": "本週",
+	"months-standAlone-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-week-relative+1": "下週",
+	"field-minute": "分鐘",
+	"field-week-relative+-1": "上週",
+	"field-day-relative+0": "今天",
+	"field-hour": "小時",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "後天",
+	"field-day": "日",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下個月",
+	"field-dayperiod": "上午/下午",
+	"field-month": "月",
+	"months-format-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-era": "年代",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-weekday": "週天",
+	"field-zone": "時區"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/generic.js b/dojo/cldr/nls/zh-hant/generic.js
new file mode 100644
index 0000000..49d0139
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/generic.js
@@ -0,0 +1,68 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
+	"field-dayperiod": "上午/下午",
+	"field-minute": "分鐘",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"field-day-relative+-2": "前天",
+	"field-weekday": "週天",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "Gy年",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "年代",
+	"field-hour": "小時",
+	"dateFormatItem-y": "Gy年",
+	"dateFormatItem-yyyy": "Gy年",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "後天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"dateFormat-long": "Gy年M月d日",
+	"field-zone": "時區",
+	"dateFormatItem-Hm": "H:mm",
+	"field-week-relative+-1": "上週",
+	"dateFormat-medium": "Gy/M/d",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"field-year-relative+-1": "去年",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"field-year": "年",
+	"dateTimeFormat-long": "{1}{0}",
+	"field-week": "週",
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"dateFormatItem-yyyyMEd": "Gy/M/d(E)",
+	"dateFormatItem-MMMd": "M月d日",
+	"field-week-relative+0": "本週",
+	"field-week-relative+1": "下週",
+	"field-month-relative+0": "本月",
+	"dateFormatItem-H": "H時",
+	"field-month": "月",
+	"field-month-relative+1": "下個月",
+	"dateFormatItem-M": "M月",
+	"field-second": "秒",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"field-day": "日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateFormatItem-yyyyQQQ": "Gy年QQQ",
+	"dateFormatItem-hm": "ah:mm",
+	"dateFormat-short": "Gy/M/d",
+	"dateFormatItem-yyyyM": "Gy/M",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-Md": "M/d",
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-d": "d日",
+	"field-month-relative+-1": "上個月",
+	"dateFormatItem-h": "ah時"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/gregorian.js b/dojo/cldr/nls/zh-hant/gregorian.js
index e82332c..94ce4e1 100644
--- a/dojo/cldr/nls/zh-hant/gregorian.js
+++ b/dojo/cldr/nls/zh-hant/gregorian.js
@@ -1,14 +1,42 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-weekday": "週天",
 	"dateFormatItem-yQQQ": "y年QQQ",
-	"dateFormatItem-yMEd": "yyyy/M/d(EEE)",
-	"dateFormatItem-MMMEd": "MMMd日E",
+	"dateFormatItem-yMEd": "y/M/d(E)",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-MMMEd": "M月d日E",
 	"eraNarrow": [
 		"西元前",
 		"西元"
 	],
+	"dateFormatItem-yMM": "y-MM",
+	"dayPeriods-format-wide-earlyMorning": "清晨",
+	"dayPeriods-format-wide-morning": "上午",
+	"days-format-short": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
 	"dateFormat-long": "y年M月d日",
 	"months-format-wide": [
 		"1月",
@@ -28,8 +56,11 @@ define(
 	"dayPeriods-format-wide-pm": "下午",
 	"dateFormat-full": "y年M月d日EEEE",
 	"dateFormatItem-Md": "M/d",
+	"dayPeriods-format-narrow-midDay": "中午",
+	"dayPeriods-format-wide-noon": "中午",
+	"dateFormatItem-yMd": "y/M/d",
 	"field-era": "年代",
-	"dateFormatItem-yM": "yyyy/M",
+	"dateFormatItem-yM": "y/M",
 	"months-standAlone-wide": [
 		"1月",
 		"2月",
@@ -51,10 +82,10 @@ define(
 		"第3季",
 		"第4季"
 	],
+	"dateFormatItem-yQQQQ": "y年QQQQ",
 	"timeFormat-long": "zah時mm分ss秒",
 	"field-year": "年",
 	"dateFormatItem-yMMM": "y年M月",
-	"dateFormatItem-yQ": "y年QQQ",
 	"field-hour": "小時",
 	"dateFormatItem-MMdd": "MM/dd",
 	"months-format-abbr": [
@@ -71,26 +102,26 @@ define(
 		"11月",
 		"12月"
 	],
-	"dateFormatItem-yyQ": "yy年第Q季度",
 	"timeFormat-full": "zzzzah時mm分ss秒",
+	"dayPeriods-format-narrow-morning": "上午",
 	"field-day-relative+0": "今天",
 	"field-day-relative+1": "明天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
 	"field-day-relative+2": "後天",
 	"dateFormatItem-H": "H時",
-	"field-day-relative+3": "大後天",
 	"months-standAlone-abbr": [
-		"一月",
-		"二月",
-		"三月",
-		"四月",
-		"五月",
-		"六月",
-		"七月",
-		"八月",
-		"九月",
-		"十月",
-		"十一月",
-		"十二月"
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
 	],
 	"quarters-format-abbr": [
 		"1季",
@@ -104,17 +135,8 @@ define(
 		"第3季",
 		"第4季"
 	],
+	"dateFormatItem-Gy": "Gy年",
 	"dateFormatItem-M": "M月",
-	"days-standAlone-wide": [
-		"星期日",
-		"星期一",
-		"星期二",
-		"星期三",
-		"星期四",
-		"星期五",
-		"星期六"
-	],
-	"dateFormatItem-yyMMM": "yy年MMM",
 	"timeFormat-medium": "ah:mm:ss",
 	"dateFormatItem-Hm": "H:mm",
 	"quarters-standAlone-abbr": [
@@ -138,16 +160,25 @@ define(
 		"週五",
 		"週六"
 	],
+	"dayPeriods-format-wide-night": "晚上",
 	"dateFormatItem-d": "d日",
 	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "昨天",
 	"dateFormatItem-h": "ah時",
 	"dateTimeFormat-long": "{1}{0}",
+	"dayPeriods-format-narrow-am": "上午",
 	"field-day-relative+-2": "前天",
-	"field-day-relative+-3": "大前天",
-	"dateFormatItem-MMMd": "MMMd日",
+	"dateFormatItem-MMMd": "M月d日",
+	"dayPeriods-format-wide-midDay": "中午",
 	"dateFormatItem-MEd": "M/d(E)",
 	"dateTimeFormat-full": "{1}{0}",
+	"dateFormatItem-yMMMM": "y年M月",
 	"field-day": "日",
 	"days-format-wide": [
 		"星期日",
@@ -158,7 +189,7 @@ define(
 		"星期五",
 		"星期六"
 	],
-	"field-zone": "區域",
+	"field-zone": "時區",
 	"dateFormatItem-y": "y年",
 	"months-standAlone-narrow": [
 		"1",
@@ -174,8 +205,11 @@ define(
 		"11",
 		"12"
 	],
-	"dateFormatItem-yyMM": "yy-MM",
+	"field-year-relative+-1": "去年",
+	"dayPeriods-format-narrow-night": "晚上",
+	"field-month-relative+-1": "上個月",
 	"dateFormatItem-hm": "ah:mm",
+	"dayPeriods-format-narrow-weeHours": "凌晨",
 	"days-format-abbr": [
 		"週日",
 		"週一",
@@ -185,21 +219,12 @@ define(
 		"週五",
 		"週六"
 	],
-	"dateFormatItem-yMMMd": "y年MMMd日",
+	"dateFormatItem-yMMMd": "y年M月d日",
 	"eraNames": [
 		"西元前",
 		"西元"
 	],
-	"days-format-narrow": [
-		"日",
-		"一",
-		"二",
-		"三",
-		"四",
-		"五",
-		"六"
-	],
-	"field-month": "月",
+	"dayPeriods-format-narrow-earlyMorning": "清晨",
 	"days-standAlone-narrow": [
 		"日",
 		"一",
@@ -210,19 +235,31 @@ define(
 		"六"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "月",
 	"dayPeriods-format-wide-am": "上午",
-	"dateFormatItem-MMMMdd": "MMMMdd日",
-	"dateFormat-short": "yy/M/d",
+	"dateFormatItem-MMMMdd": "M月dd日",
+	"dayPeriods-format-wide-weeHours": "凌晨",
+	"dateFormat-short": "y/M/d",
+	"dayPeriods-format-wide-afternoon": "下午",
+	"dayPeriods-format-narrow-afternoon": "下午",
+	"dayPeriods-format-narrow-noon": "中午",
 	"field-second": "秒",
-	"dateFormatItem-yMMMEd": "y年M月d日EEE",
-	"dateFormatItem-Ed": "d日(E)",
+	"dateFormatItem-yMMMEd": "y年M月d日E",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下個月",
+	"dateFormatItem-Ed": "d日(E)",
 	"field-week": "週",
-	"dateFormat-medium": "yyyy/M/d",
-	"dateFormatItem-yyyyM": "y年M月",
+	"dateFormat-medium": "y/M/d",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "上週",
+	"field-year-relative+1": "明年",
+	"dayPeriods-format-narrow-pm": "下午",
 	"dateTimeFormat-short": "{1} {0}",
 	"dateFormatItem-Hms": "H:mm:ss",
 	"dateFormatItem-hms": "ah:mm:ss",
-	"dateFormatItem-yyyy": "y年"
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"field-week-relative+0": "本週",
+	"field-week-relative+1": "下週"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/hebrew.js b/dojo/cldr/nls/zh-hant/hebrew.js
new file mode 100644
index 0000000..2eb4c6d
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/hebrew.js
@@ -0,0 +1,241 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"field-weekday": "週天",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"eraNarrow": [
+		"創世紀元"
+	],
+	"days-format-short": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormat-long": "Gy年M月d日",
+	"months-format-wide": [
+		"提斯利月",
+		"瑪西班月",
+		"基斯流月",
+		"提別月",
+		"細罷特月",
+		"亞達月 I",
+		"亞達月",
+		"尼散月",
+		"以珥月",
+		"西彎月",
+		"搭模斯月",
+		"埃波月",
+		"以祿月"
+	],
+	"dateFormatItem-yyyyQQQ": "Gy年QQQ",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "Gy/M/d(E)",
+	"dateFormatItem-Md": "M/d",
+	"field-era": "年代",
+	"months-standAlone-wide": [
+		"提斯利月",
+		"瑪西班月",
+		"基斯流月",
+		"提別月",
+		"細罷特月",
+		"亞達月 I",
+		"亞達月",
+		"尼散月",
+		"以珥月",
+		"西彎月",
+		"搭模斯月",
+		"埃波月",
+		"以祿月"
+	],
+	"timeFormat-short": "ah:mm",
+	"quarters-format-wide": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"timeFormat-long": "zah時mm分ss秒",
+	"field-year": "年",
+	"field-hour": "小時",
+	"months-format-abbr-leap": "亞達月 II",
+	"months-format-abbr": [
+		"提斯利月",
+		"瑪西班月",
+		"基斯流月",
+		"提別月",
+		"細罷特月",
+		"亞達月 I",
+		"亞達月",
+		"尼散月",
+		"以珥月",
+		"西彎月",
+		"搭模斯月",
+		"埃波月",
+		"以祿月"
+	],
+	"timeFormat-full": "zzzzah時mm分ss秒",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-day-relative+2": "後天",
+	"dateFormatItem-H": "H時",
+	"months-standAlone-abbr": [
+		"提斯利月",
+		"瑪西班月",
+		"基斯流月",
+		"提別月",
+		"細罷特月",
+		"亞達月 I",
+		"亞達月",
+		"尼散月",
+		"以珥月",
+		"西彎月",
+		"搭模斯月",
+		"埃波月",
+		"以祿月"
+	],
+	"quarters-format-abbr": [
+		"1季",
+		"2季",
+		"3季",
+		"4季"
+	],
+	"quarters-standAlone-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
+	],
+	"dateFormatItem-Gy": "Gy年",
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-M": "M月",
+	"days-standAlone-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"months-standAlone-wide-leap": "亞達月 II",
+	"timeFormat-medium": "ah:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
+	],
+	"eraAbbr": [
+		"創世紀元"
+	],
+	"field-minute": "分鐘",
+	"field-dayperiod": "上午/下午",
+	"days-standAlone-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormatItem-d": "d日",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-h": "ah時",
+	"dateTimeFormat-long": "{1}{0}",
+	"dayPeriods-format-narrow-am": "上午",
+	"field-day-relative+-2": "前天",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day": "日",
+	"days-format-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"field-zone": "時區",
+	"months-standAlone-abbr-leap": "亞達月 II",
+	"dateFormatItem-y": "Gy年",
+	"field-year-relative+-1": "去年",
+	"field-month-relative+-1": "上個月",
+	"dateFormatItem-hm": "ah:mm",
+	"days-format-abbr": [
+		"週日",
+		"週一",
+		"週二",
+		"週三",
+		"週四",
+		"週五",
+		"週六"
+	],
+	"eraNames": [
+		"創世紀元"
+	],
+	"days-format-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormat-short": "Gy/M/d",
+	"field-second": "秒",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下個月",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-week": "週",
+	"dateFormat-medium": "Gy/M/d",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "上週",
+	"dateFormatItem-yyyyM": "Gy/M",
+	"field-year-relative+1": "明年",
+	"dayPeriods-format-narrow-pm": "下午",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"months-format-wide-leap": "亞達月 II",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-yyyy": "Gy年",
+	"field-week-relative+0": "本週",
+	"field-week-relative+1": "下週"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/indian.js b/dojo/cldr/nls/zh-hant/indian.js
new file mode 100644
index 0000000..ef59c71
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/indian.js
@@ -0,0 +1,118 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒",
+	"field-year-relative+-1": "去年",
+	"field-week": "週",
+	"field-month-relative+-1": "上個月",
+	"field-day-relative+-1": "昨天",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "前天",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"months-standAlone-wide": [
+		"制檀邏月",
+		"吠舍佉月",
+		"逝瑟吒月",
+		"頞沙荼月",
+		"室羅伐拏月",
+		"婆羅鉢陀月",
+		"頞涇縛庚闍月",
+		"迦剌底迦月",
+		"末伽始羅月",
+		"報沙月",
+		"磨祛月",
+		"頗勒窶拏月"
+	],
+	"field-year": "年",
+	"field-week-relative+0": "本週",
+	"months-standAlone-abbr": [
+		"制檀邏月",
+		"吠舍佉月",
+		"逝瑟吒月",
+		"頞沙荼月",
+		"室羅伐拏月",
+		"婆羅鉢陀月",
+		"頞涇縛庚闍月",
+		"迦剌底迦月",
+		"末伽始羅月",
+		"報沙月",
+		"磨祛月",
+		"頗勒窶拏月"
+	],
+	"field-week-relative+1": "下週",
+	"field-minute": "分鐘",
+	"field-week-relative+-1": "上週",
+	"field-day-relative+0": "今天",
+	"field-hour": "小時",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "後天",
+	"field-day": "日",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下個月",
+	"field-dayperiod": "上午/下午",
+	"field-month": "月",
+	"months-format-wide": [
+		"制檀邏月",
+		"吠舍佉月",
+		"逝瑟吒月",
+		"頞沙荼月",
+		"室羅伐拏月",
+		"婆羅鉢陀月",
+		"頞涇縛庚闍月",
+		"迦剌底迦月",
+		"末伽始羅月",
+		"報沙月",
+		"磨祛月",
+		"頗勒窶拏月"
+	],
+	"field-era": "年代",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"months-format-abbr": [
+		"制檀邏月",
+		"吠舍佉月",
+		"逝瑟吒月",
+		"頞沙荼月",
+		"室羅伐拏月",
+		"婆羅鉢陀月",
+		"頞涇縛庚闍月",
+		"迦剌底迦月",
+		"末伽始羅月",
+		"報沙月",
+		"磨祛月",
+		"頗勒窶拏月"
+	],
+	"eraAbbr": [
+		"印度曆"
+	],
+	"field-weekday": "週天",
+	"field-zone": "時區"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/islamic.js b/dojo/cldr/nls/zh-hant/islamic.js
index 5d43414..6f4b7aa 100644
--- a/dojo/cldr/nls/zh-hant/islamic.js
+++ b/dojo/cldr/nls/zh-hant/islamic.js
@@ -1,22 +1,36 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "yyyy/M",
-	"dateFormatItem-yQ": "y年QQQ",
-	"dayPeriods-format-wide-pm": "下午",
-	"dateFormatItem-MMMEd": "MMMd日E",
-	"dateTimeFormat-full": "{1}{0}",
-	"dateFormatItem-hms": "ah:mm:ss",
-	"dateFormatItem-yQQQ": "y年QQQ",
-	"dateFormatItem-MMdd": "MM/dd",
-	"dateFormatItem-MMM": "LLL",
-	"dayPeriods-format-wide-am": "上午",
-	"dateFormatItem-y": "y年",
-	"timeFormat-full": "zzzzah時mm分ss秒",
-	"dateFormatItem-yyyy": "Gy年",
-	"dateFormatItem-Ed": "d日(E)",
-	"dateFormatItem-yMMM": "y年M月",
-	"days-standAlone-narrow": [
+	"days-standAlone-short": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "週天",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"eraNarrow": [
+		"伊斯蘭曆"
+	],
+	"days-format-short": [
 		"日",
 		"一",
 		"二",
@@ -26,52 +40,142 @@ define(
 		"六"
 	],
 	"dateFormat-long": "Gy年M月d日",
-	"timeFormat-medium": "ah:mm:ss",
-	"dateFormatItem-Hm": "H:mm",
-	"dateFormat-medium": "Gy/M/d",
-	"dateFormatItem-Hms": "H:mm:ss",
-	"dateFormatItem-ms": "mm:ss",
-	"dateTimeFormat-long": "{1}{0}",
-	"dateFormatItem-yyyyMd": "Gy/M/d",
-	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
-	"dateFormatItem-MMMd": "MMMd日",
-	"timeFormat-long": "zah時mm分ss秒",
+	"months-format-wide": [
+		"穆哈蘭姆月",
+		"色法爾月",
+		"賴比月 I",
+		"賴比月 II",
+		"主馬達月 I",
+		"主馬達月 II",
+		"賴哲卜月",
+		"舍爾邦月",
+		"賴買丹月",
+		"閃瓦魯月",
+		"都爾喀爾德月",
+		"都爾黑哲月"
+	],
+	"dateFormatItem-yyyyQQQ": "Gy年QQQ",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "Gy/M/d(E)",
+	"dateFormatItem-Md": "M/d",
+	"field-era": "年代",
+	"months-standAlone-wide": [
+		"穆哈蘭姆月",
+		"色法爾月",
+		"賴比月 I",
+		"賴比月 II",
+		"主馬達月 I",
+		"主馬達月 II",
+		"賴哲卜月",
+		"舍爾邦月",
+		"賴買丹月",
+		"閃瓦魯月",
+		"都爾喀爾德月",
+		"都爾黑哲月"
+	],
 	"timeFormat-short": "ah:mm",
+	"quarters-format-wide": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"timeFormat-long": "zah時mm分ss秒",
+	"field-year": "年",
+	"field-hour": "小時",
+	"months-format-abbr": [
+		"穆哈蘭姆月",
+		"色法爾月",
+		"賴比月 I",
+		"賴比月 II",
+		"主馬達月 I",
+		"主馬達月 II",
+		"賴哲卜月",
+		"舍爾邦月",
+		"賴買丹月",
+		"閃瓦魯月",
+		"都爾喀爾德月",
+		"都爾黑哲月"
+	],
+	"timeFormat-full": "zzzzah時mm分ss秒",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-day-relative+2": "後天",
 	"dateFormatItem-H": "H時",
+	"months-standAlone-abbr": [
+		"穆哈蘭姆月",
+		"色法爾月",
+		"賴比月 I",
+		"賴比月 II",
+		"主馬達月 I",
+		"主馬達月 II",
+		"賴哲卜月",
+		"舍爾邦月",
+		"賴買丹月",
+		"閃瓦魯月",
+		"都爾喀爾德月",
+		"都爾黑哲月"
+	],
 	"quarters-format-abbr": [
 		"1季",
 		"2季",
 		"3季",
 		"4季"
 	],
-	"days-format-abbr": [
-		"週日",
-		"週一",
-		"週二",
-		"週三",
-		"週四",
-		"週五",
-		"週六"
+	"quarters-standAlone-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
 	],
-	"dateFormatItem-MMMMdd": "MMMMdd日",
+	"dateFormatItem-Gy": "Gy年",
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
 	"dateFormatItem-M": "M月",
-	"dateFormatItem-MEd": "M/d(E)",
-	"dateFormatItem-hm": "ah:mm",
-	"dateFormat-short": "Gy/M/d",
-	"dateFormatItem-yyyyM": "Gy/M",
-	"dateFormatItem-yMMMEd": "y年M月d日EEE",
-	"dateFormat-full": "Gy年M月d日EEEE",
-	"dateFormatItem-Md": "M/d",
-	"dateFormatItem-yyyyQ": "Gy年QQQ",
-	"dateFormatItem-yMEd": "yyyy/M/d(EEE)",
+	"days-standAlone-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
 	"dateFormatItem-yyyyMMM": "Gy年M月",
-	"dateFormatItem-d": "d日",
-	"quarters-format-wide": [
-		"第1季",
-		"第2季",
-		"第3季",
-		"第4季"
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"timeFormat-medium": "ah:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
+	],
+	"eraAbbr": [
+		"伊斯蘭曆"
 	],
+	"field-minute": "分鐘",
+	"field-dayperiod": "上午/下午",
+	"days-standAlone-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormatItem-d": "d日",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-h": "ah時",
+	"dateTimeFormat-long": "{1}{0}",
+	"dayPeriods-format-narrow-am": "上午",
+	"field-day-relative+-2": "前天",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day": "日",
 	"days-format-wide": [
 		"星期日",
 		"星期一",
@@ -81,7 +185,77 @@ define(
 		"星期五",
 		"星期六"
 	],
-	"dateFormatItem-h": "ah時"
+	"field-zone": "時區",
+	"dateFormatItem-y": "Gy年",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year-relative+-1": "去年",
+	"field-month-relative+-1": "上個月",
+	"dateFormatItem-hm": "ah:mm",
+	"days-format-abbr": [
+		"週日",
+		"週一",
+		"週二",
+		"週三",
+		"週四",
+		"週五",
+		"週六"
+	],
+	"eraNames": [
+		"伊斯蘭曆"
+	],
+	"days-format-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormat-short": "Gy/M/d",
+	"field-second": "秒",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下個月",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-week": "週",
+	"dateFormat-medium": "Gy/M/d",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "上週",
+	"dateFormatItem-yyyyM": "Gy/M",
+	"field-year-relative+1": "明年",
+	"dayPeriods-format-narrow-pm": "下午",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-yyyy": "Gy年",
+	"field-week-relative+0": "本週",
+	"field-week-relative+1": "下週"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/japanese.js b/dojo/cldr/nls/zh-hant/japanese.js
new file mode 100644
index 0000000..a781386
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/japanese.js
@@ -0,0 +1,302 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
+	"field-dayperiod": "上午/下午",
+	"field-minute": "分鐘",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"field-day-relative+-2": "前天",
+	"field-weekday": "週天",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"field-era": "年代",
+	"dateFormatItem-Gy": "Gy年",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-hour": "小時",
+	"dateFormatItem-y": "Gy年",
+	"dateFormatItem-yyyy": "Gy年",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"eraAbbr": [
+		"大化",
+		"白雉",
+		"白鳳",
+		"朱鳥",
+		"大寶",
+		"慶雲",
+		"和銅",
+		"靈龜",
+		"養老",
+		"神龜",
+		"天平",
+		"天平感寶",
+		"天平勝寶",
+		"天平寶字",
+		"天平神護",
+		"神護景雲",
+		"寶龜",
+		"天應",
+		"延曆",
+		"大同",
+		"弘仁",
+		"天長",
+		"承和",
+		"嘉祥",
+		"仁壽",
+		"齊衡",
+		"天安",
+		"貞觀",
+		"元慶",
+		"仁和",
+		"寬平",
+		"昌泰",
+		"延喜",
+		"延長",
+		"承平",
+		"天慶",
+		"天曆",
+		"天德",
+		"應和",
+		"康保",
+		"安和",
+		"天祿",
+		"天延",
+		"貞元",
+		"天元",
+		"永觀",
+		"寬和",
+		"永延",
+		"永祚",
+		"正曆",
+		"長德",
+		"長保",
+		"寬弘",
+		"長和",
+		"寬仁",
+		"治安",
+		"萬壽",
+		"長元",
+		"長曆",
+		"長久",
+		"寬德",
+		"永承",
+		"天喜",
+		"康平",
+		"治曆",
+		"延久",
+		"承保",
+		"承曆",
+		"永保",
+		"應德",
+		"寬治",
+		"嘉保",
+		"永長",
+		"承德",
+		"康和",
+		"長治",
+		"嘉承",
+		"天仁",
+		"天永",
+		"永久",
+		"元永",
+		"保安",
+		"天治",
+		"大治",
+		"天承",
+		"長承",
+		"保延",
+		"永治",
+		"康治",
+		"天養",
+		"久安",
+		"仁平",
+		"久壽",
+		"保元",
+		"平治",
+		"永曆",
+		"應保",
+		"長寬",
+		"永萬",
+		"仁安",
+		"嘉應",
+		"承安",
+		"安元",
+		"治承",
+		"養和",
+		"壽永",
+		"元曆",
+		"文治",
+		"建久",
+		"正治",
+		"建仁",
+		"元久",
+		"建永",
+		"承元",
+		"建曆",
+		"建保",
+		"承久",
+		"貞應",
+		"元仁",
+		"嘉祿",
+		"安貞",
+		"寬喜",
+		"貞永",
+		"天福",
+		"文曆",
+		"嘉禎",
+		"曆仁",
+		"延應",
+		"仁治",
+		"寬元",
+		"寶治",
+		"建長",
+		"康元",
+		"正嘉",
+		"正元",
+		"文應",
+		"弘長",
+		"文永",
+		"建治",
+		"弘安",
+		"正應",
+		"永仁",
+		"正安",
+		"乾元",
+		"嘉元",
+		"德治",
+		"延慶",
+		"應長",
+		"正和",
+		"文保",
+		"元應",
+		"元亨",
+		"正中",
+		"嘉曆",
+		"元德",
+		"元弘",
+		"建武",
+		"延元",
+		"興國",
+		"正平",
+		"建德",
+		"文中",
+		"天授",
+		"康曆",
+		"弘和",
+		"元中",
+		"至德",
+		"嘉慶",
+		"康應",
+		"明德",
+		"應永",
+		"正長",
+		"永享",
+		"嘉吉",
+		"文安",
+		"寶德",
+		"享德",
+		"康正",
+		"長祿",
+		"寬正",
+		"文正",
+		"應仁",
+		"文明",
+		"長享",
+		"延德",
+		"明應",
+		"文龜",
+		"永正",
+		"大永",
+		"享祿",
+		"天文",
+		"弘治",
+		"永祿",
+		"元龜",
+		"天正",
+		"文祿",
+		"慶長",
+		"元和",
+		"寬永",
+		"正保",
+		"慶安",
+		"承應",
+		"明曆",
+		"萬治",
+		"寬文",
+		"延寶",
+		"天和",
+		"貞享",
+		"元祿",
+		"寶永",
+		"正德",
+		"享保",
+		"元文",
+		"寬保",
+		"延享",
+		"寬延",
+		"寶曆",
+		"明和",
+		"安永",
+		"天明",
+		"寬政",
+		"享和",
+		"文化",
+		"文政",
+		"天保",
+		"弘化",
+		"嘉永",
+		"安政",
+		"萬延",
+		"文久",
+		"元治",
+		"慶應",
+		"明治",
+		"大正",
+		"昭和",
+		"平成"
+	],
+	"field-day-relative+2": "後天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-zone": "時區",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "上週",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"field-year-relative+-1": "去年",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"field-year": "年",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "週",
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"dateFormatItem-yyyyMEd": "Gy/M/d(E)",
+	"dateFormatItem-MMMd": "MMM d",
+	"field-week-relative+0": "本週",
+	"field-week-relative+1": "下週",
+	"field-month-relative+0": "本月",
+	"dateFormatItem-H": "H時",
+	"field-month": "月",
+	"field-month-relative+1": "下個月",
+	"dateFormatItem-M": "M月",
+	"field-second": "秒",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"field-day": "日",
+	"dateFormatItem-yyyyQQQ": "Gy年QQQ",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateFormatItem-hm": "ah:mm",
+	"dateFormatItem-yyyyM": "Gy/M",
+	"dateFormatItem-Md": "M/d",
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-d": "d日",
+	"field-month-relative+-1": "上個月",
+	"dateFormatItem-h": "ah時"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/number.js b/dojo/cldr/nls/zh-hant/number.js
index 376cdeb..90f3078 100644
--- a/dojo/cldr/nls/zh-hant/number.js
+++ b/dojo/cldr/nls/zh-hant/number.js
@@ -1,7 +1,22 @@
 define(
 //begin v1.x content
 {
-	"currencyFormat": "¤#,##0.00"
+	"group": ",",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"minusSign": "-",
+	"decimal": ".",
+	"nan": "非數值",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "¤#,##0.00",
+	"plusSign": "+",
+	"decimalFormat-long": "000兆",
+	"decimalFormat-short": "000T"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/persian.js b/dojo/cldr/nls/zh-hant/persian.js
new file mode 100644
index 0000000..477d2ac
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/persian.js
@@ -0,0 +1,261 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "週天",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"eraNarrow": [
+		"伊朗曆"
+	],
+	"days-format-short": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormat-long": "Gy年M月d日",
+	"months-format-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"dateFormatItem-yyyyQQQ": "Gy年QQQ",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "Gy/M/d(E)",
+	"dateFormatItem-Md": "M/d",
+	"field-era": "年代",
+	"months-standAlone-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"timeFormat-short": "ah:mm",
+	"quarters-format-wide": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"timeFormat-long": "zah時mm分ss秒",
+	"field-year": "年",
+	"field-hour": "小時",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"timeFormat-full": "zzzzah時mm分ss秒",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-day-relative+2": "後天",
+	"dateFormatItem-H": "H時",
+	"months-standAlone-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"quarters-format-abbr": [
+		"1季",
+		"2季",
+		"3季",
+		"4季"
+	],
+	"quarters-standAlone-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
+	],
+	"dateFormatItem-Gy": "Gy年",
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-M": "M月",
+	"days-standAlone-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"timeFormat-medium": "ah:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
+	],
+	"eraAbbr": [
+		"伊朗曆"
+	],
+	"field-minute": "分鐘",
+	"field-dayperiod": "上午/下午",
+	"days-standAlone-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormatItem-d": "d日",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-h": "ah時",
+	"dateTimeFormat-long": "{1}{0}",
+	"dayPeriods-format-narrow-am": "上午",
+	"field-day-relative+-2": "前天",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day": "日",
+	"days-format-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"field-zone": "時區",
+	"dateFormatItem-y": "Gy年",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year-relative+-1": "去年",
+	"field-month-relative+-1": "上個月",
+	"dateFormatItem-hm": "ah:mm",
+	"days-format-abbr": [
+		"週日",
+		"週一",
+		"週二",
+		"週三",
+		"週四",
+		"週五",
+		"週六"
+	],
+	"eraNames": [
+		"伊朗曆"
+	],
+	"days-format-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormat-short": "Gy/M/d",
+	"field-second": "秒",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下個月",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-week": "週",
+	"dateFormat-medium": "Gy/M/d",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "上週",
+	"dateFormatItem-yyyyM": "Gy/M",
+	"field-year-relative+1": "明年",
+	"dayPeriods-format-narrow-pm": "下午",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-yyyy": "Gy年",
+	"field-week-relative+0": "本週",
+	"field-week-relative+1": "下週"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/roc.js b/dojo/cldr/nls/zh-hant/roc.js
new file mode 100644
index 0000000..aef9b51
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒",
+	"field-year-relative+-1": "去年",
+	"field-week": "週",
+	"field-month-relative+-1": "上個月",
+	"field-day-relative+-1": "昨天",
+	"field-day-relative+-2": "前天",
+	"field-year": "年",
+	"field-week-relative+0": "本週",
+	"field-week-relative+1": "下週",
+	"field-minute": "分鐘",
+	"field-week-relative+-1": "上週",
+	"field-day-relative+0": "今天",
+	"field-hour": "小時",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "後天",
+	"field-day": "日",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下個月",
+	"field-dayperiod": "上午/下午",
+	"field-month": "月",
+	"field-era": "年代",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"eraAbbr": [
+		"民國前",
+		"民國"
+	],
+	"field-weekday": "週天",
+	"field-zone": "時區"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hk/currency.js b/dojo/cldr/nls/zh-hk/currency.js
index 0e07210..974545a 100644
--- a/dojo/cldr/nls/zh-hk/currency.js
+++ b/dojo/cldr/nls/zh-hk/currency.js
@@ -2,12 +2,14 @@ define(
 //begin v1.x content
 {
 	"HKD_displayName": "港幣",
-	"HKD_symbol": "HK$",
+	"JPY_symbol": "¥",
 	"CAD_displayName": "加幣",
 	"CNY_displayName": "人民幣",
 	"USD_symbol": "$",
 	"AUD_displayName": "澳幣",
 	"JPY_displayName": "日圓",
+	"$locale": "zh-hant-hk",
+	"USD_displayName": "美金",
 	"GBP_displayName": "英鎊",
 	"EUR_displayName": "歐元"
 }
diff --git a/dojo/cldr/nls/zh-hk/gregorian.js b/dojo/cldr/nls/zh-hk/gregorian.js
index ff70fea..b327180 100644
--- a/dojo/cldr/nls/zh-hk/gregorian.js
+++ b/dojo/cldr/nls/zh-hk/gregorian.js
@@ -1,85 +1,84 @@
 define(
 //begin v1.x content
 {
-	"dateFormatItem-yM": "yyyy/M",
-	"field-minute": "分鐘",
-	"eraNames": [
-		"西元前",
-		"西元"
-	],
-	"field-weekday": "週天",
-	"dateFormatItem-MMdd": "MM/dd",
-	"field-day-relative+-3": "大前天",
-	"months-standAlone-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
-	],
-	"dateTimeFormat-short": "{1} {0}",
-	"field-era": "年代",
-	"field-hour": "小時",
-	"dateTimeFormat-medium": "{1} {0}",
-	"quarters-standAlone-abbr": [
+	"quarters-standAlone-wide": [
 		"第1季",
 		"第2季",
 		"第3季",
 		"第4季"
 	],
-	"timeFormat-full": "zzzzah時mm分ss秒",
-	"dateFormatItem-Ed": "d日(E)",
-	"dateFormatItem-yMMM": "y年M月",
-	"eraAbbr": [
-		"西元前",
-		"西元"
-	],
-	"field-day-relative+2": "後天",
-	"field-day-relative+3": "大後天",
-	"dateFormat-long": "y年M月d日",
-	"timeFormat-medium": "ah:mm:ss",
-	"field-zone": "區域",
-	"dateFormat-medium": "yyyy/M/d",
-	"quarters-standAlone-wide": [
+	"quarters-format-abbr": [
 		"第1季",
 		"第2季",
 		"第3季",
 		"第4季"
 	],
-	"field-week": "週",
-	"timeFormat-long": "zah時mm分ss秒",
-	"dateFormatItem-H": "H時",
-	"quarters-format-abbr": [
+	"dateFormat-medium": "y/M/d",
+	"$locale": "zh-hant-hk",
+	"quarters-standAlone-abbr": [
 		"第1季",
 		"第2季",
 		"第3季",
 		"第4季"
 	],
-	"field-second": "秒",
 	"dateFormatItem-MEd": "M/d(E)",
-	"dateFormat-short": "yy/M/d",
-	"dateFormatItem-yMMMEd": "y年M月d日EEE",
-	"dateFormat-full": "y年M月d日EEEE",
-	"dateFormatItem-Md": "M/d",
-	"dateFormatItem-yMEd": "yyyy/M/d(EEE)",
+	"dateFormatItem-yMEd": "y/M/d(E)",
+	"dateFormatItem-Hm": "H:mm",
+	"dateFormatItem-H": "H時",
+	"eraNarrow": [
+		"西元前",
+		"西元"
+	],
+	"timeFormat-full": "zzzzah時mm分ss秒",
+	"months-standAlone-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"eraNames": [
+		"西元前",
+		"西元"
+	],
+	"dateFormatItem-yQQQ": "y年QQQ",
+	"dateFormatItem-yMM": "y-MM",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormat-short": "y/M/d",
+	"months-format-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"timeFormat-long": "zah時mm分ss秒",
+	"eraAbbr": [
+		"西元前",
+		"西元"
+	],
+	"dateFormatItem-h": "ah時",
 	"quarters-format-wide": [
 		"第1季",
 		"第2季",
 		"第3季",
 		"第4季"
 	],
-	"eraNarrow": [
-		"西元前",
-		"西元"
-	],
-	"dateFormatItem-h": "ah時"
+	"dateFormatItem-Ed": "d日(E)"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hk/number.js b/dojo/cldr/nls/zh-hk/number.js
index 376cdeb..1c80fd4 100644
--- a/dojo/cldr/nls/zh-hk/number.js
+++ b/dojo/cldr/nls/zh-hk/number.js
@@ -1,7 +1,11 @@
 define(
 //begin v1.x content
 {
-	"currencyFormat": "¤#,##0.00"
+	"decimalFormat-long": "000兆",
+	"nan": "非數值",
+	"currencyFormat": "¤#,##0.00",
+	"$locale": "zh-hant-hk",
+	"decimalFormat-short": "000T"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-tw/currency.js b/dojo/cldr/nls/zh-tw/currency.js
index 0962c79..a197b17 100644
--- a/dojo/cldr/nls/zh-tw/currency.js
+++ b/dojo/cldr/nls/zh-tw/currency.js
@@ -1,14 +1,17 @@
 define(
 //begin v1.x content
 {
-	"USD_symbol": "$",
-	"EUR_displayName": "歐元",
 	"HKD_displayName": "港幣",
+	"JPY_symbol": "¥",
 	"CAD_displayName": "加幣",
+	"CNY_displayName": "人民幣",
+	"USD_symbol": "$",
+	"AUD_displayName": "澳幣",
 	"JPY_displayName": "日圓",
+	"$locale": "zh-hant-tw",
+	"USD_displayName": "美金",
 	"GBP_displayName": "英鎊",
-	"AUD_displayName": "澳幣",
-	"CNY_displayName": "人民幣"
+	"EUR_displayName": "歐元"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-tw/gregorian.js b/dojo/cldr/nls/zh-tw/gregorian.js
index 7f62583..43405fd 100644
--- a/dojo/cldr/nls/zh-tw/gregorian.js
+++ b/dojo/cldr/nls/zh-tw/gregorian.js
@@ -13,68 +13,72 @@ define(
 		"第3季",
 		"第4季"
 	],
-	"dateFormat-medium": "yyyy/M/d",
-	"field-second": "秒",
+	"dateFormat-medium": "y/M/d",
+	"$locale": "zh-hant-tw",
 	"quarters-standAlone-abbr": [
 		"第1季",
 		"第2季",
 		"第3季",
 		"第4季"
 	],
-	"dateFormatItem-MMdd": "MM/dd",
 	"dateFormatItem-MEd": "M/d(E)",
-	"dateFormatItem-yMEd": "yyyy/M/d(EEE)",
-	"field-week": "週",
+	"dateFormatItem-yMEd": "y/M/d(E)",
+	"dateFormatItem-Hm": "H:mm",
 	"dateFormatItem-H": "H時",
 	"eraNarrow": [
 		"西元前",
 		"西元"
 	],
-	"field-day-relative+-3": "大前天",
 	"timeFormat-full": "zzzzah時mm分ss秒",
-	"dateFormatItem-Md": "M/d",
-	"months-standAlone-narrow": [
-		"1",
-		"2",
-		"3",
-		"4",
-		"5",
-		"6",
-		"7",
-		"8",
-		"9",
-		"10",
-		"11",
-		"12"
+	"months-standAlone-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
 	],
 	"eraNames": [
 		"西元前",
 		"西元"
 	],
-	"field-minute": "分鐘",
-	"field-hour": "小時",
-	"field-day-relative+2": "後天",
-	"field-day-relative+3": "大後天",
-	"dateFormat-short": "yy/M/d",
-	"dateFormatItem-yMMMEd": "y年M月d日EEE",
-	"field-era": "年代",
-	"dateFormatItem-yM": "yyyy/M",
+	"dateFormatItem-yQQQ": "y年QQQ",
+	"dateFormatItem-yMM": "y-MM",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormat-short": "y/M/d",
+	"months-format-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
 	"timeFormat-long": "zah時mm分ss秒",
 	"eraAbbr": [
 		"西元前",
 		"西元"
 	],
 	"dateFormatItem-h": "ah時",
-	"dateFormatItem-yMMM": "y年M月",
 	"quarters-format-wide": [
 		"第1季",
 		"第2季",
 		"第3季",
 		"第4季"
 	],
-	"field-weekday": "週天",
-	"field-zone": "區域",
-	"dateFormatItem-Ed": "d日(E)"
+	"dateFormatItem-Ed": "d日(E)"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-tw/number.js b/dojo/cldr/nls/zh-tw/number.js
new file mode 100644
index 0000000..1c0ad32
--- /dev/null
+++ b/dojo/cldr/nls/zh-tw/number.js
@@ -0,0 +1,11 @@
+define(
+//begin v1.x content
+{
+	"decimalFormat-long": "000兆",
+	"nan": "非數值",
+	"currencyFormat": "¤#,##0.00",
+	"$locale": "zh-hant-tw",
+	"decimalFormat-short": "000T"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/buddhist.js b/dojo/cldr/nls/zh/buddhist.js
new file mode 100644
index 0000000..649bbf5
--- /dev/null
+++ b/dojo/cldr/nls/zh/buddhist.js
@@ -0,0 +1,231 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"field-weekday": "星期",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"eraNarrow": [
+		"佛历"
+	],
+	"days-format-short": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormat-long": "Gy年M月d日",
+	"months-format-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"dateFormatItem-yyyyQQQ": "Gy年第Q季度",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "Gy-M-d(E)",
+	"dateFormatItem-Md": "M-d",
+	"field-era": "时期",
+	"months-standAlone-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"timeFormat-short": "ah:mm",
+	"quarters-format-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
+	],
+	"timeFormat-long": "zah:mm:ss",
+	"field-year": "年",
+	"field-hour": "小时",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"timeFormat-full": "zzzzah:mm:ss",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-day-relative+2": "后天",
+	"dateFormatItem-H": "H时",
+	"months-standAlone-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"quarters-format-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
+	],
+	"quarters-standAlone-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
+	],
+	"dateFormatItem-Gy": "Gy年",
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-M": "M月",
+	"days-standAlone-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"timeFormat-medium": "ah:mm:ss",
+	"quarters-standAlone-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
+	],
+	"eraAbbr": [
+		"佛历"
+	],
+	"field-minute": "分钟",
+	"field-dayperiod": "上午/下午",
+	"days-standAlone-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormatItem-d": "d日",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-h": "ah时",
+	"dateTimeFormat-long": "{1}{0}",
+	"dayPeriods-format-narrow-am": "上午",
+	"field-day-relative+-2": "前天",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M-dE",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day": "日",
+	"days-format-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"field-zone": "时区",
+	"dateFormatItem-y": "Gy年",
+	"field-year-relative+-1": "去年",
+	"field-month-relative+-1": "上个月",
+	"dateFormatItem-hm": "ah:mm",
+	"days-format-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"eraNames": [
+		"佛历"
+	],
+	"days-format-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormatItem-yyyyMd": "Gy-M-d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormat-short": "Gy-M-d",
+	"field-second": "秒钟",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下个月",
+	"dateFormatItem-Ed": "d日E",
+	"field-week": "周",
+	"dateFormat-medium": "Gy年M月d日",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "上周",
+	"dateFormatItem-yyyyM": "Gy-M",
+	"field-year-relative+1": "明年",
+	"dayPeriods-format-narrow-pm": "下午",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-yyyy": "Gy年",
+	"field-week-relative+0": "本周",
+	"field-week-relative+1": "下周"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/chinese.js b/dojo/cldr/nls/zh/chinese.js
new file mode 100644
index 0000000..f72832a
--- /dev/null
+++ b/dojo/cldr/nls/zh/chinese.js
@@ -0,0 +1,141 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "U年MMMd日E",
+	"field-dayperiod": "上午/下午",
+	"field-minute": "分钟",
+	"dateFormatItem-MMMEd": "MMMd日E",
+	"field-day-relative+-1": "昨天",
+	"field-day-relative+-2": "前天",
+	"field-weekday": "星期",
+	"months-standAlone-narrow": [
+		"正",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六",
+		"七",
+		"八",
+		"九",
+		"十",
+		"十一",
+		"十二"
+	],
+	"field-era": "时期",
+	"dateFormatItem-Gy": "U年",
+	"field-hour": "小时",
+	"dateFormatItem-y": "U年",
+	"dateFormatItem-yyyy": "U年",
+	"months-standAlone-abbr": [
+		"正月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"dateFormatItem-Ed": "d日E",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "后天",
+	"dateFormatItem-GyMMMd": "U年MMMd日",
+	"dateFormat-long": "U年MMMd日",
+	"field-zone": "时区",
+	"field-week-relative+-1": "上周",
+	"dateFormat-medium": "U年MMMd日",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"dateFormatItem-yMd": "U年M月d日",
+	"field-year-relative+-1": "去年",
+	"field-year": "年",
+	"dateFormatItem-yyyyQQQQ": "U年QQQQ",
+	"months-standAlone-wide": [
+		"正月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"field-week": "周",
+	"dateFormatItem-yyyyMd": "U年M月d日",
+	"dateFormatItem-yyyyMMMd": "U年MMMd日",
+	"dateFormatItem-yyyyMEd": "U年M月d日,E",
+	"dateFormatItem-MMMd": "MMMd日",
+	"field-week-relative+0": "本周",
+	"field-week-relative+1": "下周",
+	"months-format-abbr": [
+		"正月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"field-month-relative+0": "本月",
+	"field-month": "月",
+	"field-month-relative+1": "下个月",
+	"dateFormatItem-M": "MMM",
+	"field-second": "秒钟",
+	"dateFormatItem-GyMMMEd": "U年MMMd日E",
+	"dateFormatItem-GyMMM": "U年MMM",
+	"field-day": "日",
+	"dateFormatItem-yyyyQQQ": "U年QQQQ",
+	"dateFormatItem-MEd": "M-dE",
+	"months-format-narrow": [
+		"正",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六",
+		"七",
+		"八",
+		"九",
+		"十",
+		"十一",
+		"十二"
+	],
+	"dateFormat-short": "U-M-d",
+	"dateFormatItem-yyyyM": "U年M月",
+	"dateFormat-full": "U年MMMd日EEEE",
+	"dateFormatItem-Md": "M-d",
+	"months-format-wide": [
+		"正月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"dateFormatItem-yyyyMMM": "U年MMM",
+	"dateFormatItem-d": "d日",
+	"field-month-relative+-1": "上个月"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/coptic.js b/dojo/cldr/nls/zh/coptic.js
new file mode 100644
index 0000000..3a9d396
--- /dev/null
+++ b/dojo/cldr/nls/zh/coptic.js
@@ -0,0 +1,121 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒钟",
+	"field-year-relative+-1": "去年",
+	"field-week": "周",
+	"field-month-relative+-1": "上个月",
+	"field-day-relative+-1": "昨天",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "前天",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"months-standAlone-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月",
+		"十三月"
+	],
+	"field-year": "年",
+	"field-week-relative+0": "本周",
+	"months-standAlone-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-week-relative+1": "下周",
+	"field-minute": "分钟",
+	"field-week-relative+-1": "上周",
+	"field-day-relative+0": "今天",
+	"field-hour": "小时",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "后天",
+	"field-day": "日",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下个月",
+	"field-dayperiod": "上午/下午",
+	"field-month": "月",
+	"months-format-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月",
+		"十三月"
+	],
+	"field-era": "时期",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-weekday": "星期",
+	"field-zone": "时区"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/currency.js b/dojo/cldr/nls/zh/currency.js
index 3bff810..33b5dee 100644
--- a/dojo/cldr/nls/zh/currency.js
+++ b/dojo/cldr/nls/zh/currency.js
@@ -3,13 +3,20 @@ define(
 {
 	"HKD_displayName": "港元",
 	"CHF_displayName": "瑞士法郎",
+	"JPY_symbol": "JP¥",
 	"CAD_displayName": "加拿大元",
+	"HKD_symbol": "HK$",
 	"CNY_displayName": "人民币",
+	"USD_symbol": "US$",
 	"AUD_displayName": "澳大利亚元",
 	"JPY_displayName": "日元",
+	"CAD_symbol": "CA$",
 	"USD_displayName": "美元",
+	"EUR_symbol": "€",
 	"CNY_symbol": "¥",
 	"GBP_displayName": "英镑",
+	"GBP_symbol": "£",
+	"AUD_symbol": "AU$",
 	"EUR_displayName": "欧元"
 }
 //end v1.x content
diff --git a/dojo/cldr/nls/zh/ethiopic.js b/dojo/cldr/nls/zh/ethiopic.js
new file mode 100644
index 0000000..3a9d396
--- /dev/null
+++ b/dojo/cldr/nls/zh/ethiopic.js
@@ -0,0 +1,121 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒钟",
+	"field-year-relative+-1": "去年",
+	"field-week": "周",
+	"field-month-relative+-1": "上个月",
+	"field-day-relative+-1": "昨天",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"field-day-relative+-2": "前天",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12",
+		"13"
+	],
+	"months-standAlone-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月",
+		"十三月"
+	],
+	"field-year": "年",
+	"field-week-relative+0": "本周",
+	"months-standAlone-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-week-relative+1": "下周",
+	"field-minute": "分钟",
+	"field-week-relative+-1": "上周",
+	"field-day-relative+0": "今天",
+	"field-hour": "小时",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "后天",
+	"field-day": "日",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下个月",
+	"field-dayperiod": "上午/下午",
+	"field-month": "月",
+	"months-format-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月",
+		"十三月"
+	],
+	"field-era": "时期",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"field-weekday": "星期",
+	"field-zone": "时区"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/generic.js b/dojo/cldr/nls/zh/generic.js
new file mode 100644
index 0000000..7afffbf
--- /dev/null
+++ b/dojo/cldr/nls/zh/generic.js
@@ -0,0 +1,69 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
+	"field-dayperiod": "上午/下午",
+	"field-minute": "分钟",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"field-day-relative+-2": "前天",
+	"field-weekday": "星期",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "Gy年",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "时期",
+	"field-hour": "小时",
+	"dateFormatItem-y": "Gy年",
+	"dateFormatItem-yyyy": "Gy年",
+	"dateFormatItem-Ed": "d日E",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "后天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"dateFormatItem-yyyyMMMM": "Gy年M月",
+	"dateFormat-long": "Gy年M月d日",
+	"field-zone": "时区",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "上周",
+	"dateFormat-medium": "Gy年M月d日",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"field-year-relative+-1": "去年",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"field-year": "年",
+	"dateTimeFormat-long": "{1}{0}",
+	"field-week": "周",
+	"dateFormatItem-yyyyMd": "Gy-M-d",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"dateFormatItem-yyyyMEd": "Gy-M-d(E)",
+	"dateFormatItem-MMMd": "M月d日",
+	"field-week-relative+0": "本周",
+	"field-week-relative+1": "下周",
+	"field-month-relative+0": "本月",
+	"dateFormatItem-H": "H时",
+	"field-month": "月",
+	"field-month-relative+1": "下个月",
+	"dateFormatItem-M": "M月",
+	"field-second": "秒钟",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"field-day": "日",
+	"dateFormatItem-MEd": "M-dE",
+	"dateFormatItem-yyyyQQQ": "Gy年第Q季度",
+	"dateFormatItem-hm": "ah:mm",
+	"dateFormat-short": "Gy-M-d",
+	"dateFormatItem-yyyyM": "Gy-M",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-Md": "M-d",
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-d": "d日",
+	"field-month-relative+-1": "上个月",
+	"dateFormatItem-h": "ah时"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/gregorian.js b/dojo/cldr/nls/zh/gregorian.js
index 8548b42..dbdd709 100644
--- a/dojo/cldr/nls/zh/gregorian.js
+++ b/dojo/cldr/nls/zh/gregorian.js
@@ -1,51 +1,80 @@
 define(
 //begin v1.x content
 {
+	"days-standAlone-short": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
 	"months-format-narrow": [
-		"1月",
-		"2月",
-		"3月",
-		"4月",
-		"5月",
-		"6月",
-		"7月",
-		"8月",
-		"9月",
-		"10月",
-		"11月",
-		"12月"
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"quarters-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
 	],
-	"field-weekday": "周天",
-	"dateFormatItem-yQQQ": "y年QQQ",
-	"dateFormatItem-yMEd": "y年M月d日,E",
-	"dateFormatItem-MMMEd": "MMMd日E",
+	"field-weekday": "星期",
+	"dateFormatItem-yQQQ": "y年第Q季度",
+	"dateFormatItem-yMEd": "y/M/dE",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-MMMEd": "M月d日E",
 	"eraNarrow": [
 		"公元前",
 		"公元"
 	],
+	"dateFormatItem-yMM": "y年M月",
 	"dayPeriods-format-wide-earlyMorning": "清晨",
 	"dayPeriods-format-wide-morning": "上午",
+	"days-format-short": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
 	"dateFormat-long": "y年M月d日",
 	"months-format-wide": [
-		"1月",
-		"2月",
-		"3月",
-		"4月",
-		"5月",
-		"6月",
-		"7月",
-		"8月",
-		"9月",
-		"10月",
-		"11月",
-		"12月"
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
 	],
 	"dateTimeFormat-medium": "{1} {0}",
 	"dayPeriods-format-wide-pm": "下午",
 	"dateFormat-full": "y年M月d日EEEE",
-	"dateFormatItem-Md": "M-d",
+	"dateFormatItem-Md": "M/d",
+	"dayPeriods-format-narrow-midDay": "中午",
+	"dayPeriods-format-wide-noon": "中午",
+	"dateFormatItem-yMd": "y/M/d",
+	"dateFormatItem-yM": "y/M",
 	"field-era": "时期",
-	"dateFormatItem-yM": "yyyy-M",
 	"months-standAlone-wide": [
 		"一月",
 		"二月",
@@ -62,18 +91,17 @@ define(
 	],
 	"timeFormat-short": "ah:mm",
 	"quarters-format-wide": [
-		"第1季度",
-		"第2季度",
-		"第3季度",
-		"第4季度"
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
 	],
-	"timeFormat-long": "zah时mm分ss秒",
+	"timeFormat-long": "zah:mm:ss",
+	"dateFormatItem-yMMM": "y年M月",
+	"dateFormatItem-yQQQQ": "y年QQQQ",
 	"field-year": "年",
-	"dateFormatItem-yMMM": "y年MMM",
-	"dateFormatItem-yQ": "y年QQQ",
-	"dateFormatItem-yyyyMMMM": "y年MMMM",
+	"dateFormatItem-MMdd": "MM/dd",
 	"field-hour": "小时",
-	"dateFormatItem-MMdd": "MM-dd",
 	"months-format-abbr": [
 		"1月",
 		"2月",
@@ -88,38 +116,40 @@ define(
 		"11月",
 		"12月"
 	],
-	"dateFormatItem-yyQ": "yy年第Q季度",
-	"timeFormat-full": "zzzzah时mm分ss秒",
+	"timeFormat-full": "zzzzah:mm:ss",
+	"dayPeriods-format-narrow-morning": "上午",
 	"field-day-relative+0": "今天",
 	"field-day-relative+1": "明天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
 	"field-day-relative+2": "后天",
 	"dateFormatItem-H": "H时",
 	"months-standAlone-abbr": [
-		"一月",
-		"二月",
-		"三月",
-		"四月",
-		"五月",
-		"六月",
-		"七月",
-		"八月",
-		"九月",
-		"十月",
-		"十一月",
-		"十二月"
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
 	],
 	"quarters-format-abbr": [
-		"1季",
-		"2季",
-		"3季",
-		"4季"
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
 	],
 	"quarters-standAlone-wide": [
-		"第1季度",
-		"第2季度",
-		"第3季度",
-		"第4季度"
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
 	],
+	"dateFormatItem-Gy": "Gy年",
 	"dateFormatItem-M": "M月",
 	"days-standAlone-wide": [
 		"星期日",
@@ -130,14 +160,13 @@ define(
 		"星期五",
 		"星期六"
 	],
-	"dateFormatItem-yyMMM": "yy年MMM",
 	"timeFormat-medium": "ah:mm:ss",
-	"dateFormatItem-Hm": "H:mm",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"1季",
-		"2季",
-		"3季",
-		"4季"
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
 	],
 	"eraAbbr": [
 		"公元前",
@@ -157,14 +186,22 @@ define(
 	"dayPeriods-format-wide-night": "晚上",
 	"dateFormatItem-d": "d日",
 	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4"
+	],
 	"field-day-relative+-1": "昨天",
 	"dateFormatItem-h": "ah时",
 	"dateTimeFormat-long": "{1}{0}",
+	"dayPeriods-format-narrow-am": "上午",
 	"field-day-relative+-2": "前天",
-	"dateFormatItem-MMMd": "MMMd日",
+	"dateFormatItem-MMMd": "M月d日",
 	"dayPeriods-format-wide-midDay": "中午",
-	"dateFormatItem-MEd": "M-dE",
+	"dateFormatItem-MEd": "M/dE",
 	"dateTimeFormat-full": "{1}{0}",
+	"dateFormatItem-yMMMM": "y年M月",
 	"field-day": "日",
 	"days-format-wide": [
 		"星期日",
@@ -175,24 +212,27 @@ define(
 		"星期五",
 		"星期六"
 	],
-	"field-zone": "区域",
-	"dateFormatItem-y": "y年",
+	"field-zone": "时区",
 	"months-standAlone-narrow": [
-		"1月",
-		"2月",
-		"3月",
-		"4月",
-		"5月",
-		"6月",
-		"7月",
-		"8月",
-		"9月",
-		"10月",
-		"11月",
-		"12月"
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
 	],
-	"dateFormatItem-yyMM": "yy-MM",
+	"dateFormatItem-y": "y年",
+	"field-year-relative+-1": "去年",
+	"dayPeriods-format-narrow-night": "晚上",
+	"field-month-relative+-1": "上个月",
 	"dateFormatItem-hm": "ah:mm",
+	"dayPeriods-format-narrow-weeHours": "凌晨",
 	"days-format-abbr": [
 		"周日",
 		"周一",
@@ -202,11 +242,11 @@ define(
 		"周五",
 		"周六"
 	],
-	"dateFormatItem-yMMMd": "y年MMMd日",
 	"eraNames": [
 		"公元前",
 		"公元"
 	],
+	"dateFormatItem-yMMMd": "y年M月d日",
 	"days-format-narrow": [
 		"日",
 		"一",
@@ -216,7 +256,7 @@ define(
 		"五",
 		"六"
 	],
-	"field-month": "月",
+	"dayPeriods-format-narrow-earlyMorning": "清晨",
 	"days-standAlone-narrow": [
 		"日",
 		"一",
@@ -227,21 +267,31 @@ define(
 		"六"
 	],
 	"dateFormatItem-MMM": "LLL",
+	"field-month": "月",
 	"dayPeriods-format-wide-am": "上午",
-	"dateFormatItem-MMMMdd": "MMMMdd日",
 	"dayPeriods-format-wide-weeHours": "凌晨",
+	"dateFormatItem-MMMMdd": "M月dd日",
 	"dateFormat-short": "yy-M-d",
 	"dayPeriods-format-wide-afternoon": "下午",
+	"dayPeriods-format-narrow-afternoon": "下午",
+	"dayPeriods-format-narrow-noon": "中午",
 	"field-second": "秒钟",
-	"dateFormatItem-yMMMEd": "y年MMMd日EEE",
+	"dateFormatItem-yMMMEd": "y年M月d日E",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下个月",
 	"dateFormatItem-Ed": "d日E",
 	"field-week": "周",
-	"dateFormat-medium": "yyyy-M-d",
-	"dateFormatItem-yyyyM": "y年M月",
+	"dateFormat-medium": "y年M月d日",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "上周",
+	"field-year-relative+1": "明年",
+	"dayPeriods-format-narrow-pm": "下午",
 	"dateTimeFormat-short": "{1} {0}",
-	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "ah:mm:ss",
-	"dateFormatItem-yyyy": "y年"
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"field-week-relative+0": "本周",
+	"field-week-relative+1": "下周"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/hebrew.js b/dojo/cldr/nls/zh/hebrew.js
new file mode 100644
index 0000000..34e71c8
--- /dev/null
+++ b/dojo/cldr/nls/zh/hebrew.js
@@ -0,0 +1,239 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"field-weekday": "星期",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"eraNarrow": [
+		"希伯来历"
+	],
+	"days-format-short": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormat-long": "Gy年M月d日",
+	"months-format-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月",
+		"十三月"
+	],
+	"dateFormatItem-yyyyQQQ": "Gy年第Q季度",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "Gy-M-d(E)",
+	"dateFormatItem-Md": "M-d",
+	"field-era": "时期",
+	"months-standAlone-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月",
+		"十三月"
+	],
+	"timeFormat-short": "ah:mm",
+	"quarters-format-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
+	],
+	"timeFormat-long": "zah:mm:ss",
+	"field-year": "年",
+	"field-hour": "小时",
+	"months-format-abbr-leap": "闰7月",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"timeFormat-full": "zzzzah:mm:ss",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-day-relative+2": "后天",
+	"dateFormatItem-H": "H时",
+	"months-standAlone-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月",
+		"13月"
+	],
+	"quarters-format-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
+	],
+	"quarters-standAlone-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
+	],
+	"dateFormatItem-Gy": "Gy年",
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-M": "M月",
+	"days-standAlone-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"months-standAlone-wide-leap": "闰七月",
+	"timeFormat-medium": "ah:mm:ss",
+	"quarters-standAlone-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
+	],
+	"eraAbbr": [
+		"希伯来历"
+	],
+	"field-minute": "分钟",
+	"field-dayperiod": "上午/下午",
+	"days-standAlone-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormatItem-d": "d日",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-h": "ah时",
+	"dateTimeFormat-long": "{1}{0}",
+	"dayPeriods-format-narrow-am": "上午",
+	"field-day-relative+-2": "前天",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M-dE",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day": "日",
+	"days-format-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"field-zone": "时区",
+	"months-standAlone-abbr-leap": "闰7月",
+	"dateFormatItem-y": "Gy年",
+	"field-year-relative+-1": "去年",
+	"field-month-relative+-1": "上个月",
+	"dateFormatItem-hm": "ah:mm",
+	"days-format-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"eraNames": [
+		"希伯来历"
+	],
+	"days-format-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormatItem-yyyyMd": "Gy-M-d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormat-short": "Gy-M-d",
+	"field-second": "秒钟",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下个月",
+	"dateFormatItem-Ed": "d日E",
+	"field-week": "周",
+	"dateFormat-medium": "Gy年M月d日",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "上周",
+	"dateFormatItem-yyyyM": "Gy-M",
+	"field-year-relative+1": "明年",
+	"dayPeriods-format-narrow-pm": "下午",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"months-format-wide-leap": "闰七月",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-yyyy": "Gy年",
+	"field-week-relative+0": "本周",
+	"field-week-relative+1": "下周"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/indian.js b/dojo/cldr/nls/zh/indian.js
new file mode 100644
index 0000000..569283b
--- /dev/null
+++ b/dojo/cldr/nls/zh/indian.js
@@ -0,0 +1,118 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒钟",
+	"field-year-relative+-1": "去年",
+	"field-week": "周",
+	"field-month-relative+-1": "上个月",
+	"field-day-relative+-1": "昨天",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-day-relative+-2": "前天",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"months-standAlone-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"field-year": "年",
+	"field-week-relative+0": "本周",
+	"months-standAlone-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"field-week-relative+1": "下周",
+	"field-minute": "分钟",
+	"field-week-relative+-1": "上周",
+	"field-day-relative+0": "今天",
+	"field-hour": "小时",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "后天",
+	"field-day": "日",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下个月",
+	"field-dayperiod": "上午/下午",
+	"field-month": "月",
+	"months-format-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"field-era": "时期",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"eraAbbr": [
+		"印度历"
+	],
+	"field-weekday": "星期",
+	"field-zone": "时区"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/islamic.js b/dojo/cldr/nls/zh/islamic.js
new file mode 100644
index 0000000..0f60ba8
--- /dev/null
+++ b/dojo/cldr/nls/zh/islamic.js
@@ -0,0 +1,259 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "星期",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"eraNarrow": [
+		"回历"
+	],
+	"days-format-short": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormat-long": "Gy年M月d日",
+	"months-format-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"dateFormatItem-yyyyQQQ": "Gy年第Q季度",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "Gy-M-d(E)",
+	"dateFormatItem-Md": "M-d",
+	"field-era": "时期",
+	"months-standAlone-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"timeFormat-short": "ah:mm",
+	"quarters-format-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
+	],
+	"timeFormat-long": "zah:mm:ss",
+	"field-year": "年",
+	"field-hour": "小时",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"timeFormat-full": "zzzzah:mm:ss",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-day-relative+2": "后天",
+	"dateFormatItem-H": "H时",
+	"months-standAlone-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"quarters-format-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
+	],
+	"quarters-standAlone-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
+	],
+	"dateFormatItem-Gy": "Gy年",
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-M": "M月",
+	"days-standAlone-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"timeFormat-medium": "ah:mm:ss",
+	"quarters-standAlone-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
+	],
+	"eraAbbr": [
+		"回历"
+	],
+	"field-minute": "分钟",
+	"field-dayperiod": "上午/下午",
+	"days-standAlone-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormatItem-d": "d日",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-h": "ah时",
+	"dateTimeFormat-long": "{1}{0}",
+	"dayPeriods-format-narrow-am": "上午",
+	"field-day-relative+-2": "前天",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M-dE",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day": "日",
+	"days-format-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"field-zone": "时区",
+	"dateFormatItem-y": "Gy年",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year-relative+-1": "去年",
+	"field-month-relative+-1": "上个月",
+	"dateFormatItem-hm": "ah:mm",
+	"days-format-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"eraNames": [
+		"回历"
+	],
+	"days-format-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormatItem-yyyyMd": "Gy-M-d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormat-short": "Gy-M-d",
+	"field-second": "秒钟",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下个月",
+	"dateFormatItem-Ed": "d日E",
+	"field-week": "周",
+	"dateFormat-medium": "Gy年M月d日",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "上周",
+	"dateFormatItem-yyyyM": "Gy-M",
+	"field-year-relative+1": "明年",
+	"dayPeriods-format-narrow-pm": "下午",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-yyyy": "Gy年",
+	"field-week-relative+0": "本周",
+	"field-week-relative+1": "下周"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/japanese.js b/dojo/cldr/nls/zh/japanese.js
new file mode 100644
index 0000000..c0a64bf
--- /dev/null
+++ b/dojo/cldr/nls/zh/japanese.js
@@ -0,0 +1,306 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
+	"field-dayperiod": "上午/下午",
+	"field-minute": "分钟",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"field-day-relative+-2": "前天",
+	"field-weekday": "星期",
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Gy": "Gy年",
+	"dateTimeFormat-medium": "{1} {0}",
+	"field-era": "时期",
+	"field-hour": "小时",
+	"dateFormatItem-y": "Gy年",
+	"dateFormatItem-yyyy": "Gy年",
+	"dateFormatItem-Ed": "d日E",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"eraAbbr": [
+		"大化 (645–650)",
+		"白雉 (650–671)",
+		"白凤 (672–686)",
+		"朱鸟 (686–701)",
+		"大宝 (701–704)",
+		"庆云 (704–708)",
+		"和铜 (708–715)",
+		"灵龟 (715–717)",
+		"养老 (717–724)",
+		"神龟 (724–729)",
+		"天平 (729–749)",
+		"天平感宝 (749–749)",
+		"天平胜宝 (749–757)",
+		"天平宝字 (757–765)",
+		"天平神护 (765–767)",
+		"神护景云 (767–770)",
+		"宝龟 (770–780)",
+		"天应 (781–782)",
+		"延历 (782–806)",
+		"大同 (806–810)",
+		"弘仁 (810–824)",
+		"天长 (824–834)",
+		"承和 (834–848)",
+		"嘉祥 (848–851)",
+		"仁寿 (851–854)",
+		"齐衡 (854–857)",
+		"天安 (857–859)",
+		"贞观 (859–877)",
+		"元庆 (877–885)",
+		"仁和 (885–889)",
+		"宽平 (889–898)",
+		"昌泰 (898–901)",
+		"延喜 (901–923)",
+		"延长 (923–931)",
+		"承平 (931–938)",
+		"天庆 (938–947)",
+		"天历 (947–957)",
+		"天德 (957–961)",
+		"应和 (961–964)",
+		"康保 (964–968)",
+		"安和 (968–970)",
+		"天禄 (970–973)",
+		"天延 (973–976)",
+		"贞元 (976–978)",
+		"天元 (978–983)",
+		"永观 (983–985)",
+		"宽和 (985–987)",
+		"永延 (987–989)",
+		"永祚 (989–990)",
+		"正历 (990–995)",
+		"长德 (995–999)",
+		"长保 (999–1004)",
+		"宽弘 (1004–1012)",
+		"长和 (1012–1017)",
+		"宽仁 (1017–1021)",
+		"治安 (1021–1024)",
+		"万寿 (1024–1028)",
+		"长元 (1028–1037)",
+		"长历 (1037–1040)",
+		"长久 (1040–1044)",
+		"宽德 (1044–1046)",
+		"永承 (1046–1053)",
+		"天喜 (1053–1058)",
+		"康平 (1058–1065)",
+		"治历 (1065–1069)",
+		"延久 (1069–1074)",
+		"承保 (1074–1077)",
+		"正历 (1077–1081)",
+		"永保 (1081–1084)",
+		"应德 (1084–1087)",
+		"宽治 (1087–1094)",
+		"嘉保 (1094–1096)",
+		"永长 (1096–1097)",
+		"承德 (1097–1099)",
+		"康和 (1099–1104)",
+		"长治 (1104–1106)",
+		"嘉承 (1106–1108)",
+		"天仁 (1108–1110)",
+		"天永 (1110–1113)",
+		"永久 (1113–1118)",
+		"元永 (1118–1120)",
+		"保安 (1120–1124)",
+		"天治 (1124–1126)",
+		"大治 (1126–1131)",
+		"天承 (1131–1132)",
+		"长承 (1132–1135)",
+		"保延 (1135–1141)",
+		"永治 (1141–1142)",
+		"康治 (1142–1144)",
+		"天养 (1144–1145)",
+		"久安 (1145–1151)",
+		"仁平 (1151–1154)",
+		"久寿 (1154–1156)",
+		"保元 (1156–1159)",
+		"平治 (1159–1160)",
+		"永历 (1160–1161)",
+		"应保 (1161–1163)",
+		"长宽 (1163–1165)",
+		"永万 (1165–1166)",
+		"仁安 (1166–1169)",
+		"嘉应 (1169–1171)",
+		"承安 (1171–1175)",
+		"安元 (1175–1177)",
+		"治承 (1177–1181)",
+		"养和 (1181–1182)",
+		"寿永 (1182–1184)",
+		"元历 (1184–1185)",
+		"文治 (1185–1190)",
+		"建久 (1190–1199)",
+		"正治 (1199–1201)",
+		"建仁 (1201–1204)",
+		"元久 (1204–1206)",
+		"建永 (1206–1207)",
+		"承元 (1207–1211)",
+		"建历 (1211–1213)",
+		"建保 (1213–1219)",
+		"承久 (1219–1222)",
+		"贞应 (1222–1224)",
+		"元仁 (1224–1225)",
+		"嘉禄 (1225–1227)",
+		"安贞 (1227–1229)",
+		"宽喜 (1229–1232)",
+		"贞永 (1232–1233)",
+		"天福 (1233–1234)",
+		"文历 (1234–1235)",
+		"嘉祯 (1235–1238)",
+		"历仁 (1238–1239)",
+		"延应 (1239–1240)",
+		"仁治 (1240–1243)",
+		"宽元 (1243–1247)",
+		"宝治 (1247–1249)",
+		"建长 (1249–1256)",
+		"康元 (1256–1257)",
+		"正嘉 (1257–1259)",
+		"正元 (1259–1260)",
+		"文应 (1260–1261)",
+		"弘长 (1261–1264)",
+		"文永 (1264–1275)",
+		"建治 (1275–1278)",
+		"弘安 (1278–1288)",
+		"正应 (1288–1293)",
+		"永仁 (1293–1299)",
+		"正安 (1299–1302)",
+		"干元 (1302–1303)",
+		"嘉元 (1303–1306)",
+		"德治 (1306–1308)",
+		"延庆 (1308–1311)",
+		"应长 (1311–1312)",
+		"正和 (1312–1317)",
+		"文保 (1317–1319)",
+		"元应 (1319–1321)",
+		"元亨 (1321–1324)",
+		"正中 (1324–1326)",
+		"嘉历 (1326–1329)",
+		"元德 (1329–1331)",
+		"元弘 (1331–1334)",
+		"建武 (1334–1336)",
+		"延元 (1336–1340)",
+		"兴国 (1340–1346)",
+		"正平 (1346–1370)",
+		"建德 (1370–1372)",
+		"文中 (1372–1375)",
+		"天授 (1375–1379)",
+		"康历 (1379–1381)",
+		"弘和 (1381–1384)",
+		"元中 (1384–1392)",
+		"至德 (1384–1387)",
+		"嘉庆 (1387–1389)",
+		"康应 (1389–1390)",
+		"明德 (1390–1394)",
+		"应永 (1394–1428)",
+		"正长 (1428–1429)",
+		"永享 (1429–1441)",
+		"嘉吉 (1441–1444)",
+		"文安 (1444–1449)",
+		"宝德 (1449–1452)",
+		"享德 (1452–1455)",
+		"康正 (1455–1457)",
+		"长禄 (1457–1460)",
+		"宽正 (1460–1466)",
+		"文正 (1466–1467)",
+		"应仁 (1467–1469)",
+		"文明 (1469–1487)",
+		"长享 (1487–1489)",
+		"延德 (1489–1492)",
+		"明应 (1492–1501)",
+		"文龟 (1501–1504)",
+		"永正 (1504–1521)",
+		"大永 (1521–1528)",
+		"享禄 (1528–1532)",
+		"天文 (1532–1555)",
+		"弘治 (1555–1558)",
+		"永禄 (1558–1570)",
+		"元龟 (1570–1573)",
+		"天正 (1573–1592)",
+		"文禄 (1592–1596)",
+		"庆长 (1596–1615)",
+		"元和 (1615–1624)",
+		"宽永 (1624–1644)",
+		"正保 (1644–1648)",
+		"庆安 (1648–1652)",
+		"承应 (1652–1655)",
+		"明历 (1655–1658)",
+		"万治 (1658–1661)",
+		"宽文 (1661–1673)",
+		"延宝 (1673–1681)",
+		"天和 (1681–1684)",
+		"贞享 (1684–1688)",
+		"元禄 (1688–1704)",
+		"宝永 (1704–1711)",
+		"正德 (1711–1716)",
+		"享保 (1716–1736)",
+		"元文 (1736–1741)",
+		"宽保 (1741–1744)",
+		"延享 (1744–1748)",
+		"宽延 (1748–1751)",
+		"宝历 (1751–1764)",
+		"明和 (1764–1772)",
+		"安永 (1772–1781)",
+		"天明 (1781–1789)",
+		"宽政 (1789–1801)",
+		"享和 (1801–1804)",
+		"文化 (1804–1818)",
+		"文政 (1818–1830)",
+		"天保 (1830–1844)",
+		"弘化 (1844–1848)",
+		"嘉永 (1848–1854)",
+		"安政 (1854–1860)",
+		"万延 (1860–1861)",
+		"文久 (1861–1864)",
+		"元治 (1864–1865)",
+		"庆应 (1865–1868)",
+		"明治",
+		"大正",
+		"昭和",
+		"平成"
+	],
+	"field-day-relative+2": "后天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"dateFormat-long": "Gy年M月d日",
+	"field-zone": "时区",
+	"dateFormatItem-Hm": "HH:mm",
+	"field-week-relative+-1": "上周",
+	"dateFormat-medium": "Gy年M月d日",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"field-year-relative+-1": "去年",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"field-year": "年",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "周",
+	"dateFormatItem-yyyyMd": "Gy-MM-dd",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"dateFormatItem-yyyyMEd": "Gy-M-d(E)",
+	"dateFormatItem-MMMd": "M月d日",
+	"field-week-relative+0": "本周",
+	"field-week-relative+1": "下周",
+	"field-month-relative+0": "本月",
+	"dateFormatItem-H": "H时",
+	"field-month": "月",
+	"field-month-relative+1": "下个月",
+	"dateFormatItem-M": "M月",
+	"field-second": "秒钟",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"field-day": "日",
+	"dateFormatItem-MEd": "M-dE",
+	"dateFormatItem-yyyyQQQ": "Gy年第Q季度",
+	"dateFormatItem-hm": "ah:mm",
+	"dateFormat-short": "Gyy-MM-dd",
+	"dateFormatItem-yyyyM": "Gy-MM",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-Md": "M-d",
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-d": "d日",
+	"field-month-relative+-1": "上个月",
+	"dateFormatItem-h": "ah时"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/number.js b/dojo/cldr/nls/zh/number.js
index afbe6ca..90e14e7 100644
--- a/dojo/cldr/nls/zh/number.js
+++ b/dojo/cldr/nls/zh/number.js
@@ -1,12 +1,22 @@
 define(
 //begin v1.x content
 {
-	"decimalFormat": "#,##0.###",
 	"group": ",",
+	"percentSign": "%",
+	"exponential": "E",
 	"scientificFormat": "#E0",
 	"percentFormat": "#,##0%",
-	"currencyFormat": "¤#,##0.00",
-	"decimal": "."
+	"list": ";",
+	"infinity": "∞",
+	"minusSign": "-",
+	"decimal": ".",
+	"nan": "NaN",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "¤#,##0.00;(¤#,##0.00)",
+	"plusSign": "+",
+	"decimalFormat-long": "000万亿",
+	"decimalFormat-short": "000万亿"
 }
 //end v1.x content
 );
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/persian.js b/dojo/cldr/nls/zh/persian.js
new file mode 100644
index 0000000..9e81e2a
--- /dev/null
+++ b/dojo/cldr/nls/zh/persian.js
@@ -0,0 +1,259 @@
+define(
+//begin v1.x content
+{
+	"days-standAlone-short": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-weekday": "星期",
+	"dateFormatItem-GyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-MMMEd": "M月d日E",
+	"eraNarrow": [
+		"波斯历"
+	],
+	"days-format-short": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormat-long": "Gy年M月d日",
+	"months-format-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"dateFormatItem-yyyyQQQ": "Gy年第Q季度",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-yyyyMEd": "Gy-M-d(E)",
+	"dateFormatItem-Md": "M-d",
+	"field-era": "时期",
+	"months-standAlone-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"timeFormat-short": "ah:mm",
+	"quarters-format-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
+	],
+	"timeFormat-long": "zah:mm:ss",
+	"field-year": "年",
+	"field-hour": "小时",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"timeFormat-full": "zzzzah:mm:ss",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"dateFormatItem-GyMMMd": "Gy年M月d日",
+	"field-day-relative+2": "后天",
+	"dateFormatItem-H": "H时",
+	"months-standAlone-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"quarters-format-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
+	],
+	"quarters-standAlone-wide": [
+		"第一季度",
+		"第二季度",
+		"第三季度",
+		"第四季度"
+	],
+	"dateFormatItem-Gy": "Gy年",
+	"dateFormatItem-yyyyMMMEd": "Gy年M月d日E",
+	"dateFormatItem-M": "M月",
+	"days-standAlone-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"timeFormat-medium": "ah:mm:ss",
+	"quarters-standAlone-abbr": [
+		"1季度",
+		"2季度",
+		"3季度",
+		"4季度"
+	],
+	"eraAbbr": [
+		"波斯历"
+	],
+	"field-minute": "分钟",
+	"field-dayperiod": "上午/下午",
+	"days-standAlone-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"dateFormatItem-d": "d日",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-h": "ah时",
+	"dateTimeFormat-long": "{1}{0}",
+	"dayPeriods-format-narrow-am": "上午",
+	"field-day-relative+-2": "前天",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M-dE",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day": "日",
+	"days-format-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"field-zone": "时区",
+	"dateFormatItem-y": "Gy年",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"field-year-relative+-1": "去年",
+	"field-month-relative+-1": "上个月",
+	"dateFormatItem-hm": "ah:mm",
+	"days-format-abbr": [
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
+		"周六"
+	],
+	"eraNames": [
+		"波斯历"
+	],
+	"days-format-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormatItem-yyyyMd": "Gy-M-d",
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormat-short": "Gy-M-d",
+	"field-second": "秒钟",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下个月",
+	"dateFormatItem-Ed": "d日E",
+	"field-week": "周",
+	"dateFormat-medium": "Gy年M月d日",
+	"field-year-relative+0": "今年",
+	"field-week-relative+-1": "上周",
+	"dateFormatItem-yyyyM": "Gy-M",
+	"field-year-relative+1": "明年",
+	"dayPeriods-format-narrow-pm": "下午",
+	"dateFormatItem-yyyyQQQQ": "Gy年QQQQ",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"dateFormatItem-GyMMM": "Gy年M月",
+	"dateFormatItem-yyyy": "Gy年",
+	"field-week-relative+0": "本周",
+	"field-week-relative+1": "下周"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/roc.js b/dojo/cldr/nls/zh/roc.js
new file mode 100644
index 0000000..8fb5c4a
--- /dev/null
+++ b/dojo/cldr/nls/zh/roc.js
@@ -0,0 +1,35 @@
+define(
+//begin v1.x content
+{
+	"field-second": "秒钟",
+	"field-year-relative+-1": "去年",
+	"field-week": "周",
+	"field-month-relative+-1": "上个月",
+	"field-day-relative+-1": "昨天",
+	"field-day-relative+-2": "前天",
+	"field-year": "年",
+	"field-week-relative+0": "本周",
+	"field-week-relative+1": "下周",
+	"field-minute": "分钟",
+	"field-week-relative+-1": "上周",
+	"field-day-relative+0": "今天",
+	"field-hour": "小时",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "后天",
+	"field-day": "日",
+	"field-month-relative+0": "本月",
+	"field-month-relative+1": "下个月",
+	"field-dayperiod": "上午/下午",
+	"field-month": "月",
+	"field-era": "时期",
+	"field-year-relative+0": "今年",
+	"field-year-relative+1": "明年",
+	"eraAbbr": [
+		"民国前",
+		"民国"
+	],
+	"field-weekday": "星期",
+	"field-zone": "时区"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/supplemental.js b/dojo/cldr/supplemental.js
index 83088ae..5ce84a2 100644
--- a/dojo/cldr/supplemental.js
+++ b/dojo/cldr/supplemental.js
@@ -1,43 +1,91 @@
-define(["../_base/kernel", "../_base/lang", "../i18n"], function(dojo, lang) {
-	// module:
-	//		dojo/cldr/supplemental
+define(["../_base/lang", "../i18n"], function(lang, i18n){
+
+// module:
+//		dojo/cldr/supplemental
+
+
+var supplemental = {
 	// summary:
 	//		TODOC
+};
+lang.setObject("dojo.cldr.supplemental", supplemental);
 
-lang.getObject("cldr.supplemental", true, dojo);
-
-dojo.cldr.supplemental.getFirstDayOfWeek = function(/*String?*/locale){
-// summary: Returns a zero-based index for first day of the week
-// description:
-//		Returns a zero-based index for first day of the week, as used by the local (Gregorian) calendar.
-//		e.g. Sunday (returns 0), or Monday (returns 1)
+supplemental.getFirstDayOfWeek = function(/*String?*/locale){
+	// summary:
+	//		Returns a zero-based index for first day of the week
+	// description:
+	//		Returns a zero-based index for first day of the week, as used by the local (Gregorian) calendar.
+	//		e.g. Sunday (returns 0), or Monday (returns 1)
 
 	// from http://www.unicode.org/cldr/data/common/supplemental/supplementalData.xml:supplementalData/weekData/firstDay
 	var firstDay = {/*default is 1=Monday*/
-		mv:5,
-		ae:6,af:6,bh:6,dj:6,dz:6,eg:6,er:6,et:6,iq:6,ir:6,jo:6,ke:6,kw:6,
-		ly:6,ma:6,om:6,qa:6,sa:6,sd:6,so:6,sy:6,tn:6,ye:6,
-		ar:0,as:0,az:0,bw:0,ca:0,cn:0,fo:0,ge:0,gl:0,gu:0,hk:0,
-		il:0,'in':0,jm:0,jp:0,kg:0,kr:0,la:0,mh:0,mn:0,mo:0,mp:0,
-		mt:0,nz:0,ph:0,pk:0,sg:0,th:0,tt:0,tw:0,um:0,us:0,uz:0,
-		vi:0,zw:0
-// variant. do not use?		gb:0,
+		bd:5,mv:5,
+		ae:6,af:6,bh:6,dj:6,dz:6,eg:6,iq:6,ir:6,jo:6,kw:6,
+		ly:6,ma:6,om:6,qa:6,sa:6,sd:6,sy:6,ye:6,
+		ag:0,ar:0,as:0,au:0,br:0,bs:0,bt:0,bw:0,by:0,bz:0,ca:0,cn:0,
+		co:0,dm:0,'do':0,et:0,gt:0,gu:0,hk:0,hn:0,id:0,ie:0,il:0,'in':0,
+		jm:0,jp:0,ke:0,kh:0,kr:0,la:0,mh:0,mm:0,mo:0,mt:0,mx:0,mz:0,
+		ni:0,np:0,nz:0,pa:0,pe:0,ph:0,pk:0,pr:0,py:0,sg:0,sv:0,th:0,
+		tn:0,tt:0,tw:0,um:0,us:0,ve:0,vi:0,ws:0,za:0,zw:0
 	};
 
-	var country = dojo.cldr.supplemental._region(locale);
+	var country = supplemental._region(locale);
 	var dow = firstDay[country];
 	return (dow === undefined) ? 1 : dow; /*Number*/
 };
 
-dojo.cldr.supplemental._region = function(/*String?*/locale){
-	locale = dojo.i18n.normalizeLocale(locale);
+supplemental._region = function(/*String?*/locale){
+	locale = i18n.normalizeLocale(locale);
 	var tags = locale.split('-');
 	var region = tags[1];
 	if(!region){
 		// IE often gives language only (#2269)
 		// Arbitrary mappings of language-only locales to a country:
-		region = {de:"de", en:"us", es:"es", fi:"fi", fr:"fr", he:"il", hu:"hu", it:"it",
-			ja:"jp", ko:"kr", nl:"nl", pt:"br", sv:"se", zh:"cn"}[tags[0]];
+		region = {
+			aa:"et", ab:"ge", af:"za", ak:"gh", am:"et", ar:"eg", as:"in", av:"ru", ay:"bo", az:"az", ba:"ru",
+			be:"by", bg:"bg", bi:"vu", bm:"ml", bn:"bd", bo:"cn", br:"fr", bs:"ba", ca:"es", ce:"ru", ch:"gu",
+			co:"fr", cr:"ca", cs:"cz", cv:"ru", cy:"gb", da:"dk", de:"de", dv:"mv", dz:"bt", ee:"gh", el:"gr",
+			en:"us", es:"es", et:"ee", eu:"es", fa:"ir", ff:"sn", fi:"fi", fj:"fj", fo:"fo", fr:"fr", fy:"nl",
+			ga:"ie", gd:"gb", gl:"es", gn:"py", gu:"in", gv:"gb", ha:"ng", he:"il", hi:"in", ho:"pg", hr:"hr",
+			ht:"ht", hu:"hu", hy:"am", ia:"fr", id:"id", ig:"ng", ii:"cn", ik:"us", "in":"id", is:"is", it:"it",
+			iu:"ca", iw:"il", ja:"jp", ji:"ua", jv:"id", jw:"id", ka:"ge", kg:"cd", ki:"ke", kj:"na", kk:"kz",
+			kl:"gl", km:"kh", kn:"in", ko:"kr", ks:"in", ku:"tr", kv:"ru", kw:"gb", ky:"kg", la:"va", lb:"lu",
+			lg:"ug", li:"nl", ln:"cd", lo:"la", lt:"lt", lu:"cd", lv:"lv", mg:"mg", mh:"mh", mi:"nz", mk:"mk",
+			ml:"in", mn:"mn", mo:"ro", mr:"in", ms:"my", mt:"mt", my:"mm", na:"nr", nb:"no", nd:"zw", ne:"np",
+			ng:"na", nl:"nl", nn:"no", no:"no", nr:"za", nv:"us", ny:"mw", oc:"fr", om:"et", or:"in", os:"ge",
+			pa:"in", pl:"pl", ps:"af", pt:"br", qu:"pe", rm:"ch", rn:"bi", ro:"ro", ru:"ru", rw:"rw", sa:"in",
+			sd:"in", se:"no", sg:"cf", si:"lk", sk:"sk", sl:"si", sm:"ws", sn:"zw", so:"so", sq:"al", sr:"rs",
+			ss:"za", st:"za", su:"id", sv:"se", sw:"tz", ta:"in", te:"in", tg:"tj", th:"th", ti:"et", tk:"tm",
+			tl:"ph", tn:"za", to:"to", tr:"tr", ts:"za", tt:"ru", ty:"pf", ug:"cn", uk:"ua", ur:"pk", uz:"uz",
+			ve:"za", vi:"vn", wa:"be", wo:"sn", xh:"za", yi:"il", yo:"ng", za:"cn", zh:"cn", zu:"za",
+			ace:"id", ady:"ru", agq:"cm", alt:"ru", amo:"ng", asa:"tz", ast:"es", awa:"in", bal:"pk",
+			ban:"id", bas:"cm", bax:"cm", bbc:"id", bem:"zm", bez:"tz", bfq:"in", bft:"pk", bfy:"in",
+			bhb:"in", bho:"in", bik:"ph", bin:"ng", bjj:"in", bku:"ph", bqv:"ci", bra:"in", brx:"in",
+			bss:"cm", btv:"pk", bua:"ru", buc:"yt", bug:"id", bya:"id", byn:"er", cch:"ng", ccp:"in",
+			ceb:"ph", cgg:"ug", chk:"fm", chm:"ru", chp:"ca", chr:"us", cja:"kh", cjm:"vn", ckb:"iq",
+			crk:"ca", csb:"pl", dar:"ru", dav:"ke", den:"ca", dgr:"ca", dje:"ne", doi:"in", dsb:"de",
+			dua:"cm", dyo:"sn", dyu:"bf", ebu:"ke", efi:"ng", ewo:"cm", fan:"gq", fil:"ph", fon:"bj",
+			fur:"it", gaa:"gh", gag:"md", gbm:"in", gcr:"gf", gez:"et", gil:"ki", gon:"in", gor:"id",
+			grt:"in", gsw:"ch", guz:"ke", gwi:"ca", haw:"us", hil:"ph", hne:"in", hnn:"ph", hoc:"in",
+			hoj:"in", ibb:"ng", ilo:"ph", inh:"ru", jgo:"cm", jmc:"tz", kaa:"uz", kab:"dz", kaj:"ng",
+			kam:"ke", kbd:"ru", kcg:"ng", kde:"tz", kdt:"th", kea:"cv", ken:"cm", kfo:"ci", kfr:"in",
+			kha:"in", khb:"cn", khq:"ml", kht:"in", kkj:"cm", kln:"ke", kmb:"ao", koi:"ru", kok:"in",
+			kos:"fm", kpe:"lr", krc:"ru", kri:"sl", krl:"ru", kru:"in", ksb:"tz", ksf:"cm", ksh:"de",
+			kum:"ru", lag:"tz", lah:"pk", lbe:"ru", lcp:"cn", lep:"in", lez:"ru", lif:"np", lis:"cn",
+			lki:"ir", lmn:"in", lol:"cd", lua:"cd", luo:"ke", luy:"ke", lwl:"th", mad:"id", mag:"in",
+			mai:"in", mak:"id", man:"gn", mas:"ke", mdf:"ru", mdh:"ph", mdr:"id", men:"sl", mer:"ke",
+			mfe:"mu", mgh:"mz", mgo:"cm", min:"id", mni:"in", mnk:"gm", mnw:"mm", mos:"bf", mua:"cm",
+			mwr:"in", myv:"ru", nap:"it", naq:"na", nds:"de", "new":"np", niu:"nu", nmg:"cm", nnh:"cm",
+			nod:"th", nso:"za", nus:"sd", nym:"tz", nyn:"ug", pag:"ph", pam:"ph", pap:"bq", pau:"pw",
+			pon:"fm", prd:"ir", raj:"in", rcf:"re", rej:"id", rjs:"np", rkt:"in", rof:"tz", rwk:"tz",
+			saf:"gh", sah:"ru", saq:"ke", sas:"id", sat:"in", saz:"in", sbp:"tz", scn:"it", sco:"gb",
+			sdh:"ir", seh:"mz", ses:"ml", shi:"ma", shn:"mm", sid:"et", sma:"se", smj:"se", smn:"fi",
+			sms:"fi", snk:"ml", srn:"sr", srr:"sn", ssy:"er", suk:"tz", sus:"gn", swb:"yt", swc:"cd",
+			syl:"bd", syr:"sy", tbw:"ph", tcy:"in", tdd:"cn", tem:"sl", teo:"ug", tet:"tl", tig:"er",
+			tiv:"ng", tkl:"tk", tmh:"ne", tpi:"pg", trv:"tw", tsg:"ph", tts:"th", tum:"mw", tvl:"tv",
+			twq:"ne", tyv:"ru", tzm:"ma", udm:"ru", uli:"fm", umb:"ao", unr:"in", unx:"in", vai:"lr",
+			vun:"tz", wae:"ch", wal:"et", war:"ph", xog:"ug", xsr:"np", yao:"mz", yap:"fm", yav:"cm", zza:"tr"
+		}[tags[0]];
 	}else if(region.length == 4){
 		// The ISO 3166 country code is usually in the second position, unless a
 		// 4-letter script is given. See http://www.ietf.org/rfc/rfc4646.txt
@@ -46,32 +94,34 @@ dojo.cldr.supplemental._region = function(/*String?*/locale){
 	return region;
 };
 
-dojo.cldr.supplemental.getWeekend = function(/*String?*/locale){
-// summary: Returns a hash containing the start and end days of the weekend
-// description:
-//		Returns a hash containing the start and end days of the weekend according to local custom using locale,
-//		or by default in the user's locale.
-//		e.g. {start:6, end:0}
+supplemental.getWeekend = function(/*String?*/locale){
+	// summary:
+	//		Returns a hash containing the start and end days of the weekend
+	// description:
+	//		Returns a hash containing the start and end days of the weekend according to local custom using locale,
+	//		or by default in the user's locale.
+	//		e.g. {start:6, end:0}
 
 	// from http://www.unicode.org/cldr/data/common/supplemental/supplementalData.xml:supplementalData/weekData/weekend{Start,End}
 	var weekendStart = {/*default is 6=Saturday*/
-		'in':0,
-		af:4,dz:4,ir:4,om:4,sa:4,ye:4,
-		ae:5,bh:5,eg:5,il:5,iq:5,jo:5,kw:5,ly:5,ma:5,qa:5,sd:5,sy:5,tn:5
-	};
+			'in':0,
+			af:4,dz:4,ir:4,om:4,sa:4,ye:4,
+			ae:5,bh:5,eg:5,il:5,iq:5,jo:5,kw:5,ly:5,ma:5,qa:5,sd:5,sy:5,tn:5
+		},
 
-	var weekendEnd = {/*default is 0=Sunday*/
-		af:5,dz:5,ir:5,om:5,sa:5,ye:5,
-		ae:6,bh:5,eg:6,il:6,iq:6,jo:6,kw:6,ly:6,ma:6,qa:6,sd:6,sy:6,tn:6
-	};
+		weekendEnd = {/*default is 0=Sunday*/
+			af:5,dz:5,ir:5,om:5,sa:5,ye:5,
+			ae:6,bh:5,eg:6,il:6,iq:6,jo:6,kw:6,ly:6,ma:6,qa:6,sd:6,sy:6,tn:6
+		},
+
+		country = supplemental._region(locale),
+		start = weekendStart[country],
+		end = weekendEnd[country];
 
-	var country = dojo.cldr.supplemental._region(locale);
-	var start = weekendStart[country];
-	var end = weekendEnd[country];
 	if(start === undefined){start=6;}
 	if(end === undefined){end=0;}
 	return {start:start, end:end}; /*Object {start,end}*/
 };
 
-return dojo.cldr.supplemental;
+return supplemental;
 });
diff --git a/dojo/colors.js b/dojo/colors.js
index 4111e69..880ce26 100644
--- a/dojo/colors.js
+++ b/dojo/colors.js
@@ -1,20 +1,18 @@
-define(["./_base/kernel", "./_base/lang", "./_base/Color", "./_base/array"], function(dojo, lang, Color, ArrayUtil) {
+define(["./_base/kernel", "./_base/lang", "./_base/Color", "./_base/array"], function(dojo, lang, Color, ArrayUtil){
 	// module:
 	//		dojo/colors
-	// summary:
-	//		TODOC
 
-	var ColorExt = lang.getObject("dojo.colors", true);
+	/*=====
+	return {
+		// summary:
+		//		Color utilities, extending Base dojo.Color
+	};
+	=====*/
 
-//TODO: this module appears to break naming conventions
+	var ColorExt = {};
+	lang.setObject("dojo.colors", ColorExt);
 
-/*=====
-	lang.mixin(dojo, {
-		colors: {
-			// summary: Color utilities, extending Base dojo.Color
-		}
-	});
-=====*/
+//TODO: this module appears to break naming conventions
 
 	// this is a standard conversion prescribed by the CSS3 Color Module
 	var hue2rgb = function(m1, m2, h){
@@ -27,7 +25,7 @@ define(["./_base/kernel", "./_base/lang", "./_base/Color", "./_base/array"], fun
 		return m1;
 	};
 	// Override base Color.fromRgb with the impl in this module
-	dojo.colorFromRgb = Color.fromRgb = function(/*String*/ color, /*dojo.Color?*/ obj){
+	dojo.colorFromRgb = Color.fromRgb = function(/*String*/ color, /*dojo/_base/Color?*/ obj){
 		// summary:
 		//		get rgb(a) array from css-style color declarations
 		// description:
@@ -44,9 +42,9 @@ define(["./_base/kernel", "./_base/lang", "./_base/Color", "./_base/array"], fun
 						return parseFloat(x) * 2.56;
 					});
 					if(l == 4){ a[3] = c[3]; }
-					return Color.fromArray(a, obj); // dojo.Color
+					return Color.fromArray(a, obj); // dojo/_base/Color
 				}
-				return Color.fromArray(c, obj); // dojo.Color
+				return Color.fromArray(c, obj); // dojo/_base/Color
 			}
 			if((t == "hsl" && l == 3) || (t == "hsla" && l == 4)){
 				// normalize hsl values
@@ -64,10 +62,10 @@ define(["./_base/kernel", "./_base/lang", "./_base/Color", "./_base/array"], fun
 					1
 				];
 				if(l == 4){ a[3] = c[3]; }
-				return Color.fromArray(a, obj); // dojo.Color
+				return Color.fromArray(a, obj); // dojo/_base/Color
 			}
 		}
-		return null;	// dojo.Color
+		return null;	// dojo/_base/Color
 	};
 
 	var confine = function(c, low, high){
@@ -79,18 +77,20 @@ define(["./_base/kernel", "./_base/lang", "./_base/Color", "./_base/array"], fun
 	};
 
 	Color.prototype.sanitize = function(){
-		// summary: makes sure that the object has correct attributes
+		// summary:
+		//		makes sure that the object has correct attributes
 		var t = this;
 		t.r = Math.round(confine(t.r, 0, 255));
 		t.g = Math.round(confine(t.g, 0, 255));
 		t.b = Math.round(confine(t.b, 0, 255));
 		t.a = confine(t.a, 0, 1);
-		return this;	// dojo.Color
+		return this;	// dojo/_base/Color
 	};
 
 	ColorExt.makeGrey = Color.makeGrey = function(/*Number*/ g, /*Number?*/ a){
-		// summary: creates a greyscale color with an optional alpha
-		return Color.fromArray([g, g, g, a]);	// dojo.Color
+		// summary:
+		//		creates a greyscale color with an optional alpha
+		return Color.fromArray([g, g, g, a]);	// dojo/_base/Color
 	};
 
 	// mixin all CSS3 named colors not already in _base, along with SVG 1.0 variant spellings
@@ -228,5 +228,5 @@ define(["./_base/kernel", "./_base/lang", "./_base/Color", "./_base/array"], fun
 		"yellowgreen":	[154,205,50]
 	});
 
-	return Color;
+	return Color;	// TODO: return ColorExt, not Color
 });
diff --git a/dojo/cookie.js b/dojo/cookie.js
index ac1e0f2..50cef8e 100644
--- a/dojo/cookie.js
+++ b/dojo/cookie.js
@@ -1,55 +1,55 @@
-define(["./_base/kernel", "./regexp"], function(dojo, regexp) {
-	// module:
-	//		dojo/cookie
-	// summary:
-	//		TODOC
+define(["./_base/kernel", "./regexp"], function(dojo, regexp){
 
+// module:
+//		dojo/cookie
 
 /*=====
-dojo.__cookieProps = function(){
-	//	expires: Date|String|Number?
+var __cookieProps = {
+	// expires: Date|String|Number?
 	//		If a number, the number of days from today at which the cookie
 	//		will expire. If a date, the date past which the cookie will expire.
 	//		If expires is in the past, the cookie will be deleted.
 	//		If expires is omitted or is 0, the cookie will expire when the browser closes.
-	//	path: String?
+	// path: String?
 	//		The path to use for the cookie.
-	//	domain: String?
+	// domain: String?
 	//		The domain to use for the cookie.
-	//	secure: Boolean?
+	// secure: Boolean?
 	//		Whether to only send the cookie on secure connections
-	this.expires = expires;
-	this.path = path;
-	this.domain = domain;
-	this.secure = secure;
-}
+};
 =====*/
 
 
-dojo.cookie = function(/*String*/name, /*String?*/value, /*dojo.__cookieProps?*/props){
-	//	summary:
+dojo.cookie = function(/*String*/name, /*String?*/ value, /*__cookieProps?*/ props){
+	// summary:
 	//		Get or set a cookie.
-	//	description:
-	// 		If one argument is passed, returns the value of the cookie
-	// 		For two or more arguments, acts as a setter.
-	//	name:
+	// description:
+	//		If one argument is passed, returns the value of the cookie
+	//		For two or more arguments, acts as a setter.
+	// name:
 	//		Name of the cookie
-	//	value:
+	// value:
 	//		Value for the cookie
-	//	props:
+	// props:
 	//		Properties for the cookie
-	//	example:
+	// example:
 	//		set a cookie with the JSON-serialized contents of an object which
 	//		will expire 5 days from now:
-	//	|	dojo.cookie("configObj", dojo.toJson(config), { expires: 5 });
+	//	|	require(["dojo/cookie", "dojo/json"], function(cookie, json){
+	//	|		cookie("configObj", json.stringify(config, {expires: 5 }));
+	//	|	});
 	//
-	//	example:
+	// example:
 	//		de-serialize a cookie back into a JavaScript object:
-	//	|	var config = dojo.fromJson(dojo.cookie("configObj"));
+	//	|	require(["dojo/cookie", "dojo/json"], function(cookie, json){
+	//	|		config = json.parse(cookie("configObj"));
+	//	|	});
 	//
-	//	example:
+	// example:
 	//		delete a cookie:
-	//	|	dojo.cookie("configObj", null, {expires: -1});
+	//	|	require(["dojo/cookie"], function(cookie){
+	//	|		cookie("configObj", null, {expires: -1});
+	//	|	});
 	var c = document.cookie, ret;
 	if(arguments.length == 1){
 		var matches = c.match(new RegExp("(?:^|; )" + regexp.escapeString(name) + "=([^;]*)"));
@@ -78,7 +78,7 @@ dojo.cookie = function(/*String*/name, /*String?*/value, /*dojo.__cookieProps?*/
 };
 
 dojo.cookie.isSupported = function(){
-	//	summary:
+	// summary:
 	//		Use to determine if the current browser supports cookies or not.
 	//
 	//		Returns true if user allows cookies.
diff --git a/dojo/currency.js b/dojo/currency.js
index 30306ac..d69bc1d 100644
--- a/dojo/currency.js
+++ b/dojo/currency.js
@@ -1,26 +1,30 @@
-define(["./_base/kernel", "./_base/lang", "./_base/array", "./number", "./i18n", "./i18n!./cldr/nls/currency", "./cldr/monetary"], function(dojo, lang, darray, dnumber, i18n, nlsCurrency, cldrMonetary) {
-	// module:
-	//		dojo/currency
+define([
+	"./_base/array",
+	"./_base/lang",
+	/*===== "./_base/declare", =====*/
+	"./number",
+	"./i18n", "./i18n!./cldr/nls/currency",
+	"./cldr/monetary"
+], function(darray, lang, /*===== declare, =====*/ dnumber, i18n, nlsCurrency, cldrMonetary){
+
+// module:
+//		dojo/currency
+
+var currency = {
 	// summary:
-	//		TODOC
-
-lang.getObject("currency", true, dojo);
-
-/*=====
-dojo.currency = {
-	// summary: localized formatting and parsing routines for currencies
-	//
-	// description: extends dojo.number to provide culturally-appropriate formatting of values
-	//	in various world currencies, including use of a currency symbol.  The currencies are specified
-	//	by a three-letter international symbol in all uppercase, and support for the currencies is
-	//	provided by the data in `dojo.cldr`.  The scripts generating dojo.cldr specify which
-	//	currency support is included.  A fixed number of decimal places is determined based
-	//	on the currency type and is not determined by the 'pattern' argument.  The fractional
-	//	portion is optional, by default, and variable length decimals are not supported.
-}
-=====*/
+	//		localized formatting and parsing routines for currencies
+	// description:
+	//		extends dojo.number to provide culturally-appropriate formatting of values
+	//		in various world currencies, including use of a currency symbol.  The currencies are specified
+	//		by a three-letter international symbol in all uppercase, and support for the currencies is
+	//		provided by the data in `dojo.cldr`.  The scripts generating dojo.cldr specify which
+	//		currency support is included.  A fixed number of decimal places is determined based
+	//		on the currency type and is not determined by the 'pattern' argument.  The fractional
+	//		portion is optional, by default, and variable length decimals are not supported.
+};
+lang.setObject("dojo.currency", currency);
 
-dojo.currency._mixInDefaults = function(options){
+currency._mixInDefaults = function(options){
 	options = options || {};
 	options.type = "currency";
 
@@ -42,16 +46,16 @@ dojo.currency._mixInDefaults = function(options){
 };
 
 /*=====
-dojo.declare("dojo.currency.__FormatOptions", [dojo.number.__FormatOptions], {
-	//	type: String?
+currency.__FormatOptions = declare([dnumber.__FormatOptions], {
+	// type: String?
 	//		Should not be set.  Value is assumed to be "currency".
-	//	symbol: String?
+	// symbol: String?
 	//		localized currency symbol. The default will be looked up in table of supported currencies in `dojo.cldr`
 	//		A [ISO4217](http://en.wikipedia.org/wiki/ISO_4217) currency code will be used if not found.
-	//	currency: String?
+	// currency: String?
 	//		an [ISO4217](http://en.wikipedia.org/wiki/ISO_4217) currency code, a three letter sequence like "USD".
 	//		For use with dojo.currency only.
-	//	places: Number?
+	// places: Number?
 	//		number of decimal places to show.  Default is defined based on which currency is used.
 	type: "",
 	symbol: "",
@@ -60,73 +64,67 @@ dojo.declare("dojo.currency.__FormatOptions", [dojo.number.__FormatOptions], {
 });
 =====*/
 
-dojo.currency.format = function(/*Number*/value, /*dojo.currency.__FormatOptions?*/options){
-// summary:
-//		Format a Number as a currency, using locale-specific settings
-//
-// description:
-//		Create a string from a Number using a known, localized pattern.
-//		[Formatting patterns](http://www.unicode.org/reports/tr35/#Number_Elements)
-//		appropriate to the locale are chosen from the [CLDR](http://unicode.org/cldr)
-//		as well as the appropriate symbols and delimiters and number of decimal places.
-//
-// value:
-//		the number to be formatted.
-
-	return dnumber.format(value, dojo.currency._mixInDefaults(options));
+currency.format = function(/*Number*/ value, /*__FormatOptions?*/ options){
+	// summary:
+	//		Format a Number as a currency, using locale-specific settings
+	//
+	// description:
+	//		Create a string from a Number using a known, localized pattern.
+	//		[Formatting patterns](http://www.unicode.org/reports/tr35/#Number_Elements)
+	//		appropriate to the locale are chosen from the [CLDR](http://unicode.org/cldr)
+	//		as well as the appropriate symbols and delimiters and number of decimal places.
+	//
+	// value:
+	//		the number to be formatted.
+
+	return dnumber.format(value, currency._mixInDefaults(options));
 };
 
-dojo.currency.regexp = function(/*dojo.number.__RegexpOptions?*/options){
-//
-// summary:
-//		Builds the regular needed to parse a currency value
-//
-// description:
-//		Returns regular expression with positive and negative match, group and decimal separators
-//		Note: the options.places default, the number of decimal places to accept, is defined by the currency type.
-	return dnumber.regexp(dojo.currency._mixInDefaults(options)); // String
+currency.regexp = function(/*dnumber.__RegexpOptions?*/ options){
+	//
+	// summary:
+	//		Builds the regular needed to parse a currency value
+	//
+	// description:
+	//		Returns regular expression with positive and negative match, group and decimal separators
+	//		Note: the options.places default, the number of decimal places to accept, is defined by the currency type.
+	return dnumber.regexp(currency._mixInDefaults(options)); // String
 };
 
 /*=====
-dojo.declare("dojo.currency.__ParseOptions", [dojo.number.__ParseOptions], {
-	//	type: String?
+var __ParseOptions = currency.__ParseOptions = declare(dnumber.__ParseOptions, {
+	// type: String?
 	//		Should not be set.  Value is assumed to be currency.
-	//	currency: String?
+	// currency: String?
 	//		an [ISO4217](http://en.wikipedia.org/wiki/ISO_4217) currency code, a three letter sequence like "USD".
 	//		For use with dojo.currency only.
-	//	symbol: String?
+	// symbol: String?
 	//		localized currency symbol. The default will be looked up in table of supported currencies in `dojo.cldr`
 	//		A [ISO4217](http://en.wikipedia.org/wiki/ISO_4217) currency code will be used if not found.
-	//	places: Number?
+	// places: Number?
 	//		fixed number of decimal places to accept.  The default is determined based on which currency is used.
-	//	fractional: Boolean?|Array?
+	// fractional: Boolean|Array?
 	//		Whether to include the fractional portion, where the number of decimal places are implied by the currency
 	//		or explicit 'places' parameter.  The value [true,false] makes the fractional portion optional.
 	//		By default for currencies, it the fractional portion is optional.
-	type: "",
-	currency: "",
-	symbol: "",
-	places: "",
-	fractional: ""
 });
 =====*/
 
-dojo.currency.parse = function(/*String*/expression, /*dojo.currency.__ParseOptions?*/options){
+currency.parse = function(/*String*/ expression, /*__ParseOptions?*/ options){
 	//
 	// summary:
 	//		Convert a properly formatted currency string to a primitive Number,
 	//		using locale-specific settings.
-	//
 	// description:
 	//		Create a Number from a string using a known, localized pattern.
 	//		[Formatting patterns](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
 	//		are chosen appropriate to the locale, as well as the appropriate symbols and delimiters
 	//		and number of decimal places.
-	//
-	// expression: A string representation of a currency value
+	// expression:
+	//		A string representation of a currency value
 
-	return dnumber.parse(expression, dojo.currency._mixInDefaults(options));
+	return dnumber.parse(expression, currency._mixInDefaults(options));
 };
 
-return dojo.currency;
+return currency;
 });
diff --git a/dojo/data/ItemFileReadStore.js b/dojo/data/ItemFileReadStore.js
index 3c5df8f..03f1b7d 100644
--- a/dojo/data/ItemFileReadStore.js
+++ b/dojo/data/ItemFileReadStore.js
@@ -1,43 +1,41 @@
-define(["../_base/kernel", "../_base/lang", "../_base/declare", "../_base/array", "../_base/xhr", 
-	"../Evented", "../_base/window", "./util/filter", "./util/simpleFetch", "../date/stamp"
-], function(kernel, lang, declare, array, xhr, Evented, window, filterUtil, simpleFetch, dateStamp) {
-	// module:
-	//		dojo/data/ItemFileReadStore
-	// summary:
-	//		TODOC
+define(["../_base/kernel", "../_base/lang", "../_base/declare", "../_base/array", "../_base/xhr",
+	"../Evented", "./util/filter", "./util/simpleFetch", "../date/stamp"
+], function(kernel, lang, declare, array, xhr, Evented, filterUtil, simpleFetch, dateStamp){
 
+// module:
+//		dojo/data/ItemFileReadStore
 
 var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
-	//	summary:
-	//		The ItemFileReadStore implements the dojo.data.api.Read API and reads
+	// summary:
+	//		The ItemFileReadStore implements the dojo/data/api/Read API and reads
 	//		data from JSON files that have contents in this format --
-	//		{ items: [
-	//			{ name:'Kermit', color:'green', age:12, friends:['Gonzo', {_reference:{name:'Fozzie Bear'}}]},
-	//			{ name:'Fozzie Bear', wears:['hat', 'tie']},
-	//			{ name:'Miss Piggy', pets:'Foo-Foo'}
-	//		]}
-	//		Note that it can also contain an 'identifer' property that specified which attribute on the items
+	// |	{ items: [
+	// |		{ name:'Kermit', color:'green', age:12, friends:['Gonzo', {_reference:{name:'Fozzie Bear'}}]},
+	// |		{ name:'Fozzie Bear', wears:['hat', 'tie']},
+	// |		{ name:'Miss Piggy', pets:'Foo-Foo'}
+	// |	]}
+	//		Note that it can also contain an 'identifier' property that specified which attribute on the items
 	//		in the array of items that acts as the unique identifier for that item.
-	//
+
 	constructor: function(/* Object */ keywordParameters){
-		//	summary: constructor
-		//	keywordParameters: {url: String}
-		//	keywordParameters: {data: jsonObject}
-		//	keywordParameters: {typeMap: object)
+		// summary:
+		//		constructor
+		// keywordParameters:
+		//		{url: String} {data: jsonObject} {typeMap: object}
 		//		The structure of the typeMap object is as follows:
-		//		{
-		//			type0: function || object,
-		//			type1: function || object,
-		//			...
-		//			typeN: function || object
-		//		}
+		// |	{
+		// |		type0: function || object,
+		// |		type1: function || object,
+		// |		...
+		// |		typeN: function || object
+		// |	}
 		//		Where if it is a function, it is assumed to be an object constructor that takes the
 		//		value of _value as the initialization parameters.  If it is an object, then it is assumed
 		//		to be an object of general form:
-		//		{
-		//			type: function, //constructor.
-		//			deserialize:	function(value) //The function that parses the value and constructs the object defined by type appropriately.
-		//		}
+		// |	{
+		// |		type: function, //constructor.
+		// |		deserialize:	function(value) //The function that parses the value and constructs the object defined by type appropriately.
+		// |	}
 
 		this._arrayOfAllItems = [];
 		this._arrayOfTopLevelItems = [];
@@ -50,14 +48,14 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 		this._datatypeMap = keywordParameters.typeMap || {};
 		if(!this._datatypeMap['Date']){
 			//If no default mapping for dates, then set this as default.
-			//We use the dojo.date.stamp here because the ISO format is the 'dojo way'
+			//We use the dojo/date/stamp here because the ISO format is the 'dojo way'
 			//of generically representing dates.
 			this._datatypeMap['Date'] = {
-											type: Date,
-											deserialize: function(value){
-												return dateStamp.fromISOString(value);
-											}
-										};
+				type: Date,
+				deserialize: function(value){
+					return dateStamp.fromISOString(value);
+				}
+			};
 		}
 		this._features = {'dojo.data.api.Read':true, 'dojo.data.api.Identity':true};
 		this._itemsByIdentity = null;
@@ -91,60 +89,64 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 
 	typeMap: null, //Define so parser can populate.
 
-	//Parameter to allow users to specify if a close call should force a reload or not.
-	//By default, it retains the old behavior of not clearing if close is called.  But
-	//if set true, the store will be reset to default state.  Note that by doing this,
-	//all item handles will become invalid and a new fetch must be issued.
+	// clearOnClose: Boolean
+	//		Parameter to allow users to specify if a close call should force a reload or not.
+	//		By default, it retains the old behavior of not clearing if close is called.  But
+	//		if set true, the store will be reset to default state.  Note that by doing this,
+	//		all item handles will become invalid and a new fetch must be issued.
 	clearOnClose: false,
 
-	//Parameter to allow specifying if preventCache should be passed to the xhrGet call or not when loading data from a url.
-	//Note this does not mean the store calls the server on each fetch, only that the data load has preventCache set as an option.
-	//Added for tracker: #6072
+	// urlPreventCache: Boolean
+	//		Parameter to allow specifying if preventCache should be passed to the xhrGet call or not when loading data from a url.
+	//		Note this does not mean the store calls the server on each fetch, only that the data load has preventCache set as an option.
+	//		Added for tracker: #6072
 	urlPreventCache: false,
 
-	//Parameter for specifying that it is OK for the xhrGet call to fail silently.
+	// failOk: Boolean
+	//		Parameter for specifying that it is OK for the xhrGet call to fail silently.
 	failOk: false,
 
-	//Parameter to indicate to process data from the url as hierarchical
-	//(data items can contain other data items in js form).  Default is true
-	//for backwards compatibility.  False means only root items are processed
-	//as items, all child objects outside of type-mapped objects and those in
-	//specific reference format, are left straight JS data objects.
+	// hierarchical: Boolean
+	//		Parameter to indicate to process data from the url as hierarchical
+	//		(data items can contain other data items in js form).  Default is true
+	//		for backwards compatibility.  False means only root items are processed
+	//		as items, all child objects outside of type-mapped objects and those in
+	//		specific reference format, are left straight JS data objects.
 	hierarchical: true,
 
-	_assertIsItem: function(/* item */ item){
-		//	summary:
+	_assertIsItem: function(/* dojo/data/api/Item */ item){
+		// summary:
 		//		This function tests whether the item passed in is indeed an item in the store.
-		//	item:
+		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
-			throw new Error("dojo.data.ItemFileReadStore: Invalid item argument.");
+			throw new Error(this.declaredClass + ": Invalid item argument.");
 		}
 	},
 
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
-		//	summary:
+		// summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+		// attribute:
 		//		The attribute to test for being contained by the store.
 		if(typeof attribute !== "string"){
-			throw new Error("dojo.data.ItemFileReadStore: Invalid attribute argument.");
+			throw new Error(this.declaredClass + ": Invalid attribute argument.");
 		}
 	},
 
-	getValue: function(	/* item */ item,
-						/* attribute-name-string */ attribute,
-						/* value? */ defaultValue){
-		//	summary:
-		//		See dojo.data.api.Read.getValue()
+	getValue: function(	/* dojo/data/api/Item */ item,
+						   /* attribute-name-string */ attribute,
+						   /* value? */ defaultValue){
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		var values = this.getValues(item, attribute);
 		return (values.length > 0)?values[0]:defaultValue; // mixed
 	},
 
-	getValues: function(/* item */ item,
+	getValues: function(/* dojo/data/api/Item */ item,
 						/* attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.getValues()
+		// summary:
+		//		See dojo/data/api/Read.getValues()
 
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -152,9 +154,9 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 		return (item[attribute] || []).slice(0); // Array
 	},
 
-	getAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getAttributes()
+	getAttributes: function(/* dojo/data/api/Item */ item){
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
 		for(var key in item){
@@ -166,20 +168,20 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 		return attributes; // Array
 	},
 
-	hasAttribute: function(	/* item */ item,
-							/* attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.hasAttribute()
+	hasAttribute: function(	/* dojo/data/api/Item */ item,
+							   /* attribute-name-string */ attribute){
+		// summary:
+		//		See dojo/data/api/Read.hasAttribute()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		return (attribute in item);
 	},
 
-	containsValue: function(/* item */ item,
+	containsValue: function(/* dojo/data/api/Item */ item,
 							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary:
-		//		See dojo.data.api.Read.containsValue()
+		// summary:
+		//		See dojo/data/api/Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
 			regexp = filterUtil.patternToRegExp(value, false);
@@ -187,24 +189,23 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
 
-	_containsValue: function(	/* item */ item,
-								/* attribute-name-string */ attribute,
-								/* anything */ value,
-								/* RegExp?*/ regexp){
-		//	summary:
+	_containsValue: function(	/* dojo/data/api/Item */ item,
+								 /* attribute-name-string */ attribute,
+								 /* anything */ value,
+								 /* RegExp?*/ regexp){
+		// summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description:
+		// description:
 		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//
-		//	item:
+		// item:
 		//		The data item to examine for attribute values.
-		//	attribute:
+		// attribute:
 		//		The attribute to inspect.
-		//	value:
+		// value:
 		//		The value to match.
-		//	regexp:
+		// regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
 		//		If present and attribute values are string, then it can be used for comparison instead of 'value'
 		return array.some(this.getValues(item, attribute), function(possibleValue){
@@ -219,8 +220,8 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItem()
+		// summary:
+		//		See dojo/data/api/Read.isItem()
 		if(something && something[this._storeRefPropName] === this){
 			if(this._arrayOfAllItems[something[this._itemNumPropName]] === something){
 				return true;
@@ -230,101 +231,105 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItemLoaded()
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded()
 		return this.isItem(something); //boolean
 	},
 
 	loadItem: function(/* object */ keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Read.loadItem()
+		// summary:
+		//		See dojo/data/api/Read.loadItem()
 		this._assertIsItem(keywordArgs.item);
 	},
 
 	getFeatures: function(){
-		//	summary:
-		//		See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return this._features; //Object
 	},
 
-	getLabel: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
+	getLabel: function(/* dojo/data/api/Item */ item){
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		if(this._labelAttr && this.isItem(item)){
 			return this.getValue(item,this._labelAttr); //String
 		}
 		return undefined; //undefined
 	},
 
-	getLabelAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+	getLabelAttributes: function(/* dojo/data/api/Item */ item){
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		if(this._labelAttr){
 			return [this._labelAttr]; //array
 		}
 		return null; //null
 	},
 
-	_fetchItems: function(	/* Object */ keywordArgs,
-							/* Function */ findCallback,
-							/* Function */ errorCallback){
-		//	summary:
-		//		See dojo.data.util.simpleFetch.fetch()
-		var self = this,
-		    filter = function(requestArgs, arrayOfItems){
-			var items = [],
-			    i, key;
-			if(requestArgs.query){
-				var value,
-				    ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false;
-
-				//See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the
-				//same value for each item examined.  Much more efficient.
-				var regexpList = {};
-				for(key in requestArgs.query){
-					value = requestArgs.query[key];
-					if(typeof value === "string"){
-						regexpList[key] = filterUtil.patternToRegExp(value, ignoreCase);
-					}else if(value instanceof RegExp){
-						regexpList[key] = value;
-					}
+	filter: function(/* Object */ requestArgs, /* item[] */ arrayOfItems, /* Function */ findCallback){
+		// summary:
+		//		This method handles the basic filtering needs for ItemFile* based stores.
+		var items = [],
+			i, key;
+
+		if(requestArgs.query){
+			var value,
+				ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false;
+
+			//See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the
+			//same value for each item examined.  Much more efficient.
+			var regexpList = {};
+			for(key in requestArgs.query){
+				value = requestArgs.query[key];
+				if(typeof value === "string"){
+					regexpList[key] = filterUtil.patternToRegExp(value, ignoreCase);
+				}else if(value instanceof RegExp){
+					regexpList[key] = value;
 				}
-				for(i = 0; i < arrayOfItems.length; ++i){
-					var match = true;
-					var candidateItem = arrayOfItems[i];
-					if(candidateItem === null){
-						match = false;
-					}else{
-						for(key in requestArgs.query){
-							value = requestArgs.query[key];
-							if(!self._containsValue(candidateItem, key, value, regexpList[key])){
-								match = false;
-							}
+			}
+			for(i = 0; i < arrayOfItems.length; ++i){
+				var match = true;
+				var candidateItem = arrayOfItems[i];
+				if(candidateItem === null){
+					match = false;
+				}else{
+					for(key in requestArgs.query){
+						value = requestArgs.query[key];
+						if(!this._containsValue(candidateItem, key, value, regexpList[key])){
+							match = false;
 						}
 					}
-					if(match){
-						items.push(candidateItem);
-					}
 				}
-				findCallback(items, requestArgs);
-			}else{
-				// We want a copy to pass back in case the parent wishes to sort the array.
-				// We shouldn't allow resort of the internal list, so that multiple callers
-				// can get lists and sort without affecting each other.  We also need to
-				// filter out any null values that have been left as a result of deleteItem()
-				// calls in ItemFileWriteStore.
-				for(i = 0; i < arrayOfItems.length; ++i){
-					var item = arrayOfItems[i];
-					if(item !== null){
-						items.push(item);
-					}
+				if(match){
+					items.push(candidateItem);
+				}
+			}
+			findCallback(items, requestArgs);
+		}else{
+			// We want a copy to pass back in case the parent wishes to sort the array.
+			// We shouldn't allow resort of the internal list, so that multiple callers
+			// can get lists and sort without affecting each other.  We also need to
+			// filter out any null values that have been left as a result of deleteItem()
+			// calls in ItemFileWriteStore.
+			for(i = 0; i < arrayOfItems.length; ++i){
+				var item = arrayOfItems[i];
+				if(item !== null){
+					items.push(item);
 				}
-				findCallback(items, requestArgs);
 			}
-		};
+			findCallback(items, requestArgs);
+		}
+	},
+
+	_fetchItems: function(	/* Object */ keywordArgs,
+							  /* Function */ findCallback,
+							  /* Function */ errorCallback){
+		// summary:
+		//		See dojo/data/util.simpleFetch.fetch()
+		var self = this;
 
 		if(this._loadFinished){
-			filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions));
+			this.filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions), findCallback);
 		}else{
 			//Do a check on the JsonFileUrl and crosscheck it.
 			//If it doesn't match the cross-check, it needs to be updated
@@ -333,9 +338,9 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 			//compatibility.  People use _jsonFileUrl (even though officially
 			//private.
 			if(this._jsonFileUrl !== this._ccUrl){
-				kernel.deprecated("dojo.data.ItemFileReadStore: ",
+				kernel.deprecated(this.declaredClass + ": ",
 					"To change the url, set the url property of the store," +
-					" not _jsonFileUrl.  _jsonFileUrl support will be removed in 2.0");
+						" not _jsonFileUrl.  _jsonFileUrl support will be removed in 2.0");
 				this._ccUrl = this._jsonFileUrl;
 				this.url = this._jsonFileUrl;
 			}else if(this.url !== this._ccUrl){
@@ -354,15 +359,15 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 				//a load is in progress, we have to defer the fetching to be
 				//invoked in the callback.
 				if(this._loadInProgress){
-					this._queuedFetches.push({args: keywordArgs, filter: filter});
+					this._queuedFetches.push({args: keywordArgs, filter: lang.hitch(self, "filter"), findCallback: lang.hitch(self, findCallback)});
 				}else{
 					this._loadInProgress = true;
 					var getArgs = {
-							url: self._jsonFileUrl,
-							handleAs: "json-comment-optional",
-							preventCache: this.urlPreventCache,
-							failOk: this.failOk
-						};
+						url: self._jsonFileUrl,
+						handleAs: "json-comment-optional",
+						preventCache: this.urlPreventCache,
+						failOk: this.failOk
+					};
 					var getHandler = xhr.get(getArgs);
 					getHandler.addCallback(function(data){
 						try{
@@ -370,7 +375,7 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 							self._loadFinished = true;
 							self._loadInProgress = false;
 
-							filter(keywordArgs, self._getItemsArray(keywordArgs.queryOptions));
+							self.filter(keywordArgs, self._getItemsArray(keywordArgs.queryOptions), findCallback);
 							self._handleQueuedFetches();
 						}catch(e){
 							self._loadFinished = true;
@@ -407,27 +412,29 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 					this._loadFinished = true;
 					this._getItemsFromLoadedData(this._jsonData);
 					this._jsonData = null;
-					filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions));
+					self.filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions), findCallback);
 				}catch(e){
 					errorCallback(e, keywordArgs);
 				}
 			}else{
-				errorCallback(new Error("dojo.data.ItemFileReadStore: No JSON source data was provided as either URL or a nested Javascript object."), keywordArgs);
+				errorCallback(new Error(this.declaredClass + ": No JSON source data was provided as either URL or a nested Javascript object."), keywordArgs);
 			}
 		}
 	},
 
 	_handleQueuedFetches: function(){
-		//	summary:
+		// summary:
 		//		Internal function to execute delayed request in the store.
+		
 		//Execute any deferred fetches now.
 		if(this._queuedFetches.length > 0){
 			for(var i = 0; i < this._queuedFetches.length; i++){
 				var fData = this._queuedFetches[i],
-				    delayedQuery = fData.args,
-				    delayedFilter = fData.filter;
+					delayedQuery = fData.args,
+					delayedFilter = fData.filter,
+					delayedFindCallback = fData.findCallback;
 				if(delayedFilter){
-					delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions));
+					delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions), delayedFindCallback);
 				}else{
 					this.fetchItemByIdentity(delayedQuery);
 				}
@@ -437,58 +444,56 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 	},
 
 	_getItemsArray: function(/*object?*/queryOptions){
-		//	summary:
+		// summary:
 		//		Internal function to determine which list of items to search over.
-		//	queryOptions: The query options parameter, if any.
+		// queryOptions: The query options parameter, if any.
 		if(queryOptions && queryOptions.deep){
 			return this._arrayOfAllItems;
 		}
 		return this._arrayOfTopLevelItems;
 	},
 
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		 //	summary:
-		 //		See dojo.data.api.Read.close()
-		 if(this.clearOnClose &&
+	close: function(/*dojo/data/api/Request|Object?*/ request){
+		// summary:
+		//		See dojo/data/api/Read.close()
+		if(this.clearOnClose &&
 			this._loadFinished &&
 			!this._loadInProgress){
-			 //Reset all internalsback to default state.  This will force a reload
-			 //on next fetch.  This also checks that the data or url param was set
-			 //so that the store knows it can get data.  Without one of those being set,
-			 //the next fetch will trigger an error.
+			//Reset all internalsback to default state.  This will force a reload
+			//on next fetch.  This also checks that the data or url param was set
+			//so that the store knows it can get data.  Without one of those being set,
+			//the next fetch will trigger an error.
 
-			 if(((this._jsonFileUrl == "" || this._jsonFileUrl == null) &&
-				 (this.url == "" || this.url == null)
+			if(((this._jsonFileUrl == "" || this._jsonFileUrl == null) &&
+				(this.url == "" || this.url == null)
 				) && this.data == null){
-				 console.debug("dojo.data.ItemFileReadStore: WARNING!  Data reload " +
+				console.debug(this.declaredClass + ": WARNING!  Data reload " +
 					" information has not been provided." +
 					"  Please set 'url' or 'data' to the appropriate value before" +
 					" the next fetch");
-			 }
-			 this._arrayOfAllItems = [];
-			 this._arrayOfTopLevelItems = [];
-			 this._loadFinished = false;
-			 this._itemsByIdentity = null;
-			 this._loadInProgress = false;
-			 this._queuedFetches = [];
-		 }
+			}
+			this._arrayOfAllItems = [];
+			this._arrayOfTopLevelItems = [];
+			this._loadFinished = false;
+			this._itemsByIdentity = null;
+			this._loadInProgress = false;
+			this._queuedFetches = [];
+		}
 	},
 
 	_getItemsFromLoadedData: function(/* Object */ dataObject){
-		//	summary:
+		// summary:
 		//		Function to parse the loaded data into item format and build the internal items array.
-		//	description:
+		// description:
 		//		Function to parse the loaded data into item format and build the internal items array.
-		//
-		//	dataObject:
+		// dataObject:
 		//		The JS data object containing the raw data to convery into item format.
-		//
-		// 	returns: array
+		// returns: Array
 		//		Array of items in store item format.
 
 		// First, we define a couple little utility functions...
 		var addingArrays = false,
-		    self = this;
+			self = this;
 
 		function valueIsAnItem(/* anything */ aValue){
 			// summary:
@@ -515,7 +520,7 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 				self.hierarchical;
 		}
 
-		function addItemAndSubItemsToArrayOfAllItems(/* Item */ anItem){
+		function addItemAndSubItemsToArrayOfAllItems(/* dojo/data/api/Item */ anItem){
 			self._arrayOfAllItems.push(anItem);
 			for(var attribute in anItem){
 				var valueForAttribute = anItem[attribute];
@@ -545,7 +550,7 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 
 		// Step 1: Walk through the object hierarchy and build a list of all items
 		var i,
-		    item;
+			item;
 		this._arrayOfAllItems = [];
 		this._arrayOfTopLevelItems = dataObject.items;
 
@@ -567,7 +572,7 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 		// We also store the attribute names so we can validate our store
 		// reference and item id special properties for the O(1) isItem
 		var allAttributeNames = {},
-		    key;
+			key;
 
 		for(i = 0; i < this._arrayOfAllItems.length; ++i){
 			item = this._arrayOfAllItems[i];
@@ -616,9 +621,9 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 					this._itemsByIdentity[identity] = item;
 				}else{
 					if(this._jsonFileUrl){
-						throw new Error("dojo.data.ItemFileReadStore:  The json data as specified by: [" + this._jsonFileUrl + "] is malformed.  Items within the list have identifier: [" + identifier + "].  Value collided: [" + identity + "]");
+						throw new Error(this.declaredClass + ":  The json data as specified by: [" + this._jsonFileUrl + "] is malformed.  Items within the list have identifier: [" + identifier + "].  Value collided: [" + identity + "]");
 					}else if(this._jsonData){
-						throw new Error("dojo.data.ItemFileReadStore:  The json data provided by the creation arguments is malformed.  Items within the list have identifier: [" + identifier + "].  Value collided: [" + identity + "]");
+						throw new Error(this.declaredClass + ":  The json data provided by the creation arguments is malformed.  Items within the list have identifier: [" + identifier + "].  Value collided: [" + identity + "]");
 					}
 				}
 			}
@@ -680,7 +685,7 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 								// from an item like: { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] }
 								for(var k = 0; k < this._arrayOfAllItems.length; ++k){
 									var candidateItem = this._arrayOfAllItems[k],
-									    found = true;
+										found = true;
 									for(var refKey in referenceDescription){
 										if(candidateItem[refKey] != referenceDescription[refKey]){
 											found = false;
@@ -712,42 +717,42 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 	},
 
 	_addReferenceToMap: function(/*item*/ refItem, /*item*/ parentItem, /*string*/ attribute){
-		 //	summary:
-		 //		Method to add an reference map entry for an item and attribute.
-		 //	description:
-		 //		Method to add an reference map entry for an item and attribute. 		 //
-		 //	refItem:
-		 //		The item that is referenced.
-		 //	parentItem:
-		 //		The item that holds the new reference to refItem.
-		 //	attribute:
-		 //		The attribute on parentItem that contains the new reference.
-
-		 //Stub function, does nothing.  Real processing is in ItemFileWriteStore.
+		// summary:
+		//		Method to add an reference map entry for an item and attribute.
+		// description:
+		//		Method to add an reference map entry for an item and attribute.
+		// refItem:
+		//		The item that is referenced.
+		// parentItem:
+		//		The item that holds the new reference to refItem.
+		// attribute:
+		//		The attribute on parentItem that contains the new reference.
+
+		//Stub function, does nothing.  Real processing is in ItemFileWriteStore.
 	},
 
-	getIdentity: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Identity.getIdentity()
+	getIdentity: function(/* dojo/data/api/Item */ item){
+		// summary:
+		//		See dojo/data/api/Identity.getIdentity()
 		var identifier = this._features['dojo.data.api.Identity'];
 		if(identifier === Number){
 			return item[this._itemNumPropName]; // Number
 		}else{
 			var arrayOfValues = item[identifier];
 			if(arrayOfValues){
-				return arrayOfValues[0]; // Object || String
+				return arrayOfValues[0]; // Object|String
 			}
 		}
 		return null; // null
 	},
 
 	fetchItemByIdentity: function(/* Object */ keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Identity.fetchItemByIdentity()
+		// summary:
+		//		See dojo/data/api/Identity.fetchItemByIdentity()
 
 		// Hasn't loaded yet, we have to trigger the load.
 		var item,
-		    scope;
+			scope;
 		if(!this._loadFinished){
 			var self = this;
 			//Do a check on the JsonFileUrl and crosscheck it.
@@ -757,9 +762,9 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 			//compatibility.  People use _jsonFileUrl (even though officially
 			//private.
 			if(this._jsonFileUrl !== this._ccUrl){
-				kernel.deprecated("dojo.data.ItemFileReadStore: ",
+				kernel.deprecated(this.declaredClass + ": ",
 					"To change the url, set the url property of the store," +
-					" not _jsonFileUrl.  _jsonFileUrl support will be removed in 2.0");
+						" not _jsonFileUrl.  _jsonFileUrl support will be removed in 2.0");
 				this._ccUrl = this._jsonFileUrl;
 				this.url = this._jsonFileUrl;
 			}else if(this.url !== this._ccUrl){
@@ -780,14 +785,14 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 				}else{
 					this._loadInProgress = true;
 					var getArgs = {
-							url: self._jsonFileUrl,
-							handleAs: "json-comment-optional",
-							preventCache: this.urlPreventCache,
-							failOk: this.failOk
+						url: self._jsonFileUrl,
+						handleAs: "json-comment-optional",
+						preventCache: this.urlPreventCache,
+						failOk: this.failOk
 					};
 					var getHandler = xhr.get(getArgs);
 					getHandler.addCallback(function(data){
-						var scope = keywordArgs.scope?keywordArgs.scope:window.global;
+						var scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 						try{
 							self._getItemsFromLoadedData(data);
 							self._loadFinished = true;
@@ -807,7 +812,7 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 					getHandler.addErrback(function(error){
 						self._loadInProgress = false;
 						if(keywordArgs.onError){
-							var scope = keywordArgs.scope?keywordArgs.scope:window.global;
+							var scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 							keywordArgs.onError.call(scope, error);
 						}
 					});
@@ -820,7 +825,7 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 				self._loadFinished = true;
 				item = self._getItemByIdentity(keywordArgs.identity);
 				if(keywordArgs.onItem){
-					scope = keywordArgs.scope?keywordArgs.scope:window.global;
+					scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 			}
@@ -828,14 +833,14 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 			// Already loaded.  We can just look it up and call back.
 			item = this._getItemByIdentity(keywordArgs.identity);
 			if(keywordArgs.onItem){
-				scope = keywordArgs.scope?keywordArgs.scope:window.global;
+				scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 				keywordArgs.onItem.call(scope, item);
 			}
 		}
 	},
 
 	_getItemByIdentity: function(/* Object */ identity){
-		//	summary:
+		// summary:
 		//		Internal function to look an item up by its identity map.
 		var item = null;
 		if(this._itemsByIdentity){
@@ -853,14 +858,14 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 		return item; // Object
 	},
 
-	getIdentityAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Identity.getIdentityAttributes()
+	getIdentityAttributes: function(/* dojo/data/api/Item */ item){
+		// summary:
+		//		See dojo/data/api/Identity.getIdentityAttributes()
 
 		var identifier = this._features['dojo.data.api.Identity'];
 		if(identifier === Number){
 			// If (identifier === Number) it means getIdentity() just returns
-			// an integer item-number for each item.  The dojo.data.api.Identity
+			// an integer item-number for each item.  The dojo/data/api/Identity
 			// spec says we need to return null if the identity is not composed
 			// of attributes
 			return null; // null
@@ -870,7 +875,7 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 	},
 
 	_forceLoad: function(){
-		//	summary:
+		// summary:
 		//		Internal function to force a load of the store if it hasn't occurred yet.  This is required
 		//		for specific functions to work properly.
 		var self = this;
@@ -881,9 +886,9 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 		//compatibility.  People use _jsonFileUrl (even though officially
 		//private.
 		if(this._jsonFileUrl !== this._ccUrl){
-			kernel.deprecated("dojo.data.ItemFileReadStore: ",
+			kernel.deprecated(this.declaredClass + ": ",
 				"To change the url, set the url property of the store," +
-				" not _jsonFileUrl.  _jsonFileUrl support will be removed in 2.0");
+					" not _jsonFileUrl.  _jsonFileUrl support will be removed in 2.0");
 			this._ccUrl = this._jsonFileUrl;
 			this.url = this._jsonFileUrl;
 		}else if(this.url !== this._ccUrl){
@@ -898,13 +903,13 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 		}
 
 		if(this._jsonFileUrl){
-				var getArgs = {
-					url: this._jsonFileUrl,
-					handleAs: "json-comment-optional",
-					preventCache: this.urlPreventCache,
-					failOk: this.failOk,
-					sync: true
-				};
+			var getArgs = {
+				url: this._jsonFileUrl,
+				handleAs: "json-comment-optional",
+				preventCache: this.urlPreventCache,
+				failOk: this.failOk,
+				sync: true
+			};
 			var getHandler = xhr.get(getArgs);
 			getHandler.addCallback(function(data){
 				try{
@@ -921,7 +926,7 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 						//Okay, we hit an error state we can't recover from.  A forced load occurred
 						//while an async load was occurring.  Since we cannot block at this point, the best
 						//that can be managed is to throw an error.
-						throw new Error("dojo.data.ItemFileReadStore:  Unable to perform a synchronous load, an async load is in progress.");
+						throw new Error(this.declaredClass + ":  Unable to perform a synchronous load, an async load is in progress.");
 					}
 				}catch(e){
 					console.log(e);
@@ -942,4 +947,5 @@ var ItemFileReadStore = declare("dojo.data.ItemFileReadStore", [Evented],{
 lang.extend(ItemFileReadStore,simpleFetch);
 
 return ItemFileReadStore;
+
 });
diff --git a/dojo/data/ItemFileWriteStore.js b/dojo/data/ItemFileWriteStore.js
index 2bfadcf..3facd69 100644
--- a/dojo/data/ItemFileWriteStore.js
+++ b/dojo/data/ItemFileWriteStore.js
@@ -1,31 +1,32 @@
-define(["../_base/lang", "../_base/declare", "../_base/array", "../_base/json", "../_base/window", 
+define(["../_base/lang", "../_base/declare", "../_base/array", "../_base/json", "../_base/kernel",
 	"./ItemFileReadStore", "../date/stamp"
-], function(lang, declare, arrayUtil, jsonUtil, window, ItemFileReadStore, dateStamp) {
-	// module:
-	//		dojo/data/ItemFileWriteStore
+], function(lang, declare, arrayUtil, jsonUtil, kernel, ItemFileReadStore, dateStamp){
+
+// module:
+//		dojo/data/ItemFileWriteStore
+
+return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 	// summary:
 	//		TODOC
 
-/*===== var ItemFileReadStore = dojo.data.ItemFileReadStore; =====*/
-return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 	constructor: function(/* object */ keywordParameters){
-		//	keywordParameters: {typeMap: object)
+		// keywordParameters:
 		//		The structure of the typeMap object is as follows:
-		//		{
-		//			type0: function || object,
-		//			type1: function || object,
-		//			...
-		//			typeN: function || object
-		//		}
+		// |	{
+		// |		type0: function || object,
+		// |		type1: function || object,
+		// |		...
+		// |		typeN: function || object
+		// |	}
 		//		Where if it is a function, it is assumed to be an object constructor that takes the
 		//		value of _value as the initialization parameters.  It is serialized assuming object.toString()
 		//		serialization.  If it is an object, then it is assumed
 		//		to be an object of general form:
-		//		{
-		//			type: function, //constructor.
-		//			deserialize:	function(value) //The function that parses the value and constructs the object defined by type appropriately.
-		//			serialize:	function(object) //The function that converts the object back into the proper file format form.
-		//		}
+		// |	{
+		// |		type: function, //constructor.
+		// |		deserialize:	function(value) //The function that parses the value and constructs the object defined by type appropriately.
+		// |		serialize:	function(object) //The function that converts the object back into the proper file format form.
+		// |	}
 
 		// ItemFileWriteStore extends ItemFileReadStore to implement these additional dojo.data APIs
 		this._features['dojo.data.api.Write'] = true;
@@ -66,10 +67,11 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 	},
 
 
-/* dojo.data.api.Write */
+/* dojo/data/api/Write */
 
 	newItem: function(/* Object? */ keywordArgs, /* Object? */ parentInfo){
-		// summary: See dojo.data.api.Write.newItem()
+		// summary:
+		//		See dojo/data/api/Write.newItem()
 
 		this._assert(!this._saveInProgress);
 
@@ -163,8 +165,8 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 				// need to move all our private info to some other property
 				// of all the items/objects.  So, we need to iterate over all
 				// the items and do something like:
-				//    item.__S = item._S;
-				//    item._S = undefined;
+				//	  item.__S = item._S;
+				//	  item._S = undefined;
 				// But first we have to make sure the new "__S" variable is
 				// not in use, which means we have to iterate over all the
 				// items checking for that.
@@ -184,7 +186,7 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 				}
 			}
 		}
-		this.onNew(newItem, pInfo); // dojo.data.api.Notification call
+		this.onNew(newItem, pInfo); // dojo/data/api/Notification call
 		return newItem; // item
 	},
 
@@ -197,8 +199,9 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 		return false;
 	},
 
-	deleteItem: function(/* item */ item){
-		// summary: See dojo.data.api.Write.deleteItem()
+	deleteItem: function(/* dojo/data/api/Item */ item){
+		// summary:
+		//		See dojo/data/api/Write.deleteItem()
 		this._assert(!this._saveInProgress);
 		this._assertIsItem(item);
 
@@ -281,26 +284,29 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 		if(item[this._rootItemPropName]){
 			this._removeArrayElement(this._arrayOfTopLevelItems, item);
 		}
-		this.onDelete(item); // dojo.data.api.Notification call
+		this.onDelete(item); // dojo/data/api/Notification call
 		return true;
 	},
 
-	setValue: function(/* item */ item, /* attribute-name-string */ attribute, /* almost anything */ value){
-		// summary: See dojo.data.api.Write.set()
+	setValue: function(/* dojo/data/api/Item */ item, /* attribute-name-string */ attribute, /* almost anything */ value){
+		// summary:
+		//		See dojo/data/api/Write.set()
 		return this._setValueOrValues(item, attribute, value, true); // boolean
 	},
 
-	setValues: function(/* item */ item, /* attribute-name-string */ attribute, /* array */ values){
-		// summary: See dojo.data.api.Write.setValues()
+	setValues: function(/* dojo/data/api/Item */ item, /* attribute-name-string */ attribute, /* array */ values){
+		// summary:
+		//		See dojo/data/api/Write.setValues()
 		return this._setValueOrValues(item, attribute, values, true); // boolean
 	},
 
-	unsetAttribute: function(/* item */ item, /* attribute-name-string */ attribute){
-		// summary: See dojo.data.api.Write.unsetAttribute()
+	unsetAttribute: function(/* dojo/data/api/Item */ item, /* attribute-name-string */ attribute){
+		// summary:
+		//		See dojo/data/api/Write.unsetAttribute()
 		return this._setValueOrValues(item, attribute, [], true);
 	},
 
-	_setValueOrValues: function(/* item */ item, /* attribute-name-string */ attribute, /* anything */ newValueOrValues, /*boolean?*/ callOnSet){
+	_setValueOrValues: function(/* dojo/data/api/Item */ item, /* attribute-name-string */ attribute, /* anything */ newValueOrValues, /*boolean?*/ callOnSet){
 		this._assert(!this._saveInProgress);
 
 		// Check for valid arguments
@@ -367,7 +373,7 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 			var newValueArray;
 			if(lang.isArray(newValueOrValues)){
 				// Unfortunately, it's not safe to just do this:
-				//    newValueArray = newValueOrValues;
+				//	  newValueArray = newValueOrValues;
 				// Instead, we need to copy the array, which slice() does very nicely.
 				// This is so that our internal data structure won't
 				// get corrupted if the user mucks with the values array *after*
@@ -432,23 +438,23 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 			success = true;
 		}
 
-		// Now we make the dojo.data.api.Notification call
+		// Now we make the dojo/data/api/Notification call
 		if(callOnSet){
 			this.onSet(item, attribute, oldValueOrValues, newValueOrValues);
 		}
 		return success; // boolean
 	},
 
-	_addReferenceToMap: function(/* item */ refItem, /* item */ parentItem, /* string */ attribute){
-		//	summary:
+	_addReferenceToMap: function(/* dojo/data/api/Item */ refItem, /* dojo/data/api/Item */ parentItem, /* string */ attribute){
+		// summary:
 		//		Method to add an reference map entry for an item and attribute.
-		//	description:
-		//		Method to add an reference map entry for an item and attribute. 		 //
-		//	refItem:
+		// description:
+		//		Method to add an reference map entry for an item and attribute.
+		// refItem:
 		//		The item that is referenced.
-		//	parentItem:
+		// parentItem:
 		//		The item that holds the new reference to refItem.
-		//	attribute:
+		// attribute:
 		//		The attribute on parentItem that contains the new reference.
 
 		var parentId = this.getIdentity(parentItem);
@@ -464,19 +470,18 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 		itemRef[attribute] = true;
 	},
 
-	_removeReferenceFromMap: function(/* item */ refItem, /* item */ parentItem, /* string */ attribute){
-		//	summary:
+	_removeReferenceFromMap: function(/* dojo/data/api/Item */ refItem, /* dojo/data/api/Item */ parentItem, /* string */ attribute){
+		// summary:
 		//		Method to remove an reference map entry for an item and attribute.
-		//	description:
+		// description:
 		//		Method to remove an reference map entry for an item and attribute.  This will
 		//		also perform cleanup on the map such that if there are no more references at all to
 		//		the item, its reference object and entry are removed.
-		//
-		//	refItem:
+		// refItem:
 		//		The item that is referenced.
-		//	parentItem:
+		// parentItem:
 		//		The item holding a reference to refItem.
-		//	attribute:
+		// attribute:
 		//		The attribute on parentItem that contains the reference.
 		var identity = this.getIdentity(parentItem);
 		var references = refItem[this._reverseRefMap];
@@ -497,9 +502,9 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 	},
 
 	_dumpReferenceMap: function(){
-		//	summary:
+		// summary:
 		//		Function to dump the reverse reference map of all items in the store for debug purposes.
-		//	description:
+		// description:
 		//		Function to dump the reverse reference map of all items in the store for debug purposes.
 		var i;
 		for(i = 0; i < this._arrayOfAllItems.length; i++){
@@ -510,7 +515,7 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 		}
 	},
 
-	_getValueOrValues: function(/* item */ item, /* attribute-name-string */ attribute){
+	_getValueOrValues: function(/* dojo/data/api/Item */ item, /* attribute-name-string */ attribute){
 		var valueOrValues = undefined;
 		if(this.hasAttribute(item, attribute)){
 			var valueArray = this.getValues(item, attribute);
@@ -528,9 +533,9 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 			// Given an item, return an serializable object that provides a
 			// reference to the item.
 			// For example, given kermit:
-			//    var kermit = store.newItem({id:2, name:"Kermit"});
+			//	  var kermit = store.newItem({id:2, name:"Kermit"});
 			// we want to return
-			//    {_reference:2}
+			//	  {_reference:2}
 			return {_reference: this.getIdentity(value)};
 		}else{
 			if(typeof value === "object"){
@@ -543,7 +548,7 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 							}
 							return {_type: type, _value: typeMap.serialize(value)};
 						}
-					} else if(value instanceof typeMap){
+					}else if(value instanceof typeMap){
 						//SImple mapping, therefore, return as a toString serialization.
 						return {_type: type, _value: value.toString()};
 					}
@@ -594,9 +599,9 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 	},
 
 	_isEmpty: function(something){
-		//	summary:
+		// summary:
 		//		Function to determine if an array or object has no properties or values.
-		//	something:
+		// something:
 		//		The array or object to examine.
 		var empty = true;
 		if(lang.isObject(something)){
@@ -614,7 +619,8 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 	},
 
 	save: function(/* object */ keywordArgs){
-		// summary: See dojo.data.api.Write.save()
+		// summary:
+		//		See dojo/data/api/Write.save()
 		this._assert(!this._saveInProgress);
 
 		// this._saveInProgress is set to true, briefly, from when save is first called to when it completes
@@ -630,14 +636,14 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 
 			self._saveInProgress = false; // must come after this._pending is cleared, but before any callbacks
 			if(keywordArgs && keywordArgs.onComplete){
-				var scope = keywordArgs.scope || window.global;
+				var scope = keywordArgs.scope || kernel.global;
 				keywordArgs.onComplete.call(scope);
 			}
 		};
 		var saveFailedCallback = function(err){
 			self._saveInProgress = false;
 			if(keywordArgs && keywordArgs.onError){
-				var scope = keywordArgs.scope || window.global;
+				var scope = keywordArgs.scope || kernel.global;
 				keywordArgs.onError.call(scope, err);
 			}
 		};
@@ -658,7 +664,8 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 	},
 
 	revert: function(){
-		// summary: See dojo.data.api.Write.revert()
+		// summary:
+		//		See dojo/data/api/Write.revert()
 		this._assert(!this._saveInProgress);
 
 		var identity;
@@ -740,7 +747,8 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 	},
 
 	isDirty: function(/* item? */ item){
-		// summary: See dojo.data.api.Write.isDirty()
+		// summary:
+		//		See dojo/data/api/Write.isDirty()
 		if(item){
 			// return true if the item is dirty
 			var identity = this.getIdentity(item);
@@ -756,27 +764,30 @@ return declare("dojo.data.ItemFileWriteStore", ItemFileReadStore, {
 		}
 	},
 
-/* dojo.data.api.Notification */
+/* dojo/data/api/Notification */
 
-	onSet: function(/* item */ item,
+	onSet: function(/* dojo/data/api/Item */ item,
 					/*attribute-name-string*/ attribute,
 					/*object|array*/ oldValue,
 					/*object|array*/ newValue){
-		// summary: See dojo.data.api.Notification.onSet()
+		// summary:
+		//		See dojo/data/api/Notification.onSet()
 
 		// No need to do anything. This method is here just so that the
 		// client code can connect observers to it.
 	},
 
-	onNew: function(/* item */ newItem, /*object?*/ parentInfo){
-		// summary: See dojo.data.api.Notification.onNew()
+	onNew: function(/* dojo/data/api/Item */ newItem, /*object?*/ parentInfo){
+		// summary:
+		//		See dojo/data/api/Notification.onNew()
 
 		// No need to do anything. This method is here just so that the
 		// client code can connect observers to it.
 	},
 
-	onDelete: function(/* item */ deletedItem){
-		// summary: See dojo.data.api.Notification.onDelete()
+	onDelete: function(/* dojo/data/api/Item */ deletedItem){
+		// summary:
+		//		See dojo/data/api/Notification.onDelete()
 
 		// No need to do anything. This method is here just so that the
 		// client code can connect observers to it.
diff --git a/dojo/data/ObjectStore.js b/dojo/data/ObjectStore.js
index 20be74c..799353b 100644
--- a/dojo/data/ObjectStore.js
+++ b/dojo/data/ObjectStore.js
@@ -1,35 +1,44 @@
 define(["../_base/lang", "../Evented", "../_base/declare", "../_base/Deferred", "../_base/array", 
 	"../_base/connect", "../regexp"
-], function(lang, Evented, declare, Deferred, array, connect, regexp) {
-	// module:
-	//		dojo/data/ObjectStore
-	// summary:
-	//		TODOC
+], function(lang, Evented, declare, Deferred, array, connect, regexp){
 
+// module:
+//		dojo/data/ObjectStore
 
+function convertRegex(character){
+	return character == '*' ? '.*' : character == '?' ? '.' : character; 
+}
 return declare("dojo.data.ObjectStore", [Evented],{
+		// summary:
+		//		A Dojo Data implementation that wraps Dojo object stores for backwards
+		//		compatibility.
+
 		objectStore: null,
 		constructor: function(options){
-			// summary:
-			//		A Dojo Data implementation that wraps Dojo object stores for backwards
-			//		compatibility.
-			//	options:
+			// options:
 			//		The configuration information to pass into the data store.
-			//	options.objectStore:
+			//
+			//		- options.objectStore:
+			//
 			//		The object store to use as the source provider for this data store
+			
+			this._dirtyObjects = [];
+			if(options.labelAttribute){
+				// accept the old labelAttribute to make it easier to switch from old data stores
+				options.labelProperty = options.labelAttribute; 
+			}
 			lang.mixin(this, options);
 		},
 		labelProperty: "label",
 
 		getValue: function(/*Object*/ item, /*String*/property, /*value?*/defaultValue){
 			// summary:
-			//	Gets the value of an item's 'property'
-			//
-			//	item:
+			//		Gets the value of an item's 'property'
+			// item:
 			//		The item to get the value from
-			//	property:
+			// property:
 			//		property to look up value for
-			//	defaultValue:
+			// defaultValue:
 			//		the default value
 
 			return typeof item.get === "function" ? item.get(property) :
@@ -41,9 +50,8 @@ return declare("dojo.data.ObjectStore", [Evented],{
 			//		Gets the value of an item's 'property' and returns
 			//		it. If this value is an array it is just returned,
 			//		if not, the value is added to an array and that is returned.
-			//
-			//	item: /* object */
-			//	property: /* string */
+			// item: Object
+			// property: String
 			//		property to look up value for
 
 			var val = this.getValue(item,property);
@@ -52,10 +60,9 @@ return declare("dojo.data.ObjectStore", [Evented],{
 
 		getAttributes: function(item){
 			// summary:
-			//	Gets the available attributes of an item's 'property' and returns
-			//	it as an array.
-			//
-			//	item: /* object */
+			//		Gets the available attributes of an item's 'property' and returns
+			//		it as an array.
+			// item: Object
 
 			var res = [];
 			for(var i in item){
@@ -69,19 +76,22 @@ return declare("dojo.data.ObjectStore", [Evented],{
 		hasAttribute: function(item,attribute){
 			// summary:
 			//		Checks to see if item has attribute
-			//
-			//	item: /* object */
-			//	attribute: /* string */
+			// item: Object
+			//		The item to check
+			// attribute: String
+			//		The attribute to check
 			return attribute in item;
 		},
 
 		containsValue: function(item, attribute, value){
 			// summary:
 			//		Checks to see if 'item' has 'value' at 'attribute'
-			//
-			//	item: /* object */
-			//	attribute: /* string */
-			//	value: /* anything */
+			// item: Object
+			//		The item to check
+			// attribute: String
+			//		The attribute to check
+			// value: Anything
+			//		The value to look for
 			return array.indexOf(this.getValues(item,attribute),value) > -1;
 		},
 
@@ -89,20 +99,19 @@ return declare("dojo.data.ObjectStore", [Evented],{
 		isItem: function(item){
 			// summary:
 			//		Checks to see if the argument is an item
-			//
-			//	item: /* object */
-			//	attribute: /* string */
+			// item: Object
+			//		The item to check
 
 			// we have no way of determining if it belongs, we just have object returned from
-			//	service queries
+			// service queries
 			return (typeof item == 'object') && item && !(item instanceof Date);
 		},
 
 		isItemLoaded: function(item){
 			// summary:
 			//		Checks to see if the item is loaded.
-			//
-			//		item: /* object */
+			// item: Object
+			//		The item to check
 
 			return item && typeof item.load !== "function";
 		},
@@ -114,14 +123,15 @@ return declare("dojo.data.ObjectStore", [Evented],{
 			//		that an item is loaded is situations when the item may or may not be loaded yet.
 			//		If you access a value directly through property access, you can use this to load
 			//		a lazy value as well (doesn't need to be an item).
-			//
-			//	example:
-			//		store.loadItem({
-			//			item: item, // this item may or may not be loaded
-			//			onItem: function(item){
-			//				// do something with the item
-			//			}
-			//		});
+			// args: Object
+			//		See dojo/data/api/Read.fetch()
+			// example:
+			//	|	store.loadItem({
+			//	|		item: item, // this item may or may not be loaded
+			//	|		onItem: function(item){
+			//	|			// do something with the item
+			//	|		}
+			//	|	});
 
 			var item;
 			if(typeof args.item.load === "function"){
@@ -140,12 +150,13 @@ return declare("dojo.data.ObjectStore", [Evented],{
 			return item;
 		},
 		close: function(request){
+			// summary:
+			// 		See dojo/data/api/Read.close()
 			return request && request.abort && request.abort();
 		},
 		fetch: function(args){
 			// summary:
-			//		See dojo.data.api.Read.fetch
-			//
+			//		See dojo/data/api/Read.fetch()
 
 			args = lang.delegate(args, args && args.queryOptions);
 			var self = this;
@@ -157,11 +168,11 @@ return declare("dojo.data.ObjectStore", [Evented],{
 					// find any strings and convert them to regular expressions for wildcard support
 					var required = query[i];
 					if(typeof required == "string"){
-						query[i] = RegExp("^" + regexp.escapeString(required, "*?").replace(/\*/g, '.*').replace(/\?/g, '.') + "$", args.ignoreCase ? "mi" : "m");
+						query[i] = RegExp("^" + regexp.escapeString(required, "*?\\").replace(/\\.|\*|\?/g, convertRegex) + "$", args.ignoreCase ? "mi" : "m");
 						query[i].toString = (function(original){
 							return function(){
 								return original;
-							}
+							};
 						})(required);
 					}
 				}
@@ -234,18 +245,18 @@ return declare("dojo.data.ObjectStore", [Evented],{
 			};
 		},
 
-		getLabel: function(/* item */ item){
-			//	summary:
-			//		See dojo.data.api.Read.getLabel()
+		getLabel: function(/* dojo/data/api/Item */ item){
+			// summary:
+			//		See dojo/data/api/Read.getLabel()
 			if(this.isItem(item)){
 				return this.getValue(item,this.labelProperty); //String
 			}
 			return undefined; //undefined
 		},
 
-		getLabelAttributes: function(/* item */ item){
-			//	summary:
-			//		See dojo.data.api.Read.getLabelAttributes()
+		getLabelAttributes: function(/* dojo/data/api/Item */ item){
+			// summary:
+			//		See dojo/data/api/Read.getLabelAttributes()
 			return [this.labelProperty]; //array
 		},
 
@@ -253,6 +264,9 @@ return declare("dojo.data.ObjectStore", [Evented],{
 
 
 		getIdentity: function(item){
+			// summary:
+			//		returns the identity of the given item
+			//		See dojo/data/api/Read.getIdentity()
 			return this.objectStore.getIdentity ? this.objectStore.getIdentity(item) : item[this.objectStore.idProperty || "id"];
 		},
 
@@ -260,6 +274,7 @@ return declare("dojo.data.ObjectStore", [Evented],{
 			// summary:
 			//		returns the attributes which are used to make up the
 			//		identity of an item.	Basically returns this.objectStore.idProperty
+			//		See dojo/data/api/Read.getIdentityAttributes()
 
 			return [this.objectStore.idProperty];
 		},
@@ -284,11 +299,11 @@ return declare("dojo.data.ObjectStore", [Evented],{
 			// summary:
 			//		adds a new item to the store at the specified point.
 			//		Takes two parameters, data, and options.
-			//
-			//	data: Object
+			// data: Object
 			//		The data to be added in as an item.
-			
-			// TODOC: parentInfo
+			// data: Object
+			//		See dojo/data/api/Write.newItem()
+					
 			if(parentInfo){
 				// get the previous value or any empty array
 				var values = this.getValue(parentInfo.parent,parentInfo.attribute,[]);
@@ -304,13 +319,11 @@ return declare("dojo.data.ObjectStore", [Evented],{
 		deleteItem: function(item){
 			// summary:
 			//		deletes item and any references to that item from the store.
-			//
-			//	item:
+			// item:
 			//		item to delete
-			//
 
-			//	If the desire is to delete only one reference, unsetAttribute or
-			//	setValue is the way to go.
+			// If the desire is to delete only one reference, unsetAttribute or
+			// setValue is the way to go.
 			this.changing(item, true);
 
 			this.onDelete(item);
@@ -318,7 +331,8 @@ return declare("dojo.data.ObjectStore", [Evented],{
 		setValue: function(item, attribute, value){
 			// summary:
 			//		sets 'attribute' on 'item' to 'value'
-
+			//		See dojo/data/api/Write.setValue()
+			
 			var old = item[attribute];
 			this.changing(item);
 			item[attribute]=value;
@@ -326,8 +340,9 @@ return declare("dojo.data.ObjectStore", [Evented],{
 		},
 		setValues: function(item, attribute, values){
 			// summary:
-			//	sets 'attribute' on 'item' to 'value' value
-			//	must be an array.
+			//		sets 'attribute' on 'item' to 'value' value
+			//		must be an array.
+			//		See dojo/data/api/Write.setValues()
 
 			if(!lang.isArray(values)){
 				throw new Error("setValues expects to be passed an Array object as its value");
@@ -338,6 +353,7 @@ return declare("dojo.data.ObjectStore", [Evented],{
 		unsetAttribute: function(item, attribute){
 			// summary:
 			//		unsets 'attribute' on 'item'
+			//		See dojo/data/api/Write.unsetAttribute()
 
 			this.changing(item);
 			var old = item[attribute];
@@ -345,14 +361,17 @@ return declare("dojo.data.ObjectStore", [Evented],{
 			this.onSet(item,attribute,old,undefined);
 		},
 
-		_dirtyObjects: [],
-
 		changing: function(object,_deleting){
 			// summary:
 			//		adds an object to the list of dirty objects.  This object
 			//		contains a reference to the object itself as well as a
 			//		cloned and trimmed version of old object for use with
 			//		revert.
+			// object: Object
+			//		Indicates that the given object is changing and should be marked as 
+			// 		dirty for the next save
+			// _deleting: [private] Boolean
+			
 			object.__isDirty = true;
 			//if an object is already in the list of dirty objects, don't add it again
 			//or it will overwrite the premodification data set.
@@ -380,18 +399,23 @@ return declare("dojo.data.ObjectStore", [Evented],{
 
 		save: function(kwArgs){
 			// summary:
-			//		Saves the dirty data using object store provider. See dojo.data.api.Write for API.
+			//		Saves the dirty data using object store provider. See dojo/data/api/Write for API.
+			// kwArgs:
+			//		- kwArgs.global:
+			//		  This will cause the save to commit the dirty data for all
+			//		  ObjectStores as a single transaction.
 			//
-			//	kwArgs.global:
-			//		This will cause the save to commit the dirty data for all
-			//		ObjectStores as a single transaction.
+			//		- kwArgs.revertOnError:
+			//		  This will cause the changes to be reverted if there is an
+			//		  error on the save. By default a revert is executed unless
+			//		  a value of false is provide for this parameter.
 			//
-			//	kwArgs.revertOnError
-			//		This will cause the changes to be reverted if there is an
-			//		error on the save. By default a revert is executed unless
-			//		a value of false is provide for this parameter.
+			//		- kwArgs.onError:
+			//		  Called when an error occurs in the commit
+			//
+			//		- kwArgs.onComplete:
+			//		  Called when an the save/commit is completed
 
-			// TODOC: kwArgs pseudo
 			kwArgs = kwArgs || {};
 			var result, actions = [];
 			var savingObjects = [];
@@ -448,10 +472,10 @@ return declare("dojo.data.ObjectStore", [Evented],{
 			}
 		},
 
-		revert: function(kwArgs){
+		revert: function(){
 			// summary:
 			//		returns any modified data to its original state prior to a save();
-			//
+
 			var dirtyObjects = this._dirtyObjects;
 			for(var i = dirtyObjects.length; i > 0;){
 				i--;
@@ -487,18 +511,33 @@ return declare("dojo.data.ObjectStore", [Evented],{
 		isDirty: function(item){
 			// summary:
 			//		returns true if the item is marked as dirty or true if there are any dirty items
+			// item: Object
+			//		The item to check
 			if(!item){
 				return !!this._dirtyObjects.length;
 			}
 			return item.__isDirty;
 		},
-		//Notifcation Support
 
-		onSet: function(){},
-		onNew: function(){},
-		onDelete:	function(){},
+		// Notification Support
+
+		onSet: function(){
+			// summary:
+			// 		See dojo/data/api/Notification.onSet()
+		},
+		onNew: function(){
+			// summary:
+			// 		See dojo/data/api/Notification.onNew()
+		},
+		onDelete:	function(){
+			// summary:
+			// 		See dojo/data/api/Notification.onDelete()
+		},
 		// an extra to get result sets
-		onFetch: function(results){}
+		onFetch: function(results){
+			// summary:
+			// 		Called when a fetch occurs			
+		}
 
 	}
 );
diff --git a/dojo/data/api/Identity.js b/dojo/data/api/Identity.js
index af074ea..3174960 100644
--- a/dojo/data/api/Identity.js
+++ b/dojo/data/api/Identity.js
@@ -1,43 +1,41 @@
-define(["../..", "./Read"], function(dojo) {
-	// module:
-	//		dojo/data/api/Identity
-	// summary:
-	//		TODOC
+define(["../../_base/declare", "./Read"], function(declare, Read){
 
+// module:
+//		dojo/data/api/Identity
 
-dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
-	//	summary:
+return declare("dojo.data.api.Identity", Read, {
+	// summary:
 	//		This is an abstract API that data provider implementations conform to.
 	//		This file defines methods signatures and intentionally leaves all the
 	//		methods unimplemented.
 
 	getFeatures: function(){
-		//	summary:
-		//		See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			 'dojo.data.api.Read': true,
 			 'dojo.data.api.Identity': true
 		};
 	},
 
-	getIdentity: function(/* item */ item){
-		//	summary:
+	getIdentity: function(/* dojo/data/api/Item */ item){
+		// summary:
 		//		Returns a unique identifier for an item.  The return value will be
 		//		either a string or something that has a toString() method (such as,
-		//		for example, a dojox.uuid.Uuid object).
-		//	item:
+		//		for example, a dojox/uuid object).
+		// item:
 		//		The item from the store from which to obtain its identifier.
-		//	exceptions:
+		// exceptions:
 		//		Conforming implementations may throw an exception or return null if
 		//		item is not an item.
-		//	example:
+		// example:
 		//	|	var itemId = store.getIdentity(kermit);
 		//	|	assert(kermit === store.findByIdentity(store.getIdentity(kermit)));
 		throw new Error('Unimplemented API: dojo.data.api.Identity.getIdentity');
 	},
 
-	getIdentityAttributes: function(/* item */ item){
-		//	summary:
+	getIdentityAttributes: function(/* dojo/data/api/Item */ item){
+		// summary:
 		//		Returns an array of attribute names that are used to generate the identity.
 		//		For most stores, this is a single attribute, but for some complex stores
 		//		such as RDB backed stores that use compound (multi-attribute) identifiers
@@ -46,10 +44,10 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 		//		the attributes that comprise the identity so that so that during a render
 		//		of all attributes, the UI can hide the the identity information if it
 		//		chooses.
-		//	item:
+		// item:
 		//		The item from the store from which to obtain the array of public attributes that
 		//		compose the identifier, if any.
-		//	example:
+		// example:
 		//	|	var itemId = store.getIdentity(kermit);
 		//	|	var identifiers = store.getIdentityAttributes(itemId);
 		//	|	assert(typeof identifiers === "array" || identifiers === null);
@@ -58,38 +56,42 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 
 
 	fetchItemByIdentity: function(/* object */ keywordArgs){
-		//	summary:
+		// summary:
 		//		Given the identity of an item, this method returns the item that has
 		//		that identity through the onItem callback.  Conforming implementations
 		//		should return null if there is no item with the given identity.
 		//		Implementations of fetchItemByIdentity() may sometimes return an item
 		//		from a local cache and may sometimes fetch an item from a remote server,
-		//
-		// 	keywordArgs:
+		// keywordArgs:
 		//		An anonymous object that defines the item to locate and callbacks to invoke when the
 		//		item has been located and load has completed.  The format of the object is as follows:
-		//		{
-		//			identity: string|object,
-		//			onItem: Function,
-		//			onError: Function,
-		//			scope: object
-		//		}
-		//	The *identity* parameter.
+		// |	{
+		// |		identity: string|object,
+		// |		onItem: Function,
+		// |		onError: Function,
+		// |		scope: object
+		// |	}
+		//
+		//	 	####The *identity* parameter
+		//
 		//		The identity parameter is the identity of the item you wish to locate and load
 		//		This attribute is required.  It should be a string or an object that toString()
 		//		can be called on.
 		//
-		//	The *onItem* parameter.
+		//	 	####The *onItem* parameter
+		//
 		//		Function(item)
 		//		The onItem parameter is the callback to invoke when the item has been loaded.  It takes only one
 		//		parameter, the item located, or null if none found.
 		//
-		//	The *onError* parameter.
+		//	 	####The *onError* parameter
+		//
 		//		Function(error)
 		//		The onError parameter is the callback to invoke when the item load encountered an error.  It takes only one
 		//		parameter, the error object
 		//
-		//	The *scope* parameter.
+		//	 	####The *scope* parameter
+		//
 		//		If a scope object is provided, all of the callback functions (onItem,
 		//		onError, etc) will be invoked in the context of the scope object.
 		//		In the body of the callback function, the value of the "this"
@@ -97,11 +99,11 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 		//		the callback functions will be called in the context of dojo.global.
 		//		For example, onItem.call(scope, item, request) vs.
 		//		onItem.call(dojo.global, item, request)
+
 		if(!this.isItemLoaded(keywordArgs.item)){
 			throw new Error('Unimplemented API: dojo.data.api.Identity.fetchItemByIdentity');
 		}
 	}
 });
 
-return dojo.data.api.Identity;
 });
diff --git a/dojo/data/api/Item.js b/dojo/data/api/Item.js
new file mode 100644
index 0000000..4229610
--- /dev/null
+++ b/dojo/data/api/Item.js
@@ -0,0 +1,13 @@
+define(["../../_base/declare"], function(declare){
+
+	// module:
+	//		dojo/data/api/Item
+
+	return declare(null, {
+		// summary:
+		//		An item in a dojo/data store
+		//		Class for documentation purposes only. An item can take any form, so no 
+		// 		properties or methods are defined here.
+	});
+
+});
diff --git a/dojo/data/api/Notification.js b/dojo/data/api/Notification.js
index 0e814e3..9a3805c 100644
--- a/dojo/data/api/Notification.js
+++ b/dojo/data/api/Notification.js
@@ -1,17 +1,14 @@
-define(["../..", "./Read"], function(dojo) {
-	// module:
-	//		dojo/data/api/Notification
-	// summary:
-	//		TODOC
+define(["../../_base/declare", "./Read"], function(declare, Read){
 
+// module:
+//		dojo/data/api/Notification
 
-dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
-	//	summary:
+return declare("dojo.data.api.Notification", Read, {
+	// summary:
 	//		This is an abstract API that data provider implementations conform to.
 	//		This file defines functions signatures and intentionally leaves all the
 	//		functions unimplemented.
-	//
-	//	description:
+	// description:
 	//		This API defines a set of APIs that all datastores that conform to the
 	//		Notifications API must implement.  In general, most stores will implement
 	//		these APIs as no-op functions for users who wish to monitor them to be able
@@ -21,102 +18,93 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
 	//		this feature.  In the case of a read-only store, this feature makes sense if
 	//		the store itself does internal polling to a back-end server and periodically updates
 	//		its cache of items (deletes, adds, and updates).
-	//
-	//	example:
-	//
-	//	|	function onSet(item, attribute, oldValue, newValue) {
+	// example:
+	//	|	function onSet(item, attribute, oldValue, newValue){
 	//	|		//Do something with the information...
 	//	|	};
 	//	|	var store = new some.newStore();
 	//	|	dojo.connect(store, "onSet", onSet);
 
 	getFeatures: function(){
-		//	summary:
-		//		See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true,
 			'dojo.data.api.Notification': true
 		};
 	},
 
-	onSet: function(/* item */ item,
+	onSet: function(/* dojo/data/api/Item */ item,
 					/* attribute-name-string */ attribute,
 					/* object|array */ oldValue,
 					/* object|array */ newValue){
-		//	summary:
+		// summary:
 		//		This function is called any time an item is modified via setValue, setValues, unsetAttribute, etc.
-		//	description:
+		// description:
 		//		This function is called any time an item is modified via setValue, setValues, unsetAttribute, etc.
 		//		Its purpose is to provide a hook point for those who wish to monitor actions on items in the store
 		//		in a simple manner.  The general expected usage is to dojo.connect() to the store's
 		//		implementation and be called after the store function is called.
-		//
-		//	item:
+		// item:
 		//		The item being modified.
-		//	attribute:
+		// attribute:
 		//		The attribute being changed represented as a string name.
-		//	oldValue:
+		// oldValue:
 		//		The old value of the attribute.  In the case of single value calls, such as setValue, unsetAttribute, etc,
 		//		this value will be generally be an atomic value of some sort (string, int, etc, object).  In the case of
 		//		multi-valued attributes, it will be an array.
-		//	newValue:
+		// newValue:
 		//		The new value of the attribute.  In the case of single value calls, such as setValue, this value will be
 		//		generally be an atomic value of some sort (string, int, etc, object).  In the case of multi-valued attributes,
 		//		it will be an array.  In the case of unsetAttribute, the new value will be 'undefined'.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		throw new Error('Unimplemented API: dojo.data.api.Notification.onSet');
 	},
 
-	onNew: function(/* item */ newItem, /*object?*/ parentInfo){
-		//	summary:
+	onNew: function(/* dojo/data/api/Item */ newItem, /*object?*/ parentInfo){
+		// summary:
 		//		This function is called any time a new item is created in the store.
 		//		It is called immediately after the store newItem processing has completed.
-		//	description:
+		// description:
 		//		This function is called any time a new item is created in the store.
 		//		It is called immediately after the store newItem processing has completed.
-		//
-		//	newItem:
+		// newItem:
 		//		The item created.
-		//	parentInfo:
+		// parentInfo:
 		//		An optional javascript object that is passed when the item created was placed in the store
 		//		hierarchy as a value f another item's attribute, instead of a root level item.  Note that if this
 		//		function is invoked with a value for parentInfo, then onSet is not invoked stating the attribute of
 		//		the parent item was modified.  This is to avoid getting two notification  events occurring when a new item
 		//		with a parent is created.  The structure passed in is as follows:
-		//		{
-		//			item: someItem,							//The parent item
-		//			attribute:	"attribute-name-string",	//The attribute the new item was assigned to.
-		//			oldValue: something	//Whatever was the previous value for the attribute.
-		//						//If it is a single-value attribute only, then this value will be a single value.
-		//						//If it was a multi-valued attribute, then this will be an array of all the values minues the new one.
-		//			newValue: something	//The new value of the attribute.  In the case of single value calls, such as setValue, this value will be
-		//						//generally be an atomic value of some sort (string, int, etc, object).  In the case of multi-valued attributes,
-		//						//it will be an array.
-		//		}
-		//
-		//	returns:
+		// |	{
+		// |		item: someItem,							//The parent item
+		// |		attribute:	"attribute-name-string",	//The attribute the new item was assigned to.
+		// |		oldValue: something	//Whatever was the previous value for the attribute.
+		// |					//If it is a single-value attribute only, then this value will be a single value.
+		// |					//If it was a multi-valued attribute, then this will be an array of all the values minus the new one.
+		// |		newValue: something	//The new value of the attribute.  In the case of single value calls, such as setValue, this value will be
+		// |					//generally be an atomic value of some sort (string, int, etc, object).  In the case of multi-valued attributes,
+		// |					//it will be an array.
+		// |	}
+		// returns:
 		//		Nothing.
 		throw new Error('Unimplemented API: dojo.data.api.Notification.onNew');
 	},
 
-	onDelete: function(/* item */ deletedItem){
-		//	summary:
+	onDelete: function(/* dojo/data/api/Item */ deletedItem){
+		// summary:
 		//		This function is called any time an item is deleted from the store.
 		//		It is called immediately after the store deleteItem processing has completed.
-		//	description:
+		// description:
 		//		This function is called any time an item is deleted from the store.
 		//		It is called immediately after the store deleteItem processing has completed.
-		//
-		//	deletedItem:
+		// deletedItem:
 		//		The item deleted.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		throw new Error('Unimplemented API: dojo.data.api.Notification.onDelete');
 	}
 });
 
-return dojo.data.api.Notification;
 });
diff --git a/dojo/data/api/Read.js b/dojo/data/api/Read.js
index 359dafa..cbbf977 100644
--- a/dojo/data/api/Read.js
+++ b/dojo/data/api/Read.js
@@ -1,18 +1,16 @@
-define(["../..", "./Request"], function(dojo) {
-	// module:
-	//		dojo/data/api/Read
-	// summary:
-	//		TODOC
+define(["../../_base/declare"], function(declare){
 
+// module:
+//		dojo/data/api/Read
 
-dojo.declare("dojo.data.api.Read", null, {
+return declare("dojo.data.api.Read", null, {
 	// summary:
 	//		This is an abstract API that data provider implementations conform to.
 	//		This file defines methods signatures and intentionally leaves all the
 	//		methods unimplemented.  For more information on the dojo.data APIs,
 	//		please visit: http://www.dojotoolkit.org/node/98
 
-	getValue: function(	/* item */ item,
+	getValue: function(	/* dojo/data/api/Item */ item,
 						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
 		// summary:
@@ -43,10 +41,10 @@ dojo.declare("dojo.data.api.Read", null, {
 		throw new Error('Unimplemented API: dojo.data.api.Read.getValue');
 	},
 
-	getValues: function(/* item */ item,
+	getValues: function(/* dojo/data/api/Item */ item,
 						/* attribute-name-string */ attribute){
 		// summary:
-		// 		This getValues() method works just like the getValue() method, but getValues()
+		//		This getValues() method works just like the getValue() method, but getValues()
 		//		always returns an array rather than a single attribute value.  The array
 		//		may be empty, may contain a single attribute value, or may contain
 		//		many attribute values.
@@ -66,7 +64,7 @@ dojo.declare("dojo.data.api.Read", null, {
 		throw new Error('Unimplemented API: dojo.data.api.Read.getValues');
 	},
 
-	getAttributes: function(/* item */ item){
+	getAttributes: function(/* dojo/data/api/Item */ item){
 		// summary:
 		//		Returns an array with all the attributes that this item has.  This
 		//		method will always return an array; if the item has no attributes
@@ -80,7 +78,7 @@ dojo.declare("dojo.data.api.Read", null, {
 		throw new Error('Unimplemented API: dojo.data.api.Read.getAttributes');
 	},
 
-	hasAttribute: function(	/* item */ item,
+	hasAttribute: function(	/* dojo/data/api/Item */ item,
 							/* attribute-name-string */ attribute){
 		// summary:
 		//		Returns true if the given *item* has a value for the given *attribute*.
@@ -95,7 +93,7 @@ dojo.declare("dojo.data.api.Read", null, {
 		throw new Error('Unimplemented API: dojo.data.api.Read.hasAttribute');
 	},
 
-	containsValue: function(/* item */ item,
+	containsValue: function(/* dojo/data/api/Item */ item,
 							/* attribute-name-string */ attribute,
 							/* anything */ value){
 		// summary:
@@ -141,7 +139,7 @@ dojo.declare("dojo.data.api.Read", null, {
 		throw new Error('Unimplemented API: dojo.data.api.Read.isItemLoaded');
 	},
 
-	loadItem: function(/* object */ keywordArgs){
+	loadItem: function(/* Object */ keywordArgs){
 		// summary:
 		//		Given an item, this method loads the item so that a subsequent call
 		//		to store.isItemLoaded(item) will return true.  If a call to
@@ -149,30 +147,35 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		then loadItem() need not do any work at all and will not even invoke
 		//		the callback handlers.  So, before invoking this method, check that
 		//		the item has not already been loaded.
-		// 	keywordArgs:
+		// keywordArgs:
 		//		An anonymous object that defines the item to load and callbacks to invoke when the
 		//		load has completed.  The format of the object is as follows:
-		//		{
-		//			item: object,
-		//			onItem: Function,
-		//			onError: Function,
-		//			scope: object
-		//		}
-		//	The *item* parameter.
+		// |	{
+		// |		item: object,
+		// |		onItem: Function,
+		// |		onError: Function,
+		// |		scope: object
+		// |	}
+		//
+		//		####The *item* parameter
+		//
 		//		The item parameter is an object that represents the item in question that should be
 		//		contained by the store.  This attribute is required.
 		//
-		//	The *onItem* parameter.
+		//		####The *onItem* parameter
+		//
 		//		Function(item)
 		//		The onItem parameter is the callback to invoke when the item has been loaded.  It takes only one
 		//		parameter, the fully loaded item.
 		//
-		//	The *onError* parameter.
+		//		####The *onError* parameter
+		//
 		//		Function(error)
 		//		The onError parameter is the callback to invoke when the item load encountered an error.  It takes only one
 		//		parameter, the error object
 		//
-		//	The *scope* parameter.
+		//		####The *scope* parameter
+		//
 		//		If a scope object is provided, all of the callback functions (onItem,
 		//		onError, etc) will be invoked in the context of the scope object.
 		//		In the body of the callback function, the value of the "this"
@@ -191,7 +194,6 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		this method executes the query and makes the results available as data items.
 		//		The format and expectations of stores is that they operate in a generally asynchronous
 		//		manner, therefore callbacks are always used to return items located by the fetch parameters.
-		//
 		// description:
 		//		A Request object will always be returned and is returned immediately.
 		//		The basic request is nothing more than the keyword args passed to fetch and
@@ -201,33 +203,33 @@ dojo.declare("dojo.data.api.Read", null, {
 		//
 		//		This does not mean that custom stores can not add methods and properties to the request object
 		//		returned, only that the API does not require it.  For more info about the Request API,
-		//		see dojo.data.api.Request
-		//
+		//		see dojo/data/api/Request
 		// keywordArgs:
 		//		The keywordArgs parameter may either be an instance of
-		//		conforming to dojo.data.api.Request or may be a simple anonymous object
+		//		conforming to dojo/data/api/Request or may be a simple anonymous object
 		//		that may contain any of the following:
-		//		{
-		//			query: query-object or query-string,
-		//			queryOptions: object,
-		//			onBegin: Function,
-		//			onItem: Function,
-		//			onComplete: Function,
-		//			onError: Function,
-		//			scope: object,
-		//			start: int
-		//			count: int
-		//			sort: array
-		//		}
+		// |	{
+		// |		query: query-object or query-string,
+		// |		queryOptions: object,
+		// |		onBegin: Function,
+		// |		onItem: Function,
+		// |		onComplete: Function,
+		// |		onError: Function,
+		// |		scope: object,
+		// |		start: int
+		// |		count: int
+		// |		sort: array
+		// |	}
 		//		All implementations should accept keywordArgs objects with any of
 		//		the 9 standard properties: query, onBegin, onItem, onComplete, onError
 		//		scope, sort, start, and count.  Some implementations may accept additional
 		//		properties in the keywordArgs object as valid parameters, such as
 		//		{includeOutliers:true}.
 		//
-		//	The *query* parameter.
+		//		####The *query* parameter
+		//
 		//		The query may be optional in some data store implementations.
-		//		The dojo.data.api.Read API does not specify the syntax or semantics
+		//		The dojo/data/api/Read API does not specify the syntax or semantics
 		//		of the query itself -- each different data store implementation
 		//		may have its own notion of what a query should look like.
 		//		However, as of dojo 0.9, 1.0, and 1.1, all the provided datastores in dojo.data
@@ -237,26 +239,29 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		when they dynamically update the query.  Therefore, for maximum compatibility with dijit
 		//		widgets the recommended query parameter is a key/value object.  That does not mean that the
 		//		the datastore may not take alternative query forms, such as a simple string, a Date, a number,
-		//		or a mix of such.  Ultimately, The dojo.data.api.Read API is agnostic about what the query
+		//		or a mix of such.  Ultimately, The dojo/data/api/Read API is agnostic about what the query
 		//		format.
+		//
 		//		Further note:  In general for query objects that accept strings as attribute
 		//		value matches, the store should also support basic filtering capability, such as *
 		//		(match any character) and ? (match single character).  An example query that is a query object
 		//		would be like: { attrFoo: "value*"}.  Which generally means match all items where they have
 		//		an attribute named attrFoo, with a value that starts with 'value'.
 		//
-		//	The *queryOptions* parameter
-		//		The queryOptions parameter is an optional parameter used to specify optiosn that may modify
+		//		####The *queryOptions* parameter
+		//
+		//		The queryOptions parameter is an optional parameter used to specify options that may modify
 		//		the query in some fashion, such as doing a case insensitive search, or doing a deep search
 		//		where all items in a hierarchical representation of data are scanned instead of just the root
 		//		items.  It currently defines two options that all datastores should attempt to honor if possible:
-		//		{
-		//			ignoreCase: boolean, //Whether or not the query should match case sensitively or not.  Default behaviour is false.
-		//			deep: boolean 	//Whether or not a fetch should do a deep search of items and all child
-		//							//items instead of just root-level items in a datastore.  Default is false.
-		//		}
+		// |	{
+		// |		ignoreCase: boolean, // Whether or not the query should match case sensitively or not.  Default behaviour is false.
+		// |		deep: boolean 	// Whether or not a fetch should do a deep search of items and all child
+		// |						// items instead of just root-level items in a datastore.  Default is false.
+		// |	}
+		//
+		//		####The *onBegin* parameter.
 		//
-		//	The *onBegin* parameter.
 		//		function(size, request);
 		//		If an onBegin callback function is provided, the callback function
 		//		will be called just once, before the first onItem callback is called.
@@ -266,14 +271,17 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		collection of items returned from the query, as the request may have specified to return only a
 		//		subset of the total set of items through the use of the start and count parameters.
 		//
-		//	The *onItem* parameter.
+		//		####The *onItem* parameter.
+		//
 		//		function(item, request);
+		//
 		//		If an onItem callback function is provided, the callback function
 		//		will be called as each item in the result is received. The callback
 		//		function will be passed two arguments: the item itself, and the
 		//		Request object.
 		//
-		//	The *onComplete* parameter.
+		//		####The *onComplete* parameter.
+		//
 		//		function(items, request);
 		//
 		//		If an onComplete callback function is provided, the callback function
@@ -283,15 +291,18 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		If the onItem callback is present, then onComplete is called as:
 		//		onComplete(null, request).
 		//
-		//	The *onError* parameter.
+		//		####The *onError* parameter.
+		//
 		//		function(errorData, request);
+		//
 		//		If an onError callback function is provided, the callback function
 		//		will be called if there is any sort of error while attempting to
 		//		execute the query.
 		//		The onError callback function will be passed two arguments:
 		//		an Error object and the Request object.
 		//
-		//	The *scope* parameter.
+		//		####The *scope* parameter.
+		//
 		//		If a scope object is provided, all of the callback functions (onItem,
 		//		onComplete, onError, etc) will be invoked in the context of the scope
 		//		object.  In the body of the callback function, the value of the "this"
@@ -300,34 +311,36 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		For example, onItem.call(scope, item, request) vs.
 		//		onItem.call(dojo.global(), item, request)
 		//
-		//	The *start* parameter.
+		//		####The *start* parameter.
+		//
 		//		If a start parameter is specified, this is a indication to the datastore to
 		//		only start returning items once the start number of items have been located and
 		//		skipped.  When this parameter is paired with 'count', the store should be able
 		//		to page across queries with millions of hits by only returning subsets of the
 		//		hits for each query
 		//
-		//	The *count* parameter.
+		//		####The *count* parameter.
+		//
 		//		If a count parameter is specified, this is a indication to the datastore to
 		//		only return up to that many items.  This allows a fetch call that may have
 		//		millions of item matches to be paired down to something reasonable.
 		//
-		//	The *sort* parameter.
+		//		####The *sort* parameter.
+		//
 		//		If a sort parameter is specified, this is a indication to the datastore to
 		//		sort the items in some manner before returning the items.  The array is an array of
 		//		javascript objects that must conform to the following format to be applied to the
 		//		fetching of items:
-		//		{
-		//			attribute: attribute || attribute-name-string,
-		//			descending: true|false;   // Optional.  Default is false.
-		//		}
+		// |	{
+		// |		attribute: attribute || attribute-name-string,
+		// |		descending: true|false;   // Optional.  Default is false.
+		// |	}
 		//		Note that when comparing attributes, if an item contains no value for the attribute
 		//		(undefined), then it the default ascending sort logic should push it to the bottom
 		//		of the list.  In the descending order case, it such items should appear at the top of the list.
-		//
 		// returns:
 		//		The fetch() method will return a javascript object conforming to the API
-		//		defined in dojo.data.api.Request.  In general, it will be the keywordArgs
+		//		defined in dojo/data/api/Request.  In general, it will be the keywordArgs
 		//		object returned with the required functions in Request.js attached.
 		//		Its general purpose is to provide a convenient way for a caller to abort an
 		//		ongoing fetch.
@@ -335,11 +348,9 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		The Request object may also have additional properties when it is returned
 		//		such as request.store property, which is a pointer to the datastore object that
 		//		fetch() is a method of.
-		//
 		// exceptions:
 		//		Throws an exception if the query is not valid, or if the query
 		//		is required but was not supplied.
-		//
 		// example:
 		//		Fetch all books identified by the query and call 'showBooks' when complete
 		//		|	var request = store.fetch({query:"all books", onComplete: showBooks});
@@ -370,7 +381,7 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		|	var request = store.fetch({query:{author:"King"}, queryOptions:(ignoreCase: true}, start: 0, count:100, onComplete: showKing});
 		// example:
 		//		Paging
-		//		|	var store = new dojo.data.LargeRdbmsStore({url:"jdbc:odbc:foobar"});
+		//		|	var store = new LargeRdbmsStore({url:"jdbc:odbc:foobar"});
 		//		|	var fetchArgs = {
 		//		|		query: {type:"employees", name:"Hillary *"}, // string matching
 		//		|		sort: [{attribute:"department", descending:true}],
@@ -395,37 +406,34 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		The getFeatures() method returns an simple keyword values object
 		//		that specifies what interface features the datastore implements.
 		//		A simple CsvStore may be read-only, and the only feature it
-		//		implements will be the 'dojo.data.api.Read' interface, so the
+		//		implements will be the 'dojo/data/api/Read' interface, so the
 		//		getFeatures() method will return an object like this one:
 		//		{'dojo.data.api.Read': true}.
 		//		A more sophisticated datastore might implement a variety of
-		//		interface features, like 'dojo.data.api.Read', 'dojo.data.api.Write',
-		//		'dojo.data.api.Identity', and 'dojo.data.api.Attribution'.
+		//		interface features, like 'dojo.data.api.Read', 'dojo/data/api/Write',
+		//		'dojo.data.api.Identity', and 'dojo/data/api/Attribution'.
 		return {
 			'dojo.data.api.Read': true
 		};
 	},
 
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
+	close: function(/*dojo/data/api/Request|Object?*/ request){
 		// summary:
 		//		The close() method is intended for instructing the store to 'close' out
 		//		any information associated with a particular request.
-		//
 		// description:
 		//		The close() method is intended for instructing the store to 'close' out
 		//		any information associated with a particular request.  In general, this API
-		//		expects to recieve as a parameter a request object returned from a fetch.
+		//		expects to receive as a parameter a request object returned from a fetch.
 		//		It will then close out anything associated with that request, such as
 		//		clearing any internal datastore caches and closing any 'open' connections.
 		//		For some store implementations, this call may be a no-op.
-		//
 		// request:
 		//		An instance of a request for the store to use to identify what to close out.
 		//		If no request is passed, then the store should clear all internal caches (if any)
 		//		and close out all 'open' connections.  It does not render the store unusable from
 		//		there on, it merely cleans out any current data and resets the store to initial
 		//		state.
-		//
 		// example:
 		//	|	var request = store.fetch({onComplete: doSomething});
 		//	|	...
@@ -433,11 +441,10 @@ dojo.declare("dojo.data.api.Read", null, {
 		throw new Error('Unimplemented API: dojo.data.api.Read.close');
 	},
 
-	getLabel: function(/* item */ item){
+	getLabel: function(/* dojo/data/api/Item */ item){
 		// summary:
 		//		Method to inspect the item and return a user-readable 'label' for the item
 		//		that provides a general/adequate description of what the item is.
-		//
 		// description:
 		//		Method to inspect the item and return a user-readable 'label' for the item
 		//		that provides a general/adequate description of what the item is.  In general
@@ -449,31 +456,26 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		to customize how a store instance labels items should replace the getLabel() function on
 		//		their instance of the store, or extend the store and replace the function in
 		//		the extension class.
-		//
 		// item:
 		//		The item to return the label for.
-		//
 		// returns:
 		//		A user-readable string representing the item or undefined if no user-readable label can
 		//		be generated.
 		throw new Error('Unimplemented API: dojo.data.api.Read.getLabel');
 	},
 
-	getLabelAttributes: function(/* item */ item){
+	getLabelAttributes: function(/* dojo/data/api/Item */ item){
 		// summary:
 		//		Method to inspect the item and return an array of what attributes of the item were used
 		//		to generate its label, if any.
-		//
 		// description:
 		//		Method to inspect the item and return an array of what attributes of the item were used
 		//		to generate its label, if any.  This function is to assist UI developers in knowing what
 		//		attributes can be ignored out of the attributes an item has when displaying it, in cases
 		//		where the UI is using the label as an overall identifer should they wish to hide
 		//		redundant information.
-		//
 		// item:
 		//		The item to return the list of label attributes for.
-		//
 		// returns:
 		//		An array of attribute names that were used to generate the label, or null if public attributes
 		//		were not used to generate the label.
@@ -481,5 +483,4 @@ dojo.declare("dojo.data.api.Read", null, {
 	}
 });
 
-return dojo.data.api.Read;
 });
diff --git a/dojo/data/api/Request.js b/dojo/data/api/Request.js
index 1c6af9f..f06fb80 100644
--- a/dojo/data/api/Request.js
+++ b/dojo/data/api/Request.js
@@ -1,36 +1,33 @@
-define(["../.."], function(dojo) {
-	// module:
-	//		dojo/data/api/Request
-	// summary:
-	//		TODOC
+define(["../../_base/declare"], function(declare){
 
+// module:
+//		dojo/data/api/Request
 
-dojo.declare("dojo.data.api.Request", null, {
-	//	summary:
+return declare("dojo.data.api.Request", null, {
+	// summary:
 	//		This class defines out the semantics of what a 'Request' object looks like
 	//		when returned from a fetch() method.  In general, a request object is
 	//		nothing more than the original keywordArgs from fetch with an abort function
 	//		attached to it to allow users to abort a particular request if they so choose.
 	//		No other functions are required on a general Request object return.  That does not
-	//		inhibit other store implementations from adding extentions to it, of course.
+	//		inhibit other store implementations from adding extensions to it, of course.
 	//
 	//		This is an abstract API that data provider implementations conform to.
 	//		This file defines methods signatures and intentionally leaves all the
 	//		methods unimplemented.
 	//
-	//		For more details on fetch, see dojo.data.api.Read.fetch().
+	//		For more details on fetch, see dojo/data/api/Read.fetch().
 
 	abort: function(){
-		//	summary:
+		// summary:
 		//		This function is a hook point for stores to provide as a way for
 		//		a fetch to be halted mid-processing.
-		//	description:
+		// description:
 		//		This function is a hook point for stores to provide as a way for
 		//		a fetch to be halted mid-processing.  For more details on the fetch() api,
-		//		please see dojo.data.api.Read.fetch().
+		//		please see dojo/data/api/Read.fetch().
 		throw new Error('Unimplemented API: dojo.data.api.Request.abort');
 	}
 });
 
-return dojo.data.api.Request;
 });
diff --git a/dojo/data/api/Write.js b/dojo/data/api/Write.js
index a793cdd..2753d68 100644
--- a/dojo/data/api/Write.js
+++ b/dojo/data/api/Write.js
@@ -1,19 +1,17 @@
-define(["../..", "./Read"], function(dojo) {
-	// module:
-	//		dojo/data/api/Write
-	// summary:
-	//		TODOC
+define(["../../_base/declare", "./Read"], function(declare, Read){
 
+// module:
+//		dojo/data/api/Write
 
-dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
+return declare("dojo.data.api.Write", Read, {
 	// summary:
 	//		This is an abstract API that data provider implementations conform to.
 	//		This file defines function signatures and intentionally leaves all the
-	//		functionss unimplemented.
+	//		functions unimplemented.
 
 	getFeatures: function(){
 		// summary:
-		//		See dojo.data.api.Read.getFeatures()
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true,
 			'dojo.data.api.Write': true
@@ -29,9 +27,8 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		in the new item.  In addition, for stores that support hierarchical item
 		//		creation, an optional second parameter is accepted that defines what item is the parent
 		//		of the new item and what attribute of that item should the new item be assigned to.
-		//		In general, this will assume that the attribute targetted is multi-valued and a new item
+		//		In general, this will assume that the attribute targeted is multi-valued and a new item
 		//		is appended onto the list of values for that attribute.
-		//
 		// keywordArgs:
 		//		A javascript object defining the initial content of the item as a set of JavaScript 'property name: value' pairs.
 		// parentInfo:
@@ -39,11 +36,10 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		and what attribute of that parent to assign the new item to.  If this is present, and the attribute specified
 		//		is a multi-valued attribute, it will append this item into the array of values for that attribute.  The structure
 		//		of the object is as follows:
-		//		{
-		//			parent: someItem,
-		//			attribute: "attribute-name-string"
-		//		}
-		//
+		//	|	{
+		//	|		parent: someItem,
+		//	|		attribute: "attribute-name-string"
+		//	|	}
 		// exceptions:
 		//		Throws an exception if *keywordArgs* is a string or a number or
 		//		anything other than a simple anonymous object.
@@ -55,13 +51,11 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		throw new Error('Unimplemented API: dojo.data.api.Write.newItem');
 	},
 
-	deleteItem: function(/* item */ item){
+	deleteItem: function(/* dojo/data/api/Item */ item){
 		// summary:
 		//		Deletes an item from the store.
-		//
 		// item:
 		//		The item to delete.
-		//
 		// exceptions:
 		//		Throws an exception if the argument *item* is not an item
 		//		(if store.isItem(item) returns false).
@@ -70,20 +64,18 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		throw new Error('Unimplemented API: dojo.data.api.Write.deleteItem');
 	},
 
-	setValue: function(	/* item */ item,
+	setValue: function(	/* dojo/data/api/Item */ item,
 						/* string */ attribute,
 						/* almost anything */ value){
 		// summary:
 		//		Sets the value of an attribute on an item.
 		//		Replaces any previous value or values.
-		//
 		// item:
 		//		The item to modify.
 		// attribute:
 		//		The attribute of the item to change represented as a string name.
 		// value:
 		//		The value to assign to the item.
-		//
 		// exceptions:
 		//		Throws an exception if *item* is not an item, or if *attribute*
 		//		is neither an attribute object or a string.
@@ -93,7 +85,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		throw new Error('Unimplemented API: dojo.data.api.Write.setValue');
 	},
 
-	setValues: function(/* item */ item,
+	setValues: function(/* dojo/data/api/Item */ item,
 						/* string */ attribute,
 						/* array */ values){
 		// summary:
@@ -102,40 +94,36 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		Replaces any previous value or values.
 		//		Calling store.setValues(x, y, []) (with *values* as an empty array) has
 		//		the same effect as calling store.unsetAttribute(x, y).
-		//
 		// item:
 		//		The item to modify.
 		// attribute:
 		//		The attribute of the item to change represented as a string name.
 		// values:
 		//		An array of values to assign to the attribute..
-		//
 		// exceptions:
 		//		Throws an exception if *values* is not an array, if *item* is not an
 		//		item, or if *attribute* is neither an attribute object or a string.
 		// example:
 		//	|	var success = store.setValues(kermit, "color", ["green", "aqua"]);
 		//	|	success = store.setValues(kermit, "color", []);
-		//	|	if (success) {assert(!store.hasAttribute(kermit, "color"));}
+		//	|	if (success){assert(!store.hasAttribute(kermit, "color"));}
 		throw new Error('Unimplemented API: dojo.data.api.Write.setValues');
 	},
 
-	unsetAttribute: function(	/* item */ item,
+	unsetAttribute: function(	/* dojo/data/api/Item */ item,
 								/* string */ attribute){
 		// summary:
 		//		Deletes all the values of an attribute on an item.
-		//
 		// item:
 		//		The item to modify.
 		// attribute:
 		//		The attribute of the item to unset represented as a string.
-		//
 		// exceptions:
 		//		Throws an exception if *item* is not an item, or if *attribute*
 		//		is neither an attribute object or a string.
 		// example:
 		//	|	var success = store.unsetAttribute(kermit, "color");
-		//	|	if (success) {assert(!store.hasAttribute(kermit, "color"));}
+		//	|	if (success){assert(!store.hasAttribute(kermit, "color"));}
 		throw new Error('Unimplemented API: dojo.data.api.Write.clear');
 	},
 
@@ -145,22 +133,23 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		The save operation may take some time and is generally performed
 		//		in an asynchronous fashion.  The outcome of the save action is
 		//		is passed into the set of supported callbacks for the save.
-		//
 		// keywordArgs:
-		//		{
-		//			onComplete: function
-		//			onError: function
-		//			scope: object
-		//		}
+		// |	{
+		// |		onComplete: function
+		// |		onError: function
+		// |		scope: object
+		// |	}
+		//
+		//		####The *onComplete* parameter.
 		//
-		//	The *onComplete* parameter.
 		//		function();
 		//
 		//		If an onComplete callback function is provided, the callback function
 		//		will be called just once, after the save has completed.  No parameters
 		//		are generally passed to the onComplete.
 		//
-		//	The *onError* parameter.
+		//		####The *onError* parameter.
+		//
 		//		function(errorData);
 		//
 		//		If an onError callback function is provided, the callback function
@@ -168,7 +157,8 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		execute the save.  The onError function will be based one parameter, the
 		//		error.
 		//
-		//	The *scope* parameter.
+		//		####The *scope* parameter.
+		//
 		//		If a scope object is provided, all of the callback function (
 		//		onComplete, onError, etc) will be invoked in the context of the scope
 		//		object.  In the body of the callback function, the value of the "this"
@@ -176,7 +166,6 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		the callback functions will be called in the context of dojo.global.
 		//		For example, onComplete.call(scope) vs.
 		//		onComplete.call(dojo.global)
-		//
 		// returns:
 		//		Nothing.  Since the saves are generally asynchronous, there is
 		//		no need to return anything.  All results are passed via callbacks.
@@ -191,7 +180,6 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		Discards any unsaved changes.
 		// description:
 		//		Discards any unsaved changes.
-		//
 		// example:
 		//	|	var success = store.revert();
 		throw new Error('Unimplemented API: dojo.data.api.Write.revert');
@@ -203,10 +191,8 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		since the last save().  If isDirty() is called with no *item* argument,
 		//		then this function returns true if any item has been modified since
 		//		the last save().
-		//
 		// item:
 		//		The item to check.
-		//
 		// exceptions:
 		//		Throws an exception if isDirty() is passed an argument and the
 		//		argument is not an item.
@@ -217,5 +203,4 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 	}
 });
 
-return dojo.data.api.Write;
 });
diff --git a/dojo/data/util/filter.js b/dojo/data/util/filter.js
index 49a5295..4b46188 100644
--- a/dojo/data/util/filter.js
+++ b/dojo/data/util/filter.js
@@ -1,32 +1,35 @@
-define(["dojo/_base/lang"], function(lang) {
+define(["../../_base/lang"], function(lang){
 	// module:
 	//		dojo/data/util/filter
 	// summary:
 	//		TODOC
 
-var filter = lang.getObject("dojo.data.util.filter", true);
+var filter = {};
+lang.setObject("dojo.data.util.filter", filter);
 
 filter.patternToRegExp = function(/*String*/pattern, /*boolean?*/ ignoreCase){
-	//	summary:
+	// summary:
 	//		Helper function to convert a simple pattern to a regular expression for matching.
-	//	description:
+	// description:
 	//		Returns a regular expression object that conforms to the defined conversion rules.
 	//		For example:
-	//			ca*   -> /^ca.*$/
-	//			*ca*  -> /^.*ca.*$/
-	//			*c\*a*  -> /^.*c\*a.*$/
-	//			*c\*a?*  -> /^.*c\*a..*$/
-	//			and so on.
 	//
-	//	pattern: string
+	//		- ca*   -> /^ca.*$/
+	//		- *ca*  -> /^.*ca.*$/
+	//		- *c\*a*  -> /^.*c\*a.*$/
+	//		- *c\*a?*  -> /^.*c\*a..*$/
+	//
+	//		and so on.
+	// pattern: string
 	//		A simple matching pattern to convert that follows basic rules:
-	//			* Means match anything, so ca* means match anything starting with ca
-	//			? Means match single character.  So, b?b will match to bob and bab, and so on.
-	//      	\ is an escape character.  So for example, \* means do not treat * as a match, but literal character *.
-	//				To use a \ as a character in the string, it must be escaped.  So in the pattern it should be
-	//				represented by \\ to be treated as an ordinary \ character instead of an escape.
 	//
-	//	ignoreCase:
+	//		- * Means match anything, so ca* means match anything starting with ca
+	//		- ? Means match single character.  So, b?b will match to bob and bab, and so on.
+	//		- \ is an escape character.  So for example, \* means do not treat * as a match, but literal character *.
+	//
+	//		To use a \ as a character in the string, it must be escaped.  So in the pattern it should be
+	//		represented by \\ to be treated as an ordinary \ character instead of an escape.
+	// ignoreCase:
 	//		An optional flag to indicate if the pattern matching should be treated as case-sensitive or not when comparing
 	//		By default, it is assumed case sensitive.
 
diff --git a/dojo/data/util/simpleFetch.js b/dojo/data/util/simpleFetch.js
index 40d0d22..c39ed32 100644
--- a/dojo/data/util/simpleFetch.js
+++ b/dojo/data/util/simpleFetch.js
@@ -1,16 +1,73 @@
-define(["dojo/_base/lang", "dojo/_base/window", "./sorter"], 
-  function(lang, winUtil, sorter) {
+define(["../../_base/lang", "../../_base/kernel", "./sorter"],
+  function(lang, kernel, sorter){
 	// module:
 	//		dojo/data/util/simpleFetch
 	// summary:
-	//		TODOC
+	//		The simpleFetch mixin is designed to serve as a set of function(s) that can
+	//		be mixed into other datastore implementations to accelerate their development.
+
+var simpleFetch = {};
+lang.setObject("dojo.data.util.simpleFetch", simpleFetch);
+
+simpleFetch.errorHandler = function(/*Object*/ errorData, /*Object*/ requestObject){
+	// summary:
+	//		The error handler when there is an error fetching items.  This function should not be called
+	//		directly and is used by simpleFetch.fetch().
+	if(requestObject.onError){
+		var scope = requestObject.scope || kernel.global;
+		requestObject.onError.call(scope, errorData, requestObject);
+	}
+};
+
+simpleFetch.fetchHandler = function(/*Array*/ items, /*Object*/ requestObject){
+	// summary:
+	//		The handler when items are sucessfully fetched.  This function should not be called directly
+	//		and is used by simpleFetch.fetch().
+	var oldAbortFunction = requestObject.abort || null,
+		aborted = false,
+
+		startIndex = requestObject.start?requestObject.start: 0,
+		endIndex = (requestObject.count && (requestObject.count !== Infinity))?(startIndex + requestObject.count):items.length;
+
+	requestObject.abort = function(){
+		aborted = true;
+		if(oldAbortFunction){
+			oldAbortFunction.call(requestObject);
+		}
+	};
 
-var simpleFetch = lang.getObject("dojo.data.util.simpleFetch", true);
+	var scope = requestObject.scope || kernel.global;
+	if(!requestObject.store){
+		requestObject.store = this;
+	}
+	if(requestObject.onBegin){
+		requestObject.onBegin.call(scope, items.length, requestObject);
+	}
+	if(requestObject.sort){
+		items.sort(sorter.createSortFunction(requestObject.sort, this));
+	}
+	if(requestObject.onItem){
+		for(var i = startIndex; (i < items.length) && (i < endIndex); ++i){
+			var item = items[i];
+			if(!aborted){
+				requestObject.onItem.call(scope, item, requestObject);
+			}
+		}
+	}
+	if(requestObject.onComplete && !aborted){
+		var subset = null;
+		if(!requestObject.onItem){
+			subset = items.slice(startIndex, endIndex);
+		}
+		requestObject.onComplete.call(scope, subset, requestObject);
+	}
+};
 
 simpleFetch.fetch = function(/* Object? */ request){
-	//	summary:
+	// summary:
 	//		The simpleFetch mixin is designed to serve as a set of function(s) that can
 	//		be mixed into other datastore implementations to accelerate their development.
+	// description:
 	//		The simpleFetch mixin should work well for any datastore that can respond to a _fetchItems()
 	//		call by returning an array of all the found items that matched the query.  The simpleFetch mixin
 	//		is not designed to work for datastores that respond to a fetch() call by incrementally
@@ -28,66 +85,154 @@ simpleFetch.fetch = function(/* Object? */ request){
 	//		The _fetchItems() method needs to correctly handle any other keywordArgs
 	//		parameters, including the query parameter and any optional parameters
 	//		(such as includeChildren).  The _fetchItems() method should create an array of
-	//		result items and pass it to the fetchHandler along with the original request object
-	//		-- or, the _fetchItems() method may, if it wants to, create an new request object
+	//		result items and pass it to the fetchHandler along with the original request object --
+	//		or, the _fetchItems() method may, if it wants to, create an new request object
 	//		with other specifics about the request that are specific to the datastore and pass
 	//		that as the request object to the handler.
 	//
-	//		For more information on this specific function, see dojo.data.api.Read.fetch()
+	//		For more information on this specific function, see dojo/data/api/Read.fetch()
+	//
+	// request:
+	//		The keywordArgs parameter may either be an instance of
+	//		conforming to dojo/data/api/Request or may be a simple anonymous object
+	//		that may contain any of the following:
+	// |	{
+	// |		query: query-object or query-string,
+	// |		queryOptions: object,
+	// |		onBegin: Function,
+	// |		onItem: Function,
+	// |		onComplete: Function,
+	// |		onError: Function,
+	// |		scope: object,
+	// |		start: int
+	// |		count: int
+	// |		sort: array
+	// |	}
+	//		All implementations should accept keywordArgs objects with any of
+	//		the 9 standard properties: query, onBegin, onItem, onComplete, onError
+	//		scope, sort, start, and count.  Some implementations may accept additional
+	//		properties in the keywordArgs object as valid parameters, such as
+	//		{includeOutliers:true}.
+	//
+	//		####The *query* parameter
+	//
+	//		The query may be optional in some data store implementations.
+	//		The dojo/data/api/Read API does not specify the syntax or semantics
+	//		of the query itself -- each different data store implementation
+	//		may have its own notion of what a query should look like.
+	//		However, as of dojo 0.9, 1.0, and 1.1, all the provided datastores in dojo.data
+	//		and dojox.data support an object structure query, where the object is a set of
+	//		name/value parameters such as { attrFoo: valueBar, attrFoo1: valueBar1}.  Most of the
+	//		dijit widgets, such as ComboBox assume this to be the case when working with a datastore
+	//		when they dynamically update the query.  Therefore, for maximum compatibility with dijit
+	//		widgets the recommended query parameter is a key/value object.  That does not mean that the
+	//		the datastore may not take alternative query forms, such as a simple string, a Date, a number,
+	//		or a mix of such.  Ultimately, The dojo/data/api/Read API is agnostic about what the query
+	//		format.
+	//
+	//		Further note:  In general for query objects that accept strings as attribute
+	//		value matches, the store should also support basic filtering capability, such as *
+	//		(match any character) and ? (match single character).  An example query that is a query object
+	//		would be like: { attrFoo: "value*"}.  Which generally means match all items where they have
+	//		an attribute named attrFoo, with a value that starts with 'value'.
+	//
+	//		####The *queryOptions* parameter
+	//
+	//		The queryOptions parameter is an optional parameter used to specify options that may modify
+	//		the query in some fashion, such as doing a case insensitive search, or doing a deep search
+	//		where all items in a hierarchical representation of data are scanned instead of just the root
+	//		items.  It currently defines two options that all datastores should attempt to honor if possible:
+	// |	{
+	// |		ignoreCase: boolean, // Whether or not the query should match case sensitively or not.  Default behaviour is false.
+	// |		deep: boolean	// Whether or not a fetch should do a deep search of items and all child
+	// |						// items instead of just root-level items in a datastore.  Default is false.
+	// |	}
+	//
+	//		####The *onBegin* parameter.
+	//
+	//		function(size, request);
+	//		If an onBegin callback function is provided, the callback function
+	//		will be called just once, before the first onItem callback is called.
+	//		The onBegin callback function will be passed two arguments, the
+	//		the total number of items identified and the Request object.  If the total number is
+	//		unknown, then size will be -1.  Note that size is not necessarily the size of the
+	//		collection of items returned from the query, as the request may have specified to return only a
+	//		subset of the total set of items through the use of the start and count parameters.
+	//
+	//		####The *onItem* parameter.
+	//
+	//		function(item, request);
+	//
+	//		If an onItem callback function is provided, the callback function
+	//		will be called as each item in the result is received. The callback
+	//		function will be passed two arguments: the item itself, and the
+	//		Request object.
+	//
+	//		####The *onComplete* parameter.
+	//
+	//		function(items, request);
+	//
+	//		If an onComplete callback function is provided, the callback function
+	//		will be called just once, after the last onItem callback is called.
+	//		Note that if the onItem callback is not present, then onComplete will be passed
+	//		an array containing all items which matched the query and the request object.
+	//		If the onItem callback is present, then onComplete is called as:
+	//		onComplete(null, request).
+	//
+	//		####The *onError* parameter.
+	//
+	//		function(errorData, request);
+	//
+	//		If an onError callback function is provided, the callback function
+	//		will be called if there is any sort of error while attempting to
+	//		execute the query.
+	//		The onError callback function will be passed two arguments:
+	//		an Error object and the Request object.
+	//
+	//		####The *scope* parameter.
+	//
+	//		If a scope object is provided, all of the callback functions (onItem,
+	//		onComplete, onError, etc) will be invoked in the context of the scope
+	//		object.  In the body of the callback function, the value of the "this"
+	//		keyword will be the scope object.   If no scope object is provided,
+	//		the callback functions will be called in the context of dojo.global().
+	//		For example, onItem.call(scope, item, request) vs.
+	//		onItem.call(dojo.global(), item, request)
+	//
+	//		####The *start* parameter.
+	//
+	//		If a start parameter is specified, this is a indication to the datastore to
+	//		only start returning items once the start number of items have been located and
+	//		skipped.  When this parameter is paired with 'count', the store should be able
+	//		to page across queries with millions of hits by only returning subsets of the
+	//		hits for each query
+	//
+	//		####The *count* parameter.
+	//
+	//		If a count parameter is specified, this is a indication to the datastore to
+	//		only return up to that many items.  This allows a fetch call that may have
+	//		millions of item matches to be paired down to something reasonable.
+	//
+	//		####The *sort* parameter.
+	//
+	//		If a sort parameter is specified, this is a indication to the datastore to
+	//		sort the items in some manner before returning the items.  The array is an array of
+	//		javascript objects that must conform to the following format to be applied to the
+	//		fetching of items:
+	// |	{
+	// |		attribute: attribute || attribute-name-string,
+	// |		descending: true|false;   // Optional.  Default is false.
+	// |	}
+	//		Note that when comparing attributes, if an item contains no value for the attribute
+	//		(undefined), then it the default ascending sort logic should push it to the bottom
+	//		of the list.  In the descending order case, it such items should appear at the top of the list.
+
 	request = request || {};
 	if(!request.store){
 		request.store = this;
 	}
-	var self = this;
-
-	var _errorHandler = function(errorData, requestObject){
-		if(requestObject.onError){
-			var scope = requestObject.scope || winUtil.global;
-			requestObject.onError.call(scope, errorData, requestObject);
-		}
-	};
-
-	var _fetchHandler = function(items, requestObject){
-		var oldAbortFunction = requestObject.abort || null;
-		var aborted = false;
-
-		var startIndex = requestObject.start?requestObject.start:0;
-		var endIndex = (requestObject.count && (requestObject.count !== Infinity))?(startIndex + requestObject.count):items.length;
-
-		requestObject.abort = function(){
-			aborted = true;
-			if(oldAbortFunction){
-				oldAbortFunction.call(requestObject);
-			}
-		};
 
-		var scope = requestObject.scope || winUtil.global;
-		if(!requestObject.store){
-			requestObject.store = self;
-		}
-		if(requestObject.onBegin){
-			requestObject.onBegin.call(scope, items.length, requestObject);
-		}
-		if(requestObject.sort){
-			items.sort(sorter.createSortFunction(requestObject.sort, self));
-		}
-		if(requestObject.onItem){
-			for(var i = startIndex; (i < items.length) && (i < endIndex); ++i){
-				var item = items[i];
-				if(!aborted){
-					requestObject.onItem.call(scope, item, requestObject);
-				}
-			}
-		}
-		if(requestObject.onComplete && !aborted){
-			var subset = null;
-			if(!requestObject.onItem){
-				subset = items.slice(startIndex, endIndex);
-			}
-			requestObject.onComplete.call(scope, subset, requestObject);
-		}
-	};
-	this._fetchItems(request, _fetchHandler, _errorHandler);
+	this._fetchItems(request, lang.hitch(this, "fetchHandler"), lang.hitch(this, "errorHandler"));
 	return request;	// Object
 };
 
diff --git a/dojo/data/util/sorter.js b/dojo/data/util/sorter.js
index 617fb47..1511d71 100644
--- a/dojo/data/util/sorter.js
+++ b/dojo/data/util/sorter.js
@@ -1,16 +1,17 @@
-define(["dojo/_base/lang"], function(lang) {
+define(["../../_base/lang"], function(lang){
 	// module:
 	//		dojo/data/util/sorter
 	// summary:
 	//		TODOC
 
-var sorter = lang.getObject("dojo.data.util.sorter", true);
+var sorter = {};
+lang.setObject("dojo.data.util.sorter", sorter);
 
 sorter.basicComparator = function(	/*anything*/ a,
 													/*anything*/ b){
-	//	summary:
-	//		Basic comparision function that compares if an item is greater or less than another item
-	//	description:
+	// summary:
+	//		Basic comparison function that compares if an item is greater or less than another item
+	// description:
 	//		returns 1 if a > b, -1 if a < b, 0 if equal.
 	//		'null' values (null, undefined) are treated as larger values so that they're pushed to the end of the list.
 	//		And compared to each other, null is equivalent to undefined.
@@ -34,25 +35,24 @@ sorter.basicComparator = function(	/*anything*/ a,
 	return r; //int {-1,0,1}
 };
 
-sorter.createSortFunction = function(	/* attributes array */sortSpec, /*dojo.data.core.Read*/ store){
-	//	summary:
+sorter.createSortFunction = function(	/* attributes[] */sortSpec, /*dojo/data/api/Read*/ store){
+	// summary:
 	//		Helper function to generate the sorting function based off the list of sort attributes.
-	//	description:
+	// description:
 	//		The sort function creation will look for a property on the store called 'comparatorMap'.  If it exists
 	//		it will look in the mapping for comparisons function for the attributes.  If one is found, it will
 	//		use it instead of the basic comparator, which is typically used for strings, ints, booleans, and dates.
 	//		Returns the sorting function for this particular list of attributes and sorting directions.
-	//
-	//	sortSpec: array
+	// sortSpec:
 	//		A JS object that array that defines out what attribute names to sort on and whether it should be descenting or asending.
 	//		The objects should be formatted as follows:
-	//		{
-	//			attribute: "attributeName-string" || attribute,
-	//			descending: true|false;   // Default is false.
-	//		}
-	//	store: object
+	// |	{
+	// |		attribute: "attributeName-string" || attribute,
+	// |		descending: true|false;   // Default is false.
+	// |	}
+	// store:
 	//		The datastore object to look up item values from.
-	//
+
 	var sortFunctions=[];
 
 	function createSortFunction(attr, dir, comp, s){
diff --git a/dojo/date.js b/dojo/date.js
index f3571e8..a7fb847 100644
--- a/dojo/date.js
+++ b/dojo/date.js
@@ -1,30 +1,25 @@
-define(["./_base/kernel", "./_base/lang"], function(dojo, lang) {
-	// module:
-	//		dojo/date
-	// summary:
-	//		TODOC
-
-lang.getObject("date", true, dojo);
+define(["./has", "./_base/lang"], function(has, lang){
+// module:
+//		dojo/date
 
-/*=====
-dojo.date = {
-	// summary: Date manipulation utilities
-}
-=====*/
+var date = {
+	// summary:
+	//		Date manipulation utilities
+};
 
-dojo.date.getDaysInMonth = function(/*Date*/dateObject){
-	//	summary:
+date.getDaysInMonth = function(/*Date*/dateObject){
+	// summary:
 	//		Returns the number of days in the month used by dateObject
 	var month = dateObject.getMonth();
 	var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
-	if(month == 1 && dojo.date.isLeapYear(dateObject)){ return 29; } // Number
+	if(month == 1 && date.isLeapYear(dateObject)){ return 29; } // Number
 	return days[month]; // Number
 };
 
-dojo.date.isLeapYear = function(/*Date*/dateObject){
-	//	summary:
+date.isLeapYear = function(/*Date*/dateObject){
+	// summary:
 	//		Determines if the year of the dateObject is a leap year
-	//	description:
+	// description:
 	//		Leap years are years with an additional day YYYY-02-29, where the
 	//		year number is a multiple of four with the following exception: If
 	//		a year is a multiple of 100, then it is only a leap year if it is
@@ -36,12 +31,12 @@ dojo.date.isLeapYear = function(/*Date*/dateObject){
 };
 
 // FIXME: This is not localized
-dojo.date.getTimezoneName = function(/*Date*/dateObject){
-	//	summary:
+date.getTimezoneName = function(/*Date*/dateObject){
+	// summary:
 	//		Get the user's time zone as provided by the browser
 	// dateObject:
 	//		Needed because the timezone may vary with time (daylight savings)
-	//	description:
+	// description:
 	//		Try to get time zone info from toString or toLocaleString method of
 	//		the Date object -- UTC offset is not a time zone.  See
 	//		http://www.twinsun.com/tz/tz-link.htm Note: results may be
@@ -82,16 +77,16 @@ dojo.date.getTimezoneName = function(/*Date*/dateObject){
 
 // Utility methods to do arithmetic calculations with Dates
 
-dojo.date.compare = function(/*Date*/date1, /*Date?*/date2, /*String?*/portion){
-	//	summary:
+date.compare = function(/*Date*/date1, /*Date?*/date2, /*String?*/portion){
+	// summary:
 	//		Compare two date objects by date, time, or both.
-	//	description:
-	//  	Returns 0 if equal, positive if a > b, else negative.
-	//	date1:
+	// description:
+	//		Returns 0 if equal, positive if a > b, else negative.
+	// date1:
 	//		Date object
-	//	date2:
+	// date2:
 	//		Date object.  If not specified, the current Date is used.
-	//	portion:
+	// portion:
 	//		A string indicating the "date" or "time" portion of a Date object.
 	//		Compares both "date" and "time" by default.  One of the following:
 	//		"date", "time", "datetime"
@@ -115,16 +110,16 @@ dojo.date.compare = function(/*Date*/date1, /*Date?*/date2, /*String?*/portion){
 	return 0; // int
 };
 
-dojo.date.add = function(/*Date*/date, /*String*/interval, /*int*/amount){
-	//	summary:
+date.add = function(/*Date*/date, /*String*/interval, /*int*/amount){
+	// summary:
 	//		Add to a Date in intervals of different size, from milliseconds to years
-	//	date: Date
+	// date: Date
 	//		Date object to start with
-	//	interval:
+	// interval:
 	//		A string representing the interval.  One of the following:
-	//			"year", "month", "day", "hour", "minute", "second",
-	//			"millisecond", "quarter", "week", "weekday"
-	//	amount:
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond", "quarter", "week", "weekday"
+	// amount:
 	//		How much to add to the date.
 
 	var sum = new Date(+date); // convert to Number before copying to accomodate IE (#3112)
@@ -135,7 +130,7 @@ dojo.date.add = function(/*Date*/date, /*String*/interval, /*int*/amount){
 		case "day":
 			break;
 		case "weekday":
-			//i18n FIXME: assumes Saturday/Sunday weekend, but this is not always true.  see dojo.cldr.supplemental
+			//i18n FIXME: assumes Saturday/Sunday weekend, but this is not always true.  see dojo/cldr/supplemental
 
 			// Divide the increment time span into weekspans plus leftover days
 			// e.g., 8 days is one 5-day weekspan / and two leftover days
@@ -208,19 +203,20 @@ dojo.date.add = function(/*Date*/date, /*String*/interval, /*int*/amount){
 	return sum; // Date
 };
 
-dojo.date.difference = function(/*Date*/date1, /*Date?*/date2, /*String?*/interval){
-	//	summary:
+date.difference = function(/*Date*/date1, /*Date?*/date2, /*String?*/interval){
+	// summary:
 	//		Get the difference in a specific unit of time (e.g., number of
 	//		months, weeks, days, etc.) between two dates, rounded to the
 	//		nearest integer.
-	//	date1:
+	// date1:
 	//		Date object
-	//	date2:
+	// date2:
 	//		Date object.  If not specified, the current Date is used.
-	//	interval:
+	// interval:
 	//		A string representing the interval.  One of the following:
-	//			"year", "month", "day", "hour", "minute", "second",
-	//			"millisecond", "quarter", "week", "weekday"
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond", "quarter", "week", "weekday"
+	//
 	//		Defaults to "day".
 
 	date2 = date2 || new Date();
@@ -240,8 +236,8 @@ dojo.date.difference = function(/*Date*/date1, /*Date?*/date2, /*String?*/interv
 			delta = q2 - q1;
 			break;
 		case "weekday":
-			var days = Math.round(dojo.date.difference(date1, date2, "day"));
-			var weeks = parseInt(dojo.date.difference(date1, date2, "week"));
+			var days = Math.round(date.difference(date1, date2, "day"));
+			var weeks = parseInt(date.difference(date1, date2, "week"));
 			var mod = days % 7;
 
 			// Even number of weeks
@@ -321,7 +317,7 @@ dojo.date.difference = function(/*Date*/date1, /*Date?*/date2, /*String?*/interv
 		case "week":
 			// Truncate instead of rounding
 			// Don't use Math.floor -- value may be negative
-			delta = parseInt(dojo.date.difference(date1, date2, "day")/7);
+			delta = parseInt(date.difference(date1, date2, "day")/7);
 			break;
 		case "day":
 			delta /= 24;
@@ -343,5 +339,8 @@ dojo.date.difference = function(/*Date*/date1, /*Date?*/date2, /*String?*/interv
 	return Math.round(delta); // Number (integer)
 };
 
-return dojo.date;
+// Don't use setObject() because it may overwrite dojo/date/stamp (if that has already been loaded)
+has("extend-dojo") && lang.mixin(lang.getObject("dojo.date", true), date);
+
+return date;
 });
diff --git a/dojo/date/locale.js b/dojo/date/locale.js
index 7acacfa..f1f31ea 100644
--- a/dojo/date/locale.js
+++ b/dojo/date/locale.js
@@ -1,19 +1,24 @@
 define([
-	"../_base/kernel",
 	"../_base/lang",
 	"../_base/array",
 	"../date",
+	/*===== "../_base/declare", =====*/
 	"../cldr/supplemental",
+	"../i18n",
 	"../regexp",
 	"../string",
-	"../i18n!../cldr/nls/gregorian"
-], function(dojo, lang, array, date, cldr, regexp, string, gregorian) {
-	// module:
-	//		dojo/date/locale
-	// summary:
-	//		This modules defines dojo.date.locale, localization methods for Date.
+	"../i18n!../cldr/nls/gregorian",
+	"module"
+], function(lang, array, date, /*===== declare, =====*/ supplemental, i18n, regexp, string, gregorian, module){
+
+// module:
+//		dojo/date/locale
 
-lang.getObject("date.locale", true, dojo);
+var exports = {
+	// summary:
+	//		This modules defines dojo/date/locale, localization methods for Date.
+};
+lang.setObject(module.id.replace(/\//g, "."), exports);
 
 // Localization methods for Date.   Honor local customs using locale-dependent dojo.cldr data.
 
@@ -60,35 +65,52 @@ lang.getObject("date.locale", true, dojo);
 //					}
 					break;
 				case 'M':
+				case 'L':
 					var m = dateObject.getMonth();
 					if(l<3){
 						s = m+1; pad = true;
 					}else{
-						var propM = ["months", "format", widthList[l-3]].join("-");
+						var propM = [
+							"months",
+							c == 'L' ? "standAlone" : "format",
+							widthList[l-3]
+						].join("-");
 						s = bundle[propM][m];
 					}
 					break;
 				case 'w':
 					var firstDay = 0;
-					s = dojo.date.locale._getWeekOfYear(dateObject, firstDay); pad = true;
+					s = exports._getWeekOfYear(dateObject, firstDay); pad = true;
 					break;
 				case 'd':
 					s = dateObject.getDate(); pad = true;
 					break;
 				case 'D':
-					s = dojo.date.locale._getDayOfYear(dateObject); pad = true;
+					s = exports._getDayOfYear(dateObject); pad = true;
 					break;
-				case 'E':
+				case 'e':
+				case 'c':
 					var d = dateObject.getDay();
+					if(l<2){
+						s = (d - supplemental.getFirstDayOfWeek(options.locale) + 8) % 7
+						break;
+					}
+					// fallthrough
+				case 'E':
+					d = dateObject.getDay();
 					if(l<3){
 						s = d+1; pad = true;
 					}else{
-						var propD = ["days", "format", widthList[l-3]].join("-");
+						var propD = [
+							"days",
+							c == 'c' ? "standAlone" : "format",
+							widthList[l-3]
+						].join("-");
 						s = bundle[propD][d];
 					}
 					break;
 				case 'a':
-					var timePeriod = (dateObject.getHours() < 12) ? 'am' : 'pm';
+					var timePeriod = dateObject.getHours() < 12 ? 'am' : 'pm';
 					s = options[timePeriod] || bundle['dayPeriods-format-wide-' + timePeriod];
 					break;
 				case 'h':
@@ -125,12 +147,12 @@ lang.getObject("date.locale", true, dojo);
 				case 'v': // FIXME: don't know what this is. seems to be same as z?
 				case 'z':
 					// We only have one timezone to offer; the one from the browser
-					s = dojo.date.locale._getZone(dateObject, true, options);
+					s = exports._getZone(dateObject, true, options);
 					if(s){break;}
 					l=4;
 					// fallthrough... use GMT if tz not available
 				case 'Z':
-					var offset = dojo.date.locale._getZone(dateObject, false, options);
+					var offset = exports._getZone(dateObject, false, options);
 					var tz = [
 						(offset<=0 ? "+" : "-"),
 						string.pad(Math.floor(Math.abs(offset)/60), 2),
@@ -142,7 +164,7 @@ lang.getObject("date.locale", true, dojo);
 					}
 					s = tz.join("");
 					break;
-//				case 'Y': case 'u': case 'W': case 'F': case 'g': case 'A': case 'e':
+//				case 'Y': case 'u': case 'W': case 'F': case 'g': case 'A':
 //					console.log(match+" modifier unimplemented");
 				default:
 					throw new Error("dojo.date.locale.format: invalid pattern char: "+pattern);
@@ -153,38 +175,29 @@ lang.getObject("date.locale", true, dojo);
 	}
 
 /*=====
-	dojo.date.locale.__FormatOptions = function(){
-	//	selector: String
+var __FormatOptions = exports.__FormatOptions = declare(null, {
+	// selector: String
 	//		choice of 'time','date' (default: date and time)
-	//	formatLength: String
+	// formatLength: String
 	//		choice of long, short, medium or full (plus any custom additions).  Defaults to 'short'
-	//	datePattern:String
+	// datePattern:String
 	//		override pattern with this string
-	//	timePattern:String
+	// timePattern:String
 	//		override pattern with this string
-	//	am: String
+	// am: String
 	//		override strings for am in times
-	//	pm: String
+	// pm: String
 	//		override strings for pm in times
-	//	locale: String
+	// locale: String
 	//		override the locale used to determine formatting rules
-	//	fullYear: Boolean
+	// fullYear: Boolean
 	//		(format only) use 4 digit years whenever 2 digit years are called for
-	//	strict: Boolean
+	// strict: Boolean
 	//		(parse only) strict parsing, off by default
-		this.selector = selector;
-		this.formatLength = formatLength;
-		this.datePattern = datePattern;
-		this.timePattern = timePattern;
-		this.am = am;
-		this.pm = pm;
-		this.locale = locale;
-		this.fullYear = fullYear;
-		this.strict = strict;
-	}
+});
 =====*/
 
-dojo.date.locale._getZone = function(/*Date*/dateObject, /*boolean*/getName, /*dojo.date.locale.__FormatOptions?*/options){
+exports._getZone = function(/*Date*/ dateObject, /*boolean*/ getName, /*__FormatOptions?*/ options){
 	// summary:
 	//		Returns the zone (or offset) for the given date and options.  This
 	//		is broken out into a separate function so that it can be overridden
@@ -206,7 +219,7 @@ dojo.date.locale._getZone = function(/*Date*/dateObject, /*boolean*/getName, /*d
 };
 
 
-dojo.date.locale.format = function(/*Date*/dateObject, /*dojo.date.locale.__FormatOptions?*/options){
+exports.format = function(/*Date*/ dateObject, /*__FormatOptions?*/ options){
 	// summary:
 	//		Format a Date object as a String, using locale-specific settings.
 	//
@@ -216,7 +229,7 @@ dojo.date.locale.format = function(/*Date*/dateObject, /*dojo.date.locale.__Form
 	//		Formatting patterns are chosen appropriate to the locale.  Different
 	//		formatting lengths may be chosen, with "full" used by default.
 	//		Custom patterns may be used or registered with translations using
-	//		the dojo.date.locale.addCustomFormats method.
+	//		the dojo/date/locale.addCustomFormats() method.
 	//		Formatting patterns are implemented using [the syntax described at
 	//		unicode.org](http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns)
 	//
@@ -227,9 +240,9 @@ dojo.date.locale.format = function(/*Date*/dateObject, /*dojo.date.locale.__Form
 
 	options = options || {};
 
-	var locale = dojo.i18n.normalizeLocale(options.locale),
+	var locale = i18n.normalizeLocale(options.locale),
 		formatLength = options.formatLength || 'short',
-		bundle = dojo.date.locale._getGregorianBundle(locale),
+		bundle = exports._getGregorianBundle(locale),
 		str = [],
 		sauce = lang.hitch(this, formatPattern, dateObject, bundle, options);
 	if(options.selector == "year"){
@@ -245,21 +258,21 @@ dojo.date.locale.format = function(/*Date*/dateObject, /*dojo.date.locale.__Form
 		if(pattern){str.push(_processPattern(pattern, sauce));}
 	}
 
-	return str.length == 1 ? str[0] : bundle["dateTimeFormat-"+formatLength].replace(/\{(\d+)\}/g,
+	return str.length == 1 ? str[0] : bundle["dateTimeFormat-"+formatLength].replace(/\'/g,'').replace(/\{(\d+)\}/g,
 		function(match, key){ return str[key]; }); // String
 };
 
-dojo.date.locale.regexp = function(/*dojo.date.locale.__FormatOptions?*/options){
+exports.regexp = function(/*__FormatOptions?*/ options){
 	// summary:
 	//		Builds the regular needed to parse a localized date
 
-	return dojo.date.locale._parseInfo(options).regexp; // String
+	return exports._parseInfo(options).regexp; // String
 };
 
-dojo.date.locale._parseInfo = function(/*dojo.date.locale.__FormatOptions?*/options){
+exports._parseInfo = function(/*__FormatOptions?*/ options){
 	options = options || {};
-	var locale = dojo.i18n.normalizeLocale(options.locale),
-		bundle = dojo.date.locale._getGregorianBundle(locale),
+	var locale = i18n.normalizeLocale(options.locale),
+		bundle = exports._getGregorianBundle(locale),
 		formatLength = options.formatLength || 'short',
 		datePattern = options.datePattern || bundle["dateFormat-" + formatLength],
 		timePattern = options.timePattern || bundle["timeFormat-" + formatLength],
@@ -278,7 +291,7 @@ dojo.date.locale._parseInfo = function(/*dojo.date.locale.__FormatOptions?*/opti
 	return {regexp: re, tokens: tokens, bundle: bundle};
 };
 
-dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOptions?*/options){
+exports.parse = function(/*String*/ value, /*__FormatOptions?*/ options){
 	// summary:
 	//		Convert a properly formatted string to a primitive Date object,
 	//		using locale-specific settings.
@@ -289,7 +302,7 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 	//		Formatting patterns are chosen appropriate to the locale.  Different
 	//		formatting lengths may be chosen, with "full" used by default.
 	//		Custom patterns may be used or registered with translations using
-	//		the dojo.date.locale.addCustomFormats method.
+	//		the dojo/date/locale.addCustomFormats() method.
 	//
 	//		Formatting patterns are implemented using [the syntax described at
 	//		unicode.org](http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns)
@@ -302,7 +315,7 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 
 	// remove non-printing bidi control chars from input and pattern
 	var controlChars = /[\u200E\u200F\u202A\u202E]/g,
-		info = dojo.date.locale._parseInfo(options),
+		info = exports._parseInfo(options),
 		tokens = info.tokens, bundle = info.bundle,
 		re = new RegExp("^" + info.regexp.replace(controlChars, "") + "$",
 			info.strict ? "" : "i"),
@@ -313,11 +326,12 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 	var widthList = ['abbr', 'wide', 'narrow'],
 		result = [1970,0,1,0,0,0,0], // will get converted to a Date at the end
 		amPm = "",
-		valid = dojo.every(match, function(v, i){
+		valid = array.every(match, function(v, i){
 		if(!i){return true;}
-		var token=tokens[i-1];
-		var l=token.length;
-		switch(token.charAt(0)){
+		var token = tokens[i-1],
+			l = token.length,
+			c = token.charAt(0);
+		switch(c){
 			case 'y':
 				if(l != 2 && options.strict){
 					//interpret year literally, so '5' would be 5 A.D.
@@ -343,17 +357,20 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 				}
 				break;
 			case 'M':
+			case 'L':
 				if(l>2){
-					var months = bundle['months-format-' + widthList[l-3]].concat();
+					var months = bundle['months-' +
+							    (c == 'L' ? 'standAlone' : 'format') +
+							    '-' + widthList[l-3]].concat();
 					if(!options.strict){
 						//Tolerate abbreviating period in month part
 						//Case-insensitive comparison
 						v = v.replace(".","").toLowerCase();
-						months = dojo.map(months, function(s){ return s.replace(".","").toLowerCase(); } );
+						months = array.map(months, function(s){ return s.replace(".","").toLowerCase(); } );
 					}
-					v = dojo.indexOf(months, v);
+					v = array.indexOf(months, v);
 					if(v == -1){
-//						console.log("dojo.date.locale.parse: Could not parse month name: '" + v + "'.");
+//						console.log("dojo/date/locale.parse: Could not parse month name: '" + v + "'.");
 						return false;
 					}
 				}else{
@@ -363,15 +380,18 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 				break;
 			case 'E':
 			case 'e':
-				var days = bundle['days-format-' + widthList[l-3]].concat();
+			case 'c':
+				var days = bundle['days-' +
+						  (c == 'c' ? 'standAlone' : 'format') +
+						  '-' + widthList[l-3]].concat();
 				if(!options.strict){
 					//Case-insensitive comparison
 					v = v.toLowerCase();
-					days = dojo.map(days, function(d){return d.toLowerCase();});
+					days = array.map(days, function(d){return d.toLowerCase();});
 				}
-				v = dojo.indexOf(days, v);
+				v = array.indexOf(days, v);
 				if(v == -1){
-//					console.log("dojo.date.locale.parse: Could not parse weekday name: '" + v + "'.");
+//					console.log("dojo/date/locale.parse: Could not parse weekday name: '" + v + "'.");
 					return false;
 				}
 
@@ -396,7 +416,7 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 					pm = pm.replace(period,'').toLowerCase();
 				}
 				if(options.strict && v != am && v != pm){
-//					console.log("dojo.date.locale.parse: Could not parse am/pm part.");
+//					console.log("dojo/date/locale.parse: Could not parse am/pm part.");
 					return false;
 				}
 
@@ -411,7 +431,7 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 			case 'k': //hour (0-11)
 				//TODO: strict bounds checking, padding
 				if(v > 23){
-//					console.log("dojo.date.locale.parse: Illegal hours value");
+//					console.log("dojo/date/locale.parse: Illegal hours value");
 					return false;
 				}
 
@@ -432,7 +452,7 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 //TODO				var firstDay = 0;
 //			default:
 //TODO: throw?
-//				console.log("dojo.date.locale.parse: unsupported pattern char=" + token.charAt(0));
+//				console.log("dojo/date/locale.parse: unsupported pattern char=" + token.charAt(0));
 		}
 		return true;
 	});
@@ -489,7 +509,7 @@ function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
 	var chunks = pattern.match(/(''|[^'])+/g),
 		literal = pattern.charAt(0) == "'";
 
-	dojo.forEach(chunks, function(chunk, i){
+	array.forEach(chunks, function(chunk, i){
 		if(!chunk){
 			chunks[i]='';
 		}else{
@@ -520,6 +540,7 @@ function _buildDateTimeRE(tokens, bundle, options, pattern){
 				s = '\\d{2,4}';
 				break;
 			case 'M':
+			case 'L':
 				s = (l>2) ? '\\S+?' : '1[0-2]|'+p2+'[1-9]';
 				break;
 			case 'D':
@@ -532,7 +553,9 @@ function _buildDateTimeRE(tokens, bundle, options, pattern){
 				s = '[1-4][0-9]|5[0-3]|'+p2+'[1-9]';
 				break;
 			case 'E':
-				s = '\\S+';
+			case 'e':
+			case 'c':
+				s = '.+?'; // match anything including spaces until the first pattern delimiter is found such as a comma or space
 				break;
 			case 'h': //hour (1-12)
 				s = '1[0-2]|'+p2+'[1-9]';
@@ -579,7 +602,7 @@ function _buildDateTimeRE(tokens, bundle, options, pattern){
 }
 
 var _customFormats = [];
-dojo.date.locale.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){
+exports.addCustomFormats = function(/*String*/ packageName, /*String*/ bundleName){
 	// summary:
 	//		Add a reference to a bundle containing localized custom formats to be
 	//		used by date/time formatting and parsing routines.
@@ -588,24 +611,24 @@ dojo.date.locale.addCustomFormats = function(/*String*/packageName, /*String*/bu
 	//		The user may add custom localized formats where the bundle has properties following the
 	//		same naming convention used by dojo.cldr: `dateFormat-xxxx` / `timeFormat-xxxx`
 	//		The pattern string should match the format used by the CLDR.
-	//		See dojo.date.locale.format() for details.
+	//		See dojo/date/locale.format() for details.
 	//		The resources must be loaded by dojo.requireLocalization() prior to use
 
 	_customFormats.push({pkg:packageName,name:bundleName});
 };
 
-dojo.date.locale._getGregorianBundle = function(/*String*/locale){
+exports._getGregorianBundle = function(/*String*/ locale){
 	var gregorian = {};
-	dojo.forEach(_customFormats, function(desc){
-		var bundle = dojo.i18n.getLocalization(desc.pkg, desc.name, locale);
+	array.forEach(_customFormats, function(desc){
+		var bundle = i18n.getLocalization(desc.pkg, desc.name, locale);
 		gregorian = lang.mixin(gregorian, bundle);
 	}, this);
 	return gregorian; /*Object*/
 };
 
-dojo.date.locale.addCustomFormats("dojo.cldr","gregorian");
+exports.addCustomFormats(module.id.replace(/\/date\/locale$/, ".cldr"),"gregorian");
 
-dojo.date.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale){
+exports.getNames = function(/*String*/ item, /*String*/ type, /*String?*/ context, /*String?*/ locale){
 	// summary:
 	//		Used to get localized strings from dojo.cldr for day or month names.
 	//
@@ -619,7 +642,7 @@ dojo.date.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/
 	//	override locale used to find the names
 
 	var label,
-		lookup = dojo.date.locale._getGregorianBundle(locale),
+		lookup = exports._getGregorianBundle(locale),
 		props = [item, context, type];
 	if(context == 'standAlone'){
 		var key = props.join('-');
@@ -633,11 +656,11 @@ dojo.date.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/
 	return (label || lookup[props.join('-')]).concat(); /*Array*/
 };
 
-dojo.date.locale.isWeekend = function(/*Date?*/dateObject, /*String?*/locale){
+exports.isWeekend = function(/*Date?*/ dateObject, /*String?*/ locale){
 	// summary:
 	//	Determines if the date falls on a weekend, according to local custom.
 
-	var weekend = cldr.getWeekend(locale),
+	var weekend = supplemental.getWeekend(locale),
 		day = (dateObject || new Date()).getDay();
 	if(weekend.end < weekend.start){
 		weekend.end += 7;
@@ -648,17 +671,18 @@ dojo.date.locale.isWeekend = function(/*Date?*/dateObject, /*String?*/locale){
 
 // These are used only by format and strftime.  Do they need to be public?  Which module should they go in?
 
-dojo.date.locale._getDayOfYear = function(/*Date*/dateObject){
-	// summary: gets the day of the year as represented by dateObject
+exports._getDayOfYear = function(/*Date*/ dateObject){
+	// summary:
+	//		gets the day of the year as represented by dateObject
 	return date.difference(new Date(dateObject.getFullYear(), 0, 1, dateObject.getHours()), dateObject) + 1; // Number
 };
 
-dojo.date.locale._getWeekOfYear = function(/*Date*/dateObject, /*Number*/firstDayOfWeek){
+exports._getWeekOfYear = function(/*Date*/ dateObject, /*Number*/ firstDayOfWeek){
 	if(arguments.length == 1){ firstDayOfWeek = 0; } // Sunday
 
 	var firstDayOfYear = new Date(dateObject.getFullYear(), 0, 1).getDay(),
 		adj = (firstDayOfYear - firstDayOfWeek + 7) % 7,
-		week = Math.floor((dojo.date.locale._getDayOfYear(dateObject) + adj - 1) / 7);
+		week = Math.floor((exports._getDayOfYear(dateObject) + adj - 1) / 7);
 
 	// if year starts on the specified day, start counting weeks at 1
 	if(firstDayOfYear == firstDayOfWeek){ week++; }
@@ -666,5 +690,5 @@ dojo.date.locale._getWeekOfYear = function(/*Date*/dateObject, /*Number*/firstDa
 	return week; // Number
 };
 
-return dojo.date.locale;
+return exports;
 });
diff --git a/dojo/date/stamp.js b/dojo/date/stamp.js
index 5513f9e..bf28b6d 100644
--- a/dojo/date/stamp.js
+++ b/dojo/date/stamp.js
@@ -1,53 +1,54 @@
-define(["../_base/kernel", "../_base/lang", "../_base/array"], function(dojo, lang, array) {
-	// module:
-	//		dojo/date/stamp
+define(["../_base/lang", "../_base/array"], function(lang, array){
+
+// module:
+//		dojo/date/stamp
+
+var stamp = {
 	// summary:
 	//		TODOC
-
-lang.getObject("date.stamp", true, dojo);
+};
+lang.setObject("dojo.date.stamp", stamp);
 
 // Methods to convert dates to or from a wire (string) format using well-known conventions
 
-dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/defaultTime){
-	//	summary:
+stamp.fromISOString = function(/*String*/ formattedString, /*Number?*/ defaultTime){
+	// summary:
 	//		Returns a Date object given a string formatted according to a subset of the ISO-8601 standard.
 	//
-	//	description:
+	// description:
 	//		Accepts a string formatted according to a profile of ISO8601 as defined by
 	//		[RFC3339](http://www.ietf.org/rfc/rfc3339.txt), except that partial input is allowed.
 	//		Can also process dates as specified [by the W3C](http://www.w3.org/TR/NOTE-datetime)
 	//		The following combinations are valid:
 	//
-	//			* dates only
-	//			|	* yyyy
-	//			|	* yyyy-MM
-	//			|	* yyyy-MM-dd
-	// 			* times only, with an optional time zone appended
-	//			|	* THH:mm
-	//			|	* THH:mm:ss
-	//			|	* THH:mm:ss.SSS
-	// 			* and "datetimes" which could be any combination of the above
+	//		- dates only
+	//			- yyyy
+	//			- yyyy-MM
+	//			- yyyy-MM-dd
+	//		- times only, with an optional time zone appended
+	//			- THH:mm
+	//			- THH:mm:ss
+	//			- THH:mm:ss.SSS
+	//		- and "datetimes" which could be any combination of the above
 	//
 	//		timezones may be specified as Z (for UTC) or +/- followed by a time expression HH:mm
 	//		Assumes the local time zone if not specified.  Does not validate.  Improperly formatted
 	//		input may return null.  Arguments which are out of bounds will be handled
-	// 		by the Date constructor (e.g. January 32nd typically gets resolved to February 1st)
+	//		by the Date constructor (e.g. January 32nd typically gets resolved to February 1st)
 	//		Only years between 100 and 9999 are supported.
-	//
-  	//	formattedString:
+  	// formattedString:
 	//		A string such as 2005-06-30T08:05:00-07:00 or 2005-06-30 or T08:05:00
-	//
-	//	defaultTime:
+	// defaultTime:
 	//		Used for defaults for fields omitted in the formattedString.
 	//		Uses 1970-01-01T00:00:00.0Z by default.
 
-	if(!dojo.date.stamp._isoRegExp){
-		dojo.date.stamp._isoRegExp =
+	if(!stamp._isoRegExp){
+		stamp._isoRegExp =
 //TODO: could be more restrictive and check for 00-59, etc.
 			/^(?:(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(.\d+)?)?((?:[+-](\d{2}):(\d{2}))|Z)?)?$/;
 	}
 
-	var match = dojo.date.stamp._isoRegExp.exec(formattedString),
+	var match = stamp._isoRegExp.exec(formattedString),
 		result = null;
 
 	if(match){
@@ -87,30 +88,27 @@ dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/d
 };
 
 /*=====
-	dojo.date.stamp.__Options = function(){
-		//	selector: String
-		//		"date" or "time" for partial formatting of the Date object.
-		//		Both date and time will be formatted by default.
-		//	zulu: Boolean
-		//		if true, UTC/GMT is used for a timezone
-		//	milliseconds: Boolean
-		//		if true, output milliseconds
-		this.selector = selector;
-		this.zulu = zulu;
-		this.milliseconds = milliseconds;
-	}
+var __Options = {
+	// selector: String
+	//		"date" or "time" for partial formatting of the Date object.
+	//		Both date and time will be formatted by default.
+	// zulu: Boolean
+	//		if true, UTC/GMT is used for a timezone
+	// milliseconds: Boolean
+	//		if true, output milliseconds
+};
 =====*/
 
-dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*dojo.date.stamp.__Options?*/options){
-	//	summary:
+stamp.toISOString = function(/*Date*/ dateObject, /*__Options?*/ options){
+	// summary:
 	//		Format a Date object as a string according a subset of the ISO-8601 standard
 	//
-	//	description:
+	// description:
 	//		When options.selector is omitted, output follows [RFC3339](http://www.ietf.org/rfc/rfc3339.txt)
 	//		The local time zone is included as an offset from GMT, except when selector=='time' (time without a date)
 	//		Does not check bounds.  Only years between 100 and 9999 are supported.
 	//
-	//	dateObject:
+	// dateObject:
 	//		A Date object
 
 	var _ = function(n){ return (n < 10) ? "0" + n : n; };
@@ -142,5 +140,5 @@ dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*dojo.date.stamp.__O
 	return formattedDate.join('T'); // String
 };
 
-return dojo.date.stamp;
+return stamp;
 });
diff --git a/dojo/dnd/AutoSource.js b/dojo/dnd/AutoSource.js
index 1c2f4fc..11df7fd 100644
--- a/dojo/dnd/AutoSource.js
+++ b/dojo/dnd/AutoSource.js
@@ -1,10 +1,9 @@
-define([ "./Source" ], function(Source){
-	/*===== Source = dojo.dnd.Source =====*/
-	return dojo.declare("dojo.dnd.AutoSource", Source, {
+define(["../_base/declare", "./Source"], function(declare, Source){
+	return declare("dojo.dnd.AutoSource", Source, {
 		// summary:
 		//		a source that syncs its DnD nodes by default
 
-		constructor: function(node, params){
+		constructor: function(/*===== node, params =====*/){
 			// summary:
 			//		constructor of the AutoSource --- see the Source constructor for details
 			this.autoSync = true;
diff --git a/dojo/dnd/Avatar.js b/dojo/dnd/Avatar.js
index bd06393..83aa37d 100644
--- a/dojo/dnd/Avatar.js
+++ b/dojo/dnd/Avatar.js
@@ -1,11 +1,18 @@
-define(["../main", "./common"], function(dojo) {
-	// module:
-	//		dojo/dnd/Avatar
-	// summary:
-	//		TODOC
+define([
+	"../_base/declare",
+	"../_base/window",
+	"../dom",
+	"../dom-attr",
+	"../dom-class",
+	"../dom-construct",
+	"../hccss",
+	"../query"
+], function(declare, win, dom, domAttr, domClass, domConstruct, has, query){
 
+// module:
+//		dojo/dnd/Avatar
 
-dojo.declare("dojo.dnd.Avatar", null, {
+return declare("dojo.dnd.Avatar", null, {
 	// summary:
 	//		Object that represents transferred DnD items visually
 	// manager: Object
@@ -21,8 +28,8 @@ dojo.declare("dojo.dnd.Avatar", null, {
 		// summary:
 		//		constructor function;
 		//		it is separate so it can be (dynamically) overwritten in case of need
-		this.isA11y = dojo.hasClass(dojo.body(),"dijit_a11y");
-		var a = dojo.create("table", {
+
+		var a = domConstruct.create("table", {
 				"class": "dojoDndAvatar",
 				style: {
 					position: "absolute",
@@ -31,19 +38,23 @@ dojo.declare("dojo.dnd.Avatar", null, {
 				}
 			}),
 			source = this.manager.source, node,
-			b = dojo.create("tbody", null, a),
-			tr = dojo.create("tr", null, b),
-			td = dojo.create("td", null, tr),
-			icon = this.isA11y ? dojo.create("span", {
-						id : "a11yIcon",
-						innerHTML : this.manager.copy ? '+' : "<"
-					}, td) : null,
-			span = dojo.create("span", {
-				innerHTML: source.generateText ? this._generateText() : ""
-			}, td),
+			b = domConstruct.create("tbody", null, a),
+			tr = domConstruct.create("tr", null, b),
+			td = domConstruct.create("td", null, tr),
 			k = Math.min(5, this.manager.nodes.length), i = 0;
+
+		if(has("highcontrast")){
+			domConstruct.create("span", {
+				id : "a11yIcon",
+				innerHTML : this.manager.copy ? '+' : "<"
+			}, td)
+		}
+		domConstruct.create("span", {
+			innerHTML: source.generateText ? this._generateText() : ""
+		}, td);
+
 		// we have to set the opacity on IE only after the node is live
-		dojo.attr(tr, {
+		domAttr.set(tr, {
 			"class": "dojoDndAvatarHeader",
 			style: {opacity: 0.9}
 		});
@@ -56,17 +67,17 @@ dojo.declare("dojo.dnd.Avatar", null, {
 				node = this.manager.nodes[i].cloneNode(true);
 				if(node.tagName.toLowerCase() == "tr"){
 					// insert extra table nodes
-					var table = dojo.create("table"),
-						tbody = dojo.create("tbody", null, table);
+					var table = domConstruct.create("table"),
+						tbody = domConstruct.create("tbody", null, table);
 					tbody.appendChild(node);
 					node = table;
 				}
 			}
 			node.id = "";
-			tr = dojo.create("tr", null, b);
-			td = dojo.create("td", null, tr);
+			tr = domConstruct.create("tr", null, b);
+			td = domConstruct.create("td", null, tr);
 			td.appendChild(node);
-			dojo.attr(tr, {
+			domAttr.set(tr, {
 				"class": "dojoDndAvatarItem",
 				style: {opacity: (9 - i) / 10}
 			});
@@ -76,19 +87,19 @@ dojo.declare("dojo.dnd.Avatar", null, {
 	destroy: function(){
 		// summary:
 		//		destructor for the avatar; called to remove all references so it can be garbage-collected
-		dojo.destroy(this.node);
+		domConstruct.destroy(this.node);
 		this.node = false;
 	},
 	update: function(){
 		// summary:
 		//		updates the avatar to reflect the current DnD state
-		dojo[(this.manager.canDropFlag ? "add" : "remove") + "Class"](this.node, "dojoDndAvatarCanDrop");
-		if (this.isA11y){
-			var icon = dojo.byId("a11yIcon");
+		domClass.toggle(this.node, "dojoDndAvatarCanDrop", this.manager.canDropFlag);
+		if(has("highcontrast")){
+			var icon = dom.byId("a11yIcon");
 			var text = '+';   // assume canDrop && copy
-			if (this.manager.canDropFlag && !this.manager.copy) {
+			if (this.manager.canDropFlag && !this.manager.copy){
 				text = '< '; // canDrop && move
-			}else if (!this.manager.canDropFlag && !this.manager.copy) {
+			}else if (!this.manager.canDropFlag && !this.manager.copy){
 				text = "o"; //!canDrop && move
 			}else if(!this.manager.canDropFlag){
 				text = 'x';  // !canDrop && copy
@@ -96,16 +107,16 @@ dojo.declare("dojo.dnd.Avatar", null, {
 			icon.innerHTML=text;
 		}
 		// replace text
-		dojo.query(("tr.dojoDndAvatarHeader td span" +(this.isA11y ? " span" : "")), this.node).forEach(
+		query(("tr.dojoDndAvatarHeader td span" +(has("highcontrast") ? " span" : "")), this.node).forEach(
 			function(node){
-				node.innerHTML = this._generateText();
+				node.innerHTML = this.manager.source.generateText ? this._generateText() : "";
 			}, this);
 	},
 	_generateText: function(){
-		// summary: generates a proper text to reflect copying or moving of items
+		// summary:
+		//		generates a proper text to reflect copying or moving of items
 		return this.manager.nodes.length.toString();
 	}
 });
 
-return dojo.dnd.Avatar;
 });
diff --git a/dojo/dnd/Container.js b/dojo/dnd/Container.js
index 9e832bc..748ea42 100644
--- a/dojo/dnd/Container.js
+++ b/dojo/dnd/Container.js
@@ -1,9 +1,24 @@
-define(["../main", "../Evented", "./common", "../parser"], function(dojo, Evented) {
-	// module:
-	//		dojo/dnd/Container
-	// summary:
-	//		TODOC
+define([
+	"../_base/array",
+	"../_base/declare",
+	"../_base/kernel",
+	"../_base/lang",
+	"../_base/window",
+	"../dom",
+	"../dom-class",
+	"../dom-construct",
+	"../Evented",
+	"../has",
+	"../on",
+	"../query",
+	"../touch",
+	"./common"
+], function(
+	array, declare, kernel, lang, win,
+	dom, domClass, domConstruct, Evented, has, on, query, touch, dnd){
 
+// module:
+//		dojo/dnd/Container
 
 /*
 	Container states:
@@ -14,62 +29,28 @@ define(["../main", "../Evented", "./common", "../parser"], function(dojo, Evente
 		"Over"	- mouse over a container item
 */
 
-/*=====
-dojo.declare("dojo.dnd.__ContainerArgs", [], {
-	creator: function(){
-		// summary:
-		//		a creator function, which takes a data item, and returns an object like that:
-		//		{node: newNode, data: usedData, type: arrayOfStrings}
-	},
-
-	// skipForm: Boolean
-	//		don't start the drag operation, if clicked on form elements
-	skipForm: false,
-
-	// dropParent: Node||String
-	//		node or node's id to use as the parent node for dropped items
-	//		(must be underneath the 'node' parameter in the DOM)
-	dropParent: null,
-
-	// _skipStartup: Boolean
-	//		skip startup(), which collects children, for deferred initialization
-	//		(this is used in the markup mode)
-	_skipStartup: false
-});
-
-dojo.dnd.Item = function(){
-	// summary:
-	//		Represents (one of) the source node(s) being dragged.
-	//		Contains (at least) the "type" and "data" attributes.
-	// type: String[]
-	//		Type(s) of this item, by default this is ["text"]
-	// data: Object
-	//		Logical representation of the object being dragged.
-	//		If the drag object's type is "text" then data is a String,
-	//		if it's another type then data could be a different Object,
-	//		perhaps a name/value hash.
 
-	this.type = type;
-	this.data = data;
-}
-=====*/
 
-dojo.declare("dojo.dnd.Container", Evented, {
+var Container = declare("dojo.dnd.Container", Evented, {
 	// summary:
 	//		a Container object, which knows when mouse hovers over it,
 	//		and over which element it hovers
 
 	// object attributes (for markup)
 	skipForm: false,
-
+	// allowNested: Boolean
+	//		Indicates whether to allow dnd item nodes to be nested within other elements.
+	//		By default this is false, indicating that only direct children of the container can
+	//		be draggable dnd item nodes
+	allowNested: false,
 	/*=====
 	// current: DomNode
 	//		The DOM node the mouse is currently hovered over
 	current: null,
 
-	// map: Hash<String, dojo.dnd.Item>
+	// map: Hash<String, Container.Item>
 	//		Map from an item's id (which is also the DOMNode's id) to
-	//		the dojo.dnd.Item itself.
+	//		the dojo/dnd/Container.Item itself.
 	map: {},
 	=====*/
 
@@ -78,13 +59,13 @@ dojo.declare("dojo.dnd.Container", Evented, {
 		//		a constructor of the Container
 		// node: Node
 		//		node or node's id to build the container on
-		// params: dojo.dnd.__ContainerArgs
+		// params: Container.__ContainerArgs
 		//		a dictionary of parameters
-		this.node = dojo.byId(node);
+		this.node = dom.byId(node);
 		if(!params){ params = {}; }
 		this.creator = params.creator || null;
 		this.skipForm = params.skipForm;
-		this.parent = params.dropParent && dojo.byId(params.dropParent);
+		this.parent = params.dropParent && dom.byId(params.dropParent);
 
 		// class-specific variables
 		this.map = {};
@@ -92,7 +73,7 @@ dojo.declare("dojo.dnd.Container", Evented, {
 
 		// states
 		this.containerState = "";
-		dojo.addClass(this.node, "dojoDndContainer");
+		domClass.add(this.node, "dojoDndContainer");
 
 		// mark up children
 		if(!(params && params._skipStartup)){
@@ -101,11 +82,11 @@ dojo.declare("dojo.dnd.Container", Evented, {
 
 		// set up events
 		this.events = [
-			dojo.connect(this.node, "onmouseover", this, "onMouseOver"),
-			dojo.connect(this.node, "onmouseout",  this, "onMouseOut"),
+			on(this.node, touch.over, lang.hitch(this, "onMouseOver")),
+			on(this.node, touch.out,  lang.hitch(this, "onMouseOut")),
 			// cancel text selection and text dragging
-			dojo.connect(this.node, "ondragstart",   this, "onSelectStart"),
-			dojo.connect(this.node, "onselectstart", this, "onSelectStart")
+			on(this.node, "dragstart",   lang.hitch(this, "onSelectStart")),
+			on(this.node, "selectstart", lang.hitch(this, "onSelectStart"))
 		];
 	},
 
@@ -119,9 +100,9 @@ dojo.declare("dojo.dnd.Container", Evented, {
 	getItem: function(/*String*/ key){
 		// summary:
 		//		returns a data item by its key (id)
-		return this.map[key];	// dojo.dnd.Item
+		return this.map[key];	// Container.Item
 	},
-	setItem: function(/*String*/ key, /*dojo.dnd.Item*/ data){
+	setItem: function(/*String*/ key, /*Container.Item*/ data){
 		// summary:
 		//		associates a data item with its key (id)
 		this.map[key] = data;
@@ -135,8 +116,8 @@ dojo.declare("dojo.dnd.Container", Evented, {
 		// summary:
 		//		iterates over a data map skipping members that
 		//		are present in the empty object (IE and/or 3rd-party libraries).
-		o = o || dojo.global;
-		var m = this.map, e = dojo.dnd._empty;
+		o = o || kernel.global;
+		var m = this.map, e = dnd._empty;
 		for(var i in m){
 			if(i in e){ continue; }
 			f.call(o, m[i], i, this);
@@ -153,7 +134,7 @@ dojo.declare("dojo.dnd.Container", Evented, {
 	getAllNodes: function(){
 		// summary:
 		//		returns a list (an array) of all valid child nodes
-		return dojo.query("> .dojoDndItem", this.parent);	// NodeList
+		return query((this.allowNested ? "" : "> ") + ".dojoDndItem", this.parent);	// NodeList
 	},
 	sync: function(){
 		// summary:
@@ -167,7 +148,7 @@ dojo.declare("dojo.dnd.Container", Evented, {
 					return;
 				}
 			}else{
-				node.id = dojo.dnd.getUniqueId();
+				node.id = dnd.getUniqueId();
 			}
 			var type = node.getAttribute("dndType"),
 				data = node.getAttribute("dndData");
@@ -199,15 +180,16 @@ dojo.declare("dojo.dnd.Container", Evented, {
 				anchor = anchor.nextSibling;
 			}
 		}
+		var i, t;
 		if(anchor){
-			for(var i = 0; i < data.length; ++i){
-				var t = this._normalizedCreator(data[i]);
+			for(i = 0; i < data.length; ++i){
+				t = this._normalizedCreator(data[i]);
 				this.setItem(t.node.id, {data: t.data, type: t.type});
-				this.parent.insertBefore(t.node, anchor);
+				anchor.parentNode.insertBefore(t.node, anchor);
 			}
 		}else{
-			for(var i = 0; i < data.length; ++i){
-				var t = this._normalizedCreator(data[i]);
+			for(i = 0; i < data.length; ++i){
+				t = this._normalizedCreator(data[i]);
 				this.setItem(t.node.id, {data: t.data, type: t.type});
 				this.parent.appendChild(t.node);
 			}
@@ -217,15 +199,15 @@ dojo.declare("dojo.dnd.Container", Evented, {
 	destroy: function(){
 		// summary:
 		//		prepares this object to be garbage-collected
-		dojo.forEach(this.events, dojo.disconnect);
+		array.forEach(this.events, function(handle){ handle.remove(); });
 		this.clearItems();
 		this.node = this.parent = this.current = null;
 	},
 
 	// markup methods
-	markupFactory: function(params, node, ctor){
+	markupFactory: function(params, node, Ctor){
 		params._skipStartup = true;
-		return new ctor(node, params);
+		return new Ctor(node, params);
 	},
 	startup: function(){
 		// summary:
@@ -240,7 +222,7 @@ dojo.declare("dojo.dnd.Container", Evented, {
 				if(c && c.length){ this.parent = c[0]; }
 			}
 		}
-		this.defaultCreator = dojo.dnd._defaultCreator(this.parent);
+		this.defaultCreator = dnd._defaultCreator(this.parent);
 
 		// process specially marked children
 		this.sync();
@@ -249,7 +231,7 @@ dojo.declare("dojo.dnd.Container", Evented, {
 	// mouse events
 	onMouseOver: function(e){
 		// summary:
-		//		event processor for onmouseover
+		//		event processor for onmouseover or touch, to mark that element as the current element
 		// e: Event
 		//		mouse event
 		var n = e.relatedTarget;
@@ -296,8 +278,9 @@ dojo.declare("dojo.dnd.Container", Evented, {
 		//		event processor for onselectevent and ondragevent
 		// e: Event
 		//		mouse event
-		if(!this.skipForm || !dojo.dnd.isFormElement(e)){
-			dojo.stopEvent(e);
+		if(!this.skipForm || !dnd.isFormElement(e)){
+			e.stopPropagation();
+			e.preventDefault();
 		}
 	},
 
@@ -319,8 +302,8 @@ dojo.declare("dojo.dnd.Container", Evented, {
 		//		new state
 		var prefix = "dojoDnd" + type;
 		var state  = type.toLowerCase() + "State";
-		//dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
-		dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
+		//domClass.replace(this.node, prefix + newState, prefix + this[state]);
+		domClass.replace(this.node, prefix + newState, prefix + this[state]);
 		this[state] = newState;
 	},
 	_addItemClass: function(node, type){
@@ -330,7 +313,7 @@ dojo.declare("dojo.dnd.Container", Evented, {
 		//		a node
 		// type: String
 		//		a variable suffix for a class name
-		dojo.addClass(node, "dojoDndItem" + type);
+		domClass.add(node, "dojoDndItem" + type);
 	},
 	_removeItemClass: function(node, type){
 		// summary:
@@ -339,7 +322,7 @@ dojo.declare("dojo.dnd.Container", Evented, {
 		//		a node
 		// type: String
 		//		a variable suffix for a class name
-		dojo.removeClass(node, "dojoDndItem" + type);
+		domClass.remove(node, "dojoDndItem" + type);
 	},
 	_getChildByEvent: function(e){
 		// summary:
@@ -349,66 +332,66 @@ dojo.declare("dojo.dnd.Container", Evented, {
 		var node = e.target;
 		if(node){
 			for(var parent = node.parentNode; parent; node = parent, parent = node.parentNode){
-				if(parent == this.parent && dojo.hasClass(node, "dojoDndItem")){ return node; }
+				if((parent == this.parent || this.allowNested) && domClass.contains(node, "dojoDndItem")){ return node; }
 			}
 		}
 		return null;
 	},
-	_normalizedCreator: function(/*dojo.dnd.Item*/ item, /*String*/ hint){
+	_normalizedCreator: function(/*Container.Item*/ item, /*String*/ hint){
 		// summary:
 		//		adds all necessary data to the output of the user-supplied creator function
 		var t = (this.creator || this.defaultCreator).call(this, item, hint);
-		if(!dojo.isArray(t.type)){ t.type = ["text"]; }
-		if(!t.node.id){ t.node.id = dojo.dnd.getUniqueId(); }
-		dojo.addClass(t.node, "dojoDndItem");
+		if(!lang.isArray(t.type)){ t.type = ["text"]; }
+		if(!t.node.id){ t.node.id = dnd.getUniqueId(); }
+		domClass.add(t.node, "dojoDndItem");
 		return t;
 	}
 });
 
-dojo.dnd._createNode = function(tag){
+dnd._createNode = function(tag){
 	// summary:
 	//		returns a function, which creates an element of given tag
 	//		(SPAN by default) and sets its innerHTML to given text
 	// tag: String
 	//		a tag name or empty for SPAN
-	if(!tag){ return dojo.dnd._createSpan; }
+	if(!tag){ return dnd._createSpan; }
 	return function(text){	// Function
-		return dojo.create(tag, {innerHTML: text});	// Node
+		return domConstruct.create(tag, {innerHTML: text});	// Node
 	};
 };
 
-dojo.dnd._createTrTd = function(text){
+dnd._createTrTd = function(text){
 	// summary:
 	//		creates a TR/TD structure with given text as an innerHTML of TD
 	// text: String
 	//		a text for TD
-	var tr = dojo.create("tr");
-	dojo.create("td", {innerHTML: text}, tr);
+	var tr = domConstruct.create("tr");
+	domConstruct.create("td", {innerHTML: text}, tr);
 	return tr;	// Node
 };
 
-dojo.dnd._createSpan = function(text){
+dnd._createSpan = function(text){
 	// summary:
 	//		creates a SPAN element with given text as its innerHTML
 	// text: String
 	//		a text for SPAN
-	return dojo.create("span", {innerHTML: text});	// Node
+	return domConstruct.create("span", {innerHTML: text});	// Node
 };
 
-// dojo.dnd._defaultCreatorNodes: Object
+// dnd._defaultCreatorNodes: Object
 //		a dictionary that maps container tag names to child tag names
-dojo.dnd._defaultCreatorNodes = {ul: "li", ol: "li", div: "div", p: "div"};
+dnd._defaultCreatorNodes = {ul: "li", ol: "li", div: "div", p: "div"};
 
-dojo.dnd._defaultCreator = function(node){
+dnd._defaultCreator = function(node){
 	// summary:
 	//		takes a parent node, and returns an appropriate creator function
 	// node: Node
 	//		a container node
 	var tag = node.tagName.toLowerCase();
-	var c = tag == "tbody" || tag == "thead" ? dojo.dnd._createTrTd :
-			dojo.dnd._createNode(dojo.dnd._defaultCreatorNodes[tag]);
+	var c = tag == "tbody" || tag == "thead" ? dnd._createTrTd :
+			dnd._createNode(dnd._defaultCreatorNodes[tag]);
 	return function(item, hint){	// Function
-		var isObj = item && dojo.isObject(item), data, type, n;
+		var isObj = item && lang.isObject(item), data, type, n;
 		if(isObj && item.tagName && item.nodeType && item.getAttribute){
 			// process a DOM node
 			data = item.getAttribute("dndData") || item.innerHTML;
@@ -419,14 +402,54 @@ dojo.dnd._defaultCreator = function(node){
 			// process a DnD item object or a string
 			data = (isObj && item.data) ? item.data : item;
 			type = (isObj && item.type) ? item.type : ["text"];
-			n = (hint == "avatar" ? dojo.dnd._createSpan : c)(String(data));
+			n = (hint == "avatar" ? dnd._createSpan : c)(String(data));
 		}
 		if(!n.id){
-			n.id = dojo.dnd.getUniqueId();
+			n.id = dnd.getUniqueId();
 		}
 		return {node: n, data: data, type: type};
 	};
 };
 
-return dojo.dnd.Container;
+/*=====
+Container.__ContainerArgs = declare([], {
+	creator: function(){
+		// summary:
+		//		a creator function, which takes a data item, and returns an object like that:
+		//		{node: newNode, data: usedData, type: arrayOfStrings}
+	},
+
+	// skipForm: Boolean
+	//		don't start the drag operation, if clicked on form elements
+	skipForm: false,
+
+	// dropParent: Node||String
+	//		node or node's id to use as the parent node for dropped items
+	//		(must be underneath the 'node' parameter in the DOM)
+	dropParent: null,
+
+	// _skipStartup: Boolean
+	//		skip startup(), which collects children, for deferred initialization
+	//		(this is used in the markup mode)
+	_skipStartup: false
+});
+
+Container.Item = function(){
+	// summary:
+	//		Represents (one of) the source node(s) being dragged.
+	//		Contains (at least) the "type" and "data" attributes.
+	// type: String[]
+	//		Type(s) of this item, by default this is ["text"]
+	// data: Object
+	//		Logical representation of the object being dragged.
+	//		If the drag object's type is "text" then data is a String,
+	//		if it's another type then data could be a different Object,
+	//		perhaps a name/value hash.
+
+	this.type = type;
+	this.data = data;
+};
+=====*/
+
+return Container;
 });
diff --git a/dojo/dnd/Manager.js b/dojo/dnd/Manager.js
index 9884e80..eb7f9b3 100644
--- a/dojo/dnd/Manager.js
+++ b/dojo/dnd/Manager.js
@@ -1,11 +1,14 @@
-define(["../main", "../Evented", "./common", "./autoscroll", "./Avatar"], function(dojo, Evented) {
-	// module:
-	//		dojo/dnd/Manager
-	// summary:
-	//		TODOC
+define([
+	"../_base/array",  "../_base/declare", "../_base/lang", "../_base/window",
+	"../dom-class", "../Evented", "../has", "../keys", "../on", "../topic", "../touch",
+	"./common", "./autoscroll", "./Avatar"
+], function(array, declare, lang, win, domClass, Evented, has, keys, on, topic, touch,
+	dnd, autoscroll, Avatar){
 
+// module:
+//		dojo/dnd/Manager
 
-var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
+var Manager = declare("dojo.dnd.Manager", [Evented], {
 	// summary:
 	//		the manager of DnD operations (usually a singleton)
 	constructor: function(){
@@ -19,8 +22,8 @@ var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 	},
 
 	// avatar's offset from the mouse
-	OFFSET_X: 16,
-	OFFSET_Y: 16,
+	OFFSET_X: has("touch") ? 0 : 16,
+	OFFSET_Y: has("touch") ? -64 : 16,
 
 	// methods
 	overSource: function(source){
@@ -33,7 +36,7 @@ var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 			this.canDropFlag = Boolean(this.target);
 			this.avatar.update();
 		}
-		dojo.publish("/dnd/source/over", [source]);
+		topic.publish("/dnd/source/over", source);
 	},
 	outSource: function(source){
 		// summary:
@@ -45,10 +48,10 @@ var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 				this.target = null;
 				this.canDropFlag = false;
 				this.avatar.update();
-				dojo.publish("/dnd/source/over", [null]);
+				topic.publish("/dnd/source/over", null);
 			}
 		}else{
-			dojo.publish("/dnd/source/over", [null]);
+			topic.publish("/dnd/source/over", null);
 		}
 	},
 	startDrag: function(source, nodes, copy){
@@ -60,23 +63,34 @@ var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 		//		the list of transferred items
 		// copy: Boolean
 		//		copy items, if true, move items otherwise
+
+		// Tell autoscroll that a drag is starting
+		autoscroll.autoScrollStart(win.doc);
+
 		this.source = source;
 		this.nodes  = nodes;
 		this.copy   = Boolean(copy); // normalizing to true boolean
 		this.avatar = this.makeAvatar();
-		dojo.body().appendChild(this.avatar.node);
-		dojo.publish("/dnd/start", [source, nodes, this.copy]);
+		win.body().appendChild(this.avatar.node);
+		topic.publish("/dnd/start", source, nodes, this.copy);
+
+		function stopEvent(e){
+			e.preventDefault();
+			e.stopPropagation();
+		}
+
 		this.events = [
-			dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove"),
-			dojo.connect(dojo.doc, "onmouseup",   this, "onMouseUp"),
-			dojo.connect(dojo.doc, "onkeydown",   this, "onKeyDown"),
-			dojo.connect(dojo.doc, "onkeyup",     this, "onKeyUp"),
+			on(win.doc, touch.move, lang.hitch(this, "onMouseMove")),
+			on(win.doc, touch.release,   lang.hitch(this, "onMouseUp")),
+			on(win.doc, "keydown",   lang.hitch(this, "onKeyDown")),
+			on(win.doc, "keyup",     lang.hitch(this, "onKeyUp")),
+
 			// cancel text selection and text dragging
-			dojo.connect(dojo.doc, "ondragstart",   dojo.stopEvent),
-			dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent)
+			on(win.doc, "dragstart",   stopEvent),
+			on(win.body(), "selectstart", stopEvent)
 		];
 		var c = "dojoDnd" + (copy ? "Copy" : "Move");
-		dojo.addClass(dojo.body(), c);
+		domClass.add(win.body(), c);
 	},
 	canDrop: function(flag){
 		// summary:
@@ -90,8 +104,8 @@ var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 	stopDrag: function(){
 		// summary:
 		//		stop the DnD in progress
-		dojo.removeClass(dojo.body(), ["dojoDndCopy", "dojoDndMove"]);
-		dojo.forEach(this.events, dojo.disconnect);
+		domClass.remove(win.body(), ["dojoDndCopy", "dojoDndMove"]);
+		array.forEach(this.events, function(handle){ handle.remove(); });
 		this.events = [];
 		this.avatar.destroy();
 		this.avatar = null;
@@ -101,7 +115,7 @@ var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 	makeAvatar: function(){
 		// summary:
 		//		makes the avatar; it is separate to be overwritten dynamically, if needed
-		return new dojo.dnd.Avatar(this);
+		return new Avatar(this);
 	},
 	updateAvatar: function(){
 		// summary:
@@ -117,16 +131,20 @@ var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 		//		mouse event
 		var a = this.avatar;
 		if(a){
-			dojo.dnd.autoScrollNodes(e);
-			//dojo.dnd.autoScroll(e);
+			autoscroll.autoScrollNodes(e);
+			//autoscroll.autoScroll(e);
 			var s = a.node.style;
 			s.left = (e.pageX + this.OFFSET_X) + "px";
 			s.top  = (e.pageY + this.OFFSET_Y) + "px";
-			var copy = Boolean(this.source.copyState(dojo.isCopyKey(e)));
+			var copy = Boolean(this.source.copyState(dnd.getCopyKeyState(e)));
 			if(this.copy != copy){
 				this._setCopyStatus(copy);
 			}
 		}
+		if(has("touch")){
+			// Prevent page from scrolling so that user can drag instead.
+			e.preventDefault();
+		}
 	},
 	onMouseUp: function(e){
 		// summary:
@@ -135,12 +153,11 @@ var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 		//		mouse event
 		if(this.avatar){
 			if(this.target && this.canDropFlag){
-				var copy = Boolean(this.source.copyState(dojo.isCopyKey(e))),
-				params = [this.source, this.nodes, copy, this.target, e];
-				dojo.publish("/dnd/drop/before", params);
-				dojo.publish("/dnd/drop", params);
+				var copy = Boolean(this.source.copyState(dnd.getCopyKeyState(e)));
+				topic.publish("/dnd/drop/before", this.source, this.nodes, copy, this.target, e);
+				topic.publish("/dnd/drop", this.source, this.nodes, copy, this.target, e);
 			}else{
-				dojo.publish("/dnd/cancel");
+				topic.publish("/dnd/cancel");
 			}
 			this.stopDrag();
 		}
@@ -155,14 +172,14 @@ var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 		//		keyboard event
 		if(this.avatar){
 			switch(e.keyCode){
-				case dojo.keys.CTRL:
+				case keys.CTRL:
 					var copy = Boolean(this.source.copyState(true));
 					if(this.copy != copy){
 						this._setCopyStatus(copy);
 					}
 					break;
-				case dojo.keys.ESCAPE:
-					dojo.publish("/dnd/cancel");
+				case keys.ESCAPE:
+					topic.publish("/dnd/cancel");
 					this.stopDrag();
 					break;
 			}
@@ -173,7 +190,7 @@ var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 		//		event processor for onkeyup, watching for CTRL for copy/move status
 		// e: Event
 		//		keyboard event
-		if(this.avatar && e.keyCode == dojo.keys.CTRL){
+		if(this.avatar && e.keyCode == keys.CTRL){
 			var copy = Boolean(this.source.copyState(false));
 			if(this.copy != copy){
 				this._setCopyStatus(copy);
@@ -190,24 +207,26 @@ var Manager = dojo.declare("dojo.dnd.Manager", [Evented], {
 		this.copy = copy;
 		this.source._markDndStatus(this.copy);
 		this.updateAvatar();
-		dojo.replaceClass(dojo.body(),
+		domClass.replace(win.body(),
 			"dojoDnd" + (this.copy ? "Copy" : "Move"),
 			"dojoDnd" + (this.copy ? "Move" : "Copy"));
 	}
 });
 
-// dojo.dnd._manager:
+// dnd._manager:
 //		The manager singleton variable. Can be overwritten if needed.
-dojo.dnd._manager = null;
+dnd._manager = null;
 
-Manager.manager = dojo.dnd.manager = function(){
+Manager.manager = dnd.manager = function(){
 	// summary:
 	//		Returns the current DnD manager.  Creates one if it is not created yet.
-	if(!dojo.dnd._manager){
-		dojo.dnd._manager = new dojo.dnd.Manager();
+	if(!dnd._manager){
+		dnd._manager = new Manager();
 	}
-	return dojo.dnd._manager;	// Object
+	return dnd._manager;	// Object
 };
 
+// TODO: for 2.0, store _manager and manager in Manager only.   Don't access dnd or dojo.dnd.
+
 return Manager;
 });
diff --git a/dojo/dnd/Moveable.js b/dojo/dnd/Moveable.js
index e7b9cbe..ab252ce 100644
--- a/dojo/dnd/Moveable.js
+++ b/dojo/dnd/Moveable.js
@@ -1,69 +1,51 @@
-define(["../main", "../Evented", "../touch", "./Mover"], function(dojo, Evented, touch) {
-	// module:
-	//		dojo/dnd/Moveable
-	// summary:
-	//		TODOC
+define([
+	"../_base/array", "../_base/declare", "../_base/lang",
+	"../dom", "../dom-class", "../Evented", "../on", "../topic", "../touch", "./common", "./Mover", "../_base/window"
+], function(array, declare, lang, dom, domClass, Evented, on, topic, touch, dnd, Mover, win){
 
+// module:
+//		dojo/dnd/Moveable
 
-/*=====
-dojo.declare("dojo.dnd.__MoveableArgs", [], {
-	// handle: Node||String
-	//		A node (or node's id), which is used as a mouse handle.
-	//		If omitted, the node itself is used as a handle.
-	handle: null,
 
-	// delay: Number
-	//		delay move by this number of pixels
-	delay: 0,
-
-	// skip: Boolean
-	//		skip move of form elements
-	skip: false,
-
-	// mover: Object
-	//		a constructor of custom Mover
-	mover: dojo.dnd.Mover
-});
-=====*/
+var Moveable = declare("dojo.dnd.Moveable", [Evented], {
+	// summary:
+	//		an object, which makes a node movable
 
-dojo.declare("dojo.dnd.Moveable", [Evented], {
 	// object attributes (for markup)
 	handle: "",
 	delay: 0,
 	skip: false,
 
 	constructor: function(node, params){
-		// summary:
-		//		an object, which makes a node moveable
 		// node: Node
 		//		a node (or node's id) to be moved
-		// params: dojo.dnd.__MoveableArgs?
+		// params: Moveable.__MoveableArgs?
 		//		optional parameters
-		this.node = dojo.byId(node);
+		this.node = dom.byId(node);
 		if(!params){ params = {}; }
-		this.handle = params.handle ? dojo.byId(params.handle) : null;
+		this.handle = params.handle ? dom.byId(params.handle) : null;
 		if(!this.handle){ this.handle = this.node; }
 		this.delay = params.delay > 0 ? params.delay : 0;
 		this.skip  = params.skip;
-		this.mover = params.mover ? params.mover : dojo.dnd.Mover;
+		this.mover = params.mover ? params.mover : Mover;
 		this.events = [
-			dojo.connect(this.handle, touch.press, this, "onMouseDown"),
+			on(this.handle, touch.press, lang.hitch(this, "onMouseDown")),
 			// cancel text selection and text dragging
-			dojo.connect(this.handle, "ondragstart",   this, "onSelectStart"),
-			dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
+			on(this.handle, "dragstart",   lang.hitch(this, "onSelectStart")),
+			on(this.handle, "selectstart",   lang.hitch(this, "onSelectStart"))
 		];
 	},
 
 	// markup methods
-	markupFactory: function(params, node, ctor){
-		return new ctor(node, params);
+	markupFactory: function(params, node, Ctor){
+		return new Ctor(node, params);
 	},
 
 	// methods
 	destroy: function(){
 		// summary:
 		//		stops watching for possible move, deletes all references, so the object can be garbage-collected
-		dojo.forEach(this.events, dojo.disconnect);
+		array.forEach(this.events, function(handle){ handle.remove(); });
 		this.events = this.node = this.handle = null;
 	},
 
@@ -73,18 +55,19 @@ dojo.declare("dojo.dnd.Moveable", [Evented], {
 		//		event processor for onmousedown/ontouchstart, creates a Mover for the node
 		// e: Event
 		//		mouse/touch event
-		if(this.skip && dojo.dnd.isFormElement(e)){ return; }
+		if(this.skip && dnd.isFormElement(e)){ return; }
 		if(this.delay){
 			this.events.push(
-				dojo.connect(this.handle, touch.move, this, "onMouseMove"),
-				dojo.connect(this.handle, touch.release, this, "onMouseUp")
+				on(this.handle, touch.move, lang.hitch(this, "onMouseMove")),
+				on(this.handle, touch.release, lang.hitch(this, "onMouseUp"))
 			);
 			this._lastX = e.pageX;
 			this._lastY = e.pageY;
 		}else{
 			this.onDragDetected(e);
 		}
-		dojo.stopEvent(e);
+		e.stopPropagation();
+		e.preventDefault();
 	},
 	onMouseMove: function(e){
 		// summary:
@@ -95,7 +78,8 @@ dojo.declare("dojo.dnd.Moveable", [Evented], {
 			this.onMouseUp(e);
 			this.onDragDetected(e);
 		}
-		dojo.stopEvent(e);
+		e.stopPropagation();
+		e.preventDefault();
 	},
 	onMouseUp: function(e){
 		// summary:
@@ -103,71 +87,103 @@ dojo.declare("dojo.dnd.Moveable", [Evented], {
 		// e: Event
 		//		mouse event
 		for(var i = 0; i < 2; ++i){
-			dojo.disconnect(this.events.pop());
+			this.events.pop().remove();
 		}
-		dojo.stopEvent(e);
+		e.stopPropagation();
+		e.preventDefault();
 	},
 	onSelectStart: function(e){
 		// summary:
 		//		event processor for onselectevent and ondragevent
 		// e: Event
 		//		mouse event
-		if(!this.skip || !dojo.dnd.isFormElement(e)){
-			dojo.stopEvent(e);
+		if(!this.skip || !dnd.isFormElement(e)){
+			e.stopPropagation();
+			e.preventDefault();
 		}
 	},
 
 	// local events
-	onDragDetected: function(/* Event */ e){
+	onDragDetected: function(/*Event*/ e){
 		// summary:
 		//		called when the drag is detected;
 		//		responsible for creation of the mover
 		new this.mover(this.node, e, this);
 	},
-	onMoveStart: function(/* dojo.dnd.Mover */ mover){
+	onMoveStart: function(/*Mover*/ mover){
 		// summary:
 		//		called before every move operation
-		dojo.publish("/dnd/move/start", [mover]);
-		dojo.addClass(dojo.body(), "dojoMove");
-		dojo.addClass(this.node, "dojoMoveItem");
+		topic.publish("/dnd/move/start", mover);
+		domClass.add(win.body(), "dojoMove");
+		domClass.add(this.node, "dojoMoveItem");
 	},
-	onMoveStop: function(/* dojo.dnd.Mover */ mover){
+	onMoveStop: function(/*Mover*/ mover){
 		// summary:
 		//		called after every move operation
-		dojo.publish("/dnd/move/stop", [mover]);
-		dojo.removeClass(dojo.body(), "dojoMove");
-		dojo.removeClass(this.node, "dojoMoveItem");
+		topic.publish("/dnd/move/stop", mover);
+		domClass.remove(win.body(), "dojoMove");
+		domClass.remove(this.node, "dojoMoveItem");
 	},
-	onFirstMove: function(/* dojo.dnd.Mover */ mover, /* Event */ e){
+	onFirstMove: function(/*===== mover, e =====*/){
 		// summary:
 		//		called during the very first move notification;
 		//		can be used to initialize coordinates, can be overwritten.
+		// mover: Mover
+		// e: Event
 
 		// default implementation does nothing
 	},
-	onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop, /* Event */ e){
+	onMove: function(mover, leftTop /*=====, e =====*/){
 		// summary:
 		//		called during every move notification;
 		//		should actually move the node; can be overwritten.
+		// mover: Mover
+		// leftTop: Object
+		// e: Event
 		this.onMoving(mover, leftTop);
 		var s = mover.node.style;
 		s.left = leftTop.l + "px";
 		s.top  = leftTop.t + "px";
 		this.onMoved(mover, leftTop);
 	},
-	onMoving: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+	onMoving: function(/*===== mover, leftTop =====*/){
 		// summary:
 		//		called before every incremental move; can be overwritten.
+		// mover: Mover
+		// leftTop: Object
 
 		// default implementation does nothing
 	},
-	onMoved: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+	onMoved: function(/*===== mover, leftTop =====*/){
 		// summary:
 		//		called after every incremental move; can be overwritten.
+		// mover: Mover
+		// leftTop: Object
 
 		// default implementation does nothing
 	}
 });
 
-return dojo.dnd.Moveable;
+/*=====
+Moveable.__MoveableArgs = declare([], {
+	// handle: Node||String
+	//		A node (or node's id), which is used as a mouse handle.
+	//		If omitted, the node itself is used as a handle.
+	handle: null,
+
+	// delay: Number
+	//		delay move by this number of pixels
+	delay: 0,
+
+	// skip: Boolean
+	//		skip move of form elements
+	skip: false,
+
+	// mover: Object
+	//		a constructor of custom Mover
+	mover: dnd.Mover
+});
+=====*/
+
+return Moveable;
 });
diff --git a/dojo/dnd/Mover.js b/dojo/dnd/Mover.js
index e74d770..1ddc9db 100644
--- a/dojo/dnd/Mover.js
+++ b/dojo/dnd/Mover.js
@@ -1,15 +1,17 @@
-define(["../main", "../Evented", "../touch", "./common", "./autoscroll"], function(dojo, Evented, touch) {
-	// module:
-	//		dojo/dnd/Mover
-	// summary:
-	//		TODOC
+define([
+	"../_base/array", "../_base/declare", "../_base/lang", "../sniff", "../_base/window",
+	"../dom", "../dom-geometry", "../dom-style", "../Evented", "../on", "../touch", "./common", "./autoscroll"
+], function(array, declare, lang, has, win, dom, domGeom, domStyle, Evented, on, touch, dnd, autoscroll){
+
+// module:
+//		dojo/dnd/Mover
 
+return declare("dojo.dnd.Mover", [Evented], {
+	// summary:
+	//		an object which makes a node follow the mouse, or touch-drag on touch devices.
+	//		Used as a default mover, and as a base class for custom movers.
 
-dojo.declare("dojo.dnd.Mover", [Evented], {
 	constructor: function(node, e, host){
-		// summary:
-		//		an object which makes a node follow the mouse, or touch-drag on touch devices.
-		//		Used as a default mover, and as a base class for custom movers.
 		// node: Node
 		//		a node (or node's id) to be moved
 		// e: Event
@@ -18,25 +20,35 @@ dojo.declare("dojo.dnd.Mover", [Evented], {
 		// host: Object?
 		//		object which implements the functionality of the move,
 		//	 	and defines proper events (onMoveStart and onMoveStop)
-		this.node = dojo.byId(node);
+		this.node = dom.byId(node);
 		this.marginBox = {l: e.pageX, t: e.pageY};
 		this.mouseButton = e.button;
 		var h = (this.host = host), d = node.ownerDocument;
+
+		function stopEvent(e){
+			e.preventDefault();
+			e.stopPropagation();
+		}
+
 		this.events = [
-			// At the start of a drag, onFirstMove is called, and then the following two
-			// connects are disconnected
-			dojo.connect(d, touch.move, this, "onFirstMove"),
+			// At the start of a drag, onFirstMove is called, and then the following
+			// listener is disconnected.
+			on(d, touch.move, lang.hitch(this, "onFirstMove")),
 
 			// These are called continually during the drag
-			dojo.connect(d, touch.move, this, "onMouseMove"),
+			on(d, touch.move, lang.hitch(this, "onMouseMove")),
 
 			// And these are called at the end of the drag
-			dojo.connect(d, touch.release,   this, "onMouseUp"),
+			on(d, touch.release,  lang.hitch(this, "onMouseUp")),
 
 			// cancel text selection and text dragging
-			dojo.connect(d, "ondragstart",   dojo.stopEvent),
-			dojo.connect(d.body, "onselectstart", dojo.stopEvent)
+			on(d, "dragstart",   stopEvent),
+			on(d.body, "selectstart", stopEvent)
 		];
+
+		// Tell autoscroll that a drag is starting
+		autoscroll.autoScrollStart(d);
+
 		// notify that the move has started
 		if(h && h.onMoveStart){
 			h.onMoveStart(this);
@@ -48,23 +60,25 @@ dojo.declare("dojo.dnd.Mover", [Evented], {
 		//		event processor for onmousemove/ontouchmove
 		// e: Event
 		//		mouse/touch event
-		dojo.dnd.autoScroll(e);
+		autoscroll.autoScroll(e);
 		var m = this.marginBox;
 		this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY}, e);
-		dojo.stopEvent(e);
+		e.preventDefault();
+		e.stopPropagation();
 	},
 	onMouseUp: function(e){
-		if(dojo.isWebKit && dojo.isMac && this.mouseButton == 2 ?
+		if(has("webkit") && has("mac") && this.mouseButton == 2 ?
 				e.button == 0 : this.mouseButton == e.button){ // TODO Should condition be met for touch devices, too?
 			this.destroy();
 		}
-		dojo.stopEvent(e);
+		e.preventDefault();
+		e.stopPropagation();
 	},
 	// utilities
 	onFirstMove: function(e){
 		// summary:
 		//		makes the node absolute; it is meant to be called only once.
-		// 		relative and absolutely positioned nodes are assumed to use pixel units
+		//		relative and absolutely positioned nodes are assumed to use pixel units
 		var s = this.node.style, l, t, h = this.host;
 		switch(s.position){
 			case "relative":
@@ -75,19 +89,19 @@ dojo.declare("dojo.dnd.Mover", [Evented], {
 				break;
 			default:
 				s.position = "absolute";	// enforcing the absolute mode
-				var m = dojo.marginBox(this.node);
+				var m = domGeom.getMarginBox(this.node);
 				// event.pageX/pageY (which we used to generate the initial
 				// margin box) includes padding and margin set on the body.
 				// However, setting the node's position to absolute and then
-				// doing dojo.marginBox on it *doesn't* take that additional
+				// doing domGeom.marginBox on it *doesn't* take that additional
 				// space into account - so we need to subtract the combined
 				// padding and margin.  We use getComputedStyle and
 				// _getMarginBox/_getContentBox to avoid the extra lookup of
 				// the computed style.
-				var b = dojo.doc.body;
-				var bs = dojo.getComputedStyle(b);
-				var bm = dojo._getMarginBox(b, bs);
-				var bc = dojo._getContentBox(b, bs);
+				var b = win.doc.body;
+				var bs = domStyle.getComputedStyle(b);
+				var bm = domGeom.getMarginBox(b, bs);
+				var bc = domGeom.getContentBox(b, bs);
 				l = m.l - (bc.l - bm.l);
 				t = m.t - (bc.t - bm.t);
 				break;
@@ -98,13 +112,13 @@ dojo.declare("dojo.dnd.Mover", [Evented], {
 			h.onFirstMove(this, e);
 		}
 
-		// Disconnect onmousemove and ontouchmove events that call this function
-		dojo.disconnect(this.events.shift());
+		// Disconnect touch.move that call this function
+		this.events.shift().remove();
 	},
 	destroy: function(){
 		// summary:
 		//		stops the move, deletes all references, so the object can be garbage-collected
-		dojo.forEach(this.events, dojo.disconnect);
+		array.forEach(this.events, function(handle){ handle.remove(); });
 		// undo global settings
 		var h = this.host;
 		if(h && h.onMoveStop){
@@ -115,5 +129,4 @@ dojo.declare("dojo.dnd.Mover", [Evented], {
 	}
 });
 
-return dojo.dnd.Mover;
 });
diff --git a/dojo/dnd/Selector.js b/dojo/dnd/Selector.js
index a4d9606..32a1eeb 100644
--- a/dojo/dnd/Selector.js
+++ b/dojo/dnd/Selector.js
@@ -1,9 +1,10 @@
-define(["../main", "./common", "./Container"], function(dojo) {
-	// module:
-	//		dojo/dnd/Selector
-	// summary:
-	//		TODOC
+define([
+	"../_base/array", "../_base/declare", "../_base/kernel", "../_base/lang",
+	"../dom", "../dom-construct", "../mouse", "../_base/NodeList", "../on", "../touch", "./common", "./Container"
+], function(array, declare, kernel, lang, dom, domConstruct, mouse, NodeList, on, touch, dnd, Container){
 
+// module:
+//		dojo/dnd/Selector
 
 /*
 	Container item states:
@@ -13,18 +14,18 @@ define(["../main", "./common", "./Container"], function(dojo) {
 */
 
 /*=====
-dojo.declare("dojo.dnd.__SelectorArgs", [dojo.dnd.__ContainerArgs], {
-	//	singular: Boolean
+var __SelectorArgs = declare([Container.__ContainerArgs], {
+	// singular: Boolean
 	//		allows selection of only one element, if true
 	singular: false,
 
-	//	autoSync: Boolean
+	// autoSync: Boolean
 	//		autosynchronizes the source with its list of DnD nodes,
 	autoSync: false
 });
 =====*/
 
-dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
+var Selector = declare("dojo.dnd.Selector", Container, {
 	// summary:
 	//		a Selector object, which knows how to select its children
 
@@ -41,7 +42,7 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 		//		constructor of the Selector
 		// node: Node||String
 		//		node or node's id to build the selector on
-		// params: dojo.dnd.__SelectorArgs?
+		// params: __SelectorArgs?
 		//		a dictionary of parameters
 		if(!params){ params = {}; }
 		this.singular = params.singular;
@@ -52,8 +53,9 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 		this.simpleSelection = false;
 		// set up events
 		this.events.push(
-			dojo.connect(this.node, "onmousedown", this, "onMouseDown"),
-			dojo.connect(this.node, "onmouseup",   this, "onMouseUp"));
+			on(this.node, touch.press, lang.hitch(this, "onMouseDown")),
+			on(this.node, touch.release, lang.hitch(this, "onMouseUp"))
+		);
 	},
 
 	// object attributes (for markup)
@@ -63,11 +65,11 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 	getSelectedNodes: function(){
 		// summary:
 		//		returns a list (an array) of selected nodes
-		var t = new dojo.NodeList();
-		var e = dojo.dnd._empty;
+		var t = new NodeList();
+		var e = dnd._empty;
 		for(var i in this.selection){
 			if(i in e){ continue; }
-			t.push(dojo.byId(i));
+			t.push(dom.byId(i));
 		}
 		return t;	// NodeList
 	},
@@ -80,7 +82,7 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 		// summary:
 		//		selects all items
 		this.forInItems(function(data, id){
-			this._addItemClass(dojo.byId(id), "Selected");
+			this._addItemClass(dom.byId(id), "Selected");
 			this.selection[id] = 1;
 		}, this);
 		return this._removeAnchor();	// self
@@ -88,12 +90,12 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 	deleteSelectedNodes: function(){
 		// summary:
 		//		deletes all selected items
-		var e = dojo.dnd._empty;
+		var e = dnd._empty;
 		for(var i in this.selection){
 			if(i in e){ continue; }
-			var n = dojo.byId(i);
+			var n = dom.byId(i);
 			this.delItem(i);
-			dojo.destroy(n);
+			domConstruct.destroy(n);
 		}
 		this.anchor = null;
 		this.selection = {};
@@ -102,9 +104,9 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 	forInSelectedItems: function(/*Function*/ f, /*Object?*/ o){
 		// summary:
 		//		iterates over selected items;
-		//		see `dojo.dnd.Container.forInItems()` for details
-		o = o || dojo.global;
-		var s = this.selection, e = dojo.dnd._empty;
+		//		see `dojo/dnd/Container.forInItems()` for details
+		o = o || kernel.global;
+		var s = this.selection, e = dnd._empty;
 		for(var i in s){
 			if(i in e){ continue; }
 			f.call(o, this.getItem(i), i, this);
@@ -114,7 +116,7 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 		// summary:
 		//		sync up the node list with the data map
 
-		dojo.dnd.Selector.superclass.sync.call(this);
+		Selector.superclass.sync.call(this);
 
 		// fix the anchor
 		if(this.anchor){
@@ -124,14 +126,14 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 		}
 
 		// fix the selection
-		var t = [], e = dojo.dnd._empty;
+		var t = [], e = dnd._empty;
 		for(var i in this.selection){
 			if(i in e){ continue; }
 			if(!this.getItem(i)){
 				t.push(i);
 			}
 		}
-		dojo.forEach(t, function(i){
+		array.forEach(t, function(i){
 			delete this.selection[i];
 		}, this);
 
@@ -139,7 +141,7 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 	},
 	insertNodes: function(addSelected, data, before, anchor){
 		// summary:
-		//		inserts new data items (see `dojo.dnd.Container.insertNodes()` method for details)
+		//		inserts new data items (see `dojo/dnd/Container.insertNodes()` method for details)
 		// addSelected: Boolean
 		//		all new nodes will be added to selected items, if true, no selection change otherwise
 		// data: Array
@@ -167,14 +169,14 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 			}
 			return t;
 		};
-		dojo.dnd.Selector.superclass.insertNodes.call(this, data, before, anchor);
+		Selector.superclass.insertNodes.call(this, data, before, anchor);
 		this._normalizedCreator = oldCreator;
 		return this;	// self
 	},
 	destroy: function(){
 		// summary:
 		//		prepares the object to be garbage-collected
-		dojo.dnd.Selector.superclass.destroy.call(this);
+		Selector.superclass.destroy.call(this);
 		this.selection = this.anchor = null;
 	},
 
@@ -186,17 +188,20 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 		//		mouse event
 		if(this.autoSync){ this.sync(); }
 		if(!this.current){ return; }
-		if(!this.singular && !dojo.isCopyKey(e) && !e.shiftKey && (this.current.id in this.selection)){
+		if(!this.singular && !dnd.getCopyKeyState(e) && !e.shiftKey && (this.current.id in this.selection)){
 			this.simpleSelection = true;
-			if(e.button === dojo.mouseButtons.LEFT){
-				// accept the left button and stop the event
-				// for IE we don't stop event when multiple buttons are pressed
-				dojo.stopEvent(e);
+			if(mouse.isLeft(e)){
+				// Accept the left button and stop the event.   Stopping the event prevents text selection while
+				// dragging.   However, don't stop the event on mobile because that prevents a click event,
+				// and also prevents scroll (see #15838).
+				// For IE we don't stop event when multiple buttons are pressed.
+				e.stopPropagation();
+				e.preventDefault();
 			}
 			return;
 		}
 		if(!this.singular && e.shiftKey){
-			if(!dojo.isCopyKey(e)){
+			if(!dnd.getCopyKeyState(e)){
 				this._removeSelection();
 			}
 			var c = this.getAllNodes();
@@ -207,13 +212,13 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 				}
 				this.selection[this.anchor.id] = 1;
 				if(this.anchor != this.current){
-					var i = 0;
+					var i = 0, node;
 					for(; i < c.length; ++i){
-						var node = c[i];
+						node = c[i];
 						if(node == this.anchor || node == this.current){ break; }
 					}
 					for(++i; i < c.length; ++i){
-						var node = c[i];
+						node = c[i];
 						if(node == this.anchor || node == this.current){ break; }
 						this._addItemClass(node, "Selected");
 						this.selection[node.id] = 1;
@@ -225,7 +230,7 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 		}else{
 			if(this.singular){
 				if(this.anchor == this.current){
-					if(dojo.isCopyKey(e)){
+					if(dnd.getCopyKeyState(e)){
 						this.selectNone();
 					}
 				}else{
@@ -235,7 +240,7 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 					this.selection[this.current.id] = 1;
 				}
 			}else{
-				if(dojo.isCopyKey(e)){
+				if(dnd.getCopyKeyState(e)){
 					if(this.anchor == this.current){
 						delete this.selection[this.anchor.id];
 						this._removeAnchor();
@@ -263,9 +268,10 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 				}
 			}
 		}
-		dojo.stopEvent(e);
+		e.stopPropagation();
+		e.preventDefault();
 	},
-	onMouseUp: function(e){
+	onMouseUp: function(/*===== e =====*/){
 		// summary:
 		//		event processor for onmouseup
 		// e: Event
@@ -279,7 +285,7 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 			this.selection[this.current.id] = 1;
 		}
 	},
-	onMouseMove: function(e){
+	onMouseMove: function(/*===== e =====*/){
 		// summary:
 		//		event processor for onmousemove
 		// e: Event
@@ -291,21 +297,23 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 	onOverEvent: function(){
 		// summary:
 		//		this function is called once, when mouse is over our container
-		this.onmousemoveEvent = dojo.connect(this.node, "onmousemove", this, "onMouseMove");
+		this.onmousemoveEvent = on(this.node, touch.move, lang.hitch(this, "onMouseMove"));
 	},
 	onOutEvent: function(){
 		// summary:
 		//		this function is called once, when mouse is out of our container
-		dojo.disconnect(this.onmousemoveEvent);
-		delete this.onmousemoveEvent;
+		if(this.onmousemoveEvent){
+			this.onmousemoveEvent.remove();
+			delete this.onmousemoveEvent;
+		}
 	},
 	_removeSelection: function(){
 		// summary:
 		//		unselects all items
-		var e = dojo.dnd._empty;
+		var e = dnd._empty;
 		for(var i in this.selection){
 			if(i in e){ continue; }
-			var node = dojo.byId(i);
+			var node = dom.byId(i);
 			if(node){ this._removeItemClass(node, "Selected"); }
 		}
 		this.selection = {};
@@ -320,5 +328,6 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 	}
 });
 
-return dojo.dnd.Selector;
+return Selector;
+
 });
diff --git a/dojo/dnd/Source.js b/dojo/dnd/Source.js
index 05bb3ce..288b69f 100644
--- a/dojo/dnd/Source.js
+++ b/dojo/dnd/Source.js
@@ -1,12 +1,12 @@
-define(["../main", "./Selector", "./Manager"], function(dojo, Selector, Manager) {
-	// module:
-	//		dojo/dnd/Source
-	// summary:
-	//		TODOC
+define([
+	"../_base/array", "../_base/declare", "../_base/kernel", "../_base/lang",
+	"../dom-class", "../dom-geometry", "../mouse", "../ready", "../topic",
+	"./common", "./Selector", "./Manager"
+], function(array, declare, kernel, lang, domClass, domGeom, mouse, ready, topic,
+			dnd, Selector, Manager){
 
-/*=====
-Selector = dojo.dnd.Selector;
-=====*/
+// module:
+//		dojo/dnd/Source
 
 /*
 	Container property:
@@ -25,57 +25,47 @@ Selector = dojo.dnd.Selector;
 */
 
 /*=====
-dojo.dnd.__SourceArgs = function(){
-	//	summary:
+var __SourceArgs = {
+	// summary:
 	//		a dict of parameters for DnD Source configuration. Note that any
 	//		property on Source elements may be configured, but this is the
 	//		short-list
-	//	isSource: Boolean?
+	// isSource: Boolean?
 	//		can be used as a DnD source. Defaults to true.
-	//	accept: Array?
+	// accept: Array?
 	//		list of accepted types (text strings) for a target; defaults to
 	//		["text"]
-	//	autoSync: Boolean
+	// autoSync: Boolean
 	//		if true refreshes the node list on every operation; false by default
-	//	copyOnly: Boolean?
+	// copyOnly: Boolean?
 	//		copy items, if true, use a state of Ctrl key otherwise,
 	//		see selfCopy and selfAccept for more details
-	//	delay: Number
+	// delay: Number
 	//		the move delay in pixels before detecting a drag; 0 by default
-	//	horizontal: Boolean?
+	// horizontal: Boolean?
 	//		a horizontal container, if true, vertical otherwise or when omitted
-	//	selfCopy: Boolean?
+	// selfCopy: Boolean?
 	//		copy items by default when dropping on itself,
 	//		false by default, works only if copyOnly is true
-	//	selfAccept: Boolean?
+	// selfAccept: Boolean?
 	//		accept its own items when copyOnly is true,
 	//		true by default, works only if copyOnly is true
-	//	withHandles: Boolean?
+	// withHandles: Boolean?
 	//		allows dragging only by handles, false by default
-	//  generateText: Boolean?
+	// generateText: Boolean?
 	//		generate text node for drag and drop, true by default
-	this.isSource = isSource;
-	this.accept = accept;
-	this.autoSync = autoSync;
-	this.copyOnly = copyOnly;
-	this.delay = delay;
-	this.horizontal = horizontal;
-	this.selfCopy = selfCopy;
-	this.selfAccept = selfAccept;
-	this.withHandles = withHandles;
-	this.generateText = true;
-}
+};
 =====*/
 
 // For back-compat, remove in 2.0.
-if(!dojo.isAsync){
-	dojo.ready(0, function(){
+if(!kernel.isAsync){
+	ready(0, function(){
 		var requires = ["dojo/dnd/AutoSource", "dojo/dnd/Target"];
 		require(requires);	// use indirection so modules not rolled into a build
-	})
+	});
 }
 
-return dojo.declare("dojo.dnd.Source", Selector, {
+var Source = declare("dojo.dnd.Source", Selector, {
 	// summary:
 	//		a Source object, which can be used as a DnD source, or a DnD target
 
@@ -92,15 +82,15 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 	accept: ["text"],
 	generateText: true,
 
-	constructor: function(/*DOMNode|String*/node, /*dojo.dnd.__SourceArgs?*/params){
+	constructor: function(/*DOMNode|String*/ node, /*__SourceArgs?*/ params){
 		// summary:
 		//		a constructor of the Source
 		// node:
 		//		node or node's id to build the source on
 		// params:
 		//		any property of this class may be configured via the params
-		//		object which is mixed-in to the `dojo.dnd.Source` instance
-		dojo.mixin(this, dojo.mixin({}, params));
+		//		object which is mixed-in to the `dojo/dnd/Source` instance
+		lang.mixin(this, lang.mixin({}, params));
 		var type = this.accept;
 		if(type.length){
 			this.accept = {};
@@ -119,21 +109,21 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 		// states
 		this.sourceState  = "";
 		if(this.isSource){
-			dojo.addClass(this.node, "dojoDndSource");
+			domClass.add(this.node, "dojoDndSource");
 		}
 		this.targetState  = "";
 		if(this.accept){
-			dojo.addClass(this.node, "dojoDndTarget");
+			domClass.add(this.node, "dojoDndTarget");
 		}
 		if(this.horizontal){
-			dojo.addClass(this.node, "dojoDndHorizontal");
+			domClass.add(this.node, "dojoDndHorizontal");
 		}
 		// set up events
 		this.topics = [
-			dojo.subscribe("/dnd/source/over", this, "onDndSourceOver"),
-			dojo.subscribe("/dnd/start",  this, "onDndStart"),
-			dojo.subscribe("/dnd/drop",   this, "onDndDrop"),
-			dojo.subscribe("/dnd/cancel", this, "onDndCancel")
+			topic.subscribe("/dnd/source/over", lang.hitch(this, "onDndSourceOver")),
+			topic.subscribe("/dnd/start",  lang.hitch(this, "onDndStart")),
+			topic.subscribe("/dnd/drop",   lang.hitch(this, "onDndDrop")),
+			topic.subscribe("/dnd/cancel", lang.hitch(this, "onDndCancel"))
 		];
 	},
 
@@ -189,8 +179,8 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 	destroy: function(){
 		// summary:
 		//		prepares the object to be garbage-collected
-		dojo.dnd.Source.superclass.destroy.call(this);
-		dojo.forEach(this.topics, dojo.unsubscribe);
+		Source.superclass.destroy.call(this);
+		array.forEach(this.topics, function(t){t.remove();});
 		this.targetAnchor = null;
 	},
 
@@ -201,14 +191,14 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 		// e: Event
 		//		mouse event
 		if(this.isDragging && this.targetState == "Disabled"){ return; }
-		dojo.dnd.Source.superclass.onMouseMove.call(this, e);
+		Source.superclass.onMouseMove.call(this, e);
 		var m = Manager.manager();
 		if(!this.isDragging){
 			if(this.mouseDown && this.isSource &&
 					(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay)){
 				var nodes = this.getSelectedNodes();
 				if(nodes.length){
-					m.startDrag(this, nodes, this.copyState(dojo.isCopyKey(e), true));
+					m.startDrag(this, nodes, this.copyState(dnd.getCopyKeyState(e), true));
 				}
 			}
 		}
@@ -217,10 +207,11 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 			var before = false;
 			if(this.current){
 				if(!this.targetBox || this.targetAnchor != this.current){
-					this.targetBox = dojo.position(this.current, true);
+					this.targetBox = domGeom.position(this.current, true);
 				}
 				if(this.horizontal){
-					before = (e.pageX - this.targetBox.x) < (this.targetBox.w / 2);
+					// In LTR mode, the left part of the object means "before", but in RTL mode it means "after".
+					before = (e.pageX - this.targetBox.x < this.targetBox.w / 2) == domGeom.isBodyLtr(this.current.ownerDocument);
 				}else{
 					before = (e.pageY - this.targetBox.y) < (this.targetBox.h / 2);
 				}
@@ -236,11 +227,11 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 		//		event processor for onmousedown
 		// e: Event
 		//		mouse event
-		if(!this.mouseDown && this._legalMouseDown(e) && (!this.skipForm || !dojo.dnd.isFormElement(e))){
+		if(!this.mouseDown && this._legalMouseDown(e) && (!this.skipForm || !dnd.isFormElement(e))){
 			this.mouseDown = true;
 			this._lastX = e.pageX;
 			this._lastY = e.pageY;
-			dojo.dnd.Source.superclass.onMouseDown.call(this, e);
+			Source.superclass.onMouseDown.call(this, e);
 		}
 	},
 	onMouseUp: function(e){
@@ -250,7 +241,7 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 		//		mouse event
 		if(this.mouseDown){
 			this.mouseDown = false;
-			dojo.dnd.Source.superclass.onMouseUp.call(this, e);
+			Source.superclass.onMouseUp.call(this, e);
 		}
 	},
 
@@ -260,7 +251,7 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 		//		topic event processor for /dnd/source/over, called when detected a current source
 		// source: Object
 		//		the source which has the mouse over it
-		if(this != source){
+		if(this !== source){
 			this.mouseDown = false;
 			if(this.targetAnchor){
 				this._unmarkTargetAnchor();
@@ -360,15 +351,15 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 			// we have no creator defined => move/clone nodes
 			if(copy){
 				// clone nodes
-				this._normalizedCreator = function(node, hint){
+				this._normalizedCreator = function(node /*=====, hint =====*/){
 					var t = source.getItem(node.id);
 					var n = node.cloneNode(true);
-					n.id = dojo.dnd.getUniqueId();
+					n.id = dnd.getUniqueId();
 					return {node: n, data: t.data, type: t.type};
 				};
 			}else{
 				// move nodes
-				this._normalizedCreator = function(node, hint){
+				this._normalizedCreator = function(node /*=====, hint =====*/){
 					var t = source.getItem(node.id);
 					source.delItem(node.id);
 					return {node: node, data: t.data, type: t.type};
@@ -408,10 +399,10 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 				};
 			}else{
 				// clone nodes
-				this._normalizedCreator = function(node, hint){
+				this._normalizedCreator = function(node/*=====, hint =====*/){
 					var t = this.getItem(node.id);
 					var n = node.cloneNode(true);
-					n.id = dojo.dnd.getUniqueId();
+					n.id = dnd.getUniqueId();
 					return {node: n, data: t.data, type: t.type};
 				};
 			}
@@ -421,7 +412,7 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 				// do nothing
 				return;
 			}
-			this._normalizedCreator = function(node, hint){
+			this._normalizedCreator = function(node /*=====, hint =====*/){
 				var t = this.getItem(node.id);
 				return {node: node, data: t.data, type: t.type};
 			};
@@ -445,7 +436,7 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 	onOverEvent: function(){
 		// summary:
 		//		this function is called once, when mouse is over our container
-		dojo.dnd.Source.superclass.onOverEvent.call(this);
+		Source.superclass.onOverEvent.call(this);
 		Manager.manager().overSource(this);
 		if(this.isDragging && this.targetState != "Disabled"){
 			this.onDraggingOver();
@@ -454,7 +445,7 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 	onOutEvent: function(){
 		// summary:
 		//		this function is called once, when mouse is out of our container
-		dojo.dnd.Source.superclass.onOutEvent.call(this);
+		Source.superclass.onOutEvent.call(this);
 		Manager.manager().outSource(this);
 		if(this.isDragging && this.targetState != "Disabled"){
 			this.onDraggingOut();
@@ -496,18 +487,20 @@ return dojo.declare("dojo.dnd.Source", Selector, {
 		// e: Event
 		//		mouse event
 
-		// accept only the left mouse button
-		if(!dojo.mouseButtons.isLeft(e)){ return false; }
+		// accept only the left mouse button, or the left finger
+		if(e.type != "touchstart" && !mouse.isLeft(e)){ return false; }
 
 		if(!this.withHandles){ return true; }
 
 		// check for handles
 		for(var node = e.target; node && node !== this.node; node = node.parentNode){
-			if(dojo.hasClass(node, "dojoDndHandle")){ return true; }
-			if(dojo.hasClass(node, "dojoDndItem") || dojo.hasClass(node, "dojoDndIgnore")){ break; }
+			if(domClass.contains(node, "dojoDndHandle")){ return true; }
+			if(domClass.contains(node, "dojoDndItem") || domClass.contains(node, "dojoDndIgnore")){ break; }
 		}
 		return false;	// Boolean
 	}
 });
 
+return Source;
+
 });
diff --git a/dojo/dnd/Target.js b/dojo/dnd/Target.js
index 353ae2f..18eda0d 100644
--- a/dojo/dnd/Target.js
+++ b/dojo/dnd/Target.js
@@ -1,13 +1,13 @@
-define([ "./Source" ], function(Source){
-	/*===== Source = dojo.dnd.Source =====*/
-	return dojo.declare("dojo.dnd.Target", Source, {
-		// summary: a Target object, which can be used as a DnD target
+define([ "../_base/declare", "../dom-class", "./Source" ], function(declare, domClass, Source){
+	return declare("dojo.dnd.Target", Source, {
+		// summary:
+		//		a Target object, which can be used as a DnD target
 
-		constructor: function(node, params){
+		constructor: function(/*===== node, params =====*/){
 			// summary:
-			//		a constructor of the Target --- see the `dojo.dnd.Source.constructor` for details
+			//		a constructor of the Target --- see the `dojo/dnd/Source` constructor for details
 			this.isSource = false;
-			dojo.removeClass(this.node, "dojoDndSource");
+			domClass.remove(this.node, "dojoDndSource");
 		}
 	});
 });
diff --git a/dojo/dnd/TimedMoveable.js b/dojo/dnd/TimedMoveable.js
index 9a3d2f4..918c50d 100644
--- a/dojo/dnd/TimedMoveable.js
+++ b/dojo/dnd/TimedMoveable.js
@@ -1,11 +1,9 @@
-define(["../main", "./Moveable"], function(dojo) {
+define(["../_base/declare", "./Moveable" /*=====, "./Mover" =====*/], function(declare, Moveable /*=====, Mover =====*/){
 	// module:
 	//		dojo/dnd/TimedMoveable
-	// summary:
-	//		TODOC
 
 	/*=====
-	dojo.declare("dojo.dnd.__TimedMoveableArgs", [dojo.dnd.__MoveableArgs], {
+	var __TimedMoveableArgs = declare([Moveable.__MoveableArgs], {
 		// timeout: Number
 		//		delay move by this number of ms,
 		//		accumulating position changes during the timeout
@@ -14,9 +12,9 @@ define(["../main", "./Moveable"], function(dojo) {
 	=====*/
 
 	// precalculate long expressions
-	var oldOnMove = dojo.dnd.Moveable.prototype.onMove;
+	var oldOnMove = Moveable.prototype.onMove;
 
-	dojo.declare("dojo.dnd.TimedMoveable", dojo.dnd.Moveable, {
+	return declare("dojo.dnd.TimedMoveable", Moveable, {
 		// summary:
 		//		A specialized version of Moveable to support an FPS throttling.
 		//		This class puts an upper restriction on FPS, which may reduce
@@ -31,7 +29,7 @@ define(["../main", "./Moveable"], function(dojo) {
 			//		an object that makes a node moveable with a timer
 			// node: Node||String
 			//		a node (or node's id) to be moved
-			// params: dojo.dnd.__TimedMoveableArgs
+			// params: __TimedMoveableArgs
 			//		object with additional parameters.
 
 			// sanitize parameters
@@ -41,16 +39,16 @@ define(["../main", "./Moveable"], function(dojo) {
 			}
 		},
 
-		onMoveStop: function(/* dojo.dnd.Mover */ mover){
+		onMoveStop: function(/*Mover*/ mover){
 			if(mover._timer){
 				// stop timer
 				clearTimeout(mover._timer);
 				// reflect the last received position
-				oldOnMove.call(this, mover, mover._leftTop)
+				oldOnMove.call(this, mover, mover._leftTop);
 			}
-			dojo.dnd.Moveable.prototype.onMoveStop.apply(this, arguments);
+			Moveable.prototype.onMoveStop.apply(this, arguments);
 		},
-		onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+		onMove: function(/*Mover*/ mover, /*Object*/ leftTop){
 			mover._leftTop = leftTop;
 			if(!mover._timer){
 				var _t = this;	// to avoid using dojo.hitch()
@@ -63,7 +61,4 @@ define(["../main", "./Moveable"], function(dojo) {
 			}
 		}
 	});
-
-	return dojo.dnd.TimedMoveable;
-	
 });
diff --git a/dojo/dnd/autoscroll.js b/dojo/dnd/autoscroll.js
index ffc612e..9479680 100644
--- a/dojo/dnd/autoscroll.js
+++ b/dojo/dnd/autoscroll.js
@@ -1,74 +1,104 @@
-define(["../main", "../window"], function(dojo) {
-	// module:
-	//		dojo/dnd/autoscroll
+define(["../_base/lang", "../sniff", "../_base/window", "../dom-geometry", "../dom-style", "../window"],
+	function(lang, has, win, domGeom, domStyle, winUtils){
+
+// module:
+//		dojo/dnd/autoscroll
+
+var exports = {
 	// summary:
-	//		TODOC
+	//		Used by dojo/dnd/Manager to scroll document or internal node when the user
+	//		drags near the edge of the viewport or a scrollable node
+};
+lang.setObject("dojo.dnd.autoscroll", exports);
 
-dojo.getObject("dnd", true, dojo);
+exports.getViewport = winUtils.getBox;
 
-dojo.dnd.getViewport = dojo.window.getBox;
+exports.V_TRIGGER_AUTOSCROLL = 32;
+exports.H_TRIGGER_AUTOSCROLL = 32;
 
-dojo.dnd.V_TRIGGER_AUTOSCROLL = 32;
-dojo.dnd.H_TRIGGER_AUTOSCROLL = 32;
+exports.V_AUTOSCROLL_VALUE = 16;
+exports.H_AUTOSCROLL_VALUE = 16;
 
-dojo.dnd.V_AUTOSCROLL_VALUE = 16;
-dojo.dnd.H_AUTOSCROLL_VALUE = 16;
+// These are set by autoScrollStart().
+// Set to default values in case autoScrollStart() isn't called. (back-compat, remove for 2.0)
+var viewport,
+	doc = win.doc,
+	maxScrollTop = Infinity,
+	maxScrollLeft = Infinity;
 
-dojo.dnd.autoScroll = function(e){
+exports.autoScrollStart = function(d){
 	// summary:
-	//		a handler for onmousemove event, which scrolls the window, if
-	//		necesary
+	//		Called at the start of a drag.
+	// d: Document
+	//		The document of the node being dragged.
+
+	doc = d;
+	viewport = winUtils.getBox(doc);
+
+	// Save height/width of document at start of drag, before it gets distorted by a user dragging an avatar past
+	// the document's edge
+	var html = win.body(doc).parentNode;
+	maxScrollTop = Math.max(html.scrollHeight - viewport.h, 0);
+	maxScrollLeft = Math.max(html.scrollWidth - viewport.w, 0);	// usually 0
+};
+
+exports.autoScroll = function(e){
+	// summary:
+	//		a handler for mousemove and touchmove events, which scrolls the window, if
+	//		necessary
 	// e: Event
-	//		onmousemove event
+	//		mousemove/touchmove event
 
 	// FIXME: needs more docs!
-	var v = dojo.window.getBox(), dx = 0, dy = 0;
-	if(e.clientX < dojo.dnd.H_TRIGGER_AUTOSCROLL){
-		dx = -dojo.dnd.H_AUTOSCROLL_VALUE;
-	}else if(e.clientX > v.w - dojo.dnd.H_TRIGGER_AUTOSCROLL){
-		dx = dojo.dnd.H_AUTOSCROLL_VALUE;
+	var v = viewport || winUtils.getBox(doc), // getBox() call for back-compat, in case autoScrollStart() wasn't called
+		html = win.body(doc).parentNode,
+		dx = 0, dy = 0;
+	if(e.clientX < exports.H_TRIGGER_AUTOSCROLL){
+		dx = -exports.H_AUTOSCROLL_VALUE;
+	}else if(e.clientX > v.w - exports.H_TRIGGER_AUTOSCROLL){
+		dx = Math.min(exports.H_AUTOSCROLL_VALUE, maxScrollLeft - html.scrollLeft);	// don't scroll past edge of doc
 	}
-	if(e.clientY < dojo.dnd.V_TRIGGER_AUTOSCROLL){
-		dy = -dojo.dnd.V_AUTOSCROLL_VALUE;
-	}else if(e.clientY > v.h - dojo.dnd.V_TRIGGER_AUTOSCROLL){
-		dy = dojo.dnd.V_AUTOSCROLL_VALUE;
+	if(e.clientY < exports.V_TRIGGER_AUTOSCROLL){
+		dy = -exports.V_AUTOSCROLL_VALUE;
+	}else if(e.clientY > v.h - exports.V_TRIGGER_AUTOSCROLL){
+		dy = Math.min(exports.V_AUTOSCROLL_VALUE, maxScrollTop - html.scrollTop);	// don't scroll past edge of doc
 	}
 	window.scrollBy(dx, dy);
 };
 
-dojo.dnd._validNodes = {"div": 1, "p": 1, "td": 1};
-dojo.dnd._validOverflow = {"auto": 1, "scroll": 1};
+exports._validNodes = {"div": 1, "p": 1, "td": 1};
+exports._validOverflow = {"auto": 1, "scroll": 1};
 
-dojo.dnd.autoScrollNodes = function(e){
+exports.autoScrollNodes = function(e){
 	// summary:
-	//		a handler for onmousemove event, which scrolls the first avaialble
-	//		Dom element, it falls back to dojo.dnd.autoScroll()
+	//		a handler for mousemove and touchmove events, which scrolls the first available
+	//		Dom element, it falls back to exports.autoScroll()
 	// e: Event
-	//		onmousemove event
+	//		mousemove/touchmove event
 
 	// FIXME: needs more docs!
 
 	var b, t, w, h, rx, ry, dx = 0, dy = 0, oldLeft, oldTop;
 
 	for(var n = e.target; n;){
-		if(n.nodeType == 1 && (n.tagName.toLowerCase() in dojo.dnd._validNodes)){
-			var s = dojo.getComputedStyle(n),
-				overflow = (s.overflow.toLowerCase() in dojo.dnd._validOverflow),
-				overflowX = (s.overflowX.toLowerCase() in dojo.dnd._validOverflow),
-				overflowY = (s.overflowY.toLowerCase() in dojo.dnd._validOverflow);
+		if(n.nodeType == 1 && (n.tagName.toLowerCase() in exports._validNodes)){
+			var s = domStyle.getComputedStyle(n),
+				overflow = (s.overflow.toLowerCase() in exports._validOverflow),
+				overflowX = (s.overflowX.toLowerCase() in exports._validOverflow),
+				overflowY = (s.overflowY.toLowerCase() in exports._validOverflow);
 			if(overflow || overflowX || overflowY){
-				b = dojo._getContentBox(n, s);
-				t = dojo.position(n, true);
+				b = domGeom.getContentBox(n, s);
+				t = domGeom.position(n, true);
 			}
 			// overflow-x
 			if(overflow || overflowX){
-				w = Math.min(dojo.dnd.H_TRIGGER_AUTOSCROLL, b.w / 2);
+				w = Math.min(exports.H_TRIGGER_AUTOSCROLL, b.w / 2);
 				rx = e.pageX - t.x;
-				if(dojo.isWebKit || dojo.isOpera){
+				if(has("webkit") || has("opera")){
 					// FIXME: this code should not be here, it should be taken into account
-					// either by the event fixing code, or the dojo.position()
+					// either by the event fixing code, or the domGeom.position()
 					// FIXME: this code doesn't work on Opera 9.5 Beta
-					rx += dojo.body().scrollLeft;
+					rx += win.body().scrollLeft;
 				}
 				dx = 0;
 				if(rx > 0 && rx < b.w){
@@ -84,13 +114,13 @@ dojo.dnd.autoScrollNodes = function(e){
 			// overflow-y
 			if(overflow || overflowY){
 				//console.log(b.l, b.t, t.x, t.y, n.scrollLeft, n.scrollTop);
-				h = Math.min(dojo.dnd.V_TRIGGER_AUTOSCROLL, b.h / 2);
+				h = Math.min(exports.V_TRIGGER_AUTOSCROLL, b.h / 2);
 				ry = e.pageY - t.y;
-				if(dojo.isWebKit || dojo.isOpera){
+				if(has("webkit") || has("opera")){
 					// FIXME: this code should not be here, it should be taken into account
-					// either by the event fixing code, or the dojo.position()
+					// either by the event fixing code, or the domGeom.position()
 					// FIXME: this code doesn't work on Opera 9.5 Beta
-					ry += dojo.body().scrollTop;
+					ry += win.body().scrollTop;
 				}
 				dy = 0;
 				if(ry > 0 && ry < b.h){
@@ -111,8 +141,9 @@ dojo.dnd.autoScrollNodes = function(e){
 			n = null;
 		}
 	}
-	dojo.dnd.autoScroll(e);
+	exports.autoScroll(e);
 };
 
-	return dojo.dnd;
+return exports;
+
 });
diff --git a/dojo/dnd/common.js b/dojo/dnd/common.js
index 0feba28..d209d9e 100644
--- a/dojo/dnd/common.js
+++ b/dojo/dnd/common.js
@@ -1,27 +1,36 @@
-define(["../main"], function(dojo) {
-	// module:
-	//		dojo/dnd/common
+define(["../sniff", "../_base/kernel", "../_base/lang", "../dom"],
+	function(has, kernel, lang, dom){
+
+// module:
+//		dojo/dnd/common
+
+var exports = lang.getObject("dojo.dnd", true);
+/*=====
+// TODO: for 2.0, replace line above with this code.
+var exports = {
 	// summary:
 	//		TODOC
+};
+=====*/
 
-dojo.getObject("dnd", true, dojo);
-
-dojo.dnd.getCopyKeyState = dojo.isCopyKey;
+exports.getCopyKeyState = function(evt){
+	return evt[has("mac") ? "metaKey" : "ctrlKey"]
+};
 
-dojo.dnd._uniqueId = 0;
-dojo.dnd.getUniqueId = function(){
+exports._uniqueId = 0;
+exports.getUniqueId = function(){
 	// summary:
 	//		returns a unique string for use with any DOM element
 	var id;
 	do{
-		id = dojo._scopeName + "Unique" + (++dojo.dnd._uniqueId);
-	}while(dojo.byId(id));
+		id = kernel._scopeName + "Unique" + (++exports._uniqueId);
+	}while(dom.byId(id));
 	return id;
 };
 
-dojo.dnd._empty = {};
+exports._empty = {};
 
-dojo.dnd.isFormElement = function(/*Event*/ e){
+exports.isFormElement = function(/*Event*/ e){
 	// summary:
 	//		returns true if user clicked on a form element
 	var t = e.target;
@@ -31,5 +40,5 @@ dojo.dnd.isFormElement = function(/*Event*/ e){
 	return " button textarea input select option ".indexOf(" " + t.tagName.toLowerCase() + " ") >= 0;	// Boolean
 };
 
-return dojo.dnd;
+return exports;
 });
diff --git a/dojo/dnd/move.js b/dojo/dnd/move.js
index 811216c..baa504c 100644
--- a/dojo/dnd/move.js
+++ b/dojo/dnd/move.js
@@ -1,12 +1,14 @@
-define(["../main", "./Mover", "./Moveable"], function(dojo) {
-	// module:
-	//		dojo/dnd/move
-	// summary:
-	//		TODOC
+define([
+	"../_base/declare",
+	"../dom-geometry", "../dom-style",
+	"./common", "./Mover", "./Moveable"
+], function(declare, domGeom, domStyle, dnd, Mover, Moveable){
 
+// module:
+//		dojo/dnd/move
 
 /*=====
-dojo.declare("dojo.dnd.move.__constrainedMoveableArgs", [dojo.dnd.__MoveableArgs], {
+var __constrainedMoveableArgs = declare([Moveable.__MoveableArgs], {
 	// constraints: Function
 	//		Calculates a constraint box.
 	//		It is called in a context of the moveable object.
@@ -18,7 +20,7 @@ dojo.declare("dojo.dnd.move.__constrainedMoveableArgs", [dojo.dnd.__MoveableArgs
 });
 =====*/
 
-dojo.declare("dojo.dnd.move.constrainedMoveable", dojo.dnd.Moveable, {
+var constrainedMoveable = declare("dojo.dnd.move.constrainedMoveable", Moveable, {
 	// object attributes (for markup)
 	constraints: function(){},
 	within: false,
@@ -28,14 +30,14 @@ dojo.declare("dojo.dnd.move.constrainedMoveable", dojo.dnd.Moveable, {
 		//		an object that makes a node moveable
 		// node: Node
 		//		a node (or node's id) to be moved
-		// params: dojo.dnd.move.__constrainedMoveableArgs?
+		// params: __constrainedMoveableArgs?
 		//		an optional object with additional parameters;
 		//		the rest is passed to the base class
 		if(!params){ params = {}; }
 		this.constraints = params.constraints;
 		this.within = params.within;
 	},
-	onFirstMove: function(/* dojo.dnd.Mover */ mover){
+	onFirstMove: function(/*Mover*/ mover){
 		// summary:
 		//		called during the very first move notification;
 		//		can be used to initialize coordinates, can be overwritten.
@@ -43,12 +45,12 @@ dojo.declare("dojo.dnd.move.constrainedMoveable", dojo.dnd.Moveable, {
 		c.r = c.l + c.w;
 		c.b = c.t + c.h;
 		if(this.within){
-			var mb = dojo._getMarginSize(mover.node);
+			var mb = domGeom.getMarginSize(mover.node);
 			c.r -= mb.w;
 			c.b -= mb.h;
 		}
 	},
-	onMove: function(/* dojo.dnd.Mover */ mover, /* Object */ leftTop){
+	onMove: function(/*Mover*/ mover, /*Object*/ leftTop){
 		// summary:
 		//		called during every move notification;
 		//		should actually move the node; can be overwritten.
@@ -63,14 +65,14 @@ dojo.declare("dojo.dnd.move.constrainedMoveable", dojo.dnd.Moveable, {
 });
 
 /*=====
-dojo.declare("dojo.dnd.move.__boxConstrainedMoveableArgs", [dojo.dnd.move.__constrainedMoveableArgs], {
+var __boxConstrainedMoveableArgs = declare([__constrainedMoveableArgs], {
 	// box: Object
 	//		a constraint box
 	box: {}
 });
 =====*/
 
-dojo.declare("dojo.dnd.move.boxConstrainedMoveable", dojo.dnd.move.constrainedMoveable, {
+var boxConstrainedMoveable = declare("dojo.dnd.move.boxConstrainedMoveable", constrainedMoveable, {
 	// box:
 	//		object attributes (for markup)
 	box: {},
@@ -80,7 +82,7 @@ dojo.declare("dojo.dnd.move.boxConstrainedMoveable", dojo.dnd.move.constrainedMo
 		//		an object, which makes a node moveable
 		// node: Node
 		//		a node (or node's id) to be moved
-		// params: dojo.dnd.move.__boxConstrainedMoveableArgs?
+		// params: __boxConstrainedMoveableArgs?
 		//		an optional object with parameters
 		var box = params && params.box;
 		this.constraints = function(){ return box; };
@@ -88,7 +90,7 @@ dojo.declare("dojo.dnd.move.boxConstrainedMoveable", dojo.dnd.move.constrainedMo
 });
 
 /*=====
-dojo.declare("dojo.dnd.move.__parentConstrainedMoveableArgs", [dojo.dnd.move.__constrainedMoveableArgs], {
+var __parentConstrainedMoveableArgs = declare( [__constrainedMoveableArgs], {
 	// area: String
 	//		A parent's area to restrict the move.
 	//		Can be "margin", "border", "padding", or "content".
@@ -96,7 +98,7 @@ dojo.declare("dojo.dnd.move.__parentConstrainedMoveableArgs", [dojo.dnd.move.__c
 });
 =====*/
 
-dojo.declare("dojo.dnd.move.parentConstrainedMoveable", dojo.dnd.move.constrainedMoveable, {
+var parentConstrainedMoveable = declare("dojo.dnd.move.parentConstrainedMoveable", constrainedMoveable, {
 	// area:
 	//		object attributes (for markup)
 	area: "content",
@@ -106,38 +108,40 @@ dojo.declare("dojo.dnd.move.parentConstrainedMoveable", dojo.dnd.move.constraine
 		//		an object, which makes a node moveable
 		// node: Node
 		//		a node (or node's id) to be moved
-		// params: dojo.dnd.move.__parentConstrainedMoveableArgs?
+		// params: __parentConstrainedMoveableArgs?
 		//		an optional object with parameters
 		var area = params && params.area;
 		this.constraints = function(){
 			var n = this.node.parentNode,
-				s = dojo.getComputedStyle(n),
-				mb = dojo._getMarginBox(n, s);
+				s = domStyle.getComputedStyle(n),
+				mb = domGeom.getMarginBox(n, s);
 			if(area == "margin"){
 				return mb;	// Object
 			}
-			var t = dojo._getMarginExtents(n, s);
+			var t = domGeom.getMarginExtents(n, s);
 			mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
 			if(area == "border"){
 				return mb;	// Object
 			}
-			t = dojo._getBorderExtents(n, s);
+			t = domGeom.getBorderExtents(n, s);
 			mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
 			if(area == "padding"){
 				return mb;	// Object
 			}
-			t = dojo._getPadExtents(n, s);
+			t = domGeom.getPadExtents(n, s);
 			mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
 			return mb;	// Object
 		};
 	}
 });
 
-// patching functions one level up for compatibility
 
-dojo.dnd.constrainedMover = dojo.dnd.move.constrainedMover;
-dojo.dnd.boxConstrainedMover = dojo.dnd.move.boxConstrainedMover;
-dojo.dnd.parentConstrainedMover = dojo.dnd.move.parentConstrainedMover;
+return {
+	// summary:
+	//		TODOC
+	constrainedMoveable: constrainedMoveable,
+	boxConstrainedMoveable: boxConstrainedMoveable,
+	parentConstrainedMoveable: parentConstrainedMoveable
+};
 
-return dojo.dnd.move;
 });
diff --git a/dojo/dojo.js b/dojo/dojo.js
index 698183b..54d4b8e 100644
--- a/dojo/dojo.js
+++ b/dojo/dojo.js
@@ -17,12 +17,12 @@
 	//
 	//		This loader includes sniffing machinery to determine the environment; the following environments are supported:
 	//
-	//			* browser
-	//			* node.js
-	//			* rhino
+	//		- browser
+	//		- node.js
+	//		- rhino
 	//
-	//		This is the so-called "source loader". As such, it includes many optional features that may be discadred by
-	//		building a customized verion with the build system.
+	//		This is the so-called "source loader". As such, it includes many optional features that may be discarded by
+	//		building a customized version with the build system.
 
 	// Design and Implementation Notes
 	//
@@ -89,7 +89,7 @@
 
 		forEach = function(vector, callback){
 			if(vector){
-				for(var i = 0; i < vector.length;){
+				for(var i = 0; vector[i];){
 					callback(vector[i++]);
 				}
 			}
@@ -109,7 +109,7 @@
 		uidSeed = 1,
 
 		uid = function(){
-			// Returns a unique indentifier (within the lifetime of the document) of the form /_d+/.
+			// Returns a unique identifier (within the lifetime of the document) of the form /_d+/.
 			return "_" + uidSeed++;
 		},
 
@@ -117,9 +117,9 @@
 
 		// this will be the global require function; define it immediately so we can start hanging things off of it
 		req = function(
-			config,       //(object, optional) hash of configuration properties
+			config,		  //(object, optional) hash of configuration properties
 			dependencies, //(array of commonjs.moduleId, optional) list of modules to be loaded before applying callback
-			callback      //(function, optional) lamda expression to apply to module values implied by dependencies
+			callback	  //(function, optional) lambda expression to apply to module values implied by dependencies
 		){
 			return contextRequire(config, dependencies, callback, 0, req);
 		},
@@ -142,7 +142,9 @@
 		return now && has(name);
 	};
 
-	has.add("host-node", typeof process == "object" && /node(\.exe)?$/.test(process.execPath));
+	has.add("host-node", userConfig.has && "host-node" in userConfig.has ?
+		userConfig.has["host-node"] :
+		(typeof process == "object" && process.versions && process.versions.node && process.versions.v8));
 	if(has("host-node")){
 		// fixup the default config for node.js environment
 		require("./_base/configNode.js").config(defaultConfig);
@@ -150,7 +152,9 @@
 		defaultConfig.loaderPatch.nodeRequire = require;
 	}
 
-	has.add("host-rhino", typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object"));
+	has.add("host-rhino", userConfig.has && "host-rhino" in userConfig.has ?
+		userConfig.has["host-rhino"] :
+		(typeof load == "function" && (typeof Packages == "function" || typeof Packages == "object")));
 	if(has("host-rhino")){
 		// owing to rhino's lame feature that hides the source of the script, give the user a way to specify the baseUrl...
 		for(var baseUrl = userConfig.baseUrl || ".", arg, rhinoArgs = this.arguments, i = 0; i < rhinoArgs.length;){
@@ -203,14 +207,17 @@
 		req.isXdUrl = noop;
 
 		req.initSyncLoader = function(dojoRequirePlugin_, checkDojoRequirePlugin_, transformToAmd_){
+			// the first dojo/_base/loader loaded gets to define these variables; they are designed to work
+			// in the presence of zero to many mapped dojo/_base/loaders
 			if(!dojoRequirePlugin){
 				dojoRequirePlugin = dojoRequirePlugin_;
 				checkDojoRequirePlugin = checkDojoRequirePlugin_;
 				transformToAmd = transformToAmd_;
 			}
+
 			return {
 				sync:sync,
-				xd:xd,
+				requested:requested,
 				arrived:arrived,
 				nonmodule:nonmodule,
 				executing:executing,
@@ -226,19 +233,17 @@
 				execModule:execModule,
 				dojoRequirePlugin:dojoRequirePlugin,
 				getLegacyMode:function(){return legacyMode;},
-				holdIdle:function(){checkCompleteGuard++;},
-				releaseIdle:function(){checkIdle();}
+				guardCheckComplete:guardCheckComplete
 			};
 		};
 
 		if(has("dom")){
-			// in legacy sync mode, the loader needs a minimal XHR library to load dojo/_base/loader and dojo/_base/xhr
+			// in legacy sync mode, the loader needs a minimal XHR library
 
 			var locationProtocol = location.protocol,
-				locationHost = location.host,
-				fileProtocol = !locationHost;
+				locationHost = location.host;
 			req.isXdUrl = function(url){
-				if(fileProtocol || /^\./.test(url)){
+				if(/^\./.test(url)){
 					// begins with a dot is always relative to page URL; therefore not xdomain
 					return false;
 				}
@@ -247,10 +252,13 @@
 					return true;
 				}
 				// get protocol and host
-				var match = url.match(/^([^\/\:]+\:)\/\/([^\/]+)/);
-				return match && (match[1] != locationProtocol || match[2] != locationHost);
+				// \/+ takes care of the typical file protocol that looks like file:///drive/path/to/file
+				// locationHost is falsy if file protocol => if locationProtocol matches and is "file:", || will return false
+				var match = url.match(/^([^\/\:]+\:)\/+([^\/]+)/);
+				return match && (match[1] != locationProtocol || (locationHost && match[2] != locationHost));
 			};
 
+
 			// note: to get the file:// protocol to work in FF, you must set security.fileuri.strict_origin_policy to false in about:config
 			has.add("dojo-xhr-factory", 1);
 			has.add("dojo-force-activex-xhr", has("host-browser") && !doc.addEventListener && window.location.protocol == "file:");
@@ -304,7 +312,7 @@
 	//
 	var eval_ =
 		// use the function constructor so our eval is scoped close to (but not in) in the global space with minimal pollution
-		new Function("__text", 'return eval(__text);');
+		new Function('return eval(arguments[0]);');
 
 	req.eval =
 		function(text, hint){
@@ -361,13 +369,12 @@
 			// a map from packageId to package configuration object; see fixupPackageInfo
 			= {},
 
-		packageMap
-			// map from package name to local-installed package name
+		map = req.map
+			// AMD map config variable; dojo/_base/kernel needs req.map to figure out the scope map
 			= {},
 
-		packageMapProg
-			// list of (from-package, to-package, regex, length) derived from packageMap;
-			// a "program" to apply paths; see computeMapProg
+		mapProgs
+			// vector of quads as described by computeMapProg; map-key is AMD map key, map-value is AMD map value
 			= [],
 
 		modules
@@ -377,24 +384,24 @@
 			// mid: the fully-resolved (i.e., mappings have been applied) module identifier without the package identifier (e.g., "dojo/io/script")
 			// url: the URL from which the module was retrieved
 			// pack: the package object of the package to which the module belongs
-			// executed: 0 => not executed; executing => in the process of tranversing deps and running factory; executed => factory has been executed
+			// executed: 0 => not executed; executing => in the process of traversing deps and running factory; executed => factory has been executed
 			// deps: the dependency vector for this module (vector of modules objects)
 			// def: the factory for this module
 			// result: the result of the running the factory for this module
-			// injected: (requested | arrived | nonmodule) the status of the module; nonmodule means the resource did not call define
+			// injected: (0 | requested | arrived) the status of the module; nonmodule means the resource did not call define
 			// load: plugin load function; applicable only for plugins
 			//
 			// Modules go through several phases in creation:
 			//
 			// 1. Requested: some other module's definition or a require application contained the requested module in
-			//    its dependency vector or executing code explicitly demands a module via req.require.
+			//	  its dependency vector or executing code explicitly demands a module via req.require.
 			//
 			// 2. Injected: a script element has been appended to the insert-point element demanding the resource implied by the URL
 			//
-			// 3. Loaded: the resource injected in [2] has been evalated.
+			// 3. Loaded: the resource injected in [2] has been evaluated.
 			//
 			// 4. Defined: the resource contained a define statement that advised the loader about the module. Notice that some
-			//    resources may just contain a bundle of code and never formally define a module via define
+			//	  resources may just contain a bundle of code and never formally define a module via define
 			//
 			// 5. Evaluated: the module was defined via define and the loader has evaluated the factory and computed a result.
 			= {},
@@ -404,12 +411,25 @@
 			= "",
 
 		cache
-			// hash:(mid)-->(function)
+			// hash:(mid | url)-->(function | string)
+			//
+			// A cache of resources. The resources arrive via a config.cache object, which is a hash from either mid --> function or
+			// url --> string. The url key is distinguished from the mid key by always containing the prefix "url:". url keys as provided
+			// by config.cache always have a string value that represents the contents of the resource at the given url. mid keys as provided
+			// by configl.cache always have a function value that causes the same code to execute as if the module was script injected.
+			//
+			// Both kinds of key-value pairs are entered into cache via the function consumePendingCache, which may relocate keys as given
+			// by any mappings *iff* the config.cache was received as part of a module resource request.
+			//
+			// Further, for mid keys, the implied url is computed and the value is entered into that key as well. This allows mapped modules
+			// to retrieve cached items that may have arrived consequent to another namespace.
 			//
-			// Gives the contents of a cached resource; function should cause the same actions as if the given mid was downloaded
-			// and evaluated by the host environment
 			 = {},
 
+		urlKeyPrefix
+			// the prefix to prepend to a URL key in the cache.
+			= "url:",
+
 		pendingCacheInsert
 			// hash:(mid)-->(function)
 			//
@@ -422,74 +442,95 @@
 		dojoSniffConfig
 			// map of configuration variables
 			// give the data-dojo-config as sniffed from the document (if any)
-			= {};
+			= {},
+
+		insertPointSibling
+			// the nodes used to locate where scripts are injected into the document
+			= 0;
 
 	if(has("dojo-config-api")){
 		var consumePendingCacheInsert = function(referenceModule){
-				for(var p in pendingCacheInsert){
-					var match = p.match(/^url\:(.+)/);
+				var p, item, match, now, m;
+				for(p in pendingCacheInsert){
+					item = pendingCacheInsert[p];
+					match = p.match(/^url\:(.+)/);
 					if(match){
-						cache[toUrl(match[1], referenceModule)] =  pendingCacheInsert[p];
+						cache[urlKeyPrefix + toUrl(match[1], referenceModule)] =  item;
+					}else if(p=="*now"){
+						now = item;
 					}else if(p!="*noref"){
-						cache[getModuleInfo(p, referenceModule).mid] = pendingCacheInsert[p];
+						m = getModuleInfo(p, referenceModule);
+						cache[m.mid] = cache[urlKeyPrefix + m.url] = item;
 					}
 				}
+				if(now){
+					now(createRequire(referenceModule));
+				}
 				pendingCacheInsert = {};
 			},
 
-			computeMapProg = function(map, dest, packName){
-				// This routine takes a map target-prefix(string)-->replacement(string) into a vector
-				// of quads (target-prefix, replacement, regex-for-target-prefix, length-of-target-prefix)
-				//
-				// The loader contains processes that map one string prefix to another. These
-				// are encountered when applying the requirejs paths configuration and when mapping
-				// package names. We can make the mapping and any replacement easier and faster by
-				// replacing the map with a vector of quads and then using this structure in the simple machine runMapProg.
+			escapeString = function(s){
+				return s.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){ return "\\" + c; });
+			},
+
+			computeMapProg = function(map, dest){
+				// This routine takes a map as represented by a JavaScript object and initializes dest, a vector of
+				// quads of (map-key, map-value, refex-for-map-key, length-of-map-key), sorted decreasing by length-
+				// of-map-key. The regex looks for the map-key followed by either "/" or end-of-string at the beginning
+				// of a the search source. Notice the map-value is irrelevant to the algorithm
 				dest.splice(0, dest.length);
-				var p, i, item, reverseName = 0;
-				for(p in map){
-					dest.push([p, map[p]]);
-					if(map[p]==packName){
-						reverseName = p;
-					}
+				for(var p in map){
+					dest.push([
+						p,
+						map[p],
+						new RegExp("^" + escapeString(p) + "(\/|$)"),
+						p.length]);
 				}
-				dest.sort(function(lhs, rhs){
-					return rhs[0].length - lhs[0].length;
+				dest.sort(function(lhs, rhs){ return rhs[3] - lhs[3]; });
+				return dest;
+			},
+
+			computeAliases = function(config, dest){
+				forEach(config, function(pair){
+					// take a fixed-up copy...
+					dest.push([isString(pair[0]) ? new RegExp("^" + escapeString(pair[0]) + "$") : pair[0], pair[1]]);
 				});
-				for(i = 0; i < dest.length;){
-					item = dest[i++];
-					item[2] = new RegExp("^" + item[0].replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){ return "\\" + c; }) + "(\/|$)");
-					item[3] = item[0].length + 1;
-				}
-				return reverseName;
 			},
 
-			fixupPackageInfo = function(packageInfo, baseUrl){
-				// calculate the precise (name, baseUrl, main, mappings) for a package
+
+			fixupPackageInfo = function(packageInfo){
+				// calculate the precise (name, location, main, mappings) for a package
 				var name = packageInfo.name;
 				if(!name){
 					// packageInfo must be a string that gives the name
 					name = packageInfo;
 					packageInfo = {name:name};
 				}
-				packageInfo = mix({main:"main", mapProg:[]}, packageInfo);
-				packageInfo.location = (baseUrl || "") + (packageInfo.location ? packageInfo.location : name);
-				packageInfo.reverseName = computeMapProg(packageInfo.packageMap, packageInfo.mapProg, name);
+				packageInfo = mix({main:"main"}, packageInfo);
+				packageInfo.location = packageInfo.location ? packageInfo.location : name;
+
+				// packageMap is deprecated in favor of AMD map
+				if(packageInfo.packageMap){
+					map[name] = packageInfo.packageMap;
+				}
 
 				if(!packageInfo.main.indexOf("./")){
 					packageInfo.main = packageInfo.main.substring(2);
 				}
 
-				// allow paths to be specified in the package info
-				// TODO: this is not supported; remove
-				mix(paths, packageInfo.paths);
-
 				// now that we've got a fully-resolved package object, push it into the configuration
 				packs[name] = packageInfo;
-				packageMap[name] = name;
 			},
 
-			config = function(config, booting){
+			delayedModuleConfig
+				// module config cannot be consumed until the loader is completely initialized; therefore, all
+				// module config detected during booting is memorized and applied at the end of loader initialization
+				// TODO: this is a bit of a kludge; all config should be moved to end of loader initialization, but
+				// we'll delay this chore and do it with a final loader 1.x cleanup after the 2.x loader prototyping is complete
+				= [],
+
+
+			config = function(config, booting, referenceModule){
 				for(var p in config){
 					if(p=="waitSeconds"){
 						req.waitms = (config[p] || 0) * 1000;
@@ -508,7 +549,7 @@
 						// otherwise, must be truthy => AMD
 						// legacyMode: sync | legacyAsync | xd | false
 						var mode = config[p];
-						req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? "sync" : false));
+						req.legacyMode = legacyMode = (isString(mode) && /sync|legacyAsync/.test(mode) ? mode : (!mode ? sync : false));
 						req.async = !legacyMode;
 					}
 					if(config[p]!==hasCache){
@@ -536,27 +577,45 @@
 				// for each package found in any packages config item, augment the packs map owned by the loader
 				forEach(config.packages, fixupPackageInfo);
 
-				// for each packagePath found in any packagePaths config item, augment the packs map owned by the loader
+				// for each packagePath found in any packagePaths config item, augment the packageConfig
+				// packagePaths is deprecated; remove in 2.0
 				for(baseUrl in config.packagePaths){
 					forEach(config.packagePaths[baseUrl], function(packageInfo){
-						fixupPackageInfo(packageInfo, baseUrl + "/");
+						var location = baseUrl + "/" + packageInfo;
+						if(isString(packageInfo)){
+							packageInfo = {name:packageInfo};
+						}
+						packageInfo.location = location;
+						fixupPackageInfo(packageInfo);
 					});
 				}
 
+				// notice that computeMapProg treats the dest as a reference; therefore, if/when that variable
+				// is published (see dojo-publish-privates), the published variable will always hold a valid value.
+
+				// this must come after all package processing since package processing may mutate map
+				computeMapProg(mix(map, config.map), mapProgs);
+				forEach(mapProgs, function(item){
+					item[1] = computeMapProg(item[1], []);
+					if(item[0]=="*"){
+						mapProgs.star = item;
+					}
+				});
+
 				// push in any paths and recompute the internal pathmap
-				// warning: this cann't be done until the package config is processed since packages may include path info
 				computeMapProg(mix(paths, config.paths), pathsMapProg);
 
 				// aliases
-				forEach(config.aliases, function(pair){
-					if(isString(pair[0])){
-						pair[0] = new RegExp("^" + pair[0].replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, function(c){return "\\" + c;}) + "$");
-					}
-					aliases.push(pair);
-				});
+				computeAliases(config.aliases, aliases);
 
-				// mix any packageMap config item and recompute the internal packageMapProg
-				computeMapProg(mix(packageMap, config.packageMap), packageMapProg);
+				if(booting){
+					delayedModuleConfig.push({config:config.config});
+				}else{
+					for(p in config.config){
+						var module = getModule(p, referenceModule);
+						module.config = mix(module.config || {}, config.config[p]);
+					}
+				}
 
 				// push in any new cache values
 				if(config.cache){
@@ -571,25 +630,41 @@
 			};
 
 		//
-		// execute the various sniffs
+		// execute the various sniffs; userConfig can override and value
 		//
 
 		if(has("dojo-cdn") || has("dojo-sniff")){
-			for(var dojoDir, src, match, scripts = doc.getElementsByTagName("script"), i = 0; i < scripts.length && !match; i++){
-				if((src = scripts[i].getAttribute("src")) && (match = src.match(/(.*)\/?dojo\.js(\W|$)/i))){
-					// if baseUrl wasn't explicitly set, set it here to the dojo directory; this is the 1.6- behavior
-					userConfig.baseUrl = dojoDir = userConfig.baseUrl || defaultConfig.baseUrl || match[1];
-
-					// see if there's a dojo configuration stuffed into the node
-					src = (scripts[i].getAttribute("data-dojo-config") || scripts[i].getAttribute("djConfig"));
-					if(src){
-						dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config");
-					}
-					if(has("dojo-requirejs-api")){
-						var dataMain = scripts[i].getAttribute("data-main");
-						if(dataMain){
-							dojoSniffConfig.deps = dojoSniffConfig.deps || [dataMain];
-						}
+			// the sniff regex looks for a src attribute ending in dojo.js, optionally preceded with a path.
+			// match[3] returns the path to dojo.js (if any) without the trailing slash. This is used for the
+			// dojo location on CDN deployments and baseUrl when either/both of these are not provided
+			// explicitly in the config data; this is the 1.6- behavior.
+
+			var scripts = doc.getElementsByTagName("script"),
+				i = 0,
+				script, dojoDir, src, match;
+			while(i < scripts.length){
+				script = scripts[i++];
+				if((src = script.getAttribute("src")) && (match = src.match(/(((.*)\/)|^)dojo\.js(\W|$)/i))){
+					// sniff dojoDir and baseUrl
+					dojoDir = match[3] || "";
+					defaultConfig.baseUrl = defaultConfig.baseUrl || dojoDir;
+
+					// remember an insertPointSibling
+					insertPointSibling = script;
+				}
+
+				// sniff configuration on attribute in script element
+				if((src = (script.getAttribute("data-dojo-config") || script.getAttribute("djConfig")))){
+					dojoSniffConfig = req.eval("({ " + src + " })", "data-dojo-config");
+
+					// remember an insertPointSibling
+					insertPointSibling = script;
+				}
+
+				// sniff requirejs attribute
+				if(has("dojo-requirejs-api")){
+					if((src = script.getAttribute("data-main"))){
+						dojoSniffConfig.deps = dojoSniffConfig.deps || [src];
 					}
 				}
 			}
@@ -608,23 +683,27 @@
 		// configure the loader; let the user override defaults
 		req.rawConfig = {};
 		config(defaultConfig, 1);
-		config(userConfig, 1);
-		config(dojoSniffConfig, 1);
 
+		// do this before setting userConfig/sniffConfig to allow userConfig/sniff overrides
 		if(has("dojo-cdn")){
 			packs.dojo.location = dojoDir;
+			if(dojoDir){
+				dojoDir += "/";
+			}
 			packs.dijit.location = dojoDir + "../dijit/";
 			packs.dojox.location = dojoDir + "../dojox/";
 		}
 
+		config(userConfig, 1);
+		config(dojoSniffConfig, 1);
+
 	}else{
 		// no config API, assume defaultConfig has everything the loader needs...for the entire lifetime of the application
 		paths = defaultConfig.paths;
 		pathsMapProg = defaultConfig.pathsMapProg;
 		packs = defaultConfig.packs;
 		aliases = defaultConfig.aliases;
-		packageMap = defaultConfig.packageMap;
-		packageMapProg = defaultConfig.packageMapProg;
+		mapProgs = defaultConfig.mapProgs;
 		modules = defaultConfig.modules;
 		cache = defaultConfig.cache;
 		cacheBust = defaultConfig.cacheBust;
@@ -645,26 +724,26 @@
 	// build the loader machinery iaw configuration, including has feature tests
 	var	injectDependencies = function(module){
 			// checkComplete!=0 holds the idle signal; we're not idle if we're injecting dependencies
-			checkCompleteGuard++;
-			forEach(module.deps, injectModule);
-			if(has("dojo-combo-api") && comboPending && !comboPendingTimer){
-				comboPendingTimer = setTimeout(function() {
-					comboPending = 0;
-					comboPendingTimer = null;
-					req.combo.done(function(mids, url) {
-						var onLoadCallback= function(){
-							// defQ is a vector of module definitions 1-to-1, onto mids
-							runDefQ(0, mids);
-							checkComplete();
-						};
-						combosPending.push(mids);
-						injectingModule = mids;
-						req.injectUrl(url, onLoadCallback, mids);
-						injectingModule = 0;
-					}, req);
-				}, 0);
-			}
-			checkIdle();
+			guardCheckComplete(function(){
+				forEach(module.deps, injectModule);
+				if(has("dojo-combo-api") && comboPending && !comboPendingTimer){
+					comboPendingTimer = setTimeout(function() {
+						comboPending = 0;
+						comboPendingTimer = null;
+						req.combo.done(function(mids, url) {
+							var onLoadCallback= function(){
+								// defQ is a vector of module definitions 1-to-1, onto mids
+								runDefQ(0, mids);
+								checkComplete();
+							};
+							combosPending.push(mids);
+							injectingModule = mids;
+							req.injectUrl(url, onLoadCallback, mids);
+							injectingModule = 0;
+						}, req);
+					}, 0);
+				}
+			});
 		},
 
 		contextRequire = function(a1, a2, a3, referenceModule, contextRequire){
@@ -679,7 +758,7 @@
 			}
 			if(!isArray(a1)){
 				// a1 is a configuration
-				config(a1);
+				config(a1, 0, referenceModule);
 
 				// juggle args; (a2, a3) may be (dependencies, callback)
 				a1 = a2;
@@ -695,9 +774,6 @@
 					// resolve the request list with respect to the reference module
 					for(var mid, deps = [], i = 0; i < a1.length;){
 						mid = a1[i++];
-						if(mid in {exports:1, module:1}){
-							throw makeError("illegalModuleId", mid);
-						}
 						deps.push(getModule(mid, referenceModule));
 					}
 
@@ -706,7 +782,8 @@
 						injected: arrived,
 						deps: deps,
 						def: a2 || noop,
-						require: referenceModule ? referenceModule.require : req
+						require: referenceModule ? referenceModule.require : req,
+						gc: 1 //garbage collect
 					});
 					modules[module.mid] = module;
 
@@ -717,10 +794,10 @@
 					// if already traversing a factory tree, then strict causes circular dependency to abort the execution; maybe
 					// it's possible to execute this require later after the current traversal completes and avoid the circular dependency.
 					// ...but *always* insist on immediate in synch mode
-					var strict = checkCompleteGuard && req.async;
-					checkCompleteGuard++;
-					execModule(module, strict);
-					checkIdle();
+					var strict = checkCompleteGuard && legacyMode!=sync;
+					guardCheckComplete(function(){
+						execModule(module, strict);
+					});
 					if(!module.executed){
 						// some deps weren't on board or circular dependency detected and strict; therefore, push into the execQ
 						execQ.push(module);
@@ -753,6 +830,21 @@
 						req.undef(mid, module);
 					};
 				}
+				if(has("dojo-sync-loader")){
+					result.syncLoadNls = function(mid){
+						var nlsModuleInfo = getModuleInfo(mid, module),
+							nlsModule = modules[nlsModuleInfo.mid];
+						if(!nlsModule || !nlsModule.executed){
+							cached = cache[nlsModuleInfo.mid] || cache[urlKeyPrefix + nlsModuleInfo.url];
+							if(cached){
+								evalModuleText(cached);
+								nlsModule = modules[nlsModuleInfo.mid];
+							}
+						}
+						return nlsModule && nlsModule.executed && nlsModule.result;
+					};
+				}
+
 			}
 			return result;
 		},
@@ -775,6 +867,7 @@
 			if(module.url){
 				waiting[module.url] = module.pack || 1;
 			}
+			startTimer();
 		},
 
 		setArrived = function(module){
@@ -797,11 +890,13 @@
 
 		runMapProg = function(targetMid, map){
 			// search for targetMid in map; return the map item if found; falsy otherwise
+			if(map){
 			for(var i = 0; i < map.length; i++){
 				if(map[i][2].test(targetMid)){
 					return map[i];
 				}
 			}
+			}
 			return 0;
 		},
 
@@ -821,24 +916,26 @@
 			return result.join("/");
 		},
 
-		makeModuleInfo = function(pid, mid, pack, url, cacheId){
+		makeModuleInfo = function(pid, mid, pack, url){
 			if(has("dojo-sync-loader")){
 				var xd= req.isXdUrl(url);
-				return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd)), cacheId:cacheId};
+				return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, isXd:xd, isAmd:!!(xd || (packs[pid] && packs[pid].isAmd))};
 			}else{
-				return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0, cacheId:cacheId};
+				return {pid:pid, mid:mid, pack:pack, url:url, executed:0, def:0};
 			}
 		},
 
-		getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, packageMapProg, pathsMapProg, alwaysCreate){
+		getModuleInfo_ = function(mid, referenceModule, packs, modules, baseUrl, mapProgs, pathsMapProg, aliases, alwaysCreate){
 			// arguments are passed instead of using lexical variables so that this function my be used independent of the loader (e.g., the builder)
 			// alwaysCreate is useful in this case so that getModuleInfo never returns references to real modules owned by the loader
-			var pid, pack, midInPackage, mapProg, mapItem, path, url, result, isRelative, requestedMid, cacheId=0;
+			var pid, pack, midInPackage, mapItem, url, result, isRelative, requestedMid;
 			requestedMid = mid;
 			isRelative = /^\./.test(mid);
 			if(/(^\/)|(\:)|(\.js$)/.test(mid) || (isRelative && !referenceModule)){
 				// absolute path or protocol of .js filetype, or relative path but no reference module and therefore relative to page
 				// whatever it is, it's not a module but just a URL of some sort
+				// note: pid===0 indicates the routine is returning an unmodified mid
+
 				return makeModuleInfo(0, mid, 0, mid);
 			}else{
 				// relative module ids are relative to the referenceModule; get rid of any dots
@@ -846,21 +943,23 @@
 				if(/^\./.test(mid)){
 					throw makeError("irrationalPath", mid);
 				}
-				// find the package indicated by the mid, if any
-				mapProg = referenceModule && referenceModule.pack && referenceModule.pack.mapProg;
-				mapItem = (mapProg && runMapProg(mid, mapProg)) || runMapProg(mid, packageMapProg);
+				// at this point, mid is an absolute mid
+
+				// map the mid
+				if(referenceModule){
+					mapItem = runMapProg(referenceModule.mid, mapProgs);
+				}
+				mapItem = mapItem || mapProgs.star;
+				mapItem = mapItem && runMapProg(mid, mapItem[1]);
+
 				if(mapItem){
-					// mid specified a module that's a member of a package; figure out the package id and module id
-					// notice we expect pack.main to be valid with no pre or post slash
-					pid = mapItem[1];
-					mid = mid.substring(mapItem[3]);
-					pack = packs[pid];
-					if(!mid){
-						mid= pack.main;
+					mid = mapItem[1] + mid.substring(mapItem[3]);
 					}
-					midInPackage = mid;
-					cacheId = pack.reverseName + "/" + mid;
-					mid = pid + "/" + mid;
+
+				match = mid.match(/^([^\/]+)(\/(.+))?$/);
+				pid = match ? match[1] : "";
+				if((pack = packs[pid])){
+					mid = pid + "/" + (midInPackage = (match[3] || pack.main));
 				}else{
 					pid = "";
 				}
@@ -875,20 +974,21 @@
 					}
 				});
 				if(candidate){
-					return getModuleInfo_(candidate, 0, packs, modules, baseUrl, packageMapProg, pathsMapProg, alwaysCreate);
+					return getModuleInfo_(candidate, 0, packs, modules, baseUrl, mapProgs, pathsMapProg, aliases, alwaysCreate);
 				}
 
 				result = modules[mid];
 				if(result){
-					return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url, cacheId) : modules[mid];
+					return alwaysCreate ? makeModuleInfo(result.pid, result.mid, result.pack, result.url) : modules[mid];
 				}
 			}
 			// get here iff the sought-after module does not yet exist; therefore, we need to compute the URL given the
 			// fully resolved (i.e., all relative indicators and package mapping resolved) module id
 
+			// note: pid!==0 indicates the routine is returning a url that has .js appended unmodified mid
 			mapItem = runMapProg(mid, pathsMapProg);
 			if(mapItem){
-				url = mapItem[1] + mid.substring(mapItem[3] - 1);
+				url = mapItem[1] + mid.substring(mapItem[3]);
 			}else if(pid){
 				url = pack.location + "/" + midInPackage;
 			}else if(has("config-tlmSiblingOfDojo")){
@@ -901,11 +1001,11 @@
 				url = baseUrl + url;
 			}
 			url += ".js";
-			return makeModuleInfo(pid, mid, pack, compactPath(url), cacheId);
+			return makeModuleInfo(pid, mid, pack, compactPath(url));
 		},
 
 		getModuleInfo = function(mid, referenceModule){
-			return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, packageMapProg, pathsMapProg);
+			return getModuleInfo_(mid, referenceModule, packs, modules, req.baseUrl, mapProgs, pathsMapProg, aliases);
 		},
 
 		resolvePluginResourceId = function(plugin, prid, referenceModule){
@@ -925,9 +1025,9 @@
 				if(has("dojo-sync-loader") && legacyMode == sync && !plugin.executed){
 					injectModule(plugin);
 					if(plugin.injected===arrived && !plugin.executed){
-						checkCompleteGuard++;
-						execModule(plugin);
-						checkIdle();
+						guardCheckComplete(function(){
+							execModule(plugin);
+						});
 					}
 					if(plugin.executed){
 						promoteModuleToPlugin(plugin);
@@ -964,15 +1064,14 @@
 		},
 
 		toUrl = req.toUrl = function(name, referenceModule){
-			// name must include a filetype; fault tolerate to allow no filetype (but things like "path/to/version2.13" will assume filetype of ".13")
-			var	match = name.match(/(.+)(\.[^\/\.]+?)$/),
-				root = (match && match[1]) || name,
-				ext = (match && match[2]) || "",
-				moduleInfo = getModuleInfo(root, referenceModule),
+			var moduleInfo = getModuleInfo(name+"/x", referenceModule),
 				url= moduleInfo.url;
-			// recall, getModuleInfo always returns a url with a ".js" suffix iff pid; therefore, we've got to trim it
-			url= typeof moduleInfo.pid == "string" ? url.substring(0, url.length - 3) : url;
-			return fixupUrl(url + ext);
+			return fixupUrl(moduleInfo.pid===0 ?
+				// if pid===0, then name had a protocol or absolute path; either way, toUrl is the identify function in such cases
+				name :
+				// "/x.js" since getModuleInfo automatically appends ".js" and we appended "/x" to make name look like a module id
+				url.substring(0, url.length-5)
+			);
 		},
 
 		nonModuleProps = {
@@ -1029,8 +1128,7 @@
 			var map = {};
 			forEach(plugin.loadQ, function(pseudoPluginResource){
 				// manufacture and insert the real module in modules
-				var pseudoMid = pseudoPluginResource.mid,
-					prid = resolvePluginResourceId(plugin, pseudoPluginResource.prid, pseudoPluginResource.req.module),
+				var prid = resolvePluginResourceId(plugin, pseudoPluginResource.prid, pseudoPluginResource.req.module),
 					mid = plugin.dynamic ? pseudoPluginResource.mid.replace(/waitingForPlugin$/, prid) : (plugin.mid + "!" + prid),
 					pluginResource = mix(mix({}, pseudoPluginResource), {mid:mid, prid:prid, injected:0});
 				if(!modules[mid]){
@@ -1071,7 +1169,7 @@
 				promoteModuleToPlugin(module);
 				resolvePluginLoadQ(module);
 			}
-			// remove all occurences of this module from the execQ
+			// remove all occurrences of this module from the execQ
 			for(i = 0; i < execQ.length;){
 				if(execQ[i] === module){
 					execQ.splice(i, 1);
@@ -1079,6 +1177,10 @@
 					i++;
 				}
 			}
+			// delete references to synthetic modules
+			if (/^require\*/.test(module.mid)) {
+				delete modules[module.mid];
+			}
 		},
 
 		circleTrace = [],
@@ -1086,7 +1188,7 @@
 		execModule = function(module, strict){
 			// run the dependency vector, then run the factory for module
 			if(module.executed === executing){
-				req.trace("loader-circular-dependency", [circleTrace.concat(mid).join("->")]);
+				req.trace("loader-circular-dependency", [circleTrace.concat(module.mid).join("->")]);
 				return (!module.def || strict) ? abortExec :  (module.cjs && module.cjs.exports);
 			}
 			// at this point the module is either not executed or fully executed
@@ -1109,13 +1211,12 @@
 
 				// for circular dependencies, assume the first module encountered was executed OK
 				// modules that circularly depend on a module that has not run its factory will get
-				// the premade cjs.exports===module.result. They can take a reference to this object and/or
+				// the pre-made cjs.exports===module.result. They can take a reference to this object and/or
 				// add properties to it. When the module finally runs its factory, the factory can
 				// read/write/replace this object. Notice that so long as the object isn't replaced, any
 				// reference taken earlier while walking the deps list is still valid.
 				module.executed = executing;
-				while(i < deps.length){
-					arg = deps[i++];
+				while((arg = deps[i++])){
 					argResult = ((arg === cjsRequireModule) ? createRequire(module) :
 									((arg === cjsExportsModule) ? module.cjs.exports :
 										((arg === cjsModuleModule) ? module.cjs :
@@ -1130,15 +1231,27 @@
 				}
 				runFactory(module, args);
 				finishExec(module);
+				has("dojo-trace-api") && circleTrace.pop();
 			}
 			// at this point the module is guaranteed fully executed
 
-			has("dojo-trace-api") && circleTrace.pop();
 			return module.result;
 		},
 
 
-		checkCompleteGuard =  0,
+		checkCompleteGuard = 0,
+
+		guardCheckComplete = function(proc){
+			try{
+				checkCompleteGuard++;
+				proc();
+			}finally{
+				checkCompleteGuard--;
+			}
+			if(execComplete()){
+				signal("idle", []);
+			}
+		},
 
 		checkComplete = function(){
 			// keep going through the execQ as long as at least one factory is executed
@@ -1146,30 +1259,23 @@
 			if(checkCompleteGuard){
 				return;
 			}
-			checkCompleteGuard++;
-			checkDojoRequirePlugin();
-			for(var currentDefOrder, module, i = 0; i < execQ.length;){
-				currentDefOrder = defOrder;
-				module = execQ[i];
-				execModule(module);
-				if(currentDefOrder!=defOrder){
-					// defOrder was bumped one or more times indicating something was executed (note, this indicates
-					// the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute)
-					checkDojoRequirePlugin();
-					i = 0;
-				}else{
-					// nothing happened; check the next module in the exec queue
-					i++;
+			guardCheckComplete(function(){
+				checkDojoRequirePlugin();
+				for(var currentDefOrder, module, i = 0; i < execQ.length;){
+					currentDefOrder = defOrder;
+					module = execQ[i];
+					execModule(module);
+					if(currentDefOrder!=defOrder){
+						// defOrder was bumped one or more times indicating something was executed (note, this indicates
+						// the execQ was modified, maybe a lot (for example a later module causes an earlier module to execute)
+						checkDojoRequirePlugin();
+						i = 0;
+					}else{
+						// nothing happened; check the next module in the exec queue
+						i++;
+					}
 				}
-			}
-			checkIdle();
-		},
-
-		checkIdle = function(){
-			checkCompleteGuard--;
-			if(execComplete()){
-				signal("idle", []);
-			}
+			});
 		};
 
 
@@ -1179,7 +1285,7 @@
 			// This is useful for testing frameworks (at least).
 			var module = getModule(moduleId, referenceModule);
 			setArrived(module);
-			delete modules[module.mid];
+			mix(module, {def:0, executed:0, injected:0, node:0});
 		};
 	}
 
@@ -1211,7 +1317,6 @@
 						checkComplete();
 					};
 
-				setRequested(module);
 				if(plugin.load){
 					plugin.load(module.prid, module.req, onLoad);
 				}else if(plugin.loadQ){
@@ -1221,16 +1326,9 @@
 					// dependencies of some other module because this may cause circles when the plugin
 					// loadQ is run; also, generally, we want plugins to run early since they may load
 					// several other modules and therefore can potentially unblock many modules
+					plugin.loadQ = [module];
 					execQ.unshift(plugin);
 					injectModule(plugin);
-
-					// maybe the module was cached and is now defined...
-					if(plugin.load){
-						plugin.load(module.prid, module.req, onLoad);
-					}else{
-						// nope; queue up the plugin resource to be loaded after the plugin module is loaded
-						plugin.loadQ = [module];
-					}
 				}
 			},
 
@@ -1243,7 +1341,10 @@
 			injectingCachedModule = 0,
 
 			evalModuleText = function(text, module){
-				// see def() for the injectingCachedModule bracket; it simply causes a short, safe curcuit
+				// see def() for the injectingCachedModule bracket; it simply causes a short, safe circuit
+				if(has("config-stripStrict")){
+					text = text.replace(/"use strict"/g, '');
+				}
 				injectingCachedModule = 1;
 				if(has("config-dojo-loader-catches")){
 					try{
@@ -1276,13 +1377,14 @@
 				if(module.executed || module.injected || waiting[mid] || (module.url && ((module.pack && waiting[module.url]===module.pack) || waiting[module.url]==1))){
 					return;
 				}
+				setRequested(module);
 
 				if(has("dojo-combo-api")){
 					var viaCombo = 0;
 					if(module.plugin && module.plugin.isCombo){
 						// a combo plugin; therefore, must be handled by combo service
 						// the prid should have already been converted to a URL (if required by the plugin) during
-						// the normalze process; in any event, there is no way for the loader to know how to
+						// the normalize process; in any event, there is no way for the loader to know how to
 						// to the conversion; therefore the third argument is zero
 						req.combo.add(module.plugin.mid, module.prid, 0, req);
 						viaCombo = 1;
@@ -1290,7 +1392,6 @@
 						viaCombo = req.combo.add(0, module.mid, module.url, req);
 					}
 					if(viaCombo){
-						setRequested(module);
 						comboPending= 1;
 						return;
 					}
@@ -1301,7 +1402,6 @@
 					return;
 				} // else a normal module (not a plugin)
 
-				setRequested(module);
 
 				var onLoadCallback = function(){
 					runDefQ(module);
@@ -1310,8 +1410,13 @@
 						// nothing was added to the defQ (so it wasn't an AMD module) and the module
 						// wasn't marked as arrived by dojo.provide (so it wasn't a v1.6- module);
 						// therefore, it must not have been a module; adjust state accordingly
+						if(has("dojo-enforceDefine")){
+							signal(error, makeError("noDefine", module));
+							return;
+						}
 						setArrived(module);
 						mix(module, nonModuleProps);
+						req.trace("loader-define-nonmodule", [module.url]);
 					}
 
 					if(has("dojo-sync-loader") && legacyMode){
@@ -1323,7 +1428,7 @@
 						checkComplete();
 					}
 				};
-				cached = cache[mid] || cache[module.cacheId];
+				cached = cache[mid] || cache[urlKeyPrefix + module.url];
 				if(cached){
 					req.trace("loader-inject", ["cache", module.mid, url]);
 					evalModuleText(cached, module);
@@ -1365,7 +1470,7 @@
 									// the list of dojo.requires that must be re-applied once all target modules are available;
 									// make a synthetic module to execute the dojo.require's in the correct order
 
-									// compute a guarnateed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module
+									// compute a guaranteed-unique mid for the synthetic finish module; remember the finish vector; remove it from the reference module
 									// TODO: can we just leave the module.finish...what's it hurting?
 									var finishMid = mid + "*finish",
 										finish = module.finish;
@@ -1423,7 +1528,7 @@
 					setArrived(module);
 					finishExec(module);
 					return module;
-				};
+				}
 
 				var mid = module.mid;
 				if(module.injected === arrived){
@@ -1439,12 +1544,15 @@
 						exports: (module.result = {}),
 						setExports: function(exports){
 							module.cjs.exports = exports;
+						},
+						config:function(){
+							return module.config;
 						}
 					}
 				});
 
 				// resolve deps with respect to this module
-				for(var i = 0; i < deps.length; i++){
+				for(var i = 0; deps[i]; i++){
 					deps[i] = getModule(deps[i], module);
 				}
 
@@ -1467,7 +1575,6 @@
 			runDefQ = function(referenceModule, mids){
 				// defQ is an array of [id, dependencies, factory]
 				// mids (if any) is a vector of mids given by a combo service
-				consumePendingCacheInsert(referenceModule);
 				var definedModules = [],
 					module, args;
 				while(defQ.length){
@@ -1476,10 +1583,13 @@
 					// explicit define indicates possible multiple modules in a single file; delay injecting dependencies until defQ fully
 					// processed since modules earlier in the queue depend on already-arrived modules that are later in the queue
 					// TODO: what if no args[0] and no referenceModule
-					module = args[0] && getModule(args[0]) || referenceModule;
-					definedModules.push(defineModule(module, args[1], args[2]));
+					module = (args[0] && getModule(args[0])) || referenceModule;
+					definedModules.push([module, args[1], args[2]]);
 				}
-				forEach(definedModules, injectDependencies);
+				consumePendingCacheInsert(referenceModule);
+				forEach(definedModules, function(args){
+					injectDependencies(defineModule.apply(null, args));
+				});
 			};
 	}
 
@@ -1491,19 +1601,28 @@
 		clearTimer = function(){
 			timerId && clearTimeout(timerId);
 			timerId = 0;
-		},
+		};
 
 		startTimer = function(){
 			clearTimer();
-			req.waitms && (timerId = setTimeout(function(){
+			if(req.waitms){
+				timerId = window.setTimeout(function(){
 					clearTimer();
 					signal(error, makeError("timeout", waiting));
-			}, req.waitms));
+				}, req.waitms);
+			}
 		};
 	}
 
-	if(has("dom")){
-		has.add("ie-event-behavior", doc.attachEvent && (typeof opera === "undefined" || opera.toString() != "[object Opera]"));
+	if (has("dom")) {
+		// Test for IE's different way of signaling when scripts finish loading.  Note that according to
+		// http://bugs.dojotoolkit.org/ticket/15096#comment:14, IE9 also needs to follow the
+		// IE specific code path even though it has an addEventListener() method.
+		// Unknown if special path needed on IE10+, which also has a document.attachEvent() method.
+		// Should evaluate to false for Opera and Windows 8 apps, even though they document.attachEvent()
+		//  is defined in both those environments.
+		has.add("ie-event-behavior", doc.attachEvent && typeof Windows === "undefined" &&
+			(typeof opera === "undefined" || opera.toString() != "[object Opera]"));
 	}
 
 	if(has("dom") && (has("dojo-inject-api") || has("dojo-dom-ready-api"))){
@@ -1533,27 +1652,42 @@
 			// getting its parent and then doing insertBefore solves the "Operation Aborted"
 			// error in IE from appending to a node that isn't properly closed; see
 			// dojo/tests/_base/loader/requirejs/simple-badbase.html for an example
-			var sibling = doc.getElementsByTagName("script")[0],
-				insertPoint= sibling.parentNode;
+			// don't use scripts with type dojo/... since these may be removed; see #15809
+			// prefer to use the insertPoint computed during the config sniff in case a script is removed; see #16958
+			var scripts = doc.getElementsByTagName("script"),
+				i = 0,
+				script;
+			while(!insertPointSibling){
+				if(!/^dojo/.test((script = scripts[i++]) && script.type)){
+					insertPointSibling= script;
+				}
+			}
+
 			req.injectUrl = function(url, callback, owner){
 				// insert a script element to the insert-point element with src=url;
 				// apply callback upon detecting the script has loaded.
 
-				startTimer();
 				var node = owner.node = doc.createElement("script"),
 					onLoad = function(e){
 						e = e || window.event;
 						var node = e.target || e.srcElement;
 						if(e.type === "load" || /complete|loaded/.test(node.readyState)){
-							disconnector();
+							loadDisconnector();
+							errorDisconnector();
 							callback && callback();
 						}
 					},
-					disconnector = domOn(node, "load", "onreadystatechange", onLoad);
+					loadDisconnector = domOn(node, "load", "onreadystatechange", onLoad),
+					errorDisconnector = domOn(node, "error", "onerror", function(e){
+						loadDisconnector();
+						errorDisconnector();
+						signal(error, makeError("scriptError", [url, e]));
+					});
+
 				node.type = "text/javascript";
 				node.charset = "utf-8";
 				node.src = url;
-				insertPoint.insertBefore(node, sibling);
+				insertPointSibling.parentNode.insertBefore(node, insertPointSibling);
 				return node;
 			};
 		}
@@ -1616,8 +1750,8 @@
 	}
 
 	var def = function(
-		mid,		  //(commonjs.moduleId, optional) list of modules to be loaded before running factory
-		dependencies, //(array of commonjs.moduleId, optional)
+		mid,		  //(commonjs.moduleId, optional)
+		dependencies, //(array of commonjs.moduleId, optional) list of modules to be loaded before running factory
 		factory		  //(any)
 	){
 		///
@@ -1627,25 +1761,25 @@
 		// CommonJS factory scan courtesy of http://requirejs.org
 
 		var arity = arguments.length,
-			args = 0,
-			defaultDeps = ["require", "exports", "module"];
-
-		if(has("dojo-amd-factory-scan")){
-			if(arity == 1 && isFunction(mid)){
-				dependencies = [];
-				mid.toString()
-					.replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "")
-					.replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function (match, dep){
-					dependencies.push(dep);
-				});
-				args = [0, defaultDeps.concat(dependencies), mid];
-			}
+			defaultDeps = ["require", "exports", "module"],
+			// the predominate signature...
+			args = [0, mid, dependencies];
+		if(arity==1){
+			args = [0, (isFunction(mid) ? defaultDeps : []), mid];
+		}else if(arity==2 && isString(mid)){
+			args = [mid, (isFunction(dependencies) ? defaultDeps : []), dependencies];
+		}else if(arity==3){
+			args = [mid, dependencies, factory];
 		}
-		if(!args){
-			args = arity == 1 ? [0, defaultDeps, mid] :
-				(arity == 2 ? (isArray(mid) ? [0, mid, dependencies] : (isFunction(dependencies) ? [mid, defaultDeps, dependencies] : [mid, [], dependencies])) :
-					[mid, dependencies, factory]);
+
+		if(has("dojo-amd-factory-scan") && args[1]===defaultDeps){
+			args[2].toString()
+				.replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "")
+				.replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function(match, dep){
+				args[1].push(dep);
+			});
 		}
+
 		req.trace("loader-define", args.slice(0, 2));
 		var targetModule = args[0] && getModule(args[0]),
 			module;
@@ -1704,7 +1838,7 @@
 		req.def = def;
 	}
 
-	// allow config to override default implemention of named functions; this is useful for
+	// allow config to override default implementation of named functions; this is useful for
 	// non-browser environments, e.g., overriding injectUrl, getText, log, etc. in node.js, Rhino, etc.
 	// also useful for testing and monkey patching loader
 	mix(mix(req, defaultConfig.loaderPatch), userConfig.loaderPatch);
@@ -1735,7 +1869,6 @@
 			// these may be interesting to look at when debugging
 			paths:paths,
 			aliases:aliases,
-			packageMap:packageMap,
 			modules:modules,
 			legacyMode:legacyMode,
 			execQ:execQ,
@@ -1744,12 +1877,14 @@
 
 			// these are used for testing
 			// TODO: move testing infrastructure to a different has feature
+			packs:packs,
+			mapProgs:mapProgs,
 			pathsMapProg:pathsMapProg,
-			packageMapProg:packageMapProg,
 			listenerQueues:listenerQueues,
 
 			// these are used by the builder (at least)
 			computeMapProg:computeMapProg,
+			computeAliases:computeAliases,
 			runMapProg:runMapProg,
 			compactPath:compactPath,
 			getModuleInfo:getModuleInfo_
@@ -1762,9 +1897,13 @@
 		if(has("dojo-log-api")){
 			signal(error, makeError("defineAlreadyDefined", 0));
 		}
+		return;
 	}else{
 		global.define = def;
 		global.require = req;
+		if(has("host-node")){
+			require = req;
+		}
 	}
 
 	if(has("dojo-combo-api") && req.combo && req.combo.plugins){
@@ -1776,8 +1915,9 @@
 	}
 
 	if(has("dojo-config-api")){
-		var bootDeps = defaultConfig.deps || userConfig.deps || dojoSniffConfig.deps,
-			bootCallback = defaultConfig.callback || userConfig.callback || dojoSniffConfig.callback;
+		forEach(delayedModuleConfig, function(c){ config(c); });
+		var bootDeps = dojoSniffConfig.deps ||	userConfig.deps || defaultConfig.deps,
+			bootCallback = dojoSniffConfig.callback || userConfig.callback || defaultConfig.callback;
 		req.boot = (bootDeps || bootCallback) ? [bootDeps || [], bootCallback] : 0;
 	}
 	if(!has("dojo-built")){
@@ -1812,6 +1952,8 @@
 			"dojo-sniff":1,
 			"dojo-sync-loader":1,
 			"dojo-test-sniff":1,
+			"config-deferredInstrumentation":1,
+			"config-useDeferredInstrumentation":"report-unhandled-rejections",
 			"config-tlmSiblingOfDojo":1
 		},
 		packages:[{
@@ -1845,7 +1987,8 @@
 			"loader-run-factory":0,
 			"loader-finish-exec":0,
 			"loader-define-module":0,
-			"loader-circular-dependency":0
+			"loader-circular-dependency":0,
+			"loader-define-nonmodule":0
 		},
 		async:0,
 		waitSeconds:15
diff --git a/dojo/dojo.profile.js b/dojo/dojo.profile.js
index 40e45f9..4b24edb 100644
--- a/dojo/dojo.profile.js
+++ b/dojo/dojo.profile.js
@@ -15,7 +15,11 @@ var profile = (function(){
 				"dojo/tests/_base/loader/requirejs/relative/relative-tests":1,
 				"dojo/tests/_base/loader/requirejs/exports/exports-tests":1
 			};
-			return (mid in list) || /^dojo\/_base\/config\w+$/.test(mid) || (/^dojo\/resources\//.test(mid) && !/\.css$/.test(filename)) || /(png|jpg|jpeg|gif|tiff)$/.test(filename);
+			return (mid in list) ||
+				/^dojo\/_base\/config\w+$/.test(mid) ||
+				(/^dojo\/resources\//.test(mid) && !/\.css$/.test(filename)) ||
+				/(png|jpg|jpeg|gif|tiff)$/.test(filename) ||
+				/built\-i18n\-test\/152\-build/.test(mid);
 		};
 
 	return {
@@ -31,10 +35,6 @@ var profile = (function(){
 			amd: function(filename, mid){
 				return !testResourceRe.test(mid) && !copyOnly(filename, mid) && /\.js$/.test(filename);
 			}
-		},
-
-		trees:[
-			[".", ".", /(\/\.)|(~$)/]
-		]
+		}
 	};
 })();
diff --git a/dojo/dom-attr.js b/dojo/dom-attr.js
index d9032df..677c458 100644
--- a/dojo/dom-attr.js
+++ b/dojo/dom-attr.js
@@ -1,22 +1,48 @@
-define(["exports", "./_base/sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"],
+define(["exports", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-prop"],
 		function(exports, has, lang, dom, style, prop){
 	// module:
 	//		dojo/dom-attr
 	// summary:
 	//		This module defines the core dojo DOM attributes API.
 
+	// TODOC: summary not showing up in output see https://github.com/csnover/js-doc-parse/issues/42
+
 	// =============================
 	// Element attribute Functions
 	// =============================
 
-	// This module will be obsolete soon. Use dojo.prop instead.
+	// This module will be obsolete soon. Use dojo/prop instead.
 
 	// dojo.attr() should conform to http://www.w3.org/TR/DOM-Level-2-Core/
 
 	// attribute-related functions (to be obsolete soon)
 
-	/*=====
-	dojo.hasAttr = function(node, name){
+	var forcePropNames = {
+			innerHTML:	1,
+			className:	1,
+			htmlFor:	has("ie"),
+			value:		1
+		},
+		attrNames = {
+			// original attribute names
+			classname: "class",
+			htmlfor: "for",
+			// for IE
+			tabindex: "tabIndex",
+			readonly: "readOnly"
+		};
+
+	function _hasAttr(node, name){
+		var attr = node.getAttributeNode && node.getAttributeNode(name);
+		return attr && attr.specified; // Boolean
+	}
+
+	// There is a difference in the presence of certain properties and their default values
+	// between browsers. For example, on IE "disabled" is present on all elements,
+	// but it is value is "false"; "tabIndex" of <div> returns 0 by default on IE, yet other browsers
+	// can return -1.
+
+	exports.has = function hasAttr(/*DOMNode|String*/ node, /*String*/ name){
 		// summary:
 		//		Returns true if the requested attribute is specified on the
 		//		given element, and false otherwise.
@@ -27,11 +53,12 @@ define(["exports", "./_base/sniff", "./_base/lang", "./dom", "./dom-style", "./d
 		// returns: Boolean
 		//		true if the requested attribute is specified on the
 		//		given element, and false otherwise
+
+		var lc = name.toLowerCase();
+		return forcePropNames[prop.names[lc] || name] || _hasAttr(dom.byId(node), attrNames[lc] || name);	// Boolean
 	};
-	=====*/
 
-	/*=====
-	dojo.getAttr = function(node, name){
+	exports.get = function getAttr(/*DOMNode|String*/ node, /*String*/ name){
 		// summary:
 		//		Gets an attribute on an HTML element.
 		// description:
@@ -49,11 +76,28 @@ define(["exports", "./_base/sniff", "./_base/lang", "./dom", "./dom-style", "./d
 		//	|	dojo.getAttr(dojo.byId("nodeId"), "foo");
 		//	|	// or we can just pass the id:
 		//	|	dojo.getAttr("nodeId", "foo");
+
+		node = dom.byId(node);
+		var lc = name.toLowerCase(),
+			propName = prop.names[lc] || name,
+			forceProp = forcePropNames[propName],
+			value = node[propName];		// should we access this attribute via a property or via getAttribute()?
+
+		if(forceProp && typeof value != "undefined"){
+			// node's property
+			return value;	// Anything
+		}
+		if(propName != "href" && (typeof value == "boolean" || lang.isFunction(value))){
+			// node's property
+			return value;	// Anything
+		}
+		// node's attribute
+		// we need _hasAttr() here to guard against IE returning a default value
+		var attrName = attrNames[lc] || name;
+		return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
 	};
-	=====*/
 
-	/*=====
-	dojo.setAttr = function(node, name, value){
+	exports.set = function setAttr(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
 		// summary:
 		//		Sets an attribute on an HTML element.
 		// description:
@@ -117,85 +161,7 @@ define(["exports", "./_base/sniff", "./_base/lang", "./dom", "./dom-style", "./d
 		//	|
 		//	|	// though shorter to use `dojo.style()` in this case:
 		//	|	dojo.setStyle("someNode", obj);
-	};
-	=====*/
-
-	/*=====
-	dojo.removeAttr = function(node, name){
-		// summary:
-		//		Removes an attribute from an HTML element.
-		// node: DOMNode|String
-		//		id or reference to the element to remove the attribute from
-		// name: String
-		//		the name of the attribute to remove
-	};
-	=====*/
-
-	/*=====
-	dojo.getNodeProp = function(node, name){
-		// summary:
-		//		Returns an effective value of a property or an attribute.
-		// node: DOMNode|String
-		//		id or reference to the element to remove the attribute from
-		// name: String
-		//		the name of the attribute
-		// returns:
-		//      the value of the attribute
-	};
-	=====*/
-
-	var forcePropNames = {
-			innerHTML:	1,
-			className:	1,
-			htmlFor:	has("ie"),
-			value:		1
-		},
-		attrNames = {
-			// original attribute names
-			classname: "class",
-			htmlfor: "for",
-			// for IE
-			tabindex: "tabIndex",
-			readonly: "readOnly"
-		};
 
-	function _hasAttr(node, name){
-		var attr = node.getAttributeNode && node.getAttributeNode(name);
-		return attr && attr.specified; // Boolean
-	}
-
-	// There is a difference in the presence of certain properties and their default values
-	// between browsers. For example, on IE "disabled" is present on all elements,
-	// but it is value is "false"; "tabIndex" of <div> returns 0 by default on IE, yet other browsers
-	// can return -1.
-
-	exports.has = function hasAttr(/*DOMNode|String*/node, /*String*/name){
-		var lc = name.toLowerCase();
-		return forcePropNames[prop.names[lc] || name] || _hasAttr(dom.byId(node), attrNames[lc] || name);	// Boolean
-	};
-
-	exports.get = function getAttr(/*DOMNode|String*/node, /*String*/name){
-		node = dom.byId(node);
-		var lc = name.toLowerCase(),
-			propName = prop.names[lc] || name,
-			forceProp = forcePropNames[propName];
-		// should we access this attribute via a property or via getAttribute()?
-		value = node[propName];
-		if(forceProp && typeof value != "undefined"){
-			// node's property
-			return value;	// Anything
-		}
-		if(propName != "href" && (typeof value == "boolean" || lang.isFunction(value))){
-			// node's property
-			return value;	// Anything
-		}
-		// node's attribute
-		// we need _hasAttr() here to guard against IE returning a default value
-		var attrName = attrNames[lc] || name;
-		return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
-	};
-
-	exports.set = function setAttr(/*DOMNode|String*/node, /*String|Object*/name, /*String?*/value){
 		node = dom.byId(node);
 		if(arguments.length == 2){ // inline'd type check
 			// the object form of setter: the 2nd argument is a dictionary
@@ -213,7 +179,7 @@ define(["exports", "./_base/sniff", "./_base/lang", "./dom", "./dom-style", "./d
 			return node; // DomNode
 		}
 		if(forceProp || typeof value == "boolean" || lang.isFunction(value)){
-			return prop.set(node, name, value)
+			return prop.set(node, name, value);
 		}
 		// node's attribute
 		node.setAttribute(attrNames[lc] || name, value);
@@ -221,10 +187,26 @@ define(["exports", "./_base/sniff", "./_base/lang", "./dom", "./dom-style", "./d
 	};
 
 	exports.remove = function removeAttr(/*DOMNode|String*/ node, /*String*/ name){
+		// summary:
+		//		Removes an attribute from an HTML element.
+		// node: DOMNode|String
+		//		id or reference to the element to remove the attribute from
+		// name: String
+		//		the name of the attribute to remove
+
 		dom.byId(node).removeAttribute(attrNames[name.toLowerCase()] || name);
 	};
 
 	exports.getNodeProp = function getNodeProp(/*DomNode|String*/ node, /*String*/ name){
+		// summary:
+		//		Returns an effective value of a property or an attribute.
+		// node: DOMNode|String
+		//		id or reference to the element to remove the attribute from
+		// name: String
+		//		the name of the attribute
+		// returns:
+		//		the value of the attribute
+
 		node = dom.byId(node);
 		var lc = name.toLowerCase(), propName = prop.names[lc] || name;
 		if((propName in node) && propName != "href"){
diff --git a/dojo/dom-class.js b/dojo/dom-class.js
index 4c4cb7d..06d4cce 100644
--- a/dojo/dom-class.js
+++ b/dojo/dom-class.js
@@ -1,8 +1,6 @@
 define(["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
 	// module:
 	//		dojo/dom-class
-	// summary:
-	//		This module defines the core dojo DOM class API.
 
 	var className = "className";
 
@@ -17,154 +15,6 @@ define(["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
 	// (CSS) Class Functions
 	// =============================
 
-	/*=====
-	dojo.hasClass = function(node, classStr){
-		// summary:
-		//		Returns whether or not the specified classes are a portion of the
-		//		class list currently applied to the node.
-		//
-		// node: String|DOMNode
-		//		String ID or DomNode reference to check the class for.
-		//
-		// classStr: String
-		//		A string class name to look for.
-		//
-		// returns: Boolean
-		//
-		// example:
-		//		Do something if a node with id="someNode" has class="aSillyClassName" present
-		//	|	if(dojo.hasClass("someNode","aSillyClassName")){ ... }
-	};
-	=====*/
-
-	/*=====
-	dojo.addClass = function(node, classStr){
-		// summary:
-		//		Adds the specified classes to the end of the class list on the
-		//		passed node. Will not re-apply duplicate classes.
-		//
-		// node: String|DOMNode
-		//		String ID or DomNode reference to add a class string too
-		//
-		// classStr: String|Array
-		//		A String class name to add, or several space-separated class names,
-		//		or an array of class names.
-		//
-		// example:
-		//		Add a class to some node:
-		//	|	dojo.addClass("someNode", "anewClass");
-		//
-		// example:
-		//		Add two classes at once:
-		//	|	dojo.addClass("someNode", "firstClass secondClass");
-		//
-		// example:
-		//		Add two classes at once (using array):
-		//	|	dojo.addClass("someNode", ["firstClass", "secondClass"]);
-		//
-		// example:
-		//		Available in `dojo.NodeList` for multiple additions
-		//	|	dojo.query("ul > li").addClass("firstLevel");
-	};
-	=====*/
-
-	/*=====
-	dojo.removeClass = function(node, classStr){
-		// summary:
-		//		Removes the specified classes from node. No `dojo.hasClass`
-		//		check is required.
-		//
-		// node: String|DOMNode
-		//		String ID or DomNode reference to remove the class from.
-		//
-		// classStr: String|Array
-		//		An optional String class name to remove, or several space-separated
-		//		class names, or an array of class names. If omitted, all class names
-		//		will be deleted.
-		//
-		// example:
-		//		Remove a class from some node:
-		//	|	dojo.removeClass("someNode", "firstClass");
-		//
-		// example:
-		//		Remove two classes from some node:
-		//	|	dojo.removeClass("someNode", "firstClass secondClass");
-		//
-		// example:
-		//		Remove two classes from some node (using array):
-		//	|	dojo.removeClass("someNode", ["firstClass", "secondClass"]);
-		//
-		// example:
-		//		Remove all classes from some node:
-		//	|	dojo.removeClass("someNode");
-		//
-		// example:
-		//		Available in `dojo.NodeList()` for multiple removal
-		//	|	dojo.query(".foo").removeClass("foo");
-	};
-	=====*/
-
-	/*=====
-	dojo.replaceClass = function(node, addClassStr, removeClassStr){
-		// summary:
-		//		Replaces one or more classes on a node if not present.
-		//		Operates more quickly than calling dojo.removeClass and dojo.addClass
-		//
-		// node: String|DOMNode
-		//		String ID or DomNode reference to remove the class from.
-		//
-		// addClassStr: String|Array
-		//		A String class name to add, or several space-separated class names,
-		//		or an array of class names.
-		//
-		// removeClassStr: String|Array?
-		//		A String class name to remove, or several space-separated class names,
-		//		or an array of class names.
-		//
-		// example:
-		//	|	dojo.replaceClass("someNode", "add1 add2", "remove1 remove2");
-		//
-		// example:
-		//	Replace all classes with addMe
-		//	|	dojo.replaceClass("someNode", "addMe");
-		//
-		// example:
-		//	Available in `dojo.NodeList()` for multiple toggles
-		//	|	dojo.query(".findMe").replaceClass("addMe", "removeMe");
-	};
-	=====*/
-
-	/*=====
-	dojo.toggleClass = function(node, classStr, condition){
-		// summary:
-		//		Adds a class to node if not present, or removes if present.
-		//		Pass a boolean condition if you want to explicitly add or remove.
-		//      Returns the condition that was specified directly or indirectly.
-		//
-		// node: String|DOMNode
-		//		String ID or DomNode reference to toggle a class string
-		//
-		// classStr: String|Array
-		//		A String class name to toggle, or several space-separated class names,
-		//		or an array of class names.
-		//
-		// condition:
-		//		If passed, true means to add the class, false means to remove.
-		//      Otherwise dojo.hasClass(node, classStr) is used to detect the class presence.
-		//
-		// example:
-		//	|	dojo.toggleClass("someNode", "hovered");
-		//
-		// example:
-		//		Forcefully add a class
-		//	|	dojo.toggleClass("someNode", "hovered", true);
-		//
-		// example:
-		//		Available in `dojo.NodeList()` for multiple toggles
-		//	|	dojo.query(".toggleMe").toggleClass("toggleMe");
-	};
-	=====*/
-
 	var cls, // exports object
 		spaces = /\s+/, a1 = [""];
 
@@ -254,11 +104,60 @@ define(["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
 	// regular DOM version
 	var fakeNode = {};  // for effective replacement
 	cls = {
-		contains: function containsClass(/*DomNode|String*/node, /*String*/classStr){
+		// summary:
+		//		This module defines the core dojo DOM class API.
+
+		contains: function containsClass(/*DomNode|String*/ node, /*String*/ classStr){
+			// summary:
+			//		Returns whether or not the specified classes are a portion of the
+			//		class list currently applied to the node.
+			// node: String|DOMNode
+			//		String ID or DomNode reference to check the class for.
+			// classStr: String
+			//		A string class name to look for.
+			// example:
+			//		Do something if a node with id="someNode" has class="aSillyClassName" present
+			//	|	if(dojo.hasClass("someNode","aSillyClassName")){ ... }
+
 			return ((" " + dom.byId(node)[className] + " ").indexOf(" " + classStr + " ") >= 0); // Boolean
 		},
 
-		add: function addClass(/*DomNode|String*/node, /*String|Array*/classStr){
+		add: function addClass(/*DomNode|String*/ node, /*String|Array*/ classStr){
+			// summary:
+			//		Adds the specified classes to the end of the class list on the
+			//		passed node. Will not re-apply duplicate classes.
+			//
+			// node: String|DOMNode
+			//		String ID or DomNode reference to add a class string too
+			//
+			// classStr: String|Array
+			//		A String class name to add, or several space-separated class names,
+			//		or an array of class names.
+			//
+			// example:
+			//		Add a class to some node:
+			//	|	require(["dojo/dom-class"], function(domClass){
+			//	|		domClass.add("someNode", "anewClass");
+			//	|	});
+			//
+			// example:
+			//		Add two classes at once:
+			//	|	require(["dojo/dom-class"], function(domClass){
+			//	|		domClass.add("someNode", "firstClass secondClass");
+			//	|	});
+			//
+			// example:
+			//		Add two classes at once (using array):
+			//	|	require(["dojo/dom-class"], function(domClass){
+			//	|		domClass.add("someNode", ["firstClass", "secondClass"]);
+			//	|	});
+			//
+			// example:
+			//		Available in `dojo/NodeList` for multiple additions
+			//	|	require(["dojo/query"], function(query){
+			//	|		query("ul > li").addClass("firstLevel");
+			//	|	});
+
 			node = dom.byId(node);
 			classStr = str2array(classStr);
 			var cls = node[className], oldLen;
@@ -275,7 +174,49 @@ define(["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
 			}
 		},
 
-		remove: function removeClass(/*DomNode|String*/node, /*String|Array?*/classStr){
+		remove: function removeClass(/*DomNode|String*/ node, /*String|Array?*/ classStr){
+			// summary:
+			//		Removes the specified classes from node. No `contains()`
+			//		check is required.
+			//
+			// node: String|DOMNode
+			//		String ID or DomNode reference to remove the class from.
+			//
+			// classStr: String|Array
+			//		An optional String class name to remove, or several space-separated
+			//		class names, or an array of class names. If omitted, all class names
+			//		will be deleted.
+			//
+			// example:
+			//		Remove a class from some node:
+			//	|	require(["dojo/dom-class"], function(domClass){
+			//	|		domClass.remove("someNode", "firstClass");
+			//	|	});
+			//
+			// example:
+			//		Remove two classes from some node:
+			//	|	require(["dojo/dom-class"], function(domClass){
+			//	|		domClass.remove("someNode", "firstClass secondClass");
+			//	|	});
+			//
+			// example:
+			//		Remove two classes from some node (using array):
+			//	|	require(["dojo/dom-class"], function(domClass){
+			//	|		domClass.remove("someNode", ["firstClass", "secondClass"]);
+			//	|	});
+			//
+			// example:
+			//		Remove all classes from some node:
+			//	|	require(["dojo/dom-class"], function(domClass){
+			//	|		domClass.remove("someNode");
+			//	|	});
+			//
+			// example:
+			//		Available in `dojo/NodeList` for multiple removal
+			//	|	require(["dojo/query"], function(query){
+			//	|		query("ul > li").removeClass("foo");
+			//	|	});
+
 			node = dom.byId(node);
 			var cls;
 			if(classStr !== undefined){
@@ -291,7 +232,39 @@ define(["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
 			if(node[className] != cls){ node[className] = cls; }
 		},
 
-		replace: function replaceClass(/*DomNode|String*/node, /*String|Array*/addClassStr, /*String|Array?*/removeClassStr){
+		replace: function replaceClass(/*DomNode|String*/ node, /*String|Array*/ addClassStr, /*String|Array?*/ removeClassStr){
+			// summary:
+			//		Replaces one or more classes on a node if not present.
+			//		Operates more quickly than calling dojo.removeClass and dojo.addClass
+			//
+			// node: String|DOMNode
+			//		String ID or DomNode reference to remove the class from.
+			//
+			// addClassStr: String|Array
+			//		A String class name to add, or several space-separated class names,
+			//		or an array of class names.
+			//
+			// removeClassStr: String|Array?
+			//		A String class name to remove, or several space-separated class names,
+			//		or an array of class names.
+			//
+			// example:
+			//	|	require(["dojo/dom-class"], function(domClass){
+			//	|		domClass.replace("someNode", "add1 add2", "remove1 remove2");
+			//	|	});
+			//
+			// example:
+			//	Replace all classes with addMe
+			//	|	require(["dojo/dom-class"], function(domClass){
+			//	|		domClass.replace("someNode", "addMe");
+			//	|	});
+			//
+			// example:
+			//	Available in `dojo/NodeList` for multiple toggles
+			//	|	require(["dojo/query"], function(query){
+			//	|		query(".findMe").replaceClass("addMe", "removeMe");
+			//	|	});
+
 			node = dom.byId(node);
 			fakeNode[className] = node[className];
 			cls.remove(fakeNode, removeClassStr);
@@ -301,7 +274,40 @@ define(["./_base/lang", "./_base/array", "./dom"], function(lang, array, dom){
 			}
 		},
 
-		toggle: function toggleClass(/*DomNode|String*/node, /*String|Array*/classStr, /*Boolean?*/condition){
+		toggle: function toggleClass(/*DomNode|String*/ node, /*String|Array*/ classStr, /*Boolean?*/ condition){
+			// summary:
+			//		Adds a class to node if not present, or removes if present.
+			//		Pass a boolean condition if you want to explicitly add or remove.
+			//		Returns the condition that was specified directly or indirectly.
+			//
+			// node: String|DOMNode
+			//		String ID or DomNode reference to toggle a class string
+			//
+			// classStr: String|Array
+			//		A String class name to toggle, or several space-separated class names,
+			//		or an array of class names.
+			//
+			// condition:
+			//		If passed, true means to add the class, false means to remove.
+			//		Otherwise dojo.hasClass(node, classStr) is used to detect the class presence.
+			//
+			// example:
+			//	|	require(["dojo/dom-class"], function(domClass){
+			//	|		domClass.toggle("someNode", "hovered");
+			//	|	});
+			//
+			// example:
+			//		Forcefully add a class
+			//	|	require(["dojo/dom-class"], function(domClass){
+			//	|		domClass.toggle("someNode", "hovered", true);
+			//	|	});
+			//
+			// example:
+			//		Available in `dojo/NodeList` for multiple toggles
+			//	|	require(["dojo/query"], function(query){
+			//	|		query(".toggleMe").toggleClass("toggleMe");
+			//	|	});
+
 			node = dom.byId(node);
 			if(condition === undefined){
 				classStr = str2array(classStr);
diff --git a/dojo/dom-construct.js b/dojo/dom-construct.js
index b3ccc0e..435ed15 100644
--- a/dojo/dom-construct.js
+++ b/dojo/dom-construct.js
@@ -1,202 +1,13 @@
-define(["exports", "./_base/kernel", "./_base/sniff", "./_base/window", "./dom", "./dom-attr", "./on"],
-		function(exports, dojo, has, win, dom, attr, on){
+define(["exports", "./_base/kernel", "./sniff", "./_base/window", "./dom", "./dom-attr"],
+		function(exports, dojo, has, win, dom, attr){
 	// module:
 	//		dojo/dom-construct
 	// summary:
 	//		This module defines the core dojo DOM construction API.
 
-	/*=====
-	dojo.toDom = function(frag, doc){
-		// summary:
-		//		instantiates an HTML fragment returning the corresponding DOM.
-		// frag: String
-		//		the HTML fragment
-		// doc: DocumentNode?
-		//		optional document to use when creating DOM nodes, defaults to
-		//		dojo.doc if not specified.
-		// returns: DocumentFragment
-		//
-		// example:
-		//		Create a table row:
-		//	|	var tr = dojo.toDom("<tr><td>First!</td></tr>");
-	};
-	=====*/
-
-	/*=====
-	dojo._toDom = function(frag, doc){
-		// summary:
-		//		Existing alias for `dojo.toDom`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
-
-	/*=====
-	dojo.place = function(node, refNode, position){
-		// summary:
-		//		Attempt to insert node into the DOM, choosing from various positioning options.
-		//		Returns the first argument resolved to a DOM node.
-		//
-		// node: DOMNode|String
-		//		id or node reference, or HTML fragment starting with "<" to place relative to refNode
-		//
-		// refNode: DOMNode|String
-		//		id or node reference to use as basis for placement
-		//
-		// position: String|Number?
-		//		string noting the position of node relative to refNode or a
-		//		number indicating the location in the childNodes collection of refNode.
-		//		Accepted string values are:
-		//	|	* before
-		//	|	* after
-		//	|	* replace
-		//	|	* only
-		//	|	* first
-		//	|	* last
-		//		"first" and "last" indicate positions as children of refNode, "replace" replaces refNode,
-		//		"only" replaces all children.  position defaults to "last" if not specified
-		//
-		// returns: DOMNode
-		//		Returned values is the first argument resolved to a DOM node.
-		//
-		//		.place() is also a method of `dojo.NodeList`, allowing `dojo.query` node lookups.
-		//
-		// example:
-		//		Place a node by string id as the last child of another node by string id:
-		//	|	dojo.place("someNode", "anotherNode");
-		//
-		// example:
-		//		Place a node by string id before another node by string id
-		//	|	dojo.place("someNode", "anotherNode", "before");
-		//
-		// example:
-		//		Create a Node, and place it in the body element (last child):
-		//	|	dojo.place("<div></div>", dojo.body());
-		//
-		// example:
-		//		Put a new LI as the first child of a list by id:
-		//	|	dojo.place("<li></li>", "someUl", "first");
-	};
-	=====*/
-
-	/*=====
-	dojo.create = function(tag, attrs, refNode, pos){
-		// summary:
-		//		Create an element, allowing for optional attribute decoration
-		//		and placement.
-		//
-		// description:
-		//		A DOM Element creation function. A shorthand method for creating a node or
-		//		a fragment, and allowing for a convenient optional attribute setting step,
-		//		as well as an optional DOM placement reference.
-		//|
-		//		Attributes are set by passing the optional object through `dojo.setAttr`.
-		//		See `dojo.setAttr` for noted caveats and nuances, and API if applicable.
-		//|
-		//		Placement is done via `dojo.place`, assuming the new node to be the action
-		//		node, passing along the optional reference node and position.
-		//
-		// tag: DOMNode|String
-		//		A string of the element to create (eg: "div", "a", "p", "li", "script", "br"),
-		//		or an existing DOM node to process.
-		//
-		// attrs: Object
-		//		An object-hash of attributes to set on the newly created node.
-		//		Can be null, if you don't want to set any attributes/styles.
-		//		See: `dojo.setAttr` for a description of available attributes.
-		//
-		// refNode: DOMNode?|String?
-		//		Optional reference node. Used by `dojo.place` to place the newly created
-		//		node somewhere in the dom relative to refNode. Can be a DomNode reference
-		//		or String ID of a node.
-		//
-		// pos: String?
-		//		Optional positional reference. Defaults to "last" by way of `dojo.place`,
-		//		though can be set to "first","after","before","last", "replace" or "only"
-		//		to further control the placement of the new node relative to the refNode.
-		//		'refNode' is required if a 'pos' is specified.
-		//
-		// returns: DOMNode
-		//
-		// example:
-		//		Create a DIV:
-		//	|	var n = dojo.create("div");
-		//
-		// example:
-		//		Create a DIV with content:
-		//	|	var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
-		//
-		// example:
-		//		Place a new DIV in the BODY, with no attributes set
-		//	|	var n = dojo.create("div", null, dojo.body());
-		//
-		// example:
-		//		Create an UL, and populate it with LI's. Place the list as the first-child of a
-		//		node with id="someId":
-		//	|	var ul = dojo.create("ul", null, "someId", "first");
-		//	|	var items = ["one", "two", "three", "four"];
-		//	|	dojo.forEach(items, function(data){
-		//	|		dojo.create("li", { innerHTML: data }, ul);
-		//	|	});
-		//
-		// example:
-		//		Create an anchor, with an href. Place in BODY:
-		//	|	dojo.create("a", { href:"foo.html", title:"Goto FOO!" }, dojo.body());
-		//
-		// example:
-		//		Create a `dojo.NodeList()` from a new element (for syntatic sugar):
-		//	|	dojo.query(dojo.create('div'))
-		//	|		.addClass("newDiv")
-		//	|		.onclick(function(e){ console.log('clicked', e.target) })
-		//	|		.place("#someNode"); // redundant, but cleaner.
-	};
-	=====*/
-
-	/*=====
-	dojo.empty = function(node){
-			// summary:
-			//		safely removes all children of the node.
-			// node: DOMNode|String
-			//		a reference to a DOM node or an id.
-			// example:
-			//		Destroy node's children byId:
-			//	|	dojo.empty("someId");
-			//
-			// example:
-			//		Destroy all nodes' children in a list by reference:
-			//	|	dojo.query(".someNode").forEach(dojo.empty);
-	}
-	=====*/
-
-	/*=====
-	dojo.destroy = function(node){
-		// summary:
-		//		Removes a node from its parent, clobbering it and all of its
-		//		children.
-		//
-		// description:
-		//		Removes a node from its parent, clobbering it and all of its
-		//		children. Function only works with DomNodes, and returns nothing.
-		//
-		// node: DOMNode|String
-		//		A String ID or DomNode reference of the element to be destroyed
-		//
-		// example:
-		//		Destroy a node byId:
-		//	|	dojo.destroy("someId");
-		//
-		// example:
-		//		Destroy all nodes in a list by reference:
-		//	|	dojo.query(".someNode").forEach(dojo.destroy);
-	};
-	=====*/
-
-	/*=====
-	dojo._destroyElement = function(node){
-		// summary:
-		//		Existing alias for `dojo.destroy`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
+	// TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
 
-	// support stuff for dojo.toDom
+	// support stuff for toDom()
 	var tagWrap = {
 			option: ["select"],
 			tbody: ["table"],
@@ -227,14 +38,31 @@ define(["exports", "./_base/kernel", "./_base/sniff", "./_base/window", "./dom",
 		}
 	}
 
-	function _insertBefore(/*DomNode*/node, /*DomNode*/ref){
+	var html5domfix;
+	if(has("ie") <= 8){
+		html5domfix = function(doc){
+			doc.__dojo_html5_tested = "yes";
+			var div = create('div', {innerHTML: "<nav>a</nav>", style: {visibility: "hidden"}}, doc.body);
+			if(div.childNodes.length !== 1){
+				('abbr article aside audio canvas details figcaption figure footer header ' +
+				'hgroup mark meter nav output progress section summary time video').replace(
+					/\b\w+\b/g, function(n){
+						doc.createElement(n);
+					}
+				);
+			}
+			destroy(div);
+		}
+	}
+
+	function _insertBefore(/*DomNode*/ node, /*DomNode*/ ref){
 		var parent = ref.parentNode;
 		if(parent){
 			parent.insertBefore(node, ref);
 		}
 	}
 
-	function _insertAfter(/*DomNode*/node, /*DomNode*/ref){
+	function _insertAfter(/*DomNode*/ node, /*DomNode*/ ref){
 		// summary:
 		//		Try to insert node after ref
 		var parent = ref.parentNode;
@@ -247,15 +75,20 @@ define(["exports", "./_base/kernel", "./_base/sniff", "./_base/window", "./dom",
 		}
 	}
 
-	var _destroyContainer = null,
-		_destroyDoc;
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	on(window, "unload", function(){
-		_destroyContainer = null; //prevent IE leak
-	});
-	//>>excludeEnd("webkitMobile");
-
 	exports.toDom = function toDom(frag, doc){
+		// summary:
+		//		instantiates an HTML fragment returning the corresponding DOM.
+		// frag: String
+		//		the HTML fragment
+		// doc: DocumentNode?
+		//		optional document to use when creating DOM nodes, defaults to
+		//		dojo.doc if not specified.
+		// returns:
+		//		Document fragment, unless it's a single node in which case it returns the node itself
+		// example:
+		//		Create a table row:
+		//	|	var tr = dojo.toDom("<tr><td>First!</td></tr>");
+
 		doc = doc || win.doc;
 		var masterId = doc[masterName];
 		if(!masterId){
@@ -263,6 +96,12 @@ define(["exports", "./_base/kernel", "./_base/sniff", "./_base/window", "./dom",
 			masterNode[masterId] = doc.createElement("div");
 		}
 
+		if(has("ie") <= 8){
+			if(!doc.__dojo_html5_tested && doc.body){
+				html5domfix(doc);
+			}
+		}
+
 		// make sure the frag is a string.
 		frag += "";
 
@@ -288,13 +127,51 @@ define(["exports", "./_base/kernel", "./_base/sniff", "./_base/window", "./dom",
 
 		// return multiple nodes as a document fragment
 		df = doc.createDocumentFragment();
-		while(fc = master.firstChild){ // intentional assignment
+		while((fc = master.firstChild)){ // intentional assignment
 			df.appendChild(fc);
 		}
-		return df; // DOMNode
+		return df; // DocumentFragment
 	};
 
-	exports.place = function place(/*DOMNode|String*/node, /*DOMNode|String*/refNode, /*String|Number?*/position){
+	exports.place = function place(/*DOMNode|String*/ node, /*DOMNode|String*/ refNode, /*String|Number?*/ position){
+		// summary:
+		//		Attempt to insert node into the DOM, choosing from various positioning options.
+		//		Returns the first argument resolved to a DOM node.
+		// node: DOMNode|String
+		//		id or node reference, or HTML fragment starting with "<" to place relative to refNode
+		// refNode: DOMNode|String
+		//		id or node reference to use as basis for placement
+		// position: String|Number?
+		//		string noting the position of node relative to refNode or a
+		//		number indicating the location in the childNodes collection of refNode.
+		//		Accepted string values are:
+		//
+		//		- before
+		//		- after
+		//		- replace
+		//		- only
+		//		- first
+		//		- last
+		//
+		//		"first" and "last" indicate positions as children of refNode, "replace" replaces refNode,
+		//		"only" replaces all children.  position defaults to "last" if not specified
+		// returns: DOMNode
+		//		Returned values is the first argument resolved to a DOM node.
+		//
+		//		.place() is also a method of `dojo/NodeList`, allowing `dojo.query` node lookups.
+		// example:
+		//		Place a node by string id as the last child of another node by string id:
+		//	|	dojo.place("someNode", "anotherNode");
+		// example:
+		//		Place a node by string id before another node by string id
+		//	|	dojo.place("someNode", "anotherNode", "before");
+		// example:
+		//		Create a Node, and place it in the body element (last child):
+		//	|	dojo.place("<div></div>", dojo.body());
+		// example:
+		//		Put a new LI as the first child of a list by id:
+		//	|	dojo.place("<li></li>", "someUl", "first");
+
 		refNode = dom.byId(refNode);
 		if(typeof node == "string"){ // inline'd type check
 			node = /^\s*</.test(node) ? exports.toDom(node, refNode.ownerDocument) : dom.byId(node);
@@ -334,7 +211,68 @@ define(["exports", "./_base/kernel", "./_base/sniff", "./_base/window", "./dom",
 		return node; // DomNode
 	};
 
-	exports.create = function create(/*DOMNode|String*/tag, /*Object*/attrs, /*DOMNode?|String?*/refNode, /*String?*/pos){
+	var create = exports.create = function create(/*DOMNode|String*/ tag, /*Object*/ attrs, /*DOMNode|String?*/ refNode, /*String?*/ pos){
+		// summary:
+		//		Create an element, allowing for optional attribute decoration
+		//		and placement.
+		// description:
+		//		A DOM Element creation function. A shorthand method for creating a node or
+		//		a fragment, and allowing for a convenient optional attribute setting step,
+		//		as well as an optional DOM placement reference.
+		//
+		//		Attributes are set by passing the optional object through `dojo.setAttr`.
+		//		See `dojo.setAttr` for noted caveats and nuances, and API if applicable.
+		//
+		//		Placement is done via `dojo.place`, assuming the new node to be the action
+		//		node, passing along the optional reference node and position.
+		// tag: DOMNode|String
+		//		A string of the element to create (eg: "div", "a", "p", "li", "script", "br"),
+		//		or an existing DOM node to process.
+		// attrs: Object
+		//		An object-hash of attributes to set on the newly created node.
+		//		Can be null, if you don't want to set any attributes/styles.
+		//		See: `dojo.setAttr` for a description of available attributes.
+		// refNode: DOMNode|String?
+		//		Optional reference node. Used by `dojo.place` to place the newly created
+		//		node somewhere in the dom relative to refNode. Can be a DomNode reference
+		//		or String ID of a node.
+		// pos: String?
+		//		Optional positional reference. Defaults to "last" by way of `dojo.place`,
+		//		though can be set to "first","after","before","last", "replace" or "only"
+		//		to further control the placement of the new node relative to the refNode.
+		//		'refNode' is required if a 'pos' is specified.
+		// example:
+		//		Create a DIV:
+		//	|	var n = dojo.create("div");
+		//
+		// example:
+		//		Create a DIV with content:
+		//	|	var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
+		//
+		// example:
+		//		Place a new DIV in the BODY, with no attributes set
+		//	|	var n = dojo.create("div", null, dojo.body());
+		//
+		// example:
+		//		Create an UL, and populate it with LI's. Place the list as the first-child of a
+		//		node with id="someId":
+		//	|	var ul = dojo.create("ul", null, "someId", "first");
+		//	|	var items = ["one", "two", "three", "four"];
+		//	|	dojo.forEach(items, function(data){
+		//	|		dojo.create("li", { innerHTML: data }, ul);
+		//	|	});
+		//
+		// example:
+		//		Create an anchor, with an href. Place in BODY:
+		//	|	dojo.create("a", { href:"foo.html", title:"Goto FOO!" }, dojo.body());
+		//
+		// example:
+		//		Create a `dojo/NodeList()` from a new element (for syntactic sugar):
+		//	|	dojo.query(dojo.create('div'))
+		//	|		.addClass("newDiv")
+		//	|		.onclick(function(e){ console.log('clicked', e.target) })
+		//	|		.place("#someNode"); // redundant, but cleaner.
+
 		var doc = win.doc;
 		if(refNode){
 			refNode = dom.byId(refNode);
@@ -348,33 +286,75 @@ define(["exports", "./_base/kernel", "./_base/sniff", "./_base/window", "./dom",
 		return tag; // DomNode
 	};
 
-	exports.empty =
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		has("ie") ? function(node){
-			node = dom.byId(node);
-			for(var c; c = node.lastChild;){ // intentional assignment
-				exports.destroy(c);
+	function _empty(/*DomNode*/ node){
+		if(node.canHaveChildren){
+			try{
+				// fast path
+				node.innerHTML = "";
+				return;
+			}catch(e){
+				// innerHTML is readOnly (e.g. TABLE (sub)elements in quirks mode)
+				// Fall through (saves bytes)
 			}
-		} :
-		//>>excludeEnd("webkitMobile");
-		function(node){
-			dom.byId(node).innerHTML = "";
-		};
+		}
+		// SVG/strict elements don't support innerHTML/canHaveChildren, and OBJECT/APPLET elements in quirks node have canHaveChildren=false
+		for(var c; c = node.lastChild;){ // intentional assignment
+			_destroy(c, node); // destroy is better than removeChild so TABLE subelements are removed in proper order
+		}
+	}
 
-	exports.destroy = function destroy(/*DOMNode|String*/node){
-		node = dom.byId(node);
-		try{
-			var doc = node.ownerDocument;
-			// cannot use _destroyContainer.ownerDocument since this can throw an exception on IE
-			if(!_destroyContainer || _destroyDoc != doc){
-				_destroyContainer = doc.createElement("div");
-				_destroyDoc = doc;
-			}
-			_destroyContainer.appendChild(node.parentNode ? node.parentNode.removeChild(node) : node);
-			// NOTE: see http://trac.dojotoolkit.org/ticket/2931. This may be a bug and not a feature
-			_destroyContainer.innerHTML = "";
-		}catch(e){
-			/* squelch */
+	exports.empty = function empty(/*DOMNode|String*/ node){
+		 // summary:
+		 //		safely removes all children of the node.
+		 // node: DOMNode|String
+		 //		a reference to a DOM node or an id.
+		 // example:
+		 //		Destroy node's children byId:
+		 //	|	dojo.empty("someId");
+		 //
+		 // example:
+		 //		Destroy all nodes' children in a list by reference:
+		 //	|	dojo.query(".someNode").forEach(dojo.empty);
+
+		_empty(dom.byId(node));
+	};
+
+
+	function _destroy(/*DomNode*/ node, /*DomNode*/ parent){
+		// in IE quirks, node.canHaveChildren can be false but firstChild can be non-null (OBJECT/APPLET)
+		if(node.firstChild){
+			_empty(node);
+		}
+		if(parent){
+			// removeNode(false) doesn't leak in IE 6+, but removeChild() and removeNode(true) are known to leak under IE 8- while 9+ is TBD.
+			// In IE quirks mode, PARAM nodes as children of OBJECT/APPLET nodes have a removeNode method that does nothing and
+			// the parent node has canHaveChildren=false even though removeChild correctly removes the PARAM children.
+			// In IE, SVG/strict nodes don't have a removeNode method nor a canHaveChildren boolean.
+			has("ie") && parent.canHaveChildren && "removeNode" in node ? node.removeNode(false) : parent.removeChild(node);
 		}
+	}
+	var destroy = exports.destroy = function destroy(/*DOMNode|String*/ node){
+		// summary:
+		//		Removes a node from its parent, clobbering it and all of its
+		//		children.
+		//
+		// description:
+		//		Removes a node from its parent, clobbering it and all of its
+		//		children. Function only works with DomNodes, and returns nothing.
+		//
+		// node: DOMNode|String
+		//		A String ID or DomNode reference of the element to be destroyed
+		//
+		// example:
+		//		Destroy a node byId:
+		//	|	dojo.destroy("someId");
+		//
+		// example:
+		//		Destroy all nodes in a list by reference:
+		//	|	dojo.query(".someNode").forEach(dojo.destroy);
+
+		node = dom.byId(node);
+		if(!node){ return; }
+		_destroy(node, node.parentNode);
 	};
 });
diff --git a/dojo/dom-form.js b/dojo/dom-form.js
index 68cf78b..22458c4 100644
--- a/dojo/dom-form.js
+++ b/dojo/dom-form.js
@@ -1,83 +1,8 @@
 define(["./_base/lang", "./dom", "./io-query", "./json"], function(lang, dom, ioq, json){
 	// module:
 	//		dojo/dom-form
-	// summary:
-	//		This module defines form-processing functions.
 
-	/*=====
-	dojo.fieldToObject = function(inputNode){
-		// summary:
-		//		Serialize a form field to a JavaScript object.
-		// description:
-		//		Returns the value encoded in a form field as
-		//		as a string or an array of strings. Disabled form elements
-		//		and unchecked radio and checkboxes are skipped.	Multi-select
-		//		elements are returned as an array of string values.
-		// inputNode: DOMNode|String
-		// returns: Object
-	};
-	=====*/
-
-	/*=====
-    dojo.formToObject = function(formNode){
-        // summary:
-        //		Serialize a form node to a JavaScript object.
-        // description:
-        //		Returns the values encoded in an HTML form as
-        //		string properties in an object which it then returns. Disabled form
-        //		elements, buttons, and other non-value form elements are skipped.
-        //		Multi-select elements are returned as an array of string values.
-		// formNode: DOMNode|String
-		// returns: Object
-        //
-        // example:
-        //		This form:
-        //		|	<form id="test_form">
-        //		|		<input type="text" name="blah" value="blah">
-        //		|		<input type="text" name="no_value" value="blah" disabled>
-        //		|		<input type="button" name="no_value2" value="blah">
-        //		|		<select type="select" multiple name="multi" size="5">
-        //		|			<option value="blah">blah</option>
-        //		|			<option value="thud" selected>thud</option>
-        //		|			<option value="thonk" selected>thonk</option>
-        //		|		</select>
-        //		|	</form>
-        //
-        //		yields this object structure as the result of a call to
-        //		formToObject():
-        //
-        //		|	{
-        //		|		blah: "blah",
-        //		|		multi: [
-        //		|			"thud",
-        //		|			"thonk"
-        //		|		]
-        //		|	};
-    };
-	=====*/
-
-	/*=====
-    dojo.formToQuery = function(formNode){
-        // summary:
-        //		Returns a URL-encoded string representing the form passed as either a
-        //		node or string ID identifying the form to serialize
-		// formNode: DOMNode|String
-		// returns: String
-    };
-	=====*/
-
-	/*=====
-    dojo.formToJson = function(formNode, prettyPrint){
-        // summary:
-        //		Create a serialized JSON string from a form node or string
-        //		ID identifying the form to serialize
-		// formNode: DOMNode|String
-		// prettyPrint: Boolean?
-		// returns: String
-    };
-	=====*/
-
-    function setValue(/*Object*/obj, /*String*/name, /*String*/value){
+    function setValue(/*Object*/ obj, /*String*/ name, /*String*/ value){
         // summary:
         //		For the named property in object, set the value. If a value
         //		already exists and it is a string, convert the value to be an
@@ -101,7 +26,20 @@ define(["./_base/lang", "./dom", "./io-query", "./json"], function(lang, dom, io
 	var exclude = "file|submit|image|reset|button";
 
 	var form = {
+		// summary:
+		//		This module defines form-processing functions.
+
 		fieldToObject: function fieldToObject(/*DOMNode|String*/ inputNode){
+			// summary:
+			//		Serialize a form field to a JavaScript object.
+			// description:
+			//		Returns the value encoded in a form field as
+			//		as a string or an array of strings. Disabled form elements
+			//		and unchecked radio and checkboxes are skipped.	Multi-select
+			//		elements are returned as an array of string values.
+			// inputNode: DOMNode|String
+			// returns: Object
+
 			var ret = null;
 			inputNode = dom.byId(inputNode);
 			if(inputNode){
@@ -140,6 +78,38 @@ define(["./_base/lang", "./dom", "./io-query", "./json"], function(lang, dom, io
 		},
 
 		toObject: function formToObject(/*DOMNode|String*/ formNode){
+			// summary:
+			//		Serialize a form node to a JavaScript object.
+			// description:
+			//		Returns the values encoded in an HTML form as
+			//		string properties in an object which it then returns. Disabled form
+			//		elements, buttons, and other non-value form elements are skipped.
+			//		Multi-select elements are returned as an array of string values.
+			// formNode: DOMNode|String
+			// example:
+			//		This form:
+			//		|	<form id="test_form">
+			//		|		<input type="text" name="blah" value="blah">
+			//		|		<input type="text" name="no_value" value="blah" disabled>
+			//		|		<input type="button" name="no_value2" value="blah">
+			//		|		<select type="select" multiple name="multi" size="5">
+			//		|			<option value="blah">blah</option>
+			//		|			<option value="thud" selected>thud</option>
+			//		|			<option value="thonk" selected>thonk</option>
+			//		|		</select>
+			//		|	</form>
+			//
+			//		yields this object structure as the result of a call to
+			//		formToObject():
+			//
+			//		|	{
+			//		|		blah: "blah",
+			//		|		multi: [
+			//		|			"thud",
+			//		|			"thonk"
+			//		|		]
+			//		|	};
+
 			var ret = {}, elems = dom.byId(formNode).elements;
 			for(var i = 0, l = elems.length; i < l; ++i){
 				var item = elems[i], _in = item.name, type = (item.type || "").toLowerCase();
@@ -154,10 +124,23 @@ define(["./_base/lang", "./dom", "./io-query", "./json"], function(lang, dom, io
 		},
 
 		toQuery: function formToQuery(/*DOMNode|String*/ formNode){
+			// summary:
+			//		Returns a URL-encoded string representing the form passed as either a
+			//		node or string ID identifying the form to serialize
+			// formNode: DOMNode|String
+			// returns: String
+
 			return ioq.objectToQuery(form.toObject(formNode)); // String
 		},
 
-		toJson: function formToJson(/*DOMNode|String*/ formNode, /*Boolean?*/prettyPrint){
+		toJson: function formToJson(/*DOMNode|String*/ formNode, /*Boolean?*/ prettyPrint){
+			// summary:
+			//		Create a serialized JSON string from a form node or string
+			//		ID identifying the form to serialize
+			// formNode: DOMNode|String
+			// prettyPrint: Boolean?
+			// returns: String
+
 			return json.stringify(form.toObject(formNode), null, prettyPrint ? 4 : 0); // String
 		}
 	};
diff --git a/dojo/dom-geometry.js b/dojo/dom-geometry.js
index f553ec0..4943dac 100644
--- a/dojo/dom-geometry.js
+++ b/dojo/dom-geometry.js
@@ -1,11 +1,13 @@
-define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
+define(["./sniff", "./_base/window","./dom", "./dom-style"],
 		function(has, win, dom, style){
 	// module:
 	//		dojo/dom-geometry
-	// summary:
-	//		This module defines the core dojo DOM geometry API.
 
-	var geom = {};  // the result object
+	// the result object
+	var geom = {
+		// summary:
+		//		This module defines the core dojo DOM geometry API.
+	};
 
 	// Box functions will assume this model.
 	// On IE/Opera, BORDER_BOX will be set if the primary document is in quirks mode.
@@ -25,19 +27,12 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 	// IIRC, earlier versions of Opera did in fact use border-box.
 	// Opera guys, this is really confusing. Opera being broken in quirks mode is not our fault.
 
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 	if(has("ie") /*|| has("opera")*/){
 		// client code may have to adjust if compatMode varies across iframes
 		geom.boxModel = document.compatMode == "BackCompat" ? "border-box" : "content-box";
 	}
-	//>>excludeEnd("webkitMobile");
-
-	// =============================
-	// Box Functions
-	// =============================
 
-	/*=====
-	dojo.getPadExtents = function(node, computedStyle){
+	geom.getPadExtents = function getPadExtents(/*DomNode*/ node, /*Object*/ computedStyle){
 		// summary:
 		//		Returns object with special values specifically useful for node
 		//		fitting.
@@ -52,348 +47,72 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 		//		directly, and will use the ...box... functions instead.
 		// node: DOMNode
 		// computedStyle: Object?
-		// 		This parameter accepts computed styles object.
-		// 		If this parameter is omitted, the functions will call 
-		//		dojo.getComputedStyle to get one. It is a better way, calling 
-		//		dojo.computedStyle once, and then pass the reference to this 
-		//		computedStyle parameter. Wherever possible, reuse the returned 
-		//		object of dojo.getComputedStyle.
-
+		//		This parameter accepts computed styles object.
+		//		If this parameter is omitted, the functions will call
+		//		dojo.getComputedStyle to get one. It is a better way, calling
+		//		dojo.computedStyle once, and then pass the reference to this
+		//		computedStyle parameter. Wherever possible, reuse the returned
+		//		object of dojo/dom-style.getComputedStyle().
 
+		node = dom.byId(node);
+		var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue,
+			l = px(node, s.paddingLeft), t = px(node, s.paddingTop), r = px(node, s.paddingRight), b = px(node, s.paddingBottom);
+		return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
 	};
-	=====*/
 
-	/*=====
-	dojo._getPadExtents = function(node, computedStyle){
-		// summary:
-		//		Existing alias for `dojo.getPadExtents`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
+	var none = "none";
 
-	/*=====
-	dojo.getBorderExtents = function(node, computedStyle){
+	geom.getBorderExtents = function getBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){
 		// summary:
 		//		returns an object with properties useful for noting the border
 		//		dimensions.
 		// description:
-		//		* l/t/r/b = the sum of left/top/right/bottom border (respectively)
-		//		* w = the sum of the left and right border
-		//		* h = the sum of the top and bottom border
+		//		- l/t/r/b = the sum of left/top/right/bottom border (respectively)
+		//		- w = the sum of the left and right border
+		//		- h = the sum of the top and bottom border
 		//
 		//		The w/h are used for calculating boxes.
 		//		Normally application code will not need to invoke this
 		//		directly, and will use the ...box... functions instead.
 		// node: DOMNode
 		// computedStyle: Object?
-		// 		This parameter accepts computed styles object.
-		// 		If this parameter is omitted, the functions will call 
-		//		dojo.getComputedStyle to get one. It is a better way, calling 
-		//		dojo.computedStyle once, and then pass the reference to this 
-		//		computedStyle parameter. Wherever possible, reuse the returned 
-		//		object of dojo.getComputedStyle.
-
-
-	};
-	=====*/
+		//		This parameter accepts computed styles object.
+		//		If this parameter is omitted, the functions will call
+		//		dojo.getComputedStyle to get one. It is a better way, calling
+		//		dojo.computedStyle once, and then pass the reference to this
+		//		computedStyle parameter. Wherever possible, reuse the returned
+		//		object of dojo/dom-style.getComputedStyle().
 
-	/*=====
-	dojo._getBorderExtents = function(node, computedStyle){
-		// summary:
-		//		Existing alias for `dojo.getBorderExtents`. Deprecated, will be removed in 2.0.
+		node = dom.byId(node);
+		var px = style.toPixelValue, s = computedStyle || style.getComputedStyle(node),
+			l = s.borderLeftStyle != none ? px(node, s.borderLeftWidth) : 0,
+			t = s.borderTopStyle != none ? px(node, s.borderTopWidth) : 0,
+			r = s.borderRightStyle != none ? px(node, s.borderRightWidth) : 0,
+			b = s.borderBottomStyle != none ? px(node, s.borderBottomWidth) : 0;
+		return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
 	};
-	=====*/
 
-	/*=====
-	dojo.getPadBorderExtents = function(node, computedStyle){
+	geom.getPadBorderExtents = function getPadBorderExtents(/*DomNode*/ node, /*Object*/ computedStyle){
 		// summary:
 		//		Returns object with properties useful for box fitting with
 		//		regards to padding.
 		// description:
-		//		* l/t/r/b = the sum of left/top/right/bottom padding and left/top/right/bottom border (respectively)
-		//		* w = the sum of the left and right padding and border
-		//		* h = the sum of the top and bottom padding and border
+		//		- l/t/r/b = the sum of left/top/right/bottom padding and left/top/right/bottom border (respectively)
+		//		- w = the sum of the left and right padding and border
+		//		- h = the sum of the top and bottom padding and border
 		//
 		//		The w/h are used for calculating boxes.
 		//		Normally application code will not need to invoke this
 		//		directly, and will use the ...box... functions instead.
 		// node: DOMNode
 		// computedStyle: Object?
-		// 		This parameter accepts computed styles object.
-		// 		If this parameter is omitted, the functions will call 
-		//		dojo.getComputedStyle to get one. It is a better way, calling 
-		//		dojo.computedStyle once, and then pass the reference to this 
-		//		computedStyle parameter. Wherever possible, reuse the returned 
-		//		object of dojo.getComputedStyle.
-
-
-	};
-	=====*/
-
-	/*=====
-	dojo._getPadBorderExtents = function(node, computedStyle){
-		// summary:
-		//		Existing alias for `dojo.getPadBorderExtents`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
-
-	/*=====
-	dojo.getMarginExtents = function(node, computedStyle){
-		// summary:
-		//		returns object with properties useful for box fitting with
-		//		regards to box margins (i.e., the outer-box).
-		//
-		//		* l/t = marginLeft, marginTop, respectively
-		//		* w = total width, margin inclusive
-		//		* h = total height, margin inclusive
-		//
-		//		The w/h are used for calculating boxes.
-		//		Normally application code will not need to invoke this
-		//		directly, and will use the ...box... functions instead.
-		// node: DOMNode
-		// computedStyle: Object?
-		// 		This parameter accepts computed styles object.
-		// 		If this parameter is omitted, the functions will call 
-		//		dojo.getComputedStyle to get one. It is a better way, calling 
-		//		dojo.computedStyle once, and then pass the reference to this 
-		//		computedStyle parameter. Wherever possible, reuse the returned 
-		//		object of dojo.getComputedStyle.
-	};
-	=====*/
-
-	/*=====
-	dojo._getMarginExtents = function(node, computedStyle){
-		// summary:
-		//		Existing alias for `dojo.getMarginExtents`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
-
-	/*=====
-	dojo.getMarginSize = function(node, computedStyle){
-		// summary:
-		//		returns an object that encodes the width and height of
-		//		the node's margin box
-		// node: DOMNode|String
-		// computedStyle: Object?
-		// 		This parameter accepts computed styles object.
-		// 		If this parameter is omitted, the functions will call 
-		//		dojo.getComputedStyle to get one. It is a better way, calling 
-		//		dojo.computedStyle once, and then pass the reference to this 
-		//		computedStyle parameter. Wherever possible, reuse the returned 
-		//		object of dojo.getComputedStyle.
-	};
-	=====*/
-
-	/*=====
-	dojo._getMarginSize = function(node, computedStyle){
-		// summary:
-		//		Existing alias for `dojo.getMarginSize`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
-
-	/*=====
-	dojo.getMarginBox = function(node, computedStyle){
-		// summary:
-		//		returns an object that encodes the width, height, left and top
-		//		positions of the node's margin box.
-		// node: DOMNode
-		// computedStyle: Object?
-		// 		This parameter accepts computed styles object.
-		// 		If this parameter is omitted, the functions will call 
-		//		dojo.getComputedStyle to get one. It is a better way, calling 
-		//		dojo.computedStyle once, and then pass the reference to this 
-		//		computedStyle parameter. Wherever possible, reuse the returned 
-		//		object of dojo.getComputedStyle.
-	};
-	=====*/
-
-	/*=====
-	dojo._getMarginBox = function(node, computedStyle){
-		// summary:
-		//		Existing alias for `dojo.getMarginBox`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
-
-	/*=====
-	dojo.setMarginBox = function(node, box, computedStyle){
-		// summary:
-		//		sets the size of the node's margin box and placement
-		//		(left/top), irrespective of box model. Think of it as a
-		//		passthrough to setBox that handles box-model vagaries for
-		//		you.
-		// node: DOMNode
-		// box: Object
-		//      hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height"
-		//      respectively. All specified properties should have numeric values in whole pixels.
-		// computedStyle: Object?
-		// 		This parameter accepts computed styles object.
-		// 		If this parameter is omitted, the functions will call 
-		//		dojo.getComputedStyle to get one. It is a better way, calling 
-		//		dojo.computedStyle once, and then pass the reference to this 
-		//		computedStyle parameter. Wherever possible, reuse the returned 
-		//		object of dojo.getComputedStyle.
-	};
-	=====*/
-
-	/*=====
-	dojo.getContentBox = function(node, computedStyle){
-		// summary:
-		//		Returns an object that encodes the width, height, left and top
-		//		positions of the node's content box, irrespective of the
-		//		current box model.
-		// node: DOMNode
-		// computedStyle: Object?
-		// 		This parameter accepts computed styles object.
-		// 		If this parameter is omitted, the functions will call 
-		//		dojo.getComputedStyle to get one. It is a better way, calling 
-		//		dojo.computedStyle once, and then pass the reference to this 
-		//		computedStyle parameter. Wherever possible, reuse the returned 
-		//		object of dojo.getComputedStyle.
-	};
-	=====*/
-
-	/*=====
-	dojo._getContentBox = function(node, computedStyle){
-		// summary:
-		//		Existing alias for `dojo.getContentBox`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
-
-	/*=====
-	dojo.setContentSize = function(node, box, computedStyle){
-		// summary:
-		//		Sets the size of the node's contents, irrespective of margins,
-		//		padding, or borders.
-		// node: DOMNode
-		// box: Object
-		//      hash with optional "w", and "h" properties for "width", and "height"
-		//      respectively. All specified properties should have numeric values in whole pixels.
-		// computedStyle: Object?
-		// 		This parameter accepts computed styles object.
-		// 		If this parameter is omitted, the functions will call 
-		//		dojo.getComputedStyle to get one. It is a better way, calling 
-		//		dojo.computedStyle once, and then pass the reference to this 
-		//		computedStyle parameter. Wherever possible, reuse the returned 
-		//		object of dojo.getComputedStyle.
-	};
-	=====*/
-
-	/*=====
-	dojo.isBodyLtr = function(){
-		// summary:
-		//      Returns true if the current language is left-to-right, and false otherwise.
-		// returns: Boolean
-	};
-	=====*/
-
-	/*=====
-	dojo._isBodyLtr = function(){
-		// summary:
-		//		Existing alias for `dojo.isBodyLtr`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
-
-	/*=====
-	dojo.docScroll = function(){
-		// summary:
-		//      Returns an object with {node, x, y} with corresponding offsets.
-		// returns: Object
-	};
-	=====*/
-
-	/*=====
-	dojo._docScroll = function(){
-		// summary:
-		//		Existing alias for `dojo.docScroll`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
-
-	/*=====
-	dojo.getIeDocumentElementOffset = function(){
-		// summary:
-		//		returns the offset in x and y from the document body to the
-		//		visual edge of the page for IE
-		// description:
-		//		The following values in IE contain an offset:
-		//	|		event.clientX
-		//	|		event.clientY
-		//	|		node.getBoundingClientRect().left
-		//	|		node.getBoundingClientRect().top
-		//		But other position related values do not contain this offset,
-		//		such as node.offsetLeft, node.offsetTop, node.style.left and
-		//		node.style.top. The offset is always (2, 2) in LTR direction.
-		//		When the body is in RTL direction, the offset counts the width
-		//		of left scroll bar's width.  This function computes the actual
-		//		offset.
-	};
-	=====*/
-
-	/*=====
-	dojo._getIeDocumentElementOffset = function(){
-		// summary:
-		//		Existing alias for `dojo.getIeDocumentElementOffset`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
-
-	/*=====
-	dojo.fixIeBiDiScrollLeft = function(scrollLeft){
-		// summary:
-		//      In RTL direction, scrollLeft should be a negative value, but IE
-		//      returns a positive one. All codes using documentElement.scrollLeft
-		//      must call this function to fix this error, otherwise the position
-		//      will offset to right when there is a horizontal scrollbar.
-		// scrollLeft: NUmber
-		// returns: Number
-	};
-	=====*/
-
-	/*=====
-	dojo._fixIeBiDiScrollLeft = function(scrollLeft){
-		// summary:
-		//		Existing alias for `dojo.fixIeBiDiScrollLeft`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
-
-	/*=====
-	dojo.position = function(node, includeScroll){
-		// summary:
-		//		Gets the position and size of the passed element relative to
-		//		the viewport (if includeScroll==false), or relative to the
-		//		document root (if includeScroll==true).
-		//
-		// description:
-		//		Returns an object of the form:
-		//			{ x: 100, y: 300, w: 20, h: 15 }
-		//		If includeScroll==true, the x and y values will include any
-		//		document offsets that may affect the position relative to the
-		//		viewport.
-		//		Uses the border-box model (inclusive of border and padding but
-		//		not margin).  Does not act as a setter.
-		// node: DOMNode|String
-		// includeScroll: Boolean?
-		// returns: Object
-	};
-	=====*/
-
-	geom.getPadExtents = function getPadExtents(/*DomNode*/node, /*Object*/computedStyle){
-		node = dom.byId(node);
-		var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue,
-			l = px(node, s.paddingLeft), t = px(node, s.paddingTop), r = px(node, s.paddingRight), b = px(node, s.paddingBottom);
-		return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
-	};
-
-	var none = "none";
+		//		This parameter accepts computed styles object.
+		//		If this parameter is omitted, the functions will call
+		//		dojo.getComputedStyle to get one. It is a better way, calling
+		//		dojo.computedStyle once, and then pass the reference to this
+		//		computedStyle parameter. Wherever possible, reuse the returned
+		//		object of dojo/dom-style.getComputedStyle().
 
-	geom.getBorderExtents = function getBorderExtents(/*DomNode*/node, /*Object*/computedStyle){
-		node = dom.byId(node);
-		var px = style.toPixelValue, s = computedStyle || style.getComputedStyle(node),
-			l = s.borderLeftStyle != none ? px(node, s.borderLeftWidth) : 0,
-			t = s.borderTopStyle != none ? px(node, s.borderTopWidth) : 0,
-			r = s.borderRightStyle != none ? px(node, s.borderRightWidth) : 0,
-			b = s.borderBottomStyle != none ? px(node, s.borderBottomWidth) : 0;
-		return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
-	};
-
-	geom.getPadBorderExtents = function getPadBorderExtents(/*DomNode*/node, /*Object*/computedStyle){
 		node = dom.byId(node);
 		var s = computedStyle || style.getComputedStyle(node),
 			p = geom.getPadExtents(node, s),
@@ -409,18 +128,29 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 	};
 
 	geom.getMarginExtents = function getMarginExtents(node, computedStyle){
+		// summary:
+		//		returns object with properties useful for box fitting with
+		//		regards to box margins (i.e., the outer-box).
+		//
+		//		- l/t = marginLeft, marginTop, respectively
+		//		- w = total width, margin inclusive
+		//		- h = total height, margin inclusive
+		//
+		//		The w/h are used for calculating boxes.
+		//		Normally application code will not need to invoke this
+		//		directly, and will use the ...box... functions instead.
+		// node: DOMNode
+		// computedStyle: Object?
+		//		This parameter accepts computed styles object.
+		//		If this parameter is omitted, the functions will call
+		//		dojo.getComputedStyle to get one. It is a better way, calling
+		//		dojo.computedStyle once, and then pass the reference to this
+		//		computedStyle parameter. Wherever possible, reuse the returned
+		//		object of dojo/dom-style.getComputedStyle().
+
 		node = dom.byId(node);
 		var s = computedStyle || style.getComputedStyle(node), px = style.toPixelValue,
 			l = px(node, s.marginLeft), t = px(node, s.marginTop), r = px(node, s.marginRight), b = px(node, s.marginBottom);
-		if(has("webkit") && (s.position != "absolute")){
-			// FIXME: Safari's version of the computed right margin
-			// is the space between our right edge and the right edge
-			// of our offsetParent.
-			// What we are looking for is the actual margin value as
-			// determined by CSS.
-			// Hack solution is to assume left/right margins are the same.
-			r = l;
-		}
 		return {l: l, t: t, r: r, b: b, w: l + r, h: t + b};
 	};
 
@@ -439,14 +169,22 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 	// 2. factoring the shared code wastes cycles (function call overhead)
 	// 3. duplicating the shared code wastes bytes
 
-	geom.getMarginBox = function getMarginBox(/*DomNode*/node, /*Object*/computedStyle){
+	geom.getMarginBox = function getMarginBox(/*DomNode*/ node, /*Object*/ computedStyle){
 		// summary:
 		//		returns an object that encodes the width, height, left and top
 		//		positions of the node's margin box.
+		// node: DOMNode
+		// computedStyle: Object?
+		//		This parameter accepts computed styles object.
+		//		If this parameter is omitted, the functions will call
+		//		dojo.getComputedStyle to get one. It is a better way, calling
+		//		dojo.computedStyle once, and then pass the reference to this
+		//		computedStyle parameter. Wherever possible, reuse the returned
+		//		object of dojo/dom-style.getComputedStyle().
+
 		node = dom.byId(node);
 		var s = computedStyle || style.getComputedStyle(node), me = geom.getMarginExtents(node, s),
 			l = node.offsetLeft - me.l, t = node.offsetTop - me.t, p = node.parentNode, px = style.toPixelValue, pcs;
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 		if(has("mozilla")){
 			// Mozilla:
 			// If offsetParent has a computed overflow != visible, the offsetLeft is decreased
@@ -455,7 +193,8 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 			// computed left/top which is more stable.
 			var sl = parseFloat(s.left), st = parseFloat(s.top);
 			if(!isNaN(sl) && !isNaN(st)){
-				l = sl, t = st;
+				l = sl;
+				t = st;
 			}else{
 				// If child's computed left/top are not parseable as a number (e.g. "auto"), we
 				// have no choice but to examine the parent's computed style.
@@ -475,11 +214,23 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 				t -= pcs.borderTopStyle != none ? px(node, pcs.borderTopWidth) : 0;
 			}
 		}
-		//>>excludeEnd("webkitMobile");
 		return {l: l, t: t, w: node.offsetWidth + me.w, h: node.offsetHeight + me.h};
 	};
 
 	geom.getContentBox = function getContentBox(node, computedStyle){
+		// summary:
+		//		Returns an object that encodes the width, height, left and top
+		//		positions of the node's content box, irrespective of the
+		//		current box model.
+		// node: DOMNode
+		// computedStyle: Object?
+		//		This parameter accepts computed styles object.
+		//		If this parameter is omitted, the functions will call
+		//		dojo.getComputedStyle to get one. It is a better way, calling
+		//		dojo.computedStyle once, and then pass the reference to this
+		//		computedStyle parameter. Wherever possible, reuse the returned
+		//		object of dojo/dom-style.getComputedStyle().
+
 		// clientWidth/Height are important since the automatically account for scrollbars
 		// fallback to offsetWidth/Height for special cases (see #3378)
 		node = dom.byId(node);
@@ -493,20 +244,18 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 			be.w = be.h = 0;
 		}
 		// On Opera, offsetLeft includes the parent's border
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 		if(has("opera")){
 			pe.l += be.l;
 			pe.t += be.t;
 		}
-		//>>excludeEnd("webkitMobile");
 		return {l: pe.l, t: pe.t, w: w - pe.w - be.w, h: h - pe.h - be.h};
 	};
 
 	// Box setters depend on box context because interpretation of width/height styles
 	// vary wrt box context.
 	//
-	// The value of dojo.boxModel is used to determine box context.
-	// dojo.boxModel can be set directly to change behavior.
+	// The value of boxModel is used to determine box context.
+	// boxModel can be set directly to change behavior.
 	//
 	// Beware of display: inline objects that have padding styles
 	// because the user agent ignores padding (it's a bogus setup anyway)
@@ -519,7 +268,7 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 	// In particular, margins on TABLE do not seems to appear
 	// at all in computedStyle on Mozilla.
 
-	function setBox(/*DomNode*/node, /*Number?*/l, /*Number?*/t, /*Number?*/w, /*Number?*/h, /*String?*/u){
+	function setBox(/*DomNode*/ node, /*Number?*/ l, /*Number?*/ t, /*Number?*/ w, /*Number?*/ h, /*String?*/ u){
 		// summary:
 		//		sets width/height/left/top in the current (native) box-model
 		//		dimensions. Uses the unit passed in u.
@@ -552,14 +301,14 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 		}
 	}
 
-	function isButtonTag(/*DomNode*/node){
+	function isButtonTag(/*DomNode*/ node){
 		// summary:
 		//		True if the node is BUTTON or INPUT.type="button".
 		return node.tagName.toLowerCase() == "button" ||
 			node.tagName.toLowerCase() == "input" && (node.getAttribute("type") || "").toLowerCase() == "button"; // boolean
 	}
 
-	function usesBorderBox(/*DomNode*/node){
+	function usesBorderBox(/*DomNode*/ node){
 		// summary:
 		//		True if the node uses border-box layout.
 
@@ -573,10 +322,21 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 		return geom.boxModel == "border-box" || node.tagName.toLowerCase() == "table" || isButtonTag(node); // boolean
 	}
 
-	geom.setContentSize = function setContentSize(/*DomNode*/node, /*Object*/box, /*Object*/computedStyle){
+	geom.setContentSize = function setContentSize(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){
 		// summary:
 		//		Sets the size of the node's contents, irrespective of margins,
 		//		padding, or borders.
+		// node: DOMNode
+		// box: Object
+		//		hash with optional "w", and "h" properties for "width", and "height"
+		//		respectively. All specified properties should have numeric values in whole pixels.
+		// computedStyle: Object?
+		//		This parameter accepts computed styles object.
+		//		If this parameter is omitted, the functions will call
+		//		dojo.getComputedStyle to get one. It is a better way, calling
+		//		dojo.computedStyle once, and then pass the reference to this
+		//		computedStyle parameter. Wherever possible, reuse the returned
+		//		object of dojo/dom-style.getComputedStyle().
 
 		node = dom.byId(node);
 		var w = box.w, h = box.h;
@@ -594,12 +354,29 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 
 	var nilExtents = {l: 0, t: 0, w: 0, h: 0};
 
-	geom.setMarginBox = function setMarginBox(/*DomNode*/node, /*Object*/box, /*Object*/computedStyle){
+	geom.setMarginBox = function setMarginBox(/*DomNode*/ node, /*Object*/ box, /*Object*/ computedStyle){
+		// summary:
+		//		sets the size of the node's margin box and placement
+		//		(left/top), irrespective of box model. Think of it as a
+		//		passthrough to setBox that handles box-model vagaries for
+		//		you.
+		// node: DOMNode
+		// box: Object
+		//		hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height"
+		//		respectively. All specified properties should have numeric values in whole pixels.
+		// computedStyle: Object?
+		//		This parameter accepts computed styles object.
+		//		If this parameter is omitted, the functions will call
+		//		dojo.getComputedStyle to get one. It is a better way, calling
+		//		dojo.computedStyle once, and then pass the reference to this
+		//		computedStyle parameter. Wherever possible, reuse the returned
+		//		object of dojo/dom-style.getComputedStyle().
+
 		node = dom.byId(node);
 		var s = computedStyle || style.getComputedStyle(node), w = box.w, h = box.h,
 		// Some elements have special padding, margin, and box-model settings.
 		// To use box functions you may need to set padding, margin explicitly.
-		// Controlling box-model is harder, in a pinch you might set dojo.boxModel.
+		// Controlling box-model is harder, in a pinch you might set dojo/dom-geometry.boxModel.
 			pb = usesBorderBox(node) ? nilExtents : geom.getPadBorderExtents(node, s),
 			mb = geom.getMarginExtents(node, s);
 		if(has("webkit")){
@@ -629,90 +406,143 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 	// Positioning
 	// =============================
 
-	geom.isBodyLtr = function isBodyLtr(){
-		return (win.body().dir || win.doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean
-	};
+	geom.isBodyLtr = function isBodyLtr(/*Document?*/ doc){
+		// summary:
+		//		Returns true if the current language is left-to-right, and false otherwise.
+		// doc: Document?
+		//		Optional document to query.   If unspecified, use win.doc.
+		// returns: Boolean
 
-	geom.docScroll = function docScroll(){
-		var node = win.doc.parentWindow || win.doc.defaultView;   // use UI window, not dojo.global window
-		return "pageXOffset" in node ? {x: node.pageXOffset, y: node.pageYOffset } :
-			(node = has("quirks") ? win.body() : win.doc.documentElement,
-				{x: geom.fixIeBiDiScrollLeft(node.scrollLeft || 0), y: node.scrollTop || 0 });
+		doc = doc || win.doc;
+		return (win.body(doc).dir || doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean
 	};
 
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	geom.getIeDocumentElementOffset = function getIeDocumentElementOffset(){
-		//NOTE: assumes we're being called in an IE browser
-
-		var de = win.doc.documentElement; // only deal with HTML element here, position() handles body/quirks
+	geom.docScroll = function docScroll(/*Document?*/ doc){
+		// summary:
+		//		Returns an object with {node, x, y} with corresponding offsets.
+		// doc: Document?
+		//		Optional document to query.   If unspecified, use win.doc.
+		// returns: Object
 
-		if(has("ie") < 8){
-			var r = de.getBoundingClientRect(), // works well for IE6+
-				l = r.left, t = r.top;
-			if(has("ie") < 7){
-				l += de.clientLeft;	// scrollbar size in strict/RTL, or,
-				t += de.clientTop;	// HTML border size in strict
+		doc = doc || win.doc;
+		var node = win.doc.parentWindow || win.doc.defaultView;   // use UI window, not dojo.global window.   TODO: use dojo/window::get() except for circular dependency problem
+		return "pageXOffset" in node ? {x: node.pageXOffset, y: node.pageYOffset } :
+			(node = has("quirks") ? win.body(doc) : doc.documentElement) &&
+				{x: geom.fixIeBiDiScrollLeft(node.scrollLeft || 0, doc), y: node.scrollTop || 0 };
+	};
+
+	if(has("ie")){
+		geom.getIeDocumentElementOffset = function getIeDocumentElementOffset(/*Document?*/ doc){
+			// summary:
+			//		returns the offset in x and y from the document body to the
+			//		visual edge of the page for IE
+			// doc: Document?
+			//		Optional document to query.   If unspecified, use win.doc.
+			// description:
+			//		The following values in IE contain an offset:
+			//	|		event.clientX
+			//	|		event.clientY
+			//	|		node.getBoundingClientRect().left
+			//	|		node.getBoundingClientRect().top
+			//		But other position related values do not contain this offset,
+			//		such as node.offsetLeft, node.offsetTop, node.style.left and
+			//		node.style.top. The offset is always (2, 2) in LTR direction.
+			//		When the body is in RTL direction, the offset counts the width
+			//		of left scroll bar's width.  This function computes the actual
+			//		offset.
+
+			//NOTE: assumes we're being called in an IE browser
+
+			doc = doc || win.doc;
+			var de = doc.documentElement; // only deal with HTML element here, position() handles body/quirks
+
+			if(has("ie") < 8){
+				var r = de.getBoundingClientRect(), // works well for IE6+
+					l = r.left, t = r.top;
+				if(has("ie") < 7){
+					l += de.clientLeft;	// scrollbar size in strict/RTL, or,
+					t += de.clientTop;	// HTML border size in strict
+				}
+				return {
+					x: l < 0 ? 0 : l, // FRAME element border size can lead to inaccurate negative values
+					y: t < 0 ? 0 : t
+				};
+			}else{
+				return {
+					x: 0,
+					y: 0
+				};
 			}
-			return {
-				x: l < 0 ? 0 : l, // FRAME element border size can lead to inaccurate negative values
-				y: t < 0 ? 0 : t
-			};
-		}else{
-			return {
-				x: 0,
-				y: 0
-			};
-		}
-	};
-	//>>excludeEnd("webkitMobile");
+		};
+	}
+
+	geom.fixIeBiDiScrollLeft = function fixIeBiDiScrollLeft(/*Integer*/ scrollLeft, /*Document?*/ doc){
+		// summary:
+		//		In RTL direction, scrollLeft should be a negative value, but IE
+		//		returns a positive one. All codes using documentElement.scrollLeft
+		//		must call this function to fix this error, otherwise the position
+		//		will offset to right when there is a horizontal scrollbar.
+		// scrollLeft: Number
+		// doc: Document?
+		//		Optional document to query.   If unspecified, use win.doc.
+		// returns: Number
 
-	geom.fixIeBiDiScrollLeft = function fixIeBiDiScrollLeft(/*Integer*/ scrollLeft){
 		// In RTL direction, scrollLeft should be a negative value, but IE
 		// returns a positive one. All codes using documentElement.scrollLeft
 		// must call this function to fix this error, otherwise the position
 		// will offset to right when there is a horizontal scrollbar.
 
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
+		doc = doc || win.doc;
 		var ie = has("ie");
-		if(ie && !geom.isBodyLtr()){
+		if(ie && !geom.isBodyLtr(doc)){
 			var qk = has("quirks"),
-				de = qk ? win.body() : win.doc.documentElement;
-			if(ie == 6 && !qk && win.global.frameElement && de.scrollHeight > de.clientHeight){
+				de = qk ? win.body(doc) : doc.documentElement,
+				pwin = win.global;	// TODO: use winUtils.get(doc) after resolving circular dependency b/w dom-geometry.js and dojo/window.js
+			if(ie == 6 && !qk && pwin.frameElement && de.scrollHeight > de.clientHeight){
 				scrollLeft += de.clientLeft; // workaround ie6+strict+rtl+iframe+vertical-scrollbar bug where clientWidth is too small by clientLeft pixels
 			}
 			return (ie < 8 || qk) ? (scrollLeft + de.clientWidth - de.scrollWidth) : -scrollLeft; // Integer
 		}
-		//>>excludeEnd("webkitMobile");
 		return scrollLeft; // Integer
 	};
 
-	geom.position = function(/*DomNode*/node, /*Boolean?*/includeScroll){
+	geom.position = function(/*DomNode*/ node, /*Boolean?*/ includeScroll){
+		// summary:
+		//		Gets the position and size of the passed element relative to
+		//		the viewport (if includeScroll==false), or relative to the
+		//		document root (if includeScroll==true).
+		//
+		// description:
+		//		Returns an object of the form:
+		//		`{ x: 100, y: 300, w: 20, h: 15 }`.
+		//		If includeScroll==true, the x and y values will include any
+		//		document offsets that may affect the position relative to the
+		//		viewport.
+		//		Uses the border-box model (inclusive of border and padding but
+		//		not margin).  Does not act as a setter.
+		// node: DOMNode|String
+		// includeScroll: Boolean?
+		// returns: Object
+
 		node = dom.byId(node);
-		var	db = win.body(),
-			dh = db.parentNode,
+		var	db = win.body(node.ownerDocument),
 			ret = node.getBoundingClientRect();
 		ret = {x: ret.left, y: ret.top, w: ret.right - ret.left, h: ret.bottom - ret.top};
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		if(has("ie")){
-			// On IE there's a 2px offset that we need to adjust for, see dojo.getIeDocumentElementOffset()
-			var offset = geom.getIeDocumentElementOffset();
+
+		if(has("ie") < 9){
+			// On IE<9 there's a 2px offset that we need to adjust for, see dojo.getIeDocumentElementOffset()
+			var offset = geom.getIeDocumentElementOffset(node.ownerDocument);
 
 			// fixes the position in IE, quirks mode
 			ret.x -= offset.x + (has("quirks") ? db.clientLeft + db.offsetLeft : 0);
 			ret.y -= offset.y + (has("quirks") ? db.clientTop + db.offsetTop : 0);
-		}else if(has("ff") == 3){
-			// In FF3 you have to subtract the document element margins.
-			// Fixed in FF3.5 though.
-			var cs = style.getComputedStyle(dh), px = style.toPixelValue;
-			ret.x -= px(dh, cs.marginLeft) + px(dh, cs.borderLeftWidth);
-			ret.y -= px(dh, cs.marginTop) + px(dh, cs.borderTopWidth);
 		}
-		//>>excludeEnd("webkitMobile");
+
 		// account for document scrolling
 		// if offsetParent is used, ret value already includes scroll position
 		// so we may have to actually remove that value if !includeScroll
 		if(includeScroll){
-			var scroll = geom.docScroll();
+			var scroll = geom.docScroll(node.ownerDocument);
 			ret.x += scroll.x;
 			ret.y += scroll.y;
 		}
@@ -722,20 +552,32 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 
 	// random "private" functions wildly used throughout the toolkit
 
-	geom.getMarginSize = function getMarginSize(/*DomNode*/node, /*Object*/computedStyle){
+	geom.getMarginSize = function getMarginSize(/*DomNode*/ node, /*Object*/ computedStyle){
+		// summary:
+		//		returns an object that encodes the width and height of
+		//		the node's margin box
+		// node: DOMNode|String
+		// computedStyle: Object?
+		//		This parameter accepts computed styles object.
+		//		If this parameter is omitted, the functions will call
+		//		dojo.getComputedStyle to get one. It is a better way, calling
+		//		dojo.computedStyle once, and then pass the reference to this
+		//		computedStyle parameter. Wherever possible, reuse the returned
+		//		object of dojo/dom-style.getComputedStyle().
+
 		node = dom.byId(node);
 		var me = geom.getMarginExtents(node, computedStyle || style.getComputedStyle(node));
 		var size = node.getBoundingClientRect();
 		return {
 			w: (size.right - size.left) + me.w,
 			h: (size.bottom - size.top) + me.h
-		}
+		};
 	};
 
 	geom.normalizeEvent = function(event){
 		// summary:
-		// 		Normalizes the geometry of a DOM event, normalizing the pageX, pageY,
-		// 		offsetX, offsetY, layerX, and layerX properties
+		//		Normalizes the geometry of a DOM event, normalizing the pageX, pageY,
+		//		offsetX, offsetY, layerX, and layerX properties
 		// event: Object
 		if(!("layerX" in event)){
 			event.layerX = event.offsetX;
@@ -751,8 +593,8 @@ define(["./_base/sniff", "./_base/window","./dom", "./dom-style"],
 			// DO NOT replace the following to use dojo.body(), in IE, document.documentElement should be used
 			// here rather than document.body
 			var docBody = has("quirks") ? doc.body : doc.documentElement;
-			var offset = geom.getIeDocumentElementOffset();
-			event.pageX = event.clientX + geom.fixIeBiDiScrollLeft(docBody.scrollLeft || 0) - offset.x;
+			var offset = geom.getIeDocumentElementOffset(doc);
+			event.pageX = event.clientX + geom.fixIeBiDiScrollLeft(docBody.scrollLeft || 0, doc) - offset.x;
 			event.pageY = event.clientY + (docBody.scrollTop || 0) - offset.y;
 		}
 	};
diff --git a/dojo/dom-prop.js b/dojo/dom-prop.js
index cd932ae..ccc04c5 100644
--- a/dojo/dom-prop.js
+++ b/dojo/dom-prop.js
@@ -1,17 +1,33 @@
-define(["exports", "./_base/kernel", "./_base/sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"],
+define(["exports", "./_base/kernel", "./sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"],
 		function(exports, dojo, has, lang, dom, style, ctr, conn){
 	// module:
 	//		dojo/dom-prop
 	// summary:
 	//		This module defines the core dojo DOM properties API.
-	//      Indirectly depends on dojo.empty() and dojo.toDom().
+
+	// TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
 
 	// =============================
 	// Element properties Functions
 	// =============================
 
-	/*=====
-	prop.get = function(node, name){
+	// helper to connect events
+	var _evtHdlrMap = {}, _ctr = 0, _attrId = dojo._scopeName + "attrid";
+
+	exports.names = {
+		// properties renamed to avoid clashes with reserved words
+		"class": "className",
+		"for": "htmlFor",
+		// properties written as camelCase
+		tabindex: "tabIndex",
+		readonly: "readOnly",
+		colspan: "colSpan",
+		frameborder: "frameBorder",
+		rowspan: "rowSpan",
+		valuetype: "valueType"
+	};
+
+	exports.get = function getProp(/*DOMNode|String*/ node, /*String*/ name){
 		// summary:
 		//		Gets a property on an HTML element.
 		// description:
@@ -29,11 +45,13 @@ define(["exports", "./_base/kernel", "./_base/sniff", "./_base/lang", "./dom", "
 		//	|	dojo.getProp(dojo.byId("nodeId"), "foo");
 		//	|	// or we can just pass the id:
 		//	|	dojo.getProp("nodeId", "foo");
+
+		node = dom.byId(node);
+		var lc = name.toLowerCase(), propName = exports.names[lc] || name;
+		return node[propName];	// Anything
 	};
-	=====*/
 
-	/*=====
-	prop.set = function(node, name, value){
+	exports.set = function setProp(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
 		// summary:
 		//		Sets a property on an HTML element.
 		// description:
@@ -99,39 +117,7 @@ define(["exports", "./_base/kernel", "./_base/sniff", "./_base/lang", "./dom", "
 		//	|
 		//	|	// though shorter to use `dojo.style()` in this case:
 		//	|	dojo.style("someNode", obj);
-	};
-	=====*/
-
-	// helper to connect events
-	var _evtHdlrMap = {}, _ctr = 0, _attrId = dojo._scopeName + "attrid";
-
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	// the next dictionary lists elements with read-only innerHTML on IE
-	var _roInnerHtml = {col: 1, colgroup: 1,
-			// frameset: 1, head: 1, html: 1, style: 1,
-			table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1};
-	//>>excludeEnd("webkitMobile");
-
-	exports.names = {
-		// properties renamed to avoid clashes with reserved words
-		"class": "className",
-		"for": "htmlFor",
-		// properties written as camelCase
-		tabindex: "tabIndex",
-		readonly: "readOnly",
-		colspan: "colSpan",
-		frameborder: "frameBorder",
-		rowspan: "rowSpan",
-		valuetype: "valueType"
-	};
-
-	exports.get = function getProp(/*DOMNode|String*/node, /*String*/name){
-		node = dom.byId(node);
-		var lc = name.toLowerCase(), propName = exports.names[lc] || name;
-		return node[propName];	// Anything
-	};
 
-	exports.set = function setProp(/*DOMNode|String*/node, /*String|Object*/name, /*String?*/value){
 		node = dom.byId(node);
 		var l = arguments.length;
 		if(l == 2 && typeof name != "string"){ // inline'd type check
@@ -144,21 +130,19 @@ define(["exports", "./_base/kernel", "./_base/sniff", "./_base/lang", "./dom", "
 		var lc = name.toLowerCase(), propName = exports.names[lc] || name;
 		if(propName == "style" && typeof value != "string"){ // inline'd type check
 			// special case: setting a style
-			style.style(node, value);
+			style.set(node, value);
 			return node; // DomNode
 		}
 		if(propName == "innerHTML"){
 			// special case: assigning HTML
-			//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-			if(has("ie") && node.tagName.toLowerCase() in _roInnerHtml){
+			// the hash lists elements with read-only innerHTML on IE
+			if(has("ie") && node.tagName.toLowerCase() in {col: 1, colgroup: 1,
+						table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}){
 				ctr.empty(node);
 				node.appendChild(ctr.toDom(value, node.ownerDocument));
 			}else{
-			//>>excludeEnd("webkitMobile");
 				node[propName] = value;
-			//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 			}
-			//>>excludeEnd("webkitMobile");
 			return node; // DomNode
 		}
 		if(lang.isFunction(value)){
diff --git a/dojo/dom-style.js b/dojo/dom-style.js
index 3ceec84..042cfd6 100644
--- a/dojo/dom-style.js
+++ b/dojo/dom-style.js
@@ -1,8 +1,6 @@
-define(["./_base/sniff", "./dom"], function(has, dom){
+define(["./sniff", "./dom"], function(has, dom){
 	// module:
 	//		dojo/dom-style
-	// summary:
-	//		This module defines the core dojo DOM style API.
 
 	// =============================
 	// Style Functions
@@ -17,8 +15,43 @@ define(["./_base/sniff", "./dom"], function(has, dom){
 	// This way, calling code can access computedStyle once, and then pass the reference to
 	// multiple API functions.
 
+	// Although we normally eschew argument validation at this
+	// level, here we test argument 'node' for (duck)type,
+	// by testing nodeType, ecause 'document' is the 'parentNode' of 'body'
+	// it is frequently sent to this function even
+	// though it is not Element.
+	var getComputedStyle, style = {
+		// summary:
+		//		This module defines the core dojo DOM style API.
+	};
+	if(has("webkit")){
+		getComputedStyle = function(/*DomNode*/ node){
+			var s;
+			if(node.nodeType == 1){
+				var dv = node.ownerDocument.defaultView;
+				s = dv.getComputedStyle(node, null);
+				if(!s && node.style){
+					node.style.display = "";
+					s = dv.getComputedStyle(node, null);
+				}
+			}
+			return s || {};
+		};
+	}else if(has("ie") && (has("ie") < 9 || has("quirks"))){
+		getComputedStyle = function(node){
+			// IE (as of 7) doesn't expose Element like sane browsers
+			// currentStyle can be null on IE8!
+			return node.nodeType == 1 /* ELEMENT_NODE*/ && node.currentStyle ? node.currentStyle : {};
+		};
+	}else{
+		getComputedStyle = function(node){
+			return node.nodeType == 1 /* ELEMENT_NODE*/ ?
+				node.ownerDocument.defaultView.getComputedStyle(node, null) : {};
+		};
+	}
+	style.getComputedStyle = getComputedStyle;
 	/*=====
-	dojo.getComputedStyle = function(node){
+	style.getComputedStyle = function(node){
 		// summary:
 		//		Returns a "computed style" object.
 		//
@@ -47,148 +80,16 @@ define(["./_base/sniff", "./dom"], function(has, dom){
 		//	|	var cs = dojo.getComputedStyle(dojo.byId("someNode"));
 		//	|	var w = cs.width, h = cs.height;
 		return; // CSS2Properties
-	}
-	=====*/
-
-	/*=====
-	dojo.toPixelValue = function(node, value){
-		// summary:
-		//      converts style value to pixels on IE or return a numeric value.
-		// node: DOMNode
-		// value: String
-		// returns: Number
-	};
-	=====*/
-
-	/*=====
-	dojo._toPixelValue = function(node, value){
-		// summary:
-		//		Existing alias for `dojo._toPixelValue`. Deprecated, will be removed in 2.0.
-	};
-	=====*/
-
-	/*=====
-	dojo.getStyle = function(node, name){
-		// summary:
-		//		Accesses styles on a node.
-		// description:
-		//		Getting the style value uses the computed style for the node, so the value
-		//		will be a calculated value, not just the immediate node.style value.
-		//		Also when getting values, use specific style names,
-		//		like "borderBottomWidth" instead of "border" since compound values like
-		//		"border" are not necessarily reflected as expected.
-		//		If you want to get node dimensions, use `dojo.marginBox()`,
-		//		`dojo.contentBox()` or `dojo.position()`.
-		// node: DOMNode|String
-		//		id or reference to node to get style for
-		// name: String?
-		//		the style property to get
-		// example:
-		//		Passing only an ID or node returns the computed style object of
-		//		the node:
-		//	|	dojo.getStyle("thinger");
-		// example:
-		//		Passing a node and a style property returns the current
-		//		normalized, computed value for that property:
-		//	|	dojo.getStyle("thinger", "opacity"); // 1 by default
-	};
-	=====*/
-
-	/*=====
-	dojo.setStyle = function(node, name, value){
-		// summary:
-		//		Sets styles on a node.
-		// node: DOMNode|String
-		//		id or reference to node to set style for
-		// name: String|Object
-		//		the style property to set in DOM-accessor format
-		//		("borderWidth", not "border-width") or an object with key/value
-		//		pairs suitable for setting each property.
-		// value: String?
-		//		If passed, sets value on the node for style, handling
-		//		cross-browser concerns.  When setting a pixel value,
-		//		be sure to include "px" in the value. For instance, top: "200px".
-		//		Otherwise, in some cases, some browsers will not apply the style.
-		//
-		// example:
-		//		Passing a node, a style property, and a value changes the
-		//		current display of the node and returns the new computed value
-		//	|	dojo.setStyle("thinger", "opacity", 0.5); // == 0.5
-		//
-		// example:
-		//		Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
-		//	|	dojo.setStyle("thinger", {
-		//	|		"opacity": 0.5,
-		//	|		"border": "3px solid black",
-		//	|		"height": "300px"
-		//	|	});
-		//
-		// example:
-		//		When the CSS style property is hyphenated, the JavaScript property is camelCased.
-		//		font-size becomes fontSize, and so on.
-		//	|	dojo.setStyle("thinger",{
-		//	|		fontSize:"14pt",
-		//	|		letterSpacing:"1.2em"
-		//	|	});
-		//
-		// example:
-		//		dojo.NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
-		//		dojo.style() on every element of the list. See: `dojo.query()` and `dojo.NodeList()`
-		//	|	dojo.query(".someClassName").style("visibility","hidden");
-		//	|	// or
-		//	|	dojo.query("#baz > div").style({
-		//	|		opacity:0.75,
-		//	|		fontSize:"13pt"
-		//	|	});
 	};
 	=====*/
 
-	// Although we normally eschew argument validation at this
-	// level, here we test argument 'node' for (duck)type,
-	// by testing nodeType, ecause 'document' is the 'parentNode' of 'body'
-	// it is frequently sent to this function even
-	// though it is not Element.
-	var getComputedStyle, style = {};
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	if(has("webkit")){
-	//>>excludeEnd("webkitMobile");
-		getComputedStyle = function(/*DomNode*/node){
-			var s;
-			if(node.nodeType == 1){
-				var dv = node.ownerDocument.defaultView;
-				s = dv.getComputedStyle(node, null);
-				if(!s && node.style){
-					node.style.display = "";
-					s = dv.getComputedStyle(node, null);
-				}
-			}
-			return s || {};
-		};
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	}else if(has("ie") && (has("ie") < 9 || has("quirks"))){
-		getComputedStyle = function(node){
-			// IE (as of 7) doesn't expose Element like sane browsers
-			return node.nodeType == 1 /* ELEMENT_NODE*/ ? node.currentStyle : {};
-		};
-	}else{
-		getComputedStyle = function(node){
-			return node.nodeType == 1 ?
-				node.ownerDocument.defaultView.getComputedStyle(node, null) : {};
-		};
-	}
-	//>>excludeEnd("webkitMobile");
-	style.getComputedStyle = getComputedStyle;
-
 	var toPixel;
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 	if(!has("ie")){
-	//>>excludeEnd("webkitMobile");
 		toPixel = function(element, value){
 			// style values can be floats, client code may want
 			// to round for integer pixels.
 			return parseFloat(value) || 0;
 		};
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 	}else{
 		toPixel = function(element, avalue){
 			if(!avalue){ return 0; }
@@ -213,14 +114,21 @@ define(["./_base/sniff", "./dom"], function(has, dom){
 			s.left = sLeft;
 			rs.left = rsLeft;
 			return avalue;
-		}
+		};
 	}
-	//>>excludeEnd("webkitMobile");
 	style.toPixelValue = toPixel;
+	/*=====
+	style.toPixelValue = function(node, value){
+		// summary:
+		//		converts style value to pixels on IE or return a numeric value.
+		// node: DOMNode
+		// value: String
+		// returns: Number
+	};
+	=====*/
 
 	// FIXME: there opacity quirks on FF that we haven't ported over. Hrm.
 
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 	var astr = "DXImageTransform.Microsoft.Alpha";
 	var af = function(n, f){
 		try{
@@ -230,40 +138,43 @@ define(["./_base/sniff", "./dom"], function(has, dom){
 		}
 	};
 
-	//>>excludeEnd("webkitMobile");
 	var _getOpacity =
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		has("ie") < 9 || (has("ie") && has("quirks")) ? function(node){
+		has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(node){
 			try{
 				return af(node).Opacity / 100; // Number
 			}catch(e){
 				return 1; // Number
 			}
 		} :
-	//>>excludeEnd("webkitMobile");
 		function(node){
 			return getComputedStyle(node).opacity;
 		};
 
 	var _setOpacity =
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		has("ie") < 9 || (has("ie") && has("quirks")) ? function(/*DomNode*/node, /*Number*/opacity){
-			var ov = opacity * 100, opaque = opacity == 1;
-			node.style.zoom = opaque ? "" : 1;
+		has("ie") < 9 || (has("ie") < 10 && has("quirks")) ? function(/*DomNode*/ node, /*Number*/ opacity){
+			if(opacity === ""){ opacity = 1; }
+			var ov = opacity * 100, fullyOpaque = opacity === 1;
+
+			// on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661),
+			// but still update the opacity value so we can get a correct reading if it is read later:
+			// af(node, 1).Enabled = !fullyOpaque;
 
-			if(!af(node)){
-				if(opaque){
-					return opacity;
+			if(fullyOpaque){
+				node.style.zoom = "";
+				if(af(node)){
+					node.style.filter = node.style.filter.replace(
+						new RegExp("\\s*progid:" + astr + "\\([^\\)]+?\\)", "i"), "");
 				}
-				node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
 			}else{
-				af(node, 1).Opacity = ov;
+				node.style.zoom = 1;
+				if(af(node)){
+					af(node, 1).Opacity = ov;
+				}else{
+					node.style.filter += " progid:" + astr + "(Opacity=" + ov + ")";
+				}
+				af(node, 1).Enabled = true;
 			}
 
-			// on IE7 Alpha(Filter opacity=100) makes text look fuzzy so disable it altogether (bug #2661),
-			//but still update the opacity value so we can get a correct reading if it is read later.
-			af(node, 1).Enabled = !opaque;
-
 			if(node.tagName.toLowerCase() == "tr"){
 				for(var td = node.firstChild; td; td = td.nextSibling){
 					if(td.tagName.toLowerCase() == "td"){
@@ -273,7 +184,6 @@ define(["./_base/sniff", "./dom"], function(has, dom){
 			}
 			return opacity;
 		} :
-		//>>excludeEnd("webkitMobile");
 		function(node, opacity){
 			return node.style.opacity = opacity;
 		};
@@ -285,7 +195,6 @@ define(["./_base/sniff", "./dom"], function(has, dom){
 	function _toStyleValue(node, type, value){
 		//TODO: should we really be doing string case conversion here? Should we cache it? Need to profile!
 		type = type.toLowerCase();
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 		if(has("ie")){
 			if(value == "auto"){
 				if(type == "height"){ return node.offsetHeight; }
@@ -299,31 +208,97 @@ define(["./_base/sniff", "./dom"], function(has, dom){
 				}
 			}
 		}
-		//>>excludeEnd("webkitMobile");
 		if(!(type in _pixelNamesCache)){
 			_pixelNamesCache[type] = _pixelRegExp.test(type);
 		}
 		return _pixelNamesCache[type] ? toPixel(node, value) : value;
 	}
 
-	var _floatStyle = has("ie") ? "styleFloat" : "cssFloat",
-		_floatAliases = {"cssFloat": _floatStyle, "styleFloat": _floatStyle, "float": _floatStyle};
+	var _floatAliases = {cssFloat: 1, styleFloat: 1, "float": 1};
 
 	// public API
 
 	style.get = function getStyle(/*DOMNode|String*/ node, /*String?*/ name){
+		// summary:
+		//		Accesses styles on a node.
+		// description:
+		//		Getting the style value uses the computed style for the node, so the value
+		//		will be a calculated value, not just the immediate node.style value.
+		//		Also when getting values, use specific style names,
+		//		like "borderBottomWidth" instead of "border" since compound values like
+		//		"border" are not necessarily reflected as expected.
+		//		If you want to get node dimensions, use `dojo.marginBox()`,
+		//		`dojo.contentBox()` or `dojo.position()`.
+		// node: DOMNode|String
+		//		id or reference to node to get style for
+		// name: String?
+		//		the style property to get
+		// example:
+		//		Passing only an ID or node returns the computed style object of
+		//		the node:
+		//	|	dojo.getStyle("thinger");
+		// example:
+		//		Passing a node and a style property returns the current
+		//		normalized, computed value for that property:
+		//	|	dojo.getStyle("thinger", "opacity"); // 1 by default
+
 		var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
 		if(l == 2 && op){
 			return _getOpacity(n);
 		}
-		name = _floatAliases[name] || name;
+		name = _floatAliases[name] ? "cssFloat" in n.style ? "cssFloat" : "styleFloat" : name;
 		var s = style.getComputedStyle(n);
 		return (l == 1) ? s : _toStyleValue(n, name, s[name] || n.style[name]); /* CSS2Properties||String||Number */
 	};
 
 	style.set = function setStyle(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
+		// summary:
+		//		Sets styles on a node.
+		// node: DOMNode|String
+		//		id or reference to node to set style for
+		// name: String|Object
+		//		the style property to set in DOM-accessor format
+		//		("borderWidth", not "border-width") or an object with key/value
+		//		pairs suitable for setting each property.
+		// value: String?
+		//		If passed, sets value on the node for style, handling
+		//		cross-browser concerns.  When setting a pixel value,
+		//		be sure to include "px" in the value. For instance, top: "200px".
+		//		Otherwise, in some cases, some browsers will not apply the style.
+		//
+		// example:
+		//		Passing a node, a style property, and a value changes the
+		//		current display of the node and returns the new computed value
+		//	|	dojo.setStyle("thinger", "opacity", 0.5); // == 0.5
+		//
+		// example:
+		//		Passing a node, an object-style style property sets each of the values in turn and returns the computed style object of the node:
+		//	|	dojo.setStyle("thinger", {
+		//	|		"opacity": 0.5,
+		//	|		"border": "3px solid black",
+		//	|		"height": "300px"
+		//	|	});
+		//
+		// example:
+		//		When the CSS style property is hyphenated, the JavaScript property is camelCased.
+		//		font-size becomes fontSize, and so on.
+		//	|	dojo.setStyle("thinger",{
+		//	|		fontSize:"14pt",
+		//	|		letterSpacing:"1.2em"
+		//	|	});
+		//
+		// example:
+		//		dojo/NodeList implements .style() using the same syntax, omitting the "node" parameter, calling
+		//		dojo.style() on every element of the list. See: `dojo.query()` and `dojo/NodeList`
+		//	|	dojo.query(".someClassName").style("visibility","hidden");
+		//	|	// or
+		//	|	dojo.query("#baz > div").style({
+		//	|		opacity:0.75,
+		//	|		fontSize:"13pt"
+		//	|	});
+
 		var n = dom.byId(node), l = arguments.length, op = (name == "opacity");
-		name = _floatAliases[name] || name;
+		name = _floatAliases[name] ? "cssFloat" in n.style ? "cssFloat" : "styleFloat" : name;
 		if(l == 3){
 			return op ? _setOpacity(n, value) : n.style[name] = value; // Number
 		}
diff --git a/dojo/dom.js b/dojo/dom.js
index a6696a7..4c1ec89 100644
--- a/dojo/dom.js
+++ b/dojo/dom.js
@@ -1,93 +1,28 @@
-define(["./_base/sniff", "./_base/lang", "./_base/window"],
-		function(has, lang, win){
+define(["./sniff", "./_base/window"],
+		function(has, win){
 	// module:
 	//		dojo/dom
-	// summary:
-	//		This module defines the core dojo DOM API.
 
 	// FIXME: need to add unit tests for all the semi-public methods
 
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	try{
-		document.execCommand("BackgroundImageCache", false, true);
-	}catch(e){
-		// sane browsers don't have cache "issues"
+	if(has("ie") <= 7){
+		try{
+			document.execCommand("BackgroundImageCache", false, true);
+		}catch(e){
+			// sane browsers don't have cache "issues"
+		}
 	}
-	//>>excludeEnd("webkitMobile");
 
 	// =============================
 	// DOM Functions
 	// =============================
 
-	/*=====
-	dojo.byId = function(id, doc){
+	// the result object
+	var dom = {
 		// summary:
-		//		Returns DOM node with matching `id` attribute or `null`
-		//		if not found. If `id` is a DomNode, this function is a no-op.
-		//
-		// id: String|DOMNode
-		//	 	A string to match an HTML id attribute or a reference to a DOM Node
-		//
-		// doc: Document?
-		//		Document to work in. Defaults to the current value of
-		//		dojo.doc.  Can be used to retrieve
-		//		node references from other documents.
-		//
-		// example:
-		//		Look up a node by ID:
-		//	|	var n = dojo.byId("foo");
-		//
-		// example:
-		//		Check if a node exists, and use it.
-		//	|	var n = dojo.byId("bar");
-		//	|	if(n){ doStuff() ... }
-		//
-		// example:
-		//		Allow string or DomNode references to be passed to a custom function:
-		//	|	var foo = function(nodeOrId){
-		//	|		nodeOrId = dojo.byId(nodeOrId);
-		//	|		// ... more stuff
-		//	|	}
-	=====*/
-
-	/*=====
-	dojo.isDescendant = function(node, ancestor){
-		// summary:
-		//		Returns true if node is a descendant of ancestor
-		// node: DOMNode|String
-		//		string id or node reference to test
-		// ancestor: DOMNode|String
-		//		string id or node reference of potential parent to test against
-		//
-		// example:
-		//		Test is node id="bar" is a descendant of node id="foo"
-		//	|	if(dojo.isDescendant("bar", "foo")){ ... }
-	};
-	=====*/
-
-	// TODO: do we need this function in the base?
-
-	/*=====
-	dojo.setSelectable = function(node, selectable){
-		// summary:
-		//		Enable or disable selection on a node
-		// node: DOMNode|String
-		//		id or reference to node
-		// selectable: Boolean
-		//		state to put the node in. false indicates unselectable, true
-		//		allows selection.
-		// example:
-		//		Make the node id="bar" unselectable
-		//	|	dojo.setSelectable("bar");
-		// example:
-		//		Make the node id="bar" selectable
-		//	|	dojo.setSelectable("bar", true);
+		//		This module defines the core dojo DOM API.
 	};
-	=====*/
-
-	var dom = {};   // the result object
 
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 	if(has("ie")){
 		dom.byId = function(id, doc){
 			if(typeof id != "string"){
@@ -113,20 +48,56 @@ define(["./_base/sniff", "./_base/lang", "./_base/window"],
 			}
 		};
 	}else{
-	//>>excludeEnd("webkitMobile");
 		dom.byId = function(id, doc){
 			// inline'd type check.
 			// be sure to return null per documentation, to match IE branch.
 			return ((typeof id == "string") ? (doc || win.doc).getElementById(id) : id) || null; // DOMNode
 		};
-	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 	}
-	//>>excludeEnd("webkitMobile");
 	/*=====
-	};
-	=====*/
+	 dom.byId = function(id, doc){
+		 // summary:
+		 //		Returns DOM node with matching `id` attribute or falsy value (ex: null or undefined)
+		 //		if not found.  If `id` is a DomNode, this function is a no-op.
+		 //
+		 // id: String|DOMNode
+		 //		A string to match an HTML id attribute or a reference to a DOM Node
+		 //
+		 // doc: Document?
+		 //		Document to work in. Defaults to the current value of
+		 //		dojo.doc.  Can be used to retrieve
+		 //		node references from other documents.
+		 //
+		 // example:
+		 //		Look up a node by ID:
+		 //	|	var n = dojo.byId("foo");
+		 //
+		 // example:
+		 //		Check if a node exists, and use it.
+		 //	|	var n = dojo.byId("bar");
+		 //	|	if(n){ doStuff() ... }
+		 //
+		 // example:
+		 //		Allow string or DomNode references to be passed to a custom function:
+		 //	|	var foo = function(nodeOrId){
+		 //	|		nodeOrId = dojo.byId(nodeOrId);
+		 //	|		// ... more stuff
+		 //	|	}
+	 };
+	 =====*/
+
+	dom.isDescendant = function(/*DOMNode|String*/ node, /*DOMNode|String*/ ancestor){
+		// summary:
+		//		Returns true if node is a descendant of ancestor
+		// node: DOMNode|String
+		//		string id or node reference to test
+		// ancestor: DOMNode|String
+		//		string id or node reference of potential parent to test against
+		//
+		// example:
+		//		Test is node id="bar" is a descendant of node id="foo"
+		//	|	if(dojo.isDescendant("bar", "foo")){ ... }
 
-	dom.isDescendant = function(/*DOMNode|String*/node, /*DOMNode|String*/ancestor){
 		try{
 			node = dom.byId(node);
 			ancestor = dom.byId(ancestor);
@@ -140,26 +111,74 @@ define(["./_base/sniff", "./_base/lang", "./_base/window"],
 		return false; // Boolean
 	};
 
-	// TODO: do we need this function in the base?
 
-	dom.setSelectable = function(/*DOMNode|String*/node, /*Boolean*/selectable){
+	// TODO: do we need setSelectable in the base?
+
+	// Add feature test for user-select CSS property
+	// (currently known to work in all but IE < 10 and Opera)
+	has.add("css-user-select", function(global, doc, element){
+		// Avoid exception when dom.js is loaded in non-browser environments
+		if(!element){ return false; }
+		
+		var style = element.style;
+		var prefixes = ["Khtml", "O", "ms", "Moz", "Webkit"],
+			i = prefixes.length,
+			name = "userSelect",
+			prefix;
+
+		// Iterate prefixes from most to least likely
+		do{
+			if(typeof style[name] !== "undefined"){
+				// Supported; return property name
+				return name;
+			}
+		}while(i-- && (name = prefixes[i] + "UserSelect"));
+
+		// Not supported if we didn't return before now
+		return false;
+	});
+
+	/*=====
+	dom.setSelectable = function(node, selectable){
+		// summary:
+		//		Enable or disable selection on a node
+		// node: DOMNode|String
+		//		id or reference to node
+		// selectable: Boolean
+		//		state to put the node in. false indicates unselectable, true
+		//		allows selection.
+		// example:
+		//		Make the node id="bar" unselectable
+		//	|	dojo.setSelectable("bar");
+		// example:
+		//		Make the node id="bar" selectable
+		//	|	dojo.setSelectable("bar", true);
+	};
+	=====*/
+
+	var cssUserSelect = has("css-user-select");
+	dom.setSelectable = cssUserSelect ? function(node, selectable){
+		// css-user-select returns a (possibly vendor-prefixed) CSS property name
+		dom.byId(node).style[cssUserSelect] = selectable ? "" : "none";
+	} : function(node, selectable){
 		node = dom.byId(node);
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		if(has("mozilla")){
-			node.style.MozUserSelect = selectable ? "" : "none";
-		}else if(has("khtml") || has("webkit")){
-		//>>excludeEnd("webkitMobile");
-			node.style.KhtmlUserSelect = selectable ? "auto" : "none";
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		}else if(has("ie")){
-			var v = (node.unselectable = selectable ? "" : "on"),
-				cs = node.getElementsByTagName("*"), i = 0, l = cs.length;
-			for(; i < l; ++i){
-				cs.item(i).unselectable = v;
+
+		// (IE < 10 / Opera) Fall back to setting/removing the
+		// unselectable attribute on the element and all its children
+		var nodes = node.getElementsByTagName("*"),
+			i = nodes.length;
+
+		if(selectable){
+			node.removeAttribute("unselectable");
+			while(i--){
+				nodes[i].removeAttribute("unselectable");
+			}
+		}else{
+			node.setAttribute("unselectable", "on");
+			while(i--){
+				nodes[i].setAttribute("unselectable", "on");
 			}
 		}
-		//>>excludeEnd("webkitMobile");
-		//FIXME: else?  Opera?
 	};
 
 	return dom;
diff --git a/dojo/domReady.js b/dojo/domReady.js
index 64ea1c0..207359a 100644
--- a/dojo/domReady.js
+++ b/dojo/domReady.js
@@ -3,24 +3,64 @@ define(['./has'], function(has){
 		doc = document,
 		readyStates = { 'loaded': 1, 'complete': 1 },
 		fixReadyState = typeof doc.readyState != "string",
-		ready = !!readyStates[doc.readyState];
+		ready = !!readyStates[doc.readyState],
+		readyQ = [],
+		recursiveGuard;
+
+	function domReady(callback){
+		// summary:
+		//		Plugin to delay require()/define() callback from firing until the DOM has finished loading.
+		readyQ.push(callback);
+		if(ready){ processQ(); }
+	}
+	domReady.load = function(id, req, load){
+		domReady(load);
+	};
+
+	// Export queue so that ready() can check if it's empty or not.
+	domReady._Q = readyQ;
+	domReady._onQEmpty = function(){
+		// summary:
+		//		Private method overridden by dojo/ready, to notify when everything in the
+		//		domReady queue has been processed.  Do not use directly.
+		//		Will be removed in 2.0, along with domReady._Q.
+	};
 
 	// For FF <= 3.5
 	if(fixReadyState){ doc.readyState = "loading"; }
 
+	function processQ(){
+		// Calls all functions in the queue in order, unless processQ() is already running, in which case just return
+
+		if(recursiveGuard){ return; }
+		recursiveGuard = true;
+
+		while(readyQ.length){
+			try{
+				(readyQ.shift())(doc);
+			}catch(err){
+				console.log("Error on domReady callback: " + err);
+			}
+		}
+
+		recursiveGuard = false;
+
+		// Notification for dojo/ready.  Remove for 2.0.
+		// Note that this could add more tasks to the ready queue.
+		domReady._onQEmpty();
+	}
+
 	if(!ready){
-		var readyQ = [], tests = [],
+		var tests = [],
 			detectReady = function(evt){
 				evt = evt || global.event;
 				if(ready || (evt.type == "readystatechange" && !readyStates[doc.readyState])){ return; }
-				ready = 1;
 
 				// For FF <= 3.5
 				if(fixReadyState){ doc.readyState = "complete"; }
 
-				while(readyQ.length){
-					(readyQ.shift())();
-				}
+				ready = 1;
+				processQ();
 			},
 			on = function(node, event){
 				node.addEventListener(event, detectReady, false);
@@ -80,16 +120,5 @@ define(['./has'], function(has){
 		}
 	}
 
-	function domReady(callback){
-		if(ready){
-			callback(1);
-		}else{
-			readyQ.push(callback);
-		}
-	}
-	domReady.load = function(id, req, load){
-		domReady(load);
-	};
-
 	return domReady;
 });
diff --git a/dojo/errors/CancelError.js b/dojo/errors/CancelError.js
new file mode 100644
index 0000000..bcaf2d7
--- /dev/null
+++ b/dojo/errors/CancelError.js
@@ -0,0 +1,13 @@
+define(["./create"], function(create){
+	// module:
+	//		dojo/errors/CancelError
+
+	/*=====
+	return function(){
+		// summary:
+		//		Default error if a promise is canceled without a reason.
+	};
+	=====*/
+
+	return create("CancelError", null, null, { dojoType: "cancel" });
+});
diff --git a/dojo/errors/RequestError.js b/dojo/errors/RequestError.js
new file mode 100644
index 0000000..449d76b
--- /dev/null
+++ b/dojo/errors/RequestError.js
@@ -0,0 +1,15 @@
+define(['./create'], function(create){
+	// module:
+	//		dojo/errors/RequestError
+
+	/*=====
+	 return function(){
+		 // summary:
+		 //		TODOC
+	 };
+	 =====*/
+
+	return create("RequestError", function(message, response){
+		this.response = response;
+	});
+});
diff --git a/dojo/errors/RequestTimeoutError.js b/dojo/errors/RequestTimeoutError.js
new file mode 100644
index 0000000..07bcdb6
--- /dev/null
+++ b/dojo/errors/RequestTimeoutError.js
@@ -0,0 +1,15 @@
+define(['./create', './RequestError'], function(create, RequestError){
+	// module:
+	//		dojo/errors/RequestTimeoutError
+
+	/*=====
+	 return function(){
+		 // summary:
+		 //		TODOC
+	 };
+	 =====*/
+
+	return create("RequestTimeoutError", null, RequestError, {
+		dojoType: "timeout"
+	});
+});
diff --git a/dojo/errors/create.js b/dojo/errors/create.js
new file mode 100644
index 0000000..8acfb09
--- /dev/null
+++ b/dojo/errors/create.js
@@ -0,0 +1,41 @@
+define(["../_base/lang"], function(lang){
+	return function(name, ctor, base, props){
+		base = base || Error;
+
+		var ErrorCtor = function(message){
+			if(base === Error){
+				if(Error.captureStackTrace){
+					Error.captureStackTrace(this, ErrorCtor);
+				}
+
+				// Error.call() operates on the returned error
+				// object rather than operating on |this|
+				var err = Error.call(this, message),
+					prop;
+
+				// Copy own properties from err to |this|
+				for(prop in err){
+					if(err.hasOwnProperty(prop)){
+						this[prop] = err[prop];
+					}
+				}
+
+				// messsage is non-enumerable in ES5
+				this.message = message;
+				// stack is non-enumerable in at least Firefox
+				this.stack = err.stack;
+			}else{
+				base.apply(this, arguments);
+			}
+			if(ctor){
+				ctor.apply(this, arguments);
+			}
+		};
+
+		ErrorCtor.prototype = lang.delegate(base.prototype, props);
+		ErrorCtor.prototype.name = name;
+		ErrorCtor.prototype.constructor = ErrorCtor;
+
+		return ErrorCtor;
+	};
+});
diff --git a/dojo/fx.js b/dojo/fx.js
index 55160ff..4eb7998 100644
--- a/dojo/fx.js
+++ b/dojo/fx.js
@@ -3,37 +3,30 @@ define([
 	"./Evented",
 	"./_base/kernel",
 	"./_base/array",
-	"./_base/connect",
+	"./aspect",
 	"./_base/fx",
 	"./dom",
 	"./dom-style",
 	"./dom-geometry",
 	"./ready",
 	"require" // for context sensitive loading of Toggler
-], function(lang, Evented, dojo, arrayUtil, connect, baseFx, dom, domStyle, geom, ready, require) {
+], function(lang, Evented, dojo, arrayUtil, aspect, baseFx, dom, domStyle, geom, ready, require){
 
 	// module:
 	//		dojo/fx
-	// summary:
-	//		TODOC
-
-
-	/*=====
-	dojo.fx = {
-		// summary: Effects library on top of Base animations
-	};
-	var coreFx = dojo.fx;
-	=====*/
 	
-// For back-compat, remove in 2.0.
-if(!dojo.isAsync){
-	ready(0, function(){
-		var requires = ["./fx/Toggler"];
-		require(requires);	// use indirection so modules not rolled into a build
-	});
-}
+	// For back-compat, remove in 2.0.
+	if(!dojo.isAsync){
+		ready(0, function(){
+			var requires = ["./fx/Toggler"];
+			require(requires);	// use indirection so modules not rolled into a build
+		});
+	}
 
-	var coreFx = dojo.fx = {};
+	var coreFx = dojo.fx = {
+		// summary:
+		//		Effects library on top of Base animations
+	};
 
 	var _baseObj = {
 			_fire: function(evt, args){
@@ -61,51 +54,51 @@ if(!dojo.isAsync){
 			this._fire("onAnimate", arguments);
 		},
 		_onEnd: function(){
-			connect.disconnect(this._onAnimateCtx);
-			connect.disconnect(this._onEndCtx);
+			this._onAnimateCtx.remove();
+			this._onEndCtx.remove();
 			this._onAnimateCtx = this._onEndCtx = null;
 			if(this._index + 1 == this._animations.length){
 				this._fire("onEnd");
 			}else{
 				// switch animations
 				this._current = this._animations[++this._index];
-				this._onAnimateCtx = connect.connect(this._current, "onAnimate", this, "_onAnimate");
-				this._onEndCtx = connect.connect(this._current, "onEnd", this, "_onEnd");
+				this._onAnimateCtx = aspect.after(this._current, "onAnimate", lang.hitch(this, "_onAnimate"), true);
+				this._onEndCtx = aspect.after(this._current, "onEnd", lang.hitch(this, "_onEnd"), true);
 				this._current.play(0, true);
 			}
 		},
 		play: function(/*int?*/ delay, /*Boolean?*/ gotoStart){
 			if(!this._current){ this._current = this._animations[this._index = 0]; }
 			if(!gotoStart && this._current.status() == "playing"){ return this; }
-			var beforeBegin = connect.connect(this._current, "beforeBegin", this, function(){
+			var beforeBegin = aspect.after(this._current, "beforeBegin", lang.hitch(this, function(){
 					this._fire("beforeBegin");
-				}),
-				onBegin = connect.connect(this._current, "onBegin", this, function(arg){
+				}), true),
+				onBegin = aspect.after(this._current, "onBegin", lang.hitch(this, function(arg){
 					this._fire("onBegin", arguments);
-				}),
-				onPlay = connect.connect(this._current, "onPlay", this, function(arg){
+				}), true),
+				onPlay = aspect.after(this._current, "onPlay", lang.hitch(this, function(arg){
 					this._fire("onPlay", arguments);
-					connect.disconnect(beforeBegin);
-					connect.disconnect(onBegin);
-					connect.disconnect(onPlay);
-				});
+					beforeBegin.remove();
+					onBegin.remove();
+					onPlay.remove();
+				}));
 			if(this._onAnimateCtx){
-				connect.disconnect(this._onAnimateCtx);
+				this._onAnimateCtx.remove();
 			}
-			this._onAnimateCtx = connect.connect(this._current, "onAnimate", this, "_onAnimate");
+			this._onAnimateCtx = aspect.after(this._current, "onAnimate", lang.hitch(this, "_onAnimate"), true);
 			if(this._onEndCtx){
-				connect.disconnect(this._onEndCtx);
+				this._onEndCtx.remove();
 			}
-			this._onEndCtx = connect.connect(this._current, "onEnd", this, "_onEnd");
+			this._onEndCtx = aspect.after(this._current, "onEnd", lang.hitch(this, "_onEnd"), true);
 			this._current.play.apply(this._current, arguments);
 			return this;
 		},
 		pause: function(){
 			if(this._current){
-				var e = connect.connect(this._current, "onPause", this, function(arg){
+				var e = aspect.after(this._current, "onPause", lang.hitch(this, function(arg){
 						this._fire("onPause", arguments);
-						connect.disconnect(e);
-					});
+						e.remove();
+					}), true);
 				this._current.pause();
 			}
 			return this;
@@ -135,10 +128,10 @@ if(!dojo.isAsync){
 					}
 					this._current = this._animations[this._index];
 				}
-				var e = connect.connect(this._current, "onStop", this, function(arg){
+				var e = aspect.after(this._current, "onStop", lang.hitch(this, function(arg){
 						this._fire("onStop", arguments);
-						connect.disconnect(e);
-					});
+						e.remove();
+					}), true);
 				this._current.stop();
 			}
 			return this;
@@ -147,13 +140,13 @@ if(!dojo.isAsync){
 			return this._current ? this._current.status() : "stopped";
 		},
 		destroy: function(){
-			if(this._onAnimateCtx){ connect.disconnect(this._onAnimateCtx); }
-			if(this._onEndCtx){ connect.disconnect(this._onEndCtx); }
+			if(this._onAnimateCtx){ this._onAnimateCtx.remove(); }
+			if(this._onEndCtx){ this._onEndCtx.remove(); }
 		}
 	});
 	lang.extend(_chain, _baseObj);
 
-	coreFx.chain = /*===== dojo.fx.chain = =====*/ function(/*dojo.Animation[]*/ animations){
+	coreFx.chain = function(/*dojo/_base/fx.Animation[]*/ animations){
 		// summary:
 		//		Chain a list of `dojo.Animation`s to run in sequence
 		//
@@ -166,12 +159,12 @@ if(!dojo.isAsync){
 		//
 		// example:
 		//	Once `node` is faded out, fade in `otherNode`
-		//	|	dojo.fx.chain([
+		//	|	fx.chain([
 		//	|		dojo.fadeIn({ node:node }),
 		//	|		dojo.fadeOut({ node:otherNode })
 		//	|	]).play();
 		//
-		return new _chain(animations); // dojo.Animation
+		return new _chain(animations); // dojo/_base/fx.Animation
 	};
 
 	var _combine = function(animations){
@@ -184,16 +177,16 @@ if(!dojo.isAsync){
 			var duration = a.duration;
 			if(a.delay){ duration += a.delay; }
 			if(this.duration < duration){ this.duration = duration; }
-			this._connects.push(connect.connect(a, "onEnd", this, "_onEnd"));
+			this._connects.push(aspect.after(a, "onEnd", lang.hitch(this, "_onEnd"), true));
 		}, this);
 
 		this._pseudoAnimation = new baseFx.Animation({curve: [0, 1], duration: this.duration});
 		var self = this;
 		arrayUtil.forEach(["beforeBegin", "onBegin", "onPlay", "onAnimate", "onPause", "onStop", "onEnd"],
 			function(evt){
-				self._connects.push(connect.connect(self._pseudoAnimation, evt,
-					function(){ self._fire(evt, arguments); }
-				));
+				self._connects.push(aspect.after(self._pseudoAnimation, evt,
+					function(){ self._fire(evt, arguments); },
+				true));
 			}
 		);
 	};
@@ -241,12 +234,14 @@ if(!dojo.isAsync){
 			return this._pseudoAnimation.status();
 		},
 		destroy: function(){
-			arrayUtil.forEach(this._connects, connect.disconnect);
+			arrayUtil.forEach(this._connects, function(handle){
+				handle.remove();
+			});
 		}
 	});
 	lang.extend(_combine, _baseObj);
 
-	coreFx.combine = /*===== dojo.fx.combine = =====*/ function(/*dojo.Animation[]*/ animations){
+	coreFx.combine = function(/*dojo/_base/fx.Animation[]*/ animations){
 		// summary:
 		//		Combine a list of `dojo.Animation`s to run in parallel
 		//
@@ -257,26 +252,26 @@ if(!dojo.isAsync){
 		//
 		// example:
 		//	Fade out `node` while fading in `otherNode` simultaneously
-		//	|	dojo.fx.combine([
+		//	|	fx.combine([
 		//	|		dojo.fadeIn({ node:node }),
 		//	|		dojo.fadeOut({ node:otherNode })
 		//	|	]).play();
 		//
 		// example:
 		//	When the longest animation ends, execute a function:
-		//	|	var anim = dojo.fx.combine([
+		//	|	var anim = fx.combine([
 		//	|		dojo.fadeIn({ node: n, duration:700 }),
 		//	|		dojo.fadeOut({ node: otherNode, duration: 300 })
 		//	|	]);
-		//	|	dojo.connect(anim, "onEnd", function(){
+		//	|	aspect.after(anim, "onEnd", function(){
 		//	|		// overall animation is done.
-		//	|	});
+		//	|	}, true);
 		//	|	anim.play(); // play the animation
 		//
-		return new _combine(animations); // dojo.Animation
+		return new _combine(animations); // dojo/_base/fx.Animation
 	};
 
-	coreFx.wipeIn = /*===== dojo.fx.wipeIn = =====*/ function(/*Object*/ args){
+	coreFx.wipeIn = function(/*Object*/ args){
 		// summary:
 		//		Expand a node to it's natural height.
 		//
@@ -291,7 +286,7 @@ if(!dojo.isAsync){
 		//		(such as easing: node: duration: and so on)
 		//
 		// example:
-		//	|	dojo.fx.wipeIn({
+		//	|	fx.wipeIn({
 		//	|		node:"someId"
 		//	|	}).play()
 		var node = args.node = dom.byId(args.node), s = node.style, o;
@@ -326,13 +321,13 @@ if(!dojo.isAsync){
 			s.height = "auto";
 			s.overflow = o;
 		};
-		connect.connect(anim, "onStop", fini);
-		connect.connect(anim, "onEnd", fini);
+		aspect.after(anim, "onStop", fini, true);
+		aspect.after(anim, "onEnd", fini, true);
 
-		return anim; // dojo.Animation
+		return anim; // dojo/_base/fx.Animation
 	};
 
-	coreFx.wipeOut = /*===== dojo.fx.wipeOut = =====*/ function(/*Object*/ args){
+	coreFx.wipeOut = function(/*Object*/ args){
 		// summary:
 		//		Shrink a node to nothing and hide it.
 		//
@@ -345,7 +340,7 @@ if(!dojo.isAsync){
 		//		(such as easing: node: duration: and so on)
 		//
 		// example:
-		//	|	dojo.fx.wipeOut({ node:"someId" }).play()
+		//	|	fx.wipeOut({ node:"someId" }).play()
 
 		var node = args.node = dom.byId(args.node), s = node.style, o;
 
@@ -357,23 +352,23 @@ if(!dojo.isAsync){
 			}
 		}, args));
 
-		connect.connect(anim, "beforeBegin", function(){
+		aspect.after(anim, "beforeBegin", function(){
 			o = s.overflow;
 			s.overflow = "hidden";
 			s.display = "";
-		});
+		}, true);
 		var fini = function(){
 			s.overflow = o;
 			s.height = "auto";
 			s.display = "none";
 		};
-		connect.connect(anim, "onStop", fini);
-		connect.connect(anim, "onEnd", fini);
+		aspect.after(anim, "onStop", fini, true);
+		aspect.after(anim, "onEnd", fini, true);
 
-		return anim; // dojo.Animation
+		return anim; // dojo/_base/fx.Animation
 	};
 
-	coreFx.slideTo = /*===== dojo.fx.slideTo = =====*/ function(/*Object*/ args){
+	coreFx.slideTo = function(/*Object*/ args){
 		// summary:
 		//		Slide a node to a new top/left position
 		//
@@ -417,9 +412,9 @@ if(!dojo.isAsync){
 				left: args.left || 0
 			}
 		}, args));
-		connect.connect(anim, "beforeBegin", anim, init);
+		aspect.after(anim, "beforeBegin", init, true);
 
-		return anim; // dojo.Animation
+		return anim; // dojo/_base/fx.Animation
 	};
 
 	return coreFx;
diff --git a/dojo/fx/Toggler.js b/dojo/fx/Toggler.js
index 9fa5824..580d13f 100644
--- a/dojo/fx/Toggler.js
+++ b/dojo/fx/Toggler.js
@@ -1,27 +1,23 @@
-define(["../_base/lang","../_base/declare","../_base/fx", "../_base/connect"], 
-  function(lang, declare, baseFx, connectUtil) {
+define(["../_base/lang","../_base/declare","../_base/fx", "../aspect"],
+  function(lang, declare, baseFx, aspect){
 	// module:
 	//		dojo/fx/Toggler
-	// summary:
-	//		TODOC
 
 return declare("dojo.fx.Toggler", null, {
 	// summary:
 	//		A simple `dojo.Animation` toggler API.
-	//
 	// description:
 	//		class constructor for an animation toggler. It accepts a packed
 	//		set of arguments about what type of animation to use in each
 	//		direction, duration, etc. All available members are mixed into
 	//		these animations from the constructor (for example, `node`,
 	//		`showDuration`, `hideDuration`).
-	//
 	// example:
-	//	|	var t = new dojo.fx.Toggler({
+	//	|	var t = new dojo/fx/Toggler({
 	//	|		node: "nodeId",
 	//	|		showDuration: 500,
 	//	|		// hideDuration will default to "200"
-	//	|		showFunc: dojo.fx.wipeIn,
+	//	|		showFunc: dojo/fx/wipeIn,
 	//	|		// hideFunc will default to "fadeOut"
 	//	|	});
 	//	|	t.show(100); // delay showing for 100ms
@@ -81,21 +77,23 @@ return declare("dojo.fx.Toggler", null, {
 		_t._hideArgs.duration = _t.hideDuration;
 		_t.hideAnim = _t.hideFunc(_t._hideArgs);
 
-		connectUtil.connect(_t.showAnim, "beforeBegin", lang.hitch(_t.hideAnim, "stop", true));
-		connectUtil.connect(_t.hideAnim, "beforeBegin", lang.hitch(_t.showAnim, "stop", true));
+		aspect.after(_t.showAnim, "beforeBegin", lang.hitch(_t.hideAnim, "stop", true), true);
+		aspect.after(_t.hideAnim, "beforeBegin", lang.hitch(_t.showAnim, "stop", true), true);
 	},
 
 	show: function(delay){
-		// summary: Toggle the node to showing
+		// summary:
+		//		Toggle the node to showing
 		// delay: Integer?
-		//		Ammount of time to stall playing the show animation
+		//		Amount of time to stall playing the show animation
 		return this.showAnim.play(delay || 0);
 	},
 
 	hide: function(delay){
-		// summary: Toggle the node to hidden
+		// summary:
+		//		Toggle the node to hidden
 		// delay: Integer?
-		//		Ammount of time to stall playing the hide animation
+		//		Amount of time to stall playing the hide animation
 		return this.hideAnim.play(delay || 0);
 	}
 });
diff --git a/dojo/fx/easing.js b/dojo/fx/easing.js
index 33d3c65..dfbfa70 100644
--- a/dojo/fx/easing.js
+++ b/dojo/fx/easing.js
@@ -1,19 +1,16 @@
-define(["../_base/lang"], function(lang) {
+define(["../_base/lang"], function(lang){
+
 // module:
 //		dojo/fx/easing
-// summary:
-//		This module defines standard easing functions that are useful for animations.
 
-var easingFuncs = /*===== dojo.fx.easing= =====*/ {
+var easingFuncs = {
 	// summary:
 	//		Collection of easing functions to use beyond the default
 	//		`dojo._defaultEasing` function.
-	//
 	// description:
-	//
 	//		Easing functions are used to manipulate the iteration through
 	//		an `dojo.Animation`s _Line. _Line being the properties of an Animation,
-	//		and the easing function progresses through that Line determing
+	//		and the easing function progresses through that Line determining
 	//		how quickly (or slowly) it should go. Or more accurately: modify
 	//		the value of the _Line based on the percentage of animation completed.
 	//
@@ -25,8 +22,7 @@ var easingFuncs = /*===== dojo.fx.easing= =====*/ {
 	//
 	//		One does not call the easing function directly, it must be passed to
 	//		the `easing` property of an animation.
-	//
-	//	example:
+	// example:
 	//	|	dojo.require("dojo.fx.easing");
 	//	|	var anim = dojo.fadeOut({
 	//	|		node: 'node',
@@ -37,7 +33,8 @@ var easingFuncs = /*===== dojo.fx.easing= =====*/ {
 	//
 
 	linear: function(/* Decimal? */n){
-		// summary: A linear easing function
+		// summary:
+		//		A linear easing function
 		return n;
 	},
 
@@ -159,7 +156,6 @@ var easingFuncs = /*===== dojo.fx.easing= =====*/ {
 	backOut: function(/* Decimal? */n){
 		// summary:
 		//		An easing function that pops past the range briefly, and slowly comes back.
-		//
 		// description:
 		//		An easing function that pops past the range briefly, and slowly comes back.
 		//
@@ -174,7 +170,6 @@ var easingFuncs = /*===== dojo.fx.easing= =====*/ {
 	backInOut: function(/* Decimal? */n){
 		// summary:
 		//		An easing function combining the effects of `backIn` and `backOut`
-		//
 		// description:
 		//		An easing function combining the effects of `backIn` and `backOut`.
 		//		Use caution when the easing will cause values to become negative
@@ -189,7 +184,6 @@ var easingFuncs = /*===== dojo.fx.easing= =====*/ {
 	elasticIn: function(/* Decimal? */n){
 		// summary:
 		//		An easing function the elastically snaps from the start value
-		//
 		// description:
 		//		An easing function the elastically snaps from the start value
 		//
@@ -206,7 +200,6 @@ var easingFuncs = /*===== dojo.fx.easing= =====*/ {
 		// summary:
 		//		An easing function that elasticly snaps around the target value,
 		//		near the end of the Animation
-		//
 		// description:
 		//		An easing function that elasticly snaps around the target value,
 		//		near the end of the Animation
@@ -223,7 +216,6 @@ var easingFuncs = /*===== dojo.fx.easing= =====*/ {
 		// summary:
 		//		An easing function that elasticly snaps around the value, near
 		//		the beginning and end of the Animation.
-		//
 		// description:
 		//		An easing function that elasticly snaps around the value, near
 		//		the beginning and end of the Animation.
diff --git a/dojo/gears.js b/dojo/gears.js
index bae1eb8..c982b4b 100644
--- a/dojo/gears.js
+++ b/dojo/gears.js
@@ -1,13 +1,15 @@
-define(["./_base/kernel", "./_base/lang", "./_base/sniff"],
-	function(dojo, lang, has) {
-	// module:
-	//		dojo/gears
+define(["./_base/lang", "./sniff"], function(lang, has){
+
+// module:
+//		dojo/gears
+
+var gears = {
 	// summary:
 	//		TODOC
+};
+lang.setObject("dojo.gears", gears);
 
-lang.getObject("gears", true, dojo);
-
-dojo.gears._gearsObject = function(){
+gears._gearsObject = function(){
 	// summary:
 	//		factory method to get a Google Gears plugin instance to
 	//		expose in the browser runtime environment, if present
@@ -47,15 +49,17 @@ dojo.gears._gearsObject = function(){
 	return lang.getObject("google.gears");
 };
 
-/*=====
-dojo.gears.available = {
-	// summary: True if client is using Google Gears
-};
-=====*/
+
 // see if we have Google Gears installed, and if
 // so, make it available in the runtime environment
 // and in the Google standard 'google.gears' global object
-dojo.gears.available = (!!dojo.gears._gearsObject())||0;
+gears.available = (!!gears._gearsObject())||0;
+/*=====
+ gears.available = {
+ // summary:
+ //		True if client is using Google Gears
+ };
+ =====*/
 
-return dojo.gears;
+return gears;
 });
diff --git a/dojo/has.js b/dojo/has.js
index d219ff0..dd765d3 100644
--- a/dojo/has.js
+++ b/dojo/has.js
@@ -1,4 +1,4 @@
-define(["require"], function(require) {
+define(["require", "module"], function(require, module){
 	// module:
 	//		dojo/has
 	// summary:
@@ -6,19 +6,17 @@ define(["require"], function(require) {
 	// description:
 	//		This module defines the has API as described by the project has.js with the following additional features:
 	//
-	//			* the has test cache is exposed at has.cache.
-	//			* the method has.add includes a forth parameter that controls whether or not existing tests are replaced
-	//			* the loader's has cache may be optionally copied into this module's has cahce.
+	//		- the has test cache is exposed at has.cache.
+	//		- the method has.add includes a forth parameter that controls whether or not existing tests are replaced
+	//		- the loader's has cache may be optionally copied into this module's has cahce.
 	//
 	//		This module adopted from https://github.com/phiggins42/has.js; thanks has.js team!
 
 	// try to pull the has implementation from the loader; both the dojo loader and bdLoad provide one
+	// if using a foreign loader, then the has cache may be initialized via the config object for this module
 	// WARNING: if a foreign loader defines require.has to be something other than the has.js API, then this implementation fail
 	var has = require.has || function(){};
 	if(!has("dojo-has-api")){
-		// notice the condition is written so that if has("dojo-has-api") is transformed to 1 during a build
-		// the conditional will be (!1 && typeof has=="function") which is statically false and the closure
-		// compiler will discard the block.
 		var
 			isBrowser =
 				// the most fundamental decision: are we in the browser?
@@ -31,16 +29,16 @@ define(["require"], function(require) {
 			global = this,
 			doc = isBrowser && document,
 			element = doc && doc.createElement("DiV"),
-			cache = {};
+			cache = (module.config && module.config()) || {};
 
-		has = /*===== dojo.has= =====*/ function(name){
-			//	summary:
+		has = function(name){
+			// summary:
 			//		Return the current value of the named feature.
 			//
-			//	name: String|Integer
+			// name: String|Integer
 			//		The name (if a string) or identifier (if an integer) of the feature to test.
 			//
-			//	description:
+			// description:
 			//		Returns the value of the feature named by name. The feature must have been
 			//		previously added to the cache by has.add.
 
@@ -49,45 +47,40 @@ define(["require"], function(require) {
 
 		has.cache = cache;
 
-		has.add = /*====== dojo.has.add= ======*/ function(name, test, now, force){
+		has.add = function(name, test, now, force){
 			// summary:
-			//	 Register a new feature test for some named feature.
-			//
+			//	 	Register a new feature test for some named feature.
 			// name: String|Integer
-			//	 The name (if a string) or identifier (if an integer) of the feature to test.
-			//
+			//	 	The name (if a string) or identifier (if an integer) of the feature to test.
 			// test: Function
-			//	 A test function to register. If a function, queued for testing until actually
-			//	 needed. The test function should return a boolean indicating
-			//	 the presence of a feature or bug.
-			//
+			//		 A test function to register. If a function, queued for testing until actually
+			//		 needed. The test function should return a boolean indicating
+			//	 	the presence of a feature or bug.
 			// now: Boolean?
-			//	 Optional. Omit if `test` is not a function. Provides a way to immediately
-			//	 run the test and cache the result.
-			//
+			//		 Optional. Omit if `test` is not a function. Provides a way to immediately
+			//		 run the test and cache the result.
 			// force: Boolean?
-			//	 Optional. If the test already exists and force is truthy, then the existing
-			//	 test will be replaced; otherwise, add does not replace an existing test (that
-			//	 is, by default, the first test advice wins).
-			//
+			//	 	Optional. If the test already exists and force is truthy, then the existing
+			//	 	test will be replaced; otherwise, add does not replace an existing test (that
+			//	 	is, by default, the first test advice wins).
 			// example:
-			//			A redundant test, testFn with immediate execution:
-			//	|				has.add("javascript", function(){ return true; }, true);
+			//		A redundant test, testFn with immediate execution:
+			//	|	has.add("javascript", function(){ return true; }, true);
 			//
 			// example:
-			//			Again with the redundantness. You can do this in your tests, but we should
-			//			not be doing this in any internal has.js tests
-			//	|				has.add("javascript", true);
+			//		Again with the redundantness. You can do this in your tests, but we should
+			//		not be doing this in any internal has.js tests
+			//	|	has.add("javascript", true);
 			//
 			// example:
-			//			Three things are passed to the testFunction. `global`, `document`, and a generic element
-			//			from which to work your test should the need arise.
-			//	|				has.add("bug-byid", function(g, d, el){
-			//	|						// g	== global, typically window, yadda yadda
-			//	|						// d	== document object
-			//	|						// el == the generic element. a `has` element.
-			//	|						return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer
-			//	|				});
+			//		Three things are passed to the testFunction. `global`, `document`, and a generic element
+			//		from which to work your test should the need arise.
+			//	|	has.add("bug-byid", function(g, d, el){
+			//	|		// g	== global, typically window, yadda yadda
+			//	|		// d	== document object
+			//	|		// el == the generic element. a `has` element.
+			//	|		return false; // fake test, byid-when-form-has-name-matching-an-id is slightly longer
+			//	|	});
 
 			(typeof cache[name]=="undefined" || force) && (cache[name]= test);
 			return now && has(name);
@@ -103,24 +96,29 @@ define(["require"], function(require) {
 	}
 
 	if(has("host-browser")){
-		var agent = navigator.userAgent;
 		// Common application level tests
 		has.add("dom-addeventlistener", !!document.addEventListener);
-		has.add("touch", "ontouchstart" in document);
+		has.add("touch", "ontouchstart" in document || window.navigator.msMaxTouchPoints > 0);
 		// I don't know if any of these tests are really correct, just a rough guess
 		has.add("device-width", screen.availWidth || innerWidth);
-		has.add("agent-ios", !!agent.match(/iPhone|iP[ao]d/));
-		has.add("agent-android", agent.indexOf("android") > 1);
+
+		// Tests for DOMNode.attributes[] behavior:
+		//	 - dom-attributes-explicit - attributes[] only lists explicitly user specified attributes
+		//	 - dom-attributes-specified-flag (IE8) - need to check attr.specified flag to skip attributes user didn't specify
+		//	 - Otherwise, in IE6-7. attributes[] will list hundreds of values, so need to do outerHTML to get attrs instead.
+		var form = document.createElement("form");
+		has.add("dom-attributes-explicit", form.attributes.length == 0); // W3C
+		has.add("dom-attributes-specified-flag", form.attributes.length > 0 && form.attributes.length < 40);	// IE8
 	}
 
-	has.clearElement = /*===== dojo.has.clearElement= ======*/ function(element) {
+	has.clearElement = function(element){
 		// summary:
 		//	 Deletes the contents of the element passed to test functions.
 		element.innerHTML= "";
 		return element;
 	};
 
-	has.normalize = /*===== dojo.has.normalize= ======*/ function(id, toAbsMid){
+	has.normalize = function(id, toAbsMid){
 		// summary:
 		//	 Resolves id into a module id based on possibly-nested tenary expression that branches on has feature test value(s).
 		//
@@ -153,17 +151,14 @@ define(["require"], function(require) {
 		return id && toAbsMid(id);
 	};
 
-	has.load = /*===== dojo.has.load= ======*/ function(id, parentRequire, loaded){
+	has.load = function(id, parentRequire, loaded){
 		// summary:
-		//	 Conditional loading of AMD modules based on a has feature test value.
-		//
+		//		Conditional loading of AMD modules based on a has feature test value.
 		// id: String
-		//	 Gives the resolved module id to load.
-		//
+		//		Gives the resolved module id to load.
 		// parentRequire: Function
-		//	 The loader require function with respect to the module that contained the plugin resource in it's
-		//	 dependency list.
-		//
+		//		The loader require function with respect to the module that contained the plugin resource in it's
+		//		dependency list.
 		// loaded: Function
 		//	 Callback to loader that consumes result of plugin demand.
 
diff --git a/dojo/hash.js b/dojo/hash.js
index 643f5d1..f961bfb 100644
--- a/dojo/hash.js
+++ b/dojo/hash.js
@@ -1,37 +1,31 @@
-define(["./_base/kernel", "require", "./_base/connect", "./_base/lang", "./ready", "./_base/sniff"],
-	function(dojo, require, connect, lang, ready, has) {
+define(["./_base/kernel", "require", "./_base/config", "./aspect", "./_base/lang", "./topic", "./domReady", "./sniff"],
+	function(dojo, require, config, aspect, lang, topic, domReady, has){
+
 	// module:
 	//		dojo/hash
-	// summary:
-	//		TODOC
-
-
-//TODOC: where does this go?
-// summary:
-//		Methods for monitoring and updating the hash in the browser URL.
-//
-// example:
-//		dojo.subscribe("/dojo/hashchange", context, callback);
-//
-//		function callback (hashValue){
-//			// do something based on the hash value.
-//		}
 
 	dojo.hash = function(/* String? */ hash, /* Boolean? */ replace){
-		//	summary:
-		//		Gets or sets the hash string.
-		//	description:
+		// summary:
+		//		Gets or sets the hash string in the browser URL.
+		// description:
 		//		Handles getting and setting of location.hash.
+		//
 		//		 - If no arguments are passed, acts as a getter.
 		//		 - If a string is passed, acts as a setter.
-		//	hash:
+		// hash:
 		//		the hash is set - #string.
-		//	replace:
+		// replace:
 		//		If true, updates the hash value in the current history
 		//		state instead of creating a new history state.
-		//	returns:
+		// returns:
 		//		when used as a getter, returns the current hash string.
 		//		when used as a setter, returns the new hash string.
+		// example:
+		//	|	topic.subscribe("/dojo/hashchange", context, callback);
+		//	|
+		//	|	function callback (hashValue){
+		//	|		// do something based on the hash value.
+		//	|	}
 
 		// getter
 		if(!arguments.length){
@@ -51,7 +45,7 @@ define(["./_base/kernel", "require", "./_base/connect", "./_base/lang", "./ready
 
 	// Global vars
 	var _recentHash, _ieUriMonitor, _connect,
-		_pollFrequency = dojo.config.hashPollFrequency || 100;
+		_pollFrequency = config.hashPollFrequency || 100;
 
 	//Internal functions
 	function _getSegment(str, delimiter){
@@ -64,7 +58,7 @@ define(["./_base/kernel", "require", "./_base/connect", "./_base/lang", "./ready
 	}
 
 	function _dispatchEvent(){
-		connect.publish("/dojo/hashchange", [_getHash()]);
+		topic.publish("/dojo/hashchange", _getHash());
 	}
 
 	function _pollLocation(){
@@ -96,7 +90,7 @@ define(["./_base/kernel", "require", "./_base/connect", "./_base/lang", "./ready
 		//		Determine if the browser's URI has changed or if the user has pressed the
 		//		back or forward button. If so, call _dispatchEvent.
 		//
-		//	description:
+		// description:
 		//		IE doesn't add changes to the URI's hash into the history unless the hash
 		//		value corresponds to an actual named anchor in the document. To get around
 		//		this IE difference, we use a background IFrame to maintain a back-forward
@@ -114,37 +108,56 @@ define(["./_base/kernel", "require", "./_base/connect", "./_base/lang", "./ready
 		//		This design leads to a somewhat complex state machine, which is
 		//		described below:
 		//
-		//		s1: Stable state - neither the window's location has changed nor
-		//			has the IFrame's location. Note that this is the 99.9% case, so
-		//			we optimize for it.
-		//			Transitions: s1, s2, s3
-		//		s2: Window's location changed - when a user clicks a hyperlink or
-		//			code programmatically changes the window's URI.
-		//			Transitions: s4
-		//		s3: Iframe's location changed as a result of user pressing back or
-		//			forward - when the user presses back or forward, the location of
-		//			the background's iframe changes to the previous or next value in
-		//			its history.
-		//			Transitions: s1
-		//		s4: IEUriMonitor has programmatically changed the location of the
-		//			background iframe, but it's location hasn't yet changed. In this
-		//			case we do nothing because we need to wait for the iframe's
-		//			location to reflect its actual state.
-		//			Transitions: s4, s5
-		//		s5: IEUriMonitor has programmatically changed the location of the
-		//			background iframe, and the iframe's location has caught up with
-		//			reality. In this case we need to transition to s1.
-		//			Transitions: s1
+		//		####s1
 		//
-		//		The hashchange event is always dispatched on the transition back to s1.
+		//		Stable state - neither the window's location has changed nor
+		//		has the IFrame's location. Note that this is the 99.9% case, so
+		//		we optimize for it.
+		//
+		//		Transitions: s1, s2, s3
+		//
+		//		####s2
+		//
+		//		Window's location changed - when a user clicks a hyperlink or
+		//		code programmatically changes the window's URI.
+		//
+		//		Transitions: s4
+		//
+		//		####s3
 		//
+		//		Iframe's location changed as a result of user pressing back or
+		//		forward - when the user presses back or forward, the location of
+		//		the background's iframe changes to the previous or next value in
+		//		its history.
+		//
+		//		Transitions: s1
+		//
+		//		####s4
+		//
+		//		IEUriMonitor has programmatically changed the location of the
+		//		background iframe, but it's location hasn't yet changed. In this
+		//		case we do nothing because we need to wait for the iframe's
+		//		location to reflect its actual state.
+		//
+		//		Transitions: s4, s5
+		//
+		//		####s5
+		//
+		//		IEUriMonitor has programmatically changed the location of the
+		//		background iframe, and the iframe's location has caught up with
+		//		reality. In this case we need to transition to s1.
+		//
+		//		Transitions: s1
+		//
+		//		The hashchange event is always dispatched on the transition back to s1.
+
 
 		// create and append iframe
 		var ifr = document.createElement("iframe"),
 			IFRAME_ID = "dojo-hash-iframe",
-			ifrSrc = dojo.config.dojoBlankHtmlUrl || require.toUrl("./resources/blank.html");
+			ifrSrc = config.dojoBlankHtmlUrl || require.toUrl("./resources/blank.html");
 
-		if(dojo.config.useXDomain && !dojo.config.dojoBlankHtmlUrl){
+		if(config.useXDomain && !config.dojoBlankHtmlUrl){
 			console.warn("dojo.hash: When using cross-domain Dojo builds,"
 				+ " please save dojo/resources/blank.html to your domain and set djConfig.dojoBlankHtmlUrl"
 				+ " to the path on your domain to blank.html");
@@ -171,7 +184,7 @@ define(["./_base/kernel", "require", "./_base/connect", "./_base/lang", "./ready
 		};
 
 		this.pollLocation = function(){
-			if(!ifrOffline) {
+			if(!ifrOffline){
 				try{
 					//see if we can access the iframe's location without a permission denied error
 					var iframeSearch = _getSegment(iframeLoc.href, "?");
@@ -223,9 +236,9 @@ define(["./_base/kernel", "require", "./_base/connect", "./_base/lang", "./ready
 		resetState(); // initialize state (transition to s1)
 		setTimeout(lang.hitch(this,this.pollLocation), _pollFrequency);
 	}
-	ready(function(){
+	domReady(function(){
 		if("onhashchange" in dojo.global && (!has("ie") || (has("ie") >= 8 && document.compatMode != "BackCompat"))){	//need this IE browser test because "onhashchange" exists in IE8 in IE7 mode
-			_connect = connect.connect(dojo.global,"onhashchange",_dispatchEvent);
+			_connect = aspect.after(dojo.global,"onhashchange",_dispatchEvent, true);
 		}else{
 			if(document.addEventListener){ // Non-IE
 				_recentHash = _getHash();
diff --git a/dojo/hccss.js b/dojo/hccss.js
new file mode 100644
index 0000000..fea92ca
--- /dev/null
+++ b/dojo/hccss.js
@@ -0,0 +1,52 @@
+define([
+	"require",			// require, require.toUrl
+	"./_base/config", // config.blankGif
+	"./dom-class", // domClass.add
+	"./dom-style", // domStyle.getComputedStyle
+	"./has",
+	"./domReady",
+	"./_base/window" // win.body
+], function(require, config, domClass, domStyle, has, domReady, win){
+
+	// module:
+	//		dojo/hccss
+
+	/*=====
+	return function(){
+		// summary:
+		//		Test if computer is in high contrast mode (i.e. if browser is not displaying background images).
+		//		Defines `has("highcontrast")` and sets `dj_a11y` CSS class on `<body>` if machine is in high contrast mode.
+		//		Returns `has()` method;
+	};
+	=====*/
+
+	// Has() test for when background images aren't displayed.  Don't call has("highcontrast") before dojo/domReady!.
+	has.add("highcontrast", function(){
+		// note: if multiple documents, doesn't matter which one we use
+		var div = win.doc.createElement("div");
+		div.style.cssText = "border: 1px solid; border-color:red green; position: absolute; height: 5px; top: -999px;" +
+			"background-image: url(" + (config.blankGif || require.toUrl("./resources/blank.gif")) + ");";
+		win.body().appendChild(div);
+
+		var cs = domStyle.getComputedStyle(div),
+			bkImg = cs.backgroundImage,
+			hc = (cs.borderTopColor == cs.borderRightColor) ||
+				(bkImg && (bkImg == "none" || bkImg == "url(invalid-url:)" ));
+
+		if(has("ie") <= 8){
+			div.outerHTML = "";		// prevent mixed-content warning, see http://support.microsoft.com/kb/925014
+		}else{
+			win.body().removeChild(div);
+		}
+
+		return hc;
+	});
+
+	domReady(function(){
+		if(has("highcontrast")){
+			domClass.add(win.body(), "dj_a11y");
+		}
+	});
+
+	return has;
+});
diff --git a/dojo/html.js b/dojo/html.js
index 69ed136..4befd8f 100644
--- a/dojo/html.js
+++ b/dojo/html.js
@@ -1,60 +1,64 @@
-define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", "./dom", "./dom-construct", "./parser"], function(dojo, lang, darray, declare, dom, domConstruct, parser) {
+define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", "./dom", "./dom-construct", "./parser"],
+	function(kernel, lang, darray, declare, dom, domConstruct, parser){
 	// module:
 	//		dojo/html
-	// summary:
-	//		TODOC
 
-	lang.getObject("html", true, dojo);
+	var html = {
+		// summary:
+		//		TODOC
+	};
+	lang.setObject("dojo.html", html);
 
 	// the parser might be needed..
 
-	// idCounter is incremented with each instantiation to allow asignment of a unique id for tracking, logging purposes
+	// idCounter is incremented with each instantiation to allow assignment of a unique id for tracking, logging purposes
 	var idCounter = 0;
 
-	dojo.html._secureForInnerHtml = function(/*String*/ cont){
+	html._secureForInnerHtml = function(/*String*/ cont){
 		// summary:
 		//		removes !DOCTYPE and title elements from the html string.
 		//
-		//		khtml is picky about dom faults, you can't attach a style or <title> node as child of body
+		//		khtml is picky about dom faults, you can't attach a style or `<title>` node as child of body
 		//		must go into head, so we need to cut out those tags
-		//	cont:
+		// cont:
 		//		An html string for insertion into the dom
 		//
 		return cont.replace(/(?:\s*<!DOCTYPE\s[^>]+>|<title[^>]*>[\s\S]*?<\/title>)/ig, ""); // String
 	};
 
-/*====
-	dojo.html._emptyNode = function(node){
-		// summary:
-		//		removes all child nodes from the given node
-		//	node: DOMNode
-		//		the parent element
-	};
-=====*/
-	dojo.html._emptyNode = domConstruct.empty;
-
-	dojo.html._setNodeContent = function(/* DomNode */ node, /* String|DomNode|NodeList */ cont){
+	html._emptyNode = domConstruct.empty;
+	/*=====
+	 dojo.html._emptyNode = function(node){
+		 // summary:
+		 //		Removes all child nodes from the given node.   Deprecated, should use dojo/dom-constuct.empty() directly
+		 //		instead.
+		 // node: DOMNode
+		 //		the parent element
+	 };
+	 =====*/
+
+		html._setNodeContent = function(/*DomNode*/ node, /*String|DomNode|NodeList*/ cont){
 		// summary:
 		//		inserts the given content into the given node
-		//	node:
+		// node:
 		//		the parent element
-		//	content:
+		// content:
 		//		the content to be set on the parent element.
-		//		This can be an html string, a node reference or a NodeList, dojo.NodeList, Array or other enumerable list of nodes
+		//		This can be an html string, a node reference or a NodeList, dojo/NodeList, Array or other enumerable list of nodes
 
 		// always empty
 		domConstruct.empty(node);
 
-		if(cont) {
-			if(typeof cont == "string") {
+		if(cont){
+			if(typeof cont == "string"){
 				cont = domConstruct.toDom(cont, node.ownerDocument);
 			}
-			if(!cont.nodeType && lang.isArrayLike(cont)) {
+			if(!cont.nodeType && lang.isArrayLike(cont)){
 				// handle as enumerable, but it may shrink as we enumerate it
-				for(var startlen=cont.length, i=0; i<cont.length; i=startlen==cont.length ? i+1 : 0) {
+				for(var startlen=cont.length, i=0; i<cont.length; i=startlen==cont.length ? i+1 : 0){
 					domConstruct.place( cont[i], node, "last");
 				}
-			} else {
+			}else{
 				// pass nodes, documentFragments and unknowns through to dojo.place
 				domConstruct.place(cont, node, "last");
 			}
@@ -65,7 +69,7 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 	};
 
 	// we wrap up the content-setting operation in a object
-	declare("dojo.html._ContentSetter", null,
+	html._ContentSetter = declare("dojo.html._ContentSetter", null,
 		{
 			// node: DomNode|String
 			//		An node which will be the parent element that we set content into
@@ -85,7 +89,8 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 			cleanContent: false,
 
 			// extractContent: Boolean
-			//		Should the content be treated as a full html document, and the real content stripped of <html>, <body> wrapper before injection
+			//		Should the content be treated as a full html document,
+			//		and the real content stripped of `<html> <body>` wrapper before injection
 			extractContent: false,
 
 			// parseContent: Boolean
@@ -97,15 +102,15 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 			//		will search for data-dojo-type (or dojoType).  For backwards compatibility
 			//		reasons defaults to dojo._scopeName (which is "dojo" except when
 			//		multi-version support is used, when it will be something like dojo16, dojo20, etc.)
-			parserScope: dojo._scopeName,
+			parserScope: kernel._scopeName,
 
 			// startup: Boolean
 			//		Start the child widgets after parsing them.	  Only obeyed if parseContent is true.
 			startup: true,
 
-			// lifecyle methods
-			constructor: function(/* Object */params, /* String|DomNode */node){
-				//	summary:
+			// lifecycle methods
+			constructor: function(/*Object*/ params, /*String|DomNode*/ node){
+				// summary:
 				//		Provides a configurable, extensible object to wrap the setting on content on a node
 				//		call the set() method to actually set the content..
 
@@ -124,10 +129,10 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 					].join("_");
 				}
 			},
-			set: function(/* String|DomNode|NodeList? */ cont, /* Object? */ params){
+			set: function(/* String|DomNode|NodeList? */ cont, /*Object?*/ params){
 				// summary:
 				//		front-end to the set-content sequence
-				//	cont:
+				// cont:
 				//		An html string, node or enumerable list of nodes for insertion into the dom
 				//		If not provided, the object's content property will be used
 				if(undefined !== cont){
@@ -140,21 +145,30 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 
 				this.onBegin();
 				this.setContent();
-				this.onEnd();
 
-				return this.node;
+				var ret = this.onEnd();
+
+				if(ret && ret.then){
+					// Make dojox/html/_ContentSetter.set() return a Promise that resolves when load and parse complete.
+					return ret;
+				}else{
+					// Vanilla dojo/html._ContentSetter.set() returns a DOMNode for back compat.   For 2.0, switch it to
+					// return a Deferred like above.
+					return this.node;
+				}
 			},
+
 			setContent: function(){
 				// summary:
 				//		sets the content on the node
 
 				var node = this.node;
-				if(!node) {
+				if(!node){
 					// can't proceed
 					throw new Error(this.declaredClass + ": setContent given no node");
 				}
 				try{
-					node = dojo.html._setNodeContent(node, this.content);
+					node = html._setNodeContent(node, this.content);
 				}catch(e){
 					// check if a domfault occurs when we are appending this.errorMessage
 					// like for instance if domNode is a UL and we try append a DIV
@@ -171,15 +185,23 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 				this.node = node; // DomNode
 			},
 
-			empty: function() {
-				// summary
-				//	cleanly empty out existing content
+			empty: function(){
+				// summary:
+				//		cleanly empty out existing content
+				
+				// If there is a parse in progress, cancel it.
+				if(this.parseDeferred){
+					if(!this.parseDeferred.isResolved()){
+						this.parseDeferred.cancel();
+					}
+					delete this.parseDeferred;
+				}
 
 				// destroy any widgets from a previous run
-				// NOTE: if you dont want this you'll need to empty
-				// the parseResults array property yourself to avoid bad things happenning
-				if(this.parseResults && this.parseResults.length) {
-					darray.forEach(this.parseResults, function(w) {
+				// NOTE: if you don't want this you'll need to empty
+				// the parseResults array property yourself to avoid bad things happening
+				if(this.parseResults && this.parseResults.length){
+					darray.forEach(this.parseResults, function(w){
 						if(w.destroy){
 							w.destroy();
 						}
@@ -188,21 +210,21 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 				}
 				// this is fast, but if you know its already empty or safe, you could
 				// override empty to skip this step
-				dojo.html._emptyNode(this.node);
+				domConstruct.empty(this.node);
 			},
 
 			onBegin: function(){
-				// summary
+				// summary:
 				//		Called after instantiation, but before set();
-				//		It allows modification of any of the object properties
-				//		- including the node and content provided - before the set operation actually takes place
+				//		It allows modification of any of the object properties -
+				//		including the node and content provided - before the set operation actually takes place
 				//		This default implementation checks for cleanContent and extractContent flags to
 				//		optionally pre-process html string content
 				var cont = this.content;
 
 				if(lang.isString(cont)){
 					if(this.cleanContent){
-						cont = dojo.html._secureForInnerHtml(cont);
+						cont = html._secureForInnerHtml(cont);
 					}
 
 					if(this.extractContent){
@@ -215,35 +237,41 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 				this.empty();
 
 				this.content = cont;
-				return this.node; /* DomNode */
+				return this.node; // DomNode
 			},
 
 			onEnd: function(){
-				// summary
+				// summary:
 				//		Called after set(), when the new content has been pushed into the node
 				//		It provides an opportunity for post-processing before handing back the node to the caller
 				//		This default implementation checks a parseContent flag to optionally run the dojo parser over the new content
 				if(this.parseContent){
-					// populates this.parseResults if you need those..
+					// populates this.parseResults and this.parseDeferred if you need those..
 					this._parse();
 				}
-				return this.node; /* DomNode */
+				return this.node; // DomNode
+				// TODO: for 2.0 return a Promise indicating that the parse completed.
 			},
 
 			tearDown: function(){
-				// summary
+				// summary:
 				//		manually reset the Setter instance if its being re-used for example for another set()
-				// description
+				// description:
 				//		tearDown() is not called automatically.
 				//		In normal use, the Setter instance properties are simply allowed to fall out of scope
 				//		but the tearDown method can be called to explicitly reset this instance.
 				delete this.parseResults;
+				delete this.parseDeferred;
 				delete this.node;
 				delete this.content;
 			},
 
 			onContentError: function(err){
-				return "Error occured setting content: " + err;
+				return "Error occurred setting content: " + err;
+			},
+
+			onExecError: function(err){
+				return "Error occurred executing scripts: " + err;
 			},
 
 			_mixin: function(params){
@@ -254,7 +282,7 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 				var empty = {}, key;
 				for(key in params){
 					if(key in empty){ continue; }
-					// TODO: here's our opportunity to mask the properties we dont consider configurable/overridable
+					// TODO: here's our opportunity to mask the properties we don't consider configurable/overridable
 					// .. but history shows we'll almost always guess wrong
 					this[key] = params[key];
 				}
@@ -262,6 +290,7 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 			_parse: function(){
 				// summary:
 				//		runs the dojo parser over the node contents, storing any results in this.parseResults
+				//		and the parse promise in this.parseDeferred
 				//		Any errors resulting from parsing are passed to _onError for handling
 
 				var rootNode = this.node;
@@ -273,31 +302,36 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 							inherited[name] = this[name];
 						}
 					}, this);
-					this.parseResults = parser.parse({
+					var self = this;
+					this.parseDeferred = parser.parse({
 						rootNode: rootNode,
 						noStart: !this.startup,
 						inherited: inherited,
 						scope: this.parserScope
+					}).then(function(results){
+						return self.parseResults = results;
+					}, function(e){
+						self._onError('Content', e, "Error parsing in _ContentSetter#" + this.id);
 					});
 				}catch(e){
-					this._onError('Content', e, "Error parsing in _ContentSetter#"+this.id);
+					this._onError('Content', e, "Error parsing in _ContentSetter#" + this.id);
 				}
 			},
 
 			_onError: function(type, err, consoleText){
 				// summary:
 				//		shows user the string that is returned by on[type]Error
-				//		overide/implement on[type]Error and return your own string to customize
+				//		override/implement on[type]Error and return your own string to customize
 				var errText = this['on' + type + 'Error'].call(this, err);
 				if(consoleText){
 					console.error(consoleText, err);
 				}else if(errText){ // a empty string won't change current content
-					dojo.html._setNodeContent(this.node, errText, true);
+					html._setNodeContent(this.node, errText, true);
 				}
 			}
-	}); // end dojo.declare()
+	}); // end declare()
 
-	dojo.html.set = function(/* DomNode */ node, /* String|DomNode|NodeList */ cont, /* Object? */ params){
+	html.set = function(/*DomNode*/ node, /*String|DomNode|NodeList*/ cont, /*Object?*/ params){
 			// summary:
 			//		inserts (replaces) the given content into the given node. dojo.place(cont, node, "only")
 			//		may be a better choice for simple HTML insertion.
@@ -307,30 +341,30 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 			//		an HTML string into the DOM, but it only handles inserting an HTML string as DOM
 			//		elements, or inserting a DOM node. dojo.place does not handle NodeList insertions
 			//		or the other capabilities as defined by the params object for this method.
-			//	node:
+			// node:
 			//		the parent element that will receive the content
-			//	cont:
+			// cont:
 			//		the content to be set on the parent element.
-			//		This can be an html string, a node reference or a NodeList, dojo.NodeList, Array or other enumerable list of nodes
-			//	params:
-			//		Optional flags/properties to configure the content-setting. See dojo.html._ContentSetter
-			//	example:
+			//		This can be an html string, a node reference or a NodeList, dojo/NodeList, Array or other enumerable list of nodes
+			// params:
+			//		Optional flags/properties to configure the content-setting. See dojo/html/_ContentSetter
+			// example:
 			//		A safe string/node/nodelist content replacement/injection with hooks for extension
 			//		Example Usage:
-			//		dojo.html.set(node, "some string");
-			//		dojo.html.set(node, contentNode, {options});
-			//		dojo.html.set(node, myNode.childNodes, {options});
+			//	|	html.set(node, "some string");
+			//	|	html.set(node, contentNode, {options});
+			//	|	html.set(node, myNode.childNodes, {options});
 		if(undefined == cont){
 			console.warn("dojo.html.set: no cont argument provided, using empty string");
 			cont = "";
 		}
 		if(!params){
 			// simple and fast
-			return dojo.html._setNodeContent(node, cont, true);
+			return html._setNodeContent(node, cont, true);
 		}else{
 			// more options but slower
 			// note the arguments are reversed in order, to match the convention for instantiation via the parser
-			var op = new dojo.html._ContentSetter(lang.mixin(
+			var op = new html._ContentSetter(lang.mixin(
 					params,
 					{ content: cont, node: node }
 			));
@@ -338,5 +372,5 @@ define(["./_base/kernel", "./_base/lang", "./_base/array", "./_base/declare", ".
 		}
 	};
 
-	return dojo.html;
+	return html;
 });
diff --git a/dojo/i18n.js b/dojo/i18n.js
index e916486..2cb04e4 100644
--- a/dojo/i18n.js
+++ b/dojo/i18n.js
@@ -1,19 +1,31 @@
-define(["./_base/kernel", "require", "./has", "./_base/array", "./_base/config", "./_base/lang", "./_base/xhr"],
-	function(dojo, require, has, array, config, lang, xhr) {
+define(["./_base/kernel", "require", "./has", "./_base/array", "./_base/config", "./_base/lang", "./has!host-browser?./_base/xhr", "./json", "module"],
+	function(dojo, require, has, array, config, lang, xhr, json, module){
+
 	// module:
 	//		dojo/i18n
-	// summary:
-	//		This module implements the !dojo/i18n plugin and the v1.6- i18n API
-	// description:
-	//		We choose to include our own plugin to leverage functionality already contained in dojo
-	//		and thereby reduce the size of the plugin compared to various loader implementations. Also, this
-	//		allows foreign AMD loaders to be used without their plugins.
+
+	has.add("dojo-preload-i18n-Api",
+		// if true, define the preload localizations machinery
+		1
+	);
+
+	has.add("dojo-v1x-i18n-Api",
+		// if true, define the v1.x i18n functions
+		1
+	);
+
 	var
-		thisModule= dojo.i18n=
-			// the dojo.i18n module
-			{},
+		thisModule = dojo.i18n =
+			{
+				// summary:
+				//		This module implements the dojo/i18n! plugin and the v1.6- i18n API
+				// description:
+				//		We choose to include our own plugin to leverage functionality already contained in dojo
+				//		and thereby reduce the size of the plugin compared to various loader implementations. Also, this
+				//		allows foreign AMD loaders to be used without their plugins.
+			},
 
-		nlsRe=
+		nlsRe =
 			// regexp for reconstructing the master bundle name from parts of the regexp match
 			// nlsRe.exec("foo/bar/baz/nls/en-ca/foo") gives:
 			// ["foo/bar/baz/nls/en-ca/foo", "foo/bar/baz/nls/", "/", "/", "en-ca", "foo"]
@@ -23,111 +35,255 @@ define(["./_base/kernel", "require", "./has", "./_base/array", "./_base/config",
 			// courtesy of http://requirejs.org
 			/(^.*(^|\/)nls)(\/|$)([^\/]*)\/?([^\/]*)/,
 
-		getAvailableLocales= function(
+		getAvailableLocales = function(
 			root,
 			locale,
 			bundlePath,
 			bundleName
 		){
-			// return a vector of module ids containing all available locales with respect to the target locale
-			// For example, assuming:
-			//	 * the root bundle indicates specific bundles for "fr" and "fr-ca",
-			//	 * bundlePath is "myPackage/nls"
-			//	 * bundleName is "myBundle"
-			// Then a locale argument of "fr-ca" would return
-			//	 ["myPackage/nls/myBundle", "myPackage/nls/fr/myBundle", "myPackage/nls/fr-ca/myBundle"]
-			// Notice that bundles are returned least-specific to most-specific, starting with the root.
+			// summary:
+			//		return a vector of module ids containing all available locales with respect to the target locale
+			//		For example, assuming:
+			//
+			//		- the root bundle indicates specific bundles for "fr" and "fr-ca",
+			//		-  bundlePath is "myPackage/nls"
+			//		- bundleName is "myBundle"
 			//
-			// If root===false indicates we're working with a pre-AMD i18n bundle that doesn't tell about the available locales;
-			// therefore, assume everything is available and get 404 errors that indicate a particular localization is not available
+			//		Then a locale argument of "fr-ca" would return
 			//
+			//			["myPackage/nls/myBundle", "myPackage/nls/fr/myBundle", "myPackage/nls/fr-ca/myBundle"]
+			//
+			//		Notice that bundles are returned least-specific to most-specific, starting with the root.
+			//
+			//		If root===false indicates we're working with a pre-AMD i18n bundle that doesn't tell about the available locales;
+			//		therefore, assume everything is available and get 404 errors that indicate a particular localization is not available
 
-			for(var result= [bundlePath + bundleName], localeParts= locale.split("-"), current= "", i= 0; i<localeParts.length; i++){
-				current+= (current ? "-" : "") + localeParts[i];
+			for(var result = [bundlePath + bundleName], localeParts = locale.split("-"), current = "", i = 0; i<localeParts.length; i++){
+				current += (current ? "-" : "") + localeParts[i];
 				if(!root || root[current]){
 					result.push(bundlePath + current + "/" + bundleName);
+					result.specificity = current;
 				}
 			}
 			return result;
 		},
 
-		cache= {},
+		cache = {},
 
-		getL10nName= dojo.getL10nName = function(moduleName, bundleName, locale){
+		getBundleName = function(moduleName, bundleName, locale){
 			locale = locale ? locale.toLowerCase() : dojo.locale;
-			moduleName = "dojo/i18n!" + moduleName.replace(/\./g, "/");
+			moduleName = moduleName.replace(/\./g, "/");
 			bundleName = bundleName.replace(/\./g, "/");
 			return (/root/i.test(locale)) ?
 				(moduleName + "/nls/" + bundleName) :
 				(moduleName + "/nls/" + locale + "/" + bundleName);
 		},
 
+		getL10nName = dojo.getL10nName = function(moduleName, bundleName, locale){
+			return moduleName = module.id + "!" + getBundleName(moduleName, bundleName, locale);
+		},
+
 		doLoad = function(require, bundlePathAndName, bundlePath, bundleName, locale, load){
-			// get the root bundle which instructs which other bundles are required to construct the localized bundle
+			// summary:
+			//		get the root bundle which instructs which other bundles are required to construct the localized bundle
 			require([bundlePathAndName], function(root){
-				var
-					current= cache[bundlePathAndName + "/"]= lang.clone(root.root),
-					availableLocales= getAvailableLocales(!root._v1x && root, locale, bundlePath, bundleName);
+				var current = lang.clone(root.root),
+					availableLocales = getAvailableLocales(!root._v1x && root, locale, bundlePath, bundleName);
 				require(availableLocales, function(){
-					for (var i= 1; i<availableLocales.length; i++){
-						cache[availableLocales[i]]= current= lang.mixin(lang.clone(current), arguments[i]);
+					for (var i = 1; i<availableLocales.length; i++){
+						current = lang.mixin(lang.clone(current), arguments[i]);
 					}
 					// target may not have been resolve (e.g., maybe only "fr" exists when "fr-ca" was requested)
-					var target= bundlePathAndName + "/" + locale;
-					cache[target]= current;
-					load && load(lang.delegate(current));
+					var target = bundlePathAndName + "/" + locale;
+					cache[target] = current;
+					current.$locale = availableLocales.specificity;
+					load();
 				});
 			});
 		},
 
 		normalize = function(id, toAbsMid){
-			// note: id may be relative
-			var match= nlsRe.exec(id),
-				bundlePath= match[1];
-			return /^\./.test(bundlePath) ? toAbsMid(bundlePath) + "/" +  id.substring(bundlePath.length) : id;
+			// summary:
+			//		id may be relative.
+			//		preload has form `*preload*<path>/nls/<module>*<flattened locales>` and
+			//		therefore never looks like a relative
+			return /^\./.test(id) ? toAbsMid(id) : id;
 		},
 
-		checkForLegacyModules = function(){},
+		getLocalesToLoad = function(targetLocale){
+			var list = config.extraLocale || [];
+			list = lang.isArray(list) ? list : [list];
+			list.push(targetLocale);
+			return list;
+		},
 
 		load = function(id, require, load){
-			// note: id is always absolute
-			var
-				match= nlsRe.exec(id),
-				bundlePath= match[1] + "/",
-				bundleName= match[5] || match[4],
-				bundlePathAndName= bundlePath + bundleName,
-				localeSpecified = (match[5] && match[4]),
-				targetLocale=  localeSpecified || dojo.locale,
-				target= bundlePathAndName + "/" + targetLocale;
-
-			if(localeSpecified){
-				checkForLegacyModules(target);
-				if(cache[target]){
-					// a request for a specific local that has already been loaded; just return it
-					load(cache[target]);
-				}else{
-					// a request for a specific local that has not been loaded; load and return just that locale
-					doLoad(require, bundlePathAndName, bundlePath, bundleName, targetLocale, load);
-				}
-				return;
-			}// else a non-locale-specific request; therefore always load dojo.locale + config.extraLocale
-
-			// notice the subtle algorithm that loads targetLocal last, which is the only doLoad application that passes a value for the load callback
-			// this makes the sync loader follow a clean code path that loads extras first and then proceeds with tracing the current deps graph
-			var extra = config.extraLocale || [];
-			extra = lang.isArray(extra) ? extra : [extra];
-			extra.push(targetLocale);
-			var remaining = extra.length,
-				targetBundle;
-			array.forEach(extra, function(locale){
-				doLoad(require, bundlePathAndName, bundlePath, bundleName, locale, function(bundle){
-					if(locale == targetLocale){
-						targetBundle = bundle;
+			// summary:
+			//		id is in one of the following formats
+			//
+			//		1. <path>/nls/<bundle>
+			//			=> load the bundle, localized to config.locale; load all bundles localized to
+			//			config.extraLocale (if any); return the loaded bundle localized to config.locale.
+			//
+			//		2. <path>/nls/<locale>/<bundle>
+			//			=> load then return the bundle localized to <locale>
+			//
+			//		3. *preload*<path>/nls/<module>*<JSON array of available locales>
+			//			=> for config.locale and all config.extraLocale, load all bundles found
+			//			in the best-matching bundle rollup. A value of 1 is returned, which
+			//			is meaningless other than to say the plugin is executing the requested
+			//			preloads
+			//
+			//		In cases 1 and 2, <path> is always normalized to an absolute module id upon entry; see
+			//		normalize. In case 3, it <path> is assumed to be absolute; this is arranged by the builder.
+			//
+			//		To load a bundle means to insert the bundle into the plugin's cache and publish the bundle
+			//		value to the loader. Given <path>, <bundle>, and a particular <locale>, the cache key
+			//
+			//			<path>/nls/<bundle>/<locale>
+			//
+			//		will hold the value. Similarly, then plugin will publish this value to the loader by
+			//
+			//			define("<path>/nls/<bundle>/<locale>", <bundle-value>);
+			//
+			//		Given this algorithm, other machinery can provide fast load paths be preplacing
+			//		values in the plugin's cache, which is public. When a load is demanded the
+			//		cache is inspected before starting any loading. Explicitly placing values in the plugin
+			//		cache is an advanced/experimental feature that should not be needed; use at your own risk.
+			//
+			//		For the normal AMD algorithm, the root bundle is loaded first, which instructs the
+			//		plugin what additional localized bundles are required for a particular locale. These
+			//		additional locales are loaded and a mix of the root and each progressively-specific
+			//		locale is returned. For example:
+			//
+			//		1. The client demands "dojo/i18n!some/path/nls/someBundle
+			//
+			//		2. The loader demands load(some/path/nls/someBundle)
+			//
+			//		3. This plugin require's "some/path/nls/someBundle", which is the root bundle.
+			//
+			//		4. Assuming config.locale is "ab-cd-ef" and the root bundle indicates that localizations
+			//		are available for "ab" and "ab-cd-ef" (note the missing "ab-cd", then the plugin
+			//		requires "some/path/nls/ab/someBundle" and "some/path/nls/ab-cd-ef/someBundle"
+			//
+			//		5. Upon receiving all required bundles, the plugin constructs the value of the bundle
+			//		ab-cd-ef as...
+			//
+			//				mixin(mixin(mixin({}, require("some/path/nls/someBundle"),
+			//		  			require("some/path/nls/ab/someBundle")),
+			//					require("some/path/nls/ab-cd-ef/someBundle"));
+			//
+			//		This value is inserted into the cache and published to the loader at the
+			//		key/module-id some/path/nls/someBundle/ab-cd-ef.
+			//
+			//		The special preload signature (case 3) instructs the plugin to stop servicing all normal requests
+			//		(further preload requests will be serviced) until all ongoing preloading has completed.
+			//
+			//		The preload signature instructs the plugin that a special rollup module is available that contains
+			//		one or more flattened, localized bundles. The JSON array of available locales indicates which locales
+			//		are available. Here is an example:
+			//
+			//			*preload*some/path/nls/someModule*["root", "ab", "ab-cd-ef"]
+			//
+			//		This indicates the following rollup modules are available:
+			//
+			//			some/path/nls/someModule_ROOT
+			//			some/path/nls/someModule_ab
+			//			some/path/nls/someModule_ab-cd-ef
+			//
+			//		Each of these modules is a normal AMD module that contains one or more flattened bundles in a hash.
+			//		For example, assume someModule contained the bundles some/bundle/path/someBundle and
+			//		some/bundle/path/someOtherBundle, then some/path/nls/someModule_ab would be expressed as follows:
+			//
+			//			define({
+			//				some/bundle/path/someBundle:<value of someBundle, flattened with respect to locale ab>,
+			//				some/bundle/path/someOtherBundle:<value of someOtherBundle, flattened with respect to locale ab>,
+			//			});
+			//
+			//		E.g., given this design, preloading for locale=="ab" can execute the following algorithm:
+			//
+			//			require(["some/path/nls/someModule_ab"], function(rollup){
+			//				for(var p in rollup){
+			//					var id = p + "/ab",
+			//					cache[id] = rollup[p];
+			//					define(id, rollup[p]);
+			//				}
+			//			});
+			//
+			//		Similarly, if "ab-cd" is requested, the algorithm can determine that "ab" is the best available and
+			//		load accordingly.
+			//
+			//		The builder will write such rollups for every layer if a non-empty localeList  profile property is
+			//		provided. Further, the builder will include the following cache entry in the cache associated with
+			//		any layer.
+			//
+			//			"*now":function(r){r(['dojo/i18n!*preload*<path>/nls/<module>*<JSON array of available locales>']);}
+			//
+			//		The *now special cache module instructs the loader to apply the provided function to context-require
+			//		with respect to the particular layer being defined. This causes the plugin to hold all normal service
+			//		requests until all preloading is complete.
+			//
+			//		Notice that this algorithm is rarely better than the standard AMD load algorithm. Consider the normal case
+			//		where the target locale has a single segment and a layer depends on a single bundle:
+			//
+			//		Without Preloads:
+			//
+			//		1. Layer loads root bundle.
+			//		2. bundle is demanded; plugin loads single localized bundle.
+			//
+			//		With Preloads:
+			//
+			//		1. Layer causes preloading of target bundle.
+			//		2. bundle is demanded; service is delayed until preloading complete; bundle is returned.
+			//
+			//		In each case a single transaction is required to load the target bundle. In cases where multiple bundles
+			//		are required and/or the locale has multiple segments, preloads still requires a single transaction whereas
+			//		the normal path requires an additional transaction for each additional bundle/locale-segment. However all
+			//		of these additional transactions can be done concurrently. Owing to this analysis, the entire preloading
+			//		algorithm can be discard during a build by setting the has feature dojo-preload-i18n-Api to false.
+
+			if(has("dojo-preload-i18n-Api")){
+				var split = id.split("*"),
+					preloadDemand = split[1] == "preload";
+				if(preloadDemand){
+					if(!cache[id]){
+						// use cache[id] to prevent multiple preloads of the same preload; this shouldn't happen, but
+						// who knows what over-aggressive human optimizers may attempt
+						cache[id] = 1;
+						preloadL10n(split[2], json.parse(split[3]), 1, require);
 					}
+					// don't stall the loader!
+					load(1);
+				}
+				if(preloadDemand || waitForPreloads(id, require, load)){
+					return;
+				}
+			}
+
+			var match = nlsRe.exec(id),
+				bundlePath = match[1] + "/",
+				bundleName = match[5] || match[4],
+				bundlePathAndName = bundlePath + bundleName,
+				localeSpecified = (match[5] && match[4]),
+				targetLocale =	localeSpecified || dojo.locale || "",
+				loadTarget = bundlePathAndName + "/" + targetLocale,
+				loadList = localeSpecified ? [targetLocale] : getLocalesToLoad(targetLocale),
+				remaining = loadList.length,
+				finish = function(){
 					if(!--remaining){
-						load(targetBundle);
+						load(lang.delegate(cache[loadTarget]));
 					}
-				});
+				};
+			array.forEach(loadList, function(locale){
+				var target = bundlePathAndName + "/" + locale;
+				if(has("dojo-preload-i18n-Api")){
+					checkForLegacyModules(target);
+				}
+				if(!cache[target]){
+					doLoad(require, bundlePathAndName, bundlePath, bundleName, locale, finish);
+				}else{
+					finish();
+				}
 			});
 		};
 
@@ -135,128 +291,226 @@ define(["./_base/kernel", "require", "./has", "./_base/array", "./_base/config",
 		var unitTests = thisModule.unitTests = [];
 	}
 
-	has.add("dojo-v1x-i18n-Api",
-		// if true, define the v1.x i18n functions
-		1
-	);
+	if(has("dojo-preload-i18n-Api") || has("dojo-v1x-i18n-Api")){
+		var normalizeLocale = thisModule.normalizeLocale = function(locale){
+				var result = locale ? locale.toLowerCase() : dojo.locale;
+				return result == "root" ? "ROOT" : result;
+			},
 
-	if(has("dojo-v1x-i18n-Api")){
-		var
-			__evalError = {},
-
-			evalBundle=
-				// use the function ctor to keep the minifiers away and come close to global scope
-				// if bundle is an AMD bundle, then __amdResult will be defined; otherwise it's a pre-amd bundle and the bundle value is returned by eval
-				new Function("bundle, __evalError",
-					"var __amdResult, define = function(x){__amdResult= x;};" +
-					"return [(function(){" +
-								"try{eval(arguments[0]);}catch(e){}" +
-								"if(__amdResult)return 0;" +
-								"try{return eval('('+arguments[0]+')');}" +
-								"catch(e){__evalError.e = e; return __evalError;}" +
-							"})(arguments[0]) , __amdResult];"
-				),
+			isXd = function(mid, contextRequire){
+				return (has("dojo-sync-loader") && has("dojo-v1x-i18n-Api")) ?
+					contextRequire.isXdUrl(require.toUrl(mid + ".js")) :
+					true;
+			},
+
+			preloading = 0,
+
+			preloadWaitQueue = [],
+
+			preloadL10n = thisModule._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated, /*boolean?*/ guaranteedAmdFormat, /*function?*/ contextRequire){
+				// summary:
+				//		Load available flattened resource bundles associated with a particular module for dojo/locale and all dojo/config.extraLocale (if any)
+				// description:
+				//		Only called by built layer files. The entire locale hierarchy is loaded. For example,
+				//		if locale=="ab-cd", then ROOT, "ab", and "ab-cd" are loaded. This is different than v1.6-
+				//		in that the v1.6- would only load ab-cd...which was *always* flattened.
+				//
+				//		If guaranteedAmdFormat is true, then the module can be loaded with require thereby circumventing the detection algorithm
+				//		and the extra possible extra transaction.
+
+				// If this function is called from legacy code, then guaranteedAmdFormat and contextRequire will be undefined. Since the function
+				// needs a require in order to resolve module ids, fall back to the context-require associated with this dojo/i18n module, which
+				// itself may have been mapped.
+				contextRequire = contextRequire || require;
+
+				function doRequire(mid, callback){
+					if(isXd(mid, contextRequire) || guaranteedAmdFormat){
+						contextRequire([mid], callback);
+					}else{
+						syncRequire([mid], callback, contextRequire);
+					}
+				}
+
+				function forEachLocale(locale, func){
+					// given locale= "ab-cd-ef", calls func on "ab-cd-ef", "ab-cd", "ab", "ROOT"; stops calling the first time func returns truthy
+					var parts = locale.split("-");
+					while(parts.length){
+						if(func(parts.join("-"))){
+							return;
+						}
+						parts.pop();
+					}
+					func("ROOT");
+				}
 
-			fixup= function(url, preAmdResult, amdResult){
-				// nls/<locale>/<bundle-name> indicates not the root.
-				if(preAmdResult===__evalError){
-					console.error("failed to evaluate i18n bundle; url=" + url, __evalError.e);
-					return {};
+				function preload(locale){
+					locale = normalizeLocale(locale);
+					forEachLocale(locale, function(loc){
+						if(array.indexOf(localesGenerated, loc)>=0){
+							var mid = bundlePrefix.replace(/\./g, "/")+"_"+loc;
+							preloading++;
+							doRequire(mid, function(rollup){
+								for(var p in rollup){
+									cache[require.toAbsMid(p) + "/" + loc] = rollup[p];
+								}
+								--preloading;
+								while(!preloading && preloadWaitQueue.length){
+									load.apply(null, preloadWaitQueue.shift());
+								}
+							});
+							return true;
+						}
+						return false;
+					});
 				}
-				return preAmdResult ? (/nls\/[^\/]+\/[^\/]+$/.test(url) ? preAmdResult : {root:preAmdResult, _v1x:1}) : amdResult;
+
+				preload();
+				array.forEach(dojo.config.extraLocale, preload);
+			},
+
+			waitForPreloads = function(id, require, load){
+				if(preloading){
+					preloadWaitQueue.push([id, require, load]);
+				}
+				return preloading;
 			},
 
-			syncRequire= function(deps, callback){
-				var results= [];
+			checkForLegacyModules = function()
+				{};
+	}
+
+	if(has("dojo-v1x-i18n-Api")){
+		// this code path assumes the dojo loader and won't work with a standard AMD loader
+		var amdValue = {},
+			evalBundle =
+				// use the function ctor to keep the minifiers away (also come close to global scope, but this is secondary)
+				new Function(
+					"__bundle",				   // the bundle to evalutate
+					"__checkForLegacyModules", // a function that checks if __bundle defined __mid in the global space
+					"__mid",				   // the mid that __bundle is intended to define
+					"__amdValue",
+
+					// returns one of:
+					//		1 => the bundle was an AMD bundle
+					//		a legacy bundle object that is the value of __mid
+					//		instance of Error => could not figure out how to evaluate bundle
+
+					  // used to detect when __bundle calls define
+					  "var define = function(mid, factory){define.called = 1; __amdValue.result = factory || mid;},"
+					+ "	   require = function(){define.called = 1;};"
+
+					+ "try{"
+					+		"define.called = 0;"
+					+		"eval(__bundle);"
+					+		"if(define.called==1)"
+								// bundle called define; therefore signal it's an AMD bundle
+					+			"return __amdValue;"
+
+					+		"if((__checkForLegacyModules = __checkForLegacyModules(__mid)))"
+								// bundle was probably a v1.6- built NLS flattened NLS bundle that defined __mid in the global space
+					+			"return __checkForLegacyModules;"
+
+					+ "}catch(e){}"
+					// evaulating the bundle was *neither* an AMD *nor* a legacy flattened bundle
+					// either way, re-eval *after* surrounding with parentheses
+
+					+ "try{"
+					+		"return eval('('+__bundle+')');"
+					+ "}catch(e){"
+					+		"return e;"
+					+ "}"
+				),
+
+			syncRequire = function(deps, callback, require){
+				var results = [];
 				array.forEach(deps, function(mid){
-					var url= require.toUrl(mid + ".js");
+					var url = require.toUrl(mid + ".js");
+
+					function load(text){
+						var result = evalBundle(text, checkForLegacyModules, mid, amdValue);
+						if(result===amdValue){
+							// the bundle was an AMD module; re-inject it through the normal AMD path
+							// we gotta do this since it could be an anonymous module and simply evaluating
+							// the text here won't provide the loader with the context to know what
+							// module is being defined()'d. With browser caching, this should be free; further
+							// this entire code path can be circumvented by using the AMD format to begin with
+							results.push(cache[url] = amdValue.result);
+						}else{
+							if(result instanceof Error){
+								console.error("failed to evaluate i18n bundle; url=" + url, result);
+								result = {};
+							}
+							// nls/<locale>/<bundle-name> indicates not the root.
+							results.push(cache[url] = (/nls\/[^\/]+\/[^\/]+$/.test(url) ? result : {root:result, _v1x:1}));
+						}
+					}
+
 					if(cache[url]){
 						results.push(cache[url]);
 					}else{
-
-						try {
-							var bundle= require(mid);
-							if(bundle){
-								results.push(bundle);
-								return;
-							}
-						}catch(e){}
-
-						xhr.get({
-							url:url,
-							sync:true,
-							load:function(text){
-								var result = evalBundle(text, __evalError);
-								results.push(cache[url]= fixup(url, result[0], result[1]));
-							},
-							error:function(){
-								results.push(cache[url]= {});
+						var bundle = require.syncLoadNls(mid);
+						// don't need to check for legacy since syncLoadNls returns a module if the module
+						// (1) was already loaded, or (2) was in the cache. In case 1, if syncRequire is called
+						// from getLocalization --> load, then load will have called checkForLegacyModules() before
+						// calling syncRequire; if syncRequire is called from preloadLocalizations, then we
+						// don't care about checkForLegacyModules() because that will be done when a particular
+						// bundle is actually demanded. In case 2, checkForLegacyModules() is never relevant
+						// because cached modules are always v1.7+ built modules.
+						if(bundle){
+							results.push(bundle);
+						}else{
+							if(!xhr){
+								try{
+									require.getText(url, true, load);
+								}catch(e){
+									results.push(cache[url] = {});
+								}
+							}else{
+								xhr.get({
+									url:url,
+									sync:true,
+									load:load,
+									error:function(){
+										results.push(cache[url] = {});
+									}
+								});
 							}
-						});
+						}
 					}
 				});
 				callback && callback.apply(null, results);
-			},
-
-			normalizeLocale = thisModule.normalizeLocale= function(locale){
-				var result = locale ? locale.toLowerCase() : dojo.locale;
-				if(result == "root"){
-					result = "ROOT";
-				}
-				return result;
-			},
-
-			forEachLocale = function(locale, func){
-				// this function is equivalent to v1.6 dojo.i18n._searchLocalePath with down===true
-				var parts = locale.split("-");
-				while(parts.length){
-					if(func(parts.join("-"))){
-						return true;
-					}
-					parts.pop();
-				}
-				return func("ROOT");
 			};
 
 		checkForLegacyModules = function(target){
 			// legacy code may have already loaded [e.g] the raw bundle x/y/z at x.y.z; when true, push into the cache
-			for(var names = target.split("/"), object = dojo.global[names[0]], i = 1; object && i<names.length; object = object[names[i++]]){}
+			for(var result, names = target.split("/"), object = dojo.global[names[0]], i = 1; object && i<names.length-1; object = object[names[i++]]){}
 			if(object){
-				cache[target] = object;
+				result = object[names[i]];
+				if(!result){
+					// fallback for incorrect bundle build of 1.6
+					result = object[names[i].replace(/-/g,"_")];
+				}
+				if(result){
+					cache[target] = result;
+				}
 			}
+			return result;
 		};
 
-		thisModule.getLocalization= function(moduleName, bundleName, locale){
+		thisModule.getLocalization = function(moduleName, bundleName, locale){
 			var result,
-				l10nName= getL10nName(moduleName, bundleName, locale).substring(10);
-			load(l10nName, (has("dojo-sync-loader") && !require.isXdUrl(require.toUrl(l10nName + ".js")) ? syncRequire : require), function(result_){ result= result_; });
-			return result;
-		};
+				l10nName = getBundleName(moduleName, bundleName, locale);
+			load(
+				l10nName,
 
-		thisModule._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/localesGenerated){
-			//	summary:
-			//		Load built, flattened resource bundles, if available for all
-			//		locales used in the page. Only called by built layer files.
-			//
-			//  note: this function a direct copy of v1.6 function of same name
+				// isXd() and syncRequire() need a context-require in order to resolve the mid with respect to a reference module.
+				// Since this legacy function does not have the concept of a reference module, resolve with respect to this
+				// dojo/i18n module, which, itself may have been mapped.
+				(!isXd(l10nName, require) ? function(deps, callback){ syncRequire(deps, callback, require); } : require),
 
-			function preload(locale){
-				locale = normalizeLocale(locale);
-				forEachLocale(locale, function(loc){
-					for(var i=0; i<localesGenerated.length;i++){
-						if(localesGenerated[i] == loc){
-							syncRequire([bundlePrefix.replace(/\./g, "/")+"_"+loc]);
-							return true; // Boolean
-						}
-					}
-					return false; // Boolean
-				});
-			}
-			preload();
-			var extra = dojo.config.extraLocale||[];
-			for(var i=0; i<extra.length; i++){
-				preload(extra[i]);
-			}
+				function(result_){ result = result_; }
+			);
+			return result;
 		};
 
 		if(has("dojo-unit-tests")){
@@ -264,27 +518,26 @@ define(["./_base/kernel", "require", "./has", "./_base/array", "./_base/config",
 				doh.register("tests.i18n.unit", function(t){
 					var check;
 
-					check = evalBundle("{prop:1}", __evalError);
-					t.is({prop:1}, check[0]); t.is(undefined, check[1]);
+					check = evalBundle("{prop:1}", checkForLegacyModules, "nonsense", amdValue);
+					t.is({prop:1}, check); t.is(undefined, check[1]);
 
-					check = evalBundle("({prop:1})", __evalError);
-					t.is({prop:1}, check[0]); t.is(undefined, check[1]);
+					check = evalBundle("({prop:1})", checkForLegacyModules, "nonsense", amdValue);
+					t.is({prop:1}, check); t.is(undefined, check[1]);
 
-					check = evalBundle("{'prop-x':1}", __evalError);
-					t.is({'prop-x':1}, check[0]); t.is(undefined, check[1]);
+					check = evalBundle("{'prop-x':1}", checkForLegacyModules, "nonsense", amdValue);
+					t.is({'prop-x':1}, check); t.is(undefined, check[1]);
 
-					check = evalBundle("({'prop-x':1})", __evalError);
-					t.is({'prop-x':1}, check[0]); t.is(undefined, check[1]);
+					check = evalBundle("({'prop-x':1})", checkForLegacyModules, "nonsense", amdValue);
+					t.is({'prop-x':1}, check); t.is(undefined, check[1]);
 
-					check = evalBundle("define({'prop-x':1})", __evalError);
-					t.is(0, check[0]); t.is({'prop-x':1}, check[1]);
+					check = evalBundle("define({'prop-x':1})", checkForLegacyModules, "nonsense", amdValue);
+					t.is(amdValue, check); t.is({'prop-x':1}, amdValue.result);
 
-					check = evalBundle("define({'prop-x':1});", __evalError);
-					t.is(0, check[0]); t.is({'prop-x':1}, check[1]);
+					check = evalBundle("define('some/module', {'prop-x':1})", checkForLegacyModules, "nonsense", amdValue);
+					t.is(amdValue, check); t.is({'prop-x':1}, amdValue.result);
 
-					check = evalBundle("this is total nonsense and should throw an error", __evalError);
-					t.is(__evalError, check[0]); t.is(undefined, check[1]);
-					t.is({}, fixup("some/url", check[0], check[1]));
+					check = evalBundle("this is total nonsense and should throw an error", checkForLegacyModules, "nonsense", amdValue);
+					t.is(check instanceof Error, true);
 				});
 			});
 		}
@@ -294,8 +547,7 @@ define(["./_base/kernel", "require", "./has", "./_base/array", "./_base/config",
 		dynamic:true,
 		normalize:normalize,
 		load:load,
-		cache:function(mid, value){
-			cache[mid] = value;
-		}
+		cache:cache,
+		getL10nName: getL10nName
 	});
 });
diff --git a/dojo/io-query.js b/dojo/io-query.js
index 2fa6be5..f8cf1e1 100644
--- a/dojo/io-query.js
+++ b/dojo/io-query.js
@@ -1,13 +1,16 @@
 define(["./_base/lang"], function(lang){
-	// module:
-	//		dojo/io-query
-	// summary:
-	//		This module defines query string processing functions.
 
-    var backstop = {};
+// module:
+//		dojo/io-query
 
-    function objectToQuery(/*Object*/ map){
-        // summary:
+var backstop = {};
+
+return {
+// summary:
+//		This module defines query string processing functions.
+
+	objectToQuery: function objectToQuery(/*Object*/ map){
+		// summary:
         //		takes a name/value mapping object and returns a string representing
         //		a URL-encoded version of that object.
         // example:
@@ -21,7 +24,7 @@ define(["./_base/lang"], function(lang){
         //	|		]
         //	|	};
         //
-        // yields the following query string:
+        //		yields the following query string:
         //
         //	|	"blah=blah&multi=thud&multi=thonk"
 
@@ -41,9 +44,9 @@ define(["./_base/lang"], function(lang){
             }
         }
         return pairs.join("&"); // String
-    }
+    },
 
-    function queryToObject(/*String*/ str){
+	queryToObject: function queryToObject(/*String*/ str){
         // summary:
         //		Create an object representing a de-serialized query section of a
         //		URL. Query keys with multiple values are returned in an array.
@@ -90,9 +93,5 @@ define(["./_base/lang"], function(lang){
         }
         return ret; // Object
     }
-
-    return {
-        objectToQuery: objectToQuery,
-        queryToObject: queryToObject
-    };
+};
 });
\ No newline at end of file
diff --git a/dojo/io/iframe.js b/dojo/io/iframe.js
index ac5fdde..81234d9 100644
--- a/dojo/io/iframe.js
+++ b/dojo/io/iframe.js
@@ -1,376 +1,190 @@
-define(["../main", "require"], function(dojo, require) {
-	// module:
-	//		dojo/io/iframe
-	// summary:
-	//		TODOC
+define([
+	"../_base/config", "../_base/json", "../_base/kernel", /*===== "../_base/declare", =====*/ "../_base/lang",
+	"../_base/xhr", "../sniff", "../_base/window",
+	"../dom", "../dom-construct", "../query", "require", "../aspect", "../request/iframe"
+], function(config, json, kernel, /*===== declare, =====*/ lang, xhr, has, win, dom, domConstruct, query, require, aspect, _iframe){
+
+// module:
+//		dojo/io/iframe
 
-dojo.getObject("io", true, dojo);
+kernel.deprecated("dojo/io/iframe", "Use dojo/request/iframe.", "2.0");
 
 /*=====
-dojo.declare("dojo.io.iframe.__ioArgs", dojo.__IoArgs, {
-	constructor: function(){
-		//	summary:
-		//		All the properties described in the dojo.__ioArgs type, apply
-		//		to this type. The following additional properties are allowed
-		//		for dojo.io.iframe.send():
-		//	method: String?
-		//		The HTTP method to use. "GET" or "POST" are the only supported
-		//		values.  It will try to read the value from the form node's
-		//		method, then try this argument. If neither one exists, then it
-		//		defaults to POST.
-		//	handleAs: String?
-		//		Specifies what format the result data should be given to the
-		//		load/handle callback. Valid values are: text, html, xml, json,
-		//		javascript. IMPORTANT: For all values EXCEPT html and xml, The
-		//		server response should be an HTML file with a textarea element.
-		//		The response data should be inside the textarea element. Using an
-		//		HTML document the only reliable, cross-browser way this
-		//		transport can know when the response has loaded. For the html
-		//		handleAs value, just return a normal HTML document.  NOTE: xml
-		//		is now supported with this transport (as of 1.1+); a known issue
-		//		is if the XML document in question is malformed, Internet Explorer
-		//		will throw an uncatchable error.
-		//	content: Object?
-		//		If "form" is one of the other args properties, then the content
-		//		object properties become hidden form form elements. For
-		//		instance, a content object of {name1 : "value1"} is converted
-		//		to a hidden form element with a name of "name1" and a value of
-		//		"value1". If there is not a "form" property, then the content
-		//		object is converted into a name=value&name=value string, by
-		//		using dojo.objectToQuery().
-		this.method = method;
-		this.handleAs = handleAs;
-		this.content = content;
-	}
+var __ioArgs = declare(kernel.__IoArgs, {
+	// method: String?
+	//		The HTTP method to use. "GET" or "POST" are the only supported
+	//		values.  It will try to read the value from the form node's
+	//		method, then try this argument. If neither one exists, then it
+	//		defaults to POST.
+	// handleAs: String?
+	//		Specifies what format the result data should be given to the
+	//		load/handle callback. Valid values are: text, html, xml, json,
+	//		javascript. IMPORTANT: For all values EXCEPT html and xml, The
+	//		server response should be an HTML file with a textarea element.
+	//		The response data should be inside the textarea element. Using an
+	//		HTML document the only reliable, cross-browser way this
+	//		transport can know when the response has loaded. For the html
+	//		handleAs value, just return a normal HTML document.  NOTE: xml
+	//		is now supported with this transport (as of 1.1+); a known issue
+	//		is if the XML document in question is malformed, Internet Explorer
+	//		will throw an uncatchable error.
+	// content: Object?
+	//		If "form" is one of the other args properties, then the content
+	//		object properties become hidden form form elements. For
+	//		instance, a content object of {name1 : "value1"} is converted
+	//		to a hidden form element with a name of "name1" and a value of
+	//		"value1". If there is not a "form" property, then the content
+	//		object is converted into a name=value&name=value string, by
+	//		using xhr.objectToQuery().
 });
 =====*/
 
-dojo.io.iframe = {
+/*=====
+return kernel.io.iframe = {
 	// summary:
+	//		Deprecated, use dojo/request/iframe instead.
 	//		Sends an Ajax I/O call using and Iframe (for instance, to upload files)
 
-	create: function(/*String*/fname, /*String*/onloadstr, /*String?*/uri){
-		//	summary:
+	create: function(fname, onloadstr, uri){
+		// summary:
 		//		Creates a hidden iframe in the page. Used mostly for IO
 		//		transports.  You do not need to call this to start a
-		//		dojo.io.iframe request. Just call send().
-		//	fname: String
+		//		dojo/io/iframe request. Just call send().
+		// fname: String
 		//		The name of the iframe. Used for the name attribute on the
 		//		iframe.
-		//	onloadstr: String
+		// onloadstr: String
 		//		A string of JavaScript that will be executed when the content
 		//		in the iframe loads.
-		//	uri: String
+		// uri: String
 		//		The value of the src attribute on the iframe element. If a
 		//		value is not given, then dojo/resources/blank.html will be
 		//		used.
-		if(window[fname]){ return window[fname]; }
-		if(window.frames[fname]){ return window.frames[fname]; }
-		var turi = uri;
-		if(!turi){
-			if(dojo.config["useXDomain"] && !dojo.config["dojoBlankHtmlUrl"]){
-				console.warn("dojo.io.iframe.create: When using cross-domain Dojo builds,"
-					+ " please save dojo/resources/blank.html to your domain and set djConfig.dojoBlankHtmlUrl"
-					+ " to the path on your domain to blank.html");
-			}
-			turi = (dojo.config["dojoBlankHtmlUrl"]||require.toUrl("../resources/blank.html"));
-		}
-		var cframe = dojo.place(
-			'<iframe id="'+fname+'" name="'+fname+'" src="'+turi+'" onload="'+onloadstr+
-			'" style="position: absolute; left: 1px; top: 1px; height: 1px; width: 1px; visibility: hidden">',
-		dojo.body());
-
-		window[fname] = cframe;
-
-		return cframe;
 	},
-
-	setSrc: function(/*DOMNode*/iframe, /*String*/src, /*Boolean*/replace){
-		//summary:
+	setSrc: function(iframe, src, replace){
+		// summary:
 		//		Sets the URL that is loaded in an IFrame. The replace parameter
 		//		indicates whether location.replace() should be used when
 		//		changing the location of the iframe.
-		try{
-			if(!replace){
-				if(dojo.isWebKit){
-					iframe.location = src;
-				}else{
-					frames[iframe.name].location = src;
-				}
-			}else{
-				// Fun with DOM 0 incompatibilities!
-				var idoc;
-				if(dojo.isIE || dojo.isWebKit){
-					idoc = iframe.contentWindow.document;
-				}else{ //  if(d.isMozilla){
-					idoc = iframe.contentWindow;
-				}
-
-				//For Safari (at least 2.0.3) and Opera, if the iframe
-				//has just been created but it doesn't have content
-				//yet, then iframe.document may be null. In that case,
-				//use iframe.location and return.
-				if(!idoc){
-					iframe.location = src;
-				}else{
-					idoc.location.replace(src);
-				}
-			}
-		}catch(e){
-			console.log("dojo.io.iframe.setSrc: ", e);
-		}
 	},
+	doc: function(iframeNode){
+		// summary:
+		//		Returns the document object associated with the iframe DOM Node argument.
+	}
+};
+=====*/
 
-	doc: function(/*DOMNode*/iframeNode){
-		//summary: Returns the document object associated with the iframe DOM Node argument.
-		return iframeNode.contentDocument || // W3
-			(
-				(
-					(iframeNode.name) && (iframeNode.document) &&
-					(dojo.doc.getElementsByTagName("iframe")[iframeNode.name].contentWindow) &&
-					(dojo.doc.getElementsByTagName("iframe")[iframeNode.name].contentWindow.document)
-				)
-			) ||  // IE
-			(
-				(iframeNode.name)&&(dojo.doc.frames[iframeNode.name])&&
-				(dojo.doc.frames[iframeNode.name].document)
-			) || null;
+
+var mid = _iframe._iframeName;
+mid = mid.substring(0, mid.lastIndexOf('_'));
+
+var iframe = lang.delegate(_iframe, {
+	// summary:
+	//		Deprecated, use dojo/request/iframe instead.
+	//		Sends an Ajax I/O call using and Iframe (for instance, to upload files)
+
+	create: function(){
+		return iframe._frame = _iframe.create.apply(_iframe, arguments);
 	},
 
-	send: function(/*dojo.io.iframe.__ioArgs*/args){
-		//summary:
+	// cover up delegated methods
+	get: null,
+	post: null,
+
+	send: function(/*__ioArgs*/args){
+		// summary:
 		//		Function that sends the request to the server.
 		//		This transport can only process one send() request at a time, so if send() is called
-		//multiple times, it will queue up the calls and only process one at a time.
-		if(!this["_frame"]){
-			this._frame = this.create(this._iframeName, dojo._scopeName + ".io.iframe._iframeOnload();");
-		}
+		//		multiple times, it will queue up the calls and only process one at a time.
+		var rDfd;
 
 		//Set up the deferred.
-		var dfd = dojo._ioSetArgs(
-			args,
+		var dfd = xhr._ioSetArgs(args,
 			function(/*Deferred*/dfd){
-				//summary: canceller function for dojo._ioSetArgs call.
-				dfd.canceled = true;
-				dfd.ioArgs._callNext();
+				// summary:
+				//		canceller function for xhr._ioSetArgs call.
+				rDfd && rDfd.cancel();
 			},
 			function(/*Deferred*/dfd){
-				//summary: okHandler function for dojo._ioSetArgs call.
-				var value = null;
+				// summary:
+				//		okHandler function for xhr._ioSetArgs call.
+				var value = null,
+					ioArgs = dfd.ioArgs;
 				try{
-					var ioArgs = dfd.ioArgs;
-					var dii = dojo.io.iframe;
-					var ifd = dii.doc(dii._frame);
 					var handleAs = ioArgs.handleAs;
 
 					//Assign correct value based on handleAs value.
-					value = ifd; //html
-					if(handleAs != "html"){
-						if(handleAs == "xml"){
-							//	FF, Saf 3+ and Opera all seem to be fine with ifd being xml.  We have to
-							//	do it manually for IE6-8.  Refs #6334.
-							if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
-								dojo.query("a", dii._frame.contentWindow.document.documentElement).orphan();
-								var xmlText=(dii._frame.contentWindow.document).documentElement.innerText;
-								xmlText=xmlText.replace(/>\s+</g, "><");
-								xmlText=dojo.trim(xmlText);
-								//Reusing some code in base dojo for handling XML content.  Simpler and keeps
-								//Core from duplicating the effort needed to locate the XML Parser on IE.
-								var fauxXhr = { responseText: xmlText };
-								value = dojo._contentHandlers["xml"](fauxXhr); // DOMDocument
-							}
-						}else{
-							value = ifd.getElementsByTagName("textarea")[0].value; //text
-							if(handleAs == "json"){
-								value = dojo.fromJson(value); //json
-							}else if(handleAs == "javascript"){
-								value = dojo.eval(value); //javascript
-							}
+					if(handleAs === "xml" || handleAs === "html"){
+						value = rDfd.response.data;
+					}else{
+						value = rDfd.response.text;
+						if(handleAs === "json"){
+							value = json.fromJson(value);
+						}else if(handleAs === "javascript"){
+							value = kernel.eval(value);
 						}
 					}
 				}catch(e){
 					value = e;
-				}finally{
-					ioArgs._callNext();
 				}
 				return value;
 			},
 			function(/*Error*/error, /*Deferred*/dfd){
-				//summary: errHandler function for dojo._ioSetArgs call.
+				// summary:
+				//		errHandler function for xhr._ioSetArgs call.
 				dfd.ioArgs._hasError = true;
-				dfd.ioArgs._callNext();
 				return error;
 			}
 		);
 
-		//Set up a function that will fire the next iframe request. Make sure it only
-		//happens once per deferred.
-		dfd.ioArgs._callNext = function(){
-			if(!this["_calledNext"]){
-				this._calledNext = true;
-				dojo.io.iframe._currentDfd = null;
-				dojo.io.iframe._fireNextRequest();
-			}
-		};
-
-		this._dfdQueue.push(dfd);
-		this._fireNextRequest();
-
-		//Add it the IO watch queue, to get things like timeout support.
-		dojo._ioWatch(
-			dfd,
-			function(/*Deferred*/dfd){
-				//validCheck
-				return !dfd.ioArgs["_hasError"];
-			},
-			function(dfd){
-				//ioCheck
-				return (!!dfd.ioArgs["_finished"]);
-			},
-			function(dfd){
-				//resHandle
-				if(dfd.ioArgs._finished){
-					dfd.callback(dfd);
-				}else{
-					dfd.errback(new Error("Invalid dojo.io.iframe request state"));
-				}
-			}
-		);
-
-		return dfd;
-	},
-
-	_currentDfd: null,
-	_dfdQueue: [],
-	_iframeName: dojo._scopeName + "IoIframe",
+		var ioArgs = dfd.ioArgs;
 
-	_fireNextRequest: function(){
-		//summary: Internal method used to fire the next request in the bind queue.
-		try{
-			if((this._currentDfd)||(this._dfdQueue.length == 0)){ return; }
-			//Find next deferred, skip the canceled ones.
-			do{
-				var dfd = this._currentDfd = this._dfdQueue.shift();
-			} while(dfd && dfd.canceled && this._dfdQueue.length);
+		var method = "GET",
+			form = dom.byId(args.form);
+		if(args.method && args.method.toUpperCase() === "POST" && form){
+			method = "POST";
+		}
 
-			//If no more dfds, cancel.
-			if(!dfd || dfd.canceled){
-				this._currentDfd =  null;
-				return;
-			}
+		var options = {
+			method: method,
+			handleAs: args.handleAs === "json" || args.handleAs === "javascript" ? "text" : args.handleAs,
+			form: args.form,
+			query: form ? null : args.content,
+			data: form ? args.content : null,
+			timeout: args.timeout,
+			ioArgs: ioArgs
+		};
 
-			var ioArgs = dfd.ioArgs;
-			var args = ioArgs.args;
+		if(options.method){
+			options.method = options.method.toUpperCase();
+		}
 
-			ioArgs._contentToClean = [];
-			var fn = dojo.byId(args["form"]);
-			var content = args["content"] || {};
-			if(fn){
-				if(content){
-					// if we have things in content, we need to add them to the form
-					// before submission
-					var pHandler = function(name, value) {
-						dojo.create("input", {type: "hidden", name: name, value: value}, fn);
-						ioArgs._contentToClean.push(name);
-					};
-					for(var x in content){
-						var val = content[x];
-						if(dojo.isArray(val) && val.length > 1){
-							var i;
-							for (i = 0; i < val.length; i++) {
-								pHandler(x,val[i]);
-							}
-						}else{
-							if(!fn[x]){
-								pHandler(x,val);
-							}else{
-								fn[x].value = val;
-							}
-						}
-					}
-				}
-				//IE requires going through getAttributeNode instead of just getAttribute in some form cases,
-				//so use it for all.  See #2844
-				var actnNode = fn.getAttributeNode("action");
-				var mthdNode = fn.getAttributeNode("method");
-				var trgtNode = fn.getAttributeNode("target");
-				if(args["url"]){
-					ioArgs._originalAction = actnNode ? actnNode.value : null;
-					if(actnNode){
-						actnNode.value = args.url;
-					}else{
-						fn.setAttribute("action",args.url);
-					}
-				}
-				if(!mthdNode || !mthdNode.value){
-					if(mthdNode){
-						mthdNode.value= (args["method"]) ? args["method"] : "post";
-					}else{
-						fn.setAttribute("method", (args["method"]) ? args["method"] : "post");
-					}
-				}
-				ioArgs._originalTarget = trgtNode ? trgtNode.value: null;
-				if(trgtNode){
-					trgtNode.value = this._iframeName;
-				}else{
-					fn.setAttribute("target", this._iframeName);
+		if(config.ioPublish && kernel.publish && ioArgs.args.ioPublish !== false){
+			var start = aspect.after(_iframe, "_notifyStart", function(data){
+				if(data.options.ioArgs === ioArgs){
+					start.remove();
+					xhr._ioNotifyStart(dfd);
 				}
-				fn.target = this._iframeName;
-				dojo._ioNotifyStart(dfd);
-				fn.submit();
-			}else{
-				// otherwise we post a GET string by changing URL location for the
-				// iframe
-				var tmpUrl = args.url + (args.url.indexOf("?") > -1 ? "&" : "?") + ioArgs.query;
-				dojo._ioNotifyStart(dfd);
-				this.setSrc(this._frame, tmpUrl, true);
-			}
-		}catch(e){
-			dfd.errback(e);
+			}, true);
 		}
-	},
+		rDfd = _iframe(ioArgs.url, options, true);
 
-	_iframeOnload: function(){
-		var dfd = this._currentDfd;
-		if(!dfd){
-			this._fireNextRequest();
-			return;
-		}
+		ioArgs._callNext = rDfd._callNext;
 
-		var ioArgs = dfd.ioArgs;
-		var args = ioArgs.args;
-		var fNode = dojo.byId(args.form);
+		rDfd.then(function(){
+			dfd.resolve(dfd);
+		}).otherwise(function(error){
+			dfd.ioArgs.error = error;
+			dfd.reject(error);
+		});
 
-		if(fNode){
-			// remove all the hidden content inputs
-			var toClean = ioArgs._contentToClean;
-			for(var i = 0; i < toClean.length; i++) {
-				var key = toClean[i];
-				//Need to cycle over all nodes since we may have added
-				//an array value which means that more than one node could
-				//have the same .name value.
-				for(var j = 0; j < fNode.childNodes.length; j++){
-					var chNode = fNode.childNodes[j];
-					if(chNode.name == key){
-						dojo.destroy(chNode);
-						break;
-					}
-				}
-			}
+		return dfd;
+	},
 
-			// restore original action + target
-			if(ioArgs["_originalAction"]){
-				fNode.setAttribute("action", ioArgs._originalAction);
-			}
-			if(ioArgs["_originalTarget"]){
-				fNode.setAttribute("target", ioArgs._originalTarget);
-				fNode.target = ioArgs._originalTarget;
-			}
-		}
+	_iframeOnload: win.global[mid + '_onload']
+});
 
-		ioArgs._finished = true;
-	}
-};
+lang.setObject("dojo.io.iframe", iframe);
 
-return dojo.io.iframe;
+return iframe;
 });
diff --git a/dojo/io/script.js b/dojo/io/script.js
index 58e1edc..16c0296 100644
--- a/dojo/io/script.js
+++ b/dojo/io/script.js
@@ -1,114 +1,104 @@
-define(["../main"], function(dojo) {
+define([
+	"../_base/connect", /*===== "../_base/declare", =====*/ "../_base/kernel", "../_base/lang",
+	"../sniff", "../_base/window","../_base/xhr",
+	"../dom", "../dom-construct", "../request/script", "../aspect"
+], function(connect, /*===== declare, =====*/ kernel, lang, has, win, xhr, dom, domConstruct, _script, aspect){
+
 	// module:
 	//		dojo/io/script
-	// summary:
-	//		TODOC
 
-	dojo.getObject("io", true, dojo);
+	kernel.deprecated("dojo/io/script", "Use dojo/request/script.", "2.0");
 
-/*=====
-dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
-	constructor: function(){
-		//	summary:
+	/*=====
+	var __ioArgs = declare(kernel.__IoArgs, {
+		// summary:
 		//		All the properties described in the dojo.__ioArgs type, apply to this
 		//		type as well, EXCEPT "handleAs". It is not applicable to
-		//		dojo.io.script.get() calls, since it is implied by the usage of
+		//		dojo/io/script.get() calls, since it is implied by the usage of
 		//		"jsonp" (response will be a JSONP call returning JSON)
 		//		or the response is pure JavaScript defined in
 		//		the body of the script that was attached.
-		//	callbackParamName: String
+		// callbackParamName: String
 		//		Deprecated as of Dojo 1.4 in favor of "jsonp", but still supported for
 		//		legacy code. See notes for jsonp property.
-		//	jsonp: String
+		// jsonp: String
 		//		The URL parameter name that indicates the JSONP callback string.
 		//		For instance, when using Yahoo JSONP calls it is normally,
 		//		jsonp: "callback". For AOL JSONP calls it is normally
 		//		jsonp: "c".
-		//	checkString: String
+		// checkString: String
 		//		A string of JavaScript that when evaluated like so:
 		//		"typeof(" + checkString + ") != 'undefined'"
 		//		being true means that the script fetched has been loaded.
 		//		Do not use this if doing a JSONP type of call (use callbackParamName instead).
-		//	frameDoc: Document
+		// frameDoc: Document
 		//		The Document object for a child iframe. If this is passed in, the script
 		//		will be attached to that document. This can be helpful in some comet long-polling
 		//		scenarios with Firefox and Opera.
-		this.callbackParamName = callbackParamName;
-		this.jsonp = jsonp;
-		this.checkString = checkString;
-		this.frameDoc = frameDoc;
-	}
-});
-=====*/
+	});
+	=====*/
 
-	var loadEvent = dojo.isIE ? "onreadystatechange" : "load",
-		readyRegExp = /complete|loaded/;
+	var script = {
+		// summary:
+		//		TODOC
 
-	dojo.io.script = {
-		get: function(/*dojo.io.script.__ioArgs*/args){
-			//	summary:
+		get: function(/*__ioArgs*/ args){
+			// summary:
 			//		sends a get request using a dynamically created script tag.
-			var dfd = this._makeScriptDeferred(args);
+			var rDfd;
+			var dfd = this._makeScriptDeferred(args, function(dfd){
+				rDfd && rDfd.cancel();
+			});
 			var ioArgs = dfd.ioArgs;
-			dojo._ioAddQueryToUrl(ioArgs);
-
-			dojo._ioNotifyStart(dfd);
-
-			if(this._canAttach(ioArgs)){
-				var node = this.attach(ioArgs.id, ioArgs.url, args.frameDoc);
-
-				//If not a jsonp callback or a polling checkString case, bind
-				//to load event on the script tag.
-				if(!ioArgs.jsonp && !ioArgs.args.checkString){
-					var handle = dojo.connect(node, loadEvent, function(evt){
-						if(evt.type == "load" || readyRegExp.test(node.readyState)){
-							dojo.disconnect(handle);
-							ioArgs.scriptLoaded = evt;
-						}
-					});
+			xhr._ioAddQueryToUrl(ioArgs);
+
+			xhr._ioNotifyStart(dfd);
+
+			rDfd = _script.get(ioArgs.url, {
+				timeout: args.timeout,
+				jsonp: ioArgs.jsonp,
+				checkString: args.checkString,
+				ioArgs: ioArgs,
+				frameDoc: args.frameDoc,
+				canAttach: function(rDfd){
+					// sync values
+					ioArgs.requestId = rDfd.id;
+					ioArgs.scriptId = rDfd.scriptId;
+					ioArgs.canDelete = rDfd.canDelete;
+
+					return script._canAttach(ioArgs);
 				}
-			}
+			}, true);
+
+			// Run _validCheck at the same time dojo/request/watch runs the
+			// rDfd.isValid function
+			aspect.around(rDfd, "isValid", function(isValid){
+				return function(response){
+					script._validCheck(dfd);
+					return isValid.call(this, response);
+				};
+			});
+
+			rDfd.then(function(){
+				dfd.resolve(dfd);
+			}).otherwise(function(error){
+				dfd.ioArgs.error = error;
+				dfd.reject(error);
+			});
 
-			dojo._ioWatch(dfd, this._validCheck, this._ioCheck, this._resHandle);
 			return dfd;
 		},
 
-		attach: function(/*String*/id, /*String*/url, /*Document?*/frameDocument){
-			//	summary:
-			//		creates a new <script> tag pointing to the specified URL and
-			//		adds it to the document.
-			//	description:
-			//		Attaches the script element to the DOM.	 Use this method if you
-			//		just want to attach a script to the DOM and do not care when or
-			//		if it loads.
-			var doc = (frameDocument || dojo.doc);
-			var element = doc.createElement("script");
-			element.type = "text/javascript";
-			element.src = url;
-			element.id = id;
-			element.async = true;
-			element.charset = "utf-8";
-			return doc.getElementsByTagName("head")[0].appendChild(element);
-		},
-
-		remove: function(/*String*/id, /*Document?*/frameDocument){
-			//summary: removes the script element with the given id, from the given frameDocument.
-			//If no frameDocument is passed, the current document is used.
-			dojo.destroy(dojo.byId(id, frameDocument));
+		attach: _script._attach,
+		remove: _script._remove,
 
-			//Remove the jsonp callback on dojo.io.script, if it exists.
-			if(this["jsonp_" + id]){
-				delete this["jsonp_" + id];
-			}
-		},
-
-		_makeScriptDeferred: function(/*Object*/args){
-			//summary:
+		_makeScriptDeferred: function(/*Object*/ args, /*Function?*/ cancel){
+			// summary:
 			//		sets up a Deferred object for an IO request.
-			var dfd = dojo._ioSetArgs(args, this._deferredCancel, this._deferredOk, this._deferredError);
+			var dfd = xhr._ioSetArgs(args, cancel || this._deferredCancel, this._deferredOk, this._deferredError);
 
 			var ioArgs = dfd.ioArgs;
-			ioArgs.id = dojo._scopeName + "IoScript" + (this._counter++);
+			ioArgs.id = kernel._scopeName + "IoScript" + (this._counter++);
 			ioArgs.canDelete = false;
 
 			//Special setup for jsonp case
@@ -119,10 +109,9 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 				if(ioArgs.query.length > 0){
 					ioArgs.query += "&";
 				}
-				ioArgs.query += ioArgs.jsonp
-					+ "="
-					+ (args.frameDoc ? "parent." : "")
-					+ dojo._scopeName + ".io.script.jsonp_" + ioArgs.id + "._jsonpCallback";
+				ioArgs.query += ioArgs.jsonp +
+					"=" + (args.frameDoc ? "parent." : "") +
+					kernel._scopeName + ".io.script.jsonp_" + ioArgs.id + "._jsonpCallback";
 
 				ioArgs.frameDoc = args.frameDoc;
 
@@ -131,30 +120,42 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 				dfd._jsonpCallback = this._jsonpCallback;
 				this["jsonp_" + ioArgs.id] = dfd;
 			}
-			return dfd; // dojo.Deferred
+			// Make sure this runs no matter what happens to clean things up if need be
+			dfd.addBoth(function(value){
+				if(ioArgs.canDelete){
+					if(value instanceof Error){
+						// Set up a callback that will clean things up for timeouts and cancels
+						script["jsonp_" + ioArgs.id]._jsonpCallback = function(){
+							// Delete the cached deferred
+							delete script["jsonp_" + ioArgs.id];
+							if(ioArgs.requestId){
+								// Call the dojo/request/script callback to clean itself up as well
+								kernel.global[_script._callbacksProperty][ioArgs.requestId]();
+							}
+						};
+					}else{
+						script._addDeadScript(ioArgs);
+					}
+				}
+			});
+			return dfd; // dojo/_base/Deferred
 		},
 
-		_deferredCancel: function(/*Deferred*/dfd){
-			//summary: canceller function for dojo._ioSetArgs call.
+		_deferredCancel: function(/*Deferred*/ dfd){
+			// summary:
+			//		canceller function for xhr._ioSetArgs call.
 
-			//DO NOT use "this" and expect it to be dojo.io.script.
+			//DO NOT use "this" and expect it to be script.
 			dfd.canceled = true;
-			if(dfd.ioArgs.canDelete){
-				dojo.io.script._addDeadScript(dfd.ioArgs);
-			}
 		},
 
-		_deferredOk: function(/*Deferred*/dfd){
-			//summary: okHandler function for dojo._ioSetArgs call.
+		_deferredOk: function(/*Deferred*/ dfd){
+			// summary:
+			//		okHandler function for xhr._ioSetArgs call.
 
-			//DO NOT use "this" and expect it to be dojo.io.script.
+			//DO NOT use "this" and expect it to be script.
 			var ioArgs = dfd.ioArgs;
 
-			//Add script to list of things that can be removed.
-			if(ioArgs.canDelete){
-				dojo.io.script._addDeadScript(ioArgs);
-			}
-
 			//Favor JSONP responses, script load events then lastly ioArgs.
 			//The ioArgs are goofy, but cannot return the dfd since that stops
 			//the callback chain in Deferred. The return value is not that important
@@ -162,19 +163,10 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 			return ioArgs.json || ioArgs.scriptLoaded || ioArgs;
 		},
 
-		_deferredError: function(/*Error*/error, /*Deferred*/dfd){
-			//summary: errHandler function for dojo._ioSetArgs call.
-
-			if(dfd.ioArgs.canDelete){
-				//DO NOT use "this" and expect it to be dojo.io.script.
-				if(error.dojoType == "timeout"){
-					//For timeouts, remove the script element immediately to
-					//avoid a response from it coming back later and causing trouble.
-					dojo.io.script.remove(dfd.ioArgs.id, dfd.ioArgs.frameDoc);
-				}else{
-					dojo.io.script._addDeadScript(dfd.ioArgs);
-				}
-			}
+		_deferredError: function(/*Error*/ error, /*Deferred*/ dfd){
+			// summary:
+			//		errHandler function for xhr._ioSetArgs call.
+
 			console.log("dojo.io.script error", error);
 			return error;
 		},
@@ -182,36 +174,43 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 		_deadScripts: [],
 		_counter: 1,
 
-		_addDeadScript: function(/*Object*/ioArgs){
-			//summary: sets up an entry in the deadScripts array.
-			dojo.io.script._deadScripts.push({id: ioArgs.id, frameDoc: ioArgs.frameDoc});
+		_addDeadScript: function(/*Object*/ ioArgs){
+			// summary:
+			//		sets up an entry in the deadScripts array.
+			script._deadScripts.push({id: ioArgs.id, frameDoc: ioArgs.frameDoc});
 			//Being extra paranoid about leaks:
 			ioArgs.frameDoc = null;
 		},
 
-		_validCheck: function(/*Deferred*/dfd){
-			//summary: inflight check function to see if dfd is still valid.
+		_validCheck: function(/*Deferred*/ dfd){
+			// summary:
+			//		inflight check function to see if dfd is still valid.
+
+			// TODO: why isn't dfd accessed?
 
 			//Do script cleanup here. We wait for one inflight pass
 			//to make sure we don't get any weird things by trying to remove a script
 			//tag that is part of the call chain (IE 6 has been known to
 			//crash in that case).
-			var _self = dojo.io.script;
-			var deadScripts = _self._deadScripts;
+			var deadScripts = script._deadScripts;
 			if(deadScripts && deadScripts.length > 0){
 				for(var i = 0; i < deadScripts.length; i++){
 					//Remove the script tag
-					_self.remove(deadScripts[i].id, deadScripts[i].frameDoc);
+					script.remove(deadScripts[i].id, deadScripts[i].frameDoc);
+					//Clean up the deferreds
+					delete script["jsonp_" + deadScripts[i].id];
 					deadScripts[i].frameDoc = null;
 				}
-				dojo.io.script._deadScripts = [];
+				script._deadScripts = [];
 			}
 
 			return true;
 		},
 
-		_ioCheck: function(/*Deferred*/dfd){
-			//summary: inflight check function to see if IO finished.
+		_ioCheck: function(dfd){
+			// summary:
+			//		inflight check function to see if IO finished.
+			// dfd: Deferred
 			var ioArgs = dfd.ioArgs;
 			//Check for finished jsonp
 			if(ioArgs.json || (ioArgs.scriptLoaded && !ioArgs.args.checkString)){
@@ -225,9 +224,10 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 
 		},
 
-		_resHandle: function(/*Deferred*/dfd){
-			//summary: inflight function to handle a completed response.
-			if(dojo.io.script._ioCheck(dfd)){
+		_resHandle: function(/*Deferred*/ dfd){
+			// summary:
+			//		inflight function to handle a completed response.
+			if(script._ioCheck(dfd)){
 				dfd.callback(dfd);
 			}else{
 				//This path should never happen since the only way we can get
@@ -236,21 +236,45 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 			}
 		},
 
-		_canAttach: function(/*Object*/ioArgs){
-			//summary: A method that can be overridden by other modules
-			//to control when the script attachment occurs.
+		_canAttach: function(/*===== ioArgs =====*/ ){
+			// summary:
+			//		A method that can be overridden by other modules
+			//		to control when the script attachment occurs.
+			// ioArgs: Object
 			return true;
 		},
 
-		_jsonpCallback: function(/*JSON Object*/json){
-			//summary:
+		_jsonpCallback: function(/*JSON Object*/ json){
+			// summary:
 			//		generic handler for jsonp callback. A pointer to this function
 			//		is used for all jsonp callbacks.  NOTE: the "this" in this
 			//		function will be the Deferred object that represents the script
 			//		request.
 			this.ioArgs.json = json;
+			if(this.ioArgs.requestId){
+				kernel.global[_script._callbacksProperty][this.ioArgs.requestId](json);
+			}
 		}
 	};
 
-	return dojo.io.script;
+	lang.setObject("dojo.io.script", script);
+
+	/*=====
+	script.attach = function(id, url, frameDocument){
+		// summary:
+		//		creates a new `<script>` tag pointing to the specified URL and
+		//		adds it to the document.
+		// description:
+		//		Attaches the script element to the DOM. Use this method if you
+		//		just want to attach a script to the DOM and do not care when or
+		//		if it loads.
+	};
+	script.remove = function(id, frameDocument){
+		// summary:
+		//		removes the script element with the given id, from the given frameDocument.
+		//		If no frameDocument is passed, the current document is used.
+	};
+	=====*/
+
+	return script;
 });
diff --git a/dojo/jaxer.js b/dojo/jaxer.js
deleted file mode 100644
index 638956e..0000000
--- a/dojo/jaxer.js
+++ /dev/null
@@ -1,19 +0,0 @@
-define(["./main"], function(dojo) {
-	// module:
-	//		dojo/jaxer
-	// summary:
-	//		TODOC
-
-
-if(typeof print == "function"){
-	console.debug = Jaxer.Log.debug;
-	console.warn = Jaxer.Log.warn;
-	console.error = Jaxer.Log.error;
-	console.info = Jaxer.Log.info;
-	console.log = Jaxer.Log.warn;
-}
-
-onserverload = dojo._loadInit;
-
-return dojo;
-});
diff --git a/dojo/json.js b/dojo/json.js
index b975b29..560263e 100644
--- a/dojo/json.js
+++ b/dojo/json.js
@@ -3,13 +3,59 @@ define(["./has"], function(has){
 	var hasJSON = typeof JSON != "undefined";
 	has.add("json-parse", hasJSON); // all the parsers work fine
 		// Firefox 3.5/Gecko 1.9 fails to use replacer in stringify properly https://bugzilla.mozilla.org/show_bug.cgi?id=509184
-	has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}'); 
+	has.add("json-stringify", hasJSON && JSON.stringify({a:0}, function(k,v){return v||1;}) == '{"a":1}');
+
+	/*=====
+	return {
+		// summary:
+		//		Functions to parse and serialize JSON
+
+		parse: function(str, strict){
+			// summary:
+			//		Parses a [JSON](http://json.org) string to return a JavaScript object.
+			// description:
+			//		This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
+			//		Throws for invalid JSON strings. This delegates to eval() if native JSON
+			//		support is not available. By default this will evaluate any valid JS expression.
+			//		With the strict parameter set to true, the parser will ensure that only
+			//		valid JSON strings are parsed (otherwise throwing an error). Without the strict
+			//		parameter, the content passed to this method must come
+			//		from a trusted source.
+			// str:
+			//		a string literal of a JSON item, for instance:
+			//		`'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
+			// strict:
+			//		When set to true, this will ensure that only valid, secure JSON is ever parsed.
+			//		Make sure this is set to true for untrusted content. Note that on browsers/engines
+			//		without native JSON support, setting this to true will run slower.
+		},
+		stringify: function(value, replacer, spacer){
+			// summary:
+			//		Returns a [JSON](http://json.org) serialization of an object.
+			// description:
+			//		Returns a [JSON](http://json.org) serialization of an object.
+			//		This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
+			//		Note that this doesn't check for infinite recursion, so don't do that!
+			// value:
+			//		A value to be serialized.
+			// replacer:
+			//		A replacer function that is called for each value and can return a replacement
+			// spacer:
+			//		A spacer string to be used for pretty printing of JSON
+			// example:
+			//		simple serialization of a trivial object
+			//	|	define(["dojo/json"], function(JSON){
+			// 	|		var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true });
+			//	|		doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
+		}
+	};
+	=====*/
+
 	if(has("json-stringify")){
 		return JSON;
-	}
-	else{
+	}else{
 		var escapeString = function(/*String*/str){
-			//summary:
+			// summary:
 			//		Adds escape sequences for non-visual characters, double quote and
 			//		backslash and surrounds with double quotes to form a valid string
 			//		literal.
@@ -19,47 +65,12 @@ define(["./has"], function(has){
 		};
 		return {
 			parse: has("json-parse") ? JSON.parse : function(str, strict){
-				// summary:
-				// 		Parses a [JSON](http://json.org) string to return a JavaScript object.
-				// description:
-				//		This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
-				// 		Throws for invalid JSON strings. This delegates to eval() if native JSON
-				// 		support is not available. By default this will evaluate any valid JS expression.
-				//		With the strict parameter set to true, the parser will ensure that only
-				//		valid JSON strings are parsed (otherwise throwing an error). Without the strict
-				// 		parameter, the content passed to this method must come
-				//		from a trusted source.
-				// str:
-				//		a string literal of a JSON item, for instance:
-				//			`'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
-				//	strict: 
-				//		When set to true, this will ensure that only valid, secure JSON is ever parsed.
-				// 		Make sure this is set to true for untrusted content. Note that on browsers/engines
-				//		without native JSON support, setting this to true will run slower.
-				if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])+"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){
+				if(strict && !/^([\s\[\{]*(?:"(?:\\.|[^"])*"|-?\d[\d\.]*(?:[Ee][+-]?\d+)?|null|true|false|)[\s\]\}]*(?:,|:|$))+$/.test(str)){
 					throw new SyntaxError("Invalid characters in JSON");
 				}
 				return eval('(' + str + ')');
 			},
 			stringify: function(value, replacer, spacer){
-				//	summary:
-				//		Returns a [JSON](http://json.org) serialization of an object.
-				//	description:
-				//		Returns a [JSON](http://json.org) serialization of an object.
-				//		This function follows [native JSON API](https://developer.mozilla.org/en/JSON)
-				//		Note that this doesn't check for infinite recursion, so don't do that!
-				//	value:
-				//		A value to be serialized. 
-				//	replacer:
-				//		A replacer function that is called for each value and can return a replacement
-				//	spacer:
-				//		A spacer string to be used for pretty printing of JSON
-				//		
-				//	example:
-				//		simple serialization of a trivial object
-				//		|	define(["dojo/json"], function(JSON){
-				// 		|		var jsonStr = JSON.stringify({ howdy: "stranger!", isStrange: true });
-				//		|		doh.is('{"howdy":"stranger!","isStrange":true}', jsonStr);
 				var undef;
 				if(typeof replacer == "string"){
 					spacer = replacer;
@@ -123,22 +134,24 @@ define(["./has"], function(has){
 					var output = [];
 					for(key in it){
 						var keyStr;
-						if(typeof key == "number"){
-							keyStr = '"' + key + '"';
-						}else if(typeof key == "string"){
-							keyStr = escapeString(key);
-						}else{
-							// skip non-string or number keys
-							continue;
-						}
-						val = stringify(it[key], nextIndent, key);
-						if(typeof val != "string"){
-							// skip non-serializable values
-							continue;
+						if(it.hasOwnProperty(key)){
+							if(typeof key == "number"){
+								keyStr = '"' + key + '"';
+							}else if(typeof key == "string"){
+								keyStr = escapeString(key);
+							}else{
+								// skip non-string or number keys
+								continue;
+							}
+							val = stringify(it[key], nextIndent, key);
+							if(typeof val != "string"){
+								// skip non-serializable values
+								continue;
+							}
+							// At this point, the most non-IE browsers don't get in this branch 
+							// (they have native JSON), so push is definitely the way to
+							output.push(newLine + nextIndent + keyStr + ":" + sep + val);
 						}
-						// At this point, the most non-IE browsers don't get in this branch 
-						// (they have native JSON), so push is definitely the way to
-						output.push(newLine + nextIndent + keyStr + ":" + sep + val);
 					}
 					return "{" + output.join(",") + newLine + indent + "}"; // String
 				}
diff --git a/dojo/keys.js b/dojo/keys.js
index 3347e74..6395a9b 100644
--- a/dojo/keys.js
+++ b/dojo/keys.js
@@ -1,80 +1,77 @@
-define(["./_base/kernel", "./_base/sniff"], function(dojo, has) {
+define(["./_base/kernel", "./sniff"], function(dojo, has){
+
 	// module:
 	//		dojo/keys
-	// summary:
-	//		key constants
-// Constants
 
-// Public: client code should test
-// keyCode against these named constants, as the
-// actual codes can vary by browser.
-return dojo.keys = {
-	// summary:
-	//		Definitions for common key values
-	BACKSPACE: 8,
-	TAB: 9,
-	CLEAR: 12,
-	ENTER: 13,
-	SHIFT: 16,
-	CTRL: 17,
-	ALT: 18,
-	META: has("safari") ? 91 : 224,		// the apple key on macs
-	PAUSE: 19,
-	CAPS_LOCK: 20,
-	ESCAPE: 27,
-	SPACE: 32,
-	PAGE_UP: 33,
-	PAGE_DOWN: 34,
-	END: 35,
-	HOME: 36,
-	LEFT_ARROW: 37,
-	UP_ARROW: 38,
-	RIGHT_ARROW: 39,
-	DOWN_ARROW: 40,
-	INSERT: 45,
-	DELETE: 46,
-	HELP: 47,
-	LEFT_WINDOW: 91,
-	RIGHT_WINDOW: 92,
-	SELECT: 93,
-	NUMPAD_0: 96,
-	NUMPAD_1: 97,
-	NUMPAD_2: 98,
-	NUMPAD_3: 99,
-	NUMPAD_4: 100,
-	NUMPAD_5: 101,
-	NUMPAD_6: 102,
-	NUMPAD_7: 103,
-	NUMPAD_8: 104,
-	NUMPAD_9: 105,
-	NUMPAD_MULTIPLY: 106,
-	NUMPAD_PLUS: 107,
-	NUMPAD_ENTER: 108,
-	NUMPAD_MINUS: 109,
-	NUMPAD_PERIOD: 110,
-	NUMPAD_DIVIDE: 111,
-	F1: 112,
-	F2: 113,
-	F3: 114,
-	F4: 115,
-	F5: 116,
-	F6: 117,
-	F7: 118,
-	F8: 119,
-	F9: 120,
-	F10: 121,
-	F11: 122,
-	F12: 123,
-	F13: 124,
-	F14: 125,
-	F15: 126,
-	NUM_LOCK: 144,
-	SCROLL_LOCK: 145,
-	UP_DPAD: 175,
-	DOWN_DPAD: 176,
-	LEFT_DPAD: 177,
-	RIGHT_DPAD: 178,
-	// virtual key mapping
-	copyKey: has("mac") && !has("air") ? (has("safari") ? 91 : 224 ) : 17
-};
+	return dojo.keys = {
+		// summary:
+		//		Definitions for common key values.  Client code should test keyCode against these named constants,
+		//		as the actual codes can vary by browser.
+
+		BACKSPACE: 8,
+		TAB: 9,
+		CLEAR: 12,
+		ENTER: 13,
+		SHIFT: 16,
+		CTRL: 17,
+		ALT: 18,
+		META: has("webkit") ? 91 : 224,		// the apple key on macs
+		PAUSE: 19,
+		CAPS_LOCK: 20,
+		ESCAPE: 27,
+		SPACE: 32,
+		PAGE_UP: 33,
+		PAGE_DOWN: 34,
+		END: 35,
+		HOME: 36,
+		LEFT_ARROW: 37,
+		UP_ARROW: 38,
+		RIGHT_ARROW: 39,
+		DOWN_ARROW: 40,
+		INSERT: 45,
+		DELETE: 46,
+		HELP: 47,
+		LEFT_WINDOW: 91,
+		RIGHT_WINDOW: 92,
+		SELECT: 93,
+		NUMPAD_0: 96,
+		NUMPAD_1: 97,
+		NUMPAD_2: 98,
+		NUMPAD_3: 99,
+		NUMPAD_4: 100,
+		NUMPAD_5: 101,
+		NUMPAD_6: 102,
+		NUMPAD_7: 103,
+		NUMPAD_8: 104,
+		NUMPAD_9: 105,
+		NUMPAD_MULTIPLY: 106,
+		NUMPAD_PLUS: 107,
+		NUMPAD_ENTER: 108,
+		NUMPAD_MINUS: 109,
+		NUMPAD_PERIOD: 110,
+		NUMPAD_DIVIDE: 111,
+		F1: 112,
+		F2: 113,
+		F3: 114,
+		F4: 115,
+		F5: 116,
+		F6: 117,
+		F7: 118,
+		F8: 119,
+		F9: 120,
+		F10: 121,
+		F11: 122,
+		F12: 123,
+		F13: 124,
+		F14: 125,
+		F15: 126,
+		NUM_LOCK: 144,
+		SCROLL_LOCK: 145,
+		UP_DPAD: 175,
+		DOWN_DPAD: 176,
+		LEFT_DPAD: 177,
+		RIGHT_DPAD: 178,
+		// virtual key mapping
+		copyKey: has("mac") && !has("air") ? (has("safari") ? 91 : 224 ) : 17
+	};
 });
diff --git a/dojo/main.js b/dojo/main.js
index dee4002..be155dd 100644
--- a/dojo/main.js
+++ b/dojo/main.js
@@ -1,10 +1,11 @@
 define([
-	"./_base/kernel",
+	"./_base/kernel",	// kernel.isAsync
 	"./has",
 	"require",
-	"./_base/sniff",
+	"./sniff",
 	"./_base/lang",
 	"./_base/array",
+	"./_base/config",
 	"./ready",
 	"./_base/declare",
 	"./_base/connect",
@@ -13,7 +14,8 @@ define([
 	"./_base/Color",
 	"./has!dojo-firebug?./_firebug/firebug",
 	"./has!host-browser?./_base/browser",
-	"./has!dojo-sync-loader?./_base/loader"], function(dojo, has, require, sniff, lang, array, ready){
+	"./has!dojo-sync-loader?./_base/loader"
+], function(kernel, has, require, sniff, lang, array, config, ready){
 	// module:
 	//		dojo/main
 	// summary:
@@ -22,20 +24,20 @@ define([
 	// the preferred way to load the dojo firebug console is by setting has("dojo-firebug") true in dojoConfig
 	// the isDebug config switch is for backcompat and will work fine in sync loading mode; it works in
 	// async mode too, but there's no guarantee when the module is loaded; therefore, if you need a firebug
-	// console guarnanteed at a particular spot in an app, either set config.has["dojo-firebug"] true before
+	// console guaranteed at a particular spot in an app, either set config.has["dojo-firebug"] true before
 	// loading dojo.js or explicitly include dojo/_firebug/firebug in a dependency list.
-	if(dojo.config.isDebug){
+	if(config.isDebug){
 		require(["./_firebug/firebug"]);
 	}
 
 	// dojoConfig.require is deprecated; use the loader configuration property deps
 	has.add("dojo-config-require", 1);
 	if(has("dojo-config-require")){
-		var deps= dojo.config.require;
+		var deps= config.require;
 		if(deps){
-			// dojo.config.require may be dot notation
+			// config.require may be dot notation
 			deps= array.map(lang.isArray(deps) ? deps : [deps], function(item){ return item.replace(/\./g, "/"); });
-			if(dojo.isAsync){
+			if(kernel.isAsync){
 				require(deps);
 			}else{
 				// this is a bit janky; in 1.6- dojo is defined before these requires are applied; but in 1.7+
@@ -46,5 +48,5 @@ define([
 		}
 	}
 
-	return dojo;
+	return kernel;
 });
diff --git a/dojo/mouse.js b/dojo/mouse.js
index 9d47f82..8aa9d03 100644
--- a/dojo/mouse.js
+++ b/dojo/mouse.js
@@ -1,39 +1,14 @@
 define(["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(dojo, on, has, dom, win){
 
-	/*=====
-	dojo.mouse = {
-	// summary:
-	//		This module provide mouse event handling utility functions and exports
-	//		mouseenter and mouseleave event emulation.
-	// enter: Synthetic Event
-	//		This is an extension event for the mouseenter that IE provides, emulating the
-	//		behavior on other browsers.
-	// leave: Synthetic Event
-	//		This is an extension event for the mouseleave that IE provides, emulating the
-	//		behavior on other browsers.
-	// isLeft: Function
-	//		Test an event object (from a mousedown event) to see if the left button was pressed.
-	// isMiddle: Function
-	//		Test an event object (from a mousedown event) to see if the middle button was pressed.
-	// isRight: Function
-	//		Test an event object (from a mousedown event) to see if the right button was pressed.
-	// example:
-	//		To use these events, you register a mouseenter like this:
-	//		|	define(["dojo/on", dojo/mouse"], function(on, mouse){
-	//		|		on(targetNode, mouse.enter, function(event){
-	//		|			dojo.addClass(targetNode, "highlighted");
-	//		|		});
-	//		|		on(targetNode, mouse.leave, function(event){
-	//		|			dojo.removeClass(targetNode, "highlighted");
-	//		|		});
-	};
-	======*/
+	// module:
+	//		dojo/mouse
 
     has.add("dom-quirks", win.doc && win.doc.compatMode == "BackCompat");
- 	has.add("events-mouseenter", win.doc && "onmouseenter" in win.doc.createElement("div"));
+	has.add("events-mouseenter", win.doc && "onmouseenter" in win.doc.createElement("div"));
+	has.add("events-mousewheel", win.doc && 'onmousewheel' in win.doc);
 
 	var mouseButtons;
-	if(has("dom-quirks") || !has("dom-addeventlistener")){
+	if((has("dom-quirks") && has("ie")) || !has("dom-addeventlistener")){
 		mouseButtons = {
 			LEFT:   1,
 			MIDDLE: 4,
@@ -103,25 +78,94 @@ define(["./_base/kernel", "./on", "./has", "./dom", "./_base/window"], function(
 	};
 =====*/
 
-	function eventHandler(type, mustBubble){
+	function eventHandler(type, selectHandler){
 		// emulation of mouseenter/leave with mouseover/out using descendant checking
 		var handler = function(node, listener){
 			return on(node, type, function(evt){
-				if(!dom.isDescendant(evt.relatedTarget, mustBubble ? evt.target : node)){
+				if(selectHandler){
+					return selectHandler(evt, listener);
+				}
+				if(!dom.isDescendant(evt.relatedTarget, node)){
 					return listener.call(this, evt);
 				}
 			});
 		};
-		if(!mustBubble){
-			handler.bubble = eventHandler(type, true);
-		}
+		handler.bubble = function(select){
+			return eventHandler(type, function(evt, listener){
+				// using a selector, use the select function to determine if the mouse moved inside the selector and was previously outside the selector
+				var target = select(evt.target);
+				var relatedTarget = evt.relatedTarget;
+				if(target && (target != (relatedTarget && relatedTarget.nodeType == 1 && select(relatedTarget)))){
+					return listener.call(target, evt);
+				} 
+			});
+		};
 		return handler;
 	}
+	var wheel;
+	if(has("events-mousewheel")){
+		wheel = 'mousewheel';
+	}else{ //firefox
+		wheel = function(node, listener){
+			return on(node, 'DOMMouseScroll', function(evt){
+				evt.wheelDelta = -evt.detail;
+				listener.call(this, evt);
+			});
+		};
+	}
 	return {
+		// summary:
+		//		This module provide mouse event handling utility functions and exports
+		//		mouseenter and mouseleave event emulation.
+		// example:
+		//		To use these events, you register a mouseenter like this:
+		//		|	define(["dojo/on", dojo/mouse"], function(on, mouse){
+		//		|		on(targetNode, mouse.enter, function(event){
+		//		|			dojo.addClass(targetNode, "highlighted");
+		//		|		});
+		//		|		on(targetNode, mouse.leave, function(event){
+		//		|			dojo.removeClass(targetNode, "highlighted");
+		//		|		});
+
+		_eventHandler: eventHandler,		// for dojo/touch
+
+		// enter: Synthetic Event
+		//		This is an extension event for the mouseenter that IE provides, emulating the
+		//		behavior on other browsers.
 		enter: eventHandler("mouseover"),
+
+		// leave: Synthetic Event
+		//		This is an extension event for the mouseleave that IE provides, emulating the
+		//		behavior on other browsers.
 		leave: eventHandler("mouseout"),
+
+		// wheel: Normalized Mouse Wheel Event
+		//		This is an extension event for the mousewheel that non-Mozilla browsers provide,
+		//		emulating the behavior on Mozilla based browsers.
+		wheel: wheel,
+
 		isLeft: mouseButtons.isLeft,
+		/*=====
+		isLeft: function(){
+			// summary:
+			//		Test an event object (from a mousedown event) to see if the left button was pressed.
+		},
+		=====*/
+
 		isMiddle: mouseButtons.isMiddle,
+		/*=====
+		 isMiddle: function(){
+			 // summary:
+			 //		Test an event object (from a mousedown event) to see if the middle button was pressed.
+		 },
+		 =====*/
+
 		isRight: mouseButtons.isRight
+		/*=====
+		 , isRight: function(){
+			 // summary:
+			 //		Test an event object (from a mousedown event) to see if the right button was pressed.
+		 }
+		 =====*/
 	};
 });
diff --git a/dojo/nls/ar/colors.js b/dojo/nls/ar/colors.js
index 7ad453f..4e08d74 100644
--- a/dojo/nls/ar/colors.js
+++ b/dojo/nls/ar/colors.js
@@ -1,158 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "أزرق فاتح",
-antiquewhite: "أبيض عتيق",
-aqua: "أزرق مائي",
-aquamarine: "أزرق مائل للأخضر (زبرجد)",
-azure: "أزرق سماوي",
-beige: "بيج",
-bisque: "أصفر برتقالي الى رمادي مصفر",
-black: "أسود",
-blanchedalmond: "أخضر مائل للبياض",
-blue: "أزرق",
-blueviolet: "أزرق-بنفسجي",
-brown: "بني",
-burlywood: "خشبي",
-cadetblue: "أزرق ملون بالرمادي",
-chartreuse: "أخضر مائل للصفرة",
-chocolate: "بني غامق",
-coral: "مرجاني",
-cornflowerblue: "أزرق عنبري",
-cornsilk: "حريري",
-crimson: "قرمزي",
-cyan: "أزرق سماوي",
-darkblue: "أزرق داكن",
-darkcyan: "أزرق سماوي داكن",
-darkgoldenrod: "أصفر ذهبي داكن",
-darkgray: "رمادي داكن",
-darkgreen: "أخضر داكن",
-darkgrey: "رمادي داكن", // same as darkgray
-darkkhaki: "كاكي داكن",
-darkmagenta: "قرمزي داكن",
-darkolivegreen: "أخضر زيتوني داكن",
-darkorange: "برتقالي داكن",
-darkorchid: "أرجواني داكن",
-darkred: "أحمر داكن",
-darksalmon: "فضي داكن",
-darkseagreen: "أخضر مائل للأزرق داكن",
-darkslateblue: "أزرق اردوازي داكن",
-darkslategray: "رمادي اردوازي داكن",
-darkslategrey: "رمادي اردوازي داكن", // same as darkslategray
-darkturquoise: "تركواز داكن",
-darkviolet: "بنفسجي داكن",
-deeppink: "أحمر وردي غامق",
-deepskyblue: "أزرق سماوي غامق",
-dimgray: "رمادي شاحب",
-dimgrey: "رمادي شاحب", // same as dimgray
-dodgerblue: "أزرق عنبري",
-firebrick: "أصفر زاهي",
-floralwhite: "أبيض زهري",
-forestgreen: "أخضر بلون أشجار الغابات",
-fuchsia: "فوشيا",
-gainsboro: "رمادي مائل للأزرق فاتح",
-ghostwhite: "أبيض شفاف",
-gold: "ذهبي",
-goldenrod: "أصفر ذهبي",
-gray: "رمادي",
-green: "أخضر",
-greenyellow: "أخضر مائل للأصفر",
-grey: "رمادي", // same as gray
-honeydew: "أبيض مائل للأخضر",
-hotpink: "أحمر وردي زاهي",
-indianred: "أحمر هندي",
-indigo: "نيلي",
-ivory: "عاجي",
-khaki: "كاكي",
-lavender: "أرجواني شاحب",
-lavenderblush: "أحمر أرجواني",
-lawngreen: "أخضر بلون العشب",
-lemonchiffon: "أصفر شفاف",
-lightblue: "أزرق فاتح",
-lightcoral: "مرجاني فاتح",
-lightcyan: "سماوي فاتح",
-lightgoldenrodyellow: "أصفر ذهبي فاتح",
-lightgray: "رمادي فاتح",
-lightgreen: "أخضر فاتح",
-lightgrey: "رمادي فاتح", // same as lightgray
-lightpink: "وردي فاتح",
-lightsalmon: "فضي فاتح",
-lightseagreen: "أخضر مائل للأزرق فاتح",
-lightskyblue: "أزرق سماوي فاتح",
-lightslategray: "رمادي اردوازي فاتح",
-lightslategrey: "رمادي اردوازي فاتح", // same as lightslategray
-lightsteelblue: "أزرق معدني فاتح",
-lightyellow: "أصفر فاتح",
-lime: "ليموني",
-limegreen: "أخضر ليموني",
-linen: "كتاني",
-magenta: "أحمر قرمزي",
-maroon: "أحمر داكن",
-mediumaquamarine: "أزرق مائل للأخضر (زبرجد) متوسط",
-mediumblue: "أزرق متوسط",
-mediumorchid: "أرجواني متوسط",
-mediumpurple: "قرمزي متوسط",
-mediumseagreen: "أخضر مائل للأزرق متوسط",
-mediumslateblue: "أزرق اردوازي متوسط",
-mediumspringgreen: "أخضر ربيعي متوسط",
-mediumturquoise: "تركواز متوسط",
-mediumvioletred: "أحمر-بنفسجي متوسط",
-midnightblue: "أزرق بحري",
-mintcream: "أصفر شاحب مائل للأخضر الزرعي",
-mistyrose: "وردي",
-moccasin: "نحاسي أحمر",
-navajowhite: "أبيض ملاحي",
-navy: "أزرق داكن",
-oldlace: "برتقالي مائل للأصفر شاحب",
-olive: "أخضر زيتوني داكن",
-olivedrab: "أسود فاتح",
-orange: "برتقالي",
-orangered: "أحمر مائل للبرتقالي",
-orchid: "أرجواني فاتح",
-palegoldenrod: "أصفر ذهبي شاحب",
-palegreen: "أخضر شاحب",
-paleturquoise: "تركواز شاحب",
-palevioletred: "أحمر-بنفسجي شاحب",
-papayawhip: "خوخي فاتح",
-peachpuff: "خوخي مائل للأصفر",
-peru: "بني جملي",
-pink: "وردي",
-plum: "أرجواني داكن",
-powderblue: "أزرق مائل للأصفر",
-purple: "ارجواني",
-red: "أحمر",
-rosybrown: "بني وردي",
-royalblue: "أزرق ملكي",
-saddlebrown: "بني فاتح",
-salmon: "برتقالي وردي شاحب",
-sandybrown: "بني مائل للصفرة",
-seagreen: "أخضر مائل للأزرق",
-seashell: "أبيض مائل للأصفر فاتح",
-sienna: "بني محروق",
-silver: "فضي",
-skyblue: "أزرق سماوي",
-slateblue: "أزرق اردوازي",
-slategray: "رمادي اردوازي",
-slategrey: "رمادي اردوازي", // same as slategray
-snow: "أبيض ثلجي",
-springgreen: "أخضر ربيعي",
-steelblue: "أزرق معدني",
-tan: "خمري",
-teal: "بترولي",
-thistle: "ارجواني شاحب",
-tomato: "أحمر مائل للأصفر",
-turquoise: "تركواز",
-violet: "بنفسجي",
-wheat: "أخضر قمحي",
-white: "أبيض",
-whitesmoke: "دخان أبيض",
-yellow: "أصفر",
-yellowgreen: "أخضر مائل للأصفر"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "أزرق فاتح",
+	antiquewhite: "أبيض عتيق",
+	aqua: "أزرق مائي",
+	aquamarine: "أزرق مائل للأخضر (زبرجد)",
+	azure: "أزرق سماوي",
+	beige: "بيج",
+	bisque: "أصفر برتقالي الى رمادي مصفر",
+	black: "أسود",
+	blanchedalmond: "أخضر مائل للبياض",
+	blue: "أزرق",
+	blueviolet: "أزرق-بنفسجي",
+	brown: "بني",
+	burlywood: "خشبي",
+	cadetblue: "أزرق ملون بالرمادي",
+	chartreuse: "أخضر مائل للصفرة",
+	chocolate: "بني غامق",
+	coral: "مرجاني",
+	cornflowerblue: "أزرق عنبري",
+	cornsilk: "حريري",
+	crimson: "قرمزي",
+	cyan: "أزرق سماوي",
+	darkblue: "أزرق داكن",
+	darkcyan: "أزرق سماوي داكن",
+	darkgoldenrod: "أصفر ذهبي داكن",
+	darkgray: "رمادي داكن",
+	darkgreen: "أخضر داكن",
+	darkgrey: "رمادي داكن", // same as darkgray
+	darkkhaki: "كاكي داكن",
+	darkmagenta: "قرمزي داكن",
+	darkolivegreen: "أخضر زيتوني داكن",
+	darkorange: "برتقالي داكن",
+	darkorchid: "أرجواني داكن",
+	darkred: "أحمر داكن",
+	darksalmon: "فضي داكن",
+	darkseagreen: "أخضر مائل للأزرق داكن",
+	darkslateblue: "أزرق اردوازي داكن",
+	darkslategray: "رمادي اردوازي داكن",
+	darkslategrey: "رمادي اردوازي داكن", // same as darkslategray
+	darkturquoise: "تركواز داكن",
+	darkviolet: "بنفسجي داكن",
+	deeppink: "أحمر وردي غامق",
+	deepskyblue: "أزرق سماوي غامق",
+	dimgray: "رمادي شاحب",
+	dimgrey: "رمادي شاحب", // same as dimgray
+	dodgerblue: "أزرق عنبري",
+	firebrick: "أصفر زاهي",
+	floralwhite: "أبيض زهري",
+	forestgreen: "أخضر بلون أشجار الغابات",
+	fuchsia: "فوشيا",
+	gainsboro: "رمادي مائل للأزرق فاتح",
+	ghostwhite: "أبيض شفاف",
+	gold: "ذهبي",
+	goldenrod: "أصفر ذهبي",
+	gray: "رمادي",
+	green: "أخضر",
+	greenyellow: "أخضر مائل للأصفر",
+	grey: "رمادي", // same as gray
+	honeydew: "أبيض مائل للأخضر",
+	hotpink: "أحمر وردي زاهي",
+	indianred: "أحمر هندي",
+	indigo: "نيلي",
+	ivory: "عاجي",
+	khaki: "كاكي",
+	lavender: "أرجواني شاحب",
+	lavenderblush: "أحمر أرجواني",
+	lawngreen: "أخضر بلون العشب",
+	lemonchiffon: "أصفر شفاف",
+	lightblue: "أزرق فاتح",
+	lightcoral: "مرجاني فاتح",
+	lightcyan: "سماوي فاتح",
+	lightgoldenrodyellow: "أصفر ذهبي فاتح",
+	lightgray: "رمادي فاتح",
+	lightgreen: "أخضر فاتح",
+	lightgrey: "رمادي فاتح", // same as lightgray
+	lightpink: "وردي فاتح",
+	lightsalmon: "فضي فاتح",
+	lightseagreen: "أخضر مائل للأزرق فاتح",
+	lightskyblue: "أزرق سماوي فاتح",
+	lightslategray: "رمادي اردوازي فاتح",
+	lightslategrey: "رمادي اردوازي فاتح", // same as lightslategray
+	lightsteelblue: "أزرق معدني فاتح",
+	lightyellow: "أصفر فاتح",
+	lime: "ليموني",
+	limegreen: "أخضر ليموني",
+	linen: "كتاني",
+	magenta: "أحمر قرمزي",
+	maroon: "أحمر داكن",
+	mediumaquamarine: "أزرق مائل للأخضر (زبرجد) متوسط",
+	mediumblue: "أزرق متوسط",
+	mediumorchid: "أرجواني متوسط",
+	mediumpurple: "قرمزي متوسط",
+	mediumseagreen: "أخضر مائل للأزرق متوسط",
+	mediumslateblue: "أزرق اردوازي متوسط",
+	mediumspringgreen: "أخضر ربيعي متوسط",
+	mediumturquoise: "تركواز متوسط",
+	mediumvioletred: "أحمر-بنفسجي متوسط",
+	midnightblue: "أزرق بحري",
+	mintcream: "أصفر شاحب مائل للأخضر الزرعي",
+	mistyrose: "وردي",
+	moccasin: "نحاسي أحمر",
+	navajowhite: "أبيض ملاحي",
+	navy: "أزرق داكن",
+	oldlace: "برتقالي مائل للأصفر شاحب",
+	olive: "أخضر زيتوني داكن",
+	olivedrab: "أسود فاتح",
+	orange: "برتقالي",
+	orangered: "أحمر مائل للبرتقالي",
+	orchid: "أرجواني فاتح",
+	palegoldenrod: "أصفر ذهبي شاحب",
+	palegreen: "أخضر شاحب",
+	paleturquoise: "تركواز شاحب",
+	palevioletred: "أحمر-بنفسجي شاحب",
+	papayawhip: "خوخي فاتح",
+	peachpuff: "خوخي مائل للأصفر",
+	peru: "بني جملي",
+	pink: "وردي",
+	plum: "أرجواني داكن",
+	powderblue: "أزرق مائل للأصفر",
+	purple: "ارجواني",
+	red: "أحمر",
+	rosybrown: "بني وردي",
+	royalblue: "أزرق ملكي",
+	saddlebrown: "بني فاتح",
+	salmon: "برتقالي وردي شاحب",
+	sandybrown: "بني مائل للصفرة",
+	seagreen: "أخضر مائل للأزرق",
+	seashell: "أبيض مائل للأصفر فاتح",
+	sienna: "بني محروق",
+	silver: "فضي",
+	skyblue: "أزرق سماوي",
+	slateblue: "أزرق اردوازي",
+	slategray: "رمادي اردوازي",
+	slategrey: "رمادي اردوازي", // same as slategray
+	snow: "أبيض ثلجي",
+	springgreen: "أخضر ربيعي",
+	steelblue: "أزرق معدني",
+	tan: "خمري",
+	teal: "بترولي",
+	thistle: "ارجواني شاحب",
+	tomato: "أحمر مائل للأصفر",
+	transparent: "شفاف",
+	turquoise: "تركواز",
+	violet: "بنفسجي",
+	wheat: "أخضر قمحي",
+	white: "أبيض",
+	whitesmoke: "دخان أبيض",
+	yellow: "أصفر",
+	yellowgreen: "أخضر مائل للأصفر"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/az/colors.js b/dojo/nls/az/colors.js
index f69753e..1a54dd6 100644
--- a/dojo/nls/az/colors.js
+++ b/dojo/nls/az/colors.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"lightsteelblue":"açıq metal mavi",
 	"orangered" :"narıncı qırmızı",
@@ -149,5 +148,4 @@ define(
 	"darkolivegreen" :"tünd zeytun yaşılı",
 	"yellowgreen" :"sarı-yaşıl"
 })
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojo/nls/bg/colors.js b/dojo/nls/bg/colors.js
new file mode 100644
index 0000000..b1c7965
--- /dev/null
+++ b/dojo/nls/bg/colors.js
@@ -0,0 +1,156 @@
+define(
+({
+// local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
+// is required for each color, such as a palette widget, and not for specifying color programatically.
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "alice blue",
+	antiquewhite: "antique white",
+	aqua: "aqua",
+	aquamarine: "aquamarine",
+	azure: "azure",
+	beige: "beige",
+	bisque: "bisque",
+	black: "black",
+	blanchedalmond: "blanched almond",
+	blue: "blue",
+	blueviolet: "blue-violet",
+	brown: "brown",
+	burlywood: "burlywood",
+	cadetblue: "cadet blue",
+	chartreuse: "chartreuse",
+	chocolate: "chocolate",
+	coral: "coral",
+	cornflowerblue: "cornflower blue",
+	cornsilk: "cornsilk",
+	crimson: "crimson",
+	cyan: "cyan",
+	darkblue: "dark blue",
+	darkcyan: "dark cyan",
+	darkgoldenrod: "dark goldenrod",
+	darkgray: "dark gray",
+	darkgreen: "dark green",
+	darkgrey: "dark gray", // same as darkgray
+	darkkhaki: "dark khaki",
+	darkmagenta: "dark magenta",
+	darkolivegreen: "dark olive green",
+	darkorange: "dark orange",
+	darkorchid: "dark orchid",
+	darkred: "dark red",
+	darksalmon: "dark salmon",
+	darkseagreen: "dark sea green",
+	darkslateblue: "dark slate blue",
+	darkslategray: "dark slate gray",
+	darkslategrey: "dark slate gray", // same as darkslategray
+	darkturquoise: "dark turquoise",
+	darkviolet: "dark violet",
+	deeppink: "deep pink",
+	deepskyblue: "deep sky blue",
+	dimgray: "dim gray",
+	dimgrey: "dim gray", // same as dimgray
+	dodgerblue: "dodger blue",
+	firebrick: "fire brick",
+	floralwhite: "floral white",
+	forestgreen: "forest green",
+	fuchsia: "fuchsia",
+	gainsboro: "gainsboro",
+	ghostwhite: "ghost white",
+	gold: "gold",
+	goldenrod: "goldenrod",
+	gray: "gray",
+	green: "green",
+	greenyellow: "green-yellow",
+	grey: "gray", // same as gray
+	honeydew: "honeydew",
+	hotpink: "hot pink",
+	indianred: "indian red",
+	indigo: "indigo",
+	ivory: "ivory",
+	khaki: "khaki",
+	lavender: "lavender",
+	lavenderblush: "lavender blush",
+	lawngreen: "lawn green",
+	lemonchiffon: "lemon chiffon",
+	lightblue: "light blue",
+	lightcoral: "light coral",
+	lightcyan: "light cyan",
+	lightgoldenrodyellow: "light goldenrod yellow",
+	lightgray: "light gray",
+	lightgreen: "light green",
+	lightgrey: "light gray", // same as lightgray
+	lightpink: "light pink",
+	lightsalmon: "light salmon",
+	lightseagreen: "light sea green",
+	lightskyblue: "light sky blue",
+	lightslategray: "light slate gray",
+	lightslategrey: "light slate gray", // same as lightslategray
+	lightsteelblue: "light steel blue",
+	lightyellow: "light yellow",
+	lime: "lime",
+	limegreen: "lime green",
+	linen: "linen",
+	magenta: "magenta",
+	maroon: "maroon",
+	mediumaquamarine: "medium aquamarine",
+	mediumblue: "medium blue",
+	mediumorchid: "medium orchid",
+	mediumpurple: "medium purple",
+	mediumseagreen: "medium sea green",
+	mediumslateblue: "medium slate blue",
+	mediumspringgreen: "medium spring green",
+	mediumturquoise: "medium turquoise",
+	mediumvioletred: "medium violet-red",
+	midnightblue: "midnight blue",
+	mintcream: "mint cream",
+	mistyrose: "misty rose",
+	moccasin: "moccasin",
+	navajowhite: "navajo white",
+	navy: "navy",
+	oldlace: "old lace",
+	olive: "olive",
+	olivedrab: "olive drab",
+	orange: "orange",
+	orangered: "orange red",
+	orchid: "orchid",
+	palegoldenrod: "pale goldenrod",
+	palegreen: "pale green",
+	paleturquoise: "pale turquoise",
+	palevioletred: "pale violet-red",
+	papayawhip: "papaya whip",
+	peachpuff: "peach puff",
+	peru: "peru",
+	pink: "pink",
+	plum: "plum",
+	powderblue: "powder blue",
+	purple: "purple",
+	red: "red",
+	rosybrown: "rosy brown",
+	royalblue: "royal blue",
+	saddlebrown: "saddle brown",
+	salmon: "salmon",
+	sandybrown: "sandy brown",
+	seagreen: "sea green",
+	seashell: "seashell",
+	sienna: "sienna",
+	silver: "silver",
+	skyblue: "sky blue",
+	slateblue: "slate blue",
+	slategray: "slate gray",
+	slategrey: "slate gray", // same as slategray
+	snow: "snow",
+	springgreen: "spring green",
+	steelblue: "steel blue",
+	tan: "tan",
+	teal: "teal",
+	thistle: "thistle",
+	tomato: "tomato",
+	transparent: "transparent",
+	turquoise: "turquoise",
+	violet: "violet",
+	wheat: "wheat",
+	white: "white",
+	whitesmoke: "white smoke",
+	yellow: "yellow",
+	yellowgreen: "yellow green"
+})
+);
diff --git a/dojo/nls/ca/colors.js b/dojo/nls/ca/colors.js
index c0516bf..524dca2 100644
--- a/dojo/nls/ca/colors.js
+++ b/dojo/nls/ca/colors.js
@@ -1,160 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "blau cian clar",
-antiquewhite: "blanc antic",
-aqua: "aigua",
-aquamarine: "aiguamarina",
-azure: "atzur",
-beige: "beix",
-bisque: "crema",
-black: "negre",
-blanchedalmond: "ametlla pàl·lid",
-blue: "blau",
-blueviolet: "blau violeta",
-brown: "marró",
-burlywood: "marró arenós",
-cadetblue: "blau marí",
-chartreuse: "Llimona pàl·lid",
-chocolate: "xocolata",
-coral: "corall",
-cornflowerblue: "blau blauet",
-cornsilk: "cru",
-crimson: "carmesí",
-cyan: "cian",
-darkblue: "blau fosc",
-darkcyan: "cian fosc",
-darkgoldenrod: "ocre fosc",
-darkgray: "gris fosc",
-darkgreen: "verd fosc",
-darkgrey: "gris fosc", // same as darkgray
-darkkhaki: "caqui fosc",
-darkmagenta: "magenta fosc",
-darkolivegreen: "verd oliva fosc",
-darkorange: "taronja fosc",
-darkorchid: "orquídia fosc",
-darkred: "vermell fosc",
-darksalmon: "salmó fosc",
-darkseagreen: "verd marí fosc",
-darkslateblue: "blau pissarra fosc",
-darkslategray: "gris pissarra fosc",
-darkslategrey: "gris pissarra fosc", // same as darkslategray
-darkturquoise: "turquesa fosc",
-darkviolet: "violeta fosc",
-deeppink: "rosa profund",
-deepskyblue: "blau cel profund",
-dimgray: "gris fosc",
-dimgrey: "gris fosc", // same as dimgray
-dodgerblue: "blau Dodger",
-firebrick: "maó refractari",
-floralwhite: "blanc floral",
-forestgreen: "verd bosc",
-fuchsia: "fúcsia",
-gainsboro: "gainsboro",
-ghostwhite: "blanc fantasma",
-gold: "daurat",
-goldenrod: "ocre",
-gray: "gris",
-green: "verd",
-greenyellow: "verd grogós",
-grey: "gris", // same as gray
-honeydew: "rosada de mel",
-hotpink: "rosa fúcsia",
-indianred: "vermell indi",
-indigo: "índigo",
-ivory: "marbre",
-khaki: "caqui",
-lavender: "lavanda",
-lavenderblush: "lavanda vermellosa",
-lawngreen: "verd gespa",
-lemonchiffon: "groc brisa",
-lightblue: "blau clar",
-lightcoral: "corall clar",
-lightcyan: "cian clar",
-lightgoldenrodyellow: "groc ocre clar",
-lightgray: "gris clar",
-lightgreen: "verd clar",
-lightgrey: "gris clar", // same as lightgray
-lightpink: "rosa clar",
-lightsalmon: "salmó clar",
-lightseagreen: "verd marí clar",
-lightskyblue: "blau cel clar",
-lightslategray: "gris pissarra clar",
-lightslategrey: "gris pissarra clar", // same as lightslategray
-lightsteelblue: "blau acer clar",
-lightyellow: "groc clar",
-lime: "verd llimona",
-limegreen: "verd llimona verda",
-linen: "lli",
-magenta: "magenta",
-maroon: "marró vermellós",
-mediumaquamarine: "aiguamarina mitjana",
-mediumblue: "blau mitjà",
-mediumorchid: "orquídia mitjana",
-mediumpurple: "porpra mitjana",
-mediumseagreen: "verd marí mitjà",
-mediumslateblue: "blau pissarra mitjà",
-mediumspringgreen: "verd primavera mitjà",
-mediumturquoise: "turquesa mitjana",
-mediumvioletred: "vermell violeta mitjà",
-midnightblue: "blau mitjanit",
-mintcream: "menta pàl·lid",
-mistyrose: "rosa dens",
-moccasin: "mocassí",
-navajowhite: "blanc Navajo",
-navy: "blau marí",
-oldlace: "rosa cremós",
-olive: "oliva",
-olivedrab: "gris oliva",
-orange: "taronja",
-orangered: "taronja vermellós",
-orchid: "orquídia",
-palegoldenrod: "ocre pàl·lid",
-palegreen: "verd pàl·lid",
-paleturquoise: "turquesa pàl·lid",
-palevioletred: "vermell porpra pàl·lid",
-papayawhip: "préssec pastel",
-peachpuff: "préssec",
-peru: "Perú",
-pink: "rosa",
-plum: "pruna",
-powderblue: "blau grisós",
-purple: "porpra",
-red: "vermell",
-rosybrown: "marró rosat",
-royalblue: "blau marí intens",
-saddlebrown: "marró mitjà",
-salmon: "salmó",
-sandybrown: "marró arenós",
-seagreen: "verd marí",
-seashell: "petxina marina",
-sienna: "siena",
-silver: "argent",
-skyblue: "blau cel",
-slateblue: "blau pissarra",
-slategray: "gris pissarra",
-slategrey: "gris pissarra", // same as slategray
-snow: "neu",
-springgreen: "verd de primavera",
-steelblue: "blau acer",
-tan: "tan",
-teal: "verd blavós",
-thistle: "card",
-tomato: "tomàquet",
-transparent: "transparent",
-turquoise: "turquesa",
-violet: "violeta",
-wheat: "blat",
-white: "blanc",
-whitesmoke: "blanc fumat",
-yellow: "groc",
-yellowgreen: "verd grogós"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "blau cian clar",
+	antiquewhite: "blanc antic",
+	aqua: "aigua",
+	aquamarine: "aiguamarina",
+	azure: "atzur",
+	beige: "beix",
+	bisque: "crema",
+	black: "negre",
+	blanchedalmond: "ametlla pàl·lid",
+	blue: "blau",
+	blueviolet: "blau violeta",
+	brown: "marró",
+	burlywood: "marró arenós",
+	cadetblue: "blau marí",
+	chartreuse: "Llimona pàl·lid",
+	chocolate: "xocolata",
+	coral: "corall",
+	cornflowerblue: "blau blauet",
+	cornsilk: "cru",
+	crimson: "carmesí",
+	cyan: "cian",
+	darkblue: "blau fosc",
+	darkcyan: "cian fosc",
+	darkgoldenrod: "ocre fosc",
+	darkgray: "gris fosc",
+	darkgreen: "verd fosc",
+	darkgrey: "gris fosc", // same as darkgray
+	darkkhaki: "caqui fosc",
+	darkmagenta: "magenta fosc",
+	darkolivegreen: "verd oliva fosc",
+	darkorange: "taronja fosc",
+	darkorchid: "orquídia fosc",
+	darkred: "vermell fosc",
+	darksalmon: "salmó fosc",
+	darkseagreen: "verd marí fosc",
+	darkslateblue: "blau pissarra fosc",
+	darkslategray: "gris pissarra fosc",
+	darkslategrey: "gris pissarra fosc", // same as darkslategray
+	darkturquoise: "turquesa fosc",
+	darkviolet: "violeta fosc",
+	deeppink: "rosa profund",
+	deepskyblue: "blau cel profund",
+	dimgray: "gris fosc",
+	dimgrey: "gris fosc", // same as dimgray
+	dodgerblue: "blau Dodger",
+	firebrick: "maó refractari",
+	floralwhite: "blanc floral",
+	forestgreen: "verd bosc",
+	fuchsia: "fúcsia",
+	gainsboro: "gainsboro",
+	ghostwhite: "blanc fantasma",
+	gold: "daurat",
+	goldenrod: "ocre",
+	gray: "gris",
+	green: "verd",
+	greenyellow: "verd grogós",
+	grey: "gris", // same as gray
+	honeydew: "rosada de mel",
+	hotpink: "rosa fúcsia",
+	indianred: "vermell indi",
+	indigo: "índigo",
+	ivory: "marbre",
+	khaki: "caqui",
+	lavender: "lavanda",
+	lavenderblush: "lavanda vermellosa",
+	lawngreen: "verd gespa",
+	lemonchiffon: "groc brisa",
+	lightblue: "blau clar",
+	lightcoral: "corall clar",
+	lightcyan: "cian clar",
+	lightgoldenrodyellow: "groc ocre clar",
+	lightgray: "gris clar",
+	lightgreen: "verd clar",
+	lightgrey: "gris clar", // same as lightgray
+	lightpink: "rosa clar",
+	lightsalmon: "salmó clar",
+	lightseagreen: "verd marí clar",
+	lightskyblue: "blau cel clar",
+	lightslategray: "gris pissarra clar",
+	lightslategrey: "gris pissarra clar", // same as lightslategray
+	lightsteelblue: "blau acer clar",
+	lightyellow: "groc clar",
+	lime: "verd llimona",
+	limegreen: "verd llimona verda",
+	linen: "lli",
+	magenta: "magenta",
+	maroon: "marró vermellós",
+	mediumaquamarine: "aiguamarina mitjana",
+	mediumblue: "blau mitjà",
+	mediumorchid: "orquídia mitjana",
+	mediumpurple: "porpra mitjana",
+	mediumseagreen: "verd marí mitjà",
+	mediumslateblue: "blau pissarra mitjà",
+	mediumspringgreen: "verd primavera mitjà",
+	mediumturquoise: "turquesa mitjana",
+	mediumvioletred: "vermell violeta mitjà",
+	midnightblue: "blau mitjanit",
+	mintcream: "menta pàl·lid",
+	mistyrose: "rosa dens",
+	moccasin: "mocassí",
+	navajowhite: "blanc Navajo",
+	navy: "blau marí",
+	oldlace: "rosa cremós",
+	olive: "oliva",
+	olivedrab: "gris oliva",
+	orange: "taronja",
+	orangered: "taronja vermellós",
+	orchid: "orquídia",
+	palegoldenrod: "ocre pàl·lid",
+	palegreen: "verd pàl·lid",
+	paleturquoise: "turquesa pàl·lid",
+	palevioletred: "vermell porpra pàl·lid",
+	papayawhip: "préssec pastel",
+	peachpuff: "préssec",
+	peru: "Perú",
+	pink: "rosa",
+	plum: "pruna",
+	powderblue: "blau grisós",
+	purple: "porpra",
+	red: "vermell",
+	rosybrown: "marró rosat",
+	royalblue: "blau marí intens",
+	saddlebrown: "marró mitjà",
+	salmon: "salmó",
+	sandybrown: "marró arenós",
+	seagreen: "verd marí",
+	seashell: "petxina marina",
+	sienna: "siena",
+	silver: "argent",
+	skyblue: "blau cel",
+	slateblue: "blau pissarra",
+	slategray: "gris pissarra",
+	slategrey: "gris pissarra", // same as slategray
+	snow: "neu",
+	springgreen: "verd de primavera",
+	steelblue: "blau acer",
+	tan: "tan",
+	teal: "verd blavós",
+	thistle: "card",
+	tomato: "tomàquet",
+	transparent: "transparent",
+	turquoise: "turquesa",
+	violet: "violeta",
+	wheat: "blat",
+	white: "blanc",
+	whitesmoke: "blanc fumat",
+	yellow: "groc",
+	yellowgreen: "verd grogós"
 })
-
-//end v1.x content
 );
diff --git a/dojo/nls/colors.js b/dojo/nls/colors.js
index 9808141..4ee9681 100644
--- a/dojo/nls/colors.js
+++ b/dojo/nls/colors.js
@@ -4,7 +4,7 @@ define({ root:
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "alice blue",
 antiquewhite: "antique white",
@@ -159,6 +159,7 @@ yellowgreen: "yellow green"
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -186,6 +187,7 @@ yellowgreen: "yellow green"
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dojo/nls/cs/colors.js b/dojo/nls/cs/colors.js
index affd7f3..86425e8 100644
--- a/dojo/nls/cs/colors.js
+++ b/dojo/nls/cs/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "modravá",
-antiquewhite: "krémově bílá",
-aqua: "azurová",
-aquamarine: "akvamarínová",
-azure: "bledě azurová",
-beige: "bledě béžová",
-bisque: "bledě oranžová",
-black: "černá",
-blanchedalmond: "mandlová",
-blue: "modrá",
-blueviolet: "modrofialová",
-brown: "červenohnědá",
-burlywood: "krémová",
-cadetblue: "šedomodrá",
-chartreuse: "chartreuska",
-chocolate: "hnědobéžová",
-coral: "korálová červená",
-cornflowerblue: "chrpově modrá",
-cornsilk: "režná",
-crimson: "karmínová",
-cyan: "azurová",
-darkblue: "tmavě modrá",
-darkcyan: "tmavě azurová",
-darkgoldenrod: "tmavě béžová",
-darkgray: "tmavě šedá",
-darkgreen: "tmavě zelená",
-darkgrey: "tmavě šedá", // same as darkgray
-darkkhaki: "pískově hnědá",
-darkmagenta: "tmavě purpurová",
-darkolivegreen: "tmavě olivová",
-darkorange: "tmavě oranžová",
-darkorchid: "tmavě orchidejová",
-darkred: "tmavě červená",
-darksalmon: "tmavě lososová",
-darkseagreen: "tmavá mořská zelená",
-darkslateblue: "tmavá břidlicová modrá",
-darkslategray: "tmavá břidlicová šedá",
-darkslategrey: "tmavá břidlicová šedá", // same as darkslategray
-darkturquoise: "tmavě tyrkysová",
-darkviolet: "tmavě fialová",
-deeppink: "sytě růžová",
-deepskyblue: "sytá nebeská modrá",
-dimgray: "kouřově šedá",
-dimgrey: "kouřově šedá", // same as dimgray
-dodgerblue: "jasně modrá",
-firebrick: "cihlová",
-floralwhite: "květinově bílá",
-forestgreen: "lesní zelená",
-fuchsia: "fuchsiová",
-gainsboro: "bledě šedá",
-ghostwhite: "modravě bílá",
-gold: "zlatá",
-goldenrod: "béžová",
-gray: "šedá",
-green: "zelená",
-greenyellow: "zelenožlutá",
-grey: "šedá", // same as gray
-honeydew: "nazelenalá",
-hotpink: "jasně růžová",
-indianred: "indiánská červená",
-indigo: "indigově modrá",
-ivory: "slonovinová",
-khaki: "písková",
-lavender: "levandulová",
-lavenderblush: "levandulová růžová",
-lawngreen: "jasně zelená",
-lemonchiffon: "světle citrónová",
-lightblue: "světle modrá",
-lightcoral: "světle korálová",
-lightcyan: "světle azurová",
-lightgoldenrodyellow: "světle žlutá",
-lightgray: "světle šedá",
-lightgreen: "světle zelená",
-lightgrey: "světle šedá", // same as lightgray
-lightpink: "světle růžová",
-lightsalmon: "světle lososová",
-lightseagreen: "světlá mořská zelená",
-lightskyblue: "světlá nebeská modrá",
-lightslategray: "světlá břidlicová šedá",
-lightslategrey: "světlá břidlicová šedá", // same as lightslategray
-lightsteelblue: "světlá ocelová modrá",
-lightyellow: "bledě žlutá",
-lime: "limetková",
-limegreen: "limetkově zelená",
-linen: "bledě šedobéžová",
-magenta: "purpurová",
-maroon: "kaštanová",
-mediumaquamarine: "střední akvamarínová",
-mediumblue: "středně modrá",
-mediumorchid: "středně orchidejová",
-mediumpurple: "středně nachová",
-mediumseagreen: "střední mořská zelená",
-mediumslateblue: "střední břidlicová modrá",
-mediumspringgreen: "střední jarní zelená",
-mediumturquoise: "středně tyrkysová",
-mediumvioletred: "středně fialovočervená",
-midnightblue: "temně modrá",
-mintcream: "mentolová",
-mistyrose: "růžovobílá",
-moccasin: "bledě krémová",
-navajowhite: "světle krémová",
-navy: "námořnická modrá",
-oldlace: "světle béžová",
-olive: "olivová",
-olivedrab: "khaki",
-orange: "oranžová",
-orangered: "oranžovočervená",
-orchid: "orchidejová",
-palegoldenrod: "bledě písková",
-palegreen: "bledě zelená",
-paleturquoise: "bledě tyrkysová",
-palevioletred: "bledě fialovočervená",
-papayawhip: "papájová",
-peachpuff: "broskvová",
-peru: "karamelová",
-pink: "růžová",
-plum: "švestková",
-powderblue: "bledě modrá",
-purple: "nachová",
-red: "červená",
-rosybrown: "růžovohnědá",
-royalblue: "královská modrá",
-saddlebrown: "hnědá",
-salmon: "lososová",
-sandybrown: "oranžovohnědá",
-seagreen: "mořská zelená",
-seashell: "lasturová",
-sienna: "siena",
-silver: "stříbrná",
-skyblue: "nebeská modrá",
-slateblue: "břidlicová modrá",
-slategray: "břidlicová šedá",
-slategrey: "břidlicová šedá", // same as slategray
-snow: "sněhobílá",
-springgreen: "jarní zelená",
-steelblue: "ocelová modrá",
-tan: "šedobéžová",
-teal: "šedozelená",
-thistle: "bodláková",
-tomato: "tomatová",
-transparent: "průhledná",
-turquoise: "tyrkysová",
-violet: "fialová",
-wheat: "zlatohnědá",
-white: "bílá",
-whitesmoke: "kouřově bílá",
-yellow: "žlutá",
-yellowgreen: "žlutozelená"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "modravá",
+	antiquewhite: "krémově bílá",
+	aqua: "azurová",
+	aquamarine: "akvamarínová",
+	azure: "bledě azurová",
+	beige: "bledě béžová",
+	bisque: "bledě oranžová",
+	black: "černá",
+	blanchedalmond: "mandlová",
+	blue: "modrá",
+	blueviolet: "modrofialová",
+	brown: "červenohnědá",
+	burlywood: "krémová",
+	cadetblue: "šedomodrá",
+	chartreuse: "chartreuska",
+	chocolate: "hnědobéžová",
+	coral: "korálová červená",
+	cornflowerblue: "chrpově modrá",
+	cornsilk: "režná",
+	crimson: "karmínová",
+	cyan: "azurová",
+	darkblue: "tmavě modrá",
+	darkcyan: "tmavě azurová",
+	darkgoldenrod: "tmavě béžová",
+	darkgray: "tmavě šedá",
+	darkgreen: "tmavě zelená",
+	darkgrey: "tmavě šedá", // same as darkgray
+	darkkhaki: "pískově hnědá",
+	darkmagenta: "tmavě purpurová",
+	darkolivegreen: "tmavě olivová",
+	darkorange: "tmavě oranžová",
+	darkorchid: "tmavě orchidejová",
+	darkred: "tmavě červená",
+	darksalmon: "tmavě lososová",
+	darkseagreen: "tmavá mořská zelená",
+	darkslateblue: "tmavá břidlicová modrá",
+	darkslategray: "tmavá břidlicová šedá",
+	darkslategrey: "tmavá břidlicová šedá", // same as darkslategray
+	darkturquoise: "tmavě tyrkysová",
+	darkviolet: "tmavě fialová",
+	deeppink: "sytě růžová",
+	deepskyblue: "sytá nebeská modrá",
+	dimgray: "kouřově šedá",
+	dimgrey: "kouřově šedá", // same as dimgray
+	dodgerblue: "jasně modrá",
+	firebrick: "cihlová",
+	floralwhite: "květinově bílá",
+	forestgreen: "lesní zelená",
+	fuchsia: "fuchsiová",
+	gainsboro: "bledě šedá",
+	ghostwhite: "modravě bílá",
+	gold: "zlatá",
+	goldenrod: "béžová",
+	gray: "šedá",
+	green: "zelená",
+	greenyellow: "zelenožlutá",
+	grey: "šedá", // same as gray
+	honeydew: "nazelenalá",
+	hotpink: "jasně růžová",
+	indianred: "indiánská červená",
+	indigo: "indigově modrá",
+	ivory: "slonovinová",
+	khaki: "písková",
+	lavender: "levandulová",
+	lavenderblush: "levandulová růžová",
+	lawngreen: "jasně zelená",
+	lemonchiffon: "světle citrónová",
+	lightblue: "světle modrá",
+	lightcoral: "světle korálová",
+	lightcyan: "světle azurová",
+	lightgoldenrodyellow: "světle žlutá",
+	lightgray: "světle šedá",
+	lightgreen: "světle zelená",
+	lightgrey: "světle šedá", // same as lightgray
+	lightpink: "světle růžová",
+	lightsalmon: "světle lososová",
+	lightseagreen: "světlá mořská zelená",
+	lightskyblue: "světlá nebeská modrá",
+	lightslategray: "světlá břidlicová šedá",
+	lightslategrey: "světlá břidlicová šedá", // same as lightslategray
+	lightsteelblue: "světlá ocelová modrá",
+	lightyellow: "bledě žlutá",
+	lime: "limetková",
+	limegreen: "limetkově zelená",
+	linen: "bledě šedobéžová",
+	magenta: "purpurová",
+	maroon: "kaštanová",
+	mediumaquamarine: "střední akvamarínová",
+	mediumblue: "středně modrá",
+	mediumorchid: "středně orchidejová",
+	mediumpurple: "středně nachová",
+	mediumseagreen: "střední mořská zelená",
+	mediumslateblue: "střední břidlicová modrá",
+	mediumspringgreen: "střední jarní zelená",
+	mediumturquoise: "středně tyrkysová",
+	mediumvioletred: "středně fialovočervená",
+	midnightblue: "temně modrá",
+	mintcream: "mentolová",
+	mistyrose: "růžovobílá",
+	moccasin: "bledě krémová",
+	navajowhite: "světle krémová",
+	navy: "námořnická modrá",
+	oldlace: "světle béžová",
+	olive: "olivová",
+	olivedrab: "khaki",
+	orange: "oranžová",
+	orangered: "oranžovočervená",
+	orchid: "orchidejová",
+	palegoldenrod: "bledě písková",
+	palegreen: "bledě zelená",
+	paleturquoise: "bledě tyrkysová",
+	palevioletred: "bledě fialovočervená",
+	papayawhip: "papájová",
+	peachpuff: "broskvová",
+	peru: "karamelová",
+	pink: "růžová",
+	plum: "švestková",
+	powderblue: "bledě modrá",
+	purple: "nachová",
+	red: "červená",
+	rosybrown: "růžovohnědá",
+	royalblue: "královská modrá",
+	saddlebrown: "hnědá",
+	salmon: "lososová",
+	sandybrown: "oranžovohnědá",
+	seagreen: "mořská zelená",
+	seashell: "lasturová",
+	sienna: "siena",
+	silver: "stříbrná",
+	skyblue: "nebeská modrá",
+	slateblue: "břidlicová modrá",
+	slategray: "břidlicová šedá",
+	slategrey: "břidlicová šedá", // same as slategray
+	snow: "sněhobílá",
+	springgreen: "jarní zelená",
+	steelblue: "ocelová modrá",
+	tan: "šedobéžová",
+	teal: "šedozelená",
+	thistle: "bodláková",
+	tomato: "tomatová",
+	transparent: "průhledná",
+	turquoise: "tyrkysová",
+	violet: "fialová",
+	wheat: "zlatohnědá",
+	white: "bílá",
+	whitesmoke: "kouřově bílá",
+	yellow: "žlutá",
+	yellowgreen: "žlutozelená"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/da/colors.js b/dojo/nls/da/colors.js
index 84b25a6..347238b 100644
--- a/dojo/nls/da/colors.js
+++ b/dojo/nls/da/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "babyblå",
-antiquewhite: "antikhvid",
-aqua: "akvablå",
-aquamarine: "akvamarin",
-azure: "azurblå",
-beige: "beige",
-bisque: "gulgrå",
-black: "sort",
-blanchedalmond: "blanceret mandel",
-blue: "blå",
-blueviolet: "blåviolet",
-brown: "brun",
-burlywood: "tobak",
-cadetblue: "kadetblå",
-chartreuse: "chartreuse",
-chocolate: "rust",
-coral: "koralrød",
-cornflowerblue: "kornblomstblå",
-cornsilk: "majs",
-crimson: "blodrød",
-cyan: "cyan",
-darkblue: "mørkeblå",
-darkcyan: "mørk cyan",
-darkgoldenrod: "mørk gyldenris",
-darkgray: "mørkegrå",
-darkgreen: "mørkegrøn",
-darkgrey: "mørkegrå", // same as darkgray
-darkkhaki: "mørk khaki",
-darkmagenta: "mørk magenta",
-darkolivegreen: "mørk olivengrøn",
-darkorange: "mørk orange",
-darkorchid: "mørk orkide",
-darkred: "mørkerød",
-darksalmon: "mørk laksefarvet",
-darkseagreen: "mørk havgrøn",
-darkslateblue: "mørk skiferblå",
-darkslategray: "mørk skifergrå",
-darkslategrey: "mørk skifergrå", // same as darkslategray
-darkturquoise: "mørk turkis",
-darkviolet: "mørkelilla",
-deeppink: "dyb pink",
-deepskyblue: "dyb himmelblå",
-dimgray: "svag grå",
-dimgrey: "svag grå", // same as dimgray
-dodgerblue: "dodgerblå",
-firebrick: "chamottesten",
-floralwhite: "blomsterhvid",
-forestgreen: "skovgrøn",
-fuchsia: "lyslilla",
-gainsboro: "gainsboro",
-ghostwhite: "spøgelseshvid",
-gold: "guld",
-goldenrod: "gyldenris",
-gray: "grå",
-green: "grøn",
-greenyellow: "grøngul",
-grey: "grå", // same as gray
-honeydew: "honningdug",
-hotpink: "mørk rosa",
-indianred: "lys rødbrun",
-indigo: "indigo",
-ivory: "elfenben",
-khaki: "khaki",
-lavender: "lysviolet",
-lavenderblush: "lavendelrød",
-lawngreen: "græsgrøn",
-lemonchiffon: "citronfromage",
-lightblue: "lyseblå",
-lightcoral: "lys koralrød",
-lightcyan: "lys cyan",
-lightgoldenrodyellow: "lys gyldenrisgul",
-lightgray: "lysegrå",
-lightgreen: "lysegrøn",
-lightgrey: "lysegrå", // same as lightgray
-lightpink: "lys pink",
-lightsalmon: "lys laksefarvet",
-lightseagreen: "lys havgrøn",
-lightskyblue: "lys himmelblå",
-lightslategray: "lys skifergrå",
-lightslategrey: "lys skifergrå", // same as lightslategray
-lightsteelblue: "lys stålblå",
-lightyellow: "lysegul",
-lime: "lime",
-limegreen: "limegrøn",
-linen: "lærred",
-magenta: "magenta",
-maroon: "rødbrun",
-mediumaquamarine: "mellem akvamarin",
-mediumblue: "mellemblå",
-mediumorchid: "mellem orkide",
-mediumpurple: "mellemlilla",
-mediumseagreen: "mellemhavgrøn",
-mediumslateblue: "mellemskiferblå",
-mediumspringgreen: "mellemforårsgrøn",
-mediumturquoise: "mellemturkis",
-mediumvioletred: "mellemviolet",
-midnightblue: "midnatsblå",
-mintcream: "pebermyntecreme",
-mistyrose: "blegrosa",
-moccasin: "fruesko",
-navajowhite: "navajo-hvid",
-navy: "marineblå",
-oldlace: "kniplingshvid",
-olive: "olivengrøn",
-olivedrab: "brungrøn",
-orange: "orange",
-orangered: "orangerød",
-orchid: "orkide",
-palegoldenrod: "bleg gyldenris",
-palegreen: "bleggrøn",
-paleturquoise: "bleg turkis",
-palevioletred: "blegviolet",
-papayawhip: "papaya",
-peachpuff: "fersken",
-peru: "peru",
-pink: "pink",
-plum: "blomme",
-powderblue: "pudderblå",
-purple: "lilla",
-red: "rød",
-rosybrown: "rosabrun",
-royalblue: "kongeblå",
-saddlebrown: "saddelbrun",
-salmon: "laksefarvet",
-sandybrown: "sandbrun",
-seagreen: "havgrøn",
-seashell: "muslingeskal",
-sienna: "sienna",
-silver: "sølv",
-skyblue: "himmelblå",
-slateblue: "skiferblå",
-slategray: "skifergrå",
-slategrey: "skifergrå", // same as slategray
-snow: "sne",
-springgreen: "forårsgrøn",
-steelblue: "metalblå",
-tan: "tan",
-teal: "blågrøn",
-thistle: "tidsel",
-tomato: "tomat",
-transparent: "transparent",
-turquoise: "turkis",
-violet: "lilla",
-wheat: "korngul",
-white: "hvid",
-whitesmoke: "hvid røg",
-yellow: "gul",
-yellowgreen: "gulgrøn"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "babyblå",
+	antiquewhite: "antikhvid",
+	aqua: "akvablå",
+	aquamarine: "akvamarin",
+	azure: "azurblå",
+	beige: "beige",
+	bisque: "gulgrå",
+	black: "sort",
+	blanchedalmond: "blanceret mandel",
+	blue: "blå",
+	blueviolet: "blåviolet",
+	brown: "brun",
+	burlywood: "tobak",
+	cadetblue: "kadetblå",
+	chartreuse: "chartreuse",
+	chocolate: "rust",
+	coral: "koralrød",
+	cornflowerblue: "kornblomstblå",
+	cornsilk: "majs",
+	crimson: "blodrød",
+	cyan: "cyan",
+	darkblue: "mørkeblå",
+	darkcyan: "mørk cyan",
+	darkgoldenrod: "mørk gyldenris",
+	darkgray: "mørkegrå",
+	darkgreen: "mørkegrøn",
+	darkgrey: "mørkegrå", // same as darkgray
+	darkkhaki: "mørk khaki",
+	darkmagenta: "mørk magenta",
+	darkolivegreen: "mørk olivengrøn",
+	darkorange: "mørk orange",
+	darkorchid: "mørk orkide",
+	darkred: "mørkerød",
+	darksalmon: "mørk laksefarvet",
+	darkseagreen: "mørk havgrøn",
+	darkslateblue: "mørk skiferblå",
+	darkslategray: "mørk skifergrå",
+	darkslategrey: "mørk skifergrå", // same as darkslategray
+	darkturquoise: "mørk turkis",
+	darkviolet: "mørkelilla",
+	deeppink: "dyb pink",
+	deepskyblue: "dyb himmelblå",
+	dimgray: "svag grå",
+	dimgrey: "svag grå", // same as dimgray
+	dodgerblue: "dodgerblå",
+	firebrick: "chamottesten",
+	floralwhite: "blomsterhvid",
+	forestgreen: "skovgrøn",
+	fuchsia: "lyslilla",
+	gainsboro: "gainsboro",
+	ghostwhite: "spøgelseshvid",
+	gold: "guld",
+	goldenrod: "gyldenris",
+	gray: "grå",
+	green: "grøn",
+	greenyellow: "grøngul",
+	grey: "grå", // same as gray
+	honeydew: "honningdug",
+	hotpink: "mørk rosa",
+	indianred: "lys rødbrun",
+	indigo: "indigo",
+	ivory: "elfenben",
+	khaki: "khaki",
+	lavender: "lysviolet",
+	lavenderblush: "lavendelrød",
+	lawngreen: "græsgrøn",
+	lemonchiffon: "citronfromage",
+	lightblue: "lyseblå",
+	lightcoral: "lys koralrød",
+	lightcyan: "lys cyan",
+	lightgoldenrodyellow: "lys gyldenrisgul",
+	lightgray: "lysegrå",
+	lightgreen: "lysegrøn",
+	lightgrey: "lysegrå", // same as lightgray
+	lightpink: "lys pink",
+	lightsalmon: "lys laksefarvet",
+	lightseagreen: "lys havgrøn",
+	lightskyblue: "lys himmelblå",
+	lightslategray: "lys skifergrå",
+	lightslategrey: "lys skifergrå", // same as lightslategray
+	lightsteelblue: "lys stålblå",
+	lightyellow: "lysegul",
+	lime: "lime",
+	limegreen: "limegrøn",
+	linen: "lærred",
+	magenta: "magenta",
+	maroon: "rødbrun",
+	mediumaquamarine: "mellem akvamarin",
+	mediumblue: "mellemblå",
+	mediumorchid: "mellem orkide",
+	mediumpurple: "mellemlilla",
+	mediumseagreen: "mellemhavgrøn",
+	mediumslateblue: "mellemskiferblå",
+	mediumspringgreen: "mellemforårsgrøn",
+	mediumturquoise: "mellemturkis",
+	mediumvioletred: "mellemviolet",
+	midnightblue: "midnatsblå",
+	mintcream: "pebermyntecreme",
+	mistyrose: "blegrosa",
+	moccasin: "fruesko",
+	navajowhite: "navajo-hvid",
+	navy: "marineblå",
+	oldlace: "kniplingshvid",
+	olive: "olivengrøn",
+	olivedrab: "brungrøn",
+	orange: "orange",
+	orangered: "orangerød",
+	orchid: "orkide",
+	palegoldenrod: "bleg gyldenris",
+	palegreen: "bleggrøn",
+	paleturquoise: "bleg turkis",
+	palevioletred: "blegviolet",
+	papayawhip: "papaya",
+	peachpuff: "fersken",
+	peru: "peru",
+	pink: "pink",
+	plum: "blomme",
+	powderblue: "pudderblå",
+	purple: "lilla",
+	red: "rød",
+	rosybrown: "rosabrun",
+	royalblue: "kongeblå",
+	saddlebrown: "saddelbrun",
+	salmon: "laksefarvet",
+	sandybrown: "sandbrun",
+	seagreen: "havgrøn",
+	seashell: "muslingeskal",
+	sienna: "sienna",
+	silver: "sølv",
+	skyblue: "himmelblå",
+	slateblue: "skiferblå",
+	slategray: "skifergrå",
+	slategrey: "skifergrå", // same as slategray
+	snow: "sne",
+	springgreen: "forårsgrøn",
+	steelblue: "metalblå",
+	tan: "tan",
+	teal: "blågrøn",
+	thistle: "tidsel",
+	tomato: "tomat",
+	transparent: "transparent",
+	turquoise: "turkis",
+	violet: "lilla",
+	wheat: "korngul",
+	white: "hvid",
+	whitesmoke: "hvid røg",
+	yellow: "gul",
+	yellowgreen: "gulgrøn"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/de/colors.js b/dojo/nls/de/colors.js
index cc7ca92..41648e0 100644
--- a/dojo/nls/de/colors.js
+++ b/dojo/nls/de/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "Alice-blau",
-antiquewhite: "Antikweiß",
-aqua: "Wasserblau",
-aquamarine: "Aquamarin",
-azure: "Azur",
-beige: "Beige",
-bisque: "Bisquit",
-black: "Schwarz",
-blanchedalmond: "Mandelweiß",
-blue: "Blau",
-blueviolet: "Blauviolett",
-brown: "Braun",
-burlywood: "Burlywood",
-cadetblue: "Kadettenblau",
-chartreuse: "Helles Gelbgrün",
-chocolate: "Schokoladenbraun",
-coral: "Koralle",
-cornflowerblue: "Kornblumenblau",
-cornsilk: "Kornseide",
-crimson: "Karmesinrot",
-cyan: "Zyan",
-darkblue: "Dunkelblau",
-darkcyan: "Dunkelzyan",
-darkgoldenrod: "Dunkelgoldgelb",
-darkgray: "Dunkelgrau",
-darkgreen: "Dunkelgrün",
-darkgrey: "Dunkelgrau", // same as darkgray
-darkkhaki: "Dunkelkhaki",
-darkmagenta: "Dunkelmagenta",
-darkolivegreen: "Dunkelolivgrün",
-darkorange: "Dunkelorange",
-darkorchid: "Dunkelorchidee",
-darkred: "Dunkelrot",
-darksalmon: "Dunkellachs",
-darkseagreen: "Dunkles Meergrün",
-darkslateblue: "Dunkelschieferblau",
-darkslategray: "Dunkelschiefergrau",
-darkslategrey: "Dunkelschiefergrau", // same as darkslategray
-darkturquoise: "Dunkeltürkis",
-darkviolet: "Dunkelviolett",
-deeppink: "Tiefrosa",
-deepskyblue: "Dunkles Himmelblau",
-dimgray: "Blassgrau",
-dimgrey: "Blassgrau", // same as dimgray
-dodgerblue: "Dodger-blau",
-firebrick: "Schamottestein",
-floralwhite: "Blütenweiß",
-forestgreen: "Forstgrün",
-fuchsia: "Fuchsia",
-gainsboro: "Gainsboro",
-ghostwhite: "Geisterweiß",
-gold: "Gold",
-goldenrod: "Goldgelb",
-gray: "Grau",
-green: "Grün",
-greenyellow: "Grüngelb",
-grey: "Grau", // same as gray
-honeydew: "Honigtau",
-hotpink: "Knallrosa",
-indianred: "Indischrot",
-indigo: "Indigoblau",
-ivory: "Elfenbein",
-khaki: "Khaki",
-lavender: "Lavendelblau",
-lavenderblush: "Lavendelhauch",
-lawngreen: "Grasgrün",
-lemonchiffon: "Zitronenchiffon",
-lightblue: "Hellblau",
-lightcoral: "Hellkoralle",
-lightcyan: "Hellzyan",
-lightgoldenrodyellow: "Hellgoldgelb",
-lightgray: "Hellgrau",
-lightgreen: "Hellgrün",
-lightgrey: "Hellgrau", // same as lightgray
-lightpink: "Hellrosa",
-lightsalmon: "Helllachs",
-lightseagreen: "Helles Meergrün",
-lightskyblue: "Helles Himmelblau",
-lightslategray: "Helles Schiefergrau",
-lightslategrey: "Helles Schiefergrau", // same as lightslategray
-lightsteelblue: "Helles Stahlblau",
-lightyellow: "Hellgelb",
-lime: "Limone",
-limegreen: "Limonengrün",
-linen: "Leinen",
-magenta: "Magenta",
-maroon: "Kastanienbraun",
-mediumaquamarine: "Mittelaquamarin",
-mediumblue: "Mittelblau",
-mediumorchid: "Mittelorchidee",
-mediumpurple: "Mittelpurpur",
-mediumseagreen: "Mittelmeeresgrün",
-mediumslateblue: "Mittelschieferblau ",
-mediumspringgreen: "Mittelfrühlingsgrün",
-mediumturquoise: "Mitteltürkis ",
-mediumvioletred: "Mittelviolettrot ",
-midnightblue: "Mitternachtblau",
-mintcream: "Mintcreme",
-mistyrose: "Blassrose",
-moccasin: "Mokassin",
-navajowhite: "Navajo-weiß",
-navy: "Marineblau",
-oldlace: "Alte Spitze",
-olive: "Oliv",
-olivedrab: "Olivgrau",
-orange: "Orange",
-orangered: "Orangerot",
-orchid: "Orchidee",
-palegoldenrod: "Blassgoldgelb",
-palegreen: "Blassgrün",
-paleturquoise: "Blasstürkis",
-palevioletred: "Blassviolettrot ",
-papayawhip: "Papayacreme",
-peachpuff: "Pfirsich",
-peru: "Peru",
-pink: "Rosa",
-plum: "Pflaume",
-powderblue: "Pulverblau",
-purple: "Purpurrot",
-red: "Rot",
-rosybrown: "Rosigbraun",
-royalblue: "Königsblau",
-saddlebrown: "Sattelbraun",
-salmon: "Lachs",
-sandybrown: "Sandbraun",
-seagreen: "Meeresgrün",
-seashell: "Muschelweiß",
-sienna: "Sienna",
-silver: "Silbergrau",
-skyblue: "Himmelblau",
-slateblue: "Schieferblau",
-slategray: "Schiefergrau",
-slategrey: "Schiefergrau", // same as slategray
-snow: "Schneeweiß",
-springgreen: "Frühlingsgrün",
-steelblue: "Stahlblau",
-tan: "Hautfarben",
-teal: "Smaragdgrün",
-thistle: "Distel",
-tomato: "Tomatenrot",
-transparent: "Transparent",
-turquoise: "Türkis",
-violet: "Violett",
-wheat: "Weizen",
-white: "Weiß",
-whitesmoke: "Rauchweiß",
-yellow: "Gelb",
-yellowgreen: "Gelbgrün"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "Alice-blau",
+	antiquewhite: "Antikweiß",
+	aqua: "Wasserblau",
+	aquamarine: "Aquamarin",
+	azure: "Azur",
+	beige: "Beige",
+	bisque: "Bisquit",
+	black: "Schwarz",
+	blanchedalmond: "Mandelweiß",
+	blue: "Blau",
+	blueviolet: "Blauviolett",
+	brown: "Braun",
+	burlywood: "Burlywood",
+	cadetblue: "Kadettenblau",
+	chartreuse: "Helles Gelbgrün",
+	chocolate: "Schokoladenbraun",
+	coral: "Koralle",
+	cornflowerblue: "Kornblumenblau",
+	cornsilk: "Kornseide",
+	crimson: "Karmesinrot",
+	cyan: "Zyan",
+	darkblue: "Dunkelblau",
+	darkcyan: "Dunkelzyan",
+	darkgoldenrod: "Dunkelgoldgelb",
+	darkgray: "Dunkelgrau",
+	darkgreen: "Dunkelgrün",
+	darkgrey: "Dunkelgrau", // same as darkgray
+	darkkhaki: "Dunkelkhaki",
+	darkmagenta: "Dunkelmagenta",
+	darkolivegreen: "Dunkelolivgrün",
+	darkorange: "Dunkelorange",
+	darkorchid: "Dunkelorchidee",
+	darkred: "Dunkelrot",
+	darksalmon: "Dunkellachs",
+	darkseagreen: "Dunkles Meergrün",
+	darkslateblue: "Dunkelschieferblau",
+	darkslategray: "Dunkelschiefergrau",
+	darkslategrey: "Dunkelschiefergrau", // same as darkslategray
+	darkturquoise: "Dunkeltürkis",
+	darkviolet: "Dunkelviolett",
+	deeppink: "Tiefrosa",
+	deepskyblue: "Dunkles Himmelblau",
+	dimgray: "Blassgrau",
+	dimgrey: "Blassgrau", // same as dimgray
+	dodgerblue: "Dodger-blau",
+	firebrick: "Schamottestein",
+	floralwhite: "Blütenweiß",
+	forestgreen: "Forstgrün",
+	fuchsia: "Fuchsia",
+	gainsboro: "Gainsboro",
+	ghostwhite: "Geisterweiß",
+	gold: "Gold",
+	goldenrod: "Goldgelb",
+	gray: "Grau",
+	green: "Grün",
+	greenyellow: "Grüngelb",
+	grey: "Grau", // same as gray
+	honeydew: "Honigtau",
+	hotpink: "Knallrosa",
+	indianred: "Indischrot",
+	indigo: "Indigoblau",
+	ivory: "Elfenbein",
+	khaki: "Khaki",
+	lavender: "Lavendelblau",
+	lavenderblush: "Lavendelhauch",
+	lawngreen: "Grasgrün",
+	lemonchiffon: "Zitronenchiffon",
+	lightblue: "Hellblau",
+	lightcoral: "Hellkoralle",
+	lightcyan: "Hellzyan",
+	lightgoldenrodyellow: "Hellgoldgelb",
+	lightgray: "Hellgrau",
+	lightgreen: "Hellgrün",
+	lightgrey: "Hellgrau", // same as lightgray
+	lightpink: "Hellrosa",
+	lightsalmon: "Helllachs",
+	lightseagreen: "Helles Meergrün",
+	lightskyblue: "Helles Himmelblau",
+	lightslategray: "Helles Schiefergrau",
+	lightslategrey: "Helles Schiefergrau", // same as lightslategray
+	lightsteelblue: "Helles Stahlblau",
+	lightyellow: "Hellgelb",
+	lime: "Limone",
+	limegreen: "Limonengrün",
+	linen: "Leinen",
+	magenta: "Magenta",
+	maroon: "Kastanienbraun",
+	mediumaquamarine: "Mittelaquamarin",
+	mediumblue: "Mittelblau",
+	mediumorchid: "Mittelorchidee",
+	mediumpurple: "Mittelpurpur",
+	mediumseagreen: "Mittelmeeresgrün",
+	mediumslateblue: "Mittelschieferblau ",
+	mediumspringgreen: "Mittelfrühlingsgrün",
+	mediumturquoise: "Mitteltürkis ",
+	mediumvioletred: "Mittelviolettrot ",
+	midnightblue: "Mitternachtblau",
+	mintcream: "Mintcreme",
+	mistyrose: "Blassrose",
+	moccasin: "Mokassin",
+	navajowhite: "Navajo-weiß",
+	navy: "Marineblau",
+	oldlace: "Alte Spitze",
+	olive: "Oliv",
+	olivedrab: "Olivgrau",
+	orange: "Orange",
+	orangered: "Orangerot",
+	orchid: "Orchidee",
+	palegoldenrod: "Blassgoldgelb",
+	palegreen: "Blassgrün",
+	paleturquoise: "Blasstürkis",
+	palevioletred: "Blassviolettrot ",
+	papayawhip: "Papayacreme",
+	peachpuff: "Pfirsich",
+	peru: "Peru",
+	pink: "Rosa",
+	plum: "Pflaume",
+	powderblue: "Pulverblau",
+	purple: "Purpurrot",
+	red: "Rot",
+	rosybrown: "Rosigbraun",
+	royalblue: "Königsblau",
+	saddlebrown: "Sattelbraun",
+	salmon: "Lachs",
+	sandybrown: "Sandbraun",
+	seagreen: "Meeresgrün",
+	seashell: "Muschelweiß",
+	sienna: "Sienna",
+	silver: "Silbergrau",
+	skyblue: "Himmelblau",
+	slateblue: "Schieferblau",
+	slategray: "Schiefergrau",
+	slategrey: "Schiefergrau", // same as slategray
+	snow: "Schneeweiß",
+	springgreen: "Frühlingsgrün",
+	steelblue: "Stahlblau",
+	tan: "Hautfarben",
+	teal: "Smaragdgrün",
+	thistle: "Distel",
+	tomato: "Tomatenrot",
+	transparent: "Transparent",
+	turquoise: "Türkis",
+	violet: "Violett",
+	wheat: "Weizen",
+	white: "Weiß",
+	whitesmoke: "Rauchweiß",
+	yellow: "Gelb",
+	yellowgreen: "Gelbgrün"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/el/colors.js b/dojo/nls/el/colors.js
index 141e777..5ce1319 100644
--- a/dojo/nls/el/colors.js
+++ b/dojo/nls/el/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "σιέλ",
-antiquewhite: "ξεθωριασμένο λευκό",
-aqua: "γαλάζιο",
-aquamarine: "γαλαζοπράσινο",
-azure: "μπλε του ουρανού",
-beige: "μπεζ",
-bisque: "σκούρο κρεμ",
-black: "μαύρο",
-blanchedalmond: "ζαχαρί",
-blue: "μπλε",
-blueviolet: "βιολετί",
-brown: "καφέ",
-burlywood: "καφέ του ξύλου",
-cadetblue: "μπλε του στρατού",
-chartreuse: "φωτεινό κιτρινοπράσινο",
-chocolate: "σοκολατί",
-coral: "κοραλί",
-cornflowerblue: "μεσαίο μπλε",
-cornsilk: "ασημί του καλαμποκιού",
-crimson: "βαθύ κόκκινο",
-cyan: "κυανό",
-darkblue: "σκούρο μπλε",
-darkcyan: "σκούρο κυανό",
-darkgoldenrod: "σκούρο χρυσοκίτρινο",
-darkgray: "σκούρο γκρι",
-darkgreen: "σκούρο πράσινο",
-darkgrey: "σκούρο γκρι", // same as darkgray
-darkkhaki: "σκούρο χακί",
-darkmagenta: "σκούρο ματζέντα",
-darkolivegreen: "σκούρο πράσινο λαδί",
-darkorange: "σκούρο πορτοκαλί",
-darkorchid: "σκούρα ορχιδέα",
-darkred: "σκούρο κόκκινο",
-darksalmon: "σκούρο σομόν",
-darkseagreen: "σκούρο πράσινο της θάλασσας",
-darkslateblue: "σκούρο μεταλλικό μπλε",
-darkslategray: "σκούρο μεταλλικό γκρι",
-darkslategrey: "σκούρο μεταλλικό γκρι", // same as darkslategray
-darkturquoise: "σκούρο τυρκουάζ",
-darkviolet: "σκούρο βιολετί",
-deeppink: "βαθύ ροζ",
-deepskyblue: "βαθύ μπλε το ουρανού",
-dimgray: "αχνό γκρι",
-dimgrey: "αχνό γκρι", // same as dimgray
-dodgerblue: "σκούρο ελεκτρίκ",
-firebrick: "κεραμιδί",
-floralwhite: "λευκό των ανθών",
-forestgreen: "πράσινο του δάσους",
-fuchsia: "φούξια",
-gainsboro: "γκρι σιέλ",
-ghostwhite: "άσπρο",
-gold: "χρυσαφί",
-goldenrod: "χρυσοκίτρινο",
-gray: "γκρι",
-green: "πράσινο",
-greenyellow: "πρασινοκίτρινο",
-grey: "γκρι", // same as gray
-honeydew: "μελί",
-hotpink: "έντονο ροζ",
-indianred: "ινδικό κόκκινο",
-indigo: "λουλακί",
-ivory: "ιβουάρ",
-khaki: "χακί",
-lavender: "λίλα",
-lavenderblush: "μωβ λεβάντας",
-lawngreen: "σκούρο πράσινο",
-lemonchiffon: "λεμονί",
-lightblue: "ανοιχτό μπλε",
-lightcoral: "ανοιχτό κοραλί",
-lightcyan: "ανοιχτό κυανό",
-lightgoldenrodyellow: "ανοιχτό χρυσοκίτρινο",
-lightgray: "ανοιχτό γκρι",
-lightgreen: "ανοιχτό πράσινο",
-lightgrey: "ανοιχτό γκρι", // same as lightgray
-lightpink: "ανοιχτό ροζ",
-lightsalmon: "ανοιχτό σομόν",
-lightseagreen: "ανοιχτό πράσινο της θάλασσας",
-lightskyblue: "ανοιχτό μπλε το ουρανού",
-lightslategray: "ανοιχτό μεταλλικό γκρι",
-lightslategrey: "ανοιχτό μεταλλικό γκρι", // same as lightslategray
-lightsteelblue: "ανοιχτό μπλε ατσαλιού",
-lightyellow: "ανοιχτό κίτρινο",
-lime: "λαχανί",
-limegreen: "πράσινο λαχανί",
-linen: "σπαγγί",
-magenta: "ματζέντα",
-maroon: "βυσσινί",
-mediumaquamarine: "μεσαίο γαλαζοπράσινο",
-mediumblue: "μεσαίο μπλε",
-mediumorchid: "μεσαία ορχιδέα",
-mediumpurple: "μεσαίο μωβ",
-mediumseagreen: "μεσαίο πράσινο της θάλασσας",
-mediumslateblue: "μεσαίο μεταλλικό μπλε",
-mediumspringgreen: "μεσαίο πράσινο της άνοιξης",
-mediumturquoise: "μεσαίο τυρκουάζ",
-mediumvioletred: "μεσαίο κόκκινο βιολετί",
-midnightblue: "πολύ σκούρο μπλε",
-mintcream: "βεραμάν",
-mistyrose: "τριανταφυλλί",
-moccasin: "μόκα",
-navajowhite: "άσπρο Ναβάχο",
-navy: "μπλε του ναυτικού",
-oldlace: "εκρού",
-olive: "πράσινο λαδί",
-olivedrab: "λαδί",
-orange: "πορτοκαλί",
-orangered: "πορτοκαλοκόκκινο",
-orchid: "ορχιδέα",
-palegoldenrod: "αχνό χρυσοκίτρινο",
-palegreen: "αχνό πράσινο",
-paleturquoise: "αχνό τυρκουάζ",
-palevioletred: "αχνό κόκκινο βιολετί",
-papayawhip: "αχνό ροζ",
-peachpuff: "ροδακινί",
-peru: "περού",
-pink: "ροζ",
-plum: "δαμασκηνί",
-powderblue: "αχνό μπλε",
-purple: "μωβ",
-red: "κόκκινο",
-rosybrown: "καστανό",
-royalblue: "έντονο μπλε",
-saddlebrown: "βαθύ καφέ",
-salmon: "σομόν",
-sandybrown: "μπεζ της άμμου",
-seagreen: "πράσινο της θάλασσας",
-seashell: "κοχύλι",
-sienna: "καφεκίτρινο",
-silver: "ασημί",
-skyblue: "μπλε του ουρανού",
-slateblue: "μεταλλικό μπλε",
-slategray: "μεταλλικό γκρι",
-slategrey: "μεταλλικό γκρι", // same as slategray
-snow: "χιονί",
-springgreen: "πράσινο της άνοιξης",
-steelblue: "μπλε ατσαλιού",
-tan: "ώχρα",
-teal: "πετρόλ",
-thistle: "μωβ βιολετί",
-tomato: "κόκκινο της ντομάτας",
-transparent: "διαφανές",
-turquoise: "τυρκουάζ",
-violet: "βιολετί",
-wheat: "σταρένιο",
-white: "λευκό",
-whitesmoke: "λευκός καπνός",
-yellow: "κίτρινο",
-yellowgreen: "κιτρινοπράσινο"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "σιέλ",
+	antiquewhite: "ξεθωριασμένο λευκό",
+	aqua: "γαλάζιο",
+	aquamarine: "γαλαζοπράσινο",
+	azure: "μπλε του ουρανού",
+	beige: "μπεζ",
+	bisque: "σκούρο κρεμ",
+	black: "μαύρο",
+	blanchedalmond: "ζαχαρί",
+	blue: "μπλε",
+	blueviolet: "βιολετί",
+	brown: "καφέ",
+	burlywood: "καφέ του ξύλου",
+	cadetblue: "μπλε του στρατού",
+	chartreuse: "φωτεινό κιτρινοπράσινο",
+	chocolate: "σοκολατί",
+	coral: "κοραλί",
+	cornflowerblue: "μεσαίο μπλε",
+	cornsilk: "ασημί του καλαμποκιού",
+	crimson: "βαθύ κόκκινο",
+	cyan: "κυανό",
+	darkblue: "σκούρο μπλε",
+	darkcyan: "σκούρο κυανό",
+	darkgoldenrod: "σκούρο χρυσοκίτρινο",
+	darkgray: "σκούρο γκρι",
+	darkgreen: "σκούρο πράσινο",
+	darkgrey: "σκούρο γκρι", // same as darkgray
+	darkkhaki: "σκούρο χακί",
+	darkmagenta: "σκούρο ματζέντα",
+	darkolivegreen: "σκούρο πράσινο λαδί",
+	darkorange: "σκούρο πορτοκαλί",
+	darkorchid: "σκούρα ορχιδέα",
+	darkred: "σκούρο κόκκινο",
+	darksalmon: "σκούρο σομόν",
+	darkseagreen: "σκούρο πράσινο της θάλασσας",
+	darkslateblue: "σκούρο μεταλλικό μπλε",
+	darkslategray: "σκούρο μεταλλικό γκρι",
+	darkslategrey: "σκούρο μεταλλικό γκρι", // same as darkslategray
+	darkturquoise: "σκούρο τυρκουάζ",
+	darkviolet: "σκούρο βιολετί",
+	deeppink: "βαθύ ροζ",
+	deepskyblue: "βαθύ μπλε το ουρανού",
+	dimgray: "αχνό γκρι",
+	dimgrey: "αχνό γκρι", // same as dimgray
+	dodgerblue: "σκούρο ελεκτρίκ",
+	firebrick: "κεραμιδί",
+	floralwhite: "λευκό των ανθών",
+	forestgreen: "πράσινο του δάσους",
+	fuchsia: "φούξια",
+	gainsboro: "γκρι σιέλ",
+	ghostwhite: "άσπρο",
+	gold: "χρυσαφί",
+	goldenrod: "χρυσοκίτρινο",
+	gray: "γκρι",
+	green: "πράσινο",
+	greenyellow: "πρασινοκίτρινο",
+	grey: "γκρι", // same as gray
+	honeydew: "μελί",
+	hotpink: "έντονο ροζ",
+	indianred: "ινδικό κόκκινο",
+	indigo: "λουλακί",
+	ivory: "ιβουάρ",
+	khaki: "χακί",
+	lavender: "λίλα",
+	lavenderblush: "μωβ λεβάντας",
+	lawngreen: "σκούρο πράσινο",
+	lemonchiffon: "λεμονί",
+	lightblue: "ανοιχτό μπλε",
+	lightcoral: "ανοιχτό κοραλί",
+	lightcyan: "ανοιχτό κυανό",
+	lightgoldenrodyellow: "ανοιχτό χρυσοκίτρινο",
+	lightgray: "ανοιχτό γκρι",
+	lightgreen: "ανοιχτό πράσινο",
+	lightgrey: "ανοιχτό γκρι", // same as lightgray
+	lightpink: "ανοιχτό ροζ",
+	lightsalmon: "ανοιχτό σομόν",
+	lightseagreen: "ανοιχτό πράσινο της θάλασσας",
+	lightskyblue: "ανοιχτό μπλε το ουρανού",
+	lightslategray: "ανοιχτό μεταλλικό γκρι",
+	lightslategrey: "ανοιχτό μεταλλικό γκρι", // same as lightslategray
+	lightsteelblue: "ανοιχτό μπλε ατσαλιού",
+	lightyellow: "ανοιχτό κίτρινο",
+	lime: "λαχανί",
+	limegreen: "πράσινο λαχανί",
+	linen: "σπαγγί",
+	magenta: "ματζέντα",
+	maroon: "βυσσινί",
+	mediumaquamarine: "μεσαίο γαλαζοπράσινο",
+	mediumblue: "μεσαίο μπλε",
+	mediumorchid: "μεσαία ορχιδέα",
+	mediumpurple: "μεσαίο μωβ",
+	mediumseagreen: "μεσαίο πράσινο της θάλασσας",
+	mediumslateblue: "μεσαίο μεταλλικό μπλε",
+	mediumspringgreen: "μεσαίο πράσινο της άνοιξης",
+	mediumturquoise: "μεσαίο τυρκουάζ",
+	mediumvioletred: "μεσαίο κόκκινο βιολετί",
+	midnightblue: "πολύ σκούρο μπλε",
+	mintcream: "βεραμάν",
+	mistyrose: "τριανταφυλλί",
+	moccasin: "μόκα",
+	navajowhite: "άσπρο Ναβάχο",
+	navy: "μπλε του ναυτικού",
+	oldlace: "εκρού",
+	olive: "πράσινο λαδί",
+	olivedrab: "λαδί",
+	orange: "πορτοκαλί",
+	orangered: "πορτοκαλοκόκκινο",
+	orchid: "ορχιδέα",
+	palegoldenrod: "αχνό χρυσοκίτρινο",
+	palegreen: "αχνό πράσινο",
+	paleturquoise: "αχνό τυρκουάζ",
+	palevioletred: "αχνό κόκκινο βιολετί",
+	papayawhip: "αχνό ροζ",
+	peachpuff: "ροδακινί",
+	peru: "περού",
+	pink: "ροζ",
+	plum: "δαμασκηνί",
+	powderblue: "αχνό μπλε",
+	purple: "μωβ",
+	red: "κόκκινο",
+	rosybrown: "καστανό",
+	royalblue: "έντονο μπλε",
+	saddlebrown: "βαθύ καφέ",
+	salmon: "σομόν",
+	sandybrown: "μπεζ της άμμου",
+	seagreen: "πράσινο της θάλασσας",
+	seashell: "κοχύλι",
+	sienna: "καφεκίτρινο",
+	silver: "ασημί",
+	skyblue: "μπλε του ουρανού",
+	slateblue: "μεταλλικό μπλε",
+	slategray: "μεταλλικό γκρι",
+	slategrey: "μεταλλικό γκρι", // same as slategray
+	snow: "χιονί",
+	springgreen: "πράσινο της άνοιξης",
+	steelblue: "μπλε ατσαλιού",
+	tan: "ώχρα",
+	teal: "πετρόλ",
+	thistle: "μωβ βιολετί",
+	tomato: "κόκκινο της ντομάτας",
+	transparent: "διαφανές",
+	turquoise: "τυρκουάζ",
+	violet: "βιολετί",
+	wheat: "σταρένιο",
+	white: "λευκό",
+	whitesmoke: "λευκός καπνός",
+	yellow: "κίτρινο",
+	yellowgreen: "κιτρινοπράσινο"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/es/colors.js b/dojo/nls/es/colors.js
index 54d78f2..1e99832 100644
--- a/dojo/nls/es/colors.js
+++ b/dojo/nls/es/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "blanco azulado",
-antiquewhite: "blanco antiguo",
-aqua: "aguamarina",
-aquamarine: "aguamarina 2",
-azure: "blanco cielo",
-beige: "beige",
-bisque: "miel",
-black: "negro",
-blanchedalmond: "almendra pálido",
-blue: "azul",
-blueviolet: "azul violáceo",
-brown: "marrón",
-burlywood: "madera",
-cadetblue: "azul cadete",
-chartreuse: "verde pálido 2",
-chocolate: "chocolate",
-coral: "coral",
-cornflowerblue: "azul aciano",
-cornsilk: "crudo",
-crimson: "carmesí",
-cyan: "cian",
-darkblue: "azul oscuro",
-darkcyan: "cian oscuro",
-darkgoldenrod: "ocre oscuro",
-darkgray: "gris oscuro",
-darkgreen: "verde oscuro",
-darkgrey: "gris oscuro", // same as darkgray
-darkkhaki: "caqui oscuro",
-darkmagenta: "magenta oscuro",
-darkolivegreen: "verde oliva oscuro",
-darkorange: "naranja oscuro",
-darkorchid: "orquídea oscuro",
-darkred: "rojo oscuro",
-darksalmon: "salmón oscuro",
-darkseagreen: "verde mar oscuro",
-darkslateblue: "azul pizarra oscuro",
-darkslategray: "gris pizarra oscuro",
-darkslategrey: "gris pizarra oscuro", // same as darkslategray
-darkturquoise: "turquesa oscuro",
-darkviolet: "violeta oscuro",
-deeppink: "rosa fuerte",
-deepskyblue: "azul cielo fuerte",
-dimgray: "gris marengo",
-dimgrey: "gris marengo", // same as dimgray
-dodgerblue: "azul fuerte",
-firebrick: "teja",
-floralwhite: "blanco manteca",
-forestgreen: "verde pino",
-fuchsia: "fucsia",
-gainsboro: "azul gainsboro",
-ghostwhite: "blanco ligero",
-gold: "oro",
-goldenrod: "ocre",
-gray: "gris",
-green: "verde",
-greenyellow: "amarillo verdoso",
-grey: "gris", // same as gray
-honeydew: "flor de rocío",
-hotpink: "rosa oscuro",
-indianred: "rojo teja",
-indigo: "añil",
-ivory: "marfil",
-khaki: "caqui",
-lavender: "lavanda",
-lavenderblush: "lavanda rosácea",
-lawngreen: "verde césped",
-lemonchiffon: "amarillo pastel",
-lightblue: "azul claro",
-lightcoral: "coral claro",
-lightcyan: "cian claro",
-lightgoldenrodyellow: "ocre claro",
-lightgray: "gris claro",
-lightgreen: "verde claro",
-lightgrey: "gris claro", // same as lightgray
-lightpink: "rosa claro",
-lightsalmon: "salmón claro",
-lightseagreen: "verde mar claro",
-lightskyblue: "azul cielo claro",
-lightslategray: "gris pizarra claro",
-lightslategrey: "gris pizarra claro", // same as lightslategray
-lightsteelblue: "azul acero claro",
-lightyellow: "amarillo claro",
-lime: "lima",
-limegreen: "lima limón",
-linen: "blanco arena",
-magenta: "magenta",
-maroon: "granate",
-mediumaquamarine: "aguamarina medio",
-mediumblue: "azul medio",
-mediumorchid: "orquídea medio",
-mediumpurple: "púrpura medio",
-mediumseagreen: "verde mar medio",
-mediumslateblue: "azul pizarra medio",
-mediumspringgreen: "verde primavera medio",
-mediumturquoise: "turquesa medio",
-mediumvioletred: "rojo violáceo medio",
-midnightblue: "azul medianoche",
-mintcream: "crema menta",
-mistyrose: "rosa difuminado",
-moccasin: "arena",
-navajowhite: "blanco navajo",
-navy: "azul marino",
-oldlace: "encaje antiguo",
-olive: "verde oliva",
-olivedrab: "verde oliva pardusco",
-orange: "naranja",
-orangered: "rojo anaranjado",
-orchid: "orquídea",
-palegoldenrod: "ocre pálido",
-palegreen: "verde pálido",
-paleturquoise: "turquesa pálido",
-palevioletred: "rojo violáceo pálido",
-papayawhip: "papaya claro",
-peachpuff: "melocotón",
-peru: "perú",
-pink: "rosa",
-plum: "ciruela",
-powderblue: "azul suave",
-purple: "púrpura",
-red: "rojo",
-rosybrown: "marrón rosáceo",
-royalblue: "azul real",
-saddlebrown: "cuero",
-salmon: "salmón",
-sandybrown: "marrón arcilla",
-seagreen: "verde mar",
-seashell: "blanco marfil",
-sienna: "siena",
-silver: "plateado",
-skyblue: "azul cielo",
-slateblue: "azul pizarra",
-slategray: "gris pizarra",
-slategrey: "gris pizarra", // same as slategray
-snow: "nieve",
-springgreen: "verde fuerte",
-steelblue: "azul acero",
-tan: "canela",
-teal: "verde azulado",
-thistle: "cardo",
-tomato: "tomate",
-transparent: "transparente",
-turquoise: "turquesa",
-violet: "violeta",
-wheat: "trigo",
-white: "blanco",
-whitesmoke: "blanco ahumado",
-yellow: "amarillo",
-yellowgreen: "verde amarillento"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "blanco azulado",
+	antiquewhite: "blanco antiguo",
+	aqua: "aguamarina",
+	aquamarine: "aguamarina 2",
+	azure: "blanco cielo",
+	beige: "beige",
+	bisque: "miel",
+	black: "negro",
+	blanchedalmond: "almendra pálido",
+	blue: "azul",
+	blueviolet: "azul violáceo",
+	brown: "marrón",
+	burlywood: "madera",
+	cadetblue: "azul cadete",
+	chartreuse: "verde pálido 2",
+	chocolate: "chocolate",
+	coral: "coral",
+	cornflowerblue: "azul aciano",
+	cornsilk: "crudo",
+	crimson: "carmesí",
+	cyan: "cian",
+	darkblue: "azul oscuro",
+	darkcyan: "cian oscuro",
+	darkgoldenrod: "ocre oscuro",
+	darkgray: "gris oscuro",
+	darkgreen: "verde oscuro",
+	darkgrey: "gris oscuro", // same as darkgray
+	darkkhaki: "caqui oscuro",
+	darkmagenta: "magenta oscuro",
+	darkolivegreen: "verde oliva oscuro",
+	darkorange: "naranja oscuro",
+	darkorchid: "orquídea oscuro",
+	darkred: "rojo oscuro",
+	darksalmon: "salmón oscuro",
+	darkseagreen: "verde mar oscuro",
+	darkslateblue: "azul pizarra oscuro",
+	darkslategray: "gris pizarra oscuro",
+	darkslategrey: "gris pizarra oscuro", // same as darkslategray
+	darkturquoise: "turquesa oscuro",
+	darkviolet: "violeta oscuro",
+	deeppink: "rosa fuerte",
+	deepskyblue: "azul cielo fuerte",
+	dimgray: "gris marengo",
+	dimgrey: "gris marengo", // same as dimgray
+	dodgerblue: "azul fuerte",
+	firebrick: "teja",
+	floralwhite: "blanco manteca",
+	forestgreen: "verde pino",
+	fuchsia: "fucsia",
+	gainsboro: "azul gainsboro",
+	ghostwhite: "blanco ligero",
+	gold: "oro",
+	goldenrod: "ocre",
+	gray: "gris",
+	green: "verde",
+	greenyellow: "amarillo verdoso",
+	grey: "gris", // same as gray
+	honeydew: "flor de rocío",
+	hotpink: "rosa oscuro",
+	indianred: "rojo teja",
+	indigo: "añil",
+	ivory: "marfil",
+	khaki: "caqui",
+	lavender: "lavanda",
+	lavenderblush: "lavanda rosácea",
+	lawngreen: "verde césped",
+	lemonchiffon: "amarillo pastel",
+	lightblue: "azul claro",
+	lightcoral: "coral claro",
+	lightcyan: "cian claro",
+	lightgoldenrodyellow: "ocre claro",
+	lightgray: "gris claro",
+	lightgreen: "verde claro",
+	lightgrey: "gris claro", // same as lightgray
+	lightpink: "rosa claro",
+	lightsalmon: "salmón claro",
+	lightseagreen: "verde mar claro",
+	lightskyblue: "azul cielo claro",
+	lightslategray: "gris pizarra claro",
+	lightslategrey: "gris pizarra claro", // same as lightslategray
+	lightsteelblue: "azul acero claro",
+	lightyellow: "amarillo claro",
+	lime: "lima",
+	limegreen: "lima limón",
+	linen: "blanco arena",
+	magenta: "magenta",
+	maroon: "granate",
+	mediumaquamarine: "aguamarina medio",
+	mediumblue: "azul medio",
+	mediumorchid: "orquídea medio",
+	mediumpurple: "púrpura medio",
+	mediumseagreen: "verde mar medio",
+	mediumslateblue: "azul pizarra medio",
+	mediumspringgreen: "verde primavera medio",
+	mediumturquoise: "turquesa medio",
+	mediumvioletred: "rojo violáceo medio",
+	midnightblue: "azul medianoche",
+	mintcream: "crema menta",
+	mistyrose: "rosa difuminado",
+	moccasin: "arena",
+	navajowhite: "blanco navajo",
+	navy: "azul marino",
+	oldlace: "encaje antiguo",
+	olive: "verde oliva",
+	olivedrab: "verde oliva pardusco",
+	orange: "naranja",
+	orangered: "rojo anaranjado",
+	orchid: "orquídea",
+	palegoldenrod: "ocre pálido",
+	palegreen: "verde pálido",
+	paleturquoise: "turquesa pálido",
+	palevioletred: "rojo violáceo pálido",
+	papayawhip: "papaya claro",
+	peachpuff: "melocotón",
+	peru: "perú",
+	pink: "rosa",
+	plum: "ciruela",
+	powderblue: "azul suave",
+	purple: "púrpura",
+	red: "rojo",
+	rosybrown: "marrón rosáceo",
+	royalblue: "azul real",
+	saddlebrown: "cuero",
+	salmon: "salmón",
+	sandybrown: "marrón arcilla",
+	seagreen: "verde mar",
+	seashell: "blanco marfil",
+	sienna: "siena",
+	silver: "plateado",
+	skyblue: "azul cielo",
+	slateblue: "azul pizarra",
+	slategray: "gris pizarra",
+	slategrey: "gris pizarra", // same as slategray
+	snow: "nieve",
+	springgreen: "verde fuerte",
+	steelblue: "azul acero",
+	tan: "canela",
+	teal: "verde azulado",
+	thistle: "cardo",
+	tomato: "tomate",
+	transparent: "transparente",
+	turquoise: "turquesa",
+	violet: "violeta",
+	wheat: "trigo",
+	white: "blanco",
+	whitesmoke: "blanco ahumado",
+	yellow: "amarillo",
+	yellowgreen: "verde amarillento"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/fi/colors.js b/dojo/nls/fi/colors.js
index 754b9dd..3943d68 100644
--- a/dojo/nls/fi/colors.js
+++ b/dojo/nls/fi/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "vaaleanharmaansininen",
-antiquewhite: "antiikinvalkoinen",
-aqua: "sinivihreä",
-aquamarine: "vedenvihreä",
-azure: "taivaansininen",
-beige: "vaaleanruskea",
-bisque: "vaaleanruskea",
-black: "musta",
-blanchedalmond: "kuorittu manteli",
-blue: "sininen",
-blueviolet: "sinivioletti",
-brown: "ruskea",
-burlywood: "puunruskea",
-cadetblue: "meren vihreä",
-chartreuse: "kellanvihreä",
-chocolate: "suklaanruskea",
-coral: "koralli",
-cornflowerblue: "syvänsininen",
-cornsilk: "maissinkeltainen",
-crimson: "karmiininpunainen",
-cyan: "syaani",
-darkblue: "tummansininen",
-darkcyan: "tumma turkoosi",
-darkgoldenrod: "tumma kultapiisku",
-darkgray: "tummanharmaa",
-darkgreen: "tummanvihreä",
-darkgrey: "tummanharmaa", // same as darkgray
-darkkhaki: "tumma khaki",
-darkmagenta: "tumma magenta",
-darkolivegreen: "tummanoliivinvihreä",
-darkorange: "tummanoranssi",
-darkorchid: "tumma orkidea",
-darkred: "tummanpunainen",
-darksalmon: "tumma lohenpunainen",
-darkseagreen: "tumma merenvihreä",
-darkslateblue: "tumma siniharmaa",
-darkslategray: "tummanharmaa",
-darkslategrey: "tummanharmaa", // same as darkslategray
-darkturquoise: "tumma turkoosi",
-darkviolet: "tummanvioletti",
-deeppink: "syvä vaaleanpunainen",
-deepskyblue: "tumma taivaansininen",
-dimgray: "himmeänharmaa",
-dimgrey: "himmeänharmaa", // same as dimgray
-dodgerblue: "Dodger-sininen",
-firebrick: "poltetun tiilen punainen",
-floralwhite: "kukanvalkoinen",
-forestgreen: "metsänvihreä",
-fuchsia: "purppura",
-gainsboro: "gainsboro",
-ghostwhite: "lakananvalkoinen",
-gold: "kulta",
-goldenrod: "kullanruskea",
-gray: "harmaa",
-green: "vihreä",
-greenyellow: "vihreänkeltainen",
-grey: "harmaa", // same as gray
-honeydew: "hunajameloninvihreä",
-hotpink: "pinkki",
-indianred: "kirkkaanpunainen",
-indigo: "indigo",
-ivory: "norsunluu",
-khaki: "khaki",
-lavender: "laventeli",
-lavenderblush: "laventelinpunainen",
-lawngreen: "ruohonvihreä",
-lemonchiffon: "sitruunankeltainen",
-lightblue: "vaaleansininen",
-lightcoral: "vaalea koralli",
-lightcyan: "vaalea syaani",
-lightgoldenrodyellow: "vaalea kultapiiskunkeltainen",
-lightgray: "vaaleanharmaa",
-lightgreen: "vaaleanvihreä",
-lightgrey: "vaaleanharmaa", // same as lightgray
-lightpink: "vaaleanpunainen",
-lightsalmon: "vaalea lohenpunainen",
-lightseagreen: "vaalea merenvihreä",
-lightskyblue: "vaalea taivaansininen",
-lightslategray: "vaaleanharmaa",
-lightslategrey: "vaaleanharmaa", // same as lightslategray
-lightsteelblue: "vaalea teräksensininen",
-lightyellow: "vaaleankeltainen",
-lime: "vaaleanvihreä",
-limegreen: "limetinvihreä",
-linen: "pellavanvaalea",
-magenta: "magenta",
-maroon: "kastanjanruskea",
-mediumaquamarine: "keskivaalea vedenvihreä",
-mediumblue: "keskisininen",
-mediumorchid: "keskivaalea orkidea",
-mediumpurple: "keskivaalea violetti",
-mediumseagreen: "keskivaalea merenvihreä",
-mediumslateblue: "keskivaalea siniharmaa",
-mediumspringgreen: "keskivaalea keväänvihreä",
-mediumturquoise: "keskivaalea turkoosi",
-mediumvioletred: "keskivaalea lila",
-midnightblue: "yönsininen",
-mintcream: "minttukreemi",
-mistyrose: "utuinen ruusu",
-moccasin: "nahanruskea",
-navajowhite: "navajonvalkoinen",
-navy: "laivastonsininen",
-oldlace: "vanha pitsi",
-olive: "oliivinvihreä",
-olivedrab: "oliivinruskea",
-orange: "oranssi",
-orangered: "oranssinpunainen",
-orchid: "orkidea",
-palegoldenrod: "haalea kultapiisku",
-palegreen: "haalea vihreä",
-paleturquoise: "haalea turkoosi",
-palevioletred: "haalea lila",
-papayawhip: "papaijavaahto",
-peachpuff: "persikka",
-peru: "peru",
-pink: "vaaleanpunainen",
-plum: "luumunpunainen",
-powderblue: "harmaansininen",
-purple: "violetti",
-red: "punainen",
-rosybrown: "punertavanruskea",
-royalblue: "syvänsininen",
-saddlebrown: "satulanruskea",
-salmon: "lohenpunainen",
-sandybrown: "hiekanruskea",
-seagreen: "merenvihreä",
-seashell: "simpukankuori",
-sienna: "siena",
-silver: "hopea",
-skyblue: "taivaansininen",
-slateblue: "savensininen",
-slategray: "savenharmaa",
-slategrey: "savenharmaa", // same as slategray
-snow: "lumivalkoinen",
-springgreen: "keväänvihreä",
-steelblue: "teräksensininen",
-tan: "kellanruskea",
-teal: "sinivihreä",
-thistle: "ohdake",
-tomato: "tomaatinpunainen",
-transparent: "läpinäkyvä",
-turquoise: "turkoosi",
-violet: "violetti",
-wheat: "vehnänkeltainen",
-white: "valkoinen",
-whitesmoke: "savunvalkea",
-yellow: "keltainen",
-yellowgreen: "kellanvihreä"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "vaaleanharmaansininen",
+	antiquewhite: "antiikinvalkoinen",
+	aqua: "sinivihreä",
+	aquamarine: "vedenvihreä",
+	azure: "taivaansininen",
+	beige: "vaaleanruskea",
+	bisque: "vaaleanruskea",
+	black: "musta",
+	blanchedalmond: "kuorittu manteli",
+	blue: "sininen",
+	blueviolet: "sinivioletti",
+	brown: "ruskea",
+	burlywood: "puunruskea",
+	cadetblue: "meren vihreä",
+	chartreuse: "kellanvihreä",
+	chocolate: "suklaanruskea",
+	coral: "koralli",
+	cornflowerblue: "syvänsininen",
+	cornsilk: "maissinkeltainen",
+	crimson: "karmiininpunainen",
+	cyan: "syaani",
+	darkblue: "tummansininen",
+	darkcyan: "tumma turkoosi",
+	darkgoldenrod: "tumma kultapiisku",
+	darkgray: "tummanharmaa",
+	darkgreen: "tummanvihreä",
+	darkgrey: "tummanharmaa", // same as darkgray
+	darkkhaki: "tumma khaki",
+	darkmagenta: "tumma magenta",
+	darkolivegreen: "tummanoliivinvihreä",
+	darkorange: "tummanoranssi",
+	darkorchid: "tumma orkidea",
+	darkred: "tummanpunainen",
+	darksalmon: "tumma lohenpunainen",
+	darkseagreen: "tumma merenvihreä",
+	darkslateblue: "tumma siniharmaa",
+	darkslategray: "tummanharmaa",
+	darkslategrey: "tummanharmaa", // same as darkslategray
+	darkturquoise: "tumma turkoosi",
+	darkviolet: "tummanvioletti",
+	deeppink: "syvä vaaleanpunainen",
+	deepskyblue: "tumma taivaansininen",
+	dimgray: "himmeänharmaa",
+	dimgrey: "himmeänharmaa", // same as dimgray
+	dodgerblue: "Dodger-sininen",
+	firebrick: "poltetun tiilen punainen",
+	floralwhite: "kukanvalkoinen",
+	forestgreen: "metsänvihreä",
+	fuchsia: "purppura",
+	gainsboro: "gainsboro",
+	ghostwhite: "lakananvalkoinen",
+	gold: "kulta",
+	goldenrod: "kullanruskea",
+	gray: "harmaa",
+	green: "vihreä",
+	greenyellow: "vihreänkeltainen",
+	grey: "harmaa", // same as gray
+	honeydew: "hunajameloninvihreä",
+	hotpink: "pinkki",
+	indianred: "kirkkaanpunainen",
+	indigo: "indigo",
+	ivory: "norsunluu",
+	khaki: "khaki",
+	lavender: "laventeli",
+	lavenderblush: "laventelinpunainen",
+	lawngreen: "ruohonvihreä",
+	lemonchiffon: "sitruunankeltainen",
+	lightblue: "vaaleansininen",
+	lightcoral: "vaalea koralli",
+	lightcyan: "vaalea syaani",
+	lightgoldenrodyellow: "vaalea kultapiiskunkeltainen",
+	lightgray: "vaaleanharmaa",
+	lightgreen: "vaaleanvihreä",
+	lightgrey: "vaaleanharmaa", // same as lightgray
+	lightpink: "vaaleanpunainen",
+	lightsalmon: "vaalea lohenpunainen",
+	lightseagreen: "vaalea merenvihreä",
+	lightskyblue: "vaalea taivaansininen",
+	lightslategray: "vaaleanharmaa",
+	lightslategrey: "vaaleanharmaa", // same as lightslategray
+	lightsteelblue: "vaalea teräksensininen",
+	lightyellow: "vaaleankeltainen",
+	lime: "vaaleanvihreä",
+	limegreen: "limetinvihreä",
+	linen: "pellavanvaalea",
+	magenta: "magenta",
+	maroon: "kastanjanruskea",
+	mediumaquamarine: "keskivaalea vedenvihreä",
+	mediumblue: "keskisininen",
+	mediumorchid: "keskivaalea orkidea",
+	mediumpurple: "keskivaalea violetti",
+	mediumseagreen: "keskivaalea merenvihreä",
+	mediumslateblue: "keskivaalea siniharmaa",
+	mediumspringgreen: "keskivaalea keväänvihreä",
+	mediumturquoise: "keskivaalea turkoosi",
+	mediumvioletred: "keskivaalea lila",
+	midnightblue: "yönsininen",
+	mintcream: "minttukreemi",
+	mistyrose: "utuinen ruusu",
+	moccasin: "nahanruskea",
+	navajowhite: "navajonvalkoinen",
+	navy: "laivastonsininen",
+	oldlace: "vanha pitsi",
+	olive: "oliivinvihreä",
+	olivedrab: "oliivinruskea",
+	orange: "oranssi",
+	orangered: "oranssinpunainen",
+	orchid: "orkidea",
+	palegoldenrod: "haalea kultapiisku",
+	palegreen: "haalea vihreä",
+	paleturquoise: "haalea turkoosi",
+	palevioletred: "haalea lila",
+	papayawhip: "papaijavaahto",
+	peachpuff: "persikka",
+	peru: "peru",
+	pink: "vaaleanpunainen",
+	plum: "luumunpunainen",
+	powderblue: "harmaansininen",
+	purple: "violetti",
+	red: "punainen",
+	rosybrown: "punertavanruskea",
+	royalblue: "syvänsininen",
+	saddlebrown: "satulanruskea",
+	salmon: "lohenpunainen",
+	sandybrown: "hiekanruskea",
+	seagreen: "merenvihreä",
+	seashell: "simpukankuori",
+	sienna: "siena",
+	silver: "hopea",
+	skyblue: "taivaansininen",
+	slateblue: "savensininen",
+	slategray: "savenharmaa",
+	slategrey: "savenharmaa", // same as slategray
+	snow: "lumivalkoinen",
+	springgreen: "keväänvihreä",
+	steelblue: "teräksensininen",
+	tan: "kellanruskea",
+	teal: "sinivihreä",
+	thistle: "ohdake",
+	tomato: "tomaatinpunainen",
+	transparent: "läpinäkyvä",
+	turquoise: "turkoosi",
+	violet: "violetti",
+	wheat: "vehnänkeltainen",
+	white: "valkoinen",
+	whitesmoke: "savunvalkea",
+	yellow: "keltainen",
+	yellowgreen: "kellanvihreä"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/fr/colors.js b/dojo/nls/fr/colors.js
index 5c77724..8c3c401 100644
--- a/dojo/nls/fr/colors.js
+++ b/dojo/nls/fr/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "bleu gris",
-antiquewhite: "blanc antique",
-aqua: "bleu-vert",
-aquamarine: "aigue-marine",
-azure: "bleu azur",
-beige: "beige",
-bisque: "beige rosé",
-black: "noir",
-blanchedalmond: "coquille d'oeuf",
-blue: "bleu",
-blueviolet: "bleu-violet",
-brown: "brun",
-burlywood: "bois précieux",
-cadetblue: "bleu pétrole",
-chartreuse: "vert vif",
-chocolate: "chocolat",
-coral: "corail",
-cornflowerblue: "bleuet",
-cornsilk: "vanille",
-crimson: "cramoisi",
-cyan: "cyan",
-darkblue: "bleu foncé",
-darkcyan: "cyan foncé",
-darkgoldenrod: "jaune paille foncé",
-darkgray: "gris foncé",
-darkgreen: "vert foncé",
-darkgrey: "gris foncé", // same as darkgray
-darkkhaki: "kaki foncé",
-darkmagenta: "magenta foncé",
-darkolivegreen: "olive foncé",
-darkorange: "orange foncé",
-darkorchid: "lilas foncé",
-darkred: "rouge foncé",
-darksalmon: "saumon foncé",
-darkseagreen: "vert d'eau foncé",
-darkslateblue: "bleu ardoise foncé",
-darkslategray: "gris ardoise foncé",
-darkslategrey: "gris ardoise foncé", // same as darkslategray
-darkturquoise: "turquoise foncé",
-darkviolet: "violet foncé",
-deeppink: "rose soutenu",
-deepskyblue: "bleu ciel soutenu",
-dimgray: "gris soutenu",
-dimgrey: "gris soutenu", // same as dimgray
-dodgerblue: "bleu France",
-firebrick: "rouge brique",
-floralwhite: "lys",
-forestgreen: "vert sapin",
-fuchsia: "fuchsia",
-gainsboro: "gris souris",
-ghostwhite: "blanc laiteux",
-gold: "or",
-goldenrod: "jaune paille",
-gray: "gris",
-green: "vert",
-greenyellow: "vert-jaune",
-grey: "gris", // same as gray
-honeydew: "opalin",
-hotpink: "rose intense",
-indianred: "rose indien",
-indigo: "indigo",
-ivory: "ivoire",
-khaki: "kaki",
-lavender: "lavande",
-lavenderblush: "lavandin",
-lawngreen: "vert prairie",
-lemonchiffon: "mousse de citron",
-lightblue: "bleu clair",
-lightcoral: "corail clair",
-lightcyan: "cyan clair",
-lightgoldenrodyellow: "jaune paille clair",
-lightgray: "gris clair",
-lightgreen: "vert clair",
-lightgrey: "gris clair", // same as lightgray
-lightpink: "rose clair",
-lightsalmon: "saumon clair",
-lightseagreen: "vert d'eau clair",
-lightskyblue: "bleu ciel clair",
-lightslategray: "gris ardoise clair",
-lightslategrey: "gris ardoise clair", // same as lightslategray
-lightsteelblue: "bleu acier clair",
-lightyellow: "jaune clair",
-lime: "vert citron",
-limegreen: "citron vert",
-linen: "écru",
-magenta: "magenta",
-maroon: "marron",
-mediumaquamarine: "aigue-marine moyen",
-mediumblue: "bleu moyen",
-mediumorchid: "lilas moyen",
-mediumpurple: "pourpre moyen",
-mediumseagreen: "vert d'eau moyen",
-mediumslateblue: "bleu ardoise moyen",
-mediumspringgreen: "vert printemps moyen",
-mediumturquoise: "turquoise moyen",
-mediumvioletred: "rouge violacé moyen",
-midnightblue: "bleu nuit",
-mintcream: "crème de menthe",
-mistyrose: "rose pâle",
-moccasin: "chamois",
-navajowhite: "chair",
-navy: "bleu marine",
-oldlace: "blanc cassé",
-olive: "olive",
-olivedrab: "brun verdâtre",
-orange: "orange",
-orangered: "rouge orangé",
-orchid: "lilas",
-palegoldenrod: "jaune paille pâle",
-palegreen: "vert pâle",
-paleturquoise: "turquoise pâle",
-palevioletred: "rouge violacé pâle",
-papayawhip: "crème de papaye",
-peachpuff: "pêche",
-peru: "caramel",
-pink: "rose",
-plum: "prune",
-powderblue: "bleu de smalt",
-purple: "pourpre",
-red: "rouge",
-rosybrown: "vieux rose",
-royalblue: "bleu roi",
-saddlebrown: "brun cuir",
-salmon: "saumon",
-sandybrown: "sable",
-seagreen: "vert d'eau",
-seashell: "coquillage",
-sienna: "terre de sienne",
-silver: "argent",
-skyblue: "bleu ciel",
-slateblue: "bleu ardoise",
-slategray: "gris ardoise",
-slategrey: "gris ardoise", // same as slategray
-snow: "neige",
-springgreen: "vert printemps",
-steelblue: "bleu acier",
-tan: "grège",
-teal: "sarcelle",
-thistle: "chardon",
-tomato: "tomate",
-transparent: "transparent",
-turquoise: "turquoise",
-violet: "violet",
-wheat: "blé",
-white: "blanc",
-whitesmoke: "blanc cendré",
-yellow: "jaune",
-yellowgreen: "vert jaunâtre"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "bleu gris",
+	antiquewhite: "blanc antique",
+	aqua: "bleu-vert",
+	aquamarine: "aigue-marine",
+	azure: "bleu azur",
+	beige: "beige",
+	bisque: "beige rosé",
+	black: "noir",
+	blanchedalmond: "coquille d'œuf",
+	blue: "bleu",
+	blueviolet: "bleu-violet",
+	brown: "brun",
+	burlywood: "bois précieux",
+	cadetblue: "bleu pétrole",
+	chartreuse: "vert vif",
+	chocolate: "chocolat",
+	coral: "corail",
+	cornflowerblue: "bleuet",
+	cornsilk: "vanille",
+	crimson: "cramoisi",
+	cyan: "cyan",
+	darkblue: "bleu foncé",
+	darkcyan: "cyan foncé",
+	darkgoldenrod: "jaune paille foncé",
+	darkgray: "gris foncé",
+	darkgreen: "vert foncé",
+	darkgrey: "gris foncé", // same as darkgray
+	darkkhaki: "kaki foncé",
+	darkmagenta: "magenta foncé",
+	darkolivegreen: "olive foncé",
+	darkorange: "orange foncé",
+	darkorchid: "lilas foncé",
+	darkred: "rouge foncé",
+	darksalmon: "saumon foncé",
+	darkseagreen: "vert d'eau foncé",
+	darkslateblue: "bleu ardoise foncé",
+	darkslategray: "gris ardoise foncé",
+	darkslategrey: "gris ardoise foncé", // same as darkslategray
+	darkturquoise: "turquoise foncé",
+	darkviolet: "violet foncé",
+	deeppink: "rose soutenu",
+	deepskyblue: "bleu ciel soutenu",
+	dimgray: "gris soutenu",
+	dimgrey: "gris soutenu", // same as dimgray
+	dodgerblue: "bleu France",
+	firebrick: "rouge brique",
+	floralwhite: "lys",
+	forestgreen: "vert sapin",
+	fuchsia: "fuchsia",
+	gainsboro: "gris souris",
+	ghostwhite: "blanc laiteux",
+	gold: "or",
+	goldenrod: "jaune paille",
+	gray: "gris",
+	green: "vert",
+	greenyellow: "vert-jaune",
+	grey: "gris", // same as gray
+	honeydew: "opalin",
+	hotpink: "rose intense",
+	indianred: "rose indien",
+	indigo: "indigo",
+	ivory: "ivoire",
+	khaki: "kaki",
+	lavender: "lavande",
+	lavenderblush: "lavandin",
+	lawngreen: "vert prairie",
+	lemonchiffon: "mousse de citron",
+	lightblue: "bleu clair",
+	lightcoral: "corail clair",
+	lightcyan: "cyan clair",
+	lightgoldenrodyellow: "jaune paille clair",
+	lightgray: "gris clair",
+	lightgreen: "vert clair",
+	lightgrey: "gris clair", // same as lightgray
+	lightpink: "rose clair",
+	lightsalmon: "saumon clair",
+	lightseagreen: "vert d'eau clair",
+	lightskyblue: "bleu ciel clair",
+	lightslategray: "gris ardoise clair",
+	lightslategrey: "gris ardoise clair", // same as lightslategray
+	lightsteelblue: "bleu acier clair",
+	lightyellow: "jaune clair",
+	lime: "vert citron",
+	limegreen: "citron vert",
+	linen: "écru",
+	magenta: "magenta",
+	maroon: "marron",
+	mediumaquamarine: "aigue-marine moyen",
+	mediumblue: "bleu moyen",
+	mediumorchid: "lilas moyen",
+	mediumpurple: "pourpre moyen",
+	mediumseagreen: "vert d'eau moyen",
+	mediumslateblue: "bleu ardoise moyen",
+	mediumspringgreen: "vert printemps moyen",
+	mediumturquoise: "turquoise moyen",
+	mediumvioletred: "rouge violacé moyen",
+	midnightblue: "bleu nuit",
+	mintcream: "crème de menthe",
+	mistyrose: "rose pâle",
+	moccasin: "chamois",
+	navajowhite: "chair",
+	navy: "bleu marine",
+	oldlace: "blanc cassé",
+	olive: "olive",
+	olivedrab: "brun verdâtre",
+	orange: "orange",
+	orangered: "rouge orangé",
+	orchid: "lilas",
+	palegoldenrod: "jaune paille pâle",
+	palegreen: "vert pâle",
+	paleturquoise: "turquoise pâle",
+	palevioletred: "rouge violacé pâle",
+	papayawhip: "crème de papaye",
+	peachpuff: "pêche",
+	peru: "caramel",
+	pink: "rose",
+	plum: "prune",
+	powderblue: "bleu de smalt",
+	purple: "pourpre",
+	red: "rouge",
+	rosybrown: "vieux rose",
+	royalblue: "bleu roi",
+	saddlebrown: "brun cuir",
+	salmon: "saumon",
+	sandybrown: "sable",
+	seagreen: "vert d'eau",
+	seashell: "coquillage",
+	sienna: "terre de sienne",
+	silver: "argent",
+	skyblue: "bleu ciel",
+	slateblue: "bleu ardoise",
+	slategray: "gris ardoise",
+	slategrey: "gris ardoise", // same as slategray
+	snow: "neige",
+	springgreen: "vert printemps",
+	steelblue: "bleu acier",
+	tan: "grège",
+	teal: "sarcelle",
+	thistle: "chardon",
+	tomato: "tomate",
+	transparent: "transparent",
+	turquoise: "turquoise",
+	violet: "violet",
+	wheat: "blé",
+	white: "blanc",
+	whitesmoke: "blanc cendré",
+	yellow: "jaune",
+	yellowgreen: "vert jaunâtre"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/he/colors.js b/dojo/nls/he/colors.js
index a6831a2..253a7eb 100644
--- a/dojo/nls/he/colors.js
+++ b/dojo/nls/he/colors.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "כחול פלדה",
 antiquewhite: "לבן עתיק",
@@ -146,6 +144,7 @@ tan: "חום אדמדם",
 teal: "כחול-ירוק כהה",
 thistle: "דרדר",
 tomato: "עגבניה",
+transparent: "שקוף",
 turquoise: "טורקיז",
 violet: "סגול",
 wheat: "חיוט",
@@ -154,5 +153,4 @@ whitesmoke: "עשן לבן",
 yellow: "צהוב",
 yellowgreen: "ירוק צהוב"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/hr/colors.js b/dojo/nls/hr/colors.js
index 51dbdeb..f194e9e 100644
--- a/dojo/nls/hr/colors.js
+++ b/dojo/nls/hr/colors.js
@@ -2,155 +2,155 @@ define(
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "alice plava",
-antiquewhite: "antique bijela",
-aqua: "aqua",
-aquamarine: "akvamarin",
-azure: "azurna",
-beige: "bež",
-bisque: "svjetlo smeđe ružičasta",
-black: "crna",
-blanchedalmond: "slonovača",
-blue: "plava",
-blueviolet: "plavo ljubičasta",
-brown: "smeđa",
-burlywood: "pješčano smeđa",
-cadetblue: "plavo siva",
-chartreuse: "chartreuse",
-chocolate: "čokoladna",
-coral: "koraljna",
-cornflowerblue: "različak plava",
-cornsilk: "cornsilk",
-crimson: "rumena",
-cyan: "cijan",
-darkblue: "tamno plava",
-darkcyan: "tamno cijan",
-darkgoldenrod: "tamno zlatno žuta",
-darkgray: "tamno siva",
-darkgreen: "tamno zelena",
-darkgrey: "tamno siva", // same as darkgray
-darkkhaki: "tamno sivo smeđa",
-darkmagenta: "tamno grimizna",
-darkolivegreen: "tamno maslinasto zelena",
-darkorange: "tamno narančasta",
-darkorchid: "tamno ružičasta",
-darkred: "tamno crvena",
-darksalmon: "tamno žuto ružičasta",
-darkseagreen: "tamno plavo zelena",
-darkslateblue: "tamno sivo plava",
-darkslategray: "tamno plavo siva",
-darkslategrey: "tamno plavo siva", // same as darkslategray
-darkturquoise: "tamno tirkizna",
-darkviolet: "tamno ljubičasta",
-deeppink: "intenzivno ružičasta",
-deepskyblue: "intenzivno nebesko plava",
-dimgray: "mutno siva",
-dimgrey: "mutno siva", // same as dimgray
-dodgerblue: "dodger plava",
-firebrick: "žarko crvena",
-floralwhite: "cvjetno bijela",
-forestgreen: "tamno zelena",
-fuchsia: "fuksija",
-gainsboro: "gainsboro",
-ghostwhite: "sivo bijela",
-gold: "zlatna",
-goldenrod: "zlatno žuta",
-gray: "siva",
-green: "zelena",
-greenyellow: "zeleno-žuta",
-grey: "siva", // same as gray
-honeydew: "honeydew",
-hotpink: "žarko ružičasta",
-indianred: "indijski crveno",
-indigo: "indigo",
-ivory: "slonovača",
-khaki: "sivo smeđa",
-lavender: "lavanda",
-lavenderblush: "lavanda",
-lawngreen: "livadno zelena",
-lemonchiffon: "nježno žuta",
-lightblue: "svjetlo plava",
-lightcoral: "svjetlo koraljna",
-lightcyan: "svjetlo cijan",
-lightgoldenrodyellow: "svjetlo zlatno žuta",
-lightgray: "svjetlo siva",
-lightgreen: "svjetlo zelena",
-lightgrey: "svjetlo siva", // same as lightgray
-lightpink: "svjetlo ružičasta",
-lightsalmon: "svjetlo žuto ružičasta",
-lightseagreen: "svjetlo plavo zelena",
-lightskyblue: "svjetlo nebesko plava",
-lightslategray: "svjetlo plavo siva",
-lightslategrey: "svjetlo plavo siva", // same as lightslategray
-lightsteelblue: "svjetlo čelično plava",
-lightyellow: "svjetlo žuta",
-lime: "limeta",
-limegreen: "limeta zelena",
-linen: "platno",
-magenta: "grimizna",
-maroon: "kestenjasta",
-mediumaquamarine: "srednje akvamarin",
-mediumblue: "srednje plava",
-mediumorchid: "srednje ružičasta",
-mediumpurple: "srednje purpurna",
-mediumseagreen: "srednje plavo zelena",
-mediumslateblue: "srednje sivo plava",
-mediumspringgreen: "srednje proljetno zelena",
-mediumturquoise: "srednje tirkizna",
-mediumvioletred: "srednje ljubičasto-crvena",
-midnightblue: "ponoćno plava",
-mintcream: "blijedo zelena",
-mistyrose: "mutno ružičasta",
-moccasin: "moccasin",
-navajowhite: "krem bijela",
-navy: "mornarsko plava",
-oldlace: "old lace",
-olive: "maslinasta",
-olivedrab: "maslinasta",
-orange: "narančasta",
-orangered: "narančasto crvena",
-orchid: "ružičasta",
-palegoldenrod: "blijedo zlatno žuta",
-palegreen: "svjetlo zelena",
-paleturquoise: "blijedo tirkizna",
-palevioletred: "blijedo ljubičasto crvena",
-papayawhip: "blijedo narančasta",
-peachpuff: "breskva",
-peru: "peru",
-pink: "ružičasta",
-plum: "šljiva",
-powderblue: "blijedo plava",
-purple: "purpurna",
-red: "crvena",
-rosybrown: "ružičasto smeđa",
-royalblue: "kraljevski plava",
-saddlebrown: "srednje smeđa",
-salmon: "ružičasta",
-sandybrown: "pješčano smeđa",
-seagreen: "plavo zelena",
-seashell: "nježno ružičasta",
-sienna: "sjena",
-silver: "srebrna",
-skyblue: "nebesko plava",
-slateblue: "sivo plava",
-slategray: "plavo siva",
-slategrey: "plavo siva", // same as slategray
-snow: "snijeg",
-springgreen: "proljetno zeleno",
-steelblue: "čelično plava",
-tan: "ten",
-teal: "teal",
-thistle: "čičak",
-tomato: "rajčica",
-transparent: "prozirno",
-turquoise: "tirkizna",
-violet: "ljubičasta",
-wheat: "pšenica",
-white: "bijela",
-whitesmoke: "bijeli dim",
-yellow: "žuta",
-yellowgreen: "žuto zelena"
+	aliceblue: "alice plava",
+	antiquewhite: "antique bijela",
+	aqua: "aqua",
+	aquamarine: "akvamarin",
+	azure: "azurna",
+	beige: "bež",
+	bisque: "svjetlo smeđe ružičasta",
+	black: "crna",
+	blanchedalmond: "svjetlo bademasta",
+	blue: "plava",
+	blueviolet: "plavo ljubičasta",
+	brown: "smeđa",
+	burlywood: "tamno smeđa",
+	cadetblue: "kadet plava",
+	chartreuse: "chartreuse",
+	chocolate: "čokoladna",
+	coral: "koraljna",
+	cornflowerblue: "različak plava",
+	cornsilk: "cornsilk",
+	crimson: "rumena",
+	cyan: "cijan",
+	darkblue: "tamno plava",
+	darkcyan: "tamno cijan",
+	darkgoldenrod: "tamno zlatno žuta",
+	darkgray: "tamno siva",
+	darkgreen: "tamno zelena",
+	darkgrey: "tamno siva", // same as darkgray
+	darkkhaki: "tamno sivo smeđa",
+	darkmagenta: "tamno grimizna",
+	darkolivegreen: "tamno maslinasto zelena",
+	darkorange: "tamno narančasta",
+	darkorchid: "tamno ružičasta",
+	darkred: "tamno crvena",
+	darksalmon: "tamno žuto ružičasta",
+	darkseagreen: "tamno plavo zelena",
+	darkslateblue: "tamno sivo plava",
+	darkslategray: "tamno plavo siva",
+	darkslategrey: "tamno plavo siva", // same as darkslategray
+	darkturquoise: "tamno tirkizna",
+	darkviolet: "tamno ljubičasta",
+	deeppink: "intenzivno ružičasta",
+	deepskyblue: "intenzivno nebesko plava",
+	dimgray: "mutno siva",
+	dimgrey: "mutno siva", // same as dimgray
+	dodgerblue: "dodger plava",
+	firebrick: "žarko crvena",
+	floralwhite: "cvjetno bijela",
+	forestgreen: "šumsko zelena",
+	fuchsia: "fuksija",
+	gainsboro: "gainsboro",
+	ghostwhite: "sivo bijela",
+	gold: "zlatna",
+	goldenrod: "zlatno žuta",
+	gray: "siva",
+	green: "zelena",
+	greenyellow: "zeleno žuta",
+	grey: "siva", // same as gray
+	honeydew: "honeydew",
+	hotpink: "žarko ružičasta",
+	indianred: "indijski crveno",
+	indigo: "indigo",
+	ivory: "slonovača",
+	khaki: "sivo smeđa",
+	lavender: "lavanda",
+	lavenderblush: "rumena lavanda",
+	lawngreen: "livadno zelena",
+	lemonchiffon: "nježno žuta",
+	lightblue: "svjetlo plava",
+	lightcoral: "svjetlo koraljna",
+	lightcyan: "svjetlo cijan",
+	lightgoldenrodyellow: "svjetlo zlatno žuta",
+	lightgray: "svjetlo siva",
+	lightgreen: "svjetlo zelena",
+	lightgrey: "svjetlo siva", // same as lightgray
+	lightpink: "svjetlo ružičasta",
+	lightsalmon: "svjetlo žuto ružičasta",
+	lightseagreen: "svjetlo plavo zelena",
+	lightskyblue: "svjetlo nebesko plava",
+	lightslategray: "svjetlo plavo siva",
+	lightslategrey: "svjetlo plavo siva", // same as lightslategray
+	lightsteelblue: "svjetlo čelično plava",
+	lightyellow: "svjetlo žuta",
+	lime: "limeta",
+	limegreen: "limeta zelena",
+	linen: "platno",
+	magenta: "grimizna",
+	maroon: "kestenjasta",
+	mediumaquamarine: "srednje akvamarin",
+	mediumblue: "srednje plava",
+	mediumorchid: "srednje ružičasta",
+	mediumpurple: "srednje purpurna",
+	mediumseagreen: "srednje plavo zelena",
+	mediumslateblue: "srednje sivo plava",
+	mediumspringgreen: "srednje proljetno zelena",
+	mediumturquoise: "srednje tirkizna",
+	mediumvioletred: "srednje ljubičasto crvena",
+	midnightblue: "ponoćno plava",
+	mintcream: "blijedo zelena",
+	mistyrose: "mutno ružičasta",
+	moccasin: "moccasin",
+	navajowhite: "krem bijela",
+	navy: "mornarsko plava",
+	oldlace: "old lace",
+	olive: "maslinasta",
+	olivedrab: "maslinasto siva",
+	orange: "narančasta",
+	orangered: "narančasto crvena",
+	orchid: "ružičasta",
+	palegoldenrod: "blijedo zlatno žuta",
+	palegreen: "blijedo zelena",
+	paleturquoise: "blijedo tirkizna",
+	palevioletred: "blijedo ljubičasto crvena",
+	papayawhip: "blijedo narančasta",
+	peachpuff: "breskva",
+	peru: "peru",
+	pink: "roza",
+	plum: "šljiva",
+	powderblue: "blijedo plava",
+	purple: "purpurna",
+	red: "crvena",
+	rosybrown: "ružičasto smeđa",
+	royalblue: "kraljevski plava",
+	saddlebrown: "srednje smeđa",
+	salmon: "žuto ružičasta",
+	sandybrown: "pješčano smeđa",
+	seagreen: "plavo zelena",
+	seashell: "nježno ružičasta",
+	sienna: "sjena",
+	silver: "srebrna",
+	skyblue: "nebesko plava",
+	slateblue: "sivo plava",
+	slategray: "plavo siva",
+	slategrey: "plavo siva", // same as slategray
+	snow: "snijeg",
+	springgreen: "proljetno zeleno",
+	steelblue: "čelično plava",
+	tan: "ten",
+	teal: "teal",
+	thistle: "čičak",
+	tomato: "rajčica",
+	transparent: "prozirno",
+	turquoise: "tirkizna",
+	violet: "ljubičasta",
+	wheat: "pšenica",
+	white: "bijela",
+	whitesmoke: "bijeli dim",
+	yellow: "žuta",
+	yellowgreen: "žuto zelena"
 })
 );
diff --git a/dojo/nls/hu/colors.js b/dojo/nls/hu/colors.js
index 9321871..de32bf4 100644
--- a/dojo/nls/hu/colors.js
+++ b/dojo/nls/hu/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "Alice kék",
-antiquewhite: "antik fehér",
-aqua: "vízszín",
-aquamarine: "akvamarin",
-azure: "azúrkék",
-beige: "bézs",
-bisque: "porcelán",
-black: "fekete",
-blanchedalmond: "hámozott mandula",
-blue: "kék",
-blueviolet: "ibolyakék",
-brown: "barna",
-burlywood: "nyersfa",
-cadetblue: "kadétkék",
-chartreuse: "chartreuse",
-chocolate: "csokoládé",
-coral: "korall",
-cornflowerblue: "búzavirágkék",
-cornsilk: "kukoricahaj",
-crimson: "karmazsinvörös",
-cyan: "ciánkék",
-darkblue: "sötétkék",
-darkcyan: "sötét ciánkék",
-darkgoldenrod: "sötét aranyvessző",
-darkgray: "sötétszürke",
-darkgreen: "sötétzöld",
-darkgrey: "sötétszürke", // same as darkgray
-darkkhaki: "sötét khakiszín",
-darkmagenta: "sötétbíbor",
-darkolivegreen: "sötét olajzöld",
-darkorange: "sötét narancssárga",
-darkorchid: "sötét orchidea",
-darkred: "sötétvörös",
-darksalmon: "sötét lazacszín",
-darkseagreen: "sötét tengerzöld",
-darkslateblue: "sötét palakék",
-darkslategray: "sötét palaszürke",
-darkslategrey: "sötét palaszürke", // same as darkslategray
-darkturquoise: "sötét türkizkék",
-darkviolet: "sötét ibolyaszín",
-deeppink: "sötétrózsaszín",
-deepskyblue: "sötét égszínkék",
-dimgray: "halványszürke",
-dimgrey: "halványszürke", // same as dimgray
-dodgerblue: "dodger kék",
-firebrick: "téglavörös",
-floralwhite: "virágfehér",
-forestgreen: "erdőzöld",
-fuchsia: "fukszia",
-gainsboro: "gainsboro",
-ghostwhite: "szellemfehér",
-gold: "arany",
-goldenrod: "aranyvessző",
-gray: "szürke",
-green: "zöld",
-greenyellow: "zöldessárga",
-grey: "szürke", // same as gray
-honeydew: "mézharmat",
-hotpink: "meleg rózsaszín",
-indianred: "indiánvörös",
-indigo: "indigó",
-ivory: "elefántcsont",
-khaki: "khakiszín",
-lavender: "levendula",
-lavenderblush: "pirosas levendula",
-lawngreen: "fűzöld",
-lemonchiffon: "sárga műselyem",
-lightblue: "világoskék",
-lightcoral: "világos korall",
-lightcyan: "világos ciánkék",
-lightgoldenrodyellow: "világos aranyvessző sárga",
-lightgray: "világosszürke",
-lightgreen: "világoszöld",
-lightgrey: "világosszürke", // same as lightgray
-lightpink: "világos rózsaszín",
-lightsalmon: "világos lazacszín",
-lightseagreen: "világos tengerzöld",
-lightskyblue: "világos égszínkék",
-lightslategray: "világos palaszürke",
-lightslategrey: "világos palaszürke", // same as lightslategray
-lightsteelblue: "világos acélkék",
-lightyellow: "világossárga",
-lime: "lime",
-limegreen: "limezöld",
-linen: "vászonfehér",
-magenta: "bíbor",
-maroon: "gesztenyebarna",
-mediumaquamarine: "közepes akvamarin",
-mediumblue: "közepes kék",
-mediumorchid: "közepes orchidea",
-mediumpurple: "közepes lila",
-mediumseagreen: "közepes tengerzöld",
-mediumslateblue: "közepes palakék",
-mediumspringgreen: "közepes tavaszzöld",
-mediumturquoise: "közepes türkizkék",
-mediumvioletred: "közepes ibolyavörös",
-midnightblue: "éjkék",
-mintcream: "mentaszósz",
-mistyrose: "halvány rózsaszín",
-moccasin: "mokkaszín",
-navajowhite: "navajo fehér",
-navy: "tengerészkék",
-oldlace: "régi csipke",
-olive: "olajzöld",
-olivedrab: "olajzöld drapp",
-orange: "narancssárga",
-orangered: "narancsvörös",
-orchid: "orchidea",
-palegoldenrod: "halvány aranyvessző",
-palegreen: "halványzöld",
-paleturquoise: "halvány türkizkék",
-palevioletred: "halvány ibolyavörös",
-papayawhip: "papayahab",
-peachpuff: "barackszín",
-peru: "peru",
-pink: "rózsaszín",
-plum: "szilvakék",
-powderblue: "púderkék",
-purple: "lila",
-red: "vörös",
-rosybrown: "barnásrózsaszín",
-royalblue: "királykék",
-saddlebrown: "nyeregbarna",
-salmon: "lazacszín",
-sandybrown: "homokbarna",
-seagreen: "tengerzöld",
-seashell: "kagyló",
-sienna: "vörösesbarna",
-silver: "ezüst",
-skyblue: "égszínkék",
-slateblue: "palakék",
-slategray: "palaszürke",
-slategrey: "palaszürke", // same as slategray
-snow: "hó",
-springgreen: "tavaszzöld",
-steelblue: "acélkék",
-tan: "rozsdabarna",
-teal: "pávakék",
-thistle: "bogáncs",
-tomato: "paradicsom",
-transparent: "átlátszó",
-turquoise: "türkizkék",
-violet: "ibolyaszín",
-wheat: "búza",
-white: "fehér",
-whitesmoke: "fehér füst",
-yellow: "sárga",
-yellowgreen: "sárgászöld"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "Alice kék",
+	antiquewhite: "antik fehér",
+	aqua: "vízszín",
+	aquamarine: "akvamarin",
+	azure: "azúrkék",
+	beige: "bézs",
+	bisque: "porcelán",
+	black: "fekete",
+	blanchedalmond: "hámozott mandula",
+	blue: "kék",
+	blueviolet: "ibolyakék",
+	brown: "barna",
+	burlywood: "nyersfa",
+	cadetblue: "kadétkék",
+	chartreuse: "chartreuse",
+	chocolate: "csokoládé",
+	coral: "korall",
+	cornflowerblue: "búzavirágkék",
+	cornsilk: "kukoricahaj",
+	crimson: "karmazsinvörös",
+	cyan: "ciánkék",
+	darkblue: "sötétkék",
+	darkcyan: "sötét ciánkék",
+	darkgoldenrod: "sötét aranyvessző",
+	darkgray: "sötétszürke",
+	darkgreen: "sötétzöld",
+	darkgrey: "sötétszürke", // same as darkgray
+	darkkhaki: "sötét khakiszín",
+	darkmagenta: "sötétbíbor",
+	darkolivegreen: "sötét olajzöld",
+	darkorange: "sötét narancssárga",
+	darkorchid: "sötét orchidea",
+	darkred: "sötétvörös",
+	darksalmon: "sötét lazacszín",
+	darkseagreen: "sötét tengerzöld",
+	darkslateblue: "sötét palakék",
+	darkslategray: "sötét palaszürke",
+	darkslategrey: "sötét palaszürke", // same as darkslategray
+	darkturquoise: "sötét türkizkék",
+	darkviolet: "sötét ibolyaszín",
+	deeppink: "sötétrózsaszín",
+	deepskyblue: "sötét égszínkék",
+	dimgray: "halványszürke",
+	dimgrey: "halványszürke", // same as dimgray
+	dodgerblue: "dodger kék",
+	firebrick: "téglavörös",
+	floralwhite: "virágfehér",
+	forestgreen: "erdőzöld",
+	fuchsia: "fukszia",
+	gainsboro: "gainsboro",
+	ghostwhite: "szellemfehér",
+	gold: "arany",
+	goldenrod: "aranyvessző",
+	gray: "szürke",
+	green: "zöld",
+	greenyellow: "zöldessárga",
+	grey: "szürke", // same as gray
+	honeydew: "mézharmat",
+	hotpink: "meleg rózsaszín",
+	indianred: "indiánvörös",
+	indigo: "indigó",
+	ivory: "elefántcsont",
+	khaki: "khakiszín",
+	lavender: "levendula",
+	lavenderblush: "pirosas levendula",
+	lawngreen: "fűzöld",
+	lemonchiffon: "sárga műselyem",
+	lightblue: "világoskék",
+	lightcoral: "világos korall",
+	lightcyan: "világos ciánkék",
+	lightgoldenrodyellow: "világos aranyvessző sárga",
+	lightgray: "világosszürke",
+	lightgreen: "világoszöld",
+	lightgrey: "világosszürke", // same as lightgray
+	lightpink: "világos rózsaszín",
+	lightsalmon: "világos lazacszín",
+	lightseagreen: "világos tengerzöld",
+	lightskyblue: "világos égszínkék",
+	lightslategray: "világos palaszürke",
+	lightslategrey: "világos palaszürke", // same as lightslategray
+	lightsteelblue: "világos acélkék",
+	lightyellow: "világossárga",
+	lime: "lime",
+	limegreen: "limezöld",
+	linen: "vászonfehér",
+	magenta: "bíbor",
+	maroon: "gesztenyebarna",
+	mediumaquamarine: "közepes akvamarin",
+	mediumblue: "közepes kék",
+	mediumorchid: "közepes orchidea",
+	mediumpurple: "közepes lila",
+	mediumseagreen: "közepes tengerzöld",
+	mediumslateblue: "közepes palakék",
+	mediumspringgreen: "közepes tavaszzöld",
+	mediumturquoise: "közepes türkizkék",
+	mediumvioletred: "közepes ibolyavörös",
+	midnightblue: "éjkék",
+	mintcream: "mentaszósz",
+	mistyrose: "halvány rózsaszín",
+	moccasin: "mokkaszín",
+	navajowhite: "navajo fehér",
+	navy: "tengerészkék",
+	oldlace: "régi csipke",
+	olive: "olajzöld",
+	olivedrab: "olajzöld drapp",
+	orange: "narancssárga",
+	orangered: "narancsvörös",
+	orchid: "orchidea",
+	palegoldenrod: "halvány aranyvessző",
+	palegreen: "halványzöld",
+	paleturquoise: "halvány türkizkék",
+	palevioletred: "halvány ibolyavörös",
+	papayawhip: "papayahab",
+	peachpuff: "barackszín",
+	peru: "peru",
+	pink: "rózsaszín",
+	plum: "szilvakék",
+	powderblue: "púderkék",
+	purple: "lila",
+	red: "vörös",
+	rosybrown: "barnásrózsaszín",
+	royalblue: "királykék",
+	saddlebrown: "nyeregbarna",
+	salmon: "lazacszín",
+	sandybrown: "homokbarna",
+	seagreen: "tengerzöld",
+	seashell: "kagyló",
+	sienna: "vörösesbarna",
+	silver: "ezüst",
+	skyblue: "égszínkék",
+	slateblue: "palakék",
+	slategray: "palaszürke",
+	slategrey: "palaszürke", // same as slategray
+	snow: "hó",
+	springgreen: "tavaszzöld",
+	steelblue: "acélkék",
+	tan: "rozsdabarna",
+	teal: "pávakék",
+	thistle: "bogáncs",
+	tomato: "paradicsom",
+	transparent: "átlátszó",
+	turquoise: "türkizkék",
+	violet: "ibolyaszín",
+	wheat: "búza",
+	white: "fehér",
+	whitesmoke: "fehér füst",
+	yellow: "sárga",
+	yellowgreen: "sárgászöld"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/it/colors.js b/dojo/nls/it/colors.js
index 3a03eeb..81a7f37 100644
--- a/dojo/nls/it/colors.js
+++ b/dojo/nls/it/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "blu alice",
-antiquewhite: "bianco antico",
-aqua: "acqua",
-aquamarine: "acquamarina",
-azure: "azzurro ghiaccio",
-beige: "beige",
-bisque: "incarnato",
-black: "nero",
-blanchedalmond: "mandorla chiaro",
-blue: "blu",
-blueviolet: "blu violetto",
-brown: "marrone",
-burlywood: "tabacco",
-cadetblue: "verde acqua",
-chartreuse: "verde brillante",
-chocolate: "cioccolato",
-coral: "corallo",
-cornflowerblue: "blu fiordaliso",
-cornsilk: "crema",
-crimson: "cremisi",
-cyan: "ciano",
-darkblue: "blu scuro",
-darkcyan: "ciano scuro",
-darkgoldenrod: "ocra scuro",
-darkgray: "grigio scuro",
-darkgreen: "verde scuro",
-darkgrey: "grigio scuro", // same as darkgray
-darkkhaki: "kaki scuro",
-darkmagenta: "magenta scuro",
-darkolivegreen: "verde oliva scuro",
-darkorange: "arancione scuro",
-darkorchid: "orchidea scuro",
-darkred: "rosso scuro",
-darksalmon: "salmone scuro",
-darkseagreen: "verde mare scuro",
-darkslateblue: "blu ardesia scuro",
-darkslategray: "grigio ardesia scuro",
-darkslategrey: "grigio ardesia scuro", // same as darkslategray
-darkturquoise: "turchese scuro",
-darkviolet: "viola scuro",
-deeppink: "ciclamino",
-deepskyblue: "azzurro cielo scuro",
-dimgray: "grigio 80%",
-dimgrey: "grigio 80%", // same as dimgray
-dodgerblue: "blu d'oriente",
-firebrick: "rosso mattone",
-floralwhite: "bianco giglio",
-forestgreen: "verde foresta",
-fuchsia: "fucsia",
-gainsboro: "grigio 10%",
-ghostwhite: "bianco gesso",
-gold: "oro",
-goldenrod: "ocra gialla",
-gray: "grigio",
-green: "verde",
-greenyellow: "giallo verde",
-grey: "grigio", // same as gray
-honeydew: "bianco germoglio",
-hotpink: "rosa acceso",
-indianred: "terra indiana",
-indigo: "indaco",
-ivory: "avorio",
-khaki: "kaki",
-lavender: "lavanda",
-lavenderblush: "bianco rosato",
-lawngreen: "verde prato",
-lemonchiffon: "caffelatte chiaro",
-lightblue: "azzurro",
-lightcoral: "rosa corallo",
-lightcyan: "ciano chiaro",
-lightgoldenrodyellow: "giallo tenue",
-lightgray: "grigio chiaro",
-lightgreen: "verde chiaro",
-lightgrey: "grigio chiaro", // same as lightgray
-lightpink: "rosa chiaro",
-lightsalmon: "salmone chiaro",
-lightseagreen: "verde mare chiaro",
-lightskyblue: "azzurro cielo chiaro",
-lightslategray: "grigio ardesia chiaro",
-lightslategrey: "grigio ardesia chiaro", // same as lightslategray
-lightsteelblue: "blu acciao chiaro",
-lightyellow: "giallo chiaro",
-lime: "verde fluorescente",
-limegreen: "verde lime",
-linen: "lino",
-magenta: "magenta",
-maroon: "scarlatto",
-mediumaquamarine: "acquamarina medio",
-mediumblue: "blu medio",
-mediumorchid: "orchidea medio",
-mediumpurple: "porpora medio",
-mediumseagreen: "verde mare medio",
-mediumslateblue: "blu ardesia medio",
-mediumspringgreen: "verde primavera medio",
-mediumturquoise: "turchese medio",
-mediumvioletred: "vinaccia",
-midnightblue: "blu melanzana scuro",
-mintcream: "bianco nuvola",
-mistyrose: "rosa pallido",
-moccasin: "mocassino",
-navajowhite: "pesca chiaro",
-navy: "blu notte",
-oldlace: "mandorla",
-olive: "verde oliva",
-olivedrab: "marrone oliva",
-orange: "arancione",
-orangered: "vermiglio",
-orchid: "orchidea",
-palegoldenrod: "giallo zolfo chiaro",
-palegreen: "verde pallido",
-paleturquoise: "turchese pallido",
-palevioletred: "vinaccia chiaro",
-papayawhip: "cipria",
-peachpuff: "pesca",
-peru: "marrone terra bruciata",
-pink: "rosa",
-plum: "prugna",
-powderblue: "azzurro polvere",
-purple: "porpora",
-red: "rosso",
-rosybrown: "marrone rosato",
-royalblue: "blu reale",
-saddlebrown: "cacao",
-salmon: "salmone",
-sandybrown: "marrone sabbia",
-seagreen: "verde mare",
-seashell: "sabbia rosa",
-sienna: "cuoio",
-silver: "grigio 25%",
-skyblue: "azzurro cielo",
-slateblue: "blu ardesia",
-slategray: "grigio ardesia",
-slategrey: "grigio ardesia", // same as slategray
-snow: "neve",
-springgreen: "verde primavera",
-steelblue: "blu acciao",
-tan: "grigio bruno",
-teal: "verde turchese",
-thistle: "rosa cenere",
-tomato: "pomodoro",
-transparent: "trasparente",
-turquoise: "turchese",
-violet: "viola",
-wheat: "sabbia",
-white: "bianco",
-whitesmoke: "bianco fumo",
-yellow: "giallo",
-yellowgreen: "giallo verde"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "bianco ghiaccio",
+	antiquewhite: "rosa antico",
+	aqua: "verde acqua",
+	aquamarine: "acquamarina",
+	azure: "azure",
+	beige: "beige",
+	bisque: "terracotta",
+	black: "nero",
+	blanchedalmond: "beige 2",
+	blue: "blu",
+	blueviolet: "violetto bluastro",
+	brown: "marrone",
+	burlywood: "legno massiccio",
+	cadetblue: "verde petrolio",
+	chartreuse: "verde brillante",
+	chocolate: "cioccolato",
+	coral: "corallo",
+	cornflowerblue: "blu fiordaliso",
+	cornsilk: "crema",
+	crimson: "rosso scarlatto",
+	cyan: "ciano",
+	darkblue: "blu scuro",
+	darkcyan: "celeste scuro",
+	darkgoldenrod: "ocra scuro",
+	darkgray: "grigio scuro",
+	darkgreen: "verde scuro",
+	darkgrey: "grigio scuro", // same as darkgray
+	darkkhaki: "cachi scuro",
+	darkmagenta: "magenta scuro",
+	darkolivegreen: "verde oliva scuro",
+	darkorange: "arancione scuro",
+	darkorchid: "orchidea scuro",
+	darkred: "rosso scuro",
+	darksalmon: "salmone scuro",
+	darkseagreen: "verde acqua scuro",
+	darkslateblue: "blu ardesia scuro",
+	darkslategray: "grigio ardesia scuro",
+	darkslategrey: "grigio ardesia scuro", // same as darkslategray
+	darkturquoise: "turchese scuro",
+	darkviolet: "viola scuro",
+	deeppink: "ciclamino",
+	deepskyblue: "azzurro intenso",
+	dimgray: "grigio tenue",
+	dimgrey: "grigio tenue", // same as dimgray
+	dodgerblue: "dodger blue",
+	firebrick: "mattone",
+	floralwhite: "bianco grigio",
+	forestgreen: "verde pino scuro",
+	fuchsia: "fucsia",
+	gainsboro: "gainsboro",
+	ghostwhite: "bianco gesso",
+	gold: "oro",
+	goldenrod: "dorato",
+	gray: "grigio",
+	green: "verde",
+	greenyellow: "verde-giallo",
+	grey: "grigio", // same as gray
+	honeydew: "miele",
+	hotpink: "rosa acceso",
+	indianred: "terra indiana",
+	indigo: "indaco",
+	ivory: "avorio",
+	khaki: "cachi",
+	lavender: "lavanda",
+	lavenderblush: "lavanda rosa",
+	lawngreen: "verde brillante chiaro",
+	lemonchiffon: "lemon chiffon",
+	lightblue: "blu chiaro",
+	lightcoral: "corallo chiaro",
+	lightcyan: "ciano chiaro",
+	lightgoldenrodyellow: "giallo dorato chiaro",
+	lightgray: "grigio chiaro",
+	lightgreen: "verde chiaro",
+	lightgrey: "grigio chiaro", // same as lightgray
+	lightpink: "rosa chiaro",
+	lightsalmon: "salmone chiaro",
+	lightseagreen: "verde acqua chiaro",
+	lightskyblue: "azzurro chiaro",
+	lightslategray: "grigio ardesia chiaro",
+	lightslategrey: "grigio ardesia chiaro", // same as lightslategray
+	lightsteelblue: "blu acciaio chiaro",
+	lightyellow: "giallo chiaro",
+	lime: "lime",
+	limegreen: "verde lime",
+	linen: "lino",
+	magenta: "magenta",
+	maroon: "Bordeaux",
+	mediumaquamarine: "acquamarina medio",
+	mediumblue: "blu medio",
+	mediumorchid: "orchidea medio",
+	mediumpurple: "viola medio",
+	mediumseagreen: "verde acqua medio",
+	mediumslateblue: "blu ardesia medio",
+	mediumspringgreen: "verde brillante medio",
+	mediumturquoise: "turchese medio",
+	mediumvioletred: "violetto rosso medio",
+	midnightblue: "blu notte",
+	mintcream: "bianco nuvola",
+	mistyrose: "rosa pallido",
+	moccasin: "mocassino",
+	navajowhite: "sabbia",
+	navy: "blu scuro",
+	oldlace: "mandorla",
+	olive: "verde oliva",
+	olivedrab: "verde bottiglia",
+	orange: "arancione",
+	orangered: "vermiglio",
+	orchid: "orchidea",
+	palegoldenrod: "dorato pallido",
+	palegreen: "verde pallido",
+	paleturquoise: "turchese pallido",
+	palevioletred: "violetto rosso pallido",
+	papayawhip: "papaya",
+	peachpuff: "pesche",
+	peru: "perù",
+	pink: "rosa",
+	plum: "prugna",
+	powderblue: "azzurro polvere",
+	purple: "viola",
+	red: "rosso",
+	rosybrown: "caffè latte",
+	royalblue: "royal blue",
+	saddlebrown: "cacao",
+	salmon: "salmone",
+	sandybrown: "argilla",
+	seagreen: "verde acqua",
+	seashell: "sabbia rosa",
+	sienna: "terra di siena",
+	silver: "argento",
+	skyblue: "azzurro",
+	slateblue: "blu ardesia",
+	slategray: "grigio ardesia",
+	slategrey: "grigio ardesia", // same as slategray
+	snow: "neve",
+	springgreen: "verde brillante",
+	steelblue: "blu brillante",
+	tan: "tan",
+	teal: "verde acqua",
+	thistle: "rosa cenere",
+	tomato: "pomodoro",
+	transparent: "trasparente",
+	turquoise: "turchese",
+	violet: "violetto",
+	wheat: "tabacco",
+	white: "bianco",
+	whitesmoke: "bianco fumo",
+	yellow: "giallo",
+	yellowgreen: "giallo verde"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/ja/colors.js b/dojo/nls/ja/colors.js
index a4a3949..608218b 100644
--- a/dojo/nls/ja/colors.js
+++ b/dojo/nls/ja/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "アリス・ブルー",
-antiquewhite: "アンティーク・ホワイト",
-aqua: "アクア",
-aquamarine: "碧緑",
-azure: "薄い空色",
-beige: "ベージュ",
-bisque: "ビスク",
-black: "黒",
-blanchedalmond: "皮なしアーモンド",
-blue: "青",
-blueviolet: "青紫",
-brown: "茶",
-burlywood: "バーリーウッド",
-cadetblue: "くすんだ青",
-chartreuse: "淡黄緑",
-chocolate: "チョコレート",
-coral: "珊瑚",
-cornflowerblue: "コーンフラワー・ブルー",
-cornsilk: "コーンシルク",
-crimson: "深紅",
-cyan: "シアン・ブルー",
-darkblue: "ダーク・ブルー",
-darkcyan: "ダーク・シアン・ブルー",
-darkgoldenrod: "ダーク・ゴールデン・ロッド",
-darkgray: "ダーク・グレイ",
-darkgreen: "ダーク・グリーン",
-darkgrey: "ダーク・グレイ", // same as darkgray
-darkkhaki: "ダーク・カーキー",
-darkmagenta: "ダーク・マジェンタ",
-darkolivegreen: "ダーク・オリーブ・グリーン",
-darkorange: "ダーク・オレンジ",
-darkorchid: "ダーク・オーキッド",
-darkred: "ダーク・レッド",
-darksalmon: "ダーク・サーモン",
-darkseagreen: "ダーク・シー・グリーン",
-darkslateblue: "ダーク・スレート・ブルー",
-darkslategray: "ダーク・スレート・グレイ",
-darkslategrey: "ダーク・スレート・グレイ", // same as darkslategray
-darkturquoise: "ダーク・ターコイズ",
-darkviolet: "ダーク・バイオレット",
-deeppink: "濃いピンク",
-deepskyblue: "濃い空色",
-dimgray: "くすんだグレイ",
-dimgrey: "くすんだグレイ", // same as dimgray
-dodgerblue: "ドッジャー・ブルー",
-firebrick: "赤煉瓦色",
-floralwhite: "フローラル・ホワイト",
-forestgreen: "フォレスト・グリーン",
-fuchsia: "紫紅色",
-gainsboro: "ゲインズボーロ",
-ghostwhite: "ゴースト・ホワイト",
-gold: "金",
-goldenrod: "ゴールデン・ロッド",
-gray: "グレイ",
-green: "緑",
-greenyellow: "緑黄色",
-grey: "グレイ", // same as gray
-honeydew: "ハニーデュー",
-hotpink: "ホット・ピンク",
-indianred: "インディアン・レッド",
-indigo: "藍色",
-ivory: "アイボリー",
-khaki: "カーキー",
-lavender: "ラベンダー",
-lavenderblush: "ラベンダー・ブラッシ",
-lawngreen: "ローン・グリーン",
-lemonchiffon: "レモン・シフォン",
-lightblue: "ライト・ブルー",
-lightcoral: "ライト・コーラル",
-lightcyan: "ライト・シアン",
-lightgoldenrodyellow: "ライト・ゴールデン・ロッド・イエロー",
-lightgray: "ライト・グレイ",
-lightgreen: "ライト・グリーン",
-lightgrey: "ライト・グレイ", // same as lightgray
-lightpink: "ライト・ピンク",
-lightsalmon: "ライト・サーモン",
-lightseagreen: "ライト・シー・グリーン",
-lightskyblue: "ライト・スカイ・ブルー",
-lightslategray: "ライト・スレート・グレイ",
-lightslategrey: "ライト・スレート・グレイ", // same as lightslategray
-lightsteelblue: "ライト・スチール・ブルー",
-lightyellow: "ライト・イエロー",
-lime: "ライム",
-limegreen: "ライム・グリーン",
-linen: "亜麻色",
-magenta: "赤紫",
-maroon: "えび茶",
-mediumaquamarine: "ミディアム・アクアマリーン",
-mediumblue: "ミディアム・ブルー",
-mediumorchid: "ミディアム・オーキッド",
-mediumpurple: "ミディアム・パープル",
-mediumseagreen: "ミディアム・シー・グリーン",
-mediumslateblue: "ミディアム・スレート・ブルー",
-mediumspringgreen: "ミディアム・スプリング・グリーン",
-mediumturquoise: "ミディアム・ターコイズ",
-mediumvioletred: "ミディアム・バイオレット・レッド",
-midnightblue: "ミッドナイト・ブルー",
-mintcream: "ミント・クリーム",
-mistyrose: "ミスティ・ローズ",
-moccasin: "モカシン",
-navajowhite: "ナバホ・ホワイト",
-navy: "濃紺",
-oldlace: "オールド・レイス",
-olive: "オリーブ",
-olivedrab: "濃黄緑",
-orange: "オレンジ",
-orangered: "オレンジ・レッド",
-orchid: "薄紫",
-palegoldenrod: "ペイル・ゴールデン・ロッド",
-palegreen: "ペイル・グリーン",
-paleturquoise: "ペイル・ターコイズ",
-palevioletred: "ペイル・バイオレット・レッド",
-papayawhip: "パパイア・ホイップ",
-peachpuff: "ピーチ・パフ",
-peru: "ペルー",
-pink: "ピンク",
-plum: "深紫",
-powderblue: "淡青",
-purple: "紫",
-red: "赤",
-rosybrown: "ロージー・ブラウン",
-royalblue: "藤色",
-saddlebrown: "サドル・ブラウン",
-salmon: "サーモン",
-sandybrown: "砂褐色",
-seagreen: "シー・グリーン",
-seashell: "シーシェル",
-sienna: "黄褐色",
-silver: "銀",
-skyblue: "スカイ・ブルー",
-slateblue: "スレート・ブルー",
-slategray: "スレート・グレイ",
-slategrey: "スレート・グレイ", // same as slategray
-snow: "雪色",
-springgreen: "スプリング・グリーン",
-steelblue: "鋼色",
-tan: "茶褐色",
-teal: "ティール",
-thistle: "シスル",
-tomato: "トマト色",
-transparent: "透明",
-turquoise: "ターコイズ",
-violet: "すみれ色",
-wheat: "小麦色",
-white: "白",
-whitesmoke: "ホワイト・スモーク",
-yellow: "黄",
-yellowgreen: "黄緑"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "アリスブルー",
+	antiquewhite: "アンティークホワイト",
+	aqua: "アクア",
+	aquamarine: "碧緑",
+	azure: "薄い空色",
+	beige: "ベージュ",
+	bisque: "ビスク",
+	black: "黒",
+	blanchedalmond: "皮なしアーモンド",
+	blue: "青",
+	blueviolet: "青紫",
+	brown: "茶",
+	burlywood: "バーリーウッド",
+	cadetblue: "くすんだ青",
+	chartreuse: "淡黄緑",
+	chocolate: "チョコレート",
+	coral: "珊瑚",
+	cornflowerblue: "コーンフラワーブルー",
+	cornsilk: "コーンシルク",
+	crimson: "深紅",
+	cyan: "シアンブルー",
+	darkblue: "ダークブルー",
+	darkcyan: "ダークシアンブルー",
+	darkgoldenrod: "ダークゴールデンロッド",
+	darkgray: "ダークグレイ",
+	darkgreen: "ダークグリーン",
+	darkgrey: "ダークグレイ", // same as darkgray
+	darkkhaki: "ダークカーキ",
+	darkmagenta: "ダークマジェンタ",
+	darkolivegreen: "ダークオリーブグリーン",
+	darkorange: "ダークオレンジ",
+	darkorchid: "ダークオーキッド",
+	darkred: "ダークレッド",
+	darksalmon: "ダークサーモン",
+	darkseagreen: "ダークシーグリーン",
+	darkslateblue: "ダークスレートブルー",
+	darkslategray: "ダークスレートグレイ",
+	darkslategrey: "ダークスレートグレイ", // same as darkslategray
+	darkturquoise: "ダークターコイズ",
+	darkviolet: "ダークバイオレット",
+	deeppink: "濃いピンク",
+	deepskyblue: "濃い空色",
+	dimgray: "くすんだグレイ",
+	dimgrey: "くすんだグレイ", // same as dimgray
+	dodgerblue: "ドッジャーブルー",
+	firebrick: "赤煉瓦色",
+	floralwhite: "フローラルホワイト",
+	forestgreen: "フォレストグリーン",
+	fuchsia: "紫紅色",
+	gainsboro: "ゲインズボーロ",
+	ghostwhite: "ゴーストホワイト",
+	gold: "金",
+	goldenrod: "ゴールデンロッド",
+	gray: "グレイ",
+	green: "緑",
+	greenyellow: "緑黄色",
+	grey: "グレイ", // same as gray
+	honeydew: "ハニーデュー",
+	hotpink: "ホットピンク",
+	indianred: "インディアンレッド",
+	indigo: "藍色",
+	ivory: "アイボリー",
+	khaki: "カーキ",
+	lavender: "ラベンダー",
+	lavenderblush: "ラベンダーブラッシ",
+	lawngreen: "ローングリーン",
+	lemonchiffon: "レモンシフォン",
+	lightblue: "ライトブルー",
+	lightcoral: "ライトコーラル",
+	lightcyan: "ライトシアン",
+	lightgoldenrodyellow: "ライトゴールデンロッドイエロー",
+	lightgray: "ライトグレイ",
+	lightgreen: "ライトグリーン",
+	lightgrey: "ライトグレイ", // same as lightgray
+	lightpink: "ライトピンク",
+	lightsalmon: "ライトサーモン",
+	lightseagreen: "ライトシーグリーン",
+	lightskyblue: "ライトスカイブルー",
+	lightslategray: "ライトスレートグレイ",
+	lightslategrey: "ライトスレートグレイ", // same as lightslategray
+	lightsteelblue: "ライトスチールブルー",
+	lightyellow: "ライトイエロー",
+	lime: "ライム",
+	limegreen: "ライムグリーン",
+	linen: "亜麻色",
+	magenta: "赤紫",
+	maroon: "えび茶",
+	mediumaquamarine: "ミディアムアクアマリーン",
+	mediumblue: "ミディアムブルー",
+	mediumorchid: "ミディアムオーキッド",
+	mediumpurple: "ミディアムパープル",
+	mediumseagreen: "ミディアムシーグリーン",
+	mediumslateblue: "ミディアムスレートブルー",
+	mediumspringgreen: "ミディアムスプリンググリーン",
+	mediumturquoise: "ミディアムターコイズ",
+	mediumvioletred: "ミディアムバイオレットレッド",
+	midnightblue: "ミッドナイトブルー",
+	mintcream: "ミントクリーム",
+	mistyrose: "ミスティローズ",
+	moccasin: "モカシン",
+	navajowhite: "ナバホホワイト",
+	navy: "濃紺",
+	oldlace: "オールドレイス",
+	olive: "オリーブ",
+	olivedrab: "濃黄緑",
+	orange: "オレンジ",
+	orangered: "オレンジレッド",
+	orchid: "薄紫",
+	palegoldenrod: "ペイルゴールデンロッド",
+	palegreen: "ペイルグリーン",
+	paleturquoise: "ペイルターコイズ",
+	palevioletred: "ペイルバイオレットレッド",
+	papayawhip: "パパイアホイップ",
+	peachpuff: "ピーチパフ",
+	peru: "ペルー",
+	pink: "ピンク",
+	plum: "深紫",
+	powderblue: "淡青",
+	purple: "紫",
+	red: "赤",
+	rosybrown: "ロージーブラウン",
+	royalblue: "藤色",
+	saddlebrown: "サドルブラウン",
+	salmon: "サーモン",
+	sandybrown: "砂褐色",
+	seagreen: "シーグリーン",
+	seashell: "シーシェル",
+	sienna: "黄褐色",
+	silver: "銀",
+	skyblue: "スカイブルー",
+	slateblue: "スレートブルー",
+	slategray: "スレートグレイ",
+	slategrey: "スレートグレイ", // same as slategray
+	snow: "雪色",
+	springgreen: "スプリンググリーン",
+	steelblue: "鋼色",
+	tan: "茶褐色",
+	teal: "ティール",
+	thistle: "シスル",
+	tomato: "トマト色",
+	transparent: "透明",
+	turquoise: "ターコイズ",
+	violet: "すみれ色",
+	wheat: "小麦色",
+	white: "白",
+	whitesmoke: "ホワイトスモーク",
+	yellow: "黄",
+	yellowgreen: "黄緑"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/kk/colors.js b/dojo/nls/kk/colors.js
index 2f929cb..26245a0 100644
--- a/dojo/nls/kk/colors.js
+++ b/dojo/nls/kk/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "бозғылт көк",
-antiquewhite: "ақ антик",
-aqua: "су түсі",
-aquamarine: "жасылдау-көк",
-azure: "көкшіл",
-beige: "сарғыш",
-bisque: "бисквит",
-black: "қара",
-blanchedalmond: "ағартылған бадам",
-blue: "көк",
-blueviolet: "көк-ақшыл көк",
-brown: "қоңыр",
-burlywood: "ағаш тамыры",
-cadetblue: "кадет көк",
-chartreuse: "жасылдау-сары",
-chocolate: "шоколад",
-coral: "коралл",
-cornflowerblue: "көктікен көк",
-cornsilk: "жібек",
-crimson: "таңқұрай",
-cyan: "циан",
-darkblue: "күңгірт көк",
-darkcyan: "күңгірт циан",
-darkgoldenrod: "қара алтын",
-darkgray: "қою сұры",
-darkgreen: "қою жасыл",
-darkgrey: "қою сұры", // same as darkgray
-darkkhaki: "қою хаки",
-darkmagenta: "қою күлгін",
-darkolivegreen: "қою қоңырлау жасыл",
-darkorange: "қою қызғылт сары",
-darkorchid: "күңгірт орсель",
-darkred: "күңгірт қызыл",
-darksalmon: "қою сарылау қызғылт",
-darkseagreen: "қою теңіз толқыны",
-darkslateblue: "күңгірт грифель көк",
-darkslategray: "күңгірт көкшіл сұры",
-darkslategrey: "күңгірт көкшіл сұры", // same as darkslategray
-darkturquoise: "күңгірт көгілдір",
-darkviolet: "күңгірт күлгін",
-deeppink: "қою қызғылт",
-deepskyblue: "қою аспан көк",
-dimgray: "күңгірт сұры",
-dimgrey: "күңгірт сұры", // same as dimgray
-dodgerblue: "көк доджер",
-firebrick: "қызыл кірпіш",
-floralwhite: "гүлді ақ",
-forestgreen: "шөпті жасыл",
-fuchsia: "фуксия",
-gainsboro: "gainsboro",
-ghostwhite: "елесті ақ",
-gold: "сары түсті",
-goldenrod: "алтын",
-gray: "сұры",
-green: "жасыл",
-greenyellow: "жасыл-сары",
-grey: "сұры", // same as gray
-honeydew: "балдай",
-hotpink: "ашық қызғылт",
-indianred: "үнділік қызыл",
-indigo: "индиго",
-ivory: "піл сүйег",
-khaki: "хаки",
-lavender: "бозғылт ақшыл көк",
-lavenderblush: "күңгірт ақшыл қызыл",
-lawngreen: "көгал жасыл",
-lemonchiffon: "лимон шиффон",
-lightblue: "ақшыл көк",
-lightcoral: "ашық коралл",
-lightcyan: "ашық көгілдір",
-lightgoldenrodyellow: "ашық сары түсті сары",
-lightgray: "ашық сұры",
-lightgreen: "ақшыл жасыл",
-lightgrey: "ашық сұры", // same as lightgray
-lightpink: "ақшыл қызғылт",
-lightsalmon: "ашық сарғыш қызғылт",
-lightseagreen: "ашық теңіз толқыны",
-lightskyblue: "ашық аспан көк",
-lightslategray: "ашық көкшіл сұры",
-lightslategrey: "ашық көкшіл сұры", // same as lightslategray
-lightsteelblue: "ашық сұрғылт көк",
-lightyellow: "ашық сары",
-lime: "әк",
-limegreen: "әк жасыл",
-linen: "зығыр",
-magenta: "фуксин",
-maroon: "сарғылт",
-mediumaquamarine: "орташа жасылдау көк",
-mediumblue: "орташа көк",
-mediumorchid: "орташа ақшыл",
-mediumpurple: "орташа күлгін",
-mediumseagreen: "орташа теңіз толқыны",
-mediumslateblue: "орташа көкшіл сұры",
-mediumspringgreen: "орташа ашық жасыл",
-mediumturquoise: "орташа көгілдір",
-mediumvioletred: "орташа ақшыл көк-қызыл",
-midnightblue: "түн ортасы көк",
-mintcream: "жалбыз майы",
-mistyrose: "көмескі қызғылт",
-moccasin: "мокасин",
-navajowhite: "навахо ақ",
-navy: "қара-көк",
-oldlace: "ескі бау",
-olive: "зәйтүнді",
-olivedrab: "жасылдау сары",
-orange: "қызғылт сары",
-orangered: "қызғылт сары қызыл",
-orchid: "орхидея",
-palegoldenrod: "бозғылт алтын",
-palegreen: "бозғылт жасыл",
-paleturquoise: "бозғылт көгілдір",
-palevioletred: "бозғылт ақшыл көк-қызыл",
-papayawhip: "папайя қамшысы",
-peachpuff: "шабдалы",
-peru: "перу",
-pink: "қызғылт",
-plum: "алхоры",
-powderblue: "жасылдау көк",
-purple: "күлгін",
-red: "қызыл",
-rosybrown: "қызғылт қоңыр",
-royalblue: "патша көк",
-saddlebrown: "тоқым қоңыр",
-salmon: "сомон",
-sandybrown: "құмды қоңыр",
-seagreen: "теңіз толқыны",
-seashell: "теңіз қабыршағы",
-sienna: "сиенна",
-silver: "күміс түстес",
-skyblue: "аспан көк",
-slateblue: "грифель көк",
-slategray: "көкшіл сұры",
-slategrey: "көкшіл сұры", // same as slategray
-snow: "қар",
-springgreen: "көктем жасыл",
-steelblue: "көкшіл сұрғылт",
-tan: "сарғыш қоңыр",
-teal: "шүрегей",
-thistle: "артишок",
-tomato: "қызанақ",
-transparent: "мөлдір",
-turquoise: "көгілдір",
-violet: "күлгін",
-wheat: "бидай",
-white: "ақ",
-whitesmoke: "ақ түтін",
-yellow: "сары",
-yellowgreen: "сарғыш жасыл"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "бозғылт көк",
+	antiquewhite: "ақ антик",
+	aqua: "су түсі",
+	aquamarine: "жасылдау-көк",
+	azure: "көкшіл",
+	beige: "сарғыш",
+	bisque: "бисквит",
+	black: "қара",
+	blanchedalmond: "ағартылған бадам",
+	blue: "көк",
+	blueviolet: "көк-ақшыл көк",
+	brown: "қоңыр",
+	burlywood: "ағаш тамыры",
+	cadetblue: "кадет көк",
+	chartreuse: "жасылдау-сары",
+	chocolate: "шоколад",
+	coral: "коралл",
+	cornflowerblue: "көктікен көк",
+	cornsilk: "жібек",
+	crimson: "таңқұрай",
+	cyan: "циан",
+	darkblue: "күңгірт көк",
+	darkcyan: "күңгірт циан",
+	darkgoldenrod: "қара алтын",
+	darkgray: "қою сұры",
+	darkgreen: "қою жасыл",
+	darkgrey: "қою сұры", // same as darkgray
+	darkkhaki: "қою хаки",
+	darkmagenta: "қою қызыл күрең",
+	darkolivegreen: "қою қоңырлау жасыл",
+	darkorange: "қою қызғылт сары",
+	darkorchid: "күңгірт орсель",
+	darkred: "күңгірт қызыл",
+	darksalmon: "қою сарылау қызғылт",
+	darkseagreen: "қою теңіз толқыны",
+	darkslateblue: "күңгірт грифель көк",
+	darkslategray: "күңгірт көкшіл сұры",
+	darkslategrey: "күңгірт көкшіл сұры", // same as darkslategray
+	darkturquoise: "күңгірт көгілдір",
+	darkviolet: "күңгірт қызыл күрең",
+	deeppink: "қою қызғылт",
+	deepskyblue: "қою аспан көк",
+	dimgray: "күңгірт сұры",
+	dimgrey: "күңгірт сұры", // same as dimgray
+	dodgerblue: "көк доджер",
+	firebrick: "қызыл кірпіш",
+	floralwhite: "гүлді ақ",
+	forestgreen: "шөпті жасыл",
+	fuchsia: "фуксия",
+	gainsboro: "gainsboro",
+	ghostwhite: "елесті ақ",
+	gold: "алтындай",
+	goldenrod: "алтын",
+	gray: "сұры",
+	green: "жасыл",
+	greenyellow: "жасыл-сары",
+	grey: "сұры", // same as gray
+	honeydew: "балдай",
+	hotpink: "ашық қызғылт",
+	indianred: "үнділік қызыл",
+	indigo: "индиго",
+	ivory: "піл сүйег",
+	khaki: "хаки",
+	lavender: "бозғылт ақшыл көк",
+	lavenderblush: "күңгірт ақшыл қызыл",
+	lawngreen: "көгал жасыл",
+	lemonchiffon: "лимон шиффон",
+	lightblue: "ақшыл көк",
+	lightcoral: "ашық коралл",
+	lightcyan: "ашық көгілдір",
+	lightgoldenrodyellow: "ашық алтындай сары",
+	lightgray: "ашық сұры",
+	lightgreen: "ақшыл жасыл",
+	lightgrey: "ашық сұры", // same as lightgray
+	lightpink: "ақшыл қызғылт",
+	lightsalmon: "ашық сарғыш қызғылт",
+	lightseagreen: "ашық теңіз толқыны",
+	lightskyblue: "ашық аспан көк",
+	lightslategray: "ашық көкшіл сұры",
+	lightslategrey: "ашық көкшіл сұры", // same as lightslategray
+	lightsteelblue: "ашық сұрғылт көк",
+	lightyellow: "ашық сары",
+	lime: "әк",
+	limegreen: "әк жасыл",
+	linen: "зығыр",
+	magenta: "фуксин",
+	maroon: "сарғылт",
+	mediumaquamarine: "орташа жасылдау көк",
+	mediumblue: "орташа көк",
+	mediumorchid: "орташа ақшыл",
+	mediumpurple: "орташа қызыл күрең",
+	mediumseagreen: "орташа теңіз толқыны",
+	mediumslateblue: "орташа көкшіл сұры",
+	mediumspringgreen: "орташа ашық жасыл",
+	mediumturquoise: "орташа көгілдір",
+	mediumvioletred: "орташа ақшыл көк-қызыл",
+	midnightblue: "түн ортасы көк",
+	mintcream: "жалбыз майы",
+	mistyrose: "көмескі қызғылт",
+	moccasin: "мокасин",
+	navajowhite: "навахо ақ",
+	navy: "теңіз көк",
+	oldlace: "ескі бау",
+	olive: "зәйтүнді",
+	olivedrab: "жасылдау сары",
+	orange: "қызғылт сары",
+	orangered: "қызғылт сары қызыл",
+	orchid: "орхидея",
+	palegoldenrod: "бозғылт алтын",
+	palegreen: "бозғылт жасыл",
+	paleturquoise: "бозғылт көгілдір",
+	palevioletred: "бозғылт ақшыл көк-қызыл",
+	papayawhip: "папайя қамшысы",
+	peachpuff: "шабдалы",
+	peru: "перу",
+	pink: "қызғылт",
+	plum: "алхоры",
+	powderblue: "жасылдау көк",
+	purple: "қызыл күрең",
+	red: "қызыл",
+	rosybrown: "қызғылт қоңыр",
+	royalblue: "патша көк",
+	saddlebrown: "тоқым қоңыр",
+	salmon: "сомон",
+	sandybrown: "құмды қоңыр",
+	seagreen: "теңіз толқыны",
+	seashell: "теңіз қабыршағы",
+	sienna: "сиенна",
+	silver: "күмістей",
+	skyblue: "аспан көк",
+	slateblue: "грифель көк",
+	slategray: "көкшіл сұры",
+	slategrey: "көкшіл сұры", // same as slategray
+	snow: "қар",
+	springgreen: "көктем жасыл",
+	steelblue: "көкшіл сұрғылт",
+	tan: "сарғыш қоңыр",
+	teal: "шүрегей",
+	thistle: "артишок",
+	tomato: "қызанақ",
+	transparent: "мөлдір",
+	turquoise: "көгілдір",
+	violet: "күлгін",
+	wheat: "бидай",
+	white: "ақ",
+	whitesmoke: "ақ түтін",
+	yellow: "сары",
+	yellowgreen: "сарғыш жасыл"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/ko/colors.js b/dojo/nls/ko/colors.js
index 94f295d..8d19cbe 100644
--- a/dojo/nls/ko/colors.js
+++ b/dojo/nls/ko/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "앨리스 블루(alice blue)",
-antiquewhite: "앤틱 화이트(antique white)",
-aqua: "아쿠아(aqua)",
-aquamarine: "아쿠아마린(aquamarine)",
-azure: "애쥬어(azure)",
-beige: "베이지(beige)",
-bisque: "비스크(bisque)",
-black: "블랙(black)",
-blanchedalmond: "블랜치 아몬드(blanched almond)",
-blue: "블루(blue)",
-blueviolet: "블루 바이올렛(blue-violet)",
-brown: "브라운(brown)",
-burlywood: "벌리우드(burlywood)",
-cadetblue: "카뎃 블루(cadet blue)",
-chartreuse: "샤르트뢰즈(chartreuse)",
-chocolate: "초콜렛(chocolate)",
-coral: "코랄(coral)",
-cornflowerblue: "콘플라워 블루(cornflower blue)",
-cornsilk: "콘실크(cornsilk)",
-crimson: "크림슨(crimson)",
-cyan: "시안(cyan)",
-darkblue: "다크 블루(dark blue)",
-darkcyan: "다크 시안(dark cyan)",
-darkgoldenrod: "다크 골든로드(dark goldenrod)",
-darkgray: "다크 그레이(dark gray)",
-darkgreen: "다크 그린(dark green)",
-darkgrey: "다크 그레이(dark gray)", // same as darkgray
-darkkhaki: "다크 카키(dark khaki)",
-darkmagenta: "다크 마젠타(dark magenta)",
-darkolivegreen: "다크 올리브 그린(dark olive green)",
-darkorange: "다크 오렌지(dark orange)",
-darkorchid: "다크 오키드(dark orchid)",
-darkred: "다크 레드(dark red)",
-darksalmon: "다크 샐몬(dark salmon)",
-darkseagreen: "다크 씨 그린(dark sea green)",
-darkslateblue: "다크 슬레이트 블루(dark slate blue)",
-darkslategray: "다크 슬레이트 그레이(dark slate gray)",
-darkslategrey: "다크 슬레이트 그레이(dark slate gray)", // same as darkslategray
-darkturquoise: "다크 터콰즈(dark turquoise)",
-darkviolet: "다크 바이올렛(dark violet)",
-deeppink: "딥 핑크(deep pink)",
-deepskyblue: "딥 스카이 블루(deep sky blue)",
-dimgray: "딤 그레이(dim gray)",
-dimgrey: "딤 그레이(dim gray)", // same as dimgray
-dodgerblue: "다저 블루(dodger blue)",
-firebrick: "파이어 브릭(fire brick)",
-floralwhite: "플로랄 화이트(floral white)",
-forestgreen: "포레스트 그린(forest green)",
-fuchsia: "후크샤(fuchsia)",
-gainsboro: "게인스브로(gainsboro)",
-ghostwhite: "고스트 화이트(ghost white)",
-gold: "골드(gold)",
-goldenrod: "골든로드(goldenrod)",
-gray: "그레이(gray)",
-green: "그린(green)",
-greenyellow: "그린 옐로우(green-yellow)",
-grey: "그레이(gray)", // same as gray
-honeydew: "허니듀(honeydew)",
-hotpink: "핫 핑크(hot pink)",
-indianred: "인디안 레드(indian red)",
-indigo: "인디고(indigo)",
-ivory: "아이보리(ivory)",
-khaki: "카키(khaki)",
-lavender: "라벤더(lavender)",
-lavenderblush: "라벤더 블러쉬(lavender blush)",
-lawngreen: "론 그린(lawn green)",
-lemonchiffon: "레몬 쉬폰(lemon chiffon)",
-lightblue: "라이트 블루(light blue)",
-lightcoral: "라이트 코랄(light coral)",
-lightcyan: "라이트 시안(light cyan)",
-lightgoldenrodyellow: "라이트 골든로드 옐로우(light goldenrod yellow)",
-lightgray: "라이트 그레이(light gray)",
-lightgreen: "라이트 그린(light green)",
-lightgrey: "라이트 그레이(light gray)", // same as lightgray
-lightpink: "라이트 핑크(light pink)",
-lightsalmon: "라이트 샐몬(light salmon)",
-lightseagreen: "라이트 씨 그린(light sea green)",
-lightskyblue: "라이트 스카이 블루(light sky blue)",
-lightslategray: "라이트 슬레이트 그레이(light slate gray)",
-lightslategrey: "라이트 슬레이트 그레이(light slate gray)", // same as lightslategray
-lightsteelblue: "라이트 스틸 블루(light steel blue)",
-lightyellow: "라이트 옐로우(light yellow)",
-lime: "라임(lime)",
-limegreen: "라임 그린(lime green)",
-linen: "리넨(linen)",
-magenta: "마젠타(magenta)",
-maroon: "마룬(maroon)",
-mediumaquamarine: "미디엄 아쿠아마린(medium aquamarine)",
-mediumblue: "미디엄 블루(medium blue)",
-mediumorchid: "미디엄 오키드(medium orchid)",
-mediumpurple: "미디엄 퍼플(medium purple)",
-mediumseagreen: "미디엄 씨 그린(medium sea green)",
-mediumslateblue: "미디엄 슬레이트 블루(medium slate blue)",
-mediumspringgreen: "미디엄 스프링 그린(medium spring green)",
-mediumturquoise: "미디엄 터콰즈(medium turquoise)",
-mediumvioletred: "미디엄 바이올렛 레드(medium violet-red)",
-midnightblue: "미드나잇 블루(midnight blue)",
-mintcream: "민트 크림(mint cream)",
-mistyrose: "미스티 로즈(misty rose)",
-moccasin: "모카신(moccasin)",
-navajowhite: "나바호 화이트(navajo white)",
-navy: "네이비(navy)",
-oldlace: "올드 레이스(old lace)",
-olive: "올리브(olive)",
-olivedrab: "올리브 드랩(olive drab)",
-orange: "오렌지(orange)",
-orangered: "오렌지 레드(orange red)",
-orchid: "오키드(orchid)",
-palegoldenrod: "페일 골든로드(pale goldenrod)",
-palegreen: "페일 그린(pale green)",
-paleturquoise: "페일 터콰즈(pale turquoise)",
-palevioletred: "페일 바이올렛 레드(pale violet-red)",
-papayawhip: "파파야 휩(papaya whip)",
-peachpuff: "피치 퍼프(peach puff)",
-peru: "페루(peru)",
-pink: "핑크(pink)",
-plum: "플럼(plum)",
-powderblue: "파우더 블루(powder blue)",
-purple: "퍼플(purple)",
-red: "레드(red)",
-rosybrown: "로지 브라운(rosy brown)",
-royalblue: "로얄 블루(royal blue)",
-saddlebrown: "새들 브라운(saddle brown)",
-salmon: "샐몬(salmon)",
-sandybrown: "샌디 브라운(sandy brown)",
-seagreen: "씨 그린(sea green)",
-seashell: "씨쉘(seashell)",
-sienna: "시에나(sienna)",
-silver: "실버(silver)",
-skyblue: "스카이 블루(sky blue)",
-slateblue: "슬레이트 블루(slate blue)",
-slategray: "슬레이트 그레이(slate gray)",
-slategrey: "슬레이트 그레이(slate gray)", // same as slategray
-snow: "스노우(snow)",
-springgreen: "스프링 그린(spring green)",
-steelblue: "스틸 블루(steel blue)",
-tan: "탠(tan)",
-teal: "틸(teal)",
-thistle: "시슬(thistle)",
-tomato: "토마토(tomato)",
-transparent: "투명(transparent)",
-turquoise: "터콰즈(turquoise)",
-violet: "바이올렛(violet)",
-wheat: "휘트(wheat)",
-white: "화이트(white)",
-whitesmoke: "화이트 스모크(white smoke)",
-yellow: "옐로우(yellow)",
-yellowgreen: "옐로우 그린(yellow green)"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "앨리스 블루(alice blue)",
+	antiquewhite: "앤틱 화이트(antique white)",
+	aqua: "아쿠아(aqua)",
+	aquamarine: "아쿠아마린(aquamarine)",
+	azure: "애쥬어(azure)",
+	beige: "베이지(beige)",
+	bisque: "비스크(bisque)",
+	black: "블랙(black)",
+	blanchedalmond: "블랜치 아몬드(blanched almond)",
+	blue: "블루(blue)",
+	blueviolet: "블루 바이올렛(blue-violet)",
+	brown: "브라운(brown)",
+	burlywood: "벌리우드(burlywood)",
+	cadetblue: "카뎃 블루(cadet blue)",
+	chartreuse: "샤르트뢰즈(chartreuse)",
+	chocolate: "초콜렛(chocolate)",
+	coral: "코랄(coral)",
+	cornflowerblue: "콘플라워 블루(cornflower blue)",
+	cornsilk: "콘실크(cornsilk)",
+	crimson: "크림슨(crimson)",
+	cyan: "시안(cyan)",
+	darkblue: "다크 블루(dark blue)",
+	darkcyan: "다크 시안(dark cyan)",
+	darkgoldenrod: "다크 골든로드(dark goldenrod)",
+	darkgray: "다크 그레이(dark gray)",
+	darkgreen: "다크 그린(dark green)",
+	darkgrey: "다크 그레이(dark gray)", // same as darkgray
+	darkkhaki: "다크 카키(dark khaki)",
+	darkmagenta: "다크 마젠타(dark magenta)",
+	darkolivegreen: "다크 올리브 그린(dark olive green)",
+	darkorange: "다크 오렌지(dark orange)",
+	darkorchid: "다크 오키드(dark orchid)",
+	darkred: "다크 레드(dark red)",
+	darksalmon: "다크 샐몬(dark salmon)",
+	darkseagreen: "다크 씨 그린(dark sea green)",
+	darkslateblue: "다크 슬레이트 블루(dark slate blue)",
+	darkslategray: "다크 슬레이트 그레이(dark slate gray)",
+	darkslategrey: "다크 슬레이트 그레이(dark slate gray)", // same as darkslategray
+	darkturquoise: "다크 터콰즈(dark turquoise)",
+	darkviolet: "다크 바이올렛(dark violet)",
+	deeppink: "딥 핑크(deep pink)",
+	deepskyblue: "딥 스카이 블루(deep sky blue)",
+	dimgray: "딤 그레이(dim gray)",
+	dimgrey: "딤 그레이(dim gray)", // same as dimgray
+	dodgerblue: "다저 블루(dodger blue)",
+	firebrick: "파이어 브릭(fire brick)",
+	floralwhite: "플로랄 화이트(floral white)",
+	forestgreen: "포레스트 그린(forest green)",
+	fuchsia: "후크샤(fuchsia)",
+	gainsboro: "게인스브로(gainsboro)",
+	ghostwhite: "고스트 화이트(ghost white)",
+	gold: "골드(gold)",
+	goldenrod: "골든로드(goldenrod)",
+	gray: "그레이(gray)",
+	green: "그린(green)",
+	greenyellow: "그린 옐로우(green-yellow)",
+	grey: "그레이(gray)", // same as gray
+	honeydew: "허니듀(honeydew)",
+	hotpink: "핫 핑크(hot pink)",
+	indianred: "인디안 레드(indian red)",
+	indigo: "인디고(indigo)",
+	ivory: "아이보리(ivory)",
+	khaki: "카키(khaki)",
+	lavender: "라벤더(lavender)",
+	lavenderblush: "라벤더 블러쉬(lavender blush)",
+	lawngreen: "론 그린(lawn green)",
+	lemonchiffon: "레몬 쉬폰(lemon chiffon)",
+	lightblue: "라이트 블루(light blue)",
+	lightcoral: "라이트 코랄(light coral)",
+	lightcyan: "라이트 시안(light cyan)",
+	lightgoldenrodyellow: "라이트 골든로드 옐로우(light goldenrod yellow)",
+	lightgray: "라이트 그레이(light gray)",
+	lightgreen: "라이트 그린(light green)",
+	lightgrey: "라이트 그레이(light gray)", // same as lightgray
+	lightpink: "라이트 핑크(light pink)",
+	lightsalmon: "라이트 샐몬(light salmon)",
+	lightseagreen: "라이트 씨 그린(light sea green)",
+	lightskyblue: "라이트 스카이 블루(light sky blue)",
+	lightslategray: "라이트 슬레이트 그레이(light slate gray)",
+	lightslategrey: "라이트 슬레이트 그레이(light slate gray)", // same as lightslategray
+	lightsteelblue: "라이트 스틸 블루(light steel blue)",
+	lightyellow: "라이트 옐로우(light yellow)",
+	lime: "라임(lime)",
+	limegreen: "라임 그린(lime green)",
+	linen: "리넨(linen)",
+	magenta: "마젠타(magenta)",
+	maroon: "마룬(maroon)",
+	mediumaquamarine: "미디엄 아쿠아마린(medium aquamarine)",
+	mediumblue: "미디엄 블루(medium blue)",
+	mediumorchid: "미디엄 오키드(medium orchid)",
+	mediumpurple: "미디엄 퍼플(medium purple)",
+	mediumseagreen: "미디엄 씨 그린(medium sea green)",
+	mediumslateblue: "미디엄 슬레이트 블루(medium slate blue)",
+	mediumspringgreen: "미디엄 스프링 그린(medium spring green)",
+	mediumturquoise: "미디엄 터콰즈(medium turquoise)",
+	mediumvioletred: "미디엄 바이올렛 레드(medium violet-red)",
+	midnightblue: "미드나잇 블루(midnight blue)",
+	mintcream: "민트 크림(mint cream)",
+	mistyrose: "미스티 로즈(misty rose)",
+	moccasin: "모카신(moccasin)",
+	navajowhite: "나바호 화이트(navajo white)",
+	navy: "네이비(navy)",
+	oldlace: "올드 레이스(old lace)",
+	olive: "올리브(olive)",
+	olivedrab: "올리브 드랩(olive drab)",
+	orange: "오렌지(orange)",
+	orangered: "오렌지 레드(orange red)",
+	orchid: "오키드(orchid)",
+	palegoldenrod: "페일 골든로드(pale goldenrod)",
+	palegreen: "페일 그린(pale green)",
+	paleturquoise: "페일 터콰즈(pale turquoise)",
+	palevioletred: "페일 바이올렛 레드(pale violet-red)",
+	papayawhip: "파파야 휩(papaya whip)",
+	peachpuff: "피치 퍼프(peach puff)",
+	peru: "페루(peru)",
+	pink: "핑크(pink)",
+	plum: "플럼(plum)",
+	powderblue: "파우더 블루(powder blue)",
+	purple: "퍼플(purple)",
+	red: "레드(red)",
+	rosybrown: "로지 브라운(rosy brown)",
+	royalblue: "로얄 블루(royal blue)",
+	saddlebrown: "새들 브라운(saddle brown)",
+	salmon: "샐몬(salmon)",
+	sandybrown: "샌디 브라운(sandy brown)",
+	seagreen: "씨 그린(sea green)",
+	seashell: "씨쉘(seashell)",
+	sienna: "시에나(sienna)",
+	silver: "실버(silver)",
+	skyblue: "스카이 블루(sky blue)",
+	slateblue: "슬레이트 블루(slate blue)",
+	slategray: "슬레이트 그레이(slate gray)",
+	slategrey: "슬레이트 그레이(slate gray)", // same as slategray
+	snow: "스노우(snow)",
+	springgreen: "스프링 그린(spring green)",
+	steelblue: "스틸 블루(steel blue)",
+	tan: "탠(tan)",
+	teal: "틸(teal)",
+	thistle: "시슬(thistle)",
+	tomato: "토마토(tomato)",
+	transparent: "투명(transparent)",
+	turquoise: "터콰즈(turquoise)",
+	violet: "바이올렛(violet)",
+	wheat: "휘트(wheat)",
+	white: "화이트(white)",
+	whitesmoke: "화이트 스모크(white smoke)",
+	yellow: "옐로우(yellow)",
+	yellowgreen: "옐로우 그린(yellow green)"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/nb/colors.js b/dojo/nls/nb/colors.js
index 79aa9fc..fa9b2a6 100644
--- a/dojo/nls/nb/colors.js
+++ b/dojo/nls/nb/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "blåhvit",
-antiquewhite: "antikk hvit",
-aqua: "akva",
-aquamarine: "akvamarin",
-azure: "asur",
-beige: "beige",
-bisque: "gulrosa",
-black: "svart",
-blanchedalmond: "lys mandel",
-blue: "blå",
-blueviolet: "blåfiolett",
-brown: "brun",
-burlywood: "matt mellombrun",
-cadetblue: "mørk grønnblå",
-chartreuse: "løvgrønn",
-chocolate: "sjokolade",
-coral: "korall",
-cornflowerblue: "kornblå",
-cornsilk: "cornsilk",
-crimson: "karmosinrødt",
-cyan: "cyan",
-darkblue: "mørk blå",
-darkcyan: "mørk cyan",
-darkgoldenrod: "mørk gyldenris",
-darkgray: "mørk grå",
-darkgreen: "mørk grønn",
-darkgrey: "mørk grå", // same as darkgray
-darkkhaki: "mørk khaki",
-darkmagenta: "mørk magenta",
-darkolivegreen: "mørk olivengrønn",
-darkorange: "mørk oransje",
-darkorchid: "mørk orkide",
-darkred: "mørk rød",
-darksalmon: "mørk lakserosa",
-darkseagreen: "mørk sjøgrønn",
-darkslateblue: "mørk skiferblå",
-darkslategray: "mørk skifergrå",
-darkslategrey: "mørk skifergrå", // same as darkslategray
-darkturquoise: "mørk turkis",
-darkviolet: "mørk fiolett",
-deeppink: "dyp rosa",
-deepskyblue: "dyp himmelblå",
-dimgray: "mørk mørkegrå",
-dimgrey: "mørk mørkegrå", // same as dimgray
-dodgerblue: "lys havblå",
-firebrick: "mursteinsrød",
-floralwhite: "blomsterhvit",
-forestgreen: "skoggrønn",
-fuchsia: "fuksia",
-gainsboro: "lys lys grå",
-ghostwhite: "egghvit",
-gold: "gull",
-goldenrod: "gyldenris",
-gray: "grå",
-green: "grønn",
-greenyellow: "gulgrønn",
-grey: "grå", // same as gray
-honeydew: "grønnhvit",
-hotpink: "halvmørk rosa",
-indianred: "rustrød",
-indigo: "indigo",
-ivory: "elfenbenshvit",
-khaki: "khaki",
-lavender: "lavendel",
-lavenderblush: "lillahvit",
-lawngreen: "plengrønn",
-lemonchiffon: "ferskenfarget",
-lightblue: "lys blå",
-lightcoral: "lys korall",
-lightcyan: "lys cyan",
-lightgoldenrodyellow: "lys gyldenrisgul",
-lightgray: "lys grå",
-lightgreen: "lys grønn",
-lightgrey: "lys grå", // same as lightgray
-lightpink: "lys rosa",
-lightsalmon: "lys lakserosa",
-lightseagreen: "lys sjøgrønn",
-lightskyblue: "lys himmelblå",
-lightslategray: "lys skifergrå",
-lightslategrey: "lys skifergrå", // same as lightslategray
-lightsteelblue: "lys stålblå",
-lightyellow: "lys gul",
-lime: "lime",
-limegreen: "limegrønn",
-linen: "lin",
-magenta: "magenta",
-maroon: "rødbrun",
-mediumaquamarine: "middels akvamarin",
-mediumblue: "mellomblå",
-mediumorchid: "middels orkide",
-mediumpurple: "middels purpur",
-mediumseagreen: "middels sjøgrønn",
-mediumslateblue: "middels skiferblå",
-mediumspringgreen: "middels vårgrønn",
-mediumturquoise: "middels turkis",
-mediumvioletred: "middels fiolettrød",
-midnightblue: "midnattsblå",
-mintcream: "mintkrem",
-mistyrose: "lys rosenrød",
-moccasin: "lys gulbrun",
-navajowhite: "gulbrun",
-navy: "marineblå",
-oldlace: "kniplingshvit",
-olive: "oliven",
-olivedrab: "middels olivengrønn",
-orange: "oransje",
-orangered: "rødoransje",
-orchid: "orkide",
-palegoldenrod: "svak gyldenris",
-palegreen: "svak grønn",
-paleturquoise: "svak turkis",
-palevioletred: "svak fiolettrød",
-papayawhip: "lys papaya",
-peachpuff: "brunrosa",
-peru: "lys nøttebrun",
-pink: "rosa",
-plum: "plommefarget",
-powderblue: "lys grønnblå",
-purple: "purpur",
-red: "rød",
-rosybrown: "brunlilla",
-royalblue: "kongeblå",
-saddlebrown: "mørk nøttebrun",
-salmon: "lakserosa",
-sandybrown: "sandbrun",
-seagreen: "sjøgrønn",
-seashell: "skjellhvit",
-sienna: "nøttebrun",
-silver: "sølvfarget",
-skyblue: "himmelblå",
-slateblue: "skiferblå",
-slategray: "skifergrå",
-slategrey: "skifergrå", // same as slategray
-snow: "snøhvit",
-springgreen: "vårgrønn",
-steelblue: "stålblå",
-tan: "matt mellombrun",
-teal: "mørk grønnblå",
-thistle: "lys grålilla",
-tomato: "tomatrød",
-transparent: "gjennomsiktig",
-turquoise: "turkis",
-violet: "fiolett",
-wheat: "varm sienna",
-white: "hvit",
-whitesmoke: "røykhvit",
-yellow: "gul",
-yellowgreen: "gulgrønn"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "blåhvit",
+	antiquewhite: "antikk hvit",
+	aqua: "akva",
+	aquamarine: "akvamarin",
+	azure: "asur",
+	beige: "beige",
+	bisque: "gulrosa",
+	black: "svart",
+	blanchedalmond: "lys mandel",
+	blue: "blå",
+	blueviolet: "blåfiolett",
+	brown: "brun",
+	burlywood: "matt mellombrun",
+	cadetblue: "mørk grønnblå",
+	chartreuse: "løvgrønn",
+	chocolate: "sjokolade",
+	coral: "korall",
+	cornflowerblue: "kornblå",
+	cornsilk: "cornsilk",
+	crimson: "karmosinrødt",
+	cyan: "cyan",
+	darkblue: "mørk blå",
+	darkcyan: "mørk cyan",
+	darkgoldenrod: "mørk gyldenris",
+	darkgray: "mørk grå",
+	darkgreen: "mørk grønn",
+	darkgrey: "mørk grå", // same as darkgray
+	darkkhaki: "mørk khaki",
+	darkmagenta: "mørk magenta",
+	darkolivegreen: "mørk olivengrønn",
+	darkorange: "mørk oransje",
+	darkorchid: "mørk orkide",
+	darkred: "mørk rød",
+	darksalmon: "mørk lakserosa",
+	darkseagreen: "mørk sjøgrønn",
+	darkslateblue: "mørk skiferblå",
+	darkslategray: "mørk skifergrå",
+	darkslategrey: "mørk skifergrå", // same as darkslategray
+	darkturquoise: "mørk turkis",
+	darkviolet: "mørk fiolett",
+	deeppink: "dyp rosa",
+	deepskyblue: "dyp himmelblå",
+	dimgray: "mørk mørkegrå",
+	dimgrey: "mørk mørkegrå", // same as dimgray
+	dodgerblue: "lys havblå",
+	firebrick: "mursteinsrød",
+	floralwhite: "blomsterhvit",
+	forestgreen: "skoggrønn",
+	fuchsia: "fuksia",
+	gainsboro: "lys lys grå",
+	ghostwhite: "egghvit",
+	gold: "gull",
+	goldenrod: "gyldenris",
+	gray: "grå",
+	green: "grønn",
+	greenyellow: "gulgrønn",
+	grey: "grå", // same as gray
+	honeydew: "grønnhvit",
+	hotpink: "halvmørk rosa",
+	indianred: "rustrød",
+	indigo: "indigo",
+	ivory: "elfenbenshvit",
+	khaki: "khaki",
+	lavender: "lavendel",
+	lavenderblush: "lillahvit",
+	lawngreen: "plengrønn",
+	lemonchiffon: "ferskenfarget",
+	lightblue: "lys blå",
+	lightcoral: "lys korall",
+	lightcyan: "lys cyan",
+	lightgoldenrodyellow: "lys gyldenrisgul",
+	lightgray: "lys grå",
+	lightgreen: "lys grønn",
+	lightgrey: "lys grå", // same as lightgray
+	lightpink: "lys rosa",
+	lightsalmon: "lys lakserosa",
+	lightseagreen: "lys sjøgrønn",
+	lightskyblue: "lys himmelblå",
+	lightslategray: "lys skifergrå",
+	lightslategrey: "lys skifergrå", // same as lightslategray
+	lightsteelblue: "lys stålblå",
+	lightyellow: "lys gul",
+	lime: "lime",
+	limegreen: "limegrønn",
+	linen: "lin",
+	magenta: "magenta",
+	maroon: "rødbrun",
+	mediumaquamarine: "middels akvamarin",
+	mediumblue: "mellomblå",
+	mediumorchid: "middels orkide",
+	mediumpurple: "middels purpur",
+	mediumseagreen: "middels sjøgrønn",
+	mediumslateblue: "middels skiferblå",
+	mediumspringgreen: "middels vårgrønn",
+	mediumturquoise: "middels turkis",
+	mediumvioletred: "middels fiolettrød",
+	midnightblue: "midnattsblå",
+	mintcream: "mintkrem",
+	mistyrose: "lys rosenrød",
+	moccasin: "lys gulbrun",
+	navajowhite: "gulbrun",
+	navy: "marineblå",
+	oldlace: "kniplingshvit",
+	olive: "oliven",
+	olivedrab: "middels olivengrønn",
+	orange: "oransje",
+	orangered: "rødoransje",
+	orchid: "orkide",
+	palegoldenrod: "svak gyldenris",
+	palegreen: "svak grønn",
+	paleturquoise: "svak turkis",
+	palevioletred: "svak fiolettrød",
+	papayawhip: "lys papaya",
+	peachpuff: "brunrosa",
+	peru: "lys nøttebrun",
+	pink: "rosa",
+	plum: "plommefarget",
+	powderblue: "lys grønnblå",
+	purple: "purpur",
+	red: "rød",
+	rosybrown: "brunlilla",
+	royalblue: "kongeblå",
+	saddlebrown: "mørk nøttebrun",
+	salmon: "lakserosa",
+	sandybrown: "sandbrun",
+	seagreen: "sjøgrønn",
+	seashell: "skjellhvit",
+	sienna: "nøttebrun",
+	silver: "sølvfarget",
+	skyblue: "himmelblå",
+	slateblue: "skiferblå",
+	slategray: "skifergrå",
+	slategrey: "skifergrå", // same as slategray
+	snow: "snøhvit",
+	springgreen: "vårgrønn",
+	steelblue: "stålblå",
+	tan: "matt mellombrun",
+	teal: "mørk grønnblå",
+	thistle: "lys grålilla",
+	tomato: "tomatrød",
+	transparent: "gjennomsiktig",
+	turquoise: "turkis",
+	violet: "fiolett",
+	wheat: "varm sienna",
+	white: "hvit",
+	whitesmoke: "røykhvit",
+	yellow: "gul",
+	yellowgreen: "gulgrønn"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/nl/colors.js b/dojo/nls/nl/colors.js
index 618b07f..a4f39d1 100644
--- a/dojo/nls/nl/colors.js
+++ b/dojo/nls/nl/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "lichtblauw",
-antiquewhite: "antiekwit",
-aqua: "aqua",
-aquamarine: "aquamarijn",
-azure: "azuur",
-beige: "beige",
-bisque: "oranjegeel",
-black: "zwart",
-blanchedalmond: "amandel",
-blue: "blauw",
-blueviolet: "violet",
-brown: "bruin",
-burlywood: "lichtbruin",
-cadetblue: "donkerstaalblauw",
-chartreuse: "groengeel",
-chocolate: "chocoladebruin",
-coral: "koraalrood",
-cornflowerblue: "korenbloemblauw",
-cornsilk: "maïsgeel",
-crimson: "karmozijnrood",
-cyan: "cyaan",
-darkblue: "donkerblauw",
-darkcyan: "donkercyaan",
-darkgoldenrod: "donkergoud",
-darkgray: "donkergrijs",
-darkgreen: "donkergroen",
-darkgrey: "donkergrijs", // same as darkgray
-darkkhaki: "donkerkaki",
-darkmagenta: "donkermagenta",
-darkolivegreen: "donkerolijfgroen",
-darkorange: "donkeroranje",
-darkorchid: "donkerorchidee",
-darkred: "donkerrood",
-darksalmon: "donkerzalm",
-darkseagreen: "donkerzeegroen",
-darkslateblue: "donkergrijsblauw",
-darkslategray: "donkerblauwgrijs",
-darkslategrey: "donkerblauwgrijs", // same as darkslategray
-darkturquoise: "donkerturquoise",
-darkviolet: "donkerviolet",
-deeppink: "donkerroze",
-deepskyblue: "diephemelblauw",
-dimgray: "dofgrijs",
-dimgrey: "dofgrijs", // same as dimgray
-dodgerblue: "helderblauw",
-firebrick: "vuursteenrood",
-floralwhite: "rozewit",
-forestgreen: "bosgroen",
-fuchsia: "fuchsia",
-gainsboro: "lichtblauwgrijs",
-ghostwhite: "spierwit",
-gold: "goud",
-goldenrod: "goudbruin",
-gray: "grijs",
-green: "groen",
-greenyellow: "groengeel",
-grey: "grijs", // same as gray
-honeydew: "meloen",
-hotpink: "acaciaroze",
-indianred: "indisch rood",
-indigo: "indigo",
-ivory: "ivoorwit",
-khaki: "kaki",
-lavender: "lavendelblauw",
-lavenderblush: "lavendelblos",
-lawngreen: "grasgroen",
-lemonchiffon: "citroengeel",
-lightblue: "lichtblauw",
-lightcoral: "lichtkoraal",
-lightcyan: "lichtcyaan",
-lightgoldenrodyellow: "lichtgoudgeel",
-lightgray: "lichtgrijs",
-lightgreen: "lichtgroen",
-lightgrey: "lichtgrijs", // same as lightgray
-lightpink: "lichtroze",
-lightsalmon: "lichtzalm",
-lightseagreen: "lichtzeegroen",
-lightskyblue: "lichthemelsblauw",
-lightslategray: "lichtblauwgrijs",
-lightslategrey: "lichtblauwgrijs", // same as lightslategray
-lightsteelblue: "lichtstaalblauw",
-lightyellow: "lichtgeel",
-lime: "limoen",
-limegreen: "limoengroen",
-linen: "linnen",
-magenta: "magenta",
-maroon: "kastanjebruin",
-mediumaquamarine: "midaquamarijn",
-mediumblue: "midblauw",
-mediumorchid: "midorchidee",
-mediumpurple: "midpurper",
-mediumseagreen: "midzeegroen",
-mediumslateblue: "midgrijsblauw",
-mediumspringgreen: "midlentegroen",
-mediumturquoise: "midturquoise",
-mediumvioletred: "midvioletrood",
-midnightblue: "nachtblauw",
-mintcream: "mintroomgeel",
-mistyrose: "matroze",
-moccasin: "moccasin",
-navajowhite: "navajowit",
-navy: "marineblauw",
-oldlace: "kant",
-olive: "olijfgroen",
-olivedrab: "grijsbruin",
-orange: "oranje",
-orangered: "oranjerood",
-orchid: "orchidee",
-palegoldenrod: "bleekgeel",
-palegreen: "bleekgroen",
-paleturquoise: "bleekturquoise",
-palevioletred: "bleekvioletrood",
-papayawhip: "papajaroze",
-peachpuff: "perzikroze",
-peru: "bruin",
-pink: "roze",
-plum: "pruim",
-powderblue: "lichtblauw-wit",
-purple: "purper",
-red: "rood",
-rosybrown: "roodbruin",
-royalblue: "koningsblauw",
-saddlebrown: "leerbruin",
-salmon: "zalm",
-sandybrown: "zandbruin",
-seagreen: "zeegroen",
-seashell: "schelp",
-sienna: "sienna",
-silver: "zilvergrijs",
-skyblue: "hemelsblauw",
-slateblue: "leiblauw",
-slategray: "leigrijs",
-slategrey: "leigrijs", // same as slategray
-snow: "sneeuwwit",
-springgreen: "lentegroen",
-steelblue: "staalblauw",
-tan: "geelbruin",
-teal: "grijsblauw",
-thistle: "distel",
-tomato: "tomaat",
-transparent: "transparant",
-turquoise: "turquoise",
-violet: "violet",
-wheat: "tarwebruin",
-white: "wit",
-whitesmoke: "rookwit",
-yellow: "geel",
-yellowgreen: "geelgroen"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "lichtblauw",
+	antiquewhite: "antiekwit",
+	aqua: "aqua",
+	aquamarine: "aquamarijn",
+	azure: "azuur",
+	beige: "beige",
+	bisque: "oranjegeel",
+	black: "zwart",
+	blanchedalmond: "amandel",
+	blue: "blauw",
+	blueviolet: "violet",
+	brown: "bruin",
+	burlywood: "lichtbruin",
+	cadetblue: "donkerstaalblauw",
+	chartreuse: "groengeel",
+	chocolate: "chocoladebruin",
+	coral: "koraalrood",
+	cornflowerblue: "korenbloemblauw",
+	cornsilk: "maïsgeel",
+	crimson: "karmozijnrood",
+	cyan: "cyaan",
+	darkblue: "donkerblauw",
+	darkcyan: "donkercyaan",
+	darkgoldenrod: "donkergoud",
+	darkgray: "donkergrijs",
+	darkgreen: "donkergroen",
+	darkgrey: "donkergrijs", // same as darkgray
+	darkkhaki: "donkerkaki",
+	darkmagenta: "donkermagenta",
+	darkolivegreen: "donkerolijfgroen",
+	darkorange: "donkeroranje",
+	darkorchid: "donkerorchidee",
+	darkred: "donkerrood",
+	darksalmon: "donkerzalm",
+	darkseagreen: "donkerzeegroen",
+	darkslateblue: "donkergrijsblauw",
+	darkslategray: "donkerblauwgrijs",
+	darkslategrey: "donkerblauwgrijs", // same as darkslategray
+	darkturquoise: "donkerturquoise",
+	darkviolet: "donkerviolet",
+	deeppink: "donkerroze",
+	deepskyblue: "diephemelblauw",
+	dimgray: "dofgrijs",
+	dimgrey: "dofgrijs", // same as dimgray
+	dodgerblue: "helderblauw",
+	firebrick: "vuursteenrood",
+	floralwhite: "rozewit",
+	forestgreen: "bosgroen",
+	fuchsia: "fuchsia",
+	gainsboro: "lichtblauwgrijs",
+	ghostwhite: "spierwit",
+	gold: "goud",
+	goldenrod: "goudbruin",
+	gray: "grijs",
+	green: "groen",
+	greenyellow: "groengeel",
+	grey: "grijs", // same as gray
+	honeydew: "meloen",
+	hotpink: "acaciaroze",
+	indianred: "indisch rood",
+	indigo: "indigo",
+	ivory: "ivoorwit",
+	khaki: "kaki",
+	lavender: "lavendelblauw",
+	lavenderblush: "lavendelblos",
+	lawngreen: "grasgroen",
+	lemonchiffon: "citroengeel",
+	lightblue: "lichtblauw",
+	lightcoral: "lichtkoraal",
+	lightcyan: "lichtcyaan",
+	lightgoldenrodyellow: "lichtgoudgeel",
+	lightgray: "lichtgrijs",
+	lightgreen: "lichtgroen",
+	lightgrey: "lichtgrijs", // same as lightgray
+	lightpink: "lichtroze",
+	lightsalmon: "lichtzalm",
+	lightseagreen: "lichtzeegroen",
+	lightskyblue: "lichthemelsblauw",
+	lightslategray: "lichtblauwgrijs",
+	lightslategrey: "lichtblauwgrijs", // same as lightslategray
+	lightsteelblue: "lichtstaalblauw",
+	lightyellow: "lichtgeel",
+	lime: "limoen",
+	limegreen: "limoengroen",
+	linen: "linnen",
+	magenta: "magenta",
+	maroon: "kastanjebruin",
+	mediumaquamarine: "midaquamarijn",
+	mediumblue: "midblauw",
+	mediumorchid: "midorchidee",
+	mediumpurple: "midpurper",
+	mediumseagreen: "midzeegroen",
+	mediumslateblue: "midgrijsblauw",
+	mediumspringgreen: "midlentegroen",
+	mediumturquoise: "midturquoise",
+	mediumvioletred: "midvioletrood",
+	midnightblue: "nachtblauw",
+	mintcream: "mintroomgeel",
+	mistyrose: "matroze",
+	moccasin: "moccasin",
+	navajowhite: "navajowit",
+	navy: "marineblauw",
+	oldlace: "kant",
+	olive: "olijfgroen",
+	olivedrab: "grijsbruin",
+	orange: "oranje",
+	orangered: "oranjerood",
+	orchid: "orchidee",
+	palegoldenrod: "bleekgeel",
+	palegreen: "bleekgroen",
+	paleturquoise: "bleekturquoise",
+	palevioletred: "bleekvioletrood",
+	papayawhip: "papajaroze",
+	peachpuff: "perzikroze",
+	peru: "bruin",
+	pink: "roze",
+	plum: "pruim",
+	powderblue: "lichtblauw-wit",
+	purple: "purper",
+	red: "rood",
+	rosybrown: "roodbruin",
+	royalblue: "koningsblauw",
+	saddlebrown: "leerbruin",
+	salmon: "zalm",
+	sandybrown: "zandbruin",
+	seagreen: "zeegroen",
+	seashell: "schelp",
+	sienna: "sienna",
+	silver: "zilvergrijs",
+	skyblue: "hemelsblauw",
+	slateblue: "leiblauw",
+	slategray: "leigrijs",
+	slategrey: "leigrijs", // same as slategray
+	snow: "sneeuwwit",
+	springgreen: "lentegroen",
+	steelblue: "staalblauw",
+	tan: "geelbruin",
+	teal: "grijsblauw",
+	thistle: "distel",
+	tomato: "tomaat",
+	transparent: "transparant",
+	turquoise: "turquoise",
+	violet: "violet",
+	wheat: "tarwebruin",
+	white: "wit",
+	whitesmoke: "rookwit",
+	yellow: "geel",
+	yellowgreen: "geelgroen"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/pl/colors.js b/dojo/nls/pl/colors.js
index 8ff7af0..e001e59 100644
--- a/dojo/nls/pl/colors.js
+++ b/dojo/nls/pl/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "bladoniebieski",
-antiquewhite: "biel antyczna",
-aqua: "morski",
-aquamarine: "akwamaryna",
-azure: "lazurowy",
-beige: "beżowy",
-bisque: "biszkoptowy",
-black: "czarny",
-blanchedalmond: "migdałowy",
-blue: "niebieski",
-blueviolet: "błękitnofiołkowy",
-brown: "brązowy",
-burlywood: "kolor drewna",
-cadetblue: "niebieskoszary",
-chartreuse: "żółtooliwkowy",
-chocolate: "czekoladowy",
-coral: "koralowy",
-cornflowerblue: "chabrowy",
-cornsilk: "kukurydziany",
-crimson: "karmazynowy",
-cyan: "niebieskozielony",
-darkblue: "ciemnoniebieski",
-darkcyan: "ciemnoniebieskozielony",
-darkgoldenrod: "ciemne stare złoto",
-darkgray: "ciemnoszary",
-darkgreen: "ciemnozielony",
-darkgrey: "ciemnoszary", // same as darkgray
-darkkhaki: "ciemny khaki",
-darkmagenta: "ciemnoamarantowy",
-darkolivegreen: "ciemnooliwkowy",
-darkorange: "ciemnopomarańczowy",
-darkorchid: "ciemna orchidea",
-darkred: "ciemnoczerwony",
-darksalmon: "ciemnołososiowy",
-darkseagreen: "ciemna zieleń morska",
-darkslateblue: "ciemny gołębi",
-darkslategray: "ciemny mysi",
-darkslategrey: "ciemny mysi", // same as darkslategray
-darkturquoise: "mlecznoturkusowy",
-darkviolet: "ciemnofiołkowy",
-deeppink: "głęboki różowy",
-deepskyblue: "intensywny błękit nieba",
-dimgray: "przyciemniony szary",
-dimgrey: "przyciemniony szary", // same as dimgray
-dodgerblue: "błękit Dodgers",
-firebrick: "ceglasty",
-floralwhite: "kwiatowa biel",
-forestgreen: "leśna zieleń",
-fuchsia: "fuksjowy",
-gainsboro: "bladoszary",
-ghostwhite: "bladobiały",
-gold: "złoty",
-goldenrod: "stare złoto",
-gray: "szary",
-green: "zielony",
-greenyellow: "zielonożółty",
-grey: "szary", // same as gray
-honeydew: "miodowy",
-hotpink: "odblaskoworóżowy",
-indianred: "kasztanowy",
-indigo: "indygo",
-ivory: "kość słoniowa",
-khaki: "khaki",
-lavender: "lawendowy",
-lavenderblush: "lawendowocielisty",
-lawngreen: "trawiasty",
-lemonchiffon: "cytrynowy",
-lightblue: "jasnoniebieski",
-lightcoral: "jasnokoralowy",
-lightcyan: "jasnoniebieskozielony",
-lightgoldenrodyellow: "jasnożółte stare złoto",
-lightgray: "jasnoszary",
-lightgreen: "jasnozielony",
-lightgrey: "jasnoszary", // same as lightgray
-lightpink: "jasnoróżowy",
-lightsalmon: "jasnołososiowy",
-lightseagreen: "jasna zieleń morska",
-lightskyblue: "jasny błękit nieba",
-lightslategray: "jasny mysi",
-lightslategrey: "jasny mysi", // same as lightslategray
-lightsteelblue: "jasnostalowoniebieski",
-lightyellow: "jasnożółty",
-lime: "limonkowy",
-limegreen: "zielony limonkowy",
-linen: "lniany",
-magenta: "amarantowy",
-maroon: "kasztanowy",
-mediumaquamarine: "średnia akwamaryna",
-mediumblue: "ciemnochabrowy",
-mediumorchid: "średnia orchidea",
-mediumpurple: "średni fioletowy",
-mediumseagreen: "średnia zieleń morska",
-mediumslateblue: "średni gołębi",
-mediumspringgreen: "średnia wiosenna zieleń",
-mediumturquoise: "średni turkusowy",
-mediumvioletred: "średni fiołkowowoczerwony",
-midnightblue: "granatowoczarny",
-mintcream: "jasnomiętowy",
-mistyrose: "bladoróżany",
-moccasin: "mokasynowy",
-navajowhite: "piaskowy",
-navy: "granatowy",
-oldlace: "bladopomarańczowy",
-olive: "oliwkowy",
-olivedrab: "oliwkowa zieleń",
-orange: "pomarańczowy",
-orangered: "pomarańczowoczerwony",
-orchid: "orchidea",
-palegoldenrod: "blade stare złoto",
-palegreen: "bladozielony",
-paleturquoise: "bladoturkusowy",
-palevioletred: "blady fiołkowoczerwony",
-papayawhip: "papaja",
-peachpuff: "brzoskwiniowy",
-peru: "jasnobrązowy",
-pink: "różowy",
-plum: "śliwkowy",
-powderblue: "jasnobladobłękitny",
-purple: "fioletowy",
-red: "czerwony",
-rosybrown: "różowobrązowy",
-royalblue: "królewski błękit",
-saddlebrown: "brąz skórzany",
-salmon: "łososiowy",
-sandybrown: "piaskowy brąz",
-seagreen: "zieleń morska",
-seashell: "matowoliliowy",
-sienna: "siena",
-silver: "srebrny",
-skyblue: "błękit nieba",
-slateblue: "gołębi",
-slategray: "mysi",
-slategrey: "mysi", // same as slategray
-snow: "śnieżny",
-springgreen: "wiosenna zieleń",
-steelblue: "stalowoniebieski",
-tan: "śniady",
-teal: "zielonomodry",
-thistle: "bladofioletowy",
-tomato: "pomidorowy",
-transparent: "przezroczysty",
-turquoise: "turkusowy",
-violet: "fiołkowy",
-wheat: "pszeniczny",
-white: "biały",
-whitesmoke: "przydymiony biały",
-yellow: "żółty",
-yellowgreen: "żółtozielony"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "bladoniebieski",
+	antiquewhite: "biel antyczna",
+	aqua: "morski",
+	aquamarine: "akwamaryna",
+	azure: "lazurowy",
+	beige: "beżowy",
+	bisque: "cielistobeżowy",
+	black: "czarny",
+	blanchedalmond: "obrany migdał",
+	blue: "niebieski",
+	blueviolet: "błękitnofiołkowy",
+	brown: "brązowy",
+	burlywood: "piaskowobeżowy",
+	cadetblue: "szaroniebieski",
+	chartreuse: "żółtooliwkowy",
+	chocolate: "czekoladowy",
+	coral: "koralowy",
+	cornflowerblue: "niebieskochabrowy",
+	cornsilk: "białożółty",
+	crimson: "karmazynowy",
+	cyan: "niebieskozielony",
+	darkblue: "ciemnoniebieski",
+	darkcyan: "ciemnoniebieskozielony",
+	darkgoldenrod: "ciemne stare złoto",
+	darkgray: "ciemnoszary",
+	darkgreen: "ciemnozielony",
+	darkgrey: "ciemnoszary", // same as darkgray
+	darkkhaki: "ciemny khaki",
+	darkmagenta: "ciemnoamarantowy",
+	darkolivegreen: "ciemnooliwkowozielony",
+	darkorange: "ciemnopomarańczowy",
+	darkorchid: "ciemna orchidea",
+	darkred: "ciemnoczerwony",
+	darksalmon: "ciemnołososiowy",
+	darkseagreen: "ciemna zieleń morska",
+	darkslateblue: "ciemny gołębi",
+	darkslategray: "ciemny mysi",
+	darkslategrey: "ciemny mysi", // same as darkslategray
+	darkturquoise: "ciemnoturkusowy",
+	darkviolet: "ciemnofiołkowy",
+	deeppink: "głęboki róż",
+	deepskyblue: "intensywny błękit nieba",
+	dimgray: "przyciemniony szary",
+	dimgrey: "przyciemniony szary", // same as dimgray
+	dodgerblue: "niebieski Dodgersów",
+	firebrick: "podpalana cegła",
+	floralwhite: "złamana biel",
+	forestgreen: "leśna zieleń",
+	fuchsia: "fuksjowy",
+	gainsboro: "jasnoniebieskawoszary",
+	ghostwhite: "sina biel",
+	gold: "złoty",
+	goldenrod: "stare złoto",
+	gray: "szary",
+	green: "zielony",
+	greenyellow: "zielonożółty",
+	grey: "szary", // same as gray
+	honeydew: "miodowy",
+	hotpink: "odblaskoworóżowy",
+	indianred: "kasztanowy",
+	indigo: "indygo",
+	ivory: "kość słoniowa",
+	khaki: "khaki",
+	lavender: "lawendowy",
+	lavenderblush: "lawendoworóżowy",
+	lawngreen: "trawiasty",
+	lemonchiffon: "babka cytrynowa",
+	lightblue: "jasnoniebieski",
+	lightcoral: "jasnokoralowy",
+	lightcyan: "jasnoniebieskozielony",
+	lightgoldenrodyellow: "jasne stare złoto",
+	lightgray: "jasnoszary",
+	lightgreen: "jasnozielony",
+	lightgrey: "jasnoszary", // same as lightgray
+	lightpink: "jasnoróżowy",
+	lightsalmon: "jasnołososiowy",
+	lightseagreen: "jasna zieleń morska",
+	lightskyblue: "jasny błękit nieba",
+	lightslategray: "jasny mysi",
+	lightslategrey: "jasny mysi", // same as lightslategray
+	lightsteelblue: "jasnostalowoniebieski",
+	lightyellow: "jasnożółty",
+	lime: "limonkowy",
+	limegreen: "limonkowozielony",
+	linen: "lniany",
+	magenta: "amarantowy",
+	maroon: "rdzawoczerwony",
+	mediumaquamarine: "średnia akwamaryna",
+	mediumblue: "średni niebieski",
+	mediumorchid: "średnia orchidea",
+	mediumpurple: "średni fioletowy",
+	mediumseagreen: "średnia zieleń morska",
+	mediumslateblue: "średni gołębi",
+	mediumspringgreen: "średnia wiosenna zieleń",
+	mediumturquoise: "średni turkusowy",
+	mediumvioletred: "średni fiołkowowoczerwony",
+	midnightblue: "atramentowoniebieski",
+	mintcream: "miętowokremowy",
+	mistyrose: "mglistoróżany",
+	moccasin: "mokasynowy",
+	navajowhite: "biel Nawaho",
+	navy: "granatowy",
+	oldlace: "ecru",
+	olive: "oliwkowy",
+	olivedrab: "oliwkowozielony",
+	orange: "pomarańczowy",
+	orangered: "czerwona pomarańcza",
+	orchid: "orchidea",
+	palegoldenrod: "blade stare złoto",
+	palegreen: "bladozielony",
+	paleturquoise: "bladoturkusowy",
+	palevioletred: "bladofiołkowoczerwony",
+	papayawhip: "kremowa papaja",
+	peachpuff: "cielisty brzoskwiniowy",
+	peru: "palona glina",
+	pink: "różowy",
+	plum: "śliwkowy",
+	powderblue: "jasnobladobłękitny",
+	purple: "fioletowy",
+	red: "czerwony",
+	rosybrown: "różanobrązowy",
+	royalblue: "królewska purpura",
+	saddlebrown: "brąz skórzany",
+	salmon: "łososiowy",
+	sandybrown: "piaskowobrązowy",
+	seagreen: "zieleń morska",
+	seashell: "matowoliliowy",
+	sienna: "sjena",
+	silver: "srebrny",
+	skyblue: "błękit nieba",
+	slateblue: "gołębi",
+	slategray: "mysi",
+	slategrey: "mysi", // same as slategray
+	snow: "śnieżny",
+	springgreen: "wiosenna zieleń",
+	steelblue: "stalowoniebieski",
+	tan: "śniady",
+	teal: "zielonomodry",
+	thistle: "kwiat ostu",
+	tomato: "pomidorowy",
+	transparent: "przezroczysty",
+	turquoise: "turkusowy",
+	violet: "fiołkowy",
+	wheat: "pszeniczny",
+	white: "biały",
+	whitesmoke: "siwy",
+	yellow: "żółty",
+	yellowgreen: "żółtozielony"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/pt-pt/colors.js b/dojo/nls/pt-pt/colors.js
index 0aed4f5..13d75d6 100644
--- a/dojo/nls/pt-pt/colors.js
+++ b/dojo/nls/pt-pt/colors.js
@@ -1,158 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "azul alice",
-antiquewhite: "branco antigo",
-aqua: "verde-água",
-aquamarine: "verde-azulado",
-azure: "azul-celeste",
-beige: "bege",
-bisque: "rosa-velho",
-black: "preto",
-blanchedalmond: "amêndoa claro",
-blue: "azul",
-blueviolet: "azul violeta",
-brown: "castanho",
-burlywood: "castanho pinho",
-cadetblue: "azul cadete",
-chartreuse: "amarelo esverdeado",
-chocolate: "chocolate",
-coral: "coral",
-cornflowerblue: "azul-violáceo",
-cornsilk: "branco seda",
-crimson: "carmesim",
-cyan: "ciano",
-darkblue: "azul escuro",
-darkcyan: "ciano escuro",
-darkgoldenrod: "ouro velho escuro",
-darkgray: "cinzento escuro",
-darkgreen: "verde escuro",
-darkgrey: "cinzento escuro", // same as darkgray
-darkkhaki: "caqui escuro",
-darkmagenta: "magenta escuro",
-darkolivegreen: "verde-azeitona escuro",
-darkorange: "laranja escuro",
-darkorchid: "orquídea escuro",
-darkred: "vermelho escuro",
-darksalmon: "salmão escuro",
-darkseagreen: "verde marinho escuro",
-darkslateblue: "azul ardósia escuro",
-darkslategray: "cinzento ardósia escuro",
-darkslategrey: "cinzento ardósia escuro", // same as darkslategray
-darkturquoise: "turquesa escuro",
-darkviolet: "violeta escuro",
-deeppink: "rosa profundo",
-deepskyblue: "azul céu profundo",
-dimgray: "cinzento esbatido",
-dimgrey: "cinzento esbatido", // same as dimgray
-dodgerblue: "azul furtivo",
-firebrick: "tijolo fogo",
-floralwhite: "branco floral",
-forestgreen: "verde floresta",
-fuchsia: "fúcsia",
-gainsboro: "cinzento azulado claro",
-ghostwhite: "branco sombreado",
-gold: "dourado",
-goldenrod: "ouro velho",
-gray: "cinzento",
-green: "verde",
-greenyellow: "amarelo esverdeado",
-grey: "cinzento", // same as gray
-honeydew: "mel",
-hotpink: "rosa forte",
-indianred: "almagre",
-indigo: "índigo",
-ivory: "marfim",
-khaki: "caqui",
-lavender: "alfazema",
-lavenderblush: "alfazema rosado",
-lawngreen: "verde relva",
-lemonchiffon: "limão chiffon",
-lightblue: "azul claro",
-lightcoral: "coral claro",
-lightcyan: "ciano claro",
-lightgoldenrodyellow: "ouro velho amarelado claro",
-lightgray: "cinzento claro",
-lightgreen: "verde claro",
-lightgrey: "cinzento claro", // same as lightgray
-lightpink: "rosa claro",
-lightsalmon: "salmão claro",
-lightseagreen: "verde marinho claro",
-lightskyblue: "azul céu claro",
-lightslategray: "cinzento ardósia claro",
-lightslategrey: "cinzento ardósia claro", // same as lightslategray
-lightsteelblue: "azul-aço claro",
-lightyellow: "amarelo claro",
-lime: "lima",
-limegreen: "verde-lima",
-linen: "linho",
-magenta: "magenta",
-maroon: "bordeaux",
-mediumaquamarine: "verde-azulado médio",
-mediumblue: "azul médio",
-mediumorchid: "orquídea médio",
-mediumpurple: "roxo médio",
-mediumseagreen: "verde marinho médio",
-mediumslateblue: "azul ardósia médio",
-mediumspringgreen: "verde primavera médio",
-mediumturquoise: "turquesa médio",
-mediumvioletred: "violeta avermelhado médio",
-midnightblue: "azul meia-noite",
-mintcream: "creme de menta",
-mistyrose: "rosa pálido",
-moccasin: "mocassim",
-navajowhite: "branco navajo",
-navy: "azul marinho",
-oldlace: "renda antiga",
-olive: "azeitona",
-olivedrab: "azeitona claro",
-orange: "laranja",
-orangered: "vermelho alaranjado",
-orchid: "orquídea",
-palegoldenrod: "ouro velho pálido",
-palegreen: "verde pálido",
-paleturquoise: "turquesa pálido",
-palevioletred: "violeta avermelhado pálido",
-papayawhip: "creme de papaia",
-peachpuff: "pêssego",
-peru: "peru",
-pink: "rosa",
-plum: "cor-de-ameixa",
-powderblue: "azul de esmalte",
-purple: "roxo",
-red: "vermelho",
-rosybrown: "castanho rosado",
-royalblue: "azul real",
-saddlebrown: "castanho sela",
-salmon: "salmão",
-sandybrown: "castanho areia",
-seagreen: "verde marinho",
-seashell: "concha",
-sienna: "castanho-avermelhado",
-silver: "prateado",
-skyblue: "azul céu",
-slateblue: "azul ardósia",
-slategray: "cinzento ardósia",
-slategrey: "cinzento ardósia", // same as slategray
-snow: "branco-neve",
-springgreen: "verde primavera",
-steelblue: "azul-aço",
-tan: "castanho claro",
-teal: "verde-azulado",
-thistle: "cardo",
-tomato: "vermelho tomate",
-turquoise: "turquesa",
-violet: "violeta",
-wheat: "trigo",
-white: "branco",
-whitesmoke: "fumo branco",
-yellow: "amarelo",
-yellowgreen: "verde amarelado"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "azul alice",
+	antiquewhite: "branco antigo",
+	aqua: "verde-água",
+	aquamarine: "verde-azulado",
+	azure: "azul-celeste",
+	beige: "bege",
+	bisque: "rosa-velho",
+	black: "preto",
+	blanchedalmond: "amêndoa claro",
+	blue: "azul",
+	blueviolet: "azul violeta",
+	brown: "castanho",
+	burlywood: "castanho pinho",
+	cadetblue: "azul cadete",
+	chartreuse: "amarelo esverdeado",
+	chocolate: "chocolate",
+	coral: "coral",
+	cornflowerblue: "azul-violáceo",
+	cornsilk: "branco seda",
+	crimson: "carmesim",
+	cyan: "ciano",
+	darkblue: "azul escuro",
+	darkcyan: "ciano escuro",
+	darkgoldenrod: "ouro velho escuro",
+	darkgray: "cinzento escuro",
+	darkgreen: "verde escuro",
+	darkgrey: "cinzento escuro", // same as darkgray
+	darkkhaki: "caqui escuro",
+	darkmagenta: "magenta escuro",
+	darkolivegreen: "verde-azeitona escuro",
+	darkorange: "laranja escuro",
+	darkorchid: "orquídea escuro",
+	darkred: "vermelho escuro",
+	darksalmon: "salmão escuro",
+	darkseagreen: "verde marinho escuro",
+	darkslateblue: "azul ardósia escuro",
+	darkslategray: "cinzento ardósia escuro",
+	darkslategrey: "cinzento ardósia escuro", // same as darkslategray
+	darkturquoise: "turquesa escuro",
+	darkviolet: "violeta escuro",
+	deeppink: "rosa profundo",
+	deepskyblue: "azul céu profundo",
+	dimgray: "cinzento esbatido",
+	dimgrey: "cinzento esbatido", // same as dimgray
+	dodgerblue: "azul furtivo",
+	firebrick: "tijolo fogo",
+	floralwhite: "branco floral",
+	forestgreen: "verde floresta",
+	fuchsia: "fúcsia",
+	gainsboro: "cinzento azulado claro",
+	ghostwhite: "branco sombreado",
+	gold: "dourado",
+	goldenrod: "ouro velho",
+	gray: "cinzento",
+	green: "verde",
+	greenyellow: "amarelo esverdeado",
+	grey: "cinzento", // same as gray
+	honeydew: "mel",
+	hotpink: "rosa forte",
+	indianred: "almagre",
+	indigo: "índigo",
+	ivory: "marfim",
+	khaki: "caqui",
+	lavender: "alfazema",
+	lavenderblush: "alfazema rosado",
+	lawngreen: "verde relva",
+	lemonchiffon: "limão chiffon",
+	lightblue: "azul claro",
+	lightcoral: "coral claro",
+	lightcyan: "ciano claro",
+	lightgoldenrodyellow: "ouro velho amarelado claro",
+	lightgray: "cinzento claro",
+	lightgreen: "verde claro",
+	lightgrey: "cinzento claro", // same as lightgray
+	lightpink: "rosa claro",
+	lightsalmon: "salmão claro",
+	lightseagreen: "verde marinho claro",
+	lightskyblue: "azul céu claro",
+	lightslategray: "cinzento ardósia claro",
+	lightslategrey: "cinzento ardósia claro", // same as lightslategray
+	lightsteelblue: "azul-aço claro",
+	lightyellow: "amarelo claro",
+	lime: "lima",
+	limegreen: "verde-lima",
+	linen: "linho",
+	magenta: "magenta",
+	maroon: "bordeaux",
+	mediumaquamarine: "verde-azulado médio",
+	mediumblue: "azul médio",
+	mediumorchid: "orquídea médio",
+	mediumpurple: "roxo médio",
+	mediumseagreen: "verde marinho médio",
+	mediumslateblue: "azul ardósia médio",
+	mediumspringgreen: "verde primavera médio",
+	mediumturquoise: "turquesa médio",
+	mediumvioletred: "violeta avermelhado médio",
+	midnightblue: "azul meia-noite",
+	mintcream: "creme de menta",
+	mistyrose: "rosa pálido",
+	moccasin: "mocassim",
+	navajowhite: "branco navajo",
+	navy: "azul marinho",
+	oldlace: "renda antiga",
+	olive: "azeitona",
+	olivedrab: "azeitona claro",
+	orange: "laranja",
+	orangered: "vermelho alaranjado",
+	orchid: "orquídea",
+	palegoldenrod: "ouro velho pálido",
+	palegreen: "verde pálido",
+	paleturquoise: "turquesa pálido",
+	palevioletred: "violeta avermelhado pálido",
+	papayawhip: "creme de papaia",
+	peachpuff: "pêssego",
+	peru: "peru",
+	pink: "rosa",
+	plum: "cor-de-ameixa",
+	powderblue: "azul de esmalte",
+	purple: "roxo",
+	red: "vermelho",
+	rosybrown: "castanho rosado",
+	royalblue: "azul real",
+	saddlebrown: "castanho sela",
+	salmon: "salmão",
+	sandybrown: "castanho areia",
+	seagreen: "verde marinho",
+	seashell: "concha",
+	sienna: "castanho-avermelhado",
+	silver: "prateado",
+	skyblue: "azul céu",
+	slateblue: "azul ardósia",
+	slategray: "cinzento ardósia",
+	slategrey: "cinzento ardósia", // same as slategray
+	snow: "branco-neve",
+	springgreen: "verde primavera",
+	steelblue: "azul-aço",
+	tan: "castanho claro",
+	teal: "verde-azulado",
+	thistle: "cardo",
+	tomato: "vermelho tomate",
+	transparent: "transparente",
+	turquoise: "turquesa",
+	violet: "violeta",
+	wheat: "trigo",
+	white: "branco",
+	whitesmoke: "fumo branco",
+	yellow: "amarelo",
+	yellowgreen: "verde amarelado"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/pt/colors.js b/dojo/nls/pt/colors.js
index 388cde4..3534065 100644
--- a/dojo/nls/pt/colors.js
+++ b/dojo/nls/pt/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "azul alice",
-antiquewhite: "branco antigo",
-aqua: "aqua",
-aquamarine: "água marinha",
-azure: "azul celeste",
-beige: "bege",
-bisque: "bisque",
-black: "preto",
-blanchedalmond: "amêndoa pelada",
-blue: "azul",
-blueviolet: "azul violeta",
-brown: "marrom",
-burlywood: "burlywood",
-cadetblue: "azul cadet",
-chartreuse: "chartreuse",
-chocolate: "chocolate",
-coral: "coral",
-cornflowerblue: "azul centaurea",
-cornsilk: "cornsilk",
-crimson: "carmesim",
-cyan: "ciano",
-darkblue: "azul escuro",
-darkcyan: "ciano escuro",
-darkgoldenrod: "goldenrod escuro",
-darkgray: "cinza escuro",
-darkgreen: "verde escuro",
-darkgrey: "cinza escuro", // same as darkgray
-darkkhaki: "cáqui escuro",
-darkmagenta: "magenta escuro",
-darkolivegreen: "verde oliva escuro",
-darkorange: "laranja escuro",
-darkorchid: "orquídea escuro",
-darkred: "vermelho escuro",
-darksalmon: "salmão escuro",
-darkseagreen: "verde marinho escuro",
-darkslateblue: "azul ardósia escuro",
-darkslategray: "cinza ardósia escuro",
-darkslategrey: "cinza ardósia escuro", // same as darkslategray
-darkturquoise: "turquesa escuro",
-darkviolet: "violeta escuro",
-deeppink: "rosa profundo",
-deepskyblue: "azul céu intenso",
-dimgray: "cinza turvo",
-dimgrey: "cinza turvo", // same as dimgray
-dodgerblue: "azul dodger",
-firebrick: "firebrick",
-floralwhite: "branco floral",
-forestgreen: "verde floresta",
-fuchsia: "fúcsia",
-gainsboro: "gainsboro",
-ghostwhite: "branco ghost",
-gold: "dourado",
-goldenrod: "goldenrod",
-gray: "cinza",
-green: "verde",
-greenyellow: "amarelo esverdeado",
-grey: "cinza", // same as gray
-honeydew: "honeydew",
-hotpink: "rosa quente",
-indianred: "vermelho indiano",
-indigo: "índigo",
-ivory: "marfim",
-khaki: "cáqui",
-lavender: "lavanda",
-lavenderblush: "lavanda avermelhada",
-lawngreen: "verde grama",
-lemonchiffon: "limão chiffon",
-lightblue: "azul claro",
-lightcoral: "coral claro",
-lightcyan: "ciano claro",
-lightgoldenrodyellow: "amarelo goldenrod claro",
-lightgray: "cinza claro",
-lightgreen: "verde claro",
-lightgrey: "cinza claro", // same as lightgray
-lightpink: "rosa claro",
-lightsalmon: "salmão claro",
-lightseagreen: "verde marinho claro",
-lightskyblue: "azul céu claro",
-lightslategray: "cinza ardósia claro",
-lightslategrey: "cinza ardósia claro", // same as lightslategray
-lightsteelblue: "azul aço claro",
-lightyellow: "amarelo claro",
-lime: "lima",
-limegreen: "verde lima",
-linen: "linho",
-magenta: "magenta",
-maroon: "castanho",
-mediumaquamarine: "água marinha médio",
-mediumblue: "azul médio",
-mediumorchid: "orquídea médio",
-mediumpurple: "roxo médio",
-mediumseagreen: "verde marinho médio",
-mediumslateblue: "azul ardósia médio",
-mediumspringgreen: "verde primavera médio",
-mediumturquoise: "turquesa médio",
-mediumvioletred: "vermelho violeta médio",
-midnightblue: "azul meia-noite",
-mintcream: "creme de menta",
-mistyrose: "rosa enevoado",
-moccasin: "moccasin",
-navajowhite: "branco navajo",
-navy: "marinho",
-oldlace: "cadarço velho",
-olive: "oliva",
-olivedrab: "verde oliva",
-orange: "laranja",
-orangered: "vermelho alaranjado",
-orchid: "orquídea",
-palegoldenrod: "goldenrod esbranquiçado",
-palegreen: "verde esbranquiçado",
-paleturquoise: "turquesa esbranquiçado",
-palevioletred: "vermelho violeta esbranquiçado",
-papayawhip: "creme de papaya",
-peachpuff: "peach puff",
-peru: "peru",
-pink: "rosa",
-plum: "ameixa",
-powderblue: "azul talco",
-purple: "roxo",
-red: "vermelho",
-rosybrown: "marrom rosado",
-royalblue: "azul royal",
-saddlebrown: "marrom saddle",
-salmon: "salmão",
-sandybrown: "marrom cor de areia",
-seagreen: "verde marinho",
-seashell: "seashell",
-sienna: "sienna",
-silver: "prateado",
-skyblue: "azul céu",
-slateblue: "azul ardósia",
-slategray: "cinza ardósia",
-slategrey: "cinza ardósia", // same as slategray
-snow: "branco neve",
-springgreen: "verde primavera",
-steelblue: "azul aço",
-tan: "tan",
-teal: "azul esverdeado",
-thistle: "thistle",
-tomato: "tomate",
-transparent: "transparente",
-turquoise: "turquesa",
-violet: "violeta",
-wheat: "trigo",
-white: "branco",
-whitesmoke: "fumaça branca",
-yellow: "amarelo",
-yellowgreen: "verde amarelado"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "azul alice",
+	antiquewhite: "branco antigo",
+	aqua: "aqua",
+	aquamarine: "água marinha",
+	azure: "azul celeste",
+	beige: "bege",
+	bisque: "bisque",
+	black: "preto",
+	blanchedalmond: "amêndoa pelada",
+	blue: "azul",
+	blueviolet: "azul violeta",
+	brown: "marrom",
+	burlywood: "burlywood",
+	cadetblue: "azul cadet",
+	chartreuse: "chartreuse",
+	chocolate: "chocolate",
+	coral: "coral",
+	cornflowerblue: "azul centaurea",
+	cornsilk: "cornsilk",
+	crimson: "carmesim",
+	cyan: "ciano",
+	darkblue: "azul escuro",
+	darkcyan: "ciano escuro",
+	darkgoldenrod: "goldenrod escuro",
+	darkgray: "cinza escuro",
+	darkgreen: "verde escuro",
+	darkgrey: "cinza escuro", // same as darkgray
+	darkkhaki: "cáqui escuro",
+	darkmagenta: "magenta escuro",
+	darkolivegreen: "verde oliva escuro",
+	darkorange: "laranja escuro",
+	darkorchid: "orquídea escuro",
+	darkred: "vermelho escuro",
+	darksalmon: "salmão escuro",
+	darkseagreen: "verde marinho escuro",
+	darkslateblue: "azul ardósia escuro",
+	darkslategray: "cinza ardósia escuro",
+	darkslategrey: "cinza ardósia escuro", // same as darkslategray
+	darkturquoise: "turquesa escuro",
+	darkviolet: "violeta escuro",
+	deeppink: "rosa profundo",
+	deepskyblue: "azul céu intenso",
+	dimgray: "cinza turvo",
+	dimgrey: "cinza turvo", // same as dimgray
+	dodgerblue: "azul dodger",
+	firebrick: "firebrick",
+	floralwhite: "branco floral",
+	forestgreen: "verde floresta",
+	fuchsia: "fúcsia",
+	gainsboro: "gainsboro",
+	ghostwhite: "branco ghost",
+	gold: "dourado",
+	goldenrod: "goldenrod",
+	gray: "cinza",
+	green: "verde",
+	greenyellow: "amarelo esverdeado",
+	grey: "cinza", // same as gray
+	honeydew: "honeydew",
+	hotpink: "rosa quente",
+	indianred: "vermelho indiano",
+	indigo: "índigo",
+	ivory: "marfim",
+	khaki: "cáqui",
+	lavender: "lavanda",
+	lavenderblush: "lavanda avermelhada",
+	lawngreen: "verde grama",
+	lemonchiffon: "limão chiffon",
+	lightblue: "azul claro",
+	lightcoral: "coral claro",
+	lightcyan: "ciano claro",
+	lightgoldenrodyellow: "amarelo goldenrod claro",
+	lightgray: "cinza claro",
+	lightgreen: "verde claro",
+	lightgrey: "cinza claro", // same as lightgray
+	lightpink: "rosa claro",
+	lightsalmon: "salmão claro",
+	lightseagreen: "verde marinho claro",
+	lightskyblue: "azul céu claro",
+	lightslategray: "cinza ardósia claro",
+	lightslategrey: "cinza ardósia claro", // same as lightslategray
+	lightsteelblue: "azul aço claro",
+	lightyellow: "amarelo claro",
+	lime: "lima",
+	limegreen: "verde lima",
+	linen: "linho",
+	magenta: "magenta",
+	maroon: "castanho",
+	mediumaquamarine: "água marinha médio",
+	mediumblue: "azul médio",
+	mediumorchid: "orquídea médio",
+	mediumpurple: "roxo médio",
+	mediumseagreen: "verde marinho médio",
+	mediumslateblue: "azul ardósia médio",
+	mediumspringgreen: "verde primavera médio",
+	mediumturquoise: "turquesa médio",
+	mediumvioletred: "vermelho violeta médio",
+	midnightblue: "azul meia-noite",
+	mintcream: "creme de menta",
+	mistyrose: "rosa enevoado",
+	moccasin: "moccasin",
+	navajowhite: "branco navajo",
+	navy: "marinho",
+	oldlace: "cadarço velho",
+	olive: "oliva",
+	olivedrab: "verde oliva",
+	orange: "laranja",
+	orangered: "vermelho alaranjado",
+	orchid: "orquídea",
+	palegoldenrod: "goldenrod esbranquiçado",
+	palegreen: "verde esbranquiçado",
+	paleturquoise: "turquesa esbranquiçado",
+	palevioletred: "vermelho violeta esbranquiçado",
+	papayawhip: "creme de papaya",
+	peachpuff: "peach puff",
+	peru: "peru",
+	pink: "rosa",
+	plum: "ameixa",
+	powderblue: "azul talco",
+	purple: "roxo",
+	red: "vermelho",
+	rosybrown: "marrom rosado",
+	royalblue: "azul royal",
+	saddlebrown: "marrom saddle",
+	salmon: "salmão",
+	sandybrown: "marrom cor de areia",
+	seagreen: "verde marinho",
+	seashell: "seashell",
+	sienna: "sienna",
+	silver: "prateado",
+	skyblue: "azul céu",
+	slateblue: "azul ardósia",
+	slategray: "cinza ardósia",
+	slategrey: "cinza ardósia", // same as slategray
+	snow: "branco neve",
+	springgreen: "verde primavera",
+	steelblue: "azul aço",
+	tan: "tan",
+	teal: "azul esverdeado",
+	thistle: "thistle",
+	tomato: "tomate",
+	transparent: "transparente",
+	turquoise: "turquesa",
+	violet: "violeta",
+	wheat: "trigo",
+	white: "branco",
+	whitesmoke: "fumaça branca",
+	yellow: "amarelo",
+	yellowgreen: "verde amarelado"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/ro/colors.js b/dojo/nls/ro/colors.js
index 2286643..2d5390e 100644
--- a/dojo/nls/ro/colors.js
+++ b/dojo/nls/ro/colors.js
@@ -1,160 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "alice blue",
-antiquewhite: "antique white",
-aqua: "aqua",
-aquamarine: "aquamarine",
-azure: "azuriu",
-beige: "bej",
-bisque: "bisque",
-black: "negru",
-blanchedalmond: "blanched almond",
-blue: "albastru",
-blueviolet: "albastru-violet",
-brown: "maro",
-burlywood: "burlywood",
-cadetblue: "cadet blue",
-chartreuse: "chartreuse",
-chocolate: "ciocolată",
-coral: "coral",
-cornflowerblue: "cornflower blue",
-cornsilk: "cornsilk",
-crimson: "crimson",
-cyan: "cyan",
-darkblue: "albastru închis",
-darkcyan: "cyan închis",
-darkgoldenrod: "goldenrod închis",
-darkgray: "cenuşiu închis",
-darkgreen: "verde închis",
-darkgrey: "gri închis", // same as darkgray
-darkkhaki: "kaki închis",
-darkmagenta: "magenta închis",
-darkolivegreen: "verde oliv închis",
-darkorange: "portocaliu închis",
-darkorchid: "dark orchid",
-darkred: "roşu închis",
-darksalmon: "dark salmon",
-darkseagreen: "dark sea green",
-darkslateblue: "dark slate blue",
-darkslategray: "dark slate gray",
-darkslategrey: "dark slate gray", // same as darkslategray
-darkturquoise: "dark turquoise",
-darkviolet: "violet închis",
-deeppink: "roz închis",
-deepskyblue: "deep sky blue",
-dimgray: "dim gray",
-dimgrey: "dim gray", // same as dimgray
-dodgerblue: "dodger blue",
-firebrick: "fire brick",
-floralwhite: "floral white",
-forestgreen: "verde pădure",
-fuchsia: "fuchsia",
-gainsboro: "gainsboro",
-ghostwhite: "ghost white",
-gold: "auriu",
-goldenrod: "goldenrod",
-gray: "cenuşiu",
-green: "verde",
-greenyellow: "verde-galben",
-grey: "gri", // same as gray
-honeydew: "honeydew",
-hotpink: "roz aprins",
-indianred: "roşu indian",
-indigo: "indigo",
-ivory: "ivoriu",
-khaki: "kaki",
-lavender: "levănţică",
-lavenderblush: "lavender blush",
-lawngreen: "lawn green",
-lemonchiffon: "lemon chiffon",
-lightblue: "albastru deschis",
-lightcoral: "coral deschis",
-lightcyan: "cyan deschis",
-lightgoldenrodyellow: "light goldenrod yellow",
-lightgray: "gri deschis",
-lightgreen: "verde deschis",
-lightgrey: "gri deschis", // same as lightgray
-lightpink: "roz deschis",
-lightsalmon: "somon deschis",
-lightseagreen: "verde marin deschis",
-lightskyblue: "albastru cer deschis",
-lightslategray: "light slate gray",
-lightslategrey: "light slate gray", // same as lightslategray
-lightsteelblue: "light steel blue",
-lightyellow: "galben deschis",
-lime: "lime",
-limegreen: "verde lime",
-linen: "linen",
-magenta: "magenta",
-maroon: "maroon",
-mediumaquamarine: "medium aquamarine",
-mediumblue: "medium blue",
-mediumorchid: "medium orchid",
-mediumpurple: "medium purple",
-mediumseagreen: "medium sea green",
-mediumslateblue: "medium slate blue",
-mediumspringgreen: "medium spring green",
-mediumturquoise: "medium turquoise",
-mediumvioletred: "medium violet-red",
-midnightblue: "midnight blue",
-mintcream: "mint cream",
-mistyrose: "trandafiriu obscur",
-moccasin: "moccasin",
-navajowhite: "navajo white",
-navy: "navy",
-oldlace: "old lace",
-olive: "oliv",
-olivedrab: "maron-gălbui oliv",
-orange: "portocaliu",
-orangered: "roşu portocaliu",
-orchid: "orhidee",
-palegoldenrod: "solidago pal",
-palegreen: "verde pal",
-paleturquoise: "turquoise pal",
-palevioletred: "roşu violet pal",
-papayawhip: "papaya whip",
-peachpuff: "puf de piersică",
-peru: "peru",
-pink: "roz",
-plum: "prună",
-powderblue: "albastru pudră",
-purple: "purpură",
-red: "roşu",
-rosybrown: "maro trandafiriu",
-royalblue: "albastru regal",
-saddlebrown: "maro de şa",
-salmon: "somon",
-sandybrown: "maro nisipiu",
-seagreen: "verde marin",
-seashell: "cochilie",
-sienna: "sienna",
-silver: "argintiu",
-skyblue: "albastru de cer",
-slateblue: "albastru ardezie",
-slategray: "gri ardezie",
-slategrey: "gri ardezie", // same as slategray
-snow: "zăpadă",
-springgreen: "verde de primăvară",
-steelblue: "albastru metalic",
-tan: "tan",
-teal: "lişiţă",
-thistle: "ciulin",
-tomato: "roşie",
-transparent: "transparent",
-turquoise: "turquoise",
-violet: "violet",
-wheat: "grâu",
-white: "alb",
-whitesmoke: "fum alb",
-yellow: "galben",
-yellowgreen: "verde galben"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "alice blue",
+	antiquewhite: "antique white",
+	aqua: "aqua",
+	aquamarine: "aquamarine",
+	azure: "azuriu",
+	beige: "bej",
+	bisque: "bisque",
+	black: "negru",
+	blanchedalmond: "blanched almond",
+	blue: "albastru",
+	blueviolet: "albastru-violet",
+	brown: "brun",
+	burlywood: "burlywood",
+	cadetblue: "albastru cadet",
+	chartreuse: "chartreuse",
+	chocolate: "ciocolată",
+	coral: "coral",
+	cornflowerblue: "cornflower blue",
+	cornsilk: "cornsilk",
+	crimson: "stacojiu",
+	cyan: "cyan",
+	darkblue: "albastru închis",
+	darkcyan: "cyan închis",
+	darkgoldenrod: "goldenrod închis",
+	darkgray: "gri închis",
+	darkgreen: "verde închis",
+	darkgrey: "gri închis", // same as darkgray
+	darkkhaki: "kaki închis",
+	darkmagenta: "magenta închis",
+	darkolivegreen: "verde măslină închis",
+	darkorange: "portocaliu închis",
+	darkorchid: "orchid închis",
+	darkred: "roşu închis",
+	darksalmon: "somon închis",
+	darkseagreen: "verde marin închis",
+	darkslateblue: "albastru ardezie închis",
+	darkslategray: "gri ardezie închis",
+	darkslategrey: "gri ardezie închis", // same as darkslategray
+	darkturquoise: "turcoaz închis",
+	darkviolet: "violet închis",
+	deeppink: "roz profund",
+	deepskyblue: "albastru cer profund",
+	dimgray: "dim gray",
+	dimgrey: "dim gray", // same as dimgray
+	dodgerblue: "dodger blue",
+	firebrick: "cărămiziu aprins",
+	floralwhite: "floral white",
+	forestgreen: "forest green",
+	fuchsia: "fuchsia",
+	gainsboro: "gainsboro",
+	ghostwhite: "ghost white",
+	gold: "auriu",
+	goldenrod: "goldenrod",
+	gray: "gri",
+	green: "verde",
+	greenyellow: "verde-gălbui",
+	grey: "gri", // same as gray
+	honeydew: "honeydew",
+	hotpink: "roz aprins",
+	indianred: "roşu indian",
+	indigo: "indigo",
+	ivory: "ivoriu",
+	khaki: "kaki",
+	lavender: "lavandă",
+	lavenderblush: "lavender blush",
+	lawngreen: "lawn green",
+	lemonchiffon: "lemon chiffon",
+	lightblue: "albastru deschis",
+	lightcoral: "coral deschis",
+	lightcyan: "cyan deschis",
+	lightgoldenrodyellow: "goldenrod gălbui deschis",
+	lightgray: "gri deschis",
+	lightgreen: "verde dschis",
+	lightgrey: "gri deschis", // same as lightgray
+	lightpink: "roz deschis",
+	lightsalmon: "somon deschis",
+	lightseagreen: "verde marin deschis",
+	lightskyblue: "albastru cer deschis",
+	lightslategray: "gri ardezie deschis",
+	lightslategrey: "gri ardezie deschis", // same as lightslategray
+	lightsteelblue: "albastru metalic deschis",
+	lightyellow: "galben deschis",
+	lime: "lime",
+	limegreen: "verde lime",
+	linen: "linen",
+	magenta: "magenta",
+	maroon: "maro",
+	mediumaquamarine: "aquamarin mediu",
+	mediumblue: "albastru mediu",
+	mediumorchid: "orchid mediu",
+	mediumpurple: "purpuriu mediu",
+	mediumseagreen: "verde marin mediu",
+	mediumslateblue: "albastru ardezie mediu",
+	mediumspringgreen: "verde primăvară mediu",
+	mediumturquoise: "turcoaz mediu",
+	mediumvioletred: "roşu-violet mediu",
+	midnightblue: "midnight blue",
+	mintcream: "mint cream",
+	mistyrose: "misty rose",
+	moccasin: "moccasin",
+	navajowhite: "navajo white",
+	navy: "navy",
+	oldlace: "old lace",
+	olive: "oliv",
+	olivedrab: "oliv şters",
+	orange: "portocaliu",
+	orangered: "roşu portocaliu",
+	orchid: "orchid",
+	palegoldenrod: "goldenrod pal",
+	palegreen: "verde pal",
+	paleturquoise: "turcoaz pal",
+	palevioletred: "roşu-violet pal",
+	papayawhip: "papaya whip",
+	peachpuff: "peach puff",
+	peru: "peru",
+	pink: "roz",
+	plum: "plum",
+	powderblue: "powder blue",
+	purple: "purpuriu",
+	red: "roşu",
+	rosybrown: "rosy brown",
+	royalblue: "albastru regal",
+	saddlebrown: "saddle brown",
+	salmon: "somon",
+	sandybrown: "sandy brown",
+	seagreen: "verde marin",
+	seashell: "seashell",
+	sienna: "sienna",
+	silver: "argintiu",
+	skyblue: "albastru cer",
+	slateblue: "albastru ardezie",
+	slategray: "gri ardezie",
+	slategrey: "gri ardezie", // same as slategray
+	snow: "zăpadă",
+	springgreen: "verde primăvară",
+	steelblue: "albastru metalic",
+	tan: "tan",
+	teal: "teal",
+	thistle: "thistle",
+	tomato: "tomato",
+	transparent: "transparent",
+	turquoise: "turcoaz",
+	violet: "violet",
+	wheat: "wheat",
+	white: "alb",
+	whitesmoke: "white smoke",
+	yellow: "galben",
+	yellowgreen: "verde gălbui"
 })
-
-//end v1.x content
 );
diff --git a/dojo/nls/ru/colors.js b/dojo/nls/ru/colors.js
index 7be5743..60a11b5 100644
--- a/dojo/nls/ru/colors.js
+++ b/dojo/nls/ru/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "серо-голубой",
-antiquewhite: "белый антик",
-aqua: "зеленовато-голубой",
-aquamarine: "аквамарин",
-azure: "лазурный",
-beige: "бежевый",
-bisque: "бисквитный",
-black: "черный",
-blanchedalmond: "светло-миндальный",
-blue: "синий",
-blueviolet: "сине-фиолетовый",
-brown: "коричневый",
-burlywood: "светло-коричневый",
-cadetblue: "серо-синий",
-chartreuse: "желто-салатный",
-chocolate: "шоколадный",
-coral: "коралловый",
-cornflowerblue: "фиолетово-синий",
-cornsilk: "шелковый оттенок",
-crimson: "малиновый",
-cyan: "циан",
-darkblue: "темно-синий",
-darkcyan: "темный циан",
-darkgoldenrod: "темно-золотистый",
-darkgray: "темно-серый",
-darkgreen: "темно-зеленый",
-darkgrey: "темно-серый", // same as darkgray
-darkkhaki: "темный хаки",
-darkmagenta: "темно-пурпурный",
-darkolivegreen: "темно-оливковый",
-darkorange: "темно-оранжевый",
-darkorchid: "темный орсель",
-darkred: "темно-красный",
-darksalmon: "темно-лососевый",
-darkseagreen: "темный морской волны",
-darkslateblue: "темный грифельно-синий",
-darkslategray: "темный грифельно-серый",
-darkslategrey: "темный грифельно-серый", // same as darkslategray
-darkturquoise: "темный бирюзовый",
-darkviolet: "темно-фиолетовый",
-deeppink: "темно-розовый",
-deepskyblue: "темный небесно-голубой",
-dimgray: "тускло-серый",
-dimgrey: "тускло-серый", // same as dimgray
-dodgerblue: "бледно-синий",
-firebrick: "кирпичный",
-floralwhite: "цветочно-белый",
-forestgreen: "зеленый лесной",
-fuchsia: "фуксин",
-gainsboro: "бледно-серый",
-ghostwhite: "призрачно-белый",
-gold: "золотой",
-goldenrod: "золотистый",
-gray: "серый",
-green: "зеленый",
-greenyellow: "зелено-желтый",
-grey: "серый", // same as gray
-honeydew: "медовый",
-hotpink: "красно-розовый",
-indianred: "индийский красный",
-indigo: "индиго",
-ivory: "слоновой кости",
-khaki: "хаки",
-lavender: "бледно-лиловый",
-lavenderblush: "розовато-лиловый",
-lawngreen: "зеленая лужайка",
-lemonchiffon: "бледно-лимонный",
-lightblue: "светло-синий",
-lightcoral: "светло-коралловый",
-lightcyan: "светлый циан",
-lightgoldenrodyellow: "светло-золотистый",
-lightgray: "светло-серый",
-lightgreen: "светло-зеленый",
-lightgrey: "светло-серый", // same as lightgray
-lightpink: "светло-розовый",
-lightsalmon: "светло-лососевый",
-lightseagreen: "светлый морской волны",
-lightskyblue: "светлый небесно-голубой",
-lightslategray: "светлый грифельно-серый",
-lightslategrey: "светлый грифельно-серый", // same as lightslategray
-lightsteelblue: "светлый стальной",
-lightyellow: "светло-желтый",
-lime: "лайм",
-limegreen: "зеленый лайм",
-linen: "хлопковый",
-magenta: "пурпурный",
-maroon: "темно-бордовый",
-mediumaquamarine: "нейтральный аквамарин",
-mediumblue: "нейтральный синий",
-mediumorchid: "нейтральный орсель",
-mediumpurple: "нейтральный фиолетовый",
-mediumseagreen: "нейтральный морской волны",
-mediumslateblue: "нейтральный грифельно-синий",
-mediumspringgreen: "нейтральный весенне-зеленый",
-mediumturquoise: "нейтральный бирюзовый",
-mediumvioletred: "нейтральный фиолетово-красный",
-midnightblue: "полуночно-синий",
-mintcream: "мятно-кремовый",
-mistyrose: "блекло-розовый",
-moccasin: "мокасин",
-navajowhite: "белый навахо",
-navy: "темно-синий",
-oldlace: "матово-белый",
-olive: "оливковый",
-olivedrab: "желтовато-серый",
-orange: "оранжевый",
-orangered: "оранжево-красный",
-orchid: "орсель",
-palegoldenrod: "бледно-золотистый",
-palegreen: "бледно-зеленый",
-paleturquoise: "бледно-бирюзовый",
-palevioletred: "бледный фиолетово-красный",
-papayawhip: "черенок папайи",
-peachpuff: "персиковый",
-peru: "перу",
-pink: "розовый",
-plum: "сливовый",
-powderblue: "пороховой",
-purple: "фиолетовый",
-red: "красный",
-rosybrown: "розово-коричневый",
-royalblue: "королевский голубой",
-saddlebrown: "кожано-коричневый",
-salmon: "лососевый",
-sandybrown: "коричнево-песчаный",
-seagreen: "морской волны",
-seashell: "морская раковина",
-sienna: "охра",
-silver: "серебристый",
-skyblue: "небесно-голубой",
-slateblue: "грифельно-синий",
-slategray: "грифельно-серый",
-slategrey: "грифельно-серый", // same as slategray
-snow: "белоснежный",
-springgreen: "весенний зеленый",
-steelblue: "стальной",
-tan: "рыжевато-коричневый",
-teal: "чирок",
-thistle: "чертополох",
-tomato: "помидор",
-transparent: "прозрачный",
-turquoise: "бирюзовый",
-violet: "фиолетовый",
-wheat: "пшеница",
-white: "белый",
-whitesmoke: "дымчато-белый",
-yellow: "желтый",
-yellowgreen: "желто-зеленый"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "серо-голубой",
+	antiquewhite: "белый антик",
+	aqua: "зеленовато-голубой",
+	aquamarine: "аквамарин",
+	azure: "лазурный",
+	beige: "бежевый",
+	bisque: "бисквитный",
+	black: "черный",
+	blanchedalmond: "светло-миндальный",
+	blue: "синий",
+	blueviolet: "сине-фиолетовый",
+	brown: "коричневый",
+	burlywood: "светло-коричневый",
+	cadetblue: "серо-синий",
+	chartreuse: "желто-салатный",
+	chocolate: "шоколадный",
+	coral: "коралловый",
+	cornflowerblue: "фиолетово-синий",
+	cornsilk: "шелковый оттенок",
+	crimson: "малиновый",
+	cyan: "циан",
+	darkblue: "темно-синий",
+	darkcyan: "темный циан",
+	darkgoldenrod: "темно-золотистый",
+	darkgray: "темно-серый",
+	darkgreen: "темно-зеленый",
+	darkgrey: "темно-серый", // same as darkgray
+	darkkhaki: "темный хаки",
+	darkmagenta: "темно-пурпурный",
+	darkolivegreen: "темно-оливковый",
+	darkorange: "темно-оранжевый",
+	darkorchid: "темный орсель",
+	darkred: "темно-красный",
+	darksalmon: "темно-лососевый",
+	darkseagreen: "темный морской волны",
+	darkslateblue: "темный грифельно-синий",
+	darkslategray: "темный грифельно-серый",
+	darkslategrey: "темный грифельно-серый", // same as darkslategray
+	darkturquoise: "темный бирюзовый",
+	darkviolet: "темно-фиолетовый",
+	deeppink: "темно-розовый",
+	deepskyblue: "темный небесно-голубой",
+	dimgray: "тускло-серый",
+	dimgrey: "тускло-серый", // same as dimgray
+	dodgerblue: "бледно-синий",
+	firebrick: "кирпичный",
+	floralwhite: "цветочно-белый",
+	forestgreen: "зеленый лесной",
+	fuchsia: "фуксин",
+	gainsboro: "бледно-серый",
+	ghostwhite: "призрачно-белый",
+	gold: "золотой",
+	goldenrod: "золотистый",
+	gray: "серый",
+	green: "зеленый",
+	greenyellow: "зелено-желтый",
+	grey: "серый", // same as gray
+	honeydew: "медовый",
+	hotpink: "красно-розовый",
+	indianred: "индийский красный",
+	indigo: "индиго",
+	ivory: "слоновой кости",
+	khaki: "хаки",
+	lavender: "бледно-лиловый",
+	lavenderblush: "розовато-лиловый",
+	lawngreen: "зеленая лужайка",
+	lemonchiffon: "бледно-лимонный",
+	lightblue: "светло-синий",
+	lightcoral: "светло-коралловый",
+	lightcyan: "светлый циан",
+	lightgoldenrodyellow: "светло-золотистый",
+	lightgray: "светло-серый",
+	lightgreen: "светло-зеленый",
+	lightgrey: "светло-серый", // same as lightgray
+	lightpink: "светло-розовый",
+	lightsalmon: "светло-лососевый",
+	lightseagreen: "светлый морской волны",
+	lightskyblue: "светлый небесно-голубой",
+	lightslategray: "светлый грифельно-серый",
+	lightslategrey: "светлый грифельно-серый", // same as lightslategray
+	lightsteelblue: "светлый стальной",
+	lightyellow: "светло-желтый",
+	lime: "лайм",
+	limegreen: "зеленый лайм",
+	linen: "хлопковый",
+	magenta: "пурпурный",
+	maroon: "темно-бордовый",
+	mediumaquamarine: "нейтральный аквамарин",
+	mediumblue: "нейтральный синий",
+	mediumorchid: "нейтральный орсель",
+	mediumpurple: "нейтральный фиолетовый",
+	mediumseagreen: "нейтральный морской волны",
+	mediumslateblue: "нейтральный грифельно-синий",
+	mediumspringgreen: "нейтральный весенне-зеленый",
+	mediumturquoise: "нейтральный бирюзовый",
+	mediumvioletred: "нейтральный фиолетово-красный",
+	midnightblue: "полуночно-синий",
+	mintcream: "мятно-кремовый",
+	mistyrose: "блекло-розовый",
+	moccasin: "мокасин",
+	navajowhite: "белый навахо",
+	navy: "темно-синий",
+	oldlace: "матово-белый",
+	olive: "оливковый",
+	olivedrab: "желтовато-серый",
+	orange: "оранжевый",
+	orangered: "оранжево-красный",
+	orchid: "орсель",
+	palegoldenrod: "бледно-золотистый",
+	palegreen: "бледно-зеленый",
+	paleturquoise: "бледно-бирюзовый",
+	palevioletred: "бледный фиолетово-красный",
+	papayawhip: "черенок папайи",
+	peachpuff: "персиковый",
+	peru: "перу",
+	pink: "розовый",
+	plum: "сливовый",
+	powderblue: "пороховой",
+	purple: "фиолетовый",
+	red: "красный",
+	rosybrown: "розово-коричневый",
+	royalblue: "королевский голубой",
+	saddlebrown: "кожано-коричневый",
+	salmon: "лососевый",
+	sandybrown: "коричнево-песчаный",
+	seagreen: "морской волны",
+	seashell: "морская раковина",
+	sienna: "охра",
+	silver: "серебристый",
+	skyblue: "небесно-голубой",
+	slateblue: "грифельно-синий",
+	slategray: "грифельно-серый",
+	slategrey: "грифельно-серый", // same as slategray
+	snow: "белоснежный",
+	springgreen: "весенний зеленый",
+	steelblue: "стальной",
+	tan: "рыжевато-коричневый",
+	teal: "чирок",
+	thistle: "чертополох",
+	tomato: "помидор",
+	transparent: "прозрачный",
+	turquoise: "бирюзовый",
+	violet: "фиолетовый",
+	wheat: "пшеница",
+	white: "белый",
+	whitesmoke: "дымчато-белый",
+	yellow: "желтый",
+	yellowgreen: "желто-зеленый"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/sk/colors.js b/dojo/nls/sk/colors.js
index 5e279f3..49bb5a4 100644
--- a/dojo/nls/sk/colors.js
+++ b/dojo/nls/sk/colors.js
@@ -1,160 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "modrá alice",
-antiquewhite: "antická biela",
-aqua: "svetlá zelenomodrá",
-aquamarine: "akvamarínová",
-azure: "azúrová",
-beige: "béžová",
-bisque: "biskvitová",
-black: "čierna",
-blanchedalmond: "lúpané mandle",
-blue: "modrá",
-blueviolet: "modrofialová",
-brown: "hnedá",
-burlywood: "pieskovo hnedá",
-cadetblue: "sivomodrá",
-chartreuse: "kartúza",
-chocolate: "čokoládovo hnedá",
-coral: "koralová",
-cornflowerblue: "nevädzovo modrá",
-cornsilk: "hodvábna žltá",
-crimson: "karmínová",
-cyan: "zelenomodrá",
-darkblue: "tmavomodrá",
-darkcyan: "tmavozelenomodrá",
-darkgoldenrod: "zlatobyľová tmavá",
-darkgray: "tmavosivá",
-darkgreen: "tmavozelená",
-darkgrey: "tmavosivá", // same as darkgray
-darkkhaki: "žltohnedá tmavá",
-darkmagenta: "tmavopurpurová",
-darkolivegreen: "olivovozelená tmavá",
-darkorange: "tmavooranžová",
-darkorchid: "orchideovo ružová tmavá",
-darkred: "tmavočervená",
-darksalmon: "lososovo ružová tmavá",
-darkseagreen: "morská zelená tmavá",
-darkslateblue: "bridlicová modrá tmavá",
-darkslategray: "bridlicová sivá tmavá",
-darkslategrey: "bridlicová sivá tmavá", // same as darkslategray
-darkturquoise: "tyrkysová tmavá",
-darkviolet: "tmavofialová",
-deeppink: "hlboká ružová",
-deepskyblue: "hlboká blankytná modrá",
-dimgray: "sivá matná",
-dimgrey: "sivá matná", // same as dimgray
-dodgerblue: "modrá dodger",
-firebrick: "pálená tehla",
-floralwhite: "kvetinová biela",
-forestgreen: "lesná zelená",
-fuchsia: "purpurová",
-gainsboro: "sivomodrá svetlá",
-ghostwhite: "biely tieň",
-gold: "zlatá",
-goldenrod: "zlatobyľ",
-gray: "sivá",
-green: "zelená",
-greenyellow: "žltozelená",
-grey: "sivá", // same as gray
-honeydew: "ambrózia",
-hotpink: "teplá ružová",
-indianred: "indická červená",
-indigo: "fialovo modrá",
-ivory: "slonovinová",
-khaki: "khaki",
-lavender: "levanduľová",
-lavenderblush: "levanduľový rumenec",
-lawngreen: "zelená tráva",
-lemonchiffon: "citrónový šifón",
-lightblue: "svetlomodrá",
-lightcoral: "koralová svetlá",
-lightcyan: "zelenomodrá svetlá",
-lightgoldenrodyellow: "zlatobyľová svetlá",
-lightgray: "svetlosivá",
-lightgreen: "svetlozelená",
-lightgrey: "svetlosivá", // same as lightgray
-lightpink: "svetloružová",
-lightsalmon: "lososovo ružová svetlá",
-lightseagreen: "morská zelená svetlá",
-lightskyblue: "blankytná modrá svetlá",
-lightslategray: "bridlicová sivá svetlá",
-lightslategrey: "bridlicová sivá svetlá", // same as lightslategray
-lightsteelblue: "oceľovo modrá svetlá",
-lightyellow: "svetložltá",
-lime: "lipová",
-limegreen: "lipová zelená",
-linen: "ľan",
-magenta: "purpurová",
-maroon: "gaštanovo hnedá",
-mediumaquamarine: "akvamarínová stredná",
-mediumblue: "stredne modrá",
-mediumorchid: "orchideovo ružová stredná",
-mediumpurple: "purpurová stredná",
-mediumseagreen: "morská zelená stredná",
-mediumslateblue: "bridlicová modrá stredná",
-mediumspringgreen: "jarná zelená stredná",
-mediumturquoise: "tyrkysová stredná",
-mediumvioletred: "fialovočervená stredná",
-midnightblue: "nočná modrá",
-mintcream: "mätová krémová",
-mistyrose: "zahmlená ruža",
-moccasin: "črievičníková",
-navajowhite: "navajská biela",
-navy: "vojenská zelená",
-oldlace: "stará čipka",
-olive: "olivovo zelená",
-olivedrab: "olivovo zelená fádna",
-orange: "oranžová",
-orangered: "oranžovo červená",
-orchid: "orchideovo ružová",
-palegoldenrod: "bledá zlatobyľová",
-palegreen: "bledozelená",
-paleturquoise: "bledo tyrkysová",
-palevioletred: "bledá fialovo červená",
-papayawhip: "papájový krém",
-peachpuff: "broskyňová pena",
-peru: "peru",
-pink: "ružová",
-plum: "slivková",
-powderblue: "prášková modrá",
-purple: "purpurová",
-red: "červená",
-rosybrown: "ružovo hnedá",
-royalblue: "kráľovská modrá",
-saddlebrown: "sedlová hnedá",
-salmon: "lososovo ružová",
-sandybrown: "pieskovo hnedá",
-seagreen: "morská zelená",
-seashell: "lastúrová",
-sienna: "sienská",
-silver: "strieborná",
-skyblue: "blankytná modrá",
-slateblue: "bridlicová modrá",
-slategray: "bridlicová sivá",
-slategrey: "bridlicová sivá", // same as slategray
-snow: "snehobiela",
-springgreen: "jarná zelená",
-steelblue: "oceľovo modrá",
-tan: "žltohnedá",
-teal: "tyrkysová",
-thistle: "bodliaková fialová",
-tomato: "paradajková červená",
-transparent: "priesvitná",
-turquoise: "tyrkysová",
-violet: "fialová",
-wheat: "pšeničná",
-white: "biela",
-whitesmoke: "biely dym",
-yellow: "žltá",
-yellowgreen: "žltozelená"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "modrá (alice)",
+	antiquewhite: "antická biela",
+	aqua: "vodová",
+	aquamarine: "akvamarínová",
+	azure: "azúrová",
+	beige: "béžová",
+	bisque: "porcelánová",
+	black: "čierna",
+	blanchedalmond: "bledá mandľová",
+	blue: "modrá",
+	blueviolet: "modro-fialová",
+	brown: "hnedá",
+	burlywood: "drevená hnedá",
+	cadetblue: "červeno modrá",
+	chartreuse: "kartúzska",
+	chocolate: "čokoládová",
+	coral: "koralová",
+	cornflowerblue: "nevädzová modrá",
+	cornsilk: "ôstie kukurice",
+	crimson: "karmínová",
+	cyan: "zelenomodrá",
+	darkblue: "tmavomodrá",
+	darkcyan: "tmavá zelenomodrá",
+	darkgoldenrod: "tmavá zlatobyľ",
+	darkgray: "tmavosivá",
+	darkgreen: "tmavozelená",
+	darkgrey: "tmavosivá", // same as darkgray
+	darkkhaki: "tmavá žltohnedá",
+	darkmagenta: "tmavá purpurová",
+	darkolivegreen: "tmavá olivovo zelená",
+	darkorange: "tmavá oranžová",
+	darkorchid: "tmavá orchidea",
+	darkred: "tmavočervená",
+	darksalmon: "tmavá lososová",
+	darkseagreen: "tmavá morská zelená",
+	darkslateblue: "tmavá bridlicová modrá",
+	darkslategray: "tmavá bridlicová sivá",
+	darkslategrey: "tmavá bridlicová sivá", // same as darkslategray
+	darkturquoise: "tmavá tyrkysová",
+	darkviolet: "tmavofialová",
+	deeppink: "hlboká ružová",
+	deepskyblue: "hlboká modrá obloha",
+	dimgray: "matná sivá",
+	dimgrey: "matná sivá", // same as dimgray
+	dodgerblue: "modrá (dodger)",
+	firebrick: "pálená tehla",
+	floralwhite: "biely kvet",
+	forestgreen: "lesná zelená",
+	fuchsia: "fuchsia",
+	gainsboro: "sivá - gainsboro",
+	ghostwhite: "biela (ghost white)",
+	gold: "zlatá",
+	goldenrod: "zlatobyľ",
+	gray: "sivá",
+	green: "zelená",
+	greenyellow: "zelenožltá",
+	grey: "sivá", // same as gray
+	honeydew: "ambrózia",
+	hotpink: "horúca ružová",
+	indianred: "indiánska červená",
+	indigo: "indigo",
+	ivory: "slonovina",
+	khaki: "kaki",
+	lavender: "levanduľa",
+	lavenderblush: "rumencová levanduľa",
+	lawngreen: "trávová zelená",
+	lemonchiffon: "citrónový šifón",
+	lightblue: "svetlomodrá",
+	lightcoral: "svetlá koralová",
+	lightcyan: "svetlá zelenomodrá",
+	lightgoldenrodyellow: "svetlá zlatobyľová žltá",
+	lightgray: "svetlosivá",
+	lightgreen: "svetlozelená",
+	lightgrey: "svetlosivá", // same as lightgray
+	lightpink: "svetloružová",
+	lightsalmon: "svetlá lososová",
+	lightseagreen: "svetlá morská zelená",
+	lightskyblue: "svetlá modrá obloha",
+	lightslategray: "svetlá bridlicová sivá",
+	lightslategrey: "svetlá bridlicová sivá", // same as lightslategray
+	lightsteelblue: "svetlá oceľovomodrá",
+	lightyellow: "svetložltá",
+	lime: "limetková",
+	limegreen: "limetková zelená",
+	linen: "ľan",
+	magenta: "purpurová",
+	maroon: "gaštanová hnedá",
+	mediumaquamarine: "stredná akvamarínová",
+	mediumblue: "stredná modrá",
+	mediumorchid: "stredná orchideová",
+	mediumpurple: "stredná purpurová",
+	mediumseagreen: "stredná morská zelená",
+	mediumslateblue: "stredná bridlicová modrá",
+	mediumspringgreen: "stredná jarná zelená",
+	mediumturquoise: "stredná tyrkysová",
+	mediumvioletred: "stredná fialovočervená",
+	midnightblue: "polnočná modrá",
+	mintcream: "mätová krémová",
+	mistyrose: "zahmlená ruža",
+	moccasin: "mokasínová",
+	navajowhite: "navajská biela",
+	navy: "námornícka",
+	oldlace: "stará čipka",
+	olive: "olivová",
+	olivedrab: "fádna olivová",
+	orange: "oranžová",
+	orangered: "oranžovo červená",
+	orchid: "orchideová",
+	palegoldenrod: "bledá zlatobyľová",
+	palegreen: "bledá zelená",
+	paleturquoise: "bledá tyrkysová",
+	palevioletred: "bledá fialovo červená",
+	papayawhip: "papájový krém",
+	peachpuff: "broskyňový nádych",
+	peru: "peru",
+	pink: "ružová",
+	plum: "slivková",
+	powderblue: "prášková modrá",
+	purple: "purpurová",
+	red: "červená",
+	rosybrown: "ružovo hnedá",
+	royalblue: "kráľovská modrá",
+	saddlebrown: "sedlová hnedá",
+	salmon: "lososová",
+	sandybrown: "piesková hnedá",
+	seagreen: "morská zelená",
+	seashell: "lastúrová",
+	sienna: "sienská",
+	silver: "strieborná",
+	skyblue: "modré nebo",
+	slateblue: "bridlicová modrá",
+	slategray: "bridlicová sivá",
+	slategrey: "bridlicová sivá", // same as slategray
+	snow: "snehová",
+	springgreen: "jarná zelená",
+	steelblue: "oceľovomodrá",
+	tan: "žltohnedá",
+	teal: "zelenomodrá",
+	thistle: "bodliaková",
+	tomato: "paradajková",
+	transparent: "priesvitná",
+	turquoise: "tyrkysová",
+	violet: "fialová",
+	wheat: "pšeničná",
+	white: "biela",
+	whitesmoke: "biely dym",
+	yellow: "žltá",
+	yellowgreen: "žltozelená"
 })
-
-//end v1.x content
 );
diff --git a/dojo/nls/sl/colors.js b/dojo/nls/sl/colors.js
index 8a8b668..1168c98 100644
--- a/dojo/nls/sl/colors.js
+++ b/dojo/nls/sl/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "alice blue modra",
-antiquewhite: "antično bela",
-aqua: "akva",
-aquamarine: "akvamarin",
-azure: "azurno modra",
-beige: "bež",
-bisque: "porcelanasta",
-black: "črna",
-blanchedalmond: "obledelo mandljeva",
-blue: "modra",
-blueviolet: "modro vijolična",
-brown: "rjava",
-burlywood: "peščeno sivo-rjava",
-cadetblue: "kadetsko modra",
-chartreuse: "chartreuse",
-chocolate: "čokoladna",
-coral: "koralna",
-cornflowerblue: "plavičasto modra",
-cornsilk: "koruzna",
-crimson: "karminasta",
-cyan: "cijan",
-darkblue: "temno modra",
-darkcyan: "temno cijan",
-darkgoldenrod: "temna zlata rozga",
-darkgray: "temno siva",
-darkgreen: "temno zelena",
-darkgrey: "temno siva", // same as darkgray
-darkkhaki: "temno kaki",
-darkmagenta: "temna magenta",
-darkolivegreen: "temna olivno zelena",
-darkorange: "temno oranžna",
-darkorchid: "temno orhidejasta",
-darkred: "temno rdeča",
-darksalmon: "temno lososova",
-darkseagreen: "temno morsko zelena",
-darkslateblue: "temno skrilasto modra",
-darkslategray: "temno skrilasto siva",
-darkslategrey: "temno skrilasto siva", // same as darkslategray
-darkturquoise: "temno turkizna",
-darkviolet: "temno vijolična",
-deeppink: "temno rožnata",
-deepskyblue: "temno nebeško modra",
-dimgray: "pepelnato siva",
-dimgrey: "pepelnato siva", // same as dimgray
-dodgerblue: "dodgersko modra",
-firebrick: "opečnata",
-floralwhite: "cvetno bela",
-forestgreen: "gozdno zelena",
-fuchsia: "fuksija",
-gainsboro: "gainsboro",
-ghostwhite: "senčnato bela",
-gold: "zlata",
-goldenrod: "zlata rozga",
-gray: "siva",
-green: "zelena",
-greenyellow: "zeleno-rumena",
-grey: "siva", // same as gray
-honeydew: "medena rosa",
-hotpink: "kričeče rožnata",
-indianred: "indijansko rdeča",
-indigo: "indigo",
-ivory: "slonokoščena",
-khaki: "kaki",
-lavender: "sivka",
-lavenderblush: "rožnato sivka",
-lawngreen: "travniško zelena",
-lemonchiffon: "limonast šifon",
-lightblue: "svetlo modra",
-lightcoral: "svetlo koralna",
-lightcyan: "svetlo cijan",
-lightgoldenrodyellow: "svetlo rumena zlata rozga",
-lightgray: "svetlo siva",
-lightgreen: "svetlo zelena",
-lightgrey: "svetlo siva", // same as lightgray
-lightpink: "svetlo rožnata",
-lightsalmon: "svetlo lososova",
-lightseagreen: "svetlo morsko zelena",
-lightskyblue: "svetlo nebeško modra",
-lightslategray: "svetlo skrilasto siva",
-lightslategrey: "svetlo skrilasto siva", // same as lightslategray
-lightsteelblue: "svetlo kovinsko modra",
-lightyellow: "svetlo rumena",
-lime: "limetasta",
-limegreen: "apneno zelena",
-linen: "lanena",
-magenta: "magenta",
-maroon: "kostanjeva",
-mediumaquamarine: "srednji akvamarin",
-mediumblue: "srednje modra",
-mediumorchid: "srednje orhidejasta",
-mediumpurple: "srednje škrlatna",
-mediumseagreen: "srednje morsko zelena",
-mediumslateblue: "srednje skrilasto modra",
-mediumspringgreen: "srednje pomladno zelena",
-mediumturquoise: "srednje turkizna",
-mediumvioletred: "srednje vijolično rdeča",
-midnightblue: "polnočno modra",
-mintcream: "metina krema",
-mistyrose: "megleno rožnata",
-moccasin: "mokasinasta",
-navajowhite: "navajo bela",
-navy: "mornarska",
-oldlace: "stara čipka",
-olive: "olivna",
-olivedrab: "umazano olivna",
-orange: "oranžna",
-orangered: "oranžno-rdeča",
-orchid: "orhidejasta",
-palegoldenrod: "bleda zlata rozga",
-palegreen: "bledo zelena",
-paleturquoise: "bledo turkizna",
-palevioletred: "bledo vijolično-rdeča",
-papayawhip: "papaja",
-peachpuff: "breskova",
-peru: "perujska",
-pink: "rožnata",
-plum: "slivova",
-powderblue: "kobaltovo modra",
-purple: "škrlatna",
-red: "rdeča",
-rosybrown: "rožnato rjava",
-royalblue: "kraljevsko modra",
-saddlebrown: "sedlasto rjava",
-salmon: "lososova",
-sandybrown: "peščeno rjava",
-seagreen: "morsko zelena",
-seashell: "morska lupina",
-sienna: "sienna",
-silver: "srebrna",
-skyblue: "nebeško modra",
-slateblue: "skrilasto modra",
-slategray: "skrilasto siva",
-slategrey: "skrilasto siva", // same as slategray
-snow: "snežena",
-springgreen: "pomladno zelena",
-steelblue: "kovinsko modra",
-tan: "rumeno-rjava",
-teal: "modrozelena",
-thistle: "osatna",
-tomato: "paradižnikova",
-transparent: "prosojno",
-turquoise: "turkizna",
-violet: "vijolična",
-wheat: "pšenična",
-white: "bela",
-whitesmoke: "megleno bela",
-yellow: "rumena",
-yellowgreen: "rumeno-zelena"
+	aliceblue: "alice blue modra",
+	antiquewhite: "antično bela",
+	aqua: "svetlo modra",
+	aquamarine: "akvamarin",
+	azure: "azurno modra",
+	beige: "bež",
+	bisque: "porcelanasta",
+	black: "črna",
+	blanchedalmond: "obledelo mandljeva",
+	blue: "modra",
+	blueviolet: "modro vijolična",
+	brown: "rjava",
+	burlywood: "peščeno sivo-rjava",
+	cadetblue: "kadetsko modra",
+	chartreuse: "chartreuse",
+	chocolate: "čokoladna",
+	coral: "koralna",
+	cornflowerblue: "plavičasto modra",
+	cornsilk: "koruzna",
+	crimson: "karminasta",
+	cyan: "cijan",
+	darkblue: "temno modra",
+	darkcyan: "temno cijan",
+	darkgoldenrod: "temna zlata rozga",
+	darkgray: "temno siva",
+	darkgreen: "temno zelena",
+	darkgrey: "temno siva", // same as darkgray
+	darkkhaki: "temno kaki",
+	darkmagenta: "temna magenta",
+	darkolivegreen: "temna olivno zelena",
+	darkorange: "temno oranžna",
+	darkorchid: "temno orhidejasta",
+	darkred: "temno rdeča",
+	darksalmon: "temno lososova",
+	darkseagreen: "temno morsko zelena",
+	darkslateblue: "temno skrilasto modra",
+	darkslategray: "temno skrilasto siva",
+	darkslategrey: "temno skrilasto siva", // same as darkslategray
+	darkturquoise: "temno turkizna",
+	darkviolet: "temno vijolična",
+	deeppink: "temno rožnata",
+	deepskyblue: "temno nebeško modra",
+	dimgray: "pepelnato siva",
+	dimgrey: "pepelnato siva", // same as dimgray
+	dodgerblue: "dodgersko modra",
+	firebrick: "opečnata",
+	floralwhite: "cvetno bela",
+	forestgreen: "gozdno zelena",
+	fuchsia: "roza",
+	gainsboro: "gainsboro",
+	ghostwhite: "senčnato bela",
+	gold: "zlata",
+	goldenrod: "zlata rozga",
+	gray: "siva",
+	green: "zelena",
+	greenyellow: "zeleno-rumena",
+	grey: "siva", // same as gray
+	honeydew: "medena rosa",
+	hotpink: "kričeče rožnata",
+	indianred: "indijansko rdeča",
+	indigo: "indigo",
+	ivory: "slonokoščena",
+	khaki: "kaki",
+	lavender: "sivka",
+	lavenderblush: "rožnato sivka",
+	lawngreen: "travniško zelena",
+	lemonchiffon: "limonast šifon",
+	lightblue: "svetlo modra",
+	lightcoral: "svetlo koralna",
+	lightcyan: "svetlo cijan",
+	lightgoldenrodyellow: "svetlo rumena zlata rozga",
+	lightgray: "svetlo siva",
+	lightgreen: "svetlo zelena",
+	lightgrey: "svetlo siva", // same as lightgray
+	lightpink: "svetlo rožnata",
+	lightsalmon: "svetlo lososova",
+	lightseagreen: "svetlo morsko zelena",
+	lightskyblue: "svetlo nebeško modra",
+	lightslategray: "svetlo skrilasto siva",
+	lightslategrey: "svetlo skrilasto siva", // same as lightslategray
+	lightsteelblue: "svetlo kovinsko modra",
+	lightyellow: "svetlo rumena",
+	lime: "svetlo zelena",
+	limegreen: "apneno zelena",
+	linen: "lanena",
+	magenta: "magenta",
+	maroon: "kostanjeva",
+	mediumaquamarine: "srednji akvamarin",
+	mediumblue: "srednje modra",
+	mediumorchid: "srednje orhidejasta",
+	mediumpurple: "srednje škrlatna",
+	mediumseagreen: "srednje morsko zelena",
+	mediumslateblue: "srednje skrilasto modra",
+	mediumspringgreen: "srednje pomladno zelena",
+	mediumturquoise: "srednje turkizna",
+	mediumvioletred: "srednje vijolično rdeča",
+	midnightblue: "polnočno modra",
+	mintcream: "metina krema",
+	mistyrose: "megleno rožnata",
+	moccasin: "mokasinasta",
+	navajowhite: "navajo bela",
+	navy: "mornarsko modra",
+	oldlace: "stara čipka",
+	olive: "olivno zelena",
+	olivedrab: "umazano olivna",
+	orange: "oranžna",
+	orangered: "oranžno-rdeča",
+	orchid: "orhidejasta",
+	palegoldenrod: "bleda zlata rozga",
+	palegreen: "bledo zelena",
+	paleturquoise: "bledo turkizna",
+	palevioletred: "bledo vijolično-rdeča",
+	papayawhip: "papaja",
+	peachpuff: "breskova",
+	peru: "perujska",
+	pink: "rožnata",
+	plum: "slivova",
+	powderblue: "kobaltovo modra",
+	purple: "škrlatna",
+	red: "rdeča",
+	rosybrown: "rožnato rjava",
+	royalblue: "kraljevsko modra",
+	saddlebrown: "sedlasto rjava",
+	salmon: "lososova",
+	sandybrown: "peščeno rjava",
+	seagreen: "morsko zelena",
+	seashell: "morska lupina",
+	sienna: "sienna",
+	silver: "srebrna",
+	skyblue: "nebeško modra",
+	slateblue: "skrilasto modra",
+	slategray: "skrilasto siva",
+	slategrey: "skrilasto siva", // same as slategray
+	snow: "snežena",
+	springgreen: "pomladno zelena",
+	steelblue: "kovinsko modra",
+	tan: "rumeno-rjava",
+	teal: "modrozelena",
+	thistle: "osatna",
+	tomato: "paradižnikova",
+	transparent: "prosojno",
+	turquoise: "turkizna",
+	violet: "vijolična",
+	wheat: "pšenična",
+	white: "bela",
+	whitesmoke: "megleno bela",
+	yellow: "rumena",
+	yellowgreen: "rumeno-zelena"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/sv/colors.js b/dojo/nls/sv/colors.js
index 3131845..6f579f4 100644
--- a/dojo/nls/sv/colors.js
+++ b/dojo/nls/sv/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "aliceblå",
-antiquewhite: "antikvitt",
-aqua: "akvamarin",
-aquamarine: "akvamarin",
-azure: "azurblått",
-beige: "beige",
-bisque: "biskvi",
-black: "svart",
-blanchedalmond: "skållad mandel",
-blue: "blått",
-blueviolet: "blåviolett",
-brown: "brunt",
-burlywood: "träfärgat",
-cadetblue: "kadettblått",
-chartreuse: "chartreuse",
-chocolate: "choklad",
-coral: "korall",
-cornflowerblue: "kornblått",
-cornsilk: "gulvitt",
-crimson: "karmosinrött",
-cyan: "cyan",
-darkblue: "mörkblått",
-darkcyan: "mörkt cyan",
-darkgoldenrod: "mörkt gullris",
-darkgray: "mörkgrått",
-darkgreen: "mörkgrönt",
-darkgrey: "mörkgrått", // same as darkgray
-darkkhaki: "mörkt kaki",
-darkmagenta: "mörk magenta",
-darkolivegreen: "mörkt olivgrönt",
-darkorange: "mörkorange",
-darkorchid: "mörkt orkidé",
-darkred: "mörkrött",
-darksalmon: "mörkt laxfärgat",
-darkseagreen: "mörkt havsgrönt",
-darkslateblue: "mörkt skifferblått",
-darkslategray: "mörkt skiffergrått",
-darkslategrey: "mörkt skiffergrått", // same as darkslategray
-darkturquoise: "mörkturkost",
-darkviolet: "mörkviolett",
-deeppink: "djuprosa",
-deepskyblue: "mörkt himmelsblått",
-dimgray: "smutsgrått",
-dimgrey: "smutsgrått", // same as dimgray
-dodgerblue: "dodgerblått",
-firebrick: "tegelstensrött",
-floralwhite: "blomvitt",
-forestgreen: "skogsgrönt",
-fuchsia: "fuchsia",
-gainsboro: "gainsboro",
-ghostwhite: "spökvitt",
-gold: "guld",
-goldenrod: "gullris",
-gray: "grått",
-green: "grönt",
-greenyellow: "gröngult",
-grey: "grått", // same as gray
-honeydew: "honungsdagg",
-hotpink: "varmrosa",
-indianred: "indianrött",
-indigo: "indigo",
-ivory: "elfenbensvitt",
-khaki: "kaki",
-lavender: "lavendel",
-lavenderblush: "lavendelskimrande",
-lawngreen: "gräsmattegrönt",
-lemonchiffon: "citronchiffong",
-lightblue: "ljusblått",
-lightcoral: "ljuskorall",
-lightcyan: "ljust cyan",
-lightgoldenrodyellow: "ljust gullrisgult",
-lightgray: "ljusgrått",
-lightgreen: "ljusgrönt",
-lightgrey: "ljusgrått", // same as lightgray
-lightpink: "ljusrosa",
-lightsalmon: "ljust laxfärgat",
-lightseagreen: "ljust havsgrönt",
-lightskyblue: "ljust himmelsblått",
-lightslategray: "ljust skiffergrått",
-lightslategrey: "ljust skiffergrått", // same as lightslategray
-lightsteelblue: "ljust stålblått",
-lightyellow: "ljusgult",
-lime: "lime",
-limegreen: "limegrönt",
-linen: "linne",
-magenta: "magenta",
-maroon: "rödbrunt",
-mediumaquamarine: "mellanakvamarin",
-mediumblue: "mellanblått",
-mediumorchid: "mellanorkidé",
-mediumpurple: "mellanlila",
-mediumseagreen: "mellanhavsgrönt",
-mediumslateblue: "mellanskifferblått",
-mediumspringgreen: "mellanvårgrönt",
-mediumturquoise: "mellanturkost",
-mediumvioletred: "mellanviolettrött",
-midnightblue: "midnattsblått",
-mintcream: "mintgrädde",
-mistyrose: "dunkelrosa",
-moccasin: "mockasin",
-navajowhite: "navajovitt",
-navy: "marinblått",
-oldlace: "spetsvitt",
-olive: "olivfärgat",
-olivedrab: "olivsmutsgult",
-orange: "orange",
-orangered: "orangerött",
-orchid: "orkidé",
-palegoldenrod: "blekt gullris",
-palegreen: "blekgrönt",
-paleturquoise: "blekturkost",
-palevioletred: "blekviolettrött",
-papayawhip: "papayaröra",
-peachpuff: "persika",
-peru: "peru",
-pink: "rosa",
-plum: "plommon",
-powderblue: "pulverblått",
-purple: "lila",
-red: "rött",
-rosybrown: "rosenbrunt",
-royalblue: "kungligt blått",
-saddlebrown: "sadelbrunt",
-salmon: "laxfärgat",
-sandybrown: "sandbrunt",
-seagreen: "havsgrönt",
-seashell: "snäckskal",
-sienna: "sienna",
-silver: "silver",
-skyblue: "himmelsblått",
-slateblue: "skifferblått",
-slategray: "skiffergrått",
-slategrey: "skiffergrått", // same as slategray
-snow: "snö",
-springgreen: "vårgrönt",
-steelblue: "stålblått",
-tan: "mellanbrunt",
-teal: "blågrönt",
-thistle: "tistel",
-tomato: "tomatrött",
-transparent: "transparent",
-turquoise: "turkost",
-violet: "violett",
-wheat: "vete",
-white: "vitt",
-whitesmoke: "vit rök",
-yellow: "gult",
-yellowgreen: "gulgrönt"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "aliceblå",
+	antiquewhite: "antikvitt",
+	aqua: "akvamarin",
+	aquamarine: "akvamarin",
+	azure: "azurblått",
+	beige: "beige",
+	bisque: "biskvi",
+	black: "svart",
+	blanchedalmond: "skållad mandel",
+	blue: "blått",
+	blueviolet: "blåviolett",
+	brown: "brunt",
+	burlywood: "träfärgat",
+	cadetblue: "kadettblått",
+	chartreuse: "chartreuse",
+	chocolate: "choklad",
+	coral: "korall",
+	cornflowerblue: "kornblått",
+	cornsilk: "gulvitt",
+	crimson: "karmosinrött",
+	cyan: "cyan",
+	darkblue: "mörkblått",
+	darkcyan: "mörkt cyan",
+	darkgoldenrod: "mörkt gullris",
+	darkgray: "mörkgrått",
+	darkgreen: "mörkgrönt",
+	darkgrey: "mörkgrått", // same as darkgray
+	darkkhaki: "mörkt kaki",
+	darkmagenta: "mörk magenta",
+	darkolivegreen: "mörkt olivgrönt",
+	darkorange: "mörkorange",
+	darkorchid: "mörkt orkidé",
+	darkred: "mörkrött",
+	darksalmon: "mörkt laxfärgat",
+	darkseagreen: "mörkt havsgrönt",
+	darkslateblue: "mörkt skifferblått",
+	darkslategray: "mörkt skiffergrått",
+	darkslategrey: "mörkt skiffergrått", // same as darkslategray
+	darkturquoise: "mörkturkost",
+	darkviolet: "mörkviolett",
+	deeppink: "djuprosa",
+	deepskyblue: "mörkt himmelsblått",
+	dimgray: "smutsgrått",
+	dimgrey: "smutsgrått", // same as dimgray
+	dodgerblue: "dodgerblått",
+	firebrick: "tegelstensrött",
+	floralwhite: "blomvitt",
+	forestgreen: "skogsgrönt",
+	fuchsia: "fuchsia",
+	gainsboro: "gainsboro",
+	ghostwhite: "spökvitt",
+	gold: "guld",
+	goldenrod: "gullris",
+	gray: "grått",
+	green: "grönt",
+	greenyellow: "gröngult",
+	grey: "grått", // same as gray
+	honeydew: "honungsdagg",
+	hotpink: "varmrosa",
+	indianred: "indianrött",
+	indigo: "indigo",
+	ivory: "elfenbensvitt",
+	khaki: "kaki",
+	lavender: "lavendel",
+	lavenderblush: "lavendelskimrande",
+	lawngreen: "gräsmattegrönt",
+	lemonchiffon: "citronchiffong",
+	lightblue: "ljusblått",
+	lightcoral: "ljuskorall",
+	lightcyan: "ljust cyan",
+	lightgoldenrodyellow: "ljust gullrisgult",
+	lightgray: "ljusgrått",
+	lightgreen: "ljusgrönt",
+	lightgrey: "ljusgrått", // same as lightgray
+	lightpink: "ljusrosa",
+	lightsalmon: "ljust laxfärgat",
+	lightseagreen: "ljust havsgrönt",
+	lightskyblue: "ljust himmelsblått",
+	lightslategray: "ljust skiffergrått",
+	lightslategrey: "ljust skiffergrått", // same as lightslategray
+	lightsteelblue: "ljust stålblått",
+	lightyellow: "ljusgult",
+	lime: "lime",
+	limegreen: "limegrönt",
+	linen: "linne",
+	magenta: "magenta",
+	maroon: "rödbrunt",
+	mediumaquamarine: "mellanakvamarin",
+	mediumblue: "mellanblått",
+	mediumorchid: "mellanorkidé",
+	mediumpurple: "mellanlila",
+	mediumseagreen: "mellanhavsgrönt",
+	mediumslateblue: "mellanskifferblått",
+	mediumspringgreen: "mellanvårgrönt",
+	mediumturquoise: "mellanturkost",
+	mediumvioletred: "mellanviolettrött",
+	midnightblue: "midnattsblått",
+	mintcream: "mintgrädde",
+	mistyrose: "dunkelrosa",
+	moccasin: "mockasin",
+	navajowhite: "navajovitt",
+	navy: "marinblått",
+	oldlace: "spetsvitt",
+	olive: "olivfärgat",
+	olivedrab: "olivsmutsgult",
+	orange: "orange",
+	orangered: "orangerött",
+	orchid: "orkidé",
+	palegoldenrod: "blekt gullris",
+	palegreen: "blekgrönt",
+	paleturquoise: "blekturkost",
+	palevioletred: "blekviolettrött",
+	papayawhip: "papayaröra",
+	peachpuff: "persika",
+	peru: "peru",
+	pink: "rosa",
+	plum: "plommon",
+	powderblue: "pulverblått",
+	purple: "lila",
+	red: "rött",
+	rosybrown: "rosenbrunt",
+	royalblue: "kungligt blått",
+	saddlebrown: "sadelbrunt",
+	salmon: "laxfärgat",
+	sandybrown: "sandbrunt",
+	seagreen: "havsgrönt",
+	seashell: "snäckskal",
+	sienna: "sienna",
+	silver: "silver",
+	skyblue: "himmelsblått",
+	slateblue: "skifferblått",
+	slategray: "skiffergrått",
+	slategrey: "skiffergrått", // same as slategray
+	snow: "snö",
+	springgreen: "vårgrönt",
+	steelblue: "stålblått",
+	tan: "mellanbrunt",
+	teal: "blågrönt",
+	thistle: "tistel",
+	tomato: "tomatrött",
+	transparent: "transparent",
+	turquoise: "turkost",
+	violet: "violett",
+	wheat: "vete",
+	white: "vitt",
+	whitesmoke: "vit rök",
+	yellow: "gult",
+	yellowgreen: "gulgrönt"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/th/colors.js b/dojo/nls/th/colors.js
index 314f41d..5d132d8 100644
--- a/dojo/nls/th/colors.js
+++ b/dojo/nls/th/colors.js
@@ -1,160 +1,157 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "alice blue",
-antiquewhite: "antique white",
+aliceblue: "ฟ้าจาง",
+antiquewhite: "สีเนื้อ",
 aqua: "ฟ้าน้ำทะเล",
-aquamarine: "aquamarine",
+aquamarine: "อะความารีน",
 azure: "น้ำเงินฟ้า",
 beige: "น้ำตาลเบจ",
-bisque: "bisque",
+bisque: "ขาวข้าวสาร",
 black: "ดำ",
-blanchedalmond: "blanched almond",
+blanchedalmond: "เนื้ออ่อน",
 blue: "น้ำเงิน",
 blueviolet: "น้ำเงินม่วง",
 brown: "น้ำตาล",
-burlywood: "burlywood",
-cadetblue: "cadet blue",
-chartreuse: "chartreuse",
+burlywood: "น้ำตาลอ่อน",
+cadetblue: "เขียวน้ำเงินหม่น",
+chartreuse: "เขียวสะท้อนแสง",
 chocolate: "ช็อกโกแลต",
-coral: "coral",
-cornflowerblue: "cornflower blue",
+coral: "แสดเข้มนวล",
+cornflowerblue: "สีคอร์นฟลาวเวอร์บลู",
 cornsilk: "cornsilk",
 crimson: "แดงเลือดหมู",
 cyan: "เขียวแกมน้ำเงิน",
 darkblue: "น้ำเงินเข้ม",
 darkcyan: "เขียวแกมน้ำเงินเข้ม",
-darkgoldenrod: "dark goldenrod",
+darkgoldenrod: "ทองเหลืองเข้ม",
 darkgray: "เทาเข้ม",
 darkgreen: "เขียวเข้ม",
 darkgrey: "เทาเข้ม", // same as darkgray
-darkkhaki: "dark khaki",
+darkkhaki: "กากีเข้ม",
 darkmagenta: "แดงแกมม่วงเข้ม",
 darkolivegreen: "เขียวโอลีฟเข้ม",
 darkorange: "ส้มเข้ม",
-darkorchid: "dark orchid",
+darkorchid: "สีม่วงกล้วยไม้เข้ม",
 darkred: "แดงเข้ม",
-darksalmon: "dark salmon",
-darkseagreen: "dark sea green",
-darkslateblue: "dark slate blue",
-darkslategray: "dark slate gray",
-darkslategrey: "dark slate gray", // same as darkslategray
-darkturquoise: "dark turquoise",
+darksalmon: "ส้มเข้ม",
+darkseagreen: "เขียวทะเลเข้ม",
+darkslateblue: "น้ำเงินนวลเข้ม",
+darkslategray: "เทานวลเข้ม",
+darkslategrey: "เทานวลเข้ม", // same as darkslategray
+darkturquoise: "ฟ้าขี้นกการเวกเข้ม",
 darkviolet: "ม่วงเข้ม",
 deeppink: "ชมพูเข้ม",
-deepskyblue: "deep sky blue",
-dimgray: "dim gray",
-dimgrey: "dim gray", // same as dimgray
-dodgerblue: "dodger blue",
+deepskyblue: "ฟ้าสด",
+dimgray: "เทาทึม",
+dimgrey: "เทาทึม", // same as dimgray
+dodgerblue: "ฟ้าสะท้อนแสง",
 firebrick: "สีอิฐ",
-floralwhite: "floral white",
-forestgreen: "forest green",
-fuchsia: "fuchsia",
-gainsboro: "gainsboro",
-ghostwhite: "ghost white",
+floralwhite: "ขาวแกมชมพู",
+forestgreen: "หยก",
+fuchsia: "บานเย็น",
+gainsboro: "เทานวล",
+ghostwhite: "น้ำข้าว",
 gold: "ทอง",
-goldenrod: "goldenrod",
+goldenrod: "ทองเหลือง",
 gray: "เทา",
 green: "เขียว",
 greenyellow: "เขียวแกมเหลือง",
 grey: "เทา", // same as gray
-honeydew: "honeydew",
-hotpink: "hot pink",
-indianred: "indian red",
-indigo: "indigo",
+honeydew: "ขาวแกมเขียว",
+hotpink: "ชมพูจัด",
+indianred: "แดงอมเหลือง",
+indigo: "คราม",
 ivory: "งาช้าง",
-khaki: "khaki",
+khaki: "กากี",
 lavender: "ม่วงลาเวนเดอร์",
-lavenderblush: "lavender blush",
-lawngreen: "lawn green",
+lavenderblush: "นมเย็น",
+lawngreen: "เขียวหญ้าอ่อน",
 lemonchiffon: "lemon chiffon",
 lightblue: "น้ำเงินอ่อน",
-lightcoral: "light coral",
+lightcoral: "ชมพูอมแดง",
 lightcyan: "เขียวแกมน้ำเงินอ่อน",
-lightgoldenrodyellow: "light goldenrod yellow",
+lightgoldenrodyellow: "ทองเหลืองอ่อน",
 lightgray: "เทาอ่อน",
 lightgreen: "เขียวอ่อน",
 lightgrey: "เทาอ่อน", // same as lightgray
 lightpink: "ชมพูอ่อน",
-lightsalmon: "light salmon",
-lightseagreen: "light sea green",
+lightsalmon: "ส้มจาง",
+lightseagreen: "เขียวทะเลอ่อน",
 lightskyblue: "ฟ้าอ่อน",
-lightslategray: "light slate gray",
-lightslategrey: "light slate gray", // same as lightslategray
-lightsteelblue: "light steel blue",
+lightslategray: "เทานวลอ่อน",
+lightslategrey: "เทานวลอ่อน", // same as lightslategray
+lightsteelblue: "น้ำเงินนวลอ่อน",
 lightyellow: "เหลืองอ่อน",
 lime: "เหลืองมะนาว",
 limegreen: "เขียวมะนาว",
-linen: "linen",
+linen: "ลินนิน",
 magenta: "แดงแกมม่วง",
 maroon: "น้ำตาลแดง",
-mediumaquamarine: "medium aquamarine",
-mediumblue: "medium blue",
-mediumorchid: "medium orchid",
-mediumpurple: "medium purple",
-mediumseagreen: "medium sea green",
-mediumslateblue: "medium slate blue",
-mediumspringgreen: "medium spring green",
-mediumturquoise: "medium turquoise",
-mediumvioletred: "medium violet-red",
-midnightblue: "midnight blue",
-mintcream: "mint cream",
-mistyrose: "misty rose",
+mediumaquamarine: "อะความารีนกลางๆ",
+mediumblue: "น้ำเงินกลางๆ",
+mediumorchid: "ม่วงกล้วยไม้กลางๆ",
+mediumpurple: "ม่วงอัญชัญ",
+mediumseagreen: " เขียวทะเลกลางๆ",
+mediumslateblue: "น้ำเงินนวลกลางๆ",
+mediumspringgreen: "สีเขียวนวลกลางๆ",
+mediumturquoise: "ฟ้าขี้นกการเวกกลางๆ",
+mediumvioletred: "แดงอมม่วงกลางๆ",
+midnightblue: "น้ำเงินทึบ",
+mintcream: "ขาวกะทิ",
+mistyrose: "ชมพูหม่น",
 moccasin: "ม็อคค่า",
-navajowhite: "navajo white",
+navajowhite: "ส้มหนังกลับ",
 navy: "น้ำเงินเข้ม",
-oldlace: "old lace",
+oldlace: "ขาวนวล",
 olive: "โอลีฟ",
-olivedrab: "olive drab",
+olivedrab: "เขียวมะกอกแก่",
 orange: "ส้ม",
 orangered: "ส้มแกมแดง",
-orchid: "orchid",
-palegoldenrod: "pale goldenrod",
-palegreen: "pale green",
-paleturquoise: "pale turquoise",
-palevioletred: "pale violet-red",
-papayawhip: "papaya whip",
-peachpuff: "peach puff",
-peru: "peru",
+orchid: "สีกล้วยไม้",
+palegoldenrod: "ทองเหลืองจาง",
+palegreen: "เขียวจาง",
+paleturquoise: "ฟ้าขี้นกการเวกจาง",
+palevioletred: "แดงอมม่วงจาง",
+papayawhip: "ชมพูจาง",
+peachpuff: " สีพีช",
+peru: "ส้มดินเผา",
 pink: "ชมพู",
-plum: "plum",
-powderblue: "powder blue",
+plum: "ม่วงอ่อน",
+powderblue: "ฟ้าหม่น",
 purple: "ม่วง",
 red: "แดง",
-rosybrown: "rosy brown",
-royalblue: "royal blue",
-saddlebrown: "saddle brown",
-salmon: "salmon",
-sandybrown: "sandy brown",
-seagreen: "sea green",
-seashell: "seashell",
-sienna: "sienna",
+rosybrown: "กะปิ",
+royalblue: "น้ำเงินเข้ม",
+saddlebrown: "น้ำตาล",
+salmon: "ส้มอ่อน",
+sandybrown: "น้ำตาลลูกรัง",
+seagreen: "เขียวทะเล",
+seashell: "สีขาวหอยทะเล",
+sienna: "น้ำตาลอมแดง",
 silver: "เงิน",
-skyblue: "sky blue",
-slateblue: "slate blue",
-slategray: "slate gray",
-slategrey: "slate gray", // same as slategray
-snow: "snow",
-springgreen: "spring green",
-steelblue: "steel blue",
-tan: "tan",
-teal: "teal",
-thistle: "thistle",
-tomato: "tomato",
+skyblue: "ฟ้า",
+slateblue: "น้ำเงินนวล",
+slategray: "เทาอมน้ำเงินนวล",
+slategrey: "เทาอมน้ำเงินนวล", // same as slategray
+snow: "ขาวหิมะ",
+springgreen: "เขียว",
+steelblue: "น้ำเงินด้าน",
+tan: "แทน",
+teal: "เขียวหัวเป็ด",
+thistle: "ม่วงจาง",
+tomato: "แสด",
 transparent: "สีใส",
-turquoise: "turquoise",
+turquoise: "ฟ้าขี้นกการเวก",
 violet: "ม่วง",
-wheat: "wheat",
+wheat: "เหลืองรำข้าว",
 white: "ขาว",
 whitesmoke: "ขาวควัน",
 yellow: "เหลือง",
 yellowgreen: "เหลืองแกมเขียว"
 })
-
-//end v1.x content
 );
diff --git a/dojo/nls/tr/colors.js b/dojo/nls/tr/colors.js
index 27df167..4cc5e2f 100644
--- a/dojo/nls/tr/colors.js
+++ b/dojo/nls/tr/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "alice mavisi",
-antiquewhite: "antik beyaz",
-aqua: "deniz mavisi",
-aquamarine: "akuamarin",
-azure: "azur mavisi",
-beige: "bej",
-bisque: "bisküvi",
-black: "siyah",
-blanchedalmond: "soluk badem",
-blue: "mavi",
-blueviolet: "mavi-mor",
-brown: "kahverengi",
-burlywood: "sarımsı kahverengi",
-cadetblue: "denizci mavisi",
-chartreuse: "chartreuse",
-chocolate: "çikolata",
-coral: "mercan",
-cornflowerblue: "peygamber çiçeği mavisi",
-cornsilk: "mısır rengi",
-crimson: "crimson",
-cyan: "camgöbeği",
-darkblue: "koyu mavi",
-darkcyan: "koyu camgöbeği",
-darkgoldenrod: "koyu sarı",
-darkgray: "koyu gri",
-darkgreen: "koyu yeşil",
-darkgrey: "koyu gri", // same as darkgray
-darkkhaki: "koyu haki",
-darkmagenta: "koyu mor",
-darkolivegreen: "koyu zeytin yeşili",
-darkorange: "koyu turuncu",
-darkorchid: "koyu orkide",
-darkred: "koyu kırmızı",
-darksalmon: "koyu somon",
-darkseagreen: "koyu deniz yeşili",
-darkslateblue: "koyu arduvaz mavisi",
-darkslategray: "koyu arduvaz grisi",
-darkslategrey: "koyu arduvaz grisi", // same as darkslategray
-darkturquoise: "koyu turkuaz",
-darkviolet: "koyu eflatun",
-deeppink: "koyu pembe",
-deepskyblue: "koyu gök mavisi",
-dimgray: "soluk gri",
-dimgrey: "soluk gri", // same as dimgray
-dodgerblue: "toz mavisi",
-firebrick: "canlı kiremit",
-floralwhite: "çiçek beyazı",
-forestgreen: "koyu deniz yeşili",
-fuchsia: "fuşya",
-gainsboro: "gainsboro",
-ghostwhite: "silik beyaz",
-gold: "altın",
-goldenrod: "sarısabır",
-gray: "gri",
-green: "yeşil",
-greenyellow: "yeşil-sarı",
-grey: "gri", // same as gray
-honeydew: "çam sakızı",
-hotpink: "sıcak pembe",
-indianred: "kızılderili kırmızısı",
-indigo: "çivit mavisi",
-ivory: "fildişi",
-khaki: "haki",
-lavender: "lavanta",
-lavenderblush: "lavanta pembesi",
-lawngreen: "çimen yeşili",
-lemonchiffon: "limoni",
-lightblue: "açık mavi",
-lightcoral: "açık mercan",
-lightcyan: "açık camgöbeği",
-lightgoldenrodyellow: "açık sarısabır",
-lightgray: "açık gri",
-lightgreen: "açık yeşil",
-lightgrey: "açık gri", // same as lightgray
-lightpink: "açık pembe",
-lightsalmon: "açık somon",
-lightseagreen: "açık deniz yeşili",
-lightskyblue: "açık gök mavisi",
-lightslategray: "açık arduvaz grisi",
-lightslategrey: "açık arduvaz grisi", // same as lightslategray
-lightsteelblue: "açık metalik mavi",
-lightyellow: "açık sarı",
-lime: "limon yeşili",
-limegreen: "küf yeşili",
-linen: "keten",
-magenta: "macenta",
-maroon: "kestane",
-mediumaquamarine: "orta akuamarin",
-mediumblue: "orta mavi",
-mediumorchid: "orta orkide",
-mediumpurple: "orta mor",
-mediumseagreen: "orta deniz yeşili",
-mediumslateblue: "orta arduvaz mavisi",
-mediumspringgreen: "orta bahar yeşili",
-mediumturquoise: "orta turkuaz",
-mediumvioletred: "orta menekşe kırmızısı",
-midnightblue: "gece mavisi",
-mintcream: "naneli krem",
-mistyrose: "gülkurusu",
-moccasin: "mokosen",
-navajowhite: "navajo beyazı",
-navy: "lacivert",
-oldlace: "eski dantel",
-olive: "zeytin",
-olivedrab: "asker yeşili",
-orange: "turuncu",
-orangered: "turuncu kırmızı",
-orchid: "orkide",
-palegoldenrod: "soluk sarısabır",
-palegreen: "soluk yeşil",
-paleturquoise: "soluk turkuaz",
-palevioletred: "soluk menekşe kırmızısı",
-papayawhip: "papaya sapı",
-peachpuff: "açık şeftali",
-peru: "peru",
-pink: "pembe",
-plum: "erik",
-powderblue: "pudra mavisi",
-purple: "mor",
-red: "kırmızı",
-rosybrown: "pembemsi kahverengi",
-royalblue: "parlak koyu mavi",
-saddlebrown: "açık kahve",
-salmon: "somon",
-sandybrown: "kum rengi",
-seagreen: "deniz yeşili",
-seashell: "deniz kabuğu",
-sienna: "koyu kahve",
-silver: "gümüş",
-skyblue: "gök mavisi",
-slateblue: "arduvaz mavisi",
-slategray: "arduvaz grisi",
-slategrey: "arduvaz grisi", // same as slategray
-snow: "kar",
-springgreen: "bahar yeşili",
-steelblue: "metalik mavi",
-tan: "güneş yanığı",
-teal: "Teal mavi",
-thistle: "devedikeni",
-tomato: "domates",
-transparent: "saydam",
-turquoise: "turkuaz",
-violet: "eflatun",
-wheat: "buğday",
-white: "beyaz",
-whitesmoke: "beyaz duman",
-yellow: "sarı",
-yellowgreen: "sarı yeşil"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "alice mavisi",
+	antiquewhite: "antik beyaz",
+	aqua: "deniz mavisi",
+	aquamarine: "akuamarin",
+	azure: "azur mavisi",
+	beige: "bej",
+	bisque: "bisküvi",
+	black: "siyah",
+	blanchedalmond: "soluk badem",
+	blue: "mavi",
+	blueviolet: "mavi-mor",
+	brown: "kahverengi",
+	burlywood: "sarımsı kahverengi",
+	cadetblue: "denizci mavisi",
+	chartreuse: "chartreuse",
+	chocolate: "çikolata",
+	coral: "mercan",
+	cornflowerblue: "peygamber çiçeği mavisi",
+	cornsilk: "mısır rengi",
+	crimson: "crimson",
+	cyan: "camgöbeği",
+	darkblue: "koyu mavi",
+	darkcyan: "koyu camgöbeği",
+	darkgoldenrod: "koyu sarı",
+	darkgray: "koyu gri",
+	darkgreen: "koyu yeşil",
+	darkgrey: "koyu gri", // same as darkgray
+	darkkhaki: "koyu haki",
+	darkmagenta: "koyu mor",
+	darkolivegreen: "koyu zeytin yeşili",
+	darkorange: "koyu turuncu",
+	darkorchid: "koyu orkide",
+	darkred: "koyu kırmızı",
+	darksalmon: "koyu somon",
+	darkseagreen: "koyu deniz yeşili",
+	darkslateblue: "koyu arduvaz mavisi",
+	darkslategray: "koyu arduvaz grisi",
+	darkslategrey: "koyu arduvaz grisi", // same as darkslategray
+	darkturquoise: "koyu turkuaz",
+	darkviolet: "koyu eflatun",
+	deeppink: "koyu pembe",
+	deepskyblue: "koyu gök mavisi",
+	dimgray: "soluk gri",
+	dimgrey: "soluk gri", // same as dimgray
+	dodgerblue: "toz mavisi",
+	firebrick: "canlı kiremit",
+	floralwhite: "çiçek beyazı",
+	forestgreen: "koyu deniz yeşili",
+	fuchsia: "fuşya",
+	gainsboro: "gainsboro",
+	ghostwhite: "silik beyaz",
+	gold: "altın",
+	goldenrod: "sarısabır",
+	gray: "gri",
+	green: "yeşil",
+	greenyellow: "yeşil-sarı",
+	grey: "gri", // same as gray
+	honeydew: "çam sakızı",
+	hotpink: "sıcak pembe",
+	indianred: "kızılderili kırmızısı",
+	indigo: "çivit mavisi",
+	ivory: "fildişi",
+	khaki: "haki",
+	lavender: "lavanta",
+	lavenderblush: "lavanta pembesi",
+	lawngreen: "çimen yeşili",
+	lemonchiffon: "limoni",
+	lightblue: "açık mavi",
+	lightcoral: "açık mercan",
+	lightcyan: "açık camgöbeği",
+	lightgoldenrodyellow: "açık sarısabır",
+	lightgray: "açık gri",
+	lightgreen: "açık yeşil",
+	lightgrey: "açık gri", // same as lightgray
+	lightpink: "açık pembe",
+	lightsalmon: "açık somon",
+	lightseagreen: "açık deniz yeşili",
+	lightskyblue: "açık gök mavisi",
+	lightslategray: "açık arduvaz grisi",
+	lightslategrey: "açık arduvaz grisi", // same as lightslategray
+	lightsteelblue: "açık metalik mavi",
+	lightyellow: "açık sarı",
+	lime: "limon yeşili",
+	limegreen: "küf yeşili",
+	linen: "keten",
+	magenta: "macenta",
+	maroon: "kestane",
+	mediumaquamarine: "orta akuamarin",
+	mediumblue: "orta mavi",
+	mediumorchid: "orta orkide",
+	mediumpurple: "orta mor",
+	mediumseagreen: "orta deniz yeşili",
+	mediumslateblue: "orta arduvaz mavisi",
+	mediumspringgreen: "orta bahar yeşili",
+	mediumturquoise: "orta turkuaz",
+	mediumvioletred: "orta menekşe kırmızısı",
+	midnightblue: "gece mavisi",
+	mintcream: "naneli krem",
+	mistyrose: "gülkurusu",
+	moccasin: "mokosen",
+	navajowhite: "navajo beyazı",
+	navy: "lacivert",
+	oldlace: "eski dantel",
+	olive: "zeytin",
+	olivedrab: "asker yeşili",
+	orange: "turuncu",
+	orangered: "turuncu kırmızı",
+	orchid: "orkide",
+	palegoldenrod: "soluk sarısabır",
+	palegreen: "soluk yeşil",
+	paleturquoise: "soluk turkuaz",
+	palevioletred: "soluk menekşe kırmızısı",
+	papayawhip: "papaya sapı",
+	peachpuff: "açık şeftali",
+	peru: "peru",
+	pink: "pembe",
+	plum: "erik",
+	powderblue: "pudra mavisi",
+	purple: "mor",
+	red: "kırmızı",
+	rosybrown: "pembemsi kahverengi",
+	royalblue: "parlak koyu mavi",
+	saddlebrown: "açık kahve",
+	salmon: "somon",
+	sandybrown: "kum rengi",
+	seagreen: "deniz yeşili",
+	seashell: "deniz kabuğu",
+	sienna: "koyu kahve",
+	silver: "gümüş",
+	skyblue: "gök mavisi",
+	slateblue: "arduvaz mavisi",
+	slategray: "arduvaz grisi",
+	slategrey: "arduvaz grisi", // same as slategray
+	snow: "kar",
+	springgreen: "bahar yeşili",
+	steelblue: "metalik mavi",
+	tan: "güneş yanığı",
+	teal: "Teal mavi",
+	thistle: "devedikeni",
+	tomato: "domates",
+	transparent: "saydam",
+	turquoise: "turkuaz",
+	violet: "eflatun",
+	wheat: "buğday",
+	white: "beyaz",
+	whitesmoke: "beyaz duman",
+	yellow: "sarı",
+	yellowgreen: "sarı yeşil"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/uk/colors.js b/dojo/nls/uk/colors.js
new file mode 100644
index 0000000..2e89e7c
--- /dev/null
+++ b/dojo/nls/uk/colors.js
@@ -0,0 +1,156 @@
+define(
+({
+// local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
+// is required for each color, such as a palette widget, and not for specifying color programatically.
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "сіро-блакитний",
+	antiquewhite: "білий антик",
+	aqua: "зеленувато-блакитний",
+	aquamarine: "аквамарин",
+	azure: "лазурний",
+	beige: "бежевий",
+	bisque: "кремовий",
+	black: "чорний",
+	blanchedalmond: "світло-мигдалевий",
+	blue: "блакитний",
+	blueviolet: "блакитно-фіолетовий",
+	brown: "брунатний",
+	burlywood: "світло-брунатний",
+	cadetblue: "сіро-синій",
+	chartreuse: "жовто-салатовий",
+	chocolate: "шоколадний",
+	coral: "коралевий",
+	cornflowerblue: "фіолетово-синій",
+	cornsilk: "шовковий відтінок",
+	crimson: "малиновий",
+	cyan: "синій",
+	darkblue: "темно-блакитний",
+	darkcyan: "темно-синій",
+	darkgoldenrod: "темно-золотавий",
+	darkgray: "темно-сірий",
+	darkgreen: "темно-зелений",
+	darkgrey: "темно-сірий", // same as darkgray
+	darkkhaki: "темний хакі",
+	darkmagenta: "темно-пурпуровий",
+	darkolivegreen: "темно-оливковий",
+	darkorange: "темно-жовтогарячий",
+	darkorchid: "темний орсель",
+	darkred: "темно-червоний",
+	darksalmon: "темно-лососевий",
+	darkseagreen: "темний колір морської хвилі",
+	darkslateblue: "темний грифельно-синій",
+	darkslategray: "темний грифельно-сірий",
+	darkslategrey: "темний грифельно-сірий", // same as darkslategray
+	darkturquoise: "темно-бірюзовий",
+	darkviolet: "темно-фіолетовий",
+	deeppink: "темно-рожевий",
+	deepskyblue: "насичений світло-блакитний",
+	dimgray: "тьмяно-сірий",
+	dimgrey: "тьмяно-сірий", // same as dimgray
+	dodgerblue: "блідо-блакитний",
+	firebrick: "цеглястий",
+	floralwhite: "квітково-білий",
+	forestgreen: "зелений лісний",
+	fuchsia: "фуксин",
+	gainsboro: "блідо-сірий",
+	ghostwhite: "молочно-білий",
+	gold: "золотий",
+	goldenrod: "золотавий",
+	gray: "сірий",
+	green: "зелений",
+	greenyellow: "зелено-жовтий",
+	grey: "сірий", // same as gray
+	honeydew: "медовий",
+	hotpink: "червоно-рожевий",
+	indianred: "індійський червоний",
+	indigo: "індиго",
+	ivory: "слонової кістки",
+	khaki: "хакі",
+	lavender: "лавандовий",
+	lavenderblush: "рожево-лавандовий",
+	lawngreen: "трав'янистий",
+	lemonchiffon: "блідо-лимонний",
+	lightblue: "світло-блакитний",
+	lightcoral: "світло-коралевий",
+	lightcyan: "світло-синій",
+	lightgoldenrodyellow: "світло-золотаво-жовтий",
+	lightgray: "світло-сірий",
+	lightgreen: "світло-зелений",
+	lightgrey: "світло-сірий", // same as lightgray
+	lightpink: "світло-рожевий",
+	lightsalmon: "світло-лососевий",
+	lightseagreen: "світлий морської хвилі",
+	lightskyblue: "світлий небесно-блакитний",
+	lightslategray: "світлий грифельно-сірий",
+	lightslategrey: "світлий грифельно-сірий", // same as lightslategray
+	lightsteelblue: "світлий сталевий",
+	lightyellow: "світло-жовтий",
+	lime: "лайм",
+	limegreen: "зелений лайм",
+	linen: "лляний",
+	magenta: "пурпурний",
+	maroon: "темно-брунатний",
+	mediumaquamarine: "нейтральний аквамарин",
+	mediumblue: "нейтральний блакитний",
+	mediumorchid: "нейтральний орсель",
+	mediumpurple: "нейтральний фіолетовий",
+	mediumseagreen: "нейтральний морської хвилі",
+	mediumslateblue: "нейтральний грифельно-синій",
+	mediumspringgreen: "нейтральний весняний зелений",
+	mediumturquoise: "нейтральний бірюзовий",
+	mediumvioletred: "нейтральний фіолетово-червоний",
+	midnightblue: "північно-синій",
+	mintcream: "м'ятно-кремовий",
+	mistyrose: "тьмяно-рожевий",
+	moccasin: "болотний",
+	navajowhite: "білий навахо",
+	navy: "темно-синій",
+	oldlace: "матово-білий",
+	olive: "оливковий",
+	olivedrab: "оливково-сірий",
+	orange: "жовтогарячий",
+	orangered: "жовтогаряче-червоний",
+	orchid: "світло-бузковий",
+	palegoldenrod: "блідо-золотавий",
+	palegreen: "блідо-зелений",
+	paleturquoise: "блідо-бірюзовий",
+	palevioletred: "блідо-фіолетово-червоний",
+	papayawhip: "динне дерево",
+	peachpuff: "персиковий",
+	peru: "перу",
+	pink: "рожевий",
+	plum: "сливовий",
+	powderblue: "зеленувато-блакитний",
+	purple: "фіолетовий",
+	red: "червоний",
+	rosybrown: "рожево-брунатний",
+	royalblue: "королевський блакитний",
+	saddlebrown: "шкіряно-брунатний",
+	salmon: "лососевий",
+	sandybrown: "брунатно-пісочний",
+	seagreen: "морської хвилі",
+	seashell: "морська скойка",
+	sienna: "охра",
+	silver: "сріблястий",
+	skyblue: "небесно-блакитний",
+	slateblue: "грифельно-синій",
+	slategray: "грифельно-сірий",
+	slategrey: "грифельно-сірий", // same as slategray
+	snow: "білосніжний",
+	springgreen: "весняний зелений",
+	steelblue: "сталевий",
+	tan: "бронзовий",
+	teal: "темно-бірюзовий",
+	thistle: "будяк",
+	tomato: "томатний",
+	transparent: "прозорий",
+	turquoise: "бірюзовий",
+	violet: "фіолетовий",
+	wheat: "пшениця",
+	white: "білий",
+	whitesmoke: "попелясто-білий",
+	yellow: "жовтий",
+	yellowgreen: "жовто-зелений"
+})
+);
diff --git a/dojo/nls/zh-tw/colors.js b/dojo/nls/zh-tw/colors.js
index 61f2f6f..e44a741 100644
--- a/dojo/nls/zh-tw/colors.js
+++ b/dojo/nls/zh-tw/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "愛麗絲藍",
-antiquewhite: "米白色",
-aqua: "水色",
-aquamarine: "碧綠色",
-azure: "天藍色",
-beige: "灰棕色",
-bisque: "橘黃色",
-black: "黑色",
-blanchedalmond: "杏仁白",
-blue: "藍色",
-blueviolet: "藍紫色",
-brown: "褐色",
-burlywood: "實木色",
-cadetblue: "軍服藍",
-chartreuse: "淡黃綠色",
-chocolate: "巧克力色",
-coral: "珊瑚紅",
-cornflowerblue: "矢車菊藍",
-cornsilk: "玉米黃",
-crimson: "暗深紅色",
-cyan: "青色",
-darkblue: "暗藍色",
-darkcyan: "暗青色",
-darkgoldenrod: "暗金菊色",
-darkgray: "暗灰色",
-darkgreen: "暗綠色",
-darkgrey: "暗灰色", // same as darkgray
-darkkhaki: "暗卡其色",
-darkmagenta: "暗紫紅色",
-darkolivegreen: "暗橄欖綠",
-darkorange: "暗橙色",
-darkorchid: "暗蘭花色",
-darkred: "暗紅色",
-darksalmon: "暗鮭紅",
-darkseagreen: "暗海綠色",
-darkslateblue: "暗岩藍色",
-darkslategray: "暗岩灰色",
-darkslategrey: "暗岩灰色", // same as darkslategray
-darkturquoise: "暗松石綠",
-darkviolet: "暗紫羅蘭色",
-deeppink: "深粉紅色",
-deepskyblue: "深天藍色",
-dimgray: "昏灰色",
-dimgrey: "昏灰色", // same as dimgray
-dodgerblue: "道奇藍",
-firebrick: "紅磚色",
-floralwhite: "花卉白",
-forestgreen: "森綠色",
-fuchsia: "海棠紅",
-gainsboro: "石板灰",
-ghostwhite: "幽靈色",
-gold: "金色",
-goldenrod: "金菊色",
-gray: "灰色",
-green: "綠色",
-greenyellow: "綠黃色",
-grey: "灰色", // same as gray
-honeydew: "密瓜色",
-hotpink: "暖粉紅色",
-indianred: "印度紅",
-indigo: "靛藍色",
-ivory: "象牙色",
-khaki: "卡其色",
-lavender: "薰衣草紫",
-lavenderblush: "薰衣草紫紅",
-lawngreen: "草綠色",
-lemonchiffon: "奶油黃",
-lightblue: "淡藍色",
-lightcoral: "淡珊瑚紅",
-lightcyan: "淡青色",
-lightgoldenrodyellow: "淡金菊黃",
-lightgray: "淡灰色",
-lightgreen: "淡綠色",
-lightgrey: "淡灰色", // same as lightgray
-lightpink: "淡粉紅色",
-lightsalmon: "淡鮭紅",
-lightseagreen: "淡海綠色",
-lightskyblue: "淡天藍色",
-lightslategray: "淡岩灰色",
-lightslategrey: "淡岩灰色", // same as lightslategray
-lightsteelblue: "淡鐵藍色",
-lightyellow: "淡黃色",
-lime: "檸檬色",
-limegreen: "檸檬綠",
-linen: "亞麻色",
-magenta: "紫紅色",
-maroon: "栗色",
-mediumaquamarine: "中碧綠色",
-mediumblue: "中藍色",
-mediumorchid: "中蘭紫色",
-mediumpurple: "中紫色",
-mediumseagreen: "中海綠色",
-mediumslateblue: "中岩藍色",
-mediumspringgreen: "中春綠色",
-mediumturquoise: "中松石綠",
-mediumvioletred: "中紫羅蘭紅",
-midnightblue: "午夜藍",
-mintcream: "薄荷乳白色",
-mistyrose: "霧玫瑰色",
-moccasin: "鹿皮黃色",
-navajowhite: "印地安黃色",
-navy: "海軍藍",
-oldlace: "舊蕾絲色",
-olive: "橄欖色",
-olivedrab: "橄欖綠",
-orange: "橙色",
-orangered: "橙紅色",
-orchid: "蘭花色",
-palegoldenrod: "灰金菊色",
-palegreen: "灰綠色",
-paleturquoise: "灰松石綠",
-palevioletred: "灰紫羅蘭紅",
-papayawhip: "番木瓜色",
-peachpuff: "粉撲桃色",
-peru: "祕魯色",
-pink: "粉紅色",
-plum: "李紫色",
-powderblue: "粉藍色",
-purple: "紫色",
-red: "紅色",
-rosybrown: "玫瑰褐",
-royalblue: "品藍色",
-saddlebrown: "鞍褐色",
-salmon: "鮭紅色",
-sandybrown: "沙褐色",
-seagreen: "海綠色",
-seashell: "海貝色",
-sienna: "黃土赭色",
-silver: "銀色",
-skyblue: "天藍色",
-slateblue: "岩藍色",
-slategray: "岩灰色",
-slategrey: "岩灰色", // same as slategray
-snow: "雪白色",
-springgreen: "春綠色",
-steelblue: "鐵藍色",
-tan: "皮革色",
-teal: "深藍綠色",
-thistle: "薊色",
-tomato: "蕃茄紅",
-transparent: "透明",
-turquoise: "松石綠",
-violet: "紫羅蘭色",
-wheat: "小麥色",
-white: "白色",
-whitesmoke: "白煙色",
-yellow: "黃色",
-yellowgreen: "黃綠色"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "愛麗絲藍",
+	antiquewhite: "米白色",
+	aqua: "水色",
+	aquamarine: "碧綠色",
+	azure: "天藍色",
+	beige: "灰棕色",
+	bisque: "橘黃色",
+	black: "黑色",
+	blanchedalmond: "杏仁白",
+	blue: "藍色",
+	blueviolet: "藍紫色",
+	brown: "褐色",
+	burlywood: "實木色",
+	cadetblue: "軍服藍",
+	chartreuse: "淡黃綠色",
+	chocolate: "巧克力色",
+	coral: "珊瑚紅",
+	cornflowerblue: "矢車菊藍",
+	cornsilk: "玉米黃",
+	crimson: "暗深紅色",
+	cyan: "青色",
+	darkblue: "暗藍色",
+	darkcyan: "暗青色",
+	darkgoldenrod: "暗金菊色",
+	darkgray: "暗灰色",
+	darkgreen: "暗綠色",
+	darkgrey: "暗灰色", // same as darkgray
+	darkkhaki: "暗卡其色",
+	darkmagenta: "暗紫紅色",
+	darkolivegreen: "暗橄欖綠",
+	darkorange: "暗橙色",
+	darkorchid: "暗蘭花色",
+	darkred: "暗紅色",
+	darksalmon: "暗鮭紅",
+	darkseagreen: "暗海綠色",
+	darkslateblue: "暗岩藍色",
+	darkslategray: "暗岩灰色",
+	darkslategrey: "暗岩灰色", // same as darkslategray
+	darkturquoise: "暗松石綠",
+	darkviolet: "暗紫羅蘭色",
+	deeppink: "深粉紅色",
+	deepskyblue: "深天藍色",
+	dimgray: "昏灰色",
+	dimgrey: "昏灰色", // same as dimgray
+	dodgerblue: "道奇藍",
+	firebrick: "紅磚色",
+	floralwhite: "花卉白",
+	forestgreen: "森綠色",
+	fuchsia: "海棠紅",
+	gainsboro: "石板灰",
+	ghostwhite: "幽靈色",
+	gold: "金色",
+	goldenrod: "金菊色",
+	gray: "灰色",
+	green: "綠色",
+	greenyellow: "綠黃色",
+	grey: "灰色", // same as gray
+	honeydew: "密瓜色",
+	hotpink: "暖粉紅色",
+	indianred: "印度紅",
+	indigo: "靛藍色",
+	ivory: "象牙色",
+	khaki: "卡其色",
+	lavender: "薰衣草紫",
+	lavenderblush: "薰衣草紫紅",
+	lawngreen: "草綠色",
+	lemonchiffon: "奶油黃",
+	lightblue: "淡藍色",
+	lightcoral: "淡珊瑚紅",
+	lightcyan: "淡青色",
+	lightgoldenrodyellow: "淡金菊黃",
+	lightgray: "淡灰色",
+	lightgreen: "淡綠色",
+	lightgrey: "淡灰色", // same as lightgray
+	lightpink: "淡粉紅色",
+	lightsalmon: "淡鮭紅",
+	lightseagreen: "淡海綠色",
+	lightskyblue: "淡天藍色",
+	lightslategray: "淡岩灰色",
+	lightslategrey: "淡岩灰色", // same as lightslategray
+	lightsteelblue: "淡鐵藍色",
+	lightyellow: "淡黃色",
+	lime: "檸檬色",
+	limegreen: "檸檬綠",
+	linen: "亞麻色",
+	magenta: "紫紅色",
+	maroon: "栗色",
+	mediumaquamarine: "中碧綠色",
+	mediumblue: "中藍色",
+	mediumorchid: "中蘭紫色",
+	mediumpurple: "中紫色",
+	mediumseagreen: "中海綠色",
+	mediumslateblue: "中岩藍色",
+	mediumspringgreen: "中春綠色",
+	mediumturquoise: "中松石綠",
+	mediumvioletred: "中紫羅蘭紅",
+	midnightblue: "午夜藍",
+	mintcream: "薄荷乳白色",
+	mistyrose: "霧玫瑰色",
+	moccasin: "鹿皮黃色",
+	navajowhite: "印地安黃色",
+	navy: "海軍藍",
+	oldlace: "舊蕾絲色",
+	olive: "橄欖色",
+	olivedrab: "橄欖綠",
+	orange: "橙色",
+	orangered: "橙紅色",
+	orchid: "蘭花色",
+	palegoldenrod: "灰金菊色",
+	palegreen: "灰綠色",
+	paleturquoise: "灰松石綠",
+	palevioletred: "灰紫羅蘭紅",
+	papayawhip: "番木瓜色",
+	peachpuff: "粉撲桃色",
+	peru: "祕魯色",
+	pink: "粉紅色",
+	plum: "李紫色",
+	powderblue: "粉藍色",
+	purple: "紫色",
+	red: "紅色",
+	rosybrown: "玫瑰褐",
+	royalblue: "品藍色",
+	saddlebrown: "鞍褐色",
+	salmon: "鮭紅色",
+	sandybrown: "沙褐色",
+	seagreen: "海綠色",
+	seashell: "海貝色",
+	sienna: "黃土赭色",
+	silver: "銀色",
+	skyblue: "天藍色",
+	slateblue: "岩藍色",
+	slategray: "岩灰色",
+	slategrey: "岩灰色", // same as slategray
+	snow: "雪白色",
+	springgreen: "春綠色",
+	steelblue: "鐵藍色",
+	tan: "皮革色",
+	teal: "深藍綠色",
+	thistle: "薊色",
+	tomato: "蕃茄紅",
+	transparent: "透明",
+	turquoise: "松石綠",
+	violet: "紫羅蘭色",
+	wheat: "小麥色",
+	white: "白色",
+	whitesmoke: "白煙色",
+	yellow: "黃色",
+	yellowgreen: "黃綠色"
 })
-//end v1.x content
 );
diff --git a/dojo/nls/zh/colors.js b/dojo/nls/zh/colors.js
index 3aabe7b..d7f23fd 100644
--- a/dojo/nls/zh/colors.js
+++ b/dojo/nls/zh/colors.js
@@ -1,159 +1,156 @@
 define(
-//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
-
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
-//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "艾莉斯蓝",
-antiquewhite: "古董白",
-aqua: "水绿色",
-aquamarine: "碧绿色",
-azure: "浅天蓝",
-beige: "米色",
-bisque: "乳黄色",
-black: "黑色",
-blanchedalmond: "杏仁白",
-blue: "蓝色",
-blueviolet: "蓝紫色",
-brown: "褐色",
-burlywood: "原木色",
-cadetblue: "军队蓝",
-chartreuse: "浅黄绿色",
-chocolate: "巧克力色",
-coral: "珊瑚红",
-cornflowerblue: "藏蓝色",
-cornsilk: "玉米黄",
-crimson: "绯红色",
-cyan: "青色",
-darkblue: "深蓝色",
-darkcyan: "深青色",
-darkgoldenrod: "深金黄色",
-darkgray: "深灰色",
-darkgreen: "深绿色",
-darkgrey: "深灰色", // same as darkgray
-darkkhaki: "深褐色",
-darkmagenta: "深洋红色",
-darkolivegreen: "深橄榄绿色",
-darkorange: "深橙色",
-darkorchid: "暗兰花紫",
-darkred: "深红色",
-darksalmon: "深橙红",
-darkseagreen: "深海绿色",
-darkslateblue: "深石板蓝",
-darkslategray: "深石板灰",
-darkslategrey: "深石板灰", // same as darkslategray
-darkturquoise: "深青绿色",
-darkviolet: "深紫罗兰",
-deeppink: "深粉色",
-deepskyblue: "深天蓝色",
-dimgray: "暗灰色",
-dimgrey: "暗灰色", // same as dimgray
-dodgerblue: "宝蓝",
-firebrick: "砖红色",
-floralwhite: "花白",
-forestgreen: "森林绿",
-fuchsia: "紫红色",
-gainsboro: "亮灰色",
-ghostwhite: "苍白",
-gold: "金黄色",
-goldenrod: "鲜黄",
-gray: "灰色",
-green: "绿色",
-greenyellow: "绿黄色",
-grey: "灰色", // same as gray
-honeydew: "蜜色",
-hotpink: "暗粉",
-indianred: "印度红",
-indigo: "靛蓝色",
-ivory: "象牙色",
-khaki: "黄褐色",
-lavender: "淡紫色",
-lavenderblush: "淡紫红色",
-lawngreen: "草绿色",
-lemonchiffon: "柠檬色",
-lightblue: "淡蓝色",
-lightcoral: "浅珊瑚红",
-lightcyan: "浅青色",
-lightgoldenrodyellow: "浅金黄色",
-lightgray: "浅灰色",
-lightgreen: "浅绿色",
-lightgrey: "浅灰色", // same as lightgray
-lightpink: "浅粉色",
-lightsalmon: "浅橙红色",
-lightseagreen: "浅海绿色",
-lightskyblue: "浅天蓝色",
-lightslategray: "浅石板灰",
-lightslategrey: "浅石板灰", // same as lightslategray
-lightsteelblue: "浅钢蓝色",
-lightyellow: "浅黄色",
-lime: "酸橙色",
-limegreen: "暗黄绿色",
-linen: "亚麻布色",
-magenta: "洋红色",
-maroon: "褐紫红色",
-mediumaquamarine: "淡碧绿色",
-mediumblue: "淡蓝色",
-mediumorchid: "淡兰花紫",
-mediumpurple: "淡紫色",
-mediumseagreen: "淡海绿色",
-mediumslateblue: "淡灰蓝色",
-mediumspringgreen: "淡草绿色",
-mediumturquoise: "淡青绿色",
-mediumvioletred: "淡紫罗兰",
-midnightblue: "蓝黑色",
-mintcream: "薄荷乳白",
-mistyrose: "粉红玫瑰",
-moccasin: "鹿皮黄",
-navajowhite: "印地安黄",
-navy: "藏青色",
-oldlace: "旧布黄",
-olive: "橄榄色",
-olivedrab: "暗橄榄色",
-orange: "橙色",
-orangered: "桔红色",
-orchid: "兰花紫",
-palegoldenrod: "浅金黄色",
-palegreen: "淡绿色",
-paleturquoise: "淡青绿色",
-palevioletred: "浅紫罗兰",
-papayawhip: "粉木瓜橙",
-peachpuff: "粉桃红",
-peru: "秘鲁棕",
-pink: "粉红色",
-plum: "梅红色",
-powderblue: "粉蓝色",
-purple: "紫色",
-red: "红色",
-rosybrown: "玫瑰褐色",
-royalblue: "亮蓝色",
-saddlebrown: "鞍具褐色",
-salmon: "橙红色",
-sandybrown: "浅褐色",
-seagreen: "海绿色",
-seashell: "贝壳白",
-sienna: "赭色",
-silver: "银白色",
-skyblue: "天蓝色",
-slateblue: "石板蓝",
-slategray: "石板灰",
-slategrey: "石板灰", // same as slategray
-snow: "雪白",
-springgreen: "浅草绿色",
-steelblue: "钢蓝色",
-tan: "茶色",
-teal: "青色",
-thistle: "蓟色",
-tomato: "番茄色",
-transparent: "透明的",
-turquoise: "青绿色",
-violet: "紫罗兰色",
-wheat: "淡黄色",
-white: "白色",
-whitesmoke: "烟白色",
-yellow: "黄色",
-yellowgreen: "黄绿色"
+	//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color (e.g. gray / grey).
+	//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+	aliceblue: "爱丽丝蓝",
+	antiquewhite: "古董白",
+	aqua: "浅绿色",
+	aquamarine: "碧绿色",
+	azure: "天蓝色",
+	beige: "米色",
+	bisque: "桔黄色",
+	black: "黑色",
+	blanchedalmond: "白杏色",
+	blue: "蓝色",
+	blueviolet: "蓝紫色",
+	brown: "棕色",
+	burlywood: "实木色",
+	cadetblue: "灰蓝色",
+	chartreuse: "黄绿色",
+	chocolate: "巧克力色",
+	coral: "珊瑚色",
+	cornflowerblue: "浅蓝色",
+	cornsilk: "米绸色",
+	crimson: "绯红色",
+	cyan: "青蓝色",
+	darkblue: "深蓝",
+	darkcyan: "深青绿",
+	darkgoldenrod: "深金黄",
+	darkgray: "深灰色",
+	darkgreen: "深绿色",
+	darkgrey: "深灰色", // same as darkgray
+	darkkhaki: "深卡其色",
+	darkmagenta: "深洋红色",
+	darkolivegreen: "深橄榄绿",
+	darkorange: "深橙色",
+	darkorchid: "深紫色",
+	darkred: "深红色",
+	darksalmon: "深橙红",
+	darkseagreen: "深海藻绿",
+	darkslateblue: "深青蓝",
+	darkslategray: "深青灰",
+	darkslategrey: "深青灰", // same as darkslategray
+	darkturquoise: "深粉蓝",
+	darkviolet: "深紫色",
+	deeppink: "深粉红色",
+	deepskyblue: "深天蓝色",
+	dimgray: "暗灰色",
+	dimgrey: "暗灰色", // same as dimgray
+	dodgerblue: "闪蓝色",
+	firebrick: "砖红",
+	floralwhite: "花白色",
+	forestgreen: "森林绿",
+	fuchsia: "紫红色",
+	gainsboro: "淡灰色",
+	ghostwhite: "苍白",
+	gold: "金黄色",
+	goldenrod: "金麒麟色",
+	gray: "灰色",
+	green: "绿色",
+	greenyellow: "绿黄色",
+	grey: "灰色", // same as gray
+	honeydew: "蜜汁色",
+	hotpink: "深粉红",
+	indianred: "印度红",
+	indigo: "靛青",
+	ivory: "象牙色",
+	khaki: "卡其色",
+	lavender: "淡紫色",
+	lavenderblush: "淡紫红",
+	lawngreen: "草绿色",
+	lemonchiffon: "柠檬绸色",
+	lightblue: "淡蓝色",
+	lightcoral: "浅珊瑚色",
+	lightcyan: "浅青色",
+	lightgoldenrodyellow: "浅金黄色",
+	lightgray: "浅灰色",
+	lightgreen: "浅绿色",
+	lightgrey: "浅灰色", // same as lightgray
+	lightpink: "浅粉红色",
+	lightsalmon: "淡橙色",
+	lightseagreen: "浅海藻绿",
+	lightskyblue: "浅天蓝色",
+	lightslategray: "浅青灰",
+	lightslategrey: "浅青灰", // same as lightslategray
+	lightsteelblue: "浅钢蓝色",
+	lightyellow: "浅黄色",
+	lime: "淡黄绿色",
+	limegreen: "橙绿色",
+	linen: "亚麻色",
+	magenta: "洋红色",
+	maroon: "栗色",
+	mediumaquamarine: "间绿色",
+	mediumblue: "间蓝色",
+	mediumorchid: "间紫色",
+	mediumpurple: "间紫色",
+	mediumseagreen: "间海蓝色",
+	mediumslateblue: "间暗蓝色",
+	mediumspringgreen: "间春绿色",
+	mediumturquoise: "间绿宝石色",
+	mediumvioletred: "间紫罗兰色",
+	midnightblue: "深蓝色",
+	mintcream: "薄荷色",
+	mistyrose: "浅玫瑰色",
+	moccasin: "鹿皮色",
+	navajowhite: "纳瓦白",
+	navy: "藏青色",
+	oldlace: "老白色",
+	olive: "橄榄绿",
+	olivedrab: "草绿色",
+	orange: "橙色",
+	orangered: "橙红色",
+	orchid: "紫色",
+	palegoldenrod: "淡金黄色",
+	palegreen: "淡绿色",
+	paleturquoise: "苍绿色",
+	palevioletred: "苍紫罗兰色",
+	papayawhip: "木瓜色",
+	peachpuff: "桃色",
+	peru: "秘鲁色",
+	pink: "粉红色",
+	plum: "杨李色",
+	powderblue: "铁蓝",
+	purple: "紫色",
+	red: "红色",
+	rosybrown: "褐玫瑰红",
+	royalblue: "品蓝",
+	saddlebrown: "重褐色",
+	salmon: "橙红",
+	sandybrown: "沙褐色",
+	seagreen: "海绿色",
+	seashell: "海贝色",
+	sienna: "赭色",
+	silver: "银白色",
+	skyblue: "天蓝色",
+	slateblue: "石蓝色",
+	slategray: "灰石色",
+	slategrey: "灰石色", // same as slategray
+	snow: "雪白色",
+	springgreen: "春绿色",
+	steelblue: "钢蓝色",
+	tan: "棕褐色",
+	teal: "水鸭色",
+	thistle: "蓟色",
+	tomato: "西红柿色",
+	transparent: "透明的",
+	turquoise: "绿宝石色",
+	violet: "紫色",
+	wheat: "浅黄色",
+	white: "白色",
+	whitesmoke: "烟白色",
+	yellow: "黄色",
+	yellowgreen: "黄绿色"
 })
-//end v1.x content
 );
diff --git a/dojo/node.js b/dojo/node.js
new file mode 100644
index 0000000..f804ba9
--- /dev/null
+++ b/dojo/node.js
@@ -0,0 +1,67 @@
+define(["./has"], function(has){
+	if(!has("host-node")){
+		throw new Error("node plugin failed to load because environment is not Node.js");
+	}
+
+	var pathUtil;
+	if(require.nodeRequire){
+		pathUtil = require.nodeRequire("path");
+	}else{
+		throw new Error("node plugin failed to load because it cannot find the original Node.js require");
+	}
+
+	return {
+		// summary:
+		//		This AMD plugin module allows native Node.js modules to be loaded by AMD modules using the Dojo
+		//		loader. Note that this plugin will not work with AMD loaders other than the Dojo loader.
+		// example:
+		//	|	require(["dojo/node!fs"], function(fs){
+		//	|		var fileData = fs.readFileSync("foo.txt", "utf-8");
+		//	|	});
+
+		load: function(/*string*/ id, /*Function*/ require, /*Function*/ load){
+			// summary:
+			//		Standard AMD plugin interface. See https://github.com/amdjs/amdjs-api/wiki/Loader-Plugins
+			//		for information.
+
+			if(!require.nodeRequire){
+				throw new Error("Cannot find native require function");
+			}
+
+			load((function(id, require){
+				var oldDefine = define,
+					result;
+
+				// Some modules may attempt to detect an AMD loader via define and define.amd.  This can cause issues
+				// when other CommonJS modules attempt to load them via the standard node require().  If define is
+				// temporarily moved into another variable, it will prevent modules from detecting AMD in this fashion.
+				define = undefined;
+
+				try{
+					result = require(id);
+				}finally{
+					define = oldDefine;
+				}
+				return result;
+			})(id, require.nodeRequire));
+		},
+
+		normalize: function (/**string*/ id, /*Function*/ normalize){
+			// summary:
+			//		Produces a normalized id to be used by node.  Relative ids are resolved relative to the requesting
+			//		module's location in the file system and will return an id with path separators appropriate for the
+			//		local file system.
+
+			if(id.charAt(0) === "."){
+				// dirname of the reference module - normalized to match the local file system
+				var referenceModuleDirname = require.toUrl(normalize(".")).replace("/", pathUtil.sep),
+					segments = id.split("/");
+				segments.unshift(referenceModuleDirname);
+				// this will produce an absolute path normalized to the semantics of the underlying file system.
+				id = pathUtil.join.apply(pathUtil, segments);
+			}
+
+			return id;
+		}
+	};
+});
diff --git a/dojo/number.js b/dojo/number.js
index eba7616..a6c73d5 100644
--- a/dojo/number.js
+++ b/dojo/number.js
@@ -1,46 +1,38 @@
-define(["./_base/kernel", "./_base/lang", "./i18n", "./i18n!./cldr/nls/number", "./string", "./regexp"],
-	function(dojo, lang, i18n, nlsNumber, dstring, dregexp) {
+define([/*===== "./_base/declare", =====*/ "./_base/lang", "./i18n", "./i18n!./cldr/nls/number", "./string", "./regexp"],
+	function(/*===== declare, =====*/ lang, i18n, nlsNumber, dstring, dregexp){
 
-	// module:
-	//		dojo/number
-	// summary:
-	//		TODOC
+// module:
+//		dojo/number
 
-lang.getObject("number", true, dojo);
+var number = {
+	// summary:
+	//		localized formatting and parsing routines for Number
+};
+lang.setObject("dojo.number", number);
 
 /*=====
-dojo.number = {
-	// summary: localized formatting and parsing routines for Number
-}
-
-dojo.number.__FormatOptions = function(){
-	//	pattern: String?
+number.__FormatOptions = declare(null, {
+	// pattern: String?
 	//		override [formatting pattern](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
 	//		with this string.  Default value is based on locale.  Overriding this property will defeat
 	//		localization.  Literal characters in patterns are not supported.
-	//	type: String?
+	// type: String?
 	//		choose a format type based on the locale from the following:
 	//		decimal, scientific (not yet supported), percent, currency. decimal by default.
-	//	places: Number?
+	// places: Number?
 	//		fixed number of decimal places to show.  This overrides any
 	//		information in the provided pattern.
-	//	round: Number?
+	// round: Number?
 	//		5 rounds to nearest .5; 0 rounds to nearest whole (default). -1
 	//		means do not round.
-	//	locale: String?
+	// locale: String?
 	//		override the locale used to determine formatting rules
-	//	fractional: Boolean?
+	// fractional: Boolean?
 	//		If false, show no decimal places, overriding places and pattern settings.
-	this.pattern = pattern;
-	this.type = type;
-	this.places = places;
-	this.round = round;
-	this.locale = locale;
-	this.fractional = fractional;
-}
+});
 =====*/
 
-dojo.number.format = function(/*Number*/value, /*dojo.number.__FormatOptions?*/options){
+number.format = function(/*Number*/ value, /*number.__FormatOptions?*/ options){
 	// summary:
 	//		Format a Number as a String, using locale-specific settings
 	// description:
@@ -58,13 +50,13 @@ dojo.number.format = function(/*Number*/value, /*dojo.number.__FormatOptions?*/o
 	options.customs = bundle;
 	var pattern = options.pattern || bundle[(options.type || "decimal") + "Format"];
 	if(isNaN(value) || Math.abs(value) == Infinity){ return null; } // null
-	return dojo.number._applyPattern(value, pattern, options); // String
+	return number._applyPattern(value, pattern, options); // String
 };
 
-//dojo.number._numberPatternRE = /(?:[#0]*,?)*[#0](?:\.0*#*)?/; // not precise, but good enough
-dojo.number._numberPatternRE = /[#0,]*[#0](?:\.0*#*)?/; // not precise, but good enough
+//number._numberPatternRE = /(?:[#0]*,?)*[#0](?:\.0*#*)?/; // not precise, but good enough
+number._numberPatternRE = /[#0,]*[#0](?:\.0*#*)?/; // not precise, but good enough
 
-dojo.number._applyPattern = function(/*Number*/value, /*String*/pattern, /*dojo.number.__FormatOptions?*/options){
+number._applyPattern = function(/*Number*/ value, /*String*/ pattern, /*number.__FormatOptions?*/ options){
 	// summary:
 	//		Apply pattern to format value as a string using options. Gives no
 	//		consideration to local customs.
@@ -73,8 +65,8 @@ dojo.number._applyPattern = function(/*Number*/value, /*String*/pattern, /*dojo.
 	// pattern:
 	//		a pattern string as described by
 	//		[unicode.org TR35](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
-	// options: dojo.number.__FormatOptions?
-	//		_applyPattern is usually called via `dojo.number.format()` which
+	// options: number.__FormatOptions?
+	//		_applyPattern is usually called via `dojo/number.format()` which
 	//		populates an extra property in the options parameter, "customs".
 	//		The customs object specifies group and decimal parameters if set.
 
@@ -103,38 +95,38 @@ dojo.number._applyPattern = function(/*Number*/value, /*String*/pattern, /*dojo.
 	}
 
 	//TODO: support @ sig figs?
-	var numberPatternRE = dojo.number._numberPatternRE;
+	var numberPatternRE = number._numberPatternRE;
 	var numberPattern = positivePattern.match(numberPatternRE);
 	if(!numberPattern){
 		throw new Error("unable to find a number expression in pattern: "+pattern);
 	}
 	if(options.fractional === false){ options.places = 0; }
 	return pattern.replace(numberPatternRE,
-		dojo.number._formatAbsolute(value, numberPattern[0], {decimal: decimal, group: group, places: options.places, round: options.round}));
+		number._formatAbsolute(value, numberPattern[0], {decimal: decimal, group: group, places: options.places, round: options.round}));
 };
 
-dojo.number.round = function(/*Number*/value, /*Number?*/places, /*Number?*/increment){
-	//	summary:
+number.round = function(/*Number*/ value, /*Number?*/ places, /*Number?*/ increment){
+	// summary:
 	//		Rounds to the nearest value with the given number of decimal places, away from zero
-	//	description:
+	// description:
 	//		Rounds to the nearest value with the given number of decimal places, away from zero if equal.
 	//		Similar to Number.toFixed(), but compensates for browser quirks. Rounding can be done by
 	//		fractional increments also, such as the nearest quarter.
-	//		NOTE: Subject to floating point errors.  See dojox.math.round for experimental workaround.
-	//	value:
+	//		NOTE: Subject to floating point errors.  See dojox/math/round for experimental workaround.
+	// value:
 	//		The number to round
-	//	places:
+	// places:
 	//		The number of decimal places where rounding takes place.  Defaults to 0 for whole rounding.
 	//		Must be non-negative.
-	//	increment:
+	// increment:
 	//		Rounds next place to nearest value of increment/10.  10 by default.
-	//	example:
-	//		>>> dojo.number.round(-0.5)
-	//		-1
-	//		>>> dojo.number.round(162.295, 2)
-	//		162.29  // note floating point error.  Should be 162.3
-	//		>>> dojo.number.round(10.71, 0, 2.5)
-	//		10.75
+	// example:
+	// |	>>> number.round(-0.5)
+	// |	-1
+	// |	>>> number.round(162.295, 2)
+	// |	162.29  // note floating point error.  Should be 162.3
+	// |	>>> number.round(10.71, 0, 2.5)
+	// |	10.75
 	var factor = 10 / (increment || 10);
 	return (factor * +value).toFixed(places) / factor; // Number
 };
@@ -142,35 +134,39 @@ dojo.number.round = function(/*Number*/value, /*Number?*/places, /*Number?*/incr
 if((0.9).toFixed() == 0){
 	// (isIE) toFixed() bug workaround: Rounding fails on IE when most significant digit
 	// is just after the rounding place and is >=5
-	var round = dojo.number.round;
-	dojo.number.round = function(v, p, m){
+	var round = number.round;
+	number.round = function(v, p, m){
 		var d = Math.pow(10, -p || 0), a = Math.abs(v);
-		if(!v || a >= d || a * Math.pow(10, p + 1) < 5){
+		if(!v || a >= d){
 			d = 0;
+		}else{
+			a /= d;
+			if(a < 0.5 || a >= 0.95){
+				d = 0;
+			}
 		}
 		return round(v, p, m) + (v > 0 ? d : -d);
 	};
+
+	// Use "doc hint" so the doc parser ignores this new definition of round(), and uses the one above.
+	/*===== number.round = round; =====*/
 }
 
 /*=====
-dojo.number.__FormatAbsoluteOptions = function(){
-	//	decimal: String?
+number.__FormatAbsoluteOptions = declare(null, {
+	// decimal: String?
 	//		the decimal separator
-	//	group: String?
+	// group: String?
 	//		the group separator
-	//	places: Number?|String?
+	// places: Number|String?
 	//		number of decimal places.  the range "n,m" will format to m places.
-	//	round: Number?
+	// round: Number?
 	//		5 rounds to nearest .5; 0 rounds to nearest whole (default). -1
 	//		means don't round.
-	this.decimal = decimal;
-	this.group = group;
-	this.places = places;
-	this.round = round;
-}
+});
 =====*/
 
-dojo.number._formatAbsolute = function(/*Number*/value, /*String*/pattern, /*dojo.number.__FormatAbsoluteOptions?*/options){
+number._formatAbsolute = function(/*Number*/ value, /*String*/ pattern, /*number.__FormatAbsoluteOptions?*/ options){
 	// summary:
 	//		Apply numeric pattern to absolute value using options. Gives no
 	//		consideration to local customs.
@@ -191,7 +187,7 @@ dojo.number._formatAbsolute = function(/*Number*/value, /*String*/pattern, /*doj
 		maxPlaces = (patternParts[1] || []).length;
 	}
 	if(!(options.round < 0)){
-		value = dojo.number.round(value, maxPlaces, options.round);
+		value = number.round(value, maxPlaces, options.round);
 	}
 
 	var valueParts = String(Math.abs(value)).split("."),
@@ -256,39 +252,34 @@ dojo.number._formatAbsolute = function(/*Number*/value, /*String*/pattern, /*doj
 };
 
 /*=====
-dojo.number.__RegexpOptions = function(){
-	//	pattern: String?
+number.__RegexpOptions = declare(null, {
+	// pattern: String?
 	//		override [formatting pattern](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
 	//		with this string.  Default value is based on locale.  Overriding this property will defeat
 	//		localization.
-	//	type: String?
+	// type: String?
 	//		choose a format type based on the locale from the following:
 	//		decimal, scientific (not yet supported), percent, currency. decimal by default.
-	//	locale: String?
+	// locale: String?
 	//		override the locale used to determine formatting rules
-	//	strict: Boolean?
+	// strict: Boolean?
 	//		strict parsing, false by default.  Strict parsing requires input as produced by the format() method.
 	//		Non-strict is more permissive, e.g. flexible on white space, omitting thousands separators
-	//	places: Number|String?
+	// places: Number|String?
 	//		number of decimal places to accept: Infinity, a positive number, or
 	//		a range "n,m".  Defined by pattern or Infinity if pattern not provided.
-	this.pattern = pattern;
-	this.type = type;
-	this.locale = locale;
-	this.strict = strict;
-	this.places = places;
-}
+});
 =====*/
-dojo.number.regexp = function(/*dojo.number.__RegexpOptions?*/options){
-	//	summary:
+number.regexp = function(/*number.__RegexpOptions?*/ options){
+	// summary:
 	//		Builds the regular needed to parse a number
-	//	description:
+	// description:
 	//		Returns regular expression with positive and negative match, group
 	//		and decimal separators
-	return dojo.number._parseInfo(options).regexp; // String
+	return number._parseInfo(options).regexp; // String
 };
 
-dojo.number._parseInfo = function(/*Object?*/options){
+number._parseInfo = function(/*Object?*/ options){
 	options = options || {};
 	var locale = i18n.normalizeLocale(options.locale),
 		bundle = i18n.getLocalization("dojo.cldr", "number", locale),
@@ -318,7 +309,7 @@ dojo.number._parseInfo = function(/*Object?*/options){
 
 	var re = dregexp.buildGroupRE(patternList, function(pattern){
 		pattern = "(?:"+dregexp.escapeString(pattern, '.')+")";
-		return pattern.replace(dojo.number._numberPatternRE, function(format){
+		return pattern.replace(number._numberPatternRE, function(format){
 			var flags = {
 				signed: false,
 				separator: options.strict ? group : [group,""],
@@ -350,7 +341,7 @@ dojo.number._parseInfo = function(/*Object?*/options){
 					flags.groupSize2 = groups.pop().length;
 				}
 			}
-			return "("+dojo.number._realNumberRegexp(flags)+")";
+			return "("+number._realNumberRegexp(flags)+")";
 		});
 	}, true);
 
@@ -377,30 +368,25 @@ dojo.number._parseInfo = function(/*Object?*/options){
 };
 
 /*=====
-dojo.number.__ParseOptions = function(){
-	//	pattern: String?
+number.__ParseOptions = declare(null, {
+	// pattern: String?
 	//		override [formatting pattern](http://www.unicode.org/reports/tr35/#Number_Format_Patterns)
 	//		with this string.  Default value is based on locale.  Overriding this property will defeat
 	//		localization.  Literal characters in patterns are not supported.
-	//	type: String?
+	// type: String?
 	//		choose a format type based on the locale from the following:
 	//		decimal, scientific (not yet supported), percent, currency. decimal by default.
-	//	locale: String?
+	// locale: String?
 	//		override the locale used to determine formatting rules
-	//	strict: Boolean?
+	// strict: Boolean?
 	//		strict parsing, false by default.  Strict parsing requires input as produced by the format() method.
 	//		Non-strict is more permissive, e.g. flexible on white space, omitting thousands separators
-	//	fractional: Boolean?|Array?
+	// fractional: Boolean|Array?
 	//		Whether to include the fractional portion, where the number of decimal places are implied by pattern
 	//		or explicit 'places' parameter.  The value [true,false] makes the fractional portion optional.
-	this.pattern = pattern;
-	this.type = type;
-	this.locale = locale;
-	this.strict = strict;
-	this.fractional = fractional;
-}
+});
 =====*/
-dojo.number.parse = function(/*String*/expression, /*dojo.number.__ParseOptions?*/options){
+number.parse = function(/*String*/ expression, /*number.__ParseOptions?*/ options){
 	// summary:
 	//		Convert a properly formatted string to a primitive Number, using
 	//		locale-specific settings.
@@ -412,7 +398,7 @@ dojo.number.parse = function(/*String*/expression, /*dojo.number.__ParseOptions?
     	//		Note that literal characters in patterns are not supported.
 	// expression:
 	//		A string representation of a Number
-	var info = dojo.number._parseInfo(options),
+	var info = number._parseInfo(options),
 		results = (new RegExp("^"+info.regexp+"$")).exec(expression);
 	if(!results){
 		return NaN; //NaN
@@ -437,35 +423,30 @@ dojo.number.parse = function(/*String*/expression, /*dojo.number.__ParseOptions?
 };
 
 /*=====
-dojo.number.__RealNumberRegexpFlags = function(){
-	//	places: Number?
+number.__RealNumberRegexpFlags = declare(null, {
+	// places: Number?
 	//		The integer number of decimal places or a range given as "n,m".  If
 	//		not given, the decimal part is optional and the number of places is
 	//		unlimited.
-	//	decimal: String?
+	// decimal: String?
 	//		A string for the character used as the decimal point.  Default
 	//		is ".".
-	//	fractional: Boolean?|Array?
+	// fractional: Boolean|Array?
 	//		Whether decimal places are used.  Can be true, false, or [true,
 	//		false].  Default is [true, false] which means optional.
-	//	exponent: Boolean?|Array?
+	// exponent: Boolean|Array?
 	//		Express in exponential notation.  Can be true, false, or [true,
 	//		false]. Default is [true, false], (i.e. will match if the
 	//		exponential part is present are not).
-	//	eSigned: Boolean?|Array?
+	// eSigned: Boolean|Array?
 	//		The leading plus-or-minus sign on the exponent.  Can be true,
 	//		false, or [true, false].  Default is [true, false], (i.e. will
 	//		match if it is signed or unsigned).  flags in regexp.integer can be
 	//		applied.
-	this.places = places;
-	this.decimal = decimal;
-	this.fractional = fractional;
-	this.exponent = exponent;
-	this.eSigned = eSigned;
-}
+});
 =====*/
 
-dojo.number._realNumberRegexp = function(/*dojo.number.__RealNumberRegexpFlags?*/flags){
+number._realNumberRegexp = function(/*__RealNumberRegexpFlags?*/ flags){
 	// summary:
 	//		Builds a regular expression to match a real number in exponential
 	//		notation
@@ -479,7 +460,7 @@ dojo.number._realNumberRegexp = function(/*dojo.number.__RealNumberRegexpFlags?*
 	if(!("exponent" in flags)){ flags.exponent = [true, false]; }
 	if(!("eSigned" in flags)){ flags.eSigned = [true, false]; }
 
-	var integerRE = dojo.number._integerRegexp(flags),
+	var integerRE = number._integerRegexp(flags),
 		decimalRE = dregexp.buildGroupRE(flags.fractional,
 		function(q){
 			var re = "";
@@ -498,7 +479,7 @@ dojo.number._realNumberRegexp = function(/*dojo.number.__RealNumberRegexpFlags?*
 
 	var exponentRE = dregexp.buildGroupRE(flags.exponent,
 		function(q){
-			if(q){ return "([eE]" + dojo.number._integerRegexp({ signed: flags.eSigned}) + ")"; }
+			if(q){ return "([eE]" + number._integerRegexp({ signed: flags.eSigned}) + ")"; }
 			return "";
 		}
 	);
@@ -510,27 +491,23 @@ dojo.number._realNumberRegexp = function(/*dojo.number.__RealNumberRegexpFlags?*
 };
 
 /*=====
-dojo.number.__IntegerRegexpFlags = function(){
-	//	signed: Boolean?
+number.__IntegerRegexpFlags = declare(null, {
+	// signed: Boolean?
 	//		The leading plus-or-minus sign. Can be true, false, or `[true,false]`.
 	//		Default is `[true, false]`, (i.e. will match if it is signed
 	//		or unsigned).
-	//	separator: String?
+	// separator: String?
 	//		The character used as the thousands separator. Default is no
 	//		separator. For more than one symbol use an array, e.g. `[",", ""]`,
 	//		makes ',' optional.
-	//	groupSize: Number?
+	// groupSize: Number?
 	//		group size between separators
-	//	groupSize2: Number?
+	// groupSize2: Number?
 	//		second grouping, where separators 2..n have a different interval than the first separator (for India)
-	this.signed = signed;
-	this.separator = separator;
-	this.groupSize = groupSize;
-	this.groupSize2 = groupSize2;
-}
+});
 =====*/
 
-dojo.number._integerRegexp = function(/*dojo.number.__IntegerRegexpFlags?*/flags){
+number._integerRegexp = function(/*number.__IntegerRegexpFlags?*/ flags){
 	// summary:
 	//		Builds a regular expression that matches an integer
 
@@ -572,5 +549,5 @@ dojo.number._integerRegexp = function(/*dojo.number.__IntegerRegexpFlags?*/flags
 	return signRE + numberRE; // String
 };
 
-return dojo.number;
+return number;
 });
diff --git a/dojo/on.js b/dojo/on.js
index e233209..16c8803 100644
--- a/dojo/on.js
+++ b/dojo/on.js
@@ -1,44 +1,53 @@
-define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], function(aspect, dojo, has){
-	// summary:
-	//		The export of this module is a function that provides core event listening functionality. With this function
-	//		you can provide a target, event type, and listener to be notified of
-	//		future matching events that are fired.
-	// target: Element|Object
-	//		This is the target object or DOM element that to receive events from
-	// type: String|Function
-	// 		This is the name of the event to listen for or an extension event type.
-	// listener: Function
-	// 		This is the function that should be called when the event fires.
-	// returns: Object
-	// 		An object with a remove() method that can be used to stop listening for this
-	// 		event.
-	// description:
-	// 		To listen for "click" events on a button node, we can do:
-	// 		|	define(["dojo/on"], function(listen){
-	// 		|		on(button, "click", clickHandler);
-	//		|		...
-	//  	Evented JavaScript objects can also have their own events.
-	// 		|	var obj = new Evented;
-	//		|	on(obj, "foo", fooHandler);
-	//		And then we could publish a "foo" event:
-	//		|	on.emit(obj, "foo", {key: "value"});
-	//		We can use extension events as well. For example, you could listen for a tap gesture:
-	// 		|	define(["dojo/on", "dojo/gesture/tap", function(listen, tap){
-	// 		|		on(button, tap, tapHandler);
-	//		|		...
-	//		which would trigger fooHandler. Note that for a simple object this is equivalent to calling:
-	//		|	obj.onfoo({key:"value"});
-	//		If you use on.emit on a DOM node, it will use native event dispatching when possible.
+define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./sniff"], function(aspect, dojo, has){
 
- 	"use strict";
+	"use strict";
 	if(has("dom")){ // check to make sure we are in a browser, this module should work anywhere
 		var major = window.ScriptEngineMajorVersion;
 		has.add("jscript", major && (major() + ScriptEngineMinorVersion() / 10));
 		has.add("event-orientationchange", has("touch") && !has("android")); // TODO: how do we detect this?
+		has.add("event-stopimmediatepropagation", window.Event && !!window.Event.prototype && !!window.Event.prototype.stopImmediatePropagation);
+		has.add("event-focusin", function(global, doc, element){
+			// All browsers except firefox support focusin, but too hard to feature test webkit since element.onfocusin
+			// is undefined.  Just return true for IE and use fallback path for other browsers.
+			return !!element.attachEvent;
+		});
 	}
 	var on = function(target, type, listener, dontFix){
-		if(target.on){ 
-			// delegate to the target's on() method, so it can handle it's own listening if it wants
+		// summary:
+		//		A function that provides core event listening functionality. With this function
+		//		you can provide a target, event type, and listener to be notified of
+		//		future matching events that are fired.
+		// target: Element|Object
+		//		This is the target object or DOM element that to receive events from
+		// type: String|Function
+		//		This is the name of the event to listen for or an extension event type.
+		// listener: Function
+		//		This is the function that should be called when the event fires.
+		// returns: Object
+		//		An object with a remove() method that can be used to stop listening for this
+		//		event.
+		// description:
+		//		To listen for "click" events on a button node, we can do:
+		//		|	define(["dojo/on"], function(listen){
+		//		|		on(button, "click", clickHandler);
+		//		|		...
+		//		Evented JavaScript objects can also have their own events.
+		//		|	var obj = new Evented;
+		//		|	on(obj, "foo", fooHandler);
+		//		And then we could publish a "foo" event:
+		//		|	on.emit(obj, "foo", {key: "value"});
+		//		We can use extension events as well. For example, you could listen for a tap gesture:
+		//		|	define(["dojo/on", "dojo/gesture/tap", function(listen, tap){
+		//		|		on(button, tap, tapHandler);
+		//		|		...
+		//		which would trigger fooHandler. Note that for a simple object this is equivalent to calling:
+		//		|	obj.onfoo({key:"value"});
+		//		If you use on.emit on a DOM node, it will use native event dispatching when possible.
+
+		if(typeof target.on == "function" && typeof type != "function" && !target.nodeType){
+			// delegate to the target's on() method, so it can handle it's own listening if it wants (unless it 
+			// is DOM node and we may be dealing with jQuery or Prototype's incompatible addition to the
+			// Element prototype 
 			return target.on(type, listener);
 		}
 		// delegate to main listener code
@@ -47,7 +56,7 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 	on.pausable =  function(target, type, listener, dontFix){
 		// summary:
 		//		This function acts the same as on(), but with pausable functionality. The
-		// 		returned signal object has pause() and resume() functions. Calling the
+		//		returned signal object has pause() and resume() functions. Calling the
 		//		pause() method will cause the listener to not be called for future events. Calling the
 		//		resume() method will cause the listener to again be called for future events.
 		var paused;
@@ -67,7 +76,7 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 	on.once = function(target, type, listener, dontFix){
 		// summary:
 		//		This function acts the same as on(), but will only call the listener once. The 
-		// 		listener will be called for the first
+		//		listener will be called for the first
 		//		event that takes place and then listener will automatically be removed.
 		var signal = on(target, type, function(){
 			// remove this listener
@@ -80,7 +89,7 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 	on.parse = function(target, type, listener, addListener, dontFix, matchesTarget){
 		if(type.call){
 			// event handler function
-			// on(node, dojo.touch.press, touchListener);
+			// on(node, touch.press, touchListener);
 			return type.call(matchesTarget, target, listener);
 		}
 
@@ -100,10 +109,10 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 			};
 			return handles;
 		}
-		return addListener(target, type, listener, dontFix, matchesTarget)
+		return addListener(target, type, listener, dontFix, matchesTarget);
 	};
 	var touchEvents = /^touch/;
-	function addListener(target, type, listener, dontFix, matchesTarget){		
+	function addListener(target, type, listener, dontFix, matchesTarget){
 		// event delegation:
 		var selector = type.match(/(.*):(.*)/);
 		// if we have a selector:event, the last one is interpreted as an event, and we use event delegation
@@ -127,16 +136,21 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 				listener = fixTouchListener(listener);
 			} 
 		}
+		if(addStopImmediate){
+			// add stopImmediatePropagation if it doesn't exist
+			listener = addStopImmediate(listener);
+		}
 		// normal path, the target is |this|
 		if(target.addEventListener){
 			// the target has addEventListener, which should be used if available (might or might not be a node, non-nodes can implement this method as well)
 			// check for capture conversions
-			var capture = type in captures;
-			target.addEventListener(capture ? captures[type] : type, listener, capture);
+			var capture = type in captures,
+				adjustedType = capture ? captures[type] : type;
+			target.addEventListener(adjustedType, listener, capture);
 			// create and return the signal
 			return {
 				remove: function(){
-					target.removeEventListener(type, listener, capture);
+					target.removeEventListener(adjustedType, listener, capture);
 				}
 			};
 		}
@@ -144,51 +158,58 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 		if(fixAttach && target.attachEvent){
 			return fixAttach(target, type, listener);
 		}
-	 	throw new Error("Target must be an event emitter");
+		throw new Error("Target must be an event emitter");
 	}
 
 	on.selector = function(selector, eventType, children){
 		// summary:
 		//		Creates a new extension event with event delegation. This is based on
-		// 		the provided event type (can be extension event) that
-		// 		only calls the listener when the CSS selector matches the target of the event.
-		//	selector:
+		//		the provided event type (can be extension event) that
+		//		only calls the listener when the CSS selector matches the target of the event.
+		//
+		//		The application must require() an appropriate level of dojo/query to handle the selector.
+		// selector:
 		//		The CSS selector to use for filter events and determine the |this| of the event listener.
-		//	eventType:
+		// eventType:
 		//		The event to listen for
 		// children:
 		//		Indicates if children elements of the selector should be allowed. This defaults to 
-		// 		true (except in the case of normally non-bubbling events like mouse.enter, in which case it defaults to false).
-		//	example:
-		//		define(["dojo/on", "dojo/mouse"], function(listen, mouse){
-		//			on(node, on.selector(".my-class", mouse.enter), handlerForMyHover);
+		//		true
+		// example:
+		// |	require(["dojo/on", "dojo/mouse", "dojo/query!css2"], function(listen, mouse){
+		// |		on(node, on.selector(".my-class", mouse.enter), handlerForMyHover);
 		return function(target, listener){
-			var matchesTarget = this;
-			var bubble = eventType.bubble;
-			if(bubble){
-				// the event type doesn't naturally bubble, but has a bubbling form, use that
-				eventType = bubble;
-			}else if(children !== false){
-				// for normal bubbling events we default to allowing children of the selector
-				children = true;
-			}
-			return on(target, eventType, function(event){
-				var eventTarget = event.target;
+			// if the selector is function, use it to select the node, otherwise use the matches method
+			var matchesTarget = typeof selector == "function" ? {matches: selector} : this,
+				bubble = eventType.bubble;
+			function select(eventTarget){
 				// see if we have a valid matchesTarget or default to dojo.query
 				matchesTarget = matchesTarget && matchesTarget.matches ? matchesTarget : dojo.query;
 				// there is a selector, so make sure it matches
 				while(!matchesTarget.matches(eventTarget, selector, target)){
-					if(eventTarget == target || !children || !(eventTarget = eventTarget.parentNode)){ // intentional assignment
+					if(eventTarget == target || children === false || !(eventTarget = eventTarget.parentNode) || eventTarget.nodeType != 1){ // intentional assignment
 						return;
 					}
 				}
-				return listener.call(eventTarget, event);
+				return eventTarget;
+			}
+			if(bubble){
+				// the event type doesn't naturally bubble, but has a bubbling form, use that, and give it the selector so it can perform the select itself
+				return on(target, bubble(select), listener);
+			}
+			// standard event delegation
+			return on(target, eventType, function(event){
+				// call select to see if we match
+				var eventTarget = select(event.target);
+				// if it matches we call the listener
+				return eventTarget && listener.call(eventTarget, event);
 			});
 		};
 	};
 
 	function syntheticPreventDefault(){
 		this.cancelable = false;
+		this.defaultPrevented = true;
 	}
 	function syntheticStopPropagation(){
 		this.bubbles = false;
@@ -197,38 +218,38 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 		syntheticDispatch = on.emit = function(target, type, event){
 		// summary:
 		//		Fires an event on the target object.
-		//	target:
+		// target:
 		//		The target object to fire the event on. This can be a DOM element or a plain 
-		// 		JS object. If the target is a DOM element, native event emiting mechanisms
+		//		JS object. If the target is a DOM element, native event emitting mechanisms
 		//		are used when possible.
-		//	type:
+		// type:
 		//		The event type name. You can emulate standard native events like "click" and 
-		// 		"mouseover" or create custom events like "open" or "finish".
-		//	event:
+		//		"mouseover" or create custom events like "open" or "finish".
+		// event:
 		//		An object that provides the properties for the event. See https://developer.mozilla.org/en/DOM/event.initEvent 
-		// 		for some of the properties. These properties are copied to the event object.
+		//		for some of the properties. These properties are copied to the event object.
 		//		Of particular importance are the cancelable and bubbles properties. The
 		//		cancelable property indicates whether or not the event has a default action
-		// 		that can be cancelled. The event is cancelled by calling preventDefault() on
-		// 		the event object. The bubbles property indicates whether or not the
+		//		that can be cancelled. The event is cancelled by calling preventDefault() on
+		//		the event object. The bubbles property indicates whether or not the
 		//		event will bubble up the DOM tree. If bubbles is true, the event will be called
 		//		on the target and then each parent successively until the top of the tree
 		//		is reached or stopPropagation() is called. Both bubbles and cancelable 
-		// 		default to false.
-		//	returns:
+		//		default to false.
+		// returns:
 		//		If the event is cancelable and the event is not cancelled,
-		// 		emit will return true. If the event is cancelable and the event is cancelled,
-		// 		emit will return false.
-		//	details:
+		//		emit will return true. If the event is cancelable and the event is cancelled,
+		//		emit will return false.
+		// details:
 		//		Note that this is designed to emit events for listeners registered through
 		//		dojo/on. It should actually work with any event listener except those
-		// 		added through IE's attachEvent (IE8 and below's non-W3C event emiting
-		// 		doesn't support custom event types). It should work with all events registered
-		// 		through dojo/on. Also note that the emit method does do any default
-		// 		action, it only returns a value to indicate if the default action should take
-		// 		place. For example, emiting a keypress event would not cause a character
-		// 		to appear in a textbox.
-		//	example:
+		//		added through IE's attachEvent (IE8 and below's non-W3C event emitting
+		//		doesn't support custom event types). It should work with all events registered
+		//		through dojo/on. Also note that the emit method does do any default
+		//		action, it only returns a value to indicate if the default action should take
+		//		place. For example, emitting a keypress event would not cause a character
+		//		to appear in a textbox.
+		// example:
 		//		To fire our own click event
 		//	|	on.emit(dojo.byId("button"), "click", {
 		//	|		cancelable: true,
@@ -263,31 +284,35 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 		}while(event && event.bubbles && (target = target.parentNode));
 		return event && event.cancelable && event; // if it is still true (was cancelable and was cancelled), return the event to indicate default action should happen
 	};
-	var captures = {}; 
-	if(has("dom-addeventlistener")){
-		// normalize focusin and focusout
-		captures = {
-			focusin: "focus",
-			focusout: "blur"
+	var captures = has("event-focusin") ? {} : {focusin: "focus", focusout: "blur"};
+	if(!has("event-stopimmediatepropagation")){
+		var stopImmediatePropagation =function(){
+			this.immediatelyStopped = true;
+			this.modified = true; // mark it as modified so the event will be cached in IE
 		};
-		if(has("opera")){
-			captures.keydown = "keypress"; // this one needs to be transformed because Opera doesn't support repeating keys on keydown (and keypress works because it incorrectly fires on all keydown events)
+		var addStopImmediate = function(listener){
+			return function(event){
+				if(!event.immediatelyStopped){// check to make sure it hasn't been stopped immediately
+					event.stopImmediatePropagation = stopImmediatePropagation;
+					return listener.apply(this, arguments);
+				}
+			};
 		}
-
-		// emiter that works with native event handling
+	} 
+	if(has("dom-addeventlistener")){
+		// emitter that works with native event handling
 		on.emit = function(target, type, event){
 			if(target.dispatchEvent && document.createEvent){
-				// use the native event emiting mechanism if it is available on the target object
+				// use the native event emitting mechanism if it is available on the target object
 				// create a generic event				
 				// we could create branch into the different types of event constructors, but 
 				// that would be a lot of extra code, with little benefit that I can see, seems 
 				// best to use the generic constructor and copy properties over, making it 
 				// easy to have events look like the ones created with specific initializers
-				var nativeEvent = document.createEvent("HTMLEvents");
+				var nativeEvent = target.ownerDocument.createEvent("HTMLEvents");
 				nativeEvent.initEvent(type, !!event.bubbles, !!event.cancelable);
 				// and copy all our properties over
 				for(var i in event){
-					var value = event[i];
 					if(!(i in nativeEvent)){
 						nativeEvent[i] = event[i];
 					}
@@ -310,7 +335,17 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 				var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
 				evt = w.event;
 			}
-			if(!evt){return(evt);}
+			if(!evt){return evt;}
+			try{
+				if(lastEvent && evt.type == lastEvent.type  && evt.srcElement == lastEvent.target){
+					// should be same event, reuse event object (so it can be augmented);
+					// accessing evt.srcElement rather than evt.target since evt.target not set on IE until fixup below
+					evt = lastEvent;
+				}
+			}catch(e){
+				// will occur on IE on lastEvent.type reference if lastEvent points to a previous event that already
+				// finished bubbling, but the setTimeout() to clear lastEvent hasn't fired yet
+			}
 			if(!evt.target){ // check to see if it has been fixed yet
 				evt.target = evt.srcElement;
 				evt.currentTarget = (sender || evt.srcElement);
@@ -345,7 +380,7 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 			}
 			return evt;
 		};
-		var IESignal = function(handle){
+		var lastEvent, IESignal = function(handle){
 			this.handle = handle;
 		};
 		IESignal.prototype.remove = function(){
@@ -355,9 +390,19 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 			// this is a minimal function for closing on the previous listener with as few as variables as possible
 			return function(evt){
 				evt = on._fixEvent(evt, this);
-				return listener.call(this, evt);
-			}
-		}
+				var result = listener.call(this, evt);
+				if(evt.modified){
+					// cache the last event and reuse it if we can
+					if(!lastEvent){
+						setTimeout(function(){
+							lastEvent = null;
+						});
+					}
+					lastEvent = evt;
+				}
+				return result;
+			};
+		};
 		var fixAttach = function(target, type, listener){
 			listener = fixListener(listener);
 			if(((target.ownerDocument ? target.ownerDocument.parentWindow : target.parentWindow || target.window || window) != top || 
@@ -368,18 +413,19 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 				if(typeof _dojoIEListeners_ == "undefined"){
 					_dojoIEListeners_ = [];
 				}
-				var emiter = target[type];
-				if(!emiter || !emiter.listeners){
-					var oldListener = emiter;
-					target[type] = emiter = Function('event', 'var callee = arguments.callee; for(var i = 0; i<callee.listeners.length; i++){var listener = _dojoIEListeners_[callee.listeners[i]]; if(listener){listener.call(this,event);}}');
-					emiter.listeners = [];
-					emiter.global = this;
+				var emitter = target[type];
+				if(!emitter || !emitter.listeners){
+					var oldListener = emitter;
+					emitter = Function('event', 'var callee = arguments.callee; for(var i = 0; i<callee.listeners.length; i++){var listener = _dojoIEListeners_[callee.listeners[i]]; if(listener){listener.call(this,event);}}');
+					emitter.listeners = [];
+					target[type] = emitter;
+					emitter.global = this;
 					if(oldListener){
-						emiter.listeners.push(_dojoIEListeners_.push(oldListener) - 1);
+						emitter.listeners.push(_dojoIEListeners_.push(oldListener) - 1);
 					}
 				}
 				var handle;
-				emiter.listeners.push(handle = (emiter.global._dojoIEListeners_.push(listener) - 1));
+				emitter.listeners.push(handle = (emitter.global._dojoIEListeners_.push(listener) - 1));
 				return new IESignal(handle);
 			}
 			return aspect.after(target, type, listener, true);
@@ -409,17 +455,19 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 				}catch(e){
 				}
 			}
+			this.defaultPrevented = true;
 			this.returnValue = false;
+			this.modified = true; // mark it as modified  (for defaultPrevented flag) so the event will be cached in IE
 		};
 	}
 	if(has("touch")){ 
-		var Event = function (){};
+		var Event = function(){};
 		var windowOrientation = window.orientation; 
 		var fixTouchListener = function(listener){ 
 			return function(originalEvent){ 
 				//Event normalization(for ontouchxxx and resize): 
 				//1.incorrect e.pageX|pageY in iOS 
-				//2.there are no "e.rotation", "e.scale" and "onorientationchange" in Andriod
+				//2.there are no "e.rotation", "e.scale" and "onorientationchange" in Android
 				//3.More TBD e.g. force | screenX | screenX | clientX | clientY | radiusX | radiusY
 
 				// see if it has already been corrected
@@ -431,8 +479,17 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 					}catch(e){} 
 					if(originalEvent.type){
 						// deleting properties doesn't work (older iOS), have to use delegation
-						Event.prototype = originalEvent;
-						var event = new Event;
+						if(has('mozilla')){
+							// Firefox doesn't like delegated properties, so we have to copy
+							var event = {};
+							for(var name in originalEvent){
+								event[name] = originalEvent[name];
+							}
+						}else{
+							// old iOS branch
+							Event.prototype = originalEvent;
+							var event = new Event;
+						}
 						// have to delegate methods to make them work
 						event.preventDefault = function(){
 							originalEvent.preventDefault();
@@ -448,7 +505,7 @@ define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./has"], func
 					originalEvent.corrected = event;
 					if(type == 'resize'){
 						if(windowOrientation == window.orientation){ 
-							return null;//double tap causes an unexpected 'resize' in Andriod 
+							return null;//double tap causes an unexpected 'resize' in Android
 						} 
 						windowOrientation = window.orientation;
 						event.type = "orientationchange"; 
diff --git a/dojo/package.json b/dojo/package.json
index 7618c4d..3840667 100644
--- a/dojo/package.json
+++ b/dojo/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "dojo",
-	"version":"1.7.2",
+	"version":"1.9.1",
 	"directories": {
 		"lib": "."
 	},
diff --git a/dojo/parser.js b/dojo/parser.js
index 4c849a1..46fcde3 100644
--- a/dojo/parser.js
+++ b/dojo/parser.js
@@ -1,149 +1,246 @@
-define(
-	["./_base/kernel", "./_base/lang", "./_base/array", "./_base/html", "./_base/window", "./_base/url",
-		"./_base/json", "./aspect", "./date/stamp", "./query", "./on", "./ready"],
-	function(dojo, dlang, darray, dhtml, dwindow, _Url, djson, aspect, dates, query, don){
-
-// module:
-//		dojo/parser
-// summary:
-//		The Dom/Widget parsing package
-
-new Date("X"); // workaround for #11279, new Date("") == NaN
-
-var features = {
-	// Feature detection for when node.attributes only lists the attributes specified in the markup
-	// rather than old IE/quirks behavior where it lists every default value too
-	"dom-attributes-explicit": document.createElement("div").attributes.length < 40
-};
-function has(feature){
-	return features[feature];
-}
-
-
-dojo.parser = new function(){
-	// summary:
-	//		The Dom/Widget parsing package
-
-	var _nameMap = {
-		// Map from widget name (ex: "dijit.form.Button") to structure mapping
-		// lowercase version of attribute names to the version in the widget ex:
-		//	{
-		//		label: "label",
-		//		onclick: "onClick"
-		//	}
-	};
-	function getNameMap(proto){
-		// summary:
-		//		Returns map from lowercase name to attribute name in class, ex: {onclick: "onClick"}
-		var map = {};
-		for(var name in proto){
-			if(name.charAt(0)=="_"){ continue; }	// skip internal properties
-			map[name.toLowerCase()] = name;
-		}
-		return map;
+define([
+	"require", "./_base/kernel", "./_base/lang", "./_base/array", "./_base/config", "./dom", "./_base/window",
+		"./_base/url", "./aspect", "./promise/all", "./date/stamp", "./Deferred", "./has", "./query", "./on", "./ready"
+], function(require, dojo, dlang, darray, config, dom, dwindow, _Url, aspect, all, dates, Deferred, has, query, don, ready){
+
+	// module:
+	//		dojo/parser
+
+	new Date("X"); // workaround for #11279, new Date("") == NaN
+
+	// data-dojo-props etc. is not restricted to JSON, it can be any javascript
+	function myEval(text){
+		return eval("(" + text + ")");
 	}
+
 	// Widgets like BorderContainer add properties to _Widget via dojo.extend().
 	// If BorderContainer is loaded after _Widget's parameter list has been cached,
 	// we need to refresh that parameter list (for _Widget and all widgets that extend _Widget).
+	var extendCnt = 0;
 	aspect.after(dlang, "extend", function(){
-		_nameMap = {};
+		extendCnt++;
 	}, true);
 
-	// Map from widget name (ex: "dijit.form.Button") to constructor
+	function getNameMap(ctor){
+		// summary:
+		//		Returns map from lowercase name to attribute name in class, ex: {onclick: "onClick"}
+		var map = ctor._nameCaseMap, proto = ctor.prototype;
+
+		// Create the map if it's undefined.
+		// Refresh the map if a superclass was possibly extended with new methods since the map was created.
+		if(!map || map._extendCnt < extendCnt){
+			map = ctor._nameCaseMap = {};
+			for(var name in proto){
+				if(name.charAt(0) === "_"){
+					continue;
+				}	// skip internal properties
+				map[name.toLowerCase()] = name;
+			}
+			map._extendCnt = extendCnt;
+		}
+		return map;
+	}
+
+	// Map from widget name or list of widget names(ex: "dijit/form/Button,acme/MyMixin") to a constructor.
 	var _ctorMap = {};
 
-	this._functionFromScript = function(script, attrData){
+	function getCtor(/*String[]*/ types, /*Function?*/ contextRequire){
 		// summary:
-		//		Convert a <script type="dojo/method" args="a, b, c"> ... </script>
-		//		into a function
-		// script: DOMNode
-		//		The <script> DOMNode
-		// attrData: String
-		//		For HTML5 compliance, searches for attrData + "args" (typically
-		//		"data-dojo-args") instead of "args"
-		var preamble = "";
-		var suffix = "";
-		var argsStr = (script.getAttribute(attrData + "args") || script.getAttribute("args"));
-		if(argsStr){
-			darray.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
-				preamble += "var "+part+" = arguments["+idx+"]; ";
-			});
-		}
-		var withStr = script.getAttribute("with");
-		if(withStr && withStr.length){
-			darray.forEach(withStr.split(/\s*,\s*/), function(part){
-				preamble += "with("+part+"){";
-				suffix += "}";
-			});
+		//		Retrieves a constructor.  If the types array contains more than one class/MID then the
+		//		subsequent classes will be mixed into the first class and a unique constructor will be
+		//		returned for that array.
+
+		var ts = types.join();
+		if(!_ctorMap[ts]){
+			var mixins = [];
+			for(var i = 0, l = types.length; i < l; i++){
+				var t = types[i];
+				// TODO: Consider swapping getObject and require in the future
+				mixins[mixins.length] = (_ctorMap[t] = _ctorMap[t] || (dlang.getObject(t) || (~t.indexOf('/') &&
+					(contextRequire ? contextRequire(t) : require(t)))));
+			}
+			var ctor = mixins.shift();
+			_ctorMap[ts] = mixins.length ? (ctor.createSubclass ? ctor.createSubclass(mixins) : ctor.extend.apply(ctor, mixins)) : ctor;
 		}
-		return new Function(preamble+script.innerHTML+suffix);
-	};
 
-	this.instantiate = /*====== dojo.parser.instantiate= ======*/function(nodes, mixin, args){
+		return _ctorMap[ts];
+	}
+
+	var parser = {
 		// summary:
-		//		Takes array of nodes, and turns them into class instances and
-		//		potentially calls a startup method to allow them to connect with
-		//		any children.
-		// nodes: Array
-		//		Array of nodes or objects like
-		//	|		{
-		//	|			type: "dijit.form.Button",
-		//	|			node: DOMNode,
-		//	|			scripts: [ ... ],	// array of <script type="dojo/..."> children of node
-		//	|			inherited: { ... }	// settings inherited from ancestors like dir, theme, etc.
-		//	|		}
-		// mixin: Object?
-		//		An object that will be mixed in with each node in the array.
-		//		Values in the mixin will override values in the node, if they
-		//		exist.
-		// args: Object?
-		//		An object used to hold kwArgs for instantiation.
-		//		See parse.args argument for details.
-
-		var thelist = [],
-		mixin = mixin||{};
-		args = args||{};
-
-		// Precompute names of special attributes we are looking for
-		// TODO: for 2.0 default to data-dojo- regardless of scopeName (or maybe scopeName won't exist in 2.0)
-		var dojoType = (args.scope || dojo._scopeName) + "Type",		// typically "dojoType"
-			attrData = "data-" + (args.scope || dojo._scopeName) + "-",// typically "data-dojo-"
-			dataDojoType = attrData + "type",						// typically "data-dojo-type"
-			dataDojoProps = attrData + "props",						// typically "data-dojo-props"
-			dataDojoAttachPoint = attrData + "attach-point",
-			dataDojoAttachEvent = attrData + "attach-event",
-			dataDojoId = attrData + "id";
-
-		// And make hash to quickly check if a given attribute is special, and to map the name to something friendly
-		var specialAttrs = {};
-		darray.forEach([dataDojoProps, dataDojoType, dojoType, dataDojoId, "jsId", dataDojoAttachPoint,
-				dataDojoAttachEvent, "dojoAttachPoint", "dojoAttachEvent", "class", "style"], function(name){
-			specialAttrs[name.toLowerCase()] = name.replace(args.scope, "dojo");
-		});
-
-		darray.forEach(nodes, function(obj){
-			if(!obj){ return; }
-
-			var node = obj.node || obj,
-				type = dojoType in mixin ? mixin[dojoType] : obj.node ? obj.type : (node.getAttribute(dataDojoType) || node.getAttribute(dojoType)),
-				ctor = _ctorMap[type] || (_ctorMap[type] = dlang.getObject(type)),
-				proto = ctor && ctor.prototype;
-			if(!ctor){
-				throw new Error("Could not load class '" + type);
+		//		The Dom/Widget parsing package
+
+		_clearCache: function(){
+			// summary:
+			//		Clear cached data.   Used mainly for benchmarking.
+			extendCnt++;
+			_ctorMap = {};
+		},
+
+		_functionFromScript: function(script, attrData){
+			// summary:
+			//		Convert a `<script type="dojo/method" args="a, b, c"> ... </script>`
+			//		into a function
+			// script: DOMNode
+			//		The `<script>` DOMNode
+			// attrData: String
+			//		For HTML5 compliance, searches for attrData + "args" (typically
+			//		"data-dojo-args") instead of "args"
+			var preamble = "",
+				suffix = "",
+				argsStr = (script.getAttribute(attrData + "args") || script.getAttribute("args")),
+				withStr = script.getAttribute("with");
+
+			// Convert any arguments supplied in script tag into an array to be passed to the
+			var fnArgs = (argsStr || "").split(/\s*,\s*/);
+
+			if(withStr && withStr.length){
+				darray.forEach(withStr.split(/\s*,\s*/), function(part){
+					preamble += "with(" + part + "){";
+					suffix += "}";
+				});
+			}
+
+			return new Function(fnArgs, preamble + script.innerHTML + suffix);
+		},
+
+		instantiate: function(nodes, mixin, options){
+			// summary:
+			//		Takes array of nodes, and turns them into class instances and
+			//		potentially calls a startup method to allow them to connect with
+			//		any children.
+			// nodes: Array
+			//		Array of DOM nodes
+			// mixin: Object?
+			//		An object that will be mixed in with each node in the array.
+			//		Values in the mixin will override values in the node, if they
+			//		exist.
+			// options: Object?
+			//		An object used to hold kwArgs for instantiation.
+			//		See parse.options argument for details.
+			// returns:
+			//		Array of instances.
+
+			mixin = mixin || {};
+			options = options || {};
+
+			var dojoType = (options.scope || dojo._scopeName) + "Type", // typically "dojoType"
+				attrData = "data-" + (options.scope || dojo._scopeName) + "-", // typically "data-dojo-"
+				dataDojoType = attrData + "type", // typically "data-dojo-type"
+				dataDojoMixins = attrData + "mixins";					// typically "data-dojo-mixins"
+
+			var list = [];
+			darray.forEach(nodes, function(node){
+				var type = dojoType in mixin ? mixin[dojoType] : node.getAttribute(dataDojoType) || node.getAttribute(dojoType);
+				if(type){
+					var mixinsValue = node.getAttribute(dataDojoMixins),
+						types = mixinsValue ? [type].concat(mixinsValue.split(/\s*,\s*/)) : [type];
+
+					list.push({
+						node: node,
+						types: types
+					});
+				}
+			});
+
+			// Instantiate the nodes and return the list of instances.
+			return this._instantiate(list, mixin, options);
+		},
+
+		_instantiate: function(nodes, mixin, options, returnPromise){
+			// summary:
+			//		Takes array of objects representing nodes, and turns them into class instances and
+			//		potentially calls a startup method to allow them to connect with
+			//		any children.
+			// nodes: Array
+			//		Array of objects like
+			//	|		{
+			//	|			ctor: Function (may be null)
+			//	|			types: ["dijit/form/Button", "acme/MyMixin"] (used if ctor not specified)
+			//	|			node: DOMNode,
+			//	|			scripts: [ ... ],	// array of <script type="dojo/..."> children of node
+			//	|			inherited: { ... }	// settings inherited from ancestors like dir, theme, etc.
+			//	|		}
+			// mixin: Object
+			//		An object that will be mixed in with each node in the array.
+			//		Values in the mixin will override values in the node, if they
+			//		exist.
+			// options: Object
+			//		An options object used to hold kwArgs for instantiation.
+			//		See parse.options argument for details.
+			// returnPromise: Boolean
+			//		Return a Promise rather than the instance; supports asynchronous widget creation.
+			// returns:
+			//		Array of instances, or if returnPromise is true, a promise for array of instances
+			//		that resolves when instances have finished initializing.
+
+			// Call widget constructors.   Some may be asynchronous and return promises.
+			var thelist = darray.map(nodes, function(obj){
+				var ctor = obj.ctor || getCtor(obj.types, options.contextRequire);
+				// If we still haven't resolved a ctor, it is fatal now
+				if(!ctor){
+					throw new Error("Unable to resolve constructor for: '" + obj.types.join() + "'");
+				}
+				return this.construct(ctor, obj.node, mixin, options, obj.scripts, obj.inherited);
+			}, this);
+
+			// After all widget construction finishes, call startup on each top level instance if it makes sense (as for
+			// widgets).  Parent widgets will recursively call startup on their (non-top level) children
+			function onConstruct(thelist){
+				if(!mixin._started && !options.noStart){
+					darray.forEach(thelist, function(instance){
+						if(typeof instance.startup === "function" && !instance._started){
+							instance.startup();
+						}
+					});
+				}
+
+				return thelist;
+			}
+
+			if(returnPromise){
+				return all(thelist).then(onConstruct);
+			}else{
+				// Back-compat path, remove for 2.0
+				return onConstruct(thelist);
 			}
+		},
+
+		construct: function(ctor, node, mixin, options, scripts, inherited){
+			// summary:
+			//		Calls new ctor(params, node), where params is the hash of parameters specified on the node,
+			//		excluding data-dojo-type and data-dojo-mixins.   Does not call startup().
+			// ctor: Function
+			//		Widget constructor.
+			// node: DOMNode
+			//		This node will be replaced/attached to by the widget.  It also specifies the arguments to pass to ctor.
+			// mixin: Object?
+			//		Attributes in this object will be passed as parameters to ctor,
+			//		overriding attributes specified on the node.
+			// options: Object?
+			//		An options object used to hold kwArgs for instantiation.   See parse.options argument for details.
+			// scripts: DomNode[]?
+			//		Array of `<script type="dojo/*">` DOMNodes.  If not specified, will search for `<script>` tags inside node.
+			// inherited: Object?
+			//		Settings from dir=rtl or lang=... on a node above this node.   Overrides options.inherited.
+			// returns:
+			//		Instance or Promise for the instance, if markupFactory() itself returned a promise
+
+			var proto = ctor && ctor.prototype;
+			options = options || {};
 
 			// Setup hash to hold parameter settings for this widget.	Start with the parameter
 			// settings inherited from ancestors ("dir" and "lang").
 			// Inherited setting may later be overridden by explicit settings on node itself.
 			var params = {};
 
-			if(args.defaults){
+			if(options.defaults){
 				// settings for the document itself (or whatever subtree is being parsed)
-				dlang.mixin(params, args.defaults);
+				dlang.mixin(params, options.defaults);
 			}
-			if(obj.inherited){
+			if(inherited){
 				// settings from dir=rtl or lang=... on a node above this node
-				dlang.mixin(params, obj.inherited);
+				dlang.mixin(params, inherited);
 			}
 
 			// Get list of attributes explicitly listed in the markup
@@ -151,10 +248,15 @@ dojo.parser = new function(){
 			if(has("dom-attributes-explicit")){
 				// Standard path to get list of user specified attributes
 				attributes = node.attributes;
+			}else if(has("dom-attributes-specified-flag")){
+				// Special processing needed for IE8, to skip a few faux values in attributes[]
+				attributes = darray.filter(node.attributes, function(a){
+					return a.specified;
+				});
 			}else{
-				// Special path for IE, avoid (sometimes >100) bogus entries in node.attributes
+				// Special path for IE6-7, avoid (sometimes >100) bogus entries in node.attributes
 				var clone = /^input$|^img$/i.test(node.nodeName) ? node : node.cloneNode(false),
-					attrs = clone.outerHTML.replace(/=[^\s"']+|="[^"]*"|='[^']*'/g, "").replace(/^\s*<[a-zA-Z0-9]*/, "").replace(/>.*$/, "");
+					attrs = clone.outerHTML.replace(/=[^\s"']+|="[^"]*"|='[^']*'/g, "").replace(/^\s*<[a-zA-Z0-9]*\s*/, "").replace(/\s*>.*$/, "");
 
 				attributes = darray.map(attrs.split(/\s+/), function(name){
 					var lcName = name.toLowerCase();
@@ -163,63 +265,74 @@ dojo.parser = new function(){
 						// getAttribute() doesn't work for button.value, returns innerHTML of button.
 						// but getAttributeNode().value doesn't work for the form.encType or li.value
 						value: (node.nodeName == "LI" && name == "value") || lcName == "enctype" ?
-								node.getAttribute(lcName) : node.getAttributeNode(lcName).value,
-						specified: true
+							node.getAttribute(lcName) : node.getAttributeNode(lcName).value
 					};
 				});
 			}
 
+			// Hash to convert scoped attribute name (ex: data-dojo17-params) to something friendly (ex: data-dojo-params)
+			// TODO: remove scope for 2.0
+			var scope = options.scope || dojo._scopeName,
+				attrData = "data-" + scope + "-", // typically "data-dojo-"
+				hash = {};
+			if(scope !== "dojo"){
+				hash[attrData + "props"] = "data-dojo-props";
+				hash[attrData + "type"] = "data-dojo-type";
+				hash[attrData + "mixins"] = "data-dojo-mixins";
+				hash[scope + "type"] = "dojoType";
+				hash[attrData + "id"] = "data-dojo-id";
+			}
+
 			// Read in attributes and process them, including data-dojo-props, data-dojo-type,
 			// dojoAttachPoint, etc., as well as normal foo=bar attributes.
-			var i=0, item;
+			var i = 0, item, funcAttrs = [], jsname, extra;
 			while(item = attributes[i++]){
-				if(!item || !item.specified){
-					continue;
-				}
-
 				var name = item.name,
 					lcName = name.toLowerCase(),
 					value = item.value;
 
-				if(lcName in specialAttrs){
-					switch(specialAttrs[lcName]){
+				switch(hash[lcName] || lcName){
+				// Already processed, just ignore
+				case "data-dojo-type":
+				case "dojotype":
+				case "data-dojo-mixins":
+					break;
 
-					// Data-dojo-props.   Save for later to make sure it overrides direct foo=bar settings
-					case "data-dojo-props":
-						var extra = value;
-						break;
+				// Data-dojo-props.   Save for later to make sure it overrides direct foo=bar settings
+				case "data-dojo-props":
+					extra = value;
+					break;
 
-					// data-dojo-id or jsId. TODO: drop jsId in 2.0
-					case "data-dojo-id":
-					case "jsId":
-						var jsname = value;
-						break;
+				// data-dojo-id or jsId. TODO: drop jsId in 2.0
+				case "data-dojo-id":
+				case "jsid":
+					jsname = value;
+					break;
 
-					// For the benefit of _Templated
-					case "data-dojo-attach-point":
-					case "dojoAttachPoint":
-						params.dojoAttachPoint = value;
-						break;
-					case "data-dojo-attach-event":
-					case "dojoAttachEvent":
-						params.dojoAttachEvent = value;
-						break;
+				// For the benefit of _Templated
+				case "data-dojo-attach-point":
+				case "dojoattachpoint":
+					params.dojoAttachPoint = value;
+					break;
+				case "data-dojo-attach-event":
+				case "dojoattachevent":
+					params.dojoAttachEvent = value;
+					break;
 
-					// Special parameter handling needed for IE
-					case "class":
-						params["class"] = node.className;
-						break;
-					case "style":
-						params["style"] = node.style && node.style.cssText;
-						break;
-					}
-				}else{
+				// Special parameter handling needed for IE
+				case "class":
+					params["class"] = node.className;
+					break;
+				case "style":
+					params["style"] = node.style && node.style.cssText;
+					break;
+				default:
 					// Normal attribute, ex: value="123"
 
 					// Find attribute in widget corresponding to specified name.
 					// May involve case conversion, ex: onclick --> onClick
 					if(!(name in proto)){
-						var map = (_nameMap[type] || (_nameMap[type] = getNameMap(proto)));
+						var map = getNameMap(ctor);
 						name = map[lcName] || name;
 					}
 
@@ -241,10 +354,11 @@ dojo.parser = new function(){
 								// The user has specified some text for a function like "return x+5"
 								params[name] = new Function(value);
 							}else{
-								// The user has specified the name of a function like "myOnClick"
+								// The user has specified the name of a global function like "myOnClick"
 								// or a single word function "return"
 								params[name] = dlang.getObject(value, false) || new Function(value);
 							}
+							funcAttrs.push(name);	// prevent "double connect", see #15026
 							break;
 						default:
 							var pVal = proto[name];
@@ -254,8 +368,8 @@ dojo.parser = new function(){
 										(value == "" ? new Date("") :	// the NaN of dates
 										value == "now" ? new Date() :	// current date
 										dates.fromISOString(value)) :
-								(pVal instanceof dojo._Url) ? (dojo.baseUrl + value) :
-								djson.fromJson(value);
+								(pVal instanceof _Url) ? (dojo.baseUrl + value) :
+								myEval(value);
 						}
 					}else{
 						params[name] = value;
@@ -263,10 +377,18 @@ dojo.parser = new function(){
 				}
 			}
 
+			// Remove function attributes from DOMNode to prevent "double connect" problem, see #15026.
+			// Do this as a separate loop since attributes[] is often a live collection (depends on the browser though).
+			for(var j = 0; j < funcAttrs.length; j++){
+				var lcfname = funcAttrs[j].toLowerCase();
+				node.removeAttribute(lcfname);
+				node[lcfname] = null;
+			}
+
 			// Mix things found in data-dojo-props into the params, overriding any direct settings
 			if(extra){
 				try{
-					extra = djson.fromJson.call(args.propsThis, "{" + extra + "}");
+					extra = myEval.call(options.propsThis, "{" + extra + "}");
 					dlang.mixin(params, extra);
 				}catch(e){
 					// give the user a pointer to their invalid parameters. FIXME: can we kill this in production?
@@ -277,41 +399,50 @@ dojo.parser = new function(){
 			// Any parameters specified in "mixin" override everything else.
 			dlang.mixin(params, mixin);
 
-			var scripts = obj.node ? obj.scripts : (ctor && (ctor._noScript || proto._noScript) ? [] :
-						query("> script[type^='dojo/']", node));
+			// Get <script> nodes associated with this widget, if they weren't specified explicitly
+			if(!scripts){
+				scripts = (ctor && (ctor._noScript || proto._noScript) ? [] : query("> script[type^='dojo/']", node));
+			}
 
 			// Process <script type="dojo/*"> script tags
-			// <script type="dojo/method" event="foo"> tags are added to params, and passed to
+			// <script type="dojo/method" data-dojo-event="foo"> tags are added to params, and passed to
 			// the widget on instantiation.
 			// <script type="dojo/method"> tags (with no event) are executed after instantiation
-			// <script type="dojo/connect" data-dojo-event="foo"> tags are dojo.connected after instantiation
+			// <script type="dojo/connect" data-dojo-event="foo"> tags are dojo.connected after instantiation,
+			// and likewise with <script type="dojo/aspect" data-dojo-method="foo">
 			// <script type="dojo/watch" data-dojo-prop="foo"> tags are dojo.watch after instantiation
 			// <script type="dojo/on" data-dojo-event="foo"> tags are dojo.on after instantiation
 			// note: dojo/* script tags cannot exist in self closing widgets, like <input />
-			var connects = [],	// functions to connect after instantiation
+			var aspects = [],	// aspects to connect after instantiation
 				calls = [],		// functions to call after instantiation
-				watch = [],  //functions to watch after instantiation
-				on = []; //functions to on after instantiation
+				watches = [],  // functions to watch after instantiation
+				ons = []; // functions to on after instantiation
 
 			if(scripts){
-				for(i=0; i<scripts.length; i++){
+				for(i = 0; i < scripts.length; i++){
 					var script = scripts[i];
 					node.removeChild(script);
 					// FIXME: drop event="" support in 2.0. use data-dojo-event="" instead
 					var event = (script.getAttribute(attrData + "event") || script.getAttribute("event")),
 						prop = script.getAttribute(attrData + "prop"),
-						type = script.getAttribute("type"),
+						method = script.getAttribute(attrData + "method"),
+						advice = script.getAttribute(attrData + "advice"),
+						scriptType = script.getAttribute("type"),
 						nf = this._functionFromScript(script, attrData);
 					if(event){
-						if(type == "dojo/connect"){
-							connects.push({event: event, func: nf});
-						}else if(type == "dojo/on"){
-							on.push({event: event, func: nf});
+						if(scriptType == "dojo/connect"){
+							aspects.push({ method: event, func: nf });
+						}else if(scriptType == "dojo/on"){
+							ons.push({ event: event, func: nf });
 						}else{
+							// <script type="dojo/method" data-dojo-event="foo">
+							// TODO for 2.0: use data-dojo-method="foo" instead (also affects dijit/Declaration)
 							params[event] = nf;
 						}
-					}else if(type == "dojo/watch"){
-						watch.push({prop: prop, func: nf});
+					}else if(scriptType == "dojo/aspect"){
+						aspects.push({ method: method, advice: advice, func: nf });
+					}else if(scriptType == "dojo/watch"){
+						watches.push({ prop: prop, func: nf });
 					}else{
 						calls.push(nf);
 					}
@@ -321,274 +452,469 @@ dojo.parser = new function(){
 			// create the instance
 			var markupFactory = ctor.markupFactory || proto.markupFactory;
 			var instance = markupFactory ? markupFactory(params, node, ctor) : new ctor(params, node);
-			thelist.push(instance);
 
-			// map it to the JS namespace if that makes sense
-			if(jsname){
-				dlang.setObject(jsname, instance);
-			}
+			function onInstantiate(instance){
+				// map it to the JS namespace if that makes sense
+				if(jsname){
+					dlang.setObject(jsname, instance);
+				}
 
-			// process connections and startup functions
-			for(i=0; i<connects.length; i++){
-				aspect.after(instance, connects[i].event, dojo.hitch(instance, connects[i].func), true);
-			}
-			for(i=0; i<calls.length; i++){
-				calls[i].call(instance);
-			}
-			for(i=0; i<watch.length; i++){
-				instance.watch(watch[i].prop, watch[i].func);
-			}
-			for(i=0; i<on.length; i++){
-				don(instance, on[i].event, on[i].func);
-			}
-		}, this);
-
-		// Call startup on each top level instance if it makes sense (as for
-		// widgets).  Parent widgets will recursively call startup on their
-		// (non-top level) children
-		if(!mixin._started){
-			darray.forEach(thelist, function(instance){
-				if( !args.noStart && instance  &&
-					dlang.isFunction(instance.startup) &&
-					!instance._started
-				){
-					instance.startup();
+				// process connections and startup functions
+				for(i = 0; i < aspects.length; i++){
+					aspect[aspects[i].advice || "after"](instance, aspects[i].method, dlang.hitch(instance, aspects[i].func), true);
+				}
+				for(i = 0; i < calls.length; i++){
+					calls[i].call(instance);
+				}
+				for(i = 0; i < watches.length; i++){
+					instance.watch(watches[i].prop, watches[i].func);
+				}
+				for(i = 0; i < ons.length; i++){
+					don(instance, ons[i].event, ons[i].func);
 				}
-			});
-		}
-		return thelist;
-	};
 
-	this.parse = /*====== dojo.parser.parse= ======*/ function(rootNode, args){
-		// summary:
-		//		Scan the DOM for class instances, and instantiate them.
-		//
-		// description:
-		//		Search specified node (or root node) recursively for class instances,
-		//		and instantiate them. Searches for either data-dojo-type="Class" or
-		//		dojoType="Class" where "Class" is a a fully qualified class name,
-		//		like `dijit.form.Button`
-		//
-		//		Using `data-dojo-type`:
-		//		Attributes using can be mixed into the parameters used to instantiate the
-		//		Class by using a `data-dojo-props` attribute on the node being converted.
-		//		`data-dojo-props` should be a string attribute to be converted from JSON.
-		//
-		//		Using `dojoType`:
-		//		Attributes are read from the original domNode and converted to appropriate
-		//		types by looking up the Class prototype values. This is the default behavior
-		//		from Dojo 1.0 to Dojo 1.5. `dojoType` support is deprecated, and will
-		//		go away in Dojo 2.0.
-		//
-		// rootNode: DomNode?
-		//		A default starting root node from which to start the parsing. Can be
-		//		omitted, defaulting to the entire document. If omitted, the `args`
-		//		object can be passed in this place. If the `args` object has a
-		//		`rootNode` member, that is used.
-		//
-		// args: Object
-		//		a kwArgs object passed along to instantiate()
-		//
-		//			* noStart: Boolean?
-		//				when set will prevent the parser from calling .startup()
-		//				when locating the nodes.
-		//			* rootNode: DomNode?
-		//				identical to the function's `rootNode` argument, though
-		//				allowed to be passed in via this `args object.
-		//			* template: Boolean
-		//				If true, ignores ContentPane's stopParser flag and parses contents inside of
-		//				a ContentPane inside of a template.   This allows dojoAttachPoint on widgets/nodes
-		//				nested inside the ContentPane to work.
-		//			* inherited: Object
-		//				Hash possibly containing dir and lang settings to be applied to
-		//				parsed widgets, unless there's another setting on a sub-node that overrides
-		//			* scope: String
-		//				Root for attribute names to search for.   If scopeName is dojo,
-		//				will search for data-dojo-type (or dojoType).   For backwards compatibility
-		//				reasons defaults to dojo._scopeName (which is "dojo" except when
-		//				multi-version support is used, when it will be something like dojo16, dojo20, etc.)
-		//			* propsThis: Object
-		//				If specified, "this" referenced from data-dojo-props will refer to propsThis.
-		//				Intended for use from the widgets-in-template feature of `dijit._WidgetsInTemplateMixin`
-		//
-		// example:
-		//		Parse all widgets on a page:
-		//	|		dojo.parser.parse();
-		//
-		// example:
-		//		Parse all classes within the node with id="foo"
-		//	|		dojo.parser.parse(dojo.byId('foo'));
-		//
-		// example:
-		//		Parse all classes in a page, but do not call .startup() on any
-		//		child
-		//	|		dojo.parser.parse({ noStart: true })
-		//
-		// example:
-		//		Parse all classes in a node, but do not call .startup()
-		//	|		dojo.parser.parse(someNode, { noStart:true });
-		//	|		// or
-		//	|		dojo.parser.parse({ noStart:true, rootNode: someNode });
-
-		// determine the root node based on the passed arguments.
-		var root;
-		if(!args && rootNode && rootNode.rootNode){
-			args = rootNode;
-			root = args.rootNode;
-		}else{
-			root = rootNode;
-		}
-		root = root ? dhtml.byId(root) : dwindow.body();
-		args = args || {};
-
-		var dojoType = (args.scope || dojo._scopeName) + "Type",		// typically "dojoType"
-			attrData = "data-" + (args.scope || dojo._scopeName) + "-",	// typically "data-dojo-"
-			dataDojoType = attrData + "type",						// typically "data-dojo-type"
-			dataDojoTextDir = attrData + "textdir";					// typically "data-dojo-textdir"
-
-		// List of all nodes on page w/dojoType specified
-		var list = [];
-
-		// Info on DOMNode currently being processed
-		var node = root.firstChild;
-
-		// Info on parent of DOMNode currently being processed
-		//	- inherited: dir, lang, and textDir setting of parent, or inherited by parent
-		//	- parent: pointer to identical structure for my parent (or null if no parent)
-		//	- scripts: if specified, collects <script type="dojo/..."> type nodes from children
-		var inherited = args && args.inherited;
-		if(!inherited){
-			function findAncestorAttr(node, attr){
-				return (node.getAttribute && node.getAttribute(attr)) ||
-					(node !== dwindow.doc && node !== dwindow.doc.documentElement && node.parentNode ? findAncestorAttr(node.parentNode, attr) : null);
+				return instance;
 			}
-			inherited = {
-				dir: findAncestorAttr(root, "dir"),
-				lang: findAncestorAttr(root, "lang"),
-				textDir: findAncestorAttr(root, dataDojoTextDir)
-			};
-			for(var key in inherited){
-				if(!inherited[key]){ delete inherited[key]; }
-			}
-		}
-		var parent = {
-			inherited: inherited
-		};
-
-		// For collecting <script type="dojo/..."> type nodes (when null, we don't need to collect)
-		var scripts;
 
-		// when true, only look for <script type="dojo/..."> tags, and don't recurse to children
-		var scriptsOnly;
+			if(instance.then){
+				return instance.then(onInstantiate);
+			}else{
+				return onInstantiate(instance);
+			}
+		},
 
-		function getEffective(parent){
+		scan: function(root, options){
 			// summary:
-			//		Get effective dir, lang, textDir settings for specified obj
-			//		(matching "parent" object structure above), and do caching.
-			//		Take care not to return null entries.
-			if(!parent.inherited){
-				parent.inherited = {};
-				var node = parent.node,
-					grandparent = getEffective(parent.parent);
-				var inherited  = {
-					dir: node.getAttribute("dir") || grandparent.dir,
-					lang: node.getAttribute("lang") || grandparent.lang,
-					textDir: node.getAttribute(dataDojoTextDir) || grandparent.textDir
+			//		Scan a DOM tree and return an array of objects representing the DOMNodes
+			//		that need to be turned into widgets.
+			// description:
+			//		Search specified node (or document root node) recursively for class instances
+			//		and return an array of objects that represent potential widgets to be
+			//		instantiated. Searches for either data-dojo-type="MID" or dojoType="MID" where
+			//		"MID" is a module ID like "dijit/form/Button" or a fully qualified Class name
+			//		like "dijit/form/Button".  If the MID is not currently available, scan will
+			//		attempt to require() in the module.
+			//
+			//		See parser.parse() for details of markup.
+			// root: DomNode?
+			//		A default starting root node from which to start the parsing. Can be
+			//		omitted, defaulting to the entire document. If omitted, the `options`
+			//		object can be passed in this place. If the `options` object has a
+			//		`rootNode` member, that is used.
+			// options: Object
+			//		a kwArgs options object, see parse() for details
+			//
+			// returns: Promise
+			//		A promise that is resolved with the nodes that have been parsed.
+
+			var list = [], // Output List
+				mids = [], // An array of modules that are not yet loaded
+				midsHash = {}; // Used to keep the mids array unique
+
+			var dojoType = (options.scope || dojo._scopeName) + "Type", // typically "dojoType"
+				attrData = "data-" + (options.scope || dojo._scopeName) + "-", // typically "data-dojo-"
+				dataDojoType = attrData + "type", // typically "data-dojo-type"
+				dataDojoTextDir = attrData + "textdir", // typically "data-dojo-textdir"
+				dataDojoMixins = attrData + "mixins";					// typically "data-dojo-mixins"
+
+			// Info on DOMNode currently being processed
+			var node = root.firstChild;
+
+			// Info on parent of DOMNode currently being processed
+			//	- inherited: dir, lang, and textDir setting of parent, or inherited by parent
+			//	- parent: pointer to identical structure for my parent (or null if no parent)
+			//	- scripts: if specified, collects <script type="dojo/..."> type nodes from children
+			var inherited = options.inherited;
+			if(!inherited){
+				function findAncestorAttr(node, attr){
+					return (node.getAttribute && node.getAttribute(attr)) ||
+						(node.parentNode && findAncestorAttr(node.parentNode, attr));
+				}
+
+				inherited = {
+					dir: findAncestorAttr(root, "dir"),
+					lang: findAncestorAttr(root, "lang"),
+					textDir: findAncestorAttr(root, dataDojoTextDir)
 				};
 				for(var key in inherited){
-					if(inherited[key]){
-						parent.inherited[key] = inherited[key];
+					if(!inherited[key]){
+						delete inherited[key];
 					}
 				}
 			}
-			return parent.inherited;
-		}
 
-		// DFS on DOM tree, collecting nodes with data-dojo-type specified.
-		while(true){
-			if(!node){
-				// Finished this level, continue to parent's next sibling
-				if(!parent || !parent.node){
-					break;
+			// Metadata about parent node
+			var parent = {
+				inherited: inherited
+			};
+
+			// For collecting <script type="dojo/..."> type nodes (when null, we don't need to collect)
+			var scripts;
+
+			// when true, only look for <script type="dojo/..."> tags, and don't recurse to children
+			var scriptsOnly;
+
+			function getEffective(parent){
+				// summary:
+				//		Get effective dir, lang, textDir settings for specified obj
+				//		(matching "parent" object structure above), and do caching.
+				//		Take care not to return null entries.
+				if(!parent.inherited){
+					parent.inherited = {};
+					var node = parent.node,
+						grandparent = getEffective(parent.parent);
+					var inherited = {
+						dir: node.getAttribute("dir") || grandparent.dir,
+						lang: node.getAttribute("lang") || grandparent.lang,
+						textDir: node.getAttribute(dataDojoTextDir) || grandparent.textDir
+					};
+					for(var key in inherited){
+						if(inherited[key]){
+							parent.inherited[key] = inherited[key];
+						}
+					}
 				}
-				node = parent.node.nextSibling;
-				scripts = parent.scripts;
-				scriptsOnly = false;
-				parent = parent.parent;
-				continue;
+				return parent.inherited;
 			}
 
-			if(node.nodeType != 1){
-				// Text or comment node, skip to next sibling
-				node = node.nextSibling;
-				continue;
-			}
+			// DFS on DOM tree, collecting nodes with data-dojo-type specified.
+			while(true){
+				if(!node){
+					// Finished this level, continue to parent's next sibling
+					if(!parent || !parent.node){
+						break;
+					}
+					node = parent.node.nextSibling;
+					scriptsOnly = false;
+					parent = parent.parent;
+					scripts = parent.scripts;
+					continue;
+				}
+
+				if(node.nodeType != 1){
+					// Text or comment node, skip to next sibling
+					node = node.nextSibling;
+					continue;
+				}
+
+				if(scripts && node.nodeName.toLowerCase() == "script"){
+					// Save <script type="dojo/..."> for parent, then continue to next sibling
+					type = node.getAttribute("type");
+					if(type && /^dojo\/\w/i.test(type)){
+						scripts.push(node);
+					}
+					node = node.nextSibling;
+					continue;
+				}
+				if(scriptsOnly){
+					// scriptsOnly flag is set, we have already collected scripts if the parent wants them, so now we shouldn't
+					// continue further analysis of the node and will continue to the next sibling
+					node = node.nextSibling;
+					continue;
+				}
 
-			if(scripts && node.nodeName.toLowerCase() == "script"){
-				// Save <script type="dojo/..."> for parent, then continue to next sibling
-				type = node.getAttribute("type");
-				if(type && /^dojo\/\w/i.test(type)){
-					scripts.push(node);
+				// Check for data-dojo-type attribute, fallback to backward compatible dojoType
+				// TODO: Remove dojoType in 2.0
+				var type = node.getAttribute(dataDojoType) || node.getAttribute(dojoType);
+
+				// Short circuit for leaf nodes containing nothing [but text]
+				var firstChild = node.firstChild;
+				if(!type && (!firstChild || (firstChild.nodeType == 3 && !firstChild.nextSibling))){
+					node = node.nextSibling;
+					continue;
 				}
-				node = node.nextSibling;
-				continue;
+
+				// Meta data about current node
+				var current;
+
+				var ctor = null;
+				if(type){
+					// If dojoType/data-dojo-type specified, add to output array of nodes to instantiate.
+					var mixinsValue = node.getAttribute(dataDojoMixins),
+						types = mixinsValue ? [type].concat(mixinsValue.split(/\s*,\s*/)) : [type];
+
+					// Note: won't find classes declared via dojo/Declaration or any modules that haven't been
+					// loaded yet so use try/catch to avoid throw from require()
+					try{
+						ctor = getCtor(types, options.contextRequire);
+					}catch(e){}
+
+					// If the constructor was not found, check to see if it has modules that can be loaded
+					if(!ctor){
+						darray.forEach(types, function(t){
+							if(~t.indexOf('/') && !midsHash[t]){
+								// If the type looks like a MID and it currently isn't in the array of MIDs to load, add it.
+								midsHash[t] = true;
+								mids[mids.length] = t;
+							}
+						});
+					}
+
+					var childScripts = ctor && !ctor.prototype._noScript ? [] : null; // <script> nodes that are parent's children
+
+					// Setup meta data about this widget node, and save it to list of nodes to instantiate
+					current = {
+						types: types,
+						ctor: ctor,
+						parent: parent,
+						node: node,
+						scripts: childScripts
+					};
+					current.inherited = getEffective(current); // dir & lang settings for current node, explicit or inherited
+					list.push(current);
+				}else{
+					// Meta data about this non-widget node
+					current = {
+						node: node,
+						scripts: scripts,
+						parent: parent
+					};
+				}
+
+				// Recurse, collecting <script type="dojo/..."> children, and also looking for
+				// descendant nodes with dojoType specified (unless the widget has the stopParser flag).
+				// When finished with children, go to my next sibling.
+				scripts = childScripts;
+				scriptsOnly = node.stopParser || (ctor && ctor.prototype.stopParser && !(options.template));
+				parent = current;
+				node = firstChild;
 			}
-			if(scriptsOnly){
-				node = node.nextSibling;
-				continue;
+
+			var d = new Deferred();
+
+			// If there are modules to load then require them in
+			if(mids.length){
+				// Warn that there are modules being auto-required
+				if(has("dojo-debug-messages")){
+					console.warn("WARNING: Modules being Auto-Required: " + mids.join(", "));
+				}
+				var r = options.contextRequire || require;
+				r(mids, function(){
+					// Go through list of widget nodes, filling in missing constructors, and filtering out nodes that shouldn't
+					// be instantiated due to a stopParser flag on an ancestor that we belatedly learned about due to
+					// auto-require of a module like ContentPane.   Assumes list is in DFS order.
+					d.resolve(darray.filter(list, function(widget){
+						if(!widget.ctor){
+							// Attempt to find the constructor again.   Still won't find classes defined via
+							// dijit/Declaration so need to try/catch.
+							try{
+								widget.ctor = getCtor(widget.types, options.contextRequire);
+							}catch(e){}
+						}
+
+						// Get the parent widget
+						var parent = widget.parent;
+						while(parent && !parent.types){
+							parent = parent.parent;
+						}
+
+						// Return false if this node should be skipped due to stopParser on an ancestor.
+						// Since list[] is in DFS order, this loop will always set parent.instantiateChildren before
+						// trying to compute widget.instantiate.
+						var proto = widget.ctor && widget.ctor.prototype;
+						widget.instantiateChildren = !(proto && proto.stopParser && !(options.template));
+						widget.instantiate = !parent || (parent.instantiate && parent.instantiateChildren);
+						return widget.instantiate;
+					}));
+				});
+			}else{
+				// There were no modules to load, so just resolve with the parsed nodes.   This separate code path is for
+				// efficiency, to avoid running the require() and the callback code above.
+				d.resolve(list);
 			}
 
-			// Check for data-dojo-type attribute, fallback to backward compatible dojoType
-			var type = node.getAttribute(dataDojoType) || node.getAttribute(dojoType);
+			// Return the promise
+			return d.promise;
+		},
 
-			// Short circuit for leaf nodes containing nothing [but text]
-			var firstChild = node.firstChild;
-			if(!type && (!firstChild || (firstChild.nodeType == 3 && !firstChild.nextSibling))){
-				node = node.nextSibling;
-				continue;
+		_require: function(/*DOMNode*/ script, /*Object?*/ options){
+			// summary:
+			//		Helper for _scanAMD().  Takes a `<script type=dojo/require>bar: "acme/bar", ...</script>` node,
+			//		calls require() to load the specified modules and (asynchronously) assign them to the specified global
+			//		variables, and returns a Promise for when that operation completes.
+			//
+			//		In the example above, it is effectively doing a require(["acme/bar", ...], function(a){ bar = a; }).
+
+			var hash = myEval("{" + script.innerHTML + "}"), // can't use dojo/json::parse() because maybe no quotes
+				vars = [],
+				mids = [],
+				d = new Deferred();
+
+			var contextRequire = (options && options.contextRequire) || require;
+
+			for(var name in hash){
+				vars.push(name);
+				mids.push(hash[name]);
 			}
 
-			// Setup data structure to save info on current node for when we return from processing descendant nodes
-			var current = {
-				node: node,
-				scripts: scripts,
-				parent: parent
-			};
+			contextRequire(mids, function(){
+				for(var i = 0; i < vars.length; i++){
+					dlang.setObject(vars[i], arguments[i]);
+				}
+				d.resolve(arguments);
+			});
+
+			return d.promise;
+		},
 
-			// If dojoType/data-dojo-type specified, add to output array of nodes to instantiate
-			var ctor = type && (_ctorMap[type] || (_ctorMap[type] = dlang.getObject(type))), // note: won't find classes declared via dojo.Declaration
-				childScripts = ctor && !ctor.prototype._noScript ? [] : null; // <script> nodes that are parent's children
-			if(type){
-				list.push({
-					"type": type,
-					node: node,
-					scripts: childScripts,
-					inherited: getEffective(current) // dir & lang settings for current node, explicit or inherited
+		_scanAmd: function(root, options){
+			// summary:
+			//		Scans the DOM for any declarative requires and returns their values.
+			// description:
+			//		Looks for `<script type=dojo/require>bar: "acme/bar", ...</script>` node, calls require() to load the
+			//		specified modules and (asynchronously) assign them to the specified global variables,
+			//		and returns a Promise for when those operations complete.
+			// root: DomNode
+			//		The node to base the scan from.
+			// options: Object?
+			//		a kwArgs options object, see parse() for details
+
+			// Promise that resolves when all the <script type=dojo/require> nodes have finished loading.
+			var deferred = new Deferred(),
+				promise = deferred.promise;
+			deferred.resolve(true);
+
+			var self = this;
+			query("script[type='dojo/require']", root).forEach(function(node){
+				// Fire off require() call for specified modules.  Chain this require to fire after
+				// any previous requires complete, so that layers can be loaded before individual module require()'s fire.
+				promise = promise.then(function(){
+					return self._require(node, options);
 				});
-			}
 
-			// Recurse, collecting <script type="dojo/..."> children, and also looking for
-			// descendant nodes with dojoType specified (unless the widget has the stopParser flag).
-			// When finished with children, go to my next sibling.
-			node = firstChild;
-			scripts = childScripts;
-			scriptsOnly = ctor && ctor.prototype.stopParser && !(args && args.template);
-			parent = current;
+				// Remove from DOM so it isn't seen again
+				node.parentNode.removeChild(node);
+			});
 
-		}
+			return promise;
+		},
 
-		// go build the object instances
-		var mixin = args && args.template ? {template: true} : null;
-		return this.instantiate(list, mixin, args); // Array
+		parse: function(rootNode, options){
+			// summary:
+			//		Scan the DOM for class instances, and instantiate them.
+			// description:
+			//		Search specified node (or root node) recursively for class instances,
+			//		and instantiate them. Searches for either data-dojo-type="Class" or
+			//		dojoType="Class" where "Class" is a a fully qualified class name,
+			//		like `dijit/form/Button`
+			//
+			//		Using `data-dojo-type`:
+			//		Attributes using can be mixed into the parameters used to instantiate the
+			//		Class by using a `data-dojo-props` attribute on the node being converted.
+			//		`data-dojo-props` should be a string attribute to be converted from JSON.
+			//
+			//		Using `dojoType`:
+			//		Attributes are read from the original domNode and converted to appropriate
+			//		types by looking up the Class prototype values. This is the default behavior
+			//		from Dojo 1.0 to Dojo 1.5. `dojoType` support is deprecated, and will
+			//		go away in Dojo 2.0.
+			// rootNode: DomNode?
+			//		A default starting root node from which to start the parsing. Can be
+			//		omitted, defaulting to the entire document. If omitted, the `options`
+			//		object can be passed in this place. If the `options` object has a
+			//		`rootNode` member, that is used.
+			// options: Object?
+			//		A hash of options.
+			//
+			//		- noStart: Boolean?:
+			//			when set will prevent the parser from calling .startup()
+			//			when locating the nodes.
+			//		- rootNode: DomNode?:
+			//			identical to the function's `rootNode` argument, though
+			//			allowed to be passed in via this `options object.
+			//		- template: Boolean:
+			//			If true, ignores ContentPane's stopParser flag and parses contents inside of
+			//			a ContentPane inside of a template.   This allows dojoAttachPoint on widgets/nodes
+			//			nested inside the ContentPane to work.
+			//		- inherited: Object:
+			//			Hash possibly containing dir and lang settings to be applied to
+			//			parsed widgets, unless there's another setting on a sub-node that overrides
+			//		- scope: String:
+			//			Root for attribute names to search for.   If scopeName is dojo,
+			//			will search for data-dojo-type (or dojoType).   For backwards compatibility
+			//			reasons defaults to dojo._scopeName (which is "dojo" except when
+			//			multi-version support is used, when it will be something like dojo16, dojo20, etc.)
+			//		- propsThis: Object:
+			//			If specified, "this" referenced from data-dojo-props will refer to propsThis.
+			//			Intended for use from the widgets-in-template feature of `dijit._WidgetsInTemplateMixin`
+			//		- contextRequire: Function:
+			//			If specified, this require is utilised for looking resolving modules instead of the
+			//			`dojo/parser` context `require()`.  Intended for use from the widgets-in-template feature of
+			//			`dijit._WidgetsInTemplateMixin`.
+			// returns: Mixed
+			//		Returns a blended object that is an array of the instantiated objects, but also can include
+			//		a promise that is resolved with the instantiated objects.  This is done for backwards
+			//		compatibility.  If the parser auto-requires modules, it will always behave in a promise
+			//		fashion and `parser.parse().then(function(instances){...})` should be used.
+			// example:
+			//		Parse all widgets on a page:
+			//	|		parser.parse();
+			// example:
+			//		Parse all classes within the node with id="foo"
+			//	|		parser.parse(dojo.byId('foo'));
+			// example:
+			//		Parse all classes in a page, but do not call .startup() on any
+			//		child
+			//	|		parser.parse({ noStart: true })
+			// example:
+			//		Parse all classes in a node, but do not call .startup()
+			//	|		parser.parse(someNode, { noStart:true });
+			//	|		// or
+			//	|		parser.parse({ noStart:true, rootNode: someNode });
+
+			// determine the root node and options based on the passed arguments.
+			var root;
+			if(!options && rootNode && rootNode.rootNode){
+				options = rootNode;
+				root = options.rootNode;
+			}else if(rootNode && dlang.isObject(rootNode) && !("nodeType" in rootNode)){
+				options = rootNode;
+			}else{
+				root = rootNode;
+			}
+			root = root ? dom.byId(root) : dwindow.body();
+
+			options = options || {};
+
+			var mixin = options.template ? { template: true } : {},
+				instances = [],
+				self = this;
+
+			// First scan for any <script type=dojo/require> nodes, and execute.
+			// Then scan for all nodes with data-dojo-type, and load any unloaded modules.
+			// Then build the object instances.  Add instances to already existing (but empty) instances[] array,
+			// which may already have been returned to caller.  Also, use otherwise to collect and throw any errors
+			// that occur during the parse().
+			var p =
+				this._scanAmd(root, options).then(function(){
+					return self.scan(root, options);
+				}).then(function(parsedNodes){
+					return self._instantiate(parsedNodes, mixin, options, true);
+				}).then(function(_instances){
+					// Copy the instances into the instances[] array we declared above, and are accessing as
+					// our return value.
+					return instances = instances.concat(_instances);
+				}).otherwise(function(e){
+					// TODO Modify to follow better pattern for promise error management when available
+					console.error("dojo/parser::parse() error", e);
+					throw e;
+				});
+
+			// Blend the array with the promise
+			dlang.mixin(instances, p);
+			return instances;
+		}
 	};
-}();
 
+	if(has("extend-dojo")){
+		dojo.parser = parser;
+	}
 
-//Register the parser callback. It should be the first callback
-//after the a11y test.
-if(dojo.config.parseOnLoad){
-	dojo.ready(100, dojo.parser, "parse");
-}
+	// Register the parser callback. It should be the first callback
+	// after the a11y test.
+	if(config.parseOnLoad){
+		ready(100, parser, "parse");
+	}
 
-return dojo.parser;
+	return parser;
 });
diff --git a/dojo/promise/Promise.js b/dojo/promise/Promise.js
new file mode 100644
index 0000000..d961542
--- /dev/null
+++ b/dojo/promise/Promise.js
@@ -0,0 +1,133 @@
+define([
+	"../_base/lang"
+], function(lang){
+	"use strict";
+
+	// module:
+	//		dojo/promise/Promise
+
+	function throwAbstract(){
+		throw new TypeError("abstract");
+	}
+
+	return lang.extend(function Promise(){
+		// summary:
+		//		The public interface to a deferred.
+		// description:
+		//		The public interface to a deferred. All promises in Dojo are
+		//		instances of this class.
+	}, {
+		then: function(callback, errback, progback){
+			// summary:
+			//		Add new callbacks to the promise.
+			// description:
+			//		Add new callbacks to the deferred. Callbacks can be added
+			//		before or after the deferred is fulfilled.
+			// callback: Function?
+			//		Callback to be invoked when the promise is resolved.
+			//		Receives the resolution value.
+			// errback: Function?
+			//		Callback to be invoked when the promise is rejected.
+			//		Receives the rejection error.
+			// progback: Function?
+			//		Callback to be invoked when the promise emits a progress
+			//		update. Receives the progress update.
+			// returns: dojo/promise/Promise
+			//		Returns a new promise for the result of the callback(s).
+			//		This can be used for chaining many asynchronous operations.
+
+			throwAbstract();
+		},
+
+		cancel: function(reason, strict){
+			// summary:
+			//		Inform the deferred it may cancel its asynchronous operation.
+			// description:
+			//		Inform the deferred it may cancel its asynchronous operation.
+			//		The deferred's (optional) canceler is invoked and the
+			//		deferred will be left in a rejected state. Can affect other
+			//		promises that originate with the same deferred.
+			// reason: any
+			//		A message that may be sent to the deferred's canceler,
+			//		explaining why it's being canceled.
+			// strict: Boolean?
+			//		If strict, will throw an error if the deferred has already
+			//		been fulfilled and consequently cannot be canceled.
+			// returns: any
+			//		Returns the rejection reason if the deferred was canceled
+			//		normally.
+
+			throwAbstract();
+		},
+
+		isResolved: function(){
+			// summary:
+			//		Checks whether the promise has been resolved.
+			// returns: Boolean
+
+			throwAbstract();
+		},
+
+		isRejected: function(){
+			// summary:
+			//		Checks whether the promise has been rejected.
+			// returns: Boolean
+
+			throwAbstract();
+		},
+
+		isFulfilled: function(){
+			// summary:
+			//		Checks whether the promise has been resolved or rejected.
+			// returns: Boolean
+
+			throwAbstract();
+		},
+
+		isCanceled: function(){
+			// summary:
+			//		Checks whether the promise has been canceled.
+			// returns: Boolean
+
+			throwAbstract();
+		},
+
+		always: function(callbackOrErrback){
+			// summary:
+			//		Add a callback to be invoked when the promise is resolved
+			//		or rejected.
+			// callbackOrErrback: Function?
+			//		A function that is used both as a callback and errback.
+			// returns: dojo/promise/Promise
+			//		Returns a new promise for the result of the callback/errback.
+
+			return this.then(callbackOrErrback, callbackOrErrback);
+		},
+
+		otherwise: function(errback){
+			// summary:
+			//		Add new errbacks to the promise.
+			// errback: Function?
+			//		Callback to be invoked when the promise is rejected.
+			// returns: dojo/promise/Promise
+			//		Returns a new promise for the result of the errback.
+
+			return this.then(null, errback);
+		},
+
+		trace: function(){
+			return this;
+		},
+
+		traceRejected: function(){
+			return this;
+		},
+
+		toString: function(){
+			// returns: string
+			//		Returns `[object Promise]`.
+
+			return "[object Promise]";
+		}
+	});
+});
diff --git a/dojo/promise/all.js b/dojo/promise/all.js
new file mode 100644
index 0000000..a3bd7c4
--- /dev/null
+++ b/dojo/promise/all.js
@@ -0,0 +1,76 @@
+define([
+	"../_base/array",
+	"../Deferred",
+	"../when"
+], function(array, Deferred, when){
+	"use strict";
+
+	// module:
+	//		dojo/promise/all
+
+	var some = array.some;
+
+	return function all(objectOrArray){
+		// summary:
+		//		Takes multiple promises and returns a new promise that is fulfilled
+		//		when all promises have been fulfilled.
+		// description:
+		//		Takes multiple promises and returns a new promise that is fulfilled
+		//		when all promises have been fulfilled. If one of the promises is rejected,
+		//		the returned promise is also rejected. Canceling the returned promise will
+		//		*not* cancel any passed promises.
+		// objectOrArray: Object|Array?
+		//		The promise will be fulfilled with a list of results if invoked with an
+		//		array, or an object of results when passed an object (using the same
+		//		keys). If passed neither an object or array it is resolved with an
+		//		undefined value.
+		// returns: dojo/promise/Promise
+
+		var object, array;
+		if(objectOrArray instanceof Array){
+			array = objectOrArray;
+		}else if(objectOrArray && typeof objectOrArray === "object"){
+			object = objectOrArray;
+		}
+
+		var results;
+		var keyLookup = [];
+		if(object){
+			array = [];
+			for(var key in object){
+				if(Object.hasOwnProperty.call(object, key)){
+					keyLookup.push(key);
+					array.push(object[key]);
+				}
+			}
+			results = {};
+		}else if(array){
+			results = [];
+		}
+
+		if(!array || !array.length){
+			return new Deferred().resolve(results);
+		}
+
+		var deferred = new Deferred();
+		deferred.promise.always(function(){
+			results = keyLookup = null;
+		});
+		var waiting = array.length;
+		some(array, function(valueOrPromise, index){
+			if(!object){
+				keyLookup.push(index);
+			}
+			when(valueOrPromise, function(value){
+				if(!deferred.isFulfilled()){
+					results[keyLookup[index]] = value;
+					if(--waiting === 0){
+						deferred.resolve(results);
+					}
+				}
+			}, deferred.reject);
+			return deferred.isFulfilled();
+		});
+		return deferred.promise;	// dojo/promise/Promise
+	};
+});
diff --git a/dojo/promise/first.js b/dojo/promise/first.js
new file mode 100644
index 0000000..0df9dfc
--- /dev/null
+++ b/dojo/promise/first.js
@@ -0,0 +1,49 @@
+define([
+	"../_base/array",
+	"../Deferred",
+	"../when"
+], function(array, Deferred, when){
+	"use strict";
+
+	// module:
+	//		dojo/promise/first
+
+	var forEach = array.forEach;
+
+	return function first(objectOrArray){
+		// summary:
+		//		Takes multiple promises and returns a new promise that is fulfilled
+		//		when the first of these promises is fulfilled.
+		// description:
+		//		Takes multiple promises and returns a new promise that is fulfilled
+		//		when the first of these promises is fulfilled. Canceling the returned
+		//		promise will *not* cancel any passed promises. The promise will be
+		//		fulfilled with the value of the first fulfilled promise.
+		// objectOrArray: Object|Array?
+		//		The promises are taken from the array or object values. If no value
+		//		is passed, the returned promise is resolved with an undefined value.
+		// returns: dojo/promise/Promise
+
+		var array;
+		if(objectOrArray instanceof Array){
+			array = objectOrArray;
+		}else if(objectOrArray && typeof objectOrArray === "object"){
+			array = [];
+			for(var key in objectOrArray){
+				if(Object.hasOwnProperty.call(objectOrArray, key)){
+					array.push(objectOrArray[key]);
+				}
+			}
+		}
+
+		if(!array || !array.length){
+			return new Deferred().resolve();
+		}
+
+		var deferred = new Deferred();
+		forEach(array, function(valueOrPromise){
+			when(valueOrPromise, deferred.resolve, deferred.reject);
+		});
+		return deferred.promise;	// dojo/promise/Promise
+	};
+});
diff --git a/dojo/promise/instrumentation.js b/dojo/promise/instrumentation.js
new file mode 100644
index 0000000..409f1a9
--- /dev/null
+++ b/dojo/promise/instrumentation.js
@@ -0,0 +1,105 @@
+define([
+	"./tracer",
+	"../has",
+	"../_base/lang",
+	"../_base/array"
+], function(tracer, has, lang, arrayUtil){
+	function logError(error, rejection, deferred){
+		var stack = "";
+		if(error && error.stack){
+			stack += error.stack;
+		}
+		if(rejection && rejection.stack){
+			stack += "\n    ----------------------------------------\n    rejected" + rejection.stack.split("\n").slice(1).join("\n").replace(/^\s+/, " ");
+		}
+		if(deferred && deferred.stack){
+			stack += "\n    ----------------------------------------\n" + deferred.stack;
+		}
+		console.error(error, stack);
+	}
+
+	function reportRejections(error, handled, rejection, deferred){
+		if(!handled){
+			logError(error, rejection, deferred);
+		}
+	}
+
+	var errors = [];
+	var activeTimeout = false;
+	var unhandledWait = 1000;
+	function trackUnhandledRejections(error, handled, rejection, deferred){
+		if(handled){
+			arrayUtil.some(errors, function(obj, ix){
+				if(obj.error === error){
+					errors.splice(ix, 1);
+					return true;
+				}
+			});
+		}else if(!arrayUtil.some(errors, function(obj){ return obj.error === error; })){
+			errors.push({
+				error: error,
+				rejection: rejection,
+				deferred: deferred,
+				timestamp: new Date().getTime()
+			});
+		}
+
+		if(!activeTimeout){
+			activeTimeout = setTimeout(logRejected, unhandledWait);
+		}
+	}
+
+	function logRejected(){
+		var now = new Date().getTime();
+		var reportBefore = now - unhandledWait;
+		errors = arrayUtil.filter(errors, function(obj){
+			if(obj.timestamp < reportBefore){
+				logError(obj.error, obj.rejection, obj.deferred);
+				return false;
+			}
+			return true;
+		});
+
+		if(errors.length){
+			activeTimeout = setTimeout(logRejected, errors[0].timestamp + unhandledWait - now);
+		}else{
+			activeTimeout = false;
+		}
+	}
+
+	return function(Deferred){
+		// summary:
+		//		Initialize instrumentation for the Deferred class.
+		// description:
+		//		Initialize instrumentation for the Deferred class.
+		//		Done automatically by `dojo/Deferred` if the
+		//		`deferredInstrumentation` and `useDeferredInstrumentation`
+		//		config options are set.
+		//
+		//		Sets up `dojo/promise/tracer` to log to the console.
+		//
+		//		Sets up instrumentation of rejected deferreds so unhandled
+		//		errors are logged to the console.
+
+		var usage = has("config-useDeferredInstrumentation");
+		if(usage){
+			tracer.on("resolved", lang.hitch(console, "log", "resolved"));
+			tracer.on("rejected", lang.hitch(console, "log", "rejected"));
+			tracer.on("progress", lang.hitch(console, "log", "progress"));
+
+			var args = [];
+			if(typeof usage === "string"){
+				args = usage.split(",");
+				usage = args.shift();
+			}
+			if(usage === "report-rejections"){
+				Deferred.instrumentRejected = reportRejections;
+			}else if(usage === "report-unhandled-rejections" || usage === true || usage === 1){
+				Deferred.instrumentRejected = trackUnhandledRejections;
+				unhandledWait = parseInt(args[0], 10) || unhandledWait;
+			}else{
+				throw new Error("Unsupported instrumentation usage <" + usage + ">");
+			}
+		}
+	};
+});
diff --git a/dojo/promise/tracer.js b/dojo/promise/tracer.js
new file mode 100644
index 0000000..7c277c8
--- /dev/null
+++ b/dojo/promise/tracer.js
@@ -0,0 +1,85 @@
+define([
+	"../_base/lang",
+	"./Promise",
+	"../Evented"
+], function(lang, Promise, Evented){
+	"use strict";
+
+	// module:
+	//		dojo/promise/tracer
+
+	/*=====
+	return {
+		// summary:
+		//		Trace promise fulfillment.
+		// description:
+		//		Trace promise fulfillment. Calling `.trace()` or `.traceError()` on a
+		//		promise enables tracing. Will emit `resolved`, `rejected` or `progress`
+		//		events.
+
+		on: function(type, listener){
+			// summary:
+			//		Subscribe to traces.
+			// description:
+			//		See `dojo/Evented#on()`.
+			// type: String
+			//		`resolved`, `rejected`, or `progress`
+			// listener: Function
+			//		The listener is passed the traced value and any arguments
+			//		that were used with the `.trace()` call.
+		}
+	};
+	=====*/
+
+	var evented = new Evented;
+	var emit = evented.emit;
+	evented.emit = null;
+	// Emit events asynchronously since they should not change the promise state.
+	function emitAsync(args){
+		setTimeout(function(){
+			emit.apply(evented, args);
+		}, 0);
+	}
+
+	Promise.prototype.trace = function(){
+		// summary:
+		//		Trace the promise.
+		// description:
+		//		Tracing allows you to transparently log progress,
+		//		resolution and rejection of promises, without affecting the
+		//		promise itself. Any arguments passed to `trace()` are
+		//		emitted in trace events. See `dojo/promise/tracer` on how
+		//		to handle traces.
+		// returns: dojo/promise/Promise
+		//		The promise instance `trace()` is called on.
+
+		var args = lang._toArray(arguments);
+		this.then(
+			function(value){ emitAsync(["resolved", value].concat(args)); },
+			function(error){ emitAsync(["rejected", error].concat(args)); },
+			function(update){ emitAsync(["progress", update].concat(args)); }
+		);
+		return this;
+	};
+
+	Promise.prototype.traceRejected = function(){
+		// summary:
+		//		Trace rejection of the promise.
+		// description:
+		//		Tracing allows you to transparently log progress,
+		//		resolution and rejection of promises, without affecting the
+		//		promise itself. Any arguments passed to `trace()` are
+		//		emitted in trace events. See `dojo/promise/tracer` on how
+		//		to handle traces.
+		// returns: dojo/promise/Promise
+		//		The promise instance `traceRejected()` is called on.
+
+		var args = lang._toArray(arguments);
+		this.otherwise(function(error){
+			emitAsync(["rejected", error].concat(args));
+		});
+		return this;
+	};
+
+	return evented;
+});
diff --git a/dojo/query.js b/dojo/query.js
index 4685e81..d334a95 100644
--- a/dojo/query.js
+++ b/dojo/query.js
@@ -1,6 +1,7 @@
 define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/lang", "./selector/_loader", "./selector/_loader!default"],
 	function(dojo, has, dom, on, array, lang, loader, defaultEngine){
-"use strict";
+
+	"use strict";
 
 	has.add("array-extensible", function(){
 		// test to see if we can extend an array (not supported in old IE)
@@ -9,9 +10,9 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 	
 	var ap = Array.prototype, aps = ap.slice, apc = ap.concat, forEach = array.forEach;
 
-	var tnl = function(/*Array*/ a, /*dojo.NodeList?*/ parent, /*Function?*/ NodeListCtor){
+	var tnl = function(/*Array*/ a, /*dojo/NodeList?*/ parent, /*Function?*/ NodeListCtor){
 		// summary:
-		//		decorate an array to make it look like a `dojo.NodeList`.
+		//		decorate an array to make it look like a `dojo/NodeList`.
 		// a:
 		//		Array of nodes to decorate.
 		// parent:
@@ -21,7 +22,7 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 		// NodeListCtor:
 		//		An optional constructor function to use for any
 		//		new NodeList calls. This allows a certain chain of
-		//		NodeList calls to use a different object than dojo.NodeList.
+		//		NodeList calls to use a different object than dojo/NodeList.
 		var nodeList = new (NodeListCtor || this._NodeListCtor || nl)(a);
 		return parent ? nodeList._stash(parent) : nodeList;
 	};
@@ -99,12 +100,12 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 
 	var NodeList = function(array){
 		// summary:
-		//		dojo.NodeList is an of Array-like object which adds syntactic
+		//		Array-like object which adds syntactic
 		//		sugar for chaining, common iteration operations, animation, and
 		//		node manipulation. NodeLists are most often returned as the
 		//		result of dojo.query() calls.
 		// description:
-		//		dojo.NodeList instances provide many utilities that reflect
+		//		NodeList instances provide many utilities that reflect
 		//		core Dojo APIs for Array iteration and manipulation, DOM
 		//		manipulation, and event handling. Instead of needing to dig up
 		//		functions in the dojo.* namespace, NodeLists generally make the
@@ -112,7 +113,7 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 		//		simple, chainable way.
 		// example:
 		//		create a node list from a node
-		//		|	new dojo.NodeList(dojo.byId("foo"));
+		//		|	new query.NodeList(dojo.byId("foo"));
 		// example:
 		//		get a NodeList from a CSS query and iterate on it
 		//		|	var l = dojo.query(".thinger");
@@ -149,8 +150,7 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 		//		|	// even getting the coordinates of all the items
 		//		|	var coords = dojo.query(".thinger").coords();
 		// example:
-		//		DOM manipulation functions from the dojo.* namespace area also
-		//		available:
+		//		DOM manipulation functions from the dojo.* namespace area also available:
 		//		|	// remove all of the elements in the list from their
 		//		|	// parents (akin to "deleting" them from the document)
 		//		|	dojo.query(".thinger").orphan();
@@ -235,7 +235,6 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 		nlp[name] = function(){ return f.apply(dojo, [this].concat(aps.call(arguments, 0))); };
 	});
 
-	/*===== var NodeList = dojo.NodeList; =====*/
 	lang.extend(NodeList, {
 		// copy the constructors
 		constructor: nl,
@@ -249,11 +248,11 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 			//		private function to hold to a parent NodeList. end() to return the parent NodeList.
 			//
 			// example:
-			// How to make a `dojo.NodeList` method that only returns the third node in
-			// the dojo.NodeList but allows access to the original NodeList by using this._stash:
-			//	|	dojo.extend(dojo.NodeList, {
+			//		How to make a `dojo/NodeList` method that only returns the third node in
+			//		the dojo/NodeList but allows access to the original NodeList by using this._stash:
+			//	|	dojo.extend(NodeList, {
 			//	|		third: function(){
-			//	|			var newNodeList = dojo.NodeList(this[2]);
+			//	|			var newNodeList = NodeList(this[2]);
 			//	|			return newNodeList._stash(this);
 			//	|		}
 			//	|	});
@@ -267,17 +266,17 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 			//	|
 			//
 			this._parent = parent;
-			return this; //dojo.NodeList
+			return this; // dojo/NodeList
 		},
 
 		on: function(eventName, listener){
 			// summary:
 			//		Listen for events on the nodes in the NodeList. Basic usage is:
 			//		| query(".my-class").on("click", listener);
-			// 		This supports event delegation by using selectors as the first argument with the event names as
+			//		This supports event delegation by using selectors as the first argument with the event names as
 			//		pseudo selectors. For example:
 			//		| dojo.query("#my-list").on("li:click", listener);
-			//		This will listen for click events within <li> elements that are inside the #my-list element.
+			//		This will listen for click events within `<li>` elements that are inside the `#my-list` element.
 			//		Because on supports CSS selector syntax, we can use comma-delimited events as well:
 			//		| dojo.query("#my-list").on("li button:mouseover, li:click", listener);
 			var handles = this.map(function(node){
@@ -293,11 +292,11 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 
 		end: function(){
 			// summary:
-			//		Ends use of the current `dojo.NodeList` by returning the previous dojo.NodeList
-			//		that generated the current dojo.NodeList.
+			//		Ends use of the current `NodeList` by returning the previous NodeList
+			//		that generated the current NodeList.
 			// description:
-			//		Returns the `dojo.NodeList` that generated the current `dojo.NodeList`. If there
-			//		is no parent dojo.NodeList, an empty dojo.NodeList is returned.
+			//		Returns the `NodeList` that generated the current `NodeList`. If there
+			//		is no parent NodeList, an empty NodeList is returned.
 			// example:
 			//	|	dojo.query("a")
 			//	|		.filter(".disabled")
@@ -332,9 +331,9 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 			//		Returns a new NodeList, maintaining this one in place
 			// description:
 			//		This method behaves exactly like the Array.slice method
-			//		with the caveat that it returns a dojo.NodeList and not a
-			//		raw Array. For more details, see Mozilla's (slice
-			//		documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:slice]
+			//		with the caveat that it returns a dojo/NodeList and not a
+			//		raw Array. For more details, see Mozilla's [slice
+			//		documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/slice)
 			// begin: Integer
 			//		Can be a positive or negative integer, with positive
 			//		integers noting the offset to begin at, and negative
@@ -354,9 +353,9 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 			//		at an offset, optionally deleting elements
 			// description:
 			//		This method behaves exactly like the Array.splice method
-			//		with the caveat that it returns a dojo.NodeList and not a
-			//		raw Array. For more details, see Mozilla's (splice
-			//		documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:splice]
+			//		with the caveat that it returns a dojo/NodeList and not a
+			//		raw Array. For more details, see Mozilla's [splice
+			//		documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/splice)
 			//		For backwards compatibility, calling .end() on the spliced NodeList
 			//		does not return the original NodeList -- splice alters the NodeList in place.
 			// index: Integer
@@ -371,23 +370,21 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 			// item: Object...?
 			//		Any number of optional parameters may be passed in to be
 			//		spliced into the NodeList
-			// returns:
-			//		dojo.NodeList
-			return this._wrap(a.splice.apply(this, arguments));
+			return this._wrap(a.splice.apply(this, arguments));	// dojo/NodeList
 		},
 
 		indexOf: function(value, fromIndex){
 			// summary:
 			//		see dojo.indexOf(). The primary difference is that the acted-on
 			//		array is implicitly this NodeList
-			// value: Object:
+			// value: Object
 			//		The value to search for.
-			// fromIndex: Integer?:
+			// fromIndex: Integer?
 			//		The location to start searching from. Optional. Defaults to 0.
 			// description:
 			//		For more details on the behavior of indexOf, see Mozilla's
-			//		(indexOf
-			//		docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf]
+			//		[indexOf
+			//		docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf)
 			// returns:
 			//		Positive Integer or 0 for a match, -1 of not found.
 			return d.indexOf(this, value, fromIndex); // Integer
@@ -399,8 +396,8 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 			//		acted-on array is implicitly this NodeList
 			// description:
 			//		For more details on the behavior of lastIndexOf, see
-			//		Mozilla's (lastIndexOf
-			//		docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf]
+			//		Mozilla's [lastIndexOf
+			//		docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf)
 			// value: Object
 			//		The value to search for.
 			// fromIndex: Integer?
@@ -412,13 +409,15 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 
 		every: function(callback, thisObject){
 			// summary:
-			//		see `dojo.every()` and the (Array.every
-			//		docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every].
+			//		see `dojo.every()` and the [Array.every
+			//		docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every).
 			//		Takes the same structure of arguments and returns as
 			//		dojo.every() with the caveat that the passed array is
 			//		implicitly this NodeList
-			// callback: Function: the callback
-			// thisObject: Object?: the context
+			// callback: Function
+			//		the callback
+			// thisObject: Object?
+			//		the context
 			return d.every(this, callback, thisObject); // Boolean
 		},
 
@@ -427,10 +426,12 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 			//		Takes the same structure of arguments and returns as
 			//		`dojo.some()` with the caveat that the passed array is
 			//		implicitly this NodeList.  See `dojo.some()` and Mozilla's
-			//		(Array.some
-			//		documentation)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some].
-			// callback: Function: the callback
-			// thisObject: Object?: the context
+			//		[Array.some
+			//		documentation](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some).
+			// callback: Function
+			//		the callback
+			// thisObject: Object?
+			//		the context
 			return d.some(this, callback, thisObject); // Boolean
 		},
 		=====*/
@@ -441,43 +442,36 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 			//		as well as items passed in as parameters
 			// description:
 			//		This method behaves exactly like the Array.concat method
-			//		with the caveat that it returns a `dojo.NodeList` and not a
-			//		raw Array. For more details, see the (Array.concat
-			//		docs)[http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:concat]
+			//		with the caveat that it returns a `NodeList` and not a
+			//		raw Array. For more details, see the [Array.concat
+			//		docs](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/concat)
 			// item: Object?
 			//		Any number of optional parameters may be passed in to be
 			//		spliced into the NodeList
-			// returns:
-			//		dojo.NodeList
 
 			//return this._wrap(apc.apply(this, arguments));
-			// the line above won't work for the native NodeList :-(
+			// the line above won't work for the native NodeList, or for Dojo NodeLists either :-(
 
 			// implementation notes:
-			// 1) Native NodeList is not an array, and cannot be used directly
-			// in concat() --- the latter doesn't recognize it as an array, and
-			// does not inline it, but append as a single entity.
-			// 2) On some browsers (e.g., Safari) the "constructor" property is
-			// read-only and cannot be changed. So we have to test for both
-			// native NodeList and dojo.NodeList in this property to recognize
-			// the node list.
-
-			var t = lang.isArray(this) ? this : aps.call(this, 0),
+			// Array.concat() doesn't recognize native NodeLists or Dojo NodeLists
+			// as arrays, and so does not inline them into a unioned array, but
+			// appends them as single entities. Both the original NodeList and the
+			// items passed in as parameters must be converted to raw Arrays
+			// and then the concatenation result may be re-_wrap()ed as a Dojo NodeList.
+
+			var t = aps.call(this, 0),
 				m = array.map(arguments, function(a){
-					return a && !lang.isArray(a) &&
-						(typeof NodeList != "undefined" && a.constructor === NodeList || a.constructor === this._NodeListCtor) ?
-							aps.call(a, 0) : a;
+					return aps.call(a, 0);
 				});
-			return this._wrap(apc.apply(t, m), this);	// dojo.NodeList
+			return this._wrap(apc.apply(t, m), this);	// dojo/NodeList
 		},
 
 		map: function(/*Function*/ func, /*Function?*/ obj){
 			// summary:
 			//		see dojo.map(). The primary difference is that the acted-on
 			//		array is implicitly this NodeList and the return is a
-			//		dojo.NodeList (a subclass of Array)
-			///return d.map(this, func, obj, d.NodeList); // dojo.NodeList
-			return this._wrap(array.map(this, func, obj), this); // dojo.NodeList
+			//		NodeList (a subclass of Array)
+			return this._wrap(array.map(this, func, obj), this); // dojo/NodeList
 		},
 
 		forEach: function(callback, thisObj){
@@ -487,7 +481,7 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 			//		of the forEach loop, use every() or some() instead.
 			forEach(this, callback, thisObj);
 			// non-standard return to allow easier chaining
-			return this; // dojo.NodeList
+			return this; // dojo/NodeList
 		},
 		filter: function(/*String|Function*/ filter){
 			// summary:
@@ -512,26 +506,26 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 				items = query._filterResult(this, a[0]);
 				if(a.length == 1){
 					// if we only got a string query, pass back the filtered results
-					return items._stash(this); // dojo.NodeList
+					return items._stash(this); // dojo/NodeList
 				}
 				// if we got a callback, run it over the filtered items
 				start = 1;
 			}
-			return this._wrap(array.filter(items, a[start], a[start + 1]), this);	// dojo.NodeList
+			return this._wrap(array.filter(items, a[start], a[start + 1]), this);	// dojo/NodeList
 		},
 		instantiate: function(/*String|Object*/ declaredClass, /*Object?*/ properties){
 			// summary:
 			//		Create a new instance of a specified class, using the
-			//		specified properties and each node in the nodeList as a
+			//		specified properties and each node in the NodeList as a
 			//		srcNodeRef.
 			// example:
-			//		Grabs all buttons in the page and converts them to diji.form.Buttons.
-			//	|	var buttons = dojo.query("button").instantiate("dijit.form.Button", {showLabel: true});
+			//		Grabs all buttons in the page and converts them to dijit/form/Button's.
+			//	|	var buttons = query("button").instantiate(Button, {showLabel: true});
 			var c = lang.isFunction(declaredClass) ? declaredClass : lang.getObject(declaredClass);
 			properties = properties || {};
 			return this.forEach(function(node){
 				new c(properties, node);
-			});	// dojo.NodeList
+			});	// dojo/NodeList
 		},
 		at: function(/*===== index =====*/){
 			// summary:
@@ -545,169 +539,167 @@ define(["./_base/kernel", "./has", "./dom", "./on", "./_base/array", "./_base/la
 			//
 			// example:
 			//	Shorten the list to the first, second, and third elements
-			//	|	dojo.query("a").at(0, 1, 2).forEach(fn);
+			//	|	query("a").at(0, 1, 2).forEach(fn);
 			//
 			// example:
 			//	Retrieve the first and last elements of a unordered list:
-			//	|	dojo.query("ul > li").at(0, -1).forEach(cb);
+			//	|	query("ul > li").at(0, -1).forEach(cb);
 			//
 			// example:
 			//	Do something for the first element only, but end() out back to
 			//	the original list and continue chaining:
-			//	|	dojo.query("a").at(0).onclick(fn).end().forEach(function(n){
+			//	|	query("a").at(0).onclick(fn).end().forEach(function(n){
 			//	|		console.log(n); // all anchors on the page.
 			//	|	})
-			//
-			// returns:
-			//		dojo.NodeList
+
 			var t = new this._NodeListCtor(0);
 			forEach(arguments, function(i){
 				if(i < 0){ i = this.length + i; }
 				if(this[i]){ t.push(this[i]); }
 			}, this);
-			return t._stash(this); // dojo.NodeList
+			return t._stash(this); // dojo/NodeList
 		}
 	});
 
-
-/*===== 
-dojo.query = function(selector, context){
-	// summary:
-	//		This modules provides DOM querying functionality. The module export is a function
-	//		that can be used to query for DOM nodes by CSS selector and returns a dojo.NodeList
-	//		representing the matching nodes.
-	//
-	// selector: String
-	//		A CSS selector to search for.
-	// context: String|DomNode?
-	//		An optional context to limit the searching scope. Only nodes under `context` will be 
-	//		scanned. 
-	// 
-	//	example:
-	//		add an onclick handler to every submit button in the document
-	//		which causes the form to be sent via Ajax instead:
-	//	|	define(["dojo/query"], function(query){
-	// 	|	query("input[type='submit']").on("click", function(e){
-	//	|		dojo.stopEvent(e); // prevent sending the form
-	//	|		var btn = e.target;
-	//	|		dojo.xhrPost({
-	//	|			form: btn.form,
-	//	|			load: function(data){
-	//	|				// replace the form with the response
-	//	|				var div = dojo.doc.createElement("div");
-	//	|				dojo.place(div, btn.form, "after");
-	//	|				div.innerHTML = data;
-	//	|				dojo.style(btn.form, "display", "none");
-	//	|			}
-	//	|		});
-	//	|	}); 
-	//
-	// description:
-	//		dojo/query is responsible for loading the appropriate query engine and wrapping 
-	//		its results with a `dojo.NodeList`. You can use dojo/query with a specific selector engine
-	//		by using it as a plugin. For example, if you installed the sizzle package, you could
-	//		use it as the selector engine with:
-	//		|	define("dojo/query!sizzle", function(query){
-	//		|		query("div")...
-	//
-	//		The id after the ! can be a module id of the selector engine or one of the following values:
-	//		|	+ acme: This is the default engine used by Dojo base, and will ensure that the full
-	//		|	Acme engine is always loaded. 
-	//		|	
-	//		|	+ css2: If the browser has a native selector engine, this will be used, otherwise a
-	//		|	very minimal lightweight selector engine will be loaded that can do simple CSS2 selectors
-	//		|	(by #id, .class, tag, and [name=value] attributes, with standard child or descendant (>)
-	//		|	operators) and nothing more.
-	//		|
-	//		|	+ css2.1: If the browser has a native selector engine, this will be used, otherwise the
-	//		|	full Acme engine will be loaded. 
-	//		|	
-	//		|	+ css3: If the browser has a native selector engine with support for CSS3 pseudo
-	//		|	selectors (most modern browsers except IE8), this will be used, otherwise the
-	//		|	full Acme engine will be loaded.
-	//		|	
-	//		|	+ Or the module id of a selector engine can be used to explicitly choose the selector engine
-	//		
-	//		For example, if you are using CSS3 pseudo selectors in module, you can specify that
-	//		you will need support them with:
-	//		|	define("dojo/query!css3", function(query){
-	//		|		query('#t > h3:nth-child(odd)')...
-	//
-	//		You can also choose the selector engine/load configuration by setting the <FIXME:what is the configuration setting?>.
-	//		For example:
-	//		|	<script data-dojo-config="query-selector:'css3'" src="dojo.js"></script>
-	//		
-	return new dojo.NodeList(); // dojo.NodeList
-};
-=====*/
-
-function queryForEngine(engine, NodeList){
-	var query = function(/*String*/ query, /*String|DOMNode?*/ root){
-		//	summary:
-		//		Returns nodes which match the given CSS selector, searching the
-		//		entire document by default but optionally taking a node to scope
-		//		the search by. Returns an instance of dojo.NodeList.
-		if(typeof root == "string"){
-			root = dom.byId(root);
-			if(!root){
-				return new NodeList([]);
+	function queryForEngine(engine, NodeList){
+		var query = function(/*String*/ query, /*String|DOMNode?*/ root){
+			// summary:
+			//		Returns nodes which match the given CSS selector, searching the
+			//		entire document by default but optionally taking a node to scope
+			//		the search by. Returns an instance of NodeList.
+			if(typeof root == "string"){
+				root = dom.byId(root);
+				if(!root){
+					return new NodeList([]);
+				}
 			}
+			var results = typeof query == "string" ? engine(query, root) : query ? (query.end && query.on) ? query : [query] : [];
+			if(results.end && results.on){
+				// already wrapped
+				return results;
+			}
+			return new NodeList(results);
+		};
+		query.matches = engine.match || function(node, selector, root){
+			// summary:
+			//		Test to see if a node matches a selector
+			return query.filter([node], selector, root).length > 0;
+		};
+		// the engine provides a filtering function, use it to for matching
+		query.filter = engine.filter || function(nodes, selector, root){
+			// summary:
+			//		Filters an array of nodes. Note that this does not guarantee to return a NodeList, just an array.
+			return query(selector, root).filter(function(node){
+				return array.indexOf(nodes, node) > -1;
+			});
+		};
+		if(typeof engine != "function"){
+			var search = engine.search;
+			engine = function(selector, root){
+				// Slick does it backwards (or everyone else does it backwards, probably the latter)
+				return search(root || document, selector);
+			};
 		}
-		var results = typeof query == "string" ? engine(query, root) : query.orphan ? query : [query];
-		if(results.orphan){
-			// already wrapped
-			return results; 
-		}
-		return new NodeList(results);
-	};
-	query.matches = engine.match || function(node, selector, root){
+		return query;
+	}
+	var query = queryForEngine(defaultEngine, NodeList);
+	/*=====
+	query = function(selector, context){
 		// summary:
-		//		Test to see if a node matches a selector
-		return query.filter([node], selector, root).length > 0;
-	};
-	// the engine provides a filtering function, use it to for matching
-	query.filter = engine.filter || function(nodes, selector, root){
+		//		This modules provides DOM querying functionality. The module export is a function
+		//		that can be used to query for DOM nodes by CSS selector and returns a NodeList
+		//		representing the matching nodes.
+		// selector: String
+		//		A CSS selector to search for.
+		// context: String|DomNode?
+		//		An optional context to limit the searching scope. Only nodes under `context` will be
+		//		scanned.
+		// example:
+		//		add an onclick handler to every submit button in the document
+		//		which causes the form to be sent via Ajax instead:
+		//	|	require(["dojo/query"], function(query){
+		//	|		query("input[type='submit']").on("click", function(e){
+		//	|			dojo.stopEvent(e); // prevent sending the form
+		//	|			var btn = e.target;
+		//	|			dojo.xhrPost({
+		//	|				form: btn.form,
+		//	|				load: function(data){
+		//	|					// replace the form with the response
+		//	|					var div = dojo.doc.createElement("div");
+		//	|					dojo.place(div, btn.form, "after");
+		//	|					div.innerHTML = data;
+		//	|					dojo.style(btn.form, "display", "none");
+		//	|				}
+		//	|			});
+		//	|		});
+		// |	});
+		//
+		// description:
+		//		dojo/query is responsible for loading the appropriate query engine and wrapping
+		//		its results with a `NodeList`. You can use dojo/query with a specific selector engine
+		//		by using it as a plugin. For example, if you installed the sizzle package, you could
+		//		use it as the selector engine with:
+		//		|	require(["dojo/query!sizzle"], function(query){
+		//		|		query("div")...
+		//
+		//		The id after the ! can be a module id of the selector engine or one of the following values:
+		//
+		//		- acme: This is the default engine used by Dojo base, and will ensure that the full
+		//		Acme engine is always loaded.
+		//
+		//		- css2: If the browser has a native selector engine, this will be used, otherwise a
+		//		very minimal lightweight selector engine will be loaded that can do simple CSS2 selectors
+		//		(by #id, .class, tag, and [name=value] attributes, with standard child or descendant (>)
+		//		operators) and nothing more.
+		//
+		//		- css2.1: If the browser has a native selector engine, this will be used, otherwise the
+		//		full Acme engine will be loaded.
+		//
+		//		- css3: If the browser has a native selector engine with support for CSS3 pseudo
+		//		selectors (most modern browsers except IE8), this will be used, otherwise the
+		//		full Acme engine will be loaded.
+		//
+		//		- Or the module id of a selector engine can be used to explicitly choose the selector engine
+		//
+		//		For example, if you are using CSS3 pseudo selectors in module, you can specify that
+		//		you will need support them with:
+		//		|	require(["dojo/query!css3"], function(query){
+		//		|		query('#t > h3:nth-child(odd)')...
+		//
+		//		You can also choose the selector engine/load configuration by setting the query-selector:
+		//		For example:
+		//		|	<script data-dojo-config="query-selector:'css3'" src="dojo.js"></script>
+		//
+		return new NodeList(); // dojo/NodeList
+	 };
+	 =====*/
+
+	// the query that is returned from this module is slightly different than dojo.query,
+	// because dojo.query has to maintain backwards compatibility with returning a
+	// true array which has performance problems. The query returned from the module
+	// does not use true arrays, but rather inherits from Array, making it much faster to
+	// instantiate.
+	dojo.query = queryForEngine(defaultEngine, function(array){
+		// call it without the new operator to invoke the back-compat behavior that returns a true array
+		return NodeList(array);	// dojo/NodeList
+	});
+
+	query.load = function(id, parentRequire, loaded){
 		// summary:
-		//		Filters an array of nodes. Note that this does not guarantee to return a dojo.NodeList, just an array.
-		return query(selector, root).filter(function(node){
-			return array.indexOf(nodes, node) > -1;
+		//		can be used as AMD plugin to conditionally load new query engine
+		// example:
+		//	|	require(["dojo/query!custom"], function(qsa){
+		//	|		// loaded selector/custom.js as engine
+		//	|		qsa("#foobar").forEach(...);
+		//	|	});
+		loader.load(id, parentRequire, function(engine){
+			loaded(queryForEngine(engine, NodeList));
 		});
 	};
-	if(typeof engine != "function"){
-		var search = engine.search;
-		engine = function(selector, root){
-			// Slick does it backwards (or everyone else does it backwards, probably the latter)
-			return search(root || document, selector);
-		};
-	}
-	return query;
-}
-var query = queryForEngine(defaultEngine, NodeList);
-// the query that is returned from this module is slightly different than dojo.query,
-// because dojo.query has to maintain backwards compatibility with returning a
-// true array which has performance problems. The query returned from the module
-// does not use true arrays, but rather inherits from Array, making it much faster to
-// instantiate.
-dojo.query = queryForEngine(defaultEngine, function(array){
-	// call it without the new operator to invoke the back-compat behavior that returns a true array
-	return NodeList(array);
-});
 
-query.load = /*===== dojo.query.load= ======*/ function(id, parentRequire, loaded, config){
-	// summary: can be used as AMD plugin to conditionally load new query engine
-	// example:
-	//	|	define(["dojo/query!custom"], function(qsa){ 
-	//	|		// loaded selector/custom.js as engine
-	//	|		qsa("#foobar").forEach(...);
-	//	|	});
-	loader.load(id, parentRequire, function(engine){
-		loaded(queryForEngine(engine, NodeList));
-	});
-};
-
-dojo._filterQueryResult = query._filterResult = function(nodes, selector, root){
-	return new NodeList(query.filter(nodes, selector, root));
-};
-dojo.NodeList = query.NodeList = NodeList;
-return query;
+	dojo._filterQueryResult = query._filterResult = function(nodes, selector, root){
+		return new NodeList(query.filter(nodes, selector, root));
+	};
+	dojo.NodeList = query.NodeList = NodeList;
+	return query;
 });
diff --git a/dojo/ready.js b/dojo/ready.js
index 3e1bd38..975719b 100644
--- a/dojo/ready.js
+++ b/dojo/ready.js
@@ -1,18 +1,13 @@
-define(["./_base/kernel", "./has", "require", "./has!host-browser?./domReady", "./_base/lang"], function(dojo, has, require, domReady, lang) {
+define(["./_base/kernel", "./has", "require", "./has!host-browser?./domReady", "./_base/lang"], function(dojo, has, require, domReady, lang){
 	// module:
 	//		dojo/ready
-	// summary:
-	//		This module defines the dojo.ready API.
-	//
 	// note:
 	//		This module should be unnecessary in dojo 2.0
+
 	var
 		// truthy if DOMContentLoaded or better (e.g., window.onload fired) has been achieved
 		isDomReady = 0,
 
-		// a function to call to cause onLoad to be called when all requested modules have been loaded
-		requestCompleteSignal,
-
 		// The queue of functions waiting to execute as soon as dojo.ready conditions satisfied
 		loadQ = [],
 
@@ -22,50 +17,62 @@ define(["./_base/kernel", "./has", "require", "./has!host-browser?./domReady", "
 		handleDomReady = function(){
 			isDomReady = 1;
 			dojo._postLoad = dojo.config.afterOnLoad = true;
-			if(loadQ.length){
-				requestCompleteSignal(onLoad);
-			}
+			onEvent();
 		},
 
-		// run the next function queued with dojo.ready
-		onLoad = function(){
-			if(isDomReady && !onLoadRecursiveGuard && loadQ.length){
-				//guard against recursions into this function
-				onLoadRecursiveGuard = 1;
+		onEvent = function(){
+			// Called when some state changes:
+			//		- dom ready
+			//		- dojo/domReady has finished processing everything in its queue
+			//		- task added to loadQ
+			//		- require() has finished loading all currently requested modules
+			//
+			// Run the functions queued with dojo.ready if appropriate.
+
+
+			//guard against recursions into this function
+			if(onLoadRecursiveGuard){
+				return;
+			}
+			onLoadRecursiveGuard = 1;
+
+			// Run tasks in queue if require() is finished loading modules, the dom is ready, and there are no
+			// pending tasks registered via domReady().
+			// The last step is necessary so that a user defined dojo.ready() callback is delayed until after the
+			// domReady() calls inside of dojo.	  Failure can be seen on dijit/tests/robot/Dialog_ally.html on IE8
+			// because the dijit/focus.js domReady() callback doesn't execute until after the test starts running.
+			while(isDomReady && (!domReady || domReady._Q.length == 0) && (require.idle ? require.idle() : true) && loadQ.length){
 				var f = loadQ.shift();
-					try{
-						f();
+				try{
+					f();
+				}catch(e){
+					// force the dojo.js on("error") handler do display the message
+					e.info = e.message;
+					if(require.signal){
+						require.signal("error", e);
+					}else{
+						throw e;
 					}
-						// FIXME: signal the error via require.on
-					finally{
-						onLoadRecursiveGuard = 0;
-					}
-				onLoadRecursiveGuard = 0;
-				if(loadQ.length){
-					requestCompleteSignal(onLoad);
 				}
 			}
-		};
 
-	// define requireCompleteSignal; impl depends on loader
-	if(has("dojo-loader")){
-		require.on("idle", onLoad);
-		requestCompleteSignal = function(){
-			if(require.idle()){
-				onLoad();
-			} // else do nothing, onLoad will be called with the next idle signal
-		};
-	}else{
-		// RequireJS or similar
-		requestCompleteSignal = function(){
-			// the next function call will fail if you don't have a loader with require.ready
-			// in that case, either fix your loader, use dojo's loader, or don't call dojo.ready;
-			require.ready(onLoad);
+			onLoadRecursiveGuard = 0;
 		};
+
+	// Check if we should run the next queue operation whenever require() finishes loading modules or domReady
+	// finishes processing it's queue.
+	require.on && require.on("idle", onEvent);
+	if(domReady){
+		domReady._onQEmpty = onEvent;
 	}
 
 	var ready = dojo.ready = dojo.addOnLoad = function(priority, context, callback){
-		// summary: Add a function to execute on DOM content loaded and all requested modules have arrived and been evaluated.
+		// summary:
+		//		Add a function to execute on DOM content loaded and all requested modules have arrived and been evaluated.
+		//		In most cases, the `domReady` plug-in should suffice and this method should not be needed.
+		//
+		//		When called in a non-browser environment, just checks that all requested modules have arrived and been
+		//		evaluated.
 		// priority: Integer?
 		//		The order in which to exec this callback relative to other callbacks, defaults to 1000
 		// context: Object?|Function
@@ -75,22 +82,30 @@ define(["./_base/kernel", "./has", "require", "./has!host-browser?./domReady", "
 		//
 		// example:
 		//	Simple DOM and Modules ready syntax
-		//	|	dojo.ready(function(){ alert("Dom ready!"); });
+		//	|	require(["dojo/ready"], function(ready){
+		//	|		ready(function(){ alert("Dom ready!"); });
+		//	|	});
 		//
 		// example:
 		//	Using a priority
-		//	|	dojo.ready(2, function(){ alert("low priority ready!"); })
+		//	|	require(["dojo/ready"], function(ready){
+		//	|		ready(2, function(){ alert("low priority ready!"); })
+		//	|	});
 		//
 		// example:
 		//	Using context
-		//	|	dojo.ready(foo, function(){
-		//	|		// in here, this == foo
-		//	|	})
+		//	|	require(["dojo/ready"], function(ready){
+		//	|		ready(foo, function(){
+		//	|			// in here, this == foo
+		//	|		});
+		//	|	});
 		//
 		// example:
-		//	Using dojo.hitch style args:
-		//	|	var foo = { dojoReady: function(){ console.warn(this, "dojo dom and modules ready."); } };
-		//	|	dojo.ready(foo, "dojoReady");
+		//	Using dojo/hitch style args:
+		//	|	require(["dojo/ready"], function(ready){
+		//	|		var foo = { dojoReady: function(){ console.warn(this, "dojo dom and modules ready."); } };
+		//	|		ready(foo, "dojoReady");
+		//	|	});
 
 		var hitchArgs = lang._toArray(arguments);
 		if(typeof priority != "number"){
@@ -108,7 +123,7 @@ define(["./_base/kernel", "./has", "require", "./has!host-browser?./domReady", "
 		callback.priority = priority;
 		for(var i = 0; i < loadQ.length && priority >= loadQ[i].priority; i++){}
 		loadQ.splice(i, 0, callback);
-		requestCompleteSignal();
+		onEvent();
 	};
 
 	has.add("dojo-config-addOnLoad", 1);
@@ -128,7 +143,7 @@ define(["./_base/kernel", "./has", "require", "./has!host-browser?./domReady", "
 		});
 	}
 
-	if(has("host-browser")){
+	if(domReady){
 		domReady(handleDomReady);
 	}else{
 		handleDomReady();
diff --git a/dojo/regexp.js b/dojo/regexp.js
index ba5b7b8..f2b6cb6 100644
--- a/dojo/regexp.js
+++ b/dojo/regexp.js
@@ -1,19 +1,16 @@
-define(["./_base/kernel", "./_base/lang"], function(dojo, lang) {
-	// module:
-	//		dojo/regexp
-	// summary:
-	//		TODOC
+define(["./_base/kernel", "./_base/lang"], function(dojo, lang){
 
-lang.getObject("regexp", true, dojo);
+// module:
+//		dojo/regexp
 
-/*=====
-dojo.regexp = {
-	// summary: Regular expressions and Builder resources
+var regexp = {
+	// summary:
+	//		Regular expressions and Builder resources
 };
-=====*/
+lang.setObject("dojo.regexp", regexp);
 
-dojo.regexp.escapeString = function(/*String*/str, /*String?*/except){
-	//	summary:
+regexp.escapeString = function(/*String*/str, /*String?*/except){
+	// summary:
 	//		Adds escape sequences for special characters in regular expressions
 	// except:
 	//		a String with special characters to be left unescaped
@@ -26,10 +23,10 @@ dojo.regexp.escapeString = function(/*String*/str, /*String?*/except){
 	}); // String
 };
 
-dojo.regexp.buildGroupRE = function(/*Object|Array*/arr, /*Function*/re, /*Boolean?*/nonCapture){
-	//	summary:
+regexp.buildGroupRE = function(/*Object|Array*/arr, /*Function*/re, /*Boolean?*/nonCapture){
+	// summary:
 	//		Builds a regular expression that groups subexpressions
-	//	description:
+	// description:
 	//		A utility function used by some of the RE generators. The
 	//		subexpressions are constructed by the function, re, in the second
 	//		parameter.  re builds one subexpression for each elem in the array
@@ -57,10 +54,10 @@ dojo.regexp.buildGroupRE = function(/*Object|Array*/arr, /*Function*/re, /*Boole
 	}
 
 	 // join the REs as alternatives in a RE group.
-	return dojo.regexp.group(b.join("|"), nonCapture); // String
+	return regexp.group(b.join("|"), nonCapture); // String
 };
 
-dojo.regexp.group = function(/*String*/expression, /*Boolean?*/nonCapture){
+regexp.group = function(/*String*/expression, /*Boolean?*/nonCapture){
 	// summary:
 	//		adds group match to expression
 	// nonCapture:
@@ -69,5 +66,5 @@ dojo.regexp.group = function(/*String*/expression, /*Boolean?*/nonCapture){
 	return "(" + (nonCapture ? "?:":"") + expression + ")"; // String
 };
 
-return dojo.regexp;
+return regexp;
 });
diff --git a/dojo/request.js b/dojo/request.js
new file mode 100644
index 0000000..bdb8571
--- /dev/null
+++ b/dojo/request.js
@@ -0,0 +1,81 @@
+define([
+	'./request/default!'/*=====,
+	'./_base/declare',
+	'./promise/Promise' =====*/
+], function(request/*=====, declare, Promise =====*/){
+	/*=====
+	request = function(url, options){
+		// summary:
+		//		Send a request using the default transport for the current platform.
+		// url: String
+		//		The URL to request.
+		// options: dojo/request.__Options?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	request.__Promise = declare(Promise, {
+		// response: dojo/promise/Promise
+		//		A promise resolving to an object representing
+		//		the response from the server.
+	});
+	request.__BaseOptions = declare(null, {
+		// query: String|Object?
+		//		Query parameters to append to the URL.
+		// data: String|Object?
+		//		Data to transfer.  This is ignored for GET and DELETE
+		//		requests.
+		// preventCache: Boolean?
+		//		Whether to append a cache-busting parameter to the URL.
+		// timeout: Integer?
+		//		Milliseconds to wait for the response.  If this time
+		//		passes, the then the promise is rejected.
+		// handleAs: String?
+		//		How to handle the response from the server.  Default is
+		//		'text'.  Other values are 'json', 'javascript', and 'xml'.
+	});
+	request.__MethodOptions = declare(null, {
+		// method: String?
+		//		The HTTP method to use to make the request.  Must be
+		//		uppercase.
+	});
+	request.__Options = declare([request.__BaseOptions, request.__MethodOptions]);
+
+	request.get = function(url, options){
+		// summary:
+		//		Send an HTTP GET request using the default transport for the current platform.
+		// url: String
+		//		URL to request
+		// options: dojo/request.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	request.post = function(url, options){
+		// summary:
+		//		Send an HTTP POST request using the default transport for the current platform.
+		// url: String
+		//		URL to request
+		// options: dojo/request.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	request.put = function(url, options){
+		// summary:
+		//		Send an HTTP POST request using the default transport for the current platform.
+		// url: String
+		//		URL to request
+		// options: dojo/request.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	request.del = function(url, options){
+		// summary:
+		//		Send an HTTP DELETE request using the default transport for the current platform.
+		// url: String
+		//		URL to request
+		// options: dojo/request.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	=====*/
+	return request;
+});
diff --git a/dojo/request/default.js b/dojo/request/default.js
new file mode 100644
index 0000000..b82aacf
--- /dev/null
+++ b/dojo/request/default.js
@@ -0,0 +1,32 @@
+define([
+	'exports',
+	'require',
+	'../has'
+], function(exports, require, has){
+	var defId = has('config-requestProvider'),
+		platformId;
+
+	if(has('host-browser')){
+		platformId = './xhr';
+	}else if(has('host-node')){
+		platformId = './node';
+	/* TODO:
+	}else if(has('host-rhino')){
+		platformId = './rhino';
+   */
+	}
+
+	if(!defId){
+		defId = platformId;
+	}
+
+	exports.getPlatformDefaultId = function(){
+		return platformId;
+	};
+
+	exports.load = function(id, parentRequire, loaded, config){
+		require([id == 'platform' ? platformId : defId], function(provider){
+			loaded(provider);
+		});
+	};
+});
diff --git a/dojo/request/handlers.js b/dojo/request/handlers.js
new file mode 100644
index 0000000..e04c229
--- /dev/null
+++ b/dojo/request/handlers.js
@@ -0,0 +1,74 @@
+define([
+	'../json',
+	'../_base/kernel',
+	'../_base/array',
+	'../has',
+	'../has!dom?../selector/_loader' // only included for has() qsa tests
+], function(JSON, kernel, array, has){
+	has.add('activex', typeof ActiveXObject !== 'undefined');
+	has.add('dom-parser', function(global){
+		return 'DOMParser' in global;
+	});
+
+	var handleXML;
+	if(has('activex')){
+		// GUIDs obtained from http://msdn.microsoft.com/en-us/library/ms757837(VS.85).aspx
+		var dp = [
+			'Msxml2.DOMDocument.6.0',
+			'Msxml2.DOMDocument.4.0',
+			'MSXML2.DOMDocument.3.0',
+			'MSXML.DOMDocument' // 2.0
+		];
+
+		handleXML = function(response){
+			var result = response.data;
+
+			if(result && has('dom-qsa2.1') && !result.querySelectorAll && has('dom-parser')){
+				// http://bugs.dojotoolkit.org/ticket/15631
+				// IE9 supports a CSS3 querySelectorAll implementation, but the DOM implementation 
+				// returned by IE9 xhr.responseXML does not. Manually create the XML DOM to gain 
+				// the fuller-featured implementation and avoid bugs caused by the inconsistency
+				result = new DOMParser().parseFromString(response.text, 'application/xml');
+			}
+
+			if(!result || !result.documentElement){
+				var text = response.text;
+				array.some(dp, function(p){
+					try{
+						var dom = new ActiveXObject(p);
+						dom.async = false;
+						dom.loadXML(text);
+						result = dom;
+					}catch(e){ return false; }
+					return true;
+				});
+			}
+
+			return result;
+		};
+	}
+
+	var handlers = {
+		'javascript': function(response){
+			return kernel.eval(response.text || '');
+		},
+		'json': function(response){
+			return JSON.parse(response.text || null);
+		},
+		'xml': handleXML
+	};
+
+	function handle(response){
+		var handler = handlers[response.options.handleAs];
+
+		response.data = handler ? handler(response) : (response.data || response.text);
+
+		return response;
+	}
+
+	handle.register = function(name, handler){
+		handlers[name] = handler;
+	};
+
+	return handle;
+});
diff --git a/dojo/request/iframe.js b/dojo/request/iframe.js
new file mode 100644
index 0000000..a7576ac
--- /dev/null
+++ b/dojo/request/iframe.js
@@ -0,0 +1,431 @@
+define([
+	'module',
+	'require',
+	'./watch',
+	'./util',
+	'./handlers',
+	'../_base/lang',
+	'../io-query',
+	'../query',
+	'../has',
+	'../dom',
+	'../dom-construct',
+	'../_base/window',
+	'../NodeList-dom'/*=====,
+	'../request',
+	'../_base/declare' =====*/
+], function(module, require, watch, util, handlers, lang, ioQuery, query, has, dom, domConstruct, win/*=====, NodeList, request, declare =====*/){
+	var mid = module.id.replace(/[\/\.\-]/g, '_'),
+		onload = mid + '_onload';
+
+	if(!win.global[onload]){
+		win.global[onload] = function(){
+			var dfd = iframe._currentDfd;
+			if(!dfd){
+				iframe._fireNextRequest();
+				return;
+			}
+
+			var response = dfd.response,
+				options = response.options,
+				formNode = dom.byId(options.form) || dfd._tmpForm;
+
+			if(formNode){
+				// remove all the hidden content inputs
+				var toClean = dfd._contentToClean;
+				for(var i=0; i<toClean.length; i++){
+					var key = toClean[i];
+					//Need to cycle over all nodes since we may have added
+					//an array value which means that more than one node could
+					//have the same .name value.
+					for(var j=0; j<formNode.childNodes.length; j++){
+						var childNode = formNode.childNodes[j];
+						if(childNode.name === key){
+							domConstruct.destroy(childNode);
+							break;
+						}
+					}
+				}
+
+				// restore original action + target
+				dfd._originalAction && formNode.setAttribute('action', dfd._originalAction);
+				if(dfd._originalMethod){
+					formNode.setAttribute('method', dfd._originalMethod);
+					formNode.method = dfd._originalMethod;
+				}
+				if(dfd._originalTarget){
+					formNode.setAttribute('target', dfd._originalTarget);
+					formNode.target = dfd._originalTarget;
+				}
+			}
+
+			if(dfd._tmpForm){
+				domConstruct.destroy(dfd._tmpForm);
+				delete dfd._tmpForm;
+			}
+
+			dfd._finished = true;
+		};
+	}
+
+	function create(name, onloadstr, uri){
+		if(win.global[name]){
+			return win.global[name];
+		}
+
+		if(win.global.frames[name]){
+			return win.global.frames[name];
+		}
+
+		if(!uri){
+			if(has('config-useXDomain') && !has('config-dojoBlankHtmlUrl')){
+				console.warn('dojo/request/iframe: When using cross-domain Dojo builds,' +
+					' please save dojo/resources/blank.html to your domain and set dojoConfig.dojoBlankHtmlUrl' +
+					' to the path on your domain to blank.html');
+			}
+			uri = (has('config-dojoBlankHtmlUrl')||require.toUrl('dojo/resources/blank.html'));
+		}
+
+		var frame = domConstruct.place(
+			'<iframe id="'+name+'" name="'+name+'" src="'+uri+'" onload="'+onloadstr+
+			'" style="position: absolute; left: 1px; top: 1px; height: 1px; width: 1px; visibility: hidden">',
+			win.body());
+
+		win.global[name] = frame;
+
+		return frame;
+	}
+
+	function setSrc(_iframe, src, replace){
+		var frame = win.global.frames[_iframe.name];
+
+		if(frame.contentWindow){
+			// We have an iframe node instead of the window
+			frame = frame.contentWindow;
+		}
+
+		try{
+			if(!replace){
+				frame.location = src;
+			}else{
+				frame.location.replace(src);
+			}
+		}catch(e){
+			console.log('dojo/request/iframe.setSrc: ', e);
+		}
+	}
+
+	function doc(iframeNode){
+		if(iframeNode.contentDocument){
+			return iframeNode.contentDocument;
+		}
+		var name = iframeNode.name;
+		if(name){
+			var iframes = win.doc.getElementsByTagName('iframe');
+			if(iframeNode.document && iframes[name].contentWindow && iframes[name].contentWindow.document){
+				return iframes[name].contentWindow.document;
+			}else if(win.doc.frames[name] && win.doc.frames[name].document){
+				return win.doc.frames[name].document;
+			}
+		}
+		return null;
+	}
+
+	function createForm(){
+		return domConstruct.create('form', {
+			name: mid + '_form',
+			style: {
+				position: 'absolute',
+				top: '-1000px',
+				left: '-1000px'
+			}
+		}, win.body());
+	}
+
+	function fireNextRequest(){
+		// summary:
+		//		Internal method used to fire the next request in the queue.
+		var dfd;
+		try{
+			if(iframe._currentDfd || !iframe._dfdQueue.length){
+				return;
+			}
+			do{
+				dfd = iframe._currentDfd = iframe._dfdQueue.shift();
+			}while(dfd && (dfd.canceled || (dfd.isCanceled && dfd.isCanceled())) && iframe._dfdQueue.length);
+
+			if(!dfd || dfd.canceled || (dfd.isCanceled && dfd.isCanceled())){
+				iframe._currentDfd = null;
+				return;
+			}
+
+			var response = dfd.response,
+				options = response.options,
+				c2c = dfd._contentToClean = [],
+				formNode = dom.byId(options.form),
+				notify = util.notify,
+				data = options.data || null,
+				queryStr;
+
+			if(!dfd._legacy && options.method === 'POST' && !formNode){
+				formNode = dfd._tmpForm = createForm();
+			}else if(options.method === 'GET' && formNode && response.url.indexOf('?') > -1){
+				queryStr = response.url.slice(response.url.indexOf('?') + 1);
+				data = lang.mixin(ioQuery.queryToObject(queryStr), data);
+			}
+
+			if(formNode){
+				if(!dfd._legacy){
+					var parentNode = formNode;
+					do{
+						parentNode = parentNode.parentNode;
+					}while(parentNode !== win.doc.documentElement);
+
+					// Append the form node or some browsers won't work
+					if(!parentNode){
+						formNode.style.position = 'absolute';
+						formNode.style.left = '-1000px';
+						formNode.style.top = '-1000px';
+						win.body().appendChild(formNode);
+					}
+
+					if(!formNode.name){
+						formNode.name = mid + '_form';
+					}
+				}
+
+				// if we have things in data, we need to add them to the form
+				// before submission
+				if(data){
+					var createInput = function(name, value){
+						domConstruct.create('input', {
+							type: 'hidden',
+							name: name,
+							value: value
+						}, formNode);
+						c2c.push(name);
+					};
+					for(var x in data){
+						var val = data[x];
+						if(lang.isArray(val) && val.length > 1){
+							for(var i=0; i<val.length; i++){
+								createInput(x, val[i]);
+							}
+						}else{
+							if(!formNode[x]){
+								createInput(x, val);
+							}else{
+								formNode[x].value = val;
+							}
+						}
+					}
+				}
+
+				//IE requires going through getAttributeNode instead of just getAttribute in some form cases,
+				//so use it for all.  See #2844
+				var actionNode = formNode.getAttributeNode('action'),
+					methodNode = formNode.getAttributeNode('method'),
+					targetNode = formNode.getAttributeNode('target');
+
+				if(response.url){
+					dfd._originalAction = actionNode ? actionNode.value : null;
+					if(actionNode){
+						actionNode.value = response.url;
+					}else{
+						formNode.setAttribute('action', response.url);
+					}
+				}
+
+				if(!dfd._legacy){
+					dfd._originalMethod = methodNode ? methodNode.value : null;
+					if(methodNode){
+						methodNode.value = options.method;
+					}else{
+						formNode.setAttribute('method', options.method);
+					}
+				}else{
+					if(!methodNode || !methodNode.value){
+						if(methodNode){
+							methodNode.value = options.method;
+						}else{
+							formNode.setAttribute('method', options.method);
+						}
+					}
+				}
+
+				dfd._originalTarget = targetNode ? targetNode.value : null;
+				if(targetNode){
+					targetNode.value = iframe._iframeName;
+				}else{
+					formNode.setAttribute('target', iframe._iframeName);
+				}
+				formNode.target = iframe._iframeName;
+
+				notify && notify.emit('send', response, dfd.promise.cancel);
+				iframe._notifyStart(response);
+				formNode.submit();
+			}else{
+				// otherwise we post a GET string by changing URL location for the
+				// iframe
+
+				var extra = '';
+				if(response.options.data){
+					extra = response.options.data;
+					if(typeof extra !== 'string'){
+						extra = ioQuery.objectToQuery(extra);
+					}
+				}
+				var tmpUrl = response.url + (response.url.indexOf('?') > -1 ? '&' : '?') + extra;
+				notify && notify.emit('send', response, dfd.promise.cancel);
+				iframe._notifyStart(response);
+				iframe.setSrc(iframe._frame, tmpUrl, true);
+			}
+		}catch(e){
+			dfd.reject(e);
+		}
+	}
+
+	// dojo/request/watch handlers
+	function isValid(response){
+		return !this.isFulfilled();
+	}
+	function isReady(response){
+		return !!this._finished;
+	}
+	function handleResponse(response, error){
+		if(!error){
+			try{
+				var options = response.options,
+					doc = iframe.doc(iframe._frame),
+					handleAs = options.handleAs;
+
+				if(handleAs !== 'html'){
+					if(handleAs === 'xml'){
+						// IE6-8 have to parse the XML manually. See http://bugs.dojotoolkit.org/ticket/6334
+						if(doc.documentElement.tagName.toLowerCase() === 'html'){
+							query('a', doc.documentElement).orphan();
+							var xmlText = doc.documentElement.innerText;
+							xmlText = xmlText.replace(/>\s+</g, '><');
+							response.text = lang.trim(xmlText);
+						}else{
+							response.data = doc;
+						}
+					}else{
+						// 'json' and 'javascript' and 'text'
+						response.text = doc.getElementsByTagName('textarea')[0].value; // text
+					}
+					handlers(response);
+				}else{
+					response.data = doc;
+				}
+			}catch(e){
+				error = e;
+			}
+		}
+
+		if(error){
+			this.reject(error);
+		}else if(this._finished){
+			this.resolve(response);
+		}else{
+			this.reject(new Error('Invalid dojo/request/iframe request state'));
+		}
+	}
+	function last(response){
+		this._callNext();
+	}
+
+	var defaultOptions = {
+		method: 'POST'
+	};
+	function iframe(url, options, returnDeferred){
+		var response = util.parseArgs(url, util.deepCreate(defaultOptions, options), true);
+		url = response.url;
+		options = response.options;
+
+		if(options.method !== 'GET' && options.method !== 'POST'){
+			throw new Error(options.method + ' not supported by dojo/request/iframe');
+		}
+
+		if(!iframe._frame){
+			iframe._frame = iframe.create(iframe._iframeName, onload + '();');
+		}
+
+		var dfd = util.deferred(response, null, isValid, isReady, handleResponse, last);
+		dfd._callNext = function(){
+			if(!this._calledNext){
+				this._calledNext = true;
+				iframe._currentDfd = null;
+				iframe._fireNextRequest();
+			}
+		};
+		dfd._legacy = returnDeferred;
+
+		iframe._dfdQueue.push(dfd);
+		iframe._fireNextRequest();
+
+		watch(dfd);
+
+		return returnDeferred ? dfd : dfd.promise;
+	}
+
+	/*=====
+	iframe = function(url, options){
+		// summary:
+		//		Sends a request using an iframe element with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/iframe.__Options?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	iframe.__BaseOptions = declare(request.__BaseOptions, {
+		// form: DOMNode?
+		//		A form node to use to submit data to the server.
+		// data: String|Object?
+		//		Data to transfer. When making a GET request, this will
+		//		be converted to key=value parameters and appended to the
+		//		URL.
+	});
+	iframe.__MethodOptions = declare(null, {
+		// method: String?
+		//		The HTTP method to use to make the request. Must be
+		//		uppercase. Only `"GET"` and `"POST"` are accepted.
+		//		Default is `"POST"`.
+	});
+	iframe.__Options = declare([iframe.__BaseOptions, iframe.__MethodOptions]);
+
+	iframe.get = function(url, options){
+		// summary:
+		//		Send an HTTP GET request using an iframe element with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/iframe.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	iframe.post = function(url, options){
+		// summary:
+		//		Send an HTTP POST request using an iframe element with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/iframe.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	=====*/
+	iframe.create = create;
+	iframe.doc = doc;
+	iframe.setSrc = setSrc;
+
+	// TODO: Make these truly private in 2.0
+	iframe._iframeName = mid + '_IoIframe';
+	iframe._notifyStart = function(){};
+	iframe._dfdQueue = [];
+	iframe._currentDfd = null;
+	iframe._fireNextRequest = fireNextRequest;
+
+	util.addCommonMethods(iframe, ['GET', 'POST']);
+
+	return iframe;
+});
diff --git a/dojo/request/node.js b/dojo/request/node.js
new file mode 100644
index 0000000..8b9d5b6
--- /dev/null
+++ b/dojo/request/node.js
@@ -0,0 +1,195 @@
+define([
+   'require',
+   './util',
+   './handlers',
+   '../errors/RequestTimeoutError',
+   '../node!http',
+   '../node!https',
+   '../node!url',
+   '../node!stream'/*=====,
+	'../request',
+	'../_base/declare' =====*/
+], function(require, util, handlers, RequestTimeoutError, http, https, URL, stream/*=====, request, declare =====*/){
+	var Stream = stream.Stream,
+		undefined;
+
+	var defaultOptions = {
+		method: 'GET',
+		query: null,
+		data: undefined,
+		headers: {}
+	};
+	function node(url, options){
+		var response = util.parseArgs(url, util.deepCreate(defaultOptions, options), options && options.data instanceof Stream);
+		url = response.url;
+		options = response.options;
+
+		var def = util.deferred(
+			response,
+			function(dfd, response){
+				response.clientRequest.abort();
+			}
+		);
+
+		url = URL.parse(url);
+
+		var reqOptions = response.requestOptions = {
+			hostname: url.hostname,
+			port: url.port,
+			socketPath: options.socketPath,
+			method: options.method,
+			headers: options.headers,
+			agent: options.agent,
+			pfx: options.pfx,
+			key: options.key,
+			passphrase: options.passphrase,
+			cert: options.cert,
+			ca: options.ca,
+			ciphers: options.ciphers,
+			rejectUnauthorized: options.rejectUnauthorized === false ? false : true
+		};
+		if(url.path){
+			reqOptions.path = url.path;
+		}
+		if(options.user || options.password){
+			reqOptions.auth = (options.user||'') + ':' + (options.password||'');
+		}
+		var req = response.clientRequest = (url.protocol === 'https:' ? https : http).request(reqOptions);
+
+		if(options.socketOptions){
+			if('timeout' in options.socketOptions){
+				req.setTimeout(options.socketOptions.timeout);
+			}
+			if('noDelay' in options.socketOptions){
+				req.setNoDelay(options.socketOptions.noDelay);
+			}
+			if('keepAlive' in options.socketOptions){
+				var initialDelay = options.socketOptions.keepAlive;
+				req.setKeepAlive(initialDelay >= 0, initialDelay || 0);
+			}
+		}
+
+		req.on('socket', function(){
+			response.hasSocket = true;
+			def.progress(response);
+		});
+
+		req.on('response', function(clientResponse){
+			response.clientResponse = clientResponse;
+			response.status = clientResponse.statusCode;
+			response.getHeader = function(headerName){
+				return clientResponse.headers[headerName.toLowerCase()] || null;
+			};
+
+			var body = [];
+			clientResponse.on('data', function(chunk){
+				body.push(chunk);
+
+				// TODO: progress updates via the deferred
+			});
+			clientResponse.on('end', function(){
+				if(timeout){
+					clearTimeout(timeout);
+				}
+				response.text = body.join('');
+				try{
+					handlers(response);
+					def.resolve(response);
+				}catch(error){
+					def.reject(error);
+				}
+			});
+		});
+
+		req.on('error', def.reject);
+
+		if(options.data){
+			if(typeof options.data === 'string'){
+				req.end(options.data);
+			}else{
+				options.data.pipe(req);
+			}
+		}else{
+			req.end();
+		}
+
+		if(options.timeout){
+			var timeout = setTimeout(function(){
+				def.cancel(new RequestTimeoutError(response));
+			}, options.timeout);
+		}
+
+		return def.promise;
+	}
+
+	/*=====
+	node = function(url, options){
+		// summary:
+		//		Sends a request using the included http or https interface from node.js
+		//		with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/node.__Options?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	node.__BaseOptions = declare(request.__BaseOptions, {
+		// data: String|Object|Stream?
+		//		Data to transfer. This is ignored for GET and DELETE
+		//		requests.
+		// headers: Object?
+		//		Headers to use for the request.
+		// user: String?
+		//		Username to use during the request.
+		// password: String?
+		//		Password to use during the request.
+	});
+	node.__MethodOptions = declare(null, {
+		// method: String?
+		//		The HTTP method to use to make the request. Must be
+		//		uppercase. Default is `"GET"`.
+	});
+	node.__Options = declare([node.__BaseOptions, node.__MethodOptions]);
+
+	node.get = function(url, options){
+		// summary:
+		//		Send an HTTP GET request using XMLHttpRequest with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/node.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	node.post = function(url, options){
+		// summary:
+		//		Send an HTTP POST request using XMLHttpRequest with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/node.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	node.put = function(url, options){
+		// summary:
+		//		Send an HTTP PUT request using XMLHttpRequest with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/node.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	node.del = function(url, options){
+		// summary:
+		//		Send an HTTP DELETE request using XMLHttpRequest with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/node.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	=====*/
+
+	util.addCommonMethods(node);
+
+	return node;
+});
diff --git a/dojo/request/notify.js b/dojo/request/notify.js
new file mode 100644
index 0000000..8392cb5
--- /dev/null
+++ b/dojo/request/notify.js
@@ -0,0 +1,74 @@
+define(['../Evented', '../_base/lang', './util'], function(Evented, lang, util){
+	// module:
+	//		dojo/request/notify
+	// summary:
+	//		Global notification API for dojo/request. Notifications will
+	//		only be emitted if this module is required.
+	//
+	//		| require('dojo/request', 'dojo/request/notify',
+	//		|     function(request, notify){
+	//		|         notify('load', function(response){
+	//		|             if(response.url === 'someUrl.html'){
+	//		|                 console.log('Loaded!');
+	//		|             }
+	//		|         });
+	//		|         request.get('someUrl.html');
+	//		|     }
+	//		| );
+
+	var pubCount = 0,
+		slice = [].slice;
+
+	var hub = lang.mixin(new Evented, {
+		onsend: function(data){
+			if(!pubCount){
+				this.emit('start');
+			}
+			pubCount++;
+		},
+		_onload: function(data){
+			this.emit('done', data);
+		},
+		_onerror: function(data){
+			this.emit('done', data);
+		},
+		_ondone: function(data){
+			if(--pubCount <= 0){
+				pubCount = 0;
+				this.emit('stop');
+			}
+		},
+		emit: function(type, event){
+			var result = Evented.prototype.emit.apply(this, arguments);
+
+			// After all event handlers have run, run _on* handler
+			if(this['_on' + type]){
+				this['_on' + type].apply(this, slice.call(arguments, 1));
+			}
+			return result;
+		}
+	});
+
+	function notify(type, listener){
+		// summary:
+		//		Register a listener to be notified when an event
+		//		in dojo/request happens.
+		// type: String?
+		//		The event to listen for. Events emitted: "start", "send",
+		//		"load", "error", "done", "stop".
+		// listener: Function?
+		//		A callback to be run when an event happens.
+		// returns:
+		//		A signal object that can be used to cancel the listener.
+		//		If remove() is called on this signal object, it will
+		//		stop the listener from being executed.
+		return hub.on(type, listener);
+	}
+	notify.emit = function(type, event, cancel){
+		return hub.emit(type, event, cancel);
+	};
+
+	// Attach notify to dojo/request/util to avoid
+	// try{ require('./notify'); }catch(e){}
+	return util.notify = notify;
+});
diff --git a/dojo/request/registry.js b/dojo/request/registry.js
new file mode 100644
index 0000000..bda7e5d
--- /dev/null
+++ b/dojo/request/registry.js
@@ -0,0 +1,85 @@
+define([
+	'require',
+	'../_base/array',
+	'./default!platform',
+	'./util'
+], function(require, array, fallbackProvider, util){
+	var providers = [];
+
+	function request(url, options){
+		var matchers = providers.slice(0),
+			i = 0,
+			matcher;
+
+		while(matcher=matchers[i++]){
+			if(matcher(url, options)){
+				return matcher.request.call(null, url, options);
+			}
+		}
+
+		return fallbackProvider.apply(null, arguments);
+	}
+
+	function createMatcher(match, provider){
+		var matcher;
+
+		if(provider){
+			if(match.test){
+				// RegExp
+				matcher = function(url){
+					return match.test(url);
+				};
+			}else if(match.apply && match.call){
+				matcher = function(){
+					return match.apply(null, arguments);
+				};
+			}else{
+				matcher = function(url){
+					return url === match;
+				};
+			}
+
+			matcher.request = provider;
+		}else{
+			// If only one argument was passed, assume it is a provider function
+			// to apply unconditionally to all URLs
+			matcher = function(){
+				return true;
+			};
+
+			matcher.request = match;
+		}
+
+		return matcher;
+	}
+
+	request.register = function(url, provider, first){
+		var matcher = createMatcher(url, provider);
+		providers[(first ? 'unshift' : 'push')](matcher);
+
+		return {
+			remove: function(){
+				var idx;
+				if(~(idx = array.indexOf(providers, matcher))){
+					providers.splice(idx, 1);
+				}
+			}
+		};
+	};
+
+	request.load = function(id, parentRequire, loaded, config){
+		if(id){
+			// if there's an id, load and set the fallback provider
+			require([id], function(fallback){
+				fallbackProvider = fallback;
+				loaded(request);
+			});
+		}else{
+			loaded(request);
+		}
+	};
+
+	util.addCommonMethods(request);
+
+	return request;
+});
diff --git a/dojo/request/script.js b/dojo/request/script.js
new file mode 100644
index 0000000..b0ee148
--- /dev/null
+++ b/dojo/request/script.js
@@ -0,0 +1,219 @@
+define([
+	'module',
+	'./watch',
+	'./util',
+	'../_base/array',
+	'../_base/lang',
+	'../on',
+	'../dom',
+	'../dom-construct',
+	'../has',
+	'../_base/window'/*=====,
+	'../request',
+	'../_base/declare' =====*/
+], function(module, watch, util, array, lang, on, dom, domConstruct, has, win/*=====, request, declare =====*/){
+	has.add('script-readystatechange', function(global, document){
+		var script = document.createElement('script');
+		return typeof script['onreadystatechange'] !== 'undefined' &&
+			(typeof global['opera'] === 'undefined' || global['opera'].toString() !== '[object Opera]');
+	});
+
+	var mid = module.id.replace(/[\/\.\-]/g, '_'),
+		counter = 0,
+		loadEvent = has('script-readystatechange') ? 'readystatechange' : 'load',
+		readyRegExp = /complete|loaded/,
+		callbacks = this[mid + '_callbacks'] = {},
+		deadScripts = [];
+
+	function attach(id, url, frameDoc){
+		var doc = (frameDoc || win.doc),
+			element = doc.createElement('script');
+
+		element.type = 'text/javascript';
+		element.src = url;
+		element.id = id;
+		element.async = true;
+		element.charset = 'utf-8';
+
+		return doc.getElementsByTagName('head')[0].appendChild(element);
+	}
+
+	function remove(id, frameDoc, cleanup){
+		domConstruct.destroy(dom.byId(id, frameDoc));
+
+		if(callbacks[id]){
+			if(cleanup){
+				// set callback to a function that deletes itself so requests that
+				// are in-flight don't error out when returning and also
+				// clean up after themselves
+				callbacks[id] = function(){
+					delete callbacks[id];
+				};
+			}else{
+				delete callbacks[id];
+			}
+		}
+	}
+
+	function _addDeadScript(dfd){
+		// Be sure to check ioArgs because it can dynamically change in the dojox/io plugins.
+		// See http://bugs.dojotoolkit.org/ticket/15890.
+		var options = dfd.response.options,
+			frameDoc = options.ioArgs ? options.ioArgs.frameDoc : options.frameDoc;
+
+		deadScripts.push({ id: dfd.id, frameDoc: frameDoc });
+
+		if(options.ioArgs){
+			options.ioArgs.frameDoc = null;
+		}
+		options.frameDoc = null;
+	}
+
+	function canceler(dfd, response){
+		if(dfd.canDelete){
+			//For timeouts and cancels, remove the script element immediately to
+			//avoid a response from it coming back later and causing trouble.
+			script._remove(dfd.id, response.options.frameDoc, true);
+		}
+	}
+	function isValid(response){
+		//Do script cleanup here. We wait for one inflight pass
+		//to make sure we don't get any weird things by trying to remove a script
+		//tag that is part of the call chain (IE 6 has been known to
+		//crash in that case).
+		if(deadScripts && deadScripts.length){
+			array.forEach(deadScripts, function(_script){
+				script._remove(_script.id, _script.frameDoc);
+				_script.frameDoc = null;
+			});
+			deadScripts = [];
+		}
+
+		return response.options.jsonp ? !response.data : true;
+	}
+	function isReadyScript(response){
+		return !!this.scriptLoaded;
+	}
+	function isReadyCheckString(response){
+		var checkString = response.options.checkString;
+
+		return checkString && eval('typeof(' + checkString + ') !== "undefined"');
+	}
+	function handleResponse(response, error){
+		if(this.canDelete){
+			_addDeadScript(this);
+		}
+		if(error){
+			this.reject(error);
+		}else{
+			this.resolve(response);
+		}
+	}
+
+	function script(url, options, returnDeferred){
+		var response = util.parseArgs(url, util.deepCopy({}, options));
+		url = response.url;
+		options = response.options;
+
+		var dfd = util.deferred(
+			response,
+			canceler,
+			isValid,
+			options.jsonp ? null : (options.checkString ? isReadyCheckString : isReadyScript),
+			handleResponse
+		);
+
+		lang.mixin(dfd, {
+			id: mid + (counter++),
+			canDelete: false
+		});
+
+		if(options.jsonp){
+			var queryParameter = new RegExp('[?&]' + options.jsonp + '=');
+			if(!queryParameter.test(url)){
+				url += (~url.indexOf('?') ? '&' : '?') +
+					options.jsonp + '=' +
+					(options.frameDoc ? 'parent.' : '') +
+					mid + '_callbacks.' + dfd.id;
+			}
+
+			dfd.canDelete = true;
+			callbacks[dfd.id] = function(json){
+				response.data = json;
+				dfd.handleResponse(response);
+			};
+		}
+
+		if(util.notify){
+			util.notify.emit('send', response, dfd.promise.cancel);
+		}
+
+		if(!options.canAttach || options.canAttach(dfd)){
+			var node = script._attach(dfd.id, url, options.frameDoc);
+
+			if(!options.jsonp && !options.checkString){
+				var handle = on(node, loadEvent, function(evt){
+					if(evt.type === 'load' || readyRegExp.test(node.readyState)){
+						handle.remove();
+						dfd.scriptLoaded = evt;
+					}
+				});
+			}
+		}
+
+		watch(dfd);
+
+		return returnDeferred ? dfd : dfd.promise;
+	}
+	script.get = script;
+	/*=====
+	script = function(url, options){
+		// summary:
+		//		Sends a request using a script element with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/script.__Options?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	script.__BaseOptions = declare(request.__BaseOptions, {
+		// jsonp: String?
+		//		The URL parameter name that indicates the JSONP callback string.
+		//		For instance, when using Yahoo JSONP calls it is normally,
+		//		jsonp: "callback". For AOL JSONP calls it is normally
+		//		jsonp: "c".
+		// checkString: String?
+		//		A string of JavaScript that when evaluated like so:
+		//		"typeof(" + checkString + ") != 'undefined'"
+		//		being true means that the script fetched has been loaded.
+		//		Do not use this if doing a JSONP type of call (use `jsonp` instead).
+		// frameDoc: Document?
+		//		The Document object of a child iframe. If this is passed in, the script
+		//		will be attached to that document. This can be helpful in some comet long-polling
+		//		scenarios with Firefox and Opera.
+	});
+	script.__MethodOptions = declare(null, {
+		// method: String?
+		//		This option is ignored. All requests using this transport are
+		//		GET requests.
+	});
+	script.__Options = declare([script.__BaseOptions, script.__MethodOptions]);
+
+	script.get = function(url, options){
+		// summary:
+		//		Send an HTTP GET request using a script element with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/script.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	=====*/
+
+	// TODO: Remove in 2.0
+	script._attach = attach;
+	script._remove = remove;
+	script._callbacksProperty = mid + '_callbacks';
+
+	return script;
+});
diff --git a/dojo/request/util.js b/dojo/request/util.js
new file mode 100644
index 0000000..86a9b42
--- /dev/null
+++ b/dojo/request/util.js
@@ -0,0 +1,158 @@
+define([
+	'exports',
+	'../errors/RequestError',
+	'../errors/CancelError',
+	'../Deferred',
+	'../io-query',
+	'../_base/array',
+	'../_base/lang',
+	'../promise/Promise'
+], function(exports, RequestError, CancelError, Deferred, ioQuery, array, lang, Promise){
+	exports.deepCopy = function deepCopy(target, source){
+		for(var name in source){
+			var tval = target[name],
+				sval = source[name];
+			if(tval !== sval){
+				if(tval && typeof tval === 'object' && sval && typeof sval === 'object'){
+					exports.deepCopy(tval, sval);
+				}else{
+					target[name] = sval;
+				}
+			}
+		}
+		return target;
+	};
+
+	exports.deepCreate = function deepCreate(source, properties){
+		properties = properties || {};
+		var target = lang.delegate(source),
+			name, value;
+
+		for(name in source){
+			value = source[name];
+
+			if(value && typeof value === 'object'){
+				target[name] = exports.deepCreate(value, properties[name]);
+			}
+		}
+		return exports.deepCopy(target, properties);
+	};
+
+	var freeze = Object.freeze || function(obj){ return obj; };
+	function okHandler(response){
+		return freeze(response);
+	}
+	function dataHandler (response) {
+		return response.data || response.text;
+	}
+
+	exports.deferred = function deferred(response, cancel, isValid, isReady, handleResponse, last){
+		var def = new Deferred(function(reason){
+			cancel && cancel(def, response);
+
+			if(!reason || !(reason instanceof RequestError) && !(reason instanceof CancelError)){
+				return new CancelError('Request canceled', response);
+			}
+			return reason;
+		});
+
+		def.response = response;
+		def.isValid = isValid;
+		def.isReady = isReady;
+		def.handleResponse = handleResponse;
+
+		function errHandler(error){
+			error.response = response;
+			throw error;
+		}
+		var responsePromise = def.then(okHandler).otherwise(errHandler);
+
+		if(exports.notify){
+			responsePromise.then(
+				lang.hitch(exports.notify, 'emit', 'load'),
+				lang.hitch(exports.notify, 'emit', 'error')
+			);
+		}
+
+		var dataPromise = responsePromise.then(dataHandler);
+
+		// http://bugs.dojotoolkit.org/ticket/16794
+		// The following works around a leak in IE9 through the
+		// prototype using lang.delegate on dataPromise and
+		// assigning the result a property with a reference to
+		// responsePromise.
+		var promise = new Promise();
+		for (var prop in dataPromise) {
+			if (dataPromise.hasOwnProperty(prop)) {
+				promise[prop] = dataPromise[prop];
+			}
+		}
+		promise.response = responsePromise;
+		freeze(promise);
+		// End leak fix
+
+
+		if(last){
+			def.then(function(response){
+				last.call(def, response);
+			}, function(error){
+				last.call(def, response, error);
+			});
+		}
+
+		def.promise = promise;
+		def.then = promise.then;
+
+		return def;
+	};
+
+	exports.addCommonMethods = function addCommonMethods(provider, methods){
+		array.forEach(methods||['GET', 'POST', 'PUT', 'DELETE'], function(method){
+			provider[(method === 'DELETE' ? 'DEL' : method).toLowerCase()] = function(url, options){
+				options = lang.delegate(options||{});
+				options.method = method;
+				return provider(url, options);
+			};
+		});
+	};
+
+	exports.parseArgs = function parseArgs(url, options, skipData){
+		var data = options.data,
+			query = options.query;
+		
+		if(data && !skipData){
+			if(typeof data === 'object'){
+				options.data = ioQuery.objectToQuery(data);
+			}
+		}
+
+		if(query){
+			if(typeof query === 'object'){
+				query = ioQuery.objectToQuery(query);
+			}
+			if(options.preventCache){
+				query += (query ? '&' : '') + 'request.preventCache=' + (+(new Date));
+			}
+		}else if(options.preventCache){
+			query = 'request.preventCache=' + (+(new Date));
+		}
+
+		if(url && query){
+			url += (~url.indexOf('?') ? '&' : '?') + query;
+		}
+
+		return {
+			url: url,
+			options: options,
+			getHeader: function(headerName){ return null; }
+		};
+	};
+
+	exports.checkStatus = function(stat){
+		stat = stat || 0;
+		return (stat >= 200 && stat < 300) || // allow any 2XX response code
+			stat === 304 ||                 // or, get it out of the cache
+			stat === 1223 ||                // or, Internet Explorer mangled the status code
+			!stat;                         // or, we're Titanium/browser chrome/chrome extension requesting a local file
+	};
+});
diff --git a/dojo/request/watch.js b/dojo/request/watch.js
new file mode 100644
index 0000000..6e0f2f4
--- /dev/null
+++ b/dojo/request/watch.js
@@ -0,0 +1,109 @@
+define([
+	'./util',
+	'../errors/RequestTimeoutError',
+	'../errors/CancelError',
+	'../_base/array',
+	'../has!host-browser?../_base/window:',
+	'../has!host-browser?dom-addeventlistener?:../on:'
+], function(util, RequestTimeoutError, CancelError, array, win, on){
+	// avoid setting a timer per request. It degrades performance on IE
+	// something fierece if we don't use unified loops.
+	var _inFlightIntvl = null,
+		_inFlight = [];
+
+	function watchInFlight(){
+		// summary:
+		//		internal method that checks each inflight XMLHttpRequest to see
+		//		if it has completed or if the timeout situation applies.
+
+		var now = +(new Date);
+
+		// we need manual loop because we often modify _inFlight (and therefore 'i') while iterating
+		for(var i = 0, dfd; i < _inFlight.length && (dfd = _inFlight[i]); i++){
+			var response = dfd.response,
+				options = response.options;
+			if((dfd.isCanceled && dfd.isCanceled()) || (dfd.isValid && !dfd.isValid(response))){
+				_inFlight.splice(i--, 1);
+				watch._onAction && watch._onAction();
+			}else if(dfd.isReady && dfd.isReady(response)){
+				_inFlight.splice(i--, 1);
+				dfd.handleResponse(response);
+				watch._onAction && watch._onAction();
+			}else if(dfd.startTime){
+				// did we timeout?
+				if(dfd.startTime + (options.timeout || 0) < now){
+					_inFlight.splice(i--, 1);
+					// Cancel the request so the io module can do appropriate cleanup.
+					dfd.cancel(new RequestTimeoutError('Timeout exceeded', response));
+					watch._onAction && watch._onAction();
+				}
+			}
+		}
+
+		watch._onInFlight && watch._onInFlight(dfd);
+
+		if(!_inFlight.length){
+			clearInterval(_inFlightIntvl);
+			_inFlightIntvl = null;
+		}
+	}
+
+	function watch(dfd){
+		// summary:
+		//		Watches the io request represented by dfd to see if it completes.
+		// dfd: Deferred
+		//		The Deferred object to watch.
+		// response: Object
+		//		The object used as the value of the request promise.
+		// validCheck: Function
+		//		Function used to check if the IO request is still valid. Gets the dfd
+		//		object as its only argument.
+		// ioCheck: Function
+		//		Function used to check if basic IO call worked. Gets the dfd
+		//		object as its only argument.
+		// resHandle: Function
+		//		Function used to process response. Gets the dfd
+		//		object as its only argument.
+		if(dfd.response.options.timeout){
+			dfd.startTime = +(new Date);
+		}
+
+		if(dfd.isFulfilled()){
+			// bail out if the deferred is already fulfilled
+			return;
+		}
+
+		_inFlight.push(dfd);
+		if(!_inFlightIntvl){
+			_inFlightIntvl = setInterval(watchInFlight, 50);
+		}
+
+		// handle sync requests separately from async:
+		// http://bugs.dojotoolkit.org/ticket/8467
+		if(dfd.response.options.sync){
+			watchInFlight();
+		}
+	}
+
+	watch.cancelAll = function cancelAll(){
+		// summary:
+		//		Cancels all pending IO requests, regardless of IO type
+		try{
+			array.forEach(_inFlight, function(dfd){
+				try{
+					dfd.cancel(new CancelError('All requests canceled.'));
+				}catch(e){}
+			});
+		}catch(e){}
+	};
+
+	if(win && on && win.doc.attachEvent){
+		// Automatically call cancel all io calls on unload in IE
+		// http://bugs.dojotoolkit.org/ticket/2357
+		on(win.global, 'unload', function(){
+			watch.cancelAll();
+		});
+	}
+
+	return watch;
+});
diff --git a/dojo/request/xhr.js b/dojo/request/xhr.js
new file mode 100644
index 0000000..647c2ec
--- /dev/null
+++ b/dojo/request/xhr.js
@@ -0,0 +1,316 @@
+define([
+	'../errors/RequestError',
+	'./watch',
+	'./handlers',
+	'./util',
+	'../has'/*=====,
+	'../request',
+	'../_base/declare' =====*/
+], function(RequestError, watch, handlers, util, has/*=====, request, declare =====*/){
+	has.add('native-xhr', function(){
+		// if true, the environment has a native XHR implementation
+		return typeof XMLHttpRequest !== 'undefined';
+	});
+	has.add('dojo-force-activex-xhr', function(){
+		return has('activex') && !document.addEventListener && window.location.protocol === 'file:';
+	});
+
+	has.add('native-xhr2', function(){
+		if(!has('native-xhr')){ return; }
+		var x = new XMLHttpRequest();
+		return typeof x['addEventListener'] !== 'undefined' &&
+			(typeof opera === 'undefined' || typeof x['upload'] !== 'undefined');
+	});
+
+	has.add('native-formdata', function(){
+		// if true, the environment has a native FormData implementation
+		return typeof FormData === 'function';
+	});
+
+	function handleResponse(response, error){
+		var _xhr = response.xhr;
+		response.status = response.xhr.status;
+		response.text = _xhr.responseText;
+
+		if(response.options.handleAs === 'xml'){
+			response.data = _xhr.responseXML;
+		}
+
+		if(!error){
+			try{
+				handlers(response);
+			}catch(e){
+				error = e;
+			}
+		}
+
+		if(error){
+			this.reject(error);
+		}else if(util.checkStatus(_xhr.status)){
+			this.resolve(response);
+		}else{
+			error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response);
+
+			this.reject(error);
+		}
+	}
+
+	var isValid, isReady, addListeners, cancel;
+	if(has('native-xhr2')){
+		// Any platform with XHR2 will only use the watch mechanism for timeout.
+
+		isValid = function(response){
+			// summary:
+			//		Check to see if the request should be taken out of the watch queue
+			return !this.isFulfilled();
+		};
+		cancel = function(dfd, response){
+			// summary:
+			//		Canceler for deferred
+			response.xhr.abort();
+		};
+		addListeners = function(_xhr, dfd, response){
+			// summary:
+			//		Adds event listeners to the XMLHttpRequest object
+			function onLoad(evt){
+				dfd.handleResponse(response);
+			}
+			function onError(evt){
+				var _xhr = evt.target;
+				var error = new RequestError('Unable to load ' + response.url + ' status: ' + _xhr.status, response);
+				dfd.handleResponse(response, error);
+			}
+
+			function onProgress(evt){
+				if(evt.lengthComputable){
+					response.loaded = evt.loaded;
+					response.total = evt.total;
+					dfd.progress(response);
+				}
+			}
+
+			_xhr.addEventListener('load', onLoad, false);
+			_xhr.addEventListener('error', onError, false);
+			_xhr.addEventListener('progress', onProgress, false);
+
+			return function(){
+				_xhr.removeEventListener('load', onLoad, false);
+				_xhr.removeEventListener('error', onError, false);
+				_xhr.removeEventListener('progress', onProgress, false);
+				_xhr = null;
+			};
+		};
+	}else{
+		isValid = function(response){
+			return response.xhr.readyState; //boolean
+		};
+		isReady = function(response){
+			return 4 === response.xhr.readyState; //boolean
+		};
+		cancel = function(dfd, response){
+			// summary:
+			//		canceller function for util.deferred call.
+			var xhr = response.xhr;
+			var _at = typeof xhr.abort;
+			if(_at === 'function' || _at === 'object' || _at === 'unknown'){
+				xhr.abort();
+			}
+		};
+	}
+
+	function getHeader(headerName){
+		return this.xhr.getResponseHeader(headerName);
+	}
+
+	var undefined,
+		defaultOptions = {
+			data: null,
+			query: null,
+			sync: false,
+			method: 'GET'
+		};
+	function xhr(url, options, returnDeferred){
+		var response = util.parseArgs(
+			url,
+			util.deepCreate(defaultOptions, options),
+			has('native-formdata') && options && options.data && options.data instanceof FormData
+		);
+		url = response.url;
+		options = response.options;
+
+		var remover,
+			last = function(){
+				remover && remover();
+			};
+
+		//Make the Deferred object for this xhr request.
+		var dfd = util.deferred(
+			response,
+			cancel,
+			isValid,
+			isReady,
+			handleResponse,
+			last
+		);
+		var _xhr = response.xhr = xhr._create();
+
+		if(!_xhr){
+			// If XHR factory somehow returns nothings,
+			// cancel the deferred.
+			dfd.cancel(new RequestError('XHR was not created'));
+			return returnDeferred ? dfd : dfd.promise;
+		}
+
+		response.getHeader = getHeader;
+
+		if(addListeners){
+			remover = addListeners(_xhr, dfd, response);
+		}
+
+		var data = options.data,
+			async = !options.sync,
+			method = options.method;
+
+		try{
+			// IE6 won't let you call apply() on the native function.
+			_xhr.open(method, url, async, options.user || undefined, options.password || undefined);
+
+			if(options.withCredentials){
+				_xhr.withCredentials = options.withCredentials;
+			}
+
+			var headers = options.headers,
+				contentType = 'application/x-www-form-urlencoded';
+			if(headers){
+				for(var hdr in headers){
+					if(hdr.toLowerCase() === 'content-type'){
+						contentType = headers[hdr];
+					}else if(headers[hdr]){
+						//Only add header if it has a value. This allows for instance, skipping
+						//insertion of X-Requested-With by specifying empty value.
+						_xhr.setRequestHeader(hdr, headers[hdr]);
+					}
+				}
+			}
+
+			if(contentType && contentType !== false){
+				_xhr.setRequestHeader('Content-Type', contentType);
+			}
+			if(!headers || !('X-Requested-With' in headers)){
+				_xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
+			}
+
+			if(util.notify){
+				util.notify.emit('send', response, dfd.promise.cancel);
+			}
+			_xhr.send(data);
+		}catch(e){
+			dfd.reject(e);
+		}
+
+		watch(dfd);
+		_xhr = null;
+
+		return returnDeferred ? dfd : dfd.promise;
+	}
+
+	/*=====
+	xhr = function(url, options){
+		// summary:
+		//		Sends a request using XMLHttpRequest with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/xhr.__Options?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	xhr.__BaseOptions = declare(request.__BaseOptions, {
+		// sync: Boolean?
+		//		Whether to make a synchronous request or not. Default
+		//		is `false` (asynchronous).
+		// data: String|Object|FormData?
+		//		Data to transfer. This is ignored for GET and DELETE
+		//		requests.
+		// headers: Object?
+		//		Headers to use for the request.
+		// user: String?
+		//		Username to use during the request.
+		// password: String?
+		//		Password to use during the request.
+		// withCredentials: Boolean?
+		//		For cross-site requests, whether to send credentials
+		//		or not.
+	});
+	xhr.__MethodOptions = declare(null, {
+		// method: String?
+		//		The HTTP method to use to make the request. Must be
+		//		uppercase. Default is `"GET"`.
+	});
+	xhr.__Options = declare([xhr.__BaseOptions, xhr.__MethodOptions]);
+
+	xhr.get = function(url, options){
+		// summary:
+		//		Send an HTTP GET request using XMLHttpRequest with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/xhr.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	xhr.post = function(url, options){
+		// summary:
+		//		Send an HTTP POST request using XMLHttpRequest with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/xhr.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	xhr.put = function(url, options){
+		// summary:
+		//		Send an HTTP PUT request using XMLHttpRequest with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/xhr.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	xhr.del = function(url, options){
+		// summary:
+		//		Send an HTTP DELETE request using XMLHttpRequest with the given URL and options.
+		// url: String
+		//		URL to request
+		// options: dojo/request/xhr.__BaseOptions?
+		//		Options for the request.
+		// returns: dojo/request.__Promise
+	};
+	=====*/
+	xhr._create = function(){
+		// summary:
+		//		does the work of portably generating a new XMLHTTPRequest object.
+		throw new Error('XMLHTTP not available');
+	};
+	if(has('native-xhr') && !has('dojo-force-activex-xhr')){
+		xhr._create = function(){
+			return new XMLHttpRequest();
+		};
+	}else if(has('activex')){
+		try{
+			new ActiveXObject('Msxml2.XMLHTTP');
+			xhr._create = function(){
+				return new ActiveXObject('Msxml2.XMLHTTP');
+			};
+		}catch(e){
+			try{
+				new ActiveXObject('Microsoft.XMLHTTP');
+				xhr._create = function(){
+					return new ActiveXObject('Microsoft.XMLHTTP');
+				};
+			}catch(e){}
+		}
+	}
+
+	util.addCommonMethods(xhr);
+
+	return xhr;
+});
diff --git a/dojo/resources/_modules.js b/dojo/resources/_modules.js
deleted file mode 100644
index e093a58..0000000
--- a/dojo/resources/_modules.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*=====
-// Supplemental summaries for those hard-to-doc places your conventional doc parser can't reach.
-// Where possible, these summaries should appear inline in the code.
-//
-// this is "package level documentation"
-
-dojo.cldr = {
-	// summary: transformation of relevant pieces of the Unicode.org Common Locale Data Repository
-	// (see http://unicode.org/cldr) to JSON from the original XML with associated utility classes
-};
-
-dojo.data = {
-	// summary: A uniform data access layer
-};
-
-dojo.dnd = {
-	// summary: Drag and Drop resources
-};
-
-dojo.io = {
-	// summary: Additional I/O transports (Ajax)
-};
-
-dojo.rpc = {
-	// summary: Dojo remote-procedure-call resources
-};
-
-// "variables"
-
-dojo.baseUrl = {
-	// summary: The root relative path to dojo.js (as a string)
-	// example:
-	//	if(typeof dojo != "undefined"){ console.log(dojo.baseUrl); }
-};
-
-=====*/
diff --git a/dojo/resources/dnd.css b/dojo/resources/dnd.css
index fb06118..5c8f1e6 100644
--- a/dojo/resources/dnd.css
+++ b/dojo/resources/dnd.css
@@ -11,6 +11,6 @@
 .dojoDndHandle {cursor: move;}
 .dojoDndIgnore {cursor: default;}
 
-.dijit_a11y .dojoDndAvatar { font-size: 1em; font-weight:bold;}
-.dijit_a11y .dojoDndAvatarHeader td {padding-left:2px !important;}
-.dijit_a11y .dojoDndAvatarHeader td span {padding-right: 5px;}
+.dj_a11y .dojoDndAvatar { font-size: 1em; font-weight:bold;}
+.dj_a11y .dojoDndAvatarHeader td {padding-left:2px !important;}
+.dj_a11y .dojoDndAvatarHeader td span {padding-right: 5px;}
diff --git a/dojo/robot.js b/dojo/robot.js
index 3fb9ea0..4e5ba70 100644
--- a/dojo/robot.js
+++ b/dojo/robot.js
@@ -1,172 +1,170 @@
-define(["dojo", "doh/_browserRunner", "doh/robot", "dojo/window"], function(dojo, doh) {
+define([
+	"./_base/array",
+	"./dom",
+	"./dom-geometry",
+	"./_base/kernel",
+	"./_base/lang",
+	"./_base/window",
+	"doh/_browserRunner",
+	"doh/robot",
+	"./window"
+], function(array, dom, geom, kernel, lang, win, doh, robot, winUtils){
 
-dojo.experimental("dojo.robot");
+kernel.experimental("dojo.robot");
 
-// users who use doh+dojo get the added convenience of dojo.mouseMoveAt,
+// users who use doh+dojo get the added convenience of robot.mouseMoveAt(),
 // instead of computing the absolute coordinates of their elements themselves
-dojo.mixin(doh.robot,{
+lang.mixin(robot, {
 
 	_resolveNode: function(/*String||DOMNode||Function*/ n){
 		if(typeof n == "function"){
 			// if the user passed a function returning a node, evaluate it
 			n = n();
 		}
-		return n? dojo.byId(n) : null;
+		return n ? dom.byId(n) : null;
 	},
 
 	_scrollIntoView: function(/*Node*/ n){
-		// scrolls the passed node into view, scrolling all ancester frames/windows as well.
+		// scrolls the passed node into view, scrolling all ancestor frames/windows as well.
 		// Assumes parent iframes can be made fully visible given the current browser window size
-		var dr = doh.robot,
-			p = null;
-		dojo.forEach(dr._getWindowChain(n), function(w){
-			dojo.withGlobal(w, function(){
-				// get the position of the node wrt its parent window
-				// if it is a parent frame, its padding and border extents will get added in
-				var p2 = dojo.position(n, false),
-					b = dojo._getPadBorderExtents(n),
-					oldp = null;
-				// if p2 is the position of the original passed node, store the position away as p
-				// otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
-				if(!p){
-					p = p2;
-				}else{
-					oldp = p;
-					p = {x: p.x+p2.x+b.l,
-						y: p.y+p2.y+b.t,
-						w: p.w,
-						h: p.h};
+		var p = null;
+		array.forEach(robot._getWindowChain(n), function(w){
+			// get the position of the node wrt its parent window
+			// if it is a parent frame, its padding and border extents will get added in
+			var p2 = geom.position(n, false),
+				b = geom.getPadBorderExtents(n),
+				oldp = null;
+			// if p2 is the position of the original passed node, store the position away as p
+			// otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
+			if(!p){
+				p = p2;
+			}else{
+				oldp = p;
+				p = {x: p.x+p2.x+b.l,
+					y: p.y+p2.y+b.t,
+					w: p.w,
+					h: p.h};
 
-				}
-				// scroll the parent window so that the node translated into the parent window's coordinate space is in view
-				dojo.window.scrollIntoView(n,p);
-				// adjust position for the new scroll offsets
-				p2 = dojo.position(n, false);
-				if(!oldp){
-					p = p2;
-				}else{
-					p = {x: oldp.x+p2.x+b.l,
-						y: oldp.y+p2.y+b.t,
-						w: p.w,
-						h: p.h};
-				}
-				// get the parent iframe so it can be scrolled too
-				n = w.frameElement;
-			});
+			}
+			// scroll the parent window so that the node translated into the parent window's coordinate space is in view
+			winUtils.scrollIntoView(n,p);
+			// adjust position for the new scroll offsets
+			p2 = geom.position(n, false);
+			if(!oldp){
+				p = p2;
+			}else{
+				p = {x: oldp.x+p2.x+b.l,
+					y: oldp.y+p2.y+b.t,
+					w: p.w,
+					h: p.h};
+			}
+			// get the parent iframe so it can be scrolled too
+			n = w.frameElement;
 		});
 	},
 
 	_position: function(/*Node*/ n){
-		// Returns the dojo.position of the passed node wrt the passed window's viewport,
+		// Returns the geom.position of the passed node wrt the passed window's viewport,
 		// following any parent iframes containing the node and clipping the node to each iframe.
 		// precondition: _scrollIntoView already called
-		var p = null, M = Math.max, m = Math.min;
+		var p = null, max = Math.max, min = Math.min;
 		// p: the returned position of the node
-		dojo.forEach(doh.robot._getWindowChain(n), function(w){
-			dojo.withGlobal(w, function(){
-				// get the position of the node wrt its parent window
-				// if it is a parent frame, its padding and border extents will get added in
-				var p2 = dojo.position(n, false), b = dojo._getPadBorderExtents(n);
-				// if p2 is the position of the original passed node, store the position away as p
-				// otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
-				if(!p){
-					p = p2;
-				}else{
-					var view;
-					dojo.withGlobal(n.contentWindow,function(){
-						view=dojo.window.getBox();
-					});
-					p2.r = p2.x+view.w;
-					p2.b = p2.y+view.h;
-					p = {x: M(p.x+p2.x,p2.x)+b.l, // clip left edge of node wrt the iframe
-						y: M(p.y+p2.y,p2.y)+b.t,	// top edge
-						r: m(p.x+p2.x+p.w,p2.r)+b.l,	// right edge (to compute width)
-						b: m(p.y+p2.y+p.h,p2.b)+b.t}; // bottom edge (to compute height)
-					// save a few bytes by computing width and height from r and b
-					p.w = p.r-p.x;
-					p.h = p.b-p.y;
-				}
-				// the new node is now the old node's parent iframe
-				n=w.frameElement;
-			});
+		array.forEach(robot._getWindowChain(n), function(w){
+			// get the position of the node wrt its parent window
+			// if it is a parent frame, its padding and border extents will get added in
+			var p2 = geom.position(n, false), b = geom.getPadBorderExtents(n);
+			// if p2 is the position of the original passed node, store the position away as p
+			// otherwise, node is actually an iframe. in this case, add the iframe's position wrt its parent window and also the iframe's padding and border extents
+			if(!p){
+				p = p2;
+			}else{
+				var view = winUtils.getBox(n.contentWindow.document);
+				p2.r = p2.x+view.w;
+				p2.b = p2.y+view.h;
+				p = {x: max(p.x+p2.x,p2.x)+b.l, // clip left edge of node wrt the iframe
+					y: max(p.y+p2.y,p2.y)+b.t,	// top edge
+					r: min(p.x+p2.x+p.w,p2.r)+b.l,	// right edge (to compute width)
+					b: min(p.y+p2.y+p.h,p2.b)+b.t}; // bottom edge (to compute height)
+				// save a few bytes by computing width and height from r and b
+				p.w = p.r-p.x;
+				p.h = p.b-p.y;
+			}
+			// the new node is now the old node's parent iframe
+			n=w.frameElement;
 		});
 		return p;
 	},
 
 	_getWindowChain : function(/*Node*/ n){
 		// Returns an array of windows starting from the passed node's parent window and ending at dojo's window
-		var cW = dojo.window.get(n.ownerDocument);
-		var arr=[cW];
+		var cW = winUtils.get(n.ownerDocument);
+		var arr = [cW];
 		var f = cW.frameElement;
-		return (cW == dojo.global || f == null)? arr : arr.concat(doh.robot._getWindowChain(f));
+		return (cW == win.global || !f) ? arr : arr.concat(robot._getWindowChain(f));
 	},
 
 	scrollIntoView : function(/*String||DOMNode||Function*/ node, /*Number, optional*/ delay){
 		// summary:
 		//		Scroll the passed node into view, if it is not.
-		//
 		// node:
 		//		The id of the node, or the node itself, to move the mouse to.
 		//		If you pass an id or a function that returns a node, the node will not be evaluated until the movement executes.
 		//		This is useful if you need to move the mouse to an node that is not yet present.
-		//
 		// delay:
 		//		Delay, in milliseconds, to wait before firing.
 		//		The delay is a delta with respect to the previous automation call.
-		//
-		doh.robot.sequence(function(){
-			doh.robot._scrollIntoView(doh.robot._resolveNode(node));
+
+		robot.sequence(function(){
+			robot._scrollIntoView(robot._resolveNode(node));
 		}, delay);
 	},
 
 	mouseMoveAt : function(/*String||DOMNode||Function*/ node, /*Integer, optional*/ delay, /*Integer, optional*/ duration, /*Number, optional*/ offsetX, /*Number, optional*/ offsetY){
 		// summary:
 		//		Moves the mouse over the specified node at the specified relative x,y offset.
-		//
 		// description:
-		// 		Moves the mouse over the specified node at the specified relative x,y offset.
-		// 		If you do not specify an offset, mouseMove will default to move to the middle of the node.
-		// 		Example: to move the mouse over a ComboBox's down arrow node, call doh.mouseMoveAt(dijit.byId('setvaluetest').downArrowNode);
-		//
+		//		Moves the mouse over the specified node at the specified relative x,y offset.
+		//		If you do not specify an offset, mouseMove will default to move to the middle of the node.
+		//		Example: to move the mouse over a ComboBox's down arrow node, call doh.mouseMoveAt(dijit.byId('setvaluetest').downArrowNode);
 		// node:
 		//		The id of the node, or the node itself, to move the mouse to.
 		//		If you pass an id or a function that returns a node, the node will not be evaluated until the movement executes.
 		//		This is useful if you need to move the mouse to an node that is not yet present.
-		//
 		// delay:
 		//		Delay, in milliseconds, to wait before firing.
 		//		The delay is a delta with respect to the previous automation call.
 		//		For example, the following code ends after 600ms:
-		//			doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
-		//			doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
-		//
+		// |	robot.mouseClick({left:true}, 100) // first call; wait 100ms
+		// |	robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
 		// duration:
 		//		Approximate time Robot will spend moving the mouse
 		//		The default is 100ms.
-		//
 		// offsetX:
 		//		x offset relative to the node, in pixels, to move the mouse. The default is half the node's width.
-		//
 		// offsetY:
 		//		y offset relative to the node, in pixels, to move the mouse. The default is half the node's height.
-		//
 
-		doh.robot._assertRobot();
-		duration = duration||100;
+		robot._assertRobot();
+
+		// Schedule an action to scroll the node into view, then calculate it's center point
+		var point = {};
 		this.sequence(function(){
-			node=doh.robot._resolveNode(node);
-			doh.robot._scrollIntoView(node);
-			var pos = doh.robot._position(node);
+			node = robot._resolveNode(node);
+			robot._scrollIntoView(node);
+			var pos = robot._position(node);
 			if(offsetY === undefined){
-				offsetX=pos.w/2;
-				offsetY=pos.h/2;
+				offsetX = pos.w/2;
+				offsetY = pos.h/2;
 			}
-			var x = pos.x+offsetX;
-			var y = pos.y+offsetY;
-			doh.robot._mouseMove(x, y, false, duration);
-		}, delay, duration);
+			point.x = pos.x+offsetX;
+			point.y = pos.y+offsetY;
+		}, delay);
+
+		// Schedule a bunch of actions to move the mouse from the current position to point.
+		// These actions won't run until after the above callback.
+		this.mouseMoveTo(point, 0, duration, false);
 	}
 });
 
-return doh.robot;
+return robot;
 });
diff --git a/dojo/robotx.js b/dojo/robotx.js
index 9f519c8..c376a88 100644
--- a/dojo/robotx.js
+++ b/dojo/robotx.js
@@ -1,161 +1,171 @@
-define(["dojo", "dojo/robot"], function(dojo) {
+define([
+	"require",
+	"doh/main",
+	"./aspect",
+	"./dom-construct",
+	"./dom-style",
+	"./_base/kernel",
+	"./_base/lang",
+	"./on",
+	"./robot",
+	"./sniff",
+	"./_base/window"
+], function(require, doh, aspect, construct, style, kernel, lang, on, robot, has, win){
+
+kernel.experimental("dojo.robotx");
+
+// module:
+//		dojo.robotx
+// description:
+//		loads an external app into an iframe and points dojo.doc to the iframe document, allowing the robot to control it
+//		to use: set robotURL in djConfig to the URL you want to load
+//		dojo.require this file
+
+// The iframe containing the external app
+var iframe = null;
 
-dojo.experimental("dojo.robotx");
+// On IE6/7, a firebug console will appear.   Scrunch it a bit to leave room for the external test file.
+kernel.config.debugHeight = kernel.config.debugHeight || 200;
 
-// loads an external app into an iframe and points dojo.doc to the iframe document, allowing the robot to control it
-// to use: set robotURL in djConfig to the URL you want to load
-// dojo.require this file
 
-var iframe = null;
+// urlLoaded is a Deferred that will be resolved whenever the iframe passed to initRobot() finishes loading, or reloads
+var urlLoaded;
 
-var groupStarted=dojo.connect(doh, '_groupStarted', function(){
-	dojo.disconnect(groupStarted);
-	iframe.style.visibility="visible";
-});
+function attachIframe(url){
+	// summary:
+	//		Create iframe to load external app at specified url.   Iframe gets onload handler to  call onIframeLoad()
+	//		when specified URL finishes loading, and also if the iframe loads a different URL in the future.
+	// returns:
+	//		A Deferred that fires when everything has finished initializing
 
-var attachIframe = function(){
-	dojo.addOnLoad(function(){
+	require(["./domReady!"], function(){
 		var emptyStyle = {
-			overflow: dojo.isWebKit? 'hidden' : 'visible',
-			margin: '0px',
-			borderWidth: '0px',
-			height: '100%',
-			width: '100%'
+			overflow: "hidden",
+			margin: "0px",
+			borderWidth: "0px",
+			height: "100%",
+			width: "100%"
 		};
-		dojo.style(document.documentElement, emptyStyle);
-		dojo.style(document.body, emptyStyle);
-		document.body.appendChild(iframe);
-		var base=document.createElement('base');
-		base.href=iframe.src;
-		document.getElementsByTagName("head")[0].appendChild(base);
+		style.set(document.documentElement, emptyStyle);
+		style.set(document.body, emptyStyle);
+
+		// Create the iframe for the external document.   Put it above the firebug-lite div (if such a div exists).
+		// console.log("creating iframe for external document");
+		iframe = document.createElement("iframe");
+		iframe.setAttribute("ALLOWTRANSPARENCY","true");
+		iframe.scrolling = has("ie") ? "yes" : "auto";
+		var scrollRoot = document.compatMode == "BackCompat" ? document.body : document.documentElement;
+		var consoleHeight = (document.getElementById("firebug") || {}).offsetHeight || 0;
+		style.set(iframe, {
+			border: "0px none",
+			padding: "0px",
+			margin: "0px",
+			width: "100%",
+			height: consoleHeight ? (scrollRoot.clientHeight - consoleHeight)+"px" : "100%"
+		});
+		iframe.src = url;
+
+		// Code to handle load event on iframe.  Seems like this should happen before setting iframe src on line above?
+		// Also, can't we use on() in all cases, even for old IE?
+		if(iframe.attachEvent !== undefined){
+			iframe.attachEvent("onload", onIframeLoad);
+		}else{
+			on(iframe, "load", onIframeLoad);
+		}
+
+		construct.place(iframe, win.body(), "first");
 	});
-};
-
-// Prevent race conditions between iframe loading and robot init.
-// If iframe is allowed to load while the robot is typing, sync XHRs can prevent the robot from completing its initialization.
-var robotReady=false;
-var robotFrame=null;
-var _run=doh.robot._run;
-doh.robot._run = function(frame){
-	// Called from robot when the robot completed its initialization.
-	robotReady = true;
-	robotFrame = frame;
-	doh.robot._run = _run;
-	// If initRobot was already called, then attach the iframe.
-	if(iframe.src){
-		attachIframe();
-	}
-};
-
-var onIframeLoad=function(){
-	// initial load handler: update the document and start the tests
-	doh.robot._updateDocument();
-	onIframeLoad = null;
-	var scrollRoot = (document.compatMode == 'BackCompat')? document.body : document.documentElement;
-	var consoleHeight = document.getElementById('robotconsole').offsetHeight;
-	if(consoleHeight){
-		iframe.style.height = (scrollRoot.clientHeight - consoleHeight)+"px";
-	}
+}
+
+function onIframeLoad(){
+	// summary:
+	//		Load handler when iframe specified to initRobot() finishes loading, or when it reloads.
+	//		It resolves the urlLoaded Deferred to make the rests of the tests runs.
+
+	robot._updateDocument();
+
 	// If dojo is present in the test case, then at least make a best effort to wait for it to load.
-	// The test must handle other race conditions like initial data queries by itself.
-	if(iframe.contentWindow.dojo){
-		iframe.contentWindow.dojo.addOnLoad(function(){
-			doh.robot._run(robotFrame);
+	// The test must handle other race conditions like initial data queries or asynchronous parses by itself.
+	if(iframe.contentWindow.require){
+		iframe.contentWindow.require(["dojo/ready"], function(ready){
+			ready(Infinity, function(){
+				setTimeout(function(){
+					urlLoaded.resolve(true);
+				}, 500);	// 500ms fudge factor; otherwise focus doesn't work on IE8, see ValidationTextBox.js, TimeTextBox.js, etc.
+			});
 		});
 	}else{
-		doh.robot._run(robotFrame);
+		urlLoaded.resolve(true);
 	}
-};
-
-var iframeLoad=function(){
-	if(onIframeLoad){
-		onIframeLoad();
-	}
-	var unloadConnect = dojo.connect(dojo.body(), 'onunload', function(){
-		dojo.global = window;
-		dojo.doc = document;
-		dojo.disconnect(unloadConnect);
-	});
-};
-
-// write the firebug console to a place it will fit
-dojo.config.debugContainerId = "robotconsole";
-dojo.config.debugHeight = dojo.config.debugHeight || 200;
-document.write('<div id="robotconsole" style="position:absolute;left:0px;bottom:0px;width:100%;"></div>');
-
-// write the iframe
-//document.writeln('<iframe id="robotapplication" style="visibility:hidden; border:0px none; padding:0px; margin:0px; position:absolute; left:0px; top:0px; width:100%; height:100%; z-index: 1;" src="'+dojo.config.robotURL+'" onload="iframeLoad();" ></iframe>');
-iframe = document.createElement('iframe');
-iframe.setAttribute("ALLOWTRANSPARENCY","true");
-iframe.scrolling = dojo.isIE? "yes" : "auto";
-dojo.style(iframe,{visibility:'hidden', border:'0px none', padding:'0px', margin:'0px', position:'absolute', left:'0px', top:'0px', width:'100%', height:'100%'});
-if(iframe['attachEvent'] !== undefined){
-	iframe.attachEvent('onload', iframeLoad);
-}else{
-	dojo.connect(iframe, 'onload', iframeLoad);
 }
 
-dojo.mixin(doh.robot,{
+lang.mixin(robot, {
 	_updateDocument: function(){
-		dojo.setContext(iframe.contentWindow, iframe.contentWindow.document);
-		var win = dojo.global;
+		// summary:
+		//		Called every time a new page is loaded into the iframe, to setup variables
+		//		Point dojo.global, dojo.publish, etc. to refer to iframe.
+		//		Remove for 2.0?
+
+		kernel.setContext(iframe.contentWindow, iframe.contentWindow.document);
+
+		// Also set pointers inside robot, for easy access via AMD (where there is no dojo variable)
+		robot.window = iframe.contentWindow;
+		robot.doc = iframe.contentWindow.document;
+
+		// TODO: shouldn't this wait until dojo has finished loading in the iframe?  See require code in onIframeLoad().
+		var win = kernel.global;
 		if(win.dojo){
 			// allow the tests to subscribe to topics published by the iframe
-			dojo.publish = win.dojo.publish;
-			dojo.subscribe = win.dojo.subscribe;
-			dojo.connectPublisher = win.dojo.connectPublisher;  
+			kernel.publish = win.dojo.publish;
+			kernel.subscribe = win.dojo.subscribe;
+			kernel.connectPublisher = win.dojo.connectPublisher;
 		}
-
 	},
 
 	initRobot: function(/*String*/ url){
 		// summary:
-		//		Opens the application at the specified URL for testing, redirecting dojo to point to the application environment instead of the test environment.
-		//
+		//		Opens the application at the specified URL for testing, redirecting dojo to point to the application
+		//		environment instead of the test environment.
 		// url:
-		//		URL to open. Any of the test's dojo.doc calls (e.g. dojo.byId()), and any dijit.registry calls (e.g. dijit.byId()) will point to elements and widgets inside this application.
-		//
-
-		iframe.src=url;
-		// see above note about race conditions
-		if(robotReady){
-			attachIframe();
-
-		}
+		//		URL to open. Any of the test's dojo.doc calls (e.g. dojo.byId()), and any dijit.registry calls
+		//		(e.g. dijit.byId()) will point to elements and widgets inside this application.
+
+		doh.registerGroup("initialize robot", {
+			name: "load " + url,
+			timeout: 100000,	// could take more than 10s so setting to 100s
+			runTest: function(){
+				// Setup module level urlLoaded Deferred that will be resolved by onIframeLoad(), after the iframe
+				// has finished loading
+				urlLoaded = new doh.Deferred();
+				attachIframe(url);
+
+				return urlLoaded;
+			}
+		});
 	},
 
 	waitForPageToLoad: function(/*Function*/ submitActions){
 		// summary:
-		// 		Notifies DOH that the doh.robot is about to make a page change in the application it is driving,
+		//		Notifies DOH that the doh.robot is about to make a page change in the application it is driving,
 		//		returning a doh.Deferred object the user should return in their runTest function as part of a DOH test.
-		//
-		// description:
-		// 		Notifies DOH that the doh.robot is about to make a page change in the application it is driving,
-		//		returning a doh.Deferred object the user should return in their runTest function as part of a DOH test.
-		//		Example:
-		//			runTest:function(){
-		//				return waitForPageLoad(function(){ doh.robot.keyPress(dojo.keys.ENTER, 500); });
-		//			}
-		//
+		// example:
+		// |	runTest: function(){
+		// |		return waitForPageLoad(function(){ doh.robot.keyPress(keys.ENTER, 500); });
+		// |	}
 		// submitActions:
 		//		The doh.robot will execute the actions the test passes into the submitActions argument (like clicking the submit button),
 		//		expecting these actions to create a page change (like a form submit).
 		//		After these actions execute and the resulting page loads, the next test will start.
-		//
-
-		var d = new doh.Deferred();
-		// create iframe event handler to track submit progress
-		onIframeLoad = function(){
-			onIframeLoad = null;
-			// set dojo.doc on every page change to point to the iframe doc so the robot works
-			doh.robot._updateDocument();
-			d.callback(true);
-		};
+
+		// Setup a new Deferred that onIframeLoad() will resolve when the iframe finishes loading
+		urlLoaded = new doh.Deferred();
+
 		submitActions();
-		return d;
+
+		return urlLoaded;
 	}
 
 });
 
-return doh.robot;
+return robot;
 });
diff --git a/dojo/router.js b/dojo/router.js
new file mode 100644
index 0000000..1a0e73f
--- /dev/null
+++ b/dojo/router.js
@@ -0,0 +1,28 @@
+define([
+	"./router/RouterBase"
+], function(RouterBase){
+
+	// module:
+	//		dojo/router
+
+/*=====
+return {
+	// summary:
+	//		A singleton-style instance of dojo/router/RouterBase. See that
+	//		module for specifics.
+	// example:
+	//	|	router.register("/widgets/:id", function(evt){
+	//	|		// If "/widgets/3" was matched,
+	//	|		// evt.params.id === "3"
+	//	|		xhr.get({
+	//	|			url: "/some/path/" + evt.params.id,
+	//	|			load: function(data){
+	//	|				// ...
+	//	|			}
+	//	|		});
+	//	|	});
+};
+=====*/
+
+	return new RouterBase({});
+});
diff --git a/dojo/router/RouterBase.js b/dojo/router/RouterBase.js
new file mode 100644
index 0000000..05e7873
--- /dev/null
+++ b/dojo/router/RouterBase.js
@@ -0,0 +1,376 @@
+define([
+	"dojo/_base/declare",
+	"dojo/hash",
+	"dojo/topic"
+], function(declare, hash, topic){
+
+	// module:
+	//		dojo/router/RouterBase
+
+	// Creating a basic trim to avoid needing the full dojo/string module
+	// similarly to dojo/_base/lang's trim
+	var trim;
+	if(String.prototype.trim){
+		trim = function(str){ return str.trim(); };
+	}else{
+		trim = function(str){ return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); };
+	}
+
+	// Firing of routes on the route object is always the same,
+	// no clean way to expose this on the prototype since it's for the
+	// internal router objects.
+	function fireRoute(params, currentPath, newPath){
+		var queue, isStopped, isPrevented, eventObj, callbackArgs, i, l;
+
+		queue = this.callbackQueue;
+		isStopped = false;
+		isPrevented = false;
+		eventObj = {
+			stopImmediatePropagation: function(){ isStopped = true; },
+			preventDefault: function(){ isPrevented = true; },
+			oldPath: currentPath,
+			newPath: newPath,
+			params: params
+		};
+
+		callbackArgs = [eventObj];
+
+		if(params instanceof Array){
+			callbackArgs = callbackArgs.concat(params);
+		}else{
+			for(var key in params){
+				callbackArgs.push(params[key]);
+			}
+		}
+
+		for(i=0, l=queue.length; i<l; ++i){
+			if(!isStopped){
+				queue[i].apply(null, callbackArgs);
+			}
+		}
+
+		return !isPrevented;
+	}
+
+	// Our actual class-like object
+	var RouterBase = declare(null, {
+		// summary:
+		//		A module that allows one to easily map hash-based structures into
+		//		callbacks. The router module is a singleton, offering one central
+		//		point for all registrations of this type.
+		// example:
+		//	|	var router = new RouterBase({});
+		//	|	router.register("/widgets/:id", function(evt){
+		//	|		// If "/widgets/3" was matched,
+		//	|		// evt.params.id === "3"
+		//	|		xhr.get({
+		//	|			url: "/some/path/" + evt.params.id,
+		//	|			load: function(data){
+		//	|				// ...
+		//	|			}
+		//	|		});
+		//	|	});
+
+		_routes: null,
+		_routeIndex: null,
+		_started: false,
+		_currentPath: "",
+
+		idMatch: /:(\w[\w\d]*)/g,
+		idReplacement: "([^\\/]+)",
+		globMatch: /\*(\w[\w\d]*)/,
+		globReplacement: "(.+)",
+
+		constructor: function(kwArgs){
+			// A couple of safety initializations
+			this._routes = [];
+			this._routeIndex = {};
+
+			// Simple constructor-style "Decorate myself all over" for now
+			for(var i in kwArgs){
+				if(kwArgs.hasOwnProperty(i)){
+					this[i] = kwArgs[i];
+				}
+			}
+		},
+
+		register: function(/*String|RegExp*/ route, /*Function*/ callback){
+			// summary:
+			//		Registers a route to a handling callback
+			// description:
+			//		Given either a string or a regular expression, the router
+			//		will monitor the page's hash and respond to changes that
+			//		match the string or regex as provided.
+			//
+			//		When provided a regex for the route:
+			//
+			//		- Matching is performed, and the resulting capture groups
+			//		are passed through to the callback as an array.
+			//
+			//		When provided a string for the route:
+			//
+			//		- The string is parsed as a URL-like structure, like
+			//		"/foo/bar"
+			//		- If any portions of that URL are prefixed with a colon
+			//		(:), they will be parsed out and provided to the callback
+			//		as properties of an object.
+			//		- If the last piece of the URL-like structure is prefixed
+			//		with a star (*) instead of a colon, it will be replaced in
+			//		the resulting regex with a greedy (.+) match and
+			//		anything remaining on the hash will be provided as a
+			//		property on the object passed into the callback. Think of
+			//		it like a basic means of globbing the end of a route.
+			// example:
+			//	|	router.register("/foo/:bar/*baz", function(object){
+			//	|		// If the hash was "/foo/abc/def/ghi",
+			//	|		// object.bar === "abc"
+			//	|		// object.baz === "def/ghi"
+			//	|	});
+			// returns: Object
+			//		A plain JavaScript object to be used as a handle for
+			//		either removing this specific callback's registration, as
+			//		well as to add new callbacks with the same route initially
+			//		used.
+			// route: String|RegExp
+			//		A string or regular expression which will be used when
+			//		monitoring hash changes.
+			// callback: Function
+			//		When the hash matches a pattern as described in the route,
+			//		this callback will be executed. It will receive an event
+			//		object that will have several properties:
+			//
+			//		- params: Either an array or object of properties pulled
+			//		from the new hash
+			//		- oldPath: The hash in its state before the change
+			//		- newPath: The new hash being shifted to
+			//		- preventDefault: A method that will stop hash changes
+			//		from being actually applied to the active hash. This only
+			//		works if the hash change was initiated using `router.go`,
+			//		as changes initiated more directly to the location.hash
+			//		property will already be in place
+			//		- stopImmediatePropagation: When called, will stop any
+			//		further bound callbacks on this particular route from
+			//		being executed. If two distinct routes are bound that are
+			//		different, but both happen to match the current hash in
+			//		some way, this will *not* keep other routes from receiving
+			//		notice of the change.
+
+			return this._registerRoute(route, callback);
+		},
+
+		registerBefore: function(/*String|RegExp*/ route, /*Function*/ callback){
+			// summary:
+			//		Registers a route to a handling callback, except before
+			//		any previously registered callbacks
+			// description:
+			//		Much like the `register` method, `registerBefore` allows
+			//		us to register route callbacks to happen before any
+			//		previously registered callbacks. See the documentation for
+			//		`register` for more details and examples.
+
+			return this._registerRoute(route, callback, true);
+		},
+
+		go: function(path, replace){
+			// summary:
+			//		A simple pass-through to make changing the hash easy,
+			//		without having to require dojo/hash directly. It also
+			//		synchronously fires off any routes that match.
+			// example:
+			//	|	router.go("/foo/bar");
+
+			var applyChange;
+
+			if(typeof path !== "string"){return false;}
+
+			path = trim(path);
+			applyChange = this._handlePathChange(path);
+
+			if(applyChange){
+				hash(path, replace);
+			}
+
+			return applyChange;
+		},
+
+		startup: function(defaultPath){
+			// summary:
+			//		This method must be called to activate the router. Until
+			//		startup is called, no hash changes will trigger route
+			//		callbacks.
+
+			if(this._started){ return; }
+
+			var self = this,
+				startingPath = hash();
+
+			this._started = true;
+			this._hashchangeHandle = topic.subscribe("/dojo/hashchange", function(){
+				self._handlePathChange.apply(self, arguments);
+			});
+
+			if(!startingPath){
+				// If there is no initial starting point, push our defaultPath into our
+				// history as the starting point
+				this.go(defaultPath, true);
+			}else{
+				// Handle the starting path
+				this._handlePathChange(startingPath);
+			}
+		},
+
+		destroy: function(){
+			this._hashchangeHandle.remove();
+			this._routes = null;
+			this._routeIndex = null;
+		},
+
+		_handlePathChange: function(newPath){
+			var i, j, li, lj, routeObj, result,
+				allowChange, parameterNames, params,
+				routes = this._routes,
+				currentPath = this._currentPath;
+
+			if(!this._started || newPath === currentPath){ return allowChange; }
+
+			allowChange = true;
+
+			for(i=0, li=routes.length; i<li; ++i){
+				routeObj = routes[i];
+				result = routeObj.route.exec(newPath);
+
+				if(result){
+					if(routeObj.parameterNames){
+						parameterNames = routeObj.parameterNames;
+						params = {};
+
+						for(j=0, lj=parameterNames.length; j<lj; ++j){
+							params[parameterNames[j]] = result[j+1];
+						}
+					}else{
+						params = result.slice(1);
+					}
+					allowChange = routeObj.fire(params, currentPath, newPath);
+				}
+			}
+
+			if(allowChange){
+				this._currentPath = newPath;
+			}
+
+			return allowChange;
+		},
+
+		_convertRouteToRegExp: function(route){
+			// Sub in based on IDs and globs
+			route = route.replace(this.idMatch, this.idReplacement);
+			route = route.replace(this.globMatch, this.globReplacement);
+			// Make sure it's an exact match
+			route = "^" + route + "$";
+
+			return new RegExp(route);
+		},
+
+		_getParameterNames: function(route){
+			var idMatch = this.idMatch,
+				globMatch = this.globMatch,
+				parameterNames = [], match;
+
+			idMatch.lastIndex = 0;
+
+			while((match = idMatch.exec(route)) !== null){
+				parameterNames.push(match[1]);
+			}
+			if((match = globMatch.exec(route)) !== null){
+				parameterNames.push(match[1]);
+			}
+
+			return parameterNames.length > 0 ? parameterNames : null;
+		},
+
+		_indexRoutes: function(){
+			var i, l, route, routeIndex, routes = this._routes;
+
+			// Start a new route index
+			routeIndex = this._routeIndex = {};
+
+			// Set it up again
+			for(i=0, l=routes.length; i<l; ++i){
+				route = routes[i];
+				routeIndex[route.route] = i;
+			}
+		},
+
+		_registerRoute: function(/*String|RegExp*/route, /*Function*/callback, /*Boolean?*/isBefore){
+			var index, exists, routeObj, callbackQueue, removed,
+				self = this, routes = this._routes,
+				routeIndex = this._routeIndex;
+
+			// Try to fetch the route if it already exists.
+			// This works thanks to stringifying of regex
+			index = this._routeIndex[route];
+			exists = typeof index !== "undefined";
+			if(exists){
+				routeObj = routes[index];
+			}
+
+			// If we didn't get one, make a default start point
+			if(!routeObj){
+				routeObj = {
+					route: route,
+					callbackQueue: [],
+					fire: fireRoute
+				};
+			}
+
+			callbackQueue = routeObj.callbackQueue;
+
+			if(typeof route == "string"){
+				routeObj.parameterNames = this._getParameterNames(route);
+				routeObj.route = this._convertRouteToRegExp(route);
+			}
+
+			if(isBefore){
+				callbackQueue.unshift(callback);
+			}else{
+				callbackQueue.push(callback);
+			}
+
+			if(!exists){
+				index = routes.length;
+				routeIndex[route] = index;
+				routes.push(routeObj);
+			}
+
+			// Useful in a moment to keep from re-removing routes
+			removed = false;
+
+			return { // Object
+				remove: function(){
+					var i, l;
+
+					if(removed){ return; }
+
+					for(i=0, l=callbackQueue.length; i<l; ++i){
+						if(callbackQueue[i] === callback){
+							callbackQueue.splice(i, 1);
+						}
+					}
+
+
+					if(callbackQueue.length === 0){
+						routes.splice(index, 1);
+						self._indexRoutes();
+					}
+
+					removed = true;
+				},
+				register: function(callback, isBefore){
+					return self.register(route, callback, isBefore);
+				}
+			};
+		}
+	});
+
+	return RouterBase;
+});
diff --git a/dojo/rpc/JsonService.js b/dojo/rpc/JsonService.js
index c37adf8..e8bcd6c 100644
--- a/dojo/rpc/JsonService.js
+++ b/dojo/rpc/JsonService.js
@@ -1,42 +1,46 @@
-define(["../main", "./RpcService"], function(dojo) {
+define([
+	"../_base/declare", "../_base/Deferred", "../_base/json", "../_base/lang", "../_base/xhr",
+	"./RpcService"
+], function(declare, Deferred, json, lang, xhr, RpcService){
+
 	// module:
 	//		dojo/rpc/JsonService
-	// summary:
-	//		TODOC
 
+	return declare("dojo.rpc.JsonService", RpcService, {
+		// summary:
+		//		TODOC
 
-dojo.declare("dojo.rpc.JsonService", dojo.rpc.RpcService, {
 		bustCache: false,
 		contentType: "application/json-rpc",
 		lastSubmissionId: 0,
 
 		callRemote: function(method, params){
 			// summary:
-			// 		call an arbitrary remote method without requiring it to be
-			// 		predefined with SMD
-			//	method: string
+			//		call an arbitrary remote method without requiring it to be
+			//		predefined with SMD
+			// method: string
 			//		the name of the remote method you want to call.
-			//	params: array
+			// params: array
 			//		array of parameters to pass to method
 
-			var deferred = new dojo.Deferred();
+			var deferred = new Deferred();
 			this.bind(method, params, deferred);
 			return deferred;
 		},
 
 		bind: function(method, parameters, deferredRequestHandler, url){
-			//summary:
+			// summary:
 			//		JSON-RPC bind method. Takes remote method, parameters,
 			//		deferred, and a url, calls createRequest to make a JSON-RPC
 			//		envelope and passes that off with bind.
-			//	method: string
+			// method: string
 			//		The name of the method we are calling
-			//	parameters: array
+			// parameters: array
 			//		The parameters we are passing off to the method
-			//	deferredRequestHandler: deferred
+			// deferredRequestHandler: deferred
 			//		The Deferred object for this particular request
 
-			var def = dojo.rawXhrPost({
+			var def = xhr.post({
 				url: url||this.serviceUrl,
 				postData: this.createRequest(method, parameters),
 				contentType: this.contentType,
@@ -48,24 +52,24 @@ dojo.declare("dojo.rpc.JsonService", dojo.rpc.RpcService, {
 
 		createRequest: function(method, params){
 			// summary:
-			//	create a JSON-RPC envelope for the request
-			//	method: string
-			//		The name of the method we are creating the requst for
-			//	params: array
-			//		The array of parameters for this request;
+			//		create a JSON-RPC envelope for the request
+			// method: string
+			//		The name of the method we are creating the request for
+			// params: array
+			//		The array of parameters for this request
 
 			var req = { "params": params, "method": method, "id": ++this.lastSubmissionId };
-			return dojo.toJson(req);
+			return json.toJson(req);
 		},
 
 		parseResults: function(/*anything*/obj){
-			//summary:
+			// summary:
 			//		parse the result envelope and pass the results back to
 			//		the callback function
-			//	obj: Object
-			//		Object containing envelope of data we recieve from the server
+			// obj: Object
+			//		Object containing envelope of data we receive from the server
 
-			if(dojo.isObject(obj)){
+			if(lang.isObject(obj)){
 				if("result" in obj){
 					return obj.result;
 				}
@@ -78,8 +82,6 @@ dojo.declare("dojo.rpc.JsonService", dojo.rpc.RpcService, {
 			}
 			return obj;
 		}
-	}
-);
+	});
 
-return dojo.rpc.JsonService;
 });
diff --git a/dojo/rpc/JsonpService.js b/dojo/rpc/JsonpService.js
index eb2ff63..4576efd 100644
--- a/dojo/rpc/JsonpService.js
+++ b/dojo/rpc/JsonpService.js
@@ -1,23 +1,23 @@
-define(["../main", "./RpcService", "../io/script"], function(dojo) {
-	// module:
-	//		dojo/rpc/JsonpService
-	// summary:
-	//		TODOC
+define([
+	"../_base/array", "../_base/declare", "../_base/lang", "./RpcService", "../io/script"],
+	function(array, declare, lang, RpcService, script){
 
+// module:
+//		dojo/rpc/JsonpService
 
-dojo.declare("dojo.rpc.JsonpService", dojo.rpc.RpcService, {
+return declare("dojo.rpc.JsonpService", RpcService, {
 	// summary:
-	//	Generic JSONP service.  Minimally extends RpcService to allow
-	//	easy definition of nearly any JSONP style service. Example
-	//	SMD files exist in dojox.data
+	//		Generic JSONP service.  Minimally extends RpcService to allow
+	//		easy definition of nearly any JSONP style service. Example
+	//		SMD files exist in dojox.data
 
 	constructor: function(args, requiredArgs){
-		if(this.required) {
+		if(this.required){
 			if(requiredArgs){
-				dojo.mixin(this.required, requiredArgs);
+				lang.mixin(this.required, requiredArgs);
 			}
 
-			dojo.forEach(this.required, function(req){
+			array.forEach(this.required, function(req){
 				if(req=="" || req==undefined){
 					throw new Error("Required Service Argument not found: "+req);
 				}
@@ -28,18 +28,18 @@ dojo.declare("dojo.rpc.JsonpService", dojo.rpc.RpcService, {
 	strictArgChecks: false,
 
 	bind: function(method, parameters, deferredRequestHandler, url){
-		//summary:
-		//              JSONP bind method. Takes remote method, parameters,
-		//              deferred, and a url, calls createRequest to make a JSON-RPC
-		//              envelope and passes that off with bind.
-		//      method: string
-		//              The name of the method we are calling
-		//      parameters: array
-		//              The parameters we are passing off to the method
-		//      deferredRequestHandler: deferred
-		//              The Deferred object for this particular request
+		// summary:
+		//		JSONP bind method. Takes remote method, parameters,
+		//		deferred, and a url, calls createRequest to make a JSON-RPC
+		//		envelope and passes that off with bind.
+		// method: string
+		//		The name of the method we are calling
+		// parameters: array
+		//		The parameters we are passing off to the method
+		// deferredRequestHandler: deferred
+		//		The Deferred object for this particular request
 
-		var def = dojo.io.script.get({
+		var def = script.get({
 			url: url||this.serviceUrl,
 			callbackParamName: this.callbackParamName||"callback",
 			content: this.createRequest(parameters),
@@ -52,16 +52,15 @@ dojo.declare("dojo.rpc.JsonpService", dojo.rpc.RpcService, {
 
 	createRequest: function(parameters){
 		// summary:
-		//      create a JSONP req
-		//      params: array
-		//              The array of parameters for this request;
+		//		create a JSONP req
+		// params: array
+		//		The array of parameters for this request;
 
-		var params = (dojo.isArrayLike(parameters) && parameters.length==1) ?
+		var params = (lang.isArrayLike(parameters) && parameters.length==1) ?
 				parameters[0] : {};
-		dojo.mixin(params,this.required);
+		lang.mixin(params,this.required);
 		return params;
 	}
 });
 
-return dojo.rpc.JsonpService;
 });
diff --git a/dojo/rpc/RpcService.js b/dojo/rpc/RpcService.js
index 26cb1ee..00e5959 100644
--- a/dojo/rpc/RpcService.js
+++ b/dojo/rpc/RpcService.js
@@ -1,17 +1,21 @@
-define(["../main", "../_base/url"], function(dojo) {
-	// module:
-	//		dojo/rpc/RpcService
+define([
+	"../_base/array", "../_base/declare", "../_base/Deferred", "../_base/kernel","../_base/lang",
+	"../_base/url", "../_base/xhr"
+], function(array, declare, Deferred, kernel, lang, _Url, xhr){
+
+// module:
+//		dojo/rpc/RpcService
+
+return declare("dojo.rpc.RpcService", null, {
 	// summary:
 	//		TODOC
 
-
-dojo.declare("dojo.rpc.RpcService", null, {
 	constructor: function(args){
-		//summary:
-		//Take a string as a url to retrieve an smd or an object that is an smd or partial smd to use
-		//as a definition for the service
+		// summary:
+		//		Take a string as a url to retrieve an smd or an object that is an smd or partial smd to use
+		//		as a definition for the service
 		//
-		//	args: object
+		// args: object
 		//		Takes a number of properties as kwArgs for defining the service.  It also
 		//		accepts a string.  When passed a string, it is treated as a url from
 		//		which it should synchronously retrieve an smd file.  Otherwise it is a kwArgs
@@ -24,38 +28,38 @@ dojo.declare("dojo.rpc.RpcService", null, {
 		//
 		if(args){
 			//if the arg is a string, we assume it is a url to retrieve an smd definition from
-			if( (dojo.isString(args)) || (args instanceof dojo._Url)){
-				if (args instanceof dojo._Url){
+			if( (lang.isString(args)) || (args instanceof _Url)){
+				if (args instanceof _Url){
 					var url = args + "";
 				}else{
 					url = args;
 				}
-				var def = dojo.xhrGet({
+				var def = xhr.get({
 					url: url,
 					handleAs: "json-comment-optional",
 					sync: true
 				});
 
 				def.addCallback(this, "processSmd");
-				def.addErrback(function() {
+				def.addErrback(function(){
 					throw new Error("Unable to load SMD from " + args);
 				});
 
 			}else if(args.smdStr){
-				this.processSmd(dojo.eval("("+args.smdStr+")"));
+				this.processSmd(kernel.eval("("+args.smdStr+")"));
 			}else{
 				// otherwise we assume it's an arguments object with the following
 				// (optional) properties:
-				//      - serviceUrl
-				//      - strictArgChecks
-				//      - smdStr
-				//      - smdObj
+				//		- serviceUrl
+				//		- strictArgChecks
+				//		- smdStr
+				//		- smdObj
 
 				if(args.serviceUrl){
 					this.serviceUrl = args.serviceUrl;
 				}
 
-				this.timeout = args.timeout || 3000;
+				this.timeout = args.timeout || 0;
 
 				if("strictArgChecks" in args){
 					this.strictArgChecks = args.strictArgChecks;
@@ -74,28 +78,28 @@ dojo.declare("dojo.rpc.RpcService", null, {
 		//		parse the results coming back from an rpc request.  this
 		//		base implementation, just returns the full object
 		//		subclasses should parse and only return the actual results
-		//	obj: Object
+		// obj: Object
 		//		Object that is the return results from an rpc request
 		return obj;
 	},
 
-	errorCallback: function(/* dojo.Deferred */ deferredRequestHandler){
+	errorCallback: function(/* dojo/_base/Deferred */ deferredRequestHandler){
 		// summary:
-		//		create callback that calls the Deferres errback method
-		//	deferredRequestHandler: Deferred
+		//		create callback that calls the Deferred errback method
+		// deferredRequestHandler: Deferred
 		//		The deferred object handling a request.
 		return function(data){
 			deferredRequestHandler.errback(data.message);
 		};
 	},
 
-	resultCallback: function(/* dojo.Deferred */ deferredRequestHandler){
+	resultCallback: function(/* dojo/_base/Deferred */ deferredRequestHandler){
 		// summary:
 		//		create callback that calls the Deferred's callback method
-		//	deferredRequestHandler: Deferred
+		// deferredRequestHandler: Deferred
 		//		The deferred object handling a request.
 
-		return dojo.hitch(this,
+		return lang.hitch(this,
 			function(obj){
 				if(obj.error!=null){
 					var err;
@@ -119,15 +123,15 @@ dojo.declare("dojo.rpc.RpcService", null, {
 	generateMethod: function(/*string*/ method, /*array*/ parameters, /*string*/ url){
 		// summary:
 		//		generate the local bind methods for the remote object
-		//	method: string
+		// method: string
 		//		The name of the method we are generating
-		//	parameters: array
+		// parameters: array
 		//		the array of parameters for this call.
-		//	url: string
+		// url: string
 		//		the service url for this call
 
-		return dojo.hitch(this, function(){
-			var deferredRequestHandler = new dojo.Deferred();
+		return lang.hitch(this, function(){
+			var deferredRequestHandler = new Deferred();
 
 			// if params weren't specified, then we can assume it's varargs
 			if( (this.strictArgChecks) &&
@@ -137,7 +141,7 @@ dojo.declare("dojo.rpc.RpcService", null, {
 				// put error stuff here, no enough params
 				throw new Error("Invalid number of parameters for remote method.");
 			}else{
-				this.bind(method, dojo._toArray(arguments), deferredRequestHandler, url);
+				this.bind(method, lang._toArray(arguments), deferredRequestHandler, url);
 			}
 
 			return deferredRequestHandler;
@@ -146,18 +150,18 @@ dojo.declare("dojo.rpc.RpcService", null, {
 
 	processSmd: function(object){
 		// summary:
-		//		callback method for reciept of a smd object.  Parse the smd
+		//		callback method for receipt of a smd object.  Parse the smd
 		//		and generate functions based on the description
-		//	object:
+		// object:
 		//		smd object defining this service.
 
 		if(object.methods){
-			dojo.forEach(object.methods, function(m){
+			array.forEach(object.methods, function(m){
 				if(m && m.name){
 					this[m.name] = this.generateMethod(	m.name,
 										m.parameters,
 										m.url||m.serviceUrl||m.serviceURL);
-					if(!dojo.isFunction(this[m.name])){
+					if(!lang.isFunction(this[m.name])){
 						throw new Error("RpcService: Failed to create" + m.name + "()");
 						/*console.log("RpcService: Failed to create", m.name, "()");*/
 					}
@@ -171,5 +175,4 @@ dojo.declare("dojo.rpc.RpcService", null, {
 	}
 });
 
-return dojo.rpc.RpcService;
 });
diff --git a/dojo/selector/_loader.js b/dojo/selector/_loader.js
index e5c9094..16b5b1f 100644
--- a/dojo/selector/_loader.js
+++ b/dojo/selector/_loader.js
@@ -1,7 +1,6 @@
 define(["../has", "require"],
 		function(has, require){
-// summary:
-//		This module handles loading the appropriate selector engine for the given browser
+
 "use strict";
 var testDiv = document.createElement("div");
 has.add("dom-qsa2.1", !!testDiv.querySelectorAll);
@@ -17,6 +16,9 @@ has.add("dom-qsa3", function(){
 var fullEngine;
 var acme = "./acme", lite = "./lite";
 return {
+	// summary:
+	//		This module handles loading the appropriate selector engine for the given browser
+
 	load: function(id, parentRequire, loaded, config){
 		var req = require;
 		// here we implement the default logic for choosing a selector engine
diff --git a/dojo/selector/acme.js b/dojo/selector/acme.js
index d90dc72..dc86c43 100644
--- a/dojo/selector/acme.js
+++ b/dojo/selector/acme.js
@@ -1,8 +1,9 @@
-define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array", "../_base/lang", "../_base/window"], function(dojo, has, dom){
-  //  module:
-  //    dojo/selector/acme
-  //  summary:
-  //    This module defines the Acme selector engine
+define([
+	"../dom", "../sniff", "../_base/array", "../_base/lang", "../_base/window"
+], function(dom, has, array, lang, win){
+
+	// module:
+	//		dojo/selector/acme
 
 /*
 	acme architectural overview:
@@ -44,18 +45,13 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 	// if you are extracting acme for use in your own system, you will
 	// need to provide these methods and properties. No other porting should be
 	// necessary, save for configuring the system to use a class other than
-	// dojo.NodeList as the return instance instantiator
-	var trim = 			dojo.trim;
-	var each = 			dojo.forEach;
-	// 					d.isIE; // float
-	// 					d.isSafari; // float
-	// 					d.isOpera; // float
-	// 					d.isWebKit; // float
-	// 					d.doc ; // document element
-
-	var getDoc = function(){ return dojo.doc; };
+	// dojo/NodeList as the return instance instantiator
+	var trim = 			lang.trim;
+	var each = 			array.forEach;
+
+	var getDoc = function(){ return win.doc; };
 	// NOTE(alex): the spec is idiotic. CSS queries should ALWAYS be case-sensitive, but nooooooo
-	var cssCaseBug = ((dojo.isWebKit||dojo.isMozilla) && ((getDoc().compatMode) == "BackCompat"));
+	var cssCaseBug = (getDoc().compatMode) == "BackCompat";
 
 	////////////////////////////////////////////////////////////////////////
 	// Global utilities
@@ -77,9 +73,9 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 	////////////////////////////////////////////////////////////////////////
 
 	var getQueryParts = function(query){
-		//	summary:
+		// summary:
 		//		state machine for query tokenization
-		//	description:
+		// description:
 		//		instead of using a brittle and slow regex-based CSS parser,
 		//		acme implements an AST-style query representation. This
 		//		representation is only generated once per query. For example,
@@ -103,7 +99,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		if(specials.indexOf(query.slice(-1)) >= 0){
 			// if we end with a ">", "+", or "~", that means we're implicitly
 			// searching all children, so make it explicit
-			query += " * "
+			query += " * ";
 		}else{
 			// if you have not provided a terminator, one will be provided for
 			// you...
@@ -124,7 +120,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 
 		// state keeping vars
 		var inBrackets = -1, inParens = -1, inMatchFor = -1,
-			inPseudo = -1, inClass = -1, inId = -1, inTag = -1,
+			inPseudo = -1, inClass = -1, inId = -1, inTag = -1, currentQuoteChar,
 			lc = "", cc = "", pStart;
 
 		// iteration vars
@@ -251,8 +247,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 				//	but not:
 				//		thinger > div.howdy[type=thinger]
 				//	the indidual components of the previous query would be
-				//	split into 3 parts that would be represented a structure
-				//	like:
+				//	split into 3 parts that would be represented a structure like:
 				//		[
 				//			{
 				//				query: "thinger",
@@ -276,7 +271,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 					oper: null, // ...or operator per component. Note that these wind up being exclusive.
 					id: null,	// the id component of a rule
 					getTag: function(){
-						return (caseSensitive) ? this.otag : this.tag;
+						return caseSensitive ? this.otag : this.tag;
 					}
 				};
 
@@ -287,6 +282,19 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 				inTag = x;
 			}
 
+			// Skip processing all quoted characters.
+			// If we are inside quoted text then currentQuoteChar stores the character that began the quote,
+			// thus that character that will end it.
+			if(currentQuoteChar){
+				if(cc == currentQuoteChar){
+					currentQuoteChar = null;
+				}
+				continue;
+			}else if (cc == "'" || cc == '"'){
+				currentQuoteChar = cc;
+				continue;
+			}
+
 			if(inBrackets >= 0){
 				// look for a the close first
 				if(cc == "]"){ // if we're in a [...] clause and we end, do assignment
@@ -309,6 +317,12 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 							_cp.matchFor = cmf.slice(1, -1);
 						}
 					}
+					// remove backslash escapes from an attribute match, since DOM
+					// querying will get attribute values without backslashes
+					if(_cp.matchFor){
+						_cp.matchFor = _cp.matchFor.replace(/\\/g, "");
+					}
+
 					// end the attribute by adding it to the list of attributes.
 					currentPart.attrs.push(_cp);
 					_cp = null; // necessary?
@@ -393,7 +407,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 
 		return function(){
 			return first.apply(window, arguments) && second.apply(window, arguments);
-		}
+		};
 	};
 
 	var getArr = function(i, arr){
@@ -428,7 +442,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 				//		an E element whose "foo" attribute value contains
 				//		the substring "bar"
 				return (_getAttr(elem, attr).indexOf(value)>=0);
-			}
+			};
 		},
 		"^=": function(attr, value){
 			// E[foo^="bar"]
@@ -436,7 +450,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 			//		with the string "bar"
 			return function(elem){
 				return (_getAttr(elem, attr).indexOf(value)==0);
-			}
+			};
 		},
 		"$=": function(attr, value){
 			// E[foo$="bar"]
@@ -444,8 +458,9 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 			//		with the string "bar"
 			return function(elem){
 				var ea = " "+_getAttr(elem, attr);
-				return (ea.lastIndexOf(value)==(ea.length-value.length));
-			}
+				var lastIndex = ea.lastIndexOf(value);
+				return lastIndex > -1 && (lastIndex==(ea.length-value.length));
+			};
 		},
 		"~=": function(attr, value){
 			// E[foo~="bar"]
@@ -458,7 +473,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 			return function(elem){
 				var ea = " "+_getAttr(elem, attr)+" ";
 				return (ea.indexOf(tval)>=0);
-			}
+			};
 		},
 		"|=": function(attr, value){
 			// E[hreflang|="en"]
@@ -472,12 +487,12 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 					(ea == value) ||
 					(ea.indexOf(valueDash)==0)
 				);
-			}
+			};
 		},
 		"=": function(attr, value){
 			return function(elem){
 				return (_getAttr(elem, attr) == value);
-			}
+			};
 		}
 	};
 
@@ -506,10 +521,11 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 
 	var getNodeIndex = function(node){
 		var root = node.parentNode;
+		root = root.nodeType != 7 ? root : root.nextSibling; // PROCESSING_INSTRUCTION_NODE
 		var i = 0,
 			tret = root.children || root.childNodes,
-			ci = (node["_i"]||-1),
-			cl = (root["_l"]||-1);
+			ci = (node["_i"]||node.getAttribute("_i")||-1),
+			cl = (root["_l"]|| (typeof root.getAttribute !== "undefined" ? root.getAttribute("_l") : -1));
 
 		if(!tret){ return -1; }
 		var l = tret.length;
@@ -523,11 +539,19 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		}
 
 		// else re-key things
-		root["_l"] = l;
+		if(has("ie") && typeof root.setAttribute !== "undefined"){
+			root.setAttribute("_l", l);
+		}else{
+			root["_l"] = l;
+		}
 		ci = -1;
 		for(var te = root["firstElementChild"]||root["firstChild"]; te; te = te[_ns]){
 			if(_simpleNodeTest(te)){
-				te["_i"] = ++i;
+				if(has("ie")){
+					te.setAttribute("_i", ++i);
+				}else{
+					te["_i"] = ++i;
+				}
 				if(node === te){
 					// NOTE:
 					//	shortcutting the return at this step in indexing works
@@ -556,7 +580,17 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		"checked": function(name, condition){
 			return function(elem){
 				return !!("checked" in elem ? elem.checked : elem.selected);
-			}
+			};
+		},
+		"disabled": function(name, condition){
+			return function(elem){
+				return elem.disabled;
+			};
+		},
+		"enabled": function(name, condition){
+			return function(elem){
+				return !elem.disabled;
+			};
 		},
 		"first-child": function(){ return _lookLeft; },
 		"last-child": function(){ return _lookRight; },
@@ -577,7 +611,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 					if((nt === 1)||(nt == 3)){ return false; }
 				}
 				return true;
-			}
+			};
 		},
 		"contains": function(name, condition){
 			var cz = condition.charAt(0);
@@ -586,7 +620,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 			}
 			return function(elem){
 				return (elem.innerHTML.indexOf(condition) >= 0);
-			}
+			};
 		},
 		"not": function(name, condition){
 			var p = getQueryParts(condition)[0];
@@ -600,7 +634,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 			var ntf = getSimpleFilterFunc(p, ignores);
 			return function(elem){
 				return (!ntf(elem));
-			}
+			};
 		},
 		"nth-child": function(name, condition){
 			var pi = parseInt;
@@ -638,7 +672,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 					return function(elem){
 						var i = getNodeIndex(elem);
 						return (i>=lb) && (ub<0 || i<=ub) && ((i % pred) == idx);
-					}
+					};
 				}else{
 					condition = idx;
 				}
@@ -646,20 +680,20 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 			var ncount = pi(condition);
 			return function(elem){
 				return (getNodeIndex(elem) == ncount);
-			}
+			};
 		}
 	};
 
-	var defaultGetter = (dojo.isIE && (dojo.isIE < 9 || dojo.isQuirks)) ? function(cond){
+	var defaultGetter = (has("ie") < 9 || has("ie") == 9 && has("quirks")) ? function(cond){
 		var clc = cond.toLowerCase();
 		if(clc == "class"){ cond = "className"; }
 		return function(elem){
 			return (caseSensitive ? elem.getAttribute(cond) : elem[cond]||elem[clc]);
-		}
+		};
 	} : function(cond){
 		return function(elem){
 			return (elem && elem.getAttribute && elem.hasAttribute(cond));
-		}
+		};
 	};
 
 	var getSimpleFilterFunc = function(query, ignores){
@@ -682,7 +716,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		if(!("tag" in ignores)){
 			if(query.tag != "*"){
 				ff = agree(ff, function(elem){
-					return (elem && (elem.tagName == query.getTag()));
+					return (elem && ((caseSensitive ? elem.tagName : elem.tagName.toUpperCase()) == query.getTag()));
 				});
 			}
 		}
@@ -760,7 +794,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 				break;
 			}
 			return ret;
-		}
+		};
 	};
 
 	var _nextSiblings = function(filterFunc){
@@ -778,7 +812,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 				te = te[_ns];
 			}
 			return ret;
-		}
+		};
 	};
 
 	// get an array of child *elements*, skipping text and comment nodes
@@ -800,15 +834,6 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		};
 	};
 
-	/*
-	// thanks, Dean!
-	var itemIsAfterRoot = d.isIE ? function(item, root){
-		return (item.sourceIndex > root.sourceIndex);
-	} : function(item, root){
-		return (item.compareDocumentPosition(root) == 2);
-	};
-	*/
-
 	// test to see if node is below root
 	var _isDescendant = function(node, root){
 		var pn = node.parentNode;
@@ -911,7 +936,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 							return getArr(te, arr);
 						}
 					}
-				}
+				};
 			}else if(
 				ecs &&
 				// isAlien check. Workaround for Prototype.js being totally evil/dumb.
@@ -939,7 +964,8 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 				// it's tag only. Fast-path it.
 				retFunc = function(root, arr, bag){
 					var ret = getArr(0, arr), te, x=0;
-					var tret = root.getElementsByTagName(query.getTag());
+					var tag = query.getTag(),
+						tret = tag ? root.getElementsByTagName(tag) : [];
 					while((te = tret[x++])){
 						if(_isUnique(te, bag)){
 							ret.push(te);
@@ -956,7 +982,8 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 				retFunc = function(root, arr, bag){
 					var ret = getArr(0, arr), te, x=0;
 					// we use getTag() to avoid case sensitivity issues
-					var tret = root.getElementsByTagName(query.getTag());
+					var tag = query.getTag(),
+						tret = tag ? root.getElementsByTagName(tag) : [];
 					while((te = tret[x++])){
 						if(filterFunc(te, root) && _isUnique(te, bag)){
 							ret.push(te);
@@ -1000,7 +1027,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 				// if we have more than one root at this level, provide a new
 				// hash to use for checking group membership but tell the
 				// system not to post-filter us since we will already have been
-				// gauranteed to be unique
+				// guaranteed to be unique
 				bag = {};
 				ret.nozip = true;
 			}
@@ -1029,7 +1056,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 	var _queryFuncCacheDOM = {},
 		_queryFuncCacheQSA = {};
 
-	// this is the second level of spliting, from full-length queries (e.g.,
+	// this is the second level of splitting, from full-length queries (e.g.,
 	// "div.foo .bar") into simple query expressions (e.g., ["div.foo",
 	// ".bar"])
 	var getStepQueryFunc = function(query){
@@ -1046,13 +1073,13 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 				var r = tef(root, []);
 				if(r){ r.nozip = true; }
 				return r;
-			}
+			};
 		}
 
 		// otherwise, break it up and return a runner that iterates over the parts recursively
 		return function(root){
 			return filterDown(root, qparts);
-		}
+		};
 	};
 
 	// NOTES:
@@ -1074,42 +1101,34 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 	// we need to determine if we think we can run a given query via
 	// querySelectorAll or if we'll need to fall back on DOM queries to get
 	// there. We need a lot of information about the environment and the query
-	// to make the determiniation (e.g. does it support QSA, does the query in
+	// to make the determination (e.g. does it support QSA, does the query in
 	// question work in the native QSA impl, etc.).
-	var nua = navigator.userAgent;
-	// some versions of Safari provided QSA, but it was buggy and crash-prone.
-	// We need te detect the right "internal" webkit version to make this work.
-	var wk = "WebKit/";
-	var is525 = (
-		dojo.isWebKit &&
-		(nua.indexOf(wk) > 0) &&
-		(parseFloat(nua.split(wk)[1]) > 528)
-	);
 
 	// IE QSA queries may incorrectly include comment nodes, so we throw the
 	// zipping function into "remove" comments mode instead of the normal "skip
 	// it" which every other QSA-clued browser enjoys
-	var noZip = dojo.isIE ? "commentStrip" : "nozip";
+	var noZip = has("ie") ? "commentStrip" : "nozip";
 
 	var qsa = "querySelectorAll";
-	var qsaAvail = (
-		!!getDoc()[qsa] &&
-		// see #5832
-		(!dojo.isSafari || (dojo.isSafari > 3.1) || is525 )
-	);
+	var qsaAvail = !!getDoc()[qsa];
 
 	//Don't bother with n+3 type of matches, IE complains if we modify those.
-	var infixSpaceRe = /n\+\d|([^ ])?([>~+])([^ =])?/g;
+	var infixSpaceRe = /\\[>~+]|n\+\d|([^ \\])?([>~+])([^ =])?/g;
 	var infixSpaceFunc = function(match, pre, ch, post){
 		return ch ? (pre ? pre + " " : "") + ch + (post ? " " + post : "") : /*n+3*/ match;
 	};
-
+	
+	//Don't apply the infixSpaceRe to attribute value selectors
+	var attRe = /([^[]*)([^\]]*])?/g;
+	var attFunc = function(match, nonAtt, att){
+		return nonAtt.replace(infixSpaceRe, infixSpaceFunc) + (att||"");
+	};
 	var getQueryFunc = function(query, forceDOM){
 		//Normalize query. The CSS3 selectors spec allows for omitting spaces around
 		//infix operators, >, ~ and +
 		//Do the work here since detection for spaces is used as a simple "not use QSA"
 		//test below.
-		query = query.replace(infixSpaceRe, infixSpaceFunc);
+		query = query.replace(attRe, attFunc);
 
 		if(qsaAvail){
 			// if we've got a cached variant and we think we can do it, run it!
@@ -1142,7 +1161,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 			//		http://www.w3.org/TR/css3-selectors/#w3cselgrammar
 			(specials.indexOf(qcz) == -1) &&
 			// IE's QSA impl sucks on pseudos
-			(!dojo.isIE || (query.indexOf(":") == -1)) &&
+			(!has("ie") || (query.indexOf(":") == -1)) &&
 
 			(!(cssCaseBug && (query.indexOf(".") >= 0))) &&
 
@@ -1189,10 +1208,10 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 					// default that way in the future
 					return getQueryFunc(query, true)(root);
 				}
-			}
+			};
 		}else{
 			// DOM branch
-			var parts = query.split(/\s*,\s*/);
+			var parts = query.match(/([^\s,](?:"(?:\\.|[^"])+"|'(?:\\.|[^'])+'|[^,])*)/g);
 			return _queryFuncCacheDOM[query] = ((parts.length < 2) ?
 				// if not a compound query (e.g., ".foo, .bar"), cache and return a dispatcher
 				getStepQueryFunc(query) :
@@ -1217,7 +1236,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 	// NOTE:
 	//		this function is Moo inspired, but our own impl to deal correctly
 	//		with XML in IE
-	var _nodeUID = dojo.isIE ? function(node){
+	var _nodeUID = has("ie") ? function(node){
 		if(caseSensitive){
 			// XML docs don't have uniqueID on their nodes
 			return (node.getAttribute("_uid") || node.setAttribute("_uid", ++_zipIdx) || _zipIdx);
@@ -1243,47 +1262,43 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 	};
 
 	// attempt to efficiently determine if an item in a list is a dupe,
-	// returning a list of "uniques", hopefully in doucment order
+	// returning a list of "uniques", hopefully in document order
 	var _zipIdxName = "_zipIdx";
 	var _zip = function(arr){
-		if(arr && arr.nozip){
-			return arr;
-		}
+		if(arr && arr.nozip){ return arr; }
+
+		if(!arr || !arr.length){ return []; }
+		if(arr.length < 2){ return [arr[0]]; }
+
 		var ret = [];
-		if(!arr || !arr.length){ return ret; }
-		if(arr[0]){
-			ret.push(arr[0]);
-		}
-		if(arr.length < 2){ return ret; }
 
 		_zipIdx++;
 
 		// we have to fork here for IE and XML docs because we can't set
 		// expandos on their nodes (apparently). *sigh*
-		if(dojo.isIE && caseSensitive){
+		var x, te;
+		if(has("ie") && caseSensitive){
 			var szidx = _zipIdx+"";
-			arr[0].setAttribute(_zipIdxName, szidx);
-			for(var x = 1, te; te = arr[x]; x++){
-				if(arr[x].getAttribute(_zipIdxName) != szidx){
+			for(x = 0; x < arr.length; x++){
+				if((te = arr[x]) && te.getAttribute(_zipIdxName) != szidx){
 					ret.push(te);
+					te.setAttribute(_zipIdxName, szidx);
 				}
-				te.setAttribute(_zipIdxName, szidx);
 			}
-		}else if(dojo.isIE && arr.commentStrip){
+		}else if(has("ie") && arr.commentStrip){
 			try{
-				for(var x = 1, te; te = arr[x]; x++){
-					if(_isElement(te)){
+				for(x = 0; x < arr.length; x++){
+					if((te = arr[x]) && _isElement(te)){
 						ret.push(te);
 					}
 				}
 			}catch(e){ /* squelch */ }
 		}else{
-			if(arr[0]){ arr[0][_zipIdxName] = _zipIdx; }
-			for(var x = 1, te; te = arr[x]; x++){
-				if(arr[x][_zipIdxName] != _zipIdx){
+			for(x = 0; x < arr.length; x++){
+				if((te = arr[x]) && te[_zipIdxName] != _zipIdx){
 					ret.push(te);
+					te[_zipIdxName] = _zipIdx;
 				}
-				te[_zipIdxName] = _zipIdx;
 			}
 		}
 		return ret;
@@ -1291,11 +1306,11 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 
 	// the main executor
 	var query = function(/*String*/ query, /*String|DOMNode?*/ root){
-		//	summary:
+		// summary:
 		//		Returns nodes which match the given CSS3 selector, searching the
 		//		entire document by default but optionally taking a node to scope
 		//		the search by. Returns an array.
-		//	description:
+		// description:
 		//		dojo.query() is the swiss army knife of DOM node manipulation in
 		//		Dojo. Much like Prototype's "$$" (bling-bling) function or JQuery's
 		//		"$" function, dojo.query provides robust, high-performance
@@ -1307,33 +1322,33 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		//
 		//		acme supports a rich set of CSS3 selectors, including:
 		//
-		//			* class selectors (e.g., `.foo`)
-		//			* node type selectors like `span`
-		//			* ` ` descendant selectors
-		//			* `>` child element selectors
-		//			* `#foo` style ID selectors
-		//			* `*` universal selector
-		//			* `~`, the preceded-by sibling selector
-		//			* `+`, the immediately preceded-by sibling selector
-		//			* attribute queries:
-		//			|	* `[foo]` attribute presence selector
-		//			|	* `[foo='bar']` attribute value exact match
-		//			|	* `[foo~='bar']` attribute value list item match
-		//			|	* `[foo^='bar']` attribute start match
-		//			|	* `[foo$='bar']` attribute end match
-		//			|	* `[foo*='bar']` attribute substring match
-		//			* `:first-child`, `:last-child`, and `:only-child` positional selectors
-		//			* `:empty` content emtpy selector
-		//			* `:checked` pseudo selector
-		//			* `:nth-child(n)`, `:nth-child(2n+1)` style positional calculations
-		//			* `:nth-child(even)`, `:nth-child(odd)` positional selectors
-		//			* `:not(...)` negation pseudo selectors
+		//		- class selectors (e.g., `.foo`)
+		//		- node type selectors like `span`
+		//		- ` ` descendant selectors
+		//		- `>` child element selectors
+		//		- `#foo` style ID selectors
+		//		- `*` universal selector
+		//		- `~`, the preceded-by sibling selector
+		//		- `+`, the immediately preceded-by sibling selector
+		//		- attribute queries:
+		//			- `[foo]` attribute presence selector
+		//			- `[foo='bar']` attribute value exact match
+		//			- `[foo~='bar']` attribute value list item match
+		//			- `[foo^='bar']` attribute start match
+		//			- `[foo$='bar']` attribute end match
+		//			- `[foo*='bar']` attribute substring match
+		//		- `:first-child`, `:last-child`, and `:only-child` positional selectors
+		//		- `:empty` content emtpy selector
+		//		- `:checked` pseudo selector
+		//		- `:nth-child(n)`, `:nth-child(2n+1)` style positional calculations
+		//		- `:nth-child(even)`, `:nth-child(odd)` positional selectors
+		//		- `:not(...)` negation pseudo selectors
 		//
 		//		Any legal combination of these selectors will work with
 		//		`dojo.query()`, including compound selectors ("," delimited).
 		//		Very complex and useful searches can be constructed with this
 		//		palette of selectors and when combined with functions for
-		//		manipulation presented by dojo.NodeList, many types of DOM
+		//		manipulation presented by dojo/NodeList, many types of DOM
 		//		manipulation operations become very straightforward.
 		//
 		//		Unsupported Selectors:
@@ -1343,14 +1358,14 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		//		what's reasonable for a programmatic node querying engine to
 		//		handle. Currently unsupported selectors include:
 		//
-		//			* namespace-differentiated selectors of any form
-		//			* all `::` pseduo-element selectors
-		//			* certain pseduo-selectors which don't get a lot of day-to-day use:
-		//			|	* `:root`, `:lang()`, `:target`, `:focus`
-		//			* all visual and state selectors:
-		//			|	* `:root`, `:active`, `:hover`, `:visisted`, `:link`,
+		//		- namespace-differentiated selectors of any form
+		//		- all `::` pseduo-element selectors
+		//		- certain pseudo-selectors which don't get a lot of day-to-day use:
+		//			- `:root`, `:lang()`, `:target`, `:focus`
+		//		- all visual and state selectors:
+		//			- `:root`, `:active`, `:hover`, `:visited`, `:link`,
 		//				  `:enabled`, `:disabled`
-		//			* `:*-of-type` pseudo selectors
+		//			- `:*-of-type` pseudo selectors
 		//
 		//		dojo.query and XML Documents:
 		//		-----------------------------
@@ -1369,27 +1384,27 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		//		---------------------
 		//
 		//		If something other than a String is passed for the query,
-		//		`dojo.query` will return a new `dojo.NodeList` instance
+		//		`dojo.query` will return a new `dojo/NodeList` instance
 		//		constructed from that parameter alone and all further
 		//		processing will stop. This means that if you have a reference
 		//		to a node or NodeList, you can quickly construct a new NodeList
 		//		from the original by calling `dojo.query(node)` or
 		//		`dojo.query(list)`.
 		//
-		//	query:
+		// query:
 		//		The CSS3 expression to match against. For details on the syntax of
 		//		CSS3 selectors, see <http://www.w3.org/TR/css3-selectors/#selectors>
-		//	root:
+		// root:
 		//		A DOMNode (or node id) to scope the search from. Optional.
-		//	returns: Array
-		//	example:
+		// returns: Array
+		// example:
 		//		search the entire document for elements with the class "foo":
 		//	|	dojo.query(".foo");
 		//		these elements will match:
 		//	|	<span class="foo"></span>
 		//	|	<span class="foo bar"></span>
 		//	|	<p class="thud foo"></p>
-		//	example:
+		// example:
 		//		search the entire document for elements with the classes "foo" *and* "bar":
 		//	|	dojo.query(".foo.bar");
 		//		these elements will match:
@@ -1397,7 +1412,7 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		//		while these will not:
 		//	|	<span class="foo"></span>
 		//	|	<p class="thud foo"></p>
-		//	example:
+		// example:
 		//		find `<span>` elements which are descendants of paragraphs and
 		//		which have a "highlighted" class:
 		//	|	dojo.query("p span.highlighted");
@@ -1407,16 +1422,16 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		//	|			<span class="highlighted foo bar">...</span>
 		//	|		</span>
 		//	|	</p>
-		//	example:
+		// example:
 		//		set an "odd" class on all odd table rows inside of the table
 		//		`#tabular_data`, using the `>` (direct child) selector to avoid
 		//		affecting any nested tables:
 		//	|	dojo.query("#tabular_data > tbody > tr:nth-child(odd)").addClass("odd");
-		//	example:
+		// example:
 		//		remove all elements with the class "error" from the document
 		//		and store them in a list:
 		//	|	var errors = dojo.query(".error").orphan();
-		//	example:
+		// example:
 		//		add an onclick handler to every submit button in the document
 		//		which causes the form to be sent via Ajax instead:
 		//	|	dojo.query("input[type='submit']").onclick(function(e){
@@ -1434,18 +1449,11 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		//	|		});
 		//	|	});
 
-		root = root||getDoc();
-		var od = root.ownerDocument||root.documentElement;
+		root = root || getDoc();
 
 		// throw the big case sensitivity switch
-
-		// NOTE:
-		//		Opera in XHTML mode doesn't detect case-sensitivity correctly
-		//		and it's not clear that there's any way to test for it
-		caseSensitive = (root.contentType && root.contentType=="application/xml") ||
-						(dojo.isOpera && (root.doctype || od.toString() == "[object XMLDocument]")) ||
-						(!!od) &&
-				(dojo.isIE ? od.xml : (root.xmlVersion || od.xmlVersion));
+		var od = root.ownerDocument || root;	// root is either Document or a node inside the document
+		caseSensitive = (od.createElement("div").tagName === "div");
 
 		// NOTE:
 		//		adding "true" as the 2nd argument to getQueryFunc is useful for
@@ -1458,18 +1466,18 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		if(r && r.nozip){
 			return r;
 		}
-		return _zip(r); // dojo.NodeList
+		return _zip(r); // dojo/NodeList
 	};
 	query.filter = function(/*Node[]*/ nodeList, /*String*/ filter, /*String|DOMNode?*/ root){
 		// summary:
-		// 		function for filtering a NodeList based on a selector, optimized for simple selectors
+		//		function for filtering a NodeList based on a selector, optimized for simple selectors
 		var tmpNodeList = [],
 			parts = getQueryParts(filter),
 			filterFunc =
 				(parts.length == 1 && !/[^\w#\.]/.test(filter)) ?
 				getSimpleFilterFunc(parts[0]) :
 				function(node){
-					return dojo.query(filter, root).indexOf(node) != -1;
+					return array.indexOf(query(filter, dom.byId(root)), node) != -1;
 				};
 		for(var x = 0, te; te = nodeList[x]; x++){
 			if(filterFunc(te)){ tmpNodeList.push(te); }
@@ -1477,4 +1485,4 @@ define(["../_base/kernel", "../has", "../dom", "../_base/sniff", "../_base/array
 		return tmpNodeList;
 	};
 	return query;
-});//end defineQuery
+});
diff --git a/dojo/selector/lite.js b/dojo/selector/lite.js
index 8228828..50f1ed5 100644
--- a/dojo/selector/lite.js
+++ b/dojo/selector/lite.js
@@ -1,36 +1,44 @@
 define(["../has", "../_base/kernel"], function(has, dojo){
 "use strict";
-// summary:
-//		A small lightweight query selector engine that implements CSS2.1 selectors 
-// 		minus pseudo-classes and the sibling combinator, plus CSS3 attribute selectors
+
 var testDiv = document.createElement("div");
 var matchesSelector = testDiv.matchesSelector || testDiv.webkitMatchesSelector || testDiv.mozMatchesSelector || testDiv.msMatchesSelector || testDiv.oMatchesSelector; // IE9, WebKit, Firefox have this, but not Opera yet
 var querySelectorAll = testDiv.querySelectorAll;
+var unionSplit = /([^\s,](?:"(?:\\.|[^"])+"|'(?:\\.|[^'])+'|[^,])*)/g;
 has.add("dom-matches-selector", !!matchesSelector);
 has.add("dom-qsa", !!querySelectorAll); 
 
 // this is a simple query engine. It has handles basic selectors, and for simple
 // common selectors is extremely fast
 var liteEngine = function(selector, root){
+	// summary:
+	//		A small lightweight query selector engine that implements CSS2.1 selectors
+	//		minus pseudo-classes and the sibling combinator, plus CSS3 attribute selectors
+
 	if(combine && selector.indexOf(',') > -1){
 		return combine(selector, root);
 	}
-	var match = (querySelectorAll ? 
-		/^([\w]*)#([\w\-]+$)|^(\.)([\w\-\*]+$)|^(\w+$)/ : // this one only matches on simple queries where we can beat qSA with specific methods
-		/^([\w]*)#([\w\-]+)(?:\s+(.*))?$|(?:^|(>|.+\s+))([\w\-\*]+)(\S*$)/) // this one matches parts of the query that we can use to speed up manual filtering
+	// use the root's ownerDocument if provided, otherwise try to use dojo.doc. Note 
+	// that we don't use dojo/_base/window's doc to reduce dependencies, and 
+	// fallback to plain document if dojo.doc hasn't been defined (by dojo/_base/window).
+	// presumably we will have a better way to do this in 2.0 
+	var doc = root ? root.ownerDocument || root : dojo.doc || document, 
+		match = (querySelectorAll ? 
+			/^([\w]*)#([\w\-]+$)|^(\.)([\w\-\*]+$)|^(\w+$)/ : // this one only matches on simple queries where we can beat qSA with specific methods
+			/^([\w]*)#([\w\-]+)(?:\s+(.*))?$|(?:^|(>|.+\s+))([\w\-\*]+)(\S*$)/) // this one matches parts of the query that we can use to speed up manual filtering
 			.exec(selector);
-	root = root || document;
+	root = root || doc;
 	if(match){
 		// fast path regardless of whether or not querySelectorAll exists
 		if(match[2]){
 			// an #id
-			// use dojo.byId if available as it fixes the id retrieval in IE
-			var found = dojo.byId ? dojo.byId(match[2]) : document.getElementById(match[2]);
+			// use dojo.byId if available as it fixes the id retrieval in IE, note that we can't use the dojo namespace in 2.0, but if there is a conditional module use, we will use that
+			var found = dojo.byId ? dojo.byId(match[2], doc) : doc.getElementById(match[2]);
 			if(!found || (match[1] && match[1] != found.tagName.toLowerCase())){
 				// if there is a tag qualifer and it doesn't match, no matches
 				return [];
 			}
-			if(root != document){
+			if(root != doc){
 				// there is a root element, make sure we are a child of it
 				var parent = found;
 				while(parent != root){
@@ -89,10 +97,10 @@ var liteEngine = function(selector, root){
 var useRoot = function(context, query, method){
 	// this function creates a temporary id so we can do rooted qSA queries, this is taken from sizzle
 	var oldContext = context,
-		old = context.getAttribute( "id" ),
+		old = context.getAttribute("id"),
 		nid = old || "__dojo__",
 		hasParent = context.parentNode,
-		relativeHierarchySelector = /^\s*[+~]/.test( query );
+		relativeHierarchySelector = /^\s*[+~]/.test(query);
 
 	if(relativeHierarchySelector && !hasParent){
 		return [];
@@ -105,12 +113,17 @@ var useRoot = function(context, query, method){
 	if(relativeHierarchySelector && hasParent){
 		context = context.parentNode;
 	}
+	var selectors = query.match(unionSplit);
+	for(var i = 0; i < selectors.length; i++){
+		selectors[i] = "[id='" + nid + "'] " + selectors[i];
+	}
+	query = selectors.join(",");
 
-	try {
-		return method.call(context, "[id='" + nid + "'] " + query );
-	} finally {
-		if ( !old ) {
-			oldContext.removeAttribute( "id" );
+	try{
+		return method.call(context, query);
+	}finally{
+		if(!old){
+			oldContext.removeAttribute("id");
 		}
 	}
 };
@@ -119,18 +132,25 @@ if(!has("dom-matches-selector")){
 	var jsMatchesSelector = (function(){
 		// a JS implementation of CSS selector matching, first we start with the various handlers
 		var caseFix = testDiv.tagName == "div" ? "toLowerCase" : "toUpperCase";
-		function tag(tagName){
-			tagName = tagName[caseFix]();
-			return function(node){
-				return node.tagName == tagName;
-			}
-		}
-		function className(className){
-			var classNameSpaced = ' ' + className + ' ';
-			return function(node){
-				return node.className.indexOf(className) > -1 && (' ' + node.className + ' ').indexOf(classNameSpaced) > -1;
+		var selectorTypes = {
+			"": function(tagName){
+				tagName = tagName[caseFix]();
+				return function(node){
+					return node.tagName == tagName;
+				};
+			},
+			".": function(className){
+				var classNameSpaced = ' ' + className + ' ';
+				return function(node){
+					return node.className.indexOf(className) > -1 && (' ' + node.className + ' ').indexOf(classNameSpaced) > -1;
+				};
+			},
+			"#": function(id){
+				return function(node){
+					return node.id == id;
+				};
 			}
-		}
+		};
 		var attrComparators = {
 			"^=": function(attrValue, value){
 				return attrValue.indexOf(value) == 0;
@@ -155,15 +175,17 @@ if(!has("dom-matches-selector")){
 			}
 		};
 		function attr(name, value, type){
-			if(value.match(/['"]/)){
-				// it is quoted, do an eval to parse the string (CSS and JS parsing are close enough)
-				value = eval(value);
+			var firstChar = value.charAt(0);
+			if(firstChar == '"' || firstChar == "'"){
+				// it is quoted, remove the quotes
+				value = value.slice(1, -1);
 			}
+			value = value.replace(/\\/g,'');
 			var comparator = attrComparators[type || ""];
 			return function(node){
 				var attrValue = node.getAttribute(name);
 				return attrValue && comparator(attrValue, value);
-			}
+			};
 		}
 		function ancestor(matcher){
 			return function(node, root){
@@ -196,14 +218,9 @@ if(!has("dom-matches-selector")){
 			if(!matcher){
 				// create a matcher function for the given selector
 				// parse the selectors
-				if(selector.replace(/(?:\s*([> ])\s*)|(\.)?([\w-]+)|\[([\w-]+)\s*(.?=)?\s*([^\]]*)\]/g, function(t, combinator, type, value, attrName, attrType, attrValue){
+				if(selector.replace(/(?:\s*([> ])\s*)|(#|\.)?((?:\\.|[\w-])+)|\[\s*([\w-]+)\s*(.?=)?\s*("(?:\\.|[^"])+"|'(?:\\.|[^'])+'|(?:\\.|[^\]])*)\s*\]/g, function(t, combinator, type, value, attrName, attrType, attrValue){
 					if(value){
-						if(type == "."){
-							matcher = and(matcher, className(value));
-						}
-						else{
-							matcher = and(matcher, tag(value));
-						}
+						matcher = and(matcher, selectorTypes[type || ""](value.replace(/\\/g, '')));
 					}
 					else if(combinator){
 						matcher = (combinator == " " ? ancestor : parent)(matcher);
@@ -228,13 +245,15 @@ if(!has("dom-matches-selector")){
 if(!has("dom-qsa")){
 	var combine = function(selector, root){
 		// combined queries
-		selector = selector.split(/\s*,\s*/);
+		var selectors = selector.match(unionSplit);
 		var indexed = [];
 		// add all results and keep unique ones, this only runs in IE, so we take advantage 
 		// of known IE features, particularly sourceIndex which is unique and allows us to 
 		// order the results 
-		for(var i = 0; i < selector.length; i++){
-			var results = liteEngine(selector[i], root);
+		for(var i = 0; i < selectors.length; i++){
+			selector = new String(selectors[i].replace(/\s*$/,''));
+			selector.indexOf = escape; // keep it from recursively entering combine
+			var results = liteEngine(selector, root);
 			for(var j = 0, l = results.length; j < l; j++){
 				var node = results[j];
 				indexed[node.sourceIndex] = node;
@@ -250,7 +269,7 @@ if(!has("dom-qsa")){
 }
 
 liteEngine.match = matchesSelector ? function(node, selector, root){
-	if(root){
+	if(root && root.nodeType != 9){
 		// doesn't support three args, use rooted id trick
 		return useRoot(root, selector, function(query){
 			return matchesSelector.call(node, query);
diff --git a/dojo/sniff.js b/dojo/sniff.js
new file mode 100644
index 0000000..99266d5
--- /dev/null
+++ b/dojo/sniff.js
@@ -0,0 +1,80 @@
+define(["./has"], function(has){
+	// module:
+	//		dojo/sniff
+
+	/*=====
+	return function(){
+		// summary:
+		//		This module sets has() flags based on the current browser.
+		//		It returns the has() function.
+	};
+	=====*/
+
+	if(has("host-browser")){
+		var n = navigator,
+			dua = n.userAgent,
+			dav = n.appVersion,
+			tv = parseFloat(dav);
+
+		has.add("air", dua.indexOf("AdobeAIR") >= 0);
+		has.add("msapp", parseFloat(dua.split("MSAppHost/")[1]) || undefined);
+		has.add("khtml", dav.indexOf("Konqueror") >= 0 ? tv : undefined);
+		has.add("webkit", parseFloat(dua.split("WebKit/")[1]) || undefined);
+		has.add("chrome", parseFloat(dua.split("Chrome/")[1]) || undefined);
+		has.add("safari", dav.indexOf("Safari")>=0 && !has("chrome") ? parseFloat(dav.split("Version/")[1]) : undefined);
+		has.add("mac", dav.indexOf("Macintosh") >= 0);
+		has.add("quirks", document.compatMode == "BackCompat");
+		if(dua.match(/(iPhone|iPod|iPad)/)){
+			var p = RegExp.$1.replace(/P/, "p");
+			var v = dua.match(/OS ([\d_]+)/) ? RegExp.$1 : "1";
+			var os = parseFloat(v.replace(/_/, ".").replace(/_/g, ""));
+			has.add(p, os);		// "iphone", "ipad" or "ipod"
+			has.add("ios", os);
+		}
+		has.add("android", parseFloat(dua.split("Android ")[1]) || undefined);
+		has.add("bb", (dua.indexOf("BlackBerry") >= 0 || dua.indexOf("BB10") >= 0) && parseFloat(dua.split("Version/")[1]) || undefined);
+
+		has.add("svg", typeof SVGAngle !== "undefined");
+
+		if(!has("webkit")){
+			// Opera
+			if(dua.indexOf("Opera") >= 0){
+				// see http://dev.opera.com/articles/view/opera-ua-string-changes and http://www.useragentstring.com/pages/Opera/
+				// 9.8 has both styles; <9.8, 9.9 only old style
+				has.add("opera", tv >= 9.8 ? parseFloat(dua.split("Version/")[1]) || tv : tv);
+			}
+
+			// Mozilla and firefox
+			if(dua.indexOf("Gecko") >= 0 && !has("khtml") && !has("webkit")){
+				has.add("mozilla", tv);
+			}
+			if(has("mozilla")){
+				//We really need to get away from this. Consider a sane isGecko approach for the future.
+				has.add("ff", parseFloat(dua.split("Firefox/")[1] || dua.split("Minefield/")[1]) || undefined);
+			}
+
+			// IE
+			if(document.all && !has("opera")){
+				var isIE = parseFloat(dav.split("MSIE ")[1]) || undefined;
+
+				//In cases where the page has an HTTP header or META tag with
+				//X-UA-Compatible, then it is in emulation mode.
+				//Make sure isIE reflects the desired version.
+				//document.documentMode of 5 means quirks mode.
+				//Only switch the value if documentMode's major version
+				//is different from isIE's major version.
+				var mode = document.documentMode;
+				if(mode && mode != 5 && Math.floor(isIE) != mode){
+					isIE = mode;
+				}
+
+				has.add("ie", isIE);
+			}
+
+			// Wii
+			has.add("wii", typeof opera != "undefined" && opera.wiiremote);
+		}
+	}
+
+	return has;
+});
diff --git a/dojo/store/Cache.js b/dojo/store/Cache.js
index bc3cf4f..66de169 100644
--- a/dojo/store/Cache.js
+++ b/dojo/store/Cache.js
@@ -1,39 +1,10 @@
-define(["../_base/lang","../_base/Deferred"
-],function(lang, Deferred) {
-	// module:
-	//		dojo/store/Cache
-	// summary:
-	//		TODOC
+define(["../_base/lang","../when" /*=====, "../_base/declare", "./api/Store" =====*/],
+function(lang, when /*=====, declare, Store =====*/){
 
-var store = lang.getObject("dojo.store", true);
+// module:
+//		dojo/store/Cache
 
-/*=====
-dojo.declare("dojo.store.__CacheArgs", null, {
-	constructor: function(){
-		// summary:
-		//		These are additional options for how caching is handled.
-		// isLoaded: Function?
-		//		This is a function that will be called for each item in a query response to determine
-		//		if it is cacheable. If isLoaded returns true, the item will be cached, otherwise it
-		//		will not be cached. If isLoaded is not provided, all items will be cached.
-		this.isLoaded = isLoaded;
-	}
-});
-=====*/
-store.Cache = function(masterStore, cachingStore, /*dojo.store.__CacheArgs*/ options){
-	// summary:
-	//		The Cache store wrapper takes a master store and a caching store,
-	//		caches data from the master into the caching store for faster
-	//		lookup. Normally one would use a memory store for the caching
-	//		store and a server store like JsonRest for the master store.
-	// masterStore:
-	//		This is the authoritative store, all uncached requests or non-safe requests will
-	//		be made against this store.
-	// cachingStore:
-	//		This is the caching store that will be used to store responses for quick access.
-	//		Typically this should be a local store.
-	// options:
-	//		These are additional options for how caching is handled.
+var Cache = function(masterStore, cachingStore, options){
 	options = options || {};
 	return lang.delegate(masterStore, {
 		query: function(query, directives){
@@ -48,8 +19,8 @@ store.Cache = function(masterStore, cachingStore, /*dojo.store.__CacheArgs*/ opt
 		// look for a queryEngine in either store
 		queryEngine: masterStore.queryEngine || cachingStore.queryEngine,
 		get: function(id, directives){
-			return Deferred.when(cachingStore.get(id), function(result){
-				return result || Deferred.when(masterStore.get(id, directives), function(result){
+			return when(cachingStore.get(id), function(result){
+				return result || when(masterStore.get(id, directives), function(result){
 					if(result){
 						cachingStore.put(result, {id: id});
 					}
@@ -58,21 +29,23 @@ store.Cache = function(masterStore, cachingStore, /*dojo.store.__CacheArgs*/ opt
 			});
 		},
 		add: function(object, directives){
-			return Deferred.when(masterStore.add(object, directives), function(result){
+			return when(masterStore.add(object, directives), function(result){
 				// now put result in cache
-				return cachingStore.add(typeof result == "object" ? result : object, directives);
+				cachingStore.add(object && typeof result == "object" ? result : object, directives);
+				return result; // the result from the add should be dictated by the masterStore and be unaffected by the cachingStore
 			});
 		},
 		put: function(object, directives){
 			// first remove from the cache, so it is empty until we get a response from the master store
 			cachingStore.remove((directives && directives.id) || this.getIdentity(object));
-			return Deferred.when(masterStore.put(object, directives), function(result){
+			return when(masterStore.put(object, directives), function(result){
 				// now put result in cache
-				return cachingStore.put(typeof result == "object" ? result : object, directives);
+				cachingStore.put(object && typeof result == "object" ? result : object, directives);
+				return result; // the result from the put should be dictated by the masterStore and be unaffected by the cachingStore
 			});
 		},
 		remove: function(id, directives){
-			return Deferred.when(masterStore.remove(id, directives), function(result){
+			return when(masterStore.remove(id, directives), function(result){
 				return cachingStore.remove(id, directives);
 			});
 		},
@@ -81,21 +54,47 @@ store.Cache = function(masterStore, cachingStore, /*dojo.store.__CacheArgs*/ opt
 		}
 	});
 };
+lang.setObject("dojo.store.Cache", Cache);
+
 /*=====
-dojo.declare("dojo.store.Cache", null, {
+var __CacheArgs = {
+	// summary:
+	//		These are additional options for how caching is handled.
+	// isLoaded: Function?
+	//		This is a function that will be called for each item in a query response to determine
+	//		if it is cacheable. If isLoaded returns true, the item will be cached, otherwise it
+	//		will not be cached. If isLoaded is not provided, all items will be cached.
+};
+
+Cache = declare(Store, {
+	// summary:
+	//		The Cache store wrapper takes a master store and a caching store,
+	//		caches data from the master into the caching store for faster
+	//		lookup. Normally one would use a memory store for the caching
+	//		store and a server store like JsonRest for the master store.
 	// example:
-	//	|	var master = new dojo.store.Memory(data);
-	//	|	var cacher = new dojo.store.Memory();
-	//	|	var store = new dojo.store.Cache(master, cacher);
+	//	|	var master = new Memory(data);
+	//	|	var cacher = new Memory();
+	//	|	var store = new Cache(master, cacher);
 	//
+	constructor: function(masterStore, cachingStore, options){
+		// masterStore:
+		//		This is the authoritative store, all uncached requests or non-safe requests will
+		//		be made against this store.
+		// cachingStore:
+		//		This is the caching store that will be used to store responses for quick access.
+		//		Typically this should be a local store.
+		// options: __CacheArgs?
+		//		These are additional options for how caching is handled.
+	},
 	query: function(query, directives){
 		// summary:
 		//		Query the underlying master store and cache any results.
 		// query: Object|String
 		//		The object or string containing query information. Dependent on the query engine used.
-		// directives: dojo.store.util.SimpleQueryEngine.__queryOptions?
+		// directives: dojo/store/api/Store.QueryOptions?
 		//		An optional keyword arguments object with additional parameters describing the query.
-		// returns: dojo.store.util.QueryResults
+		// returns: dojo/store/api/Store.QueryResults
 		//		A QueryResults object that can be used to iterate over.
 	},
 	get: function(id, directives){
@@ -103,9 +102,9 @@ dojo.declare("dojo.store.Cache", null, {
 		//		Get the object with the specific id.
 		// id: Number
 		//		The identifier for the object in question.
-		// directives: dojo.store.__GetOptions?
+		// directives: Object?
 		//		Any additional parameters needed to describe how the get should be performed.
-		// returns: dojo.store.util.QueryResults
+		// returns: dojo/store/api/Store.QueryResults
 		//		A QueryResults object.
 	},
 	add: function(object, directives){
@@ -113,7 +112,7 @@ dojo.declare("dojo.store.Cache", null, {
 		//		Add the given object to the store.
 		// object: Object
 		//		The object to add to the store.
-		// directives: dojo.store.__AddOptions?
+		// directives: dojo/store/api/Store.AddOptions?
 		//		Any additional parameters needed to describe how the add should be performed.
 		// returns: Number
 		//		The new id for the object.
@@ -123,18 +122,16 @@ dojo.declare("dojo.store.Cache", null, {
 		//		Put the object into the store (similar to an HTTP PUT).
 		// object: Object
 		//		The object to put to the store.
-		// directives: dojo.store.__PutOptions?
+		// directives: dojo/store/api/Store.PutDirectives?
 		//		Any additional parameters needed to describe how the put should be performed.
 		// returns: Number
 		//		The new id for the object.
 	},
-	remove: function(id, directives){
+	remove: function(id){
 		// summary:
 		//		Remove the object with the specific id.
 		// id: Number
 		//		The identifier for the object in question.
-		// directives: dojo.store.__RemoveOptions?
-		//		Any additional parameters needed to describe how the remove should be performed.
 	},
 	evict: function(id){
 		// summary:
@@ -144,5 +141,6 @@ dojo.declare("dojo.store.Cache", null, {
 	}
 });
 =====*/
-return store.Cache;
+
+return Cache;
 });
diff --git a/dojo/store/DataStore.js b/dojo/store/DataStore.js
index fac842f..c16a8d8 100644
--- a/dojo/store/DataStore.js
+++ b/dojo/store/DataStore.js
@@ -1,18 +1,24 @@
-define(["../_base/lang", "../_base/declare", "../_base/Deferred", "../_base/array", "./util/QueryResults"
-], function(lang,declare,Deferred,array,QueryResults) {
-	// module:
-	//		dojo/store/DataStore
-	// summary:
-	//		TODOC
+define([
+	"../_base/lang", "../_base/declare", "../Deferred", "../_base/array",
+	"./util/QueryResults", "./util/SimpleQueryEngine" /*=====, "./api/Store" =====*/
+], function(lang, declare, Deferred, array, QueryResults, SimpleQueryEngine /*=====, Store =====*/){
+
+// module:
+//		dojo/store/DataStore
 
 
-return declare("dojo.store.DataStore", null, {
+// No base class, but for purposes of documentation, the base class is dojo/store/api/Store
+var base = null;
+/*===== base = Store; =====*/
+
+return declare("dojo.store.DataStore", base, {
+	// summary:
+	//		This is an adapter for using Dojo Data stores with an object store consumer.
+	//		You can provide a Dojo data store and use this adapter to interact with it through
+	//		the Dojo object store API
+
 	target: "",
 	constructor: function(options){
-		// summary:
-		//		This is an adapter for using Dojo Data stores with an object store consumer.
-		//		You can provide a Dojo data store and use this adapter to interact with it through
-		//		the Dojo object store API
 		// options: Object?
 		//		This provides any configuration information that will be mixed into the store,
 		//		including a reference to the Dojo data store under the property "store".
@@ -46,19 +52,42 @@ return declare("dojo.store.DataStore", null, {
 	// store:
 	//		The object store to convert to a data store
 	store: null,
+	// queryEngine: Function
+	//		Defines the query engine to use for querying the data store
+	queryEngine: SimpleQueryEngine,
+	
 	_objectConverter: function(callback){
 		var store = this.store;
 		var idProperty = this.idProperty;
-		return function(item){
+		function convert(item){
 			var object = {};
 			var attributes = store.getAttributes(item);
 			for(var i = 0; i < attributes.length; i++){
-				object[attributes[i]] = store.getValue(item, attributes[i]);
+				var attribute = attributes[i];
+				var values = store.getValues(item, attribute);
+				if(values.length > 1){
+					for(var j = 0; j < values.length; j++){
+						var value = values[j];
+						if(typeof value == 'object' && store.isItem(value)){
+							values[j] = convert(value);
+						}
+					}
+					value = values;
+				}else{
+					var value = store.getValue(item, attribute);
+					if(typeof value == 'object' && store.isItem(value)){
+						value = convert(value);
+					}
+				}
+				object[attributes[i]] = value;
 			}
-			if(!(idProperty in object)){
+			if(!(idProperty in object) && store.getIdentity){
 				object[idProperty] = store.getIdentity(item);
 			}
-			return callback(object);
+			return object;
+		}
+		return function(item){
+			return callback(convert(item));
 		};
 	},
 	get: function(id, options){
@@ -99,6 +128,7 @@ return declare("dojo.store.DataStore", null, {
 		var idProperty = this.idProperty;
 		if(typeof id == "undefined"){
 			store.newItem(object);
+			store.save();
 		}else{
 			store.fetchItemByIdentity({
 				identity: id,
@@ -113,6 +143,7 @@ return declare("dojo.store.DataStore", null, {
 					}else{
 						store.newItem(object);
 					}
+					store.save();
 				}
 			});
 		}
@@ -127,6 +158,7 @@ return declare("dojo.store.DataStore", null, {
 			identity: id,
 			onItem: function(item){
 				store.deleteItem(item);
+				store.save();
 			}
 		});
 	},
@@ -137,7 +169,7 @@ return declare("dojo.store.DataStore", null, {
 		//		The query to use for retrieving objects from the store
 		// options: Object?
 		//		Optional options object as used by the underlying dojo.data Store.
-		// returns: dojo.store.util.QueryResults
+		// returns: dojo/store/api/Store.QueryResults
 		//		A query results object that can be used to iterate over results.
 		var fetchHandle;
 		var deferred = new Deferred(function(){ fetchHandle.abort && fetchHandle.abort(); });
diff --git a/dojo/store/JsonRest.js b/dojo/store/JsonRest.js
index e2082f4..54d1c23 100644
--- a/dojo/store/JsonRest.js
+++ b/dojo/store/JsonRest.js
@@ -1,74 +1,107 @@
-define(["../_base/xhr", "../json", "../_base/declare", "./util/QueryResults"
-], function(xhr, JSON, declare, QueryResults) {
-  //  module:
-  //    dojo/store/JsonRest
-  //  summary:
-  //    The module defines a JSON/REST based object store 
-
-return declare("dojo.store.JsonRest", null, {
+define(["../_base/xhr", "../_base/lang", "../json", "../_base/declare", "./util/QueryResults" /*=====, "./api/Store" =====*/
+], function(xhr, lang, JSON, declare, QueryResults /*=====, Store =====*/){
+
+// No base class, but for purposes of documentation, the base class is dojo/store/api/Store
+var base = null;
+/*===== base = Store; =====*/
+
+/*=====
+var __HeaderOptions = {
+		// headers: Object?
+		//		Additional headers to send along with the request.
+	},
+	__PutDirectives = declare(Store.PutDirectives, __HeaderOptions),
+	__QueryOptions = declare(Store.QueryOptions, __HeaderOptions);
+=====*/
+
+return declare("dojo.store.JsonRest", base, {
 	// summary:
 	//		This is a basic store for RESTful communicating with a server through JSON
-	//		formatted data. It implements dojo.store.api.Store.
+	//		formatted data. It implements dojo/store/api/Store.
 
-	constructor: function(/*dojo.store.JsonRest*/ options){
+	constructor: function(options){
 		// summary:
 		//		This is a basic store for RESTful communicating with a server through JSON
 		//		formatted data.
-		// options:
+		// options: dojo/store/JsonRest
 		//		This provides any configuration information that will be mixed into the store
+		this.headers = {};
 		declare.safeMixin(this, options);
 	},
+
+	// headers: Object
+	//		Additional headers to pass in all requests to the server. These can be overridden
+	//		by passing additional headers to calls to the store.
+	headers: {},
+
 	// target: String
 	//		The target base URL to use for all requests to the server. This string will be
-	// 	prepended to the id to generate the URL (relative or absolute) for requests
-	// 	sent to the server
+	//		prepended to the id to generate the URL (relative or absolute) for requests
+	//		sent to the server
 	target: "",
+
 	// idProperty: String
 	//		Indicates the property to use as the identity property. The values of this
 	//		property should be unique.
 	idProperty: "id",
+
 	// sortParam: String
-	// 		The query parameter to used for holding sort information. If this is omitted, than
-	//		the sort information is included in a functional query token to avoid colliding 
-	// 		with the set of name/value pairs.
-	
+	//		The query parameter to used for holding sort information. If this is omitted, than
+	//		the sort information is included in a functional query token to avoid colliding
+	//		with the set of name/value pairs.
+
+	// ascendingPrefix: String
+	//		The prefix to apply to sort attribute names that are ascending
+	ascendingPrefix: "+",
+
+	// descendingPrefix: String
+	//		The prefix to apply to sort attribute names that are ascending
+	descendingPrefix: "-",
+	 
+
 	get: function(id, options){
-		//	summary:
+		// summary:
 		//		Retrieves an object by its identity. This will trigger a GET request to the server using
 		//		the url `this.target + id`.
-		//	id: Number
+		// id: Number
 		//		The identity to use to lookup the object
-		//	returns: Object
+		// options: Object?
+		//		HTTP headers. For consistency with other methods, if a `headers` key exists on this object, it will be
+		//		used to provide HTTP headers instead.
+		// returns: Object
 		//		The object in the store that matches the given id.
-		var headers = options || {};
-		headers.Accept = this.accepts;
+		options = options || {};
+		var headers = lang.mixin({ Accept: this.accepts }, this.headers, options.headers || options);
 		return xhr("GET", {
-			url:this.target + id,
+			url: this.target + id,
 			handleAs: "json",
 			headers: headers
 		});
 	},
+
 	// accepts: String
 	//		Defines the Accept header to use on HTTP requests
-	accepts: "application/javascript, application/json", 
+	accepts: "application/javascript, application/json",
+
 	getIdentity: function(object){
 		// summary:
 		//		Returns an object's identity
 		// object: Object
 		//		The object to get the identity from
-		//	returns: Number
+		// returns: Number
 		return object[this.idProperty];
 	},
+
 	put: function(object, options){
 		// summary:
 		//		Stores an object. This will trigger a PUT request to the server
 		//		if the object has an id, otherwise it will trigger a POST request.
 		// object: Object
 		//		The object to store.
-		// options: dojo.store.api.Store.PutDirectives?
+		// options: __PutDirectives?
 		//		Additional metadata for storing the data.  Includes an "id"
 		//		property if a specific id is to be used.
-		//	returns: Number
+		// returns: dojo/_base/Deferred
 		options = options || {};
 		var id = ("id" in options) ? options.id : this.getIdentity(object);
 		var hasId = typeof id != "undefined";
@@ -76,64 +109,74 @@ return declare("dojo.store.JsonRest", null, {
 				url: hasId ? this.target + id : this.target,
 				postData: JSON.stringify(object),
 				handleAs: "json",
-				headers:{
+				headers: lang.mixin({
 					"Content-Type": "application/json",
 					Accept: this.accepts,
 					"If-Match": options.overwrite === true ? "*" : null,
 					"If-None-Match": options.overwrite === false ? "*" : null
-				}
+				}, this.headers, options.headers)
 			});
 	},
+
 	add: function(object, options){
 		// summary:
 		//		Adds an object. This will trigger a PUT request to the server
 		//		if the object has an id, otherwise it will trigger a POST request.
 		// object: Object
 		//		The object to store.
-		// options: dojo.store.api.Store.PutDirectives?
+		// options: __PutDirectives?
 		//		Additional metadata for storing the data.  Includes an "id"
 		//		property if a specific id is to be used.
 		options = options || {};
 		options.overwrite = false;
 		return this.put(object, options);
 	},
-	remove: function(id){
+
+	remove: function(id, options){
 		// summary:
 		//		Deletes an object by its identity. This will trigger a DELETE request to the server.
 		// id: Number
 		//		The identity to use to delete the object
-		return xhr("DELETE",{
-			url:this.target + id
+		// options: __HeaderOptions?
+		//		HTTP headers.
+		options = options || {};
+		return xhr("DELETE", {
+			url: this.target + id,
+			headers: lang.mixin({}, this.headers, options.headers)
 		});
 	},
+
 	query: function(query, options){
 		// summary:
 		//		Queries the store for objects. This will trigger a GET request to the server, with the
 		//		query added as a query string.
 		// query: Object
 		//		The query to use for retrieving objects from the store.
-		//	options: dojo.store.api.Store.QueryOptions?
+		// options: __QueryOptions?
 		//		The optional arguments to apply to the resultset.
-		//	returns: dojo.store.api.Store.QueryResults
+		// returns: dojo/store/api/Store.QueryResults
 		//		The results of the query, extended with iterative methods.
-		var headers = {Accept: this.accepts};
 		options = options || {};
 
+		var headers = lang.mixin({ Accept: this.accepts }, this.headers, options.headers);
+
 		if(options.start >= 0 || options.count >= 0){
-			headers.Range = "items=" + (options.start || '0') + '-' +
+			headers.Range = headers["X-Range"] //set X-Range for Opera since it blocks "Range" header
+				 = "items=" + (options.start || '0') + '-' +
 				(("count" in options && options.count != Infinity) ?
 					(options.count + (options.start || 0) - 1) : '');
 		}
+		var hasQuestionMark = this.target.indexOf("?") > -1;
 		if(query && typeof query == "object"){
 			query = xhr.objectToQuery(query);
-			query = query ? "?" + query: "";
+			query = query ? (hasQuestionMark ? "&" : "?") + query: "";
 		}
 		if(options && options.sort){
 			var sortParam = this.sortParam;
-			query += (query ? "&" : "?") + (sortParam ? sortParam + '=' : "sort(");
+			query += (query || hasQuestionMark ? "&" : "?") + (sortParam ? sortParam + '=' : "sort(");
 			for(var i = 0; i<options.sort.length; i++){
 				var sort = options.sort[i];
-				query += (i > 0 ? "," : "") + (sort.descending ? '-' : '+') + encodeURIComponent(sort.attribute);
+				query += (i > 0 ? "," : "") + (sort.descending ? this.descendingPrefix : this.ascendingPrefix) + encodeURIComponent(sort.attribute);
 			}
 			if(!sortParam){
 				query += ")";
@@ -146,7 +189,7 @@ return declare("dojo.store.JsonRest", null, {
 		});
 		results.total = results.then(function(){
 			var range = results.ioArgs.xhr.getResponseHeader("Content-Range");
-			return range && (range=range.match(/\/(.*)/)) && +range[1];
+			return range && (range = range.match(/\/(.*)/)) && +range[1];
 		});
 		return QueryResults(results);
 	}
diff --git a/dojo/store/Memory.js b/dojo/store/Memory.js
index 6824d5f..e135a4e 100644
--- a/dojo/store/Memory.js
+++ b/dojo/store/Memory.js
@@ -1,19 +1,22 @@
-define(["../_base/declare", "./util/QueryResults", "./util/SimpleQueryEngine"], function(declare, QueryResults, SimpleQueryEngine) {
-  //  module:
-  //    dojo/store/Memory
-  //  summary:
-  //    The module defines an in-memory object store.
+define(["../_base/declare", "./util/QueryResults", "./util/SimpleQueryEngine" /*=====, "./api/Store" =====*/],
+function(declare, QueryResults, SimpleQueryEngine /*=====, Store =====*/){
 
+// module:
+//		dojo/store/Memory
 
-return declare("dojo.store.Memory", null, {
+// No base class, but for purposes of documentation, the base class is dojo/store/api/Store
+var base = null;
+/*===== base = Store; =====*/
+
+return declare("dojo.store.Memory", base, {
 	// summary:
-	//		This is a basic in-memory object store. It implements dojo.store.api.Store.
-	constructor: function(/*dojo.store.Memory*/ options){
+	//		This is a basic in-memory object store. It implements dojo/store/api/Store.
+	constructor: function(options){
 		// summary:
 		//		Creates a memory object store.
-		// options:
+		// options: dojo/store/Memory
 		//		This provides any configuration information that will be mixed into the store.
-		// 		This should generally include the data property to provide the starting set of data.
+		//		This should generally include the data property to provide the starting set of data.
 		for(var i in options){
 			this[i] = options[i];
 		}
@@ -36,35 +39,35 @@ return declare("dojo.store.Memory", null, {
 	//		Defines the query engine to use for querying the data store
 	queryEngine: SimpleQueryEngine,
 	get: function(id){
-		//	summary:
+		// summary:
 		//		Retrieves an object by its identity
-		//	id: Number
+		// id: Number
 		//		The identity to use to lookup the object
-		//	returns: Object
+		// returns: Object
 		//		The object in the store that matches the given id.
 		return this.data[this.index[id]];
 	},
 	getIdentity: function(object){
-		// 	summary:
+		// summary:
 		//		Returns an object's identity
-		// 	object: Object
+		// object: Object
 		//		The object to get the identity from
-		//	returns: Number
+		// returns: Number
 		return object[this.idProperty];
 	},
 	put: function(object, options){
-		// 	summary:
+		// summary:
 		//		Stores an object
-		// 	object: Object
+		// object: Object
 		//		The object to store.
-		// 	options: dojo.store.api.Store.PutDirectives??
+		// options: dojo/store/api/Store.PutDirectives?
 		//		Additional metadata for storing the data.  Includes an "id"
 		//		property if a specific id is to be used.
-		//	returns: Number
+		// returns: Number
 		var data = this.data,
 			index = this.index,
 			idProperty = this.idProperty;
-		var id = (options && "id" in options) ? options.id : idProperty in object ? object[idProperty] : Math.random();
+		var id = object[idProperty] = (options && "id" in options) ? options.id : idProperty in object ? object[idProperty] : Math.random();
 		if(id in index){
 			// object exists
 			if(options && options.overwrite === false){
@@ -79,25 +82,25 @@ return declare("dojo.store.Memory", null, {
 		return id;
 	},
 	add: function(object, options){
-		// 	summary:
+		// summary:
 		//		Creates an object, throws an error if the object already exists
-		// 	object: Object
+		// object: Object
 		//		The object to store.
-		// 	options: dojo.store.api.Store.PutDirectives??
+		// options: dojo/store/api/Store.PutDirectives?
 		//		Additional metadata for storing the data.  Includes an "id"
 		//		property if a specific id is to be used.
-		//	returns: Number
+		// returns: Number
 		(options = options || {}).overwrite = false;
 		// call put with overwrite being false
 		return this.put(object, options);
 	},
 	remove: function(id){
-		// 	summary:
+		// summary:
 		//		Deletes an object by its identity
-		// 	id: Number
+		// id: Number
 		//		The identity to use to delete the object
 		// returns: Boolean
-		// 		Returns true if an object was removed, falsy (undefined) if no object matched the id
+		//		Returns true if an object was removed, falsy (undefined) if no object matched the id
 		var index = this.index;
 		var data = this.data;
 		if(id in index){
@@ -108,19 +111,19 @@ return declare("dojo.store.Memory", null, {
 		}
 	},
 	query: function(query, options){
-		// 	summary:
+		// summary:
 		//		Queries the store for objects.
-		// 	query: Object
+		// query: Object
 		//		The query to use for retrieving objects from the store.
-		//	options: dojo.store.api.Store.QueryOptions?
+		// options: dojo/store/api/Store.QueryOptions?
 		//		The optional arguments to apply to the resultset.
-		//	returns: dojo.store.api.Store.QueryResults
+		// returns: dojo/store/api/Store.QueryResults
 		//		The results of the query, extended with iterative methods.
 		//
-		// 	example:
-		// 		Given the following store:
+		// example:
+		//		Given the following store:
 		//
-		// 	|	var store = new dojo.store.Memory({
+		// 	|	var store = new Memory({
 		// 	|		data: [
 		// 	|			{id: 1, name: "one", prime: false },
 		//	|			{id: 2, name: "two", even: true, prime: true},
@@ -140,9 +143,9 @@ return declare("dojo.store.Memory", null, {
 		return QueryResults(this.queryEngine(query, options)(this.data));
 	},
 	setData: function(data){
-		// 	summary:
+		// summary:
 		//		Sets the given data as the source for this store, and indexes it
-		//	data: Object[]
+		// data: Object[]
 		//		An array of objects to use as the source of data.
 		if(data.items){
 			// just for convenience with the data format IFRS expects
diff --git a/dojo/store/Observable.js b/dojo/store/Observable.js
index 4517353..ce1469a 100644
--- a/dojo/store/Observable.js
+++ b/dojo/store/Observable.js
@@ -1,13 +1,10 @@
-define(["../_base/kernel", "../_base/lang", "../_base/Deferred", "../_base/array"
-], function(kernel, lang, Deferred, array) {
-	// module:
-	//		dojo/store/Observable
-	// summary:
-	//		TODOC
+define(["../_base/kernel", "../_base/lang", "../when", "../_base/array" /*=====, "./api/Store" =====*/
+], function(kernel, lang, when, array /*=====, Store =====*/){
 
-var ds = lang.getObject("dojo.store", true);
+// module:
+//		dojo/store/Observable
 
-return ds.Observable = function(store){
+var Observable = function(/*Store*/ store){
 	// summary:
 	//		The Observable store wrapper takes a store and sets an observe method on query()
 	//		results that can be used to monitor results for changes.
@@ -20,7 +17,7 @@ return ds.Observable = function(store){
 	//		Create a Memory store that returns an observable query, and then log some
 	//		information about that query.
 	//
-	//	|	var store = dojo.store.Observable(new dojo.store.Memory({
+	//	|	var store = Observable(new Memory({
 	//	|		data: [
 	//	|			{id: 1, name: "one", prime: false},
 	//	|			{id: 2, name: "two", even: true, prime: true},
@@ -39,6 +36,9 @@ return ds.Observable = function(store){
 	var undef, queryUpdaters = [], revision = 0;
 	// a Comet driven store could directly call notify to notify observers when data has
 	// changed on the backend
+	// create a new instance
+	store = lang.delegate(store);
+	
 	store.notify = function(object, existingId){
 		revision++;
 		var updaters = queryUpdaters.slice();
@@ -62,7 +62,7 @@ return ds.Observable = function(store){
 				if(listeners.push(listener) == 1){
 					// first listener was added, create the query checker and updater
 					queryUpdaters.push(queryUpdater = function(changed, existingId){
-						Deferred.when(results, function(resultsArray){
+						when(results, function(resultsArray){
 							var atEnd = resultsArray.length != options.count;
 							var i, l, listener;
 							if(++queryRevision != revision){
@@ -105,10 +105,17 @@ return ds.Observable = function(store){
 										resultsArray.splice(insertedInto, 0, changed); // and insert into the results array with the correct index
 									}
 								}
-							}else if(changed && !options.start){
+							}else if(changed){
 								// we don't have a queryEngine, so we can't provide any information
-								// about where it was inserted, but we can at least indicate a new object
-								insertedInto = removedFrom >= 0 ? removedFrom : (store.defaultIndex || 0);
+								// about where it was inserted or moved to. If it is an update, we leave it's position alone, other we at least indicate a new object
+								if(existingId !== undef){
+									// an update, keep the index the same
+									insertedInto = removedFrom;
+								}else if(!options.start){
+									// a new object
+									insertedInto = store.defaultIndex || 0;
+									resultsArray.splice(insertedInto, 0, changed);
+								}
 							}
 							if((removedFrom > -1 || insertedInto > -1) &&
 									(includeObjectUpdates || !queryExecutor || (removedFrom != insertedInto))){
@@ -120,19 +127,20 @@ return ds.Observable = function(store){
 						});
 					});
 				}
-				return {
-					cancel: function(){
-						// remove this listener
-						var index = array.indexOf(listeners, listener);
-						if(index > -1){ // check to make sure we haven't already called cancel
-							listeners.splice(index, 1);
-							if(!listeners.length){
-								// no more listeners, remove the query updater too
-								queryUpdaters.splice(array.indexOf(queryUpdaters, queryUpdater), 1);
-							}
-						}						
+				var handle = {};
+				// TODO: Remove cancel in 2.0.
+				handle.remove = handle.cancel = function(){
+					// remove this listener
+					var index = array.indexOf(listeners, listener);
+					if(index > -1){ // check to make sure we haven't already called cancel
+						listeners.splice(index, 1);
+						if(!listeners.length){
+							// no more listeners, remove the query updater too
+							queryUpdaters.splice(array.indexOf(queryUpdaters, queryUpdater), 1);
+						}
 					}
 				};
+				return handle;
 			};
 		}
 		return results;
@@ -149,7 +157,7 @@ return ds.Observable = function(store){
 				inMethod = true;
 				try{
 					var results = original.apply(this, arguments);
-					Deferred.when(results, function(results){
+					when(results, function(results){
 						action((typeof results == "object" && results) || value);
 					});
 					return results;
@@ -172,4 +180,8 @@ return ds.Observable = function(store){
 
 	return store;
 };
+
+lang.setObject("dojo.store.Observable", Observable);
+
+return Observable;
 });
diff --git a/dojo/store/README b/dojo/store/README
index cb33da0..4fb5ac7 100644
--- a/dojo/store/README
+++ b/dojo/store/README
@@ -1,10 +1,6 @@
-This folder contains the stores and utilities implementing the proposed new Dojo Object Store API,
+This folder contains the stores and utilities implementing the Dojo Object Store API,
 a successor and unifier to Dojo Data, Dojo Storage, and potentially Dojo Model. These
-stores are brand new, and designed to provide simple lightweight implementations 
-providing core functionality for typical applications. These modules are under active 
-development, and exist here at this time to provide maximum visibility to the 
-efforts to design and develop this new API and set of base stores. The goal is 
-to have these stores ready for Dojo 1.6. In the meantime, these stores are likely to
-have API changes, may be missing some functionality, tests, and/or documentation.
-If these modules are not deemed suitably stable by the 1.6 release, this directory (or
-individual modules) will be removed and be given a later release target.  
\ No newline at end of file
+stores are designed to provide simple lightweight implementations 
+providing core functionality for typical applications.  
+
+See http://dojotoolkit.org/features/1.6/object-store for more information
\ No newline at end of file
diff --git a/dojo/store/api/Store.js b/dojo/store/api/Store.js
index f16a836..4704669 100644
--- a/dojo/store/api/Store.js
+++ b/dojo/store/api/Store.js
@@ -1,14 +1,13 @@
-define(["dojo/_base/declare"], function(declare) {
-	// module:
-	//		dojo/store/api/Store
-	// summary:
-	//		The module defines the Dojo object store interface.
+define(["../../_base/declare"], function(declare){
+
+// module:
+//		dojo/api/Store
 
-var Store = declare("dojo.store.api.Store", null, {
+var Store = declare(null, {
 	// summary:
 	//		This is an abstract API that data provider implementations conform to.
 	//		This file defines methods signatures and intentionally leaves all the
-	//		methods unimplemented.  For more information on the dojo.store APIs,
+	//		methods unimplemented.  For more information on the ,
 	//		please visit: http://dojotoolkit.org/reference-guide/dojo/store.html
 	//		Every method and property is optional, and is only needed if the functionality
 	//		it provides is required.
@@ -17,7 +16,7 @@ var Store = declare("dojo.store.api.Store", null, {
 	//		for query() which already defines an async return value).
 
 	// idProperty: String
-	//		If the store has a single primary key, this tndicates the property to use as the
+	//		If the store has a single primary key, this indicates the property to use as the
 	//		identity property. The values of this property should be unique.
 	idProperty: "id",
 
@@ -55,7 +54,7 @@ var Store = declare("dojo.store.api.Store", null, {
 		//		Stores an object
 		// object: Object
 		//		The object to store.
-		// directives: dojo.store.api.Store.PutDirectives?
+		// directives: dojo/store/api/Store.PutDirectives?
 		//		Additional directives for storing objects.
 		// returns: Number|String
 	},
@@ -64,7 +63,7 @@ var Store = declare("dojo.store.api.Store", null, {
 		//		Creates an object, throws an error if the object already exists
 		// object: Object
 		//		The object to store.
-		// directives: dojo.store.api.Store.PutDirectives?
+		// directives: dojo/store/api/Store.PutDirectives?
 		//		Additional directives for creating objects.
 		// returns: Number|String
 	},
@@ -89,9 +88,9 @@ var Store = declare("dojo.store.api.Store", null, {
 		//		set of data from the store.
 		// query: String|Object|Function
 		//		The query to use for retrieving objects from the store.
-		// options: dojo.store.api.Store.QueryOptions
+		// options: dojo/store/api/Store.QueryOptions
 		//		The optional arguments to apply to the resultset.
-		// returns: dojo.store.api.Store.QueryResults
+		// returns: dojo/store/api/Store.QueryResults
 		//		The results of the query, extended with iterative methods.
 		//
 		// example:
@@ -109,7 +108,7 @@ var Store = declare("dojo.store.api.Store", null, {
 		//		Note that a store user might not call transaction() prior to using put,
 		//		delete, etc. in which case these operations effectively could be thought of
 		//		as "auto-commit" style actions.
-		// returns: dojo.store.api.Store.Transaction
+		// returns: dojo/store/api/Store.Transaction
 		//		This represents the new current transaction.
 	},
 	getChildren: function(parent, options){
@@ -117,9 +116,9 @@ var Store = declare("dojo.store.api.Store", null, {
 		//		Retrieves the children of an object.
 		// parent: Object
 		//		The object to find the children of.
-		// options: dojo.store.api.Store.QueryOptions?
+		// options: dojo/store/api/Store.QueryOptions?
 		//		Additional options to apply to the retrieval of the children.
-		// returns: dojo.store.api.Store.QueryResults
+		// returns: dojo/store/api/Store.QueryResults
 		//		A result set of the children of the parent object.
 	},
 	getMetadata: function(object){
@@ -133,7 +132,7 @@ var Store = declare("dojo.store.api.Store", null, {
 	}
 });
 
-Store.PutDirectives = function(id, before, parent, overwrite){
+Store.PutDirectives = declare(null, {
 	// summary:
 	//		Directives passed to put() and add() handlers for guiding the update and
 	//		creation of stored objects.
@@ -154,27 +153,21 @@ Store.PutDirectives = function(id, before, parent, overwrite){
 	//		value of false indicates that an existing object should not be updated, a new
 	//		object should be created (which is the same as an add() operation). When
 	//		this property is not provided, either an update or creation is acceptable.
-	this.id = id;
-	this.before = before;
-	this.parent = parent;
-	this.overwrite = overwrite;
-};
+});
 
-Store.SortInformation = function(attribute, descending){
+Store.SortInformation = declare(null, {
 	// summary:
 	//		An object describing what attribute to sort on, and the direction of the sort.
 	// attribute: String
 	//		The name of the attribute to sort on.
 	// descending: Boolean
 	//		The direction of the sort.  Default is false.
-	this.attribute = attribute;
-	this.descending = descending;
-};
+});
 
-Store.QueryOptions = function(sort, start, count){
+Store.QueryOptions = declare(null, {
 	// summary:
 	//		Optional object with additional parameters for query results.
-	// sort: dojo.store.api.Store.SortInformation[]?
+	// sort: dojo/store/api/Store.SortInformation[]?
 	//		A list of attributes to sort on, as well as direction
 	//		For example:
 	//		| [{attribute:"price, descending: true}].
@@ -184,12 +177,9 @@ Store.QueryOptions = function(sort, start, count){
 	//		The first result to begin iteration on
 	// count: Number?
 	//		The number of how many results should be returned.
-	this.sort = sort;
-	this.start = start;
-	this.count = count;
-};
+});
 
-declare("dojo.store.api.Store.QueryResults", null, {
+Store.QueryResults = declare(null, {
 	// summary:
 	//		This is an object returned from query() calls that provides access to the results
 	//		of a query. Queries may be executed asynchronously.
@@ -216,7 +206,7 @@ declare("dojo.store.api.Store.QueryResults", null, {
 		//		Function that is called for each object in the query results
 		// thisObject:
 		//		The object to use as |this| in the callback.
-		// returns: dojo.store.api.Store.QueryResults
+		// returns: dojo/store/api/Store.QueryResults
 	},
 	map: function(callback, thisObject){
 		// summary:
@@ -228,7 +218,7 @@ declare("dojo.store.api.Store.QueryResults", null, {
 		//		Function that is called for each object in the query results
 		// thisObject:
 		//		The object to use as |this| in the callback.
-		// returns: dojo.store.api.Store.QueryResults
+		// returns: dojo/store/api/Store.QueryResults
 	},
 	then: function(callback, errorHandler){
 		// summary:
@@ -244,18 +234,18 @@ declare("dojo.store.api.Store.QueryResults", null, {
 	observe: function(listener, includeAllUpdates){
 		// summary:
 		//		This registers a callback for notification of when data is modified in the query results.
-		//		This is an optional method, and is usually provided by dojo.store.Observable.
+		//		This is an optional method, and is usually provided by dojo/store/Observable.
 		// listener: Function
 		//		The listener function is called when objects in the query results are modified
-		//		to affect the query result. The listener function is called with the following
-		// arguments:
+		//		to affect the query result. The listener function is called with the following arguments:
 		//		| listener(object, removedFrom, insertedInto);
-		//		* The object parameter indicates the object that was create, modified, or deleted.
-		//		* The removedFrom parameter indicates the index in the result array where
+		//
+		//		- The object parameter indicates the object that was create, modified, or deleted.
+		//		- The removedFrom parameter indicates the index in the result array where
 		//		the object used to be. If the value is -1, then the object is an addition to
 		//		this result set (due to a new object being created, or changed such that it
 		//		is a part of the result set).
-		//		* The insertedInto parameter indicates the index in the result array where
+		//		- The insertedInto parameter indicates the index in the result array where
 		//		the object should be now. If the value is -1, then the object is a removal
 		//		from this result set (due to an object being deleted, or changed such that it
 		//		is not a part of the result set).
@@ -275,7 +265,7 @@ declare("dojo.store.api.Store.QueryResults", null, {
 	total: 0
 });
 
-declare("dojo.store.api.Store.Transaction", null, {
+Store.Transaction = declare(null, {
 	// summary:
 	//		This is an object returned from transaction() calls that represents the current
 	//		transaction.
diff --git a/dojo/store/util/QueryResults.js b/dojo/store/util/QueryResults.js
index f1ee949..7b390a6 100644
--- a/dojo/store/util/QueryResults.js
+++ b/dojo/store/util/QueryResults.js
@@ -1,17 +1,13 @@
-define(["../../_base/array", "../../_base/lang", "../../_base/Deferred"
-], function(array, lang, Deferred) {
-  //  module:
-  //    dojo/store/util/QueryResults
-  //  summary:
-  //    The module defines a query results wrapper
+define(["../../_base/array", "../../_base/lang", "../../when"
+], function(array, lang, when){
 
-var util = lang.getObject("dojo.store.util", true);
+// module:
+//		dojo/store/util/QueryResults
 
-util.QueryResults = function(results){
+var QueryResults = function(results){
 	// summary:
 	//		A function that wraps the results of a store query with additional
 	//		methods.
-	//
 	// description:
 	//		QueryResults is a basic wrapper that allows for array-like iteration
 	//		over any kind of returned data from a query.  While the simplest store
@@ -20,10 +16,10 @@ util.QueryResults = function(results){
 	//		the same.
 	//
 	//		Additional methods include `forEach`, `filter` and `map`.
-	//
-	// returns: Object
+	// results: Array|dojo/promise/Promise
+	//		The result set as an array, or a promise for an array.
+	// returns:
 	//		An array-like object that can be used for iterating over.
-	//
 	// example:
 	//		Query a store and iterate over the results.
 	//
@@ -42,9 +38,9 @@ util.QueryResults = function(results){
 		if(!results[method]){
 			results[method] = function(){
 				var args = arguments;
-				return Deferred.when(results, function(results){
+				return when(results, function(results){
 					Array.prototype.unshift.call(args, results);
-					return util.QueryResults(array[method].apply(array, args));
+					return QueryResults(array[method].apply(array, args));
 				});
 			};
 		}
@@ -53,12 +49,15 @@ util.QueryResults = function(results){
 	addIterativeMethod("filter");
 	addIterativeMethod("map");
 	if(!results.total){
-		results.total = Deferred.when(results, function(results){
+		results.total = when(results, function(results){
 			return results.length;
 		});
 	}
-	return results;
+	return results; // Object
 };
 
-return util.QueryResults;
+lang.setObject("dojo.store.util.QueryResults", QueryResults);
+
+return QueryResults;
+
 });
diff --git a/dojo/store/util/SimpleQueryEngine.js b/dojo/store/util/SimpleQueryEngine.js
index 2b1c262..57d67b4 100644
--- a/dojo/store/util/SimpleQueryEngine.js
+++ b/dojo/store/util/SimpleQueryEngine.js
@@ -1,8 +1,7 @@
-define(["../../_base/array"], function(arrayUtil) {
-  //  module:
-  //    dojo/store/util/SimpleQueryEngine
-  //  summary:
-  //    The module defines a simple filtering query engine for object stores. 
+define(["../../_base/array" /*=====, "../api/Store" =====*/], function(arrayUtil /*=====, Store =====*/){
+
+// module:
+//		dojo/store/util/SimpleQueryEngine
 
 return function(query, options){
 	// summary:
@@ -26,10 +25,10 @@ return function(query, options){
 	//		An object hash with fields that may match fields of items in the store.
 	//		Values in the hash will be compared by normal == operator, but regular expressions
 	//		or any object that provides a test() method are also supported and can be
-	// 		used to match strings by more complex expressions
-	// 		(and then the regex's or object's test() method will be used to match values).
+	//		used to match strings by more complex expressions
+	//		(and then the regex's or object's test() method will be used to match values).
 	//
-	// options: dojo.store.util.SimpleQueryEngine.__queryOptions?
+	// options: dojo/store/api/Store.QueryOptions?
 	//		An object that contains optional information such as sort, start, and count.
 	//
 	// returns: Function
@@ -41,10 +40,10 @@ return function(query, options){
 	//
 	//	|	var myStore = function(options){
 	//	|		//	...more properties here
-	//	|		this.queryEngine = dojo.store.util.SimpleQueryEngine;
+	//	|		this.queryEngine = SimpleQueryEngine;
 	//	|		//	define our query method
 	//	|		this.query = function(query, options){
-	//	|			return dojo.store.util.QueryResults(this.queryEngine(query, options)(this.data));
+	//	|			return QueryResults(this.queryEngine(query, options)(this.data));
 	//	|		};
 	//	|	};
 
@@ -58,7 +57,8 @@ return function(query, options){
 				for(var key in queryObject){
 					var required = queryObject[key];
 					if(required && required.test){
-						if(!required.test(object[key])){
+						// an object can provide a test method, which makes it work with regex
+						if(!required.test(object[key], object)){
 							return false;
 						}
 					}else if(required != object[key]){
@@ -82,13 +82,14 @@ return function(query, options){
 		// execute the whole query, first we filter
 		var results = arrayUtil.filter(array, query);
 		// next we sort
-		if(options && options.sort){
-			results.sort(function(a, b){
-				for(var sort, i=0; sort = options.sort[i]; i++){
+		var sortSet = options && options.sort;
+		if(sortSet){
+			results.sort(typeof sortSet == "function" ? sortSet : function(a, b){
+				for(var sort, i=0; sort = sortSet[i]; i++){
 					var aValue = a[sort.attribute];
 					var bValue = b[sort.attribute];
-					if (aValue != bValue) {
-						return !!sort.descending == aValue > bValue ? -1 : 1;
+					if (aValue != bValue){
+						return !!sort.descending == (aValue == null || aValue > bValue) ? -1 : 1;
 					}
 				}
 				return 0;
@@ -105,4 +106,5 @@ return function(query, options){
 	execute.matches = query;
 	return execute;
 };
+
 });
diff --git a/dojo/string.js b/dojo/string.js
index 767c122..7784a78 100644
--- a/dojo/string.js
+++ b/dojo/string.js
@@ -1,18 +1,18 @@
-define(["./_base/kernel", "./_base/lang"], function(dojo, lang) {
-	// module:
-	//		dojo/string
-	// summary:
-	//		TODOC
+define([
+	"./_base/kernel",	// kernel.global
+	"./_base/lang"
+], function(kernel, lang){
 
-lang.getObject("string", true, dojo);
+// module:
+//		dojo/string
 
-/*=====
-dojo.string = {
-	// summary: String utilities for Dojo
+var string = {
+	// summary:
+	//		String utilities for Dojo
 };
-=====*/
+lang.setObject("dojo.string", string);
 
-dojo.string.rep = function(/*String*/str, /*Integer*/num){
+string.rep = function(/*String*/str, /*Integer*/num){
 	// summary:
 	//		Efficiently replicate a string `n` times.
 	// str:
@@ -33,7 +33,7 @@ dojo.string.rep = function(/*String*/str, /*Integer*/num){
 	return buf.join("");	// String
 };
 
-dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boolean?*/end){
+string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boolean?*/end){
 	// summary:
 	//		Pad a string to guarantee that it is at least `size` length by
 	//		filling with the character `ch` at either the start or end of the
@@ -48,17 +48,17 @@ dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boo
 	//		adds padding at the end if true, otherwise pads at start
 	// example:
 	//	|	// Fill the string to length 10 with "+" characters on the right.  Yields "Dojo++++++".
-	//	|	dojo.string.pad("Dojo", 10, "+", true);
+	//	|	string.pad("Dojo", 10, "+", true);
 
 	if(!ch){
 		ch = '0';
 	}
 	var out = String(text),
-		pad = dojo.string.rep(ch, Math.ceil((size - out.length) / ch.length));
+		pad = string.rep(ch, Math.ceil((size - out.length) / ch.length));
 	return end ? out + pad : pad + out;	// String
 };
 
-dojo.string.substitute = function(	/*String*/		template,
+string.substitute = function(	/*String*/		template,
 									/*Object|Array*/map,
 									/*Function?*/	transform,
 									/*Object?*/		thisObject){
@@ -80,7 +80,7 @@ dojo.string.substitute = function(	/*String*/		template,
 	//		Substitutes two expressions in a string from an Array or Object
 	//	|	// returns "File 'foo.html' is not found in directory '/temp'."
 	//	|	// by providing substitution data in an Array
-	//	|	dojo.string.substitute(
+	//	|	string.substitute(
 	//	|		"File '${0}' is not found in directory '${1}'.",
 	//	|		["foo.html","/temp"]
 	//	|	);
@@ -88,14 +88,14 @@ dojo.string.substitute = function(	/*String*/		template,
 	//	|	// also returns "File 'foo.html' is not found in directory '/temp'."
 	//	|	// but provides substitution data in an Object structure.  Dotted
 	//	|	// notation may be used to traverse the structure.
-	//	|	dojo.string.substitute(
+	//	|	string.substitute(
 	//	|		"File '${name}' is not found in directory '${info.dir}'.",
 	//	|		{ name: "foo.html", info: { dir: "/temp" } }
 	//	|	);
 	// example:
 	//		Use a transform function to modify the values:
 	//	|	// returns "file 'foo.html' is not found in directory '/temp'."
-	//	|	dojo.string.substitute(
+	//	|	string.substitute(
 	//	|		"${0} is not found in ${1}.",
 	//	|		["foo.html","/temp"],
 	//	|		function(str){
@@ -107,7 +107,7 @@ dojo.string.substitute = function(	/*String*/		template,
 	// example:
 	//		Use a formatter
 	//	|	// returns "thinger -- howdy"
-	//	|	dojo.string.substitute(
+	//	|	string.substitute(
 	//	|		"${0:postfix}", ["thinger"], null, {
 	//	|			postfix: function(value, key){
 	//	|				return value + " -- howdy";
@@ -115,7 +115,7 @@ dojo.string.substitute = function(	/*String*/		template,
 	//	|		}
 	//	|	);
 
-	thisObject = thisObject || dojo.global;
+	thisObject = thisObject || kernel.global;
 	transform = transform ?
 		lang.hitch(thisObject, transform) : function(v){ return v; };
 
@@ -129,23 +129,7 @@ dojo.string.substitute = function(	/*String*/		template,
 		}); // String
 };
 
-/*=====
-dojo.string.trim = function(str){
-	// summary:
-	//		Trims whitespace from both sides of the string
-	// str: String
-	//		String to be trimmed
-	// returns: String
-	//		Returns the trimmed string
-	// description:
-	//		This version of trim() was taken from [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript).
-	//		The short yet performant version of this function is dojo.trim(),
-	//		which is part of Dojo base.  Uses String.prototype.trim instead, if available.
-	return "";	// String
-}
-=====*/
-
-dojo.string.trim = String.prototype.trim ?
+string.trim = String.prototype.trim ?
 	lang.trim : // aliasing to the native function
 	function(str){
 		str = str.replace(/^\s+/, '');
@@ -158,5 +142,21 @@ dojo.string.trim = String.prototype.trim ?
 		return str;
 	};
 
-return dojo.string;
+/*=====
+ string.trim = function(str){
+	 // summary:
+	 //		Trims whitespace from both sides of the string
+	 // str: String
+	 //		String to be trimmed
+	 // returns: String
+	 //		Returns the trimmed string
+	 // description:
+	 //		This version of trim() was taken from [Steven Levithan's blog](http://blog.stevenlevithan.com/archives/faster-trim-javascript).
+	 //		The short yet performant version of this function is dojo.trim(),
+	 //		which is part of Dojo base.  Uses String.prototype.trim instead, if available.
+	 return "";	// String
+ };
+ =====*/
+
+	return string;
 });
diff --git a/dojo/tests.js b/dojo/tests.js
index 04d192a..0c68beb 100644
--- a/dojo/tests.js
+++ b/dojo/tests.js
@@ -3,7 +3,8 @@
 
 /*=====
 dojo.tests = {
-	// summary: D.O.H. Test files for Dojo unit testing.
+	// summary:
+	//		D.O.H. Test files for Dojo unit testing.
 };
 =====*/
 
diff --git a/dojo/tests/AdapterRegistry.js b/dojo/tests/AdapterRegistry.js
index e8c3c28..953d62e 100644
--- a/dojo/tests/AdapterRegistry.js
+++ b/dojo/tests/AdapterRegistry.js
@@ -1,18 +1,18 @@
-define(["../main", "doh", "../AdapterRegistry"], function(dojo, doh){
+define(["doh/main", "../AdapterRegistry"], function(doh, AdapterRegistry){
 
 doh.register("tests.AdapterRegistry",
 	[
 		function ctor(t){
-			var taa = new dojo.AdapterRegistry();
+			var taa = new AdapterRegistry();
 			t.is(0, taa.pairs.length);
 			t.f(taa.returnWrappers);
 
-			var taa = new dojo.AdapterRegistry(true);
+			var taa = new AdapterRegistry(true);
 			t.t(taa.returnWrappers);
 		},
 
 		function register(t){
-			var taa = new dojo.AdapterRegistry();
+			var taa = new AdapterRegistry();
 			taa.register("blah",
 				function(str){ return str == "blah"; },
 				function(){ return "blah"; }
@@ -32,7 +32,7 @@ doh.register("tests.AdapterRegistry",
 		*/
 
 		function noMatch(t){
-			var taa = new dojo.AdapterRegistry();
+			var taa = new AdapterRegistry();
 			var threw = false;
 			try{
 				taa.match("blah");
@@ -43,7 +43,7 @@ doh.register("tests.AdapterRegistry",
 		},
 
 		function returnWrappers(t){
-			var taa = new dojo.AdapterRegistry();
+			var taa = new AdapterRegistry();
 			taa.register("blah",
 				function(str){ return str == "blah"; },
 				function(){ return "blah"; }
@@ -55,7 +55,7 @@ doh.register("tests.AdapterRegistry",
 		},
 
 		function unregister(t){
-			var taa = new dojo.AdapterRegistry();
+			var taa = new AdapterRegistry();
 			taa.register("blah",
 				function(str){ return str == "blah"; },
 				function(){ return "blah"; }
diff --git a/dojo/tests/Deferred.js b/dojo/tests/Deferred.js
new file mode 100644
index 0000000..d1b8c31
--- /dev/null
+++ b/dojo/tests/Deferred.js
@@ -0,0 +1,477 @@
+define([
+	"doh/main",
+	"dojo/Deferred",
+	"dojo/promise/Promise",
+	"dojo/errors/CancelError"
+], function(doh, Deferred, Promise, CancelError){
+	var tests = {
+		"deferred receives result after resolving": function(t){
+			var obj = {};
+			var received;
+			this.deferred.then(function(result){ received = result; });
+			this.deferred.resolve(obj);
+			t.t(received === obj);
+		},
+
+		"promise receives result after resolving": function(t){
+			var obj = {};
+			var received;
+			this.deferred.promise.then(function(result){ received = obj; });
+			this.deferred.resolve(obj);
+			t.t(received === obj);
+		},
+
+		"resolve() returns promise": function(t){
+			var obj = {};
+			var returnedPromise = this.deferred.resolve(obj);
+			t.t(returnedPromise instanceof Promise);
+			t.t(returnedPromise === this.deferred.promise);
+		},
+
+		"isResolved() returns true after resolving": function(t){
+			t.f(this.deferred.isResolved());
+			this.deferred.resolve();
+			t.t(this.deferred.isResolved());
+		},
+
+		"isFulfilled() returns true after resolving": function(t){
+			t.f(this.deferred.isFulfilled());
+			this.deferred.resolve();
+			t.t(this.deferred.isFulfilled());
+		},
+
+		"resolve() is ignored after having been fulfilled": function(t){
+			this.deferred.resolve();
+			this.deferred.resolve();
+		},
+
+		"resolve() throws error after having been fulfilled and strict": function(t){
+			this.deferred.resolve();
+			t.e(Error, this.deferred, "resolve", [{}, true]);
+		},
+
+		"resolve() results are cached": function(t){
+			var obj = {};
+			var received;
+			this.deferred.resolve(obj);
+			this.deferred.then(function(result){ received = result; });
+			t.t(received === obj);
+		},
+
+		"resolve() is already bound to the deferred": function(t){
+			var obj = {};
+			var received;
+			this.deferred.then(function(result){ received = result; });
+			var resolve = this.deferred.resolve;
+			resolve(obj);
+			t.t(received === obj);
+		},
+
+		"deferred receives result after rejecting": function(t){
+			var obj = {};
+			var received;
+			this.deferred.then(null, function(result){ received = result; });
+			this.deferred.reject(obj);
+			t.t(received === obj);
+		},
+
+		"promise receives result after rejecting": function(t){
+			var obj = {};
+			var received;
+			this.deferred.promise.then(null, function(result){ received = result; });
+			this.deferred.reject(obj);
+			t.t(received === obj);
+		},
+
+		"reject() returns promise": function(t){
+			var obj = {};
+			var returnedPromise = this.deferred.reject(obj);
+			t.t(returnedPromise instanceof Promise);
+			t.t(returnedPromise === this.deferred.promise);
+		},
+
+		"isRejected() returns true after rejecting": function(t){
+			t.f(this.deferred.isRejected());
+			this.deferred.reject();
+			t.t(this.deferred.isRejected());
+		},
+
+		"isFulfilled() returns true after rejecting": function(t){
+			t.f(this.deferred.isFulfilled());
+			this.deferred.reject();
+			t.t(this.deferred.isFulfilled());
+		},
+
+		"reject() is ignored after having been fulfilled": function(t){
+			this.deferred.reject();
+			this.deferred.reject();
+		},
+
+		"reject() throws error after having been fulfilled and strict": function(t){
+			this.deferred.reject();
+			t.e(Error, this.deferred, "reject", [{}, true]);
+		},
+
+		"reject() results are cached": function(t){
+			var obj = {};
+			var received;
+			this.deferred.reject(obj);
+			this.deferred.then(null, function(result){ received = result; });
+			t.t(received === obj);
+		},
+
+		"reject() is already bound to the deferred": function(t){
+			var obj = {};
+			var received;
+			this.deferred.then(null, function(result){ received = result; });
+			var reject = this.deferred.reject;
+			reject(obj);
+			t.t(received === obj);
+		},
+
+		"deferred receives result after progress": function(t){
+			var obj = {};
+			var received;
+			this.deferred.then(null, null, function(result){ received = result; });
+			this.deferred.progress(obj);
+			t.t(received === obj);
+		},
+
+		"promise receives result after progres": function(t){
+			var obj = {};
+			var received;
+			this.deferred.promise.then(null, null, function(result){ received = result; });
+			this.deferred.progress(obj);
+			t.t(received === obj);
+		},
+
+		"progress() returns promise": function(t){
+			var obj = {};
+			var returnedPromise = this.deferred.progress(obj);
+			t.t(returnedPromise instanceof Promise);
+			t.t(returnedPromise === this.deferred.promise);
+		},
+
+		"isResolved() returns false after progress": function(t){
+			t.f(this.deferred.isResolved());
+			this.deferred.progress();
+			t.f(this.deferred.isResolved());
+		},
+
+		"isRejected() returns false after progress": function(t){
+			t.f(this.deferred.isRejected());
+			this.deferred.progress();
+			t.f(this.deferred.isRejected());
+		},
+
+		"isFulfilled() returns false after progress": function(t){
+			t.f(this.deferred.isFulfilled());
+			this.deferred.progress();
+			t.f(this.deferred.isFulfilled());
+		},
+
+		"progress() is ignored after having been fulfilled": function(t){
+			this.deferred.resolve();
+			this.deferred.resolve();
+		},
+
+		"progress() throws error after having been fulfilled and strict": function(t){
+			this.deferred.resolve();
+			t.e(Error, this.deferred, "progress", [{}, true]);
+		},
+
+		"progress() results are not cached": function(t){
+			var obj1 = {}, obj2 = {};
+			var received = [];
+			this.deferred.progress(obj1);
+			this.deferred.then(null, null, function(result){ received.push(result); });
+			this.deferred.progress(obj2);
+			t.t(received[0] === obj2);
+			t.is(1, received.length);
+		},
+
+		"progress() with chaining": function(t){
+			var obj = {};
+			var inner = new Deferred();
+			var received;
+			this.deferred.then(function(){ return inner; }).then(null, null, function(result){ received = result; });
+			this.deferred.resolve();
+			inner.progress(obj);
+			t.t(received === obj);
+		},
+
+		"after progress(), the progback return value is emitted on the returned promise": function(t){
+			var received;
+			var promise = this.deferred.then(null, null, function(n){ return n * n; });
+			promise.then(null, null, function(n){ received = n; });
+			this.deferred.progress(2);
+			t.is(4, received);
+		},
+
+		"progress() is already bound to the deferred": function(t){
+			var obj = {};
+			var received;
+			this.deferred.then(null, null, function(result){ received = result; });
+			var progress = this.deferred.progress;
+			progress(obj);
+			t.t(received === obj);
+		},
+
+		"cancel() invokes a canceler": function(t){
+			var invoked;
+			this.canceler = function(){ invoked = true; };
+			this.deferred.cancel();
+			t.t(invoked);
+		},
+
+		"isCanceled() returns true after canceling": function(t){
+			t.f(this.deferred.isCanceled());
+			this.deferred.cancel();
+			t.t(this.deferred.isCanceled());
+		},
+
+		"isResolved() returns false after canceling": function(t){
+			t.f(this.deferred.isResolved());
+			this.deferred.cancel();
+			t.f(this.deferred.isResolved());
+		},
+
+		"isRejected() returns true after canceling": function(t){
+			t.f(this.deferred.isRejected());
+			this.deferred.cancel();
+			t.t(this.deferred.isRejected());
+		},
+
+		"isFulfilled() returns true after canceling": function(t){
+			t.f(this.deferred.isFulfilled());
+			this.deferred.cancel();
+			t.t(this.deferred.isFulfilled());
+		},
+
+		"cancel() is ignored after having been fulfilled": function(t){
+			var canceled = false;
+			this.canceler = function(){ canceled = true; };
+			this.deferred.resolve();
+			this.deferred.cancel();
+			t.f(canceled);
+		},
+
+		"cancel() throws error after having been fulfilled and strict": function(t){
+			this.deferred.resolve();
+			t.e(Error, this.deferred, "cancel", [null, true]);
+		},
+
+		"cancel() without reason results in CancelError": function(t){
+			var reason = this.deferred.cancel();
+			var received;
+			this.deferred.then(null, function(result){ received = result; });
+			t.t(received, reason);
+		},
+
+		"cancel() returns default reason": function(t){
+			var reason = this.deferred.cancel();
+			t.t(reason instanceof CancelError);
+		},
+
+		"reason is passed to canceler": function(t){
+			var obj = {};
+			var received;
+			this.canceler = function(reason){ received = reason; };
+			this.deferred.cancel(obj);
+			t.t(received === obj);
+		},
+
+		"cancels with reason returned from canceler": function(t){
+			var obj = {};
+			var received;
+			this.canceler = function(){ return obj; };
+			var reason = this.deferred.cancel();
+			this.deferred.then(null, function(reason){ received = reason; });
+			t.t(received === obj);
+		},
+
+		"cancel() returns reason from canceler": function(t){
+			var obj = {};
+			this.canceler = function(){ return obj; };
+			var reason = this.deferred.cancel();
+			t.t(reason === obj);
+		},
+
+		"cancel() returns reason from canceler, if canceler rejects with reason": function(t){
+			var obj = {};
+			var deferred = this.deferred;
+			this.canceler = function(){ deferred.reject(obj); return obj; };
+			var reason = this.deferred.cancel();
+			t.t(reason === obj);
+		},
+
+		"with canceler not returning anything, returns default CancelError": function(t){
+			this.canceler = function(){};
+			var reason = this.deferred.cancel();
+			var received;
+			this.deferred.then(null, function(result){ received = result; });
+			t.t(received === reason);
+		},
+
+		"with canceler not returning anything, still returns passed reason": function(t){
+			var obj = {};
+			var received;
+			this.canceler = function(){};
+			var reason = this.deferred.cancel(obj);
+			t.t(reason === obj);
+			this.deferred.then(null, function(result){ received = result; });
+			t.t(received === reason);
+		},
+
+		"cancel() doesn't reject promise if canceler resolves deferred": function(t){
+			var deferred = this.deferred;
+			var obj = {};
+			var received;
+			this.canceler = function(){ deferred.resolve(obj); };
+			this.deferred.cancel();
+			this.deferred.then(function(result){ received = result; });
+			t.t(received === obj);
+		},
+
+		"cancel() doesn't reject promise if canceler resolves a chain of promises": function(t){
+			var deferred = this.deferred;
+			var obj = {};
+			var received;
+			this.canceler = function(){ deferred.resolve(obj); };
+			var last = this.deferred.then().then().then();
+			last.cancel();
+			last.then(function(result){ received = result; });
+			t.t(received === obj);
+			t.t(this.deferred.isCanceled());
+			t.t(last.isCanceled());
+		},
+
+		"cancel() returns undefined if canceler resolves deferred": function(t){
+			var deferred = this.deferred;
+			var obj = {};
+			this.canceler = function(){ deferred.resolve(obj); };
+			var result = this.deferred.cancel();
+			t.t(typeof result === "undefined");
+		},
+
+		"cancel() doesn't change rejection value if canceler rejects deferred": function(t){
+			var deferred = this.deferred;
+			var obj = {};
+			var received;
+			this.canceler = function(){ deferred.reject(obj); };
+			this.deferred.cancel();
+			this.deferred.then(null, function(result){ received = result; });
+			t.t(received === obj);
+		},
+
+		"cancel() doesn't change rejection value if canceler rejects a chain of promises": function(t){
+			var deferred = this.deferred;
+			var obj = {};
+			var received;
+			this.canceler = function(){ deferred.reject(obj); };
+			var last = this.deferred.then().then().then();
+			last.cancel();
+			last.then(null, function(result){ received = result; });
+			t.t(received === obj);
+			t.t(this.deferred.isCanceled());
+			t.t(last.isCanceled());
+		},
+
+		"cancel() returns undefined if canceler rejects deferred": function(t){
+			var deferred = this.deferred;
+			var obj = {};
+			this.canceler = function(){ deferred.reject(obj); };
+			var result = this.deferred.cancel();
+			t.t(typeof result === "undefined");
+		},
+
+		"cancel() a promise chain": function(t){
+			var obj = {};
+			var received;
+			this.canceler = function(reason){ received = reason; };
+			this.deferred.then().then().then().cancel(obj);
+			t.t(received === obj);
+		},
+
+		"cancel() a returned promise": function(t){
+			var obj = {};
+			var received;
+			var inner = new Deferred(function(reason){ received = reason; });
+			var chain = this.deferred.then(function(){
+				return inner;
+			});
+			this.deferred.resolve();
+			chain.cancel(obj, true);
+			t.t(received === obj);
+		},
+
+		"cancel() is already bound to the deferred": function(t){
+			var received;
+			this.deferred.then(null, function(result){ received = result; });
+			var cancel = this.deferred.cancel;
+			cancel();
+			t.t(received instanceof CancelError);
+		},
+
+		"chained then()": function(t){
+			function square(n){ return n * n; }
+
+			var result;
+			this.deferred.then(square).then(square).then(function(n){
+				result = n;
+			});
+			this.deferred.resolve(2);
+			t.is(result, 16);
+		},
+
+		"asynchronously chained then()": function(t){
+			function asyncSquare(n){
+				var inner = new Deferred();
+				setTimeout(function(){ inner.resolve(n * n); }, 0);
+				return inner.promise;
+			}
+
+			var td = new doh.Deferred();
+			this.deferred.then(asyncSquare).then(asyncSquare).then(function(n){
+				t.is(n, 16);
+				td.callback(true);
+			});
+			this.deferred.resolve(2);
+			return td;
+		},
+
+		"then() is already bound to the deferred": function(t){
+			var obj = {};
+			var then = this.deferred.then;
+			var received;
+			then(function(result){ received = result; });
+			this.deferred.resolve(obj);
+			t.t(received === obj);
+		},
+
+		"then() with progback: returned promise is not fulfilled when progress is emitted": function(t){
+			var progressed = false;
+			var promise = this.deferred.then(null, null, function(){ progressed = true; });
+			this.deferred.progress();
+			t.t(progressed, "Progress was received.");
+			t.f(promise.isFulfilled(), "Promise is not fulfilled.");
+		}
+	};
+
+	var wrapped = [];
+	for(var name in tests){
+		wrapped.push({
+			name: name,
+			setUp: setUp,
+			runTest: tests[name]
+		});
+	}
+
+	function setUp(){
+		var self = this;
+		this.canceler = function(reason){};
+		this.deferred = new Deferred(function(reason){ return self.canceler(reason); });
+	}
+
+	doh.register("tests.Deferred", wrapped);
+});
diff --git a/dojo/tests/DeferredList.js b/dojo/tests/DeferredList.js
index f14d0f4..4458aa7 100644
--- a/dojo/tests/DeferredList.js
+++ b/dojo/tests/DeferredList.js
@@ -1,4 +1,4 @@
-define(["../main", "doh", "../DeferredList"], function(dojo, doh){
+define(["../main", "doh/main", "../DeferredList"], function(dojo, doh){
 	doh.register("tests.DeferredList", [
 		function callback(t){
 			var d1 = new dojo.Deferred();
diff --git a/dojo/tests/NodeList-data.html b/dojo/tests/NodeList-data.html
index ea652f4..3acde01 100644
--- a/dojo/tests/NodeList-data.html
+++ b/dojo/tests/NodeList-data.html
@@ -5,8 +5,8 @@
 		<title>Testing dojo._data / NodeList.data</title>
 		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/NodeList-data", "dojo/domReady!"], function(dojo, doh){
-				var $ = dojo.query;
+			require(["doh", "dojo/dom-construct", "dojo/query", "dojo/NodeList-data", "dojo/domReady!"],
+					function(doh, domConstruct, $, NodeList){
 				var len = function(obj){
 					var x = 0;
 					for(var i in obj){ x++ }
@@ -83,24 +83,24 @@
 					},
 
 					function plaindata(t){
-						dojo.query("#bar li").data("bar", 42)
+						$("#bar li").data("bar", 42)
 							.forEach(function(n){
 								t.is(42, dojo._nodeData(n, "bar"));
 							});
 					},
 
 					function removeData(t){
-						dojo.query("#bar li").removeData("bar");
-						dojo.query("#bar li").forEach(function(n){
+						$("#bar li").removeData("bar");
+						$("#bar li").forEach(function(n){
 							t.t(!dojo._nodeData(n, "bar"));
 						});
 
-						dojo.query("#bar li").data({
+						$("#bar li").data({
 							a:"b", c:"d", e:"f"
 						});
 
-						dojo.query("#bar li").removeData();
-						var data = dojo.query("#bar li").data()[0];
+						$("#bar li").removeData();
+						var data = $("#bar li").data()[0];
 
 						t.f(data.a);
 						t.f(data.c);
@@ -109,16 +109,16 @@
 
 					function multidata(t){
 
-						var ret = dojo.query("#bar li");
+						var ret = $("#bar li");
 						t.is(2, ret.length, "sanity: 2 (0..1) li's in query");
 						ret = ret.data("bar", "baz").data();
 
 						t.is(ret[0].bar, "baz", "item 0 was set");
 						t.is(ret[1].bar, "baz", "item 1 was set");
 
-						dojo.query("li").at(0).removeData();
+						$("li").at(0).removeData();
 
-						var ret2 = dojo.query("#bar li").data();
+						var ret2 = $("#bar li").data();
 						t.is(ret.length, 2, "sanity: 2 (0..1) li's in query");
 						t.f(ret2[0].bar, "at(0) was removed");
 						t.is(ret2[1].bar, "baz", "at(1) was untouched");
@@ -126,19 +126,19 @@
 					},
 
 					function obj(t){
-						var x = dojo.query("#foo").data({ bar: { baz:"bam" }}).data("bar");
+						var x = $("#foo").data({ bar: { baz:"bam" }}).data("bar");
 						t.is("bam", x[0].baz);
 
 					},
 
 					function cleanData(t){
 
-						if(!dojo._nodeDataCache){
-							t.t("We must be testing a built Dojo. No access to dataCache");
+						if(!NodeList._nodeDataCache){
+							doh.debug("We must be testing a built Dojo. No access to dataCache");
 							return;
 						}
 
-						var me = dojo.query("#bar li").data("die", "yes");
+						var me = $("#bar li").data("die", "yes");
 						me.at(0).attr("id", "killme");
 						var data = me.data();
 
@@ -146,13 +146,13 @@
 						t.is("yes", me.data("die")[0]);
 						t.is("yes", me.data("die")[1]);
 
-						var l = len(dojo._nodeDataCache);
+						var l = len(NodeList._nodeDataCache);
 
-						dojo.destroy("killme");
-						dojo._gcNodeData();
+						domConstruct.destroy("killme");
+						NodeList._gcNodeData();
 
-						t.is(l - 1, len(dojo._nodeDataCache), "one item removed because destroyed");
-						me = dojo.query("#bar li");
+						t.is(l - 1, len(NodeList._nodeDataCache), "one item removed because destroyed");
+						me = $("#bar li");
 						t.is(1, me.length);
 
 					},
@@ -162,30 +162,31 @@
 						// but doesn't mean you should use them.
 						var x = { a:1 };
 
-						var one = dojo.query("#lit span").data("literal", x);
+						var one = $("#lit span").data("literal", x);
 						x.a++;
 
-						t.is(2, dojo.query("#lit span").data("literal")[0].a);
-						t.is(2, dojo.query("#lit span").data("literal")[1].a);
+						t.is(2, $("#lit span").data("literal")[0].a);
+						t.is(2, $("#lit span").data("literal")[1].a);
 
 					},
 
 					function clearall(t){
 
-						if(!dojo._nodeDataCache){
-							t.t("We must be testing a built Dojo. No access to dataCache");
+						if(!NodeList._nodeDataCache){
+							doh.debug("We must be testing a built Dojo. No access to dataCache");
 							return;
 						}
 
-						var l = len(dojo._nodeDataCache);
+						var l = len(NodeList._nodeDataCache);
 						t.t(l, "there is stuff in the cache");
 
-						dojo.query("#b > *").forEach(dojo.destroy);
+						$("#b > *").forEach(domConstruct.destroy);
 						dojo._gcNodeData();
-						t.is(0, len(dojo._nodeDataCache), "no longer stuff in the cache");
+						t.is(0, len(NodeList._nodeDataCache), "no longer stuff in the cache");
 					}
 				]);
-				doh.runOnLoad();
+
+				doh.run();
 			});
 		</script>
 	</head>
diff --git a/dojo/tests/NodeList-data.js b/dojo/tests/NodeList-data.js
index 85061af..38ca319 100644
--- a/dojo/tests/NodeList-data.js
+++ b/dojo/tests/NodeList-data.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests.NodeList-data", require.toUrl("./NodeList-data.html"), 30000);
 	}
diff --git a/dojo/tests/NodeList-fx.html b/dojo/tests/NodeList-fx.html
index c8dc888..9d71f23 100644
--- a/dojo/tests/NodeList-fx.html
+++ b/dojo/tests/NodeList-fx.html
@@ -8,95 +8,96 @@
 		</style>
 		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug: true, popup: true"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/NodeList-fx", "dojo/domReady!"], function(dojo, doh){
+			require(["doh", "dojo/aspect", "dojo/dom-style", "dojo/query", "dojo/NodeList-fx", "dojo/domReady!"],
+					function(doh, aspect, domStyle, query){
 				doh.register("NodeList-fx", 
 					[
 						function fadeOut(){
-							dojo.query("p").style("opacity", 1);
-							var anim = dojo.query("p").fadeOut();
+							query("p").style("opacity", 1);
+							var anim = query("p").fadeOut();
 							var d = new doh.Deferred();
-							dojo.connect(anim, "onEnd", d.getTestCallback(function(){
-								dojo.query("p").forEach(function(item){ 
-									doh.is(0, dojo.style(item, "opacity"), "opacity for " + item);
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
+								query("p").forEach(function(item){ 
+									doh.is(0, domStyle.get(item, "opacity"), "opacity for " + item);
 								});
-							}));
+							}), true);
 							anim.play();
 							return d;
 						},
 						function fadeIn(){
-							dojo.query("p").style("opacity", 0);
-							var anim = dojo.query("p").fadeIn();
+							query("p").style("opacity", 0);
+							var anim = query("p").fadeIn();
 							var d = new doh.Deferred();
-							dojo.connect(anim, "onEnd", d.getTestCallback(function(){
-								dojo.query("p").forEach(function(item){ 
-									doh.is(1, dojo.style(item, "opacity"), "opacity for " + item);
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
+								query("p").forEach(function(item){ 
+									doh.is(1, domStyle.get(item, "opacity"), "opacity for " + item);
 								});
-							}));
+							}), true);
 							anim.play();
 							return d;
 						},
 						function wipeOut(){
-							dojo.query("p").style("height", "");
-							var anim = dojo.query("p").wipeOut();
+							query("p").style("height", "");
+							var anim = query("p").wipeOut();
 							var d = new doh.Deferred();
-							dojo.connect(anim, "onEnd", d.getTestCallback(function(){
-								dojo.query("p").forEach(function(item){ 
-									doh.is(0, dojo.style(item, "height"), "height for " + item);
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
+								query("p").forEach(function(item){ 
+									doh.is(0, domStyle.get(item, "height"), "height for " + item);
 								});
-							}));
+							}), true);
 							anim.play();
 							return d;
 						},
 						function wipeIn(){
-							dojo.query("p").style("height", 0);
-							var anim = dojo.query("p").wipeIn();
+							query("p").style("height", 0);
+							var anim = query("p").wipeIn();
 							var d = new doh.Deferred();
-							dojo.connect(anim, "onEnd", d.getTestCallback(function(){
-								dojo.query("p").forEach(function(item){ 
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
+								query("p").forEach(function(item){ 
 									// FIXME: need a more robust test for "have wiped all the way in"
-									doh.isNot(0, dojo.style(item, "height"), "height for " + item);
+									doh.isNot(0, domStyle.get(item, "height"), "height for " + item);
 								});
-							}));
+							}), true);
 							anim.play();
 							return d;
 						},
 						function slideTo(){
-							var anim = dojo.query("p").slideTo({
+							var anim = query("p").slideTo({
 								left: 500
 							});
 							var d = new doh.Deferred();
-							dojo.connect(anim, "onEnd", d.getTestCallback(function(){
-								dojo.query("p").forEach(function(item){ 
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
+								query("p").forEach(function(item){ 
 									// FIXME: need a more robust test for "have wiped all the way in"
-									doh.is(500, dojo.style(item, "left"), "left for " + item);
+									doh.is(500, domStyle.get(item, "left"), "left for " + item);
 								});
-							}));
+							}), true);
 							anim.play();
 							return d;
 						},
 						function anim(){
-							dojo.query("p").style("position", "");
-							dojo.query("p").style("left", "");
-							var anim = dojo.query("p").anim({
+							query("p").style("position", "");
+							query("p").style("left", "");
+							var anim = query("p").anim({
 								width: 500
 							});
 							console.debug(anim);
 							var d = new doh.Deferred();
-							dojo.connect(anim, "onEnd", d.getTestCallback(function(){
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
 								/*
-								dojo.query("p").forEach(function(item){ 
+								query("p").forEach(function(item){ 
 									// FIXME: need a more robust test for "have wiped all the way in"
-									doh.is(500, dojo.style(item, "width"), "width for" + item);
+									doh.is(500, domStyle.get(item, "width"), "width for" + item);
 								}));
 								*/
-							}));
+							}), true);
 							return d;
 						},
 						
 						function auto(){
 							
 							var d = new doh.Deferred(), x = 0;
-							var nl = dojo.query("p")
+							var nl = query("p")
 								.fadeOut({ 
 									auto:true,
 									onEnd:function(){
@@ -114,7 +115,7 @@
 								}))
 							;
 							
-							doh.t(nl.length, "dojo.query() found some nodes"); // ensure we actually will do _something_ 
+							doh.t(nl.length, "query() found some nodes"); // ensure we actually will do _something_ 
 							
 							return d;
 						}
diff --git a/dojo/tests/NodeList-manipulate.html b/dojo/tests/NodeList-manipulate.html
index b749c92..f1429f9 100644
--- a/dojo/tests/NodeList-manipulate.html
+++ b/dojo/tests/NodeList-manipulate.html
@@ -8,7 +8,10 @@
 		</style>
 		<script type="text/javascript" src="../dojo.js"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/NodeList-manipulate", "dojo/domReady!"], function(dojo, doh){
+			require([
+				"doh", "dojo/_base/array", "dojo/dom", "dojo/dom-construct",
+				"dojo/query", "dojo/NodeList-manipulate", "dojo/domReady!"
+			], function(doh, array, dom, domConstruct, query){
 
 				function verify(/*dojo.NodeList*/nl, /*Array*/ids){
 					for(var i = 0, node; node = nl[i]; i++){
@@ -18,22 +21,24 @@
 					doh.is(ids.length, i);
 				}
 
-				var divs = dojo.query("div.testDiv");
+				var divs = query("div.testDiv");
 
-				doh.register([
+				doh.register("NodeList-manipulate", [
 					function innerHTML(t){
 						divs.innerHTML("<ul><li>Test</li></ul>");
-						dojo.forEach(divs, function(node){
+						array.forEach(divs, function(node){
 							doh.is(1, node.childNodes.length);
 							doh.is("ul", node.childNodes[0].nodeName.toLowerCase());
 						});
 
 						doh.is("<ul><li>test</li></ul>", divs.innerHTML().toLowerCase().replace(/[\r\n]/g, ""));
+						divs.innerHTML("");
+						doh.is("", divs.innerHTML().toLowerCase().replace(/[\r\n]/g, ""));
 					},
 
 					function html(t){
 						divs.html("<ul><li>Test</li></ul>");
-						dojo.forEach(divs, function(node){
+						array.forEach(divs, function(node){
 							doh.is(1, node.childNodes.length);
 							doh.is("ul", node.childNodes[0].nodeName.toLowerCase());
 						});
@@ -46,7 +51,7 @@
 
 						divs.text("Hello World");
 
-						dojo.forEach(divs, function(node){
+						array.forEach(divs, function(node){
 							doh.is(1, node.childNodes.length);
 							doh.is("Hello World", node.childNodes[0].nodeValue);
 						});
@@ -56,29 +61,29 @@
 
 					function val(t){
 						//Input text test.
-						dojo.query('[type="text"]').val("Hello");
-						doh.is("Hello", dojo.byId("inputText").value);
+						query('[type="text"]').val("Hello");
+						doh.is("Hello", dom.byId("inputText").value);
 
 						//Textarea test.
-						dojo.query('textarea', "inputForm").val("World");
-						doh.is("World", dojo.byId("inputTextArea").value);
+						query('textarea', "inputForm").val("World");
+						doh.is("World", dom.byId("inputTextArea").value);
 
 						//Radio button test
-						dojo.query('[type="radio"]').val("radio2");
-						doh.f(dojo.byId("inputRadio1").checked);
-						doh.t(dojo.byId("inputRadio2").checked);
+						query('[type="radio"]').val("radio2");
+						doh.f(dom.byId("inputRadio1").checked);
+						doh.t(dom.byId("inputRadio2").checked);
 
 						//Checkbox test
-						dojo.query('[type="checkbox"]').val("checkbox2");
-						doh.f(dojo.byId("inputCheckBox1").checked);
-						doh.t(dojo.byId("inputCheckBox2").checked);
+						query('[type="checkbox"]').val("checkbox2");
+						doh.f(dom.byId("inputCheckBox1").checked);
+						doh.t(dom.byId("inputCheckBox2").checked);
 
-						var selects = dojo.query('select', 'inputForm');
+						var selects = query('select', 'inputForm');
 
 						//Single select test.
 						selects.at(0).val("two");
-						doh.is(1, dojo.byId("inputSelect1").selectedIndex);
-						dojo.query("option", "inputSelect1").forEach(function(node){
+						doh.is(1, dom.byId("inputSelect1").selectedIndex);
+						query("option", "inputSelect1").forEach(function(node){
 							if(node.value == "two"){
 								doh.t(node.selected);
 							}else{
@@ -88,7 +93,7 @@
 
 						//Multiple select test.
 						selects.at(1).val(["four", "six"]);
-						dojo.query("option", "inputSelect2").forEach(function(node){
+						query("option", "inputSelect2").forEach(function(node){
 							if(node.value == "four" || node.value == "six"){
 								doh.t(node.selected);
 							}else{
@@ -110,16 +115,16 @@
 						);
 
 						//Test DOMNode content
-						divs.append(dojo.query("h1")[0]).forEach(function(node){
+						divs.append(query("h1")[0]).forEach(function(node){
 							doh.is(4, node.childNodes.length);
 							doh.is("h1", node.childNodes[3].nodeName.toLowerCase());
 						});
 
-						var h1s = dojo.query("h1");
+						var h1s = query("h1");
 						doh.is(3, h1s.length);
 
 						//Move all the h1s to one div to test NodeList content.
-						dojo.query("#t, #yeah").append(document.getElementsByTagName("h1")).forEach(function(node){
+						query("#t, #yeah").append(document.getElementsByTagName("h1")).forEach(function(node){
 							doh.is(6, node.childNodes.length);
 							doh.is("h1", node.childNodes[3].nodeName.toLowerCase());
 							doh.is("h1", node.childNodes[4].nodeName.toLowerCase());
@@ -127,34 +132,34 @@
 						});
 
 						//clean up
-						dojo.query("h1").remove();
+						query("h1").remove();
 					},
 
 					function appendTo(t){
 						//Create some new things.
-						dojo.query("body").append('<p class="singer">bo</p><p class="singer">diddly</p>');
+						query("body").append('<p class="singer">bo</p><p class="singer">diddly</p>');
 
-						var ret = dojo.query(".foo").appendTo(".singer");
+						var ret = query(".foo").appendTo(".singer");
 						doh.is(6, ret.length);
 
-						dojo.query(".singer").forEach(function(node){
+						query(".singer").forEach(function(node){
 							doh.is(4, node.childNodes.length);
 							doh.is("foo", node.childNodes[1].className);
 							doh.is("foo", node.childNodes[2].className);
 							doh.is("foo", node.childNodes[3].className);
 						});
 
-						dojo.query("body").append('<p class="bands"></p><p class="drummer">john</p><p class="drummer">bonham</p>');
-						var bands = dojo.query(".bands");
-						dojo.query(".drummer").appendTo(bands);
+						query("body").append('<p class="bands"></p><p class="drummer">john</p><p class="drummer">bonham</p>');
+						var bands = query(".bands");
+						query(".drummer").appendTo(bands);
 						bands.forEach(function(node){
 							doh.is(2, node.childNodes.length);
 							doh.is("drummer", node.childNodes[0].className);
 							doh.is("drummer", node.childNodes[1].className);
 						});
 
-						dojo.query("body").append('<p class="guitarist">jimmy</p><p class="guitarist">page</p>');
-						dojo.query(".guitarist").appendTo(bands[0]);
+						query("body").append('<p class="guitarist">jimmy</p><p class="guitarist">page</p>');
+						query(".guitarist").appendTo(bands[0]);
 						bands.forEach(function(node){
 							doh.is(4, node.childNodes.length);
 							doh.is("guitarist", node.childNodes[2].className);
@@ -166,7 +171,7 @@
 					},
 
 					function prepend(t){
-						dojo.query(".singer").prepend('<span class="fry">layla</span>')
+						query(".singer").prepend('<span class="fry">layla</span>')
 							.forEach(function(node){
 								doh.is(5, node.childNodes.length);
 								doh.is("fry", node.childNodes[0].className);
@@ -176,12 +181,12 @@
 
 					function prependTo(t){
 						//Create some new things.
-						dojo.query("body").append('<p class="actor">steve</p><p class="actor">martin</p>');
+						query("body").append('<p class="actor">steve</p><p class="actor">martin</p>');
 
-						var ret = dojo.query(".bar").prependTo(".actor");
+						var ret = query(".bar").prependTo(".actor");
 						doh.is(6, ret.length);
 
-						dojo.query(".actor").forEach(function(node){
+						query(".actor").forEach(function(node){
 							doh.is(4, node.childNodes.length);
 							doh.is("bar", node.childNodes[0].className);
 							doh.is("bar", node.childNodes[1].className);
@@ -189,7 +194,7 @@
 						});
 
 						//Clean up
-						dojo.query("p").remove();
+						query("p").remove();
 					},
 
 					function after(t){
@@ -199,7 +204,7 @@
 							}
 						);
 
-						dojo.query("form").after(dojo.query(".after")).forEach(function(node){
+						query("form").after(query(".after")).forEach(function(node){
 							for(var i = 0; i < 3; i++){
 								doh.is("after", node.nextSibling.className);
 								node = node.nextSibling;
@@ -208,11 +213,11 @@
 					},
 
 					function insertAfter(t){
-						dojo.query("body").prepend('<h1>testing dojo.NodeList-manipulate</h1>');
-						var ret = dojo.query(".after").insertAfter("h1");
+						query("body").prepend('<h1>testing dojo.NodeList-manipulate</h1>');
+						var ret = query(".after").insertAfter("h1");
 						doh.is(3, ret.length);
 
-						dojo.query("h1").forEach(function(node){
+						query("h1").forEach(function(node){
 							for(var i = 0; i < 3; i++){
 								doh.is("after", node.nextSibling.className);
 								node = node.nextSibling;
@@ -227,7 +232,7 @@
 							}
 						);
 
-						dojo.query("form").before(dojo.query(".before")).forEach(function(node){
+						query("form").before(query(".before")).forEach(function(node){
 							for(var i = 0; i < 3; i++){
 								doh.is("before", node.previousSibling.className);
 								node = node.previousSibling;
@@ -236,10 +241,10 @@
 					},
 
 					function insertBefore(t){
-						var ret = dojo.query(".before").insertBefore("h1");
+						var ret = query(".before").insertBefore("h1");
 						doh.is(3, ret.length);
 
-						dojo.query("h1").forEach(function(node){
+						query("h1").forEach(function(node){
 							for(var i = 0; i < 3; i++){
 								doh.is("before", node.previousSibling.className);
 								node = node.previousSibling;
@@ -250,59 +255,59 @@
 					function remove(t){
 						//Already did some removes, make sure they are not still here.
 						//This is also just an alias for orphan which has its own tests.
-						doh.is(0, dojo.query("p").length);
+						doh.is(0, query("p").length);
 					},
 
 					function wrap(t){
-						dojo.query(".before").wrap("<b><i></i></b>").forEach(function(node){
+						query(".before").wrap("<b><i></i></b>").forEach(function(node){
 							doh.is("i", node.parentNode.nodeName.toLowerCase());
 							doh.is("b", node.parentNode.parentNode.nodeName.toLowerCase());
 						});
 
-						dojo.query("b").wrap(dojo.query("h1")[0]).forEach(function(node){
+						query("b").wrap(query("h1")[0]).forEach(function(node){
 							doh.is("h1", node.parentNode.nodeName.toLowerCase());
-							doh.is(4, dojo.query("h1").length);
+							doh.is(4, query("h1").length);
 						});
 					},
 
 					function wrapAll(t){
-						dojo.query("h1").wrapAll('<h4></h4>');
-						var h4s = dojo.query("h4");
+						query("h1").wrapAll('<h4></h4>');
+						var h4s = query("h4");
 						doh.is(1, h4s.length);
 
 						var h4 = h4s[0];
 						doh.is(4, h4.childNodes.length);
-						dojo.query("h1").forEach(function(node){
+						query("h1").forEach(function(node){
 							doh.is("h4", node.parentNode.nodeName.toLowerCase());         
 						});
 
 						//Complicated test that test for cloning of the wrap nodes in the right
 						//situation.
-						var div = dojo.create("div", {"class": "myClass"});
-						dojo.query("#inputForm").query("select").wrapAll(div).end().query("input").wrapAll(div);
-						var myClass = dojo.query(".myClass");
+						var div = domConstruct.create("div", {"class": "myClass"});
+						query("#inputForm").query("select").wrapAll(div).end().query("input").wrapAll(div);
+						var myClass = query(".myClass");
 
 						doh.is(2, myClass.length);
-						doh.is(5, dojo.query("input", myClass[0]).length);
-						doh.is(2, dojo.query("select", myClass[1]).length);
+						doh.is(5, query("input", myClass[0]).length);
+						doh.is(2, query("select", myClass[1]).length);
 					},
 
 					function wrapInner(t){
-						dojo.query("h4").wrapInner('<h3></h3>');
-						var h3s = dojo.query("h3");
+						query("h4").wrapInner('<h3></h3>');
+						var h3s = query("h3");
 						doh.is(1, h3s.length);
 
 						var h3 = h3s[0];
 						doh.is(4, h3.childNodes.length);
-						dojo.query("h1").forEach(function(node){
+						query("h1").forEach(function(node){
 							doh.is("h3", node.parentNode.nodeName.toLowerCase());         
 						});
 					},
 
 					function replaceWith(t){
-						dojo.query("h1").replaceWith('<span class="replace">replace</span><b>hello</b>');
+						query("h1").replaceWith('<span class="replace">replace</span><b>hello</b>');
 
-						dojo.query("h3").forEach(function(node){
+						query("h3").forEach(function(node){
 							doh.is(8, node.childNodes.length);
 							doh.is("replace", node.childNodes[0].className);
 							doh.is("b", node.childNodes[1].nodeName.toLowerCase());
@@ -310,23 +315,24 @@
 					},
 
 					function replaceAll(t){
-						dojo.query(".after").replaceAll("h4");
+						query(".after").replaceAll("h4");
 
-						doh.is(3, dojo.query(".after").length);
-						doh.is(0, dojo.query("h4").length);
+						doh.is(3, query(".after").length);
+						doh.is(0, query("h4").length);
 
-						dojo.query("body").append('<i class="italics">italics</i>');
-						doh.is("i", dojo.query(".italics").replaceAll(".after")[0].nodeName.toLowerCase());
-						doh.is(0, dojo.query(".after").length);
-						doh.is(3, dojo.query(".italics").length);
+						query("body").append('<i class="italics">italics</i>');
+						doh.is("i", query(".italics").replaceAll(".after")[0].nodeName.toLowerCase());
+						doh.is(0, query(".after").length);
+						doh.is(3, query(".italics").length);
 					},
 
 					function clone(t){
-						dojo.query(".italics").clone().appendTo("body");
-						doh.is(6, dojo.query(".italics").length);
+						query(".italics").clone().appendTo("body");
+						doh.is(6, query(".italics").length);
 					}
 				]);
-				doh.runOnLoad();
+
+				doh.run();
 			});
 		</script>
 	</head>
diff --git a/dojo/tests/NodeList-manipulate.js b/dojo/tests/NodeList-manipulate.js
index 044ce4a..233a0a5 100644
--- a/dojo/tests/NodeList-manipulate.js
+++ b/dojo/tests/NodeList-manipulate.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests.NodeList-manipulate", require.toUrl("./NodeList-manipulate.html"), 30000);
 	}
diff --git a/dojo/tests/NodeList-traverse.html b/dojo/tests/NodeList-traverse.html
index c12907b..cf5f36e 100644
--- a/dojo/tests/NodeList-traverse.html
+++ b/dojo/tests/NodeList-traverse.html
@@ -8,7 +8,7 @@
 		</style>
 		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug: true, popup: true"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/NodeList-traverse", "dojo/domReady!"], function(dojo, doh){
+			require(["doh", "dojo/query", "dojo/NodeList-traverse", "dojo/domReady!"], function(doh, query){
 
 				function verify(/*dojo.NodeList*/nl, /*Array*/ids, /*String*/ comment){
 					comment = comment || "verify";
@@ -19,7 +19,7 @@
 					doh.is(ids.length, i, comment + " length");
 				}
 
-				var divs = dojo.query("div.testDiv");
+				var divs = query("div.testDiv");
 
 				doh.register([
 					function children(t){
@@ -28,13 +28,13 @@
 
 					function closest(t){
 						// test simple selector
-						var classy = dojo.query("#classy");
+						var classy = query("#classy");
 						var closestDiv = classy.closest("div");
 						verify(closestDiv, ["third"], "closest('div')");
 						verify(closestDiv.end().closest(".classy"), ["classy"], "closestDiv.end().closest('.classy')");
 
 						// test descendant selector
-						var bang = dojo.query(".bang");
+						var bang = query(".bang");
 						var closestFooBar = bang.closest(".foo > .bar");
 						verify(closestFooBar, ["level4"], ".foo > .bar");
 
@@ -58,49 +58,49 @@
 						verify(closestFooBar, [], ".foo > .bar query relative to level3");
 
 						// complex test of multiple elements in NodeList
-						// Only some of the elements in dojo.query("div") have a ".foo" ancestor,
+						// Only some of the elements in query("div") have a ".foo" ancestor,
 						// and three of those elements have the *same* .foo ancestor, so
 						// closest(".foo") should result in list of just two elements
-						var closestFoo = dojo.query("div").closest(".foo");
+						var closestFoo = query("div").closest(".foo");
 						verify(closestFoo, ["level1", "level3"], ".foo from div");
 					 
 					},
 
 					function parent(t){
-						verify(dojo.query("#classy").parent(), ["third"]);
+						verify(query("#classy").parent(), ["third"]);
 					},
 
 					function parents(t){
-						var classy = dojo.query("#classy");
+						var classy = query("#classy");
 						verify(classy.parents(), ["third", "body", "html"]);
 						verify(classy.parents(".third"), ["third"]);
 						verify(classy.parents("body"), ["body"]);
 					},
 
 					function siblings(t){
-						verify(dojo.query("#classy").siblings(), ["crass", "yeah"]);
+						verify(query("#classy").siblings(), ["crass", "yeah"]);
 					},
 
 					function next(t){
-						verify(dojo.query("#crass").next(), ["classy"]);
+						verify(query("#crass").next(), ["classy"]);
 					},
 
 					function nextAll(t){
-						verify(dojo.query("#crass").nextAll(), ["classy", "yeah"]);
-						verify(dojo.query("#crass").nextAll("#yeah"), ["yeah"]);
+						verify(query("#crass").nextAll(), ["classy", "yeah"]);
+						verify(query("#crass").nextAll("#yeah"), ["yeah"]);
 					},
 
 					function prev(t){
-						verify(dojo.query("#classy").prev(), ["crass"]);
+						verify(query("#classy").prev(), ["crass"]);
 					},
 
 					function prevAll(t){
-						verify(dojo.query("#yeah").prevAll(), ["classy", "crass"]);
-						verify(dojo.query("#yeah").prevAll("#crass"), ["crass"]);
+						verify(query("#yeah").prevAll(), ["classy", "crass"]);
+						verify(query("#yeah").prevAll("#crass"), ["crass"]);
 					},
 
 					function andSelf(t){
-						verify(dojo.query("#yeah").prevAll().andSelf(), ["classy", "crass", "yeah"]);
+						verify(query("#yeah").prevAll().andSelf(), ["classy", "crass", "yeah"]);
 					},
 
 					function first(t){
@@ -123,7 +123,8 @@
 						verify(odd.end(), ["sq100", "t", "third"]);
 					}
 				]);
-				doh.runOnLoad();
+
+				doh.run();
 			});
 		</script>
 	</head>
diff --git a/dojo/tests/NodeList-traverse.js b/dojo/tests/NodeList-traverse.js
index 77c6ac3..5a59aac 100644
--- a/dojo/tests/NodeList-traverse.js
+++ b/dojo/tests/NodeList-traverse.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests.NodeList-traverse", require.toUrl("./NodeList-traverse.html"), 30000);
 	}
diff --git a/dojo/tests/Stateful.js b/dojo/tests/Stateful.js
index f4b41a1..c7b4c36 100644
--- a/dojo/tests/Stateful.js
+++ b/dojo/tests/Stateful.js
@@ -1,11 +1,12 @@
-define(["../main", "doh", "../Stateful"], function(dojo, doh){
+define(["doh/main", "../Stateful", "../_base/declare", "../Deferred", "../json"],
+function(doh, Stateful, declare, Deferred, JSON){
 
 doh.register("tests.Stateful", [
 	function getSetWatch(t){
-		var s = new dojo.Stateful({
+		var s = new Stateful({
 			foo: 3
 		});
-		doh.is(s.get("foo"), 3);
+		doh.is(3, s.get("foo"));
 		var watching = s.watch("foo", function(name, oldValue, value){
 			doh.is("foo", name);
 			doh.is(3, oldValue);
@@ -18,19 +19,64 @@ doh.register("tests.Stateful", [
 		s.set("foo", 5);
 		doh.is(5, s.get("foo"));
 	},
+	function removeWatchHandle(t){
+		var s = new Stateful({
+				foo: 3
+			}),
+			watched = false;
+
+		var watching = s.watch("foo", function(){
+			t.f(watched);
+			watched = true;
+		});
+		s.set("foo", 4);
+		watching.remove();
+		s.set("foo", 5);
+	},
+	function removeWatchHandleTwice(t){
+		var s = new Stateful({
+				foo: 3
+			}),
+			assertions = 0;
+
+		var watching = s.watch("foo", function(){
+			assertions++;
+		});
+		var watching2 = s.watch("foo", function(){
+			assertions++;
+		});
+		s.set("foo", 4);
+		watching.remove();
+		watching.remove();
+		s.set("foo", 5);
+		
+		t.is(3, assertions, "assertions");
+	},
 	function setHash(t){
-		var s = new dojo.Stateful();
+		var s = new Stateful(),
+			fooCount = 0, 
+			handle = s.watch('foo', function () { 
+				fooCount++; 
+			}); 
 		s.set({
 			foo:3,
 			bar: 5
 		});
 		doh.is(3, s.get("foo"));
 		doh.is(5, s.get("bar"));
+		doh.is(1, fooCount);
+		var s2 = new Stateful();
+		s2.set(s);
+		doh.is(3, s2.get("foo"));
+		doh.is(5, s2.get("bar"));
+		// s watchers should not be copied to s2 
+		doh.is(1, fooCount); 
+		handle.unwatch(); 
 	},
 	function wildcard(t){
-		var s = new dojo.Stateful();
+		var s = new Stateful();
 		s.set({
-			foo:3,
+			foo: 3,
 			bar: 5
 		});
 		var wildcard = 0;
@@ -45,7 +91,131 @@ doh.register("tests.Stateful", [
 		s.set("bar", 6);
 		doh.is(2, wildcard);
 		doh.is(1, foo);
+	},
+	function accessors(t){
+		var StatefulClass1 = declare([Stateful],{
+			foo: "",
+			bar: 0,
+			baz: "",
+			
+			_fooSetter: function(value){
+				this.foo = value;
+			},
+			_fooGetter: function(){
+				return "bar";
+			},
+			
+			_barSetter: function(value){
+				this.bar = value;
+			}
+		});
+		
+		var attr1 = new StatefulClass1();
+		attr1.set("foo", "nothing");
+		attr1.set("bar", 2);
+		attr1.set("baz", "bar");
+		
+		t.is("nothing", attr1.foo, "attribute set properly");
+		t.is("bar", attr1.get("foo"), "getter working properly");
+		t.is(2, attr1.bar, "attribute set properly");
+		t.is( 2, attr1.get("bar"), "getter working properly");
+		t.is("bar", attr1.get("baz"), "getter working properly");
+		t.is("bar", attr1.baz, "properly set properly");
+	},
+	function paramHandling(t){
+		var StatefulClass2 = declare([Stateful], {
+			foo: null,
+			bar: 5,
+			
+			_fooSetter: function(value){
+				this.foo = value;
+			},
+			_barSetter: function(value){
+				this.bar = value;
+			}
+		});
+		
+		var attr2 = new StatefulClass2({
+			foo: function(){
+				return "baz";
+			},
+			bar: 4
+		});
+		
+		t.is("function", typeof attr2.foo, "function attribute set");
+		t.is("baz", attr2.foo(), "function has proper return value");
+		t.is(4, attr2.get("bar"), "attribute has proper value");
+	},
+	function deferredSetting(t){
+		var td = new doh.Deferred();
+		var StatefulClass3 = declare([Stateful], {
+			foo: null,
+			
+			_fooSetter: function(value){
+				var d = new Deferred();
+				var self = this;
+				setTimeout(function(){
+					self.foo = value;
+					d.resolve(value);
+				}, 50);
+				return d;
+			}
+		});
+		
+		var attr3 = new StatefulClass3();
+		attr3.watch("foo", function(name, oldValue, value){
+			t.is("foo", name, "right attribute");
+			t.f(oldValue, "no value previously");
+			t.is(3, value, "new value set");
+			td.callback(true);
+		});
+		attr3.set("foo", 3);
+		
+		return td;
+	},
+	function changeAttrValue(t){
+		var output = [];
+		var StatefulClass4 = declare([Stateful], {
+			foo: null,
+			bar: null,
+			
+			_fooSetter: function(value){
+				this._changeAttrValue("bar", value);
+				this.foo = value;
+			},
+			_barSetter: function(value){
+				this._changeAttrValue("foo", value);
+				this.bar = value;
+			}
+		});
+		
+		var attr4 = new StatefulClass4();
+		attr4.watch("foo", function(name, oldValue, value){
+			output.push(name, oldValue, value);
+		});
+		attr4.watch("bar", function(name, oldValue, value){
+			output.push(name, oldValue, value);
+		});
+		attr4.set("foo", 3);
+		t.is(3, attr4.get("bar"), "value set properly");
+		attr4.set("bar", 4);
+		t.is(4, attr4.get("foo"), "value set properly");
+		t.is(["bar", null, 3, "foo", null, 3, "foo", 3, 4, "bar", 3, 4], output);
+	},
+	function serialize(t){
+		var StatefulClass5 = declare([Stateful], {
+			foo: null,
+			_fooSetter: function(value){
+				this.foo = value + "baz";
+			}
+		});
+		
+		var obj = new StatefulClass5({
+			foo: "bar"
+		});
+		
+		t.is('{"foo":"barbaz"}', JSON.stringify(obj), "object serializes properly");
 	}
 ]);
 
-});
\ No newline at end of file
+});
diff --git a/dojo/tests/_base.js b/dojo/tests/_base.js
index 9f6d702..1760580 100644
--- a/dojo/tests/_base.js
+++ b/dojo/tests/_base.js
@@ -9,6 +9,7 @@ define([
 	"dojo/tests/_base/json",
 	"dojo/tests/_base/object",
 	"dojo/has!host-browser?dojo/tests/_base/html",
+	"dojo/has!host-browser?dojo/tests/dom-style",
 	"dojo/has!host-browser?dojo/tests/_base/fx",
 	"dojo/has!host-browser?dojo/tests/_base/query",
 	"dojo/has!host-browser?dojo/tests/_base/xhr",
@@ -16,7 +17,7 @@ define([
 
 	// TODO: platform boot tests
 	//dojo.platformRequire({
-	//	browser: ["tests._base._loader.hostenv_browser"],
-	//	rhino: ["tests._base._loader.hostenv_rhino"],
-	//	spidermonkey: ["tests._base._loader.hostenv_spidermonkey"]
+	// browser: ["tests._base._loader.hostenv_browser"],
+	// rhino: ["tests._base._loader.hostenv_rhino"],
+	// spidermonkey: ["tests._base._loader.hostenv_spidermonkey"]
 	//});
diff --git a/dojo/tests/_base/Color.js b/dojo/tests/_base/Color.js
index 95b67f4..50ae3da 100644
--- a/dojo/tests/_base/Color.js
+++ b/dojo/tests/_base/Color.js
@@ -1,13 +1,12 @@
-dojo.provide("dojo.tests._base.Color");
+define(["doh", "dojo/_base/array", "dojo/_base/Color"], function(doh, array, Color){
 
-(function(){
-	var white  = dojo.colorFromString("white").toRgba();
-	var maroon = dojo.colorFromString("maroon").toRgba();
+	var white  = Color.fromString("white").toRgba();
+	var maroon = Color.fromString("maroon").toRgba();
 	var verifyColor = function(t, source, expected){
-		var color = new dojo.Color(source);
+		var color = new Color(source);
 		t.is(expected, color.toRgba());
-		dojo.forEach(color.toRgba(), function(n){
-			t.is("number", typeof(n));
+		array.forEach(color.toRgba(), function(n){
+			doh.is("number", typeof(n));
 		});
 	};
 
@@ -24,7 +23,7 @@ dojo.provide("dojo.tests._base.Color");
 			function testColor9(t){ verifyColor(t, maroon, maroon); },
 			function testColor10(t){ verifyColor(t, [1, 2, 3], [1, 2, 3, 1]); },
 			function testColor11(t){ verifyColor(t, [1, 2, 3, 0.5], [1, 2, 3, 0.5]); },
-			function testColor12(t){ verifyColor(t, dojo.blendColors(new dojo.Color("black"), new dojo.Color("white"), 0.5), [128, 128, 128, 1]); }
+			function testColor12(t){ verifyColor(t, Color.blendColors(new Color("black"), new Color("white"), 0.5), [128, 128, 128, 1]); }
 		]
 	);
-})();
+});
diff --git a/dojo/tests/_base/Deferred.js b/dojo/tests/_base/Deferred.js
index e0e690b..3a94eab 100644
--- a/dojo/tests/_base/Deferred.js
+++ b/dojo/tests/_base/Deferred.js
@@ -131,9 +131,6 @@ doh.register("tests._base.Deferred",
 			});
 			return td;
 		},
-		function syncWhenWithNoCallback(t){
-			t.is(dojo.when(3), 3);
-		},
 		function progress(t){
 			if(dojo.isBrowser){
 				var td = new doh.Deferred();
@@ -149,15 +146,6 @@ doh.register("tests._base.Deferred",
 			}
 			return null;
 		},
-		function errorHandler(t){
-			var def = new dojo.Deferred();
-			var handledError;
-			dojo.config.deferredOnError = function(e){
-				handledError = e;
-			};
-			def.reject(new Error("test"));
-			t.t(handledError instanceof Error);
-		},
 		function cancelThenDerivative(t){
 			var def = new dojo.Deferred();
 			var def2 = def.then();
@@ -266,14 +254,14 @@ doh.register("tests._base.Deferred",
 
 			t.assertEqual("succeed", retval);
 		},
-		function testDojoPromiseProgressBasic(t) {
+		function testDojoPromiseProgressBasic(t){
 			var a = new dojo.Deferred();
 			var b = new dojo.Deferred();
 			var called = false;
 			
-			a.then(function() {
+			a.then(function(){
 				b.then(function(){
-					if (!called) {
+					if (!called){
 						console.log("Boo. ProgressBasic not called");
 					}
 				}, function(){
@@ -290,15 +278,15 @@ doh.register("tests._base.Deferred",
 			t.t(called);
 		},
 		
-		function testDojoPromiseProgressChain(t) {
+		function testDojoPromiseProgressChain(t){
 			var a = new dojo.Deferred();
 			var b = new dojo.Deferred();
 			var called = false;
 			
-			a.then(function() {
+			a.then(function(){
 				return b;
 			}).then(function(){
-				if (!called) {
+				if (!called){
 					console.log("Boo. ProgressChain not called");
 				}
 			}, function(){
diff --git a/dojo/tests/_base/NodeList.html b/dojo/tests/_base/NodeList.html
index 0b90cd2..a084e31 100644
--- a/dojo/tests/_base/NodeList.html
+++ b/dojo/tests/_base/NodeList.html
@@ -378,7 +378,10 @@
 							doh.t(typeof NodeList != "undefined" && cat.constructor === dojo.NodeList
 								|| cat.constructor === dojo.NodeList);
 						},
-
+						function concat4(){ 
+							var res = (new dojo.NodeList()).concat([]); 
+							doh.is(0, res.length); 
+						}, 
 						function place(){
 							var ih = "<div><span></span></div><span class='thud'><b>blah</b></span>";
 
diff --git a/dojo/tests/_base/abs.html b/dojo/tests/_base/abs.html
index 906f602..f1b5df8 100644
--- a/dojo/tests/_base/abs.html
+++ b/dojo/tests/_base/abs.html
@@ -7,7 +7,7 @@
 		</style>
 		<script type="text/javascript" 
 			src="../../dojo.js" 
-			djConfig="isDebug: false"></script>
+			data-dojo-config="isDebug: false"></script>
 		<script type="text/javascript">
 			function onButtonClick(){
 				/* position a red square over pressed button */
diff --git a/dojo/tests/_base/absQuirk.html b/dojo/tests/_base/absQuirk.html
index fa525ec..e5ea65b 100644
--- a/dojo/tests/_base/absQuirk.html
+++ b/dojo/tests/_base/absQuirk.html
@@ -6,7 +6,7 @@
 		</style>
 		<script type="text/javascript" 
 			src="../../dojo.js" 
-			djConfig="isDebug: false"></script>
+			data-dojo-config="isDebug: false"></script>
 		<script type="text/javascript">
 			function onButtonClick(){
 				/* position a red square over pressed button */
diff --git a/dojo/tests/_base/array.js b/dojo/tests/_base/array.js
index ea1cdda..577938e 100644
--- a/dojo/tests/_base/array.js
+++ b/dojo/tests/_base/array.js
@@ -1,57 +1,56 @@
-dojo.provide("dojo.tests._base.array");
+define(["doh", "dojo/_base/array", "dojo/_base/lang"], function(doh, array, lang){
 
-tests.register("tests._base.array",
-	[
+	doh.register("tests._base.array", [
 		function testIndexOf(t){
 			var foo = [128, 256, 512];
 			var bar = ["aaa", "bbb", "ccc"];
 
-			t.assertEqual(1, dojo.indexOf([45, 56, 85], 56));
-			t.assertEqual(1, dojo.indexOf([Number, String, Date], String));
-			t.assertEqual(1, dojo.indexOf(foo, foo[1]));
-			t.assertEqual(2, dojo.indexOf(foo, foo[2]));
-			t.assertEqual(1, dojo.indexOf(bar, bar[1]));
-			t.assertEqual(2, dojo.indexOf(bar, bar[2]));
-			t.assertEqual(-1, dojo.indexOf({a:1}, "a"));
+			t.assertEqual(1, array.indexOf([45, 56, 85], 56));
+			t.assertEqual(1, array.indexOf([Number, String, Date], String));
+			t.assertEqual(1, array.indexOf(foo, foo[1]));
+			t.assertEqual(2, array.indexOf(foo, foo[2]));
+			t.assertEqual(1, array.indexOf(bar, bar[1]));
+			t.assertEqual(2, array.indexOf(bar, bar[2]));
+			t.assertEqual(-1, array.indexOf({a:1}, "a"));
 
 			foo.push(bar);
-			t.assertEqual(3, dojo.indexOf(foo, bar));
+			t.assertEqual(3, array.indexOf(foo, bar));
 		},
 
 		function testIndexOfFromIndex(t){
 			var foo = [128, 256, 512];
 			var bar = ["aaa", "bbb", "ccc"];
 
-			t.assertEqual(-1, dojo.indexOf([45, 56, 85], 56, 2));
-			t.assertEqual(1, dojo.indexOf([45, 56, 85], 56, 1));
-			t.assertEqual(1, dojo.indexOf([45, 56, 85], 56, -3));
+			t.assertEqual(-1, array.indexOf([45, 56, 85], 56, 2));
+			t.assertEqual(1, array.indexOf([45, 56, 85], 56, 1));
+			t.assertEqual(1, array.indexOf([45, 56, 85], 56, -3));
 			// Make sure going out of bounds doesn't throw us in an infinite loop
-			t.assertEqual(-1, dojo.indexOf([45, 56, 85], 56, 3));
+			t.assertEqual(-1, array.indexOf([45, 56, 85], 56, 3));
 		},
 
 		function testLastIndexOf(t){
 			var foo = [128, 256, 512];
 			var bar = ["aaa", "bbb", "aaa", "ccc"];
 
-			t.assertEqual(1, dojo.indexOf([45, 56, 85], 56));
-			t.assertEqual(1, dojo.indexOf([Number, String, Date], String));
-			t.assertEqual(1, dojo.lastIndexOf(foo, foo[1]));
-			t.assertEqual(2, dojo.lastIndexOf(foo, foo[2]));
-			t.assertEqual(1, dojo.lastIndexOf(bar, bar[1]));
-			t.assertEqual(2, dojo.lastIndexOf(bar, bar[2]));
-			t.assertEqual(2, dojo.lastIndexOf(bar, bar[0]));
+			t.assertEqual(1, array.indexOf([45, 56, 85], 56));
+			t.assertEqual(1, array.indexOf([Number, String, Date], String));
+			t.assertEqual(1, array.lastIndexOf(foo, foo[1]));
+			t.assertEqual(2, array.lastIndexOf(foo, foo[2]));
+			t.assertEqual(1, array.lastIndexOf(bar, bar[1]));
+			t.assertEqual(2, array.lastIndexOf(bar, bar[2]));
+			t.assertEqual(2, array.lastIndexOf(bar, bar[0]));
 		},
 
 		function testLastIndexOfFromIndex(t){
-			t.assertEqual(1, dojo.lastIndexOf([45, 56, 85], 56, 1));
-			t.assertEqual(-1, dojo.lastIndexOf([45, 56, 85], 85, 1));
-			t.assertEqual(-1, dojo.lastIndexOf([45, 56, 85], 85, -2));
-			t.assertEqual(0, dojo.lastIndexOf([45, 56, 45], 45, 0));
+			t.assertEqual(1, array.lastIndexOf([45, 56, 85], 56, 1));
+			t.assertEqual(-1, array.lastIndexOf([45, 56, 85], 85, 1));
+			t.assertEqual(-1, array.lastIndexOf([45, 56, 85], 85, -2));
+			t.assertEqual(0, array.lastIndexOf([45, 56, 45], 45, 0));
 		},
 
 		function testForEach(t){
 			var foo = [128, "bbb", 512];
-			dojo.forEach(foo, function(elt, idx, array){
+			array.forEach(foo, function(elt, idx, array){
 				switch(idx){
 					case 0: t.assertEqual(128, elt); break;
 					case 1: t.assertEqual("bbb", elt); break;
@@ -62,7 +61,7 @@ tests.register("tests._base.array",
 
 			var noException = true;
 			try{
-				dojo.forEach(undefined, function(){});
+				array.forEach(undefined, function(){});
 			}catch(e){
 				noException = false;
 			}
@@ -71,7 +70,7 @@ tests.register("tests._base.array",
 
 		function testForEach_str(t){
 			var bar = 'abc';
-			dojo.forEach(bar, function(elt, idx, array){
+			array.forEach(bar, function(elt, idx, array){
 				switch(idx){
 					case 0: t.assertEqual("a", elt); break;
 					case 1: t.assertEqual("b", elt); break;
@@ -90,15 +89,15 @@ tests.register("tests._base.array",
 			var obj = {
 				_res: ""
 			};
-			dojo.forEach(foo, "this._res += item", obj);
+			array.forEach(foo, "this._res += item", obj);
 			t.assertEqual(obj._res, "128bbb512");
 			// Test that the variable "index" contains each index.
 			obj._res = [];
-			dojo.forEach(foo, "this._res.push(index)", obj);
+			array.forEach(foo, "this._res.push(index)", obj);
 			t.assertEqual(obj._res, [0,1,2]);
 			// Test that the variable "array" always contains the entire array.
 			obj._res = [];
-			dojo.forEach(foo, "this._res.push(array)", obj);
+			array.forEach(foo, "this._res.push(array)", obj);
 			t.assertEqual(obj._res, [
 				[128, "bbb", 512],
 				[128, "bbb", 512],
@@ -107,7 +106,7 @@ tests.register("tests._base.array",
 			// Catch undefined variable usage (I used to use "i" :-)).
 			var caughtException = false;
 			try{
-				dojo.forEach(foo, "this._res += arr[i];", obj);
+				array.forEach(foo, "this._res += arr[i];", obj);
 			}catch(e){
 				caughtException = true;
 			}
@@ -119,9 +118,9 @@ tests.register("tests._base.array",
 			var foo = [128, "bbb", 512];
 
 			t.assertTrue(
-				dojo.every(foo, function(elt, idx, array){
+				array.every(foo, function(elt, idx, array){
 					t.assertEqual(Array, array.constructor);
-					t.assertTrue(dojo.isArray(array));
+					t.assertTrue(lang.isArray(array));
 					t.assertTrue(typeof idx == "number");
 					if(idx == 1){ t.assertEqual("bbb" , elt); }
 					return true;
@@ -129,7 +128,7 @@ tests.register("tests._base.array",
 			);
 
 			t.assertTrue(
-				dojo.every(foo, function(elt, idx, array){
+				array.every(foo, function(elt, idx, array){
 					switch(idx){
 						case 0: t.assertEqual(128, elt); return true;
 						case 1: t.assertEqual("bbb", elt); return true;
@@ -140,7 +139,7 @@ tests.register("tests._base.array",
 			);
 
 			t.assertFalse(
-				dojo.every(foo, function(elt, idx, array){
+				array.every(foo, function(elt, idx, array){
 					switch(idx){
 						case 0: t.assertEqual(128, elt); return true;
 						case 1: t.assertEqual("bbb", elt); return true;
@@ -155,7 +154,7 @@ tests.register("tests._base.array",
 		function testEvery_str(t){
 			var bar = 'abc';
 			t.assertTrue(
-				dojo.every(bar, function(elt, idx, array){
+				array.every(bar, function(elt, idx, array){
 					switch(idx){
 						case 0: t.assertEqual("a", elt); return true;
 						case 1: t.assertEqual("b", elt); return true;
@@ -166,7 +165,7 @@ tests.register("tests._base.array",
 			);
 
 			t.assertFalse(
-				dojo.every(bar, function(elt, idx, array){
+				array.every(bar, function(elt, idx, array){
 					switch(idx){
 						case 0: t.assertEqual("a", elt); return true;
 						case 1: t.assertEqual("b", elt); return true;
@@ -181,29 +180,29 @@ tests.register("tests._base.array",
 		function testSome(t){
 			var foo = [128, "bbb", 512];
 			t.assertTrue(
-				dojo.some(foo, function(elt, idx, array){
+				array.some(foo, function(elt, idx, array){
 					t.assertEqual(3, array.length);
 					return true;
 				})
 			);
 
 			t.assertTrue(
-				dojo.some(foo, function(elt, idx, array){
+				array.some(foo, function(elt, idx, array){
 					return idx < 1;
 
 				})
 			);
 
 			t.assertFalse(
-				dojo.some(foo, function(elt, idx, array){
+				array.some(foo, function(elt, idx, array){
 					return false;
 				})
 			);
 
 			t.assertTrue(
-				dojo.some(foo, function(elt, idx, array){
+				array.some(foo, function(elt, idx, array){
 					t.assertEqual(Array, array.constructor);
-					t.assertTrue(dojo.isArray(array));
+					t.assertTrue(lang.isArray(array));
 					t.assertTrue(typeof idx == "number");
 					if(idx == 1){ t.assertEqual("bbb" , elt); }
 					return true;
@@ -214,7 +213,7 @@ tests.register("tests._base.array",
 		function testSome_str(t){
 			var bar = 'abc';
 			t.assertTrue(
-				dojo.some(bar, function(elt, idx, array){
+				array.some(bar, function(elt, idx, array){
 					t.assertEqual(3, array.length);
 					switch(idx){
 						case 0: t.assertEqual("a", elt); return true;
@@ -226,7 +225,7 @@ tests.register("tests._base.array",
 			);
 
 			t.assertTrue(
-				dojo.some(bar, function(elt, idx, array){
+				array.some(bar, function(elt, idx, array){
 					switch(idx){
 						case 0: t.assertEqual("a", elt); return true;
 						case 1: t.assertEqual("b", elt); return true;
@@ -237,7 +236,7 @@ tests.register("tests._base.array",
 			);
 
 			t.assertFalse(
-				dojo.some(bar, function(elt, idx, array){
+				array.some(bar, function(elt, idx, array){
 					return false;
 				})
 			);
@@ -248,25 +247,25 @@ tests.register("tests._base.array",
 			var foo = ["foo", "bar", 10];
 
 			t.assertEqual(["foo"],
-				dojo.filter(foo, function(elt, idx, array){
+				array.filter(foo, function(elt, idx, array){
 					return idx < 1;
 				})
 			);
 
 			t.assertEqual(["foo"],
-				dojo.filter(foo, function(elt, idx, array){
+				array.filter(foo, function(elt, idx, array){
 					return elt == "foo";
 				})
 			);
 
 			t.assertEqual([],
-				dojo.filter(foo, function(elt, idx, array){
+				array.filter(foo, function(elt, idx, array){
 					return false;
 				})
 			);
 
 			t.assertEqual([10],
-				dojo.filter(foo, function(elt, idx, array){
+				array.filter(foo, function(elt, idx, array){
 					return typeof elt == "number";
 				})
 			);
@@ -275,13 +274,13 @@ tests.register("tests._base.array",
 		function testFilter_str(t){
 			var foo = "thinger blah blah blah";
 			t.assertEqual(["t", "h", "i"],
-				dojo.filter(foo, function(elt, idx, array){
+				array.filter(foo, function(elt, idx, array){
 					return idx < 3;
 				})
 			);
 
 			t.assertEqual([],
-				dojo.filter(foo, function(elt, idx, array){
+				array.filter(foo, function(elt, idx, array){
 					return false;
 				})
 			);
@@ -289,15 +288,15 @@ tests.register("tests._base.array",
 
 		function testMap(t){
 			t.assertEqual([],
-				dojo.map([], function(){ return true; })
+				array.map([], function(){ return true; })
 			);
 
 			t.assertEqual([1, 2, 3],
-				dojo.map(["cat", "dog", "mouse"], function(elt, idx, array){
+				array.map(["cat", "dog", "mouse"], function(elt, idx, array){
 					return idx+1;
 				})
 			);
 		}
-	]
-);
+	]);
+});
 
diff --git a/dojo/tests/_base/connect.js b/dojo/tests/_base/connect.js
index af5c392..6ab860e 100644
--- a/dojo/tests/_base/connect.js
+++ b/dojo/tests/_base/connect.js
@@ -89,16 +89,16 @@ tests.register("tests._base.connect",
 			foo.foo();
 			t.is(true, ok);
 		},
-		function basicTest(t) {
+		function basicTest(t){
 			var out = '';
 			var obj = {
-				foo: function() {
+				foo: function(){
 					out += 'foo';
 				},
-				bar: function() {
+				bar: function(){
 					out += 'bar';
 				},
-				baz: function() {
+				baz: function(){
 					out += 'baz';
 				}
 			};
@@ -138,7 +138,7 @@ tests.register("tests._base.connect",
 		},
 		function args4Test(t){
 			// standard 4 args test
-			var ok, obj = { foo: function(){ok=false;}, bar: function(){ok=true} };
+			var ok, obj = { foo: function(){ok=false;}, bar: function(){ok=true;} };
 			dojo.connect(obj, "foo", obj, "bar");
 			obj.foo();
 			t.is(true, ok);
@@ -180,7 +180,7 @@ tests.register("tests._base.connect",
 		},
 		function scopeTest1(t){
 			var foo = { ok: true, foo: function(){this.ok=false;} };
-			var bar = { ok: false, bar: function(){this.ok=true} };
+			var bar = { ok: false, bar: function(){this.ok=true;} };
 			// link foo.foo to bar.bar with natural scope
 			var link = dojo.connect(foo, "foo", bar, "bar");
 			foo.foo();
@@ -189,7 +189,7 @@ tests.register("tests._base.connect",
 		},
 		function scopeTest2(t){
 			var foo = { ok: true, foo: function(){this.ok=false;} };
-			var bar = { ok: false, bar: function(){this.ok=true} };
+			var bar = { ok: false, bar: function(){this.ok=true;} };
 			// link foo.foo to bar.bar such that scope is always 'foo'
 			var link = dojo.connect(foo, "foo", bar.bar);
 			foo.foo();
diff --git a/dojo/tests/_base/connectKey.html b/dojo/tests/_base/connectKey.html
new file mode 100644
index 0000000..b4a6ed9
--- /dev/null
+++ b/dojo/tests/_base/connectKey.html
@@ -0,0 +1,27 @@
+<html>
+	<head>
+		<title>dojo.connect() keypress/keydown test</title>
+		<script src="../../dojo.js"></script>
+		<script>
+			require(["dojo/dom", "dojo/on", "dojo/_base/connect", "dojo/domReady!"],
+			function(dom, on, connect){
+				connect.connect(dom.byId("textbox"), "onkeypress", function(evt){
+					console.log("keypress event from dojo.connect(): ", evt.type + ", " + evt.charCode + ", " + evt.charOrCode);
+				});
+				connect.connect(dom.byId("textbox"), "onkeydown", function(evt){
+					console.log("keydown event from dojo.connect(): " + evt.type + ", " + evt.keyCode);
+				});
+			});
+		</script>
+	</head>
+	<body>
+		<h1>dojo.connect() keypress/keydown test</h1>
+		<p>
+			Test for dojo.connect()'s deprecated code to normalize onkeypress/onkeydown events to behave like mozilla.
+		</p>
+		<p>
+			Type into <input>, and watch console for log messages.
+		</p>
+		<input id="textbox">
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojo/tests/_base/declare.js b/dojo/tests/_base/declare.js
index ce2fd0b..011776f 100644
--- a/dojo/tests/_base/declare.js
+++ b/dojo/tests/_base/declare.js
@@ -1,29 +1,31 @@
 // FIXME: this test assumes the existence of the global object "tests"
 tests= typeof tests=="undefined" ? {} : tests;
 
-define(["../..", "doh"], function(dojo, doh){
+define([
+	"doh/main", "dojo/aspect", "dojo/_base/declare", "dojo/_base/kernel", "dojo/_base/lang"
+], function(doh, aspect, declare, kernel, lang){
 	doh.register("tests._base.declare", [
 		function smokeTest(t){
-			dojo.declare("tests._base.declare.tmp", null);
+			declare("tests._base.declare.tmp", null);
 			var tmp = new tests._base.declare.tmp();
-			dojo.declare("testsFoo", null);
+			declare("testsFoo", null);
 			tmp = new testsFoo();
 		},
 		function smokeTest2(t){
-			dojo.declare("tests._base.declare.foo", null, {
+			declare("tests._base.declare.foo", null, {
 				foo: "thonk"
 			});
 			var tmp = new tests._base.declare.foo();
 			t.is("thonk", tmp.foo);
 
-			dojo.declare("testsFoo2", null, {
+			declare("testsFoo2", null, {
 				foo: "thonk"
 			});
 			var tmp2 = new testsFoo2();
 			t.is("thonk", tmp2.foo);
 		},
 		function smokeTestWithCtor(t){
-			dojo.declare("tests._base.declare.fooBar", null, {
+			declare("tests._base.declare.fooBar", null, {
 				constructor: function(){
 					this.foo = "blah";
 				},
@@ -33,43 +35,43 @@ define(["../..", "doh"], function(dojo, doh){
 			t.is("blah", tmp.foo);
 		},
 		function smokeTestCompactArgs(t){
-			dojo.declare("tests._base.declare.fooBar2", null, {
+			declare("tests._base.declare.fooBar2", null, {
 				foo: "thonk"
 			});
 			var tmp = new tests._base.declare.fooBar2();
 			t.is("thonk", tmp.foo);
 		},
 		function subclass(t){
-			dojo.declare("tests._base.declare.tmp3", null, {
+			declare("tests._base.declare.tmp3", null, {
 				foo: "thonk"
 			});
-			dojo.declare("tests._base.declare.tmp4", tests._base.declare.tmp3);
+			declare("tests._base.declare.tmp4", tests._base.declare.tmp3);
 			var tmp = new tests._base.declare.tmp4();
 			t.is("thonk", tmp.foo);
 		},
 		function subclassWithCtor(t){
-			dojo.declare("tests._base.declare.tmp5", null, {
+			declare("tests._base.declare.tmp5", null, {
 				constructor: function(){
 					this.foo = "blah";
 				},
 				foo: "thonk"
 			});
-			dojo.declare("tests._base.declare.tmp6", tests._base.declare.tmp5);
+			declare("tests._base.declare.tmp6", tests._base.declare.tmp5);
 			var tmp = new tests._base.declare.tmp6();
 			t.is("blah", tmp.foo);
 		},
 		function mixinSubclass(t){
-			dojo.declare("tests._base.declare.tmp7", null, {
+			declare("tests._base.declare.tmp7", null, {
 				foo: "thonk"
 			});
-			dojo.declare("tests._base.declare.tmp8", null, {
+			declare("tests._base.declare.tmp8", null, {
 				constructor: function(){
 					this.foo = "blah";
 				}
 			});
 			var tmp = new tests._base.declare.tmp8();
 			t.is("blah", tmp.foo);
-			dojo.declare("tests._base.declare.tmp9",
+			declare("tests._base.declare.tmp9",
 				[
 					tests._base.declare.tmp7, // prototypal
 					tests._base.declare.tmp8  // mixin
@@ -78,10 +80,10 @@ define(["../..", "doh"], function(dojo, doh){
 			t.is("blah", tmp2.foo);
 		},
 		function superclassRef(t){
-			dojo.declare("tests._base.declare.tmp10", null, {
+			declare("tests._base.declare.tmp10", null, {
 				foo: "thonk"
 			});
-			dojo.declare("tests._base.declare.tmp11", tests._base.declare.tmp10, {
+			declare("tests._base.declare.tmp11", tests._base.declare.tmp10, {
 				constructor: function(){
 					this.foo = "blah";
 				}
@@ -92,7 +94,7 @@ define(["../..", "doh"], function(dojo, doh){
 		},
 		function inheritedCall(t){
 			var foo = "xyzzy";
-			dojo.declare("tests._base.declare.tmp12", null, {
+			declare("tests._base.declare.tmp12", null, {
 				foo: "thonk",
 				bar: function(arg1, arg2){
 					if(arg1){
@@ -103,7 +105,7 @@ define(["../..", "doh"], function(dojo, doh){
 					}
 				}
 			});
-			dojo.declare("tests._base.declare.tmp13", tests._base.declare.tmp12, {
+			declare("tests._base.declare.tmp13", tests._base.declare.tmp12, {
 				constructor: function(){
 					this.foo = "blah";
 				}
@@ -120,7 +122,7 @@ define(["../..", "doh"], function(dojo, doh){
 		},
 		function inheritedExplicitCall(t){
 			var foo = "xyzzy";
-			dojo.declare("tests._base.declare.tmp14", null, {
+			declare("tests._base.declare.tmp14", null, {
 				foo: "thonk",
 				bar: function(arg1, arg2){
 					if(arg1){
@@ -131,7 +133,7 @@ define(["../..", "doh"], function(dojo, doh){
 					}
 				}
 			});
-			dojo.declare("tests._base.declare.tmp15", tests._base.declare.tmp14, {
+			declare("tests._base.declare.tmp15", tests._base.declare.tmp14, {
 				constructor: function(){
 					this.foo = "blah";
 				},
@@ -153,25 +155,25 @@ define(["../..", "doh"], function(dojo, doh){
 			t.is("trousers", foo);
 		},
 		function inheritedMixinCalls(t){
-			dojo.declare("tests._base.declare.tmp16", null, {
+			declare("tests._base.declare.tmp16", null, {
 				foo: "",
 				bar: function(){
 					this.foo += "tmp16";
 				}
 			});
-			dojo.declare("tests._base.declare.mixin16", null, {
+			declare("tests._base.declare.mixin16", null, {
 				bar: function(){
 					this.inherited(arguments);
 					this.foo += ".mixin16";
 				}
 			});
-			dojo.declare("tests._base.declare.mixin17", tests._base.declare.mixin16, {
+			declare("tests._base.declare.mixin17", tests._base.declare.mixin16, {
 				bar: function(){
 					this.inherited(arguments);
 					this.foo += ".mixin17";
 				}
 			});
-			dojo.declare("tests._base.declare.tmp17", [tests._base.declare.tmp16, tests._base.declare.mixin17], {
+			declare("tests._base.declare.tmp17", [tests._base.declare.tmp16, tests._base.declare.mixin17], {
 				bar: function(){
 					this.inherited(arguments);
 					this.foo += ".tmp17";
@@ -183,25 +185,25 @@ define(["../..", "doh"], function(dojo, doh){
 		},
 		function mixinPreamble(t){
 			var passed = false;
-			dojo.declare("tests._base.declare.tmp16", null);
+			declare("tests._base.declare.tmp16", null);
 			new tests._base.declare.tmp16({ preamble: function(){ passed = true; } });
 			t.t(passed);
 		},
 
 		function basicMixin(t){
 			// testing if a plain Class-like object can be inherited
-			// by dojo.declare
+			// by declare
 			var d = new doh.Deferred;
 
 			var Thing = function(args){
-				dojo.mixin(this, args);
+				lang.mixin(this, args);
 			};
 			Thing.prototype.method = function(){
 				t.t(true);
 				d.callback(true);
 			};
 
-			dojo.declare("Thinger", Thing, {
+			declare("Thinger", Thing, {
 				method: function(){
 					this.inherited(arguments);
 				}
@@ -215,14 +217,14 @@ define(["../..", "doh"], function(dojo, doh){
 
 		function mutatedMethods(t){
 			// testing if methods can be mutated (within a reason)
-			dojo.declare("tests._base.declare.tmp18", null, {
+			declare("tests._base.declare.tmp18", null, {
 				constructor: function(){ this.clear(); },
 				clear: function(){ this.flag = 0; },
 				foo: function(){ ++this.flag; },
 				bar: function(){ ++this.flag; },
 				baz: function(){ ++this.flag; }
 			});
-			dojo.declare("tests._base.declare.tmp19", tests._base.declare.tmp18, {
+			declare("tests._base.declare.tmp19", tests._base.declare.tmp18, {
 				foo: function(){ ++this.flag; this.inherited(arguments); },
 				bar: function(){ ++this.flag; this.inherited(arguments); },
 				baz: function(){ ++this.flag; this.inherited(arguments); }
@@ -235,8 +237,8 @@ define(["../..", "doh"], function(dojo, doh){
 			x.clear();
 			t.is(0, x.flag);
 			var a = 0;
-			// dojo.connect() on a prototype method
-			dojo.connect(tests._base.declare.tmp19.prototype, "foo", function(){ a = 1; });
+			// aspect.after() on a prototype method
+			aspect.after(tests._base.declare.tmp19.prototype, "foo", function(){ a = 1; });
 			x.foo();
 			t.is(2, x.flag);
 			t.is(1, a);
@@ -267,22 +269,22 @@ define(["../..", "doh"], function(dojo, doh){
 
 		function modifiedInstance(t){
 			var stack;
-			dojo.declare("tests._base.declare.tmp20", null, {
+			declare("tests._base.declare.tmp20", null, {
 				foo: function(){ stack.push(20); }
 			});
-			dojo.declare("tests._base.declare.tmp21", null, {
+			declare("tests._base.declare.tmp21", null, {
 				foo: function(){
 					this.inherited(arguments);
 					stack.push(21);
 				}
 			});
-			dojo.declare("tests._base.declare.tmp22", tests._base.declare.tmp20, {
+			declare("tests._base.declare.tmp22", tests._base.declare.tmp20, {
 				foo: function(){
 					this.inherited(arguments);
 					stack.push(22);
 				}
 			});
-			dojo.declare("tests._base.declare.tmp23",
+			declare("tests._base.declare.tmp23",
 						[tests._base.declare.tmp20, tests._base.declare.tmp21], {
 				foo: function(){
 					this.inherited(arguments);
@@ -305,8 +307,8 @@ define(["../..", "doh"], function(dojo, doh){
 			b.foo();
 			t.is([20, 21, 22], stack);
 
-			dojo.mixin(a, c);
-			dojo.mixin(b, c);
+			lang.mixin(a, c);
+			lang.mixin(b, c);
 
 			stack = [];
 			a.foo();
@@ -319,12 +321,12 @@ define(["../..", "doh"], function(dojo, doh){
 
 		function duplicatedBase(t){
 			var stack;
-			var A = dojo.declare(null, {
+			var A = declare(null, {
 				constructor: function(){
 					stack.push(1);
 				}
 			});
-			var B = dojo.declare([A, A, A], {
+			var B = declare([A, A, A], {
 				constructor: function(){
 					stack.push(2);
 				}
@@ -339,22 +341,22 @@ define(["../..", "doh"], function(dojo, doh){
 
 		function indirectlyDuplicatedBase(t){
 			var stack;
-			var A = dojo.declare(null, {
+			var A = declare(null, {
 				constructor: function(){
 					stack.push(1);
 				}
 			});
-			var B = dojo.declare(A, {
+			var B = declare(A, {
 				constructor: function(){
 					stack.push(2);
 				}
 			});
-			var C = dojo.declare([A, B], {
+			var C = declare([A, B], {
 				constructor: function(){
 					stack.push(3);
 				}
 			});
-			var D = dojo.declare([B, A], {
+			var D = declare([B, A], {
 				constructor: function(){
 					stack.push(4);
 				}
@@ -369,12 +371,12 @@ define(["../..", "doh"], function(dojo, doh){
 
 		function wrongMultipleInheritance(t){
 			var stack;
-			var A = dojo.declare([], {
+			var A = declare([], {
 				constructor: function(){
 					stack.push(1);
 				}
 			});
-			var B = dojo.declare([A], {
+			var B = declare([A], {
 				constructor: function(){
 					stack.push(2);
 				}
@@ -388,14 +390,14 @@ define(["../..", "doh"], function(dojo, doh){
 		},
 
 		function impossibleBases(t){
-			var A = dojo.declare(null);
-			var B = dojo.declare(null);
-			var C = dojo.declare([A, B]);
-			var D = dojo.declare([B, A]);
+			var A = declare(null);
+			var B = declare(null);
+			var C = declare([A, B]);
+			var D = declare([B, A]);
 
 			var flag = false;
 			try{
-				var E = dojo.declare([C, D]);
+				var E = declare([C, D]);
 			}catch(e){
 				flag = true;
 			}
@@ -409,7 +411,7 @@ define(["../..", "doh"], function(dojo, doh){
 				this.noNew_Value = 'instance value';
 			}
 
-			var g = dojo.global;
+			var g = kernel.global;
 			// this value will remain unchanged if the code for
 			// calling a constructor without 'new' works correctly.
 			g.noNew_Value = 'global value';
@@ -423,30 +425,30 @@ define(["../..", "doh"], function(dojo, doh){
 			}
 
 			// There are three different functions that might be
-			// created by dojo.declare(), so I need to test all
+			// created by declare(), so I need to test all
 			// three.
 
 			// 1. Class with manual-chained constructor
 			noNewTest(
-				dojo.declare(null, {
+				declare(null, {
 					constructor: noNewConstructor,
 					'-chains-': {constructor: 'manual'}
 				})
 			);
 
 			// 2. Class with no superclasses
-			var A = dojo.declare(null, {
+			var A = declare(null, {
 				constructor: noNewConstructor
 			});
 			noNewTest(A);
 
 			// 3. Class with at least one superclass
-			noNewTest(dojo.declare(A));
+			noNewTest(declare(A));
 
 			// Make sure multiple inheritance call works
-			var B = dojo.declare(A);
-			var C = dojo.declare(null, { ctest: function(){return true;} });
-			var D = dojo.declare([A, B, C], { dtest: function(){return true;} });
+			var B = declare(A);
+			var C = declare(null, { ctest: function(){return true;} });
+			var D = declare([A, B, C], { dtest: function(){return true;} });
 			noNewTest(D);
 			// make sure I get the test functions from
 			// all superclasses
@@ -462,6 +464,29 @@ define(["../..", "doh"], function(dojo, doh){
 			var obj = noNewClasses.D();
 			t.is(obj.noNew_Value, 'instance value');
 			t.is(noNewClasses.noNew_Value, 'unchanged');
+		},
+
+		function createSubclass(t){
+			var A = dojo.declare(null, {
+				foo: "thonk"
+			});
+			var B = dojo.declare(null, {
+			});
+			var C = dojo.declare(null, {
+				bar: "thonk"
+			});
+			var D1 = A.createSubclass([B, C], {
+				constructor: function(){
+					this.foo = "blah";
+				}
+			});
+			var D2 = A.createSubclass([B, C]);
+			var d1 = new D1();
+			var d2 = new D2();
+			t.is("blah", d1.foo);
+			t.is("thonk", d2.foo);
+			t.is("thonk", d1.bar);
+			t.is("thonk", d2.bar);
 		}
 
 		// FIXME: there are still some permutations to test like:
diff --git a/dojo/tests/_base/fx.html b/dojo/tests/_base/fx.html
index 7361855..50fb40f 100644
--- a/dojo/tests/_base/fx.html
+++ b/dojo/tests/_base/fx.html
@@ -6,7 +6,12 @@
 		</style>
 		<script type="text/javascript" src="../../dojo.js"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
+			require([
+				"doh",
+				"dojo/aspect", "dojo/_base/fx", "dojo/_base/declare",
+				"dojo/dom", "dojo/dom-geometry", "dojo/dom-style",
+				"dojo/_base/lang", "dojo/domReady!"
+			], function(doh, aspect, baseFx, declare, dom, domGeom, domStyle, lang){
 				var duration = 500;
 				var timeout = 750;
 				doh.register("t", [
@@ -14,12 +19,12 @@
 						name: "fadeOut",
 						timeout: timeout,
 						runTest: function(){
-							var opacity = dojo.style('foo', 'opacity');
+							var opacity = domStyle.get('foo', 'opacity');
 							doh.is(1, opacity);
-							var anim = dojo.fadeOut({ node: 'foo', duration: duration });
+							var anim = baseFx.fadeOut({ node: 'foo', duration: duration });
 							var d = new doh.Deferred();
-							dojo.connect(anim, "onEnd", d.getTestCallback(function(){
-								var opacity = dojo.style('foo', 'opacity');
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
+								var opacity = domStyle.get('foo', 'opacity');
 								var elapsed = (new Date()) - anim._start;
 								doh.is(0, opacity);
 								doh.t(elapsed >= duration);
@@ -33,12 +38,12 @@
 						name: "fadeIn",
 						timeout: timeout,
 						runTest: function(){
-							var opacity = dojo.style('foo', 'opacity');
+							var opacity = domStyle.get('foo', 'opacity');
 							doh.is(0, opacity);
-							var anim = dojo.fadeIn({ node: 'foo', duration: duration });
+							var anim = baseFx.fadeIn({ node: 'foo', duration: duration });
 							var d = new doh.Deferred();
-							dojo.connect(anim, "onEnd", d.getTestCallback(function(){
-								var opacity = dojo.style('foo', 'opacity');
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
+								var opacity = domStyle.get('foo', 'opacity');
 								var elapsed = (new Date()) - anim._start;
 								doh.is(1, opacity);
 								doh.t(elapsed >= duration);
@@ -53,7 +58,7 @@
 						timeout: timeout,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var anim = dojo.animateProperty({ 
+							var anim = baseFx.animateProperty({ 
 								node: "foo", 
 								duration: duration,
 								properties: { 
@@ -61,7 +66,7 @@
 									backgroundColor: 	{ start: "white", end: "black" } 
 								} 
 							});
-							dojo.connect(anim, "onEnd", anim, function(){
+							aspect.after(anim, "onEnd", function(){
 								d.callback(true);
 							});
 							anim.play();
@@ -73,7 +78,7 @@
 						timeout: timeout,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var anim = dojo.animateProperty({ 
+							var anim = baseFx.animateProperty({ 
 								node: "foo", 
 								duration: duration,
 								properties: { 
@@ -82,7 +87,7 @@
 									letterSpacing: 		{ start: 0, end: 10 } 
 								} 
 							});
-							dojo.connect(anim, "onEnd", anim, function(){
+							aspect.after(anim, "onEnd", function(){
 								d.callback(true);
 							});
 							anim.play();
@@ -93,11 +98,11 @@
 						name: "animateHeight",
 						timeout: timeout,
 						runTest: function(t){
-							dojo.byId("foo").style.height = "";
-							var startHeight = dojo.marginBox("foo").h; 
+							dom.byId("foo").style.height = "";
+							var startHeight = domGeom.getMarginBox("foo").h;
 							var endHeight = Math.round(startHeight / 2);
 							
-							var anim = dojo.animateProperty({
+							var anim = baseFx.animateProperty({
 								node: "foo",
 								properties: { height: { end: endHeight } },
 								duration: duration
@@ -105,10 +110,10 @@
 
 							var d = new doh.Deferred();
 
-							dojo.connect(anim, "onEnd", anim, d.getTestCallback(function(){
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
 								var elapsed = (new Date().valueOf()) - anim._startTime;
 								doh.t(elapsed >= duration);
-								var height = dojo.marginBox("foo").h; 
+								var height = domGeom.getMarginBox("foo").h;
 								doh.is(height, endHeight);
 							}));
 							
@@ -120,11 +125,11 @@
 						name: "animateHeight_defaults_syntax",
 						timeout: timeout,
 						runTest: function(){
-							dojo.byId("foo").style.height = "";
-							var startHeight = dojo.marginBox("foo").h; 
+							dom.byId("foo").style.height = "";
+							var startHeight = domGeom.getMarginBox("foo").h;
 							var endHeight = Math.round(startHeight / 2);
 							
-							var anim = dojo.animateProperty({
+							var anim = baseFx.animateProperty({
 								node: "foo",
 								properties: { height: endHeight },
 								duration: duration
@@ -132,10 +137,10 @@
 
 							var d = new doh.Deferred();
 
-							dojo.connect(anim, "onEnd", anim, d.getTestCallback(function(){
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
 								var elapsed = (new Date().valueOf()) - anim._startTime;
 								doh.t(elapsed >= duration);
-								var height = dojo.marginBox("foo").h; 
+								var height = domGeom.getMarginBox("foo").h;
 								doh.is(height, endHeight);
 							}));
 							
@@ -147,12 +152,12 @@
 						name: "inlineWidth",
 						timeout: timeout,
 						runTest: function(){
-							dojo.style("foo", "display", "none");
-							dojo.style("bar", "display", "");
-							var startWidth = dojo.marginBox("bar").w; 
+							domStyle.set("foo", "display", "none");
+							domStyle.set("bar", "display", "");
+							var startWidth = domGeom.getMarginBox("bar").w;
 							var endWidth = Math.round(startWidth / 2);
 							
-							var anim = dojo.animateProperty({
+							var anim = baseFx.animateProperty({
 								node: "bar",
 								properties: { width: endWidth },
 								duration: duration
@@ -160,10 +165,10 @@
 
 							var d = new doh.Deferred();
 
-							dojo.connect(anim, "onEnd", anim, d.getTestCallback(function(){
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
 								var elapsed = (new Date().valueOf()) - anim._startTime;
 								doh.t(elapsed >= duration);
-								doh.is(dojo.marginBox("bar").w, endWidth);
+								doh.is(domGeom.getMarginBox("bar").w, endWidth);
 							}));
 							
 							anim.play();
@@ -175,14 +180,14 @@
 						timeout: timeout+500,
 						runTest: function(){
 							var id = "baz";
-							dojo.style("bar", "display", "none");
-							dojo.style(id, "display", "");
+							domStyle.set("bar", "display", "none");
+							domStyle.set(id, "display", "");
 							var kickoff = new Date().valueOf();
-							var startWidth = dojo.marginBox(id).w; 
+							var startWidth = domGeom.getMarginBox(id).w;
 							var endWidth = Math.round(startWidth / 2);
 
 							var d = new doh.Deferred();
-							var anim = dojo.anim(
+							var anim = baseFx.anim(
 								id, 
 								{ 
 									width: endWidth,
@@ -199,10 +204,10 @@
 									doh.t(curTime >= (kickoff+duration+500-5),
 										"curTime >= (kickoff+duration+500-5): " + curTime + " >= (" + kickoff + "+" + duration + "+500-5)");
 
-									doh.is(dojo.marginBox(id).w, endWidth, 
+									doh.is(domGeom.getMarginBox(id).w, endWidth,
 										"width matches endWidth ");
 
-									doh.is(0, dojo.style(id, "opacity"), "opacity");
+									doh.is(0, domStyle.get(id, "opacity"), "opacity");
 								}),
 								500
 							);
@@ -214,17 +219,17 @@
 						timeout: 1000,
 						runTest: function(){
 							var id = "thud";
-							dojo.style("baz", "display", "none");
-							dojo.style(id, "display", "");
-							var startWidth = dojo.marginBox(id).w; 
+							domStyle.set("baz", "display", "none");
+							domStyle.set(id, "display", "");
+							var startWidth = domGeom.getMarginBox(id).w;
 							var endWidth = Math.round(startWidth / 2);
 
 							var d = new doh.Deferred();
-							var anim = dojo.anim(id, { width: endWidth });
-							dojo.connect(anim, "onEnd", d.getTestCallback(function(){
+							var anim = baseFx.anim(id, { width: endWidth });
+							aspect.after(anim, "onEnd", d.getTestCallback(function(){
 								var elapsed = (new Date().valueOf()) - anim._startTime;
-								doh.t(elapsed >= dojo.Animation.prototype.duration); // the default
-								doh.is(dojo.marginBox(id).w, endWidth);
+								doh.t(elapsed >= baseFx.Animation.prototype.duration); // the default
+								doh.is(domGeom.getMarginBox(id).w, endWidth);
 							}));
 							anim.play();
 							return d;
@@ -237,7 +242,7 @@
 						runTest: function(){
 							
 							var d = new doh.Deferred();
-							dojo.animateProperty({
+							baseFx.animateProperty({
 								node: "thud",
 								properties:{
 									// also testing node passed to property function
@@ -261,7 +266,7 @@
 						runTest: function(){
 							
 							var d = new doh.Deferred();
-							dojo.animateProperty({
+							baseFx.animateProperty({
 								node: "thud",
 								properties:{
 									// also testing node passed to property function
@@ -288,7 +293,7 @@
 						runTest: function(){
 							
 							var d = new doh.Deferred();
-							dojo.animateProperty({
+							baseFx.animateProperty({
 								node: "thud",
 								properties:{
 									width: { 
@@ -315,7 +320,7 @@
 						runTest: function(){
 							
 							var d = new doh.Deferred();
-							dojo.animateProperty({
+							baseFx.animateProperty({
 								node: "thud",
 								properties:{
 									width: { 
@@ -343,7 +348,7 @@
 						runTest: function(){
 							
 							var d = new doh.Deferred();
-							dojo.animateProperty({
+							baseFx.animateProperty({
 								node: "thud",
 								properties:{
 									width: 200
@@ -366,7 +371,7 @@
 						runTest: function(){
 
 							var d = new doh.Deferred();
-							dojo.animateProperty({
+							baseFx.animateProperty({
 								node: "thud",
 								properties:{
 									width: 200
@@ -386,7 +391,7 @@
 						timeout:1000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							dojo.declare("fx.Thinger", null, {
+							declare("fx.Thinger", null, {
 								constructor: function(a){
 									this.bar = 10;
 								},
@@ -395,12 +400,12 @@
 								}
 							});
 							
-							dojo.declare("fx.ThingerToo", fx.Thinger, {
+							declare("fx.ThingerToo", fx.Thinger, {
 								method: function(){
 									var a = arguments;
-									dojo.fadeIn({
+									baseFx.fadeIn({
 										node:"thud",
-										onEnd: dojo.hitch(this, function(){
+										onEnd: lang.hitch(this, function(){
 											// to call inherited in a callback, stash the orig 'arguments'
 											this.inherited(a);
 										}),
@@ -423,23 +428,23 @@
 
 							// testing vanilla inheritance
 							fx.NThinger = function(args){
-								dojo.mixin(this, args);
+								lang.mixin(this, args);
 							};
 							fx.NThinger.prototype.method = function(){
 								d.callback(true);
 							};
 							
 							
-							dojo.declare("fx.ThingerThree", fx.NThinger, {
+							declare("fx.ThingerThree", fx.NThinger, {
 								method: function(){
-									var x = dojo.fadeOut({
+									var x = baseFx.fadeOut({
 										node:"thud",
 										duration:100
 									});
 									
-									// to use with connect, pass a newArgs (arguements again) to override any 
+									// to use with connect, pass a newArgs (arguments again) to override any
 									// possible references passed from the orig function.
-									dojo.connect(x, "onEnd", dojo.hitch(this, "inherited", arguments, arguments));
+									aspect.after(x, "onEnd", lang.hitch(this, "inherited", arguments, arguments));
 									
 									x.play();
 								}
@@ -490,8 +495,8 @@
 	<body>
 		<h1>testing Core FX</h1>
 		<form name="testForm">
-		<input type="button" onClick="dojo.fadeOut({ node: 'foo', duration: 1000 }).play()" value="fade out"/>
-		<input type="button" onClick="dojo.fadeIn({ node: 'foo', duration: 1000 }).play()" value="fade in"/>
+		<input type="button" onClick="baseFx.fadeOut({ node: 'foo', duration: 1000 }).play()" value="fade out"/>
+		<input type="button" onClick="baseFx.fadeIn({ node: 'foo', duration: 1000 }).play()" value="fade in"/>
 		</form>
 		<div id="foo" class="box" style="float: left;">
 			<p>
diff --git a/dojo/tests/_base/fx.js b/dojo/tests/_base/fx.js
index 6fd377c..78fdd86 100644
--- a/dojo/tests/_base/fx.js
+++ b/dojo/tests/_base/fx.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests._base.fx", require.toUrl("./fx.html"), 15000);
 	}
diff --git a/dojo/tests/_base/fx_delay.html b/dojo/tests/_base/fx_delay.html
index c2a1cd9..fd2c58c 100644
--- a/dojo/tests/_base/fx_delay.html
+++ b/dojo/tests/_base/fx_delay.html
@@ -5,13 +5,11 @@
 </style>
 <script type="text/javascript" src="../../dojo.js"></script>
 <script type="text/javascript">
-dojo.require("dojo._base.fx");
-dojo.require("dojo._base.html");
-dojo.addOnLoad(function(){
-	var box = dojo.byId("box");
-	dojo.connect(box, "onclick", function(){
-		dojo.style(box, "opacity", "0");
-		dojo.fadeIn({node:box, delay:1}).play();
+require(["dojo/dom", "dojo/_base/fx", "dojo/on", "dojo/dom-style", "dojo/domReady!"], function(dom, baseFx, on, domStyle){
+	var box = dom.byId("box");
+	on(box, "click", function(){
+		domStyle.set(box, "opacity", "0");
+		baseFx.fadeIn({node:box, delay:1}).play();
 	});
 });
 </script>
diff --git a/dojo/tests/_base/html.html b/dojo/tests/_base/html.html
index b26906b..02ce9ad 100644
--- a/dojo/tests/_base/html.html
+++ b/dojo/tests/_base/html.html
@@ -12,7 +12,7 @@
 		</style>
 		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
+			require(["dojo", "doh", "dojo/sniff", "dojo/domReady!"], function(dojo, doh, has){
 
 				function getIframeDocument(/*DOMNode*/iframeNode){
 					//summary: Returns the document object associated with the iframe DOM Node argument.
@@ -182,9 +182,9 @@
 								var def = new doh.Deferred();
 								setTimeout(function(){ try{
 									var oldLtr = dojo._isBodyLtr();
-									var oldQuirks = dojo.isQuirks;
+									var oldQuirks = has("quirks");
 									dojo.withGlobal(dojo.byId('iframe_quirks').win, function(){
-										doh.t(dojo.isQuirks, "isQuirks == true in quirks/iframe");
+										doh.t(has("quirks"), "has('quirks') == true in quirks/iframe");
 										doh.f(dojo._isBodyLtr(), "isBodyLtr == false in RTL/iframe");
 										var pos = dojo.position('iframe_00_quirks');
 										doh.t(pos.x===0, "quirks iframe element x == 0 (x,y,w,h="+pos.x+","+pos.y+","+pos.w+","+pos.h+")");
@@ -193,7 +193,7 @@
 										doh.t(pos.h>0, "quirks iframe element h > 0 (x,y,w,h="+pos.x+","+pos.y+","+pos.w+","+pos.h+")");
 									});
 									dojo.withGlobal(dojo.byId('iframe_strict').win, function(){
-										doh.f(dojo.isQuirks, "isQuirks == false in strict/ifraee");
+										doh.f(has("quirks"), "has('quirks') == false in strict/ifraee");
 										doh.f(dojo._isBodyLtr(), "isBodyLtr == false in RTL/iframe");
 										var pos = dojo.position('iframe_00_strict');
 										doh.t(pos.x===0, "strict iframe element x == 0 (x,y,w,h="+pos.x+","+pos.y+","+pos.w+","+pos.h+")");
@@ -202,7 +202,7 @@
 										doh.t(pos.h>0, "strict iframe element h > 0 (x,y,w,h="+pos.x+","+pos.y+","+pos.w+","+pos.h+")");
 									});
 									doh.t(!oldLtr == !dojo._isBodyLtr(), "isBodyLtr restored after withGlobal");
-									doh.t(!oldQuirks == !dojo.isQuirks, "isQuirks restored after withGlobal");
+									doh.is(oldQuirks, has("quirks"), "has('quirks') restored after withGlobal");
 									def.callback(true);
 								}catch(e){ def.errback(e); } }, 1000);
 								return def;
@@ -354,7 +354,7 @@
 							doh.f(dojo.hasAttr("div-no-tabindex", "tabIndex"));
 							doh.t(dojo.attr("div-no-tabindex", "tabIndex") <= 0);
 							doh.t(dojo.hasAttr("div-tabindex-minus-1", "tabIndex"));
-							if(!dojo.isOpera){
+							if(!has("opera")){
 								// Opera (at least <= 9) does not support tabIndex="-1"
 								doh.is(-1, dojo.attr("div-tabindex-minus-1", "tabIndex"));
 							}
@@ -363,13 +363,13 @@
 							doh.is(1, dojo.attr("div-tabindex-1", "tabIndex"));
 						},
 						function getTabindexInput(t){
-							if(!dojo.isIE || dojo.isIE >= 8){
+							if(!has("ie") || has("ie") >= 8){
 								// IE6/7 always reports tabIndex as defined
 								doh.f(dojo.hasAttr("input-no-tabindex", "tabIndex"));
 								doh.f(dojo.attr("input-no-tabindex", "tabIndex"));
 							}
 							doh.t(dojo.hasAttr("input-tabindex-minus-1", "tabIndex"));
-							if(!dojo.isOpera){
+							if(!has("opera")){
 								// Opera (at least <= 9) does not support tabIndex="-1"
 								doh.is(-1, dojo.attr("input-tabindex-minus-1", "tabIndex"));
 							}
@@ -381,7 +381,7 @@
 							var div = document.createElement("div");
 							doh.is(null, dojo.attr(div, "tabIndex"));
 							dojo.attr(div, "tabIndex", -1);
-							if(!dojo.isOpera){
+							if(!has("opera")){
 								// Opera (at least <= 9) does not support tabIndex="-1"
 								doh.is(-1, dojo.attr(div, "tabIndex"));
 							}
@@ -394,7 +394,7 @@
 							var input = document.createElement("input");
 							doh.t(dojo.attr(input, "tabIndex") <= 0);
 							dojo.attr(input, "tabIndex", -1);
-							if(!dojo.isOpera){
+							if(!has("opera")){
 								// Opera (at least <= 9) does not support tabIndex="-1"
 								doh.is(-1, dojo.attr(input, "tabIndex"));
 							}
@@ -433,7 +433,8 @@
 							doh.is(false, dojo.attr(input, "readonly"));
 						},
 						function attr_map(t){
-							var input = document.createElement("input");
+							var input = document.createElement("input"),
+								input2 = document.createElement("input");
 							var ctr= 0;
 							dojo.attr(input, {
 								"class": "thinger blah",
@@ -444,8 +445,9 @@
 								}
 							});
 							dojo.body().appendChild(input);
+							dojo.body().appendChild(input2);
 							doh.is(1, dojo.attr(input, "tabIndex"), "tabIndex");
-							if(!dojo.isIE || dojo.isIE > 7){
+							if(!has("ie") || has("ie") > 7){
 								// IE6/7 treats type="text" as missing, even if it was
 								// explicitly specified
 								doh.is("text", dojo.attr(input, "type"), "type");
@@ -457,23 +459,27 @@
 							input.focus();
 							setTimeout(def.getTestErrback(function(){
 								doh.is(1, ctr, "onfocus ctr == 1");
-								input.blur();
-								input.focus();
-								setTimeout(def.getTestCallback(function(){
-									doh.is(2, ctr, "onfocus ctr == 2");
+								input2.focus();
+								setTimeout(def.getTestErrback(function(){
+									input.focus();
+									setTimeout(def.getTestCallback(function(){
+										doh.is(2, ctr, "onfocus ctr == 2");
+									}), 10);
 								}), 10);
 							}), 10);
 							return def;
 						},
 						function attr_reconnect(t){
-							var input = document.createElement("input");
+							var input = document.createElement("input"),
+								input2 = document.createElement("input");
 							var ctr = 0;
 							dojo.attr(input, "type", "text");
 							dojo.attr(input, "onfocus", function(e){ ctr++; });
 							dojo.attr(input, "onfocus", function(e){ ctr++; });
 							dojo.attr(input, "onfocus", function(e){ ctr++; });
 							dojo.body().appendChild(input);
-							if(!dojo.isIE || dojo.isIE > 7){
+							dojo.body().appendChild(input2);
+							if(!has("ie") || has("ie") > 7){
 								// IE6/7 treats type="text" as missing, even if it was
 								// explicitly specified
 								doh.is("text", dojo.attr(input, "type"));
@@ -482,11 +488,13 @@
 							var def = new doh.Deferred();
 							input.focus();
 							setTimeout(def.getTestErrback(function(){
-								doh.is(1, ctr);
-								input.blur();
-								input.focus();
-								setTimeout(def.getTestCallback(function(){
-									doh.is(2, ctr);
+								doh.is(1, ctr, "onfocus ctr == 1");
+								input2.focus();
+								setTimeout(def.getTestErrback(function(){
+									input.focus();
+									setTimeout(def.getTestCallback(function(){
+										doh.is(2, ctr, "onfocus ctr == 2");
+									}), 10);
 								}), 10);
 							}), 10);
 							return def;
@@ -519,7 +527,7 @@
 							// create label with no for attribute make sure requesting
 							// it as for and html for returns null
 							var label = document.createElement("label");
-							if(!dojo.isIE){
+							if(!has("ie")){
 								// IE always assumes that "for" is present
 								doh.f(dojo.attr(label, "for"));
 								doh.f(dojo.attr(label, "htmlFor"));
@@ -538,7 +546,7 @@
 							var labelNoFor = dojo.byId("label-no-for");
 							// make sure testing if has attribute using for or htmlFor 
 							// both return null when no value set
-							if(!dojo.isIE){
+							if(!has("ie")){
 								// IE always assumes that "for" is present
 								doh.f(dojo.hasAttr(labelNoFor, "for"));
 								doh.f(dojo.hasAttr(labelNoFor, "htmlFor"));
@@ -618,6 +626,48 @@
 					});
 				});
 
+				doh.register("t",
+					[
+						function emptySvg(t){
+							dojo.empty(dojo.byId("surface"));
+							doh.f(!!dojo.byId("surface").firstChild, "svg firstChild");
+						},
+						function destroySvg(t){
+							dojo.destroy(dojo.byId("surface"));
+							doh.f(!!dojo.byId("surface"), "svg byId");
+						},
+						function emptyObject(t){
+							dojo.empty(dojo.byId("objectToEmpty"));
+							doh.f(!!dojo.byId("objectToEmpty").firstChild, "object firstChild");
+						},
+						function destroyObject(t){
+							dojo.destroy(dojo.byId("objectToEmpty"));
+							doh.f(!!dojo.byId("objectToEmpty"), "object byId");
+						},
+						function destroyIframe(t){
+							dojo.destroy(dojo.byId("iframeToDestroy"));
+							doh.f(!!dojo.byId("iframeToDestroy"), "iframe byId");
+						},
+						function destroyDivNotInDOM(t){
+							var p = dojo.byId("divToRemoveFromDOM");
+							var n = dojo.byId("divToDestroy");
+							p = p.parentNode.removeChild(p);
+							doh.f(!!dojo.byId("divToRemoveFromDOM"), "div byId");
+							doh.t(!!p.firstChild, "div child 1");
+							doh.is(p.firstChild, n, "div 1st child");
+							doh.isNot(p.firstChild, p.lastChild, "div 1st child");
+							dojo.destroy(n);
+							doh.t(!!p.firstChild, "div child 2");
+							doh.isNot(p.firstChild, n, "div 2nd child");
+							doh.is(p.firstChild, p.lastChild, "div 2nd child");
+							dojo.empty(p);
+							doh.f(!!p.firstChild, "div child 3");
+							dojo.destroy(p);
+							doh.t(true, "no exception thrown");
+						}
+					]
+				);
+
 				doh.runOnLoad();
 			});
 		</script>
@@ -855,8 +905,25 @@
 		<div id="iframeContainer"></div>
 
 		<!-- SVG element to test dojo.getComputedStyle on IE9 (#14103) -->
-		<svg id="surface" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
-			<rect id="rect1" fill="rgb(255, 0, 0)" x="0" y="0" width="80" height="60" ry="0" rx="0" fill-rule="evenodd"/>
-		</svg>
+		<!-- SVG element to test empty -->
+		<svg id="surface" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px"
+			><rect id="rect1" fill="rgb(255, 0, 0)" x="0" y="0" width="80" height="60" ry="0" rx="0" fill-rule="evenodd"
+		/></svg>
+
+		<!-- OBJECT element to test empty -->
+		<object width="500" height="500" id="objectToEmpty" data="data:application/x-silverlight," type="application/x-silverlight"
+			><param name="background" value="transparent"
+		/></object>
+
+		<!-- IFRAME element to test destroy -->
+		<iframe id="iframeToDestroy" src="about:blank"
+			><span></span
+		></iframe>
+
+		<!-- DIV element to test destroy of element not in the DOM -->
+		<div id="divToRemoveFromDOM"
+			><div id="divToDestroy"></div
+			><div></div
+		></div>
 	</body>
 </html>
diff --git a/dojo/tests/_base/html.js b/dojo/tests/_base/html.js
index bc95808..623ccc3 100644
--- a/dojo/tests/_base/html.js
+++ b/dojo/tests/_base/html.js
@@ -1,12 +1,13 @@
-define(["doh", "require"], function(doh, require){
+define(["dojo/sniff", "doh/main", "require"], function(has, doh, require){
 	if(doh.isBrowser){
 		doh.register("tests._base.html", require.toUrl("./html.html"), 15000);
 		doh.register("tests._base.html_id", require.toUrl("./html_id.html"), 15000);
 		doh.register("tests._base.html_element", require.toUrl("./html_element.html"), 15000);
 		doh.register("tests._base.html_rtl", require.toUrl("./html_rtl.html"), 15000);
-		doh.register("tests._base.html_quirks", require.toUrl("./html_quirks.html"), 15000);
+		// IE9+ cannot handle loading quirks mode documents inside the test runner, see #14321
+		has("ie") >= 9 || doh.register("tests._base.html_quirks", require.toUrl("./html_quirks.html"), 15000);
 		doh.register("tests._base.html_box", require.toUrl("./html_box.html"), 35000);
-		doh.register("tests._base.html_box_quirks", require.toUrl("./html_box_quirks.html"), 35000);
+		has("ie") >= 9 || doh.register("tests._base.html_box_quirks", require.toUrl("./html_box_quirks.html"), 35000);
 		doh.register("tests._base.html_isBodyLtr", require.toUrl("./html_isBodyLtr.html"), 35000);
 		doh.register("tests._base.html_docScroll", require.toUrl("./html_docScroll.html"), 35000);
 	}
diff --git a/dojo/tests/_base/html_quirks.html b/dojo/tests/_base/html_quirks.html
index 097cf98..6ee6be3 100644
--- a/dojo/tests/_base/html_quirks.html
+++ b/dojo/tests/_base/html_quirks.html
@@ -9,7 +9,7 @@
 		</style>
 		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/domReady!"], function(dojo, doh){
+			require(["dojo", "doh", "dojo/sniff", "dojo/domReady!"], function(dojo, doh, has){
 				doh.register("t", 
 					[
 						"t.is(100, dojo.marginBox('sq100').w);",
@@ -66,7 +66,7 @@
 						}
 					]
 				);
-				if(dojo.isIE){ 
+				if(has("ie") <= 9){
 					// IE collapses padding in quirks mode. We just report on it.
 					doh.register("t", 
 						[
@@ -135,6 +135,48 @@
 					);
 				}
 
+				doh.register("t",
+					[
+						function emptySvg(t){
+							dojo.empty(dojo.byId("surface"));
+							doh.f(!!dojo.byId("surface").firstChild, "svg firstChild");
+						},
+						function destroySvg(t){
+							dojo.destroy(dojo.byId("surface"));
+							doh.f(!!dojo.byId("surface"), "svg byId");
+						},
+						function emptyObject(t){
+							dojo.empty(dojo.byId("objectToEmpty"));
+							doh.f(!!dojo.byId("objectToEmpty").firstChild, "object firstChild");
+						},
+						function destroyObject(t){
+							dojo.destroy(dojo.byId("objectToEmpty"));
+							doh.f(!!dojo.byId("objectToEmpty"), "object byId");
+						},
+						function destroyIframe(t){
+							dojo.destroy(dojo.byId("iframeToDestroy"));
+							doh.f(!!dojo.byId("iframeToDestroy"), "iframe byId");
+						},
+						function destroyDivNotInDOM(t){
+							var p = dojo.byId("divToRemoveFromDOM");
+							var n = dojo.byId("divToDestroy");
+							p = p.parentNode.removeChild(p);
+							doh.f(!!dojo.byId("divToRemoveFromDOM"), "div byId");
+							doh.t(!!p.firstChild, "div child 1");
+							doh.is(p.firstChild, n, "div 1st child");
+							doh.isNot(p.firstChild, p.lastChild, "div 1st child");
+							dojo.destroy(n);
+							doh.t(!!p.firstChild, "div child 2");
+							doh.isNot(p.firstChild, n, "div 2nd child");
+							doh.is(p.firstChild, p.lastChild, "div 2nd child");
+							dojo.empty(p);
+							doh.f(!!p.firstChild, "div child 3");
+							dojo.destroy(p);
+							doh.t(true, "no exception thrown");
+						}
+					]
+				);
+
 				doh.runOnLoad();
 			});
 		</script>
@@ -323,6 +365,27 @@
 		<div id="sq100nopos">
 			100px square, no positioning
 		</div>
+
+		<!-- SVG element to test empty -->
+		<svg id="surface" xmlns="http://www.w3.org/2000/svg" width="100px" height="100px"
+			><rect id="rect1" fill="rgb(255, 0, 0)" x="0" y="0" width="80" height="60" ry="0" rx="0" fill-rule="evenodd"
+		/></svg>
+
+		<!-- OBJECT element to test empty -->
+		<object width="500" height="500" id="objectToEmpty" data="data:application/x-silverlight," type="application/x-silverlight"
+			><param name="background" value="transparent"
+		/></object>
+
+		<!-- IFRAME element to test destroy -->
+		<iframe id="iframeToDestroy" src="about:blank"
+			><span></span
+		></iframe>
+
+		<!-- DIV element to test destroy of element not in the DOM -->
+		<div id="divToRemoveFromDOM"
+			><div id="divToDestroy"></div
+			><div></div
+		></div>
 	</body>
 </html>
 
diff --git a/dojo/tests/_base/html_rtl.html b/dojo/tests/_base/html_rtl.html
index a33e8b6..e066473 100644
--- a/dojo/tests/_base/html_rtl.html
+++ b/dojo/tests/_base/html_rtl.html
@@ -18,8 +18,8 @@
 							runTest: function(t){
 								var d = new doh.Deferred();
 								setTimeout(d.getTestErrback(function(){ // allow browsers time to return the scroll point back to the last position
-									scrollTo(100, 50); // scroll a little
-									scrollBy(-50, 0); // net 50px horizontal movement: back-n-forth scrolling helps with different browsers
+									scrollTo(100, 100); // scroll a little
+									scrollBy(-50, -50); // net 50px horizontal movement: back-n-forth scrolling helps with different browsers
 									setTimeout(d.getTestCallback(function(){ // time to scroll
 										var pos = dojo.position('rect100', true);
 										t.is(100, pos.y, "y pos should be 100 after vertical scroll");
@@ -32,10 +32,8 @@
 
 						{
 							name: "eventClientXY_IE",
-							timeout: 1000,
+							timeout: 2000,
 							runTest: function(t){
-								if(!dojo.isIE){ return; }
-
 								var
 								d = new doh.Deferred(),
 								rect = dojo.byId("rect100"),
@@ -43,36 +41,28 @@
 									d.getTestErrback(function(e){
 										// move the rectangle to the mouse point
 										dojo.disconnect(handler);
-										rect.style.left = e.pageX + "px";
-										rect.style.top = e.pageY + "px";
-										handler = dojo.connect(rect, 'ondblclick', null,
-											d.getTestCallback(function(e){
-												var offsetX = (event||e).offsetX,
-													offsetY = (event||e).offsetY;
-												dojo.disconnect(handler);
-												t.is(0, offsetX);
-												t.is(0, offsetY);
-											}));
-										setTimeout(d.getTestErrback(function(){
-											if(!document.createEvent){
-												rect.fireEvent('ondblclick');
-											}else{
-												var clickEvent = document.createEvent("MouseEvent");
-												clickEvent.initMouseEvent("dblclick", true, true, window, 0,0,0,0,0,0,0,0,0,0,null);
-												rect.dispatchEvent(clickEvent);
-											}
-										}), 100); // time to move rect to cursor position
-									}));
+										var	scroll = dojo.docScroll(),
+											pageX = (e.pageX || e.pageY) ? e.pageX : ((e.clientX || 0) + scroll.x),
+											pageY = (e.pageX || e.pageY) ? e.pageY : ((e.clientY || 0) + scroll.y);
+										rect.style.left = pageX + "px";
+										rect.style.top = pageY + "px";
+										setTimeout(d.getTestCallback(function(){
+											var rectPos = dojo.position(rect, true);
+											t.is(pageX, rectPos.x, "pageX");
+											t.is(pageY, rectPos.y, "pageY");
+										}), 500); // time to move rect to cursor position
+									})
+								);
+								rect.scrollIntoView();
 								setTimeout(d.getTestErrback(function(){
-									if(!document.createEvent){
-										rect.offsetParent.fireEvent('onclick');
+									if(!("dispatchEvent" in rect.offsetParent)){
+										rect.offsetParent.fireEvent('onclick'); // IE < 9
 									}else{
-										var clickEvent = document.createEvent("MouseEvent");
-										clickEvent.initMouseEvent("click", true, true, window, 0,0,0,0,0,0,0,0,0,0,null);
+										var clickEvent = rect.offsetParent.ownerDocument.createEvent("MouseEvent");
+										clickEvent.initMouseEvent("click", false, false, window, 0,0,0,60,60,0,0,0,0,0,null);
 										rect.offsetParent.dispatchEvent(clickEvent);
 									}
-
-								}), 100); // time to finish any pre-scrolling
+								}), 500); // time to finish any pre-scrolling
 								return d;
 							}
 						},
@@ -143,14 +133,14 @@
 			}
 		</style>
 	</head>
-	<body>
+	<body style="min-height:2000px;min-width:2000px;">
 		<h1>testing Core HTML/DOM/CSS/Style utils</h1>
 		<div id="rect100">
 			100px rect, abs, 
 			mouse point is at top-left after the test "eventClientXY"
 		</div>
-		<div id="rect_vert" style="height:1600px;">show vertical scrollbar</div>
-		<div id="rect_horz" style="width:1600px;position:relative;right:-200px;">show horizonal scrollbar</div>
+		<div id="rect_vert" style="padding:100px;visibility:hidden;"><input disabled value="show vertical scrollbar" style="display:block;height:100%;"></div>
+		<div id="rect_horz" style="padding:100px;visibility:hidden;"><input disabled value="show horizonal scrollbar" style="display:block;width:100%;"></div>
 		<br>
 		<script type="text/javascript" src="scrollingIframe.js"></script>
 		<div id="iframeContainer"></div>
diff --git a/dojo/tests/_base/i18nExhaustive.js b/dojo/tests/_base/i18nExhaustive.js
new file mode 100644
index 0000000..227d7c5
--- /dev/null
+++ b/dojo/tests/_base/i18nExhaustive.js
@@ -0,0 +1,107 @@
+define([
+	"../../main",
+	"doh/main",
+	"require"
+], function(dojo, doh, require){
+	var testParams = [
+		"sync,,src,./dojo,src,./i18n-test,amd",
+		"sync,,src,./dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,,src,./dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,,src,./dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"sync,,rel,./built-i18n-test/rel/dojo,src,./i18n-test,amd",
+		"sync,,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"sync,,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,src,./i18n-test,amd",
+		"sync,,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"sync,ab,src,./dojo,src,./i18n-test,amd",
+		"sync,ab,src,./dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,ab,src,./dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,ab,src,./dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"sync,ab,rel,./built-i18n-test/rel/dojo,src,./i18n-test,amd",
+		"sync,ab,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,ab,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,ab,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"sync,ab,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,src,./i18n-test,amd",
+		"sync,ab,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,ab,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,ab,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"sync,ab-cd,src,./dojo,src,./i18n-test,amd",
+		"sync,ab-cd,src,./dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,ab-cd,src,./dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,ab-cd,src,./dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"sync,ab-cd,rel,./built-i18n-test/rel/dojo,src,./i18n-test,amd",
+		"sync,ab-cd,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,ab-cd,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,ab-cd,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"sync,ab-cd,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,src,./i18n-test,amd",
+		"sync,ab-cd,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,ab-cd,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,ab-cd,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"sync,ab-cd-ef,src,./dojo,src,./i18n-test,amd",
+		"sync,ab-cd-ef,src,./dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,ab-cd-ef,src,./dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,ab-cd-ef,src,./dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"sync,ab-cd-ef,rel,./built-i18n-test/rel/dojo,src,./i18n-test,amd",
+		"sync,ab-cd-ef,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,ab-cd-ef,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,ab-cd-ef,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"sync,ab-cd-ef,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,src,./i18n-test,amd",
+		"sync,ab-cd-ef,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"sync,ab-cd-ef,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"sync,ab-cd-ef,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,,src,./dojo,src,./i18n-test,amd",
+		"async,,src,./dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,,src,./dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,,src,./dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,,rel,./built-i18n-test/rel/dojo,src,./i18n-test,amd",
+		"async,,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,src,./i18n-test,amd",
+		"async,,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,ab,src,./dojo,src,./i18n-test,amd",
+		"async,ab,src,./dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,ab,src,./dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,ab,src,./dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,ab,rel,./built-i18n-test/rel/dojo,src,./i18n-test,amd",
+		"async,ab,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,ab,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,ab,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,ab,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,src,./i18n-test,amd",
+		"async,ab,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,ab,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,ab,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,ab-cd,src,./dojo,src,./i18n-test,amd",
+		"async,ab-cd,src,./dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,ab-cd,src,./dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,ab-cd,src,./dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,ab-cd,rel,./built-i18n-test/rel/dojo,src,./i18n-test,amd",
+		"async,ab-cd,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,ab-cd,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,ab-cd,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,ab-cd,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,src,./i18n-test,amd",
+		"async,ab-cd,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,ab-cd,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,ab-cd,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,ab-cd-ef,src,./dojo,src,./i18n-test,amd",
+		"async,ab-cd-ef,src,./dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,ab-cd-ef,src,./dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,ab-cd-ef,src,./dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,ab-cd-ef,rel,./built-i18n-test/rel/dojo,src,./i18n-test,amd",
+		"async,ab-cd-ef,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,ab-cd-ef,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,ab-cd-ef,rel,./built-i18n-test/rel/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd",
+		"async,ab-cd-ef,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,src,./i18n-test,amd",
+		"async,ab-cd-ef,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built/i18nTest,amd",
+		"async,ab-cd-ef,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers/i18nTest,amd",
+		"async,ab-cd-ef,cdn,http://192.168.1.114/dev/dtk/built-i18n-test/cdn/dojo,built,./built-i18n-test/built-with-layers-and-preloads/i18nTest,amd"];
+
+	for(var i = 0; i<testParams.length; i++){
+		doh.register("tests._base.i18nExhaustive" + i, require.toUrl("dojo/main") + "/../../i18n-test/unit.html?" + testParams[i]);
+	}
+});
diff --git a/dojo/tests/_base/json.js b/dojo/tests/_base/json.js
index eff0365..99edec7 100644
--- a/dojo/tests/_base/json.js
+++ b/dojo/tests/_base/json.js
@@ -33,7 +33,7 @@ tests.register("tests._base.json",
 		},
 		// tricky json, using our JSON extensions
 		function dojoExtendedJson(t){
-			var testObj = {ex1:{b:3, json:function(){return "json" + this.b}}, ex2: {b:4, __json__:function(){return "__json__" + this.b}}};
+			var testObj = {ex1:{b:3, json:function(){return "json" + this.b;}}, ex2: {b:4, __json__:function(){return "__json__" + this.b;}}};
 			var testStr = dojo.toJson(testObj);
 			t.assertEqual('{"ex1":"json3","ex2":"__json__4"}', testStr);
 		},
diff --git a/dojo/tests/_base/lang.js b/dojo/tests/_base/lang.js
index 1d6288b..fcec650 100644
--- a/dojo/tests/_base/lang.js
+++ b/dojo/tests/_base/lang.js
@@ -1,10 +1,10 @@
-define(["dojo", "doh"], function(dojo, doh){
+define(["doh/main", "dojo/_base/array", "dojo/_base/lang"], function(doh, array, lang){
 
   doh.register("tests._base.lang", [
 		function mixin(t){
-			t.assertEqual("object", typeof dojo.mixin());
-			t.assertEqual("object", typeof dojo.mixin(undefined));
-			t.assertEqual("object", typeof dojo.mixin(null));
+			t.assertEqual("object", typeof lang.mixin());
+			t.assertEqual("object", typeof lang.mixin(undefined));
+			t.assertEqual("object", typeof lang.mixin(null));
 			var src = {
 				foo: function(){
 					t.debug("foo");
@@ -12,7 +12,7 @@ define(["dojo", "doh"], function(dojo, doh){
 				bar: "bar"
 			};
 			var dest = {};
-			dojo.mixin(dest, src);
+			lang.mixin(dest, src);
 			t.assertEqual("function", typeof dest["foo"]);
 			t.assertEqual("string", typeof dest["bar"]);
 		},
@@ -25,53 +25,53 @@ define(["dojo", "doh"], function(dojo, doh){
 				bar: "bar"
 			};
 			function dest(){}
-			dojo.extend(dest, src);
+			lang.extend(dest, src);
 			var test = new dest();
 			t.assertEqual("function", typeof test["foo"]);
 			t.assertEqual("string", typeof test["bar"]);
 		},
 
 		function isFunction(t){
-			t.assertTrue(dojo.isFunction(new Function()));
-			t.assertTrue(dojo.isFunction(isFunction));
-			if(dojo.isBrowser){ // test the Safari workaround for NodeList
-				t.assertFalse(dojo.isFunction(dojo.doc.getElementsByName("html")));
-				t.assertFalse(dojo.isFunction(dojo.doc.createElement("object")));
+			t.assertTrue(lang.isFunction(new Function()));
+			t.assertTrue(lang.isFunction(isFunction));
+			if(lang.isBrowser){ // test the Safari workaround for NodeList
+				t.assertFalse(lang.isFunction(lang.doc.getElementsByName("html")));
+				t.assertFalse(lang.isFunction(lang.doc.createElement("object")));
 			}
 		},
 
 		function isObject(t){
-			t.assertFalse(dojo.isObject(true));
-			t.assertFalse(dojo.isObject(false));
-			t.assertFalse(dojo.isObject("foo"));
-			t.assertTrue(dojo.isObject(new String("foo")));
-			t.assertTrue(dojo.isObject(null));
-			t.assertTrue(dojo.isObject({}));
-			t.assertTrue(dojo.isObject([]));
-			t.assertTrue(dojo.isObject(new Array()));
+			t.assertFalse(lang.isObject(true));
+			t.assertFalse(lang.isObject(false));
+			t.assertFalse(lang.isObject("foo"));
+			t.assertTrue(lang.isObject(new String("foo")));
+			t.assertTrue(lang.isObject(null));
+			t.assertTrue(lang.isObject({}));
+			t.assertTrue(lang.isObject([]));
+			t.assertTrue(lang.isObject(new Array()));
 		},
 
 		function isArray(t){
-			t.assertTrue(dojo.isArray([]));
-			t.assertTrue(dojo.isArray(new Array()));
-			t.assertFalse(dojo.isArray({}));
+			t.assertTrue(lang.isArray([]));
+			t.assertTrue(lang.isArray(new Array()));
+			t.assertFalse(lang.isArray({}));
 		},
 
 		function isArrayLike(t){
-			t.assertFalse(dojo.isArrayLike("thinger"));
-			t.assertTrue(dojo.isArrayLike(new Array()));
-			t.assertFalse(dojo.isArrayLike({}));
-			t.assertTrue(dojo.isArrayLike(arguments));
+			t.assertFalse(lang.isArrayLike("thinger"));
+			t.assertTrue(lang.isArrayLike(new Array()));
+			t.assertFalse(lang.isArrayLike({}));
+			t.assertTrue(lang.isArrayLike(arguments));
 		},
 
 		function isString(t){
-			t.assertFalse(dojo.isString(true));
-			t.assertFalse(dojo.isString(false));
-			t.assertTrue(dojo.isString("foo"));
-			t.assertTrue(dojo.isString(new String("foo")));
-			t.assertFalse(dojo.isString(null));
-			t.assertFalse(dojo.isString({}));
-			t.assertFalse(dojo.isString([]));
+			t.assertFalse(lang.isString(true));
+			t.assertFalse(lang.isString(false));
+			t.assertTrue(lang.isString("foo"));
+			t.assertTrue(lang.isString(new String("foo")));
+			t.assertFalse(lang.isString(null));
+			t.assertFalse(lang.isString({}));
+			t.assertFalse(lang.isString([]));
 		},
 
 		function partial(t){
@@ -81,12 +81,12 @@ define(["dojo", "doh"], function(dojo, doh){
 				return [this.foo, arg1, arg2];
 			}
 			
-			var st1 = dojo.partial(thinger);
+			var st1 = lang.partial(thinger);
 			t.assertEqual("bar", st1.call(scope)[0]);
 			t.assertEqual(undefined, st1()[0]);
-			var st2 = dojo.partial(thinger, "foo", "bar");
+			var st2 = lang.partial(thinger, "foo", "bar");
 			t.assertEqual("bar", st2()[2]);
-			var st3 = dojo.partial(thinger, "foo", "bar");
+			var st3 = lang.partial(thinger, "foo", "bar");
 		},
 
 		function nestedPartial(t){
@@ -94,12 +94,12 @@ define(["dojo", "doh"], function(dojo, doh){
 				return [arg1, arg2];
 			}
 			
-			var st1 = dojo.partial(thinger, "foo");
+			var st1 = lang.partial(thinger, "foo");
 			t.assertEqual(undefined, st1()[1]);
 			t.assertEqual("bar", st1("bar")[1]);
 
 			// partials can accumulate
-			var st2 = dojo.partial(st1, "thud");
+			var st2 = lang.partial(st1, "thud");
 			t.assertEqual("foo", st2()[0]);
 			t.assertEqual("thud", st2()[1]);
 		},
@@ -111,11 +111,11 @@ define(["dojo", "doh"], function(dojo, doh){
 				return [this.foo, arguments.length];
 			}
 			
-			var st1 = dojo.hitch(scope, thinger);
+			var st1 = lang.hitch(scope, thinger);
 			t.assertEqual("bar", st1()[0]);
 			t.assertEqual(0, st1()[1]);
 
-			var st2 = dojo.hitch(scope2, thinger);
+			var st2 = lang.hitch(scope2, thinger);
 			t.assertEqual("baz", st2()[0]);
 			t.assertEqual(0, st1()[1]);
 			t.assertEqual(1, st1("blah")[1]);
@@ -131,10 +131,10 @@ define(["dojo", "doh"], function(dojo, doh){
 				return [this.foo, arguments.length];
 			}
 			
-			var st1 = dojo.hitch(scope, thinger, "foo", "bar");
+			var st1 = lang.hitch(scope, thinger, "foo", "bar");
 			t.assertEqual("bar", st1()[0]);
 			t.assertEqual(2, st1()[1]);
-			var st2 = dojo.hitch(scope2, thinger, "foo", "bar");
+			var st2 = lang.hitch(scope2, thinger, "foo", "bar");
 			t.assertEqual("baz", st2()[0]);
 			t.assertEqual(2, st2()[1]);
 		},
@@ -146,33 +146,33 @@ define(["dojo", "doh"], function(dojo, doh){
 				return [this.foo, arg1, arg2];
 			}
 			
-			var st1 = dojo.hitch(null, thinger);
+			var st1 = lang.hitch(null, thinger);
 			t.assertEqual("bar", st1.call(scope)[0]);
 			t.assertEqual(undefined, st1()[0]);
-			var st2 = dojo.hitch(null, thinger, "foo", "bar");
+			var st2 = lang.hitch(null, thinger, "foo", "bar");
 			t.assertEqual("bar", st2()[2]);
-			var st3 = dojo.hitch(null, thinger, "foo", "bar");
+			var st3 = lang.hitch(null, thinger, "foo", "bar");
 		},
 
 		function _toArray(t){
 			var obj1 = [ 'foo', 'bar', 'spam', 'ham' ];
 
 			function thinger(){
-				return dojo._toArray(arguments);
+				return lang._toArray(arguments);
 			}
 			var obj2 = thinger.apply(this, obj1);
 			t.assertEqual(obj1[0], obj2[0]);
 
-			if(dojo.isBrowser){
+			if(lang.isBrowser){
 				//test DomCollection
 				var div = document.createElement('div');
 				div.innerHTML="<a href='#'>link</a>text";
-				var r=dojo._toArray(div.childNodes);
+				var r=lang._toArray(div.childNodes);
 				t.is(2,r.length);
 			}
 		},
 		
-		function clone(t) {
+		function clone(t){
 			var obj1 = {
 				foo: 'bar',
 				answer: 42,
@@ -189,7 +189,7 @@ define(["dojo", "doh"], function(dojo, doh){
 				},
 				toString: function(){ return "meow"; }
 			};
-			var obj2 = dojo.clone(obj1);
+			var obj2 = lang.clone(obj1);
 			t.assertEqual(obj1.foo, obj2.foo);
 			t.assertEqual(obj1.answer, obj2.answer);
 			t.assertEqual(obj1.jan102007, obj2.jan102007);
@@ -222,7 +222,7 @@ define(["dojo", "doh"], function(dojo, doh){
 			t.is(1, a.x);
 			t.is(2, a.y());
 			t.is(99, a.z1);
-			var c = dojo.delegate(a, b);
+			var c = lang.delegate(a, b);
 			t.is(1, a.x);
 			t.is(2, a.y());
 			t.is(99, a.z1);
@@ -235,7 +235,7 @@ define(["dojo", "doh"], function(dojo, doh){
 		},
 
 		function replace(t){
-			var s1 = dojo.replace("Hello, {name.first} {name.last} AKA {nick}!",
+			var s1 = lang.replace("Hello, {name.first} {name.last} AKA {nick}!",
 				{
 					nick: "Bob",
 					name: {
@@ -246,17 +246,17 @@ define(["dojo", "doh"], function(dojo, doh){
 				});
 			t.is("Hello, Robert Cringely AKA Bob!", s1);
 
-			var s2 = dojo.replace("Hello, {0} {2}!", ["Robert", "X", "Cringely"]);
+			var s2 = lang.replace("Hello, {0} {2}!", ["Robert", "X", "Cringely"]);
 			t.is("Hello, Robert Cringely!", s2);
 
 			function sum(a){
 				var t = 0;
-				dojo.forEach(a, function(x){ t += x; });
+				array.forEach(a, function(x){ t += x; });
 				return t;
 			}
-			var s3 = dojo.replace(
+			var s3 = lang.replace(
 				"{count} payments averaging {avg} USD per payment.",
-				dojo.hitch(
+				lang.hitch(
 					{ payments: [11, 16, 12] },
 					function(_, key){
 						switch(key){
@@ -271,7 +271,7 @@ define(["dojo", "doh"], function(dojo, doh){
 				));
 			t.is("3 payments averaging 13 USD per payment.", s3);
 
-			var s4 = dojo.replace("Hello, ${0} ${2}!", ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
+			var s4 = lang.replace("Hello, ${0} ${2}!", ["Robert", "X", "Cringely"], /\$\{([^\}]+)\}/g);
 			t.is("Hello, Robert Cringely!", s4);
 		}
 	]
diff --git a/dojo/tests/_base/loader.js b/dojo/tests/_base/loader.js
index 3a148cc..f8590f6 100644
--- a/dojo/tests/_base/loader.js
+++ b/dojo/tests/_base/loader.js
@@ -2,10 +2,11 @@ define([
 	"dojo",
 	"doh",
 	"require",
-	"./loader/core",
+	"dojo/sniff",
+	"dojo/has!dojo-publish-privates?./loader/core",
 	"dojo/has!dojo-amd-factory-scan?./loader/modules",
-	"./loader/moduleIds",
-	"./loader/bootstrap"], function(dojo, doh, require){
+	"dojo/has!dojo-publish-privates?./loader/moduleIds",
+	"./loader/bootstrap"], function(dojo, doh, require, has){
 	if(doh.isBrowser){
 		doh.register("tests._base.loader.asyncWithDojoRequire", require.toUrl("./loader/asyncWithDojoRequire.html"));
 
@@ -16,7 +17,9 @@ define([
 		doh.register("tests._base.loader.config?djConfig-require", require.toUrl("./loader/config.html")+"?djConfig-require");
 		doh.register("tests._base.loader.config?djConfig", require.toUrl("./loader/config.html")+"?djConfig");
 		doh.register("tests._base.loader.config?require", require.toUrl("./loader/config.html")+"?require");
-		doh.register("tests._base.loader.config?configApi.html", require.toUrl("./loader/configApi.html"));
+		if(has("dojo-publish-privates")){
+			doh.register("tests._base.loader.config?configApi.html", require.toUrl("./loader/configApi.html"));
+		}
 		doh.register("tests._base.loader.config?config-sniff.html", require.toUrl("./loader/config-sniff.html"));
 		doh.register("tests._base.loader.config?config-sniff-djConfig.html", require.toUrl("./loader/config-sniff-djConfig.html"));
 		doh.register("tests._base.loader.config?config-has.html", require.toUrl("./loader/config-has.html"));
@@ -33,10 +36,10 @@ define([
 		doh.register("tests._base.loader.xdomin-async-2", require.toUrl("./loader/xdomain/xdomain.html"), {async:"legacyAsync", variation:2});
 		// the requirejs test suite. The following tests are not used:
 		//
-		//   * baseUrl: dojo's baseUrl is different--it defaults to the dojo tree. See TODO
-		//   * layers: dojo's build system does things differently
-		//   * afterload: is not constructed in a way that works with doh
-		//   * plugin/sync: this test seems like it will always fail in async mode; TODO check with James
+		//	 * baseUrl: dojo's baseUrl is different--it defaults to the dojo tree. See TODO
+		//	 * layers: dojo's build system does things differently
+		//	 * afterload: is not constructed in a way that works with doh
+		//	 * plugin/sync: this test seems like it will always fail in async mode; TODO check with James
         //
 		doh.register("tests._base.loader.requirejs-simple-sync", require.toUrl("./loader/requirejs/simple.html"), {async:0});
 		doh.register("tests._base.loader.requirejs-simple-async", require.toUrl("./loader/requirejs/simple.html"), {async:1});
@@ -44,9 +47,10 @@ define([
 		doh.register("tests._base.loader.requirejs-config-sync", require.toUrl("./loader/requirejs/config.html"), {async:0});
 		doh.register("tests._base.loader.requirejs-config-async", require.toUrl("./loader/requirejs/config.html"), {async:1});
 
-		doh.register("tests._base.loader.requirejs-dataMain-sync", require.toUrl("./loader/requirejs/dataMain.html"), {async:0});
-		doh.register("tests._base.loader.requirejs-dataMain-async", require.toUrl("./loader/requirejs/dataMain.html"), {async:1});
-
+		if(has("dojo-requirejs-api")){
+			doh.register("tests._base.loader.requirejs-dataMain-sync", require.toUrl("./loader/requirejs/dataMain.html"), {async:0});
+			doh.register("tests._base.loader.requirejs-dataMain-async", require.toUrl("./loader/requirejs/dataMain.html"), {async:1});
+		}
 		doh.register("tests._base.loader.requirejs-simple-nohead-sync", require.toUrl("./loader/requirejs/simple-nohead.html"), {async:0});
 		doh.register("tests._base.loader.requirejs-simple-nohead-async", require.toUrl("./loader/requirejs/simple-nohead.html"), {async:1});
 
@@ -70,7 +74,7 @@ define([
 		    root= qstart!=-1 ? location.href.substring(0, qstart) : location.href,
 			setup= compactPath(root + "/../" + require.toUrl("./loader/requirejs/requirejs-setup.js")),
 			baseUrl= setup.substring(0, setup.length - "/requirejs-setup.js".length);
-		if(dojo.isIE>6){
+		if(has("ie")>6){
 			doh.register("tests._base.loader.requirejs-simple-badbase-sync", require.toUrl("./loader/requirejs/simple-badbase.html"), {
 				async:0,
 				baseUrl:baseUrl,
@@ -88,15 +92,19 @@ define([
 		//doh.register("tests._base.loader.requirejs-circular-sync", require.toUrl("./loader/requirejs/circular.html"), {async:0});
 		doh.register("tests._base.loader.requirejs-circular-async", require.toUrl("./loader/requirejs/circular.html"), {async:1});
 
-		doh.register("tests._base.loader.requirejs-depoverlap-sync", require.toUrl("./loader/requirejs/depoverlap.html"), {async:0});
-		doh.register("tests._base.loader.requirejs-depoverlap-async", require.toUrl("./loader/requirejs/depoverlap.html"), {async:1});
+		if(has("dojo-requirejs-api")){
+			doh.register("tests._base.loader.requirejs-depoverlap-sync", require.toUrl("./loader/requirejs/depoverlap.html"), {async:0});
+			doh.register("tests._base.loader.requirejs-depoverlap-async", require.toUrl("./loader/requirejs/depoverlap.html"), {async:1});
+		}
 
 		doh.register("tests._base.loader.requirejs-urlfetch-sync", require.toUrl("./loader/requirejs/urlfetch/urlfetch.html"), {async:0});
 		doh.register("tests._base.loader.requirejs-urlfetch-async", require.toUrl("./loader/requirejs/urlfetch/urlfetch.html"), {async:1});
 
-		doh.register("tests._base.loader.requirejs-uniques-sync", require.toUrl("./loader/requirejs/uniques/uniques.html"), {async:0});
-		doh.register("tests._base.loader.requirejs-uniques-async", require.toUrl("./loader/requirejs/uniques/uniques.html"), {async:1});
-
+		if(has("dojo-amd-factory-scan")){
+			doh.register("tests._base.loader.requirejs-uniques-sync", require.toUrl("./loader/requirejs/uniques/uniques.html"), {async:0});
+			doh.register("tests._base.loader.requirejs-uniques-async", require.toUrl("./loader/requirejs/uniques/uniques.html"), {async:1});
+		}
+//>>excludeStart("requireJSI18nTests", kwArgs.insertAbsMids);
 		doh.register("tests._base.loader.requirejs-i18nlocaleunknown-sync", require.toUrl("./loader/requirejs/i18n/i18n.html")+"?bundle=i18n!nls/fr-fr/colors", {async:0});
 		doh.register("tests._base.loader.requirejs-i18nlocaleunknown-async", require.toUrl("./loader/requirejs/i18n/i18n.html")+"?bundle=i18n!nls/fr-fr/colors", {async:1});
 
@@ -114,7 +122,7 @@ define([
 
 		doh.register("tests._base.loader.requirejs-i18ncommonlocale-sync", require.toUrl("./loader/requirejs/i18n/common.html")+"?locale=en-us-surfer", {async:0});
 		doh.register("tests._base.loader.requirejs-i18ncommonlocale-async", require.toUrl("./loader/requirejs/i18n/common.html")+"?locale=en-us-surfer", {async:1});
-
+//>>excludeEnd("requireJSI18nTests");
 		doh.register("tests._base.loader.requirejs-paths-sync", require.toUrl("./loader/requirejs/paths/paths.html"), {async:0});
 		doh.register("tests._base.loader.requirejs-paths-async", require.toUrl("./loader/requirejs/paths/paths.html"), {async:1});
 
@@ -131,5 +139,8 @@ define([
 
 		doh.register("tests._base.loader.requirejs-exports-sync", require.toUrl("./loader/requirejs/exports/exports.html"), {async:0});
 		doh.register("tests._base.loader.requirejs-exports-async", require.toUrl("./loader/requirejs/exports/exports.html"), {async:1});
+
+		doh.register("tests._base.loader.require-config", require.toUrl("./loader/config/test.html"), {async:1});
 	}
 });
+
diff --git a/dojo/tests/_base/loader/14808.html b/dojo/tests/_base/loader/14808.html
new file mode 100644
index 0000000..843a6ba
--- /dev/null
+++ b/dojo/tests/_base/loader/14808.html
@@ -0,0 +1,24 @@
+<html>
+	<head>
+		<script src="../../../dojo.js"></script>
+		<script type="text/javascript">
+			dojo.registerModulePath('test', './tests/_base/loader/14808');
+			dojo.require('test.App');
+
+			(function(){
+				var success = 0;
+				setTimeout(function() {!success && (dojo.byId("result").innerHTML = "FAILED");}, 1000);
+				dojo.ready(function(){
+					success = 1;
+					dojo.byId("result").innerHTML= "it worked OK"
+				});
+			})();
+		</script>
+	</head>
+	<body>
+		<h1>Ticket 14808 verification</h1>
+		<p id="result">
+			loading..
+		</p>
+	</body>
+</html>
diff --git a/dojo/tests/_base/loader/14808/App.js b/dojo/tests/_base/loader/14808/App.js
new file mode 100644
index 0000000..8f00307
--- /dev/null
+++ b/dojo/tests/_base/loader/14808/App.js
@@ -0,0 +1,10 @@
+define("test/App", ["dijit","dojo","dojox","dojo/require!test/Module"], function(dijit,dojo,dojox)
+{
+	console.log('APP loaded');
+
+	dojo.provide('test.App');
+
+	dojo.require('test.Module');
+
+	dojo.declare('test.App', [ ], { foo : null });
+});
diff --git a/dojo/tests/_base/loader/14808/Module.js b/dojo/tests/_base/loader/14808/Module.js
new file mode 100644
index 0000000..9be871c
--- /dev/null
+++ b/dojo/tests/_base/loader/14808/Module.js
@@ -0,0 +1,9 @@
+define("test/Module", ["dijit","dojo","dojox","dojo/require!dijit/_TemplatedMixin"], function(dijit,dojo,dojox){
+	console.log('MODULE loaded');
+
+	dojo.provide('test.Module');
+
+	dojo.require('dijit._TemplatedMixin');
+
+	dojo.declare('test.Module', [ dijit._TemplatedMixin ], { foo : null });
+});
diff --git a/dojo/tests/_base/loader/boot-sniffConfig.html b/dojo/tests/_base/loader/boot-sniffConfig.html
new file mode 100644
index 0000000..9d82b94
--- /dev/null
+++ b/dojo/tests/_base/loader/boot-sniffConfig.html
@@ -0,0 +1,33 @@
+<html>
+<head>
+	<script>
+		function userConfigCallback(){
+			console.log("honored user config callback");
+			try{
+				require("dojo/AdapterRegistry");
+				console.log("honored user config");
+			}catch(e){
+				console.log("DID NOT honor user config");
+			}
+		}
+		function sniffConfigCallback(){
+			console.log("honored sniff config callback");
+			try{
+				require("dojo/back");
+				console.log("honored sniff config");
+			}catch(e){
+				console.log("DID NOT honor sniff config");
+			}
+		}
+		var require = {
+			deps:["dojo/AdapterRegistry"],
+			callback:userConfigCallback
+		};
+	</script>
+
+
+	<script src="../../../dojo.js" data-dojo-config="deps:['dojo/back'], callback:sniffConfigCallback"></script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/boot-userConfig.html b/dojo/tests/_base/loader/boot-userConfig.html
new file mode 100644
index 0000000..bb23a66
--- /dev/null
+++ b/dojo/tests/_base/loader/boot-userConfig.html
@@ -0,0 +1,23 @@
+<html>
+<head>
+	<script>
+		function userConfigCallback(){
+			console.log("honored user config callback");
+			try{
+				require("dojo/AdapterRegistry");
+				console.log("honored user config");
+			}catch(e){
+				console.log("DID NOT honor user config");
+			}
+		}
+		var require = {
+			deps:["dojo/AdapterRegistry"],
+			callback:userConfigCallback
+		};
+	</script>
+
+	<script src="../../../dojo.js"></script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/bootstrap.js b/dojo/tests/_base/loader/bootstrap.js
index 616554c..8227e48 100644
--- a/dojo/tests/_base/loader/bootstrap.js
+++ b/dojo/tests/_base/loader/bootstrap.js
@@ -8,10 +8,10 @@ define(["dojo", "doh", "../../../_base/sniff", "require"], function(dojo, doh, h
 
 		function getText(t){
 			if(require.getText){
-				var text = require.getText(require.toUrl("dojo/tests/_base/loader/getText.txt")).replace(/\n/g, "");
+				var text = require.getText(require.toUrl("dojo/tests/_base/loader/getText.txt")).replace(/\r|\n/g, "");
 				t.assertEqual("dojo._getText() test data", text);
 				if(dojo._getText){
-					text = dojo._getText(require.toUrl("dojo/tests/_base/loader/getText.txt")).replace(/\n/g, "");
+					text = dojo._getText(require.toUrl("dojo/tests/_base/loader/getText.txt")).replace(/\r|\n/g, "");
 					t.assertEqual("dojo._getText() test data", text);
 				}
 			}
diff --git a/dojo/tests/_base/loader/config/pkg/m1.js b/dojo/tests/_base/loader/config/pkg/m1.js
new file mode 100644
index 0000000..ae75fb3
--- /dev/null
+++ b/dojo/tests/_base/loader/config/pkg/m1.js
@@ -0,0 +1,20 @@
+
+define(["./m2", "module", "require"], function(m2, module, require){
+	// m2 just configs one of it's dependents in several ways
+
+	var config = {};
+	if(!module.config().isMapped){
+		require({config:{"pkg/m2":{config1:"config1"}}});
+		require({config:{"./m2":{config2:"config2"}}});
+		config[module.id + "/../m2"]= {config3:"config3"};
+		require({config:config});
+	}else{
+		require({config:{"pkg/m2":{config1:"mapped-config1"}}});
+		require({config:{"./m2":{config2:"mapped-config2"}}});
+		config[module.id + "/../m2"]= {config3:"mapped-config3"};
+		require({config:config});
+	}
+	return {getConfig:function(){ return module.config();}};
+});
+
+
diff --git a/dojo/tests/_base/loader/config/pkg/m2.js b/dojo/tests/_base/loader/config/pkg/m2.js
new file mode 100644
index 0000000..9a934ac
--- /dev/null
+++ b/dojo/tests/_base/loader/config/pkg/m2.js
@@ -0,0 +1,4 @@
+define(["module"], function(module){
+	return {getConfig:function(){ return module.config();}};
+});
+
diff --git a/dojo/tests/_base/loader/config/someModule.js b/dojo/tests/_base/loader/config/someModule.js
new file mode 100644
index 0000000..f97a42b
--- /dev/null
+++ b/dojo/tests/_base/loader/config/someModule.js
@@ -0,0 +1,11 @@
+define(["pkg/m1", "pkg/m2", "require", "module"], function(m1, m2, require, module){
+	require({config:{
+		"pkg/m1":{configThroughMappedRefForM1:"configThroughMappedRefForM1"},
+		"pkg/m2":{configThroughMappedRefForM1:"configThroughMappedRefForM1"}
+	}});
+	return {
+		getConfig:function(){return module.config();},
+		m1:m1,
+		m2:m2
+	};
+});
diff --git a/dojo/tests/_base/loader/config/someModuleConfiggedPriorToBoot.js b/dojo/tests/_base/loader/config/someModuleConfiggedPriorToBoot.js
new file mode 100644
index 0000000..4fcde73
--- /dev/null
+++ b/dojo/tests/_base/loader/config/someModuleConfiggedPriorToBoot.js
@@ -0,0 +1,5 @@
+define(["module"], function(module){
+	return {
+		getConfig:function(){return module.config();}
+	};
+});
diff --git a/dojo/tests/_base/loader/config/test.html b/dojo/tests/_base/loader/config/test.html
new file mode 100644
index 0000000..793d7f6
--- /dev/null
+++ b/dojo/tests/_base/loader/config/test.html
@@ -0,0 +1,122 @@
+<html>
+<head>
+	<script>
+		// The "loader" package depends on the package "pkg"; the application also 
+		// depends on the package "pkg", but configured in a different way. Therefore, solve
+		// the problem by mapping "pkg" as seen by "loader" to "pkgMapped". Then configure
+		// the packages "pkg" and "pkgMapped" differently. 
+		// 
+		// At the app (global) level, config can be accomplished via the names "pkg" and "pkgMapped".
+		// Notice also that "pkg" does some of it's own configuration based on user configuration.
+		// This tests the ability to configure a mapped package.
+
+		var dojoConfig = {
+			async:1,
+			baseUrl:"../../../../..",
+			packages:[{
+				name:"loader",
+				location:"dojo/tests/_base/loader/config",
+				packageMap:{
+					"pkg":"pkgMapped"
+				}
+			},{
+				name:"pkg",
+				location:"dojo/tests/_base/loader/config/pkg"
+			},{
+				name:"pkgMapped",
+				location:"dojo/tests/_base/loader/config/pkg",
+				packageMap:{
+					"pkg":"pkgMapped"
+				}
+			},{
+				name:"dojo",
+				location:"dojo"
+			},{
+				name:"doh",
+				location:"util/doh"
+			}],
+			config:{
+				"loader/someModuleConfiggedPriorToBoot":{someConfig:"this is the config for someModuleConfiggedPriorToBoot"}
+			},
+			deps:["doh"],
+			callback:function(doh){
+				var master = new doh.Deferred(), waiting = 2;
+			    doh.register(
+			        "require.config",
+			        [
+			            {
+			                name: "require.config",
+			                timeout: 5000,
+			                runTest: function() {
+			                    return master;
+			                }
+			            }
+			        ]
+			    );
+			    doh.run();
+
+
+				require({config:{
+					"loader/someModule":{someConfig:"this is the config for someModule-someConfig"},
+					"pkgMapped/m1":{globalConfig:"globalConfigForpkgMapped/m1", isMapped:true},
+					"pkgMapped/m2":{globalConfig:"globalConfigForpkgMapped/m2"}
+				}});
+				require(["loader/someModuleConfiggedPriorToBoot", "loader/someModule"], function(someModuleConfiggedPriorToBoot, someModule){
+					doh.is(someModuleConfiggedPriorToBoot.getConfig(), {
+						someConfig:"this is the config for someModuleConfiggedPriorToBoot"});
+					doh.is(someModule.getConfig(), {
+						someConfig:"this is the config for someModule-someConfig"});
+					doh.is(someModule.m1.getConfig(), {
+						globalConfig:"globalConfigForpkgMapped/m1", 
+						isMapped:true,
+						configThroughMappedRefForM1:"configThroughMappedRefForM1"});
+					doh.is(someModule.m2.getConfig(), {
+						globalConfig:"globalConfigForpkgMapped/m2", 
+						configThroughMappedRefForM1:"configThroughMappedRefForM1",
+						config1:"mapped-config1",
+						config2:"mapped-config2",
+						config3:"mapped-config3"
+					});
+
+					setTimeout(function(){
+						require({
+							config:{
+								"loader/someModule":{
+									someMoreConfig:"this is the config for someModule-someMoreConfig"
+								}
+							}
+						});
+						require(["loader/someModule"], function(someModule){
+							doh.is(someModule.getConfig(), {
+								someConfig:"this is the config for someModule-someConfig",
+								someMoreConfig:"this is the config for someModule-someMoreConfig"
+							});
+							if(!(--waiting)){
+								master.callback(true);
+							}
+						});
+					}, 10);
+				});
+				require({config:{
+					"pkg/m1":{globalConfig:"globalConfigForM1"},
+					"pkg/m2":{globalConfig:"globalConfigForM2"}
+				}},["pkg/m1", "pkg/m2"], function(m1, m2){
+					doh.is(m1.getConfig(), {
+						globalConfig:"globalConfigForM1"});
+					doh.is(m2.getConfig(), {
+						globalConfig:"globalConfigForM2", 
+						config1:"config1",
+						config2:"config2",
+						config3:"config3"
+					});
+					if(!(--waiting)){
+						master.callback(true);
+					}
+				});
+				doh.run();
+			}
+		};
+	</script>
+	<script src="../../../../dojo.js"></script>
+</head>
+</html>
diff --git a/dojo/tests/_base/loader/configApi.html b/dojo/tests/_base/loader/configApi.html
index 7fa3063..f6b9e95 100644
--- a/dojo/tests/_base/loader/configApi.html
+++ b/dojo/tests/_base/loader/configApi.html
@@ -20,8 +20,7 @@
 								savedRawConfig= rawConfig;
 								t.is(config, expectedConfig2);
 							};
-						var 
-							configListeners = require.listenerQueues.config;
+						var configListeners = require.listenerQueues.config || (require.listenerQueues.config = []);
 							listenerCount= configListeners.length,
 							h1= require.on("config", configListener1),
 							h2= require.on("config", configListener2);
diff --git a/dojo/tests/_base/loader/coolio/coolio-built.html b/dojo/tests/_base/loader/coolio/coolio-built.html
index d977f9a..f0d9366 100644
--- a/dojo/tests/_base/loader/coolio/coolio-built.html
+++ b/dojo/tests/_base/loader/coolio/coolio-built.html
@@ -18,17 +18,20 @@
 					location:"../coolioBuilt/dojox",
 				},{
 					name:"cdojo",
-					location:"../coolioBuilt/dojo",
-					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+					location:"../coolioBuilt/dojo"
 				},{
 					name:"cdijit",
-					location:"../coolioBuilt/dijit",
-					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+					location:"../coolioBuilt/dijit"
 			    },{
 					name:"coolio",
-					location:"../coolioBuilt/coolio",
-					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+					location:"../coolioBuilt/coolio"
 				}],
+				map:{
+					cdojo:{dojo:"cdojo", dijit:"cdijit"},
+					cdijit:{dojo:"cdojo", dijit:"cdijit"},
+					coolio:{dojo:"cdojo", dijit:"cdijit"}
+				},
+				deps:["dojo", "cdojo"]
 			};
 		</script>
 		<script type="text/javascript" src="../coolioBuilt/dojo/dojo.js"></script>
@@ -36,6 +39,7 @@
 			var coolioCalendarMid = /legacy/.test(location.search) ? "coolio/calendar" : "coolio/calendar-amd";
 			require(["dojo/parser", coolioCalendarMid, "dojo/ready", "dijit/Calendar"], function(parser, calendar, ready){
 				ready(function(){
+					// dojo/main loaded the parser...
 					parser.parse();
 					calendar("c1");
 					console.log("total load time: " + ((new Date()).getTime() - startTime) / 1000 + "s");
diff --git a/dojo/tests/_base/loader/coolio/coolio-dev-async.html b/dojo/tests/_base/loader/coolio/coolio-dev-async-with-packageMap.html
similarity index 100%
copy from dojo/tests/_base/loader/coolio/coolio-dev-async.html
copy to dojo/tests/_base/loader/coolio/coolio-dev-async-with-packageMap.html
diff --git a/dojo/tests/_base/loader/coolio/coolio-dev-async.html b/dojo/tests/_base/loader/coolio/coolio-dev-async.html
index 463bed5..2130e60 100644
--- a/dojo/tests/_base/loader/coolio/coolio-dev-async.html
+++ b/dojo/tests/_base/loader/coolio/coolio-dev-async.html
@@ -24,22 +24,25 @@
 					// sandboxed, separate instance dojo package for coolio use; notice it uses the same code as the non-coolie dojo package
 					// all "dojo*" modules ids are mapped to "cdojo*" within this package
 					name:"cdojo",
-					location:"../../../..",
-					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+					location:"../../../.."
 				},{
 					// sandboxed, separate instance dijit package for coolio use; notice it uses the same code as the non-coolie dijitpackage
 					// all "dojo*" modules ids are mapped to "cdojo*" within this package
 					// all "dijit*" modules ids are mapped to "cdijit*" within this package
 					name:"cdijit",
-					location:"../../../../../dijit",
-					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+					location:"../../../../../dijit"
 			    },{
 					// all "dojo*" modules ids are mapped to "cdojo*" within this package
 					// all "dijit*" modules ids are mapped to "cdijit*" within this package
 					name:"coolio",
-					location:".",
-					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+					location:"."
 				}],
+
+				map:{
+					cdojo:{dojo:"cdojo", dijit:"cdijit"},
+					cdijit:{dojo:"cdojo", dijit:"cdijit"},
+					coolio:{dojo:"cdojo", dijit:"cdijit"}
+				}
 			};
 		</script>
 
diff --git a/dojo/tests/_base/loader/coolio/coolio-dev-legacy-async-with-packageMap.html b/dojo/tests/_base/loader/coolio/coolio-dev-legacy-async-with-packageMap.html
new file mode 100644
index 0000000..ff42c74
--- /dev/null
+++ b/dojo/tests/_base/loader/coolio/coolio-dev-legacy-async-with-packageMap.html
@@ -0,0 +1,83 @@
+<html>
+	<head>
+		<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/claro/claro.css" />
+
+		<script type="text/javascript">
+			var startTime = (new Date()).getTime();
+			var dojoConfig = {
+				// this is an example of developing with synchronous modules
+				async:0,
+
+				// set baseUrl === to the page URL; this overrides dojo's desire to be the center of the world
+				baseUrl:".",
+
+				packages:[{
+					// the dojo package for non-coolio use
+					name:"dojo",
+					location:"../../../..",
+				},{
+					// the dijit package for non-coolio use
+					name:"dijit",
+					location:"../../../../../dijit",
+				},{
+					// the dojox package which is always mapped when rescoping xdomain
+					name:"dojox",
+					location:"../../../../../dojox",
+				},{
+					// sandboxed, separate instance dojo package for coolio use; notice it uses the same code as the non-coolie dojo package
+					// all "dojo*" modules ids are mapped to "cdojo*" within this package
+					name:"cdojo",
+					location:"../../../..",
+					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+				},{
+					// sandboxed, separate instance dijit package for coolio use; notice it uses the same code as the non-coolie dijit package
+					// all "dojo*" modules ids are mapped to "cdojo*" within this package
+					// all "dijit*" modules ids are mapped to "cdijit*" within this package
+					name:"cdijit",
+					location:"../../../../../dijit",
+					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+			    },{
+					// all "dojo*" modules ids are mapped to "cdojo*" within this package
+					// all "dijit*" modules ids are mapped to "cdijit*" within this package
+					name:"coolio",
+					location:".",
+					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+				}],
+			};
+		</script>
+
+		<!-- load the loader, which in sync mode, also loads dojo -->
+		<script type="text/javascript" src="../../../../dojo.js"></script>
+		<script type="text/javascript">
+			dojo.require("cdojo");
+			require({async:"legacyAsync"});
+				
+			// the next two dojo.requires load the dojo and dijit instances
+			dojo.require("dijit.Calendar");
+			dojo.require("dojo.parser");
+
+			// coolio calendars load and are built on top of the cdojo and cdijit instances
+			dojo.require("coolio.calendar");
+			dojo.ready(function(){
+				coolio.calendar("c1");
+				dojo.parser.parse();
+				console.log("total load time: " + ((new Date()).getTime() - startTime) / 1000 + "s");
+				console.log(dojo);
+				console.log(dijit);
+				console.log(cdojo);
+				console.log(cdijit);
+				console.log("dojo._scopeName=" + dojo._scopeName);
+				console.log("cdojo._scopeName=" + cdojo._scopeName);
+				console.log("dijit._scopeName=" + dijit._scopeName);
+				console.log("cdijit._scopeName=" + cdijit._scopeName);
+			});
+		</script>
+	</head>
+	<body class=" claro ">
+		<!-- see it all work: instantiate a couple of widgets, one built in the dojo, dijit stack, the other in the cdojo, cdijit, coolio stack -->
+		<p>A Coolio Calendar</p>
+		<div id="c1"></div>
+		<p>A Dijit Calendar</p>
+		<div dojoType="dijit.Calendar" onChange="dojo.byId('formatted').innerHTML=dojo.date.locale.format(arguments[0], {formatLength: 'full', selector:'date'})"> </div>
+	</body>
+</html>
diff --git a/dojo/tests/_base/loader/coolio/coolio-dev-legacy-async.html b/dojo/tests/_base/loader/coolio/coolio-dev-legacy-async.html
index 13c004f..5d7b39a 100644
--- a/dojo/tests/_base/loader/coolio/coolio-dev-legacy-async.html
+++ b/dojo/tests/_base/loader/coolio/coolio-dev-legacy-async.html
@@ -27,22 +27,25 @@
 					// sandboxed, separate instance dojo package for coolio use; notice it uses the same code as the non-coolie dojo package
 					// all "dojo*" modules ids are mapped to "cdojo*" within this package
 					name:"cdojo",
-					location:"../../../..",
-					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+					location:"../../../.."
 				},{
 					// sandboxed, separate instance dijit package for coolio use; notice it uses the same code as the non-coolie dijitpackage
 					// all "dojo*" modules ids are mapped to "cdojo*" within this package
 					// all "dijit*" modules ids are mapped to "cdijit*" within this package
 					name:"cdijit",
-					location:"../../../../../dijit",
-					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+					location:"../../../../../dijit"
 			    },{
 					// all "dojo*" modules ids are mapped to "cdojo*" within this package
 					// all "dijit*" modules ids are mapped to "cdijit*" within this package
 					name:"coolio",
-					location:".",
-					packageMap:{dojo:"cdojo", dijit:"cdijit"}
+					location:"."
 				}],
+
+				map:{
+					cdojo:{dojo:"cdojo", dijit:"cdijit"},
+					cdijit:{dojo:"cdojo", dijit:"cdijit"},
+					coolio:{dojo:"cdojo", dijit:"cdijit"}
+				}
 			};
 		</script>
 
diff --git a/dojo/tests/_base/loader/coolio/coolio.js b/dojo/tests/_base/loader/coolio/coolio.js
deleted file mode 100644
index d7de313..0000000
--- a/dojo/tests/_base/loader/coolio/coolio.js
+++ /dev/null
@@ -1,17 +0,0 @@
-require({
-	packages:[{
-		name:"cdojo",
-		location:(dojoConfig.coolioDojoRoot || dojoConfig.coolioRoot) + "/dojo",
-		packageMap:{dojo:"cdojo"}
-	},{
-		name:"cdijit",
-		location:(dojoConfig.coolioDojoRoot || dojoConfig.coolioRoot) + "/dijit",
-		packageMap:{dojo:"cdojo", dijit:"cdijit"}
-    },{
-		name:"coolio",
-		location:dojoConfig.coolioRoot + "/coolio",
-		packageMap:{dojo:"cdojo", dijit:"cdijit"}
-	}],
-	cdojoScope:[["dojo", "cdojo"], ["dijit", "cdijit"]]
-});
-
diff --git a/dojo/tests/_base/loader/coolio/coolio.profile.js b/dojo/tests/_base/loader/coolio/coolio.profile.js
index f57e005..3397d0b 100644
--- a/dojo/tests/_base/loader/coolio/coolio.profile.js
+++ b/dojo/tests/_base/loader/coolio/coolio.profile.js
@@ -1,34 +1,58 @@
-dependencies = {
-	quiet:1,
-	action:"release",
-	optimize:0,
-	layerOptimize:0,
-	insertAbsMids:0,
-	copyTests:"build",
-	mini:0,
-	releaseDir:"../../dojo/tests/_base/loader",
-	releaseName:"coolioBuilt",
-	scopeMap:[["dojo", "cdojo"], ["dijit", "cdijit"], , ["dojox", "dojox"]],
-	layers: [
-		{
-			name: "dojo.js",
-			dependencies: [
-				"dojo.main",
-				"dojo.parser"
+var profile = (function(){
+	return {
+		// relative to this file
+		basePath:"../../../../..",
+
+		// relative to base path
+		releaseDir:"dojo/tests/_base/loader",
+
+		optimize:0,
+		layerOptimize:0,
+		insertAbsMids:0,
+		releaseName:"coolioBuilt",
+		selectorEngine:"lite",
+		//scopeMap:[["dojo", "cdojo"], ["dijit", "cdijit"], , ["dojox", "dojox"]],
+
+		// and include dom-ready support
+		staticHasFeatures:{
+			"dojo-publish-privates":1
+		},
+
+
+		packages:[{
+			name:"dojo",
+			location:"./dojo",
+			trees:[
+				[".", ".", /(\/\.)|(^\.)|(~$)|(tests\/_base\/)/]
 			]
 		},{
-			customBase:1,
-			name: "main.js"
+			name:"dijit",
+			location:"./dijit"
 		},{
-			name: "../dijit/Calendar.js",
-			dependencies: [
-				"dijit.Calendar"
-			]
+			name:"dojox",
+			location:"./dojox"
+		},{
+			name:"coolio",
+			location:"./dojo/tests/_base/loader/coolio",
+			resourceTags:{
+				amd: function(filename, mid){
+					return /calendar-amd\.js$/.test(filename);
+				}
+			}
+		}],
+
+		layers:{
+			"dojo/dojo":{
+				customBase:1
+			},
+			"dojo/main":{
+				include:["dojo/parser"]
+			},
+			"dijit/Calendar":{
+				include: [
+					"dijit/Calendar"
+				]
+			}
 		}
-	],
-	prefixes: [
-		["dijit", "../dijit"],
-		["dojox", "../dojox"],
-		["coolio", "./tests/_base/loader/coolio"]
-	]
-}
\ No newline at end of file
+	};
+})();
diff --git a/dojo/tests/_base/loader/coolio/test.html b/dojo/tests/_base/loader/coolio/test.html
index 14b1880..25dfd54 100644
--- a/dojo/tests/_base/loader/coolio/test.html
+++ b/dojo/tests/_base/loader/coolio/test.html
@@ -3,6 +3,7 @@
 	</head>
 	<body>
 		<h1>Relocating Demonstrations</h1>
+		<p>As of summer 2012, AMD mapping!</p>
 		<p>(AKA multi-version support or rescoping)</p>
 
 		<h3><a href="coolio-dev-legacy.html">Developing a component with the legacy API</a></h3>
@@ -16,6 +17,12 @@
 		dojo and dijit (or any other module trees) on the page while developing--no build required. Notice the console
 		when you load this example: multiple instances...also the load time is much faster!</p>
 
+		<h3><a href="coolio-dev-async-with-packageMap.html">Developing a
+				component with the AMD API using packageMap</a></h3>
+		<p>Same as above, except using the dojo-only "packageMap" config
+			variable; this variable has been replaced with the AMD-standard
+			"map" config variable.</p>
+
 		<h3><a href="coolio-dev-legacy-async.html">Developing a component with the legacy API, loaded asynchronously</a></h3>
 		<p>The idea is to force the loader into cross-domain mode so that even local, unbuilt resources will be
 		transformed to built, AMD modules on-the-fly. With these transformations, we can have multiple instances of dojo
@@ -24,6 +31,12 @@
 		<p>Generally, this mode is not useful under normal circumstances. However, it is a good test of the cross-domain
 		loader in the presense of relocated module trees.</p>
 
+		<h3><a href="coolio-dev-legacy-async-with-packageMap.html">Developing a component with
+				the legacy API, loaded asynchronously</a></h3>
+		<p>Same as above, except using the dojo-only "packageMap" config
+			variable; this variable has been replaced with the AMD-standard
+			"map" config variable.</p>
+
 		<h1>Build Time</h1>
 		<p>The v1.7 builder converts all legacy modules to AMD modules. This allows any legacy tree to be relocated just as if
 		it was an AMD tree all along. The profile coolio-legacy.profile.js is included to build the coolio project. It
@@ -31,7 +44,7 @@
 		legacy modules to AMD modules; it does not need to know the actual relocated names). You can build the coolio
 		demostration by executing the following command from the util/buildscripts directory</p>
 		<pre>
-./build.sh profile=../../dojo/tests/_base/loader/coolio/coolio.profile.js
+./build.sh -p ../../dojo/tests/_base/loader/coolio/coolio.profile.js -r
 		</pre>
 		<p> There are four demonstrations of the built code<p>
 		<p><b>Remember to do a build before you try these!</b></p>
diff --git a/dojo/tests/_base/loader/getText.txt b/dojo/tests/_base/loader/getText.txt
index 054e8e8..9fc280d 100644
--- a/dojo/tests/_base/loader/getText.txt
+++ b/dojo/tests/_base/loader/getText.txt
@@ -1 +1 @@
-dojo._getText() test data
\ No newline at end of file
+dojo._getText() test data
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/legacyModule.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/legacyModule.js
new file mode 100644
index 0000000..656c394
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/legacyModule.js
@@ -0,0 +1,60 @@
+/*
+	Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+	Available via Academic Free License >= 2.1 OR the modified BSD license.
+	see: http://dojotoolkit.org/license for details
+*/
+
+/*
+	This is an optimized version of Dojo, built for deployment and not for
+	development. To get sources and documentation, please visit:
+
+		http://dojotoolkit.org
+*/
+
+if(!dojo._hasResource["i18nTest.legacyModule"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["i18nTest.legacyModule"] = true;
+dojo.provide("i18nTest.legacyModule");
+
+
+
+window.i18nTest.legacyModule = function(){
+	var legacyBundle = dojo.i18n.getLocalization("i18nTest", "legacyBundle"),
+		result = [];
+
+	if(legacyBundle.rootValueOnly!="rootValueOnly"){
+		result.push('legacyBundle.rootValueOnly!="rootValueOnly"');
+	}
+	switch(dojo.locale){
+		case "ab":
+		case "ab-cd":
+			if(legacyBundle.legacyBundle!="legacyBundle-ab"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle-ab"');
+			}
+			if(legacyBundle.abValueOnly!="abValueOnly"){
+				result.push('legacyBundle.abValueOnly!="abValueOnly"');
+			}
+			break;
+		case "ab-cd-ef":
+			if(legacyBundle.legacyBundle!="legacyBundle-ab-cd-ef"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle-ab-cd-ef"');
+			}
+			if(legacyBundle.abValueOnly!="abValueOnly"){
+				result.push('legacyBundle.abValueOnly!="abValueOnly"');
+			}
+			if(legacyBundle.abCdEfValueOnly!="abCdEfValueOnly"){
+				result.push('legacyBundle.abCdEfValueOnly!="abCdEfValueOnly"');
+			}
+			break;
+		default:
+			if(legacyBundle.legacyBundle!="legacyBundle"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle"');
+			}
+	}
+
+	return result.length==0 ? true : result.join(";");
+};
+
+}
+
+
+dojo.i18n._preloadLocalizations("i18nTest.nls.legacyModule", ["ROOT","ab","ab-cd","ab-cd-ef","xx"]);
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/ab-cd-ef/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/ab-cd-ef/legacyBundle.js
new file mode 100644
index 0000000..992ae02
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/ab-cd-ef/legacyBundle.js
@@ -0,0 +1 @@
+({"abCdEfValueOnly":"abCdEfValueOnly","legacyBundle":"legacyBundle-ab-cd-ef","abValueOnly":"abValueOnly","rootValueOnly":"rootValueOnly"})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/ab/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/ab/legacyBundle.js
new file mode 100644
index 0000000..91cb014
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/ab/legacyBundle.js
@@ -0,0 +1 @@
+({"abValueOnly":"abValueOnly","legacyBundle":"legacyBundle-ab","rootValueOnly":"rootValueOnly"})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyBundle.js
new file mode 100644
index 0000000..5a6f414
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyBundle.js
@@ -0,0 +1 @@
+({"rootValueOnly":"rootValueOnly","legacyBundle":"legacyBundle"})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ROOT.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ROOT.js
new file mode 100644
index 0000000..825d2ac
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ROOT.js
@@ -0,0 +1 @@
+dojo.provide("i18nTest.nls.legacyModule_ROOT");dojo.provide("i18nTest.nls.legacyBundle");i18nTest.nls.legacyBundle._built=true;dojo.provide("i18nTest.nls.legacyBundle.ROOT");i18nTest.nls.legacyBundle.ROOT={"rootValueOnly":"rootValueOnly","legacyBundle":"legacyBundle"};
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ab-cd-ef.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ab-cd-ef.js
new file mode 100644
index 0000000..bc53879
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ab-cd-ef.js
@@ -0,0 +1 @@
+dojo.provide("i18nTest.nls.legacyModule_ab-cd-ef");dojo.provide("i18nTest.nls.legacyBundle");i18nTest.nls.legacyBundle._built=true;dojo.provide("i18nTest.nls.legacyBundle.ab_cd_ef");i18nTest.nls.legacyBundle.ab_cd_ef={"abCdEfValueOnly":"abCdEfValueOnly","legacyBundle":"legacyBundle-ab-cd-ef","abValueOnly":"abValueOnly","rootValueOnly":"rootValueOnly"};
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ab-cd.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ab-cd.js
new file mode 100644
index 0000000..d9eb5ce
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ab-cd.js
@@ -0,0 +1 @@
+dojo.provide("i18nTest.nls.legacyModule_ab-cd");dojo.provide("i18nTest.nls.legacyBundle");i18nTest.nls.legacyBundle._built=true;dojo.provide("i18nTest.nls.legacyBundle.ab_cd");i18nTest.nls.legacyBundle.ab_cd={"abValueOnly":"abValueOnly","legacyBundle":"legacyBundle-ab","rootValueOnly":"rootValueOnly"};
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ab.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ab.js
new file mode 100644
index 0000000..f2759c2
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_ab.js
@@ -0,0 +1 @@
+dojo.provide("i18nTest.nls.legacyModule_ab");dojo.provide("i18nTest.nls.legacyBundle");i18nTest.nls.legacyBundle._built=true;dojo.provide("i18nTest.nls.legacyBundle.ab");i18nTest.nls.legacyBundle.ab={"abValueOnly":"abValueOnly","legacyBundle":"legacyBundle-ab","rootValueOnly":"rootValueOnly"};
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_xx.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_xx.js
new file mode 100644
index 0000000..8963360
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers-and-preloads/nls/legacyModule_xx.js
@@ -0,0 +1 @@
+dojo.provide("i18nTest.nls.legacyModule_xx");dojo.provide("i18nTest.nls.legacyBundle");i18nTest.nls.legacyBundle._built=true;dojo.provide("i18nTest.nls.legacyBundle.xx");i18nTest.nls.legacyBundle.xx={"rootValueOnly":"rootValueOnly","legacyBundle":"legacyBundle"};
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/legacyModule.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/legacyModule.js
new file mode 100644
index 0000000..2066f26
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/legacyModule.js
@@ -0,0 +1,60 @@
+/*
+	Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+	Available via Academic Free License >= 2.1 OR the modified BSD license.
+	see: http://dojotoolkit.org/license for details
+*/
+
+/*
+	This is an optimized version of Dojo, built for deployment and not for
+	development. To get sources and documentation, please visit:
+
+		http://dojotoolkit.org
+*/
+
+if(!dojo._hasResource["i18nTest.legacyModule"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["i18nTest.legacyModule"] = true;
+dojo.provide("i18nTest.legacyModule");
+
+
+
+window.i18nTest.legacyModule = function(){
+	var legacyBundle = dojo.i18n.getLocalization("i18nTest", "legacyBundle"),
+		result = [];
+
+	if(legacyBundle.rootValueOnly!="rootValueOnly"){
+		result.push('legacyBundle.rootValueOnly!="rootValueOnly"');
+	}
+	switch(dojo.locale){
+		case "ab":
+		case "ab-cd":
+			if(legacyBundle.legacyBundle!="legacyBundle-ab"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle-ab"');
+			}
+			if(legacyBundle.abValueOnly!="abValueOnly"){
+				result.push('legacyBundle.abValueOnly!="abValueOnly"');
+			}
+			break;
+		case "ab-cd-ef":
+			if(legacyBundle.legacyBundle!="legacyBundle-ab-cd-ef"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle-ab-cd-ef"');
+			}
+			if(legacyBundle.abValueOnly!="abValueOnly"){
+				result.push('legacyBundle.abValueOnly!="abValueOnly"');
+			}
+			if(legacyBundle.abCdEfValueOnly!="abCdEfValueOnly"){
+				result.push('legacyBundle.abCdEfValueOnly!="abCdEfValueOnly"');
+			}
+			break;
+		default:
+			if(legacyBundle.legacyBundle!="legacyBundle"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle"');
+			}
+	}
+
+	return result.length==0 ? true : result.join(";");
+};
+
+}
+
+
+dojo.i18n._preloadLocalizations("i18nTest.nls.legacyModule", ["ROOT","ar","ca","cs","da","de","de-de","el","en","en-gb","en-us","es","es-es","fi","fi-fi","fr","fr-fr","he","he-il","hu","it","it-it","ja","ja-jp","ko","ko-kr","nb","nl","nl-nl","pl","pt","pt-br","pt-pt","ru","sk","sl","sv","th","tr","xx","zh","zh-cn","zh-tw"]);
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/ab-cd-ef/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/ab-cd-ef/legacyBundle.js
new file mode 100644
index 0000000..992ae02
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/ab-cd-ef/legacyBundle.js
@@ -0,0 +1 @@
+({"abCdEfValueOnly":"abCdEfValueOnly","legacyBundle":"legacyBundle-ab-cd-ef","abValueOnly":"abValueOnly","rootValueOnly":"rootValueOnly"})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/ab/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/ab/legacyBundle.js
new file mode 100644
index 0000000..91cb014
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/ab/legacyBundle.js
@@ -0,0 +1 @@
+({"abValueOnly":"abValueOnly","legacyBundle":"legacyBundle-ab","rootValueOnly":"rootValueOnly"})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyBundle.js
new file mode 100644
index 0000000..5a6f414
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyBundle.js
@@ -0,0 +1 @@
+({"rootValueOnly":"rootValueOnly","legacyBundle":"legacyBundle"})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyModule_ROOT.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyModule_ROOT.js
new file mode 100644
index 0000000..825d2ac
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyModule_ROOT.js
@@ -0,0 +1 @@
+dojo.provide("i18nTest.nls.legacyModule_ROOT");dojo.provide("i18nTest.nls.legacyBundle");i18nTest.nls.legacyBundle._built=true;dojo.provide("i18nTest.nls.legacyBundle.ROOT");i18nTest.nls.legacyBundle.ROOT={"rootValueOnly":"rootValueOnly","legacyBundle":"legacyBundle"};
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyModule_en-us.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyModule_en-us.js
new file mode 100644
index 0000000..0df9d56
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyModule_en-us.js
@@ -0,0 +1 @@
+dojo.provide("i18nTest.nls.legacyModule_en-us");dojo.provide("i18nTest.nls.legacyBundle");i18nTest.nls.legacyBundle._built=true;dojo.provide("i18nTest.nls.legacyBundle.en_us");i18nTest.nls.legacyBundle.en_us={"rootValueOnly":"rootValueOnly","legacyBundle":"legacyBundle"};
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyModule_en.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyModule_en.js
new file mode 100644
index 0000000..f3fb4a8
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build-with-layers/nls/legacyModule_en.js
@@ -0,0 +1 @@
+dojo.provide("i18nTest.nls.legacyModule_en");dojo.provide("i18nTest.nls.legacyBundle");i18nTest.nls.legacyBundle._built=true;dojo.provide("i18nTest.nls.legacyBundle.en");i18nTest.nls.legacyBundle.en={"rootValueOnly":"rootValueOnly","legacyBundle":"legacyBundle"};
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/legacyModule.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/legacyModule.js
new file mode 100644
index 0000000..fafd35f
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/legacyModule.js
@@ -0,0 +1,50 @@
+/*
+	Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+	Available via Academic Free License >= 2.1 OR the modified BSD license.
+	see: http://dojotoolkit.org/license for details
+*/
+
+
+if(!dojo._hasResource["i18nTest.legacyModule"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
+dojo._hasResource["i18nTest.legacyModule"] = true;
+dojo.provide("i18nTest.legacyModule");
+dojo.requireLocalization("i18nTest", "legacyBundle", null, "ROOT,ab,ab-cd-ef");
+
+window.i18nTest.legacyModule = function(){
+	var legacyBundle = dojo.i18n.getLocalization("i18nTest", "legacyBundle"),
+		result = [];
+
+	if(legacyBundle.rootValueOnly!="rootValueOnly"){
+		result.push('legacyBundle.rootValueOnly!="rootValueOnly"');
+	}
+	switch(dojo.locale){
+		case "ab":
+		case "ab-cd":
+			if(legacyBundle.legacyBundle!="legacyBundle-ab"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle-ab"');
+			}
+			if(legacyBundle.abValueOnly!="abValueOnly"){
+				result.push('legacyBundle.abValueOnly!="abValueOnly"');
+			}
+			break;
+		case "ab-cd-ef":
+			if(legacyBundle.legacyBundle!="legacyBundle-ab-cd-ef"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle-ab-cd-ef"');
+			}
+			if(legacyBundle.abValueOnly!="abValueOnly"){
+				result.push('legacyBundle.abValueOnly!="abValueOnly"');
+			}
+			if(legacyBundle.abCdEfValueOnly!="abCdEfValueOnly"){
+				result.push('legacyBundle.abCdEfValueOnly!="abCdEfValueOnly"');
+			}
+			break;
+		default:
+			if(legacyBundle.legacyBundle!="legacyBundle"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle"');
+			}
+	}
+
+	return result.length==0 ? true : result.join(";");
+};
+
+}
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/nls/ab-cd-ef/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/nls/ab-cd-ef/legacyBundle.js
new file mode 100644
index 0000000..992ae02
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/nls/ab-cd-ef/legacyBundle.js
@@ -0,0 +1 @@
+({"abCdEfValueOnly":"abCdEfValueOnly","legacyBundle":"legacyBundle-ab-cd-ef","abValueOnly":"abValueOnly","rootValueOnly":"rootValueOnly"})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/nls/ab/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/nls/ab/legacyBundle.js
new file mode 100644
index 0000000..91cb014
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/nls/ab/legacyBundle.js
@@ -0,0 +1 @@
+({"abValueOnly":"abValueOnly","legacyBundle":"legacyBundle-ab","rootValueOnly":"rootValueOnly"})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/nls/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/nls/legacyBundle.js
new file mode 100644
index 0000000..5a6f414
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/built-i18n-test/152-build/nls/legacyBundle.js
@@ -0,0 +1 @@
+({"rootValueOnly":"rootValueOnly","legacyBundle":"legacyBundle"})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/amdModule.js b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/amdModule.js
new file mode 100644
index 0000000..c7cb4a6
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/amdModule.js
@@ -0,0 +1,41 @@
+define(["dojo/_base/kernel", "dojo/i18n!./nls/amdBundle"], function(dojo, amdBundle){
+	var result = [];
+
+	if(amdBundle.rootValueOnly!="rootValueOnly"){
+		result.push('amdBundle.rootValueOnly!="rootValueOnly"');
+	}
+	switch(dojo.locale){
+		case "ab":
+		case "ab-cd":
+			if(amdBundle.amdBundle!="amdBundle-ab"){
+				result.push('amdBundle.amdBundle!="amdBundle-ab"');
+			}
+			if(amdBundle.abValueOnly!="abValueOnly"){
+				result.push('amdBundle.abValueOnly!="abValueOnly"');
+			}
+			break;
+		case "ab-cd-ef":
+			if(amdBundle.amdBundle!="amdBundle-ab-cd-ef"){
+				result.push('amdBundle.amdBundle!="amdBundle-ab-cd-ef"');
+			}
+			if(amdBundle.abValueOnly!="abValueOnly"){
+				result.push('amdBundle.abValueOnly!="abValueOnly"');
+			}
+			if(amdBundle.abCdEfValueOnly!="abCdEfValueOnly"){
+				result.push('amdBundle.abCdEfValueOnly!="abCdEfValueOnly"');
+			}
+			break;
+		default:
+			if(amdBundle.amdBundle!="amdBundle"){
+				result.push('amdBundle.amdBundle!="amdBundle"');
+			}
+	}
+
+
+	var i18n= require("dojo/i18n");
+	for(var p in i18n._cache) console.log(p);
+
+	return {
+		result:result.length==0 ? true : result.join(";")
+	};
+});
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/build-test-targets.sh b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/build-test-targets.sh
new file mode 100755
index 0000000..57dd45a
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/build-test-targets.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+../util/buildscripts/build.sh -p standard -r --releaseDir ../../built-i18n-test --releaseName rel  --layerOptimize 0 --optimize 0
+../util/buildscripts/build.sh -p standard -p cdn -r --releaseDir ../../../built-i18n-test --releaseName cdn  --layerOptimize 0 --optimize 0
+../util/buildscripts/build.sh -p ../i18n-test/i18n-test -r --layerOptimize 0 --optimize 0
+../util/buildscripts/build.sh -p ../i18n-test/i18n-test-with-layers -r  --layerOptimize 0 --optimize 0
+../util/buildscripts/build.sh -p ../i18n-test/i18n-test-with-layers-and-preloads -r  --layerOptimize 0 --optimize 0
+
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/i18n-test-with-layers-and-preloads.profile.js b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/i18n-test-with-layers-and-preloads.profile.js
new file mode 100644
index 0000000..7435dcf
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/i18n-test-with-layers-and-preloads.profile.js
@@ -0,0 +1,37 @@
+var profile = (function(){
+	return {
+		localeList:"ab,ab-cd-ef",
+		resourceTags:{
+			ignore: function(filename, mid){
+				return /(profile\.js|html)$/.test(filename);
+			},
+
+			amd: function(filename, mid){
+				return mid=="i18nTest/amdModule";
+			}
+		},
+
+		// relative to this file
+		basePath:"..",
+
+		scopeMap:[["dojo", "dojo"], ["dijit",0], ["dojox",0]],
+
+
+		packages:[{
+			name:"dojo",
+			location:"./dojo"
+		},{
+			name:"i18nTest",
+			location:"./i18n-test"
+		}],
+
+		releaseDir:"./built-i18n-test",
+		releaseName:"built-with-layers-and-preloads",
+		localeList:["ab"],
+		layers:{
+			"i18nTest/amdModule":{},
+			"i18nTest/legacyModule":{}
+		}
+	};
+
+})();
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/i18n-test-with-layers.profile.js b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/i18n-test-with-layers.profile.js
new file mode 100644
index 0000000..ca3aa9a
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/i18n-test-with-layers.profile.js
@@ -0,0 +1,35 @@
+var profile = (function(){
+	return {
+		localeList:0,
+		resourceTags:{
+			ignore: function(filename, mid){
+				return /(profile\.js|html)$/.test(filename);
+			},
+
+			amd: function(filename, mid){
+				return mid=="i18nTest/amdModule";
+			}
+		},
+
+		// relative to this file
+		basePath:"..",
+
+		scopeMap:[["dojo", "dojo"], ["dijit",0], ["dojox",0]],
+
+		packages:[{
+			name:"dojo",
+			location:"./dojo"
+		},{
+			name:"i18nTest",
+			location:"./i18n-test"
+		}],
+
+		releaseDir:"./built-i18n-test",
+		releaseName:"built-with-layers",
+		layers:{
+			"i18nTest/amdModule":{},
+			"i18nTest/legacyModule":{}
+		}
+	};
+
+})();
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/i18n-test.profile.js b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/i18n-test.profile.js
new file mode 100644
index 0000000..66ba8f9
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/i18n-test.profile.js
@@ -0,0 +1,30 @@
+var profile = (function(){
+	return {
+		resourceTags:{
+			ignore: function(filename, mid){
+				return /(profile\.js|html)$/.test(filename);
+			},
+
+			amd: function(filename, mid){
+				return mid=="i18nTest/amdModule";
+			}
+		},
+
+		// relative to this file
+		basePath:"..",
+
+		scopeMap:[["dojo", "dojo"], ["dijit",0], ["dojox",0]],
+
+		packages:[{
+			name:"dojo",
+			location:"./dojo"
+		},{
+			name:"i18nTest",
+			location:"./i18n-test"
+		}],
+
+		releaseDir:"./built-i18n-test",
+		releaseName:"built"
+	};
+
+})();
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/legacyModule.js b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/legacyModule.js
new file mode 100644
index 0000000..615b5d5
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/legacyModule.js
@@ -0,0 +1,75 @@
+dojo.provide("i18nTest.legacyModule");
+dojo.requireLocalization("i18nTest", "amdBundle");
+dojo.requireLocalization("i18nTest", "legacyBundle");
+
+i18nTest.legacyModule = function(){
+	var legacyBundle = dojo.i18n.getLocalization("i18nTest", "legacyBundle"),
+		amdBundle = dojo.i18n.getLocalization("i18nTest", "amdBundle"),
+		result = [];
+
+	if(amdBundle.rootValueOnly!="rootValueOnly"){
+		result.push('amdBundle.rootValueOnly!="rootValueOnly"');
+	}
+	switch(dojo.locale){
+		case "ab":
+		case "ab-cd":
+			if(amdBundle.amdBundle!="amdBundle-ab"){
+				result.push('amdBundle.amdBundle!="amdBundle-ab"');
+			}
+			if(amdBundle.abValueOnly!="abValueOnly"){
+				result.push('amdBundle.abValueOnly!="abValueOnly"');
+			}
+			break;
+		case "ab-cd-ef":
+			if(amdBundle.amdBundle!="amdBundle-ab-cd-ef"){
+				result.push('amdBundle.amdBundle!="amdBundle-ab-cd-ef"');
+			}
+			if(amdBundle.abValueOnly!="abValueOnly"){
+				result.push('amdBundle.abValueOnly!="abValueOnly"');
+			}
+			if(amdBundle.abCdEfValueOnly!="abCdEfValueOnly"){
+				result.push('amdBundle.abCdEfValueOnly!="abCdEfValueOnly"');
+			}
+			break;
+		default:
+			if(amdBundle.amdBundle!="amdBundle"){
+				result.push('amdBundle.amdBundle!="amdBundle"');
+			}
+	}
+
+
+	if(legacyBundle.rootValueOnly!="rootValueOnly"){
+		result.push('legacyBundle.rootValueOnly!="rootValueOnly"');
+	}
+	switch(dojo.locale){
+		case "ab":
+		case "ab-cd":
+			if(legacyBundle.legacyBundle!="legacyBundle-ab"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle-ab"');
+			}
+			if(legacyBundle.abValueOnly!="abValueOnly"){
+				result.push('legacyBundle.abValueOnly!="abValueOnly"');
+			}
+			break;
+		case "ab-cd-ef":
+			if(legacyBundle.legacyBundle!="legacyBundle-ab-cd-ef"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle-ab-cd-ef"');
+			}
+			if(legacyBundle.abValueOnly!="abValueOnly"){
+				result.push('legacyBundle.abValueOnly!="abValueOnly"');
+			}
+			if(legacyBundle.abCdEfValueOnly!="abCdEfValueOnly"){
+				result.push('legacyBundle.abCdEfValueOnly!="abCdEfValueOnly"');
+			}
+			break;
+		default:
+			if(legacyBundle.legacyBundle!="legacyBundle"){
+				result.push('legacyBundle.legacyBundle!="legacyBundle"');
+			}
+	}
+
+	var i18n= require("dojo/i18n");
+	for(var p in i18n._cache) console.log(p);
+
+	return result.length==0 ? true : result.join(";");
+};
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab-cd-ef/amdBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab-cd-ef/amdBundle.js
new file mode 100644
index 0000000..9936717
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab-cd-ef/amdBundle.js
@@ -0,0 +1,4 @@
+define({
+	amdBundle:"amdBundle-ab-cd-ef",
+	abCdEfValueOnly:"abCdEfValueOnly"
+});
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab-cd-ef/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab-cd-ef/legacyBundle.js
new file mode 100644
index 0000000..3b69347
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab-cd-ef/legacyBundle.js
@@ -0,0 +1,4 @@
+({
+	legacyBundle:"legacyBundle-ab-cd-ef",
+	abCdEfValueOnly:"abCdEfValueOnly"
+})
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab/amdBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab/amdBundle.js
new file mode 100644
index 0000000..da6dc14
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab/amdBundle.js
@@ -0,0 +1,4 @@
+define({
+	amdBundle:"amdBundle-ab",
+	abValueOnly:"abValueOnly"
+});
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab/legacyBundle.js
new file mode 100644
index 0000000..e768a98
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/ab/legacyBundle.js
@@ -0,0 +1,4 @@
+({
+	legacyBundle:"legacyBundle-ab",
+	abValueOnly:"abValueOnly"
+})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/amdBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/amdBundle.js
new file mode 100644
index 0000000..fd54b87
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/amdBundle.js
@@ -0,0 +1,8 @@
+define({
+	root:{
+		amdBundle:"amdBundle",
+		rootValueOnly:"rootValueOnly"
+	},
+	ab:1,
+	"ab-cd-ef":1
+});
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/legacyBundle.js b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/legacyBundle.js
new file mode 100644
index 0000000..54f4a5a
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/nls/legacyBundle.js
@@ -0,0 +1,4 @@
+({
+	legacyBundle:"legacyBundle",
+	rootValueOnly:"rootValueOnly"
+})
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/unit.html b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/unit.html
new file mode 100644
index 0000000..38dd877
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/i18n-test/unit.html
@@ -0,0 +1,94 @@
+<html>
+<head>
+	<style type="text/css">
+		span.pass {background-color:green}
+		span.fail {background-color:red}
+	</style>	
+</head>
+<body>
+	<p id="status">running</p>
+	<script type="text/javascript">
+
+		//#1,,src,./dojo",src,./dtk-i18n-test
+
+		(function(){
+		var hashInfo = location.search.substring(1),
+			options = hashInfo.split(",");
+			async = options[0]=="async" ? true : undefined,
+			locale = options[1],
+			dojoType = options[2],
+			dojoLocation = options[3],
+			i18nTestType = options[4],
+			i18nTestLocation = options[5],
+			testId = "async: " + async + ", locale: " + locale + ", dojo: " + dojoType + ", i18nTest: " + i18nTestType + "(" + hashInfo + ")",
+			testKind = options[6];
+
+		document.getElementById("status").innerHTML += hashInfo;
+
+		function report(result){
+			require(["doh"], function(doh){
+				doh.register(testId, function(t){
+					t.is(result, true);			
+				});
+				doh.run();
+			});
+
+			var text;
+			if(result===true){
+				text = "<span class='pass'>PASS</span>: " + testId;
+			}else{
+				text = "<span class='fail'>FAIL</span>: " + testId + "<br>" + result;
+			}
+			document.getElementById("status").innerHTML = text;
+		}	
+
+		dojoConfig = {
+			testConfig:options,
+			async:async,
+			locale:locale,
+			baseUrl:"..",
+			packages:[{
+				name:"dojo",
+				location:dojoLocation
+			},{
+				name:"doh",
+				location:"./util/doh"
+			},{
+				name:"i18nTest",
+				location:i18nTestLocation
+			}],
+			callback:function(){
+				switch(testKind){
+					case "legacy":
+						if(/legacy-built/.test(i18nTestType) && /layer/.test(i18nTestType)){
+							// ensure the 1.7+ i18n plugin is on board before trying to load a legacy-built module as a layer
+							require(["dojo/i18n"], function(){
+								require(["i18nTest/legacyModule"], function(){
+									report(i18nTest.legacyModule());
+								});
+							});
+						}else{
+							require(["i18nTest/legacyModule"], function(){
+								report(i18nTest.legacyModule());
+							});
+						}
+						break;
+
+					case "amd":
+						require(["i18nTest/amdModule"], function(amdModule){
+							report(amdModule.result);
+						});
+						break;
+				}
+			}
+		};
+		var node = document.createElement("script");
+		node.type = "text/javascript";
+		node.charset = "utf-8";
+		node.src = (/^http/.test(dojoLocation) ? dojoLocation :  "../" + dojoLocation) + "/dojo.js";
+console.log(node.src);
+		document.getElementsByTagName("head")[0].appendChild(node);
+		})();
+	</script>
+</body>
+</html>
diff --git a/dojo/tests/_base/loader/i18n-exhaustive/test-instructions.md b/dojo/tests/_base/loader/i18n-exhaustive/test-instructions.md
new file mode 100644
index 0000000..d840181
--- /dev/null
+++ b/dojo/tests/_base/loader/i18n-exhaustive/test-instructions.md
@@ -0,0 +1,64 @@
+Analysis of i18n Bundle Loading in 1.7+
+=======================================
+
+As of v.17, there are many combinations of loading i18n bundles depending on the input modules, the loader mode, the
+build profile, and the deployment scenario. This document attempts to list them all.
+
+Input Modules
+-------------
+
+A module may be expressed as
+
+  1. An AMD module with an i18n plugin resource id dependency referencing an i18n bundle that is in AMD format (an AMD
+  module cannot load a legacy bundle without using the legacy API).
+	  
+  2. A legacy module with a dojo.requireLocalization/dojo.getLocalization applications referencing an i18n bundle that
+  is either in AMD or legacy format.
+	  
+  3. [1] Built by the 1.7 builder as a module
+  
+  4. [1] Built by the 1.7 builder in a layer with some locales to be preloaded and some not
+  
+  5. [2] Built by the 1.7 builder as a module
+  
+  6. [2] Built by the 1.7 builder in a layer with some locales to be preloaded and some not
+  
+  7. [2] Built by the 1.6- builder (not xdomain) as a module with some locales to be preloaded and some not
+  
+  8. [2] Built by the 1.6- builder (not xdomain) in a layer with some locales to be preloaded and some not
+  
+Note: the i18n/loader does not currently support loading modules built with the 1.6- builder with loader=xdomain
+
+Load Scenarios
+--------------
+
+With these modules, there are several load scenarios
+
+  1. Loading with a bundle available for the current locale specialization (i.e. the value of dojo.locale) or not.
+
+  2. Loading with a preload bundle available for the current locale specialization (i.e. the value of dojo.locale) or not.
+  
+Crossed with
+
+  1. The source version of the loader in sync mode or async mode; [2, 7, 8] won't work in async.
+  
+  2. A built version of the loader in sync mode or async mode; [2, 7, 8] won't work in async. Use
+    
+  3. The CDN version of the loader located xdomain in sync and async mode;  [2, 7, 8] won't work in async. Use
+
+Test Design and Execution
+-------------------------
+
+The sources required for this test are in dojo/tests/_base/loader/i18n-exhaustive. Copy the two directories there to be
+siblings of the dojo tree in a dtk source distribution.
+
+The source modules as described in Input Modules are constructed in the subdirectory i18n-test. The v1.5.2 builder is
+used to construct various built, legacy modules.
+
+The various built module and loaders are constructed by the v1.7 builder. The shell script
+i18n-test/build-test-targets.sh accomplishes this task automatically.
+
+A unit test html page is constructed at i18n-test/unit.html. Given a query string, it will load a particular loader and
+exercise a particular set of modules.
+
+Finally, the DOH test dojo/tests/_base/i18nExhaustive runs all the various combinations.
diff --git a/dojo/tests/_base/loader/moduleIds.js b/dojo/tests/_base/loader/moduleIds.js
index 52cd2a6..45b6ff1 100644
--- a/dojo/tests/_base/loader/moduleIds.js
+++ b/dojo/tests/_base/loader/moduleIds.js
@@ -52,7 +52,7 @@ define(["doh", "dojo", "dojo/_base/url"], function(doh, dojo){
 			});
 
 			function get(mid, refmod){
-				return require.getModuleInfo(mid, refmod, require.packs, require.modules, "../../dojo/", require.packageMapProg, require.pathsMapProg, 1);
+				return require.getModuleInfo(mid, refmod, require.packs, require.modules, "../../dojo/", require.mapProgs, require.pathsMapProg, 1);
 			}
 
 			function check(result, expectedPid, expectedMidSansPid, expectedUrl){
@@ -76,13 +76,13 @@ define(["doh", "dojo", "dojo/_base/url"], function(doh, dojo){
 			check(get("pack3/myModule"), "pack3", "myModule", "/pack3Root/myModule");
 
 			// relative module id resolution; relative to module in top-level
-			var refmod= {mid:"pack1/main", pack:require.packageMap.pack1};
+			var refmod= {mid:"pack1/main", pack:require.packs.pack1};
 			check(get(".", refmod), "pack1", "main", pack1Root + "main");
 			check(get("./myModule", refmod), "pack1", "myModule", pack1Root + "myModule");
 			check(get("./myModule/mySubmodule", refmod), "pack1", "myModule/mySubmodule", pack1Root + "myModule/mySubmodule");
 
 			// relative module id resolution; relative to module
-			refmod= {mid:"pack1/sub/publicModule", pack:require.packageMap.pack1};
+			refmod= {mid:"pack1/sub/publicModule", pack:require.packs.pack1};
 			check(get(".", refmod), "pack1", "sub", pack1Root + "sub");
 			check(get("./myModule", refmod), "pack1", "sub/myModule", pack1Root + "sub/myModule");
 			check(get("..", refmod), "pack1", "main", pack1Root + "main");
diff --git a/dojo/tests/_base/loader/modules.js b/dojo/tests/_base/loader/modules.js
index 108ffa3..a4ceb54 100644
--- a/dojo/tests/_base/loader/modules.js
+++ b/dojo/tests/_base/loader/modules.js
@@ -6,7 +6,11 @@ define([
 	"./modules/wrapped",
 	"dojo/tests/_base/loader/modules/full",
 	"./modules/data",
-	"./modules/factoryArity"], function(doh, dojo, require, anon, wrapped){
+	"./modules/factoryArity",
+	"./modules/factoryArityExports",
+	"./modules/idFactoryArity",
+	"./modules/idFactoryArityExports"
+], function(doh, dojo, require, anon, wrapped){
 
 	doh.register("dojo.tests._base._loader.modules", [
 		function testAMD(t){
@@ -17,7 +21,22 @@ define([
 			t.is(dojo.require('dojo.tests._base.loader.modules.wrapped'), require('./modules/wrapped'));
 			t.is(require('./modules/full').twiceTheAnswer, 84);
 			t.is(require('./modules/data').five, 5);
-			t.is(require('./modules/factoryArity').i, 5);
+
+			t.is(require('./modules/factoryArity').module.id, "dojo/tests/_base/loader/modules/factoryArity");
+			t.is(require('./modules/factoryArity').id, "factoryArity");
+			t.is(require('./modules/factoryArity').impliedDep, "impliedDep1");
+
+			t.is(require('./modules/factoryArityExports').module.id, "dojo/tests/_base/loader/modules/factoryArityExports");
+			t.is(require('./modules/factoryArityExports').id, "factoryArityExports");
+			t.is(require('./modules/factoryArityExports').impliedDep, "impliedDep2");
+
+			t.is(require('./modules/idFactoryArity').module.id, "dojo/tests/_base/loader/modules/idFactoryArity");
+			t.is(require('./modules/idFactoryArity').id, "idFactoryArity");
+			t.is(require('./modules/idFactoryArity').impliedDep, "impliedDep3");
+
+			t.is(require('./modules/idFactoryArityExports').module.id, "dojo/tests/_base/loader/modules/idFactoryArityExports");
+			t.is(require('./modules/idFactoryArityExports').id, "idFactoryArityExports");
+			t.is(require('./modules/idFactoryArityExports').impliedDep, "impliedDep4");
 		}
 	]);
 });
diff --git a/dojo/tests/_base/loader/modules/anon.js b/dojo/tests/_base/loader/modules/anon.js
index 1bfeb82..2c8476f 100644
--- a/dojo/tests/_base/loader/modules/anon.js
+++ b/dojo/tests/_base/loader/modules/anon.js
@@ -1,4 +1,4 @@
-define(["../a", "./wrapped"], function (a, wrapped) {
+define(["../a", "./wrapped"], function(a, wrapped){
 	return {
 		theAnswer: a.number,
 		five: wrapped.five
diff --git a/dojo/tests/_base/loader/modules/factoryArity.js b/dojo/tests/_base/loader/modules/factoryArity.js
index 75f0839..e14ab82 100644
--- a/dojo/tests/_base/loader/modules/factoryArity.js
+++ b/dojo/tests/_base/loader/modules/factoryArity.js
@@ -1,2 +1,8 @@
-// make sure that module.exports doesn't kill factory result since factory has arity<3
-define(function() { return {i : 5} ; });
\ No newline at end of file
+define(function(require, exports, module){
+	var impliedDep = require("./impliedDep1");
+	return {
+		module:module,
+		id:"factoryArity",
+		impliedDep:impliedDep.id
+	};
+});
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/modules/factoryArityExports.js b/dojo/tests/_base/loader/modules/factoryArityExports.js
new file mode 100644
index 0000000..cf9b85b
--- /dev/null
+++ b/dojo/tests/_base/loader/modules/factoryArityExports.js
@@ -0,0 +1,8 @@
+define(function(require, exports, module){
+	var impliedDep = require("./impliedDep2");
+	require("dojo/_base/lang").mixin(exports, {
+		module:module,
+		id:"factoryArityExports",
+		impliedDep:impliedDep.id
+	});
+});
diff --git a/dojo/tests/_base/loader/modules/full.js b/dojo/tests/_base/loader/modules/full.js
index 1263724..3ebc20c 100644
--- a/dojo/tests/_base/loader/modules/full.js
+++ b/dojo/tests/_base/loader/modules/full.js
@@ -1,4 +1,4 @@
-define("dojo/tests/_base/loader/modules/full", ["./anon", "../a", "./wrapped", "require"], function (anon, a, wrapped, require) {
+define("dojo/tests/_base/loader/modules/full", ["./anon", "../a", "./wrapped", "require"], function(anon, a, wrapped, require){
 	return {
 		twiceTheAnswer: a.number + require("../a").number
 	};
diff --git a/dojo/tests/_base/loader/modules/idFactoryArity.js b/dojo/tests/_base/loader/modules/idFactoryArity.js
new file mode 100644
index 0000000..4203ea8
--- /dev/null
+++ b/dojo/tests/_base/loader/modules/idFactoryArity.js
@@ -0,0 +1,8 @@
+define("dojo/tests/_base/loader/modules/idFactoryArity", function(require, exports, module){
+	var impliedDep = require("./impliedDep3");
+	return {
+		module:module,
+		id:"idFactoryArity",
+		impliedDep:impliedDep.id
+	};
+});
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/modules/idFactoryArityExports.js b/dojo/tests/_base/loader/modules/idFactoryArityExports.js
new file mode 100644
index 0000000..12a5be8
--- /dev/null
+++ b/dojo/tests/_base/loader/modules/idFactoryArityExports.js
@@ -0,0 +1,8 @@
+define("dojo/tests/_base/loader/modules/idFactoryArityExports", function(require, exports, module){
+	var impliedDep = require("./impliedDep4");
+	require("dojo/_base/lang").mixin(exports, {
+		module:module,
+		id:"idFactoryArityExports",
+		impliedDep:impliedDep.id
+	});
+});
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/modules/impliedDep1.js b/dojo/tests/_base/loader/modules/impliedDep1.js
new file mode 100644
index 0000000..3595761
--- /dev/null
+++ b/dojo/tests/_base/loader/modules/impliedDep1.js
@@ -0,0 +1,3 @@
+define({
+	id:"impliedDep1"
+});
diff --git a/dojo/tests/_base/loader/modules/impliedDep2.js b/dojo/tests/_base/loader/modules/impliedDep2.js
new file mode 100644
index 0000000..e561794
--- /dev/null
+++ b/dojo/tests/_base/loader/modules/impliedDep2.js
@@ -0,0 +1,3 @@
+define({
+	id:"impliedDep2"
+});
diff --git a/dojo/tests/_base/loader/modules/impliedDep3.js b/dojo/tests/_base/loader/modules/impliedDep3.js
new file mode 100644
index 0000000..0b752cc
--- /dev/null
+++ b/dojo/tests/_base/loader/modules/impliedDep3.js
@@ -0,0 +1,3 @@
+define({
+	id:"impliedDep3"
+});
diff --git a/dojo/tests/_base/loader/modules/impliedDep4.js b/dojo/tests/_base/loader/modules/impliedDep4.js
new file mode 100644
index 0000000..511a46d
--- /dev/null
+++ b/dojo/tests/_base/loader/modules/impliedDep4.js
@@ -0,0 +1,3 @@
+define({
+	id:"impliedDep4"
+});
diff --git a/dojo/tests/_base/loader/modules/wrapped.js b/dojo/tests/_base/loader/modules/wrapped.js
index a98c602..c0d9e0e 100644
--- a/dojo/tests/_base/loader/modules/wrapped.js
+++ b/dojo/tests/_base/loader/modules/wrapped.js
@@ -1,13 +1,13 @@
 if(require.has("dojo-amd-factory-scan")){
 
-define(function (require, exports, module) {
+define(function(require, exports, module){
 	exports.five = require("./data").five;
 	exports.exports = module.exports;
 });
 
 }else{
 
-define(["require", "exports", "module"], function (require, exports, module) {
+define(["require", "exports", "module"], function(require, exports, module){
 	exports.five = require("./data").five;
 	exports.exports = module.exports;
 });
diff --git a/dojo/tests/_base/loader/onerror.html b/dojo/tests/_base/loader/onerror.html
new file mode 100644
index 0000000..d9dfaaf
--- /dev/null
+++ b/dojo/tests/_base/loader/onerror.html
@@ -0,0 +1,151 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>AMD Loader Test</title> 
+		<script type="text/javascript">
+			dojoConfig = {
+				parseOnLoad: false,
+				mblHideAddressBar: false,	
+				mblAndroidWorkaround: false,
+                mblAlwaysHideAddressBar: false,
+				traceSet:{
+					"loader-inject":0,
+					"loader-define":0,
+					"loader-runFactory":0,
+					"loader-execModule":0,
+					"loader-execModule-out":0,
+					"loader-defineModule":0
+				},
+				hasCache:{
+					"config-dojo-loader-catches":1
+				},
+				async:true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo.js"></script>
+		<script>
+			function testRequire(deps, sync){
+				console.log("test require error start");
+				require(["dojo/_base/Deferred"], function(Deferred){
+					var def1 = new Deferred();
+					var def2 = new Deferred();
+					
+					// test done when def1 resolved.
+					Deferred.when(def1, function(){
+						console.log("def1 resolved, test success.");
+					},
+					function(){
+						console.log("def1 reject, error occurred in testing");
+					});
+					
+					// resolve def1 if def2 resolved.
+					Deferred.when(def2, function(){
+						console.log("def2 resolved, will resolve def1.");
+						def1.resolve("def1 success");
+					},
+					function(){
+						console.log("def2 reject, will reject def1");
+						def1.reject("def1 reject");
+					});
+					
+					//resolve def2 if require dependencies done
+					var requireSignal;
+					requireSignal = require.on("error", function(error){
+						if(def2.fired != -1){
+							return;
+						}
+						console.error("get error event in require on.", error);
+						def2.reject("load dependencies error.");
+						requireSignal.remove();
+					});
+				
+					try {
+						var dependences = [];
+						dependences.push(deps);
+						require(dependences, function(){
+							def2.resolve("def2 resolved");
+							requireSignal.remove();
+						});
+					}catch(ex){
+						console.error("catch in require. ", ex);
+						requireSignal.remove();
+					}
+				});
+			}
+			
+			function testRequireNoexist(count, exist){
+				var str = exist?"exist ":"noexist ";
+				console.log("test "+str+count+" times start...");
+				var deps;
+				if(exist){
+					deps = ["dojo/_base/lang"];
+				}else{
+					deps = ["dojo/error/noexist"];
+				}
+				var startTime = new Date().getTime();
+				for(var i=0; i<count; i++){
+					var requireSignal;
+					requireSignal = require.on("error", function(error){
+						console.error("get error event in require on.", error);
+						requireSignal.remove();
+					});
+				
+					try {
+						require(deps, function(){
+							requireSignal.remove();
+						});
+					}catch(ex){
+						console.error("catch in require. ", ex);
+						requireSignal.remove();
+					}
+				}
+				var endTime = new Date().getTime();
+				console.log("test done. costs: "+(endTime-startTime)+"ms");
+			}
+		</script>
+	</head>
+	<body>
+		<h1>See the logs in console.</h1>
+		<p>Issue 1:<br/> This is the dojo AMD loader(require) async test.<br/>
+		 Click on "test require success" button to test require success.<br/>
+		 Click on "test require error" button to test require error and process require error.<br/>
+		 <font color="red">Click on "test require error" button again, the console output nothing, but the expect is output error again like before.</font>
+		<p>
+		<input type="button" value="test require async success" onclick="testRequire('dojo/_base/lang')" />
+		<input type="button" value="test require async error" onclick="testRequire('dojo/require/error')" /><br/>
+		
+		<p>Issue 2:<br/> This is the dojo AMD loader(require) sync test. <b>Please modify dojoConfig.async=false first.</b><br/>
+		 Click on "test require sync success" button to test require plugin success.<br/>
+		 Click on "test require sync error" button to test require plugin error and process require error.<br/>
+		 <font color="red">You can see the 404 Not Found error and catch in require output.<br/>
+		 This error is catched in catch statement, but not trigger require.on("error"). Not sure this is a defect of dojo AMD loader, but seems an error should trigger require.on("error")</font>
+		<p>
+		<input type="button" value="test require sync success" onclick="testRequire('dojo/_base/lang', true)" />
+		<input type="button" value="test require sync error" onclick="testRequire('dojo/require/error', true)" /><br/>
+		
+		<p>Issue 3:<br/> This is the dojo AMD loader plugin(dojo/text) test.<br/>
+		 Click on "test require plugin success" button to test require plugin success.<br/>
+		 Click on "test require plugin error" button to test require plugin error and process require error.<br/>
+		 <font color="red">You can see xhr plugin throw Unable to load ./requireerror.html status:404 error, but require.on("error") not be triggered as expect.<br/>
+		 In fact, require.on("error") is triggered by "timeout" error event after 30 seconds.</font>
+		<p>
+		<input type="button" value="test require plugin success" onclick="testRequire('dojo/text!./onerror.html')" />
+		<input type="button" value="test require plugin error" onclick="testRequire('dojo/text!./requireerror.html')" /><br/>
+		
+		<p>Issue 4:<br/> require not exist module test.<br/>
+		<font color="red">This test is the same as issue 1. require a not exist module more than one times will cause the require waiting list increament, and each new require will check the waiting list. If the waiting list is too big, the require perform is very low.
+		Click on "100", "1000", "10000" and "100000" button to test. You can see require a not exist module 10000 times is cannot tolerant, the browser almost crush when require 100000 times.
+		</font>
+		
+		<p>
+		<input type="button" value="Exist 100" onclick="testRequireNoexist(100, true)" />
+		<input type="button" value="Exist 1000" onclick="testRequireNoexist(1000, true)" />
+		<input type="button" value="Exist 10000" onclick="testRequireNoexist(10000, true)" />
+		<input type="button" value="Exist 100000" onclick="testRequireNoexist(100000, true)" />
+		<br/>
+		<input type="button" value="NoExist 100" onclick="testRequireNoexist(100)" />
+		<input type="button" value="NoExist 1000" onclick="testRequireNoexist(1000)" />
+		<input type="button" value="NoExist 10000" onclick="testRequireNoexist(10000)" />
+		<input type="button" value="NoExist 100000" onclick="testRequireNoexist(100000)" />
+	</body>
+</html>
diff --git a/dojo/tests/_base/loader/require/m1.js b/dojo/tests/_base/loader/require/m1.js
new file mode 100644
index 0000000..aff1a91
--- /dev/null
+++ b/dojo/tests/_base/loader/require/m1.js
@@ -0,0 +1,13 @@
+define(["dojo", "dojo/require!dojo/hash,dojo/tests/_base/loader/require/m2"], function(dojo){
+  console.log("m1, a plain-old-style synch module wrapped in dojo/require!, evaluate start");
+  dojo.provide("dojo.tests._base.loader.require.m1");
+  dojo.require("dojo.tests._base.loader.require.m2");
+  console.log("the value of m2 in m1 is: " + dojo.tests._base.loader.require.m2);
+  dojo.tests._base.loader.require.m1 = "this is the value of m1";
+
+  dojo.ready(function(){
+    console.log("ready in m1 called");
+  });
+  console.log("m1 evaluate end");
+});
+
diff --git a/dojo/tests/_base/loader/require/m2.js b/dojo/tests/_base/loader/require/m2.js
new file mode 100644
index 0000000..ec8e048
--- /dev/null
+++ b/dojo/tests/_base/loader/require/m2.js
@@ -0,0 +1,5 @@
+dojo.provide("dojo.tests._base.loader.require.m2");
+console.log("m2, a plain-old-style synch module, evaluated OK");
+
+dojo.tests._base.loader.require.m2 = "this is the value of m2";
+
diff --git a/dojo/tests/_base/loader/require/test-require-plugin.html b/dojo/tests/_base/loader/require/test-require-plugin.html
new file mode 100644
index 0000000..766ee49
--- /dev/null
+++ b/dojo/tests/_base/loader/require/test-require-plugin.html
@@ -0,0 +1,33 @@
+<html>
+  <head>
+	  <script src=../../../../dojo.js></script>
+	  <script>
+		dojo.require("dojo.tests._base.loader.require.m1");
+		dojo.ready(function(){
+			dojo.byId("msg").innerHTML = "OK";
+			console.log("the value of m1 at completion is: " + dojo.tests._base.loader.require.m1);
+			console.log("the value of m2 at completion is: " + dojo.tests._base.loader.require.m2);
+		});
+	  </script>
+  </head>
+  <body>
+    <div id="msg">loading</div>
+	<p>
+		This test dojo.require's a module (m1) that is a legacy module that
+		depends on another legacy module (m2). m1 is wrapped in dojo/require!
+		to guarantee that m2 is onboard before m1 starts evaluating. The
+		loading message above should change to "OK" and you should see the
+		following console ouput:
+	</p>
+	<pre>
+m2, a plain-old-style synch module, evaluated OK
+m1, a plain-old-style synch module wrapped in dojo/require!, evaluate start
+the value of m2 in m1 is: this is the value of m2
+m1 evaluate end
+ready in m1 called
+the value of m1 at completion is: this is the value of m1
+the value of m2 at completion is: this is the value of m2
+	</pre>
+  </body>
+</html>
+  
diff --git a/dojo/tests/_base/loader/requirejs/bar b/dojo/tests/_base/loader/requirejs/bar
index 6f020ce..0816c81 100644
--- a/dojo/tests/_base/loader/requirejs/bar
+++ b/dojo/tests/_base/loader/requirejs/bar
@@ -2,4 +2,4 @@
 
 bar = {
     name: "bar"
-};
\ No newline at end of file
+};
diff --git a/dojo/tests/_base/loader/requirejs/circular-tests.js b/dojo/tests/_base/loader/requirejs/circular-tests.js
index 625c4af..feba2b6 100644
--- a/dojo/tests/_base/loader/requirejs/circular-tests.js
+++ b/dojo/tests/_base/loader/requirejs/circular-tests.js
@@ -1,12 +1,12 @@
 require(
     ["require", "two", "funcTwo", "funcThree", "doh"],
-    function(require, two, funcTwo, funcThree, doh) {
+    function(require, two, funcTwo, funcThree, doh){
         var args = two.doSomething();
         var twoInst = new funcTwo("TWO");
         doh.register(
             "circular",
             [
-                function circular(t) {
+                function circular(t){
                     t.is("small", args.size);
                     t.is("redtwo", args.color);
                 }
@@ -17,7 +17,7 @@ require(
         doh.register(
             "circularFunc",
             [
-                function circularFunc(t) {
+                function circularFunc(t){
                     t.is("TWO", twoInst.name);
                     t.is("ONE-NESTED", twoInst.oneName());
                     t.is("THREE-THREE_SUFFIX", funcThree("THREE"));
diff --git a/dojo/tests/_base/loader/requirejs/dataMain.js b/dojo/tests/_base/loader/requirejs/dataMain.js
index c2f6ed2..b4ef86e 100644
--- a/dojo/tests/_base/loader/requirejs/dataMain.js
+++ b/dojo/tests/_base/loader/requirejs/dataMain.js
@@ -2,7 +2,7 @@ require({
         baseUrl: "./"
     },
     ["require", "simple", "doh"],
-    function(require, simple, doh) {
+    function(require, simple, doh){
         doh.register(
             "dataMain",
             [
diff --git a/dojo/tests/_base/loader/requirejs/depoverlap.js b/dojo/tests/_base/loader/requirejs/depoverlap.js
index 6af8756..a84ad9f 100644
--- a/dojo/tests/_base/loader/requirejs/depoverlap.js
+++ b/dojo/tests/_base/loader/requirejs/depoverlap.js
@@ -1,17 +1,16 @@
 require(["require", "uno", "doh"],
-function (require, uno, doh) {
+function(require, uno, doh){
     doh.register(
         "depoverlap",
         [
             function depoverlap(t){
-                //First confirm there is only one script tag for each
-                //module:
+                //First confirm there is only one script tag for each module:
                 var scripts = document.getElementsByTagName("script"),
                     i, counts = {}, modName, props, something;
-                for (var i = scripts.length - 1; i > -1; i--) {
+                for (var i = scripts.length - 1; i > -1; i--){
                     modName = scripts[i].getAttribute("data-requiremodule");
-                    if (modName) {
-                        if (!(modName in counts)) {
+                    if (modName){
+                        if (!(modName in counts)){
                             counts[modName] = 0;
                         }
                         counts[modName] += 1;
@@ -20,7 +19,7 @@ function (require, uno, doh) {
 
                 //Now that we counted all the modules make sure count
                 //is always one.
-                for (prop in counts) {
+                for (prop in counts){
                     t.is(1, counts[prop]);
                 }
 
diff --git a/dojo/tests/_base/loader/requirejs/dos.js b/dojo/tests/_base/loader/requirejs/dos.js
index 1a28c65..bd33a52 100644
--- a/dojo/tests/_base/loader/requirejs/dos.js
+++ b/dojo/tests/_base/loader/requirejs/dos.js
@@ -1,9 +1,9 @@
 define("dos",
   ["tres"],
-  function(tres) {
+  function(tres){
     return {
       name: "dos",
-      doSomething: function() {
+      doSomething: function(){
         return {
           tresName: tres.name
         };
diff --git a/dojo/tests/_base/loader/requirejs/exports/assign.js b/dojo/tests/_base/loader/requirejs/exports/assign.js
index d260a90..144e7ed 100644
--- a/dojo/tests/_base/loader/requirejs/exports/assign.js
+++ b/dojo/tests/_base/loader/requirejs/exports/assign.js
@@ -1,5 +1,5 @@
 define("assign",
             ["require", "exports", "module"],
-            function (require, exports, module) {
+            function(require, exports, module){
     module.exports = "assign";
 });
diff --git a/dojo/tests/_base/loader/requirejs/exports/assign2.js b/dojo/tests/_base/loader/requirejs/exports/assign2.js
index c6cd0c8..7048b94 100644
--- a/dojo/tests/_base/loader/requirejs/exports/assign2.js
+++ b/dojo/tests/_base/loader/requirejs/exports/assign2.js
@@ -1,4 +1,4 @@
 define(["module", "exports", "require"],
-            function (module, exports, require) {
+            function(module, exports, require){
     module.exports = "assign2";
 });
diff --git a/dojo/tests/_base/loader/requirejs/exports/exports-tests.js b/dojo/tests/_base/loader/requirejs/exports/exports-tests.js
index b31acf5..1e66753 100644
--- a/dojo/tests/_base/loader/requirejs/exports/exports-tests.js
+++ b/dojo/tests/_base/loader/requirejs/exports/exports-tests.js
@@ -4,7 +4,7 @@ require({
     ["require", "vanilla", "funcSet", "assign", "assign2", "usethis",
      "implicitModule", "simpleReturn", "doh"],
     function(require, vanilla, funcSet, assign, assign2, usethis,
-      implicitModule, simpleReturn, doh) {
+      implicitModule, simpleReturn, doh){
         doh.register(
             "exports",
             [
diff --git a/dojo/tests/_base/loader/requirejs/exports/funcSet.js b/dojo/tests/_base/loader/requirejs/exports/funcSet.js
index 5f10a31..31e030a 100644
--- a/dojo/tests/_base/loader/requirejs/exports/funcSet.js
+++ b/dojo/tests/_base/loader/requirejs/exports/funcSet.js
@@ -1,5 +1,5 @@
 define("funcSet",
             ["require", "exports", "module"],
-            function (require, exports, module) {
+            function(require, exports, module){
     module.setExports("funcSet");
 });
diff --git a/dojo/tests/_base/loader/requirejs/exports/implicitModule.js b/dojo/tests/_base/loader/requirejs/exports/implicitModule.js
index 4c021d3..c10ed1d 100644
--- a/dojo/tests/_base/loader/requirejs/exports/implicitModule.js
+++ b/dojo/tests/_base/loader/requirejs/exports/implicitModule.js
@@ -1,6 +1,6 @@
-define(function (require, exports, module) {
-    if (module.exports) {
-        module.exports = function () {
+define(function(require, exports, module){
+    if (module.exports){
+        module.exports = function(){
             return 'implicitModule';
         };
     }
diff --git a/dojo/tests/_base/loader/requirejs/exports/simpleReturn.js b/dojo/tests/_base/loader/requirejs/exports/simpleReturn.js
index 7b5e7f0..c2fb78a 100644
--- a/dojo/tests/_base/loader/requirejs/exports/simpleReturn.js
+++ b/dojo/tests/_base/loader/requirejs/exports/simpleReturn.js
@@ -2,8 +2,8 @@
 //return, but need to test that it does not
 //automatically get an exports object assigned
 define(
-    function () {
-        return function () {
+    function(){
+        return function(){
             return 'simpleReturn';
         };
     }
diff --git a/dojo/tests/_base/loader/requirejs/exports/usethis.js b/dojo/tests/_base/loader/requirejs/exports/usethis.js
index 1c19f05..6f55b75 100644
--- a/dojo/tests/_base/loader/requirejs/exports/usethis.js
+++ b/dojo/tests/_base/loader/requirejs/exports/usethis.js
@@ -1,3 +1,3 @@
-define(function (require, exports) {
+define(function(require, exports){
     this.name = 'usethis';
 });
diff --git a/dojo/tests/_base/loader/requirejs/exports/vanilla.js b/dojo/tests/_base/loader/requirejs/exports/vanilla.js
index 2168e47..1ba1e8a 100644
--- a/dojo/tests/_base/loader/requirejs/exports/vanilla.js
+++ b/dojo/tests/_base/loader/requirejs/exports/vanilla.js
@@ -1,5 +1,5 @@
 define("vanilla",
             ["require", "exports", "module"],
-            function (require, exports, module) {
+            function(require, exports, module){
     exports.name = "vanilla";
 });
diff --git a/dojo/tests/_base/loader/requirejs/foo b/dojo/tests/_base/loader/requirejs/foo
index d6a4cde..91e7b72 100644
--- a/dojo/tests/_base/loader/requirejs/foo
+++ b/dojo/tests/_base/loader/requirejs/foo
@@ -2,4 +2,4 @@
 
 foo = {
     name: "foo"
-};
\ No newline at end of file
+};
diff --git a/dojo/tests/_base/loader/requirejs/func.js b/dojo/tests/_base/loader/requirejs/func.js
index 6e4775f..11b9396 100644
--- a/dojo/tests/_base/loader/requirejs/func.js
+++ b/dojo/tests/_base/loader/requirejs/func.js
@@ -1,7 +1,7 @@
 define("func",
-    function () {
-        return function () {
+    function(){
+        return function(){
             return "You called a function";
-        }
+        };
     }
 );
diff --git a/dojo/tests/_base/loader/requirejs/funcFour.js b/dojo/tests/_base/loader/requirejs/funcFour.js
index 12db975..e8f71dd 100644
--- a/dojo/tests/_base/loader/requirejs/funcFour.js
+++ b/dojo/tests/_base/loader/requirejs/funcFour.js
@@ -1,11 +1,11 @@
 define("funcFour",
     ["require", "funcThree"],
-    function (require) {
-        var four = function (arg) {
+    function(require){
+        var four = function(arg){
             return "FOUR called with " + arg;
         };
 
-        four.suffix = function () {
+        four.suffix = function(){
             return require("funcThree").suffix();
         };
 
diff --git a/dojo/tests/_base/loader/requirejs/funcOne.js b/dojo/tests/_base/loader/requirejs/funcOne.js
index 4620592..c222045 100644
--- a/dojo/tests/_base/loader/requirejs/funcOne.js
+++ b/dojo/tests/_base/loader/requirejs/funcOne.js
@@ -1,11 +1,11 @@
 define("funcOne",
     ["require", "funcTwo"],
-    function (require) {
-        var one = function (name) {
+    function(require){
+        var one = function(name){
             this.name = name;
         };
 
-        one.prototype.getName = function () {
+        one.prototype.getName = function(){
             var inst = new (require("funcTwo"))("-NESTED");
             return this.name + inst.name;
         };
diff --git a/dojo/tests/_base/loader/requirejs/funcThree.js b/dojo/tests/_base/loader/requirejs/funcThree.js
index b02bf89..18a9314 100644
--- a/dojo/tests/_base/loader/requirejs/funcThree.js
+++ b/dojo/tests/_base/loader/requirejs/funcThree.js
@@ -1,11 +1,11 @@
 define("funcThree",
     ["funcFour"],
-    function (four) {
-        var three = function (arg) {
+    function(four){
+        var three = function(arg){
             return arg + "-" + require("funcFour").suffix();
         };
 
-        three.suffix = function () {
+        three.suffix = function(){
             return "THREE_SUFFIX";
         };
 
diff --git a/dojo/tests/_base/loader/requirejs/funcTwo.js b/dojo/tests/_base/loader/requirejs/funcTwo.js
index 38afc0e..7480511 100644
--- a/dojo/tests/_base/loader/requirejs/funcTwo.js
+++ b/dojo/tests/_base/loader/requirejs/funcTwo.js
@@ -1,12 +1,12 @@
 define("funcTwo",
     ["require", "funcOne"],
-    function (require) {
-        var two = function (name) {
+    function(require){
+        var two = function(name){
             this.name = name;
             this.one = new (require("funcOne"))("ONE");
         };
     
-        two.prototype.oneName = function () {
+        two.prototype.oneName = function(){
             return this.one.getName();
         };
 
diff --git a/dojo/tests/_base/loader/requirejs/i18n/commonA.js b/dojo/tests/_base/loader/requirejs/i18n/commonA.js
index fcdf974..63d8ec6 100644
--- a/dojo/tests/_base/loader/requirejs/i18n/commonA.js
+++ b/dojo/tests/_base/loader/requirejs/i18n/commonA.js
@@ -1,3 +1,3 @@
-define(['i18n!nls/colors'], function (colors) {
+define(['i18n!nls/colors'], function(colors){
    return colors.red;
 });
diff --git a/dojo/tests/_base/loader/requirejs/i18n/commonB.js b/dojo/tests/_base/loader/requirejs/i18n/commonB.js
index 3e7c43e..334f577 100644
--- a/dojo/tests/_base/loader/requirejs/i18n/commonB.js
+++ b/dojo/tests/_base/loader/requirejs/i18n/commonB.js
@@ -1,3 +1,3 @@
-define(['i18n!nls/colors'], function (colors) {
+define(['i18n!nls/colors'], function(colors){
    return colors.blue;
 });
diff --git a/dojo/tests/_base/loader/requirejs/i18n/testModule.js b/dojo/tests/_base/loader/requirejs/i18n/testModule.js
index 7bafb5c..cbbd779 100644
--- a/dojo/tests/_base/loader/requirejs/i18n/testModule.js
+++ b/dojo/tests/_base/loader/requirejs/i18n/testModule.js
@@ -1,4 +1,4 @@
 //A sample module to use in the i18n build test.
-define(["i18n!nls/colors"], function (colors) {
+define(["i18n!nls/colors"], function(colors){
    var red = colors.red;
 });
\ No newline at end of file
diff --git a/dojo/tests/_base/loader/requirejs/layers/helloWorld.txt b/dojo/tests/_base/loader/requirejs/layers/helloWorld.txt
index 95d09f2..3b18e51 100644
--- a/dojo/tests/_base/loader/requirejs/layers/helloWorld.txt
+++ b/dojo/tests/_base/loader/requirejs/layers/helloWorld.txt
@@ -1 +1 @@
-hello world
\ No newline at end of file
+hello world
diff --git a/dojo/tests/_base/loader/requirejs/layers/layer1.js b/dojo/tests/_base/loader/requirejs/layers/layer1.js
index 963ab00..3a70a64 100644
--- a/dojo/tests/_base/loader/requirejs/layers/layer1.js
+++ b/dojo/tests/_base/loader/requirejs/layers/layer1.js
@@ -2,7 +2,7 @@
 
 define("alpha",
     ["beta", "gamma"],
-    function (beta, gamma) {
+    function(beta, gamma){
         return {
             name: "alpha",
             betaName: beta.name
@@ -12,7 +12,7 @@ define("alpha",
 
 define("beta",
     ["gamma"],
-    function (gamma) {
+    function(gamma){
         return {
             name: "beta",
             gammaName: gamma.name
@@ -22,7 +22,7 @@ define("beta",
 
 define("gamma",
     ["epsilon"],
-    function (epsilon) {
+    function(epsilon){
         return {
             name: "gamma",
             epsilonName: epsilon.name
diff --git a/dojo/tests/_base/loader/requirejs/map.js b/dojo/tests/_base/loader/requirejs/map.js
index 3e07574..e33f962 100644
--- a/dojo/tests/_base/loader/requirejs/map.js
+++ b/dojo/tests/_base/loader/requirejs/map.js
@@ -1,5 +1,5 @@
 define("map",
-  function() {
+  function(){
     return {
       name: "map"
     };
diff --git a/dojo/tests/_base/loader/requirejs/one.js b/dojo/tests/_base/loader/requirejs/one.js
index 469a75f..b02ecee 100644
--- a/dojo/tests/_base/loader/requirejs/one.js
+++ b/dojo/tests/_base/loader/requirejs/one.js
@@ -1,9 +1,9 @@
 define("one",
   ["require", "two"],
-  function(require) {
+  function(require){
     var one = {
       size: "large",
-      doSomething: function() {
+      doSomething: function(){
         return require("two");
       }
     };
diff --git a/dojo/tests/_base/loader/requirejs/paths/first.js/first.js b/dojo/tests/_base/loader/requirejs/paths/first.js/first.js
index 72b6a94..2d9ed69 100644
--- a/dojo/tests/_base/loader/requirejs/paths/first.js/first.js
+++ b/dojo/tests/_base/loader/requirejs/paths/first.js/first.js
@@ -1,6 +1,6 @@
 globalCounter += 1;
 
-define(['./second'], function (second) {
+define(['./second'], function(second){
     globalCounter += 1;
     return {
         load: second
diff --git a/dojo/tests/_base/loader/requirejs/paths/first.js/second.js b/dojo/tests/_base/loader/requirejs/paths/first.js/second.js
index 9ebcda1..c3fdb16 100644
--- a/dojo/tests/_base/loader/requirejs/paths/first.js/second.js
+++ b/dojo/tests/_base/loader/requirejs/paths/first.js/second.js
@@ -1,5 +1,5 @@
-define(['./first'], function () {
-    return function (id, parentRequire, loaded) {
+define(['./first'], function(){
+    return function(id, parentRequire, loaded){
         loaded({
             name: 'first',
             secondName: 'second'
diff --git a/dojo/tests/_base/loader/requirejs/relative/foo/bar/message.txt b/dojo/tests/_base/loader/requirejs/relative/foo/bar/message.txt
index 95d09f2..3b18e51 100644
--- a/dojo/tests/_base/loader/requirejs/relative/foo/bar/message.txt
+++ b/dojo/tests/_base/loader/requirejs/relative/foo/bar/message.txt
@@ -1 +1 @@
-hello world
\ No newline at end of file
+hello world
diff --git a/dojo/tests/_base/loader/requirejs/relative/foo/bar/one.js b/dojo/tests/_base/loader/requirejs/relative/foo/bar/one.js
index e62290a..88ee163 100644
--- a/dojo/tests/_base/loader/requirejs/relative/foo/bar/one.js
+++ b/dojo/tests/_base/loader/requirejs/relative/foo/bar/one.js
@@ -1,6 +1,6 @@
 define("foo/bar/one",
             ["require", "./two", "../three", "text!./message.txt"],
-            function (require, two, three, message) {
+            function(require, two, three, message){
     return {
         name: "one",
         twoName: two.name,
diff --git a/dojo/tests/_base/loader/requirejs/relative/relative-tests.js b/dojo/tests/_base/loader/requirejs/relative/relative-tests.js
index 21684e2..773dc55 100644
--- a/dojo/tests/_base/loader/requirejs/relative/relative-tests.js
+++ b/dojo/tests/_base/loader/requirejs/relative/relative-tests.js
@@ -1,23 +1,23 @@
 require({
-        baseUrl: require.has("host-browser") ? "./" : "./relative/",
-        paths: {
-            text: "../../text"
-        }
-    },
-    ["require", "foo/bar/one", "doh"],
-    function(require, one, doh) {
-        doh.register(
-            "relative",
-            [
-                function relative(t){
-                    t.is("one", one.name);
-                    t.is("two", one.twoName);
-                    t.is("three", one.threeName);
-                    t.is("hello world", one.message.replace(/\n/g, ""));
-                }
-            ]
-        );
+		baseUrl: require.has("host-browser") ? "./" : "./relative/",
+		paths: {
+			text: "../../text"
+		}
+	},
+	["require", "foo/bar/one", "doh"],
+	function(require, one, doh){
+		doh.register(
+			"relative",
+			[
+				function relative(t){
+					t.is("one", one.name);
+					t.is("two", one.twoName);
+					t.is("three", one.threeName);
+					t.is("hello world", one.message.replace(/\r|\n/g, ""));
+				}
+			]
+		);
 
-        doh.run();
-    }
+		doh.run();
+	}
 );
diff --git a/dojo/tests/_base/loader/requirejs/simple-tests.js b/dojo/tests/_base/loader/requirejs/simple-tests.js
index 7cfc856..0b8bd64 100644
--- a/dojo/tests/_base/loader/requirejs/simple-tests.js
+++ b/dojo/tests/_base/loader/requirejs/simple-tests.js
@@ -2,7 +2,7 @@ require({
         baseUrl: "./"
     },
     ["require", "map", "simple", "dimple", "func", "doh"],
-    function(require, map, simple, dimple, func, doh) {
+    function(require, map, simple, dimple, func, doh){
         doh.register(
             "simple",
             [
@@ -16,7 +16,7 @@ require({
         );
 
         //In rhino there is no more simple tests, but in web browser there is.
-        if (typeof moreSimpleTests === 'undefined') {
+        if (typeof moreSimpleTests === 'undefined'){
             doh.run();
         }
     }
diff --git a/dojo/tests/_base/loader/requirejs/simple.js b/dojo/tests/_base/loader/requirejs/simple.js
index 79552cf..2236cd9 100644
--- a/dojo/tests/_base/loader/requirejs/simple.js
+++ b/dojo/tests/_base/loader/requirejs/simple.js
@@ -1,5 +1,5 @@
 define("simple",
-  function() {
+  function(){
     return {
       color: "blue"
     };
diff --git a/dojo/tests/_base/loader/requirejs/text/local.js b/dojo/tests/_base/loader/requirejs/text/local.js
index d25af0f..2a39306 100644
--- a/dojo/tests/_base/loader/requirejs/text/local.js
+++ b/dojo/tests/_base/loader/requirejs/text/local.js
@@ -1,5 +1,5 @@
-define(['text!./resources/local.html'], function (localHtml) {
+define(['text!./resources/local.html'], function(localHtml){
     return {
         localHtml: localHtml
-    }
+    };
 });
diff --git a/dojo/tests/_base/loader/requirejs/text/resources/local.html b/dojo/tests/_base/loader/requirejs/text/resources/local.html
index f62ec62..4620e25 100644
--- a/dojo/tests/_base/loader/requirejs/text/resources/local.html
+++ b/dojo/tests/_base/loader/requirejs/text/resources/local.html
@@ -1 +1 @@
-<h1>Local</h1>
\ No newline at end of file
+<h1>Local</h1>
diff --git a/dojo/tests/_base/loader/requirejs/text/subwidget.js b/dojo/tests/_base/loader/requirejs/text/subwidget.js
index 9fd0822..12e0fe7 100644
--- a/dojo/tests/_base/loader/requirejs/text/subwidget.js
+++ b/dojo/tests/_base/loader/requirejs/text/subwidget.js
@@ -1,6 +1,6 @@
 define("subwidget",
   ["text!subwidget.html!strip", "text!subwidget2.html"],
-  function(template, template2) {
+  function(template, template2){
     return {
       name: "subwidget",
       template: template,
diff --git a/dojo/tests/_base/loader/requirejs/text/subwidget2.html b/dojo/tests/_base/loader/requirejs/text/subwidget2.html
index 13a0a03..cd54631 100644
--- a/dojo/tests/_base/loader/requirejs/text/subwidget2.html
+++ b/dojo/tests/_base/loader/requirejs/text/subwidget2.html
@@ -1 +1 @@
-<span>This! is template2</span>
\ No newline at end of file
+<span>This! is template2</span>
diff --git a/dojo/tests/_base/loader/requirejs/text/text.html b/dojo/tests/_base/loader/requirejs/text/text.html
index e396f3e..a217649 100644
--- a/dojo/tests/_base/loader/requirejs/text/text.html
+++ b/dojo/tests/_base/loader/requirejs/text/text.html
@@ -33,7 +33,7 @@
 	                [
 	                    function text(t){
 							function check(expected, actual){
-								t.is(expected, actual.replace(/\n/g, ""));
+								t.is(expected, actual.replace(/\r|\n/g, ""));
 							}
 	                        check("<span>Hello World!</span>", sampleText);
 	                        check('<div data-type="widget"><h1>This is a widget!</h1><p>I am in a widget</p></div>', widget.template);
diff --git a/dojo/tests/_base/loader/requirejs/text/widget.html b/dojo/tests/_base/loader/requirejs/text/widget.html
index c11c453..f0e2820 100644
--- a/dojo/tests/_base/loader/requirejs/text/widget.html
+++ b/dojo/tests/_base/loader/requirejs/text/widget.html
@@ -1 +1 @@
-<div data-type="widget"><h1>This is a widget!</h1><p>I am in a widget</p></div>
\ No newline at end of file
+<div data-type="widget"><h1>This is a widget!</h1><p>I am in a widget</p></div>
diff --git a/dojo/tests/_base/loader/requirejs/text/widget.js b/dojo/tests/_base/loader/requirejs/text/widget.js
index 4075369..d57208b 100644
--- a/dojo/tests/_base/loader/requirejs/text/widget.js
+++ b/dojo/tests/_base/loader/requirejs/text/widget.js
@@ -1,6 +1,6 @@
 define("widget",
   ["subwidget", "text!widget.html"],
-  function(subwidget, template) {
+  function(subwidget, template){
     return {
       subWidgetName: subwidget.name,
       subWidgetTemplate: subwidget.template,
diff --git a/dojo/tests/_base/loader/requirejs/tres.js b/dojo/tests/_base/loader/requirejs/tres.js
index e3eba93..cefcc81 100644
--- a/dojo/tests/_base/loader/requirejs/tres.js
+++ b/dojo/tests/_base/loader/requirejs/tres.js
@@ -1,5 +1,5 @@
 define("tres",
-  function() {
+  function(){
     return {
       name: "tres"
     };
diff --git a/dojo/tests/_base/loader/requirejs/two.js b/dojo/tests/_base/loader/requirejs/two.js
index 8c4c055..57b4991 100644
--- a/dojo/tests/_base/loader/requirejs/two.js
+++ b/dojo/tests/_base/loader/requirejs/two.js
@@ -1,10 +1,10 @@
 define("two",
   ["require", "one"],
-  function(require, one) {
+  function(require, one){
     return {
       size: "small",
       color: "redtwo",
-      doSomething: function() {
+      doSomething: function(){
         return require("one").doSomething();
       }
     };
diff --git a/dojo/tests/_base/loader/requirejs/uniques/one.js b/dojo/tests/_base/loader/requirejs/uniques/one.js
index ccaa684..b6a9cda 100644
--- a/dojo/tests/_base/loader/requirejs/uniques/one.js
+++ b/dojo/tests/_base/loader/requirejs/uniques/one.js
@@ -1,4 +1,4 @@
-define(function (require) {
+define(function(require){
     return {
        name: "one",
        threeName: require("three").name,
diff --git a/dojo/tests/_base/loader/requirejs/uniques/two.js b/dojo/tests/_base/loader/requirejs/uniques/two.js
index f272edb..c21bce6 100644
--- a/dojo/tests/_base/loader/requirejs/uniques/two.js
+++ b/dojo/tests/_base/loader/requirejs/uniques/two.js
@@ -1,4 +1,4 @@
-define("two", ["one", "three", "one"], function (one, three, one2) {
+define("two", ["one", "three", "one"], function(one, three, one2){
     return {
         name: "two",
         oneName: one.name,
diff --git a/dojo/tests/_base/loader/requirejs/uno.js b/dojo/tests/_base/loader/requirejs/uno.js
index dcc57dc..93681b8 100644
--- a/dojo/tests/_base/loader/requirejs/uno.js
+++ b/dojo/tests/_base/loader/requirejs/uno.js
@@ -1,9 +1,9 @@
 define("uno",
   ["dos", "tres"],
-  function(dos, tres) {
+  function(dos, tres){
     return {
       name: "uno",
-      doSomething: function() {
+      doSomething: function(){
         return {
           dosName: dos.name,
           tresName: tres.name
diff --git a/dojo/tests/_base/loader/requirejs/urlfetch/three.js b/dojo/tests/_base/loader/requirejs/urlfetch/three.js
index d78a542..a7ca140 100644
--- a/dojo/tests/_base/loader/requirejs/urlfetch/three.js
+++ b/dojo/tests/_base/loader/requirejs/urlfetch/three.js
@@ -2,7 +2,7 @@ define("three", {
     name: "three"
 });
 
-define("four", ["three"], function (three) {
+define("four", ["three"], function(three){
     return {
         name: "four",
         threeName: "three"
diff --git a/dojo/tests/_base/loader/requirejs/urlfetch/two.js b/dojo/tests/_base/loader/requirejs/urlfetch/two.js
index 8617a31..309b20b 100644
--- a/dojo/tests/_base/loader/requirejs/urlfetch/two.js
+++ b/dojo/tests/_base/loader/requirejs/urlfetch/two.js
@@ -2,7 +2,7 @@ define("one", {
     name: "one"
 });
 
-define("two", ["one"], function (one) {
+define("two", ["one"], function(one){
     return {
         name: "two",
         oneName: "one"
diff --git a/dojo/tests/_base/loader/stripStrict.html b/dojo/tests/_base/loader/stripStrict.html
new file mode 100644
index 0000000..3d4fd9b
--- /dev/null
+++ b/dojo/tests/_base/loader/stripStrict.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Testing dojo.addOnLoad(), dojo.addOnUnload() and dojo.addOnWindowUnload()</title>
+		<script type="text/javascript" 
+			src="../../../dojo.js" djConfig="stripStrict: true"></script>
+		<script type="text/javascript">
+			require(["dojo/aspect"], function(aspect){
+				var obj = {
+				};
+				aspect.after(obj, "foo", function(){
+					// this will throw an error if strict mode isn't stripped properly
+					var caller = arguments.callee.caller;
+					console.log("successful");
+				});
+				obj.foo();
+			});		</script>
+	</head>
+	<body>
+	</body>
+</html>
+
diff --git a/dojo/tests/_base/loader/xdomain/xdomain.html b/dojo/tests/_base/loader/xdomain/xdomain.html
index cf19527..9ca77a6 100644
--- a/dojo/tests/_base/loader/xdomain/xdomain.html
+++ b/dojo/tests/_base/loader/xdomain/xdomain.html
@@ -11,7 +11,7 @@
 
 	  var dojoConfig = {
 		async:dohArgs.async
-	  }
+	  };
 	  var expectedSequence;
 	  
 	  var built = 1;
@@ -163,7 +163,7 @@
 
 			// pretend that everything except the stuff in dojo/tests/_base/loader/xdomain is xdomain
 			require.isXdUrl = function(url){
-				return !/loader\/xdomain/.test(url);
+				return !/loader\/xdomain/.test(url) && !/syncBundle/.test(url);
 			};
 
 			// each of these dojo.requires a xdomain module which puts the loader in xdomain loading mode,
diff --git a/dojo/tests/_base/object.js b/dojo/tests/_base/object.js
index 16cb38c..49555ca 100644
--- a/dojo/tests/_base/object.js
+++ b/dojo/tests/_base/object.js
@@ -1,42 +1,42 @@
-dojo.provide("dojo.tests._base.object");
+define(["doh", "dojo/_base/lang"], function(doh, lang){
 
 // setup the test object
+dojo = dojo || {};
 dojo.zoo = { a:1, c: { d:1 } };
 
-tests.register("tests._base.object",
-	[
+	doh.register("tests._base.object", [
 
 		function getBasic(t){
-			var x = dojo.getObject('dojo.zoo.a');
+			var x = lang.getObject('dojo.zoo.a');
 			t.is(1, x);
 		},
 
 		function setObject2(t){
-			dojo.setObject("dojo.zoo.foo.bar", 42);
+			lang.setObject("dojo.zoo.foo.bar", 42);
 			t.is(42, dojo.zoo.foo.bar);
 		},
 
 		function setWithContext(t){
 			// c is already {}
-			dojo.setObject("zoo.c.x", "foo!", dojo);
+			lang.setObject("zoo.c.x", "foo!", dojo);
 			t.is("foo!", dojo.zoo.c.x);
 		},
 
 		function getUndefined(t){
-			var x = dojo.getObject('dojo.zoo.b');
+			var x = lang.getObject('dojo.zoo.b');
 			t.is(undefined, x);
 		},
 
 		function setDeep(t){
-			dojo.setObject("dojo.zoo.c.e.f.g.h.i", 42);
+			lang.setObject("dojo.zoo.c.e.f.g.h.i", 42);
 			t.is(42, dojo.zoo.c.e.f.g.h.i);
 		},
 
 		function getDeep(t){
-			dojo.getObject("dojo.zoo.bar.baz.bam", true);
+			lang.getObject("dojo.zoo.bar.baz.bam", true);
 			dojo.zoo.bar.baz.bam.x = 10;
 			t.is(10, dojo.zoo.bar.baz.bam.x);
 		}
 
-	]
-);
+	]);
+});
diff --git a/dojo/tests/_base/query.html b/dojo/tests/_base/query.html
index ce4f208..aedc9f9 100644
--- a/dojo/tests/_base/query.html
+++ b/dojo/tests/_base/query.html
@@ -1,13 +1,13 @@
+<!DOCTYPE html>
 <html>
 	<head>
-		<title>testing dojo.query()</title>
+		<title>testing dojo/_base/query</title>
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</style>
 		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/query!lite", "dojo/io/iframe", "dojo/domReady!"], function(dojo, doh, query){
-				queryLite = query; // make a global
+			require(["dojo", "doh", "dojo/io/iframe", "dojo/domReady!"], function(dojo, doh){
 				function createDocument(xml){
 					var fauxXhr = { responseText: xml };
 					if("DOMParser" in dojo.global){
@@ -18,89 +18,11 @@
 					return dojo._contentHandlers["xml"](fauxXhr); // DOMDocument
 				}
 
+				// Legacy tests for dojo/_base/query.  Replaced by dojo/tests/query/query.html.
+				// TODO: remove in 2.0.
 				doh.register("t", 
 					[
 						// basic sanity checks
-						"doh.is(4, (queryLite('h3')).length);",
-						"doh.is(1, (queryLite('#t')).length);",
-						"doh.is(1, (queryLite('#bug')).length);",
-						"doh.is(4, (queryLite('#t h3')).length);",
-						"doh.is(0, (queryLite('span#t')).length);",
-						"doh.is(0, (queryLite('.bogus')).length);",
-						"doh.is(0, (queryLite('.bogus', dojo.byId('container'))).length);",
-						"doh.is(0, (queryLite('#bogus')).length);",
-						"doh.is(0, (queryLite('#bogus', dojo.byId('container'))).length);",
-						"doh.is(1, (queryLite('#t div > h3')).length);",
-						"doh.is(2, (queryLite('.foo')).length);",
-						"doh.is(1, (queryLite('.foo.bar')).length);",
-						"doh.is(2, (queryLite('.baz')).length);",
-						"doh.is(3, (queryLite('#t > h3')).length);",
-
-						"doh.is(2, (queryLite('#baz,#foo,#t')).length);",
-
-						// syntactic equivalents
-						"doh.is(12, (queryLite('#t > *')).length);",
-						"doh.is(3, (queryLite('.foo > *')).length);",
-
-						// with a root, by ID
-						"doh.is(3, (queryLite('> *', 'container')).length);",
-						"doh.is(3, (queryLite('> h3', 't')).length);",
-
-						// compound queries
-						"doh.is(2, (queryLite('.foo, .bar')).length);",
-						"doh.is(2, (queryLite('.foo,.bar')).length);",
-
-						// multiple class attribute
-						"doh.is(1, (queryLite('.foo.bar')).length);",
-						"doh.is(2, (queryLite('.foo')).length);",
-						"doh.is(2, (queryLite('.baz')).length);",
-
-						// case sensitivity
-						"doh.is(1, (queryLite('span.baz')).length);",
-						"doh.is(1, (queryLite('sPaN.baz')).length);",
-						"doh.is(1, (queryLite('SPAN.baz')).length);",
-						"doh.is(2, (queryLite('[foo~=\"bar\"]')).length);",
-
-						"doh.is(3, (queryLite('[foo]')).length);",
-						"doh.is(1, (queryLite('[foo$=\"thud\"]')).length);",
-						"doh.is(1, (queryLite('[foo$=thud]')).length);",
-						"doh.is(1, (queryLite('[foo$=\"thudish\"]')).length);",
-						"doh.is(1, (queryLite('#t [foo$=thud]')).length);",
-						"doh.is(1, (queryLite('#t [title$=thud]')).length);",
-						"doh.is(0, (queryLite('#t span[title$=thud ]')).length);",
-						"doh.is(2, (queryLite('[foo|=\"bar\"]')).length);",
-						"doh.is(1, (queryLite('[foo|=\"bar-baz\"]')).length);",
-						"doh.is(0, (queryLite('[foo|=\"baz\"]')).length);",
-
-						// descendant selectors
-						"doh.is(3, queryLite('> *', 'container').length);",
-						"doh.is(2, queryLite('> [qux]', 'container').length);",
-						"doh.is('child1', queryLite('> [qux]', 'container')[0].id);",
-						"doh.is('child3', queryLite('> [qux]', 'container')[1].id);",
-						"doh.is(3, queryLite('> *', 'container').length);",
-						"doh.is(3, queryLite('>*', 'container').length);",
-						"doh.is('passed', queryLite('#bug')[0].value);",
-
-						// bug 9071
-						"doh.is(2, (queryLite('a', 't4')).length);",
-						"doh.is(2, (queryLite('p a', 't4')).length);",
-						"doh.is(2, (queryLite('div p', 't4')).length);",
-						"doh.is(2, (queryLite('div p a', 't4')).length);",
-						"doh.is(2, (queryLite('.subA', 't4')).length);",
-						"doh.is(2, (queryLite('.subP .subA', 't4')).length);",
-						"doh.is(2, (queryLite('.subDiv .subP', 't4')).length);",
-						"doh.is(2, (queryLite('.subDiv .subP .subA', 't4')).length);",
-
-
-						// failed scope arg
-						"doh.is(0, (queryLite('*', 'thinger')).length);",
-						"doh.is(0, (queryLite('div#foo').length));",
-
-						// "doh.t(false, 'howdy!')",
-						// "doh.f(true, 'howdy!')",
-						// "doh.e(Error, window, function(){ throw new Error(); })",
-
-						// basic sanity checks
 						"doh.is(4, (dojo.query('h3')).length);",
 						"doh.is(1, (dojo.query('h1:first-child')).length);",
 						"doh.is(2, (dojo.query('h3:first-child')).length);",
@@ -156,6 +78,7 @@
 						"doh.is(1, (dojo.query('[foo$=\"thud\"]')).length);",
 						"doh.is(1, (dojo.query('[foo$=thud]')).length);",
 						"doh.is(1, (dojo.query('[foo$=\"thudish\"]')).length);",
+						"doh.is(1, (dojo.query('[id$=\\'55555\\']')).length);",
 						"doh.is(1, (dojo.query('#t [foo$=thud]')).length);",
 						"doh.is(1, (dojo.query('#t [ title $= thud ]')).length);",
 						"doh.is(0, (dojo.query('#t span[ title $= thud ]')).length);",
@@ -245,6 +168,27 @@
 						"doh.is(dojo.byId('radio2'), dojo.query('#t2 > input[type=radio]:checked')[0]);",
 						"doh.is(2, dojo.query('#t2select option:checked').length);",
 						
+						// special characters in attribute values
+						function attrSpecialChars(){
+							// bug 10651
+							doh.is(1, dojo.query('option[value=a+b]', 'attrSpecialChars').length, "value=a+b");
+							doh.is(1, dojo.query('option[value=a~b]', 'attrSpecialChars').length, "value=a~b");
+							doh.is(1, dojo.query('option[value=a^b]', 'attrSpecialChars').length, "value=a^b");
+							doh.is(1, dojo.query('option[value=\"a+b\"]', 'attrSpecialChars').length, "value=\"a^b\"");
+							doh.is(1, dojo.query('option[value=\"a~b\"]', 'attrSpecialChars').length, "value=\"a~b\"");
+							doh.is(1, dojo.query('option[value=\"a^b\"]', 'attrSpecialChars').length, "value=\"a^b\"");
+
+							// selector with substring that contains equals sign (bug 7479)
+							doh.is(1, dojo.query("a[href*='foo=bar']", 'attrSpecialChars').length, "a[href*='foo=bar']");
+
+							// selector with substring that contains brackets (bug 9193, 11189, 13084)
+							// note: inner quotes don't work in second dojo.query(), not sure why
+							doh.is(1, dojo.query('input[name="data[foo][bar]"]', 'attrSpecialChars').length, "data[foo][bar]");
+							doh.is(1, dojo.query('input[name=data\\[foo\\]\\[bar\\]]', 'attrSpecialChars').length, "data\\[foo\\]\\[bar\\]");
+							doh.is(1, dojo.query('input[name="foo\\[0\\].bar"]', 'attrSpecialChars').length, "foo[0].bar");
+							doh.is(1, dojo.query('input[name="test[0]"]', 'attrSpecialChars').length, "test[0]");
+						},
+
 						// check for correct document order
 						function domOrder() {
 							var inputs = dojo.query(".upperclass .lowerclass input");
@@ -335,11 +279,6 @@
 							var i = dojo.query("div");
 							// smoke test
 							i.sort(function(a,b){ return 1; })
-						},
-						function performanceTest(){
-							for(var i = 0; i < 10000; i++){
-								dojo.query('.foo');
-							}
 						}
 					]
 				);
@@ -348,7 +287,7 @@
 		</script>
 	</head>
 	<body class="upperclass">
-		<h1>testing dojo.query()</h1>
+		<h1>Back-compat tests for dojo.query()</h1>
 		<div id="t" class="lowerclass">
 			<h3>h3 <span>span</span> endh3 </h3>
 			<!-- comment to throw things off -->
@@ -396,6 +335,34 @@
 				</div>
 			</div>
 		</div>
+		<div id='other'>
+		  <div id='abc55555'></div>
+		  <div id='abd55555efg'></div>
+		  <div id='55555abc'></div>
+		  <div id='1'></div>
+		  <div id='2c'></div>
+		  <div id='3ch'></div>
+		  <div id='4chr'></div>
+		  <div id='5char'></div>
+		  <div id='6chars'></div>
+		</div>
+		
+		<div id="attrSpecialChars">
+			<select name="special">
+				<!-- tests for special characters in attribute values (characters that are part of query syntax) -->
+				<option value="a+b">1</option>
+				<option value="a~b">2</option>
+				<option value="a^b">3</option>
+			</select>
+
+			<!-- tests for quotes in attribute values -->
+			<a href="foo=bar">hi</a>
+			<!-- tests for brackets in attribute values -->
+			<input name="data[foo][bar]">
+			<!-- attribute name with a dot, goes down separate code path -->
+			<input name="foo[0].bar">
+			<input name="test[0]">
+		</div>
 	</body>
 </html>
 
diff --git a/dojo/tests/_base/query.js b/dojo/tests/_base/query.js
index 5a4b135..d50c391 100644
--- a/dojo/tests/_base/query.js
+++ b/dojo/tests/_base/query.js
@@ -1,6 +1,6 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
-		doh.register("tests._base.query", require.toUrl("./query.html"), 60000);
+		doh.register("tests._base.query", require.toUrl("./query.html"), 60000);	// tests dojo.query() back-compat shim
 		doh.register("tests._base.NodeList", require.toUrl("./NodeList.html"), 60000);
 	}
 });
diff --git a/dojo/tests/_base/scrollingIframe.js b/dojo/tests/_base/scrollingIframe.js
index 7882e28..76d060b 100644
--- a/dojo/tests/_base/scrollingIframe.js
+++ b/dojo/tests/_base/scrollingIframe.js
@@ -24,7 +24,7 @@ function runScrollingTest(resultNode){
 		abs1.style.top = p.y + "px";
 		setTimeout(function(){
 			cw = dojo.hitch(dojo, "withGlobal")(window, "position", dojo, [clientWidth, false]);
-			if(cw.x >= 0 || (cw.x < 0 && root.clientWidth - cw.w == cw.x)){
+			if(cw.x >= 0 || (cw.x < 0 && Math.round(root.clientWidth - cw.w - cw.x) == 0)){
 				if(abs1.offsetLeft == control.offsetLeft){
 					if(abs1.offsetTop == control.offsetTop){
 						resultNode.testResult = "EQUAL";
diff --git a/dojo/tests/_base/sniff.html b/dojo/tests/_base/sniff.html
new file mode 100644
index 0000000..762a7de
--- /dev/null
+++ b/dojo/tests/_base/sniff.html
@@ -0,0 +1,36 @@
+<html>
+	<head>
+		<title>dojo/_base/sniff test</title>
+		<style>
+			table {
+				border-collapse: collapse;
+			}
+			td {
+				padding: 2px;
+				border: 1px solid black;
+			}
+		</style>
+		<script src="../../dojo.js" data-dojo-config="async: true, isDebug: true"></script>
+		<script>
+			require(["dojo/_base/array", "dojo/sniff", "dojo/dom-construct", "dojo/domReady!"],
+					function(array, has, domConstruct){
+				array.forEach([
+					"isKhtml", "isWebKit", "isChrome", "isSafari",
+					"isOpera",  "isMozilla", "isMoz", "isFF", "isIE", "isQuirks",
+					"isIos", "isAndroid", "isWii", "isAir", "isMac"], function(key){
+					var res = dojo[key];
+					domConstruct.place("<tr><td>dojo." + key + "</td><td>" +
+						(res === undefined ? "undefined" : res) + "</td></tr>", "tbody");
+				});
+			});
+		</script>
+	</head>
+	<body>
+		<h1>dojo/_base/sniff results</h1>
+		<p>Note that dojo/_base/sniff is deprecated, replaced by dojo/sniff.</p>
+		<table>
+			<tbody id="tbody">
+			</tbody>
+		</table>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojo/tests/_base/window.html b/dojo/tests/_base/window.html
index ce6ee80..86a49e7 100644
--- a/dojo/tests/_base/window.html
+++ b/dojo/tests/_base/window.html
@@ -11,7 +11,7 @@ iframe {
 		<script type="text/javascript" src="../../dojo.js" data-dojo-config="async:1"></script>
 		<script type="text/javascript">
 var frameLoaded; // callback for iframes, defined later
-require(["dojo/_base/kernel", "doh", "dojo/dom-construct", "dojo/has", "dojo/_base/window", "dojo/_base/sniff"],
+require(["dojo/_base/kernel", "doh", "dojo/dom-construct", "dojo/sniff", "dojo/_base/window"],
 function(dojo, doh, domConstruct, has, win){
 	var
 		fStandards, fQuirks, // iframes used for tests
@@ -30,61 +30,63 @@ function(dojo, doh, domConstruct, has, win){
 			var d = fQuirks.contentWindow.document, finished,
 				thisObj = {test: "myThis"};
 			
-			dojo.withDoc(d, function(a1, a2){
+			win.withDoc(d, function(a1, a2){
 				t.is(1, a1, "first passed argument should be 1");
 				t.is(2, a2, "second passed argument should be 2");
 				t.is(this.test, "myThis", "context should be re-hitched");
-				t.is(d, dojo.doc, "dojo.doc should be reassigned");
+				t.is(d, win.doc, "win.doc should be reassigned");
 				finished = true;
 			}, thisObj, [1, 2]);
 			
 			t.t(finished, "Did withDoc test function complete?");
-			t.is(document, dojo.doc, "dojo.doc should be restored");
+			t.is(document, win.doc, "win.doc should be restored");
 		},
 		function withGlobal(t){
 			var w = fQuirks.contentWindow, finished,
 				thisObj = {test: "myThis"};
 			
-			dojo.withGlobal(w, function(a1, a2){
+			win.withGlobal(w, function(a1, a2){
 				t.is(1, a1, "first passed argument should be 1");
 				t.is(2, a2, "second passed argument should be 2");
 				t.is(this.test, "myThis", "context should be re-hitched");
-				t.is(42, dojo.global.answer, "dojo.global should be reassigned");
-				t.is(w.document, dojo.doc, "dojo.doc should be reassigned");
+				t.is(42, win.global.answer, "win.global should be reassigned");
+				t.is(w.document, win.doc, "win.doc should be reassigned");
 				finished = true;
 			}, thisObj, [1, 2]);
 			
 			t.t(finished, "Did withGlobal test function complete?");
-			t.is(window, dojo.global, "dojo.global should be restored");
-			t.is(document, dojo.doc, "dojo.doc should be restored");
+			t.is(window, win.global, "win.global should be restored");
+			t.is(document, win.doc, "win.doc should be restored");
 		},
-		function isQuirks(t){
+		function hasQuirks(t){
 			var origQuirks = has("quirks");
 			win.withGlobal(fQuirks.contentWindow, function(){
-				t.t(true === dojo.isQuirks && true === has("quirks"),
-					"dojo.isQuirks / has('quirks') should be true in withDoc w/ quirks document");
+				t.t(dojo.isQuirks,"dojo.isQuirks should be true in withDoc w/ quirks document");	// remove in 2.0
+				t.t(has("quirks"), "has('quirks') should be true in withDoc w/ quirks document");
 			});
-			t.t(origQuirks === dojo.isQuirks && origQuirks === has("quirks"),
-				"dojo.isQuirks / has('quirks') should be reset to initial value");
+			t.is(origQuirks, dojo.isQuirks, "dojo.isQuirks should be reset to initial value");	// remove in 2.0
+			t.is(origQuirks, has("quirks"), "has('quirks') should be reset to initial value");
 			win.withGlobal(fStandards.contentWindow, function(){
-				t.t(false === dojo.isQuirks && false === has("quirks"),
-					"dojo.isQuirks / has('quirks') should be false in withDoc w/ standards document");
+				t.f(dojo.isQuirks, "dojo.isQuirks should be false in withDoc w/ standards document");	// remove in 2.0
+				t.f(has("quirks"), "has('quirks') should be false in withDoc w/ standards document");
 			});
-			t.t(origQuirks === dojo.isQuirks && origQuirks === has("quirks"),
-				"dojo.isQuirks / has('quirks') should be reset to initial value (again)");
+			t.is(origQuirks, dojo.isQuirks,		// remove in 2.0
+				"dojo.isQuirks should be reset to initial value (again)");
+			t.is(origQuirks, has("quirks"),
+				"has('quirks') should be reset to initial value (again)");
 		}
 	];
 
-	if(has("ie") > 7){ // add isIE test for X-UA-Compatible-triggered switch
-		tests.push(function isIE(t){
+	if(has("ie") > 7){ // add hasIE test for X-UA-Compatible-triggered switch
+		tests.push(function hasIE(t){
 			var origIE = has("ie");
 			win.withGlobal(fStandards.contentWindow, function(){
-				console.log('isIE=' + dojo.isIE + ' / has: ' + has("ie"));
-				t.t(7 === dojo.isIE && 7 === has("ie"),
-					"dojo.isIE / has('ie') should be 7 in withDoc w/ standards document w/ EmulateIE7");
+				// these are disabled because it doesn't seem that we can really emulate IE7 with frames like this.
+				//t.is(7, dojo.isIE,"dojo.isIE should be 7 in withDoc w/ standards document w/ EmulateIE7");	// remove in 2.0
+				//t.is(7, has("ie"), "has('ie') should be 7 in withDoc w/ standards document w/ EmulateIE7");
 			});
-			t.t(origIE === dojo.isIE && origIE === has("ie"),
-				"dojo.isIE / has('ie') should be reset to initial value");
+			t.is(origIE, dojo.isIE, "dojo.isIE should be reset to initial value");	// remove in 2.0
+			t.is(origIE, has("ie"), "has('ie') should be reset to initial value");
 		});
 	}
 
diff --git a/dojo/tests/_base/window.js b/dojo/tests/_base/window.js
index cd4ea2b..25d9dd7 100644
--- a/dojo/tests/_base/window.js
+++ b/dojo/tests/_base/window.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests._base.window", require.toUrl("./window.html"), 15000);
 	}
diff --git a/dojo/tests/_base/xhr.html b/dojo/tests/_base/xhr.html
index 027ed56..6eff09e 100644
--- a/dojo/tests/_base/xhr.html
+++ b/dojo/tests/_base/xhr.html
@@ -451,6 +451,30 @@
 							// t.t(td instanceof dojo.Deferred);
 							return d;
 						},
+						function xhrXMLQueryable(t){
+							var d = new doh.Deferred();
+
+							dojo.xhrGet({
+								url: "../request/xhrXml.php",
+								handleAs: "xml",
+								handle: function(res, ioArgs){
+									if(res instanceof Error){
+										d.errback(res);
+										return;
+									}
+									try{
+										var results = dojo.query('bar', res);
+										t.is(2, results.length);
+									}catch(e){
+										d.errback(e);
+										return;
+									}
+									d.callback(true);
+								}
+							});
+
+							return d;
+						},
 
 						function ioPublish(t){
 							// TODO: this test needs to be rewritten as it is unreliable with the
diff --git a/dojo/tests/_base/xhr.js b/dojo/tests/_base/xhr.js
index c64a634..b7049c2 100644
--- a/dojo/tests/_base/xhr.js
+++ b/dojo/tests/_base/xhr.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests._base.xhr", require.toUrl("./xhr.html"), 60000);
 	}
diff --git a/dojo/tests/aspect.js b/dojo/tests/aspect.js
index be1bd6e..460d558 100644
--- a/dojo/tests/aspect.js
+++ b/dojo/tests/aspect.js
@@ -1,6 +1,4 @@
-dojo.provide("dojo.tests.aspect");
-
-var aspect = dojo.require("dojo.aspect");
+define(["dojo/aspect"], function(aspect){
 
 doh.register("tests.aspect",
 	[
@@ -41,24 +39,57 @@ doh.register("tests.aspect",
 				order.push(0);
 				return a+1;
 			});
-			obj.method(0);
+			obj.method(0); // 0, 0
 			var signal2 = aspect.after(obj, "method", function(a){
 				order.push(a);
 			});
-			obj.method(3);
+			obj.method(3); // 3, 0, 5
 			var signal3 = aspect.after(obj, "method", function(a){
 				order.push(3);
 			}, true);
-			obj.method(3);
+			obj.method(3); // 3, 0, 5, 3
 			signal2.remove();
-			obj.method(6);
+			obj.method(6); // 6, 0, 3
 			signal3.remove();
 			var signal4 = aspect.after(obj, "method", function(a){
 				order.push(4);
 			}, true);
 			signal.remove();
-			obj.method(7);
-			t.is(order, [0, 0, 3, 0, 5, 3, 0, 5, 3, 6, 0, 3, 7, 4]);
+			obj.method(7); // 7, 4
+			signal4.remove();
+			var signal5 = aspect.after(obj, "method", function(a){
+				order.push(a);
+				aspect.after(obj, "method", function(a){
+					order.push(a);
+				});
+				aspect.after(obj, "method", function(a){
+					order.push(a);
+				}).remove();
+				return a+1;
+			});
+			var signal6 = aspect.after(obj, "method", function(a){
+				order.push(a);
+				return a+2;
+			});
+			obj.method(8); // 8, 9, 10
+			obj.method(8); // 8, 9, 10, 12
+			t.is([0, 0, 3, 0, 5, 3, 0, 5, 3, 6, 0, 3, 7, 4, 8, 9, 10, 8, 9, 10, 12], order);
+			obj = {method: function(){}};
+			aspect.after(obj, "method", function(){
+				return false;
+			}, true);
+			t.t(obj.method() === false);
+		},
+		function afterMultiple(t){
+			var order = [];
+			obj = {
+				foo: function(){}
+			};
+			aspect.after(obj, "foo", function(){order.push(1)});
+			aspect.after(obj, "foo", function(){order.push(2)});
+			aspect.after(obj, "foo", function(){order.push(3)});
+			obj.foo();
+			t.is([1,2,3], order);
 		},
 		function around(t){
 			var order = [];
@@ -77,12 +108,71 @@ doh.register("tests.aspect",
 					a = original(a);
 					order.push(a);
 					return a+1;
-				}
+				};
 			});
 			order.push(obj.method(0));
 			obj.method(4);
 			t.is(order, [0,1,2,3,4,5,6]);
 		},
+		function around2(t){
+			var order = [];
+			var obj = {
+				method: function(a){
+					order.push(1);
+				}
+			};
+			var signal1 = aspect.around(obj, "method", function(original){
+				return function(a){
+					original();
+					order.push(2);
+				};
+			});
+			var signal2 = aspect.around(obj, "method", function(original){
+				return function(a){
+					original();
+					order.push(3);
+				};
+			});
+			var signal3 = aspect.around(obj, "method", function(original){
+				return function(a){
+					original();
+					order.push(4);
+				};
+			});
+			signal2.remove();
+			obj.method();
+			t.is(order, [1,2,4]);
+		},
+		function multipleRemove(t){
+			var foo = {bar: function(){}};
+			var order = [];
+			var signal1 = aspect.after(foo, "bar", function() {
+	    		order.push(1);
+			});
+
+			var signal2 = aspect.after(foo, "bar", function() {
+				order.push(2);
+			});
+
+			var signal3 = aspect.after(foo, "bar", function() {
+				order.push(3);
+			});
+
+			// This should execute all 3 callbacks
+			foo.bar();
+			
+			signal2.remove();
+			signal3.remove();
+
+			// Ideally signal2 should not be removed again, but can happen if the app
+			// fails to clear its state.
+			signal2.remove();
+			
+			// This should execute only the first callback, but notice that the third callback
+			// is executed as well
+			foo.bar();
+			t.is(order, [1,2,3,1]);
+		},
 		function delegation(t){
 			var order = [];
 			var proto = {
@@ -117,3 +207,5 @@ doh.register("tests.aspect",
 		}
 	]
 );
+
+});
diff --git a/dojo/tests/back-hash.js b/dojo/tests/back-hash.js
index d6cb79b..2fe7ab6 100644
--- a/dojo/tests/back-hash.js
+++ b/dojo/tests/back-hash.js
@@ -1,6 +1,6 @@
-define(["../main", "doh", "../back"], function(dojo, doh){
+define(["doh/main", "../back", "dojo/_base/array"], function(doh, back, array){
 	doh.register("tests.back.hash", [
-		function getAndSet(t) {
+		function getAndSet(t){
 			var cases = [
 				"test",
 				"test with spaces",
@@ -14,12 +14,11 @@ define(["../main", "doh", "../back"], function(dojo, doh){
 				"extra&instring",
 				"#leadinghash"
 			];
-			var b = dojo.back;
 			function verify(s){
-				dojo.back.setHash(s);
-				t.is(s, dojo.back.getHash(s));
+				back.setHash(s);
+				t.is(s, back.getHash(s));
 			}
-			dojo.forEach(cases, verify);
+			array.forEach(cases, verify);
 		}
 	]);
 });
diff --git a/dojo/tests/back.html b/dojo/tests/back.html
index 1f86150..a671d1d 100644
--- a/dojo/tests/back.html
+++ b/dojo/tests/back.html
@@ -9,59 +9,57 @@
 	</script>
 	<script type="text/javascript" 
 					src="../dojo.js" 
-					djConfig="isDebug:true, dojoIframeHistoryUrl: '../resources/iframe_history.html'"></script>
+					data-dojo-config="isDebug:true, dojoIframeHistoryUrl: '../resources/iframe_history.html'"></script>
 	<!--script type="text/javascript" src="../back.js"></script-->
 	<script type="text/javascript">
-		require(["dojo/main","dojo/back"], function(dojo, back){	
-		ApplicationState = function(stateData, outputDivId, backForwardOutputDivId, bookmarkValue){
-			this.stateData = stateData;
-			this.outputDivId = outputDivId;
-			this.backForwardOutputDivId = backForwardOutputDivId;
-			this.changeUrl = bookmarkValue || false;
-		};
-	
-		dojo.extend(ApplicationState, {
-			back: function(){
-				this.showBackForwardMessage("BACK for State Data: " + this.stateData);
-				this.showStateData();
-			},
-			forward: function(){
-				this.showBackForwardMessage("FORWARD for State Data: " + this.stateData);
-				this.showStateData();
-			},
-			showStateData: function(){
-				dojo.byId(this.outputDivId).innerHTML += this.stateData + '<br />';
-			},
-			showBackForwardMessage: function(message){
-				dojo.byId(this.backForwardOutputDivId).innerHTML += message + '<br />';
-			}
-		});
-		
-		var data = {
-			link0: "This is the initial state (page first loaded)",
-			"link with spaces": "This is data for a state with spaces",
-			"link%20with%20encoded": "This is data for a state with encoded bits",
-			"link+with+pluses": "This is data for a state with pluses",
-			link1: "This is data for link 1",
-			link2: "This is data for link 2",
-			link3: "This is data for link 3",
-			link4: "This is data for link 4",
-			link5: "This is data for link 5",
-			link6: "This is data for link 6",
-			link7: "This is data for link 7"
-		};
+		require(["dojo/_base/lang", "dojo/_base/kernel", "dojo/back", "dojo/dom", "dojo/domReady!"], function(lang, kernel, back, dom){
+			ApplicationState = function(stateData, outputDivId, backForwardOutputDivId, bookmarkValue){
+				this.stateData = stateData;
+				this.outputDivId = outputDivId;
+				this.backForwardOutputDivId = backForwardOutputDivId;
+				this.changeUrl = bookmarkValue || false;
+			};
 
-		dojo.global.goNav = function goNav(id){
-			var appState = new ApplicationState(data[id], "output", "dataOutput", id);
-			appState.showStateData();
-			dojo.back.addToHistory(appState);
-		}
+			lang.extend(ApplicationState, {
+				back: function(){
+					this.showBackForwardMessage("BACK for State Data: " + this.stateData);
+					this.showStateData();
+				},
+				forward: function(){
+					this.showBackForwardMessage("FORWARD for State Data: " + this.stateData);
+					this.showStateData();
+				},
+				showStateData: function(){
+					dom.byId(this.outputDivId).innerHTML += this.stateData + '<br />';
+				},
+				showBackForwardMessage: function(message){
+					dom.byId(this.backForwardOutputDivId).innerHTML += message + '<br />';
+				}
+			});
+
+			var data = {
+				link0: "This is the initial state (page first loaded)",
+				"link with spaces": "This is data for a state with spaces",
+				"link%20with%20encoded": "This is data for a state with encoded bits",
+				"link+with+pluses": "This is data for a state with pluses",
+				link1: "This is data for link 1",
+				link2: "This is data for link 2",
+				link3: "This is data for link 3",
+				link4: "This is data for link 4",
+				link5: "This is data for link 5",
+				link6: "This is data for link 6",
+				link7: "This is data for link 7"
+			};
+
+			kernel.global.goNav = function goNav(id){
+				var appState = new ApplicationState(data[id], "output", "dataOutput", id);
+				appState.showStateData();
+				back.addToHistory(appState);
+			};
 
-		dojo.addOnLoad(function(){
 			var appState = new ApplicationState(data["link0"], "output", "dataOutput");
 			appState.showStateData();
-			dojo.back.setInitialState(appState);
-		});
+			back.setInitialState(appState);
 		});
 	</script>
 </head>
diff --git a/dojo/tests/back.js b/dojo/tests/back.js
index cd061a9..f9c72fb 100644
--- a/dojo/tests/back.js
+++ b/dojo/tests/back.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests.back", require.toUrl("./back.html"), 30000);
 	}
diff --git a/dojo/tests/behavior.js b/dojo/tests/behavior.js
index 3d41006..428ba25 100644
--- a/dojo/tests/behavior.js
+++ b/dojo/tests/behavior.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests.behavior", require.toUrl("./behavior.html"));
 	}
diff --git a/dojo/tests/cache.js b/dojo/tests/cache.js
index 95b8445..b85776e 100644
--- a/dojo/tests/cache.js
+++ b/dojo/tests/cache.js
@@ -1,4 +1,4 @@
-define(["../main", "doh", "require", "../cache", "../_base/url"], function(dojo, doh, require) {
+define(["../main", "doh/main", "require", "../cache", "../_base/url"], function(dojo, doh, require){
 	doh.register("tests.cache", [{
 			name: "dojo.cache",
 			runTest: function(t){
diff --git a/dojo/tests/cldr.js b/dojo/tests/cldr.js
index 62295a1..d6f0522 100644
--- a/dojo/tests/cldr.js
+++ b/dojo/tests/cldr.js
@@ -1,10 +1,10 @@
-define(["..", "doh", "../cldr/supplemental", "../cldr/monetary"], function(dojo, doh){
+define(["doh/main", "../cldr/supplemental", "../cldr/monetary"], function(doh, supplemental){
 	doh.register("tests.cldr", [
 		function test_date_getWeekend(t){
-			t.is(6, dojo.cldr.supplemental.getWeekend('en-us').start);
-			t.is(0, dojo.cldr.supplemental.getWeekend('en-us').end);
-			t.is(5, dojo.cldr.supplemental.getWeekend('he-il').start);
-			t.is(6, dojo.cldr.supplemental.getWeekend('he-il').end);
+			t.is(6, supplemental.getWeekend('en-us').start);
+			t.is(0, supplemental.getWeekend('en').end);
+			t.is(5, supplemental.getWeekend('he-il').start);
+			t.is(6, supplemental.getWeekend('he').end);
 		}
 	]);
 });
diff --git a/dojo/tests/colors.js b/dojo/tests/colors.js
index 514b1c4..5774b78 100644
--- a/dojo/tests/colors.js
+++ b/dojo/tests/colors.js
@@ -1,10 +1,10 @@
-define(["../main", "doh", "../colors"], function(dojo, doh){
+define(["doh/main", "../_base/array", "../_base/Color", "../colors"], function(doh, array, Color, colors){
 
 	var verifyColor = function(t, source, expected){
-		source	 = new dojo.Color(source);
-		expected = new dojo.Color(expected);
+		source	 = new Color(source);
+		expected = new Color(expected);
 		t.is(expected.toRgba(), source.toRgba());
-		dojo.forEach(source.toRgba(), function(n){ t.is("number", typeof(n)); });
+		array.forEach(source.toRgba(), function(n){ t.is("number", typeof(n)); });
 	};
 
 	doh.register("tests.colors", [
@@ -34,8 +34,8 @@ define(["../main", "doh", "../colors"], function(dojo, doh){
 		function testColorEx23(t){ verifyColor(t, "hsla(30, 100%, 50%, 0.1)", [255, 128, 0, 0.1]); },
 		function testColorEx24(t){ verifyColor(t, "transparent", [0, 0, 0, 0]); },
 		// all tests below test greyscale colors
-		function testColorEx25(t){ verifyColor(t, dojo.colors.makeGrey(5), [5, 5, 5, 1]); },
-		function testColorEx26(t){ verifyColor(t, dojo.colors.makeGrey(2, 0.3), [2, 2, 2, 0.3]); }
+		function testColorEx25(t){ verifyColor(t, colors.makeGrey(5), [5, 5, 5, 1]); },
+		function testColorEx26(t){ verifyColor(t, colors.makeGrey(2, 0.3), [2, 2, 2, 0.3]); }
 	]);
 
 });
diff --git a/dojo/tests/cookie.html b/dojo/tests/cookie.html
index 7c4b10c..5f39b32 100644
--- a/dojo/tests/cookie.html
+++ b/dojo/tests/cookie.html
@@ -6,7 +6,7 @@
 		</style>
 		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/cookie", "dojo/domReady!"], function(dojo, doh){
+			require(["doh", "dojo/cookie", "dojo/domReady!"], function(doh, cookie){
 				doh.register([
 					{
 						name: "basicSet",
@@ -19,7 +19,7 @@
 							// set the new one
 							var n = "dojo_test";
 							var v = "test value";
-							dojo.cookie(n, v);
+							cookie(n, v);
 							t.t(document.cookie.indexOf(n+"=") >= 0);
 							var start = document.cookie.indexOf(n+"=") + n.length + 1;
 							var end = document.cookie.indexOf(";", start);
@@ -35,41 +35,42 @@
 							var v = "foofoo";
 							document.cookie = n + "=" + v;
 							
-							t.is(v, dojo.cookie(n));
+							t.is(v, cookie(n));
 						}
 					},
 					{
 						name: "daysAsNumber",
 						runTest: function(t){
 							// set a cookie with a numerical expires
-							dojo.cookie("dojo_num", "foo", { expires: 10 });
-							t.is("foo", dojo.cookie("dojo_num"));
+							cookie("dojo_num", "foo", { expires: 10 });
+							t.is("foo", cookie("dojo_num"));
 							
 							// remove the cookie by setting it with a negative
 							// numerical expires. value doesn't really matter here
-							dojo.cookie("dojo_num", "-deleted-", { expires: -10 });
-							t.is(null, dojo.cookie("dojo_num"));
+							cookie("dojo_num", "-deleted-", { expires: -10 });
+							t.is(null, cookie("dojo_num"));
 						}
 					},
 					{
 						name: "nameSuffix",
 						runTest: function(t){
 							// set two cookies with the same suffix
-							dojo.cookie("user", "123", { expires: 10 });
-							dojo.cookie("xuser", "abc", { expires: 10 });
-							t.is("123", dojo.cookie("user"));
-							t.is("abc", dojo.cookie("xuser"));
+							cookie("user", "123", { expires: 10 });
+							cookie("xuser", "abc", { expires: 10 });
+							t.is("123", cookie("user"));
+							t.is("abc", cookie("xuser"));
 
 							// remove the cookie by setting it with a negative
 							// numerical expires. value doesn't really matter here
-							dojo.cookie("user", "-deleted-", { expires: -10 });
-							t.is(null, dojo.cookie("user"));
-							dojo.cookie("xuser", "-deleted-", { expires: -10 });
-							t.is(null, dojo.cookie("xuser"));
+							cookie("user", "-deleted-", { expires: -10 });
+							t.is(null, cookie("user"));
+							cookie("xuser", "-deleted-", { expires: -10 });
+							t.is(null, cookie("xuser"));
 						}
 					}
 				]);
-				doh.runOnLoad();
+
+				doh.run();
 			});
 		</script>
 	</head>
diff --git a/dojo/tests/cookie.js b/dojo/tests/cookie.js
index 46df058..65e52fb 100644
--- a/dojo/tests/cookie.js
+++ b/dojo/tests/cookie.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests.cookie", require.toUrl("./cookie.html"), 30000);
 	}
diff --git a/dojo/tests/currency.js b/dojo/tests/currency.js
index efcbe6b..ff727db 100644
--- a/dojo/tests/currency.js
+++ b/dojo/tests/currency.js
@@ -1,53 +1,50 @@
-define(["../main", "doh", "require", "../currency"], function(dojo, doh, require){
+define(["doh/main", "require", "../currency", "../i18n"], function(doh, require, currency, i18n){
 
-	var runTest= function(dojo, t) {
-		t.is("\u20ac123.45", dojo.currency.format(123.45, {currency: "EUR", locale: "en-us"}));
-		t.is("$123.45", dojo.currency.format(123.45, {currency: "USD", locale: "en-us"}));
-		t.is("$1,234.56", dojo.currency.format(1234.56, {currency: "USD", locale: "en-us"}));
-		t.is("US$123.45", dojo.currency.format(123.45, {currency: "USD", locale: "en-ca"}));
-		t.is("$123.45", dojo.currency.format(123.45, {currency: "CAD", locale: "en-ca"}));
-		t.is("CA$123.45", dojo.currency.format(123.45, {currency: "CAD", locale: "en-us"}));
-		t.is("123,45\xa0\u20ac", dojo.currency.format(123.45, {currency: "EUR", locale: "de-de"}));
-		t.is("1.234,56\xa0\u20ac", dojo.currency.format(1234.56, {currency: "EUR", locale: "de-de"}));
+	var runTest= function(t){
+		doh.is("\u20ac123.45", currency.format(123.45, {currency: "EUR", locale: "en-us"}));
+		doh.is("$123.45", currency.format(123.45, {currency: "USD", locale: "en-us"}));
+		doh.is("$1,234.56", currency.format(1234.56, {currency: "USD", locale: "en-us"}));
+		doh.is("US$123.45", currency.format(123.45, {currency: "USD", locale: "en-ca"}));
+		doh.is("$123.45", currency.format(123.45, {currency: "CAD", locale: "en-ca"}));
+		doh.is("CA$123.45", currency.format(123.45, {currency: "CAD", locale: "en-us"}));
+		doh.is("123,45\xa0\u20ac", currency.format(123.45, {currency: "EUR", locale: "de-de"}));
+		doh.is("1.234,56\xa0\u20ac", currency.format(1234.56, {currency: "EUR", locale: "de-de"}));
 		// There is no special currency symbol for ADP, so expect the ISO code instead
-		t.is("ADP123", dojo.currency.format(123, {currency: "ADP", locale: "en-us"}));
-		t.is("$1,234", dojo.currency.format(1234, {currency: "USD", fractional: false, locale: "en-us"}));
+		doh.is("ADP123", currency.format(123, {currency: "ADP", locale: "en-us"}));
+		doh.is("$1,234", currency.format(1234, {currency: "USD", fractional: false, locale: "en-us"}));
 
-		t.is(123.45, dojo.currency.parse("$123.45", {currency: "USD", locale: "en-us"}));
-		t.is(1234.56, dojo.currency.parse("$1,234.56", {currency: "USD", locale: "en-us"}));
-		t.is(123.45, dojo.currency.parse("123,45 \u20ac", {currency: "EUR", locale: "de-de"}));
-		t.is(123.45, dojo.currency.parse("123,45\xa0\u20ac", {currency: "EUR", locale: "de-de"}));
-		t.is(1234.56, dojo.currency.parse("1.234,56 \u20ac", {currency: "EUR", locale: "de-de"}));
-		t.is(1234.56, dojo.currency.parse("1.234,56\u20ac", {currency: "EUR", locale: "de-de"}));
+		doh.is(123.45, currency.parse("$123.45", {currency: "USD", locale: "en-us"}));
+		doh.is(1234.56, currency.parse("$1,234.56", {currency: "USD", locale: "en-us"}));
+		doh.is(123.45, currency.parse("123,45 \u20ac", {currency: "EUR", locale: "de-de"}));
+		doh.is(123.45, currency.parse("123,45\xa0\u20ac", {currency: "EUR", locale: "de-de"}));
+		doh.is(1234.56, currency.parse("1.234,56 \u20ac", {currency: "EUR", locale: "de-de"}));
+		doh.is(1234.56, currency.parse("1.234,56\u20ac", {currency: "EUR", locale: "de-de"}));
 
-		t.is(1234, dojo.currency.parse("$1,234", {currency: "USD", locale: "en-us"}));
-		t.is(1234, dojo.currency.parse("$1,234", {currency: "USD", fractional: false, locale: "en-us"}));
-		t.t(isNaN(dojo.currency.parse("$1,234", {currency: "USD", fractional: true, locale: "en-us"})));
+		doh.is(1234, currency.parse("$1,234", {currency: "USD", locale: "en-us"}));
+		doh.is(1234, currency.parse("$1,234", {currency: "USD", fractional: false, locale: "en-us"}));
+		doh.t(isNaN(currency.parse("$1,234", {currency: "USD", fractional: true, locale: "en-us"})));
 	};
 
 	if(require.async){
-		require(["../main", "../currency", "../i18n"], function(dojo){
+		require(["../_base/array",  "../i18n"], function(array){
 			doh.register("tests.currency", {
 				name: "currency",
 				timeout: 2000,
 				runTest: function(t){
 					var
 						def = new doh.Deferred(),
-						deps= ["dojo"];
-					dojo.forEach(["en-us", "en-ca", "de-de"], function(locale){
-						deps.push(dojo.getL10nName("dojo/cldr", "currency", locale));
-						deps.push(dojo.getL10nName("dojo/cldr", "number", locale));
-					});
-					require(deps, function(dojo){
-						runTest(dojo, t);
-						def.callback(true);
+						deps= [];
+					array.forEach(["en-us", "en-ca", "de-de"], function(locale){
+						deps.push(i18n.getL10nName("dojo/cldr", "currency", locale));
+						deps.push(i18n.getL10nName("dojo/cldr", "number", locale));
 					});
+					require(deps, def.getTestCallback(runTest));
 					return def;
 				}
 			});
 		});
 	}else{ // tests for the v1.x loader/i18n machinery
-		tests.register("tests.currency",{
+		doh.register("tests.currency", {
 			// Test formatting and parsing of currencies in various locales pre-built in dojo.cldr
 			// NOTE: we can't set djConfig.extraLocale before bootstrapping unit tests, so directly
 			// load resources here for specific locales:
@@ -59,9 +56,7 @@ define(["../main", "doh", "require", "../currency"], function(dojo, doh, require
 					dojo.requireLocalization("dojo.cldr","number",partLocaleList[i]);
 				}
 			},
-			runTest: function(t){
-				runTest(dojo, t);
-			}
+			runTest: runTest
 		});
 	}
 });
diff --git a/dojo/tests/data.js b/dojo/tests/data.js
index 13ae1cf..8199809 100644
--- a/dojo/tests/data.js
+++ b/dojo/tests/data.js
@@ -1,9 +1,9 @@
 define([
-	"dojo",
+	"../main",
 	"./data/utils",
 	"./data/ItemFileReadStore",
 	"./data/ItemFileWriteStore",
-	"./data/ObjectStore"], function(dojo) {
+	"./data/ObjectStore"], function(dojo){
 		dojo.config.usePlainJson = true;
 });
 
diff --git a/dojo/tests/data/ItemFileReadStore.js b/dojo/tests/data/ItemFileReadStore.js
index ef10ba4..5734af9 100644
--- a/dojo/tests/data/ItemFileReadStore.js
+++ b/dojo/tests/data/ItemFileReadStore.js
@@ -1,7 +1,7 @@
 // FIXME: this test assumes the existence of the global object "tests"
 tests= typeof tests=="undefined" ? {} : tests;
 
-define(["./readOnlyItemFileTestTemplates", "dojo/data/ItemFileReadStore"], function() {
+define(["./readOnlyItemFileTestTemplates", "dojo/data/ItemFileReadStore"], function(){
 	tests.data.readOnlyItemFileTestTemplates.registerTestsForDatastore("dojo.data.ItemFileReadStore");
 });
 
diff --git a/dojo/tests/data/ItemFileWriteStore.js b/dojo/tests/data/ItemFileWriteStore.js
index e0c9947..209f22a 100644
--- a/dojo/tests/data/ItemFileWriteStore.js
+++ b/dojo/tests/data/ItemFileWriteStore.js
@@ -1,14 +1,14 @@
 // FIXME: this test assumes the existence of the global object "tests"
 define([
-  "dojo",
-  "doh",
+  "dojo/main",
+  "doh/main",
   "require",
   "./readOnlyItemFileTestTemplates",
   "dojo/data/ItemFileWriteStore",
   "dojo/data/api/Read",
   "dojo/data/api/Identity",
   "dojo/data/api/Write",
-  "dojo/data/api/Notification"], function(dojo, doh, require) {
+  "dojo/data/api/Notification"], function(dojo, doh, require){
 
 dojo.getObject("data.ItemFileWriteStore", true, tests);
 
@@ -20,7 +20,7 @@ tests.data.ItemFileWriteStore.getTestData = function(name){
 	var data = {};
 	if(name === "reference_integrity"){
 		if(dojo.isBrowser){
-			data = {url: require.toUrl("tests/data/reference_integrity.json")};
+			data = {url: require.toUrl("./reference_integrity.json")};
 		}else{
 			data =
 				{ data: {
@@ -55,9 +55,9 @@ tests.data.ItemFileWriteStore.getTestData = function(name){
 doh.register("tests.data.ItemFileWriteStore",
 	[
 		function test_getFeatures(){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -82,9 +82,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			doh.assertEqual(count, 4);
 		},
 		function testWriteAPI_setValue(){
-			//	summary:
+			// summary:
 			//		Simple test of the setValue API
-			//	description:
+			// description:
 			//		Simple test of the setValue API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -95,15 +95,15 @@ doh.register("tests.data.ItemFileWriteStore",
 				doh.assertTrue(store.containsValue(item, "capital", "Cairo"));
 
 				// FIXME:
-				//    Okay, so this seems very odd.  Maybe I'm just being dense.
-				//    These tests works:
+				//	  Okay, so this seems very odd.  Maybe I'm just being dense.
+				//	  These tests works:
 				doh.assertEqual(store.isDirty(item), false);
 				doh.assertTrue(store.isDirty(item) === false);
-				//    But these seemingly equivalent tests will not work:
+				//	  But these seemingly equivalent tests will not work:
 				// doh.assertFalse(store.isDirty(item));
 				// doh.assertTrue(!(store.isDirty(item)));
 				//
-				//    All of which seems especially weird, given that this *does* work:
+				//	  All of which seems especially weird, given that this *does* work:
 				doh.assertFalse(store.isDirty());
 
 				doh.assertTrue(store.isDirty(item) === false);
@@ -121,9 +121,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_setValues(){
-			//	summary:
+			// summary:
 			//		Simple test of the setValues API
-			//	description:
+			// description:
 			//		Simple test of the setValues API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -149,14 +149,14 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_unsetAttribute(){
-			//	summary:
+			// summary:
 			//		Simple test of the unsetAttribute API
-			//	description:
+			// description:
 			//		Simple test of the unsetAttribute API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
 			var deferred = new doh.Deferred();
-			function onComplete(items, request) {
+			function onComplete(items, request){
 				doh.assertEqual(1, items.length);
 				var item = items[0];
 				doh.assertTrue(store.containsValue(item, "name", "Egypt"));
@@ -168,16 +168,16 @@ doh.register("tests.data.ItemFileWriteStore",
 				doh.assertTrue(!store.hasAttribute(item, "name"));
 				deferred.callback(true);
 			}
-			function onError(error, request) {
+			function onError(error, request){
 				deferred.errback(error);
 			}
 			store.fetch({query:{name:"Egypt"}, onComplete: onComplete, onError: onError});
 			return deferred; //Object
 		},
 		function testWriteAPI_newItem(){
-			//	summary:
+			// summary:
 			//		Simple test of the newItem API
-			//	description:
+			// description:
 			//		Simple test of the newItem API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -211,9 +211,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_newItem_withParent(){
-			//	summary:
+			// summary:
 			//		Simple test of the newItem API with a parent assignment
-			//	description:
+			// description:
 			//		Simple test of the newItem API with a parent assignment
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -270,9 +270,9 @@ doh.register("tests.data.ItemFileWriteStore",
 		},
 
 		function testWriteAPI_newItem_multiple_withParent(){
-			//	summary:
+			// summary:
 			//		Simple test of the newItem API with a parent assignment multiple times.
-			//	description:
+			// description:
 			//		Simple test of the newItem API with a parent assignment multiple times.
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -335,9 +335,9 @@ doh.register("tests.data.ItemFileWriteStore",
 		},
 
 		function testWriteAPI_deleteItem(){
-			//	summary:
+			// summary:
 			//		Simple test of the deleteItem API
-			//	description:
+			// description:
 			//		Simple test of the deleteItem API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -356,7 +356,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				store.deleteItem(item);
 				doh.assertTrue(store.isDirty(item));
 				doh.assertTrue(store.isDirty());
-				var onCompleteToo = function(itemsToo, requestToo) {
+				var onCompleteToo = function(itemsToo, requestToo){
 					doh.assertEqual(0, itemsToo.length);
 					deferred.callback(true);
 				};
@@ -366,14 +366,14 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_isDirty(){
-			//	summary:
+			// summary:
 			//		Simple test of the isDirty API
-			//	description:
+			// description:
 			//		Simple test of the isDirty API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
 			var deferred = new doh.Deferred();
-			function onComplete(items, request) {
+			function onComplete(items, request){
 				doh.assertEqual(1, items.length);
 				var item = items[0];
 				doh.assertTrue(store.containsValue(item, "name", "Egypt"));
@@ -382,16 +382,16 @@ doh.register("tests.data.ItemFileWriteStore",
 				doh.assertTrue(store.isDirty(item));
 				deferred.callback(true);
 			}
-			function onError(error, request) {
+			function onError(error, request){
 				deferred.errback(error);
 			}
 			store.fetch({query:{name:"Egypt"}, onComplete: onComplete, onError: onError});
 			return deferred; //Object
 		},
 		function testWriteAPI_revert(){
-			//	summary:
+			// summary:
 			//		Simple test of the revert API
-			//	description:
+			// description:
 			//		Simple test of the revert API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -401,7 +401,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				deferred.errback(error);
 			};
 
-			var onComplete = function(items, request) {
+			var onComplete = function(items, request){
 				doh.assertEqual(1, items.length);
 				var item = items[0];
 				doh.assertTrue(store.containsValue(item, "name", "Egypt"));
@@ -426,9 +426,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_save(){
-			//	summary:
+			// summary:
 			//		Simple test of the save API
-			//	description:
+			// description:
 			//		Simple test of the save API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -438,7 +438,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			}
 			function onItem(item){
 				store.setValue(item, "capital", "New Cairo");
-				function onComplete() {
+				function onComplete(){
 					deferred.callback(true);
 				}
 				store.save({onComplete:onComplete, onError:onError});
@@ -447,9 +447,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveVerifyState(){
-			//	summary:
+			// summary:
 			//		Simple test of the save API
-			//	description:
+			// description:
 			//		Simple test of the save API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -459,7 +459,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			}
 			function onItem(item){
 				store.setValue(item, "capital", "New Cairo");
-				function onComplete() {
+				function onComplete(){
 					//Check internal state.  Note:  Users should NOT do this, this is a UT verification
 					//of internals in this case.  Ref tracker: #4394
 					doh.assertTrue(!store._saveInProgress);
@@ -471,9 +471,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveEverything(){
-			//	summary:
+			// summary:
 			//		Simple test of the save API
-			//	description:
+			// description:
 			//		Simple test of the save API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 			var egypt;
@@ -501,7 +501,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			};
 			var onItem = function(item){
 				egypt = item;
-				var onComplete = function() {
+				var onComplete = function(){
 					deferred.callback(true);
 				};
 				store.setValue(egypt, "capital", "New Cairo");
@@ -511,9 +511,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveEverything_HierarchyOff(){
-			//	summary:
+			// summary:
 			//		Simple test of the save API
-			//	description:
+			// description:
 			//		Simple test of the save API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("geography_hierarchy_small"));
 			store.hierarchical = false;
@@ -537,7 +537,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			};
 			var onComplete = function(items, request){
 				africa = items[0];
-				var onComplete = function() {
+				var onComplete = function(){
 					deferred.callback(true);
 				};
 				store.setValue(africa, "size", "HUGE!");
@@ -547,9 +547,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveEverything_withDateType(){
-			//	summary:
+			// summary:
 			//		Simple test of the save API	with a non-atomic type (Date) that has a type mapping.
-			//	description:
+			// description:
 			//		Simple test of the save API	with a non-atomic type (Date) that has a type mapping.
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -577,7 +577,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				deferred.errback(error);
 			};
 			var onItem = function(item){
-				var onComplete = function() {
+				var onComplete = function(){
 					deferred.callback(true);
 				};
 				store.setValue(item, "independence", new Date(1993,4,24));
@@ -587,9 +587,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveEverything_withCustomColorTypeSimple(){
-			//	summary:
+			// summary:
 			//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
-			//	description:
+			// description:
 			//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
 
 			//Set up the store basics:  What data it has, and what to do when save is called for saveEverything
@@ -634,7 +634,7 @@ doh.register("tests.data.ItemFileWriteStore",
             var onError = function(error){
 				deferred.errback(error);
 			};
-			var onComplete = function() {
+			var onComplete = function(){
 				deferred.callback(true);
 			};
 
@@ -643,9 +643,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveEverything_withCustomColorTypeGeneral(){
-			//	summary:
+			// summary:
 			//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
-			//	description:
+			// description:
 			//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
 
 			//Set up the store basics:  What data it has, and what to do when save is called for saveEverything
@@ -697,7 +697,7 @@ doh.register("tests.data.ItemFileWriteStore",
             var onError = function(error){
 				deferred.errback(error);
 			};
-			var onComplete = function() {
+			var onComplete = function(){
 				deferred.callback(true);
 			};
 
@@ -706,9 +706,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_newItem_revert(){
-			//	summary:
+			// summary:
 			//		Test for bug #5357.  Ensure that the revert properly nulls the identity position
-			//      for a new item after revert.
+			//		for a new item after revert.
 			var args = {data: {
 				label:"name",
 				items:[
@@ -732,9 +732,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			doh.assertTrue(store._arrayOfAllItems[itemEntryNum] === null);
 		},
 		function testWriteAPI_new_modify_revert(){
-			//	summary:
+			// summary:
 			//		Test of a new item, modify it, then revert, to ensure the state remains consistent.  Added due to #9022.
-			//	description:
+			// description:
 			//		Test of a new item, modify it, then revert, to ensure the state remains consistent.  Added due to #9022.
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -766,9 +766,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_new_modify_delete_revert(){
-			//	summary:
+			// summary:
 			//		Test of a new item, modify it, delete it, then revert, to ensure the state remains consistent.  Added due to #9022.
-			//	description:
+			// description:
 			//		Test of a new item, modify it, delete it, then revert, to ensure the state remains consistent.  Added due to #9022.
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 			var i;
@@ -836,9 +836,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testNotificationAPI_onSet(){
-			//	summary:
+			// summary:
 			//		Simple test of the onSet API
-			//	description:
+			// description:
 			//		Simple test of the onSet API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -864,9 +864,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			store.fetchItemByIdentity({identity:"eg", onItem:onItem, onError:onError});
 		},
 		function testNotificationAPI_onNew(){
-			//	summary:
+			// summary:
 			//		Simple test of the onNew API
-			//	description:
+			// description:
 			//		Simple test of the onNew API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -882,9 +882,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			var canada = store.newItem({name:"Canada", abbr:"ca", capital:"Ottawa"});
 		},
 		function testNotificationAPI_onDelete(){
-			//	summary:
+			// summary:
 			//		Simple test of the onDelete API
-			//	description:
+			// description:
 			//		Simple test of the onDelete API
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -907,9 +907,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			store.fetchItemByIdentity({identity:"eg", onItem:onItem, onError:onError});
 		},
 		function testReadAPI_functionConformanceToo(){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			var testStore = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 			var readApi = new dojo.data.api.Read();
@@ -929,9 +929,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			doh.assertTrue(passed);
 		},
 		function testWriteAPI_functionConformance(){
-			//	summary:
+			// summary:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
 			var testStore = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 			var writeApi = new dojo.data.api.Write();
@@ -951,9 +951,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			doh.assertTrue(passed);
 		},
 		function testNotificationAPI_functionConformance(){
-			//	summary:
+			// summary:
 			//		Simple test Notification API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test Notification API conformance.  Checks to see all declared functions are actual functions on the instances.
 			var testStore = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 			var api = new dojo.data.api.Notification();
@@ -973,7 +973,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			doh.assertTrue(passed);
 		},
 		function testIdentityAPI_noIdentifierSpecified(){
-			//	summary:
+			// summary:
 			//		Test for bug #3873. Given a datafile that does not specify an
 			//		identifier, make sure ItemFileWriteStore auto-creates identities
 			//		that are unique even after calls to deleteItem() and newItem()
@@ -1026,7 +1026,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testIdentityAPI_noIdentifierSpecified_revert(){
-			//	summary:
+			// summary:
 			//		Test for bug #4691  Given a datafile that does not specify an
 			//		identifier, make sure ItemFileWriteStore auto-creates identities
 			//		that are unique even after calls to deleteItem() and newItem()
@@ -1086,9 +1086,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_checkReferences(){
-			//	summary:
+			// summary:
 			//		Simple test to verify the references were properly resolved.
-			//	description:
+			// description:
 			//		Simple test to verify the references were properly resolved.
 
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
@@ -1105,15 +1105,15 @@ doh.register("tests.data.ItemFileWriteStore",
 				var item5  = null;
 
 				var i;
-				for (i = 0; i < items.length; i++) {
+				for (i = 0; i < items.length; i++){
 					var ident = store.getIdentity(items[i]);
-					if (ident === 10) {
+					if (ident === 10){
 						item10 = items[i];
-					}else if (ident === 1) {
+					}else if (ident === 1){
 						item1 = items[i];
-					}else if (ident === 3) {
+					}else if (ident === 3){
 						item3 = items[i];
-					}else if (ident === 5) {
+					}else if (ident === 5){
 						item5 = items[i];
 					}
 				}
@@ -1127,18 +1127,18 @@ doh.register("tests.data.ItemFileWriteStore",
 				doh.assertTrue(store.isItem(item5));
 				var found = 0;
 				try{
-					for (i = 0; i < friends.length; i++) {
-						if (i === 0) {
+					for (i = 0; i < friends.length; i++){
+						if (i === 0){
 							doh.assertTrue(store.isItem(friends[i]));
 							doh.assertEqual(friends[i], item1);
 							doh.assertEqual(store.getIdentity(friends[i]), 1);
 							found++;
-						}else if (i === 1) {
+						}else if (i === 1){
 							doh.assertTrue(store.isItem(friends[i]));
 							doh.assertEqual(friends[i], item3);
 							doh.assertEqual(store.getIdentity(friends[i]), 3);
 							found++;
-						}else if (i === 2) {
+						}else if (i === 2){
 							doh.assertTrue(store.isItem(friends[i]));
 							doh.assertEqual(friends[i], item5);
 							doh.assertEqual(store.getIdentity(friends[i]), 5);
@@ -1155,9 +1155,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_deleteReferencedItem(){
-			//	summary:
+			// summary:
 			//		Simple test to verify the references were properly deleted.
-			//	description:
+			// description:
 			//		Simple test to verify the references were properly deleted.
 
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
@@ -1210,9 +1210,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_deleteReferencedItemThenRevert(){
-			//	summary:
+			// summary:
 			//		Simple test to verify the references were properly deleted.
-			//	description:
+			// description:
 			//		Simple test to verify the references were properly deleted.
 
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
@@ -1250,10 +1250,10 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_deleteMultipleItemsWithReferencesAndRevert(){
-			//	summary:
+			// summary:
 			//		Simple test to verify that a flow of deleting items with references and reverting does not damage the internal structure.
 			//		Created for tracker bug: #5743
-			//	description:
+			// description:
 			//		Simple test to verify that a flow of deleting items with references and reverting does not damage the internal structure.
 			//		Created for tracker bug: #5743
 
@@ -1295,9 +1295,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_removeReferenceFromAttribute(){
-			//	summary:
+			// summary:
 			//		Simple test to verify the reference removal updates the internal map.
-			//	description:
+			// description:
 			//		Simple test to verify the reference removal updates the internal map.
 
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
@@ -1339,9 +1339,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_deleteReferencedItemNonParent(){
-			//	summary:
+			// summary:
 			//		Simple test to verify the references to a non-parent item was properly deleted.
-			//	description:
+			// description:
 			//		Simple test to verify the references to a non-parent item was properly deleted.
 
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
@@ -1393,9 +1393,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_addReferenceToAttribute(){
-			//	summary:
+			// summary:
 			//		Simple test to verify the reference additions can happen.
-			//	description:
+			// description:
 			//		Simple test to verify the reference additions can happen.
 
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
@@ -1435,9 +1435,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_newItemWithParentReference(){
-			//	summary:
+			// summary:
 			//		Simple test to verify that newItems with a parent properly record the parent's reference in the map.
-			//	description:
+			// description:
 			//		Simple test to verify that newItems with a parent properly record the parent's reference in the map.
 
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
@@ -1476,9 +1476,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_newItemWithReferenceToExistingItem(){
-			//	summary:
+			// summary:
 			//		Simple test to verify that a new item with references to existing items properly record the references in the map.
-			//	description:
+			// description:
 			//		Simple test to verify that a new item with references to existing items properly record the references in the map.
 
 			var store = new dojo.data.ItemFileWriteStore(tests.data.ItemFileWriteStore.getTestData("reference_integrity"));
@@ -1521,9 +1521,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_disableReferenceIntegrity(){
-			//	summary:
+			// summary:
 			//		Simple test to verify reference integrity can be disabled.
-			//	description:
+			// description:
 			//		Simple test to verify reference integrity can be disabled.
 
 			var params = tests.data.ItemFileWriteStore.getTestData("reference_integrity");
@@ -1548,9 +1548,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReadAPI_close_dirty_failure(){
-			//	summary:
+			// summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
-			if (dojo.isBrowser) {
+			if (dojo.isBrowser){
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
 				params.clearOnClose = true;
 				params.urlPreventCache = true;
@@ -1571,7 +1571,7 @@ doh.register("tests.data.ItemFileWriteStore",
 					}catch (e){
 						error = e;
 					}
-					if (error === null) {
+					if (error === null){
 						d.errback(new Error("Store was dirty, should have thrown an error on close!"));
 					}else{
 						d.callback(true);
diff --git a/dojo/tests/data/ObjectStore.js b/dojo/tests/data/ObjectStore.js
index 9b89c8e..e47dd39 100644
--- a/dojo/tests/data/ObjectStore.js
+++ b/dojo/tests/data/ObjectStore.js
@@ -97,6 +97,24 @@ tests.register("tests.data.ObjectStore",
 			}});
 			return d;
 		},
+		function testMemoryQueryWithEscapedWildcard(t){
+			var d = new doh.Deferred();
+			memoryDataStore.fetch({query:{name:"s\\*"}, onComplete: function(results){
+				t.is(results.length, 0);
+			}});
+			var newItem = memoryDataStore.newItem({
+				name: "s*",
+				id: Math.random()
+			});
+			memoryDataStore.save();
+			memoryDataStore.fetch({query:{name:"s\\*"}, onComplete: function(results){
+				var object = results[0];
+				t.is(results.length, 1);
+				t.is(object.name, "s*");
+				d.callback(true);
+			}});
+			return d;
+		},
 		function testMemoryQueryWithWildcardCaseInsensitive(t){
 			var d = new doh.Deferred();
 			memoryDataStore.fetch({query:{name:"F*"}, queryOptions: {ignoreCase: true}, onComplete: function(results){
diff --git a/dojo/tests/data/readOnlyItemFileTestTemplates.js b/dojo/tests/data/readOnlyItemFileTestTemplates.js
index dac49e1..0de1bc4 100644
--- a/dojo/tests/data/readOnlyItemFileTestTemplates.js
+++ b/dojo/tests/data/readOnlyItemFileTestTemplates.js
@@ -1,10 +1,10 @@
 // FIXME: this test assumes the existence of the global object "tests"
-define(["dojo", "doh", "require", "dojo/data/api/Read", "dojo/data/api/Identity", "dojo/date", "dojo/date/stamp"], function(dojo, doh, require) {
+define(["dojo/main", "doh/main", "require", "dojo/data/api/Read", "dojo/data/api/Identity", "dojo/date", "dojo/date/stamp"], function(dojo, doh, require){
 
 dojo.getObject("data.readOnlyItemFileTestTemplates", true, tests);
 
 dojo.declare("tests.data.Wrapper", null, {
-	//	summary:
+	// summary:
 	//		Simple class to use for typeMap in order to	test out
 	//		'falsy' values for _value.
 	_wrapped: null,
@@ -13,11 +13,11 @@ dojo.declare("tests.data.Wrapper", null, {
 		this._wrapped = obj;
 	},
 
-	getValue: function() {
+	getValue: function(){
 		return this._wrapped;
 	},
 
-	setValue: function(obj) {
+	setValue: function(obj){
 		this._wrapped = obj;
 	},
 
@@ -39,7 +39,7 @@ tests.data.readOnlyItemFileTestTemplates.registerTestsForDatastore = function(/*
 	var makeNewTestFunction = function(template){
 		return function(t){return template.runTest(datastoreClass, t);};
 	};
-	for(var i = 0; i < testTemplates.length; ++i) {
+	for(var i = 0; i < testTemplates.length; ++i){
 		var testTemplate = testTemplates[i];
 		var test = {};
 		test.name = testTemplate.name;
@@ -57,7 +57,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 	var data = null;
 	if(name === "countries"){
 		if(dojo.isBrowser){
-			data = {url: require.toUrl("tests/data/countries.json")};
+			data = {url: require.toUrl("./countries.json")};
 		}else{
 			data = {data: {
 				identifier:"abbr",
@@ -75,7 +75,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if(name === "countries_withNull"){
 		if(dojo.isBrowser){
-			data = {url: require.toUrl("tests/data/countries_withNull.json")};
+			data = {url: require.toUrl("./countries_withNull.json")};
 		}else{
 			data = {data: {
 				identifier:"abbr",
@@ -92,7 +92,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if(name === "countries_withoutid"){
 		if(dojo.isBrowser){
-			data = {url: require.toUrl("tests/data/countries_withoutid.json")};
+			data = {url: require.toUrl("./countries_withoutid.json")};
 		}else{
 			data = {data: {
 				label: "name",
@@ -109,7 +109,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if (name === "countries_withBoolean"){
 		if(dojo.isBrowser){
-			data = {url: require.toUrl("tests/data/countries_withBoolean.json")};
+			data = {url: require.toUrl("./countries_withBoolean.json")};
 		}else{
 			data = {data: {
 				identifier:"abbr",
@@ -127,7 +127,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if (name === "countries_withDates"){
 		if(dojo.isBrowser){
-			data = {url: require.toUrl("tests/data/countries_withDates.json")};
+			data = {url: require.toUrl("./countries_withDates.json")};
 		}else{
 			data = {data: {
 				identifier:"abbr",
@@ -144,7 +144,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if (name === "geography_hierarchy_small"){
 		if(dojo.isBrowser){
-			data = {url: require.toUrl("tests/data/geography_hierarchy_small.json")};
+			data = {url: require.toUrl("./geography_hierarchy_small.json")};
 		}else{
 			data = {data: {
 				items:[
@@ -168,7 +168,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if (name === "data_multitype"){
 		if(dojo.isBrowser){
-			data = {url: require.toUrl("tests/data/data_multitype.json")};
+			data = {url: require.toUrl("./data_multitype.json")};
 		}else{
 			data = {data: {
 							"identifier": "count",
@@ -192,7 +192,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		}
 	}else if (name === "countries_references"){
 		if(dojo.isBrowser){
-			data = {url: require.toUrl("tests/data/countries_references.json")};
+			data = {url: require.toUrl("./countries_references.json")};
 		}else{
 			data = {data: { identifier: 'name',
 							label: 'name',
@@ -251,7 +251,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity()",
 		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -275,7 +275,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() preventCache",
 		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			var args = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
 			args.urlPreventCache = true;
@@ -301,9 +301,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() notFound",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -323,9 +323,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: getIdentityAttributes()",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the getIdentityAttributes function.
-			//	description:
+			// description:
 			//		Simple test of the getIdentityAttributes function.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -349,16 +349,16 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() commentFilteredJson",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//		This tests loading a comment-filtered json file so that people using secure
 			//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
 			//		paper.
 
 			if(dojo.isBrowser){
-                var store = new datastore({url: require.toUrl("tests/data/countries_commentFiltered.json")});
+                var store = new datastore({url: require.toUrl("./countries_commentFiltered.json")});
 
 				var d = new doh.Deferred();
 				function onItem(item){
@@ -379,9 +379,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() nullValue",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store, checling a null value.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store, checking a null value.
 			//		This tests handling attributes in json that were defined as null properly.
 			//		Introduced because of tracker: #3153
@@ -405,9 +405,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() booleanValue",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_withBoolean"));
 
@@ -431,9 +431,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() withoutSpecifiedIdInData",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
-			//	description:
+			// description:
 			//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_withoutid"));
 
@@ -455,13 +455,13 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
         name: "Identity API: fetchItemByIdentity() Object.prototype item identifier",
         runTest: function(datastore, t){
-			//      summary:
-			//          Simple test of bug where store would raise an error
-			//          if the item identifier was the same as an Object property name.
+			// summary:
+			//		Simple test of bug where store would raise an error
+			//		if the item identifier was the same as an Object property name.
 			var data = {identifier: 'id', items: [{id: 'toString', value: 'aha'}]};
 			var store = new datastore({data: data});
 			var d = new doh.Deferred();
-			function onitem(item) {
+			function onitem(item){
 				t.assertTrue(item.value == 'aha');
 				d.callback(true);
 			}
@@ -476,13 +476,13 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
         name: "Identity API: fetchItemByIdentity() Object.prototype item identifier 2",
         runTest: function(datastore, t){
-			//      summary:
-			//          Simple test of bug where store would raise an error
-			//          if the item identifier was the same as an Object property name.
+			// summary:
+			//		Simple test of bug where store would raise an error
+			//		if the item identifier was the same as an Object property name.
 			var data = {identifier: 'id', items: [{id: 'hasOwnProperty', value: 'yep'}]};
 			var store = new datastore({data: data});
 			var d = new doh.Deferred();
-			function onitem(item) {
+			function onitem(item){
 				t.assertTrue(item.value == 'yep');
 				d.callback(true);
 			}
@@ -497,9 +497,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
         name: "Identity API: fetchItemByIdentity() Object.prototype identity",
         runTest: function(datastore, t){
-			//      summary:
-			//          Simple test of bug where fetchItemByIdentity would return
-			//          an object property.
+			// summary:
+			//		Simple test of bug where fetchItemByIdentity would return
+			//		an object property.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_withoutid"));
 			var d = new doh.Deferred();
 			function onItem(item){
@@ -517,9 +517,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
         name: "Identity API: fetchItemByIdentity() Object.prototype identity 2",
         runTest: function(datastore, t){
-			//      summary:
-			//          Simple test of bug where fetchItemByIdentity would return
-			//          an object property.
+			// summary:
+			//		Simple test of bug where fetchItemByIdentity would return
+			//		an object property.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_withoutid"));
 			var d = new doh.Deferred();
 			function onItem(item){
@@ -537,9 +537,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: getIdentity()",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the getIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getIdentity function of the store.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -560,9 +560,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: getIdentity() withoutSpecifiedId",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the #4691 bug
-			//	description:
+			// description:
 			//		Simple test of the #4691 bug
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_withoutid"));
 
@@ -583,9 +583,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() all",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -607,9 +607,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() all failOk",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore that fails quietly.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore that fails quietly.
 			if(dojo.isBrowser){
 				var storeParams = {
@@ -636,9 +636,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() abort",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch abort on ItemFileReadStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch abort on ItemFileReadStore.
 			//Can only async abort in a browser, so disable this test from rhino
 			if(dojo.isBrowser){
@@ -676,9 +676,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() all (count === Infinity)",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore and with a count of Infinity.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore and with a count of Infinity.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -700,9 +700,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() all PreventCache",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore.
 			var args = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
 			args.urlPreventCache = true;
@@ -726,9 +726,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() one",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -751,9 +751,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() shallow",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of only toplevel items
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore of only toplevel items.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("geography_hierarchy_small"));
 
@@ -777,9 +777,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() Multiple",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
-			//	description:
+			// description:
 			//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("geography_hierarchy_small"));
 
@@ -821,9 +821,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() MultipleMixedFetch",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
-			//	description:
+			// description:
 			//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 			//		Tests an item fetch and an identity fetch.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
@@ -866,9 +866,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() deep",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of all items (including children (nested))
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore of all items (including children (nested))
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("geography_hierarchy_small"));
 
@@ -893,11 +893,11 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() hierarchy off",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of all items with hierarchy disabled
 			//		This should turn off processing child objects as data store items.  It will still process
 			//		references and type maps.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore of all items with hierarchy disabled
 			//		This should turn off processing child objects as data store items.  It will still process
 			//		references and type maps.
@@ -951,11 +951,11 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() hierarchy off refs still parse",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of all items with hierarchy disabled
 			//		This should turn off processing child objects as data store items.  It will still process
 			//		references and type maps.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore of all items with hierarchy disabled
 			//		This should turn off processing child objects as data store items.  It will still process
 			//		references and type maps.
@@ -1009,15 +1009,15 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() one_commentFilteredJson",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item.
 			//		This tests loading a comment-filtered json file so that people using secure
 			//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
 			//		paper.
 			if(dojo.isBrowser){
-                var store = new datastore({url: require.toUrl("tests/data/countries_commentFiltered.json")});
+                var store = new datastore({url: require.toUrl("./countries_commentFiltered.json")});
 
 				var d = new doh.Deferred();
 				function onComplete(items, request){
@@ -1039,9 +1039,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() withNull",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item where some attributes are null.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item where some attributes are null.
 			//		Introduced because of tracker: #3153
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_withNull"));
@@ -1065,9 +1065,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() all_streaming",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on ItemFileReadStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on ItemFileReadStore.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -1103,9 +1103,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() paging",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Test of multiple fetches on a single result.  Paging, if you will.
-			//	description:
+			// description:
 			//		Test of multiple fetches on a single result.  Paging, if you will.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -1174,9 +1174,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() with MultiType Match",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch againct an attribute that has different types for the value across items
-			//	description:
+			// description:
 			//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 			//		Introduced because of tracker: #4931
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("data_multitype"));
@@ -1200,9 +1200,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() with RegExp Match",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch using a RegExp works with IFRS
-			//	description:
+			// description:
 			//		Simple test of a basic fetch using a RegExp works with IFRS
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("data_multitype"));
 
@@ -1225,9 +1225,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() with RegExp Match Inline",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch using a RegExp works with IFRS
-			//	description:
+			// description:
 			//		Simple test of a basic fetch using a RegExp works with IFRS
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("data_multitype"));
 
@@ -1250,9 +1250,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() with MultiType, MultiValue Match",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch againct an attribute that has different types for the value across items
-			//	description:
+			// description:
 			//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 			//		Introduced because of tracker: #4931
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("data_multitype"));
@@ -1276,9 +1276,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getLabel()",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -1304,9 +1304,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getLabelAttributes()",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -1332,9 +1332,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getValue()",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -1356,9 +1356,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getValues()",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValues function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValues function of the store.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -1382,9 +1382,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: isItem()",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItem function of the store
-			//	description:
+			// description:
 			//		Simple test of the isItem function of the store
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -1406,11 +1406,11 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: isItem() multistore",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItem function of the store
 			//		to verify two different store instances do not accept
 			//		items from each other.
-			//	description:
+			// description:
 			//		Simple test of the isItem function of the store
 			//		to verify two different store instances do not accept
 			//		items from each other.
@@ -1447,9 +1447,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: hasAttribute()",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the hasAttribute function of the store
-			//	description:
+			// description:
 			//		Simple test of the hasAttribute function of the store
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -1485,9 +1485,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: containsValue()",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the containsValue function of the store
-			//	description:
+			// description:
 			//		Simple test of the containsValue function of the store
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -1519,9 +1519,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getAttributes()",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes function of the store
-			//	description:
+			// description:
 			//		Simple test of the getAttributes function of the store
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -1548,9 +1548,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getFeatures()",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -1562,14 +1562,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() patternMatch0",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of everything starting with lowercase e
-			//	description:
+			// description:
 			//		Function to test pattern matching of everything starting with lowercase e
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
 			var d = new doh.Deferred();
-			function completed(items, request) {
+			function completed(items, request){
 				t.assertEqual(items.length, 5);
 				var passed = true;
 				for(var i = 0; i < items.length; i++){
@@ -1586,7 +1586,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					d.errback(new Error("Unexpected abbreviation found, match failure."));
 				}
 			}
-			function error(error, request) {
+			function error(error, request){
 				t.assertTrue(false);
 				d.errback(error);
 			}
@@ -1597,9 +1597,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() patternMatch1",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of everything with $ in it.
-			//	description:
+			// description:
 			//		Function to test pattern matching of everything with $ in it.
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -1645,9 +1645,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() patternMatch2",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match
-			//	description:
+			// description:
 			//		Function to test exact pattern match
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -1693,9 +1693,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() patternMatch_caseSensitive",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of a pattern case-sensitively
-			//	description:
+			// description:
 			//		Function to test pattern matching of a pattern case-sensitively
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -1736,9 +1736,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() patternMatch_caseInsensitive",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of a pattern case-insensitively
-			//	description:
+			// description:
 			//		Function to test pattern matching of a pattern case-insensitively
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -1779,9 +1779,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortNumeric",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test sorting numerically.
-			//	description:
+			// description:
 			//		Function to test sorting numerically.
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -1832,9 +1832,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortNumericDescending",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test sorting numerically.
-			//	description:
+			// description:
 			//		Function to test sorting numerically.
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -1884,9 +1884,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortNumericWithCount",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
-			//	description:
+			// description:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -1939,9 +1939,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortAlphabetic",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering.
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -1993,7 +1993,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				}
 			}
 
-			function error(error, request) {
+			function error(error, request){
 				t.assertTrue(false);
 				d.errback(error);
 			}
@@ -2006,9 +2006,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortAlphabeticDescending",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering in descending mode.
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -2061,7 +2061,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				}
 			}
 
-			function error(error, request) {
+			function error(error, request){
 				t.assertTrue(false);
 				d.errback(error);
 			}
@@ -2074,9 +2074,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortDate",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test sorting date.
-			//	description:
+			// description:
 			//		Function to test sorting date.
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -2129,9 +2129,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortDateDescending",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test sorting date in descending order.
-			//	description:
+			// description:
 			//		Function to test sorting date in descending order.
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -2185,9 +2185,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortMultiple",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test sorting on multiple attributes.
-			//	description:
+			// description:
 			//		Function to test sorting on multiple attributes.
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -2254,9 +2254,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortMultipleSpecialComparator",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test sorting on multiple attributes with a custom comparator.
-			//	description:
+			// description:
 			//		Function to test sorting on multiple attributes with a custom comparator.
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -2278,15 +2278,15 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 
 
 			store.comparatorMap = {};
-			store.comparatorMap["status"] = function(a,b) {
+			store.comparatorMap["status"] = function(a,b){
 				var ret = 0;
 				// We want to map these by what the priority of these items are, not by alphabetical.
 				// So, custom comparator.
 				var enumMap = { OPEN: 3, BLOCKED: 2, PENDING: 1, CLOSED: 0};
-				if (enumMap[a] > enumMap[b]) {
+				if (enumMap[a] > enumMap[b]){
 					ret = 1;
 				}
-				if (enumMap[a] < enumMap[b]) {
+				if (enumMap[a] < enumMap[b]){
 					ret = -1;
 				}
 				return ret;
@@ -2324,9 +2324,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortAlphabeticWithUndefined",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering.
 
 			var store = new datastore({data: { identifier: "uniqueId",
@@ -2366,7 +2366,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				}
 			}
 
-			function error(error, request) {
+			function error(error, request){
 				t.assertTrue(false);
 				d.errback(error);
 			}
@@ -2379,10 +2379,10 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: errorCondition_idCollision_inMemory",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the errors thrown when there is an id collision in the data.
 			//		Added because of tracker: #2546
-			//	description:
+			// description:
 			//		Simple test of the errors thrown when there is an id collision in the data.
 			//		Added because of tracker: #2546
 
@@ -2413,15 +2413,15 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: errorCondition_idCollision_xhr",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test of the errors thrown when there is an id collision in the data.
 			//		Added because of tracker: #2546
-			//	description:
+			// description:
 			//		Simple test of the errors thrown when there is an id collision in the data.
 			//		Added because of tracker: #2546
 
 			if(dojo.isBrowser){
-				var store = new datastore({url: require.toUrl("tests/data/countries_idcollision.json")});
+				var store = new datastore({url: require.toUrl("./countries_idcollision.json")});
 				var d = new doh.Deferred();
 				function onComplete(items, request){
 					//This is bad if this fires, this case should fail and not call onComplete.
@@ -2466,7 +2466,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_Color_SimpleMapping",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test using literal values with custom datatypes
 			var dataset = {
 				identifier:'name',
@@ -2498,7 +2498,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_Color_GeneralMapping",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test using literal values with custom datatypes
 			var dataset = {
 				identifier:'name',
@@ -2536,7 +2536,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_CustomObject 0 (False) value",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test type mapping and _values that are false-like
 			var dataset = {
 				identifier:'name',
@@ -2574,7 +2574,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_CustomObject Boolean False values",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test type mapping and _values that are false-like
 			var dataset = {
 				identifier:'name',
@@ -2612,7 +2612,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_CustomObject Empty String values",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test type mapping and _values that are false-like
 			var dataset = {
 				identifier:'name',
@@ -2650,7 +2650,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_CustomObject explicit null values",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test type mapping and _values that are false-like
 			var dataset = {
 				identifier:'name',
@@ -2688,7 +2688,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_CustomObject explicit undefined value",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test type mapping and _values that are false-like
 			var dataset = {
 				identifier:'name',
@@ -2753,9 +2753,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: close (clearOnClose: true)",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
-			if (dojo.isBrowser) {
+			if (dojo.isBrowser){
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
 				params.clearOnClose = true;
 				params.urlPreventCache = true;
@@ -2777,7 +2777,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					}catch (e){
 						error = e;
 					}
-					if (error) {
+					if (error){
 						d.errback(error);
 					}else{
 						d.callback(true);
@@ -2794,9 +2794,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: close (clearOnClose: true, reset url.)",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
-			if (dojo.isBrowser) {
+			if (dojo.isBrowser){
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
 				params.clearOnClose = true;
 				params.urlPreventCache = true;
@@ -2816,7 +2816,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 						t.assertTrue(store._arrayOfAllItems.length === 0);
 						t.assertTrue(store._loadFinished === false);
 
-						store.url = require.toUrl("tests/data/countries_withNull.json");
+						store.url = require.toUrl("./countries_withNull.json");
 						function onItem2 (item){
 							var err;
 							try{
@@ -2836,7 +2836,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					}catch (e){
 						error = e;
 					}
-					if (error) {
+					if (error){
 						d.errback(error);
 					}
 				}
@@ -2851,9 +2851,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch, close (clearOnClose: true, reset url.)",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
-			if (dojo.isBrowser) {
+			if (dojo.isBrowser){
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
 				params.clearOnClose = true;
 				params.urlPreventCache = true;
@@ -2873,7 +2873,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 						t.assertTrue(store._arrayOfAllItems.length === 0);
 						t.assertTrue(store._loadFinished === false);
 
-						store.url = require.toUrl("tests/data/countries_withNull.json");
+						store.url = require.toUrl("./countries_withNull.json");
 						function onComplete (items){
                             var err;
 							try{
@@ -2895,7 +2895,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					}catch (e){
 						error = e;
 					}
-					if (error) {
+					if (error){
 						d.errback(error);
 					}
 				}
@@ -2910,9 +2910,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: close (clearOnClose: true, reset _jsonFileUrl.)",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
-			if (dojo.isBrowser) {
+			if (dojo.isBrowser){
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
 				params.clearOnClose = true;
 				params.urlPreventCache = true;
@@ -2932,7 +2932,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 						t.assertTrue(store._arrayOfAllItems.length === 0);
 						t.assertTrue(store._loadFinished === false);
 
-						store._jsonFileUrl = require.toUrl("tests/data/countries_withNull.json");
+						store._jsonFileUrl = require.toUrl("./countries_withNull.json");
 						function onItem2 (item){
 							var err;
 							try{
@@ -2952,7 +2952,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					}catch (e){
 						error = e;
 					}
-					if (error) {
+					if (error){
 						d.errback(error);
 					}
 				}
@@ -2967,9 +2967,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: close (clearOnClose: false)",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
-			if (dojo.isBrowser) {
+			if (dojo.isBrowser){
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
 				params.urlPreventCache = true;
 				var store = new datastore(params);
@@ -2990,7 +2990,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					}catch (e){
 						error = e;
 					}
-					if (error) {
+					if (error){
 						d.errback(error);
 					}else{
 						d.callback(true);
@@ -3007,9 +3007,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: close (clearOnClose: true, reset data.)",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Function to test that clear on close and reset of data works.
-			//	description:
+			// description:
 			//		Function to test that clear on close and reset of data works.
 			var store = new datastore({data: { identifier: "uniqueId",
 											  items: [ {uniqueId: 1, value:"foo*bar"},
@@ -3060,7 +3060,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					}catch(e){
 						d.errback(e);
 					}
-				}
+				};
 				store.fetch({query: {value: "bar\*foo"}, onComplete: secondComplete, onError: error});
 			};
 			function error(error, request){
@@ -3129,9 +3129,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: functionConformance",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			var testStore = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 			var readApi = new dojo.data.api.Read();
@@ -3157,9 +3157,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: functionConformance",
  		runTest: function(datastore, t){
-			//	summary:
+			// summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 			var testStore = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 			var identityApi = new dojo.data.api.Identity();
diff --git a/dojo/tests/data/runTests.html b/dojo/tests/data/runTests.html
index ee3d473..6ad3561 100644
--- a/dojo/tests/data/runTests.html
+++ b/dojo/tests/data/runTests.html
@@ -2,7 +2,7 @@
 <html>
     <head>
     <title>dojo.data D.O.H. Unit Test Runner</title>
-    <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=tests.data"></HEAD>
+    <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojo.tests.data"></HEAD>
     <BODY>
         Redirecting to D.O.H runner.
     </BODY>
diff --git a/dojo/tests/data/utils.js b/dojo/tests/data/utils.js
index f9e82c9..d144daf 100644
--- a/dojo/tests/data/utils.js
+++ b/dojo/tests/data/utils.js
@@ -1,4 +1,4 @@
-define(["dojo", "doh", "dojo/data/util/filter", "dojo/data/util/sorter"], function(dojo, doh){
+define(["dojo/main", "doh/main", "dojo/data/util/filter", "dojo/data/util/sorter"], function(dojo, doh){
 
 doh.register("tests.data.utils",
 	[
diff --git a/dojo/tests/date.js b/dojo/tests/date.js
index c032249..49adf3f 100644
--- a/dojo/tests/date.js
+++ b/dojo/tests/date.js
@@ -1,4 +1,4 @@
-define(["../main", "doh", "../date", "./date/locale", "./date/stamp"], function(dojo, doh){
+define(["doh", "../date"], function(doh, date){
 doh.register("tests.date.util", [
 
 /* Informational Functions
@@ -6,36 +6,36 @@ doh.register("tests.date.util", [
 
 function test_date_getDaysInMonth(t){
 	// months other than February
-	t.is(31, dojo.date.getDaysInMonth(new Date(2006,0,1)));
-	t.is(31, dojo.date.getDaysInMonth(new Date(2006,2,1)));
-	t.is(30, dojo.date.getDaysInMonth(new Date(2006,3,1)));
-	t.is(31, dojo.date.getDaysInMonth(new Date(2006,4,1)));
-	t.is(30, dojo.date.getDaysInMonth(new Date(2006,5,1)));
-	t.is(31, dojo.date.getDaysInMonth(new Date(2006,6,1)));
-	t.is(31, dojo.date.getDaysInMonth(new Date(2006,7,1)));
-	t.is(30, dojo.date.getDaysInMonth(new Date(2006,8,1)));
-	t.is(31, dojo.date.getDaysInMonth(new Date(2006,9,1)));
-	t.is(30, dojo.date.getDaysInMonth(new Date(2006,10,1)));
-	t.is(31, dojo.date.getDaysInMonth(new Date(2006,11,1)));
+	t.is(31, date.getDaysInMonth(new Date(2006,0,1)));
+	t.is(31, date.getDaysInMonth(new Date(2006,2,1)));
+	t.is(30, date.getDaysInMonth(new Date(2006,3,1)));
+	t.is(31, date.getDaysInMonth(new Date(2006,4,1)));
+	t.is(30, date.getDaysInMonth(new Date(2006,5,1)));
+	t.is(31, date.getDaysInMonth(new Date(2006,6,1)));
+	t.is(31, date.getDaysInMonth(new Date(2006,7,1)));
+	t.is(30, date.getDaysInMonth(new Date(2006,8,1)));
+	t.is(31, date.getDaysInMonth(new Date(2006,9,1)));
+	t.is(30, date.getDaysInMonth(new Date(2006,10,1)));
+	t.is(31, date.getDaysInMonth(new Date(2006,11,1)));
 
 	// Februarys
-	t.is(28, dojo.date.getDaysInMonth(new Date(2006,1,1)));
-	t.is(29, dojo.date.getDaysInMonth(new Date(2004,1,1)));
-	t.is(29, dojo.date.getDaysInMonth(new Date(2000,1,1)));
-	t.is(28, dojo.date.getDaysInMonth(new Date(1900,1,1)));
-	t.is(28, dojo.date.getDaysInMonth(new Date(1800,1,1)));
-	t.is(28, dojo.date.getDaysInMonth(new Date(1700,1,1)));
-	t.is(29, dojo.date.getDaysInMonth(new Date(1600,1,1)));
+	t.is(28, date.getDaysInMonth(new Date(2006,1,1)));
+	t.is(29, date.getDaysInMonth(new Date(2004,1,1)));
+	t.is(29, date.getDaysInMonth(new Date(2000,1,1)));
+	t.is(28, date.getDaysInMonth(new Date(1900,1,1)));
+	t.is(28, date.getDaysInMonth(new Date(1800,1,1)));
+	t.is(28, date.getDaysInMonth(new Date(1700,1,1)));
+	t.is(29, date.getDaysInMonth(new Date(1600,1,1)));
 },
 
 function test_date_isLeapYear(t){
-	t.f(dojo.date.isLeapYear(new Date(2006,0,1)));
-	t.t(dojo.date.isLeapYear(new Date(2004,0,1)));
-	t.t(dojo.date.isLeapYear(new Date(2000,0,1)));
-	t.f(dojo.date.isLeapYear(new Date(1900,0,1)));
-	t.f(dojo.date.isLeapYear(new Date(1800,0,1)));
-	t.f(dojo.date.isLeapYear(new Date(1700,0,1)));
-	t.t(dojo.date.isLeapYear(new Date(1600,0,1)));
+	t.f(date.isLeapYear(new Date(2006,0,1)));
+	t.t(date.isLeapYear(new Date(2004,0,1)));
+	t.t(date.isLeapYear(new Date(2000,0,1)));
+	t.f(date.isLeapYear(new Date(1900,0,1)));
+	t.f(date.isLeapYear(new Date(1800,0,1)));
+	t.f(date.isLeapYear(new Date(1700,0,1)));
+	t.t(date.isLeapYear(new Date(1600,0,1)));
 },
 
 // The getTimezone function pulls from either the date's toString or
@@ -52,7 +52,7 @@ function test_date_getTimezoneName(t){
 	function FakeDate(str, strLocale){
 		this.str = str || '';
 		this.strLocale = strLocale || '';
-		this.toString = function() {
+		this.toString = function(){
 			return this.str;
 		};
 		this.toLocaleString = function(){
@@ -64,37 +64,37 @@ function test_date_getTimezoneName(t){
 	// FF 1.5 Ubuntu Linux (Breezy)
 	dt.str = 'Sun Sep 17 2006 22:25:51 GMT-0500 (CDT)';
 	dt.strLocale = 'Sun 17 Sep 2006 10:25:51 PM CDT';
-	t.is('CDT', dojo.date.getTimezoneName(dt));
+	t.is('CDT', date.getTimezoneName(dt));
 
 	// Safari 2.0 Mac OS X 10.4
 	dt.str = 'Sun Sep 17 2006 22:55:01 GMT-0500';
 	dt.strLocale = 'September 17, 2006 10:55:01 PM CDT';
-	t.is('CDT', dojo.date.getTimezoneName(dt));
+	t.is('CDT', date.getTimezoneName(dt));
 
 	// FF 1.5 Mac OS X 10.4
 	dt.str = 'Sun Sep 17 2006 22:57:18 GMT-0500 (CDT)';
 	dt.strLocale = 'Sun Sep 17 22:57:18 2006';
-	t.is('CDT', dojo.date.getTimezoneName(dt));
+	t.is('CDT', date.getTimezoneName(dt));
 
 	// Opera 9 Mac OS X 10.4 -- no TZ data expect empty string return
 	dt.str = 'Sun, 17 Sep 2006 22:58:06 GMT-0500';
 	dt.strLocale = 'Sunday September 17, 22:58:06 GMT-0500 2006';
-	t.is('', dojo.date.getTimezoneName(dt));
+	t.is('', date.getTimezoneName(dt));
 
 	// IE 6 Windows XP
 	dt.str = 'Mon Sep 18 11:21:07 CDT 2006';
 	dt.strLocale = 'Monday, September 18, 2006 11:21:07 AM';
-	t.is('CDT', dojo.date.getTimezoneName(dt));
+	t.is('CDT', date.getTimezoneName(dt));
 
 	// Opera 9 Ubuntu Linux (Breezy) -- no TZ data expect empty string return
 	dt.str = 'Mon, 18 Sep 2006 13:30:32 GMT-0500';
 	dt.strLocale = 'Monday September 18, 13:30:32 GMT-0500 2006';
-	t.is('', dojo.date.getTimezoneName(dt));
+	t.is('', date.getTimezoneName(dt));
 
 	// IE 5.5 Windows 2000
 	dt.str = 'Mon Sep 18 13:49:22 CDT 2006';
 	dt.strLocale = 'Monday, September 18, 2006 1:49:22 PM';
-	t.is('CDT', dojo.date.getTimezoneName(dt));
+	t.is('CDT', date.getTimezoneName(dt));
 }
 	]
 );
@@ -107,11 +107,11 @@ function test_date_compare(t){
 	var d2=new Date();
 	d2.setFullYear(2005);
 	d2.setHours(12);
-	t.is(0, dojo.date.compare(d1, d1));
-	t.is(1, dojo.date.compare(d1, d2, "date"));
-	t.is(-1, dojo.date.compare(d2, d1, "date"));
-	t.is(-1, dojo.date.compare(d1, d2, "time"));
-	t.is(1, dojo.date.compare(d1, d2, "datetime"));
+	t.is(0, date.compare(d1, d1));
+	t.is(1, date.compare(d1, d2, "date"));
+	t.is(-1, date.compare(d2, d1, "date"));
+	t.is(-1, date.compare(d1, d2, "time"));
+	t.is(1, date.compare(d1, d2, "datetime"));
 },
 function test_date_add(t){
 	var interv = ''; // Interval (e.g., year, month)
@@ -121,186 +121,186 @@ function test_date_add(t){
 	interv = "year";
 	dtA = new Date(2005, 11, 27);
 	dtB = new Date(2006, 11, 27);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2005, 11, 27);
 	dtB = new Date(2004, 11, 27);
-	t.is(dtB, dojo.date.add(dtA, interv, -1));
+	t.is(dtB, date.add(dtA, interv, -1));
 
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2001, 1, 28);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2005, 1, 28);
-	t.is(dtB, dojo.date.add(dtA, interv, 5));
+	t.is(dtB, date.add(dtA, interv, 5));
 
 	dtA = new Date(1900, 11, 31);
 	dtB = new Date(1930, 11, 31);
-	t.is(dtB, dojo.date.add(dtA, interv, 30));
+	t.is(dtB, date.add(dtA, interv, 30));
 
 	dtA = new Date(1995, 11, 31);
 	dtB = new Date(2030, 11, 31);
-	t.is(dtB, dojo.date.add(dtA, interv, 35));
+	t.is(dtB, date.add(dtA, interv, 35));
 
 	interv = "quarter";
 	dtA = new Date(2000, 0, 1);
 	dtB = new Date(2000, 3, 1);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2000, 7, 29);
-	t.is(dtB, dojo.date.add(dtA, interv, 2));
+	t.is(dtB, date.add(dtA, interv, 2));
 
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2001, 1, 28);
-	t.is(dtB, dojo.date.add(dtA, interv, 4));
+	t.is(dtB, date.add(dtA, interv, 4));
 
 	interv = "month";
 	dtA = new Date(2000, 0, 1);
 	dtB = new Date(2000, 1, 1);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2000, 0, 31);
 	dtB = new Date(2000, 1, 29);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2001, 1, 28);
-	t.is(dtB, dojo.date.add(dtA, interv, 12));
+	t.is(dtB, date.add(dtA, interv, 12));
 
 	interv = "week";
 	dtA = new Date(2000, 0, 1);
 	dtB = new Date(2000, 0, 8);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	interv = "day";
 	dtA = new Date(2000, 0, 1);
 	dtB = new Date(2000, 0, 2);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2001, 0, 1);
 	dtB = new Date(2002, 0, 1);
-	t.is(dtB, dojo.date.add(dtA, interv, 365));
+	t.is(dtB, date.add(dtA, interv, 365));
 
 	dtA = new Date(2000, 0, 1);
 	dtB = new Date(2001, 0, 1);
-	t.is(dtB, dojo.date.add(dtA, interv, 366));
+	t.is(dtB, date.add(dtA, interv, 366));
 
 	dtA = new Date(2000, 1, 28);
 	dtB = new Date(2000, 1, 29);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2001, 1, 28);
 	dtB = new Date(2001, 2, 1);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2000, 2, 1);
 	dtB = new Date(2000, 1, 29);
-	t.is(dtB, dojo.date.add(dtA, interv, -1));
+	t.is(dtB, date.add(dtA, interv, -1));
 
 	dtA = new Date(2001, 2, 1);
 	dtB = new Date(2001, 1, 28);
-	t.is(dtB, dojo.date.add(dtA, interv, -1));
+	t.is(dtB, date.add(dtA, interv, -1));
 
 	dtA = new Date(2000, 0, 1);
 	dtB = new Date(1999, 11, 31);
-	t.is(dtB, dojo.date.add(dtA, interv, -1));
+	t.is(dtB, date.add(dtA, interv, -1));
 
 	interv = "weekday";
 	// Sat, Jan 1
 	dtA = new Date(2000, 0, 1);
 	// Should be Mon, Jan 3
 	dtB = new Date(2000, 0, 3);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	// Sun, Jan 2
 	dtA = new Date(2000, 0, 2);
 	// Should be Mon, Jan 3
 	dtB = new Date(2000, 0, 3);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	// Sun, Jan 2
 	dtA = new Date(2000, 0, 2);
 	// Should be Fri, Jan 7
 	dtB = new Date(2000, 0, 7);
-	t.is(dtB, dojo.date.add(dtA, interv, 5));
+	t.is(dtB, date.add(dtA, interv, 5));
 
 	// Sun, Jan 2
 	dtA = new Date(2000, 0, 2);
 	// Should be Mon, Jan 10
 	dtB = new Date(2000, 0, 10);
-	t.is(dtB, dojo.date.add(dtA, interv, 6));
+	t.is(dtB, date.add(dtA, interv, 6));
 
 	// Mon, Jan 3
 	dtA = new Date(2000, 0, 3);
 	// Should be Mon, Jan 17
 	dtB = new Date(2000, 0, 17);
-	t.is(dtB, dojo.date.add(dtA, interv, 10));
+	t.is(dtB, date.add(dtA, interv, 10));
 
 	// Sat, Jan 8
 	dtA = new Date(2000, 0, 8);
 	// Should be Mon, Jan 3
 	dtB = new Date(2000, 0, 3);
-	t.is(dtB, dojo.date.add(dtA, interv, -5));
+	t.is(dtB, date.add(dtA, interv, -5));
 
 	// Sun, Jan 9
 	dtA = new Date(2000, 0, 9);
 	// Should be Wed, Jan 5
 	dtB = new Date(2000, 0, 5);
-	t.is(dtB, dojo.date.add(dtA, interv, -3));
+	t.is(dtB, date.add(dtA, interv, -3));
 
 	// Sun, Jan 23
 	dtA = new Date(2000, 0, 23);
 	// Should be Fri, Jan 7
 	dtB = new Date(2000, 0, 7);
-	t.is(dtB, dojo.date.add(dtA, interv, -11));
+	t.is(dtB, date.add(dtA, interv, -11));
 
 	interv = "hour";
 	dtA = new Date(2000, 0, 1, 11);
 	dtB = new Date(2000, 0, 1, 12);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2001, 9, 28, 0);
 	dtB = new Date(dtA.getTime() + (60 * 60 * 1000));
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2001, 9, 28, 23);
 	dtB = new Date(2001, 9, 29, 0);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2001, 11, 31, 23);
 	dtB = new Date(2002, 0, 1, 0);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	interv = "minute";
 	dtA = new Date(2000, 11, 31, 23, 59);
 	dtB = new Date(2001, 0, 1, 0, 0);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2000, 11, 27, 12, 2);
 	dtB = new Date(2000, 11, 27, 13, 2);
-	t.is(dtB, dojo.date.add(dtA, interv, 60));
+	t.is(dtB, date.add(dtA, interv, 60));
 
 	interv = "second";
 	dtA = new Date(2000, 11, 31, 23, 59, 59);
 	dtB = new Date(2001, 0, 1, 0, 0, 0);
-	t.is(dtB, dojo.date.add(dtA, interv, 1));
+	t.is(dtB, date.add(dtA, interv, 1));
 
 	dtA = new Date(2000, 11, 27, 8, 10, 59);
 	dtB = new Date(2000, 11, 27, 8, 11, 59);
-	t.is(dtB, dojo.date.add(dtA, interv, 60));
+	t.is(dtB, date.add(dtA, interv, 60));
 
 	// Test environment JS Date doesn't support millisec?
 	//interv = "millisecond";
 	//
 	//dtA = new Date(2000, 11, 31, 23, 59, 59, 999);
 	//dtB = new Date(2001, 0, 1, 0, 0, 0, 0);
-	//t.is(dtB, dojo.date.add(dtA, interv, 1));
+	//t.is(dtB, date.add(dtA, interv, 1));
 	//
 	//dtA = new Date(2000, 11, 27, 8, 10, 53, 2);
 	//dtB = new Date(2000, 11, 27, 8, 10, 54, 2);
-	//t.is(dtB, dojo.date.add(dtA, interv, 1000));
+	//t.is(dtB, date.add(dtA, interv, 1000));
 },
 function test_date_diff(t){
 	var dtA = null; // First date to compare
@@ -310,174 +310,174 @@ function test_date_diff(t){
 	interv = "year";
 	dtA = new Date(2005, 11, 27);
 	dtB = new Date(2006, 11, 27);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2000, 11, 31);
 	dtB = new Date(2001, 0, 1);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	interv = "quarter";
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2001, 2, 1);
-	t.is(4, dojo.date.difference(dtA, dtB, interv));
+	t.is(4, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2000, 11, 1);
 	dtB = new Date(2001, 0, 1);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	interv = "month";
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2001, 2, 1);
-	t.is(13, dojo.date.difference(dtA, dtB, interv));
+	t.is(13, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2000, 11, 1);
 	dtB = new Date(2001, 0, 1);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	interv = "week";
 	dtA = new Date(2000, 1, 1);
 	dtB = new Date(2000, 1, 8);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2000, 1, 28);
 	dtB = new Date(2000, 2, 6);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2000, 2, 6);
 	dtB = new Date(2000, 1, 28);
-	t.is(-1, dojo.date.difference(dtA, dtB, interv));
+	t.is(-1, date.difference(dtA, dtB, interv));
 
 	interv = "day";
 	dtA = new Date(2000, 1, 29);
 	dtB = new Date(2000, 2, 1);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2000, 11, 31);
 	dtB = new Date(2001, 0, 1);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	// DST leap -- check for rounding err
 	// This is dependent on US calendar, but
 	// shouldn't break in other locales
 	dtA = new Date(2005, 3, 3);
 	dtB = new Date(2005, 3, 4);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	interv = "weekday";
 	dtA = new Date(2006, 7, 3);
 	dtB = new Date(2006, 7, 11);
-	t.is(6, dojo.date.difference(dtA, dtB, interv));
+	t.is(6, date.difference(dtA, dtB, interv));
 
 	// Positive diffs
 	dtA = new Date(2006, 7, 4);
 	dtB = new Date(2006, 7, 11);
-	t.is(5, dojo.date.difference(dtA, dtB, interv));
+	t.is(5, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 5);
 	dtB = new Date(2006, 7, 11);
-	t.is(5, dojo.date.difference(dtA, dtB, interv));
+	t.is(5, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 6);
 	dtB = new Date(2006, 7, 11);
-	t.is(5, dojo.date.difference(dtA, dtB, interv));
+	t.is(5, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 7);
 	dtB = new Date(2006, 7, 11);
-	t.is(4, dojo.date.difference(dtA, dtB, interv));
+	t.is(4, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 7);
 	dtB = new Date(2006, 7, 13);
-	t.is(4, dojo.date.difference(dtA, dtB, interv));
+	t.is(4, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 7);
 	dtB = new Date(2006, 7, 14);
-	t.is(5, dojo.date.difference(dtA, dtB, interv));
+	t.is(5, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 7);
 	dtB = new Date(2006, 7, 15);
-	t.is(6, dojo.date.difference(dtA, dtB, interv));
+	t.is(6, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 7);
 	dtB = new Date(2006, 7, 28);
-	t.is(15, dojo.date.difference(dtA, dtB, interv));
+	t.is(15, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 2, 2);
 	dtB = new Date(2006, 2, 28);
-	t.is(18, dojo.date.difference(dtA, dtB, interv));
+	t.is(18, date.difference(dtA, dtB, interv));
 
 	// Negative diffs
 	dtA = new Date(2006, 7, 11);
 	dtB = new Date(2006, 7, 4);
-	t.is(-5, dojo.date.difference(dtA, dtB, interv));
+	t.is(-5, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 11);
 	dtB = new Date(2006, 7, 5);
-	t.is(-4, dojo.date.difference(dtA, dtB, interv));
+	t.is(-4, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 11);
 	dtB = new Date(2006, 7, 6);
-	t.is(-4, dojo.date.difference(dtA, dtB, interv));
+	t.is(-4, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 11);
 	dtB = new Date(2006, 7, 7);
-	t.is(-4, dojo.date.difference(dtA, dtB, interv));
+	t.is(-4, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 13);
 	dtB = new Date(2006, 7, 7);
-	t.is(-5, dojo.date.difference(dtA, dtB, interv));
+	t.is(-5, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 14);
 	dtB = new Date(2006, 7, 7);
-	t.is(-5, dojo.date.difference(dtA, dtB, interv));
+	t.is(-5, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 15);
 	dtB = new Date(2006, 7, 7);
-	t.is(-6, dojo.date.difference(dtA, dtB, interv));
+	t.is(-6, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 7, 28);
 	dtB = new Date(2006, 7, 7);
-	t.is(-15, dojo.date.difference(dtA, dtB, interv));
+	t.is(-15, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2006, 2, 28);
 	dtB = new Date(2006, 2, 2);
-	t.is(-18, dojo.date.difference(dtA, dtB, interv));
+	t.is(-18, date.difference(dtA, dtB, interv));
 
 	// Two days on the same weekend -- no weekday diff
 	dtA = new Date(2006, 7, 5);
 	dtB = new Date(2006, 7, 6);
-	t.is(0, dojo.date.difference(dtA, dtB, interv));
+	t.is(0, date.difference(dtA, dtB, interv));
 
 	interv = "hour";
 	dtA = new Date(2000, 11, 31, 23);
 	dtB = new Date(2001, 0, 1, 0);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2000, 11, 31, 12);
 	dtB = new Date(2001, 0, 1, 0);
-	t.is(12, dojo.date.difference(dtA, dtB, interv));
+	t.is(12, date.difference(dtA, dtB, interv));
 
 	interv = "minute";
 	dtA = new Date(2000, 11, 31, 23, 59);
 	dtB = new Date(2001, 0, 1, 0, 0);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2000, 1, 28, 23, 59);
 	dtB = new Date(2000, 1, 29, 0, 0);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	interv = "second";
 	dtA = new Date(2000, 11, 31, 23, 59, 59);
 	dtB = new Date(2001, 0, 1, 0, 0, 0);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	interv = "millisecond";
 	dtA = new Date(2000, 11, 31, 23, 59, 59, 999);
 	dtB = new Date(2001, 0, 1, 0, 0, 0, 0);
-	t.is(1, dojo.date.difference(dtA, dtB, interv));
+	t.is(1, date.difference(dtA, dtB, interv));
 
 	dtA = new Date(2000, 11, 31, 23, 59, 59, 0);
 	dtB = new Date(2001, 0, 1, 0, 0, 0, 0);
-	t.is(1000, dojo.date.difference(dtA, dtB, interv));
+	t.is(1000, date.difference(dtA, dtB, interv));
 },
 function test_date_add_diff_year(t){
 	var interv = ''; // Interval (e.g., year, month)
@@ -486,28 +486,28 @@ function test_date_add_diff_year(t){
 
 	interv = "year";
 	dtA = new Date(2005, 11, 27);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2005, 11, 27);
-	dtB = dojo.date.add(dtA, interv, -1);
-	t.is(dojo.date.difference(dtA, dtB, interv), -1);
+	dtB = date.add(dtA, interv, -1);
+	t.is(date.difference(dtA, dtB, interv), -1);
 
 	dtA = new Date(2000, 1, 29);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2000, 1, 29);
-	dtB = dojo.date.add(dtA, interv, 5);
-	t.is(dojo.date.difference(dtA, dtB, interv), 5);
+	dtB = date.add(dtA, interv, 5);
+	t.is(date.difference(dtA, dtB, interv), 5);
 
 	dtA = new Date(1900, 11, 31);
-	dtB = dojo.date.add(dtA, interv, 30);
-	t.is(dojo.date.difference(dtA, dtB, interv), 30);
+	dtB = date.add(dtA, interv, 30);
+	t.is(date.difference(dtA, dtB, interv), 30);
 
 	dtA = new Date(1995, 11, 31);
-	dtB = dojo.date.add(dtA, interv, 35);
-	t.is(dojo.date.difference(dtA, dtB, interv), 35);
+	dtB = date.add(dtA, interv, 35);
+	t.is(date.difference(dtA, dtB, interv), 35);
 },
 function test_date_add_diff_quarter(t){
 	var interv = ''; // Interval (e.g., year, month)
@@ -515,16 +515,16 @@ function test_date_add_diff_quarter(t){
 	var dtB = null; // Expected result date
 	interv = "quarter";
 	dtA = new Date(2000, 0, 1);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2000, 1, 29);
-	dtB = dojo.date.add(dtA, interv, 2);
-	t.is(dojo.date.difference(dtA, dtB, interv), 2);
+	dtB = date.add(dtA, interv, 2);
+	t.is(date.difference(dtA, dtB, interv), 2);
 
 	dtA = new Date(2000, 1, 29);
-	dtB = dojo.date.add(dtA, interv, 4);
-	t.is(dojo.date.difference(dtA, dtB, interv), 4);
+	dtB = date.add(dtA, interv, 4);
+	t.is(date.difference(dtA, dtB, interv), 4);
 },
 function test_date_add_diff_month(t){
 	var interv = ''; // Interval (e.g., year, month)
@@ -532,16 +532,16 @@ function test_date_add_diff_month(t){
 	var dtB = null; // Expected result date
 	interv = "month";
 	dtA = new Date(2000, 0, 1);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2000, 0, 31);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2000, 1, 29);
-	dtB = dojo.date.add(dtA, interv, 12);
-	t.is(dojo.date.difference(dtA, dtB, interv), 12);
+	dtB = date.add(dtA, interv, 12);
+	t.is(date.difference(dtA, dtB, interv), 12);
 },
 function test_date_add_diff_week(t){
 	var interv = ''; // Interval (e.g., year, month)
@@ -549,8 +549,8 @@ function test_date_add_diff_week(t){
 	var dtB = null; // Expected result date
 	interv = "week";
 	dtA = new Date(2000, 0, 1);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 },
 function test_date_add_diff_day(t){
 	var interv = ''; // Interval (e.g., year, month)
@@ -558,36 +558,36 @@ function test_date_add_diff_day(t){
 	var dtB = null; // Expected result date
 	interv = "day";
 	dtA = new Date(2000, 0, 1);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2001, 0, 1);
-	dtB = dojo.date.add(dtA, interv, 365);
-	t.is(dojo.date.difference(dtA, dtB, interv), 365);
+	dtB = date.add(dtA, interv, 365);
+	t.is(date.difference(dtA, dtB, interv), 365);
 
 	dtA = new Date(2000, 0, 1);
-	dtB = dojo.date.add(dtA, interv, 366);
-	t.is(dojo.date.difference(dtA, dtB, interv), 366);
+	dtB = date.add(dtA, interv, 366);
+	t.is(date.difference(dtA, dtB, interv), 366);
 
 	dtA = new Date(2000, 1, 28);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2001, 1, 28);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2000, 2, 1);
-	dtB = dojo.date.add(dtA, interv, -1);
-	t.is(dojo.date.difference(dtA, dtB, interv), -1);
+	dtB = date.add(dtA, interv, -1);
+	t.is(date.difference(dtA, dtB, interv), -1);
 
 	dtA = new Date(2001, 2, 1);
-	dtB = dojo.date.add(dtA, interv, -1);
-	t.is(dojo.date.difference(dtA, dtB, interv), -1);
+	dtB = date.add(dtA, interv, -1);
+	t.is(date.difference(dtA, dtB, interv), -1);
 
 	dtA = new Date(2000, 0, 1);
-	dtB = dojo.date.add(dtA, interv, -1);
-	t.is(dojo.date.difference(dtA, dtB, interv), -1);
+	dtB = date.add(dtA, interv, -1);
+	t.is(date.difference(dtA, dtB, interv), -1);
 },
 function test_date_add_diff_weekday(t){
 	var interv = ''; // Interval (e.g., year, month)
@@ -597,50 +597,50 @@ function test_date_add_diff_weekday(t){
 	// Sat, Jan 1
 	dtA = new Date(2000, 0, 1);
 	// Should be Mon, Jan 3
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	// Sun, Jan 2
 	dtA = new Date(2000, 0, 2);
 	// Should be Mon, Jan 3
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	// Sun, Jan 2
 	dtA = new Date(2000, 0, 2);
 	// Should be Fri, Jan 7
-	dtB = dojo.date.add(dtA, interv, 5);
-	t.is(dojo.date.difference(dtA, dtB, interv), 5);
+	dtB = date.add(dtA, interv, 5);
+	t.is(date.difference(dtA, dtB, interv), 5);
 
 	// Sun, Jan 2
 	dtA = new Date(2000, 0, 2);
 	// Should be Mon, Jan 10
-	dtB = dojo.date.add(dtA, interv, 6);
-	t.is(dojo.date.difference(dtA, dtB, interv), 6);
+	dtB = date.add(dtA, interv, 6);
+	t.is(date.difference(dtA, dtB, interv), 6);
 
 	// Mon, Jan 3
 	dtA = new Date(2000, 0, 3);
 	// Should be Mon, Jan 17
-	dtB = dojo.date.add(dtA, interv, 10);
-	t.is(dojo.date.difference(dtA, dtB, interv), 10);
+	dtB = date.add(dtA, interv, 10);
+	t.is(date.difference(dtA, dtB, interv), 10);
 
 	// Sat, Jan 8
 	dtA = new Date(2000, 0, 8);
 	// Should be Mon, Jan 3
-	dtB = dojo.date.add(dtA, interv, -5);
-	t.is(dojo.date.difference(dtA, dtB, interv), -5);
+	dtB = date.add(dtA, interv, -5);
+	t.is(date.difference(dtA, dtB, interv), -5);
 
 	// Sun, Jan 9
 	dtA = new Date(2000, 0, 9);
 	// Should be Wed, Jan 5
-	dtB = dojo.date.add(dtA, interv, -3);
-	t.is(dojo.date.difference(dtA, dtB, interv), -3);
+	dtB = date.add(dtA, interv, -3);
+	t.is(date.difference(dtA, dtB, interv), -3);
 
 	// Sun, Jan 23
 	dtA = new Date(2000, 0, 23);
 	// Should be Fri, Jan 7
-	dtB = dojo.date.add(dtA, interv, -11);
-	t.is(dojo.date.difference(dtA, dtB, interv), -11);
+	dtB = date.add(dtA, interv, -11);
+	t.is(date.difference(dtA, dtB, interv), -11);
 },
 function test_date_add_diff_hour(t){
 	var interv = ''; // Interval (e.g., year, month)
@@ -648,20 +648,20 @@ function test_date_add_diff_hour(t){
 	var dtB = null; // Expected result date
 	interv = "hour";
 	dtA = new Date(2000, 0, 1, 11);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2001, 9, 28, 0);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2001, 9, 28, 23);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2001, 11, 31, 23);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 },
 function test_date_add_diff_minute(t){
 	var interv = ''; // Interval (e.g., year, month)
@@ -669,12 +669,12 @@ function test_date_add_diff_minute(t){
 	var dtB = null; // Expected result date
 	interv = "minute";
 	dtA = new Date(2000, 11, 31, 23, 59);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2000, 11, 27, 12, 2);
-	dtB = dojo.date.add(dtA, interv, 60);
-	t.is(dojo.date.difference(dtA, dtB, interv), 60);
+	dtB = date.add(dtA, interv, 60);
+	t.is(date.difference(dtA, dtB, interv), 60);
 },
 function test_date_add_diff_second(t){
 	var interv = ''; // Interval (e.g., year, month)
@@ -683,23 +683,23 @@ function test_date_add_diff_second(t){
 	console.debug("second");
 	interv = "second";
 	dtA = new Date(2000, 11, 31, 23, 59, 59);
-	dtB = dojo.date.add(dtA, interv, 1);
-	t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	dtB = date.add(dtA, interv, 1);
+	t.is(date.difference(dtA, dtB, interv), 1);
 
 	dtA = new Date(2000, 11, 27, 8, 10, 59);
-	dtB = dojo.date.add(dtA, interv, 60);
-	t.is(dojo.date.difference(dtA, dtB, interv), 60);
+	dtB = date.add(dtA, interv, 60);
+	t.is(date.difference(dtA, dtB, interv), 60);
 
 	// Test environment JS Date doesn't support millisec?
 	//interv = "millisecond";
 	//
 	//dtA = new Date(2000, 11, 31, 23, 59, 59, 999);
-	//dtB = dojo.date.add(dtA, interv, 1);
-	//t.is(dojo.date.difference(dtA, dtB, interv), 1);
+	//dtB = date.add(dtA, interv, 1);
+	//t.is(date.difference(dtA, dtB, interv), 1);
 	//
 	//dtA = new Date(2000, 11, 27, 8, 10, 53, 2);
-	//dtB = dojo.date.add(dtA, interv, 1000);
-	//t.is(dojo.date.difference(dtA, dtB, interv), 1000);
+	//dtB = date.add(dtA, interv, 1000);
+	//t.is(date.difference(dtA, dtB, interv), 1000);
 }
 	]
 );
diff --git a/dojo/tests/date/locale.js b/dojo/tests/date/locale.js
index d6d6532..aae4023 100644
--- a/dojo/tests/date/locale.js
+++ b/dojo/tests/date/locale.js
@@ -1,9 +1,7 @@
-dojo.provide("dojo.tests.date.locale");
+define(["doh", "dojo/_base/array", "dojo/i18n", "dojo/_base/kernel", "dojo/date", "dojo/date/locale"],
+	function(doh, array, i18n, kernel, date, locale){
 
-dojo.require("dojo.date.locale");
-
-tests.register("tests.date.locale",
-	[
+	doh.register("tests.date.locale", [
 		{
 			// Test formatting and parsing of dates in various locales pre-built in dojo.cldr
 			// NOTE: we can't set djConfig.extraLocale before bootstrapping unit tests, so directly
@@ -12,17 +10,17 @@ tests.register("tests.date.locale",
 			name: "date.locale",
 			runTest: function(t){
 				var partLocaleList = ["en-us", "fr-fr", "es", "de-at", "ja-jp", "zh-cn"];
-				if(dojo.isAsync){
+				if(kernel.isAsync){
 					var def = new doh.Deferred(),
-						deps = dojo.map(partLocaleList, function(locale){
-							return dojo.getL10nName("dojo/cldr", "gregorian", locale)
+						deps = array.map(partLocaleList, function(locale){
+							return i18n.getL10nName("dojo/cldr", "gregorian", locale);
 						});
 					require(deps, function(){
 						def.callback(true);
 					});
 					return def;
 				}else{ // tests for the v1.x loader/i18n machinery
-					dojo.forEach(partLocaleList, function(locale){
+					array.forEach(partLocaleList, function(locale){
 						dojo.requireLocalization("dojo.cldr", "gregorian", locale);
 					});
 				}
@@ -41,15 +39,15 @@ tests.register("tests.date.locale",
 				var saturday = new Date(2006, 8, 23);
 				var sunday = new Date(2006, 8, 24);
 				var monday = new Date(2006, 8, 25);
-				t.f(dojo.date.locale.isWeekend(thursday, 'en-us'));
-				t.t(dojo.date.locale.isWeekend(saturday, 'en-us'));
-				t.t(dojo.date.locale.isWeekend(sunday, 'en-us'));
-				t.f(dojo.date.locale.isWeekend(monday, 'en-us'));
-//	t.f(dojo.date.locale.isWeekend(saturday, 'en-in'));
-//	t.t(dojo.date.locale.isWeekend(sunday, 'en-in'));
-//	t.f(dojo.date.locale.isWeekend(monday, 'en-in'));
-//	t.t(dojo.date.locale.isWeekend(friday, 'he-il'));
-//	t.f(dojo.date.locale.isWeekend(sunday, 'he-il'));
+				t.f(locale.isWeekend(thursday, 'en-us'));
+				t.t(locale.isWeekend(saturday, 'en-us'));
+				t.t(locale.isWeekend(sunday, 'en-us'));
+				t.f(locale.isWeekend(monday, 'en-us'));
+//	t.f(locale.isWeekend(saturday, 'en-in'));
+//	t.t(locale.isWeekend(sunday, 'en-in'));
+//	t.f(locale.isWeekend(monday, 'en-in'));
+//	t.t(locale.isWeekend(friday, 'he-il'));
+//	t.f(locale.isWeekend(sunday, 'he-il'));
 			}
 		},
 		{
@@ -58,33 +56,33 @@ tests.register("tests.date.locale",
 
 	var date = new Date(2006, 7, 11, 0, 55, 12, 345);
 
-	t.is("Friday, August 11, 2006", dojo.date.locale.format(date, {formatLength:'full',selector:'date', locale:'en-us'}));
-	t.is("vendredi 11 ao\xFBt 2006", dojo.date.locale.format(date, {formatLength:'full',selector:'date', locale:'fr-fr'}));
-	t.is("Freitag, 11. August 2006", dojo.date.locale.format(date, {formatLength:'full',selector:'date', locale:'de-at'}));
-	t.is("2006\u5E748\u670811\u65E5\u91D1\u66DC\u65E5", dojo.date.locale.format(date, {formatLength:'full',selector:'date', locale:'ja-jp'}));
+	t.is("Friday, August 11, 2006", locale.format(date, {formatLength:'full',selector:'date', locale:'en-us'}));
+	t.is("vendredi 11 ao\xFBt 2006", locale.format(date, {formatLength:'full',selector:'date', locale:'fr-fr'}));
+	t.is("Freitag, 11. August 2006", locale.format(date, {formatLength:'full',selector:'date', locale:'de-at'}));
+	t.is("2006\u5E748\u670811\u65E5\u91D1\u66DC\u65E5", locale.format(date, {formatLength:'full',selector:'date', locale:'ja-jp'}));
 
-	t.is("8/11/06", dojo.date.locale.format(date, {formatLength:'short',selector:'date', locale:'en-us'}));
-	t.is("11/08/06", dojo.date.locale.format(date, {formatLength:'short',selector:'date', locale:'fr-fr'}));
-	t.is("11.08.06", dojo.date.locale.format(date, {formatLength:'short',selector:'date', locale:'de-at'}));
-	t.is("06/08/11", dojo.date.locale.format(date, {formatLength:'short',selector:'date', locale:'ja-jp'}));
+	t.is("8/11/06", locale.format(date, {formatLength:'short',selector:'date', locale:'en-us'}));
+	t.is("11/08/2006", locale.format(date, {formatLength:'short',selector:'date', locale:'fr-fr'}));
+	t.is("11.08.06", locale.format(date, {formatLength:'short',selector:'date', locale:'de-at'}));
+	t.is("2006/08/11", locale.format(date, {formatLength:'short',selector:'date', locale:'ja-jp'}));
 
-	t.is("6", dojo.date.locale.format(date, {datePattern:'E', selector:'date'}));
+	t.is("6", locale.format(date, {datePattern:'E', selector:'date'}));
 
-	t.is("12:55 AM", dojo.date.locale.format(date, {formatLength:'short',selector:'time', locale:'en-us'}));
-	t.is("12:55:12", dojo.date.locale.format(date, {timePattern:'h:m:s',selector:'time'}));
-	t.is("12:55:12.35", dojo.date.locale.format(date, {timePattern:'h:m:s.SS',selector:'time'}));
-	t.is("24:55:12.35", dojo.date.locale.format(date, {timePattern:'k:m:s.SS',selector:'time'}));
-	t.is("0:55:12.35", dojo.date.locale.format(date, {timePattern:'H:m:s.SS',selector:'time'}));
-	t.is("0:55:12.35", dojo.date.locale.format(date, {timePattern:'K:m:s.SS',selector:'time'}));
+	t.is("12:55 AM", locale.format(date, {formatLength:'short',selector:'time', locale:'en-us'}));
+	t.is("12:55:12", locale.format(date, {timePattern:'h:m:s',selector:'time'}));
+	t.is("12:55:12.35", locale.format(date, {timePattern:'h:m:s.SS',selector:'time'}));
+	t.is("24:55:12.35", locale.format(date, {timePattern:'k:m:s.SS',selector:'time'}));
+	t.is("0:55:12.35", locale.format(date, {timePattern:'H:m:s.SS',selector:'time'}));
+	t.is("0:55:12.35", locale.format(date, {timePattern:'K:m:s.SS',selector:'time'}));
 
-	t.is("11082006", dojo.date.locale.format(date, {datePattern:"ddMMyyyy", selector:"date"}));
+	t.is("11082006", locale.format(date, {datePattern:"ddMMyyyy", selector:"date"}));
 
-	t.is("12 o'clock AM", dojo.date.locale.format(date, {datePattern:"hh 'o''clock' a", selector:"date", locale: 'en'}));
+	t.is("12 o'clock AM", locale.format(date, {datePattern:"hh 'o''clock' a", selector:"date", locale: 'en'}));
 
-	t.is("11/08/2006 12:55am", dojo.date.locale.format(date, {datePattern:"dd/MM/yyyy", timePattern:"hh:mma", locale: 'en', am:"am", pm:"pm"}));
+	t.is("11/08/2006, 12:55am", locale.format(date, {datePattern:"dd/MM/yyyy", timePattern:"hh:mma", locale: 'en', am:"am", pm:"pm"}));
 
 	// compare without timezone
-	t.is("\u4e0a\u534812\u65f655\u520612\u79d2", dojo.date.locale.format(date, {formatLength:'full',selector:'time', locale:'zh-cn'}).replace(/^.*(\u4e0a\u5348.*)/,"$1"));
+	t.is("\u4e0a\u534812:55:12", locale.format(date, {formatLength:'full',selector:'time', locale:'zh-cn'}).replace(/^.*(\u4e0a\u5348.*)/,"$1"));
 			}
 		},
 		{
@@ -95,87 +93,87 @@ tests.register("tests.date.locale",
 
 	//en: 'short' fmt: M/d/yy
 	// Tolerate either 8 or 08 for month part.
-	t.is( aug_11_2006, dojo.date.locale.parse("08/11/06", {formatLength:'short', selector:'date', locale:'en'}));
-	t.is( aug_11_2006, dojo.date.locale.parse("8/11/06", {formatLength:'short', selector:'date', locale:'en'}));
+	t.is( aug_11_2006, locale.parse("08/11/06", {formatLength:'short', selector:'date', locale:'en'}));
+	t.is( aug_11_2006, locale.parse("8/11/06", {formatLength:'short', selector:'date', locale:'en'}));
 	// Tolerate yyyy input in yy part...
-	t.is( aug_11_2006, dojo.date.locale.parse("8/11/2006", {formatLength:'short', selector:'date', locale:'en'}));
+	t.is( aug_11_2006, locale.parse("8/11/2006", {formatLength:'short', selector:'date', locale:'en'}));
 	// ...but not in strict mode
-	t.f( Boolean(dojo.date.locale.parse("8/11/2006", {formatLength:'short', selector:'date', locale:'en', strict:true})));
+	t.f( Boolean(locale.parse("8/11/2006", {formatLength:'short', selector:'date', locale:'en', strict:true})));
 
 	// test dates with no spaces
-	t.is( aug_11_2006, dojo.date.locale.parse("11Aug2006", {selector: 'date', datePattern: 'ddMMMyyyy', locale: 'en'}));
-	t.is( new Date(2006, 7, 1), dojo.date.locale.parse("Aug2006", {selector: 'date', datePattern: 'MMMyyyy', locale: 'en'}));
-	t.is( new Date(2010, 10, 19), dojo.date.locale.parse("111910", {fullyear: false, datePattern: "MMddyy", selector: "date"}));
+	t.is( aug_11_2006, locale.parse("11Aug2006", {selector: 'date', datePattern: 'ddMMMyyyy', locale: 'en'}));
+	t.is( new Date(2006, 7, 1), locale.parse("Aug2006", {selector: 'date', datePattern: 'MMMyyyy', locale: 'en'}));
+	t.is( new Date(2010, 10, 19), locale.parse("111910", {fullyear: false, datePattern: "MMddyy", selector: "date"}));
 
 	//en: 'medium' fmt: MMM d, yyyy
 	// Tolerate either 8 or 08 for month part.
-	t.is( aug_11_2006, dojo.date.locale.parse("Aug 11, 2006", {formatLength:'medium', selector:'date', locale:'en'}));
-	t.is( aug_11_2006, dojo.date.locale.parse("Aug 11, 2006", {formatLength:'medium', selector:'date', locale:'en'}));
+	t.is( aug_11_2006, locale.parse("Aug 11, 2006", {formatLength:'medium', selector:'date', locale:'en'}));
+	t.is( aug_11_2006, locale.parse("Aug 11, 2006", {formatLength:'medium', selector:'date', locale:'en'}));
 	// Tolerate abbreviating period in month part...
-	t.is( aug_11_2006, dojo.date.locale.parse("Aug. 11, 2006", {formatLength:'medium', selector:'date', locale:'en'}));
+	t.is( aug_11_2006, locale.parse("Aug. 11, 2006", {formatLength:'medium', selector:'date', locale:'en'}));
 	// ...but not in strict mode
-	t.f( Boolean(dojo.date.locale.parse("Aug. 11, 2006", {formatLength:'medium', selector:'date', locale:'en', strict:true})));
+	t.f( Boolean(locale.parse("Aug. 11, 2006", {formatLength:'medium', selector:'date', locale:'en', strict:true})));
 
 	// Note: 06 for year part will be translated literally as the year 6 C.E.
 	var aug_11_06CE = new Date(2006, 7, 11, 0);
 	aug_11_06CE.setFullYear(6); //literally the year 6 C.E.
-	t.is( aug_11_06CE, dojo.date.locale.parse("Aug 11, 06", {selector:'date', datePattern:'MMM dd, yyyy', locale: 'en', strict:true}));
+	t.is( aug_11_06CE, locale.parse("Aug 11, 06", {selector:'date', datePattern:'MMM dd, yyyy', locale: 'en', strict:true}));
 
 	//en: 'long' fmt: MMMM d, yyyy
-	t.is( aug_11_2006, dojo.date.locale.parse("August 11, 2006", {formatLength:'long', selector:'date', locale:'en'}));
+	t.is( aug_11_2006, locale.parse("August 11, 2006", {formatLength:'long', selector:'date', locale:'en'}));
 
 	//en: 'full' fmt: EEEE, MMMM d, yyyy
-	t.is( aug_11_2006, dojo.date.locale.parse("Friday, August 11, 2006", {formatLength:'full', selector:'date', locale:'en'}));
+	t.is( aug_11_2006, locale.parse("Friday, August 11, 2006", {formatLength:'full', selector:'date', locale:'en'}));
 	//TODO: wrong day-of-week should fail
-	//t.f( Boolean(dojo.date.locale.parse("Thursday, August 11, 2006", {formatLength:'full', selector:'date', locale:'en'})));
+	//t.f( Boolean(locale.parse("Thursday, August 11, 2006", {formatLength:'full', selector:'date', locale:'en'})));
 	//TODO: Whitespace tolerance
-	//	t.is( aug_11_2006, dojo.date.locale.parse(" August 11, 2006", {formatLength:'long', selector:'date', locale:'en'}));
-	//	t.is( aug_11_2006, dojo.date.locale.parse("August  11, 2006", {formatLength:'long', selector:'date', locale:'en'}));
-	//	t.is( aug_11_2006, dojo.date.locale.parse("August 11 , 2006", {formatLength:'long', selector:'date', locale:'en'}));
-	//	t.is( aug_11_2006, dojo.date.locale.parse("August 11,  2006", {formatLength:'long', selector:'date', locale:'en'}));
-	//	t.is( aug_11_2006, dojo.date.locale.parse("August 11, 2006 ", {formatLength:'long', selector:'date', locale:'en'}));
+	//	t.is( aug_11_2006, locale.parse(" August 11, 2006", {formatLength:'long', selector:'date', locale:'en'}));
+	//	t.is( aug_11_2006, locale.parse("August  11, 2006", {formatLength:'long', selector:'date', locale:'en'}));
+	//	t.is( aug_11_2006, locale.parse("August 11 , 2006", {formatLength:'long', selector:'date', locale:'en'}));
+	//	t.is( aug_11_2006, locale.parse("August 11,  2006", {formatLength:'long', selector:'date', locale:'en'}));
+	//	t.is( aug_11_2006, locale.parse("August 11, 2006 ", {formatLength:'long', selector:'date', locale:'en'}));
 
 	//Simple Validation Tests
 	//catch "month" > 12 (note: month/day reversals are common when user expectation isn't met wrt european versus US formats)
-	t.f( Boolean(dojo.date.locale.parse("15/1/2005", {formatLength:'short', selector:'date', locale:'en'})));
+	t.f( Boolean(locale.parse("15/1/2005", {formatLength:'short', selector:'date', locale:'en'})));
 	//day of month typo rolls over to the next month
-	t.f( Boolean(dojo.date.locale.parse("Aug 32, 2006", {formatLength:'medium', selector:'date', locale:'en'})));
+	t.f( Boolean(locale.parse("Aug 32, 2006", {formatLength:'medium', selector:'date', locale:'en'})));
 
 	//German (de)
-	t.is( aug_11_2006, dojo.date.locale.parse("11.08.06", {formatLength:'short', selector:'date', locale:'de'}));
-	t.f( Boolean(dojo.date.locale.parse("11.8/06", {formatLength:'short', selector:'date', locale:'de'})));
-	t.f( Boolean(dojo.date.locale.parse("11.8x06", {formatLength:'short', selector:'date', locale:'de'})));
-	t.f( Boolean(dojo.date.locale.parse("11.13.06", {formatLength:'short', selector:'date', locale:'de'})));
-	t.f( Boolean(dojo.date.locale.parse("11.0.06", {formatLength:'short', selector:'date', locale:'de'})));
-	t.f( Boolean(dojo.date.locale.parse("32.08.06", {formatLength:'short', selector:'date', locale:'de'})));
+	t.is( aug_11_2006, locale.parse("11.08.06", {formatLength:'short', selector:'date', locale:'de'}));
+	t.f( Boolean(locale.parse("11.8/06", {formatLength:'short', selector:'date', locale:'de'})));
+	t.f( Boolean(locale.parse("11.8x06", {formatLength:'short', selector:'date', locale:'de'})));
+	t.f( Boolean(locale.parse("11.13.06", {formatLength:'short', selector:'date', locale:'de'})));
+	t.f( Boolean(locale.parse("11.0.06", {formatLength:'short', selector:'date', locale:'de'})));
+	t.f( Boolean(locale.parse("32.08.06", {formatLength:'short', selector:'date', locale:'de'})));
 
 	//Spanish (es)
 	//es: 'short' fmt: d/MM/yy
-	t.is( aug_11_2006, dojo.date.locale.parse("11/08/06", {formatLength:'short', selector:'date', locale:'es'}));
-	t.is( aug_11_2006, dojo.date.locale.parse("11/8/06", {formatLength:'short', selector:'date', locale:'es'}));
+	t.is( aug_11_2006, locale.parse("11/08/06", {formatLength:'short', selector:'date', locale:'es'}));
+	t.is( aug_11_2006, locale.parse("11/8/06", {formatLength:'short', selector:'date', locale:'es'}));
 	// Tolerate yyyy input in yy part...
-	t.is( aug_11_2006, dojo.date.locale.parse("11/8/2006", {formatLength:'short', selector:'date', locale:'es'}));
+	t.is( aug_11_2006, locale.parse("11/8/2006", {formatLength:'short', selector:'date', locale:'es'}));
 	// ...but not in strict mode
-	t.f( Boolean(dojo.date.locale.parse("11/8/2006", {formatLength:'short', selector:'date', locale:'es', strict:true})));
+	t.f( Boolean(locale.parse("11/8/2006", {formatLength:'short', selector:'date', locale:'es', strict:true})));
 	//es: 'medium' fmt: dd-MMM-yy (not anymore as of CLDR 1.5.1)
-//	t.is( aug_11_2006, dojo.date.locale.parse("11-ago-06", {formatLength:'medium', selector:'date', locale:'es'}));
-//	t.is( aug_11_2006, dojo.date.locale.parse("11-ago-2006", {formatLength:'medium', selector:'date', locale:'es'}));
+//	t.is( aug_11_2006, locale.parse("11-ago-06", {formatLength:'medium', selector:'date', locale:'es'}));
+//	t.is( aug_11_2006, locale.parse("11-ago-2006", {formatLength:'medium', selector:'date', locale:'es'}));
 	// Tolerate abbreviating period in month part...
-//	t.is( aug_11_2006, dojo.date.locale.parse("11-ago.-2006", {formatLength:'medium', selector:'date', locale:'es'}));
+//	t.is( aug_11_2006, locale.parse("11-ago.-2006", {formatLength:'medium', selector:'date', locale:'es'}));
 	// ...but not in strict mode
-//	t.f( Boolean(dojo.date.locale.parse("11-ago.-2006", {formatLength:'medium', selector:'date', locale:'es', strict:true})));
+//	t.f( Boolean(locale.parse("11-ago.-2006", {formatLength:'medium', selector:'date', locale:'es', strict:true})));
 	//es: 'long' fmt: d' de 'MMMM' de 'yyyy
-	t.is( aug_11_2006, dojo.date.locale.parse("11 de agosto de 2006", {formatLength:'long', selector:'date', locale:'es'}));
+	t.is( aug_11_2006, locale.parse("11 de agosto de 2006", {formatLength:'long', selector:'date', locale:'es'}));
 	//case-insensitive month...
-	t.is( aug_11_2006, dojo.date.locale.parse("11 de Agosto de 2006", {formatLength:'long', selector:'date', locale:'es'}));
+	t.is( aug_11_2006, locale.parse("11 de Agosto de 2006", {formatLength:'long', selector:'date', locale:'es'}));
 	//...but not in strict mode
-	t.f( Boolean(dojo.date.locale.parse("11 de Agosto de 2006", {formatLength:'long', selector:'date', locale:'es', strict:true})));
+	t.f( Boolean(locale.parse("11 de Agosto de 2006", {formatLength:'long', selector:'date', locale:'es', strict:true})));
 	//es 'full' fmt: EEEE d' de 'MMMM' de 'yyyy
-	t.is( aug_11_2006, dojo.date.locale.parse("viernes 11 de agosto de 2006", {formatLength:'full', selector:'date', locale:'es'}));
+	t.is( aug_11_2006, locale.parse("viernes, 11 de agosto de 2006", {formatLength:'full', selector:'date', locale:'es'}));
 	//case-insensitive day-of-week...
-	t.is( aug_11_2006, dojo.date.locale.parse("Viernes 11 de agosto de 2006", {formatLength:'full', selector:'date', locale:'es'}));
+	t.is( aug_11_2006, locale.parse("Viernes, 11 de agosto de 2006", {formatLength:'full', selector:'date', locale:'es'}));
 	//...but not in strict mode
-	t.f( Boolean(dojo.date.locale.parse("Viernes 11 de agosto de 2006", {formatLength:'full', selector:'date', locale:'es', strict:true})));
+	t.f( Boolean(locale.parse("Viernes, 11 de agosto de 2006", {formatLength:'full', selector:'date', locale:'es', strict:true})));
 
 	//Japanese (ja)
 	//note: to avoid garbling from non-utf8-aware editors that may touch this file, using the \uNNNN format
@@ -187,43 +185,43 @@ tests.register("tests.date.locale",
 	//zenkaku space: \u3000
 
 	//ja: 'short' fmt: yy/MM/dd (note: the "short" fmt isn't actually defined in the CLDR data...)
-	t.is( aug_11_2006, dojo.date.locale.parse("06/08/11", {formatLength:'short', selector:'date', locale:'ja'}));
-	t.is( aug_11_2006, dojo.date.locale.parse("06/8/11", {formatLength:'short', selector:'date', locale:'ja'}));
+	t.is( aug_11_2006, locale.parse("06/08/11", {formatLength:'short', selector:'date', locale:'ja'}));
+	t.is( aug_11_2006, locale.parse("06/8/11", {formatLength:'short', selector:'date', locale:'ja'}));
  	// Tolerate yyyy input in yy part...
-	t.is( aug_11_2006, dojo.date.locale.parse("2006/8/11", {formatLength:'short', selector:'date', locale:'ja'}));
+	t.is( aug_11_2006, locale.parse("2006/8/11", {formatLength:'short', selector:'date', locale:'ja'}));
 	// ...but not in strict mode
-	t.f( Boolean(dojo.date.locale.parse("2006/8/11", {formatLength:'short', selector:'date', locale:'ja', strict:true})));
+	t.f( Boolean(locale.parse("2006/8/11", {formatLength:'short', selector:'date', locale:'ja', strict:true})));
 	//ja: 'medium' fmt: yyyy/MM/dd
-	t.is( aug_11_2006, dojo.date.locale.parse("2006/08/11", {formatLength:'medium', selector:'date', locale:'ja'}));
-	t.is( aug_11_2006, dojo.date.locale.parse("2006/8/11", {formatLength:'medium', selector:'date', locale:'ja'}));
+	t.is( aug_11_2006, locale.parse("2006/08/11", {formatLength:'medium', selector:'date', locale:'ja'}));
+	t.is( aug_11_2006, locale.parse("2006/8/11", {formatLength:'medium', selector:'date', locale:'ja'}));
 	//ja: 'long' fmt: yyyy'\u5e74'\u6708'd'\u65e5'
-	t.is( aug_11_2006, dojo.date.locale.parse("2006\u5e748\u670811\u65e5", {formatLength:'long', selector:'date', locale:'ja'}));
+	t.is( aug_11_2006, locale.parse("2006\u5e748\u670811\u65e5", {formatLength:'long', selector:'date', locale:'ja'}));
 	//ja 'full' fmt: yyyy'\u5e74'M'\u6708'd'\u65e5'EEEE
-	t.is( aug_11_2006, dojo.date.locale.parse("2006\u5e748\u670811\u65e5\u91d1\u66dc\u65e5", {formatLength:'full', selector:'date', locale:'ja'}));
+	t.is( aug_11_2006, locale.parse("2006\u5e748\u670811\u65e5\u91d1\u66dc\u65e5", {formatLength:'full', selector:'date', locale:'ja'}));
 
 	//TODO: Whitespace tolerance
 	//tolerate ascii space
-	//	t.is( aug_11_2006, dojo.date.locale.parse(" 2006\u5e748\u670811\u65e5\u91d1\u66dc\u65e5 ", {formatLength:'full', selector:'date', locale:'ja'}));
-	//	t.is( aug_11_2006, dojo.date.locale.parse("2006\u5e74 8\u670811\u65e5 \u91d1\u66dc\u65e5", {formatLength:'full', selector:'date', locale:'ja'}));
+	//	t.is( aug_11_2006, locale.parse(" 2006\u5e748\u670811\u65e5\u91d1\u66dc\u65e5 ", {formatLength:'full', selector:'date', locale:'ja'}));
+	//	t.is( aug_11_2006, locale.parse("2006\u5e74 8\u670811\u65e5 \u91d1\u66dc\u65e5", {formatLength:'full', selector:'date', locale:'ja'}));
 	//tolerate zenkaku space
-	//	t.is( aug_11_2006, dojo.date.locale.parse("\u30002006\u5e748\u670811\u65e5\u91d1\u66dc\u65e5\u3000", {formatLength:'full', selector:'date', locale:'ja'}));
-	//	t.is( aug_11_2006, dojo.date.locale.parse("2006\u5e74\u30008\u670811\u65e5\u3000\u91d1\u66dc\u65e5", {formatLength:'full', selector:'date', locale:'ja'}));
+	//	t.is( aug_11_2006, locale.parse("\u30002006\u5e748\u670811\u65e5\u91d1\u66dc\u65e5\u3000", {formatLength:'full', selector:'date', locale:'ja'}));
+	//	t.is( aug_11_2006, locale.parse("2006\u5e74\u30008\u670811\u65e5\u3000\u91d1\u66dc\u65e5", {formatLength:'full', selector:'date', locale:'ja'}));
 
 	var apr_11_2006 = new Date(2006, 3, 11, 0);
 	//Roundtrip
 	var options={formatLength:'medium',selector:'date', locale:'fr-fr'};
-	t.is(0, dojo.date.compare(apr_11_2006, dojo.date.locale.parse(dojo.date.locale.format(apr_11_2006, options), options)));
+	t.is(0, date.compare(apr_11_2006, locale.parse(locale.format(apr_11_2006, options), options)));
 
 	//Tolerance for abbreviations
-	t.is(0, dojo.date.compare(apr_11_2006, dojo.date.locale.parse("11 avr 06", options)));
+	t.is(0, date.compare(apr_11_2006, locale.parse("11 avr 06", options)));
 			}
 		},
 		{
 			name: "parse_dates_neg",
 			runTest: function(t){
-				t.f(Boolean(dojo.date.locale.parse("2/29/2007", {formatLength: 'short', selector: 'date', locale: 'en'})));
-				t.f(Boolean(dojo.date.locale.parse("4/31/2007", {formatLength: 'short', selector: 'date', locale: 'en'})));
-				t.f(Boolean(dojo.date.locale.parse("Decemb 30, 2007", {formatLength: 'long', selector: 'date', locale: 'en'})));
+				t.f(Boolean(locale.parse("2/29/2007", {formatLength: 'short', selector: 'date', locale: 'en'})));
+				t.f(Boolean(locale.parse("4/31/2007", {formatLength: 'short', selector: 'date', locale: 'en'})));
+				t.f(Boolean(locale.parse("Decemb 30, 2007", {formatLength: 'long', selector: 'date', locale: 'en'})));
 			}
 		},
 		{
@@ -236,21 +234,24 @@ tests.register("tests.date.locale",
 	//en: 'short' datetime fmt: M/d/yy h:mm a
 	//note: this is concatenation of dateFormat-short and timeFormat-short,
 	//cldr provisionally defines datetime fmts as well, but we're not using them at the moment
-	t.is( aug_11_2006_12_30_pm, dojo.date.locale.parse("08/11/06 12:30 PM", {formatLength:'short', locale:'en'}));
+	t.is( aug_11_2006_12_30_pm, locale.parse("08/11/06, 12:30 PM", {formatLength:'short', locale:'en'}), 'PM');
 	//case-insensitive
-	t.is( aug_11_2006_12_30_pm, dojo.date.locale.parse("08/11/06 12:30 pm", {formatLength:'short', locale:'en'}));
+	t.is( aug_11_2006_12_30_pm, locale.parse("08/11/06, 12:30 pm", {formatLength:'short', locale:'en'}), 'pm');
 	//...but not in strict mode
-	t.f( Boolean(dojo.date.locale.parse("08/11/06 12:30 pm", {formatLength:'short', locale:'en', strict:true})));
+	t.f( Boolean(locale.parse("8/11/06, 12:30 pm", {formatLength:'short', locale:'en', strict:true})), 'strict fail');
+	t.t( Boolean(locale.parse("8/11/06, 12:30 PM", {formatLength:'short', locale:'en', strict:true})), 'strict pass');
+
+	t.is( aug_11_2006_12_30_am, locale.parse("08/11/06, 12:30 AM", {formatLength:'short', locale:'en'}), 'AM');
 
-	t.is( aug_11_2006_12_30_am, dojo.date.locale.parse("08/11/06 12:30 AM", {formatLength:'short', locale:'en'}));
+	t.is( new Date(2006, 7, 11), locale.parse("11082006", {datePattern:"ddMMyyyy", selector:"date"}));
 
-	t.is( new Date(2006, 7, 11), dojo.date.locale.parse("11082006", {datePattern:"ddMMyyyy", selector:"date"}));
+	t.is( new Date(2006, 7, 31), locale.parse("31Aug2006", {datePattern:"ddMMMyyyy", selector:"date", locale:'en'}));
 
-	t.is( new Date(2006, 7, 31), dojo.date.locale.parse("31Aug2006", {datePattern:"ddMMMyyyy", selector:"date", locale:'en'}));
+	t.is(new Date(1970,0,7), locale.parse("007", {datePattern:'DDD',selector:'date'}));
+	t.is(new Date(1970,0,31), locale.parse("031", {datePattern:'DDD',selector:'date'}));
+	t.is(new Date(1970,3,10), locale.parse("100", {datePattern:'DDD',selector:'date'}));
 
-	t.is(new Date(1970,0,7), dojo.date.locale.parse("007", {datePattern:'DDD',selector:'date'}));
-	t.is(new Date(1970,0,31), dojo.date.locale.parse("031", {datePattern:'DDD',selector:'date'}));
-	t.is(new Date(1970,3,10), dojo.date.locale.parse("100", {datePattern:'DDD',selector:'date'}));
+				t.isNot(null, locale.parse(locale.format(new Date(), {locale:'he', formatLength:'full', selector:'date'}), {locale:'he', formatLength:'full', selector:'date'}), "Hebrew parse");
 
 			}
 		},
@@ -260,8 +261,8 @@ tests.register("tests.date.locale",
 				var time = new Date(2006, 7, 11, 12, 30);
 				var tformat = {selector:'time', strict:true, timePattern:"h:mm a", locale:'en'};
 
-				t.is(time.getHours(), dojo.date.locale.parse("12:30 PM", tformat).getHours());
-				t.is(time.getMinutes(), dojo.date.locale.parse("12:30 PM", tformat).getMinutes());
+				t.is(time.getHours(), locale.parse("12:30 PM", tformat).getHours());
+				t.is(time.getMinutes(), locale.parse("12:30 PM", tformat).getMinutes());
 			}
 		},
 		{
@@ -269,13 +270,13 @@ tests.register("tests.date.locale",
 			runTest: function(t){
 				var time = new Date(2006, 7, 11, 12, 30);
 				var tformat = {selector:'time', strict:true, timePattern:"h 'o''clock'", locale:'en'};
-				t.is(time.getHours(), dojo.date.locale.parse("12 o'clock", tformat).getHours());
+				t.is(time.getHours(), locale.parse("12 o'clock", tformat).getHours());
 
 				tformat = {selector:'time', strict:true, timePattern:" 'Hour is' h", locale:'en'};
-				t.is(time.getHours(), dojo.date.locale.parse(" Hour is 12", tformat).getHours());
+				t.is(time.getHours(), locale.parse(" Hour is 12", tformat).getHours());
 
 				tformat = {selector:'time', strict:true, timePattern:"'Hour is' h", locale:'en'};
-				t.is(time.getHours(), dojo.date.locale.parse("Hour is 12", tformat).getHours());
+				t.is(time.getHours(), locale.parse("Hour is 12", tformat).getHours());
 			}
 		},
 		{
@@ -283,39 +284,38 @@ tests.register("tests.date.locale",
 			runTest: function(t){
 				var time = new Date(2006, 7, 11, 12, 30);
 				var tformat = {selector:'time', strict:true, timePattern:"h 'o''clock'", locale:'en'};
-				t.is(time.getHours(), dojo.date.locale.parse("12 o'clock", tformat).getHours());
+				t.is(time.getHours(), locale.parse("12 o'clock", tformat).getHours());
 
 				tformat = {selector:'time', strict:true, timePattern:" 'Hour is' h", locale:'en'};
-				t.is(time.getHours(), dojo.date.locale.parse(" Hour is 12", tformat).getHours());
+				t.is(time.getHours(), locale.parse(" Hour is 12", tformat).getHours());
 				tformat = {selector:'time', strict:true, timePattern:"'Hour is' h", locale:'en'};
-				t.is(time.getHours(), dojo.date.locale.parse("Hour is 12", tformat).getHours());
+				t.is(time.getHours(), locale.parse("Hour is 12", tformat).getHours());
 			}
 		},
 		{
 			name: "day_of_year",
 			runTest: function(t){
 
-//				t.is(23, dojo.date.setDayOfYear(new Date(2006,0,1), 23).getDate());
-				t.is(1, dojo.date.locale._getDayOfYear(new Date(2006,0,1)));
-				t.is(32, dojo.date.locale._getDayOfYear(new Date(2006,1,1)));
-				t.is(72, dojo.date.locale._getDayOfYear(new Date(2007,2,13,0,13)));
-				t.is(72, dojo.date.locale._getDayOfYear(new Date(2007,2,13,1,13)));
+//				t.is(23, date.setDayOfYear(new Date(2006,0,1), 23).getDate());
+				t.is(1, locale._getDayOfYear(new Date(2006,0,1)));
+				t.is(32, locale._getDayOfYear(new Date(2006,1,1)));
+				t.is(72, locale._getDayOfYear(new Date(2007,2,13,0,13)));
+				t.is(72, locale._getDayOfYear(new Date(2007,2,13,1,13)));
 			}
 		},
 		{
 			name: "week_of_year",
 			runTest: function(t){
-				t.is(0, dojo.date.locale._getWeekOfYear(new Date(2000,0,1)));
-				t.is(1, dojo.date.locale._getWeekOfYear(new Date(2000,0,2)));
-				t.is(0, dojo.date.locale._getWeekOfYear(new Date(2000,0,2), 1));
-				t.is(0, dojo.date.locale._getWeekOfYear(new Date(2007,0,1)));
-				t.is(1, dojo.date.locale._getWeekOfYear(new Date(2007,0,1), 1));
-				t.is(27, dojo.date.locale._getWeekOfYear(new Date(2007,6,14)));
-				t.is(28, dojo.date.locale._getWeekOfYear(new Date(2007,6,14), 1));
+				t.is(0, locale._getWeekOfYear(new Date(2000,0,1)));
+				t.is(1, locale._getWeekOfYear(new Date(2000,0,2)));
+				t.is(0, locale._getWeekOfYear(new Date(2000,0,2), 1));
+				t.is(0, locale._getWeekOfYear(new Date(2007,0,1)));
+				t.is(1, locale._getWeekOfYear(new Date(2007,0,1), 1));
+				t.is(27, locale._getWeekOfYear(new Date(2007,6,14)));
+				t.is(28, locale._getWeekOfYear(new Date(2007,6,14), 1));
 			}
 		}
-	]
-);
+	]);
 
 /*
 // workaround deprecated methods. Should decide whether we should convert the tests or add a helper method (in dojo.date?) to do this.
@@ -327,9 +327,9 @@ dojo_validate_isValidTime = function(str, props){
 	if(!props.pm){props.pm="p.m.";}
 	var result = false;
 	if(/[hk]/.test(props.format) && props.format.indexOf('a') == -1){
-		result = dojo.date.locale.parse(str, {selector: 'time', timePattern: props.format + " a"});
+		result = locale.parse(str, {selector: 'time', timePattern: props.format + " a"});
 	}
-	return Boolean(result || dojo.date.locale.parse(str, {selector: 'time', timePattern: props.format}));
+	return Boolean(result || locale.parse(str, {selector: 'time', timePattern: props.format}));
 }
 
 dojo_validate_is12HourTime = function(str){
@@ -341,7 +341,7 @@ dojo_validate_is24HourTime = function(str){
 }
 
 dojo_validate_isValidDate = function(str, fmt){
-	return Boolean(dojo.date.locale.parse(str, {selector: 'date', datePattern: fmt}));
+	return Boolean(locale.parse(str, {selector: 'date', datePattern: fmt}));
 }
 
 function test_validate_datetime_isValidTime(){
@@ -443,3 +443,5 @@ function test_validate_datetime_isValidDate(){
 	jum.assertTrue("test25", dojo_validate_isValidDate("19-10-2005", "d-M-yyyy"));
 }
 */
+
+});
\ No newline at end of file
diff --git a/dojo/tests/date/stamp.js b/dojo/tests/date/stamp.js
index 04c4044..c46d899 100644
--- a/dojo/tests/date/stamp.js
+++ b/dojo/tests/date/stamp.js
@@ -1,12 +1,11 @@
-dojo.provide("dojo.tests.date.stamp");
+define(["doh", "dojo/date/stamp"], function(doh, stamp){
 
-dojo.require("dojo.date.stamp");
 
-tests.register("tests.date.stamp",
-	[
+doh.register("tests.date.stamp", [
+
 function test_date_iso(t){
 	var rfc  = "2005-06-29T08:05:00-07:00";
-	var date = dojo.date.stamp.fromISOString(rfc);
+	var date = stamp.fromISOString(rfc);
 	t.is(2005,date.getFullYear());
 	t.is(5,date.getMonth());
 	t.is(29,date.getUTCDate());
@@ -15,47 +14,47 @@ function test_date_iso(t){
 	t.is(0,date.getSeconds());
 
 	rfc  = "2004-02-29";
-	date = dojo.date.stamp.fromISOString(rfc);
+	date = stamp.fromISOString(rfc);
 	t.is(2004,date.getFullYear());
 	t.is(1,date.getMonth());
 	t.is(29,date.getDate());
 
 	rfc  = "2004-01";
-	date = dojo.date.stamp.fromISOString(rfc);
+	date = stamp.fromISOString(rfc);
 	t.is(2004,date.getFullYear());
 	t.is(0,date.getMonth());
 	t.is(1,date.getDate());
 
 	// No TZ info means local time
 	rfc  = "2004-02-29T01:23:45";
-	date = dojo.date.stamp.fromISOString(rfc);
+	date = stamp.fromISOString(rfc);
 	t.is(2004,date.getFullYear());
 	t.is(1,date.getMonth());
 	t.is(29,date.getDate());
 	t.is(1,date.getHours());
 
 	date = new Date(2005,5,29,8,5,0);
-	rfc = dojo.date.stamp.toISOString(date);
+	rfc = stamp.toISOString(date);
 	//truncate for comparison
 	t.is("2005-06",rfc.substring(0,7));
 
 	date = new Date(101,0,2);
 	date.setFullYear(101);
-	rfc = dojo.date.stamp.toISOString(date);
+	rfc = stamp.toISOString(date);
 	//truncate for comparison
 	t.is("0101-01",rfc.substring(0,7));
 
 	rfc  = "0101-01-01";
-	date = dojo.date.stamp.fromISOString(rfc);
+	date = stamp.fromISOString(rfc);
 	t.is(101,date.getFullYear());
 	t.is(0,date.getMonth());
 	t.is(1,date.getDate());
 
 	rfc = "0001-01T00:00:00";
-	date = dojo.date.stamp.fromISOString(rfc);
+	date = stamp.fromISOString(rfc);
 	t.is(1,date.getFullYear());
 
-	date = dojo.date.stamp.fromISOString("T18:46:39");
+	date = stamp.fromISOString("T18:46:39");
 	t.is(18, date.getHours());
 	t.is(46, date.getMinutes());
 	t.is(39, date.getSeconds());
@@ -64,7 +63,7 @@ function test_date_iso(t){
 function test_date_iso_tz(t){
 
 	//23:59:59.9942 or 235959.9942
-//	var date = dojo.date.stamp.fromISOString("T18:46:39.9942");
+//	var date = stamp.fromISOString("T18:46:39.9942");
 //	t.is(18, date.getHours());
 //	t.is(46, date.getMinutes());
 //	t.is(39, date.getSeconds());
@@ -74,25 +73,26 @@ function test_date_iso_tz(t){
 
 	//timezone tests
 	var offset = new Date().getTimezoneOffset()/60;
-	date = dojo.date.stamp.fromISOString("T18:46:39+07:00");
+	date = stamp.fromISOString("T18:46:39+07:00");
 	t.is(11, date.getUTCHours());
 
-	date = dojo.date.stamp.fromISOString("T18:46:39+00:00");
+	date = stamp.fromISOString("T18:46:39+00:00");
 	t.is(18, date.getUTCHours());
 
-	date = dojo.date.stamp.fromISOString("T18:46:39Z");
+	date = stamp.fromISOString("T18:46:39Z");
 	t.is(18, date.getUTCHours());
 
-	date = dojo.date.stamp.fromISOString("T16:46:39-07:00");
+	date = stamp.fromISOString("T16:46:39-07:00");
 	t.is(23, date.getUTCHours());
 	
-	date = dojo.date.stamp.fromISOString("T00:00:00Z", new Date(2010,3,1));
+	date = stamp.fromISOString("T00:00:00Z", new Date(2010,3,1));
 	t.is(0, date.getUTCHours());
 	t.is(2010, date.getFullYear());
 	
 	//+hh:mm, +hhmm, or +hh
 	
 	//-hh:mm, -hhmm, or -hh
-	}
-	]
-);
+}
+]);
+
+});
diff --git a/dojo/tests/dnd/dndDefault.css b/dojo/tests/dnd/dndDefault.css
index d033239..624c1b9 100644
--- a/dojo/tests/dnd/dndDefault.css
+++ b/dojo/tests/dnd/dndDefault.css
@@ -25,6 +25,10 @@
 
 .dojoDndItem { 
 	padding: 3px;
+
+	/* Prevent magnifying-glass text selection icon to appear on mobile webkit as it causes a touchout event */
+	-webkit-touch-callout: none;
+	-webkit-user-select: none; /* Disable selection/Copy of UIWebView */
 }
 
 .dj_ff2 .dojoDndItem {
diff --git a/dojo/tests/dnd/flickr_viewer.html b/dojo/tests/dnd/flickr_viewer.html
index 4520f35..71e1e6c 100644
--- a/dojo/tests/dnd/flickr_viewer.html
+++ b/dojo/tests/dnd/flickr_viewer.html
@@ -39,96 +39,87 @@
 		.dojoDndHorizontal .dojoDndItemBefore img	{border-left:  3px solid red;}
 		.dojoDndHorizontal .dojoDndItemAfter img	{border-right: 3px solid red;}
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-	<!--
-	<script type="text/javascript" src="../../dnd/common.js"></script>
-	<script type="text/javascript" src="../../dnd/autoscroll.js"></script>
-	<script type="text/javascript" src="../../dnd/Container.js"></script>
-	<script type="text/javascript" src="../../dnd/Selector.js"></script>
-	<script type="text/javascript" src="../../dnd/Source.js"></script>
-	<script type="text/javascript" src="../../dnd/Avatar.js"></script>
-	<script type="text/javascript" src="../../dnd/Manager.js"></script>
-	-->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.parser");
-		dojo.require("dojo.io.script");
-		dojo.require("dojo.dnd.Source");
-		
-		// The main image container creator
-		var main_creator = function(item, hint){
-			var type = [];
-			if(item.tags.search(/cat/i) >= 0){ type.push("cat"); }
-			if(item.tags.search(/dog/i) >= 0){ type.push("dog"); }
-			var node;
-			if(hint == "avatar"){
-				node = dojo.doc.createElement("span");
-				node.innerHTML = "<img src='" + item.media.m.replace(/_m\./, "_s.") + "'/>";
-			}else{
-				var t = ["<table border='0' cellpadding='0' cellspacing='0' width='250'>"];
-				t.push("<tr><td colspan='2' class='image' align='center' width='250'><img src='" + 
-					item.media.m + "'/></td></tr>");
-				t.push("<tr><td class='name' valign='top'>Title:</td><td class='value'><a href='" + 
-					item.link + "' target='_blank'>" + 
-					(item.title ? item.title : "<em>untitled</em>") + "</a></td></tr>");
-				t.push("<tr><td class='name' valign='top'>Author:</td><td class='value'>" + 
-					item.author + "</td></tr>");
-				t.push("<tr><td class='name' valign='top'>Tags:</td><td class='value'>" + 
-					item.tags + "</td></tr>");
-				t.push("</table>");
-				node = dojo.doc.createElement("div");
-				node.innerHTML = t.join("");
-			}
-			node.id = dojo.dnd.getUniqueId();
-			return {node: node, data: item, type: type};
-		};
-		
-		// The band image container creator
-		var band_creator = function(item, hint){
-			var type = [];
-			if(item.tags.search(/cat/i) >= 0){ type.push("cat"); }
-			if(item.tags.search(/dog/i) >= 0){ type.push("dog"); }
-			var src = item.media.m.replace(/_m\./, "_s.");
-			var node = dojo.doc.createElement("span");
-			node.innerHTML = "<img src='" + src + "'/>";
-			node.id = dojo.dnd.getUniqueId();
-			return {node: node, data: item, type: type};
-		};
+		require([
+			"dojo/dom", "dojo/parser", "dojo/request/script",
+			"dojo/dnd/common", "dojo/dnd/Avatar", "dojo/dnd/Source", "dojo/domReady!"
+		], function(dom, parser, script, dnd, Avatar, Source){
 		
-		// Flickr's JSONP function
-		var jsonFlickrFeed = function(data){
-			if(!data.items || !data.items.length){
-				dojo.byId("status").innerHTML = "Flickr didn't return any images";
-				return;
-			}
-			dojo.byId("status").innerHTML = data.items.length + " images were retrieved";
-			// initialize sources
-			c1.selectAll().deleteSelectedNodes();
-			c2.selectAll().deleteSelectedNodes();
-			c3.selectAll().deleteSelectedNodes();
-			// populate the main source
-			c1.insertNodes(false, data.items);
-		};
-		
-		var init = function(){
+			// The main image container creator
+			main_creator = function(item, hint){
+				var type = [];
+				if(item.tags.search(/cat/i) >= 0){ type.push("cat"); }
+				if(item.tags.search(/dog/i) >= 0){ type.push("dog"); }
+				var node;
+				if(hint == "avatar"){
+					node = document.createElement("span");
+					node.innerHTML = "<img src='" + item.media.m.replace(/_m\./, "_s.") + "'/>";
+				}else{
+					var t = ["<table border='0' cellpadding='0' cellspacing='0' width='250'>"];
+					t.push("<tr><td colspan='2' class='image' align='center' width='250'><img src='" + 
+						item.media.m + "'/></td></tr>");
+					t.push("<tr><td class='name' valign='top'>Title:</td><td class='value'><a href='" + 
+						item.link + "' target='_blank'>" + 
+						(item.title ? item.title : "<em>untitled</em>") + "</a></td></tr>");
+					t.push("<tr><td class='name' valign='top'>Author:</td><td class='value'>" + 
+						item.author + "</td></tr>");
+					t.push("<tr><td class='name' valign='top'>Tags:</td><td class='value'>" + 
+						item.tags + "</td></tr>");
+					t.push("</table>");
+					node = document.createElement("div");
+					node.innerHTML = t.join("");
+				}
+				node.id = dnd.getUniqueId();
+				return {node: node, data: item, type: type};
+			};
+			
+			// The band image container creator
+			band_creator = function(item, hint){
+				var type = [];
+				if(item.tags.search(/cat/i) >= 0){ type.push("cat"); }
+				if(item.tags.search(/dog/i) >= 0){ type.push("dog"); }
+				var src = item.media.m.replace(/_m\./, "_s.");
+				var node = document.createElement("span");
+				node.innerHTML = "<img src='" + src + "'/>";
+				node.id = dnd.getUniqueId();
+				return {node: node, data: item, type: type};
+			};
+			
+			// Flickr's JSONP function.
+			jsonFlickrFeed = function(data){
+				if(!data.items || !data.items.length){
+					dom.byId("status").innerHTML = "Flickr didn't return any images";
+					return;
+				}
+				dom.byId("status").innerHTML = data.items.length + " images were retrieved";
+				// initialize sources
+				c1.selectAll().deleteSelectedNodes();
+				c2.selectAll().deleteSelectedNodes();
+				c3.selectAll().deleteSelectedNodes();
+				// populate the main source
+				c1.insertNodes(false, data.items);
+			};
+
 			// replace the avatar string to make it more human readable
-			dojo.dnd.Avatar.prototype._generateText = function(){
+			Avatar.prototype._generateText = function(){
 				return (this.manager.copy ? "copy" : "mov") + 
 					"ing " + this.manager.nodes.length + " item" + 
 					(this.manager.nodes.length != 1 ? "s" : "");
 			};
-			// ask Flickr for images
-			var td = dojo.io.script.get({
-				url: "http://api.flickr.com/services/feeds/photos_public.gne",
-				content: {tags: "cat,dog,cow", tagmode: "any", format: "json"},
+
+			// Ask Flickr for images.   This calls jsonFlickrFeed rather than coming in the promise result, not sure why.
+			script.get("http://api.flickr.com/services/feeds/photos_public.gne", {
+				query: {tags: "cat,dog,cow", tagmode: "any", format: "json"},
 				handleAs: "text/javascript",
 				preventCache: true
-			});
-			td.addErrback(function(){
-				dojo.byId("status").innerHTML = "Flickr failed to return images";
-			});
-		};
-		
-		dojo.addOnLoad(init);
+			}).otherwise(
+				function(){
+					dom.byId("status").innerHTML = "Flickr failed to return images";
+				}
+			);
+		});
 	</script>
 </head>
 <body>
@@ -150,20 +141,20 @@
 	<p>Now scroll down and start dragging and dropping, rearrange images using DnD, copy and move them back!</p>
 	<p>Status: <span id="status">retrieving a list of Flickr images...</span></p>
 	<div class="wrap1">
-		<div dojoType="dojo.dnd.Source" jsId="c1" accept="cat, dog, cow" class="container">
-			<script type="dojo/method" event="creator" args="item, hint">return main_creator(item, hint);</script>
+		<div data-dojo-type="dojo/dnd/Source" data-dojo-id="c1" accept="cat, dog, cow" class="container">
+			<script type="dojo/method" data-dojo-event="creator" data-dojo-args="item, hint">return main_creator(item, hint);</script>
 		</div>
 	</div>
 	<p>Tag: cat</p>
 	<div class="wrap2">
-		<div dojoType="dojo.dnd.Source" jsId="c2" accept="cat" horizontal="true" class="container">
-			<script type="dojo/method" event="creator" args="item, hint">return band_creator(item, hint);</script>
+		<div data-dojo-type="dojo/dnd/Source" data-dojo-id="c2" accept="cat" horizontal="true" class="container">
+			<script type="dojo/method" data-dojo-event="creator" data-dojo-args="item, hint">return band_creator(item, hint);</script>
 		</div>
 	</div>
 	<p>Tag: dog</p>
 	<div class="wrap2">
-		<div dojoType="dojo.dnd.Source" jsId="c3" accept="dog" horizontal="true" class="container">
-			<script type="dojo/method" event="creator" args="item, hint">return band_creator(item, hint);</script>
+		<div data-dojo-type="dojo/dnd/Source" data-dojo-id="c3" accept="dog" horizontal="true" class="container">
+			<script type="dojo/method" data-dojo-event="creator" data-dojo-args="item, hint">return band_creator(item, hint);</script>
 		</div>
 	</div>
 </body>
diff --git a/dojo/tests/dnd/robot/test_dnd.html b/dojo/tests/dnd/robot/test_dnd.html
index 761e91f..ff5cff9 100644
--- a/dojo/tests/dnd/robot/test_dnd.html
+++ b/dojo/tests/dnd/robot/test_dnd.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
-	<title>doh.robot DnD Test</title>
+	<title>robot DnD Test</title>
 
 	<style>
 		@import "../../../../util/doh/robot/robot.css";
@@ -10,42 +10,41 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
-		dojo.require("dojo.robotx");
+		require(["doh", "dojo/dom", "dojo/query", "dojo/robotx", "dojo/domReady!"], function(doh, dom, query, robot){
 
-		dojo.addOnLoad(function(){
 			var container1;
 			var container2;
 			var container3;
 			var container4;
 			var container5;
 
-			doh.robot.initRobot('../test_dnd.html');
+			robot.initRobot('../test_dnd.html');
 
 			doh.register('dojox.robot.AutoGeneratedTestGroup',{
 				name: 'autotest0',
 				timeout: 10000,
 				setUp: function(){
-					container1=dojo.byId('container1');
-					container2=dojo.query("div[jsid='c2']")[0];
-					container3=dojo.query("div[jsid='c3']")[0];
-					container4=dojo.query("div[jsid='c4']")[0];
-					container5=dojo.query("div[jsid='c5']")[0];
+					container1=dom.byId('container1', robot.doc);
+					container2=query("div[data-dojo-id='c2']", robot.doc)[0];
+					container3=query("div[data-dojo-id='c3']", robot.doc)[0];
+					container4=query("div[data-dojo-id='c4']", robot.doc)[0];
+					container5=query("div[data-dojo-id='c5']", robot.doc)[0];
 				},
 				runTest: function(){
-					var count1=dojo.query("div", container1).length;
-					var count2=dojo.query("div", container2).length;
+					var count1=query("div", container1).length;
+					var count2=query("div", container2).length;
 					var d = new doh.Deferred();
-					doh.robot.mouseMoveAt('dojoUnique13', 500, 500, 10, 10);
-					doh.robot.mousePress({left:true}, 100);
-					doh.robot.mouseMoveAt(container2, 100, 1000);
-					doh.robot.mouseRelease({left:true}, 500);
-					doh.robot.sequence(d.getTestCallback(function(){
-						var actual = dojo.query("> div", container1).length;
+					robot.mouseMoveAt('dojoUnique13', 500, 500, 10, 10);
+					robot.mousePress({left:true}, 100);
+					robot.mouseMoveAt(container2, 100, 1000);
+					robot.mouseRelease({left:true}, 500);
+					robot.sequence(d.getTestCallback(function(){
+						var actual = query("> div", container1).length;
 						count1--;
 						doh.is(count1, actual, "Wrong number of items ("+actual+") in container 1 (expected " + count1 + ")");
-						var actual = dojo.query("> div", container2).length;
+						var actual = query("> div", container2).length;
 						count2++;
 						doh.is(count2, actual, "Wrong number of items ("+actual+") in container 2 (expected " + count2 + ")");
 					}), 1000);
@@ -56,18 +55,18 @@
 				name: 'autotest1',
 				timeout: 10000,
 				runTest: function(){
-					var count1=dojo.query("> div", container1).length;
-					var count2=dojo.query("> div", container2).length;
+					var count1=query("> div", container1).length;
+					var count2=query("> div", container2).length;
 					var d = new doh.Deferred();
-					doh.robot.mouseMoveAt('dojoUnique3', 500, 500, 10, 10);
-					doh.robot.mousePress({left:true}, 500);
-					doh.robot.mouseMoveAt(container1, 500, 1000);
-					doh.robot.mouseRelease({left:true}, 500);
-					doh.robot.sequence(d.getTestCallback(function(){
-						var actual = dojo.query("> div", container1).length;
+					robot.mouseMoveAt('dojoUnique3', 500, 500, 10, 10);
+					robot.mousePress({left:true}, 500);
+					robot.mouseMoveAt(container1, 500, 1000);
+					robot.mouseRelease({left:true}, 500);
+					robot.sequence(d.getTestCallback(function(){
+						var actual = query("> div", container1).length;
 						count1++;
 						doh.is(count1, actual, "Wrong number of items ("+actual+") in container 1 (expected " + count1 + ")");
-						var actual = dojo.query("> div", container2).length;
+						var actual = query("> div", container2).length;
 						doh.is(count2, actual, "Wrong number of items ("+actual+") in container 2 (expected " + count2 + ")");
 					}), 1000);
 					return d;
@@ -77,17 +76,17 @@
 				name: 'autotest2',
 				timeout: 10000,
 				runTest: function(){
-					var count2=dojo.query("> div", container2).length;
-					var count5=dojo.query("> div", container5).length;
+					var count2=query("> div", container2).length;
+					var count5=query("> div", container5).length;
 					var d = new doh.Deferred();
-					doh.robot.mouseMoveAt('dojoUnique11', 500, 500, 10, 10);
-					doh.robot.mousePress({left:true}, 500);
-					doh.robot.mouseMoveAt(container2, 500, 1000);
-					doh.robot.mouseRelease({left:true}, 500);
-					doh.robot.sequence(d.getTestCallback(function(){
-						var actual = dojo.query("> div", container2).length;
+					robot.mouseMoveAt('dojoUnique11', 500, 500, 10, 10);
+					robot.mousePress({left:true}, 500);
+					robot.mouseMoveAt(container2, 500, 1000);
+					robot.mouseRelease({left:true}, 500);
+					robot.sequence(d.getTestCallback(function(){
+						var actual = query("> div", container2).length;
 						doh.is(count2, actual, "Wrong number of items ("+actual+") in container 2 (expected " + count2 + ")");
-						var actual = dojo.query("> div", container5).length;
+						var actual = query("> div", container5).length;
 						doh.is(count5, actual, "Wrong number of items ("+actual+") in container 5 (expected " + count5 + ")");
 					}), 1000);
 					return d;
diff --git a/dojo/tests/dnd/test_autoscroll.html b/dojo/tests/dnd/test_autoscroll.html
new file mode 100644
index 0000000..cc25653
--- /dev/null
+++ b/dojo/tests/dnd/test_autoscroll.html
@@ -0,0 +1,195 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>Dojo DnD auto scroll test</title>
+	<style type="text/css">
+		@import "../../resources/dojo.css";
+		@import "../../resources/dnd.css";
+		@import "dndDefault.css";
+		@import "../../../util/doh/robot/robot.css";
+
+		body {
+			padding: 1em;
+			background: #ededed;
+		}
+
+		.container {
+			width: 100px;
+			display: block;
+			margin: 10px;
+		}
+
+		.clear {
+			clear: both;
+		}
+	</style>
+
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		require(["dojo/dnd/Source", "dojo/domReady!"], function(Source){
+
+			var c1 = new Source("container1");
+			c1.insertNodes(false, ["A", "B", "C", "D", "E", "F", "G"]);
+
+			var c2 = new Source("container2");
+			c2.insertNodes(false, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
+		});
+	</script>
+</head>
+<body>
+	<h1 class="testTitle">Dojo DnD auto-scroll test</h1>
+
+	<p>Should be able to both scroll the page, and the inner div, by dragging the element near the viewports's or div's top/bottom borders.</p>
+	<p>
+		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus.
+	</p>
+
+	<div id="dragLists">
+		<div id="container1" class="container" style="height: 100px; overflow: auto;"></div>
+		<div id="container2" class="container" style="height: 100px; overflow: auto;"></div>
+	</div>
+
+	<p>Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
+		imperdiet. Fusce dignissim porta augue. Nulla vestibulum. Integer lorem
+		nunc, ullamcorper a, commodo ac, malesuada sed, dolor. Aenean id mi in
+		massa bibendum suscipit. Integer eros. Nullam suscipit mauris. In
+		pellentesque. Mauris ipsum est, pharetra semper, pharetra in, viverra
+		quis, tellus. Etiam purus. Quisque egestas, tortor ac cursus lacinia,
+		felis leo adipiscing nisi, et rhoncus elit dolor eget eros. Fusce ut
+		quam. Suspendisse eleifend leo vitae ligula. Nulla facilisi. Nulla
+		rutrum, erat vitae lacinia dictum, pede purus imperdiet lacus, ut
+		semper velit ante id metus. Praesent massa dolor, porttitor sed,
+		pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit
+		tortor pharetra congue. Suspendisse pulvinar.
+	</p>
+	<p>Vestibulum convallis eros ac justo. Proin dolor. Etiam aliquam. Nam
+		ornare elit vel augue. Suspendisse potenti. Etiam sed mauris eu neque
+		nonummy mollis. Vestibulum vel purus ac pede semper accumsan. Vivamus
+		lobortis, sem vitae nonummy lacinia, nisl est gravida magna, non cursus
+		est quam sed urna. Phasellus adipiscing justo in ipsum. Duis sagittis
+		dolor sit amet magna. Suspendisse suscipit, neque eu dictum auctor,
+		nisi augue tincidunt arcu, non lacinia magna purus nec magna. Praesent
+		pretium sollicitudin sapien. Suspendisse imperdiet. Class aptent taciti
+		sociosqu ad litora torquent per conubia nostra, per inceptos
+		hymenaeos.
+	</p>
+	<p>Mauris pharetra lorem sit amet sapien. Nulla libero metus, tristique
+		et, dignissim a, tempus et, metus. Ut libero. Vivamus tempus purus vel
+		ipsum. Quisque mauris urna, vestibulum commodo, rutrum vitae, ultrices
+		vitae, nisl. Class aptent taciti sociosqu ad litora torquent per
+		conubia nostra, per inceptos hymenaeos. Nulla id erat sit amet odio
+		luctus eleifend. Proin massa libero, ultricies non, tincidunt a,
+		vestibulum non, tellus. Nunc nunc purus, lobortis a, pulvinar at,
+		egestas a, mi. Cras adipiscing velit a mauris. Morbi felis. Etiam at
+		felis. Cras eget eros et justo mattis pulvinar. Nullam at justo id
+		risus porttitor dignissim. Vestibulum sed velit vel metus tincidunt
+		tempus. Nunc euismod nisl id dolor tristique tincidunt. Nullam placerat
+		turpis sed odio. Curabitur in est id nibh tempus ultrices. Aliquam
+		consectetuer dapibus eros. Aliquam nisl.
+	</p>
+
+	<p>
+		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus.
+	</p>
+
+	<p>Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
+		imperdiet. Fusce dignissim porta augue. Nulla vestibulum. Integer lorem
+		nunc, ullamcorper a, commodo ac, malesuada sed, dolor. Aenean id mi in
+		massa bibendum suscipit. Integer eros. Nullam suscipit mauris. In
+		pellentesque. Mauris ipsum est, pharetra semper, pharetra in, viverra
+		quis, tellus. Etiam purus. Quisque egestas, tortor ac cursus lacinia,
+		felis leo adipiscing nisi, et rhoncus elit dolor eget eros. Fusce ut
+		quam. Suspendisse eleifend leo vitae ligula. Nulla facilisi. Nulla
+		rutrum, erat vitae lacinia dictum, pede purus imperdiet lacus, ut
+		semper velit ante id metus. Praesent massa dolor, porttitor sed,
+		pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit
+		tortor pharetra congue. Suspendisse pulvinar.
+	</p>
+	<p>Vestibulum convallis eros ac justo. Proin dolor. Etiam aliquam. Nam
+		ornare elit vel augue. Suspendisse potenti. Etiam sed mauris eu neque
+		nonummy mollis. Vestibulum vel purus ac pede semper accumsan. Vivamus
+		lobortis, sem vitae nonummy lacinia, nisl est gravida magna, non cursus
+		est quam sed urna. Phasellus adipiscing justo in ipsum. Duis sagittis
+		dolor sit amet magna. Suspendisse suscipit, neque eu dictum auctor,
+		nisi augue tincidunt arcu, non lacinia magna purus nec magna. Praesent
+		pretium sollicitudin sapien. Suspendisse imperdiet. Class aptent taciti
+		sociosqu ad litora torquent per conubia nostra, per inceptos
+		hymenaeos.
+	</p>
+	<p>Mauris pharetra lorem sit amet sapien. Nulla libero metus, tristique
+		et, dignissim a, tempus et, metus. Ut libero. Vivamus tempus purus vel
+		ipsum. Quisque mauris urna, vestibulum commodo, rutrum vitae, ultrices
+		vitae, nisl. Class aptent taciti sociosqu ad litora torquent per
+		conubia nostra, per inceptos hymenaeos. Nulla id erat sit amet odio
+		luctus eleifend. Proin massa libero, ultricies non, tincidunt a,
+		vestibulum non, tellus. Nunc nunc purus, lobortis a, pulvinar at,
+		egestas a, mi. Cras adipiscing velit a mauris. Morbi felis. Etiam at
+		felis. Cras eget eros et justo mattis pulvinar. Nullam at justo id
+		risus porttitor dignissim. Vestibulum sed velit vel metus tincidunt
+		tempus. Nunc euismod nisl id dolor tristique tincidunt. Nullam placerat
+		turpis sed odio. Curabitur in est id nibh tempus ultrices. Aliquam
+		consectetuer dapibus eros. Aliquam nisl.
+	</p>
+
+
+	<p>
+		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus.
+	</p>
+
+	<p>Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
+		imperdiet. Fusce dignissim porta augue. Nulla vestibulum. Integer lorem
+		nunc, ullamcorper a, commodo ac, malesuada sed, dolor. Aenean id mi in
+		massa bibendum suscipit. Integer eros. Nullam suscipit mauris. In
+		pellentesque. Mauris ipsum est, pharetra semper, pharetra in, viverra
+		quis, tellus. Etiam purus. Quisque egestas, tortor ac cursus lacinia,
+		felis leo adipiscing nisi, et rhoncus elit dolor eget eros. Fusce ut
+		quam. Suspendisse eleifend leo vitae ligula. Nulla facilisi. Nulla
+		rutrum, erat vitae lacinia dictum, pede purus imperdiet lacus, ut
+		semper velit ante id metus. Praesent massa dolor, porttitor sed,
+		pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit
+		tortor pharetra congue. Suspendisse pulvinar.
+	</p>
+	<p>Vestibulum convallis eros ac justo. Proin dolor. Etiam aliquam. Nam
+		ornare elit vel augue. Suspendisse potenti. Etiam sed mauris eu neque
+		nonummy mollis. Vestibulum vel purus ac pede semper accumsan. Vivamus
+		lobortis, sem vitae nonummy lacinia, nisl est gravida magna, non cursus
+		est quam sed urna. Phasellus adipiscing justo in ipsum. Duis sagittis
+		dolor sit amet magna. Suspendisse suscipit, neque eu dictum auctor,
+		nisi augue tincidunt arcu, non lacinia magna purus nec magna. Praesent
+		pretium sollicitudin sapien. Suspendisse imperdiet. Class aptent taciti
+		sociosqu ad litora torquent per conubia nostra, per inceptos
+		hymenaeos.
+	</p>
+	<p>Mauris pharetra lorem sit amet sapien. Nulla libero metus, tristique
+		et, dignissim a, tempus et, metus. Ut libero. Vivamus tempus purus vel
+		ipsum. Quisque mauris urna, vestibulum commodo, rutrum vitae, ultrices
+		vitae, nisl. Class aptent taciti sociosqu ad litora torquent per
+		conubia nostra, per inceptos hymenaeos. Nulla id erat sit amet odio
+		luctus eleifend. Proin massa libero, ultricies non, tincidunt a,
+		vestibulum non, tellus. Nunc nunc purus, lobortis a, pulvinar at,
+		egestas a, mi. Cras adipiscing velit a mauris. Morbi felis. Etiam at
+		felis. Cras eget eros et justo mattis pulvinar. Nullam at justo id
+		risus porttitor dignissim. Vestibulum sed velit vel metus tincidunt
+		tempus. Nunc euismod nisl id dolor tristique tincidunt. Nullam placerat
+		turpis sed odio. Curabitur in est id nibh tempus ultrices. Aliquam
+		consectetuer dapibus eros. Aliquam nisl.
+	</p>
+
+	<p>END OF DOCUMENT</p>
+</body>
+</html>
diff --git a/dojo/tests/dnd/test_box_constraints.html b/dojo/tests/dnd/test_box_constraints.html
index 5217562..c20540e 100644
--- a/dojo/tests/dnd/test_box_constraints.html
+++ b/dojo/tests/dnd/test_box_constraints.html
@@ -19,41 +19,47 @@
 			cursor: pointer;
 		}
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
 	<!--
 	<script type="text/javascript" src="../../dnd/move.js"></script>
 	-->
 	<script type="text/javascript">
-		dojo.require("dojo.parser");
-		dojo.require("dojo.dnd.move");
-		var m5, m6;
-		var init = function(){
-			m5 = new dojo.dnd.move.boxConstrainedMoveable("moveable5", {box: {l: 100, t: 100, w: 500, h: 500}});
-			m6 = new dojo.dnd.move.boxConstrainedMoveable("moveable6", {box: {l: 100, t: 100, w: 500, h: 500}, within: true});
+		require(["dojo/aspect", "dojo/dnd/move", "dojo/parser", "dojo/topic", "dojo/domReady!"], function(aspect, move, parser, topic){
+
+			parser.parse();
+
+			var m5, m6;
+
+			m5 = new move.boxConstrainedMoveable("moveable5", {box: {l: 100, t: 100, w: 500, h: 500}});
+			m6 = new move.boxConstrainedMoveable("moveable6", {box: {l: 100, t: 100, w: 500, h: 500}, within: true});
 
 			// system-wide topics
-			dojo.subscribe("/dnd/move/start", function(node){ 
+			topic.subscribe("/dnd/move/start", function(node){
 				console.debug("Start move", node); 	
 			});
-			dojo.subscribe("/dnd/move/stop", function(node){ 
+			topic.subscribe("/dnd/move/stop", function(node){
 				console.debug("Stop move", node); 	
 			});
 
 			// watching a particular moveable instance
-			dojo.connect(m5, "onDndMoveStart", function(mover){ 
+			aspect.after(m5, "onDndMoveStart", function(mover){
 				console.debug("Start moving m5 with this mover:", mover); 	
-			});
-			dojo.connect(m5, "onDndMoveStop", function(mover){ 
+			}, true);
+			aspect.after(m5, "onDndMoveStop", function(mover){
 				console.debug("Stop moving m5 with this mover:", mover); 	
-			});
-		};
-		dojo.addOnLoad(init);
+			}, true);
+		});
+
 	</script>
 </head>
 <body>
 	<h1>Dojo box constraint test</h1>
 	<div class="moveable" id="moveable5"><strong>Paragraph restricted to (100,100:500,500) box:</strong> Donec ac odio sed pede aliquet auctor. Donec et lectus. Praesent feugiat ultrices enim. Morbi lectus. Donec vestibulum posuere libero. Donec quam enim, nonummy a, auctor vitae, placerat id, massa. Vivamus vulputate luctus nibh. Donec dolor orci, sagittis ac, pretium sed, ornare sit amet, pede. Vestibulum leo justo, pellentesque sit amet, tristique sed, tempor eu, felis. Lorem ipsum dolor [...]
 	<div class="moveable" id="moveable6"><strong>Paragraph restricted to (100,100:500,500) box, it cannot go outside of this box:</strong> In hac habitasse platea dictumst. Etiam rhoncus, leo quis hendrerit vestibulum, ipsum felis porta massa, vitae posuere nunc lorem ac enim. Nam neque turpis, aliquet quis, sollicitudin sit amet, dapibus sed, eros. Duis volutpat porttitor velit. Vivamus nibh metus, iaculis eget, malesuada eget, facilisis id, lorem. Sed turpis. Vestibulum aliquam mauris. In [...]
-	<div class="moveable" dojoType="dojo.dnd.move.boxConstrainedMoveable" box="{l: 100, t: 100, w: 500, h: 500}"><strong>Marked up paragraph restricted to (100,100:500,500) box:</strong> Donec ac odio sed pede aliquet auctor. Donec et lectus. Praesent feugiat ultrices enim. Morbi lectus. Donec vestibulum posuere libero. Donec quam enim, nonummy a, auctor vitae, placerat id, massa. Vivamus vulputate luctus nibh. Donec dolor orci, sagittis ac, pretium sed, ornare sit amet, pede. Vestibulum le [...]
+
+	<script type="dojo/require">
+		move: "dojo/dnd/move"
+	</script>
+	<div class="moveable" data-dojo-type="move.boxConstrainedMoveable" box="{l: 100, t: 100, w: 500, h: 500}"><strong>Marked up paragraph restricted to (100,100:500,500) box:</strong> Donec ac odio sed pede aliquet auctor. Donec et lectus. Praesent feugiat ultrices enim. Morbi lectus. Donec vestibulum posuere libero. Donec quam enim, nonummy a, auctor vitae, placerat id, massa. Vivamus vulputate luctus nibh. Donec dolor orci, sagittis ac, pretium sed, ornare sit amet, pede. Vestibulum leo j [...]
 </body>
 </html>
diff --git a/dojo/tests/dnd/test_container.html b/dojo/tests/dnd/test_container.html
index a8b2cc4..b788dfd 100644
--- a/dojo/tests/dnd/test_container.html
+++ b/dojo/tests/dnd/test_container.html
@@ -11,21 +11,17 @@
 		}
 
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true"></script>
-	<!--
-	<script type="text/javascript" src="../../dnd/Container.js"></script>
-	-->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.dnd.Container");
-		var c1, c2, c3, c4, c5;
-		var init = function(){
-			c1 = new dojo.dnd.Container(dojo.byId("container1"));
-			c2 = new dojo.dnd.Container(dojo.byId("container2"));
-			c3 = new dojo.dnd.Container(dojo.byId("container3"));
-			c4 = new dojo.dnd.Container(dojo.byId("container4"));
-			c5 = new dojo.dnd.Container(dojo.byId("container5"));
-		};
-		dojo.addOnLoad(init);
+		require(["dojo/dnd/Container", "dojo/dom", "dojo/domReady!"], function(Container, dom){
+			var c1, c2, c3, c4, c5;
+			c1 = new Container(dom.byId("container1"));
+			c2 = new Container(dom.byId("container2"));
+			c3 = new Container(dom.byId("container3"));
+			c4 = new Container(dom.byId("container4"));
+			c5 = new Container(dom.byId("container5"));
+		});
 	</script>
 </head>
 <body>
diff --git a/dojo/tests/dnd/test_container_markup.html b/dojo/tests/dnd/test_container_markup.html
index 415ad28..123c179 100644
--- a/dojo/tests/dnd/test_container_markup.html
+++ b/dojo/tests/dnd/test_container_markup.html
@@ -11,13 +11,12 @@
 		}
 
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-	<!--
-	<script type="text/javascript" src="../../dnd/Container.js"></script>
-	-->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.parser");
-		dojo.require("dojo.dnd.Container");
+		require(["dojo/parser", "dojo/dnd/Container", "dojo/domReady!"], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
 <body>
@@ -26,25 +25,25 @@
 	<p>Containers have a notion of a "current container", and one element can be "current".</p>
 	<p>See <a href="dndDefault.css">dndDefault.css</a> for example styling</p>
 	<h2>DIV container</h2>
-	<div dojoType="dojo.dnd.Container" jsId="c1" class="container">
+	<div data-dojo-type="dojo/dnd/Container" data-dojo-id="c1" class="container">
 		<div class="dojoDndItem">Item 1</div>
 		<div class="dojoDndItem">Item 2</div>
 		<div class="dojoDndItem">Item 3</div>
 	</div>
 	<h2>UL container</h2>
-	<ul dojoType="dojo.dnd.Container" jsId="c2" class="container">
+	<ul data-dojo-type="dojo/dnd/Container" data-dojo-id="c2" class="container">
 		<li class="dojoDndItem">Item 1</li>
 		<li class="dojoDndItem">Item 2</li>
 		<li class="dojoDndItem">Item 3</li>
 	</ul>
 	<h2>OL container</h2>
-	<ol dojoType="dojo.dnd.Container" jsId="c3" class="container">
+	<ol data-dojo-type="dojo/dnd/Container" data-dojo-id="c3" class="container">
 		<li class="dojoDndItem">Item 1</li>
 		<li class="dojoDndItem">Item 2</li>
 		<li class="dojoDndItem">Item 3</li>
 	</ol>
 	<h2>TABLE container</h2>
-	<table dojoType="dojo.dnd.Container" jsId="c4" class="container" border="1px solid black">
+	<table data-dojo-type="dojo/dnd/Container" data-dojo-id="c4" class="container" border="1px solid black">
 		<tr class="dojoDndItem">
 			<td>A</td>
 			<td>row 1</td>
@@ -60,7 +59,7 @@
 	</table>
 	<h2>P container with SPAN elements</h2>
 	<p>Elements of this container are layed out horizontally.</p>
-	<p dojoType="dojo.dnd.Container" jsId="c5" class="container">
+	<p data-dojo-type="dojo/dnd/Container" data-dojo-id="c5" class="container">
 		<span class="dojoDndItem"> Item 1 </span>
 		<span class="dojoDndItem"> Item 2 </span>
 		<span class="dojoDndItem"> Item 3 </span>
diff --git a/dojo/tests/dnd/test_custom_constraints.html b/dojo/tests/dnd/test_custom_constraints.html
index efece52..9152c51 100644
--- a/dojo/tests/dnd/test_custom_constraints.html
+++ b/dojo/tests/dnd/test_custom_constraints.html
@@ -18,31 +18,26 @@
 			cursor: pointer;
 		}
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true"></script>
-	<!--
-	<script type="text/javascript" src="../../dnd/move.js"></script>
-	-->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.dnd.move");
-		
-		var STEP = 50;
+		require(["dojo/aspect", "dojo/dom-geometry", "dojo/dnd/Moveable", "dojo/domReady!"], function(aspect, domGeom, Moveable){
+			var STEP = 50;
 		
-		var init = function(){
 			// 1st way
-			var m1 = new dojo.dnd.Moveable("moveable1");
+			var m1 = new Moveable("moveable1");
 			m1.onMove = function(mover, leftTop){
 				leftTop.l -= leftTop.l % STEP;
 				leftTop.t -= leftTop.t % STEP;
-				dojo.marginBox(mover.node, leftTop);
+				domGeom.setMarginBox(mover.node, leftTop);
 			};
 			// 2nd way
-			var m2 = new dojo.dnd.Moveable("moveable2");
-			dojo.connect(m2, "onMoving", function(mover, leftTop){
+			var m2 = new Moveable("moveable2");
+			aspect.after(m2, "onMoving", function(mover, leftTop){
 				leftTop.l -= leftTop.l % STEP;
 				leftTop.t -= leftTop.t % STEP;
-			});
-		};
-		dojo.addOnLoad(init);
+			}, true);
+		});
 	</script>
 </head>
 <body>
diff --git a/dojo/tests/dnd/test_dnd.html b/dojo/tests/dnd/test_dnd.html
index 7865233..807d0d1 100644
--- a/dojo/tests/dnd/test_dnd.html
+++ b/dojo/tests/dnd/test_dnd.html
@@ -23,50 +23,40 @@
 		}
 	</style>
 
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-<!--
-	<script type="text/javascript" src="../../dnd/Container.js"></script>
-	<script type="text/javascript" src="../../dnd/Selector.js"></script>
-	<script type="text/javascript" src="../../dnd/Source.js"></script>
-	<script type="text/javascript" src="../../dnd/Avatar.js"></script>
-	<script type="text/javascript" src="../../dnd/Manager.js"></script>
-	<script type="text/javascript" src="../../../dijit/_base/wai.js"></script>
--->
-	<script type="text/javascript">
-		dojo.require("dojo.parser");
-		dojo.require("dojo.dnd.Source");
-
-		var c1;
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
 
-		function init(){
-			c1 = new dojo.dnd.Source("container1");
-			c1.insertNodes(false, [1, "A", [1, 2, 3],
-				function(x){ return x + x; },
-				{toString: function(){ return "CUSTOM!"; }},
-				null]);
+	<script type="text/javascript">
+		require([
+			"dojo/aspect", "dojo/parser", "dojo/topic", "dojo/dnd/Source", "dojo/domReady!"
+		], function(aspect, parser, topic, Source){
+			parser.parse().then(function(){
+				var c1 = new Source("container1");
+				c1.insertNodes(false, [1, "A", [1, 2, 3],
+					function(x){ return x + x; },
+					{toString: function(){ return "CUSTOM!"; }},
+					null]);
 
-			// example subscribe to events
-			dojo.subscribe("/dnd/start", function(source){
-				console.debug("Starting the drop", source);
-			});
-			dojo.subscribe("/dnd/drop/before", function(source, nodes, copy, target){
-				if(target == c1){
-					console.debug(copy ? "Copying from" : "Moving from", source, "to", target, "before", target.before);
-				}
+				// example subscribe to events
+				topic.subscribe("/dnd/start", function(source){
+					console.debug("Starting the drop", source);
+				});
+				topic.subscribe("/dnd/drop/before", function(source, nodes, copy, target){
+					if(target == c1){
+						console.debug(copy ? "Copying from" : "Moving from", source, "to", target, "before", target.before);
+					}
+				});
+				topic.subscribe("/dnd/drop", function(source, nodes, copy, target){
+					if(target == c1){
+						console.debug(copy ? "Copying from" : "Moving from", source, "to", target, "before", target.before);
+					}
+				});
+				aspect.after(c4, "onDndDrop", function(source, nodes, copy, target){
+					if(target == c4){
+						console.debug(copy ? "Copying from" : "Moving from", source);
+					}
+				}, true);
 			});
-			dojo.subscribe("/dnd/drop", function(source, nodes, copy, target){
-				if(target == c1){
-					console.debug(copy ? "Copying from" : "Moving from", source, "to", target, "before", target.before);
-				}
-			});
-			dojo.connect(c4, "onDndDrop", function(source, nodes, copy, target){
-				if(target == c4){
-					console.debug(copy ? "Copying from" : "Moving from", source);
-				}
-			});
-		}
-
-		dojo.addOnLoad(init);
+		});
 
 	</script>
 </head>
@@ -94,7 +84,7 @@
 		</div>
 		<div style="float: left; margin: 5px;">
 			<h3>Source 2 (copyOnly)</h3>
-			<div dojoType="dojo.dnd.Source" jsId="c2" class="container" copyOnly="true">
+			<div data-dojo-type="dojo/dnd/Source" data-dojo-id="c2" class="container" copyOnly="true">
 				<div class="dojoDndItem">Item <strong>X</strong></div>
 				<div class="dojoDndItem">Item <strong>Y</strong></div>
 				<div class="dojoDndItem">Item <strong>Z</strong></div>
@@ -102,25 +92,30 @@
 		</div>
 		<div style="float: left; margin: 5px;">
 			<h3>Source 3</h3>
-			<div dojoType="dojo.dnd.Source" jsId="c3" class="container">
-				<script type="dojo/method" event="creator" args="item, hint">
+			<script type="dojo/require">
+				dnd: "dojo/dnd/common"
+			</script>
+			<div data-dojo-type="dojo/dnd/Source" data-dojo-id="c3" class="container" allowNested="true">
+				<script type="dojo/method" data-dojo-event="creator" data-dojo-args="item, hint">
 					// this is custom creator, which changes the avatar representation
-					var node = dojo.doc.createElement("div"), s = String(item);
-					node.id = dojo.dnd.getUniqueId();
+					var node = document.createElement("div"), s = String(item);
+					node.id = dnd.getUniqueId();
 					node.className = "dojoDndItem";
 					node.innerHTML = (hint != "avatar" || s.indexOf("Item") < 0) ?
 						s : "<strong style='color: darkred'>Special</strong> " + s;
 					return {node: node, data: item, type: ["text"]};
 				</script>
 				<div class="dojoDndItem">Item <strong>Alpha</strong></div>
-				<div class="dojoDndItem">Item <strong>Beta</strong></div>
-				<div class="dojoDndItem">Item <strong>Gamma</strong></div>
-				<div class="dojoDndItem">Item <strong>Delta</strong></div>
+				<div class="nested">
+					<div class="dojoDndItem">Item <strong>Beta</strong></div>
+					<div class="dojoDndItem">Item <strong>Gamma</strong></div>
+					<div class="dojoDndItem">Item <strong>Delta</strong></div>
+				</div>
 			</div>
 		</div>
 		<div style="float: left; margin: 5px;">
 			<h3>Source 4 (copyOnly, selfAccept, delay=8)</h3>
-			<div dojoType="dojo.dnd.Source" jsId="c4" class="container" copyOnly="true" selfAccept="false" delay="8">
+			<div data-dojo-type="dojo/dnd/Source" data-dojo-id="c4" class="container" copyOnly="true" selfAccept="false" delay="8">
 				<div class="dojoDndItem">Item 1</div>
 				<div class="dojoDndItem">Item 2</div>
 				<div class="dojoDndItem">Item 3</div>
@@ -128,7 +123,7 @@
 		</div>
 		<div style="float: left; margin: 5px;">
 			<h3>Pure Target 5</h3>
-			<div dojoType="dojo.dnd.Target" jsId="c5" class="container">
+			<div data-dojo-type="dojo/dnd/Target" data-dojo-id="c5" class="container">
 				<div class="dojoDndItem">One item</div>
 			</div>
 		</div>
@@ -136,6 +131,98 @@
 	</div>
 
 	<p>HTML after</p>
+	<p>
+		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus.
+	</p>
+	<p>Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
+		imperdiet. Fusce dignissim porta augue. Nulla vestibulum. Integer lorem
+		nunc, ullamcorper a, commodo ac, malesuada sed, dolor. Aenean id mi in
+		massa bibendum suscipit. Integer eros. Nullam suscipit mauris. In
+		pellentesque. Mauris ipsum est, pharetra semper, pharetra in, viverra
+		quis, tellus. Etiam purus. Quisque egestas, tortor ac cursus lacinia,
+		felis leo adipiscing nisi, et rhoncus elit dolor eget eros. Fusce ut
+		quam. Suspendisse eleifend leo vitae ligula. Nulla facilisi. Nulla
+		rutrum, erat vitae lacinia dictum, pede purus imperdiet lacus, ut
+		semper velit ante id metus. Praesent massa dolor, porttitor sed,
+		pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit
+		tortor pharetra congue. Suspendisse pulvinar.
+	</p>
+	<p>Vestibulum convallis eros ac justo. Proin dolor. Etiam aliquam. Nam
+		ornare elit vel augue. Suspendisse potenti. Etiam sed mauris eu neque
+		nonummy mollis. Vestibulum vel purus ac pede semper accumsan. Vivamus
+		lobortis, sem vitae nonummy lacinia, nisl est gravida magna, non cursus
+		est quam sed urna. Phasellus adipiscing justo in ipsum. Duis sagittis
+		dolor sit amet magna. Suspendisse suscipit, neque eu dictum auctor,
+		nisi augue tincidunt arcu, non lacinia magna purus nec magna. Praesent
+		pretium sollicitudin sapien. Suspendisse imperdiet. Class aptent taciti
+		sociosqu ad litora torquent per conubia nostra, per inceptos
+		hymenaeos.
+	</p>
+	<p>Mauris pharetra lorem sit amet sapien. Nulla libero metus, tristique
+		et, dignissim a, tempus et, metus. Ut libero. Vivamus tempus purus vel
+		ipsum. Quisque mauris urna, vestibulum commodo, rutrum vitae, ultrices
+		vitae, nisl. Class aptent taciti sociosqu ad litora torquent per
+		conubia nostra, per inceptos hymenaeos. Nulla id erat sit amet odio
+		luctus eleifend. Proin massa libero, ultricies non, tincidunt a,
+		vestibulum non, tellus. Nunc nunc purus, lobortis a, pulvinar at,
+		egestas a, mi. Cras adipiscing velit a mauris. Morbi felis. Etiam at
+		felis. Cras eget eros et justo mattis pulvinar. Nullam at justo id
+		risus porttitor dignissim. Vestibulum sed velit vel metus tincidunt
+		tempus. Nunc euismod nisl id dolor tristique tincidunt. Nullam placerat
+		turpis sed odio. Curabitur in est id nibh tempus ultrices. Aliquam
+		consectetuer dapibus eros. Aliquam nisl.
+	</p>
 
+	<p>
+		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+		porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+		Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+		Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+		risus.
+	</p>
+	<p>Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
+		imperdiet. Fusce dignissim porta augue. Nulla vestibulum. Integer lorem
+		nunc, ullamcorper a, commodo ac, malesuada sed, dolor. Aenean id mi in
+		massa bibendum suscipit. Integer eros. Nullam suscipit mauris. In
+		pellentesque. Mauris ipsum est, pharetra semper, pharetra in, viverra
+		quis, tellus. Etiam purus. Quisque egestas, tortor ac cursus lacinia,
+		felis leo adipiscing nisi, et rhoncus elit dolor eget eros. Fusce ut
+		quam. Suspendisse eleifend leo vitae ligula. Nulla facilisi. Nulla
+		rutrum, erat vitae lacinia dictum, pede purus imperdiet lacus, ut
+		semper velit ante id metus. Praesent massa dolor, porttitor sed,
+		pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit
+		tortor pharetra congue. Suspendisse pulvinar.
+	</p>
+	<p>Vestibulum convallis eros ac justo. Proin dolor. Etiam aliquam. Nam
+		ornare elit vel augue. Suspendisse potenti. Etiam sed mauris eu neque
+		nonummy mollis. Vestibulum vel purus ac pede semper accumsan. Vivamus
+		lobortis, sem vitae nonummy lacinia, nisl est gravida magna, non cursus
+		est quam sed urna. Phasellus adipiscing justo in ipsum. Duis sagittis
+		dolor sit amet magna. Suspendisse suscipit, neque eu dictum auctor,
+		nisi augue tincidunt arcu, non lacinia magna purus nec magna. Praesent
+		pretium sollicitudin sapien. Suspendisse imperdiet. Class aptent taciti
+		sociosqu ad litora torquent per conubia nostra, per inceptos
+		hymenaeos.
+	</p>
+	<p>Mauris pharetra lorem sit amet sapien. Nulla libero metus, tristique
+		et, dignissim a, tempus et, metus. Ut libero. Vivamus tempus purus vel
+		ipsum. Quisque mauris urna, vestibulum commodo, rutrum vitae, ultrices
+		vitae, nisl. Class aptent taciti sociosqu ad litora torquent per
+		conubia nostra, per inceptos hymenaeos. Nulla id erat sit amet odio
+		luctus eleifend. Proin massa libero, ultricies non, tincidunt a,
+		vestibulum non, tellus. Nunc nunc purus, lobortis a, pulvinar at,
+		egestas a, mi. Cras adipiscing velit a mauris. Morbi felis. Etiam at
+		felis. Cras eget eros et justo mattis pulvinar. Nullam at justo id
+		risus porttitor dignissim. Vestibulum sed velit vel metus tincidunt
+		tempus. Nunc euismod nisl id dolor tristique tincidunt. Nullam placerat
+		turpis sed odio. Curabitur in est id nibh tempus ultrices. Aliquam
+		consectetuer dapibus eros. Aliquam nisl.
+	</p>
 </body>
 </html>
diff --git a/dojo/tests/dnd/test_dnd_handles.html b/dojo/tests/dnd/test_dnd_handles.html
index 44b1d96..a397ec3 100644
--- a/dojo/tests/dnd/test_dnd_handles.html
+++ b/dojo/tests/dnd/test_dnd_handles.html
@@ -14,17 +14,12 @@
 		.clear { clear: both; }
 	</style>
 
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-<!--
-	<script type="text/javascript" src="../../dnd/Container.js"></script>
-	<script type="text/javascript" src="../../dnd/Selector.js"></script>
-	<script type="text/javascript" src="../../dnd/Source.js"></script>
-	<script type="text/javascript" src="../../dnd/Avatar.js"></script>
-	<script type="text/javascript" src="../../dnd/Manager.js"></script>
--->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.parser");
-		dojo.require("dojo.dnd.Source");
+		require(["dojo/parser", "dojo/dnd/Source", "dojo/domReady!"], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
 <body>
@@ -44,7 +39,7 @@
 	</ul>
 	
 	<p>Source with handles. Items should be draggable by the "em" of the word "Item" (and also see a 'move' cursor on it).</p>
-	<div dojoType="dojo.dnd.Source" jsId="c1" withHandles="true" class="container handles">
+	<div data-dojo-type="dojo/dnd/Source" data-dojo-id="c1" withHandles="true" class="container handles">
 		<div class="dojoDndItem"><span class="dojoDndHandle"><span class="dojoDndIgnore">It</span>em</span> <strong>Alpha</strong></div>
 		<div class="dojoDndItem"><span class="dojoDndHandle"><span class="dojoDndIgnore">It</span>em</span> <strong>Beta</strong></div>
 		<div class="dojoDndItem"><span class="dojoDndHandle"><span class="dojoDndIgnore">It</span>em</span> <strong>Gamma</strong></div>
@@ -52,7 +47,7 @@
 	</div>
 
 	<p>Source without handles.</p>
-	<div dojoType="dojo.dnd.Source" jsId="c2" class="container">
+	<div data-dojo-type="dojo/dnd/Source" data-dojo-id="c2" class="container">
 		<div class="dojoDndItem"><span class="dojoDndHandle">Item</span> <strong>Epsilon</strong></div>
 		<div class="dojoDndItem"><span class="dojoDndHandle">Item</span> <strong>Zeta</strong></div>
 		<div class="dojoDndItem"><span class="dojoDndHandle">Item</span> <strong>Eta</strong></div>
diff --git a/dojo/tests/dnd/test_form.html b/dojo/tests/dnd/test_form.html
index 0b0ad70..0e07098 100644
--- a/dojo/tests/dnd/test_form.html
+++ b/dojo/tests/dnd/test_form.html
@@ -17,20 +17,19 @@
 
 	</style>
 
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
-		dojo.require("dojo.parser");
-		dojo.require("dojo.dnd.Source");
+		require(["dojo/parser", "dojo/dnd/Source", "dojo/dnd/Target", "dojo/topic", "dojo/domReady!"], function(parser, Source, Target, topic){
+			parser.parse();
 
-		var c1, c2;
+			var c1, c2;
 	
-		dojo.ready(function(){
-			c1 = new dojo.dnd.Source("container1");
+			c1 = new Source("container1");
 			c1.insertNodes(false, [1, 2, 3, 4, 5, 6, [1, 2, 3], function(x){ return x + x; }]);
-			c2 = new dojo.dnd.Target("container2", {accept: ["money"]});
+			c2 = new Target("container2", {accept: ["money"]});
 
 			// example subscribe to events
-			dojo.subscribe("/dnd/start",function(foo){
+			topic.subscribe("/dnd/start",function(foo){
 				console.debug(foo);
 			});
 		});
@@ -59,7 +58,7 @@
 				Input button: <input type="button" value="Button" /><br />
 				Input reset: <input type="reset" /><br />
 				Input submit: <input type="submit" /><br />
-				Input image: <input type="image" src="http://dojotoolkit.org/misc/feed.png" /><br />
+				Input image: <input type="image" src="http://dojotoolkit.org/images/logo.png" /><br />
 				Button: <button>Button</button><br />
 				Select: <select><option>Yes</option><option>No</option></select><br />
 				Textarea: <textarea cols="20" rows="3">Some text.</textarea>
@@ -70,7 +69,7 @@
 	
 	<p> </p>
 	
-	<div dojoType="dojo.dnd.Source" class="container">
+	<div data-dojo-type="dojo/dnd/Source" class="container">
 		<div>Source with <strong>skipForm = false</strong> (by default)</div>
 		<div class="dojoDndItem">Item <strong>X</strong>: <input type="text" value="1" /></div>
 		<div class="dojoDndItem">Item <strong>Y</strong>: <input type="text" value="2" /></div>
@@ -79,7 +78,7 @@
 
 	<p> </p>
 	
-	<div dojoType="dojo.dnd.Source" class="container" skipForm="true">
+	<div data-dojo-type="dojo/dnd/Source" class="container" skipForm="true">
 		<div>Source with <strong>skipForm = true</strong></div>
 		<div class="dojoDndItem">Item <strong>A</strong>: <input type="text" value="a" /></div>
 		<div class="dojoDndItem">Item <strong>B</strong>: <input type="text" value="b" /></div>
diff --git a/dojo/tests/dnd/test_moveable.html b/dojo/tests/dnd/test_moveable.html
index 336a95b..710d528 100644
--- a/dojo/tests/dnd/test_moveable.html
+++ b/dojo/tests/dnd/test_moveable.html
@@ -47,35 +47,30 @@
 			font-weight: bold;
 		}
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true"></script>
-	<!--
-	<script type="text/javascript" src="../../dnd/Mover.js"></script>
-	<script type="text/javascript" src="../../dnd/Moveable.js"></script>
-	<script type="text/javascript" src="../../dnd/move.js"></script>
-	-->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.dnd.move");
-		var m1, m2;
-		var init = function(){
-			m1 = new dojo.dnd.Moveable("moveable1", {handle: "handle1"});
-			m2 = new dojo.dnd.Moveable("moveable2");
-			m3 = new dojo.dnd.Moveable("moveable3");
+		require(["dojo/aspect", "dojo/dnd/Moveable", "dojo/topic", "dojo/domReady!"], function(aspect, Moveable, topic){
+			var m1, m2, m3;
+
+			m1 = new Moveable("moveable1", {handle: "handle1"});
+			m2 = new Moveable("moveable2");
+			m3 = new Moveable("moveable3");
 
-			dojo.subscribe("/dnd/move/start", function(mover){
+			topic.subscribe("/dnd/move/start", function(mover){
 				console.debug("Start move", mover, mover.node);
 			});
-			dojo.subscribe("/dnd/move/stop", function(mover){
+			topic.subscribe("/dnd/move/stop", function(mover){
 				console.debug("Stop move", mover, mover.node);
 			});
 			
-			dojo.connect(m1, "onMoveStart", function(mover){
+			aspect.after(m1, "onMoveStart", function(mover){
 				console.debug("Start moving m1", mover, mover.node);
-			});
-			dojo.connect(m1, "onMoveStop", function(mover){
+			}, true);
+			aspect.after(m1, "onMoveStop", function(mover){
 				console.debug("Stop moving m1", mover, mover.node);
-			});
-		};
-		dojo.addOnLoad(init);
+			}, true);
+		});
 	</script>
 </head>
 <body>
diff --git a/dojo/tests/dnd/test_moveable_markup.html b/dojo/tests/dnd/test_moveable_markup.html
index 96be17f..46dbe20 100644
--- a/dojo/tests/dnd/test_moveable_markup.html
+++ b/dojo/tests/dnd/test_moveable_markup.html
@@ -39,20 +39,17 @@
 			-moz-border-radius:8pt 8pt; 
 		}
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-	<!--
-	<script type="text/javascript" src="../../dnd/move.js"></script>
-	-->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.parser");
-		dojo.require("dojo.dnd.move");
+		require(["dojo/parser", "dojo/topic", "dojo/dnd/Moveable", "dojo/domReady!"], function(parser, topic){
+			parser.parse();
 
-		dojo.addOnLoad(function(){
-			dojo.subscribe("/dnd/move/start", function(node){ 
+			topic.subscribe("/dnd/move/start", function(node){ 
 				console.debug("Start move", node); 	
 			});
 
-			dojo.subscribe("/dnd/move/stop", function(node){ 
+			topic.subscribe("/dnd/move/stop", function(node){ 
 				console.debug("Stop move", node); 	
 			});
 		});
@@ -66,7 +63,7 @@
 	<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec est. Cras semper nunc ut metus. Pellentesque blandit pede at erat. Quisque nonummy leo id metus. Donec mi mi, viverra id, adipiscing vitae, consectetuer ut, elit. In lectus augue, porttitor quis, viverra id, dignissim id, leo. Maecenas sapien. Nam adipiscing sem. Aenean ligula. Etiam vel velit. In mollis cursus dolor. Suspendisse ac nibh id leo tempor posuere. Aliquam sapien tellus, el [...]
 	<p>Duis ac augue rhoncus neque adipiscing feugiat. Donec pulvinar sem vitae neque. Donec commodo metus at ipsum. Cras vel magna vehicula lorem varius consequat. Morbi at enim vitae lectus mollis sodales. Sed tincidunt quam ut mi varius hendrerit. Sed porta arcu non libero. Quisque et wisi. Pellentesque lobortis. Ut enim felis, varius vitae, ornare quis, auctor ut, risus. Ut porta lorem vel quam. Etiam nunc purus, consectetuer non, lobortis eu, fermentum eu, magna. Aenean ultrices ante.  [...]
 	<p>Quisque egestas turpis. Sed id ipsum id libero euismod nonummy. Nam sed dolor. Mauris in turpis. Duis nec wisi eget ante ultrices varius. Ut eget neque. Suspendisse sagittis iaculis tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus at justo. Donec imperdiet, elit et commodo bibendum, leo augue pellentesque arcu, ac dapibus lorem nulla eget erat. In viverra, tellus eu luctus eleifend, urna nibh lobortis sapien, ac pulvinar massa  [...]
-	<table id="moveable1" dojoType="dojo.dnd.Moveable" handle="handle1">
+	<table id="moveable1" data-dojo-type="dojo/dnd/Moveable" handle="handle1">
 		<tr><td id="handle1" colspan="2">You can drag the table using this handle.</td></tr>
 		<tr><td>1</td><td>Lorem ipsum dolor sit amet...</td></tr>
 		<tr><td>2</td><td>Mauris vulputate elit a risus...</td></tr>
@@ -80,6 +77,6 @@
 	<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec est. Cras semper nunc ut metus. Pellentesque blandit pede at erat. Quisque nonummy leo id metus. Donec mi mi, viverra id, adipiscing vitae, consectetuer ut, elit. In lectus augue, porttitor quis, viverra id, dignissim id, leo. Maecenas sapien. Nam adipiscing sem. Aenean ligula. Etiam vel velit. In mollis cursus dolor. Suspendisse ac nibh id leo tempor posuere. Aliquam sapien tellus, el [...]
 	<p>Duis ac augue rhoncus neque adipiscing feugiat. Donec pulvinar sem vitae neque. Donec commodo metus at ipsum. Cras vel magna vehicula lorem varius consequat. Morbi at enim vitae lectus mollis sodales. Sed tincidunt quam ut mi varius hendrerit. Sed porta arcu non libero. Quisque et wisi. Pellentesque lobortis. Ut enim felis, varius vitae, ornare quis, auctor ut, risus. Ut porta lorem vel quam. Etiam nunc purus, consectetuer non, lobortis eu, fermentum eu, magna. Aenean ultrices ante.  [...]
 	<p>Quisque egestas turpis. Sed id ipsum id libero euismod nonummy. Nam sed dolor. Mauris in turpis. Duis nec wisi eget ante ultrices varius. Ut eget neque. Suspendisse sagittis iaculis tellus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Phasellus at justo. Donec imperdiet, elit et commodo bibendum, leo augue pellentesque arcu, ac dapibus lorem nulla eget erat. In viverra, tellus eu luctus eleifend, urna nibh lobortis sapien, ac pulvinar massa  [...]
-	<div id="moveable2" dojoType="dojo.dnd.Moveable">You can drag this whole paragraph around.</div>	
+	<div id="moveable2" data-dojo-type="dojo/dnd/Moveable">You can drag this whole paragraph around.</div>
 </body>
 </html>
diff --git a/dojo/tests/dnd/test_params.html b/dojo/tests/dnd/test_params.html
index a4049df..7ed3930 100644
--- a/dojo/tests/dnd/test_params.html
+++ b/dojo/tests/dnd/test_params.html
@@ -17,20 +17,18 @@
 			cursor: pointer;
 		}
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
 	<!--
 	<script type="text/javascript" src="../../dnd/move.js"></script>
 	-->
 	<script type="text/javascript">
-		dojo.require("dojo.dnd.move");
-		var m1, m2, m3, m4;
-		var init = function(){
-			m1 = new dojo.dnd.Moveable("moveable1");
-			m2 = new dojo.dnd.Moveable("moveable2", {delay: 10});
-			m3 = new dojo.dnd.Moveable("moveable3");
-			m4 = new dojo.dnd.Moveable("moveable4", {skip: true});
-		};
-		dojo.addOnLoad(init);
+		require(["dojo/dnd/Moveable", "dojo/domReady!"], function(Moveable){
+			var m1, m2, m3, m4;
+			m1 = new Moveable("moveable1");
+			m2 = new Moveable("moveable2", {delay: 10});
+			m3 = new Moveable("moveable3");
+			m4 = new Moveable("moveable4", {skip: true});
+		});
 	</script>
 </head>
 <body>
diff --git a/dojo/tests/dnd/test_parent_constraints.html b/dojo/tests/dnd/test_parent_constraints.html
index 03abd75..df44433 100644
--- a/dojo/tests/dnd/test_parent_constraints.html
+++ b/dojo/tests/dnd/test_parent_constraints.html
@@ -26,20 +26,16 @@
 			margin: 10px;
 		}
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true"></script>
-	<!--
-	<script type="text/javascript" src="../../dnd/move.js"></script>
-	-->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.dnd.move");
-		var m1, m2, m3, m4;
-		var init = function(){
-			m1 = new dojo.dnd.move.parentConstrainedMoveable("moveable1", {area: "margin", within: true});
-			m2 = new dojo.dnd.move.parentConstrainedMoveable("moveable2", {area: "border", within: true});
-			m3 = new dojo.dnd.move.parentConstrainedMoveable("moveable3", {area: "padding", within: true});
-			m4 = new dojo.dnd.move.parentConstrainedMoveable("moveable4", {area: "content", within: true});
-		};
-		dojo.addOnLoad(init);
+		require(["dojo/dnd/move", "dojo/domReady!"], function(move){
+			var m1, m2, m3, m4;
+			m1 = new move.parentConstrainedMoveable("moveable1", {area: "margin", within: true});
+			m2 = new move.parentConstrainedMoveable("moveable2", {area: "border", within: true});
+			m3 = new move.parentConstrainedMoveable("moveable3", {area: "padding", within: true});
+			m4 = new move.parentConstrainedMoveable("moveable4", {area: "content", within: true});
+		});
 	</script>
 </head>
 <body>
diff --git a/dojo/tests/dnd/test_parent_constraints_margins.html b/dojo/tests/dnd/test_parent_constraints_margins.html
index fa5ec05..7e1ffb5 100644
--- a/dojo/tests/dnd/test_parent_constraints_margins.html
+++ b/dojo/tests/dnd/test_parent_constraints_margins.html
@@ -27,18 +27,14 @@
 			overflow: hidden;
 		}
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true"></script>
-	<!--
-	<script type="text/javascript" src="../../dnd/move.js"></script>
-	-->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.dnd.move");
-		var m7, m8;
-		var init = function(){
-			m7 = new dojo.dnd.move.parentConstrainedMoveable("moveable7", {area: "margin"});
-			m8 = new dojo.dnd.move.parentConstrainedMoveable("moveable8", {area: "margin", within: true});
-		};
-		dojo.addOnLoad(init);
+		require(["dojo/dnd/move", "dojo/domReady!"], function(move){
+			var m7, m8;
+			m7 = new move.parentConstrainedMoveable("moveable7", {area: "margin"});
+			m8 = new move.parentConstrainedMoveable("moveable8", {area: "margin", within: true});
+		});
 	</script>
 </head>
 <body>
diff --git a/dojo/tests/dnd/test_selector.html b/dojo/tests/dnd/test_selector.html
index 90be71e..216c0b7 100644
--- a/dojo/tests/dnd/test_selector.html
+++ b/dojo/tests/dnd/test_selector.html
@@ -8,23 +8,17 @@
 
 		body { padding: 20px; }
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true"></script>
-	<!--
-	<script type="text/javascript" src="../../dnd/common.js"></script>
-	<script type="text/javascript" src="../../dnd/Container.js"></script>
-	<script type="text/javascript" src="../../dnd/Selector.js"></script>
-	-->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.dnd.Selector");
-		var c1, c2, c3, c4, c5;
-		var init = function(){
-			c1 = new dojo.dnd.Selector(dojo.byId("container1"), {singular: true});
-			c2 = new dojo.dnd.Selector(dojo.byId("container2"));
-			c3 = new dojo.dnd.Selector(dojo.byId("container3"));
-			c4 = new dojo.dnd.Selector(dojo.byId("container4"));
-			c5 = new dojo.dnd.Selector(dojo.byId("container5"));
-		};
-		dojo.addOnLoad(init);
+		require(["dojo/dnd/Selector", "dojo/dom", "dojo/domReady!"], function(Selector, dom){
+			var c1, c2, c3, c4, c5;
+			c1 = new Selector(dom.byId("container1"), {singular: true});
+			c2 = new Selector(dom.byId("container2"));
+			c3 = new Selector(dom.byId("container3"));
+			c4 = new Selector(dom.byId("container4"));
+			c5 = new Selector(dom.byId("container5"));
+		});
 	</script>
 </head>
 <body>
diff --git a/dojo/tests/dnd/test_selector_markup.html b/dojo/tests/dnd/test_selector_markup.html
index 9c42159..f4cce02 100644
--- a/dojo/tests/dnd/test_selector_markup.html
+++ b/dojo/tests/dnd/test_selector_markup.html
@@ -8,13 +8,12 @@
 
 		body { padding: 20px; }
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-	<!--
-	<script type="text/javascript" src="../../dnd/Selector.js"></script>
-	-->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.parser");
-		dojo.require("dojo.dnd.Selector");
+		require(["dojo/parser", "dojo/dnd/Selector", "dojo/domReady!"], function(parser){
+			parser.parse();
+		});
 	</script>
 </head>
 <body>
@@ -30,25 +29,25 @@
 	</ul>
 	<h2>DIV selector</h2>
 	<p>This selector can select just one element a time. It was specified during the creation time.</p>
-	<div dojoType="dojo.dnd.Selector" jsId="c1" singular="true" class="container">
+	<div data-dojo-type="dojo/dnd/Selector" data-dojo-id="c1" singular="true" class="container">
 		<div class="dojoDndItem">Item 1</div>
 		<div class="dojoDndItem">Item 2</div>
 		<div class="dojoDndItem">Item 3</div>
 	</div>
 	<h2>UL selector</h2>
-	<ul dojoType="dojo.dnd.Selector" jsId="c2" class="container">
+	<ul data-dojo-type="dojo/dnd/Selector" data-dojo-id="c2" class="container">
 		<li class="dojoDndItem">Item 1</li>
 		<li class="dojoDndItem">Item 2</li>
 		<li class="dojoDndItem">Item 3</li>
 	</ul>
 	<h2>OL selector</h2>
-	<ol dojoType="dojo.dnd.Selector" jsId="c3" class="container">
+	<ol data-dojo-type="dojo/dnd/Selector" data-dojo-id="c3" class="container">
 		<li class="dojoDndItem">Item 1</li>
 		<li class="dojoDndItem">Item 2</li>
 		<li class="dojoDndItem">Item 3</li>
 	</ol>
 	<h2>TABLE selector</h2>
-	<table dojoType="dojo.dnd.Selector" jsId="c4" class="container" border="1px solid black">
+	<table data-dojo-type="dojo/dnd/Selector" data-dojo-id="c4" class="container" border="1px solid black">
 		<tr class="dojoDndItem">
 			<td>A</td>
 			<td>row 1</td>
@@ -64,7 +63,7 @@
 	</table>
 	<h2>P selector with SPAN elements</h2>
 	<p>Elements of this container are layed out horizontally.</p>
-	<p dojoType="dojo.dnd.Selector" jsId="c5" class="container">
+	<p data-dojo-type="dojo/dnd/Selector" data-dojo-id="c5" class="container">
 		<span class="dojoDndItem"> Item 1 </span>
 		<span class="dojoDndItem"> Item 2 </span>
 		<span class="dojoDndItem"> Item 3 </span>
diff --git a/dojo/tests/dnd/test_timed_moveable.html b/dojo/tests/dnd/test_timed_moveable.html
index f6c921f..e5e2837 100644
--- a/dojo/tests/dnd/test_timed_moveable.html
+++ b/dojo/tests/dnd/test_timed_moveable.html
@@ -53,36 +53,30 @@
 			-moz-border-radius:8pt 8pt; 
 		}
 	</style>
-	<script type="text/javascript" src="../../dojo.js" djConfig="isDebug: true"></script>
-	<!--
-	<script type="text/javascript" src="../../dnd/Mover.js"></script>
-	<script type="text/javascript" src="../../dnd/Moveable.js"></script>
-	<script type="text/javascript" src="../../dnd/TimedMoveable.js"></script>
-	<script type="text/javascript" src="../../dnd/move.js"></script>
-	-->
+	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
-		dojo.require("dojo.dnd.TimedMoveable");
-		var m1, m2;
-		var init = function(){
-			m1 = new dojo.dnd.TimedMoveable("moveable1", {handle: "handle1"});
-			m2 = new dojo.dnd.TimedMoveable("moveable2");
-			m3 = new dojo.dnd.TimedMoveable("moveable3", {timeout: 500});
+		require(["dojo/aspect", "dojo/dnd/TimedMoveable", "dojo/topic", "dojo/domReady!"], function(aspect, TimedMoveable, topic){
+			var m1, m2, m3;
+
+			m1 = new TimedMoveable("moveable1", {handle: "handle1"});
+			m2 = new TimedMoveable("moveable2");
+			m3 = new TimedMoveable("moveable3", {timeout: 500});
 
-			dojo.subscribe("/dnd/move/start", function(mover){ 
+			topic.subscribe("/dnd/move/start", function(mover){ 
 				console.debug("Start move", mover); 	
 			});
-			dojo.subscribe("/dnd/move/stop", function(mover){ 
+			topic.subscribe("/dnd/move/stop", function(mover){ 
 				console.debug("Stop move", mover); 	
 			});
 			
-			dojo.connect(m1, "onMoveStart", function(mover){
+			aspect.after(m1, "onMoveStart", function(mover){
 				console.debug("Start moving m1", mover); 	
-			});
-			dojo.connect(m1, "onMoveStop", function(mover){
+			}, true);
+			aspect.after(m1, "onMoveStop", function(mover){
 				console.debug("Stop moving m1", mover); 	
-			});
-		};
-		dojo.addOnLoad(init);
+			}, true);
+		});
 	</script>
 </head>
 <body>
diff --git a/dojo/tests/dom-style.html b/dojo/tests/dom-style.html
new file mode 100644
index 0000000..86849e4
--- /dev/null
+++ b/dojo/tests/dom-style.html
@@ -0,0 +1,43 @@
+<html>
+	<head>
+		<title>testing dom-style</title>
+		<style type="text/css">
+			@import "../resources/dojo.css";
+			.nodeStyle
+			{
+				padding: 1px 2px 3px 4px;
+			}
+		</style>
+		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug:true"></script>
+		<script type="text/javascript">
+			require(["dojo", "doh", "dojo/dom-style", "dojo/dom", "dojo/domReady!"], function(dojo, doh, domStyle, dom){
+				doh.register([
+					{
+						name: "getComputedStyle",
+						runTest: function(t){
+							try {
+								var node = dom.byId('node'),
+									s = domStyle.getComputedStyle(node);
+								doh.t(s !== null);
+								// Create a node on the fly,
+								// IE < 9 has issue with currentStyle when creating elements on the fly.
+								node = document.createElement('div');
+								domStyle.set(node, 'nodeStyle');
+								s = domStyle.getComputedStyle(node);
+								doh.t(s !== null);
+							} catch (err) {
+								console.error(err);
+								doh.t(false);
+							}
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+	<body>
+	<div id="node" style="padding: 1px 2px 3px 4px;"></div>
+	</body>
+</html>
diff --git a/dojo/tests/dom-style.js b/dojo/tests/dom-style.js
new file mode 100644
index 0000000..7c80526
--- /dev/null
+++ b/dojo/tests/dom-style.js
@@ -0,0 +1,5 @@
+define(["doh/main", "require"], function(doh, require){
+	if(doh.isBrowser){
+		doh.register("tests.dom-style", require.toUrl("./dom-style.html"), 30000);
+	}
+});
diff --git a/dojo/tests/errors.js b/dojo/tests/errors.js
new file mode 100644
index 0000000..6b3c14b
--- /dev/null
+++ b/dojo/tests/errors.js
@@ -0,0 +1,47 @@
+define([
+	"../errors/create",
+	"doh"
+], function(create, doh){
+	var TestError = create("TestError", function(message, foo){
+		this.foo = foo;
+	});
+
+	var OtherError = create("OtherError", function(message, foo, bar){
+		this.bar = bar;
+	}, TestError, {
+		getBar: function(){
+			return this.bar;
+		}
+	});
+
+	var testError = new TestError("hello", "asdf"),
+		otherError = new OtherError("goodbye", "qwerty", "blah");
+
+	doh.register("tests.errors", [
+		{
+			name: "TestError",
+			runTest: function(t){
+				t.t(testError instanceof Error, "testError should be an instance of Error");
+				t.t(testError instanceof TestError, "testError should be an instance of TestError");
+				t.f(testError instanceof OtherError, "testError should not be an instance of OtherError");
+				t.f("getBar" in testError, "testError should not have a 'getBar' property");
+				t.is("hello", testError.message, "testError's message property should be 'hello'");
+				if((new Error()).stack){
+					t.t(!!testError.stack, "custom error should have stack set");
+				}
+			}
+		},
+		{
+			name: "OtherError",
+			runTest: function(t){
+				t.t(otherError instanceof Error, "otherError should be an instance of Error");
+				t.t(otherError instanceof TestError, "otherError should be an instance of TestError");
+				t.t(otherError instanceof OtherError, "otherError should be an instance of OtherError");
+				t.t("getBar" in otherError, "otherError should have a 'getBar' property");
+				t.f(otherError.hasOwnProperty("getBar"), "otherError should not have a 'getBar' own property");
+				t.is("blah", otherError.getBar(), "otherError should return 'blah' from getBar()");
+				t.is("goodbye", otherError.message, "otherError's message property should be 'goodbye'");
+			}
+		}
+	]);
+});
diff --git a/dojo/tests/fx.html b/dojo/tests/fx.html
index 770393e..7b3ae72 100644
--- a/dojo/tests/fx.html
+++ b/dojo/tests/fx.html
@@ -2,39 +2,44 @@
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>Testing dojo.fx</title>
+		<title>Testing fx</title>
 		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/fx", "dojo/fx/easing", "dojo/domReady!"], function(dojo, doh){
+			require([
+				"doh",
+				"dojo/_base/array", "dojo/aspect", "dojo/dom", "dojo/dom-style",
+				"dojo/_base/fx", "dojo/fx", "dojo/fx/easing", "dojo/fx/Toggler", "dojo/_base/lang",
+				"dojo/domReady!"
+			], function(doh, array, aspect, dom, domStyle, baseFx, fx, easing, Toggler, lang){
 				doh.register("t", 
 					[
 						function slideTo(t){
-							var s = dojo.fx.slideTo({
+							var s = fx.slideTo({
 								node: "foo",
 								duration: 500,
 								left: 500,
 								top: 50
 							}).play();
 							var d = new doh.Deferred();
-							dojo.connect(s, "onEnd", function(){
-								doh.is(dojo.style("foo", "left"), 500);
-								doh.is(dojo.style("foo", "top"), 50);
-								with(dojo.byId("foo").style){
+							aspect.after(s, "onEnd", function(){
+								doh.is(domStyle.get("foo", "left"), 500);
+								doh.is(domStyle.get("foo", "top"), 50);
+								with(dom.byId("foo").style){
 									position = left = top = "";
 								}
 								d.callback(true);
-							});
+							}, true);
 							s.play();
 							return d;
 						},
 
 						function wipeOut(t){
-							dojo.byId("foo").style.height = "";
+							dom.byId("foo").style.height = "";
 							var d = new doh.Deferred();
-							var s = dojo.fx.wipeOut({
+							var s = fx.wipeOut({
 								node: "foo",
 								onEnd: function(){
-									doh.t(dojo.style("foo", "height") < 5);
+									doh.t(domStyle.get("foo", "height") < 5);
 									d.callback(true);
 								}
 							}).play();
@@ -44,11 +49,11 @@
 						function wipeIn(t){
 							var d = new doh.Deferred();
 							setTimeout(function(){
-								dojo.fx.wipeIn({
+								fx.wipeIn({
 									node: "foo", 
 									onEnd: function(){
-										console.debug(dojo.style("foo", "height"));
-										doh.t(dojo.style("foo", "height") > 10);
+										console.debug(domStyle.get("foo", "height"));
+										doh.t(domStyle.get("foo", "height") > 10);
 										d.callback(true);
 									}
 								}).play();
@@ -60,18 +65,18 @@
 							name: "chain",
 							timeout: 1500,
 							runTest: function(t){
-								dojo.byId("foo").style.height = "0px";
+								dom.byId("foo").style.height = "0px";
 								var d = new doh.Deferred();
-								var w = dojo.fx.wipeIn({
+								var w = fx.wipeIn({
 									node: "foo",
 									duration: 500
 								});
-								var f = dojo.fadeOut({
+								var f = baseFx.fadeOut({
 									node: "foo",
 									duration: 500
 								});
-								var a = dojo.fx.chain([w,f]);
-								dojo.connect(a, "onEnd", function(){
+								var a = fx.chain([w,f]);
+								aspect.after(a, "onEnd", function(){
 									doh.t((w.status()=="stopped"&&f.status()=="stopped"));
 									d.callback(true);
 								});
@@ -84,21 +89,21 @@
 							name: "combine",
 							timeout: 1500,
 							runTest: function(t){
-								dojo.byId("foo").style.height = "0px";
+								dom.byId("foo").style.height = "0px";
 								var d = new doh.Deferred();
-								var w = dojo.fx.wipeIn({
+								var w = fx.wipeIn({
 									node: "foo",
 									duration: 500
 								});
-								var f = dojo.fadeIn({
+								var f = baseFx.fadeIn({
 									node: "foo",
 									duration: 1000
 								});
-								var a = dojo.fx.combine([w,f]);
-								dojo.connect(a, "onEnd", function(){
+								var a = fx.combine([w,f]);
+								aspect.after(a, "onEnd", function(){
 									doh.t((w.status()=="stopped"&&f.status()=="stopped"));
 									d.callback(true);
-								});
+								}, true);
 								a.play();
 								return d;
 							}
@@ -108,10 +113,10 @@
 							timeout:1500,
 							runTest: function(t){
 								var d = new doh.Deferred();
-								var a = dojo.fadeOut({ node:"foo2", duration:400 });
-								var b = dojo.fadeIn({ node:"foo2", duration:400 });
-								var chain = dojo.fx.combine([a,b]);
-								dojo.connect(chain,"beforeBegin",dojo.hitch(d,"callback",true));
+								var a = baseFx.fadeOut({ node:"foo2", duration:400 });
+								var b = baseFx.fadeIn({ node:"foo2", duration:400 });
+								var chain = fx.combine([a,b]);
+								aspect.after(chain,"beforeBegin",lang.hitch(d,"callback",true), true);
 								chain.play();
 								return d;
 							}
@@ -125,15 +130,15 @@
 								var delay = 100;
 								var _anims = [];
 								var nodes = ["a","b","c","d"];
-								dojo.forEach(nodes,function(n){
-									_anims.push(dojo.fadeOut({ node:n, duration:100, delay: delay += 100 }));
+								array.forEach(nodes,function(n){
+									_anims.push(baseFx.fadeOut({ node:n, duration:100, delay: delay += 100 }));
 								});
-								var a = dojo.fx.combine(_anims);
+								var a = fx.combine(_anims);
 								var timer = (new Date()).getTime();
-								dojo.connect(a,"onEnd",function(){
+								aspect.after(a,"onEnd",function(){
 									console.warn("delayTest running time:", (new Date()).getTime() - timer, "ms, expected:", a.duration, "ms");
 									d.callback(true);
-								});
+								}, true);
 								a.play();
 								return d;	
 							}
@@ -146,15 +151,15 @@
 								var delay = 100;
 								var _anims = [];
 								var nodes = ["a","b","c","d"];
-								dojo.forEach(nodes,function(n){
-									_anims.push(dojo.fadeIn({ node:n, duration:100, delay: delay += 100 }));
+								array.forEach(nodes,function(n){
+									_anims.push(baseFx.fadeIn({ node:n, duration:100, delay: delay += 100 }));
 								});
-								var a = dojo.fx.chain(_anims);
+								var a = fx.chain(_anims);
 								var timer = (new Date()).getTime();
-								dojo.connect(a,"onEnd",function(){
+								aspect.after(a,"onEnd",function(){
 									console.warn("delayTestChain running time:", (new Date()).getTime() - timer, "ms, expected:", a.duration, "ms");
 									d.callback(true);
-								});
+								}, true);
 								a.play();
 								return d;
 							}
@@ -164,10 +169,10 @@
 							timeout:1500,
 							runTest: function(t){
 								var d = new doh.Deferred();
-								var a = dojo.fadeOut({ node:"foo2", duration:400 });
-								var b = dojo.fadeIn({ node:"foo2", duration:400 });
-								var combine = dojo.fx.combine([a,b]);
-								dojo.connect(combine,"onEnd",dojo.hitch(d,"callback",true));
+								var a = baseFx.fadeOut({ node:"foo2", duration:400 });
+								var b = baseFx.fadeIn({ node:"foo2", duration:400 });
+								var combine = fx.combine([a,b]);
+								aspect.after(combine,"onEnd",lang.hitch(d,"callback",true), true);
 								combine.play();
 								return d;
 							}
@@ -178,10 +183,10 @@
 							timeout:1500,
 							runTest: function(t){
 								var d = new doh.Deferred();
-								var a = dojo.fadeOut({ node:"foo2", duration:400 });
-								var b = dojo.fadeIn({ node:"foo2", duration:400 });
-								var combine = dojo.fx.combine([a,b]);
-								dojo.connect(combine,"onPlay",dojo.hitch(d,"callback",true));
+								var a = baseFx.fadeOut({ node:"foo2", duration:400 });
+								var b = baseFx.fadeIn({ node:"foo2", duration:400 });
+								var combine = fx.combine([a,b]);
+								aspect.after(combine,"onPlay",lang.hitch(d,"callback",true), true);
 								combine.play();
 								return d;
 							}
@@ -192,10 +197,10 @@
 							timeout:1500,
 							runTest: function(t){
 								var d = new doh.Deferred();
-								var a = dojo.fadeOut({ node:"foo2", duration:400 });
-								var b = dojo.fadeIn({ node:"foo2", duration:400 });
-								var chain = dojo.fx.chain([a,b]);
-								dojo.connect(chain,"onEnd",dojo.hitch(d,"callback",true));
+								var a = baseFx.fadeOut({ node:"foo2", duration:400 });
+								var b = baseFx.fadeIn({ node:"foo2", duration:400 });
+								var chain = fx.chain([a,b]);
+								aspect.after(chain,"onEnd",lang.hitch(d,"callback",true), true);
 								chain.play();
 								return d;
 							}
@@ -207,10 +212,10 @@
 							runTest: function(t){
 
 								var d = new doh.Deferred();
-								var a = dojo.fadeOut({ node:"foo2", duration:200 });
-								var b = dojo.fadeIn({ node:"foo2", duration:200 });
-								var chain = dojo.fx.chain([a,b]);
-								dojo.connect(chain,"onPlay",dojo.hitch(d,"callback",true));
+								var a = baseFx.fadeOut({ node:"foo2", duration:200 });
+								var b = baseFx.fadeIn({ node:"foo2", duration:200 });
+								var chain = fx.chain([a,b]);
+								aspect.after(chain,"onPlay",lang.hitch(d,"callback",true), true);
 								chain.play();
 								return d;
 							}
@@ -223,8 +228,8 @@
 							runTest: function(t){
 								
 								var d = new doh.Deferred();
-								var a = dojo.fadeOut({ node: "foo2", delay:400 });
-								dojo.connect(a, "onPlay", dojo.hitch(d, "errback", true));
+								var a = baseFx.fadeOut({ node: "foo2", delay:400 });
+								aspect.after(a, "onPlay", lang.hitch(d, "errback", true), true);
 								a.play(); 
 								a.stop();
 								setTimeout(function(){
@@ -240,8 +245,8 @@
 							runTest: function(t){
 							
 								var d = new doh.Deferred();
-								var b = dojo.fadeIn({ node: "foo2" });
-								dojo.connect(b, "onPlay", dojo.hitch(d, "errback", true));
+								var b = baseFx.fadeIn({ node: "foo2" });
+								aspect.after(b, "onPlay", lang.hitch(d, "errback", true), true);
 								b.play(400); 
 								b.stop();
 								setTimeout(function(){
@@ -252,68 +257,68 @@
 							
 						},
 						
-						function Toggler(){
+						function testToggler(){
 							var d = new doh.Deferred();
-							var t = new dojo.fx.Toggler({
+							var t = new Toggler({
 								node: "foo",
 								hideDuration: 100,
-								hideFunc: dojo.fx.wipeOut,
-								showFunc: dojo.fx.wipeIn 
+								hideFunc: fx.wipeOut,
+								showFunc: fx.wipeIn 
 							});
 							t.hide();
 							setTimeout(function(){
 								var sa = t.show();
-								dojo.connect(sa, "onEnd", dojo.hitch(d, "callback", true));
+								aspect.after(sa, "onEnd", lang.hitch(d, "callback", true), true);
 							}, 50);
 							return d;
 						},
 						
 						function combineChain(t){
 							// test combining two chained() animations
-							var anim1 = dojo.fx.chain([
-								dojo.fadeIn({ node:"chained" }),
-								dojo.fadeOut({ node:"chained" })
+							var anim1 = fx.chain([
+								baseFx.fadeIn({ node:"chained" }),
+								baseFx.fadeOut({ node:"chained" })
 							]);
-							var anim2 = dojo.fx.chain([
-								dojo.fadeOut({ node:"chainedtoo" }),
-								dojo.fadeIn({ node:"chainedtoo" })
+							var anim2 = fx.chain([
+								baseFx.fadeOut({ node:"chainedtoo" }),
+								baseFx.fadeIn({ node:"chainedtoo" })
 							]);
 							
-							var anim = dojo.fx.combine([anim1, anim2]);
+							var anim = fx.combine([anim1, anim2]);
 
 							var d = new doh.Deferred();
-							dojo.connect(anim, "onEnd", dojo.hitch(d, "callback", true));
+							aspect.after(anim, "onEnd", lang.hitch(d, "callback", true), true);
 							anim.play();
 						},
 						
 						function chainCombine(t){
 							// test chaining two combined() animations
-							var anim1 = dojo.fx.combine([
-								dojo.fadeIn({ node:"chained" }),
-								dojo.fadeOut({ node:"chainedtoo" })
+							var anim1 = fx.combine([
+								baseFx.fadeIn({ node:"chained" }),
+								baseFx.fadeOut({ node:"chainedtoo" })
 							]);
-							var anim2 = dojo.fx.combine([
-								dojo.fadeOut({ node:"chained" }),
-								dojo.fadeIn({ node:"chainedtoo" })
+							var anim2 = fx.combine([
+								baseFx.fadeOut({ node:"chained" }),
+								baseFx.fadeIn({ node:"chainedtoo" })
 							]);
 							
-							var anim = dojo.fx.chain([anim1, anim2]);
+							var anim = fx.chain([anim1, anim2]);
 
 							var d = new doh.Deferred();
-							dojo.connect(anim, "onEnd", dojo.hitch(d, "callback", true));
+							aspect.after(anim, "onEnd", lang.hitch(d, "callback", true), true);
 							anim.play();
 
 						},
 						
 						function easingNames(t){
-							for(var i in dojo.fx.easing){
-								t.assertTrue(dojo.isFunction(dojo.fx.easing[i]));
+							for(var i in easing){
+								t.assertTrue(lang.isFunction(easing[i]));
 							}
 						},
 						
 						function easingReturns(t){
-							for(var i in dojo.fx.easing){
-								t.assertTrue(!isNaN(dojo.fx.easing[i](0.5)));
+							for(var i in easing){
+								t.assertTrue(!isNaN(easing[i](0.5)));
 							}
 						},
 						
@@ -323,16 +328,16 @@
 							runTest: function(t){
 								var d = new doh.Deferred;
 								
-								var a1 = dojo.fadeOut({ node:"a1" });
-								var a2 = dojo.fadeOut({ node:"a2" });
+								var a1 = baseFx.fadeOut({ node:"a1" });
+								var a2 = baseFx.fadeOut({ node:"a2" });
 								
-								var anim = dojo.fx.chain([a1, a2]);
-								dojo.connect(anim, "onEnd", function(){
+								var anim = fx.chain([a1, a2]);
+								aspect.after(anim, "onEnd", function(){
 									t.is("stopped", a1.status());
 									t.is("stopped", a2.status());
 									t.is("stopped", anim.status());
 									d.callback(true);
-								});
+								}, true);
 								
 								anim.play();
 								
@@ -345,18 +350,18 @@
 							runTest: function(t){
 								var d = new doh.Deferred;
 
-								var a1 = dojo.fadeOut({ node:"a1" });
-								var a2 = dojo.fadeOut({ node:"a2" });
+								var a1 = baseFx.fadeOut({ node:"a1" });
+								var a2 = baseFx.fadeOut({ node:"a2" });
 
-								var anim = dojo.fx.combine([a1, a2]);
-								dojo.connect(anim, "onEnd", function(){
+								var anim = fx.combine([a1, a2]);
+								aspect.after(anim, "onEnd", function(){
 									t.is("stopped", a1.status());
 									t.is("stopped", a2.status());
 									setTimeout(function(){
 										t.is("stopped", anim.status());
 										d.callback(true);	
 									}, 10);
-								});
+								}, true);
 
 								anim.play();
 								return d;
@@ -366,17 +371,17 @@
 							name: "wipeOut onStop",
 							timeout: 1500,
 							runTest: function(t){
-								dojo.byId("foo").style.height = "auto";
-								dojo.byId("foo").style.overflow = "visible";
+								dom.byId("foo").style.height = "auto";
+								dom.byId("foo").style.overflow = "visible";
 								var d = new doh.Deferred();
-								var w = dojo.fx.wipeOut({
+								var w = fx.wipeOut({
 									node: "foo",
 									duration: 1000
 								});
-								dojo.connect(w, "onStop", function(){
-									doh.t(dojo.byId("foo").style.overflow == "visible");
+								aspect.after(w, "onStop", function(){
+									doh.t(dom.byId("foo").style.overflow == "visible");
 									d.callback(true);
-								});
+								}, true);
 								w.play();
 								setTimeout(function(){ w.stop(); }, 100);
 								return d;
@@ -386,17 +391,17 @@
 							name: "wipeIn onStop",
 							timeout: 1500,
 							runTest: function(t){
-								dojo.byId("foo").style.height = "0px";
-								dojo.byId("foo").style.overflow = "visible";
+								dom.byId("foo").style.height = "0px";
+								dom.byId("foo").style.overflow = "visible";
 								var d = new doh.Deferred();
-								var w = dojo.fx.wipeIn({
+								var w = fx.wipeIn({
 									node: "foo",
 									duration: 1000
 								});
-								dojo.connect(w, "onStop", function(){
-									doh.t(dojo.byId("foo").style.overflow == "visible");
+								aspect.after(w, "onStop", function(){
+									doh.t(dom.byId("foo").style.overflow == "visible");
 									d.callback(true);
-								});
+								}, true);
 								w.play();
 								setTimeout(function(){ w.stop(); }, 100);
 								return d;
diff --git a/dojo/tests/fx.js b/dojo/tests/fx.js
index e6d942e..096ba04 100644
--- a/dojo/tests/fx.js
+++ b/dojo/tests/fx.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests.fx", require.toUrl("./fx.html"), 30000);
 		doh.register("tests.NodeList-fx", require.toUrl("./NodeList-fx.html"), 30000);
diff --git a/dojo/tests/hash.js b/dojo/tests/hash.js
index fc9055b..2e98bdf 100644
--- a/dojo/tests/hash.js
+++ b/dojo/tests/hash.js
@@ -1,4 +1,4 @@
-define(["../main", "doh", "../hash"], function(dojo, doh){
+define(["doh/main", "../hash", "../topic"], function(doh, hash, topic){
 
 	// utilities for the tests:
 	function setHash(h){
@@ -19,13 +19,13 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 				setHash();
 			},
 			runTest: function(t){
-				t.is('', dojo.hash());
+				t.is('', hash());
 			}
 		},
 		{
 			name: "Setting an empty hash",
 			setUp: function(){
-				dojo.hash('');
+				hash('');
 			},
 			runTest: function(t){
 				t.is('', getHash());
@@ -38,7 +38,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 				setHash('test');
 			},
 			runTest: function(t){
-				t.is('test', dojo.hash());
+				t.is('test', hash());
 			},
 			tearDown: function(){
 				setHash();
@@ -47,7 +47,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 		{
 			name: "Setting the hash to 'test'",
 			setUp: function(){
-				dojo.hash('test');
+				hash('test');
 			},
 			runTest: function(t){
 				t.is('test', getHash());
@@ -63,7 +63,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 				setHash('test%20with%20spaces');
 			},
 			runTest: function(t){
-				t.is('test%20with%20spaces', dojo.hash());
+				t.is('test%20with%20spaces', hash());
 			},
 			tearDown: function(){
 				setHash();
@@ -88,7 +88,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 				setHash('test%23with%23encoded%23hashes');
 			},
 			runTest: function(t){
-				t.is('test%23with%23encoded%23hashes', dojo.hash());
+				t.is('test%23with%23encoded%23hashes', hash());
 			},
 			tearDown: function(){
 				setHash();
@@ -113,7 +113,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 				setHash('test+with+pluses');
 			},
 			runTest: function(t){
-				t.is('test+with+pluses', dojo.hash());
+				t.is('test+with+pluses', hash());
 			},
 			tearDown: function(){
 				setHash();
@@ -122,7 +122,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 		{
 			name: "Setting the hash to 'test+with+pluses'",
 			setUp: function(){
-				dojo.hash('test+with+pluses');
+				hash('test+with+pluses');
 			},
 			runTest: function(t){
 				t.is('test+with+pluses', getHash());
@@ -138,7 +138,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 				setHash('%20leadingSpace');
 			},
 			runTest: function(t){
-				t.is('%20leadingSpace', dojo.hash());
+				t.is('%20leadingSpace', hash());
 			},
 			tearDown: function(){
 				setHash();
@@ -147,7 +147,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 		{
 			name: "Setting the hash to '%20leadingSpace'",
 			setUp: function(){
-				dojo.hash('%20leadingSpace');
+				hash('%20leadingSpace');
 			},
 			runTest: function(t){
 				t.is('%20leadingSpace', getHash());
@@ -164,7 +164,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 				setHash('trailingSpace%20');
 			},
 			runTest: function(t){
-				t.is('trailingSpace%20', dojo.hash());
+				t.is('trailingSpace%20', hash());
 			},
 			tearDown: function(){
 				setHash();
@@ -173,7 +173,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 		{
 			name: "Setting the hash to 'trailingSpace%20'",
 			setUp: function(){
-				dojo.hash('trailingSpace%20');
+				hash('trailingSpace%20');
 			},
 			runTest: function(t){
 				t.is('trailingSpace%20', getHash());
@@ -189,7 +189,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 				setHash('under_score');
 			},
 			runTest: function(t){
-				t.is('under_score', dojo.hash());
+				t.is('under_score', hash());
 			},
 			tearDown: function(){
 				setHash();
@@ -198,7 +198,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 		{
 			name: "Setting the hash to 'under_score'",
 			setUp: function(){
-				dojo.hash('under_score');
+				hash('under_score');
 			},
 			runTest: function(t){
 				t.is('under_score', getHash());
@@ -213,7 +213,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 				setHash("extra&instring");
 			},
 			runTest: function(t){
-				t.is("extra&instring", dojo.hash());
+				t.is("extra&instring", hash());
 			},
 			tearDown: function(){
 				setHash();
@@ -222,7 +222,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 		{
 			name: "Setting the hash to 'extra&instring'",
 			setUp: function(){
-				dojo.hash('extra&instring');
+				hash('extra&instring');
 			},
 			runTest: function(t){
 				t.is('extra&instring', getHash());
@@ -237,7 +237,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 				setHash('extra?instring');
 			},
 			runTest: function(t){
-				t.is('extra?instring', dojo.hash());
+				t.is('extra?instring', hash());
 			},
 			tearDown: function(){
 				setHash();
@@ -246,7 +246,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 		{
 			name: "Setting the hash of 'extra?instring'",
 			setUp: function(){
-				dojo.hash('extra?instring');
+				hash('extra?instring');
 			},
 			runTest: function(t){
 				t.is('extra?instring', getHash());
@@ -261,7 +261,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 				setHash('?testa=3&testb=test');
 			},
 			runTest: function(t){
-				t.is('?testa=3&testb=test', dojo.hash());
+				t.is('?testa=3&testb=test', hash());
 			},
 			tearDown: function(){
 				setHash();
@@ -270,7 +270,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 		{
 			name: "Setting the hash resembling a query parameter ('?testa=3&testb=test')",
 			setUp: function(){
-				dojo.hash('?testa=3&testb=test');
+				hash('?testa=3&testb=test');
 			},
 			runTest: function(t){
 				t.is('?testa=3&testb=test', getHash());
@@ -282,7 +282,7 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 		{
 			name: "Setting the hash to '#leadingHash' should result in the hash being 'leadingHash'",
 			setUp: function(){
-				dojo.hash('#leadingHash');
+				hash('#leadingHash');
 			},
 			runTest: function(t){
 				t.is('leadingHash', getHash());
@@ -300,20 +300,15 @@ define(["../main", "doh", "../hash"], function(dojo, doh){
 			},
 			runTest: function(t){
 				var d = new doh.Deferred();
-				this._s = dojo.subscribe('/dojo/hashchange', null, function(value){
-					try {
-						doh.assertEqual('test', value);
-						d.callback(true);
-					} catch(e){
-						d.errback(e);
-					}
-				});
+				this._s = topic.subscribe('/dojo/hashchange', d.getTestCallback(function(value){
+					doh.assertEqual('test', value);
+				}));
 
-				dojo.hash('test');
+				hash('test');
 				return d;
 			},
 			tearDown: function(){
-				dojo.unsubscribe(this._s);
+				this._s.remove();
 				setHash();
 			}
 		}
diff --git a/dojo/tests/html.js b/dojo/tests/html.js
index 8bbb712..5aba0a9 100644
--- a/dojo/tests/html.js
+++ b/dojo/tests/html.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests.html", require.toUrl("./html/test_set.html"), 30000);
 	}
diff --git a/dojo/tests/html/test_set.html b/dojo/tests/html/test_set.html
index e23ad5d..6e3d79c 100644
--- a/dojo/tests/html/test_set.html
+++ b/dojo/tests/html/test_set.html
@@ -4,38 +4,40 @@
 <head>
 	<title>dojo.html.set test</title>
 
-	<script src='../../dojo.js' djConfig='isDebug:true, parseOnLoad:false'></script>
+	<script src="../../dojo.js" data-dojo-config="isDebug:true, parseOnLoad:false"></script>
 	<script>
-		require(["dojo", "doh", "dojo/html", "dojo/NodeList-html"], function(dojo, doh){
-
-		/* test goals
-		 * injecting content as string, node, nodelist. 
-		 * injecting exotic nodes/markup e.g. table rows, lists
-		 * injecting whole html documents (extractContent option)
-		 * parsing resulting content
-		 
-		 * cleanup when setting content
-		*/
-		dojo.declare("dojo.html.test.SimpleThing", null, {
-			constructor: function(params, node) {
-				node.setAttribute("test", "ok");
-			}
-		});
-		
-		dojo.declare("dojo.html.test.ParserInstantiateTester", null, {
-			constructor: function(params, node) {
-				node.setAttribute("test", "ok");
-			}
-		});
-		dojo.declare("dojo.html.test.DeclarativeContentSetter", dojo.html._ContentSetter, {
-			postscript: function() {
-				this.set();
-			}
-		});
-		
-		
-		dojo.addOnLoad(function(){
-
+		require([
+			"doh",
+			"dojo/_base/array", "dojo/aspect",
+			"dojo/_base/declare", "dojo/dom", "dojo/dom-construct", "dojo/html", "dojo/_base/lang", "dojo/parser",
+			"dojo/query", "dojo/NodeList-html","dojo/domReady!"
+		], function(doh, array, aspect, declare, dom, domConstruct, html, lang, parser, query){
+
+			/* test goals
+			 * injecting content as string, node, nodelist. 
+			 * injecting exotic nodes/markup e.g. table rows, lists
+			 * injecting whole html documents (extractContent option)
+			 * parsing resulting content
+			 
+			 * cleanup when setting content
+			*/
+			declare("SimpleThing", null, {
+				constructor: function(params, node) {
+					node.setAttribute("test", "ok");
+				}
+			});
+			
+			declare("ParserInstantiateTester", null, {
+				constructor: function(params, node) {
+					node.setAttribute("test", "ok");
+				}
+			});
+			declare("DeclarativeContentSetter", html._ContentSetter, {
+				postscript: function() {
+					this.set();
+				}
+			});
+	
 			function ieTrimSpaceBetweenTags(str){
 				return str.replace(/(<[a-z]*[^>]*>)\s*/ig, "$1");
 			}
@@ -48,11 +50,11 @@
 					name: 'set',
 					runTest: function(t){
 						console.log("basicChecks: " + this.name);
-						targetNode = dojo.byId("pane1");
+						targetNode = dom.byId("pane1");
 						var msg = "Simple No-params Test";
 						console.log("targetNode has content: ", targetNode.innerHTML);
 						var result = "";
-						dojo.html.set(
+						html.set(
 							targetNode,
 							msg
 						);
@@ -64,15 +66,15 @@
 					name: 'setContentWithOnEnd',
 					runTest: function(t){
 						console.log("basicChecks: " + this.name);
-						targetNode = dojo.byId("pane1");
+						targetNode = dom.byId("pane1");
 						var msg = "setContentWithOnEnd Test";
 						var result = false;
-						dojo.html.set(
+						html.set(
 							targetNode,
 							msg,
 							{
 								onEnd: function() {
-									dojo.getObject(this.declaredClass).prototype.onEnd.call(this);
+									lang.getObject(this.declaredClass).prototype.onEnd.call(this);
 									result = true;
 								}
 							}
@@ -85,15 +87,15 @@
 					name: 'setContent_with_parsing',
 					runTest: function(t){
 						console.log("basicChecks: " + this.name);
-						var cont = '<div dojoType="dojo.html.test.SimpleThing" jsId="ifrs" data="{}"></div>';
-						dojo.html.set(
-							dojo.byId("pane1"),
+						var cont = '<div data-dojo-type="SimpleThing" data-dojo-id="ifrs" data="{}"></div>';
+						html.set(
+							dom.byId("pane1"),
 							cont,
 							{
 								postscript: function() {
 									this.set();
 
-									doh.t(typeof ifrs != "undefined" && ifrs.declaredClass=="dojo.html.test.SimpleThing");
+									doh.t(typeof ifrs != "undefined" && ifrs.declaredClass=="SimpleThing");
 									doh.t(this.parseResults.length > 0);
 								},
 								parseContent: true
@@ -104,134 +106,133 @@
 				{
 					name: 'emptyElement',
 					runTest: function(t){
+						// Test of deprecated _emptyNode() method
 						console.log("basicChecks: " + this.name);
 						var msg = "setContentWithOnEnd Test";
-						var node = dojo.byId("pane1");
+						var node = dom.byId("pane1");
 						node.innerHTML = '<div><span>just</span>some test<br/></div>text';
 						var cNodes = node.childNodes.length;
 
-						dojo.html._emptyNode(dojo.byId("pane1"));
+						html._emptyNode(dom.byId("pane1"));
 						doh.t(node.childNodes.length == 0 && node.innerHTML == "");
 					}
 				},
-				// the following tests use the _emptyNode function, so ensure it passes before
-				// head-scratching over any failures that follow
 				{
 					name: 'changeContentTRHead',
 					runTest: function(t){
 						console.log("basicChecks: " + this.name);
-						targetNode = dojo.query('table#tableTest > thead > tr')[0];
+						targetNode = query('table#tableTest > thead > tr')[0];
 
-						var html = "<td><div>This</div>Should<u>Work</u></td>";
-						dojo.html.set(
+						var markup = "<td><div>This</div>Should<u>Work</u></td>";
+						html.set(
 							targetNode,
-							html,
+								markup,
 							{
 								"testname": "basicChecks changeContentTRHead"
 							}
 						);
 						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-						doh.is(html.toLowerCase(), res);
+						doh.is(markup.toLowerCase(), res);
 					},
 					tearDown: function(){
-						dojo.html._emptyNode(targetNode);
+						domConstruct.empty(targetNode);
 					}
 				},
 				{
 					name: 'changeContentTHead',
 					runTest: function(t){
 						console.log("basicChecks: " + this.name);
-						targetNode = dojo.query('table#tableTest > thead')[0];
+						targetNode = query('table#tableTest > thead')[0];
 
-						var html = "<tr><td><div>This</div>Should<u>Work</u></td></tr>";
-						dojo.html.set(
+						var markup = "<tr><td><div>This</div>Should<u>Work</u></td></tr>";
+						html.set(
 							targetNode,
-							html,
+								markup,
 							{
 								"testname": "basicChecks changeContentTHead"
 							}
 						);
 						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-						doh.is(html.toLowerCase(), res);
+						doh.is(markup.toLowerCase(), res);
 					},
 					tearDown: function(){
-						dojo.html._emptyNode(targetNode);
+						domConstruct.empty(targetNode);
 					}
 				},
 				{
 					name: 'changeContentTRBody',
 					runTest: function(t){
 						console.log("basicChecks: " + this.name);
-						targetNode = dojo.query('table#tableTest > tbody > tr')[0];
-						var html = "<td><div>This</div>Should<u>Work</u></td>";
-						dojo.html.set(
+						targetNode = query('table#tableTest > tbody > tr')[0];
+						var markup = "<td><div>This</div>Should<u>Work</u></td>";
+						html.set(
 							targetNode,
-							html,
+								markup,
 							{
 								"testname": "basicChecks changeContentTRBody"
 							});
 						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-						doh.is(html.toLowerCase(), res);
+						doh.is(markup.toLowerCase(), res);
 					},
 					tearDown: function(){
-						dojo.html._emptyNode(targetNode);
+						domConstruct.empty(targetNode);
 					}
 				},
 				{
 					name: 'changeContentTBody',
 					runTest: function(t){
 						console.log("basicChecks: " + this.name);
-						targetNode = dojo.query('table#tableTest > tbody')[0];
-						var html = "<tr><td><div>This</div>Should<u>Work</u></td></tr>";
-						dojo.html.set(
-							targetNode, html,
+						targetNode = query('table#tableTest > tbody')[0];
+						var markup = "<tr><td><div>This</div>Should<u>Work</u></td></tr>";
+						html.set(
+							targetNode, markup,
 							{
 								"testname": "basicChecks changeContentTBody"
 							});
 						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-						doh.is(html.toLowerCase(), res);
+						doh.is(markup.toLowerCase(), res);
 					},
 					tearDown: function(){
-						dojo.html._emptyNode(targetNode);
+						domConstruct.empty(targetNode);
 					}
 				},
 				{
 					name: 'changeContentTable',
 					runTest: function(t){
 						console.log("basicChecks: " + this.name);
-						targetNode = dojo.query('table#tableTest')[0];
-						var html = "<tbody><tr><td><div>This</div>Should<u>Work</u></td></tr></tbody>";
-						dojo.html.set(
-							targetNode, html,
+						targetNode = query('table#tableTest')[0];
+						var markup = "<tbody><tr><td><div>This</div>Should<u>Work</u></td></tr></tbody>";
+						html.set(
+							targetNode, markup,
 							{
 								"testname": "basicChecks changeContentTable"
 							});
 						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-						doh.is(html.toLowerCase(), res);
+						doh.is(markup.toLowerCase(), res);
 					},
 					tearDown: function(){
-						dojo.html._emptyNode(targetNode);
+						domConstruct.empty(targetNode);
 					}
 				},
 				{
 					name: 'setNodeList',
 					runTest: function(t){
 						console.log("basicChecks: " + this.name);
-						var tmpUL = dojo.create("ul");
-						dojo.create("li", { innerHTML: "item 1" }, tmpUL);
-						dojo.create("li", { innerHTML: "item 2" }, tmpUL);
+						var tmpUL = domConstruct.create("ul");
+						domConstruct.create("li", { innerHTML: "item 1" }, tmpUL);
+						domConstruct.create("li", { innerHTML: "item 2" }, tmpUL);
 						console.log("ul content: ", tmpUL.innerHTML, tmpUL.childNodes.length);
-						targetNode = dojo.byId("pane1");
-						dojo.html.set(
+						targetNode = dom.byId("pane1");
+						html.set(
 							targetNode, tmpUL.childNodes,
 							{
 								"testname": "basicChecks setNodeList"
 							});
-						var res = dojo.query("li", dojo.byId("pane1")).length;
+						var res = query("li", dom.byId("pane1")).length;
 						doh.is(2, res);
 					},
 					tearDown: function(){
-						dojo.html._emptyNode(targetNode);
+						domConstruct.empty(targetNode);
 					}
 				},
 				{
@@ -239,27 +240,27 @@
 					runTest: function(t){
 						console.log("basicChecks: " + this.name);
 
-						targetNode = dojo.byId("pane1");
-						var html = '<h4>See Jane</h4>'
+						targetNode = dom.byId("pane1");
+						var markup = '<h4>See Jane</h4>'
 						 + 'Look at her <span>Run</span>!';
-						dojo.html.set(
-							targetNode, html,
+						html.set(
+							targetNode, markup,
 							{
 								"testname": "basicChecks setMixedContent"
 							});
 						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-						doh.is(html.toLowerCase(), res);
+						doh.is(markup.toLowerCase(), res);
 					},
 					tearDown: function(){
-						dojo.html._emptyNode(targetNode);
+						domConstruct.empty(targetNode);
 					}
 				},
 				{
 					name: 'extractContent',
 					runTest: function(t){
 						console.log("basicChecks: " + this.name);
-						targetNode = dojo.byId("pane1");
-						var html = ''
+						targetNode = dom.byId("pane1");
+						var markup = ''
 						+'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">'
 						+'<html>											'
 						+'	<head>											'
@@ -274,17 +275,17 @@
 						+'	</body>											'
 						+'</html>											';
 
-						dojo.html.set(
-							targetNode, html,
+						html.set(
+							targetNode, markup,
 							{
 								"testname": "basicChecks changeContentTable",
 								extractContent: true
 							});
 						doh.t(targetNode.innerHTML.indexOf("title") == -1);
-						doh.t(dojo.query("*", targetNode).length == 3);
+						doh.t(query("*", targetNode).length == 3);
 					},
 					tearDown: function(){
-						dojo.html._emptyNode(targetNode);
+						domConstruct.empty(targetNode);
 					}
 				}
 			]);
@@ -294,7 +295,7 @@
 					runTest: function(t){
 						console.log("nodelistExtension: " + this.name);
 
-						dojo.query(".zork").html("<li dojoType='dojo.html.test.ParserInstantiateTester'>1</li><li dojoType='dojo.html.test.ParserInstantiateTester'>2</li><li dojoType='dojo.html.test.ParserInstantiateTester'>3</li>",
+						query(".zork").html("<li data-dojo-type='ParserInstantiateTester'>1</li><li data-dojo-type='ParserInstantiateTester'>2</li><li data-dojo-type='ParserInstantiateTester'>3</li>",
 						{
 							parseContent: true,
 							onBegin: function() {
@@ -303,7 +304,7 @@
 							}
 						}).removeClass("notdone").addClass("done");
 
-						var liNodes = dojo.query(".zork > li");
+						var liNodes = query(".zork > li");
 
 						// test to make sure three li's were added to class="zork" node (3x 3 set li's)
 						doh.is(9, liNodes.length);
@@ -313,7 +314,7 @@
 						console.log(this.name + ": innerHTML.match subtest was ok");
 
 						// test the parent elements got the correct className
-						doh.t( dojo.query(".zork").every(function(n) { return n.className == "zork done"; }) );
+						doh.t( query(".zork").every(function(n) { return n.className == "zork done"; }) );
 						console.log(this.name + ": li.className subtest was ok");
 
 						// and test the parser correctly created object from the child nodes
@@ -323,21 +324,21 @@
 
 					},
 					tearDown: function(){
-						// dojo.html._emptyNode(targetNode);
+						// domConstruct.empty(targetNode);
 					}
 				},
 				{
 					name: "nodeListSimple",
 					runTest: function(t){
 						var txt = "foo";
-						dojo.query("#simpleText").html("<p>"+txt+"</p>");
+						query("#simpleText").html("<p>"+txt+"</p>");
 
 						// check if its there at all
-						var len = dojo.query("#simpleText p").length;
+						var len = query("#simpleText p").length;
 						doh.is(1, len);
 
 						// check the inner html is right:
-						var p = dojo.query("#simpleText p")[0];
+						var p = query("#simpleText p")[0];
 						doh.t( p && p.innerHTML == txt );
 					}
 				}
@@ -348,11 +349,11 @@
 					runTest: function(t){
 						console.log("fromMarkup: " + this.name);
 
-						dojo.parser.parse("markupSetContentOp");
-						doh.t(dojo.byId("markupPane").innerHTML == "markupSetContentOp: new node content");
+						parser.parse("markupSetContentOp");
+						doh.t(dom.byId("markupPane").innerHTML == "markupSetContentOp: new node content");
 					},
 					tearDown: function(){
-						dojo.byId("markupPane").innerHTML = "initial content";
+						dom.byId("markupPane").innerHTML = "initial content";
 					}
 				},
 				{
@@ -360,12 +361,12 @@
 					runTest: function(t){
 						console.log("fromMarkup: " + this.name);
 
-						dojo.parser.parse("markupSetContentOpX");
+						parser.parse("markupSetContentOpX");
 
-						doh.t(dojo.byId("markupPane").innerHTML == "markupSetContentOpX: new node content".toUpperCase());
+						doh.t(dom.byId("markupPane").innerHTML == "markupSetContentOpX: new node content".toUpperCase());
 					},
 					tearDown: function(){
-						dojo.byId("markupPane").innerHTML = "initial content";
+						dom.byId("markupPane").innerHTML = "initial content";
 					}
 				}
 			]);
@@ -375,28 +376,28 @@
 					runTest: function(t){
 						console.log("fromMarkup: " + this.name);
 
-						targetNode = dojo.byId('pane1');
+						targetNode = dom.byId('pane1');
 						var args = [
 							[
 								"simple"
 							],
 							[
-								'<div dojoType="dojo.html.test.SimpleThing" jsId="id00">parsed content</div>',
+								'<div data-dojo-type="SimpleThing" data-dojo-id="id00">parsed content</div>',
 								{
 									parseContent: true
 								}
 							],
 							[
-								'<div dojoType="dojo.html.test.SimpleThing" jsId="id01">parsed content</div>',
+								'<div data-dojo-type="SimpleThing" data-dojo-id="id01">parsed content</div>',
 								{
 									parseContent: true
 								}
 							]
 						];
-						var setter = new dojo.html._ContentSetter({
+						var setter = new html._ContentSetter({
 							node: targetNode
 						});
-						dojo.forEach(args, function(applyArgs) {
+						array.forEach(args, function(applyArgs) {
 							setter.node = targetNode;
 							setter.set.apply(setter, applyArgs);
 							setter.tearDown();
@@ -406,7 +407,7 @@
 						doh.f(setter.parseResults);
 					},
 					tearDown: function(){
-						dojo.byId("markupPane").innerHTML = "initial content";
+						dom.byId("markupPane").innerHTML = "initial content";
 					}
 				}
 			]);
@@ -417,16 +418,16 @@
 				{
 					name: 'unspecified',
 					runTest: function(t){
-						var cont = '<div dojoType="dojo.html.test.SimpleThing" jsId="ifrs" data="{}"></div>';
+						var cont = '<div data-dojo-type="SimpleThing" data-dojo-id="ifrs" data="{}"></div>';
 
 						var parserCalled, inherited;
-						handle = dojo.connect(dojo.parser, "parse", function(args){
+						handle = aspect.after(parser, "parse", function(args){
 							parserCalled = true;
 							inherited = args.inherited;
-						});
+						}, true);
 
-						dojo.html.set(
-							dojo.byId("pane1"),
+						html.set(
+							dom.byId("pane1"),
 							cont,
 							{
 								parseContent: true
@@ -437,22 +438,22 @@
 						doh.f("lang" in inherited, "no lang specified");
 					},
 					tearDown: function(){
-						dojo.disconnect(handle);
+						handle.remove();
 					}
 				},
 				{
 					name: 'specified',
 					runTest: function(t){
-						var cont = '<div dojoType="dojo.html.test.SimpleThing" jsId="ifrs" data="{}"></div>';
+						var cont = '<div data-dojo-type="SimpleThing" data-dojo-id="ifrs" data="{}"></div>';
 
 						var parserCalled, inherited;
-						handle = dojo.connect(dojo.parser, "parse", function(args){
+						handle = aspect.after(parser, "parse", function(args){
 							parserCalled = true;
 							inherited = args.inherited;
-						});
+						}, true);
 
-						dojo.html.set(
-							dojo.byId("pane1"),
+						html.set(
+							dom.byId("pane1"),
 							cont,
 							{
 								dir: "rtl",
@@ -467,7 +468,7 @@
 						doh.is("ltr", inherited.textDir, "textdir");
 					},
 					tearDown: function(){
-						dojo.disconnect(handle);
+						handle.remove();
 					}
 				}
 
@@ -475,7 +476,6 @@
 
 			doh.run();
 		});
-		});
 	</script>
 	<style>
 		@import "../../../dojo/resources/dojo.css";
@@ -530,22 +530,22 @@
 
 	<div id="markupPane">initial content</div>
 	<div id="markupSetContentOp">
-		<div dojoType="dojo.html.test.DeclarativeContentSetter" node="markupPane" content="markupSetContentOp: new node content"></div>
+		<div data-dojo-type="DeclarativeContentSetter" node="markupPane" content="markupSetContentOp: new node content"></div>
 	</div>
 	<div id="markupSetContentOpX">
-		<div dojoType="dojo.html.test.DeclarativeContentSetter" jsId="markupSetContentOpX_setter" node="markupPane" content="markupSetContentOpX: new node content">
-		<script type="dojo/method" event="onBegin">
+		<div data-dojo-type="DeclarativeContentSetter" data-dojo-id="markupSetContentOpX_setter" node="markupPane" content="markupSetContentOpX: new node content">
+		<script type="dojo/method" data-dojo-event="onBegin">
 			this.content = this.content.toUpperCase();
 			console.log(this.id + ", made my content look like this:" + this.content);
 		</script>
-		<script type="dojo/method" event="onFoo">
+		<script type="dojo/method" data-dojo-event="onFoo">
 			console.log("dojo/method supplied onBegin");
 			this.content = this.content.toUpperCase();
 		</script>
 		</div>
 	</div>
 	<div id="another">
-		<div id="myTest9" dojoType="dojo.html.test.DeclarativeContentSetter">
+		<div id="myTest9" data-dojo-type="DeclarativeContentSetter">
 			Some content
 			<script type="dojo/method">
 				console.log("parsed me!");
diff --git a/dojo/tests/i18n.html b/dojo/tests/i18n.html
index 41a93ac..8c49310 100644
--- a/dojo/tests/i18n.html
+++ b/dojo/tests/i18n.html
@@ -18,7 +18,8 @@
 
 		<script type="text/javascript">
 		// the following should load the current locale + 'en-us-hawaii' and 'en-us-new_york-brooklyn
-		require(["dojo", "doh", "dojo/has", "dojo/i18n", "dojo/i18n!dojo/tests/nls/salutations"], function(dojo, doh, has, i18n){
+		require(["doh", "dojo/_base/array", "dojo/has", "dojo/i18n", "dojo/i18n!dojo/tests/nls/salutations", "dojo/domReady!"],
+				function(doh, array, has, i18n){
 			if(dohArgs.async){
 				doh.register(function extraLocalesAsync(t){
 					// the following should load synchronously...at least with the dojo loader
@@ -36,10 +37,10 @@
 				});
 			}else{
 				doh.register(function extraLocalesSync(t){
-					t.is(dojo.i18n.getLocalization("dojo/tests", "salutations", "en-us-hawaii").hello, "Aloha");
-					t.is(dojo.i18n.getLocalization("dojo/tests", "salutations", "en-us-new_york-brooklyn").hello, "Yo");
+					t.is(i18n.getLocalization("dojo/tests", "salutations", "en-us-hawaii").hello, "Aloha");
+					t.is(i18n.getLocalization("dojo/tests", "salutations", "en-us-new_york-brooklyn").hello, "Yo");
 					try{
-						t.is(dojo.i18n.getLocalization("dojo/tests", "salutations", "en-au").hello, "G'day");
+						t.is(i18n.getLocalization("dojo/tests", "salutations", "en-au").hello, "G'day");
 					}catch(e){
 						t.f("synchronous get should work if not xdomain");
 					}
@@ -47,13 +48,11 @@
 			}
 
 
-		if(has("dojo-unit-tests")){
-			console.log("here");
-			dojo.forEach(i18n.unitTests, function(item){item(doh);});
-		}
-
+			if(has("dojo-unit-tests")){
+				array.forEach(i18n.unitTests, function(item){item(doh);});
+			}
 
-			doh.runOnLoad();
+			doh.run();
 		});
 		if(!require.async){
 			dojo.requireLocalization("dojo.tests._base.loader", "syncBundle", "ab-cd-ef");
diff --git a/dojo/tests/i18n.js b/dojo/tests/i18n.js
index f3e84bb..d0b04da 100644
--- a/dojo/tests/i18n.js
+++ b/dojo/tests/i18n.js
@@ -1,9 +1,9 @@
-define(["../main", "doh", "require", "../i18n"], function(dojo, doh, require){
+define(["doh/main", "../has", "../i18n", "require"], function(doh, has, i18n, require){
 	var
 		getAsyncTest = function(value, locale){
 			return function(){
 				var def = new doh.Deferred();
-				require([dojo.getL10nName("dojo/tests", "salutations", locale)], function(bundle){
+				require([i18n.getL10nName("dojo/tests", "salutations", locale)], function(bundle){
 					doh.assertEqual(value, bundle.hello);
 					def.callback(true);
 				});
@@ -13,7 +13,7 @@ define(["../main", "doh", "require", "../i18n"], function(dojo, doh, require){
 
 		getSyncTest = function(value, locale){
 			return function(){
-				doh.assertEqual(value, dojo.i18n.getLocalization("dojo/tests", "salutations", locale).hello);
+				doh.assertEqual(value, i18n.getLocalization("dojo/tests", "salutations", locale).hello);
 			};
 		},
 
@@ -45,7 +45,11 @@ define(["../main", "doh", "require", "../i18n"], function(dojo, doh, require){
 			// A double-byte string. Everything should be read in as UTF-8 and treated as unicode within Javascript.
 			getFixture("zh-cn", "\u4f60\u597d")
 		];
+
+
 	doh.register("tests.i18n", testSet);
-	doh.register("tests.i18n.extra.sync", require.toUrl("./i18n.html"), {async:0});
-	doh.register("tests.i18n.extra.async", require.toUrl("./i18n.html"), {async:1});
+	if(has("host-browser")){
+		doh.register("tests.i18n.extra.sync", require.toUrl("./i18n.html"), {async:0});
+		doh.register("tests.i18n.extra.async", require.toUrl("./i18n.html"), {async:1});
+	}
 });
diff --git a/dojo/tests/io/iframe.html b/dojo/tests/io/iframe.html
index c87c404..279d992 100644
--- a/dojo/tests/io/iframe.html
+++ b/dojo/tests/io/iframe.html
@@ -6,14 +6,14 @@
 		<style type="text/css">
 			@import "../../resources/dojo.css";
 		</style>
-		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true"></script>
+		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true, ioPublish: true"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/io/iframe"], function(dojo, doh){
+			require(["dojo", "doh", "dojo/topic", "dojo/io/iframe"], function(dojo, doh, topic){
 				doh.register([
 					function ioIframeGetText(t){
 						var d = new doh.Deferred();
 						var td = dojo.io.iframe.send({
-							url: "iframeResponse.text.html",
+							url: "../request/iframeDummyMethod.php?type=text",
 							method: "GET",
 							timeoutSeconds: 5,
 							preventCache: true,
@@ -29,17 +29,96 @@
 						return d;
 					},
 
+					function ioIframeGetFormJson(t){
+						var d = new doh.Deferred();
+						var td = dojo.io.iframe.send({
+							url: "../request/iframeDummyMethod.php",
+							form: "contentArrayTest",
+							content: {
+								type: "json",
+								color: "blue",
+								size: 42
+							},
+							timeoutSeconds: 5,
+							preventCache: true,
+							handleAs: "json",
+							handle: function(res, ioArgs){
+								if(!(res instanceof Error) &&
+									t.is("blue", res.query.color)){
+									d.callback(true);
+								}else{
+									d.errback(false);
+								}
+							}
+						});
+						return d;
+					},
+
 					function ioIframeGetJson(t){
 						var d = new doh.Deferred();
 						var td = dojo.io.iframe.send({
-							url: "iframeResponse.json.html",
-							method: "GET",
+							url: "../request/iframeDummyMethod.php?type=json",
+							content: {
+								color: "blue",
+								size: 42
+							},
 							timeoutSeconds: 5,
 							preventCache: true,
 							handleAs: "json",
 							handle: function(res, ioArgs){
 								if(!(res instanceof Error) &&
-									t.is("blue", res.color)){
+									t.is("blue", res.query.color)){
+									d.callback(true);
+								}else{
+									d.errback(false);
+								}
+							}
+						});
+						return d;
+					},
+
+					function ioIframeNotPostJson(t){
+						var d = new doh.Deferred();
+						var td = dojo.io.iframe.send({
+							method: "post",
+							url: "../request/iframeDummyMethod.php?type=json",
+							content: {
+								color: "blue",
+								size: 42
+							},
+							timeoutSeconds: 5,
+							preventCache: true,
+							handleAs: "json",
+							handle: function(res, ioArgs){
+								if(!(res instanceof Error) &&
+									t.is("blue", res.query.color)){
+									d.callback(true);
+								}else{
+									d.errback(false);
+								}
+							}
+						});
+						return d;
+					},
+
+					function ioIframePostFormJson(t){
+						var d = new doh.Deferred();
+						var form = dojo.byId("contentArrayTest");
+						form.getAttributeNode("method").value = "post";
+						var td = dojo.io.iframe.send({
+							method: "post",
+							url: "../request/iframeDummyMethod.php?type=json",
+							form: "contentArrayTest",
+							content: {
+								color: "blue",
+								size: 42
+							},
+							timeoutSeconds: 5,
+							preventCache: true,
+							handleAs: "json",
+							handle: function(res, ioArgs){
+								if(!(res instanceof Error) &&
+									t.is("blue", res.post.color)){
 									d.callback(true);
 								}else{
 									d.errback(false);
@@ -51,6 +130,8 @@
 
 					function ioIframeGetJavascript(t){
 						var d = new doh.Deferred();
+						var form = dojo.byId("contentArrayTest");
+						form.getAttributeNode("method").value = "get";
 						var td = dojo.io.iframe.send({
 							url: "iframeResponse.js.html",
 							method: "GET",
@@ -117,13 +198,45 @@
 							url: "iframeResponse.text.html",
 							form: "contentArrayTest",
 							content: {"tag": ["value1","value2"]},
-							handle: function(res, ioArgs){
-								if(!(res instanceof Error)){
-									d.callback(true);
-								} else {
-									d.errback(false);
-								}
-							}
+							handle: d.getTestErrback(function(res, ioArgs){
+								t.f(res instanceof Error);
+							})
+						});
+						var stop = topic.subscribe("/dojo/io/stop", function(){
+							stop.remove();
+							d.callback(true);
+						});
+						return d;
+					},
+					function ioPublish(t){
+						var d = new doh.Deferred();
+
+						var topicCount = 0;
+						topic.subscribe("/dojo/io/start", function(){
+							topicCount++;
+						});
+						topic.subscribe("/dojo/io/send", function(){
+							topicCount++;
+						});
+						topic.subscribe("/dojo/io/load", function(){
+							topicCount++;
+						});
+						topic.subscribe("/dojo/io/error", function(){
+							topicCount--;
+						});
+						topic.subscribe("/dojo/io/done", function(){
+							topicCount++;
+						});
+						topic.subscribe("/dojo/io/stop", d.getTestCallback(function(){
+							topicCount++;
+							t.is(5, topicCount);
+						}));
+
+						dojo.io.iframe.send({
+							url: "iframeResponse.text.html",
+							method: "GET",
+							timeoutSeconds: 5,
+							preventCache: true
 						});
 						return d;
 					}
diff --git a/dojo/tests/io/iframe.js b/dojo/tests/io/iframe.js
index fab619c..aef013a 100644
--- a/dojo/tests/io/iframe.js
+++ b/dojo/tests/io/iframe.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests.io.iframe", require.toUrl("./iframe.html"));
 	}
diff --git a/dojo/tests/io/script.js b/dojo/tests/io/script.js
index ded51a0..aa166c3 100644
--- a/dojo/tests/io/script.js
+++ b/dojo/tests/io/script.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests.io.script", require.toUrl("./script.html"));
 	}
diff --git a/dojo/tests/io/scriptJsonp.js b/dojo/tests/io/scriptJsonp.js
index ad1a196..0a41d10 100644
--- a/dojo/tests/io/scriptJsonp.js
+++ b/dojo/tests/io/scriptJsonp.js
@@ -38,7 +38,7 @@ function getScriptUrls(){
 	var scriptUrls = new Array();
 	for(var i = 0; scripts && i < scripts.length; i++){
 		var scriptTag = scripts[i];
-		if(scriptTag.id.indexOf("dojoIoScript") == 0){
+		if(scriptTag.id.indexOf("dojo_request_script") == 0){
 			scriptUrls.push(scriptTag.src);
 		}
 	}
diff --git a/dojo/tests/json.js b/dojo/tests/json.js
index ee777a7..52b0123 100644
--- a/dojo/tests/json.js
+++ b/dojo/tests/json.js
@@ -1,4 +1,4 @@
-define(["../main", "doh", "../json"], function(dojo, doh, JSON){
+define(["doh/main", "../json", "../has"], function(doh, JSON, has){
 
 	var mustThrow = function(json){
 		try{
@@ -11,52 +11,63 @@ define(["../main", "doh", "../json"], function(dojo, doh, JSON){
 
 	doh.register("tests.json", [
 		// all tests below are taken from #4.2 of the CSS3 Color Module
-		function simpleString(t){ t.is("bar", JSON.parse('{"foo":"bar"}').foo)},
-		function simpleTrue(t){ t.is(true, JSON.parse('{"foo":true}').foo)},
-		function simpleFalse(t){ t.is(false, JSON.parse('{"foo":false}').foo)},
-		function simpleNull(t){ t.is(null, JSON.parse('{"foo":null}').foo)},
-		function simpleNumber(t){ t.is(3.3, JSON.parse('{"foo":3.3}', true).foo)},
-		function strictString(t){ t.is("bar", JSON.parse('{"foo":"bar"}', true).foo)},
-		function strictStringEsc(t){ t.is("b\n\t\"ar()", JSON.parse('{"foo":"b\\n\\t\\"ar()"}', true).foo)},
-		function strictTrue(t){ t.is(true, JSON.parse('{"foo":true}', true).foo)},
-		function strictFalse(t){ t.is(false, JSON.parse('{"foo":false}', true).foo)},
-		function strictNull(t){ t.is(null, JSON.parse('{"foo":null}', true).foo)},
-		function strictNumber(t){ t.is(3.3, JSON.parse('{"foo":3.3}', true).foo)},
-		function strictNumberNeg(t){ t.is(-3.3, JSON.parse('{"foo":-3.3}', true).foo)},
-		function exponentNegative(t){ t.is(3.3e-33, JSON.parse('{"foo":3.3e-33}', true).foo)},
-		function exponent(t){ t.is(3.3e33, JSON.parse('{"foo":3.3e33}', true).foo)},
-		function array(t){ t.is(3, JSON.parse('{"foo":[3,true,[]]}', true).foo[0])},
-		function badCall(t){ mustThrow('{"foo":alert()}')},
-		function badMath(t){ mustThrow('{"foo":3+4}')},
-		function badIndex(t){ mustThrow('{"foo":"bar"}[3]')},
-		function badKey(t){ mustThrow('{foo:"bar"}')},
+		function simpleString(t){ t.is("bar", JSON.parse('{"foo":"bar"}').foo); },
+		function simpleTrue(t){ t.is(true, JSON.parse('{"foo":true}').foo); },
+		function simpleFalse(t){ t.is(false, JSON.parse('{"foo":false}').foo); },
+		function simpleNull(t){ t.is(null, JSON.parse('{"foo":null}').foo); },
+		function simpleNumber(t){ t.is(3.3, JSON.parse('{"foo":3.3}', true).foo); },
+		function strictString(t){ t.is("bar", JSON.parse('{"foo":"bar"}', true).foo); },
+		function strictEmptyString(t){ t.is("", JSON.parse('{"foo":""}', true).foo); },
+		function strictStringEsc(t){ t.is("b\n\t\"ar()", JSON.parse('{"foo":"b\\n\\t\\"ar()"}', true).foo); },
+		function strictTrue(t){ t.is(true, JSON.parse('{"foo":true}', true).foo); },
+		function strictFalse(t){ t.is(false, JSON.parse('{"foo":false}', true).foo); },
+		function strictNull(t){ t.is(null, JSON.parse('{"foo":null}', true).foo); },
+		function strictNumber(t){ t.is(3.3, JSON.parse('{"foo":3.3}', true).foo); },
+		function strictNumberNeg(t){ t.is(-3.3, JSON.parse('{"foo":-3.3}', true).foo); },
+		function exponentNegative(t){ t.is(3.3e-33, JSON.parse('{"foo":3.3e-33}', true).foo); },
+		function exponent(t){ t.is(3.3e33, JSON.parse('{"foo":3.3e33}', true).foo); },
+		function array(t){ t.is(3, JSON.parse('{"foo":[3,true,[]]}', true).foo[0]); },
+		function badCall(t){ mustThrow('{"foo":alert()}'); },
+		function badMath(t){ mustThrow('{"foo":3+4}'); },
+		function badIndex(t){ mustThrow('{"foo":"bar"}[3]'); },
+		function badKey(t){ mustThrow('{foo:"bar"}'); },
 		//function badKey2(t){ mustThrow('{2:"bar"}')},
-		function badUnbalanced(t){ mustThrow('[')},
-		function badUnbalanced2(t){ mustThrow('}')},
-		function badType(t){ mustThrow('["foo":"bar"]')},
-		function badUnbalanced2(t){ mustThrow('}')},
-		function serializeString(t){ t.is('{"foo":"bar"}', JSON.stringify({"foo":"bar"}))},
-		function serializeNull(t){ t.is('{"foo":null}', JSON.stringify({"foo":null}))},
-		function serializeFunction(t){ t.is('{}', JSON.stringify({"foo":function(){}}))},
-		function serializeNaN(t){ t.is('{"foo":null}', JSON.stringify({"foo":NaN}))},
-		function serializeInfinity(t){ t.is('{"foo":null}', JSON.stringify({"foo":Infinity}))},
+		function badUnbalanced(t){ mustThrow('['); },
+		function badUnbalanced2(t){ mustThrow('}'); },
+		function badType(t){ mustThrow('["foo":"bar"]'); },
+		function badUnbalanced2(t){ mustThrow('}'); },
+		function serializeString(t){ t.is('{"foo":"bar"}', JSON.stringify({"foo":"bar"})); },
+		function serializeNull(t){ t.is('{"foo":null}', JSON.stringify({"foo":null})); },
+		function serializeFunction(t){ t.is('{}', JSON.stringify({"foo":function(){}})); },
+		function serializeNaN(t){ t.is('{"foo":null}', JSON.stringify({"foo":NaN})); },
+		function serializeInfinity(t){ t.is('{"foo":null}', JSON.stringify({"foo":Infinity})); },
 		// there is differences in how many decimals of accuracies in seconds in how Dates are serialized between browsers
-		function serializeDate(t){ t.t(/1970-01-01T00:00:00.*Z/.test(JSON.parse(JSON.stringify({"foo":new Date(1)})).foo));},
-		function serializeCircular(t){
-			try{
-				var a = {};
-				a.a = a;
-				console.log("circular: " + JSON.stringify(a));
-			}catch(e){
-				return;
-			}
-			throw new Error("stringify must throw for circular references");
-
+		function serializeDate(t){ t.t(/1970-01-01T00:00:00.*Z/.test(JSON.parse(JSON.stringify({"foo":new Date(1)})).foo)); },
+		function serializeInherited(t){
+			function FooBar() { this.foo = "foo"; }
+			FooBar.prototype.bar = "bar";
+			t.is('{"foo":"foo"}', JSON.stringify(new FooBar()));
 		},
 		/*Apparently Firefox doesn't pass the key to the toJSON method*/
-		function serializeToJSON(t){ t.is('{"foo":{"name":"value"}}', JSON.stringify({foo:{toJSON:function(key){return {name:"value"};}}}))}
+		function serializeToJSON(t){ t.is('{"foo":{"name":"value"}}', JSON.stringify({foo:{toJSON:function(key){return {name:"value"}; }}})); }
 	]);
 
+	if(!has("host-rhino")){
+		doh.register("tests.json.circular", [
+			function serializeCircular(t){
+				try{
+					var a = {};
+					a.a = a;
+					console.log("circular: " + JSON.stringify(a));
+				}catch(e){
+					return;
+				}
+				throw new Error("stringify must throw for circular references");
+
+			}
+		]);
+	}
+
 var smallDataSet = {
 	prop1: null,
 	prop2: true,
diff --git a/dojo/tests/module.js b/dojo/tests/module.js
index c2f88b8..0f81774 100644
--- a/dojo/tests/module.js
+++ b/dojo/tests/module.js
@@ -1,23 +1,32 @@
 define([
 	"dojo/tests/_base",
+	"dojo/tests/promise",
 	"dojo/tests/cache",
 	"dojo/tests/i18n",
 	"dojo/tests/cldr",
 	"dojo/tests/store",
 	"dojo/tests/data",
 	"dojo/tests/date",
+	"dojo/tests/date/locale",
+	"dojo/tests/date/stamp",
 	"dojo/tests/on",
+	"dojo/tests/mouse",
 	"dojo/tests/json",
 	"dojo/tests/aspect",
 	"dojo/tests/number",
 	"dojo/tests/currency",
 	"dojo/tests/AdapterRegistry",
+	"dojo/tests/query",
 	"dojo/tests/regexp",
 	"dojo/tests/store",
 	"dojo/tests/string",
 	"dojo/tests/colors",
 	"dojo/tests/DeferredList",
 	"dojo/tests/Stateful",
+	"dojo/tests/errors",
+	"dojo/has!host-node?dojo/tests/node",
+	"dojo/has!host-browser?dojo/tests/router",
+	"dojo/has!host-browser?dojo/tests/request",
 	"dojo/has!host-browser?dojo/tests/behavior",
 	"dojo/has!host-browser?dojo/tests/parser",
 	"dojo/has!host-browser?dojo/tests/html",
diff --git a/dojo/tests/mouse.js b/dojo/tests/mouse.js
new file mode 100644
index 0000000..4a2f49f
--- /dev/null
+++ b/dojo/tests/mouse.js
@@ -0,0 +1,53 @@
+define(["doh", "dojo/mouse", "dojo/on"], function(doh, mouse, on){
+
+	doh.register("tests.on", [
+		function mouseenter(t){
+			var order = [];
+			var div = document.body.appendChild(document.createElement("div"));
+			div2 = div.appendChild(document.createElement("div"));
+			div2.className = "item two";
+			div2.id = 2;
+			div3 = div.appendChild(document.createElement("div"));
+			div3.className = "item three";
+			div3.id = 3;
+			div4 = div2.appendChild(document.createElement("div"));
+			on(div, on.selector(".item", mouse.enter), function(){
+				order.push(this.id);
+			});
+			on.emit(div, "mouseover", {
+				bubbles: true,
+				relatedTarget: document.body
+			});
+			on.emit(div3, "mouseover", {
+				bubbles: true,
+				relatedTarget: div
+			});
+			on.emit(div3, "mouseover", {
+				bubbles: true,
+				relatedTarget: div3
+			});
+			on.emit(div2, "mouseover", {
+				bubbles: true,
+				relatedTarget: div3
+			});
+			on.emit(div4, "mouseover", {
+				bubbles: true,
+				relatedTarget: div2
+			});
+			on.emit(div2, "mouseover", {
+				bubbles: true,
+				relatedTarget: div4
+			});
+			on.emit(div, "mouseover", {
+				bubbles: true,
+				relatedTarget: div2
+			});
+			on.emit(div4, "mouseover", {
+				bubbles: true,
+				relatedTarget: div
+			});
+			t.is(order, [3, 2, 2]);
+			
+		}
+	]);
+});
diff --git a/dojo/tests/node.js b/dojo/tests/node.js
new file mode 100644
index 0000000..733a970
--- /dev/null
+++ b/dojo/tests/node.js
@@ -0,0 +1,55 @@
+define([ "require", "doh/main" ], function(require, doh){
+	doh.register("tests.node", [
+		function testRequireBuiltIn(t){
+			var td = new doh.Deferred();
+			require(["dojo/node!util"], td.getTestCallback(function(util){
+				t.t("puts" in util, "this is the built in node module");
+			}));
+			return td;
+		},
+
+		function testRequireMissing(t){
+			try{
+				require(["dojo/node!missing"]);
+			}catch(e){
+				t.is(e.name, "Error", "plugin threw an error");
+				t.is(e.message, "Cannot find module 'missing'", "module is missing");
+			}
+		},
+
+		function testRequireSimpleModule(t){
+			var td = new doh.Deferred();
+			require(["dojo/node!./resources/nodemodule"], td.getTestCallback(function(nodemodule){
+				t.t("test" in nodemodule, "module loaded");
+				t.is(nodemodule.test, "value", "object has expected value");
+			}));
+			return td;
+		},
+
+		function testRequireRequire(t){
+			var td = new doh.Deferred();
+			require(["dojo/node!./resources/noderequire"], td.getTestCallback(function(noderequire){
+				t.t("test" in noderequire, "module loaded");
+				t.is(noderequire.test, "value", "object has expected value");
+			}));
+			return td;
+		},
+
+		function testRequirePackageJson(t){
+			var td = new doh.Deferred();
+			require(["dojo/node!./resources/nodemod"], td.getTestCallback(function(nodemod){
+				t.t("test" in nodemod, "module loaded");
+				t.is(nodemod.test, "value", "object has expected value");
+			}));
+			return td;
+		},
+
+		function testRequireCommonJSAMD(t){
+			var td = new doh.Deferred();
+			require(["dojo/node!./resources/noderequireamd"], td.getTestCallback(function(noderequireamd){
+				t.t(noderequireamd.nodeamd.test === "foo", "module loaded");
+			}));
+			return td;
+		}
+	]);
+});
\ No newline at end of file
diff --git a/dojo/tests/number.js b/dojo/tests/number.js
index d30bcbe..69aa26c 100644
--- a/dojo/tests/number.js
+++ b/dojo/tests/number.js
@@ -1,4 +1,4 @@
-define(["../main", "doh", "../number", "../i18n"], function(dojo, doh){
+define(["doh/main", "../_base/array", "../number", "../i18n"], function(doh, array, number, i18n){
 var tests= {number:{}};
 /**
  * Refer to ICU4J's NumberFormatTest.expect(...)
@@ -25,18 +25,18 @@ tests.number.checkFormatParseCycle=function(t,options,sourceInput,expectResult,
 	var str = null==pattern?"default":pattern;
 	//print("pattern:" + str + "| locale:" + locale);
 	//print("input:" + sourceInput);
-	var result = dojo.number.format(sourceInput,options);
+	var result = number.format(sourceInput,options);
 	//print("result:" + result);
 	if(null != expectResult){
 	    t.is(expectResult,result);
 	}
 	if(backwardCheck){
-		var resultParsed = dojo.number.parse(result,options);
+		var resultParsed = number.parse(result,options);
 		//print("resultParsed:" + resultParsed);
 		if(!tests.number._decimalNumberDiff(sourceInput,resultParsed)){
 		    t.is(sourceInput,resultParsed);
 		}
-		var resultParsedReformatted = dojo.number.format(resultParsed,options);
+		var resultParsedReformatted = number.format(resultParsed,options);
 		//print("resultParsedReformatted:" + resultParsedReformatted);
 	    if(!tests.number._decimalNumberDiff(result,resultParsedReformatted)){
 			t.is(result,resultParsedReformatted);
@@ -53,7 +53,7 @@ tests.number.checkParse=function(t,options,sourceInput,expectResult){
 		str = options.pattern;
 	}
 	//print("input:" + sourceInput);
-	var result = dojo.number.parse(sourceInput,options);
+	var result = number.parse(sourceInput,options);
 	//print("result :" + result);
 	if(null != expectResult){
 	    t.is(expectResult,result);
@@ -63,10 +63,10 @@ tests.number.checkParse=function(t,options,sourceInput,expectResult){
 /**
  * //TODO:Round a given number
  */
-tests.number.rounding = function(t,number,maxFractionDigits,expected){
+tests.number.rounding = function(t,num,maxFractionDigits,expected){
 	var pattern="#0.";
 	for(var i=0; i<maxFractionDigits; i++){pattern += "#";}
-	var result = dojo.number.format(number,{locale:tests.number.locale, pattern:pattern});
+	var result = number.format(num,{locale:tests.number.locale, pattern:pattern});
 	t.is(expected,result);
 };
 
@@ -83,7 +83,7 @@ function runBatchParse(options,dataArray/*array*/,pass/*boolean*/){
 	for(; i<dataArray.length; i++){
 		try{
 			//print("["+i+"]"+"input:"+dataArray[i]);
-			result = dojo.number.parse(dataArray[i],options);
+			result = number.parse(dataArray[i],options);
 			if(isNaN(result)){
 				throw "\"" + dataArray[i] + "\" is parsed to NaN with pattern " + str;
 			}
@@ -94,7 +94,7 @@ function runBatchParse(options,dataArray/*array*/,pass/*boolean*/){
 		}
 	}
 
-	if(!pass && (exception == null)) {
+	if(!pass && (exception == null)){
 		throw "runBatchParse() - stric parse failed, no exception when parsing illegal data";
 	}else if(exception != null){
 		if(!pass && i == 0){
@@ -141,7 +141,7 @@ doh.register("tests.number",
 					var
 						def = new doh.Deferred(),
 						deps = [];
-					dojo.forEach(partLocaleList, function(locale){
+					array.forEach(partLocaleList, function(locale){
 						deps.push(dojo.getL10nName("dojo/cldr", "number", locale));
 					});
 					require(deps, function(){
@@ -150,7 +150,7 @@ doh.register("tests.number",
 					return def;
 				}else{ // tests for the v1.x loader/i18n machinery
 					for(var i = 0 ; i < partLocaleList.length; i ++){
-						dojo.i18n.getLocalization("dojo.cldr","number",partLocaleList[i]);
+						i18n.getLocalization("dojo.cldr","number",partLocaleList[i]);
 					}
 				}
 			}
@@ -158,144 +158,149 @@ doh.register("tests.number",
 		{
 			name: "invalid",
 			runTest: function(t){
-				t.t(null === dojo.number.format(NaN));
-				t.t(null === dojo.number.format(Number.NaN));
-				t.t(null === dojo.number.format(Infinity));
-				t.t(null === dojo.number.format(-Infinity));
+				t.t(null === number.format(NaN));
+				t.t(null === number.format(Number.NaN));
+				t.t(null === number.format(Infinity));
+				t.t(null === number.format(-Infinity));
 			}
 		},
 		{
 			name: "round",
 			runTest: function(t){
-				t.is(0, dojo.number.round(0));
-				t.is(1, dojo.number.round(0.5));
-				t.is(-1, dojo.number.round(-0.5));
-				t.is(0.1, dojo.number.round(0.05, 1));
-				t.is(-0.1, dojo.number.round(-0.05, 1));
-				t.is(1.1, dojo.number.round(1.05, 1));
-				t.is(-1.1, dojo.number.round(-1.05, 1));
-//				t.is(-162.29, dojo.number.round(-162.295, 2)); // see ticket #7930, dojox.math.round
-//				t.is(162.29, dojo.number.round(162.295, 2)); // ibid
+				t.is(0, number.round(0));
+				t.is(1, number.round(0.5));
+				t.is(-1, number.round(-0.5));
+				t.is(0.1, number.round(0.05, 1));
+				t.is(0.1, number.round(0.09, 1));
+				t.is(0.0, number.round(0.04999999, 1));
+				t.is(0.1, number.round(0.09499999, 1));
+				t.is(0.1, number.round(0.095, 1));
+				t.is(0.1, number.round(0.09999999, 1));
+				t.is(-0.1, number.round(-0.05, 1));
+				t.is(1.1, number.round(1.05, 1));
+				t.is(-1.1, number.round(-1.05, 1));
+//				t.is(-162.29, number.round(-162.295, 2)); // see ticket #7930, dojox.math.round
+//				t.is(162.29, number.round(162.295, 2)); // ibid
 			}
 		},
 		{
 			name: "round_multiple",
 			runTest: function(t){
-				t.is("123.455", dojo.number.round(123.4525, 2, 5));
-				t.is("123.45", dojo.number.round(123.452, 2, 5));
-				t.is("123.455", dojo.number.round(123.454, 2, 5));
-				t.is("123.455", dojo.number.round(123.456, 2, 5));
-				t.is("-123.45", dojo.number.round(-123.452, 2, 5));
-				t.is("-123.455", dojo.number.round(-123.4525, 2, 5));
-				t.is("-123.455", dojo.number.round(-123.454, 2, 5));
-				t.is("-123.455", dojo.number.round(-123.456, 2, 5));
+				t.is("123.455", number.round(123.4525, 2, 5));
+				t.is("123.45", number.round(123.452, 2, 5));
+				t.is("123.455", number.round(123.454, 2, 5));
+				t.is("123.455", number.round(123.456, 2, 5));
+				t.is("-123.45", number.round(-123.452, 2, 5));
+				t.is("-123.455", number.round(-123.4525, 2, 5));
+				t.is("-123.455", number.round(-123.454, 2, 5));
+				t.is("-123.455", number.round(-123.456, 2, 5));
 			}
 		},
 		{
 			name: "round_speleotrove",
 			runTest: function(t){
 				// submitted Mike Cowlishaw (IBM, CCLA), see http://speleotrove.com/decimal/#testcases
-				t.is(12345, dojo.number.round(12345 + -0.1), "radx200");
-				t.is(12345, dojo.number.round(12345 + -0.01), "radx201");
-				t.is(12345, dojo.number.round(12345 + -0.001), "radx202");
-				t.is(12345, dojo.number.round(12345 + -0.00001), "radx203");
-				t.is(12345, dojo.number.round(12345 + -0.000001), "radx204");
-				t.is(12345, dojo.number.round(12345 + -0.0000001), "radx205");
-				t.is(12345, dojo.number.round(12345 +  0), "radx206");
-				t.is(12345, dojo.number.round(12345 +  0.0000001), "radx207");
-				t.is(12345, dojo.number.round(12345 +  0.000001), "radx208");
-				t.is(12345, dojo.number.round(12345 +  0.00001), "radx209");
-				t.is(12345, dojo.number.round(12345 +  0.0001), "radx210");
-				t.is(12345, dojo.number.round(12345 +  0.001), "radx211");
-				t.is(12345, dojo.number.round(12345 +  0.01), "radx212");
-				t.is(12345, dojo.number.round(12345 +  0.1), "radx213");
-
-				t.is(12346, dojo.number.round(12346 +  0.49999), "radx215");
-				t.is(12347, dojo.number.round(12346 +  0.5), "radx216");
-				t.is(12347, dojo.number.round(12346 +  0.50001), "radx217");
-
-				t.is(12345, dojo.number.round(12345 +  0.4), "radx220");
-				t.is(12345, dojo.number.round(12345 +  0.49), "radx221");
-				t.is(12345, dojo.number.round(12345 +  0.499), "radx222");
-				t.is(12345, dojo.number.round(12345 +  0.49999), "radx223");
-				t.is(12346, dojo.number.round(12345 +  0.5), "radx224");
-				t.is(12346, dojo.number.round(12345 +  0.50001), "radx225");
-				t.is(12346, dojo.number.round(12345 +  0.5001), "radx226");
-				t.is(12346, dojo.number.round(12345 +  0.501), "radx227");
-				t.is(12346, dojo.number.round(12345 +  0.51), "radx228");
-				t.is(12346, dojo.number.round(12345 +  0.6), "radx229");
+				t.is(12345, number.round(12345 + -0.1), "radx200");
+				t.is(12345, number.round(12345 + -0.01), "radx201");
+				t.is(12345, number.round(12345 + -0.001), "radx202");
+				t.is(12345, number.round(12345 + -0.00001), "radx203");
+				t.is(12345, number.round(12345 + -0.000001), "radx204");
+				t.is(12345, number.round(12345 + -0.0000001), "radx205");
+				t.is(12345, number.round(12345 +  0), "radx206");
+				t.is(12345, number.round(12345 +  0.0000001), "radx207");
+				t.is(12345, number.round(12345 +  0.000001), "radx208");
+				t.is(12345, number.round(12345 +  0.00001), "radx209");
+				t.is(12345, number.round(12345 +  0.0001), "radx210");
+				t.is(12345, number.round(12345 +  0.001), "radx211");
+				t.is(12345, number.round(12345 +  0.01), "radx212");
+				t.is(12345, number.round(12345 +  0.1), "radx213");
+
+				t.is(12346, number.round(12346 +  0.49999), "radx215");
+				t.is(12347, number.round(12346 +  0.5), "radx216");
+				t.is(12347, number.round(12346 +  0.50001), "radx217");
+
+				t.is(12345, number.round(12345 +  0.4), "radx220");
+				t.is(12345, number.round(12345 +  0.49), "radx221");
+				t.is(12345, number.round(12345 +  0.499), "radx222");
+				t.is(12345, number.round(12345 +  0.49999), "radx223");
+				t.is(12346, number.round(12345 +  0.5), "radx224");
+				t.is(12346, number.round(12345 +  0.50001), "radx225");
+				t.is(12346, number.round(12345 +  0.5001), "radx226");
+				t.is(12346, number.round(12345 +  0.501), "radx227");
+				t.is(12346, number.round(12345 +  0.51), "radx228");
+				t.is(12346, number.round(12345 +  0.6), "radx229");
 
 				//negatives
-				t.is(-12345, dojo.number.round(-12345 + -0.1), "rsux200");
-				t.is(-12345, dojo.number.round(-12345 + -0.01), "rsux201");
-				t.is(-12345, dojo.number.round(-12345 + -0.001), "rsux202");
-				t.is(-12345, dojo.number.round(-12345 + -0.00001), "rsux203");
-				t.is(-12345, dojo.number.round(-12345 + -0.000001), "rsux204");
-				t.is(-12345, dojo.number.round(-12345 + -0.0000001), "rsux205");
-				t.is(-12345, dojo.number.round(-12345 +  0), "rsux206");
-				t.is(-12345, dojo.number.round(-12345 +  0.0000001), "rsux207");
-				t.is(-12345, dojo.number.round(-12345 +  0.000001), "rsux208");
-				t.is(-12345, dojo.number.round(-12345 +  0.00001), "rsux209");
-				t.is(-12345, dojo.number.round(-12345 +  0.0001), "rsux210");
-				t.is(-12345, dojo.number.round(-12345 +  0.001), "rsux211");
-				t.is(-12345, dojo.number.round(-12345 +  0.01), "rsux212");
-				t.is(-12345, dojo.number.round(-12345 +  0.1), "rsux213");
-
-				t.is(-12346, dojo.number.round(-12346 +  0.49999), "rsux215");
-				t.is(-12346, dojo.number.round(-12346 +  0.5), "rsux216");
-				t.is(-12345, dojo.number.round(-12346 +  0.50001   ), "rsux217");
-
-				t.is(-12345, dojo.number.round(-12345 +  0.4), "rsux220");
-				t.is(-12345, dojo.number.round(-12345 +  0.49), "rsux221");
-				t.is(-12345, dojo.number.round(-12345 +  0.499), "rsux222");
-				t.is(-12345, dojo.number.round(-12345 +  0.49999), "rsux223");
-				t.is(-12345, dojo.number.round(-12345 +  0.5), "rsux224");
-				t.is(-12344, dojo.number.round(-12345 +  0.50001), "rsux225");
-				t.is(-12344, dojo.number.round(-12345 +  0.5001), "rsux226");
-				t.is(-12344, dojo.number.round(-12345 +  0.501), "rsux227");
-				t.is(-12344, dojo.number.round(-12345 +  0.51), "rsux228");
-				t.is(-12344, dojo.number.round(-12345 +  0.6), "rsux229");
-
-				t.is(12345, dojo.number.round(  12345 /  1), "rdvx401");
-				t.is(12344, dojo.number.round(  12345 /  1.0001), "rdvx402");
-				t.is(12333, dojo.number.round(  12345 /  1.001), "rdvx403");
-				t.is(12223, dojo.number.round(  12345 /  1.01), "rdvx404");
-				t.is(11223, dojo.number.round(  12345 /  1.1), "rdvx405");
-
-				t.is(3088.8, dojo.number.round( 12355 /  4, 1), "rdvx406");
-				t.is(3086.3, dojo.number.round( 12345 /  4, 1), "rdvx407");
-				t.is(3088.7, dojo.number.round( 12355 /  4.0001, 1), "rdvx408");
-				t.is(3086.2, dojo.number.round( 12345 /  4.0001, 1), "rdvx409");
-				t.is(2519.4, dojo.number.round( 12345 /  4.9, 1), "rdvx410");
-				t.is(2473.9, dojo.number.round( 12345 /  4.99, 1), "rdvx411");
-				t.is(2469.5, dojo.number.round( 12345 /  4.999, 1), "rdvx412");
-				t.is(2469.0, dojo.number.round( 12345 /  4.9999, 1), "rdvx413");
-				t.is(2469, dojo.number.round( 12345 /  5, 1), "rdvx414");
-				t.is(2469.0, dojo.number.round( 12345 /  5.0001, 1), "rdvx415");
-				t.is(2468.5, dojo.number.round( 12345 /  5.001, 1), "rdvx416");
-				t.is(2464.1, dojo.number.round( 12345 /  5.01, 1), "rdvx417");
-				t.is(2420.6, dojo.number.round( 12345 /  5.1, 1), "rdvx418");
-
-				t.is(12345, dojo.number.round(  12345 *  1), "rmux401");
-				t.is(12346, dojo.number.round(  12345 *  1.0001), "rmux402");
-				t.is(12357, dojo.number.round(  12345 *  1.001), "rmux403");
-				t.is(12468, dojo.number.round(  12345 *  1.01), "rmux404");
-				t.is(13580, dojo.number.round(  12345 *  1.1), "rmux405");
-				t.is(49380, dojo.number.round(  12345 *  4), "rmux406");
-				t.is(49381, dojo.number.round(  12345 *  4.0001), "rmux407");
-				t.is(60491, dojo.number.round(  12345 *  4.9), "rmux408");
-				t.is(61602, dojo.number.round(  12345 *  4.99), "rmux409");
-				t.is(61713, dojo.number.round(  12345 *  4.999), "rmux410");
-				t.is(61724, dojo.number.round(  12345 *  4.9999), "rmux411");
-				t.is(61725, dojo.number.round(  12345 *  5), "rmux412");
-				t.is(61726, dojo.number.round(  12345 *  5.0001), "rmux413");
-				t.is(61737, dojo.number.round(  12345 *  5.001), "rmux414");
-				t.is(61848, dojo.number.round(  12345 *  5.01), "rmux415");
+				t.is(-12345, number.round(-12345 + -0.1), "rsux200");
+				t.is(-12345, number.round(-12345 + -0.01), "rsux201");
+				t.is(-12345, number.round(-12345 + -0.001), "rsux202");
+				t.is(-12345, number.round(-12345 + -0.00001), "rsux203");
+				t.is(-12345, number.round(-12345 + -0.000001), "rsux204");
+				t.is(-12345, number.round(-12345 + -0.0000001), "rsux205");
+				t.is(-12345, number.round(-12345 +  0), "rsux206");
+				t.is(-12345, number.round(-12345 +  0.0000001), "rsux207");
+				t.is(-12345, number.round(-12345 +  0.000001), "rsux208");
+				t.is(-12345, number.round(-12345 +  0.00001), "rsux209");
+				t.is(-12345, number.round(-12345 +  0.0001), "rsux210");
+				t.is(-12345, number.round(-12345 +  0.001), "rsux211");
+				t.is(-12345, number.round(-12345 +  0.01), "rsux212");
+				t.is(-12345, number.round(-12345 +  0.1), "rsux213");
+
+				t.is(-12346, number.round(-12346 +  0.49999), "rsux215");
+				t.is(-12346, number.round(-12346 +  0.5), "rsux216");
+				t.is(-12345, number.round(-12346 +  0.50001   ), "rsux217");
+
+				t.is(-12345, number.round(-12345 +  0.4), "rsux220");
+				t.is(-12345, number.round(-12345 +  0.49), "rsux221");
+				t.is(-12345, number.round(-12345 +  0.499), "rsux222");
+				t.is(-12345, number.round(-12345 +  0.49999), "rsux223");
+				t.is(-12345, number.round(-12345 +  0.5), "rsux224");
+				t.is(-12344, number.round(-12345 +  0.50001), "rsux225");
+				t.is(-12344, number.round(-12345 +  0.5001), "rsux226");
+				t.is(-12344, number.round(-12345 +  0.501), "rsux227");
+				t.is(-12344, number.round(-12345 +  0.51), "rsux228");
+				t.is(-12344, number.round(-12345 +  0.6), "rsux229");
+
+				t.is(12345, number.round(  12345 /  1), "rdvx401");
+				t.is(12344, number.round(  12345 /  1.0001), "rdvx402");
+				t.is(12333, number.round(  12345 /  1.001), "rdvx403");
+				t.is(12223, number.round(  12345 /  1.01), "rdvx404");
+				t.is(11223, number.round(  12345 /  1.1), "rdvx405");
+
+				t.is(3088.8, number.round( 12355 /  4, 1), "rdvx406");
+				t.is(3086.3, number.round( 12345 /  4, 1), "rdvx407");
+				t.is(3088.7, number.round( 12355 /  4.0001, 1), "rdvx408");
+				t.is(3086.2, number.round( 12345 /  4.0001, 1), "rdvx409");
+				t.is(2519.4, number.round( 12345 /  4.9, 1), "rdvx410");
+				t.is(2473.9, number.round( 12345 /  4.99, 1), "rdvx411");
+				t.is(2469.5, number.round( 12345 /  4.999, 1), "rdvx412");
+				t.is(2469.0, number.round( 12345 /  4.9999, 1), "rdvx413");
+				t.is(2469, number.round( 12345 /  5, 1), "rdvx414");
+				t.is(2469.0, number.round( 12345 /  5.0001, 1), "rdvx415");
+				t.is(2468.5, number.round( 12345 /  5.001, 1), "rdvx416");
+				t.is(2464.1, number.round( 12345 /  5.01, 1), "rdvx417");
+				t.is(2420.6, number.round( 12345 /  5.1, 1), "rdvx418");
+
+				t.is(12345, number.round(  12345 *  1), "rmux401");
+				t.is(12346, number.round(  12345 *  1.0001), "rmux402");
+				t.is(12357, number.round(  12345 *  1.001), "rmux403");
+				t.is(12468, number.round(  12345 *  1.01), "rmux404");
+				t.is(13580, number.round(  12345 *  1.1), "rmux405");
+				t.is(49380, number.round(  12345 *  4), "rmux406");
+				t.is(49381, number.round(  12345 *  4.0001), "rmux407");
+				t.is(60491, number.round(  12345 *  4.9), "rmux408");
+				t.is(61602, number.round(  12345 *  4.99), "rmux409");
+				t.is(61713, number.round(  12345 *  4.999), "rmux410");
+				t.is(61724, number.round(  12345 *  4.9999), "rmux411");
+				t.is(61725, number.round(  12345 *  5), "rmux412");
+				t.is(61726, number.round(  12345 *  5.0001), "rmux413");
+				t.is(61737, number.round(  12345 *  5.001), "rmux414");
+				t.is(61848, number.round(  12345 *  5.01), "rmux415");
 /*
-				t.is(1.4814E+5, dojo.number.round(  12345 *  12), "rmux416");
-				t.is(1.6049E+5, dojo.number.round(  12345 *  13), "rmux417");
-				t.is(1.4826E+5, dojo.number.round(  12355 *  12), "rmux418");
-				t.is(1.6062E+5, dojo.number.round(  12355 *  13), "rmux419");
+				t.is(1.4814E+5, number.round(  12345 *  12), "rmux416");
+				t.is(1.6049E+5, number.round(  12345 *  13), "rmux417");
+				t.is(1.4826E+5, number.round(  12355 *  12), "rmux418");
+				t.is(1.6062E+5, number.round(  12355 *  13), "rmux419");
 */
 			}
 		},
@@ -303,92 +308,92 @@ doh.register("tests.number",
 			name: "format", // old tests
 			runTest: function(t){
 
-	t.is("0123", dojo.number.format(123, {pattern: "0000"}));
-	t.is("-12,34,567.890", dojo.number.format(-1234567.89, {pattern: "#,##,##0.000##", locale: 'en-us'}));
-	t.is("-12,34,567.89012", dojo.number.format(-1234567.890123, {pattern: "#,##,##0.000##", locale: 'en-us'}));
-	t.is("(1,234,567.89012)", dojo.number.format(-1234567.890123, {pattern: "#,##0.000##;(#,##0.000##)", locale: 'en-us'}));
-	t.is("(1,234,567.89012)", dojo.number.format(-1234567.890123, {pattern: "#,##0.000##;(#)", locale: 'en-us'}));
-	t.is("50.1%", dojo.number.format(0.501, {pattern: "#0.#%", locale: 'en-us'}));
-	t.is("98", dojo.number.format(1998, {pattern: "00"}));
-	t.is("01998", dojo.number.format(1998, {pattern: "00000"}));
-	t.is("0.13", dojo.number.format(0.125, {pattern: "0.##", locale: 'en-us'})); //NOTE: expects round_half_up, not round_half_even
-	t.is("0.1250", dojo.number.format(0.125, {pattern: "0.0000", locale: 'en-us'}));
-	t.is("0.1", dojo.number.format(0.100004, {pattern: "0.####", locale: 'en-us'}));
-
-	t.is("-12", dojo.number.format(-12.3, {places:0, locale: "en-us"}));
-	t.is("-1,234,567.89", dojo.number.format(-1234567.89, {locale: "en-us"}));
-//	t.is("-12,34,567.89", dojo.number.format(-1234567.89, {locale: "en-in"}));
-	t.is("-1,234,568", dojo.number.format(-1234567.89, {places:0, locale: "en-us"}));
-//	t.is("-12,34,568", dojo.number.format(-1234567.89, {places:0, locale: "en-in"}));
-	t.is("-1\xa0000,10", dojo.number.format(-1000.1, {places:2, locale: "fr-fr"}));
-	t.is("-1,000.10", dojo.number.format(-1000.1, {places:2, locale: "en-us"}));
-	t.is("-1\xa0000,10", dojo.number.format(-1000.1, {places:2, locale: "fr-fr"}));
-	t.is("-1.234,56", dojo.number.format(-1234.56, {places:2, locale: "de-de"}));
-	t.is("-1,000.10", dojo.number.format(-1000.1, {places:2, locale: "en-us"}));
-	t.is("123.46%", dojo.number.format(1.23456, {places:2, locale: "en-us", type: "percent"}));
-	t.is("123.4", dojo.number.format(123.4, {places:'1,3', locale: 'en-us'}));
-	t.is("123.45", dojo.number.format(123.45, {places:'1,3', locale: 'en-us'}));
-	t.is("123.456", dojo.number.format(123.456, {places:'1,3', locale: 'en-us'}));
+	t.is("0123", number.format(123, {pattern: "0000"}));
+	t.is("-12,34,567.890", number.format(-1234567.89, {pattern: "#,##,##0.000##", locale: 'en-us'}));
+	t.is("-12,34,567.89012", number.format(-1234567.890123, {pattern: "#,##,##0.000##", locale: 'en-us'}));
+	t.is("(1,234,567.89012)", number.format(-1234567.890123, {pattern: "#,##0.000##;(#,##0.000##)", locale: 'en-us'}));
+	t.is("(1,234,567.89012)", number.format(-1234567.890123, {pattern: "#,##0.000##;(#)", locale: 'en-us'}));
+	t.is("50.1%", number.format(0.501, {pattern: "#0.#%", locale: 'en-us'}));
+	t.is("98", number.format(1998, {pattern: "00"}));
+	t.is("01998", number.format(1998, {pattern: "00000"}));
+	t.is("0.13", number.format(0.125, {pattern: "0.##", locale: 'en-us'})); //NOTE: expects round_half_up, not round_half_even
+	t.is("0.1250", number.format(0.125, {pattern: "0.0000", locale: 'en-us'}));
+	t.is("0.1", number.format(0.100004, {pattern: "0.####", locale: 'en-us'}));
+
+	t.is("-12", number.format(-12.3, {places:0, locale: "en-us"}));
+	t.is("-1,234,567.89", number.format(-1234567.89, {locale: "en-us"}));
+//	t.is("-12,34,567.89", number.format(-1234567.89, {locale: "en-in"}));
+	t.is("-1,234,568", number.format(-1234567.89, {places:0, locale: "en-us"}));
+//	t.is("-12,34,568", number.format(-1234567.89, {places:0, locale: "en-in"}));
+	t.is("-1\xa0000,10", number.format(-1000.1, {places:2, locale: "fr-fr"}));
+	t.is("-1,000.10", number.format(-1000.1, {places:2, locale: "en-us"}));
+	t.is("-1\xa0000,10", number.format(-1000.1, {places:2, locale: "fr-fr"}));
+	t.is("-1.234,56", number.format(-1234.56, {places:2, locale: "de-de"}));
+	t.is("-1,000.10", number.format(-1000.1, {places:2, locale: "en-us"}));
+	t.is("123.46%", number.format(1.23456, {places:2, locale: "en-us", type: "percent"}));
+	t.is("123.4", number.format(123.4, {places:'1,3', locale: 'en-us'}));
+	t.is("123.45", number.format(123.45, {places:'1,3', locale: 'en-us'}));
+	t.is("123.456", number.format(123.456, {places:'1,3', locale: 'en-us'}));
 
 	//rounding
-	t.is("-1,234,568", dojo.number.format(-1234567.89, {places:0, locale: "en-us"}));
-//	t.is("-12,34,568", dojo.number.format(-1234567.89, {places:0, locale: "en-in"}));
-	t.is("-1,000.11", dojo.number.format(-1000.114, {places:2, locale: "en-us"}));
-	t.is("-1,000.12", dojo.number.format(-1000.115, {places:2, locale: "en-us"}));
-	t.is("-1,000.12", dojo.number.format(-1000.116, {places:2, locale: "en-us"}));
-	t.is("-0.00", dojo.number.format(-0.0001, {places:2, locale: "en-us"}));
-	t.is("0.00", dojo.number.format(0, {places:2, locale: "en-us"}));
+	t.is("-1,234,568", number.format(-1234567.89, {places:0, locale: "en-us"}));
+//	t.is("-12,34,568", number.format(-1234567.89, {places:0, locale: "en-in"}));
+	t.is("-1,000.11", number.format(-1000.114, {places:2, locale: "en-us"}));
+	t.is("-1,000.12", number.format(-1000.115, {places:2, locale: "en-us"}));
+	t.is("-1,000.12", number.format(-1000.116, {places:2, locale: "en-us"}));
+	t.is("-0.00", number.format(-0.0001, {places:2, locale: "en-us"}));
+	t.is("0.00", number.format(0, {places:2, locale: "en-us"}));
 
 	//change decimal places
-	t.is("-1\xa0000,100", dojo.number.format(-1000.1, {places:3, locale: "fr-fr"}));
-	t.is("-1,000.100", dojo.number.format(-1000.1, {places:3, locale: "en-us"}));
+	t.is("-1\xa0000,100", number.format(-1000.1, {places:3, locale: "fr-fr"}));
+	t.is("-1,000.100", number.format(-1000.1, {places:3, locale: "en-us"}));
 			}
 		},
 		{
 			name: "parse", // old tests
 			runTest: function(t){
-	t.is(1000, dojo.number.parse("1000", {locale: "en-us"}));
-	t.is(1000.123, dojo.number.parse("1000.123", {locale: "en-us"}));
-	t.is(1000, dojo.number.parse("1,000", {locale: "en-us"}));
-	t.is(-1000, dojo.number.parse("-1000", {locale: "en-us"}));
-	t.is(-1000.123, dojo.number.parse("-1000.123", {locale: "en-us"}));
-	t.is(-1234567.89, dojo.number.parse("-1,234,567.89", {locale: "en-us"}));
-	t.is(-1234567.89, dojo.number.parse("-1 234 567,89", {locale: "fr-fr"}));
-	t.t(isNaN(dojo.number.parse("-1 234 567,89", {locale: "en-us"})));
+	t.is(1000, number.parse("1000", {locale: "en-us"}));
+	t.is(1000.123, number.parse("1000.123", {locale: "en-us"}));
+	t.is(1000, number.parse("1,000", {locale: "en-us"}));
+	t.is(-1000, number.parse("-1000", {locale: "en-us"}));
+	t.is(-1000.123, number.parse("-1000.123", {locale: "en-us"}));
+	t.is(-1234567.89, number.parse("-1,234,567.89", {locale: "en-us"}));
+	t.is(-1234567.89, number.parse("-1 234 567,89", {locale: "fr-fr"}));
+	t.t(isNaN(number.parse("-1 234 567,89", {locale: "en-us"})));
 
-	t.is(123, dojo.number.parse("0123", {pattern: "0000"}));
+	t.is(123, number.parse("0123", {pattern: "0000"}));
 
-	t.t(isNaN(dojo.number.parse("10,00", {locale: "en-us"})));
-	t.t(isNaN(dojo.number.parse("1000.1", {locale: "fr-fr"})));
+	t.t(isNaN(number.parse("10,00", {locale: "en-us"})));
+	t.t(isNaN(number.parse("1000.1", {locale: "fr-fr"})));
 
-	t.t(isNaN(dojo.number.parse("")));
-	t.t(isNaN(dojo.number.parse("abcd")));
+	t.t(isNaN(number.parse("")));
+	t.t(isNaN(number.parse("abcd")));
 
 	// should allow unlimited precision, by default
-	t.is(1.23456789, dojo.number.parse("1.23456789", {locale: "en-us"}));
+	t.is(1.23456789, number.parse("1.23456789", {locale: "en-us"}));
 
 	//test whitespace
-//	t.is(-1234567, dojo.number.parse("  -1,234,567  ", {locale: "en-us"}));
-
-//	t.t(dojo.number.parse("9.1093826E-31"));
-	t.is(1.23, dojo.number.parse("123%", {locale: "en-us", type: "percent"}));
-	t.is(1.23, dojo.number.parse("123%", {places:0, locale: "en-us", type: "percent"}));
-	t.t(isNaN(dojo.number.parse("123.46%", {places:0, locale: "en-us", type: "percent"})));
-	t.is(1.2346, dojo.number.parse("123.46%", {places:2, locale: "en-us", type: "percent"}));
-	t.is(0.501, dojo.number.parse("50.1%", {pattern: "#0.#%", locale: 'en-us'}));
-
-	t.is(123.4, dojo.number.parse("123.4", {pattern: "#0.#", locale: 'en-us'}));
-	t.is(-123.4, dojo.number.parse("-123.4", {pattern: "#0.#", locale: 'en-us'}));
-	t.is(123.4, dojo.number.parse("123.4", {pattern: "#0.#;(#0.#)", locale: 'en-us'}));
-	t.is(-123.4, dojo.number.parse("(123.4)", {pattern: "#0.#;(#0.#)", locale: 'en-us'}));
-
-	t.is(null, dojo.number.format("abcd", {pattern: "0000"}));
-
-	t.is(123, dojo.number.parse("123", {places:0}));
-	t.is(123, dojo.number.parse("123", {places:'0'}));
-	t.is(123.4, dojo.number.parse("123.4", {places:1, locale: 'en-us'}));
-	t.is(123.45, dojo.number.parse("123.45", {places:'1,3', locale: 'en-us'}));
-	t.is(123.45, dojo.number.parse("123.45", {places:'0,2', locale: 'en-us'}));
+//	t.is(-1234567, number.parse("  -1,234,567  ", {locale: "en-us"}));
+
+//	t.t(number.parse("9.1093826E-31"));
+	t.is(1.23, number.parse("123%", {locale: "en-us", type: "percent"}));
+	t.is(1.23, number.parse("123%", {places:0, locale: "en-us", type: "percent"}));
+	t.t(isNaN(number.parse("123.46%", {places:0, locale: "en-us", type: "percent"})));
+	t.is(1.2346, number.parse("123.46%", {places:2, locale: "en-us", type: "percent"}));
+	t.is(0.501, number.parse("50.1%", {pattern: "#0.#%", locale: 'en-us'}));
+
+	t.is(123.4, number.parse("123.4", {pattern: "#0.#", locale: 'en-us'}));
+	t.is(-123.4, number.parse("-123.4", {pattern: "#0.#", locale: 'en-us'}));
+	t.is(123.4, number.parse("123.4", {pattern: "#0.#;(#0.#)", locale: 'en-us'}));
+	t.is(-123.4, number.parse("(123.4)", {pattern: "#0.#;(#0.#)", locale: 'en-us'}));
+
+	t.is(null, number.format("abcd", {pattern: "0000"}));
+
+	t.is(123, number.parse("123", {places:0}));
+	t.is(123, number.parse("123", {places:'0'}));
+	t.is(123.4, number.parse("123.4", {places:1, locale: 'en-us'}));
+	t.is(123.45, number.parse("123.45", {places:'1,3', locale: 'en-us'}));
+	t.is(123.45, number.parse("123.45", {places:'0,2', locale: 'en-us'}));
 			}
 		},
 		{
@@ -425,9 +430,9 @@ doh.register("tests.number",
 	*/
 
 	//in icu4j should throw out an exception when formatting a string,
-	//but it seems dojo.number.format can deal with strings
+	//but it seems number.format can deal with strings
 	//return 123,456,789
-	dojo.number.format("123456789");
+	number.format("123456789");
 
 	//!!Failed case, \u00a4 and ' are not replaced
 	/*
@@ -464,10 +469,10 @@ doh.register("tests.number",
 
 	//!!Failed case
 	//In ICU4J:
-	//        unquoted special characters in the suffix are illegal
-	//        so "000.000|###" is illegal; "000.000'|###'" is legal
-	//dojo.number.format:
-	//        when formatting 1.2 with illegal pattern "000.000|###"
+	//		  unquoted special characters in the suffix are illegal
+	//		  so "000.000|###" is illegal; "000.000'|###'" is legal
+	//number.format:
+	//		  when formatting 1.2 with illegal pattern "000.000|###"
 	//		  no exception was thrown but got "001.200|###" instead.
 
 	/*
@@ -478,7 +483,7 @@ doh.register("tests.number",
 		try{
 			//"001.200'|###'" is return for "000.000'|###'"
 			//"001.200|###" is return for "000.000|###"
-			result = dojo.number.format(1.2,{pattern:patterns[i]});
+			result = number.format(1.2,{pattern:patterns[i]});
 			print("["+i+"] 1.2 is formatted to " + result + " with pattern " + patterns[i]);
 		}catch(e){
 			exception = true;
@@ -516,7 +521,7 @@ doh.register("tests.number",
 	// is this case necessary?
 	/*
 	var pattern = "s'aa''s'c#";
-	var result = dojo.number.format(6666,{pattern:pattern,locale:"en-us"});
+	var result = number.format(6666,{pattern:pattern,locale:"en-us"});
 	var expectResult = "saa'sc6666";
 	t.is(expectResult,result);
 	*/
@@ -568,7 +573,7 @@ doh.register("tests.number",
 	//Pattern ###.###\u2030 should format 0.4857 as 485.7\u2030,but got 485.700\u2030 instead
 	pattern = "###.###\u2030";
 	expectResult = "485.7\u2030";
-	result = dojo.number.format(0.4857,{pattern:pattern, locale: 'en-us'});
+	result = number.format(0.4857,{pattern:pattern, locale: 'en-us'});
 	t.is(expectResult,result);
 
     //TODO: !!Failed mile percent case - ###.###m
@@ -576,7 +581,7 @@ doh.register("tests.number",
 	/*
 	pattern = "###.###m";
 	expectResult = "485.7m";
-	result = dojo.number.format(0.4857,{pattern:pattern,locale:"en"});
+	result = number.format(0.4857,{pattern:pattern,locale:"en"});
 	t.is(expectResult,result);
 	*/
 	//print("test_number_format_PerMill() end..............\n");
@@ -607,7 +612,7 @@ doh.register("tests.number",
 /*
 	sourceInput = 1876543210;
 	expectResult = "1,87,65,43,210";
-	var result = dojo.number.format(sourceInput,{locale:"en-in"});
+	var result = number.format(sourceInput,{locale:"en-in"});
 	t.is(expectResult,result);
 */
 	//print("test_number_format_Grouping() end..............\n");
@@ -727,7 +732,7 @@ function test_number_format_pad(){
 	//Refer to ICU4J's NumberFormatTest.TestParse() which is only a rudimentary version
 	var pattern = "00";
 	var str = "0.0";
-	var result = dojo.number.parse(str,{pattern:pattern, locale: 'en-us'});
+	var result = number.parse(str,{pattern:pattern, locale: 'en-us'});
 	//TODO: add more locales
 //FIXME: is this a valid test?
 //	t.is(0,result);
@@ -850,9 +855,9 @@ function test_number_format_pad(){
 	print("test_number_parse_WhiteSpace() start..............");
    	var pattern = "a  b#0c  ";
 	var expectResult = 3456;
-	result =  dojo.number.parse("a b3456c ",{pattern:pattern,locale:"en-us"});
+	result =  number.parse("a b3456c ",{pattern:pattern,locale:"en-us"});
    	t.is(expectResult,result);
-	result =  dojo.number.parse("a   b3456c   ",{pattern:pattern,locale:"en-us"});
+	result =  number.parse("a   b3456c   ",{pattern:pattern,locale:"en-us"});
 	t.is(expectResult,result);
 	print("test_number_parse_WhiteSpace() end..............\n");
 	*/
diff --git a/dojo/tests/on.js b/dojo/tests/on.js
index 73adabb..9c279e7 100644
--- a/dojo/tests/on.js
+++ b/dojo/tests/on.js
@@ -1,229 +1,3 @@
-dojo.provide("dojo.tests.on");
-
-var on = dojo.require("dojo.on");
-var has = dojo.require("dojo.has");
-var topic = dojo.require("dojo.topic");
-var Evented = dojo.require("dojo.Evented");
-doh.register("tests.on",
-	[
-		function object(t){
-			var order = [];
-			var obj = new dojo.Evented();
-			obj.oncustom = function(event){
-				order.push(event.a);
-				return event.a+1;
-			};
-			var signal = on.pausable(obj, "custom", function(event){
-				order.push(0);
-				return event.a+1;
-			});
-			obj.oncustom({a:0});
-			var signal2 = on(obj, "custom, foo", function(event){
-				order.push(event.a);
-			});
-			on.emit(obj, "custom", {
-				a: 3
-			});
-			signal.pause();
-			var signal3 = on(obj, "custom", function(a){
-				order.push(3);
-			}, true);
-			on.emit(obj, "custom", {
-				a: 3
-			});
-			signal2.remove();
-			signal.resume();
-			on.emit(obj, "custom", {
-				a: 6
-			});
-			signal3.remove();
-			var signal4 = on(obj, "foo, custom", function(a){
-				order.push(4);
-			}, true);
-			signal.remove();
-			on.emit(obj, "custom", {
-				a: 7
-			});
-			t.is(order, [0,0,3,0,3,3,3,3,6,0,3,7,4]);
-		},
-		function once(t){
-			var order = [];
-			var obj = new dojo.Evented();
-			obj.on("custom", function(event){
-				order.push(event.a);
-			});
-			var signal = on.once(obj, "custom", function(event){
-				order.push(1);
-			});
-			obj.emit("custom",{a:0});
-			obj.oncustom({a:2}); // should call original method, but not listener
-			t.is(order, [0,1,2]);
-		},
-		function dom(t){
-			var div = document.body.appendChild(document.createElement("div"));
-			var span = div.appendChild(document.createElement("span"));
-			var order = [];
-			var signal = on(div,"custom", function(event){
-				order.push(event.a);
-				event.addedProp += "ue";
-			});
-			on(span,"custom", function(event){
-				event.addedProp = "val";
-			});
-			on.emit(div, "custom", {
-				target: div,
-				currentTarget:div,
-				relatedTarget: div,
-				a: 0
-			});
-			on.emit(div, "otherevent", {
-				a: 0
-			});
-			t.is(on.emit(span, "custom", {
-				a: 1,
-				bubbles: true,
-				cancelable: true
-			}).addedProp, "value");
-			t.t(on.emit(span, "custom", {
-				a: 1,
-				bubbles: false,
-				cancelable: true
-			}));
-			var signal2 = on.pausable(div,"custom", function(event){
-				order.push(event.a + 1);
-				event.preventDefault();
-			});
-			t.f(on.emit(span, "custom", {
-				a: 2,
-				bubbles: true,
-				cancelable: true
-			}));
-			signal2.pause();
-			t.is(on.emit(span, "custom", {
-				a: 4,
-				bubbles: true,
-				cancelable: true
-			}).type, "custom");
-			signal2.resume();
-			signal.remove();
-			t.f(on.emit(span, "custom", {
-				a: 4,
-				bubbles: true,
-				cancelable: true
-			}));
-			on(span, "custom", function(event){
-				order.push(6);
-				event.stopPropagation();
-			});
-			t.t(on.emit(span, "custom", {
-				a: 1,
-				bubbles: true,
-				cancelable: true
-			}));
-			var button = div.appendChild(document.createElement("button"));
-			// make sure we are propagating natively created events too
-			signal = on(div, "click", function(){
-				order.push(7);
-			});
-			button.click();
-			signal.remove();
-			// test out event delegation
-			if(dojo.query){
-				// if dojo.query is loaded, test event delegation
-				on(div, "button:click", function(){
-					order.push(8);
-				});
-				button.click();
-			}else{//just pass then
-				order.push(8);
-			}
-			t.is(order, [0, 1, 2, 3, 4, 5, 6, 7, 8]);
-		},
-/*
- This only works if the test page has the focus, so you can enable if you want to test focus functionality and allow the test page to have focus  
- 		function focus(t){
-			var div = document.body.appendChild(document.createElement("div"));
-			var input = div.appendChild(document.createElement("input"));
-			var order = [];
-			var signal = on(div,"input:focusin", function(event){
-				order.push('in');
-			});
-			var signal = on(div,"input:focusout", function(event){
-				order.push('out');
-			});
-			var otherInput = document.body.appendChild(document.createElement("input"));
-			input.focus();
-			otherInput.focus();
-			d = new doh.Deferred();
-			setTimeout(function(){
-				t.is(['in', 'out'], order);
-				d.callback(true);
-			}, 1);
-			return d;
-		},*/
-		function extensionEvent(t){
-			var div = document.body.appendChild(document.createElement("div"));
-			var span = div.appendChild(document.createElement("span"));
-			span.setAttribute("foo", 2);
-			var order = [];
-			var customEvent = function(target, listener){
-				return on(target, "custom", listener);
-			};
-			var signal = on(div, customEvent, function(event){
-				order.push(event.a);
-			});
-			var signal = on(div, on.selector("span", customEvent), function(event){
-				order.push(+this.getAttribute("foo"));
-			});
-			on.emit(div, "custom", {
-				a: 0
-			});
-			// should trigger selector
-			t.t(on.emit(span, "custom", {
-				a: 1,
-				bubbles: true,
-				cancelable: true
-			}));
-			// shouldn't trigger selector
-			t.t(on.emit(div, "custom", {
-				a: 3,
-				bubbles: true,
-				cancelable: true
-			}));
-			t.is(order, [0, 1, 2, 3]);
-		},
-		function testEvented(t){
-			var MyClass = dojo.declare([Evented],{
-
-			});
-			var order = [];
-			myObject = new MyClass;
-			myObject.on("custom", function(event){
-				order.push(event.a);
-			});
-			myObject.emit("custom", {a:0});
-			t.is(order, [0]);
-		},
-		function pubsub(t){
-			var fooCount = 0;
-			topic.subscribe("/test/foo", function(event, secondArg){
-				t.is("value", event.foo);
-				t.is("second", secondArg);
-				fooCount++;
-			});
-			topic.publish("/test/foo", {foo: "value"}, "second");
-			t.is(1, fooCount);
-		},
-		function touch(t){
-			console.log("has", has);
-			if(has("touch")){
-				var div = document.body.appendChild(document.createElement("div"));
-				on(div, "touchstart", function(event){
-					t.t("rotation" in event);
-					t.t("pageX" in event);
-				});
-				on.emit(div, "touchstart", {changedTouches: [{pageX:100}]});
-			}
-		}
-	]
-);
+define([
+	"dojo/tests/on/on"
+], 1);
diff --git a/dojo/tests/on/bench.html b/dojo/tests/on/bench.html
new file mode 100644
index 0000000..4db54f3
--- /dev/null
+++ b/dojo/tests/on/bench.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>Dojo/on Performance Test</title>
+		<style type="text/css">
+			@import "../../resources/dojo.css";
+		</style>
+		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true, async:true"></script>
+		<script type="text/javascript">
+		require([
+			"dojo/dom",
+			"dojo/dom-construct",
+			"dojo/on",
+			"dojo/query",
+			"doh",
+			"dojo/domReady!"
+		], function(dom, domConstruct, on, query, doh){
+
+			doh.register("on() performance tests", [
+				{
+					name: "1000 on.emit() calls, no listeners",
+					testType: "perf",
+					trialIterations: 20,
+					setUp: function(){
+						dom.byId("status").innerHTML = "Running no listeners test...";
+						button = dom.byId("emitbutton");
+					},
+					tearDown: function(){
+					},
+					runTest: function(){
+						for(var i=0; i<1000; i++){
+							on.emit(button, "myevent", {bubbles: true, cancelable: true});
+						}
+					}
+				},
+				{
+					name: "1000 on.emit() calls, listener on same node",
+					testType: "perf",
+					trialIterations: 20,
+					setUp: function(){
+						dom.byId("status").innerHTML = "Running one listener test...";
+
+						cnt = 0;
+						on(button, "myevent", function(evt){ cnt++; } );
+					},
+					tearDown: function(){
+					},
+					runTest: function(){
+						for(var i=0; i<1000; i++){
+							on.emit(button, "myevent", {bubbles: true, cancelable: true});
+						}
+					}
+				},
+				{
+					name: "1000 on.emit() calls, listener on same node and ancestor",
+					testType: "perf",
+					trialIterations: 20,
+					setUp: function(){
+						dom.byId("status").innerHTML = "Running two listener test...";
+
+						on(dom.byId("emit"), "myevent", function(evt){ cnt++; } );
+					},
+					tearDown: function(){
+					},
+					runTest: function(){
+						for(var i=0; i<1000; i++){
+							on.emit(button, "myevent", {bubbles: true, cancelable: true});
+						}
+					}
+				},
+
+				function results(){
+					dom.byId("status").innerHTML = "Graphing results...";
+				}
+			]);
+
+			doh.run();
+		});
+		</script>
+	</head>
+	<body>
+		<h1>Dojo/on Performance Test</h1>
+
+		<!-- Display progress messages so test doesn't seem hung -->
+		<h2 id="status"></h2>
+
+		<!-- Test results are displayed here -->
+		<div id="perfTestsBody"></div>
+
+		<div id="emit">
+			<div>
+				<form id="emitinner">
+					<button id="emitbutton">hi</button>
+				</form>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojo/tests/on/connectKey.html b/dojo/tests/on/connectKey.html
new file mode 100644
index 0000000..beaf8d4
--- /dev/null
+++ b/dojo/tests/on/connectKey.html
@@ -0,0 +1,33 @@
+<html>
+<head>
+	<title>dojo/on keypress/keydown test</title>
+	<script src="../../dojo.js"></script>
+	<script>
+		require(["dojo/dom", "dojo/on", "dojo/domReady!"],
+				function(dom, on){
+					on(dom.byId("textbox"), "keypress, keydown, compositionend", function(evt){
+						console.log(evt.type +
+								("keyCode" in evt ? " keyCode = " + evt.keyCode : "") +
+								("charCode" in evt ? " charCode = " + evt.charCode : "")
+						);
+
+						// stop Ctrl-W from closing the browser window, etc.
+						evt.preventDefault();
+						evt.stopPropagation();
+					});
+				});
+	</script>
+</head>
+<body>
+<h1>dojo/on keypress/keydown test</h1>
+
+<p>
+	Test how browsers fire keydown and keypress events
+</p>
+
+<p>
+	Type into <input>, and watch console for log messages.
+</p>
+<input id="textbox">
+</body>
+</html>
\ No newline at end of file
diff --git a/dojo/tests/on/on.js b/dojo/tests/on/on.js
new file mode 100644
index 0000000..6452fc7
--- /dev/null
+++ b/dojo/tests/on/on.js
@@ -0,0 +1,289 @@
+define([
+	"doh",
+	"dojo/_base/declare",  "dojo/Evented", "dojo/has", "dojo/on", "dojo/query", "dojo/topic"
+], function(doh, declare, Evented, has, on, query, topic){
+
+	doh.register("tests.on", [
+		function object(t){
+			var order = [];
+			var obj = new Evented();
+			obj.oncustom = function(event){
+				order.push(event.a);
+				return event.a+1;
+			};
+			var signal = on.pausable(obj, "custom", function(event){
+				order.push(0);
+				return event.a+1;
+			});
+			obj.oncustom({a:0});
+			var signal2 = on(obj, "custom, foo", function(event){
+				order.push(event.a);
+			});
+			on.emit(obj, "custom", {
+				a: 3
+			});
+			signal.pause();
+			var signal3 = on(obj, "custom", function(a){
+				order.push(3);
+			}, true);
+			on.emit(obj, "custom", {
+				a: 3
+			});
+			signal2.remove();
+			signal.resume();
+			on.emit(obj, "custom", {
+				a: 6
+			});
+			signal3.remove();
+			var signal4 = on(obj, "foo, custom", function(a){
+				order.push(4);
+			}, true);
+			signal.remove();
+			on.emit(obj, "custom", {
+				a: 7
+			});
+			t.is(order, [0,0,3,0,3,3,3,3,6,0,3,7,4]);
+		},
+		function once(t){
+			var order = [];
+			var obj = new Evented();
+			obj.on("custom", function(event){
+				order.push(event.a);
+			});
+			var signal = on.once(obj, "custom", function(event){
+				order.push(1);
+			});
+			obj.emit("custom",{a:0});
+			obj.oncustom({a:2}); // should call original method, but not listener
+			t.is(order, [0,1,2]);
+		},
+		function dom(t){
+			var div = document.body.appendChild(document.createElement("div"));
+			var span = div.appendChild(document.createElement("span"));
+			var order = [];
+			var signal = on(div,"custom", function(event){
+				order.push(event.a);
+				event.addedProp += "ue";
+			});
+			on(span,"custom", function(event){
+				event.addedProp = "val";
+			});
+			on.emit(div, "custom", {
+				target: div,
+				currentTarget:div,
+				relatedTarget: div,
+				a: 0
+			});
+			on.emit(div, "otherevent", {
+				a: 0
+			});
+			t.is(on.emit(span, "custom", {
+				a: 1,
+				bubbles: true,
+				cancelable: true
+			}).addedProp, "value");
+			t.t(on.emit(span, "custom", {
+				a: 1,
+				bubbles: false,
+				cancelable: true
+			}));
+			var signal2 = on.pausable(div,"custom", function(event){
+				order.push(event.a + 1);
+				event.preventDefault();
+			});
+			t.f(on.emit(span, "custom", {
+				a: 2,
+				bubbles: true,
+				cancelable: true
+			}));
+			signal2.pause();
+			t.is(on.emit(span, "custom", {
+				a: 4,
+				bubbles: true,
+				cancelable: true
+			}).type, "custom");
+			signal2.resume();
+			signal.remove();
+			t.f(on.emit(span, "custom", {
+				a: 4,
+				bubbles: true,
+				cancelable: true
+			}));
+			on(span, "custom", function(event){
+				order.push(6);
+				event.stopPropagation();
+			});
+			t.t(on.emit(span, "custom", {
+				a: 1,
+				bubbles: true,
+				cancelable: true
+			}));
+
+			// make sure we are propagating natively created events too, and that defaultPrevented works
+			var button = span.appendChild(document.createElement("button")),
+				defaultPrevented = false,
+				signal2Fired = false;
+			signal = on(span, "click", function(event){
+				event.preventDefault();
+			});
+			signal2 = on(div, "click", function(event){
+				order.push(7);
+				signal2Fired = true;
+				defaultPrevented = event.defaultPrevented;
+			});
+			button.click();
+			t.t(signal2Fired, "bubbled click event on div");
+			t.t(defaultPrevented, "defaultPrevented for click event");
+			signal.remove();
+			signal2.remove();
+
+			// make sure that evt.defaultPrevented gets set for synthetic events too
+			signal = on(span, "click", function(event){
+				event.preventDefault();
+			});
+			signal2 = on(div, "click", function(event){
+				signal2Fired = true;
+				defaultPrevented = event.defaultPrevented;
+			});
+			signal2Fired = false;
+			on.emit(button, "click", {bubbles: true, cancelable: true});
+			t.t(signal2Fired, "bubbled synthetic event on div");
+			t.t(defaultPrevented, "defaultPrevented set for synthetic event on div");
+			signal.remove();
+			signal2.remove();
+
+			// test out event delegation
+			if(query){
+				// if dojo.query is loaded, test event delegation
+				on(div, "button:click", function(){
+					order.push(8);
+				});
+				on(document, "button:click", function(){
+				}); // just make sure this doesn't throw an error
+			}else{//just pass then
+				order.push(8);
+			}
+			// test out event delegation using a custom selector
+			on(div, on.selector(function(node){
+				return node.tagName == "BUTTON";
+			}, "click"), function(){
+				order.push(9);
+			});
+			button.click();
+			t.is(order, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
+			on(span, "propertychange", function(){}); // make sure it doesn't throw an error
+		},
+		/*
+		 This only works if the test page has the focus, so you can enable if you want to test focus functionality and allow the test page to have focus
+ 		function focus(t){
+			var div = document.body.appendChild(document.createElement("div"));
+			var input = div.appendChild(document.createElement("input"));
+			var order = [];
+			var signal = on(div,"input:focusin", function(event){
+				order.push('in');
+			});
+			var signal = on(div,"input:focusout", function(event){
+				order.push('out');
+			});
+			var otherInput = document.body.appendChild(document.createElement("input"));
+			input.focus();
+			otherInput.focus();
+			d = new doh.Deferred();
+			setTimeout(function(){
+				t.is(['in', 'out'], order);
+				d.callback(true);
+			}, 1);
+			return d;
+		},*/
+		function extensionEvent(t){
+			var div = document.body.appendChild(document.createElement("div"));
+			var span = div.appendChild(document.createElement("span"));
+			span.setAttribute("foo", 2);
+			var order = [];
+			var customEvent = function(target, listener){
+				return on(target, "custom", listener);
+			};
+			on(div, customEvent, function(event){
+				order.push(event.a);
+			});
+			on(div, on.selector("span", customEvent), function(event){
+				order.push(+this.getAttribute("foo"));
+			});
+			on.emit(div, "custom", {
+				a: 0
+			});
+			// should trigger selector
+			t.t(on.emit(span, "custom", {
+				a: 1,
+				bubbles: true,
+				cancelable: true
+			}));
+			// shouldn't trigger selector
+			t.t(on.emit(div, "custom", {
+				a: 3,
+				bubbles: true,
+				cancelable: true
+			}));
+			t.is(order, [0, 1, 2, 3]);
+		},
+		function testEvented(t){
+			var MyClass = declare([Evented],{
+
+			});
+			var order = [];
+			myObject = new MyClass;
+			myObject.on("custom", function(event){
+				order.push(event.a);
+			});
+			myObject.emit("custom", {a:0});
+			t.is(order, [0]);
+		},
+		function pubsub(t){
+			var fooCount = 0;
+			topic.subscribe("/test/foo", function(event, secondArg){
+				t.is("value", event.foo);
+				t.is("second", secondArg);
+				fooCount++;
+			});
+			topic.publish("/test/foo", {foo: "value"}, "second");
+			t.is(1, fooCount);
+		},
+		function touch(t){
+			console.log("has", has);
+			if(has("touch")){
+				var div = document.body.appendChild(document.createElement("div"));
+				on(div, "touchstart", function(event){
+					t.t("rotation" in event);
+					t.t("pageX" in event);
+				});
+				on.emit(div, "touchstart", {changedTouches: [{pageX:100}]});
+			}
+		},
+		function stopImmediatePropagation(t){
+			var button = document.body.appendChild(document.createElement("button"));
+			on(button, "click", function(event){
+				event.stopImmediatePropagation();
+			});
+			var afterStop = false;
+			on(button, "click", function(event){
+				afterStop = true;
+			});
+			button.click();
+			t.f(afterStop);
+		},
+		function eventAugmentation(t){
+			var div = document.body.appendChild(document.createElement("div"));
+			var button = div.appendChild(document.createElement("button"));
+			on(button, "click", function(event){
+				event.modified = true;
+				event.test = 3;
+			});
+			var testValue;
+			on(div, "click", function(event){
+				testValue = event.test;
+			});
+			button.click();
+			t.is(testValue, 3);
+		}
+	]);
+});
diff --git a/dojo/tests/parser.html b/dojo/tests/parser.html
deleted file mode 100644
index 9f24d76..0000000
--- a/dojo/tests/parser.html
+++ /dev/null
@@ -1,789 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<title>Parser Unit Test</title>
-		<style type="text/css">     
-			@import "../resources/dojo.css";
-		</style>
-		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug:true, async:true"></script>
-		<script type="text/javascript">
-		require(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/_base/html", "dojo/Stateful", "dojo/Evented",
-				"doh", "dojo/date/stamp", "dojo/aspect", "dojo/parser", "dojo/domReady!"],
-				function(dojo, dlang, darray, declare, dhtml, Stateful, Evented, doh, dstamp, aspect, parser){
-
-			var mixin = dojo.mixin,
-				extend = dojo.extend,
-				exists = dojo.exists;
-
-			declare("tests.parser.Widget", null, {
-				constructor: function(args, node){
-					this.params = args;
-				}
-			});
-
-			declare("tests.parser.Class1", null, {
-				constructor: function(args, node){
-					this.params = args;
-					mixin(this, args);
-				}, 
-				preambleTestProp: 1,
-				preamble: function(){
-					this.preambleTestProp++;
-				},
-				intProp: 1,
-				callCount: 0, // for connect testing
-				callInc: function(){ this.callCount++; },
-				callCount2: 0, // for assignment testing
-				strProp1: "original1",
-				strProp2: "original2",
-				arrProp: [],
-				arrProp2: ["foo"],
-				boolProp1: false,
-				boolProp2: true,
-				boolProp3: false,
-				boolProp4: true,
-				dateProp1: dstamp.fromISOString('2007-01-01'),
-				dateProp2: dstamp.fromISOString('2007-01-01'),
-				dateProp3: dstamp.fromISOString('2007-01-01'),
-				funcProp: function(){},
-				funcProp2: function(){},
-				funcProp3: function(){},
-				onclick: function(){ this.prototypeOnclick=true; }
-				// FIXME: have to test dates!!
-				// FIXME: need to test the args property!!
-			});
-
-			declare("tests.parser.Class2", null, {
-				constructor: function(){
-					this.fromMarkup = false;
-				}, 
-				fromMarkup: false,
-				markupFactory: function(args, node, classCtor){
-					var i = new tests.parser.Class2();
-					i.fromMarkup = true;
-					return i;
-				}
-			});
-
-			declare("tests.parser.Class3", tests.parser.Class2, {
-				fromMarkup: false,
-				markupFactory: function(args, node, classCtor){
-					var i = new classCtor();
-					i.classCtor = classCtor;
-					i.params = args;
-					return i;
-				}
-			});
-
-			declare("tests.parser.InputClass", null, {
-				constructor: function(args, node){
-					this.params = args;
-					mixin(this, args);
-				},
-
-				// these attributes are special in HTML, they don't have a value specified
-				disabled: false,
-				readonly: false,
-				checked: false,
-
-				// other attributes native to HTML
-				value: "",
-				title: "default title",
-				tabIndex: "0",		// special because mixed case
-
-				// custom widget attributes that don't match a native HTML attributes
-				custom1: 123,
-				custom2: 456
-			});
-
-			// Test that dir, lang, etc. attributes can be inherited from ancestor node
-			declare("tests.parser.BidiClass", tests.parser.Widget, {
-				constructor: function(args, node){ mixin(this, args); },
-				dir: "",
-				lang: "",
-				textdir: "",
-				name: ""
-			});
-
-			// For testing that parser recurses correctly, except when the prototype has a
-			// stopParser flag
-			declare("tests.parser.NormalContainer", null, {
-				constructor: function(args, node){ mixin(this, args); }
-			});
-			declare("tests.parser.ShieldedContainer", null, {
-				constructor: function(args, node){ mixin(this, args); },
-
-				// flag to tell parser not to instantiate nodes inside of me
-				stopParser: true
-			});
-
-			declare("tests.parser.HTML5Props", null, {
-				constructor: function(args, node){ mixin(this, args); },
-				simple:false, 
-				a:2, 
-				b:null, c:null, d: null, e:null, f:null,
-				afn: function(){
-					return this.a * 2;
-				}
-			});
-
-			// not on .prototype:
-			tests.parser.HTML5Props._aDefaultObj = {
-				a:1, b:2, simple:true
-			};
-
-			declare("tests.parser.HTML5withMethod", null, {
-				constructor: function(args, node){ mixin(this, args); },
-				baseValue: 10,
-				someMethod: function(a, b){
-					return this.baseValue; 
-				},
-				diffMethod: function(a){
-					this._ran = true;
-				}
-			});
-			
-			declare("tests.parser.StatefulClass", [Evented, Stateful], {
-				strProp1: "",
-				objProp1: {},
-				boolProp1: false,
-				prototypeOnclick: false,
-				onclick: function() {this.prototypeOnclick=true;}
-			});
-
-			deepTestProp = {
-				blah: {
-					thinger: 1
-				}
-			};
-
-			tests.parser.FormClass = declare(tests.parser.Widget, {
-				encType: ""
-			});
-
-			dojo.ready(function(){
-				doh.register("basic tests", [
-					function parse(){
-						// Running the parser here so that failures appear in test log
-							parser.parse(dhtml.byId("main"));
-					},
-
-						function testDataDojoId(t){
-						t.t(typeof obj == "object");
-					},
-						function testJsId(t){
-							t.t(typeof obj3 == "object");
-						},
-					// Attribute parsing tests
-					function testStrProp(t){
-						// normal string parameter
-						t.t(dlang.isString(obj.strProp1));
-						t.is("text", obj.strProp1);
-
-						// make sure that you override a string value like "foo" to a blank value
-						t.t(dlang.isString(obj.strProp2));
-						t.is("", obj.strProp2);
-					},
-					function testIntProp(t){
-						t.is("number", (typeof obj.intProp));
-						t.is(5, obj.intProp);
-					},
-					function testArrProp(t){
-						t.is(3, obj.arrProp.length);
-						t.is(3, obj.arrProp[1].length);
-						t.is(["foo", "bar", "baz"], obj.arrProp);
-
-						// make sure empty arrays are possible
-						t.is([], obj.arrProp2);
-					},
-					function testBoolProp(t){
-						// make sure that both true and false get read correctly,
-						// and that unspecified attributes' values don't change
-
-						// boolProp1 specified at true
-						t.is("boolean", (typeof obj.boolProp1));
-						t.t(obj.boolProp1);
-
-						// boolProp2 specified as false
-						t.is("boolean", (typeof obj.boolProp2));
-						t.f(obj.boolProp2);
-
-						// boolProp3 not specified (prototype says false)
-						t.is("boolean", (typeof obj.boolProp3));
-						t.f(obj.boolProp3);
-
-						// boolProp4 not specified (prototype says true)
-						t.is("boolean", (typeof obj.boolProp4));
-						t.t(obj.boolProp4);
-					},
-					function testDateProp(t){
-						// dateProp1 specified as 2006-1-1
-						t.is("2006-01-01", dstamp.toISOString(obj.dateProp1, {selector: 'date'}));
-
-						// dateProp2="", should map to NaN (a blank value on DateTextBox)
-						t.t(isNaN(obj.dateProp2));
-
-						// dateProp3="now", should map to current date
-						t.is(dstamp.toISOString(new Date(), {selector: 'date'}),
-							dstamp.toISOString(obj.dateProp3, {selector: 'date'}));
-					},
-					function testUnwantedParams(t){
-						// Make sure that parser doesn't pass any unwanted parameters to
-						// widget constructor, especially "toString" or "constructor".
-						// Make exception for dir/lang which parser gleans from document itself.
-						for(var param in obj.params){
-							doh.t(darray.indexOf(
-								["strProp1", "strProp2",
-								"intProp",
-								"arrProp", "arrProp2",
-								"boolProp1", "boolProp2",
-								"dateProp1", "dateProp2", "dateProp3",
-								"funcProp2", "funcProp3",
-								"preamble",
-									"callInc1", "callInc2", "dir", "lang", "textDir"],
-								param) >= 0, param);
-						}
-					},
-					function testDisabledFlag(t){
-							t.is("boolean", typeof disabledObj.disabled, "typeof disabled");
-							t.t(disabledObj.disabled, "disabled");
-							t.f(disabledObj.checked, "checked");
-					},
-					function testCheckedFlag(t){
-							t.is("boolean", typeof checkedObj.checked, "typeof checked");
-							t.f(checkedObj.disabled, "disabled");
-							t.t(checkedObj.checked, "checked");
-					},
-					function testFunctionProp(t){
-						// make sure that unspecified functions (even with common names)
-						// don't get overridden (bug #3074)
-						obj.onclick();
-						t.t(obj.prototypeOnclick);
-
-						// funcProp2="foo"
-						obj.funcProp2();
-						t.t(obj.fooCalled);
-
-						// funcProp3="this.func3Called=true;"
-						obj.funcProp3();
-						t.t(obj.func3Called);
-					},
-
-					// test script tags inside innerHTML of source node
-					"t.is(4, obj.preambleTestProp);",
-					"t.is(deepTestProp, obj.deepProp);",
-					function testConnect(t){
-						obj.callInc();
-						t.is(2, obj.callCount);
-					},
-					function testFunctionAssignment(t){
-						obj.callInc2();
-						t.is(1, obj.callCount2);
-					},
-					function testSubNodeParse(t){
-						t.f(exists("obj2"));
-						var toParse = dhtml.byId("toParse");
-						toParse.setAttribute("dojoType", toParse.getAttribute("type"));
-						parser.parse(toParse.parentNode);
-						t.t(exists("obj2"));
-						t.is("tests.parser.Class1", obj2.declaredClass);
-					},
-					function testMarkupFactory(t){
-						t.t(exists("obj3"));
-						t.t(obj3.fromMarkup);
-					},
-					function testMarkupFactoryClass(t){
-						t.t(exists("obj4"));
-						t.is(obj4.classCtor, tests.parser.Class3);
-						t.t(obj4 instanceof tests.parser.Class3);
-						t.t(obj4 instanceof tests.parser.Class2);
-					},
-					function testnostart(t){
-
-						var started = false;
-						declare("SampleThinger", null, {
-							startup: function(){
-								started = true;
-							}
-						});
-
-						dhtml.create("div", { dojoType:"SampleThinger" }, "parsertest");
-						parser.parse("parsertest", { noStart:true });
-
-						t.f(started);
-
-						dhtml.empty("parsertest");
-
-						started = false;
-
-						dhtml.create("div", { dojoType:"SampleThinger" }, "parsertest");
-						parser.parse({ noStart:true, rootNode:"parsertest" });
-
-						t.f(started);
-					},
-
-					// test the various iterations of parser test
-					function rootTest(t){
-
-						var tmp = aspect.after(dojo, "query", function(sel, root){
-							t.is("parsertest2", root);
-						});
-
-						parser.parse("parsertest2");
-						parser.parse({ rootNode: "parsertest2" });
-						parser.parse("parsertest2", { noStart:true });
-
-						tmp.remove();
-					},
-
-					// Test that when BorderContainer etc. extends _Widget,
-					// parser is aware of the new parameters added (to _Widget
-					// and all of it's subclasses)
-					function cacheRefresh(t){
-						// Add new node to be parsed, referencing a widget that the parser has already
-						// dealt with (and thus cached)
-						var wrapper = dhtml.place("<div><div dojoType='tests.parser.Class3' newParam=12345>hi</div></div>", dhtml.body(), "last");
-
-						// Modify Class3's superclass widget to have new parameter (thus Class3 inherits it)
-						extend(tests.parser.Class2, {
-							newParam: 0
-						});
-
-						// Run the parser and see if it reads in newParam
-						var widgets = parser.parse({rootNode: wrapper});
-						doh.is(1, widgets.length, "parsed newly inserted parserTest widget");
-						doh.is(12345, widgets[0].params.newParam, "new parameter parsed");
-					},
-
-					// Test that parser recurses correctly, except when there's a stopParser flag not to
-					function recurse(){
-						doh.t(container1, "normal container created");
-						doh.t(container1.incr, "script tag works too");
-						doh.t(window.contained1, "child widget also created");
-						doh.t(window.contained2, "child widget 2 also created");
-
-						doh.t(container2, "shielded container created");
-						doh.t(container2.incr, "script tag works too");
-						doh.f(window.contained3, "child widget not created");
-						doh.f(window.contained4, "child widget 2 not created");
-					},
-
-					function simpleHTML5(){
-						doh.t(typeof html5simple == "object", "data-dojo-id export");
-						doh.t(typeof html5simple2 == "object", "data-dojo-id export");
-
-						doh.t(html5simple.simple, "default respecified in props=''");
-						doh.f(html5simple2.simple, "default overridden by props=''");
-
-						// test data-dojo-props="simple:false, a:1, b:'two', c:[1,2,3], d:function(){ return this; }, e:{ f:'g' }"
-						var it = html5simple2;
-						doh.is(1, it.a, "number in param");
-						doh.is("two", it.b, "string in param");
-						doh.t(dlang.isArray(it.c), "array in param");
-						doh.is(3, it.c.length, "array sanity");
-						doh.is("g", it.e.f, "nested object with string");
-
-						// test the function
-						doh.is(it, it.d(), "simple 'return this' function");
-
-					},
-
-					function html5inherited(){
-						doh.t(typeof html5simple3 == "object");
-						var val = html5simple3.afn();
-						doh.is(html5simple3.a * 2, val, "afn() overrides default but calls inherited")
-					},
-
-					function html5withMethod(){
-						// testing data-dojo-event and data-dojo-args support for dojo/method and dojo/connect
-						doh.t(typeof htmldojomethod == "object");
-						doh.t(htmldojomethod._methodRan, "plain dojo/method ran");
-
-						var x = htmldojomethod.someMethod(2, 2);
-						doh.is(14, x, "overridden dojo/method");
-
-						htmldojomethod.diffMethod(2);
-						doh.t(htmldojomethod._ran, "ensures original was called first");
-						doh.is(2, htmldojomethod._fromvalue, "ensures connected was executed in scope");
-					},
-					
-					function testOnWatch(){
-						// testing script-type dojo/watch and dojo/on
-						doh.t(typeof objOnWatch == "object");
-						objOnWatch.set("strProp1","newValue1");
-						doh.is("newValue1", objOnWatch.arrProp.newValue, "ensures watch executed");
-						
-						objOnWatch.onclick();
-						doh.t(objOnWatch.prototypeOnclick, "ensures original was called");
-						doh.t(objOnWatch.boolProp1, "ensure on executed in scope");
-					}
-				]);
-
-				doh.register("BIDI", [
-					// Test that dir=rtl or dir=ltr setting trickles down from root node
-					function dir(){
-						parser.parse("dirSection1");
-						parser.parse("dirSection2");
-						doh.is("rtl", setRtl.dir, "direct setting of dir=rtl works");
-						doh.is("rtl", inheritRtl.dir, "inherited rtl works");
-						doh.is("ltr", inheritLtr.dir, "inherited ltr works (closest ancestor wins)");
-						doh.is("rtl", inheritRtl2.dir, "inherited rtl works, from grandparent");
-						doh.is("ltr", setLtr.dir, "direct setting of dir=ltr overrides inherited RTL");
-					},
-					function lang(){
-						parser.parse("langSection");
-						doh.f(lang in noLang.params, "no lang");
-						doh.is("it_it", inheritedLang.lang, "inherited lang works");
-						doh.is("en_us", specifiedLang.lang,"direct setting of lang overrides inherited");
-					},
-					function textdir(){
-						parser.parse("textDirSection");
-						doh.f("textDir" in noTextdir.params, "no textdir");
-						doh.is("rtl", inheritedTextdir.textDir, "inherited textdir works");
-						doh.is("ltr", specifiedTextdir.textDir,"direct setting of textdir overrides inherited");
-					},
-					{
-						// Test that calling parser.parse(nodeX) will inherit dir/lang/etc. settings
-						// even from <html>
-						name: "inheritance from HTML",
-						setUp: function(){
-							dhtml.attr(dhtml.doc.documentElement, {dir: "rtl", lang: "ja-jp", "data-dojo-textdir": "auto"});
-							parser.parse("bidiInheritanceFromHtml");
-						},
-						runTest: function(){
-							doh.is("rtl", inheritedFromHtml.params.dir, "dir");
-							doh.is("ja-jp", inheritedFromHtml.params.lang, "lang");
-							doh.is("auto", inheritedFromHtml.params.textDir, "textDir");
-						},
-						tearDown: function(){
-							darray.forEach(["dir", "lang", "data-dojo-textdir"], function(attr){
-								dhtml.doc.documentElement.removeAttribute(attr);
-							});
-						}
-					}
-				]);
-
-				doh.register("IE attribute detection", [
-					function input1(){
-						var widgets = parser.instantiate([dhtml.byId("ieInput1")]);
-						var params = widgets[0].params;
-
-						doh.is("checkbox", params.type, "type");
-						doh.t(params.disabled, "disabled");
-						doh.t(params.checked, "checked");
-						doh.t(params.readonly, "readonly");
-						doh.is("bar", params.foo, "foo");
-						doh.is("zaz", params.bar, "bar");
-						doh.is("escaped\"dq", params.bob, "bob");
-						doh.is("escaped\'sq", params.frank, "frank");
-					},
-					function input2(){
-						var widgets = parser.instantiate([dhtml.byId("ieInput2")]);
-						var params = widgets[0].params;
-
-						doh.f("type" in params, "type");
-						doh.f("name" in params, "name");
-						doh.f("value" in params, "value");
-						doh.f("data-dojo-type" in params, "data-dojo-type");
-						doh.f("data-dojo-props" in params, "data-dojo-props");
-						doh.is("hi", params.foo, "foo");
-					},
-					function input3(){
-						var widgets = parser.instantiate([dhtml.byId("ieInput3")]);
-						var params = widgets[0].params;
-
-						doh.is("password", params.type, "type");
-						doh.is("test", params.name, "name");
-						doh.is("123", params.value, "value");
-						doh.is("myClass", params["class"], "class");
-						doh.is("display:block", params["style"].replace(/[ ;]/g, "").toLowerCase(), "style");
-						doh.is("3", params.tabIndex, "tabIndex");
-					},
-					function textarea(){
-						var widgets = parser.instantiate([dhtml.byId("ieTextarea")]);
-						var params = widgets[0].params;
-
-						doh.is("attrVal", params.value, "value");
-					},
-					function button1(){
-						var widgets = parser.instantiate([dhtml.byId("ieButton1")]);
-						var params = widgets[0].params;
-						doh.t(params.checked, "checked");
-						doh.is("button1val", params.value, "value");
-					},
-					function button2(){
-						var widgets = parser.instantiate([dhtml.byId("ieButton2")]);
-						var params = widgets[0].params;
-						doh.f("checked" in params, "checked");
-						doh.f("value" in params, "value");
-					},
-					function button3(){
-						var widgets = parser.instantiate([dhtml.byId("ieButton3")]);
-						var params = widgets[0].params;
-						doh.t(params.checked, "checked");
-					},
-					function button4(){
-						var widgets = parser.instantiate([dhtml.byId("ieButton4")]);
-						var params = widgets[0].params;
-						doh.f("checked" in params);
-					},
-					function form1(){
-						var widgets = parser.instantiate([dhtml.byId("ieForm1")]);
-						var params = widgets[0].params;
-
-						doh.is("foo", params.encType, "encType is specified");
-					},
-					function form2(){
-						var widgets = parser.instantiate([dhtml.byId("ieForm2")]);
-						var params = widgets[0].params;
-
-						doh.f("encType" in params, "encType not specified")
-					},
-					function li(){
-						var widgets = parser.instantiate([dhtml.byId("li")]);
-						var params = widgets[0].params;
-						doh.is("home", params.value);
-
-					}
-				]);
-
-				doh.register("mixed attribute specification", function mixed(){
-					parser.parse(dhtml.byId("mixedContainer"));
-					doh.is("object", typeof mixedObj, "widget created");
-					doh.is("mixedValue", mixedObj.value, "native attribute");
-					doh.is(999, mixedObj.custom1, "data-dojo-props attribute");
-					doh.is("custom title", mixedObj.title, "data-dojo-props overrides native");
-				});
-
-				doh.register("functions", function onclick(){
-					// Create objects referenced from markup inside of "functions" div
-					declare("tests.parser.Button", null, {
-						onClick: function(){
-							console.log("prototype click");
-						},
-						constructor: function(args, node){
-							mixin(this, args);
-							this.domNode = node;
-							aspect.after(this.domNode, "onclick", dlang.hitch(this, "onClick"));
-						}
-					});
-					buttonClicked = function(){
-						console.log("markup click");
-					};	// markup says onClick="buttonClicked"
-
-					// Parse markup inside "functions" div
-					parser.parse("functions");
-
-					// Should have created an instance called "button" where button.onClick == buttonClicked
-					doh.is("object", typeof button, "widget created");
-					doh.is("function", typeof button.onClick, "created as function");
-					doh.t(buttonClicked == button.onClick, "points to specified function");
-				});
-				doh.run();
-			})
-		});
-		</script>
-	</head>
-	<body>
-		<h1>Parser Unit Test</h1>
-
-		<div id=main>
-			<script>
-				function foo(){ this.fooCalled=true; }
-			</script>
-			<div dojoType="tests.parser.Class1" data-dojo-id="obj"
-				strProp1="text" strProp2=""
-				intProp="5"
-				arrProp="foo, bar, baz"
-				arrProp2=""
-				boolProp1="true" boolProp2="false"
-				dateProp1="2006-01-01" dateProp2="" dateProp3="now"
-				funcProp2="foo" funcProp3="this.func3Called=true;"
-			>
-				<script type="dojo/method" event="preamble">
-					this.preambleTestProp = 3;
-				</script>
-				<script type="dojo/method">
-					// this should be run immediately
-					this.deepProp = deepTestProp;
-				</script>
-				<script type="dojo/connect" event="callInc">
-					this.callCount++;
-				</script>
-				<script type="dojo/method" event="callInc2">
-					this.callCount2++;
-				</script>
-			</div>
-			<div>
-				<div type="tests.parser.Class1" jsId="obj2" id="toParse">
-				</div>
-			</div>
-			<div dojoType="tests.parser.Class2" jsId="obj3">
-			</div>
-			<div dojoType="tests.parser.Class3" jsId="obj4">
-			</div>
-			<input dojoType="tests.parser.InputClass" jsId="checkedObj" checked type="checkbox">
-			<button dojoType="tests.parser.InputClass" jsId="disabledObj" disabled>hi</button>
-
-			<div id="parsertest"></div>
-			<div id="parsertest2"></div>
-
-			<!-- section for testing parser recursion -->
-			<div>
-				<div dojoType="tests.parser.NormalContainer" jsId="container1">
-					<!-- this script tag should get passed as param to NormalContainer constructor -->
-					<script type="dojo/method" event="incr" args="x">
-						return x+1;
-					</script>
-
-					<!-- and these contained widgets should get instantiated -->
-					<div dojoType="tests.parser.Class1" jsId="contained1"></div>
-					<div>
-						<div dojoType="tests.parser.Class1" jsId="contained2"></div>
-					</div>
-				</div>
-			</div>
-
-			<div>
-				<div dojoType="tests.parser.ShieldedContainer" jsId="container2">
-					<!-- this script tag should get passed as param to NormalContainer constructor -->
-					<script type="dojo/method" event="incr" args="x">
-						return x+1;
-					</script>
-
-					<!-- but these contained widgets should *not* get instantiated -->
-					<div dojoType="tests.parser.Class1" jsId="contained3"></div>
-					<div>
-						<div dojoType="tests.parser.Class1" jsId="contained4"></div>
-					</div>
-				</div>
-			</div>
-
-			<!-- tests for new data-dojo-type / data-dojo-props syntax -->
-			<div>
-				<div data-dojo-id="html5simple" data-dojo-type="tests.parser.HTML5Props" data-dojo-props="simple:true"></div>
-				<div data-dojo-id="html5simple2" data-dojo-type="tests.parser.HTML5Props"
-					data-dojo-props="simple:false, a:1, b:'two', c:[1,2,3], d:function(){ return this; }, e:{ f:'g' }"
-				></div>
-				<!-- note needing to use a named inherited lookup because we're just mixing in -->
-				<div data-dojo-id="html5simple3" data-dojo-type="tests.parser.HTML5Props"
-					data-dojo-props="afn: function(){ return this.inherited('afn', arguments); }"
-				></div>
-
-				<!-- not used for tests, but thinking out loud: what about a named-resource prop, via getObject -->
-				<div data-dojo-id="html5fromobjectns" data-dojo-type="tests.parser.HTML5Props"
-					data-dojo-obj="tests.parser.HTML5Props._aDefaultObj"
-				></div>
-				<div data-dojo-id="html5fromobjectns2" data-dojo-type="tests.parser.HTML5Props"
-					data-dojo-obj="tests.parser.HTML5Props._aDefaultObj" data-dojo-props="simple:false"
-				></div>
-
-			</div>
-
-			<div>
-				<div data-dojo-id="htmldojomethod" data-dojo-type="tests.parser.HTML5withMethod">
-					<p>Some random markup</p>
-					<script type="dojo/method" data-dojo-event="someMethod" data-dojo-args="a, b">
-						return this.baseValue + a + b;
-					</script>
-					<script type="dojo/connect" data-dojo-event="diffMethod" data-dojo-args="a">
-						console.log("diffMethod connect, this is ", this);
-						this._fromvalue = a;
-					</script>
-					<script type="dojo/method">
-						this._methodRan = true;
-					</script>
-				</div>
-			</div>
-			
-			<!-- section for testing dojo/on and dojo/watch scripts -->
-			<div>
-				<div data-dojo-id="objOnWatch" data-dojo-type="tests.parser.StatefulClass">
-					<script type="dojo/watch" data-dojo-prop="strProp1" data-dojo-args="prop,oldValue,newValue">
-						this.set("arrProp",{prop: prop, oldValue: oldValue, newValue: newValue});
-					</script>
-					<script type="dojo/on" data-dojo-event="click" data-dojo-args="e">
-						console.log("diffMethod on, this is ",this);
-						this.set("boolProp1",true);
-					</script>
-				</div>
-			</div>
-		</div> <!-- end of <div id=main> -->
-
-		<!-- section for testing that dir, lang attribute trickles down from ancestor -->
-		<div id="dirSection1">
-			<div dojoType="tests.parser.BidiClass" jsId="setRtl" dir="rtl" name="RTL setting"></div>
-			<div dojoType="tests.parser.BidiClass" jsId="noDir" name="dir not inherited or set"></div>
-		</div>
-		<div id="dirSection2" dir="rtl">
-			<div dojoType="tests.parser.BidiClass" jsId="inheritRtl" name="inherited RTL from parent"></div>
-			<div dir="ltr">
-				<div dojoType="tests.parser.BidiClass" jsId="inheritLtr" name="inherited LTR from parent"></div>
-			</div>
-			<div>
-				<div dojoType="tests.parser.BidiClass" jsId="inheritRtl2" name="inherited RTL from grandparent"></div>
-			</div>
-			<div dojoType="tests.parser.BidiClass" jsId="setLtr" dir="ltr" name="LTR setting overrides inherited RTL"></div>
-		</div>
-		<div id="langSection">
-			<div dojoType="tests.parser.BidiClass" jsId="noLang" name="shouldn't get lang"></div>
-			<div lang="it_it">
-				<div dojoType="tests.parser.BidiClass" jsId="inheritedLang" name="inherited lang from parent"></div>
-				<div dojoType="tests.parser.BidiClass" jsId="specifiedLang" lang="en_us" name="specified lang overrides parent"></div>
-			</div>
-		</div>
-		<div id="textDirSection">
-			<div dojoType="tests.parser.BidiClass" jsId="noTextdir" name="shouldn't get textdir"></div>
-			<div data-dojo-textdir="rtl">
-				<div dojoType="tests.parser.BidiClass" jsId="inheritedTextdir" name="inherited textdir from parent"></div>
-				<div dojoType="tests.parser.BidiClass" jsId="specifiedTextdir" data-dojo-textdir="ltr" name="specified textdir overrides parent"></div>
-			</div>
-		</div>
-		<div id="bidiInheritanceFromHtml">
-			<div dojoType="tests.parser.BidiClass" jsId="inheritedFromHtml" name="should get dir/lang/textDir from HTML tag"></div>
-		</div>
-
-		<!-- tests that we can parse parameters correctly on IE6/7, not getting tripped up by escaped quotes etc. -->
-		<div id=ie>
-			<input id="ieInput1" data-dojo-type="tests.parser.InputClass"
-					type=checkbox disabled foo = 'bar' readonly bar=zaz bob='escaped"dq' frank="escaped'sq" checked />
-			<input id="ieInput2" data-dojo-type="tests.parser.InputClass"
-					fakeout1="type=submit" fakeout2="name='test'" fakeout3="value='123'" data-dojo-props="foo: 'hi'"/>
-			<input id="ieInput3" data-dojo-type="tests.parser.InputClass"
-					type=password name="test" value="123" class="myClass" style="display:block" tabindex="3"/>
-			<textarea id="ieTextarea" data-dojo-type="tests.parser.InputClass" value="attrVal">contentVal</textarea>
-			<button id="ieButton1" data-dojo-type="tests.parser.InputClass" checked value="button1val">
-					checked ToggleButton as button
-			</button>
-			<button id="ieButton2" data-dojo-type="tests.parser.InputClass">
-					unchecked ToggleButton as button
-			</button>
-			<div id="ieButton3" data-dojo-type="tests.parser.InputClass" checked>
-					checked ToggleButton as div
-			</div>
-			<div id="ieButton4" data-dojo-type="tests.parser.InputClass">
-					unchecked ToggleButton as div
-			</div>
-			<form id="ieForm1" data-dojo-type="tests.parser.FormClass" encType="foo"></form>
-			<form id="ieForm2" data-dojo-type="tests.parser.FormClass"></form>
-			<ul dojoType="tests.parser.Widget" class="nav">
-				<li id="li" dojoType="tests.parser.Widget" value="home">Home</li>
-				<li dojoType="tests.parser.Widget" value="contact">Contact</li>
-				<li dojoType="tests.parser.Widget" value="group">Group</li>
-				<li dojoType="tests.parser.Widget" value="campaign">Campaign</li>
-			</ul>
-		</div>
-
-		<!-- tests for when parameters are specified both natively and in data-dojo-props. -->
-		<div id="mixedContainer">
-			<input data-dojo-type="tests.parser.InputClass" data-dojo-id="mixedObj"
-				  value="mixedValue" title="native title" data-dojo-props="custom1: 999, title: 'custom title'">
-		</div>
-
-		<!-- tests for function names native to HTML, specifically an issue on IE<8 -->
-		<div id="functions">
-			<button dojoType="tests.parser.Button" onClick="buttonClicked" jsId="button">Click me</button>
-		</div>
-
-	</body>
-</html>
diff --git a/dojo/tests/parser.js b/dojo/tests/parser.js
index 51bf615..302e32b 100644
--- a/dojo/tests/parser.js
+++ b/dojo/tests/parser.js
@@ -1,5 +1,9 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
-		doh.register("tests.parser", require.toUrl("./parser.html"), 30000);
+		doh.register("parser", require.toUrl("./parser/parser.html"), 30000);
+		doh.register("parseOnLoad-auto-require", require.toUrl("./parser/parseOnLoadAutoRequire.html"), 30000);
+		doh.register("parseOnLoad-declarative-require", require.toUrl("./parser/parseOnLoadDeclarativeRequire.html"), 30000);
+		doh.register("parser-args", require.toUrl("./parser/parser-args.html"), 30000);
+		doh.register("parser-async", require.toUrl("./parser/parserAsync.html"), 30000);
 	}
 });
diff --git a/dojo/tests/parser/bench.html b/dojo/tests/parser/bench.html
new file mode 100644
index 0000000..43833f6
--- /dev/null
+++ b/dojo/tests/parser/bench.html
@@ -0,0 +1,311 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>Parser scan() Performance Test</title>
+		<style type="text/css">     
+			@import "../../resources/dojo.css";
+		</style>
+		<script type="text/javascript" src="../../dojo.js" data-dojo-config="async:true"></script>
+		<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/dom",
+			"dojo/dom-construct",
+			"dojo/_base/lang",
+			"dojo/parser",
+			"dojo/query",
+			"doh",
+			"dojo/domReady!"
+		], function(declare, dom, domConstruct, lang, parser, query, doh){
+
+			declare("TabContainer", null, {
+				numberProp1: 1,
+				numberProp2: 2,
+				booleanProp1: false,
+				booleanProp2: true,
+				strProp1: "original1",
+				strProp2: "original2",
+				funcProp: function(){}
+			});
+			declare("ContentPane", null, {
+				stopParser: true,
+				numberProp1: 1,
+				numberProp2: 2,
+				booleanProp1: false,
+				booleanProp2: true,
+				strProp1: "original1",
+				strProp2: "original2",
+				funcProp: function(){}
+			});
+			declare("TextBox", null, {
+				numberProp1: 1,
+				numberProp2: 2,
+				booleanProp1: false,
+				booleanProp2: true,
+				strProp1: "original1",
+				strProp2: "original2",
+				funcProp: function(){}
+			});
+
+			function generateDom(/*String[]*/ nodes, /*Number*/ fan, /*DOMNode*/ parent){
+				// summary:
+				//		Generate large DOM tree based on nodes in nodes[] array, with fan nodes at each level
+				var markup = nodes.shift();
+				for(var i=0; i<fan; i++){
+					var child = domConstruct.place(markup, parent);
+					if(nodes.length){
+						generateDom([].concat(nodes), fan, child);	// concat() to clone array
+					}
+				}
+			}
+
+			doh.register("parser performance tests", [
+				// Test scan of DOM without any widgets
+				{
+					name: "scan() with no widgets",
+					testType: "perf",
+					trialIterations: 20,
+					setUp: function(){
+						dom.byId("status").innerHTML = "Running scan() with no widgets test...";
+						var rows = query("tr", "tbody");
+						for(var i=0; i<55; i++){
+							domConstruct.place(rows[i%2 + 1].cloneNode(true), "tbody");
+						}
+					},
+					tearDown: function(){
+						domConstruct.empty("scan");
+					},
+					runTest: function(){
+						parser._clearCache();
+						parser.parse("scan");
+					}
+				},
+
+				{
+					name: "scan() with lots of widgets",
+					testType: "perf",
+					trialIterations: 20,
+					setUp: function(){
+						dom.byId("status").innerHTML = "Running scan() with lots of widgets test...";
+						generateDom([
+							"<div data-dojo-type=TabContainer></div>",
+							"<div data-dojo-type=TabContainer></div>",
+							"<div></div>",
+							"<input data-dojo-type=TextBox strProp1=name/>"
+						], 4, "scan");
+					},
+					tearDown: function(){
+						domConstruct.empty("scan");
+					},
+					runTest: function(){
+						parser._clearCache();
+						parser.parse("scan");
+					}
+				},
+
+				{
+					name: "scan() with lots of widgets but _stopParser",
+					testType: "perf",
+					trialIterations: 20,
+					setUp: function(){
+						dom.byId("status").innerHTML = "Running scan() with lots of widgets and _stopParser test...";
+						generateDom([
+							"<div data-dojo-type=TabContainer></div>",
+							"<div data-dojo-type=ContentPane></div>",
+							"<div></div>",
+							"<input data-dojo-type=TextBox strProp1=name/>"
+						], 4, "scan");
+					},
+					tearDown: function(){
+						domConstruct.empty("scan");
+					},
+					runTest: function(){
+						parser._clearCache();
+						parser.parse("scan");
+					}
+				},
+
+				{
+					name: "instantiate()",
+					testType: "perf",
+					trialIterations: 20,
+					setUp: function(){
+						dom.byId("status").innerHTML = "Running instantiate() test...";
+						nodes = [];
+						for(var i=0; i<100; i++){
+							nodes.push(domConstruct.place("<input data-dojo-type=TextBox numberProp1=1 numberProp2=2 stringProp1=hi booleanProp1=true funcProp='console.log(12345);'/>", "instantiate"));
+						}
+					},
+					tearDown: function(){
+						domConstruct.empty("instantiate");
+					},
+					runTest: function(){
+						parser._clearCache();
+						parser.instantiate(nodes);
+					}
+				},
+
+				function results(){
+					dom.byId("status").innerHTML = "Graphing results...";
+				}
+			]);
+
+			doh.run();
+		});
+		</script>
+	</head>
+	<body>
+		<h1>Parser Performance Test</h1>
+
+		<!-- Display progress messages so test doesn't seem hung -->
+		<h2 id="status"></h2>
+
+		<!-- Test results are displayed here -->
+		<div id="perfTestsBody"></div>
+
+		<!-- for generating markup to scan (no widgets, just nodes) -->
+		<div id="scan" style="display: none">
+ 		<table width="100%" cellspacing="0" cellpadding="0" border="0" class="datatable" id="reportTable">
+	 	<tbody id="tbody">
+			<tr class="hr">
+				<td width="1px" style="display: none;">
+					<input type="checkbox" onclick="" name="cbSelectItem" ignore="true">
+				</td>
+				<td class="left">
+				    <span id="_0">
+						Name
+					</span>
+				</td>
+
+				<td class="left">
+				    <span id="_1">
+                        RIC
+                     </span>
+                </td>
+
+				<td class="right">
+    				<span id="_2">
+                        PE
+                     </span>
+				</td>
+
+				<td class="right">
+					Est. PE
+                </td>
+
+                <td class="right">
+    				<span id="_4">
+                        EPS
+                     </span>
+				</td>
+
+				<td class="normaltext left">
+				    Ccy
+				</td>
+
+				<td class="right">
+    				<span id="_6">
+                        DPS
+                     </span>
+				</td>
+
+				<td class="normaltext left">
+				    Ccy
+				</td>
+
+				<td class="right">
+    				<span id="_8">
+                        Div. Yld (%)
+                     </span>
+				</td>
+
+				<td class="right">
+    				<span id="_9">
+                        ROE (%)
+                     </span>
+				</td>
+
+				<td class="right">
+    				<span id="_10">
+                        P/Book
+                     </span>
+				</td>
+
+				<td class="right">
+    				<span id="_11">
+                        P/Sales
+                     </span>
+				</td>
+
+				<td class="normaltext right">
+					Weight %
+				</td>
+
+				<td class="right">
+    				<span id="_12">
+                        Market Cap (USD)
+                     </span>
+				</td>
+
+			</tr>
+
+
+			<tr headrow="true" class="dr  row-o">
+				<td width="1px" style="display: none;">
+					<input type="checkbox" value="IBM.N" name="cbSelectItem" ignore="">
+				</td>
+    			<td class="normaltext left">
+					    International Business Machines Corp
+				    </td>
+    			<td class="normaltext left"><span style="">
+					<a href="#" class="CCFDATA CCF.Entity[COMP]:RIC=RIC">
+					RIC
+					</a>
+					</span><span style="visibility: hidden; display: none;">-</span></td>
+    			<td class="normaltext right">xx,xx</td>
+    			<td class="normaltext right">xx,xx</td>
+    			<td class="normaltext right">x,xx</td>
+    			<td class="normaltext left nowrap">XXX</td>
+    			<td class="normaltext right">xx.xx,xx</td>
+    			<td class="normaltext left nowrap">XXX</td>
+    			<td class="normaltext right">x,xx</td>
+    			<td class="normaltext right">xx,xx</td>
+    			<td class="normaltext right">x,xx</td>
+    			<td class="normaltext right">x,xx</td>
+    			<td class="normaltext right">-</td>
+    			<td class="normaltext right">xxx,xxx</td>
+			</tr>
+
+
+			<tr headrow="true" class="dr  row-e">
+				<td width="1px" style="display: none;">
+					<input type="checkbox" value=" " name="cbSelectItem" ignore="true">
+				</td>
+    			<td class="normaltext left">
+				    Index average (Mean)</td>
+    			<td class="normaltext left"><span style="visibility: hidden; display: none;">
+					<a href="/Explorer/Default.aspx?s=%26nbsp&amp;st=RIC" class="CCFDATA CCF.Entity[COMP]:RIC=&nbsp">
+					 
+					</a>
+					</span><span style="">-</span></td>
+    			<td class="normaltext right">xx,xx</td>
+    			<td class="normaltext right">xx,xx</td>
+    			<td class="normaltext right">n/a</td>
+    			<td class="normaltext left nowrap">n/a</td>
+    			<td class="normaltext right">n/a</td>
+    			<td class="normaltext left nowrap">n/a</td>
+    			<td class="normaltext right">xx,xx</td>
+    			<td class="normaltext right">xx,xx</td>
+    			<td class="normaltext right">x,xx</td>
+    			<td class="normaltext right">x,xx</td>
+    			<td class="normaltext right">-</td>
+    			<td class="normaltext right">xx,xxx</td>
+			</tr>
+		</tbody>
+		</table>
+		</div>
+
+		<!-- for testing widget instantiation speed -->
+		<div id="instantiate" style="display: none"></div>
+	</body>
+</html>
diff --git a/dojo/tests/parser/parseOnLoadAutoRequire.html b/dojo/tests/parser/parseOnLoadAutoRequire.html
new file mode 100644
index 0000000..5d5643d
--- /dev/null
+++ b/dojo/tests/parser/parseOnLoadAutoRequire.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>parser auto-require unit test</title>
+		<style type="text/css">
+			@import "../../resources/dojo.css";
+		</style>
+		<script type="text/javascript" src="../../dojo.js"
+				data-dojo-config="isDebug:true, async:true"></script>
+		<script type="text/javascript">
+			require(["doh", "dojo/parser", "dojo/domReady!"], function(doh, parser){
+				parser.parse().then(function(){
+					doh.register("parseOnLoad auto-require", function parseOnLoad(){
+						doh.is(typeof dr1, "object", "object using MID mapped to return var");
+						doh.is(dr1.params.foo, "bar", "parameters set on instantiation");
+						doh.is(typeof dr2, "object", "object using MID mapped to return var");
+						doh.is(dr2.params.foo, "bar", "parameters set on instantiation");
+						doh.is(typeof dr3, "object", "object using fully required");
+						doh.is(dr3.params.foo, "bar", "parameters set on instantiation");
+					});
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body>
+		<h1>parseOnLoad:true, async: true, auto-require unit test</h1>
+
+		<p>This page tests that:</p>
+		<ol>
+			<li>parseOnLoad: true parses the page on load</li>
+			<li>auto-require of modules</li>
+			<li>the parse happens before the ready() callback happens, including loading of auto-required modules</li>
+		</ol>
+		<p>See console for test results.</p>
+
+		<div data-dojo-id="dr1" data-dojo-type="dojo/tests/resources/AMDWidget" data-dojo-props="foo: 'bar'"></div>
+		<div data-dojo-id="dr2" data-dojo-type="dojo/tests/resources/AMDWidget2" data-dojo-props="foo: 'bar'"></div>
+		<div data-dojo-id="dr3" data-dojo-type="dojo/tests/resources/AMDWidget3" data-dojo-props="foo: 'bar'"></div>
+
+	</body>
+</html>
diff --git a/dojo/tests/parser/parseOnLoadDeclarativeRequire.html b/dojo/tests/parser/parseOnLoadDeclarativeRequire.html
new file mode 100644
index 0000000..8bf4595
--- /dev/null
+++ b/dojo/tests/parser/parseOnLoadDeclarativeRequire.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>parseOnLoad:true, async:false unit test</title>
+		<style type="text/css">
+			@import "../../resources/dojo.css";
+		</style>
+		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
+		<script type="text/javascript">
+			require(["doh", "dojo/ready"], function(doh, ready){
+				ready(function(){
+					doh.register("parseOnLoad declarative-require", function parseOnLoad(){
+						doh.is("object", typeof dr1, "dr1 created");
+						doh.is("bar", dr1.params.foo, "dr1 parameters set on instantiation");
+						doh.is("object", typeof dr2, "dr2 created");
+						doh.is("bar", dr2.params.foo, "dr2 parameters set on instantiation");
+						doh.is("object", typeof dr3, "dr3 created");
+						doh.is("bar", dr3.params.foo, "dr3 parameters set on instantiation");
+						doh.is(2, dr4.params.foo, "module loaded and executed");
+						doh.is(3, dr5.method1(1), "declarative script has access to parser scope");
+					});
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body>
+		<h1>parseOnLoad:true, async:false unit test</h1>
+
+		<p>This page tests that:</p>
+		<ol>
+			<li>parseOnLoad: true parses the page on load</li>
+			<li>since async:true is NOT set, parseOnLoad:true works (with deprecation message)
+				even if there's no explicit require() of dojo/parser</li>
+			<li>the parse happens before the ready() callback happens, including processing of declarative requires</li>
+		</ol>
+		<p>See console for test results.</p>
+
+		<script type="dojo/require">
+			AMDWidget: "dojo/tests/resources/AMDWidget",
+			AMDWidget2: "dojo/tests/resources/AMDWidget2"
+		</script>
+		<div data-dojo-id="dr1" data-dojo-type="AMDWidget" data-dojo-props="foo: 'bar'"></div>
+		<div data-dojo-id="dr2" data-dojo-type="AMDWidget2" data-dojo-props="foo: 'bar'"></div>
+		<script type="dojo/require">
+			"acme.AMDWidget3": "dojo/tests/resources/AMDWidget3"
+		</script>
+		<div data-dojo-id="dr3" data-dojo-type="acme.AMDWidget3" data-dojo-props="foo: 'bar'"></div>
+		<script type="dojo/require">
+			amdmodule: "dojo/tests/resources/amdmodule"
+		</script>
+		<div data-dojo-id="dr4" data-dojo-type="AMDWidget" data-dojo-props="foo: amdmodule(1)"></div>
+		<div data-dojo-id="dr5" data-dojo-type="AMDWidget2">
+			<script type="dojo/aspect" data-dojo-advice="before" data-dojo-method="method1" data-dojo-args="value">
+				return [amdmodule(value)];
+			</script>
+		</div>
+
+
+	</body>
+</html>
diff --git a/dojo/tests/parser/parser-args.html b/dojo/tests/parser/parser-args.html
new file mode 100644
index 0000000..e812727
--- /dev/null
+++ b/dojo/tests/parser/parser-args.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>Parser args Unit Test</title>
+		<style type="text/css">     
+			@import "../../resources/dojo.css";
+		</style>
+		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true, async:true"></script>
+		<script type="text/javascript">
+		require(["dojo/_base/lang", "dojo/_base/declare", "doh", "dojo/parser", "dojo/domReady!"],
+				function(dlang, declare, doh, parser){
+
+			var mixin = dlang.mixin,
+				extend = dlang.extend,
+				exists = dlang.exists;
+
+			declare("tests.parser.Class1", null, {
+				constructor: function(args, node){
+					this.params = args;
+					mixin(this, args);
+				}, 
+				strProp1: "original1",
+				strProp2: "original2"
+			});
+
+			doh.register("args scope test", [
+				function noArgs(){
+					// Test calling parse() with no arguments.
+					var widgets = parser.parse();
+					doh.is(1, widgets.length, "found 1 widget");
+					doh.is("text", widgets[0].strProp1);
+				},
+				function optionsOnly(){
+					// Test when only the options argument is passed, and it does not contain a rootNode.
+					// For 2.0, if we drop scope parameter, change this test.
+					var widgets = parser.parse({
+						scope: "myscope"
+					});
+					doh.is(1, widgets.length, "found 1 widget");
+					doh.is("text", scopeObj.strProp1);
+				}
+			]);
+
+			doh.run();
+		});
+		</script>
+	</head>
+	<body>
+		<h1>Parser args Unit Test</h1>
+
+		<div data-myscope-type="tests.parser.Class1" data-myscope-id="scopeObj"
+			 data-myscope-props="strProp1:'text'">
+		</div>
+		<div data-dojo-type="tests.parser.Class1" data-dojo-id="normalObj"
+			 data-dojo-props="strProp1:'text'">
+		</div>
+	</body>
+</html>
diff --git a/dojo/tests/parser/parser.html b/dojo/tests/parser/parser.html
new file mode 100644
index 0000000..4e72236
--- /dev/null
+++ b/dojo/tests/parser/parser.html
@@ -0,0 +1,1164 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>Parser Unit Test</title>
+		<style type="text/css">
+			@import "../../resources/dojo.css";
+		</style>
+		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true, async:true"></script>
+		<script type="text/javascript">
+		var MyNonDojoClass = function() {};
+		MyNonDojoClass.extend = function(){
+			var args = arguments;
+			return function() {
+				this.expectedClass = true;
+				this.params = args;
+			};
+		};
+
+		require([
+			"require", "dojo/_base/array", "dojo/aspect", "dojo/_base/declare",
+			"dojo/dom", "dojo/dom-attr", "dojo/dom-construct", "dojo/_base/lang", "dojo/on", "dojo/parser",
+			"dojo/_base/window", "dojo/date/stamp", "dojo/Stateful", "dojo/Evented",
+			"doh", "dojo/tests/resources/AMDWidget", "dojo/tests/resources/AMDMixin", "dojo/domReady!"
+		], function(require, array, aspect, declare, dom, domAttr, domConstruct, lang, on, parser, win, dstamp,
+						Stateful, Evented, doh, AMDWidget, AMDMixin){
+
+			declare("tests.parser.Widget", null, {
+				constructor: function(args, node){
+					this.params = args;
+				}
+			});
+
+			declare("tests.parser.Class1", null, {
+				constructor: function(args, node){
+					this.params = args;
+					lang.mixin(this, args);
+				},
+				preambleTestProp: 1,
+				preamble: function(){
+					this.preambleTestProp++;
+				},
+				intProp: 1,
+				callCount: 0, // for connect testing
+				callInc: function(){ this.callCount++; },
+				callCount2: 0, // for assignment testing
+				strProp1: "original1",
+				strProp2: "original2",
+				arrProp: [],
+				arrProp2: ["foo"],
+				boolProp1: false,
+				boolProp2: true,
+				boolProp3: false,
+				boolProp4: true,
+				dateProp1: dstamp.fromISOString('2007-01-01'),
+				dateProp2: dstamp.fromISOString('2007-01-01'),
+				dateProp3: dstamp.fromISOString('2007-01-01'),
+				funcProp: function(){},
+				funcProp2: function(){},
+				funcProp3: function(){},
+				onclick: function(){ this.prototypeOnclick=true; }
+				// FIXME: have to test dates!!
+				// FIXME: need to test the args property!!
+			});
+
+			declare("tests.parser.Class2", null, {
+				constructor: function(){
+					this.fromMarkup = false;
+				},
+				fromMarkup: false,
+				markupFactory: function(args, node, classCtor){
+					var i = new tests.parser.Class2();
+					i.fromMarkup = true;
+					return i;
+				}
+			});
+
+			declare("tests.parser.Class3", tests.parser.Class2, {
+				fromMarkup: false,
+				markupFactory: function(args, node, classCtor){
+					var i = new classCtor();
+					i.classCtor = classCtor;
+					i.params = args;
+					return i;
+				}
+			});
+
+			declare("tests.parser.InputClass", null, {
+				constructor: function(args, node){
+					this.params = args;
+					lang.mixin(this, args);
+				},
+
+				// these attributes are special in HTML, they don't have a value specified
+				disabled: false,
+				readonly: false,
+				checked: false,
+
+				// other attributes native to HTML
+				value: "default value",
+				title: "default title",
+				tabIndex: "0",		// special because mixed case
+
+				// custom widget attributes that don't match a native HTML attributes
+				custom1: 123,
+				custom2: 456
+			});
+
+			// Test that dir, lang, etc. attributes can be inherited from ancestor node
+			declare("tests.parser.BidiClass", tests.parser.Widget, {
+				constructor: function(args, node){ lang.mixin(this, args); },
+				dir: "",
+				lang: "",
+				textdir: "",
+				name: ""
+			});
+
+			// For testing that parser recurses correctly, except when the prototype has a
+			// stopParser flag
+			declare("tests.parser.NormalContainer", null, {
+				constructor: function(args, node){ lang.mixin(this, args); }
+			});
+			declare("tests.parser.ShieldedContainer", null, {
+				constructor: function(args, node){ lang.mixin(this, args); },
+
+				// flag to tell parser not to instantiate nodes inside of me
+				stopParser: true
+			});
+
+			declare("tests.parser.HTML5Props", null, {
+				constructor: function(args, node){ lang.mixin(this, args); },
+				simple:false,
+				a:2,
+				b:null, c:null, d: null, e:null, f:null,
+				afn: function(){
+					return this.a * 2;
+				}
+			});
+
+			// not on .prototype:
+			tests.parser.HTML5Props._aDefaultObj = {
+				a:1, b:2, simple:true
+			};
+
+			declare("tests.parser.HTML5withMethod", null, {
+				constructor: function(args, node){ lang.mixin(this, args); },
+				baseValue: 10,
+				someMethod: function(a, b){
+					return this.baseValue;
+				},
+				diffMethod: function(a){
+					this._ran = true;
+				}
+			});
+
+			declare("tests.parser.StatefulClass", [Evented, Stateful], {
+				strProp1: "",
+				objProp1: {},
+				boolProp1: false,
+				prototypeOnclick: false,
+				onclick: function() {this.prototypeOnclick=true;}
+			});
+
+			declare("tests.parser.MethodClass", null, {
+				method1ran: false,
+				method1after: false,
+				method2ran: false,
+				method2before: false,
+				method2after: false,
+				method3result: "",
+				method4ran: false,
+				method4after: false,
+				method1: function() { this.method1ran = true },
+				method2: function() { this.method2ran = true },
+				method3: function(result) { this.method3result = result; },
+				method4: function() { this.method4ran = true }
+			});
+
+			declare("tests.parser.ClassForMixins", null, {
+				classDone: true
+			});
+
+			declare("tests.parser.Mixin1", null, {
+				mixin1Done: true
+			});
+
+			declare("tests.parser.Mixin2", null, {
+				mixin2Done: true
+			});
+
+			deepTestProp = {
+				blah: {
+					thinger: 1
+				}
+			};
+
+			tests.parser.FormClass = declare(tests.parser.Widget, {
+				encType: ""
+			});
+
+			doh.register("basic tests", [
+				function parse(){
+					// Running the parser here so that failures appear in test log
+					parser.parse(dom.byId("main"));
+				},
+				function testDataDojoId(t){
+					t.is("object", typeof obj);
+				},
+				function testJsId(t){
+					// Back-compat test, remove for 2.0
+					t.is("object", typeof obj3);
+				},
+				// Attribute parsing tests
+				function testStrProp(t){
+					// normal string parameter
+					t.t(typeof obj.strProp1 == "string", "obj.strProp1 is string");
+					t.is("text", obj.strProp1);
+
+					// make sure that you override a string value like "foo" to a blank value
+					t.t(typeof obj.strProp2 == "string", "obj.strProp2 is string");
+					t.is("", obj.strProp2);
+				},
+				function testIntProp(t){
+					t.is("number", (typeof obj.intProp));
+					t.is(5, obj.intProp);
+				},
+				function testArrProp(t){
+					t.is(3, obj.arrProp.length);
+					t.is(3, obj.arrProp[1].length);
+					t.is(["foo", "bar", "baz"], obj.arrProp);
+
+					// make sure empty arrays are possible
+					t.is([], obj.arrProp2);
+				},
+				function testBoolProp(t){
+					// make sure that both true and false get read correctly,
+					// and that unspecified attributes' values don't change
+
+					// boolProp1 specified at true
+					t.is("boolean", (typeof obj.boolProp1));
+					t.t(obj.boolProp1);
+
+					// boolProp2 specified as false
+					t.is("boolean", (typeof obj.boolProp2));
+					t.f(obj.boolProp2);
+
+					// boolProp3 not specified (prototype says false)
+					t.is("boolean", (typeof obj.boolProp3));
+					t.f(obj.boolProp3);
+
+					// boolProp4 not specified (prototype says true)
+					t.is("boolean", (typeof obj.boolProp4));
+					t.t(obj.boolProp4);
+				},
+				function testDateProp(t){
+					// dateProp1 specified as 2006-1-1
+					t.is("2006-01-01", dstamp.toISOString(obj.dateProp1, {selector: 'date'}));
+
+					// dateProp2="", should map to NaN (a blank value on DateTextBox)
+					t.t(isNaN(obj.dateProp2));
+
+					// dateProp3="now", should map to current date
+					t.is(dstamp.toISOString(new Date(), {selector: 'date'}),
+						dstamp.toISOString(obj.dateProp3, {selector: 'date'}));
+				},
+				function testUnwantedParams(t){
+					// Make sure that parser doesn't pass any unwanted parameters to
+					// widget constructor, especially "toString" or "constructor".
+					// Make exception for dir/lang which parser gleans from document itself.
+					for(var param in obj.params){
+						doh.t(array.indexOf(
+							["strProp1", "strProp2",
+								"intProp",
+								"arrProp", "arrProp2",
+								"boolProp1", "boolProp2",
+								"dateProp1", "dateProp2", "dateProp3",
+								"funcProp2", "funcProp3",
+								"preamble",
+								"callInc1", "callInc2", "dir", "lang", "textDir"],
+							param) >= 0, param);
+					}
+				},
+				function testDisabledFlag(t){
+					t.is("boolean", typeof disabledObj.disabled, "typeof disabled");
+					t.t(disabledObj.disabled, "disabled");
+					t.f(disabledObj.checked, "checked");
+				},
+				function testCheckedFlag(t){
+					t.is("boolean", typeof checkedObj.checked, "typeof checked");
+					t.f(checkedObj.disabled, "disabled");
+					t.t(checkedObj.checked, "checked");
+				},
+				function testFunctionProp(t){
+					// make sure that unspecified functions (even with common names)
+					// don't get overridden (bug #3074)
+					obj.onclick();
+					t.t(obj.prototypeOnclick, "prototypeOnClick");
+
+					// funcProp2="foo"
+					obj.funcProp2();
+					t.t(obj.fooCalled, "fooCalled");
+
+					// funcProp3="this.func3Called=true;"
+					obj.funcProp3();
+					t.t(obj.func3Called, "func3Called");
+				},
+
+				// test script tags inside innerHTML of source node
+				"t.is(4, obj.preambleTestProp);",
+				"t.is(deepTestProp, obj.deepProp);",
+				function testConnect(t){
+					obj.callInc();
+					t.is(2, obj.callCount);
+				},
+				function testFunctionAssignment(t){
+					obj.callInc2();
+					t.is(1, obj.callCount2);
+				},
+				function testSubNodeParse(t){
+					t.f(lang.exists("obj2"), "exists before parse");
+					var toParse = dom.byId("toParse");
+					parser.parse(toParse.parentNode);
+					t.t(lang.exists("obj2"), "exists after parse");
+					t.is("tests.parser.Class1", obj2.declaredClass);
+				},
+				function testMarkupFactory(t){
+					t.t(lang.exists("obj3"), "obj3 exists");
+					t.t(obj3.fromMarkup);
+				},
+				function testMarkupFactoryClass(t){
+					t.t(lang.exists("obj4"), "obj4 exists");
+					t.is(obj4.classCtor, tests.parser.Class3);
+					t.t(obj4 instanceof tests.parser.Class3);
+					t.t(obj4 instanceof tests.parser.Class2);
+				},
+				function testnostart(t){
+
+					var started = false;
+					declare("SampleThinger", null, {
+						startup: function(){
+							started = true;
+						}
+					});
+
+					domConstruct.create("div", { dojoType:"SampleThinger" }, "parsertest");
+					parser.parse("parsertest", { noStart:true });
+
+					t.f(started, "first started check");
+
+					domConstruct.empty("parsertest");
+
+					started = false;
+
+					domConstruct.create("div", { dojoType:"SampleThinger" }, "parsertest");
+					parser.parse({ noStart:true, rootNode:"parsertest" });
+
+					t.f(started, "second started check");
+				},
+
+				// test the various iterations of parser test
+				function rootTest(t){
+
+					var tmp = aspect.after(dojo, "query", function(sel, root){
+						t.is("parsertest2", root);
+					});
+
+					parser.parse("parsertest2");
+					parser.parse({ rootNode: "parsertest2" });
+					parser.parse("parsertest2", { noStart:true });
+
+					tmp.remove();
+				},
+
+				// Test that when BorderContainer etc. extends _Widget,
+				// parser is aware of the new parameters added (to _Widget
+				// and all of it's subclasses)
+				function cacheRefresh(t){
+					// Add new node to be parsed, referencing a widget that the parser has already
+					// dealt with (and thus cached)
+					var wrapper = domConstruct.place("<div><div dojoType='tests.parser.Class3' newParam=12345>hi</div></div>", win.body(), "last");
+
+					// Modify Class3's superclass widget to have new parameter (thus Class3 inherits it)
+					lang.extend(tests.parser.Class2, {
+						newParam: 0
+					});
+
+					// Run the parser and see if it reads in newParam
+					var widgets = parser.parse({rootNode: wrapper});
+					doh.is(1, widgets.length, "parsed newly inserted parserTest widget");
+					doh.is(12345, widgets[0].params.newParam, "new parameter parsed");
+				},
+
+				// Test that parser recurses correctly, except when there's a stopParser flag not to
+				function recurse(){
+					doh.t(container1, "normal container created");
+					doh.t(container1.incr, "script tag works too");
+					doh.t(window.contained1, "child widget also created");
+					doh.t(window.contained2, "child widget 2 also created");
+
+					doh.t(container2, "shielded container created");
+					doh.t(container2.incr, "script tag works too");
+					doh.f(window.contained3, "child widget not created");
+					doh.f(window.contained4, "child widget 2 not created");
+				},
+
+				function simpleHTML5(){
+					doh.is("object", typeof html5simple, "data-dojo-id export");
+					doh.is("object", typeof html5simple2, "data-dojo-id export");
+
+					doh.t(html5simple.simple, "default respecified in props=''");
+					doh.f(html5simple2.simple, "default overridden by props=''");
+
+					// test data-dojo-props="simple:false, a:1, b:'two', c:[1,2,3], d:function(){ return this; }, e:{ f:'g' }"
+					var it = html5simple2;
+					doh.is(1, it.a, "number in param");
+					doh.is("two", it.b, "string in param");
+					doh.t(it.c instanceof Array, "array in param");
+					doh.is(3, it.c.length, "array sanity");
+					doh.is("g", it.e.f, "nested object with string");
+
+					// test the function
+					doh.is(it, it.d(), "simple 'return this' function");
+
+				},
+
+				function html5inherited(){
+					doh.is("object", typeof html5simple3);
+					var val = html5simple3.afn();
+					doh.is(html5simple3.a * 2, val, "afn() overrides default but calls inherited")
+				},
+
+				function html5withMethod(){
+					// testing data-dojo-event and data-dojo-args support for dojo/method and dojo/connect
+					doh.is("object", typeof htmldojomethod);
+					doh.t(htmldojomethod._methodRan, "plain dojo/method ran");
+
+					var x = htmldojomethod.someMethod(2, 2);
+					doh.is(14, x, "overridden dojo/method");
+
+					htmldojomethod.diffMethod(2);
+					doh.t(htmldojomethod._ran, "ensures original was called first");
+					doh.is(2, htmldojomethod._fromvalue, "ensures connected was executed in scope");
+				},
+
+				function testOnWatch(){
+					// testing script-type dojo/watch and dojo/on
+					doh.is("object", typeof objOnWatch);
+					objOnWatch.set("strProp1","newValue1");
+					doh.is("newValue1", objOnWatch.arrProp.newValue, "ensures watch executed");
+
+					objOnWatch.onclick();
+					doh.t(objOnWatch.prototypeOnclick, "ensures original was called");
+					doh.t(objOnWatch.boolProp1, "ensure on executed in scope");
+				},
+
+				function testOn2(){
+					// testing script-type dojo/on, when script comes after another element
+					parser.parse("on");
+					doh.t("on_form" in window, "widget created");
+					on_form.emit("click");
+					doh.t(on_form.clicked, "on callback fired");
+				},
+
+				function testAspect(){
+					// testing script-type dojo/aspect
+					doh.is("object", typeof objAspect);
+					doh.f(objAspect.method1ran, "ensures method unfired");
+					doh.f(objAspect.method2ran, "ensures method unfired");
+					doh.is(objAspect.method3result, "", "ensures method unfired");
+					doh.f(objAspect.method4ran, "ensures method unfired");
+
+					objAspect.method1();
+					objAspect.method2();
+					objAspect.method3("something");
+					objAspect.method4();
+
+					doh.t(objAspect.method1ran, "method fired");
+					doh.t(objAspect.method1after, "after advice fired");
+					doh.t(objAspect.method2ran, "method fired");
+					doh.t(objAspect.method2before, "around before advice fired");
+					doh.t(objAspect.method2after, "around after advice fired");
+					doh.is(objAspect.method3result, "before", "before argument passed");
+					doh.t(objAspect.method4ran, "method fired");
+					doh.t(objAspect.method4after, "after advice fired");
+				},
+
+				function testMID(){
+					// testing specifying data-dojo-type as mid
+					doh.is("object", typeof objAMDWidget);
+					doh.is("Value1", objAMDWidget.params.value, "ensure object was properly parsed using MID");
+				}
+			]);
+
+			doh.register("BIDI", [
+				// Test that dir=rtl or dir=ltr setting trickles down from root node
+				function dirAttr(){
+					parser.parse("dirSection1");
+					parser.parse("dirSection2");
+					doh.is("rtl", setRtl.dir, "direct setting of dir=rtl works");
+					doh.is("rtl", inheritRtl.dir, "inherited rtl works");
+					doh.is("ltr", inheritLtr.dir, "inherited ltr works (closest ancestor wins)");
+					doh.is("rtl", inheritRtl2.dir, "inherited rtl works, from grandparent");
+					doh.is("ltr", setLtr.dir, "direct setting of dir=ltr overrides inherited RTL");
+				},
+				function langAttr(){
+					parser.parse("langSection");
+					doh.f(lang in noLang.params, "no lang");
+					doh.is("it_it", inheritedLang.lang, "inherited lang works");
+					doh.is("en_us", specifiedLang.lang,"direct setting of lang overrides inherited");
+				},
+				function textdirAttr(){
+					parser.parse("textDirSection");
+					doh.f("textDir" in noTextdir.params, "no textdir");
+					doh.is("rtl", inheritedTextdir.textDir, "inherited textdir works");
+					doh.is("ltr", specifiedTextdir.textDir,"direct setting of textdir overrides inherited");
+				},
+				{
+					// Test that calling parser.parse(nodeX) will inherit dir/lang/etc. settings
+					// even from <html>
+					name: "inheritance from HTML",
+					setUp: function(){
+						domAttr.set(win.doc.documentElement, {dir: "rtl", lang: "ja-jp", "data-dojo-textdir": "auto"});
+						parser.parse("bidiInheritanceFromHtml");
+					},
+					runTest: function(){
+						doh.is("rtl", inheritedFromHtml.params.dir, "dir");
+						doh.is("ja-jp", inheritedFromHtml.params.lang, "lang");
+						doh.is("auto", inheritedFromHtml.params.textDir, "textDir");
+					},
+					tearDown: function(){
+						array.forEach(["dir", "lang", "data-dojo-textdir"], function(attr){
+							win.doc.documentElement.removeAttribute(attr);
+						});
+					}
+				}
+			]);
+
+			doh.register("IE attribute detection", [
+				function input1(){
+					var widgets = parser.instantiate([dom.byId("ieInput1")]);
+					var params = widgets[0].params;
+
+					doh.is("checkbox", params.type, "type");
+					doh.t(params.disabled, "disabled");
+					doh.t(params.checked, "checked");
+					doh.t(params.readonly, "readonly");
+					doh.is("bar", params.foo, "foo");
+					doh.is("zaz", params.bar, "bar");
+					doh.is("escaped\"dq", params.bob, "bob");
+					doh.is("escaped\'sq", params.frank, "frank");
+					//doh.f("value" in params, "value not specified");	// fails in IE8, thinks value=="on"
+				},
+				function input2(){
+					var widgets = parser.instantiate([dom.byId("ieInput2")]);
+					var params = widgets[0].params;
+
+					doh.f("type" in params, "type");
+					doh.f("name" in params, "name");
+					doh.f("value" in params, "value");
+					doh.f("data-dojo-type" in params, "data-dojo-type");
+					doh.f("data-dojo-props" in params, "data-dojo-props");
+					doh.is("hi", params.foo, "foo");
+					doh.f("value" in params, "value not specified");
+				},
+				function input3(){
+					var widgets = parser.instantiate([dom.byId("ieInput3")]);
+					var params = widgets[0].params;
+
+					doh.is("password", params.type, "type");
+					doh.is("test", params.name, "name");
+					doh.is("123", params.value, "value");
+					doh.is("myClass", params["class"], "class");
+					doh.is("display:block", params["style"].replace(/[ ;]/g, "").toLowerCase(), "style");
+					doh.is("3", params.tabIndex, "tabIndex");
+				},
+				function textarea(){
+					var widgets = parser.instantiate([dom.byId("ieTextarea")]);
+					var params = widgets[0].params;
+
+					doh.is("attrVal", params.value, "value");
+				},
+				function button1(){
+					var widgets = parser.instantiate([dom.byId("ieButton1")]);
+					var params = widgets[0].params;
+					doh.t(params.checked, "checked");
+					doh.is("button1val", params.value, "value");
+				},
+				function button2(){
+					var widgets = parser.instantiate([dom.byId("ieButton2")]);
+					var params = widgets[0].params;
+					doh.f("checked" in params, "checked");
+					doh.f("value" in params, "value");
+				},
+				function button3(){
+					var widgets = parser.instantiate([dom.byId("ieButton3")]);
+					var params = widgets[0].params;
+					doh.t(params.checked, "checked");
+				},
+				function button4(){
+					var widgets = parser.instantiate([dom.byId("ieButton4")]);
+					var params = widgets[0].params;
+					doh.f("checked" in params);
+				},
+				function form1(){
+					var widgets = parser.instantiate([dom.byId("ieForm1")]);
+					var params = widgets[0].params;
+
+					doh.is("foo", params.encType, "encType is specified");
+				},
+				function form2(){
+					var widgets = parser.instantiate([dom.byId("ieForm2")]);
+					var params = widgets[0].params;
+
+					doh.f("encType" in params, "encType not specified")
+				},
+				function li(){
+					var widgets = parser.instantiate([dom.byId("li")]);
+					var params = widgets[0].params;
+					doh.is("home", params.value);
+
+				}
+			]);
+
+			doh.register("mixed attribute specification", function mixed(){
+				parser.parse(dom.byId("mixedContainer"));
+				doh.is("object", typeof mixedObj, "widget created");
+				doh.is("mixedValue", mixedObj.value, "native attribute");
+				doh.is(999, mixedObj.custom1, "data-dojo-props attribute");
+				doh.is("custom title", mixedObj.title, "data-dojo-props overrides native");
+			});
+
+			doh.register("functions", function onclick(){
+				// Create objects referenced from markup inside of "functions" div
+				declare("tests.parser.Button", null, {
+					onClick: function(){
+						console.log("prototype click");
+					},
+					constructor: function(args, node){
+						lang.mixin(this, args);
+						this.domNode = node;
+						aspect.after(this.domNode, "onclick", lang.hitch(this, "onClick"));
+					}
+				});
+				buttonClicked = function(){
+					console.log("markup click");
+				};	// markup says onClick="buttonClicked"
+
+				// Parse markup inside "functions" div
+				parser.parse("functions");
+
+				// Should have created an instance called "button" where button.onClick == buttonClicked
+				doh.is("object", typeof button, "widget created");
+				doh.is("function", typeof button.onClick, "created as function");
+				doh.t(buttonClicked == button.onClick, "points to specified function");
+			});
+
+			doh.register("parser.instantiate()", function instantiate1() {
+				var nodes = [dom.byId("objId1"),dom.byId("objId2"),dom.byId("contId1"),dom.byId("objId3")];
+				parser.instantiate(nodes);
+				doh.is("object", typeof objI1, "widget 1 created");
+				doh.is("object", typeof objI2, "widget 2 created");
+				doh.t(contI1, "container created");
+				doh.is("object", typeof objI3, "child widget 3 created");
+				doh.f(window.objI4, "child widget 4 not created");
+			});
+
+			doh.register("parser.construct()", function construct1() {
+				var nodes = [dom.byId("objC1"),dom.byId("objC2")];
+
+				parser.construct(tests.parser.Class1, dom.byId("objC1"));
+				doh.is("object", typeof objC1, "widget 1 created");
+				doh.is(5, objC1.intProp, "objC1.intProp");
+
+				parser.construct(tests.parser.Class1, dom.byId("objC2"));
+				doh.is("object", typeof objC2, "widget 2 created");
+				doh.is(5, objC2.intProp, "objC2.intProp");
+			});
+
+			doh.register("data-dojo-mixins support", function mixins() {
+				parser.parse("mixins");
+				doh.t(resultMixins1, "object using data-dojo-mixins created from an already parsed type");
+				doh.t(resultMixins1.mixin1Done, "mixin1 correctly mixed in");
+				doh.t(resultMixins1.mixin2Done, "mixin2 correctly mixed in");
+				doh.t(resultMixins1.amdMixinDone, "amd mixin correctly mixed in");
+				doh.t(resultMixins2, "object using data-dojo-mixins created from a non parsed type");
+				doh.t(resultMixins2.classDone, "class correctly created");
+				doh.t(resultMixins2.mixin1Done, "mixin1 correctly mixed in");
+				doh.t(resultMixins2.mixin2Done, "mixin2 correctly mixed in");
+				doh.t(resultMixins2.amdMixinDone, "amd mixin correctly mixed in");
+				doh.t(resultNonDojoMixin.expectedClass, "correct class is returned for composeJS mixin");
+				doh.is(resultNonDojoMixin.params.length, 2, "correct # of params were passed to compose JS");
+				doh.is(resultNonDojoMixin.params[0], tests.parser.Mixin1, "correct param 1");
+				doh.is(resultNonDojoMixin.params[1], tests.parser.Mixin2, "correct param 2");
+			});
+
+			// For any special issues with behavioral widgets (as opposed to Templated)
+			doh.register("behavioral", [
+				function doubleConnect(){
+					// Class used in "behavioral" <div>
+					Behavioral1 = declare(null, {
+						constructor: function(params, node){
+							on(node, "click", lang.hitch(this, "onClick"));
+							if(typeof params.onClick != "function"){
+								throw new Error("onClick not passed to constructor");
+							}
+							lang.mixin(this, params);
+						},
+						onClick: function(){
+							console.log("original onnClick handler")
+						},
+						foo: ""
+					});
+
+					parser.parse("behavioral");
+
+					// Setup global accessed by Behavioral1.onclick handler
+					behavioralClickCounter = 0;
+
+					// Trigger click event, and make sure that handler was only called once.
+					on.emit(dom.byId("bh1"), "click", {bubbles: true, cancelable: true});
+
+					doh.is(1, behavioralClickCounter, "one click event processed");
+
+					doh.is("bar", dom.byId("bh1").getAttribute("foo"), "foo attribute not removed from widget DOMNode");
+				}
+			]);
+
+			doh.register("script type=dojo/require support", function declarativeRequire(){
+				var td = new doh.Deferred();
+
+				parser.parse("declarativeRequire").then(td.getTestCallback(function(){
+					doh.is(typeof dr1, "object", "object using MID mapped to return var");
+					doh.is(dr1.params.foo, "bar", "parameters set on instantiation");
+					doh.is(typeof dr2, "object", "object using MID mapped to return var");
+					doh.is(dr2.params.foo, "bar", "parameters set on instantiation");
+					doh.is(typeof dr3, "object", "object using fully required");
+					doh.is(dr3.params.foo, "bar", "parameters set on instantiation");
+					doh.is(dr4.params.foo, 2, "module loaded and executed");
+					doh.is(dr5.method1(1), 3, "declarative script has access to parser scope");
+				}));
+
+				return td;
+			});
+
+			doh.register("context require support", function contextRequire(){
+				var td = new doh.Deferred();
+
+				parser.parse("contextRequire", {
+					contextRequire: require
+				}).then(td.getTestCallback(function(){
+					doh.is(typeof cr1, "object", "object using relative MID mapped to return var");
+					doh.is(cr1.params.foo, "bar", "parameters set on instantiation");
+					doh.is(typeof cr2, "object", "object using relative MID mapped to return var");
+					doh.is(cr2.params.foo, "bar", "parameters set on instantiation");
+					doh.is(typeof cr3, "object", "object using relative MID mapped to return var");
+					doh.is(cr3.params.foo, "bar", "parameters set on instantiation");
+					doh.is(typeof cr4, "object", "object using relative MID mapped to return var");
+					doh.is(cr4.params.foo, "bar", "parameters set on instantiation");
+				}));
+
+				return td;
+			});
+
+			doh.register("promise error handling support", [
+				function asyncError(){
+					var td = new doh.Deferred();
+
+					parser.parse("errorHandling").then(td.getTestErrback(function(){
+						throw new Error("shouldn't get here");
+					}), td.getTestCallback(function(e){
+						doh.is(typeof e, "object", "error object returned");
+					}));
+
+					return td;
+				},
+				function missingCtor(){
+					var td = new doh.Deferred();
+
+					parser.parse("missingCtor").then(td.getTestErrback(function(){
+						throw new Error("shouldn't get here");
+					}), td.getTestCallback(function(e){
+						doh.is(typeof e, "object", "error object returned");
+						doh.is(e.toString(), "Error: Unable to resolve constructor for: 'some.type'", "proper error value returned");
+					}));
+
+					return td;
+				}
+			]);
+
+			doh.run();
+		});
+		</script>
+	</head>
+	<body>
+		<h1>Parser Unit Test</h1>
+
+		<div id=main>
+			<script>
+				function foo(){ this.fooCalled=true; }
+			</script>
+			<div dojoType="tests.parser.Class1" data-dojo-id="obj"
+				 strProp1="text" strProp2=""
+				 intProp="5"
+				 arrProp="foo, bar, baz"
+				 arrProp2=""
+				 boolProp1="true" boolProp2="false"
+				 dateProp1="2006-01-01" dateProp2="" dateProp3="now"
+				 funcProp2="foo" funcProp3="this.func3Called=true;"
+			>
+				<script type="dojo/method" data-dojo-event="preamble">
+					this.preambleTestProp = 3;
+				</script>
+				<script type="dojo/method">
+					// this should be run immediately
+					this.deepProp = deepTestProp;
+				</script>
+				<script type="dojo/connect" data-dojo-event="callInc">
+					this.callCount++;
+				</script>
+				<script type="dojo/method" data-dojo-event="callInc2">
+					this.callCount2++;
+				</script>
+			</div>
+			<div dojoType="tests.parser.Class2" jsId="obj3">
+			</div>
+			<div dojoType="tests.parser.Class3" data-dojo-id="obj4">
+			</div>
+			<input dojoType="tests.parser.InputClass" data-dojo-id="checkedObj" checked type="checkbox">
+			<button dojoType="tests.parser.InputClass" data-dojo-id="disabledObj" disabled>hi</button>
+
+			<div id="parsertest"></div>
+			<div id="parsertest2"></div>
+
+			<!-- section for testing parser recursion -->
+			<div>
+				<div dojoType="tests.parser.NormalContainer" data-dojo-id="container1">
+					<!-- this script tag should get passed as param to NormalContainer constructor -->
+					<script type="dojo/method" data-dojo-event="incr" data-dojo-args="x">
+						return x+1;
+					</script>
+
+					<!-- and these contained widgets should get instantiated -->
+					<div dojoType="tests.parser.Class1" data-dojo-id="contained1"></div>
+					<div>
+						<div dojoType="tests.parser.Class1" data-dojo-id="contained2"></div>
+					</div>
+				</div>
+			</div>
+
+			<div>
+				<div dojoType="tests.parser.ShieldedContainer" data-dojo-id="container2">
+					<!-- this script tag should get passed as param to ShieldedContainer constructor -->
+					<script type="dojo/method" data-dojo-event="incr" data-dojo-args="x">
+						return x+1;
+					</script>
+
+					<!-- but these contained widgets should *not* get instantiated -->
+					<div dojoType="tests.parser.Class1" data-dojo-id="contained3"></div>
+					<div>
+						<div dojoType="tests.parser.Class1" data-dojo-id="contained4"></div>
+					</div>
+				</div>
+			</div>
+
+			<!-- tests for new data-dojo-type / data-dojo-props syntax -->
+			<div>
+				<div data-dojo-id="html5simple" data-dojo-type="tests.parser.HTML5Props" data-dojo-props="simple:true"></div>
+				<div data-dojo-id="html5simple2" data-dojo-type="tests.parser.HTML5Props"
+					 data-dojo-props="simple:false, a:1, b:'two', c:[1,2,3], d:function(){ return this; }, e:{ f:'g' }"
+				></div>
+				<!-- note needing to use a named inherited lookup because we're just mixing in -->
+				<div data-dojo-id="html5simple3" data-dojo-type="tests.parser.HTML5Props"
+					 data-dojo-props="afn: function(){ return this.inherited('afn', arguments); }"
+				></div>
+
+				<!-- not used for tests, but thinking out loud: what about a named-resource prop, via getObject -->
+				<div data-dojo-id="html5fromobjectns" data-dojo-type="tests.parser.HTML5Props"
+					 data-dojo-obj="tests.parser.HTML5Props._aDefaultObj"
+				></div>
+				<div data-dojo-id="html5fromobjectns2" data-dojo-type="tests.parser.HTML5Props"
+					 data-dojo-obj="tests.parser.HTML5Props._aDefaultObj" data-dojo-props="simple:false"
+				></div>
+
+			</div>
+
+			<div>
+				<div data-dojo-id="htmldojomethod" data-dojo-type="tests.parser.HTML5withMethod">
+					<p>Some random markup</p>
+					<script type="dojo/method" data-dojo-event="someMethod" data-dojo-args="a, b">
+						return this.baseValue + a + b;
+					</script>
+					<script type="dojo/connect" data-dojo-event="diffMethod" data-dojo-args="a">
+						console.log("diffMethod connect, this is ", this);
+						this._fromvalue = a;
+					</script>
+					<script type="dojo/method">
+						this._methodRan = true;
+					</script>
+					<div data-dojo-id="objAspect" data-dojo-type="tests.parser.MethodClass">
+						<script type="dojo/aspect" data-dojo-method="method1" data-dojo-advice="after">
+							if(this.method1ran){
+								this.method1after = true;
+							}
+						</script>
+						<script type="dojo/aspect" data-dojo-method="method2" data-dojo-advice="around" data-dojo-args="origFn">
+							return function(){
+								if(!this.method2ran){
+									this.method2before = true;
+								}
+								origFn.call(this);
+								if(this.method2ran){
+									this.method2after = true;
+								}
+							};
+						</script>
+						<script type="dojo/aspect" data-dojo-method="method3" data-dojo-advice="before" data-dojo-args="result">
+							if(result == "something"){
+								return ["before"];
+							}
+						</script>
+						<script type="dojo/aspect" data-dojo-method="method4">
+							if(this.method4ran){
+								this.method4after = true;
+							}
+						</script>
+					</div>
+				</div>
+			</div>
+
+			<!-- section for testing dojo/on and dojo/watch scripts -->
+			<div>
+				<div data-dojo-id="objOnWatch" data-dojo-type="tests.parser.StatefulClass">
+					<script type="dojo/watch" data-dojo-prop="strProp1" data-dojo-args="prop,oldValue,newValue">
+						this.set("arrProp",{prop: prop, oldValue: oldValue, newValue: newValue});
+					</script>
+					<script type="dojo/on" data-dojo-event="click" data-dojo-args="e">
+						console.log("diffMethod on, this is ",this);
+						this.set("boolProp1",true);
+					</script>
+				</div>
+			</div>
+
+			<!-- section for testing mid syntax for data-dojo-type -->
+			<div>
+				<div data-dojo-id="objAMDWidget" data-dojo-type="dojo/tests/resources/AMDWidget" data-dojo-props="value: 'Value1'"></div>
+			</div>
+		</div> <!-- end of <div id=main> -->
+
+		<!-- more dojo/on tests -->
+		<div id="on">
+			<form action="/SomeUrl" data-dojo-type="tests.parser.StatefulClass" data-dojo-id="on_form">
+				<input data-dojo-type="tests.parser.InputClass" name="ACheckBox" />
+				<script type="dojo/on" data-dojo-event="click">
+					this.clicked = true;
+				</script>
+			</form>
+		</div>
+
+		<!-- section for testing parse on a subnode -->
+		<div>
+			<div data-dojo-type="tests.parser.Class1" data-dojo-id="obj2" id="toParse">
+			</div>
+		</div>
+
+		<!-- section for testing that dir, lang attribute trickles down from ancestor -->
+		<div id="dirSection1">
+			<div dojoType="tests.parser.BidiClass" data-dojo-id="setRtl" dir="rtl" name="RTL setting"></div>
+			<div dojoType="tests.parser.BidiClass" data-dojo-id="noDir" name="dir not inherited or set"></div>
+		</div>
+		<div id="dirSection2" dir="rtl">
+			<div dojoType="tests.parser.BidiClass" data-dojo-id="inheritRtl" name="inherited RTL from parent"></div>
+			<div dir="ltr">
+				<div dojoType="tests.parser.BidiClass" data-dojo-id="inheritLtr" name="inherited LTR from parent"></div>
+			</div>
+			<div>
+				<div dojoType="tests.parser.BidiClass" data-dojo-id="inheritRtl2" name="inherited RTL from grandparent"></div>
+			</div>
+			<div dojoType="tests.parser.BidiClass" data-dojo-id="setLtr" dir="ltr" name="LTR setting overrides inherited RTL"></div>
+		</div>
+		<div id="langSection">
+			<div dojoType="tests.parser.BidiClass" data-dojo-id="noLang" name="shouldn't get lang"></div>
+			<div lang="it_it">
+				<div dojoType="tests.parser.BidiClass" data-dojo-id="inheritedLang" name="inherited lang from parent"></div>
+				<div dojoType="tests.parser.BidiClass" data-dojo-id="specifiedLang" lang="en_us" name="specified lang overrides parent"></div>
+			</div>
+		</div>
+		<div id="textDirSection">
+			<div dojoType="tests.parser.BidiClass" data-dojo-id="noTextdir" name="shouldn't get textdir"></div>
+			<div data-dojo-textdir="rtl">
+				<div dojoType="tests.parser.BidiClass" data-dojo-id="inheritedTextdir" name="inherited textdir from parent"></div>
+				<div dojoType="tests.parser.BidiClass" data-dojo-id="specifiedTextdir" data-dojo-textdir="ltr" name="specified textdir overrides parent"></div>
+			</div>
+		</div>
+		<div id="bidiInheritanceFromHtml">
+			<div dojoType="tests.parser.BidiClass" data-dojo-id="inheritedFromHtml" name="should get dir/lang/textDir from HTML tag"></div>
+		</div>
+
+		<!-- tests that we can parse parameters correctly on IE6/7, not getting tripped up by escaped quotes etc. -->
+		<div id=ie>
+			<input id="ieInput1" data-dojo-type="tests.parser.InputClass"
+				   type=checkbox disabled foo = 'bar' readonly bar=zaz bob='escaped"dq' frank="escaped'sq" checked />
+			<input id="ieInput2" data-dojo-type="tests.parser.InputClass"
+				   fakeout1="type=submit" fakeout2="name='test'" fakeout3="value='123'" data-dojo-props="foo: 'hi'"/>
+			<input id="ieInput3" data-dojo-type="tests.parser.InputClass"
+				   type=password name="test" value="123" class="myClass" style="display:block" tabindex="3"/>
+			<textarea id="ieTextarea" data-dojo-type="tests.parser.InputClass" value="attrVal">contentVal</textarea>
+			<button id="ieButton1" data-dojo-type="tests.parser.InputClass" checked value="button1val">
+				checked ToggleButton as button
+			</button>
+			<button id="ieButton2" data-dojo-type="tests.parser.InputClass">
+				unchecked ToggleButton as button
+			</button>
+			<div id="ieButton3" data-dojo-type="tests.parser.InputClass" checked>
+				checked ToggleButton as div
+			</div>
+			<div id="ieButton4" data-dojo-type="tests.parser.InputClass">
+				unchecked ToggleButton as div
+			</div>
+			<form id="ieForm1" data-dojo-type="tests.parser.FormClass" encType="foo"></form>
+			<form id="ieForm2" data-dojo-type="tests.parser.FormClass"></form>
+			<ul dojoType="tests.parser.Widget" class="nav">
+				<li id="li" dojoType="tests.parser.Widget" value="home">Home</li>
+				<li dojoType="tests.parser.Widget" value="contact">Contact</li>
+				<li dojoType="tests.parser.Widget" value="group">Group</li>
+				<li dojoType="tests.parser.Widget" value="campaign">Campaign</li>
+			</ul>
+		</div>
+
+		<!-- tests for when parameters are specified both natively and in data-dojo-props. -->
+		<div id="mixedContainer">
+			<input data-dojo-type="tests.parser.InputClass" data-dojo-id="mixedObj"
+				   value="mixedValue" title="native title" data-dojo-props="custom1: 999, title: 'custom title'">
+		</div>
+
+		<!-- tests for function names native to HTML, specifically an issue on IE<8 -->
+		<div id="functions">
+			<button dojoType="tests.parser.Button" onClick="buttonClicked" data-dojo-id="button">Click me</button>
+		</div>
+
+		<!-- section for testing parser.instantiate() -->
+		<div id="instantiate1">
+			<div dojoType="tests.parser.Class1" data-dojo-id="objI1" id="objId1"
+				 strProp1="text" strProp2=""
+				 intProp="5"
+				 arrProp="foo, bar, baz"
+				 arrProp2=""
+				 boolProp1="true" boolProp2="false"
+				 dateProp1="2006-01-01" dateProp2="" dateProp3="now"
+				 funcProp2="foo" funcProp3="this.func3Called=true;"
+			>
+			</div>
+			<div data-dojo-type="tests.parser.Class1" data-dojo-id="objI2" id="objId2"
+				 data-dojo-props="
+					strProp1:'text',
+					strProp2:'',
+					intProp:5,
+					arrProp:['foo', 'bar', 'baz'],
+					arrProp2:[],
+					boolProp1:true,
+					boolProp2:'false',
+					dateProp1:'2006-01-01',
+					dateProp2:'',
+					dateProp3:'now',
+					funcProp2:foo,
+					funcProp3:'this.func3Called=true;'"
+			>
+			</div>
+			<div dojoType="tests.parser.NormalContainer" data-dojo-id="contI1" id ="contId1">
+				<div dojoType="tests.parser.Class1" data-dojo-id="objI3" id="objId3"></div>
+				<div dojoType="tests.parser.Class1" data-dojo-id="objI4" id="objId4"></div>
+			</div>
+		</div>
+
+		<!-- section for testing parser.construct() -->
+		<div id="construct1">
+			<div data-dojo-id="objC1" id="objC1"
+				 strProp1="text" strProp2=""
+				 intProp="5"
+				 arrProp="foo, bar, baz"
+				 arrProp2=""
+				 boolProp1="true" boolProp2="false"
+				 dateProp1="2006-01-01" dateProp2="" dateProp3="now"
+				 funcProp2="foo" funcProp3="this.func3Called=true;"
+			>
+			</div>
+			<div data-dojo-id="objC2" id="objC2"
+				 data-dojo-props="
+					strProp1:'text',
+					strProp2:'',
+					intProp:5,
+					arrProp:['foo', 'bar', 'baz'],
+					arrProp2:[],
+					boolProp1:true,
+					boolProp2:'false',
+					dateProp1:'2006-01-01',
+					dateProp2:'',
+					dateProp3:'now',
+					funcProp2:foo,
+					funcProp3:'this.func3Called=true;'"
+			>
+			</div>
+		</div>
+
+		<!-- tests for data-dojo-mixins -->
+		<div id="mixins">
+			<div data-dojo-type="tests.parser.Class1" data-dojo-mixins="tests.parser.Mixin1,tests.parser.Mixin2,dojo/tests/resources/AMDMixin"
+				 data-dojo-id="resultMixins1"></div>
+			<div data-dojo-type="tests.parser.ClassForMixins" data-dojo-mixins="tests.parser.Mixin1, tests.parser.Mixin2, dojo/tests/resources/AMDMixin"
+				 data-dojo-id="resultMixins2"></div>
+			<div data-dojo-type="MyNonDojoClass" data-dojo-mixins="tests.parser.Mixin1, tests.parser.Mixin2"
+				 data-dojo-id="resultNonDojoMixin"></div>
+		</div>
+
+		<!-- tests for behavioral widgets -->
+		<div id="behavioral">
+			<div data-dojo-type="Behavioral1" onClick="behavioralClickCounter++;" id="bh1" foo="bar">click me</div>
+		</div>
+		
+		<!-- tests for declarative require -->
+		<div id="declarativeRequire">
+			<script type="dojo/require">
+				AMDWidget: "dojo/tests/resources/AMDWidget",
+				AMDWidget2: "dojo/tests/resources/AMDWidget2"
+			</script>
+			<div data-dojo-id="dr1" data-dojo-type="AMDWidget" data-dojo-props="foo: 'bar'"></div>
+			<div data-dojo-id="dr2" data-dojo-type="AMDWidget2" data-dojo-props="foo: 'bar'"></div>
+			<script type="dojo/require">
+				AMDWidget3: "dojo/tests/resources/AMDWidget3"
+			</script>
+			<div data-dojo-id="dr3" data-dojo-type="dojo/tests/resources/AMDWidget3" data-dojo-props="foo: 'bar'"></div>
+			<script type="dojo/require">
+				amdmodule: "dojo/tests/resources/amdmodule"
+			</script>
+			<div data-dojo-id="dr4" data-dojo-type="AMDWidget" data-dojo-props="foo: amdmodule(1)"></div>
+			<div data-dojo-id="dr5" data-dojo-type="AMDWidget2">
+			<script type="dojo/aspect" data-dojo-advice="before" data-dojo-method="method1" data-dojo-args="value">
+				return [amdmodule(value)];
+			</script>
+			</div>
+		</div>
+
+		<!-- tests for context require -->
+		<!-- The relative MIDs, because they are "up", the loader thinks they are not necessarily modules, in the 
+				real world, they would most likely be in sibling paths and the need for the .js would not be
+				necessary -->
+		<div id="contextRequire">
+			<script type="dojo/require">
+				"context.AMDWidget": "../resources/AMDWidget.js",
+				"context.AMDWidget2": "../resources/AMDWidget2.js"
+			</script>
+			<div data-dojo-id="cr1" data-dojo-type="context.AMDWidget" data-dojo-props="foo: 'bar'"></div>
+			<div data-dojo-id="cr2" data-dojo-type="context.AMDWidget2" data-dojo-props="foo: 'bar'"></div>
+			<div data-dojo-id="cr3" data-dojo-type="../resources/AMDWidget.js" data-dojo-props="foo: 'bar'"></div>
+			<div data-dojo-id="cr4" data-dojo-type="../resources/AMDWidget3.js" data-dojo-props="foo: 'bar'"></div>
+		</div>
+		
+		<!-- tests for promise error handling -->
+		<div id="errorHandling">
+			<div data-dojo-type="dojo/tests/resources/AMDWidget" data-dojo-props="foo: bar"></div>
+		</div>
+		<div id="missingCtor">
+			<div data-dojo-type="some.type"></div>
+		</div>
+	</body>
+</html>
diff --git a/dojo/tests/parser/parserAsync.html b/dojo/tests/parser/parserAsync.html
new file mode 100644
index 0000000..98b43fe
--- /dev/null
+++ b/dojo/tests/parser/parserAsync.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Parser Asynchronous Widget Creation Unit Test</title>
+<style type="text/css">
+	@import "../../resources/dojo.css";
+</style>
+<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true, async:true"></script>
+<script type="text/javascript">
+
+require([
+	"doh",
+	"dojo/_base/array", "dojo/_base/declare", "dojo/Deferred", "dojo/dom", "dojo/_base/lang", "dojo/parser",
+	"dojo/domReady!"
+], function(doh, array, declare, Deferred, dom, lang, parser){
+
+	// instances of AsyncWidget will finish initializing when this Deferred is resolved
+	var finishCreatingAsyncWidgets = new Deferred();
+
+	AsyncWidget = declare(null, {
+		declaredClass: "AsyncWidget",
+		markupFactory: function(params, node){
+			// the markup factory can return a promise, and the parser will wait
+			return finishCreatingAsyncWidgets.then(function(){return new AsyncWidget(params, node); });
+		},
+		constructor: function(args, node){
+			this.params = args;
+			lang.mixin(this, args);
+		},
+		startup: function(){
+			this._started = true;
+		}
+	});
+
+	SyncWidget = declare(null, {
+		declaredClass: "SyncWidget",
+		constructor: function(args, node){
+			this.params = args;
+			lang.mixin(this, args);
+		},
+		startup: function(){
+			this._started = true;
+		}
+	});
+
+	doh.register("async tests", [
+		function parse(){
+			var d = new doh.Deferred();
+
+			// Call the parser
+			var parsePromise = parser.parse(dom.byId("main"));
+			
+			// Parse should be waiting for the async widget to finish creating
+			doh.f(parsePromise.isFulfilled(), "parse not finished yet");
+			doh.is("undefined", typeof asyncWidget, "async widget not created yet");
+			doh.f(syncWidget._started, "sync widget created by not started");
+
+			// Now make the async widget finish initializing
+			finishCreatingAsyncWidgets.resolve(true);
+
+			parsePromise.then(d.getTestCallback(function(list){
+				doh.t(asyncWidget._started, "async widget started");
+				doh.t(syncWidget._started, "sync widget started too");
+				doh.is("AsyncWidget, SyncWidget", array.map(list, function(cls){ return cls.declaredClass; }).join(", "),
+						"list of instances returned from parser");
+			}));
+
+			return d;
+		}
+	]);
+
+	doh.run();
+});
+</script>
+</head>
+<body>
+<h1>Parser Asynchronous Widget Creation Unit Test</h1>
+
+<div id=main>
+	<span data-dojo-id="asyncWidget" data-dojo-type="AsyncWidget">hi</span>
+	<span data-dojo-id="syncWidget" data-dojo-type="SyncWidget">there</span>
+</div>
+
+</body>
+</html>
diff --git a/dojo/tests/parser/runTests.html b/dojo/tests/parser/runTests.html
new file mode 100644
index 0000000..1e47011
--- /dev/null
+++ b/dojo/tests/parser/runTests.html
@@ -0,0 +1,10 @@
+<!DOCTYPE>
+<html>
+    <head>
+		<title>Dojo Parser D.O.H. Unit Test Runner</title>
+		<meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojo.tests.parser">
+    </head>
+    <body>
+        Redirecting to D.O.H runner.
+    </body>
+</html>
diff --git a/dojo/tests/promise.js b/dojo/tests/promise.js
new file mode 100644
index 0000000..130f179
--- /dev/null
+++ b/dojo/tests/promise.js
@@ -0,0 +1,8 @@
+define([
+	"dojo/tests/Deferred",
+	"dojo/tests/promise/Promise",
+	"dojo/tests/when",
+	"dojo/tests/promise/all",
+	"dojo/tests/promise/first",
+	"dojo/tests/promise/tracer"
+], 1);
diff --git a/dojo/tests/promise/Promise.js b/dojo/tests/promise/Promise.js
new file mode 100644
index 0000000..9718972
--- /dev/null
+++ b/dojo/tests/promise/Promise.js
@@ -0,0 +1,60 @@
+define([
+	"doh/main",
+	"dojo/Deferred"
+], function(doh, Deferred){
+	var tests = {
+		"always() will be invoked for resolution and rejection": function(t){
+			var obj = {};
+			var deferred1 = new Deferred();
+			var thenResult, alwaysResult;
+			deferred1.promise.then(function(result){ thenResult = result; });
+			deferred1.promise.always(function(result){ alwaysResult = result; });
+			deferred1.resolve(obj);
+			t.t(alwaysResult === obj);
+			t.t(alwaysResult === thenResult);
+
+			var deferred2 = new Deferred();
+			var thenResult2, alwaysResult2;
+			deferred2.promise.then(null, function(result){ thenResult2 = result; });
+			deferred2.promise.always(function(result){ alwaysResult2 = result; });
+			deferred2.reject(obj);
+			t.t(alwaysResult2 === obj);
+			t.t(alwaysResult2 === thenResult2);
+		},
+
+		"otherwise(…) is equivalent to then(null, …)": function(t){
+			var obj = {};
+			var thenResult, otherwiseResult;
+			this.deferred.then(null, function(result){ thenResult = result; });
+			this.deferred.promise.otherwise(function(result){ otherwiseResult = result; });
+			this.deferred.reject(obj);
+			t.t(otherwiseResult === obj);
+			t.t(otherwiseResult === thenResult);
+		},
+
+		"trace() returns the same promise": function(t){
+			var promise = this.deferred.promise.trace();
+			t.t(promise === this.deferred.promise);
+		},
+
+		"traceRejected() returns the same promise": function(t){
+			var promise = this.deferred.promise.traceRejected();
+			t.t(promise === this.deferred.promise);
+		}
+	};
+
+	var wrapped = [];
+	for(var name in tests){
+		wrapped.push({
+			name: name,
+			setUp: setUp,
+			runTest: tests[name]
+		});
+	}
+
+	function setUp(){
+		this.deferred = new Deferred;
+	}
+
+	doh.register("tests.promise.Promise", wrapped);
+});
diff --git a/dojo/tests/promise/all.js b/dojo/tests/promise/all.js
new file mode 100644
index 0000000..2169577
--- /dev/null
+++ b/dojo/tests/promise/all.js
@@ -0,0 +1,104 @@
+define([
+	"doh/main",
+	"dojo/Deferred",
+	"dojo/promise/all"
+], function(doh, Deferred, all){
+	var tests = {
+		"all() with array argument": function(t){
+			var obj1 = {}, obj2 = {}, obj3 = {};
+			var received;
+			all([this.deferred, new Deferred().resolve(obj2), obj3]).then(function(result){ received = result; });
+			this.deferred.resolve(obj1);
+			t.t(received[0] === obj1);
+			t.t(received[1] === obj2);
+			t.t(received[2] === obj3);
+		},
+
+		"all() with object argument": function(t){
+			var obj1 = {}, obj2 = {}, obj3 = {};
+			var received;
+			all({ a: this.deferred, b: new Deferred().resolve(obj2), c: obj3 }).then(function(result){ received = result; });
+			this.deferred.resolve(obj1);
+			t.t(received.a === obj1);
+			t.t(received.b === obj2);
+			t.t(received.c === obj3);
+		},
+
+		"all() without arguments": function(t){
+			var received;
+			all().then(function(){ received = arguments; });
+			t.is(received.length, 1);
+			t.t(typeof received[0] === "undefined");
+		},
+
+		"all() with single non-object argument": function(t){
+			var received;
+			all(null).then(function(){ received = arguments; });
+			t.is(received.length, 1);
+			t.t(typeof received[0] === "undefined");
+		},
+
+		"all() with empty array": function(t){
+			var received;
+			all([]).then(function(result){ received = result; });
+			t.is(received, []);
+		},
+
+		"all() with empty object": function(t){
+			var received;
+			all({}).then(function(result){ received = result; });
+			t.is(received, {});
+		},
+
+		"all() with one rejected promise": function(t){
+			var obj = {};
+			var received;
+			all([this.deferred, new Deferred().reject(obj), {}]).then(null, function(result){ received = result; });
+			t.t(received === obj);
+		},
+
+		"all() with one promise rejected later": function(t){
+			var obj = {};
+			var received;
+			all([this.deferred, new Deferred(), new Deferred()]).then(null, function(result){ received = result; });
+			this.deferred.reject(obj);
+			t.t(received === obj);
+		},
+
+		"all() with multiple promises rejected later": function(t){
+			var obj = {};
+			var deferred2 = new Deferred();
+			var received;
+			all([this.deferred, deferred2, new Deferred()]).then(null, function(result){ received = result; });
+			this.deferred.reject(obj);
+			deferred2.reject({});
+			t.t(received === obj);
+		},
+
+		"all() cancel only affects returned promise, not those we're waiting for": function(t){
+			var obj = {};
+			var canceled = false;
+			var deferred2 = new Deferred(function(){ canceled = true; });
+			var received;
+			var promise = all([this.deferred, deferred2, new Deferred()]).then(null, function(result){ received = result; });
+			promise.cancel(obj);
+			t.t(received === obj);
+			t.f(canceled);
+		}
+	};
+
+	var wrapped = [];
+	for(var name in tests){
+		wrapped.push({
+			name: name,
+			setUp: setUp,
+			runTest: tests[name]
+		});
+	}
+
+	function setUp(){
+		this.deferred = new Deferred;
+	}
+
+	doh.register("tests.promise.all", wrapped);
+});
diff --git a/dojo/tests/promise/first.js b/dojo/tests/promise/first.js
new file mode 100644
index 0000000..ce76007
--- /dev/null
+++ b/dojo/tests/promise/first.js
@@ -0,0 +1,100 @@
+define([
+	"doh/main",
+	"dojo/Deferred",
+	"dojo/promise/first"
+], function(doh, Deferred, first){
+	var tests = {
+		"first() with array argument": function(t){
+			var obj = {};
+			var received;
+			first([this.deferred, new Deferred().resolve(obj), {}]).then(function(result){ received = result; });
+			this.deferred.resolve({});
+			t.t(received === obj);
+		},
+
+		"with object argument": function(t){
+			var obj = {};
+			var received;
+			first({ a: this.deferred, b: new Deferred().resolve(obj), c: {} }).then(function(result){ received = result; });
+			this.deferred.resolve({});
+			t.t(received === obj);
+		},
+
+		"first() without arguments": function(t){
+			var received;
+			first().then(function(){ received = arguments; });
+			t.is(received.length, 1);
+			t.t(typeof received[0] === "undefined");
+		},
+
+		"first() with single non-object argument": function(t){
+			var received;
+			first(null).then(function(){ received = arguments; });
+			t.is(received.length, 1);
+			t.t(typeof received[0] === "undefined");
+		},
+
+		"first() with empty array": function(t){
+			var received = false;
+			first([]).then(function(result){ received = result; });
+			t.t(typeof received === "undefined");
+		},
+
+		"first() with empty object": function(t){
+			var received = false;
+			first({}).then(function(result){ received = result; });
+			t.t(typeof received === "undefined");
+		},
+
+		"first() with one rejected promise": function(t){
+			var obj = {};
+			var received;
+			first([this.deferred, new Deferred().reject(obj), {}]).then(null, function(result){ received = result; });
+			t.t(received === obj);
+		},
+
+		"first() with one promise rejected later": function(t){
+			var obj = {};
+			var received;
+			first([this.deferred, new Deferred(), new Deferred()]).then(null, function(result){ received = result; });
+			this.deferred.reject(obj);
+			t.t(received === obj);
+		},
+
+		"first() with multiple promises rejected later": function(t){
+			var obj = {};
+			var deferred2 = new Deferred();
+			var received;
+			first([this.deferred, deferred2, new Deferred()]).then(null, function(result){ received = result; });
+			this.deferred.reject(obj);
+			deferred2.reject({});
+			t.t(received === obj);
+		},
+
+		"first() cancel only affects returned promise, not those we're waiting for": function(t){
+			var obj = {};
+			var canceled = false;
+			var deferred2 = new Deferred(function(){ canceled = true; });
+			var received;
+			var promise = first([this.deferred, deferred2, new Deferred()]).then(null, function(result){ received = result; });
+			promise.cancel(obj);
+			t.t(received === obj);
+			t.f(canceled);
+		}
+	};
+
+	var wrapped = [];
+	for(var name in tests){
+		wrapped.push({
+			name: name,
+			setUp: setUp,
+			runTest: tests[name]
+		});
+	}
+
+	function setUp(){
+		this.deferred = new Deferred;
+	}
+
+	doh.register("tests.promise.first", wrapped);
+});
diff --git a/dojo/tests/promise/tracer.js b/dojo/tests/promise/tracer.js
new file mode 100644
index 0000000..26f0440
--- /dev/null
+++ b/dojo/tests/promise/tracer.js
@@ -0,0 +1,106 @@
+define([
+	"doh/main",
+	"dojo/Deferred",
+	"dojo/promise/tracer"
+], function(doh, Deferred, tracer){
+	var tests = {
+		"trace() resolved": function(t){
+			var td = new doh.Deferred;
+			var obj = {};
+			this.handles.push(tracer.on("resolved", function(value){
+				t.t(value === obj);
+				td.callback(true);
+			}));
+			this.deferred.promise.trace();
+			this.deferred.resolve(obj);
+			return td;
+		},
+
+		"trace() rejected": function(t){
+			var td = new doh.Deferred;
+			var obj = {};
+			this.handles.push(tracer.on("rejected", function(error){
+				t.t(error === obj);
+				td.callback(true);
+			}));
+			this.deferred.promise.trace();
+			this.deferred.reject(obj);
+			return td;
+		},
+
+		"trace() progress": function(t){
+			var td = new doh.Deferred;
+			var obj = {};
+			this.handles.push(tracer.on("progress", function(update){
+				t.t(update === obj);
+				td.callback(true);
+			}));
+			this.deferred.promise.trace();
+			this.deferred.progress(obj);
+			return td;
+		},
+
+		"passing extra arguments to trace()": function(t){
+			var td = new doh.Deferred;
+			var obj = {};
+			this.handles.push(tracer.on("resolved", function(value, arg1, arg2){
+				t.t(value === obj);
+				t.is(arg1, "test");
+				t.t(arg2 === obj);
+				td.callback(true);
+			}));
+			this.deferred.promise.trace("test", obj);
+			this.deferred.resolve(obj);
+			return td;
+		},
+
+		"traceRejected()": function(t){
+			var td = new doh.Deferred;
+			var obj = {};
+			this.handles.push(tracer.on("rejected", function(error){
+				t.t(error === obj);
+				td.callback(true);
+			}));
+			this.deferred.promise.traceRejected();
+			this.deferred.reject(obj);
+			return td;
+		},
+
+		"passing extra arguments": function(t){
+			var td = new doh.Deferred;
+			var obj = {};
+			this.handles.push(tracer.on("rejected", function(error, arg1, arg2){
+				t.t(error === obj);
+				t.is(arg1, "test");
+				t.t(arg2 === obj);
+				td.callback(true);
+			}));
+			this.deferred.promise.traceRejected("test", obj);
+			this.deferred.reject(obj);
+			return td;
+		}
+	};
+
+	var wrapped = [];
+	for(var name in tests){
+		wrapped.push({
+			name: name,
+			setUp: setUp,
+			tearDown: tearDown,
+			runTest: tests[name]
+		});
+	}
+
+	function setUp(){
+		this.handles = [];
+		this.deferred = new Deferred;
+	}
+
+	function tearDown(){
+		while(this.handles.length){
+			this.handles.pop().remove();
+		}
+	}
+
+	doh.register("tests.promise.tracer", wrapped);
+});
diff --git a/dojo/tests/query.js b/dojo/tests/query.js
new file mode 100644
index 0000000..2eb84ed
--- /dev/null
+++ b/dojo/tests/query.js
@@ -0,0 +1,27 @@
+define(["doh/main", "dojo/sniff", "require"], function(doh, has, require){
+	if(doh.isBrowser){
+		// Test dojo/query with every query engine/CSS level setting, plus with nothing specified
+		doh.register("tests.query-lite", require.toUrl("./query/query.html?selector=lite"), 30000);
+		doh.register("tests.query-css2", require.toUrl("./query/query.html?selector=css2"), 30000);
+		doh.register("tests.query-css2.1", require.toUrl("./query/query.html?selector=css2.1"), 30000);
+		doh.register("tests.query-css3", require.toUrl("./query/query.html?selector=css3"), 30000);
+		doh.register("tests.query-acme", require.toUrl("./query/query.html?selector=acme"), 30000);
+		doh.register("tests.query-unspecified", require.toUrl("./query/query.html"), 30000);
+
+		// Test quirks mode too, except on IE9+ because of the IE problem where the iframe gets confused about its
+		// mode when the iframe is quirks but the parent is standards.
+		if(!(has("ie") >= 9)){
+			doh.register("tests.query-lite-quirks", require.toUrl("./query/queryQuirks.html?selector=lite"), 30000);
+			doh.register("tests.query-css2-quirks", require.toUrl("./query/queryQuirks.html?selector=css2"), 30000);
+			doh.register("tests.query-css2.1-quirks", require.toUrl("./query/queryQuirks.html?selector=css2.1"), 30000);
+			doh.register("tests.query-css3-quirks", require.toUrl("./query/queryQuirks.html?selector=css3"), 30000);
+			doh.register("tests.query-acme-quirks", require.toUrl("./query/queryQuirks.html?selector=acme"), 30000);
+			doh.register("tests.query-unspecified-quirks", require.toUrl("./query/queryQuirks.html"), 30000);
+		}
+
+		// Test loading XHTML document.   Commented out on IE since it causes a warning dialog
+		if(!has("ie")){
+			doh.register("tests.query-xml", require.toUrl("./query/xml.xhtml"), 30000);
+		}
+	}
+});
diff --git a/dojo/tests/query/query.html b/dojo/tests/query/query.html
new file mode 100644
index 0000000..234c46a
--- /dev/null
+++ b/dojo/tests/query/query.html
@@ -0,0 +1,474 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>testing query()</title>
+		<style type="text/css">
+			@import "../../resources/dojo.css";
+		</style>
+		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true, async: true"></script>
+		<script type="text/javascript">
+			// Use selector specified in URL (ex: query.html?selector=lite), defaulting to acme if unspecified
+			var specified = window.location.search.substr(1).match(/selector=(.*)/);
+			var selector = specified ? specified[0].split("=")[1] : "acme";
+
+			require(["doh", "dojo/_base/array", "dojo/dom", "dojo/request/iframe",
+				"dojo/query!"+selector, "dojo/NodeList", "dojo/sniff", "dojo/domReady!"],
+					function(doh, array, dom, iframe, dq, NodeList, has){
+				query = dq; // make a global
+
+				function createDocument(xml){
+					var fauxXhr = { responseText: xml };
+					if("DOMParser" in window){
+						var parser = new DOMParser();
+						fauxXhr.responseXML = parser.parseFromString(xml, "text/xml");
+					}
+					// kludge: code from dojo.xhr contentHandler to create doc on IE
+					var result = fauxXhr.responseXML;
+					if(has("ie")){
+						// Needed for IE6-8
+						if((!result || !result.documentElement)){
+							var ms = function(n){ return "MSXML" + n + ".DOMDocument"; };
+							var dp = ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
+							array.some(dp, function(p){
+								try{
+									var dom = new ActiveXObject(p);
+									dom.async = false;
+									dom.loadXML(fauxXhr.responseText);
+									result = dom;
+								}catch(e){ return false; }
+								return true;
+							});
+						}
+					}
+					return result; // DOMDocument
+				}
+
+				// Tests that should work for any selector engine (lite or acme)
+				// .class, #id, tag, and star, attribute selectors, and child (>), descendant (space),and union (,)
+				// combinators. With a native selector engine, the lite engine does not support pseudo classes.
+				doh.register("css2", [
+					// basic sanity checks
+					"doh.is(4, (query('h3')).length);",
+					"doh.is(1, (query('#t')).length);",
+					"doh.is(1, (query('#bug')).length);",
+					"doh.is(4, (query('#t h3')).length);",
+					"doh.is(1, (query('div#t')).length);",
+					"doh.is(4, (query('div#t h3')).length);",
+					"doh.is(0, (query('span#t')).length);",
+					"doh.is(0, (query('.bogus')).length);",
+					function dotBogus(){ doh.is(0, (query('.bogus', dom.byId('container'))).length); },
+					"doh.is(0, (query('#bogus')).length);",
+					function poundBogus(){ doh.is(0, (query('#bogus', dom.byId('container'))).length); },
+					"doh.is(1, (query('#t div > h3')).length);",
+					"doh.is(2, (query('.foo')).length);",
+					"doh.is(1, (query('.foo.bar')).length);",
+					"doh.is(2, (query('.baz')).length);",
+					"doh.is(3, (query('#t > h3')).length);",
+					
+					// this fails on IE8 because qSA completely fails on unknown elements. not sure how to fix this other than completely disable qSA on IE8, which would be an unacceptable performance regression
+					//"doh.t(query.matches(query('section')[0],'section'));",
+
+					function comma1(){
+						doh.is(2, (query('#baz,#foo,#t')).length);
+					},
+					function comma2(){
+						doh.is(2, (query('#foo,#baz,#t')).length);
+					},
+					"doh.is(0, (query(null)).length);",
+
+					//"doh.is(1, (query('#bug')).length);",
+
+					// syntactic equivalents
+					"doh.is(12, (query('#t > *')).length);",
+					"doh.is(3, (query('.foo > *')).length);",
+
+					// with a root, by ID
+					"doh.is(3, (query('> *', 'container')).length);",
+					"doh.is(3, (query('> *, > h3', 'container')).length);",
+					"doh.is(3, (query('> h3', 't')).length);",
+
+					// compound queries
+					"doh.is(2, (query('.foo, .bar')).length);",
+					"doh.is(2, (query('.foo,.bar')).length);",
+
+					// multiple class attribute
+					"doh.is(1, (query('.foo.bar')).length);",
+					"doh.is(2, (query('.foo')).length);",
+					"doh.is(2, (query('.baz')).length);",
+
+					// case sensitivity
+					"doh.is(1, (query('span.baz')).length);",
+					"doh.is(1, (query('sPaN.baz')).length);",
+					"doh.is(1, (query('SPAN.baz')).length);",
+					"doh.is(1, query('.fooBar').length);",
+					
+					// attribute selectors
+					"doh.is(3, (query('[foo]')).length);",
+
+					// attribute substring selectors
+					"doh.is(1, (query('[foo$=\"thud\"]')).length);",
+					"doh.is(1, (query('[foo$=thud]')).length);",
+					"doh.is(1, (query('[foo$=\"thudish\"]')).length);",
+					"doh.is(1, (query('#t [foo$=thud]')).length);",
+					"doh.is(1, (query('#t [title$=thud]')).length);",
+					"doh.is(0, (query('#t span[title$=thud ]')).length);",
+					"doh.is(1, (query('[id$=\\'55555\\']')).length);",
+					"doh.is(2, (query('[foo~=\"bar\"]')).length);",
+					"doh.is(2, (query('[ foo ~= \"bar\" ]')).length);",
+					"doh.is(2, (query('[foo|=\"bar\"]')).length);",
+					"doh.is(1, (query('[foo|=\"bar-baz\"]')).length);",
+					"doh.is(0, (query('[foo|=\"baz\"]')).length);",
+					// TODO: ^=, *=
+
+					// descendant selectors
+					"doh.is(3, query('> *', 'container').length);",
+					"doh.is(2, query('> [qux]', 'container').length);",
+					"doh.is('child1', query('> [qux]', 'container')[0].id);",
+					"doh.is('child3', query('> [qux]', 'container')[1].id);",
+					"doh.is(3, query('> *', 'container').length);",
+					"doh.is(3, query('>*', 'container').length);",
+					"doh.is('passed', query('#bug')[0].value);",
+
+					// bug 9071
+					"doh.is(2, (query('a', 't4')).length);",
+					"doh.is(2, (query('p a', 't4')).length);",
+					"doh.is(2, (query('div p', 't4')).length);",
+					"doh.is(2, (query('div p a', 't4')).length);",
+					"doh.is(2, (query('.subA', 't4')).length);",
+					"doh.is(2, (query('.subP .subA', 't4')).length);",
+					"doh.is(2, (query('.subDiv .subP', 't4')).length);",
+					"doh.is(2, (query('.subDiv .subP .subA', 't4')).length);",
+
+					// failed scope arg
+					"doh.is(0, (query('*', 'thinger')).length);",
+					"doh.is(0, (query('div#foo').length));",
+
+					// escaping special characters with quotes (http://www.w3.org/TR/CSS21/syndata.html#strings)
+					// bug 10651
+					'doh.is(1, query(\'option[value="a+b"]\', "attrSpecialChars").length);',
+					'doh.is(1, query(\'option[value="a~b"]\', "attrSpecialChars").length);',
+					'doh.is(1, query(\'option[value="a^b"]\', "attrSpecialChars").length);',
+					'doh.is(1, query(\'option[value="a,b"]\', "attrSpecialChars").length);',
+
+					// selector with substring that contains equals sign (bug 7479)
+					"doh.is(1, query(\"a[href*='foo=bar']\", 'attrSpecialChars').length);",
+
+					// selector with substring that contains brackets (bug 9193, 11189, 13084)
+					'doh.is(1, query(\'input[name="data[foo][bar]"]\', "attrSpecialChars").length);',
+					'doh.is(1, query(\'input[name="foo[0].bar"]\', "attrSpecialChars").length);',
+					'doh.is(1, query(\'input[name="test[0]"]\', "attrSpecialChars").length);',
+
+					// escaping special characters with backslashes (http://www.w3.org/TR/CSS21/syndata.html#characters)
+					// selector with substring that contains brackets (bug 9193, 11189, 13084)
+					// eval() converts 4 backslashes --> 1 by the time dojo.query() sees the string
+					'doh.is(1, query("input[name=data\\\\[foo\\\\]\\\\[bar\\\\]]", "attrSpecialChars").length);',
+					'doh.is(1, query("input[name=foo\\\\[0\\\\]\\\\.bar]", "attrSpecialChars").length);',
+
+					// cross-document queries
+					{
+						name: "crossDocumentQuery",
+						setUp: function(){
+							this.t3 = window.frames["t3"];
+							this.doc = iframe.doc(t3);
+							this.doc.open();
+							this.doc.write([
+								"<html><head>",
+								"<title>inner document</title>",
+								"</head>",
+								"<body>",
+								"<div id='st1'><h3>h3 <span>span <span> inner <span>inner-inner</span></span></span> endh3 </h3></div>",
+								"</body>",
+								"</html>"
+							].join(""));
+						},
+						runTest: function(){
+							doh.is(1, query('h3', dom.byId("st1", this.doc)).length);
+							// use a long query to force a test of the XPath system on FF. see bug #7075
+							doh.is(1, query('h3 > span > span > span', dom.byId("st1", this.doc)).length);
+							doh.is(1, query('h3 > span > span > span', this.doc.body.firstChild).length);
+						}
+					},
+
+					// escaping of ":" chars inside an ID
+					function silly_IDs1(){
+						doh.t(document.getElementById("silly:id::with:colons"), "getElementById");
+						doh.is(1, query("#silly\\:id\\:\\:with\\:colons").length, "query(\"#silly\\:id\\:\\:with\\:colons\")");
+						doh.is(1, query("#silly\\~id").length, "query(\"#silly\\~id\")");
+					},
+					function xml(){
+						var doc = createDocument([
+							"<ResultSet>",
+							"<Result>One</Result>",
+							"<RESULT>Two</RESULT>",
+							"<result><nested>Three</nested></result>",
+							"<result>Four</result>",
+							"</ResultSet>"
+						].join("")
+						);
+						var de = doc.documentElement;
+
+						doh.is(2, query("result", de).length, "all lower");
+
+						//doh.is(1, query("result>nested", de).length, "nested XML");
+						doh.is(1, query("Result", de).length, "mixed case");
+						doh.is(1, query("RESULT", de).length, "all upper");
+						doh.is(0, query("resulT", de).length, "no match");
+						doh.is(0, query("rEsulT", de).length, "no match");
+					},
+					function xml_attrs(){
+						if(!has("ie")){	// remove if() when #14880 is fixed
+							var doc = createDocument([
+								"<ResultSet>",
+								"<RESULT thinger='blah'>ONE</RESULT>",
+								"<RESULT thinger='gadzooks'><CHILD>Two</CHILD></RESULT>",
+								"</ResultSet>"
+							].join(""));
+							var de = doc.documentElement;
+
+							doh.is(2, query("RESULT", de).length, "result elements");
+							doh.is(0, query("RESULT[THINGER]", de).length, "result elements with attrs (wrong)");
+							doh.is(2, query("RESULT[thinger]", de).length, "result elements with attrs");
+							doh.is(1, query("RESULT[thinger=blah]", de).length, "result elements with attr value");
+							doh.is(1, query("RESULT > CHILD", de).length, "Using child operator");
+						} // remove when #14880 is fixed
+					},
+					function sort(){
+						var i = query("div");
+						// smoke test
+						i.sort(function(a,b){ return 1; })
+					}
+				]);
+
+				// Tests for CSS2.1+, and also CSS2 pseudo selectors (which aren't supported by selector=css2 or
+				// selector=lite)
+				if(/css2.1|css3|acme/.test(selector)){
+					doh.register("css2.1", [
+						// first-child
+						"doh.is(1, (query('h1:first-child')).length);",
+						"doh.is(2, (query('h3:first-child')).length);",
+
+						// + sibling selector
+						"doh.is(1, (query('.foo+ span')).length);",
+						"doh.is(1, (query('.foo+span')).length);",
+						"doh.is(1, (query('.foo +span')).length);",
+						"doh.is(1, (query('.foo + span')).length);"
+					]);
+				}
+
+				// Tests for CSS3+
+				if(/css3|acme/.test(selector)){
+					doh.register("css3", [
+						// sub-selector parsing
+						"doh.is(1, query('#t span.foo:not(:first-child)').length);",
+
+						// ~ sibling selector
+						"doh.is(4, (query('.foo~ span')).length);",
+						"doh.is(4, (query('.foo~span')).length);",
+						"doh.is(4, (query('.foo ~span')).length);",
+						"doh.is(4, (query('.foo ~ span')).length);",
+						"doh.is(1, (query('#foo~ *')).length);",
+						"doh.is(1, (query('#foo ~*')).length);",
+						"doh.is(1, (query('#foo ~*')).length);",
+						"doh.is(1, (query('#foo ~ *')).length);",
+						// "t.is(0, (query('[ foo ~= \"\\'bar\\'\" ]')).length);",
+
+						// nth-child tests
+						"doh.is(2, query('#t > h3:nth-child(odd)').length);",
+						"doh.is(3, query('#t h3:nth-child(odd)').length);",
+						"doh.is(3, query('#t h3:nth-child(2n+1)').length);",
+						"doh.is(1, query('#t h3:nth-child(even)').length);",
+						"doh.is(1, query('#t h3:nth-child(2n)').length);",
+						"doh.is(1, query('#t h3:nth-child(2n+3)').length);",
+						"doh.is(2, query('#t h3:nth-child(1)').length);",
+						"doh.is(1, query('#t > h3:nth-child(1)').length);",
+						"doh.is(3, query('#t :nth-child(3)').length);",
+						"doh.is(0, query('#t > div:nth-child(1)').length);",
+						"doh.is(7, query('#t span').length);",
+						"doh.is(3, query('#t > *:nth-child(n+10)').length);",
+						"doh.is(1, query('#t > *:nth-child(n+12)').length);",
+						"doh.is(10, query('#t > *:nth-child(-n+10)').length);",
+						"doh.is(5, query('#t > *:nth-child(-2n+10)').length);",
+						"doh.is(6, query('#t > *:nth-child(2n+2)').length);",
+						"doh.is(5, query('#t > *:nth-child(2n+4)').length);",
+						"doh.is(5, query('#t > *:nth-child(2n+4)').length);",
+						"doh.is(5, query('#t> *:nth-child(2n+4)').length);",
+						// TODO: uncomment these two tests when #14879 fixed
+						//"doh.is(12, query('#t > *:nth-child(n-5)').length);",
+						//"doh.is(12, query('#t >*:nth-child(n-5)').length);",
+						"doh.is(6, query('#t > *:nth-child(2n-5)').length);",
+						"doh.is(6, query('#t>*:nth-child(2n-5)').length);",
+						// TODO: uncomment when #14879 fixed
+						// function(){ doh.is(dom.byId('_foo'), query('.foo:nth-child(2)')[0]); },
+						"doh.is(query('style')[0], query(':nth-child(2)')[0]);",
+
+						// :checked pseudo-selector
+						"doh.is(2, query('#t2 > :checked').length);",
+						function(){ doh.is(dom.byId('checkbox2'), query('#t2 > input[type=checkbox]:checked')[0]); },
+						function(){ doh.is(dom.byId('radio2'), query('#t2 > input[type=radio]:checked')[0]); },
+						// This :checked selector is only defined for elements that have the checked property, option elements are not specified by the spec (http://www.w3.org/TR/css3-selectors/#checked) and not universally supported 
+						//"doh.is(2, query('#t2select option:checked').length);",
+
+						"doh.is(1, query('#radio1:disabled').length);",
+						"doh.is(0, query('#radio1:enabled').length);",
+						"doh.is(0, query('#radio2:disabled').length);",
+						"doh.is(1, query('#radio2:enabled').length);",
+
+
+						// :empty pseudo-selector
+						"doh.is(4, query('#t > span:empty').length);",
+						"doh.is(6, query('#t span:empty').length);",
+						"doh.is(0, query('h3 span:empty').length);",
+						"doh.is(1, query('h3 :not(:empty)').length);"
+					]);
+				}
+
+				// Tests for ACME specific functionality (not part of CSS3)
+				if(selector == "acme"){
+					doh.register("acme", [
+						// Case insensitive class selectors (#8775, #14874).
+						// In standards mode documents, querySelectorAll() is case-sensitive about class selectors,
+						// but acme is case-insensitive for backwards compatibility.
+						"doh.is(1, query('.fooBar').length);",
+
+						// sub-selector parsing
+						// TODO: move this test to CSS3 section when #14875 is fixed
+						"doh.is(1, query('#t span.foo:not(span:first-child)').length);",
+
+						// special characters in attribute values without backslashes.
+						// supported by acme but apparently not standard, see http://www.w3.org/TR/CSS21/syndata.html#characters
+						function attrSpecialCharsNoEscape(){
+							// bug 10651
+							doh.is(1, query('option[value=a+b]', 'attrSpecialChars').length, "value=a+b");
+							doh.is(1, query('option[value=a~b]', 'attrSpecialChars').length, "value=a~b");
+							doh.is(1, query('option[value=a^b]', 'attrSpecialChars').length, "value=a^b");
+						},
+
+						// implied * after > (non-standard syntax)
+						"doh.is(12, (query('#t >')).length);",
+						"doh.is(3, (query('.foo >')).length);",
+						"doh.is(3, query('>', 'container').length);",
+						"doh.is(0, query('> .not-there').length);",
+						"doh.is(1, (query('#foo ~')).length);",
+						"doh.is(1, (query('#foo~')).length);",
+
+						// implied * before and after + and ~ (non-standard syntax)
+						"doh.is(1, query('+', 'container').length);",
+						"doh.is(3, query('~', 'container').length);",
+
+						// check for correct document order
+						// not sure if this is guaranteed by css3, so putting in acme section
+						function domOrder() {
+							var inputs = query(".upperclass .lowerclass input");
+							doh.is("notbug", inputs[0].id);
+							doh.is("bug", inputs[1].id);
+							doh.is("checkbox1", inputs[2].id);
+							doh.is("checkbox2", inputs[3].id);
+							doh.is("radio1", inputs[4].id);
+							doh.is("radio2", inputs[5].id);
+							doh.is("radio3", inputs[6].id);
+						},
+
+						// TODO: move to css2 section after #7869 fixed for lite engine (on IE)
+						function xml_nthchild(){
+							var doc = createDocument([
+								"<ResultSet>",
+								"<result>One</result>",
+								"<result>Two</result>",
+								"<result>Three</result>",
+								"<result>Four</result>",
+								"</ResultSet>"
+							].join("")
+							);
+							var de = doc.documentElement;
+							doh.is("Four", query("result:nth-child(4)", de)[0].firstChild.data, "fourth child");
+						}
+					]);
+				}
+
+				doh.run();
+			});
+		</script>
+	</head>
+	<body class="upperclass">
+		<h1>Testing dojo/query module.</h1>
+		<p>Specify ?selector=lite/css2/css2.1/css3/acme on URL to get specific test.</p>
+		<div id="t" class="lowerclass">
+			<h3>h3 <span>span</span> endh3 </h3>
+			<!-- comment to throw things off -->
+			<div class="foo bar" id="_foo">
+				<h3>h3</h3>
+				<span id="foo"></span>
+				<span></span>
+			</div>
+			<h3>h3</h3>
+			<h3 class="baz foobar" title="thud">h3</h3>
+			<span class="fooBar baz foo"></span>
+			<span foo="bar"></span>
+			<span foo="baz bar thud"></span>
+			<!-- FIXME: should foo="bar-baz-thud" match? [foo$=thud] ??? -->
+			<span foo="bar-baz-thudish" id="silly:id::with:colons"></span>
+			<div id="container">
+				<div id="child1" qux="true"></div>
+				<div id="child2"></div>
+				<div id="child3" qux="true"></div>
+			</div>
+			<div id="silly~id" qux="true"></div>
+			<input id="notbug" name="bug" type="hidden" value="failed"> 
+			<input id="bug" type="hidden" value="passed"> 
+		</div>
+		<div id="t2" class="lowerclass">
+			<input type="checkbox" name="checkbox1" id="checkbox1" value="foo">
+			<input type="checkbox" name="checkbox2" id="checkbox2" value="bar" checked>
+
+			<input type="radio" disabled="true" name="radio" id="radio1" value="thinger">
+			<input type="radio" name="radio" id="radio2" value="stuff" checked>
+			<input type="radio" name="radio" id="radio3" value="blah">
+		</div>
+		<select id="t2select" multiple="multiple">
+			<option>0</option>
+			<option selected="selected">1</option>
+			<option selected="selected">2</option>
+		</select>
+		
+		<iframe id="t3" name="t3" src="../../resources/blank.html"></iframe>
+		<div id="t4">
+			<div id="one" class="subDiv">
+				<p class="one subP"><a class="subA">one</a></p>
+				<div id="two" class="subDiv">
+					<p class="two subP"><a class="subA">two</a></p>
+				</div>
+			</div>
+		</div>
+		<section></section>
+		<div id='other'>
+		  <div id='abc55555'></div>
+		  <div id='abd55555efg'></div>
+		  <div id='55555abc'></div>
+		  <div id='1'></div>
+		  <div id='2c'></div>
+		  <div id='3ch'></div>
+		  <div id='4chr'></div>
+		  <div id='5char'></div>
+		  <div id='6chars'></div>
+		</div>
+		
+		<div id="attrSpecialChars">
+			<select name="special">
+				<!-- tests for special characters in attribute values (characters that are part of query syntax) -->
+				<option value="a+b">1</option>
+				<option value="a~b">2</option>
+				<option value="a^b">3</option>
+				<option value="a,b">4</option>
+			</select>
+
+			<!-- tests for quotes in attribute values -->
+			<a href="foo=bar">hi</a>
+			<!-- tests for brackets in attribute values -->
+			<input name="data[foo][bar]">
+			<!-- attribute name with a dot, goes down separate code path -->
+			<input name="foo[0].bar">
+			<input name="test[0]">
+		</div>
+	</body>
+</html>
+
diff --git a/dojo/tests/query/queryQuirks.html b/dojo/tests/query/queryQuirks.html
new file mode 100644
index 0000000..8612e35
--- /dev/null
+++ b/dojo/tests/query/queryQuirks.html
@@ -0,0 +1,456 @@
+<html>
+	<head>
+		<title>testing query()</title>
+		<style type="text/css">
+			@import "../../resources/dojo.css";
+		</style>
+		<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true, async: true"></script>
+		<script type="text/javascript">
+			// Use selector specified in URL (ex: query.html?selector=lite), defaulting to acme if unspecified
+			var specified = window.location.search.substr(1).match(/selector=(.*)/);
+			var selector = specified ? specified[0].split("=")[1] : "acme";
+
+			require(["dojo", "doh", "dojo/query!"+selector, "dojo/sniff", "dojo/io/iframe", "dojo/domReady!"],
+					function(dojo, doh, dq, has){
+				query = dq; // make a global
+
+				function createDocument(xml){
+					var fauxXhr = { responseText: xml };
+					if("DOMParser" in dojo.global){
+						var parser = new DOMParser();
+						fauxXhr.responseXML = parser.parseFromString(xml, "text/xml");
+					}
+					// kludge: use dojo.xhr contentHandler for XML to process IE XMLDOC as needed
+					return dojo._contentHandlers["xml"](fauxXhr); // DOMDocument
+				}
+
+				// Tests that should work for any selector engine (lite or acme)
+				// .class, #id, tag, and star, attribute selectors, and child (>), descendant (space),and union (,)
+				// combinators. With a native selector engine, the lite engine does not support pseudo classes.
+				doh.register("css2", [
+					// basic sanity checks
+					"doh.is(4, (query('h3')).length);",
+					"doh.is(1, (query('#t')).length);",
+					"doh.is(1, (query('#bug')).length);",
+					"doh.is(4, (query('#t h3')).length);",
+					"doh.is(1, (query('div#t')).length);",
+					"doh.is(4, (query('div#t h3')).length);",
+					"doh.is(0, (query('span#t')).length);",
+					"doh.is(0, (query('.bogus')).length);",
+					"doh.is(0, (query('.bogus', dojo.byId('container'))).length);",
+					"doh.is(0, (query('#bogus')).length);",
+					"doh.is(0, (query('#bogus', dojo.byId('container'))).length);",
+					"doh.is(1, (query('#t div > h3')).length);",
+					"doh.is(2, (query('.foo')).length);",
+					"doh.is(1, (query('.foo.bar')).length);",
+					"doh.is(2, (query('.baz')).length);",
+					"doh.is(3, (query('#t > h3')).length);",
+					
+					// this fails on IE8 because qSA completely fails on unknown elements. not sure how to fix this other than completely disable qSA on IE8, which would be an unacceptable performance regression
+					//"doh.t(query.matches(query('section')[0],'section'));",
+
+					"doh.is(2, (query('#baz,#foo,#t')).length);",
+					"doh.is(0, (query(null)).length);",
+
+					//"doh.is(1, (query('#bug')).length);",
+
+					// syntactic equivalents
+					"doh.is(12, (query('#t > *')).length);",
+					"doh.is(3, (query('.foo > *')).length);",
+
+					// with a root, by ID
+					"doh.is(3, (query('> *', 'container')).length);",
+					"doh.is(3, (query('> *, > h3', 'container')).length);",
+					"doh.is(3, (query('> h3', 't')).length);",
+
+					// compound queries
+					"doh.is(2, (query('.foo, .bar')).length);",
+					"doh.is(2, (query('.foo,.bar')).length);",
+
+					// multiple class attribute
+					"doh.is(1, (query('.foo.bar')).length);",
+					"doh.is(2, (query('.foo')).length);",
+					"doh.is(2, (query('.baz')).length);",
+
+					// case sensitivity
+					"doh.is(1, (query('span.baz')).length);",
+					"doh.is(1, (query('sPaN.baz')).length);",
+					"doh.is(1, (query('SPAN.baz')).length);",
+
+					// For quirks mode, case sensitivity is browser dependent, so querying .fooBar
+					//  may return 1 or 2 entries.   See #8775 and #14874 for details.
+					// "doh.is(1, query('.fooBar').length);",
+					
+					// attribute selectors
+					"doh.is(3, (query('[foo]')).length);",
+
+					// attribute substring selectors
+					"doh.is(1, (query('[foo$=\"thud\"]')).length);",
+					"doh.is(1, (query('[foo$=thud]')).length);",
+					"doh.is(1, (query('[foo$=\"thudish\"]')).length);",
+					"doh.is(1, (query('#t [foo$=thud]')).length);",
+					"doh.is(1, (query('#t [title$=thud]')).length);",
+					"doh.is(0, (query('#t span[title$=thud ]')).length);",
+					"doh.is(1, (query('[id$=\\'55555\\']')).length);",
+					"doh.is(2, (query('[foo~=\"bar\"]')).length);",
+					"doh.is(2, (query('[ foo ~= \"bar\" ]')).length);",
+					"doh.is(2, (query('[foo|=\"bar\"]')).length);",
+					"doh.is(1, (query('[foo|=\"bar-baz\"]')).length);",
+					"doh.is(0, (query('[foo|=\"baz\"]')).length);",
+					// TODO: ^=, *=
+
+					// descendant selectors
+					"doh.is(3, query('> *', 'container').length);",
+					"doh.is(2, query('> [qux]', 'container').length);",
+					"doh.is('child1', query('> [qux]', 'container')[0].id);",
+					"doh.is('child3', query('> [qux]', 'container')[1].id);",
+					"doh.is(3, query('> *', 'container').length);",
+					"doh.is(3, query('>*', 'container').length);",
+					"doh.is('passed', query('#bug')[0].value);",
+
+					// bug 9071
+					"doh.is(2, (query('a', 't4')).length);",
+					"doh.is(2, (query('p a', 't4')).length);",
+					"doh.is(2, (query('div p', 't4')).length);",
+					"doh.is(2, (query('div p a', 't4')).length);",
+					"doh.is(2, (query('.subA', 't4')).length);",
+					"doh.is(2, (query('.subP .subA', 't4')).length);",
+					"doh.is(2, (query('.subDiv .subP', 't4')).length);",
+					"doh.is(2, (query('.subDiv .subP .subA', 't4')).length);",
+
+					// failed scope arg
+					"doh.is(0, (query('*', 'thinger')).length);",
+					"doh.is(0, (query('div#foo').length));",
+
+					// escaping special characters with quotes (http://www.w3.org/TR/CSS21/syndata.html#strings)
+					// bug 10651
+					'doh.is(1, query(\'option[value="a+b"]\', "attrSpecialChars").length);',
+					'doh.is(1, query(\'option[value="a~b"]\', "attrSpecialChars").length);',
+					'doh.is(1, query(\'option[value="a^b"]\', "attrSpecialChars").length);',
+					'doh.is(1, query(\'option[value="a,b"]\', "attrSpecialChars").length);',
+
+					// selector with substring that contains equals sign (bug 7479)
+					"doh.is(1, query(\"a[href*='foo=bar']\", 'attrSpecialChars').length);",
+
+					// selector with substring that contains brackets (bug 9193, 11189, 13084)
+					'doh.is(1, query(\'input[name="data[foo][bar]"]\', "attrSpecialChars").length);',
+					'doh.is(1, query(\'input[name="foo[0].bar"]\', "attrSpecialChars").length);',
+					'doh.is(1, query(\'input[name="test[0]"]\', "attrSpecialChars").length);',
+
+					// escaping special characters with backslashes (http://www.w3.org/TR/CSS21/syndata.html#characters)
+					// selector with substring that contains brackets (bug 9193, 11189, 13084)
+					// eval() converts 4 backslashes --> 1 by the time dojo.query() sees the string
+					'doh.is(1, query("input[name=data\\\\[foo\\\\]\\\\[bar\\\\]]", "attrSpecialChars").length);',
+					'doh.is(1, query("input[name=foo\\\\[0\\\\]\\\\.bar]", "attrSpecialChars").length);',
+
+					// cross-document queries
+					{
+						name: "crossDocumentQuery",
+						setUp: function(){
+							this.t3 = window.frames["t3"];
+							this.doc = dojo.io.iframe.doc(t3);
+							this.doc.open();
+							this.doc.write([
+								"<html><head>",
+								"<title>inner document</title>",
+								"</head>",
+								"<body>",
+								"<div id='st1'><h3>h3 <span>span <span> inner <span>inner-inner</span></span></span> endh3 </h3></div>",
+								"</body>",
+								"</html>"
+							].join(""));
+						},
+						runTest: function(){
+							doh.is(1, query('h3', dojo.byId("st1", this.doc)).length);
+							// use a long query to force a test of the XPath system on FF. see bug #7075
+							doh.is(1, query('h3 > span > span > span', dojo.byId("st1", this.doc)).length);
+							doh.is(1, query('h3 > span > span > span', this.doc.body.firstChild).length);
+						}
+					},
+
+					// escaping of ":" chars inside an ID
+					function silly_IDs1(){
+						doh.t(document.getElementById("silly:id::with:colons"), "getElementById");
+						doh.is(1, query("#silly\\:id\\:\\:with\\:colons").length, "query(\"#silly\\:id\\:\\:with\\:colons\")");
+						doh.is(1, query("#silly\\~id").length, "query(\"#silly\\~id\")");
+					},
+					function NodeList_identity(){
+						var foo = new dojo.NodeList([dojo.byId("container")]);
+						doh.is(foo, query(foo));
+					},
+					function xml(){
+						var doc = createDocument([
+							"<ResultSet>",
+							"<Result>One</Result>",
+							"<RESULT>Two</RESULT>",
+							"<result><nested>Three</nested></result>",
+							"<result>Four</result>",
+							"</ResultSet>"
+						].join("")
+						);
+						var de = doc.documentElement;
+
+						doh.is(2, query("result", de).length, "all lower");
+
+						//doh.is(1, query("result>nested", de).length, "nested XML");
+						doh.is(1, query("Result", de).length, "mixed case");
+						doh.is(1, query("RESULT", de).length, "all upper");
+						doh.is(0, query("resulT", de).length, "no match");
+						doh.is(0, query("rEsulT", de).length, "no match");
+					},
+					function xml_attrs(){
+						if(!has("ie")){	// remove if() when #14880 is fixed
+							var doc = createDocument([
+								"<ResultSet>",
+								"<RESULT thinger='blah'>ONE</RESULT>",
+								"<RESULT thinger='gadzooks'><CHILD>Two</CHILD></RESULT>",
+								"</ResultSet>"
+							].join(""));
+							var de = doc.documentElement;
+
+							doh.is(2, query("RESULT", de).length, "result elements");
+							doh.is(0, query("RESULT[THINGER]", de).length, "result elements with attrs (wrong)");
+							doh.is(2, query("RESULT[thinger]", de).length, "result elements with attrs");
+							doh.is(1, query("RESULT[thinger=blah]", de).length, "result elements with attr value");
+							doh.is(1, query("RESULT > CHILD", de).length, "Using child operator");
+						} // remove when #14880 is fixed
+					},
+					function sort(){
+						var i = query("div");
+						// smoke test
+						i.sort(function(a,b){ return 1; })
+					}
+				]);
+
+				// Tests for CSS2.1+, and also CSS2 pseudo selectors (which aren't supported by selector=css2 or
+				// selector=lite)
+				if(/css2.1|css3|acme/.test(selector)){
+					doh.register("css2.1", [
+						// first-child
+						"doh.is(1, (query('h1:first-child')).length);",
+						"doh.is(2, (query('h3:first-child')).length);",
+
+						// + sibling selector
+						"doh.is(1, (query('.foo+ span')).length);",
+						"doh.is(1, (query('.foo+span')).length);",
+						"doh.is(1, (query('.foo +span')).length);",
+						"doh.is(1, (query('.foo + span')).length);"
+					]);
+				}
+
+				// Tests for CSS3+
+				if(/css3|acme/.test(selector)){
+					doh.register("css3", [
+						// sub-selector parsing
+						"doh.is(1, query('#t span.foo:not(:first-child)').length);",
+
+						// ~ sibling selector
+						"doh.is(4, (query('.foo~ span')).length);",
+						"doh.is(4, (query('.foo~span')).length);",
+						"doh.is(4, (query('.foo ~span')).length);",
+						"doh.is(4, (query('.foo ~ span')).length);",
+						"doh.is(1, (query('#foo~ *')).length);",
+						"doh.is(1, (query('#foo ~*')).length);",
+						"doh.is(1, (query('#foo ~*')).length);",
+						"doh.is(1, (query('#foo ~ *')).length);",
+						// "t.is(0, (query('[ foo ~= \"\\'bar\\'\" ]')).length);",
+
+						// nth-child tests
+						"doh.is(2, query('#t > h3:nth-child(odd)').length);",
+						"doh.is(3, query('#t h3:nth-child(odd)').length);",
+						"doh.is(3, query('#t h3:nth-child(2n+1)').length);",
+						"doh.is(1, query('#t h3:nth-child(even)').length);",
+						"doh.is(1, query('#t h3:nth-child(2n)').length);",
+						"doh.is(1, query('#t h3:nth-child(2n+3)').length);",
+						"doh.is(2, query('#t h3:nth-child(1)').length);",
+						"doh.is(1, query('#t > h3:nth-child(1)').length);",
+						"doh.is(3, query('#t :nth-child(3)').length);",
+						"doh.is(0, query('#t > div:nth-child(1)').length);",
+						"doh.is(7, query('#t span').length);",
+						"doh.is(3, query('#t > *:nth-child(n+10)').length);",
+						"doh.is(1, query('#t > *:nth-child(n+12)').length);",
+						"doh.is(10, query('#t > *:nth-child(-n+10)').length);",
+						"doh.is(5, query('#t > *:nth-child(-2n+10)').length);",
+						"doh.is(6, query('#t > *:nth-child(2n+2)').length);",
+						"doh.is(5, query('#t > *:nth-child(2n+4)').length);",
+						"doh.is(5, query('#t > *:nth-child(2n+4)').length);",
+						"doh.is(5, query('#t> *:nth-child(2n+4)').length);",
+						// TODO: uncomment these two tests when #14879 fixed
+						//"doh.is(12, query('#t > *:nth-child(n-5)').length);",
+						//"doh.is(12, query('#t >*:nth-child(n-5)').length);",
+						"doh.is(6, query('#t > *:nth-child(2n-5)').length);",
+						"doh.is(6, query('#t>*:nth-child(2n-5)').length);",
+						// TODO: uncomment when #14879 fixed
+						// "doh.is(dojo.byId('_foo'), query('.foo:nth-child(2)')[0]);",
+						"doh.is(query('style')[0], query(':nth-child(2)')[0]);",
+
+						// :checked pseudo-selector
+						"doh.is(2, query('#t2 > :checked').length);",
+						"doh.is(dojo.byId('checkbox2'), query('#t2 > input[type=checkbox]:checked')[0]);",
+						"doh.is(dojo.byId('radio2'), query('#t2 > input[type=radio]:checked')[0]);",
+						// This :checked selector is only defined for elements that have the checked property, option elements are not specified by the spec (http://www.w3.org/TR/css3-selectors/#checked) and not universally supported 
+						//"doh.is(2, query('#t2select option:checked').length);",
+
+						"doh.is(1, query('#radio1:disabled').length);",
+						"doh.is(0, query('#radio1:enabled').length);",
+						"doh.is(0, query('#radio2:disabled').length);",
+						"doh.is(1, query('#radio2:enabled').length);",
+
+
+						// :empty pseudo-selector
+						"doh.is(4, query('#t > span:empty').length);",
+						"doh.is(6, query('#t span:empty').length);",
+						"doh.is(0, query('h3 span:empty').length);",
+						"doh.is(1, query('h3 :not(:empty)').length);"
+					]);
+				}
+
+				// Tests for ACME specific functionality (not part of CSS3)
+				if(selector == "acme"){
+					doh.register("acme", [
+						// Case insensitive class selectors (#8775, #14874).
+						// Acme is case-insensitive for backwards compatibility.
+						"doh.is(1, query('.fooBar').length);",
+
+						// sub-selector parsing
+						// TODO: move this test to CSS3 section when #14875 is fixed
+						"doh.is(1, query('#t span.foo:not(span:first-child)').length);",
+
+						// special characters in attribute values without backslashes.
+						// supported by acme but apparently not standard, see http://www.w3.org/TR/CSS21/syndata.html#characters
+						function attrSpecialCharsNoEscape(){
+							// bug 10651
+							doh.is(1, query('option[value=a+b]', 'attrSpecialChars').length, "value=a+b");
+							doh.is(1, query('option[value=a~b]', 'attrSpecialChars').length, "value=a~b");
+							doh.is(1, query('option[value=a^b]', 'attrSpecialChars').length, "value=a^b");
+						},
+
+						// implied * after > (non-standard syntax)
+						"doh.is(12, (query('#t >')).length);",
+						"doh.is(3, (query('.foo >')).length);",
+						"doh.is(3, query('>', 'container').length);",
+						"doh.is(0, query('> .not-there').length);",
+						"doh.is(1, (query('#foo ~')).length);",
+						"doh.is(1, (query('#foo~')).length);",
+
+						// implied * before and after + and ~ (non-standard syntax)
+						"doh.is(1, query('+', 'container').length);",
+						"doh.is(3, query('~', 'container').length);",
+
+						// check for correct document order
+						// not sure if this is guaranteed by css3, so putting in acme section
+						function domOrder() {
+							var inputs = query(".upperclass .lowerclass input");
+							doh.is("notbug", inputs[0].id);
+							doh.is("bug", inputs[1].id);
+							doh.is("checkbox1", inputs[2].id);
+							doh.is("checkbox2", inputs[3].id);
+							doh.is("radio1", inputs[4].id);
+							doh.is("radio2", inputs[5].id);
+							doh.is("radio3", inputs[6].id);
+						},
+
+						// TODO: move to css2 section after #7869 fixed for lite engine (on IE)
+						function xml_nthchild(){
+							var doc = createDocument([
+								"<ResultSet>",
+								"<result>One</result>",
+								"<result>Two</result>",
+								"<result>Three</result>",
+								"<result>Four</result>",
+								"</ResultSet>"
+							].join("")
+							);
+							var de = doc.documentElement;
+							doh.is("Four", query("result:nth-child(4)", de)[0].firstChild.data, "fourth child");
+						}
+					]);
+				}
+
+				doh.run();
+			});
+		</script>
+	</head>
+	<body class="upperclass">
+		<h1>Testing dojo/query module.</h1>
+		<p>Specify ?selector=lite/css2/css2.1/css3/acme on URL to get specific test.</p>
+		<div id="t" class="lowerclass">
+			<h3>h3 <span>span</span> endh3 </h3>
+			<!-- comment to throw things off -->
+			<div class="foo bar" id="_foo">
+				<h3>h3</h3>
+				<span id="foo"></span>
+				<span></span>
+			</div>
+			<h3>h3</h3>
+			<h3 class="baz foobar" title="thud">h3</h3>
+			<span class="fooBar baz foo"></span>
+			<span foo="bar"></span>
+			<span foo="baz bar thud"></span>
+			<!-- FIXME: should foo="bar-baz-thud" match? [foo$=thud] ??? -->
+			<span foo="bar-baz-thudish" id="silly:id::with:colons"></span>
+			<div id="container">
+				<div id="child1" qux="true"></div>
+				<div id="child2"></div>
+				<div id="child3" qux="true"></div>
+			</div>
+			<div id="silly~id" qux="true"></div>
+			<input id="notbug" name="bug" type="hidden" value="failed"> 
+			<input id="bug" type="hidden" value="passed"> 
+		</div>
+		<div id="t2" class="lowerclass">
+			<input type="checkbox" name="checkbox1" id="checkbox1" value="foo">
+			<input type="checkbox" name="checkbox2" id="checkbox2" value="bar" checked>
+
+			<input type="radio" disabled="true" name="radio" id="radio1" value="thinger">
+			<input type="radio" name="radio" id="radio2" value="stuff" checked>
+			<input type="radio" name="radio" id="radio3" value="blah">
+		</div>
+		<select id="t2select" multiple="multiple">
+			<option>0</option>
+			<option selected="selected">1</option>
+			<option selected="selected">2</option>
+		</select>
+		
+		<iframe id="t3" name="t3" src="../../resources/blank.html"></iframe>
+		<div id="t4">
+			<div id="one" class="subDiv">
+				<p class="one subP"><a class="subA">one</a></p>
+				<div id="two" class="subDiv">
+					<p class="two subP"><a class="subA">two</a></p>
+				</div>
+			</div>
+		</div>
+		<section></section>
+		<div id='other'>
+		  <div id='abc55555'></div>
+		  <div id='abd55555efg'></div>
+		  <div id='55555abc'></div>
+		  <div id='1'></div>
+		  <div id='2c'></div>
+		  <div id='3ch'></div>
+		  <div id='4chr'></div>
+		  <div id='5char'></div>
+		  <div id='6chars'></div>
+		</div>
+		
+		<div id="attrSpecialChars">
+			<select name="special">
+				<!-- tests for special characters in attribute values (characters that are part of query syntax) -->
+				<option value="a+b">1</option>
+				<option value="a~b">2</option>
+				<option value="a^b">3</option>
+				<option value="a,b">4</option>
+			</select>
+
+			<!-- tests for quotes in attribute values -->
+			<a href="foo=bar">hi</a>
+			<!-- tests for brackets in attribute values -->
+			<input name="data[foo][bar]">
+			<!-- attribute name with a dot, goes down separate code path -->
+			<input name="foo[0].bar">
+			<input name="test[0]">
+		</div>
+	</body>
+</html>
+
diff --git a/dojo/tests/query/runTests.html b/dojo/tests/query/runTests.html
new file mode 100644
index 0000000..1116e1f
--- /dev/null
+++ b/dojo/tests/query/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+    <head>
+    <title>dojo.data D.O.H. Unit Test Runner</title>
+    <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojo.tests.query"></HEAD>
+    <BODY>
+        Redirecting to D.O.H runner.
+    </BODY>
+</HTML>
diff --git a/dojo/tests/query/xml.xhtml b/dojo/tests/query/xml.xhtml
new file mode 100644
index 0000000..1180284
--- /dev/null
+++ b/dojo/tests/query/xml.xhtml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
+<head>
+	<title>Test dojo.query() on XHTML/XML doc</title>
+	<script type="text/javascript" src="../../dojo.js"></script>
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.ready(function(){
+			doh.register(function(){
+				doh.is(1, dojo.query("p#test").length, "matched nodes");
+			});
+			doh.run();
+		});
+	</script>
+</head>
+<body>
+	<p id="test"></p>
+</body>
+</html>
\ No newline at end of file
diff --git a/dojo/tests/regexp.js b/dojo/tests/regexp.js
index 1b7d793..e0428b7 100644
--- a/dojo/tests/regexp.js
+++ b/dojo/tests/regexp.js
@@ -1,9 +1,9 @@
-define(["../main", "doh", "../regexp"], function(dojo, doh){
+define(["doh/main", "../regexp"], function(doh, regexp){
 
 doh.register("tests.regexp",
 		function test_regexp_escape(t){
-			t.assertTrue(new RegExp(dojo.regexp.escapeString("\f\b\n\t\r+.$?*|{}()[]\\/^")).test("TEST\f\b\n\t\r+.$?*|{}()[]\\/^TEST"));
-			t.assertTrue(new RegExp(dojo.regexp.escapeString("\f\b\n\t\r+.$?*|{}()[]\\/^", ".")).test("TEST\f\b\n\t\r+X$?*|{}()[]\\/^TEST"));
+			t.assertTrue(new RegExp(regexp.escapeString("\f\b\n\t\r+.$?*|{}()[]\\/^")).test("TEST\f\b\n\t\r+.$?*|{}()[]\\/^TEST"));
+			t.assertTrue(new RegExp(regexp.escapeString("\f\b\n\t\r+.$?*|{}()[]\\/^", ".")).test("TEST\f\b\n\t\r+X$?*|{}()[]\\/^TEST"));
 		}
 );
 
diff --git a/dojo/tests/request.js b/dojo/tests/request.js
new file mode 100644
index 0000000..8debc02
--- /dev/null
+++ b/dojo/tests/request.js
@@ -0,0 +1,14 @@
+define([
+	"require",
+	"doh/main",
+	"./request/handlers",
+	"../has!host-node?./request/node"
+], function(require, doh){
+	if(doh.isBrowser){
+		doh.register("tests.request.xhr", require.toUrl("./request/xhr.html"), 60000);
+		doh.register("tests.request.script", require.toUrl("./request/script.html"), 60000);
+		doh.register("tests.request.iframe", require.toUrl("./request/iframe.html"), 60000);
+		doh.register("tests.request.registry", require.toUrl("./request/registry.html"), 60000);
+		doh.register("tests.request.notify", require.toUrl("./request/notify.html"), 60000);
+	}
+});
diff --git a/dojo/tests/request/handlers.js b/dojo/tests/request/handlers.js
new file mode 100644
index 0000000..eca3686
--- /dev/null
+++ b/dojo/tests/request/handlers.js
@@ -0,0 +1,87 @@
+define([
+	"doh/main",
+	"dojo/request/handlers",
+	"dojo/has",
+	"dojo/_base/kernel",
+	"dojo/json"
+], function(doh, handlers, has, kernel, JSON){
+	var tests = [
+		function textContentHandler(t){
+			var response = handlers({
+				text: "foo bar baz ",
+				options: {}
+			});
+
+			t.is("foo bar baz ", response.data);
+		},
+		function jsonContentHandler(t){
+			var jsonObj = {
+				foo: "bar",
+				baz: [
+					{ thonk: "blarg" },
+					"xyzzy!"
+				]
+			};
+			var responseData = handlers({
+				text: JSON.stringify(jsonObj),
+				options: {
+					handleAs: "json"
+				}
+			});
+			t.is(jsonObj, responseData.data);
+		},
+		function jsContentHandler(t){
+			var jsonObj = {
+				foo: "bar",
+				baz: [
+					{ thonk: "blarg" },
+					"xyzzy!"
+				]
+			};
+			var responseData = handlers({
+				text: "("+JSON.stringify(jsonObj)+")",
+				options: {
+					handleAs: "javascript"
+				}
+			});
+			t.is(jsonObj, responseData.data);
+
+			responseData = handlers({
+				text: "true;",
+				options: {
+					handleAs: "javascript"
+				}
+			});
+			t.t(responseData.data);
+
+			responseData = handlers({
+				text: "false;",
+				options: {
+					handleAs: "javascript"
+				}
+			});
+			t.f(responseData.data);
+		}
+	];
+
+	if(has("host-browser")){
+		tests.push(
+			function xmlContentHandler(t){
+				var responseData = {
+					text: "<foo><bar baz='thonk'>blarg</bar></foo>",
+					options: {
+						handleAs: "xml"
+					}
+				};
+				if("DOMParser" in kernel.global){
+					var parser = new DOMParser();
+					responseData.data = parser.parseFromString(responseData.text, "text/xml");
+				}
+
+				responseData = handlers(responseData);
+				t.is("foo", responseData.data.documentElement.tagName);
+			}
+		);
+	}
+	doh.register("tests.request.handlers", tests);
+});
diff --git a/dojo/tests/request/iframe.html b/dojo/tests/request/iframe.html
new file mode 100644
index 0000000..b23cc61
--- /dev/null
+++ b/dojo/tests/request/iframe.html
@@ -0,0 +1,205 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Testing dojo/request/iframe</title>
+		<style type="text/css">
+			@import "../../resources/dojo.css";
+		</style>
+		<script>
+			var dojoConfig = {
+				async: true
+			};
+		</script>
+		<script type="text/javascript" src="../../dojo.js"></script>
+		<script type="text/javascript">
+			require(["doh", "dojo/request/iframe", "dojo/_base/lang", "dojo/dom", "dojo/domReady!"], function(doh, iframe, lang, dom){
+				doh.register("dojo/request/iframe", [
+					function ioIframeGetText(t){
+						var d = new doh.Deferred();
+						var td = iframe.get("iframeDummyMethod.php?type=text", {
+							preventCache: true
+						});
+						td.then(d.getTestErrback(function(data){
+							t.is("iframe succeeded", data);
+
+							return td.response.then(d.getTestCallback(function(response){
+								t.is("iframe succeeded", response.data);
+							}));
+						}));
+						return d;
+					},
+
+					function ioIframePostJson(t){
+						var d = new doh.Deferred();
+						var td = iframe.post("iframeDummyMethod.php?type=json", {
+							preventCache: true,
+							form: "contentArrayTest",
+							data: {
+								color: "blue"
+							},
+							handleAs: "json"
+						});
+						td.then(d.getTestCallback(function(data){
+							t.is("json", data.query.type);
+							t.is("blue", data.post.color);
+							t.is("42", data.post.size);
+						}));
+						return d;
+					},
+
+					function ioIframePostWithoutForm(t){
+						var d = new doh.Deferred();
+						var td = iframe.post("iframeDummyMethod.php?type=json", {
+							preventCache: true,
+							data: {
+								color: "blue"
+							},
+							handleAs: "json"
+						});
+						td.then(d.getTestCallback(function(data){
+							t.is("json", data.query.type);
+							t.is("blue", data.post.color);
+						}));
+						return d;
+					},
+
+					function ioIframeGetJson(t){
+						var d = new doh.Deferred();
+						var td = iframe.get("iframeDummyMethod.php?type=json", {
+							preventCache: true,
+							data: {
+								color: "blue"
+							},
+							handleAs: "json"
+						});
+						td.then(d.getTestCallback(function(data){
+							t.is("json", data.query.type);
+							t.is("blue", data.query.color);
+						}));
+						return d;
+					},
+
+					function ioIframeGetWithForm(t){
+						var d = new doh.Deferred();
+						var td = iframe.get("iframeDummyMethod.php?type=json", {
+							preventCache: true,
+							form: "contentArrayTest",
+							data: {
+								color: "blue"
+							},
+							handleAs: "json"
+						});
+						td.then(d.getTestCallback(function(data){
+							t.is("json", data.query.type);
+							t.is("blue", data.query.color);
+							t.is("42", data.query.size);
+						}));
+						return d;
+					},
+
+					function ioIframeGetJavascript(t){
+						var d = new doh.Deferred();
+						var td = iframe.get("iframeDummyMethod.php?type=javascript", {
+							preventCache: true,
+							handleAs: "javascript"
+						});
+						td.then(d.getTestCallback(function(){
+							t.is(42, window.iframeTestingFunction());
+						}));
+						return d;
+					},
+
+					function ioIframeGetHtml(t){
+						var d = new doh.Deferred();
+						var td = iframe.get("iframeDummyMethod.php?type=html", {
+							preventCache: true,
+							handleAs: "html"
+						});
+						td.then(d.getTestCallback(function(data){
+							t.is("SUCCESSFUL HTML response",
+								data.getElementsByTagName("h1")[0].innerHTML);
+						}));
+						return d;
+					},
+
+					function ioIframeGetXml(t){
+						var d = new doh.Deferred();
+						var td = iframe.get("iframeDummyMethod.php?type=xml", {
+							preventCache: true,
+							handleAs: "xml"
+						});
+						td.then(d.getTestCallback(function(data){
+							t.is(4, data.documentElement.getElementsByTagName("child").length);
+						}), lang.hitch(d, "errback"));
+						return d;
+					},
+					function ioIframeDataArray(t){
+						//Tests if an array passed in content causes as an error on cleanup.
+						var d = new doh.Deferred();
+						var td = iframe.post("iframeDummyMethod.php?type=json", {
+							form: "contentArrayTest",
+							data: {"tag": ["value1","value2"]},
+							handleAs: "json"
+						});
+						td.then(d.getTestCallback(function(data){
+							t.is("json", data.query.type);
+							t.is("value2", data.post.tag);
+							t.is("42", data.post.size);
+
+							/* Test to make sure the form still exists and it hasn't moved */
+							var form = dom.byId("contentArrayTest");
+							t.t(form);
+							t.isNot("absolute", dom.byId("contentArrayTest").style.position);
+						}));
+						return d;
+					},
+					{
+						name: "iframeQueue",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							iframe.get("iframeDummyMethod.php",{
+								query: {
+									type: "text",
+									delay: 2,
+									text: "one"
+								}
+							}).then(d.getTestErrback(function(data){
+								t.is("one", data);
+							}));
+							iframe.get("iframeDummyMethod.php",{
+								query: {
+									type: "text",
+									text: "two"
+								}
+							}).then(d.getTestErrback(function(data){
+								t.is("two", data);
+							}));
+							iframe.get("iframeDummyMethod.php",{
+								query: {
+									type: "text",
+									text: "three"
+								}
+							}).then(d.getTestCallback(function(data){
+								t.is("three", data);
+							}));
+
+							t.is(3, iframe._dfdQueue.length);
+
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+
+		</script>
+	</head>
+	<body>
+		<form id="contentArrayTest" method="get" enctype="multipart/form-data">
+			<input type="hidden" name="size" value="42"/>
+		</form>
+	</body>
+</html>
diff --git a/dojo/tests/request/iframeDummyMethod.php b/dojo/tests/request/iframeDummyMethod.php
new file mode 100644
index 0000000..21f566a
--- /dev/null
+++ b/dojo/tests/request/iframeDummyMethod.php
@@ -0,0 +1,109 @@
+<?php
+function fix_raw_data($data){
+	$arr = array();
+	$pairs = explode('&', $data);
+
+	foreach ($pairs as $i) {
+		if (!empty($i)) {
+			list($name, $value) = explode('=', $i, 2);
+
+			if (isset($arr[$name])) {
+				if (is_array($arr[$name])) {
+					$arr[$name][] = $value;
+				} else {
+					$arr[$name] = array($arr[$name], $value);
+				}
+			} else {
+				$arr[$name] = $value;
+			}
+		}
+	}
+
+	return $arr;
+}
+
+function outputType($type, $q, $p){
+	if($type == 'json'){
+		$result = array(
+			"method" => $_SERVER['REQUEST_METHOD'],
+			"query" => $q,
+			"post" => $p
+		);
+		echo json_encode($result);
+	}else if($type == 'javascript'){
+		echo "window.iframeTestingFunction = function(){ return 42; };";
+	}else if(array_key_exists('text', $q)){
+		echo $q['text'];
+	}else{
+		echo "iframe succeeded";
+	}
+}
+
+$query = null;
+if (!empty($_SERVER['QUERY_STRING'])) {
+	$query = fix_raw_data($_SERVER['QUERY_STRING']);
+}
+
+$post = null;
+if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+	$post = file_get_contents('php://input');
+	if(empty($post)){
+		$post = $_POST;
+	}else{
+		$post = fix_raw_data($post);
+	}
+}
+
+if((!empty($query) && array_key_exists('delay', $query))){
+	sleep((int)$query['delay']);
+}else if((!empty($post) && array_key_exists('delay', $post))){
+	sleep((int)$post['delay']);
+}
+
+header("HTTP/1.1 200 OK");
+header("Expires: " . gmdate("D, d M Y H:i:s") . "GMT");
+header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+header("Cache-Control: no-cache, must-revalidate");
+header("Pragma: no-cache");
+
+if($query['type'] == 'xml'){
+	header("Content-type: text/xml");
+	echo '<?xml version="1.0" encoding="UTF-8"?>';
+?>
+<Envelope title="Test of dojo.io.iframe xml test">
+	<Children>
+		<child>FOO</child>
+		<child>BAR</child>
+		<child>BAZ</child>
+		<child>BAT</child>
+	</Children>
+	<![CDATA[
+		function(){
+			for(var i=0; i<somethign; i++){
+				if(foo>bar){ /* whatever */ }
+			}
+		}
+	]]>
+	<a href="something">something else</a>
+</Envelope>
+<?php
+}else{
+	header("Content-type: text/html");
+?>
+<html>
+	<head></head>
+	<body>
+<?php
+	if($query['type'] == 'html'){
+?>
+		<h1>SUCCESSFUL HTML response</h1>
+<?php
+	}else{
+?>
+		<textarea style="width: 100%; height: 100px;"><?php outputType($query['type'], $query, $post); ?></textarea>
+	</body>
+</html>
+<?php
+	}
+}
+?>
diff --git a/dojo/tests/request/node.js b/dojo/tests/request/node.js
new file mode 100644
index 0000000..be45938
--- /dev/null
+++ b/dojo/tests/request/node.js
@@ -0,0 +1,78 @@
+require([
+	'require',
+	'doh/main',
+	'dojo/request',
+	'dojo/node!http',
+	'dojo/node!url',
+	'dojo/Deferred'
+], function(require, doh, request, http, url, Deferred){
+	var serverPort = 8142,
+		serverUrl = 'http://localhost:8124';
+
+	var responseDataMap = {
+		'fooBar': '{ "foo": "bar" }',
+		'invalidJson': '<not>JSON</not>'
+	};
+	function getRequestUrl(dataKey){
+		return serverUrl + '?dataKey=' + dataKey;
+	}
+	function getResponseData(request){
+		var parseQueryString = true;
+		var urlInfo = url.parse(request.url, parseQueryString);
+		return responseDataMap[urlInfo.query.dataKey];
+	}
+
+	var server = http.createServer(function(request, response){
+		var body = getResponseData(request);
+
+		response.writeHead(200, {
+			'Content-Length': body.length,
+			'Content-Type': 'application/json'
+		});
+		response.write(body);
+		response.end();
+	});
+
+	function setUp(){ /* Do nothing */ }
+	function tearDown(){ server.close(); }
+	server.on('listening', function(){
+		var tests = [
+			{
+				name: 'test',
+				runTest: function(t){
+					var d = new doh.Deferred();
+
+					request.get(getRequestUrl('fooBar'), {
+						handleAs: 'json'
+					}).then(d.getTestCallback(function(data){
+						t.is({ foo: 'bar' }, data);
+					}), function(err){
+						d.errback(err);
+					});
+
+					return d;
+				}
+			},
+			{
+				name: 'test-handler-exception',
+				runTest: function(t){
+					var d = new doh.Deferred();
+
+					request.get(getRequestUrl('invalidJson'), {
+						handleAs: 'json'
+					}).then(function(){
+						d.errback(new Error('Expected a handler exception.'));
+					}, d.getTestCallback(function(err){
+						doh.assertTrue(err instanceof SyntaxError);
+					}));
+
+					return d;
+				}
+			}
+		];
+
+		doh.register('tests.request.node', tests, setUp, tearDown);
+		doh.run();
+	});
+	server.listen(8124);
+});
diff --git a/dojo/tests/request/notify.html b/dojo/tests/request/notify.html
new file mode 100644
index 0000000..dca94bf
--- /dev/null
+++ b/dojo/tests/request/notify.html
@@ -0,0 +1,191 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta charset="utf-8">
+	<title>dojo/request/notify test</title>
+	<style>
+		@import "../../resources/dojo.css";
+	</style>
+	<script>
+		var dojoConfig = {
+			async: true
+		};
+	</script>
+	<script src="../../dojo.js"></script>
+	<script>
+		require([
+			"doh",
+			"dojo/request/xhr",
+			"dojo/request/notify",
+            "dojo/errors/CancelError",
+			"dojo/_base/lang",
+			"dojo/domReady!"
+		], function(doh, xhr, notify, CancelError, lang){
+			function resCounter(count, callback){
+				var resCount = 0;
+
+				return function(){
+					if(++resCount == count){
+						callback.apply(this, arguments);
+					}
+				};
+			}
+
+			function remover(){
+				var args = arguments;
+				return function(){
+					var i = args.length;
+					while(i--){
+						args[i].remove();
+					}
+				};
+			}
+
+			doh.register("dojo/request/notify", [{
+				name: "start/send",
+				timeout: 5000,
+				runTest: function(t){
+					var d = new doh.Deferred();
+
+					var startCount = 0,
+						sendCount = 0;
+
+					t.remove = remover(
+						notify('start', function(data){
+							startCount++;
+						}),
+						notify('send', function(data){
+							sendCount++;
+						})
+					);
+
+					var counter = resCounter(2, d.getTestCallback(function(){
+						t.is(1, startCount, "'start' should have fired once");
+						t.is(2, sendCount, "'send' should have fired twice");
+					}));
+					xhr.get("xhrDummyMethod.php?delay=1").then(counter);
+					xhr.get("xhrDummyMethod.php?delay=1").then(counter);
+
+					return d;
+				},
+				tearDown: function(t){
+					t.remove();
+				}
+			},{
+				name: "load",
+				runTest: function(t){
+					var d = new doh.Deferred();
+
+					var doneFired = 0;
+					t.remove = remover(
+						notify('done', function(response){
+							doneFired = 1;
+						}),
+						notify('load', d.getTestErrback(function(response){
+							t.is({ foo: "bar" }, response.data.query);
+							t.f(doneFired, "'load' should have fired before 'done'");
+						})),
+						notify('stop', d.getTestCallback(function(){}))
+					);
+
+					xhr.get("xhrDummyMethod.php?foo=bar", { handleAs: "json" });
+
+					return d;
+				},
+				tearDown: function(t){
+					t.remove();
+				}
+			},{
+				name: "error",
+				runTest: function(t){
+					var d = new doh.Deferred();
+
+					var doneFired = 0;
+					t.remove = remover(
+						notify('done', d.getTestErrback(function(data){
+							doneFired = 1;
+							t.t(data instanceof Error);
+						})),
+						notify('error', d.getTestErrback(function(data){
+							t.t(data instanceof Error);
+							t.f(doneFired, "'error' should have fired before 'done'");
+						})),
+						notify("stop", d.getTestCallback(function(){}))
+					);
+
+					xhr.get("doesntExist.text");
+
+					return d;
+				},
+				tearDown: function(t){
+					t.remove();
+				}
+			},{
+				name: "done/stop",
+				timeout: 5000,
+				runTest: function(t){
+					var d = new doh.Deferred();
+
+					var doneCount = 0,
+						stopCount = 0,
+						stopCalled = 0;
+
+					t.remove = remover(
+						notify("done", function(data){
+							doneCount++;
+							stopCalled = stopCount;
+						}),
+						notify("stop", function(data){
+							stopCount++;
+						})
+					);
+
+					var counter = resCounter(2, d.getTestCallback(function(){
+						t.f(stopCalled, "'done' should have fired before 'stop'");
+						t.is(2, doneCount, "'done' should have fired twice");
+						t.is(1, stopCount, "'stop' should have fired once");
+					}));
+
+					xhr.get("xhrDummyMethod.php?delay=1").then(counter);
+					xhr.get("xhrDummyMethod.php?delay=1").then(counter);
+
+					return d;
+				},
+				tearDown: function(t){
+					t.remove();
+				}
+            },{
+                name: "cancel",
+                timeout: 5000,
+                runTest: function(t){
+                    var d = new doh.Deferred();
+
+                    t.remove = remover(
+                        notify("send", function(response, cancel){
+                            cancel();
+                        })
+                    );
+
+                    xhr.get("xhrDummyMethod.php").then(
+                        function(response){
+                            d.errback(1);
+                        },
+                        d.getTestCallback(function(error){
+                            t.t(error instanceof CancelError);
+                        })
+                    );
+
+                    return d;
+                },
+                tearDown: function(t){
+                    t.remove();
+                }
+            }]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/request/registry.html b/dojo/tests/request/registry.html
new file mode 100644
index 0000000..f83c43b
--- /dev/null
+++ b/dojo/tests/request/registry.html
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML>
+<html lang="en">
+<head>
+	<meta charset="utf-8">
+	<title>Registry Test</title>
+
+	<script>
+		var dojoConfig = {
+			async: true,
+			requestProvider: 'dojo/request/registry'
+		};
+	</script>
+	<script src="../../dojo.js"></script>
+	<script>
+		require([
+			"doh",
+			"dojo/request",
+			"dojo/request/registry",
+			"dojo/request/script",
+			"dojo/domReady!"
+		], function(doh, request, registry, script){
+			doh.register("dojo/request/registry", [
+				function requestEqualsRegistry(t){
+					t.is(registry, request, "request should be the registry function");
+				},
+				{
+					name: "RegExp registration works",
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						var h = request.register(/^foo/, d.getTestCallback(function(url, options){
+							t.t(/^foo/.test(url), "URL should begin with 'foo'");
+							h.remove();
+						}));
+
+						request.get('foobar');
+
+						return d;
+					}
+				},
+				{
+					name: "Function registration works",
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						var h = request.register(function(url, options){
+							return options.method == 'POST';
+						}, d.getTestCallback(function(url, options){
+							t.is('POST', options.method, "Method should be 'POST'");
+							h.remove();
+						}));
+
+						request.post('foobar');
+
+						return d;
+					}
+				},
+				{
+					name: "String registration works",
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						var h = request.register("foobar", d.getTestCallback(function(url, options){
+							t.is('foobar', url, "URL should be 'foobar'");
+							h.remove();
+						}));
+
+						request.get('foobar');
+
+						return d;
+					}
+				},
+				{
+					name: "Fallback works",
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						var h = t.handle = request.register("foobar", function(url, options){});
+
+						request.get("registry.html").then(d.getTestCallback(function(){
+							delete t.handle;
+							h.remove();
+						}));
+
+						return d;
+					},
+					tearDown: function(t){
+						if(t.handle){
+							t.handle.remove();
+						}
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojo/tests/request/script.html b/dojo/tests/request/script.html
new file mode 100644
index 0000000..68e3459
--- /dev/null
+++ b/dojo/tests/request/script.html
@@ -0,0 +1,92 @@
+<html>
+	<head>
+		<title>dojo/request/script</title>
+		<style type="text/css">
+			@import "../../resources/dojo.css";
+		</style>
+		<script>
+			var dojoConfig = {
+				async: true
+			};
+		</script>
+		<script type="text/javascript" src="../../dojo.js"></script>
+		<script type="text/javascript">
+			var request, fr;
+			require(["dojo/request/script", "dojo/errors/RequestTimeoutError", "dojo/errors/CancelError", "doh", "dojo/_base/window", "dojo/domReady!"], function(script, RequestTimeoutError, CancelError, doh, win){
+				doh.register("dojo/request/script", [
+					function load(t){
+						//t.is("undefined", typeof(scriptLoad));
+						var d = new doh.Deferred();
+						var td = script.get("scriptDummyMethod.php", {
+							query: {
+								scriptVar: "scriptLoad"
+							}
+						}).then(d.getTestCallback(function(data){
+							t.isNot("undefined", typeof scriptLoad);
+							t.is("loaded", scriptLoad);
+						}), function(error){
+							d.errback(error);
+						});
+						return d;
+					},
+					function checkString(t){
+						var d = new doh.Deferred();
+						script.get("scriptDummyMethod.php", {
+							query: {
+								checkString: "myTasks"
+							},
+							checkString: "myTasks"
+						}).then(d.getTestCallback(function(data){
+							t.isNot("undefined", typeof myTasks);
+							t.is("Do dishes.", myTasks[1]);
+						}), function(error){
+							d.errback(error);
+						});
+						return d;
+					},
+					function jsonp(t){
+						var d = new doh.Deferred();
+						script.get("scriptDummyMethod.php", {
+							query: { foo: "bar" },
+							jsonp: "callback"
+						}).then(d.getTestCallback(function(data){
+							t.is("mammal", data.animalType);
+						}), function(error){
+							d.errback(error);
+						});
+						return d;							
+					},
+					function jsonpTimeout(t){
+						var d = new doh.Deferred();
+						script.get("scriptDummyMethod.php", {
+							query: { delay: 3 },
+							timeout: 500,
+							jsonp: "callback"
+						}).then(function(data){
+							d.errback(false);
+						}, d.getTestCallback(function(error){
+							t.t(error instanceof RequestTimeoutError);
+						}));
+						return d;
+					},
+					function jsonpCancel(t){
+						var d = new doh.Deferred();
+						script.get("scriptDummyMethod.php", {
+							query: { delay: 3 },
+							jsonp: "callback"
+						}).then(function(data){
+							d.errback(false);
+						}, d.getTestCallback(function(error){
+							t.t(error instanceof CancelError);
+						})).cancel();
+						return d;
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body>
+		<h1>dojo/request/script test</h1>
+	</body>
+</html>
diff --git a/dojo/tests/request/scriptDummyMethod.php b/dojo/tests/request/scriptDummyMethod.php
new file mode 100644
index 0000000..03ea4d4
--- /dev/null
+++ b/dojo/tests/request/scriptDummyMethod.php
@@ -0,0 +1,21 @@
+<?php
+if(array_key_exists("delay", $_GET)){
+	sleep((int)$_GET["delay"]);
+}
+
+header("HTTP/1.1 200 OK");
+header("Expires: " . gmdate("D, d M Y H:i:s") . "GMT");
+header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+header("Cache-Control: no-cache, must-revalidate");
+header("Pragma: no-cache");
+header("Content-type: application/x-javascript");
+
+if(array_key_exists("callback", $_GET)){
+	echo $_GET["callback"] . "({ animalType: 'mammal' });";
+}else if(array_key_exists("checkString", $_GET)){
+	echo "var " . $_GET["checkString"] . " = ['Take out trash.', 'Do dishes.', 'Brush teeth.'];";
+}else if(array_key_exists("scriptVar", $_GET)){
+	echo "var " . $_GET["scriptVar"] . " = 'loaded';";
+}
+
+?>
diff --git a/dojo/tests/request/xhr.html b/dojo/tests/request/xhr.html
new file mode 100644
index 0000000..5b486bf
--- /dev/null
+++ b/dojo/tests/request/xhr.html
@@ -0,0 +1,320 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>dojo/request/xhr</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<style type="text/css">
+			@import "../../resources/dojo.css";
+		</style>
+		<script>
+			var dojoConfig = {
+				async: true
+			};
+		</script>
+		<script type="text/javascript" src="../../dojo.js"></script>
+		<script type="text/javascript">
+			require([
+				"dojo/request/xhr",
+				"dojo/_base/lang",
+				"dojo/promise/all",
+				"dojo/errors/RequestTimeoutError",
+				"dojo/errors/CancelError",
+				"dojo/has",
+				"doh",
+				"dojo/query",
+				"dojo/domReady!"
+			], function(xhr, lang, all, RequestTimeoutError, CancelError, has, doh, query){
+				var tests = [
+					function xhrGet(t){
+						var d = new doh.Deferred();
+						var td = xhr.get("xhr.html", {
+							preventCache: true
+						});
+						t.t(!!(td.then && td.cancel));
+						td.response.then(function(response){
+							t.is(4, response.xhr.readyState);
+							return response;
+						});
+						td.then(lang.hitch(d, "callback"));
+						return d;
+					},
+					function xhrGet404(t){
+						var d = new doh.Deferred();
+						var td = xhr.get("xhr_blarg.html").response.then(
+							function(response){
+								d.errback(false);
+							},
+							d.getTestCallback(function(error){
+								t.is(404, error.response.status);
+								return error;
+							})
+						);
+						return d;
+					},
+					function xhrGetQuery(t){
+						var d = new doh.Deferred();
+						var td = xhr.get("xhrDummyMethod.php?color=blue", {
+							query: {
+								foo: [ "bar", "baz" ],
+								thud: "thonk",
+								xyzzy: 3
+							},
+							handleAs: "json"
+						});
+						td.then(d.getTestErrback(function(data){
+							var query = data.query;
+
+							t.t(!!(query.color && query.foo && query.foo.length && query.thud && query.xyzzy));
+							t.is("blue", query.color);
+							t.is(2, query.foo.length);
+							t.is("thonk", query.thud);
+							t.is(3, query.xyzzy);
+
+							td.response.then(d.getTestCallback(function(response){
+								t.is("xhrDummyMethod.php?color=blue&foo=bar&foo=baz&thud=thonk&xyzzy=3",
+									response.url);
+							}));
+						}));
+						return d;
+					},
+					function xhrPost(t){
+						var d = new doh.Deferred();
+
+						var callback = d.getTestCallback(function(response){
+							if(response.response){
+								response = response.response;
+							}
+
+							t.t(xhr.isDocumentOk(response.xhr) || response.status == 405);
+						});
+						var td = xhr.post("xhrDummyMethod.php", {
+							data: { color: "blue"},
+							handleAs: "json"
+						}).then(d.getTestCallback(function(data){
+							var post = data.post;
+
+							t.t(!!(post && post.color));
+							t.is("blue", post.color);
+						}), function(error){
+							d.errback(error);
+						});
+						return d;
+					},
+					function xhrPostWithQuery(t){
+						var d = new doh.Deferred();
+
+						var td = xhr.post("xhrDummyMethod.php", {
+							query: {
+								foo: [ "bar", "baz" ],
+								thud: "thonk",
+								xyzzy: 3
+							},
+							data: { color: "blue" },
+							handleAs: "json"
+						}).then(d.getTestCallback(function(data){
+							t.t(!!data);
+
+							var query = data.query,
+								post = data.post;
+
+							t.t(!!(query && query.foo && query.foo.length && query.thud && query.xyzzy));
+							t.t(!!(post && post.color));
+							t.is(["bar", "baz"], query.foo);
+							t.is("thonk", query.thud);
+							t.is(3, query.xyzzy);
+							t.is("blue", post.color);
+						}), function(error){
+							d.errback(error);
+						});
+						return d;
+					},
+					function rawXhrPost(t){
+						var d = new doh.Deferred();
+
+						var td = xhr.post("xhrDummyMethod.php", {
+							data: "foo=bar&color=blue&height=average",
+							handleAs: "json"
+						}).then(d.getTestCallback(function(data){
+							t.t(!!data);
+
+							var post = data.post;
+
+							t.t(!!(post && post.foo && post.color && post.height));
+							t.is("bar", post.foo);
+							t.is("blue", post.color);
+							t.is("average", post.height);
+						}), function(error){
+							d.errback(error);
+						});
+
+						return d;
+					},
+					function xhrPut(t){
+						var d = new doh.Deferred();
+
+						var td = xhr.put("xhrDummyMethod.php", {
+							query: { foo: "bar" },
+							data: { color: "blue"},
+							handleAs: "json"
+						}).then(d.getTestCallback(function(data){
+							t.t(!!data);
+
+							var put = data.put;
+
+							t.t(!!(put && put.color));
+							t.is("blue", put.color);
+						}), function(error){
+							d.errback(error);
+						});
+						// t.t(td instanceof dojo.Deferred);
+						return d;
+					},
+					function xhrDelete(t){
+						var d = new doh.Deferred();
+						var td = xhr.del("xhrDummyMethod.php", {
+							preventCache: true,
+							handleAs: "json"
+						}).then(d.getTestCallback(function(data){
+							t.t(!!data);
+							t.is("DELETE", data.method);
+						}), function(error){
+							d.errback(error);
+						});
+						// t.t(td instanceof dojo.Deferred);
+						return d;
+					},
+					function xhrTimeout(t){
+						var d = new doh.Deferred();
+						xhr.post("xhrDummyMethod.php?delay=1", {
+							timeout: 100
+						}).then(function(data){
+								d.errback(false);
+							}, d.getTestCallback(function(error){
+								t.t(error instanceof RequestTimeoutError);
+							}));
+						// t.t(td instanceof dojo.Deferred);
+						return d;
+					},
+					function xhrCancel(t){
+						var d = new doh.Deferred();
+						xhr.post("xhrDummyMethod.php?delay=2")
+							.then(function(data){
+								d.errback(false);
+							}, d.getTestCallback(function(error){
+								t.t(error instanceof CancelError);
+							})).cancel();
+						// t.t(td instanceof dojo.Deferred);
+						return d;
+					},
+					function xhrSync(t){
+						var called = false;
+						xhr.get("xhr.html", {
+							sync: true
+						}).then(function(){
+							called = true;
+						});
+
+						t.t(called, "'called' should be set to true");
+					},
+					{
+						name: "xhrXDomainFail",
+						timeout: 10000,
+						runTest: function xhrXDomainFail(t){
+							var d = new doh.Deferred();
+							xhr.get('http://dojotoolkit.org').response.then(function(response){
+								console.log(response);
+								d.errback(true);
+							}, function(error){
+								d.callback(true);
+							});
+
+							return d;
+						}
+					},
+					function xhrHeaders(t){
+						var d = new doh.Deferred();
+						xhr.get('xhr.html').response.then(d.getTestCallback(function(response){
+							t.isNot(null, response.getHeader('Content-Type'));
+						}),function(error){
+							d.errback(error);
+						});
+						return d;
+					},
+
+					function xhrCustomContentType(t){
+						var d = new doh.Deferred();
+
+						function postWithHeaders(headers){
+							return xhr.post("xhrEchoContentTypeHeader.php",{
+								headers: headers,
+								data: "",
+								handleAs: "text"
+							});
+						}
+
+						var expectedContentType = "application/x-test-xhr";
+
+						// Test uppercase and lowercase header names to demonstrate case insensitivity
+						all({
+							lowercaseContentType: postWithHeaders({ "content-type": expectedContentType }),
+							uppercaseContentType: postWithHeaders({ "CONTENT-TYPE": expectedContentType })
+						}).then(d.getTestCallback(function(results){
+							// Strip any header parameters added by browser for the request.
+							t.is(expectedContentType, results.lowercaseContentType.split(";")[0]);
+							t.is(expectedContentType, results.uppercaseContentType.split(";")[0]);
+						}), function(error){
+							d.errback(error);
+						});
+
+						return d;
+					},
+					function xhrXMLQueryable(t){
+						var d = new doh.Deferred();
+
+						xhr.get('xhrXml.php', {
+							handleAs: 'xml'
+						}).then(d.getTestCallback(function(xmlDoc){
+							var results = query('bar', xmlDoc);
+							t.is(2, results.length);
+						}), lang.hitch(d, 'errback'));
+						return d;
+					}
+				];
+
+				if(has('native-formdata')){
+					tests.push({
+						name: 'xhrFormData',
+						setUp: function(t){
+							t.formData = new FormData();
+							t.formData.append("foo", "bar");
+							t.formData.append("baz", "blah");
+						},
+						runTest: function(t){
+							var d = new doh.Deferred();
+							xhr.post("xhrDummyMethod.php", {
+								data: t.formData,
+								handleAs: "json",
+								headers: { "Content-Type": false }
+							}).then(d.getTestCallback(function(data){
+								t.is({ foo: "bar", baz: "blah" }, data.post);
+							}), function(error){
+								d.errback(error);
+							});
+							return d;
+						},
+						tearDown: function(t){
+							delete t.formData;
+						}
+					});
+				}
+
+				doh.register("dojo/request/xhr", tests);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
+
diff --git a/dojo/tests/request/xhrDummyMethod.php b/dojo/tests/request/xhrDummyMethod.php
new file mode 100644
index 0000000..d824b20
--- /dev/null
+++ b/dojo/tests/request/xhrDummyMethod.php
@@ -0,0 +1,72 @@
+<?php
+function fix_raw_data($data){
+	$arr = array();
+	$pairs = explode('&', $data);
+
+	foreach ($pairs as $i) {
+		if (!empty($i)) {
+			list($name, $value) = explode('=', $i, 2);
+
+			if (isset($arr[$name])) {
+				if (is_array($arr[$name])) {
+					$arr[$name][] = $value;
+				} else {
+					$arr[$name] = array($arr[$name], $value);
+				}
+			} else {
+				$arr[$name] = $value;
+			}
+		}
+	}
+
+	return $arr;
+}
+
+//Just a dummy end point to use in HTTP method calls like PUT and DELETE.
+//This avoids getting a 405 method not allowed calls for the tests that reference
+//this file.
+
+$query = null;
+if (!empty($_SERVER['QUERY_STRING'])) {
+	$query = fix_raw_data($_SERVER['QUERY_STRING']);
+	if(!empty($query) && array_key_exists('delay', $query)){
+		sleep((int)$query['delay']);
+	}
+}
+
+$post = null;
+if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+	if(!strcmp($_SERVER['HTTP_CONTENT_TYPE'], 'application/x-www-form-urlencoded')){
+		$post = fix_raw_data(file_get_contents('php://input'));
+	}else{
+		$post = $_POST;
+	}
+}
+
+$put = null;
+if ($_SERVER['REQUEST_METHOD'] == 'PUT') {
+	$put = fix_raw_data(file_get_contents('php://input'));
+}
+
+$del = false;
+if ($_SERVER['REQUEST_METHOD'] == 'DELETE') {
+	$del = true;
+}
+
+$result = array(
+	"method" => $_SERVER['REQUEST_METHOD'],
+	"query" => $query,
+	"post" => $post,
+	"put" => $put,
+	"del" => $del
+);
+
+header("HTTP/1.1 200 OK");
+header("Expires: " . gmdate("D, d M Y H:i:s") . "GMT");
+header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+header("Cache-Control: no-cache, must-revalidate");
+header("Pragma: no-cache");
+header("Content-type: application/json");
+
+echo json_encode($result);
+?>
diff --git a/dojo/tests/request/xhrEchoContentTypeHeader.php b/dojo/tests/request/xhrEchoContentTypeHeader.php
new file mode 100644
index 0000000..6e11906
--- /dev/null
+++ b/dojo/tests/request/xhrEchoContentTypeHeader.php
@@ -0,0 +1,12 @@
+<?php
+
+header("HTTP/1.1 200 OK");
+header("Expires: " . gmdate("D, d M Y H:i:s") . "GMT");
+header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+header("Cache-Control: no-cache, must-revalidate");
+header("Pragma: no-cache");
+header("Content-type: text/plain");
+
+echo $_SERVER["CONTENT_TYPE"]
+
+?>
diff --git a/dojo/tests/request/xhrXml.php b/dojo/tests/request/xhrXml.php
new file mode 100644
index 0000000..2ca3589
--- /dev/null
+++ b/dojo/tests/request/xhrXml.php
@@ -0,0 +1,9 @@
+<?php
+header("HTTP/1.1 200 OK");
+header("Expires: " . gmdate("D, d M Y H:i:s") . "GMT");
+header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+header("Cache-Control: no-cache, must-revalidate");
+header("Pragma: no-cache");
+header("Content-type: application/xml");
+?><?php echo '<?xml version="1.0" encoding="UTF-8" ?>'; ?>
+<foo><bar baz='thonk'>blarg</bar><bar>blah</bar></foo>
diff --git a/dojo/tests/resources/AMDMixin.js b/dojo/tests/resources/AMDMixin.js
new file mode 100644
index 0000000..1171dcd
--- /dev/null
+++ b/dojo/tests/resources/AMDMixin.js
@@ -0,0 +1,10 @@
+define(["dojo/_base/declare"], function(declare){
+
+	return declare(null, {
+		amdMixinDone: true,
+		constructor: function(args, node){
+			this.params = args;
+		}
+	});
+
+});
\ No newline at end of file
diff --git a/dojo/tests/resources/AMDWidget.js b/dojo/tests/resources/AMDWidget.js
new file mode 100644
index 0000000..a0689ee
--- /dev/null
+++ b/dojo/tests/resources/AMDWidget.js
@@ -0,0 +1,9 @@
+define(["dojo/_base/declare"], function(declare){
+
+	return declare(null, {
+		constructor: function(args, node){
+			this.params = args;
+		}
+	});
+
+});
\ No newline at end of file
diff --git a/dojo/tests/resources/AMDWidget2.js b/dojo/tests/resources/AMDWidget2.js
new file mode 100644
index 0000000..07f52b5
--- /dev/null
+++ b/dojo/tests/resources/AMDWidget2.js
@@ -0,0 +1,14 @@
+define(["dojo/_base/declare"], function(declare){
+
+	return declare(null, {
+		constructor: function(args, node){
+			this.params = args;
+		},
+
+		method1: function(value){
+			value++;
+			return value;
+		}
+	});
+
+});
diff --git a/dojo/tests/resources/AMDWidget3.js b/dojo/tests/resources/AMDWidget3.js
new file mode 100644
index 0000000..5686125
--- /dev/null
+++ b/dojo/tests/resources/AMDWidget3.js
@@ -0,0 +1,9 @@
+define(["dojo/_base/declare"], function(declare){
+
+	return declare(null, {
+		constructor: function(args, node){
+			this.params = args;
+		}
+	});
+
+});
diff --git a/dojo/tests/resources/amdmodule.js b/dojo/tests/resources/amdmodule.js
new file mode 100644
index 0000000..96b74d5
--- /dev/null
+++ b/dojo/tests/resources/amdmodule.js
@@ -0,0 +1,8 @@
+define([], function(){
+	
+	return function(value){
+		value++;
+		return value;
+	};
+
+});
diff --git a/dojo/tests/resources/nodeamd.js b/dojo/tests/resources/nodeamd.js
new file mode 100644
index 0000000..da21a49
--- /dev/null
+++ b/dojo/tests/resources/nodeamd.js
@@ -0,0 +1,26 @@
+/*
+ * Test module for dojo/node plugin that tries to detect AMD
+ */
+
+(function(undefined){
+
+	var nodeamd = {};
+
+	nodeamd.test = 'foo';
+
+	// "Improper" detection of AMD in a combined CommonJS/AMD modules, where the module thinks it is being loaded
+	// by an AMD loader, when in fact it could be being loaded by a CommonJS module loader.  The dojo/node plugin
+	// needs to "hide" define from these types of modules.
+	if (typeof define === "function" && define.amd) {
+		define("nodeamd", [], function () {
+			return nodeamd;
+		});
+	}
+	else if (typeof module !== 'undefined' && module.exports) {
+		module.exports = nodeamd;
+	}
+	else if (typeof ender === 'undefined') {
+		this['nodeamd'] = nodeamd;
+	}
+
+}).call(this);
\ No newline at end of file
diff --git a/dojo/tests/resources/nodemod/m.js b/dojo/tests/resources/nodemod/m.js
new file mode 100644
index 0000000..a456936
--- /dev/null
+++ b/dojo/tests/resources/nodemod/m.js
@@ -0,0 +1,7 @@
+/*
+ * Test module for dojo/node plugin
+ */
+
+var m = module.exports = exports;
+
+m.test = "value";
\ No newline at end of file
diff --git a/dojo/tests/resources/nodemod/package.json b/dojo/tests/resources/nodemod/package.json
new file mode 100644
index 0000000..4a016f8
--- /dev/null
+++ b/dojo/tests/resources/nodemod/package.json
@@ -0,0 +1,4 @@
+{
+  "name": "nodemod",
+  "main": "m"
+}
\ No newline at end of file
diff --git a/dojo/tests/resources/nodemodule.js b/dojo/tests/resources/nodemodule.js
new file mode 100644
index 0000000..64ff21e
--- /dev/null
+++ b/dojo/tests/resources/nodemodule.js
@@ -0,0 +1,7 @@
+/*
+ * Test module for dojo/node plugin
+ */
+
+var nodemodule = module.exports = exports;
+
+nodemodule.test = "value";
\ No newline at end of file
diff --git a/dojo/tests/resources/noderequire.js b/dojo/tests/resources/noderequire.js
new file mode 100644
index 0000000..82e204f
--- /dev/null
+++ b/dojo/tests/resources/noderequire.js
@@ -0,0 +1,5 @@
+/*
+ * Tests that the node.js standard require works fine
+ */
+
+module.exports = require('./nodemodule');
diff --git a/dojo/tests/resources/noderequireamd.js b/dojo/tests/resources/noderequireamd.js
new file mode 100644
index 0000000..d7366f8
--- /dev/null
+++ b/dojo/tests/resources/noderequireamd.js
@@ -0,0 +1,7 @@
+/*
+ * Test module for dojo/node plugin that relies upon a 'dual' AMD/CommonJS module
+ */
+
+var noderequireamd = module.exports = exports;
+
+noderequireamd.nodeamd = require("./nodeamd");
diff --git a/dojo/tests/router.js b/dojo/tests/router.js
new file mode 100644
index 0000000..2e7c9bf
--- /dev/null
+++ b/dojo/tests/router.js
@@ -0,0 +1,379 @@
+define([
+	"../_base/array",
+	"../hash",
+	"../router/RouterBase",
+	"doh"
+], function(arrayUtil, hash, RouterBase, doh){
+	// This test uses RouterBase so that I can test a few different behaviors of the router
+	// which require re-initializing a new router
+	var count = 0,
+		router = new RouterBase(),
+		handle, foo;
+
+	// Simple helper to make tearDown simpler
+	function removeAll(handles) {
+		arrayUtil.forEach(handles, function(handle){
+			handle.remove();
+		});
+	}
+
+	doh.register("tests.router", [
+		{
+			name: "Router API",
+			setUp: function(t){
+				// Reset the hash to make sure we get a clean test
+				hash("", true);
+			},
+			runTest: function(t){
+				t.t(router.register, "Router has a register");
+				t.t(router.go, "Router has a go");
+				t.t(router.startup, "Router has a startup");
+				t.t(router.destroy, "Router has a destroy");
+			}
+		},
+		{
+			name: "Registering a route by string",
+			runTest: function(t){
+				handle = router.register("/foo", function(){
+					count++;
+					console.log("/foo fired! New count:", count);
+				});
+
+				// Make sure it looks right
+				t.t(handle.remove, "Handle has a remove");
+				t.t(handle.register, "Handle has a register");
+			}
+		},
+		{
+			name: "Ensuring routes don't fire before startup",
+			setUp: function(){
+				count = 0;
+			},
+			runTest: function(t){
+				hash("/foo");
+				t.t(count === 0, "Count should have been 0, was " + count);
+			}
+		},
+		{
+			name: "Ensuring routes do fire after startup",
+			runTest: function(t){
+				router.startup();
+				t.t(count === 1, "Count should have been 1, was " + count);
+			}
+		},
+		{
+			name: "Ensuring that hash changes fire routes",
+			runTest: function(t){
+				// Due to the nature of the hashchange event,
+				// this test is going to be async - but we have to nest it,
+				// sadly.
+
+				var d = new doh.Deferred();
+
+				// Reset the hash
+				hash("");
+
+				setTimeout(function(){
+					// As soon as possible, set it back to our test...
+					hash("/foo");
+					console.log("Setting hash");
+
+					// ... and then check to make sure the events fired
+					setTimeout(d.getTestCallback(function(){
+						console.log("Checking count, current hash:", hash());
+						t.t(count === 2, "Count should have been 2, was " + count);
+					}), 50);
+				}, 0);
+
+				return d;
+			}
+		},
+		{
+			name: "Ensuring that router.go fires changes",
+			runTest: function(t){
+				var d = new doh.Deferred();
+
+				// Since router.go fires off routes immediately, this should
+				// kick off changes!
+				router.go("");
+				router.go("/foo");
+
+				t.t(count === 3, "Count should have been 3, was " + count);
+			}
+		},
+		{
+			name: "Ensuring route doesn't fire after removal",
+			runTest: function(t){
+				handle.remove();
+				router.go("");
+				router.go("/foo");
+
+				t.t(count === 3, "Count should have been 3, was " + count);
+			}
+		},
+		{
+			name: "Registering a route by regexp",
+			runTest: function(t){
+				handle = router.register(/^\/bar$/, function(){
+					count++;
+				});
+				router.go("/bar");
+
+				t.t(count === 4, "Count should have been 4, was " + count);
+			},
+			tearDown: function(){
+				handle.remove();
+			}
+		},
+		{
+			name: "Checking event object",
+			runTest: function(t){
+				var oldPath, newPath, params, stopImmediatePropagation, preventDefault;
+
+				router.go("");
+
+				handle = router.register("/checkEventObject/:foo", function(event){
+					oldPath = event.oldPath;
+					newPath = event.newPath;
+					params = event.params;
+					stopImmediatePropagation = typeof event.stopImmediatePropagation;
+					preventDefault = typeof event.preventDefault;
+				});
+
+				router.go("/checkEventObject/bar");
+
+				t.t(oldPath === "", "oldPath should be empty string, was " + oldPath);
+				t.t(newPath === "/checkEventObject/bar", "newPath should be '/checkEventObject/bar', was " + newPath);
+				t.t(params, "params should be a truthy value, was " + params);
+				t.t(params.hasOwnProperty("foo"), "params should have a .foo property");
+				t.t(params.foo === "bar", "params.foo should be bar, was " + params.foo);
+				t.t(stopImmediatePropagation === "function", "stopImmediatePropagation should be a function, was " + stopImmediatePropagation);
+				t.t(preventDefault === "function", "preventDefault should be a function, was " + preventDefault);
+			},
+			tearDown: function(){
+				handle.remove();
+			}
+		},
+		{
+			name: "Checking extra arguments - string route",
+			runTest: function(t){
+				var a, b;
+
+				handle = router.register("/stringtest/:applied/:arg", function(event, applied, arg){
+					a = applied;
+					b = arg;
+				});
+
+				router.go("/stringtest/extra/args");
+
+				t.t(a === "extra", "a should have been 'extra', was " + a);
+				t.t(b === "args", "b should have been 'args', was " + b);
+			},
+			tearDown: function(){
+				handle.remove();
+			}
+		},
+		{
+			name: "Checking extra arguments - regex route",
+			runTest: function(t){
+				var a, b;
+				
+				handle = router.register(/\/regextest\/(\w+)\/(\w+)/, function(event, applied, arg){
+					a = applied;
+					b = arg;
+				});
+
+				router.go("/regextest/extra/args");
+
+				t.t(a === "extra", "a should have been 'extra', was " + a);
+				t.t(b === "args", "b should have been 'args', was " + b);
+			},
+			tearDown: function(){
+				handle.remove();
+			}
+		},
+		{
+			name: "Registering long routes with placeholders",
+			runTest: function(t){
+				var testObject;
+
+				handle = router.register("/path/:to/:some/:long/*thing", function(event){
+					testObject = event.params;
+				});
+
+				router.go("/path/to/some/long/thing/this/is/in/splat");
+
+				t.t(testObject instanceof Object, "testObject should have been an object, but wasn't");
+				t.t(testObject.to === "to", "testObject.to should have been 'to', was " + testObject.to);
+				t.t(testObject.some === "some", "testObject.some should have been 'some', was " + testObject.some);
+				t.t(testObject["long"] === "long", "testObject.long should have been 'long', was " + testObject["long"]);
+				t.t(testObject.thing === "thing/this/is/in/splat", "testObject.thing should have been 'thing/this/is/in/splat', was " + testObject.thing);
+
+				testObject = null;
+
+				router.go("/path/1/2/3/4/5/6");
+
+				t.t(testObject instanceof Object, "testObject should have been an object, but wasn't");
+				t.t(testObject.to === "1", "testObject.to should have been '1', was " + testObject.to);
+				t.t(testObject.some === "2", "testObject.some should have been '2', was " + testObject.some);
+				t.t(testObject["long"] === "3", "testObject.long should have been '3', was " + testObject["long"]);
+				t.t(testObject.thing === "4/5/6", "testObject.thing should have been '4/5/6', was " + testObject.thing);
+			},
+			tearDown: function(){
+				handle.remove();
+			}
+		},
+		{
+			name: "Using capture groups in a regex route",
+			runTest: function(t){
+				var testObject;
+
+				handle = router.register(/^\/path\/(\w+)\/(\d+)$/, function(event){
+					testObject = event.params;
+				});
+
+				router.go("/path/abcdef/1234");
+
+				t.t(testObject instanceof Array, "testObject should have been an array, but wasn't");
+				t.t(testObject[0] === "abcdef", "testObject[0] should have been 'abcdef', was " + testObject[0]);
+				t.t(testObject[1] === "1234", "testObject[1] should have been '1234', was " + testObject[1]);
+
+				testObject = null;
+
+				router.go("/path/abc/def");
+
+				t.t(testObject === null, "testObject should have been null, but wasn't");
+
+				router.go("/path/abc123/456def");
+
+				t.t(testObject === null, "testObject should have been null, but wasn't");
+
+				router.go("/path/abc123/456");
+
+				t.t(testObject instanceof Array, "testObject should have been an array, but wasn't");
+				t.t(testObject[0] === "abc123", "testObject[0] should have been 'abc123', was " + testObject[0]);
+				t.t(testObject[1] === "456", "testObject[1] should have been '456', was " + testObject[1]);
+			},
+			tearDown: function(){
+				handle.remove();
+			}
+		},
+		{
+			name: "Testing registerBefore",
+			runTest: function(t){
+				var test = "";
+
+				handle = [];
+
+				handle.push(router.register("/isBefore", function(){
+					test += "1";
+				}));
+
+				handle.push(router.registerBefore("/isBefore", function(){
+					test += "2";
+				}));
+
+				handle.push(router.register("/isBefore", function(){
+					test += "3";
+				}));
+
+				handle.push(router.registerBefore("/isBefore", function(){
+					test += "4";
+				}));
+
+				handle.push(router.register("/isBefore", function(){
+					test += "5";
+				}));
+
+				router.go("/isBefore");
+
+				t.t(test === "42135", "test should have been '42135', was " + test);
+			},
+			tearDown: function(){
+				removeAll(handle);
+			}
+		},
+		{
+			name: "Stopping propagation",
+			runTest: function(t){
+				var test = "";
+
+				handle = [];
+
+				handle.push(router.register("/stopImmediatePropagation", function(){ test += "A"; }));
+				handle.push(router.register("/stopImmediatePropagation", function(){ test += "B"; }));
+
+				handle.push(router.register("/stopImmediatePropagation", function(event){
+					event.stopImmediatePropagation();
+					test += "C";
+				}));
+
+				handle.push(router.register("/stopImmediatePropagation", function(){ test += "D"; }));
+				handle.push(router.register("/stopImmediatePropagation", function(){ test += "E"; }));
+
+				router.go("/stopImmediatePropagation");
+
+				t.t(test === "ABC", "test should have been 'ABC', was " + test);
+			},
+			tearDown: function(){
+				removeAll(handle);
+			}
+		},
+		{
+			name: "Preventing default (change)",
+			runTest: function(t){
+				var prevented = false, goResult;
+
+				hash("");
+
+				t.t(hash() === "", "hash should be empty");
+
+				handle.push(router.register("/preventDefault", function(event){
+					event.preventDefault();
+				}));
+
+				goResult = router.go("/preventDefault");
+
+				t.t(hash() === "", "hash should still be empty");
+				t.t(goResult === false, "goResult should be false");
+
+				goResult = router.go("/someOtherPath");
+
+				t.t(hash() === "/someOtherPath", "hash should be '/someOtherPath'");
+				t.t(goResult === true, "goResult should be true");
+
+				handle.push(router.register("/allowDefault", function(event){
+					console.log("Doing something here without explicitly stopping");
+				}));
+			},
+			tearDown: function(){
+				removeAll(handle);
+			}
+		},
+		{
+			name: "Default router path",
+			setUp: function(){
+				// Set up a new router for use in this test
+				router.destroy();
+				router = new RouterBase();
+
+				// Start with a clean hash
+				hash("");
+			},
+			runTest: function(t){
+				var routeHit = false;
+
+				handle = router.register("/default", function(event){
+					routeHit = true;
+				});
+
+				router.startup("/default");
+
+				t.t(routeHit, "Our route was not hit, but should have been");
+			},
+			tearDown: function(){
+				handle.remove();
+			}
+		}
+	]);
+});
diff --git a/dojo/tests/rpc.js b/dojo/tests/rpc.js
index ef6e477..10610cc 100644
--- a/dojo/tests/rpc.js
+++ b/dojo/tests/rpc.js
@@ -1,4 +1,5 @@
-define(["../main", "doh", "require", "../rpc/RpcService", "../rpc/JsonService", "../rpc/JsonpService"], function(dojo, doh, require){
+define(["doh/main", "require", "../rpc/RpcService", "../rpc/JsonService", "../rpc/JsonpService"],
+	function(doh, require, RpcService, JsonService, JsonpService){
 
 	doh.register("tests.rpc", [
 		{
@@ -21,19 +22,19 @@ define(["../main", "doh", "require", "../rpc/RpcService", "../rpc/JsonService",
 					]
 				};
 
-				this.svc = new dojo.rpc.JsonService(testSmd);
+				this.svc = new JsonService(testSmd);
 			},
 			runTest: function(){
 				var d = new doh.Deferred();
 				var td = this.svc.myecho("RPC TEST");
 
-				if (window.location.protocol=="file:") {
+				if (window.location.protocol=="file:"){
 					var err= new Error("This Test requires a webserver and PHP and will fail intentionally if loaded from file://");
 					d.errback(err);
 					return d;
 				}
 
-				td.addCallbacks(function(result) {
+				td.addCallbacks(function(result){
 					if(result=="<P>RPC TEST</P>"){
 						return true;
 					}else{
@@ -59,13 +60,13 @@ define(["../main", "doh", "require", "../rpc/RpcService", "../rpc/JsonService",
 					methods:[ { name:"contentB" } ]
 				};
 
-				this.svc = new dojo.rpc.JsonService(testSmd);
+				this.svc = new JsonService(testSmd);
 			},
 			runTest: function(){
 				var d = new doh.Deferred();
 				var td = this.svc.contentB();
 
-				if (window.location.protocol=="file:") {
+				if (window.location.protocol=="file:"){
 					var err= new Error("This Test requires a webserver and PHP and will fail intentionally if loaded from file://");
 					d.errback(err);
 					return d;
@@ -90,13 +91,13 @@ define(["../main", "doh", "require", "../rpc/RpcService", "../rpc/JsonService",
 		{
 			name: "JsonRPC_SMD_Loading_test",
 			setUp: function(){
-				this.svc = new dojo.rpc.JsonService("../../dojo/tests/resources/testClass.smd");
+				this.svc = new JsonService("../../dojo/tests/resources/testClass.smd");
 			},
 			runTest: function(){
 
-				if (this.svc.objectName=="testClass") {
+				if (this.svc.objectName=="testClass"){
 					return true;
-				} else {
+				}else{
 					return new Error("Error loading and/or parsing an smd file");
 				}
 			}
@@ -106,12 +107,12 @@ define(["../main", "doh", "require", "../rpc/RpcService", "../rpc/JsonService",
 			name: "JsonP_test",
 			timeout: 10000,
 			setUp: function(){
-				this.svc = new dojo.rpc.JsonpService(require.toUrl("dojo/tests/resources/yahoo_smd_v1.smd"), {appid: "foo"});
+				this.svc = new JsonpService(require.toUrl("dojo/tests/resources/yahoo_smd_v1.smd"), {appid: "foo"});
 			},
 			runTest: function(){
 				var d = new doh.Deferred();
 
-				if (window.location.protocol=="file:") {
+				if (window.location.protocol=="file:"){
 					var err= new Error("This Test requires a webserver and will fail intentionally if loaded from file://");
 					d.errback(err);
 					return d;
@@ -121,7 +122,7 @@ define(["../main", "doh", "require", "../rpc/RpcService", "../rpc/JsonService",
 
 				td.addCallbacks(function(result){
 					return true;
-					if (result["ResultSet"]["Result"][0]["DisplayUrl"]=="dojotoolkit.org/") {
+					if (result["ResultSet"]["Result"][0]["DisplayUrl"]=="dojotoolkit.org/"){
 						return true;
 					}else{
 						return new Error("JsonRpc_SMD_Loading_Test failed, resultant content didn't match");
diff --git a/dojo/tests/smoke-dojo-sie.html b/dojo/tests/smoke-dojo-sie.html
deleted file mode 100644
index 5649141..0000000
--- a/dojo/tests/smoke-dojo-sie.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>Minimum Dojo Application</title>
-		<script type="text/javascript" src="../dojo-sie.js"></script>
-	</head>
-	<body>
-    <p>hello, world</p>
-	</body>
-</html>
diff --git a/dojo/tests/sniff.html b/dojo/tests/sniff.html
new file mode 100644
index 0000000..c904d5e
--- /dev/null
+++ b/dojo/tests/sniff.html
@@ -0,0 +1,35 @@
+<html>
+	<head>
+		<title>dojo/sniff test</title>
+		<style>
+			table {
+				border-collapse: collapse;
+			}
+			td {
+				padding: 2px;
+				border:  1px solid black;
+			}
+		</style>
+		<script src="../dojo.js" data-dojo-config="async: true, isDebug: true"></script>
+		<script>
+			require(["dojo/_base/array", "dojo/sniff", "dojo/dom-construct", "dojo/domReady!"],
+					function(array, has, domConstruct){
+				array.forEach([
+					"khtml", "webkit", "chrome", "safari",
+					"opera",  "mozilla", "ie", "ff", "quirks",
+					"ios", "android", "wii", "air", "mac"], function(key){
+					var res = has(key);
+					domConstruct.place("<tr><td>has(\"" + key + "\")</td><td>" +
+						(res === undefined ? "undefined" : res) + "</td></tr>", "tbody");
+				});
+			});
+		</script>
+	</head>
+	<body>
+		<h1>dojo/sniff results</h1>
+		<table>
+			<tbody id="tbody">
+			</tbody>
+		</table>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojo/tests/store/Cache.js b/dojo/tests/store/Cache.js
index 1b2c0ac..8d18c8f 100644
--- a/dojo/tests/store/Cache.js
+++ b/dojo/tests/store/Cache.js
@@ -1,8 +1,6 @@
-dojo.provide("dojo.tests.store.Cache");
-dojo.require("dojo.store.Memory");
-dojo.require("dojo.store.Cache");
-(function(){
-	var masterStore = new dojo.store.Memory({
+define(["doh", "dojo/store/Memory", "dojo/store/Cache"], function(doh, Memory, Cache){
+
+	var masterStore = new Memory({
 		data: [
 			{id: 1, name: "one", prime: false},
 			{id: 2, name: "two", even: true, prime: true},
@@ -11,10 +9,10 @@ dojo.require("dojo.store.Cache");
 			{id: 5, name: "five", prime: true}
 		]
 	});
-	var cachingStore = new dojo.store.Memory();
+	var cachingStore = new Memory();
 	var options = {};
-	var store = dojo.store.Cache(masterStore, cachingStore, options);
-	tests.register("dojo.tests.store.Cache",
+	var store = Cache(masterStore, cachingStore, options);
+	doh.register("dojo.tests.store.Cache",
 		[
 			function testGet(t){
 				t.is(store.get(1).name, "one");
@@ -77,7 +75,20 @@ dojo.require("dojo.store.Cache");
 				t.t(store.get(7).prime);
 				t.t(cachingStore.get(7).prime);
 				t.t(masterStore.get(7).prime);
+			},
+			function testResultsFromMaster(t){
+				var originalAdd = masterStore.add;
+				masterStore.add = function(object){
+					return {
+						test: "value"
+					};
+				};
+				t.is(store.add({
+					id: 7,
+					prop: "doesn't matter"
+				}).test, "value");
+				masterStore.add = originalAdd;
 			}
 		]
 	);
-})();
+});
diff --git a/dojo/tests/store/DataStore.js b/dojo/tests/store/DataStore.js
index fc0ec85..789f787 100644
--- a/dojo/tests/store/DataStore.js
+++ b/dojo/tests/store/DataStore.js
@@ -1,33 +1,35 @@
-dojo.provide("dojo.tests.store.DataStore");
-dojo.require("dojo.store.DataStore");
-dojo.require("dojo.data.ItemFileWriteStore");
-var temp = function(){
+define(["doh", "dojo/store/DataStore", "dojo/data/ItemFileReadStore", "dojo/data/ItemFileWriteStore"],
+	function(doh, DataStore, ItemFileReadStore, ItemFileWriteStore){
+
 	var two = {id: 2, name: "two", even: true, prime: true},
 			four = {id: 4, name: "four", even: true, prime: false};
 	
-	var dataStore = new dojo.data.ItemFileWriteStore({data:{
+	var dataStore = new ItemFileWriteStore({data:{
 		items: [
 			{id: 1, name: "one", prime: false},
 			{id: 2, name: "two", even: true, prime: true},
 			{id: 3, name: "three", prime: true},
 			{id: 4, name: "four", even: true, prime: false},
-			{id: 5, name: "five", prime: true}
+			{id: 5, name: "five", prime: true,
+				children:[{_reference:1}, {_reference:2}, {_reference:3}]}
 		],
 		identifier:"id"
 	}});
 	dataStore.fetchItemByIdentity({identity:null});
-	var store = new dojo.store.DataStore({store:dataStore});
-	tests.register("dojo.tests.store.DataStore",
+	var store = new DataStore({store:dataStore});
+	doh.register("dojo.tests.store.DataStore",
 		[
 			function testGet(t){
 				t.is(store.get(1).name, "one");
 				t.is(store.get(4).name, "four");
 				t.t(store.get(5).prime);
+				t.is(store.get(5).children[1].name, "two");
 			},
 			function testQuery1(t){
 				var d = new doh.Deferred();
 				store.query({prime: true}).then(d.getTestCallback(function(results){
 					t.is(results.length, 3);
+					t.is(results[2].children[2].name, "three");
 				}));
 				return d;
 			},
@@ -59,10 +61,9 @@ var temp = function(){
 				t.t(store.get(6).perfect);
 			},
 			function testNoWriteFeature(t){
-				var readOnlyStore = new dojo.store.DataStore({store:new dojo.data.ItemFileReadStore({})});
+				var readOnlyStore = new DataStore({store:new ItemFileReadStore({})});
 				t.f(readOnlyStore.put);
 			}
 		]
 	);
-};
-temp();
+});
diff --git a/dojo/tests/store/JsonRest.js b/dojo/tests/store/JsonRest.js
index c9e41e1..81e9826 100644
--- a/dojo/tests/store/JsonRest.js
+++ b/dojo/tests/store/JsonRest.js
@@ -1,5 +1,18 @@
-define(["dojo", "doh", "require", "dojo/store/JsonRest"], function(dojo, doh, require){
-	var store = new dojo.store.JsonRest({target: require.toUrl("dojo/tests/store/x.y").match(/(.+)x\.y$/)[1]});
+define(["doh/main", "require", "dojo/_base/lang", "dojo/store/JsonRest"], function(doh, require, lang, JsonRest){
+	var globalHeaders = {
+			"test-global-header-a": true,
+			"test-global-header-b": "yes"
+		},
+		requestHeaders = {
+			"test-local-header-a": true,
+			"test-local-header-b": "yes",
+			"test-override": "overridden"
+		},
+		store = new JsonRest({
+			target: require.toUrl("dojo/tests/store/x.y").match(/(.+)x\.y$/)[1],
+			headers: lang.mixin({ "test-override": false }, globalHeaders)
+		});
+
 	doh.register("tests.store.JsonRest",
 		[
 			function testGet(t){
@@ -32,6 +45,57 @@ define(["dojo", "doh", "require", "dojo/store/JsonRest"], function(dojo, doh, re
 					d.callback(true);
 				});
 				return d;
+			},
+			function testHeaders(t){
+				var d = new doh.Deferred(),
+					error,
+					expected = 0,
+					received = 0;
+
+				// NOTE: Because HTTP headers are case-insensitive they should always be provided as all-lowercase
+				// strings to simplify testing.
+				function runTest(method, args){
+					expected++;
+
+					store[method].apply(store, args).then(function(result){
+						received++;
+
+						if(error){
+							return;
+						}
+
+						var k;
+
+						for(k in requestHeaders){
+							if(!result.headers.hasOwnProperty(k) || "" + result.headers[k] !== "" + requestHeaders[k]){
+								error = true;
+								d.errback(new Error("Header mismatch in " + method + ": " + k));
+								return;
+							}
+						}
+
+						for(k in globalHeaders){
+							if(!result.headers.hasOwnProperty(k) || "" + result.headers[k] !== "" + globalHeaders[k]){
+								error = true;
+								d.errback(new Error("Global header mismatch in " + method + ": " + k));
+								return;
+							}
+						}
+
+						if(expected === received){
+							d.callback(true);
+						}
+					});
+				}
+
+				runTest("get", [ "index.php", requestHeaders ]);
+				runTest("get", [ "index.php", { headers: requestHeaders } ]);
+				runTest("remove", [ "index.php", { headers: requestHeaders } ]);
+				runTest("query", [ {}, { headers: requestHeaders, start: 20, count: 42 } ]);
+				runTest("put", [ {}, { headers: requestHeaders } ]);
+				runTest("add", [ {}, { headers: requestHeaders } ]);
+
+				return d;
 			}
 		]
 	);
diff --git a/dojo/tests/store/Memory.js b/dojo/tests/store/Memory.js
index edf8081..005a6ab 100644
--- a/dojo/tests/store/Memory.js
+++ b/dojo/tests/store/Memory.js
@@ -1,16 +1,14 @@
-dojo.provide("dojo.tests.store.Memory");
-dojo.require("dojo.store.Memory");
-(function(){
-	var store = new dojo.store.Memory({
+define(["doh", "dojo/store/Memory"], function(doh, Memory){
+	var store = new Memory({
 		data: [
-			{id: 1, name: "one", prime: false},
-			{id: 2, name: "two", even: true, prime: true},
-			{id: 3, name: "three", prime: true},
-			{id: 4, name: "four", even: true, prime: false},
-			{id: 5, name: "five", prime: true}
+			{id: 1, name: "one", prime: false, mappedTo: "E"}, 
+			{id: 2, name: "two", even: true, prime: true, mappedTo: "D"}, 
+			{id: 3, name: "three", prime: true, mappedTo: "C"}, 
+			{id: 4, name: "four", even: true, prime: false, mappedTo: null}, 
+			{id: 5, name: "five", prime: true, mappedTo: "A"} 		
 		]
 	});
-	tests.register("dojo.tests.store.Memory",
+	doh.register("dojo.tests.store.Memory",
 		[
 			function testGet(t){
 				t.is(store.get(1).name, "one");
@@ -31,9 +29,17 @@ dojo.require("dojo.store.Memory");
 				t.is(store.query({name: /^o/}).length, 1);
 				t.is(store.query({name: /o/}).length, 3);
 			},
+			function testQueryWithTestFunction(t){
+				t.is(store.query({id: {test: function(id){ return id < 4;}}}).length, 3);
+				t.is(store.query({even: {test: function(even, object){ return even && object.id > 2;}}}).length, 1);
+			},
 			function testQueryWithSort(t){
 				t.is(store.query({prime: true}, {sort:[{attribute:"name"}]}).length, 3);
 				t.is(store.query({even: true}, {sort:[{attribute:"name"}]})[1].name, "two");
+				t.is(store.query({even: true}, {sort:function(a, b){
+						return a.name < b.name ? -1 : 1;
+					}})[1].name, "two");
+				t.is(store.query(null, {sort:[{attribute:"mappedTo"}]})[4].name, "four");
 			},
 			function testQueryWithPaging(t){
 				t.is(store.query({prime: true}, {start: 1, count: 1}).length, 1);
@@ -86,7 +92,7 @@ dojo.require("dojo.store.Memory");
 				t.is(store.query({perfect: true}).length, 1);
 			},
 			function testIFRSStyleData(t){
-				var anotherStore = new dojo.store.Memory({
+				var anotherStore = new Memory({
 					data: {
 						items:[
 							{name: "one", prime: false},
@@ -98,7 +104,14 @@ dojo.require("dojo.store.Memory");
 				});
 				t.is(anotherStore.get("one").name,"one");
 				t.is(anotherStore.query({name:"one"})[0].name,"one");
+			},
+			function testAddNewIdAssignment(t){
+				var object = {
+					random: true
+				};
+				store.add(object);
+				t.t(!!object.id);
 			}
 		]
 	);
-})();
+});
diff --git a/dojo/tests/store/Observable.js b/dojo/tests/store/Observable.js
index f607d71..38a8b64 100644
--- a/dojo/tests/store/Observable.js
+++ b/dojo/tests/store/Observable.js
@@ -1,8 +1,16 @@
-dojo.provide("dojo.tests.store.Observable");
-dojo.require("dojo.store.Memory");
-dojo.require("dojo.store.Observable");
-(function(){
-	var store = dojo.store.Observable(new dojo.store.Memory({
+define([
+	"doh",
+	"dojo/_base/array", "dojo/_base/declare", "dojo/_base/lang",
+	"dojo/store/Memory", "dojo/store/Observable"
+], function(doh, array, declare, lang, Memory, Observable){
+
+	var MyStore = declare([Memory], {
+		get: function(){
+			// need to make sure that this.inherited still works with Observable
+			return this.inherited(arguments);
+		}
+	});
+	var memoryStore, store = new Observable(memoryStore = new MyStore({ /*dojo.store.Memory*/
 		data: [
 			{id: 0, name: "zero", even: true, prime: false},
 			{id: 1, name: "one", prime: false},
@@ -12,7 +20,12 @@ dojo.require("dojo.store.Observable");
 			{id: 5, name: "five", prime: true}
 		]
 	}));
-	tests.register("dojo.tests.store.Observable",
+    var data = [], i;
+    for(i = 1; i <= 100; i++){
+        data.push({id: i, name: "item " + i, order: i});
+    }
+	var bigStore = Observable(new Memory({data:data}));
+	doh.register("dojo.tests.store.Observable",
 		[
 			function testGet(t){
 				t.is(store.get(1).name, "one");
@@ -29,7 +42,8 @@ dojo.require("dojo.store.Observable");
 				var secondObserver = results.observe(function(object, previousIndex, newIndex){
 					secondChanges.push({previousIndex:previousIndex, newIndex:newIndex, object:object});
 				});
-				var expectedChanges = [];
+				var expectedChanges = [],
+					expectedSecondChanges = [];
 				var two = results[0];
 				two.prime = false;
 				store.put(two); // should remove it from the array
@@ -44,6 +58,7 @@ dojo.require("dojo.store.Observable");
 							prime: false
 						}
 					});
+				expectedSecondChanges.push(expectedChanges[expectedChanges.length - 1]);
 				secondObserver.cancel();
 				var one = store.get(1);
 				one.prime = true;
@@ -82,10 +97,11 @@ dojo.require("dojo.store.Observable");
 					});
 				t.is(results.length, 3);
 				
-				observer.cancel(); // shouldn't get any more calls
+				observer.remove(); // shouldn't get any more calls
 				store.add({// should not be added
 					id:11, name:"eleven", prime:true
 				});
+				t.is(secondChanges, expectedSecondChanges);
 				t.is(changes, expectedChanges);
 			},
 			function testQueryWithZeroId(t){
@@ -99,7 +115,42 @@ dojo.require("dojo.store.Observable");
                 }, true);
                 store.put({id: 5, name: "-FIVE-", prime: true});
                 store.put({id: 0, name: "-ZERO-", prime: false});
-            }			
+            },
+            function testPaging(t){
+				var results, opts = {count: 25, sort: [{attribute: "order"}]};
+				results = window.results = [
+				    bigStore.query({}, lang.delegate(opts, {start: 0})),
+				    bigStore.query({}, lang.delegate(opts, {start: 25})),
+				    bigStore.query({}, lang.delegate(opts, {start: 50})),
+				    bigStore.query({}, lang.delegate(opts, {start: 75}))
+				];
+				var observations = [];
+				array.forEach(results, function(r, i){
+				    r.observe(function(obj, from, to){
+				    	observations.push({from: from, to: to});
+				        console.log(i, " observed: ", obj, from, to);
+				    }, true);
+				});
+				bigStore.add({id: 101, name: "one oh one", order: 2.5});
+				t.is(results[0].length, 26);
+				t.is(results[1].length, 25);
+				t.is(results[2].length, 25);
+				t.is(results[3].length, 25);
+				t.is(observations.length, 1);
+				bigStore.remove(101);
+				t.is(observations.length, 2);
+				t.is(results[0].length, 25);
+				bigStore.add({id: 102, name: "one oh two", order: 26.5});
+				t.is(results[0].length, 25);
+				t.is(results[1].length, 26);
+				t.is(results[2].length, 25);
+				t.is(observations.length, 3);
+            },
+            function testType(t){
+            	t.f(memoryStore == store);
+            	// TODO: use store.instanceOf()
+//			  	t.t(store instanceof Observable);
+            }
 		]
 	);
-})();
+});
diff --git a/dojo/tests/store/index.php b/dojo/tests/store/index.php
new file mode 100644
index 0000000..45d792d
--- /dev/null
+++ b/dojo/tests/store/index.php
@@ -0,0 +1,23 @@
+<?php
+
+$data = array(
+	"method" => strtoupper($_SERVER["REQUEST_METHOD"]),
+	"headers" => array(),
+	"content" => null
+);
+
+foreach($_SERVER as $key => $value){
+	if(strpos($key, "HTTP_") === 0){
+		$data["headers"][strtr(strtolower(substr($key, 5)), "_", "-")] = $value;
+	}
+}
+
+if($data["method"] === "GET"){
+	$data["content"] = $_GET;
+}elseif($data["method"] === "PUT" || $data["method"] === "POST"){
+	$data["content"] = json_decode(file_get_contents("php://input"), true);
+}
+
+header("Content-Type: application/json");
+header("Cache-Control: no-cache");
+echo json_encode($data);
\ No newline at end of file
diff --git a/dojo/tests/string.js b/dojo/tests/string.js
index 2fa1dda..92217b1 100644
--- a/dojo/tests/string.js
+++ b/dojo/tests/string.js
@@ -1,22 +1,22 @@
-define(["../main", "doh", "../string"], function(dojo, doh){
+define(["doh/main", "../string"], function(doh, string){
 
 doh.register("tests.string",
 	[
 		function test_string_pad(t){
-			t.is("00001", dojo.string.pad("1", 5));
-			t.is("000001", dojo.string.pad("000001", 5));
-			t.is("10000", dojo.string.pad("1", 5, null, true));
+			t.is("00001", string.pad("1", 5));
+			t.is("000001", string.pad("000001", 5));
+			t.is("10000", string.pad("1", 5, null, true));
 		},
 
 		function test_string_substitute(t){
 			t.is("File 'foo.html' is not found in directory '/temp'.",
-				dojo.string.substitute(
+				string.substitute(
 					"File '${0}' is not found in directory '${1}'.",
 					["foo.html","/temp"]
 				)
 			);
 			t.is("File 'foo.html' is not found in directory '/temp'.",
-				dojo.string.substitute(
+				string.substitute(
 					"File '${name}' is not found in directory '${info.dir}'.",
 					{
 						name: "foo.html",
@@ -25,7 +25,7 @@ doh.register("tests.string",
 				)
 			);
 			// Verify that an error is thrown!
-			t.assertError(Error, dojo.string, "substitute", ["${x}", {y:1}]);
+			t.assertError(Error, string, "substitute", ["${x}", {y:1}]);
 		},
 
 		function test_string_substitute_transform(t){
@@ -44,7 +44,7 @@ doh.register("tests.string",
 			};
 
 			t.is("file 'foo.html' is not found in directory '/temp'.",
-				dojo.string.substitute(
+				string.substitute(
 					"${0} is not found in ${1}.",
 					["foo.html","/temp"],
 					getPrefix
@@ -52,7 +52,7 @@ doh.register("tests.string",
 			);
 
 			t.is("...file 'foo.html' is not found in ...directory '/temp'.",
-				dojo.string.substitute(
+				string.substitute(
 					"${0} is not found in ${1}.",
 					["foo.html","/temp"],
 					obj.getPrefix, obj
@@ -62,7 +62,7 @@ doh.register("tests.string",
 
 		function test_string_substitute_formatter(t){
 			t.is("thinger -- howdy",
-				dojo.string.substitute(
+				string.substitute(
 					"${0:postfix}", ["thinger"], null, {
 						postfix: function(value, key){
 							return value + " -- howdy";
@@ -73,18 +73,18 @@ doh.register("tests.string",
 		},
 
 		function test_string_trim(t){
-			t.is("astoria", dojo.string.trim("   \f\n\r\t      astoria           "));
-			t.is("astoria", dojo.string.trim("astoria                            "));
-			t.is("astoria", dojo.string.trim("                            astoria"));
-			t.is("astoria", dojo.string.trim("astoria"));
-			t.is("a", dojo.string.trim("   a   "));
+			t.is("astoria", string.trim("   \f\n\r\t      astoria           "));
+			t.is("astoria", string.trim("astoria                            "));
+			t.is("astoria", string.trim("                            astoria"));
+			t.is("astoria", string.trim("astoria"));
+			t.is("a", string.trim("   a   "));
 		},
 
 		function test_string_rep(t){
-			t.is("aaaaa", dojo.string.rep("a", 5));
-			t.is("abababab", dojo.string.rep("ab", 4));
-			t.is("", dojo.string.rep("ab", 0));
-			t.is("", dojo.string.rep("", 3));
+			t.is("aaaaa", string.rep("a", 5));
+			t.is("abababab", string.rep("ab", 4));
+			t.is("", string.rep("ab", 0));
+			t.is("", string.rep("", 3));
 		}
 	]
 );
diff --git a/dojo/tests/test_dom_setSelectable.html b/dojo/tests/test_dom_setSelectable.html
new file mode 100644
index 0000000..9e0dabf
--- /dev/null
+++ b/dojo/tests/test_dom_setSelectable.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<title>Test Page for dojo/dom.setSelectable</title>
+		<style>
+			@import "../resources/dojo.css";
+			#test {
+				border: 1px solid #000;
+				padding: 10px;
+			}
+			.item {
+				float: left;
+				padding: 10px;
+			}
+			.item td {
+				border: 1px solid #ccc;
+			}
+			.clear {
+				clear: both;
+				padding: 10px;
+			}
+		</style>
+	</head>
+	<body>
+		<h1>Test Page for dojo/dom.setSelectable</h1>
+		<p>Use the buttons below and then attempt selecting in the bordered area
+			underneath.</p>
+		<p>
+			<button onclick="makeSelectable(true);">Allow Selection</button>
+			<button onclick="makeSelectable(false);">Prevent Selection</button>
+		</p>
+		<div id="test">
+			<p>Some notes:</p>
+			<ul>
+				<li>In WebKit and IE10, <code>*-user-select: none</code> doesn't prevent you from
+					selecting within textboxes, whereas in Firefox it does</li>
+				<li>The <code>unselectable</code> attribute (used where <code>user-select</code>
+					is unavailable, e.g. IE < 10 and Opera) does not prevent text selection
+					when the selection is started from outside the node in question</li>
+				<li>In IE10, <code>-ms-user-select</code> exhibits the same behavior as
+					described in the previous bullet; all other browsers which implement
+					<code>*-user-select</code> seem to properly prevent selection even
+					when it is started outside of the node in question</li>
+				<li>Opera doesn't honor the <code>unselectable</code> attribute on textboxes</li>
+				<li>IE honors <code>unselectable</code> on textboxes, but moreover, it
+					prevents any input whatsoever</li>
+			</ul>
+			<div class="item">
+				Some text
+			</div>
+			<table class="item">
+				<tr>
+					<td>A</td>
+					<td>table</td>
+					<td>here</td>
+				</tr>
+			</table>
+			<div class="clear">
+				<input type="text" value="an input here">
+			</div>
+			More text here
+		</div>
+		<script src="../dojo.js"></script>
+		<script>
+			var makeSelectable; // function to be defined below
+			require(["dojo/dom", "dojo/domReady!"], function(dom){
+				makeSelectable = function(selectable){
+					dom.setSelectable("test", selectable);
+				};
+			});
+		</script>
+	</body>
+</html>
diff --git a/dojo/tests/test_fx.html b/dojo/tests/test_fx.html
index 4f4fd28..d3add1f 100644
--- a/dojo/tests/test_fx.html
+++ b/dojo/tests/test_fx.html
@@ -43,36 +43,36 @@
 
 		<script type="text/javascript" src="../dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript">
-			require(["dojo", "doh", "dojo/fx", "dojo/domReady!"], function(dojo, doh){
-				dojo.byId("foo").style.height = "0px";
-				var w1 = dojo.fx.wipeIn({
+			require(["doh", "dojo/aspect", "dojo/dom", "dojo/_base/fx", "dojo/fx", "dojo/domReady!"], function(doh, aspect, dom, baseFx, fx){
+				dom.byId("foo").style.height = "0px";
+				var w1 = fx.wipeIn({
 					node: "foo",
 					duration: 500
 				});
-				var f1 = dojo.fadeOut({
+				var f1 = baseFx.fadeOut({
 					node: "foo",
 					duration: 500
 				});
-				var a1 = dojo.fx.chain([w1, f1]);
+				var a1 = fx.chain([w1, f1]);
 
-				dojo.byId("foo").style.height = "0px";
-				var w2 = dojo.fx.wipeIn({
+				dom.byId("foo").style.height = "0px";
+				var w2 = fx.wipeIn({
 					node: "foo",
 					duration: 500
 				});
-				var f2 = dojo.fadeIn({
+				var f2 = baseFx.fadeIn({
 					node: "foo",
 					duration: 1000
 				});
-				var a2 = dojo.fx.combine([w2, f2]);
+				var a2 = fx.combine([w2, f2]);
 				
-				dojo.connect(a1, "onEnd", function(){
+				aspect.after(a1, "onEnd", function(){
 					console.log("finish1");
 					a2.play();
-				});
-				dojo.connect(a2, "onEnd", function(){
+				}, true);
+				aspect.after(a2, "onEnd", function(){
 					console.log("finish2");
-				});
+				}, true);
 				a1.play();
 			});
 		</script>
diff --git a/dojo/tests/test_touch.html b/dojo/tests/test_touch.html
index 5a2b510..8e2b16e 100644
--- a/dojo/tests/test_touch.html
+++ b/dojo/tests/test_touch.html
@@ -11,71 +11,113 @@
 				border: 1px solid #7FB0DB;
 				background-color: #7FB0DB;			
 			}
-			#log {
+			#innertest {
+				border: 1px solid white;
+				width: 100px;
+				heigh: 75px;
+				background-color: white;
+			}
+			#test2 {
+				/* for testing touch.move */
+				width: 200px;
+				height: 50px;
+				border: 1px solid yellow;
+				background-color: yellow;
+			}
+			#current, #log {
 				width: 300px;
 				height: 200px;
+				float: left;
 			}
 			#dohDiv{
 				display: none;
 			}			
 		</style>
-		<script type="text/javascript" src="../dojo.js" djConfig="parseOnLoad: true"></script>
+		<script type="text/javascript" src="../dojo.js" data-dojo-config="async: true"></script>
 		<script>
 			require([
-				"dojo/_base/html",
-				"dojo/_base/event",
-				"dojo/ready",
+				"dojo/_base/array",
+				"dojo/dom",
+				"dojo/_base/lang",
 				"dojo/touch",
 				"dojo/on",
 				"dojo/has",
-				"dojo/dom-style",
-				"doh/runner"
-			], function(html, evt, ready, touch, on, has, domStyle, doh){			
-				ready(function(){
-					var action = function(e){
-						evt.stop(e);
-						html.byId("log").innerHTML = "";
-						var info = "[Touch Event]: " + e.type + "<br/> ------ Event Properties: ------<br/>";
-						for(var i in e){
-						  if(i == "touches" || i == "targetTouches" || i == "changedTouches"){
-						    info += i + ": " + e[i].length + "<br/>";
-						  }else{
-						    if(typeof e[i] != "function"){
-						      info += " " + i + ": " + e[i] + "<br/>";
-						    }
-						  }
-						}
-						html.byId("log").innerHTML += info + "<br/>";
-					};
-					
-					var node = html.byId("test");
+				"dojo/domReady!"
+			], function(array, dom, lang, touch, on, has){
+
+				var mspointer = navigator.msPointerEnabled; // IE10+ PSPointer events?
 				
-					//1. should work well on PC and touch devices 
-					on(node, touch.press, action);
-					on(node, touch.move, action);
-					on(node, touch.release, action);
-					on(node, touch.cancel, action);
+				var action = function(comment, e){
+					// summary:
+					//		Callback to display into when events fire
+					// Detailed log of the most recent event:
+
+					dom.byId("current").innerHTML = "Most recent non touch.move event:";
+					var info = "[Touch Event]: " + e.type + " on " + comment +
+							"<br/> ------ Event Properties: ------<br/>";
+					for(var i in e){
+					  if(i == "touches" || i == "targetTouches" || i == "changedTouches"){
+						info += i + ": " + e[i].length + "<br/>";
+					  }else{
+						if(typeof e[i] != "function"){
+						  info += " " + i + ": " + e[i] + "<br/>";
+						}
+					  }
+					}
+					dom.byId("current").innerHTML += info + "<br/>";
+
+					// This is a log of all events, most recent first:
+					dom.byId("log").innerHTML = comment + "{type:" +
+							e.type + ", target:" + (e.target.id||e.target.tagName) +
+							"}<br/>" + dom.byId("log").innerHTML;
+
+					e.preventDefault();
+				};
+
+				var node = dom.byId("test"),
+					innerNode = dom.byId("innertest");
+
+				//1. should work well on PC and touch devices
+				array.forEach(["test", "innertest"], function(name){
+					for(var event in touch){
+						if(event != "move"){
+							on(dom.byId(name), touch[event], lang.hitch(null, action, "on("+name+", touch."+event+")-->"));
+						}
+					}
+				});
+
+				on(dom.byId("test2"), touch.move, function(e){
+					dom.byId("log").innerHTML = "on(touch2, touch.move)--> {type:" +
+							e.type + ", target:" + (e.target.id||e.target.tagName) +
+							", pageX = " + e.pageX + ", pageY = " + e.pageY +
+							"}<br/>" + dom.byId("log").innerHTML;
+
+
+					// this should stop scrolling
+					e.preventDefault();
+
+					// stopPropagation() should work too
+					e.stopPropagation();
+				});
 
-					
 //					//2. should work well across touch devices
 //					on(node, "touchstart", action);
 //					on(node, "touchmove", action);
 //					on(node, "touchend", action);
 //					on(node, "touchcancel", action);
 //					on(node, "orientationchange", action);
-					
-					//3. we can also isolate mouse/touch handlers
-					on(node, "touchend", function(){alert("isolated touchend handler");});
-					on(node, "mouseup", function(){alert("isolated mouseup handler");});
-				
-					//================================= DoH tests - only running on desktop ======================
-					if(has("touch")){
-						//FIXME - DoH not supported on touch device
-						return;
-					}
-					var dohDiv = html.byId('dohDiv');
+
+
+				//================================= DoH tests - only running on desktop ======================
+				if(has("touch")){
+					//FIXME - DoH not supported on touch device
+					return;
+				}
+
+				require(["doh/runner", "dojo/dom-style"], function(doh, domStyle){
+					var dohDiv = dom.byId('dohDiv');
 					domStyle.set(dohDiv, {display: 'block'});
-					
+
 					function setObj(obj, e){
 						obj.type = e.type;
 						obj.target = e.target;
@@ -93,9 +135,9 @@
 								executed = true;
 								setObj(obj, e);
 							});
-							on.emit(dohDiv, 'mousedown', {});
+							on.emit(dohDiv, mspointer?'MSPointerDown':'mousedown', {});
 							doh.assertTrue(executed, 'dojo.touch.press not fired');
-							assert(obj, 'mousedown', dohDiv);							
+							assert(obj, mspointer?'MSPointerDown':'mousedown', dohDiv);
 						},
 						function move(){
 							var executed, obj = {};
@@ -104,9 +146,9 @@
 								executed = true;
 								setObj(obj, e);
 							});
-							on.emit(dohDiv, 'mousemove', {});
+							on.emit(dohDiv, mspointer?'MSPointerMove':'mousemove', {});
 							doh.assertTrue(executed, 'dojo.touch.move not fired');
-							assert(obj, 'mousemove', dohDiv);
+							assert(obj, mspointer?'MSPointerMove':'mousemove', dohDiv);
 						},
 						function release(){
 							var executed, obj = {};
@@ -115,9 +157,9 @@
 								executed = true;
 								setObj(obj, e);
 							});
-							on.emit(dohDiv, 'mouseup',  {screenX: 0, screenY: 50});
+							on.emit(dohDiv, mspointer?'MSPointerUp':'mouseup',  {screenX: 0, screenY: 50});
 							doh.assertTrue(executed, 'dojo.touch.release not fired');
-							assert(obj, 'mouseup', dohDiv);
+							assert(obj, mspointer?'MSPointerUp':'mouseup', dohDiv);
 						},
 						function cancel(){
 							var executed, obj = {};
@@ -130,15 +172,25 @@
 							assert(obj, 'mouseout', dohDiv);
 						}
 					]);
+
 					doh.run();
 				});
 			});
 		</script>
 	</head>
 	<body>
-		<div id="test"></div>
+		<div id="test">
+			test
+			<div id="innertest">
+				inner test
+			</div>
+		</div>
+		<div id="test2">
+			touch.move
+		</div>
+		<div id="current"></div>
 		<div id="log"></div>
-		<br/>
+		<br style="clear:both"/>
 		<div id="dohDiv">doh</div>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojo/tests/touch.js b/dojo/tests/touch.js
index 5f5dc59..b03ba9a 100644
--- a/dojo/tests/touch.js
+++ b/dojo/tests/touch.js
@@ -1,4 +1,4 @@
-define(["doh", "require"], function(doh, require){
+define(["doh/main", "require"], function(doh, require){
 	if(doh.isBrowser){
 		doh.register("tests.touch", require.toUrl("./test_touch.html"));
 	}
diff --git a/dojo/tests/uacss.js b/dojo/tests/uacss.js
index 2e3bb57..650811a 100644
--- a/dojo/tests/uacss.js
+++ b/dojo/tests/uacss.js
@@ -1,6 +1,7 @@
-define(["doh", "require"], function(doh, require){
+define(["dojo/sniff", "doh", "require"], function(has, doh, require){
 
-	doh.register("tests.uacss.sniffQuirks", require.toUrl("./uacss/sniffQuirks.html"));
+	// IE9+ cannot handle quirks mode in test runner, see #14321
+	has("ie") >= 9 || doh.register("tests.uacss.sniffQuirks", require.toUrl("./uacss/sniffQuirks.html"));
 	doh.register("tests.uacss.sniffStandards", require.toUrl("./uacss/sniffStandards.html"));
 
 });
diff --git a/dojo/tests/uacss/sniffQuirks.html b/dojo/tests/uacss/sniffQuirks.html
index ca070ef..d8e823a 100644
--- a/dojo/tests/uacss/sniffQuirks.html
+++ b/dojo/tests/uacss/sniffQuirks.html
@@ -25,17 +25,21 @@
 	</style>
 	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true"></script>
 	<script type="text/javascript">
-		require(["dojo", "doh", "dojo/uacss", "dojo/domReady!"], function(dojo, doh){
-			var node = dojo.byId("box1");
-			var reportNode = dojo.byId("log");
+		require([
+			"doh",
+			"dojo/dom", "dojo/dom-geometry", "dojo/dom-style",
+			"dojo/json", "dojo/uacss", "dojo/domReady!"
+		], function(doh, dom, domGeom, domStyle, json, has){
+			var node = dom.byId("box1");
+			var reportNode = dom.byId("log");
 			var inner = (reportNode.textContent) ? "textContent": "innerText";
-			reportNode.innerHTML = dojo.toJson({
-				boxModel: dojo.boxModel,
-				isQuirks: dojo.isQuirks,
+			reportNode.innerHTML = json.stringify({
+				boxModel: domGeom.boxModel,
+				hasQuirks: has("quirks"),
 				width: dojo.style(node, "width"),
-				marginBoxWidth: dojo.marginBox(node).w,
-				htmlClassName: dojo.doc.documentElement.className
-			}, 1);
+				marginBoxWidth: domGeom.getMarginBox(node).w,
+				htmlClassName: document.documentElement.className
+			}, null, "    ");
 			doh.register("tests.window.sniffQuirks", [
 				function test_boxModel(t) {
 					// ensure the box-model correction in the stylesheet have been correctly applied
diff --git a/dojo/tests/uacss/sniffStandards.html b/dojo/tests/uacss/sniffStandards.html
index a0ed84f..08a4632 100644
--- a/dojo/tests/uacss/sniffStandards.html
+++ b/dojo/tests/uacss/sniffStandards.html
@@ -24,17 +24,21 @@
 	</style>
 	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug:true"></script>
 	<script type="text/javascript">
-		require(["dojo", "doh", "dojo/uacss", "dojo/domReady!"], function(dojo, doh){
-			var node = dojo.byId("box1");
-			var reportNode = dojo.byId("log");
+		require([
+			"doh",
+			"dojo/dom", "dojo/dom-geometry", "dojo/dom-style",
+			"dojo/json", "dojo/uacss", "dojo/domReady!"
+		], function(doh, dom, domGeom, domStyle, json, has){
+			var node = dom.byId("box1");
+			var reportNode = dom.byId("log");
 			var inner = (reportNode.textContent) ? "textContent": "innerText";
-			reportNode.innerHTML = dojo.toJson({
-				boxModel: dojo.boxModel,
-				isQuirks: dojo.isQuirks,
+			reportNode.innerHTML = json.stringify({
+				boxModel: domGeom.boxModel,
+				hasQuirks: has("quirks"),
 				width: dojo.style(node, "width"),
-				marginBoxWidth: dojo.marginBox(node).w,
-				htmlClassName: dojo.doc.documentElement.className
-			}, 1);
+				marginBoxWidth: domGeom.getMarginBox(node).w,
+				htmlClassName: document.documentElement.className
+			}, null, "    ");
 			doh.register("tests.window.sniffStandards", [
 				function test_boxModel(t) {
 					// ensure the box-model correction in the stylesheet have been correctly applied
diff --git a/dojo/tests/when.js b/dojo/tests/when.js
new file mode 100644
index 0000000..a90c55a
--- /dev/null
+++ b/dojo/tests/when.js
@@ -0,0 +1,101 @@
+define([
+	"doh/main",
+	"dojo/Deferred",
+	"dojo/promise/Promise",
+	"dojo/when"
+], function(doh, Deferred, Promise, when){
+	var tests = {
+		"when() returns the same promise without callbacks": function(t){
+			var obj = {};
+			var promise1 = when(obj);
+			t.t(promise1 instanceof Promise);
+			var promise2 = when(this.deferred.promise);
+			t.t(promise2 instanceof Promise);
+			t.t(this.deferred.promise === promise2);
+		},
+
+		"when() doesn't convert to promise if errback is passed but no callback": function(t){
+			var obj = {};
+			var result = when(obj, null, function(){});
+			t.t(result === obj);
+		},
+
+		"when() with a result value": function(t){
+			var obj = {};
+			var received;
+			when(obj, function(result){ received = result; });
+			t.t(received === obj);
+		},
+
+		"when() with a result value, returns result of callback": function(t){
+			var obj1 = {}, obj2 = {};
+			var received;
+			var returned = when(obj1, function(result){
+				received = result;
+				return obj2;
+			});
+			t.t(received === obj1);
+			t.t(returned === obj2);
+		},
+
+		"when() with a promise that gets resolved": function(t){
+			var obj = {};
+			var received;
+			when(this.deferred.promise, function(result){ received = result; });
+			this.deferred.resolve(obj);
+			t.t(received === obj);
+		},
+
+		"when() with a promise that gets rejected": function(t){
+			var obj = {};
+			var received;
+			when(this.deferred.promise, null, function(result){ received = result; });
+			this.deferred.reject(obj);
+			t.t(received === obj);
+		},
+
+		"when() with a promise that gets progress": function(t){
+			var obj = {};
+			var received;
+			when(this.deferred.promise, null, null, function(result){ received = result; });
+			this.deferred.progress(obj);
+			t.t(received === obj);
+		},
+
+		"when() with chaining of the result": function(t){
+			function square(n){ return n * n; }
+
+			var received;
+			when(2).then(square).then(square).then(function(n){ received = n; });
+			t.is(received, 16);
+		},
+
+		"when() converts foreign promises": function(t){
+			var _callback;
+			var foreign = { then: function(cb){ _callback = cb; } };
+			var promise = when(foreign);
+
+			var obj = {};
+			var received;
+			promise.then(function(result){ received = result; });
+			_callback(obj);
+			t.t(promise instanceof Promise);
+			t.t(received === obj);
+		}
+	};
+
+	var wrapped = [];
+	for(var name in tests){
+		wrapped.push({
+			name: name,
+			setUp: setUp,
+			runTest: tests[name]
+		});
+	}
+
+	function setUp(){
+		this.deferred = new Deferred;
+	}
+
+	doh.register("tests.when", wrapped);
+});
diff --git a/dojo/tests/window.js b/dojo/tests/window.js
index 40e4b09..1cc0702 100755
--- a/dojo/tests/window.js
+++ b/dojo/tests/window.js
@@ -1,5 +1,6 @@
-define(["doh", "require"], function(doh, require){
+define(["dojo/sniff", "doh/main", "require"], function(has, doh, require){
 	doh.register("tests.window.viewport", require.toUrl("./window/viewport.html"));
-	doh.register("tests.window.viewportQuirks", require.toUrl("./window/viewportQuirks.html"));
+	// IE9+ cannot handle quirks mode in test runner, see #14321
+	has("ie") >= 9 || doh.register("tests.window.viewportQuirks", require.toUrl("./window/viewportQuirks.html"));
 	doh.register("tests.window.test_scroll", require.toUrl("./window/test_scroll.html"), 99999999);
 });
\ No newline at end of file
diff --git a/dojo/tests/window/test_scroll.html b/dojo/tests/window/test_scroll.html
index 2875eca..4abd814 100644
--- a/dojo/tests/window/test_scroll.html
+++ b/dojo/tests/window/test_scroll.html
@@ -10,251 +10,556 @@
 		FIELDSET IFRAME { width:100px; height:100px; }
 	</style>
 	<script type="text/javascript" src="../../dojo.js"
-		djConfig="isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
 	<script type="text/javascript">
-		var loading; //global
-		require(["doh"], function(doh){
-			loading = new doh.Deferred();
-		});
+		// Global methods accessed by iframes
+		var count, loading;
+		function initIframeMethods(iframeWin, parentWin){
+			iframeWin.frameElement.findInput = function(){ return parentWin._findInput(iframeWin); };
+			iframeWin.frameElement.scrollMin = function(n){ parentWin._scroll(iframeWin,true,n); };
+			iframeWin.frameElement.scrollMax = function(n){ parentWin._scroll(iframeWin,false,n); };
+			iframeWin.frameElement.getBoundingRect = function(n){ return parentWin._getBoundingRect(iframeWin, n); };
+			iframeWin.frameElement.getVisibleSize = function(n){ return parentWin._getVisibleSize(iframeWin, n); };
+			iframeWin.frameElement.scrollIntoView = function(x,y,w,h){ parentWin._scrollIntoView(iframeWin,x,y,w,h); };
+			iframeWin.frameElement.onClick = function(e){ parentWin._onClick(iframeWin);return false; };
+		}
 
-		require(["dojo", "doh", "dojo/window", "dojo/domReady!"], function(dojo, doh) {
+		function _findInput(win){
+			return win.document.getElementById('it');
+		}
 
-			var usingNative = !(dojo.isMoz || dojo.isIE || dojo.isWebKit || dojo.isOpera);
-			var count = 0;
+		function _getBoundingRect(win, n){
+			var r = n.getBoundingClientRect();
+			return { left: r.left, right: r.right, top: r.top, bottom: r.bottom, w: Math.round(r.right - r.left), h: Math.round(r.bottom - r.top) };
+		}
 
-			innerScrollBarSize = dojo.byId("nonscroll").clientWidth - dojo.byId("withscroll").clientWidth;
+		function _scroll(win,isMin,n){
+			while(n && n.tagName){
+				n.scrollTop = isMin ? -9999 : 9999;
+				n.scrollLeft = isMin ? -9999 : 9999;
+				if(n.tagName == "BODY" && (n.scrollLeft || n.scrollTop)){
+					break; // skip HTML
+				}
+				n = n.parentNode;
+			}
+		}
+
+		var loaded = {};
+		function iframeLoaded(id){
+			if(!loaded[id]){	// ignore duplicate notifications
+				loaded[id] = true;
+				if(--count == 0){ loading.callback(true); }
+			}
+		}
+
+		require([
+			"doh",
+			"dojo/dom", "dojo/dom-attr", "dojo/dom-geometry", "dojo/dom-style",
+			"dojo/query", "dojo/sniff", "dojo/_base/window", "dojo/window", "dojo/_base/array", "dojo/domReady!"
+		], function(doh, dom, domAttr, domGeom, domStyle, query, has, baseWin, winUtils, array) {
+
+			// More global methods accessed by iframes
+			_scrollIntoView = function(win,x,y,w,h){
+				var n = _findInput(win);
+				var pos;
+				if(typeof x == "number" && typeof y == "number"){
+					var p = baseWin.withGlobal(win, 'position', domGeom, [ n ]);
+					pos = { x: p.x + x, y: p.y + y, w: isNaN(w) ? 1 : w, h: isNaN(h) ? 1 : h };
+				}
+				baseWin.withGlobal(win, 'scrollIntoView', winUtils, [ n, pos ]);
+			};
+			_onClick = function(win){
+				_scrollIntoView(win);
+			};
+
+			_getVisibleSize = function(win,n){
+				var	html = win.document.documentElement,
+					body = win.document.body,
+					rect = n.getBoundingClientRect(),
+					width = Math.min(body.clientWidth || html.clientWidth, html.clientWidth || body.clientWidth),
+					height = Math.min(body.clientHeight || html.clientHeight, html.clientHeight || body.clientHeight),
+					pos = baseWin.withGlobal(win, 'position', domGeom, [ n ]);
+				// adjust width and height for IE nonsense
+				width += Math.round(rect.left - pos.x);
+				height += Math.round(rect.top - pos.y);
+				if(has('ie')){ width += outerScrollBarSize; } // IE10 bug
+				for(y = 0; y < height; y++){
+					for(x = 0; x < width; x++){
+						var pointElement = win.document.elementFromPoint(x,y);
+						if(pointElement == n){
+							// work around browser bugs
+							// Opera 12.12 says the element is showing beyond the browser edge
+							// IE 10 says`
+							for(var w = 1; (x+w) < width && win.document.elementFromPoint(x+w,y) == n; w++);
+							for(var h = 1; (y+h) < height && win.document.elementFromPoint(x,y+h) == n; h++);
+							return { w: w, h: h };
+						}
+					}
+				}
+				return { w: 0, h: 0 };
+			};
+			
+
+			// Below is the magic code that creates the iframes from the given template.
+			// This should be generalized for other files to include.
+
+			function getIframeSrc(id, content, doctype, rtl){
+				content = content.replace(/"/g/*balance"*/,"'").replace(/iframe.javascript/g,"text/javascript").replace(/<input\b/ig,"<INPUT disabled ");
+				var iframeSrc = 'javascript:"';
+				// find browser specific CSS attributes
+				if(has("ie")){
+					content = content.replace(/IE([A-Z]_)/g, "$1");
+				}else if(has("webkit")){
+					content = content.replace(/WK([A-Z]_)/g, "$1");
+				}else if(has("mozilla")){
+					content = content.replace(/MZ([A-Z]_)/g, "$1");
+				}else if(has("opera")){
+					content = content.replace(/OP([A-Z]_)/g, "$1");
+				}
+				// find DOCTYPE specific CSS attributes
+				if(doctype=="strict"){
+					iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>\n";
+					content = content.replace(/[A-Z0-9_]*(\b|_)[SZ]_[A-Z0-9_]*/g, "");
+				}else if(doctype=="loose"){
+					iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n";
+					content = content.replace(/[A-Z0-9_]*(\b|_)[TZ]_[A-Z0-9_]*/g, "");
+				}else{
+					if(has("webkit")){
+						iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>\n"; // quirks: needed for WebKit's javascript: protocol
+					}
+					content = content.replace(/[A-Z0-9_]*(\b|_)[QZ]_[A-Z0-9_]*/g, "");
+				}
+				if(rtl){
+					content = content.replace(/[A-Z0-9_]*(\b|_)R_[A-Z0-9_]*/g, "");
+				}else{
+					content = content.replace(/[A-Z0-9_]*(\b|_)L_[A-Z0-9_]*/g, "");
+				}
+				content = content.replace(/\s*<(\/?)iframestyle>\s*/ig,"<$1"+"STYLE>");
+				var i = content.indexOf('<STYLE>');
+				var style = '';
+				if(i >= 0){
+					var j = content.indexOf('</STYLE>');
+					if(j >= 0){
+						style = content.substring(i+7, j);
+						content = content.substr(j+8);
+					}
+				}
+				iframeSrc +=
+				'<HTML dir='+(rtl?'rtl':'ltr')+'>'+
+				'<HEAD>'+
+					'<STYLE>'+
+						'* { border:0px solid white;padding:0px;margin:0px;font-style:normal;font-family:monospace;font-size:0px;line-height:normal; }\n'+
+						'INPUT { display:block;background-color:red;font-size:0px;line-height:0px;overflow:hidden;width:20px;height:20px; }\n'+
+						'UL { list-style-type: none;line-height:0px;width:45px;overflow:auto; }\n'+
+						'LI { list-style-type: none;line-height:20px;overflow:visible;max-width:20px;max-height:20px;height:20px;width:20px;float:left; }\n'+
+						'HR { width:120px;height:1px;visibility:hidden;display:block; }\n'+
+						style+
+					'<\/STYLE>'+
+				'<\/HEAD>'+
+				'<BODY BGCOLOR=#ffffff>'+
+					content+
+					'<SCRIPT type=text/javascript>'+
+						'win=frameElement.ownerDocument.defaultView||frameElement.document.parentWindow;'+
+						'win.initIframeMethods(window, win);'+
+						'win.iframeLoaded(\'' + id + "-" + doctype + "-" + (rtl ?'rtl':'ltr') + '\');'+
+						'document.body.onclick=frameElement.onClick;'+
+					'<\/SCRIPT>'+
+				'<\/BODY>'+
+				'<\/HTML>"';
+				return iframeSrc;
+			}
+
+			function makeIframe(id, className, style, content, doctype, rtl, srcNode){
+				var iframeSrc = getIframeSrc(id, content, doctype, rtl);
+				var container = document.createElement('fieldset');
+				var text = (doctype=="strict"? 'strict': (doctype=="loose"? 'loose' : 'quirks')) + (rtl? ' RTL' : '');
+				var color = (rtl? 'medium': '') + (doctype=="strict"? 'SpringGreen': (doctype=="loose"? 'Turquoise' : 'Aquamarine'));
+				var idSuffix = (doctype=="strict"? '_strict': (doctype=="loose"? '_loose': '_quirks')) + (rtl? '_rtl' : '');
+				domStyle.set(container, "cssText", "display:inline;border:1px ridge gray;padding:0px;margin:0px;background-color:"+color+";text-align:"+(rtl?"right;":"left;"));
+				container.appendChild(document.createTextNode(text));
+				var iframe = document.createElement('iframe');
+				iframe.setAttribute('src', iframeSrc);
+				iframe.setAttribute('frameBorder', "0");
+				iframe.setAttribute('scrolling', "auto");
+				iframe.setAttribute('allowTransparency', "true");
+				iframe.setAttribute('id', id + idSuffix);
+				iframe.setAttribute('name', id + idSuffix);
+				iframe.className = className;
+				domStyle.set(iframe, "cssText", "visibility:hidden;display:block;border:2px solid "+color+";background-color:transparent;margin:0px;padding:3px;"+style);
+				container.appendChild(iframe);
+				srcNode.appendChild(container);
+				var src = iframe.getAttribute("src");
+				if(!src || src.indexOf("javascript") == -1){
+					// set it again if it didn't stick the first time: esp. older Opera and WebKit
+					setTimeout(function(){ iframe.setAttribute('src', iframeSrc); }, 0);
+				}
+			}
+
+			var innerScrollBarSize = Math.ceil(dom.byId("nonscroll").clientWidth - dom.byId("withscroll").clientWidth);
 			console.debug('inner scrollbar size = ' + innerScrollBarSize);
-			outerScrollBarSize = (dojo.isIE >= 9) ? ((dojo.position(document.documentElement).w - document.documentElement.clientWidth) || innerScrollBarSize) : innerScrollBarSize;
+			var outerScrollBarSize = Math.ceil((has("ie") >= 9) ? ((domGeom.position(document.documentElement).w - document.documentElement.clientWidth) || innerScrollBarSize) : innerScrollBarSize);
 			console.debug('outer scrollbar size = ' + outerScrollBarSize);
+
 			doh.register("dojo.window.scroll",[
 				{
-					name: "wait for iframes to load",
+					name: "create iframes and wait for them to load",
 					timeout: 20000,
 					runTest: function(){
+						loading = new doh.Deferred();
+						var testIframes = query('DIV[type="testIframe"]');
+						count = testIframes.length * 4;
+						console.log("count is " + count);
+						// have to do all the iframes at once so the iPad doesn't resize and cause problems
+						for(var i=0; i < testIframes.length; i++){
+							var srcNode = testIframes[i];
+							var content = srcNode.innerHTML || '';
+							var id = srcNode.id || "";
+							var style = srcNode.getAttribute('style') || "";
+							var className = srcNode.getAttribute('class') || srcNode.className || "";
+							if(typeof style == "object"){
+								style = style.cssText || "";
+							}
+							srcNode.innerHTML = "";
+							srcNode.removeAttribute('style');
+							srcNode.className = "";
+
+							makeIframe(id, className, style, content, "strict", false, srcNode);
+							makeIframe(id, className, style, content, "quirks", false, srcNode);
+							makeIframe(id, className, style, content, "loose", true, srcNode);
+							makeIframe(id, className, style, content, "quirks", true, srcNode);
+						}
 						return loading;
 					}
 				},
 				function checkAttrs(){
-					var body = dojo.body();
-					dojo.window.scrollIntoView(body);
-					doh.f(dojo.hasAttr(body,'_offsetParent'));
-					doh.f(dojo.hasAttr(body,'_parent'));
-				},
-				function test_8249(){
-					generateTest('8249_strict', '(0,-10)', '(0,+10)');
-					generateTest('8249_quirks', '(0,-10)', '(0,+10)');
-					generateTest('8249_loose_rtl', '(0,-10)', '(0,+10)');
-					generateTest('8249_quirks_rtl', '(0,-10)', '(0,+10)');
-				},
-				function test_8284(){
-					var minScroll, maxScroll, fudge=0;
-					if(dojo.isIE <= 8){
-						minScroll = maxScroll = 11;
-						if(dojo.isIE <= 6){
-							fudge = dojo.byId('8284_quirks').contentWindow.document.body.clientHeight-100; // needed for running inside DOH runner
-						}
-					}else{
-						minScroll = maxScroll = 10;
-					}
-					generateTestXY('8284_quirks', "0", -maxScroll+fudge, "0", minScroll-fudge);
-					generateTestXY('8284_quirks_rtl', "0", -maxScroll+fudge, "0", minScroll-fudge);
-					if(dojo.isIE == 8){
-						minScroll = maxScroll = 10;
-					}
-					generateTestXY('8284_strict', "0", -maxScroll, "0", minScroll);
-					generateTestXY('8284_loose_rtl', "0", -maxScroll, "0", minScroll);
-				},
-				function test_absContent(){
-					generateTestXY('absContent_strict', 0, -10, 0, 10);
-					generateTestXY('absContent_loose_rtl', 0, -10, 0, 10);
-					generateTestXY('absContent_quirks', 0, -10, 0, 10);
-					generateTestXY('absContent_quirks_rtl', 0, -10, 0, 10);
-				},
-				function test_fixedNode(){
-					if(!(dojo.isIE <= 6)){
-						generateTest('fixedNode_strict', "(-1,-1)", "(+1,+1)");
-						generateTest('fixedNode_loose_rtl', "(-1,-1)", "(+1,+1)");
-					}
-					if(!dojo.isIE){
-						generateTest('fixedNode_quirks', "(-1,-1)", "(+1,+1)");
-						generateTest('fixedNode_quirks_rtl', "(-1,-1)", "(+1,+1)");
-					}
-				},
-				function test_fixedScrollable(){
-					if(!(dojo.isIE <= 6)){
-						generateTest('fixedScrollable_strict', dojo.isIE == 7? "(0,-54)(0,-1)" : "(0,-39)(0,-1)", dojo.isIE == 7? "(0,+39)(0,+1)" : "(0,+38)(0,+1)");
-						generateTest('fixedScrollable_loose_rtl', dojo.isIE == 7? "(0,-54)(0,-1)" : "(0,-39)(0,-1)", dojo.isIE == 7? "(0,+39)(0,+1)" : "(0,+38)(0,+1)");
-					}
-					if(!dojo.isIE){
-						generateTest('fixedScrollable_quirks', "(0,-39)(0,-1)", "(0,+38)(0,+1)");
-						generateTest('fixedScrollable_quirks_rtl', "(0,-39)(0,-1)", "(0,+38)(0,+1)");
-					}
-				},
-				function test_7036_8665(){
-					var maxScroll = 39;
-					var minScroll = 38;
-					if(dojo.isIE <= 7){
-						maxScroll = 54;
-						minScroll = 39;
-					}
-					generateTest('7036_8665_strict', "(0,-"+maxScroll+")(0,-1)", "(0,+"+minScroll+")(0,+1)");
-					generateTest('7036_8665_loose_rtl', "(0,-"+maxScroll+")(0,-1)", "(0,+"+minScroll+")(0,+1)");
-					if(dojo.isIE == 8){
-						maxScroll = 54;
-						minScroll = 39;
-					}
-					generateTest('7036_8665_quirks', "(0,-"+maxScroll+")(0,-1)", "(0,+"+minScroll+")(0,+1)");
-					generateTest('7036_8665_quirks_rtl', "(0,-"+maxScroll+")(0,-1)", "(0,+"+minScroll+")(0,+1)");
-				},
-				function test_innerNoScrollBars(){
-					var scroll;
-					if(dojo.isIE <= 6){
-						scroll = 53;
-					}else if(dojo.isIE == 7){
-						scroll = 46;
-					}else{
-						scroll = 39;
-					}
-					generateTestXY('innerNoScrollBars_strict', scroll, -29, scroll, -29);
-					if(dojo.isIE <= 8){
-						scroll = -38;
-					}
-					generateTestXY('innerNoScrollBars_quirks', scroll, -29, scroll, -29);
-					if(dojo.isIE <= 6){
-						scroll = 53;
-					}else if(dojo.isIE == 7){
-						scroll = 46;
-					}else if(dojo.isIE >= 8 || dojo.isOpera){
-						scroll = "0";
-					}else if(dojo.isWebKit){
-						scroll = "-0";
-					}else{
-						scroll = 39;
-					}
-					generateTestXY('innerNoScrollBars_loose_rtl', scroll, -29, scroll, -29);
-					if(dojo.isIE <= 8){
-						scroll = -38;
-					}
-					generateTestXY('innerNoScrollBars_quirks_rtl', scroll, -29, scroll, -29);
-				},
-				function test_noScrollBars(){
-					generateTest('noScrollBars_strict', "(0,0)", "(0,0)");
-					generateTest('noScrollBars_quirks', "(0,0)", "(0,0)");
-					generateTest('noScrollBars_loose_rtl', "(0,0)", "(0,0)");
-					generateTest('noScrollBars_quirks_rtl', "(0,0)", "(0,0)");
-				},
-				function test_table(){
-					var minScroll, maxScroll;
-					minScroll = "(0,+15)";
-					maxScroll = "(0,-15)";
-					generateTest('table_strict', maxScroll, minScroll);
-					generateTest('table_loose_rtl', maxScroll, minScroll);
-					if(dojo.isIE <= 6){
-						var fudge = dojo.byId('table_quirks').contentWindow.document.body.clientHeight-100; // needed for running inside DOH runner
-						maxScroll = "(0,-"+(15-fudge)+")";
-						minScroll = "(0,+"+(15-fudge)+")";
-					}
-					generateTest('table_quirks', maxScroll, minScroll);
-					generateTest('table_quirks_rtl', maxScroll, minScroll);
-				},
-				function test_innerScrollbars(){
-					var scroll = innerScrollBarSize - 5;
-					generateTestXY('innerScrollbars_strict', -scroll, -scroll, scroll, scroll);
-					generateTestXY('innerScrollbars_loose_rtl', -scroll, -scroll, dojo.isIE == 7 ? -25 : scroll, scroll);
-					generateTestXY('innerScrollbars_quirks', -scroll, -scroll, scroll, scroll);
-					generateTestXY('innerScrollbars_quirks_rtl', -scroll, -scroll, scroll, scroll);
-				},
-				function test_8542(){
-					var fudge = 0;
-					if(dojo.isIE <= 6){
-						fudge = dojo.byId('8542_quirks').contentWindow.document.body.clientHeight-100; // needed for running inside DOH runner
-					}
-					generateTest('8542_strict', "(0,-10)", "(0,+20)");
-					generateTest('8542_quirks', "(0,-"+(10-fudge)+")", "(0,+"+(20-fudge)+")");
-					generateTest('8542_loose_rtl', "(0,-10)", "(0,+20)");
-					generateTest('8542_quirks_rtl', "(0,-"+(10-fudge)+")", "(0,+"+(20-fudge)+")");
-				},
-				function test_tooBig(){
-					var fudge = 0;
-					if(dojo.isIE <= 6){
-						fudge = dojo.byId('tooBig_quirks').contentWindow.document.body.clientHeight-100+innerScrollBarSize; // needed for running inside DOH runner
-					}
-					var minScroll, maxScroll;
-					generateTestXY('tooBig_strict', outerScrollBarSize+10,outerScrollBarSize+20, 1,1);
-					generateTestXY('tooBig_quirks', outerScrollBarSize+10-fudge,outerScrollBarSize+20-fudge, 1,1);
-					if(dojo.isIE <= 7 || dojo.isMoz || dojo.isChrome){
-						maxScroll = -1;
-					}else if(dojo.isIE){
-						maxScroll = +20;
-					}else if(dojo.isOpera){
-						maxScroll = -90;
-					}else{
-						maxScroll = outerScrollBarSize+10;
-					}
-					if(dojo.isIE <= 7 || dojo.isMoz || dojo.isChrome){
-						minScroll = -20;
-					}else if(dojo.isOpera){
-						minScroll = 80 + outerScrollBarSize;
-					}else{
-						minScroll = 1;
-					}
-					generateTestXY('tooBig_loose_rtl', maxScroll,outerScrollBarSize+20, minScroll,1);
-					if(dojo.isIE >= 8){
-						maxScroll = -1;
-					}
-					if(dojo.isIE == 8){
-						minScroll = -20;
-					}
-					generateTestXY('tooBig_quirks_rtl', maxScroll,outerScrollBarSize+20-fudge, minScroll,1);
-				},
-				function test_htmlPadding(){
-					var fudge = 0;
-					if(dojo.isIE <= 6){
-						fudge = dojo.byId('tooBig_quirks').contentWindow.document.body.clientHeight-100+innerScrollBarSize; // needed for running inside DOH runner
-					}
-					var minScroll, maxScroll;
-					if(dojo.isIE <= 7){
-						maxScroll = minScroll = 84;
-					}else{
-						maxScroll = minScroll = 70;
-					}
-					generateTest('htmlPadding_strict', "(0,-"+maxScroll+")", "(0,+"+minScroll+")");
-					generateTest('htmlPadding_loose_rtl', "(0,-"+maxScroll+")", "(0,+"+minScroll+")");
-					if(dojo.isIE <= 8){
-						maxScroll = minScroll = 34;
-					}
-					generateTest('htmlPadding_quirks', "(0,-"+(maxScroll-fudge)+")", "(0,+"+(minScroll-fudge)+")");
-					generateTest('htmlPadding_quirks_rtl', "(0,-"+(maxScroll-fudge)+")", "(0,+"+(minScroll-fudge)+")");
+					var body = baseWin.body();
+					winUtils.scrollIntoView(body);
+					doh.f(domAttr.has(body,'_offsetParent'));
+					doh.f(domAttr.has(body,'_parent'));
 				}
 			]);
-			function generateTest(id, maxVal, minVal){
-				var compare = usingNative? "isNot" : "is";
-				with(dojo.byId(id)){
-					scrollMin();
-					scrollMax();
-					scrollIntoView();
-					var maxActualScroll = getScroll();
-					var maxExpectedScroll = usingNative? "(-1,-1)" : maxVal;
-					scrollIntoView(); // make sure the value sticks
-					var repMaxActualScroll = getScroll();
-					scrollMin();
-					scrollIntoView();
-					var minActualScroll = getScroll();
-					var minExpectedScroll = usingNative? "(+1,+1)" : minVal;
-					dojo.byId(id).style.visibility = 'visible';
-					doh[compare](maxExpectedScroll, maxActualScroll, id+" max failed");
-					doh[compare](maxExpectedScroll, repMaxActualScroll, id+" repeat max failed");
-					doh[compare](minExpectedScroll, minActualScroll, id+" min failed");
-				}
-			}
-			function generateTestXY(id, maxScrollX, maxScrollY, minScrollX, minScrollY){
-				if(typeof maxScrollX == "number" && maxScrollX > 0){ maxScrollX = "+" + maxScrollX; }
-				if(typeof maxScrollY == "number" && maxScrollY > 0){ maxScrollY = "+" + maxScrollY; }
-				if(typeof minScrollX == "number" && minScrollX > 0){ minScrollX = "+" + minScrollX; }
-				if(typeof minScrollY == "number" && minScrollY > 0){ minScrollY = "+" + minScrollY; }
-				generateTest(id, "("+maxScrollX+","+maxScrollY+")", "("+minScrollX+","+minScrollY+")");
-			}
+                        array.forEach([	'8249',
+					'8284',
+					'absContent',
+					'fixedNode',
+					'fixedScrollable',
+					'7036_8665',
+					'innerNoScrollBars',
+					'noScrollBars',
+					'table',
+					'innerScrollbars',
+					'8542',
+					'tooBig',
+					'htmlPadding' ],
+				function(test){
+                        		array.forEach([	"_strict", "_quirks", "_loose_rtl", "_quirks_rtl" ],
+						function(mode){
+							var	id = test+mode,
+								n, maxWidth, maxHeight, nodeWidth, nodeHeight, rAfterScroll, vAfterScroll, rBeforeScroll, vBeforeScroll;
+							doh.register(id, [
+							{
+								timeout: 4000,
+								name: "compare to native",
+								runTest: function(){ with(dom.byId(id)){
+									n = findInput();
+									scrollMin(n);
+									var d = new doh.Deferred();
+									setTimeout(function(){
+										rBeforeScroll = getBoundingRect(n);
+										vBeforeScroll = getVisibleSize(n);
+										nodeWidth = rBeforeScroll.w;
+										nodeHeight = rBeforeScroll.h;
+										dom.byId(id).style.visibility = 'visible';
+										n.scrollIntoView(true);
+										setTimeout(function(){
+											var vAfterNativeScroll = getVisibleSize(n);
+											scrollIntoView();
+											setTimeout(d.getTestCallback(function(){
+												vAfterScroll = getVisibleSize(n);
+												doh.t(vAfterScroll.w > 0, "min width " + vAfterScroll.w);
+												doh.t(vAfterScroll.h > 0, "min height " + vAfterScroll.h);
+												doh.t(vAfterScroll.w >= vAfterNativeScroll.w, "width compare " + vAfterNativeScroll.w + " to " + vAfterScroll.w);
+												doh.t(vAfterScroll.h >= vAfterNativeScroll.h, "height compare " + vAfterNativeScroll.h + " to " + vAfterScroll.h);
+												maxWidth = Math.max(vAfterNativeScroll.w, vAfterScroll.w);
+												maxHeight = Math.max(vAfterNativeScroll.h, vAfterScroll.h);
+											}), 0);
+										}, 0);
+									}, 0);
+									return d;
+								}}
+							},
+							{
+								timeout: 4000,
+								name: "min start horizontal",
+								runTest: function(){ with(dom.byId(id)){
+									scrollMin(n);
+									var d = new doh.Deferred();
+									setTimeout(function(){
+										scrollIntoView(1,0);
+										setTimeout(function(){
+											rAfterScroll = getBoundingRect(n);
+											vAfterScroll = getVisibleSize(n);
+											if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so all but leftmost pixel on first row is showing
+												scrollIntoView(0,0);
+												setTimeout(d.getTestCallback(function(){
+													doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "min: start: shift right partial width");
+													vAfterScroll = getVisibleSize(n);
+													doh.is(vAfterScroll.w, maxWidth, "min: start: shift right full width");
+												}), 0);
+											}else if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so only 2 leftmost pixels on first row are showing
+												scrollIntoView(nodeWidth-1,0);
+												setTimeout(d.getTestCallback(function(){
+													doh.is(2, vAfterScroll.w, "min: start: shift left width");
+													vAfterScroll = getVisibleSize(n);
+													doh.is(vAfterScroll.w, maxWidth, "min: start: shift left full width");
+												}), 0);
+											}else{ // no horizontal scrolling
+												scrollIntoView(0,0,nodeWidth);
+												setTimeout(d.getTestCallback(function(){
+													vAfterScroll = getVisibleSize(n);
+													doh.is(maxWidth, vAfterScroll.w, "min: start: no shift full width");
+												}), 0);
+											}
+										}, 0);
+									}, 0);
+									return d;
+								}}
+							},
+							{
+								timeout: 2000,
+								name: "min start vertical",
+								runTest: function(){ with(dom.byId(id)){
+									var d = new doh.Deferred();
+									if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so all rows are showing
+										scrollIntoView(1,nodeHeight-1);
+										setTimeout(d.getTestCallback(function(){
+											doh.is(vAfterScroll.h, maxHeight, "min: start: shift down height");
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "min: start: shift down full height");
+										}), 0);
+									}else if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so only the first row is showing
+										scrollIntoView(0,nodeHeight-1);
+										setTimeout(d.getTestCallback(function(){
+											doh.is(1, vAfterScroll.h, "min: start: shift up height");
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "min: start: shift up full height");
+										}), 0);
+									}else{ // no vertical scrolling
+										scrollIntoView(0,nodeHeight-1);
+										setTimeout(d.getTestCallback(function(){
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "min: start: no shift full height");
+										}), 0);
+									}
+									return d;
+								}}
+							},
+							{
+								timeout: 4000,
+								name: "min end horizontal",
+								runTest: function(){ with(dom.byId(id)){
+									scrollMin(n);
+									var d = new doh.Deferred();
+									setTimeout(function(){
+										scrollIntoView(nodeWidth-2,nodeHeight-1);
+										setTimeout(function(){
+											rAfterScroll = getBoundingRect(n);
+											vAfterScroll = getVisibleSize(n);
+											if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so all but rightmost pixel on first row is showing
+												scrollIntoView(nodeWidth-1,nodeHeight-1);
+												setTimeout(d.getTestCallback(function(){
+													doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "min: end: shift left partial width");
+													vAfterScroll = getVisibleSize(n);
+													doh.is(vAfterScroll.w, maxWidth, "min: end: shift left full width");
+												}), 0);
+											}else if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so only 2 rightmost pixels on first row are showing
+												scrollIntoView(0,nodeHeight-1);
+												setTimeout(d.getTestCallback(function(){
+													doh.is(2, vAfterScroll.w, "min: end: shift right width");
+													vAfterScroll = getVisibleSize(n);
+													doh.is(vAfterScroll.w, maxWidth, "min: end: shift right full width");
+												}), 0);
+											}else{ // no horizontal scrolling
+												scrollIntoView(0,nodeHeight-1,nodeWidth);
+												setTimeout(d.getTestCallback(function(){
+													vAfterScroll = getVisibleSize(n);
+													doh.is(vAfterScroll.w, maxWidth, "min: end: no shift full width");
+												}), 0);
+											}
+										}, 0);
+									}, 0);
+									return d;
+								}}
+							},
+							{
+								timeout: 2000,
+								name: "min end vertical",
+								runTest: function(){ with(dom.byId(id)){
+									var d = new doh.Deferred();
+									if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so all rows are showing
+										scrollIntoView(nodeWidth-1,0);
+										setTimeout(d.getTestCallback(function(){
+											doh.is(vAfterScroll.h, maxHeight, "min: end: shift up height");
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "min: end: shift up full height");
+										}), 0);
+									}else if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so only the last row is showing
+										scrollIntoView(0,0);
+										setTimeout(d.getTestCallback(function(){
+											doh.is(1, vAfterScroll.h, "min: end: shift down height");
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "min: end: shift down full height");
+										}), 0);
+									}else{ // no vertical scrolling
+										scrollIntoView(0,nodeHeight-1);
+										setTimeout(d.getTestCallback(function(){
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "min: end: no shift full height");
+										}), 0);
+									}
+									return d;
+								}}
+							},
+							{
+								timeout: 4000,
+								name: "max start horizontal",
+								runTest: function(){ with(dom.byId(id)){
+									scrollMax(n);
+									var d = new doh.Deferred();
+									setTimeout(function(){
+										rBeforeScroll = getBoundingRect(n);
+										vBeforeScroll = getVisibleSize(n);
+										scrollIntoView(1,0);
+										setTimeout(function(){
+											rAfterScroll = getBoundingRect(n);
+											vAfterScroll = getVisibleSize(n);
+											if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so all but leftmost pixel on first row is showing
+												scrollIntoView(0,0);
+												setTimeout(d.getTestCallback(function(){
+													doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "max: start: shift right partial width");
+													vAfterScroll = getVisibleSize(n);
+													doh.is(vAfterScroll.w, maxWidth, "max: start: shift right full width");
+												}), 0);
+											}else if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so only 2 leftmost pixels on first row are showing
+												scrollIntoView(nodeWidth-1,0);
+												setTimeout(d.getTestCallback(function(){
+													doh.is(2, vAfterScroll.w, "max: start: shift left width");
+													vAfterScroll = getVisibleSize(n);
+													doh.is(vAfterScroll.w, maxWidth, "max: start: shift left full width");
+												}), 0);
+											}else{ // no horizontal scrolling
+												scrollIntoView(0,0,nodeWidth);
+												setTimeout(d.getTestCallback(function(){
+													vAfterScroll = getVisibleSize(n);
+													doh.is(vAfterScroll.w, maxWidth, "max: start: no shift full width");
+												}), 0);
+											}
+										}, 0);
+									}, 0);
+									return d;
+								}}
+							},
+							{
+								timeout: 2000,
+								name: "max start vertical",
+								runTest: function(){ with(dom.byId(id)){
+									var d = new doh.Deferred();
+									if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so all rows are showing
+										scrollIntoView(1,nodeHeight-1);
+										setTimeout(d.getTestCallback(function(){
+											doh.is(vAfterScroll.h, maxHeight, "max: start: shift down height");
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "max: start: shift down full height");
+										}), 0);
+									}else if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so only the first row is showing
+										scrollIntoView(0,nodeHeight-1);
+										setTimeout(d.getTestCallback(function(){
+											doh.is(1, vAfterScroll.h, "max: start: shift up height");
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "max: start: shift up full height");
+										}), 0);
+									}else{ // no vertical scrolling
+										scrollIntoView(0,nodeHeight-1);
+										setTimeout(d.getTestCallback(function(){
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "max: start: no shift full height");
+										}), 0);
+									}
+									return d;
+								}}
+							},
+							{
+								timeout: 4000,
+								name: "max end horizontal",
+								runTest: function(){ with(dom.byId(id)){
+									scrollMax(n);
+									var d = new doh.Deferred();
+									setTimeout(function(){
+										scrollIntoView(nodeWidth-2,nodeHeight-1);
+										setTimeout(function(){
+											rAfterScroll = getBoundingRect(n);
+											vAfterScroll = getVisibleSize(n);
+											if(rAfterScroll.left < rBeforeScroll.left){ // shifted left so all but rightmost pixel on first row is showing
+												scrollIntoView(nodeWidth-1,nodeHeight-1);
+												setTimeout(d.getTestCallback(function(){
+													doh.is(nodeWidth > maxWidth ? maxWidth : (maxWidth-1), vAfterScroll.w, "max: end: shift left partial width");
+													vAfterScroll = getVisibleSize(n);
+													doh.is(vAfterScroll.w, maxWidth, "max: end: shift left full width");
+												}), 0);
+											}else if(rAfterScroll.left > rBeforeScroll.left){ // shifted right so only 2 rightmost pixels on first row are showing
+												scrollIntoView(0,nodeHeight-1);
+												setTimeout(d.getTestCallback(function(){
+													doh.is(2, vAfterScroll.w, "max: end: shift right width");
+													vAfterScroll = getVisibleSize(n);
+													doh.is(vAfterScroll.w, maxWidth, "max: end: shift right full width");
+												}), 0);
+											}else{ // no horizontal scrolling
+												scrollIntoView(0,nodeHeight-1,nodeWidth);
+												setTimeout(d.getTestCallback(function(){
+													vAfterScroll = getVisibleSize(n);
+													doh.is(vAfterScroll.w, maxWidth, "max: end: no shift full width");
+												}), 0);
+											}
+										}, 0);
+									}, 0);
+									return d;
+								}}
+							},
+							{
+								timeout: 2000,
+								name: "max end vertical",
+								runTest: function(){ with(dom.byId(id)){
+									var d = new doh.Deferred();
+									if(rAfterScroll.top < rBeforeScroll.top){ // shifted up so all rows are showing
+										scrollIntoView(nodeWidth-1,0);
+										setTimeout(d.getTestCallback(function(){
+											doh.is(vAfterScroll.h, maxHeight, "max: end: shift up height");
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "max: end: shift up full height");
+										}), 0);
+									}else if(rAfterScroll.top > rBeforeScroll.top){ // shifted down so only the last row is showing
+										scrollIntoView(0,0);
+										setTimeout(d.getTestCallback(function(){
+											doh.is(1, vAfterScroll.h, "max: end: shift down height");
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "max: end: shift down full height");
+										}), 0);
+									}else{ // no vertical scrolling
+										scrollIntoView(0,0);
+										setTimeout(d.getTestCallback(function(){
+											vAfterScroll = getVisibleSize(n);
+											doh.is(vAfterScroll.h, maxHeight, "max: end: no shift full height");
+										}), 0);
+									}
+									return d;
+								}}
+							}]);
+						}
+					);
+				} 
+			);
+
 			doh.run();
 		});
 	</script>
@@ -270,17 +575,19 @@
 <fieldset>
 <label for="8249">Scrollable parent != offsetParent:</label>
 <div type="testIframe" id="8249">
-	<iframestyle>INPUT { float:left; }</iframestyle>
-	<div style="border-width:13px;"
-		><ul style="height:70px;"
-			><li><input style="background-color:white;"></li
-			><li><input style="background-color:white;"></li
-			><li><input style="background-color:white;"></li
-			><li><input id=it></li
-			><li><input style="background-color:white;"></li
-			><li><input style="background-color:white;"></li
-			><li><input style="background-color:white;"></li
-		></ul
+	<iframestyle>INPUT { float:left; }
+		HTML, BODY { overflow: hidden; }
+	</iframestyle>
+	<div style="height:61px;width:50px;overflow-y:scroll;margin:11px 20px"
+		><p style="display:inline;"
+		><li><input style="visibility:hidden;"></li
+		><li><input style="visibility:hidden;"></li
+		><li><input style="visibility:hidden;"></li
+		><li><input id=it></li
+		><li><input style="visibility:hidden;"></li
+		><li><input style="visibility:hidden;"></li
+		><li><input style="visibility:hidden;"></li
+		></p
 	></div>
 </div>
 </fieldset>
@@ -313,10 +620,10 @@
 <fieldset>
 <label for="fixedScrollable">Fixed-positioned scrollable content:</label>
 <div type="testIframe" id="fixedScrollable">
-	<iframestyle>HTML { overflow-x:hidden !important; /*IE6*/ }
-		INPUT { height:20px; MZT_MZQ_WKT_WKQ_IEQ_OPQ_OPT_height:28px; width:20px; MZT_MZQ_WKT_WKQ_IEQ_OPQ_OPT_width:28px; }</iframestyle>
-	<div style="height:120px;width:70px;overflow-y:scroll;position:fixed;margin:-10px 0px 0px 0px;">
-		<input id=it style="margin:120px 0px;border:1px solid red;padding:3px;">
+	<iframestyle>HTML { overflow:hidden !important; /*IE6*/ }
+		INPUT { height:20px; width:20px; }</iframestyle>
+	<div style="height:100px;width:70px;overflow-y:scroll;position:fixed;top:0px;left:0;">
+		<input id=it style="margin:120px 0px;">
 		<hr style="width:10px;">
 	</div>
 	<hr style="height:200px;width:20px;"/>
@@ -325,9 +632,9 @@
 <fieldset>
 <label for="7036_8665">Double scrollbars with absolute positioned content:</label>
 <div type="testIframe" id="7036_8665">
-	<iframestyle>INPUT { height:20px; MZT_MZQ_WKT_WKQ_IEQ_OPQ_OPT_height:28px; width:20px; MZT_MZQ_WKT_WKQ_IEQ_OPQ_OPT_width:28px; }</iframestyle>
+	<iframestyle>INPUT { height:28px; width:28px; }</iframestyle>
 	<div style="height:70px;width:70px;overflow-y:scroll;position:absolute;top:26px;left:5px;"
-		><input id=it style="margin:80px 0px 80px 0px;border:1px solid red;padding:3px;"
+		><input id=it style="margin:80px 0px 80px 0px;"
 		><hr style="width:10px;"
 	></div>
 	<div style="height:26px;width:10px;position:absolute;top:96px;left:10px;"></div>
@@ -341,9 +648,9 @@
 	><div style="overflow:hidden; width:20px;height:20px;"
 		><fieldset style="width:59px;overflow:visible;"
 			><input style="background-color:green;height:15px;float:left;"
-			><nobr style="margin:7px;padding:3px;border:5px solid pink;overflow:visible;display:block;width:90px;float:left;"
+			><nobr style="margin:7px;padding:3px;border:5px solid black;overflow:visible;display:block;width:90px;float:left;"
 				><input style="background-color:black;display:inline;width:24px;height:24px;float:left;"
-				><input id=it style="background-color:red;display:inline;float:left;"
+				><input id=it style="display:inline;float:left;"
 				><input style="background-color:blue;display:inline;width:16px;height:16px;float:left;"
 			></nobr
 			><input style="background-color:cyan;height:10px;float:left;"
@@ -380,9 +687,9 @@
 		TABLE { OPR_float:left; }
 	</iframestyle>
 	<div style="overflow:scroll;height:80px;width:80px;"
-		><fieldset
-			><table cellspacing="25" cellpadding="0" border="0"
-				><tr><td><input id=it style="width:50px;height:50px;float:left;"></td></tr
+		><fieldset style="visibility:hidden;"
+			><table cellspacing="65" cellpadding="0" border="0"
+				><tr><td><input id=it style="width:50px;height:50px;clear:both;float:left;visibility:visible;"></td></tr
 			></table
 		></fieldset
 	></div>
@@ -421,204 +728,5 @@
 </div>
 </fieldset>
 <br>
-<!--	Below is the magic code that creates the iframes from the given template.
-	This should be generalized for other files to include. -->
-<script>
-	function _findInput(win){
-		return win.document.getElementById('it');
-	}
-	function _scrollMin(win){
-		var n = _findInput(win);
-		while(n && n.tagName){
-			n.scrollTop = -9999;
-			n.scrollLeft = -9999;
-			n._scrollMinY = n.scrollTop;
-			n._scrollMinX = n.scrollLeft;
-			n.scrollTop++;
-			if(((n._scrollMaxX||0)-n._scrollMinX) == innerScrollBarSize && (n.scrollWidth <= n.clientWidth || n.scrollWidth <= n.offsetWidth)){ // ignore fake scrolls
-			}else if((n._scrollMaxX||0) > n._scrollMinX){
-				n.scrollLeft++;
-			}
-			if(n.tagName == "BODY" && (n.scrollLeft || n.scrollTop)){ break; }
-			n = n.parentNode;
-		}
-	}
-	function _scrollMax(win){
-		var n = _findInput(win);
-		while(n && n.tagName){
-			n.scrollTop = 9999;
-			n.scrollLeft = 9999;
-			n._scrollMaxY = n.scrollTop;
-			n._scrollMaxX = n.scrollLeft;
-			n.scrollTop--;
-			if((n._scrollMaxX-(n._scrollMinX||0)) == innerScrollBarSize && (n.scrollWidth <= n.clientWidth || n.scrollWidth <= n.offsetWidth)){
-				n._scrollMaxX = n.scrollLeft = (n._scrollMinX || 0); // ignore fake scrolls
-			}else{
-				n.scrollLeft--;
-			}
-			if(n.tagName == "BODY" && (n.scrollLeft || n.scrollTop || n._scrollMaxY || n._scrollMaxX)){
-				break; // skip HTML
-			}
-			n = n.parentNode;
-		}
-	}
-	function _getScroll(win){
-		var n = _findInput(win), scroll = '';
-		while(n && n.tagName){
-			var left = n.scrollLeft - n._scrollMinX,
-			top = n.scrollTop - n._scrollMinY,
-			right = n._scrollMaxX - n.scrollLeft,
-			bottom = n._scrollMaxY - n.scrollTop;
-			if(left || top || n._scrollMinX || n._scrollMaxX || n._scrollMinY || n._scrollMaxY){
-				//scroll += '('+(left<=right?((left==right?'':'+')+left):(right<0 ? '0' : ('-'+right)))+','+(top<=bottom?((top==bottom?'':'+')+top):(bottom<0 ? '0' : ('-'+bottom)))+')';
-				scroll += "(";
-				if(left <= right){
-					scroll += (left != right && left > 0 ? "+" : "") + left;
-				}else{
-					scroll += right < 0 ? '0' : ('-' + right);
-				}
-				scroll += ",";
-				if(top <= bottom){
-					scroll += (top != bottom && top > 0 ? "+" : "") + top;
-				}else{
-					scroll += bottom < 0 ? '0' : ('-' + bottom);
-				}
-				scroll += ")";
-			}
-			n = n.parentNode;
-		}
-		return scroll || '(0,0)';
-	}
-	function _scrollIntoView(win){
-		var n = _findInput(win);
-		dojo.withGlobal(win, 'scrollIntoView', dojo.window, [n]);
-	}
-	function _onClick(win){
-		_scrollIntoView(win);
-		alert(_getScroll(win));
-	}
-	function iframeLoaded(){
-		if(--count == 0){ loading.callback(true); }
-	}
-	function initIframeMethods(iframeWin, parentWin){
-		iframeWin.frameElement.findInput = function(){ return parentWin._findInput(iframeWin) };
-		iframeWin.frameElement.scrollMin = function(){ parentWin._scrollMin(iframeWin) };
-		iframeWin.frameElement.scrollMax = function(){ parentWin._scrollMax(iframeWin) };
-		iframeWin.frameElement.getScroll = function(){ return parentWin._getScroll(iframeWin) };
-		iframeWin.frameElement.scrollIntoView = function(){ parentWin._scrollIntoView(iframeWin) };
-		iframeWin.frameElement.onClick = function(){ parentWin._onClick(iframeWin) };
-	}
-	function getIframeSrc(content, doctype, rtl){
-		content = content.replace(/"/g/*balance"*/,"'").replace(/iframe.javascript/g,"text/javascript").replace(/<input\b/ig,"<INPUT readOnly ");
-		var iframeSrc = 'javascript:"';
-		// find browser specific CSS attributes
-		if(dojo.isIE){
-			content = content.replace(/IE([A-Z]_)/g, "$1");
-		}else if(dojo.isWebKit){
-			content = content.replace(/WK([A-Z]_)/g, "$1");
-		}else if(dojo.isMoz){
-			content = content.replace(/MZ([A-Z]_)/g, "$1");
-		}else if(dojo.isOpera){
-			content = content.replace(/OP([A-Z]_)/g, "$1");
-		}
-		// find DOCTYPE specific CSS attributes
-		if(doctype=="strict"){
-			iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>\n";
-			content = content.replace(/[A-Z0-9_]*(\b|_)[SZ]_[A-Z0-9_]*/g, "");
-		}else if(doctype=="loose"){
-			iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0 Transitional//EN' 'http://www.w3.org/TR/html4/loose.dtd'>\n";
-			content = content.replace(/[A-Z0-9_]*(\b|_)[TZ]_[A-Z0-9_]*/g, "");
-		}else{
-			if(dojo.isWebKit){
-				iframeSrc += "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>\n"; // quirks: needed for WebKit's javascript: protocol
-			}
-			content = content.replace(/[A-Z0-9_]*(\b|_)[QZ]_[A-Z0-9_]*/g, "");
-		}
-		if(rtl){
-			content = content.replace(/[A-Z0-9_]*(\b|_)R_[A-Z0-9_]*/g, "");
-		}else{
-			content = content.replace(/[A-Z0-9_]*(\b|_)L_[A-Z0-9_]*/g, "");
-		}
-		content = content.replace(/\s*<(\/?)iframestyle>\s*/ig,"<$1"+"STYLE>");
-		var i = content.indexOf('<STYLE>');
-		var style = '';
-		if(i >= 0){
-			var j = content.indexOf('</STYLE>');
-			if(j >= 0){
-				style = content.substring(i+7, j);
-				content = content.substr(j+8);
-			}
-		}
-		iframeSrc +=
-		'<HTML dir='+(rtl?'rtl':'ltr')+'>'+
-		'<HEAD>'+
-			'<STYLE>'+
-				'* { border:0px solid white;padding:0px;margin:0px;font-style:normal;font-family:monospace;font-size:0px;line-height:normal; }\n'+
-				'INPUT { display:block;background-color:#ff0000;font-size:0px;line-height:0px;overflow:hidden;width:20px;height:20px; }\n'+
-				'UL { list-style-type: none;line-height:0px;width:45px;overflow:auto; }\n'+
-				'LI { list-style-type: none;line-height:20px;overflow:visible;max-width:20px;max-height:20px;height:20px;width:20px;float:left; }\n'+
-				'HR { width:120px;height:1px;visibility:hidden;display:block; }\n'+
-				style+
-			'<\/STYLE>'+
-		'<\/HEAD>'+
-		'<BODY BGCOLOR=#ffffff>'+
-			content+
-			'<SCRIPT type=text/javascript>'+
-				'win=frameElement.ownerDocument.defaultView||frameElement.document.parentWindow;'+
-				'win.initIframeMethods(window, win);'+
-				'win.iframeLoaded();'+
-				'document.body.onclick=frameElement.onClick;'+
-			'<\/SCRIPT>'+
-		'<\/BODY>'+
-		'<\/HTML>"';
-		return iframeSrc;
-	}
-
-	function makeIframe(doctype, rtl){
-		var iframeSrc = getIframeSrc(content, doctype, rtl);
-		var container = document.createElement('fieldset');
-		var text = (doctype=="strict"? 'strict': (doctype=="loose"? 'loose' : 'quirks')) + (rtl? ' RTL' : '');
-		var color = (rtl? 'medium': '') + (doctype=="strict"? 'SpringGreen': (doctype=="loose"? 'Turquoise' : 'Aquamarine'));
-		var idSuffix = (doctype=="strict"? '_strict': (doctype=="loose"? '_loose': '_quirks')) + (rtl? '_rtl' : '');
-		dojo.style(container, "cssText", "display:inline;border:1px ridge gray;padding:0px;margin:0px;background-color:"+color+";text-align:"+(rtl?"right;":"left;"));
-		container.appendChild(document.createTextNode(text));
-		var iframe = document.createElement('iframe');
-		iframe.setAttribute('src', iframeSrc);
-		iframe.setAttribute('frameBorder', "0");
-		iframe.setAttribute('scrolling', "auto");
-		iframe.setAttribute('allowTransparency', "true");
-		iframe.setAttribute('id', id + idSuffix);
-		iframe.setAttribute('name', id + idSuffix);
-		iframe.className = className;
-		dojo.style(iframe, "cssText", "visibility:hidden;display:block;border:2px solid "+color+";background-color:transparent;margin:0px;padding:3px;"+style);
-		container.appendChild(iframe);
-		srcNode.appendChild(container);
-		var src = iframe.getAttribute("src");
-		if(!src || src.indexOf("javascript") == -1){
-			// set it again if it didn't stick the first time: esp. older Opera and WebKit
-			setTimeout(function(){ iframe.setAttribute('src', iframeSrc); }, 0);
-		}
-	}
-	var testIframes = dojo.query('DIV[type="testIframe"]');
-	count = testIframes.length * 4;
-	for(var i=0; i < testIframes.length; i++){
-		var srcNode = testIframes[i];
-		var content = srcNode.innerHTML || '';
-		var id = srcNode.id || "";
-		var style = srcNode.getAttribute('style') || "";
-		var className = srcNode.getAttribute('class') || srcNode.className || "";
-		if(typeof style == "object"){
-			style = style.cssText || "";
-		}
-		srcNode.innerHTML = "";
-		srcNode.removeAttribute('style');
-		srcNode.className = "";
-
-		makeIframe("strict", false);
-		makeIframe("quirks", false);
-		makeIframe("loose", true);
-		makeIframe("quirks", true);
-	}
-</script>
 </body>
 </html>
diff --git a/dojo/tests/window/test_scrollNoDTD.html b/dojo/tests/window/test_scrollNoDTD.html
index 1b5f222..4167f6e 100644
--- a/dojo/tests/window/test_scrollNoDTD.html
+++ b/dojo/tests/window/test_scrollNoDTD.html
@@ -6,25 +6,23 @@
 		@import "../../resources/dojo.css";
 	</style>
 	<script type="text/javascript" src="../../dojo.js"
-		djConfig="isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojo.window");
-
-		dojo.addOnLoad(function(){
+		require(["doh", "dojo/dom", "dojo/dom-geometry", "dojo/sniff", "dojo/window", "dojo/domReady!"],
+				function(doh, dom, domGeom, has, winUtils){
 			doh.register("window.scrollNoDTD",
 				function scrollIntoView(){
-					dojo.global.scrollTo(100,100);
-					var s2 = dojo.byId('s2');
+					scrollTo(100,100);
+					var s2 = dom.byId('s2');
 					s2.scrollTop = s2.scrollLeft = 10;
-					dojo.window.scrollIntoView('q2');
-					doh.is((dojo.isMoz && !dojo._isBodyLtr())? -87 : 87, s2.scrollLeft);
+					winUtils.scrollIntoView('q2');
+					doh.is((has("mozilla") && !domGeom.isBodyLtr())? -87 : 87, s2.scrollLeft);
 					doh.is(113, s2.scrollTop);
 					doh.f(dojo.hasAttr(s2,'_offsetParent'));
 					doh.f(dojo.hasAttr(s2,'_parent'));
 					doh.f(dojo.hasAttr(s2,'_child'));
-					dojo.global.scrollTo(!dojo._isBodyLtr() ? 4000 : 0, 4000);
+					scrollTo(!domGeom.isBodyLtr() ? 4000 : 0, 4000);
 				}
 			);
 			doh.run();
diff --git a/dojo/tests/window/test_scrollStrictDTD.html b/dojo/tests/window/test_scrollStrictDTD.html
index ee9a1f7..e79bf78 100644
--- a/dojo/tests/window/test_scrollStrictDTD.html
+++ b/dojo/tests/window/test_scrollStrictDTD.html
@@ -8,25 +8,23 @@
 		@import "../../../dojo/resources/dojo.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojo.window");
-
-		dojo.addOnLoad(function(){
+		require(["doh", "dojo/dom", "dojo/dom-geometry", "dojo/sniff", "dojo/window", "dojo/domReady!"],
+				function(doh, dom, domGeom, has, winUtils){
 			doh.register("dojo.window.scroll",
 				function scrollIntoView(){
-					dojo.global.scrollTo(100,100);
-					var s2 = dojo.byId('s2');
+					scrollTo(100,100);
+					var s2 = dom.byId('s2');
 					s2.scrollTop = s2.scrollLeft = 10;
-					dojo.window.scrollIntoView('q2');
-					doh.is((dojo.isMoz && !dojo._isBodyLtr())? -87 : 87, s2.scrollLeft);
+					winUtils.scrollIntoView('q2');
+					doh.is((has("mozilla") && !domGeom.isBodyLtr())? -87 : 87, s2.scrollLeft);
 					doh.is(113, s2.scrollTop);
 					doh.f(dojo.hasAttr(s2,'_offsetParent'));
 					doh.f(dojo.hasAttr(s2,'_parent'));
 					doh.f(dojo.hasAttr(s2,'_child'));
-					dojo.global.scrollTo(!dojo._isBodyLtr() ? 4000 : 0, 4000);
+					scrollTo(!domGeom.isBodyLtr() ? 4000 : 0, 4000);
 				}
 			);
 			doh.run();
diff --git a/dojo/tests/window/viewport.html b/dojo/tests/window/viewport.html
index f0089c4..2bb6e83 100644
--- a/dojo/tests/window/viewport.html
+++ b/dojo/tests/window/viewport.html
@@ -10,25 +10,25 @@
 	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 
 	<script type="text/javascript">
-		require(["dojo", "doh", "dojo/window", "dojo/domReady!"], function(dojo, doh){
+		require(["doh", "dojo/dom", "dojo/dom-geometry", "dojo/window", "dojo/domReady!"], function(doh, dom, domGeom, winUtils){
 			function compute(){
-				var d = dojo.marginBox(dojo.byId("documentBorder")),
-					v = dojo.window.getBox();
-				dojo.byId("results").innerHTML +=
+				var d = domGeom.getMarginBox(dom.byId("documentBorder")),
+					v = winUtils.getBox();
+				dom.byId("results").innerHTML +=
 					"Document is " + d.w + "px x " + d.h + "px" +
 					", viewport is " + v.w + "px x " + v.h + "px" +
 					", with scroll offset of (" + v.l + ", " + v.t + ")<br>";
 			}
  
 			function addText(){
-				dojo.byId("results").innerHTML += "Adding text...<br><br>";
+				dom.byId("results").innerHTML += "Adding text...<br><br>";
 				var text=[];
 				for(var i=0;i<100;i++){
 					text.push("<span style='white-space: nowrap'>");
 					for(var j=0;j<3;j++){ text.push("Now is the time for all good men to come to the aid of their country."); }
 					text.push("</span><br>");
 				}
-				dojo.byId("documentBorder").innerHTML += text.join("\n");
+				dom.byId("documentBorder").innerHTML += text.join("\n");
 			}
 
 			doh.register("dojo.window.viewport", [
@@ -36,17 +36,17 @@
 						console.log("calling compute");
 						compute();
 						console.log("called compute");
-						var d = dojo.marginBox(dojo.byId("documentBorder")),
-							v = dojo.window.getBox();
+						var d = domGeom.getMarginBox(dom.byId("documentBorder")),
+							v = winUtils.getBox();
 						doh.t(v.h > d.h, "test that viewport is bigger than document");
 						console.log("v.h is " + v.h + " and d.h is " + d.h);
 					},
 					function expand(t){
-						var v = dojo.window.getBox();
+						var v = winUtils.getBox();
 						console.log("calling addText");
 						addText();
 						compute();
-						var v2 = dojo.window.getBox();
+						var v2 = winUtils.getBox();
 						doh.t(v2.h <= v.h, "test that viewport didn't increase in size due to text added to document");
 						doh.t(v2.h+20 >= v.h, "test that viewport didn't shrink, except for space taken by scrollbars");
 						console.log("end");
diff --git a/dojo/text.js b/dojo/text.js
index f5deb51..752b3d2 100644
--- a/dojo/text.js
+++ b/dojo/text.js
@@ -1,23 +1,15 @@
-define(["./_base/kernel", "require", "./has", "./has!host-browser?./_base/xhr"], function(dojo, require, has, xhr){
+define(["./_base/kernel", "require", "./has", "./has!host-browser?./request"], function(dojo, require, has, request){
 	// module:
 	//		dojo/text
-	// summary:
-	//		This module implements the !dojo/text plugin and the dojo.cache API.
-	// description:
-	//		We choose to include our own plugin to leverage functionality already contained in dojo
-	//		and thereby reduce the size of the plugin compared to various foreign loader implementations.
-	//		Also, this allows foreign AMD loaders to be used without their plugins.
-	//
-	//		CAUTION: this module is designed to optionally function synchronously to support the dojo v1.x synchronous
-	//		loader. This feature is outside the scope of the CommonJS plugins specification.
 
 	var getText;
 	if(has("host-browser")){
 		getText= function(url, sync, load){
-			xhr("GET", {url:url, sync:!!sync, load:load});
+			request(url, {sync:!!sync}).then(load);
 		};
 	}else{
-		// TODOC: only works for dojo AMD loader
+		// Path for node.js and rhino, to load from local file system.
+		// TODO: use node.js native methods rather than depending on a require.getText() method to exist.
 		if(require.getText){
 			getText= require.getText;
 		}else{
@@ -26,7 +18,7 @@ define(["./_base/kernel", "require", "./has", "./has!host-browser?./_base/xhr"],
 	}
 
 	var
-		theCache= {},
+		theCache = {},
 
 		strip= function(text){
 			//Strips <?xml ...?> declarations so that external SVG and XML
@@ -46,64 +38,63 @@ define(["./_base/kernel", "require", "./has", "./has!host-browser?./_base/xhr"],
 
 		notFound = {},
 
-		pending = {},
+		pending = {};
 
-		result= {
-			dynamic:
-				// the dojo/text caches it's own resources because of dojo.cache
-				true,
+	dojo.cache = function(/*String||Object*/module, /*String*/url, /*String||Object?*/value){
+		// summary:
+		//		A getter and setter for storing the string content associated with the
+		//		module and url arguments.
+		// description:
+		//		If module is a string that contains slashes, then it is interpretted as a fully
+		//		resolved path (typically a result returned by require.toUrl), and url should not be
+		//		provided. This is the preferred signature. If module is a string that does not
+		//		contain slashes, then url must also be provided and module and url are used to
+		//		call `dojo.moduleUrl()` to generate a module URL. This signature is deprecated.
+		//		If value is specified, the cache value for the moduleUrl will be set to
+		//		that value. Otherwise, dojo.cache will fetch the moduleUrl and store it
+		//		in its internal cache and return that cached value for the URL. To clear
+		//		a cache value pass null for value. Since XMLHttpRequest (XHR) is used to fetch the
+		//		the URL contents, only modules on the same domain of the page can use this capability.
+		//		The build system can inline the cache values though, to allow for xdomain hosting.
+		// module: String||Object
+		//		If a String with slashes, a fully resolved path; if a String without slashes, the
+		//		module name to use for the base part of the URL, similar to module argument
+		//		to `dojo.moduleUrl`. If an Object, something that has a .toString() method that
+		//		generates a valid path for the cache item. For example, a dojo._Url object.
+		// url: String
+		//		The rest of the path to append to the path derived from the module argument. If
+		//		module is an object, then this second argument should be the "value" argument instead.
+		// value: String||Object?
+		//		If a String, the value to use in the cache for the module/url combination.
+		//		If an Object, it can have two properties: value and sanitize. The value property
+		//		should be the value to use in the cache, and sanitize can be set to true or false,
+		//		to indicate if XML declarations should be removed from the value and if the HTML
+		//		inside a body tag in the value should be extracted as the real value. The value argument
+		//		or the value property on the value argument are usually only used by the build system
+		//		as it inlines cache content.
+		// example:
+		//		To ask dojo.cache to fetch content and store it in the cache (the dojo["cache"] style
+		//		of call is used to avoid an issue with the build system erroneously trying to intern
+		//		this example. To get the build system to intern your dojo.cache calls, use the
+		//		"dojo.cache" style of call):
+		//		| //If template.html contains "<h1>Hello</h1>" that will be
+		//		| //the value for the text variable.
+		//		| var text = dojo["cache"]("my.module", "template.html");
+		// example:
+		//		To ask dojo.cache to fetch content and store it in the cache, and sanitize the input
+		//		 (the dojo["cache"] style of call is used to avoid an issue with the build system
+		//		erroneously trying to intern this example. To get the build system to intern your
+		//		dojo.cache calls, use the "dojo.cache" style of call):
+		//		| //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
+		//		| //text variable will contain just "<h1>Hello</h1>".
+		//		| var text = dojo["cache"]("my.module", "template.html", {sanitize: true});
+		// example:
+		//		Same example as previous, but demonstrates how an object can be passed in as
+		//		the first argument, then the value argument can then be the second argument.
+		//		| //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
+		//		| //text variable will contain just "<h1>Hello</h1>".
+		//		| var text = dojo["cache"](new dojo._Url("my/module/template.html"), {sanitize: true});
 
-			normalize:function(id, toAbsMid){
-				// id is something like (path may be relative):
-				//
-				//	 "path/to/text.html"
-				//	 "path/to/text.html!strip"
-				var parts= id.split("!"),
-					url= parts[0];
-				return (/^\./.test(url) ? toAbsMid(url) : url) + (parts[1] ? "!" + parts[1] : "");
-			},
-
-			load:function(id, require, load){
-				// id is something like (path is always absolute):
-				//
-				//	 "path/to/text.html"
-				//	 "path/to/text.html!strip"
-				var
-					parts= id.split("!"),
-					stripFlag= parts.length>1,
-					absMid= parts[0],
-					url = require.toUrl(parts[0]),
-					text = notFound,
-					finish = function(text){
-						load(stripFlag ? strip(text) : text);
-					};
-				if(absMid in theCache){
-					text = theCache[absMid];
-				}else if(url in require.cache){
-					text = require.cache[url];
-				}else if(url in theCache){
-					text = theCache[url];
-				}
-				if(text===notFound){
-					if(pending[url]){
-						pending[url].push(finish);
-					}else{
-						var pendingList = pending[url] = [finish];
-						getText(url, !require.async, function(text){
-							theCache[absMid]= theCache[url]= text;
-							for(var i = 0; i<pendingList.length;){
-								pendingList[i++](text);
-							}
-							delete pending[url];
-						});
-					}
-				}else{
-					finish(text);
-				}
-			}
-		};
-
-	dojo.cache= function(/*String||Object*/module, /*String*/url, /*String||Object?*/value){
 		//	 * (string string [value]) => (module, url, value)
 		//	 * (object [value])        => (module, value), url defaults to ""
 		//
@@ -148,65 +139,77 @@ define(["./_base/kernel", "require", "./has", "./has!host-browser?./_base/xhr"],
 		}
 	};
 
-	return result;
+	return {
+		// summary:
+		//		This module implements the dojo/text! plugin and the dojo.cache API.
+		// description:
+		//		We choose to include our own plugin to leverage functionality already contained in dojo
+		//		and thereby reduce the size of the plugin compared to various foreign loader implementations.
+		//		Also, this allows foreign AMD loaders to be used without their plugins.
+		//
+		//		CAUTION: this module is designed to optionally function synchronously to support the dojo v1.x synchronous
+		//		loader. This feature is outside the scope of the CommonJS plugins specification.
+
+		// the dojo/text caches it's own resources because of dojo.cache
+		dynamic: true,
+
+		normalize: function(id, toAbsMid){
+			// id is something like (path may be relative):
+			//
+			//	 "path/to/text.html"
+			//	 "path/to/text.html!strip"
+			var parts= id.split("!"),
+				url= parts[0];
+			return (/^\./.test(url) ? toAbsMid(url) : url) + (parts[1] ? "!" + parts[1] : "");
+		},
+
+		load: function(id, require, load){
+			// id: String
+			//		Path to the resource.
+			// require: Function
+			//		Object that include the function toUrl with given id returns a valid URL from which to load the text.
+			// load: Function
+			//		Callback function which will be called, when the loading finished.
+
+			// id is something like (path is always absolute):
+			//
+			//	 "path/to/text.html"
+			//	 "path/to/text.html!strip"
+			var
+				parts= id.split("!"),
+				stripFlag= parts.length>1,
+				absMid= parts[0],
+				url = require.toUrl(parts[0]),
+				requireCacheUrl = "url:" + url,
+				text = notFound,
+				finish = function(text){
+					load(stripFlag ? strip(text) : text);
+				};
+			if(absMid in theCache){
+				text = theCache[absMid];
+			}else if(require.cache && requireCacheUrl in require.cache){
+				text = require.cache[requireCacheUrl];
+			}else if(url in theCache){
+				text = theCache[url];
+			}
+			if(text===notFound){
+				if(pending[url]){
+					pending[url].push(finish);
+				}else{
+					var pendingList = pending[url] = [finish];
+					getText(url, !require.async, function(text){
+						theCache[absMid]= theCache[url]= text;
+						for(var i = 0; i<pendingList.length;){
+							pendingList[i++](text);
+						}
+						delete pending[url];
+					});
+				}
+			}else{
+				finish(text);
+			}
+		}
+	};
 
-/*=====
-dojo.cache = function(module, url, value){
-	// summary:
-	//		A getter and setter for storing the string content associated with the
-	//		module and url arguments.
-	// description:
-	//		If module is a string that contains slashes, then it is interpretted as a fully
-	//		resolved path (typically a result returned by require.toUrl), and url should not be
-	//		provided. This is the preferred signature. If module is a string that does not
-	//		contain slashes, then url must also be provided and module and url are used to
-	//		call `dojo.moduleUrl()` to generate a module URL. This signature is deprecated.
-	//		If value is specified, the cache value for the moduleUrl will be set to
-	//		that value. Otherwise, dojo.cache will fetch the moduleUrl and store it
-	//		in its internal cache and return that cached value for the URL. To clear
-	//		a cache value pass null for value. Since XMLHttpRequest (XHR) is used to fetch the
-	//		the URL contents, only modules on the same domain of the page can use this capability.
-	//		The build system can inline the cache values though, to allow for xdomain hosting.
-	// module: String||Object
-	//		If a String with slashes, a fully resolved path; if a String without slashes, the
-	//		module name to use for the base part of the URL, similar to module argument
-	//		to `dojo.moduleUrl`. If an Object, something that has a .toString() method that
-	//		generates a valid path for the cache item. For example, a dojo._Url object.
-	// url: String
-	//		The rest of the path to append to the path derived from the module argument. If
-	//		module is an object, then this second argument should be the "value" argument instead.
-	// value: String||Object?
-	//		If a String, the value to use in the cache for the module/url combination.
-	//		If an Object, it can have two properties: value and sanitize. The value property
-	//		should be the value to use in the cache, and sanitize can be set to true or false,
-	//		to indicate if XML declarations should be removed from the value and if the HTML
-	//		inside a body tag in the value should be extracted as the real value. The value argument
-	//		or the value property on the value argument are usually only used by the build system
-	//		as it inlines cache content.
-	//	example:
-	//		To ask dojo.cache to fetch content and store it in the cache (the dojo["cache"] style
-	//		of call is used to avoid an issue with the build system erroneously trying to intern
-	//		this example. To get the build system to intern your dojo.cache calls, use the
-	//		"dojo.cache" style of call):
-	//		| //If template.html contains "<h1>Hello</h1>" that will be
-	//		| //the value for the text variable.
-	//		| var text = dojo["cache"]("my.module", "template.html");
-	//	example:
-	//		To ask dojo.cache to fetch content and store it in the cache, and sanitize the input
-	//		 (the dojo["cache"] style of call is used to avoid an issue with the build system
-	//		erroneously trying to intern this example. To get the build system to intern your
-	//		dojo.cache calls, use the "dojo.cache" style of call):
-	//		| //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
-	//		| //text variable will contain just "<h1>Hello</h1>".
-	//		| var text = dojo["cache"]("my.module", "template.html", {sanitize: true});
-	//	example:
-	//		Same example as previous, but demostrates how an object can be passed in as
-	//		the first argument, then the value argument can then be the second argument.
-	//		| //If template.html contains "<html><body><h1>Hello</h1></body></html>", the
-	//		| //text variable will contain just "<h1>Hello</h1>".
-	//		| var text = dojo["cache"](new dojo._Url("my/module/template.html"), {sanitize: true});
-	return val; //String
-};
-=====*/
 });
 
diff --git a/dojo/topic.js b/dojo/topic.js
index b29cfa3..fd96098 100644
--- a/dojo/topic.js
+++ b/dojo/topic.js
@@ -1,33 +1,38 @@
 define(["./Evented"], function(Evented){
-	// summary:
-	//		The export of this module is a pubsub hub
-	//		You can also use listen function itself as a pub/sub hub:
-	//		| 	topic.subscribe("some/topic", function(event){
-	//		|	... do something with event
-	//		|	});
-	//		|	topic.publish("some/topic", {name:"some event", ...});
+
+	// module:
+	//		dojo/topic
 
 	var hub = new Evented;
 	return {
+		// summary:
+		//		Pubsub hub.
+		// example:
+		//		| 	topic.subscribe("some/topic", function(event){
+		//		|	... do something with event
+		//		|	});
+		//		|	topic.publish("some/topic", {name:"some event", ...});
+
 		publish: function(topic, event){
 			// summary:
 			//		Publishes a message to a topic on the pub/sub hub. All arguments after
-			// 		the first will be passed to the subscribers, so any number of arguments
-			// 		can be provided (not just event).
+			//		the first will be passed to the subscribers, so any number of arguments
+			//		can be provided (not just event).
 			// topic: String
 			//		The name of the topic to publish to
 			// event: Object
 			//		An event to distribute to the topic listeners
 			return hub.emit.apply(hub, arguments);
 		},
+
 		subscribe: function(topic, listener){
 			// summary:
-			//		Subcribes to a topic on the pub/sub hub
+			//		Subscribes to a topic on the pub/sub hub
 			// topic: String
 			//		The topic to subscribe to
-			//	listener: Function
+			// listener: Function
 			//		A function to call when a message is published to the given topic
 			return hub.on.apply(hub, arguments);
 		}
-	}
+	};
 });
diff --git a/dojo/touch.js b/dojo/touch.js
index 328ae1f..ac30fe5 100644
--- a/dojo/touch.js
+++ b/dojo/touch.js
@@ -1,34 +1,290 @@
-define(["./_base/kernel", "./on", "./has", "./mouse"], function(dojo, on, has, mouse){
-// module:
-//		dojo/touch
+define(["./_base/kernel", "./aspect", "./dom", "./dom-class", "./_base/lang", "./on", "./has", "./mouse", "./domReady", "./_base/window"],
+function(dojo, aspect, dom, domClass, lang, on, has, mouse, domReady, win){
 
-/*=====
-	dojo.touch = {
+	// module:
+	//		dojo/touch
+
+	var hasTouch = has("touch");
+
+	var ios4 = has("ios") < 5;
+	
+	var msPointer = navigator.msPointerEnabled;
+
+	// Click generation variables
+	var clicksInited, clickTracker, clickTarget, clickX, clickY, clickDx, clickDy, clickTime;
+
+	// Time of most recent touchstart, touchmove, or touchend event
+	var lastTouch;
+
+	function dualEvent(mouseType, touchType, msPointerType){
+		// Returns synthetic event that listens for both the specified mouse event and specified touch event.
+		// But ignore fake mouse events that were generated due to the user touching the screen.
+		if(msPointer && msPointerType){
+			// IE10+: MSPointer* events are designed to handle both mouse and touch in a uniform way,
+			// so just use that regardless of hasTouch.
+			return function(node, listener){
+				return on(node, msPointerType, listener);
+			}
+		}else if(hasTouch){
+			return function(node, listener){
+				var handle1 = on(node, touchType, listener),
+					handle2 = on(node, mouseType, function(evt){
+						if(!lastTouch || (new Date()).getTime() > lastTouch + 1000){
+							listener.call(this, evt);
+						}
+					});
+				return {
+					remove: function(){
+						handle1.remove();
+						handle2.remove();
+					}
+				};
+			};
+		}else{
+			// Avoid creating listeners for touch events on performance sensitive older browsers like IE6
+			return function(node, listener){
+				return on(node, mouseType, listener);
+			}
+		}
+	}
+
+	function marked(/*DOMNode*/ node){
+		// Test if a node or its ancestor has been marked with the dojoClick property to indicate special processing,
+		do{
+			if(node.dojoClick){ return node.dojoClick; }
+		}while(node = node.parentNode);
+	}
+	
+	function doClicks(e, moveType, endType){
+		// summary:
+		//		Setup touch listeners to generate synthetic clicks immediately (rather than waiting for the browser
+		//		to generate clicks after the double-tap delay) and consistently (regardless of whether event.preventDefault()
+		//		was called in an event listener. Synthetic clicks are generated only if a node or one of its ancestors has
+		//		its dojoClick property set to truthy.
+		
+		clickTracker  = !e.target.disabled && marked(e.target); // click threshold = true, number or x/y object
+		if(clickTracker){
+			clickTarget = e.target;
+			clickX = e.touches ? e.touches[0].pageX : e.clientX;
+			clickY = e.touches ? e.touches[0].pageY : e.clientY;
+			clickDx = (typeof clickTracker == "object" ? clickTracker.x : (typeof clickTracker == "number" ? clickTracker : 0)) || 4;
+			clickDy = (typeof clickTracker == "object" ? clickTracker.y : (typeof clickTracker == "number" ? clickTracker : 0)) || 4;
+
+			// add move/end handlers only the first time a node with dojoClick is seen,
+			// so we don't add too much overhead when dojoClick is never set.
+			if(!clicksInited){
+				clicksInited = true;
+
+				win.doc.addEventListener(moveType, function(e){
+					clickTracker = clickTracker &&
+						e.target == clickTarget &&
+						Math.abs((e.touches ? e.touches[0].pageX : e.clientX) - clickX) <= clickDx &&
+						Math.abs((e.touches ? e.touches[0].pageY : e.clientY) - clickY) <= clickDy;
+				}, true);
+
+				win.doc.addEventListener(endType, function(e){
+					if(clickTracker){
+						clickTime = (new Date()).getTime();
+						var target = e.target;
+						if(target.tagName === "LABEL"){
+							// when clicking on a label, forward click to its associated input if any
+							target = dom.byId(target.getAttribute("for")) || target;
+						}
+						setTimeout(function(){
+							on.emit(target, "click", {
+								bubbles : true,
+								cancelable : true,
+								_dojo_click : true
+							});
+						});
+					}
+				}, true);
+
+				function stopNativeEvents(type){
+					win.doc.addEventListener(type, function(e){
+						// Stop native events when we emitted our own click event.  Note that the native click may occur
+						// on a different node than the synthetic click event was generated on.  For example,
+						// click on a menu item, causing the menu to disappear, and then (~300ms later) the browser
+						// sends a click event to the node that was *underneath* the menu.  So stop all native events
+						// sent shortly after ours, similar to what is done in dualEvent.
+						// The INPUT.dijitOffScreen test is for offscreen inputs used in dijit/form/Button, on which
+						// we call click() explicitly, we don't want to stop this event.
+						if(!e._dojo_click &&
+								(new Date()).getTime() <= clickTime + 1000 &&
+								!(e.target.tagName == "INPUT" && domClass.contains(e.target, "dijitOffScreen"))){
+							e.stopPropagation();
+							e.stopImmediatePropagation && e.stopImmediatePropagation();
+							if(type == "click" && (e.target.tagName != "INPUT" || e.target.type == "radio" || e.target.type == "checkbox")
+								&& e.target.tagName != "TEXTAREA" && e.target.tagName != "AUDIO" && e.target.tagName != "VIDEO"){
+								 // preventDefault() breaks textual <input>s on android, keyboard doesn't popup,
+								 // but it is still needed for checkboxes and radio buttons, otherwise in some cases
+								 // the checked state becomes inconsistent with the widget's state
+								e.preventDefault();
+							}
+						}
+					}, true);
+				}
+
+				stopNativeEvents("click");
+
+				// We also stop mousedown/up since these would be sent well after with our "fast" click (300ms),
+				// which can confuse some dijit widgets.
+				stopNativeEvents("mousedown");
+				stopNativeEvents("mouseup");
+			}
+		}
+	}
+
+	var hoveredNode;
+
+	if(hasTouch){
+		if(msPointer){
+			 // MSPointer (IE10+) already has support for over and out, so we just need to init click support
+			domReady(function(){
+				win.doc.addEventListener("MSPointerDown", function(evt){
+					doClicks(evt, "MSPointerMove", "MSPointerUp");
+				}, true);
+			});		
+		}else{
+			domReady(function(){
+				// Keep track of currently hovered node
+				hoveredNode = win.body();	// currently hovered node
+
+				win.doc.addEventListener("touchstart", function(evt){
+					lastTouch = (new Date()).getTime();
+
+					// Precede touchstart event with touch.over event.  DnD depends on this.
+					// Use addEventListener(cb, true) to run cb before any touchstart handlers on node run,
+					// and to ensure this code runs even if the listener on the node does event.stop().
+					var oldNode = hoveredNode;
+					hoveredNode = evt.target;
+					on.emit(oldNode, "dojotouchout", {
+						relatedTarget: hoveredNode,
+						bubbles: true
+					});
+					on.emit(hoveredNode, "dojotouchover", {
+						relatedTarget: oldNode,
+						bubbles: true
+					});
+				
+					doClicks(evt, "touchmove", "touchend"); // init click generation
+				}, true);
+
+				function copyEventProps(evt){
+					// Make copy of event object and also set bubbles:true.  Used when calling on.emit().
+					var props = lang.delegate(evt, {
+						bubbles: true
+					});
+
+					if(has("ios") >= 6){
+						// On iOS6 "touches" became a non-enumerable property, which 
+						// is not hit by for...in.  Ditto for the other properties below.
+						props.touches = evt.touches;
+						props.altKey = evt.altKey;
+						props.changedTouches = evt.changedTouches;
+						props.ctrlKey = evt.ctrlKey;
+						props.metaKey = evt.metaKey;
+						props.shiftKey = evt.shiftKey;
+						props.targetTouches = evt.targetTouches;
+					}
+
+					return props;
+				}
+				
+				on(win.doc, "touchmove", function(evt){
+					lastTouch = (new Date()).getTime();
+
+					var newNode = win.doc.elementFromPoint(
+						evt.pageX - (ios4 ? 0 : win.global.pageXOffset), // iOS 4 expects page coords
+						evt.pageY - (ios4 ? 0 : win.global.pageYOffset)
+					);
+
+					if(newNode){
+						// Fire synthetic touchover and touchout events on nodes since the browser won't do it natively.
+						if(hoveredNode !== newNode){
+							// touch out on the old node
+							on.emit(hoveredNode, "dojotouchout", {
+								relatedTarget: newNode,
+								bubbles: true
+							});
+
+							// touchover on the new node
+							on.emit(newNode, "dojotouchover", {
+								relatedTarget: hoveredNode,
+								bubbles: true
+							});
+
+							hoveredNode = newNode;
+						}
+
+						// Unlike a listener on "touchmove", on(node, "dojotouchmove", listener) fires when the finger
+						// drags over the specified node, regardless of which node the touch started on.
+						on.emit(newNode, "dojotouchmove", copyEventProps(evt));
+					}
+				});
+
+				// Fire a dojotouchend event on the node where the finger was before it was removed from the screen.
+				// This is different than the native touchend, which fires on the node where the drag started.
+				on(win.doc, "touchend", function(evt){
+					lastTouch = (new Date()).getTime();
+					var node = win.doc.elementFromPoint(
+						evt.pageX - (ios4 ? 0 : win.global.pageXOffset), // iOS 4 expects page coords
+						evt.pageY - (ios4 ? 0 : win.global.pageYOffset)
+					) || win.body(); // if out of the screen
+
+					on.emit(node, "dojotouchend", copyEventProps(evt));
+				});
+			});
+		}
+	}
+
+	//device neutral events - touch.press|move|release|cancel/over/out
+	var touch = {
+		press: dualEvent("mousedown", "touchstart", "MSPointerDown"),
+		move: dualEvent("mousemove", "dojotouchmove", "MSPointerMove"),
+		release: dualEvent("mouseup", "dojotouchend", "MSPointerUp"),
+		cancel: dualEvent(mouse.leave, "touchcancel", hasTouch?"MSPointerCancel":null),
+		over: dualEvent("mouseover", "dojotouchover", "MSPointerOver"),
+		out: dualEvent("mouseout", "dojotouchout", "MSPointerOut"),
+		enter: mouse._eventHandler(dualEvent("mouseover","dojotouchover", "MSPointerOver")),
+		leave: mouse._eventHandler(dualEvent("mouseout", "dojotouchout", "MSPointerOut"))
+	};
+
+	/*=====
+	touch = {
 		// summary:
 		//		This module provides unified touch event handlers by exporting
 		//		press, move, release and cancel which can also run well on desktop.
 		//		Based on http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
+		//		Also, if the dojoClick property is set to true on a DOM node, dojo/touch generates
+		//		click events immediately for this node and its descendants, to avoid the
+		//		delay before native browser click events, and regardless of whether evt.preventDefault()
+		//		was called in a touch.press event listener.
 		//
 		// example:
-		//		1. Used with dojo.connect()
-		//		|	dojo.connect(node, dojo.touch.press, function(e){});
-		//		|	dojo.connect(node, dojo.touch.move, function(e){});
-		//		|	dojo.connect(node, dojo.touch.release, function(e){});
-		//		|	dojo.connect(node, dojo.touch.cancel, function(e){});
-		//
-		//		2. Used with dojo.on
+		//		Used with dojo.on
 		//		|	define(["dojo/on", "dojo/touch"], function(on, touch){
 		//		|		on(node, touch.press, function(e){});
 		//		|		on(node, touch.move, function(e){});
 		//		|		on(node, touch.release, function(e){});
 		//		|		on(node, touch.cancel, function(e){});
-		//
-		//		3. Used with dojo.touch.* directly
-		//		|	dojo.touch.press(node, function(e){});
-		//		|	dojo.touch.move(node, function(e){});
-		//		|	dojo.touch.release(node, function(e){});
-		//		|	dojo.touch.cancel(node, function(e){});
+		// example:
+		//		Used with touch.* directly
+		//		|	touch.press(node, function(e){});
+		//		|	touch.move(node, function(e){});
+		//		|	touch.release(node, function(e){});
+		//		|	touch.cancel(node, function(e){});
+		// example:
+		//		Have dojo/touch generate clicks without delay, with a default move threshold of 4 pixels
+		//		|	node.dojoClick = true;
+		// example:
+		//		Have dojo/touch generate clicks without delay, with a move threshold of 10 pixels horizontally and vertically
+		//		|	node.dojoClick = 10;
+		// example:
+		//		Have dojo/touch generate clicks without delay, with a move threshold of 50 pixels horizontally and 10 pixels vertically
+		//		|	node.dojoClick = {x:50, y:5};
 		
+
 		press: function(node, listener){
 			// summary:
 			//		Register a listener to 'touchstart'|'mousedown' for the given node
@@ -41,7 +297,7 @@ define(["./_base/kernel", "./on", "./has", "./mouse"], function(dojo, on, has, m
 		},
 		move: function(node, listener){
 			// summary:
-			//		Register a listener to 'touchmove'|'mousemove' for the given node
+			//		Register a listener that fires when the mouse cursor or a finger is dragged over the given node.
 			// node: Dom
 			//		Target node to listen to
 			// listener: Function
@@ -51,7 +307,8 @@ define(["./_base/kernel", "./on", "./has", "./mouse"], function(dojo, on, has, m
 		},
 		release: function(node, listener){
 			// summary:
-			//		Register a listener to 'touchend'|'mouseup' for the given node
+			//		Register a listener to releasing the mouse button while the cursor is over the given node
+			//		(i.e. "mouseup") or for removing the finger from the screen while touching the given node.
 			// node: Dom
 			//		Target node to listen to
 			// listener: Function
@@ -68,22 +325,51 @@ define(["./_base/kernel", "./on", "./has", "./mouse"], function(dojo, on, has, m
 			//		Callback function
 			// returns:
 			//		A handle which will be used to remove the listener by handle.remove()
+		},
+		over: function(node, listener){
+			// summary:
+			//		Register a listener to 'mouseover' or touch equivalent for the given node
+			// node: Dom
+			//		Target node to listen to
+			// listener: Function
+			//		Callback function
+			// returns:
+			//		A handle which will be used to remove the listener by handle.remove()
+		},
+		out: function(node, listener){
+			// summary:
+			//		Register a listener to 'mouseout' or touch equivalent for the given node
+			// node: Dom
+			//		Target node to listen to
+			// listener: Function
+			//		Callback function
+			// returns:
+			//		A handle which will be used to remove the listener by handle.remove()
+		},
+		enter: function(node, listener){
+			// summary:
+			//		Register a listener to mouse.enter or touch equivalent for the given node
+			// node: Dom
+			//		Target node to listen to
+			// listener: Function
+			//		Callback function
+			// returns:
+			//		A handle which will be used to remove the listener by handle.remove()
+		},
+		leave: function(node, listener){
+			// summary:
+			//		Register a listener to mouse.leave or touch equivalent for the given node
+			// node: Dom
+			//		Target node to listen to
+			// listener: Function
+			//		Callback function
+			// returns:
+			//		A handle which will be used to remove the listener by handle.remove()
 		}
 	};
-=====*/
+	=====*/
 
-	function _handle(/*String - press | move | release | cancel*/type){
-		return function(node, listener){//called by on(), see dojo.on
-			return on(node, type, listener);
-		};
-	}
-	var touch = has("touch");
-	//device neutral events - dojo.touch.press|move|release|cancel
-	dojo.touch = {
-		press: _handle(touch ? "touchstart": "mousedown"),
-		move: _handle(touch ? "touchmove": "mousemove"),
-		release: _handle(touch ? "touchend": "mouseup"),
-		cancel: touch ? _handle("touchcancel") : mouse.leave
-	};
-	return dojo.touch;
-});
\ No newline at end of file
+	has("extend-dojo") && (dojo.touch = touch);
+
+	return touch;
+});
diff --git a/dojo/uacss.js b/dojo/uacss.js
index 8591a1b..2ce9ee7 100644
--- a/dojo/uacss.js
+++ b/dojo/uacss.js
@@ -1,16 +1,25 @@
-define(["./dom-geometry", "./_base/lang", "./ready", "./_base/sniff", "./_base/window"],
-	function(geometry, lang, ready, has, baseWindow){
+define(["./dom-geometry", "./_base/lang", "./domReady", "./sniff", "./_base/window"],
+	function(geometry, lang, domReady, has, baseWindow){
+
 	// module:
 	//		dojo/uacss
-	// summary:
-	//		Applies pre-set CSS classes to the top-level HTML node, based on:
-	//			- browser (ex: dj_ie)
-	//			- browser version (ex: dj_ie6)
-	//			- box model (ex: dj_contentBox)
-	//			- text direction (ex: dijitRtl)
-	//
-	//		In addition, browser, browser version, and box model are
-	//		combined with an RTL flag when browser text is RTL. ex: dj_ie-rtl.
+
+	/*=====
+	return {
+		// summary:
+		//		Applies pre-set CSS classes to the top-level HTML node, based on:
+		//
+		//		- browser (ex: dj_ie)
+		//		- browser version (ex: dj_ie6)
+		//		- box model (ex: dj_contentBox)
+		//		- text direction (ex: dijitRtl)
+		//
+		//		In addition, browser, browser version, and box model are
+		//		combined with an RTL flag when browser text is RTL. ex: dj_ie-rtl.
+		//
+		//		Returns the has() method.
+	};
+	=====*/
 
 	var
 		html = baseWindow.doc.documentElement,
@@ -21,13 +30,7 @@ define(["./dom-geometry", "./_base/lang", "./ready", "./_base/sniff", "./_base/w
 		boxModel = geometry.boxModel.replace(/-/,''),
 
 		classes = {
-			"dj_ie": ie,
-			"dj_ie6": maj(ie) == 6,
-			"dj_ie7": maj(ie) == 7,
-			"dj_ie8": maj(ie) == 8,
-			"dj_ie9": maj(ie) == 9,
 			"dj_quirks": has("quirks"),
-			"dj_iequirks": ie && has("quirks"),
 
 			// NOTE: Opera not supported by dijit
 			"dj_opera": opera,
@@ -39,9 +42,20 @@ define(["./dom-geometry", "./_base/lang", "./ready", "./_base/sniff", "./_base/w
 			"dj_chrome": has("chrome"),
 
 			"dj_gecko": has("mozilla"),
-			"dj_ff3": maj(ff) == 3
+
+			"dj_ios": has("ios"),
+			"dj_android": has("android")
 		}; // no dojo unsupported browsers
 
+	if(ie){
+		classes["dj_ie"] = true;
+		classes["dj_ie" + maj(ie)] = true;
+		classes["dj_iequirks"] = has("quirks");
+	}
+	if(ff){
+		classes["dj_ff" + maj(ff)] = true;
+	}
+
 	classes["dj_" + boxModel] = true;
 
 	// apply browser, browser version, and box model class names
@@ -55,8 +69,7 @@ define(["./dom-geometry", "./_base/lang", "./ready", "./_base/sniff", "./_base/w
 
 	// If RTL mode, then add dj_rtl flag plus repeat existing classes with -rtl extension.
 	// We can't run the code below until the <body> tag has loaded (so we can check for dir=rtl).
-	// priority is 90 to run ahead of parser priority of 100
-	ready(90, function(){
+	domReady(function(){
 		if(!geometry.isBodyLtr()){
 			var rtlClassStr = "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl ");
 			html.className = lang.trim(html.className + " " + rtlClassStr + "dj_rtl dijitRtl " + classStr.replace(/ /g, "-rtl "));
diff --git a/dojo/when.js b/dojo/when.js
new file mode 100644
index 0000000..36704ad
--- /dev/null
+++ b/dojo/when.js
@@ -0,0 +1,55 @@
+define([
+	"./Deferred",
+	"./promise/Promise"
+], function(Deferred, Promise){
+	"use strict";
+
+	// module:
+	//		dojo/when
+
+	return function when(valueOrPromise, callback, errback, progback){
+		// summary:
+		//		Transparently applies callbacks to values and/or promises.
+		// description:
+		//		Accepts promises but also transparently handles non-promises. If no
+		//		callbacks are provided returns a promise, regardless of the initial
+		//		value. Foreign promises are converted.
+		//
+		//		If callbacks are provided and the initial value is not a promise,
+		//		the callback is executed immediately with no error handling. Returns
+		//		a promise if the initial value is a promise, or the result of the
+		//		callback otherwise.
+		// valueOrPromise:
+		//		Either a regular value or an object with a `then()` method that
+		//		follows the Promises/A specification.
+		// callback: Function?
+		//		Callback to be invoked when the promise is resolved, or a non-promise
+		//		is received.
+		// errback: Function?
+		//		Callback to be invoked when the promise is rejected.
+		// progback: Function?
+		//		Callback to be invoked when the promise emits a progress update.
+		// returns: dojo/promise/Promise
+		//		Promise, or if a callback is provided, the result of the callback.
+
+		var receivedPromise = valueOrPromise && typeof valueOrPromise.then === "function";
+		var nativePromise = receivedPromise && valueOrPromise instanceof Promise;
+
+		if(!receivedPromise){
+			if(arguments.length > 1){
+				return callback ? callback(valueOrPromise) : valueOrPromise;
+			}else{
+				return new Deferred().resolve(valueOrPromise);
+			}
+		}else if(!nativePromise){
+			var deferred = new Deferred(valueOrPromise.cancel);
+			valueOrPromise.then(deferred.resolve, deferred.reject, deferred.progress);
+			valueOrPromise = deferred.promise;
+		}
+
+		if(callback || errback || progback){
+			return valueOrPromise.then(callback, errback, progback);
+		}
+		return valueOrPromise;
+	};
+});
diff --git a/dojo/window.js b/dojo/window.js
index 25b0fda..c9d24b2 100644
--- a/dojo/window.js
+++ b/dojo/window.js
@@ -1,169 +1,229 @@
-define(["./_base/lang", "./_base/sniff", "./_base/window", "./dom", "./dom-geometry", "./dom-style"],
-	function(lang, has, baseWindow, dom, geom, style) {
-
-// module:
-//		dojo/window
-// summary:
-//		TODOC
-
-var window = lang.getObject("dojo.window", true);
-
-/*=====
-dojo.window = {
-	// summary:
-	//		TODO
-};
-window = dojo.window;
-=====*/
-
-window.getBox = function(){
-	// summary:
-	//		Returns the dimensions and scroll position of the viewable area of a browser window
-
-	var
-		scrollRoot = (baseWindow.doc.compatMode == 'BackCompat') ? baseWindow.body() : baseWindow.doc.documentElement,
-		// get scroll position
-		scroll = geom.docScroll(), // scrollRoot.scrollTop/Left should work
-		w, h;
-
-	if(has("touch")){ // if(scrollbars not supported)
-		var uiWindow = baseWindow.doc.parentWindow || baseWindow.doc.defaultView;   // use UI window, not dojo.global window. baseWindow.doc.parentWindow probably not needed since it's not defined for webkit
-		// on mobile, scrollRoot.clientHeight <= uiWindow.innerHeight <= scrollRoot.offsetHeight, return uiWindow.innerHeight
-		w = uiWindow.innerWidth || scrollRoot.clientWidth; // || scrollRoot.clientXXX probably never evaluated
-		h = uiWindow.innerHeight || scrollRoot.clientHeight;
-	}else{
-		// on desktops, scrollRoot.clientHeight <= scrollRoot.offsetHeight <= uiWindow.innerHeight, return scrollRoot.clientHeight
-		// uiWindow.innerWidth/Height includes the scrollbar and cannot be used
-		w = scrollRoot.clientWidth;
-		h = scrollRoot.clientHeight;
-	}
-	return {
-		l: scroll.x,
-		t: scroll.y,
-		w: w,
-		h: h
-	};
-};
-
-window.get = function(doc){
-	// summary:
-	// 		Get window object associated with document doc
-
-	// In some IE versions (at least 6.0), document.parentWindow does not return a
-	// reference to the real window object (maybe a copy), so we must fix it as well
-	// We use IE specific execScript to attach the real window reference to
-	// document._parentWindow for later use
-	if(has("ie") && window !== document.parentWindow){
-		/*
-		In IE 6, only the variable "window" can be used to connect events (others
-		may be only copies).
-		*/
-		doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
-		//to prevent memory leak, unset it after use
-		//another possibility is to add an onUnload handler which seems overkill to me (liucougar)
-		var win = doc._parentWindow;
-		doc._parentWindow = null;
-		return win;	//	Window
-	}
-
-	return doc.parentWindow || doc.defaultView;	//	Window
-};
-
-window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
-	// summary:
-	//		Scroll the passed node into view, if it is not already.
-
-	// don't rely on node.scrollIntoView working just because the function is there
-
-	try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method
-		node = dom.byId(node);
-		var doc = node.ownerDocument || baseWindow.doc,
-			body = doc.body || baseWindow.body(),
-			html = doc.documentElement || body.parentNode,
-			isIE = has("ie"), isWK = has("webkit");
-		// if an untested browser, then use the native method
-		if((!(has("mozilla") || isIE || isWK || has("opera")) || node == body || node == html) && (typeof node.scrollIntoView != "undefined")){
-			node.scrollIntoView(false); // short-circuit to native if possible
-			return;
-		}
-		var backCompat = doc.compatMode == 'BackCompat',
-			clientAreaRoot = (isIE >= 9 && node.ownerDocument.parentWindow.frameElement)
-				? ((html.clientHeight > 0 && html.clientWidth > 0 && (body.clientHeight == 0 || body.clientWidth == 0 || body.clientHeight > html.clientHeight || body.clientWidth > html.clientWidth)) ? html : body)
-				: (backCompat ? body : html),
-			scrollRoot = isWK ? body : clientAreaRoot,
-			rootWidth = clientAreaRoot.clientWidth,
-			rootHeight = clientAreaRoot.clientHeight,
-			rtl = !geom.isBodyLtr(),
-			nodePos = pos || geom.position(node),
-			el = node.parentNode,
-			isFixed = function(el){
-				return ((isIE <= 6 || (isIE && backCompat))? false : (style.get(el, 'position').toLowerCase() == "fixed"));
-			};
-		if(isFixed(node)){ return; } // nothing to do
-
-		while(el){
-			if(el == body){ el = scrollRoot; }
-			var elPos = geom.position(el),
-				fixedPos = isFixed(el);
-
-			if(el == scrollRoot){
-				elPos.w = rootWidth; elPos.h = rootHeight;
-				if(scrollRoot == html && isIE && rtl){ elPos.x += scrollRoot.offsetWidth-elPos.w; } // IE workaround where scrollbar causes negative x
-				if(elPos.x < 0 || !isIE){ elPos.x = 0; } // IE can have values > 0
-				if(elPos.y < 0 || !isIE){ elPos.y = 0; }
+define(["./_base/lang", "./sniff", "./_base/window", "./dom", "./dom-geometry", "./dom-style", "./dom-construct"],
+	function(lang, has, baseWindow, dom, geom, style, domConstruct){
+
+	// feature detection
+	/* not needed but included here for future reference
+	has.add("rtl-innerVerticalScrollBar-on-left", function(win, doc){
+		var	body = baseWindow.body(doc),
+			scrollable = domConstruct.create('div', {
+				style: {overflow:'scroll', overflowX:'hidden', direction:'rtl', visibility:'hidden', position:'absolute', left:'0', width:'64px', height:'64px'}
+			}, body, "last"),
+			center = domConstruct.create('center', {
+				style: {overflow:'hidden', direction:'ltr'}
+			}, scrollable, "last"),
+			inner = domConstruct.create('div', {
+				style: {overflow:'visible', display:'inline' }
+			}, center, "last");
+		inner.innerHTML=" ";
+		var midPoint = Math.max(inner.offsetLeft, geom.position(inner).x);
+		var ret = midPoint >= 32;
+		center.removeChild(inner);
+		scrollable.removeChild(center);
+		body.removeChild(scrollable);
+		return ret;
+	});
+	*/
+	has.add("rtl-adjust-position-for-verticalScrollBar", function(win, doc){
+		var	body = baseWindow.body(doc),
+			scrollable = domConstruct.create('div', {
+				style: {overflow:'scroll', overflowX:'visible', direction:'rtl', visibility:'hidden', position:'absolute', left:'0', top:'0', width:'64px', height:'64px'}
+			}, body, "last"),
+			div = domConstruct.create('div', {
+				style: {overflow:'hidden', direction:'ltr'}
+			}, scrollable, "last"),
+			ret = geom.position(div).x != 0;
+		scrollable.removeChild(div);
+		body.removeChild(scrollable);
+		return ret;
+	});
+
+	has.add("position-fixed-support", function(win, doc){
+		// IE6, IE7+quirks, and some older mobile browsers don't support position:fixed
+		var	body = baseWindow.body(doc),
+			outer = domConstruct.create('span', {
+				style: {visibility:'hidden', position:'fixed', left:'1px', top:'1px'}
+			}, body, "last"),
+			inner = domConstruct.create('span', {
+				style: {position:'fixed', left:'0', top:'0'}
+			}, outer, "last"),
+			ret = geom.position(inner).x != geom.position(outer).x;
+		outer.removeChild(inner);
+		body.removeChild(outer);
+		return ret;
+	});
+
+	// module:
+	//		dojo/window
+
+	var window = {
+		// summary:
+		//		TODOC
+
+		getBox: function(/*Document?*/ doc){
+			// summary:
+			//		Returns the dimensions and scroll position of the viewable area of a browser window
+
+			doc = doc || baseWindow.doc;
+
+			var
+				scrollRoot = (doc.compatMode == 'BackCompat') ? baseWindow.body(doc) : doc.documentElement,
+				// get scroll position
+				scroll = geom.docScroll(doc), // scrollRoot.scrollTop/Left should work
+				w, h;
+
+			if(has("touch")){ // if(scrollbars not supported)
+				var uiWindow = window.get(doc);   // use UI window, not dojo.global window
+				// on mobile, scrollRoot.clientHeight <= uiWindow.innerHeight <= scrollRoot.offsetHeight, return uiWindow.innerHeight
+				w = uiWindow.innerWidth || scrollRoot.clientWidth; // || scrollRoot.clientXXX probably never evaluated
+				h = uiWindow.innerHeight || scrollRoot.clientHeight;
 			}else{
-				var pb = geom.getPadBorderExtents(el);
-				elPos.w -= pb.w; elPos.h -= pb.h; elPos.x += pb.l; elPos.y += pb.t;
-				var clientSize = el.clientWidth,
-					scrollBarSize = elPos.w - clientSize;
-				if(clientSize > 0 && scrollBarSize > 0){
-					elPos.w = clientSize;
-					elPos.x += (rtl && (isIE || el.clientLeft > pb.l/*Chrome*/)) ? scrollBarSize : 0;
-				}
-				clientSize = el.clientHeight;
-				scrollBarSize = elPos.h - clientSize;
-				if(clientSize > 0 && scrollBarSize > 0){
-					elPos.h = clientSize;
-				}
+				// on desktops, scrollRoot.clientHeight <= scrollRoot.offsetHeight <= uiWindow.innerHeight, return scrollRoot.clientHeight
+				// uiWindow.innerWidth/Height includes the scrollbar and cannot be used
+				w = scrollRoot.clientWidth;
+				h = scrollRoot.clientHeight;
 			}
-			if(fixedPos){ // bounded by viewport, not parents
-				if(elPos.y < 0){
-					elPos.h += elPos.y; elPos.y = 0;
-				}
-				if(elPos.x < 0){
-					elPos.w += elPos.x; elPos.x = 0;
-				}
-				if(elPos.y + elPos.h > rootHeight){
-					elPos.h = rootHeight - elPos.y;
+			return {
+				l: scroll.x,
+				t: scroll.y,
+				w: w,
+				h: h
+			};
+		},
+
+		get: function(/*Document*/ doc){
+			// summary:
+			//		Get window object associated with document doc.
+			// doc:
+			//		The document to get the associated window for.
+
+			// In some IE versions (at least 6.0), document.parentWindow does not return a
+			// reference to the real window object (maybe a copy), so we must fix it as well
+			// We use IE specific execScript to attach the real window reference to
+			// document._parentWindow for later use
+			if(has("ie") && window !== document.parentWindow){
+				/*
+				In IE 6, only the variable "window" can be used to connect events (others
+				may be only copies).
+				*/
+				doc.parentWindow.execScript("document._parentWindow = window;", "Javascript");
+				//to prevent memory leak, unset it after use
+				//another possibility is to add an onUnload handler which seems overkill to me (liucougar)
+				var win = doc._parentWindow;
+				doc._parentWindow = null;
+				return win;	//	Window
+			}
+
+			return doc.parentWindow || doc.defaultView;	//	Window
+		},
+
+		scrollIntoView: function(/*DomNode*/ node, /*Object?*/ pos){
+			// summary:
+			//		Scroll the passed node into view using minimal movement, if it is not already.
+
+			// Don't rely on node.scrollIntoView working just because the function is there since
+			// it forces the node to the page's bottom or top (and left or right in IE) without consideration for the minimal movement.
+			// WebKit's node.scrollIntoViewIfNeeded doesn't work either for inner scrollbars in right-to-left mode
+			// and when there's a fixed position scrollable element
+
+			try{ // catch unexpected/unrecreatable errors (#7808) since we can recover using a semi-acceptable native method
+				node = dom.byId(node);
+				var	doc = node.ownerDocument || baseWindow.doc,	// TODO: why baseWindow.doc?  Isn't node.ownerDocument always defined?
+					body = baseWindow.body(doc),
+					html = doc.documentElement || body.parentNode,
+					isIE = has("ie"),
+					isWK = has("webkit");
+				// if an untested browser, then use the native method
+				if(node == body || node == html){ return; }
+				if(!(has("mozilla") || isIE || isWK || has("opera")) && ("scrollIntoView" in node)){
+					node.scrollIntoView(false); // short-circuit to native if possible
+					return;
 				}
-				if(elPos.x + elPos.w > rootWidth){
-					elPos.w = rootWidth - elPos.x;
+				var	backCompat = doc.compatMode == 'BackCompat',
+					rootWidth = Math.min(body.clientWidth || html.clientWidth, html.clientWidth || body.clientWidth),
+					rootHeight = Math.min(body.clientHeight || html.clientHeight, html.clientHeight || body.clientHeight),
+					scrollRoot = (isWK || backCompat) ? body : html,
+					nodePos = pos || geom.position(node),
+					el = node.parentNode,
+					isFixed = function(el){
+						return (isIE <= 6 || (isIE == 7 && backCompat))
+							? false
+							: (has("position-fixed-support") && (style.get(el, 'position').toLowerCase() == "fixed"));
+					};
+				if(isFixed(node)){ return; } // nothing to do
+				while(el){
+					if(el == body){ el = scrollRoot; }
+					var	elPos = geom.position(el),
+						fixedPos = isFixed(el),
+						rtl = style.getComputedStyle(el).direction.toLowerCase() == "rtl";
+
+					if(el == scrollRoot){
+						elPos.w = rootWidth; elPos.h = rootHeight;
+						if(scrollRoot == html && isIE && rtl){ elPos.x += scrollRoot.offsetWidth-elPos.w; } // IE workaround where scrollbar causes negative x
+						if(elPos.x < 0 || !isIE || isIE >= 9){ elPos.x = 0; } // older IE can have values > 0
+						if(elPos.y < 0 || !isIE || isIE >= 9){ elPos.y = 0; }
+					}else{
+						var pb = geom.getPadBorderExtents(el);
+						elPos.w -= pb.w; elPos.h -= pb.h; elPos.x += pb.l; elPos.y += pb.t;
+						var clientSize = el.clientWidth,
+							scrollBarSize = elPos.w - clientSize;
+						if(clientSize > 0 && scrollBarSize > 0){
+							if(rtl && has("rtl-adjust-position-for-verticalScrollBar")){
+								elPos.x += scrollBarSize;
+							}
+							elPos.w = clientSize;
+						}
+						clientSize = el.clientHeight;
+						scrollBarSize = elPos.h - clientSize;
+						if(clientSize > 0 && scrollBarSize > 0){
+							elPos.h = clientSize;
+						}
+					}
+					if(fixedPos){ // bounded by viewport, not parents
+						if(elPos.y < 0){
+							elPos.h += elPos.y; elPos.y = 0;
+						}
+						if(elPos.x < 0){
+							elPos.w += elPos.x; elPos.x = 0;
+						}
+						if(elPos.y + elPos.h > rootHeight){
+							elPos.h = rootHeight - elPos.y;
+						}
+						if(elPos.x + elPos.w > rootWidth){
+							elPos.w = rootWidth - elPos.x;
+						}
+					}
+					// calculate overflow in all 4 directions
+					var	l = nodePos.x - elPos.x, // beyond left: < 0
+//						t = nodePos.y - Math.max(elPos.y, 0), // beyond top: < 0
+						t = nodePos.y - elPos.y, // beyond top: < 0
+						r = l + nodePos.w - elPos.w, // beyond right: > 0
+						bot = t + nodePos.h - elPos.h; // beyond bottom: > 0
+					var s, old;
+					if(r * l > 0 && (!!el.scrollLeft || el == scrollRoot || el.scrollWidth > el.offsetHeight)){
+						s = Math[l < 0? "max" : "min"](l, r);
+						if(rtl && ((isIE == 8 && !backCompat) || isIE >= 9)){ s = -s; }
+						old = el.scrollLeft;
+						el.scrollLeft += s;
+						s = el.scrollLeft - old;
+						nodePos.x -= s;
+					}
+					if(bot * t > 0 && (!!el.scrollTop || el == scrollRoot || el.scrollHeight > el.offsetHeight)){
+						s = Math.ceil(Math[t < 0? "max" : "min"](t, bot));
+						old = el.scrollTop;
+						el.scrollTop += s;
+						s = el.scrollTop - old;
+						nodePos.y -= s;
+					}
+					el = (el != scrollRoot) && !fixedPos && el.parentNode;
 				}
+			}catch(error){
+				console.error('scrollIntoView: ' + error);
+				node.scrollIntoView(false);
 			}
-			// calculate overflow in all 4 directions
-			var l = nodePos.x - elPos.x, // beyond left: < 0
-				t = nodePos.y - Math.max(elPos.y, 0), // beyond top: < 0
-				r = l + nodePos.w - elPos.w, // beyond right: > 0
-				bot = t + nodePos.h - elPos.h; // beyond bottom: > 0
-			if(r * l > 0){
-				var s = Math[l < 0? "max" : "min"](l, r);
-				if(rtl && ((isIE == 8 && !backCompat) || isIE >= 9)){ s = -s; }
-				nodePos.x += el.scrollLeft;
-				el.scrollLeft += s;
-				nodePos.x -= el.scrollLeft;
-			}
-			if(bot * t > 0){
-				nodePos.y += el.scrollTop;
-				el.scrollTop += Math[t < 0? "max" : "min"](t, bot);
-				nodePos.y -= el.scrollTop;
-			}
-			el = (el != scrollRoot) && !fixedPos && el.parentNode;
 		}
-	}catch(error){
-		console.error('scrollIntoView: ' + error);
-		node.scrollIntoView(false);
-	}
-};
+	};
+
+	has("extend-dojo") && lang.setObject("dojo.window", window);
 
-return window;
+	return window;
 });
diff --git a/dojox/.gitmodules b/dojox/.gitmodules
new file mode 100644
index 0000000..2f8644d
--- /dev/null
+++ b/dojox/.gitmodules
@@ -0,0 +1,9 @@
+[submodule "app"]
+	path = app
+	url = https://github.com/dmachi/dojox_application.git
+[submodule "calendar"]
+	path = calendar
+	url = https://github.com/damiengarbarino/dojo-calendar.git
+[submodule "dgauges"]
+	path = dgauges
+	url = https://github.com/dmandrioli/dgauges.git
diff --git a/dojox/LICENSE b/dojox/LICENSE
index aa6b39f..b1ddd34 100644
--- a/dojox/LICENSE
+++ b/dojox/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2011, The Dojo Foundation
+Copyright (c) 2005-2013, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/dojox/NodeList/delegate.js b/dojox/NodeList/delegate.js
index dfdb332..fedbcff 100644
--- a/dojox/NodeList/delegate.js
+++ b/dojox/NodeList/delegate.js
@@ -1,13 +1,14 @@
-define(["dojo/_base/lang", "dojo/query", "dojo/_base/NodeList", "dojo/NodeList-traverse"], function(lang, query, NodeList) {
-	// module:
-	//		dojox/NodeList/delegate
-	// summary:
-	//		TODOC
+define([
+	"dojo/_base/lang",
+	"dojo/query",
+	"dojo/_base/NodeList",	// for this.connect()
+	"dojo/NodeList-traverse"
+], function(lang, query) {
 
-/*=====
-// doc alias helpers:
-NodeList = dojo.NodeList;
-=====*/
+// module:
+//		dojox/NodeList/delegate
+
+var NodeList = query.NodeList;
 
 lang.extend(NodeList, {
 	delegate: function(/*String*/ selector, /*String*/ eventName, /*Function*/ fn){
@@ -36,7 +37,7 @@ lang.extend(NodeList, {
 		// fn:
 		//		Callback function passed the event object, and where this == the node that matches the selector.
 		//		That means that for example, after setting up a handler via
-		//			 dojo.query("body").delegate("fieldset", "onclick", ...)
+		// |		 dojo.query("body").delegate("fieldset", "onclick", ...)
 		//		clicking on a fieldset or *any nodes inside of a fieldset* will be reported
 		//		as a click on the fieldset itself.
 		// example:
@@ -57,7 +58,7 @@ lang.extend(NodeList, {
 			if(closest.length){
 				fn.call(closest[0], evt);
 			}
-		}); //dojo.NodeList
+		}); //dojo/NodeList
 	}
 });
 
diff --git a/dojox/NodeList/tests/delegate.html b/dojox/NodeList/tests/delegate.html
index ff0d35b..e04829f 100644
--- a/dojox/NodeList/tests/delegate.html
+++ b/dojox/NodeList/tests/delegate.html
@@ -7,7 +7,7 @@
 			@import "../../resources/dojo.css";
 		</style>
 		<script type="text/javascript" 
-			src="../../../dojo/dojo.js" djConfig="isDebug: true, popup: true"></script>
+			src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, popup: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.NodeList.delegate");
 				
diff --git a/dojox/analytics.js b/dojox/analytics.js
index fbd71e6..ac7048e 100644
--- a/dojox/analytics.js
+++ b/dojox/analytics.js
@@ -1,3 +1,10 @@
 define(["./analytics/_base"], function(analytics) {
+	/*=====
+	 return {
+		 // summary:
+		 //		Deprecated.  Should require dojox/analytics modules directly rather than trying to access them through
+		 //		this module.
+	 };
+	 =====*/
 	return analytics;
 });
diff --git a/dojox/analytics/README b/dojox/analytics/README
index 7299925..a6c4655 100644
--- a/dojox/analytics/README
+++ b/dojox/analytics/README
@@ -11,6 +11,7 @@ Project state:
 Project authors
 	Dustin Machi  (dmachi)
 	Peter Higgins (dante)
+	Ed Chatelain  (edchat) added touch and gesture support 11/15/2011.
 -------------------------------------------------------------------------------
 Project description
 	analytics and client monitoring system.  Including the base analytics
@@ -22,7 +23,10 @@ back to the server.  Plugins included at this time:
 	mouseOver - allows periodic sampling of mouseOver 
 	mouseClick - reports any mouse clicks to the server
 	idle - reports idle/activity 
-	consoleMessages - reports console.* messages to the server	
+	consoleMessages - reports console.* messages to the server
+	touchPress - reports touch.press and touch.release
+	touchMove - allows periodic sampling during a touch.move
+	gestureEvents - reports swipe, tap, tap.doubletap, tap.taphold	
 
 	Additionally, a Google Analytics (Urchin tracker) helper is included
 	in this project, though is unrelated to the Core dojox.analytics 
@@ -51,7 +55,7 @@ can use the system as such:
                 //tracks mouse clicks on the page
                 dojo.require("dojox.analytics.plugins.mouseClick");
 
-                // this plugin returns the informatin dojo collects when it launches
+                // this plugin returns the information dojo collects when it launches
                 dojo.require("dojox.analytics.plugins.dojo");
 
                 // this plugin return the information the window has when it launches
@@ -69,6 +73,17 @@ can use the system as such:
                 // and storing this data
                 dojo.require("dojox.analytics.plugins.mouseOver");
 
+                //tracks touch press and touch release on the page
+                dojo.require("dojox.analytics.plugins.touchPress");
+
+                // tracks where a touch move is done on a page, what it is over, periodically sampling
+                // and storing this data
+                dojo.require("dojox.analytics.plugins.touchMove");
+
+                // tracks these gesture events tap, taphold, doubletap, and swipe using the dojox.gesture 
+                // support. For swipe it will periodically sample and store the data
+                dojo.require("dojox.analytics.plugins.gestureEvents");
+
                 //tracks when the user has gone idle
                 dojo.require("dojox.analytics.plugins.idle");
 
@@ -100,27 +115,72 @@ Available Configuration Parameters:
 
 	consoleLogFuncs - functions from the console object that you will log to 
 			the server. If the console object doesn't exist
-			or a particuarl method doesn't exist it will be
+			or a particular method doesn't exist it will be
 			created as a remote logging only method. This provides
-			a quick and convient way to automatically define
-			a remote logging funciton that includes the functions
-			name in the log.  The 'rlog' in the default paramerters
+			a quick and convenient way to automatically define
+			a remote logging function that includes the functions
+			name in the log.  The 'rlog' in the default parameters
 			is an example of this.  Defaults to ["error", "warn", "info", "rlog"]	
 
 	idle Config:
 	
 		idleTime - Number of ms to be idle before being reported to the server as idle
 
+	mouseClick config:
+		targetProps - the properties whose values will be reported for each target from
+				a mouse click sample.  
+				defaults to ["id","className","nodeName", "localName","href", "spellcheck", "lang"]
+
+		textContentMaxChars - the max number of characters to show for text or textContent, defaults to 50
+
 	mouseOver config:
 		targetProps - the properties whose values will be reported for each target from
-				a mouse over sample.  defaults to ["id","className","localName","href", "spellcheck", "lang", "textContent", "value" ]
+				a mouse over sample.  
+				defaults to ["id","className","localName","href", "spellcheck", "lang", "textContent", "value" ]
+
+		watchMouseOver - log mouseover and mouseout events defaults to true
 
 		sampleDelay - the delay in ms between mouseover samples. Defaults to 2500
 
+		textContentMaxChars - the max number of characters to show for text or textContent, defaults to 50
+
 	window config:
 		windowConnects - methods on the window objec that will be attached to 
 				have its data passed to the server when called.
 
+	touchPress config:
+		targetProps - the properties whose values will be reported for each target from
+				a touch.press or touch.release sample.  
+				defaults to ["id","className","nodeName", "localName","href", "spellcheck", "lang"]
+
+		textContentMaxChars - the max number of characters to show for text or textContent, defaults to 50
+
+		showTouchesDetails - include the details for the touches in the touches array, defaults to true
+
+
+	touchMove config:
+		targetProps - the properties whose values will be reported for each target from
+				a touch move sample.  
+				defaults to ["id","className","localName","href", "spellcheck", "lang", "textContent", "value" ]
+
+		textContentMaxChars - the max number of characters to show for text or textContent, defaults to 50
+
+		showTouchesDetails - include the details for the touches in the touches array, defaults to true
+
+		touchSampleDelay - the delay in ms between touch.move samples. Defaults to 1000
+
+	gestureEvents config:
+		targetProps - the properties whose values will be reported for each target from
+				a gesture event (tap, taphold, doubletap, swipe) sample.  
+				defaults to ["id","className","localName","href", "spellcheck", "lang", "textContent", "value" ]
+
+		swipeSampleDelay - the delay in ms between swipe samples. Defaults to 1000
+
+		textContentMaxChars - the max number of characters to show for text or textContent, defaults to 50
+
+		watchSwipe - log swipe events in addition to the tap events, defaults to true
+
+
 	
 Note that the basic usage of this system simply serializes json with toJson() when passed
 to the analytics addData() method.  If data is passed that has circular references
diff --git a/dojox/analytics/Urchin.js b/dojox/analytics/Urchin.js
index 2fb4707..c48bd09 100644
--- a/dojox/analytics/Urchin.js
+++ b/dojox/analytics/Urchin.js
@@ -3,7 +3,7 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 ], function(lang, declare, window, config, construct){
 
 	/*=====
-	dojo.mixin(djConfig,{
+	lang.mixin(config,{
 		// urchin: String
 		//		Used by `dojox.analytics.Urchin` as the default UA-123456-7 account
 		//		number used when being created. Alternately, you can pass an acct:""
@@ -13,9 +13,9 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 	=====*/
 
 	return declare("dojox.analytics.Urchin", null, {
-		// summary: A Google-analytics helper, for post-onLoad inclusion of the tracker, and
+		// summary:
+		//		A Google-analytics helper, for post-onLoad inclusion of the tracker, and
 		//		dynamic tracking during long-lived page cycles.
-		//
 		// description:
 		//		A small class object will allows for lazy-loading the Google Analytics API
 		//		at any point during a page lifecycle. Most commonly, Google-Analytics is loaded
@@ -32,12 +32,11 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 		//		This module will not work simultaneously with the core dojox.analytics
 		//		package. If you need the ability to run Google Analytics AND your own local
 		//		analytics system, you MUST include dojox.analytics._base BEFORE dojox.analytics.Urchin
-		//
-		//	example:
+		// example:
 		//	|	// create the tracker programatically:
 		//	|	var tracker = new dojox.analytics.Urchin({ acct:"UA-123456-7" });
 		//
-		//	example:
+		// example:
 		//	|	// define the urchin djConfig option:
 		//	|	var djConfig = { urchin: "UA-123456-7" };
 		//	|
@@ -46,10 +45,10 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 		//	|	// or code:
 		//	|	new dojox.analytics.Urchin();
 		//
-		//	example:
+		// example:
 		//	|	// create and define all analytics with one tag.
 		//	|	<div dojoType="dojox.analytics.Urchin" acct="UA-12345-67"></div>
-		//
+
 		// acct: String
 		//		your GA urchin tracker account number. Overrides `djConfig.urchin`
 		acct: "",
@@ -81,7 +80,8 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 		},
 
 		_gotGA: function(){
-			// summary: initialize the tracker
+			// summary:
+			//		initialize the tracker
 			this.tracker = _gat._getTracker(this.acct);
 			this.GAonLoad.apply(this, arguments);
 		},
@@ -89,15 +89,15 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 		GAonLoad: function(){
 			// summary:
 			//		Stub function to fire when urchin is complete
-			//	description:
+			// description:
 			//		This function is executed when the tracker variable is
 			//		complete and initialized. The initial trackPageView (with
 			//		no arguments) is called here as well, so remeber to call
 			//		manually if overloading this method.
 			//
-			//	example:
-			//	Create an Urchin tracker that will track a specific page on init
-			//	after page load (or parsing, if parseOnLoad is true)
+			// example:
+			//		Create an Urchin tracker that will track a specific page on init
+			//		after page load (or parsing, if parseOnLoad is true)
 			//	|	dojo.addOnLoad(function(){
 			//	|		new dojox.ananlytics.Urchin({
 			//	|			acct:"UA-12345-67",
@@ -111,14 +111,13 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 		},
 
 		trackPageView: function(/* string */url){
-			// summary: A public API attached to this widget instance, allowing you
+			// summary:
+			//		A public API attached to this widget instance, allowing you
 			//		Ajax-like notification of updates.
-			//
-			//	url: String
+			// url: String
 			//		A location to tell the tracker to track, eg: "/my-ajaxy-endpoint"
-			//
-			//	example:
-			//	Track clicks from a container of anchors and populate a `ContentPane`
+			// example:
+			//		Track clicks from a container of anchors and populate a `ContentPane`
 			//	|	// 'tracker' is our `Urchin` instance, pane is the `ContentPane` ref.
 			//	|	dojo.connect(container, "onclick", function(e){
 			//	|		var ref = dojo.attr(e.target, "href");
diff --git a/dojox/analytics/_base.js b/dojox/analytics/_base.js
index 33a0074..ae69980 100644
--- a/dojox/analytics/_base.js
+++ b/dojox/analytics/_base.js
@@ -1,114 +1,107 @@
-define(["dojo/_base/lang", "dojo/_base/config", "dojo/ready", "dojo/_base/unload", 
-        "dojo/_base/sniff", "dojo/_base/xhr", "dojo/_base/json", "dojo/io-query", "dojo/io/script"
-], function(lang, config, ready, unload, has, xhr, json, ioQuery, scriptIO){
-	/*=====
-		ready = dojo.ready;
-		ioQuery = dojo/io-query;
-		scriptIO = dojo/io/script;
-	=====*/
+define(["dojo/_base/lang", "dojo/_base/config", "dojo/ready", "dojo/_base/unload",
+        "dojo/_base/sniff", "dojo/request", "dojo/json", "dojo/io-query", "dojo/request/script"
+], function(lang, config, ready, unload, has, request, JSON, ioQuery, script){
 
 	var Analytics = function(){
-		// summary: TODOC
+		// summary:
 		//		where we store data until we're ready to send it off.
-		//
-		//the data queue;
+
+		// the data queue;
 		this._data = [];
 
-		//id of messages for this session/page
+		// id of messages for this session/page
 		this._id = 1;
 
-		//some default values
+		// some default values
 		this.sendInterval = config["sendInterval"] || 5000;
 		this.inTransitRetry = config["inTransitRetry"] || 200;
 		this.dataUrl = config["analyticsUrl"] || require.toUrl("dojox/analytics/logger/dojoxAnalytics.php");
 		this.sendMethod = config["sendMethod"] || "xhrPost";
 		this.maxRequestSize = has("ie") ? 2000 : config["maxRequestSize"] || 4000;
 
-		//while we can go ahead and being logging as soon as this constructor is completed
-		//we're not going to schedule pushing data to the server until after the page
-		//has completed loading
+		// while we can go ahead and being logging as soon as this constructor is completed
+		// we're not going to schedule pushing data to the server until after the page
+		// has completed loading
 		ready(this, "schedulePusher");
-		unload.addOnUnload(this, "pushData", true);
+		unload.addOnUnload(this, function(){
+			this.pushData();
+		});
 	};
 
 	lang.extend(Analytics, {
 		schedulePusher: function(/* Int */interval){
-			// summary: Schedule the data pushing routines to happen in interval ms
+			// summary:
+			//		Schedule the data pushing routines to happen in interval ms
 			setTimeout(lang.hitch(this, "checkData"), interval || this.sendInterval);
 		},
 
 		addData: function(dataType, data){
 			// summary:
-			//	add data to the queue. Will be pusshed to the server on the next
-			//	data push
+			//		add data to the queue. Will be pusshed to the server on the next
+			//		data push
 
 			if(arguments.length > 2){
 				// FIXME: var c = dojo._toArray(arguments) ?
-				var c = [];
-				for(var i = 1; i < arguments.length; i++){
-					c.push(arguments[i]);
-				}
-				data = c;
+				data = Array.prototype.slice.call(arguments,1);
 			}
 
 			this._data.push({ plugin: dataType, data: data });
 		},
 
 		checkData: function(){
-			// summary: TODOC?
+			// summary:
+			//		TODOC?
 			if(this._inTransit){
 				this.schedulePusher(this.inTransitRetry);
 				return;
 			}
-			
+
 			if(this.pushData()){ return; }
 			this.schedulePusher();
 		},
 
 		pushData: function(){
 			// summary:
-			//	pushes data to the server if any exists.  If a push is done, return
-			//	the deferred after hooking up completion callbacks.  If there is no data
-			//	to be pushed, return false;
+			//		pushes data to the server if any exists.  If a push is done, return
+			//		the deferred after hooking up completion callbacks.  If there is no data
+			//		to be pushed, return false;
 			if(this._data.length){
-				//clear the queue
+				// clear the queue
 				this._inTransit = this._data;
 				this._data = [];
-				var def;
+				var promise;
 				switch(this.sendMethod){
 					case "script":
-						def = scriptIO.get({
-							url: this.getQueryPacket(),
+						promise = script.get(this.getQueryPacket(), {
 							preventCache: 1,
 							callbackParamName: "callback"
 						});
 						break;
 					case "xhrPost":
 					default:
-						def = xhr.post({
-							url:this.dataUrl,
-							content:{
+						promise = request.post(this.dataUrl, {
+							data:{
 								id: this._id++,
-								data: json.toJson(this._inTransit)
+								data: JSON.stringify(this._inTransit)
 							}
 						});
 						break;
 				}
-				def.addCallback(this, "onPushComplete");
-				return def;
+				promise.then(lang.hitch(this, "onPushComplete"));
+				return promise;
 			}
 			return false;
 		},
 
 		getQueryPacket: function(){
-			// summary: TODOC
+			// TODOC
 			while(true){
 				var content = {
 					id: this._id++,
-					data: json.toJson(this._inTransit)
+					data: JSON.stringify(this._inTransit)
 				};
-				
-				//FIXME would like a much better way to get the query down to length
+
+				// FIXME would like a much better way to get the query down to length
 				var query = this.dataUrl + '?' + ioQuery.objectToQuery(content);
 				if(query.length > this.maxRequestSize){
 					this._data.unshift(this._inTransit.pop());
@@ -121,8 +114,8 @@ define(["dojo/_base/lang", "dojo/_base/config", "dojo/ready", "dojo/_base/unload
 
 		onPushComplete: function(results){
 			// summary:
-			//	If our data push was successfully, remove the _inTransit data and schedule the next
-			//	parser run.
+			//		If our data push was successfully, remove the _inTransit data and schedule the next
+			//		parser run.
 			if(this._inTransit){
 				delete this._inTransit;
 			}
@@ -135,6 +128,6 @@ define(["dojo/_base/lang", "dojo/_base/config", "dojo/ready", "dojo/_base/unload
 		}
 	});
 
-	//create the analytics  singleton
+	// create the analytics singleton
 	return lang.setObject("dojox.analytics",new Analytics());
 });
diff --git a/dojox/analytics/logger/dojoxAnalytics.php b/dojox/analytics/logger/dojoxAnalytics.php
index dfc7ac8..e472498 100644
--- a/dojox/analytics/logger/dojoxAnalytics.php
+++ b/dojox/analytics/logger/dojoxAnalytics.php
@@ -21,7 +21,7 @@
 	
 	fclose($handle);
 
-	$response = "{'eventsRecieved': '" . sizeof($items) . "', 'id': '" . $id . "'}";
+	$response = '{"eventsReceived": "' . sizeof($items) . '", "id": "' . $id . '"}';
 	if ($_REQUEST["callback"]){
 		print htmlentities($_REQUEST["callback"]) . "(" . $response . ");";
 	}else{
diff --git a/dojox/analytics/plugins/consoleMessages.js b/dojox/analytics/plugins/consoleMessages.js
index 19602cd..da24aa1 100644
--- a/dojox/analytics/plugins/consoleMessages.js
+++ b/dojox/analytics/plugins/consoleMessages.js
@@ -1,13 +1,10 @@
-define(["dojo/_base/lang","../_base", "dojo/_base/config", "dojo/aspect"
+define(["dojo/_base/lang", "../_base", "dojo/_base/config", "dojo/aspect"
 ], function(lang, dxa, config, aspect){
-	/*=====
-		dxa = dojox.analytics;
-		aspect = dojo.aspect;
-	=====*/
-	consoleMessages = lang.getObject("dojox.analytics.plugins.consoleMessages", true);
+
+	var consoleMessages = lang.getObject("dojox.analytics.plugins.consoleMessages", true);
 
 		// summary:
-		//	plugin to have analyitcs return the base info dojo collects
+		//		plugin to have analyitcs return the base info dojo collects
 		this.addData = lang.hitch(dxa, "addData", "consoleMessages");
 
 		var lvls = config["consoleLogFuncs"] || ["error", "warn", "info", "rlog"];
@@ -15,11 +12,12 @@ define(["dojo/_base/lang","../_base", "dojo/_base/config", "dojo/aspect"
 			console = {};
 		}
 
-		for(var i=0; i < lvls.length; i++){
-			if(console[lvls[i]]){
-				aspect.after(console, lvls[i], lang.hitch(this, "addData", lvls[i]),true);
+		for(var i = 0; i < lvls.length; i++){
+			var fnName = lvls[i], _addData = lang.hitch(this, "addData", fnName);
+			if(console[fnName]){
+				aspect.after(console, fnName, _addData,true);
 			}else{
-				console[lvls[i]] = lang.hitch(this, "addData", lvls[i]);
+				console[fnName] = _addData;
 			}
 		}
 	return consoleMessages;
diff --git a/dojox/analytics/plugins/dojo.js b/dojox/analytics/plugins/dojo.js
index 75f367d..1ee9c93 100644
--- a/dojox/analytics/plugins/dojo.js
+++ b/dojox/analytics/plugins/dojo.js
@@ -1,26 +1,20 @@
 define(["dojo/_base/lang","../_base", "dojo/_base/config", "dojo/ready"
 ], function(lang, dxa, config, ready){
 	var plugins = lang.getObject("dojox.analytics.plugins", true);
-	/*=====
-		dxa = dojox.analytics;
-		ready = dojo.ready;
-		plugins = dojox.analytics.plugins; 
-		plugins.dojo = dojox.analytics.plugins.dojo;
-	=====*/	
 
 	return (plugins.dojo = new (function(){
 		// summary:
-		//	plugin to have analyitcs return the base info dojo collects
+		//		plugin to have analyitcs return the base info dojo collects
 		this.addData = lang.hitch(dxa, "addData", "dojo");
 		ready(lang.hitch(this, function(){
 			var data = {};
 			for(var i in dojo){
-				if ((i=="version") || ((!(typeof dojo[i] == "object" || typeof dojo[i] == "function"))&&(i[0]!="_"))){
-					data[i]=dojo[i];
+				if((i == "version") || ((!(typeof dojo[i] == "object" || typeof dojo[i] == "function")) && (i[0] != "_"))){
+					data[i] = dojo[i];
 				}
 			}
 
-			if (config){data.djConfig=config}
+			if(config){data.djConfig = config}
 			this.addData(data);
 		}));
 	})());
diff --git a/dojox/analytics/plugins/gestureEvents.js b/dojox/analytics/plugins/gestureEvents.js
new file mode 100644
index 0000000..c6718d2
--- /dev/null
+++ b/dojox/analytics/plugins/gestureEvents.js
@@ -0,0 +1,95 @@
+define(["dojo/_base/lang","../_base", "dojo/_base/window", "dojo/on", "dojo/_base/config", "dojo/touch",
+		"dojox/gesture/tap", "dojox/gesture/swipe"
+
+], function(lang, dxa, window, on, config, touch, tap, swipe){
+
+	// window startup data
+	return (dxa.plugins.gestureEvents = new (function(){
+
+		// watch for dojox.gesture.swipe, use delay to avoid getting too many
+		if(config["watchSwipe"] !== undefined && !config["watchSwipe"]){
+			this.watchSwipe = false;			
+		}else{
+			this.watchSwipe = true;
+		}
+		this.swipeSampleDelay = config["swipeSampleDelay"] || 1000;
+		this.targetProps = config["targetProps"] || ["id","className","localName","href", "spellcheck", "lang", "textContent", "value" ];
+		this.textContentMaxChars = config["textContentMaxChars"] || 50;
+
+		this.addDataSwipe = lang.hitch(dxa, "addData", "gesture.swipe");
+		this.sampleSwipe = function(e){
+			if(!this._rateLimited){
+				this.addDataSwipe(this.trimEvent(e));
+				this._rateLimited = true;
+				setTimeout(lang.hitch(this, function(){
+					if(this._rateLimited){
+						this.trimEvent(this._lastSwipeEvent);
+						delete this._lastSwipeEvent;
+						delete this._rateLimited;
+					}
+				}), this.swipeSampleDelay);
+			}
+			this._lastSwipeEvent = e;
+			return e;
+		}
+		if(this.watchSwipe){
+			on(window.doc, swipe, lang.hitch(this, "sampleSwipe"));
+		}
+		
+		
+		// watch for dojox.gesture.tap
+		this.addData = lang.hitch(dxa, "addData", "gesture.tap");
+		this.onGestureTap = function(e){
+			this.addData(this.trimEvent(e));
+		}
+		on(window.doc, tap, lang.hitch(this, "onGestureTap"));
+
+		// watch for dojox.gesture.tap.doubletap
+		this.addDataDoubleTap = lang.hitch(dxa, "addData", "gesture.tap.doubletap");
+		this.onGestureDoubleTap = function(e){
+			this.addDataDoubleTap(this.trimEvent(e));
+		}
+		on(window.doc, tap.doubletap, lang.hitch(this, "onGestureDoubleTap"));
+
+		// watch for dojox.gesture.tap.taphold
+		this.addDataTapHold = lang.hitch(dxa, "addData", "gesture.tap.taphold");
+		this.onGestureTapHold = function(e){
+			this.addDataTapHold(this.trimEvent(e));
+		}
+		on(window.doc, tap.hold, lang.hitch(this, "onGestureTapHold"));
+			
+		
+		this.trimEvent = function(e){
+			var t = {};
+			for(var i in e){
+				switch(i){
+					case "target":
+						var props = this.targetProps;						
+						t[i] = {};
+						for(var j = 0;j < props.length;j++){
+							if(e[i][props[j]]){
+								if(props[j] == "text" || props[j] == "textContent"){
+									if((e[i]["localName"] != "HTML") && (e[i]["localName"] != "BODY")){
+										t[i][props[j]] = e[i][props[j]].substr(0,this.textContentMaxChars);
+									}
+								}else{
+									t[i][props[j]] = e[i][props[j]];
+								}
+							}
+						}
+						break;
+					case "clientX":
+					case "clientY":
+					case "screenX":
+					case "screenY":
+					case "dx":
+					case "dy":
+					case "time":
+						t[i] = e[i];
+						break;
+				}
+			}
+			return t;
+		}
+	})());
+});
diff --git a/dojox/analytics/plugins/idle.js b/dojox/analytics/plugins/idle.js
index 236d455..688d109 100644
--- a/dojox/analytics/plugins/idle.js
+++ b/dojox/analytics/plugins/idle.js
@@ -1,38 +1,33 @@
 define(["dojo/_base/lang", "../_base", "dojo/_base/config", "dojo/ready", 
-        "dojo/aspect", "dojo/_base/window"
+		"dojo/aspect", "dojo/_base/window"
 ], function(lang, dxa, config, ready, aspect, window){
-	/*=====
-		dxa = dojox.analytics;
-		ready = dojo.ready;
-		aspect = dojo/aspect;
-	=====*/
 
 	// window startup data
 	return (dxa.plugins.idle = new (function(){
 		this.addData = lang.hitch(dxa, "addData", "idle");
-		this.idleTime=config["idleTime"] || 60000;
-		this.idle=true;
+		this.idleTime = config["idleTime"] || 60000;
+		this.idle = true;
 
 		this.setIdle = function(){
 			this.addData("isIdle");
-			this.idle=true;
+			this.idle = true;
 
 		}
 
 		ready(lang.hitch(this, function(){
-			var idleResets=["onmousemove","onkeydown","onclick","onscroll"];
-			for (var i=0;i<idleResets.length;i++){
+			var idleResets = ["onmousemove","onkeydown","onclick","onscroll"];
+			for(var i = 0;i < idleResets.length;i++){
 				aspect.after(window.doc,idleResets[i],lang.hitch(this, function(e){
-					if (this.idle){
-						this.idle=false;
+					if(this.idle){
+						this.idle = false;
 						this.addData("isActive");
-						this.idleTimer=setTimeout(lang.hitch(this,"setIdle"), this.idleTime);
+						this.idleTimer = setTimeout(lang.hitch(this,"setIdle"), this.idleTime);
 					}else{
 						clearTimeout(this.idleTimer);
-						this.idleTimer=setTimeout(lang.hitch(this,"setIdle"), this.idleTime);
+						this.idleTimer = setTimeout(lang.hitch(this,"setIdle"), this.idleTime);
 					}
 				}),true);
 			}
 		}));
 	})());
-});
\ No newline at end of file
+});
diff --git a/dojox/analytics/plugins/mouseClick.js b/dojox/analytics/plugins/mouseClick.js
index 02c0bc8..37bced1 100644
--- a/dojox/analytics/plugins/mouseClick.js
+++ b/dojox/analytics/plugins/mouseClick.js
@@ -1,36 +1,35 @@
-define(["dojo/_base/lang","../_base", "dojo/_base/window", "dojo/on"
-], function(lang, dxa, window, on){
-	/*=====
-		dxa = dojox.analytics;
-		on = dojo.on;
-	=====*/	
+define(["dojo/_base/lang","../_base", "dojo/_base/config", "dojo/_base/window", "dojo/on"
+], function(lang, dxa, config, window, on){
 
 	// window startup data
 	return (dxa.plugins.mouseClick = new (function(){
 		this.addData = lang.hitch(dxa, "addData", "mouseClick");
+		this.targetProps = config["targetProps"] || ["id","className","nodeName", "localName","href", "spellcheck", "lang"];
+		this.textContentMaxChars = config["textContentMaxChars"] || 50;
 
-		this.onClick=function(e){
+		this.onClick = function(e){
 			this.addData(this.trimEvent(e));
-		}
+		};
 		on(window.doc, "click", lang.hitch(this, "onClick"));
 
-		this.trimEvent=function(e){
+		this.trimEvent = function(e){
 			var t = {};
-			for (var i in e){
+			for(var i in e){
 				switch(i){
 					case "target":
 					case "originalTarget":
 					case "explicitOriginalTarget":
-						var props=["id","className","nodeName", "localName","href", "spellcheck", "lang"];
-						t[i]={};
-						for(var j=0;j<props.length;j++){
+						//var props = ["id","className","nodeName", "localName","href", "spellcheck", "lang"];
+						var props = this.targetProps;
+						t[i] = {};
+						for(var j = 0;j < props.length;j++){
 							if(e[i][props[j]]){
-								if (props[j]=="text" || props[j]=="textContent"){
-									if ((e[i]["localName"]!="HTML")&&(e[i]["localName"]!="BODY")){
-										t[i][props[j]]=e[i][props[j]].substr(0,50);
+								if(props[j] == "text" || props[j] == "textContent"){
+									if((e[i]["localName"] != "HTML") && (e[i]["localName"] != "BODY")){
+										t[i][props[j]] = e[i][props[j]].substr(0,this.textContentMaxChars);
 									}
 								}else{
-									t[i][props[j]]=e[i][props[j]];
+									t[i][props[j]] = e[i][props[j]];
 								}
 							}
 						}
@@ -41,11 +40,11 @@ define(["dojo/_base/lang","../_base", "dojo/_base/window", "dojo/on"
 					case "pageY":
 					case "screenX":
 					case "screenY":
-						t[i]=e[i];
+						t[i] = e[i];
 						break;
 				}
 			}
 			return t;
-		}
+		};
 	})());
-});
\ No newline at end of file
+});
diff --git a/dojox/analytics/plugins/mouseOver.js b/dojox/analytics/plugins/mouseOver.js
index f8c024c..231ce89 100644
--- a/dojox/analytics/plugins/mouseOver.js
+++ b/dojox/analytics/plugins/mouseOver.js
@@ -1,36 +1,33 @@
 define(["dojo/_base/lang", "../_base", "dojo/_base/config", "dojo/_base/window", "dojo/on"
 ], function(lang, dxa, config, window, on){
-	/*=====
-		dxa = dojox.analytics;
-		on = dojo.on;
-	=====*/	
 
 	return (dxa.plugins.mouseOver = new (function(){
 		this.watchMouse = config["watchMouseOver"] || true;
 		this.mouseSampleDelay = config["sampleDelay"] || 2500;
 		this.addData = lang.hitch(dxa, "addData", "mouseOver");
 		this.targetProps = config["targetProps"] || ["id","className","localName","href", "spellcheck", "lang", "textContent", "value" ];
+		this.textContentMaxChars = config["textContentMaxChars"] || 50;
 
-		this.toggleWatchMouse=function(){
-			if (this._watchingMouse){
+		this.toggleWatchMouse = function(){
+			if(this._watchingMouse){
 				this._watchingMouse.remove();
 				delete this._watchingMouse;
 				return;
 			}
 			on(window.doc, "mousemove", lang.hitch(this, "sampleMouse"));
-		}
+		};
 
-		if (this.watchMouse){
+		if(this.watchMouse){
 			on(window.doc, "mouseover", lang.hitch(this, "toggleWatchMouse"));
 			on(window.doc, "mouseout", lang.hitch(this, "toggleWatchMouse"));
 		}
 
-		this.sampleMouse=function(e){
-			if (!this._rateLimited){
+		this.sampleMouse = function(e){
+			if(!this._rateLimited){
 				this.addData("sample",this.trimMouseEvent(e));
-				this._rateLimited=true;
+				this._rateLimited = true;
 				setTimeout(lang.hitch(this, function(){
-					if (this._rateLimited){
+					if(this._rateLimited){
 						//this.addData("sample", this.trimMouseEvent(this._lastMouseEvent));
 						this.trimMouseEvent(this._lastMouseEvent);
 						delete this._lastMouseEvent;
@@ -40,45 +37,46 @@ define(["dojo/_base/lang", "../_base", "dojo/_base/config", "dojo/_base/window",
 			}
 			this._lastMouseEvent = e;
 			return e;
-		}
+		};
 
-		this.trimMouseEvent=function(e){
+		this.trimMouseEvent = function(e){
 			var t = {};
-			for (var i in e){
+			for(var i in e){
 				switch(i){
-					//case "currentTarget":
+					//case "currentTarget":  //currentTarget caused an error
 					case "target":
 					//case "originalTarget":
 					//case "explicitOriginalTarget":
-						var props=this.targetProps;
-						t[i]={};
+						var props = this.targetProps;
+						t[i] = {};
 						//console.log(e, i, e[i]);
-						for(var j=0;j<props.length;j++){
+						for(var j = 0;j < props.length;j++){
 							if((typeof e[i] == "object" || typeof e[i] == "function") && props[j] in e[i]){
 								 
-								if (props[j]=="text" || props[j]=="textContent"){
-									if (e[i]["localName"] && (e[i]["localName"]!="HTML")&&(e[i]["localName"]!="BODY")){
-										t[i][props[j]]=e[i][props[j]].substr(0,50);
+								if(props[j] == "text" || props[j] == "textContent"){
+									if(e[i]["localName"] && (e[i]["localName"] != "HTML") && (e[i]["localName"] != "BODY")){
+										t[i][props[j]] = e[i][props[j]].substr(0,this.textContentMaxChars);
 									}
 								}else{
-									t[i][props[j]]=e[i][props[j]];
+									t[i][props[j]] = e[i][props[j]];
 								}
 							}
 						}
 						break;
+					// clientX, pageX and x are usually the same so no need to show all 3, same for y
 					//case "clientX":
 					//case "clientY":
 					//case "pageX":
 					//case "pageY":
-					//case "screenX":
-					//case "screenY":
+					case "screenX":
+					case "screenY":
 					case "x":
 					case "y":
-						if (e[i]) {
+						if(e[i]){
 							//console.log("Attempting: " + i);
 							var val = e[i];
 							//console.log("val: " +  val); console.log(i + "e of i: " + val);
-							t[i]=val + '';
+							t[i] = val + '';
 						}
 						break;
 					default:
@@ -87,6 +85,6 @@ define(["dojo/_base/lang", "../_base", "dojo/_base/config", "dojo/_base/window",
 				}
 			}
 			return t;
-		}
+		};
 	})());
-});
\ No newline at end of file
+});
diff --git a/dojox/analytics/plugins/touchMove.js b/dojox/analytics/plugins/touchMove.js
new file mode 100644
index 0000000..fee7e1c
--- /dev/null
+++ b/dojox/analytics/plugins/touchMove.js
@@ -0,0 +1,109 @@
+define(["dojo/_base/lang", "../_base", "dojo/_base/config", "dojo/_base/window", "dojo/on", "dojo/touch"
+], function(lang, dxa, config, window, on, touch){
+
+
+	return (dxa.plugins.touchMove = new (function(){
+		if(config["watchTouch"] !== undefined && !config["watchTouch"]){
+			this.watchTouch = false;			
+		}else{
+			this.watchTouch = true;
+		}
+		if(config["showTouchesDetails"] !== undefined && !config["showTouchesDetails"]){
+			this.showTouchesDetails = false;			
+		}else{
+			this.showTouchesDetails = true;
+		}
+		this.touchSampleDelay = config["touchSampleDelay"] || 1000;
+		this.targetProps = config["targetProps"] || ["id","className","localName","href", "spellcheck", "lang", "textContent", "value" ];
+		this.textContentMaxChars = config["textContentMaxChars"] || 50;
+		this.addData = lang.hitch(dxa, "addData", "touch.move");
+		
+		this.sampleTouchMove = function(e){
+			if(!this._rateLimited){
+				this.addData("sample",this.trimTouchEvent(e));
+				this._rateLimited = true;
+				setTimeout(lang.hitch(this, function(){
+					if(this._rateLimited){
+						this.trimTouchEvent(this._lastTouchEvent);
+						delete this._lastTouchEvent;
+						delete this._rateLimited;
+					}
+				}), this.touchSampleDelay);
+			}
+			this._lastTouchEvent = e;
+			return e;
+		};
+
+		on(window.doc, touch.move, lang.hitch(this, "sampleTouchMove"));
+
+		this.handleTarget = function(t, target, i){
+			var props = this.targetProps;
+			t[i] = {};
+			for(var j = 0;j < props.length;j++){
+				if((typeof target == "object" || typeof target == "function") && props[j] in target){
+								 
+					if(props[j] == "text" || props[j] == "textContent"){
+						if(target["localName"] && (target["localName"] != "HTML") && (target["localName"] != "BODY")){
+							t[i][props[j]] = target[props[j]].substr(0,this.textContentMaxChars);
+						}
+					}else{
+						t[i][props[j]] = target[props[j]];
+					}
+				}
+			}
+		};
+		
+		this.trimTouchEvent = function(e){
+			var t = {};
+			var val;
+			for(var i in e){
+				switch(i){
+					case "target":
+						this.handleTarget(t, e[i], i)
+						break;
+						case "touches":
+							if(e[i].length !== 0){
+								t["touches.length"] = e[i].length;
+							}
+							if(this.showTouchesDetails){
+								for(var j = 0;j < e[i].length;j++){
+									for(var s in e[i][j]){
+										switch(s){
+											case "target":
+												this.handleTarget(t, e[i][j].target, "touches["+j+"][target]");
+											break;	
+											case "clientX":
+											case "clientY":
+											case "screenX":
+											case "screenY":
+												if(e[i][j]){
+													val = e[i][j][s];
+													t["touches["+j+"]["+s+"]"] = val + '';
+												}
+											break;
+											default:
+												//console.log("Skipping: ", i);
+											break;
+										}
+									}
+								}
+							}
+						break;
+					case "clientX":
+					case "clientY":
+					case "screenX":
+					case "screenY":
+						if(e[i]){
+							val = e[i];
+							t[i] = val + '';
+						}
+						break;
+					default:
+						//console.log("Skipping: ", i);
+						break;
+				}
+			}
+			return t;
+		};
+	})());
+});
diff --git a/dojox/analytics/plugins/touchPress.js b/dojox/analytics/plugins/touchPress.js
new file mode 100644
index 0000000..aa8fabb
--- /dev/null
+++ b/dojox/analytics/plugins/touchPress.js
@@ -0,0 +1,91 @@
+define(["dojo/_base/lang","../_base", "dojo/_base/config", "dojo/_base/window", "dojo/on", "dojo/touch"
+], function(lang, dxa, config, window, on, touch){
+
+	// window startup data
+	return (dxa.plugins.touchPress = new (function(){
+		if(config["showTouchesDetails"] !== undefined && !config["showTouchesDetails"]){
+			this.showTouchesDetails = false;			
+		}else{
+			this.showTouchesDetails = true;
+		}
+		this.targetProps = config["targetProps"] || ["id","className","nodeName", "localName","href", "spellcheck", "lang"];
+		this.textContentMaxChars = config["textContentMaxChars"] || 50;
+
+		this.addData = lang.hitch(dxa, "addData", "touch.press");
+		this.onTouchPress = function(e){
+			this.addData(this.trimEvent(e));
+		};
+
+		this.addDataRelease = lang.hitch(dxa, "addData", "touch.release");
+		this.onTouchRelease = function(e){
+			this.addDataRelease(this.trimEvent(e));
+		};
+
+		on(window.doc, touch.press, lang.hitch(this, "onTouchPress"));
+		on(window.doc, touch.release, lang.hitch(this, "onTouchRelease"));
+
+		this.handleTarget = function(t, target, i){
+			var props = this.targetProps;
+			t[i] = {};
+			for(var j = 0;j < props.length;j++){
+				if((typeof target == "object" || typeof target == "function") && props[j] in target){
+								 
+					if(props[j] == "text" || props[j] == "textContent"){
+						if(target["localName"] && (target["localName"] != "HTML") && (target["localName"] != "BODY")){
+							t[i][props[j]] = target[props[j]].substr(0,this.textContentMaxChars);
+						}
+					}else{
+						t[i][props[j]] = target[props[j]];
+					}
+				}
+			}
+		};
+		
+
+		this.trimEvent = function(e){
+			var t = {};
+			for(var i in e){
+				switch(i){
+					case "target":
+						this.handleTarget(t, e[i], i)
+						break;
+						case "touches":
+							if(e[i].length !== 0){
+								t["touches.length"] = e[i].length;
+							}
+							if(this.showTouchesDetails){
+								for(var j = 0;j < e[i].length;j++){
+									for(var s in e[i][j]){
+										switch(s){
+											case "target":
+												this.handleTarget(t, e[i][j].target, "touches["+j+"][target]");
+											break;	
+											case "clientX":
+											case "clientY":
+											case "screenX":
+											case "screenY":
+												if(e[i][j]){
+													var val = e[i][j][s];
+													t["touches["+j+"]["+s+"]"] = val + '';
+												}
+											break;
+											default:
+												//console.log("Skipping: ", i);
+											break;
+										}
+									}
+								}
+							}
+						break;
+					case "clientX":
+					case "clientY":
+					case "screenX":
+					case "screenY":
+						t[i] = e[i];
+						break;
+				}
+			}
+			return t;
+		};
+	})());
+});
diff --git a/dojox/analytics/plugins/window.js b/dojox/analytics/plugins/window.js
index 38c8dfa..163ce1d 100644
--- a/dojox/analytics/plugins/window.js
+++ b/dojox/analytics/plugins/window.js
@@ -1,37 +1,32 @@
 define(["dojo/_base/lang","../_base", "dojo/ready", "dojo/_base/config", "dojo/aspect"
 ], function(lang, dxa, ready, config, aspect){
-	/*=====
-		dxa = dojox.analytics;
-		ready = dojo.ready;
-		aspect = dojo.aspect;
-	=====*/	
 
 	// window startup data
 	return (dxa.plugins.window = new (function(){
 		this.addData = lang.hitch(dxa, "addData", "window");
 		this.windowConnects = config["windowConnects"] || ["open", "onerror"];
 
-		for(var i=0; i<this.windowConnects.length;i++){
+		for(var i = 0; i < this.windowConnects.length;i++){
 			aspect.after(window, this.windowConnects[i], lang.hitch(this, "addData", this.windowConnects[i]),true);
 		}
 
 		ready(lang.hitch(this, function(){
 			var data = {};
 			for(var i in window){
-				if (typeof window[i] == "object" || typeof window[i] == "function"){
+				if(typeof window[i] == "object" || typeof window[i] == "function"){
 					switch(i){
 						case "location":
 						case "console":
-							data[i]=window[i];
+							data[i] = window[i];
 							break;
 						default:
 							break;
 					}
 				}else{
-					data[i]=window[i];
+					data[i] = window[i];
 				}
 			}
 			this.addData(data);
 		}));
 	})());
-});
\ No newline at end of file
+});
diff --git a/dojox/analytics/profiles/analytics.profile.js b/dojox/analytics/profiles/analytics.profile.js
index a2ee2b1..5fbaec7 100644
--- a/dojox/analytics/profiles/analytics.profile.js
+++ b/dojox/analytics/profiles/analytics.profile.js
@@ -1,21 +1,17 @@
 dependencies = {
-        layers: [
-                {
-			name: "../dojox/analytics.js",
-                        dependencies: [
-                                "dojox.analytics",
-				"dojox.analytics.plugins.dojo",
-				"dojox.analytics.plugins.window",
-				"dojox.analytics.plugins.consoleMessages",
-				"dojox.analytics.plugins.mouseOver",
-				"dojox.analytics.plugins.mouseClick",
-				"dojox.analytics.plugins.idle"
-                        ]
-                }
-	],
+	layers : [ {
+		name : "../dojox/analytics.js",
+		dependencies : [ "dojox.analytics", 
+						"dojox.analytics.plugins.dojo",
+						"dojox.analytics.plugins.window",
+						"dojox.analytics.plugins.consoleMessages",
+						"dojox.analytics.plugins.mouseOver",
+						"dojox.analytics.plugins.mouseClick",
+						"dojox.analytics.plugins.touchPress",
+						"dojox.analytics.plugins.touchMove",
+						"dojox.analytics.plugins.gestureEvents",
+						"dojox.analytics.plugins.idle"]
+	} ],
 
-	prefixes: [
-                [ "dojox", "../dojox" ],
-                [ "dijit", "../dijit" ]
-        ]
+	prefixes : [ [ "dojox", "../dojox" ], [ "dijit", "../dijit" ] ]
 }
diff --git a/dojox/analytics/profiles/analyticsInBase.profile.js b/dojox/analytics/profiles/analyticsInBase.profile.js
index cf3c50e..e348031 100644
--- a/dojox/analytics/profiles/analyticsInBase.profile.js
+++ b/dojox/analytics/profiles/analyticsInBase.profile.js
@@ -4,14 +4,16 @@ dependencies = {
 			//name: "../dojox/analytics.js",
 			name: "dojo.js",
                         dependencies: [
-                                "dojox.analytics",
-				"dojox.analytics.plugins.dojo",
-				"dojox.analytics.plugins.window",
-				"dojox.analytics.plugins.consoleMessages",
-				"dojox.analytics.plugins.mouseOver",
-				"dojox.analytics.plugins.mouseClick",
-				"dojox.analytics.plugins.idle"
-                        ]
+								"dojox.analytics",
+								"dojox.analytics.plugins.dojo",
+								"dojox.analytics.plugins.window",
+								"dojox.analytics.plugins.consoleMessages",
+								"dojox.analytics.plugins.mouseOver",
+								"dojox.analytics.plugins.mouseClick",
+								"dojox.analytics.plugins.touchPress",
+								"dojox.analytics.plugins.touchMove",
+								"dojox.analytics.plugins.gestureEvents",
+								"dojox.analytics.plugins.idle"]
                 }
 	],
 
diff --git a/dojox/analytics/tests/test_GoogleAnalytics.html b/dojox/analytics/tests/test_GoogleAnalytics.html
index 53cce99..56c2da3 100644
--- a/dojox/analytics/tests/test_GoogleAnalytics.html
+++ b/dojox/analytics/tests/test_GoogleAnalytics.html
@@ -1,61 +1,66 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-<head>
-	<title>Dojox Analytics Test</title>
+	<head>
+		<meta charset="UTF-8">
+		<title>DojoX Google Analytics Test</title>
 
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../../../dijit/tests/css/dijitTests.css";
-	</style>
-	
-	<!-- required: a default theme file -->
-	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css" />
-	
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true, usePlainJson: true, sendMethod: 'script', sendInterval: 5000, analyticsUrl: 'http://dojotoolkit.org/~dmachi/dojo-1.0/dojox/analytics/logger/dojoxAnalytics.php'"></script>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
 
-	<!-- do not use: only for testing alternate themes -->
-	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
+		<!-- required: a default theme file -->
+		<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css" />
 
-	<script language="JavaScript" type="text/javascript">
-		// include the analytics system
-		dojo.require("dojox.analytics.Urchin");
-		var tracker = null; 
+		<!-- required: dojo.js -->
+		<script src="../../../dojo/dojo.js"
+			data-dojo-config="parseOnLoad: true, isDebug: true, async:true, usePlainJson: true,
+				sendMethod: 'script', sendInterval: 5000,
+				analyticsUrl: 'http://dojotoolkit.org/~dmachi/dojo-1.0/dojox/analytics/logger/dojoxAnalytics.php'">
+		</script>
 
-//	can run onLoad, too: 
-//		dojo.addOnLoad(function(){
-		var createTracker = function(){	
-			if(tracker) return;
-			// create and initialize Urchin after onLoad. You need a _real_ UA number
-			// available from http://google.com/analytics
-			tracker = new dojox.analytics.Urchin({ 
-				acct:"UA-123456-7",
-				GAonLoad: function(){
-					this.inherited("GAonLoad", arguments);
-					dojo.attr("lazy", "disabled", false);
-				}
-			});
-//		});
-		}
-		
-		var trackRandom = function(){
-			// FIXME: there is a small window (10ms to 'however long it took to load')
-			//	that trackPageView is unavailable. use tracker.GAonLoad function to 
-			// 	reliably know when the tracker is available.
-			tracker.trackPageView("/some-ajax-taggr");
-		}
-	</script>
-
-</head>
-<body class="tundra">
+		<!-- do not use: only for testing alternate themes -->
+		<script src="../../../dijit/tests/_testCommon.js"></script>
 
-	<h1>Simple Lazy loading of Google Analytics Code</h1>
-	
-	<button id="galoader" onclick="createTracker()">Create Tracker</button>
-	
-	<button id="lazy" onclick="trackRandom()" disabled="disabled">Track something</button>
-	
-</body>
+		<script>
+			require([
+				"dojo/ready",
+				"dojox/analytics",
+				"dojox/analytics/Urchin",
+				"dojo/on",
+				"dojo/dom-attr",
+				"dojo/dom"
+			], function(ready, analytics, Urchin, on, domAttr, dom){
+				ready(function(){
+					var tracker = null;
+					var createTracker = function(){
+						if(tracker) return;
+						// create and initialize Urchin after onLoad. You need a _real_ UA number
+						// available from http://google.com/analytics
+						tracker = new Urchin({
+							acct:"UA-123456-7",
+							GAonLoad: function(){
+								this.inherited("GAonLoad", arguments);
+								// FIXME: preserve context for domAttr
+								domAttr("lazy", "disabled", false);
+							}
+						});
+					};
+					var trackRandom = function(){
+						// FIXME: there is a small window (10ms to 'however long it took to load')
+						// that trackPageView is unavailable. use tracker.GAonLoad function to
+						// reliably know when the tracker is available.
+						tracker.trackPageView("/some-ajax-taggr");
+					};
+					on(dom.byId("galoader"), "click", createTracker);
+					on(dom.byId("lazy"), "click", trackRandom);
+				});
+			});
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Simple Lazy loading of Google Analytics Code</h1>
+		<button id="galoader">Create Tracker</button>
+		<button id="lazy" disabled="disabled">Track something</button>
+	</body>
 </html>
diff --git a/dojox/analytics/tests/test_GoogleAnalyticsMarkup.html b/dojox/analytics/tests/test_GoogleAnalyticsMarkup.html
index 6979163..11b0a5b 100644
--- a/dojox/analytics/tests/test_GoogleAnalyticsMarkup.html
+++ b/dojox/analytics/tests/test_GoogleAnalyticsMarkup.html
@@ -1,51 +1,47 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-<head>
-	<title>Dojox Analytics Test</title>
+	<head>
+		<meta charset="UTF-8">
+		<title>DojoX Google Analytics Test</title>
 
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../../../dijit/tests/css/dijitTests.css";
-	</style>
-	
-	<!-- required: dojo.js -->
-	<script type="text/javascript">
-		var djConfig = { 
-			parseOnLoad: true, 
-			isDebug: true //,
-			// ALERT: you need a _real_ UA number, obtainable from
-			// signup @ http://google.com/analytics
-//			urchin: "UA-123456-7"
-		};
-	</script>
-	<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
 
-	<!-- do not use: only for testing alternate themes -->
-	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
+		<!-- required: dojo.js -->
+		<script src="../../../dojo/dojo.js"
+			data-dojo-config="parseOnLoad: true, isDebug: true, async:true, urchin: 'UA-123456-7'">
+		</script>
 
-	<script language="JavaScript" type="text/javascript">
-		// include the analytics system
-		dojo.require("dojo.parser");
-		dojo.require("dojox.analytics.Urchin");
-		dojo.addOnLoad(function(){
-			// NOTE: this method does not permit you to do Ajax-style page tracking
-			// 	you will need to manually create a tracker programatically, and save
-			//	a reference. This is done to avoid taking in _Widget overhead for
-			// this simple class.
-			console.log("dom ready, now loading Urchin in background");
-			console.log("passed:", inmarkup.acct == "UA-12345-6785");
-			console.log("passed:", fromconfig.acct == "UA-123456-7");
-		});
-	</script>
+		<!-- do not use: only for testing alternate themes -->
+		<script src="../../../dijit/tests/_testCommon.js"></script>
 
-</head>
-<body>
-
-	<h1>Simple Lazy loading of Google Analytics Code</h1>
-	
-	<div jsId="fromconfig" dojoType="dojox.analytics.Urchin" acct="UA-123456-7"></div>
-	<div jsId="inmarkup" dojoType="dojox.analytics.Urchin" acct="UA-12345-6785"></div>
-
-</body>
+		<script>
+			require([
+				"dojo/ready",
+				"dojo/parser",
+				"dojox/analytics",
+				"dojox/analytics/Urchin",
+				"dojo/on",
+				"dojo/dom-attr",
+				"dojo/dom"
+			], function(ready, analytics, Urchin, on, domAttr, dom){
+				ready(function(){
+					// NOTE: this method does not permit you to do Ajax-style page tracking
+					// you will need to manually create a tracker programatically, and save
+					// a reference. This is done to avoid taking in _Widget overhead for
+					// this simple class.
+					console.log("dom ready, now loading Urchin in background");
+					console.log("passed:", inmarkup.acct == "UA-12345-6785");
+					console.log("passed:", fromconfig.acct == "UA-123456-7");
+				});
+			});
+		</script>
+	</head>
+	<body>
+		<h1>Simple Lazy loading of Google Analytics Code</h1>
+		<div data-dojo-id="fromconfig" data-dojo-type="dojox/analytics/Urchin" data-dojo-props="acct:'UA-123456-7'"></div>
+		<div data-dojo-id="inmarkup" dojoType="dojox/analytics/Urchin" data-dojo-props="acct:'acctUA-12345-6785'"></div>
+	</body>
 </html>
diff --git a/dojox/analytics/tests/test_analytics-async.html b/dojox/analytics/tests/test_analytics-async.html
index 69cb559..c0820d9 100644
--- a/dojox/analytics/tests/test_analytics-async.html
+++ b/dojox/analytics/tests/test_analytics-async.html
@@ -1,121 +1,90 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-<head>
-	<title>Dojox Analytics Test</title>
+	<head>
+		<meta charset="utf-8">
+		<title>DojoX Analytics Async Test</title>
 
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../../../dijit/tests/css/dijitTests.css";
-	</style>
-	
-	<!-- required: a default theme file -->
-	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css">
-	
-	<!-- required: dojo.js Update analyticsUrl: to point to your test server-->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="parseOnLoad:true, async:true, isDebug: true, usePlainJson: true, sendMethod: 'script', sendInterval: 5000, 
-				analyticsUrl: 'http://dojotoolkit.org/~dmachi/dojo-1.0/dojox/analytics/logger/dojoxAnalytics.php'"></script>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
 
-	<!-- do not use: only for testing alternate themes -->
-	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
+		<!-- required: a default theme file -->
+		<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css">
 
-	<script language="JavaScript" type="text/javascript">
-		// include the analytics system
-		//dojo.require("dojox.analytics");
+		<!-- required: dojo.js Update analyticsUrl: to point to your test server-->
+		<script src="../../../dojo/dojo.js"
+			data-dojo-config="parseOnLoad:true, async:true, isDebug: true, usePlainJson: true,
+			//sendMethod: 'script',
+			sendInterval: 5000,
+			// the line below can be used to override the sampleDelay for mouseOver and targetProps and textContentMaxChars
+			//sampleDelay : 2000, targetProps : ['id','className'], textContentMaxChars : 12,
+			analyticsUrl: 'http://dojotoolkit.org/~dmachi/dojo-1.0/dojox/analytics/logger/dojoxAnalytics.php'">
+		</script>
 
-		// this plugin returns the informatin dojo collects when it launches 
-		//dojo.require("dojox.analytics.plugins.dojo");
+		<!-- do not use: only for testing alternate themes -->
+		<script src="../../../dijit/tests/_testCommon.js"></script>
 
-		// this plugin return the information the window has when it launches
-		// and it also ties to a few events such as window.option
-		//dojo.require("dojox.analytics.plugins.window");
+		<script>
+			require([
+				"dojo/ready",
+				"dojox/analytics",
+				"dojox/analytics/plugins/dojo",
+				"dojox/analytics/plugins/window",
+				"dojox/analytics/plugins/consoleMessages",
+				"dojox/analytics/plugins/mouseOver",
+				"dojox/analytics/plugins/mouseClick",
+				"dojox/analytics/plugins/idle",
+				"dijit/TitlePane",
+				"dojo/parser",
+				"dojo/request/script",
+				"dijit/form/Button",
+				"dijit/form/ComboBox"],
+			function(ready, analytics, dojoplugin, windowplugin, consolemsgplugin, mouseoverplugin, mouseclickplugin,
+					idleplugin, TitlePane, parser, scriptIO, Button, ComboBox){
 
-		// this plugin tracks console. message, It logs console.error, warn, and 
-		// info messages to the tracker.  It also defines console.rlog() which 
-		// can be used to log only to the server.  Note that if isDebug() is disabled
-		// you will still see the console messages on the sever, but not in the actual
-		// browser console.
-		//dojo.require("dojox.analytics.plugins.consoleMessages");
+				ready(function(){
+					console.info("Async Page Loaded Sample Message");
+				});
+			});
+		</script>
+	</head>
+	<body class="tundra">
+		<table>
+			<tr>
+				<td colspan=3>
+					<h1 class="testTitle">DojoX Analytics Async Test</h1>
+				</td>
+			</tr>
+			<tr>
+				<td width="20%"></td>
+				<td>
+					<div data-dojo-type="dijit/TitlePane" data-dojo-props="title:'dgrid', style:'width: 300px;'">
+						Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
+						iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing
+						orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus
+						pulvinar orci, sed vestibulum urna sem ut pede. More Ipsum...
+						Sed sollicitudin suscipit risus. Nam ullamcorper. Sed nisl lectus, pellentesque
+						nec, malesuada eget, ornare a, libero. Lorem ipsum dolor sit amet,
+						consectetuer adipiscing elit.
 
-		// tracks where a mouse is on a page an what it is over, periodically sampling
-		// and storing this data
-		//dojo.require("dojox.analytics.plugins.mouseOver");
+						<a href="http://dgrid.io">dgrid.io</a>
+					</div>
 
-		//tracks mouse clicks on the page
-		//dojo.require("dojox.analytics.plugins.mouseClick");
+					<div data-dojo-type="dijit/TitlePane" data-dojo-props="title:'dojo', style:'width: 300px;'">
+						Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
+						iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing
+						orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus
+						pulvinar orci, sed vestibulum urna sem ut pede. More Ipsum...
+						Sed sollicitudin suscipit risus. Nam ullamcorper. Sed nisl lectus, pellentesque
+						nec, malesuada eget, ornare a, libero. Lorem ipsum dolor sit amet,
+						consectetuer adipiscing elit.
 
-		//tracks when the user has gone idle
-		//dojo.require("dojox.analytics.plugins.idle");
-		
-		//dojo.require("dijit.TitlePane");
-		//dojo.require("dojo.parser");
-		//dojo.require("dojo.io.script");
-
-		// widgets used inside subpage loaded via href=
-		//dojo.require("dijit.form.Button");
-		//dojo.require("dijit.form.ComboBox");
-require([
-	"dojo/ready",
-	"dojox/analytics",
-	"dojox/analytics/plugins/dojo", 
-	"dojox/analytics/plugins/window", 
-	"dojox/analytics/plugins/consoleMessages",
-	"dojox/analytics/plugins/mouseOver", 
-	"dojox/analytics/plugins/mouseClick",
-	"dojox/analytics/plugins/idle",
-	"dijit/TitlePane", 
-	"dojo/parser", 
-	"dojo/io/script", 
-	"dijit/form/Button", 
-	"dijit/form/ComboBox"],
-	function(ready, analytics, dojoplugin, windowplugin, consolemsgplugin, mouseoverplugin, mouseclickplugin, 
-				idleplugin, TitlePane, parser, scriptIO, Button, ComboBox){
-
-		ready(function(){
-			console.info("Async Page Loaded Sample Message");
-		});
-	});
-		
-	</script>
-
-</head>
-<body class="tundra">
-	<table>
-		<tr>
-			<td colspan=3>
-				<h1 class="testTitle">Async Analytics Test</h1>
-			</td>
-		</tr>
-		<tr>
-			<td width="20%"></td>
-			<td>
-				<div data-dojo-type="dijit.TitlePane" data-dojo-props='title:"digg", style:"width: 300px;"'> 
-					Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
-					iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing
-					orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus
-					pulvinar orci, sed vestibulum urna sem ut pede. More Ipsum...
-					Sed sollicitudin suscipit risus. Nam ullamcorper. Sed nisl lectus, pellentesque
-					nec, malesuada eget, ornare a, libero. Lorem ipsum dolor sit amet,
-					consectetuer adipiscing elit.
-
-					<a href="http://cometdaily.com">cometdaily.com</a>
-				</div>
-
-				<div data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Article 1", style:"width: 300px;"'> 
-					Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
-					iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing
-					orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus
-					pulvinar orci, sed vestibulum urna sem ut pede. More Ipsum...
-					Sed sollicitudin suscipit risus. Nam ullamcorper. Sed nisl lectus, pellentesque
-					nec, malesuada eget, ornare a, libero. Lorem ipsum dolor sit amet,
-					consectetuer adipiscing elit.
-
-					<a href="http://dojotoolkit.org">dojotoolkit.org</a>
-				</div>
-			</td>
-			<td width="20%"></td>
-		</tr>
-	</table>
-</body>
+						<a href="http://dojotoolkit.org">dojotoolkit.org</a>
+					</div>
+				</td>
+				<td width="20%"></td>
+			</tr>
+		</table>
+	</body>
 </html>
diff --git a/dojox/analytics/tests/test_analytics-gestureEvents.html b/dojox/analytics/tests/test_analytics-gestureEvents.html
new file mode 100644
index 0000000..6e7e78e
--- /dev/null
+++ b/dojox/analytics/tests/test_analytics-gestureEvents.html
@@ -0,0 +1,161 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>DojoX Analytics Gesture Test</title>
+		<style type="text/css">
+			@import "../../mobile/themes/iphone/base.css";
+			@import "../../mobile/themes/iphone/TabBar.css";
+			#outerHeading {
+				height: 240px;
+			}
+			#outer {
+				width: 100%;
+				height: 240px;
+				border: 1px solid #54A201;
+				background-color: #54A201;
+			}
+			#inner {
+				width: 250px;
+				height: 110px;
+				border: 1px solid #7FB0DB;
+				background-color: #7FB0DB
+			}
+			#log1, #log2 {
+				width: 100%;
+				height: 50px;
+			}
+		</style>
+		<script src="../../../dojo/dojo.js"
+			data-dojo-config="parseOnLoad:true, async:true, isDebug: true, usePlainJson: true,
+				sendMethod: 'script', sendInterval: 5000, mblAlwaysHideAddressBar: true,
+				// the line below can be used to override the swipeSampleDelay, targetProps and textContentMaxChars
+				//swipeSampleDelay : 500, targetProps : ['id','className'], textContentMaxChars : 12
+				analyticsUrl: 'http://dojotoolkit.org/~dmachi/dojo-1.0/dojox/analytics/logger/dojoxAnalytics.php'">
+		</script>
+
+
+		<script>
+			require([
+				"dojo/ready",
+				"dojo/parser",
+				"dojox/mobile",			// This is a mobile app.
+				"dojox/mobile/ScrollableView",
+				"dojox/mobile/compat", // This mobile app supports running on desktop browsers
+				"dojox/analytics",
+				// this plugin returns the information dojo collects when it launches
+				"dojox/analytics/plugins/dojo",
+				// this plugin return the information the window has when it launches
+				// and it also ties to a few events such as window.option
+				"dojox/analytics/plugins/window",
+				// this plugin tracks console. message, It logs console.error, warn, and
+				// info messages to the tracker.  It also defines console.rlog() which
+				// can be used to log only to the server.  Note that if isDebug() is disabled
+				// you will still see the console messages on the sever, but not in the actual
+				// browser console.
+				"dojox/analytics/plugins/consoleMessages",
+				// tracks where a dojox.gesture.tap and swipe events
+				"dojox/analytics/plugins/gestureEvents",
+				"dojox/analytics/plugins/idle",
+				"dojox/gesture/tap",
+				"dojox/gesture/swipe",
+				"dojo/_base/html",
+				"dojo/dom",
+				"dojo/touch",
+				"dojo/on",
+				"dojo/_base/window",
+				"dojo/has",
+				"dojo/dom-style",
+				"dojox/mobile/Heading"
+			], function(ready, parser, mobile, scrollableView, compat,
+				analytics, dojoplugin, windowplugin, consolemsgplugin,
+				gestureplugin, idleplugin, tap, swipe,
+				html, dom, touch, on, win, has, domStyle){
+
+				ready(function(){
+					var action = function(e){
+						dom.byId("log1").innerHTML = "";
+						var info = " e.target.id=" + e.target.id + " | e.type=" + e.type +
+							" | e.currentTarget.id="+ e.currentTarget.id;
+						dom.byId("log1").innerHTML += info;
+					};
+
+					var swipeAction = function(e){
+						dom.byId("log2").innerHTML = "";
+						var info =  " e.target.id=" + e.target.id + " | e.type=" + e.type +
+							" | e.currentTarget.id="+ e.currentTarget.id +
+							" e.dx=" + e.dx + " e.dy=" + e.dy + " e.time=" + e.time + "<br/>";
+						dom.byId("log2").innerHTML += info;
+					};
+
+					var action2 = function(e){
+						dom.byId("log").innerHTML = "";
+						var info = "[Touch Event]: " + e.type + "<br/> ------ Event Properties: ------<br/>";
+						if(e["target"]){
+						   info += "target.textContent: " + e["target"]["textContent"] + "<br/>";
+						}
+						for(var i in e){
+						  if(i == "touches" || i == "targetTouches" || i == "changedTouches"){
+							info += i + ": " + e[i].length + "<br/>";
+						  }else{
+							if(typeof e[i] != "function"){
+							  info += " " + i + ": " + e[i] + "<br/>";
+							}
+						  }
+						}
+						dom.byId("log").innerHTML += info + "<br/>";
+					};
+
+					//tap and swipe gestures both work well both on PC and touch devices
+					var inner = dom.byId("inner");
+					on(inner, tap, action);
+					on(inner, tap.hold, action);
+					on(inner, tap.doubletap, action);
+					on(inner, swipe, swipeAction);
+
+					//test gesture events bubbling from inner div
+					var outer = dom.byId("outer");
+					on(outer, tap, action);
+					on(outer, tap.hold, action);
+					on(outer, tap.doubletap, action);
+					on(outer, swipe, swipeAction);
+					on(outer, swipe.end, swipeAction);
+
+					// Event info, uncomment one of the lines below to see what these events return
+					//on(outer, tap, action2);
+					//on(outer, tap.hold, action2);
+					on(inner, tap.doubletap, action2);
+					//on(inner, swipe, action2);
+					on(outer, swipe.end, action2);
+					//on(outer, touch.move, action2);
+					//on(outer, touch.press, action2);
+					//on(inner, touch.release, action2);
+
+
+					on(win.doc, "orientationchange", function(e){
+						dom.byId("log1").innerHTML="";
+						dom.byId("log2").innerHTML="";
+						dom.byId("log").innerHTML="";
+					});
+				});
+			});
+		</script>
+	</head>
+	<body style="visibility:hidden;">
+		<div id="categ" dojoType="dojox/mobile/ScrollableView"  selected="true">
+ 			<div id="outerHeading" dojoType="dojox/mobile/Heading" fixed="top">
+				<div id="outer">
+					outer content <div id="inner">inner content</div>
+				</div>
+			</div>
+			<div id="log1"></div>
+			<hr/>
+			<div id="log2"></div>
+			<hr/>
+			<div id="log"></div>
+
+		</div>
+	</body>
+</html>
diff --git a/dojox/analytics/tests/test_analytics-touchAndGestureEvents.html b/dojox/analytics/tests/test_analytics-touchAndGestureEvents.html
new file mode 100644
index 0000000..c729481
--- /dev/null
+++ b/dojox/analytics/tests/test_analytics-touchAndGestureEvents.html
@@ -0,0 +1,167 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>DojoX Analytics Touch and Gesture Test</title>
+		<style type="text/css">
+			@import "../../mobile/themes/iphone/base.css";
+			@import "../../mobile/themes/iphone/TabBar.css";
+			#outerHeading {
+				height: 240px;
+			}
+			#outer {
+				width: 100%;
+				height: 240px;
+				border: 1px solid #54A201;
+				background-color: #54A201;
+			}
+			#inner {
+				width: 250px;
+				height: 110px;
+				border: 1px solid #7FB0DB;
+				background-color: #7FB0DB
+			}
+			#log1, #log2 {
+				width: 100%;
+				height: 50px;
+			}
+		</style>
+		<!-- required: dojo.js Update analyticsUrl: to point to your test server-->
+		<script src="../../../dojo/dojo.js"
+			data-dojo-config="parseOnLoad:true, async:true, isDebug: true, usePlainJson: true,
+				sendMethod: 'script', sendInterval: 5000, mblAlwaysHideAddressBar: true,
+				// the line below can be used to override the touchSampleDelay for touchMove
+				// and to override the swipeSampleDelay for gestureEvents and targetProps.
+				//touchSampleDelay : 500, swipeSampleDelay : 800, targetProps : ['id','className'],
+				analyticsUrl: 'http://dojotoolkit.org/~dmachi/dojo-1.0/dojox/analytics/logger/dojoxAnalytics.php'">
+		</script>
+
+
+		<script>
+			require([
+				"dojo/ready",
+				"dojo/parser",
+				"dojox/mobile",			// This is a mobile app.
+				"dojox/mobile/ScrollableView",
+				"dojox/mobile/compat", 	// This mobile app supports running on desktop browsers
+				"dojox/analytics",
+				// this plugin returns the information dojo collects when it launches
+				"dojox/analytics/plugins/dojo",
+				// this plugin return the information the window has when it launches
+				// and it also ties to a few events such as window.option
+				"dojox/analytics/plugins/window",
+				// this plugin tracks console. message, It logs console.error, warn, and
+				// info messages to the tracker.  It also defines console.rlog() which
+				// can be used to log only to the server.  Note that if isDebug() is disabled
+				// you will still see the console messages on the sever, but not in the actual
+				// browser console.
+				"dojox/analytics/plugins/consoleMessages",
+				// tracks where a dojo.touch.press is on a page an what it is over, periodically sampling
+				// and storing this data
+				"dojox/analytics/plugins/touchPress",
+				// tracks where a dojo.touch.move is on a page an what it is over, periodically sampling
+				// and storing this data
+				"dojox/analytics/plugins/touchMove",
+				// tracks where a dojox.gesture.tap and swipe events
+				"dojox/analytics/plugins/gestureEvents",
+				"dojox/analytics/plugins/idle",
+				"dojox/gesture/tap",
+				"dojox/gesture/swipe",
+				"dojo/dom",
+				"dojo/touch",
+				"dojo/on",
+				"dojo/_base/window",
+				"dojo/has",
+				"dojo/dom-style",
+				"dojox/mobile/Heading"
+			], function(ready, parser, mobile,scrollableView, compat,
+				analytics, dojoplugin, windowplugin, consolemsgplugin,
+				touchpressplugin, touchmoveplugin, gestureplugin, idleplugin, tap, swipe,
+				dom, touch, on, win, has, domStyle){
+
+				ready(function(){
+					var action = function(e){
+						dom.byId("log1").innerHTML = "";
+						var info = " e.target.id=" + e.target.id + " | e.type=" + e.type +
+							" | e.currentTarget.id="+ e.currentTarget.id;
+						dom.byId("log1").innerHTML += info;
+					};
+
+					var swipeAction = function(e){
+						dom.byId("log2").innerHTML = "";
+						var info =  " e.target.id=" + e.target.id + " | e.type=" + e.type +
+							" | e.currentTarget.id="+ e.currentTarget.id +
+							" e.dx=" + e.dx + " e.dy=" + e.dy + " e.time=" + e.time + "<br/>";
+						dom.byId("log2").innerHTML += info;
+					};
+
+					var action2 = function(e){
+						dom.byId("log").innerHTML = "";
+						var info = "[Touch Event]: " + e.type + "<br/> ------ Event Properties: ------<br/>";
+						if(e["target"]){
+						   info += "target.textContent: " + e["target"]["textContent"] + "<br/>";
+						}
+						for(var i in e){
+						  if(i == "touches" || i == "targetTouches" || i == "changedTouches"){
+							info += i + ": " + e[i].length + "<br/>";
+						  }else{
+							if(typeof e[i] != "function"){
+							  info += " " + i + ": " + e[i] + "<br/>";
+							}
+						  }
+						}
+						dom.byId("log").innerHTML += info + "<br/>";
+					};
+
+					//tap and swipe gestures both work well both on PC and touch devices
+					var inner = dom.byId("inner");
+					on(inner, tap, action);
+					on(inner, tap.hold, action);
+					on(inner, tap.doubletap, action);
+					on(inner, swipe, swipeAction);
+
+					//test gesture events bubbling from inner div
+					var outer = dom.byId("outer");
+					on(outer, tap, action);
+					on(outer, tap.hold, action);
+					on(outer, tap.doubletap, action);
+					on(outer, swipe, swipeAction);
+					on(outer, swipe.end, swipeAction);
+
+					// Event info, uncomment one of the lines below to see what these events return
+					//on(outer, tap, action2);
+					on(inner, tap, action2);
+					//on(outer, tap.doubletap, action2);
+					//on(inner, swipe, action2);
+					on(outer, swipe.end, action2);
+					//on(outer, touch.move, action2);
+					//on(outer, touch.press, action2);
+					//on(inner, touch.release, action2);
+
+					on(win.doc, "orientationchange", function(e){
+						dom.byId("log1").innerHTML="";
+						dom.byId("log2").innerHTML="";
+						dom.byId("log").innerHTML="";
+					});
+				});
+			});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="categ" dojoType="dojox.mobile.ScrollableView"  selected="true">
+ 		<div id="outerHeading" dojoType="dojox.mobile.Heading" fixed="top">
+			<div id="outer">
+				outer content <div id="inner">inner content</div>
+			</div>
+		</div>
+			<div id="log1"></div>
+			<hr/>
+			<div id="log2"></div>
+			<hr/>
+			<div id="log"></div>
+
+	</div>
+</body>
+</html>
diff --git a/dojox/analytics/tests/test_analytics-touchEvents.html b/dojox/analytics/tests/test_analytics-touchEvents.html
new file mode 100644
index 0000000..87bf300
--- /dev/null
+++ b/dojox/analytics/tests/test_analytics-touchEvents.html
@@ -0,0 +1,165 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta charset="utf-8">
+
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>DojoX Analytics Touch Test</title>
+		<style type="text/css">
+			@import "../../mobile/themes/iphone/base.css";
+			@import "../../mobile/themes/iphone/TabBar.css";
+			#outerHeading {
+				height: 240px;
+			}
+			#outer {
+				width: 100%;
+				height: 240px;
+				border: 1px solid #54A201;
+				background-color: #54A201;
+			}
+			#inner {
+				width: 250px;
+				height: 110px;
+				border: 1px solid #7FB0DB;
+				background-color: #7FB0DB
+			}
+			#log1 {
+				width: 100%;
+				height: 50px;
+			}
+		</style>
+		<!-- required: dojo.js Update analyticsUrl: to point to your test server-->
+		<script src="../../../dojo/dojo.js"
+			data-dojo-config="parseOnLoad:true, async:true, isDebug: true, usePlainJson: true,
+					sendMethod: 'script', sendInterval: 5000, mblAlwaysHideAddressBar: true,
+					// the line below can be used to override the touchSampleDelay for touchMove,
+					// targetProps, textContentMaxChars and showTouchesDetails
+					//touchSampleDelay : 500, targetProps : ['id','className'],
+					//textContentMaxChars : 12, showTouchesDetails : false,
+					analyticsUrl: 'http://dojotoolkit.org/~dmachi/dojo-1.0/dojox/analytics/logger/dojoxAnalytics.php'">
+		</script>
+
+		<script>
+			require([
+				"dojo/ready",
+				"dojo/parser",
+				"dojox/mobile",			// This is a mobile app.
+				"dojox/mobile/ScrollableView",
+				"dojox/mobile/compat", // This mobile app supports running on desktop browsers
+				"dojox/analytics",
+				// this plugin returns the information dojo collects when it launches
+				"dojox/analytics/plugins/dojo",
+				// this plugin return the information the window has when it launches
+				// and it also ties to a few events such as window.option
+				"dojox/analytics/plugins/window",
+				// this plugin tracks console. message, It logs console.error, warn, and
+				// info messages to the tracker.  It also defines console.rlog() which
+				// can be used to log only to the server.  Note that if isDebug() is disabled
+				// you will still see the console messages on the sever, but not in the actual
+				// browser console.
+				"dojox/analytics/plugins/consoleMessages",
+				// tracks where a dojo.touch.press and touch.release is done on a page
+				"dojox/analytics/plugins/touchPress",
+				// tracks where a dojo.touch.move is on a page an what it is over, periodically sampling
+				// and storing this data
+				"dojox/analytics/plugins/touchMove",
+				"dojox/analytics/plugins/idle",
+				"dojo/dom",
+				"dojo/touch",
+				"dojo/on",
+				"dojo/_base/window",
+				"dojo/has",
+				"dojo/dom-style",
+				"dojox/mobile/Heading"
+			], function(ready, parser, mobile, scrollableView, compat,
+					analytics, dojoplugin, windowplugin, consolemsgplugin,
+					touchpressplugin, touchmoveplugin, idleplugin,
+					dom, touch, on, win, has, domStyle){
+				ready(function(){
+					var action2 = function(e){
+						dom.byId("log1").innerHTML = "";
+						var info = " e.target.id=" + e.target.id + " | e.type=" + e.type + " | e.currentTarget.id="+ e.currentTarget.id+ " | e.touches="+ e.touches;
+						dom.byId("log1").innerHTML += info;
+					};
+
+					var action = function(e){
+						dom.byId("log").innerHTML = "";
+						var info = "[Touch Event]: " + e.type + "<br/> ------ Event Properties: ------<br/>";
+						for(var i in e){
+						  if(i == "touches" || i == "targetTouches" || i == "changedTouches"){
+							info += i + ": " + e[i].length + "<br/>";
+						  }else{
+							if(typeof e[i] != "function"){
+							  info += " " + i + ": " + e[i] + "<br/>";
+							}
+						  }
+						}
+						if(e.touches){
+							if(e.touches.length == 0){
+								info += "[touches]: " + e.touches + "<br/> ------ Event touches: ------<br/>";
+									for(var i in e.touches){
+										//console.log("includes "+i+" = "+e.touches[i]);
+										if(i == "target"){
+											info += i + ": " + e.touches[i].id + "<br/>";
+										}else{
+											if(typeof e.touches[i] != "function"){
+												info += " " + i + ": " + e.touches[i] + "<br/>";
+											}
+										}
+									}
+							}else{
+								info += "[touches length]: " + e.touches.length + "<br/> ------ Event touches: ------<br/>";
+								for(var j in e.touches){
+									for(var i in e.touches[j]){
+										if(i == "target"){
+											info += i + ": " + e.touches[j][i].id + "<br/>";
+										}else{
+											if(typeof e.touches[j][i] != "function"){
+												info += " touches["+j+"] " + i + ": " + e.touches[j][i] + "<br/>";
+											}
+										}
+									}
+								}
+							}
+						}else{
+							var info = "[Touch Event]: " + e.type + "<br/> ------ Event Properties: ------<br/>";
+						}
+						dom.byId("log").innerHTML += info;
+					};
+
+					//1. should work well on PC and touch devices
+					on(outer, touch.press, action2);
+					on(outer, touch.move, action2);
+					on(outer, touch.release, action2);
+					on(outer, touch.cancel, action2);
+
+					// Event info, uncomment one of the lines below to see what the event returns
+					on(inner, touch.press, action);
+					//on(inner, touch.move, action);
+					//on(outer, touch.move, action);
+					//on(outer, touch.release, action);
+					//on(outer, "touchend", action);
+
+					on(win.doc, "orientationchange", function(e){
+						dom.byId("log1").innerHTML="";
+						dom.byId("log").innerHTML="";
+					});
+				});
+			});
+		</script>
+	</head>
+	<body style="visibility:hidden;">
+		<div id="categ" dojoType="dojox/mobile/ScrollableView"  selected="true">
+	 		<div id="outerHeading" dojoType="dojox/mobile/Heading" fixed="top">
+				<div id="outer">
+					outer content <div id="inner">inner content</div>
+				</div>
+			</div>
+				<div id="log1"></div>
+				<hr/>
+				<div id="log"></div>
+
+		</div>
+	</body>
+</html>
diff --git a/dojox/analytics/tests/test_analytics.html b/dojox/analytics/tests/test_analytics.html
index eb08e8b..daeeabd 100644
--- a/dojox/analytics/tests/test_analytics.html
+++ b/dojox/analytics/tests/test_analytics.html
@@ -1,78 +1,80 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-<head>
-	<title>Dojox Analytics Test</title>
-
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../../../dijit/tests/css/dijitTests.css";
-	</style>
-	
-	<!-- required: a default theme file -->
-	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css">
-	
-	<!-- required: dojo.js Update analyticsUrl: to point to your test server-->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true, usePlainJson: true, sendMethod: 'script', sendInterval: 5000, 
+	<head>
+		<meta charset="utf-8">
+		<title>DojoX Analytics Legacy Test</title>
+
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+
+		<!-- required: a default theme file -->
+		<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css">
+
+		<!-- required: dojo.js Update analyticsUrl: to point to your test server-->
+		<script src="../../../dojo/dojo.js"
+			data-dojo-config="parseOnLoad: true, isDebug: true, usePlainJson: true, sendMethod: 'script', sendInterval: 5000,
+				// the line below can be used to override the sampleDelay for mouseOver and targetProps and textContentMaxChars
+				//sampleDelay : 2000, targetProps : ['id','className'], textContentMaxChars : 12,
 				analyticsUrl: 'http://dojotoolkit.org/~dmachi/dojo-1.0/dojox/analytics/logger/dojoxAnalytics.php'"></script>
 
-	<!-- do not use: only for testing alternate themes -->
-	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		// include the analytics system
-		dojo.require("dojox.analytics");
-
-		// this plugin returns the informatin dojo collects when it launches 
-		dojo.require("dojox.analytics.plugins.dojo");
-
-		// this plugin return the information the window has when it launches
-		// and it also ties to a few events such as window.option
-		dojo.require("dojox.analytics.plugins.window");
-
-		// this plugin tracks console. message, It logs console.error, warn, and 
-		// info messages to the tracker.  It also defines console.rlog() which 
-		// can be used to log only to the server.  Note that if isDebug() is disabled
-		// you will still see the console messages on the sever, but not in the actual
-		// browser console.
-		dojo.require("dojox.analytics.plugins.consoleMessages");
-
-		// tracks where a mouse is on a page an what it is over, periodically sampling
-		// and storing this data
-		dojo.require("dojox.analytics.plugins.mouseOver");
-
-		//tracks mouse clicks on the page
-		dojo.require("dojox.analytics.plugins.mouseClick");
-
-		//tracks when the user has gone idle
-		dojo.require("dojox.analytics.plugins.idle");
-		
-		dojo.require("dijit.TitlePane");
-		dojo.require("dojo.parser");
-		dojo.require("dojo.io.script");
-
-		// widgets used inside subpage loaded via href=
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.form.ComboBox");
-
-		dojo.addOnLoad(function(){
-			console.info("Page Loaded Sample Message");
-		});
-	</script>
-
-</head>
-<body class="tundra">
-	<table>
-		<tr>
-			<td colspan=3>
-				<h1 class="testTitle">Dijit TitlePane Test</h1>
-			</td>
-		</tr>
-		<tr>
-			<td width="20%"></td>
-			<td>
-				<div dojoType="dijit.TitlePane" title="digg" style="width: 300px;">
+		<!-- do not use: only for testing alternate themes -->
+		<script src="../../../dijit/tests/_testCommon.js"></script>
+
+		<script>
+			// NOTE: This test intentionally tests the legacy syntax. See test_analytics-async.html for same test in AMD format
+			// include the analytics system
+			dojo.require("dojox.analytics");
+
+			// this plugin returns the information dojo collects when it launches
+			dojo.require("dojox.analytics.plugins.dojo");
+
+			// this plugin return the information the window has when it launches
+			// and it also ties to a few events such as window.option
+			dojo.require("dojox.analytics.plugins.window");
+
+			// this plugin tracks console. message, It logs console.error, warn, and
+			// info messages to the tracker.  It also defines console.rlog() which
+			// can be used to log only to the server.  Note that if isDebug() is disabled
+			// you will still see the console messages on the sever, but not in the actual
+			// browser console.
+			dojo.require("dojox.analytics.plugins.consoleMessages");
+
+			// tracks where a mouse is on a page an what it is over, periodically sampling
+			// and storing this data
+			dojo.require("dojox.analytics.plugins.mouseOver");
+
+			//tracks mouse clicks on the page
+			dojo.require("dojox.analytics.plugins.mouseClick");
+
+			//tracks when the user has gone idle
+			dojo.require("dojox.analytics.plugins.idle");
+
+			dojo.require("dijit.TitlePane");
+			dojo.require("dojo.parser");
+			dojo.require("dojo.io.script");
+
+			// widgets used inside subpage loaded via href=
+			dojo.require("dijit.form.Button");
+			dojo.require("dijit.form.ComboBox");
+
+			dojo.addOnLoad(function(){
+				console.info("Page Loaded Sample Message");
+			});
+		</script>
+
+	</head>
+	<body class="tundra">
+		<table>
+			<tr>
+				<td colspan=3>
+					<h1 class="testTitle">DojoX Analytics Legacy Test</h1>
+				</td>
+			</tr>
+			<tr>
+				<td width="20%"></td>
+				<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'dgrid', style:'width: 300px;'">
 					Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
 					iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing
 					orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus
@@ -81,10 +83,10 @@
 					nec, malesuada eget, ornare a, libero. Lorem ipsum dolor sit amet,
 					consectetuer adipiscing elit.
 
-					<a href="http://cometdaily.com">cometdaily.com</a>
+					<a href="http://dgrid.io">dgrid.io</a>
 				</div>
 
-				<div dojoType="dijit.TitlePane" title="Article 1" style="width: 300px;">
+				<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'dojo', style:'width: 300px;'">
 					Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
 					iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing
 					orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus
@@ -95,9 +97,8 @@
 
 					<a href="http://dojotoolkit.org">dojotoolkit.org</a>
 				</div>
-			</td>
-			<td width="20%"></td>
-		</tr>
-	</table>
-</body>
+				<td width="20%"></td>
+			</tr>
+		</table>
+	</body>
 </html>
diff --git a/dojox/app/CONTRIBUTING.md b/dojox/app/CONTRIBUTING.md
new file mode 100755
index 0000000..5ae012f
--- /dev/null
+++ b/dojox/app/CONTRIBUTING.md
@@ -0,0 +1,3 @@
+All contributions to this repository must:
+- be done under the Dojo Contributor License Agreement (CLA, http://dojofoundation.org/about/claForm) that you must sign
+- follow the Dojo style guide (https://dojotoolkit.org/community/styleGuide)
diff --git a/dojox/app/Controller.js b/dojox/app/Controller.js
new file mode 100755
index 0000000..49b7ec1
--- /dev/null
+++ b/dojox/app/Controller.js
@@ -0,0 +1,75 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/on"], function(lang, declare, on){
+	// module:
+	//		dojox/app/Controller
+	// summary:
+	//		Bind events on dojox/app application's dojo/Evented instance or document.
+
+	return declare("dojox.app.Controller", null, {
+		constructor: function(app, events){
+			// summary:
+			//		bind events on application dojo/Evented instance.
+			//		bind css selector events on document.
+			//
+			// app:
+			//		dojox/app application instance.
+			// events:
+			//		{event : handler}
+
+			this.events = this.events || events;
+			this._boundEvents = [];
+			this.app = app;
+		},
+
+		bind: function(evented, event, handler){
+			// summary:
+			//		Bind event on dojo/Evented instance, document, domNode or window.
+			//		Save event signal in controller instance. If no parameter is provided
+			//		automatically bind all events registered in controller events property.
+			//
+			// evented: Object
+			//		dojo/Evented instance, document, domNode or window
+			// event: String
+			//		event
+			// handler: Function
+			//		event handler
+			if(arguments.length == 0){
+				if(this.events){
+					for(var item in this.events){
+						if(item.charAt(0) !== "_"){//skip the private properties
+							this.bind(this.app, item, lang.hitch(this, this.events[item]));
+						}
+					}
+				}
+			}else{
+				var signal = on(evented, event, handler);
+				this._boundEvents.push({
+					"event": event,
+					"evented": evented,
+					"signal": signal
+				});
+			}
+			return this;
+		},
+
+		unbind: function(evented, event){
+			// summary:
+			//		remove a binded event signal.
+			//
+			// evented: Object
+			//		dojo/Evented instance, document, domNode or window
+			// event: String
+			//		event
+
+			var len = this._boundEvents.length;
+			for(var i = 0; i < len; i++){
+				if((this._boundEvents[i]['event'] == event) && (this._boundEvents[i]['evented'] == evented)){
+					this._boundEvents[i]['signal'].remove();
+					this._boundEvents.splice(i, 1);
+					return;
+				}
+			}
+			console.warn("event '"+event+"' not bind on ", evented);
+			return this;
+		}
+	});
+});
diff --git a/dojox/app/LICENSE b/dojox/app/LICENSE
new file mode 100755
index 0000000..6a527af
--- /dev/null
+++ b/dojox/app/LICENSE
@@ -0,0 +1,195 @@
+Dojo is available under *either* the terms of the modified BSD license *or* the
+Academic Free License version 2.1. As a recipient of Dojo, you may choose which
+license to receive this code under (except as noted in per-module LICENSE
+files). Some modules may not be the copyright of the Dojo Foundation. These
+modules contain explicit declarations of copyright in both the LICENSE files in
+the directories in which they reside and in the code itself. No external
+contributions are allowed under licenses which are fundamentally incompatible
+with the AFL or BSD licenses that Dojo is distributed under.
+
+The text of the AFL and BSD licenses is reproduced below.
+
+-------------------------------------------------------------------------------
+The "New" BSD License:
+**********************
+
+Copyright (c) 2005-2013, The Dojo Foundation
+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 the Dojo Foundation 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+-------------------------------------------------------------------------------
+The Academic Free License, v. 2.1:
+**********************************
+
+This Academic Free License (the "License") applies to any original work of
+authorship (the "Original Work") whose owner (the "Licensor") has placed the
+following notice immediately following the copyright notice for the Original
+Work:
+
+Licensed under the Academic Free License version 2.1
+
+1) Grant of Copyright License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license to do the
+following:
+
+a) to reproduce the Original Work in copies;
+
+b) to prepare derivative works ("Derivative Works") based upon the Original
+Work;
+
+c) to distribute copies of the Original Work and Derivative Works to the
+public;
+
+d) to perform the Original Work publicly; and
+
+e) to display the Original Work publicly.
+
+2) Grant of Patent License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
+claims owned or controlled by the Licensor that are embodied in the Original
+Work as furnished by the Licensor, to make, use, sell and offer for sale the
+Original Work and Derivative Works.
+
+3) Grant of Source Code License. The term "Source Code" means the preferred
+form of the Original Work for making modifications to it and all available
+documentation describing how to modify the Original Work. Licensor hereby
+agrees to provide a machine-readable copy of the Source Code of the Original
+Work along with each copy of the Original Work that Licensor distributes.
+Licensor reserves the right to satisfy this obligation by placing a
+machine-readable copy of the Source Code in an information repository
+reasonably calculated to permit inexpensive and convenient access by You for as
+long as Licensor continues to distribute the Original Work, and by publishing
+the address of that information repository in a notice immediately following
+the copyright notice that applies to the Original Work.
+
+4) Exclusions From License Grant. Neither the names of Licensor, nor the names
+of any contributors to the Original Work, nor any of their trademarks or
+service marks, may be used to endorse or promote products derived from this
+Original Work without express prior written permission of the Licensor. Nothing
+in this License shall be deemed to grant any rights to trademarks, copyrights,
+patents, trade secrets or any other intellectual property of Licensor except as
+expressly stated herein. No patent license is granted to make, use, sell or
+offer to sell embodiments of any patent claims other than the licensed claims
+defined in Section 2. No right is granted to the trademarks of Licensor even if
+such marks are included in the Original Work. Nothing in this License shall be
+interpreted to prohibit Licensor from licensing under different terms from this
+License any Original Work that Licensor otherwise would have a right to
+license.
+
+5) This section intentionally omitted.
+
+6) Attribution Rights. You must retain, in the Source Code of any Derivative
+Works that You create, all copyright, patent or trademark notices from the
+Source Code of the Original Work, as well as any notices of licensing and any
+descriptive text identified therein as an "Attribution Notice." You must cause
+the Source Code for any Derivative Works that You create to carry a prominent
+Attribution Notice reasonably calculated to inform recipients that You have
+modified the Original Work.
+
+7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
+the copyright in and to the Original Work and the patent rights granted herein
+by Licensor are owned by the Licensor or are sublicensed to You under the terms
+of this License with the permission of the contributor(s) of those copyrights
+and patent rights. Except as expressly stated in the immediately proceeding
+sentence, the Original Work is provided under this License on an "AS IS" BASIS
+and WITHOUT WARRANTY, either express or implied, including, without limitation,
+the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
+This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
+license to Original Work is granted hereunder except under this disclaimer.
+
+8) Limitation of Liability. Under no circumstances and under no legal theory,
+whether in tort (including negligence), contract, or otherwise, shall the
+Licensor be liable to any person for any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License
+or the use of the Original Work including, without limitation, damages for loss
+of goodwill, work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses. This limitation of liability shall not
+apply to liability for death or personal injury resulting from Licensor's
+negligence to the extent applicable law prohibits such limitation. Some
+jurisdictions do not allow the exclusion or limitation of incidental or
+consequential damages, so this exclusion and limitation may not apply to You.
+
+9) Acceptance and Termination. If You distribute copies of the Original Work or
+a Derivative Work, You must make a reasonable effort under the circumstances to
+obtain the express assent of recipients to the terms of this License. Nothing
+else but this License (or another written agreement between Licensor and You)
+grants You permission to create Derivative Works based upon the Original Work
+or to exercise any of the rights granted in Section 1 herein, and any attempt
+to do so except under the terms of this License (or another written agreement
+between Licensor and You) is expressly prohibited by U.S. copyright law, the
+equivalent laws of other countries, and by international treaty. Therefore, by
+exercising any of the rights granted to You in Section 1 herein, You indicate
+Your acceptance of this License and all of its terms and conditions.
+
+10) Termination for Patent Action. This License shall terminate automatically
+and You may no longer exercise any of the rights granted to You by this License
+as of the date You commence an action, including a cross-claim or counterclaim,
+against Licensor or any licensee alleging that the Original Work infringes a
+patent. This termination provision shall not apply for an action alleging
+patent infringement by combinations of the Original Work with other software or
+hardware.
+
+11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
+License may be brought only in the courts of a jurisdiction wherein the
+Licensor resides or in which Licensor conducts its primary business, and under
+the laws of that jurisdiction excluding its conflict-of-law provisions. The
+application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any use of the Original Work outside the
+scope of this License or after its termination shall be subject to the
+requirements and penalties of the U.S. Copyright Act, 17 U.S.C. � 101 et
+seq., the equivalent laws of other countries, and international treaty. This
+section shall survive the termination of this License.
+
+12) Attorneys Fees. In any action to enforce the terms of this License or
+seeking damages relating thereto, the prevailing party shall be entitled to
+recover its costs and expenses, including, without limitation, reasonable
+attorneys' fees and costs incurred in connection with such action, including
+any appeal of such action. This section shall survive the termination of this
+License.
+
+13) Miscellaneous. This License represents the complete agreement concerning
+the subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to
+make it enforceable.
+
+14) Definition of "You" in This License. "You" throughout this License, whether
+in upper or lower case, means an individual or a legal entity exercising rights
+under, and complying with all of the terms of, this License. For legal
+entities, "You" includes any entity that controls, is controlled by, or is
+under common control with you. For purposes of this definition, "control" means
+(i) the power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty percent
+(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
+entity.
+
+15) Right to Use. You may use the Original Work in all ways not otherwise
+restricted or conditioned by this License or by law, and Licensor promises not
+to interfere with or be responsible for such uses by You.
+
+This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
+Permission is hereby granted to copy and distribute this license without
+modification. This license may not be modified without the express written
+permission of its copyright owner.
\ No newline at end of file
diff --git a/dojox/app/README.txt b/dojox/app/README.txt
old mode 100644
new mode 100755
index 1849006..7118545
--- a/dojox/app/README.txt
+++ b/dojox/app/README.txt
@@ -1,21 +1,24 @@
 -------------------------------------------------------------------------------
-DojoX app 
+dojox/app 
 -------------------------------------------------------------------------------
-Version 0.1
-Release date: 05/08/2011
--------------------------------------------------------------------------------
-Project state: EXPERIMENTAL / Under Construction
+Project state: stable
 
-This project is under active development with increasing capabilities beginning
-in dojo 1.7, but is not yet capable or stable enough to use in production
+This project is licensed under the Dojo Tookit licensing scheme and contributions
+provided under the Dojo CLA.
 -------------------------------------------------------------------------------
 Project authors
 	Dustin Machi
 	Stephen Zhang
+	Eric Wang
+	Ed Chatelain
+	Christophe Jolif
 -------------------------------------------------------------------------------
 Project description
 
-dojox/app is a small application framework providing a set of classes to manage the the lifecycle and behavior of a single page application hosted on mobile or desktop platforms.    The main class, Application, is responsible for providing the lifecycle of the application, but is designed to be easily modified with additional custom behaviors.  An application instance contains scenes and views which provide the visible user interface.  The available views, scenes, module dependencies, an [...]
+dojox/app is a small application framework providing a set of classes to manage the the lifecycle and behavior of a single page application delivered to a mobile or desktop platform.
+The main class, Application, is responsible for providing the lifecycle of the application and is designed to be easily modified with additional custom behaviors.
+An application instance contains views which provide the visible user interface.
+The available views, module dependencies, and other information about the application are all passed into the Application class through a JSON configuration file.
 -------------------------------------------------------------------------------
 Dependencies:
 
@@ -25,11 +28,18 @@ Documentation
 
 config.json 
 
-The config file defines all of the dependencies, application behaviors, top level views and scenes, and any other information required for the application to function.  
+The config file defines all of the dependencies, application behaviors, top level views, and any other information required for the application to function.
 
 Example Config:
-<code>
+```javascript
 {
+	/* any object that complies with Dojo AMD loader configuration. */
+	"loaderConfig" : {
+		"paths": {
+			"mypackage" : "can/be/found/here"
+		}
+	},
+
 	/* global application dependencies */
 	"dependencies": [
 		"dojox/mobile/Heading",
@@ -43,8 +53,19 @@ Example Config:
 		"my/custom/appModule"
 	],
 
-	/* The html template for the application itself */
-	template: "example.html",
+	/* Application Controllers. */
+	"controllers": [
+		"dojox/app/controllers/History",
+		"my/custom/appController"
+	],
+
+	/* The Application level HTML template. */
+	template: "./views/example.html",
+	
+	/* Application level view controller. Application will have a root view even if it has no template.
+	  "./views/myView.js" -- load controller from "./views/myView.js",
+	  no controller -- no controller for this view */
+	"controller": "./views/myView.js",
 
 	/* the view to start on by default */
 	"defaultView": "home",
@@ -52,15 +73,12 @@ Example Config:
 	/* transition to use if none has been provided */
 	"defaultTransition": "slide",
 
-	/* Views and Scenes */
+	/* Views */
 	"views": {
 
 		/* home is a top level dojox.app.view */
 		"home": {
 
-			/* class to instantiate this view as */
-			"type": "dojox.app.view",
-
 			/* dependencies specific to this view */
 			"dependencies: [
 				"dojox/mobile/ListItem",
@@ -68,107 +86,162 @@ Example Config:
 			],
 
 			/* template to use for this view */
-			template: "views/home.html"
+			template: "./views/home.html"
+
+			/* view controller. "none" -- ,
+			  "./views/myHome.js" -- load controller from "./views/myHome.js",
+			  no controller -- no controller for this view */
 		},
 	
-		/* tabscene is a dojox.app.scene, and it contains three child views */
+		/* tabs view contains three child views */
+		"tabs": { 
+			/* the tabs view template */
+			"template": "./views/tabScene.html",
 
-		"tabscene": { 
-			/* class to instantiate, a scene in this case */
-			"type": "dojox.app.scene",
-
-			/* the scene's template */
-			"template": "tabScene.html",
-
-			/* the default view within this scene */	
+			/* the default view within tabs view */	
 			"defaultView": "tab1",
 
 			/* when transitioning between tabs, use a flip animation by default */
 			"defaultTransition": "flip",
 
-			//the views available to this scene
+			//the views available to tabs view
 			"views": { 
 				"tab1":{
-					"template": "views/tabs/tab1.html" 
+					"template": "./views/tabs/tab1.html"
+					/* no controller define for tab1 view, load tab1 view controller from the same location as the template. */
 				},
 				"tab2":{
-					"template": "views/tabs/tab2.html" 
+					"template": "./views/tabs/tab2.html" 
 				},
 				"tab3":{
-					"template": "views/tabs/tab3.html" 
+					"template": "./views/tabs/tab3.html" 
 				}
 			},
 
-			/* dependencies specific to this scene */
-			"dependencies":["dojox/mobile/RoundRectList","dojox/mobile/ListItem", "dojox/mobile/EdgeToEdgeCategory"],
+			/* dependencies specific to tabs view */
+			"dependencies":["dojox/mobile/RoundRectList","dojox/mobile/ListItem", "dojox/mobile/EdgeToEdgeCategory"]
 		}
 
 	}
 }
-
-</code>
+```
 
 Property descriptions
 
-	- dependencies -  These are the modules that are required for the application when defined at the root of the configuration.  When defined inside of a scene or a view, the dependency property defines modules which must be loaded before that view/scene can be instantiated.  
+	- loaderConfig -  This is the configuration that will be passed to the Dojo AMD loader. This allows to specify for example where the loader needs to find modules.
+	 See: http://livedocs.dojotoolkit.org/loader/amd#module-identifiers
 
-	- modules -  The modules property defines application modules that will mixed into the Application class to control the lifecycle and behavior of the application.  These properties will become the array of mixins provided to a dojo.declare() extending the base Application class.  In other words, the Application class that is instantiated is dynamically created at run time using the base class and this list of modules.
+	- dependencies -  These are the modules that are required for the application to run when defined at the root of the configuration.
+	 When defined inside of a view, the dependency property defines modules which must be loaded before that view can be instantiated.
 
-	- template - This is the template/html that is used for the application when defined at the root of the configuration.  Within the context of a view or a scene, it is the template/html for defining said component.  
+	- modules -  The modules property defines application modules that will mixed into the Application class to control the lifecycle and behavior of the application. This property will become the array of mixins provided to a dojo/declare extending the base Application class. In other words, the Application class that is instantiated dynamically is created at run time using the base class and this list of modules.
 
-	- defaultView - The default view defines the starting view for the application when loaded to its root. 
+	- controllers -  The controllers property defines application controllers that will be loaded during application startup to respond to events of the application. The controllers bind events on application's root domNode and the events can be triggered by application's emit() method and documented actions.
 
-	- defaultTransition - This is the default transition method for top level views/scenes when defined at the root of the configuration.  When defined within a scene, it is the default transition method for the associated scene only.
+	- template -  This is the template/HTML that is used for the application when defined at the root of the configuration.
+	 Within the context of a view, it is the template/HTML for defining the view.
 
-	- views -   The views property is a nested set of objects defining the views and scenes available to the application.  Details of views and scene classes will be discussed below.
+	- controller -  This is the view controller that is used for the application template view when defined at the root of the configuration. It implements the view's life cycle interface like init(), beforeActivate(), destroy(), etc. and allows one to control the view.
 
-Some additional properties, such as models, stores, id, name, and description are reserved for future use, but their exact use is still under development.  
+	- defaultView -  The defaultView defines the startup view for the application.
 
-The Application Class:
-	The application class itself doesn't currently exist as an exported class!  The base Application class is a very simple extension of the Scene Class (see below) defined in dojox/app/main.js.  This module file exports a generatation function, which when provided a configuration file will declare the application class that will actually be used on a page and then start it up at a specific node:
-
-<code>
-	require(["dojo/_base/html","dojox/app/main", "dojo/text!app/config.json"],function(dojo,Application,config){
-		app = Application(json.parse(config));
-	});
-</code>
+	- defaultTransition -  This is the default transition method for top level views when defined at the root of the configuration.
+	 When defined within a view, it is the default transition method for the associated views only.
 
+	- views -  The views property is a nested set of objects defining the views available to the application. Details of views classes is discussed below.
 
-The Scene Class:
+	- stores -  The dojo/store implementations that will be used by the application
 
-	The Scene Class provides a templated container for views.  Its purpose is to allow the layout of the scene to be provided through an html template and to have a set of children views which the scene transitions between.  For example, to display a set of tabs, you would use a Scene with a child view for each tab.  The scene's template would define where within the scene the views are displayed and where any tab buttons and such are displayed.
+	- models -  The models (potentially dojox/mvc models) connecting to the stores and exposing data to the application.
 
-	Internally, the Scene steals some concepts layout and templated dijits provide.  The "template", for the base Scene is pretty simple and not really a template.  It is simply HTML content.  However, nodes within the template can be tagged with region="top" (bottom, left, right) to define where that node and its children should be displayed.  For example:
+	- id - The identifier of the application, a global variable with the id name is created by the application.
 
-<code>
-<div  style="background:#c5ccd3;" class="view mblView"> 
-	<div region="top" dojoType="dojox.mobile.Heading">Tab Scene</div>
-	<ul region="top" dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" transitionOptions='{title:"TabScene-Tab1",target:"tabscene,tab1",url: "#tabscene,tab1"}' selected="true">Tab 1</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" transitionOptions='{title:"TabScene-Tab2",target:"tabscene,tab2",url: "#tabscene,tab2"}'>Tab 2</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" transitionOptions='{title:"TabScene-Tab3",target:"tabscene,tab3",url: "#tabscene,tab3"}'>Tab 3</li>
-	</ul>
-</div>
-</code>
+Some additional properties, such as name and description are reserved for future use, but their exact use is still under development.
 
-This template for the tab scene defines two areas with region top, a header and the tab buttons.  The will be placed at the top of this scene when rendered.  
+The Application module:
 
-Normally, when using a BorderContainer, one would also have a region="center" section.  In the case of a Scene however, the "center" region will be applied to the currently active view (the current tab for example).
+The Application class itself doesn't currently exist as an exported class.
+This module exports a generation function, which when provided a configuration file will declare & instantiate the application class that will actually be used on a page. Finally it then starts it up at a specific node:
 
-In addition to the code to support the appropriate lifecycle of the scene and its rendering, it provides a transition method which controls the transition of content from one child view to another.    This includes propogating transition events on to children if the active child is itself another scene.  Scene can container views and other scenes.  Views can only be leaf nodes in the view tree.
+```javascript
+	require(["dojox/json/ref", "dojox/app/main", "dojo/text!app/config.json"],function(json, Application, config){
+		app = Application(json.parse(config));
+	});
+```
 
-The View Class:
+The View module:
 
-Views, like Scenes, are also containers of content.  However, instead of containing additional views as children, they contain only the content defined by their template.  The template may contain widgets.
+The View module provides a View class to construct View instances, a template rendering engine to render view template and view lifecycle APIs. Each View can have one parent view and several children views. It provides a templated container to host the domNodes for the children views. Its purpose is to allow the layout of the view to be provided through an html template and to have a set of children views which the view transitions between. For example, to display a set of tabs, you woul [...]
+In this case the  "template", for the base View is pretty simple. It is a simple HTML content. However, nodes within the template can be tagged with data-app-constraint="top" (bottom, left, right) to define where that node and its children should be displayed.
+For example:
 
-All three of these classes are intended to, at their base, be as simple and feature free as possible providing only basic structure and lifecycle described above (though additional core methods/lifecycle hooks will be added as the are worked out).  A developer using the dojox/app framework can define additional custom  view or scene types simply by extending the base classes (or implementing equivalent functionality) and defining them in the applications configuration file.  The base app [...]
+```html
+<div  style="background:#c5ccd3;" class="view mblView"> 
+	<div data-app-constraint="top" data-dojo-type="dojox/mobile/Heading">Tab View</div>
+	<ul data-app-constraint="top" data-dojo-type="dojox/mobile/TabBar" barType="segmentedControl">
+		<li data-dojo-type="dojox/mobile/TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png"
+			transitionOptions='{title:"TabScene-Tab1",target:"tabscene,tab1",url: "#tabscene,tab1"}' selected="true">Tab 1</li>
+		<li data-dojo-type="dojox/mobile/TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png"
+			transitionOptions='{title:"TabScene-Tab2",target:"tabscene,tab2",url: "#tabscene,tab2"}'>Tab 2</li>
+		<li data-dojo-type="dojox/mobile/TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png"
+			transitionOptions='{title:"TabScene-Tab3",target:"tabscene,tab3",url: "#tabscene,tab3"}'>Tab 3</li>
+	</ul>
+</div>
+```
 
-TODO:
+This template for the tabs view defines two areas with region top, a header and the tab buttons. The will be placed at the top of this main view when rendered.
 
-dojox/app is still an experimental framework with several key pieces still under design and development before a final release.  This final release is expected to occur prior to the Dojo 2.0 release.  The following items are piece that are under development and testing and we see as requirements prior to the final release
+Normally, when using a BorderContainer, one would also have a data-app-constraint="center" section. In the case of a View however, the "center" region will be applied to the currently active view (the current tab for example).
 
-- Model/Store support.  We have a couple of preliminary implementations of model/store support, including one for dojox/mvc.  However, additional work and testing are required to come to a simple and agreed up on API for these components.  While MVC systems such as dojox/mvc should be supported with first class capabilities, they should not be required.   An application developer can 'control' the html of any one view by simply extending the view class and using javascript if they so desired.
+The application can also provide view controller modules to implement the View lifecyle APIs (like init(), destory(),...) for each view. The Transition controller controls the transition from one child view to another. This includes propagating transition events on to children if the active child is itself another view.
 
-- Desktop/Mobile Branching -  Dojox/app is not to be specific to any one particular web platform.  Using css media selectors and definitions within the config, there will be support for choosing which set of views and parameters to use based on the users browser.  
+The Controller module:
 
-- Intelligent build support -  For performance, especially on the mobile side, an appropriate build of the application is required.  Rather than adding a build profile for the app, there will be a wrapper utility that runs the build from the config.json.  This will allow us to intelligently build the base layers and dynamically loaded layers which should be defined by dependencies and default views as well as other information.
+The Controller module provides a base Class to control the application by binding events on application's root domNode. Several controllers required by the framework are implemented in dojox/app/controllers package:
+	
+   * Load controller: load view templates and view controllers
+   * Transition controller: respond to "startTransition" event and do transition between views
+   * Layout controller: perform views layout
+   * History controller: maintain application's history. This is based on HTML5 history APIs and will not work on platforms that do not support it like IE, Android 3 & 4, iOS4, etc.
+   * HistoryHash controller: maintain application's history. This is based on URL hash and has limitation if refresh the browser and back to an URL which out of current application's history stack.
+	
+A developer using the dojox/app framwork can define additional custom controller by extending the base class (dojox/app/Controller) and specifying them in the application configuration file. The events binding to application's root domNode is done by default.
+A developer can use Controller's bind() method to bind event to document, window or dojo/Evented object if needed.
+	
+```javascript
+define(["dojo/_base/lang", "dojo/_base/declare"], function(lang, declare){
+
+	return declare("myApp.myController", Controller, {
+
+		constructor: function(app, events){
+			// summary:
+			//		bind "myEvent1" and "myEvent2" events on application's root domNode.
+			//		bind "resize" event on window
+			// app:
+			//		dojox.app application instance.
+			// events:
+			//		{event : handler}
+			this.events = {
+				"myEvent1": this.myEvent1,
+				"myEvent2": this.myEvent2
+			};
+			this.inherited(arguments);
+
+			// bind "resize" event on window
+			this.bind(window, "resize", this.onResize);
+		},
+		
+		myEvent1: function(){
+			// add your code here
+		},
+		
+		myEvent2: function(){
+			// add your code here
+		},
+		
+		onResize: function(){
+			// add your code here
+		}
+	});
+});
+```
diff --git a/dojox/app/View.js b/dojox/app/View.js
new file mode 100755
index 0000000..ecc3833
--- /dev/null
+++ b/dojox/app/View.js
@@ -0,0 +1,149 @@
+define(["require", "dojo/when", "dojo/on", "dojo/_base/declare", "dojo/_base/lang", "dojo/Deferred",
+		"dijit/Destroyable", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin", "./ViewBase", "./utils/nls"],
+	function(require, when, on, declare, lang, Deferred, Destroyable, _TemplatedMixin, _WidgetsInTemplateMixin, ViewBase, nls){
+
+	return declare("dojox.app.View", [_TemplatedMixin, _WidgetsInTemplateMixin, Destroyable, ViewBase], {
+		// summary:
+		//		View class inheriting from ViewBase adding templating & globalization capabilities.
+		constructor: function(params){
+			// summary:
+			//		Constructs a View instance either from a configuration or programmatically.
+			//
+			// example:
+			//		|	use configuration file
+			//		|
+			// 		|	// load view controller from views/simple.js by default
+			//		|	"simple":{
+			//		|		"template": "myapp/views/simple.html",
+			//		|		"nls": "myapp/nls/simple"
+			//		|		"dependencies":["dojox/mobile/TextBox"]
+			//		|	}
+			//		|
+			//		|	"home":{
+			//		|		"template": "myapp/views/home.html", // no controller set to not use a view controller
+			//		|		"dependencies":["dojox/mobile/TextBox"]
+			//		|	}
+			//		|	"main":{
+			//		|		"template": "myapp/views/main.html",
+			//		|		"controller": "myapp/views/main.js", // identify load view controller from views/main.js
+			//		|		"dependencies":["dojox/mobile/TextBox"]
+			//		|	}
+			//
+			// example:
+			//		|	var viewObj = new View({
+			//		|		app: this.app,
+			//		|		id: this.id,
+			//		|		name: this.name,
+			//		|		parent: this,
+			//		|		templateString: this.templateString,
+			//		|		template: this.template, 
+			//		|		controller: this.controller
+			//		|	});
+			//		|	viewObj.start(); // start view
+			//
+			// params:
+			//		view parameters, include:
+			//
+			//		- app: the app
+			//		- id: view id
+			//		- name: view name
+			//		- template: view template identifier. If templateString is not empty, this parameter is ignored.
+			//		- templateString: view template string
+			//		- controller: view controller module identifier
+			//		- parent: parent view
+			//		- children: children views
+			//		- nls: nls definition module identifier
+		},
+
+		// _TemplatedMixin requires a connect method if data-dojo-attach-* are used
+		connect: function(obj, event, method){
+			return this.own(on(obj, event, lang.hitch(this, method)))[0]; // handle
+		},
+
+		_loadTemplate: function(){
+			// summary:
+			//		load view HTML template and dependencies.
+			// tags:
+			//		private
+			//
+
+			if(this.templateString){
+				return true;
+			}else{
+				var tpl = this.template;
+				var deps = this.dependencies?this.dependencies:[];
+				if(tpl){
+					if(tpl.indexOf("./") == 0){
+						tpl = "app/"+tpl;
+					}
+					deps = deps.concat(["dojo/text!"+tpl]);
+				}
+				var def = new Deferred();
+				if(deps.length > 0){
+					var requireSignal;
+					try{
+						requireSignal = require.on("error", lang.hitch(this, function(error){
+							if(def.isResolved() || def.isRejected()){
+								return;
+							}
+							if(error.info[0] && error.info[0].indexOf(this.template) >= 0 ){
+								def.resolve(false);
+								requireSignal.remove();
+							}
+						}));
+						require(deps, function(){
+							def.resolve.call(def, arguments);
+							requireSignal.remove();
+						});
+					}catch(e){
+						def.resolve(false);
+						if(requireSignal){
+							requireSignal.remove();
+						}
+					}
+				}else{
+					def.resolve(true);
+				}
+				var loadViewDeferred = new Deferred();
+				when(def, lang.hitch(this, function(){
+					this.templateString = this.template ? arguments[0][arguments[0].length - 1] : "<div></div>";
+					loadViewDeferred.resolve(this);
+				}));
+				return loadViewDeferred;
+			}
+		},
+
+		// start view
+		load: function(){
+			var tplDef = new Deferred();
+			var defDef = this.inherited(arguments);
+			var nlsDef = nls(this);
+			// when parent loading is done (controller), proceed with template
+			// (for data-dojo-* to work we need to wait for controller to be here, this is also
+			// useful when the controller is used as a layer for the view)
+			when(defDef, lang.hitch(this, function(){
+				when(nlsDef, lang.hitch(this, function(nls){
+					// we inherit from the parent NLS
+					this.nls = lang.mixin({}, this.parent.nls);
+					if(nls){
+						// make sure template can access nls doing ${nls.myprop}
+						lang.mixin(this.nls, nls);
+					}
+					when(this._loadTemplate(), function(value){
+						tplDef.resolve(value);
+					});
+				}));
+			}));
+			return tplDef;
+		},
+
+		_startup: function(){
+			// summary:
+			//		startup widgets in view template.
+			// tags:
+			//		private
+			this.buildRendering();
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dojox/app/ViewBase.js b/dojox/app/ViewBase.js
new file mode 100755
index 0000000..2b3f980
--- /dev/null
+++ b/dojox/app/ViewBase.js
@@ -0,0 +1,258 @@
+define(["require", "dojo/when", "dojo/on", "dojo/dom-attr", "dojo/_base/declare", "dojo/_base/lang",
+	"dojo/Deferred", "./utils/model", "./utils/constraints"],
+	function(require, when, on, domAttr, declare, lang, Deferred, model, constraints){
+	return declare("dojox.app.ViewBase", null, {
+		// summary:
+		//		View base class with model & controller capabilities. Subclass must implement rendering capabilities.
+		constructor: function(params){
+			// summary:
+			//		Constructs a ViewBase instance.
+			// params:
+			//		view parameters, include:
+			//
+			//		- app: the app
+			//		- id: view id
+			//		- name: view name
+			//		- parent: parent view
+			//		- controller: view controller module identifier
+			//		- children: children views
+			this.id = "";
+			this.name = "";
+			this.children = {};
+			this.selectedChildren = {};
+			this.loadedStores = {};
+			// private
+			this._started = false;
+			lang.mixin(this, params);
+			// mixin views configuration to current view instance.
+			if(this.parent.views){
+				lang.mixin(this, this.parent.views[this.name]);
+			}
+		},
+
+		// start view
+		start: function(){
+			// summary:
+			//		start view object.
+			//		load view template, view controller implement and startup all widgets in view template.
+			if(this._started){
+				return this;
+			}
+			this._startDef = new Deferred();
+			when(this.load(), lang.hitch(this, function(){
+				// call setupModel, after setupModel startup will be called after startup the loadViewDeferred will be resolved
+				this._createDataStore(this);
+				this._setupModel();
+			}));
+			return this._startDef;
+		},
+
+		load: function(){
+			var vcDef = this._loadViewController();
+			when(vcDef, lang.hitch(this, function(controller){
+				if(controller){
+					lang.mixin(this, controller);
+				}
+			}));
+			return vcDef;
+		},
+
+		_createDataStore: function(){
+			// summary:
+			//		Create data store instance for View specific stores
+			//
+			// TODO: move this into a common place for use by main and ViewBase
+			//
+			if(this.parent.loadedStores){
+				lang.mixin(this.loadedStores, this.parent.loadedStores);
+			}
+
+			if(this.stores){
+				//create stores in the configuration.
+				for(var item in this.stores){
+					if(item.charAt(0) !== "_"){//skip the private properties
+						var type = this.stores[item].type ? this.stores[item].type : "dojo/store/Memory";
+						var config = {};
+						if(this.stores[item].params){
+							lang.mixin(config, this.stores[item].params);
+						}
+						// we assume the store is here through dependencies
+						try{
+							var storeCtor = require(type);
+						}catch(e){
+							throw new Error(type+" must be listed in the dependencies");
+						}
+						if(config.data && lang.isString(config.data)){
+							//get the object specified by string value of data property
+							//cannot assign object literal or reference to data property
+							//because json.ref will generate __parent to point to its parent
+							//and will cause infinitive loop when creating StatefulModel.
+							config.data = lang.getObject(config.data);
+						}
+						if(this.stores[item].observable){
+							try{
+								var observableCtor = require("dojo/store/Observable");
+							}catch(e){
+								throw new Error("dojo/store/Observable must be listed in the dependencies");
+							}
+							this.stores[item].store = observableCtor(new storeCtor(config));
+						}else{
+							this.stores[item].store = new storeCtor(config);
+						}
+						this.loadedStores[item] = this.stores[item].store; // add this store to loadedStores for the view							
+					}
+				}
+			}
+		},
+
+		_setupModel: function(){
+			// summary:
+			//		Load views model if it is not already loaded then call _startup.
+			// tags:
+			//		private
+						
+			if(!this.loadedModels){
+				var createPromise;
+				try{
+					createPromise = model(this.models, this.parent, this.app);
+				}catch(e){
+					throw new Error("Error creating models: "+e.message);
+				}
+				when(createPromise, lang.hitch(this, function(models){
+					if(models){
+						// if models is an array it comes from dojo/promise/all. Each array slot contains the same result object
+						// so pick slot 0.
+						this.loadedModels = lang.isArray(models)?models[0]:models;
+					}
+					this._startup();
+				}),
+				function(err){
+					throw new Error("Error creating models: "+err.message);					
+				});
+			}else{ // loadedModels already created so call _startup
+				this._startup();				
+			}		
+		},
+
+		_startup: function(){
+			// summary:
+			//		startup widgets in view template.
+			// tags:
+			//		private
+
+			this._startLayout();			
+		},
+
+		_startLayout: function(){
+			// summary:
+			//		startup widgets in view template.
+			// tags:
+			//		private
+			this.app.log("  > in app/ViewBase _startLayout firing layout for name=[",this.name,"], parent.name=[",this.parent.name,"]");
+
+			if(!this.hasOwnProperty("constraint")){
+				this.constraint = domAttr.get(this.domNode, "data-app-constraint") || "center";
+			}
+			constraints.register(this.constraint);
+
+
+			this.app.emit("app-initLayout", {
+				"view": this, 
+				"callback": lang.hitch(this, function(){
+						//start widget
+						this.startup();
+
+						// call view assistant's init() method to initialize view
+						this.app.log("  > in app/ViewBase calling init() name=[",this.name,"], parent.name=[",this.parent.name,"]");
+						this.init();
+						this._started = true;
+						if(this._startDef){
+							this._startDef.resolve(this);
+						}
+				})
+			});
+		},
+
+
+		_loadViewController: function(){
+			// summary:
+			//		Load view controller by configuration or by default.
+			// tags:
+			//		private
+			//
+			var viewControllerDef = new Deferred();
+			var path;
+
+			if(!this.controller){ // no longer using this.controller === "none", if we dont have one it means none.
+				this.app.log("  > in app/ViewBase _loadViewController no controller set for view name=[",this.name,"], parent.name=[",this.parent.name,"]");
+				viewControllerDef.resolve(true);
+				return viewControllerDef;
+			}else{
+				path = this.controller.replace(/(\.js)$/, "");
+			}
+
+			var requireSignal;
+			try{
+				var loadFile = path;
+				var index = loadFile.indexOf("./");
+				if(index >= 0){
+					loadFile = path.substring(index+2);
+				}
+				requireSignal = require.on("error", function(error){
+					if(viewControllerDef.isResolved() || viewControllerDef.isRejected()){
+						return;
+					}
+					if(error.info[0] && (error.info[0].indexOf(loadFile) >= 0)){
+						viewControllerDef.resolve(false);
+						requireSignal.remove();
+					}
+				});
+
+				if(path.indexOf("./") == 0){
+					path = "app/"+path;
+				}
+
+				require([path], function(controller){
+					viewControllerDef.resolve(controller);
+					requireSignal.remove();
+				});
+			}catch(e){
+				viewControllerDef.reject(e);
+				if(requireSignal){
+					requireSignal.remove();
+				}
+			}
+			return viewControllerDef;
+		},
+
+		init: function(){
+			// summary:
+			//		view life cycle init()
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeDeactivate()
+		},
+
+		afterDeactivate: function(){
+			// summary:
+			//		view life cycle afterDeactivate()
+		},
+
+		destroy: function(){
+			// summary:
+			//		view life cycle destroy()
+		}
+	});
+});
diff --git a/dojox/app/animation.js b/dojox/app/animation.js
deleted file mode 100644
index a2d168c..0000000
--- a/dojox/app/animation.js
+++ /dev/null
@@ -1,346 +0,0 @@
-define(["dojo/_base/kernel", 
-        "dojo/_base/lang",
-        "dojo/_base/declare",
-        "dojo/_base/array",
-        "dojo/_base/Deferred",
-        "dojo/DeferredList",
-        "dojo/on",
-        "dojo/_base/sniff"], 
-        function(dojo, lang, declare, array, deferred, deferredList, on, has){
-    //TODO create cross platform animation/transition effects
-    var transitionEndEventName = "transitionend";
-    var transitionPrefix = "t"; //by default use "t" prefix and "ransition" to make word "transition"
-    var translateMethodStart = "translate3d(";//Android 2.x does not support translateX in CSS Transition, we need to use translate3d in webkit browsers
-    var translateMethodEnd = ",0,0)";
-    if(has("webkit")){
-        transitionPrefix = "WebkitT";
-        transitionEndEventName = "webkitTransitionEnd";
-    }else if(has("mozilla")){
-        transitionPrefix = "MozT";
-        translateMethodStart = "translateX(";
-        translateMethodEnd = ")";
-    }
-    
-    
-
-    //TODO find a way to lock the animation and prevent animation conflict
-    declare("dojox.app.animation", null, {
-        
-
-        constructor: function(args){
-            //default config should be in animation object itself instead of its prototype
-            //otherwise, it might be easy for making mistake of modifying prototype
-            var defaultConfig = {
-                startState: {},
-                endState: {},
-                node: null,
-                duration: 250,
-                "in": true,
-                direction: 1,
-                autoClear: true
-            };
-            
-            lang.mixin(this, defaultConfig);
-            lang.mixin(this, args);
-            
-            //create the deferred object which will resolve after the animation is finished.
-            //We can rely on "onAfterEnd" function to notify the end of a single animation,
-            //but using a deferred object is easier to wait for multiple animations end.
-            if(!this.deferred){
-                this.deferred = new deferred();
-            }
-        },
-        
-        play: function(){
-            //play the animation using CSS3 Transition
-            dojox.app.animation.groupedPlay([this]);
-        },
-        
-        //method to apply the state of the transition
-        _applyState: function(state){
-            var style = this.node.style;
-            for(var property in state){
-                if(state.hasOwnProperty(property)){
-                    style[property] = state[property];
-                }
-            }
-        },
-        
-        //method to initialize state for transition
-        initState: function(){
-            
-            //apply the immediate style change for initial state.
-            this.node.style[transitionPrefix + "ransitionProperty"] = "none";
-            this.node.style[transitionPrefix + "ransitionDuration"] = "0ms";
-            this._applyState(this.startState);
-            
-        },
-        
-        _beforeStart: function(){
-            if (this.node.style.display === "none"){
-                this.node.style.display = "";
-            }
-            this.beforeStart();
-        },
-        
-        _beforeClear: function(){
-            this.node.style[transitionPrefix + "ransitionProperty"] = null;
-            this.node.style[transitionPrefix + "ransitionDuration"] = null;
-            if(this["in"] !== true){
-                this.node.style.display = "none";
-            }            
-            this.beforeClear();
-        },
-        
-        _onAfterEnd: function(){
-            this.deferred.resolve(this.node);
-            if(this.node.id && dojox.app.animation.playing[this.node.id]===this.deferred){
-                delete dojox.app.animation.playing[this.node.id];
-            }
-            this.onAfterEnd();
-        },
-        
-        beforeStart: function(){
-            
-        },
-        
-        beforeClear: function(){
-            
-        },
-        
-        onAfterEnd: function(){
-            
-        },
-        
-        //method to start the transition
-        start: function(){
-            this._beforeStart();
-            
-            var self = this;
-            //change the transition duration
-            self.node.style[transitionPrefix + "ransitionProperty"] = "all";
-            self.node.style[transitionPrefix + "ransitionDuration"] = self.duration + "ms";
-            
-            //connect to clear the transition state after the transition end.
-            //Since the transition is conducted asynchronously, we need to 
-            //connect to transition end event to clear the state
-            on.once(self.node, transitionEndEventName, function(){
-                self.clear();
-            });
-            
-            this._applyState(this.endState);
-        },
-        
-        //method to clear state after transition
-        clear: function(){
-            this._beforeClear();
-            this._removeState(this.endState);
-            console.log(this.node.id + " clear.");
-            this._onAfterEnd();
-        },
-        
-        //create removeState method
-        _removeState: function(state){
-            var style = this.node.style;
-            for(var property in state){
-                if(state.hasOwnProperty(property)){
-                    style[property] = null;
-                }
-            }
-        }
-        
-    });
-    
-    //TODO add the lock mechanism for all of the transition effects
-    //     consider using only one object for one type of transition.
-    //TODO create the first animation, slide.
-    dojox.app.animation.slide = function(node, config){
-
-        //TODO create the return and set the startState, endState of the return
-        var ret = new dojox.app.animation(config);
-        ret.node = node;
-        
-        var startX = "0";
-        var endX = "0";
-        
-        if(ret["in"]){
-            if(ret.direction === 1){
-                startX = "100%";
-            }else{
-                startX = "-100%";
-            }
-        }else{
-            if(ret.direction === 1){
-                endX = "-100%";
-            }else{
-                endX = "100%";
-            }
-        }
-        
-        
-        ret.startState[transitionPrefix + "ransform"]=translateMethodStart+startX+translateMethodEnd;
-        
-        ret.endState[transitionPrefix + "ransform"]=translateMethodStart+endX+translateMethodEnd;
-        
-        return ret;
-    };
-        
-    
-    //fade in/out animation effects
-    dojox.app.animation.fade = function(node, config){
-        
-        var ret = new dojox.app.animation(config);
-        ret.node = node;
-        
-        var startOpacity = "0";
-        var endOpacity = "0";
-        
-        if(ret["in"]){
-            endOpacity = "1";
-        }else{
-            startOpacity = "1";
-        }
-        
-        lang.mixin(ret, {
-            startState:{
-                "opacity": startOpacity
-            },
-            endState:{
-                "opacity": endOpacity
-            }
-        });
-        
-        return ret;
-    };
-    
-  //fade in/out animation effects
-    dojox.app.animation.flip = function(node, config){
-        
-        var ret = new dojox.app.animation(config);
-        ret.node = node;
-       
-        if(ret["in"]){
-            //Need to set opacity here because Android 2.2 has bug that
-            //scale(...) in transform does not persist status
-            lang.mixin(ret,{
-                startState:{
-                    "opacity": "0"
-                },
-                endState:{
-                    "opacity": "1"
-                }
-            });
-            ret.startState[transitionPrefix + "ransform"]="scale(0,0.8) skew(0,-30deg)";
-            ret.endState[transitionPrefix + "ransform"]="scale(1,1) skew(0,0)";
-        }else{
-            lang.mixin(ret,{
-                startState:{
-                    "opacity": "1"
-                },
-                endState:{
-                    "opacity": "0"
-                }
-            });         
-            ret.startState[transitionPrefix + "ransform"]="scale(1,1) skew(0,0)";
-            ret.endState[transitionPrefix + "ransform"]="scale(0,0.8) skew(0,30deg)";
-        }
-        
-        return ret;
-    };
-    
-    var getWaitingList = function(/*Array*/ nodes){
-        var defs = [];
-        array.forEach(nodes, function(node){
-            //check whether the node is under other animation
-            if(node.id && dojox.app.animation.playing[node.id]){
-                //TODO hook on deferred object in dojox.app.animation.playing
-                defs.push(dojox.app.animation.playing[node.id]);
-            }
-            
-        });
-        return new deferredList(defs);
-    };
-    
-    dojox.app.animation.getWaitingList = getWaitingList;
-    
-    //TODO groupedPlay should ensure the UI update happens when
-    //all animations end.
-    //the group player to start multiple animations together
-    dojox.app.animation.groupedPlay = function(/*Array*/args){
-        //args should be array of dojox.app.animation
-        
-        var animNodes = array.filter(args, function(item){
-            return item.node;
-        });
-        
-        var waitingList = getWaitingList(animNodes);
-
-        //update registry with deferred objects in animations of args.
-        array.forEach(args, function(item){
-            if(item.node.id){
-                dojox.app.animation.playing[item.node.id] = item.deferred;
-            }
-        });
-        
-        //TODO wait for all deferred object in deferred list to resolve
-        dojo.when(waitingList, function(){
-            array.forEach(args, function(item){
-                //set the start state
-                item.initState();
-            });
-            
-            //Assume the fps of the animation should be higher than 30 fps and
-            //allow the browser to use one frame's time to redraw so that
-            //the transition can be started
-            setTimeout(function(){
-                array.forEach(args, function(item){
-                    item.start();
-                });            
-            }, 33);
-        });        
-    };
-    
-    //the chain player to start multiple animations one by one
-    dojox.app.animation.chainedPlay = function(/*Array*/args){
-        //args should be array of dojox.app.animation
-        
-        var animNodes = array.filter(args, function(item){
-            return item.node;
-        });
-        
-        var waitingList = getWaitingList(animNodes);
-
-        //update registry with deferred objects in animations of args.
-        array.forEach(args, function(item){
-            if(item.node.id){
-                dojox.app.animation.playing[item.node.id] = item.deferred;
-            }
-        });
-        
-        dojo.when(waitingList, function(){
-            array.forEach(args, function(item){
-                //set the start state
-                item.initState();
-            });
-            
-            //chain animations together
-            for (var i=1, len=args.length; i < len; i++){
-                args[i-1].deferred.then(lang.hitch(args[i], function(){
-                    this.start();
-                }));
-            }
-            
-            //Assume the fps of the animation should be higher than 30 fps and
-            //allow the browser to use one frame's time to redraw so that
-            //the transition can be started
-            setTimeout(function(){
-                args[0].start();
-            }, 33);
-        });        
-    };
-    
-    //TODO complete the registry mechanism for animation handling and prevent animation conflicts
-    dojox.app.animation.playing = {};
-    
-    return dojox.app.animation;
-});
diff --git a/dojox/app/bind.js b/dojox/app/bind.js
deleted file mode 100644
index 3bb43c2..0000000
--- a/dojox/app/bind.js
+++ /dev/null
@@ -1,39 +0,0 @@
-define(["dojo/_base/kernel", "dojo/query" , "dojo/_base/array", "dijit", "dojo/_base/json"], function(dojo, query, array, dijit, djson){
-    return function(/*Array of widgets*/widgets, /*Object*/ models){
-        array.forEach(widgets, function(item){
-            //TODO need to find a better way to get all bindable widgets
-            var bindWidgets = query("div[dojoType^=\"dojox.mvc\"],div[data-dojo-type^=\"dojox.mvc\"]", item.domNode);
-            //set ref for each dojox.mvc widgets.
-            array.forEach(bindWidgets, function(widget){
-                //TODO need to find a better way to know which model the widget is bound to
-                //currently, the ref attribute in dojox.mvc.Group cannot be empty, leave
-                //explicit string with single quote in ref attribute.
-                var ref = widget.getAttribute("ref");
-                
-                if(ref === null){
-                    var refProps = widget.getAttribute("data-dojo-props");
-                    if(refProps){
-                        try{
-                            refProps = djson.fromJson("{" + refProps + "}");
-                        }catch(e){
-                            // give the user a pointer to their invalid parameters. FIXME: can we kill this in production?
-                            throw new Error(e.toString() + " in data-dojo-props='" + extra + "'");
-                        }
-                        ref = refProps.ref.replace(/^\s*rel\s*:\s*/, "");
-                    }
-                }
-                
-                if (ref) {
-                    if(ref[0] === "'"){
-                        ref = ref.substring(1, ref.length-1);
-                    }
-                    var model = dojo.getObject(ref, false, models);
-                    if (model){
-                        dijit.byNode(widget).set("ref", model);
-                    }                    
-                }
-            }, this);
-        }, this);
-        
-    }
-});
diff --git a/dojox/app/build/buildControlApp.js b/dojox/app/build/buildControlApp.js
new file mode 100755
index 0000000..6d8eeaa
--- /dev/null
+++ b/dojox/app/build/buildControlApp.js
@@ -0,0 +1,9 @@
+define(["build/buildControlDefault"], function(bc){
+	// module:
+	//		dojox/app/build/buildControlApp
+	// summary:
+	//		This module extend default build control module to add dojox/app build support
+	// enhance buildControl
+	bc.discoveryProcs.splice(0, 0, "dojox/app/build/discoverAppConfig");
+	return bc;
+});
diff --git a/dojox/app/build/discoverAppConfig.js b/dojox/app/build/discoverAppConfig.js
new file mode 100755
index 0000000..f3f44ae
--- /dev/null
+++ b/dojox/app/build/discoverAppConfig.js
@@ -0,0 +1,120 @@
+define([
+	"build/argv",
+	"build/fs",
+	"build/buildControl",
+	"build/messages",
+	"build/process",
+	"dojox/json/ref"
+], function(argv, fs, bc, messages, process, json){
+	var parseViews = function(mids, mainLayer, views, params){
+		for(var key in views){
+			// ignore naming starting with _ (jsonref adding is own stuff in there)
+			if(key.indexOf("_") == 0){
+				continue;
+			}
+			var view = views[key];
+			// TODO deal with "./" shortcut & default view location (which relies on "./")
+			if(view.controller && view.controller != "none"){
+				var mid = view.controller.replace(/(\.js)$/, "");
+				if(!bc.layers[mid] && bc.multipleAppConfigLayers){
+					bc.layers[mid] = { include: [], exclude: [ "dojo/dojo", mainLayer ] };
+					mids = bc.layers[mid].include;
+				}
+				mids.push(mid);
+			}
+			if(view.template){
+				// we need dojo/text to load templates, let's put it in the main layer in all cases
+				// as this will be shared by a lot of views
+				if(!params.text){
+					params.text = true;
+					bc.layers[mainLayer].include.push("dojo/text");
+				}
+				mids.push(view.template);
+			}
+			if(view.nls){
+				// we use nls let's add dojo/i18n to the main layer as it will be shared by a lot of views
+				if(!params.nls){
+					params.nls = true;
+					bc.layers[mainLayer].include.push("dojo/i18n");
+				}
+				mids.push(view.nls);
+			}
+			if(view.dependencies){
+				Array.prototype.splice.apply(mids, [ mids.length, 0 ].concat(view.dependencies));
+			}
+			if(view.views){
+				parseViews(mids, mainLayer, view.views, params);
+			}
+		}
+	};
+	return function(){
+		var config;
+		try{
+			config = json.fromJson(fs.readFileSync(bc.getSrcModuleInfo(argv.args.appConfigFile, null, false).url));
+		}catch(e){
+			console.log(e);
+		}
+		if(config){
+			var mids = [], params = {};
+			if(config.loaderConfig){
+				require(config.loaderConfig);
+			}
+			// main layer
+			var mainLayer;
+			if(!argv.args.appConfigLayer){
+				// no layer specified, take the first one
+				for(var l in bc.layers){
+					mainLayer = l;
+					break;
+				}
+			}
+			if(!mainLayer && !bc.layers[argv.args.appConfigLayer]){
+				bc.layers[mainLayer = argv.args.appConfigLayer] = { include: [], exclude: [ "dojo/dojo"] };
+			}
+			if(config.dependencies){
+				mids = mids.concat(config.dependencies);
+			}
+			if(config.controllers){
+				mids = mids.concat(config.controllers);
+			}
+			if(config.modules){
+				mids = mids.concat(config.modules);
+			}
+			if(config.transit){
+				mids.push(config.transit);
+			}else{
+				mids.push("dojox/css3/transit");
+			}
+			if(config.template){
+				params.text = true;
+				bc.layers[mainLayer].include.push("dojo/text");
+				mids.push(config.template);
+			}
+			if(config.controller && config.controller != "none"){
+				mids.push(config.controller.replace(/(\.js)$/, ""));
+			}
+			if(config.nls){
+				// we use nls let's add dojo/i18n to the main layer as it will be shared by a lot of views
+				params.nls = true;
+				bc.layers[mainLayer].include.push("dojo/i18n");
+				mids.push(config.nls);
+			}
+			if(config.view){
+				// we use a custom view class
+				mids.push(config.view);
+			}else{
+				// regular view
+				mids.push("dojox/app/View");
+			}
+			// go into the view children
+			if(config.views){
+				parseViews(mids, mainLayer, config.views, params);
+			}
+			Array.prototype.splice.apply(bc.layers[mainLayer].include, [bc.layers[mainLayer].length, 0].concat(mids));
+		}else{
+			messages.log("pacify", argv.args.appConfigFile+" is not a valid dojox/app JSON config file");
+			process.exit(-1);
+		}
+	};
+});
+
diff --git a/dojox/app/controllers/BorderLayout.js b/dojox/app/controllers/BorderLayout.js
new file mode 100755
index 0000000..8d005c3
--- /dev/null
+++ b/dojox/app/controllers/BorderLayout.js
@@ -0,0 +1,88 @@
+define(["dojo/_base/declare", "dojo/dom-attr", "dojo/dom-style", "./LayoutBase","dijit/layout/BorderContainer",
+		"dijit/layout/StackContainer", "dijit/layout/ContentPane", "dijit/registry"],
+function(declare, domAttr, domStyle, LayoutBase, BorderContainer, StackContainer, ContentPane, registry){
+	// module:
+	//		dojox/app/controllers/BorderLayout
+	// summary:
+	//		Will layout an application with a BorderContainer.  
+	//		Each view to be shown in a region of the BorderContainer will be wrapped in a StackContainer and a ContentPane.
+	//		
+
+	return declare("dojox.app.controllers.BorderLayout", LayoutBase, {
+
+		initLayout: function(event){
+			// summary:
+			//		Response to dojox/app "app-initLayout" event which is setup in LayoutBase.
+			//		The initLayout event is called once when the View is being created the first time.
+			//
+			// example:
+			//		Use emit to trigger "app-initLayout" event, and this function will respond to the event. For example:
+			//		|	this.app.emit("app-initLayout", view);
+			//
+			// event: Object
+			// |		{"view": view, "callback": function(){}};
+			this.app.log("in app/controllers/BorderLayout.initLayout event.view.name=[",event.view.name,"] event.view.parent.name=[",event.view.parent.name,"]");
+
+			var bc;
+			if(!this.borderLayoutCreated){ // If the BorderContainer has not been created yet, create it.
+				this.borderLayoutCreated = true;
+				bc = new BorderContainer({id:this.app.id+"-BC", style: "height:100%;width:100%;border:1px solid black"});
+				event.view.parent.domNode.appendChild(bc.domNode);	// put the border container into the parent (app)
+
+				bc.startup();	// startup the BorderContainer
+			}else{
+				bc = registry.byId(this.app.id+"-BC");				
+			}
+
+			this.app.log("in app/controllers/BorderLayout.initLayout event.view.constraint=",event.view.constraint);
+			var constraint = event.view.constraint;	// constraint holds the region for this view, center, top etc.
+			
+			if(event.view.parent.id == this.app.id){	// If the parent of this view is the app we are working with the BorderContainer
+				var reg = registry.byId(event.view.parent.id+"-"+constraint);			
+				if(reg){	// already has a stackContainer, just create the contentPane for this view and add it to the stackContainer.
+					var cp1 = new ContentPane({id:event.view.id+"-cp-"+constraint});
+					cp1.addChild(event.view); // important to add the widget to the cp before adding cp to BorderContainer for height
+					reg.addChild(cp1);
+					bc.addChild(reg);
+				}else{ // need a contentPane
+					// this is where the region (constraint) is set for the BorderContainer's StackContainer
+					var noSplitter = this.app.borderLayoutNoSplitter || false;
+					var sc1 = new StackContainer({doLayout: true, splitter:!noSplitter, region:constraint, id:event.view.parent.id+"-"+constraint});
+					var cp1 = new ContentPane({id:event.view.id+"-cp-"+constraint});
+					cp1.addChild(event.view); // should we use addChild or appendChild?
+					sc1.addChild(cp1);
+					bc.addChild(sc1);
+				}
+			}else{ // Not a top level page transition, so not changing a page in the BorderContainer, so handle it like Layout.
+				event.view.parent.domNode.appendChild(event.view.domNode);
+				domAttr.set(event.view.domNode, "data-app-constraint", event.view.constraint);
+			}
+
+			this.inherited(arguments);
+		},
+
+		hideView: function(view){
+			var bc = registry.byId(this.app.id+"-BC");
+			var sc = registry.byId(view.parent.id+"-"+view.constraint);
+			if(bc && sc){
+				sc.removedFromBc = true;
+				bc.removeChild(sc);
+			}
+		},
+
+		showView: function(view){
+			var sc = registry.byId(view.parent.id+"-"+view.constraint);
+			var cp = registry.byId(view.id+"-cp-"+view.constraint);
+			if(sc && cp){
+				if(sc.removedFromBc){
+					sc.removedFromBc = false;
+					registry.byId(this.app.id+"-BC").addChild(sc);
+					domStyle.set(view.domNode, "display", "");
+				}
+				domStyle.set(cp.domNode, "display", "");
+				sc.selectChild(cp);
+				sc.resize();
+			}
+		}
+	});
+});
diff --git a/dojox/app/controllers/History.js b/dojox/app/controllers/History.js
new file mode 100755
index 0000000..8fbc1f9
--- /dev/null
+++ b/dojox/app/controllers/History.js
@@ -0,0 +1,127 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/on", "../Controller", "../utils/hash", "dojo/topic"],
+function(lang, declare, on, Controller, hash, topic){
+	// module:
+	//		dojox/app/controllers/History
+	// summary:
+	//		Bind "app-domNode" event on dojox/app application instance.
+	//		Bind "startTransition" event on dojox/app application domNode.
+	//		Bind "popstate" event on window object.
+	//		Maintain history by HTML5 "pushState" method and "popstate" event.
+
+	return declare("dojox.app.controllers.History", Controller, {
+		// _currentPosition:     Integer
+		//              Persistent variable which indicates the current position/index in the history
+		//              (so as to be able to figure out whether the popState event was triggerd by
+		//              a backward or forward action).
+		_currentPosition: 0,
+
+		// currentState: Object
+		//              Current state
+		currentState: {},
+
+		constructor: function(){
+			// summary:
+			//		Bind "app-domNode" event on dojox/app application instance.
+			//		Bind "startTransition" event on dojox/app application domNode.
+			//		Bind "popstate" event on window object.
+			//
+
+			this.events = {
+				"app-domNode": this.onDomNodeChange
+			};
+			if(this.app.domNode){
+				this.onDomNodeChange({oldNode: null, newNode: this.app.domNode});
+			}
+			this.bind(window, "popstate", lang.hitch(this, this.onPopState));
+		},
+
+		onDomNodeChange: function(evt){
+			if(evt.oldNode != null){
+				this.unbind(evt.oldNode, "startTransition");
+			}
+			this.bind(evt.newNode, "startTransition", lang.hitch(this, this.onStartTransition));
+		},
+
+		onStartTransition: function(evt){
+			// summary:
+			//		Response to dojox/app "startTransition" event.
+			//
+			// example:
+			//		Use "dojox/mobile/TransitionEvent" to trigger "startTransition" event, and this function will response the event. For example:
+			//		|	var transOpts = {
+			//		|		title:"List",
+			//		|		target:"items,list",
+			//		|		url: "#items,list",
+			//		|		params: {"param1":"p1value"}
+			//		|	};
+			//		|	new TransitionEvent(domNode, transOpts, e).dispatch();
+			//
+			// evt: Object
+			//		Transition options parameter
+			var currentHash = window.location.hash;
+			var currentView = hash.getTarget(currentHash, this.app.defaultView);
+			var currentParams =  hash.getParams(currentHash);
+			var _detail = lang.clone(evt.detail);
+			_detail.target = _detail.title = currentView;
+			_detail.url = currentHash;
+			_detail.params = currentParams;
+			_detail.id = this._currentPosition;
+
+			// Create initial state if necessary
+			if(history.length == 1){
+				history.pushState(_detail, _detail.href, currentHash);
+			}
+
+			// Update the current state
+			_detail.bwdTransition = _detail.transition;
+			lang.mixin(this.currentState, _detail);
+			history.replaceState(this.currentState, this.currentState.href, currentHash);
+
+			// Create a new "current state" history entry
+			this._currentPosition += 1;
+			evt.detail.id = this._currentPosition;
+
+			var newHash = evt.detail.url || "#" + evt.detail.target;
+
+			if(evt.detail.params){
+				newHash = hash.buildWithParams(newHash, evt.detail.params);
+			}
+
+			evt.detail.fwdTransition = evt.detail.transition;
+			history.pushState(evt.detail, evt.detail.href, newHash);
+			this.currentState = lang.clone(evt.detail);
+
+			// Finally: Publish pushState topic
+			topic.publish("/app/history/pushState", evt.detail.target);
+		},
+
+		onPopState: function(evt){
+			// summary:
+			//		Response to dojox/app "popstate" event.
+			//
+			// evt: Object
+			//		Transition options parameter
+
+			// Clean browser's cache and refresh the current page will trigger popState event,
+			// but in this situation the application has not started and throws an error.
+			// So we need to check application status, if application not STARTED, do nothing.
+			if((this.app.getStatus() !== this.app.lifecycle.STARTED) || !evt.state ){
+				return;
+			}
+
+			// Get direction of navigation and update _currentPosition accordingly
+			var backward = evt.state.id < this._currentPosition;
+			backward ? this._currentPosition -= 1 : this._currentPosition += 1;
+
+			// Publish popState topic and transition to the target view. Important: Use correct transition.
+			// Reverse transitionDir only if the user navigates backwards.
+			var opts = lang.mixin({reverse: backward ? true : false}, evt.state);
+			opts.transition = backward ? opts.bwdTransition : opts.fwdTransition;
+			this.app.emit("app-transition", {
+				viewId: evt.state.target,
+				opts: opts
+			});
+			topic.publish("/app/history/popState", evt.state.target);
+		}
+	});
+});
diff --git a/dojox/app/controllers/HistoryHash.js b/dojox/app/controllers/HistoryHash.js
new file mode 100755
index 0000000..c2b6940
--- /dev/null
+++ b/dojox/app/controllers/HistoryHash.js
@@ -0,0 +1,291 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/topic", "dojo/on", "../Controller", "../utils/hash", "dojo/hash"],
+	function(lang, declare, topic, on, Controller, hash){
+	// module:
+	//		dojox/app/controllers/HistoryHash
+	// summary:
+	//		Bind "app-domNode" event on dojox/app application instance,
+	//		Bind "startTransition" event on dojox/app application domNode,
+	//		Bind "/dojo/hashchange" event on window object.
+	//		Maintain history by history hash.
+
+	return declare("dojox.app.controllers.HistoryHash", Controller, {
+
+		constructor: function(app){
+			// summary:
+			//		Bind "app-domNode" event on dojox/app application instance,
+			//		Bind "startTransition" event on dojox/app application domNode,
+			//		subscribe "/dojo/hashchange" event.
+			//
+			// app:
+			//		dojox/app application instance.
+			this.events = {
+				"app-domNode": this.onDomNodeChange
+			};
+			if(this.app.domNode){
+				this.onDomNodeChange({oldNode: null, newNode: this.app.domNode});
+			}
+			topic.subscribe("/dojo/hashchange", lang.hitch(this, function(newhash){
+				this._onHashChange(newhash);
+			}));
+
+			this._historyStack = []; // application history stack
+			this._historyLen = 0;	// current window.history length
+			this._historyDiff = 0; // the diff of window.history stack and application history stack 
+			this._current = null;	// current history item in application history stack
+			this._next = null;		// next history item in application history stack
+			this._previous = null;	// previous history item in application history stack
+			this._index = 0;		// identify current history item's index in application history stack
+			this._oldHistoryLen = 0;// window.history stack length before hash change
+			this._newHistoryLen = 0;// window.history stack length after hash change
+			this._addToHistoryStack = false;
+			this._startTransitionEvent = false;
+
+			// push the default page to the history stack
+			var currentHash = window.location.hash;
+			if(currentHash && (currentHash.length > 1)){
+				currentHash = currentHash.substr(1);
+			}
+			this._historyStack.push({
+				"hash": currentHash,
+				"url": window.location.href,
+				"detail": {target:currentHash}
+			});
+			this._historyLen = window.history.length;
+			this._index = this._historyStack.length - 1;
+			this._current = currentHash;
+
+			// get the diff of window.history and application history
+			this._historyDiff = window.history.length - this._historyStack.length;
+		},
+
+		onDomNodeChange: function(evt){
+			if(evt.oldNode != null){
+				this.unbind(evt.oldNode, "startTransition");
+			}
+			this.bind(evt.newNode, "startTransition", lang.hitch(this, this.onStartTransition));
+		},
+
+		onStartTransition: function(evt){
+			// summary:
+			//		Response to dojox/app "startTransition" event.
+			//
+			// example:
+			//		Use "dojox/mobile/TransitionEvent" to trigger "startTransition" event, and this function will response the event. For example:
+			//		|	var transOpts = {
+			//		|		title:"List",
+			//		|		target:"items,list",
+			//		|		url: "#items,list"
+			//		|		params: {"param1":"p1value"}
+			//		|	};
+			//		|	new TransitionEvent(domNode, transOpts, e).dispatch();
+			//
+			// evt: Object
+			//		transition options parameter
+
+			var target = evt.detail.target;
+			var regex = /#(.+)/;
+			if(!target && regex.test(evt.detail.href)){
+				target = evt.detail.href.match(regex)[1];
+			}
+
+			var currentHash = evt.detail.url || "#" + target;
+
+			if(evt.detail.params){
+				currentHash = hash.buildWithParams(currentHash, evt.detail.params);
+			}
+
+			this._oldHistoryLen = window.history.length;
+			// pushState on iOS will not change location bar hash because of security.
+			// window.history.pushState(evt.detail, title, currentHash);
+
+			// history.length will be changed by set location hash
+			// change url hash, to workaround iOS pushState not change address bar issue.
+			window.location.hash = currentHash;
+
+			// The operation above will trigger hashchange.
+			// Use _addToHistoryStack flag to indicate the _onHashChange method should add this hash to history stack.
+			// When add hash to history stack, this flag should be set to false, we do this in _addHistory.
+			this._addToHistoryStack = true;
+			//set startTransition event flag to true if the hash change from startTransition event.
+			this._startTransitionEvent = true;
+		},
+
+		_addHistory: function(hash){
+			// summary:
+			//		Add hash to application history stack, update history management flags.
+			//
+			// hash:
+			//		new hash should be added to _historyStack.
+			this._historyStack.push({
+				"hash": hash,
+				"url": window.location.href,
+				"detail": {target:hash}
+			});
+
+			this._historyLen = window.history.length;
+			this._index = this._historyStack.length - 1;
+
+			this._previous = this._current;
+			this._current = hash;
+			this._next = null;
+
+			this._historyDiff = window.history.length - this._historyStack.length;
+
+			// In order to make sure _addToHistoryStack flag invalid after add hash to history stack,
+			// we set this flag to false in every addHistory operation even if it's already false.
+			this._addToHistoryStack = false;
+		},
+
+		_onHashChange: function(currentHash){
+			// summary:
+			//		subscribe /dojo/hashchange and do add history, back, forward and go operation.
+			//
+			// currentHash:
+			//		the new url hash when /dojo/hashchange is triggered.
+
+			if(this._index < 0 || this._index > (window.history.length - 1)){
+				throw Error("Application history out of management.");
+			}
+
+			this._newHistoryLen = window.history.length;
+
+			// Application history stack asynchronized with window.history, refresh application history stack.
+			if(this._oldHistoryLen > this._newHistoryLen){
+				//console.log("need to refresh _historyStack, oldLen:"+this._oldHistoryLen+", newLen: "+this._newHistoryLen+", diff:"+this._historyDiff);
+				this._historyStack.splice((this._newHistoryLen - this._historyDiff - 1), (this._historyStack.length - 1));
+
+				// Reset _historyLen to make sure this._historyLen<window.history.length, so it will push this hash to history stack.
+				this._historyLen = this._historyStack.length;
+
+				// Reset this._oldHistoryLen, so it can avoid refresh history stack again in some situation,
+				// because by doing this, this._oldHistoryLen !== this._newHistoryLen
+				this._oldHistoryLen = 0;
+			}
+
+			// this._oldHistoryLen === this._newHistoryLen, it maybe need to refresh history stack or do history go, back and forward,
+			// so we use _addToHistoryStack to identify the refresh operation.
+			if(this._addToHistoryStack && (this._oldHistoryLen === this._newHistoryLen)){
+				this._historyStack.splice((this._newHistoryLen - this._historyDiff - 1), (this._historyStack.length - 1));
+				this._addHistory(currentHash);
+
+				// It's a refresh operation, so that's no need to check history go, back or forward, just return.
+				return;
+			}
+
+			//window.history.length increase, add hash to application history stack.
+			if(this._historyLen < window.history.length){
+				this._addHistory(currentHash);
+				if(!this._startTransitionEvent){
+					// transition to the target view
+					this.app.emit("app-transition", {
+						viewId: hash.getTarget(currentHash),
+						opts: { params: hash.getParams(currentHash) || {} }
+					});
+				}
+			}else{
+				if(currentHash == this._current){
+					// console.log("do nothing.");
+				}else if(currentHash === this._previous){ // back
+					this._back(currentHash, this._historyStack[this._index]["detail"]);
+				}else if(currentHash === this._next){ //forward
+					this._forward(currentHash, this._historyStack[this._index]["detail"]);
+				}else{ // go
+					//search in "back" first, then "forward"
+					var index = -1;
+					for(var i = this._index; i > 0; i--){
+						if(currentHash === this._historyStack[i]["hash"]){
+							index = i;
+							break;
+						}
+					}
+
+					//search in "forward"
+					if(-1 === index){
+						for(var i = this._index; i < this._historyStack.length; i++){
+							if(currentHash === this._historyStack[i]["hash"]){
+								index = i;
+								break;
+							}
+						}
+					}
+
+					if(0 < index < this._historyStack.length){
+						this._go(index, (index - this._index));
+					}else{
+						this.app.log("go error. index out of history stack.");
+					}
+				}
+			}
+			// set startTransition event flag to false
+			this._startTransitionEvent = false;
+		},
+
+		_back: function(currentHash, detail){
+			this.app.log("back");
+			this._next = this._historyStack[this._index]["hash"];
+			this._index--;
+			if(this._index > 0){
+				this._previous = this._historyStack[this._index - 1]["hash"];
+			}else{
+				this._previous = null;
+			}
+			this._current = currentHash;
+
+			var target = hash.getTarget(currentHash, this.app.defaultView);
+
+			// publish history back event
+			topic.publish("/app/history/back", {"viewId": target, "detail": detail});
+
+			// transition to the target view
+			this.app.emit("app-transition", {
+				viewId: target,
+ 				opts: lang.mixin({reverse: true}, detail, {"params": hash.getParams(currentHash)})
+			});
+		},
+
+		_forward: function(currentHash, detail){
+			this.app.log("forward");
+			this._previous = this._historyStack[this._index]["hash"];
+			this._index++;
+			if(this._index < this._historyStack.length - 1){
+				this._next = this._historyStack[this._index + 1]["hash"];
+			}else{
+				this._next = null;
+			}
+			this._current = currentHash;
+
+			var target = hash.getTarget(currentHash, this.app.defaultView);
+
+			// publish history forward event
+			topic.publish("/app/history/forward", {"viewId": target, "detail": detail});
+
+			// transition to the target view
+			this.app.emit("app-transition", {
+				viewId: target,
+ 				opts: lang.mixin({reverse: false}, detail, {"params": hash.getParams(currentHash)})
+			});
+		},
+
+		_go: function(index, step){
+			if(index < 0 || (index > window.history.length - 1)){
+				throw Error("Application history.go steps out of management, index: "+index+" length: "+window.history.length);
+			}
+
+			this._index = index;
+			this._current = this._historyStack[index]["hash"];
+			this._previous = this._historyStack[index - 1] ? this._historyStack[index - 1]["hash"] : null;
+			this._next = this._historyStack[index + 1] ? this._historyStack[index + 1]["hash"] : null;
+
+			var target = hash.getTarget(this._current, this.app.defaultView);
+
+			// publish history go event
+			topic.publish("/app/history/go", {"viewId": target, "step": step, "detail": this._historyStack[index]["detail"]});
+
+			// transition to the target view
+			this.app.emit("app-transition", {
+				viewId: target,
+				opts: lang.mixin({reverse: (step <= 0)}, this._historyStack[index]["detail"], {"params": hash.getParams(this._current)})
+			});
+		}
+	});
+});
diff --git a/dojox/app/controllers/Layout.js b/dojox/app/controllers/Layout.js
new file mode 100755
index 0000000..06dc53f
--- /dev/null
+++ b/dojox/app/controllers/Layout.js
@@ -0,0 +1,192 @@
+define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/window",
+		"dojo/query", "dojo/dom-geometry", "dojo/dom-attr", "dojo/dom-style", "dijit/registry",
+		"./LayoutBase", "../utils/layout", "../utils/constraints"],
+function(declare, lang, array, win, query, domGeom, domAttr, domStyle, registry, LayoutBase, layout, constraints){
+	// module:
+	//		dojox/app/controllers/Layout
+	// summary:
+	//		Extends LayoutBase which binds "app-initLayout", "app-layoutView" and "app-resize" events on application instance.
+
+	return declare("dojox.app.controllers.Layout", LayoutBase, {
+
+		constructor: function(app, events){
+			// summary:
+			//		bind "app-initLayout" and "app-layoutView" events on application instance.
+			//
+			// app:
+			//		dojox/app application instance.
+			// events:
+			//		{event : handler}
+		},
+
+		onResize: function(){
+			this._doResize(this.app);
+			// this is needed to resize the children on an orientation change or a resize of the browser.
+			// it was being done in _doResize, but was not needed for every call to _doResize.
+			this.resizeSelectedChildren(this.app);
+		},
+
+
+		resizeSelectedChildren: function(w){
+			for(var hash in w.selectedChildren){	// need this to handle all selectedChildren
+				if(w.selectedChildren[hash]){
+					this.app.log("in Layout resizeSelectedChildren calling resizeSelectedChildren calling _doResize for w.selectedChildren[hash].id="+w.selectedChildren[hash].id);
+					this._doResize(w.selectedChildren[hash]);
+					// Call resize on child widgets, needed to get the scrollableView to resize correctly initially	
+					array.forEach(w.selectedChildren[hash].domNode.children, function(child){
+						if(registry.byId(child.id) && registry.byId(child.id).resize){ 
+							registry.byId(child.id).resize(); 
+						}
+					});	
+
+					this.resizeSelectedChildren(w.selectedChildren[hash]);
+				}
+			}
+		},
+
+		initLayout: function(event){
+			// summary:
+			//		Response to dojox/app "app-initLayout" event.
+			//
+			// example:
+			//		Use emit to trigger "app-initLayout" event, and this function will respond to the event. For example:
+			//		|	this.app.emit("app-initLayout", view);
+			//
+			// event: Object
+			// |		{"view": view, "callback": function(){}};
+			this.app.log("in app/controllers/Layout.initLayout event=",event);
+			this.app.log("in app/controllers/Layout.initLayout event.view.parent.name=[",event.view.parent.name,"]");
+
+			event.view.parent.domNode.appendChild(event.view.domNode);
+
+			domAttr.set(event.view.domNode, "data-app-constraint", event.view.constraint);
+
+			this.inherited(arguments);
+		},
+
+		_doResize: function(view){
+			// summary:
+			//		resize view.
+			//
+			// view: Object
+			//		view instance needs to do layout.
+			var node = view.domNode;
+			if(!node){
+				this.app.log("Warning - View has not been loaded, in Layout _doResize view.domNode is not set for view.id="+view.id+" view=",view);
+				return;
+			}
+
+			// If either height or width wasn't specified by the user, then query node for it.
+			// But note that setting the margin box and then immediately querying dimensions may return
+			// inaccurate results, so try not to depend on it.
+			var mb = {};
+			if( !("h" in mb) || !("w" in mb) ){
+				mb = lang.mixin(domGeom.getMarginBox(node), mb);	// just use dojo/_base/html.marginBox() to fill in missing values
+			}
+
+			// Compute and save the size of my border box and content box
+			// (w/out calling dojo/_base/html.contentBox() since that may fail if size was recently set)
+			if(view !== this.app){
+				var cs = domStyle.getComputedStyle(node);
+				var me = domGeom.getMarginExtents(node, cs);
+				var be = domGeom.getBorderExtents(node, cs);
+				var bb = (view._borderBox = {
+					w: mb.w - (me.w + be.w),
+					h: mb.h - (me.h + be.h)
+				});
+				var pe = domGeom.getPadExtents(node, cs);
+				view._contentBox = {
+					l: domStyle.toPixelValue(node, cs.paddingLeft),
+					t: domStyle.toPixelValue(node, cs.paddingTop),
+					w: bb.w - pe.w,
+					h: bb.h - pe.h
+				};
+			}else{
+				// if we are layouting the top level app the above code does not work when hiding address bar
+				// so let's use similar code to dojo mobile.
+				view._contentBox = {
+					l: 0,
+					t: 0,
+					h: win.global.innerHeight || win.doc.documentElement.clientHeight,
+					w: win.global.innerWidth || win.doc.documentElement.clientWidth
+				};
+			}
+
+			this.inherited(arguments);
+		},
+
+		layoutView: function(event){
+			// summary:
+			//		Response to dojox/app "app-layoutView" event.
+			//
+			// example:
+			//		Use emit to trigger "app-layoutView" event, and this function will response the event. For example:
+			//		|	this.app.emit("app-layoutView", view);
+			//
+			// event: Object
+			// |		{"parent":parent, "view":view, "removeView": boolean}
+			if(event.view){
+				this.inherited(arguments);
+				// do selected view layout
+				// call _doResize for parent and view here, doResize will no longer call it for all children.
+				this._doResize(event.parent || this.app);
+				this._doResize(event.view);
+			}
+		},
+
+		_doLayout: function(view){
+			// summary:
+			//		do view layout.
+			//
+			// view: Object
+			//		view instance needs to do layout.
+
+			if(!view){
+				console.warn("layout empty view.");
+				return;
+			}
+			this.app.log("in Layout _doLayout called for view.id="+view.id+" view=",view);
+
+			var children;
+			// TODO: probably need to handle selectedChildren here, not just selected child...
+			// TODO: why are we passing view here? not parent? This call does not seem logical?
+			var selectedChild = constraints.getSelectedChild(view, view.constraint);
+			if(selectedChild && selectedChild.isFullScreen){
+				console.warn("fullscreen sceen layout");
+				/*
+				 fullScreenScene=true;
+				 children=[{domNode: selectedChild.domNode,constraint: "center"}];
+				 query("> [constraint]",this.domNode).forEach(function(c){
+				 if(selectedChild.domNode!==c.domNode){
+				 dstyle(c.domNode,"display","none");
+				 }
+				 })
+				 */
+			}else{
+				children = query("> [data-app-constraint]", view.domNode).map(function(node){
+					var w = registry.getEnclosingWidget(node);
+					if(w){
+						w._constraint = domAttr.get(node, "data-app-constraint");
+						return w;
+					}
+
+					return {
+						domNode: node,
+						_constraint: domAttr.get(node, "data-app-constraint")
+					};
+				});
+				
+				if(selectedChild){
+					children = array.filter(children, function(c){
+						// do not need to set display none here it is set in select.
+						return c.domNode && c._constraint;
+					}, view);
+				}
+			}
+			// We don't need to layout children if this._contentBox is null for the operation will do nothing.
+			if(view._contentBox){
+				layout.layoutChildren(view.domNode, view._contentBox, children);
+			}
+		}
+	});
+});
diff --git a/dojox/app/controllers/LayoutBase.js b/dojox/app/controllers/LayoutBase.js
new file mode 100755
index 0000000..f71b627
--- /dev/null
+++ b/dojox/app/controllers/LayoutBase.js
@@ -0,0 +1,130 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/sniff", "dojo/_base/window", "dojo/_base/config",
+		"dojo/dom-attr", "dojo/topic", "dojo/dom-style", "../utils/constraints", "../Controller"],
+function(lang, declare, has, win, config, domAttr, topic, domStyle, constraints, Controller){
+	// module:
+	//		dojox/app/controllers/LayoutBase
+	// summary:
+	//		Bind "app-initLayout", "app-layoutView" and "app-resize" events on application instance.
+
+	return declare("dojox.app.controllers.LayoutBase", Controller, {
+
+		constructor: function(app, events){
+			// summary:
+			//		bind "app-initLayout", "app-layoutView" and "app-resize" events on application instance.
+			//
+			// app:
+			//		dojox/app application instance.
+			// events:
+			//		{event : handler}
+			this.events = {
+				"app-initLayout": this.initLayout,
+				"app-layoutView": this.layoutView,
+				"app-resize": this.onResize
+			};
+			// if we are using dojo mobile & we are hiding address bar we need to be bit smarter and listen to
+			// dojo mobile events instead
+			if(config.mblHideAddressBar){
+				topic.subscribe("/dojox/mobile/afterResizeAll", lang.hitch(this, this.onResize));
+			}else{
+				// bind to browsers orientationchange event for ios otherwise bind to browsers resize
+				this.bind(win.global, has("ios") ? "orientationchange" : "resize", lang.hitch(this, this.onResize));
+			}
+		},
+
+		onResize: function(){
+			this._doResize(this.app);
+			// this is needed to resize the children on an orientation change or a resize of the browser.
+			// it was being done in _doResize, but was not needed for every call to _doResize.
+			for(var hash in this.app.selectedChildren){	// need this to handle all selectedChildren
+				if(this.app.selectedChildren[hash]){
+					this._doResize(this.app.selectedChildren[hash]);
+				}
+			}
+			
+		},
+		
+		initLayout: function(event){
+			// summary:
+			//		Response to dojox/app "app-initLayout" event.
+			//
+			// example:
+			//		Use emit to trigger "app-initLayout" event, and this function will respond to the event. For example:
+			//		|	this.app.emit("app-initLayout", view);
+			//
+			// event: Object
+			// |		{"view": view, "callback": function(){}};
+			domAttr.set(event.view.domNode, "id", event.view.id);	// Set the id for the domNode
+			if(event.callback){	// if the event has a callback, call it.
+				event.callback();
+			}
+		},
+
+		_doLayout: function(view){
+			// summary:
+			//		do view layout.
+			//
+			// view: Object
+			//		view instance needs to do layout.
+
+			if(!view){
+				console.warn("layout empty view.");
+			}
+		},
+
+		_doResize: function(view){
+			// summary:
+			//		resize view.
+			//
+			// view: Object
+			//		view instance needs to do resize.
+			this.app.log("in LayoutBase _doResize called for view.id="+view.id+" view=",view);
+			this._doLayout(view);
+		},
+
+		layoutView: function(event){
+			// summary:
+			//		Response to dojox/app "app-layoutView" event.
+			//
+			// example:
+			//		Use emit to trigger "app-layoutView" event, and this function will response the event. For example:
+			//		|	this.app.emit("app-layoutView", view);
+			//
+			// event: Object
+			// |		{"parent":parent, "view":view, "removeView": boolean}
+			var parent = event.parent || this.app;
+			var view = event.view;
+
+			if(!view){
+				return;
+			}
+			
+			// if the parent has a child in the view constraint it has to be hidden, and this view displayed.
+			var parentSelChild = constraints.getSelectedChild(parent, view.constraint);
+			if(event.removeView){	// if this view is being removed set display to none and the selectedChildren entry to null
+				view.viewShowing = false;
+				this.hideView(view);
+				if(view == parentSelChild){
+					constraints.setSelectedChild(parent, view.constraint, null);	// remove from selectedChildren
+				}
+			}else if(view !== parentSelChild){
+				if(parentSelChild){
+				//	domStyle.set(parentSelChild.domNode, "zIndex", 25);
+					parentSelChild.viewShowing = false;
+					this.hideView(parentSelChild);
+				}
+				view.viewShowing = true;
+				this.showView(view);
+				//domStyle.set(view.domNode, "zIndex", 50);
+				constraints.setSelectedChild(parent, view.constraint, view);
+			}
+		},
+
+		hideView: function(view){
+			domStyle.set(view.domNode, "display", "none");
+		},
+
+		showView: function(view){
+			domStyle.set(view.domNode, "display", "");
+		}
+	});
+});
diff --git a/dojox/app/controllers/Load.js b/dojox/app/controllers/Load.js
new file mode 100755
index 0000000..68b5d75
--- /dev/null
+++ b/dojox/app/controllers/Load.js
@@ -0,0 +1,278 @@
+define(["require", "dojo/_base/lang", "dojo/_base/declare", "dojo/on", "dojo/Deferred", "dojo/when", "../Controller"],
+	function(require, lang, declare, on, Deferred, when, Controller, View){
+	// module:
+	//		dojox/app/controllers/Load
+	// summary:
+	//		Bind "app-load" event on dojox/app application instance.
+	//		Load child view and sub children at one time.
+
+	return declare("dojox.app.controllers.Load", Controller, {
+
+
+		_waitingQueue:[],
+
+		constructor: function(app, events){
+			// summary:
+			//		bind "app-load" event on application instance.
+			//
+			// app:
+			//		dojox/app application instance.
+			// events:
+			//		{event : handler}
+			this.events = {
+				"app-init": this.init,
+				"app-load": this.load
+			};
+		},
+
+		init: function(event){
+			// when the load controller received "app-init", before the lifecycle really starts we create the root view
+			// if any. This used to be done in main.js but must be done in Load to be able to create custom
+			// views from the Load controller.
+			//create and start child. return Deferred
+			when(this.createView(event.parent, null, null, {
+					templateString: event.templateString,
+					controller: event.controller
+			}, null, event.type), function(newView){
+				when(newView.start(), event.callback);
+			});
+		},
+
+		load: function(event){
+			// summary:
+			//		Response to dojox/app "loadArray" event.
+			//
+			// example:
+			//		Use trigger() to trigger "loadArray" event, and this function will response the event. For example:
+			//		|	this.trigger("app-load", {"parent":parent, "viewId":viewId, "viewArray":viewArray, "callback":function(){...}});
+			//
+			// event: Object
+			//		LoadArray event parameter. It should be like this: {"parent":parent, "viewId":viewId, "viewArray":viewArray, "callback":function(){...}}
+			// returns:
+			//		A dojo/Deferred object.
+			//		The return value cannot return directly. 
+			//		If the caller need to use the return value, pass callback function in event parameter and process return value in callback function.
+
+			this.app.log("in app/controllers/Load event.viewId="+event.viewId+" event =", event);
+			var views = event.viewId || "";
+			var viewArray = [];
+			// create an array from the diff views in event.viewId (they are separated by +)
+			var parts = views.split('+');
+			while(parts.length > 0){ 	
+				var viewId = parts.shift();
+				viewArray.push(viewId);
+			}
+
+			var def;
+			this.proceedLoadViewDef = new Deferred();
+			if(viewArray && viewArray.length > 1){
+				// loop thru the array calling loadView for each item in the array
+				for(var i = 0; i < viewArray.length-1; i++){
+					var newEvent = lang.clone(event);
+					newEvent.callback = null;	// skip callback until after last view is loaded.
+					newEvent.viewId = viewArray[i];
+					this._waitingQueue.push(newEvent);
+				}
+				this.proceedLoadView(this._waitingQueue.shift());
+				when(this.proceedLoadViewDef, lang.hitch(this, function(){
+					// for last view leave the callback to be notified
+					var newEvent = lang.clone(event);
+					newEvent.viewId = viewArray[i];
+					def = this.loadView(newEvent);
+					return def;
+				}));
+			}else{
+				def = this.loadView(event);
+				return def;
+			}
+		},
+		
+		proceedLoadView: function(loadEvt){
+			// summary:
+			//		Proceed load queue by FIFO by default.
+			//		If load is in proceeding, add the next load to waiting queue.
+			//
+			// loadEvt: Object
+			//		LoadArray event parameter. It should be like this: {"parent":parent, "viewId":viewId, "viewArray":viewArray, "callback":function(){...}}
+
+			var def = this.loadView(loadEvt);
+			when(def, lang.hitch(this, function(){
+						this.app.log("in app/controllers/Load proceedLoadView back from loadView for event", loadEvt);
+						var nextEvt = this._waitingQueue.shift();
+						if(nextEvt){
+							this.app.log("in app/controllers/Load proceedLoadView back from loadView calling this.proceedLoadView(nextEvt) for ",nextEvt);
+							this.proceedLoadView(nextEvt);
+						}else{
+							this._waitingQueue = [];
+							this.proceedLoadViewDef.resolve();
+						}
+			}));
+		},
+
+		loadView: function(event){
+			// summary:
+			//		Response to dojox/app "app-load" event.
+			//
+			// example:
+			//		Use trigger() to trigger "app-load" event, and this function will response the event. For example:
+			//		|	this.trigger("app-load", {"parent":parent, "viewId":viewId, "callback":function(){...}});
+			//
+			// event: Object
+			//		Load event parameter. It should be like this: {"parent":parent, "viewId":viewId, "callback":function(){...}}
+			// returns:
+			//		A dojo/Deferred object.
+			//		The return value cannot return directly. 
+			//		If the caller need to use the return value, pass callback function in event parameter and process return value in callback function.
+
+			var parent = event.parent || this.app;
+			var viewId = event.viewId || "";
+			var parts = viewId.split(',');
+			var childId = parts.shift();
+			var subIds = parts.join(",");
+			var params = event.params || "";
+
+			var def = this.loadChild(parent, childId, subIds, params);
+			// call Load event callback
+			if(event.callback){
+				when(def, event.callback);
+			}
+			return def;
+		},
+
+		createChild: function(parent, childId, subIds, params){
+			// summary:
+			//		Create a view instance if not already loaded by calling createView. This is typically a
+			//		dojox/app/View.
+			//
+			// parent: Object
+			//		parent of the view.
+			// childId: String
+			//		view id need to be loaded.
+			// subIds: String
+			//		sub views' id of this view.
+			// returns:
+			//		If view exist, return the view object.
+			//		Otherwise, create the view and return a dojo.Deferred instance.
+
+			var id = parent.id + '_' + childId;
+			
+			// check for possible default params if no params were provided
+			if(!params && parent.views[childId].defaultParams){
+				params = parent.views[childId].defaultParams;
+			}
+			var view = parent.children[id];
+			if(view){
+				// set params to new value before returning
+				if(params){
+					view.params = params;
+				}
+				this.app.log("in app/controllers/Load createChild view is already loaded so return the loaded view with the new parms ",view);
+				return view;
+			}
+			var def = new Deferred();
+			// create and start child. return Deferred
+			when(this.createView(parent, id, childId, null, params, parent.views[childId].type), function(newView){
+				parent.children[id] = newView;
+				when(newView.start(), function(view){
+					def.resolve(view);
+				});
+			});
+			return def;
+		},
+
+		createView: function(parent, id, name, mixin, params, type){
+			// summary:
+			//		Create a dojox/app/View instance. Can be overridden to create different type of views.
+			// parent: Object
+			//		parent of this view.
+			// id: String
+			//		view id.
+			// name: String
+			//		view name.
+			// mixin: String
+			//		additional property to be mixed into the view (templateString, controller...)
+			// params: Object
+			//		params of this view.
+			// type: String
+			//		the MID of the View. If not provided "dojox/app/View".
+			// returns:
+			//		A dojo/Deferred instance which will be resolved when the view will be instantiated.
+			// tags:
+			//		protected
+			var def = new Deferred();
+			var app = this.app;
+			require([type?type:"../View"], function(View){
+				var newView = new View(lang.mixin({
+					"app": app,
+					"id": id,
+					"name": name,
+					"parent": parent
+				}, { "params": params }, mixin));
+				def.resolve(newView);
+			});
+			return def;
+		},
+
+		loadChild: function(parent, childId, subIds, params){
+			// summary:
+			//		Load child and sub children views recursively.
+			//
+			// parent: Object
+			//		parent of this view.
+			// childId: String
+			//		view id need to be loaded.
+			// subIds: String
+			//		sub views' id of this view.
+			// params: Object
+			//		params of this view.
+			// returns:
+			//		A dojo/Deferred instance which will be resolved when all views loaded.
+
+			//TODO: Can this be called with a viewId or default view which includes multiple views with a "+"?  Need to handle that!
+
+			if(!parent){
+				throw Error("No parent for Child '" + childId + "'.");
+			}
+
+			if(!childId){
+				var parts = parent.defaultView ? parent.defaultView.split(",") : "default";
+				childId = parts.shift();
+				subIds = parts.join(',');
+			}
+
+			var loadChildDeferred = new Deferred();
+			var createPromise;
+			try{
+				createPromise = this.createChild(parent, childId, subIds, params);
+			}catch(ex){
+				loadChildDeferred.reject("load child '"+childId+"' error.");
+				return loadChildDeferred.promise;
+			}
+			when(createPromise, lang.hitch(this, function(child){
+				// if no subIds and current view has default view, load the default view.
+				if(!subIds && child.defaultView){
+					subIds = child.defaultView;
+				}
+
+				var parts = subIds.split(',');
+				childId = parts.shift();
+				subIds = parts.join(',');
+				if(childId){
+					var subLoadDeferred = this.loadChild(child, childId, subIds, params);
+					when(subLoadDeferred, function(){
+						loadChildDeferred.resolve();
+					},
+					function(){
+						loadChildDeferred.reject("load child '"+childId+"' error.");
+					});
+				}else{
+					loadChildDeferred.resolve();
+				}
+			}),
+			function(){
+				loadChildDeferred.reject("load child '"+childId+"' error.")
+			});
+			return loadChildDeferred.promise; // dojo/Deferred.promise
+		}
+	});
+});
diff --git a/dojox/app/controllers/Transition.js b/dojox/app/controllers/Transition.js
new file mode 100755
index 0000000..6d623a8
--- /dev/null
+++ b/dojox/app/controllers/Transition.js
@@ -0,0 +1,430 @@
+define(["require", "dojo/_base/lang", "dojo/_base/declare", "dojo/has", "dojo/on", "dojo/Deferred", "dojo/when",
+	"dojo/dom-style", "../Controller", "../utils/constraints"],
+	function(require, lang, declare, has, on, Deferred, when, domStyle, Controller, constraints){
+
+	var transit;
+
+	// module:
+	//		dojox/app/controllers/transition
+	//		Bind "app-transition" event on dojox/app application instance.
+	//		Do transition from one view to another view.
+	return declare("dojox.app.controllers.Transition", Controller, {
+
+		proceeding: false,
+
+		waitingQueue:[],
+
+		constructor: function(app, events){
+			// summary:
+			//		bind "app-transition" event on application instance.
+			//
+			// app:
+			//		dojox/app application instance.
+			// events:
+			//		{event : handler}
+			this.events = {
+				"app-transition": this.transition,
+				"app-domNode": this.onDomNodeChange
+			};
+			require([this.app.transit || "dojox/css3/transit"], function(t){
+				transit = t;
+			});
+			if(this.app.domNode){
+				this.onDomNodeChange({oldNode: null, newNode: this.app.domNode});
+			}
+		},
+
+		transition: function(event){
+			// summary:
+			//		Response to dojox/app "app-transition" event.
+			//
+			// example:
+			//		Use emit to trigger "app-transition" event, and this function will response to the event. For example:
+			//		|	this.app.emit("app-transition", {"viewId": viewId, "opts": opts});
+			//
+			// event: Object
+			//		"app-transition" event parameter. It should be like this: {"viewId": viewId, "opts": opts}
+			
+			var viewsId = event.viewId || "";
+			this.proceedingSaved = this.proceeding;	
+			var parts = viewsId.split('+');
+			var viewId, newEvent;
+			if(parts.length > 0){
+				while(parts.length > 1){ 	
+					viewId = parts.shift();
+					newEvent = lang.clone(event);
+					newEvent.viewId = viewId;
+					this.proceeding = true;
+					this.proceedTransition(newEvent);					
+				}
+				viewId = parts.shift();
+				var removeParts = viewId.split('-');
+				if(removeParts.length > 0){
+					viewId = removeParts.shift();
+					while(removeParts.length > 0){ 	
+						var remViewId = removeParts.shift();
+						newEvent = lang.clone(event);
+						newEvent.viewId = remViewId;
+						this._doTransition(newEvent.viewId, newEvent.opts, newEvent.opts.params, event.opts.data, this.app, true, newEvent._doResize);
+					}
+				}
+				if(viewId.length > 0){ // check viewId.length > 0 to skip this section for a transition with only -viewId
+					this.proceeding = this.proceedingSaved;
+					event.viewId = viewId;	
+					event._doResize = true; // at the end of the last transition call resize
+					this.proceedTransition(event);
+				}
+			}else{
+				event._doResize = true; // at the end of the last transition call resize
+				this.proceedTransition(event);
+			}
+		},
+
+		onDomNodeChange: function(evt){
+			if(evt.oldNode != null){
+				this.unbind(evt.oldNode, "startTransition");
+			}
+			this.bind(evt.newNode, "startTransition", lang.hitch(this, this.onStartTransition));
+		},
+
+		onStartTransition: function(evt){
+			// summary:
+			//		Response to dojox/app "startTransition" event.
+			//
+			// example:
+			//		Use "dojox/mobile/TransitionEvent" to trigger "startTransition" event, and this function will response the event. For example:
+			//		|	var transOpts = {
+			//		|		title:"List",
+			//		|		target:"items,list",
+			//		|		url: "#items,list",
+			//		|		data: {}
+			//		|	};
+			//		|	new TransitionEvent(domNode, transOpts, e).dispatch();
+			//
+			// evt: Object
+			//		transition options parameter
+
+			// prevent event from bubbling to window and being
+			// processed by dojox/mobile/ViewController
+			if(evt.preventDefault){
+				evt.preventDefault();
+			}
+			evt.cancelBubble = true;
+			if(evt.stopPropagation){
+				evt.stopPropagation();
+			}
+
+			var target = evt.detail.target;
+			var regex = /#(.+)/;
+			if(!target && regex.test(evt.detail.href)){
+				target = evt.detail.href.match(regex)[1];
+			}
+
+			// transition to the target view
+			this.transition({ "viewId":target, opts: lang.mixin({}, evt.detail), data: evt.detail.data });
+		},
+
+		proceedTransition: function(transitionEvt){
+			// summary:
+			//		Proceed transition queue by FIFO by default.
+			//		If transition is in proceeding, add the next transition to waiting queue.
+			//
+			// transitionEvt: Object
+			//		"app-transition" event parameter. It should be like this: {"viewId":viewId, "opts":opts}
+
+			if(this.proceeding){
+				this.app.log("in app/controllers/Transition proceedTransition push event", transitionEvt);
+				this.waitingQueue.push(transitionEvt);
+				this.processingQueue = false;
+				return;
+			}
+			// If there are events waiting, needed to have the last in be the last processed, so add it to waitingQueue
+			// process the events in order.
+			if(this.waitingQueue.length > 0 && !this.processingQueue){
+				this.processingQueue = true;
+				this.waitingQueue.push(transitionEvt);
+				transitionEvt = this.waitingQueue.shift();	
+			}
+			
+			this.proceeding = true;
+
+			this.app.log("in app/controllers/Transition proceedTransition calling trigger load", transitionEvt);
+			if(!transitionEvt.opts){
+				transitionEvt.opts = {};
+			}
+			var params = transitionEvt.params || transitionEvt.opts.params;
+			this.app.emit("app-load", {
+				"viewId": transitionEvt.viewId,
+				"params": params,
+				"callback": lang.hitch(this, function(){
+					var transitionDef = this._doTransition(transitionEvt.viewId, transitionEvt.opts, params, transitionEvt.opts.data, this.app, false, transitionEvt._doResize);
+					when(transitionDef, lang.hitch(this, function(){
+						this.proceeding = false;
+						var nextEvt = this.waitingQueue.shift();
+						if(nextEvt){
+							this.proceedTransition(nextEvt);
+						}
+					}));
+				})
+			});
+		},
+
+		_getTransition: function(parent, transitionTo, opts){
+			// summary:
+			//		Get view's transition type from the config for the view or from the parent view recursively.
+			//		If not available use the transition option otherwise get view default transition type in the
+			//		config from parent view.
+			//
+			// parent: Object
+			//		view's parent
+			// transitionTo: Object
+			//		view to transition to
+			//	opts: Object
+			//		transition options
+			//
+			// returns:
+			//		transition type like "slide", "fade", "flip" or "none".
+			var parentView = parent;
+			var transition = null;
+			if(parentView.views[transitionTo]){
+				transition = parentView.views[transitionTo].transition;
+			} 
+			if(!transition){
+				transition = parentView.transition;
+			}
+			var defaultTransition = parentView.defaultTransition;
+			while(!transition && parentView.parent){
+				parentView = parentView.parent;
+				transition = parentView.transition;
+				if(!defaultTransition){
+					defaultTransition = parentView.defaultTransition;
+				}
+			}
+			return transition || opts.transition || defaultTransition || "none";
+		},
+
+
+		_getParamsForView: function(view, params){
+			// summary:
+			//		Get view's params only include view specific params if they are for this view.
+			//
+			// view: String
+			//		the view's name
+			// params: Object
+			//		the params
+			//
+			// returns:
+			//		params Object for this view
+			var viewParams = {};
+			for(var item in params){
+				var value = params[item];
+				if(lang.isObject(value)){	// view specific params
+					if(item == view){		// it is for this view
+						// need to add these params for the view
+						viewParams = lang.mixin(viewParams, value);
+					} 
+				}else{	// these params are for all views, so add them
+					if(item && value != null){
+						viewParams[item] = params[item];
+					}
+				}
+			}
+			return viewParams;
+		},
+
+		_doTransition: function(transitionTo, opts, params, data, parent, removeView, doResize, nested){
+			// summary:
+			//		Transitions from the currently visible scene to the defined scene.
+			//		It should determine what would be the best transition unless
+			//		an override in opts tells it to use a specific transitioning methodology
+			//		the transitionTo is a string in the form of [view]@[scene].  If
+			//		view is left of, the current scene will be transitioned to the default
+			//		view of the specified scene (eg @scene2), if the scene is left off
+			//		the app controller will instruct the active scene to the view (eg view1).  If both
+			//		are supplied (view1 at scene2), then the application should transition to the scene,
+			//		and instruct the scene to navigate to the view.
+			//
+			// transitionTo: Object
+			//		transition to view id. It looks like #tabScene,tab1
+			// opts: Object
+			//		transition options
+			// params: Object
+			//		params
+			// data: Object
+			//		data object that will be passed on activate & de-activate methods of the view
+			// parent: Object
+			//		view's parent
+			// removeView: Boolean
+			//		remove the view instead of transition to it
+			// doResize: Boolean
+			//		emit a resize event
+			// nested: Boolean
+			//		whether the method is called from the transitioning of a parent view
+			//
+			// returns:
+			//		transit dojo/promise/all object.
+
+			if(!parent){
+				throw Error("view parent not found in transition.");
+			}
+
+			this.app.log("in app/controllers/Transition._doTransition transitionTo=[",transitionTo,"], removeView = [",removeView,"] parent.name=[",parent.name,"], opts=",opts);
+
+			var parts, toId, subIds, next;
+			if(transitionTo){
+				parts = transitionTo.split(",");
+			}else{
+				// If parent.defaultView is like "main,main", we also need to split it and set the value to toId and subIds.
+				// Or cannot get the next view by "parent.children[parent.id + '_' + toId]"
+				parts = parent.defaultView.split(",");
+			}
+			toId = parts.shift();
+			subIds = parts.join(',');
+
+			// next is loaded and ready for transition
+			next = parent.children[parent.id + '_' + toId];
+			if(!next){
+				if(removeView){
+					this.app.log("> in Transition._doTransition called with removeView true, but that view is not available to remove");
+					return;	// trying to remove a view which is not showing
+				}
+				throw Error("child view must be loaded before transition.");
+			}
+
+			var current = constraints.getSelectedChild(parent, next.constraint);
+
+			// set params on next view.
+			next.params = this._getParamsForView(next.name, params);
+
+			// if no subIds and next has default view, 
+			// set the subIds to the default view and transition to default view.
+			if(!subIds && next.defaultView){
+				subIds = next.defaultView;
+			}
+
+			if(removeView){
+				if(next !== current){ // nothing to remove
+					this.app.log("> in Transition._doTransition called with removeView true, but that view is not available to remove");
+					return;	// trying to remove a view which is not showing
+				}	
+				// if next == current we will set next to null and remove the view with out a replacement
+				next = null;
+			}
+
+			// next is not a Deferred object, so Deferred.when is no needed.
+			if(next !== current){
+				//When clicking fast, history module will cache the transition request que
+				//and prevent the transition conflicts.
+				//Originally when we conduct transition, selectedChild will not be the
+				//view we want to start transition. For example, during transition 1 -> 2
+				//if user click button to transition to 3 and then transition to 1. After
+				//1->2 completes, it will perform transition 2 -> 3 and 2 -> 1 because
+				//selectedChild is always point to 2 during 1 -> 2 transition and transition
+				//will record 2->3 and 2->1 right after the button is clicked.
+
+				//assume next is already loaded so that this.set(...) will not return
+				//a promise object. this.set(...) will handles the this.selectedChild,
+				//activate or deactivate views and refresh layout.
+
+				// deactivate sub child of current view, then deactivate current view
+				var selChildren = constraints.getAllSelectedChildren(current);
+				for(var i = 0; i < selChildren.length; i++){					
+					var subChild = selChildren[i];
+					if(subChild && subChild.beforeDeactivate){ 
+						this.app.log("< in Transition._doTransition calling subChild.beforeDeactivate subChild name=[",subChild.name,"], parent.name=[",subChild.parent.name,"], next!==current path");
+						// TODO what to pass to beforeDeactivate here?
+						subChild.beforeDeactivate();
+					}
+				}
+				if(current){
+					this.app.log("< in Transition._doTransition calling current.beforeDeactivate current name=[",current.name,"], parent.name=[",current.parent.name,"], next!==current path");
+					current.beforeDeactivate(next, data);
+				}
+				if(next){
+					this.app.log("> in Transition._doTransition calling next.beforeActivate next name=[",next.name,"], parent.name=[",next.parent.name,"], next!==current path");
+					next.beforeActivate(current, data);
+				}
+				this.app.log("> in Transition._doTransition calling app.emit layoutView view next");
+				if(!removeView){
+					// if we are removing the view we must delay the layout to _after_ the animation
+					this.app.emit("app-layoutView", {"parent": parent, "view": next });
+				}
+				if(doResize && !subIds){
+					this.app.emit("app-resize"); // after last layoutView fire app-resize			
+				}
+				
+				var result = true;
+				if(transit && (!nested || current != null)){
+					// css3 transit has the check for IE so it will not try to do it on ie, so we do not need to check it here.
+					// We skip in we are transitioning to a nested view from a parent view and that nested view
+					// did not have any current
+					var mergedOpts = lang.mixin({}, opts); // handle reverse from mergedOpts or transitionDir
+					mergedOpts = lang.mixin({}, mergedOpts, {
+						reverse: (mergedOpts.reverse || mergedOpts.transitionDir === -1)?true:false,
+						// if transition is set for the view (or parent) in the config use it, otherwise use it from the event or defaultTransition from the config
+						transition: this._getTransition(parent, toId, mergedOpts)
+					});
+					if(next){
+						this.app.log("    > in Transition._doTransition calling transit for current ="+next.name);
+					}
+					result = transit(current && current.domNode, next && next.domNode, mergedOpts);
+				}
+				when(result, lang.hitch(this, function(){
+					if(next){
+						this.app.log("    < in Transition._doTransition back from transit for next ="+next.name);
+					}
+					if(removeView){
+						this.app.emit("app-layoutView", {"parent": parent, "view": current, "removeView": true});
+					}
+
+					// deactivate sub child of current view, then deactivate current view
+					var selChildren = constraints.getAllSelectedChildren(current);
+					for(var i = 0; i < selChildren.length; i++){					
+						var subChild = selChildren[i];
+						if(subChild && subChild.beforeDeactivate){ 
+							this.app.log("  < in Transition._doTransition calling subChild.afterDeactivate subChild name=[",subChild.name,"], parent.name=[",subChild.parent.name,"], next!==current path");
+							// TODO what  to pass to beforeDeactivate here?
+							subChild.afterDeactivate();
+						}
+					}
+					if(current){
+						this.app.log("  < in Transition._doTransition calling current.afterDeactivate current name=[",current.name,"], parent.name=[",current.parent.name,"], next!==current path");
+						current.afterDeactivate(next, data);
+					}
+					if(next){
+						this.app.log("  > in Transition._doTransition calling next.afterActivate next name=[",next.name,"], parent.name=[",next.parent.name,"], next!==current path");
+						next.afterActivate(current, data);
+					}
+
+					if(subIds){
+						this._doTransition(subIds, opts, params, data, next || parent, removeView, doResize, true);
+					}
+				}));
+				return result; // dojo/promise/all
+			}
+
+			// next view == current view, refresh current view
+			// deactivate next view
+			this.app.log("< in Transition._doTransition calling next.beforeDeactivate refresh current view next name=[",next.name,"], parent.name=[",next.parent.name,"], next==current path");
+			next.beforeDeactivate(current, data);
+			this.app.log("  < in Transition._doTransition calling next.afterDeactivate refresh current view next name=[",next.name,"], parent.name=[",next.parent.name,"], next==current path");
+			next.afterDeactivate(current, data);
+			// activate next view
+			this.app.log("> in Transition._doTransition calling next.beforeActivate next name=[",next.name,"], parent.name=[",next.parent.name,"], next==current path");
+			next.beforeActivate(current, data);
+			// layout current view, or remove it
+			this.app.log("> in Transition._doTransition calling app.triggger layoutView view next name=[",next.name,"], removeView = [",removeView,"], parent.name=[",next.parent.name,"], next==current path");
+			this.app.emit("app-layoutView", {"parent":parent, "view": next, "removeView": removeView});
+			if(doResize && !subIds){
+				this.app.emit("app-resize"); // after last layoutView fire app-resize
+			}
+			this.app.log("  > in Transition._doTransition calling next.afterActivate next name=[",next.name,"], parent.name=[",next.parent.name,"], next==current path");
+			next.afterActivate(current, data);
+
+			// do sub transition like transition from "tabScene,tab1" to "tabScene,tab2"
+			if(subIds){
+				return this._doTransition(subIds, opts, params, data, next, removeView); //dojo.DeferredList
+			}
+		}
+	});
+});
diff --git a/dojox/app/main.js b/dojox/app/main.js
old mode 100644
new mode 100755
index cc0880f..ceaae01
--- a/dojox/app/main.js
+++ b/dojox/app/main.js
@@ -1,115 +1,386 @@
-define(["dojo/_base/kernel",
-	"dojo/_base/lang",
-	"dojo/_base/declare",
-	"dojo/_base/Deferred",
-	"dojo/_base/connect",
-	"dojo/ready",
-	"dojo/_base/window",
-	"dojo/dom-construct",
-	"./scene"],
-	function(dojo, lang, declare, deferred, connect, ready, baseWindow, dom, sceneCtor){
-
-        dojo.experimental("dojox.app");
-	var Application = declare([sceneCtor], {
-		constructor: function(params){
-			this.scenes={};
+define(["require", "dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/config",
+	"dojo/_base/window", "dojo/Evented", "dojo/Deferred", "dojo/when", "dojo/has", "dojo/on", "dojo/ready",
+	"dojo/dom-construct", "dojo/dom-attr", "./utils/model", "./utils/nls", "./module/lifecycle",
+	"./utils/hash", "./utils/constraints", "./utils/config"],
+	function(require, kernel, lang, declare, config, win, Evented, Deferred, when, has, on, ready, domConstruct, domAttr,
+		 model, nls, lifecycle, hash, constraints, configUtils){
+
+	has.add("app-log-api", (config["app"] || {}).debugApp);
+
+	var Application = declare(Evented, {
+		constructor: function(params, node){
+			lang.mixin(this, params);
+			this.params = params;
+			this.id = params.id;
+			this.defaultView = params.defaultView;
+			this.controllers = [];
+			this.children = {};
+			this.loadedModels = {};
+			this.loadedStores = {};
+			// Create a new domNode and append to body
+			// Need to bind startTransition event on application domNode,
+			// Because dojox/mobile/ViewController bind startTransition event on document.body
+			// Make application's root domNode id unique because this id can be visited by window namespace on Chrome 18.
+			this.setDomNode(domConstruct.create("div", {
+				id: this.id+"_Root",
+				style: "width:100%; height:100%; overflow-y:hidden; overflow-x:hidden;"
+			}));
+			node.appendChild(this.domNode);
+		},
+
+		createDataStore: function(params){
+			// summary:
+			//		Create data store instance
+			//
+			// params: Object
+			//		data stores configuration.
+
 			if(params.stores){
-			    //create stores in the configuration.
-			    for (var item in params.stores){
-			        if(item.charAt(0)!=="_"){//skip the private properties
-			            var type = params.stores[item].type? params.stores[item].type : "dojo.store.Memory";
-			            var config = {};
-			            if(params.stores[item].params){
-			                dojo.mixin(config, params.stores[item].params);
-			            }
-			            var storeCtor = dojo.getObject(type);
-			            if(config.data && lang.isString(config.data)){
-			                //get the object specified by string value of data property
-			                //cannot assign object literal or reference to data property
-			                //because json.ref will generate __parent to point to its parent
-			                //and will cause infinitive loop when creating StatefulModel.
-			                config.data = dojo.getObject(config.data);
-			            }
-			            params.stores[item].store = new storeCtor(config);
-			        }
-			    }
+				//create stores in the configuration.
+				for(var item in params.stores){
+					if(item.charAt(0) !== "_"){//skip the private properties
+						var type = params.stores[item].type ? params.stores[item].type : "dojo/store/Memory";
+						var config = {};
+						if(params.stores[item].params){
+							lang.mixin(config, params.stores[item].params);
+						}
+						// we assume the store is here through dependencies
+						try{
+							var storeCtor = require(type);
+						}catch(e){
+							throw new Error(type+" must be listed in the dependencies");
+						}
+						if(config.data && lang.isString(config.data)){
+							//get the object specified by string value of data property
+							//cannot assign object literal or reference to data property
+							//because json.ref will generate __parent to point to its parent
+							//and will cause infinitive loop when creating StatefulModel.
+							config.data = lang.getObject(config.data);
+						}
+						if(params.stores[item].observable){
+							try{
+								var observableCtor = require("dojo/store/Observable");
+							}catch(e){
+								throw new Error("dojo/store/Observable must be listed in the dependencies");
+							}
+							params.stores[item].store = observableCtor(new storeCtor(config));
+						}else{
+							params.stores[item].store = new storeCtor(config);
+						}
+						this.loadedStores[item] = params.stores[item].store;							
+					}
+				}
 			}
+		},
+
+		createControllers: function(controllers){
+			// summary:
+			//		Create controller instance
+			//
+			// controllers: Array
+			//		controller configuration array.
+			// returns:
+			//		controllerDeferred object
+
+			if(controllers){
+				var requireItems = [];
+				for(var i = 0; i < controllers.length; i++){
+					requireItems.push(controllers[i]);
+				}
 
+				var def = new Deferred();
+				var requireSignal;
+				try{
+					requireSignal = require.on("error", function(error){
+						if(def.isResolved() || def.isRejected()){
+							return;
+						}
+						def.reject("load controllers error.");
+						requireSignal.remove();
+					});
+					require(requireItems, function(){
+						def.resolve.call(def, arguments);
+						requireSignal.remove();
+					});
+				}catch(e){
+					def.reject(e);
+					if(requireSignal){
+						requireSignal.remove();
+					}
+				}
+
+				var controllerDef = new Deferred();
+				when(def, lang.hitch(this, function(){
+					for(var i = 0; i < arguments[0].length; i++){
+						// instantiate controllers, set Application object, and perform auto binding
+						this.controllers.push((new arguments[0][i](this)).bind());
+					}
+					controllerDef.resolve(this);
+				}), function(){
+					//require def error, reject loadChildDeferred
+					controllerDef.reject("load controllers error.");
+				});
+				return controllerDef;
+			}
 		},
 
-		// load default view and startup the default view
-        start: function(applicaton){
-            var child = this.loadChild();
-
-            deferred.when(child, dojo.hitch(this, function(){
-                this.startup();
-
-                //set application status to STARTED
-                this.setStatus(this.lifecycle.STARTED);
-            }));
-        },
-		templateString: "<div></div>",
-		selectedChild: null,
-		baseClass: "application mblView",
-		defaultViewType: sceneCtor,
-		buildRendering: function(){
-			if (this.srcNodeRef===baseWindow.body()){
-				this.srcNodeRef = dom.create("DIV",{},baseWindow.body());
+		trigger: function(event, params){
+			// summary:
+			//		trigger an event. Deprecated, use emit instead.
+			//
+			// event: String
+			//		event name. The event is binded by controller.bind() method.
+			// params: Object
+			//		event params.
+			kernel.deprecated("dojox.app.Application.trigger", "Use dojox.app.Application.emit instead", "2.0");
+			this.emit(event, params);
+		},
+
+		// setup default view and Controllers and startup the default view
+		start: function(){
+			//
+			//create application level data store
+			this.createDataStore(this.params);
+
+			// create application level data model
+			var loadModelLoaderDeferred = new Deferred();
+			var createPromise;
+			try{
+				createPromise = model(this.params.models, this, this);
+			}catch(e){
+				loadModelLoaderDeferred.reject(e);
+				return loadModelLoaderDeferred.promise;
 			}
-			this.inherited(arguments);
-		}
+			when(createPromise, lang.hitch(this, function(models){
+				// if models is an array it comes from dojo/promise/all. Each array slot contains the same result object
+				// so pick slot 0.
+				this.loadedModels = lang.isArray(models)?models[0]:models;
+				this.setupControllers();
+				// if available load root NLS
+				when(nls(this.params), lang.hitch(this, function(nls){
+					if(nls){
+						lang.mixin(this.nls = {}, nls);
+					}
+					this.startup();
+				}));
+			}), function(){
+				loadModelLoaderDeferred.reject("load model error.")
+			});
+		},
+
+		setDomNode: function(domNode){
+			var oldNode = this.domNode;
+			this.domNode = domNode;
+			this.emit("app-domNode", {
+				oldNode: oldNode,
+				newNode: domNode
+			});
+		},
+
+		setupControllers: function(){
+			// create application controller instance
+			// move set _startView operation from history module to application
+			var currentHash = window.location.hash;
+		//	this._startView = (((currentHash && currentHash.charAt(0) == "#") ? currentHash.substr(1) : currentHash) || this.defaultView).split('&')[0];
+			this._startView = hash.getTarget(currentHash, this.defaultView);
+			this._startParams = hash.getParams(currentHash);
+		},
+
+		startup: function(){
+			// load controllers and views
+			//
+			this.selectedChildren = {};			
+			var controllers = this.createControllers(this.params.controllers);
+			// constraint on app
+			if(this.hasOwnProperty("constraint")){
+				constraints.register(this.params.constraints);
+			}else{
+				this.constraint = "center";
+			}
+			var emitLoad = function(){
+				// emit "app-load" event and let controller to load view.
+				this.emit("app-load", {
+					viewId: this.defaultView,
+					params: this._startParams,
+					callback: lang.hitch(this, function (){
+						var parts = this.defaultView.split('+'), selectId, constraint;
+						// TODO all this code should be moved to a controller, there is no reason to do that here
+						// for initial view and somewhere else for the rest
+						if(parts.length > 0){		
+							while(parts.length > 0){ 	
+								var viewId = parts.shift();
+								selectId = viewId.split(",").shift();
+								// set the constraint
+								if(!this.children[this.id + "_" + selectId].hasOwnProperty("constraint")){
+									this.children[this.id + '_' + selectId].constraint = domAttr.get(this.children[this.id + '_' + selectId].domNode, "data-app-constraint") || "center";
+								}
+								constraints.register(constraint = this.children[this.id + '_' + selectId].constraint);
+								constraints.setSelectedChild(this, constraint, this.children[this.id + '_' + selectId]);
+							}
+						}else{
+							var selectId = this.defaultView.split(",").shift();
+							// set the constraint
+							if(!this.children[this.id + "_" + selectId].hasOwnProperty("constraint")){
+								this.children[this.id + '_' + selectId].constraint = domAttr.get(this.children[this.id + '_' + selectId].domNode, "data-app-constraint") || "center";
+							}
+							constraints.register(constraint = this.children[this.id + '_' + selectId].constraint);
+							constraints.setSelectedChild(this, constraint, this.children[this.id + '_' + selectId]);
+						}
+						// transition to startView. If startView==defaultView, that means initial the default view.
+						this.emit("app-transition", {
+							viewId: this._startView,
+							opts: { params: this._startParams }
+						});
+						this.setStatus(this.lifecycle.STARTED);
+					})
+				});
+			};
+			when(controllers, lang.hitch(this, function(){
+				if(this.template){
+					// emit "app-init" event so that the Load controller can initialize root view
+					this.emit("app-init", {
+						app: this,	// pass the app into the View so it can have easy access to app
+						name: this.name,
+						type: this.type,
+						parent: this,
+						templateString: this.templateString,
+						controller: this.controller,
+						callback: lang.hitch(this, function(view){
+							this.setDomNode(view.domNode);
+							emitLoad.call(this);
+						})
+					});
+				}else{
+					emitLoad.call(this);
+				}
+			}));
+		}		
 	});
-	
-	function generateApp(config,node,appSchema,validate){
 
-		//console.log("config.modules: ", config.modules);
-		var modules = config.modules.concat(config.dependencies);
+	function generateApp(config, node){
+		// summary:
+		//		generate the application
+		//
+		// config: Object
+		//		app config
+		// node: domNode
+		//		domNode.
+		var path;
+
+		// call configProcessHas to process any has blocks in the config
+		config = configUtils.configProcessHas(config);
+
+		if(!config.loaderConfig){
+			config.loaderConfig = {};
+		}
+		if(!config.loaderConfig.paths){
+			config.loaderConfig.paths = {};
+		}
+		if(!config.loaderConfig.paths["app"]){
+			// Register application module path
+			path = window.location.pathname;
+			if(path.charAt(path.length) != "/"){
+				path = path.split("/");
+				path.pop();
+				path = path.join("/");
+			}
+			config.loaderConfig.paths["app"] = path;
+		}
+		require(config.loaderConfig);
+
+		if(!config.modules){
+			config.modules = [];
+		}
+		// add dojox/app lifecycle module by default
+		config.modules.push("./module/lifecycle");
+		var modules = config.modules.concat(config.dependencies?config.dependencies:[]);
 
-		if (config.template){
-			//console.log("config.template: ", config.template);
-			modules.push("dojo/text!" + "app/" + config.template);
+		if(config.template){
+			path = config.template;
+			if(path.indexOf("./") == 0){
+				path = "app/"+path;
+			}
+			modules.push("dojo/text!" + path);
 		}
-		//console.log("modules: ", modules);	
 
 		require(modules, function(){
-			var modules=[Application];
-			for(var i=0;i<config.modules.length;i++){
+			var modules = [Application];
+			for(var i = 0; i < config.modules.length; i++){
 				modules.push(arguments[i]);
 			}
 
-			if (config.template){
+			if(config.template){
 				var ext = {
-					templateString: arguments[arguments.length-1] 
-				}	
+					templateString: arguments[arguments.length - 1]
+				}
 			}
-			App = declare(modules,ext);
+			App = declare(modules, ext);
 
 			ready(function(){
-				app = App(config,node || baseWindow.body());
-                app.setStatus(app.lifecycle.STARTING);
-                app.start();
+				var app = new App(config, node || win.body());
+
+				if(has("app-log-api")){
+					app.log = function(){
+						// summary:
+						//		If config is set to turn on app logging, then log msg to the console
+						//
+						// arguments: 
+						//		the message to be logged, 
+						//		all but the last argument will be treated as Strings and be concatenated together, 
+						//      the last argument can be an object it will be added as an argument to the console.log 						
+						var msg = "";
+						try{
+							for(var i = 0; i < arguments.length-1; i++){
+								msg = msg + arguments[i];
+							}
+							console.log(msg,arguments[arguments.length-1]);
+						}catch(e){}
+					};
+				}else{
+					app.log = function(){}; // noop
+				}
+
+				app.transitionToView = function(/*DomNode*/target, /*Object*/transitionOptions, /*Event?*/triggerEvent){
+					// summary:
+					//		A convenience function to fire the transition event to transition to the view.
+					//
+					// target:
+					//		The DOM node that initiates the transition (for example a ListItem).
+					// transitionOptions:
+					//		Contains the transition options.
+					// triggerEvent:
+					//		The event that triggered the transition (for example a touch event on a ListItem).
+					var opts = {bubbles:true, cancelable:true, detail: transitionOptions, triggerEvent: triggerEvent||null};	
+					on.emit(target,"startTransition", opts);
+				};
+
+				app.setStatus(app.lifecycle.STARTING);
+				// Create global namespace for application.
+				// The global name is application id. For example: modelApp
+				var globalAppName = app.id;
+				if(window[globalAppName]){
+					lang.mixin(app, window[globalAppName]);
+				}
+				window[globalAppName] = app;
+				app.start();
 			});
 		});
 	}
 
-
-	return function(config,node){
-		if (!config){
-			throw Error("App Config Missing");
+	return function(config, node){
+		if(!config){
+			throw new Error("App Config Missing");
 		}
 
-		
-		if (config.validate){
-			require(["dojox/json/schema","dojox/json/ref","dojo/text!dojox/application/schema/application.json"],function(schema,appSchema){
-				schema = dojox.json.ref.resolveJson(schema);	
-				if (schema.validate(config,appSchema)){
-					generateApp(config,node);
-				}	
+		if(config.validate){
+			require(["dojox/json/schema", "dojox/json/ref", "dojo/text!dojox/application/schema/application.json"], function(schema, appSchema){
+				schema = dojox.json.ref.resolveJson(schema);
+				if(schema.validate(config, appSchema)){
+					generateApp(config, node);
+				}
 			});
-		
-
 		}else{
-			generateApp(config,node);
+			generateApp(config, node);
 		}
 	}
 });
diff --git a/dojox/app/model.js b/dojox/app/model.js
deleted file mode 100644
index db5fbfd..0000000
--- a/dojox/app/model.js
+++ /dev/null
@@ -1,26 +0,0 @@
-define(["dojo/_base/kernel","dojo/_base/Deferred","dojox/mvc/StatefulModel"], function(dojo,deferred){
-	return function(config, parent){
-                //load models here. create dojox.newStatefulModel 
-                //using the configuration data for models
-	        var loadedModels = {};
-	        if(parent){
-	            dojo.mixin(loadedModels, parent);
-	        }
-	        if(config){
-                    for(var item in config){
-                        if(item.charAt(0)!=="_"){
-                            var params = config[item].params ? config[item].params:{};
-                            var options = {
-                                "store": params.store.store,
-                                "query": params.store.query ? params.store.query : {}
-                            };
-                            
-                            //TODO improve performance of loading at here
-                            // do not wait for the models to be created.
-                            loadedModels[item] = deferred.when(dojox.mvc.newStatefulModel(options), function(model){return model});
-                        }
-                    }
-	        }
-                return loadedModels;
-	}
-});
diff --git a/dojox/app/module/history.js b/dojox/app/module/history.js
deleted file mode 100644
index 09e754c..0000000
--- a/dojox/app/module/history.js
+++ /dev/null
@@ -1,90 +0,0 @@
-define(["dojo/_base/kernel","dojo/_base/lang", "dojo/_base/declare", "dojo/on"],function(dojo,dlang,declare,listen){
-	return declare(null, {
-		postCreate: function(params,node){
-			this.inherited(arguments);
-			var hash=window.location.hash;
-			this._startView= ((hash && hash.charAt(0)=="#")?hash.substr(1):hash)||this.defaultView;
-
-			listen(this.domNode, "startTransition", dojo.hitch(this, "onStartTransition"));
-			listen(window,"popstate", dojo.hitch(this, "onPopState"));
-		},
-		startup: function(){
-			this.inherited(arguments);
-		},
-
-		onStartTransition: function(evt){
-			console.log("onStartTransition", evt.detail.href, history.state);
-			if (evt.preventDefault){
-				evt.preventDefault();
-			}
-
-			var target = evt.detail.target;
-			var regex = /#(.+)/;
-			if(!target && regex.test(evt.detail.href)){
-				target = evt.detail.href.match(regex)[1];
-			}
-			
-			//prevent event from bubbling to window and being
-			//processed by dojox/mobile/ViewController
-			evt.cancelBubble = true;
-			if(evt.stopPropagation){
-			    evt.stopPropagation();
-			}
-			
-			dojo.when(this.transition(target, dojo.mixin({reverse: false},evt.detail)), dojo.hitch(this, function(){
-				history.pushState(evt.detail,evt.detail.href, evt.detail.url);
-			}))
-	
-		},
-
-		/*
-		onHashChange: function(evt){
-			var target = window.location.hash.substr(1);;
-			var evt = {target: window.location.hash, url: "#" + target,title:null};
-			//this.onStartTransition(evt);
-		},
-		*/
-
-		onPopState: function(evt){
-			// Check application status, if application status not STARTED, do nothing.
-			// when clean browser's cache then refresh the current page, it will trigger popState event. 
-			// but the application not start, it will throw an error.
-			if(this.getStatus() !== this.lifecycle.STARTED ){
-				return;
-			}
-			var state = evt.state;
-			if (!state){
-
-				if(!this._startView && window.location.hash){
-					state={
-						target: (location.hash && location.hash.charAt(0)=="#")?location.hash.substr(1):location.hash,
-						url: location.hash
-					}		
-				}else{
-					state={};	
-				}
-			}
-
-			var target = state.target || this._startView || this.defaultView;
-
-			if (this._startView){
-				this._startView=null;
-			}
-			var title = state.title||null;
-			var href = state.url || null;
-
-			if (evt._sim) {
-				history.replaceState(state, title, href );
-			}
-
-			/*
-			dojo.when(this.transition(window.history.state, {rev: true}), dojo.hitch(this, function(){
-
-				console.log('done transition from onPopState');
-			}))
-			*/
-			var currentState = history.state;
-			this.transition(target, dojo.mixin({reverse: true},state));	
-		}
-	});	
-});
diff --git a/dojox/app/module/lifecycle.js b/dojox/app/module/lifecycle.js
old mode 100644
new mode 100755
index 8029baf..5f6fc63
--- a/dojox/app/module/lifecycle.js
+++ b/dojox/app/module/lifecycle.js
@@ -1,26 +1,26 @@
-define(["dojo/_base/declare", "dojo/_base/connect"], function(declare, connect){
-    return declare(null, {
-    
-        lifecycle: {
-            UNKNOWN: 0, //unknown
-            STARTING: 1, //starting
-            STARTED: 2, //started
-            STOPPING: 3, //stopping
-            STOPPED: 4 //stopped
-        },
-        
-        _status: 0, //unknown
-        
-        getStatus: function(){
-            return this._status;
-        },
-        
-        setStatus: function(newStatus){
-            this._status = newStatus;
-            
-            // publish /app/stauts event.
-            // application can subscribe this event to do some status change operation.
-            connect.publish("/app/status", [newStatus]);
-        }
-    });
+define(["dojo/_base/declare", "dojo/topic"], function(declare, topic){
+	return declare(null, {
+
+		lifecycle: {
+			UNKNOWN: 0, //unknown
+			STARTING: 1, //starting
+			STARTED: 2, //started
+			STOPPING: 3, //stopping
+			STOPPED: 4 //stopped
+		},
+
+		_status: 0, //unknown
+
+		getStatus: function(){
+			return this._status;
+		},
+
+		setStatus: function(newStatus){
+			this._status = newStatus;
+
+			// publish /app/status event.
+			// application can subscribe this event to do some status change operation.
+			topic.publish("/app/status", newStatus);
+		}
+	});
 });
diff --git a/dojox/app/scene.js b/dojox/app/scene.js
deleted file mode 100644
index 76d3afd..0000000
--- a/dojox/app/scene.js
+++ /dev/null
@@ -1,588 +0,0 @@
-define(["dojo/_base/kernel",
-	"dojo/_base/declare",
-	"dojo/_base/connect",
-	"dojo/_base/array",
-	"dojo/_base/Deferred",
-	"dojo/_base/lang",
-	"dojo/_base/sniff",
-	"dojo/dom-style",
-	"dojo/dom-geometry",
-	"dojo/dom-class",
-	"dojo/dom-construct",
-	"dojo/dom-attr",
-	"dojo/query",
-	"dijit",
-	"dojox",
-	"dijit/_WidgetBase",
-	"dijit/_TemplatedMixin",
-	"dijit/_WidgetsInTemplateMixin",
-	"dojox/css3/transit", 
-	"./animation",
-	"./model", 
-	"./view", 
-	"./bind"], 
-	function(dojo,declare,connect, array,deferred,dlang,has,dstyle,dgeometry,cls,dconstruct,dattr,query,dijit,dojox,WidgetBase,Templated,WidgetsInTemplate,transit, anim, model, baseView, bind){
-	
-	var marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
-		// summary:
-		//		Given the margin-box size of a node, return its content box size.
-		//		Functions like dojo.contentBox() but is more reliable since it doesn't have
-		//		to wait for the browser to compute sizes.
-		var cs = dstyle.getComputedStyle(node);
-		var me = dgeometry.getMarginExtents(node, cs);
-		var pb = dgeometry.getPadBorderExtents(node, cs);
-		return {
-			l: dstyle.toPixelValue(node, cs.paddingLeft),
-			t: dstyle.toPixelValue(node, cs.paddingTop),
-			w: mb.w - (me.w + pb.w),
-			h: mb.h - (me.h + pb.h)
-		};
-	};
-
-	var capitalize = function(word){
-		return word.substring(0,1).toUpperCase() + word.substring(1);
-	};
-
-	var size = function(widget, dim){
-		// size the child
-		var newSize = widget.resize ? widget.resize(dim) : dgeometry.setMarginBox(widget.domNode, dim);
-		// record child's size
-		if(newSize){
-			// if the child returned it's new size then use that
-			dojo.mixin(widget, newSize);
-		}else{
-			// otherwise, call marginBox(), but favor our own numbers when we have them.
-			// the browser lies sometimes
-			dojo.mixin(widget, dgeometry.getMarginBox(widget.domNode));
-
-			dojo.mixin(widget, dim);
-		}
-	};
-
-	return declare("dojox.app.scene", [dijit._WidgetBase, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
-		isContainer: true,
-		widgetsInTemplate: true,
-		defaultView: "default",
-
-		selectedChild: null,
-		baseClass: "scene mblView",
-		isFullScreen: false,
-		defaultViewType: baseView,
-		
-		//Temporary work around for getting a null when calling getParent
-		getParent: function(){return null;},
-
-
-		constructor: function(params,node){
-			this.children={};
-			if(params.parent){
-				this.parent=params.parent
-			}
-			if(params.app){
-				this.app = params.app;
-			}
-		},
-
-		buildRendering: function(){
-			this.inherited(arguments);
-			dstyle.set(this.domNode, {width: "100%", "height": "100%"});
-			cls.add(this.domNode,"dijitContainer");
-		},
-
-		splitChildRef: function(childId){
-			var id = childId.split(",");
-			if (id.length>0){
-				var to = id.shift();
-			}else{
-				console.warn("invalid child id passed to splitChildRef(): ", childId);
-			}
-
-			return {
-				id:to || this.defaultView,
-				next: id.join(',') 
-			}
-		},
-
-		loadChild: function(childId,subIds){
-			// if no childId, load the default view
-            if (!childId) {
-                var parts = this.defaultView ? this.defaultView.split(",") : "default";
-                childId = parts.shift();
-                subIds = parts.join(',');
-            }
-
-			var cid = this.id+"_" + childId;
-			if (this.children[cid]){
-				return this.children[cid];
-			}
-
-			if (this.views&& this.views[childId]){
-				var conf = this.views[childId];
-				if (!conf.dependencies){conf.dependencies=[];}
-				var deps = conf.template? conf.dependencies.concat(["dojo/text!app/"+conf.template]) :
-						conf.dependencies.concat([]);
-			
-				var def = new deferred();
-				if (deps.length>0) {
-					require(deps,function(){
-						def.resolve.call(def, arguments);			
-					});
-				}else{
-					def.resolve(true);
-				}
-		
-			   var loadChildDeferred = new deferred();
-			   var self = this;
-				deferred.when(def, function(){
-					var ctor;
-					if (conf.type){
-						ctor=dojo.getObject(conf.type);
-					}else if (self.defaultViewType){
-						ctor=self.defaultViewType;
-					}else{
-						throw Error("Unable to find appropriate ctor for the base child class");
-					}
-
-					var params = dojo.mixin({}, conf, {
-						id: self.id + "_" + childId,
-						templateString: conf.template?arguments[0][arguments[0].length-1]:"<div></div>",
-						parent: self,
-						app: self.app
-					}) 
-					if (subIds){
-						params.defaultView=subIds;
-					}
-                    var child = new ctor(params);
-                    //load child's model if it is not loaded before
-                    if(!child.loadedModels){
-                        child.loadedModels = model(conf.models, self.loadedModels)
-                        //TODO need to find out a better way to get all bindable controls in a view
-                        bind([child], child.loadedModels);
-                    }
-					var addResult = self.addChild(child);
-					//publish /app/loadchild event
-					//application can subscript this event to do user define operation like select TabBarButton, add dynamic script text etc.
-					connect.publish("/app/loadchild", [child]);
-
-                 var promise;
-
-                 subIds = subIds.split(',');
-                 if ((subIds[0].length > 0) && (subIds.length > 1)) {//TODO join subIds
-                     promise = child.loadChild(subIds[0], subIds[1]);
-                 }
-                 else 
-                     if (subIds[0].length > 0) {
-                         promise = child.loadChild(subIds[0], "");
-                     }
-                 
-                 dojo.when(promise, function(){
-                     loadChildDeferred.resolve(addResult)
-                 });
-				});
-              return loadChildDeferred;
-			}
-	
-			throw Error("Child '" + childId + "' not found.");
-		},
-
-		resize: function(changeSize,resultSize){
-			var node = this.domNode;
-
-			// set margin box size, unless it wasn't specified, in which case use current size
-			if(changeSize){
-				dgeometry.setMarginBox(node, changeSize);
-
-				// set offset of the node
-				if(changeSize.t){ node.style.top = changeSize.t + "px"; }
-				if(changeSize.l){ node.style.left = changeSize.l + "px"; }
-			}
-
-			// If either height or width wasn't specified by the user, then query node for it.
-			// But note that setting the margin box and then immediately querying dimensions may return
-			// inaccurate results, so try not to depend on it.
-			var mb = resultSize || {};
-			dojo.mixin(mb, changeSize || {});	// changeSize overrides resultSize
-			if( !("h" in mb) || !("w" in mb) ){
-				mb = dojo.mixin(dgeometry.getMarginBox(node), mb);	// just use dojo.marginBox() to fill in missing values
-			}
-
-			// Compute and save the size of my border box and content box
-			// (w/out calling dojo.contentBox() since that may fail if size was recently set)
-			var cs = dstyle.getComputedStyle(node);
-			var me = dgeometry.getMarginExtents(node, cs);
-			var be = dgeometry.getBorderExtents(node, cs);
-			var bb = (this._borderBox = {
-				w: mb.w - (me.w + be.w),
-				h: mb.h - (me.h + be.h)
-			});
-			var pe = dgeometry.getPadExtents(node, cs);
-			this._contentBox = {
-				l: dstyle.toPixelValue(node, cs.paddingLeft),
-				t: dstyle.toPixelValue(node, cs.paddingTop),
-				w: bb.w - pe.w,
-				h: bb.h - pe.h
-			};
-
-			// Callback for widget to adjust size of its children
-			this.layout();
-		},
-
-		layout: function(){
-			var fullScreenScene,children,hasCenter;
-			//console.log("fullscreen: ", this.selectedChild && this.selectedChild.isFullScreen);
-			if (this.selectedChild && this.selectedChild.isFullScreen) {
-				console.warn("fullscreen sceen layout");
-				/*
-				fullScreenScene=true;		
-				children=[{domNode: this.selectedChild.domNode,region: "center"}];
-				dojo.query("> [region]",this.domNode).forEach(function(c){
-					if(this.selectedChild.domNode!==c.domNode){
-						dojo.style(c.domNode,"display","none");
-					}
-				})
-				*/
-			}else{
-				children = query("> [region]", this.domNode).map(function(node){
-					var w = dijit.getEnclosingWidget(node);
-					if (w){return w;}
-
-					return {		
-						domNode: node,
-						region: dattr.get(node,"region")
-					}
-						
-				});
-				if (this.selectedChild){
-					children = array.filter(children, function(c){
-						if (c.region=="center" && this.selectedChild && this.selectedChild.domNode!==c.domNode){
-							dstyle.set(c.domNode,"zIndex",25);
-							dstyle.set(c.domNode,'display','none');
-							return false;
-						}else if (c.region!="center"){
-							dstyle.set(c.domNode,"display","");
-							dstyle.set(c.domNode,"zIndex",100);
-						}
-					
-						return c.domNode && c.region;
-					},this);
-
-				//	this.selectedChild.region="center";	
-				//	dojo.attr(this.selectedChild.domNode,"region","center");
-				//	dojo.style(this.selectedChild.domNode, "display","");
-				//	dojo.style(this.selectedChild.domNode,"zIndex",50);
-
-				//	children.push({domNode: this.selectedChild.domNode, region: "center"});	
-				//	children.push(this.selectedChild);
-				//	console.log("children: ", children);
-				}else{
-					array.forEach(children, function(c){
-						if (c && c.domNode && c.region=="center"){
-							dstyle.set(c.domNode,"zIndex",25);
-							dstyle.set(c.domNode,'display','none');
-						}	
-					});
-				}
-			
-			}	
-			// We don't need to layout children if this._contentBox is null for the operation will do nothing.
-			if (this._contentBox) {
-				this.layoutChildren(this.domNode, this._contentBox, children);
-			}
-			array.forEach(this.getChildren(), function(child){ 
-				if (!child._started && child.startup){
-					child.startup(); 
-				}
-
-			});
-
-		},
-
-
-		layoutChildren: function(/*DomNode*/ container, /*Object*/ dim, /*Widget[]*/ children,
-			/*String?*/ changedRegionId, /*Number?*/ changedRegionSize){
-			// summary
-			//		Layout a bunch of child dom nodes within a parent dom node
-			// container:
-			//		parent node
-			// dim:
-			//		{l, t, w, h} object specifying dimensions of container into which to place children
-			// children:
-			//		an array of Widgets or at least objects containing:
-			//			* domNode: pointer to DOM node to position
-			//			* region or layoutAlign: position to place DOM node
-			//			* resize(): (optional) method to set size of node
-			//			* id: (optional) Id of widgets, referenced from resize object, below.
-			// changedRegionId:
-			//		If specified, the slider for the region with the specified id has been dragged, and thus
-			//		the region's height or width should be adjusted according to changedRegionSize
-			// changedRegionSize:
-			//		See changedRegionId.
-	
-			// copy dim because we are going to modify it
-			dim = dojo.mixin({}, dim);
-	
-			cls.add(container, "dijitLayoutContainer");
-	
-			// Move "client" elements to the end of the array for layout.  a11y dictates that the author
-			// needs to be able to put them in the document in tab-order, but this algorithm requires that
-			// client be last.    TODO: move these lines to LayoutContainer?   Unneeded other places I think.
-			children = array.filter(children, function(item){ return item.region != "center" && item.layoutAlign != "client"; })
-				.concat(array.filter(children, function(item){ return item.region == "center" || item.layoutAlign == "client"; }));
-	
-			// set positions/sizes
-			array.forEach(children, function(child){
-				var elm = child.domNode,
-					pos = (child.region || child.layoutAlign);
-	
-				// set elem to upper left corner of unused space; may move it later
-				var elmStyle = elm.style;
-				elmStyle.left = dim.l+"px";
-				elmStyle.top = dim.t+"px";
-				elmStyle.position = "absolute";
-	
-				cls.add(elm, "dijitAlign" + capitalize(pos));
-	
-				// Size adjustments to make to this child widget
-				var sizeSetting = {};
-	
-				// Check for optional size adjustment due to splitter drag (height adjustment for top/bottom align
-				// panes and width adjustment for left/right align panes.
-				if(changedRegionId && changedRegionId == child.id){
-					sizeSetting[child.region == "top" || child.region == "bottom" ? "h" : "w"] = changedRegionSize;
-				}
-	
-				// set size && adjust record of remaining space.
-				// note that setting the width of a <div> may affect its height.
-				if(pos == "top" || pos == "bottom"){
-					sizeSetting.w = dim.w;
-					size(child, sizeSetting);
-					dim.h -= child.h;
-					if(pos == "top"){
-						dim.t += child.h;
-					}else{
-						elmStyle.top = dim.t + dim.h + "px";
-					}
-				}else if(pos == "left" || pos == "right"){
-					sizeSetting.h = dim.h;
-					size(child, sizeSetting);
-					dim.w -= child.w;
-					if(pos == "left"){
-						dim.l += child.w;
-					}else{
-						elmStyle.left = dim.l + dim.w + "px";
-					}
-				}else if(pos == "client" || pos == "center"){
-					size(child, dim);
-				}
-			});
-		},
-
-		getChildren: function(){
-			return this._supportingWidgets;
-		},
-
-		startup: function(){
-			if(this._started){ return; }
-			this._started=true;
-
-			var parts = this.defaultView?this.defaultView.split(","):"default";
-			var toId, subIds;
-			toId= parts.shift();
-			subIds = parts.join(',');
-
-			if(this.views[this.defaultView] && this.views[this.defaultView]["defaultView"]){
-				subIds =  this.views[this.defaultView]["defaultView"];
-			}	
-			
-			if(this.models && !this.loadedModels){
-				//if there is this.models config data and the models has not been loaded yet,
-				//load models at here using the configuration data and load model logic in model.js
-				this.loadedModels = model(this.models);
-				bind(this.getChildren(), this.loadedModels);
-			}
-			
-			//startup assumes all children are loaded into DOM before startup is called
-			//startup will only start the current available children.
-			var cid = this.id + "_" + toId;
-            if (this.children[cid]) {
-				var next = this.children[cid];
-
-				this.set("selectedChild", next);
-				
-				// If I am a not being controlled by a parent layout widget...
-				var parent = this.getParent && this.getParent();
-				if (!(parent && parent.isLayoutContainer)) {
-					// Do recursive sizing and layout of all my descendants
-					// (passing in no argument to resize means that it has to glean the size itself)
-					this.resize();
-					
-					// Since my parent isn't a layout container, and my style *may be* width=height=100%
-					// or something similar (either set directly or via a CSS class),
-					// monitor when my size changes so that I can re-layout.
-					// For browsers where I can't directly monitor when my size changes,
-					// monitor when the viewport changes size, which *may* indicate a size change for me.
-					this.connect(has("ie") ? this.domNode : dojo.global, 'onresize', function(){
-						// Using function(){} closure to ensure no arguments to resize.
-						this.resize();
-					});
-					
-				}
-				
-				array.forEach(this.getChildren(), function(child){
-					child.startup();
-				});
-
-				//transition to _startView
-              if (this._startView && (this._startView != this.defaultView)) {
-                  this.transition(this._startView, {});
-              }
-			}
-		},
-
-		addChild: function(widget){
-			cls.add(widget.domNode, this.baseClass + "_child");
-			widget.region = "center";;
-			dattr.set(widget.domNode,"region","center");
-			this._supportingWidgets.push(widget);
-			dconstruct.place(widget.domNode,this.domNode);
-			this.children[widget.id] = widget;
-			return widget;
-		},
-
-		removeChild: function(widget){
-			// summary:
-			//		Removes the passed widget instance from this widget but does
-			//		not destroy it.  You can also pass in an integer indicating
-			//		the index within the container to remove
-
-			if(widget){
-				var node = widget.domNode;
-				if(node && node.parentNode){
-					node.parentNode.removeChild(node); // detach but don't destroy
-				}
-				return widget;
-			}
-		},
-
-		_setSelectedChildAttr: function(child,opts){
-			if (child !== this.selectedChild) { 
-				return deferred.when(child, dlang.hitch(this, function(child){
-					if (this.selectedChild){
-						if (this.selectedChild.deactivate){
-							this.selectedChild.deactivate(); 
-						}
-
-						dstyle.set(this.selectedChild.domNode,"zIndex",25);
-					}
-		
-					//dojo.style(child.domNode, {
-					//	"display": "",
-					//	"zIndex": 50,
-					//	"overflow": "auto"
-					//});
-					this.selectedChild = child;
-					dstyle.set(child.domNode, "display", "");
-					dstyle.set(child.domNode,"zIndex",50);
-					this.selectedChild=child;
-					if (this._started) {	
-						if (child.startup && !child._started){
-							child.startup();
-						}else if (child.activate){
-							child.activate();
-						}
-		
-					}
-					this.layout();
-				}));
-			}
-		},
-
-
-		transition: function(transitionTo,opts){
-			//summary: 
-			//  transitions from the currently visible scene to the defined scene.
-			//  it should determine what would be the best transition unless
-			//  an override in opts tells it to use a specific transitioning methodology
-			//  the transitionTo is a string in the form of [view]@[scene].  If
-			//  view is left of, the current scene will be transitioned to the default
-			//  view of the specified scene (eg @scene2), if the scene is left off
-			//  the app controller will instruct the active scene to the view (eg view1).  If both
-			//  are supplied (view1 at scene2), then the application should transition to the scene,
-			//  and instruct the scene to navigate to the view.
-			var toId,subIds,next, current = this.selectedChild;
-			console.log("scene", this.id, transitionTo);
-			if (transitionTo){	
-				var parts = transitionTo.split(",");
-				toId= parts.shift();
-				subIds = parts.join(',');
-
-			}else{
-				toId = this.defaultView;
-				if(this.views[this.defaultView] && this.views[this.defaultView]["defaultView"]){
-					subIds =  this.views[this.defaultView]["defaultView"];
-				}	
-			}
-		
-			next = this.loadChild(toId,subIds);
-
-			if (!current){
-				//assume this.set(...) will return a promise object if child is first loaded
-				//return nothing if child is already in array of this.children
-				return this.set("selectedChild",next);	
-			}	
-
-			var transitionDeferred  = new deferred();
-			deferred.when(next, dlang.hitch(this, function(next){
-			        var promise;
-			    
-				if (next!==current){
-				    //TODO need to refactor here, when clicking fast, current will not be the 
-				    //view we want to start transition. For example, during transition 1 -> 2
-				    //if user click button to transition to 3 and then transition to 1. It will
-				    //perform transition 2 -> 3 and 2 -> 1 because current is always point to 
-				    //2 during 1 -> 2 transition.
-				    
-				    var waitingList = anim.getWaitingList([next.domNode, current.domNode]);
-				    //update registry with deferred objects in animations of args.
-				    var transitionDefs = {};
-				    transitionDefs[current.domNode.id] = anim.playing[current.domNode.id] = new deferred();
-				    transitionDefs[next.domNode.id] = anim.playing[current.domNode.id] = new deferred();
-				                
-				    deferred.when(waitingList, dojo.hitch(this, function(){
-					//assume next is already loaded so that this.set(...) will not return
-					//a promise object. this.set(...) will handles the this.selectedChild,
-					//activate or deactivate views and refresh layout.
-					this.set("selectedChild", next);
-					
-					//publish /app/transition event
-					//application can subscript this event to do user define operation like select TabBarButton, etc.
-					connect.publish("/app/transition", [next, toId]);
-					transit(current.domNode,next.domNode,dojo.mixin({},opts,{transition: this.defaultTransition || "none", transitionDefs: transitionDefs})).then(dlang.hitch(this, function(){
-						//dojo.style(current.domNode, "display", "none");
-						if (subIds && next.transition){
-							promise = next.transition(subIds,opts);
-						}
-						deferred.when(promise, function(){
-		                                    transitionDeferred.resolve();
-		                                });
-					}));
-				    }));
-				    return;
-				}
-
-				//we didn't need to transition, but continue to propogate.
-				if (subIds && next.transition){
-					promise = next.transition(subIds,opts);
-				}
-				deferred.when(promise, function(){
-				    transitionDeferred.resolve();
-				});
-			}));
-			return transitionDeferred;
-		},
-		toString: function(){return this.id},
-
-		activate: function(){},
-		deactive: function(){}
-	});
-});
diff --git a/dojox/app/schema/application.json b/dojox/app/schema/application.json
index 7f8fdd4..ac4bf30 100644
--- a/dojox/app/schema/application.json
+++ b/dojox/app/schema/application.json
@@ -1,4 +1,4 @@
-define({
+{
 	"description":"A representation of an Application",
 	"type": "object",
 	"properties":{
@@ -21,7 +21,7 @@ define({
 
 
 		"defaultScene": {
-			"type": "string"
+			"type": "string",
 			"description": "id of scene to load for this application at startup"
 		},
 
@@ -52,4 +52,4 @@ define({
 			"default": {}
 		}
 	}
-});
+}
diff --git a/dojox/app/schema/model.json b/dojox/app/schema/model.json
index a630516..02de20a 100644
--- a/dojox/app/schema/model.json
+++ b/dojox/app/schema/model.json
@@ -5,7 +5,7 @@
 		"type": {
 			"type": "string",
 			"description": "Model Instance Type (Class)"
-		},
+		}
 	},
 	"additionalProperties": true
 }
diff --git a/dojox/app/schema/scene.json b/dojox/app/schema/scene.json
index 412ce90..41989e4 100644
--- a/dojox/app/schema/scene.json
+++ b/dojox/app/schema/scene.json
@@ -18,11 +18,12 @@
 					"id": {
 						"type": "string"
 					},
-					"view": "$ref": "/jdoe/test/schema/view",
+					"view": {"$ref": "/jdoe/test/schema/view"},
 					"params": {
 						"type": "object"
 					}
 				}
+			}
 		}
 	},
 	"additionalProperties": true
diff --git a/dojox/app/schema/store.json b/dojox/app/schema/store.json
index 924f5e1..2d41641 100644
--- a/dojox/app/schema/store.json
+++ b/dojox/app/schema/store.json
@@ -5,7 +5,7 @@
 		"type": {
 			"type": "string",
 			"description": "Store Instance Type (Class)"
-		},
+		}
 	},
 	"additionalProperties": true
 }
diff --git a/dojox/app/tests/borderLayoutApp/borderlayoutApp.js b/dojox/app/tests/borderLayoutApp/borderlayoutApp.js
new file mode 100644
index 0000000..35fb5e0
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/borderlayoutApp.js
@@ -0,0 +1,45 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojo/sniff"],
+function(win, Application, jsonRef, config, has){
+	win.global.modelApp = {};
+	modelApp.listData = { 
+		identifier: "id",
+		'items':[{
+			"id": "item1",
+			"label": "Chad Chapman",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Chad",
+			"Last": "Chapman",
+			"Location": "CA",
+			"Office": "1278",
+			"Email": "c.c at test.com",
+			"Tel": "408-764-8237",
+			"Fax": "408-764-8228"
+		}, {
+			"id": "item2",
+			"label": "Irene Ira",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Irene",
+			"Last": "Ira",
+			"Location": "NJ",	
+			"Office": "F09",
+			"Email": "i.i at test.com",
+			"Tel": "514-764-6532",
+			"Fax": "514-764-7300"
+		}, {
+			"id": "item3",
+			"label": "John Jacklin",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "John",
+			"Last": "Jacklin",
+			"Location": "CA",
+			"Office": "6701",
+			"Email": "j.j at test.com",
+			"Tel": "408-764-1234",
+			"Fax": "408-764-4321"
+		}]
+	};
+	var cfg = jsonRef.fromJson(config);
+	has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+	Application(cfg);
+	
+});
diff --git a/dojox/app/tests/borderLayoutApp/config.json b/dojox/app/tests/borderLayoutApp/config.json
new file mode 100644
index 0000000..1b6037c
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/config.json
@@ -0,0 +1,148 @@
+{
+	"id": "borderLayoutApp",
+	"name": "border layout App",
+	"description": "A border layout App",
+	"splash": "splash",
+
+	"loaderConfig": {
+		"paths": {
+			"layoutApp": "../dojox/app/tests/borderLayoutApp"
+		}
+	},
+
+	"dependencies": [
+		"dojox/mobile/_base",
+		"dojox/mobile/compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRectList",
+		"dojox/mobile/ListItem",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/Heading",
+		"dojox/mobile/ScrollableView",
+		"dojo/store/Memory",
+		"dojox/mobile/EdgeToEdgeStoreList",
+		"dojo/store/Observable",		
+		"dijit/layout/BorderContainer",
+		"dojox/mobile/View",
+		"dojox/app/widgets/Container"
+	],
+
+	"modules": [],
+
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/BorderLayout"   
+	//	"dojox/app/controllers/Layout"         // this test can work with either Layout or BorderLayout
+	],
+
+	"borderLayoutNoSplitter": false,  // set true to turn off the splitter on the StackContainer.
+
+	// these are the possible defaultTransitions, 
+	// the defaultTransition is only used if transition is not set in the config and it is not set or defaulted on the transitionEvent
+	//"defaultTransition": "slide",
+	//"defaultTransition": "none",
+	//"defaultTransition": "fade",
+	//"defaultTransition": "flip",     // Note: flip does not work with a BorderLayout Controller
+
+	// these are the possible transitions, 
+	// if a transition is set on a view or parent it will override the transition set on the transitionEvent or the defaultTransition in the config.
+	"transition": "slide",
+	//"transition": "none",
+	//"transition": "fade",
+	//"transition": "flip",     // Note: flip does not work with a BorderLayout Controller
+
+	//stores we are using 
+	"stores": {
+       "listStore":{
+           "type": "dojo/store/Memory",
+	       "observable": true,
+           "params": {
+                "data": "modelApp.listData"
+           }
+       }
+	},
+	
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+	// this app uses constraint (region) and multiple files in defaultView instead of an outer template for the layout
+
+	//the name of the view to load when the app is initialized.
+	//"defaultView": "view1+view3+view7+view9+view5", 
+	//"defaultView": "view1+view9+view3+view7+view5", 
+	//"defaultView": "view9+view1+view7+view3+view5", 
+	"defaultView": "view2+view10+view4+view8+view6", 
+	
+		
+	"views": {
+		"view1":{
+			"constraint" : "top",
+			"controller" : "layoutApp/views/view1.js",			
+			"template": "layoutApp/templates/view1.html"
+		},
+		"view2":{
+			"constraint" : "top",
+			"template": "layoutApp/templates/view2.html"
+		},
+		"view3":{
+			"constraint" : "left",
+			"template": "layoutApp/templates/view3.html"
+		},
+		"view4":{
+			"constraint" : "left",
+			"template": "layoutApp/templates/view4.html"
+		},
+		"view5":{
+			"constraint" : "center",
+			"controller" : "layoutApp/views/view5.js",
+			"template": "layoutApp/templates/view5.html"
+		},
+		"view6":{
+			"constraint" : "center",
+			"template": "layoutApp/templates/view6.html"
+		},
+		"view7":{
+			"constraint" : "right",
+			"template": "layoutApp/templates/view7.html"
+		},
+		"view8":{
+			"constraint" : "right",
+			"template": "layoutApp/templates/view8.html"
+		},
+		"view9":{
+			"constraint" : "bottom",
+			"template": "layoutApp/templates/view9.html"
+		},
+		"view10":{
+			"constraint" : "bottom",
+			"template": "layoutApp/templates/view10.html"
+		},
+		//list view, include list view and details view
+		"list":{
+			"controller" : "layoutApp/views/list.js",
+			"template": "layoutApp/templates/list.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		},
+		"itemDetails":{
+			"controller" : "layoutApp/views/itemDetails.js",
+			"template": "layoutApp/templates/itemDetails.html",
+			"dependencies":["dojox/mobile/TextBox"],
+			"defaultParams": {"cursor":"2"}
+		}
+	}	
+}
diff --git a/dojox/app/tests/borderLayoutApp/css/layoutApp.css b/dojox/app/tests/borderLayoutApp/css/layoutApp.css
new file mode 100644
index 0000000..fb3e8dc
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/css/layoutApp.css
@@ -0,0 +1,117 @@
+html,body {
+	width: 100%;
+	height: 100%;
+}
+
+button.baseBtn {
+	-webkit-background-clip: padding-box;
+	-webkit-box-align: center;
+	background-clip: padding-box;
+	border-style: solid;
+	border-width: 1px;
+	color: black;
+	font-family: 'Helvetica Neue', HelveticaNeue, Helvetica-Neue, Helvetica, 'BBAlpha Sans';
+	font-size: 18px;
+	font-weight: bold;
+	vertical-align: middle;
+	margin: 10px;
+	height: 34px;
+	border-bottom-left-radius: 7px;
+	border-bottom-right-radius: 7px;
+	border-top-left-radius: 7px;
+	border-top-right-radius: 7px;
+	width: 240px;
+}
+
+button.whiteBtn{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(white), color-stop(0.06, #f2f2f2), to(#b7b7b7));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+button.whiteBtnSelected{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(#ffffff), color-stop(0.06, #bbbbbb), to(#fcfcfc));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+#header button {
+	position:absolute;
+	margin:0;
+}
+
+#navButton {
+	width:60px;
+}
+
+#loadDiv {
+	position:absolute;
+	left:0;
+	top:0;
+	width:100%;
+	height:100%;
+	z-index:999;
+}
+#loadDiv {
+	display:table;
+	font-size: 20px;
+	text-align:center;
+	background-color:white;
+}
+#loadDiv span {
+	display:table-cell;
+	vertical-align:middle;
+}
+
+body .mblProgContainer {
+	top:45%;
+	height: 45px;
+	width: 140px;
+	margin-left:-70px;
+	background-color: #2A2A28;
+	border-style: solid;
+	border-width: 2px;
+	border-color: #666666;
+	border-radius: 0.4em;
+	-webkit-border-radius: 0.4em;
+	-moz-border-radius: 0.4em;
+}
+
+body .mblProgContainer > div {
+	height: 100%;
+	width: 100%;
+	line-height: 45px;
+	vertical-align: middle;
+	font-size: 20px;
+	color: #c2c2c2;
+}
+
+body .mblProg {
+	left: 3px;
+	top: 3px;
+}
+
+body .mblProgContainer > div::after {
+	padding-left: 42px;
+	content: "Updating...";
+}
+
+#jsContent, #htmlContent {
+	padding-left:2px;
+}
+
+ at media screen and (max-width: 600px) {
+	#jsContent, #htmlContent {
+		font-size: 14px;
+	}
+}
+
+.hidden {
+	display:none;
+}
+
+div .navPane {
+	width:250px;
+	border-right:1px solid black;
+	background-color: #C5CCD3;
+}
diff --git a/dojox/app/tests/borderLayoutApp/index.html b/dojox/app/tests/borderLayoutApp/index.html
new file mode 100644
index 0000000..27facaa
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/index.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Border Layout App</title>
+		<link type="text/css" href="./css/layoutApp.css" rel="stylesheet" />
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+				mblAlwaysHideAddressBar: false,
+				app: {debugApp: 1},  // set debugApp to log app transitions and view activate/deactivate
+				async: 1">
+		</script>
+		<script>
+			require(["./borderLayoutApp.js"], function(){
+			});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/borderLayoutApp/index2.html b/dojox/app/tests/borderLayoutApp/index2.html
new file mode 100644
index 0000000..54f8382
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/index2.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Border Layout App</title>
+		<link type="text/css" href="./css/layoutApp.css" rel="stylesheet" />
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+				mblAlwaysHideAddressBar: false,
+				app: {debugApp: 1},  // set debugApp to log app transitions and view activate/deactivate
+				async: 1">
+		</script>
+		<script>
+			require(["./layoutApp.js"], function(){
+			});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/borderLayoutApp/layoutApp.js b/dojox/app/tests/borderLayoutApp/layoutApp.js
new file mode 100644
index 0000000..73e4f53
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/layoutApp.js
@@ -0,0 +1,47 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojo/sniff"],
+function(win, Application, jsonRef, config, has){
+	win.global.modelApp = {};
+	modelApp.listData = { 
+		identifier: "id",
+		'items':[{
+			"id": "item1",
+			"label": "Chad Chapman",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Chad",
+			"Last": "Chapman",
+			"Location": "CA",
+			"Office": "1278",
+			"Email": "c.c at test.com",
+			"Tel": "408-764-8237",
+			"Fax": "408-764-8228"
+		}, {
+			"id": "item2",
+			"label": "Irene Ira",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Irene",
+			"Last": "Ira",
+			"Location": "NJ",	
+			"Office": "F09",
+			"Email": "i.i at test.com",
+			"Tel": "514-764-6532",
+			"Fax": "514-764-7300"
+		}, {
+			"id": "item3",
+			"label": "John Jacklin",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "John",
+			"Last": "Jacklin",
+			"Location": "CA",
+			"Office": "6701",
+			"Email": "j.j at test.com",
+			"Tel": "408-764-1234",
+			"Fax": "408-764-4321"
+		}]
+	};
+	var cfg = jsonRef.fromJson(config);
+	has.add("ie9orLess", has("ie") && (has("ie") <= 9));	
+	cfg.controllers[2] = "dojox/app/controllers/Layout";		
+	console.log("cfg.controllers[2] was set to Layout to force it to use Layout="+cfg.controllers[2]);	
+	Application(cfg);
+	
+});
diff --git a/dojox/app/tests/borderLayoutApp/templates/itemDetails.html b/dojox/app/tests/borderLayoutApp/templates/itemDetails.html
new file mode 100644
index 0000000..2923f41
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/itemDetails.html
@@ -0,0 +1,37 @@
+<div class="view mblView">
+    <h1 dojoType="dojox/mobile/Heading" data-dojo-props='back:"Back"'>List Item Details</h1>
+    <form name="listTestForm" id="listTestForm">    
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Updates to First or Last Name will be reflected in the list</h2>
+					<table id="table" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="First"
+									data-dojo-props="placeholder:'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Last"
+									 
+									data-dojo-props="placeholder:'Last Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput2" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Email"
+									data-dojo-props="placeholder:'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Tel"
+									data-dojo-props="placeholder:'Telephone'">
+							</td>
+						</tr>
+					</table>
+		</form>
+</div>
diff --git a/dojox/app/tests/borderLayoutApp/templates/list.html b/dojox/app/tests/borderLayoutApp/templates/list.html
new file mode 100644
index 0000000..b9a00e0
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/list.html
@@ -0,0 +1,11 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"List Example"'>
+  		<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="listInsert1"
+       		 data-dojo-props='icon:"mblDomButtonWhitePlus"'
+        		style="float:right;" onclick="console.log('+ was clicked')"></span>
+	</div>    
+	<form name="listTestForm">
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Using a dojox/mobile/EdgeToEdgeStoreList</h2>
+		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" data-dojo-attach-point="list" data-dojo-props='append:true'></ul>
+	</form>
+</div>
diff --git a/dojox/app/tests/borderLayoutApp/templates/view1.html b/dojox/app/tests/borderLayoutApp/templates/view1.html
new file mode 100644
index 0000000..cebc932
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/view1.html
@@ -0,0 +1,3 @@
+<div style='background-color:pink;'>
+    <h3 style='background-color:yellow;'>View 1 init top pane</h3>
+</div>
diff --git a/dojox/app/tests/borderLayoutApp/templates/view10.html b/dojox/app/tests/borderLayoutApp/templates/view10.html
new file mode 100644
index 0000000..b6e06dd
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/view10.html
@@ -0,0 +1,3 @@
+<div>
+    <h3 style='background-color:yellow;'>View 10 init footer pane</h3>
+</div>
diff --git a/dojox/app/tests/borderLayoutApp/templates/view2.html b/dojox/app/tests/borderLayoutApp/templates/view2.html
new file mode 100644
index 0000000..116ad41
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/view2.html
@@ -0,0 +1,3 @@
+<div>
+    <h3 style='background-color:pink;'>View 2 - 2nd top pane</h3>
+</div>
diff --git a/dojox/app/tests/borderLayoutApp/templates/view3.html b/dojox/app/tests/borderLayoutApp/templates/view3.html
new file mode 100644
index 0000000..23add1f
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/view3.html
@@ -0,0 +1,20 @@
+<div style='background-color:cyan;'>
+    <h3 style='background-color:cyan;'>View 3 left......................</h3>
+	<div data-dojo-type="dojox/mobile/ScrollableView">    
+			<ul data-dojo-type="dojox/mobile/RoundRectList">
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 2+10+4+8+6',target:'view2+view10+view4+view8+view6',url:'#view2+view10+view4+view8+view6'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 1+9+3+7+5',target:'view1+view9+view3+view7+view5',url:'#view1+view9+view3+view7+view5'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 1-8 top',target:'view1-view8',url:'#view1-view8'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 2-7 top',target:'view2-view7',url:'#view2-view7'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View left 3-9',target:'view3-view9',url:'#view3-view9'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 4 left',target:'view4',url:'#view4'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View center 5-10',target:'view5-view10',url:'#view5-view10'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View center 6-10',target:'view6-view10',url:'#view6-view10'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 7 right',target:'view7',url:'#view7'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 8 right',target:'view8',url:'#view8'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 9 bottom',target:'view9',url:'#view9'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 10 bottom',target:'view10',url:'#view10'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'List Data Test',target:'list',url:'#list'"></li>
+			</ul>
+	</div>
+</div>
diff --git a/dojox/app/tests/borderLayoutApp/templates/view4.html b/dojox/app/tests/borderLayoutApp/templates/view4.html
new file mode 100644
index 0000000..875f1f4
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/view4.html
@@ -0,0 +1,47 @@
+<div style='background-color:green;'>
+    <h3>View 4 left..added for spacing..</h3>
+	<div data-dojo-type="dojox/mobile/ScrollableView">    
+			<ul data-dojo-type="dojox/mobile/RoundRectList">
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view2+view10+view4+view8+view6',url:'#view2+view10+view4+view8+view6'">
+					View 2+10+4+8+6
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view1+view9+view3+view7+view5',url:'#view1+view9+view3+view7+view5'">
+					View 1+9+3+7+5
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view1-view8',url:'#view1-view8'">
+					View 1-8 top
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view2-view7',url:'#view2-view7'">
+					View 2-7 top
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view3-view9',url:'#view3-view9'">
+					View left 3-9
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view4',url:'#view4'">
+					View 4 left
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view5-view10',url:'#view5-view10'">
+					View center 5-10 
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view6-view10',url:'#view6-view10'">
+					View center 6-10 
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view7',url:'#view7'">
+					View 7 right
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view8',url:'#view8'">
+					View 8 right
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view9',url:'#view9'">
+					View 9 bottom
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'view10',url:'#view10'">
+					View 10 bottom
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'list',url:'#list'">
+					List Data Test
+				</li>
+				
+			</ul>
+	</div>    
+</div>
diff --git a/dojox/app/tests/borderLayoutApp/templates/view5.html b/dojox/app/tests/borderLayoutApp/templates/view5.html
new file mode 100644
index 0000000..d4e581b
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/view5.html
@@ -0,0 +1,15 @@
+<div>
+    <h3 style='background-color:blue;'>View 5 center.</h3>
+    <h3 style='background-color:blue;'>View 5 center.</h3>
+    <h3 style='background-color:blue;'>View 5 center.</h3>
+    <h3 style='background-color:blue;'>View 5 center.</h3>
+    <h3 style='background-color:blue;'>View 5 center.</h3>
+			<ul data-dojo-type="dojox/mobile/RoundRectList">
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 1 top',target:'view1',url:'#view1'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 2 top',target:'view2',url:'#view2'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 3 left',target:'view3',url:'#view3'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 4 left',target:'view4',url:'#view4'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Remove view7 right',target:'-view7',url:'#-view7'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Remove view8 right',target:'-view8',url:'#-view8'"></li>
+			</ul>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/borderLayoutApp/templates/view6.html b/dojox/app/tests/borderLayoutApp/templates/view6.html
new file mode 100644
index 0000000..7e8b8d4
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/view6.html
@@ -0,0 +1,14 @@
+<div>
+    <h3 style='background-color:green;'>View 6 center.</h3>
+    <h3 style='background-color:green;'>View 6 center.</h3>
+    <h3 style='background-color:green;'>View 6 center.</h3>
+    <h3 style='background-color:green;'>View 6 center.</h3>
+    		<ul data-dojo-type="dojox/mobile/RoundRectList">
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 1 top',target:'view1',url:'#view1'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 2 top',target:'view2',url:'#view2'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 3 left',target:'view3',url:'#view3'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'View 4 left',target:'view4',url:'#view4'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Remove view7 right',target:'-view7',url:'#-view7'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Remove view8 right',target:'-view8',url:'#-view8'"></li>
+			</ul>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/borderLayoutApp/templates/view7.html b/dojox/app/tests/borderLayoutApp/templates/view7.html
new file mode 100644
index 0000000..5d56c8b
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/view7.html
@@ -0,0 +1,5 @@
+<div>
+    <h3 style='background-color:pink;'>View 7 right</h3>
+    <h3 style='background-color:pink;'>View 7 right</h3>
+    <h3 style='background-color:pink;'>View 7 right</h3>
+</div>
diff --git a/dojox/app/tests/borderLayoutApp/templates/view8.html b/dojox/app/tests/borderLayoutApp/templates/view8.html
new file mode 100644
index 0000000..4ee48b3
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/view8.html
@@ -0,0 +1,5 @@
+<div>
+    <h3 style='background-color:orange;'>View 8 right</h3>
+    <h3 style='background-color:orange;'>View 8 right</h3>
+    <h3 style='background-color:orange;'>View 8 right</h3>
+</div>
diff --git a/dojox/app/tests/borderLayoutApp/templates/view9.html b/dojox/app/tests/borderLayoutApp/templates/view9.html
new file mode 100644
index 0000000..3cd9156
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/templates/view9.html
@@ -0,0 +1,3 @@
+<div>
+    <h3 style='background-color:blue;'>View 9 init footer pane</h3>
+</div>
diff --git a/dojox/app/tests/borderLayoutApp/test_BorderContainer_full.html b/dojox/app/tests/borderLayoutApp/test_BorderContainer_full.html
new file mode 100644
index 0000000..c6a6845
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/test_BorderContainer_full.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>dijit.layout.BorderContainer Test - Full Screen</title>
+
+	<style type="text/css">
+		@import "../../../../dijit/themes/claro/document.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+
+		html, body, #main{
+			width: 100%;	/* make the body expand to fill the visible window */
+			height: 100%;
+			overflow: hidden;	/* erase window level scrollbars */
+			padding: 0 0 0 0;
+			margin: 0 0 0 0;
+			font: 10pt Arial,Myriad,Tahoma,Verdana,sans-serif;
+		}
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+
+	<!-- only needed for alternate theme testing: do NOT use in your code! -->
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.layout.BorderContainer");
+		dojo.require("dijit.layout.ContentPane");
+		dojo.require("dijit.form.FilteringSelect");
+	</script>
+
+</head>
+<body class="claro" role="main">
+	<div id="main" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='design:"sidebar" '>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"main-leading", region:"leading", style:"background-color: #acb386; width: 100px;"'>
+			leading
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"main-top", region:"top", style:"background-color: #b39b86; height: 100px;"'>
+			top bar
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"main-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+			(to check we're copying children around properly).<br />
+			<select aria-label="select" data-dojo-type="dijit/form/FilteringSelect">
+				<option value="1">foo</option>
+				<option value="2">bar</option>
+				<option value="3">baz</option>
+			</select>
+			Here's some text that comes AFTER the combo box.
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"main-bottom", region:"bottom", style:"background-color: #b39b86; height: 100px;", splitter:true'>
+			bottom bar
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props='id:"main-trailing", region:"trailing", style:"background-color: #acb386; width: 100px;", splitter:true'>
+			trailing
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/app/tests/borderLayoutApp/test_BorderContainer_full2.html b/dojox/app/tests/borderLayoutApp/test_BorderContainer_full2.html
new file mode 100644
index 0000000..5fce228
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/test_BorderContainer_full2.html
@@ -0,0 +1,121 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>dijit.layout.BorderContainer Test - Full Screen</title>
+
+	<style type="text/css">
+		@import "../../../../dijit/themes/claro/document.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+
+		html, body, #main{
+			width: 100%;	/* make the body expand to fill the visible window */
+			height: 100%;
+			overflow: hidden;	/* erase window level scrollbars */
+			padding: 0 0 0 0;
+			margin: 0 0 0 0;
+			font: 10pt Arial,Myriad,Tahoma,Verdana,sans-serif;
+		}
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+
+	<!-- only needed for alternate theme testing: do NOT use in your code! -->
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+
+	<script type="text/javascript">
+	//	dojo.require("dijit.dijit"); // optimize: load dijit layer
+	//	dojo.require("dijit/layout/BorderContainer");
+	//	dojo.require("dijit/layout/ContentPane");
+	//	dojo.require("dojox/app/widgets/Container");
+	//	dojo.require("dijit/form/FilteringSelect");
+		var bc, cp1, cp2, cp3, stack, cp2b, cp2c;
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			'dijit/layout/BorderContainer',
+			'dijit/layout/StackContainer',
+			'dijit/layout/StackController',
+			'dijit/layout/ContentPane', 
+			'dojox/app/widgets/Container',
+			'dijit/form/Button',
+			'dijit/form/FilteringSelect'
+			], function(parser, ready, BorderContainer, StackContainer, StackController, ContentPane){
+		
+        dojo.ready(function(){
+				
+			bc = new BorderContainer({style:'height:400px;width:500px;border:1px solid black'}, dojo.byId('main2'));
+			
+			cp1 = new ContentPane({region:'top',style:'height:100px;background-color:red',splitter:true, id:"cp1"});
+			cp1.domNode.innerHTML = "top pane";
+			bc.addChild(cp1);
+
+		//	cp2 = new ContentPane({region:'center',style:'background-color:green', id:'cp2'});
+			stack = new StackContainer({region:'center',style:'background-color:green', id: "sc" });
+			bc.addChild(stack);
+		//	cp2.addChild(stack);
+
+			cp2b = new ContentPane({style:'background-color:green', id:'cp2b'});
+			cp2b.domNode.innerHTML = "center pane1 in stack";
+			stack.addChild(cp2b);
+
+			cp2c = new ContentPane({style:'background-color:yellow', id:'cp2c'});
+			cp2c.domNode.innerHTML = "center pane2 in stack";
+			stack.addChild(cp2c);
+
+		//	bc.addChild(cp2);
+
+			cp3 = new ContentPane({region:'left', splitter: true, style:'width: 100px;', id:'cp3'});
+			cp3.domNode.innerHTML = "left pane";
+			
+			bc.startup();
+        });
+
+			});
+		
+	</script>
+
+</head>
+<body class="claro">
+		<div id='main2'></div>
+
+	<button id="addLeft" onclick="bc.addChild(cp3);">add left pane</button>
+	<button id="removeLeft" onclick="bc.removeChild(cp3);">remove left pane</button>
+	<button id="addTop" onclick="bc.addChild(cp1);">add top pane</button>
+	<button id="removeTop" onclick="bc.removeChild(cp1);">remove top pane</button>
+	<button id="selectStack1" onclick="stack.selectChild(cp2b);">Select Stack 1</button>
+	<button id="selectStack2" onclick="stack.selectChild(cp2c);">Select Stack 2</button>
+
+	<div id="main" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props='design:"sidebar" '>
+		<div data-dojo-type="dojox/app/widgets/Container" data-dojo-props='id:"main-leading", region:"left", style:"background-color: #acb386; width: 100px; height: 500px"'>
+			leading
+		</div>
+		<div data-dojo-type="dojox/app/widgets/Container" data-dojo-props='id:"main-top", region:"top", style:"background-color: #b39b86; height: 100px;"'>
+			top bar
+		</div>
+		<div data-dojo-type="dojox/app/widgets/Container" data-dojo-props='id:"main-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+			(to check we're copying children around properly).<br />
+			<select aria-label="select" data-dojo-type="dijit/form/FilteringSelect">
+				<option value="1">foo</option>
+				<option value="2">bar</option>
+				<option value="3">baz</option>
+			</select>
+			Here's some text that comes AFTER the combo box.
+		</div>
+		<div data-dojo-type="dojox/app/widgets/Container" data-dojo-props='id:"main-bottom", region:"bottom", style:"background-color: #b39b86; height: 100px;", splitter:true'>
+			bottom bar
+		</div>
+		<div data-dojo-type="dojox/app/widgets/Container" data-dojo-props='id:"main-trailing", region:"trailing", style:"background-color: #acb386; width: 100px;", splitter:true'>
+			trailing
+		</div>
+	</div>
+
+
+</body>
+</html>
diff --git a/dojox/app/tests/borderLayoutApp/views/itemDetails.js b/dojox/app/tests/borderLayoutApp/views/itemDetails.js
new file mode 100644
index 0000000..b25bc08
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/views/itemDetails.js
@@ -0,0 +1,48 @@
+define([],
+function(){
+
+	var listStore = null;	//list data
+	var currentItem = null;
+
+	return {
+		// show an item detail
+		setDetailsContext: function(index){
+			// only set the cursor if it is different and valid
+			if(parseInt(index) < listStore.data.length){
+				currentItem = listStore.data[index];
+				this.First.set("value",currentItem.First);
+				this.Last.set("value",currentItem.Last);
+				this.Email.set("value",currentItem.Email);
+				this.Tel.set("value",currentItem.Tel);
+			}
+		},
+
+		// list view init
+		init: function(){
+			listStore = this.loadedStores.listStore;
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			// if this.params["cursor"] is set use it to set the selected Details Context
+			if(this.params["cursor"] || this.params["cursor"] == 0){
+				this.setDetailsContext(this.params["cursor"]);
+			}
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeDeactivate()
+			//
+			// put any updates back to the store
+			currentItem.label = this.First.get("value") + " " + this.Last.get("value");
+			currentItem.First = this.First.get("value");
+			currentItem.Last = this.Last.get("value");
+			currentItem.Email = this.Email.get("value");
+			currentItem.Tel = this.Tel.get("value");
+			listStore.put(currentItem);
+		}
+	}
+});
diff --git a/dojox/app/tests/borderLayoutApp/views/list.js b/dojox/app/tests/borderLayoutApp/views/list.js
new file mode 100644
index 0000000..c98ff3e
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/views/list.js
@@ -0,0 +1,76 @@
+define(["dojo/_base/lang"], function(lang){
+	var _onResults = []; // events on array
+
+	return {
+	// setDetailsContext for an item
+		setDetailsContext: function(index, e, params){
+			if(params){
+				params.cursor = index;
+			}else{
+				params = {"cursor":index};
+			}
+			// transition to itemDetails view with the &cursor=index
+			var transOpts = {
+				title : "itemDetails",
+				target : "itemDetails",
+				url : "#itemDetails", // this is optional if not set it will be created from target   
+				params : params
+			};
+			this.app.transitionToView(e.target,transOpts,e);
+ 
+		
+		},
+
+	// insert an item
+		insertResult: function(index, e){
+			if(index<0 || index>this.list.store.data.length){
+				throw Error("index out of data model.");
+			}
+			if((this.list.store.data[index-1].First=="") ||
+				(this.list.store.data[index] && (this.list.store.data[index].First == ""))){
+				return;
+			}
+			var data = {id:Math.random(), "label": "", "rightIcon":"mblDomButtonBlueCircleArrow", "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+			this.list.store.add(data);
+			this.setDetailsContext(index, e);
+		},
+
+
+		// list view init
+		init: function(){
+			var list = this.list;
+			if(!list.Store){
+				list.setStore(this.loadedStores.listStore);
+			}
+		//	for(var i = 0; i < this.list.store.data.length; i++){
+		//		var item = dom.byId(this.list.store.data[i].id);
+		//		on(item, "click", lang.hitch(this, function(e){
+		//			var item = this.list.store.query({"label": e.target.innerHTML})
+		//			var index = this.list.store.index[item[0].id];
+		//			console.log("index is "+index);
+		//			this.setDetailsContext(index, e, this.params);
+		//		})); 
+		//	}
+			
+			this.list.on("click", lang.hitch(this, function(e){
+				console.log("List on click hit ",e);
+				var item = this.list.store.query({"label": e.target.innerHTML});
+				var index = this.list.store.index[item[0].id];
+				console.log("index is "+index);
+				this.setDetailsContext(index, e, this.params);	
+			})); 
+
+			this.listInsert1.on("click", lang.hitch(this, function(e){
+				console.log("listInsert1 on click hit ",e);
+				var index = this.list.store.data.length;
+				this.insertResult(index, e);
+			})); 
+			
+		},
+
+		// view destroy, this destroy function can be removed since it is empty
+		destroy: function(){
+			// _WidgetBase.on listener is automatically destroyed when the Widget itself is.
+		}
+	};
+});
diff --git a/dojox/app/tests/borderLayoutApp/views/view1.js b/dojox/app/tests/borderLayoutApp/views/view1.js
new file mode 100644
index 0000000..d391dbd
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/views/view1.js
@@ -0,0 +1,24 @@
+define([], function(){
+
+	return {
+		init: function(){
+			console.log("In view1 init called");
+		},
+
+		beforeActivate: function(){
+			console.log("In view1 beforeActivate called");
+		},
+
+		afterActivate: function(){
+			console.log("In view1 afterActivate called");
+		},
+
+		beforeDeactivate: function(){
+			console.log("In view1 beforeDeactivate called");
+		},
+
+		afterDeactivate: function(){
+			console.log("In view1 afterDeactivate called");
+		}
+	}
+});
diff --git a/dojox/app/tests/borderLayoutApp/views/view5.js b/dojox/app/tests/borderLayoutApp/views/view5.js
new file mode 100644
index 0000000..48c3739
--- /dev/null
+++ b/dojox/app/tests/borderLayoutApp/views/view5.js
@@ -0,0 +1,24 @@
+define([], function(){
+
+	return {
+		init: function(){
+			console.log("In view5 init called");
+		},
+
+		beforeActivate: function(){
+			console.log("In view5 beforeActivate called");
+		},
+
+		afterActivate: function(){
+			console.log("In view5 afterActivate called");
+		},
+
+		beforeDeactivate: function(){
+			console.log("In view5 beforeDeactivate called");
+		},
+
+		afterDeactivate: function(){
+			console.log("In view5 afterDeactivate called");
+		}
+	}
+});
diff --git a/dojox/app/tests/customApp/DtlView.js b/dojox/app/tests/customApp/DtlView.js
new file mode 100755
index 0000000..0320441
--- /dev/null
+++ b/dojox/app/tests/customApp/DtlView.js
@@ -0,0 +1,7 @@
+define(["dojo/_base/declare", "dojox/app/View", "dojox/dtl/_Templated"],
+	function(declare, View, _Templated){
+		return declare([_Templated, View], {
+			_dijitTemplateCompat: true
+		});
+	}
+);
\ No newline at end of file
diff --git a/dojox/app/tests/customApp/WidgetView.js b/dojox/app/tests/customApp/WidgetView.js
new file mode 100644
index 0000000..2c34bac
--- /dev/null
+++ b/dojox/app/tests/customApp/WidgetView.js
@@ -0,0 +1,13 @@
+define(["dojo/_base/declare", "dojox/app/ViewBase", "dijit/_WidgetBase", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin"],
+	function(declare, ViewBase, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin){
+		return declare([_WidgetBase, ViewBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+			postCreate: function(){
+				this.inherited(arguments);
+				// use the dojo attach point
+				this.myButton.on("click", function(){
+					console.log("I was correctly attached!")
+				});
+			}
+		});
+	}
+);
\ No newline at end of file
diff --git a/dojox/app/tests/customApp/WidgetView2.js b/dojox/app/tests/customApp/WidgetView2.js
new file mode 100755
index 0000000..b9c1350
--- /dev/null
+++ b/dojox/app/tests/customApp/WidgetView2.js
@@ -0,0 +1,14 @@
+define(["dojo/_base/declare", "dojox/app/ViewBase", "dijit/form/Button"],
+	function(declare, ViewBase, Button){
+		return declare([Button, ViewBase], {
+			postscript: function(){
+				// we want to avoid kickin the Dijit lifecycle at ctor time so that definition has been mixed into the
+				// widget when it is instanciated. This is only really needed if you need the definition
+			},
+			_startup: function(){
+				this.create();
+				this.inherited(arguments);
+			}
+		});
+	}
+);
\ No newline at end of file
diff --git a/dojox/app/tests/customApp/config.json b/dojox/app/tests/customApp/config.json
new file mode 100644
index 0000000..4740ab2
--- /dev/null
+++ b/dojox/app/tests/customApp/config.json
@@ -0,0 +1,61 @@
+{
+	"id": "customApp",
+	"name": "customApp",
+	"description": "A simple app to show how to plug custom view controllers",
+
+	"loaderConfig": {
+		"paths": {
+			"customApp": "../dojox/app/tests/customApp"
+		}
+	},
+
+	"modules": [
+	],
+
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],
+	
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+	
+	"defaultView": "home",
+
+	"views": {
+		"home": {
+			"template": "customApp/home.html",
+			"dependencies":	[
+				"dojox/mobile/RoundRectList",
+				"dojox/mobile/ListItem"
+			]
+		},
+		"dtl": {
+			"type": "customApp/DtlView",
+			"controller" : "customApp/dtl",
+			"template": "customApp/dtl.html"
+		},
+		"widget": {
+			"type": "customApp/WidgetView",
+			"templateString": "<div><button data-dojo-attach-point='myButton' data-dojo-type='dojox/mobile/Button'>I'm the templated view widget</button></div>"
+		},
+		"widget2": {
+			"type": "customApp/WidgetView2",
+			"controller": "customApp/widget"
+		}
+
+	}
+}
diff --git a/dojox/app/tests/customApp/customApp.js b/dojox/app/tests/customApp/customApp.js
new file mode 100755
index 0000000..852484f
--- /dev/null
+++ b/dojox/app/tests/customApp/customApp.js
@@ -0,0 +1,7 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojo/sniff"],
+function(win, Application, jsonRef, config, has){
+	var cfg = jsonRef.fromJson(config);
+	has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+	Application(cfg);
+
+});
diff --git a/dojox/app/tests/customApp/dtl.html b/dojox/app/tests/customApp/dtl.html
new file mode 100755
index 0000000..f7e9c20
--- /dev/null
+++ b/dojox/app/tests/customApp/dtl.html
@@ -0,0 +1 @@
+<div><input><ul>{% for item in items %}<li>${oldRepl} {{ item }}</li>{% endfor %}</ul></div>
\ No newline at end of file
diff --git a/dojox/app/tests/customApp/dtl.js b/dojox/app/tests/customApp/dtl.js
new file mode 100755
index 0000000..b8f7b1d
--- /dev/null
+++ b/dojox/app/tests/customApp/dtl.js
@@ -0,0 +1,6 @@
+define([], function(){
+	return {
+		oldRepl: "Fruit: ",
+		items: ["apple", "banana", "orange"]
+	}
+});
\ No newline at end of file
diff --git a/dojox/app/tests/customApp/home.html b/dojox/app/tests/customApp/home.html
new file mode 100755
index 0000000..9a43dac
--- /dev/null
+++ b/dojox/app/tests/customApp/home.html
@@ -0,0 +1,7 @@
+<div class="view mblView">
+    <ul data-dojo-type="dojox/mobile/RoundRectList">
+        <li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'DTL Custom View',target:'dtl',url:'#dtl'"></li>
+        <li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Templated Widget Custom View',target:'widget',url:'#widget'"></li>
+		<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Widget Custom View 2',target:'widget2',url:'#widget2'"></li>
+    </ul>
+</div>
diff --git a/dojox/app/tests/customApp/index.html b/dojox/app/tests/customApp/index.html
new file mode 100755
index 0000000..e369d0c
--- /dev/null
+++ b/dojox/app/tests/customApp/index.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
+		<meta name="apple-mobile-web-app-capable" content="yes" /> 
+		<title>Custom App Test</title>
+		<link rel="stylesheet" href="../../../../dijit/themes/claro/claro.css">
+		<style>
+			html,body {
+				width: 100%;
+				height: 100%;
+				background: #eee;
+				font-family: arial;
+				color: #333;
+				overflow: hidden;
+				margin: 0;
+				padding: 0;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"></script>
+		<script type="text/javascript" data-dojo-config="parseOnLoad: false, async: false" src="../../../../dojo/dojo.js"></script>
+		<script>
+			require(["dojox/app/main", "dojox/json/ref", "dojo/text!./config.json"],
+			function(Application, jsonRef, config){
+				var cfg = jsonRef.fromJson(config);
+				Application(cfg);
+			});
+
+        </script>
+
+	</head>
+	<body class="claro">
+	</body>
+</html>
diff --git a/dojox/app/tests/customApp/widget.js b/dojox/app/tests/customApp/widget.js
new file mode 100755
index 0000000..e4633bd
--- /dev/null
+++ b/dojox/app/tests/customApp/widget.js
@@ -0,0 +1,5 @@
+define([], function(){
+	return {
+		label: "test label"
+	}
+});
\ No newline at end of file
diff --git a/dojox/app/tests/doh/borderLayoutApp/config.json b/dojox/app/tests/doh/borderLayoutApp/config.json
new file mode 100644
index 0000000..1b6037c
--- /dev/null
+++ b/dojox/app/tests/doh/borderLayoutApp/config.json
@@ -0,0 +1,148 @@
+{
+	"id": "borderLayoutApp",
+	"name": "border layout App",
+	"description": "A border layout App",
+	"splash": "splash",
+
+	"loaderConfig": {
+		"paths": {
+			"layoutApp": "../dojox/app/tests/borderLayoutApp"
+		}
+	},
+
+	"dependencies": [
+		"dojox/mobile/_base",
+		"dojox/mobile/compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRectList",
+		"dojox/mobile/ListItem",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/Heading",
+		"dojox/mobile/ScrollableView",
+		"dojo/store/Memory",
+		"dojox/mobile/EdgeToEdgeStoreList",
+		"dojo/store/Observable",		
+		"dijit/layout/BorderContainer",
+		"dojox/mobile/View",
+		"dojox/app/widgets/Container"
+	],
+
+	"modules": [],
+
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/BorderLayout"   
+	//	"dojox/app/controllers/Layout"         // this test can work with either Layout or BorderLayout
+	],
+
+	"borderLayoutNoSplitter": false,  // set true to turn off the splitter on the StackContainer.
+
+	// these are the possible defaultTransitions, 
+	// the defaultTransition is only used if transition is not set in the config and it is not set or defaulted on the transitionEvent
+	//"defaultTransition": "slide",
+	//"defaultTransition": "none",
+	//"defaultTransition": "fade",
+	//"defaultTransition": "flip",     // Note: flip does not work with a BorderLayout Controller
+
+	// these are the possible transitions, 
+	// if a transition is set on a view or parent it will override the transition set on the transitionEvent or the defaultTransition in the config.
+	"transition": "slide",
+	//"transition": "none",
+	//"transition": "fade",
+	//"transition": "flip",     // Note: flip does not work with a BorderLayout Controller
+
+	//stores we are using 
+	"stores": {
+       "listStore":{
+           "type": "dojo/store/Memory",
+	       "observable": true,
+           "params": {
+                "data": "modelApp.listData"
+           }
+       }
+	},
+	
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+	// this app uses constraint (region) and multiple files in defaultView instead of an outer template for the layout
+
+	//the name of the view to load when the app is initialized.
+	//"defaultView": "view1+view3+view7+view9+view5", 
+	//"defaultView": "view1+view9+view3+view7+view5", 
+	//"defaultView": "view9+view1+view7+view3+view5", 
+	"defaultView": "view2+view10+view4+view8+view6", 
+	
+		
+	"views": {
+		"view1":{
+			"constraint" : "top",
+			"controller" : "layoutApp/views/view1.js",			
+			"template": "layoutApp/templates/view1.html"
+		},
+		"view2":{
+			"constraint" : "top",
+			"template": "layoutApp/templates/view2.html"
+		},
+		"view3":{
+			"constraint" : "left",
+			"template": "layoutApp/templates/view3.html"
+		},
+		"view4":{
+			"constraint" : "left",
+			"template": "layoutApp/templates/view4.html"
+		},
+		"view5":{
+			"constraint" : "center",
+			"controller" : "layoutApp/views/view5.js",
+			"template": "layoutApp/templates/view5.html"
+		},
+		"view6":{
+			"constraint" : "center",
+			"template": "layoutApp/templates/view6.html"
+		},
+		"view7":{
+			"constraint" : "right",
+			"template": "layoutApp/templates/view7.html"
+		},
+		"view8":{
+			"constraint" : "right",
+			"template": "layoutApp/templates/view8.html"
+		},
+		"view9":{
+			"constraint" : "bottom",
+			"template": "layoutApp/templates/view9.html"
+		},
+		"view10":{
+			"constraint" : "bottom",
+			"template": "layoutApp/templates/view10.html"
+		},
+		//list view, include list view and details view
+		"list":{
+			"controller" : "layoutApp/views/list.js",
+			"template": "layoutApp/templates/list.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		},
+		"itemDetails":{
+			"controller" : "layoutApp/views/itemDetails.js",
+			"template": "layoutApp/templates/itemDetails.html",
+			"dependencies":["dojox/mobile/TextBox"],
+			"defaultParams": {"cursor":"2"}
+		}
+	}	
+}
diff --git a/dojox/app/tests/doh/borderLayoutApp/index.html b/dojox/app/tests/doh/borderLayoutApp/index.html
new file mode 100644
index 0000000..a130426
--- /dev/null
+++ b/dojox/app/tests/doh/borderLayoutApp/index.html
@@ -0,0 +1,164 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Border Layout App</title>
+		<link type="text/css" href="../../borderLayoutApp/css/layoutApp.css" rel="stylesheet" />
+		<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+		<script type="text/javascript" src="../../../../../dojox/mobile/deviceTheme.js"></script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+				mblAlwaysHideAddressBar: false,
+				app: {debugApp: 0},  // set debugApp to log app transtions and view activate/deactivate 
+				async: 1">
+		</script>
+
+		<script>
+            // the actual  launcher
+            require(["../../borderLayoutApp/borderLayoutApp.js"], function(){});
+        </script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/topic",
+				"dojo/_base/lang",
+				"dojo/dom",
+				"dojox/mobile/TransitionEvent",				
+				"dijit/registry"
+					], function(doh, topic, lang, dom, TransitionEvent, registry) {
+						
+						var events = [];
+
+						var getLabelfromWid = function(wid, indx1, indx2){
+							var val = wid.labelNode.innerText || wid.labelNode.firstChild.nodeValue || "";
+							val = lang.trim(val);
+							if(indx2){
+								val = val.substring(indx1,indx2)
+							}
+							return val;
+						};
+
+						topic.subscribe("/app/status", lang.hitch(this, function(newStatus) {
+							events.push(newStatus);
+							if (newStatus == 2) {
+								var listItem_0TestStr = "View 2+10+4+8+6";
+								var listItem_1TestStr = "View 1+9+3+7+5";
+								doh.register("Test-globalizedApp", [{
+									// Test initial listitem labels
+									name : "initial-listItem-labels",
+									timeout: 4000,
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+											var ListItem_0Label = registry.byId("dojox_mobile_ListItem_0");
+											if(ListItem_0Label){
+												var lab = getLabelfromWid(ListItem_0Label,0,listItem_0TestStr.length); 
+												doh.is(lab, listItem_0TestStr);
+											}else{
+												throw new Error("In initial-listItem-labels ListItem_0Label not found."); 
+											}
+											var ListItem_1Label = registry.byId("dojox_mobile_ListItem_1");
+											if(ListItem_1Label){
+												doh.is(getLabelfromWid(ListItem_1Label,0,listItem_1TestStr.length), listItem_1TestStr);
+											}else{
+												throw new Error("In initial-listItem-labels ListItem_1Label not found."); 
+											}
+											if(borderLayoutApp.children["borderLayoutApp_view2"]){
+												doh.t(borderLayoutApp.children["borderLayoutApp_view2"], "borderLayoutApp_view2 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view10"], "borderLayoutApp_view10 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view4"], "borderLayoutApp_view4 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view8"], "borderLayoutApp_view8 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view6"], "borderLayoutApp_view6 viewShowing should be true");
+											}else{
+												throw new Error("borderLayoutApp_view2 not found."); 
+											}
+											return dfd.callback(true);
+										}, 1000);
+										return dfd;
+									}
+								}, {
+									// Test first transition
+									name : "transition-test-1",
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+										// transition to first li
+											var liWidget = registry.byId("dojox_mobile_ListItem_1");
+											var ev = new TransitionEvent(liWidget.domNode, liWidget.params);
+											ev.dispatch();
+											return dfd.callback(true);
+										}, 500);
+									}			
+								}, {
+									// Test globalized view 1
+									name : "borderLayoutApp-test-1",
+									timeout: 5000,
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+											if(borderLayoutApp.children["borderLayoutApp_view1"]){
+												doh.t(borderLayoutApp.children["borderLayoutApp_view1"].viewShowing, "borderLayoutApp_view1 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view9"].viewShowing, "borderLayoutApp_view9 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view3"].viewShowing, "borderLayoutApp_view3 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view7"].viewShowing, "borderLayoutApp_view7 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view5"].viewShowing, "borderLayoutApp_view5 viewShowing should be true");
+											}else{
+												throw new Error("borderLayoutApp_view1 not found."); 
+											}
+											return dfd.callback(true);
+										}, 3000);
+										return dfd;
+									}
+								}, {
+									// Test second transition
+									name : "transition-test-2",
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+											var liWidget = registry.byId("dojox_mobile_ListItem_19");
+											var ev = new TransitionEvent(liWidget.domNode, liWidget.params);
+											ev.dispatch();
+											return dfd.callback(true);
+										}, 500);
+									}			
+										}, {
+									// Test globalized view 2
+									name : "borderLayoutApp-test-2",
+									timeout: 5000,
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+											if(borderLayoutApp.children["borderLayoutApp_view2"]){
+												doh.t(borderLayoutApp.children["borderLayoutApp_view2"], "borderLayoutApp_view2 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view10"], "borderLayoutApp_view10 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view4"], "borderLayoutApp_view4 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view8"], "borderLayoutApp_view8 viewShowing should be true");
+												doh.t(borderLayoutApp.children["borderLayoutApp_view6"], "borderLayoutApp_view6 viewShowing should be true");
+											}else{
+												throw new Error("borderLayoutApp_view2 not found."); 
+											}
+											if(history){
+												history.back();
+												setTimeout(function() {
+													history.back();
+												}, 500);
+											}	
+											return dfd.callback(true);
+										}, 1000);
+										return dfd;
+									}
+						}]);
+
+								doh.run();
+							}
+						}));
+
+					});
+		</script>
+	</head>
+	<body>
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/app/tests/doh/config.html b/dojox/app/tests/doh/config.html
new file mode 100755
index 0000000..3a6cce8
--- /dev/null
+++ b/dojox/app/tests/doh/config.html
@@ -0,0 +1,3 @@
+<div>
+
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/doh/error.js b/dojox/app/tests/doh/error.js
new file mode 100755
index 0000000..7afe1ec
--- /dev/null
+++ b/dojox/app/tests/doh/error.js
@@ -0,0 +1,163 @@
+define(["doh", "dojox/app/main", "dojox/json/ref", "dojo/text!./error1.json", "dojo/text!./error2.json",
+	"dojo/text!./error3.json", "dojo/text!./error4.json", "dojo/text!./error5.json", "dojo/text!./errorLast.json", "dojo/topic"],
+	function(doh, Application, json, config1, config2, config3, config4, config5, configLast, topic){
+	doh.register("dojox.app.tests.doh.error", [
+		{
+			timeout: 4000,
+			name: "error1",
+			runTest: function(t){
+				var dohDeferred = new doh.Deferred();
+				// stack events that are pushed
+				var events = [];
+				this._topic = topic.subscribe("/app/status", function(evt){
+					events.push(evt);
+				});
+				Application(json.fromJson(config1));
+				// we need to check that before timeout we _never_ entered the START (2) state
+				setTimeout(dohDeferred.getTestCallback(function(){
+					t.assertEqual([1], events);
+				}), 3000);
+				return dohDeferred;
+			},
+			tearDown: function(){
+				this._topic.remove();
+				// maybe dojox/app should do that?
+				delete testApp;
+			}
+		},
+		{
+			timeout: 4000,
+			name: "error2",
+			runTest: function(t){
+				var dohDeferred = new doh.Deferred();
+				// stack events that are pushed
+				var events = [];
+				this._topic = topic.subscribe("/app/status", function(evt){
+					events.push(evt);
+				});
+				Application(json.fromJson(config2));
+				// we need to check that before timeout we _never_ entered the START (2) state
+				setTimeout(dohDeferred.getTestCallback(function(){
+					t.assertEqual([1], events);
+				}), 3000);
+				return dohDeferred;
+			},
+			tearDown: function(){
+				this._topic.remove();
+				// maybe dojox/app should do that?
+				delete testApp;
+			}
+		},
+		{
+			timeout: 4000,
+			name: "error3",
+			runTest: function(t){
+				var dohDeferred = new doh.Deferred();
+				// stack events that are pushed
+				var events = [];
+				this._topic = topic.subscribe("/app/status", function(evt){
+					events.push(evt);
+				});
+				Application(json.fromJson(config3));
+				// we need to check that before timeout we _never_ entered the START (2) state
+				setTimeout(dohDeferred.getTestCallback(function(){
+					t.assertEqual([1], events);
+				}), 3000);
+				return dohDeferred;
+			},
+			tearDown: function(){
+				this._topic.remove();
+				// maybe dojox/app should do that?
+				delete testApp;
+			}
+		},
+		{
+			timeout: 4000,
+			name: "error4",
+			runTest: function(t){
+				var dohDeferred = new doh.Deferred();
+				// stack events that are pushed
+				var events = [];
+				this._topic = topic.subscribe("/app/status", function(evt){
+					events.push(evt);
+				});
+				Application(json.fromJson(config4));
+				// we need to check that before timeout we _never_ entered the START (2) state
+				setTimeout(dohDeferred.getTestCallback(function(){
+					t.assertEqual([1], events);
+				}), 3000);
+				return dohDeferred;
+			},
+			tearDown: function(){
+				this._topic.remove();
+				// maybe dojox/app should do that?
+				delete testApp;
+			}
+		},
+		{
+			timeout: 4000,
+			name: "error5",
+			runTest: function(t){
+				var dohDeferred = new doh.Deferred();
+				// stack events that are pushed
+				var events = [];
+				var goterror = false;
+				this._topic = topic.subscribe("/app/status", function(evt){
+					events.push(evt);
+				});
+				require(["dojox/app/main"], function(Application){
+					require.on("error", function(){
+						goterror = true;
+					});
+					Application(json.fromJson(config5));
+					// we need to check that before timeout we _never_ entered the START (2) state
+					// and we must check error has been thrown
+					setTimeout(dohDeferred.getTestCallback(function(){
+						t.assertEqual([1], events);
+						t.assertTrue(goterror);
+					}), 3000);
+				});
+				return dohDeferred;
+			},
+			tearDown: function(){
+				this._topic.remove();
+				// maybe dojox/app should do that?
+				delete testApp;
+			}
+		},
+		{
+			timeout: 4000,
+			name: "errorLast",
+			runTest: function(t){
+				var dohDeferred = new doh.Deferred();
+				// stack events that are pushed
+				var events = [];
+				this._topic = topic.subscribe("/app/status", function(evt){
+					events.push(evt);
+				});
+				// to workaround http://trac.dojotoolkit.org/ticket/16032
+				for(var p in require.waiting){
+					delete require.waiting[p];
+				}
+				require.execQ.length = 0;
+				require(["dojox/app/main"], function(Application){
+					Application(json.fromJson(configLast));
+					// we need to check that before timeout we _never_ entered the START (2) state
+					setTimeout(dohDeferred.getTestCallback(function(){
+						t.assertEqual([1], events);
+					}), 3000);
+				});
+				return dohDeferred;
+			},
+			tearDown: function(){
+				this._topic.remove();
+				for(var p in require.waiting){
+					delete require.waiting[p];
+				}
+				require.execQ.length = 0;
+				// maybe dojox/app should do that?
+				delete testApp;
+			}
+		}
+	]);
+});
diff --git a/dojox/app/tests/doh/error1.json b/dojox/app/tests/doh/error1.json
new file mode 100755
index 0000000..33ff2ea
--- /dev/null
+++ b/dojox/app/tests/doh/error1.json
@@ -0,0 +1,29 @@
+{
+	"id": "testApp",
+	"name": "Test App",
+	"description": "A testApp",
+	"splash": "splash",
+
+	"dependencies": [
+	],
+
+	"modules": [
+	],
+	
+	"controllers": [
+		"dojox/app/controllers/History"
+	],
+
+	"defaultView": "home",
+
+	"defaultTransition": "slide",
+
+	"views": {
+
+		"home": { 
+			"controller" : "dojox/app/tests/doh/errorDef1",
+			"template": "dojox/app/tests/doh/config.html"
+		}
+
+	}
+}
diff --git a/dojox/app/tests/doh/error2.json b/dojox/app/tests/doh/error2.json
new file mode 100755
index 0000000..51a70d4
--- /dev/null
+++ b/dojox/app/tests/doh/error2.json
@@ -0,0 +1,29 @@
+{
+	"id": "testApp",
+	"name": "Test App",
+	"description": "A testApp",
+	"splash": "splash",
+
+	"dependencies": [
+	],
+
+	"modules": [
+	],
+	
+	"controllers": [
+		"dojox/app/controllers/History"
+	],
+
+	"defaultView": "home",
+
+	"defaultTransition": "slide",
+
+	"views": {
+
+		"home": { 
+			"controller" : "dojox/app/tests/doh/errorDef2",
+			"template": "dojox/app/tests/doh/config.html"
+		}
+
+	}
+}
diff --git a/dojox/app/tests/doh/error3.html b/dojox/app/tests/doh/error3.html
new file mode 100755
index 0000000..1adc783
--- /dev/null
+++ b/dojox/app/tests/doh/error3.html
@@ -0,0 +1,4 @@
+incorrect html
+<div>
+ <incorrect html>/incorrect>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/doh/error3.json b/dojox/app/tests/doh/error3.json
new file mode 100755
index 0000000..b9ac007
--- /dev/null
+++ b/dojox/app/tests/doh/error3.json
@@ -0,0 +1,28 @@
+{
+	"id": "testApp",
+	"name": "Test App",
+	"description": "A testApp",
+	"splash": "splash",
+
+	"dependencies": [
+	],
+
+	"modules": [
+	],
+	
+	"controllers": [
+		"dojox/app/controllers/History"
+	],
+
+	"defaultView": "home",
+
+	"defaultTransition": "slide",
+
+	"views": {
+
+		"home": { 
+			"template": "dojox/app/tests/doh/error3.html"
+		}
+
+	}
+}
diff --git a/dojox/app/tests/doh/error4.json b/dojox/app/tests/doh/error4.json
new file mode 100755
index 0000000..2ed89a8
--- /dev/null
+++ b/dojox/app/tests/doh/error4.json
@@ -0,0 +1,28 @@
+{
+	"id": "testApp",
+	"name": "Test App",
+	"description": "A testApp",
+	"splash": "splash",
+
+	"dependencies": [
+	],
+
+	"modules": [
+	],
+	
+	"controllers": [
+		"dojox/app/controllers/History"
+	],
+
+	"defaultView": "home",
+
+	"defaultTransition": "slide",
+
+	"views": {
+
+		"home": { 
+			"template": "dojox/app/tests/doh/doesnotexist.html"
+		}
+
+	}
+}
diff --git a/dojox/app/tests/doh/error5.json b/dojox/app/tests/doh/error5.json
new file mode 100755
index 0000000..520e50b
--- /dev/null
+++ b/dojox/app/tests/doh/error5.json
@@ -0,0 +1,29 @@
+{
+	"id": "testApp",
+
+	"dependencies": [
+	],
+
+	"modules": [
+	],
+	
+	"controllers": [
+		"dojox/app/controllers/History"
+	],
+
+	"defaultView": "home",
+
+	"defaultTransition": "slide",
+
+	"stores": {
+		"namesStore":{
+			"type": "dojo/store/Memory"
+		}
+	},
+
+	"views": {
+		"home": {
+			"template": "dojox/app/tests/doh/config.html"
+		}
+	}
+}
diff --git a/dojox/app/tests/doh/errorDef1.js b/dojox/app/tests/doh/errorDef1.js
new file mode 100755
index 0000000..f94c75a
--- /dev/null
+++ b/dojox/app/tests/doh/errorDef1.js
@@ -0,0 +1,7 @@
+define([], function(){
+	return {
+		init: function(){
+			throw new Error("error1-error");
+		}
+	}
+});
\ No newline at end of file
diff --git a/dojox/app/tests/doh/errorDef2.js b/dojox/app/tests/doh/errorDef2.js
new file mode 100755
index 0000000..2531e86
--- /dev/null
+++ b/dojox/app/tests/doh/errorDef2.js
@@ -0,0 +1,7 @@
+define([], function(){
+	throw new Error("error2-error");
+	return {
+		init: function(){
+		}
+	}
+});
\ No newline at end of file
diff --git a/dojox/app/tests/doh/errorDojoDef.js b/dojox/app/tests/doh/errorDojoDef.js
new file mode 100755
index 0000000..c42a2c0
--- /dev/null
+++ b/dojox/app/tests/doh/errorDojoDef.js
@@ -0,0 +1,5 @@
+(function(){
+	require.has = {
+	    "dojo-publish-privates": true
+	};
+})();
\ No newline at end of file
diff --git a/dojox/app/tests/doh/errorLast.json b/dojox/app/tests/doh/errorLast.json
new file mode 100755
index 0000000..b3f8b79
--- /dev/null
+++ b/dojox/app/tests/doh/errorLast.json
@@ -0,0 +1,29 @@
+{
+	"id": "testApp",
+	"name": "Test App",
+	"description": "A testApp",
+	"splash": "splash",
+
+	"dependencies": [
+	],
+
+	"modules": [
+	],
+	
+	"controllers": [
+		"dojox/app/controllers/History"
+	],
+
+	"defaultView": "home",
+
+	"defaultTransition": "slide",
+
+	"views": {
+
+		"home": { 
+			"controller" : "doesnotexist",
+			"template": "dojox/app/tests/doh/config.html"
+		}
+
+	}
+}
diff --git a/dojox/app/tests/doh/globalizedApp/config.json b/dojox/app/tests/doh/globalizedApp/config.json
new file mode 100644
index 0000000..33fa4ec
--- /dev/null
+++ b/dojox/app/tests/doh/globalizedApp/config.json
@@ -0,0 +1,56 @@
+{
+	"id": "globalizedApp",
+	"name": "globalizedApp",
+	"description": "A simple app to show how to plug custom controllers",
+
+	"loaderConfig": {
+		"paths": {
+			"globalizedApp": "../dojox/app/tests/globalizedApp"
+		}
+	},
+
+	"nls": "globalizedApp/nls/app",
+
+	"modules": [
+	],
+
+	// Array of AMD modules identifiers. Controllers for the application. All the controllers defined here will be 
+	// loaded during application startup to respond to application events and controller the application logic. 
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],	
+
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+		
+	"defaultView": "home",
+
+	"views": {
+		"home": {
+			"template": "globalizedApp/home.html",
+			"nls": "globalizedApp/nls/home",
+			"dependencies":	[
+				"dojox/mobile/RoundRectList",
+				"dojox/mobile/ListItem"
+			]
+		},
+		"detail": {
+			"controller" : "globalizedApp/detail.js",
+			"template": "globalizedApp/detail.html"
+		}
+	}
+}
diff --git a/dojox/app/tests/doh/globalizedApp/index.html b/dojox/app/tests/doh/globalizedApp/index.html
new file mode 100644
index 0000000..a8e8714
--- /dev/null
+++ b/dojox/app/tests/doh/globalizedApp/index.html
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
+		<meta name="apple-mobile-web-app-capable" content="yes" /> 
+		<title>Globalized Model App Test</title>
+		<link href="../../../../mobile/themes/iphone/base.css" rel="stylesheet">
+		<style>
+			html,body {
+				width: 100%;
+				height: 100%;
+				background: #eee;
+				font-family: arial;
+				color: #333;
+				overflow: hidden;
+				margin: 0;
+				padding: 0;
+				visibility: visible;
+			}
+
+			#splash {
+				width: 90%;
+				height: 90%;
+				margin: auto;
+				overflow: hidden;
+				border: 2px solid green;
+				color: #333;
+				text-align: center;
+			}
+
+		</style>
+		<script type="text/javascript">
+			dojoConfig = {
+				parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+                mblAlwaysHideAddressBar: false,	
+				async:1,
+				app: {debugApp: 0}  // set debugApp to log app transitions and view activate/deactivate
+			};
+		</script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
+
+		<script>
+            // the actual  launcher
+            require(["../../globalizedApp/globalizedApp.js"], function(){});
+        </script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/topic",
+				"dojo/_base/lang",
+				"dojo/dom",
+				"dojox/mobile/TransitionEvent",				
+				"dijit/registry"
+					], function(doh, topic, lang, dom, TransitionEvent, registry) {
+						var events = [];
+
+						var getLabelfromWid = function(wid, indx1, indx2){
+							var val = wid.labelNode.innerText || wid.labelNode.firstChild.nodeValue || "";
+							val = lang.trim(val);
+							if(indx2){
+								val = val.substring(indx1,indx2)
+							}
+							return val;
+						};
+
+						var getLabelfromDom = function(node, indx1, indx2){
+							var val = node.innerText || node.firstChild.nodeValue || "";
+							val = lang.trim(val);
+							if(indx2){
+								val = val.substring(indx1,indx2)
+							}
+							return val;
+						};
+
+						topic.subscribe("/app/status", lang.hitch(this, function(newStatus) {
+							events.push(newStatus);
+							if (newStatus == 2) {
+								var listItem_0TestStr = "Label Zero";
+								var listItem_1TestStr = "Label One";
+								doh.register("Test-GlobalizedApp", [{
+									// Test initial listitem labels
+									name : "initial-listItem-labels",
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+											var ListItem_0Label = registry.byId("dojox_mobile_ListItem_0");
+											if(ListItem_0Label){
+												var lab = getLabelfromWid(ListItem_0Label,0,listItem_0TestStr.length); 
+												doh.is(lab, listItem_0TestStr);
+											}else{
+												throw new Error("In initial-listItem-labels ListItem_0Label not found."); 
+											}
+											var ListItem_1Label = registry.byId("dojox_mobile_ListItem_1");
+											if(ListItem_1Label){
+												doh.is(getLabelfromWid(ListItem_1Label,0,listItem_1TestStr.length), listItem_1TestStr);
+											}else{
+												throw new Error("In initial-listItem-labels ListItem_1Label not found."); 
+											}
+											return dfd.callback(true);
+										}, 500);
+										return dfd;
+									}
+								}, {
+									// Test first transition
+									name : "transition-test-1",
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+										// transition to first li
+											var liWidget = registry.byId("dojox_mobile_ListItem_2");
+											var ev = new TransitionEvent(liWidget.domNode, liWidget.params.transitionOptions);
+											ev.dispatch();
+											return dfd.callback(true);
+										}, 500);
+									}
+								}, {
+									// Test global data 1
+									name : "global-data-test-1",
+									timeout: 4000,
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+											var d = dom.byId("label");
+											if(d){
+												var globalOutput = "Home-foo";
+												var lab = getLabelfromDom(d,0,globalOutput.length);
+												doh.is(globalOutput, lab, "label should be of Home-foo");
+											}else{
+												throw new Error("In global-data-test-1 label should be of Home-foo.");
+											}
+											return dfd.callback(true);
+										}, 2000);
+										return dfd;
+									}
+								}, {
+									// Test back transition
+									name : "transition-back-1",
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										if(history){
+											history.back();
+											setTimeout(function() {
+												doh.t(globalizedApp.children["globalizedApp_home"], "globalizedApp_home viewShowing should be true");
+												return dfd.callback(true);
+											}, 500);
+										}
+									}
+								}]);
+
+								doh.run();
+							}
+						}));
+
+					});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/doh/hasConfigTest/config.json b/dojox/app/tests/doh/hasConfigTest/config.json
new file mode 100644
index 0000000..db6f8d8
--- /dev/null
+++ b/dojox/app/tests/doh/hasConfigTest/config.json
@@ -0,0 +1,72 @@
+{
+	"id": "testApp",
+	"name": "Test App",
+	"description": "A testApp",
+	"splash": "splash",
+
+	"dependencies": [
+	],
+
+	"modules": [
+	],
+	
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],
+
+	// These configTest... lines are only used for the doh test, this is not typical for a config
+	"configTestSetTrueInHas": "FAILED",
+	"configTestNotSetInHas": "InitOk",
+	"configTestTablet": "No",
+	"configTestPhone": "No",
+	"configTestPhoneIosOrAndroid": "No",
+	"configTestTabletIosOrAndroid": "No",
+
+	// These configTest... lines are only used for the doh test, this is not typical for a config
+	"has" : {
+		"testTrue" : {
+			"configTestSetTrueInHas": "SetInHasOk"
+		},
+		"testFalse" : {
+			"configTestNotSetInHas": "FAILED"
+		},
+		"phone,ios,android" : {
+			"configTestPhoneIosOrAndroid": "Yes"
+		},
+		"ios,android,!phone" : {
+			"configTestTabletIosOrAndroid": "Yes"
+		},
+		"phone" : {
+			"configTestPhone": "Yes",
+			"isTablet" : false
+		},
+		"!phone" : {
+			"configTestTablet": "Yes",
+			"isTablet" : true
+		},
+		"ie" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+	"defaultView": "home",
+
+	"defaultTransition": "slide",
+
+	"views": {
+
+		"home": { 
+			"template": "dojox/app/tests/doh/config.html"
+		}
+
+	}
+}
diff --git a/dojox/app/tests/doh/hasConfigTest/index.html b/dojox/app/tests/doh/hasConfigTest/index.html
new file mode 100644
index 0000000..de964f5
--- /dev/null
+++ b/dojox/app/tests/doh/hasConfigTest/index.html
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
+		<meta name="apple-mobile-web-app-capable" content="yes" /> 
+		<title>Lifecycle and Controller Test</title> 
+		<script type="text/javascript">
+			dojoConfig = {
+				parseOnLoad: false,
+				async:1,
+				app: {debugApp: 0}  // set debugApp to log app transitions and view activate/deactivate
+			};
+		</script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
+
+		<script>
+            // the actual  launcher
+            require(["./modelApp.js"], function(){});
+        </script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/topic",
+				"dojo/_base/lang",
+				"dojox/mobile/TransitionEvent",				
+				"dojo/parser",
+				"dojo/when",
+ 				"dojox/app/controllers/Load", 
+ 				"dojox/app/controllers/Transition", 
+ 				"dojox/app/controllers/Layout",
+  				"dojox/app/controllers/History",
+  				"dojox/app/controllers/HistoryHash",
+  				"dojox/app/utils/config", 
+				"dojox/json/ref", 
+				"dojo/sniff",
+				"dojo/text!./config.json"  				
+					], function(doh, topic, lang, TransitionEvent, parser, when, Load, Transition, Layout, History, HistoryHash,
+						configUtil, jsonRef, has, config) {
+						var originalConfig = jsonRef.fromJson(config);
+						var isTablet = false;
+						var width = window.innerWidth || document.documentElement.clientWidth;
+						if(width > 600){
+							isTablet = true;
+						}
+
+						has.add("testTrue", true);
+						has.add("tablet", isTablet);
+						has.add("phone", !isTablet);
+						has.add("notIE", !has("ie"));
+						
+						// configUtil.configProcessHas is only called here to test the configProcessHas, normally the app does not call it directly
+						config = configUtil.configProcessHas(originalConfig);
+						doh.register("Test-HasConfig", [{
+							name : "test-HasConfig",
+							runTest : function(t) {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									t.assertEqual(config.controllers[0], "dojox/app/controllers/Load");
+									t.assertEqual(config.configTestSetTrueInHas, "SetInHasOk");
+									t.assertEqual(config.configTestNotSetInHas, "InitOk");
+									if(config.isTablet){
+										t.assertEqual(config.configTestTablet, "Yes");
+										t.assertEqual(config.configTestPhone, "No");
+									}else{
+										t.assertEqual(config.configTestTablet, "No");
+										t.assertEqual(config.configTestPhone, "Yes");
+									}
+									return dfd.callback(true);
+								}, 500);
+								return dfd;
+							}
+						}, {
+							// Test controllers
+							name : "test-Controllers",
+							runTest : function(t) {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									// test controllers
+									t.assertEqual(4, config.controllers.length);
+									if(has("ie")){
+										t.assertEqual(config.controllers[3], "dojox/app/controllers/HistoryHash");										
+										t.assertTrue(testApp.controllers[3] instanceof HistoryHash);
+									}else{
+										t.assertEqual(config.controllers[3], "dojox/app/controllers/History");										
+										t.assertTrue(testApp.controllers[3] instanceof History);
+									}
+									return dfd.callback(true);
+								}, 500);
+								return dfd;
+							}
+						}]);
+
+						doh.run();
+						
+
+					});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/doh/hasConfigTest/modelApp.js b/dojox/app/tests/doh/hasConfigTest/modelApp.js
new file mode 100644
index 0000000..d818614
--- /dev/null
+++ b/dojox/app/tests/doh/hasConfigTest/modelApp.js
@@ -0,0 +1,15 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojox/app/utils/config", "dojo/sniff"],
+function(win, Application, jsonRef, config, configUtil, has){
+	var originalConfig = jsonRef.fromJson(config);
+	var isTablet = false;
+	var width = window.innerWidth || document.documentElement.clientWidth;
+	if(width > 600){
+		isTablet = true;
+	}
+
+	has.add("testTrue", true);
+	has.add("phone", !isTablet);
+						
+	// using originalConfig here because main.js will automatically process the has
+	Application(originalConfig);
+});
diff --git a/dojox/app/tests/doh/helpers.js b/dojox/app/tests/doh/helpers.js
new file mode 100644
index 0000000..adcc162
--- /dev/null
+++ b/dojox/app/tests/doh/helpers.js
@@ -0,0 +1,73 @@
+// Helper methods for automated testing
+
+function isVisible(/*dijit._Widget || DomNode*/ node){
+	// summary:
+	//		Return true if node/widget is visible
+	var p;
+	if(node.domNode){ node = node.domNode; }
+	return (dojo.style(node, "display") != "none") &&
+		(dojo.style(node, "visibility") != "hidden") &&
+		(p = dojo.position(node, true), p.y + p.h >= 0 && p.x + p.w >= 0 && p.h && p.w);
+}
+
+function isHidden(/*dijit._Widget || DomNode*/ node){
+	// summary:
+	//		Return true if node/widget is hidden
+	var p;
+	if(node.domNode){ node = node.domNode; }
+	return (dojo.style(node, "display") == "none") ||
+		(dojo.style(node, "visibility") == "hidden") ||
+		(p = dojo.position(node, true), p.y + p.h < 0 || p.x + p.w < 0 || p.h <= 0 || p.w <= 0);
+}
+
+function innerText(/*DomNode*/ node){
+	// summary:
+	//		Browser portable function to get the innerText of specified DOMNode
+	return node.textContent || node.innerText || "";
+}
+
+function tabOrder(/*DomNode?*/ root){
+	// summary:
+	//		Return all tab-navigable elements under specified node in the order that
+	//		they will be visited (by repeated presses of the tab key)
+
+	var elems = [];
+
+	function walkTree(/*DOMNode*/parent){
+		dojo.query("> *", parent).forEach(function(child){
+			// Skip hidden elements, and also non-HTML elements (those in custom namespaces) in IE,
+			// since show() invokes getAttribute("type"), which crash on VML nodes in IE.
+			if((dojo.isIE && child.scopeName!=="HTML") || !dijit._isElementShown(child)){
+				return;
+			}
+
+			if(dijit.isTabNavigable(child)){
+				elems.push({
+					elem: child,
+					tabIndex: dojo.hasAttr(child, "tabIndex") ? dojo.attr(child, "tabIndex") : 0,
+					pos: elems.length
+				});
+			}
+			if(child.nodeName.toUpperCase() != 'SELECT'){
+				walkTree(child);
+			}
+		});
+	}
+	walkTree(root || dojo.body());
+
+	elems.sort(function(a, b){
+		return a.tabIndex != b.tabIndex ? a.tabIndex - b.tabIndex : a.pos - b.pos;
+	});
+	return dojo.map(elems, function(elem){ return elem.elem; });
+}
+
+
+function onFocus(func){
+	// summary:
+	//		On the next change of focus, and after widget has had time to react to focus event,
+	//		call func(node) with the newly focused node
+	var handle = dojo.subscribe("focusNode", function(node){
+		dojo.unsubscribe(handle);
+		setTimeout(function(){ func(node); }, 0);
+	});
+}
\ No newline at end of file
diff --git a/dojox/app/tests/doh/layoutApp/config.json b/dojox/app/tests/doh/layoutApp/config.json
new file mode 100644
index 0000000..63d0cf6
--- /dev/null
+++ b/dojox/app/tests/doh/layoutApp/config.json
@@ -0,0 +1,135 @@
+{
+	"id": "layoutApp",
+	"name": "layout App",
+	"description": "A layout App",
+	"splash": "splash",
+
+	"loaderConfig": {
+		"paths": {
+			"layoutApp": "../dojox/app/tests/layoutApp"
+		}
+	},
+
+	"dependencies": [
+		"dojox/app/utils/simpleModel",
+		"dojox/mobile/_base",
+		"dojox/mobile/compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/Heading",
+		"dojo/store/Memory",
+		"dojo/store/Observable",		
+		"dojox/mobile/EdgeToEdgeStoreList",
+		"dojox/mobile/View",
+		"dojox/app/widgets/Container"
+	],
+
+	"modules": [],
+	
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],
+	
+	//stores we are using
+	"stores": {
+		"namesStore":{
+			"type": "dojo/store/Memory",
+			"params": {
+				"data": "modelApp.names"
+			}
+		},
+		"listStore":{
+			"type": "dojo/store/Memory",
+			"observable": true,
+			"params": {
+				"data": "modelApp.listData"
+			}
+		}
+	},
+
+	//models and instantiation parameters for the models. Including 'type' as a property allows
+	//one to override the class that will be used for the model.
+	"models": {
+	   "names": {
+			"modelLoader": "dojox/app/utils/simpleModel",
+			"params":{
+				"store": {"$ref":"#stores.namesStore"}
+			}
+	   }
+	},
+
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+	"template": "layoutApp/views/navigation.html",
+
+	//the name of the view to load when the app is initialized.
+	"defaultView": "simple",
+
+	// these are the possible defaultTransitions, 
+	// the defaultTransition is only used if transition is not set in the config and it is not set or defaulted on the transitionEvent
+	//"defaultTransition": "slide",
+	//"defaultTransition": "none",
+	//"defaultTransition": "fade",
+	//"defaultTransition": "flip",     // Note: flip does not work with a BorderLayout Controller
+
+	// these are the possible transitions, 
+	// if a transition is set on a view or parent it will override the transition set on the transitionEvent or the defaultTransition in the config.
+	//"transition": "slide",
+	//"transition": "none",
+	//"transition": "fade",
+	"transition": "flip",
+
+	"views": {
+		"simple":{
+			"controller" : "layoutApp/views/simple.js",
+			"template": "layoutApp/views/simple.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		},
+
+		//list view, include list view and details view
+		"listMain": {
+			"defaultView": "list",
+			"transition": "fade",
+
+			"views": {
+				"list":{
+					"controller" : "layoutApp/views/list.js",
+					"transition": "slide",
+					"template": "layoutApp/views/list.html",
+					"dependencies":["dojox/mobile/TextBox"]
+				},
+				"itemDetails":{
+					"controller" : "layoutApp/views/itemDetails.js",
+					"transition": "flip",
+					"template": "layoutApp/views/itemDetails.html",
+					"dependencies":["dojox/mobile/TextBox"],
+					"defaultParams": {"cursor":"2"}
+				}
+			}
+		},
+
+		"date": {
+            "controller": "layoutApp/views/date.js",
+            "template": "layoutApp/views/date.html",
+            "dependencies":["dojox/mobile/DatePicker", "dojox/mobile/Opener"]
+		}
+	}	
+}
diff --git a/dojox/app/tests/doh/layoutApp/index.html b/dojox/app/tests/doh/layoutApp/index.html
new file mode 100644
index 0000000..1f309d2
--- /dev/null
+++ b/dojox/app/tests/doh/layoutApp/index.html
@@ -0,0 +1,146 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
+		<meta name="apple-mobile-web-app-capable" content="yes" /> 
+		<title>Layout App</title>
+		<link type="text/css" href="../../layoutApp/css/layoutApp.css" rel="stylesheet" />
+		<link href="../../../../mobile/themes/iphone/base.css" rel="stylesheet">
+		<style>
+			html,body {
+				width: 100%;
+				height: 100%;
+				background: #eee;
+				font-family: arial;
+				color: #333;
+				overflow: hidden;
+				margin: 0;
+				padding: 0;
+				visibility: visible;
+			}
+
+			#splash {
+				width: 90%;
+				height: 90%;
+				margin: auto;
+				overflow: hidden;
+				border: 2px solid green;
+				color: #333;
+				text-align: center;
+			}
+
+		</style>
+		<script type="text/javascript">
+			dojoConfig = {
+				parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+                mblAlwaysHideAddressBar: false,	
+				async:1,
+				app: {debugApp: 0}  // set debugApp to log app transitions and view activate/deactivate
+			};
+		</script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
+
+		<script>
+            // the actual  launcher
+            require(["../../layoutApp/layoutApp.js"], function(){});
+        </script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/topic",
+				"dojo/_base/lang",
+				"dojo/dom",
+				"dojox/mobile/TransitionEvent",				
+				"dijit/registry"
+					], function(doh, topic, lang, dom, TransitionEvent, registry) {
+						var events = [];
+
+						var getLabelfromWid = function(wid, indx1, indx2){
+							var val = wid.labelNode.innerText || wid.labelNode.firstChild.nodeValue || "";
+							val = lang.trim(val);
+							if(indx2){
+								val = val.substring(indx1,indx2)
+							}
+							return val;
+						};
+
+						topic.subscribe("/app/status", lang.hitch(this, function(newStatus) {
+							events.push(newStatus);
+							if (newStatus == 2) {
+								var listItem_0TestStr = "Simple Form Data";
+								var listItem_1TestStr = "List Data Test";
+								doh.register("Test-layoutApp1", [{
+									// Test initial values
+									name : "initial-listItem-labels",
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+											var ListItem_0Label = registry.byId("dojox_mobile_ListItem_0");
+											if(ListItem_0Label){
+												var lab = getLabelfromWid(ListItem_0Label,0,listItem_0TestStr.length); 
+												doh.is(lab, listItem_0TestStr);
+											}
+											var ListItem_1Label = registry.byId("dojox_mobile_ListItem_1");
+											if(ListItem_1Label){
+												doh.is(getLabelfromWid(ListItem_1Label,0,listItem_1TestStr.length), listItem_1TestStr);
+											}
+											var shiptostreetInput1Text = registry.byId("shiptostreetInput1");
+											if(shiptostreetInput1Text){
+												doh.is(shiptostreetInput1Text.value,"123 Valley Rd");
+											}
+											return dfd.callback(true);
+										}, 500);
+										return dfd;
+									}
+								}, {
+									// Test first transition
+									name : "transition-test-1",
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+											var liWidget = registry.byId("dojox_mobile_ListItem_1");
+											var ev = new TransitionEvent(liWidget.domNode, liWidget.params);
+											ev.dispatch();
+											return dfd.callback(true);
+										}, 500);
+									}
+								}, {
+									// Test layout data 1
+									name : "layout-data-test-1",
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+											var d = registry.byId("dojox_mobile_EdgeToEdgeCategory_2");
+											if(d){
+												doh.is("Using a dojox/mobile/EdgeToEdgeStoreList", d.domNode.innerHTML, "dojox_mobile_EdgeToEdgeCategory_2 should be set");
+											}
+											doh.t(layoutApp.children["layoutApp_listMain"], "layoutApp_listMain viewShowing should be true");
+											return dfd.callback(true);
+										}, 1000);
+										return dfd;
+									}
+								}, {
+									// Test back transition
+									name : "transition-back-1",
+									runTest : function() {
+										var dfd = new doh.Deferred();
+										if(history){
+											history.back();
+											setTimeout(function() {
+												doh.t(layoutApp.children["layoutApp_simple"], "layoutApp_simple viewShowing should be true");
+												return dfd.callback(true);
+											}, 500);
+										}
+									}
+								}]);
+								doh.run();
+							}
+						}));
+					});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/doh/lifecycleTest/config.json b/dojox/app/tests/doh/lifecycleTest/config.json
new file mode 100644
index 0000000..2dbd7f9
--- /dev/null
+++ b/dojox/app/tests/doh/lifecycleTest/config.json
@@ -0,0 +1,31 @@
+{
+	"id": "testApp",
+	"name": "Test App",
+	"description": "A testApp",
+	"splash": "splash",
+
+	"dependencies": [
+	],
+
+	"modules": [
+	],
+	
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout",
+		"dojox/app/controllers/History"
+	],
+
+	"defaultView": "home",
+
+	"defaultTransition": "slide",
+
+	"views": {
+
+		"home": { 
+			"template": "dojox/app/tests/doh/config.html"
+		}
+
+	}
+}
diff --git a/dojox/app/tests/doh/lifecycleTest/index.html b/dojox/app/tests/doh/lifecycleTest/index.html
new file mode 100644
index 0000000..8bb8d68
--- /dev/null
+++ b/dojox/app/tests/doh/lifecycleTest/index.html
@@ -0,0 +1,78 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
+		<meta name="apple-mobile-web-app-capable" content="yes" /> 
+		<title>Lifecycle and Controller Test</title> 
+		<script type="text/javascript">
+			dojoConfig = {
+				parseOnLoad: false,
+				async:1,
+				app: {debugApp: 0}  // set debugApp to log app transitions and view activate/deactivate
+			};
+		</script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
+
+		<script>
+            // the actual  launcher
+            require(["./modelApp.js"], function(){});
+        </script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/topic",
+				"dojo/_base/lang",
+				"dojox/mobile/TransitionEvent",				
+				"dojo/parser",
+				"dojo/when",
+ 				"dojox/app/controllers/Load", 
+ 				"dojox/app/controllers/Transition", 
+ 				"dojox/app/controllers/Layout",
+  				"dojox/app/controllers/History"
+					], function(doh, topic, lang, TransitionEvent, parser, when, Load, Transition, Layout, History) {
+						var events = [];
+						topic.subscribe("/app/status", lang.hitch(this, function(newStatus) {
+							events.push(newStatus);
+							if (newStatus == 2) {
+								doh.register("Test-LifeCycle App", [{
+									name : "test-LifeCycle",
+									runTest : function(t) {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+											t.assertEqual([1, 2], events);
+											// test lifecycle methods are available
+											t.assertNotEqual(null, testApp.setStatus);
+											t.assertNotEqual(null, testApp.getStatus);
+											t.assertNotEqual(null, testApp.lifecycle);
+											return dfd.callback(true);
+										}, 500);
+										return dfd;
+									}
+								}, {
+									// Test controllers
+									name : "test-Controllers",
+									runTest : function(t) {
+										var dfd = new doh.Deferred();
+										setTimeout(function() {
+											// test controllers
+											t.assertEqual(4, testApp.controllers.length);
+											t.assertTrue(testApp.controllers[0] instanceof Load);
+											t.assertTrue(testApp.controllers[1] instanceof Transition);
+											t.assertTrue(testApp.controllers[2] instanceof Layout);
+											t.assertTrue(testApp.controllers[3] instanceof History);
+											return dfd.callback(true);
+										}, 500);
+										return dfd;
+									}
+								}]);
+
+								doh.run();
+							}
+						}));
+
+					});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/doh/lifecycleTest/modelApp.js b/dojox/app/tests/doh/lifecycleTest/modelApp.js
new file mode 100644
index 0000000..916456d
--- /dev/null
+++ b/dojox/app/tests/doh/lifecycleTest/modelApp.js
@@ -0,0 +1,4 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json"],
+function(win, Application, jsonRef, config){
+	Application(jsonRef.fromJson(config));
+});
diff --git a/dojox/app/tests/doh/mediaQuery3ColumnApp/config.json b/dojox/app/tests/doh/mediaQuery3ColumnApp/config.json
new file mode 100644
index 0000000..26e72d0
--- /dev/null
+++ b/dojox/app/tests/doh/mediaQuery3ColumnApp/config.json
@@ -0,0 +1,124 @@
+{
+	"id": "MQ3ColApp",
+	"name": "mediaQuery 3 column App",
+	"description": "A mediaQuery 3 column App",
+	"splash": "splash",
+
+	"loaderConfig": {
+		"paths": {
+			"mediaQuery3ColumnApp": "../dojox/app/tests/mediaQuery3ColumnApp"
+		}
+	},
+
+	"dependencies": [
+		"dojox/mobile/_base",
+		"dojox/mobile/compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/RoundRectList",
+		"dojox/mobile/EdgeToEdgeList",
+		"dojox/mobile/Heading",
+		"dojox/mobile/ScrollableView",
+		"dojo/store/Memory",
+		"dojox/mobile/View",
+		"dojox/app/widgets/Container"
+	],
+
+	"modules": [],
+	
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/tests/mediaQuery3ColumnApp/controllers/CssLayout",
+		"dojox/app/tests/mediaQuery3ColumnApp/controllers/NavigationController"
+	],
+
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		},
+		"isInitiallySmall" : {
+			//the name of the view to load when the app is initialized.
+			"defaultView": "navLeft+navCenter+lastRight"
+		},
+		"!isInitiallySmall" : {
+			//the name of the view to load when the app is initialized.
+			"defaultView": "navLeft+mainCenter+lastRight"
+		}
+	},	
+
+
+	// these are the possilbe defaultTransitions
+	"defaultTransition": "slide",
+	//"defaultTransition": "none",
+	//"defaultTransition": "fade",
+	//"defaultTransition": "flip",     
+
+	//"transition": "flip",  //fade may have a problem     
+
+	"views": {
+		"navLeft":{
+			"constraint" : "left",
+			"controller": "mediaQuery3ColumnApp/views/nav/navigation.js",
+			"template": "mediaQuery3ColumnApp/views/nav/navigation.html",
+			"nls":      "mediaQuery3ColumnApp/nls/app"
+		},
+		"navCenter":{
+			"constraint" : "center",
+			"controller": "mediaQuery3ColumnApp/views/nav/navigation.js",
+			"template": "mediaQuery3ColumnApp/views/nav/navigation.html"
+		},
+		"mainCenter":{
+			"constraint" : "center",
+			"controller": "mediaQuery3ColumnApp/views/main/main.js",
+			"template": "mediaQuery3ColumnApp/views/main/main.html",
+			"nls":      "mediaQuery3ColumnApp/nls/app"
+		},
+		"mainCenter2":{
+			"constraint" : "center",
+			"controller": "mediaQuery3ColumnApp/views/main/main.js",
+			"template": "mediaQuery3ColumnApp/views/main/main.html"
+		},
+		"mainCenter3":{
+			"constraint" : "center",
+			"controller": "mediaQuery3ColumnApp/views/main/main.js",
+			"template": "mediaQuery3ColumnApp/views/main/main.html"
+		},
+		"mainLeft":{
+			"constraint" : "left",
+			"controller": "mediaQuery3ColumnApp/views/main/main.js",
+			"template": "mediaQuery3ColumnApp/views/main/main.html"
+		},
+		"lastRight":{
+			"constraint" : "right",
+			"controller": "mediaQuery3ColumnApp/views/last/last.js",
+			"template": "mediaQuery3ColumnApp/views/last/last.html"
+		},
+		"lastCenter":{
+			"constraint" : "center",
+			"controller" : "mediaQuery3ColumnApp/views/last/last.js",
+			"template": "mediaQuery3ColumnApp/views/last/last.html"
+		},
+		"TestInfo": {
+			"constraint" : "center",
+			"controller" : "mediaQuery3ColumnApp/views/main/TestInfo.js",
+			"template": "mediaQuery3ColumnApp/views/main/TestInfo.html"
+		},	
+		"header":{
+			"constraint" : "top",
+			"template": "mediaQuery3ColumnApp/views/header.html"
+		}
+	}	
+}
diff --git a/dojox/app/tests/doh/mediaQuery3ColumnApp/index.html b/dojox/app/tests/doh/mediaQuery3ColumnApp/index.html
new file mode 100644
index 0000000..4117c6f
--- /dev/null
+++ b/dojox/app/tests/doh/mediaQuery3ColumnApp/index.html
@@ -0,0 +1,127 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Media Query 3 Column App</title>
+		<link type="text/css" href="../../mediaQuery3ColumnApp/css/mediaQuery3ColumnApp.css" rel="stylesheet" />
+		<script type="text/javascript" src="../../../../../dojox/mobile/deviceTheme.js"></script>
+		<script type="text/javascript">
+			dojoConfig = {
+				parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+                mblAlwaysHideAddressBar: false,	
+				async:1,
+				app: {debugApp: 0}  // set debugApp to log app transitions and view activate/deactivate
+			};
+		</script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
+
+		<script>
+            // the actual  launcher
+            require(["../../mediaQuery3ColumnApp/mediaQuery3ColumnApp.js"], function(){});
+        </script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/topic",
+				"dojo/_base/lang",
+				"dojo/dom",
+				"dojox/mobile/TransitionEvent",				
+				"dijit/registry"
+			], function(doh, topic, lang, dom, TransitionEvent, registry) {
+				var events = [];
+
+				var getLabelfromWid = function(wid, indx1, indx2){
+					var val = wid.labelNode.innerText || wid.labelNode.firstChild.nodeValue || "";
+					val = lang.trim(val);
+					if(indx2){
+						val = val.substring(indx1,indx2)
+					}
+					return val;
+				};
+
+				topic.subscribe("/app/status", lang.hitch(this, function(newStatus) {
+					events.push(newStatus);
+					if (newStatus == 2) {
+						var listItem_0TestStr = "Main Option 1";
+						var listItem_1TestStr = "Main Option 2";
+						doh.register("Test-mediaQuery3ColumnApp1", [{
+							// Test initial values
+							name : "initial-listItem-labels",
+							runTest : function() {
+							var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var ListItem_0Label = registry.byId("dojox_mobile_ListItem_0");
+									if(ListItem_0Label){
+										var lab = getLabelfromWid(ListItem_0Label,0,listItem_0TestStr.length); 
+										doh.is(lab, listItem_0TestStr);
+									}
+									var ListItem_1Label = registry.byId("dojox_mobile_ListItem_1");
+									if(ListItem_1Label){
+										doh.is(getLabelfromWid(ListItem_1Label,0,listItem_1TestStr.length), listItem_1TestStr);
+									}
+									var shiptostreetInput1Text = registry.byId("shiptostreetInput1");
+									if(shiptostreetInput1Text){
+										doh.is(shiptostreetInput1Text.value,"123 Valley Rd");
+									}
+									return dfd.callback(true);
+								}, 500);
+								return dfd;
+							}
+						}, {
+							// Test first transition
+							name : "transition-test-1",
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var liWidget = registry.byId("dojox_mobile_ListItem_1");
+									var ev = new TransitionEvent(liWidget.domNode, liWidget.params);
+									MQ3ColApp.children["MQ3ColApp_navLeft"].mainOption1Clicked(ev);
+									//ev.dispatch()
+									return dfd.callback(true);
+								}, 500);
+							}
+						}, {
+							// Test layout data 1
+							name : "layout-data-test-1",
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var d = registry.byId("dojox_mobile_EdgeToEdgeCategory_0");
+									if(d){
+										doh.is("MainOption1 selected", d.domNode.innerHTML, "dojox_mobile_EdgeToEdgeCategory_0 should be set");
+									}
+									doh.t(MQ3ColApp.children["MQ3ColApp_navLeft"], "MQ3ColApp_navLeft viewShowing should be true");
+									return dfd.callback(true);
+								}, 1000);
+								return dfd;
+							}
+						}, {
+							// Test back transition
+							name : "transition-back-1",
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								if(history){
+									history.back();
+									setTimeout(function() {
+										doh.t(MQ3ColApp.children["MQ3ColApp_navLeft"], "MQ3ColApp_navLeft viewShowing should be true");
+										var d = registry.byId("dojox_mobile_EdgeToEdgeCategory_0");
+										if(d){
+											doh.is("None selected", d.domNode.innerHTML, "dojox_mobile_EdgeToEdgeCategory_0 should be None selected");
+										}
+										return dfd.callback(true);
+									}, 500);
+								}
+							}
+						}]);
+						doh.run();
+					}
+				}));
+			});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/doh/module.js b/dojox/app/tests/doh/module.js
new file mode 100755
index 0000000..fc0487f
--- /dev/null
+++ b/dojox/app/tests/doh/module.js
@@ -0,0 +1,18 @@
+define([
+	"require",
+	"doh/runner"
+], function(require, doh){
+	try{
+		var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g, "").replace(/^&/, "?");
+		// DOH
+		doh.registerUrl("dojox.app.tests.doh.lifecycleTest", require.toUrl("./lifecycleTest/" + userArgs), 999999);
+		doh.registerUrl("dojox.app.tests.doh.hasConfigTest", require.toUrl("./hasConfigTest/" + userArgs), 999999);
+		doh.registerUrl("dojox.app.tests.doh.simpleModelApp", require.toUrl("./simpleModelApp/" + userArgs), 999999);
+		doh.registerUrl("dojox.app.tests.doh.globalizedApp", require.toUrl("./globalizedApp/" + userArgs), 999999);
+		doh.registerUrl("dojox.app.tests.doh.borderLayoutApp", require.toUrl("./borderLayoutApp/" + userArgs), 999999);
+		doh.registerUrl("dojox.app.tests.doh.layoutApp", require.toUrl("./layoutApp/" + userArgs), 999999);
+		doh.registerUrl("dojox.app.tests.doh.mediaQuery3ColumnApp", require.toUrl("./mediaQuery3ColumnApp/" + userArgs), 999999);
+	}catch(e){
+		doh.debug(e);
+	}
+});
diff --git a/dojox/app/tests/doh/runErrorsTests.html b/dojox/app/tests/doh/runErrorsTests.html
new file mode 100755
index 0000000..d7b669e
--- /dev/null
+++ b/dojox/app/tests/doh/runErrorsTests.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+    <head>
+    <title>DojoX App Unit Test Runner</title>
+    <meta http-equiv="REFRESH" content="0;url=../../../../util/doh/runner.html?testModule=dojox.app.tests.doh.error&boot=../../dojox/app/tests/doh/errorDojoDef.js,../../dojo/dojo.js">
+	</head>
+    <body>
+        Redirecting to D.O.H runner.
+    </body>
+</HTML> 
diff --git a/dojox/app/tests/doh/runTests.html b/dojox/app/tests/doh/runTests.html
new file mode 100755
index 0000000..546fbe4
--- /dev/null
+++ b/dojox/app/tests/doh/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+    <head>
+    <title>DojoX App Unit Test Runner</title>
+    <meta http-equiv="REFRESH" content="0;url=../../../../util/doh/runner.html?testModule=dojox.app.tests.doh.module"></HEAD>
+    <BODY>
+        Redirecting to D.O.H runner.
+    </BODY>
+</HTML> 
diff --git a/dojox/app/tests/doh/simpleModelApp/config.json b/dojox/app/tests/doh/simpleModelApp/config.json
new file mode 100644
index 0000000..6e1894c
--- /dev/null
+++ b/dojox/app/tests/doh/simpleModelApp/config.json
@@ -0,0 +1,233 @@
+{
+	"id": "simpleModelApp",
+	"name": "Simple Model App",
+	"description": "A simple app to show how to use different types of Stores and Models",
+	"splash": "splash",
+
+	"dependencies": [
+		"dojox/mobile/_base",
+		"dojox/app/widgets/Container",
+		"dojox/mobile/compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/Heading",
+		"dojo/store/Memory",
+		"dojo/store/JsonRest",
+		"dojo/store/Memory",
+		"dojo/data/ItemFileWriteStore",
+		"dojo/store/DataStore",
+		"dojox/app/utils/simpleModel",
+		"dojox/app/utils/mvcModel",
+		"dojox/mvc/EditStoreRefListController",
+		"dojox/mvc/EditModelRefController",
+		"dojox/mobile/deviceTheme"
+	],
+	// Modules for the application.  The are basically used as the second
+	// array of mixins in a dojo.declare().  Modify the top level behavior
+	// of the application, how it processes the config or any other life cycle
+	// by creating and including one or more of these
+	"modules": [],
+		
+	// Array of AMD modules identifiers. Controllers for the application. All the controllers defined here will be 
+	// loaded during application startup to respond to application events and controller the application logic. 
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],	
+
+	//stores we are using 
+	"stores": {
+		"namesStore":{
+			"type": "dojo/store/Memory",
+			"params": {
+				"data": "modelApp.names"
+			}
+		},
+		"repeatStore":{
+			"type": "dojo/store/Memory",
+			"params": {
+				"data": "modelApp.repeatData"
+			}
+		},
+		"repeatItemStore":{
+			"type": "dojo/data/ItemFileWriteStore",
+			"params": {
+				"url": "./resources/data/repeat.json"
+			}
+		},
+		// note that a jsonRest store requires the data be in a different format...
+		"jsonStore":{
+			"type": "dojo/store/JsonRest",
+			"params": {
+				"target": "./resources/data/jsonRestRepeatData.json"
+			}
+		}
+	},
+
+	//models and instantiation parameters for the models. Including 'type' as a property allows
+	//one to override the class that will be used for the model.  By default it is dojox/mvc/mvcModel
+	"models": {
+		"namesXUnused": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"store": {"$ref":"#stores.namesStore"}
+					}
+		},
+		"repeatmodels3": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"datastore": {"$ref":"#stores.repeatItemStore"}
+					}
+		},
+		// The query param will not work with a file, but you should be able to see it passed to the service. 
+		"jsonRestModel": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"store": {"$ref":"#stores.jsonStore"},
+						"query": {"Location": "NY"}
+					}
+		}
+	},
+
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+	//the name of the scene to load when the app is initialized.
+	"defaultView": "home",
+
+	"defaultTransition": "slide",
+	//scenes are groups of views and models loaded at once	
+	"views": {
+
+		"home": {
+			"dependencies":["dojox/mobile/ListItem","dojox/mobile/RoundRectList","dojox/mobile/RoundRectCategory","dojox/mobile/Heading"],
+			"template": "../app/tests/simpleModelApp/main/main.html"
+		},
+
+		"simple":{
+			"models": {
+				"names": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/ModelRefController",
+					"params":{
+						"data": "modelApp.names"
+					}
+				}
+			},
+			"controller" : "../app/tests/simpleModelApp/simple/simple.js",
+			"template": "../app/tests/simpleModelApp/simple/simple.html",
+			"dependencies":["dojox/mobile/TextBox","dojox/mvc/Group","dojox/mvc/Repeat","dojox/mvc/Output"]
+		},
+
+		"simple2":{
+			"models": {
+				"names": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditModelRefController",
+					"params":{
+						"data": "modelApp.names"
+					}
+				},
+				"repeatmodelsXUnused": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"datastore": {"$ref":"#stores.repeatItemStore"}
+					}
+				}
+			},
+			"controller" : "../app/tests/simpleModelApp/simple/simple2.js",
+			"template": "../app/tests/simpleModelApp/simple/simple2.html",
+			"dependencies":["dojox/mobile/TextBox","dojox/mvc/Group","dojox/mvc/Repeat","dojox/mvc/Output"]
+		},
+
+		"simple3":{
+			"models": {
+				"namesXUnused": {
+					"modelLoader": "dojox/app/utils/simpleModel",
+					"params":{
+						"store": {"$ref":"#stores.namesStore"}
+					}
+				},
+				"names3": {
+					"modelLoader": "dojox/app/utils/simpleModel",
+					"params":{
+						"store": {"$ref":"#stores.namesStore"}
+					}
+				}
+			},
+			"controller" : "../app/tests/simpleModelApp/simple/simple3.js",
+			"template": "../app/tests/simpleModelApp/simple/simple3.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		},
+
+		"repeat": {
+			"models": {
+				"repeatmodels": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"store": {"$ref":"#stores.repeatStore"}
+					}
+				},
+				"repeatmodelsXUnused": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"datastore": {"$ref":"#stores.repeatItemStore"}
+					}
+				}
+			},
+			"template": "../app/tests/simpleModelApp/repeat/repeat.html",
+			"controller" : "../app/tests/simpleModelApp/repeat/repeat.js",
+			"dependencies":["dojox/mobile/TextBox","dojox/mvc/Group","dojox/mvc/Repeat","dojox/mvc/Output"]
+		},
+
+		"repeat2": {
+			"models": {
+				"repeatmodels2": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"datastore": {"$ref":"#stores.repeatItemStore"},
+						"query": {"Location": "NY"}
+					}
+				}
+			},
+			"template": "../app/tests/simpleModelApp/repeat/repeat2.html",
+			"controller" : "../app/tests/simpleModelApp/repeat/repeat2.js",
+			"dependencies":["dojox/mobile/TextBox","dojox/mvc/Group","dojox/mvc/Repeat","dojox/mvc/Output"]
+		},
+
+		"repeat3": {
+			"template": "../app/tests/simpleModelApp/repeat/repeat3.html",
+			"controller" : "../app/tests/simpleModelApp/repeat/repeat3.js",
+			"dependencies":["dojox/mobile/TextBox","dojox/mvc/Group","dojox/mvc/Repeat","dojox/mvc/Output"]
+		},
+
+		"generate": {
+			"template": "../app/tests/simpleModelApp/generate/generate.html",
+			"controller" : "../app/tests/simpleModelApp/generate/generate.js",
+			"dependencies":["dojox/mobile/TextBox", "dojox/mobile/TextArea", "dojox/mvc/Generate"]
+		}
+	}
+}
diff --git a/dojox/app/tests/doh/simpleModelApp/index.html b/dojox/app/tests/doh/simpleModelApp/index.html
new file mode 100644
index 0000000..01dc1ae
--- /dev/null
+++ b/dojox/app/tests/doh/simpleModelApp/index.html
@@ -0,0 +1,273 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
+		<meta name="apple-mobile-web-app-capable" content="yes" /> 
+		<title>Simple Model App Test</title> 
+		<link href="../../../../mobile/themes/iphone/base.css" rel="stylesheet">
+		<style>
+			html,body {
+				width: 100%;
+				height: 100%;
+				background: #eee;
+				font-family: arial;
+				color: #333;
+				overflow: hidden;
+				margin: 0;
+				padding: 0;
+				visibility: visible;
+			}
+
+			#splash {
+				width: 90%;
+				height: 90%;
+				margin: auto;
+				overflow: hidden;
+				border: 2px solid green;
+				color: #333;
+				text-align: center;
+			}
+
+		</style>
+		<script type="text/javascript">
+			dojoConfig = {
+				parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+                mblAlwaysHideAddressBar: false,	
+				async:1,
+				app: {debugApp: 0}  // set debugApp to log app transitions and view activate/deactivate
+			};
+		</script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
+
+		<script>
+            // the actual  launcher
+            require(["../../simpleModelApp/modelApp.js"], function(){});
+        </script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/topic",
+				"dojo/_base/lang",
+				"dojox/mobile/TransitionEvent",				
+				"dojo/parser",
+				"dojo/when",
+				"dojo/Stateful",
+				"dijit/registry",
+				"dojox/mvc/at"
+			], function(doh, topic, lang, TransitionEvent, parser, when, Stateful, registry, at){
+				window.at = at;
+				var events = [];
+
+				var getLabelfromWid = function(wid, indx1, indx2){
+					var val = wid.labelNode.innerText || wid.labelNode.firstChild.nodeValue || "";
+					val = lang.trim(val);
+					if(indx2){
+						val = val.substring(indx1,indx2)
+					}
+					return val;
+				};
+
+				topic.subscribe("/app/status", lang.hitch(this, function(newStatus) {
+					events.push(newStatus);
+					if (newStatus == 2) {
+						var listItem_0TestStr = "simple - Using an mvcModel (dojox/mvc/ModelRefController) with json data, no store";
+						var listItem_1TestStr = "simple2 - Using an mvcModel (dojox/mvc/EditModelRefController) with json data, no store";
+						doh.register("Test-SimpleApp", [{
+							// Test initial listitem labels
+							name : "initial-listItem-labels",
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var ListItem_0Label = registry.byId("dojox_mobile_ListItem_0");
+									if(ListItem_0Label){
+										var lab = getLabelfromWid(ListItem_0Label,0,listItem_0TestStr.length); 
+										doh.is(lab, listItem_0TestStr);
+									}else{
+										throw new Error("In initial-listItem-labels ListItem_0Label not found."); 
+									}
+									var ListItem_1Label = registry.byId("dojox_mobile_ListItem_1");
+									if(ListItem_1Label){
+										doh.is(getLabelfromWid(ListItem_1Label,0,listItem_1TestStr.length), listItem_1TestStr);
+									}else{
+										throw new Error("In initial-listItem-labels ListItem_1Label not found."); 
+									}
+									return dfd.callback(true);
+								}, 500);
+								return dfd;
+							}
+						}, {
+							// Test first transition
+							name : "transition-test-1",
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+								// transition to first li
+									var liWidget = registry.byId("dojox_mobile_ListItem_0");
+									var ev = new TransitionEvent(liWidget.domNode, liWidget.params);
+									ev.dispatch();
+									return dfd.callback(true);
+								}, 500);
+							}
+						}, {
+							// Test simple view 1
+							name : "simple-mvc-test-1",
+							timeout: 4000,
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var wid = registry.byId("streetInput");
+									if(wid){
+										doh.is("123 Valley Rd", wid.get("value"), "Street should be of ShipTo");
+									}else{
+										throw new Error("In simple-mvc-test-1 streetInput not found.");
+										//console.warn("In simple-mvc-test-1 streetInput not found."); 
+									}
+									var wid = registry.byId("cityInput");
+									if(wid){
+										doh.is("Katonah", wid.get("value"), "City should be of ShipTo");
+									}else{
+										throw new Error("In simple-mvc-test-1 cityInput not found.");
+										//console.warn("In simple-mvc-test-1 cityInput not found."); 
+									}
+									return dfd.callback(true);
+								}, 1000);
+								return dfd;
+							}
+						}, {
+							// Test switch to billto
+							name : "simple-mvc-test-2",
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var group = registry.byId("addrGroup");
+									group.set("target", at("rel:", "BillTo"));
+									doh.is("17 Skyline Dr", registry.byId("streetInput").get("value"), "Street should be of BillTo");
+									doh.is("Hawthorne", registry.byId("cityInput").get("value"), "City should be of BillTo");
+									return dfd.callback(true);
+								}, 500);
+								return dfd;
+							}
+						}, {
+							// Test switch back to home
+							name : "backToHome1",
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var backHeader = registry.byId("dojox_mobile_Heading_1");
+									var transOpts = {
+										viewid : "home",
+										reverse : true,
+										url : "#home" // this is optional if not set it will be created from target
+									};
+									var ev = new TransitionEvent(backHeader.domNode, transOpts);
+									ev.dispatch();
+									return dfd.callback(true);
+								}, 500);
+								return dfd;
+							}
+						}, {
+							// Test verify back to at home
+							name : "testbackToHome1",
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var ListItem_0Label = registry.byId("dojox_mobile_ListItem_0");
+									if(ListItem_0Label){
+										doh.is(getLabelfromWid(ListItem_0Label,0,82), listItem_0TestStr);
+									}else{
+										throw new Error("In testbackToHome1 ListItem_0Label not found."); 
+									}
+									var ListItem_1Label = registry.byId("dojox_mobile_ListItem_1");
+									if(ListItem_1Label){
+										doh.is(getLabelfromWid(ListItem_1Label,0,87), listItem_1TestStr);
+									}else{
+										throw new Error("In testbackToHome1 ListItem_1Label not found."); 
+									}
+									return dfd.callback(true);
+								}, 500);
+								return dfd;
+							}
+						}, {
+							// Test second transition
+							name : "transition-test-2",
+							runTest : function() {
+								// transition to first li
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var liWidget = registry.byId("dojox_mobile_ListItem_3");
+									var ev = new TransitionEvent(liWidget.domNode, liWidget.params);
+									ev.dispatch();
+									return dfd.callback(true);
+								}, 500);
+								return dfd;
+							}
+						}, {
+							// Test verify back to at home
+							name : "testInputs1",
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var wid = registry.byId("nameInput0");
+									if (wid) {
+										doh.is("Anne", registry.byId("nameInput0").get("value"), "NameInput0 should be Anne");
+										doh.is("Anne", registry.byId("firstInput").get("value"), "firstInput should be Anne");
+									}
+									return dfd.callback(true);
+								}, 500);
+								return dfd;
+							}
+						}, {
+							// Test switch back to home
+							name : "backToHome2",
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var backHeader = registry.byId("dojox_mobile_Heading_1");
+									var transOpts = {
+										viewid : "home",
+										reverse : true,
+										url : "#home" // this is optional if not set it will be created from target
+									};
+									var ev = new TransitionEvent(backHeader.domNode, transOpts);
+									ev.dispatch();
+									return dfd.callback(true);
+								}, 500);
+								return dfd;
+							}
+						}, {
+							// Test verify back to at home
+							name : "testbackToHome",
+							runTest : function() {
+								var dfd = new doh.Deferred();
+								setTimeout(function() {
+									var ListItem_0Label = registry.byId("dojox_mobile_ListItem_0");
+									if(ListItem_0Label){
+										doh.is(getLabelfromWid(ListItem_0Label,0,82), listItem_0TestStr);
+									}else{
+										throw new Error("In testbackToHome ListItem_0Label not found."); 
+									}
+									var ListItem_1Label = registry.byId("dojox_mobile_ListItem_1");
+									if(ListItem_1Label){
+										doh.is(getLabelfromWid(ListItem_1Label,0,87), listItem_1TestStr);
+									}else{
+										throw new Error("In testbackToHome ListItem_1Label not found."); 
+									}
+									return dfd.callback(true);
+								}, 500);
+								return dfd;
+							}
+						}]);
+
+						doh.run();
+					}
+				}));
+
+			});
+		</script>
+	</head>
+	<body>
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+	</body>
+</html>
diff --git a/dojox/app/tests/doh/simpleModelApp/resources/data/jsonRestRepeatData.json b/dojox/app/tests/doh/simpleModelApp/resources/data/jsonRestRepeatData.json
new file mode 100644
index 0000000..d0cd4c7
--- /dev/null
+++ b/dojox/app/tests/doh/simpleModelApp/resources/data/jsonRestRepeatData.json
@@ -0,0 +1,102 @@
+[ 
+                    {
+                        "Serial"  : "A111",
+                        "First"   : "Anne",
+                        "Last"    : "Ackerman",
+                        "Location": "NY",
+                        "Office"  : "1S76",
+                        "Email"   : "a.a at test.com",
+                        "Tel"     : "123-764-8237",
+                        "Fax"     : "123-764-8228"
+                    },
+                    {
+                        "Serial"  : "B111",
+                        "First"   : "Ben",
+                        "Last"    : "Beckham",
+                        "Location": "NY",
+                        "Office"  : "5N47",
+                        "Email"   : "b.b at test.com",
+                        "Tel"     : "123-764-8599",
+                        "Fax"     : "123-764-8600"
+                    },
+                    {
+                        "Serial"  : "C111",
+                        "First"   : "Chad",
+                        "Last"    : "Chapman",
+                        "Location": "CA",
+                        "Office"  : "1278",
+                        "Email"   : "c.c at test.com",
+                        "Tel"     : "408-764-8237",
+                        "Fax"     : "408-764-8228"
+                    },
+                    {
+                        "Serial"  : "D111",
+                        "First"   : "David",
+                        "Last"    : "Durham",
+                        "Location": "NJ",
+                        "Office"  : "C12",
+                        "Email"   : "d.d at test.com",
+                        "Tel"     : "514-764-8237",
+                        "Fax"     : "514-764-8228"
+                    },
+                    {
+                        "Serial"  : "E111",
+                        "First"   : "Emma",
+                        "Last"    : "Eklof",
+                        "Location": "NY",
+                        "Office"  : "4N76",
+                        "Email"   : "e.e at test.com",
+                        "Tel"     : "123-764-1234",
+                        "Fax"     : "123-764-4321"
+                    },
+                    {
+                        "Serial"  : "F111",
+                        "First"   : "Fred",
+                        "Last"    : "Fisher",
+                        "Location": "NJ",
+                        "Office"  : "V89",
+                        "Email"   : "f.f at test.com",
+                        "Tel"     : "514-764-8567",
+                        "Fax"     : "514-764-8000"
+                    },
+                    {
+                        "Serial"  : "G111",
+                        "First"   : "George",
+                        "Last"    : "Garnett",
+                        "Location": "NY",
+                        "Office"  : "7S11",
+                        "Email"   : "gig at test.com",
+                        "Tel"     : "123-999-8599",
+                        "Fax"     : "123-999-8600"
+                    },
+                    {
+                        "Serial"  : "H111",
+                        "First"   : "Hunter",
+                        "Last"    : "Huffman",
+                        "Location": "CA",
+                        "Office"  : "6532",
+                        "Email"   : "h.h at test.com",
+                        "Tel"     : "408-874-8237",
+                        "Fax"     : "408-874-8228"
+                    },
+                    {
+                        "Serial"  : "I111",
+                        "First"   : "Irene",
+                        "Last"    : "Ira",
+                        "Location": "NJ",
+                        "Office"  : "F09",
+                        "Email"   : "i.i at test.com",
+                        "Tel"     : "514-764-6532",
+                        "Fax"     : "514-764-7300"
+                    },
+                    {
+                        "Serial"  : "J111",
+                        "First"   : "John",
+                        "Last"    : "Jacklin",
+                        "Location": "CA",
+                        "Office"  : "6701",
+                        "Email"   : "j.j at test.com",
+                        "Tel"     : "408-764-1234",
+                        "Fax"     : "408-764-4321"
+                    }
+]
diff --git a/dojox/app/tests/doh/simpleModelApp/resources/data/names2.json b/dojox/app/tests/doh/simpleModelApp/resources/data/names2.json
new file mode 100644
index 0000000..8973b0b
--- /dev/null
+++ b/dojox/app/tests/doh/simpleModelApp/resources/data/names2.json
@@ -0,0 +1,11 @@
+{
+  "identifier": "id",
+  "items": [ 
+	{
+		"id" : "1",
+		"Serial": "360324",
+		"First": "John",
+		"Last": "Doe",
+		"Email": "jdoe at us.ibm.com"
+	}]
+}
diff --git a/dojox/app/tests/doh/simpleModelApp/resources/data/repeat.json b/dojox/app/tests/doh/simpleModelApp/resources/data/repeat.json
new file mode 100644
index 0000000..191b80b
--- /dev/null
+++ b/dojox/app/tests/doh/simpleModelApp/resources/data/repeat.json
@@ -0,0 +1,105 @@
+{
+  "identifier": "Serial",
+   "items": [ 
+                    {
+                        "Serial"  : "A111",
+                        "First"   : "Anne",
+                        "Last"    : "Ackerman",
+                        "Location": "NY",
+                        "Office"  : "1S76",
+                        "Email"   : "a.a at test.com",
+                        "Tel"     : "123-764-8237",
+                        "Fax"     : "123-764-8228"
+                    },
+                    {
+                        "Serial"  : "B111",
+                        "First"   : "Ben",
+                        "Last"    : "Beckham",
+                        "Location": "NY",
+                        "Office"  : "5N47",
+                        "Email"   : "b.b at test.com",
+                        "Tel"     : "123-764-8599",
+                        "Fax"     : "123-764-8600"
+                    },
+                    {
+                        "Serial"  : "C111",
+                        "First"   : "Chad",
+                        "Last"    : "Chapman",
+                        "Location": "CA",
+                        "Office"  : "1278",
+                        "Email"   : "c.c at test.com",
+                        "Tel"     : "408-764-8237",
+                        "Fax"     : "408-764-8228"
+                    },
+                    {
+                        "Serial"  : "D111",
+                        "First"   : "David",
+                        "Last"    : "Durham",
+                        "Location": "NJ",
+                        "Office"  : "C12",
+                        "Email"   : "d.d at test.com",
+                        "Tel"     : "514-764-8237",
+                        "Fax"     : "514-764-8228"
+                    },
+                    {
+                        "Serial"  : "E111",
+                        "First"   : "Emma",
+                        "Last"    : "Eklof",
+                        "Location": "NY",
+                        "Office"  : "4N76",
+                        "Email"   : "e.e at test.com",
+                        "Tel"     : "123-764-1234",
+                        "Fax"     : "123-764-4321"
+                    },
+                    {
+                        "Serial"  : "F111",
+                        "First"   : "Fred",
+                        "Last"    : "Fisher",
+                        "Location": "NJ",
+                        "Office"  : "V89",
+                        "Email"   : "f.f at test.com",
+                        "Tel"     : "514-764-8567",
+                        "Fax"     : "514-764-8000"
+                    },
+                    {
+                        "Serial"  : "G111",
+                        "First"   : "George",
+                        "Last"    : "Garnett",
+                        "Location": "NY",
+                        "Office"  : "7S11",
+                        "Email"   : "gig at test.com",
+                        "Tel"     : "123-999-8599",
+                        "Fax"     : "123-999-8600"
+                    },
+                    {
+                        "Serial"  : "H111",
+                        "First"   : "Hunter",
+                        "Last"    : "Huffman",
+                        "Location": "CA",
+                        "Office"  : "6532",
+                        "Email"   : "h.h at test.com",
+                        "Tel"     : "408-874-8237",
+                        "Fax"     : "408-874-8228"
+                    },
+                    {
+                        "Serial"  : "I111",
+                        "First"   : "Irene",
+                        "Last"    : "Ira",
+                        "Location": "NJ",
+                        "Office"  : "F09",
+                        "Email"   : "i.i at test.com",
+                        "Tel"     : "514-764-6532",
+                        "Fax"     : "514-764-7300"
+                    },
+                    {
+                        "Serial"  : "J111",
+                        "First"   : "John",
+                        "Last"    : "Jacklin",
+                        "Location": "CA",
+                        "Office"  : "6701",
+                        "Email"   : "j.j at test.com",
+                        "Tel"     : "408-764-1234",
+                        "Fax"     : "408-764-4321"
+                    }
+                ]
+}
diff --git a/dojox/app/tests/globalizedApp/build.profile.js b/dojox/app/tests/globalizedApp/build.profile.js
new file mode 100755
index 0000000..28cd403
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/build.profile.js
@@ -0,0 +1,31 @@
+require(["dojox/app/build/buildControlApp"], function(bc){
+});
+
+var profile = {
+	basePath: "..",
+	releaseDir: "./globalizedApp/release",
+	action: "release",
+	cssOptimize: "comments",
+	packages:[{
+		name: "dojo",
+		location: "../../../dojo"
+	},{
+		name: "dijit",
+		location: "../../../dijit"
+	},{
+		name: "globalizedApp",
+		location: "../../../dojox/app/tests/globalizedApp",
+		destLocation: "./dojox/app/tests/globalizedApp"
+	},{
+		name: "dojox",
+		location: "../../../dojox"
+	}],
+	layers: {
+		"globalizedApp/globalizedApp": {
+			include: [ "globalizedApp/index.html" ]
+		}
+	}
+};
+
+
+
diff --git a/dojox/app/tests/globalizedApp/config.json b/dojox/app/tests/globalizedApp/config.json
new file mode 100755
index 0000000..33fa4ec
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/config.json
@@ -0,0 +1,56 @@
+{
+	"id": "globalizedApp",
+	"name": "globalizedApp",
+	"description": "A simple app to show how to plug custom controllers",
+
+	"loaderConfig": {
+		"paths": {
+			"globalizedApp": "../dojox/app/tests/globalizedApp"
+		}
+	},
+
+	"nls": "globalizedApp/nls/app",
+
+	"modules": [
+	],
+
+	// Array of AMD modules identifiers. Controllers for the application. All the controllers defined here will be 
+	// loaded during application startup to respond to application events and controller the application logic. 
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],	
+
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+		
+	"defaultView": "home",
+
+	"views": {
+		"home": {
+			"template": "globalizedApp/home.html",
+			"nls": "globalizedApp/nls/home",
+			"dependencies":	[
+				"dojox/mobile/RoundRectList",
+				"dojox/mobile/ListItem"
+			]
+		},
+		"detail": {
+			"controller" : "globalizedApp/detail.js",
+			"template": "globalizedApp/detail.html"
+		}
+	}
+}
diff --git a/dojox/app/tests/globalizedApp/detail.html b/dojox/app/tests/globalizedApp/detail.html
new file mode 100755
index 0000000..6107114
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/detail.html
@@ -0,0 +1,3 @@
+<div class="view mblView">
+	<span id="label"></span>
+</div>
diff --git a/dojox/app/tests/globalizedApp/detail.js b/dojox/app/tests/globalizedApp/detail.js
new file mode 100755
index 0000000..cc926db
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/detail.js
@@ -0,0 +1,8 @@
+define(["dojo/dom"], function(dom){
+	return {
+		beforeActivate: function(previousView, data){
+			dom.byId("label").innerHTML = this.nls[previousView.name] + (data ? ("-" + data) : "");
+
+		}
+	}
+});
\ No newline at end of file
diff --git a/dojox/app/tests/globalizedApp/globalizedApp.js b/dojox/app/tests/globalizedApp/globalizedApp.js
new file mode 100755
index 0000000..134174f
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/globalizedApp.js
@@ -0,0 +1,6 @@
+require(["dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojo/sniff"],
+function(Application, jsonRef, config, has){
+	var cfg = jsonRef.fromJson(config);
+	has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+	Application(cfg);
+});
diff --git a/dojox/app/tests/globalizedApp/globalizedApp.profile.js b/dojox/app/tests/globalizedApp/globalizedApp.profile.js
new file mode 100755
index 0000000..1f8b8bf
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/globalizedApp.profile.js
@@ -0,0 +1,13 @@
+var profile = {
+	resourceTags:{
+		declarative: function(filename){
+	 		return /\.html?$/.test(filename); // tags any .html or .htm files as declarative
+	 	},
+		amd: function(filename){
+			return /\.js$/.test(filename);
+		},
+		copyOnly: function(filename, mid){
+			return mid == "globalizedApp/build.profile";
+		}
+	}
+};
diff --git a/dojox/app/tests/globalizedApp/home.html b/dojox/app/tests/globalizedApp/home.html
new file mode 100755
index 0000000..580d155
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/home.html
@@ -0,0 +1,11 @@
+<div class="view mblView">
+    <ul data-dojo-type="dojox/mobile/RoundRectList">
+		<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="'clickable':true, 'label': '${nls.label0}', target: 'detail'">
+  		</li>
+        <li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="'clickable':true, 'label': '${nls.label1}', target: 'detail'">
+        </li>
+        <li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="'clickable':true, target: 'detail', transitionOptions: { data: 'foo' }">
+			${nls.label2}
+        </li>
+    </ul>
+</div>
diff --git a/dojox/app/tests/globalizedApp/index.html b/dojox/app/tests/globalizedApp/index.html
new file mode 100755
index 0000000..aa2dd0e
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/index.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
+		<meta name="apple-mobile-web-app-capable" content="yes" /> 
+		<title>Globalized App Test</title>
+		<style>
+			html,body {
+				width: 100%;
+				height: 100%;
+				background: #eee;
+				font-family: arial;
+				color: #333;
+				overflow: hidden;
+				margin: 0;
+				padding: 0;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"></script>
+		<script type="text/javascript" data-dojo-config="parseOnLoad: false, async: true" src="../../../../dojo/dojo.js"></script>
+		<script>
+			require(["./globalizedApp.js"]);
+        </script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/globalizedApp/nls/app.js b/dojox/app/tests/globalizedApp/nls/app.js
new file mode 100755
index 0000000..3eff041
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/nls/app.js
@@ -0,0 +1,7 @@
+define({
+	root: {
+	  home: "Home",
+	  label0: "Label Zero"
+	},
+	fr: true
+});
\ No newline at end of file
diff --git a/dojox/app/tests/globalizedApp/nls/fr/app.js b/dojox/app/tests/globalizedApp/nls/fr/app.js
new file mode 100755
index 0000000..43e8dd4
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/nls/fr/app.js
@@ -0,0 +1,4 @@
+define({
+	home: "Maison",
+   	label0: "Etiquette 0"
+});
\ No newline at end of file
diff --git a/dojox/app/tests/globalizedApp/nls/fr/home.js b/dojox/app/tests/globalizedApp/nls/fr/home.js
new file mode 100755
index 0000000..93b5a35
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/nls/fr/home.js
@@ -0,0 +1,4 @@
+define({
+	label1: "Etiquette Un",
+	label2: "Etiquette Deux"
+});
\ No newline at end of file
diff --git a/dojox/app/tests/globalizedApp/nls/home.js b/dojox/app/tests/globalizedApp/nls/home.js
new file mode 100755
index 0000000..b8cfbfd
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/nls/home.js
@@ -0,0 +1,7 @@
+define({
+	root: {
+		label1: "Label One",
+		label2: "Label Two"
+	},
+	fr: true
+});
\ No newline at end of file
diff --git a/dojox/app/tests/globalizedApp/package.json b/dojox/app/tests/globalizedApp/package.json
new file mode 100755
index 0000000..ab06393
--- /dev/null
+++ b/dojox/app/tests/globalizedApp/package.json
@@ -0,0 +1,4 @@
+{
+	"name": "globalizedApp",
+	"dojoBuild": "globalizedApp.profile.js"
+}
diff --git a/dojox/app/tests/layoutApp/build.profile.js b/dojox/app/tests/layoutApp/build.profile.js
new file mode 100755
index 0000000..d8a744e
--- /dev/null
+++ b/dojox/app/tests/layoutApp/build.profile.js
@@ -0,0 +1,32 @@
+require(["dojox/app/build/buildControlApp"], function(bc){
+});
+
+var profile = {
+	basePath: "..",
+	releaseDir: "./layoutApp/release",
+	action: "release",
+	cssOptimize: "comments",
+/*	multipleAppConfigLayers: true,*/
+	packages:[{
+		name: "dojo",
+		location: "../../../dojo"
+	},{
+		name: "dijit",
+		location: "../../../dijit"
+	},{
+		name: "layoutApp",
+		location: "../../../dojox/app/tests/layoutApp",
+		destLocation: "./dojox/app/tests/layoutApp"
+	},{
+		name: "dojox",
+		location: "../../../dojox"
+	}],
+	layers: {
+		"layoutApp/layoutApp": {
+			include: [ "layoutApp/index.html" ]
+		}
+	}
+};
+
+
+
diff --git a/dojox/app/tests/layoutApp/config.json b/dojox/app/tests/layoutApp/config.json
new file mode 100755
index 0000000..c63a969
--- /dev/null
+++ b/dojox/app/tests/layoutApp/config.json
@@ -0,0 +1,135 @@
+{
+	"id": "layoutApp",
+	"name": "layout App",
+	"description": "A layout App",
+	"splash": "splash",
+
+	"loaderConfig": {
+		"paths": {
+			"layoutApp": "../dojox/app/tests/layoutApp"
+		}
+	},
+
+	"dependencies": [
+		"dojox/app/utils/simpleModel",
+		"dojox/mobile/_base",
+		"dojox/mobile/compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/Heading",
+		"dojo/store/Memory",
+		"dojo/store/Observable",		
+		"dojox/mobile/EdgeToEdgeStoreList",
+		"dojox/mobile/View",
+		"dojox/app/widgets/Container"
+	],
+
+	"modules": [],
+	
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],
+	
+	//stores we are using
+	"stores": {
+		"namesStore":{
+			"type": "dojo/store/Memory",
+			"params": {
+				"data": "modelApp.names"
+			}
+		},
+		"listStore":{
+			"type": "dojo/store/Memory",
+			"observable": true,
+			"params": {
+				"data": "modelApp.listData"
+			}
+		}
+	},
+
+	//models and instantiation parameters for the models. Including 'type' as a property allows
+	//one to override the class that will be used for the model.
+	"models": {
+	   "names": {
+			"modelLoader": "dojox/app/utils/simpleModel",
+			"params":{
+				"store": {"$ref":"#stores.namesStore"}
+			}
+	   }
+	},
+
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+	"template": "layoutApp/views/navigation.html",
+
+	//the name of the view to load when the app is initialized.
+	"defaultView": "simple",
+
+	// these are the possible defaultTransitions, 
+	// the defaultTransition is only used if transition is not set in the config and it is not set or defaulted on the transitionEvent
+	//"defaultTransition": "slide",
+	//"defaultTransition": "none",
+	//"defaultTransition": "fade",
+	//"defaultTransition": "flip",     // Note: flip does not work with a BorderLayout Controller
+
+	// these are the possible transitions, 
+	// if a transition is set on a view or parent it will override the transition set on the transitionEvent or the defaultTransition in the config.
+	//"transition": "slide",
+	//"transition": "none",
+	//"transition": "fade",
+	"defaultTransition": "flip",
+
+	"views": {
+		"simple":{
+			"controller" : "layoutApp/views/simple.js",
+			"template": "layoutApp/views/simple.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		},
+
+		//list view, include list view and details view
+		"listMain": {
+			"defaultView": "list",
+			"defaultTransition": "fade",
+
+			"views": {
+				"list":{
+					"controller" : "layoutApp/views/list.js",
+					"defaultTransition": "slide",
+					"template": "layoutApp/views/list.html",
+					"dependencies":["dojox/mobile/TextBox"]
+				},
+				"itemDetails":{
+					"controller" : "layoutApp/views/itemDetails.js",
+					"defaultTransition": "flip",
+					"template": "layoutApp/views/itemDetails.html",
+					"dependencies":["dojox/mobile/TextBox"],
+					"defaultParams": {"cursor":"2"}
+				}
+			}
+		},
+
+		"date": {
+            "controller": "layoutApp/views/date.js",
+            "template": "layoutApp/views/date.html",
+            "dependencies":["dojox/mobile/DatePicker", "dojox/mobile/Opener", "dojox/mobile/SpinWheelDatePicker"]
+		}
+	}	
+}
diff --git a/dojox/app/tests/layoutApp/css/layoutApp.css b/dojox/app/tests/layoutApp/css/layoutApp.css
new file mode 100644
index 0000000..59dc37b
--- /dev/null
+++ b/dojox/app/tests/layoutApp/css/layoutApp.css
@@ -0,0 +1,118 @@
+html,body {
+	width: 100%;
+	height: 100%;
+}
+
+button.baseBtn {
+	-webkit-background-clip: padding-box;
+	-webkit-box-align: center;
+	background-clip: padding-box;
+	border-style: solid;
+	border-width: 1px;
+	color: black;
+	font-family: 'Helvetica Neue', HelveticaNeue, Helvetica-Neue, Helvetica, 'BBAlpha Sans';
+	font-size: 18px;
+	font-weight: bold;
+	vertical-align: middle;
+	margin: 10px;
+	height: 34px;
+	border-bottom-left-radius: 7px;
+	border-bottom-right-radius: 7px;
+	border-top-left-radius: 7px;
+	border-top-right-radius: 7px;
+	width: 240px;
+}
+
+button.whiteBtn{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(white), color-stop(0.06, #f2f2f2), to(#b7b7b7));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+button.whiteBtnSelected{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(#ffffff), color-stop(0.06, #bbbbbb), to(#fcfcfc));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+#header button {
+	position:absolute;
+	margin:0;
+}
+
+#navButton {
+	width:60px;
+}
+
+#loadDiv {
+	position:absolute;
+	left:0;
+	top:0;
+	width:100%;
+	height:100%;
+	z-index:999;
+}
+#loadDiv {
+	display:table;
+	font-size: 20px;
+	text-align:center;
+	background-color:white;
+}
+#loadDiv span {
+	display:table-cell;
+	vertical-align:middle;
+}
+
+body .mblProgContainer {
+	top:45%;
+	height: 45px;
+	width: 140px;
+	margin-left:-70px;
+	background-color: #2A2A28;
+	border-style: solid;
+	border-width: 2px;
+	border-color: #666666;
+	border-radius: 0.4em;
+	-webkit-border-radius: 0.4em;
+	-moz-border-radius: 0.4em;
+}
+
+body .mblProgContainer > div {
+	height: 100%;
+	width: 100%;
+	line-height: 45px;
+	vertical-align: middle;
+	font-size: 20px;
+	color: #c2c2c2;
+}
+
+body .mblProg {
+	left: 3px;
+	top: 3px;
+}
+
+body .mblProgContainer > div::after {
+	padding-left: 42px;
+	content: "Updating...";
+}
+
+#jsContent, #htmlContent {
+	padding-left:2px;
+}
+
+ at media screen and (max-width: 600px) {
+	#jsContent, #htmlContent {
+		font-size: 14px;
+	}
+}
+
+.hidden {
+	display:none;
+}
+
+div .navPane {
+	width:250px;
+	border-right:1px solid black;
+	background-color: #C5CCD3;
+	z-index:100;	
+}
diff --git a/dojox/app/tests/layoutApp/index.html b/dojox/app/tests/layoutApp/index.html
new file mode 100755
index 0000000..49d375f
--- /dev/null
+++ b/dojox/app/tests/layoutApp/index.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Layout App</title>
+		<link type="text/css" href="./css/layoutApp.css" rel="stylesheet" />
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+				mblAlwaysHideAddressBar: false,
+				app: {debugApp: 0},  // set debugApp to log app transtions and view activate/deactivate
+				async: 1">
+		</script>
+		<script>
+			require(["./layoutApp.js"], function(){
+			});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/layoutApp/layoutApp.js b/dojox/app/tests/layoutApp/layoutApp.js
new file mode 100755
index 0000000..593939a
--- /dev/null
+++ b/dojox/app/tests/layoutApp/layoutApp.js
@@ -0,0 +1,68 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojo/sniff"],
+	function(win, Application, jsonRef, config, has){
+	win.global.modelApp = {};
+	modelApp.names = {
+		identifier: "id",
+		items: [{
+			"id": "1",
+			"Serial": "360324",
+			"First": "John",
+			"Last": "Doe",
+			"Email": "jdoe at us.ibm.com",
+			"ShipTo": {
+				"Street": "123 Valley Rd",
+				"City": "Katonah",
+				"State": "NY",
+				"Zip": "10536"
+			},
+			"BillTo": {
+				"Street": "17 Skyline Dr",
+				"City": "Hawthorne",
+				"State": "NY",
+				"Zip": "10532"
+			}
+		}]
+	};
+
+	modelApp.listData = { 
+		identifier: "id",
+		'items':[{
+			"id": "item1",
+			"label": "Chad Chapman",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Chad",
+			"Last": "Chapman",
+			"Location": "CA",
+			"Office": "1278",
+			"Email": "c.c at test.com",
+			"Tel": "408-764-8237",
+			"Fax": "408-764-8228"
+		}, {
+			"id": "item2",
+			"label": "Irene Ira",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Irene",
+			"Last": "Ira",
+			"Location": "NJ",	
+			"Office": "F09",
+			"Email": "i.i at test.com",
+			"Tel": "514-764-6532",
+			"Fax": "514-764-7300"
+		}, {
+			"id": "item3",
+			"label": "John Jacklin",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "John",
+			"Last": "Jacklin",
+			"Location": "CA",
+			"Office": "6701",
+			"Email": "j.j at test.com",
+			"Tel": "408-764-1234",
+			"Fax": "408-764-4321"
+		}]
+	};
+	var cfg = jsonRef.fromJson(config);
+	has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+	Application(cfg);
+	
+});
diff --git a/dojox/app/tests/layoutApp/layoutApp.profile.js b/dojox/app/tests/layoutApp/layoutApp.profile.js
new file mode 100755
index 0000000..1e81b20
--- /dev/null
+++ b/dojox/app/tests/layoutApp/layoutApp.profile.js
@@ -0,0 +1,13 @@
+var profile = {
+	resourceTags:{
+		declarative: function(filename){
+	 		return /\.html?$/.test(filename); // tags any .html or .htm files as declarative
+	 	},
+		amd: function(filename){
+			return /\.js$/.test(filename);
+		},
+		copyOnly: function(filename, mid){
+			return mid == "layoutApp/build.profile";
+		}
+	}
+};
diff --git a/dojox/app/tests/layoutApp/package.json b/dojox/app/tests/layoutApp/package.json
new file mode 100755
index 0000000..0c40200
--- /dev/null
+++ b/dojox/app/tests/layoutApp/package.json
@@ -0,0 +1,4 @@
+{
+	"name": "layoutApp",
+	"dojoBuild": "layoutApp.profile.js"
+}
diff --git a/dojox/app/tests/layoutApp/views/date.html b/dojox/app/tests/layoutApp/views/date.html
new file mode 100644
index 0000000..eac41ec
--- /dev/null
+++ b/dojox/app/tests/layoutApp/views/date.html
@@ -0,0 +1,24 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Date Example"'></div>
+	<div>
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Using a dojox/mobile/DatePicker and a dojox/mobile/Opener</h2>
+
+		<h2 dojoType="dojox/mobile/RoundRectCategory">Click to select a date</h2>
+
+		<input data-dojo-attach-point="selDate1" readOnly value="" placeholder="Select a date" style="margin-left: 20px;">
+
+		<div id="opener" data-dojo-attach-point="opener" data-dojo-type="dojox/mobile/Opener">
+			<h1 data-dojo-type="dojox/mobile/Heading" label="Date Picker">
+				<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="save" 
+					data-dojo-props="label:'Done'" class="mblColorBlue"
+					style="position:absolute;width:45px;right:0;">
+				</span>
+				<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="cancel"
+					data-dojo-props="label:'Cancel'" class="mblColorBlue" 
+					style="position:absolute;width:45px;left:0;">
+				</span>
+			</h1>
+			<div data-dojo-attach-point="datePicker2" data-dojo-type="dojox/mobile/DatePicker"></div>
+		</div>
+	</div>	
+</div>
diff --git a/dojox/app/tests/layoutApp/views/date.js b/dojox/app/tests/layoutApp/views/date.js
new file mode 100644
index 0000000..31b7844
--- /dev/null
+++ b/dojox/app/tests/layoutApp/views/date.js
@@ -0,0 +1,43 @@
+define(["dojo/_base/lang", "dojo/on", "dijit/registry", "dojo/date/stamp"],
+function(lang, on, registry, stamp){
+	var _onResults = []; // events on array
+	var opener;
+
+	return {
+		init: function(){
+			opener = this.opener;
+			var onResult = on(this.selDate1, "click", lang.hitch(this, function(){
+				this.datePicker2.set("value", date);
+				this.opener.show(this.selDate1, ['below-centered','above-centered','after','before']);
+			})); 
+			_onResults.push(onResult);
+
+			var onResult = on(this.save, "click", lang.hitch(this, function(){
+				this.opener.hide(true);
+				date = this.selDate1.value = this.datePicker2.get("value");
+			})); 
+			_onResults.push(onResult);
+
+			var onResult = on(this.cancel, "click", lang.hitch(this, function(){
+					this.opener.hide(false);
+			})); 
+			_onResults.push(onResult);
+			
+			// initialize the global Date variable as today
+			date = stamp.toISOString(new Date(), {selector: "date"});
+		},
+
+		beforeActivate: function(){
+			//console.log("date view beforeActivate()");
+		},
+
+		// view destroy
+		destroy: function(){
+			var onResult = _onResults.pop();
+			while(onResult){
+				onResult.remove();
+				onResult = _onResults.pop();
+			}
+		}
+	};	
+});
diff --git a/dojox/app/tests/layoutApp/views/itemDetails.html b/dojox/app/tests/layoutApp/views/itemDetails.html
new file mode 100644
index 0000000..2923f41
--- /dev/null
+++ b/dojox/app/tests/layoutApp/views/itemDetails.html
@@ -0,0 +1,37 @@
+<div class="view mblView">
+    <h1 dojoType="dojox/mobile/Heading" data-dojo-props='back:"Back"'>List Item Details</h1>
+    <form name="listTestForm" id="listTestForm">    
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Updates to First or Last Name will be reflected in the list</h2>
+					<table id="table" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="First"
+									data-dojo-props="placeholder:'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Last"
+									 
+									data-dojo-props="placeholder:'Last Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput2" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Email"
+									data-dojo-props="placeholder:'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Tel"
+									data-dojo-props="placeholder:'Telephone'">
+							</td>
+						</tr>
+					</table>
+		</form>
+</div>
diff --git a/dojox/app/tests/layoutApp/views/itemDetails.js b/dojox/app/tests/layoutApp/views/itemDetails.js
new file mode 100644
index 0000000..b25bc08
--- /dev/null
+++ b/dojox/app/tests/layoutApp/views/itemDetails.js
@@ -0,0 +1,48 @@
+define([],
+function(){
+
+	var listStore = null;	//list data
+	var currentItem = null;
+
+	return {
+		// show an item detail
+		setDetailsContext: function(index){
+			// only set the cursor if it is different and valid
+			if(parseInt(index) < listStore.data.length){
+				currentItem = listStore.data[index];
+				this.First.set("value",currentItem.First);
+				this.Last.set("value",currentItem.Last);
+				this.Email.set("value",currentItem.Email);
+				this.Tel.set("value",currentItem.Tel);
+			}
+		},
+
+		// list view init
+		init: function(){
+			listStore = this.loadedStores.listStore;
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			// if this.params["cursor"] is set use it to set the selected Details Context
+			if(this.params["cursor"] || this.params["cursor"] == 0){
+				this.setDetailsContext(this.params["cursor"]);
+			}
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeDeactivate()
+			//
+			// put any updates back to the store
+			currentItem.label = this.First.get("value") + " " + this.Last.get("value");
+			currentItem.First = this.First.get("value");
+			currentItem.Last = this.Last.get("value");
+			currentItem.Email = this.Email.get("value");
+			currentItem.Tel = this.Tel.get("value");
+			listStore.put(currentItem);
+		}
+	}
+});
diff --git a/dojox/app/tests/layoutApp/views/list.html b/dojox/app/tests/layoutApp/views/list.html
new file mode 100644
index 0000000..b9a00e0
--- /dev/null
+++ b/dojox/app/tests/layoutApp/views/list.html
@@ -0,0 +1,11 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"List Example"'>
+  		<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="listInsert1"
+       		 data-dojo-props='icon:"mblDomButtonWhitePlus"'
+        		style="float:right;" onclick="console.log('+ was clicked')"></span>
+	</div>    
+	<form name="listTestForm">
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Using a dojox/mobile/EdgeToEdgeStoreList</h2>
+		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" data-dojo-attach-point="list" data-dojo-props='append:true'></ul>
+	</form>
+</div>
diff --git a/dojox/app/tests/layoutApp/views/list.js b/dojox/app/tests/layoutApp/views/list.js
new file mode 100644
index 0000000..009438f
--- /dev/null
+++ b/dojox/app/tests/layoutApp/views/list.js
@@ -0,0 +1,76 @@
+define(["dojo/_base/lang", "dojo/on"], function(lang, on){
+
+	return {
+	// setDetailsContext for an item
+		setDetailsContext: function(index, e, params){
+			if(params){
+				params.cursor = index;
+			}else{
+				params = {"cursor":index};
+			}
+			// transition to itemDetails view with the &cursor=index
+			var transOpts = {
+				transition: "flip",
+				title : "itemDetails",
+				target : "listMain,itemDetails",
+				url : "#listMain,itemDetails", // this is optional if not set it will be created from target   
+				params : params
+			};
+			this.app.transitionToView(e.target,transOpts,e);
+ 
+		
+		},
+
+	// insert an item
+		insertResult: function(index, e){
+			if(index<0 || index>this.list.store.data.length){
+				throw Error("index out of data model.");
+			}
+			if((this.list.store.data[index-1].First=="") ||
+				(this.list.store.data[index] && (this.list.store.data[index].First == ""))){
+				return;
+			}
+			var data = {id:Math.random(), "label": "", "rightIcon":"mblDomButtonBlueCircleArrow", "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+			this.list.store.add(data);
+			this.setDetailsContext(index, e);
+		},
+
+
+		// list view init
+		init: function(){
+			var list = this.list;
+			if(!list.Store){
+				list.setStore(this.loadedStores.listStore);
+			}
+		//	for(var i = 0; i < this.list.store.data.length; i++){
+		//		var item = dom.byId(this.list.store.data[i].id);
+		//		on(item, "click", lang.hitch(this, function(e){
+		//			var item = this.list.store.query({"label": e.target.innerHTML})
+		//			var index = this.list.store.index[item[0].id];
+		//			console.log("index is "+index);
+		//			this.setDetailsContext(index, e, this.params);
+		//		})); 
+		//	}
+			
+			this.list.on("click", lang.hitch(this, function(e){
+				console.log("List on click hit ",e);
+				var item = this.list.store.query({"label": e.target.innerHTML});
+				var index = this.list.store.index[item[0].id];
+				console.log("index is "+index);
+				this.setDetailsContext(index, e, this.params);	
+			})); 
+
+			this.listInsert1.on("click", lang.hitch(this, function(e){
+				console.log("listInsert1 on click hit ",e);
+				var index = this.list.store.data.length;
+				this.insertResult(index, e);
+			})); 
+			
+		},
+
+		// view destroy, this destroy function can be removed since it is empty
+		destroy: function(){
+			// _WidgetBase.on listener is automatically destroyed when the Widget itself is.
+		}
+	};
+});
diff --git a/dojox/app/tests/layoutApp/views/navigation.html b/dojox/app/tests/layoutApp/views/navigation.html
new file mode 100755
index 0000000..d1c436a
--- /dev/null
+++ b/dojox/app/tests/layoutApp/views/navigation.html
@@ -0,0 +1,14 @@
+<div>
+	<!-- left -->
+	<div data-dojo-type="dojox/app/widgets/Container" class="navPane" data-app-constraint="left">
+		<h1 data-app-constraint="top" data-dojo-type="dojox/mobile/Heading">Layout App</h1>
+		<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+			<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;">Navigation</h2>
+			<ul data-dojo-type="dojox/mobile/RoundRectList" data-app-constraint="center">
+				<li dojoType="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Simple Form Data',target:'simple',url:'#simple'"></li>
+				<li dojoType="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'List Data Test',target:'listMain',url:'#listMain'"></li>
+				<li dojoType="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Date Test',target:'date',url:'#date'"></li>
+			</ul>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/layoutApp/views/simple.html b/dojox/app/tests/layoutApp/views/simple.html
new file mode 100755
index 0000000..f222950
--- /dev/null
+++ b/dojox/app/tests/layoutApp/views/simple.html
@@ -0,0 +1,101 @@
+<div id="settings" class="view mblView">
+    <h1 data-dojo-type="dojox/mobile/Heading">Simple Form Data</h1>
+    <form name="testForm" id="testForm">    
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Using simple JSON Model with data from a dojo/store/Memory</h2>
+  			<table id="table" cellspacing="10"  style="width: 100%">
+				<tr>
+					<td style="width: 100px;" class="layout">First</td>
+					<td class="layout">							
+						<input  id="firstInput1" data-dojo-type="dojox/mobile/TextBox" 
+								data-dojo-props="placeholder:'First'">
+					</td>
+				</tr>
+				<tr>
+					<td style="width: 100px;" class="layout">Last Name</td>
+					<td class="layout">
+						<input 	id="lastInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+								data-dojo-props="placeholder:'Last Name'">
+					</td>
+				</tr>
+				<tr>
+					<td style="width: 100px;" class="layout">Email</td>
+					<td class="layout">
+						<input id="emailInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+								data-dojo-props="placeholder:'Email'">
+					</td>
+				</tr>
+			</table>
+		
+	
+  			<div class="spacer"></div>
+			<button id="shipto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Ship To</button>
+			<button id="billto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="shiptodiv" >Ship To:
+	  			<table id="table" cellspacing="10" style="width: 100%">
+					<tr>
+						<td style="width: 100px;" class="layout">Street</td>
+						<td class="layout">							
+							<input  id="shiptostreetInput1" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="placeholder:'Street'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">City</td>
+						<td class="layout">
+							<input 	id="shiptocityInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'City'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">State</td>
+						<td class="layout">
+							<input id="shiptostateInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'State'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">Zip Code</td>
+						<td class="layout">
+							<input id="shiptozipInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'Zip Code'">
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="fieldset" id="billtodiv" >Bill To:
+	  			<table id="table" cellspacing="10" style="width: 100%">
+					<tr>
+						<td style="width: 100px;" class="layout">Street</td>
+						<td class="layout">							
+							<input  id="billtostreetInput1" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="placeholder:'Street'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">City</td>
+						<td class="layout">
+							<input 	id="billtocityInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'City'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">State</td>
+						<td class="layout">
+							<input id="billtostateInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'State'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">Zip Code</td>
+						<td class="layout">
+							<input id="billtozipInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'Zip Code'">
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="spacer"></div>
+			<button id="reset1" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Reset</button>
+    </form>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/layoutApp/views/simple.js b/dojox/app/tests/layoutApp/views/simple.js
new file mode 100644
index 0000000..9c8a065
--- /dev/null
+++ b/dojox/app/tests/layoutApp/views/simple.js
@@ -0,0 +1,62 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry"],
+function(dom, connect, registry){
+
+	var _connectResults = []; // events connect results
+	var currentModel = null;
+
+	var setFromModel = function (){
+		registry.byId("firstInput1").set('value', currentModel[0].First);
+		registry.byId("lastInput1").set('value', currentModel[0].Last);
+		registry.byId("emailInput1").set('value', currentModel[0].Email);
+		registry.byId("shiptostreetInput1").set('value', currentModel[0].ShipTo.Street);
+		registry.byId("shiptocityInput1").set('value', currentModel[0].ShipTo.City);
+		registry.byId("shiptostateInput1").set('value', currentModel[0].ShipTo.State);
+		registry.byId("shiptozipInput1").set('value', currentModel[0].ShipTo.Zip);
+		registry.byId("billtostreetInput1").set('value', currentModel[0].BillTo.Street);
+		registry.byId("billtocityInput1").set('value', currentModel[0].BillTo.City);
+		registry.byId("billtostateInput1").set('value', currentModel[0].BillTo.State);
+		registry.byId("billtozipInput1").set('value', currentModel[0].BillTo.Zip);
+	};
+
+	return {
+		// simple view init
+		init: function(){
+			currentModel = this.loadedModels.names;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId('shipto'), "click", function(){
+				//console.log("shipTo called. ");
+				dom.byId("billtodiv").style.display = "none";
+				dom.byId("shiptodiv").style.display = "";
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('billto'), "click", function(){
+				//console.log("billTo called. ");
+				dom.byId("billtodiv").style.display = "";
+				dom.byId("shiptodiv").style.display = "none";
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('reset1'), "click", function(){
+				//console.log("reset called. ");
+				setFromModel();
+				//console.log("reset done. ");
+			});
+			_connectResults.push(connectResult);
+
+			dom.byId("billtodiv").style.display = "none";
+			setFromModel();
+			
+		},
+
+		// simple view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/layoutApp2/config.json b/dojox/app/tests/layoutApp2/config.json
new file mode 100644
index 0000000..3d1dbdf
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/config.json
@@ -0,0 +1,134 @@
+{
+	"id": "layoutApp2",
+	"name": "layout App2",
+	"description": "A layout App2",
+	"splash": "splash",
+
+	"loaderConfig": {
+		"paths": {
+			"layoutApp2": "../dojox/app/tests/layoutApp2"
+		}
+	},
+
+	"dependencies": [
+		"dojox/app/utils/simpleModel",
+		"dojox/mobile/_base",
+		"dojox/mobile/compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/Heading",
+		"dojo/store/Memory",
+		"dojo/store/Observable",		
+		"dojox/mobile/EdgeToEdgeStoreList",
+		"dojox/mobile/View",
+		"dojox/app/widgets/Container"
+	],
+
+	"modules": [],
+	
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout",
+		"dojox/app/tests/layoutApp2/controllers/UnloadViewController"
+	],
+
+	//stores we are using
+	"stores": {
+	   "namesStore":{
+	       "type": "dojo/store/Memory",
+		   "params": {
+		      "data": "modelApp.names"
+		   }
+		},
+		"listStore":{
+			"type": "dojo/store/Memory",
+			"observable": true,
+			"params": {
+				"data": "modelApp.listData"
+			}
+       }
+	},
+
+	//models and instantiation parameters for the models. Including 'type' as a property allows
+	//one to override the class that will be used for the model.
+	"models": {
+	   "names": {
+			"modelLoader": "dojox/app/utils/simpleModel",
+			"params":{
+				"store": {"$ref":"#stores.namesStore"}
+			}
+	   }
+	}, 
+	
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+// this app uses constraints and multiple files in defaultView instead of an outer template for a table layout
+//	"template": "layoutApp2/views/navigation.html",
+
+	//the name of the view to load when the app is initialized.
+	"defaultView": "navigation+simple",
+
+	// these are the possilbe defaultTransitions
+	//"defaultTransition": "slide",
+	//"defaultTransition": "none",
+	//"defaultTransition": "fade",
+	"defaultTransition": "fade",
+
+	"views": {
+		"navigation":{
+			"constraint" : "left",
+			"template": "layoutApp2/views/navigation.html"
+		},
+		"simple":{
+			"controller" : "layoutApp2/views/simple.js",
+			"constraint" : "center",
+			"template": "layoutApp2/views/simple.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		},
+
+		//list view, include list view and details view
+		"listMain": {
+			"defaultView": "list",
+			"transition": "flip",
+			"constraint" : "center",
+
+			"views": {
+				"list":{
+					"controller" : "layoutApp2/views/list.js",
+					"template": "layoutApp2/views/list.html",
+					"dependencies":["dojox/mobile/TextBox"]
+				},
+				"itemDetails":{
+					"controller" : "layoutApp2/views/itemDetails.js",
+					"template": "layoutApp2/views/itemDetails.html",
+					"dependencies":["dojox/mobile/TextBox"],
+					"defaultParams": {"cursor":"2"}
+				}
+			}
+		},
+
+		"date": {
+            "controller": "layoutApp2/views/date.js",
+            "template": "layoutApp2/views/date.html",
+            "constraint" : "center",
+            "dependencies":["dojox/mobile/DatePicker", "dojox/mobile/Opener"]
+		}
+	}	
+}
diff --git a/dojox/app/tests/layoutApp2/controllers/UnloadViewController.js b/dojox/app/tests/layoutApp2/controllers/UnloadViewController.js
new file mode 100644
index 0000000..c9afdcf
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/controllers/UnloadViewController.js
@@ -0,0 +1,94 @@
+define(["dojo/_base/lang","dojo/_base/declare", "dojo/Deferred", "dojo/_base/array", "dojo/dom-construct", "dijit/registry", "dojox/app/Controller"],
+	function(lang, declare, Deferred, array, domConstruct, registry, Controller){
+	// module:
+	//		dojox/app/tests/layoutApp2/controllers/UnloadViewController
+	// summary:
+	//		Used to Unload Views when they are no longer needed
+	//		Bind "unload-view" event on dojox/app application instance.
+	//		Do transition from one view to another view.
+
+	return declare("dojox/app/tests/layoutApp2/controllers/UnloadViewController", Controller, {
+
+		constructor: function(app){
+			this.app = app;
+			// summary:
+			//		bind "app-transition" event on application instance.
+			//
+			// app:
+			//		dojox/app application instance.
+			// events:
+			//		{event : handler}
+			this.events = {
+				"unload-view": this.unloadView
+			};
+		},
+
+		unloadView: function(event){
+			// summary:
+			//		Response to dojox/app "unload-view" event.
+			// 		If a view has children loaded the view and any children of the child will be unloaded.
+			//
+			// example:
+			//		Use trigger() to trigger "unload-view" event, and this function will response the event. For example:
+			//		|	this.trigger("unload-view", {"parent":parent, "view":view, "callback":function(){...}});
+			//
+			// event: Object
+			//		unloadView event parameter. It should be like this: {"parent":parent, "view":view, "callback":function(){...}}
+
+			var parent = event.parent || this.app;
+			var view = event.view || "";
+			var viewId = view.id;
+
+			if(!parent || !view || !viewId){
+				console.warn("unload-view event for view with no parent or with an invalid view with view = ", view);
+				return;
+			}
+
+			if(parent.selectedChildren[viewId]){
+				console.warn("unload-view event for a view which is still in use so it can not be unloaded for view id = " + viewId + "'.");
+				return;
+			}
+
+			if(!parent.children[viewId]){
+				console.warn("unload-view event for a view which was not found in parent.children[viewId] for viewId = " + viewId + "'.");
+				return;
+			}
+
+			this.unloadChild(parent, view);
+
+			// call Load event callback
+			if(event.callback){
+				event.callback();
+			}
+		},
+
+		unloadChild: function(parent, viewToUnload){
+			// summary:
+			//		Unload the view, and all of its child views recursively.
+			// 		Destroy all children, destroy all widgets, destroy the domNode, remove the view from the parent.children,
+			// 		then destroy the view.
+			//
+			// parent: Object
+			//		parent of this view.
+			// viewToUnload: Object
+			//		the view to be unloaded.
+
+			for(var child in viewToUnload.children){
+				this.unloadChild(viewToUnload, child);  // unload children then unload the view itself
+			}
+			if(viewToUnload.domNode){
+				// destroy all widgets, then destroy the domNode, then destroy the view.
+				var widList = registry.findWidgets(viewToUnload.domNode);
+				for(var wid in widList){
+					widList[wid].destroyRecursive();
+				}
+				domConstruct.destroy(viewToUnload.domNode);
+			}
+
+			delete parent.children[viewToUnload.id]; // remove it from the parents children
+			if(viewToUnload.destroy){
+				viewToUnload.destroy(); // call destroy for the view.
+			}
+		}
+	});
+});
diff --git a/dojox/app/tests/layoutApp2/css/layoutApp.css b/dojox/app/tests/layoutApp2/css/layoutApp.css
new file mode 100644
index 0000000..525eeca
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/css/layoutApp.css
@@ -0,0 +1,118 @@
+html,body {
+	width: 100%;
+	height: 100%;
+}
+
+button.baseBtn {
+	-webkit-background-clip: padding-box;
+	-webkit-box-align: center;
+	background-clip: padding-box;
+	border-style: solid;
+	border-width: 1px;
+	color: black;
+	font-family: 'Helvetica Neue', HelveticaNeue, Helvetica-Neue, Helvetica, 'BBAlpha Sans';
+	font-size: 18px;
+	font-weight: bold;
+	vertical-align: middle;
+	margin: 10px;
+	height: 34px;
+	border-bottom-left-radius: 7px;
+	border-bottom-right-radius: 7px;
+	border-top-left-radius: 7px;
+	border-top-right-radius: 7px;
+	width: 240px;
+}
+
+button.whiteBtn{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(white), color-stop(0.06, #f2f2f2), to(#b7b7b7));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+button.whiteBtnSelected{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(#ffffff), color-stop(0.06, #bbbbbb), to(#fcfcfc));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+#header button {
+	position:absolute;
+	margin:0;
+}
+
+#navButton {
+	width:60px;
+}
+
+#loadDiv {
+	position:absolute;
+	left:0;
+	top:0;
+	width:100%;
+	height:100%;
+	z-index:999;
+}
+#loadDiv {
+	display:table;
+	font-size: 20px;
+	text-align:center;
+	background-color:white;
+}
+#loadDiv span {
+	display:table-cell;
+	vertical-align:middle;
+}
+
+body .mblProgContainer {
+	top:45%;
+	height: 45px;
+	width: 140px;
+	margin-left:-70px;
+	background-color: #2A2A28;
+	border-style: solid;
+	border-width: 2px;
+	border-color: #666666;
+	border-radius: 0.4em;
+	-webkit-border-radius: 0.4em;
+	-moz-border-radius: 0.4em;
+}
+
+body .mblProgContainer > div {
+	height: 100%;
+	width: 100%;
+	line-height: 45px;
+	vertical-align: middle;
+	font-size: 20px;
+	color: #c2c2c2;
+}
+
+body .mblProg {
+	left: 3px;
+	top: 3px;
+}
+
+body .mblProgContainer > div::after {
+	padding-left: 42px;
+	content: "Updating...";
+}
+
+#jsContent, #htmlContent {
+	padding-left:2px;
+}
+
+ at media screen and (max-width: 600px) {
+	#jsContent, #htmlContent {
+		font-size: 14px;
+	}
+}
+
+.hidden {
+	display:none;
+}
+
+div .navPane {
+	width:250px;
+	border-right:1px solid black;
+	background-color: #C5CCD3;
+	z-index:100;
+}
diff --git a/dojox/app/tests/layoutApp2/index.html b/dojox/app/tests/layoutApp2/index.html
new file mode 100644
index 0000000..6682d2a
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/index.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Layout App</title>
+		<link type="text/css" href="./css/layoutApp.css" rel="stylesheet" />
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+				mblAlwaysHideAddressBar: false,
+				app: {debugApp: 1},  // set debugApp to log app transtions and view activate/deactivate
+				async: 1">
+		</script>
+		<script>
+			require(["./layoutApp.js"], function(){
+			});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/layoutApp2/layoutApp.js b/dojox/app/tests/layoutApp2/layoutApp.js
new file mode 100644
index 0000000..593939a
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/layoutApp.js
@@ -0,0 +1,68 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojo/sniff"],
+	function(win, Application, jsonRef, config, has){
+	win.global.modelApp = {};
+	modelApp.names = {
+		identifier: "id",
+		items: [{
+			"id": "1",
+			"Serial": "360324",
+			"First": "John",
+			"Last": "Doe",
+			"Email": "jdoe at us.ibm.com",
+			"ShipTo": {
+				"Street": "123 Valley Rd",
+				"City": "Katonah",
+				"State": "NY",
+				"Zip": "10536"
+			},
+			"BillTo": {
+				"Street": "17 Skyline Dr",
+				"City": "Hawthorne",
+				"State": "NY",
+				"Zip": "10532"
+			}
+		}]
+	};
+
+	modelApp.listData = { 
+		identifier: "id",
+		'items':[{
+			"id": "item1",
+			"label": "Chad Chapman",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Chad",
+			"Last": "Chapman",
+			"Location": "CA",
+			"Office": "1278",
+			"Email": "c.c at test.com",
+			"Tel": "408-764-8237",
+			"Fax": "408-764-8228"
+		}, {
+			"id": "item2",
+			"label": "Irene Ira",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Irene",
+			"Last": "Ira",
+			"Location": "NJ",	
+			"Office": "F09",
+			"Email": "i.i at test.com",
+			"Tel": "514-764-6532",
+			"Fax": "514-764-7300"
+		}, {
+			"id": "item3",
+			"label": "John Jacklin",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "John",
+			"Last": "Jacklin",
+			"Location": "CA",
+			"Office": "6701",
+			"Email": "j.j at test.com",
+			"Tel": "408-764-1234",
+			"Fax": "408-764-4321"
+		}]
+	};
+	var cfg = jsonRef.fromJson(config);
+	has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+	Application(cfg);
+	
+});
diff --git a/dojox/app/tests/layoutApp2/views/date.html b/dojox/app/tests/layoutApp2/views/date.html
new file mode 100644
index 0000000..05e28f9
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/views/date.html
@@ -0,0 +1,26 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Date Example"'></div>
+	<div>
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Using a dojox/mobile/DatePicker and a dojox/mobile/Opener</h2>
+
+		<h2 data-dojo-type="dojox/mobile/RoundRectCategory">Click to select a date</h2>
+
+		<input data-dojo-attach-point="selDate1" readOnly value="" placeholder="Select a date" style="margin-left: 20px;">
+		<button data-dojo-attach-point="unloadSimple" data-dojo-type="dojox/mobile/Button" style="margin-left: 20px;">Unload Simple View</button>
+		<button data-dojo-attach-point="unloadList" data-dojo-type="dojox/mobile/Button" style="margin-left: 20px;">Unload List View</button>
+
+		<div id="opener" data-dojo-attach-point="opener" data-dojo-type="dojox/mobile/Opener">
+			<h1 data-dojo-type="dojox/mobile/Heading" label="Date Picker">
+				<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="save" 
+					data-dojo-props="label:'Done'" class="mblColorBlue"
+					style="position:absolute;width:45px;right:0;">
+				</span>
+				<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="cancel"
+					data-dojo-props="label:'Cancel'" class="mblColorBlue" 
+					style="position:absolute;width:45px;left:0;">
+				</span>
+			</h1>
+			<div data-dojo-attach-point="datePicker2" data-dojo-type="dojox/mobile/DatePicker"></div>
+		</div>
+	</div>	
+</div>
diff --git a/dojox/app/tests/layoutApp2/views/date.js b/dojox/app/tests/layoutApp2/views/date.js
new file mode 100644
index 0000000..1ded31b
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/views/date.js
@@ -0,0 +1,65 @@
+define(["dojo/_base/lang", "dojo/on", "dijit/registry", "dojo/date/stamp"],
+function(lang, on, registry, stamp){
+	var _onResults = []; // events on array
+	var opener;
+
+	return {
+		init: function(){
+			opener = this.opener;
+			var onResult = on(this.selDate1, "click", lang.hitch(this, function(){
+				this.datePicker2.set("value", date);
+				this.opener.show(this.selDate1, ['below-centered','above-centered','after','before']);
+			})); 
+			_onResults.push(onResult);
+
+			var onResult = on(this.save, "click", lang.hitch(this, function(){
+				this.opener.hide(true);
+				date = this.selDate1.value = this.datePicker2.get("value");
+			})); 
+			_onResults.push(onResult);
+
+			onResult = on(this.cancel, "click", lang.hitch(this, function(){
+				this.opener.hide(false);
+			})); 
+			_onResults.push(onResult);
+
+			onResult = on(this.unloadSimple, "click", lang.hitch(this, function(e){
+				var params = {};
+				params.parent = this.parent;
+				var view = this.parent.children.layoutApp2_simple;
+				params.view = view;
+			//	params.viewId = view.id;
+				this.app.emit("unload-view", params);
+			}));
+			_onResults.push(onResult);
+
+			onResult = on(this.unloadList, "click", lang.hitch(this, function(e){
+				var params = {};
+				params.parent = this.parent;
+				var view = this.parent.children.layoutApp2_listMain;
+				params.view = view;
+				//params.viewId = view.id;
+				this.app.emit("unload-view", params);
+			}));
+			_onResults.push(onResult);
+
+			// initialize the global Date variable as today
+			date = stamp.toISOString(new Date(), {selector: "date"});
+		},
+
+		beforeActivate: function(){
+			//console.log("date view beforeActivate()");
+		},
+
+
+		// view destroy
+		destroy: function(){
+			var onResult = _onResults.pop();
+			while(onResult){
+				onResult.remove();
+				onResult = _onResults.pop();
+			}
+		}
+	};
+	
+});
diff --git a/dojox/app/tests/layoutApp2/views/itemDetails.html b/dojox/app/tests/layoutApp2/views/itemDetails.html
new file mode 100644
index 0000000..2923f41
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/views/itemDetails.html
@@ -0,0 +1,37 @@
+<div class="view mblView">
+    <h1 dojoType="dojox/mobile/Heading" data-dojo-props='back:"Back"'>List Item Details</h1>
+    <form name="listTestForm" id="listTestForm">    
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Updates to First or Last Name will be reflected in the list</h2>
+					<table id="table" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="First"
+									data-dojo-props="placeholder:'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Last"
+									 
+									data-dojo-props="placeholder:'Last Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput2" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Email"
+									data-dojo-props="placeholder:'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Tel"
+									data-dojo-props="placeholder:'Telephone'">
+							</td>
+						</tr>
+					</table>
+		</form>
+</div>
diff --git a/dojox/app/tests/layoutApp2/views/itemDetails.js b/dojox/app/tests/layoutApp2/views/itemDetails.js
new file mode 100644
index 0000000..b25bc08
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/views/itemDetails.js
@@ -0,0 +1,48 @@
+define([],
+function(){
+
+	var listStore = null;	//list data
+	var currentItem = null;
+
+	return {
+		// show an item detail
+		setDetailsContext: function(index){
+			// only set the cursor if it is different and valid
+			if(parseInt(index) < listStore.data.length){
+				currentItem = listStore.data[index];
+				this.First.set("value",currentItem.First);
+				this.Last.set("value",currentItem.Last);
+				this.Email.set("value",currentItem.Email);
+				this.Tel.set("value",currentItem.Tel);
+			}
+		},
+
+		// list view init
+		init: function(){
+			listStore = this.loadedStores.listStore;
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			// if this.params["cursor"] is set use it to set the selected Details Context
+			if(this.params["cursor"] || this.params["cursor"] == 0){
+				this.setDetailsContext(this.params["cursor"]);
+			}
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeDeactivate()
+			//
+			// put any updates back to the store
+			currentItem.label = this.First.get("value") + " " + this.Last.get("value");
+			currentItem.First = this.First.get("value");
+			currentItem.Last = this.Last.get("value");
+			currentItem.Email = this.Email.get("value");
+			currentItem.Tel = this.Tel.get("value");
+			listStore.put(currentItem);
+		}
+	}
+});
diff --git a/dojox/app/tests/layoutApp2/views/list.html b/dojox/app/tests/layoutApp2/views/list.html
new file mode 100644
index 0000000..41b87d4
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/views/list.html
@@ -0,0 +1,32 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"List Example"'>
+  		<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="listInsert1"
+       		 data-dojo-props='icon:"mblDomButtonWhitePlus"'
+        		style="float:right;" onclick="console.log('+ was clicked')"></span>
+	</div>    
+	<form name="listTestForm">
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Using a dojox/mobile/EdgeToEdgeStoreList</h2>
+		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" data-dojo-attach-point="list" data-dojo-props='append:true'></ul>
+	</form>
+			<ul data-dojo-type="dojox/mobile/RoundRectList">
+				<li data-dojo-type="dojox/mobile/ListItem" clickable="true" transitionOptions="{title:'-listMain',target:'-listMain',url:'#-listMain'}">
+					Remove listMain view
+				</li>					
+				<li data-dojo-type="dojox/mobile/ListItem" clickable="true" transitionOptions="{title:'-listMain,list',target:'-listMain,list',url:'#-listMain,list'}">
+					Remove listMain,list views
+				</li>					
+				<li data-dojo-type="dojox/mobile/ListItem" clickable="true" transitionOptions="{title:'-navigation',target:'-navigation',url:'#-navigation'}">
+					Remove navigation view
+				</li>					
+				<li data-dojo-type="dojox/mobile/ListItem" clickable="true" transitionOptions="{title:'navigation',target:'navigation',url:'#navigation'}">
+					Add navigation view
+				</li>					
+				<li data-dojo-type="dojox/mobile/ListItem" clickable="true" transitionOptions="{title:'listMain,list-navigation',target:'listMain,list-navigation',url:'#listMain,list-navigation'}">
+					Remove navigation view. leave listMain,list
+				</li>					
+				<li data-dojo-type="dojox/mobile/ListItem" clickable="true" transitionOptions="{title:'listMain,list+navigation',target:'listMain,list+navigation',url:'#listMain,list+navigation'}">
+					Add navigation view to listMain,list
+				</li>					
+			</ul>
+
+</div>
diff --git a/dojox/app/tests/layoutApp2/views/list.js b/dojox/app/tests/layoutApp2/views/list.js
new file mode 100644
index 0000000..3962726
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/views/list.js
@@ -0,0 +1,79 @@
+define(["dojo/_base/lang", "dojo/on"], function(lang, on){
+	var _onResults = []; // events on array
+
+	return {
+	// setDetailsContext for an item
+		setDetailsContext: function(index, e, params){
+			if(params){
+				params.cursor = index;
+			}else{
+				params = {"cursor":index};
+			}
+			// transition to itemDetails view with the &cursor=index
+			var transOpts = {
+				title : "itemDetails",
+				target : "listMain,itemDetails",
+				url : "#listMain,itemDetails", // this is optional if not set it will be created from target   
+				params : params
+			};
+			this.app.transitionToView(e.target,transOpts,e);
+ 
+		
+		},
+
+	// insert an item
+		insertResult: function(index, e){
+			if(index<0 || index>this.list.store.data.length){
+				throw Error("index out of data model.");
+			}
+			if((this.list.store.data[index-1].First=="") ||
+				(this.list.store.data[index] && (this.list.store.data[index].First == ""))){
+				return;
+			}
+			var data = {id:Math.random(), "label": "", "rightIcon":"mblDomButtonBlueCircleArrow", "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+			this.list.store.add(data);
+			this.setDetailsContext(index, e);
+		},
+
+
+		// list view init
+		init: function(){
+			var list = this.list;
+			if(!list.Store){
+				list.setStore(this.loadedStores.listStore);
+			}
+			var onResult;
+		//	for(var i = 0; i < this.list.store.data.length; i++){
+		//		var item = dom.byId(this.list.store.data[i].id);
+		//		onResult = on(item, "click", lang.hitch(this, function(e){
+		//			var item = this.list.store.query({"label": e.target.innerHTML})
+		//			var index = this.list.store.index[item[0].id];
+		//			console.log("index is "+index);
+		//			this.setDetailsContext(index, e, this.params);
+		//		})); 
+		//		_onResults.push(onResult);
+		//	}
+			
+			this.list.on("click", lang.hitch(this, function(e){
+				console.log("List on click hit ",e);
+				var item = this.list.store.query({"label": e.target.innerHTML});
+				var index = this.list.store.index[item[0].id];
+				console.log("index is "+index);
+				this.setDetailsContext(index, e, this.params);	
+			})); 
+
+			this.listInsert1.on("click", lang.hitch(this, function(e){
+				console.log("listInsert1 on click hit ",e);
+				var index = this.list.store.data.length;
+				this.insertResult(index, e);
+			})); 
+			
+		},
+
+		// view destroy, this destroy function can be removed since it is empty
+		destroy: function(){
+			// _WidgetBase.on listener is automatically destroyed when the Widget itself is. 
+			console.log("layoutApp2 list view destroy called");
+		}
+	};
+});
diff --git a/dojox/app/tests/layoutApp2/views/navigation.html b/dojox/app/tests/layoutApp2/views/navigation.html
new file mode 100644
index 0000000..d7e85f8
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/views/navigation.html
@@ -0,0 +1,17 @@
+<div class="navPane">
+	<!-- left -->
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Layout App"' data-app-constraint="top"></h1>
+	<div data-dojo-type="dojox/app/widgets/Container"  class="navPane" data-app-constraint="left" data-dojo-props="scrollable:true">
+
+<!--	 <div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable:true"> --> 
+		<div>
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Navigation</h2>
+			<ul data-dojo-type="dojox/mobile/RoundRectList" data-app-constraint="center">
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Simple Form Data',target:'simple',url:'#simple'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'List Data Test',target:'listMain,list',url:'#listMain,list'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Nav + List Data Test',target:'navigation+listMain,list',transition:'flip',url:'#navigation+listMain,list'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Date Test',target:'date',transition:'flip',url:'#date'"></li>
+			</ul>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/layoutApp2/views/simple.html b/dojox/app/tests/layoutApp2/views/simple.html
new file mode 100644
index 0000000..f222950
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/views/simple.html
@@ -0,0 +1,101 @@
+<div id="settings" class="view mblView">
+    <h1 data-dojo-type="dojox/mobile/Heading">Simple Form Data</h1>
+    <form name="testForm" id="testForm">    
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Using simple JSON Model with data from a dojo/store/Memory</h2>
+  			<table id="table" cellspacing="10"  style="width: 100%">
+				<tr>
+					<td style="width: 100px;" class="layout">First</td>
+					<td class="layout">							
+						<input  id="firstInput1" data-dojo-type="dojox/mobile/TextBox" 
+								data-dojo-props="placeholder:'First'">
+					</td>
+				</tr>
+				<tr>
+					<td style="width: 100px;" class="layout">Last Name</td>
+					<td class="layout">
+						<input 	id="lastInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+								data-dojo-props="placeholder:'Last Name'">
+					</td>
+				</tr>
+				<tr>
+					<td style="width: 100px;" class="layout">Email</td>
+					<td class="layout">
+						<input id="emailInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+								data-dojo-props="placeholder:'Email'">
+					</td>
+				</tr>
+			</table>
+		
+	
+  			<div class="spacer"></div>
+			<button id="shipto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Ship To</button>
+			<button id="billto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="shiptodiv" >Ship To:
+	  			<table id="table" cellspacing="10" style="width: 100%">
+					<tr>
+						<td style="width: 100px;" class="layout">Street</td>
+						<td class="layout">							
+							<input  id="shiptostreetInput1" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="placeholder:'Street'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">City</td>
+						<td class="layout">
+							<input 	id="shiptocityInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'City'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">State</td>
+						<td class="layout">
+							<input id="shiptostateInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'State'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">Zip Code</td>
+						<td class="layout">
+							<input id="shiptozipInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'Zip Code'">
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="fieldset" id="billtodiv" >Bill To:
+	  			<table id="table" cellspacing="10" style="width: 100%">
+					<tr>
+						<td style="width: 100px;" class="layout">Street</td>
+						<td class="layout">							
+							<input  id="billtostreetInput1" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="placeholder:'Street'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">City</td>
+						<td class="layout">
+							<input 	id="billtocityInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'City'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">State</td>
+						<td class="layout">
+							<input id="billtostateInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'State'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">Zip Code</td>
+						<td class="layout">
+							<input id="billtozipInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'Zip Code'">
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="spacer"></div>
+			<button id="reset1" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Reset</button>
+    </form>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/layoutApp2/views/simple.js b/dojox/app/tests/layoutApp2/views/simple.js
new file mode 100644
index 0000000..8dc2922
--- /dev/null
+++ b/dojox/app/tests/layoutApp2/views/simple.js
@@ -0,0 +1,62 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry"],
+function(dom, connect, registry){
+
+	var _connectResults = []; // events connect results
+	var currentModel = null;
+
+	var setFromModel = function (){
+		registry.byId("firstInput1").set('value', currentModel[0].First);
+		registry.byId("lastInput1").set('value', currentModel[0].Last);
+		registry.byId("emailInput1").set('value', currentModel[0].Email);
+		registry.byId("shiptostreetInput1").set('value', currentModel[0].ShipTo.Street);
+		registry.byId("shiptocityInput1").set('value', currentModel[0].ShipTo.City);
+		registry.byId("shiptostateInput1").set('value', currentModel[0].ShipTo.State);
+		registry.byId("shiptozipInput1").set('value', currentModel[0].ShipTo.Zip);
+		registry.byId("billtostreetInput1").set('value', currentModel[0].BillTo.Street);
+		registry.byId("billtocityInput1").set('value', currentModel[0].BillTo.City);
+		registry.byId("billtostateInput1").set('value', currentModel[0].BillTo.State);
+		registry.byId("billtozipInput1").set('value', currentModel[0].BillTo.Zip);
+	};
+
+	return {
+		// view init
+		init: function(){
+			currentModel = this.loadedModels.names;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId('shipto'), "click", function(){
+				//console.log("shipTo called. ");
+				dom.byId("billtodiv").style.display = "none";
+				dom.byId("shiptodiv").style.display = "";
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('billto'), "click", function(){
+				//console.log("billTo called. ");
+				dom.byId("billtodiv").style.display = "";
+				dom.byId("shiptodiv").style.display = "none";
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('reset1'), "click", function(){
+				//console.log("reset called. ");
+				setFromModel();
+				//console.log("reset done. ");
+			});
+			_connectResults.push(connectResult);
+
+			dom.byId("billtodiv").style.display = "none";
+			setFromModel();
+			
+		},
+
+		// view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/longListTestApp/config.json b/dojox/app/tests/longListTestApp/config.json
new file mode 100644
index 0000000..4ad45a0
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/config.json
@@ -0,0 +1,127 @@
+{
+	"id": "longListTestApp",
+	"name": "Scrollable Test App",
+	"description": "This is a test app for scrollable lists.",
+	"splash": "splash",
+
+	"loaderConfig": {
+		"paths": {
+			"longListTestApp": "../dojox/app/tests/longListTestApp"
+		}
+	},
+
+	"dependencies": [
+		"dojox/mobile/_base",
+		"dojox/mobile/_compat",
+		"dojox/mobile/Button",
+		"dojox/mobile/Heading",
+		"dojox/mobile/ListItem",
+		"dojox/mobile/RoundRectList",
+		"dojox/mobile/RoundRectCategory",
+		"dojox/mobile/EdgeToEdgeStoreList",
+		"dojox/mobile/LongListMixin",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/TabBarButton",
+		"dojox/app/widgets/Container",
+		"dojo/store/Memory",
+		"dojo/store/Observable",
+		"dojox/mobile/ScrollableView"
+	],
+	// Modules for the application.  They are basically used as the second
+	// array of mixins in a dojo.declare().  Modify the top level behavior
+	// of the application, how it processes the config or any other life cycle
+	// by creating and including one or more of these
+	"modules": [
+		"longListTestApp/longListTestApp"
+	],
+
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],
+
+	//stores we are using
+	"stores": {
+		"longlistStore":{
+	       "type": "dojo/store/Memory",
+	       "observable": true,
+		   "params": {
+                "data": "modelApp.list"
+		   }
+		}	   
+	},
+	
+	"has" : {
+		"phone" : {
+			"defaultView": "Footer1,Header1,LongList1"
+		},
+		"!phone" : {
+			"template": "longListTestApp/views/tablet/ViewScrollableLists.html",
+			"controller": "longListTestApp/views/tablet/ViewScrollableLists",
+			"defaultView": "Footer1,Header1,LongList1"
+		},
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+	// these are the possible transitions, 
+	// if a transition is set on a view or parent it will override the transition set on the transitionEvent or the defaultTransition in the config.
+	"transition": "slide",
+
+	//views are groups of views and models loaded at once
+	"views": {
+		"configuration": {
+			"defaultView": "ScrollableListSelection",
+			"transition": "slide",
+
+			"views": {
+				"ScrollableListSelection": {
+					"controller": "longListTestApp/views/configuration/ScrollableListSelection.js",
+					"template": "longListTestApp/views/configuration/ScrollableListSelection.html"
+				}
+			}
+		},
+		"Footer1": {
+			"controller": "longListTestApp/views/Footer1.js",
+			"template": "longListTestApp/views/Footer1.html",
+			"views": {
+				"Header1": {
+					"template": "longListTestApp/views/Header1.html",
+					"controller": "longListTestApp/views/Header1.js",
+					"views": {
+						"TestInfo": {
+							"transition": "none",
+							"template": "longListTestApp/views/TestInfo.html",
+							"controller": "longListTestApp/views/TestInfo.js"
+						},
+						"LongList1": {
+							"template": "longListTestApp/views/LongList1.html",
+							"controller": "longListTestApp/views/LongList1.js"
+						},
+						"LongList3": {
+							"template": "longListTestApp/views/LongList3.html",
+							"controller": "longListTestApp/views/LongList3.js"
+						}
+					}
+				}
+			}
+		},
+		"LongList2": {
+			"controller": "longListTestApp/views/LongList2.js",
+			"template": "longListTestApp/views/LongList2.html"
+		},
+		"LongList4": {
+			"controller": "longListTestApp/views/LongList4.js",
+			"template": "longListTestApp/views/LongList4.html"
+		}
+	}
+}
diff --git a/dojox/app/tests/longListTestApp/css/demo.css b/dojox/app/tests/longListTestApp/css/demo.css
new file mode 100644
index 0000000..2e49304
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/css/demo.css
@@ -0,0 +1,12 @@
+html,body {
+	width: 100%;
+	height: 100%;
+	background-color: black;
+}
+.lineItemPreventTouch {
+	width:2.5em;
+	height:3em; 
+	position:absolute; 
+	margin-left: -8px;
+	margin-top: -11px;
+}
diff --git a/dojox/app/tests/longListTestApp/css/tablet.css b/dojox/app/tests/longListTestApp/css/tablet.css
new file mode 100644
index 0000000..b13bfcf
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/css/tablet.css
@@ -0,0 +1,81 @@
+#header button {
+	position:absolute;
+	margin:0;
+}
+
+#navButton {
+	width:60px;
+}
+
+#loadDiv {
+	position:absolute;
+	left:0;
+	top:0;
+	width:100%;
+	height:100%;
+	z-index:999;
+}
+#loadDiv {
+	display:table;
+	font-size: 20px;
+	text-align:center;
+	background-color:white;
+}
+#loadDiv span {
+	display:table-cell;
+	vertical-align:middle;
+}
+
+body .mblProgContainer {
+	top:45%;
+	height: 45px;
+	width: 140px;
+	margin-left:-70px;
+	background-color: #2A2A28;
+	border-style: solid;
+	border-width: 2px;
+	border-color: #666666;
+	border-radius: 0.4em;
+	-webkit-border-radius: 0.4em;
+	-moz-border-radius: 0.4em;
+}
+
+body .mblProgContainer > div {
+	height: 100%;
+	width: 100%;
+	line-height: 45px;
+	vertical-align: middle;
+	font-size: 20px;
+	color: #c2c2c2;
+}
+
+body .mblProg {
+	left: 3px;
+	top: 3px;
+}
+
+body .mblProgContainer > div::after {
+	padding-left: 42px;
+	content: "Updating...";
+}
+
+#jsContent, #htmlContent {
+	padding-left:2px;
+}
+
+ at media screen and (max-width: 600px) {
+	#jsContent, #htmlContent {
+		font-size: 14px;
+	}
+}
+
+.hidden {
+	display:none;
+}
+
+div .navPane {
+	width:250px;
+	border-right:1px solid black;
+	background-color: #C5CCD3;
+	z-index:100;
+}
diff --git a/dojox/app/tests/longListTestApp/index.html b/dojox/app/tests/longListTestApp/index.html
new file mode 100644
index 0000000..be25857
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/index.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes"/>		
+		<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
+		<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">		
+		<title>Scrollable Test App</title>
+		<link rel="stylesheet" type="text/css" href="css/tablet.css">
+		<link type="text/css" href="css/demo.css" rel="stylesheet">
+	<style>
+	.subject {
+		font: bold 16px Helvetica;
+	}
+	.textBox {
+		font-size: 12px; 
+		font-weight: normal;
+		overflow: hidden;
+	}
+	</style>
+	
+		
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"
+   					data-dojo-config="mblThemeFiles:['@theme',['dojox/app/tests/longListTestApp','todo']]"></script>
+
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+				mblAlwaysHideAddressBar: true,
+				app: {debugApp: 1},  // set debugApp to log app transtions and view activate/deactivate
+				mvc: {debugBindings: 0},  // set on to debug mvc data bindings
+				async: 1">
+		</script>
+		<script>
+			require(["./src.js"], function(){
+			});
+		</script>
+		
+	</head>
+	<body style="overflow-y:hidden; overflow-x:hidden;">
+	</body>
+</html>
diff --git a/dojox/app/tests/longListTestApp/longListTestApp.js b/dojox/app/tests/longListTestApp/longListTestApp.js
new file mode 100644
index 0000000..f63e816
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/longListTestApp.js
@@ -0,0 +1,30 @@
+define(["dojox/mobile/ProgressIndicator"], function(ProgressIndicator){
+	return function(){
+		// the default select_item is 0, or will throw an error if directly transition to #details,EditTodoItem view
+		this.selected_item = 0;
+		this.selected_configuration_item = 0;
+		this.progressIndicator = null;
+		/*
+	 	* show or hide global progress indicator
+	 	*/
+	 	
+		this.showProgressIndicator = function(show){
+				
+			if(!this.progressIndicator){
+				this.progressIndicator = ProgressIndicator.getInstance({removeOnStop:false, startSpinning:true, size:40, center:true, interval:30});
+				// TODO: use dojo.body will throw no appendChild method error.
+				var body = document.getElementsByTagName("body")[0];
+				body.appendChild(this.progressIndicator.domNode);
+				this.progressIndicator.domNode.style.zIndex = 999;
+			}
+			if(show){
+				this.progressIndicator.domNode.style.visibility = "visible";
+				this.progressIndicator.start();
+			}else{
+				this.progressIndicator.stop();
+				this.progressIndicator.domNode.style.visibility = "hidden";
+			}
+			
+		}
+	};
+});
diff --git a/dojox/app/tests/longListTestApp/resources/data/repeat.json b/dojox/app/tests/longListTestApp/resources/data/repeat.json
new file mode 100644
index 0000000..191b80b
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/resources/data/repeat.json
@@ -0,0 +1,105 @@
+{
+  "identifier": "Serial",
+   "items": [ 
+                    {
+                        "Serial"  : "A111",
+                        "First"   : "Anne",
+                        "Last"    : "Ackerman",
+                        "Location": "NY",
+                        "Office"  : "1S76",
+                        "Email"   : "a.a at test.com",
+                        "Tel"     : "123-764-8237",
+                        "Fax"     : "123-764-8228"
+                    },
+                    {
+                        "Serial"  : "B111",
+                        "First"   : "Ben",
+                        "Last"    : "Beckham",
+                        "Location": "NY",
+                        "Office"  : "5N47",
+                        "Email"   : "b.b at test.com",
+                        "Tel"     : "123-764-8599",
+                        "Fax"     : "123-764-8600"
+                    },
+                    {
+                        "Serial"  : "C111",
+                        "First"   : "Chad",
+                        "Last"    : "Chapman",
+                        "Location": "CA",
+                        "Office"  : "1278",
+                        "Email"   : "c.c at test.com",
+                        "Tel"     : "408-764-8237",
+                        "Fax"     : "408-764-8228"
+                    },
+                    {
+                        "Serial"  : "D111",
+                        "First"   : "David",
+                        "Last"    : "Durham",
+                        "Location": "NJ",
+                        "Office"  : "C12",
+                        "Email"   : "d.d at test.com",
+                        "Tel"     : "514-764-8237",
+                        "Fax"     : "514-764-8228"
+                    },
+                    {
+                        "Serial"  : "E111",
+                        "First"   : "Emma",
+                        "Last"    : "Eklof",
+                        "Location": "NY",
+                        "Office"  : "4N76",
+                        "Email"   : "e.e at test.com",
+                        "Tel"     : "123-764-1234",
+                        "Fax"     : "123-764-4321"
+                    },
+                    {
+                        "Serial"  : "F111",
+                        "First"   : "Fred",
+                        "Last"    : "Fisher",
+                        "Location": "NJ",
+                        "Office"  : "V89",
+                        "Email"   : "f.f at test.com",
+                        "Tel"     : "514-764-8567",
+                        "Fax"     : "514-764-8000"
+                    },
+                    {
+                        "Serial"  : "G111",
+                        "First"   : "George",
+                        "Last"    : "Garnett",
+                        "Location": "NY",
+                        "Office"  : "7S11",
+                        "Email"   : "gig at test.com",
+                        "Tel"     : "123-999-8599",
+                        "Fax"     : "123-999-8600"
+                    },
+                    {
+                        "Serial"  : "H111",
+                        "First"   : "Hunter",
+                        "Last"    : "Huffman",
+                        "Location": "CA",
+                        "Office"  : "6532",
+                        "Email"   : "h.h at test.com",
+                        "Tel"     : "408-874-8237",
+                        "Fax"     : "408-874-8228"
+                    },
+                    {
+                        "Serial"  : "I111",
+                        "First"   : "Irene",
+                        "Last"    : "Ira",
+                        "Location": "NJ",
+                        "Office"  : "F09",
+                        "Email"   : "i.i at test.com",
+                        "Tel"     : "514-764-6532",
+                        "Fax"     : "514-764-7300"
+                    },
+                    {
+                        "Serial"  : "J111",
+                        "First"   : "John",
+                        "Last"    : "Jacklin",
+                        "Location": "CA",
+                        "Office"  : "6701",
+                        "Email"   : "j.j at test.com",
+                        "Tel"     : "408-764-1234",
+                        "Fax"     : "408-764-4321"
+                    }
+                ]
+}
diff --git a/dojox/app/tests/longListTestApp/src.js b/dojox/app/tests/longListTestApp/src.js
new file mode 100644
index 0000000..0d69a9b
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/src.js
@@ -0,0 +1,21 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/sniff"],
+	function(win, Application, json, has){
+	win.global.modelApp = {};
+	modelApp.list = { 
+		identifier: "label",
+		'items':[]
+	};
+
+
+	var configurationFile = "./config.json";
+
+	require(["dojo/text!"+configurationFile], function(configJson){
+		var config = json.fromJson(configJson);
+		var width = window.innerWidth || document.documentElement.clientWidth;
+		if(width <= 600){
+			has.add("phone", true);
+		}
+		has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+		Application(config);
+	});
+});
diff --git a/dojox/app/tests/longListTestApp/themes/android/todo.css b/dojox/app/tests/longListTestApp/themes/android/todo.css
new file mode 100644
index 0000000..616a45c
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/themes/android/todo.css
@@ -0,0 +1,25 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  padding-left: 5px;
+  padding-top: 16px;
+  padding-bottom: 16px;
+  padding-right: 1px;
+
+  font-size: 21px;
+  color: white;
+
+  border: 1px solid #ADAAAD;
+  border-radius: 8px;
+  background-color: black;
+}
+div .navPane {
+	background-color: black !important;
+	border-right: 1px solid #ADAAAD !important;
+}
+button.baseBtn {
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  height: 48px;
+  margin-bottom: 6px;
+}
diff --git a/dojox/app/tests/longListTestApp/themes/blackberry/todo.css b/dojox/app/tests/longListTestApp/themes/blackberry/todo.css
new file mode 100644
index 0000000..6d5ec0e
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/themes/blackberry/todo.css
@@ -0,0 +1,21 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  font-size: 18px;
+
+  padding-top: 16px;
+  padding-bottom: 16px;
+  padding-left: 7px;
+  
+  border: 1px solid #c6c7c6;
+  border-radius: 6px;
+  background-color: white;
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 0;
+}
+button.baseBtn {
+  font-size: 18px;
+  height: 48px;
+  margin-bottom: 8px;
+}
diff --git a/dojox/app/tests/longListTestApp/themes/iphone/todo.css b/dojox/app/tests/longListTestApp/themes/iphone/todo.css
new file mode 100644
index 0000000..21f9cb0
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/themes/iphone/todo.css
@@ -0,0 +1,31 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  color: #324f85;
+  
+  padding-left: 8px;
+  padding-right: 1px;
+  padding-top: 10px;
+  padding-bottom: 10px;
+
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
+  border-bottom-style: solid;
+  border-bottom-color: #ADAAAD;
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 0;
+}
+button.baseBtn {
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  height: 40px;
+  margin-bottom: 8px;
+}
diff --git a/dojox/app/tests/longListTestApp/views/Footer1.html b/dojox/app/tests/longListTestApp/views/Footer1.html
new file mode 100644
index 0000000..5ea37b3
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/Footer1.html
@@ -0,0 +1,9 @@
+<div class="view mblView">
+
+<!--	<h1 data-dojo-type="dojox/mobile/Heading" id="footer1" data-dojo-props="label: 'Scrollable List One Footer Bar'" data-app-constraint="bottom"></h1> -->
+	<ul id="footer1" data-dojo-type="dojox/mobile/TabBar" data-app-constraint="bottom" data-dojo-props='barType:"tabBar"'  style="z-index: 1;">
+		<li data-dojo-type="dojox/mobile/TabBarButton" data-dojo-props='icon1:"mblDomButtonCatalogTabIcon", selected:true'>catalogTab</li>
+		<li data-dojo-type="dojox/mobile/TabBarButton" data-dojo-props='icon1:"mblDomButtonFavoritesTabIcon"'>favoritesTab</li>
+		<li data-dojo-type="dojox/mobile/TabBarButton" data-dojo-props='icon1:"mblDomButtonUpdatesTabIcon"'>updatesTab</li>
+	</ul>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/longListTestApp/views/Footer1.js b/dojox/app/tests/longListTestApp/views/Footer1.js
new file mode 100644
index 0000000..5699f8d
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/Footer1.js
@@ -0,0 +1,18 @@
+define([], function(){
+	var app = null;
+	return {
+		init: function(){
+			app = this.app;
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+		}
+	};
+});
diff --git a/dojox/app/tests/longListTestApp/views/Header1.html b/dojox/app/tests/longListTestApp/views/Header1.html
new file mode 100644
index 0000000..356aa82
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/Header1.html
@@ -0,0 +1,7 @@
+<div class="view mblView">
+	<h1 id="heading1" data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List One"' data-app-constraint="top">
+		<span id="sc1back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="target: 'configuration,ScrollableListSelection', url: '#configuration,ScrollableListSelection', transitionDir: -1">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">5</span>
+	</h1>     
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/longListTestApp/views/Header1.js b/dojox/app/tests/longListTestApp/views/Header1.js
new file mode 100644
index 0000000..c426cae
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/Header1.js
@@ -0,0 +1,67 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/store/Memory", "dojo/store/Observable", "dojo/sniff"],
+function(dom, domStyle, connect, Memory, Observable, has){
+
+		var _connectResults = []; // events connect result
+		var backId = 'sc1back1';
+		var insert10Id = 'sc1insert10x';
+		var app = null;
+		
+		var loadMore = function(){
+			if(!app){
+				return;
+			}
+			if(!app.listStart){
+				app.listStart = 1;
+				app.listCount = 5;
+			}
+			setTimeout(function(){ // to simulate network latency
+				for(var i = app.listStart; i < app.listStart+5; i++){
+					var newdata = {'label': 'Item #'+i};
+					app.stores.longlistStore.store.put(newdata);
+				}
+				app.listStart += app.listCount;
+				app.listTotal = app.listStart-1;				
+				return false;
+			}, 500);
+		};
+	return {
+		init: function(){
+			app = this.app;
+			var memoryStore = new Memory({data: {}});
+			new Observable(memoryStore);
+
+			var connectResult;
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				loadMore();
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+		},
+				
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/longListTestApp/views/LongList1.html b/dojox/app/tests/longListTestApp/views/LongList1.html
new file mode 100644
index 0000000..c66c332
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/LongList1.html
@@ -0,0 +1,11 @@
+<div class="view mblView">
+
+	<div data-dojo-type="dojox/app/widgets/Container" data-dojo-props="scrollable: true, fixedFooter:'footer1'" data-app-constraint="center">
+
+		<div class="field-title">Should scroll from under the top header to the end of the page, this text will also scroll.</div>
+
+		<form name="repeatTestForm">
+				<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" data-dojo-mixins="dojox/mobile/LongListMixin" id="list" data-dojo-props='append:true'></ul>
+		</form>
+	</div>
+</div>
diff --git a/dojox/app/tests/longListTestApp/views/LongList1.js b/dojox/app/tests/longListTestApp/views/LongList1.js
new file mode 100644
index 0000000..65a6eb3
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/LongList1.js
@@ -0,0 +1,40 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect","dijit/registry"],
+function(dom, domStyle, connect, registry){
+		var _connectResults = []; // events connect result
+		var	list = null;
+		var listId = 'list';
+		var app = null;
+	return {
+		init: function(){
+			app = this.app;
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			app.list1 = registry.byId(listId);
+
+			list = app.list1;
+			if(!list.Store){
+				list.setStore(app.stores.longlistStore.store);
+			}
+
+			if(registry.byId("heading1")){
+				registry.byId("heading1").labelDivNode.innerHTML = "Long List One";
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/longListTestApp/views/LongList2.html b/dojox/app/tests/longListTestApp/views/LongList2.html
new file mode 100644
index 0000000..f8edada
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/LongList2.html
@@ -0,0 +1,21 @@
+<div class="view mblView">
+	<h1 id="heading2" data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Long List Two"' data-app-constraint="top">
+		<span id="sc2back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="target: 'configuration,ScrollableListSelection', url: '#configuration,ScrollableListSelection', transitionDir: -1">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc2insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">5</span>
+	</h1>     
+	<div data-app-constraint="top">
+		<div class="field-title">Should scroll between this text and the bottom footer.</div>
+	</div>     
+
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+
+		<div class="field-title">Should scroll from under the top header to the end of the page, this text will also scroll.</div>
+
+		<form name="repeatTestForm3">
+				<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" data-dojo-mixins="dojox/mobile/LongListMixin" id="list2" data-dojo-props='append:true'></ul> 
+		<!--		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" id="list3" data-dojo-props='append:true'></ul> -->
+				
+		</form>
+	</div>
+</div>
diff --git a/dojox/app/tests/longListTestApp/views/LongList2.js b/dojox/app/tests/longListTestApp/views/LongList2.js
new file mode 100644
index 0000000..8520c8a
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/LongList2.js
@@ -0,0 +1,68 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect","dijit/registry", "dojo/sniff"],
+function(dom, domStyle, connect, registry, has){
+		var _connectResults = []; // events connect result
+		var	list = null;
+		var listId = 'list2';
+		var backId = 'sc2back1';
+		var insert10Id = 'sc2insert10x';
+		var app = null;
+
+	var loadMore = function(){
+		if(!app){
+			return;
+		}
+		if(!app.listStart){
+			app.listStart = 1;
+			app.listCount = 5;
+		}
+		setTimeout(function(){ // to simulate network latency
+			for(var i = app.listStart; i < app.listStart+5; i++){
+				var newdata = {'label': 'Item #'+i};
+				app.stores.longlistStore.store.put(newdata);
+			}
+			app.listStart += app.listCount;
+			app.listTotal = app.listStart-1;
+			return false;
+		}, 500);
+	};
+	return {
+		init: function(){
+			app = this.app;
+			
+			var connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				loadMore();
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			
+			app.list2 = registry.byId(listId);
+
+			list = app.list2;
+			if(!list.store){
+				list.setStore(app.stores.longlistStore.store);
+			}
+
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/longListTestApp/views/LongList3.html b/dojox/app/tests/longListTestApp/views/LongList3.html
new file mode 100644
index 0000000..6bc6833
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/LongList3.html
@@ -0,0 +1,15 @@
+<div class="view mblView">
+<!--
+	<div data-app-constraint="top">
+	</div>
+-->
+	<div data-dojo-type="dojox/app/widgets/Container" data-dojo-props="scrollable: true, fixedFooter:'footer1'"  data-app-constraint="center">
+
+		<div class="field-title">Should scroll from under the top header to the end of the page, this text will also scroll.</div>
+
+		<form name="repeatTestForm3">
+				<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" data-dojo-mixins="dojox/mobile/LongListMixin" id="list3" data-dojo-props='append:true'></ul>
+		<!--		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" id="list3" data-dojo-props='append:true'></ul> -->
+		</form>
+	</div>
+</div>
diff --git a/dojox/app/tests/longListTestApp/views/LongList3.js b/dojox/app/tests/longListTestApp/views/LongList3.js
new file mode 100644
index 0000000..d04aceb
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/LongList3.js
@@ -0,0 +1,42 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect","dijit/registry"],
+function(dom, domStyle, connect, registry){
+
+		var _connectResults = []; // events connect result
+		var	list = null;
+		var listId = 'list3';
+		var app = null;
+	return {
+		init: function(){
+			app = this.app;
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			// description:
+			//		beforeActivate will save the list is app and set the store on the list
+			app.list3 = registry.byId(listId);
+			list = app.list3;
+			if(!list.store){
+				list.setStore(app.stores.longlistStore.store);
+			}
+
+			if(registry.byId("heading1")){
+				registry.byId("heading1").labelDivNode.innerHTML = "Long List Three";
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/longListTestApp/views/LongList4.html b/dojox/app/tests/longListTestApp/views/LongList4.html
new file mode 100644
index 0000000..f035b43
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/LongList4.html
@@ -0,0 +1,22 @@
+<div class="view mblView">
+	<h1 id="heading4" data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Long List Four"' data-app-constraint="top">
+		<span id="sc4back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="target: 'configuration,ScrollableListSelection', url: '#configuration,ScrollableListSelection', transitionDir: -1">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc4insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">5</span>
+	</h1>     
+	<div data-app-constraint="top">
+		<div class="field-title">Should scroll between this text and the bottom footer.</div>
+	</div>     
+
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+
+		<div class="field-title">Should scroll from under the top header to the end of the page, this text will also scroll.</div>
+
+		<form name="repeatTestForm3">
+				<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" data-dojo-mixins="dojox/mobile/LongListMixin" id="list4" data-dojo-props='append:true'></ul> 
+		<!--		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" id="list4" data-dojo-props='append:true'></ul> -->
+				
+		</form>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Scrollable List One Footer Bar'" data-app-constraint="bottom"></h1>
+</div>
diff --git a/dojox/app/tests/longListTestApp/views/LongList4.js b/dojox/app/tests/longListTestApp/views/LongList4.js
new file mode 100644
index 0000000..5ebd1ed
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/LongList4.js
@@ -0,0 +1,68 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect","dijit/registry", "dojo/sniff"],
+function(dom, domStyle, connect, registry, has){
+		var _connectResults = []; // events connect result
+		var	list = null;
+		var listId = 'list4';
+		var backId = 'sc4back1';
+		var insert10Id = 'sc4insert10x';
+		var app = null;
+
+	var loadMore = function(){
+		if(!app){
+			return;
+		}
+		if(!app.listStart){
+			app.listStart = 1;
+			app.listCount = 5;
+		}
+		setTimeout(function(){ // to simulate network latency
+			for(var i = app.listStart; i < app.listStart+5; i++){
+				var newdata = {'label': 'Item #'+i};
+				app.stores.longlistStore.store.put(newdata);
+			}
+			app.listStart += app.listCount;
+			app.listTotal = app.listStart-1;
+			return false;
+		}, 500);
+	};
+	return {
+		init: function(){
+			app = this.app;
+			
+			var connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				loadMore();
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			
+			app.list4 = registry.byId(listId);
+
+			list = app.list4;
+			if(!list.store){
+				list.setStore(app.stores.longlistStore.store);
+			}
+
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/longListTestApp/views/TestInfo.html b/dojox/app/tests/longListTestApp/views/TestInfo.html
new file mode 100644
index 0000000..48a6cbf
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/TestInfo.html
@@ -0,0 +1,25 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+		<div id="tst1WrapperB" style="visibility:visible">
+			<br>
+			<br>
+			<div class="field-title">Each test is sharing an observable store and using an EdgeToEdgeStoreList with a LongListMixin.</div>
+			<div class="field-title">Use the +5 button to add 5 rows to the lists, it will update all lists.</div>
+			<br>
+			<div class="field-title">There was a problem with LongListMixin in a scrollable view where it would not get added on the pages which were not visible when the rows were added, but now it is fixed.</div>
+			<br>
+			<div class="field-title">The fix to the above problem caused a new problem where it would scroll up a little on a transition back to a page which had been scrolled all the way down.</div>
+			<br>
+			<div class="field-title">My attempt to fix that problem worked, but only if the footer were included as a sibling of the scrollable container, or if fixedFooter is set on the Container. If the footer is from a different view it will not be found without fixedFooter.</div>
+			<br>
+			<div class="field-title">I have setup LongList One and Three using the separate Footer View, and Long List Two and Four with their own footer.  So Two and Four work and One and Three only work because fixedFooter is set.</div>
+			<br>
+			<div class="field-title">To see what had been the problem with LongList One or Three, select that view, hit the +5 button enough to fill the page, scroll to the bottom and then hit select the view again.</div>
+			<br>
+			<div class="field-title">View Two or Four, do not have the problem because the Footer is being found and the size of the footer is taken into account for the size of the scrollable area.</div>
+			<br>
+			<div class="field-title">If fixedHeader is set (in addition to fixedFooter) that will cause problems, similar to not setting fixedFooter, it will not scroll to the bottom correctly.</div>
+			<br><br>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/longListTestApp/views/TestInfo.js b/dojox/app/tests/longListTestApp/views/TestInfo.js
new file mode 100644
index 0000000..2779b4e
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/TestInfo.js
@@ -0,0 +1,37 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/sniff"],
+function(dom, domStyle, connect, has){
+		var _connectResults = []; // events connect result
+		var backId = 'ti1back1';
+		var wrapperIdB = 'tst1WrapperB';
+	return {
+		init: function(){			
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperB") && !has("phone")){ 
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+			domStyle.set(dom.byId(wrapperIdB), "visibility", "visible");  // show the view when it is ready
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/longListTestApp/views/configuration/ScrollableListSelection.html b/dojox/app/tests/longListTestApp/views/configuration/ScrollableListSelection.html
new file mode 100644
index 0000000..a390168
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/configuration/ScrollableListSelection.html
@@ -0,0 +1,49 @@
+<div class="view mblView">
+	
+	<div>
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-app-constraint="top">Select Scrollable List</h1>
+		
+			<ul data-dojo-type="dojox/mobile/RoundRectList"  data-dojo-props='variableHeight:true'>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Footer1,Header1,LongList1', url: '#Footer1,Header1,LongList1'">
+					<div class="textBox">
+						<div class="subject">Long List One</div>
+						Uses app/widgets/Container with a parent Header view no footer with data-app-constraint and EdgeToEdgeStoreList				
+					</div>				
+				</li>
+			
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'LongList2', url: '#LongList2'">
+					<div class="textBox">
+						<div class="subject">Long List Two</div>
+						Uses app/widgets/Container with a fixed Header no footer with data-app-constraint and EdgeToEdgeStoreList				
+					</div>				
+				</li>
+			
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Footer1,Header1,LongList3', url: '#Footer1,Header1,LongList3'">
+					<div class="textBox">
+						<div class="subject">Long List Three</div>
+						Uses app/widgets/Container with a fixed Header no footer with data-app-constraint and EdgeToEdgeStoreList				
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, title:'List',target: 'LongList4', url: '#LongList4'">
+					<div class="textBox">
+						<div class="subject">Long List Four</div>
+						Uses app/widgets/Container with a fixed Header and footer defined in LongList4 with data-app-constraint and EdgeToEdgeStoreList				
+					</div>				
+				</li>
+				
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Footer1,Header1,TestInfo', url: '#Footer1,Header1,TestInfo'">
+					<div class="textBox">
+						<div class="subject">Test Instructions</div>
+						Test instructions, notes and known problems (transition none)				
+					</div>				
+				</li>
+			</ul>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/longListTestApp/views/configuration/ScrollableListSelection.js b/dojox/app/tests/longListTestApp/views/configuration/ScrollableListSelection.js
new file mode 100644
index 0000000..08f98eb
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/configuration/ScrollableListSelection.js
@@ -0,0 +1,23 @@
+define([],function(){
+
+	var app = null;
+
+	return {
+		init: function(){
+			app = this.app;
+		},
+		
+		beforeActivate: function(){
+			app.stopTransition = false;
+		},
+		
+		afterActivate: function(){
+		},
+		
+		beforeDeactivate: function(){
+		},
+
+		afterDeactivate: function(){
+		}
+	};
+});
diff --git a/dojox/app/tests/longListTestApp/views/tablet/ViewScrollableLists.html b/dojox/app/tests/longListTestApp/views/tablet/ViewScrollableLists.html
new file mode 100644
index 0000000..c7a69f0
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/tablet/ViewScrollableLists.html
@@ -0,0 +1,57 @@
+<div>
+	<!-- left -->
+	<div data-dojo-type="dojox/app/widgets/Container" class="navPane" data-app-constraint="left">
+		<h1 id="tab1WrapperA" style="visibility:hidden" data-dojo-type="dojox/mobile/Heading" data-app-constraint="top">
+			Select Scrollable List</h1>
+
+		<div id="tab1WrapperB" style="visibility:hidden"
+			 data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center"
+			 data-dojo-props="scrollable: true">
+			<ul data-dojo-type="dojox/mobile/RoundRectList" data-dojo-props='variableHeight:true'>
+
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Footer1,Header1,LongList1', url: '#Footer1,Header1,LongList1'">
+					<div class="textBox">
+						<div class="subject">Long List One</div>
+						Uses app/widgets/Container with a parent Header view no footer with data-app-constraint and
+						EdgeToEdgeStoreList
+					</div>
+				</li>
+
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'LongList2', url: '#LongList2'">
+					<div class="textBox">
+						<div class="subject">Long List Two</div>
+						Uses app/widgets/Container with a fixed Header no footer with data-app-constraint and
+						EdgeToEdgeStoreList
+					</div>
+				</li>
+
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Footer1,Header1,LongList3', url: '#Footer1,Header1,LongList3'">
+					<div class="textBox">
+						<div class="subject">Long List Three</div>
+						Uses app/widgets/Container with a fixed Header no footer with data-app-constraint and
+						EdgeToEdgeStoreList
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'LongList4', url: '#LongList4'">
+					<div class="textBox">
+						<div class="subject">Long List Four</div>
+						Uses app/widgets/Container with a fixed Header and footer defined in LongList4 with
+						data-app-constraint and EdgeToEdgeStoreList
+					</div>
+				</li>
+
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Footer1,Header1,TestInfo', url: '#Footer1,Header1,TestInfo'">
+					<div class="textBox">
+						<div class="subject">Test Instructions</div>
+						Test instructions, notes and known problems (transition none)
+					</div>
+				</li>
+			</ul>
+		</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/longListTestApp/views/tablet/ViewScrollableLists.js b/dojox/app/tests/longListTestApp/views/tablet/ViewScrollableLists.js
new file mode 100755
index 0000000..71f3aec
--- /dev/null
+++ b/dojox/app/tests/longListTestApp/views/tablet/ViewScrollableLists.js
@@ -0,0 +1,26 @@
+define([], function(){
+	return {
+		init: function(){
+			console.log("navigation view init ok");
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+			console.log("ViewScrollableLists view beforeActivate called");
+		// this will be done in the other views, since beforeActivate is not called for the left view...
+		//	if(dom.byId("tab1WrapperA")){ 
+		//		domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+		//		domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+		//	}
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+			console.log("ViewScrollableLists view beforeActivate called");
+		}
+		
+		
+	};
+});
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/config.json b/dojox/app/tests/mediaQuery3ColumnApp/config.json
new file mode 100644
index 0000000..26e72d0
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/config.json
@@ -0,0 +1,124 @@
+{
+	"id": "MQ3ColApp",
+	"name": "mediaQuery 3 column App",
+	"description": "A mediaQuery 3 column App",
+	"splash": "splash",
+
+	"loaderConfig": {
+		"paths": {
+			"mediaQuery3ColumnApp": "../dojox/app/tests/mediaQuery3ColumnApp"
+		}
+	},
+
+	"dependencies": [
+		"dojox/mobile/_base",
+		"dojox/mobile/compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/RoundRectList",
+		"dojox/mobile/EdgeToEdgeList",
+		"dojox/mobile/Heading",
+		"dojox/mobile/ScrollableView",
+		"dojo/store/Memory",
+		"dojox/mobile/View",
+		"dojox/app/widgets/Container"
+	],
+
+	"modules": [],
+	
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/tests/mediaQuery3ColumnApp/controllers/CssLayout",
+		"dojox/app/tests/mediaQuery3ColumnApp/controllers/NavigationController"
+	],
+
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		},
+		"isInitiallySmall" : {
+			//the name of the view to load when the app is initialized.
+			"defaultView": "navLeft+navCenter+lastRight"
+		},
+		"!isInitiallySmall" : {
+			//the name of the view to load when the app is initialized.
+			"defaultView": "navLeft+mainCenter+lastRight"
+		}
+	},	
+
+
+	// these are the possilbe defaultTransitions
+	"defaultTransition": "slide",
+	//"defaultTransition": "none",
+	//"defaultTransition": "fade",
+	//"defaultTransition": "flip",     
+
+	//"transition": "flip",  //fade may have a problem     
+
+	"views": {
+		"navLeft":{
+			"constraint" : "left",
+			"controller": "mediaQuery3ColumnApp/views/nav/navigation.js",
+			"template": "mediaQuery3ColumnApp/views/nav/navigation.html",
+			"nls":      "mediaQuery3ColumnApp/nls/app"
+		},
+		"navCenter":{
+			"constraint" : "center",
+			"controller": "mediaQuery3ColumnApp/views/nav/navigation.js",
+			"template": "mediaQuery3ColumnApp/views/nav/navigation.html"
+		},
+		"mainCenter":{
+			"constraint" : "center",
+			"controller": "mediaQuery3ColumnApp/views/main/main.js",
+			"template": "mediaQuery3ColumnApp/views/main/main.html",
+			"nls":      "mediaQuery3ColumnApp/nls/app"
+		},
+		"mainCenter2":{
+			"constraint" : "center",
+			"controller": "mediaQuery3ColumnApp/views/main/main.js",
+			"template": "mediaQuery3ColumnApp/views/main/main.html"
+		},
+		"mainCenter3":{
+			"constraint" : "center",
+			"controller": "mediaQuery3ColumnApp/views/main/main.js",
+			"template": "mediaQuery3ColumnApp/views/main/main.html"
+		},
+		"mainLeft":{
+			"constraint" : "left",
+			"controller": "mediaQuery3ColumnApp/views/main/main.js",
+			"template": "mediaQuery3ColumnApp/views/main/main.html"
+		},
+		"lastRight":{
+			"constraint" : "right",
+			"controller": "mediaQuery3ColumnApp/views/last/last.js",
+			"template": "mediaQuery3ColumnApp/views/last/last.html"
+		},
+		"lastCenter":{
+			"constraint" : "center",
+			"controller" : "mediaQuery3ColumnApp/views/last/last.js",
+			"template": "mediaQuery3ColumnApp/views/last/last.html"
+		},
+		"TestInfo": {
+			"constraint" : "center",
+			"controller" : "mediaQuery3ColumnApp/views/main/TestInfo.js",
+			"template": "mediaQuery3ColumnApp/views/main/TestInfo.html"
+		},	
+		"header":{
+			"constraint" : "top",
+			"template": "mediaQuery3ColumnApp/views/header.html"
+		}
+	}	
+}
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/controllers/CssLayout.js b/dojox/app/tests/mediaQuery3ColumnApp/controllers/CssLayout.js
new file mode 100644
index 0000000..3c6566f
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/controllers/CssLayout.js
@@ -0,0 +1,61 @@
+define(["dojo/_base/declare", "dojo/dom", "dojo/dom-style",
+		"dojo/dom-class", "dojo/dom-attr", "dojo/dom-construct", 
+		"dojox/app/controllers/LayoutBase"],
+function(declare, dom, domStyle, domClass, domAttr, domConstruct, LayoutBase){
+	// module:
+	//		dojox/app/tests/mediaQuery3ColumnApp/controllers/CssLayout
+	// summary:
+	//		Will layout an application with a BorderContainer.  
+	//		Each view to be shown in a region of the BorderContainer will be wrapped in a StackContainer and a ContentPane.
+	//		
+
+	return declare("dojox/app/tests/mediaQuery3ColumnApp/controllers/CssLayout", LayoutBase, {
+
+		constructor: function(app, events){
+			// summary:
+			//		bind "app-initLayout" and "app-layoutView" events on application instance.
+			//
+			// app:
+			//		dojox/app application instance.
+			// events:
+			//		{event : handler}
+		},
+
+		initLayout: function(event){
+			// summary:
+			//		Response to dojox/app "app-initLayout" event which is setup in LayoutBase.
+			//		The initLayout event is called once when the View is being created the first time.
+			//
+			// example:
+			//		Use emit to trigger "app-initLayout" event, and this function will respond to the event. For example:
+			//		|	this.app.emit("app-initLayout", view);
+			//
+			// event: Object
+			// |		{"view": view, "callback": function(){}};
+			this.app.log("in app/controllers/CssLayout.initLayout event.view.name=[",event.view.name,"] event.view.parent.name=[",event.view.parent.name,"]");
+
+
+			this.app.log("in app/controllers/CssLayout.initLayout event.view.constraint=",event.view.constraint);
+			var constraint = event.view.constraint;  // constraint holds the region for this view, center, top etc.
+			
+			event.view.parent.domNode.appendChild(event.view.domNode);
+			domClass.add(event.view.domNode, constraint);  // set the class to the constraint
+
+			this.inherited(arguments);
+		},
+
+		onResize: function(){
+			// do nothing on resize
+		},
+
+		hideView: function(view){
+			domStyle.set(view.domNode, "display", "none !important");
+			//domClass.add(view.domNode, "hide");
+		},
+
+		showView: function(view){
+			domStyle.set(view.domNode, "display", "block");
+			//domClass.remove(view.domNode, "hide");			
+		}
+	});
+});
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/controllers/NavigationController.js b/dojox/app/tests/mediaQuery3ColumnApp/controllers/NavigationController.js
new file mode 100644
index 0000000..51e278a
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/controllers/NavigationController.js
@@ -0,0 +1,213 @@
+define(["dojo/_base/lang","dojo/_base/declare", "dojo/dom", "dojo/dom-style", "dojo/sniff", "dojo/_base/window", "dojo/_base/config",
+		"dojo/dom-class", "dojo/dom-attr", "dojo/dom-construct", "dojox/app/Controller"],
+function(lang, declare, dom, domStyle, has, win, config, domClass, domAttr, domConstruct, Controller){
+	// module:
+	//		dojox/app/tests/mediaQuery3ColumnApp/controllers/NavigationController
+	// summary:
+	//		Used to handle Navigation for the application 
+	//		
+
+	return declare("dojox/app/tests/mediaQuery3ColumnApp/controllers/NavigationController", Controller, {
+
+		constructor: function(app){
+			this.app = app;
+			// large > 860 medium <= 860  small <= 560 
+			this.small = 560;
+			this.medium = 860;
+	
+			this.lastTransition = "";
+			this.lastParams = "";
+			this.lastEvent = null;
+			this.lastSize = "";
+			
+			this.events = {
+				"MQ3ColApp/TestOption1": this.TestOption1,
+				"MQ3ColApp/MainOption1": this.MainOption1,
+				"MQ3ColApp/MainOption2": this.MainOption2,
+				"MQ3ColApp/MainOption3": this.MainOption3,
+				"MQ3ColApp/LastOption1": this.LastOption1,
+				"MQ3ColApp/LastOption2": this.LastOption2,
+				"MQ3ColApp/LastOption3": this.LastOption3,
+				"MQ3ColApp/BackFromMain": this.BackFromMain,
+				"MQ3ColApp/BackFromTest": this.BackFromTest,
+				"MQ3ColApp/BackFromLast": this.BackFromLast
+			};
+			
+			// if we are using dojo mobile & we are hiding address bar we need to be bit smarter and listen to
+			// dojo mobile events instead
+			if(config.mblHideAddressBar){
+				topic.subscribe("/dojox/mobile/afterResizeAll", lang.hitch(this, this.onResize));
+			}else{
+				// bind to browsers orientationchange event for ios otherwise bind to browsers resize
+				this.bind(win.global, has("ios") ? "orientationchange" : "resize", lang.hitch(this, this.onResize));
+			}
+		},
+		
+		TestOption1: function(e){
+			this.doTransition(e, "navLeft","TestInfo","lastRight", null, null);
+		},
+		MainOption1: function(e){
+			var params = {"mainCenter":{'mainSel':"MainOption1","tparam1":"tValue1"}};
+			console.log("in NavigationController MainOption1 called.");
+			this.doTransition(e, "navLeft","mainCenter","lastRight", params, false);
+		},
+		MainOption2: function(e){
+			var params = {"mainCenter2":{'mainSel':"MainOption2"}};
+			console.log("in NavigationController MainOption2 called.");
+			this.doTransition(e, "navLeft","mainCenter2","lastRight", params, false);
+		},
+		MainOption3: function(e){
+			var params = {"mainCenter3":{'mainSel':"MainOption3"}};
+			console.log("in NavigationController MainOption3 called.");
+			this.doTransition(e, "navLeft","mainCenter3","lastRight", params, false);
+		},
+		LastOption1: function(e){
+			var params = lang.mixin(this.lastParams,{'lastSel':"LastOption1"});
+			if(!this.isLarge()){
+				console.log("in NavigationController LastOption1 called with isMedium or isSmall.");
+				this.doTransition(e, "navLeft","lastCenter","lastRight", params, false);
+			}else{
+				console.log("in NavigationController LastOption1 called with isLarge.");
+				this.doTransition(e, "navLeft", this._getMainCenter(),"lastRight", params, false);
+			}
+		},
+		LastOption2: function(e){
+			var params = lang.mixin(this.lastParams,{'lastSel':"LastOption2"});
+			if(!this.isLarge()){
+				console.log("in NavigationController LastOption2 called with isMedium or isSmall.");
+				this.doTransition(e, "navLeft","lastCenter","lastRight", params, false);
+			}else{
+				console.log("in NavigationController LastOption2 called with isLarge.");
+				this.doTransition(e, "navLeft", this._getMainCenter(),"lastRight", params, false);
+			}
+		},
+		LastOption3: function(e){
+			var params = lang.mixin(this.lastParams,{'lastSel':"LastOption3"});
+			if(!this.isLarge()){
+				console.log("in NavigationController LastOption3 called with isMedium or isSmall.");
+				this.doTransition(e, "navLeft","lastCenter","lastRight", params, false);
+			}else{	
+				console.log("in NavigationController LastOption2 called with isLarge.");
+				this.doTransition(e, "navLeft", this._getMainCenter(),"lastRight", params, false);
+			}
+		},
+
+		// Called to get the correct mainCenter
+		_getMainCenter: function(){
+			if(this.lastCenter == "mainCenter" || this.lastCenter == "mainCenter2" || this.lastCenter == "mainCenter3"){
+				return this.lastCenter;
+			}
+			return "mainCenter";
+
+		},
+		// These BackFrom ones need work to really go back in the history.
+		BackFromMain: function(e){
+			if(this.isSmall()){
+				console.log("in NavigationController BackFromMain called with isSmall.");
+				// not sure about using his.lastParams
+				this.doTransition(e, "navLeft","navCenter","lastRight", this.lastParams, true);
+			}else{
+				console.log("in NavigationController BackFromMain called with !isSmall.");
+				this.doTransition(e, "mainCenter","navLeft","lastRight", this.lastParams, true);
+			}
+		},
+		BackFromTest: function(e){
+			if(this.isSmall()){
+				console.log("in NavigationController BackFromTest called with isSmall.");
+				this.doTransition(e, "navLeft","navCenter","lastRight", this.lastParams, true);
+			}else{
+				console.log("in NavigationController BackFromTest called with !isSmall.");
+				this.doTransition(e, "navLeft","mainCenter","lastRight", this.lastParams, true);
+			}
+		},
+		BackFromLast: function(e){
+			console.log("in NavigationController BackFromLast called.");
+			this.doTransition(e, "navLeft","mainCenter","lastRight", this.lastParams, true);
+		},
+
+		doTransition: function(e, left, center, right, params, back){
+			this.lastLeft = left;
+			this.lastCenter = center;
+			this.lastRight = right;
+			this.lastParams = params;
+			var views = this.lastTransition = left+"+"+center;
+			if(right !== "-lastRight"){
+				views = this.lastTransition = views+"+"+right;
+			}else{
+				views = this.lastTransition = views+right;
+			}
+			console.log("in NavigationController views = "+views+"  this.params="+this.params);
+			
+			this.lastParams = params;
+			this.lastEvent = e;
+			var transOpts = {
+				title: views,
+				target: views,
+				url: "#"+views,
+				reverse: back,
+			//	"transition": "none",
+				params:params
+			};
+			this.app.transitionToView(e.target,transOpts,e);
+		},
+
+	
+		
+		onResize: function(){
+			// this is called on a resize, normally we want to use css to adjust, but a resize or an orientation change
+			// causes us to be showing duplicate views, then we need to update the views being shown.
+			
+			if(this.lastSize == this.getSize()){
+				return;
+			}
+			this.lastSize = this.getSize();
+			
+			// for a large screen we should always be showing "navLeft+mainCenter+lastRight"
+			if(this.isLarge() && this.lastEvent && 
+				(this.lastTransition !== "navLeft+mainCenter+lastRight" && this.lastTransition !== "navLeft+TestInfo+lastRight")){
+				console.log("in NavigationController onResize isLarge calling transition with navLeft+mainCenter+lastRight");
+				this.doTransition(this.lastEvent, "navLeft","mainCenter","lastRight", this.lastParams);
+			}else if(this.isMedium() && this.lastEvent){
+				// for a medium screen we need to check for "navLeft+navCenter+lastRight" and for "navLeft+lastCenter+lastRight"
+				if(this.lastTransition == "navLeft+navCenter+lastRight"){
+					console.log("in NavigationController onResize isMedium and navCenter calling transition with navLeft+mainCenter+lastRight");
+					this.doTransition(this.lastEvent, "navLeft","mainCenter","lastRight", this.lastParams);
+				}else if(this.lastTransition == "navLeft+lastCenter+lastRight"){
+					console.log("in NavigationController onResize isMedium and lastCenter calling transition with navLeft+LastCenter+lastRight");
+					this.doTransition(this.lastEvent, "navLeft","lastCenter","lastRight", this.lastParams);
+				}
+			}
+
+		},
+
+		getSize: function(){
+			if(this.isLarge()){
+				return "large";
+			}else if(this.isMedium()){
+				return "medium";
+			}else{
+				return "small";
+			}
+		},
+		
+		// large > 860 medium <= 860  small <= 560 
+		isLarge: function(){
+			var width = window.innerWidth || document.documentElement.clientWidth;
+			return width > this.medium;
+
+		},
+
+		isMedium: function(){
+			var width = window.innerWidth || document.documentElement.clientWidth;
+			return width <= this.medium && width > this.small;
+
+		},
+
+		isSmall: function(){
+			var width = window.innerWidth || document.documentElement.clientWidth;
+			return width <= this.small;
+
+		}
+		
+	});
+});
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/css/mediaQuery3ColumnApp.css b/dojox/app/tests/mediaQuery3ColumnApp/css/mediaQuery3ColumnApp.css
new file mode 100644
index 0000000..b303f68
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/css/mediaQuery3ColumnApp.css
@@ -0,0 +1,267 @@
+.hide {
+	display: none !important;
+}
+
+.center {
+	float: left;
+	height: 100%; 
+	width: 59.7%;
+}
+
+.hideOnTablet {
+	display: none !important;
+}
+
+.hideOnLarge {
+	display: none !important;
+}
+
+.left {
+	float: left; 
+	width: 20% !important;
+	border-right:1px solid black;
+	background-color: #C5CCD3;
+	z-index: 100;	
+	height: 100%; 
+}
+
+.right {
+	float: right; 
+	width: 20%;
+	border-left:1px solid black;
+	background-color: #C5CCD3;
+	z-index: 100;	
+	height: 100%; 
+}
+
+/* Medium */
+ at media screen and (max-width: 860px) {
+
+	.left {
+		float: left; 
+		width:20%;
+	}
+
+	.center {
+		float: left;
+		width: 79.6%; 
+	}
+	.showOnMedium {
+		display: block !important;
+	}
+
+	.hideOnMedium {
+		display: none !important;
+	}
+}
+
+
+/* Small */
+ at media screen and (max-width: 560px) {
+
+	.left {
+		float: left; 
+		width:0;
+	}
+
+	.center {
+		float: left;
+		width: 99.6%; 
+	}
+
+	.showOnSmall {
+		display: block !important;
+	}
+	.hideOnSmall {
+		display: none !important;
+	}
+	.hideOnPhone {
+		display: none !important;
+	}
+}
+
+/*
+ at media only screen and (orientation: portrait) {
+
+	.left {
+		float: left; 
+		width:0px;
+	}
+
+	.center {
+		float: left;
+		width: 99.6%; 
+	}
+
+	.hideOnPhone {
+		display: none !important;
+	}
+
+	.hideOnTablet {
+		display: block !important;
+	}
+
+}
+
+ at media only screen and (orientation: landscape) and (max-width: 568px) {
+	.center {
+		float: left;
+		width: 80%;
+		height: 100%;
+		
+	}
+
+	.left {
+		float: left; 
+		width:20%;
+		border-right:1px solid black;
+		background-color: #C5CCD3;
+		z-index:100;	
+		height: 100%; 
+	}
+
+}
+*/
+/*@media only screen and (device-width: 480px) and (orientation: landscape) and (resolution: 163dpi) { */
+	/* CSS3 Rules for XX iPhone in Portrait Orientation */
+/*@media only screen and (device-width: 568px) and (orientation: landscape) {
+	.center {
+		float: left;
+		width: 300px;
+		height: 100%;
+		
+	}
+
+	.left {
+		float: left; 
+		width:100px;
+		border-right:1px solid black;
+		background-color: #C5CCD3;
+		z-index:100;	
+		height: 100% 
+	}
+}
+*/
+
+
+
+html,body {
+	width: 100%;
+	height: 100%;
+}
+
+button.baseBtn {
+	-webkit-background-clip: padding-box;
+	-webkit-box-align: center;
+	background-clip: padding-box;
+	border-style: solid;
+	border-width: 1px;
+	color: black;
+	font-family: 'Helvetica Neue', HelveticaNeue, Helvetica-Neue, Helvetica, 'BBAlpha Sans';
+	font-size: 18px;
+	font-weight: bold;
+	vertical-align: middle;
+	margin: 10px;
+	height: 34px;
+	border-bottom-left-radius: 7px;
+	border-bottom-right-radius: 7px;
+	border-top-left-radius: 7px;
+	border-top-right-radius: 7px;
+	width: 240px;
+}
+
+button.whiteBtn{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(white), color-stop(0.06, #f2f2f2), to(#b7b7b7));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+button.whiteBtnSelected{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(#ffffff), color-stop(0.06, #bbbbbb), to(#fcfcfc));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+#header button {
+	position:absolute;
+	margin:0;
+}
+
+#navButton {
+	width:60px;
+}
+
+#loadDiv {
+	position:absolute;
+	left:0;
+	top:0;
+	width:100%;
+	height:100%;
+	z-index:999;
+}
+#loadDiv {
+	display:table;
+	font-size: 20px;
+	text-align:center;
+	background-color:white;
+}
+#loadDiv span {
+	display:table-cell;
+	vertical-align:middle;
+}
+
+body .mblProgContainer {
+	top:45%;
+	height: 45px;
+	width: 140px;
+	margin-left:-70px;
+	background-color: #2A2A28;
+	border-style: solid;
+	border-width: 2px;
+	border-color: #666666;
+	border-radius: 0.4em;
+	-webkit-border-radius: 0.4em;
+	-moz-border-radius: 0.4em;
+}
+
+body .mblProgContainer > div {
+	height: 100%;
+	width: 100%;
+	line-height: 45px;
+	vertical-align: middle;
+	font-size: 20px;
+	color: #c2c2c2;
+}
+
+body .mblProg {
+	left: 3px;
+	top: 3px;
+}
+
+body .mblProgContainer > div::after {
+	padding-left: 42px;
+	content: "Updating...";
+}
+
+#jsContent, #htmlContent {
+	padding-left:2px;
+}
+
+ at media screen and (max-width: 600px) {
+	#jsContent, #htmlContent {
+		font-size: 14px;
+	}
+}
+
+.hidden {
+	display:none;
+}
+
+/*
+div .navPane {
+	width:250px;
+	border-right:1px solid black;
+	background-color: #C5CCD3;
+	z-index:100;
+}
+*/
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/index.html b/dojox/app/tests/mediaQuery3ColumnApp/index.html
new file mode 100644
index 0000000..000e282
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/index.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Media Query 3 Column App</title>
+		<link type="text/css" href="./css/mediaQuery3ColumnApp.css" rel="stylesheet" />
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+				mblAlwaysHideAddressBar: false,
+				app: {debugApp: 1},  // set debugApp to log app transtions and view activate/deactivate
+				async: 1">
+		</script>
+		<script>
+			require(["./mediaQuery3ColumnApp.js"], function(){
+			});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/mediaQuery3ColumnApp.js b/dojox/app/tests/mediaQuery3ColumnApp/mediaQuery3ColumnApp.js
new file mode 100644
index 0000000..ea3ffd6
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/mediaQuery3ColumnApp.js
@@ -0,0 +1,19 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojo/sniff"],
+	function(win, Application, jsonRef, config, has){
+
+	var small = 560;
+
+	// large > 860 medium <= 860  small <= 560 
+	var isSmall = function(){				
+		var width = window.innerWidth || document.documentElement.clientWidth;
+		return width <= small;
+
+	};
+
+	
+	var cfg = jsonRef.fromJson(config);
+	has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+	has.add("isInitiallySmall", isSmall());
+	Application(cfg);
+	
+});
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/nls/app.js b/dojox/app/tests/mediaQuery3ColumnApp/nls/app.js
new file mode 100755
index 0000000..3eff041
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/nls/app.js
@@ -0,0 +1,7 @@
+define({
+	root: {
+	  home: "Home",
+	  label0: "Label Zero"
+	},
+	fr: true
+});
\ No newline at end of file
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/nls/fr/app.js b/dojox/app/tests/mediaQuery3ColumnApp/nls/fr/app.js
new file mode 100755
index 0000000..43e8dd4
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/nls/fr/app.js
@@ -0,0 +1,4 @@
+define({
+	home: "Maison",
+   	label0: "Etiquette 0"
+});
\ No newline at end of file
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/nls/fr/home.js b/dojox/app/tests/mediaQuery3ColumnApp/nls/fr/home.js
new file mode 100755
index 0000000..93b5a35
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/nls/fr/home.js
@@ -0,0 +1,4 @@
+define({
+	label1: "Etiquette Un",
+	label2: "Etiquette Deux"
+});
\ No newline at end of file
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/nls/home.js b/dojox/app/tests/mediaQuery3ColumnApp/nls/home.js
new file mode 100755
index 0000000..b8cfbfd
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/nls/home.js
@@ -0,0 +1,7 @@
+define({
+	root: {
+		label1: "Label One",
+		label2: "Label Two"
+	},
+	fr: true
+});
\ No newline at end of file
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/views/header.html b/dojox/app/tests/mediaQuery3ColumnApp/views/header.html
new file mode 100644
index 0000000..ddb4688
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/views/header.html
@@ -0,0 +1,9 @@
+<div>
+	<!-- top -->
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Media Query 3 Column App", fixed:"top"'>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" tabindex="0" id="headerBackButton" class="hide"
+			data-dojo-props='label:"Back", fixed:"top", arrow:"left"'>
+		</span>
+	</h1>
+	
+</div>
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/views/last/last.html b/dojox/app/tests/mediaQuery3ColumnApp/views/last/last.html
new file mode 100644
index 0000000..8b8b649
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/views/last/last.html
@@ -0,0 +1,25 @@
+<div data-dojo-attach-point="lastOuterDiv">
+	<div data-dojo-type="dojox/app/widgets/Container" data-dojo-attach-point="lastOuterContainer" data-app-constraint="right">
+
+	<!-- <div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable:true">  -->
+		<div>
+			<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Last", fixed:"top"'>
+				<span data-dojo-type="dojox/mobile/ToolBarButton" tabindex="0" data-dojo-attach-point="lastheaderBackButton" 
+					data-dojo-props='label:"Main", fixed:"top", arrow:"left"'>
+				</span>
+			</h1>
+			<h2 data-dojo-attach-point="lastH2" data-dojo-type="dojox/mobile/EdgeToEdgeCategory" data-dojo-props='label:"None selected", fixed:"top"'></h2>		
+			<ul data-dojo-attach-point="lastList" data-dojo-type="dojox/mobile/RoundRectList" data-app-constraint="center">
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-attach-event="onClick:lastOption1Clicked" data-dojo-props='clickable:true,noArrow:true'>
+					Option 1
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-attach-event="onClick:lastOption2Clicked" data-dojo-props='clickable:true,noArrow:true'>
+					Option 2
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-attach-event="onClick:lastOption3Clicked" data-dojo-props='clickable:true,noArrow:true'>
+					Option 3
+				</li>
+			</ul>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/views/last/last.js b/dojox/app/tests/mediaQuery3ColumnApp/views/last/last.js
new file mode 100644
index 0000000..c1407d6
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/views/last/last.js
@@ -0,0 +1,70 @@
+define(["dojo/_base/lang", "dojo/dom-class"],
+function(lang, domClass){
+
+	return {
+		// view init
+		init: function(){
+			console.log("in init for view with this.name = "+this.name);
+
+			// handle the backButton click
+			this.lastheaderBackButton.on("click", lang.hitch(this, function(e){
+				if(history){
+					history.back();
+				}else{
+					this.app.emit("MQ3ColApp/BackFromLast", e);
+				}
+			})); 
+
+			// This code will setup the view to work in the center or the right depending upon the viewName
+			if(this.name == "lastCenter"){
+				this.lastOuterContainer["data-app-constraint"] = "center";
+				domClass.add(this.lastheaderBackButton.domNode, "showOnMedium hideOnLarge showOnSmall");
+				domClass.add(this.lastOuterContainer, "center");
+			}else{
+				this.lastOuterContainer["data-app-constraint"] = "right";				
+				domClass.add(this.lastheaderBackButton.domNode, "showOnSmall hideOnMedium hideOnLarge");
+				domClass.add(this.lastOuterDiv, "navPane hideOnMedium");
+				domClass.add(this.lastOuterContainer, "hideOnMedium right");
+			}
+
+
+		},
+		
+		beforeActivate: function(previousView, data){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			this.previousView = previousView;
+
+			// Set the selection from the params
+			if(this.params["lastSel"]){ 
+				this.lastH2.set("label",this.params["lastSel"]+" selected");
+			}else{
+				this.lastH2.set("label","None selected");				
+			}
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+		},
+
+		lastOption1Clicked: function(/*Event*/ e){
+			this.app.emit("MQ3ColApp/LastOption1", e);
+		},
+
+		lastOption2Clicked: function(/*Event*/ e){
+			this.app.emit("MQ3ColApp/LastOption2", e);
+		},
+
+		lastOption3Clicked: function(/*Event*/ e){
+			this.app.emit("MQ3ColApp/LastOption3", e);
+		},
+
+		// view destroy, this destroy function can be removed since it is empty
+		destroy: function(){
+			// _WidgetBase.on listener is automatically destroyed when the Widget itself is. 
+		}
+	};
+});
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/views/main/TestInfo.html b/dojox/app/tests/mediaQuery3ColumnApp/views/main/TestInfo.html
new file mode 100644
index 0000000..ebf92cb
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/views/main/TestInfo.html
@@ -0,0 +1,28 @@
+<div   data-dojo-attach-point="testOuterDiv" class="view mblView">
+
+
+<!--	<div data-dojo-type="dojox/mobile/ScrollableView"> -->
+	<div> 
+			<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Main", fixed:"top"'>
+				<span data-dojo-type="dojox/mobile/ToolBarButton" tabindex="0" data-dojo-attach-point="testheaderBackButton" 
+					data-dojo-props='label:"Nav", fixed:"top", arrow:"left"'>
+				</span>
+			</h1>
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" data-app-constraint="top">Test Info for this test.</h2>
+
+		<div>
+			<div class="field-title">This test app has 3 columns, Left (Nav), Center (Main), Right (Last) which are shown (or not shown) based upon media queries.</div>
+			<br>
+			<div class="field-title">The app responds to 3 screen sizes (Large over 860, Medium less than 860, and Small less than 560).</div>
+			<br>
+			<div class="field-title">The views can be reused for different positions, for example in the config there is a navLeft and a navCenter which both use the same controller and templates.</div>
+			<br>
+			<div class="field-title">For Large all 3 columns are shown (navLeft | mainCenter | lastRight).</div>
+			<div class="field-title">For Medium the right column is hidden and the left and center columns are shown (navLeft | mainCenter) or (navLeft | lastCenter).</div>
+			<div class="field-title">For Small only the center column is shown, the left and right columns are hidden  (navCenter) or (mainCenter) or (lastCenter).</div>
+			<br>
+			<div class="field-title">There is also code in the custom NavigationController which is notified of orientation changes or resize events which will handle the cases where the same logical view is about to be shown in the left and center (or the center and right).</div>
+			<br>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/views/main/TestInfo.js b/dojox/app/tests/mediaQuery3ColumnApp/views/main/TestInfo.js
new file mode 100644
index 0000000..202e6de
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/views/main/TestInfo.js
@@ -0,0 +1,30 @@
+define(["dojo/_base/lang", "dojo/dom-class"],
+function(lang, domClass){
+
+	return {
+		// view init
+		init: function(){
+			console.log("in init for view with this.name = "+this.name);
+
+			// handle the backButton click
+			this.testheaderBackButton.on("click", lang.hitch(this, function(e){
+				this.app.emit("MQ3ColApp/BackFromTest", e);
+			})); 
+			 
+			// This code will setup the classes for the backButton
+			domClass.add(this.testheaderBackButton.domNode, "showOnSmall hideOnMedium hideOnLarge");
+		},
+
+
+		afterDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+		},
+
+		// view destroy, this destroy function can be removed since it is empty
+		destroy: function(){
+			// _WidgetBase.on listener is automatically destroyed when the Widget itself is. 
+		}
+	};
+});
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/views/main/main.html b/dojox/app/tests/mediaQuery3ColumnApp/views/main/main.html
new file mode 100644
index 0000000..21a779f
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/views/main/main.html
@@ -0,0 +1,25 @@
+<div  data-dojo-attach-point="mainOuterDiv">
+	<div data-dojo-type="dojox/app/widgets/Container" data-dojo-attach-point="mainOuterContainer" data-app-constraint="center">
+
+	<!-- <div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable:true">  -->
+		<div>
+			<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Main", fixed:"top"'>
+				<span data-dojo-type="dojox/mobile/ToolBarButton" tabindex="0" data-dojo-attach-point="mainheaderBackButton" 
+					data-dojo-props='label:"Nav", fixed:"top", arrow:"left"'>
+				</span>
+			</h1>
+			<h2 data-dojo-attach-point="mainH2" data-dojo-type="dojox/mobile/EdgeToEdgeCategory" data-dojo-props='label:"None selected", fixed:"top"'></h2>		
+			<ul data-dojo-attach-point="navList" data-dojo-type="dojox/mobile/RoundRectList" data-app-constraint="center">
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true" data-dojo-attach-event="onClick:lastOption1Clicked">
+					Last Option 1
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true" data-dojo-attach-event="onClick:lastOption2Clicked">
+					Last Option 2
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true" data-dojo-attach-event="onClick:lastOption3Clicked">
+					Last Option 3
+				</li>
+			</ul>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/views/main/main.js b/dojox/app/tests/mediaQuery3ColumnApp/views/main/main.js
new file mode 100644
index 0000000..6519933
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/views/main/main.js
@@ -0,0 +1,74 @@
+define(["dojo/_base/lang", "dojo/dom-class"],
+function(lang, domClass){
+
+	return {
+		// view init
+		init: function(){
+			console.log("in init for view with this.name = "+this.name);
+
+			// handle the backButton click
+			this.mainheaderBackButton.on("click", lang.hitch(this, function(e){
+				if(history){
+					history.back();
+				}else{
+					this.app.emit("MQ3ColApp/BackFromMain", e);
+				}
+			})); 
+
+			// This code will setup the view to work in the left or center depending upon the view name
+			if(this.name == "mainLeft"){  // app was changed to stop using mainLeft for now.
+				this.mainOuterContainer["data-app-constraint"] = "left";
+				domClass.add(this.mainheaderBackButton.domNode, "showOnMedium");
+				domClass.add(this.mainOuterContainer, "left");
+				domClass.add(this.mainOuterDiv, "navPane hideOnSmall");  // for main on left
+			}else{
+				this.mainOuterContainer["data-app-constraint"] = "center";				
+				domClass.add(this.mainheaderBackButton.domNode, "showOnSmall hideOnMedium hideOnLarge");
+				domClass.add(this.mainOuterContainer, "center");
+			}
+
+
+		},
+		
+		beforeActivate: function(previousView, data){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			this.previousView = previousView;
+			
+			// Set the selection from the params
+			if(this.params["mainSel"]){ 
+				if(this.mainH2){
+					this.mainH2.set("label",this.params["mainSel"]+" selected");
+				}else{
+					console.error("Problem this.mainH2 should not be null ");
+				}	
+			}else{
+				this.mainH2.set("label","None selected");				
+			}
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+		},
+
+		lastOption1Clicked: function(/*Event*/ e){
+			this.app.emit("MQ3ColApp/LastOption1", e);
+		},
+
+		lastOption2Clicked: function(/*Event*/ e){
+			this.app.emit("MQ3ColApp/LastOption2", e);
+		},
+
+		lastOption3Clicked: function(/*Event*/ e){
+			this.app.emit("MQ3ColApp/LastOption3", e);
+		},
+
+		// view destroy, this destroy function can be removed since it is empty
+		destroy: function(){
+			// _WidgetBase.on listener is automatically destroyed when the Widget itself is. 
+		}
+	};
+});
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/views/nav/navigation.html b/dojox/app/tests/mediaQuery3ColumnApp/views/nav/navigation.html
new file mode 100644
index 0000000..55d9e03
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/views/nav/navigation.html
@@ -0,0 +1,29 @@
+<div data-dojo-attach-point="navOuterDiv">
+	<!-- left -->
+	<div data-dojo-type="dojox/app/widgets/Container" data-dojo-attach-point="navOuterContainer">
+
+	<!-- <div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable:true">  -->
+		<div>
+			<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Nav", fixed:"top"'>
+				<span data-dojo-type="dojox/mobile/ToolBarButton" tabindex="0" data-dojo-attach-point="navheaderBackButton" 
+					data-dojo-props='label:"Back", fixed:"top", arrow:"left"'>
+				</span>
+			</h1>
+			
+			<ul data-dojo-attach-point="navList" data-dojo-type="dojox/mobile/RoundRectList" data-app-constraint="center">
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true" data-dojo-attach-event="onClick:mainOption1Clicked">
+					Main Option 1
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true" data-dojo-attach-event="onClick:mainOption2Clicked">
+					Main Option 2
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true" data-dojo-attach-event="onClick:mainOption3Clicked">
+					Main Option 3
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true" data-dojo-attach-event="onClick:testOption1Clicked">
+					Test Information
+				</li>
+			</ul>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/mediaQuery3ColumnApp/views/nav/navigation.js b/dojox/app/tests/mediaQuery3ColumnApp/views/nav/navigation.js
new file mode 100644
index 0000000..36208fb
--- /dev/null
+++ b/dojox/app/tests/mediaQuery3ColumnApp/views/nav/navigation.js
@@ -0,0 +1,54 @@
+define(["dojo/dom-class"],
+function(domClass){
+	return {
+		// view init
+		init: function(){
+			console.log("in init for view with this.name = "+this.name);
+
+			// the back button is never shown for Nav
+			domClass.add(this.navheaderBackButton.domNode, "hide");
+
+			// This code will setup the view to work in the left or center depending upon the view name
+			if(this.name == "navLeft"){
+				this.navOuterContainer["data-app-constraint"] = "left";
+				domClass.add(this.navOuterDiv, "hideOnSmall");  // for navigation on the left
+			}else{
+				this.navOuterContainer["data-app-constraint"] = "center";				
+				domClass.add(this.navOuterContainer, "center");
+			}
+
+		},
+		
+		beforeActivate: function(previousView){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			this.previousView = previousView;
+			
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+		},
+
+		testOption1Clicked: function(/*Event*/ e){
+			e.transitionNext = e.target.parentElement.id;
+			this.app.emit("MQ3ColApp/TestOption1", e);
+		},
+
+		mainOption1Clicked: function(/*Event*/ e){
+			this.app.emit("MQ3ColApp/MainOption1", e);
+		},
+
+		mainOption2Clicked: function(/*Event*/ e){
+			this.app.emit("MQ3ColApp/MainOption2", e);
+		},
+
+		mainOption3Clicked: function(/*Event*/ e){
+			this.app.emit("MQ3ColApp/MainOption3", e);
+		}
+
+	}
+});
diff --git a/dojox/app/tests/mediaQueryLayoutApp/config.json b/dojox/app/tests/mediaQueryLayoutApp/config.json
new file mode 100644
index 0000000..3b82330
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/config.json
@@ -0,0 +1,137 @@
+{
+	"id": "mediaQueryLayoutApp",
+	"name": "mediaQuery Layout App",
+	"description": "A mediaQuery Layout App",
+	"splash": "splash",
+
+	"loaderConfig": {
+		"paths": {
+			"mediaQueryLayoutApp": "../dojox/app/tests/mediaQueryLayoutApp"
+		}
+	},
+
+	"dependencies": [
+		"dojox/mobile/_base",
+		"dojox/mobile/compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/Heading",
+		"dojox/mobile/ScrollableView",
+		"dojo/store/Memory",
+		"dojox/mobile/View",
+		"dojox/mobile/EdgeToEdgeStoreList",
+		"dojox/app/utils/simpleModel",
+		"dojo/store/Observable",		
+		"dojox/mobile/DatePicker",
+		"dojox/mobile/Opener",
+		"dojox/app/widgets/Container"
+	],
+
+	"modules": [],
+	
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/tests/mediaQueryLayoutApp/controllers/CssLayout"
+	],
+
+	//stores we are using
+	"stores": {
+	   "namesStore":{
+	       "type": "dojo/store/Memory",
+		   "params": {
+		      "data": "modelApp.names"
+		   }
+	   },
+       "listStore":{
+           "type": "dojo/store/Memory",
+	       "observable": true,
+           "params": {
+                "data": "modelApp.listData"
+           }
+       }
+	},
+	
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+	//the name of the view to load when the app is initialized.
+	"defaultView": "header+navigation+TestInfo",
+
+	// these are the possilbe defaultTransitions
+	"defaultTransition": "slide",
+	//"defaultTransition": "none",
+	//"defaultTransition": "fade",
+	//"defaultTransition": "flip",     
+
+	"transition": "flip",     
+
+	"views": {
+		"navigation":{
+			"constraint" : "left",
+			"template": "mediaQueryLayoutApp/views/navigation.html"
+		},
+		"TestInfo": {
+			"controller" : "mediaQueryLayoutApp/views/TestInfo.js",
+			"constraint" : "center",
+			"template": "mediaQueryLayoutApp/views/TestInfo.html"
+		},	
+		"centerNavigation":{
+			"controller" : "mediaQueryLayoutApp/views/centerNavigation.js",
+			"constraint" : "center",
+			"template": "mediaQueryLayoutApp/views/centerNavigation.html"
+		},
+		"header":{
+			"controller" : "mediaQueryLayoutApp/views/header.js",
+			"constraint" : "top",
+			"template": "mediaQueryLayoutApp/views/header.html"
+		},
+		"simple":{
+            "models": {
+				"names": {
+					"modelLoader": "dojox/app/utils/simpleModel",
+					"params":{
+						"store": {"$ref":"#stores.namesStore"}
+					}
+				}
+			},
+			"controller" : "mediaQueryLayoutApp/views/simple/simple.js",
+			"constraint" : "center",
+			"template": "mediaQueryLayoutApp/views/simple/simple.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		},
+		//list view, include list view and details view
+		"listMain":{
+			"controller" : "mediaQueryLayoutApp/views/list/list.js",
+			"template": "mediaQueryLayoutApp/views/list/list.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		},
+		"itemDetails":{
+			"controller" : "mediaQueryLayoutApp/views/list/itemDetails.js",
+			"template": "mediaQueryLayoutApp/views/list/itemDetails.html",
+			"dependencies":["dojox/mobile/TextBox"],
+			"defaultParams": {"cursor":"2"}
+		},
+
+		"date": {
+            "controller": "mediaQueryLayoutApp/views/date/date.js",
+            "template": "mediaQueryLayoutApp/views/date/date.html",
+            "dependencies":["dojox/mobile/TextBox", "dojox/mobile/TextArea"]
+		}
+	}	
+}
diff --git a/dojox/app/tests/mediaQueryLayoutApp/controllers/CssLayout.js b/dojox/app/tests/mediaQueryLayoutApp/controllers/CssLayout.js
new file mode 100644
index 0000000..87f7287
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/controllers/CssLayout.js
@@ -0,0 +1,79 @@
+define(["dojo/_base/declare", "dojo/dom", "dojo/dom-style",
+		"dojo/dom-class", "dojo/dom-attr", "dojo/dom-construct", 
+		"dojox/app/controllers/LayoutBase"],
+function(declare, dom, domStyle, domClass, domAttr, domConstruct, LayoutBase){
+	// module:
+	//		dojox/app/tests/mediaQueryLayoutApp/controllers/CssLayout
+	// summary:
+	//		Will layout an application with a BorderContainer.  
+	//		Each view to be shown in a region of the BorderContainer will be wrapped in a StackContainer and a ContentPane.
+	//		
+
+	return declare("dojox/app/tests/mediaQueryLayoutApp/controllers/CssLayout", LayoutBase, {
+
+		initLayout: function(event){
+			// summary:
+			//		Response to dojox/app "app-initLayout" event which is setup in LayoutBase.
+			//		The initLayout event is called once when the View is being created the first time.
+			//
+			// example:
+			//		Use emit to trigger "app-initLayout" event, and this function will respond to the event. For example:
+			//		|	this.app.emit("app-initLayout", view);
+			//
+			// event: Object
+			// |		{"view": view, "callback": function(){}};
+			this.app.log("in app/controllers/CssLayout.initLayout event.view.name=[",event.view.name,"] event.view.parent.name=[",event.view.parent.name,"]");
+
+
+			this.app.log("in app/controllers/CssLayout.initLayout event.view.constraint=",event.view.constraint);
+			var constraint = event.view.constraint;  // constraint holds the region for this view, center, top etc.
+			
+		//	if(event.view.parent.id == this.app.id){  // If the parent of this view is the app we are working with the BorderContainer
+			//	var reg = dom.byId(event.view.parent.id+"-"+constraint);			
+			//	if(reg){  // already has a wrapperNode, just add to it.
+			//		reg.appendChild(event.view.domNode);
+			//	}else{ // need a wrapperNode
+			//		var container;
+			//		event.view.parent.domNode.appendChild(container = domConstruct.create("div"));
+			//		container.appendChild(event.view.domNode);
+			//		domAttr.set(container, "id", event.view.parent.id+"-"+constraint);
+			//		domClass.add(event.view.domNode, constraint);  // set the class to the constraint
+			//	}
+		//	}else{ // Not a top level page transition, so not changing a page in the BorderContainer, so handle it like Layout.
+				event.view.parent.domNode.appendChild(event.view.domNode);
+				domClass.add(event.view.domNode, constraint);  // set the class to the constraint
+		//	}
+
+			this.inherited(arguments);
+		},
+
+		onResize: function(){
+			// do nothing on resize
+		},
+
+		hideView: function(view){
+			domStyle.set(view.domNode, "display", "none");
+			//var sc = registry.byId(view.parent.id+"-"+view.constraint);
+			//if(sc){
+			//	sc.removedFromBc = true;
+			//	sc.removeChild(view.domNode);
+			//}
+		},
+
+		showView: function(view){
+			domStyle.set(view.domNode, "display", "");
+			
+			//var sc = registry.byId(view.parent.id+"-"+view.constraint);
+			//if(sc){
+			//	if(sc.removedFromBc){
+			//		sc.removedFromBc = false;
+			//		registry.byId(this.app.id+"-BC").addChild(sc);
+			//		domStyle.set(view.domNode, "display", "");
+			//	}
+			//	domStyle.set(cp.domNode, "display", "");
+			//	sc.selectChild(cp);
+			//	sc.resize();
+			//}
+		}
+	});
+});
diff --git a/dojox/app/tests/mediaQueryLayoutApp/css/mediaQueryLayoutApp.css b/dojox/app/tests/mediaQueryLayoutApp/css/mediaQueryLayoutApp.css
new file mode 100644
index 0000000..3e6c85b
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/css/mediaQueryLayoutApp.css
@@ -0,0 +1,187 @@
+.hide {
+	display: none !important;
+}
+
+.center {
+	float: left;
+	height: 100%; 
+	width:69.8%;
+}
+
+.showOnTablet {
+	display: block !important;
+}
+
+.hideOnTablet {
+	display: none !important;
+}
+
+.left {
+	float: left; 
+	width:30%;
+	border-right:1px solid black;
+	background-color: #C5CCD3;
+	z-index:100;	
+	height: 100%; 
+}
+
+/* Phone */
+ at media screen and (max-width: 560px) {
+
+	.left {
+		float: left; 
+		width:0;
+	}
+	.center {
+		float: left;
+		width: 99.6%; 
+	}
+	.showOnPhone {
+		display: block !important;
+	}
+	.hideOnPhone {
+		display: none !important;
+	}
+}
+
+/* portrait mode */
+ at media only screen and (orientation: portrait) {
+
+
+	.left {
+		float: left; 
+		width:0;
+	}
+	.center {
+		float: left;
+		width: 99.6%; 
+	}
+	.showOnPhone {
+		display: block !important;
+	}
+	.hideOnPhone {
+		display: none !important;
+	}
+}
+
+
+html,body {
+	width: 100%;
+	height: 100%;
+}
+
+button.baseBtn {
+	-webkit-background-clip: padding-box;
+	-webkit-box-align: center;
+	background-clip: padding-box;
+	border-style: solid;
+	border-width: 1px;
+	color: black;
+	font-family: 'Helvetica Neue', HelveticaNeue, Helvetica-Neue, Helvetica, 'BBAlpha Sans';
+	font-size: 18px;
+	font-weight: bold;
+	vertical-align: middle;
+	margin: 10px;
+	height: 34px;
+	border-bottom-left-radius: 7px;
+	border-bottom-right-radius: 7px;
+	border-top-left-radius: 7px;
+	border-top-right-radius: 7px;
+	width: 240px;
+}
+
+button.whiteBtn{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(white), color-stop(0.06, #f2f2f2), to(#b7b7b7));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+button.whiteBtnSelected{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(#ffffff), color-stop(0.06, #bbbbbb), to(#fcfcfc));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+#header button {
+	position:absolute;
+	margin:0;
+}
+
+#navButton {
+	width:60px;
+}
+
+#loadDiv {
+	position:absolute;
+	left:0;
+	top:0;
+	width:100%;
+	height:100%;
+	z-index:999;
+}
+#loadDiv {
+	display:table;
+	font-size: 20px;
+	text-align:center;
+	background-color:white;
+}
+#loadDiv span {
+	display:table-cell;
+	vertical-align:middle;
+}
+
+body .mblProgContainer {
+	top:45%;
+	height: 45px;
+	width: 140px;
+	margin-left:-70px;
+	background-color: #2A2A28;
+	border-style: solid;
+	border-width: 2px;
+	border-color: #666666;
+	border-radius: 0.4em;
+	-webkit-border-radius: 0.4em;
+	-moz-border-radius: 0.4em;
+}
+
+body .mblProgContainer > div {
+	height: 100%;
+	width: 100%;
+	line-height: 45px;
+	vertical-align: middle;
+	font-size: 20px;
+	color: #c2c2c2;
+}
+
+body .mblProg {
+	left: 3px;
+	top: 3px;
+}
+
+body .mblProgContainer > div::after {
+	padding-left: 42px;
+	content: "Updating...";
+}
+
+#jsContent, #htmlContent {
+	padding-left:2px;
+}
+
+ at media screen and (max-width: 600px) {
+	#jsContent, #htmlContent {
+		font-size: 14px;
+	}
+}
+
+.hidden {
+	display:none;
+}
+
+/*
+div .navPane {
+	width:250px;
+	border-right:1px solid black;
+	background-color: #C5CCD3;
+	z-index:100;
+}
+*/
diff --git a/dojox/app/tests/mediaQueryLayoutApp/index.html b/dojox/app/tests/mediaQueryLayoutApp/index.html
new file mode 100644
index 0000000..96fa9e9
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/index.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Media Query Layout App</title>
+		<link type="text/css" href="./css/mediaQueryLayoutApp.css" rel="stylesheet" />
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+				mblAlwaysHideAddressBar: false,
+				app: {debugApp: 1},  // set debugApp to log app transtions and view activate/deactivate
+				async: 1">
+		</script>
+		<script>
+			require(["./mediaQueryLayoutApp.js"], function(){
+			});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/mediaQueryLayoutApp/mediaQueryLayoutApp.js b/dojox/app/tests/mediaQueryLayoutApp/mediaQueryLayoutApp.js
new file mode 100644
index 0000000..593939a
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/mediaQueryLayoutApp.js
@@ -0,0 +1,68 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojo/sniff"],
+	function(win, Application, jsonRef, config, has){
+	win.global.modelApp = {};
+	modelApp.names = {
+		identifier: "id",
+		items: [{
+			"id": "1",
+			"Serial": "360324",
+			"First": "John",
+			"Last": "Doe",
+			"Email": "jdoe at us.ibm.com",
+			"ShipTo": {
+				"Street": "123 Valley Rd",
+				"City": "Katonah",
+				"State": "NY",
+				"Zip": "10536"
+			},
+			"BillTo": {
+				"Street": "17 Skyline Dr",
+				"City": "Hawthorne",
+				"State": "NY",
+				"Zip": "10532"
+			}
+		}]
+	};
+
+	modelApp.listData = { 
+		identifier: "id",
+		'items':[{
+			"id": "item1",
+			"label": "Chad Chapman",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Chad",
+			"Last": "Chapman",
+			"Location": "CA",
+			"Office": "1278",
+			"Email": "c.c at test.com",
+			"Tel": "408-764-8237",
+			"Fax": "408-764-8228"
+		}, {
+			"id": "item2",
+			"label": "Irene Ira",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Irene",
+			"Last": "Ira",
+			"Location": "NJ",	
+			"Office": "F09",
+			"Email": "i.i at test.com",
+			"Tel": "514-764-6532",
+			"Fax": "514-764-7300"
+		}, {
+			"id": "item3",
+			"label": "John Jacklin",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "John",
+			"Last": "Jacklin",
+			"Location": "CA",
+			"Office": "6701",
+			"Email": "j.j at test.com",
+			"Tel": "408-764-1234",
+			"Fax": "408-764-4321"
+		}]
+	};
+	var cfg = jsonRef.fromJson(config);
+	has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+	Application(cfg);
+	
+});
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/TestInfo.html b/dojox/app/tests/mediaQueryLayoutApp/views/TestInfo.html
new file mode 100644
index 0000000..702be6e
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/TestInfo.html
@@ -0,0 +1,24 @@
+<div class="view mblView">
+
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Test Info for this test.</h2>
+
+		<div>
+			<div class="field-title">This has been setup to use a custom layout controller (CssLayout) with media queries.</div>
+			<div class="field-title">The CssLayout layout controller uses css to size the views, it does not call resize on the views, this is to improve performance during orientation changes.</div>
+			<br>
+			<div class="field-title">On a desktop you can make the window smaller and the navigation area will be hidden and the Back button will display when the screen gets less than max-width: 560px.</div>
+			<br>
+			<div class="field-title">On a phone or tablet the Naviagtion will be hidden in portrait orientation and shown in landscape orientation.</div>
+			<br><br>
+			<div class="field-title">More work needs to be done for the following.</div>
+			<br>
+			<div class="field-title">1) When the Navigation area is hidden and Back button takes you to the Configuration (Navigation) view, and then the screen is rotated or enlarged to show the navigation area on the left, the configuration (navigation view) in the center should be transitioned to a different view, either the previous view or some default view.</div>
+			<br>
+			<div class="field-title">2) There are some cases where a view needs to have resize called, this should be an option set on the config to indicate that a call resize is required for a view.</div>
+			<div class="field-title">3) There are problems getting things to display without the resize calls when using a dojox/mobile/ScrollableView.</div>
+			<div class="field-title">4) I had trouble getting TestInfo to display as the defaultView until I created a TestInfo.js and set it up as the defintion.</div>
+			<br>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/TestInfo.js b/dojox/app/tests/mediaQueryLayoutApp/views/TestInfo.js
new file mode 100644
index 0000000..bde770d
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/TestInfo.js
@@ -0,0 +1,52 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojox/mobile/TransitionEvent"],
+function(dom, domStyle, connect, TransitionEvent){
+	var _connectResults = []; // events connect result
+
+	return {
+		// view init
+		init: function(){
+		},
+		
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+
+			var connectResult;
+			
+			var backButtomDom = dom.byId('headerBackButton');
+			connectResult = connect.connect(backButtomDom, "onclick", function(e){
+				
+				var transOpts = {
+					title:'header+navigation+centerNavigation',
+					target:'header+navigation+centerNavigation',
+					url:'#header+navigation+centerNavigation'					
+				};
+				new TransitionEvent(e.target, transOpts, e).dispatch(); 
+
+			});
+			_connectResults.push(connectResult);
+			
+		},
+
+
+		afterDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		},
+		
+		// view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/centerNavigation.html b/dojox/app/tests/mediaQueryLayoutApp/views/centerNavigation.html
new file mode 100644
index 0000000..6d62d72
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/centerNavigation.html
@@ -0,0 +1,15 @@
+<div>
+	<!-- center -->
+	<div>
+
+		<div>
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Navigation</h2>
+			<ul data-dojo-type="dojox/mobile/RoundRectList" data-app-constraint="center">
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Test Information',target:'header+navigation+TestInfo',url:'#header+navigation+TestInfo'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Simple Data Binding',target:'header+navigation+simple',url:'#header+navigation+simple'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Simple List Test',target:'header+navigation+listMain',url:'#header+navigation+listMain'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Simple Date Test',target:'header+navigation+date',url:'#header+navigation+date'"></li>
+			</ul>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/centerNavigation.js b/dojox/app/tests/mediaQueryLayoutApp/views/centerNavigation.js
new file mode 100644
index 0000000..4a5e5b7
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/centerNavigation.js
@@ -0,0 +1,30 @@
+define(["dojo/dom", "dojo/dom-class"], function(dom, domClass){
+
+	return {
+		// view init
+		init: function(){
+		},
+		
+		beforeActivate: function(view, data){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			this.previousView = view;
+			var backButtomDom = dom.byId('headerBackButton');
+			domClass.remove(backButtomDom, "showOnPhone");
+			domClass.add(backButtomDom, "hide");
+			
+			// setup code to watch for the navigation pane being visible
+			
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			var backButtomDom = dom.byId('headerBackButton');
+			domClass.remove(backButtomDom, "hide");
+			domClass.add(backButtomDom, "showOnPhone");
+		}
+	}
+});
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/date/date.html b/dojox/app/tests/mediaQueryLayoutApp/views/date/date.html
new file mode 100644
index 0000000..3d2cf74
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/date/date.html
@@ -0,0 +1,21 @@
+<div class="view mblView">
+	<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Simple Date Test</h2>
+
+    <h2 dojoType="dojox/mobile/RoundRectCategory">Click to select a date</h2>
+	
+	<input data-dojo-attach-point="selDate1" readOnly value="" placeholder="Select a date" style="margin-left: 20px;">
+	
+	<div id="opener" data-dojo-attach-point="opener" data-dojo-type="dojox/mobile/Opener">
+		<h1 data-dojo-type="dojox/mobile/Heading" label="Date Picker">
+			<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="save" 
+				data-dojo-props="label:'Done'" class="mblColorBlue"
+				style="position:absolute;width:45px;right:0;">
+			</span>
+			<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="cancel"
+				data-dojo-props="label:'Cancel'" class="mblColorBlue" 
+				style="position:absolute;width:45px;left:0;">
+			</span>
+		</h1>
+		<div data-dojo-attach-point="datePicker2" data-dojo-type="dojox/mobile/DatePicker"></div>
+	</div>
+</div>
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/date/date.js b/dojox/app/tests/mediaQueryLayoutApp/views/date/date.js
new file mode 100644
index 0000000..6873f51
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/date/date.js
@@ -0,0 +1,58 @@
+define(["dojo/_base/lang", "dojo/on", "dijit/registry", "dojo/date/stamp"],
+function(lang, on, registry, stamp){
+	var _onResults = []; // events on array
+
+	var opener, datePicker2;
+
+	return {
+		init: function(){
+			opener = this.opener;
+			var onResult = on(this.selDate1, "click", lang.hitch(this, function(){
+				this.datePicker2.set("value", date);
+				this.opener.show(this.selDate1, ['below-centered','above-centered','after','before']);
+			})); 
+			_onResults.push(onResult);
+
+			onResult = on(this.save, "click", lang.hitch(this, function(){
+				this.opener.hide(true);
+				date = this.selDate1.value = this.datePicker2.get("value");
+			}));
+			_onResults.push(onResult);
+
+			onResult = on(this.cancel, "click", lang.hitch(this, function(){
+				this.opener.hide(false);
+			})); 
+			_onResults.push(onResult);
+			
+			datePicker2 = registry.byId("datePicker2");
+			// initialize the global Date variable as today
+			date = stamp.toISOString(new Date(), {selector: "date"});
+		},
+
+		beforeActivate: function(){
+			//console.log("date view beforeActivate()");
+	/*		var backButtomDom = dom.byId('headerBackButton');
+			onResult = on(backButtomDom, "click", lang.hitch(this, function(e){
+				
+				var transOpts = {
+					title:'header+navigation+centerNavigation',
+					target:'header+navigation+centerNavigation',
+					url:'#header+navigation+centerNavigation'					
+				};
+				new TransitionEvent(e.target, transOpts, e).dispatch(); 
+			})); 
+			_onResults.push(onResult);
+	*/					
+		},
+
+
+		// view destroy
+		destroy: function(){
+			var onResult = _onResults.pop();
+			while(onResult){
+				onResult.remove();
+				onResult = _onResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/header.html b/dojox/app/tests/mediaQueryLayoutApp/views/header.html
new file mode 100644
index 0000000..1b75ff0
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/header.html
@@ -0,0 +1,20 @@
+<div>
+	<!-- top -->
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Media Query Layout App", fixed:"top"'>
+		<span class="mblToolBarButton mblToolBarButtonHasLeftArrow hideOnTablet showOnPhone" tabindex="0" id="headerBackButton" 
+			widgetid="headerBackButton">
+			<span class="mblToolBarButtonArrow mblToolBarButtonLeftArrow mblColorDefault mblColorDefault45"></span>
+			<span class="mblToolBarButtonBody mblColorDefault"><table cellpadding="0" cellspacing="0" border="0" class="mblToolBarButtonText">
+				<tbody><tr>
+					<td class="mblToolBarButtonIcon"></td>
+					<td class="mblToolBarButtonLabel">Back</td>
+				</tr></tbody></table>
+			</span>
+		</span>
+	  		<span data-dojo-type="dojox/mobile/ToolBarButton" id="listInsert1" class="hide"
+       		 data-dojo-props='icon:"mblDomButtonWhitePlus"'
+        		style="float:right;" onclick="console.log('+ was clicked')">
+        	</span>
+	</h1>
+	
+</div>
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/header.js b/dojox/app/tests/mediaQueryLayoutApp/views/header.js
new file mode 100644
index 0000000..d36877b
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/header.js
@@ -0,0 +1,45 @@
+define(["dojo/_base/lang", "dojo/dom", "dojo/on", "dijit/registry", "dojo/date/stamp", "dojox/app/utils/constraints", "dojox/mobile/TransitionEvent"], 
+function(lang, dom, on, registry, stamp, constraints, TransitionEvent){
+	var _onResults = []; // events on array
+
+
+	return {
+		init: function(){
+			//console.log("date view beforeActivate()");
+			var backButtomDom = dom.byId('headerBackButton');
+			var onResult = on(backButtomDom, "click", lang.hitch(this, function(e){
+
+				if(this.app.children.mediaQueryLayoutApp_itemDetails && this.app.children.mediaQueryLayoutApp_itemDetails.viewShowing){
+					var transOpts = {
+						title:'header+navigation+listMain',
+						target:'header+navigation+listMain',
+						url:'#header+navigation+listMain'					
+					};
+					new TransitionEvent(e.target, transOpts, e).dispatch();
+				}else{			
+					var transOpts = {
+						title:'header+navigation+centerNavigation',
+						target:'header+navigation+centerNavigation',
+						url:'#header+navigation+centerNavigation'					
+					};
+					new TransitionEvent(e.target, transOpts, e).dispatch();
+				} 
+			})); 
+			_onResults.push(onResult);			
+		},
+
+		beforeActivate: function(){
+		},
+
+
+		// view destroy
+		destroy: function(){
+			var onResult = _onResults.pop();
+			while(onResult){
+				onResult.remove();
+				onResult = _onResults.pop();
+			}
+		}
+	};
+	
+});
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/list/itemDetails.html b/dojox/app/tests/mediaQueryLayoutApp/views/list/itemDetails.html
new file mode 100644
index 0000000..c7488a1
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/list/itemDetails.html
@@ -0,0 +1,38 @@
+<div class="view mblView">
+	<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" class="showOnPhone hideOnTablet" style="height: 32px;" data-app-constraint="top">List Item Details</h2>
+    <h1 class="showOnTablet hideOnPhone"  dojoType="dojox/mobile/Heading" data-dojo-props='back:"Back"'>List Item Details</h1>
+    <form name="listTestForm" id="listTestForm">    
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Updates to First or Last Name will be reflected in the list</h2>
+					<table id="table" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="First"
+									data-dojo-props="placeholder:'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Last"
+									 
+									data-dojo-props="placeholder:'Last Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput2" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Email"
+									data-dojo-props="placeholder:'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Tel"
+									data-dojo-props="placeholder:'Telephone'">
+							</td>
+						</tr>
+					</table>
+		</form>
+</div>
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/list/itemDetails.js b/dojox/app/tests/mediaQueryLayoutApp/views/list/itemDetails.js
new file mode 100644
index 0000000..b25bc08
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/list/itemDetails.js
@@ -0,0 +1,48 @@
+define([],
+function(){
+
+	var listStore = null;	//list data
+	var currentItem = null;
+
+	return {
+		// show an item detail
+		setDetailsContext: function(index){
+			// only set the cursor if it is different and valid
+			if(parseInt(index) < listStore.data.length){
+				currentItem = listStore.data[index];
+				this.First.set("value",currentItem.First);
+				this.Last.set("value",currentItem.Last);
+				this.Email.set("value",currentItem.Email);
+				this.Tel.set("value",currentItem.Tel);
+			}
+		},
+
+		// list view init
+		init: function(){
+			listStore = this.loadedStores.listStore;
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			// if this.params["cursor"] is set use it to set the selected Details Context
+			if(this.params["cursor"] || this.params["cursor"] == 0){
+				this.setDetailsContext(this.params["cursor"]);
+			}
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeDeactivate()
+			//
+			// put any updates back to the store
+			currentItem.label = this.First.get("value") + " " + this.Last.get("value");
+			currentItem.First = this.First.get("value");
+			currentItem.Last = this.Last.get("value");
+			currentItem.Email = this.Email.get("value");
+			currentItem.Tel = this.Tel.get("value");
+			listStore.put(currentItem);
+		}
+	}
+});
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/list/list.html b/dojox/app/tests/mediaQueryLayoutApp/views/list/list.html
new file mode 100644
index 0000000..2a24097
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/list/list.html
@@ -0,0 +1,6 @@
+<div class="view mblView">
+	<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">List Test</h2>
+		<form name="listTestForm">
+			<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" data-dojo-attach-point="list" data-dojo-props='append:true'></ul>
+		</form>
+</div>
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/list/list.js b/dojox/app/tests/mediaQueryLayoutApp/views/list/list.js
new file mode 100644
index 0000000..b07ce90
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/list/list.js
@@ -0,0 +1,113 @@
+define(["dojo/_base/lang", "dojo/dom", "dojo/on", "dijit/registry", "dojo/dom-class"],
+function(lang, dom, on, registry, domClass){
+	var _onResults = []; // events on array
+
+	return {
+	// setDetailsContext for an item
+		setDetailsContext: function(index, e, params){
+			if(params){
+				params.cursor = index;
+			}else{
+				params = {"cursor":index};
+			}
+			// transition to itemDetails view with the &cursor=index
+			var transOpts = {
+				title : "itemDetails",
+				target : "itemDetails",
+				url : "#itemDetails", // this is optional if not set it will be created from target   
+				params : params
+			};
+			this.app.transitionToView(e.target,transOpts,e);
+ 
+		
+		},
+
+	// insert an item
+		insertResult: function(index, e){
+			if(index<0 || index>this.list.store.data.length){
+				throw Error("index out of data model.");
+			}
+			if((this.list.store.data[index-1].First=="") ||
+				(this.list.store.data[index] && (this.list.store.data[index].First == ""))){
+				return;
+			}
+			var data = {id:Math.random(), "label": "", "rightIcon":"mblDomButtonBlueCircleArrow", "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+			this.list.store.add(data);
+			this.setDetailsContext(index, e);
+		},
+
+
+		// list view init
+		init: function(){
+			var list = this.list;
+			if(!list.Store){
+				list.setStore(this.loadedStores.listStore);
+			}
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+
+			var onResult;
+			
+			domClass.remove(dom.byId("listInsert1"), "hide");
+			domClass.add(dom.byId("listInsert1"), "show");
+			
+		//	for(var i = 0; i < this.list.store.data.length; i++){
+		//		var item = dom.byId(this.list.store.data[i].id);
+		//		onResult = on(item, "click", lang.hitch(this, function(e){
+		//			var item = this.list.store.query({"label": e.target.innerHTML})
+		//			var index = this.list.store.index[item[0].id];
+		//			console.log("index is "+index);
+		//			this.setDetailsContext(index, e, this.params);
+		//		})); 
+		//		_onResults.push(onResult);
+		//	}
+			
+			onResult = this.list.on("click", lang.hitch(this, function(e){
+				console.log("List on click hit ",e);
+				var item = this.list.store.query({"label": e.target.innerHTML});
+				var index = this.list.store.index[item[0].id];
+				console.log("index is "+index);
+				this.setDetailsContext(index, e, this.params);	
+			})); 
+			_onResults.push(onResult);
+	
+			var listInsert1 = dom.byId("listInsert1");
+			onResult = on(listInsert1, "click", lang.hitch(this, function(e){
+				console.log("listInsert1 on click hit ",e);
+				var index = this.list.store.data.length;
+				this.insertResult(index, e);
+			})); 
+			_onResults.push(onResult);
+			
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			domClass.remove(dom.byId("listInsert1"), "show");
+			domClass.add(dom.byId("listInsert1"), "hide");
+		},
+		
+		afterDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			var onResult = _onResults.pop();
+			while(onResult){
+				onResult.remove();
+				onResult = _onResults.pop();
+			}
+		},
+		
+		
+		// view destroy, this destroy function can be removed since it is empty
+		destroy: function(){
+			// _WidgetBase.on listener is automatically destroyed when the Widget itself is. 
+		}
+	};
+});
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/navigation.html b/dojox/app/tests/mediaQueryLayoutApp/views/navigation.html
new file mode 100644
index 0000000..50895af
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/navigation.html
@@ -0,0 +1,16 @@
+<div class="hideOnPhone">
+	<!-- left -->
+	<div data-dojo-type="dojox/app/widgets/Container" id="NavWidId" class="navPane hideOnPhone" data-app-constraint="left">
+
+	<!-- <div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable:true">  -->
+		<div>
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Navigation</h2>
+			<ul data-dojo-type="dojox/mobile/RoundRectList" data-app-constraint="center">
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Test Information',target:'header+navigation+TestInfo',url:'#header+navigation+TestInfo'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Simple Data Binding',target:'header+navigation+simple',url:'#header+navigation+simple'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Simple List Test',target:'header+navigation+listMain',url:'#header+navigation+listMain'"></li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Simple Date Test',target:'header+navigation+date',url:'#header+navigation+date'"></li>
+			</ul>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/simple/simple.html b/dojox/app/tests/mediaQueryLayoutApp/views/simple/simple.html
new file mode 100755
index 0000000..1e4caea
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/simple/simple.html
@@ -0,0 +1,101 @@
+<div id="settings" class="view mblView">
+	<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Simple Form Data</h2>
+    <form name="testForm" id="testForm">    
+  	<div class="field-title">Using simple JSON Model with data from a dojo/store/Memory</div>
+  			<table id="table" cellspacing="10"  style="width: 100%">
+				<tr>
+					<td style="width: 100px;" class="layout">First</td>
+					<td class="layout">							
+						<input  id="firstInput1" data-dojo-type="dojox/mobile/TextBox" 
+								data-dojo-props="placeholder:'First'">
+					</td>
+				</tr>
+				<tr>
+					<td style="width: 100px;" class="layout">Last Name</td>
+					<td class="layout">
+						<input 	id="lastInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+								data-dojo-props="placeholder:'Last Name'">
+					</td>
+				</tr>
+				<tr>
+					<td style="width: 100px;" class="layout">Email</td>
+					<td class="layout">
+						<input id="emailInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+								data-dojo-props="placeholder:'Email'">
+					</td>
+				</tr>
+			</table>
+		
+	
+  			<div class="spacer"></div>
+			<button id="shipto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Ship To</button>
+			<button id="billto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="shiptodiv" >Ship To:
+	  			<table id="table" cellspacing="10" style="width: 100%">
+					<tr>
+						<td style="width: 100px;" class="layout">Street</td>
+						<td class="layout">							
+							<input  id="shiptostreetInput1" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="placeholder:'Street'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">City</td>
+						<td class="layout">
+							<input 	id="shiptocityInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'City'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">State</td>
+						<td class="layout">
+							<input id="shiptostateInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'State'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">Zip Code</td>
+						<td class="layout">
+							<input id="shiptozipInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'Zip Code'">
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="fieldset" id="billtodiv" >Bill To:
+	  			<table id="table" cellspacing="10" style="width: 100%">
+					<tr>
+						<td style="width: 100px;" class="layout">Street</td>
+						<td class="layout">							
+							<input  id="billtostreetInput1" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="placeholder:'Street'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">City</td>
+						<td class="layout">
+							<input 	id="billtocityInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'City'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">State</td>
+						<td class="layout">
+							<input id="billtostateInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'State'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">Zip Code</td>
+						<td class="layout">
+							<input id="billtozipInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'Zip Code'">
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="spacer"></div>
+			<button id="reset1" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Reset</button>
+    </form>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/mediaQueryLayoutApp/views/simple/simple.js b/dojox/app/tests/mediaQueryLayoutApp/views/simple/simple.js
new file mode 100755
index 0000000..9c8a065
--- /dev/null
+++ b/dojox/app/tests/mediaQueryLayoutApp/views/simple/simple.js
@@ -0,0 +1,62 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry"],
+function(dom, connect, registry){
+
+	var _connectResults = []; // events connect results
+	var currentModel = null;
+
+	var setFromModel = function (){
+		registry.byId("firstInput1").set('value', currentModel[0].First);
+		registry.byId("lastInput1").set('value', currentModel[0].Last);
+		registry.byId("emailInput1").set('value', currentModel[0].Email);
+		registry.byId("shiptostreetInput1").set('value', currentModel[0].ShipTo.Street);
+		registry.byId("shiptocityInput1").set('value', currentModel[0].ShipTo.City);
+		registry.byId("shiptostateInput1").set('value', currentModel[0].ShipTo.State);
+		registry.byId("shiptozipInput1").set('value', currentModel[0].ShipTo.Zip);
+		registry.byId("billtostreetInput1").set('value', currentModel[0].BillTo.Street);
+		registry.byId("billtocityInput1").set('value', currentModel[0].BillTo.City);
+		registry.byId("billtostateInput1").set('value', currentModel[0].BillTo.State);
+		registry.byId("billtozipInput1").set('value', currentModel[0].BillTo.Zip);
+	};
+
+	return {
+		// simple view init
+		init: function(){
+			currentModel = this.loadedModels.names;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId('shipto'), "click", function(){
+				//console.log("shipTo called. ");
+				dom.byId("billtodiv").style.display = "none";
+				dom.byId("shiptodiv").style.display = "";
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('billto'), "click", function(){
+				//console.log("billTo called. ");
+				dom.byId("billtodiv").style.display = "";
+				dom.byId("shiptodiv").style.display = "none";
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('reset1'), "click", function(){
+				//console.log("reset called. ");
+				setFromModel();
+				//console.log("reset done. ");
+			});
+			_connectResults.push(connectResult);
+
+			dom.byId("billtodiv").style.display = "none";
+			setFromModel();
+			
+		},
+
+		// simple view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/modelApp/config.json b/dojox/app/tests/modelApp/config.json
old mode 100644
new mode 100755
index e3d7383..e546056
--- a/dojox/app/tests/modelApp/config.json
+++ b/dojox/app/tests/modelApp/config.json
@@ -5,56 +5,63 @@
 	"splash": "splash",
 
 	"dependencies": [
+		"dojox/app/utils/simpleModel",
+		"dojo/store/Observable",		
 		"dojox/mobile/_base",
+		"dojox/mobile/compat",
 		"dojox/mobile/TabBar",
 		"dojox/mobile/RoundRect",
 		"dojox/mobile/TabBarButton",
 		"dojox/mobile/Button",
+		"dojox/mobile/TextBox",
 		"dojox/mobile/RoundRect",
 		"dojox/mobile/Heading",
-		"dojox/mvc/StatefulModel", //TODO remove the explicit dependency for stores.
-		"dojo/store/Memory", //TODO remove the explicit dependency for stores.
-		"dojox/mvc/Group",
-        "dojox/mvc/Repeat",
-        "dojox/mvc"
+		"dojox/mobile/EdgeToEdgeStoreList",
+		"dojox/mobile/DatePicker",
+		"dojox/mobile/Opener",
+		"dojo/store/Memory",
+		"dojox/mobile/deviceTheme"
 	],
 	// Modules for the application.  The are basically used as the second
 	// array of mixins in a dojo.declare().  Modify the top level behavior
 	// of the application, how it processes the config or any other life cycle
 	// by creating and including one or more of these
 	"modules": [
-		"dojox/app/module/env",
-		"dojox/app/module/history",
-		"dojox/app/module/lifecycle"
-		//"dojox/app/module/phonegap",
-		//"dojox/app/module/somePlugin"
+		//"dojox/app/module/env",
+		//"dojox/app/module/lifecycle"
+	],
+	
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
 	],
 
 	//stores we are using 
 	"stores": {
-	   "namesStore":{
-	       "type": "dojo.store.Memory",
-		   "params": {
-		      "data": "modelApp.names"
-		   }
-	   },
-       "repeatStore":{
-           "type": "dojo.store.Memory",
+       "listStore":{
+           "type": "dojo/store/Memory",
+	       "observable": true,
            "params": {
-                "data": "modelApp.repeatData"
+                "data": "modelApp.listData"
            }
        }
 	},
-
-	//models and instantiation parameters for the models. Including 'type' as a property allows
-	//one to overide the class that will be used for the model.  By default it is dojox/mvc/model
-	"models": {
-	   "names": {
-	       "params":{
-		      "store": {"$ref":"#stores.namesStore"}
-		   }	       
-	   }
-	}, 
+	
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
 
 	//the name of the scene to load when the app is initialized.
 	"defaultView": "home", 
@@ -64,34 +71,56 @@
 	"views": {
 
 		"home": { 
-			"type": "dojox.app.view",
 			"dependencies":["dojox/mobile/ListItem","dojox/mobile/RoundRectList","dojox/mobile/RoundRectCategory","dojox/mobile/Heading"],
-			"template": "views/main.html"
+			"template": "./main/main.html"
 		},
 
-		"simple":{
-			"type": "dojox.app.view",
-			"template": "views/simple.html",			
-			"dependencies":["dojox/mobile/TextBox"],
+		//list view, include list view and details view
+		"listMain": {
+			"defaultView": "list",
+			"defaultTransition": "slide",
+
+			"views": {
+				"list":{
+					"controller" : "./list/list.js",
+					"template": "./list/list.html",
+					"dependencies":["dojox/mobile/TextBox"]
+				},
+				"itemDetails":{
+					"controller" : "./list/itemDetails.js",
+					"template": "./list/itemDetails.html",
+					"dependencies":["dojox/mobile/TextBox"],
+					"defaultParams": {"cursor":"2"}
+				}
+			}
 		},
 
-		"repeat": {
-            "type": "dojox.app.view",
+		"simple":{
+			"stores": {
+				"namesStore":{
+					"type": "dojo/store/Memory",
+					"params": {
+		    	  		"data": "modelApp.names"
+		  		 	}
+		  		 }
+	   		},
             "models": {
-                "repeatmodels": {
-                    "params":{
-                        "store": {"$ref":"#stores.repeatStore"}
-                    }           
-                }
-            },
-            "template": "views/repeat.html",
-            "dependencies":["dojox/mobile/TextBox"],
+				"names": {
+					"modelLoader": "dojox/app/utils/simpleModel",
+					"params":{
+						"store": {"$ref":"#views.simple.stores.namesStore"}
+					}
+				}
+			},
+			"controller" : "./simple/simple.js",
+			"template": "./simple/simple.html",
+			"dependencies":["dojox/mobile/TextBox"]
 		},
 
-		"generate": {
-            "type": "dojox.app.view",
-            "template": "views/generate.html",
-            "dependencies":["dojox/mobile/TextBox", "dojox/mobile/TextArea", "dojox/mvc/Generate"],
+		"date": {
+            "controller": "./date/date.js",
+            "template": "./date/date.html",
+            "dependencies":["dojox/mobile/TextBox", "dojox/mobile/TextArea"]
 		}
 	}	
 }
diff --git a/dojox/app/tests/modelApp/date/date.html b/dojox/app/tests/modelApp/date/date.html
new file mode 100644
index 0000000..035de6d
--- /dev/null
+++ b/dojox/app/tests/modelApp/date/date.html
@@ -0,0 +1,24 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Date Example", back:"Home"'></div>
+	<div>
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Using a dojox/mobile/DatePicker and a dojox/mobile/Opener</h2>
+
+		<h2 dojoType="dojox/mobile/RoundRectCategory">Click to select a date</h2>
+
+		<input data-dojo-attach-point="selDate1" readOnly value="" placeholder="Select a date" style="margin-left: 20px;">
+
+		<div id="opener" data-dojo-attach-point="opener" data-dojo-type="dojox/mobile/Opener">
+			<h1 data-dojo-type="dojox/mobile/Heading" label="Date Picker">
+				<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="save" 
+					data-dojo-props="label:'Done'" class="mblColorBlue"
+					style="position:absolute;width:45px;right:0;">
+				</span>
+				<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="cancel"
+					data-dojo-props="label:'Cancel'" class="mblColorBlue" 
+					style="position:absolute;width:45px;left:0;">
+				</span>
+			</h1>
+			<div data-dojo-attach-point="datePicker2" data-dojo-type="dojox/mobile/DatePicker"></div>
+		</div>
+	</div>	
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/modelApp/date/date.js b/dojox/app/tests/modelApp/date/date.js
new file mode 100644
index 0000000..132154b
--- /dev/null
+++ b/dojox/app/tests/modelApp/date/date.js
@@ -0,0 +1,44 @@
+define(["dojo/_base/lang", "dojo/on", "dijit/registry", "dojo/date/stamp"],
+function(lang, on, registry, stamp){
+	var _onResults = []; // events on array
+	var opener;
+
+	return {
+		init: function(){
+			opener = this.opener;
+			var onResult = on(this.selDate1, "click", lang.hitch(this, function(){
+				this.datePicker2.set("value", date);
+				this.opener.show(this.selDate1, ['below-centered','above-centered','after','before']);
+			})); 
+			_onResults.push(onResult);
+
+			onResult = on(this.save, "click", lang.hitch(this, function(){
+				this.opener.hide(true);
+				date = this.selDate1.value = this.datePicker2.get("value");
+			})); 
+			_onResults.push(onResult);
+
+			onResult = on(this.cancel, "click", lang.hitch(this, function(){
+				this.opener.hide(false);
+			})); 
+			_onResults.push(onResult);
+
+			// initialize the global Date variable as today
+			date = stamp.toISOString(new Date(), {selector: "date"});
+		},
+
+		beforeActivate: function(){
+			//console.log("date view beforeActivate()");
+		},
+
+
+		// view destroy
+		destroy: function(){
+			var onResult = _onResults.pop();
+			while(onResult){
+				onResult.remove();
+				onResult = _onResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/modelApp/index.html b/dojox/app/tests/modelApp/index.html
index c2469fd..db3709e 100644
--- a/dojox/app/tests/modelApp/index.html
+++ b/dojox/app/tests/modelApp/index.html
@@ -1,10 +1,10 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
-		<meta name="apple-mobile-web-app-capable" content="yes" /> 
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
 		<title>Model App Test</title> 
-		<link href="../../../mobile/themes/iphone/base.css" rel="stylesheet"></link>
+		<link href="../../../mobile/themes/iphone/base.css" rel="stylesheet">
 		<style>
 			html,body {
 				width: 100%;
@@ -13,8 +13,8 @@
 				font-family: arial;
 				color: #333;
 				overflow: hidden;
-				margin: 0px;
-				padding: 0px;
+				margin: 0;
+				padding: 0;
 				visibility: visible;
 			}
 
@@ -24,11 +24,12 @@
 				margin: auto;
 				overflow: hidden;
 				border: 2px solid green;
-				font-color: #333;
+				color: #333;
 				text-align: center;
 			}
 
 		</style>
+		
 		<script type="text/javascript">
 			dojoConfig = {
 				parseOnLoad: false,
@@ -43,13 +44,13 @@
 					"loader-execModule-out":1,
 					"loader-defineModule":1
 				},
-				async:1
-			}
+				async:1,
+				app: {debugApp: 1}  // set debugApp to log app transtions and view activate/deactivate 
+			};
 		</script>
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 
 		<script>
-            console.log("post dojo");
             // the actual  launcher
             require(["./modelApp.js"], function(){});
         </script>
diff --git a/dojox/app/tests/modelApp/list/itemDetails.html b/dojox/app/tests/modelApp/list/itemDetails.html
new file mode 100644
index 0000000..2923f41
--- /dev/null
+++ b/dojox/app/tests/modelApp/list/itemDetails.html
@@ -0,0 +1,37 @@
+<div class="view mblView">
+    <h1 dojoType="dojox/mobile/Heading" data-dojo-props='back:"Back"'>List Item Details</h1>
+    <form name="listTestForm" id="listTestForm">    
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Updates to First or Last Name will be reflected in the list</h2>
+					<table id="table" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="First"
+									data-dojo-props="placeholder:'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Last"
+									 
+									data-dojo-props="placeholder:'Last Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput2" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Email"
+									data-dojo-props="placeholder:'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-attach-point="Tel"
+									data-dojo-props="placeholder:'Telephone'">
+							</td>
+						</tr>
+					</table>
+		</form>
+</div>
diff --git a/dojox/app/tests/modelApp/list/itemDetails.js b/dojox/app/tests/modelApp/list/itemDetails.js
new file mode 100644
index 0000000..b25bc08
--- /dev/null
+++ b/dojox/app/tests/modelApp/list/itemDetails.js
@@ -0,0 +1,48 @@
+define([],
+function(){
+
+	var listStore = null;	//list data
+	var currentItem = null;
+
+	return {
+		// show an item detail
+		setDetailsContext: function(index){
+			// only set the cursor if it is different and valid
+			if(parseInt(index) < listStore.data.length){
+				currentItem = listStore.data[index];
+				this.First.set("value",currentItem.First);
+				this.Last.set("value",currentItem.Last);
+				this.Email.set("value",currentItem.Email);
+				this.Tel.set("value",currentItem.Tel);
+			}
+		},
+
+		// list view init
+		init: function(){
+			listStore = this.loadedStores.listStore;
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			// if this.params["cursor"] is set use it to set the selected Details Context
+			if(this.params["cursor"] || this.params["cursor"] == 0){
+				this.setDetailsContext(this.params["cursor"]);
+			}
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeDeactivate()
+			//
+			// put any updates back to the store
+			currentItem.label = this.First.get("value") + " " + this.Last.get("value");
+			currentItem.First = this.First.get("value");
+			currentItem.Last = this.Last.get("value");
+			currentItem.Email = this.Email.get("value");
+			currentItem.Tel = this.Tel.get("value");
+			listStore.put(currentItem);
+		}
+	}
+});
diff --git a/dojox/app/tests/modelApp/list/list.html b/dojox/app/tests/modelApp/list/list.html
new file mode 100644
index 0000000..61a03ab
--- /dev/null
+++ b/dojox/app/tests/modelApp/list/list.html
@@ -0,0 +1,11 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"List Example", back:"Home"'>
+  		<span data-dojo-type="dojox/mobile/ToolBarButton" data-dojo-attach-point="listInsert1"
+       		 data-dojo-props='icon:"mblDomButtonWhitePlus"'
+        		style="float:right;" onclick="console.log('+ was clicked')"></span>
+	</div>    
+	<form name="listTestForm">
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Using a dojox/mobile/EdgeToEdgeStoreList</h2>
+		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" data-dojo-attach-point="list" data-dojo-props='append:true'></ul>
+	</form>
+</div>
diff --git a/dojox/app/tests/modelApp/list/list.js b/dojox/app/tests/modelApp/list/list.js
new file mode 100644
index 0000000..192eb76
--- /dev/null
+++ b/dojox/app/tests/modelApp/list/list.js
@@ -0,0 +1,66 @@
+define(["dojo/_base/lang", "dojo/on"], function(lang, on){
+
+	return {
+	// setDetailsContext for an item
+		setDetailsContext: function(index, e, params){
+			if(params){
+				params.cursor = index;
+			}else{
+				params = {"cursor":index};
+			}
+			// transition to itemDetails view with the &cursor=index
+			var transOpts = {
+				title : "itemDetails",
+				target : "listMain,itemDetails",
+				url : "#listMain,itemDetails", // this is optional if not set it will be created from target   
+				params : params
+			};
+			this.app.transitionToView(e.target,transOpts,e);
+ 
+		
+		},
+
+	// insert an item
+		insertResult: function(index, e){
+			if(index<0 || index>this.list.store.data.length){
+				throw Error("index out of data model.");
+			}
+			if((this.list.store.data[index-1].First=="") ||
+				(this.list.store.data[index] && (this.list.store.data[index].First == ""))){
+				return;
+			}
+			var data = {id:Math.random(), "label": "", "rightIcon":"mblDomButtonBlueCircleArrow", "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+			this.list.store.add(data);
+			this.setDetailsContext(index, e);
+		},
+
+
+		// list view init
+		init: function(){
+			var list = this.list;
+			if(!list.Store){
+				list.setStore(this.loadedStores.listStore);
+			}
+			
+			this.list.on("click", lang.hitch(this, function(e){
+				console.log("List on click hit ",e);
+				var item = this.list.store.query({"label": e.target.innerHTML});
+				var index = this.list.store.index[item[0].id];
+				console.log("index is "+index);
+				this.setDetailsContext(index, e, this.params);	
+			})); 
+
+			this.listInsert1.on("click", lang.hitch(this, function(e){
+				console.log("listInsert1 on click hit ",e);
+				var index = this.list.store.data.length;
+				this.insertResult(index, e);
+			})); 
+			
+		},
+
+		// view destroy, this destroy function can be removed since it is empty
+		destroy: function(){
+			// _WidgetBase.on listener is automatically destroyed when the Widget itself is. 
+		}
+	};
+});
diff --git a/dojox/app/tests/modelApp/main/main.html b/dojox/app/tests/modelApp/main/main.html
new file mode 100644
index 0000000..4710dbf
--- /dev/null
+++ b/dojox/app/tests/modelApp/main/main.html
@@ -0,0 +1,9 @@
+<div class="view mblView">
+    <h1 dojoType="dojox/mobile/Heading">App Demo</h1>
+    <h2 dojoType="dojox/mobile/RoundRectCategory">App demo Views</h2>
+    <ul dojoType="dojox/mobile/RoundRectList">
+        <li dojoType="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Simple Form Data',target:'simple',url:'#simple'"></li>
+        <li dojoType="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'List Data Test',target:'listMain',url:'#listMain'"></li>
+        <li dojoType="dojox/mobile/ListItem" data-dojo-props="clickable:true,label:'Date Test',target:'date',url:'#date'"></li>
+    </ul>
+</div>
diff --git a/dojox/app/tests/modelApp/modelApp.js b/dojox/app/tests/modelApp/modelApp.js
index 78809ea..d9739d9 100644
--- a/dojox/app/tests/modelApp/modelApp.js
+++ b/dojox/app/tests/modelApp/modelApp.js
@@ -1,98 +1,68 @@
-require(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/loader"], function(dojo, lang){
-var path = window.location.pathname;
-if (path.charAt(path.length)!="/"){
-	path = path.split("/");
-	path.pop();
-	path=path.join("/");	
-}
-dojo.registerModulePath("app",path);
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojo/sniff"],
+function(win, Application, jsonRef, config, has){
+	win.global.modelApp = {};
+	modelApp.names = {
+		identifier: "id",
+		items: [{
+			"id": "1",
+			"Serial": "360324",
+			"First": "John",
+			"Last": "Doe",
+			"Email": "jdoe at us.ibm.com",
+			"ShipTo": {
+				"Street": "123 Valley Rd",
+				"City": "Katonah",
+				"State": "NY",
+				"Zip": "10536"
+			},
+			"BillTo": {
+				"Street": "17 Skyline Dr",
+				"City": "Hawthorne",
+				"State": "NY",
+				"Zip": "10532"
+			}
+		}]
+	};
+
+	modelApp.listData = { 
+		identifier: "id",
+		'items':[{
+			"id": "item1",
+			"label": "Chad Chapman",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Chad",
+			"Last": "Chapman",
+			"Location": "CA",
+			"Office": "1278",
+			"Email": "c.c at test.com",
+			"Tel": "408-764-8237",
+			"Fax": "408-764-8228"
+		}, {
+			"id": "item2",
+			"label": "Irene Ira",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "Irene",
+			"Last": "Ira",
+			"Location": "NJ",	
+			"Office": "F09",
+			"Email": "i.i at test.com",
+			"Tel": "514-764-6532",
+			"Fax": "514-764-7300"
+		}, {
+			"id": "item3",
+			"label": "John Jacklin",
+			"rightIcon":"mblDomButtonBlueCircleArrow",
+			"First": "John",
+			"Last": "Jacklin",
+			"Location": "CA",
+			"Office": "6701",
+			"Email": "j.j at test.com",
+			"Tel": "408-764-1234",
+			"Fax": "408-764-4321"
+		}]
+	};
+	var cfg = jsonRef.fromJson(config);
+	has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+	Application(cfg);
 
-    // search script tag and create new tag in head to fix IE and Firefox not load script.
-    // In IE, set script text to innerHTML with <script type="text/javascript" defer> can load script.
-    // In Firefox and Chrome, not support defer in innerHTML, but support defer in static page.
-    // Use string.match(/<script.*?>.*?<\/script>/, templateString) cannot get matches because templateString contains "\n".
-    // So use string.indexOf to check "<script" and "</script>", then replace "<script*" to empty.
-    var addDynamicScript = function(node){
-        if (!node.templateString) {
-            return;
-        }
-        var tempStr = node.templateString;
-        var scriptText = "";
-        var startIndex = tempStr.indexOf("<script");
-        var endIndex = tempStr.indexOf("<\/script>");
-        
-        while ((startIndex > -1) && (endIndex > -1) && (endIndex > startIndex)) {
-            var str = tempStr.substring(startIndex, endIndex);
-            str = str.replace(/<script.*?>.*?/, "");
-            scriptText += str;
-            
-            startIndex = tempStr.indexOf("<script", endIndex);
-            endIndex = tempStr.indexOf("<\/script>", endIndex);
-        }
-        
-        if (scriptText) {
-            var header = document.getElementsByTagName('head')[0];
-            var scriptTag = document.createElement('script');
-            scriptTag.text = scriptText;
-            header.appendChild(scriptTag);
-        }
-    };
-    
-    require(["dojo", "dojox/app/main", "dojox/json/ref", "dojo/text!app/config.json", "dojo/_base/connect"], function(dojo, Application, jsonRef, config, connect){
-    //app = Application(dojox.json.ref.resolveJson(config), dojo.body());
-    dojo.global.modelApp = {};
-    modelApp.names = [{
-            "Serial" : "360324",
-            "First"  : "John",
-            "Last"   : "Doe",
-            "Email"  : "jdoe at us.ibm.com",
-            "ShipTo" : {
-                "Street" : "123 Valley Rd",
-                "City"   : "Katonah",
-                "State"  : "NY",
-                "Zip"    : "10536"
-            },
-            "BillTo" : {
-                "Street" : "17 Skyline Dr",
-                "City"   : "Hawthorne",
-                "State"  : "NY",
-                "Zip"    : "10532"
-            }
-        }];
-    modelApp.repeatData = [ 
-                   {
-                       "First"   : "Chad",
-                       "Last"    : "Chapman",
-                       "Location": "CA",
-                       "Office"  : "1278",
-                       "Email"   : "c.c at test.com",
-                       "Tel"     : "408-764-8237",
-                       "Fax"     : "408-764-8228"
-                   },
-                   {
-                       "First"   : "Irene",
-                       "Last"    : "Ira",
-                       "Location": "NJ",
-                       "Office"  : "F09",
-                       "Email"   : "i.i at test.com",
-                       "Tel"     : "514-764-6532",
-                       "Fax"     : "514-764-7300"
-                   },
-                   {
-                       "First"   : "John",
-                       "Last"    : "Jacklin",
-                       "Location": "CA",
-                       "Office"  : "6701",
-                       "Email"   : "j.j at test.com",
-                       "Tel"     : "408-764-1234",
-                       "Fax"     : "408-764-4321"
-                   }
-                   ];
-        app = Application(jsonRef.fromJson(config));
-        
-        connect.subscribe("/app/loadchild", lang.hitch(app, function(node){
-            console.log(node);
-			addDynamicScript(node);
-        }));
 });
-});
\ No newline at end of file
diff --git a/dojox/app/tests/modelApp/simple/simple.html b/dojox/app/tests/modelApp/simple/simple.html
new file mode 100755
index 0000000..eec2159
--- /dev/null
+++ b/dojox/app/tests/modelApp/simple/simple.html
@@ -0,0 +1,101 @@
+<div id="settings" class="view mblView">
+    <h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='back:"Home"'>Simple Form Data</h1>
+    <form name="testForm" id="testForm">    
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Using simple JSON Model with data from a dojo/store/Memory</h2>
+  			<table id="table" cellspacing="10"  style="width: 100%">
+				<tr>
+					<td style="width: 100px;" class="layout">First</td>
+					<td class="layout">							
+						<input  id="firstInput1" data-dojo-type="dojox/mobile/TextBox" 
+								data-dojo-props="placeholder:'First'">
+					</td>
+				</tr>
+				<tr>
+					<td style="width: 100px;" class="layout">Last Name</td>
+					<td class="layout">
+						<input 	id="lastInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+								data-dojo-props="placeholder:'Last Name'">
+					</td>
+				</tr>
+				<tr>
+					<td style="width: 100px;" class="layout">Email</td>
+					<td class="layout">
+						<input id="emailInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+								data-dojo-props="placeholder:'Email'">
+					</td>
+				</tr>
+			</table>
+		
+	
+  			<div class="spacer"></div>
+			<button id="shipto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Ship To</button>
+			<button id="billto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="shiptodiv" >Ship To:
+	  			<table id="table" cellspacing="10" style="width: 100%">
+					<tr>
+						<td style="width: 100px;" class="layout">Street</td>
+						<td class="layout">							
+							<input  id="shiptostreetInput1" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="placeholder:'Street'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">City</td>
+						<td class="layout">
+							<input 	id="shiptocityInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'City'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">State</td>
+						<td class="layout">
+							<input id="shiptostateInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'State'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">Zip Code</td>
+						<td class="layout">
+							<input id="shiptozipInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'Zip Code'">
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="fieldset" id="billtodiv" >Bill To:
+	  			<table id="table" cellspacing="10" style="width: 100%">
+					<tr>
+						<td style="width: 100px;" class="layout">Street</td>
+						<td class="layout">							
+							<input  id="billtostreetInput1" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="placeholder:'Street'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">City</td>
+						<td class="layout">
+							<input 	id="billtocityInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'City'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">State</td>
+						<td class="layout">
+							<input id="billtostateInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'State'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">Zip Code</td>
+						<td class="layout">
+							<input id="billtozipInput1" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'Zip Code'">
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="spacer"></div>
+			<button id="reset1" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Reset</button>
+    </form>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/modelApp/simple/simple.js b/dojox/app/tests/modelApp/simple/simple.js
new file mode 100755
index 0000000..9c8a065
--- /dev/null
+++ b/dojox/app/tests/modelApp/simple/simple.js
@@ -0,0 +1,62 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry"],
+function(dom, connect, registry){
+
+	var _connectResults = []; // events connect results
+	var currentModel = null;
+
+	var setFromModel = function (){
+		registry.byId("firstInput1").set('value', currentModel[0].First);
+		registry.byId("lastInput1").set('value', currentModel[0].Last);
+		registry.byId("emailInput1").set('value', currentModel[0].Email);
+		registry.byId("shiptostreetInput1").set('value', currentModel[0].ShipTo.Street);
+		registry.byId("shiptocityInput1").set('value', currentModel[0].ShipTo.City);
+		registry.byId("shiptostateInput1").set('value', currentModel[0].ShipTo.State);
+		registry.byId("shiptozipInput1").set('value', currentModel[0].ShipTo.Zip);
+		registry.byId("billtostreetInput1").set('value', currentModel[0].BillTo.Street);
+		registry.byId("billtocityInput1").set('value', currentModel[0].BillTo.City);
+		registry.byId("billtostateInput1").set('value', currentModel[0].BillTo.State);
+		registry.byId("billtozipInput1").set('value', currentModel[0].BillTo.Zip);
+	};
+
+	return {
+		// simple view init
+		init: function(){
+			currentModel = this.loadedModels.names;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId('shipto'), "click", function(){
+				//console.log("shipTo called. ");
+				dom.byId("billtodiv").style.display = "none";
+				dom.byId("shiptodiv").style.display = "";
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('billto'), "click", function(){
+				//console.log("billTo called. ");
+				dom.byId("billtodiv").style.display = "";
+				dom.byId("shiptodiv").style.display = "none";
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('reset1'), "click", function(){
+				//console.log("reset called. ");
+				setFromModel();
+				//console.log("reset done. ");
+			});
+			_connectResults.push(connectResult);
+
+			dom.byId("billtodiv").style.display = "none";
+			setFromModel();
+			
+		},
+
+		// simple view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/modelApp/views/generate.html b/dojox/app/tests/modelApp/views/generate.html
deleted file mode 100644
index 738091e..0000000
--- a/dojox/app/tests/modelApp/views/generate.html
+++ /dev/null
@@ -1,68 +0,0 @@
-    <div id="generate" class="view mblView"> 
-    <h1 dojoType="dojox.mobile.Heading" back="Home">Simple Form Generate Example</h1> 
-    <div class="field-title"></div> 
-        <div id="main"> 
-          <div id="leftNav"> 
-          </div> 
-          <div id="mainContent" class="generate-maincontent"> 
-            <div id="outerModelArea"> 
-                <h3 dojoType="dojox.mobile.RoundRectCategory">Model</h3> 
-                <div class="generate-textarea-row"> 
-                    <textarea class="generate-textarea-cell" dojoType="dojox.mobile.TextArea" id="modelArea" style="width: 300px; height: 300px;"> 
-{
-    "Serial": "11111",
-    "First": "John",
-    "Last": "Doe",
-    "Email": "jdoe at example.com",
-    "Phones": [
-        {
-            "Office": "111-111-1111"
-        },
-        {
-            "Mobile": "222-222-2222"
-        }
-    ]
-}
-                    </textarea> 
-                </div> 
-                <div class="fieldset"> 
-                    <div class="spacer"></div> 
-                    <button id="generate1" dojoType="dojox.mobile.Button" class="mblBlueButton" data-dojo-props="onClick: function(e){updateView();}">Generate Form</button> 
-                </div> 
-            </div> 
-            <div id="viewArea" style="display:none"> 
-                <h3 dojoType="dojox.mobile.RoundRectCategory">Generated View</h3> 
-                <div class="fieldset"> 
-                    <div id="view" dojoType="dojox.mvc.Generate"></div> 
-                </div> 
-                <div class="fieldset"> 
-                    <div class="spacer"></div> 
-                    <button id="updateModel" dojoType="dojox.mobile.Button" class="mblBlueButton" data-dojo-props="onClick: function(e){updateModel();}">Update Model</button> 
-                </div> 
-            </div> 
-          </div> 
-        </div>
-        <script type="text/javascript">
-            // used in the Generate View demo
-            var genmodel;
-            function updateView() {
-                try {
-                    var modeldata = dojo.fromJson(dojo.byId("modelArea").value);
-                    genmodel = dojox.mvc.newStatefulModel({ data : modeldata });
-                    dijit.byId("view").set("ref", genmodel);
-                    dojo.byId("outerModelArea").style.display = "none";
-                    dojo.byId("viewArea").style.display = "";                   
-                }catch(err){
-                    console.error("Error parsing json from model: "+err);
-                }
-            };
-
-            // used in the Generate View demo
-            function updateModel() {
-                dojo.byId("modelArea").focus(); // hack: do this to force focus off of the textbox, bug on mobile?
-                dojo.byId("viewArea").style.display = "none";
-                dojo.byId("outerModelArea").style.display = "";
-                dijit.byId("modelArea").set("value",(dojo.toJson(genmodel.toPlainObject(), true)));
-            };
-        </script>
-        </div> 
\ No newline at end of file
diff --git a/dojox/app/tests/modelApp/views/main.html b/dojox/app/tests/modelApp/views/main.html
deleted file mode 100644
index f81f51c..0000000
--- a/dojox/app/tests/modelApp/views/main.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<div class="view mblView">
-    <h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo</h1>
-    <h2 dojoType="dojox.mobile.RoundRectCategory">Mobile MVC Views</h2>
-    <ul dojoType="dojox.mobile.RoundRectList">
-        <li dojoType="dojox.mobile.ListItem" clickable="true" transitionOptions="{title:'simple',target:'simple'}">
-            Simple Data Binding
-        </li>
-        <li dojoType="dojox.mobile.ListItem" clickable="true" transitionOptions="{title:'repeat',target:'repeat'}">
-            Repeat Data Binding
-        </li>
-        <li dojoType="dojox.mobile.ListItem" clickable="true" transitionOptions="{title:'generate',target:'generate'}">
-            Simple Form Generate
-        </li>
-    </ul>
-</div>
diff --git a/dojox/app/tests/modelApp/views/repeat.html b/dojox/app/tests/modelApp/views/repeat.html
deleted file mode 100644
index 28a238c..0000000
--- a/dojox/app/tests/modelApp/views/repeat.html
+++ /dev/null
@@ -1,89 +0,0 @@
-<div class="view mblView">
-    <h1 dojoType="dojox.mobile.Heading" back="Home">Repeat Data Binding Example</h1>
-    <form name="repeatTestForm" id="repeatTestForm">    
-    <div class="field-title">Search Results</div>
-    
-        <div id="repeatWidget" class="fieldset" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="exprchar: '#', ref: 'repeatmodels'" >
-            <div dojoType="dojox.mvc.Group" ref="'rel:#{this.index}'">
-                <div class="row">            
-                    <input dojoType="dojox.mobile.TextBox"
-                        id="nameInput#{this.index}" ref="'rel:First'" placeHolder="First Name"></input>
-                    <button type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" data-dojo-props="onClick: function(e){setDetailsContext('#{this.index}');}">
-                        Details
-                    </button>
-                    <button type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" data-dojo-props="onClick: function(){insertResult('#{this.index}');}">
-                        +
-                    </button>
-                    <button type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" data-dojo-props="onClick: function(){deleteResult('#{this.index}');}">
-                        -
-                    </button>
-                </div>
-            </div>
-        </div>
-        
-        <div class="spacer"></div>
-        <div  dojoType="dojox.mvc.Group" ref="'repeatmodels'">
-            <div id="detailsBanner">Details for selected index:</div>
-                <div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
-                    <div class="field-row">
-                        <span>First Name</span>
-                        <input type=text id="firstInput" dojoType="dojox.mobile.TextBox"
-                            placeholder="First Name" ref="'rel:First'"></input>
-                    </div>
-                    <div class="field-row">
-                        <span>Last Name</span>
-                        <input type=text id="lastInput" dojoType="dojox.mobile.TextBox"
-                            placeholder="Last Name" ref="'rel:Last'"></input>
-                    </div>
-                    <div class="field-row">
-                        <span>Email</span>
-                        <input type=text id="emailInput2" dojoType="dojox.mobile.TextBox"
-                            placeholder="Email" ref="'rel:Email'"></input>
-                    </div>
-                    <div class="field-row">
-                        <span>Telephone</span>
-                        <input type=text id="telInput" dojoType="dojox.mobile.TextBox"
-                            placeholder="Telephone" ref="'rel:Tel'"></input>
-                    </div>
-                </div>
-            </div>         
-        <div class="spacer"></div>
-        <button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" data-dojo-props="onClick: function(){console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit();}">Save</button>
-        <button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" data-dojo-props="onClick: function(){repeatmodel.reset();}">Reset</button>
-        <script type="text/javascript">
-            var selectedIndex = 0;
-            var repeatmodel = dijit.byId('repeatWidget').ref;
-
-            function setDetailsContext(index) {
-                var widget = dijit.byId("detailsGroup");
-                widget.set("ref", index);
-                selectedIndex = index;
-            }
-
-            // used in the Repeat Data binding demo
-        function insertResult(index){
-
-            if (repeatmodel[index].First.value !== "") {
-                var insert = dojox.mvc.newStatefulModel({
-                    "data": {
-                        "First": "",
-                        "Last": "",
-                        "Location": "CA",
-                        "Office": "",
-                        "Email": "",
-                        "Tel": "",
-                        "Fax": ""
-                    }
-                });
-                repeatmodel.add(index, insert);
-												
-                setDetailsContext(parseInt(index)+1);
-            }
-
-        };
-        
-        function deleteResult(index){
-            repeatmodel.remove(index);
-        }
-        </script>
-</div>
diff --git a/dojox/app/tests/modelApp/views/simple.html b/dojox/app/tests/modelApp/views/simple.html
deleted file mode 100644
index bfe3b2c..0000000
--- a/dojox/app/tests/modelApp/views/simple.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<div id="settings" class="view mblView">
-    <script type="text/javascript">
-        function setRef(id, addrRef) {
-                var widget = dijit.byId("infoGroup");
-                var target = dijit.byId(id);
-                var model = widget.get("ref");
-                target.set("ref", model[addrRef]);
-            }
-    </script>
-    <h1 dojoType="dojox.mobile.Heading" back="Home">Data Binding Example</h1>
-    <form name="testForm" id="testForm">    
-    <div class="field-title">Ship to - Bill to Address</div>
-        <div id="infoGroup" class="fieldset" dojoType="dojox.mvc.Group" ref="'names.0'">
-            <div class="field-row">
-                <span>Order #</span>
-                <input type=text id="lastnameInput" dojoType="dojox.mobile.TextBox"
-                    placeholder="Order #" ref="'rel:Serial'"></input>
-            </div>
-            <div class="field-row">
-                <span>Last</span>
-                <input type=text id="serialInput" dojoType="dojox.mobile.TextBox"
-                    placeholder="Last" ref="'rel:Last'"></input>
-            </div>
-            <div class="field-row">
-                <span>Email</span>
-                <input type=text id="emailInput1" dojoType="dojox.mobile.TextBox"
-                    placeholder="Last" ref="'rel:Email'"></input>
-            </div>
-        </div>
-        <div class="spacer"></div>
-        <button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', 'ShipTo')">Ship To</button>
-        <button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', 'BillTo')">Bill To</button>     
-        <br/>
-        <div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="'names.0.ShipTo'">
-            <div class="field-row">
-                <span>Street</span>
-                <input type=text id="streetInput" dojoType="dojox.mobile.TextBox"
-                    placeholder="Street" ref="'rel:Street'"></input>
-            </div>
-            <div class="field-row">
-                <span>City</span>
-                <input type=text id="cityInput" dojoType="dojox.mobile.TextBox"
-                    placeholder="City" ref="'rel:City'"></input>
-            </div>
-            <div class="field-row">
-                <span>State</span>
-                <input type=text id="stateInput" dojoType="dojox.mobile.TextBox"
-                    placeholder="State" ref="'rel:State'"></input>
-            </div>
-            <div class="field-row">
-                <span>ZIP Code</span>
-                <input type=text id="zipInput" dojoType="dojox.mobile.TextBox"
-                    placeholder="ZIP Code" ref="'rel:Zip'"></input>
-            </div>
-        </div>
-        <div class="spacer"></div>
-        <button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="dijit.byId('infoGroup').get('ref').reset();">Reset</button>
-    </form>
-</div>
\ No newline at end of file
diff --git a/dojox/app/tests/multiSceneApp/application.html b/dojox/app/tests/multiSceneApp/application.html
old mode 100644
new mode 100755
index dad92c8..705bcc2
--- a/dojox/app/tests/multiSceneApp/application.html
+++ b/dojox/app/tests/multiSceneApp/application.html
@@ -1,5 +1,5 @@
 <div>
-	<ul region="bottom" dojoType="dojox.mobile.TabBar" fixed="bottom" style="position: relative;border-bottom:none;" iconBase="../images/tab-icons.png">
+	<ul data-app-constraint="bottom" dojoType="dojox.mobile.TabBar" fixed="bottom" style="position: relative;border-bottom:none;" iconBase="../images/tab-icons.png">
 		<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,58,29,29" iconPos2="29,58,29,29" selected="true" transitionOptions='{title:"Home",target:"home",url: "#home"}'>Home</li> 
 		<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,0,29,29" iconPos2="29,0,29,29"  transitionOptions='{title:"Main",target:"main,main",url: "#main,main"}'>Main</li> 
 		<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,29,29,29" iconPos2="29,29,29,29" transitionOptions='{title:"TabScene - Tab1",target:"tabscene,tab1",url: "#tabscene,tab1"}'>Tabbed Scene</li> 
diff --git a/dojox/app/tests/multiSceneApp/config.json b/dojox/app/tests/multiSceneApp/config.json
old mode 100644
new mode 100755
index 609a379..33d1072
--- a/dojox/app/tests/multiSceneApp/config.json
+++ b/dojox/app/tests/multiSceneApp/config.json
@@ -18,17 +18,23 @@
 	// of the app, how it processes the config or any other life cycle
 	// by creating and including one or more of these
 	"modules": [
-		"dojox/app/module/env",
-		"dojox/app/module/history",
-        "dojox/app/module/lifecycle"
+		//"dojox/app/module/env",
+        //"dojox/app/module/lifecycle"
 		//"dojox/app/module/phonegap",
 		//"dojox/app/module/somePlugin"
 	],
+	
+	"controllers": [
+		"dojox/app/controllers/History",
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],
 
 	//stores we are using 
 	"stores": {},
 
-	"template": "application.html",
+	"template": "./application.html",
 
 	//models and instantiation parameters for the models. Including 'type' as a property allows
 	//one to overide the class that will be used for the model.  By default it is dojox/mvc/model
@@ -43,125 +49,50 @@
 
 		//simple scene which loads all views and shows the default first
 		"home": { 
-			"type": "dojox.app.view",
 			"dependencies":["dojox/mobile/RoundRectList","dojox/mobile/ListItem", "dojox/mobile/EdgeToEdgeCategory"],
-			"template": "views/simple/home.html"
+			"template": "./templates/simple/home.html"
 		},
 
 		"main":{
 			//all views in the main scene will be bound to the user model
 			"models": [],
-			"type": "dojox.app.scene",
-			"template": "simple.html",	
+			"template": "./simple.html",
 			"defaultView": "main",
 			"defaultTransition": "slide",
 			//the views available to this scene
 			"views": { 
 				"main":{
-					"template": "views/simple/main.html"
+					"template": "./templates/simple/main.html"
 				},
 				"second":{
-					"template": "views/simple/second.html" 
+					"template": "./templates/simple/second.html"
 				},
 				"third":{
-					"template": "views/simple/third.html" 
+					"template": "./templates/simple/third.html"
 				}
 			},
-			"dependencies":["dojox/mobile/RoundRectList","dojox/mobile/ListItem","dojox/mobile/EdgeToEdgeCategory","dojox/mobile/EdgeToEdgeList"],
+			"dependencies":["dojox/mobile/RoundRectList","dojox/mobile/ListItem","dojox/mobile/EdgeToEdgeCategory","dojox/mobile/EdgeToEdgeList"]
 		},
 		//simple scene which loads all views and shows the default first
 		"tabscene": { 
 			//all views in the second scene will be bound to the user model
 			"models": [],
-			"template": "tabScene.html",	
+			"template": "./tabScene.html",
 			"defaultView": "tab1",
 			"defaultTransition": "flip",
-			"type": "dojox.app.scene",
 			//the views available to this scene
 			"views": { 
 				"tab1":{
-					"template": "views/tabs/tab1.html" 
+					"template": "./templates/tabs/tab1.html"
 				},
 				"tab2":{
-					"template": "views/tabs/tab2.html" 
+					"template": "./templates/tabs/tab2.html"
 				},
 				"tab3":{
-					"template": "views/tabs/tab3.html" 
+					"template": "./templates/tabs/tab3.html"
 				}
 			},
-			"dependencies":["dojox/mobile/RoundRectList","dojox/mobile/ListItem", "dojox/mobile/EdgeToEdgeCategory"],
-		},
-		//simple scene which loads all views and shows the default first
-		"gallery": { 
-			//all views in the main scene will be bound to the user model
-			"models": [],
-	
-			"defaultView": "welcome",
-			"defaultTransition": "flip",
-			"type": "dojox.app.scene",
-			"template": "gallery.html",
-			//the views available to this scene
-			"views": { 
-				"welcome": {
-					"template": "views/gallery/welcome.html"
-				},
-				"tabbar": {
-					"template": "views/gallery/tabbar.html"
-				},
-				"navigation": {
-					"template": "views/gallery/navigation.html"
-				},
-				"map": {
-					"template": "views/gallery/map.html"
-				},
-				"list": {
-					"template": "views/gallery/list.html"
-				},
-				"jsonp": {
-					"template": "views/gallery/jsonp.html"
-				},
-				"icons": {
-					"template": "views/gallery/icons.html"
-				},
-				"headings": {
-					"template": "views/gallery/headings.html"
-				},
-				"forms": {
-					"template": "views/gallery/forms.html"
-				},
-				"flippableViews": {
-					"template": "views/gallery/flippableViews.html"
-				},
-				"buttons": {
-					"type": "dojox.app.scene",
-					"template": "views/gallery/buttonScene.html",
-					"defaultView": "tab1",
-					"views": {
-						"tab1":{
-							"template": "views/gallery/buttons/tab1.html"
-						},
-						"tab2":{
-							"template": "views/gallery/buttons/tab2.html"
-						},
-						"tab3":{
-							"template": "views/gallery/buttons/tab3.html"
-						}
-					}
-				},
-				"animations": {
-					"template": "views/gallery/animations.html"
-				},
-				"ajaxLoad": {
-					"template": "views/gallery/ajaxLoad.html"
-				},
-				"ajax": {
-					"template": "views/gallery/ajax.html"
-				}
-			},
-
-			"dependencies": [
-				"dojox/mobile/Button"
-			]
+			"dependencies":["dojox/mobile/RoundRectList","dojox/mobile/ListItem", "dojox/mobile/EdgeToEdgeCategory"]
 		}
 	}	
 }
diff --git a/dojox/app/tests/multiSceneApp/gallery.html b/dojox/app/tests/multiSceneApp/gallery.html
deleted file mode 100644
index 57d8d51..0000000
--- a/dojox/app/tests/multiSceneApp/gallery.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<div style="background:#c5ccd3;" class="view simpleView"> 
-	<h1 region="top" dojoType="dojox.mobile.Heading"  >Mobile Widget Gallery</h1>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/index.html b/dojox/app/tests/multiSceneApp/index.html
index d7c0761..4f69271 100644
--- a/dojox/app/tests/multiSceneApp/index.html
+++ b/dojox/app/tests/multiSceneApp/index.html
@@ -3,16 +3,16 @@
 	<head>
 	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
 		<meta name="apple-mobile-web-app-capable" content="yes" /> 
-		<title>Multi Scene App Test</title> 
-		<link href="../../../mobile/themes/iphone/base.css" rel="stylesheet"></link> 
-		<link href="../../../mobile/themes/iphone/TabBar.css" rel="stylesheet"></link> 
-		<link href="../../../mobile/themes/iphone/IconContainer.css" rel="stylesheet"></link> 
-		<link href="../../../mobile/themes/iphone/Button.css" rel="stylesheet"></link> 
-		<link href="../../../mobile/themes/iphone/CheckBox.css" rel="stylesheet"></link> 
-		<link href="../../../mobile/themes/iphone/ComboBox.css" rel="stylesheet"></link> 
-		<link href="../../../mobile/themes/iphone/RadioButton.css" rel="stylesheet"></link> 
-		<link href="../../../mobile/themes/iphone/Slider.css" rel="stylesheet"></link> 
-		<link href="../../../mobile/themes/iphone/TabBar.css" rel="stylesheet"></link> 
+		<title>Multi Scene App Test</title>
+		<!-- TODO: check all these paths -->
+		<link href="../../../mobile/themes/iphone/base.css" rel="stylesheet">
+		<link href="../../../mobile/themes/iphone/TabBar.css" rel="stylesheet">
+		<link href="../../../mobile/themes/iphone/IconContainer.css" rel="stylesheet">
+		<link href="../../../mobile/themes/iphone/Button.css" rel="stylesheet">
+		<link href="../../../mobile/themes/iphone/CheckBox.css" rel="stylesheet">
+		<link href="../../../mobile/themes/iphone/ComboBox.css" rel="stylesheet">
+		<link href="../../../mobile/themes/iphone/RadioButton.css" rel="stylesheet">
+		<link href="../../../mobile/themes/iphone/Slider.css" rel="stylesheet">
 
 		<style>
 			html,body {
@@ -22,8 +22,8 @@
 				font-family: arial;
 				color: #333;
 				overflow: hidden;
-				margin: 0px;
-				padding: 0px;
+				margin: 0;
+				padding: 0;
 				visibility: visible;
 			}
 
@@ -33,7 +33,7 @@
 				margin: auto;
 				overflow: hidden;
 				border: 2px solid green;
-				font-color: #333;
+				color: #333;
 				text-align: center;
 			}
 
@@ -57,13 +57,14 @@
 					"loader-execModule-out":0,
 					"loader-defineModule":0
 				},
-				async:1
-			}
-			console.log("pre dojo");
+				async:1,
+				app: {debugApp: 1}  // set debugApp to log app transtions and view activate/deactivate 
+			};
+			//console.log("pre dojo");
 		</script>
 		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
 		<script>
-			console.log("post dojo");
+			//console.log("post dojo");
             // the actual  launcher
             require(["./multiSceneApp.js"], function(){});
 		</script>
diff --git a/dojox/app/tests/multiSceneApp/multiSceneApp.js b/dojox/app/tests/multiSceneApp/multiSceneApp.js
index a8f4214..8e81f64 100644
--- a/dojox/app/tests/multiSceneApp/multiSceneApp.js
+++ b/dojox/app/tests/multiSceneApp/multiSceneApp.js
@@ -1,15 +1,4 @@
-require(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/loader"], 
-function(dojo, lang, array){
-    var path = window.location.pathname;
-    if (path.charAt(path.length)!="/"){
-    	path = path.split("/");
-    	path.pop();
-    	path=path.join("/");	
-    }
-
-    dojo.registerModulePath("app",path);
-    require(["dojo/_base/html","dojox/app/main", "dojo/text!app/config.json"],
-	function(dojo,Application,config){
-    	app = Application(eval("(" + config + ")"));
-    });
+require(["dojox/app/main", "dojo/text!./config.json"],
+function(Application,config){
+	Application(eval("(" + config + ")"));
 });
diff --git a/dojox/app/tests/multiSceneApp/simple.html b/dojox/app/tests/multiSceneApp/simple.html
old mode 100644
new mode 100755
index 4e97f2c..0bc0075
--- a/dojox/app/tests/multiSceneApp/simple.html
+++ b/dojox/app/tests/multiSceneApp/simple.html
@@ -1,3 +1,3 @@
 <div style="background:#c5ccd3;" class="view simpleView"> 
-	<h1 region="top" dojoType="dojox.mobile.Heading"  >Main Scene</h1>
+	<h1 data-app-constraint="top" dojoType="dojox.mobile.Heading"  >Main Scene</h1>
 </div>
diff --git a/dojox/app/tests/multiSceneApp/tabScene.html b/dojox/app/tests/multiSceneApp/tabScene.html
old mode 100644
new mode 100755
index 2d49dfb..dc04871
--- a/dojox/app/tests/multiSceneApp/tabScene.html
+++ b/dojox/app/tests/multiSceneApp/tabScene.html
@@ -1,6 +1,6 @@
 <div  style="background:#c5ccd3;" class="view mblView"> 
-	<div region="top" dojoType="dojox.mobile.Heading">Tab Scene</div>
-	<ul region="top" dojoType="dojox.mobile.TabBar" barType="segmentedControl">
+	<div data-app-constraint="top" dojoType="dojox.mobile.Heading">Tab Scene</div>
+	<ul data-app-constraint="top" dojoType="dojox.mobile.TabBar" barType="segmentedControl">
 		<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-16.png" icon2="../images/tab-icon-16h.png" transitionOptions='{title:"TabScene-Tab1",target:"tabscene,tab1",url: "#tabscene,tab1"}' selected="true">Tab 1</li>
 		<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-15.png" icon2="../images/tab-icon-15h.png" transitionOptions='{title:"TabScene-Tab2",target:"tabscene,tab2",url: "#tabscene,tab2"}'>Tab 2</li>
 		<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-10.png" icon2="../images/tab-icon-10h.png" transitionOptions='{title:"TabScene-Tab3",target:"tabscene,tab3",url: "#tabscene,tab3"}'>Tab 3</li>
diff --git a/dojox/app/tests/multiSceneApp/views/simple/home.html b/dojox/app/tests/multiSceneApp/templates/simple/home.html
similarity index 100%
rename from dojox/app/tests/multiSceneApp/views/simple/home.html
rename to dojox/app/tests/multiSceneApp/templates/simple/home.html
diff --git a/dojox/app/tests/multiSceneApp/templates/simple/main.html b/dojox/app/tests/multiSceneApp/templates/simple/main.html
new file mode 100644
index 0000000..f83a41c
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/templates/simple/main.html
@@ -0,0 +1,27 @@
+<div style="background:#c5ccd3;width: 100%; height: 100%;"  class="view mblView"> 
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+	  This is the content of the main scene. Use the buttons in each scene to move between
+	  the multiple scenes, or views, contained in the app.
+	</div>
+	<ul dojoType="dojox.mobile.RoundRectList" iconBase="../images/i-icon-all.png">
+		<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Main Scene Views</h2>
+
+		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" clickable="false">
+			Main Scene::Main View (Current View)
+		</li>
+		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29"  clickable="true" transitionOptions='{title:"Main Scene::SecondView",target:"main,second",url: "#main,second"}'>
+			Main Scene::Second View
+		</li>
+		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29"  clickable="true" transitionOptions='{title:"Main Scene::ThirdView",target:"main,third",url: "#main,third"}'>
+			Main Scene::Third View
+		</li>
+	</ul>
+
+	<ul dojoType="dojox.mobile.RoundRectList" iconBase="../images/i-icon-all.png">
+		<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Tab Scene Views</h2>
+		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
+			clickable="true" transitionOptions='{title:"TabScene - Tab1",target:"tabscene,tab1",url: "#tabscene,tab1"}'>
+			Tab Scene	
+		</li>
+	</ul>
+</div>
diff --git a/dojox/app/tests/multiSceneApp/templates/simple/second.html b/dojox/app/tests/multiSceneApp/templates/simple/second.html
new file mode 100644
index 0000000..bb767fb
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/templates/simple/second.html
@@ -0,0 +1,12 @@
+<div  style="background:#c5ccd3;" class="view mblView"> 
+	<div dojoType="dojox.mobile.Heading" data-dojo-props='back:"Back"'>View simple/second</div>
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		<a href="#main,main">to main,main</a><br>
+		<a href="#main,second">to main,second</a><br>
+		<a href="#main,third">to main,third</a><br>
+	</div>
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		<a href="#tabscene,tab2">to tabscene,tab2</a><br>
+	</div>
+
+</div>
diff --git a/dojox/app/tests/multiSceneApp/templates/simple/third.html b/dojox/app/tests/multiSceneApp/templates/simple/third.html
new file mode 100644
index 0000000..4939fa3
--- /dev/null
+++ b/dojox/app/tests/multiSceneApp/templates/simple/third.html
@@ -0,0 +1,38 @@
+<div style="background:#c5ccd3;"  class="view mblView" scrollable="true"> 
+	<div dojoType="dojox.mobile.Heading" data-dojo-props='back:"Back"'>View simple/second</div>
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		  simple/third View. 
+	</div>
+
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+	<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Single Select</h2>
+		<ul dojoType="dojox.mobile.EdgeToEdgeList" select="single">
+			<li dojoType="dojox.mobile.ListItem" checked="true">
+				Cube
+			</li>
+				<li dojoType="dojox.mobile.ListItem">
+				Dissolve
+			</li>
+			<li dojoType="dojox.mobile.ListItem">
+				Ripple
+			</li>
+		</ul>
+	</div>
+
+	<div dojoType="dojox.mobile.RoundRect" shadow="true">
+		<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Multiple Select</h2>
+		<ul dojoType="dojox.mobile.EdgeToEdgeList" select="multiple">
+			<li dojoType="dojox.mobile.ListItem" checked="true">
+				Cube
+			</li>
+			<li dojoType="dojox.mobile.ListItem">
+				Dissolve
+			</li>
+			<li dojoType="dojox.mobile.ListItem">
+				Ripple
+			</li>
+		</ul>
+
+	</div>	
+
+</div>
diff --git a/dojox/app/tests/multiSceneApp/views/tabs/tab1.html b/dojox/app/tests/multiSceneApp/templates/tabs/tab1.html
similarity index 100%
rename from dojox/app/tests/multiSceneApp/views/tabs/tab1.html
rename to dojox/app/tests/multiSceneApp/templates/tabs/tab1.html
diff --git a/dojox/app/tests/multiSceneApp/views/tabs/tab2.html b/dojox/app/tests/multiSceneApp/templates/tabs/tab2.html
similarity index 100%
rename from dojox/app/tests/multiSceneApp/views/tabs/tab2.html
rename to dojox/app/tests/multiSceneApp/templates/tabs/tab2.html
diff --git a/dojox/app/tests/multiSceneApp/views/tabs/tab3.html b/dojox/app/tests/multiSceneApp/templates/tabs/tab3.html
similarity index 100%
rename from dojox/app/tests/multiSceneApp/views/tabs/tab3.html
rename to dojox/app/tests/multiSceneApp/templates/tabs/tab3.html
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/ajax.html b/dojox/app/tests/multiSceneApp/views/gallery/ajax.html
deleted file mode 100644
index 61799df..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/ajax.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<div class="view mblView" >
-	<div dojoType="dojox.mobile.Heading" style="text-align:left;">
-		<button dojoType="dojox.mobile.Button" class="greyBtn headingBtn"
-		onclick="demo.ajax.refreshData();">
-		Load using AJAX</button>
-	</div>
-	<div dojoType="dojox.mobile.ScrollableView" selected="true">
-		<pre id="ajaxPane" style="white-space:pre-wrap;"></pre>
-	</div>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/ajaxLoad.html b/dojox/app/tests/multiSceneApp/views/gallery/ajaxLoad.html
deleted file mode 100644
index 8326af1..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/ajaxLoad.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<div style="text-align:center;vertical-align:middle;">
-	<div style="font-weight:bold;font-size:24px;">I'm using Dojo.</div>
-	<div style="display:table;width:100%;">
-		<img src="./images/dojoLogo.png" style="margin:0 auto;"/>
-	</div>
-	<a href="http://dojotoolkit.org" style="display:block;">Visit us</a>
-</div>
\ No newline at end of file
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/animations.html b/dojox/app/tests/multiSceneApp/views/gallery/animations.html
deleted file mode 100644
index 60c9e82..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/animations.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<div class="view mblView>
-	<div id="animationView1" dojoType="dojox.mobile.ScrollableView" selected="true">
-		<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-		<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-			<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29"
-				moveTo="animationView2" transition="slide">Slide</li>
-			<li dojoType="dojox.mobile.ListItem" iconPos="0,29,29,29"
-				moveTo="animationView2" transition="flip">Flip</li>
-			<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29"
-				moveTo="animationView2" transition="fade">Fade</li>
-		</ul>
-	</div>
-	<div id="animationView2" dojoType="dojox.mobile.ScrollableView">
-		<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-		<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png" style="background-color:#FFEBB5;">
-			<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29"
-				moveTo="animationView1" transition="slide">Slide</li>
-			<li dojoType="dojox.mobile.ListItem" iconPos="0,29,29,29"
-				moveTo="animationView1" transition="flip">Flip</li>
-			<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29"
-				moveTo="animationView1" transition="fade">Fade</li>
-		</ul>
-	</div>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/buttonScene.html b/dojox/app/tests/multiSceneApp/views/gallery/buttonScene.html
deleted file mode 100644
index 2d5b1ac..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/buttonScene.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<div  style="background:#c5ccd3;" class="view mblView"> 
-	<div region="top" dojoType="dojox.mobile.Heading">Button Gallery</div>
-	<ul region="top" dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" href="#gallery,buttons,tab1" selected="true">Tab 1</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" href="#gallery,buttons,tab2">Tab 2</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" href="#gallery,buttons,tab3">Tab 3</li>
-	</ul>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab1.html b/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab1.html
deleted file mode 100644
index 453c2dd..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab1.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<div class="mblView">
-	<div dojoType="dojox.mobile.RoundRect" shadow="true">
-		<button dojoType="dojox.mobile.Button" class="baseBtn whiteBtn" style="width: 240px;">White</button>
-		<button dojoType="dojox.mobile.Button" class="baseBtn navyBtn" style="width: 240px;">Blue</button>
-		<button dojoType="dojox.mobile.Button" class="baseBtn orangeBtn" style="width: 240px;">Orange</button>
-		<button dojoType="dojox.mobile.Button" class="baseBtn redBtn" style="width: 240px;">Red</button>
-		<button dojoType="dojox.mobile.Button" class="baseBtn blackBtn" style="width: 240px;">Black</button>        
-	</div>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab2.html b/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab2.html
deleted file mode 100644
index e3dbd88..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab2.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<div class="mblView">
-	<div dojoType="dojox.mobile.RoundRect" shadow="true">
-		<button dojoType="dojox.mobile.Button" class="baseBtn navyBtn" style="width: 240px;">Matte</button>
-		<button dojoType="dojox.mobile.Button" class="baseBtn glossy navyBtn" style="width: 240px;">Glossy</button>
-		<button dojoType="dojox.mobile.Button" class="baseBtn candy navyBtn" style="width: 240px;">Candy</button>
-		<button dojoType="dojox.mobile.Button" class="baseBtn shadow navyBtn" style="width: 240px;">Shadow</button>			
-	</div>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab3.html b/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab3.html
deleted file mode 100644
index d205a80..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/buttons/tab3.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<div class="mblView">
-	<div dojoType="dojox.mobile.RoundRect" shadow="true">
-		<button dojoType="dojox.mobile.Button" class="baseBtn backBtn greyBtn" style="width: 240px;">Back</button>
-		<button dojoType="dojox.mobile.Button" class="baseBtn roundBtn navyBtn" style="width: 240px;">Round</button>
-	</div>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/flippableViews.html b/dojox/app/tests/multiSceneApp/views/gallery/flippableViews.html
deleted file mode 100644
index ea1ddda..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/flippableViews.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<div>
-<div id="flippableView" dojoType="dojox.mobile.ScrollableView">
-<div id="flippableView1" dojoType="dojox.mobile.FlippableView" style="background-color:#EEE" selected="true">
-<div style="text-align:center; vertical-align:middle; position:relative; top: 10%"><img src="images/flip1.jpg" style="height: 60%"></img>
-<h3>Page 1/3</h3>
-</div>
-</div>
-<div id="flippableView2" dojoType="dojox.mobile.FlippableView" style="background-color:#5E99CC">
-<div style="text-align:center; vertical-align:middle; position:relative; top: 10%"><img src="images/flip2.jpg" style="height: 60%"></img>
-<h3>Page 2/3</h3>
-</div>
-</div>
-<div id="flippableView3" dojoType="dojox.mobile.FlippableView" style="background-color:#759E60">
-<div style="text-align:center; vertical-align:middle; position:relative; top: 10%"><img src="images/flip3.jpg" style="height: 60%"></img>
-<h3 style="text-align:center; vertical-align:middle">Page 3/3</h3>
-</div>
-</div>
-</div>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/forms.html b/dojox/app/tests/multiSceneApp/views/gallery/forms.html
deleted file mode 100644
index ac914a1..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/forms.html
+++ /dev/null
@@ -1,110 +0,0 @@
-<div id="forms" 
-	style="width: 100%;">
-	<form name="testForm" id="testForm">
-		<div class="field-title">Personal Data</div>
-		<div class="fieldset">
-			<div class="field-row">
-				<span>Full name</span>
-				<input id="forms_name" dojoType="dojox.mobile.TextBox" selectOnClick="true" value="Luke" type=text name="name"></input>
-			</div>
-			 <!--div class="field-row">
-                <span>Title</span>
-                <select name="title" id="titlelist">
-                    <option value="1">Mr.</option>
-                    <option value="0">Mrs.</option>
-					<option value="0">Ms.</option>
-					<option value="0">Miss</option>
-					<option value="0">Dr.</option>
-                </select>
-				<input id="titlecombo"></input>
-            </div>
-			<div class="field-row">
-                <span>Phone</span>
-                <input type=tel name="tel">
-                </input>
-            </div>
-            <div class="field-row">
-                <span>Email</span>
-                <input type=email name="email" multiple placeholder="me at dojotoolkit.org">
-                </input>
-            </div>
-            <div class="field-row">
-                <span>Website</span>
-                <input type=url name="url" placeholder="http://dojotoolkit.org">
-                </input>
-            </div>
-            <div class="field-row">
-                <span style="vertical-align:top;">Birthdate</span>
-                <div id="birthdate" dojoType="dojox.mobile.SpinWheelDatePicker" style="display:inline-block;"></div>
-            </div>
-			<div class="field-row">
-                <span>Hide birthdate</span>
-                <input type=checkbox dojoType="dojox.mobile.CheckBox" name="hidebirth" checked style="margin-left:0px;">
-                </input>
-            </div-->
-			<div class="field-row">
-                <span style="vertical-align:top;">Goals</span>
-                <textarea name="goals" dojoType="dojox.mobile.TextArea" maxLength="100" cols="20"></textarea>
-            </div>
-		</div>
-		
-		<div class="field-title">
-            Login
-        </div>
-		<div class="fieldset">
-            <div class="field-row">
-                <span>User name*</span>
-                <input type=text dojoType="dojox.mobile.TextBox" name="username" required>
-                </input>
-            </div>
-            <div class="field-row">
-                <span>Password*</span>
-                <input type=password name="pass" dojoType="dojox.mobile.TextBox">
-                </input>
-            </div>
-            <!--div class="field-row">
-                <span>Login retries</span>
-                <input type=number name="retries" value="3">
-                </input>
-            </div-->
-        </div>
-		
-        <div class="field-title">
-            Alerts
-        </div>
-        <div class="fieldset">
-            <span>Issue alerts for:</span>
-            <br/>
-            <div class="field-row">
-                <span>All messages</span>
-                <input type=radio name="forwardtype" dojoType="dojox.mobile.RadioButton" value="all">
-                </input>
-            </div>
-            <div class="field-row">
-                <span>Urgent messages only</span>
-                <input type=radio name="forwardtype" dojoType="dojox.mobile.RadioButton" checked="true" value="urgent">
-                </input>
-            </div>
-            <div class="field-row">
-                <span style="vertical-align:top;">Audible alerts:</span>
-                <div dojoType="dojox.mobile.Switch" value="off" style="display:-moz-inline-box;display:inline-block;">
-                </div>
-            </div>
-			<div class="field-row">
-	            <span>Alert volume</span>
-			</div>
-		    <input id="alertSlider" dojoType="dojox.mobile.Slider" name="alertvolume" min="0" max="100" value="0" style="width:50%;">
-            </input>
-            <!--div class="field-row">
-                <span>Forward to</span>
-                <input type=search results=10>
-                </input>
-            </div-->
-        </div>
-        <div style="text-align: center;">
-            <button type=reset dojotype="dojox.mobile.Button" class="mblButton greyBtn baseBtn normalBtn" onclick="dojo.byId('testForm').reset();">
-                Reset Form
-            </button>
-        </div>
-    </form>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/headings.html b/dojox/app/tests/multiSceneApp/views/gallery/headings.html
deleted file mode 100644
index 9a59b1c..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/headings.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<div > 
-	<h1 dojoType="dojox.mobile.Heading">
-		<div  dojoType="dojox.mobile.ToolBarButton">Default</div>
-		<div dojoType="dojox.mobile.ToolBarButton" class="roundBtn mblColorBlue">Round</div>
-		<div dojoType="dojox.mobile.ToolBarButton" toggle="true">Toggle Button</div>
-    </h1>
-    <h1 dojoType="dojox.mobile.Heading">
-		<ul  dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-			<li dojoType="dojox.mobile.TabBarButton">New</li>
-			<li dojoType="dojox.mobile.TabBarButton">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton">Genius</li>
-		</ul>
-	</h1>
-	<h1 dojoType="dojox.mobile.Heading">
-
-		<button dojoType="dojox.mobile.Button" class="baseBtn defaultBtn backBtn">Back</button>
-		
-		<div dojoType="dojox.mobile.ToolBarButton" icon="images/a-icon-12.png"></div> 
-		<div ></div> 
-		<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButton mblDomButtonPlus_2" style="float:right;"></div>
-	</h1>
-	<div style="text-align:center;">Pick up a button, any button.</div>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/icons.html b/dojox/app/tests/multiSceneApp/views/gallery/icons.html
deleted file mode 100644
index 5dc8b26..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/icons.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<div >
-	<ul dojoType="dojox.mobile.IconContainer">
-		<li dojoType="dojox.mobile.IconItem" label="Expand" icon="images/icon-1.png" lazy="true">
-			<div class="box">
-				Click the close icon on the left top corner to close this box.
-			</div>
-		</li>
-		<li dojoType="dojox.mobile.IconItem" label="moveTo" icon="images/icon-1.png" moveTo="icons-moveTo" transition="slide"></li> 
-		<li dojoType="dojox.mobile.IconItem" label="url" icon="images/icon-1.png" url="icons-url.html" transition="slide"></li>
-	</ul>
-</div>
-<div id="icons-moveTo" dojoType="dojox.mobile.View"> 
-	<h1 dojoType="dojox.mobile.Heading" back="Icons" moveTo="icons">Move To</h1> 
-	<h2 dojoType="dojox.mobile.RoundRectCategory">About</h2> 
-	<pre>
-	You can click "Icons" back button to go back to "Icons" view. 
-	</pre> 
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/jsonp.html b/dojox/app/tests/multiSceneApp/views/gallery/jsonp.html
deleted file mode 100644
index 95d0add..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/jsonp.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<div>
-	<div dojoType="dojox.mobile.Heading" style="text-align:left;">
-		<button dojoType="dojox.mobile.Button" class="greyBtn headingBtn"
-		onclick="demo.jsonp.refreshData();">
-		Load using JSON-P</button>
-	</div>
-	<div dojoType="dojox.mobile.ScrollableView" selected="true">
-		<div id="searchResults" style="display:none;"></div>
-	</div>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/list.html b/dojox/app/tests/multiSceneApp/views/gallery/list.html
deleted file mode 100644
index 76d3cdb..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/list.html
+++ /dev/null
@@ -1,143 +0,0 @@
-<div class="view mblView">
-    <ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-        <li dojoType="dojox.mobile.TabBarButton" moveTo="roundRectList" selected="true" transition="slide">RoundRectList</li>
-        <li dojoType="dojox.mobile.TabBarButton" moveTo="edgeToEdgeList" transition="slide">EdgeToEdgeList</li>
-    </ul>
-    <div dojoType="dojox.mobile.View" selected="true">
-		<div dojoType="dojox.mobile.ScrollableView" selected="true">
-            <h2 dojoType="dojox.mobile.RoundRectCategory">File Genres</h2>
-			<div dojoType="dojox.mobile.RoundRect" style="width:280px;">
-			    <div dojoType="dojox.mobile.RoundRectList">
-			        <li dojoType="dojox.mobile.ListItem"
-			            moveTo="slide1" transition="slide">Action</li>
-			        <li dojoType="dojox.mobile.ListItem"
-			            moveTo="flip1" transition="slide">Comedy</li>
-                    <li dojoType="dojox.mobile.ListItem"
-                        moveTo="fade1" transition="slide">Sci-Fi</li>
-			    </div>
-			</div>
-		</div>
-		<div dojoType="dojox.mobile.ScrollableView" >
-                <h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Classical</h2>
-			    <div dojoType="dojox.mobile.EdgeToEdgeList">
-			        <li dojoType="dojox.mobile.ListItem"
-                        moveTo="baroque">Baroque</li>
-			        <li dojoType="dojox.mobile.ListItem"
-                        moveTo="romantic">Romantic</li>
-			        <li dojoType="dojox.mobile.ListItem"
-                        moveTo="modern">Modern</li>
-			    </div>
-                <h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Rock</h2>
-                <div dojoType="dojox.mobile.EdgeToEdgeList">
-                    <li dojoType="dojox.mobile.ListItem"
-                        moveTo="alternative">Alternative</li>
-                    <li dojoType="dojox.mobile.ListItem"
-                        moveTo="metal">Metal</li>
-                    <li dojoType="dojox.mobile.ListItem"
-                        moveTo="progressive">Progressive</li>
-                    <li dojoType="dojox.mobile.ListItem"
-                        moveTo="randb">R&B</li>
-                </div>
-		</div>
-		<div dojoType="dojox.mobile.ScrollableView">
-	        <h1 dojoType="dojox.mobile.Heading"  back="Back" moveTo="roundRectList">Action Movies</h1>
-	        <div dojoType="dojox.mobile.RoundRect" style="width:280px;">
-                <div dojoType="dojox.mobile.RoundRectList">
-                    <li dojoType="dojox.mobile.ListItem">Braveheart</li>
-                    <li dojoType="dojox.mobile.ListItem">Hellboy</li>
-                    <li dojoType="dojox.mobile.ListItem">Iron Man</li>
-                    <li dojoType="dojox.mobile.ListItem">Kill Bill</li>
-                    <li dojoType="dojox.mobile.ListItem">Rambo</li>
-                    <li dojoType="dojox.mobile.ListItem">Spider Man</li>
-                    <li dojoType="dojox.mobile.ListItem">Terminator</li>
-                    <li dojoType="dojox.mobile.ListItem">The Dark Knight</li>
-                    <li dojoType="dojox.mobile.ListItem">Transformers</li>
-                    <li dojoType="dojox.mobile.ListItem">True Lies</li>
-                </div>
-            </div>
-	    </div>
-	    <div dojoType="dojox.mobile.ScrollableView">
-	        <h1 dojoType="dojox.mobile.Heading"  back="Back" moveTo="roundRectList">Comedy Movies</h1>
-	        <div dojoType="dojox.mobile.RoundRect" style="width:280px;">
-                <div dojoType="dojox.mobile.RoundRectList">
-                    <li dojoType="dojox.mobile.ListItem">Ace Ventura</li>
-                    <li dojoType="dojox.mobile.ListItem">Pineapple Express</li>
-                    <li dojoType="dojox.mobile.ListItem">Shrek</li>
-                    <li dojoType="dojox.mobile.ListItem">Superbad</li>
-                    <li dojoType="dojox.mobile.ListItem">The Simpsons Movie</li>
-                </div>
-            </div>
-	    </div>
-	    <div dojoType="dojox.mobile.ScrollableView">
-	        <h1 dojoType="dojox.mobile.Heading"  back="Back" moveTo="roundRectList">Sci-Fi Movies</h1>
-	        <div dojoType="dojox.mobile.RoundRect" style="width:280px;">
-                <div dojoType="dojox.mobile.RoundRectList">
-                    <li dojoType="dojox.mobile.ListItem">Alien</li>
-                    <li dojoType="dojox.mobile.ListItem">Avatar</li>
-                    <li dojoType="dojox.mobile.ListItem">Back to the Future</li>
-                    <li dojoType="dojox.mobile.ListItem">Blade Runner</li>
-                    <li dojoType="dojox.mobile.ListItem">District 9</li>
-                    <li dojoType="dojox.mobile.ListItem">Inception</li>
-                    <li dojoType="dojox.mobile.ListItem">Star Wars</li>
-                    <li dojoType="dojox.mobile.ListItem">The Matrix</li>
-                </div>
-            </div>
-	    </div>
-        <div dojoType="dojox.mobile.ScrollableView">
-            <h1 dojoType="dojox.mobile.Heading"  back="Back" moveTo="edgeToEdgeList">Baroque</h1>
-            <div dojoType="dojox.mobile.EdgeToEdgeList">
-                <li dojoType="dojox.mobile.ListItem">Antonio Vivaldi</li>
-                <li dojoType="dojox.mobile.ListItem">Henry Purcell</li>
-                <li dojoType="dojox.mobile.ListItem">Johann Sebastian Bach</li>
-            </div>
-        </div>
-        <div dojoType="dojox.mobile.ScrollableView">
-            <h1 dojoType="dojox.mobile.Heading"  back="Back" moveTo="edgeToEdgeList">Romantic</h1>
-            <div dojoType="dojox.mobile.EdgeToEdgeList">
-                <li dojoType="dojox.mobile.ListItem">Ludwig van Beethoven</li>
-                <li dojoType="dojox.mobile.ListItem">Hector Berlioz</li>
-                <li dojoType="dojox.mobile.ListItem">Modest Petrovich</li>
-                <li dojoType="dojox.mobile.ListItem">Mussorgsky</li>
-            </div>
-        </div>
-        <div dojoType="dojox.mobile.ScrollableView">
-            <h1 dojoType="dojox.mobile.Heading"  back="Back" moveTo="edgeToEdgeList">Modern</h1>
-            <div dojoType="dojox.mobile.EdgeToEdgeList">
-                <li dojoType="dojox.mobile.ListItem">Aaron Copeland</li>
-                <li dojoType="dojox.mobile.ListItem">Igor Stravinksy</li>
-                <li dojoType="dojox.mobile.ListItem">Philip Glass</li>
-            </div>
-        </div>
-        <div dojoType="dojox.mobile.ScrollableView">
-            <h1 dojoType="dojox.mobile.Heading"  back="Back" moveTo="edgeToEdgeList">Alternative</h1>
-            <div dojoType="dojox.mobile.EdgeToEdgeList">
-                <li dojoType="dojox.mobile.ListItem">Nirvana</li>
-                <li dojoType="dojox.mobile.ListItem">R.E.M.</li>
-                <li dojoType="dojox.mobile.ListItem">The White Stripes</li>
-            </div>
-        </div>
-        <div dojoType="dojox.mobile.ScrollableView">
-            <h1 dojoType="dojox.mobile.Heading"  back="Back" moveTo="edgeToEdgeList">Metal</h1>
-            <div dojoType="dojox.mobile.EdgeToEdgeList">
-                <li dojoType="dojox.mobile.ListItem">Led Zeppelin</li>
-                <li dojoType="dojox.mobile.ListItem">Metalica</li>
-            </div>
-        </div>
-        <div dojoType="dojox.mobile.ScrollableView">
-            <h1 dojoType="dojox.mobile.Heading"  back="Back" moveTo="edgeToEdgeList">Progressive</h1>
-            <div dojoType="dojox.mobile.EdgeToEdgeList">
-                <li dojoType="dojox.mobile.ListItem">King Crimson</li>
-                <li dojoType="dojox.mobile.ListItem">Pink Floyd</li>
-                <li dojoType="dojox.mobile.ListItem">Yes</li>
-            </div>
-        </div>
-        <div dojoType="dojox.mobile.ScrollableView">
-            <h1 dojoType="dojox.mobile.Heading"  back="Back" moveTo="edgeToEdgeList">R&B</h1>
-            <div dojoType="dojox.mobile.EdgeToEdgeList">
-                <li dojoType="dojox.mobile.ListItem">Chuck Berry</li>
-                <li dojoType="dojox.mobile.ListItem">Elvis Presley</li>
-                <li dojoType="dojox.mobile.ListItem">Sam  Cooke</li>
-            </div>
-        </div>
-    </div>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/map.html b/dojox/app/tests/multiSceneApp/views/gallery/map.html
deleted file mode 100644
index eb2f526..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/map.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div class="view mblView">
-<div id="map" style="height:100%;">
-	<div id="googleMap" style="width:100% !important;height:100% !important;"></div>
-</div>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/navigation.html b/dojox/app/tests/multiSceneApp/views/gallery/navigation.html
deleted file mode 100644
index c2999b3..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/navigation.html
+++ /dev/null
@@ -1,51 +0,0 @@
-<div>
-	<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Controls</h2>
-	<ul dojoType="dojox.mobile.EdgeToEdgeList" iconBase="images/list/navigation_list_all_29.png">
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29"
-			moveTo="buttons">Buttons<sup>1.6</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29"
-			moveTo="forms">Forms<sup>1.6</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29"
-			href="../mvcMobile/demo.html" hrefTarget="_blank">Forms Data<sup>1.7</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29"
-			href="../../dojox/mobile/tests/test_iPhone-Switch.html" hrefTarget="_blank">Switches<sup>1.7</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="58,0,29,29"
-			moveTo="flippableView">Flippable<sup>1.6</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="87,0,29,29"
-			moveTo="icons">Icons<sup>1.6</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="116,0,29,29"
-			moveTo="tabBar">Tab Bar<sup>1.6</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="145,0,29,29"
-			moveTo="headings">Headings<sup>1.6</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="174,0,29,29"
-			moveTo="map">Map (Google)<sup>1.6</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="174,0,29,29"
-			href="../mobileOpenLayers/demos.html" hrefTarget="_blank">Maps<sup>1.7</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="203,0,29,29"
-			moveTo="list">List<sup>1.6</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="203,0,29,29"
-			href="../../dojox/mobile/tests/test_RoundRectDataList.html" hrefTarget="_blank">List Data<sup>1.7</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="377,0,29,29"
-			href="../mobileCharting/demo.html" hrefTarget="_blank">Charts<sup>1.7</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="232,0,29,29"
-			href="../mobileGauges/demo.html" hrefTarget="_blank">Gauges<sup>1.7</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="261,0,29,29"
-			href="../../touch/demos/touch/demo.html" hrefTarget="_blank">Touch Layer<sup>1.7</sup></li>
-	</ul>
-	<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Effects</h2>
-	<ul dojoType="dojox.mobile.EdgeToEdgeList" iconBase="images/list/navigation_list_all_29.png">
-		<li dojoType="dojox.mobile.ListItem" iconPos="290,0,29,29"
-			moveTo="animations">Transitions<sup>1.6</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="290,0,29,29"
-			href="../../dojox/mobile/tests/test_transition-animations.html" hrefTarget="_blank">Transitions<sup>1.7</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="406,0,29,29"
-			href="../css3/demo.html" hrefTarget="_blank">CSS3 Effects<sup>1.6</sup></li>
-	</ul>
-	<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Data</h2>
-	<ul dojoType="dojox.mobile.EdgeToEdgeList" iconBase="images/list/navigation_list_all_29.png">
-		<li dojoType="dojox.mobile.ListItem" iconPos="319,0,29,29"
-			moveTo="jsonp">JSON P<sup>1.6</sup></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="348,0,29,29"
-			moveTo="ajax">AJAX<sup>1.6</sup></li>
-	</ul>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/rowTemplate.html b/dojox/app/tests/multiSceneApp/views/gallery/rowTemplate.html
deleted file mode 100644
index 89b9b1c..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/rowTemplate.html
+++ /dev/null
@@ -1 +0,0 @@
-<div class="row"><strong>${firstName}</strong> ${lastName}</div>
\ No newline at end of file
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/tabbar.html b/dojox/app/tests/multiSceneApp/views/gallery/tabbar.html
deleted file mode 100644
index 0812865..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/tabbar.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<div class="view mblView"> 
-	<h2>Here is the Tab Bar. You can put it in any place.</h2>
-	<div> 
-		<div class="label">
-			<div dojoType="dojox.mobile.View" selected="true">
-				<div class="tabContent"><span>You can place the tab bar content view in any place.</span></div> 
-			</div>
-			<div  dojoType="dojox.mobile.View"> 
-				<div class="tabContent"><span>Tab 1</span></div> 
-			</div> 
-			<div  dojoType="dojox.mobile.View"> 
-				<div class="tabContent"><span>Tab 2</span></div> 
-			</div> 
-			<div dojoType="dojox.mobile.View"> 
-				<div class="tabContent"><span>Tab 3</span></div> 
-			</div>
-		</div>
-		<ul dojoType="dojox.mobile.TabBar" single="true" iconBase="images/tab/toolbar_all_30.png">
-			<li dojotype="dojox.mobile.TabBarButton" moveTo="tabView1" iconPos1="0,0,30,30"
-				iconPos2="30,0,30,30"/>
-			<li dojotype="dojox.mobile.TabBarButton" moveTo="tabView2" iconPos1="60,0,30,30"
-				iconPos2="90,0,30,30"/>
-			<li dojotype="dojox.mobile.TabBarButton" moveTo="tabView3" iconPos1="120,0,30,30"
-				iconPos2="150,0,30,30"/>
-		</ul>
-	</div>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/gallery/welcome.html b/dojox/app/tests/multiSceneApp/views/gallery/welcome.html
deleted file mode 100644
index b591b23..0000000
--- a/dojox/app/tests/multiSceneApp/views/gallery/welcome.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div class="view mblView">
-    <h1 dojoType="dojox.mobile.RoundRectCategory" style="text-align:center;vertical-align:middle;margin-left:0px;padding-left:0px"><div>Welcome to Dojo Mobile Showcase</div>
-    <img src="images/welcomeLogo.png"/>
-    </h1>
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/simple/main.html b/dojox/app/tests/multiSceneApp/views/simple/main.html
deleted file mode 100644
index a8b1235..0000000
--- a/dojox/app/tests/multiSceneApp/views/simple/main.html
+++ /dev/null
@@ -1,92 +0,0 @@
-<div style="background:#c5ccd3;width: 100%; height: 100%;"  class="view mblView"> 
-	<div dojoType="dojox.mobile.RoundRect" shadow="true">
-	  This is the content of the main scene. Use the buttons in each scene to move between
-	  the multiple scenes, or views, contained in the app.
-	</div>
-	<ul dojoType="dojox.mobile.RoundRectList" iconBase="../images/i-icon-all.png">
-		<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Main Scene Views</h2>
-
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" clickable="false">
-			Main Scene::Main View (Current View)
-		</li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29"  clickable="true" transitionOptions='{title:"Main Scene::SecondView",target:"main,second",url: "#main,second"}'>
-			Main Scene::Second View
-		</li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29"  clickable="true" transitionOptions='{title:"Main Scene::ThirdView",target:"main,third",url: "#main,third"}'>
-			Main Scene::Third View
-		</li>
-	</ul>
-
-	<ul dojoType="dojox.mobile.RoundRectList" iconBase="../images/i-icon-all.png">
-		<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Tab Scene Views</h2>
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" transitionOptions='{title:"TabScene - Tab1",target:"tabscene,tab1",url: "#tabscene,tab1"}'>
-			Tab Scene	
-		</li>
-	</ul>
-	<!--
-	<ul dojoType="dojox.mobile.RoundRectList" iconBase="../images/i-icon-all.png">
-		<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Gallery Views</h2>
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery">
-			Mobile Gallery
-		</li>
-
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,welcome">
-			Welcome
-		</li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,tabbar">
-			Tab Bar
-		</li>
-
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,map">
-			Map
-		</li>
-
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,list">
-			List
-		</li>
-
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,jsonp">
-			Jsonp
-		</li>
-
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,icons">
-			Icons
-		</li>
-
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,headings">
-			Headings
-		</li>
-
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,forms">
-			Forms
-		</li>
-
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,flippableViews">
-			Flippable Views
-		</li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,buttons">
-			Buttons
-		</li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,ajax">
-			Ajax
-		</li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" 
-			clickable="true" href="#gallery,ajaxLoad">
-			Ajax Load
-		</li>
-	</ul>
-	-->
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/simple/second.html b/dojox/app/tests/multiSceneApp/views/simple/second.html
deleted file mode 100644
index 08429f5..0000000
--- a/dojox/app/tests/multiSceneApp/views/simple/second.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<div  style="background:#c5ccd3;" class="view mblView"> 
-	<div dojoType="dojox.mobile.Heading" back="back">View simple/second</div>
-	<div dojoType="dojox.mobile.RoundRect" shadow="true">
-		<a href="#main,main">to main,main</a><br>
-		<a href="#main,second">to main,second</a><br>
-		<a href="#main,third">to main,third</a><br>
-	</div>
-	<div dojoType="dojox.mobile.RoundRect" shadow="true">
-		<a href="#tabscene,tab2">to tabscene,tab2</a><br>
-		<!--<a transitionOptions='{title:"Gallery Welcome",target:"gallery,welcome",url: "#tabscene,tab1"}'>to galler,welcome</a>
-	</div>
-
-</div>
diff --git a/dojox/app/tests/multiSceneApp/views/simple/third.html b/dojox/app/tests/multiSceneApp/views/simple/third.html
deleted file mode 100644
index 7d84ff4..0000000
--- a/dojox/app/tests/multiSceneApp/views/simple/third.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<div style="background:#c5ccd3;"  class="view mblView" scrollable="true"> 
-	<div dojoType="dojox.mobile.Heading" back="back">View simple/second</div>
-	<div dojoType="dojox.mobile.RoundRect" shadow="true">
-		  simple/third View. 
-	</div>
-
-	<div dojoType="dojox.mobile.RoundRect" shadow="true">
-	<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Single Select</h2>
-		<ul dojoType="dojox.mobile.EdgeToEdgeList" select="single">
-			<li dojoType="dojox.mobile.ListItem" checked="true">
-				Cube
-			</li>
-				<li dojoType="dojox.mobile.ListItem">
-				Dissolve
-			</li>
-			<li dojoType="dojox.mobile.ListItem">
-				Ripple
-			</li>
-		</ul>
-	</div>
-
-	<div dojoType="dojox.mobile.RoundRect" shadow="true">
-		<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Multiple Select</h2>
-		<ul dojoType="dojox.mobile.EdgeToEdgeList" select="multiple">
-			<li dojoType="dojox.mobile.ListItem" checked="true">
-				Cube
-			</li>
-			<li dojoType="dojox.mobile.ListItem">
-				Dissolve
-			</li>
-			<li dojoType="dojox.mobile.ListItem">
-				Ripple
-			</li>
-		</ul>
-
-	</div>	
-
-</div>
diff --git a/dojox/app/tests/scrollableTestApp/config.json b/dojox/app/tests/scrollableTestApp/config.json
new file mode 100644
index 0000000..731ba75
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/config.json
@@ -0,0 +1,194 @@
+{
+	"id": "scrollableTestApp",
+	"name": "Scrollable Test App",
+	"description": "This is a test app for scrollable lists.",
+	"splash": "splash",
+
+	// Dependencies, modules and controllers are loaded using the Dojo AMD loader. 
+	// This parameter allows to configure the loader itself and specify for example where custom modules can be found.
+	"loaderConfig": {
+		"paths": {
+			"scrollableTestApp": "../dojox/app/tests/scrollableTestApp"
+		}
+	},
+
+	// Array of AMD modules identifiers. When defined at the top level dependencies of the dojox/app application. 
+	// When defined at view level, dependencies for the view.
+	"dependencies": [
+		"dojox/mobile/_base",
+		"dojox/mobile/_compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/TextBox",
+		"dojox/mobile/Button",
+		"dojox/mobile/Heading",
+		"dojox/mobile/ListItem",
+		"dojox/mobile/RoundRectList",
+		"dojox/mobile/RoundRectCategory",
+		"dojox/app/widgets/Container",
+		"dojox/mobile/Container",
+		"dojo/data/ItemFileWriteStore",
+		"dojo/store/DataStore",
+		"dojox/app/utils/mvcModel",
+		"dojox/mvc/EditStoreRefListController",
+		"dojox/mvc/Repeat",
+		"dojox/mvc/WidgetList",
+		"dojox/mvc/Templated",
+		"dojox/mvc/_InlineTemplateMixin",
+		"dojox/mobile/ScrollableView",
+		"dojox/mvc/Group",
+		"dojox/mvc/Output",
+		"dojox/mvc/at"
+	],
+	// Modules for the application.  They are basically used as the second
+	// array of mixins in a dojo.declare().  Modify the top level behavior
+	// of the application, how it processes the config or any other life cycle
+	// by creating and including one or more of these
+	"modules": [
+		"scrollableTestApp/scrollableTestApp"
+	],
+
+	// Array of AMD modules identifiers. Controllers for the application. All the controllers defined here will be 
+	// loaded during application startup to respond to application events and controller the application logic. 
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],
+
+	// Dojo stores which are used by dojox/app to setup data models. A store item is an object with a
+	// a type and a params property. The type property is the AMD module identifier for the store class to be
+	// instantiated. The content of the params property is passed to the store class constructor to build an 
+	// instance. 
+	"stores": {
+		"repeatStore":{
+			"type": "dojo/data/ItemFileWriteStore",
+			"params": {
+				"url": "./resources/data/repeat.json"
+			}
+	   }
+	},
+
+	// Models and their instantiation parameters. A model item is an object with three properties: the 
+	// model type, the modelLoader and the params. The modelLoader property defines whether an MVC or a
+	// simple model must be loaded. The type property defines which class must be used for that model using
+	// an AMD module identifier and finally the params property content is passed to the model class 
+	// constructor to build an instance.
+	"models": {
+       "repeatmodels": {
+       					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"datastore": {"$ref":"#stores.repeatStore"}
+					}
+        }
+	},
+	
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"phone" : {
+			//The name(s) of the view(s) to load when the application is initialized.
+			"defaultView": "configuration,ScrollableListSelection"
+		},
+		"!phone" : {
+			//The name(s) of the view(s) to load when the application is initialized.
+			"defaultView": "TestInfo",
+			"template": "scrollableTestApp/views/tablet/ViewScrollableLists.html",
+			"controller": "scrollableTestApp/views/tablet/ViewScrollableLists"
+		},
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+	// defaultTransition: The default animation type for the view transition.
+	// the defaultTransition is only used if transition is not set in the config and the transition is not set or 
+	// defaulted on the transitionEvent
+	// These are the possible defaultTransitions, 
+	//"defaultTransition": "slide",
+	//"defaultTransition": "none",
+	//"defaultTransition": "fade",
+	"defaultTransition": "flip",     // Note: flip does not work with a BorderLayout Controller
+
+	// transition: The animation type to use for all view transitions.
+	// if a transition is set on a view or parent it will override the transition set on the transitionEvent or the defaultTransition in the config.
+	//"transition": "slide",
+
+	// views: The children views of an application or of a view. Dependencies may be defined on views for
+	// optimization and organization purposes. Models might also be defined on views if they are view-specific
+	// Finally a view item as three additional properties: transition for specific view transitions, template for
+	// defining the view rendering and finally controller to provide an AMD module to be mixed into the view to 
+	// control it. AMD modules identifiers starting with “.” will be resolved relative to the application root. All other
+	// modules identifiers will be resolved according to the Dojo AMD loader rules and in particular with respect
+	// to its configuration provided as part of the loaderConfig attribute. If you do not want a controller
+	// module at all you should not specify one, setting it to none will no longer work.
+
+	"views": {
+		"configuration": {
+			"defaultView": "ScrollableListSelection",
+			"transition": "slide",
+
+			"views": {
+				"ScrollableListSelection": {
+					"controller": "scrollableTestApp/views/configuration/ScrollableListSelection.js",
+					"template": "scrollableTestApp/views/configuration/ScrollableListSelection.html"
+				}
+			}
+		},
+		
+		
+		"TestInfo": {
+			"transition": "none",
+			"controller": "scrollableTestApp/views/TestInfo.js",
+			"template": "scrollableTestApp/views/TestInfo.html"
+		},
+		"Scrollable1": {
+			"transition": "slide",
+			"controller": "scrollableTestApp/views/Scrollable1.js",
+			"template": "scrollableTestApp/views/Scrollable1.html"
+		},
+		"Scrollable1P": {
+			"transition": "flip",
+			"controller": "scrollableTestApp/views/Scrollable1P.js",
+			"template": "scrollableTestApp/views/Scrollable1P.html"
+		},
+		"Scrollable2": {
+			"transition": "fade",
+			"controller": "scrollableTestApp/views/Scrollable2.js",
+			"template": "scrollableTestApp/views/Scrollable2.html"
+		},
+		"Scrollable3": {
+			"controller": "scrollableTestApp/views/Scrollable3.js",
+			"template": "scrollableTestApp/views/Scrollable3.html"
+		},
+		"Scrollable4": {
+			"controller": "scrollableTestApp/views/Scrollable4.js",
+			"template": "scrollableTestApp/views/Scrollable4.html"
+		},
+		"Scrollable5": {
+			"controller": "scrollableTestApp/views/Scrollable5.js",
+			"template": "scrollableTestApp/views/Scrollable5.html"
+		},
+		"ListItemDomButtons": {
+			"controller": "scrollableTestApp/views/ListItem-domButtons",
+			"template": "scrollableTestApp/views/ListItem-domButtons.html"
+		},
+		"ListItemDomButtons2": {
+			"template": "scrollableTestApp/views/ListItem-domButtons2.html"
+		},
+		
+		"repeatDetails": {
+			"controller": "scrollableTestApp/views/repeatDetails.js",
+			"template": "scrollableTestApp/views/repeatDetails.html",
+			"transition": "slide"
+		}
+	}
+}
diff --git a/dojox/app/tests/scrollableTestApp/css/demo.css b/dojox/app/tests/scrollableTestApp/css/demo.css
new file mode 100644
index 0000000..2e49304
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/css/demo.css
@@ -0,0 +1,12 @@
+html,body {
+	width: 100%;
+	height: 100%;
+	background-color: black;
+}
+.lineItemPreventTouch {
+	width:2.5em;
+	height:3em; 
+	position:absolute; 
+	margin-left: -8px;
+	margin-top: -11px;
+}
diff --git a/dojox/app/tests/scrollableTestApp/css/tablet.css b/dojox/app/tests/scrollableTestApp/css/tablet.css
new file mode 100644
index 0000000..b13bfcf
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/css/tablet.css
@@ -0,0 +1,81 @@
+#header button {
+	position:absolute;
+	margin:0;
+}
+
+#navButton {
+	width:60px;
+}
+
+#loadDiv {
+	position:absolute;
+	left:0;
+	top:0;
+	width:100%;
+	height:100%;
+	z-index:999;
+}
+#loadDiv {
+	display:table;
+	font-size: 20px;
+	text-align:center;
+	background-color:white;
+}
+#loadDiv span {
+	display:table-cell;
+	vertical-align:middle;
+}
+
+body .mblProgContainer {
+	top:45%;
+	height: 45px;
+	width: 140px;
+	margin-left:-70px;
+	background-color: #2A2A28;
+	border-style: solid;
+	border-width: 2px;
+	border-color: #666666;
+	border-radius: 0.4em;
+	-webkit-border-radius: 0.4em;
+	-moz-border-radius: 0.4em;
+}
+
+body .mblProgContainer > div {
+	height: 100%;
+	width: 100%;
+	line-height: 45px;
+	vertical-align: middle;
+	font-size: 20px;
+	color: #c2c2c2;
+}
+
+body .mblProg {
+	left: 3px;
+	top: 3px;
+}
+
+body .mblProgContainer > div::after {
+	padding-left: 42px;
+	content: "Updating...";
+}
+
+#jsContent, #htmlContent {
+	padding-left:2px;
+}
+
+ at media screen and (max-width: 600px) {
+	#jsContent, #htmlContent {
+		font-size: 14px;
+	}
+}
+
+.hidden {
+	display:none;
+}
+
+div .navPane {
+	width:250px;
+	border-right:1px solid black;
+	background-color: #C5CCD3;
+	z-index:100;
+}
diff --git a/dojox/app/tests/scrollableTestApp/index.html b/dojox/app/tests/scrollableTestApp/index.html
new file mode 100644
index 0000000..5ba16a9
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/index.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes"/>		
+		<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
+		<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">		
+		<title>Scrollable Test App</title>
+		<link rel="stylesheet" type="text/css" href="css/tablet.css">
+	<!--	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/> -->
+		<link type="text/css" href="css/demo.css" rel="stylesheet">
+	<style>
+	.subject {
+		font: bold 16px Helvetica;
+	}
+	.textBox {
+		font-size: 12px; 
+		font-weight: normal;
+		overflow: hidden;
+	}
+	</style>
+	
+		
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"
+   					data-dojo-config="mblThemeFiles:['@theme',['dojox/app/tests/scrollableTestApp','todo']]"></script>
+
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false,
+				mblHideAddressBar: true,
+				mblAndroidWorkaround: false,
+				mblAlwaysHideAddressBar: true,
+				app: {debugApp: 1},  // set debugApp to log app transtions and view activate/deactivate
+				mvc: {debugBindings: 0},  // set on to debug mvc data bindings
+				async: 1">
+		</script>
+		<script>
+			require(["./src.js"], function(){
+			});
+		</script>
+		
+	</head>
+	<body style="overflow-y:hidden; overflow-x:hidden;">
+	</body>
+</html>
diff --git a/dojox/app/tests/scrollableTestApp/resources/data/repeat.json b/dojox/app/tests/scrollableTestApp/resources/data/repeat.json
new file mode 100644
index 0000000..191b80b
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/resources/data/repeat.json
@@ -0,0 +1,105 @@
+{
+  "identifier": "Serial",
+   "items": [ 
+                    {
+                        "Serial"  : "A111",
+                        "First"   : "Anne",
+                        "Last"    : "Ackerman",
+                        "Location": "NY",
+                        "Office"  : "1S76",
+                        "Email"   : "a.a at test.com",
+                        "Tel"     : "123-764-8237",
+                        "Fax"     : "123-764-8228"
+                    },
+                    {
+                        "Serial"  : "B111",
+                        "First"   : "Ben",
+                        "Last"    : "Beckham",
+                        "Location": "NY",
+                        "Office"  : "5N47",
+                        "Email"   : "b.b at test.com",
+                        "Tel"     : "123-764-8599",
+                        "Fax"     : "123-764-8600"
+                    },
+                    {
+                        "Serial"  : "C111",
+                        "First"   : "Chad",
+                        "Last"    : "Chapman",
+                        "Location": "CA",
+                        "Office"  : "1278",
+                        "Email"   : "c.c at test.com",
+                        "Tel"     : "408-764-8237",
+                        "Fax"     : "408-764-8228"
+                    },
+                    {
+                        "Serial"  : "D111",
+                        "First"   : "David",
+                        "Last"    : "Durham",
+                        "Location": "NJ",
+                        "Office"  : "C12",
+                        "Email"   : "d.d at test.com",
+                        "Tel"     : "514-764-8237",
+                        "Fax"     : "514-764-8228"
+                    },
+                    {
+                        "Serial"  : "E111",
+                        "First"   : "Emma",
+                        "Last"    : "Eklof",
+                        "Location": "NY",
+                        "Office"  : "4N76",
+                        "Email"   : "e.e at test.com",
+                        "Tel"     : "123-764-1234",
+                        "Fax"     : "123-764-4321"
+                    },
+                    {
+                        "Serial"  : "F111",
+                        "First"   : "Fred",
+                        "Last"    : "Fisher",
+                        "Location": "NJ",
+                        "Office"  : "V89",
+                        "Email"   : "f.f at test.com",
+                        "Tel"     : "514-764-8567",
+                        "Fax"     : "514-764-8000"
+                    },
+                    {
+                        "Serial"  : "G111",
+                        "First"   : "George",
+                        "Last"    : "Garnett",
+                        "Location": "NY",
+                        "Office"  : "7S11",
+                        "Email"   : "gig at test.com",
+                        "Tel"     : "123-999-8599",
+                        "Fax"     : "123-999-8600"
+                    },
+                    {
+                        "Serial"  : "H111",
+                        "First"   : "Hunter",
+                        "Last"    : "Huffman",
+                        "Location": "CA",
+                        "Office"  : "6532",
+                        "Email"   : "h.h at test.com",
+                        "Tel"     : "408-874-8237",
+                        "Fax"     : "408-874-8228"
+                    },
+                    {
+                        "Serial"  : "I111",
+                        "First"   : "Irene",
+                        "Last"    : "Ira",
+                        "Location": "NJ",
+                        "Office"  : "F09",
+                        "Email"   : "i.i at test.com",
+                        "Tel"     : "514-764-6532",
+                        "Fax"     : "514-764-7300"
+                    },
+                    {
+                        "Serial"  : "J111",
+                        "First"   : "John",
+                        "Last"    : "Jacklin",
+                        "Location": "CA",
+                        "Office"  : "6701",
+                        "Email"   : "j.j at test.com",
+                        "Tel"     : "408-764-1234",
+                        "Fax"     : "408-764-4321"
+                    }
+                ]
+}
diff --git a/dojox/app/tests/scrollableTestApp/scrollableTestApp.js b/dojox/app/tests/scrollableTestApp/scrollableTestApp.js
new file mode 100644
index 0000000..78ca218
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/scrollableTestApp.js
@@ -0,0 +1,67 @@
+define(["dojox/mobile/ProgressIndicator", "dojox/mobile/TransitionEvent", "dojox/mvc/getStateful"], function(ProgressIndicator, TransitionEvent, getStateful){
+	return function(){
+		// the default select_item is 0, or will throw an error if directly transition to #details,EditTodoItem view
+		this.selected_item = 0;
+		this.selected_configuration_item = 0;
+		this.progressIndicator = null;
+		/*
+	 	* show or hide global progress indicator
+	 	*/
+	 	
+	 	// show an item detail
+		this.setDetailsContext = function(index){
+			if(this.loadedModels.repeatmodels) {
+				this.loadedModels.repeatmodels.set("cursorIndex", index);
+			}		
+		};
+
+		// global for call from template
+		this.removeScrollableItem = function(index){
+				this.loadedModels.repeatmodels.model.splice(index, 1);
+				return false; 	 		
+		};
+
+		// insert an item
+		this.insertResult = function(index, e){
+			var repeatmodel = this.loadedModels.repeatmodels;
+			if(index<0 || index>repeatmodel.model.length){
+				throw Error("index out of data model.");
+			}
+			if((repeatmodel.model[index].First=="") ||
+				(repeatmodel.model[index+1] && (repeatmodel.model[index+1].First == ""))){
+				return;
+			}
+			var data = {id:Math.random(), "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+			repeatmodel.model.splice(index+1, 0, new getStateful(data));
+			this.setDetailsContext(index+1);
+			var transOpts = {
+				title : "repeatDetails",
+				target : "repeatDetails",
+				url : "#repeatDetails", // this is optional if not set it will be created from target   
+				params : {"cursor":index+1}
+			};
+			new TransitionEvent(e.target, transOpts, e).dispatch(); 
+			
+		};
+
+	 	
+		this.showProgressIndicator = function(show){
+				
+			if(!this.progressIndicator){
+				this.progressIndicator = ProgressIndicator.getInstance({removeOnStop:false, startSpinning:true, size:40, center:true, interval:30});
+				// TODO: use dojo.body will throw no appendChild method error.
+				var body = document.getElementsByTagName("body")[0];
+				body.appendChild(this.progressIndicator.domNode);
+				this.progressIndicator.domNode.style.zIndex = 999;
+			}
+			if(show){
+				this.progressIndicator.domNode.style.visibility = "visible";
+				this.progressIndicator.start();
+			}else{
+				this.progressIndicator.stop();
+				this.progressIndicator.domNode.style.visibility = "hidden";
+			}
+			
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp/src.js b/dojox/app/tests/scrollableTestApp/src.js
new file mode 100644
index 0000000..fb34be8
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/src.js
@@ -0,0 +1,15 @@
+require(["dojox/app/main", "dojox/json/ref", "dojo/sniff"],
+	function(Application, json, has){
+
+	var configurationFile = "./config.json";
+
+	require(["dojo/text!"+configurationFile], function(configJson){
+		var config = json.fromJson(configJson);
+		var width = window.innerWidth || document.documentElement.clientWidth;
+		if(width <= 600){
+			has.add("phone", true);
+		}
+		has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+		Application(config);
+	});
+});
diff --git a/dojox/app/tests/scrollableTestApp/themes/android/todo.css b/dojox/app/tests/scrollableTestApp/themes/android/todo.css
new file mode 100644
index 0000000..616a45c
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/themes/android/todo.css
@@ -0,0 +1,25 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  padding-left: 5px;
+  padding-top: 16px;
+  padding-bottom: 16px;
+  padding-right: 1px;
+
+  font-size: 21px;
+  color: white;
+
+  border: 1px solid #ADAAAD;
+  border-radius: 8px;
+  background-color: black;
+}
+div .navPane {
+	background-color: black !important;
+	border-right: 1px solid #ADAAAD !important;
+}
+button.baseBtn {
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  height: 48px;
+  margin-bottom: 6px;
+}
diff --git a/dojox/app/tests/scrollableTestApp/themes/blackberry/todo.css b/dojox/app/tests/scrollableTestApp/themes/blackberry/todo.css
new file mode 100644
index 0000000..6d5ec0e
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/themes/blackberry/todo.css
@@ -0,0 +1,21 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  font-size: 18px;
+
+  padding-top: 16px;
+  padding-bottom: 16px;
+  padding-left: 7px;
+  
+  border: 1px solid #c6c7c6;
+  border-radius: 6px;
+  background-color: white;
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 0;
+}
+button.baseBtn {
+  font-size: 18px;
+  height: 48px;
+  margin-bottom: 8px;
+}
diff --git a/dojox/app/tests/scrollableTestApp/themes/iphone/todo.css b/dojox/app/tests/scrollableTestApp/themes/iphone/todo.css
new file mode 100644
index 0000000..21f9cb0
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/themes/iphone/todo.css
@@ -0,0 +1,31 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  color: #324f85;
+  
+  padding-left: 8px;
+  padding-right: 1px;
+  padding-top: 10px;
+  padding-bottom: 10px;
+
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
+  border-bottom-style: solid;
+  border-bottom-color: #ADAAAD;
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 0;
+}
+button.baseBtn {
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  height: 40px;
+  margin-bottom: 8px;
+}
diff --git a/dojox/app/tests/scrollableTestApp/views/ListItem-domButtons.html b/dojox/app/tests/scrollableTestApp/views/ListItem-domButtons.html
new file mode 100644
index 0000000..c3d5a1f
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/ListItem-domButtons.html
@@ -0,0 +1,106 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+<!--
+			<div data-dojo-type="dojox/mobile/Heading" data-dojo-props='fixed:"top", data-app-constraint="top",
+-->
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='fixed:"top", 
+							label:"Mobile Scrollable Test."'>
+			<span id="mli1back" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+			data-dojo-props="target: 'configuration', url: '#configuration', transitionDir: -1">Back</span>
+		</h1>
+
+		<h2 data-dojo-type="dojox/mobile/RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox/mobile/RoundRect">
+			header: Mobile Scrollable Test<br>
+			footer: application-footer<br>
+			scrollDir: vertical with 27 items
+		</div>
+
+		<ul data-dojo-type="dojox/mobile/RoundRectList">
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-1.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 1
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-2.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 2
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-3.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 3
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-4.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 4
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-5.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 5
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-6.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 6
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-7.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 7
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-8.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 8
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-9.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 9
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-1.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 10
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-2.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 11
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-3.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 12
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-4.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 13
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-5.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 14
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-6.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 15
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-7.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 16
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-8.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 17
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-9.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 18
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-7.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 19
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-8.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 20
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-9.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 21
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-7.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 22
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-8.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 23
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-9.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 24
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-7.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 25
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-8.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 26
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-9.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 27
+			</li>
+		</ul>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Application Footer Bar</h1>
+
+</div>
diff --git a/dojox/app/tests/scrollableTestApp/views/ListItem-domButtons.js b/dojox/app/tests/scrollableTestApp/views/ListItem-domButtons.js
new file mode 100644
index 0000000..c8298d7
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/ListItem-domButtons.js
@@ -0,0 +1,18 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dijit/registry", "dojox/mvc/at", "dojox/mobile/TransitionEvent", "dojox/mvc/Repeat", 
+		"dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, registry, at, TransitionEvent, Repeat, getStateful, Output, has){
+
+	return {
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId("mli1back") && !has("phone")){ 
+				domStyle.set(dom.byId("mli1back"), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp/views/ListItem-domButtons2.html b/dojox/app/tests/scrollableTestApp/views/ListItem-domButtons2.html
new file mode 100644
index 0000000..2e0debf
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/ListItem-domButtons2.html
@@ -0,0 +1,42 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='fixed:"top", back:"Back"'>Mobile Scrollable Test.</h1>
+		<ul data-dojo-type="dojox/mobile/RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox/mobile/ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Application Footer Bar</h1>
+
+</div>
diff --git a/dojox/app/tests/scrollableTestApp/views/RoundRectWidListTemplate.html b/dojox/app/tests/scrollableTestApp/views/RoundRectWidListTemplate.html
new file mode 100644
index 0000000..03f28cc
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/RoundRectWidListTemplate.html
@@ -0,0 +1,8 @@
+<li data-dojo-type="dojox/mobile/ListItem">
+	<div data-dojo-type="dojox/mobile/ToolBarButton" 
+		data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+			onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+									scrollableTestApp.removeScrollableItem(this.indexAtStartup); return false; }"
+		style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+	<div data-dojo-type="dojox/mvc/Output" style="display: inline" data-dojo-attach-point="titleNode"></div>		
+</li>
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable1.html b/dojox/app/tests/scrollableTestApp/views/Scrollable1.html
new file mode 100644
index 0000000..bd40818
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable1.html
@@ -0,0 +1,41 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List One"' data-app-constraint="top">
+		<span id="sc1back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="target: 'configuration,ScrollableListSelection', url: '#configuration,ScrollableListSelection', transitionDir: -1">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1insert1x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1remove10x" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>     
+	<div data-app-constraint="top">
+		<div class="field-title">Should scroll between this text and the bottom footer.</div>
+	</div>     
+
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+	
+		<form name="repeatTestForm">    
+				<ul
+					data-dojo-type="dojox/mobile/RoundRectList"
+					data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: this.loadedModels.repeatmodels.model"
+					data-mvc-child-type="dojox/mvc/Templated"
+					data-mvc-child-mixins="dojox/mobile/ListItem"
+					data-mvc-child-props="clickable: true,
+							transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+							onClick: function(){scrollableTestApp.setDetailsContext(this.indexAtStartup);}">					
+					<script type="dojox/mvc/InlineTemplate">
+						<li data-dojo-type="dojox/mobile/ListItem">
+							<div data-dojo-type="dojox/mobile/ToolBarButton" 
+								data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+								                 onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+								                 	        scrollableTestApp.removeScrollableItem(this.indexAtStartup); return false; }"
+								style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+							<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'First')"></div>	
+						</li>
+					</script>
+				</ul>
+		</form>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Scrollable List One Footer Bar'" data-app-constraint="bottom"></h1>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable1.js b/dojox/app/tests/scrollableTestApp/views/Scrollable1.js
new file mode 100644
index 0000000..4967dbe
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable1.js
@@ -0,0 +1,86 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", 
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc1back1';
+	var insert1Id = 'sc1insert1x';
+	var insert10Id = 'sc1insert10x';
+	var remove10Id = 'sc1remove10x';
+
+	var app = null;
+
+	return {
+		// repeat view init
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", lang.hitch(this,function(e){
+				this.app.insertResult(repeatmodel.model.length-1,e);
+			}));
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable1P.html b/dojox/app/tests/scrollableTestApp/views/Scrollable1P.html
new file mode 100644
index 0000000..38941ef
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable1P.html
@@ -0,0 +1,23 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List OneP"' data-app-constraint="top">
+		<span id="sc1back1P" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="target: 'configuration,ScrollableListSelection', url: '#configuration,ScrollableListSelection', transitionDir: -1">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1insert1xP" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1insert10xP" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1remove10xP" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>     
+	<div data-app-constraint="top">
+		<div class="field-title">Should scroll between this text and the bottom footer.</div>
+	</div>     
+
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+		<div>	
+			<form name="repeatTestForm">   
+				<div id="addWidgetHere"></div>	 
+			</form>
+		</div>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Scrollable List OneP Footer Bar'" data-app-constraint="bottom"></h1>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable1P.js b/dojox/app/tests/scrollableTestApp/views/Scrollable1P.js
new file mode 100644
index 0000000..a4e3c74
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable1P.js
@@ -0,0 +1,151 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang", "dojo/_base/declare", "dijit/registry", "dojox/mvc/at", 
+"dojox/mobile/TransitionEvent", "dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff", 
+"dojox/mobile/RoundRectList", "dojox/mvc/WidgetList", "dojox/mvc/Templated", "dojox/mobile/ListItem", "dojo/text!../views/RoundRectWidListTemplate.html"],
+function(dom, domStyle, connect, lang, declare, registry, at, TransitionEvent, Repeat, getStateful, Output, has, RoundRectList, WidgetList, Templated, 
+	ListItem, RoundRectWidListTemplate){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	var roundRectWidList = null;
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc1back1P';
+	var insert1Id = 'sc1insert1xP';
+	var insert10Id = 'sc1insert10xP';
+	var remove10Id = 'sc1remove10xP';
+
+	var app = null;
+
+	// insert an item
+	var insertResult = function(index, e){
+		if(index<0 || index>repeatmodel.model.length){
+			throw Error("index out of data model.");
+		}
+		if((repeatmodel.model[index].First=="") ||
+			(repeatmodel.model[index+1] && (repeatmodel.model[index+1].First == ""))){
+			return;
+		}
+		var data = {id:Math.random(), "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+		repeatmodel.model.splice(index+1, 0, new getStateful(data));
+		this.app.setDetailsContext(index+1);
+		var transOpts = {
+			title : "repeatDetails",
+			target : "repeatDetails",
+			url : "#repeatDetails", // this is optional if not set it will be created from target   
+			params : {"cursor":index+1}
+		};
+		new TransitionEvent(e.target, transOpts, e).dispatch(); 
+		
+	};
+	
+	var showListData = function(/*dojox/mvc/EditStoreRefListController*/ datamodel){
+		// summary:
+		//		create the WidgetList programatically if it has not been created, and 
+		//		set the children for items_list widget to the datamodel to show the items in the selected list.
+		//		RoundRectWidListTemplate is used for the templateString of the WidgetList.
+		//
+		// datamodel: dojox/mvc/EditStoreRefListController
+		//		The EditStoreRefListController whose model holds the items for the selected list.
+		//
+		if(!roundRectWidList){
+			var clz = declare([WidgetList, RoundRectList], {});
+			roundRectWidList = new clz({
+				children: at(datamodel, 'model'),
+				childClz: declare([Templated /* dojox/mvc/Templated module return value */, ListItem /* dojox/mobile/ListItem module return value */]),
+				childParams: {
+					transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+					clickable: true,
+					onClick: function(){
+						console.log("in onClick this.indexAtStartup="+this.indexAtStartup);
+						app.setDetailsContext(this.indexAtStartup);}
+				},
+				childBindings: {
+					titleNode: {value: at("rel:", "First")}
+				},
+				templateString: RoundRectWidListTemplate
+			});
+			roundRectWidList.placeAt(dom.byId("addWidgetHere"));
+			roundRectWidList.startup();
+		}else{
+			roundRectWidList.set("children", at(datamodel, 'model'));
+		}
+	};
+
+	return {
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", function(e){
+				app.insertResult(repeatmodel.model.length-1,e);
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+			
+			showListData(this.loadedModels.repeatmodels);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+			//domStyle.set(dom.byId(wrapperIdA), "visibility", "visible");  // show the view when it is ready
+			//domStyle.set(dom.byId(wrapperIdB), "visibility", "visible");  // show the view when it is ready
+			//domStyle.set(dom.byId(wrapperIdC), "visibility", "visible");  // show the view when it is ready
+			//domStyle.set(dom.byId(wrapperIdD), "visibility", "visible");  // show the view when it is ready
+
+			showListData(this.loadedModels.repeatmodels);			
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable2.html b/dojox/app/tests/scrollableTestApp/views/Scrollable2.html
new file mode 100644
index 0000000..7b890e0
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable2.html
@@ -0,0 +1,41 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List Two"' data-app-constraint="top">
+		<span id="sc2back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="target: 'configuration,ScrollableListSelection', url: '#configuration,ScrollableListSelection', transitionDir: -1">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc2insert1x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc2insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc2remove10x" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>
+
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+
+		<div class="field-title">Should scroll between the header and footer, this text will also scroll.</div>
+
+		<form name="repeatTestForm">
+				<ul
+					data-dojo-type="dojox/mobile/RoundRectList"
+					data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: this.loadedModels.repeatmodels.model"
+					data-mvc-child-type="dojox/mvc/Templated"
+					data-mvc-child-mixins="dojox/mobile/ListItem"
+					data-mvc-child-props="clickable: true,
+							transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+							onClick: function(){scrollableTestApp.setDetailsContext(this.indexAtStartup);}">
+					<script type="dojox/mvc/InlineTemplate">
+						<li data-dojo-type="dojox/mobile/ListItem">
+							<div data-dojo-type="dojox/mobile/ToolBarButton"
+								data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+													onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+																		scrollableTestApp.removeScrollableItem(this.indexAtStartup); return false; }"
+								style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+							<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'First')"></div>	
+						</li>
+					</script>
+				</ul>
+		</form>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Scrollable List Two Footer Bar'" data-app-constraint="bottom"></h1>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable2.js b/dojox/app/tests/scrollableTestApp/views/Scrollable2.js
new file mode 100644
index 0000000..ee34df2
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable2.js
@@ -0,0 +1,81 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", 
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc2back1';
+	var insert1Id = 'sc2insert1x';
+	var insert10Id = 'sc2insert10x';
+	var remove10Id = 'sc2remove10x';
+
+	var app = null;
+
+	return {
+		// repeat view init
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", lang.hitch(this,function(e){
+				this.app.insertResult(repeatmodel.model.length-1,e);
+			}));
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable3.html b/dojox/app/tests/scrollableTestApp/views/Scrollable3.html
new file mode 100644
index 0000000..01648d6
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable3.html
@@ -0,0 +1,42 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List Three"' data-app-constraint="top">
+		<span id="sc3back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="target: 'configuration,ScrollableListSelection', url: '#configuration,ScrollableListSelection', transitionDir: -1">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc3insert1x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc3insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc3remove10x" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>
+	<div data-app-constraint="top">
+	</div>
+
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+
+		<div class="field-title">Should scroll from under the top header to the end of the page, this text will also scroll.</div>
+
+		<form name="repeatTestForm">
+				<ul
+					data-dojo-type="dojox/mobile/RoundRectList"
+					data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: this.loadedModels.repeatmodels.model"
+					data-mvc-child-type="dojox/mvc/Templated"
+					data-mvc-child-mixins="dojox/mobile/ListItem"
+					data-mvc-child-props="clickable: true,
+							transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+							onClick: function(){scrollableTestApp.setDetailsContext(this.indexAtStartup);}">
+					<script type="dojox/mvc/InlineTemplate">
+						<li data-dojo-type="dojox/mobile/ListItem">
+							<div data-dojo-type="dojox/mobile/ToolBarButton"
+								data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+													onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+																		scrollableTestApp.removeScrollableItem(this.indexAtStartup); return false; }"
+								style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+							<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'First')"></div>	
+						</li>
+					</script>
+				</ul>
+		</form>
+	</div>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable3.js b/dojox/app/tests/scrollableTestApp/views/Scrollable3.js
new file mode 100644
index 0000000..db4dc2a
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable3.js
@@ -0,0 +1,81 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", "dojox/mobile/TransitionEvent",
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, TransitionEvent, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc3back1';
+	var insert1Id = 'sc3insert1x';
+	var insert10Id = 'sc3insert10x';
+	var remove10Id = 'sc3remove10x';
+
+	var app = null;
+
+	return {
+		// repeat view init
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", lang.hitch(this,function(e){
+				this.app.insertResult(repeatmodel.model.length-1,e);
+			}));
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable4.html b/dojox/app/tests/scrollableTestApp/views/Scrollable4.html
new file mode 100644
index 0000000..839638e
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable4.html
@@ -0,0 +1,43 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List Four", fixed:"top"'>
+		<span id="sc4back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="target: 'configuration,ScrollableListSelection', url: '#configuration,ScrollableListSelection', transitionDir: -1">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc4insert1x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc4insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc4remove10x" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>
+	<div>
+		<div class="field-title">Should scroll between the top header and the bottom footer, this text will also scroll.</div>
+	</div>
+
+	
+		<form name="repeatTestForm">
+				<ul
+					data-dojo-type="dojox/mobile/RoundRectList"
+					data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: this.loadedModels.repeatmodels.model"
+					data-mvc-child-type="dojox/mvc/Templated"
+					data-mvc-child-mixins="dojox/mobile/ListItem"
+					data-mvc-child-props="clickable: true,
+							transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+							onClick: function(){scrollableTestApp.setDetailsContext(this.indexAtStartup);}">
+					<script type="dojox/mvc/InlineTemplate">
+						<li data-dojo-type="dojox/mobile/ListItem">
+							<div data-dojo-type="dojox/mobile/ToolBarButton" 
+								data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+												onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+																		scrollableTestApp.removeScrollableItem(this.indexAtStartup); return false; }"
+								style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+							<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'First')"></div>	
+						</li>
+					</script>
+				</ul>
+		</form>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Scrollable List Four Footer Bar', fixed:'bottom'"></h1>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable4.js b/dojox/app/tests/scrollableTestApp/views/Scrollable4.js
new file mode 100644
index 0000000..6830f03
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable4.js
@@ -0,0 +1,81 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", 
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc4back1';
+	var insert1Id = 'sc4insert1x';
+	var insert10Id = 'sc4insert10x';
+	var remove10Id = 'sc4remove10x';
+
+	var app = null;
+
+	return {
+		// repeat view init
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", lang.hitch(this,function(e){
+				this.app.insertResult(repeatmodel.model.length-1,e);
+			}));
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable5.html b/dojox/app/tests/scrollableTestApp/views/Scrollable5.html
new file mode 100644
index 0000000..e8665e5
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable5.html
@@ -0,0 +1,42 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List Five", fixed:"top"'>
+		<span id="sc5back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="target: 'configuration,ScrollableListSelection', url: '#configuration,ScrollableListSelection', transitionDir: -1">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc5insert1x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc5insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc5remove10x" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>
+	<div>
+		<div class="field-title">Should scroll between the header and the end of the page, this text will also scroll.</div>
+	</div>
+
+	
+		<form name="repeatTestForm">
+				<ul
+					data-dojo-type="dojox/mobile/RoundRectList"
+					data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: this.loadedModels.repeatmodels.model"
+					data-mvc-child-type="dojox/mvc/Templated"
+					data-mvc-child-mixins="dojox/mobile/ListItem"
+					data-mvc-child-props="clickable: true,
+							transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+							onClick: function(){scrollableTestApp.setDetailsContext(this.indexAtStartup);}">
+					<script type="dojox/mvc/InlineTemplate">
+						<li data-dojo-type="dojox/mobile/ListItem">
+							<div data-dojo-type="dojox/mobile/ToolBarButton" 
+								data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+												onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+																scrollableTestApp.removeScrollableItem(this.indexAtStartup); return false; }"
+								style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+							<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'First')"></div>	
+						</li>
+					</script>
+				</ul>
+		</form>
+	</div>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp/views/Scrollable5.js b/dojox/app/tests/scrollableTestApp/views/Scrollable5.js
new file mode 100644
index 0000000..4262f50
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/Scrollable5.js
@@ -0,0 +1,81 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", 
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc5back1';
+	var insert1Id = 'sc5insert1x';
+	var insert10Id = 'sc5insert10x';
+	var remove10Id = 'sc5remove10x';
+
+	var app = null;
+
+	return {
+		// repeat view init
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", lang.hitch(this,function(e){
+				this.app.insertResult(repeatmodel.model.length-1,e);
+			}));
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp/views/TestInfo.html b/dojox/app/tests/scrollableTestApp/views/TestInfo.html
new file mode 100644
index 0000000..f17c8a2
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/TestInfo.html
@@ -0,0 +1,27 @@
+<div class="view mblView">
+
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+
+		<h1 id="tst1WrapperA" style="visibility:hidden"
+			data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Test Info for Scrollable tests.", fixed:"top"'>
+			<span id="ti1back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left"
+				data-dojo-props="target: 'configuration,ScrollableListSelection', url: '#configuration,ScrollableListSelection', transitionDir: -1">Back</span>
+		</h1>
+
+		<div id="tst1WrapperB" style="visibility:hidden">
+			<div class="field-title">Each test will indicate which area should scroll.</div>
+			<div class="field-title">Use the +10 or + icons to add data to enable scrolling if necessary.</div>
+			<br>
+			<div class="field-title">Be sure to test orientation changes or on browser resize.</div>
+			<div class="field-title">Verify that you can scroll to the top and bottom of the scrollable data.</div>
+			<div class="field-title">Also refresh the page for each scrollable view, had a problem without height="auto", but ended up removing height='auto' on a mobile ScrollableView</div>
+			<br><br>
+			<div class="field-title">Note that the tests which use <b>dojox/app/widgets/Container with scrollable:true</b> should use use headers or footers with data-app-constraint="top" or data-app-constraint="bottom" and they should not use headers and footers with fixed:'top' and fixed:'bottom'.</div>
+			<br>
+			<div class="field-title">Note that the tests which use <b>dojox/mobile/ScrollableView</b> should use headers and footers with fixed:'top' and fixed:'bottom' and they should not use headers or footers with data-app-constraint="top" or data-app-constraint="bottom".</div>
+			<br>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp/views/TestInfo.js b/dojox/app/tests/scrollableTestApp/views/TestInfo.js
new file mode 100644
index 0000000..2be8244
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/TestInfo.js
@@ -0,0 +1,46 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", "dojox/mobile/TransitionEvent", 
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, TransitionEvent, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'ti1back1';
+	var wrapperIdA = 'tst1WrapperA';
+	var wrapperIdB = 'tst1WrapperB';
+
+
+	return {
+		// repeat view init
+		init: function(){			
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA") && !has("phone")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+			domStyle.set(dom.byId(wrapperIdA), "visibility", "visible");  // show the view when it is ready
+			domStyle.set(dom.byId(wrapperIdB), "visibility", "visible");  // show the view when it is ready
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp/views/configuration/ScrollableListSelection.html b/dojox/app/tests/scrollableTestApp/views/configuration/ScrollableListSelection.html
new file mode 100644
index 0000000..b1c7915
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/configuration/ScrollableListSelection.html
@@ -0,0 +1,70 @@
+<div class="view mblView">
+	
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Scrollable List Selection'" data-app-constraint="top"></h1>
+	<h2 data-dojo-type="dojox/mobile/RoundRectCategory" data-app-constraint="top">Select a Scrollable List</h2>
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+		
+		<div>
+			<ul data-dojo-type="dojox/mobile/RoundRectList"  data-dojo-props='variableHeight:true'>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'TestInfo', url: '#TestInfo'">
+					<div class="textBox">
+						<div class="subject">Test Instructions</div>
+						Test instructions, notes and known problems (transition none)				
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable1', url: '#Scrollable1'">
+					<div class="textBox">
+						<div class="subject">Scrollable list One</div>
+					Uses app/widgets/Container with a fixed Header and a fixed Footer both with data-app-constraint	 (transition slide)				
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable1P', url: '#Scrollable1P'">
+					<div class="textBox">
+						<div class="subject">Scrollable list OneP</div>
+						Programmatic creation of WidgetList uses app/widgets/Container with a fixed Header and a fixed Footer both with data-app-constraint  (transition flip)					
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable2', url: '#Scrollable2'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Two</div>
+					Uses app/widgets/Container with a fixed Header and a fixed Footer both with data-app-constraint  (transition fade)
+					</div>				
+				</li>
+			
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable3', url: '#Scrollable3'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Three</div>
+						Uses app/widgets/Container with a fixed Header no footer with data-app-constraint					
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+				data-dojo-props="clickable: true, noArrow: true, transition:'fade', target: 'Scrollable4', url: '#Scrollable4'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Four</div>
+					Uses dojox/mobile/ScrollableView (removed height="auto") with a fixed Header and a fixed Footer (transition event fade)					
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+				data-dojo-props="clickable: true, noArrow: true, transition:'flip', target: 'Scrollable5', url: '#Scrollable5'">
+					<div class="textBox">
+					<div class="subject">Scrollable list Five</div>
+					Uses dojox/mobile/ScrollableView (removed height="auto") with a fixed Header and No Footer (transition event flip)				
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'ListItemDomButtons', url: '#ListItemDomButtons'">
+					<div class="textBox">
+						<div class="subject">Dojox Mobile Test</div>
+						A copy of the dojox/mobile test test_ListItemDomButtons, (removed height="auto"), had used it to avoid problem with initially showing this page.					
+					</div>				
+				</li>
+			</ul>
+		</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/scrollableTestApp/views/configuration/ScrollableListSelection.js b/dojox/app/tests/scrollableTestApp/views/configuration/ScrollableListSelection.js
new file mode 100644
index 0000000..5642fcd
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/configuration/ScrollableListSelection.js
@@ -0,0 +1,31 @@
+define([], function(){
+
+	var app = null;
+
+	return {
+		init: function(){
+			app = this.app;
+		},
+		
+		beforeActivate: function(){
+			app.stopTransition = false;
+			//console.log("configuration/ScrollableListSelection beforeActivate called this.app.selected_configuration_item=",this.app.selected_configuration_item);
+		},
+		
+		afterActivate: function(){
+			//console.log("configuration/ScrollableListSelection afterActivate called this.app.selected_configuration_item=",this.app.selected_configuration_item);
+			//console.log("setting configurewrapper visible 1");
+			//domStyle.set(dom.byId("configurewrapper"), "visibility", "visible"); // show the items list
+		},
+		
+		beforeDeactivate: function(){
+			//console.log("configuration/ScrollableListSelection beforeDeactivate called this.app.selected_configuration_item=",this.app.selected_configuration_item);
+		},
+
+		afterDeactivate: function(){
+			//console.log("configuration/ScrollableListSelection afterDeactivate called this.app.selected_configuration_item=",this.app.selected_configuration_item);
+			//console.log("setting configurewrapper hidden");
+			//domStyle.set(dom.byId("configurewrapper"), "visibility", "hidden"); // hide the items list 
+		}
+	}
+});
diff --git a/dojox/app/tests/scrollableTestApp/views/items.js b/dojox/app/tests/scrollableTestApp/views/items.js
new file mode 100644
index 0000000..94b2e8e
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/items.js
@@ -0,0 +1,24 @@
+define(["dojo/_base/lang", "dojo/dom", "dojo/dom-style", "dijit/registry", "dojox/mobile/TransitionEvent", "dojo/sniff"],
+	function(lang, dom, domStyle, registry, TransitionEvent, has){
+	return {
+		init: function(){
+			if(!has("phone")){
+				domStyle.set(dom.byId("gotoConfigurationView"), "display", "none");
+			}
+/*
+			registry.byId("itemslist_add").on("click", lang.hitch(this, function(e){
+				// use selected_item = -1 to identify add a new item
+				this.app._addNewItem = true;
+
+				// transition to detail view for edit
+				var transOpts = {
+					title: "Detail",
+					target: "details,EditTodoItem",
+					url: "#details,EditTodoItem"
+				};
+				new TransitionEvent(e.target, transOpts, e).dispatch();
+			}));
+*/			
+		}
+	}
+});
diff --git a/dojox/app/tests/scrollableTestApp/views/repeatDetails.html b/dojox/app/tests/scrollableTestApp/views/repeatDetails.html
new file mode 100644
index 0000000..ea51f01
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/repeatDetails.html
@@ -0,0 +1,46 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='back:"Back"'>Repeat Details</h1>
+	<form name="repeatTestForm" id="repeatTestForm">    
+		<div data-dojo-type="dojox/mvc/Group" 
+			data-dojo-props="target: at(this.loadedModels.repeatmodels, 'cursor')">
+					<div class="field-title">
+						<div style="display: inline-block;" id="detailsBanner">Details for selected index:</div>
+						<span class="cell" id="indexOutput"
+							data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at(this.loadedModels.repeatmodels, 'cursorIndex')"></span>
+					</div>
+					<table id="table" cellspacing="10" style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'First'), placeholder:'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput" data-dojo-type="dojox/mobile/TextBox"
+									 
+									data-dojo-props="placeholder:'Last Name', value: at('rel:', 'Last')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput2" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Email'), placeholder:'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Tel'), placeholder:'Telephone'">
+							</td>
+						</tr>
+					</table>
+		</div>
+		</form>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp/views/repeatDetails.js b/dojox/app/tests/scrollableTestApp/views/repeatDetails.js
new file mode 100644
index 0000000..630821c
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/repeatDetails.js
@@ -0,0 +1,34 @@
+define(["dojo/dom", "dojo/dom-style"],
+function(dom, domStyle){
+	var repeatmodel = null;	//repeat view data model
+
+	// show an item detail
+	var setDetailsContext = function(index){
+		// only set the cursor if it is different and valid
+		if(parseInt(index) != repeatmodel.cursorIndex && parseInt(index) < repeatmodel.model.length){
+			repeatmodel.set("cursorIndex", parseInt(index));
+		}
+	};
+
+	return {
+		// repeat view init
+		init: function(){
+			console.log("IN REPEATDETAILS");
+			repeatmodel = this.loadedModels.repeatmodels;
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			// if this.params["cursor"] is set use it to set the selected Details Context
+			if(this.params["cursor"]){
+				setDetailsContext(this.params["cursor"]);
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		}
+	}
+});
diff --git a/dojox/app/tests/scrollableTestApp/views/tablet/ViewScrollableLists.html b/dojox/app/tests/scrollableTestApp/views/tablet/ViewScrollableLists.html
new file mode 100644
index 0000000..39d8e00
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/tablet/ViewScrollableLists.html
@@ -0,0 +1,78 @@
+<div>
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<!-- left -->
+	<div data-dojo-type="dojox/app/widgets/Container" class="navPane" data-app-constraint="left">
+		<h1 id="tab1WrapperA" style="visibility:hidden" data-dojo-type="dojox/mobile/Heading" data-app-constraint="top">
+			Select Scrollable List</h1>
+
+		<div id="tab1WrapperB" style="visibility:hidden"
+			 data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center"
+			 data-dojo-props="scrollable: true">
+			<ul data-dojo-type="dojox/mobile/RoundRectList" data-dojo-props='variableHeight:true'>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'TestInfo', url: '#TestInfo'">
+					<div class="textBox">
+						<div class="subject">Test Instructions</div>
+						Test instructions, notes and known problems (transition none)
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable1', url: '#Scrollable1'">
+					<div class="textBox">
+						<div class="subject">Scrollable list One</div>
+						Uses app/widgets/Container with a fixed Header and a fixed Footer both with data-app-constraint
+						(transition slide)
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable1P', url: '#Scrollable1P'">
+					<div class="textBox">
+						<div class="subject">Scrollable list OneP</div>
+						Programmatic creation of WidgetList uses app/widgets/Container with a fixed Header and a fixed
+						Footer both with data-app-constraint (transition flip)
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable2', url: '#Scrollable2'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Two</div>
+						Uses app/widgets/Container with a fixed Header and a fixed Footer both with data-app-constraint
+						(transition fade)
+					</div>
+				</li>
+
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable3', url: '#Scrollable3'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Three</div>
+						Uses app/widgets/Container with a fixed Header no footer with data-app-constraint
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, transition:'fade', target: 'Scrollable4', url: '#Scrollable4'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Four</div>
+						Uses dojox/mobile/ScrollableView (removed height="auto") with a fixed Header and a fixed Footer
+						(transition event fade)
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, transition:'flip', target: 'Scrollable5', url: '#Scrollable5'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Five</div>
+						Uses dojox/mobile/ScrollableView (removed height="auto") with a fixed Header and No Footer
+						(transition event flip)
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'ListItemDomButtons', url: '#ListItemDomButtons'">
+					<div class="textBox">
+						<div class="subject">Dojox Mobile Test</div>
+						A copy of the dojox/mobile test test_ListItemDomButtons, (removed height="auto"), had used it to
+						avoid problem with initially showing this page.
+					</div>
+				</li>
+			</ul>
+		</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/scrollableTestApp/views/tablet/ViewScrollableLists.js b/dojox/app/tests/scrollableTestApp/views/tablet/ViewScrollableLists.js
new file mode 100755
index 0000000..71f3aec
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp/views/tablet/ViewScrollableLists.js
@@ -0,0 +1,26 @@
+define([], function(){
+	return {
+		init: function(){
+			console.log("navigation view init ok");
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+			console.log("ViewScrollableLists view beforeActivate called");
+		// this will be done in the other views, since beforeActivate is not called for the left view...
+		//	if(dom.byId("tab1WrapperA")){ 
+		//		domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+		//		domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+		//	}
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+			console.log("ViewScrollableLists view beforeActivate called");
+		}
+		
+		
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp2/config.json b/dojox/app/tests/scrollableTestApp2/config.json
new file mode 100644
index 0000000..030986e
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/config.json
@@ -0,0 +1,200 @@
+{
+	"id": "scrollableTestApp2",
+	"name": "Scrollable Test App2",
+	"description": "This is a test app for scrollable lists.",
+	"splash": "splash",
+
+	"loaderConfig": {
+		"paths": {
+			"scrollableTestApp": "../dojox/app/tests/scrollableTestApp2"
+		}
+	},
+
+	// Array of AMD modules identifiers. When defined at the top level dependencies of the dojox/app application. 
+	// When defined at view level, dependencies for the view.
+	"dependencies": [
+		"dojox/mobile/_base",
+		"dojox/mobile/_compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/TextBox",
+		"dojox/mobile/Button",
+		"dojox/mobile/Heading",
+		"dojox/mobile/ListItem",
+		"dojox/mobile/RoundRectList",
+		"dojox/mobile/RoundRectCategory",
+		"dojox/app/widgets/Container",
+		"dojo/data/ItemFileWriteStore",
+		"dojo/store/DataStore",
+		"dojox/app/utils/mvcModel",
+		"dojox/mvc/EditStoreRefListController",
+		"dojox/mvc/Repeat",
+		"dojox/mvc/WidgetList",
+		"dojox/mvc/Templated",
+		"dojox/mvc/_InlineTemplateMixin",
+		"dojox/mobile/ScrollableView",
+		"dojox/mvc/Group",
+		"dojox/mvc/Output",
+		"dojox/mvc/at"
+	],
+	// Modules for the application.  They are basically used as the second
+	// array of mixins in a dojo.declare().  Modify the top level behavior
+	// of the application, how it processes the config or any other life cycle
+	// by creating and including one or more of these
+	"modules": [
+		"scrollableTestApp/scrollableTestApp"
+	],
+
+	// Array of AMD modules identifiers. Controllers for the application. All the controllers defined here will be 
+	// loaded during application startup to respond to application events and controller the application logic. 
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],	
+
+	// Dojo stores which are used by dojox/app to setup data models. A store item is an object with a
+	// a type and a params property. The type property is the AMD module identifier for the store class to be
+	// instantiated. The content of the params property is passed to the store class constructor to build an 
+	// instance. 
+	"stores": {
+		"repeatStore":{
+			"type": "dojo/data/ItemFileWriteStore",
+			"params": {
+				"url": "./resources/data/repeat.json"
+			}
+	   }
+	},
+
+	// Models and their instantiation parameters. A model item is an object with three properties: the 
+	// model type, the modelLoader and the params. The modelLoader property defines whether an MVC or a
+	// simple model must be loaded. The type property defines which class must be used for that model using
+	// an AMD module identifier and finally the params property content is passed to the model class 
+	// constructor to build an instance.
+	"models": {
+		"repeatmodels": {
+       					"modelLoader": "dojox/app/utils/mvcModel",
+						"type": "dojox/mvc/EditStoreRefListController",
+						"params":{
+							"datastore": {"$ref":"#stores.repeatStore"}
+						}
+		}
+	},
+	
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"phone" : {
+			//The name(s) of the view(s) to load when the application is initialized.
+			"defaultView": "configuration"
+		},
+		"!phone" : {
+			"defaultView": "configuration+TestInfo"
+		},
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+	// defaultTransition: The default animation type for the view transition.
+	// the defaultTransition is only used if transition is not set in the config and the transition is not set or 
+	// defaulted on the transitionEvent
+	// These are the possible defaultTransitions, 
+	//"defaultTransition": "slide",
+	//"defaultTransition": "none",
+	//"defaultTransition": "fade",
+	"defaultTransition": "flip",     // Note: flip does not work with a BorderLayout Controller
+
+	// transition: The animation type to use for all view transitions.
+	// if a transition is set on a view or parent it will override the transition set on the transitionEvent or the defaultTransition in the config.
+	//"transition": "slide",
+
+	// views: The children views of an application or of a view. Dependencies may be defined on views for
+	// optimization and organization purposes. Models might also be defined on views if they are view-specific
+	// Finally a view item as three additional properties: transition for specific view transitions, template for
+	// defining the view rendering and finally controller to provide an AMD module to be mixed into the view to 
+	// control it. AMD modules identifiers starting with “.” will be resolved relative to the application root. All other
+	// modules identifiers will be resolved according to the Dojo AMD loader rules and in particular with respect
+	// to its configuration provided as part of the loaderConfig attribute. If you do not want a controller
+	// module at all you should not specify one, setting it to none will no longer work.
+	"views": {
+		"navigation": {
+			"template": "scrollableTestApp/views/tablet/ViewScrollableLists.html",
+			"controller" : "scrollableTestApp/views/tablet/ViewScrollableLists.js",
+			"transition": "slide",
+			"constraint" : "left"
+		},
+		"configuration": {
+				"template": "scrollableTestApp/views/configuration/ScrollableListSelection.html",
+				"controller": "scrollableTestApp/views/configuration/ScrollableListSelection.js",
+				"has" : {
+					"phone" : {
+						"constraint" : "center"
+					},
+					"!phone" : { 
+						"constraint" : "left"
+					}	
+				}
+		},
+		
+		"TestInfo": {
+			"transition": "none",
+			"controller": "scrollableTestApp/views/TestInfo.js",
+			"template": "scrollableTestApp/views/TestInfo.html"
+		},
+		"Scrollable1": {
+			"transition": "slide",
+			"controller": "scrollableTestApp/views/Scrollable1.js",
+			"template": "scrollableTestApp/views/Scrollable1.html"
+		},
+		"Scrollable1P": {
+			"controller": "scrollableTestApp/views/Scrollable1P.js",
+			"template": "scrollableTestApp/views/Scrollable1P.html",
+			"transition": "flip",
+			"constraint" : "center"
+		},
+		"Scrollable2": {
+			"controller": "scrollableTestApp/views/Scrollable2.js",
+			"template": "scrollableTestApp/views/Scrollable2.html",
+			"transition": "fade",
+			"constraint" : "center"
+		},
+		"Scrollable3": {
+			"controller": "scrollableTestApp/views/Scrollable3.js",
+			"template": "scrollableTestApp/views/Scrollable3.html",
+			"constraint" : "center"
+		},
+		"Scrollable4": {
+			"controller": "scrollableTestApp/views/Scrollable4.js",
+			"template": "scrollableTestApp/views/Scrollable4.html",
+			"constraint" : "center"
+		},
+		"Scrollable5": {
+			"controller": "scrollableTestApp/views/Scrollable5.js",
+			"template": "scrollableTestApp/views/Scrollable5.html"
+		},
+		"ListItemDomButtons": {
+			"controller": "scrollableTestApp/views/ListItem-domButtons",
+			"template": "scrollableTestApp/views/ListItem-domButtons.html",
+			"constraint" : "center"
+		},
+		"ListItemDomButtons2": {
+			"template": "scrollableTestApp/views/ListItem-domButtons2.html",
+			"constraint" : "center"
+		},
+		
+		"repeatDetails": {
+			"controller": "scrollableTestApp/views/repeatDetails.js",
+			"template": "scrollableTestApp/views/repeatDetails.html",
+			"transition": "slide",
+			"constraint" : "center"
+		}
+	}
+}
diff --git a/dojox/app/tests/scrollableTestApp2/css/demo.css b/dojox/app/tests/scrollableTestApp2/css/demo.css
new file mode 100644
index 0000000..2e49304
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/css/demo.css
@@ -0,0 +1,12 @@
+html,body {
+	width: 100%;
+	height: 100%;
+	background-color: black;
+}
+.lineItemPreventTouch {
+	width:2.5em;
+	height:3em; 
+	position:absolute; 
+	margin-left: -8px;
+	margin-top: -11px;
+}
diff --git a/dojox/app/tests/scrollableTestApp2/css/tablet.css b/dojox/app/tests/scrollableTestApp2/css/tablet.css
new file mode 100644
index 0000000..b13bfcf
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/css/tablet.css
@@ -0,0 +1,81 @@
+#header button {
+	position:absolute;
+	margin:0;
+}
+
+#navButton {
+	width:60px;
+}
+
+#loadDiv {
+	position:absolute;
+	left:0;
+	top:0;
+	width:100%;
+	height:100%;
+	z-index:999;
+}
+#loadDiv {
+	display:table;
+	font-size: 20px;
+	text-align:center;
+	background-color:white;
+}
+#loadDiv span {
+	display:table-cell;
+	vertical-align:middle;
+}
+
+body .mblProgContainer {
+	top:45%;
+	height: 45px;
+	width: 140px;
+	margin-left:-70px;
+	background-color: #2A2A28;
+	border-style: solid;
+	border-width: 2px;
+	border-color: #666666;
+	border-radius: 0.4em;
+	-webkit-border-radius: 0.4em;
+	-moz-border-radius: 0.4em;
+}
+
+body .mblProgContainer > div {
+	height: 100%;
+	width: 100%;
+	line-height: 45px;
+	vertical-align: middle;
+	font-size: 20px;
+	color: #c2c2c2;
+}
+
+body .mblProg {
+	left: 3px;
+	top: 3px;
+}
+
+body .mblProgContainer > div::after {
+	padding-left: 42px;
+	content: "Updating...";
+}
+
+#jsContent, #htmlContent {
+	padding-left:2px;
+}
+
+ at media screen and (max-width: 600px) {
+	#jsContent, #htmlContent {
+		font-size: 14px;
+	}
+}
+
+.hidden {
+	display:none;
+}
+
+div .navPane {
+	width:250px;
+	border-right:1px solid black;
+	background-color: #C5CCD3;
+	z-index:100;
+}
diff --git a/dojox/app/tests/scrollableTestApp2/index.html b/dojox/app/tests/scrollableTestApp2/index.html
new file mode 100644
index 0000000..5ba16a9
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/index.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes"/>		
+		<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
+		<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">		
+		<title>Scrollable Test App</title>
+		<link rel="stylesheet" type="text/css" href="css/tablet.css">
+	<!--	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/> -->
+		<link type="text/css" href="css/demo.css" rel="stylesheet">
+	<style>
+	.subject {
+		font: bold 16px Helvetica;
+	}
+	.textBox {
+		font-size: 12px; 
+		font-weight: normal;
+		overflow: hidden;
+	}
+	</style>
+	
+		
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"
+   					data-dojo-config="mblThemeFiles:['@theme',['dojox/app/tests/scrollableTestApp','todo']]"></script>
+
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false,
+				mblHideAddressBar: true,
+				mblAndroidWorkaround: false,
+				mblAlwaysHideAddressBar: true,
+				app: {debugApp: 1},  // set debugApp to log app transtions and view activate/deactivate
+				mvc: {debugBindings: 0},  // set on to debug mvc data bindings
+				async: 1">
+		</script>
+		<script>
+			require(["./src.js"], function(){
+			});
+		</script>
+		
+	</head>
+	<body style="overflow-y:hidden; overflow-x:hidden;">
+	</body>
+</html>
diff --git a/dojox/app/tests/scrollableTestApp2/resources/data/repeat.json b/dojox/app/tests/scrollableTestApp2/resources/data/repeat.json
new file mode 100644
index 0000000..191b80b
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/resources/data/repeat.json
@@ -0,0 +1,105 @@
+{
+  "identifier": "Serial",
+   "items": [ 
+                    {
+                        "Serial"  : "A111",
+                        "First"   : "Anne",
+                        "Last"    : "Ackerman",
+                        "Location": "NY",
+                        "Office"  : "1S76",
+                        "Email"   : "a.a at test.com",
+                        "Tel"     : "123-764-8237",
+                        "Fax"     : "123-764-8228"
+                    },
+                    {
+                        "Serial"  : "B111",
+                        "First"   : "Ben",
+                        "Last"    : "Beckham",
+                        "Location": "NY",
+                        "Office"  : "5N47",
+                        "Email"   : "b.b at test.com",
+                        "Tel"     : "123-764-8599",
+                        "Fax"     : "123-764-8600"
+                    },
+                    {
+                        "Serial"  : "C111",
+                        "First"   : "Chad",
+                        "Last"    : "Chapman",
+                        "Location": "CA",
+                        "Office"  : "1278",
+                        "Email"   : "c.c at test.com",
+                        "Tel"     : "408-764-8237",
+                        "Fax"     : "408-764-8228"
+                    },
+                    {
+                        "Serial"  : "D111",
+                        "First"   : "David",
+                        "Last"    : "Durham",
+                        "Location": "NJ",
+                        "Office"  : "C12",
+                        "Email"   : "d.d at test.com",
+                        "Tel"     : "514-764-8237",
+                        "Fax"     : "514-764-8228"
+                    },
+                    {
+                        "Serial"  : "E111",
+                        "First"   : "Emma",
+                        "Last"    : "Eklof",
+                        "Location": "NY",
+                        "Office"  : "4N76",
+                        "Email"   : "e.e at test.com",
+                        "Tel"     : "123-764-1234",
+                        "Fax"     : "123-764-4321"
+                    },
+                    {
+                        "Serial"  : "F111",
+                        "First"   : "Fred",
+                        "Last"    : "Fisher",
+                        "Location": "NJ",
+                        "Office"  : "V89",
+                        "Email"   : "f.f at test.com",
+                        "Tel"     : "514-764-8567",
+                        "Fax"     : "514-764-8000"
+                    },
+                    {
+                        "Serial"  : "G111",
+                        "First"   : "George",
+                        "Last"    : "Garnett",
+                        "Location": "NY",
+                        "Office"  : "7S11",
+                        "Email"   : "gig at test.com",
+                        "Tel"     : "123-999-8599",
+                        "Fax"     : "123-999-8600"
+                    },
+                    {
+                        "Serial"  : "H111",
+                        "First"   : "Hunter",
+                        "Last"    : "Huffman",
+                        "Location": "CA",
+                        "Office"  : "6532",
+                        "Email"   : "h.h at test.com",
+                        "Tel"     : "408-874-8237",
+                        "Fax"     : "408-874-8228"
+                    },
+                    {
+                        "Serial"  : "I111",
+                        "First"   : "Irene",
+                        "Last"    : "Ira",
+                        "Location": "NJ",
+                        "Office"  : "F09",
+                        "Email"   : "i.i at test.com",
+                        "Tel"     : "514-764-6532",
+                        "Fax"     : "514-764-7300"
+                    },
+                    {
+                        "Serial"  : "J111",
+                        "First"   : "John",
+                        "Last"    : "Jacklin",
+                        "Location": "CA",
+                        "Office"  : "6701",
+                        "Email"   : "j.j at test.com",
+                        "Tel"     : "408-764-1234",
+                        "Fax"     : "408-764-4321"
+                    }
+                ]
+}
diff --git a/dojox/app/tests/scrollableTestApp2/scrollableTestApp.js b/dojox/app/tests/scrollableTestApp2/scrollableTestApp.js
new file mode 100644
index 0000000..78ca218
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/scrollableTestApp.js
@@ -0,0 +1,67 @@
+define(["dojox/mobile/ProgressIndicator", "dojox/mobile/TransitionEvent", "dojox/mvc/getStateful"], function(ProgressIndicator, TransitionEvent, getStateful){
+	return function(){
+		// the default select_item is 0, or will throw an error if directly transition to #details,EditTodoItem view
+		this.selected_item = 0;
+		this.selected_configuration_item = 0;
+		this.progressIndicator = null;
+		/*
+	 	* show or hide global progress indicator
+	 	*/
+	 	
+	 	// show an item detail
+		this.setDetailsContext = function(index){
+			if(this.loadedModels.repeatmodels) {
+				this.loadedModels.repeatmodels.set("cursorIndex", index);
+			}		
+		};
+
+		// global for call from template
+		this.removeScrollableItem = function(index){
+				this.loadedModels.repeatmodels.model.splice(index, 1);
+				return false; 	 		
+		};
+
+		// insert an item
+		this.insertResult = function(index, e){
+			var repeatmodel = this.loadedModels.repeatmodels;
+			if(index<0 || index>repeatmodel.model.length){
+				throw Error("index out of data model.");
+			}
+			if((repeatmodel.model[index].First=="") ||
+				(repeatmodel.model[index+1] && (repeatmodel.model[index+1].First == ""))){
+				return;
+			}
+			var data = {id:Math.random(), "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+			repeatmodel.model.splice(index+1, 0, new getStateful(data));
+			this.setDetailsContext(index+1);
+			var transOpts = {
+				title : "repeatDetails",
+				target : "repeatDetails",
+				url : "#repeatDetails", // this is optional if not set it will be created from target   
+				params : {"cursor":index+1}
+			};
+			new TransitionEvent(e.target, transOpts, e).dispatch(); 
+			
+		};
+
+	 	
+		this.showProgressIndicator = function(show){
+				
+			if(!this.progressIndicator){
+				this.progressIndicator = ProgressIndicator.getInstance({removeOnStop:false, startSpinning:true, size:40, center:true, interval:30});
+				// TODO: use dojo.body will throw no appendChild method error.
+				var body = document.getElementsByTagName("body")[0];
+				body.appendChild(this.progressIndicator.domNode);
+				this.progressIndicator.domNode.style.zIndex = 999;
+			}
+			if(show){
+				this.progressIndicator.domNode.style.visibility = "visible";
+				this.progressIndicator.start();
+			}else{
+				this.progressIndicator.stop();
+				this.progressIndicator.domNode.style.visibility = "hidden";
+			}
+			
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp2/src.js b/dojox/app/tests/scrollableTestApp2/src.js
new file mode 100644
index 0000000..fb34be8
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/src.js
@@ -0,0 +1,15 @@
+require(["dojox/app/main", "dojox/json/ref", "dojo/sniff"],
+	function(Application, json, has){
+
+	var configurationFile = "./config.json";
+
+	require(["dojo/text!"+configurationFile], function(configJson){
+		var config = json.fromJson(configJson);
+		var width = window.innerWidth || document.documentElement.clientWidth;
+		if(width <= 600){
+			has.add("phone", true);
+		}
+		has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+		Application(config);
+	});
+});
diff --git a/dojox/app/tests/scrollableTestApp2/themes/android/todo.css b/dojox/app/tests/scrollableTestApp2/themes/android/todo.css
new file mode 100644
index 0000000..616a45c
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/themes/android/todo.css
@@ -0,0 +1,25 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  padding-left: 5px;
+  padding-top: 16px;
+  padding-bottom: 16px;
+  padding-right: 1px;
+
+  font-size: 21px;
+  color: white;
+
+  border: 1px solid #ADAAAD;
+  border-radius: 8px;
+  background-color: black;
+}
+div .navPane {
+	background-color: black !important;
+	border-right: 1px solid #ADAAAD !important;
+}
+button.baseBtn {
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  height: 48px;
+  margin-bottom: 6px;
+}
diff --git a/dojox/app/tests/scrollableTestApp2/themes/blackberry/todo.css b/dojox/app/tests/scrollableTestApp2/themes/blackberry/todo.css
new file mode 100644
index 0000000..6d5ec0e
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/themes/blackberry/todo.css
@@ -0,0 +1,21 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  font-size: 18px;
+
+  padding-top: 16px;
+  padding-bottom: 16px;
+  padding-left: 7px;
+  
+  border: 1px solid #c6c7c6;
+  border-radius: 6px;
+  background-color: white;
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 0;
+}
+button.baseBtn {
+  font-size: 18px;
+  height: 48px;
+  margin-bottom: 8px;
+}
diff --git a/dojox/app/tests/scrollableTestApp2/themes/iphone/todo.css b/dojox/app/tests/scrollableTestApp2/themes/iphone/todo.css
new file mode 100644
index 0000000..21f9cb0
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/themes/iphone/todo.css
@@ -0,0 +1,31 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  color: #324f85;
+  
+  padding-left: 8px;
+  padding-right: 1px;
+  padding-top: 10px;
+  padding-bottom: 10px;
+
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
+  border-bottom-style: solid;
+  border-bottom-color: #ADAAAD;
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 0;
+}
+button.baseBtn {
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  height: 40px;
+  margin-bottom: 8px;
+}
diff --git a/dojox/app/tests/scrollableTestApp2/views/ListItem-domButtons.html b/dojox/app/tests/scrollableTestApp2/views/ListItem-domButtons.html
new file mode 100644
index 0000000..c3d5a1f
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/ListItem-domButtons.html
@@ -0,0 +1,106 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+<!--
+			<div data-dojo-type="dojox/mobile/Heading" data-dojo-props='fixed:"top", data-app-constraint="top",
+-->
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='fixed:"top", 
+							label:"Mobile Scrollable Test."'>
+			<span id="mli1back" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+			data-dojo-props="target: 'configuration', url: '#configuration', transitionDir: -1">Back</span>
+		</h1>
+
+		<h2 data-dojo-type="dojox/mobile/RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox/mobile/RoundRect">
+			header: Mobile Scrollable Test<br>
+			footer: application-footer<br>
+			scrollDir: vertical with 27 items
+		</div>
+
+		<ul data-dojo-type="dojox/mobile/RoundRectList">
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-1.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 1
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-2.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 2
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-3.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 3
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-4.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 4
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-5.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 5
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-6.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 6
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-7.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 7
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-8.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 8
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-9.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 9
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-1.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 10
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-2.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 11
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-3.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 12
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-4.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 13
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-5.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 14
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-6.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 15
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-7.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 16
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-8.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 17
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-9.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 18
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-7.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 19
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-8.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 20
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-9.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 21
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-7.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 22
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-8.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 23
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-9.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 24
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-7.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"slide"'>
+				Slide 25
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-8.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"flip"'>
+				Flip 26
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../../mobile/tests/images/i-icon-9.png", target: "ListItemDomButtons2", url: "#ListItemDomButtons2", transition:"fade"'>
+				Fade 27
+			</li>
+		</ul>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Application Footer Bar</h1>
+
+</div>
diff --git a/dojox/app/tests/scrollableTestApp2/views/ListItem-domButtons.js b/dojox/app/tests/scrollableTestApp2/views/ListItem-domButtons.js
new file mode 100644
index 0000000..f590f16
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/ListItem-domButtons.js
@@ -0,0 +1,35 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dijit/registry", "dojox/mvc/at", "dojox/mobile/TransitionEvent", "dojox/mvc/Repeat", 
+		"dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, registry, at, TransitionEvent, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+
+	return {
+		// repeat view init
+		init: function(){
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId("mli1back") && !has("phone")){ 
+				domStyle.set(dom.byId("mli1back"), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		
+		// view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp2/views/ListItem-domButtons2.html b/dojox/app/tests/scrollableTestApp2/views/ListItem-domButtons2.html
new file mode 100644
index 0000000..2e0debf
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/ListItem-domButtons2.html
@@ -0,0 +1,42 @@
+<div class="view mblView">
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='fixed:"top", back:"Back"'>Mobile Scrollable Test.</h1>
+		<ul data-dojo-type="dojox/mobile/RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox/mobile/ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Application Footer Bar</h1>
+
+</div>
diff --git a/dojox/app/tests/scrollableTestApp2/views/RoundRectWidListTemplate.html b/dojox/app/tests/scrollableTestApp2/views/RoundRectWidListTemplate.html
new file mode 100644
index 0000000..de9f2ba
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/RoundRectWidListTemplate.html
@@ -0,0 +1,8 @@
+<li data-dojo-type="dojox/mobile/ListItem">
+	<div data-dojo-type="dojox/mobile/ToolBarButton" 
+		data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+			onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+									scrollableTestApp2.removeScrollableItem(this.indexAtStartup); return false; }"
+		style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+	<div data-dojo-type="dojox/mvc/Output" style="display: inline" data-dojo-attach-point="titleNode"></div>		
+</li>
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable1.html b/dojox/app/tests/scrollableTestApp2/views/Scrollable1.html
new file mode 100644
index 0000000..a4398e2
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable1.html
@@ -0,0 +1,43 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List One"' data-app-constraint="top">
+		<span id="sc1back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="transitionOptions: {title: 'Configure', target: 'configuration', url: '#configuration', transitionDir: -1}">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1insert1x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1remove10x" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>     
+	<div data-app-constraint="top">
+		<div class="field-title">Should scroll between this text and the bottom footer.</div>
+	</div>     
+
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+	<div>
+	
+		<form name="repeatTestForm">    
+				<ul
+					data-dojo-type="dojox/mobile/RoundRectList"
+					data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: this.loadedModels.repeatmodels.model"
+					data-mvc-child-type="dojox/mvc/Templated"
+					data-mvc-child-mixins="dojox/mobile/ListItem"
+					data-mvc-child-props="clickable: true,
+							transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+							onClick: function(){scrollableTestApp2.setDetailsContext(this.indexAtStartup);}">					
+					<script type="dojox/mvc/InlineTemplate">
+						<li data-dojo-type="dojox/mobile/ListItem">
+							<div data-dojo-type="dojox/mobile/ToolBarButton" 
+								data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+								                 onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+								                 	        scrollableTestApp2.removeScrollableItem(this.indexAtStartup); return false; }"
+								style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+							<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'First')"></div>	
+						</li>
+					</script>
+				</ul>
+		</form>
+</div>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Scrollable List One Footer Bar'" data-app-constraint="bottom"></h1>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable1.js b/dojox/app/tests/scrollableTestApp2/views/Scrollable1.js
new file mode 100644
index 0000000..4967dbe
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable1.js
@@ -0,0 +1,86 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", 
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc1back1';
+	var insert1Id = 'sc1insert1x';
+	var insert10Id = 'sc1insert10x';
+	var remove10Id = 'sc1remove10x';
+
+	var app = null;
+
+	return {
+		// repeat view init
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", lang.hitch(this,function(e){
+				this.app.insertResult(repeatmodel.model.length-1,e);
+			}));
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable1P.html b/dojox/app/tests/scrollableTestApp2/views/Scrollable1P.html
new file mode 100644
index 0000000..3bf5f3b
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable1P.html
@@ -0,0 +1,23 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List OneP"' data-app-constraint="top">
+		<span id="sc1back1P" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="transitionOptions: {title: 'Configure', target: 'configuration', url: '#configuration', transitionDir: -1}">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1insert1xP" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1insert10xP" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc1remove10xP" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>     
+	<div data-app-constraint="top">
+		<div class="field-title">Should scroll between this text and the bottom footer.</div>
+	</div>     
+
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+		<div>	
+			<form name="repeatTestForm">   
+				<div id="addWidgetHere"></div>	 
+			</form>
+		</div>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Scrollable List OneP Footer Bar'" data-app-constraint="bottom"></h1>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable1P.js b/dojox/app/tests/scrollableTestApp2/views/Scrollable1P.js
new file mode 100644
index 0000000..a4e3c74
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable1P.js
@@ -0,0 +1,151 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang", "dojo/_base/declare", "dijit/registry", "dojox/mvc/at", 
+"dojox/mobile/TransitionEvent", "dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff", 
+"dojox/mobile/RoundRectList", "dojox/mvc/WidgetList", "dojox/mvc/Templated", "dojox/mobile/ListItem", "dojo/text!../views/RoundRectWidListTemplate.html"],
+function(dom, domStyle, connect, lang, declare, registry, at, TransitionEvent, Repeat, getStateful, Output, has, RoundRectList, WidgetList, Templated, 
+	ListItem, RoundRectWidListTemplate){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	var roundRectWidList = null;
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc1back1P';
+	var insert1Id = 'sc1insert1xP';
+	var insert10Id = 'sc1insert10xP';
+	var remove10Id = 'sc1remove10xP';
+
+	var app = null;
+
+	// insert an item
+	var insertResult = function(index, e){
+		if(index<0 || index>repeatmodel.model.length){
+			throw Error("index out of data model.");
+		}
+		if((repeatmodel.model[index].First=="") ||
+			(repeatmodel.model[index+1] && (repeatmodel.model[index+1].First == ""))){
+			return;
+		}
+		var data = {id:Math.random(), "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+		repeatmodel.model.splice(index+1, 0, new getStateful(data));
+		this.app.setDetailsContext(index+1);
+		var transOpts = {
+			title : "repeatDetails",
+			target : "repeatDetails",
+			url : "#repeatDetails", // this is optional if not set it will be created from target   
+			params : {"cursor":index+1}
+		};
+		new TransitionEvent(e.target, transOpts, e).dispatch(); 
+		
+	};
+	
+	var showListData = function(/*dojox/mvc/EditStoreRefListController*/ datamodel){
+		// summary:
+		//		create the WidgetList programatically if it has not been created, and 
+		//		set the children for items_list widget to the datamodel to show the items in the selected list.
+		//		RoundRectWidListTemplate is used for the templateString of the WidgetList.
+		//
+		// datamodel: dojox/mvc/EditStoreRefListController
+		//		The EditStoreRefListController whose model holds the items for the selected list.
+		//
+		if(!roundRectWidList){
+			var clz = declare([WidgetList, RoundRectList], {});
+			roundRectWidList = new clz({
+				children: at(datamodel, 'model'),
+				childClz: declare([Templated /* dojox/mvc/Templated module return value */, ListItem /* dojox/mobile/ListItem module return value */]),
+				childParams: {
+					transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+					clickable: true,
+					onClick: function(){
+						console.log("in onClick this.indexAtStartup="+this.indexAtStartup);
+						app.setDetailsContext(this.indexAtStartup);}
+				},
+				childBindings: {
+					titleNode: {value: at("rel:", "First")}
+				},
+				templateString: RoundRectWidListTemplate
+			});
+			roundRectWidList.placeAt(dom.byId("addWidgetHere"));
+			roundRectWidList.startup();
+		}else{
+			roundRectWidList.set("children", at(datamodel, 'model'));
+		}
+	};
+
+	return {
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", function(e){
+				app.insertResult(repeatmodel.model.length-1,e);
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+			
+			showListData(this.loadedModels.repeatmodels);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+			//domStyle.set(dom.byId(wrapperIdA), "visibility", "visible");  // show the view when it is ready
+			//domStyle.set(dom.byId(wrapperIdB), "visibility", "visible");  // show the view when it is ready
+			//domStyle.set(dom.byId(wrapperIdC), "visibility", "visible");  // show the view when it is ready
+			//domStyle.set(dom.byId(wrapperIdD), "visibility", "visible");  // show the view when it is ready
+
+			showListData(this.loadedModels.repeatmodels);			
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable2.html b/dojox/app/tests/scrollableTestApp2/views/Scrollable2.html
new file mode 100644
index 0000000..6b5c663
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable2.html
@@ -0,0 +1,41 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List Two"' data-app-constraint="top">
+		<span id="sc2back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="transitionOptions: {title: 'Configure', target: 'configuration', url: '#configuration', transitionDir: -1}">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc2insert1x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc2insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc2remove10x" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>
+
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+
+		<div class="field-title">Should scroll between the header and footer, this text will also scroll.</div>
+
+		<form name="repeatTestForm">
+				<ul
+					data-dojo-type="dojox/mobile/RoundRectList"
+					data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: this.loadedModels.repeatmodels.model"
+					data-mvc-child-type="dojox/mvc/Templated"
+					data-mvc-child-mixins="dojox/mobile/ListItem"
+					data-mvc-child-props="clickable: true,
+							transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+							onClick: function(){scrollableTestApp2.setDetailsContext(this.indexAtStartup);}">
+					<script type="dojox/mvc/InlineTemplate">
+						<li data-dojo-type="dojox/mobile/ListItem">
+							<div data-dojo-type="dojox/mobile/ToolBarButton"
+								data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+													onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+																		scrollableTestApp2.removeScrollableItem(this.indexAtStartup); return false; }"
+								style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+							<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'First')"></div>	
+						</li>
+					</script>
+				</ul>
+		</form>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Scrollable List Two Footer Bar'" data-app-constraint="bottom"></h1>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable2.js b/dojox/app/tests/scrollableTestApp2/views/Scrollable2.js
new file mode 100644
index 0000000..ee34df2
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable2.js
@@ -0,0 +1,81 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", 
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc2back1';
+	var insert1Id = 'sc2insert1x';
+	var insert10Id = 'sc2insert10x';
+	var remove10Id = 'sc2remove10x';
+
+	var app = null;
+
+	return {
+		// repeat view init
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", lang.hitch(this,function(e){
+				this.app.insertResult(repeatmodel.model.length-1,e);
+			}));
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable3.html b/dojox/app/tests/scrollableTestApp2/views/Scrollable3.html
new file mode 100644
index 0000000..cf79a97
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable3.html
@@ -0,0 +1,42 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List Three"' data-app-constraint="top">
+		<span id="sc3back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="transitionOptions: {title: 'Configure', target: 'configuration', url: '#configuration', transitionDir: -1}">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc3insert1x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc3insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc3remove10x" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>
+	<div data-app-constraint="top">
+	</div>
+
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+
+		<div class="field-title">Should scroll from under the top header to the end of the page, this text will also scroll.</div>
+
+		<form name="repeatTestForm">
+				<ul
+					data-dojo-type="dojox/mobile/RoundRectList"
+					data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: this.loadedModels.repeatmodels.model"
+					data-mvc-child-type="dojox/mvc/Templated"
+					data-mvc-child-mixins="dojox/mobile/ListItem"
+					data-mvc-child-props="clickable: true,
+							transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+							onClick: function(){scrollableTestApp2.setDetailsContext(this.indexAtStartup);}">
+					<script type="dojox/mvc/InlineTemplate">
+						<li data-dojo-type="dojox/mobile/ListItem">
+							<div data-dojo-type="dojox/mobile/ToolBarButton"
+								data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+													onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+																		scrollableTestApp2.removeScrollableItem(this.indexAtStartup); return false; }"
+								style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+							<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'First')"></div>	
+						</li>
+					</script>
+				</ul>
+		</form>
+	</div>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable3.js b/dojox/app/tests/scrollableTestApp2/views/Scrollable3.js
new file mode 100644
index 0000000..db4dc2a
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable3.js
@@ -0,0 +1,81 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", "dojox/mobile/TransitionEvent",
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, TransitionEvent, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc3back1';
+	var insert1Id = 'sc3insert1x';
+	var insert10Id = 'sc3insert10x';
+	var remove10Id = 'sc3remove10x';
+
+	var app = null;
+
+	return {
+		// repeat view init
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", lang.hitch(this,function(e){
+				this.app.insertResult(repeatmodel.model.length-1,e);
+			}));
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable4.html b/dojox/app/tests/scrollableTestApp2/views/Scrollable4.html
new file mode 100644
index 0000000..dc60e26
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable4.html
@@ -0,0 +1,43 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List Four", fixed:"top"'>
+		<span id="sc4back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="transitionOptions: {title: 'Configure', target: 'configuration', url: '#configuration', transitionDir: -1}">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc4insert1x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc4insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc4remove10x" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>
+	<div>
+		<div class="field-title">Should scroll between the top header and the bottom footer, this text will also scroll.</div>
+	</div>
+
+	
+		<form name="repeatTestForm">
+				<ul
+					data-dojo-type="dojox/mobile/RoundRectList"
+					data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: this.loadedModels.repeatmodels.model"
+					data-mvc-child-type="dojox/mvc/Templated"
+					data-mvc-child-mixins="dojox/mobile/ListItem"
+					data-mvc-child-props="clickable: true,
+							transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+							onClick: function(){scrollableTestApp2.setDetailsContext(this.indexAtStartup);}">
+					<script type="dojox/mvc/InlineTemplate">
+						<li data-dojo-type="dojox/mobile/ListItem">
+							<div data-dojo-type="dojox/mobile/ToolBarButton" 
+								data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+												onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+																		scrollableTestApp2.removeScrollableItem(this.indexAtStartup); return false; }"
+								style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+							<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'First')"></div>	
+						</li>
+					</script>
+				</ul>
+		</form>
+	</div>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Scrollable List Four Footer Bar', fixed:'bottom'"></h1>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable4.js b/dojox/app/tests/scrollableTestApp2/views/Scrollable4.js
new file mode 100644
index 0000000..6830f03
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable4.js
@@ -0,0 +1,81 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", 
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc4back1';
+	var insert1Id = 'sc4insert1x';
+	var insert10Id = 'sc4insert10x';
+	var remove10Id = 'sc4remove10x';
+
+	var app = null;
+
+	return {
+		// repeat view init
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", lang.hitch(this,function(e){
+				this.app.insertResult(repeatmodel.model.length-1,e);
+			}));
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable5.html b/dojox/app/tests/scrollableTestApp2/views/Scrollable5.html
new file mode 100644
index 0000000..c2a7835
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable5.html
@@ -0,0 +1,42 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Scrollable List Five", fixed:"top"'>
+		<span id="sc5back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		data-dojo-props="transitionOptions: {title: 'Configure', target: 'configuration', url: '#configuration', transitionDir: -1}">Back</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc5insert1x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">1</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc5insert10x" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;">10</span>
+		<span data-dojo-type="dojox/mobile/ToolBarButton" id="sc5remove10x" data-dojo-props='icon:"mblDomButtonWhiteMinus"' style="float:right;">10</span>
+
+	</h1>
+	<div>
+		<div class="field-title">Should scroll between the header and the end of the page, this text will also scroll.</div>
+	</div>
+
+	
+		<form name="repeatTestForm">
+				<ul
+					data-dojo-type="dojox/mobile/RoundRectList"
+					data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: this.loadedModels.repeatmodels.model"
+					data-mvc-child-type="dojox/mvc/Templated"
+					data-mvc-child-mixins="dojox/mobile/ListItem"
+					data-mvc-child-props="clickable: true,
+							transitionOptions: {title:'Details',target:'repeatDetails',url:'#repeatDetails',params:{'cursor':this.indexAtStartup}},
+							onClick: function(){scrollableTestApp2.setDetailsContext(this.indexAtStartup);}">
+					<script type="dojox/mvc/InlineTemplate">
+						<li data-dojo-type="dojox/mobile/ListItem">
+							<div data-dojo-type="dojox/mobile/ToolBarButton" 
+								data-dojo-props="icon: 'mblDomButtonRedCircleMinus',preventTouch: true, indexAtStartup: this.indexAtStartup,
+												onClick: function(e){ /*console.log(this); console.log(this.indexAtStartup);console.log(e);*/
+																scrollableTestApp2.removeScrollableItem(this.indexAtStartup); return false; }"
+								style="float: left; color: white; background-color: transparent; background-image: none; border: none;"></div>
+							<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'First')"></div>	
+						</li>
+					</script>
+				</ul>
+		</form>
+	</div>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp2/views/Scrollable5.js b/dojox/app/tests/scrollableTestApp2/views/Scrollable5.js
new file mode 100644
index 0000000..4262f50
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/Scrollable5.js
@@ -0,0 +1,81 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", 
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+	
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'sc5back1';
+	var insert1Id = 'sc5insert1x';
+	var insert10Id = 'sc5insert10x';
+	var remove10Id = 'sc5remove10x';
+
+	var app = null;
+
+	return {
+		// repeat view init
+		init: function(){
+			app = this.app;
+
+			repeatmodel = this.loadedModels.repeatmodels;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId(insert1Id), "click", lang.hitch(this,function(e){
+				this.app.insertResult(repeatmodel.model.length-1,e);
+			}));
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(insert10Id), "click", function(){
+				//Add 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){
+					var maxentries = repeatmodel.model.length+10;
+					for(var i = repeatmodel.model.length; i < maxentries; i++){
+						var data = {id:Math.random(), "First": "First"+repeatmodel.model.length, "Last": "Last"+repeatmodel.model.length, "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+						repeatmodel.model.splice(repeatmodel.model.length, 0, new getStateful(data));					
+					}
+					app.showProgressIndicator(false);
+				}), 100);				
+				
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId(remove10Id), "click", function(){
+				//remove 10 items to the end of the model
+				app.showProgressIndicator(true);
+				setTimeout(lang.hitch(this,function(){				
+					var maxentries = repeatmodel.model.length-10;
+					for(var i = repeatmodel.model.length; i >= maxentries; i--){
+						repeatmodel.model.splice(i, 1);
+					}
+					repeatmodel.set("cursorIndex", 0);		
+					app.showProgressIndicator(false);
+				}), 100);				
+			});
+			_connectResults.push(connectResult);
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp2/views/TestInfo.html b/dojox/app/tests/scrollableTestApp2/views/TestInfo.html
new file mode 100644
index 0000000..a7c1058
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/TestInfo.html
@@ -0,0 +1,27 @@
+<div class="view mblView">
+
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+
+	<div data-dojo-type="dojox/mobile/ScrollableView">
+
+		<h1 id="tst1WrapperA" style="visibility:hidden"
+			data-dojo-type="dojox/mobile/Heading" data-dojo-props='label:"Test Info for Scrollable tests.", fixed:"top"'>
+			<span id="ti1back1" data-dojo-type="dojox/mobile/ToolBarButton" arrow="left"
+				data-dojo-props="transitionOptions: {title: 'Configure', target: 'configuration', url: '#configuration', transitionDir: -1}">Back</span>
+		</h1>
+
+		<div id="tst1WrapperB" style="visibility:hidden">
+			<div class="field-title">Each test will indicate which area should scroll.</div>
+			<div class="field-title">Use the +10 or + icons to add data to enable scrolling if necessary.</div>
+			<br>
+			<div class="field-title">Be sure to test orientation changes or on browser resize.</div>
+			<div class="field-title">Verify that you can scroll to the top and bottom of the scrollable data.</div>
+			<div class="field-title">Also refresh the page for each scrollable view, had a problem without height="auto", but ended up removing height='auto' on a mobile ScrollableView</div>
+			<br><br>
+			<div class="field-title">Note that the tests which use <b>dojox/app/widgets/Container with scrollable:true</b> should use use headers or footers with data-app-constraint="top" or data-app-constraint="bottom" and they should not use headers and footers with fixed:'top' and fixed:'bottom'.</div>
+			<br>
+			<div class="field-title">Note that the tests which use <b>dojox/mobile/ScrollableView</b> should use headers and footers with fixed:'top' and fixed:'bottom' and they should not use headers or footers with data-app-constraint="top" or data-app-constraint="bottom".</div>
+			<br>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp2/views/TestInfo.js b/dojox/app/tests/scrollableTestApp2/views/TestInfo.js
new file mode 100644
index 0000000..2be8244
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/TestInfo.js
@@ -0,0 +1,46 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect", "dojo/_base/lang","dijit/registry", "dojox/mvc/at", "dojox/mobile/TransitionEvent", 
+		"dojox/mvc/Repeat", "dojox/mvc/getStateful", "dojox/mvc/Output", "dojo/sniff"],
+function(dom, domStyle, connect, lang, registry, at, TransitionEvent, Repeat, getStateful, Output, has){
+	var _connectResults = []; // events connect result
+
+	// these ids are updated here and in the html file to avoid duplicate ids
+	var backId = 'ti1back1';
+	var wrapperIdA = 'tst1WrapperA';
+	var wrapperIdB = 'tst1WrapperB';
+
+
+	return {
+		// repeat view init
+		init: function(){			
+		},
+
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			if(dom.byId(backId) && !has("phone")){ 
+				domStyle.set(dom.byId(backId), "visibility", "hidden"); // hide the back button in tablet mode
+			}
+			if(dom.byId("tab1WrapperA") && !has("phone")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+			domStyle.set(dom.byId(wrapperIdA), "visibility", "visible");  // show the view when it is ready
+			domStyle.set(dom.byId(wrapperIdB), "visibility", "visible");  // show the view when it is ready
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+		},
+		
+		
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/scrollableTestApp2/views/configuration/ScrollableListSelection.html b/dojox/app/tests/scrollableTestApp2/views/configuration/ScrollableListSelection.html
new file mode 100644
index 0000000..cfb086d
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/configuration/ScrollableListSelection.html
@@ -0,0 +1,70 @@
+<div class="view mblView navPane">
+	
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Scrollable List Selection'" data-app-constraint="top"></h1>
+	<h2 data-dojo-type="dojox/mobile/RoundRectCategory" data-app-constraint="top">Select a Scrollable List</h2>
+	<div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable: true">
+		
+		<div>
+			<ul data-dojo-type="dojox/mobile/RoundRectList"  data-dojo-props='variableHeight:true'>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'TestInfo', url: '#TestInfo'">
+					<div class="textBox">
+						<div class="subject">Test Instructions</div>
+						Test instructions, notes and known problems (transition none)				
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable1', url: '#Scrollable1'">
+					<div class="textBox">
+						<div class="subject">Scrollable list One</div>
+					Uses app/widgets/Container with a fixed Header and a fixed Footer both with data-app-constraint	 (transition slide)				
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable1P', url: '#Scrollable1P'">
+					<div class="textBox">
+						<div class="subject">Scrollable list OneP</div>
+						Programmatic creation of WidgetList uses app/widgets/Container with a fixed Header and a fixed Footer both with data-app-constraint  (transition flip)					
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable2', url: '#Scrollable2'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Two</div>
+					Uses app/widgets/Container with a fixed Header and a fixed Footer both with data-app-constraint  (transition fade)
+					</div>				
+				</li>
+			
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable3', url: '#Scrollable3'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Three</div>
+						Uses app/widgets/Container with a fixed Header no footer with data-app-constraint					
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+				data-dojo-props="clickable: true, noArrow: true, transition:'fade', target: 'Scrollable4', url: '#Scrollable4'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Four</div>
+					Uses dojox/mobile/ScrollableView (removed height="auto") with a fixed Header and a fixed Footer (transition event fade)					
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+				data-dojo-props="clickable: true, noArrow: true, transition:'flip', target: 'Scrollable5', url: '#Scrollable5'">
+					<div class="textBox">
+					<div class="subject">Scrollable list Five</div>
+					Uses dojox/mobile/ScrollableView (removed height="auto") with a fixed Header and No Footer (transition event flip)				
+					</div>				
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'ListItemDomButtons', url: '#ListItemDomButtons'">
+					<div class="textBox">
+						<div class="subject">Dojox Mobile Test</div>
+						A copy of the dojox/mobile test test_ListItemDomButtons, (removed height="auto"), had used it to avoid problem with initially showing this page.					
+					</div>				
+				</li>
+			</ul>
+		</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/scrollableTestApp2/views/configuration/ScrollableListSelection.js b/dojox/app/tests/scrollableTestApp2/views/configuration/ScrollableListSelection.js
new file mode 100644
index 0000000..5938f3c
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/configuration/ScrollableListSelection.js
@@ -0,0 +1,38 @@
+define([], function(){
+
+	var app = null;
+
+	return {
+		init: function(){
+			app = this.app;
+		},
+		
+		beforeActivate: function(){
+			if(app){
+				app.stopTransition = false;
+			}
+			//console.log("configuration/ScrollableListSelection beforeActivate called this.app.selected_configuration_item=",this.app.selected_configuration_item);
+		},
+		
+		afterActivate: function(){
+			//console.log("configuration/ScrollableListSelection afterActivate called this.app.selected_configuration_item=",this.app.selected_configuration_item);
+			//console.log("setting configurewrapper visible 1");
+			//domStyle.set(dom.byId("configurewrapper"), "visibility", "visible"); // show the items list
+		},
+		
+		beforeDeactivate: function(){
+			//console.log("configuration/ScrollableListSelection beforeDeactivate called this.app.selected_configuration_item=",this.app.selected_configuration_item);
+		},
+
+		afterDeactivate: function(){
+			//console.log("configuration/ScrollableListSelection afterDeactivate called this.app.selected_configuration_item=",this.app.selected_configuration_item);
+			//console.log("setting configurewrapper hidden");
+			//domStyle.set(dom.byId("configurewrapper"), "visibility", "hidden"); // hide the items list 
+		},
+
+		// view destroy, this destroy function can be removed since it is empty
+		destroy: function(){
+			// _WidgetBase.on listener is automatically destroyed when the Widget itself is. 
+		}
+	}
+});
diff --git a/dojox/app/tests/scrollableTestApp2/views/items.js b/dojox/app/tests/scrollableTestApp2/views/items.js
new file mode 100644
index 0000000..94b2e8e
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/items.js
@@ -0,0 +1,24 @@
+define(["dojo/_base/lang", "dojo/dom", "dojo/dom-style", "dijit/registry", "dojox/mobile/TransitionEvent", "dojo/sniff"],
+	function(lang, dom, domStyle, registry, TransitionEvent, has){
+	return {
+		init: function(){
+			if(!has("phone")){
+				domStyle.set(dom.byId("gotoConfigurationView"), "display", "none");
+			}
+/*
+			registry.byId("itemslist_add").on("click", lang.hitch(this, function(e){
+				// use selected_item = -1 to identify add a new item
+				this.app._addNewItem = true;
+
+				// transition to detail view for edit
+				var transOpts = {
+					title: "Detail",
+					target: "details,EditTodoItem",
+					url: "#details,EditTodoItem"
+				};
+				new TransitionEvent(e.target, transOpts, e).dispatch();
+			}));
+*/			
+		}
+	}
+});
diff --git a/dojox/app/tests/scrollableTestApp2/views/repeatDetails.html b/dojox/app/tests/scrollableTestApp2/views/repeatDetails.html
new file mode 100644
index 0000000..ea51f01
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/repeatDetails.html
@@ -0,0 +1,46 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='back:"Back"'>Repeat Details</h1>
+	<form name="repeatTestForm" id="repeatTestForm">    
+		<div data-dojo-type="dojox/mvc/Group" 
+			data-dojo-props="target: at(this.loadedModels.repeatmodels, 'cursor')">
+					<div class="field-title">
+						<div style="display: inline-block;" id="detailsBanner">Details for selected index:</div>
+						<span class="cell" id="indexOutput"
+							data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at(this.loadedModels.repeatmodels, 'cursorIndex')"></span>
+					</div>
+					<table id="table" cellspacing="10" style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'First'), placeholder:'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput" data-dojo-type="dojox/mobile/TextBox"
+									 
+									data-dojo-props="placeholder:'Last Name', value: at('rel:', 'Last')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput2" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Email'), placeholder:'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Tel'), placeholder:'Telephone'">
+							</td>
+						</tr>
+					</table>
+		</div>
+		</form>
+</div>
diff --git a/dojox/app/tests/scrollableTestApp2/views/repeatDetails.js b/dojox/app/tests/scrollableTestApp2/views/repeatDetails.js
new file mode 100644
index 0000000..630821c
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/repeatDetails.js
@@ -0,0 +1,34 @@
+define(["dojo/dom", "dojo/dom-style"],
+function(dom, domStyle){
+	var repeatmodel = null;	//repeat view data model
+
+	// show an item detail
+	var setDetailsContext = function(index){
+		// only set the cursor if it is different and valid
+		if(parseInt(index) != repeatmodel.cursorIndex && parseInt(index) < repeatmodel.model.length){
+			repeatmodel.set("cursorIndex", parseInt(index));
+		}
+	};
+
+	return {
+		// repeat view init
+		init: function(){
+			console.log("IN REPEATDETAILS");
+			repeatmodel = this.loadedModels.repeatmodels;
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			// if this.params["cursor"] is set use it to set the selected Details Context
+			if(this.params["cursor"]){
+				setDetailsContext(this.params["cursor"]);
+			}
+			if(dom.byId("tab1WrapperA")){ 
+				domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+				domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+			}
+		}
+	}
+});
diff --git a/dojox/app/tests/scrollableTestApp2/views/tablet/ViewScrollableLists.html b/dojox/app/tests/scrollableTestApp2/views/tablet/ViewScrollableLists.html
new file mode 100644
index 0000000..bceabbf
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/tablet/ViewScrollableLists.html
@@ -0,0 +1,78 @@
+<div class="navPane">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<!-- left -->
+	<div data-dojo-type="dojox/app/widgets/Container" class="navPane" data-app-constraint="left">
+		<h1 id="tab1WrapperA" style="visibility:hidden" data-dojo-type="dojox/mobile/Heading" data-app-constraint="top">
+			Select Scrollable List</h1>
+
+		<div id="tab1WrapperB" style="visibility:hidden"
+			 data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center"
+			 data-dojo-props="scrollable: true">
+			<ul data-dojo-type="dojox/mobile/RoundRectList" data-dojo-props='variableHeight:true'>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'TestInfo', url: '#TestInfo'">
+					<div class="textBox">
+						<div class="subject">Test Instructions</div>
+						Test instructions, notes and known problems (transition none)
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable1', url: '#Scrollable1'">
+					<div class="textBox">
+						<div class="subject">Scrollable list One</div>
+						Uses app/widgets/Container with a fixed Header and a fixed Footer both with data-app-constraint
+						(transition slide)
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable1P', url: '#Scrollable1P'">
+					<div class="textBox">
+						<div class="subject">Scrollable list OneP</div>
+						Programmatic creation of WidgetList uses app/widgets/Container with a fixed Header and a fixed
+						Footer both with data-app-constraint (transition flip)
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable2', url: '#Scrollable2'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Two</div>
+						Uses app/widgets/Container with a fixed Header and a fixed Footer both with data-app-constraint
+						(transition fade)
+					</div>
+				</li>
+
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'Scrollable3', url: '#Scrollable3'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Three</div>
+						Uses app/widgets/Container with a fixed Header no footer with data-app-constraint
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, transition:'fade', target: 'Scrollable4', url: '#Scrollable4'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Four</div>
+						Uses dojox/mobile/ScrollableView (removed height="auto") with a fixed Header and a fixed Footer
+						(transition event fade)
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, transition:'flip', target: 'Scrollable5', url: '#Scrollable5'">
+					<div class="textBox">
+						<div class="subject">Scrollable list Five</div>
+						Uses dojox/mobile/ScrollableView (removed height="auto") with a fixed Header and No Footer
+						(transition event flip)
+					</div>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-props="clickable: true, noArrow: true, target: 'ListItemDomButtons', url: '#ListItemDomButtons'">
+					<div class="textBox">
+						<div class="subject">Dojox Mobile Test</div>
+						A copy of the dojox/mobile test test_ListItemDomButtons, (removed height="auto"), had used it to
+						avoid problem with initially showing this page.
+					</div>
+				</li>
+			</ul>
+		</div>
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/scrollableTestApp2/views/tablet/ViewScrollableLists.js b/dojox/app/tests/scrollableTestApp2/views/tablet/ViewScrollableLists.js
new file mode 100755
index 0000000..1d07226
--- /dev/null
+++ b/dojox/app/tests/scrollableTestApp2/views/tablet/ViewScrollableLists.js
@@ -0,0 +1,27 @@
+define([], function(){
+
+	return {
+		init: function(){
+			console.log("navigation view init ok");
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+			console.log("ViewScrollableLists view beforeActivate called");
+		// this will be done in the other views, since beforeActivate is not called for the left view...
+		//	if(dom.byId("tab1WrapperA")){ 
+		//		domStyle.set(dom.byId("tab1WrapperA"), "visibility", "visible");  // show the nav view if it being used
+		//		domStyle.set(dom.byId("tab1WrapperB"), "visibility", "visible");  // show the nav view if it being used
+		//	}
+		},
+
+		afterActivate: function(){
+			// summary:
+			//		view life cycle afterActivate()
+			console.log("ViewScrollableLists view beforeActivate called");
+		}
+		
+		
+	};
+});
diff --git a/dojox/app/tests/simpleModelApp/config.json b/dojox/app/tests/simpleModelApp/config.json
new file mode 100755
index 0000000..fbbd8e5
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/config.json
@@ -0,0 +1,260 @@
+{
+	"id": "simpleModelApp",
+	"name": "Simple Model App",
+	"description": "A simple app to show how to use different types of Stores and Models",
+	"splash": "splash",
+
+	"dependencies": [
+		"dojox/mobile/_base",
+		"dojox/app/widgets/Container",
+		"dojox/mobile/compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/Heading",
+		"dojo/store/Memory",
+		"dojo/store/JsonRest",
+		"dojo/store/Memory",
+		"dojo/data/ItemFileWriteStore",
+	 	"dojo/store/DataStore",
+		"dojox/app/utils/simpleModel",
+		"dojox/app/utils/mvcModel",
+		"dojox/mvc/EditStoreRefListController",
+		"dojox/mvc/EditModelRefController",
+		"dojox/mobile/deviceTheme"
+	],
+	// Modules for the application.  The are basically used as the second
+	// array of mixins in a dojo.declare().  Modify the top level behavior
+	// of the application, how it processes the config or any other life cycle
+	// by creating and including one or more of these
+	"modules": [],
+
+	// Array of AMD modules identifiers. Controllers for the application. All the controllers defined here will be 
+	// loaded during application startup to respond to application events and controller the application logic. 
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/controllers/Layout"
+	],	
+
+	//stores we are using 
+	"stores": {
+		"namesStore":{
+			"type": "dojo/store/Memory",
+			"params": {
+				"data": "modelApp.names"
+			}
+		},
+		"repeatStore":{
+			"type": "dojo/store/Memory",
+			"params": {
+				"data": "modelApp.repeatData"
+			}
+		},
+		"repeatItemStore":{
+			"type": "dojo/data/ItemFileWriteStore",
+			"params": {
+				"url": "./resources/data/repeat.json"
+			}
+		},
+		"nameItemStore":{
+			"type": "dojo/data/ItemFileWriteStore",
+			"params": {
+				"url": "./resources/data/names2.json"
+			}
+		},
+		// note that a jsonRest store requires the data be in a different format...
+		"jsonStore":{
+			"type": "dojo/store/JsonRest",
+			"params": {
+				"target": "./resources/data/jsonRestRepeatData.json"
+			}
+		},
+		// note that a jsonRest store requires the data be in a different format...
+		"jsonNameStore":{
+			"type": "dojo/store/JsonRest",
+			"params": {
+				"target": "./resources/data/jsonRestNamesData.json"
+			}
+		}
+	},
+
+	//models and instantiation parameters for the models. Including 'type' as a property allows
+	//one to override the class that will be used for the model.  By default it is dojox/mvc/mvcModel
+	"models": {
+		"namesXUnused": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"store": {"$ref":"#stores.namesStore"}
+					}
+		},
+		"repeatmodels3": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"datastore": {"$ref":"#stores.repeatItemStore"}
+					}
+		},
+		"jsonRestModel": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"store": {"$ref":"#stores.jsonStore"},
+						"query": {"Location": "NY"}
+					}
+		}
+	},
+
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+	//the name of the scene to load when the app is initialized.
+	"defaultView": "home",
+
+	"defaultTransition": "slide",
+	//scenes are groups of views and models loaded at once	
+	"views": {
+
+		"home": {
+			"dependencies":["dojox/mobile/ListItem","dojox/mobile/RoundRectList","dojox/mobile/RoundRectCategory","dojox/mobile/Heading"],
+			"template": "./main/main.html"
+		},
+
+		"simple":{
+			"models": {
+				"names": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/ModelRefController",
+					"params":{
+						"data": "modelApp.names"
+					}
+				}
+			},
+			"controller" : "./simple/simple.js",
+			"template": "./simple/simple.html",
+			"dependencies":["dojox/mobile/TextBox","dojox/mvc/Group","dojox/mvc/Repeat","dojox/mvc/Output"]
+		},
+
+		"simple2":{
+			"models": {
+				"names": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditModelRefController",
+					"params":{
+						"data": "modelApp.names"
+					}
+				},
+				"repeatmodelsXUnused": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"datastore": {"$ref":"#stores.repeatItemStore"}
+					}
+				}
+			},
+			"controller" : "./simple/simple2.js",
+			"template": "./simple/simple2.html",
+			"dependencies":["dojox/mobile/TextBox","dojox/mvc/Group","dojox/mvc/Repeat","dojox/mvc/Output"]
+		},
+
+		"simple3":{
+			"models": {
+				"names3": {
+					"modelLoader": "dojox/app/utils/simpleModel",
+					"params":{
+						"store": {"$ref":"#stores.namesStore"}
+
+					}
+				},
+				"names3JsonStoreUnused": {
+					"modelLoader": "dojox/app/utils/simpleModel",
+					"params":{
+						"store": {"$ref":"#stores.jsonNameStore"},
+						"query": {"id": "1"}
+					}
+				},
+				"names3dataStoreUnused": {
+					"modelLoader": "dojox/app/utils/simpleModel",
+					"params":{
+						"datastore": {"$ref":"#stores.nameItemStore"}
+
+					}
+				},
+				"namesXUnused": {
+					"modelLoader": "dojox/app/utils/simpleModel",
+					"params":{
+						"store": {"$ref":"#stores.namesStore"}
+					}
+				}
+			},
+			"controller" : "./simple/simple3.js",
+			"template": "./simple/simple3.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		},
+
+		"repeat": {
+			"models": {
+				"repeatmodels": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"store": {"$ref":"#stores.repeatStore"}
+					}
+				},
+				"repeatmodelsXUnused": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"datastore": {"$ref":"#stores.repeatItemStore"}
+					}
+				}
+			},
+			"controller": "./repeat/repeat.js",
+			"template": "./repeat/repeat.html",
+			"dependencies":["dojox/mobile/TextBox","dojox/mvc/Group","dojox/mvc/Repeat","dojox/mvc/Output"]
+		},
+
+		"repeat2": {
+			"models": {
+				"repeatmodels2": {
+					"modelLoader": "dojox/app/utils/mvcModel",
+					"type": "dojox/mvc/EditStoreRefListController",
+					"params":{
+						"datastore": {"$ref":"#stores.repeatItemStore"},
+						"query": {"Location": "NY"}
+					}
+				}
+			},
+			"controller": "./repeat/repeat2.js",
+			"template": "./repeat/repeat2.html",
+			"dependencies":["dojox/mobile/TextBox","dojox/mvc/Group","dojox/mvc/Repeat","dojox/mvc/Output"]
+		},
+
+		"repeat3": {
+			"controller": "./repeat/repeat3.js",
+			"template": "./repeat/repeat3.html",
+			"dependencies":["dojox/mobile/TextBox","dojox/mvc/Group","dojox/mvc/Repeat","dojox/mvc/Output"]
+		},
+
+		"generate": {
+			"controller": "./generate/generate.js",
+			"template": "./generate/generate.html",
+			"dependencies":["dojox/mobile/TextBox", "dojox/mobile/TextArea", "dojox/mvc/Generate"]
+		}
+	}
+}
diff --git a/dojox/app/tests/simpleModelApp/generate/generate.html b/dojox/app/tests/simpleModelApp/generate/generate.html
new file mode 100644
index 0000000..9eba5bb
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/generate/generate.html
@@ -0,0 +1,49 @@
+<div id="generate" class="view mblView"> 
+<div data-dojo-type="dojox/app/widgets/Container" data-dojo-props="scrollable:true" data-app-constraint="center">
+	<h1 dojoType="dojox/mobile/Heading">The App shows how to use different types of Stores and Models</h1>
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+    <h1 dojoType="dojox/mobile/Heading" back="Home">generate - Simple Form Generate Example</h1> 
+    <div class="field-title"></div> 
+        <div id="main"> 
+          <div id="leftNav"> 
+          </div> 
+          <div id="mainContent" class="generate-maincontent"> 
+            <div id="outerModelArea"> 
+                <h3 dojoType="dojox/mobile/RoundRectCategory">Model</h3> 
+                <div class="generate-textarea-row"> 
+                    <textarea class="generate-textarea-cell" dojoType="dojox/mobile/TextArea" id="modelArea" style="width: 300px; height: 300px;"> 
+{
+    "Serial": "11111",
+    "First": "John",
+    "Last": "Doe",
+    "Email": "jdoe at example.com",
+    "Phones": [
+        {
+            "Office": "111-111-1111"
+        },
+        {
+            "Mobile": "222-222-2222"
+        }
+    ]
+}
+                    </textarea> 
+                </div> 
+                <div class="fieldset"> 
+                    <div class="spacer"></div> 
+                    <button id="generate1" dojoType="dojox/mobile/Button" class="mblBlueButton">Generate Form</button> 
+                </div> 
+            </div> 
+            <div id="viewArea" style="display:none"> 
+                <h3 dojoType="dojox/mobile/RoundRectCategory">Generated View</h3> 
+                <div class="fieldset"> 
+                    <div id="view" dojoType="dojox.mvc.Generate"></div> 
+                </div> 
+                <div class="fieldset"> 
+                    <div class="spacer"></div> 
+                    <button id="updateModel" dojoType="dojox/mobile/Button" class="mblBlueButton">Update Model</button> 
+                </div> 
+            </div> 
+          </div> 
+        </div>
+</div> 
+</div> 
\ No newline at end of file
diff --git a/dojox/app/tests/simpleModelApp/generate/generate.js b/dojox/app/tests/simpleModelApp/generate/generate.js
new file mode 100644
index 0000000..0091319
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/generate/generate.js
@@ -0,0 +1,53 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry", "dojox/mvc"], function(dom, connect, registry, mvc){
+	var genmodel = null; // generate view data model
+	var _connectResults = []; // events connect result
+
+	var updateModel = function(){
+		dom.byId("modelArea").focus();
+		dom.byId("viewArea").style.display = "none";
+		dom.byId("outerModelArea").style.display = "";
+		registry.byId("modelArea").set("value", (dojo.toJson(genmodel.toPlainObject(), true)));
+	};
+
+	var updateView = function(){
+		try{
+			var modeldata = dojo.fromJson(dom.byId("modelArea").value);
+			genmodel = mvc.newStatefulModel({
+				data: modeldata
+			});
+			registry.byId("view").set("ref", genmodel);
+			dom.byId("outerModelArea").style.display = "none";
+			dom.byId("viewArea").style.display = "";
+		}catch(err){
+			console.error("Error parsing json from model: " + err);
+		}
+	};
+
+	return {
+		init: function(){
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId('generate1'), "click", function(){
+				updateView();
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('updateModel'), "click", function(){
+				updateModel();
+			});
+			_connectResults.push(connectResult);
+		},
+
+		beforeActivate: function(){
+			//console.log("generate view beforeActivate()");
+		},
+
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/simpleModelApp/index.html b/dojox/app/tests/simpleModelApp/index.html
new file mode 100644
index 0000000..04f84cd
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/index.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/> 
+		<meta name="apple-mobile-web-app-capable" content="yes" /> 
+		<title>Simple Model App Test</title> 
+		<link href="../../../mobile/themes/iphone/base.css" rel="stylesheet">
+		<style>
+			html,body {
+				width: 100%;
+				height: 100%;
+				background: #eee;
+				font-family: arial;
+				color: #333;
+				overflow: hidden;
+				margin: 0;
+				padding: 0;
+				visibility: visible;
+			}
+
+			#splash {
+				width: 90%;
+				height: 90%;
+				margin: auto;
+				overflow: hidden;
+				border: 2px solid green;
+				color: #333;
+				text-align: center;
+			}
+
+		</style>
+		<script type="text/javascript">
+			dojoConfig = {
+				parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+                mblAlwaysHideAddressBar: false,	
+				traceSet:{
+					"loader-inject":1,
+					"loader-define":1,
+					"loader-runFactory":1,
+					"loader-execModule":1,
+					"loader-execModule-out":1,
+					"loader-defineModule":1
+				},
+				async:1,
+				app: {debugApp: 1}  // set debugApp to log app transtions and view activate/deactivate 
+			};
+		</script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+		<script>
+            // the actual  launcher
+            require(["./modelApp.js"], function(){});
+        </script>
+
+	</head>
+	<body>
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+	</body>
+</html>
diff --git a/dojox/app/tests/simpleModelApp/main/main.html b/dojox/app/tests/simpleModelApp/main/main.html
new file mode 100644
index 0000000..1cae64a
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/main/main.html
@@ -0,0 +1,30 @@
+<div class="view mblView">
+<h1 data-dojo-type="dojox/mobile/Heading" data-app-constraint="top">The App shows how to use different types of Stores and Models</h1>
+<h2 data-dojo-type="dojox/mobile/RoundRectCategory" data-app-constraint="top">The App Shows how to use different types of Stores and Models</h2>
+
+<div data-dojo-type="dojox/app/widgets/Container" data-dojo-props="scrollable:true">    
+    <ul data-dojo-type="dojox/mobile/RoundRectList">
+        <li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'simple',url:'#simple'">
+            simple - Using an mvcModel (dojox/mvc/ModelRefController) with json data, no store.
+        </li>
+        <li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'simple2',url:'#simple2'">
+            simple2 - Using an mvcModel (dojox/mvc/EditModelRefController) with json data, no store.
+        </li>
+        <li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'simple3',url:'#simple3'">
+            simple 3 - Using simple JSON Model with data from a dojo.store.Memory
+        </li>
+        <li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'repeat',url:'#repeat'">
+            repeat - Using an mvcModel (dojox/mvc/EditStoreRefListController) with a dojo.store.JsonRest. 
+        </li>
+        <li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'repeat2',url:'#repeat2'">
+            repeat2 - Using an mvcModel (dojox/mvc/EditStoreRefListController) with an ItemFileWriteStore which gets wrapped in DataStore, with a query. 
+        </li>
+        <li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'repeat3',url:'#repeat3'">
+            repeat3 - Using an mvcModel (dojox/mvc/EditStoreRefListController) with an ItemFileWriteStore which gets wrapped in DataStore, no query. 
+        </li>
+        <li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true,target:'generate',url:'#generate'">
+            generate - Simple Form Generate
+        </li>
+    </ul>
+</div>
+</div>
diff --git a/dojox/app/tests/simpleModelApp/modelApp.js b/dojox/app/tests/simpleModelApp/modelApp.js
new file mode 100644
index 0000000..f12aea3
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/modelApp.js
@@ -0,0 +1,77 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojo/sniff"],
+function(win, Application, jsonRef, config, has){
+	win.global.modelApp = {};
+	modelApp.names = {
+		identifier: "id",
+		items: [{
+			"id": "1",
+			"Serial": "360324",
+			"First": "John",
+			"Last": "Doe",
+			"Email": "jdoe at us.ibm.com",
+			"ShipTo": {
+				"Street": "123 Valley Rd",
+				"City": "Katonah",
+				"State": "NY",
+				"Zip": "10536"
+			},
+			"BillTo": {
+				"Street": "17 Skyline Dr",
+				"City": "Hawthorne",
+				"State": "NY",
+				"Zip": "10532"
+			}
+		}]
+	};
+	modelApp.names2 = {
+			identifier: "id",
+			items: [{
+				"id": "1",
+				"Serial": "360324",
+				"First": "John",
+				"Last": "Doe",
+				"Email": "jdoe at us.ibm.com",
+				"ShipTo": {
+					"Street": "123 Valley Rd",
+					"City": "Katonah",
+					"State": "NY",
+					"Zip": "10536"
+				},
+				"BillTo": {
+					"Street": "17 Skyline Dr",
+					"City": "Hawthorne",
+					"State": "NY",
+					"Zip": "10532"
+				}
+			}]
+		};
+	modelApp.repeatData = [{
+		"First": "Chad",
+		"Last": "Chapman",
+		"Location": "CA",
+		"Office": "1278",
+		"Email": "c.c at test.com",
+		"Tel": "408-764-8237",
+		"Fax": "408-764-8228"
+	}, {
+		"First": "Irene",
+		"Last": "Ira",
+		"Location": "NJ",
+		"Office": "F09",
+		"Email": "i.i at test.com",
+		"Tel": "514-764-6532",
+		"Fax": "514-764-7300"
+	}, {
+		"First": "John",
+		"Last": "Jacklin",
+		"Location": "CA",
+		"Office": "6701",
+		"Email": "j.j at test.com",
+		"Tel": "408-764-1234",
+		"Fax": "408-764-4321"
+	}];
+	var cfg = jsonRef.fromJson(config);
+	has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+	Application(cfg);
+
+});
diff --git a/dojox/app/tests/simpleModelApp/repeat/repeat.html b/dojox/app/tests/simpleModelApp/repeat/repeat.html
new file mode 100644
index 0000000..7b43fe3
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/repeat/repeat.html
@@ -0,0 +1,67 @@
+<div class="view mblView">
+<h1 data-dojo-type="dojox/mobile/Heading" data-app-constraint="top" data-dojo-props='back:"Home"'>repeat</h1>
+
+<div data-dojo-type="dojox/app/widgets/Container" data-dojo-props="scrollable:true" data-app-constraint="center">    
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+    <form name="repeatTestForm" id="repeatTestForm">    
+    <div class="field-title">repeat - Using an mvcModel (dojox/mvc/EditStoreRefListController) with a dojo.store.JsonRest.</div>
+        <div id="repeatWidget" class="fieldset" data-dojo-type="dojox/mvc/Repeat" 
+        	data-dojo-props="exprchar: '#', children: this.loadedModels.jsonRestModel.model" >
+           <div class="row">            
+                    <input data-dojo-type="dojox/mobile/TextBox"
+                        id="nameInput#{this.index}" data-dojo-props="value: at('rel:#{this.index}','First')" placeHolder="First Name">
+                    <button type="button" id="detail#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        Details
+                    </button>
+                    <button type="button" id="insert#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        +
+                    </button>
+                    <button type="button" id="delete#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        -
+                    </button>
+                </div>
+        </div>
+        <div class="spacer"></div>
+		<div data-dojo-type="dojox/mvc/Group" 
+			data-dojo-props="target: at(this.loadedModels.jsonRestModel, 'cursor')">
+					<div class="field-title">
+						<div style="display: inline-block;" id="detailsBanner">Details for selected index:</div>
+						<span class="cell" id="indexOutput"
+							data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at(this.loadedModels.jsonRestModel, 'cursorIndex')"></span>
+					</div>
+					<table id="table" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'First'), placeholder:'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput" data-dojo-type="dojox/mobile/TextBox"
+									 
+									data-dojo-props="placeholder:'Last Name', value: at('rel:', 'Last')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput2" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Email'), placeholder:'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Tel'), placeholder:'Telephone'">
+							</td>
+						</tr>
+					</table>
+		</div>
+		</form>
+</div>
+</div>
diff --git a/dojox/app/tests/simpleModelApp/repeat/repeat.js b/dojox/app/tests/simpleModelApp/repeat/repeat.js
new file mode 100644
index 0000000..a061eec
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/repeat/repeat.js
@@ -0,0 +1,76 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry", "dojox/mvc/at", "dojox/mvc/Repeat", "dojox/mvc/getStateful"],
+function(dom, connect, registry, at, Repeat, getStateful){
+
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+
+	// delete an item
+	var deleteResult = function(index){
+		var nextIndex = repeatmodel.get("cursorIndex");
+		if(nextIndex >= index){
+			nextIndex = nextIndex-1;
+		}
+		repeatmodel.model.splice(index, 1);
+		repeatmodel.set("cursorIndex", nextIndex);		
+	};
+	// show an item detail
+	var setDetailsContext = function(index){
+		repeatmodel.set("cursorIndex", index);
+	};
+	// insert an item
+	var insertResult = function(index){
+		if(index<0 || index>repeatmodel.model.length){
+			throw Error("index out of data model.");
+		}
+		if((repeatmodel.model[index].First=="") ||
+			(repeatmodel.model[index+1] && (repeatmodel.model[index+1].First == ""))){
+			return;
+		}
+		var data = {id:Math.random(), "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+		repeatmodel.model.splice(index+1, 0, new getStateful(data));
+		setDetailsContext(index+1);
+	};
+	// get index from dom node id
+	var getIndexFromId = function(nodeId, perfix){
+		var len = perfix.length;
+		if(nodeId.length <= len){
+			throw Error("repeat node id error.");
+		}
+		var index = nodeId.substring(len, nodeId.length);
+		return parseInt(index);
+	};
+
+	return {
+		// repeat view init
+		init: function(){
+			repeatmodel = this.loadedModels.jsonRestModel;
+			var repeatDom = dom.byId('repeatWidget');
+			var connectResult;
+			connectResult = connect.connect(repeatDom, "button[id^=\"detail\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "detail");
+				setDetailsContext(index);
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(repeatDom, "button[id^=\"insert\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "insert");
+				insertResult(index);
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(repeatDom, "button[id^=\"delete\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "delete");
+				deleteResult(index);
+			});
+			_connectResults.push(connectResult);
+		},
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/simpleModelApp/repeat/repeat2.html b/dojox/app/tests/simpleModelApp/repeat/repeat2.html
new file mode 100644
index 0000000..b09dc5b
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/repeat/repeat2.html
@@ -0,0 +1,64 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+    <h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='back:"Home"'>repeat2</h1>
+    <form name="repeatTestForm" id="repeatTestForm2">    
+    <div class="field-title">repeat2 - Using an mvcModel (dojox/mvc/EditStoreRefListController) with an ItemFileWriteStore which gets wrapped in DataStore, with a query.</div>
+      <div id="repeatWidget2" class="fieldset" data-dojo-type="dojox/mvc/Repeat" 
+        	data-dojo-props="exprchar: '#', children: this.loadedModels.repeatmodels2.model" >
+           <div class="row">            
+                    <input data-dojo-type="dojox/mobile/TextBox"
+                        id="nameInput2#{this.index}" data-dojo-props="value: at('rel:#{this.index}','First')" placeHolder="First Name">
+                    <button type="button" id="detail2#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        Details
+                    </button>
+                    <button type="button" id="insert2#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        +
+                    </button>
+                    <button type="button" id="delete2#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        -
+                    </button>
+                </div>
+        </div>
+        <div class="spacer"></div>
+		<div data-dojo-type="dojox/mvc/Group" 
+			data-dojo-props="target: at(this.loadedModels.repeatmodels2, 'cursor')">
+					<div class="field-title">
+						<div style="display: inline-block;" id="detailsBanner2">Details for selected index:</div>
+						<span class="cell" id="indexOutput2"
+							data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at(this.loadedModels.repeatmodels2, 'cursorIndex')"></span>
+					</div>
+					<table id="table2" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput2" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'First'), placeholder:'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput2" data-dojo-type="dojox/mobile/TextBox"
+									 
+									data-dojo-props="placeholder:'Last Name', value: at('rel:', 'Last')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput22" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Email'), placeholder:'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput2" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Tel'), placeholder:'Telephone'">
+							</td>
+						</tr>
+					</table>
+		</div>
+		</form>
+</div>
diff --git a/dojox/app/tests/simpleModelApp/repeat/repeat2.js b/dojox/app/tests/simpleModelApp/repeat/repeat2.js
new file mode 100644
index 0000000..b6a12ae
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/repeat/repeat2.js
@@ -0,0 +1,77 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry", "dojox/mvc/at", "dojox/mvc/Repeat", "dojox/mvc/getStateful"],
+function(dom, connect, registry, at, Repeat, getStateful){
+
+	var _connectResults = []; // events connect result
+
+	var repeatmodel2 = null;	//repeat view data model
+
+	// delete an item
+	var deleteResult = function(index){
+		var nextIndex = repeatmodel2.get("cursorIndex");
+		if(nextIndex >= index){
+			nextIndex = nextIndex-1;
+		}
+		repeatmodel2.model.splice(index, 1);
+		repeatmodel2.set("cursorIndex", nextIndex);		
+	};
+	// show an item detail
+	var setDetailsContext = function(index){
+		repeatmodel2.set("cursorIndex", index);
+	};
+	// insert an item
+	var insertResult = function(index){
+		if(index<0 || index>repeatmodel2.model.length){
+			throw Error("index out of data model.");
+		}
+		if((repeatmodel2.model[index].First=="") ||
+			(repeatmodel2.model[index+1] && (repeatmodel2.model[index+1].First == ""))){
+			return;
+		}
+		var data = {id:Math.random(), "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+		repeatmodel2.model.splice(index+1, 0, new getStateful(data));
+		setDetailsContext(index+1);
+	};
+	// get index from dom node id
+	var getIndexFromId = function(nodeId, perfix){
+		var len = perfix.length;
+		if(nodeId.length <= len){
+			throw Error("repeat node id error.");
+		}
+		var index = nodeId.substring(len, nodeId.length);
+		return parseInt(index);
+	};
+
+	return {
+		// repeat2 view init
+		init: function(){
+			repeatmodel2 = this.loadedModels.repeatmodels2;
+			var repeatDom = dom.byId('repeatWidget2');
+			var connectResult;
+			connectResult = connect.connect(repeatDom, "button[id^=\"detail2\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "detail2");
+				setDetailsContext(index);
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(repeatDom, "button[id^=\"insert2\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "insert2");
+				insertResult(index);
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(repeatDom, "button[id^=\"delete2\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "delete2");
+				deleteResult(index);
+			});
+			_connectResults.push(connectResult);
+		},
+		// repeat2 view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/simpleModelApp/repeat/repeat3.html b/dojox/app/tests/simpleModelApp/repeat/repeat3.html
new file mode 100644
index 0000000..ea88510
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/repeat/repeat3.html
@@ -0,0 +1,64 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+    <h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='back:"Home"'>repeat3</h1>
+    <form name="repeatTestForm" id="repeatTestForm3">    
+    <div class="field-title">repeat3 - - Using an mvcModel (dojox/mvc/EditStoreRefListController) with an ItemFileWriteStore which gets wrapped in DataStore, no query.</div>
+      <div id="repeatWidget3" class="fieldset" data-dojo-type="dojox/mvc/Repeat" 
+        	data-dojo-props="exprchar: '#', children: this.loadedModels.repeatmodels3.model" >
+           <div class="row">            
+                    <input data-dojo-type="dojox/mobile/TextBox"
+                        id="nameInput3#{this.index}" data-dojo-props="value: at('rel:#{this.index}','First')" placeHolder="First Name">
+                    <button type="button" id="detail3#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        Details
+                    </button>
+                    <button type="button" id="insert3#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        +
+                    </button>
+                    <button type="button" id="delete3#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        -
+                    </button>
+                </div>
+        </div>
+        <div class="spacer"></div>
+		<div data-dojo-type="dojox/mvc/Group" 
+			data-dojo-props="target: at(this.loadedModels.repeatmodels3, 'cursor')">
+					<div class="field-title">
+						<div style="display: inline-block;" id="detailsBanner3">Details for selected index:</div>
+						<span class="cell" id="indexOutput3"
+							data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at(this.loadedModels.repeatmodels3, 'cursorIndex')"></span>
+					</div>
+					<table id="table3" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput3" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'First'), placeholder:'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput3" data-dojo-type="dojox/mobile/TextBox"
+									 
+									data-dojo-props="placeholder:'Last Name', value: at('rel:', 'Last')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput33" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Email'), placeholder:'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput3" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Tel'), placeholder:'Telephone'">
+							</td>
+						</tr>
+					</table>
+		</div>
+		</form>
+</div>
diff --git a/dojox/app/tests/simpleModelApp/repeat/repeat3.js b/dojox/app/tests/simpleModelApp/repeat/repeat3.js
new file mode 100644
index 0000000..aa2c468
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/repeat/repeat3.js
@@ -0,0 +1,77 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry", "dojox/mvc/at", "dojox/mvc/Repeat", "dojox/mvc/getStateful"],
+function(dom, connect, registry, at, Repeat, getStateful){
+
+	var _connectResults = []; // events connect result
+
+	var repeatmodel3 = null;	//repeat view data model
+
+	// delete an item
+	var deleteResult = function(index){
+		var nextIndex = repeatmodel3.get("cursorIndex");
+		if(nextIndex >= index){
+			nextIndex = nextIndex-1;
+		}
+		repeatmodel3.model.splice(index, 1);
+		repeatmodel3.set("cursorIndex", nextIndex);		
+	};
+	// show an item detail
+	var setDetailsContext = function(index){
+		repeatmodel3.set("cursorIndex", index);
+	};
+	// insert an item
+	var insertResult = function(index){
+		if(index<0 || index>repeatmodel3.model.length){
+			throw Error("index out of data model.");
+		}
+		if((repeatmodel3.model[index].First=="") ||
+			(repeatmodel3.model[index+1] && (repeatmodel3.model[index+1].First == ""))){
+			return;
+		}
+		var data = {id:Math.random(), "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+		repeatmodel3.model.splice(index+1, 0, new getStateful(data));
+		setDetailsContext(index+1);
+	};
+	// get index from dom node id
+	var getIndexFromId = function(nodeId, perfix){
+		var len = perfix.length;
+		if(nodeId.length <= len){
+			throw Error("repeat node id error.");
+		}
+		var index = nodeId.substring(len, nodeId.length);
+		return parseInt(index);
+	};
+
+	return {
+		// repeat3 view init
+		init: function(){
+			repeatmodel3 = this.loadedModels.repeatmodels3;
+			var repeatDom = dom.byId('repeatWidget3');
+			var connectResult;
+			connectResult = connect.connect(repeatDom, "button[id^=\"detail3\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "detail3");
+				setDetailsContext(index);
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(repeatDom, "button[id^=\"insert3\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "insert3");
+				insertResult(index);
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(repeatDom, "button[id^=\"delete3\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "delete3");
+				deleteResult(index);
+			});
+			_connectResults.push(connectResult);
+		},
+		// repeat3 view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/simpleModelApp/resources/data/jsonRestNamesData.json b/dojox/app/tests/simpleModelApp/resources/data/jsonRestNamesData.json
new file mode 100644
index 0000000..1044159
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/resources/data/jsonRestNamesData.json
@@ -0,0 +1,9 @@
+[ 
+	{
+		"id" : "1",
+		"Serial": "360324",
+		"First": "John",
+		"Last": "Doe",
+		"Email": "jdoe at us.ibm.com"
+	}
+]
\ No newline at end of file
diff --git a/dojox/app/tests/simpleModelApp/resources/data/jsonRestRepeatData.json b/dojox/app/tests/simpleModelApp/resources/data/jsonRestRepeatData.json
new file mode 100644
index 0000000..d0cd4c7
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/resources/data/jsonRestRepeatData.json
@@ -0,0 +1,102 @@
+[ 
+                    {
+                        "Serial"  : "A111",
+                        "First"   : "Anne",
+                        "Last"    : "Ackerman",
+                        "Location": "NY",
+                        "Office"  : "1S76",
+                        "Email"   : "a.a at test.com",
+                        "Tel"     : "123-764-8237",
+                        "Fax"     : "123-764-8228"
+                    },
+                    {
+                        "Serial"  : "B111",
+                        "First"   : "Ben",
+                        "Last"    : "Beckham",
+                        "Location": "NY",
+                        "Office"  : "5N47",
+                        "Email"   : "b.b at test.com",
+                        "Tel"     : "123-764-8599",
+                        "Fax"     : "123-764-8600"
+                    },
+                    {
+                        "Serial"  : "C111",
+                        "First"   : "Chad",
+                        "Last"    : "Chapman",
+                        "Location": "CA",
+                        "Office"  : "1278",
+                        "Email"   : "c.c at test.com",
+                        "Tel"     : "408-764-8237",
+                        "Fax"     : "408-764-8228"
+                    },
+                    {
+                        "Serial"  : "D111",
+                        "First"   : "David",
+                        "Last"    : "Durham",
+                        "Location": "NJ",
+                        "Office"  : "C12",
+                        "Email"   : "d.d at test.com",
+                        "Tel"     : "514-764-8237",
+                        "Fax"     : "514-764-8228"
+                    },
+                    {
+                        "Serial"  : "E111",
+                        "First"   : "Emma",
+                        "Last"    : "Eklof",
+                        "Location": "NY",
+                        "Office"  : "4N76",
+                        "Email"   : "e.e at test.com",
+                        "Tel"     : "123-764-1234",
+                        "Fax"     : "123-764-4321"
+                    },
+                    {
+                        "Serial"  : "F111",
+                        "First"   : "Fred",
+                        "Last"    : "Fisher",
+                        "Location": "NJ",
+                        "Office"  : "V89",
+                        "Email"   : "f.f at test.com",
+                        "Tel"     : "514-764-8567",
+                        "Fax"     : "514-764-8000"
+                    },
+                    {
+                        "Serial"  : "G111",
+                        "First"   : "George",
+                        "Last"    : "Garnett",
+                        "Location": "NY",
+                        "Office"  : "7S11",
+                        "Email"   : "gig at test.com",
+                        "Tel"     : "123-999-8599",
+                        "Fax"     : "123-999-8600"
+                    },
+                    {
+                        "Serial"  : "H111",
+                        "First"   : "Hunter",
+                        "Last"    : "Huffman",
+                        "Location": "CA",
+                        "Office"  : "6532",
+                        "Email"   : "h.h at test.com",
+                        "Tel"     : "408-874-8237",
+                        "Fax"     : "408-874-8228"
+                    },
+                    {
+                        "Serial"  : "I111",
+                        "First"   : "Irene",
+                        "Last"    : "Ira",
+                        "Location": "NJ",
+                        "Office"  : "F09",
+                        "Email"   : "i.i at test.com",
+                        "Tel"     : "514-764-6532",
+                        "Fax"     : "514-764-7300"
+                    },
+                    {
+                        "Serial"  : "J111",
+                        "First"   : "John",
+                        "Last"    : "Jacklin",
+                        "Location": "CA",
+                        "Office"  : "6701",
+                        "Email"   : "j.j at test.com",
+                        "Tel"     : "408-764-1234",
+                        "Fax"     : "408-764-4321"
+                    }
+]
diff --git a/dojox/app/tests/simpleModelApp/resources/data/names2.json b/dojox/app/tests/simpleModelApp/resources/data/names2.json
new file mode 100644
index 0000000..8973b0b
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/resources/data/names2.json
@@ -0,0 +1,11 @@
+{
+  "identifier": "id",
+  "items": [ 
+	{
+		"id" : "1",
+		"Serial": "360324",
+		"First": "John",
+		"Last": "Doe",
+		"Email": "jdoe at us.ibm.com"
+	}]
+}
diff --git a/dojox/app/tests/simpleModelApp/resources/data/repeat.json b/dojox/app/tests/simpleModelApp/resources/data/repeat.json
new file mode 100644
index 0000000..191b80b
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/resources/data/repeat.json
@@ -0,0 +1,105 @@
+{
+  "identifier": "Serial",
+   "items": [ 
+                    {
+                        "Serial"  : "A111",
+                        "First"   : "Anne",
+                        "Last"    : "Ackerman",
+                        "Location": "NY",
+                        "Office"  : "1S76",
+                        "Email"   : "a.a at test.com",
+                        "Tel"     : "123-764-8237",
+                        "Fax"     : "123-764-8228"
+                    },
+                    {
+                        "Serial"  : "B111",
+                        "First"   : "Ben",
+                        "Last"    : "Beckham",
+                        "Location": "NY",
+                        "Office"  : "5N47",
+                        "Email"   : "b.b at test.com",
+                        "Tel"     : "123-764-8599",
+                        "Fax"     : "123-764-8600"
+                    },
+                    {
+                        "Serial"  : "C111",
+                        "First"   : "Chad",
+                        "Last"    : "Chapman",
+                        "Location": "CA",
+                        "Office"  : "1278",
+                        "Email"   : "c.c at test.com",
+                        "Tel"     : "408-764-8237",
+                        "Fax"     : "408-764-8228"
+                    },
+                    {
+                        "Serial"  : "D111",
+                        "First"   : "David",
+                        "Last"    : "Durham",
+                        "Location": "NJ",
+                        "Office"  : "C12",
+                        "Email"   : "d.d at test.com",
+                        "Tel"     : "514-764-8237",
+                        "Fax"     : "514-764-8228"
+                    },
+                    {
+                        "Serial"  : "E111",
+                        "First"   : "Emma",
+                        "Last"    : "Eklof",
+                        "Location": "NY",
+                        "Office"  : "4N76",
+                        "Email"   : "e.e at test.com",
+                        "Tel"     : "123-764-1234",
+                        "Fax"     : "123-764-4321"
+                    },
+                    {
+                        "Serial"  : "F111",
+                        "First"   : "Fred",
+                        "Last"    : "Fisher",
+                        "Location": "NJ",
+                        "Office"  : "V89",
+                        "Email"   : "f.f at test.com",
+                        "Tel"     : "514-764-8567",
+                        "Fax"     : "514-764-8000"
+                    },
+                    {
+                        "Serial"  : "G111",
+                        "First"   : "George",
+                        "Last"    : "Garnett",
+                        "Location": "NY",
+                        "Office"  : "7S11",
+                        "Email"   : "gig at test.com",
+                        "Tel"     : "123-999-8599",
+                        "Fax"     : "123-999-8600"
+                    },
+                    {
+                        "Serial"  : "H111",
+                        "First"   : "Hunter",
+                        "Last"    : "Huffman",
+                        "Location": "CA",
+                        "Office"  : "6532",
+                        "Email"   : "h.h at test.com",
+                        "Tel"     : "408-874-8237",
+                        "Fax"     : "408-874-8228"
+                    },
+                    {
+                        "Serial"  : "I111",
+                        "First"   : "Irene",
+                        "Last"    : "Ira",
+                        "Location": "NJ",
+                        "Office"  : "F09",
+                        "Email"   : "i.i at test.com",
+                        "Tel"     : "514-764-6532",
+                        "Fax"     : "514-764-7300"
+                    },
+                    {
+                        "Serial"  : "J111",
+                        "First"   : "John",
+                        "Last"    : "Jacklin",
+                        "Location": "CA",
+                        "Office"  : "6701",
+                        "Email"   : "j.j at test.com",
+                        "Tel"     : "408-764-1234",
+                        "Fax"     : "408-764-4321"
+                    }
+                ]
+}
diff --git a/dojox/app/tests/simpleModelApp/simple/simple.html b/dojox/app/tests/simpleModelApp/simple/simple.html
new file mode 100644
index 0000000..4964d4a
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/simple/simple.html
@@ -0,0 +1,80 @@
+<div id="settings" class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+    <h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='back:"Home"'>simple</h1>
+    <form name="testForm" id="testForm">    
+  	<div class="field-title">simple - Using an mvcModel (dojox/mvc/ModelRefController) with json data, no store.</div>
+	<div class="fieldset" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(this.loadedModels.names, 'model')">
+	<div data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:', 'items')">
+	<div data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:', 0)">
+  			<table id="table" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First</td>
+							<td class="layout">							
+								<input  id="firstInput1" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'First'), placeholder:'First'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput1" data-dojo-type="dojox/mobile/TextBox"
+									 
+									data-dojo-props="placeholder:'Last Name', value: at('rel:', 'Last')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput1" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Email'), placeholder:'Email'">
+							</td>
+						</tr>
+					</table>
+		
+	
+  			<div class="spacer"></div>
+			<button id="shipto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Ship To</button>
+			<button id="billto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="addrGroup" data-dojo-type="dojox/mvc/Group" 
+							data-dojo-props="target: at('rel:','ShipTo')">
+					<table id="table" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">Street</td>
+							<td class="layout">							
+								<input  id="streetInput" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'Street'), placeholder:'Street'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">City</td>
+							<td class="layout">
+								<input id="cityInput" data-dojo-type="dojox/mobile/TextBox"
+									 
+									data-dojo-props="placeholder:'City', value: at('rel:', 'City')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">State</td>
+							<td class="layout">
+								<input  id="StateInput" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'State'), placeholder:'State'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">State</td>
+							<td class="layout">
+								<input  id="ZipInput" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Zip'), placeholder:'Zip Code'">
+							</td>
+						</tr>
+					</table>
+			</div>
+			</div>
+			</div>
+			</div>
+			
+			<div class="spacer"></div>
+	<!-- 	<button id="reset1" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Reset</button> -->
+    </form>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/simpleModelApp/simple/simple.js b/dojox/app/tests/simpleModelApp/simple/simple.js
new file mode 100644
index 0000000..e2281dc
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/simple/simple.js
@@ -0,0 +1,44 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry", "dojox/mvc/at"],
+function(dom, connect, registry, at){
+
+	var _connectResults = []; // events connect results
+	var currentModel = null;
+
+	var setRef = function (id, attr){
+		var widget = registry.byId(id);
+		widget.set("target", at("rel:", attr));
+		//console.log("setRef done.");
+	};
+	return {
+		// simple view init
+		init: function(){
+			currentModel = this.loadedModels.names;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId('shipto'), "click", function(){
+				setRef('addrGroup', 'ShipTo');
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('billto'), "click", function(){
+				setRef('addrGroup', 'BillTo');
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('reset1'), "click", function(){
+				currentModel.reset();
+				//console.log("reset done. ");
+			});
+			_connectResults.push(connectResult);
+		},
+
+		// simple view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	}
+});
diff --git a/dojox/app/tests/simpleModelApp/simple/simple2.html b/dojox/app/tests/simpleModelApp/simple/simple2.html
new file mode 100644
index 0000000..8ff9df3
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/simple/simple2.html
@@ -0,0 +1,80 @@
+<div id="settings-2" class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+    <h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='back:"Home"'>simple2</h1>
+    <form name="testForm-2" id="testForm">    
+  	<div class="field-title">simple2 - Using an mvcModel (dojox/mvc/EditModelRefController) with json data, no store.</div>
+	<div class="fieldset" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(this.loadedModels.names, 'model')">
+	<div data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:', 'items')">
+	<div data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:', 0)">
+  			<table id="table-2" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First</td>
+							<td class="layout">							
+								<input  id="firstInput1-2" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'First'), placeholder:'First'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput1-2" data-dojo-type="dojox/mobile/TextBox"
+									 
+									data-dojo-props="placeholder:'Last Name', value: at('rel:', 'Last')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput1-2" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Email'), placeholder:'Email'">
+							</td>
+						</tr>
+					</table>
+		
+	
+  			<div class="spacer"></div>
+			<button id="shipto-2" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Ship To</button>
+			<button id="billto-2" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="addrGroup-2" data-dojo-type="dojox/mvc/Group" 
+							data-dojo-props="target: at('rel:','ShipTo')">
+					<table id="table-2" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">Street</td>
+							<td class="layout">							
+								<input  id="streetInput-2" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'Street'), placeholder:'Street'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">City</td>
+							<td class="layout">
+								<input id="cityInput-2" data-dojo-type="dojox/mobile/TextBox"
+									 
+									data-dojo-props="placeholder:'City', value: at('rel:', 'City')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">State</td>
+							<td class="layout">
+								<input  id="StateInput-2" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'State'), placeholder:'State'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">State</td>
+							<td class="layout">
+								<input  id="ZipInput-2" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Zip'), placeholder:'Zip Code'">
+							</td>
+						</tr>
+					</table>
+			</div>
+			</div>
+			</div>
+			</div>
+			
+			<div class="spacer"></div>
+		 	<button id="reset1-2" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Reset</button> 
+    </form>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/simpleModelApp/simple/simple2.js b/dojox/app/tests/simpleModelApp/simple/simple2.js
new file mode 100644
index 0000000..6fbbd5b
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/simple/simple2.js
@@ -0,0 +1,44 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry", "dojox/mvc/at"],
+function(dom, connect, registry, at){
+
+	var _connectResults = []; // events connect results
+	var currentModel = null;
+
+	var setRef = function (id, attr){
+		var widget = registry.byId(id);
+		widget.set("target", at("rel:", attr));
+		//console.log("setRef done.");
+	};
+	return {
+		// simple view init
+		init: function(){
+			currentModel = this.loadedModels.names;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId('shipto-2'), "click", function(){
+				setRef('addrGroup-2', 'ShipTo');
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('billto-2'), "click", function(){
+				setRef('addrGroup-2', 'BillTo');
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('reset1-2'), "click", function(){
+				currentModel.reset();
+				//console.log("reset done. ");
+			});
+			_connectResults.push(connectResult);
+		},
+
+		// simple view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/simpleModelApp/simple/simple3.html b/dojox/app/tests/simpleModelApp/simple/simple3.html
new file mode 100644
index 0000000..45a7da4
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/simple/simple3.html
@@ -0,0 +1,102 @@
+<div id="settings-3" class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+    <h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='back:"Home"'>simple 3</h1>
+    <form name="testForm" id="testForm-3">    
+  	<div class="field-title">simple 3 - Using simple JSON Model with data from a dojo.store.Memory</div>
+  			<table id="table-3" cellspacing="10"  style="width: 100%">
+				<tr>
+					<td style="width: 100px;" class="layout">First</td>
+					<td class="layout">							
+						<input  id="firstInput1-3" data-dojo-type="dojox/mobile/TextBox" 
+								data-dojo-props="placeholder:'First'">
+					</td>
+				</tr>
+				<tr>
+					<td style="width: 100px;" class="layout">Last Name</td>
+					<td class="layout">
+						<input 	id="lastInput1-3" data-dojo-type="dojox/mobile/TextBox" 								 
+								data-dojo-props="placeholder:'Last Name'">
+					</td>
+				</tr>
+				<tr>
+					<td style="width: 100px;" class="layout">Email</td>
+					<td class="layout">
+						<input id="emailInput1-3" data-dojo-type="dojox/mobile/TextBox" 								 
+								data-dojo-props="placeholder:'Email'">
+					</td>
+				</tr>
+			</table>
+		
+	
+  			<div class="spacer"></div>
+			<button id="shipto-3" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Ship To</button>
+			<button id="billto-3" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="shiptodiv-3" >Ship To:
+	  			<table id="table-3" cellspacing="10" style="width: 100%">
+					<tr>
+						<td style="width: 100px;" class="layout">Street</td>
+						<td class="layout">							
+							<input  id="shiptostreetInput1-3" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="placeholder:'Street'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">City</td>
+						<td class="layout">
+							<input 	id="shiptocityInput1-3" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'City'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">State</td>
+						<td class="layout">
+							<input id="shiptostateInput1-3" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'State'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">Zip Code</td>
+						<td class="layout">
+							<input id="shiptozipInput1-3" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'Zip Code'">
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="fieldset" id="billtodiv-3" >Bill To:
+	  			<table id="table-3" cellspacing="10" style="width: 100%">
+					<tr>
+						<td style="width: 100px;" class="layout">Street</td>
+						<td class="layout">							
+							<input  id="billtostreetInput1-3" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="placeholder:'Street'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">City</td>
+						<td class="layout">
+							<input 	id="billtocityInput1-3" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'City'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">State</td>
+						<td class="layout">
+							<input id="billtostateInput1-3" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'State'">
+						</td>
+					</tr>
+					<tr>
+						<td style="width: 100px;" class="layout">Zip Code</td>
+						<td class="layout">
+							<input id="billtozipInput1-3" data-dojo-type="dojox/mobile/TextBox" 								 
+									data-dojo-props="placeholder:'Zip Code'">
+						</td>
+					</tr>
+				</table>
+			</div>
+			<div class="spacer"></div>
+			<button id="reset1-3" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">Reset</button>
+    </form>
+</div>
\ No newline at end of file
diff --git a/dojox/app/tests/simpleModelApp/simple/simple3.js b/dojox/app/tests/simpleModelApp/simple/simple3.js
new file mode 100644
index 0000000..9eccdb6
--- /dev/null
+++ b/dojox/app/tests/simpleModelApp/simple/simple3.js
@@ -0,0 +1,62 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry"],
+function(dom, connect, registry){
+
+	var _connectResults = []; // events connect results
+	var currentModel = null;
+
+	var setFromModel = function (){
+		registry.byId("firstInput1-3").set('value', currentModel[0].First);
+		registry.byId("lastInput1-3").set('value', currentModel[0].Last);
+		registry.byId("emailInput1-3").set('value', currentModel[0].Email);
+		registry.byId("shiptostreetInput1-3").set('value', currentModel[0].ShipTo.Street);
+		registry.byId("shiptocityInput1-3").set('value', currentModel[0].ShipTo.City);
+		registry.byId("shiptostateInput1-3").set('value', currentModel[0].ShipTo.State);
+		registry.byId("shiptozipInput1-3").set('value', currentModel[0].ShipTo.Zip);
+		registry.byId("billtostreetInput1-3").set('value', currentModel[0].BillTo.Street);
+		registry.byId("billtocityInput1-3").set('value', currentModel[0].BillTo.City);
+		registry.byId("billtostateInput1-3").set('value', currentModel[0].BillTo.State);
+		registry.byId("billtozipInput1-3").set('value', currentModel[0].BillTo.Zip);
+	};
+
+	return {
+		// simple view init
+		init: function(){
+			currentModel = this.loadedModels.names3;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId('shipto-3'), "click", function(){
+				//console.log("shipTo called. ");
+				dom.byId("billtodiv-3").style.display = "none";
+				dom.byId("shiptodiv-3").style.display = "";
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('billto-3'), "click", function(){
+				//console.log("billTo called. ");
+				dom.byId("billtodiv-3").style.display = "";
+				dom.byId("shiptodiv-3").style.display = "none";
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('reset1-3'), "click", function(){
+				//console.log("reset called. ");
+				setFromModel();
+				//console.log("reset done. ");
+			});
+			_connectResults.push(connectResult);
+
+			dom.byId("billtodiv-3").style.display = "none";
+			setFromModel();
+			
+		},
+
+		// simple view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/swapViewTestApp/config.json b/dojox/app/tests/swapViewTestApp/config.json
new file mode 100644
index 0000000..90b0acb
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/config.json
@@ -0,0 +1,151 @@
+{
+	"id": "swapViewTestApp",
+	"name": "Layout By Div Id App",
+	"description": "A Layout test App using a custom layout controller which uses div ids for the layout.",
+	"splash": "splash",
+
+	"loaderConfig": {
+		"paths": {
+			"swapViewTestApp": "../dojox/app/tests/swapViewTestApp"
+		}
+	},
+
+	"dependencies": [
+		"dojox/app/utils/mvcModel",
+		"dojox/mobile/_base",
+		
+		"dojox/mobile/FixedSplitter",
+		"dojox/mobile/Pane",
+		"dojox/mobile/Container",
+		"dojox/mobile/SwapView",
+		"dojox/mobile/PageIndicator",		
+		
+		"dojox/mobile/compat",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/Button",
+		"dojox/mobile/RoundRect",
+		"dojox/mobile/Heading",
+		"dojox/mobile/ScrollableView",
+		"dojo/store/Memory",
+		"dojox/mvc/EditStoreRefListController",
+		"dojox/mvc/Group",
+        "dojox/mvc/Repeat",
+        "dojox/mvc/Output",
+		"dojox/mobile/View",
+		"dojox/app/widgets/Container"
+	],
+
+	"modules": [],
+	
+	"controllers": [
+		"dojox/app/controllers/Load",
+		"dojox/app/controllers/Transition",
+		"dojox/app/tests/swapViewTestApp/controllers/DivIdBasedLayout"
+	],
+
+	//stores we are using
+	"stores": {
+	   "namesStore":{
+	       "type": "dojo/store/Memory",
+		   "params": {
+		      "data": "modelApp.names"
+		   }
+	   },
+       "repeatStore":{
+           "type": "dojo/store/Memory",
+           "params": {
+                "data": "modelApp.repeatData"
+           }
+       }
+	},
+
+	//models and instantiation parameters for the models. Including 'type' as a property allows
+	//one to overide the class that will be used for the model.  By default it is dojox/mvc/model
+	"models": {
+	   "names": {
+			"modelLoader": "dojox/app/utils/mvcModel",
+			"type": "dojox/mvc/EditStoreRefListController",
+			"params":{
+				"store": {"$ref":"#stores.namesStore"}
+			}	       
+	   },
+		"repeatmodels": {
+			"modelLoader": "dojox/app/utils/mvcModel",
+			"type": "dojox/mvc/EditStoreRefListController",
+			"params":{
+				"store": {"$ref":"#stores.repeatStore"}
+			}           
+		}
+	}, 
+	
+	// The has section will include the sections for which the has checks are true.  
+	// For the sections with ! it will include the section if the has check is not true.
+	"has" : {
+		"ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/HistoryHash"
+			]
+		},
+		"!ie9orLess" : {
+			"controllers": [
+				"dojox/app/controllers/History"
+			]
+		}
+	},	
+
+
+	//the name of the view to load when the app is initialized.
+	//"defaultView": "header+navigation+TestInfo",
+	"defaultView": "main+header+TestInfo+simple+repeatList+navigation",
+	//"defaultView": "main+navigation+TestInfo+simple+repeatList",
+	
+
+	// these are the possilbe defaultTransitions
+	"defaultTransition": "slide",
+	//"defaultTransition": "none",
+	//"defaultTransition": "fade",
+	//"defaultTransition": "flip",     
+
+	"views": {
+		"main": {
+			"controller" : "swapViewTestApp/views/main.js",
+			"constraint" : "center",
+			"template": "swapViewTestApp/views/main.html"
+		},	
+		"navigation":{
+			"controller" : "swapViewTestApp/views/navigation.js",
+			"constraint" : "nav1Id",
+			"template": "swapViewTestApp/views/navigation.html"
+		},
+		"TestInfo": {
+			"controller" : "swapViewTestApp/views/TestInfo.js",
+			"constraint" : "swapView1Id",
+			"template": "swapViewTestApp/views/TestInfo.html"
+		},	
+		"header":{
+			"constraint" : "heading1Id",
+			"template": "swapViewTestApp/views/header.html"
+		},
+		"simple":{
+			"controller" : "swapViewTestApp/views/simple.js",
+			"constraint" : "swapView2Id",
+			"template": "swapViewTestApp/views/simple.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		},
+
+		"repeatList":{
+			"controller" : "swapViewTestApp/views/repeat.js",
+			"constraint" : "swapView3Id",
+			"template": "swapViewTestApp/views/repeat.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		},
+		"repeatDetails":{
+			"controller" : "swapViewTestApp/views/repeatDetails.js",
+			"constraint" : "swapView3Id",
+			"template": "swapViewTestApp/views/repeatDetails.html",
+			"dependencies":["dojox/mobile/TextBox"]
+		}
+	}	
+}
diff --git a/dojox/app/tests/swapViewTestApp/controllers/DivIdBasedLayout.js b/dojox/app/tests/swapViewTestApp/controllers/DivIdBasedLayout.js
new file mode 100644
index 0000000..1f8c47e
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/controllers/DivIdBasedLayout.js
@@ -0,0 +1,70 @@
+define(["dojo/_base/declare", "dojo/dom", "dojo/dom-style",
+		"dojo/dom-class", "dojo/dom-attr", "dojo/dom-construct", 
+		"dojox/app/controllers/LayoutBase"],
+function(declare, dom, domStyle, domClass, domAttr, domConstruct, LayoutBase){
+	// module:
+	//		dojox/app/tests/swapViewTestApp/controllers/DivIdBasedLayout
+	// summary:
+	//		Will layout an application based upon div ids.  
+	//		Each view will be appended inside the div with the id that matches the value set in the constraints for the view.
+	//		
+
+	return declare("dojox/app/tests/swapViewTestApp/controllers/DivIdBasedLayout", LayoutBase, {
+
+		initLayout: function(event){
+			// summary:
+			//		Response to dojox/app "app-initLayout" event which is setup in LayoutBase.
+			//		The initLayout event is called once when the View is being created the first time.
+			//
+			// example:
+			//		Use emit to trigger "app-initLayout" event, and this function will respond to the event. For example:
+			//		|	this.app.emit("app-initLayout", view);
+			//
+			// event: Object
+			// |		{"view": view, "callback": function(){}};
+			this.app.log("in app/controllers/DivIdBasedLayout.initLayout event.view.name=[",event.view.name,"] event.view.parent.name=[",event.view.parent.name,"]");
+
+
+			this.app.log("in app/controllers/DivIdBasedLayout.initLayout event.view.constraint=",event.view.constraint);
+			var constraint = event.view.constraint;  // constraint holds the region for this view, center, top etc.
+			var parentDiv = dom.byId(constraint);
+			if(parentDiv){  // If the parentDiv is found append this views domNode to it
+				parentDiv.appendChild(event.view.domNode);
+			}else{
+				event.view.parent.domNode.appendChild(event.view.domNode);
+			//	domClass.add(event.view.domNode, constraint);  // set the class to the constraint
+			}
+
+			this.inherited(arguments);
+		},
+
+		onResize: function(){
+			// do nothing on resize
+		},
+
+		hideView: function(view){
+			domStyle.set(view.domNode, "display", "none");
+			//var sc = registry.byId(view.parent.id+"-"+view.constraint);
+			//if(sc){
+			//	sc.removedFromBc = true;
+			//	sc.removeChild(view.domNode);
+			//}
+		},
+
+		showView: function(view){
+			domStyle.set(view.domNode, "display", "");
+			
+			//var sc = registry.byId(view.parent.id+"-"+view.constraint);
+			//if(sc){
+			//	if(sc.removedFromBc){
+			//		sc.removedFromBc = false;
+			//		registry.byId(this.app.id+"-BC").addChild(sc);
+			//		domStyle.set(view.domNode, "display", "");
+			//	}
+			//	domStyle.set(cp.domNode, "display", "");
+			//	sc.selectChild(cp);
+			//	sc.resize();
+			//}
+		}
+	});
+});
diff --git a/dojox/app/tests/swapViewTestApp/css/layoutApp.css b/dojox/app/tests/swapViewTestApp/css/layoutApp.css
new file mode 100644
index 0000000..fb6a180
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/css/layoutApp.css
@@ -0,0 +1,271 @@
+.main {
+	float: left;
+	width: 100%;
+	height: 100% 
+}
+
+.mainCenter {
+	left: 251px !important;
+}
+
+.center {
+	float: left;
+	width: 900px;
+	height: 100% 
+}
+
+/*
+.top {
+	float: top;
+}
+*/
+
+.left {
+	float: left; 
+	width:250px;
+	background-color: #C5CCD3;
+	z-index:100;	
+	height: 100% 
+}
+
+#headerBackButton {
+	display: none;
+}
+
+ at media screen and (max-width: 1154px) {
+	.center {
+		float: left;
+		width: 600px 
+	}
+
+	.left {
+		float: left; 
+		width:250px;
+		background-color: #C5CCD3;
+		z-index:100;	
+		height: 100% 
+	}
+
+}
+
+ at media screen and (max-width: 854px) {
+	.center {
+		float: left;
+		width: 520px;
+		height: 100%;
+		
+	}
+
+	.left {
+		float: left; 
+		width:250px;
+		background-color: #C5CCD3;
+		z-index:100;	
+		height: 100% 
+	}
+
+}
+
+ at media screen and (max-width: 560px) {
+	.center {
+		float: left;
+		width: 100%; 
+	}
+
+	.mainCenter {
+		left: 0 !important;
+	}
+
+	.left {
+		display: none;
+		float: left; 
+		width:0;
+	}
+
+	#headerBackButton {
+		display: block;
+	}
+
+}
+
+
+ at media only screen and (orientation: portrait) {
+	.center {
+		float: left;
+		width: 100%; 
+	}
+
+	.mainCenter {
+		left: 0 !important;
+	}
+
+	.left {
+		display: none;
+		float: left; 
+		width:0;
+	}
+
+	#headerBackButton {
+		display: block;
+	}
+}
+
+ at media only screen and (orientation: landscape) and (max-width: 568px) {
+	.center {
+		float: left;
+		width: 360px;
+		height: 100%;
+	}
+
+	.mainCenter {
+		left: 151px !important;
+	}
+
+	.left {
+		float: left; 
+		width:150px;
+		background-color: #C5CCD3;
+		z-index:100;	
+		height: 100% 
+	}
+
+}
+
+/*@media only screen and (device-width: 480px) and (orientation: landscape) and (resolution: 163dpi) { */
+	/* CSS3 Rules for XX iPhone in Portrait Orientation */
+/*@media only screen and (device-width: 568px) and (orientation: landscape) {
+	.center {
+		float: left;
+		width: 300px;
+		height: 100%;
+		
+	}
+
+	.left {
+		float: left; 
+		width:100px;
+		border-right:1px solid black;
+		background-color: #C5CCD3;
+		z-index:100;	
+		height: 100% 
+	}
+}
+*/
+
+
+
+html,body {
+	width: 100%;
+	height: 100%;
+}
+
+button.baseBtn {
+	-webkit-background-clip: padding-box;
+	-webkit-box-align: center;
+	background-clip: padding-box;
+	border-style: solid;
+	border-width: 1px;
+	color: black;
+	font-family: 'Helvetica Neue', HelveticaNeue, Helvetica-Neue, Helvetica, 'BBAlpha Sans';
+	font-size: 18px;
+	font-weight: bold;
+	vertical-align: middle;
+	margin: 10px;
+	height: 34px;
+	border-bottom-left-radius: 7px;
+	border-bottom-right-radius: 7px;
+	border-top-left-radius: 7px;
+	border-top-right-radius: 7px;
+	width: 240px;
+}
+
+button.whiteBtn{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(white), color-stop(0.06, #f2f2f2), to(#b7b7b7));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+button.whiteBtnSelected{
+	background-image: -webkit-gradient(linear, 0% 0, 0% 100%, from(#ffffff), color-stop(0.06, #bbbbbb), to(#fcfcfc));
+	border-color: #979797;
+	border-bottom-color: #727272;
+}
+
+#header button {
+	position:absolute;
+	margin:0;
+}
+
+#navButton {
+	width:60px;
+}
+
+#loadDiv {
+	position:absolute;
+	left:0;
+	top:0;
+	width:100%;
+	height:100%;
+	z-index:999;
+}
+#loadDiv {
+	display:table;
+	font-size: 20px;
+	text-align:center;
+	background-color:white;
+}
+#loadDiv span {
+	display:table-cell;
+	vertical-align:middle;
+}
+
+body .mblProgContainer {
+	top:45%;
+	height: 45px;
+	width: 140px;
+	margin-left:-70px;
+	background-color: #2A2A28;
+	border-style: solid;
+	border-width: 2px;
+	border-color: #666666;
+	border-radius: 0.4em;
+	-webkit-border-radius: 0.4em;
+	-moz-border-radius: 0.4em;
+}
+
+body .mblProgContainer > div {
+	height: 100%;
+	width: 100%;
+	line-height: 45px;
+	vertical-align: middle;
+	font-size: 20px;
+	color: #c2c2c2;
+}
+
+body .mblProg {
+	left: 3px;
+	top: 3px;
+}
+
+#jsContent, #htmlContent {
+	padding-left:2px;
+}
+
+ at media screen and (max-width: 600px) {
+	#jsContent, #htmlContent {
+		font-size: 14px;
+	}
+}
+
+.hidden {
+	display:none;
+}
+
+/*
+.navPane {
+	width:250px;
+	border-right:1px solid black;
+	background-color: #C5CCD3;
+	z-index:100;
+}
+*/
diff --git a/dojox/app/tests/swapViewTestApp/index.html b/dojox/app/tests/swapViewTestApp/index.html
new file mode 100644
index 0000000..5b01d26
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/index.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+
+		<title>Media Query Layout App</title>
+		<link type="text/css" href="./css/layoutApp.css" rel="stylesheet" />
+		<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false,
+				mblHideAddressBar: false,
+				mblAndroidWorkaround: false,
+				mblAlwaysHideAddressBar: false,
+				app: {debugApp: 1},  // set debugApp to log app transtions and view activate/deactivate
+				async: 1">
+		</script>
+		<script>
+			require(["./layoutApp.js"], function(){
+			});
+		</script>
+
+		
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/app/tests/swapViewTestApp/layoutApp.js b/dojox/app/tests/swapViewTestApp/layoutApp.js
new file mode 100644
index 0000000..b7559d2
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/layoutApp.js
@@ -0,0 +1,55 @@
+require(["dojo/_base/window","dojox/app/main", "dojox/json/ref", "dojo/text!./config.json", "dojo/sniff"],
+	function(win, Application, jsonRef, config, has){
+	win.global.modelApp = {};
+	modelApp.names = {
+		identifier: "id",
+		items: [{
+			"id": "1",
+			"Serial": "360324",
+			"First": "John",
+			"Last": "Doe",
+			"Email": "jdoe at us.ibm.com",
+			"ShipTo": {
+				"Street": "123 Valley Rd",
+				"City": "Katonah",
+				"State": "NY",
+				"Zip": "10536"
+			},
+			"BillTo": {
+				"Street": "17 Skyline Dr",
+				"City": "Hawthorne",
+				"State": "NY",
+				"Zip": "10532"
+			}
+		}]
+	};
+	modelApp.repeatData = [{
+		"First": "Chad",
+		"Last": "Chapman",
+		"Location": "CA",
+		"Office": "1278",
+		"Email": "c.c at test.com",
+		"Tel": "408-764-8237",
+		"Fax": "408-764-8228"
+	}, {
+		"First": "Irene",
+		"Last": "Ira",
+		"Location": "NJ",
+		"Office": "F09",
+		"Email": "i.i at test.com",
+		"Tel": "514-764-6532",
+		"Fax": "514-764-7300"
+	}, {
+		"First": "John",
+		"Last": "Jacklin",
+		"Location": "CA",
+		"Office": "6701",
+		"Email": "j.j at test.com",
+		"Tel": "408-764-1234",
+		"Fax": "408-764-4321"
+	}];
+	var cfg = jsonRef.fromJson(config);
+	has.add("ie9orLess", has("ie") && (has("ie") <= 9));
+	Application(cfg);
+	
+});
diff --git a/dojox/app/tests/swapViewTestApp/views/TestInfo.html b/dojox/app/tests/swapViewTestApp/views/TestInfo.html
new file mode 100644
index 0000000..fa7d88f
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/TestInfo.html
@@ -0,0 +1,23 @@
+<div class="view mblView">
+
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+
+	<!--<div data-dojo-type="dojox/mobile/ScrollableView"> -->
+	<div>
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Test Info for this test.</h2>
+
+		<div>
+			<div class="field-title">This test has been setup to use a custom layout controller (DivIdBasedLayout) along with mobile/SwapView and mobile/PageIndicator.</div>
+			<div class="field-title">The DivIdBasedLayout will try to layout views by appending them inside the div with the id that matches the value set in the constraints for the view.</div>
+			<br>
+			<div class="field-title">There are 3 views shown in the SwapViews, they can be seen by swipping from the left to the right in the main content area, the Header and Nav area are also added to the main area by div id.</div>
+			<div class="field-title">The 3rd view will transition to a details view, which will add a Back button to return to this view, the swapViews are still active after the transition.</div>
+			<br>
+			<div class="field-title">Some of the css from the mediaQueryLayout test is included, so on a desktop you can make the window smaller and the navigation area will become hidden when the screen gets less than max-width: 560px.</div>
+			<div class="field-title">And on a phone or tablet the Naviagtion will be hidden in portrait orientation and shown in landscape orientation.</div>
+			<br>
+			<div class="field-title">Should try to get rid of the FixedSplitters in main.html and just use css for positioning, also add nested footer and right side nav.</div>
+			<br><br>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/swapViewTestApp/views/TestInfo.js b/dojox/app/tests/swapViewTestApp/views/TestInfo.js
new file mode 100644
index 0000000..114ce61
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/TestInfo.js
@@ -0,0 +1,53 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect"], function(dom, domStyle, connect){
+	var _connectResults = []; // events connect result
+
+	return {
+		// view init
+		init: function(){
+		},
+		
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+		/*
+		 	var connectResult;
+			var backButtomDom = dom.byId('headerBackButton');
+			connectResult = connect.connect(backButtomDom, "onclick", function(e){
+				// transition to repeatDetails view with the &cursor=index
+				
+				var transOpts = {
+					title:'main+TestInfo+simple+repeatList+navigation+header',
+					target:'main+TestInfo+simple+repeatList+navigation+header',
+					url:'#main+TestInfo+simple+repeatList+navigation+header'					
+				};
+				new TransitionEvent(e.target, transOpts, e).dispatch(); 
+
+			});
+		*/	
+			
+		},
+
+
+		afterDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		},
+		
+		// view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+
+		}
+	};
+});
diff --git a/dojox/app/tests/swapViewTestApp/views/header.html b/dojox/app/tests/swapViewTestApp/views/header.html
new file mode 100644
index 0000000..790bb93
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/header.html
@@ -0,0 +1,4 @@
+<div>
+	<!-- top -->
+	<div data-dojo-type="dojox/mobile/Heading" fixed="top">This shows a SwapView with a PageIndicator</div>
+</div>
diff --git a/dojox/app/tests/swapViewTestApp/views/main.html b/dojox/app/tests/swapViewTestApp/views/main.html
new file mode 100644
index 0000000..4caab40
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/main.html
@@ -0,0 +1,35 @@
+<div id="settings" class="view mblView main">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<div data-dojo-type="dojox/mobile/FixedSplitter" data-dojo-props='orientation:"V"'>
+		<div data-dojo-type="dojox/mobile/Container" style="overflow:hidden;">
+		<!--	<div data-dojo-type="dojox/mobile/Heading"  fixed:"top">This is a SwapView with a PageIndicator</div> -->
+			<div id="heading1Id"></div>
+		</div>
+		
+	<div data-dojo-type="dojox/mobile/FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox/mobile/Container" style="overflow:hidden;  border-right: 1px solid black;">
+			<div id="nav1Id"></div>
+		</div>
+
+		<div data-dojo-type="dojox/mobile/Container" class="mainCenter" style="overflow:hidden;">
+			<div id="swap1" data-dojo-type="dojox/mobile/SwapView">
+				<div data-dojo-type="dojox/mobile/ScrollableView" data-dojo-props='height:"100%"'>
+					<div id="swapView1Id"></div>
+				</div>
+			</div>
+
+			<div id="swap2" data-dojo-type="dojox/mobile/SwapView">
+				<div data-dojo-type="dojox/mobile/ScrollableView" data-dojo-props='height:"100%"'>
+					<div id="swapView2Id"></div>
+				</div>
+			</div>
+
+			<div id="swap3" data-dojo-type="dojox/mobile/SwapView">
+					<div id="swapView3Id"></div>
+			</div>
+
+			<div data-dojo-type="dojox/mobile/PageIndicator" data-dojo-props='fixed:"bottom"'></div>
+		</div>
+	</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/swapViewTestApp/views/main.js b/dojox/app/tests/swapViewTestApp/views/main.js
new file mode 100644
index 0000000..6aa9c55
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/main.js
@@ -0,0 +1,76 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry", "dojox/mvc/at"],
+function(dom, connect, registry, at){
+	var _connectResults = []; // events connect results
+	var currentModel = null;
+
+	var setRef = function (id, attr){
+		var widget = registry.byId(id);
+		widget.set("target", at("rel:", attr));
+		console.log("setRef done.");
+	};
+	return {
+		// main view init
+		init: function(){
+		},
+		
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			currentModel = this.loadedModels.names;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId('shipto'), "click", function(){
+				setRef('addrGroup', 'ShipTo');
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('billto'), "click", function(){
+				setRef('addrGroup', 'BillTo');
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('reset1'), "click", function(){
+				currentModel.reset();
+				console.log("reset done. ");
+			});
+			_connectResults.push(connectResult);
+		/*	
+			var backButtomDom = dom.byId('headerBackButton');
+			connectResult = connect.connect(backButtomDom, "onclick", function(e){
+				// transition to repeatDetails view with the &cursor=index
+				
+				var transOpts = {
+					title:'main+TestInfo+simple+repeatList+navigation+header',
+					target:'main+TestInfo+simple+repeatList+navigation+header',
+					url:'#main+TestInfo+simple+repeatList+navigation+header'					
+				};
+				new TransitionEvent(e.target, transOpts, e).dispatch(); 
+
+			});
+		*/	
+			
+		},
+
+		afterDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		},
+		
+
+		// main view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/swapViewTestApp/views/navigation.html b/dojox/app/tests/swapViewTestApp/views/navigation.html
new file mode 100644
index 0000000..6ea8eec
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/navigation.html
@@ -0,0 +1,21 @@
+<div class="navPane">
+	<!-- left -->
+	<div data-dojo-type="dojox/app/widgets/Container" id="NavWidId" class="navPane left" data-app-constraint="left">
+
+	<!-- <div data-dojo-type="dojox/app/widgets/Container" data-app-constraint="center" data-dojo-props="scrollable:true">  -->
+		<div>
+		<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Navigation</h2>
+			<ul data-dojo-type="dojox/mobile/RoundRectList" data-app-constraint="center">
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true">
+					Dummy item 1
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true">
+					Dummy item 2
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props="clickable:true">
+					Dummy item 3
+				</li>
+			</ul>
+		</div>
+	</div>
+</div>
diff --git a/dojox/app/tests/swapViewTestApp/views/navigation.js b/dojox/app/tests/swapViewTestApp/views/navigation.js
new file mode 100644
index 0000000..0fd5746
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/navigation.js
@@ -0,0 +1,34 @@
+define(["dojo/dom", "dojo/dom-style", "dojo/_base/connect"], function(dom, domStyle, connect){
+	var _connectResults = []; // events connect result
+
+	return {
+		// view init
+		init: function(){
+		},
+		
+		beforeActivate: function(view){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			this.previousView = view;
+			
+			// setup code to watch for the navigation pane being visible
+			
+		},
+
+		beforeDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+		},
+		
+		// view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/swapViewTestApp/views/repeat.html b/dojox/app/tests/swapViewTestApp/views/repeat.html
new file mode 100644
index 0000000..b370340
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/repeat.html
@@ -0,0 +1,24 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+   	<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Repeat Data Binding Example</h2>
+ 
+    <form name="repeatTestForm" id="repeatTestForm">    
+    	<div class="field-title">Search Results</div>
+        <div id="repeatWidget" class="fieldset" data-dojo-type="dojox/mvc/Repeat" 
+        	data-dojo-props="exprchar: '#', children: this.loadedModels.repeatmodels.model" >
+           <div class="row">            
+                    <input data-dojo-type="dojox/mobile/TextBox"
+                        id="nameInput#{this.index}" data-dojo-props="value: at('rel:#{this.index}','First')" placeHolder="First Name">
+                    <button type="button" id="detail#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        Details
+                    </button>
+                    <button type="button" id="insert#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        +
+                    </button>
+                    <button type="button" id="delete#{this.index}" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+                        -
+                    </button>
+			</div>
+        </div>
+	</form>
+</div>
diff --git a/dojox/app/tests/swapViewTestApp/views/repeat.js b/dojox/app/tests/swapViewTestApp/views/repeat.js
new file mode 100644
index 0000000..87ea3bb
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/repeat.js
@@ -0,0 +1,122 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry", "dojox/mvc/at", "dojox/mobile/TransitionEvent", "dojox/mvc/Repeat", "dojox/mvc/getStateful"],
+function(dom, connect, registry, at, TransitionEvent, Repeat, getStateful){
+	var _connectResults = []; // events connect result
+
+	var repeatmodel = null;	//repeat view data model
+
+	// delete an item
+	var deleteResult = function(index){
+		var nextIndex = repeatmodel.get("cursorIndex");
+		if(nextIndex >= index){
+			nextIndex = nextIndex-1;
+		}
+		repeatmodel.model.splice(index, 1);
+		repeatmodel.set("cursorIndex", nextIndex);		
+	};
+	// show an item detail
+	var setDetailsContext = function(index,e){
+		repeatmodel.set("cursorIndex", index);
+
+		// transition to repeatDetails view with the &cursor=index
+		var transOpts = {
+	//		title : "main+TestInfo+simple+repeatDetails+navigation+header",
+	//		target : "main+TestInfo+simple+repeatDetails+navigation+header",
+	//		url : "#main+TestInfo+simple+repeatDetails+navigation+header", // this is optional if not set it will be created from target   
+			title : "main+TestInfo+simple+repeatDetails+navigation",
+			target : "main+TestInfo+simple+repeatDetails+navigation",
+			url : "#main+TestInfo+simple+repeatDetails+navigation", // this is optional if not set it will be created from target   
+			params : {"cursor":index}
+		};
+		new TransitionEvent(e.target, transOpts, e).dispatch(); 
+		
+	};
+	// insert an item
+	var insertResult = function(index, e){
+		if(index<0 || index>repeatmodel.model.length){
+			throw Error("index out of data model.");
+		}
+		if((repeatmodel.model[index].First=="") ||
+			(repeatmodel.model[index+1] && (repeatmodel.model[index+1].First == ""))){
+			return;
+		}
+		var data = {id:Math.random(), "First": "", "Last": "", "Location": "CA", "Office": "", "Email": "", "Tel": "", "Fax": ""};
+		repeatmodel.model.splice(index+1, 0, new getStateful(data));
+		setDetailsContext(index+1, e);
+	};
+	// get index from dom node id
+	var getIndexFromId = function(nodeId, perfix){
+		var len = perfix.length;
+		if(nodeId.length <= len){
+			throw Error("repeat node id error.");
+		}
+		var index = nodeId.substring(len, nodeId.length);
+		return parseInt(index);
+	};
+
+	return {
+		// repeat view init
+		init: function(){
+			repeatmodel = this.loadedModels.repeatmodels;
+		},
+		
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			var repeatDom = dom.byId('repeatWidget');
+			var connectResult;
+			connectResult = connect.connect(repeatDom, "button[id^=\"detail\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "detail");
+				setDetailsContext(index, e);
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(repeatDom, "button[id^=\"insert\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "insert");
+				insertResult(index, e);
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(repeatDom, "button[id^=\"delete\"]:click", function(e){
+				var index = getIndexFromId(e.target.id, "delete");
+				deleteResult(index);
+			});
+			_connectResults.push(connectResult);
+		/*	
+			var backButtomDom = dom.byId('headerBackButton');
+			connectResult = connect.connect(backButtomDom, "onclick", function(e){
+				// transition to repeatDetails view with the &cursor=index
+				
+				var transOpts = {
+					title:'main+TestInfo+simple+repeatList+navigation+header',
+					target:'main+TestInfo+simple+repeatList+navigation+header',
+					url:'#main+TestInfo+simple+repeatList+navigation+header'					
+				};
+				new TransitionEvent(e.target, transOpts, e).dispatch(); 
+
+			});
+		*/	
+			
+		},
+
+		afterDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		},
+		
+		// view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/tests/swapViewTestApp/views/repeatDetails.html b/dojox/app/tests/swapViewTestApp/views/repeatDetails.html
new file mode 100644
index 0000000..f99dd8d
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/repeatDetails.html
@@ -0,0 +1,48 @@
+<div class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+    <h4 data-dojo-type="dojox/mobile/Heading" data-dojo-props='back:"Back"'>Repeat Details</h4>
+   	<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory"  data-dojo-props='back:"Back"' style="height: 32px;" data-app-constraint="top">Repeat Data Binding Example</h2>
+    
+    <form name="repeatTestForm" id="repeatTestForm">    
+		<div data-dojo-type="dojox/mvc/Group" 
+			data-dojo-props="target: at(this.loadedModels.repeatmodels, 'cursor')">
+					<div class="field-title">
+						<div style="display: inline-block;" id="detailsBanner">Details for selected index:</div>
+						<span class="cell" id="indexOutput"
+							data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at(this.loadedModels.repeatmodels, 'cursorIndex')"></span>
+					</div>
+					<table id="table" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'First'), placeholder:'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput" data-dojo-type="dojox/mobile/TextBox"
+									 
+									data-dojo-props="placeholder:'Last Name', value: at('rel:', 'Last')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput2" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Email'), placeholder:'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Tel'), placeholder:'Telephone'">
+							</td>
+						</tr>
+					</table>
+		</div>
+		</form>
+</div>
diff --git a/dojox/app/tests/swapViewTestApp/views/repeatDetails.js b/dojox/app/tests/swapViewTestApp/views/repeatDetails.js
new file mode 100644
index 0000000..87f2f0d
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/repeatDetails.js
@@ -0,0 +1,29 @@
+define([], function(){
+
+	var repeatmodel = null;	//repeat view data model
+
+	// show an item detail
+	var setDetailsContext = function(index){
+		// only set the cursor if it is different and valid
+		if(parseInt(index) != repeatmodel.cursorIndex && parseInt(index) < repeatmodel.model.length){
+			repeatmodel.set("cursorIndex", parseInt(index));
+		}
+	};
+
+	return {
+		// repeat view init
+		init: function(){
+			repeatmodel = this.loadedModels.repeatmodels;
+		},
+
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			// if this.params["cursor"] is set use it to set the selected Details Context
+			if(this.params["cursor"]){
+				setDetailsContext(this.params["cursor"]);
+			}
+		}
+	}
+});
diff --git a/dojox/app/tests/swapViewTestApp/views/simple.html b/dojox/app/tests/swapViewTestApp/views/simple.html
new file mode 100644
index 0000000..b655ad3
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/simple.html
@@ -0,0 +1,90 @@
+<div id="settings" class="view mblView">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h2 data-dojo-type="dojox/mobile/EdgeToEdgeCategory" style="height: 32px;" data-app-constraint="top">Simple Data Binding Example</h2>
+	
+		<form name="testForm" id="testForm">
+			<div class="field-title">
+				Ship to - Bill to Address
+			</div>
+			<div class="fieldset" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(this.loadedModels.names, 'model')">
+				<div data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:', 0)">
+					<table id="table" cellspacing="10" style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">
+								First
+							</td>
+							<td class="layout">
+								<input id="firstInput1" data-dojo-type="dojox/mobile/TextBox" data-dojo-props="value: at('rel:', 'First'), placeholder:'First'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">
+								Last Name
+							</td>
+							<td class="layout">
+								<input id="lastInput1" data-dojo-type="dojox/mobile/TextBox" data-dojo-props="placeholder:'Last Name', value: at('rel:', 'Last')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">
+								Email
+							</td>
+							<td class="layout">
+								<input id="emailInput1" data-dojo-type="dojox/mobile/TextBox" data-dojo-props="value: at('rel:', 'Email'), placeholder:'Email'">
+							</td>
+						</tr>
+					</table>
+					<div class="spacer">
+					</div>
+					<button id="shipto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+						Ship To
+					</button>
+					<button id="billto" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+						Bill To
+					</button>
+					<br/>
+					<div class="fieldset" id="addrGroup" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:','ShipTo')">
+						<table id="table" cellspacing="10" style="width: 100%">
+							<tr>
+								<td style="width: 100px;" class="layout">
+									Street
+								</td>
+								<td class="layout">
+									<input id="streetInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-props="value: at('rel:', 'Street'), placeholder:'Street'">
+								</td>
+							</tr>
+							<tr>
+								<td style="width: 100px;" class="layout">
+									City
+								</td>
+								<td class="layout">
+									<input id="cityInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-props="placeholder:'City', value: at('rel:', 'City')">
+								</td>
+							</tr>
+							<tr>
+								<td style="width: 100px;" class="layout">
+									State
+								</td>
+								<td class="layout">
+									<input id="StateInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-props="value: at('rel:', 'State'), placeholder:'State'">
+								</td>
+							</tr>
+							<tr>
+								<td style="width: 100px;" class="layout">
+									State
+								</td>
+								<td class="layout">
+									<input id="ZipInput" data-dojo-type="dojox/mobile/TextBox" data-dojo-props="value: at('rel:', 'Zip'), placeholder:'Zip Code'">
+								</td>
+							</tr>
+						</table>
+					</div>
+				</div>
+			</div>
+			<div class="spacer">
+			</div>
+			<button id="reset1" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton">
+				Reset
+			</button>
+		</form>
+</div>
diff --git a/dojox/app/tests/swapViewTestApp/views/simple.js b/dojox/app/tests/swapViewTestApp/views/simple.js
new file mode 100644
index 0000000..e86c7a1
--- /dev/null
+++ b/dojox/app/tests/swapViewTestApp/views/simple.js
@@ -0,0 +1,76 @@
+define(["dojo/dom", "dojo/_base/connect", "dijit/registry", "dojox/mvc/at"],
+function(dom, connect, registry, at){
+	var _connectResults = []; // events connect results
+	var currentModel = null;
+
+	var setRef = function (id, attr){
+		var widget = registry.byId(id);
+		widget.set("target", at("rel:", attr));
+		console.log("setRef done.");
+	};
+	return {
+		// simple view init
+		init: function(){
+		},
+		
+		beforeActivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			currentModel = this.loadedModels.names;
+			var connectResult;
+
+			connectResult = connect.connect(dom.byId('shipto'), "click", function(){
+				setRef('addrGroup', 'ShipTo');
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('billto'), "click", function(){
+				setRef('addrGroup', 'BillTo');
+			});
+			_connectResults.push(connectResult);
+
+			connectResult = connect.connect(dom.byId('reset1'), "click", function(){
+				currentModel.reset();
+				console.log("reset done. ");
+			});
+			_connectResults.push(connectResult);
+		/*	
+			var backButtomDom = dom.byId('headerBackButton');
+			connectResult = connect.connect(backButtomDom, "onclick", function(e){
+				// transition to repeatDetails view with the &cursor=index
+				
+				var transOpts = {
+					title:'main+TestInfo+simple+repeatList+navigation+header',
+					target:'main+TestInfo+simple+repeatList+navigation+header',
+					url:'#main+TestInfo+simple+repeatList+navigation+header'					
+				};
+				new TransitionEvent(e.target, transOpts, e).dispatch(); 
+
+			});
+		*/	
+			
+		},
+
+		afterDeactivate: function(){
+			// summary:
+			//		view life cycle beforeActivate()
+			//
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		},
+		
+
+		// view destroy
+		destroy: function(){
+			var connectResult = _connectResults.pop();
+			while(connectResult){
+				connect.disconnect(connectResult);
+				connectResult = _connectResults.pop();
+			}
+		}
+	};
+});
diff --git a/dojox/app/transition.js b/dojox/app/transition.js
deleted file mode 100644
index 39e2ed0..0000000
--- a/dojox/app/transition.js
+++ /dev/null
@@ -1,60 +0,0 @@
-define(["dojo/_base/kernel", "dojo/_base/array","dojo/_base/html","dojo/DeferredList","./animation"],
-	function(dojo, darray, dhtml, DeferredList,animation){
-	return function(from, to, options){
-		var rev = (options && options.reverse) ? -1 : 1;
-		if(!options || !options.transition || !animation[options.transition]){
-			dojo.style(from,"display","none");
-			dojo.style(to, "display", "");
-			if(options.transitionDefs){
-			    if(options.transitionDefs[from.id]){
-			        options.transitionDefs[from.id].resolve(from);
-			    }
-			    if(options.transitionDefs[to.id]){
-                                options.transitionDefs[to.id].resolve(to);
-                            }
-			}
-		}else{
-			var defs=[];
-			var transit=[];
-			var duration = 250;
-			if(options.transition === "fade"){
-			    duration = 600;
-			}else if (options.transition === "flip"){
-			    duration = 200;
-			}
-			dojo.style(from, "display", ""); 
-			dojo.style(to, "display", "");
-			if (from){
-				//create animation to transit "from" out
-				var fromTransit = animation[options.transition](from, {
-				    "in": false,
-				    direction: rev,
-				    duration: duration,
-				    deferred: (options.transitionDefs && options.transitionDefs[from.id]) ? options.transitionDefs[from.id] : null
-				});
-				defs.push(fromTransit.deferred);//every animation object should have a deferred.
-				transit.push(fromTransit);
-			}
-			
-			//create animation to transit "to" in	                
-			var toTransit = animation[options.transition](to, {
-                            direction: rev,
-                            duration: duration,
-                            deferred: (options.transitionDefs && options.transitionDefs[to.id]) ? options.transitionDefs[to.id] : null
-                        });
-			defs.push(toTransit.deferred);//every animation object should have a deferred.
-			transit.push(toTransit);
-			
-			//TODO If it is flip use the chainedPlay
-			//play fromTransit and toTransit together
-			if(options.transition === "flip"){
-			    animation.chainedPlay(transit);
-			}else{
-			    animation.groupedPlay(transit);
-			}
-
-			return new dojo.DeferredList(defs);
-			
-		}
-	};
-});
diff --git a/dojox/app/utils/config.js b/dojox/app/utils/config.js
new file mode 100644
index 0000000..1f6e4e3
--- /dev/null
+++ b/dojox/app/utils/config.js
@@ -0,0 +1,85 @@
+define(["dojo/sniff"], function(has){
+
+// module:
+//		dojox/app/utils/config
+
+return {
+	// summary:
+	//		This module contains the config
+
+	configProcessHas: function(/*Object*/ source){
+		// summary:
+		//		scan the source config for has checks and call configMerge to merge has sections, and remove the has sections from the source.
+		// description:
+		//		configProcessHas will scan the source config for has checks. 
+		//		For each has section the items inside the has section will be tested with has (sniff)
+		//		If the has test is true it will call configMerge to merge has sections back into the source config.
+		//		It will always remove the has section from the source after processing it.
+		//		The names in the has section can be separated by a comma, indicating that any of those being true will satisfy the test.
+		// source:
+		//		an object representing the config to be processed.
+		// returns:
+		//		the updated source object.
+		for(var name in source){
+			var	sval = source[name];
+			if(name == "has"){ // found a "has" section in source
+				for(var hasname in sval){ // get the hasnames from the has section
+					if(!(hasname.charAt(0) == '_' && hasname.charAt(1) == '_') && sval && typeof sval === 'object'){
+						// need to handle multiple has checks separated by a ",".
+						var parts = hasname.split(',');
+						if(parts.length > 0){
+							while(parts.length > 0){ 	
+								var haspart = parts.shift();
+								// check for has(haspart) or if haspart starts with ! check for !(has(haspart))
+								if((has(haspart)) || (haspart.charAt(0) == '!' && !(has(haspart.substring(1))))){ // if true this one should be merged
+									var hasval = sval[hasname];
+									this.configMerge(source, hasval); // merge this has section into the source config
+									break;	// found a match for this multiple has test, so go to the next one
+								}
+							}
+						}
+					}
+				}
+				delete source["has"];	// after merge remove this has section from the config
+			}else{
+				if(!(name.charAt(0) == '_' && name.charAt(1) == '_') && sval && typeof sval === 'object'){
+						this.configProcessHas(sval);
+				}
+			}
+		}
+		return source;
+	},
+
+	configMerge: function(/*Object*/ target, /*Object*/ source){
+		// summary:
+		//		does a deep copy of the source into the target to merge the config from the source into the target
+		// description:
+		//		configMerge will merge the source config into the target config with a deep copy.
+		//		anything starting with __ will be skipped and if the target is an array the source items will be pushed into the target.
+		// target:
+		//		an object representing the config which will be updated by merging in the source.
+		// source:
+		//		an object representing the config to be merged into the target.
+		// returns:
+		//		the updated target object.
+
+		for(var name in source){
+			var tval = target[name];
+			var	sval = source[name];
+			if(tval !== sval && !(name.charAt(0) == '_' && name.charAt(1) == '_')){
+				if(tval && typeof tval === 'object' && sval && typeof sval === 'object'){
+					this.configMerge(tval, sval);
+				}else{
+					if(target instanceof Array){
+						target.push(sval);
+					}else{
+						target[name] = sval;
+					}
+				}
+			}
+		}
+		return target;
+	}
+};
+
+});
diff --git a/dojox/app/utils/constraints.js b/dojox/app/utils/constraints.js
new file mode 100755
index 0000000..1e4c2d5
--- /dev/null
+++ b/dojox/app/utils/constraints.js
@@ -0,0 +1,99 @@
+define(["dojo/_base/array"], function(arr){
+	var constraints = [];
+	return {
+		getSelectedChild: function(view, constraint){
+			// summary:
+			//		get current selected child according to the constraint
+			//
+			// view: View
+			//		the View to get the child from
+			// constraint: Object
+			//		tbe constraint object
+			//
+			// returns:
+			//		the selected child view for this constraint
+			var type = typeof(constraint);
+			var hash = (type == "string" || type == "number") ? constraint : constraint.__hash;
+			return (view && view.selectedChildren && view.selectedChildren[hash]) ?
+				view.selectedChildren[hash] : null;
+		},
+
+		setSelectedChild: function(view, constraint, child){
+			// summary:
+			//		set current selected child according to the constraint
+			//
+			// view: View
+			//		the View to set the selected child to
+			// constraint: Object
+			//		tbe constraint object
+			// child: View
+			//		the child to select
+			var type = typeof(constraint);
+			var hash = (type == "string" || type == "number") ? constraint : constraint.__hash;
+			view.selectedChildren[hash] = child;
+		},
+
+
+		getAllSelectedChildren: function(view, selChildren){
+			// summary:
+			//		get current all selected children for this view and it's selected subviews
+			//
+			// view: View
+			//		the View to get the child from
+			//
+			// selChildren: Array
+			//		the Array of the subChildren found
+			//
+			// returns:
+			//		selChildren array of all of the selected child views
+			//
+			selChildren = selChildren || [];
+			if(view && view.selectedChildren){
+				for(var hash in view.selectedChildren){
+					if(view.selectedChildren[hash]){
+						var subChild = view.selectedChildren[hash];
+						selChildren.push(subChild);
+						this.getAllSelectedChildren(subChild, selChildren);
+					}
+				}
+			}
+			return selChildren;
+		},
+
+		register: function(constraint){
+			// if the constraint has already been registered we don't care about it...
+			var type = typeof(constraint);
+			if(!constraint.__hash && type != "string" && type != "number"){
+				var match = null;
+				arr.some(constraints, function(item){
+					var ok = true;
+					for(var prop in item){
+						if(prop.charAt(0) !== "_"){//skip the private properties
+							if(item[prop] != constraint[prop]){
+								ok = false;
+								break;
+							}
+						}
+					}
+					if(ok == true){
+						match = item;
+					}
+					return ok;
+				});
+				if(match){
+					constraint.__hash = match.__hash;
+				}else{
+					// create a new "hash"
+					var hash = "";
+					for(var prop in constraint){
+						if(prop.charAt(0) !== "_"){
+							hash += constraint[prop];
+						}
+					}
+					constraint.__hash = hash;
+					constraints.push(constraint);
+				}
+			}
+		}
+	};
+});
\ No newline at end of file
diff --git a/dojox/app/utils/hash.js b/dojox/app/utils/hash.js
new file mode 100755
index 0000000..6ac6ed3
--- /dev/null
+++ b/dojox/app/utils/hash.js
@@ -0,0 +1,176 @@
+define(["dojo/_base/lang"], function(lang){
+
+// module:
+//		dojox/app/utils/hash
+
+var hashUtil = {
+	// summary:
+	//		This module contains the hash
+
+		getParams: function(/*String*/ hash){
+			// summary:
+			//		get the params from the hash
+			//
+			// hash: String
+			//		the url hash
+			//
+			// returns:
+			//		the params object
+			//
+			var params;
+			if(hash && hash.length){
+				// fixed handle view specific params
+				
+				while(hash.indexOf("(") > 0){ 
+					var index = hash.indexOf("(");
+					var endindex = hash.indexOf(")");
+					var viewPart = hash.substring(index,endindex+1);
+					if(!params){ params = {}; }
+					params = hashUtil.getParamObj(params, viewPart);
+					// next need to remove the viewPart from the hash, and look for the next one
+					var viewName = viewPart.substring(1,viewPart.indexOf("&"));
+					hash = hash.replace(viewPart, viewName);
+				}	
+				// after all of the viewParts need to get the other params	
+
+				for(var parts = hash.split("&"), x = 0; x < parts.length; x++){
+					var tp = parts[x].split("="), name = tp[0], value = encodeURIComponent(tp[1] || "");
+					if(name && value){
+						if(!params){ params = {}; }
+						params[name] = value;
+					}
+				}
+			}
+			return params; // Object
+		},
+
+		getParamObj: function(/*Object*/ params, /*String*/ viewPart){
+			// summary:
+			//		called to handle a view specific params object
+			// params: Object
+			//		the view specific params object
+			// viewPart: String
+			//		the part of the view with the params for the view
+			//
+			// returns:
+	 		//		the params object for the view
+			//
+			var viewparams;
+			var viewName = viewPart.substring(1,viewPart.indexOf("&"));
+			var hash = viewPart.substring(viewPart.indexOf("&"), viewPart.length-1);
+				for(var parts = hash.split("&"), x = 0; x < parts.length; x++){
+					var tp = parts[x].split("="), name = tp[0], value = encodeURIComponent(tp[1] || "");
+					if(name && value){
+						if(!viewparams){ viewparams = {}; }
+						viewparams[name] = value;
+					}
+				}
+			params[viewName] = 	viewparams;
+			return params; // Object
+		},
+
+		buildWithParams: function(/*String*/ hash, /*Object*/ params){
+			// summary:
+			//		build up the url hash adding the params
+			// hash: String
+			//		the url hash
+			// params: Object
+			//		the params object
+			//
+			// returns:
+	 		//		the params object
+			//
+			if(hash.charAt(0) !== "#"){
+				hash = "#"+hash;
+			}
+			for(var item in params){
+				var value = params[item];
+				// add a check to see if the params includes a view name if so setup the hash like (viewName&item=value);
+				if(lang.isObject(value)){
+					hash = hashUtil.addViewParams(hash, item, value);
+				}else{
+					if(item && value != null){
+						hash = hash+"&"+item+"="+params[item];
+					}
+				}
+			}
+			return hash; // String
+		},
+
+		addViewParams: function(/*String*/ hash, /*String*/ view, /*Object*/ params){
+			// summary:
+			//		add the view specific params to the hash for example (view1&param1=value1)
+			// hash: String
+			//		the url hash
+			// view: String
+			//		the view name
+			// params: Object
+			//		the params for this view
+			//
+			// returns:
+			//		the hash string
+			//
+			if(hash.charAt(0) !== "#"){
+				hash = "#"+hash;
+			}
+			var index = hash.indexOf(view);
+			if(index > 0){ // found the view?
+				if((hash.charAt(index-1) == "#" || hash.charAt(index-1) == "+") && // assume it is the view? or could check the char after for + or & or -
+					(hash.charAt(index+view.length) == "&" || hash.charAt(index+view.length) == "+" || hash.charAt(index+view.length) == "-")){
+					// found the view at this index.
+					var oldView = hash.substring(index-1,index+view.length+1);
+					var paramString = hashUtil.getParamString(params);
+					var newView = hash.charAt(index-1) + "(" + view + paramString + ")" + hash.charAt(index+view.length);
+					hash = hash.replace(oldView, newView);
+				}
+			}
+			
+			return hash; // String
+		},
+
+		getParamString: function(/*Object*/ params){
+			// summary:
+			//		return the param string
+			// params: Object
+			//		the params object
+			//
+			// returns:
+			//		the params string
+			//
+			var paramStr = "";
+			for(var item in params){
+				var value = params[item];
+				if(item && value != null){
+					paramStr = paramStr+"&"+item+"="+params[item];
+				}
+			}
+			return paramStr; // String
+		},
+
+		getTarget: function(/*String*/ hash, /*String?*/ defaultView){
+			// summary:
+			//		return the target string
+			// hash: String
+			//		the hash string
+			// defaultView: String
+			//		the optional defaultView string
+			//
+			// returns:
+			//		the target string
+			//
+			if(!defaultView){ defaultView = ""}
+			while(hash.indexOf("(") > 0){ 
+				var index = hash.indexOf("(");
+				var endindex = hash.indexOf(")");
+				var viewPart = hash.substring(index,endindex+1);
+				var viewName = viewPart.substring(1,viewPart.indexOf("&"));
+				hash = hash.replace(viewPart, viewName);
+			}	
+			
+			return (((hash && hash.charAt(0) == "#") ? hash.substr(1) : hash) || defaultView).split('&')[0];	// String
+		}
+};
+
+return hashUtil;
+
+});
\ No newline at end of file
diff --git a/dojox/app/utils/layout.js b/dojox/app/utils/layout.js
new file mode 100644
index 0000000..eaeb17f
--- /dev/null
+++ b/dojox/app/utils/layout.js
@@ -0,0 +1,141 @@
+define([
+	"dojo/_base/array", // array.filter array.forEach
+	"dojo/dom-class", // domClass.add domClass.remove
+	"dojo/dom-geometry", // domGeometry.marginBox
+	"dojo/dom-style", // domStyle.getComputedStyle
+	"dojo/_base/lang" // lang.mixin
+], function(array, domClass, domGeometry, domStyle, lang){
+
+	// module:
+	//		dijit/layout/utils
+	// summary:
+	//		marginBox2contentBox() and layoutChildren()
+
+	var layout = {};
+	/*===== layout = dijit/layout =====*/
+
+	layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
+		// summary:
+		//		Given the margin-box size of a node, return its content box size.
+		//		Functions like domGeometry.contentBox() but is more reliable since it doesn't have
+		//		to wait for the browser to compute sizes.
+		var cs = domStyle.getComputedStyle(node);
+		var me = domGeometry.getMarginExtents(node, cs);
+		var pb = domGeometry.getPadBorderExtents(node, cs);
+		return {
+			l: domStyle.toPixelValue(node, cs.paddingLeft),
+			t: domStyle.toPixelValue(node, cs.paddingTop),
+			w: mb.w - (me.w + pb.w),
+			h: mb.h - (me.h + pb.h)
+		};
+	};
+
+	function capitalize(word){
+		return word.substring(0,1).toUpperCase() + word.substring(1);
+	}
+
+	function size(widget, dim){
+		// size the child
+		var newSize = widget.resize ? widget.resize(dim) : domGeometry.setMarginBox(widget.domNode, dim);
+
+		// record child's size
+		if(newSize){
+			// if the child returned it's new size then use that
+			lang.mixin(widget, newSize);
+		}else{
+			// otherwise, call getMarginBox(), but favor our own numbers when we have them.
+			// the browser lies sometimes
+			lang.mixin(widget, domGeometry.getMarginBox(widget.domNode));
+			lang.mixin(widget, dim);
+		}
+	}
+
+	layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Widget[]*/ children,
+			/*String?*/ changedRegionId, /*Number?*/ changedRegionSize){
+		// summary:
+		//		Layout a bunch of child dom nodes within a parent dom node
+		// container:
+		//		parent node
+		// dim:
+		//		{l, t, w, h} object specifying dimensions of container into which to place children
+		// children:
+		//		An array of Widgets or at least objects containing:
+		//
+		//		- domNode: pointer to DOM node to position
+		//		- constraint or layoutAlign: position to place DOM node
+		//		- resize(): (optional) method to set size of node
+		//		- id: (optional) Id of widgets, referenced from resize object, below.
+		// changedRegionId:
+		//		If specified, the slider for the region with the specified id has been dragged, and thus
+		//		the region's height or width should be adjusted according to changedRegionSize
+		// changedRegionSize:
+		//		See changedRegionId.
+
+		// copy dim because we are going to modify it
+		dim = lang.mixin({}, dim);
+
+		domClass.add(container, "dijitLayoutContainer");
+
+		// Move "client" elements to the end of the array for layout.  a11y dictates that the author
+		// needs to be able to put them in the document in tab-order, but this algorithm requires that
+		// client be last.    TODO: move these lines to LayoutContainer?   Unneeded other places I think.
+		children = array.filter(children, function(item){ return item._constraint != "center" && item.layoutAlign != "client"; })
+			.concat(array.filter(children, function(item){ return item._constraint == "center" || item.layoutAlign == "client"; }));
+
+		// set positions/sizes
+		array.forEach(children, function(child){
+			var elm = child.domNode,
+				pos = (child._constraint || child.layoutAlign);
+			if(!pos){
+				throw new Error("No constraint setting for " + child.id)
+			}
+
+			// set elem to upper left corner of unused space; may move it later
+			var elmStyle = elm.style;
+			elmStyle.left = dim.l+"px";
+			elmStyle.top = dim.t+"px";
+			elmStyle.position = "absolute";
+
+			domClass.add(elm, "dijitAlign" + capitalize(pos));
+
+			// Size adjustments to make to this child widget
+			var sizeSetting = {};
+
+			// Check for optional size adjustment due to splitter drag (height adjustment for top/bottom align
+			// panes and width adjustment for left/right align panes.
+			if(changedRegionId && changedRegionId == child.id){
+				sizeSetting[child._constraint == "top" || child._constraint == "bottom" ? "h" : "w"] = changedRegionSize;
+			}
+
+			// set size && adjust record of remaining space.
+			// note that setting the width of a <div> may affect its height.
+			if(pos == "top" || pos == "bottom"){
+				sizeSetting.w = dim.w;
+				size(child, sizeSetting);
+				dim.h -= child.h;
+				if(pos == "top"){
+					dim.t += child.h;
+				}else{
+					elmStyle.top = dim.t + dim.h + "px";
+				}
+			}else if(pos == "left" || pos == "right"){
+				sizeSetting.h = dim.h;
+				size(child, sizeSetting);
+				dim.w -= child.w;
+				if(pos == "left"){
+					dim.l += child.w;
+				}else{
+					elmStyle.left = dim.l + dim.w + "px";
+				}
+			}else if(pos == "client" || pos == "center"){
+				size(child, dim);
+			}
+		});
+	};
+
+
+	return {
+		marginBox2contentBox: layout.marginBox2contentBox,
+		layoutChildren: layout.layoutChildren
+	};
+});
diff --git a/dojox/app/utils/model.js b/dojox/app/utils/model.js
new file mode 100755
index 0000000..b262955
--- /dev/null
+++ b/dojox/app/utils/model.js
@@ -0,0 +1,62 @@
+define(["dojo/_base/lang", "dojo/Deferred", "dojo/promise/all", "dojo/when"], function(lang, Deferred, all, when){
+	return function(/*Object*/ config, /*Object*/ parent, /*Object*/ app){
+		// summary:
+		//		model is called to create all of the models for the app, and all models for a view, it will
+		//		create and call the appropriate model utility based upon the modelLoader set in the model in the config
+		// description:
+		//		Called for each view or for the app.  For each model in the config, it will  
+		//		create the model utility based upon the modelLoader and call it to create and load the model. 
+		// config: Object
+		//		The models section of the config for this view or for the app.
+		// parent: Object
+		//		The parent of this view or the app itself, so that models from the parent will be 
+		//		available to the view.
+		// returns: loadedModels 
+		//		 loadedModels is an object holding all of the available loaded models for this view.
+		var loadedModels = {};
+		if(parent.loadedModels){
+			lang.mixin(loadedModels, parent.loadedModels);
+		}
+		if(config){
+			var allDeferred = [];
+			for(var item in config){
+				if(item.charAt(0) !== "_"){
+					allDeferred.push(setupModel(config, item, app, loadedModels));
+				}
+			}
+			return (allDeferred.length == 0) ? loadedModels : all(allDeferred);
+		}else{
+			return loadedModels;
+		}
+	};
+
+	function setupModel(config, item, app, loadedModels){
+		// Here we need to create the modelLoader and call it passing in the item and the config[item].params
+		var params = config[item].params ? config[item].params : {};
+
+		var modelLoader = config[item].modelLoader ? config[item].modelLoader : "dojox/app/utils/simpleModel";
+		// modelLoader must be listed in the dependencies and has thus already been loaded so it _must_ be here
+		// => no need for complex code here
+		try{
+			var modelCtor = require(modelLoader);
+		}catch(e){
+			throw new Error(modelLoader+" must be listed in the dependencies");
+		}
+		var loadModelDeferred = new Deferred();
+		var createModelPromise;
+		try{
+			createModelPromise = modelCtor(config, params, item);
+		}catch(e){
+			throw new Error("Error creating "+modelLoader+" for model named ["+item+"]: "+e.message);
+		}
+		when(createModelPromise, lang.hitch(this, function(newModel){
+			loadedModels[item] = newModel;
+			app.log("in app/model, for item=[",item,"] loadedModels =", loadedModels);
+			loadModelDeferred.resolve(loadedModels);
+			return loadedModels;
+		}), function(e){
+			throw new Error("Error loading model named ["+item+"]: "+e.message);
+		});
+		return loadModelDeferred;
+	}
+});
diff --git a/dojox/app/utils/mvcModel.js b/dojox/app/utils/mvcModel.js
new file mode 100755
index 0000000..82bc265
--- /dev/null
+++ b/dojox/app/utils/mvcModel.js
@@ -0,0 +1,99 @@
+define(["dojo/_base/lang", "dojo/Deferred", "dojo/when", "dojox/mvc/getStateful"],
+function(lang, Deferred, when, getStateful){
+	return function(/*Object*/config, /*Object*/params, /*String*/item){
+		// summary:
+		//		mvcModel is called for each mvc model, to create the mvc model based upon the type and params.
+		//		It will also load models and return the either the loadedModels or a promise.
+		// description:
+		//		Called for each model with a modelLoader of "dojox/app/utils/mvcModel", it will
+		//		create the model based upon the type and the params set for the model in the config.
+		// config: Object
+		//		The models section of the config for this view or for the app.
+		// params: Object
+		//		The params set into the config for this model.
+		// item: String
+		//		The String with the name of this model
+		// returns: model 
+		//		The model, of the type specified in the config for this model.
+		var loadedModels = {};
+		var loadMvcModelDeferred = new Deferred();
+
+		var fixupQuery = function(query){
+			var ops = {};
+			for(var item in query){ // need this to handle query params without errors
+				if(item.charAt(0) !== "_"){
+					ops[item] = query[item];
+				}
+			}
+			return(ops);
+		};
+
+		var options;
+		if(params.store){
+			//	if query is not set on the model params, it may be set on the store
+			options = {
+				"store": params.store.store,
+				"query": params.query ? fixupQuery(params.query) : params.store.query ? fixupQuery(params.store.query) : {}
+			};
+		}else if(params.datastore){
+			try{
+				var dataStoreCtor = require("dojo/store/DataStore");
+			}catch(e){
+				throw new Error("When using datastore the dojo/store/DataStore module must be listed in the dependencies");
+			}
+			options = {
+				"store": new dataStoreCtor({
+					store: params.datastore.store
+				}),
+				"query": fixupQuery(params.query)
+			};
+		}else if(params.data){
+			if(params.data && lang.isString(params.data)){
+				//get the object specified by string value of data property
+				//cannot assign object literal or reference to data property
+				//because json.ref will generate __parent to point to its parent
+				//and will cause infinitive loop when creating StatefulModel.
+				params.data = lang.getObject(params.data);
+			}
+			options = {"data": params.data, query: {}};
+		}
+		else{
+			console.warn("mvcModel: Missing parameters.");
+		}
+
+		var type = config[item].type ? config[item].type : "dojox/mvc/EditStoreRefListController";
+		// need to load the class to use for the model
+		// modelLoader must be listed in the dependencies and has thus already been loaded so it _must_ be here
+		// => no need for complex code here
+		try{
+			var modelCtor = require(type);
+		}catch(e){
+			throw new Error(type+" must be listed in the dependencies");
+		}
+		var newModel = new modelCtor(options);
+		var createMvcPromise;
+		try{
+			if(newModel.queryStore){
+				createMvcPromise = newModel.queryStore(options.query);
+			}else{
+				var modelProp = newModel._refSourceModelProp || newModel._refModelProp || "model";
+				newModel.set(modelProp, getStateful(options.data));
+				createMvcPromise = newModel;
+			}
+		}catch(ex){
+			//console.warn("load mvc model error.", ex);
+			loadMvcModelDeferred.reject("load mvc model error.");
+			return loadMvcModelDeferred.promise;
+		}
+		when(createMvcPromise, lang.hitch(this, function(){
+			// now the loadedModels[item].models is set.
+			loadedModels = newModel;
+			loadMvcModelDeferred.resolve(loadedModels);
+			//this.app.log("in mvcModel promise path, loadedModels = ", loadedModels);
+			return loadedModels;
+		}), function(){
+			loadMvcModelDeferred.reject("load model error.")
+		});
+		return loadMvcModelDeferred;
+	}
+});
diff --git a/dojox/app/utils/nls.js b/dojox/app/utils/nls.js
new file mode 100755
index 0000000..17413c5
--- /dev/null
+++ b/dojox/app/utils/nls.js
@@ -0,0 +1,49 @@
+define(["require", "dojo/Deferred"],  function(require, Deferred){
+	return function(/*Object*/ config, /*Object*/ parent){
+		// summary:
+		//		nsl is called to create to load the nls all for the app, or for a view.
+		// config: Object
+		//		The section of the config for this view or for the app.
+		// parent: Object
+		//		The parent of this view or the app itself, so that models from the parent will be
+		//		available to the view.
+		var path = config.nls;
+		if(path){
+			var nlsDef = new Deferred();
+			var requireSignal;
+			try{
+				var loadFile = path;
+				var index = loadFile.indexOf("./");
+				if(index >= 0){
+					loadFile = path.substring(index+2);
+				}
+				requireSignal = require.on("error", function(error){
+					if (nlsDef.isResolved() || nlsDef.isRejected()) {
+						return;
+					}
+					if(error.info[0] && (error.info[0].indexOf(loadFile)>= 0)){
+						nlsDef.resolve(false);
+						requireSignal.remove();
+					}
+				});
+
+				if(path.indexOf("./") == 0){
+					path = "app/"+path;
+				}
+
+				require(["dojo/i18n!"+path], function(nls){
+					nlsDef.resolve(nls);
+					requireSignal.remove();
+				});
+			}catch(e){
+				nlsDef.reject(e);
+				if(requireSignal){
+					requireSignal.remove();
+				}
+			}
+			return nlsDef;
+		}else{
+			return false;
+		}
+	};
+});
diff --git a/dojox/app/utils/simpleModel.js b/dojox/app/utils/simpleModel.js
new file mode 100755
index 0000000..cca317f
--- /dev/null
+++ b/dojox/app/utils/simpleModel.js
@@ -0,0 +1,110 @@
+define(["dojo/_base/lang", "dojo/Deferred", "dojo/when"],
+function(lang, Deferred, when){
+	return function(/*Object*/config, /*Object*/params, /*String*/item){
+		// summary:
+		//		simpleModel is called for each simple model, to create the simple model from the DataStore 
+		//		based upon the store and query params.
+		//		It will also load models and return the either the loadedModels or a promise.
+		// description:
+		//		Called for each model with a modelLoader of "dojox/app/utils/simpleModel", it will
+		//		create the model based upon the store and query params set for the model in the config.
+		// config: Object
+		//		The models section of the config for this view or for the app.
+		// params: Object
+		//		The params set into the config for this model.
+		// item: String
+		//		The String with the name of this model
+		// returns: model 
+		//		 The model, of the store and query params specified in the config for this model.
+		var loadedModels = {};
+		var loadSimpleModelDeferred = new Deferred();
+
+		var fixupQuery = function(query){
+			var ops = {};
+			for(var item in query){ // need this to handle query params without errors
+				if(item.charAt(0) !== "_"){
+					ops[item] = query[item];
+				}
+			}
+			return(ops);
+		};
+
+		var options, dataStoreCtor;
+		if(params.store){
+			if(!params.store.params){
+				throw new Error("Invalid store for model ["+item+"]");
+			}else if((params.store.params.data || params.store.params.store)){
+				options = {
+					"store": params.store.store,
+					"query": params.query ? fixupQuery(params.query) : params.store.query ? fixupQuery(params.store.query) : {}
+				};
+			}else if(params.store.params.url){
+				try{
+					dataStoreCtor = require("dojo/store/DataStore");
+				}catch(e){
+					throw new Error("dojo/store/DataStore must be listed in the dependencies");
+				}
+				options = {
+					"store": new dataStoreCtor({
+						store: params.store.store
+					}),
+					"query": params.query ? fixupQuery(params.query) : params.store.query ? fixupQuery(params.store.query) : {}
+				};
+			} else if(params.store.store){
+				//	if query is not set on the model params, it may be set on the store
+				options = {
+					"store": params.store.store,
+					"query": params.query ? fixupQuery(params.query) : params.store.query ? fixupQuery(params.store.query) : {}
+				};
+			}
+		}else if(params.datastore){
+			try{
+				dataStoreCtor = require("dojo/store/DataStore");
+			}catch(e){
+				throw new Error("When using datastore the dojo/store/DataStore module must be listed in the dependencies");
+			}
+			options = {
+				"store": new dataStoreCtor({
+					store: params.datastore.store
+				}),
+				"query": fixupQuery(params.query)
+			};
+		}else if(params.data){
+			if(params.data && lang.isString(params.data)){
+				params.data = lang.getObject(params.data);
+			}
+			options = {"data": params.data, query: {}};
+		} else{
+			console.warn("simpleModel: Missing parameters.");
+		}
+		var createSimplePromise;
+		try{
+			if(options.store){
+				createSimplePromise = options.store.query();
+			}else{
+				createSimplePromise = options.data;
+			}
+		}catch(ex){
+			loadSimpleModelDeferred.reject("load simple model error.");
+			return loadSimpleModelDeferred.promise;
+		}
+		if(createSimplePromise.then){
+			when(createSimplePromise, lang.hitch(this, function(newModel){
+				// now the loadedModels[item].models is set.
+				//console.log("in simpleModel promise path, loadedModels = ", loadedModels);
+				loadedModels = newModel;
+				loadSimpleModelDeferred.resolve(loadedModels);
+				return loadedModels;
+			}), function(){
+				loadModelLoaderDeferred.reject("load model error.")
+			});
+		}else{ // query did not return a promise, so use newModel
+			loadedModels = createSimplePromise;
+			//console.log("in simpleModel else path, loadedModels = ",loadedModels);
+			loadSimpleModelDeferred.resolve(loadedModels);
+			return loadedModels;
+		}
+			
+		return loadSimpleModelDeferred;
+	}
+});
diff --git a/dojox/app/view.js b/dojox/app/view.js
deleted file mode 100644
index 74202d4..0000000
--- a/dojox/app/view.js
+++ /dev/null
@@ -1,15 +0,0 @@
-define(["dojo/_base/declare", "dijit/_WidgetBase", "dijit/_Container", "dijit/_Contained","dijit/_TemplatedMixin","dijit/_WidgetsInTemplateMixin"],function(declare,Widget,Container,Contained,TemplatedMixin,WidgetsInTemplateMixin){
-	return declare("dojox.app.view", [Widget,TemplatedMixin,Container,Contained, WidgetsInTemplateMixin], {
-		selected: false,
-		keepScrollPosition: true,
-		baseClass: "applicationView mblView",
-		config:null,
-		widgetsInTemplate: true,
-		templateString: '<div></div>',
-		toString: function(){return this.id},
-		activate:function(){},
-		deactivate: function(){},
-		//Temporary work around for getting a null when calling getParent
-		getParent: function(){return null;}
-	});
-});
diff --git a/dojox/app/widgets/Container.js b/dojox/app/widgets/Container.js
new file mode 100755
index 0000000..9ca1555
--- /dev/null
+++ b/dojox/app/widgets/Container.js
@@ -0,0 +1,150 @@
+define(["dojo/_base/declare", "dojo/_base/lang", "dijit/registry", "dojo/dom-attr", "dojo/dom-geometry",
+	"dojo/dom-style", "dijit/_WidgetBase", "dijit/_Container", "dijit/_Contained", "dojo/_base/array", "dojo/query", "../utils/layout", "./_ScrollableMixin"],
+function(declare, lang, registry, domAttr, domGeom, domStyle, WidgetBase, Container, Contained, array, query, layoutUtils, ScrollableMixin){
+	return declare("dojox.app.widgets.Container", [WidgetBase, Container, Contained, ScrollableMixin], {
+		scrollable: false,
+		fixedFooter:"",
+		fixedHeader:"",
+
+		buildRendering: function(){
+			//set default _constraint="center"
+			if(!this._constraint){
+				this._constraint = "center";
+				domAttr.set(this.srcNodeRef, "data-app-constraint", "center");
+			}
+			this.inherited(arguments);
+
+			//fix slide transition issue on tablet
+			domStyle.set(this.domNode, "overflow-x", "hidden");
+			domStyle.set(this.domNode, "overflow-y", "auto");
+
+			// build scrollable container if scrollable=true
+			if(this.scrollable){
+				this.inherited(arguments);
+				this.domNode.style.position = "absolute";
+				this.domNode.style.width = "100%";
+				this.domNode.style.height = "100%";
+			}
+		},
+
+		startup: function(){
+			if(this._started){
+				return;
+			}
+			// startup scrollable container if scrollable=true
+			if(this.scrollable){
+				this.inherited(arguments);
+			}
+			this._started = true;
+		},
+
+		resize: function(changeSize, resultSize){
+			// summary:
+			//		Call this to resize a widget, or after its size has changed.
+			// description:
+			//		####Change size mode
+			//
+			//		When changeSize is specified, changes the marginBox of this widget
+			//		and forces it to re-layout its contents accordingly.
+			//		changeSize may specify height, width, or both.
+			//
+			//		If resultSize is specified it indicates the size the widget will
+			//		become after changeSize has been applied.
+			//
+			//		####Notification mode
+			//
+			//		When changeSize is null, indicates that the caller has already changed
+			//		the size of the widget, or perhaps it changed because the browser
+			//		window was resized.  Tells widget to re-layout its contents accordingly.
+			//
+			//		If resultSize is also specified it indicates the size the widget has
+			//		become.
+			//
+			//		In either mode, this method also:
+			//
+			//		1. Sets this._borderBox and this._contentBox to the new size of
+			//			the widget.  Queries the current domNode size if necessary.
+			//		2. Calls layout() to resize contents (and maybe adjust child widgets).
+			//
+			// changeSize: Object?
+			//		Sets the widget to this margin-box size and position.
+			//		May include any/all of the following properties:
+			//	|	{w: int, h: int, l: int, t: int}
+			//
+			// resultSize: Object?
+			//		The margin-box size of this widget after applying changeSize (if
+			//		changeSize is specified).  If caller knows this size and
+			//		passes it in, we don't need to query the browser to get the size.
+			//	|	{w: int, h: int}
+
+			var node = this.domNode;
+
+			if(this.scrollable){
+				this.inherited(arguments);
+				this.layout();
+				return;
+			}
+
+			// set margin box size, unless it wasn't specified, in which case use current size
+			if(changeSize){
+				domGeom.setMarginBox(node, changeSize);
+			}
+
+			// If either height or width wasn't specified by the user, then query node for it.
+			// But note that setting the margin box and then immediately querying dimensions may return
+			// inaccurate results, so try not to depend on it.
+			var mb = resultSize || {};
+			lang.mixin(mb, changeSize || {});	// changeSize overrides resultSize
+			if( !("h" in mb) || !("w" in mb) ){
+				mb = lang.mixin(domGeom.getMarginBox(node), mb);	// just use domGeometry.marginBox() to fill in missing values
+			}
+
+			// Compute and save the size of my border box and content box
+			// (w/out calling domGeometry.getContentBox() since that may fail if size was recently set)
+			var cs = domStyle.getComputedStyle(node);
+			var me = domGeom.getMarginExtents(node, cs);
+			var be = domGeom.getBorderExtents(node, cs);
+			var bb = (this._borderBox = {
+				w: mb.w - (me.w + be.w),
+				h: mb.h - (me.h + be.h)
+			});
+			var pe = domGeom.getPadExtents(node, cs);
+			this._contentBox = {
+				l: domStyle.toPixelValue(node, cs.paddingLeft),
+				t: domStyle.toPixelValue(node, cs.paddingTop),
+				w: bb.w - pe.w,
+				h: bb.h - pe.h
+			};
+
+			// Callback for widget to adjust size of its children
+			this.layout();
+		},
+
+		layout: function(){
+			// summary:
+			//		layout container
+
+			var children = query("> [data-app-constraint]", this.domNode).map(function(node){
+				var w = registry.getEnclosingWidget(node);
+				if(w){
+					w._constraint = domAttr.get(node, "data-app-constraint");
+					return w;
+				}
+
+				return {
+					domNode: node,
+					_constraint: domAttr.get(node, "data-app-constraint")
+				};
+			});
+
+			if(this._contentBox){
+				layoutUtils.layoutChildren(this.domNode, this._contentBox, children);
+			}
+			array.forEach(this.getChildren(), function(child){
+				if(!child._started && child.startup){
+					child.startup();
+				}
+			});
+		}
+	});
+});
diff --git a/dojox/app/widgets/_ScrollableMixin.js b/dojox/app/widgets/_ScrollableMixin.js
new file mode 100644
index 0000000..a4122fe
--- /dev/null
+++ b/dojox/app/widgets/_ScrollableMixin.js
@@ -0,0 +1,162 @@
+// This module is modified from dojox/mobile/_ScrollableMixin and dojox/mobile/ScrollableView
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dijit/registry",
+	"dojo/dom",
+	"dojo/dom-construct",
+	"dojox/mobile/scrollable"],
+	function(declare, lang, array, win, domClass, registry, dom, domConstruct, Scrollable){
+	// module:
+	//		dojox/mobile/_ScrollableMixin
+	// summary:
+	//		Mixin for widgets to have a touch scrolling capability.
+
+	return declare("dojox.app.widgets._ScrollableMixin", Scrollable, {
+		// summary:
+		//		Mixin for widgets to have a touch scrolling capability.
+		// description:
+		//		Actual implementation is in dojox/mobile/scrollable.js.
+		//		scrollable.js is not a dojo class, but just a collection
+		//		of functions. This module makes scrollable.js a dojo class.
+
+		// scrollableParams: Object
+		//		Parameters for dojox/mobile/scrollable.init().
+		scrollableParams: null,
+
+		// appBars: Boolean
+		//		Enables the search for application-specific bars (header or footer).
+		appBars: true, 
+
+		// allowNestedScrolls: Boolean
+		//		e.g. Allow ScrollableView in a SwapView.
+		allowNestedScrolls: true,
+
+		constructor: function(){
+			this.scrollableParams = {noResize: true}; // set noResize to true to match the way it was done in app/widgets/scrollable.js
+		},
+
+		destroy: function(){
+			this.cleanup();
+			this.inherited(arguments);
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this.findAppBars();
+			var node, params = this.scrollableParams;
+			if(this.fixedHeader){
+				node = dom.byId(this.fixedHeader);
+				if(node.parentNode == this.domNode){ // local footer
+					this.isLocalHeader = true;
+				}
+				params.fixedHeaderHeight = node.offsetHeight;
+			}
+			if(this.fixedFooter){
+				node = dom.byId(this.fixedFooter);
+				if(node.parentNode == this.domNode){ // local footer
+					this.isLocalFooter = true;
+					node.style.bottom = "0px";
+				}
+				params.fixedFooterHeight = node.offsetHeight;
+			}
+			
+			this.init(params);
+			this.inherited(arguments);
+			this.reparent();
+		},
+
+		// build scrollable container domNode. This method from dojox/mobile/ScrollableView
+		buildRendering: function(){
+			this.inherited(arguments);
+			domClass.add(this.domNode, "mblScrollableView");
+			this.domNode.style.overflow = "hidden";
+			this.domNode.style.top = "0px";
+			this.containerNode = domConstruct.create("div",	{className:"mblScrollableViewContainer"}, this.domNode);
+			this.containerNode.style.position = "absolute";
+			this.containerNode.style.top = "0px"; // view bar is relative
+			if(this.scrollDir === "v"){
+				this.containerNode.style.width = "100%";
+			}
+		},
+
+		// This method from dojox/mobile/ScrollableView
+		reparent: function(){
+			// summary:
+			//		Moves all the children to containerNode.
+			var i, idx, len, c;
+			for(i = 0, idx = 0, len = this.domNode.childNodes.length; i < len; i++){
+				c = this.domNode.childNodes[idx];
+				// search for view-specific header or footer
+		//		if(c === this.containerNode){
+				if(c === this.containerNode || this.checkFixedBar(c, true)){
+					idx++;
+					continue;
+				}
+				this.containerNode.appendChild(this.domNode.removeChild(c));
+			}
+		},
+
+		// This method from dojox/mobile/ScrollableView
+		resize: function(){
+			// summary:
+			//		Calls resize() of each child widget.
+			this.inherited(arguments); // scrollable#resize() will be called
+			array.forEach(this.getChildren(), function(child){
+				if(child.resize){ child.resize(); }
+			});
+		},
+
+
+		findAppBars: function(){
+			// summary:
+			//		Search for application-specific header or footer.
+			if(!this.appBars){ return; }
+			var i, len, c;
+			for(i = 0, len = win.body().childNodes.length; i < len; i++){
+				c = win.body().childNodes[i];
+				this.checkFixedBar(c, false);
+			}
+			if(this.domNode.parentNode){
+				for(i = 0, len = this.domNode.parentNode.childNodes.length; i < len; i++){
+					c = this.domNode.parentNode.childNodes[i];
+					this.checkFixedBar(c, false);
+				}
+			}
+			this.fixedFooterHeight = this.fixedFooter ? this.fixedFooter.offsetHeight : 0;
+		},
+
+	
+		checkFixedBar: function(/*DomNode*/node, /*Boolean*/local){
+			// summary:
+			//		Checks if the given node is a fixed bar or not.
+			if(node.nodeType === 1){
+				var fixed = node.getAttribute("data-app-constraint")
+					|| (registry.byNode(node) && registry.byNode(node)["data-app-constraint"]);
+			/*	if(fixed === "top"){
+					domClass.add(node, "mblFixedHeaderBar");
+					if(local){
+						node.style.top = "0px";
+						this.fixedHeader = node;
+					}
+					return fixed;
+				}else
+			*/	 
+				if(fixed === "bottom"){
+					domClass.add(node, "mblFixedBottomBar");
+					if(local){
+						this.fixedFooter = node;
+					}else{
+						this._fixedAppFooter = node;
+					}
+					return fixed;
+				}
+			}
+			return null;
+		}
+			
+	});
+});
diff --git a/dojox/atom/io/Connection.js b/dojox/atom/io/Connection.js
index 0eeb3bc..04640f2 100755
--- a/dojox/atom/io/Connection.js
+++ b/dojox/atom/io/Connection.js
@@ -1,17 +1,20 @@
 define([
+	"dojo/_base/declare",
 	"dojo/_base/kernel",
 	"dojo/_base/xhr",
-	"dojo/_base/window",
-	"./model",
-	"dojo/_base/declare"], function (dojo, xhrUtil, windowUtil, model) {
-return dojo.declare("dojox.atom.io.Connection",null,{
-	// summary: This object implements a transport layer for working with ATOM feeds and ATOM publishing protocols.
-	// description: This object implements a transport layer for working with ATOM feeds and ATOM publishing protocols.
-	//   Specifically, it provides a mechanism by which feeds can be fetched and entries can be fetched, created
-	//   deleted, and modified.  It also provides access to the introspection data.
+	"./model"
+], function (declare, kernel, xhrUtil, model){
+
+return declare("dojox.atom.io.Connection",null,{
+	// summary:
+	//		This object implements a transport layer for working with ATOM feeds and ATOM publishing protocols.
+	// description:
+	//		This object implements a transport layer for working with ATOM feeds and ATOM publishing protocols.
+	//		Specifically, it provides a mechanism by which feeds can be fetched and entries can be fetched, created
+	//		deleted, and modified.  It also provides access to the introspection data.
 
 	constructor: function(/* Boolean */sync, /* Boolean */preventCache){
-		// 	summary:
+		// summary:
 		//		initializer
 		this.sync = sync;
 		this.preventCache = preventCache;
@@ -22,86 +25,78 @@ return dojo.declare("dojox.atom.io.Connection",null,{
 	alertsEnabled: false, //Flag to turn on alerts instead of throwing errors.
 
 	getFeed: function(/*String*/url, /*Function*/callback, /*Function*/errorCallback, scope){
-		// 	summary:
+		// summary:
 		//		Function to obtain a s specific ATOM feed from a given ATOM Feed url.
-		//	description:
+		// description:
 		//		This function takes the URL for a specific ATOM feed and returns
 		//		the data from that feed to the caller through the use of a callback
 		//		handler.
-		//
-		// 	url: String
+		// url: String
 		//		The URL of the ATOM feed to fetch.
-		//	callback:
+		// callback:
 		//		Function
 		//		A function reference that will handle the feed when it has been retrieved.
 		//		The callback should accept two parameters:  The feed object and the original complete DOM object.
-		//	scope: Object
+		// scope: Object
 		//		The scope to use for all callbacks.
-		//
-		//	returns:
+		// returns:
 		//		Nothing. The return is handled through the callback handler.
 		this._getXmlDoc(url, "feed", new model.Feed(), model._Constants.ATOM_NS, callback, /*handleDocumentRetrieved,*/ errorCallback, scope);
 	},
 	
 	getService: function(url, callback, errorCallback, scope){
-		//	summary:
+		// summary:
 		//		Function to retrieve an introspection document from the given URL.
-		// 	description:
+		// description:
 		//		This function takes the URL for an ATOM item and feed and returns
 		//		the introspection document.
-		//
-		//	url:
+		// url:
 		//		String
 		//		The URL of the ATOM document to obtain the introspection document of.
-		//	callback:
+		// callback:
 		//		Function
 		//		A function reference that will handle the introspection document when it has been retrieved.
 		//		The callback should accept two parameters:  The introspection document object and the original complete DOM object.
-		//
-		//	returns:
+		// returns:
 		//		Nothing. The return is handled through the callback handler.
 		this._getXmlDoc(url, "service", new model.Service(url), model._Constants.APP_NS, callback, errorCallback, scope);
 	},
 	
 	getEntry: function(url, callback, errorCallback, scope){
-		//	summary:
+		// summary:
 		//		Function to retrieve a single entry from an ATOM feed from the given URL.
-		//	description:
+		// description:
 		//		This function takes the URL for an ATOM entry and returns the constructed dojox.atom.io.model.Entry object through
 		//		the specified callback.
-		//
-		//	url:
+		// url:
 		//		String
 		//		The URL of the ATOM Entry document to parse.
-		//	callback:
+		// callback:
 		//		Function
 		//		A function reference that will handle the Entry object obtained.
 		//		The callback should accept two parameters, the dojox.atom.io.model.Entry object and the original dom.
-		//
-		//	returns:
+		// returns:
 		//		Nothing. The return is handled through the callback handler.
 		this._getXmlDoc(url, "entry", new model.Entry(), model._Constants.ATOM_NS, callback, errorCallback, scope);
 	},
 
 	_getXmlDoc: function(url, nodeName, newNode, namespace, callback, errorCallback, scope){
-		//	summary:
+		// summary:
 		//		Internal Function to retrieve an XML document and pass the results to a callback.
-		//	description:
+		// description:
 		//		This internal function takes the URL for an XML document and and passes the
 		//		parsed contents to a specified callback.
-		//
-		//	url:
+		// url:
 		//		String
 		//		The URL of the XML document to retrieve
-		//	callback:
+		// callback:
 		//		Function
 		//		A function reference that will handle the retrieved XML data.
 		//		The callback should accept one parameter, the DOM of the parsed XML document.
-		//
-		//	returns:
+		// returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
-			scope = windowUtil.global;
+			scope = kernel.global;
 		}
 		var ae = this.alertsEnabled;
 		var xhrArgs = {
@@ -174,36 +169,34 @@ return dojo.declare("dojox.atom.io.Connection",null,{
 	},
 
 	updateEntry: function(entry, callback, errorCallback, retrieveUpdated, xmethod, scope){
-		//	summary:
+		// summary:
 		//		Function to update a specific ATOM entry by putting the new changes via APP.
-		//	description:
+		// description:
 		//		This function takes a specific dojox.atom.io.model.Entry object and pushes the
 		//		changes back to the provider of the Entry.
 		//		The entry MUST have a link tag with rel="edit" for this to work.
-		//
-		//	entry:
+		// entry:
 		//		Object
 		//		The dojox.atom.io.model.Entry object to update.
-		//	callback:
+		// callback:
 		//		Function
 		//		A function reference that will handle the results from the entry update.
 		//		The callback should accept two parameters:  The first is an Entry object, and the second is the URL of that Entry
 		//		Either can be null, depending on the value of retrieveUpdated.
-		//	retrieveUpdated:
+		// retrieveUpdated:
 		//		boolean
 		//		A boolean flag denoting if the entry that was updated should then be
 		//		retrieved and returned to the caller via the callback.
-		//	xmethod:
+		// xmethod:
 		//		boolean
 		//		Whether to use POST for PUT/DELETE items and send the X-Method-Override header.
-		//	scope:
+		// scope:
 		//		Object
 		//		The scope to use for all callbacks.
-		//
-		//	returns:
+		// returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
-			scope = windowUtil.global;
+			scope = kernel.global;
 		}
 		entry.updated = new Date();
 		var url = entry.getEditHref();
@@ -272,32 +265,30 @@ return dojo.declare("dojox.atom.io.Connection",null,{
 	},
 
 	addEntry: function(entry, url, callback, errorCallback, retrieveEntry, scope){
-		//	summary:
+		// summary:
 		//		Function to add a new ATOM entry by posting the new entry via APP.
-		//	description:
+		// description:
 		//		This function takes a specific dojox.atom.io.model.Entry object and pushes the
 		//		changes back to the provider of the Entry.
-		//
-		//	entry:
+		// entry:
 		//		Object
 		//		The dojox.atom.io.model.Entry object to publish.
-		//	callback:
+		// callback:
 		//		Function
 		//		A function reference that will handle the results from the entry publish.
 		//		The callback should accept two parameters:   The first is an dojox.atom.io.model.Entry object, and the second is the location of the entry
 		//		Either can be null, depending on the value of retrieveUpdated.
-		//	retrieveEntry:
+		// retrieveEntry:
 		//		boolean
 		//		A boolean flag denoting if the entry that was created should then be
 		//		retrieved and returned to the caller via the callback.
-		//	scope:
+		// scope:
 		//		Object
 		//	 	The scope to use for all callbacks.
-		//
-		//	returns:
+		// returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
-			scope = windowUtil.global;
+			scope = kernel.global;
 		}
 
 		entry.published = new Date();
@@ -368,25 +359,23 @@ return dojo.declare("dojox.atom.io.Connection",null,{
 	},
 
 	deleteEntry: function(entry,callback,errorCallback,xmethod,scope){
-		//	summary:
+		// summary:
 		//		Function to delete a specific ATOM entry via APP.
-		//	description:
+		// description:
 		//		This function takes a specific dojox.atom.io.model.Entry object and calls for a delete on the
 		//		service housing the ATOM Entry database.
 		//		The entry MUST have a link tag with rel="edit" for this to work.
-		//
-		//	entry:
+		// entry:
 		//		Object
 		//		The dojox.atom.io.model.Entry object to delete.
-		//	callback:
+		// callback:
 		//		Function
 		//		A function reference that will handle the results from the entry delete.
 		//		The callback is called only if the delete is successful.
-		//
-		//	returns:
+		// returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
-			scope = windowUtil.global;
+			scope = kernel.global;
 		}
 
 		var url = null;
diff --git a/dojox/atom/io/model.js b/dojox/atom/io/model.js
index 4f375f9..83af2a1 100644
--- a/dojox/atom/io/model.js
+++ b/dojox/atom/io/model.js
@@ -1,18 +1,19 @@
 define([
 	"dojo/_base/kernel",
-	"dojo/_base/declare", // dojo.declare
+	"dojo/_base/declare",
 	 "dojo/_base/lang",
 	"dojo/date/stamp",
 	"dojox/xml/parser"
 ], function (dojo, declare, lang, stamp, parser) {
 
-var model = dojo.getObject("dojox.atom.io.model", true);
+var model = {};
+
+dojo.setObject("dojox.atom.io.model", model);
 
 model._Constants = {
-	//	summary:
-	//		Container for general constants.
-	//	description:
+	// summary:
 	//		Container for general constants.
+
 	"ATOM_URI": "http://www.w3.org/2005/Atom",
 	"ATOM_NS": "http://www.w3.org/2005/Atom",
 	"PURL_NS": "http://purl.org/atom/app#",
@@ -20,14 +21,14 @@ model._Constants = {
 };
 
 model._actions = {
-	//	summary:
+	// summary:
 	//		Container for tag handling functions.
-	//	description:
+	// description:
 	//		Container for tag handling functions.  Each child of this container is
 	//		a handler function for the given type of node. Each accepts two parameters:
-	//	obj:  Object.
+	// obj:  Object.
 	//		  The object to insert data into.
-	//	node: DOM Node.
+	// node: DOM Node.
 	//		  The dom node containing the data
 	"link": function(obj,node){
 		if(obj.links === null){obj.links = [];}
@@ -120,15 +121,12 @@ model._actions = {
 };
 
 model.util = {
-	createDate: function(/*DOM node*/node){
-		//	summary:
+	createDate: function(/*DOMNode*/ node){
+		// summary:
 		//		Utility function to create a date from a DOM node's text content.
-		//	description:
-		//		Utility function to create a date from a DOM node's text content.
-		//
-		//	node:
+		// node:
 		//		The DOM node to inspect.
-		//	returns:
+		// returns:
 		//		Date object from a DOM Node containing a ISO-8610 string.
 		var textContent = parser.textContent(node);
 		if(textContent){
@@ -136,45 +134,34 @@ model.util = {
 		}
 		return null;
 	},
-	escapeHtml: function(/*String*/str){
-		//	summary:
-		//		Utility function to escape XML special characters in an HTML string.
-		//	description:
+	escapeHtml: function(/*String*/ str){
+		// summary:
 		//		Utility function to escape XML special characters in an HTML string.
-		//
-		//	str:
+		// str:
 		//		The string to escape
-		//	returns:
+		// returns:
 		//		HTML String with special characters (<,>,&, ", etc,) escaped.
 		return str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """)
 			.replace(/'/gm, "'"); // String
 	},
-	unEscapeHtml: function(/*String*/str){
-		//	summary:
+	unEscapeHtml: function(/*String*/ str){
+		// summary:
 		//		Utility function to un-escape XML special characters in an HTML string.
-		//	description:
-		//		Utility function to un-escape XML special characters in an HTML string.
-		//
-		//	str:
+		// str:
 		//		The string to un-escape.
-		//	returns:
+		// returns:
 		//		HTML String converted back to the normal text (unescaped) characters (<,>,&, ", etc,).
 		return str.replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, "\"")
 			.replace(/'/gm, "'").replace(/&/gm, "&"); // String
 	},
-	getNodename: function(/*DOM node*/node){
-		//	summary:
-		//		Utility function to get a node name and deal with IE's bad handling of namespaces
-		//		on tag names.
-		//	description:
+	getNodename: function(/*DOMNode*/ node){
+		// summary:
 		//		Utility function to get a node name and deal with IE's bad handling of namespaces
 		//		on tag names.
-		//
-		//	node:
+		// node:
 		//		The DOM node whose name to retrieve.
-		//	returns:
-		//		String
-		//	The name without namespace prefixes.
+		// returns: String
+		//		The name without namespace prefixes.
 		var name = null;
 		if(node !== null){
 			name = node.localName ? node.localName: node.nodeName;
@@ -189,7 +176,7 @@ model.util = {
 	}
 };
 
-model.Node = dojo.declare(/*===== 'dojox.atom.io.model.Node', =====*/ null, {
+model.Node = declare(null, {
 	constructor: function(name_space,name, attributes,content, shortNs){
 		this.name_space = name_space;
 		this.name = name;
@@ -297,8 +284,11 @@ model.Node = dojo.declare(/*===== 'dojox.atom.io.model.Node', =====*/ null, {
 });
 //Types are as follows: links: array of Link, authors: array of Person, categories: array of Category
 //contributors: array of Person, ico
-model.AtomItem = dojo.declare(/*===== "dojox.atom.io.model.AtomItem", =====*/ model.Node,{
-	 constructor: function(args){
+model.AtomItem = declare(model.Node,{
+	// summary:
+	//		Class container for generic Atom items.
+
+	constructor: function(args){
 		this.ATOM_URI = model._Constants.ATOM_URI;
 		this.links = null;						//Array of Link
 		this.authors = null;					//Array of Person
@@ -316,8 +306,7 @@ model.AtomItem = dojo.declare(/*===== "dojox.atom.io.model.AtomItem", =====*/ mo
 		this._objName = "AtomItem";			 //for debugging purposes
 		this.nodeType = "AtomItem";
 	},
-	// summary: Class container for generic Atom items.
-	// description: Class container for generic Atom items.
+
 	_getAttributeNames: function(){return null;},
 	_accepts: {},
 	accept: function(tag){return Boolean(this._accepts[tag]);},
@@ -359,65 +348,45 @@ model.AtomItem = dojo.declare(/*===== "dojox.atom.io.model.AtomItem", =====*/ mo
 			this.name_spaces[shortName] = fullName;
 		}
 	},
-	addAuthor: function(/*String*/name, /*String*/email, /*String*/uri){
-		//	summary:
-		//		Function to add in an author to the list of authors.
-		//	description:
+	addAuthor: function(/*String*/ name, /*String*/ email, /*String*/ uri){
+		// summary:
 		//		Function to add in an author to the list of authors.
-		//
-		//	name:
+		// name:
 		//		The author's name.
-		//	email:
+		// email:
 		//		The author's e-mail address.
-		//	uri:
+		// uri:
 		//		A URI associated with the author.
 		if(!this.authors){this.authors = [];}
 		this.authors.push(new model.Person("author",name,email,uri));
 	},
-	addContributor: function(/*String*/name, /*String*/email, /*String*/uri){
-		//	summary:
-		//		Function to add in an author to the list of authors.
-		//	description:
+	addContributor: function(/*String*/ name, /*String*/ email, /*String*/ uri){
+		// summary:
 		//		Function to add in an author to the list of authors.
-		//
-		//	name:
+		// name:
 		//		The author's name.
-		//	email:
+		// email:
 		//		The author's e-mail address.
-		//	uri:
+		// uri:
 		//		A URI associated with the author.
 		if(!this.contributors){this.contributors = [];}
 		this.contributors.push(new model.Person("contributor",name,email,uri));
 	},
-	addLink: function(/*String*/href,/*String*/rel,/*String*/hrefLang,/*String*/title,/*String*/type){
-		//	summary:
+	addLink: function(/*String*/ href,/*String*/ rel,/*String*/ hrefLang,/*String*/ title,/*String*/ type){
+		// summary:
 		//		Function to add in a link to the list of links.
-		//	description:
-		//		Function to add in a link to the list of links.
-		//
-		//	href:
-		//		The href.
-		//	rel:
-		//		String
-		//	hrefLang:
-		//		String
-		//	title:
+		// title:
 		//		A title to associate with the link.
-		//	type:
+		// type:
 		//		The type of link is is.
 		if(!this.links){this.links=[];}
 		this.links.push(new model.Link(href,rel,hrefLang,title,type));
 	},
-	removeLink: function(/*String*/href, /*String*/rel){
-		//	summary:
+	removeLink: function(/*String*/ href, /*String*/ rel){
+		// summary:
 		//		Function to remove a link from the list of links.
-		//	description:
-		//		Function to remove a link from the list of links.
-		//
-		//	href:
+		// href:
 		//		The href.
-		//	rel:
-		//		String
 		if(!this.links || !lang.isArray(this.links)){return;}
 		var count = 0;
 		for(var i = 0; i < this.links.length; i++){
@@ -428,10 +397,8 @@ model.AtomItem = dojo.declare(/*===== "dojox.atom.io.model.AtomItem", =====*/ mo
 		return count;
 	},
 	removeBasicLinks: function(){
-		//	summary:
+		// summary:
 		//		Function to remove all basic links from the list of links.
-		//	description:
-		//		Function to remove all basic link from the list of links.
 		if(!this.links){return;}
 		var count = 0;
 		for(var i = 0; i < this.links.length; i++){
@@ -439,30 +406,19 @@ model.AtomItem = dojo.declare(/*===== "dojox.atom.io.model.AtomItem", =====*/ mo
 		}
 		return count;
 	},
-	addCategory: function(/*String*/scheme, /*String*/term, /*String*/label){
-		//	summary:
-		//		Function to add in a category to the list of categories.
-		//	description:
+	addCategory: function(/*String*/ scheme, /*String*/ term, /*String*/ label){
+		// summary:
 		//		Function to add in a category to the list of categories.
-		//
-		//	scheme:
-		//		String
-		//	term:
-		//		String
-		//	label:
-		//		String
+
 		if(!this.categories){this.categories = [];}
 		this.categories.push(new model.Category(scheme,term,label));
 	},
-	getCategories: function(/*String*/scheme){
-		//	summary:
-		//		Function to get all categories that match a particular scheme.
-		//	description:
+	getCategories: function(/*String*/ scheme){
+		// summary:
 		//		Function to get all categories that match a particular scheme.
-		//
-		//	scheme:
-		//		String
+		// scheme:
 		//		The scheme to filter on.
+
 		if(!scheme){return this.categories;}
 		//If categories belonging to a particular scheme are required, then create a new array containing these
 		var arr = [];
@@ -471,15 +427,12 @@ model.AtomItem = dojo.declare(/*===== "dojox.atom.io.model.AtomItem", =====*/ mo
 		}
 		return arr;
 	},
-	removeCategories: function(/*String*/scheme, /*String*/term){
-		//	summary:
-		//		Function to remove all categories that match a particular scheme and term.
-		//	description:
+	removeCategories: function(/*String*/ scheme, /*String*/ term){
+		// summary:
 		//		Function to remove all categories that match a particular scheme and term.
-		//
-		//	scheme:
+		// scheme:
 		//		The scheme to filter on.
-		//	term:
+		// term:
 		//		The term to filter on.
 		if(!this.categories){return;}
 		var count = 0;
@@ -490,47 +443,38 @@ model.AtomItem = dojo.declare(/*===== "dojox.atom.io.model.AtomItem", =====*/ mo
 		}
 		return count;
 	},
-	setTitle: function(/*String*/str, /*String*/type){
-		//	summary:
-		//		Function to set the title of the item.
-		//	description:
+	setTitle: function(/*String*/ str, /*String*/ type){
+		// summary:
 		//		Function to set the title of the item.
-		//
-		//	str:
+		// str:
 		//		The title to set.
-		//	type:
+		// type:
 		//		The type of title format, text, xml, xhtml, etc.
 		if(!str){return;}
 		this.title = new model.Content("title");
 		this.title.value = str;
 		if(type){this.title.type = type;}
 	},
-	addExtension: function(/*String*/name_space,/*String*/name, /*Array*/attributes, /*String*/content, /*String*/shortNS){
-		//	summary:
+	addExtension: function(/*String*/ name_space,/*String*/ name, /*Array*/ attributes, /*String*/ content, /*String*/ shortNS){
+		// summary:
 		//		Function to add in an extension namespace into the item.
-		//	description:
-		//		Function to add in an extension namespace into the item.
-		//
-		//	name_space:
+		// name_space:
 		//		The namespace of the extension.
-		//	name:
+		// name:
 		//		The name of the extension
-		//	attributes:
+		// attributes:
 		//		The attributes associated with the extension.
-		//	content:
+		// content:
 		//		The content of the extension.
 		if(!this.extensions){this.extensions=[];}
 		this.extensions.push(new model.Node(name_space,name,attributes,content, shortNS || "ns"+this.extensions.length));
 	},
-	getExtensions: function(/*String*/name_space, /*String*/name){
-		//	summary:
-		//		Function to get extensions that match a namespace and name.
-		//	description:
+	getExtensions: function(/*String*/ name_space, /*String*/ name){
+		// summary:
 		//		Function to get extensions that match a namespace and name.
-		//
-		//	name_space:
+		// name_space:
 		//		The namespace of the extension.
-		//	name:
+		// name:
 		//		The name of the extension
 		var arr = [];
 		if(!this.extensions){return arr;}
@@ -541,15 +485,12 @@ model.AtomItem = dojo.declare(/*===== "dojox.atom.io.model.AtomItem", =====*/ mo
 		}
 		return arr;
 	},
-	removeExtensions: function(/*String*/name_space, /*String*/name){
-		//	summary:
+	removeExtensions: function(/*String*/ name_space, /*String*/ name){
+		// summary:
 		//		Function to remove extensions that match a namespace and name.
-		//	description:
-		//		Function to remove extensions that match a namespace and name.
-		//
-		//	name_space:
+		// name_space:
 		//		The namespace of the extension.
-		//	name:
+		// name:
 		//		The name of the extension
 		if(!this.extensions){return;}
 		for(var i=0; i< this.extensions.length; i++){
@@ -575,12 +516,11 @@ model.AtomItem = dojo.declare(/*===== "dojox.atom.io.model.AtomItem", =====*/ mo
 	}
 });
 
-model.Category = dojo.declare(/*===== "dojox.atom.io.model.Category", =====*/ model.Node,{
-	//	summary:
-	//		Class container for 'Category' types.
-	//	description:
+model.Category = declare(model.Node,{
+	// summary:
 	//		Class container for 'Category' types.
-	constructor: function(/*String*/scheme, /*String*/term, /*String*/label){
+
+	constructor: function(/*String*/ scheme, /*String*/ term, /*String*/ label){
 		this.scheme = scheme; this.term = term; this.label = label;
 		this._objName = "Category";//for debugging
 		this.nodeType = "Category";
@@ -590,9 +530,7 @@ model.Category = dojo.declare(/*===== "dojox.atom.io.model.Category", =====*/ mo
 		return ["label","scheme","term"];
 	},
 	toString: function(){
-		//	summary:
-		//		Function to construct string form of the category tag, which is an XML structure.
-		//	description:
+		// summary:
 		//		Function to construct string form of the category tag, which is an XML structure.
 		var s = [];
 		s.push('<category ');
@@ -602,13 +540,10 @@ model.Category = dojo.declare(/*===== "dojox.atom.io.model.Category", =====*/ mo
 		s.push('/>\n');
 		return s.join('');
 	},
-	buildFromDom: function(/*DOM node*/node){
-		//	summary:
+	buildFromDom: function(/*DOMNode*/ node){
+		// summary:
 		//		Function to do construction of the Category data from the DOM node containing it.
-		//	description:
-		//		Function to do construction of the Category data from the DOM node containing it.
-		//
-		//	node:
+		// node:
 		//		The DOM node to process for content.
 		this._saveAttributes(node);//just get the attributes from the node
 		this.label = this.attributes.label;
@@ -618,11 +553,10 @@ model.Category = dojo.declare(/*===== "dojox.atom.io.model.Category", =====*/ mo
 	}
 });
 
-model.Content = dojo.declare(/*===== "dojox.atom.io.model.Content", =====*/ model.Node,{
-	//	summary:
-	//		Class container for 'Content' types. Such as summary, content, username, and so on types of data.
-	//	description:
+model.Content = declare(model.Node,{
+	// summary:
 	//		Class container for 'Content' types. Such as summary, content, username, and so on types of data.
+
 	constructor: function(tagName, value, src, type,xmlLang){
 		this.tagName = tagName; this.value = value; this.src = src; this.type=type; this.xmlLang = xmlLang;
 		this.HTML = "html"; this.TEXT = "text"; this.XHTML = "xhtml"; this.XML="xml";
@@ -631,15 +565,13 @@ model.Content = dojo.declare(/*===== "dojox.atom.io.model.Content", =====*/ mode
 	},
 	_getAttributeNames: function(){return ["type","src"];},
 	_postBuild: function(){},
-	buildFromDom: function(/*DOM node*/node){
-		//	summary:
+	buildFromDom: function(/*DOMNode*/ node){
+		// summary:
 		//		Function to do construction of the Content data from the DOM node containing it.
-		//	description:
-		//		Function to do construction of the Content data from the DOM node containing it.
-		//
-		//	node:
+		// node:
 		//		The DOM node to process for content.
-		//Handle checking for XML content as the content type
+
+		// Handle checking for XML content as the content type
 		var type = node.getAttribute("type");
 		if(type){
 			type = type.toLowerCase();
@@ -684,10 +616,9 @@ model.Content = dojo.declare(/*===== "dojox.atom.io.model.Content", =====*/ mode
 		if(this._postBuild){this._postBuild();}
 	},
 	toString: function(){
-		//	summary:
-		//		Function to construct string form of the content tag, which is an XML structure.
-		//	description:
+		// summary:
 		//		Function to construct string form of the content tag, which is an XML structure.
+
 		var s = [];
 		s.push('<'+this.tagName+' ');
 		if(!this.type){this.type = "text";}
@@ -706,11 +637,10 @@ model.Content = dojo.declare(/*===== "dojox.atom.io.model.Content", =====*/ mode
 	}
 });
 
-model.Link = dojo.declare(/*===== "dojox.atom.io.model.Link", =====*/ model.Node,{
-	//	summary:
-	//		Class container for 'link' types.
-	//	description:
+model.Link = declare(model.Node,{
+	// summary:
 	//		Class container for 'link' types.
+
 	constructor: function(href,rel,hrefLang,title,type){
 		this.href = href; this.hrefLang = hrefLang; this.rel = rel; this.title = title;this.type = type;
 		this.nodeType = "Link";
@@ -718,12 +648,9 @@ model.Link = dojo.declare(/*===== "dojox.atom.io.model.Link", =====*/ model.Node
 	_getAttributeNames: function(){return ["href","jrefLang","rel","title","type"];},
 	_postBuild: function(){},
 	buildFromDom: function(node){
-		//	summary:
+		// summary:
 		//		Function to do construction of the link data from the DOM node containing it.
-		//	description:
-		//		Function to do construction of the link data from the DOM node containing it.
-		//
-		//	node:
+		// node:
 		//		The DOM node to process for link data.
 		this._saveAttributes(node);//just get the attributes from the node
 		this.href = this.attributes.href;
@@ -734,10 +661,9 @@ model.Link = dojo.declare(/*===== "dojox.atom.io.model.Link", =====*/ model.Node
 		if(this._postBuild){this._postBuild();}
 	},
 	toString: function(){
-		//	summary:
-		//		Function to construct string form of the link tag, which is an XML structure.
-		//	description:
+		// summary:
 		//		Function to construct string form of the link tag, which is an XML structure.
+
 		var s = [];
 		s.push('<link ');
 		if(this.href){s.push(' href="'+this.href+'" ');}
@@ -750,11 +676,10 @@ model.Link = dojo.declare(/*===== "dojox.atom.io.model.Link", =====*/ model.Node
 	}
 });
 
-model.Person = dojo.declare(/*===== "dojox.atom.io.model.Person", =====*/ model.Node,{
-	//	summary:
-	//		Class container for 'person' types, such as Author, controbutors, and so on.
-	//	description:
-	//		Class container for 'person' types, such as Author, controbutors, and so on.
+model.Person = declare(model.Node,{
+	// summary:
+	//		Class container for 'person' types, such as Author, contributors, and so on.
+
 	constructor: function(personType, name, email, uri){
 		this.author = "author";
 		this.contributor = "contributor";
@@ -772,12 +697,9 @@ model.Person = dojo.declare(/*===== "dojox.atom.io.model.Person", =====*/ model.
 	_postBuild: function(){},
 	accept: function(tag){return Boolean(this._accepts[tag]);},
 	buildFromDom: function(node){
-		//	summary:
-		//		Function to do construction of the person data from the DOM node containing it.
-		//	description:
+		// summary:
 		//		Function to do construction of the person data from the DOM node containing it.
-		//
-		//	node:
+		// node:
 		//		The DOM node to process for person data.
 		var c = node.childNodes;
 		for(var i = 0; i< c.length; i++){
@@ -808,10 +730,9 @@ model.Person = dojo.declare(/*===== "dojox.atom.io.model.Person", =====*/ model.
 		'email': true
 	},
 	toString: function(){
-		//	summary:
-		//		Function to construct string form of the Person tag, which is an XML structure.
-		//	description:
+		// summary:
 		//		Function to construct string form of the Person tag, which is an XML structure.
+
 		var s = [];
 		s.push('<'+this.personType+'>\n');
 		if(this.name){s.push('\t<name>'+this.name+'</name>\n');}
@@ -822,24 +743,20 @@ model.Person = dojo.declare(/*===== "dojox.atom.io.model.Person", =====*/ model.
 	}
 });
 
-model.Generator = dojo.declare(/*===== "dojox.atom.io.model.Generator", =====*/ model.Node,{
-	//	summary:
+model.Generator = declare(model.Node,{
+	// summary:
 	//		Class container for 'Generator' types.
-	//	description:
-	//		Class container for 'Generator' types.
-	constructor: function(/*String*/uri, /*String*/version, /*String*/value){
+
+	constructor: function(/*String*/ uri, /*String*/ version, /*String*/ value){
 		this.uri = uri;
 		this.version = version;
 		this.value = value;
 	},
 	_postBuild: function(){},
 	buildFromDom: function(node){
-		//	summary:
+		// summary:
 		//		Function to do construction of the generator data from the DOM node containing it.
-		//	description:
-		//		Function to do construction of the generator data from the DOM node containing it.
-		//
-		//	node:
+		// node:
 		//		The DOM node to process for link data.
 
 		this.value = parser.textContent(node);
@@ -851,10 +768,9 @@ model.Generator = dojo.declare(/*===== "dojox.atom.io.model.Generator", =====*/
 		if(this._postBuild){this._postBuild();}
 	},
 	toString: function(){
-		//	summary:
-		//		Function to construct string form of the Generator tag, which is an XML structure.
-		//	description:
+		// summary:
 		//		Function to construct string form of the Generator tag, which is an XML structure.
+
 		var s = [];
 		s.push('<generator ');
 		if(this.uri){s.push(' uri="'+this.uri+'" ');}
@@ -865,12 +781,11 @@ model.Generator = dojo.declare(/*===== "dojox.atom.io.model.Generator", =====*/
 	}
 });
 
-model.Entry = dojo.declare(/*===== "dojox.atom.io.model.Entry", =====*/ model.AtomItem,{
-	//	summary:
+model.Entry = declare(model.AtomItem,{
+	// summary:
 	//		Class container for 'Entry' types.
-	//	description:
-	//		Class container for 'Entry' types.
-	constructor: function(/*String*/id){
+
+	constructor: function(/*String*/ id){
 		this.id = id; this._objName = "Entry"; this.feedUrl = null;
 	},
 	_getAttributeNames: function(){return null;},
@@ -892,10 +807,9 @@ model.Entry = dojo.declare(/*===== "dojox.atom.io.model.Entry", =====*/ model.At
 		'modified': true
 	},
 	toString: function(amPrimary){
-		//	summary:
-		//		Function to construct string form of the entry tag, which is an XML structure.
-		//	description:
+		// summary:
 		//		Function to construct string form of the entry tag, which is an XML structure.
+
 		var s = [];
 		var i;
 		if(amPrimary){
@@ -933,12 +847,9 @@ model.Entry = dojo.declare(/*===== "dojox.atom.io.model.Entry", =====*/ model.At
 		return s.join(''); //string
 	},
 	getEditHref: function(){
-		//	summary:
+		// summary:
 		//		Function to get the href that allows editing of this feed entry.
-		//	description:
-		//		Function to get the href that allows editing of this feed entry.
-		//
-		//	returns:
+		// returns:
 		//		The href that specifies edit capability.
 		if(this.links === null || this.links.length === 0){
 			return null;
@@ -964,11 +875,10 @@ model.Entry = dojo.declare(/*===== "dojox.atom.io.model.Entry", =====*/ model.At
 	}
 });
 
-model.Feed = dojo.declare(/*===== "dojox.atom.io.model.Feed", =====*/ model.AtomItem,{
-	//	summary:
-	//		Class container for 'Feed' types.
-	//	description:
+model.Feed = declare(model.AtomItem,{
+	// summary:
 	//		Class container for 'Feed' types.
+
 	_accepts: {
 		'author': true,
 		'content': true,
@@ -990,12 +900,10 @@ model.Feed = dojo.declare(/*===== "dojox.atom.io.model.Feed", =====*/ model.Atom
 		'icon': true,
 		'subtitle': true
 	},
-	addEntry: function(/*object*/entry){
-		//	summary:
-		//		Function to add an entry to this feed.
-		//	description:
+	addEntry: function(/*object*/ entry){
+		// summary:
 		//		Function to add an entry to this feed.
-		//	entry:
+		// entry:
 		//		The entry object to add.
 		if(!entry.id){
 			throw new Error("The entry object must be assigned an ID attribute.");
@@ -1005,23 +913,17 @@ model.Feed = dojo.declare(/*===== "dojox.atom.io.model.Feed", =====*/ model.Atom
 		this.entries.push(entry);
 	},
 	getFirstEntry: function(){
-		//	summary:
-		//		Function to get the first entry of the feed.
-		//	description:
+		// summary:
 		//		Function to get the first entry of the feed.
-		//
-		//	returns:
+		// returns:
 		//		The first entry in the feed.
 		if(!this.entries || this.entries.length === 0){return null;}
 		return this.entries[0]; //object
 	},
-	getEntry: function(/*String*/entryId){
-		//	summary:
+	getEntry: function(/*String*/ entryId){
+		// summary:
 		//		Function to get an entry by its id.
-		//	description:
-		//		Function to get an entry by its id.
-		//
-		//	returns:
+		// returns:
 		//		The entry desired, or null if none.
 		if(!this.entries){return null;}
 		for(var x in this.entries){
@@ -1031,13 +933,10 @@ model.Feed = dojo.declare(/*===== "dojox.atom.io.model.Feed", =====*/ model.Atom
 		}
 		return null;
 	},
-	removeEntry: function(/*object*/entry){
-		//	summary:
-		//		Function to remove an entry from the list of links.
-		//	description:
+	removeEntry: function(/*object*/ entry){
+		// summary:
 		//		Function to remove an entry from the list of links.
-		//
-		//	entry:
+		// entry:
 		//		The entry.
 		if(!this.entries){return;}
 		var count = 0;
@@ -1049,22 +948,17 @@ model.Feed = dojo.declare(/*===== "dojox.atom.io.model.Feed", =====*/ model.Atom
 		}
 		return count;
 	},
-	setEntries: function(/*array*/arrayOfEntry){
-		//	summary:
+	setEntries: function(/*array*/ arrayOfEntry){
+		// summary:
 		//		Function to add a set of entries to the feed.
-		//	description:
-		//		Function to get an entry by its id.
-		//
-		//	arrayOfEntry:
+		// arrayOfEntry:
 		//		An array of entry objects to add to the feed.
 		for(var x in arrayOfEntry){
 			this.addEntry(arrayOfEntry[x]);
 		}
 	},
 	toString: function(){
-		//	summary:
-		//		Function to construct string form of the feed tag, which is an XML structure.
-		//	description:
+		// summary:
 		//		Function to construct string form of the feed tag, which is an XML structure.
 		var s = [];
 		var i;
@@ -1103,22 +997,18 @@ model.Feed = dojo.declare(/*===== "dojox.atom.io.model.Feed", =====*/ model.Atom
 		return s.join('');
 	},
 	createEntry: function(){
-		//	summary:
+		// summary:
 		//		Function to Create a new entry object in the feed.
-		//	description:
-		//		Function to Create a new entry object in the feed.
-		//	returns:
+		// returns:
 		//		An empty entry object in the feed.
 		var entry = new model.Entry();
 		entry.feedUrl = this.getSelfHref();
 		return entry; //object
 	},
 	getSelfHref: function(){
-		//	summary:
-		//		Function to get the href that refers to this feed.
-		//	description:
+		// summary:
 		//		Function to get the href that refers to this feed.
-		//	returns:
+		// returns:
 		//		The href that refers to this feed or null if none.
 		if(this.links === null || this.links.length === 0){
 			return null;
@@ -1132,24 +1022,20 @@ model.Feed = dojo.declare(/*===== "dojox.atom.io.model.Feed", =====*/ model.Atom
 	}
 });
 
-model.Service = dojo.declare(/*===== "dojox.atom.io.model.Service", =====*/ model.AtomItem,{
-	//	summary:
-	//		Class container for 'Feed' types.
-	//	description:
+model.Service = declare(model.AtomItem,{
+	// summary:
 	//		Class container for 'Feed' types.
+
 	constructor: function(href){
 		this.href = href;
 	},
 	//builds a Service document.  each element of this, except for the namespace, is the href of
 	//a service that the server supports.  Some of the common services are:
 	//"create-entry" , "user-prefs" , "search-entries" , "edit-template" , "categories"
-	buildFromDom: function(/*DOM node*/node){
-		//	summary:
-		//		Function to do construction of the Service data from the DOM node containing it.
-		//	description:
+	buildFromDom: function(/*DOMNode*/ node){
+		// summary:
 		//		Function to do construction of the Service data from the DOM node containing it.
-		//
-		//	node:
+		// node:
 		//		The DOM node to process for content.
 		var i;
 		this.workspaces = [];
@@ -1187,13 +1073,10 @@ model.Service = dojo.declare(/*===== "dojox.atom.io.model.Service", =====*/ mode
 			}
 		}
 	},
-	getCollection: function(/*String*/url){
-		//	summary:
+	getCollection: function(/*String*/ url){
+		// summary:
 		//		Function to collections that match a specific url.
-		//	description:
-		//		Function to collections that match a specific url.
-		//
-		//	url:
+		// url:
 		//		e URL to match collections against.
 		for(var i=0;i<this.workspaces.length;i++){
 			var coll=this.workspaces[i].collections;
@@ -1207,23 +1090,18 @@ model.Service = dojo.declare(/*===== "dojox.atom.io.model.Service", =====*/ mode
 	}
 });
 
-model.Workspace = dojo.declare(/*===== "dojox.atom.io.model.Workspace", =====*/ model.AtomItem,{
-	//	summary:
-	//		Class container for 'Workspace' types.
-	//	description:
+model.Workspace = declare(model.AtomItem,{
+	// summary:
 	//		Class container for 'Workspace' types.
 	constructor: function(title){
 		this.title = title;
 		this.collections = [];
 	},
 
-	buildFromDom: function(/*DOM node*/node){
-		//	summary:
+	buildFromDom: function(/*DOMNode*/ node){
+		// summary:
 		//		Function to do construction of the Workspace data from the DOM node containing it.
-		//	description:
-		//		Function to do construction of the Workspace data from the DOM node containing it.
-		//
-		//	node:
+		// node:
 		//		The DOM node to process for content.
 		var name = model.util.getNodename(node);
 		if(name != "workspace"){return;}
@@ -1251,11 +1129,10 @@ model.Workspace = dojo.declare(/*===== "dojox.atom.io.model.Workspace", =====*/
 	}
 });
 
-model.Collection = dojo.declare(/*===== "dojox.atom.io.model.Collection", =====*/ model.AtomItem,{
-	//	summary:
-	//		Class container for 'Collection' types.
-	//	description:
+model.Collection = declare(model.AtomItem,{
+	// summary:
 	//		Class container for 'Collection' types.
+
 	constructor: function(href, title){
 		this.href = href;
 		this.title = title;
@@ -1266,13 +1143,10 @@ model.Collection = dojo.declare(/*===== "dojox.atom.io.model.Collection", =====*
 		this.id = null;
 	},
 
-	buildFromDom: function(/*DOM node*/node){
-		//	summary:
-		//		Function to do construction of the Collection data from the DOM node containing it.
-		//	description:
+	buildFromDom: function(/*DOMNode*/ node){
+		// summary:
 		//		Function to do construction of the Collection data from the DOM node containing it.
-		//
-		//	node:
+		// node:
 		//		The DOM node to process for content.
 		this.href = node.getAttribute("href");
 		var c = node.childNodes;
diff --git a/dojox/atom/widget/FeedEntryEditor.js b/dojox/atom/widget/FeedEntryEditor.js
index 6f04828..a78f353 100644
--- a/dojox/atom/widget/FeedEntryEditor.js
+++ b/dojox/atom/widget/FeedEntryEditor.js
@@ -2,6 +2,7 @@ define([
 	"dojo/_base/kernel",
 	"dojo/_base/lang",
 	"dojo/_base/connect",
+	"dojo/_base/declare",
 	"dojo/_base/fx",
 	"dojo/_base/sniff",
 	"dojo/dom",
@@ -19,18 +20,17 @@ define([
 	"dojo/text!./templates/PeopleEditor.html",
 	"dojo/i18n!./nls/FeedEntryViewer",
 	"dojo/i18n!./nls/FeedEntryEditor",
-	"dojo/i18n!./nls/PeopleEditor",
-	"dojo/_base/declare"
-], function (dojo, lang, connect, fx, has, domUtil, domStyle, domConstruct, _Widget, _Templated, _Container, Editor, TextBox, SimpleTextarea, FeedEntryViewer, model, template, peopleEditorTemplate, i18nViewer, i18nEditor, i18nPeople) {
+	"dojo/i18n!./nls/PeopleEditor"
+], function (dojo, lang, connect, declare, fx, has, domUtil, domStyle, domConstruct,
+			 _Widget, _Templated, _Container, Editor, TextBox, SimpleTextarea,
+			 FeedEntryViewer, model, template, peopleEditorTemplate, i18nViewer, i18nEditor, i18nPeople) {
 dojo.experimental("dojox.atom.widget.FeedEntryEditor");
 
-var widget = dojo.getObject("dojox.atom.widget", true);
 
-widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor", =====*/ FeedEntryViewer,{
-	//	summary:
-	//		An ATOM feed entry editor that allows viewing of the individual attributes of an entry.
-	//	description:
+var FeedEntryEditor = declare("dojox.atom.widget.FeedEntryEditor", FeedEntryViewer,{
+	// summary:
 	//		An ATOM feed entry editor that allows viewing of the individual attributes of an entry.
+
 	_contentEditor: null,
 	_oldContent: null,
 	_setObject: null,
@@ -66,12 +66,9 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 	
 	setEntry: function(/*object*/entry, /*object*/feed, /*boolean*/leaveMenuState){
-		//	summary:
+		// summary:
 		//		Function to set the current entry that is being edited.
-		//	description:
-		//		Function to set the current entry that is being edited.
-		//
-		//	entry:
+		// entry:
 		//		Instance of dojox.atom.io.model.Entry to display for reading/editing.
 		if(this._entry !== entry){
 			//If we swap entries, we don't want to keep the menu states and modes.
@@ -80,7 +77,7 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 		}else{
 			leaveMenuState = true;
 		}
-		widget.FeedEntryEditor.superclass.setEntry.call(this, entry, feed);
+		FeedEntryEditor.superclass.setEntry.call(this, entry, feed);
 		this._editable = this._isEditable(entry);
 		if(!leaveMenuState && !this._editable){
 			domStyle.set(this.entryEditButton, 'display', 'none');
@@ -98,12 +95,9 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 
 	_toggleEdit: function(){
-		//	summary:
-		//		Internal function for toggling/enabling the display of edit mode
-		//	description:
+		// summary:
 		//		Internal function for toggling/enabling the display of edit mode
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		if(this._editable && this.enableEdit){
 			domStyle.set(this.entryEditButton, 'display', 'none');
@@ -116,34 +110,28 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 
 	_handleEvent: function(/*object*/entrySelectionEvent){
-		//	summary:
+		// summary:
 		//		Internal function for listening to a topic that will handle entry notification.
-		//	description:
-		//		Internal function for listening to a topic that will handle entry notification.
-		//
-		//	entrySelectionEvent:
+		// entrySelectionEvent:
 		//		The topic message containing the entry that was selected for view.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		if(entrySelectionEvent.source != this && entrySelectionEvent.action == "delete" &&
 			entrySelectionEvent.entry && entrySelectionEvent.entry == this._entry){
 				domStyle.set(this.entryEditButton, 'display', 'none');
 		}
-		widget.FeedEntryEditor.superclass._handleEvent.call(this, entrySelectionEvent);
+		FeedEntryEditor.superclass._handleEvent.call(this, entrySelectionEvent);
 	},
 
 	_isEditable: function(/*object*/entry){
-		//	summary:
+		// summary:
 		//		Internal function for determining of a particular entry is editable.
-		//	description:
+		// description:
 		//		Internal function for determining of a particular entry is editable.
 		//		This is used for determining if the delete action should be displayed or not.
-		//
-		//	entry:
+		// entry:
 		//		The dojox.atom.io.model.Entry object to examine
-		//
-		//	returns:
+		// returns:
 		//		Boolean denoting if the entry seems editable or not..
 		var retVal = false;
 		if(entry && entry !== null && entry.links && entry.links !== null){
@@ -160,21 +148,20 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	// The following set<Attribute> functions override the corresponding functions in FeedEntryViewer.  These handle
 	// the editMode flag by inserting appropriate editor widgets inside of just splashing the content in the page.
 	setTitle: function(/*DOM node*/titleAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+		// summary:
 		//		Function to set the contents of the title node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the title node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	titleAnchorNode:
+		// titleAnchorNode:
 		//		The DOM node to attach the title data to.
-		//	editMode:
-		// 		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// editMode:
+		//		Boolean to indicate if the display should be in edit mode or not.
+		// entry:
 		//		The Feed Entry to work with.
-		//
+
 		if(!editMode){
-			widget.FeedEntryEditor.superclass.setTitle.call(this, titleAnchorNode, editMode, entry);
+			FeedEntryEditor.superclass.setTitle.call(this, titleAnchorNode, editMode, entry);
 			if(entry.title && entry.title.value && entry.title.value !== null){
 				this.setFieldValidity("title", true);
 			}
@@ -195,20 +182,19 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 
 	setAuthors: function(/*DOM node*/authorsAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+		// summary:
 		//		Function to set the contents of the author node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the author node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	authorsAnchorNode:
+		// authorsAnchorNode:
 		//		The DOM node to attach the author data to.
-		//	editMode:
-		// 		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
-		// 		The Feed Entry to work with.
+		// editMode:
+		//		Boolean to indicate if the display should be in edit mode or not.
+		// entry:
+		//		The Feed Entry to work with.
 		if(!editMode){
-			widget.FeedEntryEditor.superclass.setAuthors.call(this, authorsAnchorNode, editMode, entry);
+			FeedEntryEditor.superclass.setAuthors.call(this, authorsAnchorNode, editMode, entry);
 			if(entry.authors && entry.authors.length > 0){
 				this.setFieldValidity("authors", true);
 			}
@@ -222,20 +208,19 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 
 
 	setContributors: function(/*DOM node*/contributorsAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+		// summary:
 		//		Function to set the contents of the contributor node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the contributor node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	contributorsAnchorNode:
+		// contributorsAnchorNode:
 		//		The DOM node to attach the contributor data to.
-		//	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(!editMode){
-			widget.FeedEntryEditor.superclass.setContributors.call(this, contributorsAnchorNode, editMode, entry);
+			FeedEntryEditor.superclass.setContributors.call(this, contributorsAnchorNode, editMode, entry);
 			if(entry.contributors && entry.contributors.length > 0){
 				this.setFieldValidity("contributors", true);
 			}
@@ -249,20 +234,19 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 
 
 	setId: function(/*DOM node*/idAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+		// summary:
 		//		Function to set the contents of the ID  node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the ID node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	idAnchorNode:
+		// idAnchorNode:
 		//		The DOM node to attach the ID data to.
-		//	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(!editMode){
-			widget.FeedEntryEditor.superclass.setId.call(this, idAnchorNode, editMode, entry);
+			FeedEntryEditor.superclass.setId.call(this, idAnchorNode, editMode, entry);
 			if(entry.id && entry.id !== null){
 				this.setFieldValidity("id", true);
 			}
@@ -275,20 +259,19 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 
 	setUpdated: function(/*DOM node*/updatedAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+		// summary:
 		//		Function to set the contents of the updated  node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the updated node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	updatedAnchorNode:
-		//		The DOM node to attach the udpated data to.
-		//	editMode:
+		// updatedAnchorNode:
+		//		The DOM node to attach the updated data to.
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(!editMode){
-			widget.FeedEntryEditor.superclass.setUpdated.call(this, updatedAnchorNode, editMode, entry);
+			FeedEntryEditor.superclass.setUpdated.call(this, updatedAnchorNode, editMode, entry);
 			if(entry.updated && entry.updated !== null){
 				this.setFieldValidity("updated", true);
 			}
@@ -302,20 +285,19 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 
 
 	setSummary: function(/*DOM node*/summaryAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+		// summary:
 		//		Function to set the contents of the summary  node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the summary node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	summaryAnchorNode:
+		// summaryAnchorNode:
 		//		The DOM node to attach the summary data to.
-		//	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(!editMode){
-			widget.FeedEntryEditor.superclass.setSummary.call(this, summaryAnchorNode, editMode, entry);
+			FeedEntryEditor.superclass.setSummary.call(this, summaryAnchorNode, editMode, entry);
 			if(entry.summary && entry.summary.value && entry.summary.value !== null){
 				this.setFieldValidity("summary", true);
 			}
@@ -336,20 +318,19 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 
 	setContent: function(/*DOM node*/contentAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+		// summary:
 		//		Function to set the contents of the content node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the content node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	summaryAnchorNode:
+		// summaryAnchorNode:
 		//		The DOM node to attach the content data to.
-		//	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		// 	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(!editMode){
-			widget.FeedEntryEditor.superclass.setContent.call(this, contentAnchorNode, editMode, entry);
+			FeedEntryEditor.superclass.setContent.call(this, contentAnchorNode, editMode, entry);
 			if(entry.content && entry.content.value && entry.content.value !== null){
 				this.setFieldValidity("content",true);
 			}
@@ -369,23 +350,19 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 	
 	_createEditor: function(/*DOM node*/anchorNode, /*DOM node*/node, /*boolean*/multiline, /*object*/rte){
-		//	summary:
+		// summary:
 		//		Function to create an appropriate text editor widget based on the given parameters.
-		//	description:
-		//		Function to create an appropriate text editor widget based on the given parameters.
-		//
-		//	anchorNode:
+		// anchorNode:
 		//		The DOM node to attach the editor widget to.
-		//	node:
+		// node:
 		//		An object containing the value to be put into the editor.  This ranges from an anonymous object
 		//		with a value parameter to a dojox.atom.io.model.Content object.
-		//	multiline:
+		// multiline:
 		//		A boolean indicating whether the content should be multiline (such as a textarea) instead of a
 		//		single line (such as a textbox).
-		//	rte:
+		// rte:
 		//		A boolean indicating whether the content should be a rich text editor widget.
-		//
-		//	returns:
+		// returns:
 		//		Either a widget (for textarea or textbox widgets) or an anonymous object to be used to create a
 		//		rich text area widget.
 		var viewNode;
@@ -476,13 +453,12 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 	
 	_switchEditor: function(/*object*/event){
-		//	summary:
+		// summary:
 		//		Function to switch between editor types.
-		//	description:
+		// description:
 		//		Function to switch between a rich text editor and a textarea widget.  Used for title, summary,
 		//		And content when switching between text and html/xhtml content.
-		//
-		//	event:
+		// event:
 		//		The event generated by the change in the select box on the page.
 		var type = null;
 		var target = null;
@@ -542,32 +518,28 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 	
 	_createPeopleEditor: function(/*DOM node*/anchorNode, /*DOM node*/node){
-		//	summary:
-		//		Creates a People Editor widget and returns it.
-		//	description:
+		// summary:
 		//		Creates a People Editor widget, sets its value, and returns it.
-		//
-		//	anchorNode:
+		// anchorNode:
 		//		The node to attach the editor to.
-		//	node:
+		// node:
 		//		An object containing the value to be put into the editor. Typically, this is an
 		//		dojox.atom.io.model.Person object.
-		//
-		// returns: A new People Editor object.
+		// returns:
+		//		A new People Editor object.
 		var viewNode = document.createElement("div");
 		anchorNode.appendChild(viewNode);
-		return new widget.PeopleEditor(node,viewNode);
+		return new PeopleEditor(node,viewNode);
 	},
 
 	saveEdits: function(){
-		//	summary:
+		// summary:
 		//		Saves edits submitted when the 'save' button is pressed.
-		//	description:
+		// description:
 		//		Saves edits submitted when the 'save' button is pressed.  Distinguishes between new and existing
 		//		entries and saves appropriately.  Fetches the values of the editors, and, if existing, compares them to
 		//		the existing values and submits the updates, otherwise creates a new entry and posts it as a new entry.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		domStyle.set(this.entrySaveCancelButtons, 'display', 'none');
 		domStyle.set(this.entryEditButton, 'display', '');
@@ -706,7 +678,7 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 				//var atomIO = new dojox.atom.io.Connection();
 				//atomIO.updateEntry(entry, dojo.hitch(this,this._handleSave));
 				//WARNING: Use above when testing with SimpleProxy (or any other servlet which
-				// 			doesn't actually create a new entry and return it properly)
+				//			doesn't actually create a new entry and return it properly)
 				//atomIO.updateEntry(entry, dojo.hitch(this,this._handleSave), true);
 			}
 		}else{
@@ -759,18 +731,15 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 		this.setEntry(entry, this._feed, true);
 	},
 	
-	_handleSave: function(/*object*/entry, /*string*/location){
-		//	summary:
-		//		Function for handling the save of an entry, cleaning up the display after the edit is completed.
-		//	description:
+	_handleSave: function(/*object*/entry, /*string*/ location){
+		// summary:
 		//		Function for handling the save of an entry, cleaning up the display after the edit is completed.
-		//
-		//	entry: dojox.atom.io.model.Entry object
+		// entry: dojox.atom.io.model.Entry object
 		//		The entry that was saved.
-		//	Location: String
+		// Location: String
 		//		A URL to be used, not used here, but part of the call back from the AtomIO
-		//	returns:
-		//		Nothing.
+		// returns: Nothing
+
 		//Close the editor and revert out.
 		this._editMode = false;
 		
@@ -780,12 +749,9 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 
 	cancelEdits: function(){
-		//	summary:
-		//		Cancels edits and reverts the editor to its previous state (display mode)
-		//	description:
+		// summary:
 		//		Cancels edits and reverts the editor to its previous state (display mode)
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		this._new = false;
 		domStyle.set(this.entrySaveCancelButtons, 'display', 'none');
@@ -801,13 +767,11 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 
 	clear: function(){
-		//	summary:
-		//		Clears the editor, destorys all editors, leaving the editor completely clear
-		//	description:
-		//		Clears the editor, destorys all editors, leaving the editor completely clear
+		// summary:
+		//		Clears the editor, destroys all editors, leaving the editor completely clear
 		this._editable=false;
 		this.clearEditors();
-		widget.FeedEntryEditor.superclass.clear.apply(this);
+		FeedEntryEditor.superclass.clear.apply(this);
 		if(this._contentEditor){
 			// Note that the superclass clear destroys the widget since it's in the child widget list,
 			// so this is just ref clearing.
@@ -827,15 +791,11 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 
 	_enforceXhtml: function(/*string*/html){
-		//	summary:
+		// summary:
 		//		Function for cleaning up/enforcing the XHTML standard in HTML returned from the editor2 widget.
-		//	description:
-		//		Function for cleaning up/enforcing the XHTML standard in HTML returned from the editor2 widget.
-		//
-		// 	html:
+		// html:
 		//		HTML string to be enforced as xhtml.
-		//
-		// 	returns:
+		// returns:
 		//		string of cleaned up HTML.
 		var xhtml = null;
 		if(html){
@@ -853,18 +813,15 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 
 	_closeTag: function(/*string*/xhtml, /*string*/tag){
-		//	summary:
-		//		Function for closing tags in a text of HTML/XHTML
-		//	description:
+		// summary:
 		//		Function for closing tags in a text of HTML/XHTML
-		//
-		//	xhtml: String
+		// xhtml: String
 		//		XHTML string which needs the closing tag.
-		//	tag:
+		// tag:
 		//		The tag to close.
-		//
-		//	returns:  string of cleaned up HTML.
-		//
+		// returns:
+		//		string of cleaned up HTML.
+
 		// NOTE:  Probably should redo this function in a more efficient way.  This could get expensive.
 		var tagStart = "<" + tag;
 		var tagIndex = xhtml.indexOf(tagStart);
@@ -894,11 +851,9 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 	
 	_toggleNew: function(){
-		//	summary:
+		// summary:
 		//		Function to put the editor into a state to create a new entry.
-		//	description:
-		//		Function to put the editor into a state to create a new entry.
-		
+
 		// Hide the edit/new buttons and show the save/cancel buttons.
 		domStyle.set(this.entryNewButton, 'display', 'none');
 		domStyle.set(this.entryEditButton, 'display', 'none');
@@ -915,44 +870,44 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 		
 		var _nlsResources = i18nViewer;
 		// Create all headers and editors.
-		var titleHeader = new widget.EntryHeader({title: _nlsResources.title});
+		var titleHeader = new FeedEntryViewer.EntryHeader({title: _nlsResources.title});
 		this.entryTitleHeader.appendChild(titleHeader.domNode);
 		
 		this._editors.title = this._createEditor(this.entryTitleNode, null);
 		this.setFieldValidity("title",true);
 		
-		var authorHeader = new widget.EntryHeader({title: _nlsResources.authors});
+		var authorHeader = new FeedEntryViewer.EntryHeader({title: _nlsResources.authors});
 		this.entryAuthorHeader.appendChild(authorHeader.domNode);
 
 		this._editors.authors = this._createPeopleEditor(this.entryAuthorNode, {name: "Author"});
 		this.setFieldValidity("authors", true);
 		
-		var contributorHeader = new widget.EntryHeader({title: _nlsResources.contributors});
+		var contributorHeader = new FeedEntryViewer.EntryHeader({title: _nlsResources.contributors});
 		this.entryContributorHeader.appendChild(contributorHeader.domNode);
 
 		this._editors.contributors = this._createPeopleEditor(this.entryContributorNode, {name: "Contributor"});
 		this.setFieldValidity("contributors", true);
 		
-		var idHeader = new widget.EntryHeader({title: _nlsResources.id});
+		var idHeader = new FeedEntryViewer.EntryHeader({title: _nlsResources.id});
 		this.entryIdHeader.appendChild(idHeader.domNode);
 		
 		this._editors.id = this._createEditor(this.entryIdNode, null);
 		this.setFieldValidity("id",true);
 
-		var updatedHeader = new widget.EntryHeader({title: _nlsResources.updated});
+		var updatedHeader = new FeedEntryViewer.EntryHeader({title: _nlsResources.updated});
 		this.entryUpdatedHeader.appendChild(updatedHeader.domNode);
 		
 		this._editors.updated = this._createEditor(this.entryUpdatedNode, null);
 		this.setFieldValidity("updated",true);
 
-		var summaryHeader = new widget.EntryHeader({title: _nlsResources.summary});
+		var summaryHeader = new FeedEntryViewer.EntryHeader({title: _nlsResources.summary});
 		this.entrySummaryHeader.appendChild(summaryHeader.domNode);
 		
 		this._editors.summary = this._createEditor(this.entrySummaryNode, null, true);
 		this.setFieldValidity("summaryedit",true);
 		this.setFieldValidity("summary",true);
 
-		var contentHeader = new widget.EntryHeader({title: _nlsResources.content});
+		var contentHeader = new FeedEntryViewer.EntryHeader({title: _nlsResources.content});
 		this.entryContentHeader.appendChild(contentHeader.domNode);
 		
 		this._editors.content = this._createEditor(this.entryContentNode, null, true);
@@ -964,9 +919,9 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	},
 	
 	_displaySections: function(){
-		// summary: Function to display the appropriate sections based on validity.
-		// description: Function to display the appropriate sections based on validity.
-		
+		// summary:
+		//		Function to display the appropriate sections based on validity.
+
 		// Hide select boxes.
 		domStyle.set(this.entrySummarySelect, 'display', 'none');
 		domStyle.set(this.entryContentSelect, 'display', 'none');
@@ -983,7 +938,7 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 			domStyle.set(this.entryTitleSelect, 'display', '');
 		}
 		// Call super's _displaySections.
-		widget.FeedEntryEditor.superclass._displaySections.apply(this);
+		FeedEntryEditor.superclass._displaySections.apply(this);
 		
 		// If we have editors to load after the nodes are created on the page, execute those now.
 		if(this._toLoad){
@@ -1002,10 +957,10 @@ widget.FeedEntryEditor = dojo.declare(/*===== "dojox.atom.widget.FeedEntryEditor
 	}
 });
 
-widget.PeopleEditor = dojo.declare(/*===== "dojox.atom.widget.PeopleEditor", =====*/ [_Widget, _Templated, _Container],{
-		//	summary:
+var PeopleEditor = declare("dojox.atom.widget.PeopleEditor", [_Widget, _Templated, _Container],{
+		// summary:
 		//		An editor for dojox.atom.io.model.Person objects.
-		//	description:
+		// description:
 		//		An editor for dojox.atom.io.model.Person objects.  Displays multiple rows for the respective arrays
 		//		of people.  Can add/remove rows on the fly.
 		templateString: peopleEditorTemplate,
@@ -1051,18 +1006,15 @@ widget.PeopleEditor = dojo.declare(/*===== "dojox.atom.widget.PeopleEditor", ===
 		},
 		
 		_createEditors: function(/*string*/name, /*string*/email, /*string*/uri, /*int*/index, /*string*/widgetName){
-			//	summary:
-			//		creates editor boxes (textbox widgets) for the individual values of a Person.
-			//	description:
+			// summary:
 			//		creates editor boxes (textbox widgets) for the individual values of a Person.
-			//
-			//	name:
+			// name:
 			//		The name of this Person.
-			//	email:
+			// email:
 			//		The email of this Person.
-			//	uri:
+			// uri:
 			//		The Person's URI.
-			//	index:
+			// index:
 			//		The row index to use for this Person.
 			var row = document.createElement("tr");
 			this.peopleEditorEditors.appendChild(row);
@@ -1121,23 +1073,19 @@ widget.PeopleEditor = dojo.declare(/*===== "dojox.atom.widget.PeopleEditor", ===
 		},
 		
 		_createEditor: function(/*string*/value, /*string*/id, /*string*/name, /*DOM node*/labelNode, /*DOM node*/node){
-			//	summary:
+			// summary:
 			//		Creates an individual editor widget (textbox) for a value.
-			// 	description:
-			//		Creates an individual editor widget (textbox) for a value.
-			//
-			// 	value:
+			// value:
 			//		The initial value of the textbox
-			// 	id:
+			// id:
 			//		The id the textbox should have.
-			// 	name:
+			// name:
 			//		The text to put in the label element for this textbox.
-			//	labelNode:
+			// labelNode:
 			//		The node to attach the label to.
-			//	node:
+			// node:
 			//		The node to attach the editor rows to.
-			//
-			//	returns:
+			// returns:
 			//		Editor widget.
 			var row = document.createElement("tr");
 			labelNode.appendChild(row);
@@ -1166,13 +1114,12 @@ widget.PeopleEditor = dojo.declare(/*===== "dojox.atom.widget.PeopleEditor", ===
 		},
 		
 		_removeEditor: function(/*object*/event){
-			//	summary:
+			// summary:
 			//		Removes a Person from our list of editors.
-			//	description:
+			// description:
 			//		Removes a Person from our list of editors by removing the block of editors that
 			//		make up that Person.
-			//
-			//	event:
+			// event:
 			//		The event generated when the remove button is pressed on the page.
 			var target = null;
 		
@@ -1205,9 +1152,7 @@ widget.PeopleEditor = dojo.declare(/*===== "dojox.atom.widget.PeopleEditor", ===
 		},
 		
 		_add: function(){
-			//	summary:
-			//		Adds a new block of blank editors to represent a Person.
-			//	description:
+			// summary:
 			//		Adds a new block of blank editors to represent a Person.
 			this._createEditors(null, null, null, this._index);
 			this._index++;
@@ -1215,12 +1160,11 @@ widget.PeopleEditor = dojo.declare(/*===== "dojox.atom.widget.PeopleEditor", ===
 		},
 		
 		getValues: function(){
-			//	summary:
+			// summary:
 			//		Gets the values of this editor in an array.
-			//	description:
+			// description:
 			//		Gets the values of this editor in an array, with each Person as an object within the array.
-			//
-			//	returns:
+			// returns:
 			//		An array of anonymous objects representing dojox.atom.io.model.Persons.
 			var values = [];
 			for(var i in this._editors){
@@ -1231,5 +1175,6 @@ widget.PeopleEditor = dojo.declare(/*===== "dojox.atom.widget.PeopleEditor", ===
 			return values;
 		}
 });
-return widget.FeedEntryEditor;
+
+return FeedEntryEditor;
 });
diff --git a/dojox/atom/widget/FeedEntryViewer.js b/dojox/atom/widget/FeedEntryViewer.js
index d3c98f5..5b32dbf 100644
--- a/dojox/atom/widget/FeedEntryViewer.js
+++ b/dojox/atom/widget/FeedEntryViewer.js
@@ -18,17 +18,15 @@ define([
 
 dojo.experimental("dojox.atom.widget.FeedEntryViewer");
 
-var widget = dojo.getObject("dojox.atom.widget", true);
 
-widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer", =====*/ [_Widget, _Templated, _Container],{
-	//	summary:
-	//		An ATOM feed entry editor for publishing updated ATOM entries, or viewing non-editable entries.
-	//	description:
+var FeedEntryViewer = declare("dojox.atom.widget.FeedEntryViewer", [_Widget, _Templated, _Container],{
+	// summary:
 	//		An ATOM feed entry editor for publishing updated ATOM entries, or viewing non-editable entries.
+
 	entrySelectionTopic: "",	//The topic to listen on for entries to edit.
 
 	_validEntryFields: {},		//The entry fields that were present on the entry and are being displayed.
-								//This works in conjuntion with what is selected to be displayed.
+								//This works in conjunction with what is selected to be displayed.
 	displayEntrySections: "", //What current sections of the entries to display as a comma separated list.
 	_displayEntrySections: null,
 	
@@ -81,10 +79,9 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 
 	clear: function(){
-		//	summary:
-		//		Function to clear the state of the widget.
-		//	description:
+		// summary:
 		//		Function to clear the state of the widget.
+
 		this.destroyDescendants();
 		this._entry=null;
 		this._feed=null;
@@ -92,9 +89,7 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 	
 	clearNodes: function(){
-		//	summary:
-		//		Function to clear all the display nodes for the ATOM entry from the viewer.
-		//	description:
+		// summary:
 		//		Function to clear all the display nodes for the ATOM entry from the viewer.
 
 		arrayUtil.forEach([
@@ -118,12 +113,9 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 
 	setEntry: function(/*object*/entry, /*object*/feed, /*boolean*/leaveMenuState){
-		//	summary:
-		//		Function to set the current entry that is being edited.
-		//	description:
+		// summary:
 		//		Function to set the current entry that is being edited.
-		//
-		//	entry:
+		// entry:
 		//		Instance of dojox.atom.io.model.Entry to display for reading/editing.
 		this.clear();
 		this._validEntryFields = {};
@@ -191,39 +183,37 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 		this._displaySections();
 	},
 
-	setTitleHeader: function(/*DOM node*/titleHeaderNode, /*object*/entry){
-		//	summary:
+	setTitleHeader: function(/*DOMNode*/ titleHeaderNode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the title header node in the template to some value.
-		//	description:
+		// description:
 		//		Function to set the contents of the title header node in the template to some value.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	titleAchorNode:
+		// titleAnchorNode:
 		//		The DOM node to attach the title data to.
-		//	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
-		//
+
 		if(entry.title && entry.title.value && entry.title.value !== null){
 			var _nlsResources = i18nViewer;
-			var titleHeader = new widget.EntryHeader({title: _nlsResources.title});
+			var titleHeader = new EntryHeader({title: _nlsResources.title});
 			titleHeaderNode.appendChild(titleHeader.domNode);
 		}
 	},
 
 	setTitle: function(titleAnchorNode, editMode, entry){
-		//	summary:
+		// summary:
 		//		Function to set the contents of the title node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the title node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	titleAchorNode:
+		// titleAnchorNode:
 		//		The DOM node to attach the title data to.
-		//	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.title && entry.title.value && entry.title.value !== null){
 			if(entry.title.type == "text"){
@@ -239,36 +229,34 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 		}
 	},
 
-	setAuthorsHeader: function(/*DOM node*/authorHeaderNode, /*object*/entry){
-		//	summary:
+	setAuthorsHeader: function(/*DOMNode*/ authorHeaderNode, /*object*/entry){
+		// summary:
 		//		Function to set the title format for the authors section of the author row in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the title format for the authors section of the author row in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the author data is filled out from an entry.
-		//
-		//	authorHeaderNode:
+		// authorHeaderNode:
 		//		The DOM node to attach the author section header data to.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.authors && entry.authors.length > 0){
 			var _nlsResources = i18nViewer;
-			var authorHeader = new widget.EntryHeader({title: _nlsResources.authors});
+			var authorHeader = new EntryHeader({title: _nlsResources.authors});
 			authorHeaderNode.appendChild(authorHeader.domNode);
 		}
 	},
 
-	setAuthors: function(/*DOM node*/authorsAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+	setAuthors: function(/*DOMNode*/ authorsAnchorNode, /*boolean*/editMode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the author node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the author node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	authorsAchorNode:
+		// authorsAnchorNode:
 		//		The DOM node to attach the author data to.
-		//	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		authorsAnchorNode.innerHTML = "";
 		if(entry.authors && entry.authors.length > 0){
@@ -295,37 +283,35 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 		}
 	},
 
-	setContributorsHeader: function(/*DOM node*/contributorsHeaderNode, /*object*/entry){
-		//	summary:
+	setContributorsHeader: function(/*DOMNode*/ contributorsHeaderNode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the contributor header node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the contributor header node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	contributorsHeaderNode:
+		// contributorsHeaderNode:
 		//		The DOM node to attach the contributor title to.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.contributors && entry.contributors.length > 0){
 			var _nlsResources = i18nViewer;
-			var contributorHeader = new widget.EntryHeader({title: _nlsResources.contributors});
+			var contributorHeader = new EntryHeader({title: _nlsResources.contributors});
 			contributorsHeaderNode.appendChild(contributorHeader.domNode);
 		}
 	},
 
 
-	setContributors: function(/*DOM node*/contributorsAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+	setContributors: function(/*DOMNode*/ contributorsAnchorNode, /*boolean*/editMode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the contributor node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the contributor node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	contributorsAnchorNode:
+		// contributorsAnchorNode:
 		//		The DOM node to attach the contributor data to.
-		//	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.contributors && entry.contributors.length > 0){
 			for(var i in entry.contributors){
@@ -339,37 +325,35 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 
 				 
-	setIdHeader: function(/*DOM node*/idHeaderNode, /*object*/entry){
-		//	summary:
+	setIdHeader: function(/*DOMNode*/ idHeaderNode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the ID  node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the ID node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	idAnchorNode:
+		// idAnchorNode:
 		//		The DOM node to attach the ID data to.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.id && entry.id !== null){
 			var _nlsResources = i18nViewer;
-			var idHeader = new widget.EntryHeader({title: _nlsResources.id});
+			var idHeader = new EntryHeader({title: _nlsResources.id});
 			idHeaderNode.appendChild(idHeader.domNode);
 		}
 	},
 
 
-	setId: function(/*DOM node*/idAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+	setId: function(/*DOMNode*/ idAnchorNode, /*boolean*/editMode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the ID  node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the ID node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	idAnchorNode:
+		// idAnchorNode:
 		//		The DOM node to attach the ID data to.
-		// 	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.id && entry.id !== null){
 			var idNode = document.createTextNode(entry.id);
@@ -378,36 +362,34 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 		}
 	},
 	
-	setUpdatedHeader: function(/*DOM node*/updatedHeaderNode, /*object*/entry){
-		//	summary:
+	setUpdatedHeader: function(/*DOMNode*/ updatedHeaderNode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the updated header node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the updated header node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	updatedHeaderNode:
+		// updatedHeaderNode:
 		//		The DOM node to attach the updated header data to.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.updated && entry.updated !== null){
 			var _nlsResources = i18nViewer;
-			var updatedHeader = new widget.EntryHeader({title: _nlsResources.updated});
+			var updatedHeader = new EntryHeader({title: _nlsResources.updated});
 			updatedHeaderNode.appendChild(updatedHeader.domNode);
 		}
 	},
 
-	setUpdated: function(/*DOM node*/updatedAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+	setUpdated: function(/*DOMNode*/ updatedAnchorNode, /*boolean*/editMode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the updated  node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the updated node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	updatedAnchorNode:
+		// updatedAnchorNode:
 		//		The DOM node to attach the udpated data to.
-		//	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.updated && entry.updated !== null){
 			var updatedNode = document.createTextNode(entry.updated);
@@ -416,37 +398,35 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 		}
 	},
 
-	setSummaryHeader: function(/*DOM node*/summaryHeaderNode, /*object*/entry){
-		//	summary:
+	setSummaryHeader: function(/*DOMNode*/ summaryHeaderNode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the summary  node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the summary node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	summaryHeaderNode:
+		// summaryHeaderNode:
 		//		The DOM node to attach the summary title to.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.summary && entry.summary.value && entry.summary.value !== null){
 			var _nlsResources = i18nViewer;
-			var summaryHeader = new widget.EntryHeader({title: _nlsResources.summary});
+			var summaryHeader = new EntryHeader({title: _nlsResources.summary});
 			summaryHeaderNode.appendChild(summaryHeader.domNode);
 		}
 	},
 
 
-	setSummary: function(/*DOM node*/summaryAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+	setSummary: function(/*DOMNode*/ summaryAnchorNode, /*boolean*/editMode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the summary  node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the summary node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	summaryAnchorNode:
+		// summaryAnchorNode:
 		//		The DOM node to attach the summary data to.
-		//	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.summary && entry.summary.value && entry.summary.value !== null){
 			var summaryViewNode = document.createElement("span");
@@ -457,36 +437,34 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 		}
 	},
 
-	setContentHeader: function(/*DOM node*/contentHeaderNode, /*object*/entry){
-		//	summary:
+	setContentHeader: function(/*DOMNode*/ contentHeaderNode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the content node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the content node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	contentHeaderNode:
+		// contentHeaderNode:
 		//		The DOM node to attach the content data to.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.content && entry.content.value && entry.content.value !== null){
 			var _nlsResources = i18nViewer;
-			var contentHeader = new widget.EntryHeader({title: _nlsResources.content});
+			var contentHeader = new EntryHeader({title: _nlsResources.content});
 			contentHeaderNode.appendChild(contentHeader.domNode);
 		}
 	},
 
-	setContent: function(/*DOM node*/contentAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:
+	setContent: function(/*DOMNode*/ contentAnchorNode, /*boolean*/editMode, /*object*/entry){
+		// summary:
 		//		Function to set the contents of the content node in the template to some value from the entry.
-		//	description:
+		// description:
 		//		Function to set the contents of the content node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
-		//
-		//	contentAnchorNode:
+		// contentAnchorNode:
 		//		The DOM node to attach the content data to.
-		//	editMode:
+		// editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		//	entry:
+		// entry:
 		//		The Feed Entry to work with.
 		if(entry.content && entry.content.value && entry.content.value !== null){
 			var contentViewNode = document.createElement("span");
@@ -499,12 +477,9 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 
 
 	_displaySections: function(){
-		//	summary:
-		//		Internal function for determining which sections of the view to actually display.
-		//	description:
+		// summary:
 		//		Internal function for determining which sections of the view to actually display.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		domStyle.set(this.entryTitleRow, 'display', 'none');
 		domStyle.set(this.entryAuthorRow, 'display', 'none');
@@ -542,15 +517,11 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 
 	setDisplaySections: function(/*array*/sectionsArray){
-		//	summary:
+		// summary:
 		//		Function for setting which sections of the entry should be displayed.
-		//	description:
-		//		Function for setting which sections of the entry should be displayed.
-		//
-		//	sectionsArray:
+		// sectionsArray:
 		//		Array of string names that indicate which sections to display.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		if(sectionsArray !== null){
 			this._displayEntrySections = sectionsArray;
@@ -561,12 +532,9 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 
 	_setDisplaySectionsCheckboxes: function(){
-		//	summary:
-		//		Internal function for setting which checkboxes on the display are selected.
-		//	description:
+		// summary:
 		//		Internal function for setting which checkboxes on the display are selected.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		var items = ["title","authors","contributors","summary","content","id","updated"];
 		for(var i in items){
@@ -579,13 +547,8 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 
 	_readDisplaySections: function(){
-		//	summary:
+		// summary:
 		//		Internal function for reading what is currently checked for display and generating the display list from it.
-		//	description:
-		//		Internal function for reading what is currently checked for display and generating the display list from it.
-		//
-		//	returns:
-		//		Nothing.
 		var checkedList = [];
 
 		if(this.feedEntryCheckBoxTitle.checked){
@@ -613,17 +576,13 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 
 	_toggleCheckbox: function(/*object*/checkBox){
-		//	summary:
+		// summary:
 		//		Internal function for determining of a particular entry is editable.
-		//	description:
+		// description:
 		//		Internal function for determining of a particular entry is editable.
 		//		This is used for determining if the delete action should be displayed or not.
-		//
-		//	checkBox:
+		// checkBox:
 		//		The checkbox object to toggle the selection on.
-		//
-		//	returns:
-		//		Nothing
 		if(checkBox.checked){
 			checkBox.checked=false;
 		}else{
@@ -634,17 +593,13 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 
 	_toggleOptions: function(/*object*/checkBox){
-		//	summary:
+		// summary:
 		//		Internal function for determining of a particular entry is editable.
-		//	description:
+		// description:
 		//		Internal function for determining of a particular entry is editable.
 		//		This is used for determining if the delete action should be displayed or not.
-		//
-		//	checkBox:
+		// checkBox:
 		//		The checkbox object to toggle the selection on.
-		//
-		//	returns:
-		//		Nothing
 		if(this.enableMenu){
 			var fade = null;
 			var anim;
@@ -689,15 +644,11 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 
 	_handleEvent: function(/*object*/entrySelectionEvent){
-		//	summary:
+		// summary:
 		//		Internal function for listening to a topic that will handle entry notification.
-		//	description:
-		//		Internal function for listening to a topic that will handle entry notification.
-		//
-		//	entrySelectionEvent:
+		// entrySelectionEvent:
 		//		The topic message containing the entry that was selected for view.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		if(entrySelectionEvent.source != this){
 			if(entrySelectionEvent.action == "set" && entrySelectionEvent.entry){
@@ -709,19 +660,17 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 
 	setFieldValidity: function(/*string*/field, /*boolean*/isValid){
-		//	summary:
+		// summary:
 		//		Function to set whether a field in the view is valid and displayable.
-		//	description:
+		// description:
 		//		Function to set whether a field in the view is valid and displayable.
 		//		This is needed for over-riding of the set* functions and customization of how data is displayed in the attach point.
 		//		So if custom implementations use their own display logic, they can still enable the field.
-		//
-		//	field:
+		// field:
 		//		The field name to set the valid parameter on.  Such as 'content', 'id', etc.
-		//	isValid:
+		// isValid:
 		//		Flag denoting if the field is valid or not.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		if(field){
 			var lowerField = field.toLowerCase();
@@ -730,15 +679,11 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	},
 	
 	isFieldValid: function(/*string*/field){
-		//	summary:
-		//		Function to return if a displayable field is valid or not
-		//	description:
+		// summary:
 		//		Function to return if a displayable field is valid or not
-		//
-		//	field:
+		// field:
 		//		The field name to get the valid parameter of.  Such as 'content', 'id', etc.
-		//
-		//	returns:
+		// returns:
 		//		boolean denoting if the field is valid and set.
 		return this._validEntryFields[field.toLowerCase()];
 	},
@@ -757,10 +702,8 @@ widget.FeedEntryViewer = dojo.declare(/*===== "dojox.atom.widget.FeedEntryViewer
 	}
 });
 
-widget.EntryHeader = dojo.declare(/*===== "dojox.atom.widget.EntryHeader", =====*/ [_Widget, _Templated, _Container],{
-	//	summary:
-	//		Widget representing a header in a FeedEntryViewer/Editor
-	//	description:
+var EntryHeader = FeedEntryViewer.EntryHeader = declare("dojox.atom.widget.EntryHeader", [_Widget, _Templated, _Container],{
+	// summary:
 	//		Widget representing a header in a FeedEntryViewer/Editor
 	title: "",
 	templateString: headerTemplate,
@@ -792,5 +735,6 @@ widget.EntryHeader = dojo.declare(/*===== "dojox.atom.widget.EntryHeader", =====
 	}
 });
 
-return widget.FeedEntryViewer;
+
+return FeedEntryViewer;
 });
diff --git a/dojox/atom/widget/FeedViewer.js b/dojox/atom/widget/FeedViewer.js
index c591360..6a345ed 100644
--- a/dojox/atom/widget/FeedViewer.js
+++ b/dojox/atom/widget/FeedViewer.js
@@ -3,6 +3,7 @@ define([
 	"dojo/_base/lang",
 	"dojo/_base/array",
 	"dojo/_base/connect",
+	"dojo/_base/declare",
 	"dojo/dom-class",
 	"dijit/_Widget",
 	"dijit/_Templated",
@@ -11,18 +12,14 @@ define([
 	"dojo/text!./templates/FeedViewer.html",
 	"dojo/text!./templates/FeedViewerEntry.html",
 	"dojo/text!./templates/FeedViewerGrouping.html",
-	"dojo/i18n!./nls/FeedViewerEntry",
-	"dojo/_base/declare"
-], function (dojo, lang, arrayUtil, connect, domClass, _Widget, _Templated, _Container, Connection, template, entryTemplate, groupingTemplate, i18nViewer) {
+	"dojo/i18n!./nls/FeedViewerEntry"
+], function (dojo, lang, arrayUtil, connect, declare, domClass, _Widget, _Templated, _Container, Connection, template, entryTemplate, groupingTemplate, i18nViewer) {
 dojo.experimental("dojox.atom.widget.FeedViewer");
 
-var widget = dojo.getObject("dojox.atom.widget", true);
-
-widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/ [_Widget, _Templated, _Container],{
-	//	summary:
-	//		An ATOM feed viewer that allows for viewing a feed, deleting entries, and editing entries.
-	//	description:
+var FeedViewer = declare("dojox.atom.widget.FeedViewer", [_Widget, _Templated, _Container],{
+	// summary:
 	//		An ATOM feed viewer that allows for viewing a feed, deleting entries, and editing entries.
+
 	feedViewerTableBody: null,	//The body of the feed viewer table so we can access it and populate it.  Will be assigned via template.
 	feedViewerTable: null,		//The overal table container which contains the feed viewer table.  Will be assigned via template.
 	entrySelectionTopic: "",	//The topic to broadcast when any entry is clicked so that a listener can pick up it and display it.
@@ -41,9 +38,9 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	alertsEnabled: false,
 
 	postCreate: function(){
-		//	summary:
+		// summary:
 		//		The postCreate function.
-		//	description:
+		// description:
 		//		The postCreate function.  Creates our AtomIO object for future interactions and subscribes to the
 		//		event given in markup/creation.
 		this._includeFilters = [];
@@ -56,16 +53,16 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 	
 	startup: function(){
-		//	summary:
+		// summary:
 		//		The startup function.
-		//	description:
+		// description:
 		//		The startup function.  Parses the filters and sets the feed based on the given url.
 		this.containerNode = this.feedViewerTableBody;
 		var children = this.getDescendants();
 		for(var i in children){
 			var child = children[i];
 			if(child && child.isFilter){
-				this._includeFilters.push(new widget.FeedViewer.CategoryIncludeFilter(child.scheme, child.term, child.label));
+				this._includeFilters.push(new FeedViewer.CategoryIncludeFilter(child.scheme, child.term, child.label));
 				child.destroy();
 			}
 		}
@@ -76,26 +73,19 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	clear: function(){
-		//	summary:
+		// summary:
 		//		Function clearing all current entries in the feed view.
-		//	description:
-		//		Function clearing all current entries in the feed view.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		this.destroyDescendants();
 	},
 
 	setFeedFromUrl: function(/*string*/url){
-		//	summary:
+		// summary:
 		//		Function setting the feed from a URL which to get the feed.
-		//	description:
-		//		Function setting the dojox.atom.io.model.Feed data into the view.
-		//
-		//	url:
+		// url:
 		//		The URL to the feed to load.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		if(url !== ""){
 			if(this._isRelativeURL(url)){
@@ -114,15 +104,11 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 
 
 	setFeed: function(/*object*/feed){
-		//	summary:
+		// summary:
 		//		Function setting the dojox.atom.io.model.Feed data into the view.
-		//	description:
-		//		Function setting the dojox.atom.io.model.Feed data into the view.
-		//
-		//	entry:
+		// entry:
 		//		The dojox.atom.io.model.Feed object to process
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		this._feed = feed;
 		this.clear();
@@ -171,14 +157,11 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	_displayDateForEntry: function(/*object*/entry){
-		//	summary:
+		// summary:
 		//		Internal function for determining the appropriate date to display.
-		//		description: Internal function for determining of a particular entry is editable.
-		//
-		//	entry:
+		// entry:
 		//		The dojox.atom.io.model.Entry object to examine.
-		//
-		//	returns:
+		// returns:
 		//		An appropriate date for the feed viewer display.
 		if(entry.updated){return entry.updated;}
 		if(entry.modified){return entry.modified;}
@@ -187,34 +170,26 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	appendGrouping: function(/*string*/titleText){
-		//	summary:
+		// summary:
 		//		Function for appending a new grouping of entries to the feed view.
-		//	description:
-		//		Function for appending a grouping of entries to the feed view.
-		//
-		//	entry:
+		// entry:
 		//		The title of the new grouping to create on the view.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
-		var entryWidget = new widget.FeedViewerGrouping({});
+		var entryWidget = new FeedViewerGrouping({});
 		entryWidget.setText(titleText);
 		this.addChild(entryWidget);
 		this.childWidgets.push(entryWidget);
 	},
 
 	appendEntry: function(/*object*/entry){
-		//	summary:
-		//		Function for appending an entry to the feed view.
-		//	description:
+		// summary:
 		//		Function for appending an entry to the feed view.
-		//
-		//	entry:
+		// entry:
 		//		The dojox.atom.io.model.Entry object to append
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
-		var entryWidget = new widget.FeedViewerEntry({"xmethod": this.xmethod});
+		var entryWidget = new FeedViewerEntry({"xmethod": this.xmethod});
 		entryWidget.setTitle(entry.title.value);
 		entryWidget.setTime(this._displayDateForEntry(entry).toLocaleTimeString());
 		entryWidget.entrySelectionTopic = this.entrySelectionTopic;
@@ -230,9 +205,7 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 	
 	deleteEntry: function(/*object*/entryRow){
-		//	summary:
-		//		Function for deleting a row from the view
-		//	description:
+		// summary:
 		//		Function for deleting a row from the view
 		if(!this.localSaveOnly){
 			this.atomIO.deleteEntry(entryRow.entry, lang.hitch(this, this._removeEntry, entryRow), null, this.xmethod);
@@ -243,9 +216,7 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	_removeEntry: function(/*FeedViewerEntry*/ entry, /* boolean */success){
-		//	summary:
-		//		callback for when an entry is deleted from a feed.
-		//	description:
+		// summary:
 		//		callback for when an entry is deleted from a feed.
 		if(success){
 			/* Check if this is the last Entry beneath the given date */
@@ -263,15 +234,11 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 	
 	_rowSelected: function(/*object*/evt){
-		//	summary:
+		// summary:
 		//		Internal function for handling the selection of feed entries.
-		//	description:
-		//		Internal function for handling the selection of feed entries.
-		//
-		//	evt:
+		// evt:
 		//		The click event that triggered a selection.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		var selectedNode = evt.target;
 		while(selectedNode){
@@ -310,12 +277,9 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	_deselectCurrentSelection: function(){
-		//	summary:
-		//		Internal function for unselecting the current selection.
-		//	description:
+		// summary:
 		//		Internal function for unselecting the current selection.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		if(this._currentSelection){
 			domClass.add(this._currentSelection._entryWidget.timeNode, "feedViewerEntryUpdated");
@@ -328,16 +292,14 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 
 
 	_isEditable: function(/*object*/entry){
-		//	summary:
+		// summary:
 		//		Internal function for determining of a particular entry is editable.
-		//	description:
+		// description:
 		//		Internal function for determining of a particular entry is editable.
 		//		This is used for determining if the delete action should be displayed or not.
-		//
-		//	entry:
+		// entry:
 		//		The dojox.atom.io.model.Entry object to examine
-		//
-		//	returns:
+		// returns:
 		//		Boolean denoting if the entry seems editable or not..
 		var retVal = false;
 		if(entry && entry !== null && entry.links && entry.links !== null){
@@ -352,30 +314,24 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	onEntrySelected: function(/*object*/entry){
-		//	summary:
+		// summary:
 		//		Function intended for over-riding/replacement as an attachpoint to for other items to recieve
 		//		selection notification.
-		//	description: Function intended for over0-riding/replacement as an attachpoint to for other items to recieve
-		//		selection notification.
-		//
-		//	entry:
+		// entry:
 		//		The dojox.atom.io.model.Entry object selected.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 	},
 
 	_isRelativeURL: function(/*string*/url){
-		//	summary:
+		// summary:
 		//		Method to determine if the URL is relative or absolute.
-		//	description:
+		// description:
 		//		Method to determine if the URL is relative or absolute.  Basic assumption is if it doesn't start
 		//		with http:// or file://, it's relative to the current document.
-		//
-		//	url:
+		// url:
 		//		The URL to inspect.
-		//
-		//	returns:
+		// returns:
 		//		boolean indicating whether it's a relative url or not.
 		var isFileURL = function(url){
 			var retVal = false;
@@ -383,7 +339,7 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 				retVal = true;
 			}
 			return retVal;
-		}
+		};
 
 		var isHttpURL = function(url){
 			var retVal = false;
@@ -391,7 +347,7 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 				retVal = true;
 			}
 			return retVal;
-		}
+		};
 
 		var retVal = false;
 		if(url !== null){
@@ -403,17 +359,13 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	_calculateBaseURL: function(/*string*/fullURL, /*boolean*/currentPageRelative){
-		//	summary:
+		// summary:
 		//		Internal function to calculate a baseline URL from the provided full URL.
-		//	description:
-		//		Internal function to calculate a baseline URL from the provided full URL.
-		//
-		//	fullURL:
+		// fullURL:
 		//		The full URL as a string.
-		//	currentPageRelative:
+		// currentPageRelative:
 		//		Flag to denote of the base URL should be calculated as just the server base, or relative to the current page/location in the URL.
-		//
-		//	returns:
+		// returns:
 		//		String of the baseline URL
 		var baseURL = null;
 		if(fullURL !== null){
@@ -455,12 +407,9 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	_isFilterAccepted: function(/*object*/entry) {
-		//	summary:
-		//		Internal function to do matching of category filters to widgets.
-		//	description:
+		// summary:
 		//		Internal function to do matching of category filters to widgets.
-		//
-		//	returns:
+		// returns:
 		//		boolean denoting if this entry matched one of the accept filters.
 		var accepted = false;
 		if (this._includeFilters && (this._includeFilters.length > 0)) {
@@ -479,16 +428,12 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	addCategoryIncludeFilter: function(/*object*/filter) {
-		//	summary:
+		// summary:
 		//		Function to add a filter for entry inclusion in the feed view.
-		//	description:
-		//		Function to add a filter for entry inclusion in the feed view.
-		//
-		//	filter:
+		// filter:
 		//		The basic items to filter on and the values.
-		//		Should be of format: {scheme: <some text or null>, term: <some text or null>, label: <some text or null>}
-		//
-		//	returns:
+		//		Should be of format: {scheme: ``some text or null``, term: ``some text or null``, label: ``some text or null``}
+		// returns:
 		//		Nothing.
 		if (filter) {
 			var scheme = filter.scheme;
@@ -524,16 +469,12 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	removeCategoryIncludeFilter: function(/*object*/filter) {
-		//	summary:
-		//		Function to remove a filter for entry inclusion in the feed view.
-		//	description:
+		// summary:
 		//		Function to remove a filter for entry inclusion in the feed view.
-		//
-		//	filter:
+		// filter:
 		//		The basic items to identify the filter that is present.
-		//		Should be of format: {scheme: <some text or null>, term: <some text or null>, label: <some text or null>}
-		//
-		//	returns:
+		//		Should be of format: {scheme: ``some text or null``, term: ``some text or null``, label: ``some text or null``}
+		// returns:
 		//		Nothing.
 		if (filter) {
 			var scheme = filter.scheme;
@@ -565,15 +506,11 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	_handleEvent: function(/*object*/entrySelectionEvent) {
-		//	summary:
-		//		Internal function for listening to a topic that will handle entry notification.
-		//	description:
+		// summary:
 		//		Internal function for listening to a topic that will handle entry notification.
-		//
-		//	entrySelectionEvent:
+		// entrySelectionEvent:
 		//		The topic message containing the entry that was selected for view.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		if(entrySelectionEvent.source != this) {
 			if(entrySelectionEvent.action == "update" && entrySelectionEvent.entry) {
@@ -594,9 +531,9 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 	
 	_addEntry: function(/*object*/entry) {
-		//	summary:
+		// summary:
 		//		callback function used when adding an entry to the feed.
-		//	description:
+		// description:
 		//		callback function used when adding an entry to the feed.  After the entry has been posted to the feed,
 		//		we add it to our feed representation (to show it on the page) and publish an event to update any entry viewers.
 		this._feed.addEntry(entry);
@@ -605,19 +542,16 @@ widget.FeedViewer = dojo.declare(/*===== "dojox.atom.widget.FeedViewer", =====*/
 	},
 
 	destroy: function(){
-		//	summary:
-		//		Destroys this widget, including all descendants and subscriptions.
-		//	description:
+		// summary:
 		//		Destroys this widget, including all descendants and subscriptions.
 		this.clear();
 		arrayUtil.forEach(this._subscriptions, dojo.unsubscribe);
 	}
 });
 
-widget.FeedViewerEntry = dojo.declare(/*===== "dojox.atom.widget.FeedViewerEntry", =====*/ [_Widget, _Templated],{
-	//	summary:
+var FeedViewerEntry = FeedViewer.FeedViewerEntry = declare("dojox.atom.widget.FeedViewerEntry", [_Widget, _Templated],{
+	// summary:
 	//		Widget for handling the display of an entry and specific events associated with it.
-	//		description: Widget for handling the display of an entry and specific events associated with it.
 
 	templateString: entryTemplate,
 
@@ -633,15 +567,11 @@ widget.FeedViewerEntry = dojo.declare(/*===== "dojox.atom.widget.FeedViewerEntry
 	},
 
 	setTitle: function(/*string*/text){
-		//	summary:
-		//		Function to set the title of the entry.
-		//	description:
+		// summary:
 		//		Function to set the title of the entry.
-		//
-		//	text:
+		// text:
 		//		The title.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		if (this.titleNode.lastChild){this.titleNode.removeChild(this.titleNode.lastChild);}
 		
@@ -651,15 +581,11 @@ widget.FeedViewerEntry = dojo.declare(/*===== "dojox.atom.widget.FeedViewerEntry
 	},
 
 	setTime: function(/*string*/timeText){
-		//	summary:
+		// summary:
 		//		Function to set the time of the entry.
-		//	description:
-		//		Function to set the time of the entry.
-		//
-		//	timeText:
+		// timeText:
 		//		The string form of the date.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		if (this.timeNode.lastChild){this.timeNode.removeChild(this.timeNode.lastChild);}
 		var timeTextNode = document.createTextNode(timeText);
@@ -667,12 +593,9 @@ widget.FeedViewerEntry = dojo.declare(/*===== "dojox.atom.widget.FeedViewerEntry
 	},
 
 	enableDelete: function(){
-		//	summary:
-		//		Function to enable the delete action on this entry.
-		//	description:
+		// summary:
 		//		Function to enable the delete action on this entry.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		if (this.deleteButton !== null) {
 			//TODO Fix this
@@ -681,12 +604,9 @@ widget.FeedViewerEntry = dojo.declare(/*===== "dojox.atom.widget.FeedViewerEntry
 	},
 
 	disableDelete: function(){
-		//	summary:
+		// summary:
 		//		Function to disable the delete action on this entry.
-		//	description:
-		//		Function to disable the delete action on this entry.
-		//
-		// 	returns:
+		// returns:
 		//		Nothing.
 		if (this.deleteButton !== null) {
 			this.deleteButton.style.display = 'none';
@@ -694,12 +614,9 @@ widget.FeedViewerEntry = dojo.declare(/*===== "dojox.atom.widget.FeedViewerEntry
 	},
 
 	deleteEntry: function(/*object*/event) {
-		//	summary:
-		//		Function to handle the delete event and delete the entry.
-		// 	description:
+		// summary:
 		//		Function to handle the delete event and delete the entry.
-		//
-		//	returns:
+		// returns:
 		//		Nothing.
 		event.preventDefault();
 		event.stopPropagation();
@@ -707,33 +624,26 @@ widget.FeedViewerEntry = dojo.declare(/*===== "dojox.atom.widget.FeedViewerEntry
 	},
 
 	onClick: function(/*object*/e){
-		//	summary:
+		// summary:
 		//		Attach point for when a row is clicked on.
-		// 	description:
-		//		Attach point for when a row is clicked on.
-		//
-		// 	e:
+		// e:
 		//		The event generated by the click.
 	}
 });
 
-widget.FeedViewerGrouping = dojo.declare(/*===== "dojox.atom.widget.FeedViewerGrouping", =====*/ [_Widget, _Templated],{
-	//	summary:
-	//		Grouping of feed entries.
-	//	description:
+var FeedViewerGrouping = FeedViewer.FeedViewerGrouping = declare("dojox.atom.widget.FeedViewerGrouping", [_Widget, _Templated],{
+	// summary:
 	//		Grouping of feed entries.
+
 	templateString: groupingTemplate,
 	
 	groupingNode: null,
 	titleNode: null,
 
 	setText: function(text){
-		//	summary:
-		//		Sets the text to be shown above this grouping.
-		//	description:
+		// summary:
 		//		Sets the text to be shown above this grouping.
-		//
-		//	text:
+		// text:
 		//		The text to show.
 		if (this.titleNode.lastChild){this.titleNode.removeChild(this.titleNode.lastChild);}
 		var textNode = document.createTextNode(text);
@@ -741,10 +651,8 @@ widget.FeedViewerGrouping = dojo.declare(/*===== "dojox.atom.widget.FeedViewerGr
 	}
 });
 
-widget.AtomEntryCategoryFilter = dojo.declare(/*===== "dojox.atom.widget.AtomEntryCategoryFilter", =====*/ [_Widget, _Templated],{
-	//	summary:
-	//		A filter to be applied to the list of entries.
-	//	description:
+FeedViewer.AtomEntryCategoryFilter = declare("dojox.atom.widget.AtomEntryCategoryFilter",  null,{
+	// summary:
 	//		A filter to be applied to the list of entries.
 	scheme: "",
 	term: "",
@@ -752,11 +660,9 @@ widget.AtomEntryCategoryFilter = dojo.declare(/*===== "dojox.atom.widget.AtomEnt
 	isFilter: true
 });
 
-widget.FeedViewer.CategoryIncludeFilter = dojo.declare(/*===== "dojox.atom.widget.FeedViewer.CategoryIncludeFilter", =====*/ null,{
+FeedViewer.CategoryIncludeFilter = declare("dojox.atom.widget.FeedViewer.CategoryIncludeFilter", null,{
 	constructor: function(scheme, term, label){
-		//	summary:
-		//		The initializer function.
-		//	description:
+		// summary:
 		//		The initializer function.
 		this.scheme = scheme;
 		this.term = term;
@@ -764,12 +670,9 @@ widget.FeedViewer.CategoryIncludeFilter = dojo.declare(/*===== "dojox.atom.widge
 	},
 
 	match: function(entry) {
-		//	summary:
+		// summary:
 		//		Function to determine if this category filter matches against a category on an atom entry
-		//	description:
-		//		Function to determine if this category filter matches against a category on an atom entry
-		//
-		//	returns:
+		// returns:
 		//		boolean denoting if this category filter matched to this entry.
 		var matched = false;
 		if (entry !== null) {
@@ -803,5 +706,6 @@ widget.FeedViewer.CategoryIncludeFilter = dojo.declare(/*===== "dojox.atom.widge
 		return matched;
 	}
 });
-return widget.FeedViewer;
+
+return FeedViewer;
 });
\ No newline at end of file
diff --git a/dojox/atom/widget/nls/FeedEntryEditor.js b/dojox/atom/widget/nls/FeedEntryEditor.js
index b4140c3..60e570c 100644
--- a/dojox/atom/widget/nls/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/FeedEntryEditor.js
@@ -10,6 +10,7 @@ define({ root:
 ,
 "ar": true,
 "az": true,
+"bg": true,
 "ca": true,
 "cs": true,
 "da": true,
@@ -37,6 +38,7 @@ define({ root:
 "sv": true,
 "th": true,
 "tr": true,
+"uk": true,
 "zh": true,
 "zh-tw": true
-})
+});
diff --git a/dojox/atom/widget/nls/FeedEntryViewer.js b/dojox/atom/widget/nls/FeedEntryViewer.js
index 0b05018..2133ec6 100644
--- a/dojox/atom/widget/nls/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/FeedEntryViewer.js
@@ -15,6 +15,7 @@ define({ root:
 ,
 "ar": true,
 "az": true,
+"bg": true,
 "ca": true,
 "cs": true,
 "da": true,
@@ -42,6 +43,7 @@ define({ root:
 "sv": true,
 "th": true,
 "tr": true,
+"uk": true,
 "zh": true,
 "zh-tw": true
 });
diff --git a/dojox/atom/widget/nls/FeedViewerEntry.js b/dojox/atom/widget/nls/FeedViewerEntry.js
index f4817b6..5c08605 100644
--- a/dojox/atom/widget/nls/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/FeedViewerEntry.js
@@ -7,6 +7,7 @@ define({ root:
 ,
 "ar": true,
 "az": true,
+"bg": true,
 "ca": true,
 "cs": true,
 "da": true,
@@ -34,6 +35,7 @@ define({ root:
 "sv": true,
 "th": true,
 "tr": true,
+"uk": true,
 "zh": true,
 "zh-tw": true
 });
diff --git a/dojox/atom/widget/nls/PeopleEditor.js b/dojox/atom/widget/nls/PeopleEditor.js
index b1072d4..a31e6c5 100644
--- a/dojox/atom/widget/nls/PeopleEditor.js
+++ b/dojox/atom/widget/nls/PeopleEditor.js
@@ -9,6 +9,7 @@ define({ root:
 ,
 "ar": true,
 "az": true,
+"bg": true,
 "ca": true,
 "cs": true,
 "da": true,
@@ -36,6 +37,7 @@ define({ root:
 "sv": true,
 "th": true,
 "tr": true,
+"uk": true,
 "zh": true,
 "zh-tw": true
 });
diff --git a/dojox/atom/widget/nls/ar/FeedEntryEditor.js b/dojox/atom/widget/nls/ar/FeedEntryEditor.js
index 794cfc3..74ce267 100644
--- a/dojox/atom/widget/nls/ar/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ar/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[جديد]",
 	edit: "[تحرير]",
 	save: "[حفظ]",
 	cancel: "[الغاء]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ar/FeedEntryViewer.js b/dojox/atom/widget/nls/ar/FeedEntryViewer.js
index b12f468..2c34b68 100644
--- a/dojox/atom/widget/nls/ar/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ar/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[اختيارات العرض]",
 	title: "العنوان",
@@ -11,5 +10,4 @@ define(
 	summary: "الملخص",
 	content: "المحتويات"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ar/FeedViewerEntry.js b/dojox/atom/widget/nls/ar/FeedViewerEntry.js
index 1b4beb3..e481616 100644
--- a/dojox/atom/widget/nls/ar/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ar/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[حذف]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ar/PeopleEditor.js b/dojox/atom/widget/nls/ar/PeopleEditor.js
index cc9eed1..9af7f63 100644
--- a/dojox/atom/widget/nls/ar/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ar/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "اضافة",
 	addAuthor: "اضافة مؤلف",
 	addContributor: "اضافة مشارك"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/az/FeedEntryEditor.js b/dojox/atom/widget/nls/az/FeedEntryEditor.js
index 94453d4..3c43685 100644
--- a/dojox/atom/widget/nls/az/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/az/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"edit" : "[tərtib et]",
 	"save" : "[saxla]",
 	"cancel" : "[ləğv et]",
 	"doNew" : "[yeni]"
 })
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/atom/widget/nls/az/FeedEntryViewer.js b/dojox/atom/widget/nls/az/FeedEntryViewer.js
index 3d94dc4..cb71d5a 100644
--- a/dojox/atom/widget/nls/az/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/az/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"close" : "[çıx]",
 	"title" : "Başlıq",
@@ -11,5 +10,4 @@ define(
 	"displayOptions" : "[göstərmə seçimləri]",
 	"id" : "Şəxsiyyət"
 })
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/atom/widget/nls/az/FeedViewerEntry.js b/dojox/atom/widget/nls/az/FeedViewerEntry.js
index f92f842..60ce4ab 100644
--- a/dojox/atom/widget/nls/az/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/az/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"deleteButton" : "[Sil]"
 })
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/atom/widget/nls/az/PeopleEditor.js b/dojox/atom/widget/nls/az/PeopleEditor.js
index 470ea80..c25a93d 100644
--- a/dojox/atom/widget/nls/az/PeopleEditor.js
+++ b/dojox/atom/widget/nls/az/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	"add" : "Əlavə Et",
 	"addAuthor" : "Yazıçı Əlavə Et",
 	"addContributor" : "Əməyi keçənlərə Əlavə Et"
 })
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/atom/widget/nls/bg/FeedEntryEditor.js b/dojox/atom/widget/nls/bg/FeedEntryEditor.js
new file mode 100644
index 0000000..8cc0b98
--- /dev/null
+++ b/dojox/atom/widget/nls/bg/FeedEntryEditor.js
@@ -0,0 +1,8 @@
+define(
+({
+	doNew: "[нов]",
+	edit: "[редактирай]",
+	save: "[запази]",
+	cancel: "[отмени]"
+})
+);
diff --git a/dojox/atom/widget/nls/bg/FeedEntryViewer.js b/dojox/atom/widget/nls/bg/FeedEntryViewer.js
new file mode 100644
index 0000000..8def138
--- /dev/null
+++ b/dojox/atom/widget/nls/bg/FeedEntryViewer.js
@@ -0,0 +1,13 @@
+define(
+({
+	displayOptions: "[опция за показване]",
+	title: "Заглавие",
+	authors: "Автори",
+	contributors: "Сътрудници",
+	id: "Идентификатор",
+	close: "[затвори]",
+	updated: "Обновен",
+	summary: "Обобщение",
+	content: "Съдържание"
+})
+);
diff --git a/dojox/atom/widget/nls/bg/FeedViewerEntry.js b/dojox/atom/widget/nls/bg/FeedViewerEntry.js
new file mode 100644
index 0000000..63e87e4
--- /dev/null
+++ b/dojox/atom/widget/nls/bg/FeedViewerEntry.js
@@ -0,0 +1,5 @@
+define(
+({
+	deleteButton: "[Изтрий]"
+})
+);
diff --git a/dojox/atom/widget/nls/bg/PeopleEditor.js b/dojox/atom/widget/nls/bg/PeopleEditor.js
new file mode 100644
index 0000000..55a41e4
--- /dev/null
+++ b/dojox/atom/widget/nls/bg/PeopleEditor.js
@@ -0,0 +1,7 @@
+define(
+({
+	add: "Добави",
+	addAuthor: "Добави автор",
+	addContributor: "Добави сътрудник"
+})
+);
diff --git a/dojox/atom/widget/nls/ca/FeedEntryEditor.js b/dojox/atom/widget/nls/ca/FeedEntryEditor.js
index d4e2e5e..42cb5d9 100644
--- a/dojox/atom/widget/nls/ca/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ca/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[nou]",
 	edit: "[edita]",
 	save: "[desa]",
 	cancel: "[cancel·la]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ca/FeedEntryViewer.js b/dojox/atom/widget/nls/ca/FeedEntryViewer.js
index e8e069f..1d92db9 100644
--- a/dojox/atom/widget/nls/ca/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ca/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[mostra opcions]",
 	title: "Títol",
@@ -11,5 +10,4 @@ define(
 	summary: "Resum",
 	content: "Contingut"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ca/FeedViewerEntry.js b/dojox/atom/widget/nls/ca/FeedViewerEntry.js
index 09d0637..81ac61c 100644
--- a/dojox/atom/widget/nls/ca/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ca/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Suprimeix]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ca/PeopleEditor.js b/dojox/atom/widget/nls/ca/PeopleEditor.js
index 5812a77..6f09ba3 100644
--- a/dojox/atom/widget/nls/ca/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ca/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Afegeix",
 	addAuthor: "Afegeix un autor",
 	addContributor: "Afegeix un col·laborador"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/cs/FeedEntryEditor.js b/dojox/atom/widget/nls/cs/FeedEntryEditor.js
index 4cdca82..5222cc6 100644
--- a/dojox/atom/widget/nls/cs/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/cs/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[nové]",
 	edit: "[upravit]",
 	save: "[uložit]",
 	cancel: "[storno]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/cs/FeedEntryViewer.js b/dojox/atom/widget/nls/cs/FeedEntryViewer.js
index 3001df4..6808ad9 100644
--- a/dojox/atom/widget/nls/cs/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/cs/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[volby zobrazení]",
 	title: "Název",
@@ -11,5 +10,4 @@ define(
 	summary: "Souhrn",
 	content: "Obsah"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/cs/FeedViewerEntry.js b/dojox/atom/widget/nls/cs/FeedViewerEntry.js
index ef49dff..52f1f41 100644
--- a/dojox/atom/widget/nls/cs/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/cs/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Odstranit]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/cs/PeopleEditor.js b/dojox/atom/widget/nls/cs/PeopleEditor.js
index 902299d..83597c4 100644
--- a/dojox/atom/widget/nls/cs/PeopleEditor.js
+++ b/dojox/atom/widget/nls/cs/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Přidat",
 	addAuthor: "Přidat autora",
 	addContributor: "Přidat přispěvatele"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/da/FeedEntryEditor.js b/dojox/atom/widget/nls/da/FeedEntryEditor.js
index 2c384b1..f708943 100644
--- a/dojox/atom/widget/nls/da/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/da/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[ny]",
 	edit: "[redigér]",
 	save: "[gem]",
 	cancel: "[annullér]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/da/FeedEntryViewer.js b/dojox/atom/widget/nls/da/FeedEntryViewer.js
index e423bbe..a71cd1a 100644
--- a/dojox/atom/widget/nls/da/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/da/FeedEntryViewer.js
@@ -1,7 +1,6 @@
 define(
-//begin v1.x content
 ({
-	displayOptions: "[fremvisningsvalg]",
+	displayOptions: "[visningsindstillinger]",
 	title: "Titel",
 	authors: "Forfattere",
 	contributors: "Bidragydere",
@@ -11,5 +10,4 @@ define(
 	summary: "Resumé",
 	content: "Indhold"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/da/FeedViewerEntry.js b/dojox/atom/widget/nls/da/FeedViewerEntry.js
index 70f46db..1263dcf 100644
--- a/dojox/atom/widget/nls/da/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/da/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Slet]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/da/PeopleEditor.js b/dojox/atom/widget/nls/da/PeopleEditor.js
index a3be0e0..7700367 100644
--- a/dojox/atom/widget/nls/da/PeopleEditor.js
+++ b/dojox/atom/widget/nls/da/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Tilføj",
 	addAuthor: "Tilføj forfatter",
 	addContributor: "Tilføj bidragyder"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/de/FeedEntryEditor.js b/dojox/atom/widget/nls/de/FeedEntryEditor.js
index 5f99cd6..cb23027 100644
--- a/dojox/atom/widget/nls/de/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/de/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[Neu]",
 	edit: "[Bearbeiten]",
 	save: "[Speichern]",
 	cancel: "[Abbrechen]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/de/FeedEntryViewer.js b/dojox/atom/widget/nls/de/FeedEntryViewer.js
index 964ca9b..b30c9ba 100644
--- a/dojox/atom/widget/nls/de/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/de/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[Anzeigeoptionen]",
 	title: "Titel",
@@ -11,5 +10,4 @@ define(
 	summary: "Zusammenfassung",
 	content: "Inhalt"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/de/FeedViewerEntry.js b/dojox/atom/widget/nls/de/FeedViewerEntry.js
index 3d31af6..77090f0 100644
--- a/dojox/atom/widget/nls/de/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/de/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Löschen]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/de/PeopleEditor.js b/dojox/atom/widget/nls/de/PeopleEditor.js
index 0d8ae2c..c028bb8 100644
--- a/dojox/atom/widget/nls/de/PeopleEditor.js
+++ b/dojox/atom/widget/nls/de/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Hinzufügen",
 	addAuthor: "Autor hinzufügen",
 	addContributor: "Mitwirkenden hinzufügen"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/el/FeedEntryEditor.js b/dojox/atom/widget/nls/el/FeedEntryEditor.js
index dfbc26a..82b0c52 100644
--- a/dojox/atom/widget/nls/el/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/el/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[δημιουργία]",
 	edit: "[τροποποίηση]",
 	save: "[αποθήκευση]",
 	cancel: "[ακύρωση]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/el/FeedEntryViewer.js b/dojox/atom/widget/nls/el/FeedEntryViewer.js
index 9fe5927..c3fd1d8 100644
--- a/dojox/atom/widget/nls/el/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/el/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[επιλογές παρουσίασης]",
 	title: "Τίτλος",
@@ -11,5 +10,4 @@ define(
 	summary: "Περίληψη",
 	content: "Περιεχόμενο"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/el/FeedViewerEntry.js b/dojox/atom/widget/nls/el/FeedViewerEntry.js
index 26ff04a..590de67 100644
--- a/dojox/atom/widget/nls/el/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/el/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Διαγραφή]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/el/PeopleEditor.js b/dojox/atom/widget/nls/el/PeopleEditor.js
index f77bccd..6cf2c6e 100644
--- a/dojox/atom/widget/nls/el/PeopleEditor.js
+++ b/dojox/atom/widget/nls/el/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Προσθήκη",
 	addAuthor: "Προσθήκη συντάκτη",
 	addContributor: "Προσθήκη συνεισφέροντα"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/es/FeedEntryEditor.js b/dojox/atom/widget/nls/es/FeedEntryEditor.js
index 9875ea9..6568973 100644
--- a/dojox/atom/widget/nls/es/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/es/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[nuevo]",
 	edit: "[editar]",
 	save: "[guardar]",
 	cancel: "[cancelar]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/es/FeedEntryViewer.js b/dojox/atom/widget/nls/es/FeedEntryViewer.js
index 183d3c2..313640d 100644
--- a/dojox/atom/widget/nls/es/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/es/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[opciones de visualización]",
 	title: "Título",
@@ -11,5 +10,4 @@ define(
 	summary: "Resumen",
 	content: "Contenido"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/es/FeedViewerEntry.js b/dojox/atom/widget/nls/es/FeedViewerEntry.js
index 5a4bbab..8386473 100644
--- a/dojox/atom/widget/nls/es/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/es/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Suprimir]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/es/PeopleEditor.js b/dojox/atom/widget/nls/es/PeopleEditor.js
index e44cd21..4023b9a 100644
--- a/dojox/atom/widget/nls/es/PeopleEditor.js
+++ b/dojox/atom/widget/nls/es/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Añadir",
 	addAuthor: "Añadir autor",
 	addContributor: "Añadir colaborador"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/fi/FeedEntryEditor.js b/dojox/atom/widget/nls/fi/FeedEntryEditor.js
index ff67f18..7206f12 100644
--- a/dojox/atom/widget/nls/fi/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/fi/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[uusi]",
 	edit: "[muokkaa]",
 	save: "[tallenna]",
 	cancel: "[peruuta]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/fi/FeedEntryViewer.js b/dojox/atom/widget/nls/fi/FeedEntryViewer.js
index 5fe38a7..7fa3b68 100644
--- a/dojox/atom/widget/nls/fi/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/fi/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[näyttöasetukset]",
 	title: "Otsikko",
@@ -8,8 +7,7 @@ define(
 	id: "Tunnus",
 	close: "[sulje]",
 	updated: "Päivitetty",
-	summary: "Tiivistelmä",
+	summary: "Yhteenveto",
 	content: "Sisältö"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/fi/FeedViewerEntry.js b/dojox/atom/widget/nls/fi/FeedViewerEntry.js
index b105b9a..56b1ce0 100644
--- a/dojox/atom/widget/nls/fi/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/fi/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Poista]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/fi/PeopleEditor.js b/dojox/atom/widget/nls/fi/PeopleEditor.js
index 9788510..7fcea8f 100644
--- a/dojox/atom/widget/nls/fi/PeopleEditor.js
+++ b/dojox/atom/widget/nls/fi/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Lisää",
 	addAuthor: "Lisää tekijä",
 	addContributor: "Lisää lisääjä"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/fr/FeedEntryEditor.js b/dojox/atom/widget/nls/fr/FeedEntryEditor.js
index 75207e9..af64497 100644
--- a/dojox/atom/widget/nls/fr/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/fr/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[nouveau]",
 	edit: "[éditer]",
 	save: "[sauvegarder]",
 	cancel: "[annuler]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/fr/FeedEntryViewer.js b/dojox/atom/widget/nls/fr/FeedEntryViewer.js
index 6cfa5ba..7aa664c 100644
--- a/dojox/atom/widget/nls/fr/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/fr/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[options d'affichage]",
 	title: "Titre",
@@ -11,5 +10,4 @@ define(
 	summary: "Récapitulatif",
 	content: "Contenu"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/fr/FeedViewerEntry.js b/dojox/atom/widget/nls/fr/FeedViewerEntry.js
index e59ee80..247d67c 100644
--- a/dojox/atom/widget/nls/fr/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/fr/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Supprimer]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/fr/PeopleEditor.js b/dojox/atom/widget/nls/fr/PeopleEditor.js
index 467c093..9a81bb3 100644
--- a/dojox/atom/widget/nls/fr/PeopleEditor.js
+++ b/dojox/atom/widget/nls/fr/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Ajouter",
 	addAuthor: "Ajouter un auteur",
 	addContributor: "Ajouter un collaborateur"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/he/FeedEntryEditor.js b/dojox/atom/widget/nls/he/FeedEntryEditor.js
index ee70d5f..70da51d 100644
--- a/dojox/atom/widget/nls/he/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/he/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[חדש]",
 	edit: "[עריכה]",
 	save: "[שמירה]",
 	cancel: "[ביטול]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/he/FeedEntryViewer.js b/dojox/atom/widget/nls/he/FeedEntryViewer.js
index ebc1fef..b8d418a 100644
--- a/dojox/atom/widget/nls/he/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/he/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[אפשרויות הצגה]",
 	title: "כותרת",
@@ -11,5 +10,4 @@ define(
 	summary: "סיכום",
 	content: "תוכן"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/he/FeedViewerEntry.js b/dojox/atom/widget/nls/he/FeedViewerEntry.js
index f4a105c..d0a7fa5 100644
--- a/dojox/atom/widget/nls/he/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/he/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[מחיקה]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/he/PeopleEditor.js b/dojox/atom/widget/nls/he/PeopleEditor.js
index ed16c78..9c4a87a 100644
--- a/dojox/atom/widget/nls/he/PeopleEditor.js
+++ b/dojox/atom/widget/nls/he/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "הוספה",
 	addAuthor: "הוספת מחבר",
 	addContributor: "הוספת תורם"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/hu/FeedEntryEditor.js b/dojox/atom/widget/nls/hu/FeedEntryEditor.js
index 7f1df74..fa25f82 100644
--- a/dojox/atom/widget/nls/hu/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/hu/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[új]",
 	edit: "[szerkesztés]",
 	save: "[mentés]",
 	cancel: "[mégse]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/hu/FeedEntryViewer.js b/dojox/atom/widget/nls/hu/FeedEntryViewer.js
index 606763a..91931f3 100644
--- a/dojox/atom/widget/nls/hu/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/hu/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[megjelenítési beállítások]",
 	title: "Cím",
@@ -11,5 +10,4 @@ define(
 	summary: "Összegzés",
 	content: "Tartalom"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/hu/FeedViewerEntry.js b/dojox/atom/widget/nls/hu/FeedViewerEntry.js
index d33877c..bc4168f 100644
--- a/dojox/atom/widget/nls/hu/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/hu/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Törlés]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/hu/PeopleEditor.js b/dojox/atom/widget/nls/hu/PeopleEditor.js
index ed930e6..4ef4ccb 100644
--- a/dojox/atom/widget/nls/hu/PeopleEditor.js
+++ b/dojox/atom/widget/nls/hu/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Hozzáadás",
 	addAuthor: "Szerző hozzáadása",
 	addContributor: "Közreműködő hozzáadása"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/it/FeedEntryEditor.js b/dojox/atom/widget/nls/it/FeedEntryEditor.js
index eb86b7e..0006494 100644
--- a/dojox/atom/widget/nls/it/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/it/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[nuovo]",
 	edit: "[modifica]",
 	save: "[salva]",
 	cancel: "[annulla]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/it/FeedEntryViewer.js b/dojox/atom/widget/nls/it/FeedEntryViewer.js
index b336fa8..0511130 100644
--- a/dojox/atom/widget/nls/it/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/it/FeedEntryViewer.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[visualizza opzioni]",
 	title: "Titolo",
 	authors: "Autori",
-	contributors: "Collaboratori",
+	contributors: "Contributor",
 	id: "ID",
 	close: "[chiudi]",
 	updated: "Aggiornato",
 	summary: "Riepilogo",
-	content: "Indice"
+	content: "Contenuto"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/it/FeedViewerEntry.js b/dojox/atom/widget/nls/it/FeedViewerEntry.js
index 65838d0..8c5835c 100644
--- a/dojox/atom/widget/nls/it/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/it/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
-	deleteButton: "[Cancella]"
+	deleteButton: "[Elimina]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/it/PeopleEditor.js b/dojox/atom/widget/nls/it/PeopleEditor.js
index 82f0b58..ba795a1 100644
--- a/dojox/atom/widget/nls/it/PeopleEditor.js
+++ b/dojox/atom/widget/nls/it/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Aggiungi",
 	addAuthor: "Aggiungi autore",
-	addContributor: "Aggiungi collaboratori"
+	addContributor: "Aggiungi contributor"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ja/FeedEntryEditor.js b/dojox/atom/widget/nls/ja/FeedEntryEditor.js
index c416414..962581f 100644
--- a/dojox/atom/widget/nls/ja/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ja/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[新規]",
 	edit: "[編集]",
 	save: "[保存]",
 	cancel: "[キャンセル]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ja/FeedEntryViewer.js b/dojox/atom/widget/nls/ja/FeedEntryViewer.js
index 7529c46..07788f1 100644
--- a/dojox/atom/widget/nls/ja/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ja/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[表示オプション]",
 	title: "タイトル",
@@ -11,5 +10,4 @@ define(
 	summary: "要約",
 	content: "内容"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ja/FeedViewerEntry.js b/dojox/atom/widget/nls/ja/FeedViewerEntry.js
index eb1dcd5..1ee52ac 100644
--- a/dojox/atom/widget/nls/ja/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ja/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[削除]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ja/PeopleEditor.js b/dojox/atom/widget/nls/ja/PeopleEditor.js
index 6e9ed94..43a61bf 100644
--- a/dojox/atom/widget/nls/ja/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ja/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "追加",
 	addAuthor: "作成者の追加",
 	addContributor: "貢献者の追加"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/kk/FeedEntryEditor.js b/dojox/atom/widget/nls/kk/FeedEntryEditor.js
index e639c51..2aba51f 100644
--- a/dojox/atom/widget/nls/kk/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/kk/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[жаңа]",
 	edit: "[өңдеу]",
 	save: "[сақтау]",
 	cancel: "[болдырмау]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/kk/FeedEntryViewer.js b/dojox/atom/widget/nls/kk/FeedEntryViewer.js
index aba4117..7b2bf33 100644
--- a/dojox/atom/widget/nls/kk/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/kk/FeedEntryViewer.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[көрсету параметрлері]",
 	title: "Тақырып",
 	authors: "Авторлар",
-	contributors: "Таратушылар",
-	id: "ID коды",
+	contributors: "Салымшылар",
+	id: "Жалпылауыш",
 	close: "[жабу]",
 	updated: "Жаңартылған",
 	summary: "Жиынтық",
 	content: "Мазмұн"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/kk/FeedViewerEntry.js b/dojox/atom/widget/nls/kk/FeedViewerEntry.js
index 29e37cd..30d1259 100644
--- a/dojox/atom/widget/nls/kk/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/kk/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Жою]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/kk/PeopleEditor.js b/dojox/atom/widget/nls/kk/PeopleEditor.js
index e6a5d51..bef2863 100644
--- a/dojox/atom/widget/nls/kk/PeopleEditor.js
+++ b/dojox/atom/widget/nls/kk/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Қосу",
 	addAuthor: "Авторды қосу",
 	addContributor: "Салымшыны қосу"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ko/FeedEntryEditor.js b/dojox/atom/widget/nls/ko/FeedEntryEditor.js
index 96d7121..6bc4b0c 100644
--- a/dojox/atom/widget/nls/ko/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ko/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[새로 작성]",
 	edit: "[편집]",
 	save: "[저장]",
 	cancel: "[취소]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ko/FeedEntryViewer.js b/dojox/atom/widget/nls/ko/FeedEntryViewer.js
index c09eeec..cc5585e 100644
--- a/dojox/atom/widget/nls/ko/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ko/FeedEntryViewer.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[옵션 표시]",
 	title: "제목",
 	authors: "작성자",
-	contributors: "기고자",
+	contributors: "제공자",
 	id: "ID",
 	close: "[닫기]",
 	updated: "업데이트된 날짜",
 	summary: "요약",
 	content: "컨텐츠"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ko/FeedViewerEntry.js b/dojox/atom/widget/nls/ko/FeedViewerEntry.js
index 3ed9505..1027295 100644
--- a/dojox/atom/widget/nls/ko/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ko/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[삭제]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ko/PeopleEditor.js b/dojox/atom/widget/nls/ko/PeopleEditor.js
index 4d13a0b..2fe2443 100644
--- a/dojox/atom/widget/nls/ko/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ko/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "추가",
 	addAuthor: "작성자 추가",
 	addContributor: "제공자 추가"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/nb/FeedEntryEditor.js b/dojox/atom/widget/nls/nb/FeedEntryEditor.js
index 47276a8..f3bd1c5 100644
--- a/dojox/atom/widget/nls/nb/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/nb/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[ny(tt)]",
 	edit: "[rediger]",
 	save: "[lagre]",
 	cancel: "[avbryt]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/nb/FeedEntryViewer.js b/dojox/atom/widget/nls/nb/FeedEntryViewer.js
index b866294..3144f8d 100644
--- a/dojox/atom/widget/nls/nb/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/nb/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[visningsalternativer]",
 	title: "Tittel",
@@ -11,5 +10,4 @@ define(
 	summary: "Sammendrag",
 	content: "Innhold"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/nb/FeedViewerEntry.js b/dojox/atom/widget/nls/nb/FeedViewerEntry.js
index 012ba64..ce11a7c 100644
--- a/dojox/atom/widget/nls/nb/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/nb/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Slett]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/nb/PeopleEditor.js b/dojox/atom/widget/nls/nb/PeopleEditor.js
index 4557df9..6e76ec0 100644
--- a/dojox/atom/widget/nls/nb/PeopleEditor.js
+++ b/dojox/atom/widget/nls/nb/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Legg til",
 	addAuthor: "Legg til forfatter",
 	addContributor: "Legg til bidragsyter"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/nl/FeedEntryEditor.js b/dojox/atom/widget/nls/nl/FeedEntryEditor.js
index 3b2be53..d3790e9 100644
--- a/dojox/atom/widget/nls/nl/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/nl/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[nieuw]",
 	edit: "[bewerken]",
 	save: "[opslaan]",
 	cancel: "[annuleren]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/nl/FeedEntryViewer.js b/dojox/atom/widget/nls/nl/FeedEntryViewer.js
index 088876f..8c6743e 100644
--- a/dojox/atom/widget/nls/nl/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/nl/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[weergaveopties]",
 	title: "Titel",
@@ -11,5 +10,4 @@ define(
 	summary: "Overzicht",
 	content: "Content"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/nl/FeedViewerEntry.js b/dojox/atom/widget/nls/nl/FeedViewerEntry.js
index e44093c..a020fce 100644
--- a/dojox/atom/widget/nls/nl/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/nl/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Wissen]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/nl/PeopleEditor.js b/dojox/atom/widget/nls/nl/PeopleEditor.js
index 74324dc..6e709c8 100644
--- a/dojox/atom/widget/nls/nl/PeopleEditor.js
+++ b/dojox/atom/widget/nls/nl/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Toevoegen",
 	addAuthor: "Auteur toevoegen",
 	addContributor: "Deelnemer toevoegen"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pl/FeedEntryEditor.js b/dojox/atom/widget/nls/pl/FeedEntryEditor.js
index 4f0a243..9a1c342 100644
--- a/dojox/atom/widget/nls/pl/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/pl/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[nowy]",
 	edit: "[edytuj]",
 	save: "[zapisz]",
 	cancel: "[anuluj]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pl/FeedEntryViewer.js b/dojox/atom/widget/nls/pl/FeedEntryViewer.js
index 48799aa..98ac9ab 100644
--- a/dojox/atom/widget/nls/pl/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/pl/FeedEntryViewer.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[opcje wyświetlania]",
 	title: "Tytuł",
 	authors: "Autorzy",
 	contributors: "Kontrybutorzy",
-	id: "Identyfikator",
+	id: "ID",
 	close: "[zamknij]",
 	updated: "Zaktualizowano",
 	summary: "Podsumowanie",
 	content: "Treść"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pl/FeedViewerEntry.js b/dojox/atom/widget/nls/pl/FeedViewerEntry.js
index c95c641..8e8fc4e 100644
--- a/dojox/atom/widget/nls/pl/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/pl/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Usuń]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pl/PeopleEditor.js b/dojox/atom/widget/nls/pl/PeopleEditor.js
index 56ffe89..90b7816 100644
--- a/dojox/atom/widget/nls/pl/PeopleEditor.js
+++ b/dojox/atom/widget/nls/pl/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Dodaj",
 	addAuthor: "Dodaj autora",
 	addContributor: "Dodaj kontrybutora"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js b/dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js
index f134efc..cf9af7e 100644
--- a/dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/pt-pt/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[novo]",
 	edit: "[editar]",
 	save: "[guardar]",
 	cancel: "[cancelar]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js b/dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js
index 12732fd..4598aea 100644
--- a/dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/pt-pt/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[opções de visualização]",
 	title: "Título",
@@ -11,5 +10,4 @@ define(
 	summary: "Resumo",
 	content: "Conteúdo"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js b/dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js
index bff7222..a8f1747 100644
--- a/dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/pt-pt/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Eliminar]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pt-pt/PeopleEditor.js b/dojox/atom/widget/nls/pt-pt/PeopleEditor.js
index 601c753..123bf2f 100644
--- a/dojox/atom/widget/nls/pt-pt/PeopleEditor.js
+++ b/dojox/atom/widget/nls/pt-pt/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Adicionar",
 	addAuthor: "Adicionar autor",
 	addContributor: "Adicionar contribuinte"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pt/FeedEntryEditor.js b/dojox/atom/widget/nls/pt/FeedEntryEditor.js
index 26c3f10..174cec8 100644
--- a/dojox/atom/widget/nls/pt/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/pt/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[novo]",
 	edit: "[editar]",
 	save: "[salvar]",
 	cancel: "[cancelar]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pt/FeedEntryViewer.js b/dojox/atom/widget/nls/pt/FeedEntryViewer.js
index 4dc46e0..fde5aa7 100644
--- a/dojox/atom/widget/nls/pt/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/pt/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[exibir opções]",
 	title: "Título",
@@ -11,5 +10,4 @@ define(
 	summary: "Resumo",
 	content: "Conteúdo"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pt/FeedViewerEntry.js b/dojox/atom/widget/nls/pt/FeedViewerEntry.js
index 8bb50b6..99f0728 100644
--- a/dojox/atom/widget/nls/pt/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/pt/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Excluir]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/pt/PeopleEditor.js b/dojox/atom/widget/nls/pt/PeopleEditor.js
index b5e50e3..530fff4 100644
--- a/dojox/atom/widget/nls/pt/PeopleEditor.js
+++ b/dojox/atom/widget/nls/pt/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
-	add: "Adicionar",
+	add: "Incluir",
 	addAuthor: "Adicionar Autor",
 	addContributor: "Adicionar Contribuidor"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ro/FeedEntryEditor.js b/dojox/atom/widget/nls/ro/FeedEntryEditor.js
index a105010..c6a8be0 100644
--- a/dojox/atom/widget/nls/ro/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ro/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[nou]",
 	edit: "[editare]",
 	save: "[salvare]",
 	cancel: "[anulare]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ro/FeedEntryViewer.js b/dojox/atom/widget/nls/ro/FeedEntryViewer.js
index cf2973b..a1f86e9 100644
--- a/dojox/atom/widget/nls/ro/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ro/FeedEntryViewer.js
@@ -1,7 +1,6 @@
 define(
-//begin v1.x content
 ({
-	displayOptions: "[opţiuni afişare]",
+	displayOptions: "[opţiuni de afişare]",
 	title: "Titlu",
 	authors: "Autori",
 	contributors: "Contribuitori",
@@ -11,5 +10,4 @@ define(
 	summary: "Sumar",
 	content: "Conţinut"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ro/FeedViewerEntry.js b/dojox/atom/widget/nls/ro/FeedViewerEntry.js
index 5121ce8..501086f 100644
--- a/dojox/atom/widget/nls/ro/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ro/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Ştergere]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ro/PeopleEditor.js b/dojox/atom/widget/nls/ro/PeopleEditor.js
index 29a6dcf..406f1ba 100644
--- a/dojox/atom/widget/nls/ro/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ro/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Adăugare",
 	addAuthor: "Adăugare autor",
 	addContributor: "Adăugare contribuitor"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ru/FeedEntryEditor.js b/dojox/atom/widget/nls/ru/FeedEntryEditor.js
index 9e4df1e..0c4d148 100644
--- a/dojox/atom/widget/nls/ru/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/ru/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[создать]",
 	edit: "[изменить]",
 	save: "[сохранить]",
 	cancel: "[отмена]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ru/FeedEntryViewer.js b/dojox/atom/widget/nls/ru/FeedEntryViewer.js
index 32db5f1..5f474c4 100644
--- a/dojox/atom/widget/nls/ru/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ru/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[показать опции]",
 	title: "Название",
@@ -11,5 +10,4 @@ define(
 	summary: "Сводка",
 	content: "Информационное наполнение"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ru/FeedViewerEntry.js b/dojox/atom/widget/nls/ru/FeedViewerEntry.js
index 93347a1..65d5eb0 100644
--- a/dojox/atom/widget/nls/ru/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/ru/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Удалить]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/ru/PeopleEditor.js b/dojox/atom/widget/nls/ru/PeopleEditor.js
index 56e7b87..048cdfe 100644
--- a/dojox/atom/widget/nls/ru/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ru/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Добавить",
 	addAuthor: "Добавить автора",
 	addContributor: "Добавить участника"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sk/FeedEntryEditor.js b/dojox/atom/widget/nls/sk/FeedEntryEditor.js
index 1c5625e..76a5287 100644
--- a/dojox/atom/widget/nls/sk/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/sk/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[nový]",
 	edit: "[upraviť]",
 	save: "[uložiť]",
 	cancel: "[zrušiť]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sk/FeedEntryViewer.js b/dojox/atom/widget/nls/sk/FeedEntryViewer.js
index 9021643..1b2b1b5 100644
--- a/dojox/atom/widget/nls/sk/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/sk/FeedEntryViewer.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
-	displayOptions: "[zobraziť voľby]",
+	displayOptions: "[voľby zobrazenia]",
 	title: "Nadpis",
 	authors: "Autori",
 	contributors: "Prispievatelia",
 	id: "ID",
 	close: "[zatvoriť]",
-	updated: "Aktualizovaný",
-	summary: "Súhrn",
+	updated: "Aktualizované",
+	summary: "Zhrnutie",
 	content: "Obsah"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sk/FeedViewerEntry.js b/dojox/atom/widget/nls/sk/FeedViewerEntry.js
index 04f781b..8f37dd1 100644
--- a/dojox/atom/widget/nls/sk/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/sk/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
-	deleteButton: "[Vymazať]"
+	deleteButton: "[Odstrániť]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sk/PeopleEditor.js b/dojox/atom/widget/nls/sk/PeopleEditor.js
index a87e12d..e7609ed 100644
--- a/dojox/atom/widget/nls/sk/PeopleEditor.js
+++ b/dojox/atom/widget/nls/sk/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Pridať",
 	addAuthor: "Pridať autora",
 	addContributor: "Pridať prispievateľa"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sl/FeedEntryEditor.js b/dojox/atom/widget/nls/sl/FeedEntryEditor.js
index 600a46b..0d09a17 100644
--- a/dojox/atom/widget/nls/sl/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/sl/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[novo]",
 	edit: "[urejanje]",
 	save: "[shrani]",
 	cancel: "[prekliči]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sl/FeedEntryViewer.js b/dojox/atom/widget/nls/sl/FeedEntryViewer.js
index 7233447..adb9217 100644
--- a/dojox/atom/widget/nls/sl/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/sl/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[možnosti prikaza]",
 	title: "Naslov",
@@ -8,8 +7,7 @@ define(
 	id: "ID",
 	close: "[zapri]",
 	updated: "Posodobljeno",
-	summary: "Povzetek",
+	summary: "Seštevek",
 	content: "Vsebina"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sl/FeedViewerEntry.js b/dojox/atom/widget/nls/sl/FeedViewerEntry.js
index 57deaff..ae50ee3 100644
--- a/dojox/atom/widget/nls/sl/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/sl/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Izbriši]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sl/PeopleEditor.js b/dojox/atom/widget/nls/sl/PeopleEditor.js
index 398504d..fc7f7c1 100644
--- a/dojox/atom/widget/nls/sl/PeopleEditor.js
+++ b/dojox/atom/widget/nls/sl/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Dodaj",
 	addAuthor: "Dodaj avtorja",
 	addContributor: "Dodaj kontributorja"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sv/FeedEntryEditor.js b/dojox/atom/widget/nls/sv/FeedEntryEditor.js
index 1119de5..fbf07a3 100644
--- a/dojox/atom/widget/nls/sv/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/sv/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
-	doNew: "[Nytt]",
-	edit: "[Redigera]",
-	save: "[Spara]",
-	cancel: "[Avbryt]"
+	doNew: "[nytt]",
+	edit: "[redigera]",
+	save: "[spara]",
+	cancel: "[avbryt]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sv/FeedEntryViewer.js b/dojox/atom/widget/nls/sv/FeedEntryViewer.js
index d7bd22d..b3f139d 100644
--- a/dojox/atom/widget/nls/sv/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/sv/FeedEntryViewer.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
-	displayOptions: "[Visningsalternativ]",
-	title: "Rubrik",
+	displayOptions: "[visningsalternativ]",
+	title: "Namn",
 	authors: "Författare",
 	contributors: "Medverkande",
 	id: "ID",
-	close: "[Stäng]",
+	close: "[stäng]",
 	updated: "Uppdaterat",
-	summary: "Sammanfattning",
+	summary: "Översikt",
 	content: "Innehåll"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sv/FeedViewerEntry.js b/dojox/atom/widget/nls/sv/FeedViewerEntry.js
index 220dc3b..389c850 100644
--- a/dojox/atom/widget/nls/sv/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/sv/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Ta bort]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/sv/PeopleEditor.js b/dojox/atom/widget/nls/sv/PeopleEditor.js
index 79eee2b..0b267d9 100644
--- a/dojox/atom/widget/nls/sv/PeopleEditor.js
+++ b/dojox/atom/widget/nls/sv/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Lägg till",
 	addAuthor: "Lägg till författare",
 	addContributor: "Lägg till medverkande"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/th/FeedEntryEditor.js b/dojox/atom/widget/nls/th/FeedEntryEditor.js
index 2386f0e..7616a81 100644
--- a/dojox/atom/widget/nls/th/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/th/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
-	doNew: "[สร้าง]",
+	doNew: "[สร้างใหม่]",
 	edit: "[แก้ไข]",
 	save: "[บันทึก]",
 	cancel: "[ยกเลิก]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/th/FeedEntryViewer.js b/dojox/atom/widget/nls/th/FeedEntryViewer.js
index 7f6fa5e..fee27dd 100644
--- a/dojox/atom/widget/nls/th/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/th/FeedEntryViewer.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
-	displayOptions: "[อ็อพชันการแสดงผล]",
-	title: "ชื่อเรื่อง",
+	displayOptions: "[แสดงอ็อพชัน]",
+	title: "หัวเรื่อง",
 	authors: "ผู้เขียน",
-	contributors: "ผู้อนุเคราะห์",
+	contributors: "ผู้ร่วมให้ข้อมูล",
 	id: "ID",
 	close: "[ปิด]",
 	updated: "อัพเดต",
-	summary: "สรุป",
+	summary: "ยอดรวม",
 	content: "เนื้อหา"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/th/FeedViewerEntry.js b/dojox/atom/widget/nls/th/FeedViewerEntry.js
index 2e2ce0b..279b68e 100644
--- a/dojox/atom/widget/nls/th/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/th/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[ลบ]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/th/PeopleEditor.js b/dojox/atom/widget/nls/th/PeopleEditor.js
index 4acc14d..8616b17 100644
--- a/dojox/atom/widget/nls/th/PeopleEditor.js
+++ b/dojox/atom/widget/nls/th/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "เพิ่ม",
 	addAuthor: "เพิ่มผู้เขียน",
-	addContributor: "เพิ่มผู้อนุเคราะห์"
+	addContributor: "เพิ่มผู้ให้ข้อมูล"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/tr/FeedEntryEditor.js b/dojox/atom/widget/nls/tr/FeedEntryEditor.js
index afc61bb..bb9bbc1 100644
--- a/dojox/atom/widget/nls/tr/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/tr/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[yeni]",
 	edit: "[düzenle]",
 	save: "[kaydet]",
 	cancel: "[iptal]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/tr/FeedEntryViewer.js b/dojox/atom/widget/nls/tr/FeedEntryViewer.js
index bed8901..a37faea 100644
--- a/dojox/atom/widget/nls/tr/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/tr/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[görüntüleme seçenekleri]",
 	title: "Başlık",
@@ -11,5 +10,4 @@ define(
 	summary: "Özet",
 	content: "İçerik"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/tr/FeedViewerEntry.js b/dojox/atom/widget/nls/tr/FeedViewerEntry.js
index 7b6071c..ecc0fc7 100644
--- a/dojox/atom/widget/nls/tr/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/tr/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[Sil]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/tr/PeopleEditor.js b/dojox/atom/widget/nls/tr/PeopleEditor.js
index dd78561..6ef8a1e 100644
--- a/dojox/atom/widget/nls/tr/PeopleEditor.js
+++ b/dojox/atom/widget/nls/tr/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "Ekle",
 	addAuthor: "Yazar Ekle",
 	addContributor: "Katkıda Bulunan Ekle"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/uk/FeedEntryEditor.js b/dojox/atom/widget/nls/uk/FeedEntryEditor.js
new file mode 100644
index 0000000..8f9b007
--- /dev/null
+++ b/dojox/atom/widget/nls/uk/FeedEntryEditor.js
@@ -0,0 +1,8 @@
+define(
+({
+	doNew: "[створити]",
+	edit: "[змінити]",
+	save: "[зберегти]",
+	cancel: "[скасувати]"
+})
+);
diff --git a/dojox/atom/widget/nls/uk/FeedEntryViewer.js b/dojox/atom/widget/nls/uk/FeedEntryViewer.js
new file mode 100644
index 0000000..4ad725f
--- /dev/null
+++ b/dojox/atom/widget/nls/uk/FeedEntryViewer.js
@@ -0,0 +1,13 @@
+define(
+({
+	displayOptions: "[показати опції]",
+	title: "Заголовок",
+	authors: "Автори",
+	contributors: "Учасники",
+	id: "Ідентифікатор",
+	close: "[закрити]",
+	updated: "Оновлено",
+	summary: "Підсумкові дані",
+	content: "Вміст"
+})
+);
diff --git a/dojox/atom/widget/nls/uk/FeedViewerEntry.js b/dojox/atom/widget/nls/uk/FeedViewerEntry.js
new file mode 100644
index 0000000..73debaa
--- /dev/null
+++ b/dojox/atom/widget/nls/uk/FeedViewerEntry.js
@@ -0,0 +1,5 @@
+define(
+({
+	deleteButton: "[Видалити]"
+})
+);
diff --git a/dojox/atom/widget/nls/uk/PeopleEditor.js b/dojox/atom/widget/nls/uk/PeopleEditor.js
new file mode 100644
index 0000000..c87319c
--- /dev/null
+++ b/dojox/atom/widget/nls/uk/PeopleEditor.js
@@ -0,0 +1,7 @@
+define(
+({
+	add: "Додати",
+	addAuthor: "Додати автора",
+	addContributor: "Додати учасника"
+})
+);
diff --git a/dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js b/dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js
index b87c26c..8a35a9e 100644
--- a/dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/zh-tw/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[新建]",
 	edit: "[編輯]",
 	save: "[儲存]",
 	cancel: "[取消]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js b/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js
index e903d76..38bc66c 100644
--- a/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[顯示選項]",
 	title: "標題",
@@ -11,5 +10,4 @@ define(
 	summary: "摘要",
 	content: "內容"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js b/dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js
index c2336df..1b7b0b3 100644
--- a/dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/zh-tw/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[刪除]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/zh-tw/PeopleEditor.js b/dojox/atom/widget/nls/zh-tw/PeopleEditor.js
index 41ea811..d7f1e98 100644
--- a/dojox/atom/widget/nls/zh-tw/PeopleEditor.js
+++ b/dojox/atom/widget/nls/zh-tw/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "新增",
 	addAuthor: "新增作者",
 	addContributor: "新增貢獻者"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/zh/FeedEntryEditor.js b/dojox/atom/widget/nls/zh/FeedEntryEditor.js
index ac9f053..b564c76 100644
--- a/dojox/atom/widget/nls/zh/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/zh/FeedEntryEditor.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	doNew: "[新建]",
 	edit: "[编辑]",
 	save: "[保存]",
 	cancel: "[取消]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/zh/FeedEntryViewer.js b/dojox/atom/widget/nls/zh/FeedEntryViewer.js
index 7d59651..71df2cf 100644
--- a/dojox/atom/widget/nls/zh/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/zh/FeedEntryViewer.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
 	displayOptions: "[显示选项]",
 	title: "标题",
-	authors: "作者",
-	contributors: "内容添加者",
+	authors: "创建者",
+	contributors: "添加者",
 	id: "标识",
 	close: "[关闭]",
-	updated: "更新时间",
-	summary: "摘要",
+	updated: "已更新",
+	summary: "概要",
 	content: "内容"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/zh/FeedViewerEntry.js b/dojox/atom/widget/nls/zh/FeedViewerEntry.js
index 7ebd582..d266527 100644
--- a/dojox/atom/widget/nls/zh/FeedViewerEntry.js
+++ b/dojox/atom/widget/nls/zh/FeedViewerEntry.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	deleteButton: "[删除]"
 })
-//end v1.x content
 );
diff --git a/dojox/atom/widget/nls/zh/PeopleEditor.js b/dojox/atom/widget/nls/zh/PeopleEditor.js
index 7eb3533..76844ce 100644
--- a/dojox/atom/widget/nls/zh/PeopleEditor.js
+++ b/dojox/atom/widget/nls/zh/PeopleEditor.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	add: "添加",
 	addAuthor: "添加作者",
-	addContributor: "添加内容添加者"
+	addContributor: "添加添加者"
 })
-//end v1.x content
 );
diff --git a/dojox/calc/FuncGen.js b/dojox/calc/FuncGen.js
index 376fcfc..fb6ae5d 100644
--- a/dojox/calc/FuncGen.js
+++ b/dojox/calc/FuncGen.js
@@ -15,29 +15,24 @@ define([
 	"dijit/form/TextBox" // template
 ], function(declare, lang, domStyle, WidgetBase, WidgetsInTemplateMixin, TemplatedMixin, math, registry, template, calc){
 
-	/*=====
-		WidgetBase = dijit._WidgetBase;
-		WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
-		TemplatedMixin = dijit._TemplatedMixin;
-	=====*/
 	var FuncGen = declare(
 		"dojox.calc.FuncGen",
 		[WidgetBase, TemplatedMixin, WidgetsInTemplateMixin],
 	{
 		// summary:
 		//		The dialog layout for making functions
-		//
+
 		templateString: template,
 
 		onSelect: function(){
-			// summary
-			//	if they select something in the name combobox, then change the body and arguments to correspond to the function they selected
+			// summary:
+			//		if they select something in the name combobox, then change the body and arguments to correspond to the function they selected
 			this.reset();
 		},
 		onClear: function(){
-			// summary
-			//	the clear button in the template calls this
-			//	clear the name, arguments, and body if the user says yes
+			// summary:
+			//		The clear button in the template calls this.
+			//		Clear the name, arguments, and body if the user says yes.
 			var answer = confirm("Do you want to clear the name, argument, and body text?");
 			if(answer){
 				this.clear();
@@ -51,23 +46,24 @@ define([
 			//console.log("Save was pressed");
 		},
 		clear: function(){
-			// summary
-			//	clear the name, arguments, and body
+			// summary:
+			//		clear the name, arguments, and body
 			this.textarea.set("value", "");
 			this.args.set("value", "");
 			this.combo.set("value", "");
 		},
 		reset: function(){
-			// summary
-			//	set the arguments and body to match a function selected if it exists in the function list
+			// summary:
+			//		set the arguments and body to match a function selected if it exists in the function list
 			if(this.combo.get("value") in this.functions){
 				this.textarea.set("value", this.functions[this.combo.get("value")].body);
 				this.args.set("value", this.functions[this.combo.get("value")].args);
 			}
 		},
 		onReset: function(){
-			// summary
-			//	(Reset button on click event) reset the arguments and body to their previously saved state if the user says yes
+			// summary:
+			//		(Reset button on click event) reset the arguments and body to their previously saved state if the user says yes
+
 			//console.log("Reset was pressed");
 			if(this.combo.get("value") in this.functions){
 				var answer = confirm("Do you want to reset this function?");
@@ -78,8 +74,8 @@ define([
 			}
 		},
 		deleteThing: function(item){
-			// summary
-			//	delete an item in the writestore
+			// summary:
+			//		delete an item in the writestore
 			if(this.writeStore.isItem(item)){
 				// delete it
 				//console.log("Found item "+item);
@@ -93,8 +89,8 @@ define([
 			// override me
 		},
 		onDelete: function(){
-			// summary
-			//	(Delete button on click event) delete a function if the user clicks yes
+			// summary:
+			//		(Delete button on click event) delete a function if the user clicks yes
 
 			//console.log("Delete was pressed");
 
@@ -118,8 +114,8 @@ define([
 			}
 		},
 		readyStatus: function(){
-			// summary
-			//	set the status in the template to ready
+			// summary:
+			//		set the status in the template to ready
 			this.status.set("value", "Ready");
 		},
 		writeStore:null, //the user can save functions to the writestore
@@ -134,9 +130,9 @@ define([
 		},*/
 
 		startup: function(){
-			// summary
-			//	make sure the parent has a close button if it needs to be able to close
-			//	link the write store too
+			// summary:
+			//		make sure the parent has a close button if it needs to be able to close
+			//		link the write store too
 			this.combo.set("store", this.writeStore);
 
 			this.inherited(arguments);// this is super class startup
diff --git a/dojox/calc/GraphPro.js b/dojox/calc/GraphPro.js
index cee505c..c53c61f 100644
--- a/dojox/calc/GraphPro.js
+++ b/dojox/calc/GraphPro.js
@@ -18,16 +18,14 @@ define([
 	"dijit/form/TextBox" // template
 ], function(declare, lang, win, domStyle, domConstruct, domGeometry, ready, Standard, calc, FloatingPane, template){
 
-	/*=====
-		Standard = dojox.calc.Standard;
-	=====*/
+
 	return declare(
 		"dojox.calc.GraphPro",
 		Standard,
 	{
 		// summary:
 		//		The dialog widget for a graphing, scientific calculator
-		//
+
 		templateString: template,
 
 		grapher:null,
@@ -35,8 +33,8 @@ define([
 		aFloatingPane: null,
 
 		executorLoaded: function(){
-			// summary
-			//	when executor loads check to see if the writestore is there
+			// summary:
+			//		when executor loads check to see if the writestore is there
 			this.inherited(arguments);
 			ready(lang.hitch(this, function(){
 				if(this.writeStore == null && "functionMakerButton" in this){
@@ -45,8 +43,8 @@ define([
 			}));
 		},
 		makeFunctionWindow: function(){
-			// summary
-			//	use this function to create a function window (with the button on the layout)
+			// summary:
+			//		use this function to create a function window (with the button on the layout)
 			var body = win.body();
 
 			var pane = domConstruct.create('div');
@@ -84,8 +82,8 @@ define([
 			this.aFloatingPane.bringToTop();
 		},
 		makeGrapherWindow: function(){
-			// summary
-			//	use this to make a Grapher window appear with a button
+			// summary:
+			//		use this to make a Grapher window appear with a button
 			var body = win.body();
 
 			var pane = domConstruct.create('div');
diff --git a/dojox/calc/Grapher.js b/dojox/calc/Grapher.js
index 9ada5bd..0be2aff 100644
--- a/dojox/calc/Grapher.js
+++ b/dojox/calc/Grapher.js
@@ -27,34 +27,25 @@ define([
 	"dijit/form/Select" // template
 ], function(declare, lang, win, domConstruct, domClass, domStyle, WidgetBase, WidgetsInTemplateMixin, TemplatedMixin, math, registry, DropDownButton, TooltipDialog, TextBox, CheckBox, ColorPalette, Chart, axis2d, plot2d, Lines, Tufte, colors, template, calc){
 
-	// summary
-	//	provide static functions for Grapher
 	var
 		epsilon = 1e-15 / 9,
 		bigNumber = 1e200,
 		log2 = Math.log(2),
 		defaultParams = {graphNumber:0, fOfX:true, color:{stroke:"black"}};
 
-
-	/*=====
-		WidgetBase = dijit._WidgetBase;
-		WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
-		TemplatedMixin = dijit._TemplatedMixin;
-	=====*/
 	var Grapher = declare(
 		"dojox.calc.Grapher",
 		[WidgetBase, TemplatedMixin, WidgetsInTemplateMixin],
 	{
 		// summary:
 		//		The dialog layout for making graphs
-		//
+
 		templateString: template,
 
 		addXYAxes: function(chart){
 			// summary:
 			//		add or re-add the default x/y axes to the Chart provided
-			// params:
-			//	chart is an instance of dojox.charting.Chart
+			// chart: dojox.charting.Chart
 
 			return chart.addAxis("x", {
 				max: parseInt(this.graphMaxX.get("value")),
@@ -88,15 +79,15 @@ define([
 			});
 		},
 		selectAll: function(){
-			// summary
-			//	select all checkboxes inside the function table
+			// summary:
+			//		select all checkboxes inside the function table
 			for(var i = 0; i < this.rowCount; i++){
 				this.array[i][this.checkboxIndex].set("checked", true);
 			}
 		},
 		deselectAll: function(){
-			// summary
-			//	deselect all checkboxes inside the function table
+			// summary:
+			//		deselect all checkboxes inside the function table
 			for(var i = 0; i < this.rowCount; i++){
 				this.array[i][this.checkboxIndex].set("checked", false);
 			}
@@ -111,9 +102,9 @@ define([
 		},
 		erase: function(i){
 			// summary:
-			//	erase the chart inside this.array with the index i
-			// params:
-			//	i is the integer index to this.array that represents the current row number in the table
+			//		erase the chart inside this.array with the index i
+			// i: Integer
+			//		index to this.array that represents the current row number in the table
 			var nameNum = 0;
 			var name = "Series "+this.array[i][this.funcNumberIndex]+"_"+nameNum;
 			while(name in this.array[i][this.chartIndex].runs){
@@ -126,8 +117,8 @@ define([
 		},
 		onErase: function(){
 			// summary:
-			//	the erase button's onClick method
-			//	it see's if the checkbox is checked and then erases it if it is.
+			//		the erase button's onClick method
+			//		it see's if the checkbox is checked and then erases it if it is.
 			for(var i = 0; i < this.rowCount; i++){
 				if(this.array[i][this.checkboxIndex].get("checked")){
 					this.erase(i);
@@ -136,8 +127,8 @@ define([
 		},
 		onDelete: function(){
 			// summary:
-			//	the delete button's onClick method
-			//	delete all of the selected rows
+			//		The delete button's onClick method.
+			//		Delete all of the selected rows.
 			for(var i = 0; i < this.rowCount; i++){
 				if(this.array[i][this.checkboxIndex].get("checked")){
 					this.erase(i);
@@ -169,7 +160,7 @@ define([
 
 		createFunction: function(){
 			// summary:
-			//	create a new row in the table with all of the dojo objects.
+			//		create a new row in the table with all of the dojo objects.
 
 			var tr = this.graphTable.insertRow(-1);
 			this.array[tr.rowIndex] = [];
@@ -250,16 +241,17 @@ define([
 		},
 		setStatus: function(i, status){
 			// summary:
-			//	set the status of the row i to be status
-			// params:
-			//	i is an integer index of this.array as well as a row index
-			//	status is a String, it is either Error, Hidden, or Drawn
+			//		set the status of the row i to be status
+			// i: Integer
+			//		index of this.array as well as a row index
+			// status: String
+			//		either Error, Hidden, or Drawn
 			this.array[i][this.statusIndex].innerHTML = status; //this.array[i][this.statusIndex].set("value", status);
 		},
 		changedColor: function(){
 			// summary:
-			//	make the color of the chart the new color
-			//	the context is changed to the colorPalette, and a reference to chart was added to it a an attribute
+			//		Make the color of the chart the new color.
+			//		The context is changed to the colorPalette, and a reference to chart was added to it a an attribute.
 			var chart = this.get("chart");
 			var colorBoxFieldset = this.get("colorBox");
 			for(var i = 0; i < chart.series.length; i++){
@@ -275,17 +267,17 @@ define([
 		},
 		makeDirty: function(){
 			// summary:
-			//	if something in the window options is changed, this is called
+			//		if something in the window options is changed, this is called
 			this.dirty = true;
 		},
 		checkDirty1: function(){
 			// summary:
-			//	to stay in sync with onChange, checkDirty is called with a timeout
+			//		to stay in sync with onChange, checkDirty is called with a timeout
 			setTimeout(lang.hitch(this, 'checkDirty'), 0);
 		},
 		checkDirty: function(){
 			// summary:
-			//	adjust all charts in this.array according to any changes in window options
+			//		adjust all charts in this.array according to any changes in window options
 			if(this.dirty){
 				// change the axes of all charts if it is dirty
 				for(var i = 0; i < this.rowCount; i++){
@@ -298,8 +290,8 @@ define([
 			this.dirty = false;
 		},
 		postCreate: function(){
-			// summary
-			//	add Event handlers, some additional attributes, etc
+			// summary:
+			//		add Event handlers, some additional attributes, etc
 			this.inherited(arguments);// this is super class postCreate
 			this.createFunc.set("onClick", lang.hitch(this, 'createFunction'));
 
@@ -325,8 +317,8 @@ define([
 
 		},
 		startup: function(){
-			// summary
-			//	make sure the parent has a close button if it needs to be able to close
+			// summary:
+			//		make sure the parent has a close button if it needs to be able to close
 			this.inherited(arguments);// this is super class startup
 			// close is only valid if the parent is a widget with a close function
 			var parent = registry.getEnclosingWidget(this.domNode.parentNode);
@@ -348,12 +340,14 @@ define([
 
 	return lang.mixin(calc, {
 		draw: function(/*Chart*/ chart, /*Function*/ functionToGraph, params){
-			// summary
-			//	graph a chart with the given function.
-			// params
-			//	chart is a dojox.charting.Chart object, functionToGraph is a function with one numeric parameter (x or y typically)
-			//	and params is an Object the can contain the number of the graph in the chart it is (an integer), a boolean saying if the functionToGraph is a function of x (otherwise y)
-			//	and the color, which is an object with a stroke with a color's name eg: color:{stroke:"black"}
+			// summary:
+			//		graph a chart with the given function.
+			// chart: dojox.charting.Chart
+			// functionToGraph: Function
+			//		Function with one numeric parameter (x or y typically)
+			// params: Object
+			//		can contain the number of the graph in the chart it is (an integer), a boolean saying if the functionToGraph is a function of x (otherwise y)
+			//		and the color, which is an object with a stroke with a color's name eg: color:{stroke:"black"}
 
 			params = lang.mixin({}, defaultParams, params);
 			chart.fullGeometry();
@@ -392,14 +386,25 @@ define([
 
 		generatePoints: function(/*Function*/ funcToGraph, /*String*/ x, /*String*/ y, /*Number*/ width, /*Number*/ minX, /*Number*/ maxX, /*Number*/ minY, /*Number*/ maxY){
 			// summary:
-			//	create the points with information about the graph.
-			// params:
-			//	funcToGraph is a function with one numeric parameter (x or y typically)
-			//	x and y are Strings which always have the values of "x" or "y".  If y="x" and x="y" then it is creating points for the function as though it was a function of y
-			//	Number minX, Number maxX, Number minY, Number maxY are all bounds of the chart.  If x="y" then maxY should be the maximum bound of x rather than y
-			//	Number width is the pixel width of the chart
+			//		create the points with information about the graph.
+			// funcToGraph: Function
+			//		A function with one numeric parameter (x or y typically)
+			// x: String
+			//		x and y are Strings which always have the values of "x" or "y".  If y="x" and x="y" then it is creating points for the function as though it was a function of y
+			// y: String
+			//		x and y are Strings which always have the values of "x" or "y".  If y="x" and x="y" then it is creating points for the function as though it was a function of y
+			// minX:
+			//		minX, maxX, minY, and maxY are all bounds of the chart.  If x="y" then maxY should be the maximum bound of x rather than y
+			// maxX:
+			//		minX, maxX, minY, and maxY are all bounds of the chart.  If x="y" then maxY should be the maximum bound of x rather than y
+			// minY:
+			//		minX, maxX, minY, and maxY are all bounds of the chart.  If x="y" then maxY should be the maximum bound of x rather than y
+			// maxY:
+			//		minX, maxX, minY, and maxY are all bounds of the chart.  If x="y" then maxY should be the maximum bound of x rather than y
+			// width:
+			//		pixel width of the chart
 			// output:
-			//	an array of arrays of points
+			//		an array of arrays of points
 			var pow2 = (1 << Math.ceil(Math.log(width) / log2));
 			var
 				dx = (maxX - minX) / pow2, // divide by 2^n instead of width to avoid loss of precision
diff --git a/dojox/calc/Standard.js b/dojox/calc/Standard.js
index bb3fe72..df4f0f5 100644
--- a/dojox/calc/Standard.js
+++ b/dojox/calc/Standard.js
@@ -24,18 +24,13 @@ define([
 	"dijit/form/TextBox" // template
 ], function(declare, lang, has, win, event, domStyle, ready, keys, registry, typematic, WidgetBase, WidgetsInTemplateMixin, TemplatedMixin, _TextBoxMixin, math, TooltipDialog, template, calc){
 
-	/*=====
-		WidgetBase = dijit._WidgetBase;
-		WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
-		TemplatedMixin = dijit._TemplatedMixin;
-	=====*/
 	return declare(
 		"dojox.calc.Standard",
 		[WidgetBase, TemplatedMixin, WidgetsInTemplateMixin],
 	{
 		// summary:
 		//		The dialog layout for a standard 4 function/algebraic calculator
-		//
+
 		templateString: template,
 
 		readStore:null,
@@ -43,8 +38,8 @@ define([
 		functions: [],
 
 		executorLoaded: function(){
-			// summary
-			//	load in the stores after executor is loaded (the stores need executor to be loaded because it parses them)
+			// summary:
+			//		load in the stores after executor is loaded (the stores need executor to be loaded because it parses them)
 			ready(lang.hitch(this, function(){
 				this.loadStore(this.readStore, true);
 				this.loadStore(this.writeStore);
@@ -52,16 +47,16 @@ define([
 		},
 
 		saveFunction: function(name, args, body){
-			// summary
-			//	make the function with executor
+			// summary:
+			//		make the function with executor
 			this.functions[name] = this.executor.normalizedFunction(name, args, body);
 			this.functions[name].args = args;
 			this.functions[name].body = body;
 		},
 
 		loadStore: function(store, isReadOnly){
-			// summary
-			//	load an entire store, and make it publicly editable/viewable based on isReadOnly
+			// summary:
+			//		load an entire store, and make it publicly editable/viewable based on isReadOnly
 			if(!store){
 				return;
 			}
@@ -71,8 +66,8 @@ define([
 		},
 
 		parseTextbox: function(){
-			// summary
-			//	parse the contents of the textboxWidget and display the answer somewhere (depending on the layout)
+			// summary:
+			//		parse the contents of the textboxWidget and display the answer somewhere (depending on the layout)
 			var text = this.textboxWidget.textbox.value;
 			if(text == "" && this.commandList.length > 0){
 				this.setTextboxValue(this.textboxWidget, this.commandList[this.commandList.length-1]);
@@ -110,9 +105,9 @@ define([
 			}
 		},
 		cycleCommands: function(count, node, event){
-			// summary
-			//	cycle through the commands that the user has entered
-			//	it does not wrap around
+			// summary:
+			//		Cycle through the commands that the user has entered.
+			//		It does not wrap around.
 			if(count == -1 || this.commandList.length==0){
 				return;
 			}
@@ -125,8 +120,8 @@ define([
 			}
 		},
 		cycleCommandUp: function(){
-			// summary
-			//	cycle up through the list of commands the user has entered already
+			// summary:
+			//		cycle up through the list of commands the user has entered already
 			if(this.commandIndex-1<0){
 				this.commandIndex=0;
 			}else{
@@ -135,8 +130,8 @@ define([
 			this.setTextboxValue(this.textboxWidget, this.commandList[this.commandIndex]);
 		},
 		cycleCommandDown: function(){
-			// summary
-			//	cycle down through the list of commands the user has entered already
+			// summary:
+			//		cycle down through the list of commands the user has entered already
 			if(this.commandIndex+1>=this.commandList.length){
 				this.commandIndex=this.commandList.length;
 				this.setTextboxValue(this.textboxWidget, "");
@@ -147,8 +142,8 @@ define([
 
 		},
 		onBlur: function(){
-			// summary
-			//	IE is lacking in function when it comes to the text boxes, so here, make it work like other browsers do by forcing a node.selectionStart and End onto it
+			// summary:
+			//		IE is lacking in function when it comes to the text boxes, so here, make it work like other browsers do by forcing a node.selectionStart and End onto it
 			if(has('ie')){
 				var tr = win.doc.selection.createRange().duplicate();
 				var selectedText = tr.text || '';
@@ -163,8 +158,8 @@ define([
 			}
 		},
 		onKeyPress: function(e){
-			// summary
-			// handle key input for Enter and operators
+			// summary:
+			//		handle key input for Enter and operators
 			if(e.charOrCode == keys.ENTER){
 				this.parseTextbox();
 				// stop form submissions
@@ -193,13 +188,13 @@ define([
 			}
 		},
 		insertMinus: function(){
-			// summary
-			//	insert a minus sign when they press (-) in the combo button
+			// summary:
+			//		insert a minus sign when they press (-) in the combo button
 			this.insertText('-');
 		},
 		print: function(text, isRight){
-			// summary
-			//	print the answer (typically) to the display or the input box
+			// summary:
+			//		print the answer (typically) to the display or the input box
 			var t = "<span style='display:block;";
 			if(isRight){
 				t += "text-align:right;'>";
@@ -215,13 +210,14 @@ define([
 			//this.setTextboxValue(this.displayBox, this.displayBox.get('value')+'\n'+text);
 		},
 		setTextboxValue: function(widget, val){
-			// summary
-			//	set a widget's value
+			// summary:
+			//		set a widget's value
 			widget.set('value', val);
 		},
 		putInAnsIfTextboxIsHighlighted: function(node){
-			// summary
-			//	try seeing if the textbox is highlighted completely so you know if Ans should be put in for an operator like +
+			// summary:
+			//		try seeing if the textbox is highlighted completely so you know if Ans should be put in for an operator like +
+
 			//console.log("Entered "+node.selectionStart + " "+ node.selectionEnd);
 			if(typeof node.selectionStart == "number"){ // not-IE
 				if(node.selectionStart==0 && node.selectionEnd == node.value.length){
@@ -241,8 +237,8 @@ define([
 			return false;
 		},
 		clearText: function(){
-			// summary
-			//	this clears the input box if it has content, but if it does not it clears the display
+			// summary:
+			//		this clears the input box if it has content, but if it does not it clears the display
 			if(this.hasDisplay && this.textboxWidget.get('value')==""){
 				this.displayBox.innerHTML = "";//this.setTextboxValue(this.displayBox, "");
 			}else{
@@ -260,8 +256,8 @@ define([
 			this.insertText('-');
 		},*/
 		insertOperator: function(newText){
-			// summary
-			//	insert an operator with a button
+			// summary:
+			//		insert an operator with a button
 			if(typeof newText == "object"){
 				newText = newText = registry.getEnclosingWidget(newText["target"]).value;
 			}
@@ -271,8 +267,8 @@ define([
 			this.insertText(newText);
 		},
 		insertText: function(newText){//(node, newText){
-			// summary
-			//	insert text to the textboxWidget node
+			// summary:
+			//		insert text to the textboxWidget node
 			setTimeout(lang.hitch(this, function(){
 
 			var node = this.textboxWidget.textbox;
@@ -315,8 +311,8 @@ define([
 		},
 		hasDisplay: false,
 		postCreate: function(){
-			// summary
-			//	run startup, see if there is an upper display box, etc
+			// summary:
+			//		run startup, see if there is an upper display box, etc
 			this.handle = null;
 			this.commandList = [];
 			this.commandIndex = 0;
diff --git a/dojox/calc/_Executor.js b/dojox/calc/_Executor.js
index 8a4abf6..7615601 100644
--- a/dojox/calc/_Executor.js
+++ b/dojox/calc/_Executor.js
@@ -15,10 +15,6 @@ define([
 
 	var magicBigInt = (1 << 30) - 35; // 2^30 - 35 is a prime that ensures approx(n/(2^k)) != n/(2^k) for k >= 1 and n < 2^k
 
-	/*=====
-		WidgetBase = dijit._WidgetBase;
-		TemplatedMixin = dijit._TemplatedMixin;
-	=====*/
 	var Executor = declare(
 		"dojox.calc._Executor",
 		[WidgetBase, TemplatedMixin],
@@ -31,9 +27,9 @@ define([
 			'" style="display:none;" onload="if(arguments[0] && arguments[0].Function)'+dijit._scopeName+'.byNode(this)._onLoad(arguments[0])"></iframe>',
 
 		_onLoad: function(env){
-			// summary
-			//	prepare for communications between the user and the calculator by saving the calculator environment, storing the prompt function locally, and making dojox.math available
-			//
+			// summary:
+			//		prepare for communications between the user and the calculator by saving the calculator environment, storing the prompt function locally, and making dojox.math available
+
 			calcEnv = env;
 			env.outerPrompt = window.prompt; // for IE who can't execute the iframe's prompt method without notifying the user first
 			// let the user call dojo math functions
@@ -83,17 +79,17 @@ define([
 
 		onLoad: function(){
 			// summary:
-			//	this should be overwritten and become a great place for making user predefined functions
-			//
+			//		this should be overwritten and become a great place for making user predefined functions
 		},
 		Function: function(name, args, body){
-			// summary
-			//	create an anonymous function to run the code the parser generates from the user input.
-			// params
-			//	name: this argument is simply a String that represents the name of the function being evaluated. It can be undefined, but in that case the function is a one time use.
-			//	args: the function arguments (a String)
-			//	body: the function body, also a String
-			//
+			// summary:
+			//		create an anonymous function to run the code the parser generates from the user input.
+			// name:
+			//		this argument is simply a String that represents the name of the function being evaluated. It can be undefined, but in that case the function is a one time use.
+			// args: String
+			//		the function arguments
+			// body: String
+			//		the function body
 			return lang.hitch(calcEnv, calcEnv.Function.apply(calcEnv, arguments));
 		},
 		normalizedFunction: function(name, args, body){
@@ -104,11 +100,10 @@ define([
 			delete calcEnv[name];
 		},
 		eval: function(text){
-			// summary
-			//	create an anonymous function to run the code the parser generates from the user input.
-			// params
-			//	text, type String, is the user input that needs to be parsed
-			//
+			// summary:
+			//		create an anonymous function to run the code the parser generates from the user input.
+			// text: String
+			//		the user input that needs to be parsed
 			return calcEnv.eval.apply(calcEnv, arguments);
 		},
 		destroy: function(){
diff --git a/dojox/calc/_ExecutorIframe.html b/dojox/calc/_ExecutorIframe.html
index 0d2cac5..82fc7c9 100644
--- a/dojox/calc/_ExecutorIframe.html
+++ b/dojox/calc/_ExecutorIframe.html
@@ -57,11 +57,12 @@ Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+
 		window: undefined, "delete": undefined, "new": undefined, // invalidate access to the globals for security so that window.blah is invalid as is delete window
 
 		prompt: function(label, defaultValue){
-			// summary
-			//	prompt the user for input without making IE8 mad.
-			// params
-			//	label: the String name of the variable you are asking the user to input
-			//	defaultValue: primitive, the prompt will show this value initially
+			// summary:
+			//		prompt the user for input without making IE8 mad.
+			// label:
+			//		the String name of the variable you are asking the user to input
+			// defaultValue: primitive
+			//		the prompt will show this value initially
 
 			label = label || '';
 			defaultValue = defaultValue || '';
@@ -72,11 +73,12 @@ Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+
 			}
 		},
 		val: function(local, name, obj){
-			// summary
-			//	allow the user to use locals, globals, or give input for undefined values
-			// params:
-			//	local, a primitive object, is what value might've been passed to val as a local parameter.
-			//	name is the String name of the object.  It is passed to see if there is an available global or to set the global.
+			// summary:
+			//		allow the user to use locals, globals, or give input for undefined values
+			// local: a primitive object
+			//		what value might've been passed to val as a local parameter.
+			// name: String
+			//		String name of the object.  It is passed to see if there is an available global or to set the global.
 			var objValue = obj[name];
 			local = (objValue == undefined) ? (local == undefined ? window[name] : local) : objValue ;
 
@@ -91,15 +93,16 @@ Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+
 			return local;
 		},
 		_makeKeywordsLiteral: function (text){
-			// summary
-			//	surround reserved words with hex characters
+			// summary:
+			//		surround reserved words with hex characters
+
 			// ==, then >=. the <=, then !=, then = and surround them with \x0n first
 			text = text.replace(/(!=(?!=)|==|>=|<=|=)/g, "\x02$1\x02");
 			return text.replace(/\b(abstract|boolean|break|byte|case|catch|char|class|const|continue|debugger|default|do|double|else|enum|export|extends|false|final|finally|float|for|function|goto|if|implements|import|in| instanceof|int|interface|long|native|null|package|private|protected|public|return|short|static|super| switch|synchronized|this|throw|throws|transient|true|try|typeof|var|void|volatile|while|with)\b/g, "\x02$1\x02");
 		},
 		switchToGermanNumbers: function(text){
-			// summary
-			//	change the format of some javascript allowed numbers to an alternate form 3.5 goes to 3,5
+			// summary:
+			//		change the format of some javascript allowed numbers to an alternate form 3.5 goes to 3,5
 			var num = 0;
 			var numbers = [];
 			function substituteCommas(whole, junk, text){
@@ -133,10 +136,10 @@ Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+
 			return text.replace(/\x02((.|\s)*?)\x02/g, "$1");
 		},
 		normalizeTextLanguage: function(text){
-			// summary
-			//	change text to use javascript list separators and decimal points instead of commas
-			// params
-			//	text is a string like "pow(3,1; 4);"
+			// summary:
+			//		change text to use javascript list separators and decimal points instead of commas
+			// text: String
+			//		string like "pow(3,1; 4);"
 			//		for that input, this method should return "pow(3.1, 4);"
 
 			var num = 0;
@@ -165,8 +168,8 @@ Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+
 			return text.replace(/\x02((.|\s)*?)\x02/g, "$1");
 		},
 		preparse: function(text){
-			// summary
-			//	change the numbers to javascript allowed numbers if it is from a different locale
+			// summary:
+			//		change the numbers to javascript allowed numbers if it is from a different locale
 			if(!this.isJavaScriptLanguage){
 				text = this.normalizeTextLanguage(text);
 			}
@@ -175,16 +178,16 @@ Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+
 		// parseFloat(Number(4.5).toString(3)) should return 4.5
 
 		postparse: function(text){
-			// summary
-			//	make the javascript numbers match the locale
+			// summary:
+			//		make the javascript numbers match the locale
 			if(!this.isJavaScriptLanguage){
 				text = this.switchToGermanNumbers(text);
 			}
 			return text;
 		},
 		toDecimalRegExp: function(whole, base, number){
-			// summary
-			//	get the decimal number from a float
+			// summary:
+			//		get the decimal number from a float
 			function getBase(base){
 				switch(base){
 					case '0b':
@@ -201,11 +204,11 @@ Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+
 			return parseFloat(base+number);
 		},
 		parse: function(text){
-			// summary
-			//	This parses augmented mathematical syntax and converts it to executable JavaScript.
-			// params:
-			//	text should be a String which represents an expression, a function, a number, etc
-			//
+			// summary:
+			//		This parses augmented mathematical syntax and converts it to executable JavaScript.
+			// text: String
+			//		should be a String which represents an expression, a function, a number, etc
+
 			// this array holds the substitutions that represent an expression's parentheses and functions in a simplified way.
 			var	numbers = [],
 				// characters
@@ -447,10 +450,11 @@ Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+
 
 		},
 		eval: function(text){
-			// summary
-			//	create an anonymous function to run the code the parser generates from the user input.
-			// params
-			//	text, type String, is the user input that needs to be parsed
+			// summary:
+			//		create an anonymous function to run the code the parser generates from the user input.
+			// text: String
+			//		is the user input that needs to be parsed
+
 			// this try catch is necessary to ensure that any incorrect input will receive NaN (it won't cause a self destruct from a user typo)
 			try{
 				var value = this.Function(undefined, '', 'return ' + text).call(this); // make sure it is called within the correct scope.
@@ -461,12 +465,14 @@ Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+
 			}
 		},
 		normalizedFunction: function(name, args, body){
-			// summary
-			//	create an anonymous function to run the code the parser generates from the user input.
-			// params
-			//	name: this argument is simply a String that represents the name of the function being evaluated. It can be undefined, but in that case the function is a one time use.
-			//	args: the function arguments (a String)
-			//	body: the function body, also a String
+			// summary:
+			//		create an anonymous function to run the code the parser generates from the user input.
+			// name: String
+			//		this argument is simply a String that represents the name of the function being evaluated. It can be undefined, but in that case the function is a one time use.
+			// args: String
+			//		the function arguments
+			// body: String
+			//		the function body
 			var	argMultiVals = '',
 			// make an array of parameters with what's given (if nothing is given, make an empty array)
 				params = args ? (args||'').split(/\W+/) : [];
@@ -500,12 +506,14 @@ Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+
 			return _f_;
 		},
 		Function: function(name, args, body){
-			// summary
-			//	create an anonymous function to run the code the parser generates from the user input.  It also normalizes the language format.
-			// params
-			//	name: this argument is simply a String that represents the name of the function being evaluated. It can be undefined, but in that case the function is a one time use.
-			//	args: the function arguments (a String)
-			//	body: the function body, also a String
+			// summary:
+			//		create an anonymous function to run the code the parser generates from the user input.  It also normalizes the language format.
+			// name: String
+			//		this argument is simply a String that represents the name of the function being evaluated. It can be undefined, but in that case the function is a one time use.
+			// args: String
+			//		the function arguments
+			// body: String
+			//		the function body
 
 			body = this.preparse(body);
 			return this.normalizedFunction(name, args, body);
diff --git a/dojox/calc/tests/test_GraphPro.html b/dojox/calc/tests/test_GraphPro.html
index 52bda2b..fc58d04 100644
--- a/dojox/calc/tests/test_GraphPro.html
+++ b/dojox/calc/tests/test_GraphPro.html
@@ -11,7 +11,7 @@
 		@import "../../../dojox/calc/resources/GraphPro.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<script type="text/javascript">
 		//TODO make the graphing window textboxes respond to the input buttons on the layout
diff --git a/dojox/calc/tests/test_Standard.html b/dojox/calc/tests/test_Standard.html
index f722702..317ffc1 100644
--- a/dojox/calc/tests/test_Standard.html
+++ b/dojox/calc/tests/test_Standard.html
@@ -11,7 +11,7 @@
 		@import "../../../dojox/calc/resources/Standard.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: false"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: false"></script>
 
 	<script type="text/javascript">
 		require([
diff --git a/dojox/calc/toFrac.js b/dojox/calc/toFrac.js
index 8871edc..4db9787 100644
--- a/dojox/calc/toFrac.js
+++ b/dojox/calc/toFrac.js
@@ -112,7 +112,8 @@ define([
 		},
 		pow: function(base, exponent){// pow benefits from toFrac because it can overcome many of the limitations set before the standard Math.pow
 			// summary:
-			//	Computes base ^ exponent
+			//		Computes base ^ exponent
+
 			//	Wrapper to Math.pow(base, exponent) to handle (-27) ^ (1/3)
 			function isInt(n){
 				return Math.floor(n) == n;
diff --git a/dojox/calendar/CONTRIBUTING.md b/dojox/calendar/CONTRIBUTING.md
new file mode 100755
index 0000000..5ae012f
--- /dev/null
+++ b/dojox/calendar/CONTRIBUTING.md
@@ -0,0 +1,3 @@
+All contributions to this repository must:
+- be done under the Dojo Contributor License Agreement (CLA, http://dojofoundation.org/about/claForm) that you must sign
+- follow the Dojo style guide (https://dojotoolkit.org/community/styleGuide)
diff --git a/dojox/calendar/Calendar.js b/dojox/calendar/Calendar.js
new file mode 100644
index 0000000..059b473
--- /dev/null
+++ b/dojox/calendar/Calendar.js
@@ -0,0 +1,59 @@
+define(["dojo/_base/declare", "dojo/_base/lang", "./CalendarBase", "./ColumnView", "./ColumnViewSecondarySheet", 
+				"./VerticalRenderer", "./MatrixView",	"./HorizontalRenderer", "./LabelRenderer", 
+				"./ExpandRenderer", "./Keyboard", "./Mouse", "dojo/text!./templates/Calendar.html", 
+				"dijit/form/Button", "dijit/Toolbar", "dijit/ToolbarSeparator"],
+	
+	function(declare, lang, CalendarBase, ColumnView, ColumnViewSecondarySheet, VerticalRenderer, 
+					 MatrixView, HorizontalRenderer, LabelRenderer, ExpandRenderer, Keyboard, Mouse, template){
+	
+	return declare("dojox.calendar.Calendar", CalendarBase, {
+		
+		templateString: template,
+		
+		// summary:
+		//		This class defines a calendar widget that display events in time.
+		
+		_createDefaultViews: function(){
+			// summary:
+			//		Creates the default views:
+			//		- A dojox.calendar.ColumnView instance used to display one day to seven days time intervals,
+			//		- A dojox.calendar.MatrixView instance used to display the other time intervals.
+			//		The views are mixed with Mouse and Keyboard to allow editing items using mouse and keyboard.
+
+			var secondarySheetClass = declare([ColumnViewSecondarySheet, Keyboard, Mouse]);
+			
+			var colView = declare([ColumnView, Keyboard, Mouse])(lang.mixin({
+				secondarySheetClass: secondarySheetClass,
+				verticalRenderer: VerticalRenderer,
+				horizontalRenderer: HorizontalRenderer,
+				expandRenderer: ExpandRenderer
+			}, this.columnViewProps));
+			
+			var matrixView = declare([MatrixView, Keyboard, Mouse])(lang.mixin({
+				horizontalRenderer: HorizontalRenderer,
+				labelRenderer: LabelRenderer,
+				expandRenderer: ExpandRenderer
+			}, this.matrixViewProps));
+								
+			this.columnView = colView;
+			this.matrixView = matrixView;
+			
+			var views = [colView, matrixView];
+			
+			this.installDefaultViewsActions(views);
+			
+			return views;
+		},
+		
+		installDefaultViewsActions: function(views){
+			// summary:
+			//		Installs the default actions on newly created default views.
+			//		By default this action is registering:
+			//		- the matrixViewRowHeaderClick method on the rowHeaderClick event of the matrix view.
+			//		- the columnViewColumnHeaderClick method on the columnHeaderClick event of the column view.
+			this.matrixView.on("rowHeaderClick", lang.hitch(this, this.matrixViewRowHeaderClick));
+			this.columnView.on("columnHeaderClick", lang.hitch(this, this.columnViewColumnHeaderClick));
+		}
+		
+	});
+});
diff --git a/dojox/calendar/CalendarBase.js b/dojox/calendar/CalendarBase.js
new file mode 100755
index 0000000..96bb6ca
--- /dev/null
+++ b/dojox/calendar/CalendarBase.js
@@ -0,0 +1,1464 @@
+define([
+"dojo/_base/declare", 
+"dojo/_base/sniff", 
+"dojo/_base/event", 
+"dojo/_base/lang", 
+"dojo/_base/array", 
+"dojo/cldr/supplemental",
+"dojo/dom", 
+"dojo/dom-class", 
+"dojo/dom-style",
+"dojo/dom-construct", 
+"dojo/date", 
+"dojo/date/locale", 
+"dojo/_base/fx", 
+"dojo/fx",
+"dojo/on", 
+"dijit/_WidgetBase", 
+"dijit/_TemplatedMixin", 
+"dijit/_WidgetsInTemplateMixin", 
+"./StoreMixin", 
+"dojox/widget/_Invalidating", 
+"dojox/widget/Selection", 
+"dojox/calendar/time", 
+"dojo/i18n!./nls/buttons"],	
+function(
+declare, 
+has, 
+event, 
+lang, 
+arr, 
+cldr, 
+dom, 
+domClass, 
+domStyle,
+domConstruct, 
+date, 
+locale,
+coreFx,
+fx, 
+on,  
+_WidgetBase, 
+_TemplatedMixin, 
+_WidgetsInTemplateMixin, 
+StoreMixin, 
+_Invalidating, 
+Selection, 
+timeUtil,
+_nls){
+	
+	/*=====
+	var __HeaderClickEventArgs = {
+		// summary:
+		//		A column click event.
+		// index: Integer
+		//		The column index. 
+		// date: Date
+		//		The date displayed by the column.
+		// triggerEvent: Event
+		//		The origin event.
+	};
+	=====*/
+	
+	/*=====
+	var __TimeIntervalChangeArgs = {
+		// summary:
+		//		An time interval change event, dispatched when the calendar displayed time range has changed.
+		// oldStartTime: Date
+		//		The start of the previously displayed time interval, if any. 
+		// startTime: Date
+		//		The new start of the displayed time interval.
+		// oldEndTime: Date
+		//		The end of the previously displayed time interval, if any.
+		// endTime: Date
+		//		The new end of the displayed time interval.
+	};
+	=====*/
+	
+	/*=====
+	var __GridClickEventArgs = {
+		// summary:
+		//		The event dispatched when the grid is clicked or double-clicked.
+		// date: Date
+		//		The start of the previously displayed time interval, if any. 
+		// triggerEvent: Event
+		//		The event at the origin of this event.
+	};
+	=====*/
+	
+	/*=====
+	var __ItemMouseEventArgs = {
+		// summary:
+		//		The event dispatched when an item is clicked, double-clicked or context-clicked.
+		// item: Object
+		//		The item clicked.
+		// renderer: dojox/calendar/_RendererMixin
+		//		The item renderer clicked.
+		// triggerEvent: Event
+		//		The event at the origin of this event.
+	};
+	=====*/
+	
+	/*=====
+	var __itemEditingEventArgs = {
+		// summary:
+		//		An item editing event.
+		// item: Object
+		//		The render item that is being edited. Set/get the startTime and/or endTime properties to customize editing behavior.
+		// storeItem: Object
+		//		The real data from the store. DO NOT change properties, but you may use properties of this item in the editing behavior logic.
+		// editKind: String
+		//		Kind of edit: "resizeBoth", "resizeStart", "resizeEnd" or "move".
+		// dates: Date[]
+		//		The computed date/time of the during the event editing. One entry per edited date (touch use case).
+		// startTime: Date?
+		//		The start time of data item.
+		// endTime: Date?
+		//		The end time of data item.
+		// sheet: String
+		//		For views with several sheets (columns view for example), the sheet when the event occurred.
+		// source: dojox/calendar/ViewBase
+		//		The view where the event occurred.
+		// eventSource: String
+		//		The device that triggered the event. This property can take the following values:
+		//
+		//		- "mouse", 
+		//		- "keyboard", 
+		//		- "touch"		
+		// triggerEvent: Event
+		//		The event at the origin of this event.
+	};
+	=====*/
+	
+	/*=====
+	var __rendererLifecycleEventArgs = {
+		// summary:
+		//		A renderer lifecycle event.
+		// renderer: Object
+		//		The renderer.		
+		// source: dojox/calendar/ViewBase
+		//		The view where the event occurred.
+		// item:Object?
+		//		The item that will be displayed by the renderer for the "rendererCreated" and "rendererReused" events.
+	};
+	=====*/
+	
+	/*=====
+	var __ExpandRendererClickEventArgs = {
+		// summary:
+		//		A expand renderer click event.
+		// columnIndex: Integer
+		//		The column index of the cell. 
+		// rowIndex: Integer
+		//		The row index of the cell.
+		// date: Date
+		//		The date displayed by the cell.
+		// triggerEvent: Event
+		//		The origin event.
+	};
+	=====*/
+
+	return declare("dojox.calendar.CalendarBase", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, StoreMixin, _Invalidating, Selection], {
+		
+		// summary:		
+		//		This class defines a generic calendar widget that manages several views to display event in time.
+		
+		baseClass: "dojoxCalendar",
+		
+		// datePackage: Object
+		//		JavaScript namespace to find Calendar routines. Uses Gregorian Calendar routines at dojo.date by default.
+		datePackage: date,
+		
+		// startDate: Date
+		//		The start date of the displayed time interval.
+		startDate: null,
+
+		// endDate: Date
+		//		The end date of the displayed time interval (included).		
+		endDate: null,
+		
+		// date:Date
+		//		The reference date used to determine along with the <code>dateInterval</code> 
+		//		and <code>dateIntervalSteps</code> properties the time interval to display.
+		date: null,
+	
+		// dateInterval:String
+		//		The date interval used to compute along with the <code>date</code> and 
+		//		<code>dateIntervalSteps</code> the time interval to display.
+		//		Valid values are "day", "week" (default value) and "month".
+		dateInterval: "week",
+		
+		// dateIntervalSteps:Integer
+		//		The number of date intervals used to compute along with the <code>date</code> and 
+		//		<code>dateInterval</code> the time interval to display.
+		//		Default value is 1.		
+		dateIntervalSteps: 1,		
+		
+		// viewContainer: Node
+		//		The DOM node that will contains the views.
+		viewContainer: null,
+		
+		// firstDayOfWeek: Integer
+		//		(Optional) The first day of week override. By default the first day of week is determined 
+		//		for the current locale (extracted from the CLDR).
+		//		Special value -1 (default value), means use locale dependent value.
+		firstDayOfWeek: -1, 
+		
+		// formatItemTimeFunc: Function?
+		//		Optional function to format the time of day of the item renderers.
+		//		The function takes the date and render data object as arguments and returns a String.
+		formatItemTimeFunc: null,
+		
+		// editable: Boolean
+		//		A flag that indicates whether or not the user can edit
+		//		items in the data provider.
+		//		If <code>true</code>, the item renderers in the control are editable.
+		//		The user can click on an item renderer, or use the keyboard or touch devices, to move or resize the associated event.
+		editable: true,
+		
+		// moveEnabled: Boolean
+		//		A flag that indicates whether the user can move items displayed.
+		//		If <code>true</code>, the user can move the items.
+		moveEnabled: true,
+		
+		// resizeEnabled: Boolean
+		//		A flag that indicates whether the items can be resized.
+		//		If <code>true</code>, the control supports resizing of items.
+		resizeEnabled: true,
+		
+		// columnView: dojox/calendar/ColumnView
+		//		The column view is displaying one day to seven days time intervals.
+		columnView: null,
+		
+		// matrixView: dojox/calendar/MatrixView
+		//		The column view is displaying time intervals that lasts more than seven days.
+		matrixView: null,
+		
+		// columnViewProps: Object
+		//		Map of property/value passed to the constructor of the column view.
+		columnViewProps: null,
+		
+		// matrixViewProps: Object
+		//		Map of property/value passed to the constructor of the matrix view.
+		matrixViewProps: null,
+		
+		// createOnGridClick: Boolean
+		//		Indicates whether the user can create new event by clicking and dragging the grid.
+		//		A createItem function must be defined on the view or the calendar object.
+		createOnGridClick: false,
+		
+		// createItemFunc: Function
+		//		A user supplied function that creates a new event.
+		//		This function is used when createOnGridClick is set to true and the user is clicking and dragging on the grid.
+		//		This view takes two parameters:
+		//
+		//		- view: the current view,
+		//		- d: the date at the clicked location.
+		createItemFunc: null,
+		
+		// currentView: ViewBase
+		//		The current view displayed by the Calendar object.
+		//		The currentViewChange event can be used to react on a view change.
+		currentView: null,
+				
+		_currentViewIndex: -1,
+		
+		views: null,
+		
+		_calendar: "gregorian",
+		
+		constructor: function(/*Object*/args){
+			this.views = [];
+			
+			this.invalidatingProperties = ["store", "items", "startDate", "endDate", "views", 
+				"date", "dateInterval", "dateIntervalSteps", "firstDayOfWeek"];
+			
+			args = args || {};
+			this._calendar = args.datePackage ? args.datePackage.substr(args.datePackage.lastIndexOf(".")+1) : this._calendar;
+			this.dateModule = args.datePackage ? lang.getObject(args.datePackage, false) : date; 
+			this.dateClassObj = this.dateModule.Date || Date; 
+			this.dateLocaleModule = args.datePackage ? lang.getObject(args.datePackage+".locale", false) : locale;
+								
+			this.invalidateRendering();
+		},
+				
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(this.views == null || this.views.length == 0){
+				this.set("views", this._createDefaultViews());	
+			}			
+		},
+		
+		_applyAttributes: function(){
+			this._applyAttr = true;
+			this.inherited(arguments);
+			delete this._applyAttr;
+		},
+		
+		////////////////////////////////////////////////////
+		//
+		// Getter / setters
+		//
+		////////////////////////////////////////////////////
+				
+		_setStartDateAttr: function(value){
+			this._set("startDate", value);
+			this._timeRangeInvalidated = true;
+		},
+		
+		_setEndDateAttr: function(value){
+			this._set("endDate", value);
+			this._timeRangeInvalidated = true;
+		},
+		
+		_setDateAttr: function(value){
+			this._set("date", value);
+			this._timeRangeInvalidated = true;
+		},
+		
+		_setDateIntervalAttr: function(value){
+			this._set("dateInterval", value);
+			this._timeRangeInvalidated = true;
+		},
+		
+		_setDateIntervalStepsAttr: function(value){
+			this._set("dateIntervalSteps", value);
+			this._timeRangeInvalidated = true;
+		},
+		
+		_setFirstDayOfWeekAttr: function(value){
+			this._set("firstDayOfWeek", value);
+			if(this.get("date") != null && this.get("dateInterval") == "week"){
+				this._timeRangeInvalidated = true;
+			}			
+		},
+		
+		_setTextDirAttr: function(value){
+			arr.forEach(this.views, function(view){
+				view.set("textDir", value);
+			});
+		},
+		
+		///////////////////////////////////////////////////
+		//
+		// Validating
+		//
+		///////////////////////////////////////////////////
+		
+		refreshRendering: function(){
+			// summary:
+			//		Refreshes all the visual rendering of the calendar. 
+			// tags:
+			//		protected
+			this.inherited(arguments);
+			this._validateProperties();
+		},
+		
+		_refreshItemsRendering: function(){
+			if(this.currentView){
+				this.currentView._refreshItemsRendering();
+			}
+		},
+		
+		resize: function(){
+			if(this.currentView){
+				this.currentView.resize();
+			}
+		},
+				
+		_validateProperties: function(){
+			// tags:
+			//		private
+
+			var cal = this.dateModule;
+			var startDate = this.get("startDate");
+			var endDate = this.get("endDate");
+			var date = this.get("date");
+			
+			if(this.firstDayOfWeek < -1 || this.firstDayOfWeek > 6){
+				this._set("firstDayOfWeek", 0);
+			}
+			
+			if(date == null && (startDate != null || endDate != null)){
+				
+				if(startDate == null){
+					startDate = new this.dateClassObj();
+					this._set("startDate", startDate);
+					this._timeRangeInvalidated = true;
+				}
+				
+				if(endDate == null){
+					endDate = new this.dateClassObj();
+					this._set("endDate", endDate);
+					this._timeRangeInvalidated = true;
+				}
+				
+				if(cal.compare(startDate, endDate) >= 0){
+					endDate = cal.add(startDate, "day", 1);
+					this._set("endDate", endDate);
+					this._timeRangeInvalidated = true;
+				}
+			
+			}else{
+			
+				if(this.date == null){
+					this._set("date", new this.dateClassObj());
+					this._timeRangeInvalidated = true;
+				}
+				
+				var dint = this.get("dateInterval");
+				if(dint != "day" && dint != "week" && dint != "month"){
+					this._set("dateInterval", "day");
+					this._timeRangeInvalidated = true;
+				}
+				
+				var dis = this.get("dateIntervalSteps");
+				if(lang.isString(dis)){
+					dis = parseInt(dis);
+					this._set("dateIntervalSteps", dis);
+				}
+				if(dis <= 0) {
+					this.set("dateIntervalSteps", 1);
+					this._timeRangeInvalidated = true;
+				}
+			}
+			
+			if(this._timeRangeInvalidated){
+				this._timeRangeInvalidated = false;
+				var timeInterval = this.computeTimeInterval();
+				
+				if(this._timeInterval == null || 
+					 cal.compare(this._timeInterval[0], timeInterval[0]) != 0 || 
+					 cal.compare(this._timeInterval[1], timeInterval[1]) != 0){
+					this.onTimeIntervalChange({
+						oldStartTime: this._timeInterval == null ? null : this._timeInterval[0],
+						oldEndTime: this._timeInterval == null ? null : this._timeInterval[1],
+						startTime: timeInterval[0],
+						endTime: timeInterval[1]
+					});
+				}
+				
+				this._timeInterval = timeInterval;
+				
+				var duration = this.dateModule.difference(this._timeInterval[0], this._timeInterval[1], "day");
+				var view = this._computeCurrentView(timeInterval[0], timeInterval[1], duration);
+				
+				var index = arr.indexOf(this.views, view);
+				
+				if(view == null || index == -1){
+					return;
+				}
+				
+				if(this.animateRange && (!has("ie") || has("ie")>8) ){
+					if(this.currentView){ // there's a view to animate
+						var ltr = this.isLeftToRight();
+						var inLeft = this._animRangeInDir=="left" || this._animRangeInDir == null; 
+						var outLeft = this._animRangeOutDir=="left" || this._animRangeOutDir == null;
+						this._animateRange(this.currentView.domNode, outLeft && ltr, false, 0, outLeft ? -100 : 100, 
+							lang.hitch(this, function(){
+								this.animateRangeTimer = setTimeout(lang.hitch(this, function(){
+									this._applyViewChange(view, index, timeInterval, duration);
+									this._animateRange(this.currentView.domNode, inLeft && ltr, true, inLeft ? -100 : 100, 0);
+									this._animRangeInDir = null;
+									this._animRangeOutDir = null;
+								}), 100);	// setTimeout give time for layout of view.							
+							}));
+					}else{
+						this._applyViewChange(view, index, timeInterval, duration);						
+					}
+				}else{					
+					this._applyViewChange(view, index, timeInterval, duration);
+				}
+			}
+		},
+		
+		_applyViewChange: function(view, index, timeInterval, duration){			
+			// summary:
+			//		Applies the changes of a view time and changes the currently visible view if needed.
+			// view: ViewBase
+			//		The view that is configured and is or will be shown.
+			// index: Integer
+			//		The view index in the internal structure.
+			// timeInterval: Date[]
+			//		The time interval displayed by the calendar.
+			// duration: Integer
+			//		The duration in days of the time interval.
+			// tags:
+			//		protected
+			
+			this._configureView(view, index, timeInterval, duration);
+			
+			if(index != this._currentViewIndex){
+				if(this.currentView == null){
+					view.set("items", this.items);
+					this.set("currentView", view);			
+				}else{					
+					if(this.items == null || this.items.length == 0){
+						this.set("currentView", view);
+						if(this.animateRange && (!has("ie") || has("ie")>8) ){
+							domStyle.set(this.currentView.domNode, "opacity", 0);
+						}
+						view.set("items", this.items);
+					}else{
+						this.currentView = view;
+						view.set("items", this.items);
+						this.set("currentView", view);
+						if(this.animateRange && (!has("ie") || has("ie")>8) ){
+							domStyle.set(this.currentView.domNode, "opacity", 0);
+						}
+					}																	
+				}											
+			}
+		},
+		
+		_timeInterval: null,
+		
+		computeTimeInterval: function(){
+			// summary:
+			//		Computes the displayed time interval according to the date, dateInterval and 
+			//		dateIntervalSteps if date is not null or startDate and endDate properties otherwise.
+			// tags:
+			//		protected
+					
+			var cal = this.dateModule;
+			var d = this.get("date");
+			
+			if(d == null){
+				return [ this.floorToDay(this.get("startDate")), cal.add(this.get("endDate"), "day", 1) ];
+			}
+				
+			var s = this.floorToDay(d);
+			var di = this.get("dateInterval");
+			var dis = this.get("dateIntervalSteps");
+			var e;
+			
+			switch(di){
+				case "day":						
+					e = cal.add(s, "day", dis);
+					break;
+				case "week":
+					s = this.floorToWeek(s);
+					e = cal.add(s, "week", dis);
+					break;
+				case "month":
+					s.setDate(1);
+					e = cal.add(s, "month", dis);						
+					break;
+			}				
+			return [s, e];						
+		},
+		
+		onTimeIntervalChange: function(e){
+			// summary:
+			//		Event dispatched when the displayed time interval has changed.
+			// e: __TimeIntervalChangeArgs
+			//		The time interval change event.
+			// tags:
+			//		callback
+		},
+		
+		/////////////////////////////////////////////////////
+		//
+		// View Management
+		//
+		/////////////////////////////////////////////////////
+		
+		// views: dojox.calendar.ViewBase[]
+		//		The views displayed by the widget.
+		//		To add/remove only one view, prefer, respectively, the addView() or removeView() methods.
+		views: null,
+		
+		_setViewsAttr: function(views){
+			if(!this._applyAttr){
+				// 1/ in create() the constructor parameters are mixed in the widget 
+				// 2/ in _applyAttributes(), every property with a setter is called.
+				// So no need to call on view removed for a non added view.... 
+				for(var i=0;i<this.views.length;i++){
+					this._onViewRemoved(this.views[i]);
+				}
+			}
+			if(views != null){
+				for(var i=0;i<views.length;i++){
+					this._onViewAdded(views[i]);
+				}			
+			}
+			this._set("views",  views == null ? [] : views.concat());			
+		},
+		
+		_getViewsAttr: function(){
+			return this.views.concat();
+		},
+		
+		_createDefaultViews: function(){
+			// summary:
+			//		Creates the default views.
+			//		This method does nothing and is designed to be overridden.
+			// tags:
+			//		protected
+		},
+		
+		addView: function(view, index){
+			// summary:
+			//		Add a view to the calendar's view list.
+			// view: dojox/calendar/ViewBase
+			//		The view to add to the calendar.
+			// index: Integer
+			//		Optional, the index where to insert the view in current view list.
+			// tags:
+			//		protected
+
+			if(index <= 0 || index > this.views.length){
+				index = this.views.length;
+			}
+			this.views.splice(index, view);
+			this._onViewAdded(view);
+		},
+		
+		removeView: function(view){
+			// summary:
+			//		Removes a view from the calendar's view list.
+			// view: dojox/calendar/ViewBase
+			//		The view to remove from the calendar.
+			// tags:
+			//		protected
+
+			if(index < 0 || index >=  this.views.length){
+				return;
+			}
+			
+			this._onViewRemoved(this.views[index]);
+			this.views.splice(index, 1);
+		},
+		
+		_onViewAdded: function(view){
+			view.owner = this;
+			view.buttonContainer = this.buttonContainer;
+			view._calendar = this._calendar;
+			view.datePackage = this.datePackage;
+			view.dateModule = this.dateModule;
+			view.dateClassObj = this.dateClassObj;
+			view.dateLocaleModule = this.dateLocaleModule;
+			domStyle.set(view.domNode, "display", "none");			
+			domClass.add(view.domNode, "view");
+			domConstruct.place(view.domNode, this.viewContainer);
+			this.onViewAdded(view);
+		},
+		
+		onViewAdded: function(view){
+			// summary:
+			//		Event dispatched when a view is added from the calendar.
+			// view: dojox/calendar/ViewBase
+			//		The view that has been added to the calendar.
+			// tags:
+			//		callback
+
+		},
+		
+		_onViewRemoved: function(view){
+			view.owner = null;
+			view.buttonContainer = null;
+			domClass.remove(view.domNode, "view");
+			this.viewContainer.removeChild(view.domNode);
+			this.onViewRemoved(view);
+		},
+		
+		onViewRemoved: function(view){			
+			// summary:
+			//		Event dispatched when a view is removed from the calendar.
+			// view: dojox/calendar/ViewBase
+			//		The view that has been removed from the calendar.
+			// tags:
+			//		callback
+
+		},
+		
+		_setCurrentViewAttr: function(view){
+			var index = arr.indexOf(this.views, view);
+			if(index != -1){
+				var oldView = this.get("currentView");
+				this._currentViewIndex = index;
+				this._set("currentView", view);
+				
+				this._showView(oldView, view);
+				this.onCurrentViewChange({
+					oldView: oldView,
+					newView: view
+				});
+			}					
+		},
+				
+		_getCurrentViewAttr: function(){
+			return this.views[this._currentViewIndex];		
+		},
+		
+		onCurrentViewChange: function(e){
+			// summary:
+			//		Event dispatched when the current view has changed.
+			// e: Event
+			//		Object that contains the oldView and newView properties.
+			// tags:
+			//		callback
+
+		},
+		
+		_configureView: function(view, index, timeInterval, duration){
+			// summary:
+			//		Configures the view to show the specified time interval.
+			//		This method is computing and setting the following properties:
+			//		- "startDate", "columnCount" for a column view,
+			//		- "startDate", "columnCount", "rowCount", "refStartTime" and "refEndTime" for a matrix view.
+			//		This method can be extended to configure other properties like layout properties for example.
+			// view: dojox/calendar/ViewBase
+			//		The view to configure.
+			// index: Integer
+			//		The index of the view in the Calendar view list.
+			// timeInterval: Date[]
+			//		The time interval that will be displayed by the view.
+			// duration: Integer
+			//		The duration, in days, of the displayed time interval.
+			// tags:
+			//		protected
+
+			var cal = this.dateModule;
+			if(view.viewKind == "columns"){
+				view.set("startDate", timeInterval[0]);
+				view.set("columnCount", duration);
+			}else if(view.viewKind == "matrix"){
+				if(duration > 7){ // show only full weeks.
+					var s = this.floorToWeek(timeInterval[0]);					
+					var e = this.floorToWeek(timeInterval[1]);
+					if(cal.compare(e, timeInterval[1]) != 0){
+						e = this.dateModule.add(e, "week", 1);
+					}					
+					duration = this.dateModule.difference(s, e, "day");
+					view.set("startDate", s);
+					view.set("columnCount", 7);
+					view.set("rowCount", Math.ceil(duration/7));
+					view.set("refStartTime", timeInterval[0]);
+					view.set("refEndTime", timeInterval[1]);					
+				}else{ 
+					view.set("startDate", timeInterval[0]);
+					view.set("columnCount", duration);
+					view.set("rowCount", 1);
+					view.set("refStartTime", null);
+					view.set("refEndTime", null);
+				}				
+			}
+		},
+		
+		_computeCurrentView: function(startDate, endDate, duration){
+			// summary:
+			//		If the time range is lasting less than seven days returns the column view or the matrix view otherwise.
+			// startDate: Date
+			//		The start date of the displayed time interval
+			// endDate: Date
+			//		The end date of the displayed time interval	
+			// duration: Integer
+			//		Duration of the 		
+			// returns: dojox/calendar/ViewBase
+			//		The view to display.
+			// tags:
+			//		protected
+
+			return duration <= 7 ? this.columnView : this.matrixView;
+		},
+		
+		matrixViewRowHeaderClick: function(e){
+			// summary:
+			//		Function called when the cell of a row header of the matrix view is clicked.
+			//		The implementation is doing the foolowing actions:
+			//		- If another row is already expanded, collapse it and then expand the clicked row.
+			//		- If the clicked row is already expadned, collapse it.
+			//		- If no row is expanded, expand the click row.
+			// e: Object
+			//		The row header click event.
+			// tags:
+			//		protected
+
+			var expIndex = this.matrixView.getExpandedRowIndex();
+				if(expIndex == e.index){
+					this.matrixView.collapseRow();
+				}else if(expIndex == -1){
+					this.matrixView.expandRow(e.index);
+				}else{
+					var h = this.matrixView.on("expandAnimationEnd", lang.hitch(this, function(){
+						h.remove();
+						this.matrixView.expandRow(e.index);
+					}));
+					this.matrixView.collapseRow();
+				}
+		},
+		
+		columnViewColumnHeaderClick: function(e){
+			// summary:
+			//		Function called when the cell of a column header of the column view is clicked.
+			//		Show the time range defined by the clicked date.
+			// e: Object
+			//		The column header click event.
+			// tags:
+			//		protected
+
+			var cal = this.dateModule;
+			if(cal.compare(e.date, this._timeInterval[0]) == 0 && this.dateInterval == "day" && this.dateIntervalSteps == 1){
+				this.set("dateInterval", "week");
+			}else{
+				this.set("date", e.date);
+				this.set("dateInterval", "day");
+				this.set("dateIntervalSteps", 1);
+			}
+		},
+		
+		// viewFadeDuration: Integer
+		//		The duration in milliseconds of the fade animation when the current view is changing.
+		viewChangeDuration: 0,
+		
+		_showView: function(oldView, newView){
+			// summary:
+			//		Displays the current view.
+			// oldView: dojox/calendar/ViewBase
+			//		The previously displayed view or null.
+			// newView: dojox/calendar/ViewBase
+			//		The view to display.
+			// tags:
+			//		protected
+
+			if(oldView != null){									
+				domStyle.set(oldView.domNode, "display", "none");							
+			}
+			if(newView != null){												
+				domStyle.set(newView.domNode, "display", "block");
+				newView.resize();				
+				if(!has("ie") || has("ie") > 7){
+					domStyle.set(newView.domNode, "opacity", "1");
+				}
+			}
+		},
+		
+		////////////////////////////////////////////////////
+		//
+		// Store & data
+		//
+		////////////////////////////////////////////////////
+		
+		_setItemsAttr: function(value){
+			this._set("items", value);
+			if(this.currentView){
+				this.currentView.set("items", value);
+				if(!this._isEditing){
+					this.currentView.invalidateRendering();
+				}
+			}
+		},
+		
+		/////////////////////////////////////////////////////
+		//
+		// Time utilities
+		//
+		////////////////////////////////////////////////////
+		
+		floorToDay: function(date, reuse){
+			// summary:
+			//		Floors the specified date to the start of day.
+			// date: Date
+			//		The date to floor.
+			// reuse: Boolean
+			//		Whether use the specified instance or create a new one. Default is false.
+			// returns: Date
+			return timeUtil.floorToDay(date, reuse, this.dateClassObj);
+		},
+		
+		floorToWeek: function(d){
+			// summary:
+			//		Floors the specified date to the beginning of week.
+			// date: Date
+			//		Date to floor.
+			return timeUtil.floorToWeek(d, this.dateClassObj, this.dateModule, this.firstDayOfWeek, this.locale);
+		},
+		
+		newDate: function(obj){
+			// summary:
+			//		Creates a new Date object.
+			// obj: Object
+			//		This object can have several values:
+			//		- the time in milliseconds since gregorian epoch.
+			//		- a Date instance
+			// returns: Date
+			return timeUtil.newDate(obj, this.dateClassObj);			
+		},
+		
+		isToday: function(date){
+			// summary:
+			//		Returns whether the specified date is in the current day.
+			// date: Date
+			//		The date to test.
+			// renderData: Object
+			//		The current renderData
+			// returns: Boolean
+			return timeUtil.isToday(date, this.dateClassObj);
+		},
+		
+		isStartOfDay: function(d){
+			// summary:
+			//		Tests if the specified date represents the starts of day. 
+			// d:Date
+			//		The date to test.
+			// returns: Boolean
+			return timeUtil.isStartOfDay(d, this.dateClassObj, this.dateModule);
+		},
+		
+		floorDate: function(date, unit, steps, reuse){
+			// summary:
+			//		floors the date to the unit.
+			// date: Date
+			//		The date/time to floor.
+			// unit: String
+			//		The unit. Valid values are "minute", "hour", "day".
+			// steps: Integer
+			//		For "day" only 1 is valid.
+			// reuse: Boolean
+			//		Whether use the specified instance or create a new one. Default is false.			
+			// returns: Date
+			return timeUtil.floor(date, unit, steps, reuse, this.classFuncObj);
+		},
+		
+		/////////////////////////////////////////////////////
+		//
+		// Time navigation
+		//
+		////////////////////////////////////////////////////
+		
+		
+		// animateRange: Boolean
+		//		Indicates that the previous/next range method will be animated.
+		animateRange: true,
+		
+		// animationRangeDuration: Integer
+		//		The duration of the next/previous range animation.
+		animationRangeDuration: 400,
+		
+		_animateRange : function(node, toLeft, fadeIn, xFrom, xTo, onEnd){
+			// summary:
+			//		Animates the current view using a synchronous fade and horizontal translation.
+			// toLeft: Boolean
+			//		Whether the view is moved to the left or to the right.
+			// fadeIn: Boolean
+			//		Whether the view is faded in or out.
+			// xFrom: Integer
+			//		Position before the animation
+			// xTo: Integer
+			//		Position after the animation
+			// onEnd: Function
+			//		Function called when the animation is finished.
+			// tags:
+			//		protected
+
+			
+			if(this.animateRangeTimer){ // cleanup previous call not finished
+				clearTimeout(this.animateRangeTimer);
+				delete this.animateRangeTimer;
+			}
+			
+			var fadeFunc = fadeIn ? coreFx.fadeIn : coreFx.fadeOut;								
+			domStyle.set(node, {left: xFrom + "px", right: (-xFrom) + "px"});
+						
+			fx.combine([
+				coreFx.animateProperty({
+					node: node, 
+					properties: {left: xTo, right: -xTo},
+					duration: this.animationRangeDuration/2,
+					onEnd: onEnd									
+				}),
+				fadeFunc({node: node, duration: this.animationRangeDuration/2})
+			]).play();
+		},			
+		
+		// _animRangeOutDir: Boolean
+		//		Direction of the range animation when the view 'leaving' the screen. 
+		//		Valid values are: 
+		//		- null: auto value,
+		//		- "left": hides to left side (right in right to left).
+		//		- "right": hides to right side (left in right to left).
+		_animRangeOutDir: null,
+
+		// _animRangeInDir: Boolean
+		//		Direction of the range animation when the view 'entering' the screen. 
+		//		Valid values are: 
+		//		- null: auto value,
+		//		- "left": shows from left side (right in right to left).
+		//		- "right": shows from  right side (left in right to left).
+		_animRangeOutDir: null,		
+		
+		nextRange: function(){
+			this._animRangeOutDir = "left";
+			this._animRangeInDir = "right";			
+			this._navigate(1);			
+		},
+		
+		previousRange: function(){
+			this._animRangeOutDir = "right";
+			this._animRangeInDir =  "left";			
+			this._navigate(-1);			
+		},
+		
+		_navigate: function(dir){
+			// tags:
+			//		private
+
+			var d = this.get("date");
+			var cal = this.dateModule;
+			
+			if(d == null){
+				var s = this.get("startDate");
+				var e = this.get("endDate");
+				var dur = cal.difference(s, e, "day");
+				if(dir == 1){								
+					e = cal.add(e, "day", 1);
+					this.set("startDate", e);
+					this.set("endDate", cal.add(e, "day", dur));
+				}else{
+					s = cal.add(s, "day", -1);
+					this.set("startDate", cal.add(s, "day", -dur));
+					this.set("endDate", s);
+				}
+			}else{
+				var di = this.get("dateInterval");
+				var dis = this.get("dateIntervalSteps");
+				this.set("date", cal.add(d, di, dir * dis));
+			}
+		},
+		
+		goToday: function(){
+			// summary:
+			//		Changes the displayed time interval to show the current day.
+			//		Sets the date property to the current day, the dateInterval property to "day" and 
+			//		the "dateIntervalSteps" to 1.
+			this.set("date", this.floorToDay(new this.dateClassObj(), true));
+			this.set("dateInterval", "day");
+			this.set("dateIntervalSteps", 1);			
+		},
+		
+		////////////////////////////////////////////////////
+		//
+		// Buttons
+		//
+		////////////////////////////////////////////////////
+		
+		postCreate: function(){
+			this.inherited(arguments);
+			this.configureButtons();
+		},
+		
+		configureButtons: function(){
+			// summary:
+			//		Set the localized labels of the buttons and the event handlers.
+			// tags:
+			//		protected
+
+			var rtl = !this.isLeftToRight();
+			
+			if(this.previousButton){
+				this.previousButton.set("label", _nls[rtl?"nextButton":"previousButton"]);
+				this.own(
+					on(this.previousButton, "click", lang.hitch(this, rtl?this.nextRange:this.previousRange))
+				);	
+			}
+			
+			if(this.nextButton){
+				this.nextButton.set("label", _nls[rtl?"previousButton":"nextButton"]);
+				this.own(
+					on(this.nextButton, "click", lang.hitch(this, rtl?this.previousRange:this.nextRange))
+				);	
+			}
+			
+			if(rtl && this.previousButton && this.nextButton){
+				var t = this.previousButton;
+				this.previousButton = this.nextButton;
+				this.nextButton = t;
+			}
+			
+			if(this.todayButton){
+				this.todayButton.set("label", _nls.todayButton);
+				this.own(
+					on(this.todayButton, "click", lang.hitch(this, this.todayButtonClick))
+				);	
+			}
+			
+			if(this.dayButton){
+				this.dayButton.set("label", _nls.dayButton);
+				this.own(
+					on(this.dayButton, "click", lang.hitch(this, this.dayButtonClick))
+				);
+			}		
+			
+			if(this.weekButton){
+				this.weekButton.set("label", _nls.weekButton);
+				this.own(
+					on(this.weekButton, "click", lang.hitch(this, this.weekButtonClick))
+				);	
+			}		
+
+			if(this.fourDaysButton){
+				this.fourDaysButton.set("label", _nls.fourDaysButton);
+				this.own(
+					on(this.fourDaysButton, "click", lang.hitch(this, this.fourDaysButtonClick))
+				);
+			}
+			
+			if(this.monthButton){
+				this.monthButton.set("label", _nls.monthButton);
+				this.own(
+					on(this.monthButton, "click", lang.hitch(this, this.monthButtonClick))
+				);	
+			}	
+		},
+		
+		todayButtonClick: function(e){
+			// summary:
+			//		The action triggered when the today button is clicked.
+			//		By default, calls the goToday() method.
+
+			this.goToday();							
+		},
+		dayButtonClick: function(e){
+			// summary:
+			//		The action triggerred when the day button is clicked.
+			//		By default, sets the dateInterval property to "day" and 
+			//		the "dateIntervalSteps" to 1.
+
+			if(this.get("date") == null){
+				this.set("date", this.floorToDay(new this.dateClassObj(), true));
+			}			
+			this.set("dateInterval", "day");
+			this.set("dateIntervalSteps", 1);								
+		},
+		
+		weekButtonClick: function(e){
+			// summary:
+			//		The action triggered when the week button is clicked.
+			//		By default, sets the dateInterval property to "week" and 
+			//		the "dateIntervalSteps" to 1.
+			this.set("dateInterval", "week");
+			this.set("dateIntervalSteps", 1);						
+		},
+		fourDaysButtonClick: function(e){
+			// summary:
+			//		The action triggerred when the 4 days button is clicked.
+			//		By default, sets the dateInterval property to "day" and 
+			//		the "dateIntervalSteps" to 4.
+			this.set("dateInterval", "day");
+			this.set("dateIntervalSteps", 4);		
+		},
+		monthButtonClick: function(e){
+			// summary:
+			//		The action triggered when the month button is clicked.
+			//		By default, sets the dateInterval property to "month" and 
+			//		the "dateIntervalSteps" to 1.
+			this.set("dateInterval", "month");
+			this.set("dateIntervalSteps", 1);		
+		},
+					
+		/////////////////////////////////////////////////////
+		//
+		// States item
+		//
+		////////////////////////////////////////////////////
+		
+		updateRenderers: function(obj, stateOnly){
+			if(this.currentView){
+				this.currentView.updateRenderers(obj, stateOnly);
+			}			
+		},
+
+		getIdentity: function(item){
+			return item ? item.id : null; 
+		},
+
+		_setHoveredItem: function(item, renderer){			
+			if(this.hoveredItem && item && this.hoveredItem.id != item.id || 
+				item == null || this.hoveredItem == null){
+				var old = this.hoveredItem;
+				this.hoveredItem = item;
+				
+				this.updateRenderers([old, this.hoveredItem], true);
+				
+				if(item && renderer){					
+					this.currentView._updateEditingCapabilities(item._item ? item._item : item, renderer);
+				}
+			}
+		},
+		
+		// hoveredItem: Object
+		//		Current render item which is under the mouse cursor.
+		hoveredItem: null,
+		
+		isItemHovered: function(item){
+			// summary:
+			//		Returns whether the specified item is hovered or not.
+			// item: Object
+			//		The item.
+			// returns: Boolean								
+			return this.hoveredItem != null && this.hoveredItem.id == item.id;			
+		},
+		
+		////////////////////////////////////////////////////////////////////////
+		//
+		// Editing 
+		//
+		////////////////////////////////////////////////////////////////////////
+
+		isItemEditable: function(item, rendererKind){
+			// summary:
+			//		Computes whether particular item renderer can be edited.
+			//		By default it is using the editable property value.
+			// item: Object
+			//		The data item represented by the renderer.
+			// rendererKind: String
+			//		The kind of renderer.
+			// returns: Boolean
+			return this.editable;
+		},
+		
+		isItemMoveEnabled: function(item, rendererKind){
+			// summary:
+			//		Computes whether particular item renderer can be moved.
+			//		By default it is using the moveEnabled property value.
+			// item: Object
+			//		The data item represented by the renderer.
+			// rendererKind: String
+			//		The kind of renderer.
+			// returns: Boolean
+			return this.isItemEditable(item, rendererKind) && this.moveEnabled;
+		},
+		
+		isItemResizeEnabled: function(item, rendererKind){
+			// summary:
+			//		Computes whether particular item renderer can be resized.
+			//		By default it is using the resizedEnabled property value.
+			// item: Object
+			//		The data item represented by the renderer.
+			// rendererKind: String
+			//		The kind of renderer.
+			// returns: Boolean
+			
+			return this.isItemEditable(item, rendererKind) && this.resizeEnabled;
+		},
+		
+
+		////////////////////////////////////////////////////////////////////////
+		//
+		// Widget events
+		//
+		////////////////////////////////////////////////////////////////////////
+		
+		onGridClick: function(e){
+			// summary:
+			//		Event dispatched when the grid has been clicked.
+			// e: __GridClickEventArgs
+			//		The event dispatched when the grid is clicked.
+			// tags:
+			//		callback
+
+		},
+		
+		onGridDoubleClick: function(e){
+			// summary:
+			//		Event dispatched when the grid has been double-clicked.	
+			// e: __GridClickEventArgs
+			//		The event dispatched when the grid is double-clicked.
+			// tags:
+			//		callback
+		},	
+		
+		onItemClick: function(e){
+			// summary:
+			//		Event dispatched when an item renderer has been clicked.
+			// e: __ItemMouseEventArgs
+			//		The event dispatched when an item is clicked.
+			// tags:
+			//		callback
+		},
+		
+		onItemDoubleClick: function(e){
+			// summary:
+			//		Event dispatched when an item renderer has been double-clicked.
+			// e: __ItemMouseEventArgs
+			//		The event dispatched when an item is double-clicked.
+			// tags:
+			//		callback
+		},
+		
+		onItemContextMenu: function(e){
+			// summary:
+			//		Event dispatched when an item renderer has been context-clicked.
+			// e: __ItemMouseEventArgs
+			//		The event dispatched when an item is context-clicked.
+			// tags:
+			//		callback
+		},
+		
+		onItemEditBegin: function(e){
+			// summary:
+			//		Event dispatched when the item is entering the editing mode.
+			// e: __itemEditingEventArgs
+			//		The editing event.
+			// tags:
+			//		callback
+		},
+		
+		onItemEditEnd: function(e){
+			// summary:
+			//		Event dispatched when the item is leaving the editing mode.
+			// e: __itemEditingEventArgs
+			//		The editing event.
+			// tags:
+			//		callback
+		},
+		
+		onItemEditBeginGesture: function(e){
+			// summary:
+			//		Event dispatched when an editing gesture is beginning.
+			// e: __itemEditingEventArgs
+			//		The editing event.
+			// tags:
+			//		callback
+		},
+		
+		onItemEditMoveGesture: function(e){
+			// summary:
+			//		Event dispatched during a move editing gesture.		
+			// e: __itemEditingEventArgs
+			//		The editing event.
+			// tags:
+			//		callback
+		},
+		
+		onItemEditResizeGesture: function(e){
+			// summary:
+			//		Event dispatched during a resize editing gesture.
+			// e: __itemEditingEventArgs
+			//		The editing event.
+			// tags:
+			//		callback
+		},
+		
+		onItemEditEndGesture: function(e){
+			// summary:
+			//		Event dispatched at the end of an editing gesture.
+			// e: __itemEditingEventArgs
+			//		The editing event.
+			// tags:
+			//		callback
+		},
+		
+		onItemRollOver: function(e){
+			// Summary:
+			//		Event dispatched when the mouse cursor in going over an item renderer.
+			// e: __ItemMouseEventArgs
+			//		The event dispatched when the mouse cursor enters in the item renderer.
+			// tags:
+			//		callback
+		},
+		
+		onItemRollOut: function(e){
+			// Summary:
+			//		Event dispatched when the mouse cursor in leaving an item renderer.
+			// e: __ItemMouseEventArgs
+			//		The event dispatched when the mouse cursor enters in the item renderer.
+			// tags:
+			//		callback
+		},
+		
+		onColumnHeaderClick: function(e){
+			// summary:
+			//		Event dispatched when a column header cell is dispatched.
+			// e: __HeaderClickEventArgs
+			//		Header click event.
+			// tags:
+			//		callback
+		},
+				
+		onRowHeaderClick: function(e){
+			// summary:
+			//		Event dispatched when a row header cell is clicked.
+			// e: __HeaderClickEventArgs
+			//		Header click event.
+			// tags:
+			//		callback
+		},
+		
+		onExpandRendererClick: function(e){
+			// summary:
+			//		Event dispatched when an expand renderer is clicked.
+			// e: __ExpandRendererClickEventArgs
+			//		Expand renderer click event.
+			// tags:
+			//		callback
+		},
+		
+		_onRendererCreated: function(e){
+			this.onRendererCreated(e);
+		},
+		
+		onRendererCreated: function(e){
+			// summary:
+			//		Event dispatched when an item renderer has been created.
+			// e: __rendererLifecycleEventArgs
+			//		The renderer lifecycle event.
+			// tags:
+			//		callback
+		},
+		
+		_onRendererRecycled: function(e){
+			this.onRendererRecycled(e);
+		},
+		
+		onRendererRecycled: function(e){
+			// summary:
+			//		Event dispatched when an item renderer has been recycled.
+			// e: __rendererLifecycleEventArgs
+			//		The renderer lifecycle event.
+			// tags:
+			//		callback
+		},
+		
+		_onRendererReused: function(e){
+			this.onRendererReused(e);
+		},
+		
+		onRendererReused: function(e){
+			// summary:
+			//		Event dispatched when an item renderer that was recycled is reused.
+			// e: __rendererLifecycleEventArgs
+			//		The renderer lifecycle event.
+			// tags:
+			//		callback
+		},
+		
+		_onRendererDestroyed: function(e){
+			this.onRendererDestroyed(e);
+		},
+		
+		onRendererDestroyed: function(e){
+			// summary:
+			//		Event dispatched when an item renderer is destroyed.
+			// e: __rendererLifecycleEventArgs
+			//		The renderer lifecycle event.
+			// tags:
+			//		callback
+		},
+		
+		_onRenderersLayoutDone: function(view){
+			this.onRenderersLayoutDone(view);
+		},
+		
+		onRenderersLayoutDone: function(view){
+			// summary:
+			//		Event triggered when item renderers layout has been done.
+			// view: dojox/calendar/ViewBase
+			//		The view that has been laid-out.
+			// tags:
+			//		callback
+		}
+
+	});
+});
diff --git a/dojox/calendar/ColumnView.js b/dojox/calendar/ColumnView.js
new file mode 100644
index 0000000..cfa4770
--- /dev/null
+++ b/dojox/calendar/ColumnView.js
@@ -0,0 +1,257 @@
+define([    
+"dojo/_base/declare", 
+"dojo/_base/event", 
+"dojo/_base/lang", 
+"dojo/_base/sniff", 
+"dojo/_base/fx", 
+"dojo/dom",
+"dojo/dom-class",
+"dojo/dom-style", 
+"dojo/dom-geometry", 
+"dojo/dom-construct", 
+"dojo/on",
+"dojo/date", 
+"dojo/date/locale", 
+"dojo/query",	
+"dojox/html/metrics",
+"./SimpleColumnView", 
+"dojo/text!./templates/ColumnView.html", 
+"./ColumnViewSecondarySheet"],
+
+function(
+	declare, 
+	event, 
+	lang, 
+	has, 
+	fx, 
+	dom, 
+	domClass, 
+	domStyle,
+	domGeometry, 
+	domConstruct,
+	on,
+	date, 
+	locale, 
+	query, 
+	metrics,
+	SimpleColumnView, 
+	template, 
+	ColumnViewSecondarySheet){
+
+	return declare("dojox.calendar.ColumnView", SimpleColumnView, {
+
+		// summary:		
+		//		This class defines a simple column view that also uses a secondary 
+		//		sheet to display long or all day events. 
+		//		By default an dojox.calendar.ColumnViewSecondarySheet instance is created.
+		//		Set the secondarySheetClass property to define the class to instantiate,
+		//		for example to mix the default class with Mouse, Keyboard or Touch plugins. 
+
+		templateString: template,
+	
+		baseClass: "dojoxCalendarColumnView",
+		
+		// secondarySheetClass: Class
+		//		The secondary sheet class, by default dojox.calendar.ColumnViewSecondarySheet.
+		secondarySheetClass: ColumnViewSecondarySheet,
+		
+		// secondarySheetProps: Object
+		//		Secondary sheet constructor parameters.
+		secondarySheetProps: null,
+		
+		// headerPadding: Integer
+		//		Padding between the header (composed of the secondary sheet and the column header) 
+		//		and the primary sheet.
+		headerPadding: 3,
+		
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(this.secondarySheetNode){
+				var args = lang.mixin({owner: this}, this.secondarySheetProps);
+				this.secondarySheet = new this.secondarySheetClass(args, this.secondarySheetNode);				
+				this.secondarySheetNode = this.secondarySheet.domNode;				
+			}
+		},
+			
+		destroy: function(preserveDom){
+			if(this.secondarySheet){
+				this.secondarySheet.destroy(preserveDom);
+			}
+			this.inherited(arguments);
+		},
+		
+		_setVisibility: function(value){
+			// tags:
+			//		private
+
+			this.inherited(arguments);
+			if(this.secondarySheet){
+				this.secondarySheet._setVisibility(value);
+			}
+		},
+		
+		
+		resize: function(e){
+			// tags:
+			//		private
+			
+			this.inherited(arguments);
+			if(this.secondarySheet){
+				this.secondarySheet.resize(e);
+			}
+		},
+
+		invalidateLayout: function(){
+			// tags:
+			//		private
+
+			this._layoutRenderers(this.renderData);
+			if(this.secondarySheet){
+				this.secondarySheet._layoutRenderers(this.secondarySheet.renderData);
+			}
+		},
+		
+		onRowHeaderClick: function(e){
+			// summary:
+			//		Event dispatched when the row header cell of the secondary sheet is clicked.
+			// tags:
+			//		callback
+
+		},
+		
+		resizeSecondarySheet: function(height){
+			// summary:
+			//		Resizes the secondary sheet header and relayout the other sub components according this new height.
+			//		Warning: this method is only available for the default template and default CSS.
+			// height: Integer
+			//		The new height in pixels.
+			if(this.secondarySheetNode){
+				var headerH = domGeometry.getMarginBox(this.header).h;
+				domStyle.set(this.secondarySheetNode, "height", height+"px");
+				this.secondarySheet._resizeHandler(null, true);
+				var top = (height + headerH + this.headerPadding)+"px";
+				domStyle.set(this.scrollContainer, "top", top);
+				if(this.vScrollBar){
+					domStyle.set(this.vScrollBar, "top", top);
+				}
+			}
+		},
+		
+		updateRenderers: function(obj, stateOnly){
+			this.inherited(arguments);
+			if(this.secondarySheet){
+				this.secondarySheet.updateRenderers(obj, stateOnly);
+			}
+		},
+		
+		_setItemsAttr: function(value){
+			this.inherited(arguments);
+			if(this.secondarySheet){
+				this.secondarySheet.set("items", value);
+			}
+		},
+		
+		_setStartDateAttr: function(value){
+			this.inherited(arguments);
+			if(this.secondarySheet){
+				this.secondarySheet.set("startDate", value);
+			}
+		},
+		
+		_setColumnCountAttr: function(value){
+			this.inherited(arguments);
+			if(this.secondarySheet){
+				this.secondarySheet.set("columnCount", value);
+			}
+		},
+		
+		_setHorizontalRendererAttr: function(value){
+			if(this.secondarySheet){
+				this.secondarySheet.set("horizontalRenderer", value);
+			}
+		},
+		
+		_getHorizontalRendererAttr: function(){
+			if(this.secondarySheet){
+				return this.secondarySheet.get("horizontalRenderer");
+			}
+            return null;
+		},
+		
+		_setExpandRendererAttr: function(value){
+			if(this.secondarySheet){
+				this.secondarySheet.set("expandRenderer", value);
+			}
+		},
+		
+		_getExpandRendererAttr: function(){
+			if(this.secondarySheet){
+				return this.secondarySheet.get("expandRenderer");
+			}
+            return null;
+		},
+					
+		_setTextDirAttr: function(value){
+			this.secondarySheet.set("textDir", value);
+			this._set("textDir", value);
+		},
+		
+		_defaultItemToRendererKindFunc: function(item){
+			return item.allDay ? null : "vertical"; // String
+		},
+		
+		getSecondarySheet: function(){
+			// summary:
+			//		Returns the secondary sheet
+			// returns: dojox/calendar/MatrixView
+			return this.secondarySheet;
+		},
+		
+		_onGridTouchStart: function(e){
+			this.inherited(arguments);
+			this._doEndItemEditing(this.secondarySheet, "touch");
+		},
+		
+		_onGridMouseDown: function(e){
+			this.inherited(arguments);
+			this._doEndItemEditing(this.secondarySheet, "mouse");
+		},
+		
+		_configureScrollBar: function(renderData){
+
+
+			this.inherited(arguments);
+			if(this.secondarySheetNode){
+				var atRight = this.isLeftToRight() ? true : this.scrollBarRTLPosition == "right";
+				domStyle.set(this.secondarySheetNode, atRight ? "right" : "left", renderData.scrollbarWidth + "px");
+				domStyle.set(this.secondarySheetNode, atRight ? "left" : "right", "0");
+			}
+		},
+		
+		_refreshItemsRendering: function(){
+			this.inherited(arguments);
+			if(this.secondarySheet){
+				var rd = this.secondarySheet.renderData;
+				this.secondarySheet._computeVisibleItems(rd);
+				this.secondarySheet._layoutRenderers(rd);
+			}			
+		},
+		
+		_layoutRenderers: function(renderData){
+			if(!this.secondarySheet._domReady){
+				this.secondarySheet._domReady = true;
+				this.secondarySheet._layoutRenderers(this.secondarySheet.renderData);
+			}
+			
+			this.inherited(arguments);
+		},
+		
+		invalidateRendering: function(){
+			if(this.secondarySheet){
+				this.secondarySheet.invalidateRendering();
+			}
+			this.inherited(arguments);
+		}
+
+	});
+});
diff --git a/dojox/calendar/ColumnViewSecondarySheet.js b/dojox/calendar/ColumnViewSecondarySheet.js
new file mode 100644
index 0000000..d44c10e
--- /dev/null
+++ b/dojox/calendar/ColumnViewSecondarySheet.js
@@ -0,0 +1,105 @@
+define(["./MatrixView", "dojo/text!./templates/ColumnViewSecondarySheet.html",
+	"dojo/_base/html", "dojo/_base/declare", "dojo/_base/event", "dojo/_base/lang", 
+	"dojo/_base/sniff", "dojo/dom", "dojo/dom-class", "dojo/dom-geometry", "dojo/dom-construct", 
+	"dojo/date", "dojo/date/locale", "dojo/query", "dojox/html/metrics", "dojo/_base/fx", "dojo/on", 
+	"dojo/window"],
+	
+	function(MatrixView, template, html, declare, event, lang, has, dom, domClass, domGeometry, domConstruct, 
+		date, locale, query, metrics, fx, on, win){
+	
+	return declare("dojox.calendar.ColumnViewSecondarySheet", MatrixView, {
+		
+		// summary:
+		//		This class defines a matrix view designed to be embedded in a column view, 
+		//		usually to display long or all day events on one row. 
+
+		templateString: template,
+	
+		rowCount: 1,
+		
+		cellPaddingTop: 4,
+		
+		roundToDay: false,
+		
+		_defaultHeight: -1,
+		
+		layoutDuringResize: true,
+		
+		_defaultItemToRendererKindFunc: function(item){
+			// tags:
+			//		private
+			return item.allDay ? "horizontal" : null;
+		},
+		
+		_formatGridCellLabel: function(){return null;},
+		
+		_formatRowHeaderLabel: function(){return null;},
+		
+		
+		// events redispatch
+		__fixEvt:function(e){
+			e.sheet = "secondary";
+			e.source = this;
+			return e;
+		},
+		
+		_dispatchCalendarEvt: function(e, name){
+			e = this.inherited(arguments);
+			if(this.owner.owner){ // the calendar
+				this.owner.owner[name](e);
+			}
+		},
+		
+		_layoutExpandRenderers: function(index, hasHiddenItems, hiddenItems){
+			if(!this.expandRenderer){
+				return;
+			}
+			var h = domGeometry.getMarginBox(this.domNode).h;
+			if(this._defaultHeight == -1){
+				this._defaultHeight = h;
+			}
+			if(this._defaultHeight != -1 && this._defaultHeight != h && h >= this._getExpandedHeight()){
+				this._layoutExpandRendererImpl(0, this._expandedRowCol, null, true);
+			}else{
+				this.inherited(arguments);
+			}
+		},
+	
+		expandRendererClickHandler: function(e, renderer){
+			// summary:
+			//		Default action when an expand renderer is clicked.
+			//		This method will expand the secondary sheet to show all the events.
+			// e: Event
+			//		The mouse event.
+			// renderer: Object
+			//		The renderer that was clicked.
+			// tags:
+			//		callback
+
+			
+			event.stop(e);
+			var h = domGeometry.getMarginBox(this.domNode).h;			
+			if(this._defaultHeight == h || h < this._getExpandedHeight()){
+				this._expandedRowCol = renderer.columnIndex;
+				this.owner.resizeSecondarySheet(this._getExpandedHeight());
+			}else{
+				this.owner.resizeSecondarySheet(this._defaultHeight);
+			}
+		},
+		
+		_getExpandedHeight: function(){
+			// tags:
+			//		private
+
+			return this.naturalRowsHeight[0] + this.expandRendererHeight + this.verticalGap + this.verticalGap;
+		},
+		
+		_layoutRenderers: function(renderData){
+			if(!this._domReady){			
+				return;
+			}
+			this.inherited(arguments);
+		}
+
+	});
+});
diff --git a/dojox/calendar/ExpandRenderer.js b/dojox/calendar/ExpandRenderer.js
new file mode 100644
index 0000000..6012d5a
--- /dev/null
+++ b/dojox/calendar/ExpandRenderer.js
@@ -0,0 +1,144 @@
+define([
+"dojo/_base/declare", 
+"dojo/_base/lang", 
+"dojo/_base/event", 
+"dojo/_base/window", 
+"dojo/on", 
+"dojo/dom-class", 
+"dojo/dom-style",
+"dijit/_WidgetBase", 
+"dijit/_TemplatedMixin", 
+"dojo/text!./templates/ExpandRenderer.html"],
+	 
+function(
+declare, 
+lang, 
+event, 
+win, 
+on, 
+domClass, 
+domStyle, 
+_WidgetBase, 
+_TemplatedMixin, 
+template){
+	
+	return declare("dojox.calendar.ExpandRenderer", [_WidgetBase, _TemplatedMixin], {
+		
+		// summary:
+		//		The default renderer display in MatrixView cells where some item renderers cannot be displayed because of size constraints.
+		
+		templateString: template,
+		
+		baseClass: "dojoxCalendarExpand",
+		
+		// owner: dojox/calendar/_ViewBase
+		//		The view that contains this renderer.
+		owner: null,
+
+		// focused: Boolean
+		//		Indicates that the renderer is focused.
+		focused: false,
+
+		// up: Boolean
+		//		Indicates that the mouse cursor is over renderer.
+		up: false,
+
+		// down: Boolean
+		//		Indicates that the renderer is pressed.
+		down: false,
+
+		// date: Date
+		//		The date displayed by the cell where this renderer is used.
+		date: null,
+
+		// items: Object[]
+		//		List of items that are not displayed in the cell because of the size constraints.
+		items: null,
+		
+		// rowIndex: Integer
+		//		Row index where this renderer is used.
+		rowIndex: -1,
+		
+		// columnIndex: Integer
+		//		Column index where this renderer is used.
+		columnIndex: -1,
+		
+		_setExpandedAttr: function(value){
+			domStyle.set(this.expand, "display", value ? "none" : "inline-block");
+			domStyle.set(this.collapse, "display", value ? "inline-block" : "none"); 
+			this._set("expanded", value);
+		},
+
+		_setDownAttr: function(value){
+			this._setState("down", value, "Down");
+		},
+
+		_setUpAttr: function(value){
+			this._setState("up", value, "Up");
+		},
+
+		_setFocusedAttr: function(value){
+			this._setState("focused", value, "Focused");
+		},
+
+		_setState: function(prop, value, cssClass){
+			if (this[prop] != value){
+				var tn = this.stateNode || this.domNode;
+				domClass[value ? "add" : "remove"](tn, cssClass);
+				this._set(prop, value);
+			}	
+		},
+
+		_onClick: function(e){
+			// tags:
+			//		private
+
+			if(this.owner && this.owner.expandRendererClickHandler){
+				this.owner.expandRendererClickHandler(e, this);
+			}
+		},
+
+		_onMouseDown: function(e){
+			// tags:
+			//		private
+
+			event.stop(e);
+			this.set("down", true);
+		},
+
+		_onMouseUp: function(e){
+			// tags:
+			//		private
+
+			this.set("down", false);
+		},
+
+		_onMouseOver: function(e){
+			// tags:
+			//		private
+
+			if(!this.up){
+				var buttonDown = e.button == 1;
+				this.set("up", !buttonDown);
+				this.set("down", buttonDown);
+			}
+		},
+
+		_onMouseOut: function(e){
+			// tags:
+			//		private
+
+			var node = e.relatedTarget;
+			while(node != e.currentTarget && node != win.doc.body && node != null){
+				node = node.parentNode;
+			}
+			if(node == e.currentTarget){
+				return;
+			}
+			this.set("up", false);
+			this.set("down", false);
+		}
+
+	});
+
+});
diff --git a/dojox/calendar/HorizontalRenderer.js b/dojox/calendar/HorizontalRenderer.js
new file mode 100644
index 0000000..b9a0c0a
--- /dev/null
+++ b/dojox/calendar/HorizontalRenderer.js
@@ -0,0 +1,92 @@
+define([
+"dojo/_base/declare", 
+"dojo/dom-style", 
+"dijit/_WidgetBase", 
+"dijit/_TemplatedMixin",
+"dojox/calendar/_RendererMixin", 
+"dojo/text!./templates/HorizontalRenderer.html"],
+	 
+function(
+declare, 
+domStyle, 
+_WidgetBase, 
+_TemplatedMixin, 
+_RendererMixin, 
+template){
+	
+	return declare("dojox.calendar.HorizontalRenderer", [_WidgetBase, _TemplatedMixin, _RendererMixin], {
+		
+		// summary:
+		//		The default item horizontal renderer. 
+		
+		templateString: template,
+		
+		_orientation: "horizontal",
+		
+		visibilityLimits: {
+			resizeStartHandle: 50,
+			resizeEndHandle: -1,
+			summaryLabel: 15,
+			startTimeLabel: 32,
+			endTimeLabel: 30
+		},
+		
+		_displayValueMap: {
+			"beforeIcon": "inline",
+			"afterIcon": "inline"
+		},
+		
+		_displayValue: "inline",
+		
+		// arrowPadding: Integer
+		//		The padding size in pixels to apply to the label container on left and/or right side, to show the arrows correctly.
+		arrowPadding: 12, 
+		
+		_isElementVisible: function(elt, startHidden, endHidden, size){
+			var d;
+			var ltr = this.isLeftToRight();
+			
+			if(elt == "startTimeLabel"){
+				if(this.labelContainer && (ltr && endHidden || !ltr && startHidden)){
+					domStyle.set(this.labelContainer, "marginRight", this.arrowPadding+"px");
+				}else{
+					domStyle.set(this.labelContainer, "marginRight", 0);
+				}
+				if(this.labelContainer && (!ltr && endHidden || ltr && startHidden)){
+					domStyle.set(this.labelContainer, "marginLeft", this.arrowPadding+"px");
+				}else{
+					domStyle.set(this.labelContainer, "marginLeft", 0);
+				}
+			}
+			
+			switch(elt){
+				case "startTimeLabel":
+					d = this.item.startTime;
+					if(this.item.allDay || this.owner.isStartOfDay(d)){
+						return false;
+					}
+					break;
+				case "endTimeLabel":
+					d = this.item.endTime;
+					if(this.item.allDay || this.owner.isStartOfDay(d)){
+						return false;
+					}
+					break;
+			}
+			return this.inherited(arguments);
+		},
+		
+		getDisplayValue: function(part){
+			var res = this._displayValueMap[part];
+			if(res){
+				return res;
+			}
+			return this._displayValue;
+		},
+		
+		postCreate: function() {
+			this.inherited(arguments);
+			this._applyAttributes();
+		}
+	});
+});
diff --git a/dojox/calendar/Keyboard.js b/dojox/calendar/Keyboard.js
new file mode 100755
index 0000000..10d108e
--- /dev/null
+++ b/dojox/calendar/Keyboard.js
@@ -0,0 +1,349 @@
+define(["dojo/_base/array", "dojo/_base/lang", "dojo/_base/declare", "dojo/on", "dojo/_base/event", "dojo/keys"],
+	function(arr, lang, declare, on, event, keys){
+	
+	return declare("dojox.calendar.Keyboard", null, {
+
+		// summary:
+		//		This mixin is managing the keyboard interactions on a calendar view.
+		
+		// keyboardUpDownUnit: String
+		//		Unit used during editing of an event using the keyboard and the up or down keys were pressed. Valid values are "week", "day", "hours" "minute".
+		keyboardUpDownUnit: "minute",
+		
+		// keyboardUpDownSteps: Integer
+		//		Steps used during editing of an event using the keyboard and the up or down keys were pressed.		
+		keyboardUpDownSteps: 15,		
+		
+		// keyboardLeftRightUnit: String
+		//		Unit used during editing of an event using the keyboard and the left or right keys were pressed. Valid values are "week", "day", "hours" "minute".
+		keyboardLeftRightUnit: "day",
+		
+		// keyboardLeftRightSteps: Integer
+		//		Unit used during editing of an event using the keyboard and the left or right keys were pressed.		
+		keyboardLeftRightSteps: 1,
+
+		// allDayKeyboardUpDownUnit: Integer
+		//		Steps used during editing of an all day event using the keyboard and the up or down keys were pressed.
+		allDayKeyboardUpDownUnit: "day",
+		
+		// allDayKeyboardUpDownSteps: String
+		//		Unit used during editing of an all day event using the keyboard and the up or down keys were pressed. Valid values are "week", "day", "hours" "minute".		
+		allDayKeyboardUpDownSteps: 7,
+		
+		// allDayKeyboardLeftRightUnit: Integer
+		//		Steps used during editing of an all day event using the keyboard and the up or down keys were pressed.
+		allDayKeyboardLeftRightUnit: "day",
+		
+		// allDayKeyboardLeftRightSteps: String
+		//		Unit used during editing of an all day event using the keyboard and the left or right keys were pressed. Valid values are "week", "day", "hours" "minute".
+		allDayKeyboardLeftRightSteps: 1,
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this._viewHandles.push(on(this.domNode, "keydown", lang.hitch(this, this._onKeyDown)));
+		},
+		
+		// resizeModfier: String
+		//		The modifier used to determine if the item is resized instead moved during the editing on an item.
+		resizeModifier: "ctrl",
+
+		// maxScrollAnimationDuration: Number
+		//		The duration in milliseconds to scroll the entire view. 
+		//		The scroll speed is constant when scrolling to show an item renderer. 
+		maxScrollAnimationDuration: 1000,
+		
+		///////////////////////////////////////////////////////////////
+		//
+		// Focus management
+		//
+		//////////////////////////////////////////////////////////////
+		
+		// tabIndex: String
+		//		Order fields are traversed when user hits the tab key
+		tabIndex: "0",
+		
+		// focusedItem: Object
+		//		The data item that currently has the focus.
+		focusedItem: null,
+		
+		_isItemFocused: function(item){
+			return this.focusedItem != null && this.focusedItem.id == item.id;
+		},
+
+		_setFocusedItemAttr: function(value){
+			if(value != this.focusedItem){
+				var old = this.focusedItem;
+				this._set("focusedItem", value);
+				this.updateRenderers([old, this.focusedItem], true);
+				this.onFocusChange({
+					oldValue: old,
+					newValue: value
+				});
+			}
+			if(value != null){
+				if(this.owner != null && this.owner.get("focusedItem") != null){
+					this.owner.set("focusedItem", null);
+				}
+				if(this._secondarySheet != null && this._secondarySheet.set("focusedItem") != null){
+					this._secondarySheet.set("focusedItem", null);
+				}
+			}			
+		},
+		
+		onFocusChange: function(e){
+			// summary:
+			//		Event dispatched when the focus has changed.
+			// tags:
+			//		callback
+
+		},
+
+		// showFocus: Boolean
+		//		Show or hide the focus graphic feedback on item renderers.
+		showFocus: false,		
+		
+		_focusNextItem: function(dir){			
+			// summary:
+			//		Moves the focus to the next item in the specified direction.
+			//		If there is no current child focused, the first (dir == 1) or last (dir == -1) is focused.
+			// dir: Integer
+			//		The direction of the next child to focus.
+			//
+			//		- 1: Move focus to the next item in the list.
+			//		- -1: Move focus to the previous item in the list.
+			
+			if(!this.renderData || !this.renderData.items || this.renderData.items.length == 0){
+				return null;
+			}
+			
+			var index = -1;
+			var list = this.renderData.items;
+			var max = list.length - 1;
+			var focusedItem = this.get("focusedItem");
+			
+			// find current index.
+			if(focusedItem == null){
+				index = dir > 0 ? 0 : max;
+			}else{
+				arr.some(list, lang.hitch(this, function(item, i){
+					var found = item.id == focusedItem.id;
+					if(found){
+						index = i;
+					}
+					return found;
+				}));
+				index = this._focusNextItemImpl(dir, index, max);
+			}
+			
+			// find the first item with renderers.
+			var reachedOnce = false;
+			var old = -1;
+			
+			while(old != index && (!reachedOnce || index != 0)){
+				
+				if(!reachedOnce && index == 0){
+					reachedOnce = true;
+				}
+				
+				var item = list[index];
+				
+				if(this.itemToRenderer[item.id] != null){
+					// found item
+					this.set("focusedItem", item);
+					return;
+				}
+				old = index;				
+				index = this._focusNextItemImpl(dir, index, max);
+				
+			}						
+		},
+		
+		_focusNextItemImpl: function(dir, index, max){
+			// tags:
+			//		private
+
+			if(index == -1){ // not found should not occur
+				index = dir > 0 ? 0 : max;
+			}else{				
+				if(index == 0 && dir == -1 || index == max && dir == 1){
+					return index;
+				}				
+				index = dir > 0 ? ++index : --index;					
+			}			
+			return index; 	
+		},
+		
+		///////////////////////////////////////////////////////////
+		//
+		// Keyboard
+		//
+		//////////////////////////////////////////////////////////
+
+		_handlePrevNextKeyCode: function(e, dir){
+			// tags:
+			//		private
+
+			if(!this.isLeftToRight()){
+				dir = dir == 1 ? -1 : 1;
+			}
+			this.showFocus = true;
+			this._focusNextItem(dir);
+			
+			var focusedItem = this.get("focusedItem");
+			
+			if(!e.ctrlKey && focusedItem){
+				this.set("selectedItem", focusedItem);
+			}
+
+			if(focusedItem){
+				this.ensureVisibility(focusedItem.startTime, focusedItem.endTime, "both", undefined, this.maxScrollAnimationDuration);
+			}
+		},
+
+		_keyboardItemEditing: function(e, dir){
+			// tags:
+			//		private
+
+			event.stop(e);
+
+			var p = this._edProps;
+
+			var unit, steps; 
+
+			if(p.editedItem.allDay || this.roundToDay || p.rendererKind == "label"){
+				unit = dir == "up" || dir == "down" ? this.allDayKeyboardUpDownUnit : this.allDayKeyboardLeftRightUnit; 
+				steps = dir == "up" || dir == "down" ? this.allDayKeyboardUpDownSteps : this.allDayKeyboardLeftRightSteps;
+			}else{
+				unit = dir == "up" || dir == "down" ? this.keyboardUpDownUnit : this.keyboardLeftRightUnit; 
+				steps = dir == "up" || dir == "down" ? this.keyboardUpDownSteps : this.keyboardLeftRightSteps;
+			}			
+						
+			if(dir == "up" || !this.isLeftToRight() && dir == "right" || 
+				 this.isLeftToRight() && dir == "left"){
+				steps = -steps;
+			}
+						
+			var editKind = e[this.resizeModifier+"Key"] ? "resizeEnd" : "move";
+			
+			var d = editKind == "resizeEnd" ? p.editedItem.endTime : p.editedItem.startTime;
+			
+			var newTime = this.renderData.dateModule.add(d, unit, steps);
+			
+			this._startItemEditingGesture([d], editKind, "keyboard", e);
+			this._moveOrResizeItemGesture([newTime], "keyboard", e);
+			this._endItemEditingGesture(editKind, "keyboard", e, false);
+			
+			if(editKind == "move"){
+				if(this.renderData.dateModule.compare(newTime, d) == -1){
+					this.ensureVisibility(p.editedItem.startTime, p.editedItem.endTime, "start");
+				}else{
+					this.ensureVisibility(p.editedItem.startTime, p.editedItem.endTime, "end");
+				}				
+			}else{ // resize end only
+				this.ensureVisibility(p.editedItem.startTime, p.editedItem.endTime, "end");	
+			}						
+		},
+						
+		_onKeyDown: function(e){
+			// tags:
+			//		private
+
+			var focusedItem = this.get("focusedItem");
+			
+			switch(e.keyCode){
+
+				case keys.ESCAPE:
+
+					if(this._isEditing){
+						
+						if(this._editingGesture){
+							this._endItemEditingGesture("keyboard", e, true);
+						}
+						
+						this._endItemEditing("keyboard", true);
+
+						this._edProps = null;
+					}
+					break;
+
+				case keys.SPACE:
+
+					event.stop(e); // prevent browser shortcut
+
+					if(focusedItem != null){
+						this.setItemSelected(focusedItem, e.ctrlKey ? !this.isItemSelected(focusedItem) : true);
+					}
+					break;
+
+				case keys.ENTER:
+
+					event.stop(e); // prevent browser shortcut
+
+					if(focusedItem != null){
+
+						if(this._isEditing){
+							this._endItemEditing("keyboard", false);
+						}else{
+							
+							var renderers = this.itemToRenderer[focusedItem.id];
+								
+							if(renderers && renderers.length > 0 && this.isItemEditable(focusedItem, renderers[0].kind)){
+
+								this._edProps = {
+									renderer: renderers[0],
+									rendererKind: renderers[0].kind,
+									tempEditedItem: focusedItem,
+									liveLayout: this.liveLayout
+								};
+
+								this.set("selectedItem", focusedItem);
+
+								this._startItemEditing(focusedItem, "keyboard");
+							}
+						}
+					}
+					break;
+
+				case keys.LEFT_ARROW:
+				
+					event.stop(e); // prevent browser shortcut
+					
+					if(this._isEditing){
+						this._keyboardItemEditing(e, "left");
+					}else{
+						this._handlePrevNextKeyCode(e, -1);
+					}				
+					break;
+					
+				case keys.RIGHT_ARROW:
+				
+					event.stop(e); // prevent browser shortcut
+					
+					if(this._isEditing){
+						this._keyboardItemEditing(e, "right");
+					}else{
+						this._handlePrevNextKeyCode(e, 1);
+					}
+					break;
+				
+				case keys.UP_ARROW:
+					if(this._isEditing){
+						this._keyboardItemEditing(e, "up");
+					}else if(this.scrollable){
+						this.scrollView(-1);
+					}
+					break;
+					
+				case keys.DOWN_ARROW:
+					if(this._isEditing){
+						this._keyboardItemEditing(e, "down");
+					}else if(this.scrollable){
+						this.scrollView(1);
+					}
+					break;
+					
+			}
+			
+		}
+	});
+});
diff --git a/dojox/calendar/LICENSE b/dojox/calendar/LICENSE
new file mode 100755
index 0000000..b064ab1
--- /dev/null
+++ b/dojox/calendar/LICENSE
@@ -0,0 +1,195 @@
+Dojo is available under *either* the terms of the modified BSD license *or* the
+Academic Free License version 2.1. As a recipient of Dojo, you may choose which
+license to receive this code under (except as noted in per-module LICENSE
+files). Some modules may not be the copyright of the Dojo Foundation. These
+modules contain explicit declarations of copyright in both the LICENSE files in
+the directories in which they reside and in the code itself. No external
+contributions are allowed under licenses which are fundamentally incompatible
+with the AFL or BSD licenses that Dojo is distributed under.
+
+The text of the AFL and BSD licenses is reproduced below. 
+
+-------------------------------------------------------------------------------
+The "New" BSD License:
+**********************
+
+Copyright (c) 2005-2013, The Dojo Foundation
+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 the Dojo Foundation 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+-------------------------------------------------------------------------------
+The Academic Free License, v. 2.1:
+**********************************
+
+This Academic Free License (the "License") applies to any original work of
+authorship (the "Original Work") whose owner (the "Licensor") has placed the
+following notice immediately following the copyright notice for the Original
+Work:
+
+Licensed under the Academic Free License version 2.1
+
+1) Grant of Copyright License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license to do the
+following:
+
+a) to reproduce the Original Work in copies;
+
+b) to prepare derivative works ("Derivative Works") based upon the Original
+Work;
+
+c) to distribute copies of the Original Work and Derivative Works to the
+public;
+
+d) to perform the Original Work publicly; and
+
+e) to display the Original Work publicly.
+
+2) Grant of Patent License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
+claims owned or controlled by the Licensor that are embodied in the Original
+Work as furnished by the Licensor, to make, use, sell and offer for sale the
+Original Work and Derivative Works.
+
+3) Grant of Source Code License. The term "Source Code" means the preferred
+form of the Original Work for making modifications to it and all available
+documentation describing how to modify the Original Work. Licensor hereby
+agrees to provide a machine-readable copy of the Source Code of the Original
+Work along with each copy of the Original Work that Licensor distributes.
+Licensor reserves the right to satisfy this obligation by placing a
+machine-readable copy of the Source Code in an information repository
+reasonably calculated to permit inexpensive and convenient access by You for as
+long as Licensor continues to distribute the Original Work, and by publishing
+the address of that information repository in a notice immediately following
+the copyright notice that applies to the Original Work.
+
+4) Exclusions From License Grant. Neither the names of Licensor, nor the names
+of any contributors to the Original Work, nor any of their trademarks or
+service marks, may be used to endorse or promote products derived from this
+Original Work without express prior written permission of the Licensor. Nothing
+in this License shall be deemed to grant any rights to trademarks, copyrights,
+patents, trade secrets or any other intellectual property of Licensor except as
+expressly stated herein. No patent license is granted to make, use, sell or
+offer to sell embodiments of any patent claims other than the licensed claims
+defined in Section 2. No right is granted to the trademarks of Licensor even if
+such marks are included in the Original Work. Nothing in this License shall be
+interpreted to prohibit Licensor from licensing under different terms from this
+License any Original Work that Licensor otherwise would have a right to
+license.
+
+5) This section intentionally omitted.
+
+6) Attribution Rights. You must retain, in the Source Code of any Derivative
+Works that You create, all copyright, patent or trademark notices from the
+Source Code of the Original Work, as well as any notices of licensing and any
+descriptive text identified therein as an "Attribution Notice." You must cause
+the Source Code for any Derivative Works that You create to carry a prominent
+Attribution Notice reasonably calculated to inform recipients that You have
+modified the Original Work.
+
+7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
+the copyright in and to the Original Work and the patent rights granted herein
+by Licensor are owned by the Licensor or are sublicensed to You under the terms
+of this License with the permission of the contributor(s) of those copyrights
+and patent rights. Except as expressly stated in the immediately proceeding
+sentence, the Original Work is provided under this License on an "AS IS" BASIS
+and WITHOUT WARRANTY, either express or implied, including, without limitation,
+the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
+This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
+license to Original Work is granted hereunder except under this disclaimer.
+
+8) Limitation of Liability. Under no circumstances and under no legal theory,
+whether in tort (including negligence), contract, or otherwise, shall the
+Licensor be liable to any person for any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License
+or the use of the Original Work including, without limitation, damages for loss
+of goodwill, work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses. This limitation of liability shall not
+apply to liability for death or personal injury resulting from Licensor's
+negligence to the extent applicable law prohibits such limitation. Some
+jurisdictions do not allow the exclusion or limitation of incidental or
+consequential damages, so this exclusion and limitation may not apply to You.
+
+9) Acceptance and Termination. If You distribute copies of the Original Work or
+a Derivative Work, You must make a reasonable effort under the circumstances to
+obtain the express assent of recipients to the terms of this License. Nothing
+else but this License (or another written agreement between Licensor and You)
+grants You permission to create Derivative Works based upon the Original Work
+or to exercise any of the rights granted in Section 1 herein, and any attempt
+to do so except under the terms of this License (or another written agreement
+between Licensor and You) is expressly prohibited by U.S. copyright law, the
+equivalent laws of other countries, and by international treaty. Therefore, by
+exercising any of the rights granted to You in Section 1 herein, You indicate
+Your acceptance of this License and all of its terms and conditions.
+
+10) Termination for Patent Action. This License shall terminate automatically
+and You may no longer exercise any of the rights granted to You by this License
+as of the date You commence an action, including a cross-claim or counterclaim,
+against Licensor or any licensee alleging that the Original Work infringes a
+patent. This termination provision shall not apply for an action alleging
+patent infringement by combinations of the Original Work with other software or
+hardware.
+
+11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
+License may be brought only in the courts of a jurisdiction wherein the
+Licensor resides or in which Licensor conducts its primary business, and under
+the laws of that jurisdiction excluding its conflict-of-law provisions. The
+application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any use of the Original Work outside the
+scope of this License or after its termination shall be subject to the
+requirements and penalties of the U.S. Copyright Act, 17 U.S.C. � 101 et
+seq., the equivalent laws of other countries, and international treaty. This
+section shall survive the termination of this License.
+
+12) Attorneys Fees. In any action to enforce the terms of this License or
+seeking damages relating thereto, the prevailing party shall be entitled to
+recover its costs and expenses, including, without limitation, reasonable
+attorneys' fees and costs incurred in connection with such action, including
+any appeal of such action. This section shall survive the termination of this
+License.
+
+13) Miscellaneous. This License represents the complete agreement concerning
+the subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to
+make it enforceable.
+
+14) Definition of "You" in This License. "You" throughout this License, whether
+in upper or lower case, means an individual or a legal entity exercising rights
+under, and complying with all of the terms of, this License. For legal
+entities, "You" includes any entity that controls, is controlled by, or is
+under common control with you. For purposes of this definition, "control" means
+(i) the power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty percent
+(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
+entity.
+
+15) Right to Use. You may use the Original Work in all ways not otherwise
+restricted or conditioned by this License or by law, and Licensor promises not
+to interfere with or be responsible for such uses by You.
+
+This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
+Permission is hereby granted to copy and distribute this license without
+modification. This license may not be modified without the express written
+permission of its copyright owner.
\ No newline at end of file
diff --git a/dojox/calendar/LabelRenderer.js b/dojox/calendar/LabelRenderer.js
new file mode 100644
index 0000000..7c5f97e
--- /dev/null
+++ b/dojox/calendar/LabelRenderer.js
@@ -0,0 +1,44 @@
+define(["dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
+	"dojox/calendar/_RendererMixin", "dojo/text!./templates/LabelRenderer.html"],
+	 
+	function(declare, _WidgetBase, _TemplatedMixin, _RendererMixin, template){
+	
+	return declare("dojox.calendar.LabelRenderer", [_WidgetBase, _TemplatedMixin, _RendererMixin], {
+		
+		// summary:
+		//		The default item label renderer. 
+		
+		templateString: template,
+		
+		_orientation: "horizontal",
+		
+		resizeEnabled: false,
+		
+		visibilityLimits: {
+			resizeStartHandle: 50,
+			resizeEndHandle: -1,
+			summaryLabel: 15,
+			startTimeLabel: 45,
+			endTimeLabel: 30
+		},
+		
+		_isElementVisible: function(elt, startHidden, endHidden, size){
+			switch(elt){
+				case "startTimeLabel":
+					var d = this.item.startTime;
+					if(this.item.isAllDay || d.getHours() == 0 && d.getMinutes() == 0 && d.getSeconds() == 0 && d.getMilliseconds() == 0){
+						return false;
+					}
+					break;
+			}
+			return this.inherited(arguments);
+		},
+		
+		_displayValue: "inline",
+		
+		postCreate: function() {
+			this.inherited(arguments);
+			this._applyAttributes();
+		}
+	});
+});
diff --git a/dojox/calendar/MatrixView.js b/dojox/calendar/MatrixView.js
new file mode 100644
index 0000000..928260f
--- /dev/null
+++ b/dojox/calendar/MatrixView.js
@@ -0,0 +1,2307 @@
+define([
+"dojo/_base/declare", 
+"dojo/_base/array", 
+"dojo/_base/event", 
+"dojo/_base/lang", 
+"dojo/_base/sniff", 
+"dojo/_base/fx", 
+"dojo/_base/html",
+"dojo/on", 
+"dojo/dom", 
+"dojo/dom-class", 
+"dojo/dom-style",
+"dojo/dom-geometry", 
+"dojo/dom-construct", 
+"dojo/query", 
+"dojox/html/metrics", 
+"dojo/i18n",
+"./ViewBase", 
+"dojo/text!./templates/MatrixView.html", 
+"dijit/_TemplatedMixin"],
+	
+function(
+	declare, 
+	arr, 
+	event, 
+	lang, 
+	has, 
+	fx, 
+	html,
+	on, 
+	dom, 
+	domClass, 
+	domStyle,
+	domGeometry,
+	domConstruct, 
+	query, 
+	metrics, 
+	i18n,
+	ViewBase, 
+	template, 
+	_TemplatedMixin){
+	
+	/*=====
+	var __HeaderClickEventArgs = {
+		// summary:
+		//		A column click event.
+		// index: Integer
+		//		The column index. 
+		// date: Date
+		//		The date displayed by the column.
+		// triggerEvent: Event
+		//		The origin event.
+	};
+	=====*/
+	
+	/*=====
+	var __ExpandRendererClickEventArgs = {
+		// summary:
+		//		A expand renderer click event.
+		// columnIndex: Integer
+		//		The column index of the cell. 
+		// rowIndex: Integer
+		//		The row index of the cell.
+		// date: Date
+		//		The date displayed by the cell.
+		// triggerEvent: Event
+		//		The origin event.
+	};
+	=====*/
+	
+	return declare("dojox.calendar.MatrixView", [ViewBase, _TemplatedMixin], {
+		
+		// summary:
+		//		The matrix view is a calendar view that displaying a matrix where each cell is a day.
+
+		templateString: template,
+	
+		baseClass: "dojoxCalendarMatrixView",
+		
+		_setTabIndexAttr: "domNode",
+		
+		// viewKind: String
+		//		Type of the view. Used by the calendar widget to determine how to configure the view.
+		//		This view kind is "matrix".
+		viewKind: "matrix",
+
+		// renderData: Object
+		//		The render data object contains all the data needed to render the widget.
+		renderData: null,
+		
+		// startDate: Date
+		//		The start date of the time interval displayed.
+		//		If not set at initialization time, will be set to current day.
+		startDate: null,
+		
+		// refStartTime: Date?
+		//		(Optional) Start of the time interval of interest. 
+		//		It is used to style differently the displayed rows out of the 
+		//		time interval of interest.  		
+		refStartTime: null,
+		
+		// refStartTime: Date?
+		//		(Optional) End of the time interval of interest. 
+		//		It is used to style differently the displayed rows out of the 
+		//		time interval of interest.  
+		refEndTime: null,
+				
+		// columnCount: Integer
+		//		The number of column to display (from the startDate).
+		columnCount: 7,
+		
+		// rowCount: Integer
+		//		The number of rows to display (from the startDate).
+		rowCount: 5,
+			
+		// horizontalRenderer: Class
+		//		The class use to create horizontal renderers.
+		horizontalRenderer: null,
+		
+		// labelRenderer: Class
+		//		The class use to create label renderers.
+		labelRenderer: null,
+
+		// expandRenderer: Class
+		//		The class use to create drill down renderers.		
+		expandRenderer: null,
+		
+		// percentOverlap: Integer
+		//		The percentage of the renderer width used to superimpose one item renderers on another 
+		//		when two events are overlapping. By default 0.
+		percentOverlap: 0,
+		
+		// verticalGap: Integer
+		//		The number of pixels between two item renderers that are overlapping each other if the percentOverlap property is 0.
+		verticalGap: 2,
+		
+		// horizontalRendererHeight: Integer
+		//		The height in pixels of the horizontal and label renderers that is applied by the layout.
+		horizontalRendererHeight: 17,
+		
+		// horizontalRendererHeight: Integer
+		//		The height in pixels of the horizontal and label renderers that is applied by the layout.
+		labelRendererHeight: 14,
+		
+		// expandRendererHeight: Integer
+		//		The height in pixels of the expand/collapse renderers that is applied by the layout.
+		expandRendererHeight: 15,
+		
+		// cellPaddingTop: Integer
+		//		The top offset in pixels of each cell applied by the layout.
+		cellPaddingTop: 16,
+		
+		// expandDuration: Integer
+		//		Duration of the animation when expanding or collapsing a row.
+		expandDuration: 300,
+		
+		// expandEasing: Function
+		//		Easing function of the animation when expanding or collapsing a row (null by default).
+		expandEasing: null,
+		
+		// layoutDuringResize: Boolean
+		//		Indicates if the item renderers' position and size is updated or if they are hidden during a resize of the widget. 
+		layoutDuringResize: false,
+		
+		// roundToDay: Boolean
+		//		For horizontal renderers that are not filling entire days, whether fill the day or not.
+		roundToDay: true,
+		
+		// showCellLabel: Boolean
+		//		Whether display or not the grid cells label (usually the day of month).
+		showCellLabel: true,
+		
+		// scrollable: [private] Boolean
+		scrollable: false,
+
+		// resizeCursor: [private] Boolean
+		resizeCursor: "e-resize",
+		
+		constructor: function(){
+			this.invalidatingProperties = ["columnCount", "rowCount", "startDate", "horizontalRenderer", "labelRenderer", "expandRenderer",
+			"rowHeaderDatePattern", "columnHeaderLabelLength", "cellHeaderShortPattern", "cellHeaderLongPattern", "percentOverlap", 
+			"verticalGap", "horizontalRendererHeight", "labelRendererHeight", "expandRendererHeight", "cellPaddingTop", 
+			"roundToDay", "itemToRendererKindFunc", "layoutPriorityFunction", "formatItemTimeFunc", "textDir", "items"];
+			
+			this._ddRendererList = [];
+			this._ddRendererPool = [];
+			this._rowHeaderHandles = [];			
+		},
+		
+		destroy: function(preserveDom){
+			this._cleanupRowHeader();
+			this.inherited(arguments);
+		},
+			
+		postCreate: function(){
+			this.inherited(arguments);
+			this._initialized = true;
+			if(!this.invalidRendering){
+				this.refreshRendering();
+			}			
+		},
+						
+		_createRenderData: function(){
+			
+			var rd = {};
+			
+			rd.dateLocaleModule = this.dateLocaleModule;
+			rd.dateClassObj = this.dateClassObj;
+			rd.dateModule = this.dateModule; // arithmetics on Dates
+			
+			rd.dates = [];
+			
+			rd.columnCount = this.get("columnCount");
+			rd.rowCount = this.get("rowCount");
+			
+			rd.sheetHeight = this.itemContainer.offsetHeight;
+			
+			this._computeRowsHeight(rd);
+			
+			var d = this.get("startDate");
+		
+			if(d == null){
+				d = new rd.dateClassObj();				
+			}
+
+			d = this.floorToDay(d, false, rd);
+			
+			this.startDate = d;					
+			
+			for(var row = 0; row < rd.rowCount ; row++){
+				rd.dates.push([]);
+				for(var col = 0; col < rd.columnCount ; col++){
+					rd.dates[row].push(d);
+					d = rd.dateModule.add(d, "day", 1);
+					d = this.floorToDay(d, false, rd);					
+				}
+			}
+
+			rd.startTime = this.newDate(rd.dates[0][0], rd);
+			rd.endTime = this.newDate(rd.dates[rd.rowCount-1][rd.columnCount-1], rd);
+			rd.endTime = rd.dateModule.add(rd.endTime, "day", 1);
+			rd.endTime = this.floorToDay(rd.endTime, true);
+			
+			if(this.displayedItemsInvalidated){
+				this.displayedItemsInvalidated = false;
+				this._computeVisibleItems(rd);
+				
+				if(this._isEditing){
+					this._endItemEditing(null, false);
+				}
+				
+			}else if(this.renderData){
+				rd.items = this.renderData.items;
+			}
+			
+			rd.rtl = !this.isLeftToRight();
+			
+			return rd;
+		},
+				
+		_validateProperties: function(){
+			
+			this.inherited(arguments);
+						
+			if(this.columnCount<1 || isNaN(this.columnCount)){
+				this.columnCount = 1;
+			}
+			
+			if(this.rowCount<1 || isNaN(this.rowCount)){
+				this.rowCount = 1;
+			}
+			
+			if(isNaN(this.percentOverlap) || this.percentOverlap < 0 || this.percentOverlap > 100){
+				this.percentOverlap = 0;
+			}
+			
+			if(isNaN(this.verticalGap) || this.verticalGap < 0){
+				this.verticalGap = 2;
+			}
+			
+			if(isNaN(this.horizontalRendererHeight) || this.horizontalRendererHeight < 1){
+				this.horizontalRendererHeight = 17;
+			}
+			
+			if(isNaN(this.labelRendererHeight) || this.labelRendererHeight < 1){
+				this.labelRendererHeight = 14;
+			}
+			
+			if(isNaN(this.expandRendererHeight) || this.expandRendererHeight < 1){
+				this.expandRendererHeight = 15;
+			}
+		
+		},
+		
+		_setStartDateAttr: function(value){
+			this.displayedItemsInvalidated = true;
+			this._set("startDate", value);
+		},
+		
+		_setColumnCountAttr: function(value){
+			this.displayedItemsInvalidated = true;
+			this._set("columnCount", value);
+		},
+		
+		_setRowCountAttr: function(value){
+			this.displayedItemsInvalidated = true;
+			this._set("rowCount", value);
+		},
+		
+		__fixEvt:function(e){
+			e.sheet = "primary";
+			e.source = this;
+			return e;
+		},
+
+		//////////////////////////////////////////
+		//
+		// Formatting functions
+		//
+		//////////////////////////////////////////
+
+		_formatRowHeaderLabel: function(/*Date*/d){
+			// summary:
+			//		Computes the row header label for the specified time of day.
+			//		By default the getWeekNumberLabel() function is called. 
+			//		The rowHeaderDatePattern property can be used to set a 
+			//		custom date pattern to the formatter.
+			// d: Date
+			//		The date to format	
+			// tags:
+			//		protected
+
+			if(this.rowHeaderDatePattern){
+				return this.renderData.dateLocaleModule.format(d, {
+					selector: 'date',
+					datePattern: this.rowHeaderDatePattern
+				});
+			}else{
+				return this.getWeekNumberLabel(d);
+			}
+
+		},
+	
+		_formatColumnHeaderLabel: function(d){
+			// summary:
+			//		Computes the column header label for the specified date.
+			//		By default a formatter is used, optionally the <code>columnHeaderLabelLength</code> 
+			//		property can be used to specify the length of the string.
+			// d: Date
+			//		The date to format 
+			// tags:
+			//		protected
+
+			return this.renderData.dateLocaleModule.getNames('days', this.columnHeaderLabelLength ? this.columnHeaderLabelLength : 'wide', 'standAlone')[d.getDay()];
+		},
+		
+		_formatGridCellLabel: function(d, row, col){
+			// summary:
+			//		Computes the column header label for the specified date.
+			//		By default a formatter is used, optionally the <code>cellHeaderLongPattern</code> and <code>cellHeaderShortPattern</code> 
+			//		properties can be used to set a custom date pattern to the formatter.
+			// d: Date
+			//		The date to format.
+			// row: Integer
+			//		The row that displays the current date.
+			// col: Integer
+			//		The column that displays the current date.
+			// tags:
+			//		protected
+
+
+			var isFirstDayOfMonth = row == 0 && col == 0 || d.getDate() == 1;
+			var format, rb;
+			if(isFirstDayOfMonth){
+				if(this.cellHeaderLongPattern){
+					format = this.cellHeaderLongPattern;
+				}else{
+					rb = i18n.getLocalization("dojo.cldr", this._calendar);
+					format = rb["dateFormatItem-MMMd"];
+				}
+			}else{
+				if(this.cellHeaderShortPattern){
+					format = this.cellHeaderShortPattern;
+				}else{
+					rb = i18n.getLocalization("dojo.cldr", this._calendar);
+					format = rb["dateFormatItem-d"];
+				}
+			}
+			return this.renderData.dateLocaleModule.format(d, {
+				selector: 'date',
+				datePattern: format
+			});
+		},
+		
+		////////////////////////////////////////////
+		//
+		// HTML structure management
+		//
+		///////////////////////////////////////////
+	
+		refreshRendering: function(){
+			this.inherited(arguments);
+			
+			if(!this.domNode){
+				return;
+			}
+						
+			this._validateProperties();
+
+			var oldRd = this.renderData;
+			this.renderData = this._createRenderData();
+
+			this._createRendering(this.renderData, oldRd);
+			
+			this._layoutRenderers(this.renderData);						
+		},
+		
+		_createRendering: function(renderData, oldRenderData){
+			// summary:
+			//		Creates the HTML structure (grid, place holders, headers, etc)
+			// renderData: Object
+			//		The new render data
+			// oldRenderData: Object
+			//		The previous render data
+			// tags:
+			//		private
+			
+			if(renderData.rowHeight <= 0){
+				renderData.columnCount = 0;
+				renderData.rowCount = 0;
+				return;
+			}
+			
+			this._buildColumnHeader(renderData, oldRenderData);
+			this._buildRowHeader(renderData, oldRenderData);
+			this._buildGrid(renderData, oldRenderData);
+			this._buildItemContainer(renderData, oldRenderData);
+			
+			if(this.buttonContainer && this.owner != null && this.owner.currentView == this){
+				domStyle.set(this.buttonContainer, {"right":0, "left":0});
+			}
+		},	
+		
+		_buildColumnHeader: function(/*Object*/ renderData, /*Object*/oldRenderData){
+			// summary:
+			//		Creates incrementally the HTML structure of the column header and configures its content.
+			//
+			// renderData:
+			//		The render data to display.
+			//
+			// oldRenderData:
+			//		The previously render data displayed, if any.
+			// tags:
+			//		private
+			var table = this.columnHeaderTable;
+			
+			if(!table){
+				return;
+			}	
+						
+			var count = renderData.columnCount - (oldRenderData ? oldRenderData.columnCount : 0);
+			
+			if(has("ie") == 8){
+				// workaround Internet Explorer 8 bug.
+				// if on the table, width: 100% and table-layout: fixed are set
+				// and columns are removed, width of remaining columns is not 
+				// recomputed: must rebuild all. 
+				if(this._colTableSave == null){
+					this._colTableSave = lang.clone(table);
+				}else if(count < 0){
+					this.columnHeader.removeChild(table);
+					domConstruct.destroy(table);
+					table = lang.clone(this._colTableSave);
+					this.columnHeaderTable = table;
+					this.columnHeader.appendChild(table);
+					count = renderData.columnCount;
+				}
+				
+			} // else incremental dom add/remove for real browsers.
+		
+			var tbodies = query("tbody", table);
+			var trs = query("tr", table);
+			var tbody, tr, td;
+			
+			if(tbodies.length == 1){
+				tbody = tbodies[0];
+			}else{ 
+				tbody = html.create("tbody", null, table);
+			}
+			
+			if(trs.length == 1){
+				tr = trs[0];
+			}else{ 
+				tr = domConstruct.create("tr", null, tbody);
+			}			
+						 
+			// Build HTML structure (incremental)
+			if(count > 0){ // creation				
+				for(var i=0; i < count; i++){
+					td = domConstruct.create("td", null, tr);
+				}
+			}else{ // deletion
+				count = -count;
+				for(var i=0; i < count; i++){
+					tr.removeChild(tr.lastChild);
+				}
+			}
+			
+			// fill & configure		
+			query("td", table).forEach(function(td, i){
+				td.className = "";
+				var d = renderData.dates[0][i];
+				this._setText(td, this._formatColumnHeaderLabel(d));
+				if(i == 0){
+					domClass.add(td, "first-child");
+				}else if(i == this.renderData.columnCount-1){
+					domClass.add(td, "last-child");
+				}
+				this.styleColumnHeaderCell(td, d, renderData);
+			}, this);
+			
+			if(this.yearColumnHeaderContent){
+				var d = renderData.dates[0][0];
+					this._setText(this.yearColumnHeaderContent, renderData.dateLocaleModule.format(d,
+						{selector: "date", datePattern:"yyyy"}));
+			}
+		},
+		
+		styleColumnHeaderCell: function(node, date, renderData){
+			// summary:
+			//		Styles the CSS classes to the node that displays a column header cell.
+			//		By default this method is setting the "dojoxCalendarWeekend" if the day of week represents a weekend.
+			// node: Node
+			//		The DOM node that displays the column in the grid.
+			// date: Date
+			//		The date displayed by this column
+			// renderData: Object			
+			//		The render data.
+			// tags:
+			//		protected
+			
+			domClass.add(node, this._cssDays[date.getDay()]);
+
+			if(this.isWeekEnd(date)){
+				domClass.add(node, "dojoxCalendarWeekend");
+			}	
+		},		
+		
+		_rowHeaderHandles: null,
+		
+		_cleanupRowHeader: function(){
+			// tags:
+			//		private
+
+			while(this._rowHeaderHandles.length > 0){
+				var list = this._rowHeaderHandles.pop();
+				while(list.length>0){
+					list.pop().remove();
+				}
+			}
+		},
+
+		
+		_rowHeaderClick: function(e){
+			// tags:
+			//		private
+
+			var index = query("td", this.rowHeaderTable).indexOf(e.currentTarget);
+			this._onRowHeaderClick({
+				index: index,
+				date: this.renderData.dates[index][0],
+				triggerEvent: e
+			});
+		},
+		 
+		_buildRowHeader: function(renderData, oldRenderData){
+			
+			// summary:
+			//		Creates incrementally the HTML structure of the row header and configures its content.			
+			//
+			// renderData:
+			//		The render data to display.
+			//
+			// oldRenderData:
+			//		The previously render data displayed, if any.
+			// tags:
+			//		private
+			
+			var rowHeaderTable = this.rowHeaderTable;
+			
+			if(!rowHeaderTable){
+				return;
+			}
+
+			var tbodies = query("tbody", rowHeaderTable);			
+			var tbody, tr, td;
+			
+			if(tbodies.length == 1){
+				tbody = tbodies[0];
+			}else{ 
+				tbody = domConstruct.create("tbody", null, rowHeaderTable);
+			}				
+						
+			var count = renderData.rowCount - query("tr", rowHeaderTable).length;
+			
+			// Build HTML structure
+			if(count>0){ // creation
+				for(var i=0; i < count; i++){
+					tr = domConstruct.create("tr", null, tbody);
+					td = domConstruct.create("td", null, tr);
+					
+					var h = [];
+						
+					h.push(on(td, "click", lang.hitch(this, this._rowHeaderClick)));
+					
+					if(!has("touch")){
+						h.push(on(td, "mousedown", function(e){
+							domClass.add(e.currentTarget, "Active");
+						}));
+						
+						h.push(on(td, "mouseup", function(e){
+							domClass.remove(e.currentTarget, "Active");
+						}));
+						
+						h.push(on(td, "mouseover", function(e){
+							domClass.add(e.currentTarget, "Hover");
+						}));
+						
+						h.push(on(td, "mouseout", function(e){
+							domClass.remove(e.currentTarget, "Hover");
+						}));
+					}
+					this._rowHeaderHandles.push(h);
+				}
+			}else{
+				count = -count;
+				// deletion of existing nodes
+				for(var i=0; i < count; i++){
+					tbody.removeChild(tbody.lastChild);
+					var list = this._rowHeaderHandles.pop();
+					while(list.length>0){
+						list.pop().remove();
+					}
+				}
+			}
+
+			// fill labels
+
+			query("tr", rowHeaderTable).forEach(function(tr, i){
+
+				domStyle.set(tr, "height", this._getRowHeight(i) + "px");
+				
+				var d = renderData.dates[i][0];
+				
+				var td = query("td", tr)[0];
+				td.className = "";
+				if(i == 0){
+					domClass.add(td, "first-child");
+				}	
+				if(i == this.renderData.rowCount-1){
+					domClass.add(td, "last-child");
+				}
+								
+				this.styleRowHeaderCell(td, d, renderData);
+
+				this._setText(td, this._formatRowHeaderLabel(d));
+			}, this);
+
+		},		
+		
+		styleRowHeaderCell: function(node, date, renderData){
+			// summary:
+			//		Styles the CSS classes to the node that displays a row header cell.
+			//		By default this method is doing nothing.
+			// node: Node
+			//		The DOM node that displays the column in the grid.
+			// date: Date
+			//		The date in the week.
+			// renderData: Object
+			//		The render data.
+			// tags:
+			//		protected
+
+				
+		},
+	
+		_buildGrid: function (renderData, oldRenderData){
+			// summary:
+			//		Creates incrementally the HTML structure of the grid and configures its content.
+			//
+			// renderData:
+			//		The render data to display.
+			//
+			// oldRenderData:
+			//		The previously render data displayed, if any.
+			// tags:
+			//		private
+
+			var table = this.gridTable;
+			
+			if(!table){
+				return;
+			}
+			
+			var currentTR = query("tr", table);
+
+			var rowDiff = renderData.rowCount - currentTR.length;
+			var addRows = rowDiff > 0;
+			
+			var colDiff  = renderData.columnCount - (currentTR ? query("td", currentTR[0]).length : 0);
+			
+			if(has("ie") == 8){
+				// workaround Internet Explorer 8 bug.
+				// if on the table, width: 100% and table-layout: fixed are set
+				// and columns are removed, width of remaining columns is not 
+				// recomputed: must rebuild all. 
+				if(this._gridTableSave == null){
+					this._gridTableSave = lang.clone(table);
+				}else if(colDiff < 0){					
+					this.grid.removeChild(table);
+					domConstruct.destroy(table);
+					table = lang.clone(this._gridTableSave);
+					this.gridTable = table;
+					this.grid.appendChild(table);
+					colDiff = renderData.columnCount;
+					rowDiff = renderData.rowCount;
+					addRows = true;
+				}				
+			}
+			
+			var tbodies = query("tbody", table);
+			var tbody;
+
+			if(tbodies.length == 1){
+				tbody = tbodies[0];
+			}else{ 
+				tbody = domConstruct.create("tbody", null, table);
+			}
+
+			// Build rows HTML structure (incremental)
+			if(addRows){ // creation
+				for(var i=0; i<rowDiff; i++){
+					domConstruct.create("tr", null, tbody);
+				}		 
+			}else{ // deletion		 
+				rowDiff = -rowDiff;
+				for(var i=0; i<rowDiff; i++){
+					tbody.removeChild(tbody.lastChild);
+				}
+			}
+
+			var rowIndex = renderData.rowCount - rowDiff;
+			
+			var addCols = addRows || colDiff >0; 
+			colDiff = addCols ? colDiff : -colDiff;
+			
+			query("tr", table).forEach(function(tr, i){
+				
+				if(addCols){ // creation
+					var len = i >= rowIndex ? renderData.columnCount : colDiff;
+					for(var i=0; i<len; i++){
+						var td = domConstruct.create("td", null, tr);
+						domConstruct.create("span", null, td);
+					}
+				}else{ // deletion
+					for(var i=0; i<colDiff; i++){
+						tr.removeChild(tr.lastChild);
+					}
+				}
+			});
+
+			// Set the CSS classes
+
+			query("tr", table).forEach(function (tr, row){
+				
+				domStyle.set(tr, "height", this._getRowHeight(row) + "px");
+				
+				tr.className = "";
+				// compatibility layer for IE7 & 8 that does not support :first-child and :last-child pseudo selectors
+				if(row == 0){
+					domClass.add(tr, "first-child");
+				}
+				if(row == renderData.rowCount-1){
+					domClass.add(tr, "last-child");
+				}
+
+				query("td", tr).forEach(function (td, col){
+					
+					td.className = "";
+					
+					if(col == 0){
+						domClass.add(td, "first-child");
+					}
+					
+					if(col == renderData.columnCount-1){
+						domClass.add(td, "last-child");
+					}
+					
+					var d = renderData.dates[row][col];
+					
+					var span = query("span", td)[0];
+					this._setText(span, this.showCellLabel ? this._formatGridCellLabel(d, row, col): null);
+					
+					this.styleGridCell(td, d, renderData);
+				}, this);
+			}, this); 
+
+		},
+		
+		// styleGridCellFunc: Function
+		//		Custom function to customize the appearance of a grid cell by installing custom CSS class on the node.
+		//		The signature of the function must be the same then the styleGridCell one.
+		//		By default the defaultStyleGridCell function is used.
+		styleGridCellFunc: null,
+		
+		defaultStyleGridCell: function(node, date, renderData){
+			// summary:
+			//		Styles the CSS classes to the node that displays a cell.
+			//		By default this method is setting the following CSS classes:
+			//		- "dojoxCalendarToday" class name if the date displayed is the current date, 
+			//		- "dojoxCalendarWeekend" if the date represents a weekend or
+			//		- "dojoxCalendarDayDisabled" if the date is out of the [refStartTime, refEndTime] interval.
+			//		- the CSS class corresponding of the displayed day of week ("Sun", "Mon" and so on).			
+			// node: Node
+			//		The DOM node that displays the cell in the grid.
+			// date: Date
+			//		The date displayed by this cell.
+			// renderData: Object
+			//		The render data.
+			// tags:
+			//		protected
+			
+			domClass.add(node, this._cssDays[date.getDay()]);
+			
+			var cal = this.dateModule;
+			if(this.isToday(date)){				
+				domClass.add(node, "dojoxCalendarToday");
+			}else if(this.refStartTime != null && this.refEndTime != null && 
+								(cal.compare(date, this.refEndTime) >= 0 || 
+				 				 cal.compare(cal.add(date, "day", 1), this.refStartTime) <= 0)){
+				domClass.add(node, "dojoxCalendarDayDisabled");
+			}else if(this.isWeekEnd(date)){
+				domClass.add(node, "dojoxCalendarWeekend");
+			}	
+		},
+		
+		styleGridCell: function(node, date, renderData){
+			// summary:
+			//		Styles the CSS classes to the node that displays a cell.
+			//		Delegates to styleGridCellFunc if defined or defaultStyleGridCell otherwise.
+			// node: Node
+			//		The DOM node that displays the cell in the grid.
+			// date: Date
+			//		The date displayed by this cell.
+			// renderData: Object
+			//		The render data.
+			// tags:
+			//		protected
+			if(this.styleGridCellFunc){
+				this.styleGridCellFunc(node, date, renderData);
+			}else{
+				this.defaultStyleGridCell(node, date, renderData);
+			}
+		},
+
+		_buildItemContainer: function(renderData, oldRenderData){
+			// summary:
+			//		Creates the HTML structure of the item container and configures its content.
+			//
+			// renderData:
+			//		The render data to display.
+			//
+			// oldRenderData:
+			//		The previously render data displayed, if any.
+			// tags:
+			//		private
+			
+			var table = this.itemContainerTable;
+			
+			if(!table){
+				return;
+			}
+			
+			var rows = [];
+	
+			var count = renderData.rowCount - (oldRenderData ? oldRenderData.rowCount : 0);
+			
+			if(has("ie") == 8){
+				// workaround Internet Explorer 8 bug.
+				// if on the table, width: 100% and table-layout: fixed are set
+				// and columns are removed, width of remaining columns is not 
+				// recomputed: must rebuild all. 
+				if(this._itemTableSave == null){
+					this._itemTableSave = lang.clone(table);
+				}else if(count < 0){
+					this.itemContainer.removeChild(table);
+					this._recycleItemRenderers(true);
+					this._recycleExpandRenderers(true);
+					domConstruct.destroy(table);
+					table = lang.clone(this._itemTableSave);
+					this.itemContainerTable = table;
+					this.itemContainer.appendChild(table);
+					count = renderData.columnCount;
+				}
+				
+			} // else incremental dom add/remove for real browsers.
+			
+			var tbodies = query("tbody", table);
+			var tbody, tr, td, div;
+			
+			if(tbodies.length == 1){
+				tbody = tbodies[0];
+			}else{ 
+				tbody = domConstruct.create("tbody", null, table);
+			}
+			
+			// Build HTML structure (incremental)
+			if(count>0){ // creation
+				for(var i=0; i < count; i++){
+					tr = domConstruct.create("tr", null, tbody);
+					domClass.add(tr, "dojoxCalendarItemContainerRow");
+					td = domConstruct.create("td", null, tr);	
+					div = domConstruct.create("div", null, td);
+					domClass.add(div, "dojoxCalendarContainerRow");
+				}
+			}else{ // deletion		 
+				count = -count;
+				for(var i=0; i < count; i++){
+					tbody.removeChild(tbody.lastChild);
+				}
+			}
+
+			query(".dojoxCalendarItemContainerRow", table).forEach(function(tr, i){
+				domStyle.set(tr, "height", this._getRowHeight(i) + "px");
+				rows.push(tr.childNodes[0].childNodes[0]);
+			}, this); 
+
+			renderData.cells = rows;
+		},
+		
+		resize: function(e){
+			this._resizeHandler(e);
+		},
+
+		_resizeHandler: function(e, apply){
+			// summary:
+			//		Refreshes and apply the row height according to the widget height.
+			// e: Event
+			//		The resize event (optional)
+			// apply: Boolean
+			//		Whether take into account the layoutDuringResize flag to relayout item while resizing or not.
+			// tags:
+			//		private
+
+			var rd = this.renderData;
+			
+			if(rd == null){
+				this.refreshRendering();
+				return;
+			}
+
+			if(rd.sheetHeight != this.itemContainer.offsetHeight){
+				// refresh values
+				rd.sheetHeight = this.itemContainer.offsetHeight;
+				var expRow = this.getExpandedRowIndex();
+				if(expRow == -1){
+					this._computeRowsHeight();
+					this._resizeRows();
+				}else{
+					this.expandRow(rd.expandedRow, rd.expandedRowCol, 0, null, true);
+				}
+			}
+			
+			if(this.layoutDuringResize || apply){
+				// Use a time for FF (at least). In FF the cell size and position info are not ready yet. 
+				setTimeout(lang.hitch(this, function(){
+					this._layoutRenderers(this.renderData);
+				  }), 20);
+								
+			}else{
+				domStyle.set(this.itemContainer, "opacity", 0);
+				this._recycleItemRenderers();
+				this._recycleExpandRenderers();
+				if(this._resizeTimer != undefined){
+					clearTimeout(this._resizeTimer);
+				}
+				this._resizeTimer = setTimeout(lang.hitch(this, function(){
+					delete this._resizeTimer;
+					this._resizeRowsImpl(this.itemContainer, "tr");
+					this._layoutRenderers(this.renderData);
+					if(this.resizeAnimationDuration == 0){
+						domStyle.set(this.itemContainer, "opacity", 1);
+					}else{
+						fx.fadeIn({node:this.itemContainer, curve:[0, 1]}).play(this.resizeAnimationDuration);
+					}					
+				}), 200);
+			}
+
+		},
+		
+		// resizeAnimationDuration: Integer
+		//		Duration, in milliseconds, of the fade animation showing the item renderers after a widget resize.
+		resizeAnimationDuration: 0,
+		
+		/////////////////////////////////////////////
+		//
+		// Row height management
+		//
+		//////////////////////////////////////////////
+		
+		getExpandedRowIndex: function(){
+			// summary:
+			//		Returns the index of the expanded row or -1 if there's no row expanded.
+			return this.renderData.expandedRow == null ? -1 : this.renderData.expandedRow;
+		},
+		
+		collapseRow: function(duration, easing, apply){
+			// summary:
+			//		Collapses the expanded row, if any.
+			// duration: Integer
+			//		Duration in milliseconds of the optional animation.
+			// easing: Function
+			//		Easing function of the optional animation.
+			
+			var rd = this.renderData;
+			
+			if(apply == undefined){
+				apply = true;
+			}
+			if(duration == undefined){
+				duration = this.expandDuration;
+			}
+			
+			if(rd && rd.expandedRow != null && rd.expandedRow != -1){
+				if(apply && duration){
+					var index = rd.expandedRow;
+					var oldSize = rd.expandedRowHeight;
+					delete rd.expandedRow;
+					this._computeRowsHeight(rd);
+					var size = this._getRowHeight(index);
+					rd.expandedRow = index;
+					
+					this._recycleExpandRenderers();
+					this._recycleItemRenderers();
+					domStyle.set(this.itemContainer, "display", "none");
+					
+					this._expandAnimation = new fx.Animation({
+						curve: [oldSize, size],
+						duration: duration,
+						easing: easing,
+						onAnimate: lang.hitch(this, function(size) {
+							this._expandRowImpl(Math.floor(size));
+						}),
+						onEnd: lang.hitch(this, function(size) {
+							this._expandAnimation = null;
+							this._collapseRowImpl(false);
+							this._resizeRows();
+							domStyle.set(this.itemContainer, "display", "block");
+							setTimeout(lang.hitch(this, function(){								
+								this._layoutRenderers(rd);								
+							}), 100);
+							this.onExpandAnimationEnd(false);
+						}) 
+					});
+									
+					this._expandAnimation.play();
+				}else{
+					this._collapseRowImpl(apply);
+				}				
+			}
+		},
+		
+		_collapseRowImpl: function(apply){
+			// tags:
+			//		private
+
+			var rd = this.renderData;
+			delete rd.expandedRow;
+			delete rd.expandedRowHeight;
+			this._computeRowsHeight(rd);
+			if(apply == undefined || apply){
+				this._resizeRows();
+				this._layoutRenderers(rd);
+			}
+		},
+		
+		expandRow: function(rowIndex, colIndex, duration, easing, apply){
+			// summary:
+			//		Expands the specified row.
+			// rowIndex: Integer
+			//		The index of the row to expand.
+			// colIndex: Integer?
+			//		The column index of the expand renderer that triggers the action, optional. 
+			// duration: Integer?
+			//		Duration in milliseconds of the optional animation.
+			// easing: Function?
+			//		Easing function of the optional animation.
+			
+			var rd = this.renderData;
+			if(!rd || rowIndex < 0 || rowIndex >= rd.rowCount){
+				return -1;
+			}
+			if(colIndex == undefined || colIndex < 0 || colIndex >= rd.columnCount){
+				colIndex = -1; // ignore invalid values
+			}
+			if(apply == undefined){
+				apply = true;
+			}
+			if(duration == undefined){
+				duration = this.expandDuration;
+			}
+			if(easing == undefined){
+				easing = this.expandEasing;
+			}
+			
+			var oldSize = this._getRowHeight(rowIndex);
+			var size = rd.sheetHeight - Math.ceil(this.cellPaddingTop * (rd.rowCount-1));
+
+			rd.expandedRow = rowIndex;
+			rd.expandedRowCol = colIndex;
+			rd.expandedRowHeight = size;
+
+			if(apply){
+				if(duration){
+					//debugger;
+					this._recycleExpandRenderers();
+					this._recycleItemRenderers();
+					domStyle.set(this.itemContainer, "display", "none");
+					
+					this._expandAnimation = new fx.Animation({
+						curve: [oldSize, size],
+						duration: duration,
+						delay:50,
+						easing: easing,
+						onAnimate: lang.hitch(this, function(size) {
+							this._expandRowImpl(Math.floor(size));
+						}),
+						onEnd: lang.hitch(this, function(){
+							this._expandAnimation = null;
+							domStyle.set(this.itemContainer, "display", "block");
+							setTimeout(lang.hitch(this, function(){
+								this._expandRowImpl(size, true);
+							}), 100);
+							this.onExpandAnimationEnd(true);
+						})
+					});
+					this._expandAnimation.play();
+				}else{
+					this._expandRowImpl(size);
+				}
+			}			
+		},
+		
+		_expandRowImpl: function(size, layout){
+			// tags:
+			//		private
+
+			var rd = this.renderData;
+			rd.expandedRowHeight = size;
+			this._computeRowsHeight(rd, rd.sheetHeight-size);
+			this._resizeRows();
+			if(layout){
+				this._layoutRenderers(rd);
+			}
+		},
+		
+		onExpandAnimationEnd: function(expand){
+			// summary:
+			//		Event dispatched at the end of an expand or collapse animation.
+			// expand: Boolean
+			//		Whether the finished animation was an expand or a collapse animation.
+			// tags:
+			//		callback
+
+		},
+		
+		_resizeRows: function(){
+			// summary:
+			//		Refreshes the height of the underlying HTML objects.
+			// tags:
+			//		private
+			
+			if(this._getRowHeight(0) <= 0){
+				return;
+			}
+			
+			if(this.rowHeaderTable){
+				this._resizeRowsImpl(this.rowHeaderTable, "tr");
+			}
+			if(this.gridTable){
+				this._resizeRowsImpl(this.gridTable, "tr");
+			}
+			if(this.itemContainerTable){
+				this._resizeRowsImpl(this.itemContainerTable, "tr");
+			}
+		},
+		
+		_computeRowsHeight:function(renderData, max){
+			// summary:
+			//		1. Determine if it's better to add or remove pixels
+			//		2. distribute added/removed pixels on first and last rows.
+			//		if rows are not too small, it is not noticeable.
+			// tags:
+			//		private
+
+			var rd = renderData == null ? this.renderData : renderData;
+			
+			max = max || rd.sheetHeight;
+			
+			max--;
+			
+			if(has("ie") == 7){
+				max -= rd.rowCount;
+			}
+			
+			if(rd.rowCount == 1){
+				rd.rowHeight = max;
+				rd.rowHeightFirst = max;
+				rd.rowHeightLast = max;
+				return;
+			}
+								
+			var count = rd.expandedRow == null ? rd.rowCount : rd.rowCount-1;
+			var rhx = max / count;
+			var rhf, rhl, rh;
+			
+			var diffMin = max - (Math.floor(rhx) * count);
+			var diffMax = Math.abs(max - (Math.ceil(rhx) * count));
+			var diff;
+			
+			var sign = 1;
+			if(diffMin < diffMax){
+				rh = Math.floor(rhx);
+				diff = diffMin;
+			}else{
+				sign = -1;
+				rh = Math.ceil(rhx);
+				diff = diffMax;
+			}
+			rhf = rh + sign * Math.floor(diff/2);
+			rhl = rhf + sign * (diff%2);
+
+			rd.rowHeight = rh;
+			rd.rowHeightFirst = rhf;
+			rd.rowHeightLast = rhl;
+		},
+
+		_getRowHeight: function(index){
+			// tags:
+			//		private
+
+			var rd = this.renderData;
+			if(index == rd.expandedRow){
+				return rd.expandedRowHeight;
+			} else if(rd.expandedRow == 0 && index == 1 || index == 0){
+				return rd.rowHeightFirst;
+			} else if(rd.expandedRow == this.renderData.rowCount-1 && 
+								index == this.renderData.rowCount-2 || 
+								index == this.renderData.rowCount-1){
+				return rd.rowHeightLast;
+			}else{
+				return rd.rowHeight;
+			}
+		},
+
+		_resizeRowsImpl: function(tableNode, query){
+			// tags:
+			//		private
+			dojo.query(query, tableNode).forEach(function(tr, i){
+				domStyle.set(tr, "height", this._getRowHeight(i)+"px");
+			}, this);
+		},
+
+		////////////////////////////////////////////
+		//
+		// Item renderers
+		//
+		///////////////////////////////////////////
+				
+		_setHorizontalRendererAttr: function(value){
+			this._destroyRenderersByKind("horizontal");
+			this._set("horizontalRenderer", value);			
+		},
+		
+		_setLabelRendererAttr: function(value){
+			this._destroyRenderersByKind("label");			
+			this._set("labelRenderer", value);
+		},
+		
+		_destroyExpandRenderer: function(renderer){
+			// summary: 
+			//		Destroys the expand renderer.
+			// renderer: dojox/calendar/_RendererMixin
+			//		The item renderer to destroy.
+			// tags:
+			//		protected
+			
+			if(renderer["destroyRecursive"]){
+				renderer.destroyRecursive();
+			}
+			
+			html.destroy(renderer.domNode);	
+		},
+		
+		_setExpandRendererAttr: function(value){
+			while(this._ddRendererList.length>0){
+				this._destroyExpandRenderer(this._ddRendererList.pop());
+			}			
+						
+			var pool = this._ddRendererPool;
+			if(pool){
+				while(pool.length > 0){
+					this._destroyExpandRenderer(pool.pop());
+				}
+			}							
+			this._set("expandRenderer", value);
+		},				
+		
+		_ddRendererList: null,
+		_ddRendererPool: null,
+
+		_getExpandRenderer: function(date, items, rowIndex, colIndex, expanded){
+			// tags:
+			//		private
+			
+			if(this.expandRenderer == null){
+				return null;
+			}
+			
+			var ir = this._ddRendererPool.pop();
+			if(ir == null){
+				ir = new this.expandRenderer();
+			}
+			
+			this._ddRendererList.push(ir);
+			
+			ir.set("owner", this);
+			ir.set("date", date);
+			ir.set("items", items);
+			ir.set("rowIndex", rowIndex);
+			ir.set("columnIndex", colIndex);
+			ir.set("expanded", expanded);
+			return ir;
+		},
+		
+		_recycleExpandRenderers: function(remove){
+			// tags:
+			//		private
+			
+			for(var i=0; i<this._ddRendererList.length; i++){
+				var ir = this._ddRendererList[i];
+				ir.set("Up", false);
+				ir.set("Down", false);
+				if(remove){
+					ir.domNode.parentNode.removeChild(ir.domNode);
+				}
+				domStyle.set(ir.domNode, "display", "none");
+			}
+			this._ddRendererPool = this._ddRendererPool.concat(this._ddRendererList);
+			this._ddRendererList = [];
+		},
+
+		_defaultItemToRendererKindFunc:function(item){
+			// tags:
+			//		private
+			var dur = Math.abs(this.renderData.dateModule.difference(item.startTime, item.endTime, "minute"));
+			return dur >= 1440 ? "horizontal" : "label";
+		}, 
+		
+		////////////////////////////////////////////
+		//
+		// Layout
+		//
+		///////////////////////////////////////////
+		
+		// naturalRowHeight: Integer[]
+		//		After an item layout has been done, contains for each row the natural height of the row. 
+		//		Ie. the height, in pixels, needed to display all the item renderers. 
+		naturalRowsHeight: null,
+		
+		_roundItemToDay: function(item){
+			// tags:
+			//		private
+			
+			var s = item.startTime, e = item.endTime;
+			
+			if(!this.isStartOfDay(s)){
+				s = this.floorToDay(s, false, this.renderData);
+			}
+			if(!this.isStartOfDay(e)){
+				e = this.renderData.dateModule.add(e, "day", 1);
+				e = this.floorToDay(e, true);
+			}
+			return {startTime:s, endTime:e};
+		},
+		
+		_sortItemsFunction: function(a, b){
+			// tags:
+			//		private
+			
+			if(this.roundToDay){
+				a = this._roundItemToDay(a);
+				b = this._roundItemToDay(b);
+			}
+			var res = this.dateModule.compare(a.startTime, b.startTime);
+			if(res == 0){
+				res = -1 * this.dateModule.compare(a.endTime, b.endTime);
+			}
+			return res;
+		},
+		
+		_overlapLayoutPass3: function(lanes){
+			// summary:
+			//		Third pass of the overlap layout (optional). Compute the number of lanes used by sub interval.
+			// lanes: Object[]
+			//		The array of lanes.
+			// tags:
+			//		private
+
+			var pos=0, posEnd=0;
+			var res = [];
+			
+			var refPos = domGeometry.position(this.gridTable).x;
+			
+			for(var col=0; col<this.renderData.columnCount; col++){
+				
+				var stop = false;
+				var colPos = domGeometry.position(this._getCellAt(0, col));
+				pos = colPos.x - refPos;
+				posEnd = pos + colPos.w;
+				
+				for(var lane=lanes.length-1; lane>=0 && !stop; lane--){
+					for (var i=0; i<lanes[lane].length; i++){
+						var item = lanes[lane][i];
+						stop = item.start < posEnd && pos < item.end;
+						if(stop){
+							res[col] = lane + 1;
+							break;
+						}
+					}
+				}
+				
+				if(!stop){
+					res[col] = 0;
+				}
+			}
+			
+			return res;
+		},
+		
+		applyRendererZIndex: function(item, renderer, hovered, selected, edited, focused){
+			// summary:
+			//		Applies the z-index to the renderer based on the state of the item.
+			//		This methods is setting a z-index of 20 is the item is selected or edited 
+			//		and the current lane value computed by the overlap layout (i.e. the renderers 
+			//		are stacked according to their lane).
+			// item: Object
+			//		The render item.
+			// renderer: Object
+			//		A renderer associated with the render item.
+			// hovered: Boolean
+			//		Whether the item is hovered or not.
+			// selected: Boolean
+			//		Whether the item is selected or not.
+			// edited: Boolean
+			//		Whether the item is being edited not not.
+			// focused: Boolean
+			//		Whether the item is focused not not.
+			// tags:
+			//		private
+						
+			domStyle.set(renderer.container, {"zIndex": edited || selected ? renderer.renderer.mobile ? 100 : 0: item.lane == undefined ? 1 : item.lane+1});
+		},
+
+		_layoutRenderers: function(renderData){
+			// tags:
+			//		private
+			if(renderData == null || renderData.items == null || renderData.rowHeight <= 0){
+				return;
+			}					
+			
+			if(!this.gridTable || this._expandAnimation != null || 
+				(this.horizontalRenderer == null && this.labelRenderer == null)){
+				this._recycleItemRenderers();
+				return;
+			}
+			
+			this.renderData.gridTablePosX = domGeometry.position(this.gridTable).x;		
+			this._layoutStep = renderData.columnCount;
+			this._recycleExpandRenderers();
+			this._hiddenItems = [];
+			this._offsets = [];
+			this.naturalRowsHeight = [];
+			
+			this.inherited(arguments);
+		},
+
+		_offsets: null,
+
+		_layoutInterval: function(/*Object*/renderData, /*Integer*/index, /*Date*/start, /*Date*/end, /*Object[]*/items){
+			// tags:
+			//		private
+			
+			if(this.renderData.cells == null){
+				return;
+			}
+			var horizontalItems = [];
+			var labelItems = [];
+
+			for(var i=0; i<items.length; i++){
+				var item = items[i];
+				var kind = this._itemToRendererKind(item);
+				if(kind == "horizontal"){
+					horizontalItems.push(item);
+				}else if(kind == "label"){
+					labelItems.push(item);
+				}
+			}
+			
+			var expIndex = this.getExpandedRowIndex();
+			
+			if(expIndex != -1 && expIndex != index){
+				return; // when row is expanded, layout only expanded row
+			}
+			
+			var offsets;
+			
+			var hiddenItems = [];
+			
+			var hItems = null;
+			var hOffsets = [];
+			if(horizontalItems.length > 0 && this.horizontalRenderer){
+				var hItems = this._createHorizontalLayoutItems(index, start, end, horizontalItems);
+				var hOverlapLayout = this._computeHorizontalOverlapLayout(hItems, hOffsets);
+			}
+			
+			var lItems;
+			var lOffsets = [];
+			if(labelItems.length > 0 && this.labelRenderer){
+				lItems = this._createLabelLayoutItems(index, start, end, labelItems);
+				this._computeLabelOffsets(lItems, lOffsets);
+			}
+			
+			var hasHiddenItems = this._computeColHasHiddenItems(index, hOffsets, lOffsets);
+			
+			if(hItems != null){
+				this._layoutHorizontalItemsImpl(index, hItems, hOverlapLayout, hasHiddenItems, hiddenItems);
+			}
+			
+			if(lItems != null){
+				this._layoutLabelItemsImpl(index, lItems, hasHiddenItems, hiddenItems, hOffsets);
+			}
+			
+			this._layoutExpandRenderers(index, hasHiddenItems, hiddenItems);
+			
+			this._hiddenItems[index] = hiddenItems;
+		},
+
+		_createHorizontalLayoutItems: function(/*Integer*/index, /*Date*/startTime, /*Date*/endTime, /*Object[]*/items){
+			// tags:
+			//		private
+			
+			if(this.horizontalRenderer == null){
+				return;
+			}
+
+			var rd = this.renderData;
+			var cal = rd.dateModule;
+			var sign = rd.rtl ? -1 : 1;
+			var layoutItems = [];
+
+			// step 1: compute projected position and size
+			for(var i = 0; i < items.length; i++){
+				
+				var item = items[i];
+				var overlap = this.computeRangeOverlap(rd, item.startTime, item.endTime, startTime, endTime);
+				
+				var startOffset = cal.difference(startTime, this.floorToDay(overlap[0], false, rd), "day");
+				var dayStart = rd.dates[index][startOffset];
+				
+				var celPos = domGeometry.position(this._getCellAt(index, startOffset, false));
+				var start = celPos.x - rd.gridTablePosX;
+				if(rd.rtl){
+					start += celPos.w;
+				}
+				
+				if(!this.roundToDay && !item.allDay){
+					start += sign * this.computeProjectionOnDate(rd, dayStart, overlap[0], celPos.w);
+				}
+				
+				start = Math.ceil(start);
+				
+				var endOffset = cal.difference(startTime, this.floorToDay(overlap[1], false, rd), "day");
+				
+				var end;
+				if(endOffset > rd.columnCount-1){
+					celPos = domGeometry.position(this._getCellAt(index, rd.columnCount-1, false));
+					if(rd.rtl){
+						end = celPos.x - rd.gridTablePosX;						
+					}else{
+						end = celPos.x - rd.gridTablePosX + celPos.w;
+					}				
+				}else{ 
+					dayStart = rd.dates[index][endOffset];
+					celPos = domGeometry.position(this._getCellAt(index, endOffset, false));
+					end = celPos.x - rd.gridTablePosX;
+					
+					if(rd.rtl){
+						end += celPos.w;
+					}
+					
+					if(this.roundToDay){
+						if(!this.isStartOfDay(overlap[1])){
+							end += sign * celPos.w;
+						}
+					}else{
+						end += sign * this.computeProjectionOnDate(rd, dayStart, overlap[1], celPos.w);
+					}
+				}
+				
+				end = Math.floor(end);
+				
+				if(rd.rtl){
+					var t = end;
+					end = start;
+					start = t; 
+				}
+				
+				if(end > start){ // invalid items are not displayed
+					var litem = lang.mixin({
+						start: start,
+						end: end,
+						range: overlap,
+						item: item,
+						startOffset: startOffset,
+						endOffset: endOffset
+					}, item);
+					layoutItems.push(litem);
+				}
+			}
+			return layoutItems;
+		},
+		
+		_computeHorizontalOverlapLayout: function(layoutItems, offsets){
+			// tags:
+			//		private
+			
+			var rd = this.renderData;
+			var irHeight = this.horizontalRendererHeight;
+			var overlapLayoutRes = this.computeOverlapping(layoutItems, this._overlapLayoutPass3);
+			var vOverlap = this.percentOverlap / 100;
+		
+			for(var i=0; i<rd.columnCount; i++){
+				var numLanes = overlapLayoutRes.addedPassRes[i];
+				var index = rd.rtl ? rd.columnCount - i - 1 : i;				
+				if(vOverlap == 0){
+					offsets[index] = numLanes == 0 ? 0 : numLanes == 1 ? irHeight : irHeight + (numLanes-1) * (irHeight + this.verticalGap);
+				}else{
+					offsets[index] = numLanes == 0 ? 0 : numLanes * irHeight - (numLanes-1) * (vOverlap * irHeight) + this.verticalGap;
+				}
+				offsets[index] += this.cellPaddingTop;
+			}
+			return overlapLayoutRes;
+		},
+		
+		_createLabelLayoutItems: function(/*Integer*/index, /*Date*/startTime, /*Date*/endTime, /*Object[]*/items){
+			// tags:
+			//		private
+			
+			if(this.labelRenderer == null){
+				return;
+			}
+			
+			var d;
+			var rd = this.renderData;
+			var cal = rd.dateModule;
+			
+			var layoutItems = [];
+			
+			for(var i = 0; i < items.length; i++){
+				var item = items[i];
+				
+				d = this.floorToDay(item.startTime, false, rd);
+								
+				var comp = this.dateModule.compare;
+				
+				// iterate on columns overlapped by this item to create one item per column
+				//while(d < item.endTime && d < rd.endTime){
+				while(comp(d, item.endTime) == -1 && comp(d, endTime) == -1){
+					
+					var dayEnd = cal.add(d, "day", 1);
+					dayEnd = this.floorToDay(dayEnd, true);
+					
+					var overlap = this.computeRangeOverlap(rd, item.startTime, item.endTime, d, dayEnd);
+					var startOffset = cal.difference(startTime, this.floorToDay(overlap[0], false, rd), "day");
+										
+					if(startOffset >= this.columnCount){
+						// If the offset is greater than the column count
+						// the item will be processed in another row.
+						break;
+					}
+					
+					if(startOffset >= 0){					
+						var list = layoutItems[startOffset];
+						if(list == null){
+							list = [];
+							layoutItems[startOffset] = list;
+						}
+						
+						list.push(lang.mixin(
+							{	startOffset: startOffset,
+								range: overlap,
+								item: item
+							}, item));
+					}
+					
+					d = cal.add(d, "day", 1);
+					this.floorToDay(d, true);
+				}
+			}
+			return layoutItems;
+		},
+
+		_computeLabelOffsets: function(layoutItems, offsets){
+			// tags:
+			//		private
+			
+			for(var i=0; i<this.renderData.columnCount; i++){
+				offsets[i] = layoutItems[i] == null ? 0 : layoutItems[i].length * (this.labelRendererHeight + this.verticalGap);
+			}
+		},			
+
+		_computeColHasHiddenItems: function(index, hOffsets, lOffsets){
+			// tags:
+			//		private
+			
+			var res = [];
+			var cellH = this._getRowHeight(index);
+			var h;
+			var maxH = 0;
+			for(var i=0; i<this.renderData.columnCount; i++){
+				h = hOffsets == null || hOffsets[i] == null ? this.cellPaddingTop : hOffsets[i];
+				h += lOffsets == null || lOffsets[i] == null ? 0 : lOffsets[i];
+				if(h > maxH){
+					maxH = h;
+				}
+				res[i] = h > cellH;
+			}
+			
+			this.naturalRowsHeight[index] = maxH;
+			return res;
+		},
+
+		_layoutHorizontalItemsImpl: function(index, layoutItems, hOverlapLayout, hasHiddenItems, hiddenItems){
+			
+			// tags:
+			//		private
+			
+			var rd = this.renderData;
+			var cell = rd.cells[index];
+			var cellH = this._getRowHeight(index);
+			var irHeight = this.horizontalRendererHeight;
+			var vOverlap = this.percentOverlap / 100;
+
+			for(var i=0; i<layoutItems.length; i++){
+
+				var item = layoutItems[i];
+				var lane = item.lane;
+
+				var posY = this.cellPaddingTop;
+
+				if(vOverlap == 0) {
+					//no overlap and a padding between each event
+					posY += lane * (irHeight + this.verticalGap);
+				} else {
+					// an overlap	
+					posY += lane * (irHeight - vOverlap * irHeight);
+				}
+				
+				var exp = false;
+				var maxH = cellH;
+				if(this.expandRenderer){				
+					for(var off=item.startOffset; off<=item.endOffset; off++){
+						if(hasHiddenItems[off]){
+							exp = true;
+							break;
+						}
+					}
+					maxH = exp ? cellH - this.expandRendererHeight : cellH;
+				}
+				
+				if(posY + irHeight <= maxH){
+
+					var ir = this._createRenderer(item, "horizontal", this.horizontalRenderer, "dojoxCalendarHorizontal");
+	
+					var fullHeight = this.isItemBeingEdited(item) && !this.liveLayout && this._isEditing;
+					var h = fullHeight ? cellH - this.cellPaddingTop : irHeight;
+					var w = item.end - item.start;
+					if (has("ie") >= 9 && item.start + w < this.itemContainer.offsetWidth) {
+						w++;
+					}
+
+					domStyle.set(ir.container, {
+						"top": (fullHeight ? this.cellPaddingTop : posY) + "px",
+						"left": item.start + "px",
+						"width": w + "px",
+						"height": h + "px"
+					});
+
+					this._applyRendererLayout(item, ir, cell, w, h, "horizontal");
+
+				}else{
+					// The items does not fit in view, fill hidden items per column
+					for(var d=item.startOffset;d<item.endOffset;d++){
+						if(hiddenItems[d] == null){
+							hiddenItems[d] = [item.item];
+						}else{
+							hiddenItems[d].push(item.item);
+						}
+					}
+				}
+			}
+		},
+		
+		_layoutLabelItemsImpl: function(index, layoutItems, hasHiddenItems, hiddenItems, hOffsets){
+			// tags:
+			//		private
+			var list, posY;
+			var rd = this.renderData;
+			var cell = rd.cells[index];
+			var cellH = this._getRowHeight(index);
+			var irHeight = this.labelRendererHeight;
+			var maxW = domGeometry.getMarginBox(this.itemContainer).w;
+
+			for(var i=0; i<layoutItems.length; i++){
+				list = layoutItems[i];
+				
+				if(list != null){
+					
+					var maxH = this.expandRenderer ? (hasHiddenItems[i] ? cellH - this.expandRendererHeight: cellH) : cellH;
+					posY = hOffsets == null || hOffsets[i] == null ? this.cellPaddingTop : hOffsets[i] + this.verticalGap;
+					var celPos = domGeometry.position(this._getCellAt(index, i));
+					var left = celPos.x - rd.gridTablePosX;
+					
+					for(var j=0; j<list.length; j++){
+						
+						if(posY + irHeight + this.verticalGap <= maxH){
+							var item = list[j];
+							
+							lang.mixin(item, {
+								start: left,
+								end: left + celPos.w
+							});
+							
+							var ir = this._createRenderer(item, "label", this.labelRenderer, "dojoxCalendarLabel");
+								
+							var fullHeight = this.isItemBeingEdited(item) && !this.liveLayout && this._isEditing;
+							var h = fullHeight ? this._getRowHeight(index) - this.cellPaddingTop : irHeight;
+							
+							if(rd.rtl){
+								item.start = maxW - item.end;
+								item.end = item.start + celPos.w;
+							}
+								 
+							domStyle.set(ir.container, {
+								"top": (fullHeight ? this.cellPaddingTop : posY) + "px",
+								"left": item.start + "px",
+								"width": celPos.w + "px",
+								"height": h + "px"
+							});
+							
+							this._applyRendererLayout(item, ir, cell, celPos.w, h, "label");
+						
+						}else{
+							break;
+						}
+						posY += irHeight + this.verticalGap;
+					}
+					
+					for(var j; j<list.length; j++){
+						if(hiddenItems[i] == null){
+							hiddenItems[i] = [list[j]];
+						}else{
+							hiddenItems[i].push(list[j]);
+						}
+					}
+				}
+			}
+		},
+		
+		_applyRendererLayout: function(item, ir, cell, w, h, kind){
+			// tags:
+			//		private
+			
+			var edited = this.isItemBeingEdited(item);
+			var selected = this.isItemSelected(item);
+			var hovered = this.isItemHovered(item);
+			var focused = this.isItemFocused(item);
+			
+			var renderer = ir.renderer;			
+
+			renderer.set("hovered", hovered);
+			renderer.set("selected", selected);
+			renderer.set("edited", edited);
+			renderer.set("focused", this.showFocus ? focused : false);
+			renderer.set("moveEnabled", this.isItemMoveEnabled(item._item, kind));
+			renderer.set("storeState", this.getItemStoreState(item));
+			
+			if(kind != "label"){
+				renderer.set("resizeEnabled", this.isItemResizeEnabled(item, kind));
+			}
+
+			this.applyRendererZIndex(item, ir, hovered, selected, edited, focused);
+
+			if(renderer.updateRendering){
+				renderer.updateRendering(w, h);
+			}
+										
+			domConstruct.place(ir.container, cell);
+			domStyle.set(ir.container, "display", "block");
+		},
+		
+		_getCellAt: function(rowIndex, columnIndex, rtl){
+			// tags:
+			//		private
+			
+			if((rtl == undefined || rtl == true) && !this.isLeftToRight()){
+				columnIndex = this.renderData.columnCount -1 - columnIndex;
+			}
+			return this.gridTable.childNodes[0].childNodes[rowIndex].childNodes[columnIndex];
+		},
+	
+		_layoutExpandRenderers: function(index, hasHiddenItems, hiddenItems){
+			// tags:
+			//		private
+			
+			if(!this.expandRenderer){
+				return;
+			}
+			var rd = this.renderData;
+			if(rd.expandedRow == index){
+				if(rd.expandedRowCol != null && rd.expandedRowCol != -1){
+					this._layoutExpandRendererImpl(rd.expandedRow, rd.expandedRowCol, null, true);
+				}
+			}else{
+				if(rd.expandedRow == null){
+					for(var i=0; i<rd.columnCount; i++){
+						if(hasHiddenItems[i]){
+							this._layoutExpandRendererImpl(index, rd.rtl ? rd.columnCount -1 -i: i, hiddenItems[i], false);
+						}
+					}
+				}
+			}
+		},
+		
+		_layoutExpandRendererImpl: function(rowIndex, colIndex, items, expanded){
+			// tags:
+			//		private
+			
+			var rd = this.renderData;
+			var d = lang.clone(rd.dates[rowIndex][colIndex]);
+			var ir = null;
+			var cell = rd.cells[rowIndex];					
+			
+			ir = this._getExpandRenderer(d,	items, rowIndex, colIndex, expanded);
+				
+			var dim = domGeometry.position(this._getCellAt(rowIndex, colIndex));
+			dim.x -= rd.gridTablePosX;
+			this.layoutExpandRenderer(ir, d, items, dim, this.expandRendererHeight);
+			domConstruct.place(ir.domNode, cell);
+			domStyle.set(ir.domNode, "display", "block");
+		},
+		
+		layoutExpandRenderer: function(renderer, date, items, cellPosition, height){
+			// summary:
+			//		Computes and sets the position of the expand/collapse renderers.
+			//		By default the renderer is set to take the width of the cell and is placed at the bottom of the cell.
+			//		The renderer DOM node is in a row that takes all the grid width. 
+			// renderer: Object
+			//		The renderer used in specified cell that indicates that some items cannot be displayed.
+			// date: Date
+			//		The date displayed by the cell.
+			// items: Object[]
+			//		The list of non visible items.
+			// cellPosition: Object
+			//		An object that contains the position (x and y properties) and size of the cell (w and h properties).
+			// tags:
+			//		private
+			domStyle.set(renderer.domNode, {
+				"left": cellPosition.x + "px",
+				"width": cellPosition.w + "px",
+				"height": height + "px",
+				"top":  (cellPosition.h - height -1) + "px"
+			});
+		},
+		
+		/////////////////////////////////////////////
+		//
+		// Editing
+		//
+		//////////////////////////////////////////////
+		
+		_onItemEditBeginGesture: function(e){
+			// tags:
+			//		private
+			var p = this._edProps;
+			
+			var item = p.editedItem;
+			var dates = e.dates;
+			
+			var refTime = this.newDate(p.editKind == "resizeEnd" ? item.endTime : item.startTime);
+			
+			if(p.rendererKind == "label"){
+				// noop
+			}else if(e.editKind == "move" && (item.allDay || this.roundToDay)){							
+				var cal = this.renderData.dateModule;
+				p.dayOffset = cal.difference(
+					this.floorToDay(dates[0], false, this.renderData), 
+					refTime, "day");
+			} // else managed in super
+			
+			this.inherited(arguments);
+		},
+		
+		_computeItemEditingTimes: function(item, editKind, rendererKind, times, eventSource){
+			// tags:
+			//		private
+			var cal = this.renderData.dateModule;
+			var p = this._edProps;
+			
+			if(rendererKind == "label"){ // noop
+			}else	if(item.allDay || this.roundToDay){		
+				var isStartOfDay = this.isStartOfDay(times[0]);	
+				switch(editKind){
+					case "resizeEnd":
+						if(!isStartOfDay && item.allDay){
+							times[0] = cal.add(times[0], "day", 1); // no break;
+						}
+					case "resizeStart":
+						if(!isStartOfDay){
+							times[0] = this.floorToDay(times[0], true);
+						}
+						break;
+					case "move":
+						times[0] = cal.add(times[0], "day", p.dayOffset);
+						break;
+					case "resizeBoth":
+						if(!isStartOfDay){
+							times[0] = this.floorToDay(times[0], true);
+						}
+						if(!this.isStartOfDay(times[1])){
+							times[1] = this.floorToDay(cal.add(times[1], "day", 1), true);
+						}
+						break; 
+				}	
+				
+			}else{
+				times = this.inherited(arguments); 
+			}			
+			
+			return times;			
+		},
+			
+		
+		/////////////////////////////////////////////
+		//
+		// Pixel to Time projection
+		//
+		//////////////////////////////////////////////
+		
+		getTime: function(e, x, y, touchIndex){
+			// summary:
+			//		Returns the time displayed at the specified point by this component.
+			// e: Event
+			//		Optional mouse event.
+			// x: Number
+			//		Position along the x-axis with respect to the sheet container used if event is not defined.
+			// y: Number
+			//		Position along the y-axis with respect to the sheet container (scroll included) used if event is not defined.
+			// touchIndex: Integer
+			//		If parameter 'e' is not null and a touch event, the index of the touch to use.
+			// returns: Date
+			
+			var rd = this.renderData;
+			
+			if(e != null){				
+				var refPos = domGeometry.position(this.itemContainer, true);
+				
+				if(e.touches){
+
+					touchIndex = touchIndex==undefined ? 0 : touchIndex;
+
+					x = e.touches[touchIndex].pageX - refPos.x;
+					y = e.touches[touchIndex].pageY - refPos.y;
+					
+				}else{
+
+					x = e.pageX - refPos.x;
+					y = e.pageY - refPos.y;
+				}
+			}
+			
+			var r = domGeometry.getContentBox(this.itemContainer);
+			
+			if(x < 0){
+				x = 0;
+			}else if(x > r.w){
+				x = r.w-1;
+			}
+			
+			if(y < 0){
+				y = 0;
+			}else if(y > r.h){
+				y = r.h-1;
+			}
+
+			// compute the date from column the time in day instead of time from start date of row to prevent DST hour offset.
+			
+			var w = domGeometry.getMarginBox(this.itemContainer).w;
+			var colW = w / rd.columnCount;
+			 
+			var row;
+			if(rd.expandedRow == null){
+				row = Math.floor(y / (domGeometry.getMarginBox(this.itemContainer).h / rd.rowCount));
+			}else{
+				row = rd.expandedRow; //other rows are not usable
+			}
+			
+			var r = domGeometry.getContentBox(this.itemContainer);
+			
+			if(rd.rtl){
+				x = r.w - x;
+			}
+			
+			var col = Math.floor(x / colW);
+			
+			var tm = Math.floor((x-(col*colW)) * 1440 / colW);
+			
+			var date = null;
+			if(row < rd.dates.length && col < this.renderData.dates[row].length){
+				date = this.newDate(this.renderData.dates[row][col]); 
+				date = this.renderData.dateModule.add(date, "minute", tm);
+			}
+			
+			return date;
+		},
+		
+		/////////////////////////////////////////////
+		//
+		// Event management
+		//
+		//////////////////////////////////////////////
+		
+		_onGridMouseUp: function(e){
+			// tags:
+			//		private
+			
+			this.inherited(arguments);
+			
+			if(this._gridMouseDown){
+				this._gridMouseDown = false;
+				
+				this._onGridClick({
+					date: this.getTime(e),
+					triggerEvent: e
+				});
+			}			
+		},
+		
+		_onGridTouchEnd: function(e){
+			// tags:
+			//		private
+			this.inherited(arguments);
+
+			var g = this._gridProps;
+			
+			if(g){
+				
+				if(!this._isEditing){
+						
+					// touched on grid and on touch start editing was ongoing.
+					if(!g.fromItem && !g.editingOnStart){
+						this.selectFromEvent(e, null, null, true);
+					}			
+					
+					if(!g.fromItem){
+					
+						if(this._pendingDoubleTap && this._pendingDoubleTap.grid){
+														
+							this._onGridDoubleClick({
+								date: this.getTime(this._gridProps.event),
+								triggerEvent: this._gridProps.event
+							});
+							
+							clearTimeout(this._pendingDoubleTap.timer);
+					
+							delete this._pendingDoubleTap;
+							
+						}else{
+
+							this._onGridClick({
+								date: this.getTime(this._gridProps.event),
+								triggerEvent: this._gridProps.event
+							});
+							
+							this._pendingDoubleTap = {
+								grid: true,
+								timer: setTimeout(lang.hitch(this, function(){
+										delete this._pendingDoubleTap;
+								}), this.doubleTapDelay)
+							};
+						}
+					}	
+				}
+				
+				this._gridProps = null;
+			}					
+		},
+		
+				
+		/////////////////////////////////////////////
+		//
+		// Events
+		//
+		//////////////////////////////////////////////
+		
+		_onRowHeaderClick: function(e){
+			this._dispatchCalendarEvt(e, "onRowHeaderClick");
+			// tags:
+			//		private
+		},
+		
+		onRowHeaderClick: function(e){
+			// summary:
+			//		Event dispatched when a row header cell is clicked.
+			// e: __HeaderClickEventArgs
+			//		Header click event.
+			// tags:
+			//		callback
+		},
+		
+		expandRendererClickHandler: function(e, renderer){
+			// summary:
+			//		Default action when an expand renderer is clicked.
+			// e: Event
+			//		The mouse event.
+			// renderer: Object
+			//		The expand renderer.
+			// tags:
+			//		protected
+			
+			event.stop(e);
+			
+			var ri = renderer.get("rowIndex");
+			var ci = renderer.get("columnIndex");
+			
+			this._onExpandRendererClick(lang.mixin(this._createItemEditEvent(), {
+				rowIndex: ri,
+				columnIndex: ci,
+				renderer: renderer,
+				triggerEvent: e,
+				date: this.renderData.dates[ri][ci]
+			}));
+		},
+		
+		onExpandRendererClick: function(e){
+			// summary:
+			//		Event dispatched when an expand renderer is clicked.
+			// e: __ExpandRendererClickEventArgs
+			//		Expand renderer click event.
+			// tags:
+			//		callback
+		},
+		
+		_onExpandRendererClick: function(e){
+			
+			this._dispatchCalendarEvt(e, "onExpandRendererClick");
+			
+			if(!e.isDefaultPrevented()){
+			
+				if(this.getExpandedRowIndex() != -1){
+					this.collapseRow();
+				}else{
+					this.expandRow(e.rowIndex, e.columnIndex);
+				}
+			}
+		},
+		
+		
+		////////////////////////////////////////////
+		//
+		// Editing
+		//
+		///////////////////////////////////////////
+								
+		snapUnit: "minute",
+		snapSteps: 15,
+		minDurationUnit: "minute",
+		minDurationSteps: 15,
+		triggerExtent: 3,
+		liveLayout: false,
+		stayInView: true,
+		allowStartEndSwap: true,
+		allowResizeLessThan24H: false		
+
+	});
+});
diff --git a/dojox/calendar/MobileCalendar.js b/dojox/calendar/MobileCalendar.js
new file mode 100644
index 0000000..5707108
--- /dev/null
+++ b/dojox/calendar/MobileCalendar.js
@@ -0,0 +1,58 @@
+define(["dojo/_base/declare", "dojo/_base/lang", "./CalendarBase", "./ColumnView", "./ColumnViewSecondarySheet", 
+				"./MobileVerticalRenderer", "./MatrixView",	"./MobileHorizontalRenderer", "./LabelRenderer", 
+				"./ExpandRenderer", "./Touch", "dojo/text!./templates/MobileCalendar.html", "dojox/mobile/Button"],
+	
+	function(declare, lang, CalendarBase, ColumnView, ColumnViewSecondarySheet, VerticalRenderer, 
+					 MatrixView, HorizontalRenderer, LabelRenderer, ExpandRenderer, Touch, template){
+	
+	return declare("dojox.calendar.MobileCalendar", CalendarBase, {
+		
+		// summary:
+		//		This class defines a calendar widget that display events in time designed to be used in mobile environment.
+		
+		templateString: template,
+		
+		_createDefaultViews: function(){
+			// summary:
+			//		Creates the default views:
+			//		- A dojox.calendar.ColumnView instance used to display one day to seven days time intervals,
+			//		- A dojox.calendar.MatrixView instance used to display the other time intervals.
+			//		The views are mixed with Mouse and Keyboard to allow editing items using mouse and keyboard.
+
+			var secondarySheetClass = declare([ColumnViewSecondarySheet, Touch]);
+			
+			var colView = declare([ColumnView, Touch])(lang.mixin({
+				secondarySheetClass: secondarySheetClass,
+				verticalRenderer: VerticalRenderer,
+				horizontalRenderer: HorizontalRenderer,
+				expandRenderer: ExpandRenderer
+			}, this.columnViewProps));
+			
+			var matrixView = declare([MatrixView, Touch])(lang.mixin({
+				horizontalRenderer: HorizontalRenderer,
+				labelRenderer: LabelRenderer,
+				expandRenderer: ExpandRenderer
+			}, this.matrixViewProps));
+								
+			this.columnView = colView;
+			this.matrixView = matrixView;
+			
+			var views = [colView, matrixView];
+			
+			this.installDefaultViewsActions(views);
+			
+			return views;
+		},
+		
+		installDefaultViewsActions: function(views){
+			// summary:
+			//		Installs the default actions on newly created default views.
+			//		By default this action is registering:
+			//		- the matrixViewRowHeaderClick method	on the rowHeaderClick event of the matrix view.
+			//		- the columnViewColumnHeaderClick method	on the columnHeaderClick event of the column view.
+			this.matrixView.on("rowHeaderClick", lang.hitch(this, this.matrixViewRowHeaderClick));
+			this.columnView.on("columnHeaderClick", lang.hitch(this, this.columnViewColumnHeaderClick));			
+		}
+		
+	});
+});
diff --git a/dojox/calendar/MobileHorizontalRenderer.js b/dojox/calendar/MobileHorizontalRenderer.js
new file mode 100644
index 0000000..79c80a0
--- /dev/null
+++ b/dojox/calendar/MobileHorizontalRenderer.js
@@ -0,0 +1,81 @@
+define([
+"dojo/_base/declare", 
+"dojo/dom-style", 
+"dijit/_WidgetBase", 
+"dijit/_TemplatedMixin",
+"dojox/calendar/_RendererMixin", 
+"dojo/text!./templates/MobileHorizontalRenderer.html"],
+	 
+function(
+declare, 
+domStyle, 
+_WidgetBase, 
+_TemplatedMixin, 
+_RendererMixin, 
+template){
+	
+	return declare("dojox.calendar.MobileHorizontalRenderer", [_WidgetBase, _TemplatedMixin, _RendererMixin], {
+		
+		// summary:
+		//		The mobile specific item horizontal renderer.
+		
+		templateString: template,
+		
+		_orientation: "horizontal",
+		
+		mobile: true,
+		
+		visibilityLimits: {
+			resizeStartHandle: 50,
+			resizeEndHandle: -1,
+			summaryLabel: 15,
+			startTimeLabel: 32,
+			endTimeLabel: 30
+		},
+		
+		_displayValue: "inline",
+		
+		// arrowPadding: Integer
+		//		The padding size in pixels to apply to the label container on left and/or right side, to show the arrows correctly.
+		arrowPadding: 12, 
+		
+		_isElementVisible: function(elt, startHidden, endHidden, size){
+			var d;
+			var ltr = this.isLeftToRight();
+			
+			if(elt == "startTimeLabel"){
+				if(this.labelContainer && (ltr && endHidden || !ltr && startHidden)){
+					domStyle.set(this.labelContainer, "marginRight", this.arrowPadding+"px");
+				}else{
+					domStyle.set(this.labelContainer, "marginRight", 0);
+				}
+				if(this.labelContainer && (!ltr && endHidden || ltr && startHidden)){
+					domStyle.set(this.labelContainer, "marginLeft", this.arrowPadding+"px");
+				}else{
+					domStyle.set(this.labelContainer, "marginLeft", 0);
+				}
+			}
+			
+			switch(elt){
+				case "startTimeLabel":
+					d = this.item.startTime;
+					if(this.item.allDay || this.owner.isStartOfDay(d)){
+						return false;
+					}
+					break;
+				case "endTimeLabel":
+					d = this.item.endTime;
+					if(this.item.allDay || this.owner.isStartOfDay(d)){
+						return false;
+					}
+					break;
+			}
+			return this.inherited(arguments);
+		},
+		
+		postCreate: function() {
+			this.inherited(arguments);
+			this._applyAttributes();
+		}
+	});
+});
diff --git a/dojox/calendar/MobileVerticalRenderer.js b/dojox/calendar/MobileVerticalRenderer.js
new file mode 100644
index 0000000..662ab6d
--- /dev/null
+++ b/dojox/calendar/MobileVerticalRenderer.js
@@ -0,0 +1,47 @@
+define(["dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin", 
+	"dojox/calendar/_RendererMixin", "dojo/text!./templates/MobileVerticalRenderer.html"],
+	 
+	function(declare, _WidgetBase, _TemplatedMixin, _RendererMixin, template){
+	
+	return declare("dojox.calendar.MobileVerticalRenderer", [_WidgetBase, _TemplatedMixin, _RendererMixin], {
+				
+		// summary:
+		//		The mobile specific item vertical renderer.
+		
+		templateString: template,
+		mobile: true,
+		
+		visibilityLimits: {
+			resizeStartHandle: 75,
+			resizeEndHandle: -1,
+			summaryLabel: 55,			
+			startTimeLabel: 75,
+			endTimeLabel: 20
+		},		
+		
+		postCreate: function() {
+			this.inherited(arguments);
+			this._applyAttributes();
+		},
+		
+		_isElementVisible: function(elt, startHidden, endHidden, size){
+			var d;
+			
+			switch(elt){
+				case "startTimeLabel":
+					d = this.item.startTime;
+					if(this.item.allDay || this.owner.isStartOfDay(d)){
+						return false;
+					}
+					break;
+				case "endTimeLabel":
+					d = this.item.endTime;
+					if(this.item.allDay || this.owner.isStartOfDay(d)){
+						return false;
+					}
+					break;
+			}
+			return this.inherited(arguments);
+		}
+	});
+});
diff --git a/dojox/calendar/MonthColumnView.js b/dojox/calendar/MonthColumnView.js
new file mode 100644
index 0000000..1beb731
--- /dev/null
+++ b/dojox/calendar/MonthColumnView.js
@@ -0,0 +1,1512 @@
+define([
+"./ViewBase", 
+"dijit/_TemplatedMixin", 
+"./_VerticalScrollBarBase", 
+"dojo/text!./templates/MonthColumnView.html",
+"dojo/_base/declare", 
+"dojo/_base/event", 
+"dojo/_base/lang", 
+"dojo/_base/array",
+"dojo/_base/sniff",
+"dojo/_base/fx", 
+"dojo/_base/html",
+"dojo/on",
+"dojo/dom", 
+"dojo/dom-class", 
+"dojo/dom-style", 
+"dojo/dom-geometry", 
+"dojo/dom-construct", 
+"dojo/mouse",
+"dojo/query", 
+"dojo/i18n",
+"dojox/html/metrics"],
+
+function(
+	ViewBase, 
+	_TemplatedMixin, 
+	_VerticalScrollBarBase, 
+	template, 
+	declare, 
+	event, 
+	lang, 
+	arr, 
+	has,
+	fx, 
+	html,
+	on,
+	dom, 
+	domClass, 
+	domStyle,
+	domGeometry, 
+	domConstruct,
+	mouse,
+	query, 
+	i18n,
+	metrics){
+	
+	/*=====
+	var __ColumnClickEventArgs = {
+		// summary:
+		//		A column click event.
+		// index: Integer
+		//		The column index. 
+		// date: Date
+		//		The date displayed by the column.
+		// triggerEvent: Event
+		//		The origin event.
+	};
+	=====*/
+				
+	return declare("dojox.calendar.MonthColumnView", [ViewBase, _TemplatedMixin], {
+
+		// summary:
+		//		The month column view is a calendar view used to display a month per column where each cell of the column is a day.
+
+		baseClass: "dojoxCalendarMonthColumnView",
+		
+		templateString: template,
+		
+		// viewKind: String
+		//		Type of the view. Used by the calendar widget to determine how to configure the view.
+		//		This view kind is "columns".
+		viewKind: "monthColumns",
+		
+		// scroll container is the focusable item to enable scrolling using up and down arrows
+		_setTabIndexAttr: "domNode",
+		
+		// renderData: Object
+		//		The render data is the object that contains all the properties needed to render the component.
+		renderData: null,		
+				
+		// startDate: Date
+		//		The start date of the time interval displayed.
+		//		If not set at initialization time, will be set to current day.
+		startDate: null,
+			
+		// columnCount: Integer
+		//		The number of column to display (from the startDate).
+		columnCount: 6,
+		
+		// daySize: Integer
+		//		The desired size in pixels of an hour on the screen.
+		//		Note that the effective size may be different as the time slot size must be an integer.
+		daySize: 30,
+		
+		// showCellLabel: Boolean
+		//		Whether display or not the grid cells label (usually the day of month).
+		showCellLabel: true,
+		
+		// showHiddenItems: Boolean
+		//		Whether show or not the hidden items.
+		//		By default the events that are shorter than a day are not displayed using vertical renderers by this widget.
+		//		But the grid cells that contains one or several hidden items display a decoration.
+		showHiddenItems: true,
+			
+		// verticalRenderer: Class
+		//		The class use to create vertical renderers.
+		verticalRenderer: null,
+		
+		// percentOverlap: Integer
+		//		The percentage of the renderer width used to superimpose one item renderer on another 
+		//		when two events are overlapping.
+		percentOverlap: 0,
+				
+		// horizontalGap: Integer
+		//		The number of pixels between two item renderers.
+		horizontalGap: 4,
+		
+		// columnHeaderFormatLength: String
+		//		Length of the column labels. Valid values are "wide" or "abbr".
+		columnHeaderFormatLength: null,
+		
+		// gridCellDatePattern: String
+		//		The date pattern of the cell labels. By default a custom function is used to compute the label.
+		gridCellDatePattern: null,
+		
+		// roundToDay: [private] Boolean
+		roundToDay: true,
+		
+		// _layoutUnit: String
+		//		Unit of layout: each column is displaying a month. 
+		_layoutUnit: "month",
+		
+		_columnHeaderHandlers: null,
+		
+		constructor: function(){
+			this.invalidatingProperties = ["columnCount", "startDate", "daySize", "percentOverlap", "verticalRenderer",
+				"columnHeaderDatePattern", "horizontalGap", "scrollBarRTLPosition", "itemToRendererKindFunc", 
+				"layoutPriorityFunction", "textDir", "items", "showCellLabel", "showHiddenItems"];
+			this._columnHeaderHandlers = [];
+		},
+		
+		postCreate: function(){
+			this.inherited(arguments);
+			this.keyboardUpDownUnit = "day";	
+			this.keyboardUpDownSteps =  1;			
+			this.keyboardLeftRightUnit = "month";			
+			this.keyboardLeftRightSteps = 1;
+			this.allDayKeyboardUpDownUnit = "day";			
+			this.allDayKeyboardUpDownSteps = 1;	
+			this.allDayKeyboardLeftRightUnit = "month";			
+			this.allDayKeyboardLeftRightSteps = 1;
+		},
+		
+		destroy: function(preserveDom){
+			this._cleanupColumnHeader();
+			if(this.scrollBar){
+				this.scrollBar.destroy(preserveDom);
+			}
+			this.inherited(arguments);
+		},
+		
+		_scrollBar_onScroll: function(value){
+			// tags:
+			//		private
+			this.scrollContainer.scrollTop = value;
+		},
+		
+		buildRendering: function(){
+			// tags:
+			//		private
+			this.inherited(arguments);
+			if(this.vScrollBar){
+				this.scrollBar = new _VerticalScrollBarBase(
+					{content: this.vScrollBarContent}, 
+					this.vScrollBar);
+					
+				this.scrollBar.on("scroll", lang.hitch(this, this._scrollBar_onScroll));
+				this._viewHandles.push(
+					on(this.scrollContainer, mouse.wheel,  
+						dojo.hitch(this, this._mouseWheelScrollHander)));
+			}
+		},
+		
+		postscript: function(){
+			this.inherited(arguments);
+			this._initialized = true;
+			if(!this.invalidRendering){
+				this.refreshRendering();
+			}
+		},
+		
+		_setVerticalRendererAttr: function(value){
+			this._destroyRenderersByKind("vertical");
+			this._set("verticalRenderer", value);	
+		},
+				
+		_createRenderData: function(){
+			
+			var rd = {};
+						
+			rd.daySize = this.get("daySize");				
+			rd.scrollbarWidth = metrics.getScrollbar().w + 1;
+					
+			rd.dateLocaleModule = this.dateLocaleModule;
+			rd.dateClassObj = this.dateClassObj;
+			rd.dateModule = this.dateModule; // arithmetics on Dates
+			
+			rd.dates = [];
+						
+			rd.columnCount = this.get("columnCount");
+
+			var d = this.get("startDate");
+		
+			if (d == null){
+				d = new rd.dateClassObj();
+			}
+
+			d = this.floorToMonth(d, false, rd);
+			
+			this.startDate = d;
+			var currentMonth = d.getMonth();
+			var maxDayCount = 0;			
+			
+			for(var col = 0; col < rd.columnCount ; col++){
+				
+				var dates = [];
+				rd.dates.push(dates);
+				
+				while(d.getMonth() == currentMonth){							
+					dates.push(d);
+					d = rd.dateModule.add(d, "day", 1);
+					d = this.floorToDay(d, false, rd);					
+				}
+				
+				currentMonth = d.getMonth();
+				
+				if(maxDayCount < dates.length){
+					maxDayCount = dates.length;
+				}						
+			}
+						
+			rd.startTime = new rd.dateClassObj(rd.dates[0][0]);			
+			rd.endTime = new rd.dateClassObj(dates[dates.length-1]);
+			rd.endTime = rd.dateModule.add(rd.endTime, "day", 1);
+						
+			rd.maxDayCount = maxDayCount;
+			rd.sheetHeight = rd.daySize * maxDayCount;
+			
+			if(this.displayedItemsInvalidated){
+				this.displayedItemsInvalidated = false;
+				this._computeVisibleItems(rd);
+				
+				if(this._isEditing){					
+					this._endItemEditing(null, false);
+				}
+				
+			}else if (this.renderData){
+				rd.items = this.renderData.items;
+			}
+			
+			return rd;
+		},
+		
+		_validateProperties: function() {
+			
+			this.inherited(arguments);
+						
+			if (this.columnCount<1 || isNaN(this.columnCount)){
+				this.columnCount = 1;				
+			}
+			
+			if(this.daySize<5 || isNaN(this.daySize)){
+				this.daySize = 5;
+			}
+			
+		},
+		
+		_setStartDateAttr: function(value){
+			this.displayedItemsInvalidated = true;			
+			this._set("startDate", value);
+		},
+		
+		_setColumnCountAttr: function(value){			
+			this.displayedItemsInvalidated = true;
+			this._set("columnCount", value);
+		},
+		
+		__fixEvt:function(e){
+			e.sheet = "primary";
+			e.source = this;
+			return e;
+		},
+		
+		//////////////////////////////////////////
+		//
+		// Formatting functions
+		//
+		//////////////////////////////////////////
+		
+		_formatColumnHeaderLabel: function(/*Date*/d){			
+			// summary:
+			//		Computes the column header label for the specified date.
+			// d: Date
+			//		The date to format
+			// tags:
+			//		protected
+			
+			var len = "wide";
+			
+			if(this.columnHeaderFormatLength){
+				len = this.columnHeaderFormatLength;
+			}
+			
+			var months = this.renderData.dateLocaleModule.getNames("months", len, "standAlone");
+			
+			return months[d.getMonth()];
+		},
+		
+		_formatGridCellLabel: function(d, row, col){
+			// summary:
+			//		Computes the column header label for the specified date.
+			//		By default a formatter is used, optionally the <code>gridCellDatePattern</code> 
+			//		property can be used to set a custom date pattern to the formatter.
+			// d: Date
+			//		The date to format.
+			// row: Integer
+			//		The row that displays the current date.
+			// col: Integer
+			//		The column that displays the current date.
+			// tags:
+			//		protected
+
+			var format, rb;
+			
+			if(d == null){
+				return "";
+			}
+			
+			if(this.gridCellPattern){
+				return this.renderData.dateLocaleModule.format(d, {
+					selector: 'date',
+					datePattern: this.gridCellDatePattern
+				});
+			}else{
+				rb = i18n.getLocalization("dojo.cldr", this._calendar);
+				format = rb["dateFormatItem-d"];
+			
+				var days = this.renderData.dateLocaleModule.getNames("days", "abbr", "standAlone");
+					
+				return days[d.getDay()].substring(0, 1) + " " + this.renderData.dateLocaleModule.format(d, {
+					selector: 'date',
+					datePattern: format
+				});
+			}
+		},
+		
+		//////////////////////////////////////////
+		//
+		// Time of day management
+		//
+		//////////////////////////////////////////
+		
+		// scrollPosition: Integer
+		//		The scroll position of the view. 
+		scrollPosition: null,
+				
+		// scrollBarRTLPosition: String
+		//		Position of the scroll bar in right-to-left display.
+		//		Valid values are "left" and "right", default value is "left".
+		scrollBarRTLPosition: "left",
+					
+		_setScrollPositionAttr: function(value){
+			this._setScrollPosition(value.date, value.duration, value.easing);
+		},
+		
+		_getScrollPositionAttr: function(){
+			return {date: (this.scrollContainer.scrollTop / this.daySize) + 1};
+		},
+		
+		_setScrollPosition: function(date, maxDuration, easing){
+			// tags:
+			//		private
+			
+			if(date < 1){
+				date = 1;
+			}else if(date>31){
+				date = 31;
+			}
+			
+			var position = (date-1) * this.daySize;
+			
+			if(maxDuration) {
+				
+				if(this._scrollAnimation){
+					this._scrollAnimation.stop();
+				}
+				
+				var duration = Math.abs(((position - this.scrollContainer.scrollTop) * maxDuration) / this.renderData.sheetHeight);
+				
+				this._scrollAnimation = new fx.Animation({
+					curve: [this.scrollContainer.scrollTop, position],
+					duration: duration,
+					easing: easing,
+					onAnimate: lang.hitch(this, function(position) {
+						this._setScrollImpl(position);
+					})
+				});
+								
+				this._scrollAnimation.play();
+
+			}else{
+				this._setScrollImpl(position);
+			}
+		},
+		
+		_setScrollImpl: function(v){
+			// tags:
+			//		private
+			
+			this.scrollContainer.scrollTop = v;
+			if(this.scrollBar){
+				this.scrollBar.set("value", v);
+			}
+		},
+		
+		ensureVisibility: function(start, end, visibilityTarget, margin, duration){
+			
+			// summary:
+			//		Scrolls the view if the [start, end] time range is not visible or only partially visible.
+			// start: Date
+			//		Start time of the range of interest.
+			// end: Date
+			//		End time of the range of interest.
+			// margin: Integer
+			//		Margin in minutes around the time range.
+			// visibilityTarget: String
+			//		The end(s) of the time range to make visible.
+			//		Valid values are: "start", "end", "both".	
+			// duration: Number
+			//		Optional, the maximum duration of the scroll animation.
+			
+			margin = margin == undefined ? 1 : margin;
+			
+			if(this.scrollable && this.autoScroll){
+							
+				var s = start.getDate() - margin; // -1 because day of months starts at 1 and not 0
+				if(this.isStartOfDay(end)){
+					end = this._waDojoxAddIssue(end, "day", -1);
+				}
+				var e = end.getDate() + margin;
+				
+				var viewStart = this.get("scrollPosition").date;
+				var r = domGeometry.getContentBox(this.scrollContainer);
+				var viewEnd = (this.get("scrollPosition").date + (r.h/this.daySize)); 
+				
+				var visible = false;
+				var target = null;
+				
+				switch(visibilityTarget){
+					case "start":
+						visible = s >= viewStart && s <= viewEnd;
+						target = s ;
+						break;
+					case "end":
+						visible = e >= viewStart && e <= viewEnd;
+						target = e - (viewEnd - viewStart);
+						break;
+					case "both":
+						visible = s >= viewStart && e <= viewEnd;
+						target = s;
+						break;
+				}
+				
+				if(!visible){
+					this._setScrollPosition(target, duration);
+				}
+			}
+		},
+		
+		scrollView: function(dir){
+			// summary:
+			//		Scrolls the view to the specified direction of one time slot duration.
+			// dir: Integer
+			//		Direction of the scroll. Valid values are -1 and 1.
+			//
+			var pos = this.get("scrollPosition").date + dir;
+			this._setScrollPosition(pos);
+		},
+		
+		_mouseWheelScrollHander: function(e){
+			// summary:
+			//		Mouse wheel handler.
+			// tags:
+			//		protected
+			this.scrollView(e.wheelDelta > 0 ? -1 : 1);
+		},		
+		
+		//////////////////////////////////////////
+		//
+		// HTML structure management
+		//
+		//////////////////////////////////////////		
+	
+		refreshRendering: function(){
+			if(!this._initialized){
+				return;
+			}
+						
+			this._validateProperties();
+
+			var oldRd = this.renderData;
+			var rd = this._createRenderData();
+			this.renderData = rd;			
+			this._createRendering(rd, oldRd);
+			this._layoutRenderers(rd);
+		},
+		
+		_createRendering: function(/*Object*/renderData, /*Object*/oldRenderData){
+			// tags:
+			//		private
+			domStyle.set(this.sheetContainer, "height", renderData.sheetHeight + "px");
+			// padding for the scroll bar.
+			this._configureScrollBar(renderData);
+			this._buildColumnHeader(renderData, oldRenderData);			
+			this._buildGrid(renderData, oldRenderData);
+			this._buildItemContainer(renderData, oldRenderData);
+		},
+		
+		_configureScrollBar: function(renderData){
+			// summary:
+			//		Sets the scroll bar size and position.
+			// renderData: Object
+			//		The render data.
+			// tags:
+			//		protected
+			
+			if(has("ie") && this.scrollBar){
+				domStyle.set(this.scrollBar.domNode, "width", (renderData.scrollbarWidth + 1) + "px");
+			}
+						
+			var atRight = this.isLeftToRight() ? true : this.scrollBarRTLPosition == "right";
+			var rPos = atRight ? "right" : "left";
+			var lPos = atRight? "left" : "right";
+			
+			if(this.scrollBar){
+				this.scrollBar.set("maximum", renderData.sheetHeight);			
+				domStyle.set(this.scrollBar.domNode, rPos, 0);
+				domStyle.set(this.scrollBar.domNode, lPos, "auto");
+			}
+			domStyle.set(this.scrollContainer, rPos, renderData.scrollbarWidth + "px");
+			domStyle.set(this.scrollContainer, lPos, "0");
+			domStyle.set(this.columnHeader, rPos, renderData.scrollbarWidth + "px");
+			domStyle.set(this.columnHeader, lPos, "0");
+			if(this.buttonContainer && this.owner != null && this.owner.currentView == this){
+				domStyle.set(this.buttonContainer, rPos, renderData.scrollbarWidth + "px");
+				domStyle.set(this.buttonContainer, lPos, "0");
+			}
+		},
+		
+		_columnHeaderClick: function(e){
+			// tags:
+			//		private
+
+			event.stop(e);
+			var index = query("td", this.columnHeaderTable).indexOf(e.currentTarget);
+			this._onColumnHeaderClick({
+				index: index,
+				date: this.renderData.dates[index][0],
+				triggerEvent: e
+			});						
+		},
+		
+		_buildColumnHeader: function(renderData, oldRenderData){				
+			// summary:
+			//		Creates incrementally the HTML structure of the column header and configures its content.
+			//
+			// renderData:
+			//		The render data to display.
+			//
+			// oldRenderData:
+			//		The previously render data displayed, if any.
+			// tags:
+			//		private
+
+
+			var table = this.columnHeaderTable;
+			
+			if (!table){
+				return;
+			}
+					
+			var count = renderData.columnCount - (oldRenderData ? oldRenderData.columnCount : 0);
+			
+			if(has("ie") == 8){
+				// workaround Internet Explorer 8 bug.
+				// if on the table, width: 100% and table-layout: fixed are set
+				// and columns are removed, width of remaining columns is not 
+				// recomputed: must rebuild all. 
+				if(this._colTableSave == null){
+					this._colTableSave = lang.clone(table);
+				}else if(count < 0){
+					this._cleanupColumnHeader();
+					this.columnHeader.removeChild(table);
+					domConstruct.destroy(table);
+					table = lang.clone(this._colTableSave);
+					this.columnHeaderTable = table;
+					this.columnHeader.appendChild(table);
+					count = renderData.columnCount;
+				}
+				
+			} // else incremental dom add/remove for real browsers.
+					
+			var tbodies = query("tbody", table);
+			
+			var trs = query("tr", table);
+			var tbody, tr, td;
+			
+			if (tbodies.length == 1){
+				tbody = tbodies[0];
+			}else{ 
+				tbody = html.create("tbody", null, table);
+			}
+			
+			if (trs.length == 1){
+				tr = trs[0];
+			}else{ 
+				tr = domConstruct.create("tr", null, tbody);
+			}
+						 
+			// Build HTML structure (incremental)
+			if(count > 0){ // creation				
+				for(var i=0; i < count; i++){
+														
+					td = domConstruct.create("td", null, tr);
+					
+					var h = [];
+					h.push(on(td, "click", lang.hitch(this, this._columnHeaderClick)));
+										
+					if(has("touch")){					
+						h.push(on(td, "touchstart", function(e){
+							event.stop(e);
+							domClass.add(e.currentTarget, "Active");
+						}));
+						
+						h.push(on(td, "touchend", function(e){			
+							event.stop(e);			
+							domClass.remove(e.currentTarget, "Active");			
+						}));
+					}else{
+						h.push(on(td, "mousedown", function(e){
+							event.stop(e);
+							domClass.add(e.currentTarget, "Active");
+						}));
+												
+						h.push(on(td, "mouseup", function(e){
+							event.stop(e);
+							domClass.remove(e.currentTarget, "Active");
+						}));					
+						
+						h.push(on(td, "mouseover", function(e){
+							event.stop(e);
+							domClass.add(e.currentTarget, "Hover");
+						}));
+											
+						h.push(on(td, "mouseout", function(e){
+							event.stop(e);
+							domClass.remove(e.currentTarget, "Hover");
+						}));
+					
+					}
+					
+					this._columnHeaderHandlers.push(h);					 
+				}
+				
+			}else{ // deletion
+				count = -count;
+				for(var i=0; i < count; i++){
+					td = tr.lastChild;
+					tr.removeChild(td);
+					domConstruct.destroy(td);
+					var list = this._columnHeaderHandlers.pop();
+					while(list.length>0){
+						list.pop().remove();
+					}
+				}
+			}
+			
+			// fill & configure		
+			query("td", table).forEach(function(td, i){
+				td.className = "";											
+				if(i == 0){
+					domClass.add(td, "first-child");
+				}else if(i == this.renderData.columnCount-1){
+					domClass.add(td, "last-child");
+				}
+				var d = renderData.dates[i][0];
+				this._setText(td, this._formatColumnHeaderLabel(d));
+				this.styleColumnHeaderCell(td, d, renderData);						
+			}, this);
+						
+		},
+		
+		_cleanupColumnHeader: function(){
+			// tags:
+			//		private
+
+			while(this._columnHeaderHandlers.length > 0){
+				var list = this._columnHeaderHandlers.pop();
+				while(list.length > 0){
+					list.pop().remove();
+				}
+			}
+		},
+		
+		styleColumnHeaderCell: function(node, date, renderData){
+			// summary:
+			//		Styles the CSS classes to the node that displays a column header cell.
+			//		By default this method is does nothing and is designed to be overridden.
+			// node: Node
+			//		The DOM node that displays the column in the grid.
+			// date: Date
+			//		The date displayed by this column
+			// renderData: Object			
+			//		The render data.			
+			// tags:
+			//		protected
+
+		},
+		
+		_buildGrid: function (renderData, oldRenderData){
+			// summary:
+			//		Creates incrementally the HTML structure of the grid and configures its content.
+			//
+			// renderData:
+			//		The render data to display.
+			//
+			// oldRenderData:
+			//		The previously render data displayed, if any.
+			// tags:
+			//		private
+
+
+			var table = this.gridTable;
+			
+			if(!table){
+				return;
+			}
+			
+			domStyle.set(table, "height", renderData.sheetHeight + "px");				
+
+			var rowDiff = renderData.maxDayCount - (oldRenderData ? oldRenderData.maxDayCount : 0);
+			var addRows = rowDiff > 0;
+			
+			var colDiff  = renderData.columnCount - (oldRenderData ? oldRenderData.columnCount : 0);
+			
+			if(has("ie") == 8){
+				// workaround Internet Explorer 8 bug.
+				// if on the table, width: 100% and table-layout: fixed are set
+				// and columns are removed, width of remaining columns is not 
+				// recomputed: must rebuild all. 
+				if(this._gridTableSave == null){
+					this._gridTableSave = lang.clone(table);
+				}else if(colDiff < 0){					
+					this.grid.removeChild(table);
+					domConstruct.destroy(table);
+					table = lang.clone(this._gridTableSave);
+					this.gridTable = table;
+					this.grid.appendChild(table);
+					colDiff = renderData.columnCount;
+					rowDiff = renderData.maxDayCount;
+					addRows = true;
+				}				
+			}
+			
+			var tbodies = query("tbody", table);
+			var tbody;
+
+			if(tbodies.length == 1){
+				tbody = tbodies[0];
+			}else{ 
+				tbody = domConstruct.create("tbody", null, table);
+			}
+
+			// Build rows HTML structure (incremental)
+			if(addRows){ // creation
+				for(var i=0; i<rowDiff; i++){
+					domConstruct.create("tr", null, tbody);
+				}		 
+			}else{ // deletion		 
+				rowDiff = -rowDiff;
+				for(var i=0; i<rowDiff; i++){
+					tbody.removeChild(tbody.lastChild);
+				}
+			}
+
+			var rowIndex = renderData.maxDayCount - rowDiff;
+			
+			var addCols = addRows || colDiff >0; 
+			colDiff = addCols ? colDiff : -colDiff;
+			
+			query("tr", table).forEach(function(tr, i){
+				
+				if(addCols){ // creation
+					var len = i >= rowIndex ? renderData.columnCount : colDiff;
+					for(var i=0; i<len; i++){
+						var td = domConstruct.create("td", null, tr);
+						domConstruct.create("span", null, td);
+					}
+				}else{ // deletion
+					for(var i=0; i<colDiff; i++){
+						tr.removeChild(tr.lastChild);
+					}
+				}
+			});
+
+			// Set the CSS classes
+
+			query("tr", table).forEach(function (tr, row){
+				
+				tr.className = "";
+				// compatibility layer for IE7 & 8 that does not support :first-child and :last-child pseudo selectors
+				if(row == 0){
+					domClass.add(tr, "first-child");
+				}
+				if(row == renderData.maxDayCount-1){
+					domClass.add(tr, "last-child");
+				}
+
+				query("td", tr).forEach(function (td, col){
+					
+					td.className = "";
+					
+					if(col == 0){
+						domClass.add(td, "first-child");
+					}
+					
+					if(col == renderData.columnCount-1){
+						domClass.add(td, "last-child");
+					}
+					
+					var d = null;
+					if(row < renderData.dates[col].length) {
+						d = renderData.dates[col][row];
+					}
+					
+					var span = query("span", td)[0];
+					this._setText(span, this.showCellLabel ? this._formatGridCellLabel(d, row, col): null);
+					
+					this.styleGridCell(td, d, col, row, renderData);
+					
+				}, this);
+			}, this); 
+
+		},
+		
+		// styleGridCellFunc: Function
+		//		Custom function to customize the appearance of a grid cell by installing custom CSS class on the node.
+		//		The signature of the function must be the same then the styleGridCell one.
+		//		By default the defaultStyleGridCell function is used.
+		styleGridCellFunc: null,
+		
+		defaultStyleGridCell: function(node, date, col, row, renderData){
+			// summary:
+			//		Styles the CSS classes to the node that displays a column.
+			//		By default this method is setting the following CSS classes:
+			//		- "dojoxCalendarToday" class name if the date displayed is the current date,
+			//		- "dojoxCalendarWeekend" if the date represents a weekend,
+			//		- the CSS class corresponding of the displayed day of week ("Sun", "Mon" and so on),
+			// node: Node
+			//		The DOM node that displays the cell in the grid.
+			// date: Date
+			//		The date displayed by this cell.
+			// col: Integer
+			//		The column index of this cell.
+			// row: Integer
+			//		The row index of this cell.
+			// renderData: Object
+			//		The render data.
+			// tags:
+			//		protected
+			
+			if(date == null){
+				return;
+			}
+			domClass.add(node, this._cssDays[date.getDay()]);
+			if(this.isToday(date)){				
+				domClass.add(node, "dojoxCalendarToday");
+			}else if(this.isWeekEnd(date)){
+				domClass.add(node, "dojoxCalendarWeekend");
+			}					
+		},
+		
+		styleGridCell: function(node, date, col, row, renderData){
+			// summary:
+			//		Styles the CSS classes to the node that displays a column.
+			//		Delegates to styleGridCellFunc if defined or defaultStyleGridCell otherwise.
+			// node: Node
+			//		The DOM node that displays the cell in the grid.
+			// date: Date
+			//		The date displayed by this cell.
+			// col: Integer
+			//		The column index of this cell.
+			// row: Integer
+			//		The row index of this cell.
+			// renderData: Object
+			//		The render data.
+			// tags:
+			//		protected
+
+			if(this.styleGridCellFunc){
+				this.styleGridCellFunc(node, date, col, row, renderData);
+			}else{
+				this.defaultStyleGridCell(node, date, col, row, renderData);
+			}				
+		},
+							
+		_buildItemContainer: function(renderData, oldRenderData){
+			// summary:
+			//		Creates the HTML structure of the item container and configures its content.
+			// renderData:
+			//		The render data to display.
+			// oldRenderData:
+			//		The previously render data displayed, if any.
+			// tags:
+			//		private
+
+			
+			var table = this.itemContainerTable;
+			
+			if (!table){
+				return;
+			}
+			
+			var bgCols = [];
+	
+			domStyle.set(table, "height", renderData.sheetHeight + "px");			
+			
+			var count = renderData.columnCount - (oldRenderData ? oldRenderData.columnCount : 0);
+			
+			if(has("ie") == 8){
+				// workaround Internet Explorer 8 bug.
+				// if on the table, width: 100% and table-layout: fixed are set
+				// and columns are removed, width of remaining columns is not 
+				// recomputed: must rebuild all. 
+				if(this._itemTableSave == null){
+					this._itemTableSave = lang.clone(table);
+				}else if(count < 0){
+					this.itemContainer.removeChild(table);
+					this._recycleItemRenderers(true);
+					domConstruct.destroy(table);
+					table = lang.clone(this._itemTableSave);
+					this.itemContainerTable = table;
+					this.itemContainer.appendChild(table);
+					count = renderData.columnCount;
+				}
+				
+			} // else incremental dom add/remove for real browsers.
+			
+			var tbodies = query("tbody", table);
+			var trs = query("tr", table);
+			var tbody, tr, td;
+			
+			if (tbodies.length == 1){
+				tbody = tbodies[0];
+			}else{ 
+				tbody = domConstruct.create("tbody", null, table);
+			}
+			
+			if (trs.length == 1){
+				tr = trs[0];
+			}else{ 
+				tr = domConstruct.create("tr", null, tbody);
+			}					
+								
+			// Build HTML structure (incremental)
+			if(count>0){ // creation
+				for(var i=0; i < count; i++){
+					td = domConstruct.create("td", null, tr);	
+					domConstruct.create("div", {"className": "dojoxCalendarContainerColumn"}, td);
+				}
+			}else{ // deletion		 
+				count = -count;
+				for(var i=0; i < count; i++){
+					tr.removeChild(tr.lastChild);
+				}
+			}	
+			
+			query("td>div", table).forEach(function(div, i){
+
+				domStyle.set(div, {
+					"height": renderData.sheetHeight + "px"
+				});
+				bgCols.push(div);		
+			}, this);
+			
+			renderData.cells = bgCols;
+		},			
+		
+		///////////////////////////////////////////////////////////////
+		//
+		// Layout
+		//
+		///////////////////////////////////////////////////////////////
+		
+		_overlapLayoutPass2: function(lanes){
+			// summary:
+			//		Second pass of the overlap layout (optional). Compute the extent of each layout item.
+			// lanes:
+			//		The array of lanes.
+			// tags:
+			//		private
+			var i,j,lane, layoutItem;
+			// last lane, no extent possible
+			lane = lanes[lanes.length-1];
+			
+			for(j = 0; j < lane.length; j++){
+				lane[j].extent = 1;
+			}
+						
+			for(i=0; i<lanes.length-1; i++){
+				lane = lanes[i];
+				
+				for(var j=0; j<lane.length; j++){	 
+					layoutItem = lane[j];
+					
+					// if item was already overlapping another one there is no extent possible.
+					if(layoutItem.extent == -1){
+						layoutItem.extent = 1;
+						var space = 0;
+						
+						var stop = false;
+						
+						for(var k = i + 1; k < lanes.length && !stop; k++){
+							var ccol = lanes[k];
+							for(var l = 0; l < ccol.length && !stop; l++){
+								var layoutItem2 = ccol[l];
+								
+								if(layoutItem.start < layoutItem2.end && layoutItem2.start < layoutItem.end){
+									stop = true;
+								}
+							}
+							if(!stop){
+								//no hit in the entire lane
+								space++;
+							}
+						}
+						layoutItem.extent += space;
+					}
+				}
+			}
+		},
+		
+		_defaultItemToRendererKindFunc: function(item){
+			// tags:
+			//		private
+
+			if(item.allDay){
+				return "vertical";
+			}
+			var dur = Math.abs(this.renderData.dateModule.difference(item.startTime, item.endTime, "minute"));
+			return dur >= 1440 ? "vertical" : null;
+		},
+		
+		_layoutRenderers: function(renderData){
+			this.hiddenEvents = {};
+			this.inherited(arguments);
+		},
+		
+		_layoutInterval: function(/*Object*/renderData, /*Integer*/index, /*Date*/start, /*Date*/end, /*Object[]*/items){
+			// tags:
+			//		private
+
+			var verticalItems = [];
+			var hiddenItems = [];
+			renderData.colW = this.itemContainer.offsetWidth / renderData.columnCount;
+			
+			for(var i=0; i<items.length; i++){
+				var item = items[i];
+				if(this._itemToRendererKind(item) == "vertical"){
+					verticalItems.push(item);
+				}else if(this.showHiddenItems){	
+					hiddenItems.push(item);					
+				}
+			}
+			
+			if(verticalItems.length > 0){
+				this._layoutVerticalItems(renderData, index, start, end, verticalItems);
+			}
+			if(hiddenItems.length > 0){
+				this._layoutBgItems(renderData, index, start, end, hiddenItems);
+			}
+		},
+		
+		_dateToYCoordinate: function(renderData, d, start){
+			// tags:
+			//		private
+
+			var pos = 0;
+			if(start || d.getHours() != 0 || d.getMinutes() != 0){
+				pos = (d.getDate()-1) * this.renderData.daySize;
+			}else{
+				var d2 = this._waDojoxAddIssue(d, "day", -1);
+				pos = this.renderData.daySize + ((d2.getDate()-1) * this.renderData.daySize);
+			}			 
+			pos += (d.getHours()*60+d.getMinutes())*this.renderData.daySize/1440;
+			
+			return pos;
+		},
+		
+		_layoutVerticalItems: function(/*Object*/renderData, /*Integer*/index, /*Date*/startTime, /*Date*/endTime, /*Object[]*/items){
+			// tags:
+			//		private
+
+			if(this.verticalRenderer == null){
+				return;
+			}
+			
+			var cell = renderData.cells[index];
+			var layoutItems = [];			
+			
+			// step 1 compute projected position and size
+			for(var i = 0; i < items.length; i++){
+				
+				var item = items[i];
+				var overlap = this.computeRangeOverlap(renderData, item.startTime, item.endTime, startTime, endTime);
+				
+				var top = this._dateToYCoordinate(renderData, overlap[0], true);
+				var bottom = this._dateToYCoordinate(renderData, overlap[1], false);
+				
+				if (bottom > top){
+					var litem = lang.mixin({
+						start: top,
+						end: bottom,
+						range: overlap,
+						item: item
+					}, item);
+					layoutItems.push(litem);
+				}
+			}
+			
+			// step 2: compute overlapping layout
+			var numLanes = this.computeOverlapping(layoutItems, this._overlapLayoutPass2).numLanes;
+
+			var hOverlap = this.percentOverlap / 100;
+
+			// step 3: create renderers and apply layout
+			for(i=0; i<layoutItems.length; i++){
+
+				item = layoutItems[i];					
+				var lane = item.lane;
+				var extent = item.extent;
+
+				var w;
+				var posX;				
+
+				if(hOverlap == 0) {
+					//no overlap and a padding between each event
+					w = numLanes == 1 ? renderData.colW : ((renderData.colW - (numLanes - 1) * this.horizontalGap)/ numLanes);
+					posX = lane * (w + this.horizontalGap);
+					w = extent == 1 ? w : w * extent + (extent-1) * this.horizontalGap;
+					w = 100 * w / renderData.colW;
+					posX = 100 * posX / renderData.colW; 
+				} else {
+					// an overlap
+					w = numLanes == 1 ? 100 : (100 / (numLanes - (numLanes - 1) * hOverlap));
+					posX = lane * (w - hOverlap*w);
+					w = extent == 1 ? w : w * ( extent - (extent-1) * hOverlap);
+				}
+
+				var ir = this._createRenderer(item, "vertical", this.verticalRenderer, "dojoxCalendarVertical");
+
+				domStyle.set(ir.container, {
+					"top": item.start + "px",
+					"left": posX + "%",
+					"width": w + "%",
+					"height": (item.end-item.start+1) + "px"
+				});
+
+				var edited = this.isItemBeingEdited(item);
+				var selected = this.isItemSelected(item);
+				var hovered = this.isItemHovered(item);
+				var focused = this.isItemFocused(item);
+				
+				var renderer = ir.renderer;
+
+				renderer.set("hovered", hovered);
+				renderer.set("selected", selected);
+				renderer.set("edited", edited);
+				renderer.set("focused", this.showFocus ? focused : false);
+				
+				renderer.set("storeState", this.getItemStoreState(item));
+				
+				renderer.set("moveEnabled", this.isItemMoveEnabled(item._item, "vertical"));
+				renderer.set("resizeEnabled", this.isItemResizeEnabled(item._item, "vertical"));
+				
+				this.applyRendererZIndex(item, ir, hovered, selected, edited, focused);
+
+				if(renderer.updateRendering){
+					renderer.updateRendering(w, item.end-item.start+1);
+				}
+
+				domConstruct.place(ir.container, cell);
+				domStyle.set(ir.container, "display", "block");
+			}
+		},
+		
+		_getCellAt: function(rowIndex, columnIndex, rtl){
+			// tags:
+			//		private
+
+			if((rtl == undefined || rtl == true) && !this.isLeftToRight()){
+				columnIndex = this.renderData.columnCount -1 - columnIndex;
+			}
+			return this.gridTable.childNodes[0].childNodes[rowIndex].childNodes[columnIndex];
+		},
+		
+		invalidateLayout: function(){
+			//make sure to clear hiddens object state
+			query("td", this.gridTable).forEach(function(td){
+				domClass.remove(td, "dojoxCalendarHiddenEvents");
+			});
+			this.inherited(arguments);			
+		},
+		
+		_layoutBgItems: function(/*Object*/renderData, /*Integer*/col, /*Date*/startTime, /*Date*/endTime, /*Object[]*/items){
+			// tags:
+			//		private
+
+			var bgItems = {};
+			for(var i = 0; i < items.length; i++){
+				
+				var item = items[i];
+				var overlap = this.computeRangeOverlap(renderData, item.startTime, item.endTime, startTime, endTime);
+				var start = overlap[0].getDate()-1;
+				// handle use case where end time is first day of next month.
+				var end;
+				if(this.isStartOfDay(overlap[1])){
+					end = this._waDojoxAddIssue(overlap[1], "day", -1);
+					end = end.getDate()-1;
+				}else{
+					end = overlap[1].getDate()-1;
+				}
+				
+				for (var d=start; d<=end; d++){
+					bgItems[d] = true;
+				}
+			}					
+	
+			for(var row in bgItems) {
+				if(bgItems[row]){
+					var node = this._getCellAt(row, col, false);
+					domClass.add(node, "dojoxCalendarHiddenEvents");
+				}
+			}			
+		},
+		
+		_sortItemsFunction: function(a, b){
+			// tags:
+			//		private
+
+			var res = this.dateModule.compare(a.startTime, b.startTime);
+			if(res == 0){
+				res = -1 * this.dateModule.compare(a.endTime, b.endTime);
+			}
+			return this.isLeftToRight() ? res : -res;
+		},
+		
+		///////////////////////////////////////////////////////////////
+		//
+		// View to time projection
+		//
+		///////////////////////////////////////////////////////////////
+		
+		getTime: function(e, x, y, touchIndex){
+			// summary:
+			//		Returns the time displayed at the specified point by this component.
+			// e: Event
+			//		Optional mouse event.
+			// x: Number
+			//		Position along the x-axis with respect to the sheet container used if event is not defined.
+			// y: Number
+			//		Position along the y-axis with respect to the sheet container (scroll included) used if event is not defined.
+			// touchIndex: Integer
+			//		If parameter 'e' is not null and a touch event, the index of the touch to use.
+			// returns: Date
+			
+			if (e != null){				
+				var refPos = domGeometry.position(this.itemContainer, true);
+				
+				if(e.touches){									
+					
+					touchIndex = touchIndex==undefined ? 0 : touchIndex;
+									
+					x = e.touches[touchIndex].pageX - refPos.x;
+					y = e.touches[touchIndex].pageY - refPos.y;									
+					
+				}else{
+					
+					x = e.pageX - refPos.x;					
+					y = e.pageY - refPos.y;					
+				}
+			}
+			
+			var r = domGeometry.getContentBox(this.itemContainer);
+			
+			if(!this.isLeftToRight()){
+				x = r.w - x;
+			}
+			
+			if (x < 0){
+				x = 0;
+			}else if(x > r.w){
+				x = r.w-1;
+			}
+			
+			if (y < 0){
+				y = 0;
+			}else if(y > r.h){
+				y = r.h-1;
+			}
+			
+			var col = Math.floor(x / (r.w / this.renderData.columnCount));
+			var row = Math.floor(y / (r.h / this.renderData.maxDayCount));
+			
+			var date = null;
+			if(col < this.renderData.dates.length && 
+				 row < this.renderData.dates[col].length){			
+				date = this.newDate(this.renderData.dates[col][row]); 			
+			}
+	
+			return date;
+		},
+		
+		///////////////////////////////////////////////////////////////
+		//
+		// Events
+		//
+		///////////////////////////////////////////////////////////////
+		
+		_onGridMouseUp: function(e){
+			
+			// tags:
+			//		private
+
+			
+			this.inherited(arguments);
+			
+			if (this._gridMouseDown) {
+				this._gridMouseDown = false;
+				
+				this._onGridClick({
+					date: this.getTime(e),
+					triggerEvent: e
+				});
+			}			
+		},			
+			
+		_onGridTouchStart: function(e){
+			// tags:
+			//		private
+
+			
+			this.inherited(arguments);			
+			
+			var g = this._gridProps;						
+
+			g.moved= false;
+			g.start= e.touches[0].screenY;
+			g.scrollTop= this.scrollContainer.scrollTop;
+		},
+		
+		_onGridTouchMove: function(e){
+			// tags:
+			//		private
+
+			this.inherited(arguments);						
+			
+			if (e.touches.length > 1 && !this._isEditing){
+				event.stop(e);				
+				return;
+			}			
+			
+			if(this._gridProps && !this._isEditing){
+				
+				var touch = {x: e.touches[0].screenX, y: e.touches[0].screenY};
+				
+				var p = this._edProps;
+				
+				if (!p || p && 
+					(Math.abs(touch.x - p.start.x) > 25 || 
+					 Math.abs(touch.y - p.start.y) > 25)) {
+																		
+					this._gridProps.moved = true;
+					var d = e.touches[0].screenY - this._gridProps.start; 
+					var value = this._gridProps.scrollTop - d;
+					var max = this.itemContainer.offsetHeight - this.scrollContainer.offsetHeight;
+					if (value < 0){
+						this._gridProps.start = e.touches[0].screenY;
+						this._setScrollImpl(0);
+						this._gridProps.scrollTop = 0;
+					}else if(value > max){
+						this._gridProps.start = e.touches[0].screenY;
+						this._setScrollImpl(max);
+						this._gridProps.scrollTop = max;
+					}else{
+						this._setScrollImpl(value);
+					}
+				}
+			}
+		},
+		
+		_onGridTouchEnd: function(e){
+			// tags:
+			//		private
+
+			//event.stop(e);
+								
+			this.inherited(arguments);
+									
+			var g = this._gridProps;					
+			
+			if(g){
+				if(!this._isEditing){
+					if(!g.moved){
+						
+						// touched on grid and on touch start editing was ongoing.
+						if(!g.fromItem && !g.editingOnStart){								
+							this.selectFromEvent(e, null, null, true);
+						}			
+						
+						if(!g.fromItem){
+						
+							if(this._pendingDoubleTap && this._pendingDoubleTap.grid){
+															
+								this._onGridDoubleClick({
+									date: this.getTime(this._gridProps.event),
+									triggerEvent: this._gridProps.event
+								});
+								
+								clearTimeout(this._pendingDoubleTap.timer);
+						
+								delete this._pendingDoubleTap;
+								
+							}else{
+															
+								this._onGridClick({
+									date: this.getTime(this._gridProps.event),
+									triggerEvent: this._gridProps.event
+								});
+								
+								this._pendingDoubleTap = {
+									grid: true,
+									timer: setTimeout(lang.hitch(this, function(){
+											delete this._pendingDoubleTap;
+									}), this.doubleTapDelay)
+								};
+							}
+						}	
+					}
+				}
+				
+				this._gridProps = null;
+			}
+		},
+		
+		_onColumnHeaderClick: function(e){
+			// tags:
+			//		private
+
+			this._dispatchCalendarEvt(e, "onColumnHeaderClick");
+		},
+		
+		onColumnHeaderClick: function(e){
+			// summary:
+			//		Event dispatched when a column header cell is dispatched.
+			// e: __ColumnClickEventArgs
+			// tags:
+			//		callback
+
+		},
+		
+
+		///////////////////////////////////////////////////////////////
+		//
+		// View limits
+		//
+		///////////////////////////////////////////////////////////////
+						
+		_onScrollTimer_tick: function(){
+			// tags:
+			//		private
+
+			this._setScrollImpl(this.scrollContainer.scrollTop + this._scrollProps.scrollStep);
+		},
+		
+		////////////////////////////////////////////
+		//
+		// Editing
+		//
+		///////////////////////////////////////////						
+		
+		snapUnit: "day",
+		snapSteps: 1,
+		minDurationUnit: "day",
+		minDurationSteps: 1,
+		liveLayout: false,
+		stayInView: true,
+		allowStartEndSwap: true,
+		allowResizeLessThan24H: false
+		
+	});
+});
diff --git a/dojox/calendar/Mouse.js b/dojox/calendar/Mouse.js
new file mode 100755
index 0000000..6090ba0
--- /dev/null
+++ b/dojox/calendar/Mouse.js
@@ -0,0 +1,313 @@
+define([
+	"dojo/_base/array", 
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/lang",
+	"dojo/_base/window", 
+	"dojo/dom-geometry",
+	"dojo/mouse",
+	"dojo/on", 	
+	"dojo/keys"],
+	
+function(
+	arr, 	
+	declare,
+	event,
+	lang, 	
+	win, 
+	domGeometry,
+	mouse,
+	on, 	
+	keys){
+	
+	/*=====
+	var __ItemMouseEventArgs = {
+		// summary:
+		//		The event dispatched when an item is clicked, double-clicked or context-clicked.
+		// item: Object
+		//		The item clicked.
+		// renderer: dojox/calendar/_RendererMixin
+		//		The item renderer clicked.
+		// triggerEvent: Event
+		//		The event at the origin of this event.
+	};
+	=====*/
+			
+	return declare("dojox.calendar.Mouse", null, {
+
+		// summary:
+		//		This plugin is managing the mouse interactions on item renderers displayed by a calendar view.		
+				
+		// triggerExtent: Number
+		//		The distance in pixels along the vertical or horizontal axis to cover with the 
+		//		mouse button down before triggering the editing gesture.
+		triggerExtent: 3,
+					
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			
+			this.on("rendererCreated", lang.hitch(this, function(irEvent){
+				
+				var renderer = irEvent.renderer.renderer;
+
+				this.own(on(renderer.domNode, "click", lang.hitch(this, function(e){
+					event.stop(e);
+					this._onItemClick({
+						triggerEvent: e,
+						renderer: renderer,
+						item: renderer.item._item
+					});
+				})));
+				
+				this.own(on(renderer.domNode, "dblclick", lang.hitch(this, function(e){
+					event.stop(e);
+					this._onItemDoubleClick({
+						triggerEvent: e,
+						renderer: renderer,
+						item: renderer.item._item
+					});
+				})));
+				
+				this.own(on(renderer.domNode, "contextmenu", lang.hitch(this, function(e){
+					this._onItemContextMenu({
+						triggerEvent: e,
+						renderer: renderer,
+						item:renderer.item._item
+					});
+				})));
+				
+				if(renderer.resizeStartHandle){
+					this.own(on(renderer.resizeStartHandle, "mousedown", lang.hitch(this, function(e){
+						this._onRendererHandleMouseDown(e, renderer, "resizeStart");
+					})));
+				}
+				
+				if(renderer.moveHandle){
+					this.own(on(renderer.moveHandle, "mousedown", lang.hitch(this, function(e){
+						this._onRendererHandleMouseDown(e, renderer, "move");
+					})));
+					
+				}
+				
+				if(renderer.resizeEndHandle){
+					this.own(on(renderer.resizeEndHandle, "mousedown", lang.hitch(this, function(e){
+						this._onRendererHandleMouseDown(e, renderer, "resizeEnd");
+					})));
+				}				
+				
+				this.own(on(renderer.domNode, "mousedown", lang.hitch(this, function(e){
+					this._rendererMouseDownHandler(e, renderer);
+				})));
+				
+				
+				this.own(on(irEvent.renderer.container, mouse.enter, lang.hitch(this, function(e){
+					if(!renderer.item) return;
+					
+					if(!this._editingGesture){
+						this._setHoveredItem(renderer.item.item, renderer);
+						this._onItemRollOver(this.__fixEvt({
+							item: renderer.item._item,
+							renderer: renderer,
+							triggerEvent: e
+						}));
+					}					
+				})));
+				
+				this.own(on(renderer.domNode, mouse.leave, lang.hitch(this, function(e){
+					if(!renderer.item) return;
+					if(!this._editingGesture){						
+						this._setHoveredItem(null);
+						
+						this._onItemRollOut(this.__fixEvt({
+							item: renderer.item._item,
+							renderer: renderer,
+							triggerEvent: e
+						}));
+					}
+				})));
+				
+			}));			
+		},
+		
+		_onItemRollOver: function(e){
+			// tags:
+			//		private
+
+			this._dispatchCalendarEvt(e, "onItemRollOver");
+		},
+		
+		onItemRollOver: function(e){
+			// summary:
+			//		Event dispatched when the mouse cursor in going over an item renderer.
+			// e: __ItemMouseEventArgs
+			//		The event dispatched when the mouse cursor enters in the item renderer.
+			// tags:
+			//		callback
+
+		},
+		
+		_onItemRollOut: function(e){
+			// tags:
+			//		private
+
+			this._dispatchCalendarEvt(e, "onItemRollOut");
+		},
+		
+		onItemRollOut: function(e){
+			// summary:
+			//		Event dispatched when the mouse cursor in leaving an item renderer.
+			// e: __ItemMouseEventArgs
+			//		The event dispatched when the mouse cursor enters in the item renderer.
+			// tags:
+			//		protected
+
+		},
+		
+		_rendererMouseDownHandler: function(e, renderer){
+			
+			// summary:
+			//		Callback if the user clicked on the item renderer but not on a handle.
+			//		Manages item selection.
+			// tags:
+			//		private
+
+			event.stop(e);				
+			
+			var item = renderer.item._item;
+			
+			this.selectFromEvent(e, item, renderer, true);
+			
+			if(this._setTabIndexAttr){
+				this[this._setTabIndexAttr].focus();
+			}
+		},
+		
+		_onRendererHandleMouseDown: function(e, renderer, editKind){
+			// summary:
+			//		Callback if the user clicked on a handle of an item renderer.
+			//		Manages item selection and editing gesture. If editing is not allowed, 
+			//		resize handles are not displayed and so this callback will never be called.
+			//		In that case selected is managed by the _rendererMouseDownHandler function.
+			// tags:
+			//		private
+
+			
+			event.stop(e);				
+			
+			this.showFocus = false;
+			
+			// save item here as calling endItemEditing may call a relayout and changes the item.
+			var ritem = renderer.item;
+			var item = ritem.item;
+			
+			if(!this.isItemBeingEdited(item)){
+						
+				if(this._isEditing){								
+					this._endItemEditing("mouse", false);								
+				}
+				
+				this.selectFromEvent(e, renderer.item._item, renderer, true);
+				
+				if(this._setTabIndexAttr){
+					this[this._setTabIndexAttr].focus();
+				}
+				
+				this._edProps = {
+					editKind: editKind,
+					editedItem: item,
+					rendererKind: renderer.rendererKind,
+					tempEditedItem: item,					
+					liveLayout: this.liveLayout				
+				};
+							
+				this.set("focusedItem", this._edProps.editedItem);	
+			}
+																						
+			var handles = [];
+			handles.push(on(win.doc, "mouseup", lang.hitch(this, this._editingMouseUpHandler)));
+			handles.push(on(win.doc, "mousemove", lang.hitch(this, this._editingMouseMoveHandler)));
+			
+			var p = this._edProps;
+			p.handles = handles;
+			p.eventSource = "mouse";
+			p.editKind = editKind;
+			
+			this._startPoint = {x: e.screenX, y: e.screenY};												
+		},
+		
+		_editingMouseMoveHandler: function(e){
+			// tags:
+			//		private
+
+			var p = this._edProps;
+					
+			if(this._editingGesture){
+				
+				if(!this._autoScroll(e.pageX, e.pageY, true)){
+					this._moveOrResizeItemGesture([this.getTime(e)], "mouse", e);	
+				}
+											
+			}else if(Math.abs(this._startPoint.x - e.screenX) >= this.triggerExtent || // moved enough to trigger editing
+							 Math.abs(this._startPoint.y - e.screenY) >= this.triggerExtent){
+							 	
+				if(!this._isEditing){
+					this._startItemEditing(p.editedItem, "mouse");	
+				}
+				
+				p = this._edProps;
+								
+				this._startItemEditingGesture([this.getTime(e)], p.editKind, "mouse", e);
+			}
+		},		
+		
+		_editingMouseUpHandler: function(e){
+			// tags:
+			//		private
+			
+			var p = this._edProps;
+			
+			this._stopAutoScroll();
+									
+			if(this._isEditing){			
+				
+				if(this._editingGesture){ // a gesture is ongoing.					
+					this._endItemEditingGesture("mouse", e);					
+				}
+				
+				this._endItemEditing("mouse", false);
+								
+			}else{ // handlers were not removed by endItemEditing
+				arr.forEach(p.handles, function(handle){
+					handle.remove();
+				});
+			}
+		},
+		
+		_autoScroll: function(globalX, globalY, isVertical){
+			
+			if (!this.scrollable || !this.autoScroll) {
+				return false;
+			}
+								
+			var scrollerPos = domGeometry.position(this.scrollContainer, true);
+			
+			var p = isVertical ? globalY - scrollerPos.y : globalX - scrollerPos.x;
+			var max = isVertical ? scrollerPos.h : scrollerPos.w;
+			
+			if (p < 0 || p > max) {
+				
+				var step = Math.floor((p < 0	? p : p - max)/2)/3;
+				
+				this._startAutoScroll(step);
+						
+				return true;
+				
+			} else {
+				
+				this._stopAutoScroll();				
+			}
+			return false;
+		}							
+	});
+
+});
diff --git a/dojox/calendar/README b/dojox/calendar/README
new file mode 100644
index 0000000..ff15bb8
--- /dev/null
+++ b/dojox/calendar/README
@@ -0,0 +1,18 @@
+-------------------------------------------------------------------------------
+dojox.calendar
+-------------------------------------------------------------------------------
+Project state: stable
+-------------------------------------------------------------------------------
+Credits:
+	Damien Garbarino
+	Christophe Jolif
+-------------------------------------------------------------------------------
+Project description:
+Candidate calendar widget for Dojo 1.8+
+-------------------------------------------------------------------------------
+Dependencies:
+Dojo Core, Dijit, dojox.html, dojox.widget
+-------------------------------------------------------------------------------
+Documentation:
+    http://docs.dojocampus.org/dojox/calendar
+-------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/dojox/calendar/SimpleColumnView.js b/dojox/calendar/SimpleColumnView.js
new file mode 100644
index 0000000..8b2ed93
--- /dev/null
+++ b/dojox/calendar/SimpleColumnView.js
@@ -0,0 +1,1750 @@
+define([
+"./ViewBase", 
+"dijit/_TemplatedMixin", 
+"./_VerticalScrollBarBase", 
+"dojo/text!./templates/SimpleColumnView.html",
+"dojo/_base/declare", 
+"dojo/_base/event", 
+"dojo/_base/lang", 
+"dojo/_base/array",
+"dojo/_base/sniff",
+"dojo/_base/fx", 
+"dojo/_base/html",
+"dojo/on",
+"dojo/dom", 
+"dojo/dom-class", 
+"dojo/dom-style", 
+"dojo/dom-geometry", 
+"dojo/dom-construct",
+"dojo/mouse", 
+"dojo/query", 
+"dojox/html/metrics"],
+
+function(
+	ViewBase, 
+	_TemplatedMixin, 
+	_VerticalScrollBarBase, 
+	template, 
+	declare, 
+	event, 
+	lang, 
+	arr, 
+	has,
+	fx, 
+	html,
+	on,
+	dom, 
+	domClass, 
+	domStyle,
+	domGeometry, 
+	domConstruct,
+	mouse,
+	query, 
+	metrics){
+	
+	/*=====
+	var __ColumnClickEventArgs = {
+		// summary:
+		//		A column click event.
+		// index: Integer
+		//		The column index. 
+		// date: Date
+		//		The date displayed by the column.
+		// triggerEvent: Event
+		//		The origin event.
+	};
+	=====*/
+				
+	return declare("dojox.calendar.SimpleColumnView", [ViewBase, _TemplatedMixin], {
+		
+		// summary:
+		//		The simple column view is displaying a day per column. Each cell of a column is a time slot.
+
+		baseClass: "dojoxCalendarSimpleColumnView",
+		
+		templateString: template,
+		
+		// viewKind: String
+		//		Type of the view. Used by the calendar widget to determine how to configure the view.
+		//		This view kind is "columns".
+		viewKind: "columns",
+		
+		// scroll container is the focusable item to enable scrolling using up and down arrows
+		_setTabIndexAttr: "domNode",
+		
+		// renderData: Object
+		//		The render data is the object that contains all the properties needed to render the component.
+		renderData: null,		
+				
+		// startDate: Date
+		//		The start date of the time interval displayed.
+		//		If not set at initialization time, will be set to current day.
+		startDate: null,
+			
+		// columnCount: Integer
+		//		The number of column to display (from the startDate).
+		columnCount: 7,
+	
+		// minHours: Integer
+		//		The minimum hour to be displayed. It must be in the [0,23] interval and must be lower than the maxHours.
+		minHours: 8,
+		
+		// maxHours: Integer
+		//		The maximum hour to be displayed. It must be in the [1,24] interval and must be greater than the minHours.	
+		maxHours: 18,
+		
+		// hourSize: Integer
+		//		The desired size in pixels of an hour on the screen.
+		//		Note that the effective size may be different as the time slot size must be an integer.
+		hourSize: 100,
+		
+		// timeSlotDuration: Integer
+		//		Duration of the time slot in minutes. Must be a divisor of 60.
+		timeSlotDuration: 15,
+
+		// rowHeaderGridSlotDuration: Integer
+		//		Duration of the time slot in minutes in the row header. Must be a divisor of 60 and a multiple/divisor of timeSlotDuration.
+		rowHeaderGridSlotDuration: 60,
+		
+		// rowHeaderLabelSlotDuration: Integer
+		//		Duration of the time slot in minutes in the row header labels. Must be a divisor of 60 and a multiple/divisor of timeSlotDuration.
+		rowHeaderLabelSlotDuration: 60,
+		
+		// rowHeaderLabelOffset: Integer
+		//		Offset of the row label from the top of the row header cell in pixels.
+		rowHeaderLabelOffset: 2,
+		
+		// rowHeaderFirstLabelOffset: Integer
+		//		Offset of the first row label from the top of the first row header cell in pixels.
+		rowHeaderFirstLabelOffset: 2,
+		
+		// verticalRenderer: Class
+		//		The class use to create vertical renderers.
+		verticalRenderer: null,
+		
+		// percentOverlap: Integer
+		//		The percentage of the renderer width used to superimpose one item renderer on another 
+		//		when two events are overlapping.
+		percentOverlap: 70,
+		
+		// horizontalGap: Integer
+		//		The number of pixels between two item renderers that are overlapping each other if the percentOverlap property is 0.
+		horizontalGap: 4,
+		
+		_columnHeaderHandlers: null,
+		
+		constructor: function(){
+			this.invalidatingProperties = ["columnCount", "startDate", "minHours", "maxHours", "hourSize", "verticalRenderer",
+				"rowHeaderTimePattern", "columnHeaderDatePattern", "timeSlotDuration", "rowHeaderGridSlotDuration", "rowHeaderLabelSlotDuration", 
+				"rowHeaderLabelOffset", "rowHeaderFirstLabelOffset","percentOverlap", "horizontalGap", "scrollBarRTLPosition","itemToRendererKindFunc", 
+				"layoutPriorityFunction", "formatItemTimeFunc", "textDir", "items"];
+			this._columnHeaderHandlers = [];
+		},
+		
+		destroy: function(preserveDom){
+			this._cleanupColumnHeader();
+			if(this.scrollBar){
+				this.scrollBar.destroy(preserveDom);
+			}
+			this.inherited(arguments);
+		},
+		
+		_scrollBar_onScroll: function(value){
+			this._setScrollPosition(value);
+		},
+		
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(this.vScrollBar){
+				this.scrollBar = new _VerticalScrollBarBase(
+					{content: this.vScrollBarContent}, 
+					this.vScrollBar);
+					
+				this.scrollBar.on("scroll", lang.hitch(this, this._scrollBar_onScroll));
+				this._viewHandles.push(
+						on(this.scrollContainer, mouse.wheel,  
+							dojo.hitch(this, this._mouseWheelScrollHander)));
+			}
+		},
+		
+		postscript: function(){
+			this.inherited(arguments);
+			this._initialized = true;
+			if(!this.invalidRendering){
+				this.refreshRendering();
+			}
+		},
+		
+		_setVerticalRendererAttr: function(value){
+			this._destroyRenderersByKind("vertical");
+			this._set("verticalRenderer", value);	
+		},
+				
+		_createRenderData: function(){
+			
+			var renderData = {};
+
+			renderData.minHours = this.get("minHours");		
+			renderData.maxHours = this.get("maxHours");
+			renderData.hourSize = this.get("hourSize");
+			renderData.hourCount = renderData.maxHours - renderData.minHours;		
+			renderData.slotDuration = this.get("timeSlotDuration"); // must be consistent with previous statement
+			renderData.rowHeaderGridSlotDuration = this.get("rowHeaderGridSlotDuration");
+			renderData.slotSize = Math.ceil(renderData.hourSize / (60 / renderData.slotDuration));
+			renderData.hourSize = renderData.slotSize * (60 / renderData.slotDuration);			
+			renderData.sheetHeight = renderData.hourSize * renderData.hourCount;		
+			renderData.scrollbarWidth = metrics.getScrollbar().w + 1;
+			
+			renderData.dateLocaleModule = this.dateLocaleModule;
+			renderData.dateClassObj = this.dateClassObj;
+			renderData.dateModule = this.dateModule; // arithmetics on Dates
+			
+			renderData.dates = [];
+						
+			renderData.columnCount = this.get("columnCount");
+
+			var d = this.get("startDate");
+		
+			if (d == null){
+				d = new renderData.dateClassObj();
+			}
+
+			d = this.floorToDay(d, false, renderData);
+			
+			this.startDate = d;
+			
+			for(var col = 0; col < renderData.columnCount ; col++){
+				renderData.dates.push(d);
+				d = renderData.dateModule.add(d, "day", 1);
+				d = this.floorToDay(d, false, renderData);
+			}
+
+			renderData.startTime = new renderData.dateClassObj(renderData.dates[0]);
+			renderData.startTime.setHours(renderData.minHours);
+			renderData.endTime = new renderData.dateClassObj(renderData.dates[renderData.columnCount-1]);
+			renderData.endTime.setHours(renderData.maxHours);
+			
+			if(this.displayedItemsInvalidated){
+				this.displayedItemsInvalidated = false;
+				this._computeVisibleItems(renderData);
+				
+				if(this._isEditing){					
+					this._endItemEditing(null, false);
+				}
+				
+			}else if (this.renderData){
+				renderData.items = this.renderData.items;
+			}
+			
+			return renderData;
+		},
+		
+		_validateProperties: function() {
+			
+			this.inherited(arguments);
+			
+			var v = this.minHours;
+			if(v < 0 || v>23 || isNaN(v)){
+				this.minHours = 0;
+			}
+			v = this.maxHours;
+			if (v < 1 || v>24 || isNaN(v)){
+				this.minHours = 24;
+			}
+			
+			if(this.minHours > this.maxHours){
+				var t = this.maxHours;
+				this.maxHours = this.minHours;
+				this.minHours = t;
+			}
+			if (this.maxHours - this.minHours < 1){
+				this.minHours = 0;
+				this.maxHours = 24;				
+			}
+			if (this.columnCount<1 || isNaN(this.columnCount)){
+				this.columnCount = 1;				
+			}
+			
+			v = this.percentOverlap;
+			if(v < 0 ||v > 100 || isNaN(v)){
+				this.percentOverlap = 70;
+			}
+			if(this.hourSize<5 || isNaN(this.hourSize)){
+				this.hourSize = 10;
+			}
+			v = this.timeSlotDuration;
+            if (v < 1 || v > 60 || isNaN(v)) {
+                this.timeSlotDuration = 15;
+            }
+		},
+		
+		_setStartDateAttr: function(value){
+			this.displayedItemsInvalidated = true;			
+			this._set("startDate", value);
+		},
+		
+		_setColumnCountAttr: function(value){			
+			this.displayedItemsInvalidated = true;
+			this._set("columnCount", value);
+		},
+		
+		__fixEvt:function(e){
+			// tags:
+			//		private
+			e.sheet = "primary";
+			e.source = this;
+			return e;
+		},
+		
+		//////////////////////////////////////////
+		//
+		// Formatting functions
+		//
+		//////////////////////////////////////////
+		
+		_formatRowHeaderLabel: function(/*Date*/d){
+			// summary:
+			//		Computes the row header label for the specified time of day.
+			//		By default a formatter is used, optionally the <code>rowHeaderTimePattern</code> property can be used to set a custom time pattern to the formatter.
+			// d: Date
+			//		The date to format
+			// tags:
+			//		protected
+
+			return this.renderData.dateLocaleModule.format(d, {
+				selector: "time", 
+				timePattern: this.rowHeaderTimePattern
+			});
+		},
+	
+		_formatColumnHeaderLabel: function(/*Date*/d){			
+			// summary:
+			//		Computes the column header label for the specified date.
+			//		By default a formatter is used, optionally the <code>columnHeaderDatePattern</code> property can be used to set a custom date pattern to the formatter.
+			// d: Date
+			//		The date to format 
+			// tags:
+			//		protected
+
+			return this.renderData.dateLocaleModule.format(d, {
+				selector: "date", 
+				datePattern: this.columnHeaderDatePattern, 
+				formatLength: "medium"
+			});
+		},
+		
+		//////////////////////////////////////////
+		//
+		// Time of day management
+		//
+		//////////////////////////////////////////
+		
+		// startTimeOfDay: Object
+		//		The scroll position of the view. The value is an object made of "hours" and "minutes" properties.
+		startTimeOfDay: null,
+				
+		// scrollBarRTLPosition: String
+		//		Position of the scroll bar in right-to-left display.
+		//		Valid values are "left" and "right", default value is "left".
+		scrollBarRTLPosition: "left",
+		
+		_getStartTimeOfDay: function(){
+			// summary:
+			//		Returns the visible first time of day.
+			// tags:
+			//		protected
+			// returns: Integer[]
+
+			var v = (this.get("maxHours") - this.get("minHours")) * 
+				this._getScrollPosition() / this.renderData.sheetHeight;
+			
+			return {
+				hours: this.renderData.minHours + Math.floor(v),
+				minutes: (v - Math.floor(v)) * 60
+			};
+		},
+		
+		_getEndTimeOfDay: function(){
+			// summary:
+			//		Returns the visible last time of day.
+			// tags:
+			//		protected
+			// returns: Integer[]
+
+			var v = (this.get("maxHours") - this.get("minHours")) * 
+				(this._getScrollPosition() + this.scrollContainer.offsetHeight) / this.renderData.sheetHeight;
+			
+			return {
+				hours: this.renderData.minHours + Math.floor(v),
+				minutes: (v - Math.floor(v)) * 60
+			};
+		},
+		
+		_setStartTimeOfDayAttr: function(value){
+			this._setStartTimeOfDay(value.hours, value.minutes, value.duration, value.easing);
+		},
+		
+		_getStartTimeOfDayAttr: function(){
+			return this._getStartTimeOfDay();
+		},
+		
+		_setStartTimeOfDay: function(hour, minutes, maxDuration, easing){
+			// summary:
+			//		Scrolls the view to show the specified first time of day.
+			// hour: Integer
+			//		The hour of the start time of day.
+			// minutes: Integer
+			//		The minutes part of the start time of day.
+			// maxDuration: Integer
+			//		The max duration of the scroll animation.
+			// tags:
+			//		protected
+
+			var rd = this.renderData;
+			
+			hour = hour || rd.minHours;
+			minutes = minutes || 0;
+			maxDuration = maxDuration || 0;
+			
+			if (minutes < 0){
+				minutes = 0;
+			}else if (minutes > 59){
+				minutes = 59;
+			}
+			
+			if (hour < 0){
+				hour = 0;
+			}else if (hour > 24){
+				hour = 24;
+			}
+			
+			var timeInMinutes = hour * 60 + minutes;
+			
+			var minH = rd.minHours*60;
+			var maxH = rd.maxHours*60;
+			
+			if (timeInMinutes < minH){
+				timeInMinutes = minH;
+			}else if(timeInMinutes > maxH){
+				timeInMinutes = maxH;
+			}
+					
+			var pos = (timeInMinutes - minH) * rd.sheetHeight / (maxH - minH);
+			pos = Math.min(rd.sheetHeight - this.scrollContainer.offsetHeight, pos);
+			
+			this._scrollToPosition(pos, maxDuration, easing);
+		},
+		
+		_scrollToPosition: function(position, maxDuration, easing){
+			// summary:
+			//		Scrolls the view to show the specified first time of day.
+			// position: Integer
+			//		The position in pixels.
+			// maxDuration: Integer
+			//		The max duration of the scroll animation.
+			// tags:
+			//		protected
+			
+			if (maxDuration) {
+				
+				if(this._scrollAnimation){
+					this._scrollAnimation.stop();
+				}
+				
+				var scrollPos = this._getScrollPosition();
+				
+				var duration = Math.abs(((position - scrollPos) * maxDuration) / this.renderData.sheetHeight);
+				
+				this._scrollAnimation = new fx.Animation({
+					curve: [scrollPos, position],
+					duration: duration,
+					easing: easing,
+					onAnimate: lang.hitch(this, function(position) {
+						this._setScrollImpl(position);
+					})
+				});
+								
+				this._scrollAnimation.play();
+
+			}else{
+				this._setScrollImpl(position);
+			}
+		},
+		
+		_setScrollImpl: function(v){
+			this._setScrollPosition(v);
+			if(this.scrollBar){
+				this.scrollBar.set("value", v);
+			}
+		},
+		
+		ensureVisibility: function(start, end, visibilityTarget, margin, duration){
+			
+			// summary:
+			//		Scrolls the view if the [start, end] time range is not visible or only partially visible.
+			// start: Date
+			//		Start time of the range of interest.
+			// end: Date
+			//		End time of the range of interest.
+			// margin: Integer
+			//		Margin in minutes around the time range.
+			// visibilityTarget: String
+			//		The end(s) of the time range to make visible.
+			//		Valid values are: "start", "end", "both".	
+			// duration: Number
+			//		Optional, the maximum duration of the scroll animation.
+			
+			margin = margin == undefined ? this.renderData.slotDuration : margin;
+			
+			if(this.scrollable && this.autoScroll){
+				
+				var s = start.getHours() * 60 + start.getMinutes() - margin;
+				var e = end.getHours() * 60 + end.getMinutes() + margin;
+				
+				var vs = this._getStartTimeOfDay();
+				var ve = this._getEndTimeOfDay();
+				
+				var viewStart = vs.hours * 60 + vs.minutes; 
+				var viewEnd = ve.hours * 60 + ve.minutes;
+				
+				var visible = false;
+				var target = null;
+				
+				switch(visibilityTarget){
+					case "start":
+						visible = s >= viewStart && s <= viewEnd;
+						target = s ;
+						break;
+					case "end":
+						visible = e >= viewStart && e <= viewEnd;
+						target = e - (viewEnd - viewStart);
+						break;
+					case "both":
+						visible = s >= viewStart && e <= viewEnd;
+						target = s;
+						break;
+				}
+
+				if(!visible){
+					this._setStartTimeOfDay(Math.floor(target/60), target%60, duration);
+				}
+			}
+		},
+		
+		scrollView: function(dir){
+			// summary:
+			//		Scrolls the view to the specified direction of one time slot duration.
+			// dir: Integer
+			//		Direction of the scroll. Valid values are -1 and 1.
+			//
+			var t = this._getStartTimeOfDay();
+			t = t.hours*60 + t.minutes + (dir * this.timeSlotDuration);
+			this._setStartTimeOfDay(Math.floor(t/60), t%60);
+		},
+		
+		_mouseWheelScrollHander: function(e){
+			// summary:
+			//		Mouse wheel handler.
+			// tags:
+			//		protected
+			this.scrollView(e.wheelDelta > 0 ? -1 : 1);
+		},		
+		
+		//////////////////////////////////////////
+		//
+		// HTML structure management
+		//
+		//////////////////////////////////////////		
+	
+		refreshRendering: function(){
+			if(!this._initialized){
+				return;
+			}
+						
+			this._validateProperties();
+
+			var oldRd = this.renderData;
+			var rd = this._createRenderData();
+			this.renderData = rd;
+			this._createRendering(rd, oldRd);
+			this._layoutRenderers(rd);
+		},
+		
+		_createRendering: function(/*Object*/renderData, /*Object*/oldRenderData){
+			// tags:
+			//		private
+			domStyle.set(this.sheetContainer, "height", renderData.sheetHeight + "px");
+			// padding for the scroll bar.
+			this._configureScrollBar(renderData);
+			this._buildColumnHeader(renderData, oldRenderData);
+			this._buildRowHeader(renderData, oldRenderData);
+			this._buildGrid(renderData, oldRenderData);
+			this._buildItemContainer(renderData, oldRenderData);
+		},
+		
+		_configureScrollBar: function(renderData){
+			// summary:
+			//		Sets the scroll bar size and position.
+			// renderData: Object
+			//		The render data.
+			// tags:
+			//		protected
+
+			if(has("ie") && this.scrollBar){
+				domStyle.set(this.scrollBar.domNode, "width", (renderData.scrollbarWidth + 1) + "px");
+			}
+						
+			var atRight = this.isLeftToRight() ? true : this.scrollBarRTLPosition == "right";
+			var rPos = atRight ? "right" : "left";
+			var lPos = atRight? "left" : "right";
+			
+			if(this.scrollBar){
+				this.scrollBar.set("maximum", renderData.sheetHeight);			
+				domStyle.set(this.scrollBar.domNode, rPos, 0);
+				domStyle.set(this.scrollBar.domNode, atRight? "left" : "right", "auto");
+			}
+			domStyle.set(this.scrollContainer, rPos, renderData.scrollbarWidth + "px");
+			domStyle.set(this.scrollContainer, lPos, "0");
+			domStyle.set(this.header, rPos, renderData.scrollbarWidth + "px");
+			domStyle.set(this.header, lPos, "0");
+			if(this.buttonContainer && this.owner != null && this.owner.currentView == this){
+				domStyle.set(this.buttonContainer, rPos, renderData.scrollbarWidth + "px");
+				domStyle.set(this.buttonContainer, lPos, "0");
+			}
+		},
+		
+		_columnHeaderClick: function(e){
+			// tags:
+			//		private
+
+			event.stop(e);
+			var index = query("td", this.columnHeaderTable).indexOf(e.currentTarget);
+			this._onColumnHeaderClick({
+				index: index,
+				date: this.renderData.dates[index],
+				triggerEvent: e
+			});						
+		},
+		
+		_buildColumnHeader: function(renderData, oldRenderData){				
+			// summary:
+			//		Creates incrementally the HTML structure of the column header and configures its content.
+			//
+			// renderData:
+			//		The render data to display.
+			//
+			// oldRenderData:
+			//		The previously render data displayed, if any.
+			// tags:
+			//		private
+
+			var table = this.columnHeaderTable;
+			
+			if (!table){
+				return;
+			}
+					
+			var count = renderData.columnCount - (oldRenderData ? oldRenderData.columnCount : 0);
+			
+			if(has("ie") == 8){
+				// workaround Internet Explorer 8 bug.
+				// if on the table, width: 100% and table-layout: fixed are set
+				// and columns are removed, width of remaining columns is not 
+				// recomputed: must rebuild all. 
+				if(this._colTableSave == null){
+					this._colTableSave = lang.clone(table);
+				}else if(count < 0){
+					this._cleanupColumnHeader();
+					this.columnHeader.removeChild(table);
+					domConstruct.destroy(table);
+					table = lang.clone(this._colTableSave);
+					this.columnHeaderTable = table;
+					this.columnHeader.appendChild(table);
+					count = renderData.columnCount;
+				}
+				
+			} // else incremental dom add/remove for real browsers.
+					
+			var tbodies = query("tbody", table);
+			
+			var trs = query("tr", table);
+			var tbody, tr, td;
+			
+			if (tbodies.length == 1){
+				tbody = tbodies[0];
+			}else{ 
+				tbody = html.create("tbody", null, table);
+			}
+			
+			if (trs.length == 1){
+				tr = trs[0];
+			}else{ 
+				tr = domConstruct.create("tr", null, tbody);
+			}
+						 
+			// Build HTML structure (incremental)
+			if(count > 0){ // creation				
+				for(var i=0; i < count; i++){
+														
+					td = domConstruct.create("td", null, tr);
+					
+					var h = [];
+					h.push(on(td, "click", lang.hitch(this, this._columnHeaderClick)));
+										
+					if(has("touch")){					
+						h.push(on(td, "touchstart", function(e){
+							event.stop(e);
+							domClass.add(e.currentTarget, "Active");
+						}));
+						
+						h.push(on(td, "touchend", function(e){			
+							event.stop(e);			
+							domClass.remove(e.currentTarget, "Active");			
+						}));
+					}else{
+						h.push(on(td, "mousedown", function(e){
+							event.stop(e);
+							domClass.add(e.currentTarget, "Active");
+						}));
+												
+						h.push(on(td, "mouseup", function(e){
+							event.stop(e);
+							domClass.remove(e.currentTarget, "Active");
+						}));					
+						
+						h.push(on(td, "mouseover", function(e){
+							event.stop(e);
+							domClass.add(e.currentTarget, "Hover");
+						}));
+											
+						h.push(on(td, "mouseout", function(e){
+							event.stop(e);
+							domClass.remove(e.currentTarget, "Hover");
+						}));
+					
+					}
+					
+					this._columnHeaderHandlers.push(h);
+					 
+				}
+			}else{ // deletion
+				count = -count;
+				for(var i=0; i < count; i++){
+					td = tr.lastChild;
+					tr.removeChild(td);
+					domConstruct.destroy(td);
+					var list = this._columnHeaderHandlers.pop();
+					while(list.length>0){
+						list.pop().remove();
+					}
+				}
+			}
+			
+			// fill & configure		
+			query("td", table).forEach(function(td, i){
+				td.className = "";											
+				if(i == 0){
+					domClass.add(td, "first-child");
+				}else if(i == this.renderData.columnCount-1){
+					domClass.add(td, "last-child");
+				}
+				var d = renderData.dates[i];
+				this._setText(td, this._formatColumnHeaderLabel(d));
+				this.styleColumnHeaderCell(td, d, renderData);						
+			}, this);
+			
+			if(this.yearColumnHeaderContent){
+				var d = renderData.dates[0];
+					this._setText(this.yearColumnHeaderContent, renderData.dateLocaleModule.format(d,
+						{selector: "date", datePattern:"yyyy"}));
+			}
+		},
+		
+		_cleanupColumnHeader: function(){
+			while(this._columnHeaderHandlers.length > 0){
+				var list = this._columnHeaderHandlers.pop();
+				while(list.length > 0){
+					list.pop().remove();
+				}
+			}
+		},
+		
+		styleColumnHeaderCell: function(node, date, renderData){
+			// summary:
+			//		Styles the CSS classes to the node that displays a column header cell.
+			//		By default this method is setting:
+			//		- "dojoxCalendarToday" class name if the date displayed is the current date,
+			//		- "dojoxCalendarWeekend" if the date represents a weekend,
+			//		- the CSS class corresponding of the displayed day of week ("Sun", "Mon" and so on).
+			// node: Node
+			//		The DOM node that displays the column in the grid.
+			// date: Date
+			//		The date displayed by this column
+			// renderData: Object			
+			//		The render data.
+			// tags:
+			//		protected
+			
+			domClass.add(node, this._cssDays[date.getDay()]);
+
+			if(this.isToday(date)){				
+				domClass.add(node, "dojoxCalendarToday");
+			} else if(this.isWeekEnd(date)){
+				domClass.add(node, "dojoxCalendarWeekend");
+			}	
+		},
+
+        _addMinutesClasses: function(node, minutes){
+            switch(minutes){
+                case 0:
+                    domClass.add(node, "hour");
+                    break;
+                case 30:
+                    domClass.add(node, "halfhour");
+                    break;
+                case 15:
+                case 45:
+                    domClass.add(node, "quarterhour");
+                    break;
+            }
+        },
+		
+		_buildRowHeader: function(renderData, oldRenderData){
+
+			// summary:
+			//		Creates incrementally the HTML structure of the row header and configures its content.			
+			//
+			// renderData:
+			//		The render data to display.
+			//
+			// oldRenderData:
+			//		The previously render data displayed, if any.
+			// tags:
+			//		private
+
+			
+			var rowHeaderTable = this.rowHeaderTable;
+			
+			if (!rowHeaderTable){
+				return;
+			}
+			
+			if(this._rowHeaderLabelContainer == null){
+				this._rowHeaderLabelContainer = domConstruct.create("div", {"class": "dojoxCalendarRowHeaderLabelContainer"}, this.rowHeader);				 
+			}
+			
+						
+			domStyle.set(rowHeaderTable, "height", renderData.sheetHeight + "px");
+			
+			var tbodies = query("tbody", rowHeaderTable);			
+			var tbody, tr, td;
+			
+			if (tbodies.length == 1){
+				tbody = tbodies[0];
+			}else{ 
+				tbody = domConstruct.create("tbody", null, rowHeaderTable);
+			}
+						
+			var nbRows = Math.floor(60 / renderData.rowHeaderGridSlotDuration) * renderData.hourCount;
+			
+			var count = nbRows - 
+				(oldRenderData ? Math.floor(60 / oldRenderData.rowHeaderGridSlotDuration) * oldRenderData.hourCount : 0);
+		
+			// Build HTML structure
+			if(count>0){ // creation
+				for(var i=0; i < count; i++){
+					tr = domConstruct.create("tr", null, tbody);
+					td = domConstruct.create("td", null, tr);						
+				}					 
+			}else{
+				count = -count;
+				// deletion of existing nodes
+				for(var i=0; i < count; i++){
+					tbody.removeChild(tbody.lastChild);
+				}
+			}		
+								
+			// fill labels
+			
+						
+			var rd = this.renderData;
+			var size = Math.ceil(renderData.hourSize / (60 / renderData.rowHeaderGridSlotDuration));
+			var d = new Date(2000, 0, 1, 0, 0, 0);
+			
+			query("tr", rowHeaderTable).forEach(function(tr, i){
+				var td = query("td", tr)[0];				
+				td.className = "";				
+								
+				domStyle.set(tr, "height", (has("ie") == 7)?size-2*(60 / renderData.rowHeaderGridSlotDuration):size + "px");
+				
+				this.styleRowHeaderCell(td, d.getHours(), d.getMinutes(), rd);
+				
+				var m = (i * this.renderData.rowHeaderGridSlotDuration) % 60;
+
+                this._addMinutesClasses(td, m);
+
+			}, this);
+			
+			var lc = this._rowHeaderLabelContainer;			
+			count = (Math.floor(60 / this.rowHeaderLabelSlotDuration) * renderData.hourCount) - lc.childNodes.length;
+			
+			var span;
+			if(count>0){ // creation
+				for(var i=0; i < count; i++){
+					span = domConstruct.create("span", null, lc);
+					domClass.add(span, "dojoxCalendarRowHeaderLabel");
+				}					 
+			}else{
+				count = -count;
+				// deletion of existing nodes
+				for(var i=0; i < count; i++){
+					lc.removeChild(lc.lastChild);
+				}
+			}
+			
+			size = Math.ceil(renderData.hourSize / (60 / this.rowHeaderLabelSlotDuration));
+								
+			query(">span", lc).forEach(function(span, i){
+				d.setHours(0);
+				d.setMinutes(renderData.minHours * 60 + (i*this.rowHeaderLabelSlotDuration));
+				this._configureRowHeaderLabel(span, d, i, size*i, rd);
+			}, this);
+			
+		},
+		
+		_configureRowHeaderLabel: function(node, d, index, pos, renderData){
+			// summary:
+			//		Configures the label of a row header cell.
+			// node: DOMNode
+			//		The DOM node that is the parent of the label.
+			// d:Date
+			//		A date object that contains the hours and minutes displayed by this row header cell.
+			// index: Integer
+			//		The index of this row header cell
+			// pos: Integer
+			//		The computed position of the row header cell
+			// renderData: Object
+			//		The render data.
+			
+			this._setText(node, this._formatRowHeaderLabel(d));
+			domStyle.set(node, "top", (pos + (index==0?this.rowHeaderFirstLabelOffset:this.rowHeaderLabelOffset))+"px");
+			var m = (index * this.rowHeaderLabelSlotDuration) % 60;
+			domClass.remove(node, ["hour", "halfhour", "quarterhour"]);
+            this._addMinutesClasses(node, m);
+		},
+		
+		styleRowHeaderCell: function(node, h, m, renderData){
+			// summary:
+			//		Styles the CSS classes to the node that displays a row header cell.
+			//		By default this method is doing nothing.
+			// node: Node
+			//		The DOM node that displays the column in the grid.
+			// h: Integer
+			//		The time of day displayed by this row header cell.
+			// renderData: Object
+			//		The render data.
+			// tags:
+			//		protected
+		},
+	
+		_buildGrid: function (renderData, oldRenderData){
+			// summary:
+			//		Creates incrementally the HTML structure of the grid and configures its content.
+			//
+			// renderData:
+			//		The render data to display.
+			//
+			// oldRenderData:
+			//		The previously render data displayed, if any.	
+			// tags:
+			//		private
+
+									
+			var table = this.gridTable;
+			
+			if (!table){
+				return;
+			}
+			
+			domStyle.set(table, "height", renderData.sheetHeight + "px");											
+			
+			var nbRows = Math.floor(60 / renderData.slotDuration) * renderData.hourCount;
+			
+			var rowDiff = nbRows - 
+				(oldRenderData ? Math.floor(60 / oldRenderData.slotDuration) * oldRenderData.hourCount : 0);
+				
+			var addRows = rowDiff > 0;
+			
+			var colDiff  = renderData.columnCount - (oldRenderData ? oldRenderData.columnCount : 0);
+			
+			if(has("ie") == 8){
+				// workaround Internet Explorer 8 bug.
+				// if on the table, width: 100% and table-layout: fixed are set
+				// and columns are removed, width of remaining columns is not 
+				// recomputed: must rebuild all. 
+				if(this._gridTableSave == null){
+					this._gridTableSave = lang.clone(table);
+				}else if(colDiff < 0){										
+					this.grid.removeChild(table);
+					domConstruct.destroy(table);
+					table = lang.clone(this._gridTableSave);
+					this.gridTable = table;
+					this.grid.appendChild(table);
+					colDiff = renderData.columnCount;
+					rowDiff = nbRows;
+					addRows = true;
+				}				
+			}
+			
+			var tbodies = query("tbody", table);			
+			var tbody;
+			
+			if (tbodies.length == 1){
+				tbody = tbodies[0];
+			}else{ 
+				tbody = domConstruct.create("tbody", null, table);
+			}
+			
+			// Build time slots (lines) HTML structure (incremental)
+			if(addRows){ // creation
+				for(var i=0; i<rowDiff; i++){
+					domConstruct.create("tr", null, tbody);
+				}		 
+			}else{ // deletion		 
+				rowDiff = -rowDiff;
+				for(var i=0; i<rowDiff; i++){
+					tbody.removeChild(tbody.lastChild);
+				}
+			}
+			
+			var rowIndex = Math.floor(60 / renderData.slotDuration) * renderData.hourCount - rowDiff;
+			
+			var addCols = addRows || colDiff >0; 
+			colDiff = addCols ? colDiff : -colDiff;
+			
+			query("tr", table).forEach(function(tr, i){
+				
+				if(addCols){ // creation				
+					var len = i >= rowIndex ? renderData.columnCount : colDiff;							
+					for(var i=0; i<len; i++){
+						domConstruct.create("td", null, tr);
+					}
+				}else{ // deletion								
+					for(var i=0; i<colDiff; i++){
+						tr.removeChild(tr.lastChild);
+					}
+				}
+			});
+			
+			// Set the CSS classes
+			
+			query("tr", table).forEach(function (tr, i){
+				
+				domStyle.set(tr, "height", renderData.slotSize + "px");
+				
+				if(i == 0){
+					domClass.add(tr, "first-child");
+				}else if(i == nbRows-1){
+					domClass.add(tr, "last-child");
+				}
+				
+				// the minutes part of the time of day displayed by the current tr
+				var m = (i * this.renderData.slotDuration) % 60;
+				var h = this.minHours + Math.floor((i * this.renderData.slotDuration) / 60);
+				query("td", tr).forEach(function (td, col){
+					
+					td.className = "";
+					
+					if(col == 0){
+						domClass.add(td, "first-child");
+					}else if(col == this.renderData.columnCount-1){
+						domClass.add(td, "last-child");
+					}
+					
+					var d = renderData.dates[col];
+					
+					this.styleGridCell(td, d, h, m, renderData);
+
+                    this._addMinutesClasses(td, m);
+
+				}, this);				
+			}, this); 
+												 
+		},
+		
+		// styleGridCellFunc: Function
+		//		Custom function to customize the appearance of a grid cell by installing custom CSS class on the node.
+		//		The signature of the function must be the same then the styleGridCell one.
+		//		By default the defaultStyleGridCell function is used.
+		styleGridCellFunc: null,
+				
+		defaultStyleGridCell: function(node, date, hours, minutes, renderData){
+			// summary:
+			//		Styles the CSS classes to the node that displays a cell.
+			//		By default this method is setting:
+			//		- "dojoxCalendarToday" class name if the date displayed is the current date,
+			//		- "dojoxCalendarWeekend" if the date represents a weekend,
+			//		- the CSS class corresponding of the displayed day of week ("Sun", "Mon" and so on),
+			//		- the CSS classes corresponfing to the time of day (e.g. "H14" and "M30" for for 2:30pm).   
+			// node: Node
+			//		The DOM node that displays the cell in the grid.
+			// date: Date
+			//		The date displayed by this cell.
+			// hours: Integer
+			//		The hours part of time of day displayed by the start of this cell.
+			// minutes: Integer
+			//		The minutes part of time of day displayed by the start of this cell.
+			// renderData: Object
+			//		The render data object.
+			// tags:
+			//		protected
+			
+			domClass.add(node, [this._cssDays[date.getDay()], "H"+hours, "M"+minutes]);
+
+			if(this.isToday(date)){				
+				return domClass.add(node, "dojoxCalendarToday");
+			} else if(this.isWeekEnd(date)){
+				return domClass.add(node, "dojoxCalendarWeekend");
+			}
+		},
+		
+		styleGridCell: function(node, date, hours, minutes, renderData){
+			// summary:
+			//		Styles the CSS classes to the node that displays a cell.
+			//		Delegates to styleGridCellFunc if defined or defaultStyleGridCell otherwise.
+			// node: Node
+			//		The DOM node that displays the cell in the grid.
+			// date: Date
+			//		The date displayed by this column
+			// renderData: Object
+			//		The render data object.
+			// tags:
+			//		protected
+
+			if(this.styleGridCellFunc){
+				this.styleGridCellFunc(node, date, hours, minutes, renderData);
+			}else{
+				this.defaultStyleGridCell(node, date, hours, minutes, renderData);
+			}
+		},
+							
+		_buildItemContainer: function(renderData, oldRenderData){
+			// summary:
+			//		Creates the HTML structure of the item container and configures its content.
+			// renderData:
+			//		The render data to display.
+			// oldRenderData:
+			//		The previously render data displayed, if any.
+			// tags:
+			//		private
+
+			var table = this.itemContainerTable;
+			
+			if (!table){
+				return;
+			}
+			
+			var bgCols = [];
+	
+			domStyle.set(table, "height", renderData.sheetHeight + "px");			
+			
+			var count = renderData.columnCount - (oldRenderData ? oldRenderData.columnCount : 0);
+			
+			if(has("ie") == 8){
+				// workaround Internet Explorer 8 bug.
+				// if on the table, width: 100% and table-layout: fixed are set
+				// and columns are removed, width of remaining columns is not 
+				// recomputed: must rebuild all. 
+				if(this._itemTableSave == null){
+					this._itemTableSave = lang.clone(table);
+				}else if(count < 0){
+					this.itemContainer.removeChild(table);
+					this._recycleItemRenderers(true);
+					domConstruct.destroy(table);
+					table = lang.clone(this._itemTableSave);
+					this.itemContainerTable = table;
+					this.itemContainer.appendChild(table);
+					count = renderData.columnCount;
+				}
+				
+			} // else incremental dom add/remove for real browsers.
+			
+			var tbodies = query("tbody", table);
+			var trs = query("tr", table);
+			var tbody, tr, td;
+			
+			if (tbodies.length == 1){
+				tbody = tbodies[0];
+			}else{ 
+				tbody = domConstruct.create("tbody", null, table);
+			}
+			
+			if (trs.length == 1){
+				tr = trs[0];
+			}else{ 
+				tr = domConstruct.create("tr", null, tbody);
+			}					
+								
+			// Build HTML structure (incremental)
+			if(count>0){ // creation
+				for(var i=0; i < count; i++){
+					td = domConstruct.create("td", null, tr);	
+					domConstruct.create("div", {"className": "dojoxCalendarContainerColumn"}, td);
+				}
+			}else{ // deletion		 
+				count = -count;
+				for(var i=0; i < count; i++){
+					tr.removeChild(tr.lastChild);
+				}
+			}	
+			
+			query("td>div", table).forEach(function(div, i){
+
+				domStyle.set(div, {
+					"height": renderData.sheetHeight + "px"
+				});
+				bgCols.push(div);		
+			}, this);
+			
+			renderData.cells = bgCols;
+		},			
+		
+		///////////////////////////////////////////////////////////////
+		//
+		// Layout
+		//
+		///////////////////////////////////////////////////////////////
+		
+		_overlapLayoutPass2: function(lanes){
+			// summary:
+			//		Second pass of the overlap layout (optional). Compute the extent of each layout item.
+			// lanes:
+			//		The array of lanes.
+			// tags:
+			//		private
+			var i,j,lane, layoutItem;
+			// last lane, no extent possible
+			lane = lanes[lanes.length-1];
+			
+			for(j = 0; j < lane.length; j++){
+				lane[j].extent = 1;
+			}
+						
+			for(i=0; i<lanes.length-1; i++){
+				lane = lanes[i];
+				
+				for(var j=0; j<lane.length; j++){	 
+					layoutItem = lane[j];
+					
+					// if item was already overlapping another one there is no extent possible.
+					if(layoutItem.extent == -1){
+						layoutItem.extent = 1;
+						var space = 0;
+						
+						var stop = false;
+						
+						for(var k = i + 1; k < lanes.length && !stop; k++){
+							var ccol = lanes[k];
+							for(var l = 0; l < ccol.length && !stop; l++){
+								var layoutItem2 = ccol[l];
+								
+								if(layoutItem.start < layoutItem2.end && layoutItem2.start < layoutItem.end){
+									stop = true;
+								}
+							}
+							if(!stop){
+								//no hit in the entire lane
+								space++;
+							}
+						}
+						layoutItem.extent += space;
+					}
+				}
+			}
+		},
+		
+		_defaultItemToRendererKindFunc: function(item){
+			// tags:
+			//		private
+			return "vertical"; // String
+		},
+		
+		_layoutInterval: function(/*Object*/renderData, /*Integer*/index, /*Date*/start, /*Date*/end, /*Object[]*/items){
+			// tags:
+			//		private
+
+			var verticalItems = [];
+			renderData.colW = this.itemContainer.offsetWidth / renderData.columnCount;
+			
+			for(var i=0; i<items.length; i++){
+				var item = items[i];
+				if(this._itemToRendererKind(item) == "vertical"){
+					verticalItems.push(item);
+				}
+			}
+			
+			if(verticalItems.length > 0){
+				this._layoutVerticalItems(renderData, index, start, end, verticalItems);
+			}
+		},
+
+		_layoutVerticalItems: function(/*Object*/renderData, /*Integer*/index, /*Date*/startTime, /*Date*/endTime, /*Object[]*/items){
+			// tags:
+			//		private
+
+			if(this.verticalRenderer == null){
+				return;
+			}
+			
+			var cell = renderData.cells[index];
+			var layoutItems = [];			
+			
+			// step 1 compute projected position and size
+			for(var i = 0; i < items.length; i++){
+				
+				var item = items[i];
+				var overlap = this.computeRangeOverlap(renderData, item.startTime, item.endTime, startTime, endTime);
+				
+				var top = this.computeProjectionOnDate(renderData, startTime, overlap[0], renderData.sheetHeight);
+				var bottom = this.computeProjectionOnDate(renderData, startTime, overlap[1], renderData.sheetHeight);
+				
+				if (bottom > top){
+					var litem = lang.mixin({
+						start: top,
+						end: bottom,
+						range: overlap,
+						item: item
+					}, item);
+					layoutItems.push(litem);
+				}
+			}
+			
+			// step 2: compute overlapping layout
+			var numLanes = this.computeOverlapping(layoutItems, this._overlapLayoutPass2).numLanes;
+
+			var hOverlap = this.percentOverlap / 100;
+
+			// step 3: create renderers and apply layout
+			for(i=0; i<layoutItems.length; i++){
+
+				item = layoutItems[i];					
+				var lane = item.lane;
+				var extent = item.extent;
+
+				var w;
+				var posX;				
+
+				if(hOverlap == 0) {
+					//no overlap and a padding between each event
+					w = numLanes == 1 ? renderData.colW : ((renderData.colW - (numLanes - 1) * this.horizontalGap)/ numLanes);
+					posX = lane * (w + this.horizontalGap);
+					w = extent == 1 ? w : w * extent + (extent-1) * this.horizontalGap;
+					w = 100 * w / renderData.colW;
+					posX = 100 * posX / renderData.colW; 
+				} else {
+					// an overlap
+					w = numLanes == 1 ? 100 : (100 / (numLanes - (numLanes - 1) * hOverlap));
+					posX = lane * (w - hOverlap*w);
+					w = extent == 1 ? w : w * ( extent - (extent-1) * hOverlap);
+				}
+
+				var ir = this._createRenderer(item, "vertical", this.verticalRenderer, "dojoxCalendarVertical");
+
+				domStyle.set(ir.container, {
+					"top": item.start + "px",
+					"left": posX + "%",
+					"width": w + "%",
+					"height": (item.end-item.start+1) + "px"
+				});
+
+				var edited = this.isItemBeingEdited(item);
+				var selected = this.isItemSelected(item);
+				var hovered = this.isItemHovered(item);
+				var focused = this.isItemFocused(item);
+				
+				var renderer = ir.renderer;
+
+				renderer.set("hovered", hovered);
+				renderer.set("selected", selected);
+				renderer.set("edited", edited);
+				renderer.set("focused", this.showFocus ? focused : false);
+				renderer.set("storeState", this.getItemStoreState(item));
+				
+				renderer.set("moveEnabled", this.isItemMoveEnabled(item._item, "vertical"));
+				renderer.set("resizeEnabled", this.isItemResizeEnabled(item._item, "vertical"));
+
+				this.applyRendererZIndex(item, ir, hovered, selected, edited, focused);
+
+				if(renderer.updateRendering){
+					renderer.updateRendering(w, item.end-item.start+1);
+				}
+
+				domConstruct.place(ir.container, cell);
+				domStyle.set(ir.container, "display", "block");
+			}
+		},
+		
+		_sortItemsFunction: function(a, b){
+			// tags:
+			//		private
+
+			var res = this.dateModule.compare(a.startTime, b.startTime);
+			if(res == 0){
+				res = -1 * this.dateModule.compare(a.endTime, b.endTime);
+			}
+			return this.isLeftToRight() ? res : -res;
+		},
+		
+		///////////////////////////////////////////////////////////////
+		//
+		// View to time projection
+		//
+		///////////////////////////////////////////////////////////////
+		
+		getTime: function(e, x, y, touchIndex){
+			// summary:
+			//		Returns the time displayed at the specified point by this component.
+			// e: Event
+			//		Optional mouse event.
+			// x: Number
+			//		Position along the x-axis with respect to the sheet container used if event is not defined.
+			// y: Number
+			//		Position along the y-axis with respect to the sheet container (scroll included) used if event is not defined.
+			// touchIndex: Integer
+			//		If parameter 'e' is not null and a touch event, the index of the touch to use.
+			// returns: Date
+			
+			if (e != null){				
+				var refPos = domGeometry.position(this.itemContainer, true);
+				
+				if(e.touches){									
+					
+					touchIndex = touchIndex==undefined ? 0 : touchIndex;
+									
+					x = e.touches[touchIndex].pageX - refPos.x;
+					y = e.touches[touchIndex].pageY - refPos.y;									
+					
+				}else{
+					
+					x = e.pageX - refPos.x;					
+					y = e.pageY - refPos.y;					
+				}
+			}
+			
+			var r = domGeometry.getContentBox(this.itemContainer);
+			
+			if(!this.isLeftToRight()){
+				x = r.w - x;
+			}
+			
+			if (x < 0){
+				x = 0;
+			}else if(x > r.w){
+				x = r.w-1;
+			}
+			
+			if (y < 0){
+				y = 0;
+			}else if(y > r.h){
+				y = r.h-1;
+			}
+			
+			var col = Math.floor(x / (domGeometry.getMarginBox(this.itemContainer).w / this.renderData.columnCount));
+			var t = this.getTimeOfDay(y, this.renderData);
+			
+			var date = null;
+			if(col < this.renderData.dates.length){			
+				date = this.newDate(this.renderData.dates[col]); 
+				date = this.floorToDay(date, true);
+				date.setHours(t.hours);
+				date.setMinutes(t.minutes);
+			}
+	
+			return date;
+		},
+		
+		///////////////////////////////////////////////////////////////
+		//
+		// Events
+		//
+		///////////////////////////////////////////////////////////////
+		
+		_onGridMouseUp: function(e){
+			// tags:
+			//		private
+
+			this.inherited(arguments);
+			
+			if (this._gridMouseDown) {
+				this._gridMouseDown = false;
+				
+				this._onGridClick({
+					date: this.getTime(e),
+					triggerEvent: e
+				});
+			}			
+		},			
+			
+		_onGridTouchStart: function(e){
+			// tags:
+			//		private
+
+			this.inherited(arguments);
+			
+			var g = this._gridProps;
+
+			g.moved= false;
+			g.start= e.touches[0].screenY;
+			g.scrollTop= this._getScrollPosition();
+		},
+		
+		_onGridTouchMove: function(e){
+			// tags:
+			//		private
+
+			this.inherited(arguments);						
+			
+			if (e.touches.length > 1 && !this._isEditing){
+				event.stop(e);				
+				return;
+			}			
+			
+			if(this._gridProps && !this._isEditing){
+				
+				var touch = {x: e.touches[0].screenX, y: e.touches[0].screenY};
+				
+				var p = this._edProps;
+				
+				if (!p || p && 
+					(Math.abs(touch.x - p.start.x) > 25 || 
+					 Math.abs(touch.y - p.start.y) > 25)) {
+																		
+					this._gridProps.moved = true;
+					var d = e.touches[0].screenY - this._gridProps.start; 
+					var value = this._gridProps.scrollTop - d;
+					var max = this.itemContainer.offsetHeight - this.scrollContainer.offsetHeight;
+					if (value < 0){
+						this._gridProps.start = e.touches[0].screenY;
+						this._setScrollImpl(0);
+						this._gridProps.scrollTop = 0;
+					}else if(value > max){
+						this._gridProps.start = e.touches[0].screenY;
+						this._setScrollImpl(max);
+						this._gridProps.scrollTop = max;
+					}else{
+						this._setScrollImpl(value);
+					}
+				}
+			}
+		},
+		
+		_onGridTouchEnd: function(e){
+			// tags:
+			//		private
+
+			//event.stop(e);
+								
+			this.inherited(arguments);
+									
+			var g = this._gridProps;					
+			
+			if(g){
+				if(!this._isEditing){
+					if(!g.moved){
+						
+						// touched on grid and on touch start editing was ongoing.
+						if(!g.fromItem && !g.editingOnStart){								
+							this.selectFromEvent(e, null, null, true);
+						}			
+						
+						if(!g.fromItem){
+						
+							if(this._pendingDoubleTap && this._pendingDoubleTap.grid){
+															
+								this._onGridDoubleClick({
+									date: this.getTime(this._gridProps.event),
+									triggerEvent: this._gridProps.event
+								});
+								
+								clearTimeout(this._pendingDoubleTap.timer);
+						
+								delete this._pendingDoubleTap;
+								
+							}else{
+															
+								this._onGridClick({
+									date: this.getTime(this._gridProps.event),
+									triggerEvent: this._gridProps.event
+								});
+								
+								this._pendingDoubleTap = {
+									grid: true,
+									timer: setTimeout(lang.hitch(this, function(){
+											delete this._pendingDoubleTap;
+									}), this.doubleTapDelay)
+								};
+							}
+						}	
+					}
+				}
+				
+				this._gridProps = null;
+			}
+		},
+		
+		_onColumnHeaderClick: function(e){
+			// tags:
+			//		private
+
+			this._dispatchCalendarEvt(e, "onColumnHeaderClick");
+		},
+		
+		
+		
+		onColumnHeaderClick: function(e){
+			// summary:
+			//		Event dispatched when a column header cell is dispatched.
+			// e: __ColumnClickEventArgs
+			//		The event has the following properties
+			// tags:
+			//		callback					
+		},
+		
+
+		getTimeOfDay: function (pos, rd) {
+			// summary:
+			//		Return the time of day associated to the specified position.
+			// pos: Integer
+			//		The position in pixels.
+			// rd: Object
+			//		The render data.
+			var minH = rd.minHours*60;
+			var maxH = rd.maxHours*60;
+			var minutes = minH + (pos * (maxH - minH) / rd.sheetHeight);
+			return {
+				hours: Math.floor(minutes / 60),
+				minutes: Math.floor(minutes % 60)
+			};
+		},
+		
+		///////////////////////////////////////////////////////////////
+		//
+		// View limits
+		//
+		///////////////////////////////////////////////////////////////
+		
+		_isItemInView: function(item){
+			
+			// subclassed to add some tests
+									
+			var res = this.inherited(arguments);
+			
+			if(res){
+				
+				// test if time range is overlapping [maxHours, next day min hours]
+				var rd = this.renderData;
+				
+				var len = rd.dateModule.difference(item.startTime, item.endTime, "millisecond"); 
+				var vLen = (24 - rd.maxHours + rd.minHours) * 3600000; // 60 * 60 * 1000, number of milliseconds in 1 minute
+				
+				if(len > vLen){ // longer events are always visible
+					return true;
+				}						
+				
+				var sMin = item.startTime.getHours()*60 + item.startTime.getMinutes();
+				var eMin = item.endTime.getHours()*60 + item.endTime.getMinutes(); 
+				var sV = rd.minHours * 60;
+				var eV = rd.maxHours * 60;
+				
+				if(sMin > 0 && sMin < sV || sMin > eV && sMin <= 1440){
+					return false;
+				}
+				
+				if(eMin > 0 && eMin < sV || eMin > eV && eMin <= 1440){
+					return false;
+				}							
+			}
+			return res;
+		},
+				
+		_ensureItemInView: function(item){
+											
+			var fixed;
+			
+			var startTime = item.startTime;
+			var endTime = item.endTime;
+									
+			// test if time range is overlapping [maxHours, next day min hours]
+			var rd = this.renderData;
+			var cal = rd.dateModule;
+			
+			var len = Math.abs(cal.difference(item.startTime, item.endTime, "millisecond")); 
+			var vLen = (24 - rd.maxHours + rd.minHours) * 3600000;
+			
+			if(len > vLen){ // longer events are always visible
+				return false;
+			}						
+			
+			var sMin = startTime.getHours()*60 + startTime.getMinutes();
+			var eMin = endTime.getHours()*60 + endTime.getMinutes(); 
+			var sV = rd.minHours * 60;
+			var eV = rd.maxHours * 60;
+			
+			if(sMin > 0 && sMin < sV){
+				this.floorToDay(item.startTime, true, rd);
+				item.startTime.setHours(rd.minHours);
+				item.endTime = cal.add(item.startTime, "millisecond", len);
+				fixed = true;
+			}else if(sMin > eV && sMin <= 1440){
+				// go on next visible time
+				this.floorToDay(item.startTime, true, rd);
+				item.startTime = cal.add(item.startTime, "day", 1);
+				// if we are going out of the view, the super() will fix it
+				item.startTime.setHours(rd.minHours);
+				item.endTime = cal.add(item.startTime, "millisecond", len);
+				fixed = true;
+			}
+			
+			if(eMin > 0 && eMin < sV){
+				// go on previous day
+				this.floorToDay(item.endTime, true, rd);
+				item.endTime = cal.add(item.endTime, "day", -1);
+				item.endTime.setHours(rd.maxHours);
+				item.startTime = cal.add(item.endTime, "millisecond", -len);
+				fixed = true;
+			}else if(eMin > eV && eMin <= 1440){
+				this.floorToDay(item.endTime, true, rd);
+				item.endTime.setHours(rd.maxHours);
+				item.startTime = cal.add(item.endTime, "millisecond", -len);
+				fixed = true;
+			}							
+			
+			fixed = fixed || this.inherited(arguments);
+			
+			return fixed;
+		},
+				
+		_onScrollTimer_tick: function(){
+			// tags:
+			//		private
+
+			this._scrollToPosition(this._getScrollPosition() + this._scrollProps.scrollStep);
+		},
+		
+		////////////////////////////////////////////
+		//
+		// Editing
+		//
+		///////////////////////////////////////////						
+		
+		snapUnit: "minute",
+		snapSteps: 15,
+		minDurationUnit: "minute",
+		minDurationSteps: 15,
+		liveLayout: false,
+		stayInView: true,
+		allowStartEndSwap: true,
+		allowResizeLessThan24H: true
+		
+	});
+});
diff --git a/dojox/calendar/StoreMixin.js b/dojox/calendar/StoreMixin.js
new file mode 100644
index 0000000..f8a3e0d
--- /dev/null
+++ b/dojox/calendar/StoreMixin.js
@@ -0,0 +1,329 @@
+define(["dojo/_base/declare", "dojo/_base/array", "dojo/_base/html", "dojo/_base/lang", "dojo/dom-class",
+	"dojo/Stateful", "dojo/when"],
+	function(declare, arr, html, lang, domClass, Stateful, when){
+
+	return declare("dojox.calendar.StoreMixin", Stateful, {
+		
+		// summary:
+		//		This mixin contains the store management.
+		
+		// store: dojo.store.Store
+		//		The store that contains the events to display.
+		store: null,
+		
+		// query: Object
+		//		A query that can be passed to when querying the store.
+		query: {},
+
+		// queryOptions: dojo/store/api/Store.QueryOptions?
+		//		Options to be applied when querying the store.
+		queryOptions: null,
+
+		// startTimeAttr: String
+		//		The attribute of the store item that contains the start time of 
+		//		the events represented by this item.	Default is "startTime". 
+		startTimeAttr: "startTime",
+		
+		// endTimeAttr: String
+		//		The attribute of the store item that contains the end time of 
+		//		the events represented by this item.	Default is "endTime".
+		endTimeAttr: "endTime",
+		
+		// summaryAttr: String
+		//		The attribute of the store item that contains the summary of 
+		//		the events represented by this item.	Default is "summary".
+		summaryAttr: "summary",
+		
+		// allDayAttr: String
+		//		The attribute of the store item that contains the all day state of 
+		//		the events represented by this item.	Default is "allDay".
+		allDayAttr: "allDay",
+	
+		// cssClassFunc: Function
+		//		Optional function that returns a css class name to apply to item renderers that are displaying the specified item in parameter. 
+		cssClassFunc: null,		
+							
+		// decodeDate: Function?
+		//		An optional function to transform store date into Date objects.	Default is null. 
+		decodeDate: null,
+		
+		// encodeDate: Function?
+		//		An optional function to transform Date objects into store date.	Default is null. 
+		encodeDate: null,
+		
+		// displayedItemsInvalidated: Boolean
+		//		Whether the data items displayed must be recomputed, usually after the displayed 
+		//		time range has changed. 
+		// tags:
+		//		protected
+		displayedItemsInvalidated: false,
+									
+		itemToRenderItem: function(item, store){
+			// summary:
+			//		Creates the render item based on the dojo.store item. It must be of the form:
+			//	|	{
+			//  |		id: Object,
+			//	|		startTime: Date,
+			//	|		endTime: Date,
+			//	|		summary: String
+			//	|	}
+			//		By default it is building an object using the store id, the summaryAttr, 
+			//		startTimeAttr and endTimeAttr properties as well as decodeDate property if not null. 
+			//		Other fields or way to query fields can be used if needed.
+			// item: Object
+			//		The store item. 
+			// store: dojo.store.api.Store
+			//		The store.
+			// returns: Object
+			if(this.owner){
+				return this.owner.itemToRenderItem(item, store);
+			}
+			return {
+				id: store.getIdentity(item),
+				summary: item[this.summaryAttr],
+				startTime: (this.decodeDate && this.decodeDate(item[this.startTimeAttr])) || this.newDate(item[this.startTimeAttr], this.dateClassObj),
+				endTime: (this.decodeDate && this.decodeDate(item[this.endTimeAttr])) || this.newDate(item[this.endTimeAttr], this.dateClassObj),
+				allDay: item[this.allDayAttr] != null ? item[this.allDayAttr] : false,
+				cssClass: this.cssClassFunc ? this.cssClassFunc(item) : null 
+			};
+		},
+		
+		renderItemToItem: function(/*Object*/ renderItem, /*dojo.store.api.Store*/ store){
+			// summary:
+			//		Create a store item based on the render item. It must be of the form:
+			//	|	{
+			//	|		id: Object
+			//	|		startTime: Date,
+			//	|		endTime: Date,
+			//	|		summary: String
+			//	|	}
+			//		By default it is building an object using the summaryAttr, startTimeAttr and endTimeAttr properties
+			//		and encodeDate property if not null. If the encodeDate property is null a Date object will be set in the start and end time.
+			//		When using a JsonRest store, for example, it is recommended to transfer dates using the ISO format (see dojo.date.stamp).
+			//		In that case, provide a custom function to the encodeDate property that is using the date ISO encoding provided by Dojo. 
+			// renderItem: Object
+			//		The render item. 
+			// store: dojo.store.api.Store
+			//		The store.
+			// returns:Object
+			if(this.owner){
+				return this.owner.renderItemToItem(renderItem, store);
+			}
+			var item = {};
+			item[store.idProperty] = renderItem.id;
+			item[this.summaryAttr] = renderItem.summary;
+			item[this.startTimeAttr] = (this.encodeDate && this.encodeDate(renderItem.startTime)) || renderItem.startTime;
+			item[this.endTimeAttr] = (this.encodeDate && this.encodeDate(renderItem.endTime)) || renderItem.endTime;
+			return lang.mixin(store.get(renderItem.id), item);
+		},			
+		
+		_computeVisibleItems: function(renderData){
+			// summary:
+			//		Computes the data items that are in the displayed interval.
+			// renderData: Object
+			//		The renderData that contains the start and end time of the displayed interval.
+			// tags:
+			//		protected
+
+			var startTime = renderData.startTime;
+			var endTime = renderData.endTime;
+			if(this.items){
+				renderData.items = arr.filter(this.items, function(item){
+					return this.isOverlapping(renderData, item.startTime, item.endTime, startTime, endTime);
+				}, this);
+			}
+		},
+		
+		_initItems: function(items){
+			// tags:
+			//		private
+			this.set("items", items);
+			return items;
+		},
+		
+		_refreshItemsRendering: function(renderData){
+		},
+		
+		_updateItems: function(object, previousIndex, newIndex){
+			// as soon as we add a item or remove one layout might change,
+			// let's make that the default
+			// TODO: what about items in non visible area...
+			// tags:
+			//		private
+			var layoutCanChange = true;
+			var oldItem = null;
+			var newItem = this.itemToRenderItem(object, this.store);
+			// keep a reference on the store data item. 
+			newItem._item = object;
+			
+			// set the item as in the store
+			
+			if(previousIndex!=-1){
+				if(newIndex!=previousIndex){
+					// this is a remove or a move
+					this.items.splice(previousIndex, 1);
+					if(this.setItemSelected && this.isItemSelected(newItem)){
+						this.setItemSelected(newItem, false);
+						this.dispatchChange(newItem, this.get("selectedItem"), null, null);
+					}
+				}else{
+					// this is a put, previous and new index identical
+					// check what changed
+					oldItem = this.items[previousIndex];
+					var cal = this.dateModule; 
+					layoutCanChange = cal.compare(newItem.startTime, oldItem.startTime) != 0 ||
+						cal.compare(newItem.endTime, oldItem.endTime) != 0;
+					// we want to keep the same item object and mixin new values
+					// into old object
+					lang.mixin(oldItem, newItem); 
+				}
+			}else if(newIndex!=-1){
+				// this is a add
+				var s = this._getItemStoreStateObj(newItem);
+				if(s){
+					// if the item is at the correct index (creation)
+					// we must fix it. Should not occur but ensure integrity.
+					if(this.items[newIndex].id != newItem.id){						
+						var l = this.items.length; 
+						for(var i=l-1; i>=0; i--){
+							if(this.items[i].id == newItem.id){
+								this.items.splice(i, 1);
+								break;
+							}
+						}						
+						this.items.splice(newIndex, 0, newItem);						
+					}
+					// update with the latest values from the store.
+					lang.mixin(s.renderItem, newItem);
+				}else{
+					this.items.splice(newIndex, 0, newItem);					
+				}
+				this.set("items", this.items);
+			}	
+			
+			this._setItemStoreState(newItem, "stored");
+			
+			if(!this._isEditing){
+				if(layoutCanChange){				
+					this._refreshItemsRendering();			
+				}else{
+					// just update the item
+					this.updateRenderers(oldItem);
+				}
+			}
+		},
+		
+		_setStoreAttr: function(value){
+			this.displayedItemsInvalidated = true;
+			var r;
+
+			if(this._observeHandler){
+				this._observeHandler.remove();
+				this._observeHandler = null;
+			}
+			if(value){				
+				var results = value.query(this.query, this.queryOptions);
+				if(results.observe){
+					// user asked us to observe the store
+					this._observeHandler = results.observe(lang.hitch(this, this._updateItems), true);
+				}				
+				results = results.map(lang.hitch(this, function(item){
+					var renderItem = this.itemToRenderItem(item, value);
+					// keep a reference on the store data item.
+					renderItem._item = item;
+					return renderItem;
+				}));
+				r = when(results, lang.hitch(this, this._initItems));
+			}else{
+				// we remove the store
+				r = this._initItems([]);
+			}
+			this._set("store", value);
+			return r;
+		},
+		
+		_getItemStoreStateObj: function(/*Object*/item){
+			// tags
+			//		private
+			
+			if(this.owner){
+				return this.owner._getItemStoreStateObj(item);
+			}
+			
+			var store = this.get("store");
+			if(store != null && this._itemStoreState != null){
+				var id = item.id == undefined ? store.getIdentity(item) : item.id;
+				return this._itemStoreState[id];
+			}
+			return null;
+		},
+		
+		getItemStoreState: function(item){
+			//	summary:
+			//		Returns the creation state of an item. 
+			//		This state is changing during the interactive creation of an item.
+			//		Valid values are:
+			//		- "unstored": The event is being interactively created. It is not in the store yet.
+			//		- "storing": The creation gesture has ended, the event is being added to the store.
+			//		- "stored": The event is not in the two previous states, and is assumed to be in the store 
+			//		(not checking because of performance reasons, use store API for testing existence in store).
+			// item: Object
+			//		The item.
+			// returns: String
+			
+			if(this.owner){
+				return this.owner.getItemStoreState(item);
+			}
+
+			if(this._itemStoreState == null){
+				return "stored";
+			}
+			
+			var store = this.get("store");
+			var id = item.id == undefined ? store.getIdentity(item) : item.id;
+			var s = this._itemStoreState[id];
+			
+			if(store != null && s != undefined){				
+				return s.state;								
+			}
+			return "stored";		
+		},
+		
+		_setItemStoreState: function(/*Object*/item, /*String*/state){
+			// tags
+			//		private
+			
+			if(this.owner){
+				this.owner._setItemStoreState(item, state);
+				return;
+			}
+			
+			if(this._itemStoreState == undefined){
+				this._itemStoreState = {};
+			}
+			
+			var store = this.get("store");
+			var id = item.id == undefined ? store.getIdentity(item) : item.id;
+			var s = this._itemStoreState[id];
+			
+						
+			if(state == "stored" || state == null){
+				if(s != undefined){
+					delete this._itemStoreState[id];					
+				}
+				return;	
+			}
+
+			if(store){				
+				this._itemStoreState[id] = {
+						id: id,
+						item: item,
+						renderItem: this.itemToRenderItem(item, store),
+						state: state
+				};						
+			}
+		}
+				
+	});
+
+});
diff --git a/dojox/calendar/Touch.js b/dojox/calendar/Touch.js
new file mode 100755
index 0000000..6d59583
--- /dev/null
+++ b/dojox/calendar/Touch.js
@@ -0,0 +1,448 @@
+define(["dojo/_base/array", "dojo/_base/lang", "dojo/_base/declare", "dojo/dom", "dojo/dom-geometry", "dojo/_base/window", "dojo/on", "dojo/_base/event", "dojo/keys"],
+
+	function(arr, lang, declare, dom, domGeometry, win, on, event, keys){
+			
+	return declare("dojox.calendar.Touch", null, {
+		
+		// summary:
+		//		This plugin is managing the touch interactions on item renderers displayed by a calendar view.		
+				
+		// touchStartEditingTimer: Integer
+		//		The delay of one touch over the renderer before setting the item in editing mode.		
+		touchStartEditingTimer: 500,
+		
+		// touchEndEditingTimer: Integer
+		//		The delay after which the item is leaving the editing mode after the previous editing gesture, in touch context.
+		touchEndEditingTimer: 10000,
+		
+		postMixInProperties: function(){
+			
+			this.on("rendererCreated", lang.hitch(this, function(irEvent){
+				
+				var renderer = irEvent.renderer.renderer;
+						
+				this.own(on(renderer.domNode, "touchstart", lang.hitch(this, function(e){
+					this._onRendererTouchStart(e, renderer);
+				})));
+				
+			}));
+		},
+		
+		_onRendererTouchStart: function(e, renderer){
+			// tags:
+			//		private
+			var p = this._edProps;	
+			
+			if(p && p.endEditingTimer){
+				clearTimeout(p.endEditingTimer);
+				p.endEditingTimer = null;
+			}				
+
+			var theItem = renderer.item.item;
+
+			if(p && p.endEditingTimer){
+				clearTimeout(p.endEditingTimer);
+				p.endEditingTimer = null;
+			}
+
+			if(p != null && p.item != theItem){
+				// another item is edited.
+				// stop previous item
+				if(p.startEditingTimer){
+					clearTimeout(p.startEditingTimer);
+				}
+
+				this._endItemEditing("touch", false);
+				p = null;
+
+			}
+
+			// initialize editing properties
+			if(!p){
+				
+				// register event listeners to manage gestures.
+				var handles = [];
+				
+				handles.push(on(win.doc, "touchend", lang.hitch(this, this._docEditingTouchEndHandler)));
+				handles.push(on(this.itemContainer, "touchmove", lang.hitch(this, this._docEditingTouchMoveHandler)));						
+				
+				this._setEditingProperties({
+					touchMoved: false,
+					item: theItem,
+					renderer: renderer,
+					rendererKind: renderer.rendererKind,
+					event: e,
+					handles: handles,
+					liveLayout: this.liveLayout
+				});
+
+				p = this._edProps;
+			}
+
+			if(this._isEditing){
+									
+				// get info on touches 
+				lang.mixin(p, this._getTouchesOnRenderers(e, p.editedItem));
+				
+				// start an editing gesture.
+				this._startTouchItemEditingGesture(e);
+				
+			} else {
+				
+				// initial touch that will trigger or not the editing
+			
+				if(e.touches.length > 1){
+					event.stop(e);
+					return;
+				}
+				
+				// set the selection state without dispatching (on touch end) after a short amount of time.
+				// to allow a bit of time to scroll without selecting (graphically at least) 											
+				this._touchSelectionTimer = setTimeout(lang.hitch(this, function(){									
+					
+					this._saveSelectedItems = this.get("selectedItems");
+							
+					var changed = this.selectFromEvent(e, theItem._item, renderer, false);
+					
+					if(changed){					
+						this._pendingSelectedItem = theItem;
+					}else{
+						delete this._saveSelectedItems;
+					}
+					this._touchSelectionTimer = null;
+				}), 200);
+				
+				p.start = {x: e.touches[0].screenX, y: e.touches[0].screenY};
+				
+				if(this.isItemEditable(p.item, p.rendererKind)){
+									
+					// editing gesture timer
+					this._edProps.startEditingTimer = setTimeout(lang.hitch(this, function(){											
+						
+						// we are editing, so the item *must* be selected.
+						if(this._touchSelectionTimer){							
+							clearTimeout(this._touchSelectionTimer);
+							delete this._touchSelectionTime; 
+						}
+						if(this._pendingSelectedItem){							
+							this.dispatchChange(this._saveSelectedItems == null ? null : this._saveSelectedItems[0], this._pendingSelectedItem, null, e);
+							delete this._saveSelectedItems;
+							delete this._pendingSelectedItem;
+						}else{							
+							this.selectFromEvent(e, theItem._item, renderer);
+						}
+																					
+						this._startItemEditing(p.item, "touch", e);
+						
+						p.moveTouchIndex = 0;
+						
+						// A move gesture is initiated even if we don't move 
+						this._startItemEditingGesture([this.getTime(e)], "move", "touch", e);
+						
+					}), this.touchStartEditingTimer);
+				
+				}				
+			}							
+		},
+		
+		_docEditingTouchMoveHandler: function(e){
+			// tags:
+			//		private
+			var p = this._edProps;
+										
+			// When the screen is touched, it can dispatch move events if the 
+			// user press the finger a little more...
+			var touch = {x: e.touches[0].screenX, y: e.touches[0].screenY};														
+			if(p.startEditingTimer && 
+					(Math.abs(touch.x - p.start.x) > 25 || 
+					 Math.abs(touch.y - p.start.y) > 25)) {
+					 	
+				// scroll use case, do not edit
+				clearTimeout(p.startEditingTimer);
+				p.startEditingTimer = null;
+				
+				clearTimeout(this._touchSelectionTimer);
+				this._touchSelectionTimer = null;				
+				
+				if(this._pendingSelectedItem){					
+					delete this._pendingSelectedItem;
+					this.selectFromEvent(e, null, null, false);
+				}			
+			}
+			
+			p.touchMoved = true;
+								
+			if(this._editingGesture){				
+			
+				event.stop(e);
+				
+				if(p.itemBeginDispatched){
+					
+					var times = [];
+					var d = p.editKind == "resizeEnd" ? p.editedItem.endTime : p.editedItem.startTime;
+					
+					switch(p.editKind){
+						case "move":
+						  var touchIndex = p.moveTouchIndex == null || p.moveTouchIndex < 0 ? 0 : p.moveTouchIndex;
+							times[0] = this.getTime(e, -1, -1, touchIndex);							
+							break;
+						case "resizeStart":
+							times[0] = this.getTime(e, -1, -1, p.resizeStartTouchIndex);							
+							break;
+						case "resizeEnd":
+							times[0] = this.getTime(e, -1, -1, p.resizeEndTouchIndex);							
+							break;
+						case "resizeBoth":
+							times[0] = this.getTime(e, -1, -1, p.resizeStartTouchIndex);
+							times[1] = this.getTime(e, -1, -1, p.resizeEndTouchIndex);
+							break;							
+					}
+														
+					this._moveOrResizeItemGesture(times, "touch", e);
+					
+					if(p.editKind == "move"){
+						if(this.renderData.dateModule.compare(p.editedItem.startTime, d) == -1){
+							this.ensureVisibility(p.editedItem.startTime, p.editedItem.endTime, "start", this.autoScrollTouchMargin);							
+						}else{
+							this.ensureVisibility(p.editedItem.startTime, p.editedItem.endTime, "end", this.autoScrollTouchMargin);
+						}
+					}else if(e.editKind == "resizeStart" || e.editKind == "resizeBoth"){
+						this.ensureVisibility(p.editedItem.startTime, p.editedItem.endTime, "start", this.autoScrollTouchMargin);	
+					}else{
+						this.ensureVisibility(p.editedItem.startTime, p.editedItem.endTime, "end", this.autoScrollTouchMargin);
+					}
+																		
+				}			
+			} // else scroll, if any, is delegated to sub class							
+						
+		},
+		
+		// autoScrollTouchMargin: Integer
+		//		The minimum number of minutes of margin around the edited event. 
+		autoScrollTouchMargin: 10,
+		
+		_docEditingTouchEndHandler: function(e){
+			// tags:
+			//		private
+			event.stop(e);
+			
+			var p = this._edProps;
+			
+			if(p.startEditingTimer){
+				clearTimeout(p.startEditingTimer);
+				p.startEditingTimer = null;
+			}
+								
+			if(this._isEditing){
+				
+				lang.mixin(p, this._getTouchesOnRenderers(e, p.editedItem));
+				
+				if(this._editingGesture){
+				
+					if(p.touchesLen == 0){
+						
+						// all touches were removed => end of editing gesture
+						this._endItemEditingGesture("touch", e);
+						
+						if(this.touchEndEditingTimer > 0){
+						
+							// Timer that trigger the end of the item editing mode.
+							p.endEditingTimer = setTimeout(lang.hitch(this, function(){															
+																	
+								this._endItemEditing("touch", false);															
+								
+							}), this.touchEndEditingTimer);
+						} // else validation must be explicit
+						
+					}else{
+												
+						if(this._editingGesture){
+							this._endItemEditingGesture("touch", e);
+						}
+						// there touches of interest on item, process them.
+						this._startTouchItemEditingGesture(e);						
+					}
+				}
+				
+			}else if(!p.touchMoved){
+												
+				event.stop(e);
+					
+				arr.forEach(p.handles, function(handle){
+					handle.remove();
+				});
+								
+				if(this._touchSelectionTimer){					
+					// selection timer was not reached to a proper selection.
+					clearTimeout(this._touchSelectionTimer);
+					this.selectFromEvent(e, p.item._item, p.renderer, true);
+					
+				}else if(this._pendingSelectedItem){
+					// selection timer was reached, dispatch change event
+					this.dispatchChange(this._saveSelectedItems.length == 0 ? null : this._saveSelectedItems[0], 
+						this._pendingSelectedItem, null, e); // todo renderer ?
+					delete this._saveSelectedItems;
+					delete this._pendingSelectedItem;					
+				}
+								
+				if(this._pendingDoubleTap && this._pendingDoubleTap.item == p.item){							
+					this._onItemDoubleClick({
+						triggerEvent: e,
+						renderer: p.renderer,
+						item: p.item._item
+					});
+					
+					clearTimeout(this._pendingDoubleTap.timer);
+					
+					delete this._pendingDoubleTap;					
+					
+				}else{
+					
+					this._pendingDoubleTap = {
+						item: p.item,
+						timer: setTimeout(lang.hitch(this, function(){
+								delete this._pendingDoubleTap;								
+							}), this.doubleTapDelay)
+					};
+																						
+					this._onItemClick({
+						triggerEvent: e,
+						renderer: p.renderer,
+						item: p.item._item
+					});
+				}
+								
+				this._edProps = null;
+							
+			}else{
+				// scroll view has finished.									
+				
+				if(this._saveSelectedItems){									
+											
+					// selection without dipatching was done, but the view scrolled, 
+					// so revert last selection
+				  this.set("selectedItems", this._saveSelectedItems);					
+					delete this._saveSelectedItems;
+					delete this._pendingSelectedItem;
+				}								
+							
+				arr.forEach(p.handles, function(handle){
+					handle.remove();
+				});
+							
+				this._edProps = null;				
+			}
+		},
+		
+		_startTouchItemEditingGesture: function(e){
+			// summary:
+			//		Determines if a editing gesture is starting according to touches.  
+			// tags:
+			//		private
+
+			var p = this._edProps;
+
+			var fromResizeStart = p.resizeStartTouchIndex != -1;
+			var fromResizeEnd = p.resizeEndTouchIndex != -1;
+
+			if(fromResizeStart && fromResizeEnd || // initial gesture using two touches 
+					this._editingGesture && p.touchesLen == 2 && 
+					(fromResizeEnd && p.editKind == "resizeStart" || 
+					 fromResizeStart && p.editKind =="resizeEnd")){ // gesture one after the other touch
+
+				if(this._editingGesture && p.editKind != "resizeBoth"){ // stop ongoing gesture
+					this._endItemEditingGesture("touch", e);
+				}
+
+				p.editKind = "resizeBoth";
+
+				this._startItemEditingGesture([this.getTime(e, -1, -1, p.resizeStartTouchIndex), 
+					this.getTime(e, -1, -1, p.resizeEndTouchIndex)], 
+					p.editKind, "touch", e);
+
+			}else if(fromResizeStart && p.touchesLen == 1 && !this._editingGesture){
+
+				this._startItemEditingGesture([this.getTime(e, -1, -1, p.resizeStartTouchIndex)], 
+					"resizeStart", "touch", e);
+
+			}else if(fromResizeEnd && p.touchesLen == 1 && !this._editingGesture){
+
+				this._startItemEditingGesture([this.getTime(e, -1, -1, p.resizeEndTouchIndex)], 
+					"resizeEnd", "touch", e);
+
+			} else {
+				// A move gesture is initiated even if we don't move 
+				this._startItemEditingGesture([this.getTime(e)], "move", "touch", e);
+			}					
+		},
+		
+		_getTouchesOnRenderers: function(e, item){
+			// summary:
+			//		Returns the touch indices that are on a editing handles or body of the renderers 
+			// tags:
+			//		private
+			// item: Object
+			//		The render item.
+			// e: Event
+			//		The touch event.
+			// tags:
+			//		private
+			
+			var irs = this._getStartEndRenderers(item);
+										
+			var resizeStartTouchIndex = -1;			
+			var resizeEndTouchIndex = -1;			
+			var moveTouchIndex = -1;
+			var hasResizeStart = irs[0] != null && irs[0].resizeStartHandle != null;
+			var hasResizeEnd = irs[1] != null && irs[1].resizeEndHandle != null;
+			var len = 0;
+			var touched = false;			
+			var list = this.itemToRenderer[item.id];
+														
+			for(var i=0; i<e.touches.length; i++){
+				
+				if(resizeStartTouchIndex == -1 && hasResizeStart){
+					touched = dom.isDescendant(e.touches[i].target, irs[0].resizeStartHandle);
+					if(touched){
+						resizeStartTouchIndex = i;
+						len++;
+					}
+				}
+				
+				if(resizeEndTouchIndex == -1 && hasResizeEnd){
+					touched = dom.isDescendant(e.touches[i].target, irs[1].resizeEndHandle);
+					if(touched){
+						resizeEndTouchIndex = i;
+						len++;
+					}
+				}
+
+				if(resizeStartTouchIndex == -1 && resizeEndTouchIndex == -1){ 
+
+					for (var j=0; j<list.length; j++){
+					  touched = dom.isDescendant(e.touches[i].target, list[j].container);
+						if(touched){
+							moveTouchIndex = i;
+							len++;
+							break;
+						}
+					}
+				}
+
+				if(resizeStartTouchIndex != -1 && resizeEndTouchIndex != -1 && moveTouchIndex != -1){
+					// all touches of interest were found, ignore other ones.
+				  break;	
+				}
+			}
+
+			return {
+				touchesLen: len,
+				resizeStartTouchIndex: resizeStartTouchIndex,
+				resizeEndTouchIndex: resizeEndTouchIndex,
+				moveTouchIndex: moveTouchIndex
+			};
+		}
+
+	});
+
+});
diff --git a/dojox/calendar/VerticalRenderer.js b/dojox/calendar/VerticalRenderer.js
new file mode 100644
index 0000000..0c86504
--- /dev/null
+++ b/dojox/calendar/VerticalRenderer.js
@@ -0,0 +1,39 @@
+define(["dojo/_base/declare", "dijit/_WidgetBase", "dijit/_TemplatedMixin",
+	"dojox/calendar/_RendererMixin", "dojo/text!./templates/VerticalRenderer.html"],
+	
+	function(declare, _WidgetBase, _TemplatedMixin, _RendererMixin, template){
+	
+	return declare("dojox.calendar.VerticalRenderer", [_WidgetBase, _TemplatedMixin, _RendererMixin], {
+		
+		// summary:
+		//		The default item vertical renderer.		
+		
+		templateString: template,
+		
+		postCreate: function() {
+			this.inherited(arguments);
+			this._applyAttributes();
+		},
+	
+		_isElementVisible: function(elt, startHidden, endHidden, size){
+			var d;
+			
+			switch(elt){
+				case "startTimeLabel":
+					d = this.item.startTime;
+					if(this.item.allDay || this.owner.isStartOfDay(d)){
+						return false;
+					}
+					break;
+				case "endTimeLabel":
+					d = this.item.endTime;
+					if(this.item.allDay || this.owner.isStartOfDay(d)){
+						return false;
+					}
+					break;
+			}
+			return this.inherited(arguments);
+		}
+		
+	});
+});
diff --git a/dojox/calendar/ViewBase.js b/dojox/calendar/ViewBase.js
new file mode 100755
index 0000000..26aacba
--- /dev/null
+++ b/dojox/calendar/ViewBase.js
@@ -0,0 +1,2843 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/window",
+	"dojo/_base/event",
+	"dojo/_base/html",
+	"dojo/sniff",
+	"dojo/query",
+	"dojo/dom",
+	"dojo/dom-style",
+	"dojo/dom-construct",
+	"dojo/dom-geometry",
+	"dojo/on",
+	"dojo/date",
+	"dojo/date/locale",
+	"dijit/_WidgetBase",
+	"dojox/widget/_Invalidating",
+	"dojox/widget/Selection",
+	"dojox/calendar/time",
+	"./StoreMixin"],
+
+	function(
+		declare,
+		lang,
+		arr,
+		win,
+		event,
+		html,
+		has,
+		query,
+		dom,
+		domStyle,
+		domConstruct,
+		domGeometry,
+		on,
+		date,
+		locale,
+		_WidgetBase,
+		_Invalidating,
+		Selection,
+		timeUtil,
+		StoreMixin){
+	
+	/*=====
+	var __GridClickEventArgs = {
+		// summary:
+		//		The event dispatched when the grid is clicked or double-clicked.
+		// date: Date
+		//		The start of the previously displayed time interval, if any. 
+		// triggerEvent: Event
+		//		The event at the origin of this event.
+	};
+	=====*/
+	
+	/*=====
+	var __ItemMouseEventArgs = {
+		// summary:
+		//		The event dispatched when an item is clicked, double-clicked or context-clicked.
+		// item: Object
+		//		The item clicked.
+		// renderer: dojox/calendar/_RendererMixin
+		//		The item renderer clicked.
+		// triggerEvent: Event
+		//		The event at the origin of this event.
+	};
+	=====*/
+	
+	/*=====
+	var __itemEditingEventArgs = {
+		// summary:
+		//		An item editing event.
+		// item: Object
+		//		The render item that is being edited. Set/get the startTime and/or endTime properties to customize editing behavior.
+		// storeItem: Object
+		//		The real data from the store. DO NOT change properties, but you may use properties of this item in the editing behavior logic.
+		// editKind: String
+		//		Kind of edit: "resizeBoth", "resizeStart", "resizeEnd" or "move".
+		// dates: Date[]
+		//		The computed date/time of the during the event editing. One entry per edited date (touch use case).
+		// startTime: Date?
+		//		The start time of data item.
+		// endTime: Date?
+		//		The end time of data item.
+		// sheet: String
+		//		For views with several sheets (columns view for example), the sheet when the event occurred.
+		// source: dojox/calendar/ViewBase
+		//		The view where the event occurred.
+		// eventSource: String
+		//		The device that triggered the event. This property can take the following values:
+		//
+		//		- "mouse", 
+		//		- "keyboard", 
+		//		- "touch"		
+		// triggerEvent: Event
+		//		The event at the origin of this event.
+	};
+	=====*/
+	
+	/*=====
+	var __rendererLifecycleEventArgs = {
+		// summary:
+		//		An renderer lifecycle event.
+		// renderer: Object
+		//		The renderer.		
+		// source: dojox/calendar/ViewBase
+		//		The view where the event occurred.
+		// item:Object?
+		//		The item that will be displayed by the renderer for the "rendererCreated" and "rendererReused" events. 
+	};
+	=====*/
+
+	return declare("dojox.calendar.ViewBase", [_WidgetBase, StoreMixin, _Invalidating, Selection], {
+		
+		// summary:
+		//		The dojox.calendar.ViewBase widget is the base of calendar view widgets
+		
+		// datePackage: Object
+		//		JavaScript namespace to find Calendar routines. Uses Gregorian Calendar routines at dojo.date by default.
+		datePackage: date,
+		
+		_calendar: "gregorian",
+		
+		// viewKind: String
+		//		Kind of the view. Used by the calendar widget to determine how to configure the view.
+		viewKind: null,
+		
+		// _layoutStep: [protected] Integer
+		//		The number of units displayed by a visual layout unit (i.e. a column or a row)
+		_layoutStep: 1,
+		
+		// _layoutStep: [protected] Integer
+		//		The unit displayed by a visual layout unit (i.e. a column or a row)
+		_layoutUnit: "day",
+		
+		// resizeCursor: String
+		//		CSS value to apply to the cursor while resizing an item renderer. 
+		resizeCursor: "n-resize",
+		
+		// formatItemTimeFunc: Function
+		//		Optional function to format the time of day of the item renderers.
+		//		The function takes the date and render data object as arguments and returns a String.
+		formatItemTimeFunc: null,
+		
+		_cssDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+				
+		_getFormatItemTimeFuncAttr: function(){
+			if(this.owner != null){
+				return this.owner.get("formatItemTimeFunc");
+			}
+			return this.formatItemTimeFunc;			
+		},
+		
+		// The listeners added by the view itself.
+		_viewHandles: null,
+		
+		// doubleTapDelay: Integer
+		//		The maximum time amount in milliseconds between to touchstart events that trigger a double-tap event.  
+		doubleTapDelay: 300,
+		
+		constructor: function(/*Object*/ args){
+			args = args || {};
+			
+			this._calendar = args.datePackage ? args.datePackage.substr(args.datePackage.lastIndexOf(".")+1) : this._calendar; 
+			this.dateModule = args.datePackage ? lang.getObject(args.datePackage, false) : date; 
+			this.dateClassObj = this.dateModule.Date || Date; 
+			this.dateLocaleModule = args.datePackage ? lang.getObject(args.datePackage+".locale", false) : locale; 
+			
+			this.rendererPool = [];
+			this.rendererList = [];
+			this.itemToRenderer = {};
+			this._viewHandles = [];
+		},
+		
+		destroy: function(preserveDom){
+			// renderers
+			while(this.rendererList.length > 0){
+				this._destroyRenderer(this.rendererList.pop());
+			}			
+			for(var kind in this._rendererPool){
+				var pool = this._rendererPool[kind];
+				if(pool){
+					while(pool.length > 0){
+						this._destroyRenderer(pool.pop());
+					}
+				}
+			}
+			
+			while(this._viewHandles.length > 0){
+				this._viewHandles.pop().remove();
+			}
+		
+			this.inherited(arguments);
+		},
+		
+		
+		resize: function(){
+			// summary:
+			//		Function to call when the view is resized. 
+			//		If the view is in a Dijit container or in a Dojo mobile container, it will be automatically called.
+			//		On other use cases, this method must called when the window is resized and/or when the orientation has changed.
+		},
+		
+		_getTopOwner: function(){
+			// summary:
+			//		Returns the top owner: the calendar or the parent view.
+			var p = this;
+			while(p.owner != undefined){
+				p = p.owner;
+			}
+			return p;
+		},
+		
+		_createRenderData: function(){
+			// summary:
+			//		Creates the object that contains all the data needed to render this widget.
+			// tags:
+			//		protected
+		},
+		
+		_validateProperties: function(){
+			// summary:
+			//		Validates the widget properties before the rendering pass.
+			// tags:
+			//		protected
+		},
+
+		_setText: function(node, text, allowHTML){
+			// summary:
+			//		Creates a text node under the parent node after having removed children nodes if any.
+			// node: Node
+			//		The node that will contain the text node.
+			// text: String
+			//		The text to set to the text node.
+			if(text != null){			
+				if(!allowHTML && node.hasChildNodes()){
+					// span > textNode
+					node.childNodes[0].childNodes[0].nodeValue = text;
+				}else{												
+			
+					while(node.hasChildNodes()){
+						node.removeChild(node.lastChild);
+					}				
+			
+					var tNode = win.doc.createElement("span");
+					if(has("dojo-bidi")){
+						this.applyTextDir(tNode, text);
+					}
+					
+					if(allowHTML){
+						tNode.innerHTML = text;
+					}else{
+						tNode.appendChild(win.doc.createTextNode(text));
+					}
+					node.appendChild(tNode);
+				}
+			}
+		},
+		
+		isAscendantHasClass: function(node, ancestor, className){
+			// summary:
+			//		Determines if a node has an ascendant node that has the css class specified.
+			// node: Node
+			//		The DOM node.
+			// ancestor: Node
+			//		The ancestor node used to limit the search in hierarchy.
+			// className: String
+			//		The css class name.
+			// returns: Boolean
+			
+			while(node != ancestor && node != document){
+				
+				if(dojo.hasClass(node, className)){
+					return true;
+				}
+				
+				node = node.parentNode;
+			}
+			return false;
+		},
+		
+		isWeekEnd: function(date){
+			// summary:
+			//		Determines whether the specified date is a week-end.
+			//		This method is using dojo.date.locale.isWeekend() method as
+			//		dojox.date.XXXX calendars are not supporting this method.
+			// date: Date
+			//		The date to test.  
+			return locale.isWeekend(date);
+		},
+		
+		getWeekNumberLabel: function(date){
+			// summary:
+			//		Returns the week number string from dojo.date.locale.format() method as
+			//		dojox.date.XXXX calendar are not supporting the "w" pattern.
+			// date: Date
+			//		The date to format.
+			if(date.toGregorian){
+				date = date.toGregorian();
+			}
+			return locale.format(date, {
+				selector: "date", 
+				datePattern: "w"});
+		},
+		
+		floorToDay: function(date, reuse){
+			// summary:
+			//		Floors the specified date to the start of day.
+			// date: Date
+			//		The date to floor.
+			// reuse: Boolean
+			//		Whether use the specified instance or create a new one. Default is false.
+			// returns: Date
+			return timeUtil.floorToDay(date, reuse, this.dateClassObj);
+		},
+		
+		floorToMonth: function(date, reuse){
+			// summary:
+			//		Floors the specified date to the start of the date's month.
+			// date: Date
+			//		The date to floor.
+			// reuse: Boolean
+			//		Whether use the specified instance or create a new one. Default is false.
+			// returns: Date
+			return timeUtil.floorToMonth(date, reuse, this.dateClassObj);
+		},
+		
+				
+		floorDate: function(date, unit, steps, reuse){
+			// summary:
+			//		floors the date to the unit.
+			// date: Date
+			//		The date/time to floor.
+			// unit: String
+			//		The unit. Valid values are "minute", "hour", "day".
+			// steps: Integer
+			//		For "day" only 1 is valid.
+			// reuse: Boolean
+			//		Whether use the specified instance or create a new one. Default is false.			
+			// returns: Date
+			return timeUtil.floor(date, unit, steps, reuse, this.dateClassObj);
+		},
+
+		isToday: function(date){
+			// summary:
+			//		Returns whether the specified date is in the current day.
+			// date: Date
+			//		The date to test.
+			// renderData: Object
+			//		The current renderData
+			// returns: Boolean
+			return timeUtil.isToday(date, this.dateClassObj);
+		},
+		
+		isStartOfDay: function(d){
+			// summary:
+			//		Tests if the specified date represents the starts of day. 
+			// d:Date
+			//		The date to test.
+			// returns: Boolean
+			return timeUtil.isStartOfDay(d, this.dateClassObj, this.dateModule);
+		},
+		
+		isOverlapping: function(renderData, start1, end1, start2, end2, includeLimits){
+			// summary:
+			//		Computes if the first time range defined by the start1 and end1 parameters 
+			//		is overlapping the second time range defined by the start2 and end2 parameters.
+			// renderData: Object
+			//		The render data.
+			// start1: Date
+			//		The start time of the first time range.
+			// end1: Date
+			//		The end time of the first time range.
+			// start2: Date
+			//		The start time of the second time range.
+			// end2: Date
+			//		The end time of the second time range.
+			// includeLimits: Boolean
+			//		Whether include the end time or not.
+			// returns: Boolean
+			if(start1 == null || start2 == null || end1 == null || end2 == null){
+				return false;
+			}
+			
+			var cal = renderData.dateModule;
+			
+			if(includeLimits){
+				if(cal.compare(start1, end2) == 1 || cal.compare(start2, end1) == 1){
+					return false;
+				}					
+			}else if(cal.compare(start1, end2) != -1 || cal.compare(start2, end1) != -1){
+				return false;
+			}
+			return true; 
+		},			 
+			 
+		computeRangeOverlap: function(renderData, start1, end1, start2, end2, includeLimits){
+			// summary:
+			//		Computes the overlap time range of the time ranges.
+			//		Returns a vector of Date with at index 0 the start time and at index 1 the end time.
+			// renderData: Object.
+			//		The render data.
+			// start1: Date
+			//		The start time of the first time range.
+			// end1: Date
+			//		The end time of the first time range.
+			// start2: Date
+			//		The start time of the second time range.
+			// end2: Date
+			//		The end time of the second time range.
+			// includeLimits: Boolean
+			//		Whether include the end time or not.
+			// returns: Date[]
+			var cal = renderData.dateModule;
+			
+			if(start1 == null || start2 == null || end1 == null || end2 == null){
+				return null;
+			}
+			
+			var comp1 = cal.compare(start1, end2);
+			var comp2 = cal.compare(start2, end1);
+			
+			if(includeLimits){
+				
+				if(comp1 == 0 || comp1 == 1 || comp2 == 0 || comp2 == 1){
+					return null;
+				}
+			} else if(comp1 == 1 || comp2 == 1){
+				return null;
+			}
+			
+			return [
+				this.newDate(cal.compare(start1, start2)>0 ? start1: start2, renderData),
+				this.newDate(cal.compare(end1, end2)>0 ? end2: end1, renderData)
+			];
+		},
+		
+		isSameDay : function(date1, date2){
+			// summary:
+			//		Tests if the specified dates are in the same day.
+			// date1: Date
+			//		The first date.
+			// date2: Date
+			//		The second date.
+			// returns: Boolean
+			if(date1 == null || date2 == null){
+				return false; 
+			}
+		
+			return date1.getFullYear() == date2.getFullYear() &&
+						 date1.getMonth() == date2.getMonth() &&
+						 date1.getDate() == date2.getDate();
+			 
+		},
+		
+		computeProjectionOnDate: function(renderData, refDate, date, max){
+			// summary:
+			//		Computes the time to pixel projection in a day.
+			// renderData: Object
+			//		The render data.
+			// refDate: Date
+			//		The reference date that defines the destination date.
+			// date: Date
+			//		The date to project.
+			// max: Integer
+			//		The size in pixels of the representation of a day.
+			// tags:
+			//		protected
+			// returns: Number
+
+			var cal = renderData.dateModule;
+			
+			if(max <= 0 || cal.compare(date, refDate) == -1){
+				return 0;
+			}
+			
+			var referenceDate = this.floorToDay(refDate, false, renderData);
+
+			if(date.getDate() != referenceDate.getDate()){
+				if(date.getMonth() == referenceDate.getMonth()){
+					if(date.getDate() < referenceDate.getDate()){
+						return 0;
+					} else if(date.getDate() > referenceDate.getDate()){
+						return max;
+					}
+				}else{
+					if(date.getFullYear() == referenceDate.getFullYear()){
+						if(date.getMonth() < referenceDate.getMonth()){
+							return 0;
+						} else if(date.getMonth() > referenceDate.getMonth()){
+							return max;
+						}						 
+					}else{
+						if(date.getFullYear() < referenceDate.getFullYear()){
+							return 0;
+						} else if(date.getFullYear() > referenceDate.getFullYear()){
+							return max;
+						}
+					}
+				}
+			}
+
+			var res;
+
+			if(this.isSameDay(refDate, date)){
+				
+				var d = lang.clone(refDate);
+				var minTime = 0;
+				
+				if(renderData.minHours != null && renderData.minHours != 0){
+					d.setHours(renderData.minHours);
+					minTime = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds();
+				}
+				
+				d = lang.clone(refDate);
+				
+				var maxTime;
+				if(renderData.maxHours == null || renderData.maxHours == 24){
+					maxTime = 86400; // 24h x 60m x 60s
+				}else{
+					d.setHours(renderData.maxHours);
+					maxTime = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds();
+				}
+				
+				//precision is the second
+				//use this API for daylight time issues.
+				var delta = date.getHours() * 3600 + date.getMinutes() * 60 + date.getSeconds() - minTime;
+				
+				if(delta < 0){
+					return 0;
+				}
+				if(delta > maxTime){
+					return max;
+				}
+
+				res = (max * delta)/(maxTime - minTime);
+				
+			}else{
+				
+				if(date.getDate() < refDate.getDate() && 
+						date.getMonth() == refDate.getMonth()){
+					return 0;
+				}
+				
+				var d2 = this.floorToDay(date);
+				var dp1 = renderData.dateModule.add(refDate, "day", 1);
+				dp1 = this.floorToDay(dp1, false, renderData);
+				
+				if(cal.compare(d2, refDate) == 1 && cal.compare(d2, dp1) == 0 || cal.compare(d2, dp1) == 1){
+					res =	max;
+				}else{
+					res = 0;
+				}
+			}
+				
+			return res;
+		},	
+		
+		getTime: function(e, x, y, touchIndex){
+			// summary:
+			//		Returns the time displayed at the specified point by this component.
+			// e: Event
+			//		Optional mouse event.
+			// x: Number
+			//		Position along the x-axis with respect to the sheet container used if event is not defined.
+			// y: Number
+			//		Position along the y-axis with respect to the sheet container (scroll included) used if event is not defined.
+			// touchIndex: Integer
+			//		If parameter 'e' is not null and a touch event, the index of the touch to use.
+			// returns: Date
+			return null;
+		},
+		
+		newDate: function(obj){
+			// summary:
+			//		Creates a new Date object.
+			// obj: Object
+			//		This object can have several values:
+			//
+			//		- the time in milliseconds since gregorian epoch.
+			//		- a Date instance
+			// returns: Date
+			return timeUtil.newDate(obj, this.dateClassObj);			
+		},
+		
+		_isItemInView: function(item){
+			// summary:
+			//		Computes whether the specified item is entirely in the view or not.
+			// item: Object
+			//		The item to test
+			// returns: Boolean	
+			var rd = this.renderData;
+			var cal = rd.dateModule;
+			
+			if(cal.compare(item.startTime, rd.startTime) == -1){
+				return false;
+			} 			
+			
+			return cal.compare(item.endTime, rd.endTime) != 1;
+		},
+		
+		_ensureItemInView: function(item){
+			// summary:
+			//		If needed, moves the item to be entirely in view.
+			// item: Object
+			//		The item to test
+			// returns: Boolean
+			//		Whether the item has been moved to be in view or not.
+			// tags:
+			//		protected
+
+			var rd = this.renderData;
+			var cal = rd.dateModule;
+			
+			var duration = Math.abs(cal.difference(item.startTime, item.endTime, "millisecond"));
+			var fixed = false;
+			
+			if(cal.compare(item.startTime, rd.startTime) == -1){
+				item.startTime = rd.startTime;
+				item.endTime = cal.add(item.startTime, "millisecond", duration);
+				fixed = true;
+			}else if(cal.compare(item.endTime, rd.endTime) == 1){
+				item.endTime = rd.endTime;
+				item.startTime = cal.add(item.endTime, "millisecond", -duration);
+				fixed = true;
+			}			
+			return fixed;
+		},
+		
+		/////////////////////////////////////////////////////////
+		//
+		// Scrollable
+		//
+		/////////////////////////////////////////////////////////
+				
+		// scrollable: Boolean
+		//		Indicates whether the view can be scrolled or not.
+		scrollable: true,
+		
+		// autoScroll: Boolean
+		//		Indicates whether the view can be scrolled automatically. 
+		//		Auto scrolling is used when moving focus to a non visible renderer using keyboard 
+		//		and while editing an item. 
+		autoScroll: true,				
+		
+		_autoScroll: function(gx, gy, orientation){
+			// summary:
+			//		Starts or stops the auto scroll according to the mouse cursor position during an item editing.
+			// gx: Integer
+			//		The position of the mouse cursor along the x-axis.
+			// gy: Integer
+			//		The position of the mouse cursor along the y-axis.			
+			// tags:
+			//		extension
+
+			return false;
+		},
+			
+		// scrollMethod: String
+		//		Method used to scroll the view, for example the scroll of column view.
+		//		Valid value are:
+		//
+		//		- "auto": let the view decide (default),
+		//		- "css": use css 3d transform,
+		//		- "dom": use the scrollTop property.
+		scrollMethod: "auto",
+		
+		_setScrollMethodAttr: function(value){
+			if(this.scrollMethod != value){
+				this.scrollMethod = value;
+				
+				// reset
+				if(this._domScroll !== undefined){
+					if(this._domScroll){
+						domStyle.set(this.sheetContainer, this._cssPrefix+"transform", "translateY(0px)");
+					}else{
+						this.scrollContainer.scrollTop = 0;
+					}
+				}
+				
+				delete this._domScroll;
+				var pos = this._getScrollPosition();
+				delete this._scrollPos;
+				
+				this._setScrollPosition(pos);
+			}
+			
+		},
+		
+		_startAutoScroll: function(step){
+			// summary:
+			//		Starts the auto scroll of the view (if it's scrollable). Used only during editing.
+			// tags:
+			//		protected
+			var sp = this._scrollProps;
+			if(!sp){
+				sp = this._scrollProps = {};
+			}
+				
+			sp.scrollStep = step;
+			
+			if (!sp.isScrolling){
+				sp.isScrolling = true;
+				sp.scrollTimer = setInterval(lang.hitch(this, this._onScrollTimer_tick), 10);
+			}		
+		},
+				
+		_stopAutoScroll: function(){
+			// summary:
+			//		Stops the auto scroll of the view (if it's scrollable). Used only during editing.
+			// tags:
+			//		protected
+			var sp = this._scrollProps;
+			
+			if (sp && sp.isScrolling) {
+				clearInterval(sp.scrollTimer);
+				sp.scrollTimer = null;
+			}
+			this._scrollProps = null;
+		},
+		
+		_onScrollTimer_tick: function(pos){
+		},
+		
+		_scrollPos: 0,
+		
+		getCSSPrefix: function(){
+			// summary:
+			//		Utility method that return the specific CSS prefix
+			//		for non standard CSS properties. Ex: -moz-border-radius.
+			if(has("ie")){
+				return "-ms-";
+			}
+			if(has("webkit")){
+				return "-webkit-";
+			}
+			if(has("mozilla")){
+				return "-moz-";
+			}
+			if(has("opera")){
+				return "-o-";
+			}
+            return "";
+		},				
+		
+		_setScrollPosition: function(pos){
+			// summary:
+			//		Sets the scroll position (if the view is scrollable), using the scroll method defined.
+			// tags:
+			//		protected
+
+			if(this._scrollPos == pos){
+				return;
+			}
+			
+			// determine scroll method once.
+			if(this._domScroll === undefined){
+			
+				var sm = this.get("scrollMethod");
+				if(sm === "auto"){					
+					this._domScroll = !has("ios") && !has("android") && !has("webkit");
+				}else{
+					this._domScroll = sm === "dom";
+				}
+			}
+			
+			var containerSize = domGeometry.getMarginBox(this.scrollContainer);
+			var sheetSize = domGeometry.getMarginBox(this.sheetContainer);
+			var max = sheetSize.h - containerSize.h;
+			
+			if(pos < 0){
+				pos = 0;
+			}else if(pos > max){
+				pos = max;
+			}
+			
+			this._scrollPos = pos;
+												
+			if(this._domScroll){				
+				this.scrollContainer.scrollTop = pos;				
+			}else{			
+				if(!this._cssPrefix){
+					this._cssPrefix =  this.getCSSPrefix();
+				}
+				domStyle.set(this.sheetContainer, this._cssPrefix+"transform", "translateY(-"+pos+"px)");
+			}
+		},
+		
+		_getScrollPosition: function(){
+			// summary:
+			//		Returns the scroll position (if the view is scrollable), using the scroll method defined.
+			// tags:
+			//		protected
+
+			return this._scrollPos; 
+		},
+		
+		scrollView: function(dir){
+			// summary:
+			//		If the view is scrollable, scrolls it to the specified direction.
+			// dir: Integer
+			//		Direction of the scroll. Valid values are -1 and 1.
+			// tags:
+			//		extension
+		},
+		
+		ensureVisibility: function(start, end, margin, visibilityTarget, duration){
+			// summary:
+			//		Scrolls the view if the [start, end] time range is not visible or only partially visible.
+			// start: Date
+			//		Start time of the range of interest.
+			// end: Date
+			//		End time of the range of interest.
+			// margin: int
+			//		Margin in minutes around the time range.
+			// visibilityTarget: String
+			//		The end(s) of the time range to make visible.
+			//		Valid values are: "start", "end", "both".	
+			// duration: Number
+			//		Optional, the maximum duration of the scroll animation.
+			// tags:
+			//		extension
+
+		},
+
+	  	////////////////////////////////////////////////////////
+		//
+		// Store & Items
+		//
+		////////////////////////////////////////////////////////
+		
+		_getStoreAttr: function(){
+			if(this.owner){
+				return this.owner.get("store");
+			}
+			return this.store;
+		},
+
+		_setItemsAttr: function(value){
+			this._set("items", value);
+			this.displayedItemsInvalidated = true;
+		},
+
+		_refreshItemsRendering: function(){
+			var rd = this.renderData;
+			this._computeVisibleItems(rd);
+			this._layoutRenderers(rd);
+		},
+		
+		invalidateLayout: function(){
+			// summary:
+			//		Triggers a re-layout of the renderers.
+			this._layoutRenderers(this.renderData);
+		},
+		
+		resize: function(){
+			//this.invalidateRendering();
+		},
+
+		////////////////////////////////////////////////////////
+		//
+		// Layout
+		//
+		////////////////////////////////////////////////////////
+				
+		computeOverlapping: function(layoutItems, func){
+			// summary:
+			//		Computes the overlap layout of a list of items. A lane and extent properties are added to each layout item.
+			// layoutItems: Object[]
+			//		List of layout items, each item must have a start and end properties.
+			// addedPass: Function
+			//		Whether computes the extent of each item renderer on free sibling lanes.
+			// returns: Object
+			// tags:
+			//		protected
+
+			
+			if(layoutItems.length == 0){
+				return {
+					numLanes: 0,
+					addedPassRes: [1]
+				};
+			}
+			
+			var lanes = [];
+
+			for(var i=0; i<layoutItems.length; i++){
+				var layoutItem = layoutItems[i];
+				this._layoutPass1(layoutItem, lanes);
+			}
+
+			var addedPassRes = null;
+			if(func){
+				addedPassRes = lang.hitch(this, func)(lanes);
+			}
+			
+			return {
+				numLanes: lanes.length,
+				addedPassRes: addedPassRes
+			};
+		},
+
+		_layoutPass1: function (layoutItem, lanes){
+			// summary:
+			//		First pass of the overlap layout. Find a lane where the item can be placed or create a new one.
+			// layoutItem: Object
+			//		An object that contains a start and end properties at least.
+			// lanes:
+			//		The array of lanes.
+			// tags:
+			//		protected
+			var stop = true;
+			
+			for(var i=0; i<lanes.length; i++){
+				var lane = lanes[i]; 
+				stop = false;
+				for(var j=0; j<lane.length && !stop; j++){
+					if(lane[j].start < layoutItem.end && layoutItem.start < lane[j].end){
+						// one already placed item is overlapping
+						stop = true;
+						lane[j].extent = 1;
+					} 
+				}
+				if(!stop){
+					//we have found a place
+					layoutItem.lane = i;
+					layoutItem.extent = -1;
+					lane.push(layoutItem);
+					return;
+				}
+			}
+			
+			//no place found -> add a lane
+			lanes.push([layoutItem]);
+			layoutItem.lane = lanes.length-1;			 
+			layoutItem.extent = -1;
+		},
+			
+		
+		
+		_layoutInterval: function(renderData, index, start, end, items){
+			// summary:
+			//		For each item in the items list: retrieve a renderer, compute its location and size and add it to the DOM.
+			// renderData: Object
+			//		The render data.
+			// index: Integer
+			//		The index of the interval.
+			// start: Date
+			//		The start time of the displayed date interval.
+			// end: Date
+			//		The end time of the displayed date interval.
+			// items: Object[]
+			//		The list of the items to represent.
+			// tags:
+			//		extension
+		},
+		
+		// layoutPriorityFunction: Function
+		//		An optional comparison function use to determine the order the item will be laid out
+		//		The function is used to sort an array and must, as any sorting function, take two items 
+		//		as argument and must return an integer whose sign define order between arguments.
+		//		By default, a comparison by start time then end time is used.
+		layoutPriorityFunction: null,
+		
+		_sortItemsFunction: function(a, b){
+			var res = this.dateModule.compare(a.startTime, b.startTime);
+			if(res == 0){
+				res = -1 * this.dateModule.compare(a.endTime, b.endTime);
+			}
+			return res;
+		},
+		
+		_layoutRenderers: function(renderData){
+			// summary:
+			//		Renders the data items. This method will call the _layoutInterval() method.
+			// renderData: Object
+			//		The render data.
+			// tags:
+			//		protected
+			if(!renderData.items){
+				return;
+			}
+						
+			// recycle renderers first
+			this._recycleItemRenderers();
+			
+			var cal = renderData.dateModule; 
+			
+			// Date
+			var startDate = this.newDate(renderData.startTime);
+			
+			// Date and time
+			var startTime = lang.clone(startDate);
+			
+			var endDate;
+			
+			var items = renderData.items.concat();
+
+			var itemsTemp = [], events;
+			
+			var index = 0;
+			
+			while(cal.compare(startDate, renderData.endTime) == -1 && items.length > 0){
+			
+				endDate = cal.add(startDate, this._layoutUnit, this._layoutStep);
+				endDate = this.floorToDay(endDate, true, renderData);
+				
+				var endTime = lang.clone(endDate);
+				
+				if(renderData.minHours){
+					startTime.setHours(renderData.minHours);
+				}
+				
+				if(renderData.maxHours && renderData.maxHours != 24){
+					endTime = cal.add(endDate, "day", -1);
+					endTime = this.floorToDay(endTime, true, renderData);
+					endTime.setHours(renderData.maxHours);
+				}
+				
+				// look for events that overlap the current sub interval
+				events = arr.filter(items, function(item){
+					var r = this.isOverlapping(renderData, item.startTime, item.endTime, startTime, endTime);
+					if(r){
+						// item was not fully processed as it overlaps another sub interval
+						if(cal.compare(item.endTime, endTime) == 1){
+							itemsTemp.push(item);
+						}	
+					}else{
+						itemsTemp.push(item);
+					}
+					return r;
+				}, this);
+
+				items = itemsTemp;
+				itemsTemp = [];
+				
+				// if event are in the current sub interval, layout them
+				if(events.length > 0){
+					// Sort the item according a sorting function, by default start time then end time comparison are used.
+					events.sort(lang.hitch(this, this.layoutPriorityFunction ? this.layoutPriorityFunction : this._sortItemsFunction));
+					this._layoutInterval(renderData, index, startTime, endTime, events);
+				}
+
+				startDate = endDate;
+				startTime = lang.clone(startDate);
+
+				index++;
+			}			
+			
+			this._onRenderersLayoutDone(this);
+		},
+	
+		/////////////////////////////////////////////////////////////////
+		//
+		//	Renderers management
+		//
+		////////////////////////////////////////////////////////////////
+		
+		_recycleItemRenderers: function(remove){
+			// summary:
+			//		Recycles all the item renderers.
+			// remove: Boolean
+			//		Whether remove the DOM node from it parent.
+			// tags:
+			//		protected
+			while(this.rendererList.length>0){
+				this._recycleRenderer(this.rendererList.pop(), remove);
+			}
+			this.itemToRenderer = {};
+		},
+				
+		// rendererPool: [protected] Array
+		//		The stack of recycled renderers available.
+		rendererPool: null,
+		
+		// rendererList: [protected] Array
+		//		The list of used renderers
+		rendererList: null,
+		
+		// itemToRenderer: [protected] Object
+		//		The associated array item to renderer list.
+		itemToRenderer: null,
+		
+		getRenderers: function(item){
+			// summary:
+			//		Returns the renderers that are currently used to displayed the speficied item.
+			//		Returns an array of objects that contains two properties:
+			//		- container: The DOM node that contains the renderer.
+			//		- renderer: The dojox.calendar._RendererMixin instance.
+			//		Do not keep references on the renderers are they are recycled and reused for other items.
+			// item: Object
+			//		The data or render item.
+			// returns: Object[]
+			if(item == null || item.id == null){
+				return null;
+			}
+			var list = this.itemToRenderer[item.id];
+			return list == null ? null : list.concat();
+		},
+		
+		_rendererHandles: {},
+		
+		// itemToRendererKindFunc: Function
+		//		An optional function to associate a kind of renderer ("horizontal", "label" or null) with the specified item.
+		//		By default, if an item is lasting more that 24 hours an horizontal item is used, otherwise a label is used.
+		itemToRendererKindFunc: null,
+		
+		_itemToRendererKind: function(item){
+			// summary: 
+			//		Associates a kind of renderer with a data item.
+			// item: Object
+			//		The data item.
+			// returns: String
+			// tags:
+			//		protected			
+			if(this.itemToRendererKindFunc){
+				return this.itemToRendererKindFunc(item);
+			}
+			return this._defaultItemToRendererKindFunc(item); // String
+		},
+		
+		_defaultItemToRendererKindFunc:function(item){
+			// tags:
+			//		private
+			return null;
+		},
+
+		_createRenderer: function(item, kind, rendererClass, cssClass){			
+			// summary: 
+			//		Creates an item renderer of the specified kind. A renderer is an object with the "container" and "instance" properties.
+			// item: Object
+			//		The data item.
+			// kind: String
+			//		The kind of renderer.
+			// rendererClass: Object
+			//		The class to instantiate to create the renderer.
+			// returns: Object
+			// tags:
+			//		protected				
+						
+			if(item != null && kind != null && rendererClass != null){
+				
+				var res=null, renderer=null;
+				
+				var pool = this.rendererPool[kind];
+				
+				if(pool != null){
+					res = pool.shift();
+				}
+
+				if (res == null){
+
+					renderer = new rendererClass;
+
+					// the container allow to lay out the renderer
+					// this is important for styling (in box model 
+					// content size does take into account border)
+					var container = domConstruct.create("div");
+
+					// The DOM object that will contain the event renderer
+					container.className = "dojoxCalendarEventContainer "+ cssClass ;
+					container.appendChild(renderer.domNode);
+					
+					res = {
+						renderer: renderer,
+						container: renderer.domNode,
+						kind: kind
+					};
+
+					this._onRendererCreated({renderer:res, source:this, item:item});
+					
+				} else {
+					renderer = res.renderer; 
+					
+					this._onRendererReused({renderer:renderer, source:this, item:item});
+				}
+				
+				renderer.owner = this;
+				renderer.set("rendererKind", kind);
+				renderer.set("item", item);
+				
+				var list = this.itemToRenderer[item.id];
+				if (list == null) {
+					this.itemToRenderer[item.id] = list = [];
+				}
+				list.push(res);
+				
+				this.rendererList.push(res);
+				return res;	
+			}
+			return null;
+		},
+		
+		_onRendererCreated: function(e){
+			if(e.source == this){
+				this.onRendererCreated(e);
+			}
+			if(this.owner != null){
+				this.owner._onRendererCreated(e);
+			}
+		},
+		
+		onRendererCreated: function(e){
+			// summary:
+			//		Event dispatched when an item renderer has been created.
+			// e: __rendererLifecycleEventArgs
+			//		The renderer lifecycle event.
+			// tags:
+			//		callback
+		},	
+		
+		_onRendererRecycled: function(e){
+			if(e.source == this){
+				this.onRendererRecycled(e);
+			}
+			if(this.owner != null){
+				this.owner._onRendererRecycled(e);
+			}
+		},
+		
+		onRendererRecycled: function(e){
+			// summary:
+			//		Event dispatched when an item renderer has been recycled.
+			// e: __rendererLifecycleEventArgs
+			//		The renderer lifecycle event.
+			// tags:
+			//		callback
+
+		},
+						
+		_onRendererReused: function(e){
+			if(e.source == this){
+				this.onRendererReused(e);
+			}
+			if(this.owner != null){
+				this.owner._onRendererReused(e);
+			}
+		},
+		
+		onRendererReused: function(e){
+			// summary:
+			//		Event dispatched when an item renderer that was recycled is reused.
+			// e: __rendererLifecycleEventArgs
+			//		The renderer lifecycle event.
+			// tags:
+			//		callback
+		},
+		
+		_onRendererDestroyed: function(e){
+			if(e.source == this){
+				this.onRendererDestroyed(e);
+			}
+			if(this.owner != null){
+				this.owner._onRendererDestroyed(e);
+			}
+		},
+		
+		onRendererDestroyed: function(e){
+			// summary:
+			//		Event dispatched when an item renderer is destroyed.
+			// e: __rendererLifecycleEventArgs
+			//		The renderer lifecycle event.
+			// tags:
+			//		callback
+		},
+				
+		_onRenderersLayoutDone: function(view){
+			// tags:
+			//		private
+
+			this.onRenderersLayoutDone(view);
+			if(this.owner != null){
+				this.owner._onRenderersLayoutDone(view);
+			}				
+		},
+									
+		onRenderersLayoutDone: function(view){
+			// summary:
+			//		Event triggered when item renderers layout has been done.
+			// tags:
+			//		callback
+		},
+
+		_recycleRenderer: function(renderer, remove){
+			// summary: 
+			//		Recycles the item renderer to be reused in the future.
+			// renderer: dojox/calendar/_RendererMixin
+			//		The item renderer to recycle.
+			// tags:
+			//		protected			
+								
+			this._onRendererRecycled({renderer:renderer, source:this});
+			
+			var pool = this.rendererPool[renderer.kind];
+			
+			if(pool == null){
+				this.rendererPool[renderer.kind] = [renderer];
+			}else{
+				pool.push(renderer);
+			}
+								
+			if(remove){
+				renderer.container.parentNode.removeChild(renderer.container);
+			}
+
+			domStyle.set(renderer.container, "display", "none");
+
+			renderer.renderer.owner = null;
+			renderer.renderer.set("item", null);
+		},
+							
+		_destroyRenderer: function(renderer){
+			// summary: 
+			//		Destroys the item renderer.
+			// renderer: dojox/calendar/_RendererMixin
+			//		The item renderer to destroy.
+			// tags:
+			//		protected
+			this._onRendererDestroyed({renderer:renderer, source:this});
+			
+			var ir = renderer.renderer;		
+			
+			if(ir["destroy"]){
+				ir.destroy();
+			}
+			
+			html.destroy(renderer.container);	
+		},
+		
+		_destroyRenderersByKind: function(kind){
+			// tags:
+			//		private
+
+			var list = [];
+			for(var i=0;i<this.rendererList.length;i++){
+				var ir = this.rendererList[i];
+				if(ir.kind == kind){
+					this._destroyRenderer(ir);
+				}else{
+					list.push(ir);
+				}
+			}
+			
+			this.rendererList = list;
+			
+			var pool = this.rendererPool[kind];
+			if(pool){
+				while(pool.length > 0){
+					this._destroyRenderer(pool.pop());
+				}
+			}
+			
+		},
+				
+					
+		_updateEditingCapabilities: function(item, renderer){
+			// summary:
+			//		Update the moveEnabled and resizeEnabled properties of a renderer according to its event current editing state.
+			// item: Object
+			//		The store data item.
+			// renderer: dojox/calendar/_RendererMixin
+			//		The item renderer.
+			// tags:
+			//		protected
+
+			var moveEnabled = this.isItemMoveEnabled(item, renderer.rendererKind);
+			var resizeEnabled = this.isItemResizeEnabled(item, renderer.rendererKind);
+			var changed = false;
+			
+			if(moveEnabled != renderer.get("moveEnabled")){
+				renderer.set("moveEnabled", moveEnabled);
+				changed = true;
+			}
+			if(resizeEnabled != renderer.get("resizeEnabled")){
+				renderer.set("resizeEnabled", resizeEnabled);
+				changed = true;
+			}
+			
+			if(changed){
+				renderer.updateRendering();
+			}
+		},
+	
+		updateRenderers: function(obj, stateOnly){
+			// summary:
+			//		Updates all the renderers that represents the specified item(s).
+			// obj: Object
+			//		A render item or an array of render items.
+			// stateOnly: Boolean
+			//		Whether only the state of the item has changed (selected, edited, edited, focused) or a more global change has occured.
+			// tags:
+			//		protected
+
+			if(obj == null){
+				return;
+			}
+			
+			var items = lang.isArray(obj) ? obj : [obj];
+			
+			for(var i=0; i<items.length; i++){
+				
+				var item = items[i];
+				
+				if(item == null || item.id == null){
+					continue;
+				}
+						
+				var list = this.itemToRenderer[item.id];
+				
+				if(list == null){
+					continue;
+				}
+				
+				var selected = this.isItemSelected(item);
+				var hovered = this.isItemHovered(item);
+				var edited = this.isItemBeingEdited(item);
+				var focused = this.showFocus ? this.isItemFocused(item) : false;				
+				
+				for(var j = 0; j < list.length; j++){
+					
+					var renderer = list[j].renderer;
+					renderer.set("hovered", hovered);
+					renderer.set("selected", selected);
+					renderer.set("edited", edited);
+					renderer.set("focused", focused);
+					renderer.set("storeState", this.getItemStoreState(item));
+					
+					this.applyRendererZIndex(item, list[j], hovered, selected, edited, focused);
+					
+					if(!stateOnly){
+						renderer.set("item", item); // force content refresh
+						if(renderer.updateRendering){
+							renderer.updateRendering(); // reuse previously set dimensions	
+						}
+					}
+				}
+				
+			}
+		},
+		
+		applyRendererZIndex: function(item, renderer, hovered, selected, edited, focused){
+			// summary:
+			//		Applies the z-index to the renderer based on the state of the item.
+			//		This methods is setting a z-index of 20 is the item is selected or edited 
+			//		and the current lane value computed by the overlap layout (i.e. the renderers 
+			//		are stacked according to their lane).
+			// item: Object
+			//		The render item.
+			// renderer: Object
+			//		A renderer associated with the render item.
+			// hovered: Boolean
+			//		Whether the item is hovered or not.
+			// selected: Boolean
+			//		Whether the item is selected or not.
+			// edited: Boolean
+			//		Whether the item is being edited not not.
+			// focused: Boolean
+			//		Whether the item is focused not not.
+			// tags:
+			//		protected
+						
+			domStyle.set(renderer.container, {"zIndex": edited || selected ? 20: item.lane == undefined ? 0 : item.lane});
+		},
+		
+		getIdentity: function(item){
+			return this.owner ? this.owner.getIdentity(item) : item.id; 
+		},		
+		
+		/////////////////////////////////////////////////////
+		//
+		// Hovered item
+		//
+		////////////////////////////////////////////////////
+
+		_setHoveredItem: function(item, renderer){
+			// summary:
+			//		Sets the current hovered item.
+			// item: Object
+			//		The data item.
+			// renderer: dojox/calendar/_RendererMixin
+			//		The item renderer.
+			// tags:
+			//		protected
+
+			if(this.owner){
+				this.owner._setHoveredItem(item, renderer);
+				return;
+			}
+			
+			if(this.hoveredItem && item && this.hoveredItem.id != item.id || 
+				item == null || this.hoveredItem == null){
+				var old = this.hoveredItem;
+				this.hoveredItem = item;
+				
+				this.updateRenderers([old, this.hoveredItem], true);
+				
+				if(item && renderer){
+					this._updateEditingCapabilities(item._item ? item._item : item, renderer);
+				}
+			}
+		},
+		
+		// hoveredItem: Object
+		//		The currently hovered data item.
+		hoveredItem: null,
+		
+		isItemHovered: function(item){
+			// summary:
+			//		Returns whether the specified item is hovered or not.
+			// item: Object
+			//		The item.
+			// returns: Boolean
+			if (this._isEditing && this._edProps){
+				return item.id == this._edProps.editedItem.id;
+			}
+			return this.owner ?  
+				this.owner.isItemHovered(item) : 
+				this.hoveredItem != null && this.hoveredItem.id == item.id;
+			
+		},
+		
+		isItemFocused: function(item){
+			// summary:
+			//		Returns whether the specified item is focused or not.
+			// item: Object
+			//		The item.
+			// returns: Boolean
+			return this._isItemFocused ? this._isItemFocused(item) : false;
+		},
+		
+		////////////////////////////////////////////////////////////////////
+		//
+		// Selection delegation
+		//
+		///////////////////////////////////////////////////////////////////
+		
+		_setSelectionModeAttr: function(value){
+			if(this.owner){
+				this.owner.set("selectionMode", value);
+			}else{
+				this.inherited(arguments);
+			}			
+		},					
+		
+		_getSelectionModeAttr: function(value){			
+			if(this.owner){
+				return this.owner.get("selectionMode");
+			}
+			return this.inherited(arguments);			
+		},
+		
+		_setSelectedItemAttr: function(value){			
+			if(this.owner){
+				this.owner.set("selectedItem", value);
+			}else{
+				this.inherited(arguments);
+			}
+		},
+		
+		_getSelectedItemAttr: function(value){			
+			if(this.owner){
+				return this.owner.get("selectedItem");
+			}
+			return this.selectedItem; // no getter on super class (dojox.widget.Selection)			
+		},
+		
+		_setSelectedItemsAttr: function(value){			
+			if(this.owner){
+				this.owner.set("selectedItems", value);
+			}else{
+				this.inherited(arguments);
+			}
+		},
+		
+		_getSelectedItemsAttr: function(){			
+			if(this.owner){
+				return this.owner.get("selectedItems");
+			}
+			return this.inherited(arguments);
+		},
+		
+		isItemSelected: function(item){			
+			if(this.owner){
+				return this.owner.isItemSelected(item);
+			}
+			return this.inherited(arguments);
+		},
+		
+		selectFromEvent: function(e, item, renderer, dispatch){			
+			if(this.owner){
+				this.owner.selectFromEvent(e, item, renderer, dispatch);
+			}else{
+				this.inherited(arguments);
+			}
+		},
+		
+		setItemSelected: function(item, value){
+			if(this.owner){
+				this.owner.setItemSelected(item, value);
+			}else{
+				this.inherited(arguments);
+			}
+		},
+		
+		////////////////////////////////////////////////////////////////////
+		//
+		// Event creation
+		//
+		///////////////////////////////////////////////////////////////////
+		
+		createItemFunc: null,
+		/*=====
+		createItemFunc: function(view, d, e){
+		 	// summary:
+			//		A user supplied function that creates a new event.
+			// view:
+			//		the current view,
+			// d:
+			//		the date at the clicked location.
+			// e:
+			//		the mouse event (can be used to return null for example)
+		},
+		=====*/
+
+				
+		_getCreateItemFuncAttr: function(){			
+			if(this.owner){
+				return this.owner.get("createItemFunc");
+			}
+			return this.createItemFunc;
+		},
+		
+		// createOnGridClick: Boolean
+		//		Indicates whether the user can create new event by clicking and dragging the grid.
+		//		A createItem function must be defined on the view or the calendar object.
+		createOnGridClick: false,
+		
+		_getCreateOnGridClickAttr: function(){
+			if(this.owner){
+				return this.owner.get("createOnGridClick");
+			}
+			return this.createOnGridClick;			
+		},
+		
+		////////////////////////////////////////////////////////////////////
+		//
+		// Event creation
+		//
+		///////////////////////////////////////////////////////////////////	
+		
+		_gridMouseDown: false,		
+				
+		_onGridMouseDown: function(e){
+			// tags:
+			//		private
+			this._gridMouseDown = true;
+								
+			this.showFocus = false;
+								
+			if(this._isEditing){	
+				this._endItemEditing("mouse", false);
+			}
+			
+			this._doEndItemEditing(this.owner, "mouse");			
+			
+			this.set("focusedItem", null);
+			this.selectFromEvent(e, null, null, true);
+			
+			if(this._setTabIndexAttr){
+				this[this._setTabIndexAttr].focus();
+			}
+								
+			if(this._onRendererHandleMouseDown){
+				
+				var f = this.get("createItemFunc");
+				
+				if(!f){
+					return;
+				}
+				
+				var newItem = this._createdEvent = f(this, this.getTime(e), e);
+								
+				var store = this.get("store");
+											
+				if(!newItem || store == null){
+					return;
+				}
+								
+				var newRenderItem = this.itemToRenderItem(newItem, store);
+				newRenderItem._item = newItem;
+				this._setItemStoreState(newItem, "unstored");
+				
+				// add the new temporary item to the displayed list and force view refresh
+				var owner = this._getTopOwner();
+				var items = owner.get("items");
+				
+				owner.set("items", items ? items.concat([newRenderItem]) : [newRenderItem]);
+								
+				this._refreshItemsRendering();
+				
+				// renderer created in _refreshItemsRenderering()
+				var renderers = this.getRenderers(newItem);				
+				if(renderers && renderers.length>0){
+					var renderer = renderers[0];					
+					if(renderer){
+						// trigger editing
+						this._onRendererHandleMouseDown(e, renderer.renderer, "resizeEnd");
+					}					
+				}
+			}
+		},
+		
+		_onGridMouseMove: function(e){
+			// tags:
+			//		private
+		},
+		
+		_onGridMouseUp: function(e){
+			// tags:
+			//		private
+		},
+		
+		_onGridTouchStart: function(e){
+			// tags:
+			//		private
+
+			var p = this._edProps;
+
+			this._gridProps = {
+				event: e,				
+				fromItem: this.isAscendantHasClass(e.target, this.eventContainer, "dojoxCalendarEventContainer")
+			};			
+	
+			if(this._isEditing){
+				
+				if(this._gridProps){
+					this._gridProps.editingOnStart = true;
+				}
+
+				lang.mixin(p, this._getTouchesOnRenderers(e, p.editedItem));
+				
+				if(p.touchesLen == 0){
+					
+					if(p && p.endEditingTimer){
+						clearTimeout(p.endEditingTimer);
+						p.endEditingTimer = null;
+					}
+					this._endItemEditing("touch", false);
+				}
+			}
+			
+			this._doEndItemEditing(this.owner, "touch");		
+
+			event.stop(e);
+			
+		},
+		
+		_doEndItemEditing: function(obj, eventSource){
+			// tags:
+			//		private
+
+			if(obj && obj._isEditing){
+				var p = obj._edProps;
+				if(p && p.endEditingTimer){
+					clearTimeout(p.endEditingTimer);
+					p.endEditingTimer = null;
+				}
+				obj._endItemEditing(eventSource, false);
+			}	
+		},
+					
+		_onGridTouchEnd: function(e){
+			// tags:
+			//		private
+		},
+		
+		_onGridTouchMove: function(e){
+			// tags:
+			//		private
+		},
+		
+		__fixEvt: function(e){
+			// summary:
+			//		Extension point for a view to add some event properties to a calendar event.
+			// tags:
+			//		callback
+			return e;
+		},
+		
+		_dispatchCalendarEvt: function(e, name){
+			// summary:
+			//		Adds view properties to event and enable bubbling at owner level.
+			// e: Event
+			//		The dispatched event.
+			// name: String
+			//		The event name.
+			// tags:
+			//		protected
+			
+			e = this.__fixEvt(e);
+			this[name](e);
+			if(this.owner){
+				this.owner[name](e);
+			}
+			return e;
+		},
+
+		_onGridClick: function(e){
+			// tags:
+			//		private
+			if(!e.triggerEvent){
+				e = {
+					date: this.getTime(e),
+					triggerEvent: e
+				};
+			}	
+			
+			this._dispatchCalendarEvt(e, "onGridClick");
+		},
+		
+		onGridClick: function(e){
+			// summary:
+			//		Event dispatched when the grid has been clicked.
+			// e: __GridClickEventArgs
+			//		The event dispatched when the grid is clicked.
+			// tags:
+			//		callback
+		},
+		
+		_onGridDoubleClick: function(e){
+			// tags:
+			//		private
+
+			if(!e.triggerEvent){
+				e = {
+					date: this.getTime(e),
+					triggerEvent: e
+				};
+			}
+						
+			this._dispatchCalendarEvt(e, "onGridDoubleClick");
+		},
+				
+		onGridDoubleClick: function(e){
+			// summary:
+			//		Event dispatched when the grid has been double-clicked.
+			// e: __GridClickEventArgs
+			//		The event dispatched when the grid is double-clicked.
+			// tags:
+			//		protected
+
+		},
+		
+		_onItemClick: function(e){
+			// tags:
+			//		private
+
+			this._dispatchCalendarEvt(e, "onItemClick");
+		},
+		
+		onItemClick: function(e){
+			// summary:
+			//		Event dispatched when an item renderer has been clicked.
+			// e: __ItemMouseEventArgs
+			//		The event dispatched when an item is clicked.
+			// tags:
+			//		callback
+
+		},
+		
+		_onItemDoubleClick: function(e){
+			// tags:
+			//		private
+
+			this._dispatchCalendarEvt(e, "onItemDoubleClick");	
+		},
+		
+		onItemDoubleClick: function(e){
+			// summary:
+			//		Event dispatched when an item renderer has been double-clicked.
+			// e: __ItemMouseEventArgs
+			//		The event dispatched when an item is double-clicked.
+			// tags:
+			//		callback
+
+		},
+
+		_onItemContextMenu: function(e){
+			this._dispatchCalendarEvt(e, "onItemContextMenu");
+			// tags:
+			//		private
+
+		},
+		
+		onItemContextMenu: function(e){
+			// summary:
+			//		Event dispatched when an item renderer has been context-clicked.
+			// e: __ItemMouseEventArgs
+			//		The event dispatched when an item is context-clicked.
+			// tags:
+			//		callback
+
+		},
+		
+		//////////////////////////////////////////////////////////
+		//
+		//	Editing
+		//
+		//////////////////////////////////////////////////////////
+
+		_getStartEndRenderers: function(item){
+			// summary:
+			//		Returns an array that contains the first and last renderers of an item 			
+			//		that are currently displayed. They could be the same renderer if only one renderer is used.
+			// item: Object
+			//		The render item.
+			// returns: Object[]
+			// tags:
+			//		protected
+
+
+			var list = this.itemToRenderer[item.id];
+
+			if(list == null){
+				return null;
+			}
+
+			// trivial and most common use case.
+			if(list.length == 1){
+				var node = list[0].renderer;
+				return [node, node];
+			}
+
+			var rd = this.renderData;
+			var resizeStartFound = false;
+			var resizeEndFound = false;
+
+			var res = [];
+
+			for(var i=0; i<list.length; i++){
+
+				var ir = list[i].renderer;
+
+				if (!resizeStartFound){
+					resizeStartFound = rd.dateModule.compare(ir.item.range[0], ir.item.startTime) == 0;
+					res[0] = ir;
+				}
+
+				if (!resizeEndFound){
+					resizeEndFound =  rd.dateModule.compare(ir.item.range[1], ir.item.endTime) == 0;
+					res[1] = ir;
+				}
+
+				if (resizeStartFound && resizeEndFound){
+					break;	
+				}
+			}
+
+			return res;			
+		},
+								
+		// editable: Boolean
+		//		A flag that indicates whether or not the user can edit
+		//		items in the data provider.
+		//		If <code>true</code>, the item renderers in the control are editable.
+		//		The user can click on an item renderer, or use the keyboard or touch devices, to move or resize the associated event.
+		editable: true,
+
+		// moveEnabled: Boolean
+		//		A flag that indicates whether the user can move items displayed.
+		//		If <code>true</code>, the user can move the items.
+		moveEnabled: true,
+
+		// resizeEnabled: Boolean
+		//		A flag that indicates whether the items can be resized.
+		//		If `true`, the control supports resizing of items.
+		resizeEnabled: true,
+		
+		isItemEditable: function(item, rendererKind){
+			// summary:
+			//		Computes whether particular item renderer can be edited or not.
+			//		By default it is using the editable property value.
+			// item: Object
+			//		The item represented by the renderer.
+			// rendererKind: String
+			//		The kind of renderer.
+			// returns: Boolean			
+			return this.getItemStoreState(item) != "storing" && this.editable && (this.owner ? this.owner.isItemEditable(item, rendererKind) : true);
+		},
+
+		isItemMoveEnabled: function(item, rendererKind){
+			// summary:
+			//		Computes whether particular item renderer can be moved.
+			//		By default it is using the moveEnabled property value.
+			// item: Object
+			//		The item represented by the renderer.
+			// rendererKind: String
+			//		The kind of renderer.
+			// returns: Boolean
+			return this.isItemEditable(item, rendererKind) && this.moveEnabled && 
+				(this.owner ? this.owner.isItemMoveEnabled(item, rendererKind): true);
+		},
+		
+		isItemResizeEnabled: function(item, rendererKind){
+			// summary:
+			//		Computes whether particular item renderer can be resized.
+			//		By default it is using the resizedEnabled property value.
+			// item: Object
+			//		The item represented by the renderer.
+			// rendererKind: String
+			//		The kind of renderer.
+			// returns: Boolean
+			
+			return this.isItemEditable(item, rendererKind) && this.resizeEnabled && 
+				(this.owner ? this.owner.isItemResizeEnabled(item, rendererKind): true);
+		},
+
+		// _isEditing: Boolean
+		//		Whether an item is being edited or not.
+		_isEditing: false,
+		
+		isItemBeingEdited: function(item){
+			// summary:
+			//		Returns whether an item is being edited or not.
+			// item: Object
+			//		The item to test.
+			// returns: Boolean
+			return this._isEditing && this._edProps && this._edProps.editedItem && this._edProps.editedItem.id == item.id;
+		},
+		
+		_setEditingProperties: function(props){
+			// summary:
+			//		Registers the editing properties used by the editing functions.
+			//		This method should only be called by editing interaction mixins like Mouse, Keyboard and Touch.
+			// tags:
+			//		protected
+
+			this._edProps = props;
+		},
+		
+		_startItemEditing: function(item, eventSource){
+			// summary:
+			//		Configures the component, renderers to start one (mouse) of several (touch, keyboard) editing gestures.
+			// item: Object
+			//		The item that will be edited.
+			// eventSource: String
+			//		"mouse", "keyboard", "touch"
+			// tags:
+			//		protected
+
+			this._isEditing = true;
+			this._getTopOwner()._isEditing = true;
+			var p = this._edProps;
+			
+			p.editedItem = item;
+			p.storeItem = this.renderItemToItem(item, this.get("store"));
+			p.eventSource = eventSource;
+			
+			p.secItem = this._secondarySheet ? this._findRenderItem(item.id, this._secondarySheet.renderData.items) : null;
+			p.ownerItem = this.owner ? this._findRenderItem(item.id, this.items) : null;
+						
+			if (!p.liveLayout){
+				p.editSaveStartTime = item.startTime;
+				p.editSaveEndTime = item.endTime;
+				
+				p.editItemToRenderer = this.itemToRenderer;
+				p.editItems = this.renderData.items;
+				p.editRendererList = this.rendererList;
+				
+				this.renderData.items = [p.editedItem];
+				var id = p.editedItem.id;
+			
+				this.itemToRenderer = {};
+				this.rendererList = [];
+				var list = p.editItemToRenderer[id];
+				
+				p.editRendererIndices = [];
+				
+				arr.forEach(list, lang.hitch(this, function(ir, i){
+					if(this.itemToRenderer[id] == null){
+						this.itemToRenderer[id] = [ir];
+					}else{
+						this.itemToRenderer[id].push(ir);
+					}
+					this.rendererList.push(ir);
+				}));
+				
+				// remove in old map & list the occurrence used by the edited item
+				p.editRendererList = arr.filter(p.editRendererList, function(ir){
+					return ir != null && ir.renderer.item.id != id;
+				});
+				delete p.editItemToRenderer[id];
+			}
+			
+			// graphic feedback refresh
+			this._layoutRenderers(this.renderData);
+			
+			this._onItemEditBegin({
+				item: item,
+				storeItem: p.storeItem,
+				eventSource: eventSource
+			});
+		},
+		
+		_onItemEditBegin: function(e){
+			// tags:
+			//		private
+
+			this._editStartTimeSave = this.newDate(e.item.startTime);
+			this._editEndTimeSave = this.newDate(e.item.endTime);
+			
+			this._dispatchCalendarEvt(e, "onItemEditBegin");
+		},
+		
+		onItemEditBegin: function(e){
+			// summary:
+			//		Event dispatched when the item is entering the editing mode.
+			// tags:
+			//		callback
+
+		},
+		
+		_endItemEditing: function(/*String*/eventSource, /*Boolean*/canceled){
+			// summary:
+			//		Leaves the item editing mode.
+			// item: Object
+			//		The item that was edited.
+			// eventSource: String
+			//		"mouse", "keyboard", "touch"
+			// tags:
+			//		protected
+
+			this._isEditing = false;
+			this._getTopOwner()._isEditing = false;
+			
+			var p = this._edProps;
+			
+			arr.forEach(p.handles, function(handle){
+				handle.remove();
+			});					
+						
+			if (!p.liveLayout){
+				this.renderData.items = p.editItems;
+				this.rendererList = p.editRendererList.concat(this.rendererList);
+				lang.mixin(this.itemToRenderer, p.editItemToRenderer);
+			}
+
+			this._onItemEditEnd(lang.mixin(this._createItemEditEvent(), {
+				item: p.editedItem,
+				storeItem: p.storeItem,
+				eventSource: eventSource,
+				completed: !canceled
+			}));
+			
+			this._layoutRenderers(this.renderData);				
+			
+			this._edProps = null;
+		},
+		
+		_onItemEditEnd: function(e){
+			// tags:
+			//		private
+								
+			this._dispatchCalendarEvt(e, "onItemEditEnd");
+			
+			if(!e.isDefaultPrevented()){
+				
+				var store = this.get("store");
+				
+				// updated store item
+				var storeItem = this.renderItemToItem(e.item, store);
+				
+				var s = this._getItemStoreStateObj(e.item);
+				
+				if(s != null && s.state == "unstored"){
+														
+					if(e.completed){
+						// renderItemToItem cannot find the original data item
+						// (as it does not exist in the store yet) to mixin with.
+						// so we must do it here.
+						storeItem = lang.mixin(s.item, storeItem);
+						this._setItemStoreState(storeItem, "storing");
+						
+						// add to the store.
+						store.add(storeItem);
+						
+					}else{ // creation canceled
+						// cleanup items list
+						var owner = this._getTopOwner();
+						var items = owner.get("items");
+						var l = items.length; 
+						for(var i=l-1; i>=0; i--){
+							if(items[i].id == s.id){
+								items.splice(i, 1);
+								break;
+							}
+						}
+						this._setItemStoreState(storeItem, null);
+						owner.set("items", items);						
+					}									
+					
+				} else if(e.completed){
+					// Inject new properties in data store item				
+					// and apply data changes		
+					this._setItemStoreState(storeItem, "storing");
+					store.put(storeItem);								
+				}else{
+					e.item.startTime = this._editStartTimeSave; 
+					e.item.endTime = this._editEndTimeSave;
+				}
+			}
+		},
+		
+		onItemEditEnd: function(e){
+			// summary:
+			//		Event dispatched when the item is leaving the editing mode.
+			// tags:
+			//		protected
+
+		},
+		
+		_createItemEditEvent: function(){
+			// tags:
+			//		private
+
+			var e = {
+				cancelable: true,
+				bubbles: false,
+				__defaultPrevent: false
+			};
+			
+			e.preventDefault = function(){
+				this.__defaultPrevented = true;
+			};
+			
+			e.isDefaultPrevented = function(){
+				return this.__defaultPrevented;
+			};
+			
+			return e;
+		},
+
+		
+		_startItemEditingGesture: function(dates, editKind, eventSource, e){
+			// summary:
+			//		Starts the editing gesture.
+			// date: Date[]
+			//		The reference dates (at least one). 
+			// editKind: String
+			//		Kind of edit: "resizeBoth", "resizeStart", "resizeEnd" or "move".
+			// eventSource: String
+			//		"mouse", "keyboard", "touch"
+			// e: Event
+			//		The event at the origin of the editing gesture.
+			// tags:
+			//		protected
+			
+			var p = this._edProps;
+			
+			if(!p || p.editedItem == null){
+				return;
+			}
+			
+			this._editingGesture = true;
+			
+			var item = p.editedItem;
+			
+			p.editKind = editKind; 
+			
+			this._onItemEditBeginGesture(this.__fixEvt(lang.mixin(this._createItemEditEvent(), {
+				item: item,
+				storeItem: p.storeItem,
+				startTime: item.startTime,
+				endTime: item.endTime,
+				editKind: editKind,
+				rendererKind: p.rendererKind,
+				triggerEvent: e,
+				dates: dates,
+				eventSource: eventSource
+			})));
+			
+			p.itemBeginDispatched = true;
+
+		},
+		
+		
+		_onItemEditBeginGesture: function(e){
+			// tags:
+			//		private
+			var p = this._edProps;
+			
+			var item = p.editedItem;
+			var dates = e.dates;
+			
+			p.editingTimeFrom = [];			
+			p.editingTimeFrom[0] = dates[0];			
+			
+			p.editingItemRefTime = [];
+			p.editingItemRefTime[0] = this.newDate(p.editKind == "resizeEnd" ? item.endTime : item.startTime);
+			
+			if (p.editKind == "resizeBoth"){
+				p.editingTimeFrom[1] = dates[1];
+				p.editingItemRefTime[1] = this.newDate(item.endTime);				
+			}		
+			
+			var cal = this.renderData.dateModule;
+			
+			p.inViewOnce = this._isItemInView(item);
+			
+			if(p.rendererKind == "label" || this.roundToDay){
+				p._itemEditBeginSave = this.newDate(item.startTime);
+				p._itemEditEndSave = this.newDate(item.endTime);
+			}
+			
+			p._initDuration = cal.difference(item.startTime, item.endTime, item.allDay?"day":"millisecond");	
+			
+			this._dispatchCalendarEvt(e, "onItemEditBeginGesture");
+
+			if (!e.isDefaultPrevented()){
+				
+				if (e.eventSource == "mouse"){
+					var cursor = e.editKind=="move"?"move":this.resizeCursor;
+					p.editLayer = domConstruct.create("div", {
+						style: "position: absolute; left:0; right:0; bottom:0; top:0; z-index:30; tabIndex:-1; background-image:url('"+this._blankGif+"'); cursor: "+cursor,
+						onresizestart: function(e){return false;},
+						onselectstart: function(e){return false;}
+					}, this.domNode);
+					p.editLayer.focus();
+				}
+			}
+		},
+		
+		onItemEditBeginGesture: function(e){
+			// summary:
+			//		Event dispatched when an editing gesture is beginning.
+			// e: __itemEditingEventArgs
+			//		The editing event.
+			// tags:
+			//		callback
+
+		},
+		
+		_waDojoxAddIssue: function(d, unit, steps){
+			// summary:
+			//		Workaround an issue of dojox.date.XXXXX.date.add() function 
+			//		that does not support the subtraction of time correctly (normalization issues). 
+			// d: Date
+			//		Reference date.
+			// unit: String
+			//		Unit to add.
+			// steps: Integer
+			//		Number of units to add.
+			// tags:
+			//		protected
+
+			var cal = this.renderData.dateModule;
+			if(this._calendar != "gregorian" && steps < 0){
+				var gd = d.toGregorian();
+				gd = date.add(gd, unit, steps);
+				return new this.renderData.dateClassObj(gd);
+			}else{
+				return cal.add(d, unit, steps);
+			}
+		},
+						
+		_computeItemEditingTimes: function(item, editKind, rendererKind, times, eventSource){
+			// tags:
+			//		private
+
+			var cal = this.renderData.dateModule;
+			var p = this._edProps;
+			var diff = cal.difference(p.editingTimeFrom[0], times[0], "millisecond");
+			times[0] = this._waDojoxAddIssue(p.editingItemRefTime[0], "millisecond", diff);
+			
+			if(editKind == "resizeBoth"){
+				diff = cal.difference(p.editingTimeFrom[1], times[1], "millisecond");
+				times[1] = this._waDojoxAddIssue(p.editingItemRefTime[1], "millisecond", diff); 
+			}
+			return times;
+		},
+		
+		_moveOrResizeItemGesture: function(dates, eventSource, e){
+			// summary:
+			//		Moves or resizes an item.
+			// dates: Date[]
+			//		The reference dates.
+			// editKind: String
+			//		Kind of edit: "resizeStart", "resizeEnd", "resizeBoth" or "move".
+			// eventSource: String
+			//		"mouse", "keyboard", "touch"
+			// e: Event
+			//		The event at the origin of the editing gesture.
+			// tags:
+			//		private
+
+			if(!this._isEditing || dates[0] == null){
+				return;
+			}
+			
+			var p = this._edProps;
+			var item = p.editedItem;
+			var rd = this.renderData;
+			var cal = rd.dateModule;
+			var editKind = p.editKind;
+					
+			var newTimes = [dates[0]];
+			
+			if(editKind == "resizeBoth"){
+				newTimes[1] = dates[1];
+			}
+			
+			newTimes = this._computeItemEditingTimes(item, p.editKind, p.rendererKind, newTimes, eventSource);
+							
+			var newTime = newTimes[0]; // usual use case
+					
+			var moveOrResizeDone = false;
+			
+			var oldStart = lang.clone(item.startTime);
+			var oldEnd = lang.clone(item.endTime);
+			
+			// swap cannot used using keyboard as a gesture is made of one single change (loss of start/end context).
+			var allowSwap = p.eventSource == "keyboard" ? false : this.allowStartEndSwap;
+
+			// Update the Calendar with the edited value.
+			if(editKind == "move"){
+					
+				if(cal.compare(item.startTime, newTime) != 0){
+					var duration = cal.difference(item.startTime, item.endTime, "millisecond");
+					item.startTime = this.newDate(newTime);
+					item.endTime = cal.add(item.startTime, "millisecond", duration);
+					moveOrResizeDone = true;
+				}
+				
+			}else if(editKind == "resizeStart"){
+				
+				if(cal.compare(item.startTime, newTime) != 0){	
+					if(cal.compare(item.endTime, newTime) != -1){				
+						item.startTime = this.newDate(newTime);
+					}else{ // swap detected
+						if(allowSwap){
+							item.startTime = this.newDate(item.endTime);
+							item.endTime = this.newDate(newTime);	
+							p.editKind = editKind = "resizeEnd";
+							if(eventSource == "touch"){ // invert touches as well!
+								p.resizeEndTouchIndex = p.resizeStartTouchIndex;
+								p.resizeStartTouchIndex = -1;
+							}	
+						}else{ // block the swap but keep the time of day
+							item.startTime = this.newDate(item.endTime);
+							item.startTime.setHours(newTime.getHours());
+							item.startTime.setMinutes(newTime.getMinutes());
+							item.startTime.setSeconds(newTime.getSeconds());
+						}
+					}
+					moveOrResizeDone = true;
+				}
+				
+			}else if(editKind == "resizeEnd"){
+				
+				if(cal.compare(item.endTime, newTime) != 0){
+					if(cal.compare(item.startTime, newTime) != 1){
+						item.endTime = this.newDate(newTime);	
+					}else{ // swap detected
+
+						if(allowSwap){
+							item.endTime = this.newDate(item.startTime);
+							item.startTime = this.newDate(newTime);	
+							p.editKind = editKind = "resizeStart";
+							if(eventSource == "touch"){ // invert touches as well!
+								p.resizeStartTouchIndex = p.resizeEndTouchIndex;
+								p.resizeEndTouchIndex = -1;
+							}
+						}else{ // block the swap but keep the time of day
+							item.endTime = this.newDate(item.startTime);
+							item.endTime.setHours(newTime.getHours());
+							item.endTime.setMinutes(newTime.getMinutes());
+							item.endTime.setSeconds(newTime.getSeconds());	
+						}
+					}
+
+					moveOrResizeDone = true;
+				}
+			}else if(editKind == "resizeBoth"){
+				
+					moveOrResizeDone = true;
+
+					var start =  this.newDate(newTime);
+					var end = this.newDate(newTimes[1]);		
+
+					if(cal.compare(start, end) != -1){ // swap detected
+						if(allowSwap){
+							var t = start;
+							start = end;
+							end = t;
+						}else{ // as both ends are moved, the simple way is to forbid the move gesture.
+							moveOrResizeDone = false;
+						}
+					}
+
+					if(moveOrResizeDone){
+						item.startTime = start;
+						item.endTime = end; 
+					}
+
+			}else{	
+				return false;
+			}
+
+			if(!moveOrResizeDone){
+				return false;
+			}
+
+			var evt = lang.mixin(this._createItemEditEvent(), {
+				item: item,
+				storeItem: p.storeItem,
+				startTime: item.startTime,
+				endTime: item.endTime,
+				editKind: editKind,
+				rendererKind: p.rendererKind,
+				triggerEvent: e,
+				eventSource: eventSource
+			}); 
+			
+			// trigger snapping, rounding, minimal duration, boundaries checks etc.
+			if(editKind == "move"){
+				this._onItemEditMoveGesture(evt);
+			}else{
+				this._onItemEditResizeGesture(evt);
+			}
+			
+			// prevent invalid range
+			if(cal.compare(item.startTime, item.endTime) == 1){
+				var tmp = item.startTime;
+				item.startTime = item.endTime;
+				item.endTime = tmp;
+			}
+			
+			moveOrResizeDone = 
+				cal.compare(oldStart, item.startTime) != 0 || 
+				cal.compare(oldEnd, item.endTime) != 0;
+			
+			if(!moveOrResizeDone){
+				return false;
+			}
+
+			this._layoutRenderers(this.renderData);	
+
+			if(p.liveLayout && p.secItem != null){
+				p.secItem.startTime = item.startTime;
+				p.secItem.endTime = item.endTime;
+				this._secondarySheet._layoutRenderers(this._secondarySheet.renderData);
+			}else if(p.ownerItem != null && this.owner.liveLayout){
+				p.ownerItem.startTime = item.startTime;
+				p.ownerItem.endTime = item.endTime;
+				this.owner._layoutRenderers(this.owner.renderData);
+			}
+												
+			return true;
+		},
+		
+		_findRenderItem: function(id, list){
+			// tags:
+			//		private
+
+			list = list || this.renderData.items;
+			for(var i=0; i<list.length; i++){
+				if(list[i].id == id){
+					return list[i];
+				}
+			}
+			return null;
+		},
+
+		_onItemEditMoveGesture: function(e){	
+			// tags:
+			//		private
+
+			this._dispatchCalendarEvt(e, "onItemEditMoveGesture");
+
+			if(!e.isDefaultPrevented()){
+				
+				var p = e.source._edProps;
+				var rd = this.renderData;
+				var cal = rd.dateModule;
+				var newStartTime, newEndTime;
+				
+				if(p.rendererKind == "label" || (this.roundToDay && !e.item.allDay)){
+					
+					newStartTime = this.floorToDay(e.item.startTime, false, rd);
+					newStartTime.setHours(p._itemEditBeginSave.getHours());
+					newStartTime.setMinutes(p._itemEditBeginSave.getMinutes());
+					
+					newEndTime = cal.add(newStartTime, "millisecond", p._initDuration);
+					
+				}else if(e.item.allDay){
+					newStartTime = this.floorToDay(e.item.startTime, true);
+					newEndTime = cal.add(newStartTime, "day", p._initDuration);
+				}else{
+					newStartTime = this.floorDate(e.item.startTime, this.snapUnit, this.snapSteps);
+					newEndTime = cal.add(newStartTime, "millisecond", p._initDuration);
+				} 
+
+				e.item.startTime = newStartTime;
+				e.item.endTime = newEndTime;
+				
+				if(!p.inViewOnce){
+					p.inViewOnce = this._isItemInView(e.item);
+				}
+
+				// to prevent strange behaviors use constraint in items already fully in view.
+				if(p.inViewOnce && this.stayInView){
+					this._ensureItemInView(e.item);
+				}
+			}
+		},
+		
+		_DAY_IN_MILLISECONDS: 24 * 60 * 60 * 1000,
+		
+		onItemEditMoveGesture: function(e){
+			// summary:
+			//		Event dispatched during a move editing gesture.
+			// e: __itemEditingEventArgs
+			//		The editing event.
+			// tags:
+			//		callback
+
+		},
+				
+		_onItemEditResizeGesture: function(e){
+			// tags:
+			//		private
+
+			this._dispatchCalendarEvt(e, "onItemEditResizeGesture");
+			
+			if(!e.isDefaultPrevented()){				
+							
+				var p = e.source._edProps;
+				var rd = this.renderData;
+				var cal = rd.dateModule;
+				
+				var newStartTime = e.item.startTime;
+				var newEndTime = e.item.endTime;
+				
+				if(e.editKind == "resizeStart"){
+					if(e.item.allDay){
+						newStartTime = this.floorToDay(e.item.startTime, false, this.renderData);
+					}else if(this.roundToDay){
+						newStartTime = this.floorToDay(e.item.startTime, false, rd);
+						newStartTime.setHours(p._itemEditBeginSave.getHours());
+						newStartTime.setMinutes(p._itemEditBeginSave.getMinutes());
+					}else{
+						newStartTime = this.floorDate(e.item.startTime, this.snapUnit, this.snapSteps);
+					}
+				}else if(e.editKind == "resizeEnd"){
+					if(e.item.allDay){
+						if(!this.isStartOfDay(e.item.endTime)){
+							newEndTime = this.floorToDay(e.item.endTime, false, this.renderData);
+							newEndTime = cal.add(newEndTime, "day", 1);
+						}
+					}else if(this.roundToDay){
+						newEndTime = this.floorToDay(e.item.endTime, false, rd);
+						newEndTime.setHours(p._itemEditEndSave.getHours());
+						newEndTime.setMinutes(p._itemEditEndSave.getMinutes());
+					}else{
+						newEndTime = this.floorDate(e.item.endTime, this.snapUnit, this.snapSteps);
+					
+						if(e.eventSource == "mouse"){
+							newEndTime = cal.add(newEndTime, this.snapUnit, this.snapSteps);
+						}
+					}
+				}else{ // Resize both
+					newStartTime = this.floorDate(e.item.startTime, this.snapUnit, this.snapSteps);
+					newEndTime = this.floorDate(e.item.endTime, this.snapUnit, this.snapSteps);
+					newEndTime = cal.add(newEndTime, this.snapUnit, this.snapSteps);
+				}
+				
+				e.item.startTime = newStartTime;
+				e.item.endTime = newEndTime;
+				
+				var minimalDay = e.item.allDay || p._initDuration >= this._DAY_IN_MILLISECONDS && !this.allowResizeLessThan24H;
+				
+				this.ensureMinimalDuration(this.renderData, e.item, 
+					minimalDay ? "day" : this.minDurationUnit, 
+					minimalDay ? 1 : this.minDurationSteps, 
+					e.editKind);
+					
+				if(!p.inViewOnce){
+					p.inViewOnce = this._isItemInView(e.item);
+				}
+
+				// to prevent strange behaviors use constraint in items already fully in view.
+				if(p.inViewOnce && this.stayInView){
+					this._ensureItemInView(e.item);
+				}
+			}
+		},
+		
+		onItemEditResizeGesture: function(e){
+			// summary:
+			//		Event dispatched during a resize editing gesture.
+			// e: __itemEditingEventArgs
+			//		The editing event.
+			// tags:
+			//		callback
+
+		},
+		
+		_endItemEditingGesture: function(/*String*/eventSource,	/*Event*/e){
+			// tags:
+			//		protected
+
+			if(!this._isEditing){
+				return;
+			}					
+			
+			this._editingGesture = false;
+			
+			var p = this._edProps;
+			var item = p.editedItem;
+			
+			p.itemBeginDispatched = false;							
+			
+			this._onItemEditEndGesture(lang.mixin(this._createItemEditEvent(), {
+				item: item,
+				storeItem: p.storeItem,
+				startTime: item.startTime,
+				endTime: item.endTime,
+				editKind: p.editKind,
+				rendererKind: p.rendererKind,
+				triggerEvent: e,
+				eventSource: eventSource
+			}));
+
+		},
+		
+		_onItemEditEndGesture: function(e){
+			// tags:
+			//		private
+
+			var p = this._edProps;
+			
+			delete p._itemEditBeginSave;
+			delete p._itemEditEndSave;
+					
+			this._dispatchCalendarEvt(e, "onItemEditEndGesture");
+			
+			if (!e.isDefaultPrevented()){
+				if(p.editLayer){
+					if(has("ie")){
+						p.editLayer.style.cursor = "default";
+					}
+					setTimeout(lang.hitch(this, function(){
+						if(this.domNode){ // for unit tests					
+							this.domNode.focus();
+							p.editLayer.parentNode.removeChild(p.editLayer);
+							p.editLayer = null;
+						}		
+					}), 10);
+								
+				}
+			}
+		},
+		
+		onItemEditEndGesture: function(e){
+			// summary:
+			//		Event dispatched at the end of an editing gesture.
+			// e: __itemEditingEventArgs
+			//		The editing event.
+			// tags:
+			//		callback
+
+		},
+		
+		ensureMinimalDuration: function(renderData, item, unit, steps, editKind){
+			// summary:
+			//		During the resize editing gesture, ensures that the item has the specified minimal duration.
+			// renderData: Object
+			//		The render data.
+			// item: Object
+			//		The edited item.
+			// unit: String
+			//		The unit used to define the minimal duration.
+			// steps: Integer
+			//		The number of time units.
+			// editKind: String
+			//		The edit kind: "resizeStart" or "resizeEnd".
+			var minTime;
+			var cal = renderData.dateModule;
+			
+			if(editKind == "resizeStart"){
+				minTime = cal.add(item.endTime, unit, -steps);
+				if(cal.compare(item.startTime, minTime) == 1){
+					item.startTime = minTime;
+				}
+			} else {
+				minTime = cal.add(item.startTime, unit, steps);
+				if(cal.compare(item.endTime, minTime) == -1){
+					item.endTime = minTime;
+				}
+			}
+		},
+		
+		// doubleTapDelay: Integer
+		//		The maximum delay between two taps needed to trigger an "itemDoubleClick" event, in touch context.		
+		doubleTapDelay: 300,
+		
+		// snapUnit: String
+		//		The unit of the snapping to apply during the editing of an event.
+		//		"day", "hour" and "minute" are valid values. 
+		snapUnit: "minute",
+		
+		// snapSteps: Integer
+		//		The number of units used to compute the snapping of the edited item.
+		snapSteps: 15,
+		
+		// minDurationUnit: "String"
+		//		The unit used to define the minimal duration of the edited item.
+		//		"day", "hour" and "minute" are valid values.
+		minDurationUnit: "hour",
+		
+		// minDurationSteps: Integer
+		//		The number of units used to define the minimal duration of the edited item.
+		minDurationSteps: 1,
+		
+		// liveLayout: Boolean
+		//		If true, all the events are laid out during the editing gesture. If false, only the edited event is laid out.
+		liveLayout: false,			
+		
+		// stayInView: Boolean
+		//		Specifies during editing, if the item is already in view, if the item must stay in the time range defined by the view or not.		
+		stayInView: true,
+		
+		// allowStartEndSwap: Boolean
+		//		Specifies if the start and end time of an item can be swapped during an editing gesture. Note that using the keyboard this property is ignored.	
+		allowStartEndSwap: true,			
+		
+		// allowResizeLessThan24H: Boolean
+		//		If an event has a duration greater than 24 hours, indicates if using a resize gesture, it can be resized to last less than 24 hours.
+		//		This flag is usually used when two different kind of renderers are used (MatrixView) to prevent changing the kind of renderer during an editing gesture.
+		allowResizeLessThan24H: false
+		
+	});
+});
diff --git a/dojox/calendar/_RendererMixin.js b/dojox/calendar/_RendererMixin.js
new file mode 100644
index 0000000..a073fda
--- /dev/null
+++ b/dojox/calendar/_RendererMixin.js
@@ -0,0 +1,307 @@
+define(["dojo/_base/declare", "dojo/_base/lang", "dojo/dom-style", "dojo/dom-class", "dojo/Stateful"],
+	 
+	function(declare, lang, domStyle, domClass, Stateful){
+	
+	return declare("dojox.calendar._RendererMixin", Stateful, {
+		
+		// summary:
+		//		This class is the base class of calendar renderers.
+		
+		// item: Object
+		//		The layout item displayed by this renderer.
+		item: null,
+		
+		// owner: dojox/calendar/_ViewBase
+		//		The view that contains this renderer.
+		owner: null,
+		
+		// edited: Boolean
+		//		Indicates that the item displayed by this renderer is in editing mode.
+		edited: false,
+		
+		// focused: Boolean
+		//		Indicates that the item displayed by this renderer is focused.
+		focused: false,
+		
+		// hovered: Boolean
+		//		Indicates that the item displayed by this renderer is hovered.
+		hovered: false,
+		
+		// selected: Boolean
+		//		Indicates that the item displayed by this renderer is selected.
+		selected: false,
+		
+		// storeState: Boolean
+		//		Indicates that the item displayed by this renderer is not in the store, being saved to the store or in the store.
+		storeState: false,
+		
+		// moveEnabled: Boolean
+		//		Whether the event displayed by this renderer can be moved.
+		moveEnabled: true,
+		
+		// resizeEnabled: Boolean
+		//		Whether the event displayed by this renderer can be resized.
+		resizeEnabled: true,
+		
+		_orientation: "vertical",
+		_displayValue: "block",		
+		
+		_displayValueMap: {},
+		
+		visibilityLimits: {
+			resizeStartHandle: 50,
+			resizeEndHandle: -1,
+			summaryLabel: 15,
+			startTimeLabel: 45,
+			endTimeLabel: 50
+		},		
+		
+		_setSelectedAttr: function(value){			
+			this._setState("selected", value, "Selected");
+		},
+		
+		_setFocusedAttr: function(value){
+			this._setState("focused", value, "Focused");
+		},
+
+		_setEditedAttr: function(value){
+			this._setState("edited", value, "Edited");
+		},
+		
+		_setHoveredAttr: function(value){
+			this._setState("hovered", value, "Hovered");
+		},
+		
+		_setStoreStateAttr: function(value){
+			var cssClass = null;
+			switch(value){
+				case "storing":
+					cssClass = "Storing";
+					break;
+				case "unstored":
+					cssClass = "Unstored";
+					break;
+				default:
+					cssClass = null;
+			}
+			var tn = this.stateNode || this.domNode;				
+			domClass.remove(tn, "Storing");
+			domClass.remove(tn, "Unstored");
+			
+			this._set("storeState", value);
+			
+			if(cssClass != null){		
+				domClass.add(tn, cssClass);
+			}
+		},
+		
+		_setState: function(prop, value, cssClass){
+			if(this[prop] != value){
+				var tn = this.stateNode || this.domNode;				
+				domClass[value ? "add" : "remove"](tn, cssClass);			
+				this._set(prop, value);
+			}	
+		},
+		
+		_setItemAttr: function(value){
+			if(value == null){
+				if(this.item && this.item.cssClass){
+					domClass.remove(this.domNode, this.item.cssClass);
+				}
+				this.item = null;
+			}else{
+				if(this.item != null){
+					if(this.item.cssClass != value.cssClass){
+						if(this.item.cssClass){
+							domClass.remove(this.domNode, this.item.cssClass);
+						}
+					}
+					this.item = lang.mixin(this.item, value);
+					if(value.cssClass){
+						domClass.add(this.domNode, value.cssClass);
+					}
+				}else{
+					this.item = value;
+					if(value.cssClass){
+						domClass.add(this.domNode, value.cssClass);
+					}
+				}
+			}
+		},
+		
+		_setText: function(node, text, allowHTML){
+			// summary:
+			//		Set the text to the specified node.
+			// node: Node
+			//		The parent node.
+			// text: String
+			//		The text to display.
+			// allowHTML: Boolean
+			//		Whether text is containing HTML formatting.
+			// tags:
+			//		protected
+			
+			if(this.owner){
+				this.owner._setText(node, text, allowHTML);
+			}			
+		},
+		
+		_isElementVisible: function(elt, startHidden, endHidden, size){
+			// summary:
+			//		Determine whether the item renderer sub element is visible or not.
+			// elt: String
+			//		The element node.
+			// startHidden: Boolean
+			//		Indicates that the start of time interval displayed by this item renderer is not the start of the displayed event. 
+			// endHidden: Boolean
+			//		Indicates that the end of time interval displayed by this item renderer is not the end of the displayed event.
+			// size: Integer
+			//		The size of the item renderer on the time axis. 
+			// tags:
+			//		protected
+			var visible;
+			var limit = this.visibilityLimits[elt];
+			
+			switch(elt){
+				case "moveHandle":
+					visible = this.moveEnabled;
+					break;
+				case "resizeStartHandle":
+					if(this.mobile){
+						visible = this.resizeEnabled && !startHidden && this.edited && (limit == -1 || size>limit);
+					}else{
+						visible = this.resizeEnabled && !startHidden && (limit == -1 || size>limit);
+					}
+					break;
+				case "resizeEndHandle":
+					if(this.mobile){
+						visible = this.resizeEnabled && !endHidden && this.edited && (limit == -1 || size>limit);
+					}else{
+						visible = this.resizeEnabled && !endHidden && (limit == -1 || size>limit);
+					}
+					break;
+				case "startTimeLabel":
+					if(this.mobile){
+						visible = !startHidden && (!this.edited || this.edited && (limit == -1 || size>limit));
+					}else{
+						visible = !startHidden && (limit == -1 || size>limit);
+					}
+					break;
+				case "endTimeLabel":
+					
+					visible = this.edited && !endHidden && (limit == -1 || size>limit);
+					
+					break;
+				case "summaryLabel":
+					if(this.mobile){
+						visible = !this.edited || this.edited && (limit == -1 || size>limit);
+					}else{
+						visible = limit == -1 || size>limit;
+					}
+					break;
+			}
+			
+			return visible;
+		},
+		
+		_formatTime: function(rd, d){
+			// summary:
+			//		Returns the time formatted string.
+			// rd: Object
+			//		The render data.
+			// d: Date
+			//		The time to format.
+			// tags:
+			//		protected
+			if(this.owner){
+				var f = this.owner.get("formatItemTimeFunc");
+				if(f != null){
+					return this.owner.formatItemTimeFunc(d, rd);
+				}
+			}
+			return rd.dateLocaleModule.format(d, {selector: 'time'});
+		},
+		
+		getDisplayValue: function(part){
+			return this._displayValue;
+		},
+		
+		updateRendering: function (w, h) {
+			// summary:
+			//		Updates the visual appearance of the renderer according the new values of the properties and the new size of the component.
+			// w: Number?
+			//		The width in pixels of the renderer.
+			// h: Number?
+			//		The height in pixels of the renderer.
+		
+			h = h || this.item.h;
+			w = w || this.item.w;
+			
+			if(!h && !w){
+				return;
+			}
+			
+			this.item.h = h;
+			this.item.w = w;
+			
+			var size = this._orientation == "vertical" ? h : w;
+	
+			var rd = this.owner.renderData;
+
+			var startHidden = rd.dateModule.compare(this.item.range[0], this.item.startTime) != 0;
+			var endHidden =  rd.dateModule.compare(this.item.range[1], this.item.endTime) != 0;
+			
+			var visible;
+			
+			if(this.beforeIcon != null) {
+				visible = this._orientation != "horizontal" || this.isLeftToRight() ? startHidden : endHidden;
+				domStyle.set(this.beforeIcon, "display", visible ? this.getDisplayValue("beforeIcon") : "none");
+			}
+
+			if(this.afterIcon != null) {
+				visible = this._orientation != "horizontal" || this.isLeftToRight() ? endHidden : startHidden;
+				domStyle.set(this.afterIcon, "display", visible ? this.getDisplayValue("afterIcon") : "none");
+			}
+			
+			if(this.moveHandle){
+				visible = this._isElementVisible("moveHandle", startHidden, endHidden, size);
+				domStyle.set(this.moveHandle, "display", visible?this.getDisplayValue("moveHandle"):"none");				
+			}
+			
+			if(this.resizeStartHandle){
+				visible = this._isElementVisible("resizeStartHandle", startHidden, endHidden, size);
+				domStyle.set(this.resizeStartHandle, "display", visible?this.getDisplayValue("resizeStartHandle"):"none");				
+			}
+			
+			if(this.resizeEndHandle){
+				visible = this._isElementVisible("resizeEndHandle", startHidden, endHidden, size);
+				domStyle.set(this.resizeEndHandle, "display", visible?this.getDisplayValue("resizeEndHandle"):"none");				
+			}
+			
+			if(this.startTimeLabel) {
+				visible = this._isElementVisible("startTimeLabel", startHidden, endHidden, size);
+				
+				domStyle.set(this.startTimeLabel, "display", visible?this.getDisplayValue("startTimeLabel"):"none");
+				if(visible) {
+					this._setText(this.startTimeLabel, this._formatTime(rd, this.item.startTime));
+				}
+			}
+			
+			if(this.endTimeLabel) {
+				visible = this._isElementVisible("endTimeLabel", startHidden, endHidden, size);
+				domStyle.set(this.endTimeLabel, "display", visible?this.getDisplayValue("endTimeLabel"):"none");
+				if(visible) {
+					this._setText(this.endTimeLabel, this._formatTime(rd, this.item.endTime));
+				}
+			}
+			
+			if(this.summaryLabel) {
+				visible = this._isElementVisible("summaryLabel", startHidden, endHidden, size);
+				domStyle.set(this.summaryLabel, "display", visible?this.getDisplayValue("summaryLabel"):"none");
+				if(visible){
+					this._setText(this.summaryLabel, this.item.summary, true);
+				}
+			}
+		}
+	});
+});
diff --git a/dojox/calendar/_VerticalScrollBarBase.js b/dojox/calendar/_VerticalScrollBarBase.js
new file mode 100644
index 0000000..17108c1
--- /dev/null
+++ b/dojox/calendar/_VerticalScrollBarBase.js
@@ -0,0 +1,79 @@
+define(["dojo/_base/declare", "dojo/_base/event", "dojo/_base/lang", "dojo/on", "dojo/dom-style", "dijit/_WidgetBase"],
+function(declare, event, lang, on, domStyle, _WidgetBase){
+	
+		return declare('dojox.calendar._VerticalScrollBarBase', _WidgetBase, {
+		
+		// value: Number 
+		//		The value of the scroll bar in pixel offset.
+		value: 0,
+		
+		// minimum: Number 
+		//		The minimum value of the scroll bar.
+		minimum: 0,
+		
+		// maximum: Number 
+		//		The maximum value of the scroll bar.
+		maximum: 100,
+		
+		_scrollHandle: null,
+		
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.own(on(this.domNode, "scroll", lang.hitch(this, function(param) {
+				this.value = this._getDomScrollerValue();
+				this.onChange(this.value);
+				this.onScroll(this.value);
+			})));
+		},
+
+		_getDomScrollerValue : function() {
+			return this.domNode.scrollTop;
+		},
+		
+		_setDomScrollerValue : function(value) {
+			this.domNode.scrollTop = value;	
+		},
+			
+		_setValueAttr: function(value){
+			value = Math.min(this.maximum, value);
+			value = Math.max(this.minimum, value);
+			if (this.value != value) {
+				this.value = value;			 
+				this.onChange(value);
+				this._setDomScrollerValue(value);
+			}
+		},
+				
+		onChange: function(value){
+			// summary:
+			//		 An extension point invoked when the value has changed.
+			// value: Integer
+			//		The postiion of the scroll bar in pixels.
+			// tags:
+			//		callback
+		},
+		
+		onScroll: function(value){
+			// summary:
+			//		 An extension point invoked when the user scrolls with the mouse.
+			// value: Integer
+			//		The position of the scroll bar in pixels.
+			// tags:
+			//		callback
+		},
+		
+		_setMinimumAttr: function(value){
+			value = Math.min(value, this.maximum);
+			this.minimum = value;
+		},
+		
+		_setMaximumAttr: function(value){
+			value = Math.max(value, this.minimum);
+			this.maximum = value;
+			
+			domStyle.set(this.content, "height", value + "px");
+		}
+
+	});
+
+});
diff --git a/dojox/calendar/nls/ar/buttons.js b/dojox/calendar/nls/ar/buttons.js
new file mode 100755
index 0000000..102798c
--- /dev/null
+++ b/dojox/calendar/nls/ar/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "اليوم",
+	dayButton: "‏اليوم‏",
+	weekButton: "أسبوع",
+	fourDaysButton: "4 أيام",
+	monthButton: "‏الشهر‏"
+}
+);
diff --git a/dojox/calendar/nls/bg/buttons.js b/dojox/calendar/nls/bg/buttons.js
new file mode 100755
index 0000000..61eb2fc
--- /dev/null
+++ b/dojox/calendar/nls/bg/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Днес",
+	dayButton: "Ден",
+	weekButton: "Седмица",
+	fourDaysButton: "4 дни",
+	monthButton: "Месец"
+}
+);
diff --git a/dojox/calendar/nls/buttons.js b/dojox/calendar/nls/buttons.js
new file mode 100755
index 0000000..f86d07f
--- /dev/null
+++ b/dojox/calendar/nls/buttons.js
@@ -0,0 +1,45 @@
+define({ root: {
+//begin v1.x content
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Today",
+	dayButton: "Day",
+	weekButton: "Week",
+	fourDaysButton: "4 Days",
+	monthButton: "Month"
+}
+//end v1.x content
+,
+"zh": true,
+"zh-tw": true,
+"uk": true,
+"tr": true,
+"th": true,
+"sv": true,
+"sl": true,
+"sk": true,
+"ru": true,
+"ro": true,
+"pt": true,
+"pt-pt": true,
+"pl": true,
+"nl": true,
+"nb": true,
+"ko": true,
+"kk": true,
+"ja": true,
+"it": true,
+"hu": true,
+"hr": true,
+"he": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true,
+"bg": true,
+"ar": true
+});
diff --git a/dojox/calendar/nls/ca/buttons.js b/dojox/calendar/nls/ca/buttons.js
new file mode 100755
index 0000000..966f967
--- /dev/null
+++ b/dojox/calendar/nls/ca/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Avuí",
+	dayButton: "Dia",
+	weekButton: "Setmana",
+	fourDaysButton: "4 dies",
+	monthButton: "Mes"
+}
+);
diff --git a/dojox/calendar/nls/cs/buttons.js b/dojox/calendar/nls/cs/buttons.js
new file mode 100755
index 0000000..b082f11
--- /dev/null
+++ b/dojox/calendar/nls/cs/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Dnes",
+	dayButton: "Den",
+	weekButton: "Týden",
+	fourDaysButton: "4 dny",
+	monthButton: "Měsíc"
+}
+);
diff --git a/dojox/calendar/nls/da/buttons.js b/dojox/calendar/nls/da/buttons.js
new file mode 100755
index 0000000..253baf0
--- /dev/null
+++ b/dojox/calendar/nls/da/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "I dag",
+	dayButton: "Dag",
+	weekButton: "Uge",
+	fourDaysButton: "4 dage",
+	monthButton: "Måned"
+}
+);
diff --git a/dojox/calendar/nls/de/buttons.js b/dojox/calendar/nls/de/buttons.js
new file mode 100755
index 0000000..d3053db
--- /dev/null
+++ b/dojox/calendar/nls/de/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Heute",
+	dayButton: "Tag",
+	weekButton: "Woche",
+	fourDaysButton: "4 Tage",
+	monthButton: "Monat"
+}
+);
diff --git a/dojox/calendar/nls/el/buttons.js b/dojox/calendar/nls/el/buttons.js
new file mode 100755
index 0000000..759f868
--- /dev/null
+++ b/dojox/calendar/nls/el/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Σήμερα",
+	dayButton: "Ημέρα",
+	weekButton: "Εβδομάδα",
+	fourDaysButton: "4 ημέρες",
+	monthButton: "Μήνας"
+}
+);
diff --git a/dojox/calendar/nls/es/buttons.js b/dojox/calendar/nls/es/buttons.js
new file mode 100755
index 0000000..0b4db22
--- /dev/null
+++ b/dojox/calendar/nls/es/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Hoy",
+	dayButton: "Día",
+	weekButton: "Semana",
+	fourDaysButton: "4 días",
+	monthButton: "Mes"
+}
+);
diff --git a/dojox/calendar/nls/fi/buttons.js b/dojox/calendar/nls/fi/buttons.js
new file mode 100755
index 0000000..ed75a80
--- /dev/null
+++ b/dojox/calendar/nls/fi/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Tänään",
+	dayButton: "Päivä",
+	weekButton: "Viikko",
+	fourDaysButton: "4 päivää",
+	monthButton: "Kuukausi"
+}
+);
diff --git a/dojox/calendar/nls/fr/buttons.js b/dojox/calendar/nls/fr/buttons.js
new file mode 100755
index 0000000..529a3c1
--- /dev/null
+++ b/dojox/calendar/nls/fr/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Aujourd'hui",
+	dayButton: "Jour",
+	weekButton: "Semaine",
+	fourDaysButton: "4 jours",
+	monthButton: "Mois"
+}
+);
diff --git a/dojox/calendar/nls/he/buttons.js b/dojox/calendar/nls/he/buttons.js
new file mode 100755
index 0000000..9271cba
--- /dev/null
+++ b/dojox/calendar/nls/he/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "היום",
+	dayButton: "יום ",
+	weekButton: "שבוע ",
+	fourDaysButton: "4 ימים",
+	monthButton: "חודש "
+}
+);
diff --git a/dojox/calendar/nls/hr/buttons.js b/dojox/calendar/nls/hr/buttons.js
new file mode 100755
index 0000000..93aadf2
--- /dev/null
+++ b/dojox/calendar/nls/hr/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Danas",
+	dayButton: "Dan",
+	weekButton: "Tjedan",
+	fourDaysButton: "4 dana",
+	monthButton: "Mjesec"
+}
+);
diff --git a/dojox/calendar/nls/hu/buttons.js b/dojox/calendar/nls/hu/buttons.js
new file mode 100755
index 0000000..14c9ce4
--- /dev/null
+++ b/dojox/calendar/nls/hu/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Ma",
+	dayButton: "Nap",
+	weekButton: "Hét",
+	fourDaysButton: "4 Nap",
+	monthButton: "Hónap"
+}
+);
diff --git a/dojox/calendar/nls/it/buttons.js b/dojox/calendar/nls/it/buttons.js
new file mode 100755
index 0000000..6aa5df4
--- /dev/null
+++ b/dojox/calendar/nls/it/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Oggi",
+	dayButton: "Giorno",
+	weekButton: "Settimana",
+	fourDaysButton: "4 Giorni",
+	monthButton: "Mese"
+}
+);
diff --git a/dojox/calendar/nls/ja/buttons.js b/dojox/calendar/nls/ja/buttons.js
new file mode 100755
index 0000000..614fb83
--- /dev/null
+++ b/dojox/calendar/nls/ja/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "今日",
+	dayButton: "日",
+	weekButton: "週",
+	fourDaysButton: "4 日間",
+	monthButton: "月"
+}
+);
diff --git a/dojox/calendar/nls/kk/buttons.js b/dojox/calendar/nls/kk/buttons.js
new file mode 100755
index 0000000..8102ac1
--- /dev/null
+++ b/dojox/calendar/nls/kk/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Бүгін",
+	dayButton: "Күн",
+	weekButton: "Апта",
+	fourDaysButton: "4 күн",
+	monthButton: "Ай"
+}
+);
diff --git a/dojox/calendar/nls/ko/buttons.js b/dojox/calendar/nls/ko/buttons.js
new file mode 100755
index 0000000..7600f20
--- /dev/null
+++ b/dojox/calendar/nls/ko/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "오늘",
+	dayButton: "일",
+	weekButton: "주",
+	fourDaysButton: "4일",
+	monthButton: "월"
+}
+);
diff --git a/dojox/calendar/nls/nb/buttons.js b/dojox/calendar/nls/nb/buttons.js
new file mode 100755
index 0000000..291e3f8
--- /dev/null
+++ b/dojox/calendar/nls/nb/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "I dag",
+	dayButton: "Dag",
+	weekButton: "Uke",
+	fourDaysButton: "4 dager",
+	monthButton: "Måned"
+}
+);
diff --git a/dojox/calendar/nls/nl/buttons.js b/dojox/calendar/nls/nl/buttons.js
new file mode 100755
index 0000000..58c7773
--- /dev/null
+++ b/dojox/calendar/nls/nl/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Vandaag",
+	dayButton: "Dag",
+	weekButton: "Week",
+	fourDaysButton: "4 dagen",
+	monthButton: "Maand"
+}
+);
diff --git a/dojox/calendar/nls/pl/buttons.js b/dojox/calendar/nls/pl/buttons.js
new file mode 100755
index 0000000..01a8565
--- /dev/null
+++ b/dojox/calendar/nls/pl/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Dzisiaj",
+	dayButton: "Dzień",
+	weekButton: "Tydzień",
+	fourDaysButton: "4 dni",
+	monthButton: "Miesiąc"
+}
+);
diff --git a/dojox/calendar/nls/pt-pt/buttons.js b/dojox/calendar/nls/pt-pt/buttons.js
new file mode 100755
index 0000000..3bef6cc
--- /dev/null
+++ b/dojox/calendar/nls/pt-pt/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Hoje",
+	dayButton: "Dia",
+	weekButton: "Semana",
+	fourDaysButton: "4 dias",
+	monthButton: "Mês"
+}
+);
diff --git a/dojox/calendar/nls/pt/buttons.js b/dojox/calendar/nls/pt/buttons.js
new file mode 100755
index 0000000..3bef6cc
--- /dev/null
+++ b/dojox/calendar/nls/pt/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Hoje",
+	dayButton: "Dia",
+	weekButton: "Semana",
+	fourDaysButton: "4 dias",
+	monthButton: "Mês"
+}
+);
diff --git a/dojox/calendar/nls/ro/buttons.js b/dojox/calendar/nls/ro/buttons.js
new file mode 100755
index 0000000..ccd85e5
--- /dev/null
+++ b/dojox/calendar/nls/ro/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Astăzi",
+	dayButton: "Zi",
+	weekButton: "Săptămână",
+	fourDaysButton: "4 zile",
+	monthButton: "Lună"
+}
+);
diff --git a/dojox/calendar/nls/ru/buttons.js b/dojox/calendar/nls/ru/buttons.js
new file mode 100755
index 0000000..3c28203
--- /dev/null
+++ b/dojox/calendar/nls/ru/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Сегодня",
+	dayButton: "День",
+	weekButton: "Неделя",
+	fourDaysButton: "4 дня",
+	monthButton: "Месяц"
+}
+);
diff --git a/dojox/calendar/nls/sk/buttons.js b/dojox/calendar/nls/sk/buttons.js
new file mode 100755
index 0000000..7c8cc72
--- /dev/null
+++ b/dojox/calendar/nls/sk/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Dnes",
+	dayButton: "Deň",
+	weekButton: "Týždeň",
+	fourDaysButton: "4 dni",
+	monthButton: "Mesiac"
+}
+);
diff --git a/dojox/calendar/nls/sl/buttons.js b/dojox/calendar/nls/sl/buttons.js
new file mode 100755
index 0000000..1f8cabb
--- /dev/null
+++ b/dojox/calendar/nls/sl/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Danes",
+	dayButton: "Dan",
+	weekButton: "Teden",
+	fourDaysButton: "4 dnevi",
+	monthButton: "Mesec"
+}
+);
diff --git a/dojox/calendar/nls/sv/buttons.js b/dojox/calendar/nls/sv/buttons.js
new file mode 100755
index 0000000..8306363
--- /dev/null
+++ b/dojox/calendar/nls/sv/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "I dag",
+	dayButton: "Dag",
+	weekButton: "Vecka",
+	fourDaysButton: "4 dagar",
+	monthButton: "Månad"
+}
+);
diff --git a/dojox/calendar/nls/th/buttons.js b/dojox/calendar/nls/th/buttons.js
new file mode 100755
index 0000000..a1271c3
--- /dev/null
+++ b/dojox/calendar/nls/th/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "วันนี้",
+	dayButton: "วัน",
+	weekButton: "อาทิตย์",
+	fourDaysButton: "4 วัน",
+	monthButton: "เดือน"
+}
+);
diff --git a/dojox/calendar/nls/tr/buttons.js b/dojox/calendar/nls/tr/buttons.js
new file mode 100755
index 0000000..cb57c8b
--- /dev/null
+++ b/dojox/calendar/nls/tr/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Bugün",
+	dayButton: "Gün",
+	weekButton: "Hafta",
+	fourDaysButton: "4 Gün",
+	monthButton: "Ay"
+}
+);
diff --git a/dojox/calendar/nls/uk/buttons.js b/dojox/calendar/nls/uk/buttons.js
new file mode 100755
index 0000000..76522dc
--- /dev/null
+++ b/dojox/calendar/nls/uk/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "Сьогодні",
+	dayButton: "День",
+	weekButton: "Тиждень",
+	fourDaysButton: "4 дні",
+	monthButton: "Місяць"
+}
+);
diff --git a/dojox/calendar/nls/zh-tw/buttons.js b/dojox/calendar/nls/zh-tw/buttons.js
new file mode 100755
index 0000000..a511cc3
--- /dev/null
+++ b/dojox/calendar/nls/zh-tw/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "今天",
+	dayButton: "天",
+	weekButton: "周",
+	fourDaysButton: "4 天",
+	monthButton: "月"
+}
+);
diff --git a/dojox/calendar/nls/zh/buttons.js b/dojox/calendar/nls/zh/buttons.js
new file mode 100755
index 0000000..ee175a4
--- /dev/null
+++ b/dojox/calendar/nls/zh/buttons.js
@@ -0,0 +1,10 @@
+define( {
+	previousButton: "◄",
+	nextButton: "►",
+	todayButton: "今天",
+	dayButton: "天",
+	weekButton: "星期",
+	fourDaysButton: "四天",
+	monthButton: "月"
+}
+);
diff --git a/dojox/calendar/templates/Calendar.html b/dojox/calendar/templates/Calendar.html
new file mode 100755
index 0000000..e951f99
--- /dev/null
+++ b/dojox/calendar/templates/Calendar.html
@@ -0,0 +1,16 @@
+<div>
+	<div data-dojo-attach-point="buttonContainer" class="buttonContainer">
+		<div data-dojo-attach-point="toolbar" data-dojo-type="dijit.Toolbar" >
+			<button data-dojo-attach-point="previousButton" data-dojo-type="dijit.form.Button" >◄</button>
+			<button data-dojo-attach-point="nextButton" data-dojo-type="dijit.form.Button" >►</button>
+			<span data-dojo-type="dijit.ToolbarSeparator"></span>
+			<button data-dojo-attach-point="todayButton" data-dojo-type="dijit.form.Button" >Today</button>
+			<span data-dojo-type="dijit.ToolbarSeparator"></span>
+			<button data-dojo-attach-point="dayButton" data-dojo-type="dijit.form.Button" >Day</button>
+			<button data-dojo-attach-point="fourDaysButton" data-dojo-type="dijit.form.Button" >4 Days</button>
+			<button data-dojo-attach-point="weekButton" data-dojo-type="dijit.form.Button" >Week</button>			
+			<button data-dojo-attach-point="monthButton" data-dojo-type="dijit.form.Button" >Month</button>
+		</div>
+	</div>
+	<div data-dojo-attach-point="viewContainer" class="viewContainer"></div>
+</div>
diff --git a/dojox/calendar/templates/ColumnView.html b/dojox/calendar/templates/ColumnView.html
new file mode 100644
index 0000000..7165dd9
--- /dev/null
+++ b/dojox/calendar/templates/ColumnView.html
@@ -0,0 +1,32 @@
+<div data-dojo-attach-events="keydown:_onKeyDown">
+	
+	<div data-dojo-attach-point="header" class="dojoxCalendarHeader">
+		<div class="dojoxCalendarYearColumnHeader" data-dojo-attach-point="yearColumnHeader">
+			<table cellspacing="0" cellpadding="0"><tr><td><span data-dojo-attach-point="yearColumnHeaderContent"></span></td></tr></table>		
+		</div>
+		<div data-dojo-attach-point="columnHeader" class="dojoxCalendarColumnHeader">
+			<table data-dojo-attach-point="columnHeaderTable" class="dojoxCalendarColumnHeaderTable" cellpadding="0" cellspacing="0"></table>
+		</div>
+	</div>
+	
+	<div data-dojo-attach-point="secondarySheetNode"></div>
+	
+	<div data-dojo-attach-point="scrollContainer" class="dojoxCalendarScrollContainer">
+		<div data-dojo-attach-point="sheetContainer" style="position:relative;left:0;right:0;margin:0;padding:0">
+			<div data-dojo-attach-point="rowHeader" class="dojoxCalendarRowHeader">
+				<table data-dojo-attach-point="rowHeaderTable" class="dojoxCalendarRowHeaderTable" cellpadding="0" cellspacing="0"></table>
+			</div>
+			<div data-dojo-attach-point="grid" class="dojoxCalendarGrid">
+				<table data-dojo-attach-point="gridTable" class="dojoxCalendarGridTable" cellpadding="0" cellspacing="0" style="width:100%"></table>
+			</div>
+			<div data-dojo-attach-point="itemContainer" class="dojoxCalendarContainer" data-dojo-attach-event="mousedown:_onGridMouseDown,mouseup:_onGridMouseUp,ondblclick:_onGridDoubleClick,touchstart:_onGridTouchStart,touchmove:_onGridTouchMove,touchend:_onGridTouchEnd">
+				<table data-dojo-attach-point="itemContainerTable" class="dojoxCalendarContainerTable" cellpadding="0" cellspacing="0" style="width:100%"></table>
+			</div>
+		</div> 
+	</div>
+	
+	<div data-dojo-attach-point="vScrollBar" class="dojoxCalendarVScrollBar">
+		<div data-dojo-attach-point="vScrollBarContent" style="visibility:hidden;position:relative;width:1px;height:1px;" ></div>
+	</div>
+	
+</div>
diff --git a/dojox/calendar/templates/ColumnViewSecondarySheet.html b/dojox/calendar/templates/ColumnViewSecondarySheet.html
new file mode 100755
index 0000000..e9bd93b
--- /dev/null
+++ b/dojox/calendar/templates/ColumnViewSecondarySheet.html
@@ -0,0 +1,11 @@
+<div data-dojo-attach-events="keydown:_onKeyDown">
+	<div  data-dojo-attach-point="rowHeader" class="dojoxCalendarRowHeader">
+		<table data-dojo-attach-point="rowHeaderTable" class="dojoxCalendarRowHeaderTable" cellpadding="0" cellspacing="0"></table>
+	</div>	
+	<div data-dojo-attach-point="grid" class="dojoxCalendarGrid">
+		<table data-dojo-attach-point="gridTable" class="dojoxCalendarGridTable" cellpadding="0" cellspacing="0"></table>
+	</div>
+	<div data-dojo-attach-point="itemContainer" class="dojoxCalendarContainer" data-dojo-attach-event="mousedown:_onGridMouseDown,mouseup:_onGridMouseUp,ondblclick:_onGridDoubleClick,touchstart:_onGridTouchStart,touchmove:_onGridTouchMove,touchend:_onGridTouchEnd">
+		<table data-dojo-attach-point="itemContainerTable" class="dojoxCalendarContainerTable" cellpadding="0" cellspacing="0" style="width:100%"></table>
+	</div>
+</div>
diff --git a/dojox/calendar/templates/ExpandRenderer.html b/dojox/calendar/templates/ExpandRenderer.html
new file mode 100755
index 0000000..3c81df1
--- /dev/null
+++ b/dojox/calendar/templates/ExpandRenderer.html
@@ -0,0 +1,3 @@
+<div class="dojoxCalendarExpand" onselectstart="return false;" data-dojo-attach-event="click:_onClick,touchstart:_onMouseDown,touchend:_onClick,mousedown:_onMouseDown,mouseup:_onMouseUp,mouseover:_onMouseOver,mouseout:_onMouseOut">
+	<div class="bg"><span data-dojo-attach-point="expand">▼</span><span style="display:none" data-dojo-attach-point="collapse">▲</span></div>	
+</div>
diff --git a/dojox/calendar/templates/HorizontalRenderer.html b/dojox/calendar/templates/HorizontalRenderer.html
new file mode 100755
index 0000000..dda3894
--- /dev/null
+++ b/dojox/calendar/templates/HorizontalRenderer.html
@@ -0,0 +1,13 @@
+<div class="dojoxCalendarEvent dojoxCalendarHorizontal" onselectstart="return false;">
+	<div class="bg" ></div>
+	<div style="position:absolute;left:2px;bottom:2px" data-dojo-attach-point="beforeIcon" class="beforeIcon">◄</div>	
+	<div data-dojo-attach-point="labelContainer" class="labels">		
+		<span data-dojo-attach-point="startTimeLabel" class="startTime"></span>
+		<span data-dojo-attach-point="summaryLabel" class="summary"></span>
+		<span  data-dojo-attach-point="endTimeLabel" class="endTime"></span>
+	</div>
+	<div style="position:absolute;right:2px;bottom:2px" data-dojo-attach-point="afterIcon" class="afterIcon">►</div>
+	<div data-dojo-attach-point="moveHandle" class="handle moveHandle" ></div>
+	<div data-dojo-attach-point="resizeStartHandle" class="handle resizeStartHandle"></div>
+	<div data-dojo-attach-point="resizeEndHandle" class="handle resizeEndHandle" ></div>	
+</div>
diff --git a/dojox/calendar/templates/LabelRenderer.html b/dojox/calendar/templates/LabelRenderer.html
new file mode 100755
index 0000000..26d97fb
--- /dev/null
+++ b/dojox/calendar/templates/LabelRenderer.html
@@ -0,0 +1,8 @@
+<div class="dojoxCalendarEvent dojoxCalendarLabel" onselectstart="return false;">	
+	<div class="labels">
+		<span data-dojo-attach-point="startTimeLabel" class="startTime"></span>
+		<span data-dojo-attach-point="summaryLabel" class="summary"></span>
+		<span data-dojo-attach-point="endTimeLabel" class="endTime"></span>
+	</div>	
+	<div data-dojo-attach-point="moveHandle" class="handle moveHandle" ></div>
+</div>
diff --git a/dojox/calendar/templates/MatrixView.html b/dojox/calendar/templates/MatrixView.html
new file mode 100644
index 0000000..dd21ed2
--- /dev/null
+++ b/dojox/calendar/templates/MatrixView.html
@@ -0,0 +1,17 @@
+<div data-dojo-attach-events="keydown:_onKeyDown">
+	<div  class="dojoxCalendarYearColumnHeader" data-dojo-attach-point="yearColumnHeader">
+		<table><tr><td><span data-dojo-attach-point="yearColumnHeaderContent"></span></td></tr></table>		
+	</div>	
+	<div data-dojo-attach-point="columnHeader" class="dojoxCalendarColumnHeader">
+		<table data-dojo-attach-point="columnHeaderTable" class="dojoxCalendarColumnHeaderTable" cellpadding="0" cellspacing="0"></table>
+	</div>		
+	<div dojoAttachPoint="rowHeader" class="dojoxCalendarRowHeader">
+		<table data-dojo-attach-point="rowHeaderTable" class="dojoxCalendarRowHeaderTable" cellpadding="0" cellspacing="0"></table>
+	</div>	
+	<div dojoAttachPoint="grid" class="dojoxCalendarGrid">
+		<table data-dojo-attach-point="gridTable" class="dojoxCalendarGridTable" cellpadding="0" cellspacing="0"></table>
+	</div>	
+	<div data-dojo-attach-point="itemContainer" class="dojoxCalendarContainer" data-dojo-attach-event="mousedown:_onGridMouseDown,mouseup:_onGridMouseUp,ondblclick:_onGridDoubleClick,touchstart:_onGridTouchStart,touchmove:_onGridTouchMove,touchend:_onGridTouchEnd">
+		<table data-dojo-attach-point="itemContainerTable" class="dojoxCalendarContainerTable" cellpadding="0" cellspacing="0" style="width:100%"></table>
+	</div>	
+</div>
diff --git a/dojox/calendar/templates/MobileCalendar.html b/dojox/calendar/templates/MobileCalendar.html
new file mode 100755
index 0000000..e2e7ea3
--- /dev/null
+++ b/dojox/calendar/templates/MobileCalendar.html
@@ -0,0 +1,11 @@
+<div>
+	<div data-dojo-attach-point="viewContainer" class="viewContainer"></div>
+	<div data-dojo-attach-point="buttonContainer" class="buttonContainer">
+			<button data-dojo-attach-point="previousButton" data-dojo-type="dojox.mobile.Button" >◄</button>
+			<button data-dojo-attach-point="todayButton" data-dojo-type="dojox.mobile.Button" >Today</button>
+			<button data-dojo-attach-point="dayButton" data-dojo-type="dojox.mobile.Button" >Day</button>
+			<button data-dojo-attach-point="weekButton" data-dojo-type="dojox.mobile.Button" >Week</button>			
+			<button data-dojo-attach-point="monthButton" data-dojo-type="dojox.mobile.Button" >Month</button>
+		<button data-dojo-attach-point="nextButton" data-dojo-type="dojox.mobile.Button" >►</button>
+	</div>
+</div>
diff --git a/dojox/calendar/templates/MobileHorizontalRenderer.html b/dojox/calendar/templates/MobileHorizontalRenderer.html
new file mode 100755
index 0000000..fae00ab
--- /dev/null
+++ b/dojox/calendar/templates/MobileHorizontalRenderer.html
@@ -0,0 +1,13 @@
+<div class="dojoxCalendarEvent dojoxCalendarHorizontal" onselectstart="return false;">
+	<div class="bg" ></div>
+	<div style="position:absolute;left:2px;bottom:2px"><span data-dojo-attach-point="beforeIcon" class="beforeIcon">◄</span></div>	
+	<div data-dojo-attach-point="labelContainer" class="labels">		
+		<span data-dojo-attach-point="startTimeLabel" class="startTime"></span>
+		<span data-dojo-attach-point="summaryLabel" class="summary"></span>
+		<span  data-dojo-attach-point="endTimeLabel" class="endTime"></span>
+	</div>
+	<div style="position:absolute;right:2px;bottom:2px"><span data-dojo-attach-point="afterIcon" class="afterIcon">►</span></div>
+	<div data-dojo-attach-point="moveHandle" class="moveHandle" ></div>	
+	<div data-dojo-attach-point="resizeStartHandle" class="resizeHandle resizeStartHandle"><div></div></div>	
+	<div data-dojo-attach-point="resizeEndHandle" class="resizeHandle resizeEndHandle"><div></div></div>	
+</div>
diff --git a/dojox/calendar/templates/MobileVerticalRenderer.html b/dojox/calendar/templates/MobileVerticalRenderer.html
new file mode 100755
index 0000000..f73070e
--- /dev/null
+++ b/dojox/calendar/templates/MobileVerticalRenderer.html
@@ -0,0 +1,12 @@
+<div class="dojoxCalendarEvent dojoxCalendarVertical">
+	<div class="bg"></div>	
+	<div data-dojo-attach-point="resizeStartHandle" class="resizeStartHandle resizeHandle"><div></div></div>
+	<dl style="width:100%;">				
+		<dd data-dojo-attach-point="beforeIcon" class="beforeIcon">▲</dd>
+		<dd data-dojo-attach-point="startTimeLabel" class="startTime"></dd>
+		<dd data-dojo-attach-point="summaryLabel" class="summary"></dd>
+	</dl>
+	<span data-dojo-attach-point="afterIcon" class="afterIcon">▼</span>	
+	<div data-dojo-attach-point="resizeEndHandle" class="resizeEndHandle resizeHandle"><div></div></div>
+	<span data-dojo-attach-point="endTimeLabel" class="endTime"></span>
+</div>
diff --git a/dojox/calendar/templates/MonthColumnView.html b/dojox/calendar/templates/MonthColumnView.html
new file mode 100644
index 0000000..b6c116e
--- /dev/null
+++ b/dojox/calendar/templates/MonthColumnView.html
@@ -0,0 +1,18 @@
+<div data-dojo-attach-events="keydown:_onKeyDown">		
+	<div data-dojo-attach-point="columnHeader" class="dojoxCalendarColumnHeader">
+		<table data-dojo-attach-point="columnHeaderTable" class="dojoxCalendarColumnHeaderTable" cellpadding="0" cellspacing="0"></table>
+	</div>	
+	<div data-dojo-attach-point="vScrollBar" class="dojoxCalendarVScrollBar">
+		<div data-dojo-attach-point="vScrollBarContent" style="visibility:hidden;position:relative; width:1px; height:1px;" ></div>
+	</div>	
+	<div data-dojo-attach-point="scrollContainer" class="dojoxCalendarScrollContainer">
+		<div data-dojo-attach-point="sheetContainer" style="position:relative;left:0;right:0;margin:0;padding:0">			
+			<div data-dojo-attach-point="grid" class="dojoxCalendarGrid">
+				<table data-dojo-attach-point="gridTable" class="dojoxCalendarGridTable" cellpadding="0" cellspacing="0" style="width:100%"></table>
+			</div>
+			<div data-dojo-attach-point="itemContainer" class="dojoxCalendarContainer" data-dojo-attach-event="mousedown:_onGridMouseDown,mouseup:_onGridMouseUp,ondblclick:_onGridDoubleClick,touchstart:_onGridTouchStart,touchmove:_onGridTouchMove,touchend:_onGridTouchEnd">
+				<table data-dojo-attach-point="itemContainerTable" class="dojoxCalendarContainerTable" cellpadding="0" cellspacing="0" style="width:100%"></table>
+			</div>
+		</div> 
+	</div>	
+</div>
diff --git a/dojox/calendar/templates/SimpleColumnView.html b/dojox/calendar/templates/SimpleColumnView.html
new file mode 100755
index 0000000..5aee9b2
--- /dev/null
+++ b/dojox/calendar/templates/SimpleColumnView.html
@@ -0,0 +1,27 @@
+<div data-dojo-attach-events="keydown:_onKeyDown">	
+	<div data-dojo-attach-point="header" class="dojoxCalendarHeader">
+		<div class="dojoxCalendarYearColumnHeader" data-dojo-attach-point="yearColumnHeader">
+			<table><tr><td><span data-dojo-attach-point="yearColumnHeaderContent"></span></td></tr></table>		
+		</div>
+		<div data-dojo-attach-point="columnHeader" class="dojoxCalendarColumnHeader">
+			<table data-dojo-attach-point="columnHeaderTable" class="dojoxCalendarColumnHeaderTable" cellpadding="0" cellspacing="0"></table>
+		</div>
+	</div>	
+	<div data-dojo-attach-point="vScrollBar" class="dojoxCalendarVScrollBar">
+		<div data-dojo-attach-point="vScrollBarContent" style="visibility:hidden;position:relative; width:1px; height:1px;" ></div>
+	</div>	
+	<div data-dojo-attach-point="scrollContainer" class="dojoxCalendarScrollContainer">
+		<div data-dojo-attach-point="sheetContainer" style="position:relative;left:0;right:0;margin:0;padding:0">
+			<div data-dojo-attach-point="rowHeader" class="dojoxCalendarRowHeader">
+				<table data-dojo-attach-point="rowHeaderTable" class="dojoxCalendarRowHeaderTable" cellpadding="0" cellspacing="0"></table>
+			</div>
+			<div data-dojo-attach-point="grid" class="dojoxCalendarGrid">
+				<table data-dojo-attach-point="gridTable" class="dojoxCalendarGridTable" cellpadding="0" cellspacing="0" style="width:100%"></table>
+			</div>
+			<div data-dojo-attach-point="itemContainer" class="dojoxCalendarContainer" data-dojo-attach-event="mousedown:_onGridMouseDown,mouseup:_onGridMouseUp,ondblclick:_onGridDoubleClick,touchstart:_onGridTouchStart,touchmove:_onGridTouchMove,touchend:_onGridTouchEnd">
+				<table data-dojo-attach-point="itemContainerTable" class="dojoxCalendarContainerTable" cellpadding="0" cellspacing="0" style="width:100%"></table>
+			</div>
+		</div> 
+	</div>
+</div>
+
diff --git a/dojox/calendar/templates/SimpleMatrixView.html b/dojox/calendar/templates/SimpleMatrixView.html
new file mode 100644
index 0000000..dd21ed2
--- /dev/null
+++ b/dojox/calendar/templates/SimpleMatrixView.html
@@ -0,0 +1,17 @@
+<div data-dojo-attach-events="keydown:_onKeyDown">
+	<div  class="dojoxCalendarYearColumnHeader" data-dojo-attach-point="yearColumnHeader">
+		<table><tr><td><span data-dojo-attach-point="yearColumnHeaderContent"></span></td></tr></table>		
+	</div>	
+	<div data-dojo-attach-point="columnHeader" class="dojoxCalendarColumnHeader">
+		<table data-dojo-attach-point="columnHeaderTable" class="dojoxCalendarColumnHeaderTable" cellpadding="0" cellspacing="0"></table>
+	</div>		
+	<div dojoAttachPoint="rowHeader" class="dojoxCalendarRowHeader">
+		<table data-dojo-attach-point="rowHeaderTable" class="dojoxCalendarRowHeaderTable" cellpadding="0" cellspacing="0"></table>
+	</div>	
+	<div dojoAttachPoint="grid" class="dojoxCalendarGrid">
+		<table data-dojo-attach-point="gridTable" class="dojoxCalendarGridTable" cellpadding="0" cellspacing="0"></table>
+	</div>	
+	<div data-dojo-attach-point="itemContainer" class="dojoxCalendarContainer" data-dojo-attach-event="mousedown:_onGridMouseDown,mouseup:_onGridMouseUp,ondblclick:_onGridDoubleClick,touchstart:_onGridTouchStart,touchmove:_onGridTouchMove,touchend:_onGridTouchEnd">
+		<table data-dojo-attach-point="itemContainerTable" class="dojoxCalendarContainerTable" cellpadding="0" cellspacing="0" style="width:100%"></table>
+	</div>	
+</div>
diff --git a/dojox/calendar/templates/VerticalRenderer.html b/dojox/calendar/templates/VerticalRenderer.html
new file mode 100755
index 0000000..d74bebc
--- /dev/null
+++ b/dojox/calendar/templates/VerticalRenderer.html
@@ -0,0 +1,13 @@
+<div class="dojoxCalendarEvent dojoxCalendarVertical" onselectstart="return false;">
+	<div class="bg"></div>
+	<dl style="width:100%;">
+		<dd data-dojo-attach-point="beforeIcon" class="beforeIcon">▲</dd>
+		<dd data-dojo-attach-point="startTimeLabel" class="startTime"></dd>
+		<dd data-dojo-attach-point="summaryLabel" class="summary"></dd>
+	</dl>	
+	<span data-dojo-attach-point="afterIcon" class="afterIcon">▼</span>
+	<div data-dojo-attach-point="moveHandle" class="handle moveHandle" ></div>
+	<div data-dojo-attach-point="resizeStartHandle" class="handle resizeStartHandle"></div>
+	<div data-dojo-attach-point="resizeEndHandle" class="handle resizeEndHandle" ></div>
+	<div data-dojo-attach-point="endTimeLabel" class="endTime"></div>
+</div>
diff --git a/dojox/calendar/tests/CalendarMonthColumn.html b/dojox/calendar/tests/CalendarMonthColumn.html
new file mode 100644
index 0000000..dd1566c
--- /dev/null
+++ b/dojox/calendar/tests/CalendarMonthColumn.html
@@ -0,0 +1,17 @@
+<div>
+	<div data-dojo-attach-point="buttonContainer" class="buttonContainer">
+		<div data-dojo-attach-point="toolbar" data-dojo-type="dijit.Toolbar" >
+			<button data-dojo-attach-point="previousButton" data-dojo-type="dijit.form.Button" >◄</button>
+			<button data-dojo-attach-point="nextButton" data-dojo-type="dijit.form.Button" >►</button>
+			<span data-dojo-type="dijit.ToolbarSeparator"></span>
+			<button data-dojo-attach-point="todayButton" data-dojo-type="dijit.form.Button" />Today</button>
+			<span data-dojo-type="dijit.ToolbarSeparator"></span>
+			<button data-dojo-attach-point="dayButton" data-dojo-type="dijit.form.Button" >Day</button>
+			<button data-dojo-attach-point="fourDaysButton" data-dojo-type="dijit.form.Button" >4 Days</button>
+			<button data-dojo-attach-point="weekButton" data-dojo-type="dijit.form.Button" >Week</button>			
+			<button data-dojo-attach-point="monthButton" data-dojo-type="dijit.form.Button" >Month</button>
+			<button data-dojo-attach-point="sixMonthButton" data-dojo-type="dijit.form.Button" >6 Months</button>
+		</div>
+	</div>
+	<div data-dojo-attach-point="viewContainer" class="viewContainer"></div>
+</div>
\ No newline at end of file
diff --git a/dojox/calendar/tests/DatePicker.js b/dojox/calendar/tests/DatePicker.js
new file mode 100644
index 0000000..21206f8
--- /dev/null
+++ b/dojox/calendar/tests/DatePicker.js
@@ -0,0 +1,27 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dijit/Calendar"],
+
+function(
+	declare,
+	lang,
+	Calendar){
+					
+	return declare("demo.DatePicker", Calendar, {
+		
+		minDate: null,
+		maxDate: null,
+		
+		getClassForDate: function(date, locale){
+			if(this.minDate && this.maxDate){
+				var cal = this.dateModule;
+				if(cal.compare(date, this.minDate) >= 0 && cal.compare(date, this.maxDate) <= 0){
+					return "Highlighted";
+				}				
+			}
+			return null;
+		}
+		
+	});
+});
diff --git a/dojox/calendar/tests/ExtendedCalendar.js b/dojox/calendar/tests/ExtendedCalendar.js
new file mode 100644
index 0000000..d46deb3
--- /dev/null
+++ b/dojox/calendar/tests/ExtendedCalendar.js
@@ -0,0 +1,91 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/on", 
+	"dojox/calendar/Calendar", 
+	"dojox/calendar/MonthColumnView", 
+	"dojox/calendar/VerticalRenderer", 
+	"dojox/calendar/Mouse",
+	"dojox/calendar/Keyboard",
+	"dojo/text!./CalendarMonthColumn.html"],
+
+function(
+	declare,
+	lang,
+	on,
+	Calendar, 
+	MonthColumnView,		
+	VerticalRenderer, 
+	Mouse,
+	Keyboard,
+	template){
+					
+	return declare("demo.ExtendedCalendar", Calendar, {
+		
+		// summary:
+		//		A Calendar subclass that embeds a month column view.	
+		
+		templateString: template,
+		
+		verticalRenderer: VerticalRenderer,
+		
+		_createDefaultViews: function(){
+			this.inherited(arguments);
+			// create the month column view.
+			this.monthColumnView = declare([MonthColumnView, Keyboard, Mouse])({
+				verticalRenderer: VerticalRenderer				
+			});
+			
+			this.monthColumnView.on("columnHeaderClick", lang.hitch(this, function(e){
+				this.set("dateInterval", "month");
+				this.set("dateIntervalSteps", 1);
+				this.set("date", e.date);
+			}));			
+			
+			return [this.columnView, this.matrixView, this.monthColumnView];
+		},
+		
+		_computeCurrentView: function(startDate, endDate, duration){
+			// show the month column view if the duration is greater than 31x2 days
+			if(duration>62){
+				return this.monthColumnView;
+			}else{
+				return this.inherited(arguments);
+			}
+		},
+		
+		_configureView: function(view, index, timeInterval, duration){
+			// show only from January to June or from July to December
+			if(view.viewKind == "monthColumns"){
+				var m = timeInterval[0].getMonth();
+				var d = this.newDate(timeInterval[0]);
+				d.setMonth(m<6?0:6);
+				view.set("startDate", d);
+				view.set("columnCount", 6);
+			}else{
+				this.inherited(arguments);
+			}
+		},
+		
+		configureButtons: function(){
+			// configure the 6 months button
+			this.inherited(arguments);
+			if(this.sixMonthButton){
+				// should set label from resource bundle here!
+				this.own(
+					on(this.sixMonthButton, "click", lang.hitch(this, function(){						
+						this.set("dateIntervalSteps", 6);
+						this.set("dateInterval", "month");
+					}))
+				);	
+			}
+		},
+		
+		matrixViewRowHeaderClick: function(e){
+			this.set("dateInterval", "week");
+			this.set("dateIntervalSteps", 1);
+			this.set("date", e.date);
+		}
+		
+	});
+});
diff --git a/dojox/calendar/tests/SimpleMatrixView.html b/dojox/calendar/tests/SimpleMatrixView.html
new file mode 100644
index 0000000..8ebebb9
--- /dev/null
+++ b/dojox/calendar/tests/SimpleMatrixView.html
@@ -0,0 +1,11 @@
+<div data-dojo-attach-events="keydown:_onKeyDown">
+	<div data-dojo-attach-point="columnHeader" class="dojoxCalendarColumnHeader">
+		<table data-dojo-attach-point="columnHeaderTable" class="dojoxCalendarColumnHeaderTable" cellpadding="0" cellspacing="0"></table>
+	</div>		
+	<div dojoAttachPoint="grid" class="dojoxCalendarGrid">
+		<table data-dojo-attach-point="gridTable" class="dojoxCalendarGridTable" cellpadding="0" cellspacing="0"></table>
+	</div>	
+	<div data-dojo-attach-point="itemContainer" class="dojoxCalendarContainer" data-dojo-attach-event="mousedown:_onGridMouseDown,mouseup:_onGridMouseUp,ondblclick:_onGridDoubleClick,touchstart:_onGridTouchStart,touchmove:_onGridTouchMove,touchend:_onGridTouchEnd">
+		<table data-dojo-attach-point="itemContainerTable" class="dojoxCalendarContainerTable" cellpadding="0" cellspacing="0" style="width:100%"></table>
+	</div>	
+</div>
diff --git a/dojox/calendar/tests/asyncStore.css b/dojox/calendar/tests/asyncStore.css
new file mode 100644
index 0000000..4044512
--- /dev/null
+++ b/dojox/calendar/tests/asyncStore.css
@@ -0,0 +1,41 @@
+
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Unstored .bg {
+  filter: alpha(opacity=70);
+  opacity: 0.4;  
+}
+
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Storing .bg {  
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+  animation:animKeyframes 1s infinite;
+  -moz-animation:animKeyframes 1s infinite; /* Firefox */
+  -webkit-animation:animKeyframes 1s infinite; /* Safari and Chrome */	
+  -o-animation: animKeyframes 1s infinite; /* Opera */	
+}
+
+ at keyframes animKeyframes
+{
+	0%   {opacity: 0.7;}
+	50% {opacity: 0.9;}
+	100% {opacity: 0.7;}
+}
+
+ at -moz-keyframes animKeyframes /* Firefox */
+{
+	0%   {opacity: 0.7;}
+	50% {opacity: 0.9;}
+	100% {opacity: 0.7;}
+}
+
+ at -webkit-keyframes animKeyframes /* Safari and Chrome */
+{
+	0%   {opacity: 0.7;}
+	50% {opacity: 0.9;}
+	100% {opacity: 0.7;}
+}
+ at -o-keyframes myfirst /* Opera */
+{
+	0%   {opacity: 0.7;}
+	50% {opacity: 0.9;}
+	100% {opacity: 0.7;}
+}
\ No newline at end of file
diff --git a/dojox/calendar/tests/asyncStore.html b/dojox/calendar/tests/asyncStore.html
new file mode 100644
index 0000000..12e80aa
--- /dev/null
+++ b/dojox/calendar/tests/asyncStore.html
@@ -0,0 +1,183 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Calendar Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/Calendar.css";
+			@import "calendar.css";
+			@import "asyncStore.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>	
+				
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>		 				
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/array", "dojo/_base/fx", "dojo/on", 
+			         "dojo/date/locale", "dojo/parser",	"dojo/Deferred", "dojo/dom", "dojo/dom-construct",	"dojo/store/Memory", 
+			         "dojo/store/Observable",	"dojox/calendar/Calendar", "dijit/Calendar", "dijit/Menu", "dijit/MenuItem"	],
+
+				function(ready, declare, lang, has, arr, fx, on, locale, parser, Deferred, dom, domConstruct,
+					Memory, Observable, Calendar){
+
+					ready(function(){
+					
+						// Display different hint every 10 seconds 
+						var hints = [
+							"Hint: Create an event by clicking and dragging on the grid while maintaining the control key",
+							"Hint: Move an event by clicking on it and dragging it",
+							"Hint: Resize an event by clicking on one of its ends and dragging it"
+						];
+						
+						var hintIdx = 0;
+						dom.byId("hint").innerHTML = hints[0];
+												
+						setInterval(function(){
+							fx.fadeOut({node: "hint", 
+								onEnd: function(){
+									hintIdx = hintIdx+1>hints.length-1 ? 0 : hintIdx+1;
+									dom.byId("hint").innerHTML = hints[hintIdx];
+									fx.fadeIn({node: "hint"}).play(500); 									
+								}
+							}).play(500);
+						}, 10000);
+																					
+						// Calendar model creation						
+						var modelBase = [
+							{day: 1, start: [10,0], duration: 1400},
+							{day: 2, start: [10,30], duration: 120},
+							{day: 2, start: [12,0], duration: 240},
+							{day: 3, start: [6,0], duration: 180},
+							{day: 3, start: [0,0], duration: 2880, allDay: true}
+						];
+						
+						var someData = [];
+												
+						var startOfWeek = calendar.floorToWeek(new calendar.dateClassObj());
+						
+						for (var id=0; id<modelBase.length; id++) {
+							var newObj = {
+								id: id,
+								summary: "New Event " + id,
+								startTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								endTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								allDay: modelBase[id].allDay
+							};
+
+							newObj.startTime = calendar.dateModule.add(newObj.startTime, "day", modelBase[id].day);
+							newObj.startTime.setHours(modelBase[id].start[0]);
+							newObj.startTime.setMinutes(modelBase[id].start[1]);
+
+							newObj.endTime = calendar.dateModule.add(newObj.startTime, "minute", modelBase[id].duration);
+
+							someData.push(newObj);
+						}
+						
+						
+						// BEGIN HACK
+						// Hack to simulate some latency when adding / updating an event.
+						// Observable is breaking completely the inheritance chain
+						var store = new Observable(Memory({data: someData}));
+						var oldPut = store.put;
+						store.put = function(value, options){													
+							setTimeout(lang.hitch(this, function(){
+								oldPut.call(this, value, options);																		
+							}), 3000);							
+							return new Deferred();
+						};
+						// END HACK
+						
+						calendar.set("store", store);
+						calendar.set("date", startOfWeek);
+						
+						// Enable creation of event interactively by ctrl clicking grid.
+						var createItem = function(view, d, e){
+											
+							// create item by maintaining control key
+							if(!e.ctrlKey || e.shiftKey || e.altKey){
+								return null;
+							}
+						
+							// create a new event
+							var start, end;
+							var colView = calendar.columnView;
+							var cal = calendar.dateModule;
+							
+							if(view == colView){
+								start = calendar.floorDate(d, "minute", colView.timeSlotDuration);
+								end = cal.add(start, "minute", colView.timeSlotDuration); 
+							}else{
+								start = calendar.floorToDay(d);
+								end = cal.add(start, "day", 1);
+							}
+							
+							var item = {
+								id: id,
+								created: true,
+								summary: "New event " + id,
+								startTime: start,
+								endTime: end,
+								allDay: view.viewKind == "matrix"
+							};
+							
+							id++;	
+							
+							return item;							
+						};
+						
+						calendar.set("createOnGridClick", true);
+						calendar.set("createItemFunc", createItem);						
+											
+						// show context menu on right clicking an event
+						calendar.on("itemContextMenu", function(e){
+							dojo.stopEvent(e.triggerEvent);
+							calendarContextMenu._openMyself({ 
+								target: e.renderer.domNode, 
+								coords: {x: e.triggerEvent.pageX, y: e.triggerEvent.pageY} 
+							});
+						});
+						
+						contextMenuDelete.on("click", function(){
+							arr.forEach(calendar.selectedItems, function(item){
+								calendar.store.remove(item.id);
+							}); 							
+						});
+																																					
+						// Hide loading panel when application is ready
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+						
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>			
+		    
+		    <div data-dojo-id="calendar" data-dojo-type="dojox.calendar.Calendar" 
+				style="position:absolute;left:10px;top:10px;bottom:30px;right:10px">
+				<div data-dojo-type="dijit.Menu" data-dojo-id="calendarContextMenu" style="display: none;">
+	                <div data-dojo-type="dijit.MenuItem" data-dojo-id="contextMenuDelete" data-dojo-props="iconClass:'dijitIcon dijitIconDelete'">Delete</div>
+	            </div>	
+			</div>
+			<div id="hint" style="position:absolute;left:10px;height:15px;bottom:10px;right:10px;color:#999;overflow:auto"></div>
+	    		    
+		</div>																		
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/calendar.css b/dojox/calendar/tests/calendar.css
new file mode 100644
index 0000000..b9cb9b0
--- /dev/null
+++ b/dojox/calendar/tests/calendar.css
@@ -0,0 +1,89 @@
+.claro .dojoxCalendar  {
+	font-size: 0.9em;
+}
+
+.claro .dojoxCalendarEvent.Calendar2 .bg.bg {
+	background: #2095B4;
+}
+
+.claro .dojoxCalendarEvent.Calendar2.Hovered .bg.bg {
+	background: #24A5C8;
+}
+
+.claro .dojoxCalendarEvent.Calendar2.Selected .bg.bg {
+	background: #166B81;
+}
+
+.claro .dojoxCalendarEvent.Edited.Invalid .bg.bg {
+	background: #FFF;
+}
+
+
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2 .startTime {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #00768F;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: 1px solid #260000;
+  border-left: 1px solid #260000;
+  border-right: 1px solid #260000;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2.Focused .startTime {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #6c0000;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: dashed 1px #ffffff;
+  border-left: dashed 1px #ffffff;
+  border-right: dashed 1px #ffffff;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2.Hovered .startTime {
+  background-color: #0094B4;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2.Selected .startTime {
+  background-color: #005A6D;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2.Edited .startTime {
+  background-color: #0095b4;
+  border-top: dashed 1px #ffffff;
+  border-left: dashed 1px #ffffff;
+  border-right: dashed 1px #ffffff;
+}
+.claro .deleteButton .dijitButtonNode{
+	background-color: #F88;
+}
+
+html, body {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+#dateChooser{
+	position:absolute; 
+	left:10px; 
+	right:10px; 
+	top:10px; 
+}
+
+label{
+	vertical-align: middle;
+}
+
+.propertyTitle {
+	font-weight: bold;
+	font-size:0.9em;
+}
diff --git a/dojox/calendar/tests/calendar.html b/dojox/calendar/tests/calendar.html
new file mode 100644
index 0000000..8219415
--- /dev/null
+++ b/dojox/calendar/tests/calendar.html
@@ -0,0 +1,396 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Calendar Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/Calendar.css";
+			@import "../themes/nihilo/Calendar.css";
+			@import "calendar.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			.dijitCalendar .Highlighted {
+				background-color: #fff0b4;
+					
+			}
+			.dijitCalendar .Highlighted .dijitCalendarDateLabel {
+				color: red !important;
+				border: solid 1px #fff0b4;				
+			}					
+			
+		</style>			
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+				data-dojo-config="async: true, parseOnLoad: true, paths : {'demo' : '../dojox/calendar/tests'}"
+ 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/array", "dojo/_base/fx", "dojo/dom-class", "dojo/on", 
+			         "dojo/date/locale", "dojo/parser",	"dojo/dom", "dojo/dom-construct",	"dojo/store/Memory", 
+			         "dojo/store/Observable",	"dojox/calendar/Calendar", "demo/DatePicker",  "dijit/TitlePane", 
+			         "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/form/CheckBox", 
+			         "dijit/form/TextBox", "dijit/form/DateTextBox", "dijit/form/TimeTextBox", 
+			         "dijit/form/Button", "dijit/form/ComboBox", "dijit/Menu", "dijit/MenuItem"	],
+
+				function(ready, lang, has, arr, fx, domClass, on, locale, parser, dom, domConstruct,
+					Memory, Observable, Calendar){
+
+					ready(function(){
+					
+						// Display different hint every 10 seconds 
+						var hints = [
+							"Hint: Create an event by clicking and dragging on the grid while maintaining the control key",
+							"Hint: Move an event by clicking on it and dragging it",
+							"Hint: Resize an event by clicking on one of its ends and dragging it"
+						];
+						
+						var hintIdx = 0;
+						dom.byId("hint").innerHTML = hints[0];
+												
+						setInterval(function(){
+							fx.fadeOut({node: "hint", 
+								onEnd: function(){
+									hintIdx = hintIdx+1>hints.length-1 ? 0 : hintIdx+1;
+									dom.byId("hint").innerHTML = hints[hintIdx];
+									fx.fadeIn({node: "hint"}).play(500); 									
+								}
+							}).play(500);
+						}, 10000);
+					
+											
+						calendar.set("cssClassFunc", function(item){
+							// Use custom css class on renderers depending of a parameter (calendar).							
+							return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+						});
+						
+						// Calendar model creation						
+						var modelBase = [
+							{day: 1, start: [10,0], duration: 1400},
+							{day: 2, start: [10,30], duration: 120},
+							{day: 2, start: [12,0], duration: 240},
+							{day: 3, start: [6,0], duration: 180},
+							{day: 3, start: [0,0], duration: 2880, allDay: true}
+						];
+						
+						var someData = [];
+												
+						var startOfWeek = calendar.floorToWeek(new calendar.dateClassObj());
+						
+						for (var id=0; id<modelBase.length; id++) {
+							var newObj = {
+								id: id,
+								summary: "New Event " + id,
+								startTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								endTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								calendar: id%2 == 0 ? "cal1" : "cal2",
+								allDay: modelBase[id].allDay
+							};
+
+							newObj.startTime = calendar.dateModule.add(newObj.startTime, "day", modelBase[id].day);
+							newObj.startTime.setHours(modelBase[id].start[0]);
+							newObj.startTime.setMinutes(modelBase[id].start[1]);
+
+							newObj.endTime = calendar.dateModule.add(newObj.startTime, "minute", modelBase[id].duration);
+
+							someData.push(newObj);
+						}
+						
+						var store = new Observable(new Memory({data: someData}));
+						calendar.set("store", store);
+						calendar.set("date", startOfWeek);
+						
+						// Enable creation of event interactively by ctrl clicking grid.
+						var createItem = function(view, d, e){
+						
+							var cal1 = calendar1CB.get("checked");
+							var cal2 = calendar2CB.get("checked");
+						
+							// create item by maintaining control key
+							if(!e.ctrlKey || e.shiftKey || e.altKey || (!cal1 && !cal2)){
+								return null;
+							}
+						
+							// create a new event
+							var start, end;
+							var colView = calendar.columnView;
+							var cal = calendar.dateModule;
+							
+							if(view == colView){
+								start = calendar.floorDate(d, "minute", colView.timeSlotDuration);
+								end = cal.add(start, "minute", colView.timeSlotDuration); 
+							}else{
+								start = calendar.floorToDay(d);
+								end = cal.add(start, "day", 1);
+							}
+							
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: start,
+								endTime: end,
+								calendar: cal1 ? "cal1" : "cal2",
+								allDay: view.viewKind == "matrix"
+							};
+							
+							id++;	
+							
+							return item;							
+						};
+						
+						calendar.set("createOnGridClick", true);
+						calendar.set("createItemFunc", createItem);						
+						
+						// filter out event according to their calendar
+						var calendarVisibility = [true, true];
+						
+						var itemToRendererKindFunc = function(item){
+							if(item.cssClass == "Calendar1" && calendarVisibility[0] ||
+								item.cssClass == "Calendar2" && calendarVisibility[1]){
+									return this._defaultItemToRendererKindFunc(item);
+								}
+							return null
+						};
+						
+						calendar.columnView.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						calendar.columnView.secondarySheet.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						calendar.matrixView.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						
+						// show context menu on right clicking an event
+						calendar.on("itemContextMenu", function(e){
+							dojo.stopEvent(e.triggerEvent);
+							calendarContextMenu._openMyself({ 
+								target: e.renderer.domNode, 
+								coords: {x: e.triggerEvent.pageX, y: e.triggerEvent.pageY} 
+							});
+						});
+						
+						contextMenuDelete.on("click", function(){
+							arr.forEach(calendar.selectedItems, function(item){
+								calendar.store.remove(item.id);
+							}); 							
+						});
+						
+						// refresh item panel on event selection.
+						var editedItem;
+						
+						var selectionChanged = function(item){
+							
+							var itemNull = item == null;
+							
+							var widgets = [itemSummaryEditor, itemStartDateEditor, itemStartTimeEditor, itemEndDateEditor,
+								itemEndTimeEditor, calendarEditor, allDayCB, deleteItemButton, updateItemButton];
+							
+							arr.forEach(widgets, function(w){
+								w.set("disabled", itemNull);
+								w.set("value", null, false);
+							});
+							
+							editedItem = itemNull ? null : lang.mixin({}, item); 
+							
+							if(!itemNull){
+							
+								var allDay = item.allDay === true;
+								
+								itemStartTimeEditor.set("disabled", allDay);
+								itemEndTimeEditor.set("disabled", allDay);
+																
+								itemSummaryEditor.set("value", item.summary);
+								itemStartDateEditor.set("value", item.startTime);
+								itemStartTimeEditor.set("value", item.startTime);
+								itemEndDateEditor.set("value", item.endTime);
+								itemEndTimeEditor.set("value", item.endTime);
+								calendarEditor.set("value", item.calendar == "cal1" ? "Calendar 1" : "Calendar 2");																					
+								allDayCB.set("checked", allDay, false);
+							}																						
+						};
+						
+						calendar.on("change", function(e){							
+							selectionChanged(e.newValue);							
+						});	
+						
+						calendar.on("itemEditEnd", function(e){
+							selectionChanged(e.item);
+						});
+						
+						// configure item properties panel
+						calendar.on("timeIntervalChange", function(e){
+							datePicker.set("currentFocus", e.startTime, false);							
+							datePicker.set("minDate", e.startTime);
+							datePicker.set("maxDate", e.endTime);
+							datePicker._populateGrid();
+						});
+						
+						allDayCB.on("change", function(value){
+							
+							itemStartTimeEditor.set("disabled", value);
+							itemEndTimeEditor.set("disabled", value);
+							
+							var d;
+							if(value){
+								d = itemStartTimeEditor.get("value");
+								calendar.floorToDay(d, true);
+								itemStartTimeEditor.set("value", d);
+								d = itemEndTimeEditor.get("value");
+								calendar.floorToDay(d, true);
+								itemEndTimeEditor.set("value", d);
+								
+								if(!calendar.isStartOfDay(editedItem.endTime)){
+									d = itemEndDateEditor.get("value");
+									calendar.floorToDay(d, true);
+									d = calendar.dateModule.add(d, "day", 1);
+									itemEndDateEditor.set("value", d);
+								}
+								
+							}else{
+								editedItem.startTime.setHours(8);
+								editedItem.endTime.setHours(9);
+								itemStartTimeEditor.set("value", editedItem.startTime);
+								itemEndTimeEditor.set("value", editedItem.endTime);
+								d = itemEndDateEditor.get("value");
+								calendar.floorToDay(d, true);
+								d = calendar.dateModule.add(d, "day", -1);
+								itemEndDateEditor.set("value", d);
+							}
+							
+						});
+						
+						var mergeDateTime = function(isStart){
+							var dateEditor = isStart ? itemStartDateEditor : itemEndDateEditor;
+							var timeEditor = isStart ? itemStartTimeEditor : itemEndTimeEditor;
+							var date = dateEditor.get("value");
+							var time = timeEditor.get("value");
+							date.setHours(time.getHours());
+							date.setMinutes(time.getMinutes());
+							return date;
+						};
+						
+						updateItemButton.on("click", function(value){
+							
+							if (editedItem != null) {
+								editedItem.summary = itemSummaryEditor.get("value");
+								if(allDayCB.get("value")){
+									if(!calendar.isStartOfDay(editedItem.startTime)){
+										editedItem.startTime = calendar.floorToDay(itemStartDateEditor.get("value"), true);
+									}
+									if(!calendar.isStartOfDay(editedItem.endTime)){
+										editedItem.endTime = calendar.floorToDay(itemEndDateEditor.get("value"), true);
+									}			
+									editedItem.allDay = true;						
+								}else{
+									editedItem.startTime = mergeDateTime(true);
+									editedItem.endTime = mergeDateTime(false);
+									delete editedItem.allDay;
+								}
+								
+								var calValue = calendarEditor.get("value");
+								editedItem.calendar = calValue == "Calendar 1" ? "cal1" : "cal2";
+								calendar.store.put(editedItem);
+							}
+							
+						});
+						
+						deleteItemButton.on("click", function(value){
+							if (editedItem != null) {
+								calendar.store.remove(editedItem.id);
+							}
+						});
+																										
+						// Synchronize date picker.																	
+						datePicker.set("value", startOfWeek);
+						datePicker.on("change", function(e){
+							var d = datePicker.get("value");
+							calendar.set("date", d);
+						});						
+										
+						calendar1CB.on("change", function(v){
+							calendarVisibility[0] = v;
+							calendar.currentView.invalidateLayout();
+						});
+						
+						calendar2CB.on("change", function(v){
+							calendarVisibility[1] = v;
+							calendar.currentView.invalidateLayout();
+						});											
+						
+						// Hide loading panel when application is ready
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+						
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+			
+			<div data-dojo-type="dijit.layout.BorderContainer" style="width:100%;height:100%" data-dojo-props="design:'sidebar', gutters:true" >
+		    <div data-dojo-type="dijit.layout.ContentPane" style="width:200px" data-dojo-props="splitter:false, region:'leading'">
+		        <div data-dojo-id="datePicker" data-dojo-type="demo.DatePicker" style="width:100%"></div>
+						<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'Calendars', style:'margin-top:10px;'" >
+							<div>
+								<input type="checkbox" data-dojo-id="calendar1CB" data-dojo-type="dijit.form.CheckBox" checked="true"/>
+								<label for="calendar1CB">Calendar 1</label>
+							</div>
+									
+							<div style="margin-top:5px">
+								<input type="checkbox" data-dojo-id="calendar2CB" data-dojo-type="dijit.form.CheckBox" checked="true"/>
+								<label for="calendar2CB">Calendar 2</label>
+							</div>
+						</div>
+						<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'Event properties', style:'margin-top:10px;'" >
+							<div><span class="propertyTitle">Summary:</span></div>
+							<div data-dojo-id="itemSummaryEditor" data-dojo-type="dijit.form.TextBox" style="width:165px;" data-dojo-props="disabled:true"></div>
+							<div style="margin-top:10px"><span class="propertyTitle">Start:</span></div>
+							<div>
+								<div data-dojo-id="itemStartDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:90px;"  data-dojo-props="disabled:true"></div>
+								<div data-dojo-id="itemStartTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:70px;" data-dojo-props="disabled:true" ></div>
+							</div>
+							<div style="margin-top:10px"><span class="propertyTitle">End:</span></div>
+							<div>
+								<div data-dojo-id="itemEndDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:90px;" data-dojo-props="disabled:true" ></div>
+								<div data-dojo-id="itemEndTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:70px;" data-dojo-props="disabled:true" ></div>
+							</div>
+							<div style="margin-top:10px"><span class="propertyTitle">Calendar:</span></div>
+							<select data-dojo-id="calendarEditor" data-dojo-type="dijit.form.ComboBox"  style="width:165px;" data-dojo-props="disabled:true" >
+								<option>Calendar 1</option>
+								<option>Calendar 2</option>									
+							</select>
+							<div style="margin-top:10px">
+								<input type="checkbox" data-dojo-id="allDayCB" data-dojo-type="dijit.form.CheckBox" checked="false" data-dojo-props="disabled:true" />
+								<label for="allDayCB">All day</label>
+							</div>	
+							<div style="margin-top:10px; text-align:right">
+								<span style="text-align:left">
+									<button data-dojo-id="deleteItemButton" class="deleteButton" data-dojo-type="dijit.form.Button"  data-dojo-props="disabled:true">Delete</button>
+								</span>
+								<span style="text-align:right">
+									<button data-dojo-id="updateItemButton" data-dojo-type="dijit.form.Button" data-dojo-props="disabled:true" >Update</button>
+								</span>
+							</div>
+						</div>
+		    </div>
+		    <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="splitter:false, region:'center'">
+		        <div data-dojo-id="calendar" data-dojo-type="dojox.calendar.Calendar" 
+					style="position:absolute;left:10px;top:10px;bottom:30px;right:10px">
+					<div data-dojo-type="dijit.Menu" data-dojo-id="calendarContextMenu" style="display: none;">
+		                <div data-dojo-type="dijit.MenuItem" data-dojo-id="contextMenuDelete" data-dojo-props="iconClass:'dijitIcon dijitIconDelete'">Delete</div>
+		            </div>	
+				</div>
+				<div id="hint" style="position:absolute;left:10px;height:15px;bottom:10px;right:10px;color:#999;overflow:auto"></div>
+		    </div>
+		    
+		</div>																		
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/calendarItemEvents.html b/dojox/calendar/tests/calendarItemEvents.html
new file mode 100644
index 0000000..92e86eb
--- /dev/null
+++ b/dojox/calendar/tests/calendarItemEvents.html
@@ -0,0 +1,183 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Calendar Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/Calendar.css";
+			@import "calendar.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			html{
+				font-family: Lucida grande, Tahoma, Verdana, Arial, Sans-serif;
+			}
+			#calendarNode {
+		      position:absolute;
+		      left: 10px;
+		      right: 10px;
+		      top: 10px;
+		      bottom: 10px;
+		    } 
+		</style>			
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/_base/declare", "dojo/ready", "dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/array", "dojo/_base/fx", "dojo/dom-class", "dojo/on", 
+			         "dojo/date/locale", "dojo/parser",	"dojo/dom", "dojo/dom-construct",	"dojo/store/Memory", 
+			         "dojo/store/Observable",	"dojox/calendar/Calendar", "dijit/Menu", "dijit/MenuItem"],
+
+				function(declare, ready, lang, has, arr, fx, domClass, on, locale, parser, dom, domConstruct,
+					Memory, Observable, Calendar){
+
+					ready(function(){
+																					
+						calendar.set("cssClassFunc", function(item){
+							// Use custom css class on renderers depending of a parameter (calendar).							
+							return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+						});
+						
+						// Calendar model creation						
+						var modelBase = [
+							{day: 1, start: [10,0], duration: 1400},
+							{day: 2, start: [10,30], duration: 120},
+							{day: 2, start: [12,0], duration: 240},
+							{day: 3, start: [6,0], duration: 180},
+							{day: 3, start: [0,0], duration: 2880, allDay: true}
+						];
+						
+						var someData = [];
+												
+						var startOfWeek = calendar.floorToWeek(new calendar.dateClassObj());
+						
+						for (var id=0; id<modelBase.length; id++) {
+							var newObj = {
+								id: id,
+								summary: "New Event " + id,
+								startTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								endTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								calendar: id%2 == 0 ? "cal1" : "cal2",
+								editable: true,
+								resizeEnabled: true,
+								moveEnabled:true,
+								allDay: modelBase[id].allDay
+							};
+
+							newObj.startTime = calendar.dateModule.add(newObj.startTime, "day", modelBase[id].day);
+							newObj.startTime.setHours(modelBase[id].start[0]);
+							newObj.startTime.setMinutes(modelBase[id].start[1]);
+
+							newObj.endTime = calendar.dateModule.add(newObj.startTime, "minute", modelBase[id].duration);
+
+							someData.push(newObj);
+						}
+						
+						var store = new Observable(new Memory({data: someData}));
+						calendar.set("store", store);
+						calendar.set("date", startOfWeek);
+						
+						// show context menu on right clicking an event
+						calendar.on("itemContextMenu", function(e){
+							dojo.stopEvent(e.triggerEvent);
+							console.log("itemContextMenu", e.item.summary);
+							if(e.item.calendar == undefined){
+								alert("itemContextMenu not ok");
+							}
+						});
+						
+						calendar.on("itemClick", function(e){
+							console.log("itemClick", e.item.summary);
+							if(e.item.calendar == undefined){
+								alert("itemClick not ok");
+							}
+						});
+						calendar.on("itemDoubleClick", function(e){
+							console.log("itemDoubleClick", e.item.summary);
+							if(e.item.calendar == undefined){
+								alert("itemDoubleClick not ok");
+							}
+						});
+						calendar.on("itemRollOver", function(e){
+							console.log("itemRollOver", e.item.summary);
+							if(e.item.calendar == undefined){
+								alert("itemRollOver not ok");
+							}
+						});
+						calendar.on("itemRollOut", function(e){
+							console.log("itemRollOut", e.item.summary);
+							if(e.item.calendar == undefined){
+								alert("itemRollOut not ok");
+							}
+						});
+						
+						// editing events
+						calendar.on("itemEditBegin", function(e){
+							console.log("itemEditBegin", e.storeItem.summary);
+							if(e.storeItem.calendar == undefined){
+								alert("itemEditBegin not ok");
+							}
+						});
+						calendar.on("itemEditBeginGesture", function(e){
+							console.log("itemEditBeginGesture", e.storeItem.summary);
+							if(e.storeItem.calendar == undefined){
+								alert("itemEditBeginGesture not ok");
+							}
+						});
+						calendar.on("itemEditMoveGesture", function(e){
+							console.log("itemEditMoveGesture", e.storeItem.summary);
+							if(e.storeItem.calendar == undefined){
+								alert("itemEditMoveGesture not ok");
+							}
+						});
+						calendar.on("itemEditResizeGesture", function(e){
+							console.log("itemEditResizeGesture", e.storeItem.summary);
+							if(e.storeItem.calendar == undefined){
+								alert("itemEditResizeGesture not ok");
+							}
+						});
+						calendar.on("itemEditEndGesture", function(e){
+							console.log("itemEditEndGesture", e.storeItem.summary);
+							if(e.storeItem.calendar == undefined){
+								alert("itemEditEndGesture not ok");
+							}
+						});
+						calendar.on("itemEditEnd", function(e){
+							console.log("itemEditEnd", e.storeItem.summary);
+							if(e.storeItem.calendar == undefined){
+								alert("itemEditEnd not ok");
+							}
+						});
+																						
+						// Hide loading panel when application is ready
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+																																
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+  			<div id="calendarNode" data-dojo-id="calendar" data-dojo-type="dojox.calendar.Calendar">
+  				<div data-dojo-type="dijit.Menu" data-dojo-id="calendarContextMenu" style="display: none;">
+					<div data-dojo-type="dijit.MenuItem" data-dojo-id="contextMenuEditable" >Useless menu item</div>
+				</div>
+			</div>
+			
+		    
+		</div>																		
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/calendarMonthView.html b/dojox/calendar/tests/calendarMonthView.html
new file mode 100644
index 0000000..bb4035a
--- /dev/null
+++ b/dojox/calendar/tests/calendarMonthView.html
@@ -0,0 +1,454 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Calendar Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/Calendar.css";
+			@import "../themes/claro/MonthColumnView.css";
+			@import "calendar.css";			
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>			
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true, paths : {'demo' : '../dojox/calendar/tests'}"
+		 				src="../../../dojo/dojo.js"></script>
+		
+		<script type="text/javascript">
+
+			require([
+				"dojo/ready",  
+				"dojo/_base/lang", 
+				"dojo/_base/array", 
+				"dojo/_base/fx", 
+				"dojo/on", 
+				"dojo/date/locale", 
+				"dojo/parser",
+				"dojo/dom", 
+				"dojo/dom-construct", 
+				"dojo/store/Memory", 
+				"dojo/store/Observable",	
+				"demo/ExtendedCalendar", 
+				"dijit/Calendar",  
+				"dijit/TitlePane", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dijit/form/CheckBox", 
+				"dijit/form/TextBox", 
+				"dijit/form/DateTextBox",	
+				"dijit/form/TimeTextBox", 
+				"dijit/form/Button", 
+				"dijit/form/ComboBox",
+				"dijit/Menu", 
+				"dijit/MenuItem"
+			],
+			
+			function(
+				ready, 
+				lang, 
+				arr, 
+				fx, 
+				on, 
+				locale, 
+				parser, 
+				dom, 
+				domConstruct,
+				Memory, 
+				Observable, 
+				ExtendedCalendar){
+
+					ready(function(){
+										
+						var hints = [
+							"Hint: Create an event by clicking and dragging on the grid while maintaining the control key",
+							"Hint: Drill down the view by clicking row or column header cells",
+							"Hint: Drill down the view by double-clicking a grid cell while maintaining the shift and control key",
+							"Hint: Drill up by double-clicking the grid while maintaining the shift key",
+							"Hint: Move an event by clicking on it and dragging it",
+							"Hint: Resize an event by clicking on one of its ends and dragging it"
+						];
+						
+						var hintIdx = 0;
+						dom.byId("hint").innerHTML = hints[0];
+												
+						setInterval(function(){
+							fx.fadeOut({node: "hint", 
+								onEnd: function(){
+									hintIdx = hintIdx+1>hints.length-1 ? 0 : hintIdx+1;
+									dom.byId("hint").innerHTML = hints[hintIdx];
+									fx.fadeIn({node: "hint"}).play(500); 									
+								}
+							}).play(500);
+						}, 10000);
+																	
+						calendar.set("cssClassFunc", function(item){
+							// Use custom css class on renderers depending of a parameter (calendar). 
+							return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+						});
+						
+						// Calendar model creation
+						
+						var modelBase = [
+							{day: 1, start: [10,0], duration: 1400},
+							{day: 2, start: [10,30], duration: 120},
+							{day: 2, start: [12,0], duration: 240},
+							{day: 3, start: [6,0], duration: 180},
+							{day: 3, start: [0,0], duration: 2880, allDay: true}
+						];
+						
+						var someData = [];
+												
+						var startOfWeek = calendar.floorToWeek(new calendar.dateClassObj());
+						
+						for (var id=0; id<modelBase.length; id++) {
+							var newObj = {
+								id: id,
+								summary: "New Event " + id,
+								startTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								endTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								calendar: id%2 == 0 ? "cal1" : "cal2",
+								allDay: modelBase[id].allDay
+							};
+
+							newObj.startTime = calendar.dateModule.add(newObj.startTime, "day", modelBase[id].day);
+							newObj.startTime.setHours(modelBase[id].start[0]);
+							newObj.startTime.setMinutes(modelBase[id].start[1]);
+
+							newObj.endTime = calendar.dateModule.add(newObj.startTime, "minute", modelBase[id].duration);
+
+							someData.push(newObj);
+						}
+						
+						calendar.set("store", new Observable(new Memory({data: someData})));
+						calendar.set("date", startOfWeek);
+						
+						calendar.on("gridDoubleClick", function(e){
+							
+							if(e.triggerEvent.ctrlKey && e.triggerEvent.shiftKey){
+								// drill down
+								calendar.set("date", e.date);
+								calendar.set("dateIntervalSteps", 1);
+								calendar.set("dateInterval", "day");								
+								return;
+							}
+							
+							if(e.triggerEvent.shiftKey){
+								// drill up								
+								var dis = calendar.get("dateIntervalSteps");
+								var di = calendar.get("dateInterval");
+								var d = e.date;
+								switch(e.source.viewKind){
+									case "columns":
+										if(dis == 1){
+											di = "day";
+											dis = 7;
+											d = calendar.floorToWeek(e.date);
+										}else{
+											di = "month";
+											dis = 1;
+										}																			
+										break;
+									case "matrix":
+										di = "month";
+										dis = 6;
+										break;																										
+								}
+								calendar.set("date", e.date);
+								calendar.set("dateIntervalSteps", dis);
+								calendar.set("dateInterval", di);
+							}
+									
+						});
+						
+						// Enable creation of event interactively by ctrl clicking grid.
+						var createItem = function(view, d, e){
+						
+							var cal1 = calendar1CB.get("checked");
+							var cal2 = calendar2CB.get("checked");
+						
+							// create item by maintaining control key
+							if(!e.ctrlKey || e.shiftKey || e.altKey || (!cal1 && !cal2)){
+								return null;
+							}
+						
+							// create a new event
+							var start, end;
+							var colView = calendar.columnView;
+							var cal = calendar.dateModule;
+							
+							if(view == colView){
+								start = calendar.floorDate(d, "minute", colView.timeSlotDuration);
+								end = cal.add(start, "minute", colView.timeSlotDuration); 
+							}else{
+								start = calendar.floorToDay(d);
+								end = cal.add(start, "day", 1);
+							}
+							
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: start,
+								endTime: end,
+								calendar: cal1 ? "cal1" : "cal2",
+								allDay: view.viewKind != "columns" // use viewKind to manage secondary sheet of columns view
+							};
+							
+							id++;	
+							
+							return item;							
+						};
+						
+						calendar.set("createOnGridClick", true);
+						calendar.set("createItemFunc", createItem);		
+						
+						// filter out event according to their calendar
+						var calendarVisibility = [true, true];
+						
+						var itemToRendererKindFunc = function(item){
+							if(item.cssClass == "Calendar1" && calendarVisibility[0] ||
+								item.cssClass == "Calendar2" && calendarVisibility[1]){
+									return this._defaultItemToRendererKindFunc(item);
+								}
+							return null
+						};
+						
+						calendar.columnView.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						calendar.columnView.secondarySheet.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						calendar.matrixView.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						calendar.monthColumnView.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						
+						// show context menu on right clicking an event
+						calendar.on("itemContextMenu", function(e){
+							dojo.stopEvent(e.triggerEvent);
+							calendarContextMenu._openMyself({ 
+								target: e.renderer.domNode, 
+								coords: {x: e.triggerEvent.pageX, y: e.triggerEvent.pageY} 
+							});
+						});
+						
+						contextMenuDelete.on("click", function(){
+							arr.forEach(calendar.selectedItems, function(item){
+								calendar.store.remove(item.id);
+							}); 							
+						});
+						
+						// refresh item panel on event selection.
+						var editedItem;
+						
+						var selectionChanged = function(item){
+							
+							var itemNull = item == null;
+							
+							var widgets = [itemSummaryEditor, itemStartDateEditor, itemStartTimeEditor, itemEndDateEditor,
+								itemEndTimeEditor, calendarEditor, allDayCB, deleteItemButton, updateItemButton];
+							
+							arr.forEach(widgets, function(w){
+								w.set("disabled", itemNull);
+								w.set("value", null, false);
+							});
+							
+							editedItem = itemNull ? null : lang.mixin({}, item); 
+							
+							if(!itemNull){
+							
+								var allDay = item.allDay === true;
+								
+								itemStartTimeEditor.set("disabled", allDay);
+								itemEndTimeEditor.set("disabled", allDay);
+																
+								itemSummaryEditor.set("value", item.summary);
+								itemStartDateEditor.set("value", item.startTime);
+								itemStartTimeEditor.set("value", item.startTime);
+								itemEndDateEditor.set("value", item.endTime);
+								itemEndTimeEditor.set("value", item.endTime);
+								calendarEditor.set("value", item.calendar == "cal1" ? "Calendar 1" : "Calendar 2");																					
+								allDayCB.set("checked", allDay, false);
+							}																						
+						};
+						
+						calendar.on("change", function(e){							
+							selectionChanged(e.newValue);							
+						});	
+						
+						calendar.on("itemEditEnd", function(e){
+							selectionChanged(e.item);
+						});
+						
+						// configure item properties panel
+						calendar.on("timeIntervalChange", function(e){
+							dateChooser.set("value", e.startTime, false);
+						});
+						
+						allDayCB.on("change", function(value){
+							
+							itemStartTimeEditor.set("disabled", value);
+							itemEndTimeEditor.set("disabled", value);
+							
+							var d;
+							if(value){
+								d = itemStartTimeEditor.get("value");
+								calendar.floorToDay(d, true);
+								itemStartTimeEditor.set("value", d);
+								d = itemEndTimeEditor.get("value");
+								calendar.floorToDay(d, true);
+								itemEndTimeEditor.set("value", d);
+								
+								if(!calendar.isStartOfDay(editedItem.endTime)){
+									d = itemEndDateEditor.get("value");
+									calendar.floorToDay(d, true);
+									d = calendar.dateModule.add(d, "day", 1);
+									itemEndDateEditor.set("value", d);
+								}
+								
+							}else{
+								editedItem.startTime.setHours(8);
+								editedItem.endTime.setHours(9);
+								itemStartTimeEditor.set("value", editedItem.startTime);
+								itemEndTimeEditor.set("value", editedItem.endTime);
+								d = itemEndDateEditor.get("value");
+								calendar.floorToDay(d, true);
+								d = calendar.dateModule.add(d, "day", -1);
+								itemEndDateEditor.set("value", d);
+							}
+							
+						});
+						
+						var mergeDateTime = function(isStart){
+							var dateEditor = isStart ? itemStartDateEditor : itemEndDateEditor;
+							var timeEditor = isStart ? itemStartTimeEditor : itemEndTimeEditor;
+							var date = dateEditor.get("value");
+							var time = timeEditor.get("value");
+							date.setHours(time.getHours());
+							date.setMinutes(time.getMinutes());
+							return date;
+						};
+						
+						updateItemButton.on("click", function(value){
+							
+							if (editedItem != null) {
+								editedItem.summary = itemSummaryEditor.get("value");
+								if(allDayCB.get("value")){
+									if(!calendar.isStartOfDay(editedItem.startTime)){
+										editedItem.startTime = calendar.floorToDay(itemStartDateEditor.get("value"), true);
+									}
+									if(!calendar.isStartOfDay(editedItem.endTime)){
+										editedItem.endTime = calendar.floorToDay(itemEndDateEditor.get("value"), true);
+									}			
+									editedItem.allDay = true;						
+								}else{
+									editedItem.startTime = mergeDateTime(true);
+									editedItem.endTime = mergeDateTime(false);
+									delete editedItem.allDay;
+								}
+								
+								var calValue = calendarEditor.get("value");
+								editedItem.calendar = calValue == "Calendar 1" ? "cal1" : "cal2";
+								calendar.store.put(editedItem);
+							}
+							
+						});
+						
+						deleteItemButton.on("click", function(value){
+							if (editedItem != null) {
+								calendar.store.remove(editedItem.id);
+							}
+						});
+																										
+						// Synchronize date picker.															
+						dateChooser.set("value", startOfWeek);
+						dateChooser.on("change", function(e){
+							var d = dateChooser.get("value");
+							calendar.set("date", d);
+						});						
+										
+						calendar1CB.on("change", function(v){
+							calendarVisibility[0] = v;
+							calendar.currentView.invalidateLayout();
+						});
+						
+						calendar2CB.on("change", function(v){
+							calendarVisibility[1] = v;
+							calendar.currentView.invalidateLayout();
+						});											
+						
+						// Hide loading panel when application is ready
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+			
+			<div data-dojo-type="dijit.layout.BorderContainer" style="width:100%;height:100%" data-dojo-props="design:'sidebar', gutters:true" >
+		    <div data-dojo-type="dijit.layout.ContentPane" style="width:200px" data-dojo-props="splitter:false, region:'leading'">
+		        <div data-dojo-id="dateChooser" data-dojo-type="dijit.Calendar" style="width:100%"></div>
+						<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'Calendars', style:'margin-top:10px;'" >
+							<div>
+								<input type="checkbox" data-dojo-id="calendar1CB" data-dojo-type="dijit.form.CheckBox" checked="true"/>
+								<label for="calendar1CB">Calendar 1</label>
+							</div>
+									
+							<div style="margin-top:5px">
+								<input type="checkbox" data-dojo-id="calendar2CB" data-dojo-type="dijit.form.CheckBox" checked="true"/>
+								<label for="calendar2CB">Calendar 2</label>
+							</div>
+						</div>
+						<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'Event properties', style:'margin-top:10px;'" >
+							<div><span class="propertyTitle">Summary:</span></div>
+							<div data-dojo-id="itemSummaryEditor" data-dojo-type="dijit.form.TextBox" style="width:165px;" data-dojo-props="disabled:true"></div>
+							<div style="margin-top:10px"><span class="propertyTitle">Start:</span></div>
+							<div>
+								<div data-dojo-id="itemStartDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:90px;"  data-dojo-props="disabled:true"></div>
+								<div data-dojo-id="itemStartTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:70px;" data-dojo-props="disabled:true" ></div>
+							</div>
+							<div style="margin-top:10px"><span class="propertyTitle">End:</span></div>
+							<div>
+								<div data-dojo-id="itemEndDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:90px;" data-dojo-props="disabled:true" ></div>
+								<div data-dojo-id="itemEndTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:70px;" data-dojo-props="disabled:true" ></div>
+							</div>
+							<div style="margin-top:10px"><span class="propertyTitle">Calendar:</span></div>
+							<select data-dojo-id="calendarEditor" data-dojo-type="dijit.form.ComboBox"  style="width:165px;" data-dojo-props="disabled:true" >
+								<option>Calendar 1</option>
+								<option>Calendar 2</option>									
+							</select>
+							<div style="margin-top:10px">
+								<input type="checkbox" data-dojo-id="allDayCB" data-dojo-type="dijit.form.CheckBox" checked="false" data-dojo-props="disabled:true" />
+								<label for="allDayCB">All day</label>
+							</div>	
+							<div style="margin-top:10px; text-align:right">
+								<span style="text-align:left">
+									<button data-dojo-id="deleteItemButton" class="deleteButton" data-dojo-type="dijit.form.Button"  data-dojo-props="disabled:true">Delete</button>
+								</span>
+								<span style="text-align:right">
+									<button data-dojo-id="updateItemButton" data-dojo-type="dijit.form.Button" data-dojo-props="disabled:true" >Update</button>
+								</span>
+							</div>
+						</div>
+		    </div>
+		    <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="splitter:false, region:'center'">
+		        <div data-dojo-id="calendar" data-dojo-type="demo.ExtendedCalendar" 
+					style="position:absolute;left:10px;top:10px;bottom:30px;right:10px">
+					<div data-dojo-type="dijit.Menu" data-dojo-id="calendarContextMenu" style="display: none;">
+		                <div data-dojo-type="dijit.MenuItem" data-dojo-id="contextMenuDelete" data-dojo-props="iconClass:'dijitIcon dijitIconDelete'">Delete</div>
+		            </div>	
+			    </div>
+	   	        <div id="hint" style="position:absolute;left:10px;height:15px;bottom:10px;right:10px;color:#999;overflow:auto"></div> 
+	
+			</div>																							
+		</div>																		
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/calendarStyleGridCell.html b/dojox/calendar/tests/calendarStyleGridCell.html
new file mode 100644
index 0000000..99aaa62
--- /dev/null
+++ b/dojox/calendar/tests/calendarStyleGridCell.html
@@ -0,0 +1,84 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Calendar Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/Calendar.css";
+			@import "../themes/claro/MonthColumnView.css";
+			@import "calendar.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			.greyCell{
+				background-color: #F8F8F8 !important;				
+			}
+		</style>			
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+				data-dojo-config="async: true, parseOnLoad: true, paths : {'demo' : '../dojox/calendar/tests'}"
+		 		src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/array", "dojo/_base/fx", "dojo/dom-class", "dojo/on", 
+			         "dojo/date/locale", "dojo/parser",	"dojo/dom", "dojo/dom-construct",	"dojo/store/Memory", 
+			         "dojo/store/Observable",	"demo/ExtendedCalendar"],
+
+				function(ready, lang, has, arr, fx, domClass, on, locale, parser, dom, domConstruct,
+					Memory, Observable, Calendar){
+
+					ready(function(){
+			
+						var startOfWeek = calendar.floorToWeek(new calendar.dateClassObj());
+						
+						calendar.set("date", startOfWeek);
+						
+						calendar.columnView.set("styleGridCellFunc", function(node, date, hours, minutes){
+							// grey out Wednesday & time range between 12pm and 2pm
+							if(hours >= 12 && hours < 14 || date.getDay() == 3){
+								domClass.add(node, "greyCell");
+							}
+							this.defaultStyleGridCell(node, date, hours, minutes);
+						});
+						
+						var func = function(node, date){
+							// grey out Wednesday
+							if(date != null && date.getDay() == 3){
+								domClass.add(node, "greyCell");
+							}
+							this.defaultStyleGridCell(node, date);
+						};
+						
+						calendar.columnView.secondarySheet.set("styleGridCellFunc", func);				
+						calendar.matrixView.set("styleGridCellFunc", func);						
+						calendar.monthColumnView.set("styleGridCellFunc", func);											
+						
+						// Hide loading panel when application is ready
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+						
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+			
+	        <div data-dojo-id="calendar" data-dojo-type="demo.ExtendedCalendar" 
+				style="position:absolute;left:10px;top:10px;bottom:10px;right:10px">
+			</div>				
+		    
+		</div>																		
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/calendarStyleGridCellCSS.html b/dojox/calendar/tests/calendarStyleGridCellCSS.html
new file mode 100644
index 0000000..4ec5d75
--- /dev/null
+++ b/dojox/calendar/tests/calendarStyleGridCellCSS.html
@@ -0,0 +1,67 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Calendar Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/Calendar.css";
+			@import "../themes/claro/MonthColumnView.css";
+			@import "calendar.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+
+			.dojoxCalendar .dojoxCalendarGrid .Wed, 
+			.dojoxCalendar .dojoxCalendarGrid .H12,
+			.dojoxCalendar .dojoxCalendarGrid .H13	{
+				background-color: #F8F8F8 !important;
+			}
+		</style>			
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+				data-dojo-config="async: true, parseOnLoad: true, paths : {'demo' : '../dojox/calendar/tests'}"
+		 		src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/array", "dojo/_base/fx", "dojo/dom-class", "dojo/on", 
+			         "dojo/date/locale", "dojo/parser",	"dojo/dom", "dojo/dom-construct",	"dojo/store/Memory", 
+			         "dojo/store/Observable",	"demo/ExtendedCalendar"],
+
+				function(ready, lang, has, arr, fx, domClass, on, locale, parser, dom, domConstruct,
+					Memory, Observable, Calendar){
+
+					ready(function(){
+			
+						var startOfWeek = calendar.floorToWeek(new calendar.dateClassObj());
+						
+						calendar.set("date", startOfWeek);																	
+						
+						// Hide loading panel when application is ready
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+						
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+			
+	        <div data-dojo-id="calendar" data-dojo-type="demo.ExtendedCalendar" 
+				style="position:absolute;left:10px;top:10px;bottom:10px;right:10px">
+			</div>				
+		    
+		</div>																		
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/columntablet.css b/dojox/calendar/tests/columntablet.css
new file mode 100644
index 0000000..107ec0d
--- /dev/null
+++ b/dojox/calendar/tests/columntablet.css
@@ -0,0 +1,12 @@
+html, body {
+    margin: 0;
+    padding: 0;
+    width: 100%;
+    height: 100%;
+}
+
+#calendarNode {
+    width:640px;
+    height:640px;
+}
+
diff --git a/dojox/calendar/tests/columntablet.html b/dojox/calendar/tests/columntablet.html
new file mode 100644
index 0000000..9e69a79
--- /dev/null
+++ b/dojox/calendar/tests/columntablet.html
@@ -0,0 +1,164 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html debug="true">
+		<head>
+				<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+				<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+				<meta name="apple-mobile-web-app-capable" content="yes" />
+				<title>ColumnView Sample: Tablet</title>
+				<style type="text/css">
+						@import "../themes/iphone/ColumnView.css";
+						@import "../../../dojo/resources/dojo.css";
+						@import "../../../dijit/themes/dijit.css";
+						@import "../../../dijit/themes/claro/claro.css";
+						@import "columntablet.css";
+				</style>				
+		</head>
+		<body>
+				<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		 				
+				<script type="text/javascript">
+					
+						require(["dojo/ready", "dojo/_base/declare",
+				"dojo/on", "dojo/date/locale", "dojox/mobile", 
+				"dojo/date", "dojo/dom", "dojo/dom-construct", "dojo/_base/window", 
+				"dojox/mobile/CheckBox", "dojox/calendar/ColumnView", "dojox/calendar/ColumnViewSecondarySheet", "dojox/calendar/Touch", "dojox/calendar/MobileVerticalRenderer",
+				"dojox/calendar/HorizontalRenderer", "dojox/calendar/ExpandRenderer",
+				"dojo/store/Memory", "dojo/store/Observable", "dojox/gesture/swipe"],
+				 
+				function(ready, declare, on, locale, mobile, date, dom, domConstruct, win,
+					CheckBox, ColumnView, ColumnViewSecondarySheet, CalendarTouch, MobileVerticalRenderer, HorizontalRenderer, ExpandRenderer, Memory, Observable, swipe){
+							ready(function(){
+								
+								var dateClassObj = Date;
+								var modelBase = [
+									{	day: 1,	start: [0, 0], duration: 1440, allDay: true	}, 
+									{	day: 2,	start: [10, 0], duration: 270	},
+									{	day: 2,	start: [12, 0],	duration: 240	}
+								];
+								
+								var someData = [];
+								var startOfWeek = new dateClassObj();
+								startOfWeek.setHours(0);
+								startOfWeek.setMinutes(0);
+								startOfWeek.setSeconds(0);
+								startOfWeek.setMilliseconds(0);
+								startOfWeek = date.add(startOfWeek, "day", -startOfWeek.getDay());
+								
+								for (var i = 0; i < modelBase.length; i++) {
+									var newObj = {
+										id: i,
+										summary: "New Event " + i,
+										startTime: new dateClassObj(startOfWeek.getTime()),
+										endTime: new dateClassObj(startOfWeek.getTime()),
+										allDay: modelBase[i].allDay
+									};
+									newObj.startTime = date.add(newObj.startTime, "day", modelBase[i].day);
+									newObj.startTime.setHours(modelBase[i].start[0]);
+									newObj.startTime.setMinutes(modelBase[i].start[1]);
+									newObj.endTime = date.add(newObj.startTime, "minute", modelBase[i].duration);
+									someData.push(newObj);
+								}
+								
+																
+								var id = i;
+								var secondarySheetClass = declare([ColumnViewSecondarySheet, CalendarTouch]);
+								colView = declare([ColumnView, CalendarTouch])({
+									secondarySheetClass: secondarySheetClass,
+									store: new Observable(new Memory({
+												data: someData
+											})),
+									verticalRenderer: MobileVerticalRenderer,
+									horizontalRenderer: HorizontalRenderer,
+									expandRenderer: ExpandRenderer,
+									columnCount: 5,
+									hourSize: 75,
+									maxHours: 22,
+									timeSlotDuration: 30
+								}, "calendarNode");
+								
+								window.onresize = window.onorientationchange = function(e){
+									var n = colView.domNode;
+									if(n.offsetWidth > n.offsetHeight){
+										colView.set("columnCount", 5);
+									}else{
+										colView.set("columnCount", 1);
+									}
+								};
+								
+								window.onresize();								
+								
+								var goNextRange = function(direction){
+									var days = (direction == "left" ? 1 : -1) * colView.get("columnCount");
+									var startDate = colView.get("startDate");									
+									var newStartDate = colView.renderData.dateModule.add(startDate, "day", days);									
+									colView.set("startDate", newStartDate);
+									
+									//TODO Add animation 
+								};
+								
+								on(colView.itemContainer, swipe.end, function(e){
+									if(e.time < 200 && Math.abs(e.dx) > 50){
+										goNextRange(e.dx < 0 ? "left" : "right");
+									}
+								});
+								
+								
+								colView.snapSteps = 15;
+								colView.liveLayout = false;
+								
+								var id=4;
+								colView.on("gridDoubleClick", function(e){
+
+									// create a event when double-clicking on grid.
+									var start, end;
+									if(e.sheet == "primary"){
+										start = colView.floorDate(e.date, "minute", colView.timeSlotDuration);
+										end = date.add(start, "hour", 1);
+									}else{
+										start = colView.floorToDay(e.date, false, colView.renderData);
+										end = date.add(start, "day", 1);
+									}
+		
+									var item = {
+										id: id,
+										summary: "New event " + id,
+										startTime: start,
+										endTime: end,
+										allDay: e.sheet == "secondary"
+									};
+									
+									id++;		
+									colView.store.add(item);
+									
+									colView.set("selectedItem", item);
+									colView.set("focusedItem", item);
+									
+								});
+								
+								var startDateSave;
+								var columnCountSave;
+								
+								colView.on("columnHeaderClick", function(e){
+									if (colView.get("columnCount") == 1) {
+										colView.set("startDate", startDateSave);
+										colView.set("columnCount", columnCountSave);
+									} else {
+										startDateSave = colView.get("startDate");
+										columnCountSave = colView.get("columnCount");
+										colView.set("startDate", e.date);
+										colView.set("columnCount", 1);
+									}
+								});
+
+								
+							});
+						});
+				</script>
+				
+				<div id="calendarNode">
+				</div>
+				
+		</body>
+</html>
diff --git a/dojox/calendar/tests/columnview.css b/dojox/calendar/tests/columnview.css
new file mode 100644
index 0000000..eec5fd6
--- /dev/null
+++ b/dojox/calendar/tests/columnview.css
@@ -0,0 +1,175 @@
+ .claro .dojoxCalendarColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+ 
+.claro .dojoxCalendarColumnView .dojoxCalendarCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+ 	-moz-user-select: none;
+	-webkit-user-select: none;
+	khtml-user-select: none;
+	user-select: none;
+	font-weight: bold;
+	border-radius: 5px;
+}
+
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent {
+	font-size: 90%;
+	font-family: Tahoma, serifSansSerifMonospace;
+}
+
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2 .bg {
+	background: #2095B4;
+}
+
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2.Hovered .bg {
+	background: #24A5C8;
+}
+
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2.Selected .bg {
+	background: #166B81;
+}
+
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2 .startTime {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #00768F;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: 1px solid #260000;
+  border-left: 1px solid #260000;
+  border-right: 1px solid #260000;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2.Focused .startTime {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #6c0000;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: dashed 1px #ffffff;
+  border-left: dashed 1px #ffffff;
+  border-right: dashed 1px #ffffff;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2.Hovered .startTime {
+  background-color: #0094B4;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2.Selected .startTime {
+  background-color: #005A6D;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Calendar2.Edited .startTime {
+  background-color: #0095b4;
+  border-top: dashed 1px #ffffff;
+  border-left: dashed 1px #ffffff;
+  border-right: dashed 1px #ffffff;
+}
+
+html, body {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+#formDiv {
+	position:absolute;
+	left:10px;					
+	width: 250px;
+	top: 0;
+	bottom: 0;
+	margin-bottom: 10px;
+	overflow-y: auto;
+}
+
+.formPanel {
+	width: 230px;
+	margin-top: 10px;
+}
+
+#formDiv table {
+	width: 100%;					
+}
+
+.formTable td:first-child {
+	text-align: right;
+	padding-right: 10px;
+	font-size: 0.9em;
+}
+
+.smallText {
+	font-size:0.9em;
+}
+
+.disabled{
+	color: #CCCCCC;
+}
+
+#calendarNode {
+	position:absolute; 
+	left:270px; 
+	right:10px; 
+	top:10px; 
+	bottom:120px;
+}
+
+#eventLogPane {
+	position:absolute; 
+	left:270px; 
+	right:10px; 
+	height: 100px;
+	bottom:10px;	
+}
+
+#logTableContainer{	
+	width:100%;
+	height:100%;
+	overflow-y:auto;	
+}
+
+#eventLogPane .dijitTitlePaneTitle{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: 20px
+}
+
+#eventLogPane .dijitTitlePaneContentOuter{
+	position: absolute;
+	left: 0; 
+	right: 0; 
+	top: 25px; 
+	bottom: 0;
+}
+
+#eventLogPane .dijitTitlePaneContentInner{
+	position: relative;
+	width: 100%; 
+	height: 100%; 
+	padding: 0;
+}
+
+#eventLogPane .dijitReset{
+	position: relative; 
+	width: 100%; 
+	height: 100%;
+}
+
+#eventLogPane .dijitArrowNode{
+	display: none;
+}
+
+#logTable{
+	width: 100%;	
+	position:relative;
+}
diff --git a/dojox/calendar/tests/columnview.html b/dojox/calendar/tests/columnview.html
new file mode 100644
index 0000000..0b7f7c1
--- /dev/null
+++ b/dojox/calendar/tests/columnview.html
@@ -0,0 +1,732 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" width="100%" height="100%">
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>ColumnView Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/ColumnView.css";
+			@import "../themes/claro/MatrixView.css";
+			@import "columnview.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>			
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/declare", "dojo/_base/fx", "dojo/on", "dojo/date/locale", "dojo/parser", "dojo/date", "dojo/_base/lang",
+					"dojo/dom", "dojo/dom-construct", "dojo/dom-class", "dojo/_base/window", "dijit/registry", "dojo/query", "dojox/calendar/ColumnView", 
+					"dojox/calendar/ColumnViewSecondarySheet", "dojox/calendar/Keyboard", "dojox/calendar/Mouse",	"dojox/calendar/VerticalRenderer", 
+					"dojox/calendar/HorizontalRenderer", "dojox/calendar/ExpandRenderer", "dojo/store/Memory", "dojo/store/Observable",
+					"dijit/form/VerticalSlider", "dijit/form/NumberSpinner", "dijit/form/ComboBox", "dijit/form/DateTextBox", "dijit/form/TimeTextBox", 
+					"dijit/form/TextBox", "dijit/form/Button", "dijit/TitlePane", "dijit/Tooltip", "dijit/form/CheckBox"],
+
+				function(ready, declare, fx,on, locale, parser, date, lang, dom, domConstruct, domClass, win, registry, query,
+					ColumnView, ColumnViewSecondarySheet, CalendarKeyboard, CalendarMouse, VerticalRenderer, HorizontalRenderer, ExpandRenderer, Memory, Observable, VerticalSlider, 
+					NumberSpinner, ComboBox, DateTextBox, TimeTextBox, TextBox, Button, TitlePane, Tooltip, CheckBox){
+
+					ready(function(){
+
+						// singleton
+						win.doc.appState = {
+							moveDisabledMap: {},
+							resizeDisabledMap: {}
+						};
+						
+						var mergeDateTime = function(isStart){
+							var dateEditor = isStart ? itemStartDateEditor : itemEndDateEditor;
+							var timeEditor = isStart ? itemStartTimeEditor : itemEndTimeEditor;
+							var date = dateEditor.get("value");
+							var time = timeEditor.get("value");
+							date.setHours(time.getHours());
+							date.setMinutes(time.getMinutes());
+							return date;
+						};
+						
+						var addLogEntry = function(name, content){
+							var tr = domConstruct.create("tr", null, dom.byId("logBody"), "first");
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(locale.format(new Date(), {selector:"time", timePattern:"h:mm:ss"})));
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(name));
+							td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(content));
+						};
+						// Calendar model creation
+						
+						var dateClassObj = Date;
+						
+						var modelBase = [
+							{day: 1, start: [10,0], duration: 1400},
+							{day: 2, start: [10,30], duration: 120},
+							{day: 2, start: [12,0], duration: 240},
+							{day: 3, start: [6,0], duration: 180},
+							{day: 3, start: [0,0], duration: 2880, allDay: true}
+						];
+						
+						// TODO manage first day of week
+						var floorToWeek= function(d){
+							d.setHours(0);
+							d.setMinutes(0);
+							d.setSeconds(0);
+							d.setMilliseconds(0);
+							d = date.add(d, "day", -d.getDay());
+							return d;
+						};
+						
+						var someData = [];
+						
+						var startOfWeek = new dateClassObj();
+						startOfWeek = floorToWeek(startOfWeek);
+						
+						startDateEditor.set("value", startOfWeek);
+						
+						for (var id=0; id<modelBase.length; id++) {
+							var newObj = {
+								id: id,
+								summary: "New Event " + id,
+								startTime: new dateClassObj(startOfWeek.getTime()),
+								endTime: new dateClassObj(startOfWeek.getTime()),
+								calendar: id%2 == 0 ? "cal1" : "cal2",
+								allDay: modelBase[id].allDay
+							};
+
+							newObj.startTime = date.add(newObj.startTime, "day", modelBase[id].day);
+							newObj.startTime.setHours(modelBase[id].start[0]);
+							newObj.startTime.setMinutes(modelBase[id].start[1]);
+
+							newObj.endTime = date.add(newObj.startTime, "minute", modelBase[id].duration);
+
+							someData.push(newObj);
+						}
+
+						
+						// Calendar creation & configuration
+						
+						var secondarySheetClass = declare([ColumnViewSecondarySheet, CalendarKeyboard, CalendarMouse]);
+						
+						colView = declare([ColumnView, CalendarKeyboard, CalendarMouse])({
+							store: new Observable(new Memory({data: someData})),
+							secondarySheetClass: secondarySheetClass,
+							secondarySheetArgs: {
+								horizontalRendererHeight: 18
+							},	
+							verticalRenderer: VerticalRenderer,
+							horizontalRenderer: HorizontalRenderer,
+							expandRenderer: ExpandRenderer,							
+							cssClassFunc: function(item){
+								return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+							},
+							isItemMoveEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.moveDisabledMap[item.id] !== true;
+							},
+							isItemResizeEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.resizeDisabledMap[item.id] !== true;
+							}
+						}, "calendarNode");
+
+						// Events management
+						
+						
+						colView.on("gridDoubleClick", function(e){
+
+							// create a event when double-clicking on grid.
+							var start, end;
+							if(e.sheet == "primary"){
+								start = colView.floorDate(e.date, "minute", colView.timeSlotDuration);
+								end = date.add(start, "hour", 1);
+							}else{
+								start = colView.floorToDay(e.date, false, colView.renderData);
+								end = date.add(start, "day", 1);
+							}
+
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: start,
+								endTime: end,
+								calendar: id % 2 == 0 ? "cal1" : "cal2",
+								allDay: e.sheet == "secondary"
+							};
+							
+							id++;		
+							colView.store.add(item);
+							
+							colView.set("selectedItem", item);
+							colView.set("focusedItem", item);
+							onColViewChange(item);							
+						});
+
+						var startDateSave;
+						var columnCountSave;
+
+						colView.on("columnHeaderClick", function(e){
+							if (colView.get("columnCount") == 1) {
+								colView.set("startDate", startDateSave);
+								colView.set("columnCount", columnCountSave);
+							} else {
+								startDateSave = colView.get("startDate");
+								columnCountSave = colView.get("columnCount");
+								colView.set("startDate", e.date);
+								colView.set("columnCount", 1);
+							}
+						});
+						
+						var onColViewChange = function(item){
+							if (item == null){
+								
+								editedItem = null;
+								
+								itemSummaryEditor.set("value", null);
+								itemSummaryEditor.set("disabled", true);
+								
+								itemStartDateEditor.set("value", null);
+								itemStartDateEditor.set("disabled", true);
+								
+								itemStartTimeEditor.set("value", null);
+								itemStartTimeEditor.set("disabled", true);
+								
+								itemEndDateEditor.set("value", null);
+								itemEndDateEditor.set("disabled", true);
+								
+								itemEndTimeEditor.set("value", null);
+								itemEndTimeEditor.set("disabled", true);
+								
+								updateItemButton.set("disabled", true);
+								
+								allDayCB.set("disabled", true);
+								allDayCB.set("checked", false, false);
+								
+								resizeEnabledCB.set("disabled", true);
+								resizeEnabledCB.set("checked", false);
+								
+								moveEnabledCB.set("disabled", true);
+								moveEnabledCB.set("checked", false);
+								
+								calendarEditor.set("disabled", true);
+								
+								
+							}else{
+								// work on a copy
+								editedItem = lang.mixin({}, item);
+								
+								var allDay = item.allDay === true;
+																
+								itemSummaryEditor.set("value", item.summary);
+								itemSummaryEditor.set("disabled", false);
+								
+								itemStartDateEditor.set("value", item.startTime);
+								itemStartDateEditor.set("disabled", false);
+								
+								itemStartTimeEditor.set("value", item.startTime);
+								itemStartTimeEditor.set("disabled", allDay);
+								
+								itemEndDateEditor.set("value", item.endTime);
+								itemEndDateEditor.set("disabled", false);
+								
+								itemEndTimeEditor.set("value", item.endTime);
+								itemEndTimeEditor.set("disabled", allDay);
+								
+								calendarEditor.set("value", item.calendar == "cal1" ? "Calendar 1" : "Calendar 2");
+								
+								updateItemButton.set("disabled", false);
+								calendarEditor.set("disabled", false);	
+								
+								allDayCB.set("disabled", false);
+								allDayCB.set("checked", allDay, false);
+								
+								resizeEnabledCB.set("disabled", false);
+								resizeEnabledCB.set("checked", win.doc.appState.resizeDisabledMap[item.id] !== true);
+								
+								moveEnabledCB.set("disabled", false);
+								moveEnabledCB.set("checked", win.doc.appState.moveDisabledMap[item.id] !== true);
+							}
+							
+							var res = "";
+							if(item == null){
+								res = null;
+							}else{
+								var list = colView.get("selectedItems");
+								for(var i=0; i<list.length; i++){
+									res += list[i].summary;
+									if(i != list.length-1){
+										res += ", ";
+									}
+								}
+							}
+							addLogEntry("onChange", res);
+						};
+						
+						allDayCB.on("change", function(value){
+							
+							itemStartTimeEditor.set("disabled", value);
+							itemEndTimeEditor.set("disabled", value);
+							var d;
+							if(value){
+								d = itemStartTimeEditor.get("value");
+								colView.floorToDay(d, true);
+								itemStartTimeEditor.set("value", d);
+								d = itemEndTimeEditor.get("value");
+								colView.floorToDay(d, true);
+								itemEndTimeEditor.set("value", d);
+								
+								if(!colView.isStartOfDay(editedItem.endTime)){
+									d = itemEndDateEditor.get("value");
+									colView.floorToDay(d, true);
+									d = colView.renderData.dateModule.add(d, "day", 1);
+									itemEndDateEditor.set("value", d);
+								}
+								
+							}else{
+								editedItem.startTime.setHours(8);
+								editedItem.endTime.setHours(9);
+								itemStartTimeEditor.set("value", editedItem.startTime);
+								itemEndTimeEditor.set("value", editedItem.endTime);
+								d = itemEndDateEditor.get("value");
+								colView.floorToDay(d, true);
+								d = colView.renderData.dateModule.add(d, "day", -1);
+								itemEndDateEditor.set("value", d);
+							}
+							
+						});
+						
+						colView.on("change", function(e){							
+							onColViewChange(e.newValue);							
+						});
+						
+						startDateEditor.on("change", function(value){
+							colView.set("startDate", value);
+						});
+						
+						var editedItem;
+						
+						updateItemButton.on("click", function(value){
+							
+							if (editedItem != null) {
+								editedItem.summary = itemSummaryEditor.get("value");
+								if(allDayCB.get("value")){
+									if(!colView.isStartOfDay(editedItem.startTime)){
+										editedItem.startTime = colView.floorToDay(itemStartDateEditor.get("value"), true);
+									}
+									if(!colView.isStartOfDay(editedItem.endTime)){
+										editedItem.endTime = colView.floorToDay(itemEndDateEditor.get("value"), true);
+									}			
+									editedItem.allDay = true;						
+								}else{
+									editedItem.startTime = mergeDateTime(true);
+									editedItem.endTime = mergeDateTime(false);
+									delete editedItem.allDay;
+								}
+								
+								var calValue = calendarEditor.get("value");
+								editedItem.calendar = calValue == "Calendar 1" ? "cal1" : "cal2";
+								colView.store.put(editedItem);
+							}
+							
+						});
+
+						dateFormatButton.on("click", function(value){
+							colView.set("rowHeaderTimePattern", rowHeaderFormatEditor.value);
+							colView.set("columnHeaderDatePattern", columnHeaderFormatEditor.value);
+						});
+						
+						colView.on("itemClick", function(e){
+							addLogEntry("onItemClick", e.item.summary);
+						});
+						colView.on("itemDoubleClick", function(e){
+							addLogEntry("onItemDoubleClick", e.item.summary);
+						});
+						colView.on("gridClick", function(e){
+							addLogEntry("onGridClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});
+						colView.on("gridDoubleClick", function(e){
+							addLogEntry("onGridDoubleClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});
+												
+						
+						colView.on("itemRollOut", function(e){
+							addLogEntry("onItemRollOut", e.item.summary);
+						});											
+						
+						var getItemLabel = function(item){
+							return "<b>" + item.summary + "</b><br/><table><tr><td style='text-align:right'>" + 
+								"Start:</td><td>" + colView.renderData.dateLocaleModule.format(item.startTime, {formatLength: "medium"}) + "</td></tr><tr><td style='text-align:right'>" + 
+								"End:</td><td>" + colView.renderData.dateLocaleModule.format(item.endTime, {formatLength: "medium"}) + "</td></tr></table>";
+						};
+						
+						colView.on("focusChange", function(e){
+							addLogEntry("focusChange", e.item ? e.item.summary: "null");					
+						});
+												
+						colView.on("itemRollOver", function(e){							
+							addLogEntry("onItemRollOver", e.item.summary);																				
+						});
+						
+						colView.on("itemEditBegin", function(e){							
+							addLogEntry("onItemEditBegin", e.item.summary);
+						});
+						
+						colView.on("itemEditBeginGesture", function(e){
+							addLogEntry("onItemEditBeginGesture", e.editKind + ", " + e.item.summary);							
+						});
+						
+						colView.on("itemEditEndGesture", function(e){
+							addLogEntry("onItemEditEndGesture", e.editKind + ", " + e.item.summary);														
+							onColViewChange(e.item);
+						});
+						
+												
+						colView.on("itemEditEnd", function(e){
+							addLogEntry("onItemEditEnd", e.item.summary + ", completed:" + e.completed);																							
+						});
+																	
+						editableCB.on("change", function(value){
+							colView.set("editable", value);
+						});
+						
+						keyEditableCB.on("change", function(value){
+							colView.set("keyboardEditable", value);
+						});
+						
+						liveEditCB.on("change", function(value){
+							colView.liveLayout = value;
+						});
+												
+						allowSwapCB.on("change", function(value){							
+							colView.allowStartEndSwap = value;
+						});
+						
+						viewConstrainCB.on("change", function(value){							
+							colView.stayInView = value;
+						});											
+												
+						resizeEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("resizeEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("resizeEnabledCBLabel", "disabled");
+							}							
+						});
+
+						moveEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("moveEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("moveEnabledCBLabel", "disabled");
+							}
+						});
+						
+						resizeEnabledCB.on("change", function(value){
+							if (colView.selectedItem) {
+								if (value){
+									delete win.doc.appState.resizeDisabledMap[colView.selectedItem.id]	
+								} else {
+									win.doc.appState.resizeDisabledMap[colView.selectedItem.id] = true;
+								}								
+							}
+						});
+
+						moveEnabledCB.on("change", function(value){
+							if (colView.selectedItem) {
+								if (value){
+									delete win.doc.appState.moveDisabledMap[colView.selectedItem.id]	
+								} else {
+									win.doc.appState.moveDisabledMap[colView.selectedItem.id] = true;
+								}
+							}
+						});
+						
+						overlapEditor.on("change", function(value){
+							colView.set('percentOverlap', this.value);
+							hGapEditor.set("disabled", value!=0)
+						});
+						
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+			
+			<div id="formDiv">
+				
+				<div data-dojo-type="dijit.TitlePane" title="Date Interval" class="formPanel">
+					<table class="formTable">	
+						<tr>
+							<td>Start date:</td>
+							<td><div data-dojo-id="startDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:80px"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Column count:</td>
+							<td><div data-dojo-id="columnCountEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" data-dojo-props="constraints:{min:1, max:14}, value:7, intermediateChanges:true" onChange="colView.set('columnCount', this.value);"></div></td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Main Properties" class="formPanel">
+					<table class="formTable">
+								
+						<tr>
+							<td>Min hours:</td>
+							<td><div data-dojo-id="minHoursEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" value="8" data-dojo-props="constraints:{min:0, max:24}, intermediateChanges:true" onChange="colView.set('minHours', this.value);"></div></td>
+						</tr>
+								
+						<tr>
+							<td>Max Hours:</td>
+							<td><div data-dojo-id="maxHoursEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" value="18" data-dojo-props="constraints:{min:0, max:24}, intermediateChanges:true" onChange="colView.set('maxHours', this.value);"></div></td>
+						</tr>
+								
+						<tr>
+							<td>Hour size(px):</td>
+							<td><div data-dojo-id="hourSizeEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" value="100" data-dojo-props="constraints:{min:0, max:500}, intermediateChanges:true, smallDelta:25" onChange="colView.set('hourSize', this.value);"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Timeslot (minutes):</td>
+							<td>
+								<select data-dojo-id="timeSlotEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.set('timeSlotDuration', this.value);">
+									<option value="15" selected>15</option>									
+									<option value="30">30</option>
+									<option value="60">60</option>
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td>Row Grid Timeslot:</td>
+							<td>
+								<select data-dojo-id="rhgtimeSlotEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.set('rowHeaderGridSlotDuration', this.value);">																	
+									<option value="15">15</option>									
+									<option value="30">30</option>
+									<option value="60" selected>60</option>
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td>Row Label Timeslot:</td>
+							<td>
+								<select data-dojo-id="rhltimeSlotEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.set('rowHeaderLabelSlotDuration', this.value);">
+									<option value="15">15</option>
+									<option value="30">30</option>
+									<option value="60" selected>60</option>
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td>Row Label offset:</td>
+							<td><div data-dojo-id="rhoEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" value="2" data-dojo-props="constraints:{min:-20, max:20}, intermediateChanges:true" onChange="colView.set('rowHeaderLabelOffset', this.value);"></div></td>
+						</tr>
+						
+						
+						<tr>
+							<td>Overlap (%):</td>
+							<td><div data-dojo-id="overlapEditor" data-dojo-type="dijit.form.NumberSpinner" data-dojo-props="value:70, constraints:{min:0, max:100}, intermediateChanges:true, smallDelta:10" style="width:80px"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Horizontal gap (px):</td>
+							<td><div data-dojo-id="hGapEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" data-dojo-props="constraints:{min:0, max:30}, value:2, intermediateChanges:true, disabled:true" onChange="colView.set('horizontalGap', this.value);"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Start time of day (h):</td>
+							<td><div data-dojo-id="startTimeOfDayEditor" data-dojo-type="dijit.form.NumberSpinner" data-dojo-props="value:8, constraints:{min:0, max:24}, intermediateChanges:true, smallDelta:1" style="width:80px" onChange="colView.set('startTimeOfDay', {hours: this.value, duration: 250});"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Selection mode:</td>
+							<td>
+								<select data-dojo-id="selectionModeEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.set('selectionMode', this.value);">
+									<option>none</option>
+									<option selected>single</option>
+									<option>multiple</option>
+								</select>
+							</td>
+						</tr>
+					</table>
+				</div>
+
+				<div data-dojo-type="dijit.TitlePane" title="Date/Time Patterns" class="formPanel" open="false">
+					<table class="formTable">
+						<tr>
+							<td>Row format:</td>
+							<td><div data-dojo-id="rowHeaderFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" data-dojo-props="placeHolder:'ex: h a'"></div></td>
+						</tr>
+						<tr>
+							<td>Column format:</td>
+							<td><div data-dojo-id="columnHeaderFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" data-dojo-props="placeHolder:'ex: EEE MMM, dd'"></div></td>
+							
+						</tr>
+						<tr>
+							<td colspan="2" style="text-align:right;padding-top:5px;padding-right:5px"><button data-dojo-id="dateFormatButton" data-dojo-type="dijit.form.Button">Apply</button></td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Item Properties" class="formPanel" open="false">					
+					<table>					
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Summary:</span>
+								<div data-dojo-id="itemSummaryEditor" data-dojo-type="dijit.form.TextBox" style="width:140px; margin-left: 10px" data-dojo-props="placeHolder:'Summary...'"></div>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Calendar:</span>					
+								<select data-dojo-id="calendarEditor" data-dojo-type="dijit.form.ComboBox"  style="width:140px; margin-left: 12px" >
+									<option>Calendar 1</option>
+									<option>Calendar 2</option>									
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allDayCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label for="allDayCB">All day</label>
+							</td>
+						</tr>
+						
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">Start time:</td>
+						</tr>
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemStartDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemStartTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" ></div>
+							</td>
+						</tr>											
+						
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">End time:</td>
+						</tr>
+						
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemEndDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemEndTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" ></div>
+							</td>
+						</tr>
+						
+						<tr>
+							<td colspan="2" style="text-align:right;padding-top:5px;font-size:0.9em">
+								<button data-dojo-id="updateItemButton" data-dojo-type="dijit.form.Button" disabled="true">Update</button>
+							</td>
+						</tr>
+					</table>	
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Editing properties" class="formPanel" data-dojo-props="open:true">
+					<table>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="liveEditCB" data-dojo-type="dijit.form.CheckBox" checked="false" />
+								<label for="liveEditCB">Live layout</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allowSwapCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="allowSwapCB">Allow start/end swap</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="editableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="editableCB">Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="keyEditableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="keyEditableCB">Keyboard Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="viewConstrainCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="viewConstrainCB">Stay in view (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" id="moveEnabledCB" data-dojo-id="moveEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="moveEnabledCBLabel" for="moveEnabledCB" class="disabled">Move Enabled (item)</label>
+							</td>						
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" id="resizeEnabledCB" data-dojo-id="resizeEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="resizeEnabledCBLabel" for="resizeEnabledCB" class="disabled">Resize Enabled (item)</label>
+							</td>
+						</tr>
+						
+						<tr>
+							<td class="smallText">Snap (minutes):</td>
+							<td>
+								<select data-dojo-id="editingSnapEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.snapSteps = parseInt(this.value);">
+									<option value="5">5</option>
+									<option value="10">10</option>
+									<option value="15" selected>15</option>
+									<option value="20">20</option>
+									<option value="30">30</option>
+									<option value="60">60</option>
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td class="smallText">Min duration (minutes):</td>
+							<td>
+								<select data-dojo-id="editingMinDurationEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.minDurationSteps = parseInt(this.value);">
+									<option value="5">5</option>
+									<option value="10">10</option>
+									<option value="15" selected>15</option>
+									<option value="20">20</option>
+									<option value="30">30</option>
+									<option value="60">60</option>
+								</select>
+							</td>
+						</tr>
+					</table>
+				</div>
+				
+			</div>
+						
+			<div id="calendarNode"></div>
+			
+			<div id="eventLogPane" title="Calendar events" data-dojo-type="dijit.TitlePane" data-dojo-props="toggleable:false" >
+							
+				<div id="logTableContainer">
+					<table id="logTable">
+						<tbody id="logBody"></tbody>
+					</table>		
+				</div>
+				
+			</div>
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/columnview_rtl.css b/dojox/calendar/tests/columnview_rtl.css
new file mode 100644
index 0000000..e1b8e4a
--- /dev/null
+++ b/dojox/calendar/tests/columnview_rtl.css
@@ -0,0 +1,5 @@
+.formTable td:first-child {
+	text-align: left;
+	padding-left: 10px;
+	font-size: 0.9em;
+}
\ No newline at end of file
diff --git a/dojox/calendar/tests/columnview_rtl.html b/dojox/calendar/tests/columnview_rtl.html
new file mode 100644
index 0000000..944946d
--- /dev/null
+++ b/dojox/calendar/tests/columnview_rtl.html
@@ -0,0 +1,746 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>ColumnView Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/ColumnView.css";
+			@import "../themes/claro/MatrixView.css";
+			@import "columnview.css";
+			@import "../themes/claro/ColumnView_rtl.css";
+			@import "../themes/claro/MatrixView_rtl.css";
+			@import "columnview_rtl.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>			
+	</head>
+	
+	<body class="claro" dir="rtl">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		
+		<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/declare", "dojo/_base/fx", "dojo/on", "dojo/date/locale", "dojo/parser", "dojo/date", "dojo/_base/lang",
+					"dojo/dom", "dojo/dom-construct", "dojo/dom-class", "dojo/_base/window",
+					"dijit/registry", "dojo/query", "dojox/calendar/ColumnView", "dojox/calendar/ColumnViewSecondarySheet", "dojox/calendar/Keyboard", "dojox/calendar/Mouse", 
+					"dojox/calendar/VerticalRenderer", "dojox/calendar/HorizontalRenderer", "dojox/calendar/ExpandRenderer", "dojo/store/Memory", "dojo/store/Observable",
+					"dijit/form/VerticalSlider", "dijit/form/NumberSpinner", 
+					"dijit/form/ComboBox", "dijit/form/DateTextBox", "dijit/form/TimeTextBox", "dijit/form/TextBox", 
+					"dijit/form/Button", "dijit/TitlePane", "dijit/Tooltip", 
+					"dijit/form/CheckBox", "dijit/_BidiSupport"],
+
+				function(ready, declare, fx,on, locale, parser, date, lang, dom, domConstruct, domClass, win, registry, query,
+					ColumnView, ColumnViewSecondarySheet, CalendarKeyboard, CalendarMouse, VerticalRenderer, HorizontalRenderer, ExpandRenderer, Memory, Observable, VerticalSlider, 
+					NumberSpinner, ComboBox, DateTextBox, TimeTextBox, TextBox, Button, TitlePane, Tooltip, CheckBox){
+
+					ready(function(){
+
+						// singleton
+						win.doc.appState = {
+							moveDisabledMap: {},
+							resizeDisabledMap: {}
+						};
+						
+						var mergeDateTime = function(isStart){
+							var dateEditor = isStart ? itemStartDateEditor : itemEndDateEditor;
+							var timeEditor = isStart ? itemStartTimeEditor : itemEndTimeEditor;
+							var date = dateEditor.get("value");
+							var time = timeEditor.get("value");
+							date.setHours(time.getHours());
+							date.setMinutes(time.getMinutes());
+							return date;
+						};
+						
+						var addLogEntry = function(name, content){
+							var tr = domConstruct.create("tr", null, dom.byId("logBody"), "first");
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(locale.format(new Date(), {selector:"time", timePattern:"h:mm:ss"})));
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(name));
+							td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(content));						
+						};
+
+						// Calendar model creation
+						
+						var dateClassObj = Date;
+						
+						var modelBase = [
+							{day: 1, start: [10,0], duration: 1400},
+							{day: 2, start: [10,30], duration: 120},
+							{day: 2, start: [12,0], duration: 240},
+							{day: 3, start: [6,0], duration: 180}
+						];
+						
+						// TODO manage first day of week
+						var floorToWeek= function(d){
+							d.setHours(0);
+							d.setMinutes(0);
+							d.setSeconds(0);
+							d.setMilliseconds(0);
+							d = date.add(d, "day", -d.getDay());
+							return d;
+						};
+						
+						var someData = [];
+						
+						var startOfWeek = new dateClassObj();
+						startOfWeek = floorToWeek(startOfWeek);
+						
+						startDateEditor.set("value", startOfWeek);
+						
+						for (var i=0; i<modelBase.length; i++) {
+							var newObj = {
+								id: i,
+								summary: "New Event " + i,
+								startTime: new dateClassObj(startOfWeek.getTime()),
+								endTime: new dateClassObj(startOfWeek.getTime()),
+								calendar: i%2 == 0 ? "cal1" : "cal2"
+							};
+
+							newObj.startTime = date.add(newObj.startTime, "day", modelBase[i].day);
+							newObj.startTime.setHours(modelBase[i].start[0]);
+							newObj.startTime.setMinutes(modelBase[i].start[1]);
+
+							newObj.endTime = date.add(newObj.startTime, "minute", modelBase[i].duration);
+
+							someData.push(newObj);
+						}
+						
+						var id = i;
+						
+						// Calendar creation & configuration
+						
+						var secondarySheetClass = declare([ColumnViewSecondarySheet, CalendarKeyboard, CalendarMouse]);
+						
+						colView = declare([ColumnView, CalendarKeyboard, CalendarMouse])({
+							tabIndex: 1,
+							store: new Observable(new Memory({data: someData})),
+							secondarySheetClass: secondarySheetClass,		
+							verticalRenderer: VerticalRenderer,
+							horizontalRenderer: HorizontalRenderer,
+							expandRenderer: ExpandRenderer,
+							cssClassFunc: function(item){
+								return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+							},
+							isItemMoveEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.moveDisabledMap[item.id] !== true;
+							},							
+							isItemResizeEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.resizeDisabledMap[item.id] !== true;
+							}
+						}, "calendarNode");									
+																						
+						// Events management
+						
+						colView.on("gridDoubleClick", function(e){
+
+							// create a event when double-clicking on grid.
+							var start, end;
+							if(e.sheet == "primary"){
+								start = colView.floorDate(e.date, "minute", colView.timeSlotDuration);
+								end = date.add(start, "hour", 1);
+							}else{
+								start = colView.floorToDay(e.date, false, colView.renderData);
+								end = date.add(start, "day", 1);
+							}
+
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: start,
+								endTime: end,
+								calendar: id % 2 == 0 ? "cal1" : "cal2",
+								allDay: e.sheet == "secondary"
+							};
+							
+							id++;		
+							colView.store.add(item);
+							
+							colView.set("selectedItem", item);
+							colView.set("focusedItem", item);
+							onColViewChange(item);							
+						});
+									
+						var onColViewChange = function(item){
+							if (item == null){
+								
+								editedItem = null;
+								
+								itemSummaryEditor.set("value", null);
+								itemSummaryEditor.set("disabled", true);
+								
+								itemStartDateEditor.set("value", null);
+								itemStartDateEditor.set("disabled", true);
+								
+								itemStartTimeEditor.set("value", null);
+								itemStartTimeEditor.set("disabled", true);
+								
+								itemEndDateEditor.set("value", null);
+								itemEndDateEditor.set("disabled", true);
+								
+								itemEndTimeEditor.set("value", null);
+								itemEndTimeEditor.set("disabled", true);
+								
+								updateItemButton.set("disabled", true);
+								
+								allDayCB.set("disabled", true);
+								allDayCB.set("checked", false, false);
+								
+								resizeEnabledCB.set("disabled", true);
+								resizeEnabledCB.set("checked", false);
+								
+								moveEnabledCB.set("disabled", true);
+								moveEnabledCB.set("checked", false);
+								
+								calendarEditor.set("disabled", true);
+								
+								
+							}else{
+								// work on a copy
+								editedItem = lang.mixin({}, item);
+								
+								var allDay = item.allDay === true;
+																
+								itemSummaryEditor.set("value", item.summary);
+								itemSummaryEditor.set("disabled", false);
+								
+								itemStartDateEditor.set("value", item.startTime);
+								itemStartDateEditor.set("disabled", false);
+								
+								itemStartTimeEditor.set("value", item.startTime);
+								itemStartTimeEditor.set("disabled", allDay);
+								
+								itemEndDateEditor.set("value", item.endTime);
+								itemEndDateEditor.set("disabled", false);
+								
+								itemEndTimeEditor.set("value", item.endTime);
+								itemEndTimeEditor.set("disabled", allDay);
+								
+								calendarEditor.set("value", item.calendar == "cal1" ? "Calendar 1" : "Calendar 2");
+								
+								updateItemButton.set("disabled", false);
+								calendarEditor.set("disabled", false);	
+								
+								allDayCB.set("disabled", false);
+								allDayCB.set("checked", allDay, false);
+								
+								resizeEnabledCB.set("disabled", false);
+								resizeEnabledCB.set("checked", win.doc.appState.resizeDisabledMap[item.id] !== true);
+								
+								moveEnabledCB.set("disabled", false);
+								moveEnabledCB.set("checked", win.doc.appState.moveDisabledMap[item.id] !== true);
+							}
+							
+							var res = "";
+							if(item == null){
+								res = null;
+							}else{
+								var list = colView.get("selectedItems");
+								for(var i=0; i<list.length; i++){
+									res += list[i].summary;
+									if(i != list.length-1){
+										res += ", ";
+									}
+								}
+							}
+							addLogEntry("onChange", res);
+						};
+						
+						allDayCB.on("change", function(value){
+							
+							itemStartTimeEditor.set("disabled", value);
+							itemEndTimeEditor.set("disabled", value);
+							var d;
+							if(value){
+								d = itemStartTimeEditor.get("value");
+								colView.floorToDay(d, true);
+								itemStartTimeEditor.set("value", d);
+								d = itemEndTimeEditor.get("value");
+								colView.floorToDay(d, true);
+								itemEndTimeEditor.set("value", d);
+								
+								if(!colView.isStartOfDay(editedItem.endTime)){
+									d = itemEndDateEditor.get("value");
+									colView.floorToDay(d, true);
+									d = colView.renderData.dateModule.add(d, "day", 1);
+									itemEndDateEditor.set("value", d);
+								}
+								
+							}else{
+								editedItem.startTime.setHours(8);
+								editedItem.endTime.setHours(9);
+								itemStartTimeEditor.set("value", editedItem.startTime);
+								itemEndTimeEditor.set("value", editedItem.endTime);
+								d = itemEndDateEditor.get("value");
+								colView.floorToDay(d, true);
+								d = colView.renderData.dateModule.add(d, "day", -1);
+								itemEndDateEditor.set("value", d);
+							}
+							
+						});
+						
+						colView.on("change", function(e){							
+							onColViewChange(e.newValue);							
+						});
+						
+						startDateEditor.on("change", function(value){
+							colView.set("startDate", value);
+						});
+						
+						var editedItem;
+						
+						updateItemButton.on("click", function(value){
+							
+							if (editedItem != null) {
+								editedItem.summary = itemSummaryEditor.get("value");
+								if(allDayCB.get("value")){
+									if(!colView.isStartOfDay(editedItem.startTime)){
+										editedItem.startTime = colView.floorToDay(itemStartDateEditor.get("value"), true);
+									}
+									if(!colView.isStartOfDay(editedItem.endTime)){
+										editedItem.endTime = colView.floorToDay(itemEndDateEditor.get("value"), true);
+									}			
+									editedItem.allDay = true;						
+								}else{
+									editedItem.startTime = mergeDateTime(true);
+									editedItem.endTime = mergeDateTime(false);
+									delete editedItem.allDay;
+								}
+								
+								var calValue = calendarEditor.get("value");
+								editedItem.calendar = calValue == "Calendar 1" ? "cal1" : "cal2";
+								colView.store.put(editedItem);
+							}
+							
+						});
+
+						dateFormatButton.on("click", function(value){
+							colView.set("rowHeaderTimePattern", rowHeaderFormatEditor.value);
+							colView.set("columnHeaderDatePattern", columnHeaderFormatEditor.value);
+						});
+						
+						colView.on("itemClick", function(e){
+							addLogEntry("onItemClick", e.item.summary);
+						});
+						colView.on("itemDoubleClick", function(e){
+							addLogEntry("onItemDoubleClick", e.item.summary);
+						});
+						colView.on("gridClick", function(e){
+							addLogEntry("onGridClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});
+						colView.on("gridDoubleClick", function(e){
+							addLogEntry("onGridDoubleClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});
+												
+						var dataTip = new Tooltip({position:["above"], showDelay: 0});
+						var timer;																
+						
+						colView.on("itemRollOut", function(e){
+							addLogEntry("onItemRollOut", e.item.summary);
+							dataTip.close();
+							if(timer){
+								clearTimeout(timer);
+							}
+						});											
+						
+						var getDataTipLabel = function(item){
+							return "<b>" + item.summary + "</b><br/><table><tr><td style='text-align:right'>" + 
+								"Start:</td><td>" + colView.renderData.dateLocaleModule.format(item.startTime, {formatLength: "medium"}) + "</td></tr><tr><td style='text-align:right'>" + 
+								"End:</td><td>" + colView.renderData.dateLocaleModule.format(item.endTime, {formatLength: "medium"}) + "</td></tr></table>";
+						};
+						
+						colView.on("focusChange", function(e){
+							if(e.newValue){
+								dataTip.set("label", getDataTipLabel(e.newValue));	
+								var irs = colView.getRenderers(e.newValue);		
+								if(irs != null){
+									dataTip.open(irs[0].container);
+								}
+							}else{
+								dataTip.close();
+							}					
+						});
+												
+						colView.on("itemRollOver", function(e){
+							
+							addLogEntry("onItemRollOver", e.item.summary);
+														
+							dataTip.set("label", getDataTipLabel(e.item));
+							
+							timer = setTimeout(function(){
+								var irs = colView.getRenderers(e.item);
+								if(irs != null){
+									dataTip.open(irs[0].container);	
+								}								
+							}, 400);							
+							
+						});
+						
+						var editProperties = null;
+												
+						colView.on("itemEditBegin", function(e){							
+							if(timer){
+								clearTimeout(timer);
+							}
+							dataTip.close();
+							addLogEntry("onItemEditBegin", e.item.summary);
+							editProperties = {
+								item: e.item
+							};
+						});
+						
+						colView.on("itemEditBeginGesture", function(e){
+							addLogEntry("onItemEditBeginGesture", e.editKind + ", " + e.item.summary);							
+						});
+						
+						var showDataTipAfterLayout = false;
+												
+						colView.on("renderersLayoutDone", function(){
+							
+							if(editProperties != null && showDataTipAfterLayout){
+								var item = editProperties.item;
+									
+								// HACK: setting the label should dynamically set the content 
+								dataTip.label = getDataTipLabel(item);
+																
+								showDataTipAfterLayout= false;
+								
+								var irs = colView.getRenderers(item);
+								if(irs != null){
+									dataTip.open(irs[0].container);	
+								}																																
+							}
+
+						});
+						
+						colView.on("itemEditMoveGesture", function(e){
+							//showDataTipAfterLayout = true;
+						});
+						
+						colView.on("itemEditEnd", function(e){
+							addLogEntry("onItemEditEnd", e.item.summary + ", completed:" + e.completed);										
+							showDataTipAfterLayout = true;													
+						});
+																	
+						editableCB.on("change", function(value){
+							colView.set("editable", value);
+						});
+						
+						keyEditableCB.on("change", function(value){
+							colView.set("keyboardEditable", value);
+						});
+						
+						liveEditCB.on("change", function(value){
+							colView.liveLayout = value;
+						});
+												
+						allowSwapCB.on("change", function(value){							
+							colView.allowStartEndSwap = value;
+						});
+						
+						viewConstrainCB.on("change", function(value){							
+							colView.stayInView = value;
+						});											
+												
+						resizeEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("resizeEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("resizeEnabledCBLabel", "disabled");
+							}							
+						});
+
+						moveEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("moveEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("moveEnabledCBLabel", "disabled");
+							}
+						});
+						
+						resizeEnabledCB.on("change", function(value){
+							if (colView.selectedItem) {
+								if (value){
+									delete win.doc.appState.resizeDisabledMap[colView.selectedItem.id]	
+								} else {
+									win.doc.appState.resizeDisabledMap[colView.selectedItem.id] = true;
+								}								
+							}
+						});
+
+						moveEnabledCB.on("change", function(value){
+							if (colView.selectedItem) {
+								if (value){
+									delete win.doc.appState.moveDisabledMap[colView.selectedItem.id]	
+								} else {
+									win.doc.appState.moveDisabledMap[colView.selectedItem.id] = true;
+								}
+							}
+						});
+																																
+					});
+			});
+			</script>
+			
+			<div id="formDiv">
+				
+				<div data-dojo-type="dijit.TitlePane" title="Date Interval" class="formPanel">
+					<table class="formTable">	
+						<tr>
+							<td>Start date:</td>
+							<td><div data-dojo-id="startDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:80px" onChange="colView.set('startDate', this.value);"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Column count:</td>
+							<td><div data-dojo-id="columnCountEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:1, max:14}" value="7" intermediateChanges="true" onChange="colView.set('columnCount', this.value);"></div></td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Main Properties" class="formPanel">
+					<table class="formTable">
+								
+						<tr>
+							<td>Min hours:</td>
+							<td><div data-dojo-id="minHoursEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" value="8" constraints="{min:0, max:24}" intermediateChanges= "true" onChange="colView.set('minHours', this.value);"></div></td>
+						</tr>
+								
+						<tr>
+							<td>Max Hours:</td>
+							<td><div data-dojo-id="maxHoursEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" value="18" constraints="{min:0, max:24}" intermediateChanges= "true" onChange="colView.set('maxHours', this.value);"></div></td>
+						</tr>
+								
+						<tr>
+							<td>Hour size(px):</td>
+							<td><div data-dojo-id="hourSizeEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" value="100" constraints="{min:0, max:500}" intermediateChanges= "true" smallDelta="25" onChange="colView.set('hourSize', this.value);"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Timeslot (minutes):</td>
+							<td>
+								<select data-dojo-id="timeSlotEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.set('timeSlotDuration', this.value);">
+									<option value="5">5</option>
+									<option value="10">10</option>
+									<option value="15" selected>15</option>
+									<option value="20">20</option>
+									<option value="30">30</option>
+									<option value="60">60</option>
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td>Overlap (%):</td>
+							<td><div data-dojo-id="overlapEditor" data-dojo-type="dijit.form.NumberSpinner" value="70" constraints="{min:0, max:100}" intermediateChanges="true" smallDelta="10" style="width:80px" onChange="colView.set('percentOverlap', this.value);"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Start time of day (h):</td>
+							<td><div data-dojo-id="startTimeOfDayEditor" data-dojo-type="dijit.form.NumberSpinner" value="8" constraints="{min:0, max:24}" intermediateChanges="true" smallDelta="1" style="width:80px" onChange="colView.set('startTimeOfDay', {hours: this.value, duration: 250});"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Selection mode:</td>
+							<td>
+								<select data-dojo-id="selectionModeEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.set('selectionMode', this.value);">
+									<option>none</option>
+									<option selected>single</option>
+									<option>multiple</option>
+								</select>
+							</td>
+						</tr>
+						<tr>
+							<td>Scroll Bar:</td>
+							<td>
+								<select data-dojo-id="scrollBarPosEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.set('scrollBarRTLPosition', this.value);">
+									<option selected>left</option>
+									<option>right</option>
+								</select>
+							</td>
+						</tr>
+						<tr>
+							<td>Text Dir:</td>
+							<td>
+								<select data-dojo-id="textDirEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.set('textDir', this.value);dataTip.set('textDir', this.value)">
+									<option selected>auto</option>
+									<option>ltr</option>
+									<option>rtl</option>
+								</select>
+							</td>
+						</tr>
+					</table>
+				</div>
+
+				<div data-dojo-type="dijit.TitlePane" title="Date/Time Patterns" class="formPanel" open="false">
+					<table class="formTable">
+						<tr>
+							<td>Row format:</td>
+							<td><div data-dojo-id="rowHeaderFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" placeHolder="ex: h a"></div></td>
+						</tr>
+						<tr>
+							<td>Column format:</td>
+							<td><div data-dojo-id="columnHeaderFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" placeHolder="ex: EEE MMM, dd"></div></td>
+							
+						</tr>
+						<tr>
+							<td colspan="2" style="text-align:right;padding-top:5px;padding-right:5px"><button data-dojo-id="dateFormatButton" data-dojo-type="dijit.form.Button">Apply</button></td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Item Properties" class="formPanel" open="false">					
+					<table>					
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Summary:</span>
+								<div data-dojo-id="itemSummaryEditor" data-dojo-type="dijit.form.TextBox" style="width:140px; margin-left: 10px" placeHolder="Summary..."></div>
+							</td>
+						</tr>
+                        <tr>
+                            <td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allDayCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label for="allDayCB">All day</label>
+							</td>
+						</tr>
+
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Calendar:</span>					
+								<select data-dojo-id="calendarEditor" data-dojo-type="dijit.form.ComboBox"  style="width:140px; margin-left: 12px" >
+									<option>Calendar 1</option>
+									<option>Calendar 2</option>									
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">Start time:</td>
+						</tr>
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemStartDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemStartTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" ></div>
+							</td>
+						</tr>											
+						
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">End time:</td>
+						</tr>
+						
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemEndDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemEndTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" ></div>
+							</td>
+						</tr>
+						
+						<tr>
+							<td colspan="2" style="text-align:right;padding-top:5px;font-size:0.9em">
+								<button data-dojo-id="updateItemButton" data-dojo-type="dijit.form.Button" disabled="true">Update</button>
+							</td>
+						</tr>
+					</table>	
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Editing properties" class="formPanel" open="true">
+					<table>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="liveEditCB" data-dojo-type="dijit.form.CheckBox" checked="false" />
+								<label for="liveEditCB">Live layout</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allowSwapCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="allowSwapCB">Allow start/end swap</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="editableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="editableCB">Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="keyEditableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="keyEditableCB">Keyboard Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="viewConstrainCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="viewConstrainCB">Stay in view (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="moveEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="moveEnabledCBLabel" for="moveEnabledCB" class="disabled">Move Enabled (item)</label>
+							</td>						
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="resizeEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="resizeEnabledCBLabel" for="resizeEnabledCB" class="disabled">Resize Enabled (item)</label>
+							</td>
+						</tr>
+						
+						<tr>
+							<td class="smallText">Snap (minutes):</td>
+							<td>
+								<select data-dojo-id="editingSnapEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.snapSteps = parseInt(this.value);">
+									<option value="5">5</option>
+									<option value="10">10</option>
+									<option value="15" selected>15</option>
+									<option value="20">20</option>
+									<option value="30">30</option>
+									<option value="60">60</option>
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td class="smallText">Min duration (minutes):</td>
+							<td>
+								<select data-dojo-id="editingMinDurationEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.minDurationSteps = parseInt(this.value);">
+									<option value="5">5</option>
+									<option value="10">10</option>
+									<option value="15" selected>15</option>
+									<option value="20">20</option>
+									<option value="30">30</option>
+									<option value="60">60</option>
+								</select>
+							</td>
+						</tr>
+					</table>
+				</div>
+				
+			</div>
+						
+			<div id="calendarNode"></div>
+			
+			<div id="eventLogPane" title="Calendar events" data-dojo-type="dijit.TitlePane" toggleable="false" >
+							
+				<div id="logTableContainer">
+					<table id="logTable">
+						<tbody id="logBody"></tbody>
+					</table>		
+				</div>
+				
+			</div>
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/contextmenu.html b/dojox/calendar/tests/contextmenu.html
new file mode 100644
index 0000000..d3d2c71
--- /dev/null
+++ b/dojox/calendar/tests/contextmenu.html
@@ -0,0 +1,342 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Calendar Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/Calendar.css";
+			@import "calendar.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>			
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/fx", "dojo/on", 
+			         "dojo/date/locale", "dojo/parser",	"dojo/dom", "dojo/dom-construct",	"dojo/store/Memory", 
+			         "dojo/store/Observable",	"dojox/calendar/Calendar", "dijit/Calendar",  "dijit/TitlePane", 
+			         "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/form/CheckBox", 
+			         "dijit/form/TextBox", "dijit/form/DateTextBox", "dijit/form/TimeTextBox", 
+			         "dijit/form/Button", "dijit/form/ComboBox", "dijit/Menu", "dijit/MenuItem"	],
+
+				function(ready, lang, arr, fx, on, locale, parser, dom, domConstruct,
+					Memory, Observable, Calendar){
+
+					ready(function(){
+						
+						calendar.set("cssClassFunc", function(item){
+							// Use custom css classes on renderers depending of a parameter (calendar). 
+							return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+						});
+						
+						// Calendar model creation
+						
+						var modelBase = [
+							{day: 1, start: [10,0], duration: 1400},
+							{day: 2, start: [10,30], duration: 120},
+							{day: 2, start: [12,0], duration: 240},
+							{day: 3, start: [6,0], duration: 180},
+							{day: 3, start: [0,0], duration: 2880, allDay: true}
+						];
+						
+						var someData = [];
+												
+						var startOfWeek = calendar.floorToWeek(new calendar.dateClassObj());
+						
+						for (var id=0; id<modelBase.length; id++) {
+							var newObj = {
+								id: id,
+								summary: "New Event " + id,
+								startTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								endTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								calendar: id%2 == 0 ? "cal1" : "cal2",
+								allDay: modelBase[id].allDay
+							};
+
+							newObj.startTime = calendar.dateModule.add(newObj.startTime, "day", modelBase[id].day);
+							newObj.startTime.setHours(modelBase[id].start[0]);
+							newObj.startTime.setMinutes(modelBase[id].start[1]);
+
+							newObj.endTime = calendar.dateModule.add(newObj.startTime, "minute", modelBase[id].duration);
+
+							someData.push(newObj);
+						}
+						
+						calendar.set("store", new Observable(new Memory({data: someData})));
+						calendar.set("date", startOfWeek);
+						
+						calendar.on("gridDoubleClick", function(e){
+
+							// create a event when double-clicking on grid.
+							var start, end;
+							var colView = calendar.columnView;
+							var cal = calendar.dateModule;
+							
+							if(e.source == colView){
+								start = calendar.floorDate(e.date, "minute", colView.timeSlotDuration);
+								end = cal.add(start, "hour", 1);
+							}else{
+								start = calendar.floorToDay(e.date);
+								end = cal.add(start, "day", 1);
+							}
+							
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: start,
+								endTime: end,
+								calendar: "cal1",
+								allDay: e.source.viewKind == "matrix"
+							};
+							
+							id++;		
+							calendar.store.add(item);
+							
+							calendar.set("selectedItem", item);
+							calendar.get("currentView").set("focusedItem", item);
+							
+							selectionChanged(item);						
+						});	
+						
+						
+						var calendarVisibility = [true, true];
+						
+						var itemToRendererKindFunc = function(item){
+							if(item.cssClass == "Calendar1" && calendarVisibility[0] ||
+								item.cssClass == "Calendar2" && calendarVisibility[1]){
+									return this._defaultItemToRendererKindFunc(item);
+								}
+							return null
+						};
+						
+						calendar.columnView.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						calendar.columnView.secondarySheet.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						calendar.matrixView.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						
+						var editedItem;
+						
+						var selectionChanged = function(item){
+							
+							var itemNull = item == null;
+							
+							var widgets = [itemSummaryEditor, itemStartDateEditor, itemStartTimeEditor, itemEndDateEditor,
+								itemEndTimeEditor, calendarEditor, allDayCB, deleteItemButton, updateItemButton];
+							
+							arr.forEach(widgets, function(w){
+								w.set("disabled", itemNull);
+								w.set("value", null, false);
+							});
+							
+							editedItem = itemNull ? null : lang.mixin({}, item); 
+							
+							if(!itemNull){
+							
+								var allDay = item.allDay === true;
+								
+								itemStartTimeEditor.set("disabled", allDay);
+								itemEndTimeEditor.set("disabled", allDay);
+																
+								itemSummaryEditor.set("value", item.summary);
+								itemStartDateEditor.set("value", item.startTime);
+								itemStartTimeEditor.set("value", item.startTime);
+								itemEndDateEditor.set("value", item.endTime);
+								itemEndTimeEditor.set("value", item.endTime);
+								calendarEditor.set("value", item.calendar == "cal1" ? "Calendar 1" : "Calendar 2");																					
+								allDayCB.set("checked", allDay, false);
+							}																						
+						};
+						
+						calendar.on("change", function(e){							
+							selectionChanged(e.newValue);							
+						});	
+						
+						calendar.on("itemEditEnd", function(e){
+							selectionChanged(e.item);
+						});
+						
+						calendar.on("timeIntervalChange", function(e){
+							dateChooser.set("value", e.startTime, false);
+						});
+						
+						allDayCB.on("change", function(value){
+							
+							itemStartTimeEditor.set("disabled", value);
+							itemEndTimeEditor.set("disabled", value);
+							
+							var d;
+							if(value){
+								d = itemStartTimeEditor.get("value");
+								calendar.floorToDay(d, true);
+								itemStartTimeEditor.set("value", d);
+								d = itemEndTimeEditor.get("value");
+								calendar.floorToDay(d, true);
+								itemEndTimeEditor.set("value", d);
+								
+								if(!calendar.isStartOfDay(editedItem.endTime)){
+									d = itemEndDateEditor.get("value");
+									calendar.floorToDay(d, true);
+									d = calendar.dateModule.add(d, "day", 1);
+									itemEndDateEditor.set("value", d);
+								}
+								
+							}else{
+								editedItem.startTime.setHours(8);
+								editedItem.endTime.setHours(9);
+								itemStartTimeEditor.set("value", editedItem.startTime);
+								itemEndTimeEditor.set("value", editedItem.endTime);
+								d = itemEndDateEditor.get("value");
+								calendar.floorToDay(d, true);
+								d = calendar.dateModule.add(d, "day", -1);
+								itemEndDateEditor.set("value", d);
+							}
+							
+						});
+						
+						var mergeDateTime = function(isStart){
+							var dateEditor = isStart ? itemStartDateEditor : itemEndDateEditor;
+							var timeEditor = isStart ? itemStartTimeEditor : itemEndTimeEditor;
+							var date = dateEditor.get("value");
+							var time = timeEditor.get("value");
+							date.setHours(time.getHours());
+							date.setMinutes(time.getMinutes());
+							return date;
+						};
+						
+						updateItemButton.on("click", function(value){
+							
+							if (editedItem != null) {
+								editedItem.summary = itemSummaryEditor.get("value");
+								if(allDayCB.get("value")){
+									if(!calendar.isStartOfDay(editedItem.startTime)){
+										editedItem.startTime = calendar.floorToDay(itemStartDateEditor.get("value"), true);
+									}
+									if(!calendar.isStartOfDay(editedItem.endTime)){
+										editedItem.endTime = calendar.floorToDay(itemEndDateEditor.get("value"), true);
+									}			
+									editedItem.allDay = true;						
+								}else{
+									editedItem.startTime = mergeDateTime(true);
+									editedItem.endTime = mergeDateTime(false);
+									delete editedItem.allDay;
+								}
+								
+								var calValue = calendarEditor.get("value");
+								editedItem.calendar = calValue == "Calendar 1" ? "cal1" : "cal2";
+								calendar.store.put(editedItem);
+							}
+							
+						});
+						
+						deleteItemButton.on("click", function(value){
+							if (editedItem != null) {
+								calendar.store.remove(editedItem.id);
+							}
+						});
+																										
+																							
+						dateChooser.set("value", startOfWeek);
+						dateChooser.on("change", function(e){
+							var d = dateChooser.get("value");
+							calendar.set("date", d);
+						});						
+										
+						calendar1CB.on("change", function(v){
+							calendarVisibility[0] = v;
+							calendar.currentView.invalidateLayout();
+						});
+						
+						calendar2CB.on("change", function(v){
+							calendarVisibility[1] = v;
+							calendar.currentView.invalidateLayout();
+						});											
+						
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+			
+			<div data-dojo-type="dijit.layout.BorderContainer" style="width:100%;height:100%" data-dojo-props="design:'sidebar', gutters:true" >
+		    <div data-dojo-type="dijit.layout.ContentPane" style="width:200px" data-dojo-props="splitter:false, region:'leading'">
+		        <div data-dojo-id="dateChooser" data-dojo-type="dijit.Calendar" style="width:100%"></div>
+						<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'Calendars', style:'margin-top:10px;'" >
+							<div>
+								<input type="checkbox" data-dojo-id="calendar1CB" data-dojo-type="dijit.form.CheckBox" checked="true"/>
+								<label for="calendar1CB">Calendar 1</label>
+							</div>
+									
+							<div style="margin-top:5px">
+								<input type="checkbox" data-dojo-id="calendar2CB" data-dojo-type="dijit.form.CheckBox" checked="true"/>
+								<label for="calendar2CB">Calendar 2</label>
+							</div>
+						</div>
+						<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'Event properties', style:'margin-top:10px;'" >
+							<div><span class="propertyTitle">Summary:</span></div>
+							<div data-dojo-id="itemSummaryEditor" data-dojo-type="dijit.form.TextBox" style="width:165px;" data-dojo-props="disabled:true"></div>
+							<div style="margin-top:10px"><span class="propertyTitle">Start:</span></div>
+							<div>
+								<div data-dojo-id="itemStartDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:90px;"  data-dojo-props="disabled:true"></div>
+								<div data-dojo-id="itemStartTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:70px;" data-dojo-props="disabled:true" ></div>
+							</div>
+							<div style="margin-top:10px"><span class="propertyTitle">End:</span></div>
+							<div>
+								<div data-dojo-id="itemEndDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:90px;" data-dojo-props="disabled:true" ></div>
+								<div data-dojo-id="itemEndTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:70px;" data-dojo-props="disabled:true" ></div>
+							</div>
+							<div style="margin-top:10px"><span class="propertyTitle">Calendar:</span></div>
+							<select data-dojo-id="calendarEditor" data-dojo-type="dijit.form.ComboBox"  style="width:165px;" data-dojo-props="disabled:true" >
+								<option>Calendar 1</option>
+								<option>Calendar 2</option>									
+							</select>
+							<div style="margin-top:10px">
+								<input type="checkbox" data-dojo-id="allDayCB" data-dojo-type="dijit.form.CheckBox" checked="false" data-dojo-props="disabled:true" />
+								<label for="allDayCB">All day</label>
+							</div>	
+							<div style="margin-top:10px">
+								<span style="text-align:left">
+									<button data-dojo-id="deleteItemButton" class="deleteButton" data-dojo-type="dijit.form.Button"  data-dojo-props="disabled:true">Delete</button>
+								</span>
+								<span style="text-align:right">
+									<button data-dojo-id="updateItemButton" data-dojo-type="dijit.form.Button" data-dojo-props="disabled:true" >Update</button>
+								</span>
+							</div>
+						</div>
+		    </div>
+		    <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="splitter:false, region:'center'">
+		        <div data-dojo-id="calendar" data-dojo-type="dojox.calendar.Calendar" 
+									style="position:absolute;left:10px;top:10px;bottom:10px;right:10px">
+						
+							<script type="dojo/connect" data-dojo-event="onItemContextMenu" data-dojo-args="e">
+							dojo.stopEvent(e.triggerEvent);
+							calendarContextMenu._openMyself({ target: e.renderer.domNode, coords: {x: e.triggerEvent.pageX, y: e.triggerEvent.pageY} });
+							</script>
+						
+						</div>
+						
+						<div data-dojo-type="dijit.Menu" data-dojo-id="calendarContextMenu" style="display: none;">
+						    <div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass:'dijitIcon dijitIconDelete',
+						        onClick:function(){ if (calendar.selectedItem) { calendar.store.remove(calendar.selectedItem.id); } }">Remove</div>
+						</div>
+						
+		    </div>
+		</div>																		
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/editing.html b/dojox/calendar/tests/editing.html
new file mode 100644
index 0000000..cb69534
--- /dev/null
+++ b/dojox/calendar/tests/editing.html
@@ -0,0 +1,135 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Calendar Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/Calendar.css";
+			@import "calendar.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>			
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/array", "dojo/_base/fx", "dojo/on", 
+			         "dojo/date/locale", "dojo/parser",	"dojo/dom", "dojo/dom-construct",	"dojo/store/Memory", 
+			         "dojo/store/Observable",	"dojox/calendar/Calendar", "dijit/Calendar",  "dijit/TitlePane", 
+			         "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dijit/form/CheckBox", 
+			         "dijit/form/TextBox", "dijit/form/DateTextBox", "dijit/form/TimeTextBox", 
+			         "dijit/form/Button", "dijit/form/ComboBox", "dijit/Menu", "dijit/MenuItem"	],
+
+				function(ready, lang, has, arr, fx, on, locale, parser, dom, domConstruct,
+					Memory, Observable, Calendar){
+
+					ready(function(){
+					
+						// Display different hint every 10 seconds 
+											
+						calendar.set("cssClassFunc", function(item){
+							// Use custom css class on renderers depending of a parameter (calendar).							
+							return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+						});
+						
+						// Calendar model creation						
+						var modelBase = [
+							{day: 1, start: [10,0], duration: 1400},
+							{day: 2, start: [10,30], duration: 120},
+							{day: 2, start: [12,0], duration: 240},
+							{day: 3, start: [6,0], duration: 180},
+							{day: 3, start: [0,0], duration: 2880, allDay: true}
+						];
+						
+						var someData = [];
+												
+						var startOfWeek = calendar.floorToWeek(new calendar.dateClassObj());
+						
+						for (var id=0; id<modelBase.length; id++) {
+							var newObj = {
+								id: id,
+								summary: "New Event " + id,
+								startTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								endTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								calendar: id%2 == 0 ? "cal1" : "cal2",
+								allDay: modelBase[id].allDay
+							};
+
+							newObj.startTime = calendar.dateModule.add(newObj.startTime, "day", modelBase[id].day);
+							newObj.startTime.setHours(modelBase[id].start[0]);
+							newObj.startTime.setMinutes(modelBase[id].start[1]);
+
+							newObj.endTime = calendar.dateModule.add(newObj.startTime, "minute", modelBase[id].duration);
+
+							someData.push(newObj);
+						}
+						
+						calendar.set("store", new Observable(new Memory({data: someData})));
+						calendar.set("date", startOfWeek);									
+						
+						contextMenuDelete.on("click", function(){
+							arr.forEach(calendar.selectedItems, function(item){
+								calendar.store.remove(item.id);
+							}); 							
+						});
+						
+						
+						var ss, se;
+						calendar.on("itemEditBegin", function(e){
+							// save initial values
+							ss = calendar.newDate(e.item.startTime);
+							se = calendar.newDate(e.item.endTime);
+						});
+						
+						calendar.on("itemEditEnd", function(e){
+							// a condition using properties of the store item and the render item
+							if(e.storeItem.calendar == "cal2" && e.item.startTime.getHours() >= 13){
+								// cancel default behavior (i.e. applying changes to store)
+								e.preventDefault();
+								
+								// set the previously values to revert changes on the render item
+								e.item.startTime = ss;
+								e.item.endTime = se;
+							} // default behavior for other use cases
+						});																					
+												
+						
+						// Hide loading panel when application is ready
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+						
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+			
+			<div data-dojo-type="dijit.layout.BorderContainer" style="width:100%;height:100%" data-dojo-props="design:'sidebar', gutters:true" >
+		    <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="splitter:false, region:'center'">
+		        <div data-dojo-id="calendar" data-dojo-type="dojox.calendar.Calendar" 
+					style="position:absolute;left:10px;top:10px;bottom:30px;right:10px">
+					<div data-dojo-type="dijit.Menu" data-dojo-id="calendarContextMenu" style="display: none;">
+		                <div data-dojo-type="dijit.MenuItem" data-dojo-id="contextMenuDelete" data-dojo-props="iconClass:'dijitIcon dijitIconDelete'">Delete</div>
+		            </div>	
+				</div>
+				<div id="hint" style="position:absolute;left:10px;height:15px;bottom:10px;right:10px;color:#999;overflow:auto">Move a blue event after 1pm, gesture is canceled.</div>
+		    </div>
+		    
+		</div>																		
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/hcalendar.html b/dojox/calendar/tests/hcalendar.html
new file mode 100755
index 0000000..2721891
--- /dev/null
+++ b/dojox/calendar/tests/hcalendar.html
@@ -0,0 +1,325 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Calendar Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/nihilo/Calendar.css";
+			@import "../themes/nihilo/Calendar_rtl.css";
+			@import "calendar.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/nihilo/nihilo.css";
+		</style>			
+	</head>
+	
+	<body class="nihilo" dir="rtl">
+		<script type="text/javascript" 
+						data-dojo-config="locale: 'en', async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/fx", "dojo/on", "dojo/date/locale", "dojo/parser",
+					"dojo/dom", "dojo/dom-construct", 
+					"dojo/store/Memory", "dojo/store/Observable",					
+					"dojox/calendar/Calendar", "dijit/Calendar",  
+					"dojox/date/hebrew", "dojox/date/hebrew/Date", "dojox/date/hebrew/locale",
+					"dijit/TitlePane", "dijit/layout/BorderContainer", 
+					"dijit/layout/ContentPane", "dijit/form/CheckBox", "dijit/form/TextBox", "dijit/form/DateTextBox", 
+					"dijit/form/TimeTextBox", "dijit/form/Button", "dijit/form/ComboBox"					
+					],
+
+				function(ready, declare, lang, arr, fx, on, locale, parser, dom, domConstruct,
+					Memory, Observable, Calendar, hCal, hDate){
+
+					ready(function(){
+						
+						calendar.set("cssClassFunc", function(item){
+							// Use custom css classes on renderers depending of a parameter (calendar). 
+							return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+						});
+						
+						// Calendar model creation
+						
+						var modelBase = [
+							{day: 1, start: [10,0], duration: 1400},
+							{day: 2, start: [10,30], duration: 120},
+							{day: 2, start: [12,0], duration: 240},
+							{day: 3, start: [6,0], duration: 180},
+							{day: 3, start: [0,0], duration: 2880, allDay: true}
+						];
+						
+						var someData = [];
+												
+						var startOfWeek = calendar.floorToWeek(new calendar.dateClassObj());
+						
+						for (var id=0; id<modelBase.length; id++) {
+							var newObj = {
+								id: id,
+								summary: "New Event " + id,
+								startTime: new calendar.dateClassObj(startOfWeek),
+								endTime: new calendar.dateClassObj(startOfWeek),
+								calendar: id%2 == 0 ? "cal1" : "cal2",
+								allDay: modelBase[id].allDay
+							};
+
+							newObj.startTime = calendar.dateModule.add(newObj.startTime, "day", modelBase[id].day);
+							newObj.startTime.setHours(modelBase[id].start[0]);
+							newObj.startTime.setMinutes(modelBase[id].start[1]);
+
+							newObj.endTime = calendar.dateModule.add(newObj.startTime, "minute", modelBase[id].duration);
+
+							someData.push(newObj);
+						}
+						
+						calendar.set("store", new Observable(new Memory({data: someData})));
+						calendar.set("date", startOfWeek);
+						
+						calendar.on("gridDoubleClick", function(e){
+
+							// create a event when double-clicking on grid.
+							var start, end;
+							var colView = calendar.columnView;
+							var cal = calendar.dateModule;
+							
+							if(e.source == colView){
+								start = calendar.floorDate(e.date, "minute", colView.timeSlotDuration);
+								end = cal.add(start, "hour", 1);
+							}else{
+								start = calendar.floorToDay(e.date);
+								end = cal.add(start, "day", 1);
+							}
+							
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: start,
+								endTime: end,
+								calendar: "cal1",
+								allDay: e.source.viewKind == "matrix"
+							};
+							
+							id++;		
+							calendar.store.add(item);
+							
+							calendar.set("selectedItem", item);
+							calendar.get("currentView").set("focusedItem", item);
+							
+							selectionChanged(item);						
+						});	
+						
+						
+						var calendarVisibility = [true, true];
+						
+						var itemToRendererKindFunc = function(item){
+							if(item.cssClass == "Calendar1" && calendarVisibility[0] ||
+								item.cssClass == "Calendar2" && calendarVisibility[1]){
+									return this._defaultItemToRendererKindFunc(item);
+								}
+							return null
+						};
+						
+						calendar.columnView.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						calendar.columnView.secondarySheet.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						calendar.matrixView.set("itemToRendererKindFunc", itemToRendererKindFunc);
+						
+						var editedItem;
+						
+						var selectionChanged = function(item){
+							
+							var itemNull = item == null;
+							
+							var widgets = [itemSummaryEditor, itemStartDateEditor, itemStartTimeEditor, itemEndDateEditor,
+								itemEndTimeEditor, calendarEditor, allDayCB, deleteItemButton, updateItemButton];
+							
+							arr.forEach(widgets, function(w){
+								w.set("disabled", itemNull);
+								w.set("value", null, false);
+							});
+							
+							editedItem = itemNull ? null : lang.mixin({}, item); 
+							
+							if(!itemNull){
+							
+								var allDay = item.allDay === true;
+								
+								itemStartTimeEditor.set("disabled", allDay);
+								itemEndTimeEditor.set("disabled", allDay);
+																
+								itemSummaryEditor.set("value", item.summary);
+								itemStartDateEditor.set("value", item.startTime);
+								itemStartTimeEditor.set("value", item.startTime);
+								itemEndDateEditor.set("value", item.endTime);
+								itemEndTimeEditor.set("value", item.endTime);
+								calendarEditor.set("value", item.calendar == "cal1" ? "Calendar 1" : "Calendar 2");																					
+								allDayCB.set("checked", allDay, false);
+							}																						
+						};
+						
+						calendar.on("change", function(e){							
+							selectionChanged(e.newValue);							
+						});	
+						
+						allDayCB.on("change", function(value){
+							
+							itemStartTimeEditor.set("disabled", value);
+							itemEndTimeEditor.set("disabled", value);
+							
+							var d;
+							if(value){
+								d = itemStartTimeEditor.get("value");
+								calendar.floorToDay(d, true);
+								itemStartTimeEditor.set("value", d);
+								d = itemEndTimeEditor.get("value");
+								calendar.floorToDay(d, true);
+								itemEndTimeEditor.set("value", d);
+								
+								if(!calendar.isStartOfDay(editedItem.endTime)){
+									d = itemEndDateEditor.get("value");
+									calendar.floorToDay(d, true);
+									d = calendar.dateModule.add(d, "day", 1);
+									itemEndDateEditor.set("value", d);
+								}
+								
+							}else{
+								editedItem.startTime.setHours(8);
+								editedItem.endTime.setHours(9);
+								itemStartTimeEditor.set("value", editedItem.startTime);
+								itemEndTimeEditor.set("value", editedItem.endTime);
+								d = itemEndDateEditor.get("value");
+								calendar.floorToDay(d, true);
+								d = calendar.dateModule.add(d, "day", -1);
+								itemEndDateEditor.set("value", d);
+							}
+							
+						});
+						
+						var mergeDateTime = function(isStart){
+							var dateEditor = isStart ? itemStartDateEditor : itemEndDateEditor;
+							var timeEditor = isStart ? itemStartTimeEditor : itemEndTimeEditor;
+							var date = dateEditor.get("value");
+							var time = timeEditor.get("value");
+							date.setHours(time.getHours());
+							date.setMinutes(time.getMinutes());
+							return date;
+						};
+						
+						updateItemButton.on("click", function(value){
+							
+							if (editedItem != null) {
+								editedItem.summary = itemSummaryEditor.get("value");
+								if(allDayCB.get("value")){
+									if(!calendar.isStartOfDay(editedItem.startTime)){
+										editedItem.startTime = calendar.floorToDay(itemStartDateEditor.get("value"), true);
+									}
+									if(!calendar.isStartOfDay(editedItem.endTime)){
+										editedItem.endTime = calendar.floorToDay(itemEndDateEditor.get("value"), true);
+									}			
+									editedItem.allDay = true;						
+								}else{
+									editedItem.startTime = mergeDateTime(true);
+									editedItem.endTime = mergeDateTime(false);
+									delete editedItem.allDay;
+								}
+								
+								var calValue = calendarEditor.get("value");
+								editedItem.calendar = calValue == "Calendar 1" ? "cal1" : "cal2";
+								calendar.store.put(editedItem);
+							}
+							
+						});
+						
+						deleteItemButton.on("click", function(value){
+							if (editedItem != null) {
+								calendar.store.remove(editedItem.id);								
+							}
+						});
+																										
+																							
+						dateChooser.set("value", startOfWeek);
+						dateChooser.on("change", function(e){
+							var d = dateChooser.get("value");
+							calendar.set("date", d);
+						});						
+										
+						calendar1CB.on("change", function(v){
+							calendarVisibility[0] = v;
+							calendar.currentView.invalidateLayout();
+						});
+						
+						calendar2CB.on("change", function(v){
+							calendarVisibility[1] = v;
+							calendar.currentView.invalidateLayout();
+						});											
+						
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+			
+			<div data-dojo-type="dijit.layout.BorderContainer" style="width:100%;height:100%" data-dojo-props="design:'sidebar', gutters:true" >
+		    <div data-dojo-type="dijit.layout.ContentPane" style="width:200px" data-dojo-props="splitter:false, region:'leading'">
+		        <div data-dojo-id="dateChooser" data-dojo-type="dijit.Calendar" data-dojo-props="datePackage: 'dojox.date.hebrew'" style="width:100%"></div>
+						<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'Calendars', style:'margin-top:10px;'" >
+							<div>
+								<input type="checkbox" data-dojo-id="calendar1CB" data-dojo-type="dijit.form.CheckBox" checked="true"/>
+								<label for="calendar1CB">Calendar 1</label>
+							</div>
+									
+							<div style="margin-top:5px">
+								<input type="checkbox" data-dojo-id="calendar2CB" data-dojo-type="dijit.form.CheckBox" checked="true"/>
+								<label for="calendar2CB">Calendar 2</label>
+							</div>
+						</div>
+						<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'Event properties', style:'margin-top:10px;'" >
+							<div><span class="propertyTitle">Summary:</span></div>
+							<div data-dojo-id="itemSummaryEditor" data-dojo-type="dijit.form.TextBox" style="width:165px;" data-dojo-props="disabled:true"></div>
+							<div style="margin-top:10px"><span class="propertyTitle">Start:</span></div>
+							<div>
+								<div data-dojo-id="itemStartDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:90px;"  data-dojo-props="disabled:true"></div>
+								<div data-dojo-id="itemStartTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:70px;" data-dojo-props="disabled:true" ></div>
+							</div>
+							<div style="margin-top:10px"><span class="propertyTitle">End:</span></div>
+							<div>
+								<div data-dojo-id="itemEndDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:90px;" data-dojo-props="disabled:true" ></div>
+								<div data-dojo-id="itemEndTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:70px;" data-dojo-props="disabled:true" ></div>
+							</div>
+							<div style="margin-top:10px"><span class="propertyTitle">Calendar:</span></div>
+							<select data-dojo-id="calendarEditor" data-dojo-type="dijit.form.ComboBox"  style="width:165px;" data-dojo-props="disabled:true" >
+								<option>Calendar 1</option>
+								<option>Calendar 2</option>									
+							</select>
+							<div style="margin-top:10px">
+								<input type="checkbox" data-dojo-id="allDayCB" data-dojo-type="dijit.form.CheckBox" checked="false" data-dojo-props="disabled:true" />
+								<label for="allDayCB">All day</label>
+							</div>	
+							<div style="margin-top:10px">
+								<span style="text-align:left">
+									<button data-dojo-id="deleteItemButton" class="deleteButton" data-dojo-type="dijit.form.Button"  data-dojo-props="disabled:true">Delete</button>
+								</span>
+								<span style="text-align:right">
+									<button data-dojo-id="updateItemButton" data-dojo-type="dijit.form.Button" data-dojo-props="disabled:true" >Update</button>
+								</span>
+							</div>
+						</div>
+		    </div>
+		    <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="splitter:false, region:'center'">
+		        <div data-dojo-id="calendar" data-dojo-type="dojox.calendar.Calendar" data-dojo-props="datePackage: 'dojox.date.hebrew', textDir:'rtl'"
+									style="position:absolute;left:10px;top:10px;bottom:10px;right:10px"></div>
+		    </div>
+		</div>																		
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/isItemEditable.html b/dojox/calendar/tests/isItemEditable.html
new file mode 100644
index 0000000..703ccb4
--- /dev/null
+++ b/dojox/calendar/tests/isItemEditable.html
@@ -0,0 +1,163 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Calendar Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/Calendar.css";
+			@import "calendar.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			html{
+				font-family: Lucida grande, Tahoma, Verdana, Arial, Sans-serif;
+			}
+			#calendarNode {
+		      position:absolute;
+		      left: 10px;
+		      right: 10px;
+		      top: 10px;
+		      bottom: 10px;
+		    } 
+		</style>			
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: false"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/_base/declare", "dojo/ready", "dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/array", "dojo/_base/fx", "dojo/dom-class", "dojo/on", 
+			         "dojo/date/locale", "dojo/parser",	"dojo/dom", "dojo/dom-construct",	"dojo/store/Memory", 
+			         "dojo/store/Observable",	"dojox/calendar/Calendar", "dijit/Menu", "dijit/CheckedMenuItem"],
+
+				function(declare, ready, lang, has, arr, fx, domClass, on, locale, parser, dom, domConstruct,
+					Memory, Observable, Calendar){
+
+					ready(function(){
+						
+						var ECalendar = declare("extended.Calendar", Calendar, {
+
+						  isItemEditable: function(item, rendererKind){
+						    return this.editable && item.editable;
+						  },
+
+						  isItemResizeEnabled: function(item, rendererKind){
+						      return this.isItemEditable(item, rendererKind) && item.resizeEnabled;
+						  },
+						  
+						  isItemMoveEnabled: function(item, rendererKind){
+						      return this.isItemEditable(item, rendererKind) && item.moveEnabled;
+						  }
+						});
+						
+						
+						// parse after class definition										
+ 						parser.parse();
+																					
+						calendar.set("cssClassFunc", function(item){
+							// Use custom css class on renderers depending of a parameter (calendar).							
+							return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+						});
+						
+						// Calendar model creation						
+						var modelBase = [
+							{day: 1, start: [10,0], duration: 1400},
+							{day: 2, start: [10,30], duration: 120},
+							{day: 2, start: [12,0], duration: 240},
+							{day: 3, start: [6,0], duration: 180},
+							{day: 3, start: [0,0], duration: 2880, allDay: true}
+						];
+						
+						var someData = [];
+												
+						var startOfWeek = calendar.floorToWeek(new calendar.dateClassObj());
+						
+						for (var id=0; id<modelBase.length; id++) {
+							var newObj = {
+								id: id,
+								summary: "New Event " + id,
+								startTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								endTime: new calendar.dateClassObj(startOfWeek.getTime()),
+								calendar: id%2 == 0 ? "cal1" : "cal2",
+								editable: true,
+								resizeEnabled: true,
+								moveEnabled:true,
+								allDay: modelBase[id].allDay
+							};
+
+							newObj.startTime = calendar.dateModule.add(newObj.startTime, "day", modelBase[id].day);
+							newObj.startTime.setHours(modelBase[id].start[0]);
+							newObj.startTime.setMinutes(modelBase[id].start[1]);
+
+							newObj.endTime = calendar.dateModule.add(newObj.startTime, "minute", modelBase[id].duration);
+
+							someData.push(newObj);
+						}
+						
+						var store = new Observable(new Memory({data: someData}));
+						calendar.set("store", store);
+						calendar.set("date", startOfWeek);
+						
+						// show context menu on right clicking an event
+						calendar.on("itemContextMenu", function(e){
+							dojo.stopEvent(e.triggerEvent);
+							calendarContextMenu._openMyself({ 
+								target: e.renderer.domNode, 
+								coords: {x: e.triggerEvent.pageX, y: e.triggerEvent.pageY} 
+							});
+						});
+						
+						contextMenuEditable.on("click", function(e){
+							arr.forEach(calendar.selectedItems, function(item){
+								item.editable = contextMenuEditable.get("checked");
+								calendar.store.put(item, {overwrite: true});
+							}); 
+						});
+						
+						contextMenuMove.on("click", function(e){
+							arr.forEach(calendar.selectedItems, function(item){
+								item.moveEnabled = contextMenuMove.get("checked");
+								calendar.store.put(item, {overwrite: true});
+							}); 
+						});
+						
+						contextMenuResize.on("click", function(e){
+							arr.forEach(calendar.selectedItems, function(item){
+								item.resizeEnabled = contextMenuResize.get("checked");
+								calendar.store.put(item, {overwrite: true});
+							}); 
+						});
+						
+						
+						// Hide loading panel when application is ready
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+																																
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+  			<div id="calendarNode" data-dojo-id="calendar" data-dojo-type="extended.Calendar">
+  				<div data-dojo-type="dijit.Menu" data-dojo-id="calendarContextMenu" style="display: none;">
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-id="contextMenuEditable" data-dojo-props="checked:true">Editable</div>
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-id="contextMenuMove" data-dojo-props="checked:true">Move enabled</div>
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-id="contextMenuResize" data-dojo-props="checked:true">Resize enabled</div>
+				</div>
+			</div>
+			
+		    
+		</div>																		
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/matrixtablet.css b/dojox/calendar/tests/matrixtablet.css
new file mode 100644
index 0000000..6ab6c67
--- /dev/null
+++ b/dojox/calendar/tests/matrixtablet.css
@@ -0,0 +1,14 @@
+html, body {
+    margin: 0;
+    padding: 0;
+    width: 100%;
+    height: 100%;
+}
+
+#calendarNode {
+	position:absolute; 
+	left:5px; 
+	right:5px; 
+	top:5px; 
+	bottom:5px;
+}
\ No newline at end of file
diff --git a/dojox/calendar/tests/matrixtablet.html b/dojox/calendar/tests/matrixtablet.html
new file mode 100644
index 0000000..1fa8c20
--- /dev/null
+++ b/dojox/calendar/tests/matrixtablet.html
@@ -0,0 +1,190 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		
+		<title>MatrixView Sample: Tablet</title>				
+		<style type="text/css">
+			@import "../themes/iphone/MatrixView.css";
+			@import "matrixtablet.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+	</head>
+	
+	<body>
+			<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/declare", "dojo/on", "dojo/date/locale", "dojo/parser", "dojo/date", "dojo/_base/lang",
+					"dojo/dom", "dojo/dom-construct", "dojo/dom-class", "dojo/_base/window",
+					"dijit/registry", "dojo/query", "dojox/calendar/MatrixView", "dojox/calendar/Touch", 
+					"dojox/calendar/MobileHorizontalRenderer", "dojox/calendar/LabelRenderer", "dojox/calendar/ExpandRenderer", "dojo/store/Memory", "dojo/store/Observable",
+					 "dojo/_base/fx"],
+
+				function(ready, declare, on, locale, parser, date, lang, dom, domConstruct, domClass, win, registry, query,
+					MatrixView, CalendarTouch, HorizontalRenderer, LabelRenderer, ExpandRenderer, Memory, Observable, fx){
+
+					ready(function(){
+
+						// Calendar model creation
+						
+						var dateClassObj = Date;
+						
+						var modelBase = [
+							{day: 0, start: [0,0], duration: 1440, allDay:true},
+							{day: 1, start: [6,0], duration: 240},
+							{day: 1, start: [10,0], duration: 240},
+							{day: 1, start: [16,0], duration: 60},
+							{day: 2, start: [8,0], duration: 120},
+							{day: 2, start: [10,0], duration: 120},
+							{day: 2, start: [16,0], duration: 120},
+							{day: 3, start: [8,0], duration: 1440*2},
+							{day: 5, start: [0,0], duration: 1440, allDay:true},
+							{day: 6, start: [0,0], duration: 2*1440, allDay:true}
+						];
+																
+						// TODO manage first day of week
+						var floorToWeek= function(d){
+							d.setHours(0);
+							d.setMinutes(0);
+							d.setSeconds(0);
+							d.setMilliseconds(0);
+							d = date.add(d, "day", -d.getDay());
+							return d;
+						};
+						
+						var someData = [];
+						
+						var startOfWeek = new dateClassObj();
+						startOfWeek = floorToWeek(startOfWeek);
+												
+						var id;
+						for (var w=0; w<5; w++) {
+							for (var i=0; i<modelBase.length; i++) {
+								id = (w*modelBase.length)+i;
+								var newObj = {
+									id: id,
+									summary: "New Event " + id,
+									startTime: new dateClassObj(startOfWeek.getTime()),
+									endTime: new dateClassObj(startOfWeek.getTime())
+								};
+	
+								newObj.startTime = date.add(newObj.startTime, "day", Math.floor(Math.random()*7));
+								newObj.startTime.setHours(modelBase[i].start[0]);
+								newObj.startTime.setMinutes(modelBase[i].start[1]);
+	
+								newObj.endTime = date.add(newObj.startTime, "minute", modelBase[i].duration);
+								
+								if(modelBase[i].allDay != undefined){
+									newObj.allDay = modelBase[i].allDay; 
+								}
+	
+								someData.push(newObj);
+							}
+							startOfWeek = date.add(startOfWeek, "day", 7);
+						}
+						
+						id++;
+						
+						// Calendar creation & configuration
+						
+						matrixView = declare([MatrixView, CalendarTouch])({
+							startDate: startOfWeek,
+							store: new Observable(new Memory({data: someData})),		
+							horizontalRenderer: HorizontalRenderer,
+							horizontalRendererHeight: 20,
+							labelRenderer: LabelRenderer,
+							labelRendererHeight: 15,
+							expandRenderer: ExpandRenderer,
+							expandRendererHeight: 20,
+							verticalGap:2
+						}, "calendarNode");
+						
+						var setRowWidth = function(value){
+							matrixView.grid.style.left = value + "px";
+							matrixView.yearColumnHeader.style.width = value + "px";
+							matrixView.columnHeader.style.left = value + "px";
+							matrixView.rowHeader.style.width = value + "px";
+							matrixView.itemContainer.style.left = value + "px";							
+						};
+						
+						window.onresize = window.onorientationchange = function(e){
+							matrixView.resize();
+							var n = matrixView.domNode;
+							if(n.offsetWidth > n.offsetHeight){
+								matrixView.columnHeaderLabelLength = "wide";
+								matrixView.set("rowCount", 2);								
+								setRowWidth(50);
+							}else{
+								matrixView.columnHeaderLabelLength = "abbr";
+								matrixView.set("rowCount", 4);
+								setRowWidth(20);								
+							}
+						};
+						
+						window.onresize();
+
+						// Events management
+						
+						matrixView.on("gridDoubleClick", function(e){
+
+							// create a event when double-clicking on grid.
+							var d = matrixView.floorToDay(e.date, true);
+
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: d,
+								endTime: date.add(d, "day", 1)
+							};
+							id++;
+							matrixView.store.add(item);
+							
+							matrixView.set("selectedItem", item);
+							matrixView.set("focusedItem", item);
+							onMatrixViewChange(item);
+						});
+
+						matrixView.on("rowHeaderClick", function(e){
+							var expIndex = matrixView.getExpandedRowIndex();
+							if(expIndex == e.index){
+								matrixView.collapseRow();
+							}else if(expIndex == -1){
+								matrixView.expandRow(e.index);
+							}else{
+								var h = matrixView.on("expandAnimationEnd", function(){
+									h.remove();
+									matrixView.expandRow(e.index);
+								});
+								matrixView.collapseRow();
+							}
+						});																																				
+																													
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff;text-align: center">
+				<span style="background: #DBEB8F">Loading...</span>
+			</div>
+						
+			<div id="calendarNode"></div>					
+
+	</body>
+</html>
diff --git a/dojox/calendar/tests/matrixview.css b/dojox/calendar/tests/matrixview.css
new file mode 100644
index 0000000..049ba7f
--- /dev/null
+++ b/dojox/calendar/tests/matrixview.css
@@ -0,0 +1,120 @@
+ .claro .dojoxCalendarMatrixView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent {
+	font-size: 11px;
+}
+
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Calendar2 .bg {
+	background: #2095B4;
+}
+
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Calendar2.Hovered .bg {
+	background: #24A5C8;
+}
+
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Calendar2.Selected .bg {
+	background: #166B81;
+}
+
+html, body {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+#formDiv {
+	position:absolute;
+	left:10px;					
+	width: 250px;
+	top: 0;
+	bottom: 0;
+	margin-bottom: 10px;
+	overflow-y: auto;
+}
+
+.formPanel {
+	width: 230px;
+	margin-top: 10px;
+}
+
+#formDiv table {
+	width: 100%;					
+}
+
+.formTable td:first-child {
+	text-align: right;
+	padding-right: 10px;
+	font-size: 0.9em;
+}
+
+.smallText {
+	font-size:0.9em;
+}
+
+.disabled{
+	color: #CCCCCC;
+}
+
+#calendarNode {
+	position:absolute; 
+	left:270px; 
+	right:10px; 
+	top:10px; 
+	bottom:120px;
+}
+
+#eventLogPane {
+	position:absolute; 
+	left:270px; 
+	right:10px; 
+	height: 100px;
+	bottom:10px;	
+}
+
+#logTableContainer{	
+	width:100%;
+	height:100%;
+	overflow-y:auto;	
+}
+
+#eventLogPane .dijitTitlePaneTitle{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: 20px
+}
+
+#eventLogPane .dijitTitlePaneContentOuter{
+	position: absolute;
+	left: 0; 
+	right: 0; 
+	top: 25px; 
+	bottom: 0;
+}
+
+#eventLogPane .dijitTitlePaneContentInner{
+	position: relative;
+	width: 100%; 
+	height: 100%; 
+	padding: 0;
+}
+
+#eventLogPane .dijitReset{
+	position: relative; 
+	width: 100%; 
+	height: 100%;
+}
+
+#eventLogPane .dijitArrowNode{
+	display: none;
+}
+
+#logTable{
+	width: 100%;	
+	position:relative;
+}
diff --git a/dojox/calendar/tests/matrixview.html b/dojox/calendar/tests/matrixview.html
new file mode 100644
index 0000000..2cf7d9c
--- /dev/null
+++ b/dojox/calendar/tests/matrixview.html
@@ -0,0 +1,766 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>MatrixView Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/MatrixView.css";
+			@import "matrixview.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>			
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/declare", "dojo/on", "dojo/date/locale", "dojo/parser", "dojo/date", "dojo/_base/lang",
+					"dojo/dom", "dojo/dom-construct", "dojo/dom-class", "dojo/_base/window",
+					"dijit/registry", "dojo/query", "dojox/calendar/MatrixView", "dojox/calendar/Keyboard", "dojox/calendar/Mouse", 
+					"dojox/calendar/HorizontalRenderer", "dojox/calendar/LabelRenderer", "dojox/calendar/ExpandRenderer", "dojo/store/Memory", "dojo/store/Observable",
+					"dijit/form/VerticalSlider", "dijit/form/NumberSpinner", 
+					"dijit/form/ComboBox", "dijit/form/DateTextBox", "dijit/form/TimeTextBox", "dijit/form/TextBox", 
+					"dijit/form/Button", "dijit/TitlePane", "dijit/Tooltip", 
+					"dijit/form/CheckBox", "dojo/_base/fx"],
+
+				function(ready, declare, on, locale, parser, date, lang, dom, domConstruct, domClass, win, registry, query,
+					MatrixView, CalendarKeyboard, CalendarMouse, HorizontalRenderer, LabelRenderer, ExpandRenderer, Memory, Observable, VerticalSlider, 
+					NumberSpinner, ComboBox, DateTextBox, TimeTextBox, TextBox, Button, TitlePane, Tooltip, CheckBox, fx){
+
+					ready(function(){
+
+						// singleton
+						win.doc.appState = {
+							moveDisabledMap: {},
+							resizeDisabledMap: {}
+						};
+						
+						var mergeDateTime = function(isStart){
+							var dateEditor = isStart ? itemStartDateEditor : itemEndDateEditor;
+							var timeEditor = isStart ? itemStartTimeEditor : itemEndTimeEditor;
+							var date = dateEditor.get("value");
+							var time = timeEditor.get("value");
+							date.setHours(time.getHours());
+							date.setMinutes(time.getMinutes());
+							return date;
+						};
+						
+						var addLogEntry = function(name, content){
+							var tr = domConstruct.create("tr", null, dom.byId("logBody"), "first");
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(locale.format(new Date(), {selector:"time", timePattern:"h:mm:ss"})));
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(name));
+							td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(content));
+						};
+
+						// Calendar model creation
+						
+						var dateClassObj = Date;
+						
+						var modelBase = [
+							{day: 0, start: [0,0], duration: 1440, allDay:true},
+							{day: 1, start: [6,0], duration: 240},
+							{day: 1, start: [10,0], duration: 240},
+							{day: 1, start: [16,0], duration: 60},
+							{day: 2, start: [8,0], duration: 120},
+							{day: 2, start: [10,0], duration: 120},
+							{day: 2, start: [16,0], duration: 120},
+							{day: 3, start: [8,0], duration: 1440*2},
+							{day: 5, start: [0,0], duration: 1440, allDay:true},
+							{day: 6, start: [0,0], duration: 2*1440, allDay:true}
+						];
+						
+						// TODO manage first day of week
+						var floorToWeek= function(d){
+							d.setHours(0);
+							d.setMinutes(0);
+							d.setSeconds(0);
+							d.setMilliseconds(0);
+							d = date.add(d, "day", -d.getDay());
+							return d;
+						};
+						
+						var someData = [];
+						
+						var startOfWeek = new dateClassObj();
+						startOfWeek = floorToWeek(startOfWeek);
+												
+						startDateEditor.set("value", startOfWeek);
+						
+						var id;
+						for (var w=0; w<5; w++) {
+							for (var i=0; i<modelBase.length; i++) {
+								id = (w*modelBase.length)+i;
+								var newObj = {
+									id: id,
+									summary: "New Event " + id,
+									startTime: new dateClassObj(startOfWeek.getTime()),
+									endTime: new dateClassObj(startOfWeek.getTime()),
+									calendar: i%2 == 0 ? "cal1" : "cal2"
+								};
+	
+								newObj.startTime = date.add(newObj.startTime, "day", Math.floor(Math.random()*7));
+								newObj.startTime.setHours(modelBase[i].start[0]);
+								newObj.startTime.setMinutes(modelBase[i].start[1]);
+	
+								newObj.endTime = date.add(newObj.startTime, "minute", modelBase[i].duration);
+								
+								if(modelBase[i].allDay != undefined){
+									newObj.allDay = modelBase[i].allDay; 
+								}
+	
+								someData.push(newObj);
+							}
+							startOfWeek = date.add(startOfWeek, "day", 7);
+						}
+						
+						id++;
+						
+						// Calendar creation & configuration
+						
+						matrixView = declare([MatrixView, CalendarKeyboard, CalendarMouse])({
+							
+							store: new Observable(new Memory({data: someData})),		
+							horizontalRenderer: HorizontalRenderer,
+							labelRenderer: LabelRenderer,
+							expandRenderer: ExpandRenderer,
+							verticalGap:4,
+							cssClassFunc: function(item){
+								return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+							},
+							isItemMoveEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.moveDisabledMap[item.id] !== true;
+							},
+							isItemResizeEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.resizeDisabledMap[item.id] !== true;
+							}
+						}, "calendarNode");
+						
+						// matrix view is *not* in a dijit container, must register resize handler
+						window.onresize = function(e){
+							matrixView.resize(e);
+						};
+
+						// Events management
+						
+						matrixView.on("gridDoubleClick", function(e){
+
+							// create a event when double-clicking on grid.
+							var d = matrixView.floorToDay(e.date, true);
+
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: d,
+								endTime: date.add(d, "day", 1),
+								calendar: id % 2 == 0 ? "cal1" : "cal2"
+							};
+							id++;
+							matrixView.store.add(item);
+							
+							matrixView.set("selectedItem", item);
+							matrixView.set("focusedItem", item);
+							onMatrixViewChange(item);
+						});
+
+						matrixView.on("rowHeaderClick", function(e){
+							var expIndex = matrixView.getExpandedRowIndex();
+							if(expIndex == e.index){
+								matrixView.collapseRow();
+							}else if(expIndex == -1){
+								matrixView.expandRow(e.index);
+							}else{
+								var h = matrixView.on("expandAnimationEnd", function(){
+									h.remove();
+									matrixView.expandRow(e.index);
+								});
+								matrixView.collapseRow();
+							}
+						});
+						
+						var editedItem;
+						
+						var onMatrixViewChange = function(item){
+
+							if (item == null){
+								editedItem = null;
+								
+								itemSummaryEditor.set("value", null);
+								itemSummaryEditor.set("disabled", true);
+								
+								itemStartDateEditor.set("value", null);
+								itemStartDateEditor.set("disabled", true);
+								
+								itemStartTimeEditor.set("value", null);
+								itemStartTimeEditor.set("disabled", true);
+								
+								itemEndDateEditor.set("value", null);
+								itemEndDateEditor.set("disabled", true);
+								
+								itemEndTimeEditor.set("value", null);
+								itemEndTimeEditor.set("disabled", true);
+								
+								updateItemButton.set("disabled", true);
+								
+								allDayCB.set("disabled", true);
+								allDayCB.set("checked", false, false);
+								
+								resizeEnabledCB.set("disabled", true);
+								resizeEnabledCB.set("checked", false);
+								
+								moveEnabledCB.set("disabled", true);
+								moveEnabledCB.set("checked", false);
+								
+								calendarEditor.set("disabled", true);
+								
+							}else{
+								
+								editedItem = lang.mixin({}, item);
+								
+								var allDay = item.allDay === true;
+																
+								itemSummaryEditor.set("value", item.summary);
+								itemSummaryEditor.set("disabled", false);
+								
+								itemStartDateEditor.set("value", item.startTime);
+								itemStartDateEditor.set("disabled", false);
+								
+								itemStartTimeEditor.set("value", item.startTime);
+								itemStartTimeEditor.set("disabled", allDay);
+								
+								itemEndDateEditor.set("value", item.endTime);
+								itemEndDateEditor.set("disabled", false);
+								
+								itemEndTimeEditor.set("value", item.endTime);
+								itemEndTimeEditor.set("disabled", allDay);
+								
+								calendarEditor.set("value", item.calendar == "cal1" ? "Calendar 1" : "Calendar 2");
+								
+								updateItemButton.set("disabled", false);
+								calendarEditor.set("disabled", false);	
+								
+								allDayCB.set("disabled", false);
+								allDayCB.set("checked", allDay, false);
+								
+								resizeEnabledCB.set("disabled", false);
+								resizeEnabledCB.set("checked", win.doc.appState.resizeDisabledMap[item.id] !== true);
+								
+								moveEnabledCB.set("disabled", false);
+								moveEnabledCB.set("checked", win.doc.appState.moveDisabledMap[item.id] !== true);
+							}
+
+							var res = "";
+							if(item == null){
+								res = null;
+							}else{
+								var list = matrixView.get("selectedItems");
+								for(var i=0; i<list.length; i++){
+									res += list[i].summary;
+									if(i != list.length-1){
+										res += ", ";
+									}
+								}
+							}
+							addLogEntry("onChange", res);
+						};
+						
+
+						allDayCB.on("change", function(value){
+							
+							itemStartTimeEditor.set("disabled", value);
+							itemEndTimeEditor.set("disabled", value);
+							var d;
+							if(value){
+								d = itemStartTimeEditor.get("value");
+								matrixView.floorToDay(d, true);
+								itemStartTimeEditor.set("value", d);
+								d = itemEndTimeEditor.get("value");
+								matrixView.floorToDay(d, true);
+								itemEndTimeEditor.set("value", d);
+								
+								if(!matrixView.isStartOfDay(editedItem.endTime)){
+									d = itemEndDateEditor.get("value");
+									matrixView.floorToDay(d, true);
+									d = matrixView.renderData.dateModule.add(d, "day", 1);
+									itemEndDateEditor.set("value", d);
+								}
+								
+							}else{
+								editedItem.startTime.setHours(8);
+								editedItem.endTime.setHours(9);
+								itemStartTimeEditor.set("value", editedItem.startTime);
+								itemEndTimeEditor.set("value", editedItem.endTime);
+								d = itemEndDateEditor.get("value");
+								matrixView.floorToDay(d, true);
+								d = matrixView.renderData.dateModule.add(d, "day", -1);
+								itemEndDateEditor.set("value", d);
+							}
+							
+						});
+						
+						matrixView.on("change", function(e){
+							onMatrixViewChange(e.newValue);
+						});
+						
+						startDateEditor.on("change", function(value){
+							matrixView.set("startDate", value);
+						});
+						
+						updateItemButton.on("click", function(value){
+							
+							if (editedItem != null) {
+								editedItem.summary = itemSummaryEditor.get("value");
+								if(allDayCB.get("value")){
+									if(!matrixView.isStartOfDay(editedItem.startTime)){
+										editedItem.startTime = matrixView.floorToDay(itemStartDateEditor.get("value"), true);
+									}
+									if(!matrixView.isStartOfDay(editedItem.endTime)){
+										editedItem.endTime = matrixView.floorToDay(itemEndDateEditor.get("value"), true);
+									}			
+									editedItem.allDay = true;						
+								}else{
+									editedItem.startTime = mergeDateTime(true);
+									editedItem.endTime = mergeDateTime(false);
+									delete editedItem.allDay;
+								}
+								
+								var calValue = calendarEditor.get("value");
+								editedItem.calendar = calValue == "Calendar 1" ? "cal1" : "cal2";
+								matrixView.store.put(editedItem);
+							}
+							
+						});
+
+						dateFormatButton.on("click", function(){
+							matrixView.set("rowHeaderDatePattern", rowHeaderFormatEditor.value);
+							//matrixView.set("columnHeaderDatePattern", columnHeaderFormatEditor.value);
+							
+							matrixView.set("cellHeaderLongPattern", cellLongFormatEditor.value);
+							matrixView.set("cellHeaderShortPattern", cellShortFormatEditor.value);
+						});
+						
+						var formatItemTimeFunc = function(d, rd){
+							return rd.dateLocaleModule.format(d, {
+								selector: 'time', 
+								timePattern: d.getMinutes() == 0 ? "ha":"h:mma"}
+							).toLowerCase();
+						};
+						
+						customTimeFormatCB.on("change", function(value){
+							matrixView.set("formatItemTimeFunc", value ? formatItemTimeFunc : null);
+						});
+												
+						matrixView.on("itemClick", function(e){
+							addLogEntry("onItemClick", e.item.summary);
+						});
+						matrixView.on("itemDoubleClick", function(e){
+							addLogEntry("onItemDoubleClick", e.item.summary);
+						});
+						matrixView.on("gridClick", function(e){
+							addLogEntry("onGridClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});
+						matrixView.on("gridDoubleClick", function(e){
+							addLogEntry("onGridDoubleClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});
+
+						matrixView.on("itemRollOut", function(e){
+							addLogEntry("onItemRollOut", e.item.summary);
+						});
+
+						var getDataTipLabel = function(item){
+							return "<b>" + item.summary + "</b><br/><table><tr><td style='text-align:right'>" + 
+								"Start:</td><td>" + matrixView.renderData.dateLocaleModule.format(item.startTime, {formatLength: "short"}) + "</td></tr><tr><td style='text-align:right'>" + 
+								"End:</td><td>" + matrixView.renderData.dateLocaleModule.format(item.endTime, {formatLength: "short"}) + "</td></tr></table>";
+						};
+						
+						matrixView.on("focusChange", function(e){
+							addLogEntry("focusChange", e.newValue ? e.newValue.summary: "null");					
+						}); 
+												
+						matrixView.on("itemRollOver", function(e){							
+							addLogEntry("onItemRollOver", e.item.summary);																				
+						});
+						
+						matrixView.on("itemEditBegin", function(e){							
+							addLogEntry("onItemEditBegin", e.item.summary);							
+						});
+						
+						matrixView.on("itemEditBeginGesture", function(e){
+							addLogEntry("onItemEditBeginGesture", e.editKind + ", " + e.item.summary);							
+						});
+
+                        var showDataTipAfterLayout = false;
+						matrixView.on("itemEditMoveGesture", function(e){
+							showDataTipAfterLayout = true;
+						});
+						
+						matrixView.on("itemEditEndGesture", function(e){
+							addLogEntry("onItemEditEndGesture", e.editKind + ", " + e.item.summary);							
+							
+							onMatrixViewChange(e.item);
+
+						});
+						
+						matrixView.on("itemEditEnd", function(e){
+							addLogEntry("onItemEditEnd", e.item.summary + ", completed:" + e.completed);										
+						});
+																	
+						editableCB.on("change", function(value){
+							matrixView.set("editable", value);
+						});
+						
+						keyEditableCB.on("change", function(value){
+							matrixView.set("keyboardEditable", value);
+						});
+						
+						liveEditCB.on("change", function(value){
+							matrixView.liveLayout = value;
+						});
+												
+						allowSwapCB.on("change", function(value){							
+							matrixView.allowStartEndSwap = value;
+						});
+						
+						viewConstrainCB.on("change", function(value){							
+							matrixView.stayInView = value;
+						});											
+												
+						resizeEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("resizeEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("resizeEnabledCBLabel", "disabled");
+							}							
+						});
+
+						moveEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("moveEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("moveEnabledCBLabel", "disabled");
+							}
+						});
+						
+						resizeEnabledCB.on("change", function(value){
+							if (matrixView.selectedItem) {
+								if (value){
+									delete win.doc.appState.resizeDisabledMap[matrixView.selectedItem.id]	
+								} else {
+									win.doc.appState.resizeDisabledMap[matrixView.selectedItem.id] = true;
+								}								
+							}
+						});
+
+						moveEnabledCB.on("change", function(value){
+							if (matrixView.selectedItem) {
+								if (value){
+									delete win.doc.appState.moveDisabledMap[matrixView.selectedItem.id]	
+								} else {
+									win.doc.appState.moveDisabledMap[matrixView.selectedItem.id] = true;
+								}
+							}
+						});
+
+						roundToDayCB.on("change", function(value){
+							matrixView.set("roundToDay", value);
+						});
+
+						overlapEditor.on("change", function(value){
+							matrixView.set("percentOverlap", this.value);
+							vGapEditor.set("disabled", value!=0);
+						});
+						
+						// the item to renderer kind functions.
+						var itemToRendererKindFuncs = [
+							null, 
+							function(item){ return "horizontal"; },
+							function(item){ return item.allDay ? "horizontal" : "label"},
+							function(item){ return "label"}
+						]; 
+						
+						rendererKindEditor.set("store", new Memory({data:[
+							{id:0, label: "default"},
+							{id:1, label: "All horizontals"},
+							{id:2, label: "Only all day horizontals"},
+							{id:3, label: "All labels"}
+						]}));
+						
+						rendererKindEditor.watch("item", function(prop, oldValue, newValue){
+							matrixView.set("itemToRendererKindFunc", itemToRendererKindFuncs[newValue.id]);
+						});
+												
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff;text-align: center">
+				<span style="background: #DBEB8F">Loading...</span>
+			</div>
+			
+			<div id="formDiv">
+				
+				<div data-dojo-type="dijit.TitlePane" title="Date Interval" class="formPanel">
+					<table class="formTable">	
+						<tr>
+							<td>Start date:</td>
+							<td><div data-dojo-id="startDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:80px" ></div></td>
+						</tr>
+						
+						<tr>
+							<td>Column count:</td>
+							<td><div data-dojo-id="columnCountEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:1, max:14}" value="7" intermediateChanges="true" onChange="matrixView.set('columnCount', this.value);"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Row count:</td>
+							<td><div data-dojo-id="rowCountEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:1, max:14}" value="5" intermediateChanges="true" onChange="matrixView.set('rowCount', this.value);"></div></td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Main Properties" class="formPanel">
+					<table class="formTable">
+						<tr>
+							<td class="smallText">
+								<label for="roundToDayCB">Round to day:</label>
+							</td>
+							<td class="smallText">
+								<input type="checkbox" data-dojo-id="roundToDayCB" data-dojo-type="dijit.form.CheckBox" checked="true"/>
+							</td>
+						</tr>
+						
+						<tr>
+							<td>Overlap (%):</td>
+							<td><div data-dojo-id="overlapEditor" data-dojo-type="dijit.form.NumberSpinner" value="0" constraints="{min:0, max:100}" intermediateChanges="true" smallDelta="10" style="width:80px" onChange="matrixView.set('percentOverlap', this.value);"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Vertical gap (px):</td>
+							<td><div data-dojo-id="vGapEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:0, max:30}" value="4" intermediateChanges="true" onChange="matrixView.set('verticalGap', this.value);"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Horiz. height (px):</td>
+							<td><div data-dojo-id="hRendererHeightEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:0, max:50}" value="17" intermediateChanges="true" onChange="matrixView.set('horizontalRendererHeight', this.value);"></div></td>
+						</tr>
+
+						<tr>
+							<td>Labels height (px):</td>
+							<td><div data-dojo-id="lRendererHeightEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:0, max:50}" value="14" intermediateChanges="true" onChange="matrixView.set('labelRendererHeight', this.value);"></div></td>
+						</tr>
+
+						<tr>
+							<td>Expand irs height (px):</td>
+							<td><div data-dojo-id="eRendererHeightEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:0, max:50}" value="15" intermediateChanges="true" onChange="matrixView.set('expandRendererHeight', this.value);"></div></td>
+						</tr>
+
+						<tr>
+							<td>Selection mode:</td>
+							<td>
+								<select data-dojo-id="selectionModeEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="matrixView.set('selectionMode', this.value);">
+									<option>none</option>
+									<option selected>single</option>
+									<option>multiple</option>
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td>Renderer kind:</td>
+							<td>
+								<select data-dojo-id="rendererKindEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" searchAttr="label">
+								</select>
+							</td>
+						</tr>
+					</table>
+				</div>
+
+				<div data-dojo-type="dijit.TitlePane" title="Date/Time Patterns" class="formPanel" open="false">
+					<table class="formTable">
+						<tr>
+							<td>Row format:</td>
+							<td><div data-dojo-id="rowHeaderFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" placeHolder="ex: w"></div></td>
+						</tr>
+						<!--<tr>
+							<td>Column format:</td>
+							<td><div data-dojo-id="columnHeaderFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" placeHolder="ex: EEE MMM, dd"></div></td>
+						</tr>-->
+						<tr>
+							<td>Cell short format:</td>
+							<td><div data-dojo-id="cellShortFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" placeHolder="ex: dd"></div></td>
+						</tr>
+						<tr>
+							<td>Cell long format:</td>
+							<td><div data-dojo-id="cellLongFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" placeHolder="ex: MMMM, dd"></div></td>
+						</tr>
+						<tr>
+							<td class="smallText" >
+								<label for="customTimeFormatCB">Time format ex:</label>
+							</td><td>
+								<input type="checkbox" data-dojo-id="customTimeFormatCB" data-dojo-type="dijit.form.CheckBox" checked="false" />
+								
+							</td>
+						</tr>
+
+						<tr>
+							<td colspan="2" style="text-align:right;padding-top:5px;padding-right:5px"><button data-dojo-id="dateFormatButton" data-dojo-type="dijit.form.Button">Apply</button></td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Item Properties" class="formPanel" open="true">
+					<table>
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Summary:</span>
+								<div data-dojo-id="itemSummaryEditor" data-dojo-type="dijit.form.TextBox" style="width:140px; margin-left: 10px" placeHolder="Summary..." disabled="true"></div>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Calendar:</span>
+								<select data-dojo-id="calendarEditor" data-dojo-type="dijit.form.ComboBox"  style="width:140px; margin-left: 12px"  disabled="true">
+									<option>Calendar 1</option>
+									<option>Calendar 2</option>
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allDayCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label for="allDayCB">All day</label>
+							</td>
+						</tr>
+						
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">Start time:</td>
+						</tr>
+						
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemStartDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" disabled="true" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemStartTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" disabled="true" ></div>
+							</td>
+						</tr>
+
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">End time:</td>
+						</tr>
+						
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemEndDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" disabled="true" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemEndTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" disabled="true" ></div>
+							</td>
+						</tr>
+						
+						<tr>
+							<td colspan="2" style="text-align:right;padding-top:5px;font-size:0.9em">
+								<button data-dojo-id="updateItemButton" data-dojo-type="dijit.form.Button" disabled="true">Update</button>
+							</td>
+						</tr>
+					</table>	
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Editing properties" class="formPanel" open="true">
+					<table>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="liveEditCB" data-dojo-type="dijit.form.CheckBox" checked="false" />
+								<label for="liveEditCB">Live layout</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allowSwapCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="allowSwapCB">Allow start/end swap</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="editableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="editableCB">Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="keyEditableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="keyEditableCB">Keyboard Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="viewConstrainCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="viewConstrainCB">Stay in view (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" id="moveEnabledCB" data-dojo-id="moveEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="moveEnabledCBLabel" for="moveEnabledCB" class="disabled">Move Enabled (item)</label>
+							</td>						
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" id="resizeEnabledCB" data-dojo-id="resizeEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="resizeEnabledCBLabel" for="resizeEnabledCB" class="disabled">Resize Enabled (item)</label>
+							</td>
+						</tr>
+						
+						<tr>
+							<td class="smallText">Snap (minutes):</td>
+							<td>
+								<select data-dojo-id="editingSnapEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="matrixView.snapSteps = matrixView.keyboardLeftRightSteps = parseInt(this.value);">
+									<option>5</option>
+									<option>10</option>
+									<option selected>15</option>
+									<option>20</option>
+									<option>30</option>
+									<option>60</option>
+									<option>120</option>
+									<option>360</option>
+									<option>720</option>
+									<option>1440</option>
+								</select>
+							</td>
+						</tr>
+						
+					</table>
+				</div>
+				
+			</div>
+						
+			<div id="calendarNode"></div>
+			
+			<div id="eventLogPane" title="Calendar events" data-dojo-type="dijit.TitlePane" toggleable="false" >
+							
+				<div id="logTableContainer">
+					<table id="logTable">
+						<tbody id="logBody"></tbody>
+					</table>		
+				</div>
+				
+			</div>
+
+	</body>
+</html>
diff --git a/dojox/calendar/tests/matrixview_rtl.css b/dojox/calendar/tests/matrixview_rtl.css
new file mode 100644
index 0000000..cde454b
--- /dev/null
+++ b/dojox/calendar/tests/matrixview_rtl.css
@@ -0,0 +1,6 @@
+.formTable td:first-child {
+	text-align: left;
+	padding-left: 10px;
+	font-size: 0.9em;
+}
+
diff --git a/dojox/calendar/tests/matrixview_rtl.html b/dojox/calendar/tests/matrixview_rtl.html
new file mode 100644
index 0000000..dbf72b4
--- /dev/null
+++ b/dojox/calendar/tests/matrixview_rtl.html
@@ -0,0 +1,844 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>MatrixView Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/MatrixView.css";
+			@import "matrixview.css";
+			@import "../themes/claro/MatrixView_rtl.css";
+			@import "matrixview_rtl.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>			
+	</head>
+	
+	<body class="claro" dir="rtl">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/declare", "dojo/on", "dojo/date/locale", "dojo/parser", "dojo/date", "dojo/_base/lang",
+					"dojo/dom", "dojo/dom-construct", "dojo/dom-class", "dojo/_base/window",
+					"dijit/registry", "dojo/query", "dojox/calendar/MatrixView", "dojox/calendar/Keyboard", "dojox/calendar/Mouse", 
+					"dojox/calendar/HorizontalRenderer", "dojox/calendar/LabelRenderer", "dojox/calendar/ExpandRenderer", "dojo/store/Memory", "dojo/store/Observable",
+					"dijit/form/VerticalSlider", "dijit/form/NumberSpinner", 
+					"dijit/form/ComboBox", "dijit/form/DateTextBox", "dijit/form/TimeTextBox", "dijit/form/TextBox", 
+					"dijit/form/Button", "dijit/TitlePane", "dijit/Tooltip", 
+					"dijit/form/CheckBox", "dojo/_base/fx", "dijit/_BidiSupport"],
+
+				function(ready, declare, on, locale, parser, date, lang, dom, domConstruct, domClass, win, registry, query,
+					MatrixView, CalendarKeyboard, CalendarMouse, HorizontalRenderer, LabelRenderer, ExpandRenderer, Memory, Observable, VerticalSlider, 
+					NumberSpinner, ComboBox, DateTextBox, TimeTextBox, TextBox, Button, TitlePane, Tooltip, CheckBox, fx){
+
+					ready(function(){
+
+						// singleton
+						win.doc.appState = {
+							moveDisabledMap: {},
+							resizeDisabledMap: {}
+						};
+						
+						var mergeDateTime = function(isStart){
+							var dateEditor = isStart ? itemStartDateEditor : itemEndDateEditor;
+							var timeEditor = isStart ? itemStartTimeEditor : itemEndTimeEditor;
+							var date = dateEditor.get("value");
+							var time = timeEditor.get("value");
+							date.setHours(time.getHours());
+							date.setMinutes(time.getMinutes());
+							return date;
+						};
+						
+						var addLogEntry = function(name, content){
+							var tr = domConstruct.create("tr", null, dom.byId("logBody"), "first");
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(locale.format(new Date(), {selector:"time", timePattern:"h:mm:ss"})));
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(name));
+							td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(content));
+						};
+
+						// Calendar model creation
+						
+						var dateClassObj = Date;
+						
+						var modelBase = [
+							{day: 5, start: [0,0], duration: 1440, allDay:true},
+							{day: 5, start: [6,0], duration: 240}/*,
+							{day: 1, start: [10,0], duration: 240},
+							{day: 1, start: [16,0], duration: 60},
+							{day: 2, start: [8,0], duration: 120},
+							{day: 2, start: [10,0], duration: 120},
+							{day: 2, start: [16,0], duration: 120},
+							{day: 3, start: [8,0], duration: 1440*2},
+							{day: 5, start: [0,0], duration: 1440, allDay:true},
+							{day: 6, start: [0,0], duration: 2*1440, allDay:true}*/
+						];
+						
+						// TODO manage first day of week
+						var floorToWeek= function(d){
+							d.setHours(0);
+							d.setMinutes(0);
+							d.setSeconds(0);
+							d.setMilliseconds(0);
+							d = date.add(d, "day", -d.getDay());
+							return d;
+						};
+						
+						var someData = [];
+						
+						var startOfWeek = new dateClassObj();
+						startOfWeek = floorToWeek(startOfWeek);
+						
+						startDateEditor.set("value", startOfWeek);
+						var id;
+						for (var w=0; w<1; w++) {
+							for (var i=0; i<modelBase.length; i++) {
+								id = (w*modelBase.length)+i;
+								var newObj = {
+									id: id,
+									summary: "New Event " + id,
+									startTime: new dateClassObj(startOfWeek.getTime()),
+									endTime: new dateClassObj(startOfWeek.getTime()),
+									calendar: i%2 == 0 ? "cal1" : "cal2"
+								};
+	
+								newObj.startTime = date.add(newObj.startTime, "day", 6);
+								newObj.startTime.setHours(modelBase[i].start[0]);
+								newObj.startTime.setMinutes(modelBase[i].start[1]);
+	
+								newObj.endTime = date.add(newObj.startTime, "minute", modelBase[i].duration);
+								
+								if(modelBase[i].allDay != undefined){
+									newObj.allDay = modelBase[i].allDay; 
+								}
+	
+								someData.push(newObj);
+							}
+							startOfWeek = date.add(startOfWeek, "day", 7);
+						}
+						
+						id++;
+						
+						// Calendar creation & configuration
+						
+						matrixView = declare([MatrixView, CalendarKeyboard, CalendarMouse])({
+							
+							store: new Observable(new Memory({data: someData})),		
+							horizontalRenderer: HorizontalRenderer,
+							labelRenderer: LabelRenderer,
+							expandRenderer: ExpandRenderer,
+							verticalGap:4,
+							cssClassFunc: function(item){
+								return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+							},
+							isItemMoveEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.moveDisabledMap[item.id] !== true;
+							},
+							isItemResizeEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.resizeDisabledMap[item.id] !== true;
+							}
+						}, "calendarNode");
+						
+						// matrix view is *not* in a dijit container, must register resize handler
+						window.onresize = function(e){
+							matrixView.resize(e);
+						};
+
+						// Events management
+						
+						matrixView.on("gridDoubleClick", function(e){
+
+							// create a event when double-clicking on grid.
+							var d = matrixView.floorToDay(e.date, true);
+
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: d,
+								endTime: date.add(d, "day", 1),
+								calendar: id % 2 == 0 ? "cal1" : "cal2"
+							};
+							id++;
+							matrixView.store.add(item);
+							
+							matrixView.set("selectedItem", item);
+							matrixView.set("focusedItem", item);
+							onMatrixViewChange(item);
+						});
+
+						matrixView.on("rowHeaderClick", function(e){
+							var expIndex = matrixView.getExpandedRowIndex();
+							if(expIndex == e.index){
+								matrixView.collapseRow();
+							}else if(expIndex == -1){
+								matrixView.expandRow(e.index);
+							}else{
+								var h = matrixView.on("expandAnimationEnd", function(){
+									h.remove();
+									matrixView.expandRow(e.index);
+								});
+								matrixView.collapseRow();
+							}
+						});
+						
+						var editedItem;
+						
+						var onMatrixViewChange = function(item){
+
+							if (item == null){
+								editedItem = null;
+								
+								itemSummaryEditor.set("value", null);
+								itemSummaryEditor.set("disabled", true);
+								
+								itemStartDateEditor.set("value", null);
+								itemStartDateEditor.set("disabled", true);
+								
+								itemStartTimeEditor.set("value", null);
+								itemStartTimeEditor.set("disabled", true);
+								
+								itemEndDateEditor.set("value", null);
+								itemEndDateEditor.set("disabled", true);
+								
+								itemEndTimeEditor.set("value", null);
+								itemEndTimeEditor.set("disabled", true);
+								
+								updateItemButton.set("disabled", true);
+								deleteItemButton.set("disabled", true);
+								
+								allDayCB.set("disabled", true);
+								allDayCB.set("checked", false, false);
+								
+								resizeEnabledCB.set("disabled", true);
+								resizeEnabledCB.set("checked", false);
+								
+								moveEnabledCB.set("disabled", true);
+								moveEnabledCB.set("checked", false);
+								
+								calendarEditor.set("disabled", true);
+								
+							}else{
+								
+								editedItem = lang.mixin({}, item);
+								
+								var allDay = item.allDay === true;
+																
+								itemSummaryEditor.set("value", item.summary);
+								itemSummaryEditor.set("disabled", false);
+								
+								itemStartDateEditor.set("value", item.startTime);
+								itemStartDateEditor.set("disabled", false);
+								
+								itemStartTimeEditor.set("value", item.startTime);
+								itemStartTimeEditor.set("disabled", allDay);
+								
+								itemEndDateEditor.set("value", item.endTime);
+								itemEndDateEditor.set("disabled", false);
+								
+								itemEndTimeEditor.set("value", item.endTime);
+								itemEndTimeEditor.set("disabled", allDay);
+								
+								calendarEditor.set("value", item.calendar == "cal1" ? "Calendar 1" : "Calendar 2");
+								
+								updateItemButton.set("disabled", false);
+								deleteItemButton.set("disabled", false);
+								
+								calendarEditor.set("disabled", false);	
+								
+								allDayCB.set("disabled", false);
+								allDayCB.set("checked", allDay, false);
+								
+								resizeEnabledCB.set("disabled", false);
+								resizeEnabledCB.set("checked", win.doc.appState.resizeDisabledMap[item.id] !== true);
+								
+								moveEnabledCB.set("disabled", false);
+								moveEnabledCB.set("checked", win.doc.appState.moveDisabledMap[item.id] !== true);
+							}
+
+							var res = "";
+							if(item == null){
+								res = null;
+							}else{
+								var list = matrixView.get("selectedItems");
+								for(var i=0; i<list.length; i++){
+									res += list[i].summary;
+									if(i != list.length-1){
+										res += ", ";
+									}
+								}
+							}
+							addLogEntry("onChange", res);
+						};
+						
+
+						allDayCB.on("change", function(value){
+							
+							itemStartTimeEditor.set("disabled", value);
+							itemEndTimeEditor.set("disabled", value);
+							var d;
+							if(value){
+								d = itemStartTimeEditor.get("value");
+								matrixView.floorToDay(d, true);
+								itemStartTimeEditor.set("value", d);
+								d = itemEndTimeEditor.get("value");
+								matrixView.floorToDay(d, true);
+								itemEndTimeEditor.set("value", d);
+								
+								if(!matrixView.isStartOfDay(editedItem.endTime)){
+									d = itemEndDateEditor.get("value");
+									matrixView.floorToDay(d, true);
+									d = matrixView.renderData.dateModule.add(d, "day", 1);
+									itemEndDateEditor.set("value", d);
+								}
+								
+							}else{
+								editedItem.startTime.setHours(8);
+								editedItem.endTime.setHours(9);
+								itemStartTimeEditor.set("value", editedItem.startTime);
+								itemEndTimeEditor.set("value", editedItem.endTime);
+								d = itemEndDateEditor.get("value");
+								matrixView.floorToDay(d, true);
+								d = matrixView.renderData.dateModule.add(d, "day", -1);
+								itemEndDateEditor.set("value", d);
+							}
+							
+						});
+						
+						matrixView.on("change", function(e){
+							onMatrixViewChange(e.newValue);
+						});
+						
+						startDateEditor.on("change", function(value){
+							matrixView.set("startDate", value);
+						});
+																	
+						deleteItemButton.on("click", function(value){
+							if (editedItem != null){
+								matrixView.store.remove(editedItem.id);
+								matrixView.selectedItem = null;
+								onMatrixViewChange(null);
+							}
+						});
+						
+						updateItemButton.on("click", function(value){
+							
+							if (editedItem != null) {
+								editedItem.summary = itemSummaryEditor.get("value");
+								if(allDayCB.get("value")){
+									if(!matrixView.isStartOfDay(editedItem.startTime)){
+										editedItem.startTime = matrixView.floorToDay(itemStartDateEditor.get("value"), true);
+									}
+									if(!matrixView.isStartOfDay(editedItem.endTime)){
+										editedItem.endTime = matrixView.floorToDay(itemEndDateEditor.get("value"), true);
+									}			
+									editedItem.allDay = true;						
+								}else{
+									editedItem.startTime = mergeDateTime(true);
+									editedItem.endTime = mergeDateTime(false);
+									delete editedItem.allDay;
+								}
+								
+								var calValue = calendarEditor.get("value");
+								editedItem.calendar = calValue == "Calendar 1" ? "cal1" : "cal2";
+								matrixView.store.put(editedItem);
+							}
+							
+						});
+
+						dateFormatButton.on("click", function(){
+							matrixView.set("rowHeaderDatePattern", rowHeaderFormatEditor.value);
+							//matrixView.set("columnHeaderDatePattern", columnHeaderFormatEditor.value);
+							
+							matrixView.set("cellHeaderLongPattern", cellLongFormatEditor.value);
+							matrixView.set("cellHeaderShortPattern", cellShortFormatEditor.value);
+						});
+						
+						var formatItemTimeFunc = function(d, rd){
+							return rd.dateLocaleModule.format(d, {
+								selector: 'time', 
+								timePattern: d.getMinutes() == 0 ? "ha":"h:mma"}
+							).toLowerCase();
+						};
+						
+						customTimeFormatCB.on("change", function(value){
+							matrixView.set("formatItemTimeFunc", value ? formatItemTimeFunc : null);
+						});
+												
+						matrixView.on("itemClick", function(e){
+							addLogEntry("onItemClick", e.item.summary);
+						});
+						matrixView.on("itemDoubleClick", function(e){
+							addLogEntry("onItemDoubleClick", e.item.summary);
+						});
+						matrixView.on("gridClick", function(e){
+							addLogEntry("onGridClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});
+						matrixView.on("gridDoubleClick", function(e){
+							addLogEntry("onGridDoubleClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});
+
+						var dataTip = new Tooltip({position:["below"], showDelay: 0});
+						var timer;
+
+						matrixView.on("itemRollOut", function(e){
+							addLogEntry("onItemRollOut", e.item.summary);
+							dataTip.close();
+							if(timer){
+								clearTimeout(timer);
+							}
+						});
+
+						var getDataTipLabel = function(item){
+							return "<b>" + item.summary + "</b><br/><table><tr><td style='text-align:right'>" + 
+								"Start:</td><td>" + matrixView.renderData.dateLocaleModule.format(item.startTime, {formatLength: "short"}) + "</td></tr><tr><td style='text-align:right'>" + 
+								"End:</td><td>" + matrixView.renderData.dateLocaleModule.format(item.endTime, {formatLength: "short"}) + "</td></tr></table>";
+						};
+						
+						matrixView.on("focusChange", function(e){
+							if(e.newValue){
+								dataTip.set("label", getDataTipLabel(e.newValue));	
+								var irs = matrixView.getRenderers(e.newValue);		
+								if(irs != null){
+									dataTip.open(irs[0].container);
+								}
+							}else{
+								dataTip.close();
+							}					
+						}); 
+												
+						matrixView.on("itemRollOver", function(e){
+							
+							addLogEntry("onItemRollOver", e.item.summary);
+														
+							dataTip.set("label", getDataTipLabel(e.item));
+							
+							timer = setTimeout(function(){
+								var irs = matrixView.getRenderers(e.item);
+								if(irs != null){
+									dataTip.open(irs[0].container);	
+								}								
+							}, 400); 
+							
+						});
+						
+						var editProperties = null;
+												
+						matrixView.on("itemEditBegin", function(e){							
+							if(timer){
+								clearTimeout(timer);
+							}
+							dataTip.close();
+							addLogEntry("onItemEditBegin", e.item.summary);
+							editProperties = {
+								item: e.item
+							};
+						});
+						
+						matrixView.on("itemEditBeginGesture", function(e){
+							addLogEntry("onItemEditBeginGesture", e.editKind + ", " + e.item.summary);							
+						});
+						
+						var showDataTipAfterLayout = false;
+												
+						matrixView.on("renderersLayoutDone", function(){
+							
+							if(editProperties != null && showDataTipAfterLayout){
+								var item = editProperties.item;
+									
+								// HACK: setting the label should dynamically set the content 
+								dataTip.label = getDataTipLabel(item);
+																
+								showDataTipAfterLayout= false;
+								
+								var irs = matrixView.getRenderers(item);
+								if(irs != null){
+									dataTip.open(irs[0].container);	
+								}
+							}
+
+						});
+						
+						matrixView.on("itemEditMoveGesture", function(e){
+							showDataTipAfterLayout = true;
+						});
+						
+						matrixView.on("itemEditEndGesture", function(e){
+							addLogEntry("onItemEditEndGesture", e.editKind + ", " + e.item.summary);							
+							
+							onMatrixViewChange(e.item);
+
+						});
+						
+						matrixView.on("itemEditEnd", function(e){
+							addLogEntry("onItemEditEnd", e.item.summary + ", completed:" + e.completed);										
+							showDataTipAfterLayout = true;													
+						});
+																	
+						editableCB.on("change", function(value){
+							matrixView.set("editable", value);
+						});
+						
+						keyEditableCB.on("change", function(value){
+							matrixView.set("keyboardEditable", value);
+						});
+						
+						liveEditCB.on("change", function(value){
+							matrixView.liveLayout = value;
+						});
+												
+						allowSwapCB.on("change", function(value){							
+							matrixView.allowStartEndSwap = value;
+						});
+						
+						viewConstrainCB.on("change", function(value){							
+							matrixView.stayInView = value;
+						});											
+												
+						resizeEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("resizeEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("resizeEnabledCBLabel", "disabled");
+							}							
+						});
+
+						moveEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("moveEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("moveEnabledCBLabel", "disabled");
+							}
+						});
+						
+						resizeEnabledCB.on("change", function(value){
+							if (matrixView.selectedItem) {
+								if (value){
+									delete win.doc.appState.resizeDisabledMap[matrixView.selectedItem.id]	
+								} else {
+									win.doc.appState.resizeDisabledMap[matrixView.selectedItem.id] = true;
+								}								
+							}
+						});
+
+						moveEnabledCB.on("change", function(value){
+							if (matrixView.selectedItem) {
+								if (value){
+									delete win.doc.appState.moveDisabledMap[matrixView.selectedItem.id]	
+								} else {
+									win.doc.appState.moveDisabledMap[matrixView.selectedItem.id] = true;
+								}
+							}
+						});
+
+						roundToDayCB.on("change", function(value){
+							matrixView.set("roundToDay", value);
+						});
+
+						overlapEditor.on("change", function(value){
+							matrixView.set("percentOverlap", this.value);
+							vGapEditor.set("disabled", value!=0);
+						});
+						
+						// the item to renderer kind functions.
+						var itemToRendererKindFuncs = [
+							null, 
+							function(item){ return "horizontal"; },
+							function(item){ return item.allDay ? "horizontal" : "label"},
+							function(item){ return "label"}
+						]; 
+						
+						rendererKindEditor.set("store", new Memory({data:[
+							{id:0, label: "default"},
+							{id:1, label: "All horizontals"},
+							{id:2, label: "Only all day horizontals"},
+							{id:3, label: "All labels"}
+						]}));
+						
+						rendererKindEditor.watch("item", function(prop, oldValue, newValue){
+							matrixView.set("itemToRendererKindFunc", itemToRendererKindFuncs[newValue.id]);
+						});
+												
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff;text-align: center">
+				<span style="background: #DBEB8F">Loading...</span>
+			</div>
+			
+			<div id="formDiv">
+				
+				<div data-dojo-type="dijit.TitlePane" title="Date Interval" class="formPanel">
+					<table class="formTable">	
+						<tr>
+							<td>Start date:</td>
+							<td><div data-dojo-id="startDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:80px" ></div></td>
+						</tr>
+						
+						<tr>
+							<td>Column count:</td>
+							<td><div data-dojo-id="columnCountEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:1, max:14}" value="7" intermediateChanges="true" onChange="matrixView.set('columnCount', this.value);"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Row count:</td>
+							<td><div data-dojo-id="rowCountEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:1, max:14}" value="5" intermediateChanges="true" onChange="matrixView.set('rowCount', this.value);"></div></td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Main Properties" class="formPanel">
+					<table class="formTable">
+						<tr>
+							<td class="smallText">
+								<label for="roundToDayCB">Round to day:</label>
+							</td>
+							<td class="smallText">
+								<input type="checkbox" data-dojo-id="roundToDayCB" data-dojo-type="dijit.form.CheckBox" checked="true"/>
+							</td>
+						</tr>
+						
+						<tr>
+							<td>Overlap (%):</td>
+							<td><div data-dojo-id="overlapEditor" data-dojo-type="dijit.form.NumberSpinner" value="0" constraints="{min:0, max:100}" intermediateChanges="true" smallDelta="10" style="width:80px" onChange="matrixView.set('percentOverlap', this.value);"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Vertical gap (px):</td>
+							<td><div data-dojo-id="vGapEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:0, max:30}" value="4" intermediateChanges="true" onChange="matrixView.set('verticalGap', this.value);"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Horiz. height (px):</td>
+							<td><div data-dojo-id="hRendererHeightEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:0, max:50}" value="17" intermediateChanges="true" onChange="matrixView.set('horizontalRendererHeight', this.value);"></div></td>
+						</tr>
+
+						<tr>
+							<td>Labels height (px):</td>
+							<td><div data-dojo-id="lRendererHeightEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:0, max:50}" value="14" intermediateChanges="true" onChange="matrixView.set('labelRendererHeight', this.value);"></div></td>
+						</tr>
+
+						<tr>
+							<td>Expand irs height (px):</td>
+							<td><div data-dojo-id="eRendererHeightEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" constraints="{min:0, max:50}" value="15" intermediateChanges="true" onChange="matrixView.set('expandRendererHeight', this.value);"></div></td>
+						</tr>
+
+						<tr>
+							<td>Selection mode:</td>
+							<td>
+								<select data-dojo-id="selectionModeEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="matrixView.set('selectionMode', this.value);">
+									<option>none</option>
+									<option selected>single</option>
+									<option>multiple</option>
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td>Renderer kind:</td>
+							<td>
+								<select data-dojo-id="rendererKindEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" searchAttr="label">
+								</select>
+							</td>
+						</tr>
+						<tr>
+							<td>Text Dir:</td>
+							<td>
+								<select data-dojo-id="textDirEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="matrixView.set('textDir', this.value);dataTip.set('textDir', this.value)">
+									<option selected>auto</option>
+									<option>ltr</option>
+									<option>rtl</option>
+								</select>
+							</td>
+						</tr>
+					</table>
+				</div>
+
+				<div data-dojo-type="dijit.TitlePane" title="Date/Time Patterns" class="formPanel" open="false">
+					<table class="formTable">
+						<tr>
+							<td>Row format:</td>
+							<td><div data-dojo-id="rowHeaderFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" placeHolder="ex: w"></div></td>
+						</tr>
+						<!--<tr>
+							<td>Column format:</td>
+							<td><div data-dojo-id="columnHeaderFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" placeHolder="ex: EEE MMM, dd"></div></td>
+						</tr>-->
+						<tr>
+							<td>Cell short format:</td>
+							<td><div data-dojo-id="cellShortFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" placeHolder="ex: dd"></div></td>
+						</tr>
+						<tr>
+							<td>Cell long format:</td>
+							<td><div data-dojo-id="cellLongFormatEditor" data-dojo-type="dijit.form.TextBox" style="width:110px" placeHolder="ex: MMMM, dd"></div></td>
+						</tr>
+						<tr>
+							<td class="smallText" >
+								<label for="customTimeFormatCB">Time format ex:</label>
+							</td><td>
+								<input type="checkbox" data-dojo-id="customTimeFormatCB" data-dojo-type="dijit.form.CheckBox" checked="false" />
+								
+							</td>
+						</tr>
+
+						<tr>
+							<td colspan="2" style="text-align:right;padding-top:5px;padding-right:5px"><button data-dojo-id="dateFormatButton" data-dojo-type="dijit.form.Button">Apply</button></td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Item Properties" class="formPanel" open="true">
+					<table>
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Summary:</span>
+								<div data-dojo-id="itemSummaryEditor" data-dojo-type="dijit.form.TextBox" style="width:140px; margin-left: 10px" placeHolder="Summary..." disabled="true"></div>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Calendar:</span>
+								<select data-dojo-id="calendarEditor" data-dojo-type="dijit.form.ComboBox"  style="width:140px; margin-left: 12px"  disabled="true">
+									<option>Calendar 1</option>
+									<option>Calendar 2</option>
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allDayCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label for="allDayCB">All day</label>
+							</td>
+						</tr>
+						
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">Start time:</td>
+						</tr>
+						
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemStartDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" disabled="true" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemStartTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" disabled="true" ></div>
+							</td>
+						</tr>
+
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">End time:</td>
+						</tr>
+						
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemEndDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" disabled="true" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemEndTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" disabled="true" ></div>
+							</td>
+						</tr>
+						
+						<tr>
+							<td colspan="2" style="text-align:right;padding-top:5px;font-size:0.9em">
+								<button data-dojo-id="deleteItemButton" data-dojo-type="dijit.form.Button" disabled="true">Remove</button>
+								<button data-dojo-id="updateItemButton" data-dojo-type="dijit.form.Button" disabled="true">Update</button>
+							</td>
+						</tr>
+					</table>	
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Editing properties" class="formPanel" open="true">
+					<table>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="liveEditCB" data-dojo-type="dijit.form.CheckBox" checked="false" />
+								<label for="liveEditCB">Live layout</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allowSwapCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="allowSwapCB">Allow start/end swap</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="editableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="editableCB">Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="keyEditableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="keyEditableCB">Keyboard Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="viewConstrainCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="viewConstrainCB">Stay in view (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="moveEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="moveEnabledCBLabel" for="moveEnabledCB" class="disabled">Move Enabled (item)</label>
+							</td>						
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="resizeEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="resizeEnabledCBLabel" for="resizeEnabledCB" class="disabled">Resize Enabled (item)</label>
+							</td>
+						</tr>
+						
+						<tr>
+							<td class="smallText">Snap (minutes):</td>
+							<td>
+								<select data-dojo-id="editingSnapEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="matrixView.snapSteps = matrixView.keyboardLeftRightSteps = parseInt(this.value);">
+									<option>5</option>
+									<option>10</option>
+									<option selected>15</option>
+									<option>20</option>
+									<option>30</option>
+									<option>60</option>
+									<option>120</option>
+									<option>360</option>
+									<option>720</option>
+									<option>1440</option>
+								</select>
+							</td>
+						</tr>
+						
+					</table>
+				</div>
+				
+			</div>
+						
+			<div id="calendarNode"></div>
+			
+			<div id="eventLogPane" title="Calendar events" data-dojo-type="dijit.TitlePane" toggleable="false" >
+							
+				<div id="logTableContainer">
+					<table id="logTable">
+						<tbody id="logBody"></tbody>
+					</table>		
+				</div>
+				
+			</div>
+
+	</body>
+</html>
diff --git a/dojox/calendar/tests/module.js b/dojox/calendar/tests/module.js
new file mode 100644
index 0000000..0ffb20b
--- /dev/null
+++ b/dojox/calendar/tests/module.js
@@ -0,0 +1,6 @@
+define([
+	"dojox/calendar/tests/unitTest_TimeRanges",
+	"dojox/calendar/tests/unitTest_editing",
+	"dojox/calendar/tests/unitTest_Store",
+	"dojox/calendar/tests/unitTest_Time"
+], 1);
diff --git a/dojox/calendar/tests/monthcolumnview.css b/dojox/calendar/tests/monthcolumnview.css
new file mode 100644
index 0000000..fa6127f
--- /dev/null
+++ b/dojox/calendar/tests/monthcolumnview.css
@@ -0,0 +1,132 @@
+ .claro .dojoxCalendarMonthColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+ 
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+ 	-moz-user-select: none;
+	-webkit-user-select: none;
+	khtml-user-select: none;
+	user-select: none;
+	font-weight: bold;
+	border-radius: 5px;
+}
+       
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent {
+	font-size: 90%;
+	font-family: Tahoma, serifSansSerifMonospace;
+}
+
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Calendar2 .bg {
+	background: #2095B4;
+}
+
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Calendar2.Hovered .bg {
+	background: #24A5C8;
+}
+
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Calendar2.Selected .bg {
+	background: #166B81;
+}
+
+html, body {
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+#formDiv {
+	position:absolute;
+	left:10px;					
+	width: 250px;
+	top: 0;
+	bottom: 0;
+	margin-bottom: 10px;
+	overflow-y: auto;
+}
+
+.formPanel {
+	width: 230px;
+	margin-top: 10px;
+}
+
+#formDiv table {
+	width: 100%;					
+}
+
+.formTable td:first-child {
+	text-align: right;
+	padding-right: 10px;
+	font-size: 0.9em;
+}
+
+.smallText {
+	font-size:0.9em;
+}
+
+.disabled{
+	color: #CCCCCC;
+}
+
+#calendarNode {
+	position:absolute; 
+	left:270px; 
+	right:10px; 
+	top:10px; 
+	bottom:120px;
+}
+
+#eventLogPane {
+	position:absolute; 
+	left:270px; 
+	right:10px; 
+	height: 100px;
+	bottom:10px;	
+}
+
+#logTableContainer{	
+	width:100%;
+	height:100%;
+	overflow-y:auto;	
+}
+
+#eventLogPane .dijitTitlePaneTitle{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: 20px
+}
+
+#eventLogPane .dijitTitlePaneContentOuter{
+	position: absolute;
+	left: 0; 
+	right: 0; 
+	top: 25px; 
+	bottom: 0;
+}
+
+#eventLogPane .dijitTitlePaneContentInner{
+	position: relative;
+	width: 100%; 
+	height: 100%; 
+	padding: 0;
+}
+
+#eventLogPane .dijitReset{
+	position: relative; 
+	width: 100%; 
+	height: 100%;
+}
+
+#eventLogPane .dijitArrowNode{
+	display: none;
+}
+
+#logTable{
+	width: 100%;	
+	position:relative;
+}
diff --git a/dojox/calendar/tests/monthcolumnview.html b/dojox/calendar/tests/monthcolumnview.html
new file mode 100644
index 0000000..f3ad694
--- /dev/null
+++ b/dojox/calendar/tests/monthcolumnview.html
@@ -0,0 +1,610 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" width="100%" height="100%">
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Month ColumnView Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/MonthColumnView.css";
+			@import "monthcolumnview.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>			
+	</head>
+	
+	<body class="claro">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/declare", "dojo/_base/fx", "dojo/on", "dojo/date/locale", "dojo/parser", "dojo/date", "dojo/_base/lang",
+					"dojo/dom", "dojo/dom-construct", "dojo/dom-class", "dojo/_base/window", "dijit/registry", "dojo/query", "dojox/calendar/MonthColumnView", 
+					"dojox/calendar/Keyboard", "dojox/calendar/Mouse",	"dojox/calendar/VerticalRenderer", 
+					"dojo/store/Memory", "dojo/store/Observable",
+					"dijit/form/VerticalSlider", "dijit/form/NumberSpinner", "dijit/form/ComboBox", "dijit/form/DateTextBox", "dijit/form/TimeTextBox", 
+					"dijit/form/TextBox", "dijit/form/Button", "dijit/TitlePane", "dijit/Tooltip", "dijit/form/CheckBox"],
+
+				function(ready, declare, fx,on, locale, parser, date, lang, dom, domConstruct, domClass, win, registry, query,
+					MonthColumnView, CalendarKeyboard, CalendarMouse, VerticalRenderer, Memory, Observable, VerticalSlider, 
+					NumberSpinner, ComboBox, DateTextBox, TimeTextBox, TextBox, Button, TitlePane, Tooltip, CheckBox){
+
+					ready(function(){
+
+						// singleton
+						win.doc.appState = {
+							moveDisabledMap: {},
+							resizeDisabledMap: {}
+						};
+						
+						var mergeDateTime = function(isStart){
+							var dateEditor = isStart ? itemStartDateEditor : itemEndDateEditor;
+							var timeEditor = isStart ? itemStartTimeEditor : itemEndTimeEditor;
+							var date = dateEditor.get("value");
+							var time = timeEditor.get("value");
+							date.setHours(time.getHours());
+							date.setMinutes(time.getMinutes());
+							return date;
+						};
+						
+						var addLogEntry = function(name, content){
+							var tr = domConstruct.create("tr", null, dom.byId("logBody"), "first");
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(locale.format(new Date(), {selector:"time", timePattern:"h:mm:ss"})));
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(name));
+							td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(content));
+						};
+
+						// Calendar model creation
+						
+						var dateClassObj = Date;
+						
+						var modelBase = [
+							{day: 1, start: [0,0], duration: 1440*4, allDay: true},
+							{day: 3, start: [0,0], duration: 2880, allDay: true}
+						];
+						
+						// TODO manage first day of week
+						var floorToWeek= function(d){
+							d.setHours(0);
+							d.setMinutes(0);
+							d.setSeconds(0);
+							d.setMilliseconds(0);
+							d = date.add(d, "day", -d.getDay());
+							return d;
+						};
+						
+						var someData = [];
+						
+						var startOfWeek = new dateClassObj();
+						startOfWeek = floorToWeek(startOfWeek);
+						
+						startDateEditor.set("value", startOfWeek);
+						
+						for (var id=0; id<modelBase.length; id++) {
+							var newObj = {
+								id: id,
+								summary: "New Event " + id,
+								startTime: new dateClassObj(startOfWeek.getTime()),
+								endTime: new dateClassObj(startOfWeek.getTime()),
+								calendar: id%2 == 0 ? "cal1" : "cal2",
+								allDay: modelBase[id].allDay
+							};
+
+							newObj.startTime = date.add(newObj.startTime, "day", modelBase[id].day);
+							newObj.startTime.setHours(modelBase[id].start[0]);
+							newObj.startTime.setMinutes(modelBase[id].start[1]);
+
+							newObj.endTime = date.add(newObj.startTime, "minute", modelBase[id].duration);
+
+							someData.push(newObj);
+						}
+
+						
+						// Calendar creation & configuration
+						
+						colView = declare([MonthColumnView, CalendarKeyboard, CalendarMouse])({
+							store: new Observable(new Memory({data: someData})),
+							verticalRenderer: VerticalRenderer,
+							cssClassFunc: function(item){
+								return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+							},
+							isItemMoveEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.moveDisabledMap[item.id] !== true;
+							},
+							isItemResizeEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.resizeDisabledMap[item.id] !== true;
+							}
+						}, "calendarNode");
+
+						// Events management
+						
+						
+						colView.on("gridDoubleClick", function(e){
+
+							// create a event when double-clicking on grid.
+							var start = colView.floorToDay(e.date, "day");
+							var end = date.add(start, "day", 1);
+							
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: start,
+								endTime: end,
+								calendar: id % 2 == 0 ? "cal1" : "cal2",
+								allDay: e.sheet == "secondary"
+							};
+							
+							id++;		
+							colView.store.add(item);
+							
+							colView.set("selectedItem", item);
+							colView.set("focusedItem", item);
+							onColViewChange(item);							
+						});
+
+						var startDateSave;
+						var columnCountSave;
+
+						colView.on("columnHeaderClick", function(e){
+							if (colView.get("columnCount") == 1) {
+								colView.set("startDate", startDateSave);
+								colView.set("columnCount", columnCountSave);
+							} else {
+								startDateSave = colView.get("startDate");
+								columnCountSave = colView.get("columnCount");
+								colView.set("startDate", e.date);
+								colView.set("columnCount", 1);
+							}
+						});
+						
+						var onColViewChange = function(item){
+							if (item == null){
+								
+								editedItem = null;
+								
+								itemSummaryEditor.set("value", null);
+								itemSummaryEditor.set("disabled", true);
+								
+								itemStartDateEditor.set("value", null);
+								itemStartDateEditor.set("disabled", true);
+								
+								itemStartTimeEditor.set("value", null);
+								itemStartTimeEditor.set("disabled", true);
+								
+								itemEndDateEditor.set("value", null);
+								itemEndDateEditor.set("disabled", true);
+								
+								itemEndTimeEditor.set("value", null);
+								itemEndTimeEditor.set("disabled", true);
+								
+								updateItemButton.set("disabled", true);
+								
+								allDayCB.set("disabled", true);
+								allDayCB.set("checked", false, false);
+								
+								resizeEnabledCB.set("disabled", true);
+								resizeEnabledCB.set("checked", false);
+								
+								moveEnabledCB.set("disabled", true);
+								moveEnabledCB.set("checked", false);
+								
+								calendarEditor.set("disabled", true);
+								
+								
+							}else{
+								// work on a copy
+								editedItem = lang.mixin({}, item);
+								
+								var allDay = item.allDay === true;
+																
+								itemSummaryEditor.set("value", item.summary);
+								itemSummaryEditor.set("disabled", false);
+								
+								itemStartDateEditor.set("value", item.startTime);
+								itemStartDateEditor.set("disabled", false);
+								
+								itemStartTimeEditor.set("value", item.startTime);
+								itemStartTimeEditor.set("disabled", allDay);
+								
+								itemEndDateEditor.set("value", item.endTime);
+								itemEndDateEditor.set("disabled", false);
+								
+								itemEndTimeEditor.set("value", item.endTime);
+								itemEndTimeEditor.set("disabled", allDay);
+								
+								calendarEditor.set("value", item.calendar == "cal1" ? "Calendar 1" : "Calendar 2");
+								
+								updateItemButton.set("disabled", false);
+								calendarEditor.set("disabled", false);	
+								
+								allDayCB.set("disabled", false);
+								allDayCB.set("checked", allDay, false);
+								
+								resizeEnabledCB.set("disabled", false);
+								resizeEnabledCB.set("checked", win.doc.appState.resizeDisabledMap[item.id] !== true);
+								
+								moveEnabledCB.set("disabled", false);
+								moveEnabledCB.set("checked", win.doc.appState.moveDisabledMap[item.id] !== true);
+							}
+							
+							var res = "";
+							if(item == null){
+								res = null;
+							}else{
+								var list = colView.get("selectedItems");
+								for(var i=0; i<list.length; i++){
+									res += list[i].summary;
+									if(i != list.length-1){
+										res += ", ";
+									}
+								}
+							}
+							addLogEntry("onChange", res);
+						};
+						
+						allDayCB.on("change", function(value){
+							
+							itemStartTimeEditor.set("disabled", value);
+							itemEndTimeEditor.set("disabled", value);
+							var d;
+							if(value){
+								d = itemStartTimeEditor.get("value");
+								colView.floorToDay(d, true);
+								itemStartTimeEditor.set("value", d);
+								d = itemEndTimeEditor.get("value");
+								colView.floorToDay(d, true);
+								itemEndTimeEditor.set("value", d);
+								
+								if(!colView.isStartOfDay(editedItem.endTime)){
+									d = itemEndDateEditor.get("value");
+									colView.floorToDay(d, true);
+									d = colView.renderData.dateModule.add(d, "day", 1);
+									itemEndDateEditor.set("value", d);
+								}
+								
+							}else{
+								editedItem.startTime.setHours(8);
+								editedItem.endTime.setHours(9);
+								itemStartTimeEditor.set("value", editedItem.startTime);
+								itemEndTimeEditor.set("value", editedItem.endTime);
+								d = itemEndDateEditor.get("value");
+								colView.floorToDay(d, true);
+								d = colView.renderData.dateModule.add(d, "day", -1);
+								itemEndDateEditor.set("value", d);
+							}
+							
+						});
+						
+						colView.on("change", function(e){							
+							onColViewChange(e.newValue);							
+						});
+						
+						startDateEditor.on("change", function(value){
+							colView.set("startDate", value);
+						});
+						
+						var editedItem;
+						
+						updateItemButton.on("click", function(value){
+							
+							if (editedItem != null) {
+								editedItem.summary = itemSummaryEditor.get("value");
+								if(allDayCB.get("value")){
+									if(!colView.isStartOfDay(editedItem.startTime)){
+										editedItem.startTime = colView.floorToDay(itemStartDateEditor.get("value"), true);
+									}
+									if(!colView.isStartOfDay(editedItem.endTime)){
+										editedItem.endTime = colView.floorToDay(itemEndDateEditor.get("value"), true);
+									}			
+									editedItem.allDay = true;						
+								}else{
+									editedItem.startTime = mergeDateTime(true);
+									editedItem.endTime = mergeDateTime(false);
+									delete editedItem.allDay;
+								}
+								
+								var calValue = calendarEditor.get("value");
+								editedItem.calendar = calValue == "Calendar 1" ? "cal1" : "cal2";
+								colView.store.put(editedItem);
+							}
+							
+						});
+						
+						colView.on("itemClick", function(e){
+							addLogEntry("onItemClick", e.item.summary);
+						});
+						colView.on("itemDoubleClick", function(e){
+							addLogEntry("onItemDoubleClick", e.item.summary);
+						});
+						colView.on("gridClick", function(e){
+							addLogEntry("onGridClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});
+						colView.on("gridDoubleClick", function(e){
+							addLogEntry("onGridDoubleClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});												
+						
+						colView.on("itemRollOut", function(e){
+							addLogEntry("onItemRollOut", e.item.summary);
+						});											
+						
+						var getItemLabel = function(item){
+							return "<b>" + item.summary + "</b><br/><table><tr><td style='text-align:right'>" + 
+								"Start:</td><td>" + colView.renderData.dateLocaleModule.format(item.startTime, {formatLength: "medium"}) + "</td></tr><tr><td style='text-align:right'>" + 
+								"End:</td><td>" + colView.renderData.dateLocaleModule.format(item.endTime, {formatLength: "medium"}) + "</td></tr></table>";
+						};
+						
+						colView.on("focusChange", function(e){
+							addLogEntry("focusChange", e.item ? e.item.summary: "null");					
+						});
+												
+						colView.on("itemRollOver", function(e){							
+							addLogEntry("onItemRollOver", e.item.summary);																				
+						});
+						
+						colView.on("itemEditBegin", function(e){							
+							addLogEntry("onItemEditBegin", e.item.summary);
+						});
+						
+						colView.on("itemEditBeginGesture", function(e){
+							addLogEntry("onItemEditBeginGesture", e.editKind + ", " + e.item.summary);							
+						});
+						
+						colView.on("itemEditEndGesture", function(e){
+							addLogEntry("onItemEditEndGesture", e.editKind + ", " + e.item.summary);														
+							onColViewChange(e.item);
+						});
+						
+												
+						colView.on("itemEditEnd", function(e){
+							addLogEntry("onItemEditEnd", e.item.summary + ", completed:" + e.completed);																							
+						});
+																	
+						editableCB.on("change", function(value){
+							colView.set("editable", value);
+						});
+						
+						keyEditableCB.on("change", function(value){
+							colView.set("keyboardEditable", value);
+						});
+						
+						liveEditCB.on("change", function(value){
+							colView.liveLayout = value;
+						});
+												
+						allowSwapCB.on("change", function(value){							
+							colView.allowStartEndSwap = value;
+						});
+						
+						viewConstrainCB.on("change", function(value){							
+							colView.stayInView = value;
+						});											
+												
+						resizeEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("resizeEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("resizeEnabledCBLabel", "disabled");
+							}							
+						});
+
+						moveEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("moveEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("moveEnabledCBLabel", "disabled");
+							}
+						});
+						
+						resizeEnabledCB.on("change", function(value){
+							if (colView.selectedItem) {
+								if (value){
+									delete win.doc.appState.resizeDisabledMap[colView.selectedItem.id]	
+								} else {
+									win.doc.appState.resizeDisabledMap[colView.selectedItem.id] = true;
+								}								
+							}
+						});
+
+						moveEnabledCB.on("change", function(value){
+							if (colView.selectedItem) {
+								if (value){
+									delete win.doc.appState.moveDisabledMap[colView.selectedItem.id]	
+								} else {
+									win.doc.appState.moveDisabledMap[colView.selectedItem.id] = true;
+								}
+							}
+						});
+						
+						overlapEditor.on("change", function(value){
+							colView.set('percentOverlap', this.value);
+							hGapEditor.set("disabled", value!=0)
+						});
+						
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+			
+			<div id="formDiv">
+				
+				<div data-dojo-type="dijit.TitlePane" title="Date Interval" class="formPanel">
+					<table class="formTable">	
+						<tr>
+							<td>Start date:</td>
+							<td><div data-dojo-id="startDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:80px"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Column count:</td>
+							<td><div data-dojo-id="columnCountEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" data-dojo-props="constraints:{min:1, max:12}, value:6, intermediateChanges:true" onChange="colView.set('columnCount', this.value);"></div></td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Main Properties" class="formPanel">
+					<table class="formTable">
+						<tr>
+							<td>Day size(px):</td>
+							<td><div data-dojo-id="daySizeEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" value="30" data-dojo-props="constraints:{min:20, max:200}, intermediateChanges:true, smallDelta:5" onChange="colView.set('daySize', this.value);"></div></td>
+						</tr>
+												
+						<tr>
+							<td>Overlap (%):</td>
+							<td><div data-dojo-id="overlapEditor" data-dojo-type="dijit.form.NumberSpinner" data-dojo-props="value:0, constraints:{min:0, max:100}, intermediateChanges:true, smallDelta:10" style="width:80px"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Horizontal gap (px):</td>
+							<td><div data-dojo-id="hGapEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" data-dojo-props="constraints:{min:0, max:30}, value:2, intermediateChanges:true" onChange="colView.set('horizontalGap', this.value);"></div></td>
+						</tr>
+												
+						<tr>
+							<td>Selection mode:</td>
+							<td>
+								<select data-dojo-id="selectionModeEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.set('selectionMode', this.value);">
+									<option>none</option>
+									<option selected>single</option>
+									<option>multiple</option>
+								</select>
+							</td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Item Properties" class="formPanel" open="false">					
+					<table>					
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Summary:</span>
+								<div data-dojo-id="itemSummaryEditor" data-dojo-type="dijit.form.TextBox" style="width:140px; margin-left: 10px" data-dojo-props="placeHolder:'Summary...'"></div>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Calendar:</span>					
+								<select data-dojo-id="calendarEditor" data-dojo-type="dijit.form.ComboBox"  style="width:140px; margin-left: 12px" >
+									<option>Calendar 1</option>
+									<option>Calendar 2</option>									
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allDayCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label for="allDayCB">All day</label>
+							</td>
+						</tr>
+						
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">Start time:</td>
+						</tr>
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemStartDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemStartTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" ></div>
+							</td>
+						</tr>											
+						
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">End time:</td>
+						</tr>
+						
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemEndDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemEndTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" ></div>
+							</td>
+						</tr>
+						
+						<tr>
+							<td colspan="2" style="text-align:right;padding-top:5px;font-size:0.9em">
+								<button data-dojo-id="updateItemButton" data-dojo-type="dijit.form.Button" disabled="true">Update</button>
+							</td>
+						</tr>
+					</table>	
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Editing properties" class="formPanel" data-dojo-props="open:true">
+					<table>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="liveEditCB" data-dojo-type="dijit.form.CheckBox" checked="false" />
+								<label for="liveEditCB">Live layout</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allowSwapCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="allowSwapCB">Allow start/end swap</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="editableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="editableCB">Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="keyEditableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="keyEditableCB">Keyboard Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="viewConstrainCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="viewConstrainCB">Stay in view (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" id="moveEnabledCB" data-dojo-id="moveEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="moveEnabledCBLabel" for="moveEnabledCB" class="disabled">Move Enabled (item)</label>
+							</td>						
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" id="resizeEnabledCB" data-dojo-id="resizeEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="resizeEnabledCBLabel" for="resizeEnabledCB" class="disabled">Resize Enabled (item)</label>
+							</td>
+						</tr>
+						
+					</table>
+				</div>
+				
+			</div>
+						
+			<div id="calendarNode"></div>
+			
+			<div id="eventLogPane" title="Calendar events" data-dojo-type="dijit.TitlePane" data-dojo-props="toggleable:false" >
+							
+				<div id="logTableContainer">
+					<table id="logTable">
+						<tbody id="logBody"></tbody>
+					</table>		
+				</div>
+				
+			</div>
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/monthcolumnview_rtl.html b/dojox/calendar/tests/monthcolumnview_rtl.html
new file mode 100644
index 0000000..af80d72
--- /dev/null
+++ b/dojox/calendar/tests/monthcolumnview_rtl.html
@@ -0,0 +1,611 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" width="100%" height="100%">
+	
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<title>Month ColumnView Sample: Desktop</title>				
+		<style type="text/css">
+			@import "../themes/claro/MonthColumnView.css";
+			@import "../themes/claro/MonthColumnView_rtl.css";
+			@import "monthcolumnview.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>			
+	</head>
+	
+	<body class="claro" dir="rtl">
+		<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/declare", "dojo/_base/fx", "dojo/on", "dojo/date/locale", "dojo/parser", "dojo/date", "dojo/_base/lang",
+					"dojo/dom", "dojo/dom-construct", "dojo/dom-class", "dojo/_base/window", "dijit/registry", "dojo/query", "dojox/calendar/MonthColumnView", 
+					"dojox/calendar/Keyboard", "dojox/calendar/Mouse",	"dojox/calendar/VerticalRenderer", 
+					"dojo/store/Memory", "dojo/store/Observable",
+					"dijit/form/VerticalSlider", "dijit/form/NumberSpinner", "dijit/form/ComboBox", "dijit/form/DateTextBox", "dijit/form/TimeTextBox", 
+					"dijit/form/TextBox", "dijit/form/Button", "dijit/TitlePane", "dijit/Tooltip", "dijit/form/CheckBox"],
+
+				function(ready, declare, fx,on, locale, parser, date, lang, dom, domConstruct, domClass, win, registry, query,
+					MonthColumnView, CalendarKeyboard, CalendarMouse, VerticalRenderer, Memory, Observable, VerticalSlider, 
+					NumberSpinner, ComboBox, DateTextBox, TimeTextBox, TextBox, Button, TitlePane, Tooltip, CheckBox){
+
+					ready(function(){
+
+						// singleton
+						win.doc.appState = {
+							moveDisabledMap: {},
+							resizeDisabledMap: {}
+						};
+						
+						var mergeDateTime = function(isStart){
+							var dateEditor = isStart ? itemStartDateEditor : itemEndDateEditor;
+							var timeEditor = isStart ? itemStartTimeEditor : itemEndTimeEditor;
+							var date = dateEditor.get("value");
+							var time = timeEditor.get("value");
+							date.setHours(time.getHours());
+							date.setMinutes(time.getMinutes());
+							return date;
+						};
+						
+						var addLogEntry = function(name, content){
+							var tr = domConstruct.create("tr", null, dom.byId("logBody"), "first");
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(locale.format(new Date(), {selector:"time", timePattern:"h:mm:ss"})));
+							var td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(name));
+							td = domConstruct.create("td", null, tr);
+							td.appendChild(win.doc.createTextNode(content));
+						};
+
+						// Calendar model creation
+						
+						var dateClassObj = Date;
+						
+						var modelBase = [
+							{day: 1, start: [0,0], duration: 1440*4, allDay: true},
+							{day: 3, start: [0,0], duration: 2880, allDay: true}
+						];
+						
+						// TODO manage first day of week
+						var floorToWeek= function(d){
+							d.setHours(0);
+							d.setMinutes(0);
+							d.setSeconds(0);
+							d.setMilliseconds(0);
+							d = date.add(d, "day", -d.getDay());
+							return d;
+						};
+						
+						var someData = [];
+						
+						var startOfWeek = new dateClassObj();
+						startOfWeek = floorToWeek(startOfWeek);
+						
+						startDateEditor.set("value", startOfWeek);
+						
+						for (var id=0; id<modelBase.length; id++) {
+							var newObj = {
+								id: id,
+								summary: "New Event " + id,
+								startTime: new dateClassObj(startOfWeek.getTime()),
+								endTime: new dateClassObj(startOfWeek.getTime()),
+								calendar: id%2 == 0 ? "cal1" : "cal2",
+								allDay: modelBase[id].allDay
+							};
+
+							newObj.startTime = date.add(newObj.startTime, "day", modelBase[id].day);
+							newObj.startTime.setHours(modelBase[id].start[0]);
+							newObj.startTime.setMinutes(modelBase[id].start[1]);
+
+							newObj.endTime = date.add(newObj.startTime, "minute", modelBase[id].duration);
+
+							someData.push(newObj);
+						}
+
+						
+						// Calendar creation & configuration
+						
+						colView = declare([MonthColumnView, CalendarKeyboard, CalendarMouse])({
+							store: new Observable(new Memory({data: someData})),
+							verticalRenderer: VerticalRenderer,
+							cssClassFunc: function(item){
+								return item.calendar == "cal1" ? "Calendar1" : "Calendar2"
+							},
+							isItemMoveEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.moveDisabledMap[item.id] !== true;
+							},
+							isItemResizeEnabled: function(item, kind){
+								return this.isItemEditable(item, kind) && win.doc.appState.resizeDisabledMap[item.id] !== true;
+							}
+						}, "calendarNode");
+
+						// Events management
+						
+						
+						colView.on("gridDoubleClick", function(e){
+
+							// create a event when double-clicking on grid.
+							var start = colView.floorToDay(e.date, "day");
+							var end = date.add(start, "day", 1);
+							
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: start,
+								endTime: end,
+								calendar: id % 2 == 0 ? "cal1" : "cal2",
+								allDay: e.sheet == "secondary"
+							};
+							
+							id++;		
+							colView.store.add(item);
+							
+							colView.set("selectedItem", item);
+							colView.set("focusedItem", item);
+							onColViewChange(item);							
+						});
+
+						var startDateSave;
+						var columnCountSave;
+
+						colView.on("columnHeaderClick", function(e){
+							if (colView.get("columnCount") == 1) {
+								colView.set("startDate", startDateSave);
+								colView.set("columnCount", columnCountSave);
+							} else {
+								startDateSave = colView.get("startDate");
+								columnCountSave = colView.get("columnCount");
+								colView.set("startDate", e.date);
+								colView.set("columnCount", 1);
+							}
+						});
+						
+						var onColViewChange = function(item){
+							if (item == null){
+								
+								editedItem = null;
+								
+								itemSummaryEditor.set("value", null);
+								itemSummaryEditor.set("disabled", true);
+								
+								itemStartDateEditor.set("value", null);
+								itemStartDateEditor.set("disabled", true);
+								
+								itemStartTimeEditor.set("value", null);
+								itemStartTimeEditor.set("disabled", true);
+								
+								itemEndDateEditor.set("value", null);
+								itemEndDateEditor.set("disabled", true);
+								
+								itemEndTimeEditor.set("value", null);
+								itemEndTimeEditor.set("disabled", true);
+								
+								updateItemButton.set("disabled", true);
+								
+								allDayCB.set("disabled", true);
+								allDayCB.set("checked", false, false);
+								
+								resizeEnabledCB.set("disabled", true);
+								resizeEnabledCB.set("checked", false);
+								
+								moveEnabledCB.set("disabled", true);
+								moveEnabledCB.set("checked", false);
+								
+								calendarEditor.set("disabled", true);
+								
+								
+							}else{
+								// work on a copy
+								editedItem = lang.mixin({}, item);
+								
+								var allDay = item.allDay === true;
+																
+								itemSummaryEditor.set("value", item.summary);
+								itemSummaryEditor.set("disabled", false);
+								
+								itemStartDateEditor.set("value", item.startTime);
+								itemStartDateEditor.set("disabled", false);
+								
+								itemStartTimeEditor.set("value", item.startTime);
+								itemStartTimeEditor.set("disabled", allDay);
+								
+								itemEndDateEditor.set("value", item.endTime);
+								itemEndDateEditor.set("disabled", false);
+								
+								itemEndTimeEditor.set("value", item.endTime);
+								itemEndTimeEditor.set("disabled", allDay);
+								
+								calendarEditor.set("value", item.calendar == "cal1" ? "Calendar 1" : "Calendar 2");
+								
+								updateItemButton.set("disabled", false);
+								calendarEditor.set("disabled", false);	
+								
+								allDayCB.set("disabled", false);
+								allDayCB.set("checked", allDay, false);
+								
+								resizeEnabledCB.set("disabled", false);
+								resizeEnabledCB.set("checked", win.doc.appState.resizeDisabledMap[item.id] !== true);
+								
+								moveEnabledCB.set("disabled", false);
+								moveEnabledCB.set("checked", win.doc.appState.moveDisabledMap[item.id] !== true);
+							}
+							
+							var res = "";
+							if(item == null){
+								res = null;
+							}else{
+								var list = colView.get("selectedItems");
+								for(var i=0; i<list.length; i++){
+									res += list[i].summary;
+									if(i != list.length-1){
+										res += ", ";
+									}
+								}
+							}
+							addLogEntry("onChange", res);
+						};
+						
+						allDayCB.on("change", function(value){
+							
+							itemStartTimeEditor.set("disabled", value);
+							itemEndTimeEditor.set("disabled", value);
+							var d;
+							if(value){
+								d = itemStartTimeEditor.get("value");
+								colView.floorToDay(d, true);
+								itemStartTimeEditor.set("value", d);
+								d = itemEndTimeEditor.get("value");
+								colView.floorToDay(d, true);
+								itemEndTimeEditor.set("value", d);
+								
+								if(!colView.isStartOfDay(editedItem.endTime)){
+									d = itemEndDateEditor.get("value");
+									colView.floorToDay(d, true);
+									d = colView.renderData.dateModule.add(d, "day", 1);
+									itemEndDateEditor.set("value", d);
+								}
+								
+							}else{
+								editedItem.startTime.setHours(8);
+								editedItem.endTime.setHours(9);
+								itemStartTimeEditor.set("value", editedItem.startTime);
+								itemEndTimeEditor.set("value", editedItem.endTime);
+								d = itemEndDateEditor.get("value");
+								colView.floorToDay(d, true);
+								d = colView.renderData.dateModule.add(d, "day", -1);
+								itemEndDateEditor.set("value", d);
+							}
+							
+						});
+						
+						colView.on("change", function(e){							
+							onColViewChange(e.newValue);							
+						});
+						
+						startDateEditor.on("change", function(value){
+							colView.set("startDate", value);
+						});
+						
+						var editedItem;
+						
+						updateItemButton.on("click", function(value){
+							
+							if (editedItem != null) {
+								editedItem.summary = itemSummaryEditor.get("value");
+								if(allDayCB.get("value")){
+									if(!colView.isStartOfDay(editedItem.startTime)){
+										editedItem.startTime = colView.floorToDay(itemStartDateEditor.get("value"), true);
+									}
+									if(!colView.isStartOfDay(editedItem.endTime)){
+										editedItem.endTime = colView.floorToDay(itemEndDateEditor.get("value"), true);
+									}			
+									editedItem.allDay = true;						
+								}else{
+									editedItem.startTime = mergeDateTime(true);
+									editedItem.endTime = mergeDateTime(false);
+									delete editedItem.allDay;
+								}
+								
+								var calValue = calendarEditor.get("value");
+								editedItem.calendar = calValue == "Calendar 1" ? "cal1" : "cal2";
+								colView.store.put(editedItem);
+							}
+							
+						});
+						
+						colView.on("itemClick", function(e){
+							addLogEntry("onItemClick", e.item.summary);
+						});
+						colView.on("itemDoubleClick", function(e){
+							addLogEntry("onItemDoubleClick", e.item.summary);
+						});
+						colView.on("gridClick", function(e){
+							addLogEntry("onGridClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});
+						colView.on("gridDoubleClick", function(e){
+							addLogEntry("onGridDoubleClick", locale.format(e.date, {datePattern:"yyyy/MM/dd", timePattern:"h:mm"}));
+						});												
+						
+						colView.on("itemRollOut", function(e){
+							addLogEntry("onItemRollOut", e.item.summary);
+						});											
+						
+						var getItemLabel = function(item){
+							return "<b>" + item.summary + "</b><br/><table><tr><td style='text-align:right'>" + 
+								"Start:</td><td>" + colView.renderData.dateLocaleModule.format(item.startTime, {formatLength: "medium"}) + "</td></tr><tr><td style='text-align:right'>" + 
+								"End:</td><td>" + colView.renderData.dateLocaleModule.format(item.endTime, {formatLength: "medium"}) + "</td></tr></table>";
+						};
+						
+						colView.on("focusChange", function(e){
+							addLogEntry("focusChange", e.item ? e.item.summary: "null");					
+						});
+												
+						colView.on("itemRollOver", function(e){							
+							addLogEntry("onItemRollOver", e.item.summary);																				
+						});
+						
+						colView.on("itemEditBegin", function(e){							
+							addLogEntry("onItemEditBegin", e.item.summary);
+						});
+						
+						colView.on("itemEditBeginGesture", function(e){
+							addLogEntry("onItemEditBeginGesture", e.editKind + ", " + e.item.summary);							
+						});
+						
+						colView.on("itemEditEndGesture", function(e){
+							addLogEntry("onItemEditEndGesture", e.editKind + ", " + e.item.summary);														
+							onColViewChange(e.item);
+						});
+						
+												
+						colView.on("itemEditEnd", function(e){
+							addLogEntry("onItemEditEnd", e.item.summary + ", completed:" + e.completed);																							
+						});
+																	
+						editableCB.on("change", function(value){
+							colView.set("editable", value);
+						});
+						
+						keyEditableCB.on("change", function(value){
+							colView.set("keyboardEditable", value);
+						});
+						
+						liveEditCB.on("change", function(value){
+							colView.liveLayout = value;
+						});
+												
+						allowSwapCB.on("change", function(value){							
+							colView.allowStartEndSwap = value;
+						});
+						
+						viewConstrainCB.on("change", function(value){							
+							colView.stayInView = value;
+						});											
+												
+						resizeEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("resizeEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("resizeEnabledCBLabel", "disabled");
+							}							
+						});
+
+						moveEnabledCB.watch("disabled", function(oldV, newV){
+							if (newV){
+								domClass.remove("moveEnabledCBLabel", "disabled");	
+							}else{
+								domClass.add("moveEnabledCBLabel", "disabled");
+							}
+						});
+						
+						resizeEnabledCB.on("change", function(value){
+							if (colView.selectedItem) {
+								if (value){
+									delete win.doc.appState.resizeDisabledMap[colView.selectedItem.id]	
+								} else {
+									win.doc.appState.resizeDisabledMap[colView.selectedItem.id] = true;
+								}								
+							}
+						});
+
+						moveEnabledCB.on("change", function(value){
+							if (colView.selectedItem) {
+								if (value){
+									delete win.doc.appState.moveDisabledMap[colView.selectedItem.id]	
+								} else {
+									win.doc.appState.moveDisabledMap[colView.selectedItem.id] = true;
+								}
+							}
+						});
+						
+						overlapEditor.on("change", function(value){
+							colView.set('percentOverlap', this.value);
+							hGapEditor.set("disabled", value!=0)
+						});
+						
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff">
+				<span style="background: #DBEB8F;padding:2px">Loading...</span>
+			</div>
+			
+			<div id="formDiv">
+				
+				<div data-dojo-type="dijit.TitlePane" title="Date Interval" class="formPanel">
+					<table class="formTable">	
+						<tr>
+							<td>Start date:</td>
+							<td><div data-dojo-id="startDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:80px"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Column count:</td>
+							<td><div data-dojo-id="columnCountEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" data-dojo-props="constraints:{min:1, max:12}, value:6, intermediateChanges:true" onChange="colView.set('columnCount', this.value);"></div></td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Main Properties" class="formPanel">
+					<table class="formTable">
+						<tr>
+							<td>Day size(px):</td>
+							<td><div data-dojo-id="daySizeEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" value="30" data-dojo-props="constraints:{min:20, max:200}, intermediateChanges:true, smallDelta:5" onChange="colView.set('daySize', this.value);"></div></td>
+						</tr>
+												
+						<tr>
+							<td>Overlap (%):</td>
+							<td><div data-dojo-id="overlapEditor" data-dojo-type="dijit.form.NumberSpinner" data-dojo-props="value:0, constraints:{min:0, max:100}, intermediateChanges:true, smallDelta:10" style="width:80px"></div></td>
+						</tr>
+						
+						<tr>
+							<td>Horizontal gap (px):</td>
+							<td><div data-dojo-id="hGapEditor" data-dojo-type="dijit.form.NumberSpinner" style="width:80px" data-dojo-props="constraints:{min:0, max:30}, value:2, intermediateChanges:true" onChange="colView.set('horizontalGap', this.value);"></div></td>
+						</tr>
+												
+						<tr>
+							<td>Selection mode:</td>
+							<td>
+								<select data-dojo-id="selectionModeEditor" data-dojo-type="dijit.form.ComboBox" style="width:80px;" onChange="colView.set('selectionMode', this.value);">
+									<option>none</option>
+									<option selected>single</option>
+									<option>multiple</option>
+								</select>
+							</td>
+						</tr>
+					</table>
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Item Properties" class="formPanel" open="false">					
+					<table>					
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Summary:</span>
+								<div data-dojo-id="itemSummaryEditor" data-dojo-type="dijit.form.TextBox" style="width:140px; margin-left: 10px" data-dojo-props="placeHolder:'Summary...'"></div>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2">
+								<span style="font-size:0.9em">Calendar:</span>					
+								<select data-dojo-id="calendarEditor" data-dojo-type="dijit.form.ComboBox"  style="width:140px; margin-left: 12px" >
+									<option>Calendar 1</option>
+									<option>Calendar 2</option>									
+								</select>
+							</td>
+						</tr>
+						
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allDayCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label for="allDayCB">All day</label>
+							</td>
+						</tr>
+						
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">Start time:</td>
+						</tr>
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemStartDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemStartTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" ></div>
+							</td>
+						</tr>											
+						
+						<tr>
+							<td style="padding-top:5px;font-size:0.9em">End time:</td>
+						</tr>
+						
+						<tr>
+							<td style="text-align:right;">
+								<div data-dojo-id="itemEndDateEditor" data-dojo-type="dijit.form.DateTextBox" style="width:100px;" ></div>
+							</td>
+							<td>
+								<div data-dojo-id="itemEndTimeEditor" data-dojo-type="dijit.form.TimeTextBox" style="width:100px;" ></div>
+							</td>
+						</tr>
+						
+						<tr>
+							<td colspan="2" style="text-align:right;padding-top:5px;font-size:0.9em">
+								<button data-dojo-id="updateItemButton" data-dojo-type="dijit.form.Button" disabled="true">Update</button>
+							</td>
+						</tr>
+					</table>	
+				</div>
+				
+				<div data-dojo-type="dijit.TitlePane" title="Editing properties" class="formPanel" data-dojo-props="open:true">
+					<table>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="liveEditCB" data-dojo-type="dijit.form.CheckBox" checked="false" />
+								<label for="liveEditCB">Live layout</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="allowSwapCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="allowSwapCB">Allow start/end swap</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="editableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="editableCB">Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="keyEditableCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="keyEditableCB">Keyboard Editable (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" data-dojo-id="viewConstrainCB" data-dojo-type="dijit.form.CheckBox" checked="true" />
+								<label for="viewConstrainCB">Stay in view (global)</label>
+							</td>
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" id="moveEnabledCB" data-dojo-id="moveEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="moveEnabledCBLabel" for="moveEnabledCB" class="disabled">Move Enabled (item)</label>
+							</td>						
+						</tr>
+						<tr>
+							<td colspan="2" class="smallText" >
+								<input type="checkbox" id="resizeEnabledCB" data-dojo-id="resizeEnabledCB" data-dojo-type="dijit.form.CheckBox" checked="false" disabled="true" />
+								<label id="resizeEnabledCBLabel" for="resizeEnabledCB" class="disabled">Resize Enabled (item)</label>
+							</td>
+						</tr>
+						
+					</table>
+				</div>
+				
+			</div>
+						
+			<div id="calendarNode"></div>
+			
+			<div id="eventLogPane" title="Calendar events" data-dojo-type="dijit.TitlePane" data-dojo-props="toggleable:false" >
+							
+				<div id="logTableContainer">
+					<table id="logTable">
+						<tbody id="logBody"></tbody>
+					</table>		
+				</div>
+				
+			</div>
+						
+	</body>
+</html>
diff --git a/dojox/calendar/tests/monthtablet.css b/dojox/calendar/tests/monthtablet.css
new file mode 100644
index 0000000..6ab6c67
--- /dev/null
+++ b/dojox/calendar/tests/monthtablet.css
@@ -0,0 +1,14 @@
+html, body {
+    margin: 0;
+    padding: 0;
+    width: 100%;
+    height: 100%;
+}
+
+#calendarNode {
+	position:absolute; 
+	left:5px; 
+	right:5px; 
+	top:5px; 
+	bottom:5px;
+}
\ No newline at end of file
diff --git a/dojox/calendar/tests/monthtablet.html b/dojox/calendar/tests/monthtablet.html
new file mode 100644
index 0000000..d4c7a5a
--- /dev/null
+++ b/dojox/calendar/tests/monthtablet.html
@@ -0,0 +1,138 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	
+	<head>
+		
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		
+		<title>Month Column View Sample: Tablet</title>				
+		<style type="text/css">
+			@import "../themes/iphone/MonthColumnView.css";
+			@import "monthtablet.css";
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+	</head>
+	
+	<body>
+			<script type="text/javascript" 
+						data-dojo-config="async: true, parseOnLoad: true"
+		 				src="../../../dojo/dojo.js"></script>
+		
+			<script type="text/javascript">
+
+			require(["dojo/ready", "dojo/_base/declare", "dojo/on", "dojo/date/locale", "dojo/parser", "dojo/date", "dojo/_base/lang",
+					"dojo/dom", "dojo/dom-construct", "dojo/dom-class", "dojo/_base/window",
+					"dijit/registry", "dojo/query", "dojox/calendar/MonthColumnView", "dojox/calendar/Touch", 
+					"dojox/calendar/MobileVerticalRenderer", "dojox/calendar/time", "dojo/store/Memory", "dojo/store/Observable",
+					 "dojo/_base/fx"],
+
+				function(ready, declare, on, locale, parser, date, lang, dom, domConstruct, domClass, win, registry, query,
+					MonthColumnView, CalendarTouch, VerticalRenderer, time, Memory, Observable, fx){
+
+					ready(function(){
+
+						// Calendar model creation
+						
+						var dateClassObj = Date;
+						
+						var modelBase = [
+							{day: 0, start: [0,0], duration: 1440, allDay:true},
+							{day: 1, start: [6,0], duration: 240},
+							{day: 1, start: [10,0], duration: 240},
+							{day: 1, start: [16,0], duration: 60},
+							{day: 2, start: [8,0], duration: 120},
+							{day: 2, start: [10,0], duration: 120},
+							{day: 2, start: [16,0], duration: 120},
+							{day: 3, start: [8,0], duration: 1440*2},
+							{day: 5, start: [0,0], duration: 1440, allDay:true},
+							{day: 6, start: [0,0], duration: 2*1440, allDay:true}
+						];
+						
+						
+						var someData = [];
+						
+						var startOfMonth = new Date();
+						startOfMonth = time.floorToMonth(startOfMonth, Date);
+												
+						var id;
+						
+							for (var i=0; i<modelBase.length; i++) {
+								id = (modelBase.length)+i;
+								var newObj = {
+									id: id,
+									summary: "New Event " + id,
+									startTime: new dateClassObj(startOfMonth.getTime()),
+									endTime: new dateClassObj(startOfMonth.getTime())
+								};
+	
+								newObj.startTime = date.add(newObj.startTime, "day", Math.floor(Math.random()*30));
+								newObj.startTime.setHours(modelBase[i].start[0]);
+								newObj.startTime.setMinutes(modelBase[i].start[1]);
+	
+								newObj.endTime = date.add(newObj.startTime, "minute", modelBase[i].duration);
+								
+								if(modelBase[i].allDay != undefined){
+									newObj.allDay = modelBase[i].allDay; 
+								}
+	
+								someData.push(newObj);
+							}
+							
+						
+						id++;
+						
+						// Calendar creation & configuration
+						
+						monthView = declare([MonthColumnView, CalendarTouch])({
+							store: new Observable(new Memory({data: someData})),
+							startDate: startOfMonth,
+							verticalRenderer: VerticalRenderer,
+							columnCount: 1							
+						}, "calendarNode");
+
+						// Events management
+						
+						monthView.on("gridDoubleClick", function(e){
+
+							// create a event when double-clicking on grid.
+							var d = monthView.floorToDay(e.date, true);
+
+							var item = {
+								id: id,
+								summary: "New event " + id,
+								startTime: d,
+								endTime: date.add(d, "day", 1),
+								calendar: id % 2 == 0 ? "cal1" : "cal2"
+							};
+							id++;
+							monthView.store.add(item);
+							
+							monthView.set("selectedItem", item);
+							monthView.set("focusedItem", item);							
+						});
+
+																																				
+																													
+						fx.fadeOut({
+							node:"loadingPanel", 
+							onEnd: function(node){
+								node.parentNode.removeChild(node)
+							}}).play(500);
+
+					});
+			});
+			</script>
+			
+			<div id="loadingPanel" style="position:absolute;z-index:10;width:100%;height:100%;background:#ffffff;text-align: center">
+				<span style="background: #DBEB8F">Loading...</span>
+			</div>
+						
+			<div id="calendarNode"></div>					
+
+	</body>
+</html>
diff --git a/dojox/calendar/tests/runTests.html b/dojox/calendar/tests/runTests.html
new file mode 100644
index 0000000..4835ef0
--- /dev/null
+++ b/dojox/calendar/tests/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+  <head>
+  <title>Dojo Diagrammer Unit Test Runner</title>
+    <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?test=dojox/calendar/tests/module"></HEAD>
+  <BODY>
+    Redirecting to D.O.H runner.
+  </BODY>
+</HTML>
\ No newline at end of file
diff --git a/dojox/calendar/tests/unitTest_Store.js b/dojox/calendar/tests/unitTest_Store.js
new file mode 100644
index 0000000..e53abf4
--- /dev/null
+++ b/dojox/calendar/tests/unitTest_Store.js
@@ -0,0 +1,14 @@
+define(["doh", "../Calendar", "dojo/when", "dojo/store/JsonRest"],
+	function(doh, Calendar, when, JsonRest){
+	doh.register("tests.unitTest_Store", [
+		function test_Error(t){
+			var calendar = new Calendar();
+			var d = when(calendar.set("store", new JsonRest({ target: "/" }), function(){
+				t.f(true, "ok fct must not have been called");
+			}, function(){
+				t.t(true, "failure fct must have been called");
+			}));
+			calendar.startup();
+		}
+	]);
+});
diff --git a/dojox/calendar/tests/unitTest_Time.js b/dojox/calendar/tests/unitTest_Time.js
new file mode 100644
index 0000000..2a0d641
--- /dev/null
+++ b/dojox/calendar/tests/unitTest_Time.js
@@ -0,0 +1,22 @@
+define(["doh", "../time", "dojo/date", "dojo/date/locale", "dojox/date/hebrew/Date", "dojox/date/hebrew", "dojox/date/hebrew/locale"],
+	function(doh, time, date, dateLocale, hDate, h, hLocale){
+	doh.register("tests.unitTest_Time", [
+		function test_decodeDate(doh){
+			var d = new Date(2009, 2, 20, 5, 27, 30, 0);
+			var t = d.getTime();
+			var hd = new hDate(t);
+			var s = "2009-03-20T05:27:30";
+			
+			doh.is(date.compare(d, time.newDate(d)), 0);
+			doh.is(date.compare(d, time.newDate(t)), 0);
+			doh.is(date.compare(d, time.newDate(s)), 0);
+			doh.is(date.compare(d, time.newDate(hd)), 0);
+			
+			doh.is(h.compare(hd, time.newDate(hd, hDate)), 0);
+			doh.is(h.compare(hd, time.newDate(d, hDate)), 0);
+			doh.is(h.compare(hd, time.newDate(t, hDate)), 0);
+			doh.is(h.compare(hd, time.newDate(s, hDate)), 0);
+			
+		}
+	]);
+});
diff --git a/dojox/calendar/tests/unitTest_TimeRanges.js b/dojox/calendar/tests/unitTest_TimeRanges.js
new file mode 100644
index 0000000..84869dd
--- /dev/null
+++ b/dojox/calendar/tests/unitTest_TimeRanges.js
@@ -0,0 +1,151 @@
+define(["doh", "../Calendar"], 
+	function(doh, Calendar){
+	doh.register("tests.unitTest_TimeRanges", [
+	
+		/* Should work but does not. Unfortunately I don't have time to investigate why...
+		 {
+			name: "TotoTest",
+			setUp: function(){
+				this.toto = 10;
+			},
+			tearDown: function(){
+				delete this.toto;
+			},
+			test1: function(){
+				doh.is(this.toto, 10);
+			},
+			test2: function(){
+				doh.is(this.toto, 10);
+			}
+		},*/
+	
+		function test_DayInterval(doh){
+			var o = new Calendar();
+			var cal = o.dateModule;
+			var startDate = new Date(2011, 0, 5);
+			var res;
+			
+			o.set("date", startDate);
+			o.set("dateInterval", "day");
+			o.set("dateIntervalSteps", 1);
+			o.validateRendering();
+			doh.is(cal.compare(o.get("date"), startDate), 0);
+			
+			res = o._timeInterval;
+			doh.is(cal.compare(res[0], new Date(2011, 0, 5)), 0);
+			doh.is(cal.compare(res[1], new Date(2011, 0, 6)), 0);
+			o.destroyRecursive();					
+		},
+		
+		function test_MultiDayInterval(doh){
+			var o = new Calendar();
+			var cal = o.dateModule;
+			var startDate = new Date(2011, 0, 5);
+			var res;
+			
+			o.set("date", startDate);
+			o.set("dateInterval", "day");
+			o.set("dateIntervalSteps", 3);
+			o.validateRendering();
+			doh.is(cal.compare(o.get("date"), startDate), 0);
+			
+			res = o._timeInterval;
+			doh.is(cal.compare(res[0], new Date(2011, 0, 5)), 0);
+			doh.is(cal.compare(res[1], new Date(2011, 0, 8)), 0);
+			o.destroyRecursive();					
+		},
+		
+		function test_WeekInterval(doh){
+			var o = new Calendar({
+				firstDayOfWeek: 0 // do not depend on locale
+			});
+			var cal = o.dateModule;
+			var startDate = new Date(2011, 0, 5);
+			var res;
+			
+			o.set("date", startDate);
+			o.set("dateInterval", "week");
+			o.set("dateIntervalSteps", 1);
+			o.validateRendering();
+			doh.is(cal.compare(o.get("date"), startDate), 0);
+			
+			res = o._timeInterval;
+			doh.is(cal.compare(res[0], new Date(2011, 0, 2)), 0);
+			doh.is(cal.compare(res[1], new Date(2011, 0, 9)), 0);
+			
+			o.set("firstDayOfWeek", 1);
+			o.validateRendering();
+			doh.is(cal.compare(o.get("date"), startDate), 0);
+			
+			res = o._timeInterval;
+			doh.is(cal.compare(res[0], new Date(2011, 0, 3)), 0);
+			doh.is(cal.compare(res[1], new Date(2011, 0, 10)), 0);		
+			o.destroyRecursive();		
+		},
+		
+		function test_MultiWeekInterval(doh){
+			var o = new Calendar({
+				firstDayOfWeek: 0 // do not depend on locale
+			});
+			var cal = o.dateModule;
+			var startDate = new Date(2011, 0, 5);
+			var res;
+			
+			o.set("date", startDate);
+			o.set("dateInterval", "week");
+			o.set("dateIntervalSteps", 2);
+			o.validateRendering();
+			doh.is(cal.compare(o.get("date"), startDate), 0);
+			
+			res = o._timeInterval;
+			doh.is(cal.compare(res[0], new Date(2011, 0, 2)), 0);
+			doh.is(cal.compare(res[1], new Date(2011, 0, 16)), 0);
+			
+			o.set("firstDayOfWeek", 1);
+			o.validateRendering();
+			doh.is(cal.compare(o.get("date"), startDate), 0);
+			
+			res = o._timeInterval;
+			doh.is(cal.compare(res[0], new Date(2011, 0, 3)), 0);
+			doh.is(cal.compare(res[1], new Date(2011, 0, 17)), 0);
+			o.destroyRecursive();				
+		},
+		
+		function test_MonthInterval(doh){
+			var o = new Calendar();
+			var cal = o.dateModule;
+			var startDate = new Date(2011, 0, 5);
+			var res;
+			
+			o.set("date", startDate);
+			o.set("dateInterval", "month");
+			o.set("dateIntervalSteps", 1);
+			o.validateRendering();
+			doh.is(cal.compare(o.get("date"), startDate), 0);
+			
+			res = o._timeInterval;
+			doh.is(cal.compare(res[0], new Date(2011, 0, 1)), 0);
+			doh.is(cal.compare(res[1], new Date(2011, 1, 1)), 0);
+			o.destroyRecursive();					
+		},
+		
+		function test_MultiMonthInterval(doh){
+			var o = new Calendar();
+			var cal = o.dateModule;
+			var startDate = new Date(2011, 0, 5);
+			var res;
+			
+			o.set("date", startDate);
+			o.set("dateInterval", "month");
+			o.set("dateIntervalSteps", 2);
+			o.validateRendering();
+			doh.is(cal.compare(o.get("date"), startDate), 0);
+			
+			res = o._timeInterval;
+			doh.is(cal.compare(res[0], new Date(2011, 0, 1)), 0);
+			doh.is(cal.compare(res[1], new Date(2011, 2, 1)), 0);
+			o.destroyRecursive();					
+		}
+		
+	]);
+});
diff --git a/dojox/calendar/tests/unitTest_editing.js b/dojox/calendar/tests/unitTest_editing.js
new file mode 100644
index 0000000..14abadc
--- /dev/null
+++ b/dojox/calendar/tests/unitTest_editing.js
@@ -0,0 +1,736 @@
+define(["doh", "../ColumnView", "../MatrixView", "dojo/store/Memory", "dojo/store/Observable"], 
+	function(doh, ColumnView, MatrixView, Memory, Observable){
+	doh.register("tests.unitTest_editing", [
+	
+		function test_MoveNoSnap(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5, 10), endTime: new Date(2011, 0, 5, 11) };
+			var data = [ item ];
+			
+			var o = new ColumnView({				
+				startDate:  new Date(2011, 0, 5),
+				store: new Observable(new Memory({data: data})),
+				snapSteps: 1
+			});
+			
+			var cal = o.dateModule;
+			o.validateRendering();
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "vertical",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 37)], "mouse"); // move +7 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 10, 7)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 5, 11, 7)), 0);
+			
+			renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "vertical",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 27)], "mouse"); // move -3 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 10, 4)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 5, 11, 4)), 0);
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		},
+		
+		function test_MoveSnap(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5, 10), endTime: new Date(2011, 0, 5, 11) };
+			var data = [ item ];
+			
+			var o = new ColumnView({			
+				startDate:  new Date(2011, 0, 5),	
+				store: new Observable(new Memory({data: data})),
+				snapSteps: 15
+			});
+			
+			var cal = o.dateModule;
+			o.validateRendering();
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "vertical",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 35)], "mouse"); // move +5 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 10, 0)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 5, 11, 0)), 0);
+			
+			renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "vertical",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 47)], "mouse"); // move +17 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 10, 15)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 5, 11, 15)), 0);
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		},
+		
+		function test_ResizeNoSnap(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5, 10), endTime: new Date(2011, 0, 5, 11) };
+			var data = [ item ];
+			
+			var o = new ColumnView({		
+				startDate:  new Date(2011, 0, 5),		
+				store: new Observable(new Memory({data: data})),
+				snapSteps: 1
+			});
+			
+			var cal = o.dateModule;
+			o.validateRendering();
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "resizeStart",
+				editedItem: renderItem,
+				rendererKind: "vertical",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "resizeStart", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 23)], "mouse"); // resize start -7 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 9, 53)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 5, 11)), 0);
+			
+			renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "resizeEnd",
+				editedItem: renderItem,
+				rendererKind: "vertical",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "resizeEnd", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 37)], "mouse"); // resize end +7 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 9, 53)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 5, 11, 8)), 0); // 7 + 1 as end is moved
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		},
+		
+		function test_ResizeSnap(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5, 10), endTime: new Date(2011, 0, 5, 11) };
+			var data = [ item ];
+			
+			var o = new ColumnView({	
+				startDate:  new Date(2011, 0, 5),			
+				store: new Observable(new Memory({data: data})),
+				snapSteps: 5
+			});
+			
+			var cal = o.dateModule;
+			o.validateRendering();
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "resizeStart",
+				editedItem: renderItem,
+				rendererKind: "vertical",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "resizeStart", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 23)], "mouse"); // resize start -7 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 9, 50)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 5, 11)), 0);
+			
+			renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "resizeEnd",
+				editedItem: renderItem,
+				rendererKind: "vertical",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "resizeEnd", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 37)], "mouse"); // resize end +7 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 9, 50)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 5, 11, 10)), 0);
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		},
+		
+		function test_ResizeMinDurationColumnView(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5, 10), endTime: new Date(2011, 0, 5, 11) };
+			var data = [ item ];
+			
+			var o = new ColumnView({	
+				startDate:  new Date(2011, 0, 5),			
+				store: new Observable(new Memory({data: data})),
+				minDurationUnit: "minute",
+				minDurationSteps: 15,
+				snapSteps: 1
+			});
+			
+			var cal = o.dateModule;
+			o.validateRendering();
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "resizeEnd",
+				editedItem: renderItem,
+				rendererKind: "vertical",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 0)], "resizeEnd", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 9, 10)], "mouse"); //- 50 min 
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 10)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 5, 10, 15)), 0);					
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		},
+		
+		function test_MoveAllDay(doh){
+			
+			var item = {	id:0, startTime: new Date(2011, 0, 5), endTime: new Date(2011, 0, 6), allDay: true };
+			var data = [ item ];
+			
+			var o = new MatrixView({	
+				startDate:  new Date(2011, 0, 3),			
+				store: new Observable(new Memory({data: data}))
+			});
+			
+			var cal = o.dateModule;
+			o.validateRendering();					
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 12)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 18)], "mouse"); // move _at_ 18
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 6)), 0);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 12)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 6, 1)], "mouse"); // move _at_ 6 @ 1am
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 6)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 7)), 0);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 6, 1)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 1)], "mouse"); // move _at_ 5 @ 1am
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 6)), 0);
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		},
+		
+		function test_ResizeStartAllDay(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5), endTime: new Date(2011, 0, 6), allDay: true };
+			var data = [ item ];
+			
+			var o = new MatrixView({				
+				startDate:  new Date(2011, 0, 3),
+				store: new Observable(new Memory({data: data}))
+			});
+			
+			var cal = o.dateModule;
+			o.validateRendering();					
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "resizeStart",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 12)], "resizeStart", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 6)], "mouse"); 
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 6)), 0);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 12)], "resizeStart", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 4, 23)], "mouse"); 
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 4)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 6)), 0);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 4, 23)], "resizeStart", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 1)], "mouse"); 
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 6)), 0);
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		}, 
+		
+		
+		function test_ResizeEndAllDay(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5), endTime: new Date(2011, 0, 6), allDay: true };
+			var data = [ item ];
+			
+			var o = new MatrixView({	
+				startDate: new Date(2011, 0, 3),			
+				store: new Observable(new Memory({data: data}))
+			});
+			
+			var cal = o.dateModule;			
+			o.validateRendering();					
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "resizeEnd",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 12)], "resizeEnd", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 18)], "mouse"); 
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 6)), 0);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 12)], "resizeEnd", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 6, 1)], "mouse"); 
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 7)), 0);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 6, 23)], "resizeEnd", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 1)], "mouse"); 
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 6)), 0);
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		}, 
+		
+		function test_MoveNoSnapMatrixView(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5, 10), endTime: new Date(2011, 0, 7, 11) };
+			var data = [ item ];
+			
+			var o = new MatrixView({			
+				startDate: new Date(2011, 0, 3),	
+				roundToDay: false,
+				store: new Observable(new Memory({data: data})),
+				snapSteps: 1
+			});
+			
+			var cal = o.dateModule;			
+			o.validateRendering();
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 37)], "mouse"); // move +7 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 10, 7)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 7, 11, 7)), 0);
+			
+			renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 27)], "mouse"); // move -3 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 10, 4)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 7, 11, 4)), 0);
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		},
+		
+		function test_MoveSnapMatrixView(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5, 10), endTime: new Date(2011, 0, 7, 11) };
+			var data = [ item ];
+			
+			var o = new MatrixView({			
+				startDate: new Date(2011, 0, 3),	
+				roundToDay: false,
+				store: new Observable(new Memory({data: data})),
+				snapSteps: 5
+			});
+			
+			var cal = o.dateModule;			
+			o.validateRendering();
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 37)], "mouse"); // move +7 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 10, 5)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 7, 11, 5)), 0);
+			
+			renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 27)], "mouse"); // move -3 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 10, 0)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 7, 11, 0)), 0);
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		},
+		
+		function test_MoveRoundToDayMatrixView(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5, 10), endTime: new Date(2011, 0, 7, 11) };
+			var data = [ item ];
+			
+			var o = new MatrixView({			
+				startDate: new Date(2011, 0, 3),	
+				roundToDay: true,
+				store: new Observable(new Memory({data: data}))			
+			});
+			
+			var cal = o.dateModule;			
+			o.validateRendering();
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 37)], "mouse"); // move +7 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 10)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 7, 11)), 0);
+			
+			renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "horizontal",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 6, 1)], "mouse"); 
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 6, 10, 0)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 8, 11, 0)), 0);
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		},
+		
+		function test_MoveLabelMatrixView(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5, 10), endTime: new Date(2011, 0, 5, 11) };
+			var data = [ item ];
+			
+			var o = new MatrixView({			
+				startDate: new Date(2011, 0, 3),	
+				roundToDay: true,
+				store: new Observable(new Memory({data: data}))			
+			});
+			
+			var cal = o.dateModule;			
+			o.validateRendering();
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "label",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 37)], "mouse"); // move +7 min in time
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 10)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 5, 11)), 0);
+			
+			renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "move",
+				editedItem: renderItem,
+				rendererKind: "label",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 5, 10, 30)], "move", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 6, 1)], "mouse"); 
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 6, 10, 0)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 6, 11, 0)), 0);
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		},
+		
+		function test_ResizeMinDurationMatrixView(doh){
+			var item = {	id:0, startTime: new Date(2011, 0, 5, 6), endTime: new Date(2011, 0, 6, 12) };
+			var data = [ item ];
+			
+			var o = new MatrixView({
+				startDate: new Date(2011, 0, 3),
+				store: new Observable(new Memory({data: data})),
+				roundToDay: false,
+				minDurationUnit: "day",
+				minDurationSteps: 1,
+				snapSteps: 1
+			});
+			
+			var cal = o.dateModule;
+			
+			o.validateRendering();
+			
+			var renderItem = o.itemToRenderItem(item, o.store);
+			
+			o._edProps = {
+				editKind: "resizeEnd",
+				editedItem: renderItem,
+				rendererKind: "vertical",
+				tempEditedItem: renderItem,					
+				liveLayout: true			
+			};
+			
+			o._startItemEditing(item, "mouse");
+			o._startItemEditingGesture([new Date(2011, 0, 6, 10, 0)], "resizeEnd", "mouse");
+			o._moveOrResizeItemGesture([new Date(2011, 0, 5, 10, 10)], "mouse"); // -1 day 
+			o._endItemEditingGesture("mouse");
+			o._endItemEditing("mouse", false); // validate changes
+			
+			doh.is(cal.compare(item.startTime, new Date(2011, 0, 5, 6)), 0);
+			doh.is(cal.compare(item.endTime, new Date(2011, 0, 6, 6)), 0);					
+			
+			o.validateRendering();
+			o.destroyRecursive();
+		}
+	
+		
+	]);
+});
diff --git a/dojox/calendar/themes/claro/Calendar.css b/dojox/calendar/themes/claro/Calendar.css
new file mode 100644
index 0000000..1b3f933
--- /dev/null
+++ b/dojox/calendar/themes/claro/Calendar.css
@@ -0,0 +1,28 @@
+ at import url("MatrixView.css");
+
+ at import url("ColumnView.css");
+.claro .dojoxCalendar .buttonContainer {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 31px;
+}
+.claro .dojoxCalendar .buttonContainer .dijitToolbar {
+  border: 1px solid #B5BCC7;
+}
+.claro .dojoxCalendar .viewContainer {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 31px;
+  bottom: 0;
+  overflow: hidden;
+}
+.claro .dojoxCalendar .view {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+}
diff --git a/dojox/calendar/themes/claro/Calendar.less b/dojox/calendar/themes/claro/Calendar.less
new file mode 100644
index 0000000..e2fd1c9
--- /dev/null
+++ b/dojox/calendar/themes/claro/Calendar.less
@@ -0,0 +1,36 @@
+ at button-container-height: 31px;
+
+ at import url("MatrixView.css");
+ at import url("ColumnView.css");
+
+.claro .dojoxCalendar {
+
+	.buttonContainer{
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		height: @button-container-height;
+	
+		 .dijitToolbar {
+			border: 1px solid #B5BCC7;
+		}
+	}
+	
+	.viewContainer{
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: @button-container-height;
+		bottom: 0;
+		overflow: hidden;
+	}
+	
+	.view{
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		bottom: 0;
+	}
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/claro/Calendar_rtl.css b/dojox/calendar/themes/claro/Calendar_rtl.css
new file mode 100644
index 0000000..106a1d6
--- /dev/null
+++ b/dojox/calendar/themes/claro/Calendar_rtl.css
@@ -0,0 +1,3 @@
+ at import url("MatrixView_rtl.css");
+
+ at import url("ColumnView_rtl.css");
diff --git a/dojox/calendar/themes/claro/Calendar_rtl.less b/dojox/calendar/themes/claro/Calendar_rtl.less
new file mode 100644
index 0000000..25ef90d
--- /dev/null
+++ b/dojox/calendar/themes/claro/Calendar_rtl.less
@@ -0,0 +1,3 @@
+ at import url("MatrixView_rtl.css");
+ at import url("ColumnView_rtl.css");
+
diff --git a/dojox/calendar/themes/claro/ColumnView.css b/dojox/calendar/themes/claro/ColumnView.css
new file mode 100644
index 0000000..3cc7a0f
--- /dev/null
+++ b/dojox/calendar/themes/claro/ColumnView.css
@@ -0,0 +1,521 @@
+.event-header {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #6c0000;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: 1px solid #260000;
+  border-left: 1px solid #260000;
+  border-right: 1px solid #260000;
+}
+.claro .dojoxCalendarColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarHeader {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 29px;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 72px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-top: 1px solid #b5bcc7;
+  border-bottom: 1px solid #b5bcc7;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px 1px solid #b5bcc7;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff0b4;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarGridTable .tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff0b4;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #e5f2fe;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #e5f2fe;
+}
+.claro .dojoxCalendarColumnView td.hour {
+  border-top: 1px solid #c7bebe;
+}
+.claro .dojoxCalendarColumnView td.halfhour {
+  border-top: dotted 1px #c7bebe;
+}
+.claro .dojoxCalendarColumnView td.quarterhour {
+  border-top: dotted 1px #c7bebe;
+}
+.claro .dojoxCalendarColumnView span.hour {
+  color: #000000;
+  background-color: #efefef;
+}
+.claro .dojoxCalendarColumnView span.halfhour,
+.claro .dojoxCalendarColumnView span.quarterhour {
+  color: #555555;
+  background-color: #efefef;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  cursor: default;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 2px;
+  margin-right: 9px;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  height: 29px;
+  left: 0;
+  width: 68px;
+  top: 0;
+  border-left: 1px solid #b5bcc7;
+  border-top: 1px solid #b5bcc7;
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #b5bcc7;
+  color: #000000;
+  background-color: #efefef;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 70px;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background-color: #efefef;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+  border-right: 1px solid #cccccc;
+  border-top: 1px solid #b5bcc7;
+  border-bottom: 1px solid #b5bcc7;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #000000;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+  font-weight: bold;
+  color: #ff0000;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #759dc0;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+  background-color: #abd6ff;
+  border-color: #769dc0;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+  background-color: #7dbefa;
+  border-color: #769dc0;
+  background-position: 0 -136px;
+  -webkit-transition-duration: 0s;
+  -moz-transition-duration: 0s;
+  transition-duration: 0s;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarRowHeader {
+  position: absolute;
+  width: 68px;
+  cursor: default;
+  border-left: 1px solid #b5bcc7;
+  border-right: 1px solid #b5bcc7;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabelContainer {
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel {
+  right: 4px;
+  position: absolute;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td.dummy {
+  border-top: 1px solid #efefef;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td {
+  background-color: #efefef;
+  color: #000000;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable tr:first-child td {
+  border-top: 1px solid #efefef;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+  overflow: hidden;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9f0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+  white-space: nowrap;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background-color: #F00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #cc0000;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #ffffff;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #ffffff;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #6c0000;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: 1px solid #260000;
+  border-left: 1px solid #260000;
+  border-right: 1px solid #260000;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Focused .startTime {
+  border-top: dashed 1px #ffffff;
+  border-left: dashed 1px #ffffff;
+  border-right: dashed 1px #ffffff;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Hovered .startTime {
+  background-color: #990000;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Selected .startTime {
+  background-color: #330000;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarEvent.Edited .startTime {
+  background-color: #6c0000;
+  border-top: dashed 1px #ffffff;
+  border-left: dashed 1px #ffffff;
+  border-right: dashed 1px #ffffff;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 72px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 30px;
+  height: 39px;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  bottom: 0;
+  cursor: default;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 70px;
+  bottom: 0;
+  border-right: none;
+  border-left: none;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+  text-align: right;
+  vertical-align: top;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td {
+  border-bottom: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child {
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+  border-top: 1px solid #cccccc;
+  border-left: 1px solid #b5bcc7;
+  border-right: 1px solid #b5bcc7;
+  border-bottom: 1px solid #b5bcc7;
+  background-color: #efefef;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background-color: #F00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  position: absolute;
+  width: 5px;
+  height: 100%;
+  cursor: e-resize;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+  left: 0;
+  top: 0;
+  width: 100%;
+  cursor: move;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+  right: 0px;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .afterIcon {
+  width: auto;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .endTime {
+  position: relative;
+  bottom: auto;
+  left: auto;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  position: absolute;
+  left: 3px;
+  right: 1px;
+  bottom: 2px;
+  overflow: hidden;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand {
+  position: absolute;
+  text-align: center;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+  position: relative;
+  margin-right: 10%;
+  margin-left: 10%;
+  border-radius: 5px;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  border: 1px solid transparent;
+  -moz-border-radius: 5px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+  background-color: #e5f2fe;
+  border: 1px solid #909da9;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+  background-color: #a5d1fb;
+  border: 1px solid #507ca6;
+}
+.claro .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent div {
+  white-space: nowrap;
+}
diff --git a/dojox/calendar/themes/claro/ColumnView.less b/dojox/calendar/themes/claro/ColumnView.less
new file mode 100644
index 0000000..426fa07
--- /dev/null
+++ b/dojox/calendar/themes/claro/ColumnView.less
@@ -0,0 +1,522 @@
+ at import "ColumnViewCommon.less";
+
+.claro .dojoxCalendarColumnView {	
+	cursor: default;
+	-webkit-user-select: none;
+
+	.dojoxCalendarHeader {
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		height: @column-header-height - 1px;
+		.border-box;
+	}
+
+	.dojoxCalendarScrollContainer {
+		left: 0;
+		right: 0;
+		bottom: 0;
+		top: @sheet-top;
+		position: absolute;
+		overflow-y: hidden;
+		overflow-x: hidden;
+		border-top: @outer-border;
+		border-bottom: @outer-border;
+		.border-box;
+	}
+	
+	.dojoxCalendarGrid {
+		position: absolute;
+		left: @row-header-width;
+		right: 0;
+	}
+
+	.dojoxCalendarGridTable {
+		border-collapse: collapse;
+		table-layout: fixed;
+		width: 100%;
+		position: relative;
+		margin: 0;
+		padding: 0;
+		
+	 	td {
+			border-top: dotted 1px @outer-border;	
+			border-right: @inner-border;
+			.border-box;
+		}
+	
+		tr:first-child td	{
+			border-top: 1px solid transparent;
+		}
+
+		.dojoxCalendarToday {
+			background-color: @today-color;
+		}
+		
+		tr td.last-child	{
+			border-right: @outer-border;
+		}
+		
+		.tr:first-child td.dojoxCalendarToday	{
+			border-top: 1px solid @today-color;
+		}
+		
+		.dojoxCalendarWeekend {
+			background-color: @week-end-color;
+		}
+		
+		tr:first-child td.dojoxCalendarWeekend	{
+			border-top: 1px solid @week-end-color;
+		}	
+	}
+
+	 
+	td.hour {
+		border-top: @hour-stroke;
+	}
+
+	td.halfhour{
+		border-top: @half-hour-stroke;	
+	}
+
+	td.quarterhour{
+		border-top: @quarter-hour-stroke;
+	}
+
+	span.hour {
+		color: @label-color;
+		background-color: @row-color;
+	}
+
+	span.halfhour,
+	span.quarterhour{
+		color: @secondary-label-color;
+		background-color: @row-color;
+	}
+
+	.dojoxCalendarContainer {
+		position: absolute;
+		top: 0;
+		left: @row-header-width;
+		right: 0;
+		cursor: default;
+	}
+
+	.dojoxCalendarContainerTable {
+		border-collapse: collapse;
+		table-layout: fixed;
+		width: 100%;
+		position: relative;
+		margin: 0;
+		padding: 0;
+	
+		td {
+			height: 100%;
+			padding: 0;
+			vertical-align: top;
+		}
+	}
+
+	.dojoxCalendarContainerColumn {
+		position:	relative;
+		margin-left: 2px;
+		margin-right: 9px;
+	}
+
+	.dojoxCalendarEventContainer {
+		position: absolute;
+		overflow: hidden;
+		.select-none;
+	}
+
+	.dojoxCalendarYearColumnHeader{
+		position: absolute;
+		height: @column-header-height - 1px;
+		left: 0;
+		width: @row-header-width - 2px;
+		top: 0;	
+		border-left: @outer-border;
+		border-top: @outer-border;
+		border-right: @outer-border;	
+	
+		table {
+			position:relative;
+			width:100%;
+			height:100%;	
+		}
+		
+		table td {
+			text-align: center;
+			vertical-align: middle;
+			border-bottom: @outer-border;	
+			color: @label-color;
+			.header-background;
+		}
+	}
+
+	.dojoxCalendarColumnHeader {
+		position: absolute;
+		height: @column-header-height;	 
+		left: @row-header-width;
+		right: 0;
+		top: 0;
+		cursor: default;
+	}
+
+	.dojoxCalendarColumnHeaderTable {
+		border-collapse: collapse;
+		table-layout: fixed;
+		position: relative;
+		margin: 0;
+		padding: 0;			
+		width: 100%;
+		height: 100%;	
+
+		td {	
+			overflow:hidden;
+			white-space: nowrap;
+			vertical-align: middle;
+			text-align: center;
+			.header-background;
+			border-right: @inner-border;
+			border-top: @outer-border;
+			border-bottom: @outer-border;
+			.select-none;
+			color: @label-color;
+			.transition-duration(0.2s);
+		}
+		
+		td.last-child {	
+			border-right: @outer-border;	
+		}
+		
+		.dojoxCalendarToday {
+			font-weight: bold;
+			color: @today-label-color;
+		}
+		
+		.dojoxCalendarWeekend {
+			color: @week-end-label-color;
+		}
+		
+		td.Hover{	
+			cursor: pointer;		
+			.header-hover-background;
+		}
+		
+		td.Active{	
+			.header-active-background;
+		}
+	}
+
+	.dojoxCalendarRowHeader {
+		position: absolute;
+		width: @row-header-width - 2px;
+		cursor: default;
+		border-left: @outer-border;
+		border-right: @outer-border;
+		height: 100%;
+		.select-none;
+	}
+
+	.dojoxCalendarRowHeaderLabelContainer{
+		width: 100%;
+		height: 100%;
+		z-index: 10;
+	}
+
+	.dojoxCalendarRowHeaderLabel{	
+		right: 4px;		
+		position: absolute;	
+	}
+
+	.dojoxCalendarRowHeaderTable {
+		border-collapse: collapse;
+		table-layout: fixed;
+		position: relative;
+		margin: 0;
+		padding: 0;
+		width: 100%;
+		height: 100%;
+	
+		td.dummy{
+			border-top: 1px solid @row-color;
+		}
+		
+		td {
+			background-color: @row-color;
+			color: @label-color;
+			.border-box;
+		}
+		
+		tr:first-child td	{
+			border-top: 1px solid @row-color;
+		}
+	}
+ 
+	.dojoxCalendarEvent {
+		position: absolute;	
+		text-align: left;
+		color: #FFF;
+		cursor: default;
+		overflow: hidden;
+	
+		.bg {
+			position: absolute;
+			left: 0;
+			right: 0;
+			top: 0;
+			bottom: 0;
+			z-index: -1;
+			border: @event-border;
+			.rounded-corners;
+			background-color: @event-bg-color;
+			.opacity(90);
+		}
+				
+		.endTime {
+			position: absolute;		
+			font-weight: bold;	
+			bottom:3px;
+			left: 6px;
+			white-space:nowrap;
+		}
+
+		.beforeIcon {
+			text-align: center;
+		}
+
+		.afterIcon {
+			position: absolute;
+			bottom: 2px;
+			width: 100%;
+			text-align: center;
+		}
+
+		.handle {
+			.glass-view;
+		}
+
+		.moveHandle {
+			position: absolute;
+			top:0;
+			width:100%;
+			bottom:0;
+			cursor:move;	
+		}
+
+		.resizeStartHandle {
+			position: absolute;
+			top:0;
+			width:100%;
+			height:10px;
+			cursor:n-resize;	
+		}
+
+		.resizeEndHandle {
+			position: absolute;
+			bottom:0;
+			width:100%;
+			height:10px;
+			cursor:n-resize;	
+		}
+
+		dl {
+			margin: 0;
+		}
+
+		dd {
+			margin: 0;
+			padding: 0 3px;
+			text-align: left;
+		}
+	}
+
+	.dojoxCalendarEvent.Hovered .bg {
+		background-color: @event-hovered-bg-color;	
+	}
+
+	.dojoxCalendarEvent.Selected .bg {
+		background-color: @event-selected-bg-color;
+	}
+
+	.dojoxCalendarEvent.Edited .bg {
+		border: @event-border-focused;
+		.opacity(70);
+	}
+
+	.dojoxCalendarEvent.Focused .bg {
+		border: @event-border-focused;
+	}
+	
+	.dojoxCalendarEvent .startTime {
+		.event-header();		
+	}
+
+	.dojoxCalendarEvent.Focused .startTime {
+		.top-left-right-border(@event-border-focused);
+	}
+
+	.dojoxCalendarEvent.Hovered .startTime {
+		background-color: @event-header-hovered-bg-color;
+	}
+
+	.dojoxCalendarEvent.Selected .startTime {
+		background-color: @event-header-selected-bg-color;
+	}
+
+	.dojoxCalendarEvent.Edited .startTime {
+		background-color: @event-header-bg-color;
+		.top-left-right-border(@event-border-focused);
+	}
+
+	.dojoxCalendarVScrollBar {
+		position: absolute;
+		top: @sheet-top;
+		bottom: 0;
+		overflow-y: scroll;
+		overflow-x: hidden;
+	}
+
+	.dojoxCalendarMatrixView {	
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: @column-header-height;
+		height: @secondary-sheet-height;
+	
+
+		.dojoxCalendarGrid {	
+			position: absolute;
+			left: @row-header-width;
+			right: 0;
+			top: 0;
+			bottom: 0;
+			.border-box;
+		}
+		
+		.dojoxCalendarContainer {	
+			position: absolute;
+			top: 0;
+			left: @row-header-width;
+			right: 0;
+			bottom: 0;
+			cursor: default;
+		}
+		
+		.dojoxCalendarRowHeader {
+			position: absolute;
+			left: 0;				
+			top: 0;
+			width: @row-header-width;
+			bottom: 0;
+			
+			border-right: none;
+			border-left: none;
+			.border-box;
+		}
+		
+		.dojoxCalendarGridTable{
+			
+			td {
+				text-align: right;
+				vertical-align: top;	
+				border-top: @inner-border;
+				border-bottom: @inner-border;
+				border-right: @inner-border;
+				.border-box;
+			}
+			
+			tr.last-child td	{
+				border-bottom: @outer-border;
+			}
+			
+			td.last-child	{
+				border-right: @outer-border;
+			}
+			
+		}
+		
+		.dojoxCalendarRowHeaderTable td {
+			border-top: @inner-border;
+			border-left: @outer-border;
+			border-right: @outer-border;
+			border-bottom: @outer-border;
+			background-color: @row-color;
+		}
+		
+		.dojoxCalendarEvent {
+			.handle {
+				.glass-view;
+				position: absolute;
+				width:5px;
+				height:100%;
+				cursor:e-resize;	
+			}
+			
+			.moveHandle {
+				left:0;
+				top:0;
+				width:100%;
+				cursor:move;	
+			}
+
+			.resizeEndHandle {
+				right:0px;
+			}
+			
+			.afterIcon {
+				width:auto;
+			}
+			
+			.endTime {
+				position: relative;				
+				bottom:auto;
+				left: auto;
+			}
+		}
+		
+		.dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+			position: absolute;
+			left: 3px;
+			right: 1px;
+			bottom: 2px;
+			overflow: hidden;
+		}
+		
+		.dojoxCalendarExpand {
+			position: absolute;
+			text-align: center;
+			
+			.bg {
+				position: relative;
+				margin-right: 10%;
+				margin-left: 10%;
+				border-radius: 5px;
+				height: 100%;
+				.select-none;
+				border: 1px solid transparent;
+				-moz-border-radius: 5px;
+				-webkit-transition-duration: 0.2s;
+				-moz-transition-duration: 0.2s;
+				transition-duration: 0.2s;			
+			}	
+		}
+		
+		.dojoxCalendarExpand.Up .bg {
+			background-color: @expand-up-color;
+			border: 1px solid @expand-up-color - #555;
+		}
+		
+		.dojoxCalendarExpand.Down .bg {
+			background-color: @expand-down-color;
+			border: 1px solid @expand-down-color - #555;
+		}
+		
+		.dojoxCalendarEvent div {
+			white-space:nowrap;
+		}
+	}
+	
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/claro/ColumnViewCommon.less b/dojox/calendar/themes/claro/ColumnViewCommon.less
new file mode 100644
index 0000000..b397fb3
--- /dev/null
+++ b/dojox/calendar/themes/claro/ColumnViewCommon.less
@@ -0,0 +1,10 @@
+ at import "Common.less";
+
+ at hour-stroke: 1px solid #C7BEBE;
+ at half-hour-stroke: dotted 1px #C7BEBE;
+ at quarter-hour-stroke: dotted 1px #C7BEBE;
+
+ at column-header-height: 30px;
+ at row-header-width: 70px;
+ at secondary-sheet-height: 39px;
+ at sheet-top: @secondary-sheet-height + @column-header-height + 3px;
diff --git a/dojox/calendar/themes/claro/ColumnView_rtl.css b/dojox/calendar/themes/claro/ColumnView_rtl.css
new file mode 100644
index 0000000..25313a9
--- /dev/null
+++ b/dojox/calendar/themes/claro/ColumnView_rtl.css
@@ -0,0 +1,117 @@
+.event-header {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #6c0000;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: 1px solid #260000;
+  border-left: 1px solid #260000;
+  border-right: 1px solid #260000;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarScrollContainer {
+  border-left: none;
+  border-right: none;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarGrid {
+  left: 0;
+  right: 70px;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarGridTable td {
+  border-left: 1px solid #b5bcc7;
+  border-right: none;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarContainer {
+  left: 0;
+  right: 70px;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarContainerColumn {
+  margin-right: 1px;
+  margin-left: 9px;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarYearColumnHeader {
+  right: 0;
+  width: 68px;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeader {
+  left: 0;
+  right: 70px;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #b5bcc7;
+  border-right: none;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarRowHeaderLabel {
+  right: auto;
+  left: 4px;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .summary {
+  text-align: right;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .startTime {
+  text-align: right;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .endTime {
+  text-align: right;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarVScrollBar {
+  margin-left: -1px;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+  right: 70px;
+  left: 0;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {
+  text-align: left;
+  border-bottom: 1px solid #cccccc;
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span {
+  padding-left: 2px;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child {
+  border-left: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+  right: 70px;
+  left: 0;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  text-align: right;
+  vertical-align: top;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+  right: 70px;
+  left: 0;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #b5bcc7;
+  border-right: none;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+  right: 0;
+  left: auto;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+  right: 0;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+  left: 0;
+  right: auto;
+}
+.claro .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  text-align: right;
+  right: 2px;
+}
diff --git a/dojox/calendar/themes/claro/ColumnView_rtl.less b/dojox/calendar/themes/claro/ColumnView_rtl.less
new file mode 100644
index 0000000..f4a2f17
--- /dev/null
+++ b/dojox/calendar/themes/claro/ColumnView_rtl.less
@@ -0,0 +1,134 @@
+ at import "ColumnViewCommon.less";
+
+.claro .dojoxCalendarColumnViewRtl {
+	.dojoxCalendarScrollContainer {	
+		border-left: none;
+		border-right: none;
+	}
+	
+	.dojoxCalendarGrid {
+		left: 0;
+		right: @row-header-width;
+	}
+	
+	.dojoxCalendarGridTable td {
+		border-left: @outer-border;
+		border-right: none;
+	}
+	
+	.dojoxCalendarContainer {	
+		left: 0;
+		right: @row-header-width;
+	}
+	
+	.dojoxCalendarContainerColumn {
+		margin-right: 1px;
+		margin-left: 9px;
+	}
+	
+	.dojoxCalendarYearColumnHeader{
+		right: 0;
+		width: @row-header-width - 2;
+	}
+	
+	.dojoxCalendarColumnHeader {
+		left: 0;
+		right: @row-header-width;
+	}
+	
+	.dojoxCalendarColumnHeaderTable td {	
+		border-left: @outer-border;
+		border-right: none;
+	}
+	
+	.dojoxCalendarRowHeaderLabel{	
+		right: auto;		
+		left: 4px;
+	}
+	
+	.dojoxCalendarEvent .summary {
+		text-align: right;
+	}
+	
+	.dojoxCalendarEvent .startTime {
+		text-align: right;
+	}
+	
+	.dojoxCalendarEvent .endTime {
+		text-align: right;
+	}
+	
+	.dojoxCalendarVScrollBar { 	
+		margin-left: -1px;
+	}
+	
+	.dojoxCalendarMatrixViewRtl {
+	
+		.dojoxCalendarGrid {
+			right: @row-header-width;
+			left: 0;
+		}
+		
+		 .dojoxCalendarGridTable td {			
+			text-align: left;
+			border-bottom: @inner-border;
+			border-left: @inner-border;
+			border-right: none;
+		}
+		
+		 .dojoxCalendarGridTable td span{
+			padding-left: 2px;
+		}
+		
+		 .dojoxCalendarGridTable td.last-child	{
+			border-left: @outer-border;
+		}
+		
+		 .dojoxCalendarContainer {
+			right: @row-header-width;
+			left: 0;
+		}
+		
+		 .dojoxCalendarContainerTable td {
+			border-bottom: solid 1px transparent;
+			border-right: solid 1px transparent;
+			text-align: right;
+			vertical-align: top;		
+		}
+		
+		 .dojoxCalendarYearColumnHeader{
+			position: absolute;
+			right: 0;
+			left: auto;
+		}
+		
+		 .dojoxCalendarColumnHeader {
+			right: @row-header-width;
+			left: 0;
+		}
+		
+		.dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {	
+			border-left: @outer-border;
+			border-right: none;
+		}
+		
+		 .dojoxCalendarRowHeader {
+			right: 0;
+			left: auto;
+		}
+		
+		 .dojoxCalendarEvent .resizeStartHandle {
+			right: 0;
+		}
+		
+		 .dojoxCalendarEvent .resizeEndHandle {
+			left: 0;
+			right: auto;
+		}
+		
+		 .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+			text-align: right;
+			right: 2px;
+		}
+	}
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/claro/Common.less b/dojox/calendar/themes/claro/Common.less
new file mode 100644
index 0000000..7168248
--- /dev/null
+++ b/dojox/calendar/themes/claro/Common.less
@@ -0,0 +1,111 @@
+ at outer-border: 1px solid #B5BCC7;
+ at inner-border: 1px solid #CCC;
+
+ at row-color:#EFEFEF;
+ at row-color-hover: #E5F2FE;
+ at row-color-active: #A5D1FB;
+
+ at today-color: #FFF0B4;
+ at today-label-color: #FF0000;
+
+ at week-end-color: #E5F2FE;
+ at week-end-label-color:#759DC0;
+
+ at expand-up-color: #E5F2FE;
+ at expand-down-color: #A5D1FB;
+
+ at label-color: #000;
+ at secondary-label-color: #555;
+
+ at event-border: 1px solid #260000;
+ at event-border-focused: dashed 1px #FFFFFF;
+
+ at event-bg-color: #9F0000;
+ at event-selected-bg-color: #660000;
+ at event-hovered-bg-color: #CC0000;
+
+ at event-header-bg-color: @event-bg-color - #330000;
+ at event-header-selected-bg-color: @event-selected-bg-color - #330000;
+ at event-header-hovered-bg-color: @event-hovered-bg-color  - #330000;
+
+.border-box(){
+	-webkit-box-sizing: border-box;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.opacity(@op){
+	filter: ~"alpha(opacity=@{op})";
+	opacity:@op/100;	
+}
+
+.transition-duration(@dur: 0s){
+	-webkit-transition-duration: @dur;
+	-moz-transition-duration: @dur;
+	transition-duration: @dur;
+}
+
+.select-none() {
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	khtml-user-select: none;
+	user-select: none;
+}
+
+.glass-view(){
+	z-index: 2;	
+	background-color: #F00;	
+	.opacity(0);
+	.select-none;
+}
+
+.header-background(){
+	background-color: #efefef;
+	background-image: url("images/titlebar.png");
+	background-repeat: repeat-x;
+}
+
+.header-hover-background(){
+	background-image: url("images/titlebar.png");
+  	background-repeat: repeat-x;  	
+	background-color: #abd6ff;
+  	border-color: #769dc0;
+}
+
+.header-active-background(){
+	cursor: pointer;		
+	background-color: #7dbefa;
+	border-color: #769dc0;
+	background-position: 0 -136px;
+	.transition-duration(0s);
+}
+
+.rounded-corners (@radius: 5px) {
+  border-radius: @radius;
+  -webkit-border-radius: @radius;
+  -moz-border-radius: @radius;
+}
+
+.top-rounded-corners (@radius: 5px) {
+  border-top-left-radius: @radius;
+  border-top-right-radius: @radius;
+  -webkit-border-top-left-radius: @radius;
+  -webkit-border-top-right-radius: @radius;
+  -moz-border-top-right-radius: @radius;
+  -moz-border-top-left-radius: @radius;
+}
+
+.top-left-right-border(@style){
+	border-top: @style;
+	border-left: @style;
+	border-right: @style;
+}
+
+.event-header{
+	font-weight: bold;	
+	.top-rounded-corners;
+	background-color: @event-header-bg-color;
+	white-space: nowrap;
+	padding: 1px 2px 2px 1px;	
+	.top-left-right-border(@event-border);
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/claro/MatrixView.css b/dojox/calendar/themes/claro/MatrixView.css
new file mode 100644
index 0000000..356c8d2
--- /dev/null
+++ b/dojox/calendar/themes/claro/MatrixView.css
@@ -0,0 +1,376 @@
+.event-header {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #6c0000;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: 1px solid #260000;
+  border-left: 1px solid #260000;
+  border-right: 1px solid #260000;
+}
+.claro .dojoxCalendarMatrixView {
+  cursor: default;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarGrid {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 30px;
+  bottom: 0px;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarGridTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+  /* 
+		 * The dojoxCalendarColToday & dojoxCalendarColWeekend classes is added by the 
+		 * MatrixView.styleGridCell method that can be subclassed to add/remove css classes
+		 */
+
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarGridTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+  text-align: right;
+  vertical-align: top;
+  border-bottom: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarGridTable td span {
+  padding-right: 2px;
+  padding-top: 2px;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td {
+  border-bottom: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child {
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarGridTable td.dojoxCalendarToday {
+  background-color: #fff0b4;
+  font-weight: bold;
+  color: #ff0000;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #e5f2fe;
+  color: #759dc0;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarDayDisabled {
+  background-color: #e5f2fe;
+  color: #759dc0;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  left: 0px;
+  top: 0px;
+  width: 50px;
+  height: 29px;
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid #b5bcc7;
+  border-top: 1px solid #b5bcc7;
+  border-right: 1px solid #b5bcc7;
+  background-color: #efefef;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+  color: #000000;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarColumnHeader {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 0px;
+  height: 29px;
+  cursor: default;
+  border-bottom: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+  /* 
+		 * The dojoxCalendarColWeekend class is added by the 
+		 * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css class.
+		 */
+
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  vertical-align: middle;
+  text-align: center;
+  background-color: #efefef;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+  border-right: 1px solid #cccccc;
+  border-top: 1px solid #b5bcc7;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #000000;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #759dc0;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+  position: absolute;
+  left: 0px;
+  top: 30px;
+  width: 50px;
+  bottom: 0;
+  cursor: default;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  border-collapse: collapse;
+  table-layout: fixed;
+  margin: 0;
+  padding: 0;
+  /* 
+		 * The MatrixView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+		 */
+
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid #b5bcc7;
+  border-right: 1px solid #b5bcc7;
+  border-bottom: 1px solid #cccccc;
+  background-color: #efefef;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  color: #000000;
+  cursor: pointer;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.last-child {
+  border-bottom: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Hover {
+  background-color: #e5f2fe;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Active {
+  background-color: #a5d1fb;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarContainer {
+  position: absolute;
+  top: 30px;
+  left: 50px;
+  right: 0px;
+  bottom: 0px;
+  cursor: default;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarContainerTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarContainerTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarContainerTable td {
+  vertical-align: top;
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarContainerTable td div.dojoxCalendarContainerRow {
+  position: relative;
+  height: 100%;
+  width: 100%;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #000;
+  cursor: default;
+  white-space: nowrap;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal {
+  color: #FFF;
+  position: absolute;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .bg {
+  border: 1px solid #260000;
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  color: #000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9f0000;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Hovered .bg {
+  background-color: #cc0000;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Selected .bg {
+  background-color: #660000;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.Edited {
+  color: #FFF;
+  font-weight: bold;
+  text-decoration: none;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .bg {
+  border: dashed 1px #FFF;
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Focused .bg {
+  border: dashed 1px #FFF;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Hovered {
+  color: #F40;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Selected {
+  color: #F00;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Edited {
+  border: dashed 1px #FFF;
+  background: #600;
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+  color: #FFF;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Focused {
+  border: dashed 1px #000;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  position: absolute;
+  left: 3px;
+  right: 1px;
+  bottom: 2px;
+  overflow: hidden;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+  position: absolute;
+  left: 2px;
+  right: 2px;
+  bottom: 0;
+  overflow: hidden;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background-color: #F00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  position: absolute;
+  width: 5px;
+  height: 100%;
+  cursor: e-resize;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+  left: 0;
+  top: 0;
+  width: 100%;
+  cursor: move;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+  right: 0px;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarExpand {
+  position: absolute;
+  text-align: center;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarExpand span {
+  display: inline-block;
+  vertical-align: middle;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+  position: relative;
+  margin-right: 5px;
+  margin-left: 5px;
+  height: 100%;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  border: 1px solid transparent;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+  background-color: #e5f2fe;
+  border: 1px solid #909da9;
+}
+.claro .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+  background-color: #a5d1fb;
+  border: 1px solid #507ca6;
+}
diff --git a/dojox/calendar/themes/claro/MatrixView.less b/dojox/calendar/themes/claro/MatrixView.less
new file mode 100644
index 0000000..ececfbb
--- /dev/null
+++ b/dojox/calendar/themes/claro/MatrixView.less
@@ -0,0 +1,374 @@
+ at import "MatrixViewCommon.less";
+
+.claro .dojoxCalendarMatrixView {
+	cursor: default;
+	.select-none;
+
+	.dojoxCalendarGrid {
+		position: absolute;
+		left: @row-header-width;
+		right: 0px;
+		top: @column-header-height;
+		bottom: 0px;
+	}
+	
+	.dojoxCalendarGridTable {
+		position: relative;
+		width: 100%;
+		height: 100%;	
+		margin: 0;
+		padding: 0;
+		border-collapse: collapse;
+		table-layout: fixed;
+	
+		tr{
+			.border-box;
+		}
+		
+		td {
+			text-align: right;
+			vertical-align: top;	
+			border-bottom: @inner-border;
+			border-right: @inner-border;
+			.border-box;
+		}
+		
+		td span{
+			padding-right: 2px;
+			padding-top: 2px;		
+		}
+		
+		td span.FirstVisibleDayOfMonth{	
+		}
+		
+		tr.last-child td	{
+			border-bottom: @outer-border;
+		}
+		
+		td.last-child	{
+			border-right: @outer-border;
+		}
+		
+		/* 
+		 * The dojoxCalendarColToday & dojoxCalendarColWeekend classes is added by the 
+		 * MatrixView.styleGridCell method that can be subclassed to add/remove css classes
+		 */
+		td.dojoxCalendarToday	{
+			background-color: @today-color;		
+			font-weight: bold;
+			color: @today-label-color;
+		}
+					
+		.dojoxCalendarWeekend {
+			background-color: @week-end-color;
+			color: @week-end-label-color;
+		}
+		
+		.dojoxCalendarDayDisabled {
+			background-color: @disabled-day-color;
+			color: @disabled-day-label-color;
+		}
+	}
+	
+	.dojoxCalendarYearColumnHeader{
+		position: absolute;
+		left: 0px;
+		top: 0px;
+		width: @row-header-width;
+		height: @column-header-height - 1px;
+		text-align: center;
+		vertical-align: middle;
+		border-bottom: @outer-border;
+		
+		table{
+			position: relative;		
+			width:100%;
+			height: 100%;
+			table-layout: fixed;
+			border-collapse: collapse;			
+			
+			td{
+				text-align: center;
+				vertical-align: middle;		
+				border-left: @outer-border;
+				border-top: @outer-border;
+				border-right: @outer-border;
+				.header-background;
+				color: @label-color;
+			}
+		}
+	}
+	
+	.dojoxCalendarColumnHeader {
+		position: absolute;
+		left: @row-header-width;
+		right: 0px;
+		top: 0px;
+		height: @column-header-height - 1px;
+		cursor: default;
+		border-bottom: @outer-border;	
+	}
+	
+	.dojoxCalendarColumnHeaderTable {
+		position: relative;		
+		width:100%;
+		height: 100%;
+		table-layout: fixed;
+		border-collapse: collapse;		
+	
+		td {
+			overflow:hidden;
+			vertical-align: middle;
+			text-align: center;
+			.header-background;
+			border-right: @inner-border;
+			border-top: @outer-border;
+			.select-none;
+			color: @label-color;
+		}
+		
+		td.last-child {
+			border-right: @outer-border;
+		}
+		
+		/* 
+		 * The dojoxCalendarColWeekend class is added by the 
+		 * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css class.
+		 */
+		.dojoxCalendarWeekend {
+			color: @week-end-label-color;
+		}
+	}
+	
+	.dojoxCalendarRowHeader {
+		position: absolute;
+		left: 0px;				
+		top: @column-header-height;
+		width: @row-header-width;
+		bottom: 0;
+		cursor: default;
+		
+		.select-none;
+	}
+	
+	.dojoxCalendarRowHeaderTable {
+		position: relative;			
+		width: 100%;
+		height: 100%;
+		border-collapse: collapse;
+		table-layout: fixed;
+		margin: 0;
+		padding: 0;
+	
+		tr{
+			.border-box;
+		}
+		
+		/* 
+		 * The MatrixView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+		 */
+		td {
+			text-align: center;
+			vertical-align: middle;	
+			border-left: @outer-border;
+			border-right: @outer-border;
+			border-bottom: @inner-border;
+			background-color: @row-color;
+			.transition-duration(0.2s);
+			.border-box;
+			color: @label-color;
+			cursor: pointer;
+		}
+		
+		td.last-child {
+			border-bottom: @outer-border;
+		}
+		
+		td.Hover {
+			background-color: @row-color-hover;
+		}
+		
+		td.Active {
+			background-color: @row-color-active;
+		}
+	}
+	
+	.dojoxCalendarContainer {
+		position: absolute;
+		top: @column-header-height;
+		left: @row-header-width;
+		right: 0px;
+		bottom: 0px;
+		cursor: default;
+	}
+	
+	.dojoxCalendarContainerTable {
+		position: relative;
+		width: 100%;
+		height: 100%;	
+		margin: 0;
+		padding: 0;
+		border-collapse: collapse;
+		table-layout: fixed;	
+		
+		tr{
+			.border-box;
+		}
+		
+		td{
+			vertical-align: top;
+			border-bottom: solid 1px transparent;
+			border-right: solid 1px transparent;
+			.border-box;
+		}
+		
+		td div.dojoxCalendarContainerRow{
+			position:relative;
+			height:100%;
+			width:100%;
+		}
+	}
+	
+	.dojoxCalendarEventContainer {
+		position: absolute;
+		overflow: hidden;
+	 	.select-none;
+	}
+	
+	.dojoxCalendarEvent {	
+		position: absolute;
+		text-align: left;
+		color: #000;
+		cursor: default;
+		white-space: nowrap;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarHorizontal {
+		color: #FFF;
+		position: absolute;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarHorizontal .bg {
+		border: @horizontal-border;	
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		bottom: 0;	
+		color: #000;	
+		.rounded-corners(5px);
+		background-color: @horizontal-color;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarHorizontal.Hovered  .bg {
+		background-color: @horizontal-hover-color;	
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarHorizontal.Selected .bg {
+		background-color: @horizontal-selected-bg-color;
+	}
+	
+	.dojoxCalendarEvent.Edited {
+		color: #FFF;
+		font-weight: bold;
+		text-decoration: none;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .bg {
+		border: dashed 1px #FFF;
+		.opacity(30);
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarHorizontal.Focused .bg {
+		border: dashed 1px #FFF;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarLabel.Hovered {
+		color: #F40;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarLabel.Selected {
+		color: #F00;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarLabel.Edited {
+		border: dashed 1px #FFF;
+		background: #600;
+		.opacity(30);
+		color: #FFF;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarLabel.Focused {
+		border: dashed 1px #000;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+		position: absolute;
+		left: 3px;
+		right: 1px;
+		bottom: 2px;
+		overflow: hidden;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarLabel .labels {
+		position: absolute;
+		left: 2px;
+		right: 2px;
+		bottom: 0;
+		overflow: hidden;
+	}
+	
+	.dojoxCalendarEvent .handle {
+		.glass-view;
+		position: absolute;
+		width:5px;
+		height:100%;
+		cursor:e-resize;	
+	}
+	
+	.dojoxCalendarEvent .moveHandle {
+		left:0;
+		top:0;
+		width:100%;
+		cursor:move;	
+	}
+	
+	.dojoxCalendarEvent .resizeStartHandle {
+	}
+	
+	.dojoxCalendarEvent .resizeEndHandle {
+		right:0px;
+	}
+	
+	.dojoxCalendarExpand {
+		position: absolute;
+		text-align: center;
+	
+		span {
+			display: inline-block;
+			vertical-align: middle;
+			}
+		
+		.bg {
+			position: relative;
+			margin-right: 5px;
+			margin-left: 5px;
+			height: 100%;
+			.rounded-corners(5px);
+			.transition-duration(0.2s);
+			.border-box;	
+			border: 1px solid transparent;
+		}
+	}
+		
+	.dojoxCalendarExpand.Up .bg {
+		background-color: @expand-up-color;
+		border: 1px solid @expand-up-color - #555;
+	}
+	
+	.dojoxCalendarExpand.Down .bg {
+		background-color: @expand-down-color;
+		border: 1px solid @expand-down-color - #555;
+	}
+
+}
diff --git a/dojox/calendar/themes/claro/MatrixViewCommon.less b/dojox/calendar/themes/claro/MatrixViewCommon.less
new file mode 100644
index 0000000..7022021
--- /dev/null
+++ b/dojox/calendar/themes/claro/MatrixViewCommon.less
@@ -0,0 +1,12 @@
+ at import "Common.less";
+
+ at disabled-day-color: #E5F2FE;
+ at disabled-day-label-color:#759DC0;
+
+ at horizontal-color: #9F0000;
+ at horizontal-hover-color: #CC0000;
+ at horizontal-selected-bg-color: #660000;
+ at horizontal-border: 1px solid #260000;
+
+ at column-header-height: 30px;
+ at row-header-width: 50px;
diff --git a/dojox/calendar/themes/claro/MatrixView_rtl.css b/dojox/calendar/themes/claro/MatrixView_rtl.css
new file mode 100644
index 0000000..1524a3f
--- /dev/null
+++ b/dojox/calendar/themes/claro/MatrixView_rtl.css
@@ -0,0 +1,71 @@
+.event-header {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #6c0000;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: 1px solid #260000;
+  border-left: 1px solid #260000;
+  border-right: 1px solid #260000;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+  right: 50px;
+  left: 0;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {
+  text-align: left;
+  border-bottom: 1px solid #cccccc;
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span {
+  padding-left: 2px;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child {
+  border-left: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+  right: 50px;
+  left: 0;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  text-align: right;
+  vertical-align: top;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+  right: 50px;
+  left: 0;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #b5bcc7;
+  border-right: none;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+  right: 0;
+  left: auto;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  text-align: right;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+  text-align: right;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+  right: 0;
+}
+.claro .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+  left: 0;
+  right: auto;
+}
diff --git a/dojox/calendar/themes/claro/MatrixView_rtl.less b/dojox/calendar/themes/claro/MatrixView_rtl.less
new file mode 100644
index 0000000..3045088
--- /dev/null
+++ b/dojox/calendar/themes/claro/MatrixView_rtl.less
@@ -0,0 +1,75 @@
+ at import "MatrixViewCommon.less";
+
+.claro .dojoxCalendarMatrixViewRtl { 
+
+	.dojoxCalendarGrid {
+		right: @row-header-width;
+		left: 0;
+	}
+	
+	.dojoxCalendarGridTable td {			
+		text-align: left;
+		border-bottom: @inner-border;
+		border-left: @inner-border;
+		border-right: none;
+	}
+	
+	.dojoxCalendarGridTable td span{
+		padding-left: 2px;
+	}
+	
+	.dojoxCalendarGridTable td.last-child	{
+		border-left: @outer-border;
+	}
+	
+	.dojoxCalendarContainer {
+		right: @row-header-width;
+		left: 0;
+	}
+	
+	.dojoxCalendarContainerTable td {
+		border-bottom: solid 1px transparent;
+		border-right: solid 1px transparent;
+		text-align: right;
+		vertical-align: top;		
+	}
+	
+	.dojoxCalendarYearColumnHeader{
+		position: absolute;
+		right: 0;
+		left: auto;
+	}
+	
+	.dojoxCalendarColumnHeader {
+		right: @row-header-width;
+		left: 0;
+	}
+	
+	.dojoxCalendarColumnHeaderTable td {	
+		border-left: @outer-border;
+		border-right: none;
+	}
+	
+	.dojoxCalendarRowHeader {
+		right: 0;
+		left: auto;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+		text-align: right;
+	}
+	
+	.dojoxCalendarEvent.dojoxCalendarLabel .labels {
+		text-align: right;
+	}
+	
+	.dojoxCalendarEvent .resizeStartHandle {
+		right: 0;
+	}
+	
+	.dojoxCalendarEvent .resizeEndHandle {
+		left:0;
+		right:auto;
+	}
+
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/claro/MonthColumnView.css b/dojox/calendar/themes/claro/MonthColumnView.css
new file mode 100644
index 0000000..c5cb42f
--- /dev/null
+++ b/dojox/calendar/themes/claro/MonthColumnView.css
@@ -0,0 +1,283 @@
+.event-header {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #6c0000;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: 1px solid #260000;
+  border-left: 1px solid #260000;
+  border-right: 1px solid #260000;
+}
+.claro .dojoxCalendarMonthColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 30px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-bottom: 1px solid #b5bcc7;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGrid {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  /* 
+		 * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+		 * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+		 */
+
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td span {
+  padding-left: 3px;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff0b4;
+  font-weight: bold;
+  color: #ff0000;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarHiddenEvents {
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents {
+  background: #fff0b4 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.first-child {
+  border-left: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff0b4;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #e5f2fe;
+  color: #759dc0;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #e5f2fe;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  cursor: default;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 35px;
+  margin-right: 5px;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 0;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background-color: #efefef;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+  border-right: 1px solid #cccccc;
+  border-top: 1px solid #b5bcc7;
+  border-bottom: 1px solid #b5bcc7;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #000000;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.first-child {
+  border-left: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+  background-color: #abd6ff;
+  border-color: #769dc0;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+  background-color: #7dbefa;
+  border-color: #769dc0;
+  background-position: 0 -136px;
+  -webkit-transition-duration: 0s;
+  -moz-transition-duration: 0s;
+  transition-duration: 0s;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+  overflow: hidden;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9f0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background-color: #F00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.claro .dojoxCalendarMonthColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 30px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/claro/MonthColumnView.less b/dojox/calendar/themes/claro/MonthColumnView.less
new file mode 100644
index 0000000..b59e0a8
--- /dev/null
+++ b/dojox/calendar/themes/claro/MonthColumnView.less
@@ -0,0 +1,282 @@
+ at import "ColumnViewCommon.less";
+
+.claro .dojoxCalendarMonthColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+
+	.dojoxCalendarScrollContainer {
+		left: 0;
+		right: 0;
+		bottom: 0;
+		top: @column-header-height;
+		position: absolute;
+		overflow-y: hidden;
+		overflow-x: hidden;	
+		border-bottom: @outer-border;
+		.border-box;
+	}
+		
+	.dojoxCalendarGrid {
+		position: absolute;
+		top: 0;
+		left: 0;
+		right: 0;
+	}
+	
+	.dojoxCalendarGridTable {
+		border-collapse: collapse;
+		table-layout: fixed;
+		width: 100%;
+		position: relative;
+		margin: 0;
+		padding: 0;
+	
+	
+		td {
+			border-top: dotted 1px #B5BCC7;	
+			border-right: @inner-border;
+			.border-box;
+		}
+		
+		td span {
+		  padding-left:3px;
+		}
+		
+		tr:first-child td	{
+			border-top: 1px solid transparent;
+		}
+		
+		/* 
+		 * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+		 * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+		 */
+		.dojoxCalendarToday {
+			background-color: @today-color;
+			font-weight: bold;
+			color: @today-label-color;
+		}
+		
+		.dojoxCalendarHiddenEvents	{	
+			background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;	
+		}
+		
+		.dojoxCalendarToday.dojoxCalendarHiddenEvents	{	
+			background: @today-color url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;	
+		}
+		
+		tr td.last-child	{
+			border-right: @outer-border;
+		}
+		
+		tr td.first-child	{
+			border-left: @outer-border;
+		}
+		
+		
+		tr:first-child td.dojoxCalendarToday	{
+			border-top: 1px solid @today-color;
+		}
+		
+		.dojoxCalendarWeekend {
+			background-color: @week-end-color;
+			color: @week-end-label-color;
+		}
+		
+		tr:first-child td.dojoxCalendarWeekend	{
+			border-top: 1px solid @week-end-color;
+		}
+		
+	}
+	
+	.dojoxCalendarContainer {
+		position: absolute;
+		top: 0;
+		left: 0;
+		right: 0;
+		cursor: default;
+	}
+	
+	.dojoxCalendarContainerTable {
+		border-collapse: collapse;
+		table-layout: fixed;
+		width: 100%;
+		position: relative;
+		margin: 0;
+		padding: 0;
+	}
+	
+	.dojoxCalendarContainerTable td {
+		height: 100%;
+		padding: 0;
+		vertical-align: top;
+	}
+	
+	.dojoxCalendarContainerColumn {
+		position:	relative;
+		margin-left: 35px;
+		margin-right: 5px;
+	}
+	
+	.dojoxCalendarEventContainer {
+		position: absolute;
+		overflow: hidden;
+		.select-none;
+	}
+	
+	.dojoxCalendarColumnHeader {
+		position: absolute;
+		height: @column-header-height;	 
+		left: 0;
+		right: 0;
+		top: 0;
+		cursor: default;
+	}
+	
+	.dojoxCalendarColumnHeaderTable {
+		border-collapse: collapse;
+		table-layout: fixed;
+		position: relative;
+		margin: 0;
+		padding: 0;			
+		width: 100%;
+		height: 100%;	
+	
+		td {	
+			overflow:hidden;
+			white-space: nowrap;
+			vertical-align: middle;
+			text-align: center;
+			.header-background;
+			border-right: @inner-border;
+			border-top: @outer-border;
+			border-bottom: @outer-border;
+			.select-none;
+			color: @label-color;
+			.transition-duration(0.2s);
+		}
+	
+		td.last-child {	
+			border-right: @outer-border;	
+		}
+		
+		td.first-child {	
+			border-left: @outer-border;	
+		}
+		
+		td.Hover{	
+			cursor: pointer;		
+			.header-hover-background;
+		}
+		
+		td.Active{	
+			.header-active-background;
+		}
+	}
+	 
+	.dojoxCalendarEvent {
+		position: absolute;	
+		text-align: left;
+		color: #FFF;
+		cursor: default;
+		overflow: hidden;
+		
+		.bg {
+			position: absolute;
+			left: 0;
+			right: 0;
+			top: 0;
+			bottom: 0;
+			z-index: -1;
+			border: @event-border;
+			.rounded-corners;
+			background-color: @event-bg-color;
+			.opacity(90);
+		}
+	
+		.startTime {
+			font-weight: bold;
+		}
+		
+		.endTime {
+			position: absolute;		
+			font-weight: bold;	
+			bottom:3px;
+			left: 6px;
+		}
+		
+		.beforeIcon {
+			text-align: center;
+		}
+		
+		.afterIcon {
+			position: absolute;
+			bottom: 2px;
+			width: 100%;
+			text-align: center;
+		}
+		
+		.handle {
+			.glass-view;
+		}
+		
+		.moveHandle {
+			position: absolute;
+			top:0;
+			width:100%;
+			bottom:0;
+			cursor:move;	
+		}
+		
+		.resizeStartHandle {
+			position: absolute;
+			top:0;
+			width:100%;
+			height:10px;
+			cursor:n-resize;	
+		}
+		
+		.resizeEndHandle {
+			position: absolute;
+			bottom:0;
+			width:100%;
+			height:10px;
+			cursor:n-resize;	
+		}
+		
+		dl {
+			margin: 0;
+		}
+		
+		dd {
+			margin: 0;
+			padding: 0 3px;
+			text-align: left;
+		}
+	}
+	
+	.dojoxCalendarEvent.Hovered .bg {
+		background-color: #CC0000;	
+	}
+	
+	.dojoxCalendarEvent.Selected .bg {
+		background-color: #660000;
+	}
+	
+	.dojoxCalendarEvent.Edited .bg {
+		border: dashed 1px #FFFFFF;
+		.opacity(70);
+	}
+	
+	.dojoxCalendarEvent.Focused .bg {
+		border: dashed 1px #FFFFFF;
+	}
+	
+	.dojoxCalendarVScrollBar {
+		position: absolute;
+		top: @column-header-height;
+		bottom: 0;
+		overflow-y: scroll;
+		overflow-x: hidden;
+	}
+
+}
diff --git a/dojox/calendar/themes/claro/MonthColumnViewCommon.less b/dojox/calendar/themes/claro/MonthColumnViewCommon.less
new file mode 100644
index 0000000..9bb3ec8
--- /dev/null
+++ b/dojox/calendar/themes/claro/MonthColumnViewCommon.less
@@ -0,0 +1,7 @@
+ at import "Common.less";
+
+ at hour-stroke: 1px solid #C7BEBE;
+ at half-hour-stroke: dotted 1px #C7BEBE;
+ at quarter-hour-stroke: dotted 1px #C7BEBE;
+
+ at column-header-height: 30px;
diff --git a/dojox/calendar/themes/claro/MonthColumnView_rtl.css b/dojox/calendar/themes/claro/MonthColumnView_rtl.css
new file mode 100644
index 0000000..b24b5c3
--- /dev/null
+++ b/dojox/calendar/themes/claro/MonthColumnView_rtl.css
@@ -0,0 +1,58 @@
+.event-header {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #6c0000;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: 1px solid #260000;
+  border-left: 1px solid #260000;
+  border-right: 1px solid #260000;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td {
+  border-right: none;
+  border-left: 1px solid #cccccc;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td span {
+  padding-right: 3px;
+  paddint-left: 0px;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable .dojoxCalendarHiddenEvents {
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents {
+  background: #fff0b4 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.last-child {
+  border-left: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.first-child {
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarContainerColumn {
+  margin-left: 5px;
+  margin-right: 35px;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.last-child {
+  border-left: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.first-child {
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .summary {
+  text-align: right;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .startTime {
+  text-align: right;
+}
+.claro .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .endTime {
+  text-align: right;
+}
diff --git a/dojox/calendar/themes/claro/MonthColumnView_rtl.less b/dojox/calendar/themes/claro/MonthColumnView_rtl.less
new file mode 100644
index 0000000..06669f3
--- /dev/null
+++ b/dojox/calendar/themes/claro/MonthColumnView_rtl.less
@@ -0,0 +1,60 @@
+ at import "ColumnViewCommon.less";
+
+.claro .dojoxCalendarMonthColumnViewRtl {
+	
+	.dojoxCalendarGridTable td {
+		border-right: none;	
+		border-left: @inner-border;
+	}
+	
+	.dojoxCalendarGridTable td span {
+	  padding-right:3px;
+	  paddint-left: 0px;
+	}
+	
+	.dojoxCalendarGridTable .dojoxCalendarHiddenEvents	{
+		background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;	
+	}
+	
+	.claro .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents	{	
+		background: @today-color url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y  right top;	
+	}
+	
+	.dojoxCalendarGridTable tr td.last-child	{
+		border-left: @outer-border;	
+	}
+	
+	.dojoxCalendarGridTable tr td.first-child	{
+		border-right: @outer-border;
+	}
+	
+	.dojoxCalendarContainerColumn {	
+		margin-left: 5px;
+		margin-right: 35px;
+	}
+	
+	.dojoxCalendarColumnHeaderTable td {	
+		border-left: @inner-border;
+		border-right: none;	
+	}
+	
+	.dojoxCalendarColumnHeaderTable td.last-child {	
+		border-left: @outer-border;	
+	}
+	
+	.dojoxCalendarColumnHeaderTable td.first-child {	
+		border-right: @outer-border;	
+	}
+	 
+	.dojoxCalendarEvent .summary {
+		text-align: right;
+	}
+	
+	.dojoxCalendarEvent .startTime {
+		text-align: right;
+	}
+	
+	.dojoxCalendarEvent .endTime {
+		text-align: right;
+	}
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/claro/SimpleColumnView.css b/dojox/calendar/themes/claro/SimpleColumnView.css
new file mode 100644
index 0000000..4cae437
--- /dev/null
+++ b/dojox/calendar/themes/claro/SimpleColumnView.css
@@ -0,0 +1,390 @@
+.event-header {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #6c0000;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: 1px solid #260000;
+  border-left: 1px solid #260000;
+  border-right: 1px solid #260000;
+}
+.claro .dojoxCalendarSimpleColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarHeader {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 29px;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 30px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-top: 1px solid #b5bcc7;
+  border-bottom: 1px solid #b5bcc7;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff0b4;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff0b4;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #e5f2fe;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #e5f2fe;
+}
+.claro .dojoxCalendarSimpleColumnView .claro .dojoxCalendarColumnView td.hour {
+  border-top: 1px solid #c7bebe;
+}
+.claro .dojoxCalendarSimpleColumnView .claro .dojoxCalendarColumnView td.halfhour {
+  border-top: dotted 1px #c7bebe;
+}
+.claro .dojoxCalendarSimpleColumnView .claro .dojoxCalendarColumnView td.quarterhour {
+  border-top: dotted 1px #c7bebe;
+}
+.claro .dojoxCalendarSimpleColumnView .claro .dojoxCalendarColumnView span.hour {
+  color: #000000;
+  background-color: #efefef;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  cursor: default;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 2px;
+  margin-right: 9px;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  height: 29px;
+  left: 0;
+  width: 68px;
+  top: 0;
+  border-left: 1px solid #b5bcc7;
+  border-top: 1px solid #b5bcc7;
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #b5bcc7;
+  color: #000000;
+  background-color: #efefef;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 70px;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background-color: #efefef;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+  border-right: 1px solid #cccccc;
+  border-top: 1px solid #b5bcc7;
+  border-bottom: 1px solid #b5bcc7;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #000000;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #b5bcc7;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+  font-weight: bold;
+  color: #ff0000;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #759dc0;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+  background-color: #abd6ff;
+  border-color: #769dc0;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+  background-color: #7dbefa;
+  border-color: #769dc0;
+  background-position: 0 -136px;
+  -webkit-transition-duration: 0s;
+  -moz-transition-duration: 0s;
+  transition-duration: 0s;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeader {
+  position: absolute;
+  width: 68px;
+  cursor: default;
+  border-left: 1px solid #b5bcc7;
+  border-right: 1px solid #b5bcc7;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderLabelContainer {
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderLabel {
+  right: 4px;
+  position: absolute;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td.dummy {
+  border-top: 1px solid #efefef;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td {
+  vertical-align: top;
+  text-align: right;
+  border-top: 1px solid #b5bcc7;
+  background-color: #efefef;
+  color: #000000;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable tr:first-child td {
+  border-top: 1px solid #efefef;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+  overflow: hidden;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #6c0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+  white-space: nowrap;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background-color: #F00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #cc0000;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #ffffff;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #ffffff;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+  -webkit-border-top-left-radius: 5px;
+  -webkit-border-top-right-radius: 5px;
+  -moz-border-top-right-radius: 5px;
+  -moz-border-top-left-radius: 5px;
+  background-color: #6c0000;
+  white-space: nowrap;
+  padding: 1px 2px 2px 1px;
+  border-top: 1px solid #260000;
+  border-left: 1px solid #260000;
+  border-right: 1px solid #260000;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Focused .startTime {
+  border-top: dashed 1px #ffffff;
+  border-left: dashed 1px #ffffff;
+  border-right: dashed 1px #ffffff;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Hovered .startTime {
+  background-color: #990000;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Selected .startTime {
+  background-color: #330000;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Edited .startTime {
+  background-color: #6c0000;
+  border-top: dashed 1px #ffffff;
+  border-left: dashed 1px #ffffff;
+  border-right: dashed 1px #ffffff;
+}
+.claro .dojoxCalendarSimpleColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 30px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/claro/SimpleColumnView.less b/dojox/calendar/themes/claro/SimpleColumnView.less
new file mode 100644
index 0000000..50d5591
--- /dev/null
+++ b/dojox/calendar/themes/claro/SimpleColumnView.less
@@ -0,0 +1,391 @@
+ at import "ColumnViewCommon.less";
+
+ at row-header-width: 70px;
+ at secondary-sheet-height: 0px;
+ at sheet-top: @column-header-height;
+
+.claro .dojoxCalendarSimpleColumnView {	
+	cursor: default;
+	-webkit-user-select: none;
+
+	.dojoxCalendarHeader {
+		position: absolute;
+		left: 0;
+		right: 0;
+		top: 0;
+		height: @column-header-height - 1px;
+		.border-box;
+	}
+	
+	.dojoxCalendarScrollContainer {
+		left: 0;
+		right: 0;
+		bottom: 0;
+		top: @sheet-top;
+		position: absolute;
+		overflow-y: hidden;
+		overflow-x: hidden;
+		border-top: @outer-border;
+		border-bottom: @outer-border;
+		.border-box;
+	}
+		
+	.dojoxCalendarGrid {
+		position: absolute;
+		left: @row-header-width;
+		right: 0;
+	}
+	
+	.dojoxCalendarGridTable {
+		border-collapse: collapse;
+		table-layout: fixed;
+		width: 100%;
+		position: relative;
+		margin: 0;
+		padding: 0;
+		
+		td {
+			border-top: dotted 1px #B5BCC7;	
+			border-right: @inner-border;
+			.border-box;
+		}
+		
+		tr:first-child td	{
+			border-top: 1px solid transparent;
+		}
+	
+		.dojoxCalendarToday {
+			background-color: @today-color;
+		}
+		
+		tr td.last-child	{
+			border-right: @outer-border;
+		}
+		
+		tr:first-child td.dojoxCalendarToday	{
+			border-top: 1px solid @today-color;
+		}
+		
+		.dojoxCalendarWeekend {
+			background-color: @week-end-color;
+		}
+		
+		tr:first-child td.dojoxCalendarWeekend	{
+			border-top: 1px solid @week-end-color;
+		}
+	
+	}
+	
+	.claro .dojoxCalendarColumnView {
+		td.hour {
+			border-top: @hour-stroke;
+		}
+	
+	
+		td.halfhour{
+			border-top: @half-hour-stroke;	
+		}
+		
+		td.quarterhour{
+			border-top: @quarter-hour-stroke;
+		}
+		
+		span.hour {
+			color: @label-color;
+			background-color: @row-color;
+		}
+	
+	}
+	
+	.dojoxCalendarContainer {
+		position: absolute;
+		top: 0;
+		left: @row-header-width;
+		right: 0;
+		cursor: default;
+	}
+	
+	.dojoxCalendarContainerTable {
+		border-collapse: collapse;
+		table-layout: fixed;
+		width: 100%;
+		position: relative;
+		margin: 0;
+		padding: 0;
+	
+		td {
+			height: 100%;
+			padding: 0;
+			vertical-align: top;
+		}
+	
+	}
+	
+	.dojoxCalendarContainerColumn {
+		position:	relative;
+		margin-left: 2px;
+		margin-right: 9px;
+	}
+	
+	.dojoxCalendarEventContainer {
+		position: absolute;
+		overflow: hidden;
+		.select-none;
+	}
+	
+	.dojoxCalendarYearColumnHeader{
+		position: absolute;
+		height: @column-header-height - 1px;
+		left: 0;
+		width: @row-header-width - 2px;
+		top: 0;	
+		border-left: @outer-border;
+		border-top: @outer-border;
+		border-right: @outer-border;	
+	}
+	
+	.dojoxCalendarYearColumnHeader table {
+		position:relative;
+		width:100%;
+		height:100%;	
+
+		td {
+			text-align: center;
+			vertical-align: middle;
+			border-bottom: @outer-border;	
+			color: @label-color;
+			.header-background;
+		}	
+	}
+	
+	.dojoxCalendarColumnHeader {
+		position: absolute;
+		height: @column-header-height;	 
+		left: @row-header-width;
+		right: 0;
+		top: 0;
+		cursor: default;
+	}
+	
+	.dojoxCalendarColumnHeaderTable {
+		border-collapse: collapse;
+		table-layout: fixed;
+		position: relative;
+		margin: 0;
+		padding: 0;			
+		width: 100%;
+		height: 100%;	
+	
+		td {	
+			overflow:hidden;
+			white-space: nowrap;
+			vertical-align: middle;
+			text-align: center;
+			.header-background;
+			border-right: @inner-border;
+			border-top: @outer-border;
+			border-bottom: @outer-border;
+			.select-none;
+			color: @label-color;
+			.transition-duration(0.2s);
+		}
+		
+		td.last-child {	
+			border-right: @outer-border;	
+		}
+
+		.dojoxCalendarToday {
+			font-weight: bold;
+			color: @today-label-color;
+		}
+		
+		.dojoxCalendarWeekend {
+			color: @week-end-label-color;
+		}
+		
+		td.Hover{	
+			cursor: pointer;		
+			.header-hover-background;
+		}
+		
+		td.Active{	
+			.header-active-background;
+		}
+	
+	}
+	
+	.dojoxCalendarRowHeader {
+		position: absolute;
+		width: @row-header-width - 2px;
+		cursor: default;
+		border-left: @outer-border;
+		border-right: @outer-border;
+		height: 100%;
+		.select-none;
+	}
+	
+	.dojoxCalendarRowHeaderLabelContainer{
+		width: 100%;
+		height: 100%;
+		z-index: 10;
+	}
+	
+	.dojoxCalendarRowHeaderLabel{	
+		right: 4px;		
+		position: absolute;	
+	}
+	
+	.dojoxCalendarRowHeaderTable {
+		border-collapse: collapse;
+		table-layout: fixed;
+		position: relative;
+		margin: 0;
+		padding: 0;
+		width: 100%;
+		height: 100%;
+		
+		 td.dummy{
+			border-top: 1px solid @row-color;
+		}
+	
+		 td {	
+			vertical-align: top;			
+			text-align: right;	
+			border-top: @outer-border; 	
+			background-color: @row-color;
+			color: @label-color;
+			.border-box;
+		}
+	
+		 tr:first-child td	{
+			border-top: 1px solid @row-color;
+		}
+		
+	}
+		
+	 
+	.dojoxCalendarEvent {
+		position: absolute;	
+		text-align: left;
+		color: #FFF;
+		cursor: default;
+		overflow: hidden;
+	
+		.bg {
+			position: absolute;
+			left: 0;
+			right: 0;
+			top: 0;
+			bottom: 0;
+			z-index: -1;
+			border: @event-border;
+			.rounded-corners;
+			background-color: @event-header-bg-color;
+			.opacity(90);
+		}
+				
+		.endTime {
+			position: absolute;		
+			font-weight: bold;	
+			bottom:3px;
+			left: 6px;
+			white-space:nowrap;
+		}
+
+		.beforeIcon {
+			text-align: center;
+		}
+
+		.afterIcon {
+			position: absolute;
+			bottom: 2px;
+			width: 100%;
+			text-align: center;
+		}
+
+		.handle {
+			.glass-view;
+		}
+
+		.moveHandle {
+			position: absolute;
+			top:0;
+			width:100%;
+			bottom:0;
+			cursor:move;	
+		}
+
+		.resizeStartHandle {
+			position: absolute;
+			top:0;
+			width:100%;
+			height:10px;
+			cursor:n-resize;	
+		}
+
+		.resizeEndHandle {
+			position: absolute;
+			bottom:0;
+			width:100%;
+			height:10px;
+			cursor:n-resize;	
+		}
+
+		dl {
+			margin: 0;
+		}
+
+		dd {
+			margin: 0;
+			padding: 0 3px;
+			text-align: left;
+		}
+	}
+
+	.dojoxCalendarEvent.Hovered .bg {
+		background-color: @event-hovered-bg-color;	
+	}
+
+	.dojoxCalendarEvent.Selected .bg {
+		background-color: @event-selected-bg-color;
+	}
+
+	.dojoxCalendarEvent.Edited .bg {
+		border: @event-border-focused;
+		.opacity(70);
+	}
+
+	.dojoxCalendarEvent.Focused .bg {
+		border: @event-border-focused;
+	}
+	
+	.dojoxCalendarEvent .startTime {
+		.event-header();		
+	}
+
+	.dojoxCalendarEvent.Focused .startTime {
+		.top-left-right-border(@event-border-focused);
+	}
+
+	.dojoxCalendarEvent.Hovered .startTime {
+		background-color: @event-header-hovered-bg-color;
+	}
+
+	.dojoxCalendarEvent.Selected .startTime {
+		background-color: @event-header-selected-bg-color;
+	}
+
+	.dojoxCalendarEvent.Edited .startTime {
+		background-color: @event-header-bg-color;
+		.top-left-right-border(@event-border-focused);
+	}
+	
+	.dojoxCalendarVScrollBar {
+		position: absolute;
+		top: @sheet-top;
+		bottom: 0;
+		overflow-y: scroll;
+		overflow-x: hidden;
+	}
+}
+
diff --git a/dijit/themes/claro/images/titlebar.png b/dojox/calendar/themes/claro/images/titlebar.png
similarity index 100%
rename from dijit/themes/claro/images/titlebar.png
rename to dojox/calendar/themes/claro/images/titlebar.png
diff --git a/dojox/calendar/themes/iphone/Calendar.css b/dojox/calendar/themes/iphone/Calendar.css
new file mode 100644
index 0000000..7a135dd
--- /dev/null
+++ b/dojox/calendar/themes/iphone/Calendar.css
@@ -0,0 +1,25 @@
+ at import url("MatrixView.css");
+
+ at import url("ColumnView.css");
+.dojoxCalendar .buttonContainer {
+  position: absolute;
+  left: 0;
+  right: 0;
+  bottom: 1px;
+  height: 32px;
+  text-align: center;
+}
+.dojoxCalendar .viewContainer {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 32px;
+}
+.dojoxCalendar .view {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+}
diff --git a/dojox/calendar/themes/iphone/Calendar.less b/dojox/calendar/themes/iphone/Calendar.less
new file mode 100644
index 0000000..a47c976
--- /dev/null
+++ b/dojox/calendar/themes/iphone/Calendar.less
@@ -0,0 +1,30 @@
+ at button-container-height: 32px;
+
+ at import url("MatrixView.css");
+ at import url("ColumnView.css");
+
+.dojoxCalendar .buttonContainer{
+	position: absolute;
+	left: 0;
+	right: 0;
+	bottom: 1px;
+	height: @button-container-height;
+	text-align: center;
+}
+
+.dojoxCalendar .viewContainer{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: @button-container-height;
+}
+
+.dojoxCalendar .view{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+}
+
diff --git a/dojox/calendar/themes/iphone/Calendar_rtl.css b/dojox/calendar/themes/iphone/Calendar_rtl.css
new file mode 100644
index 0000000..106a1d6
--- /dev/null
+++ b/dojox/calendar/themes/iphone/Calendar_rtl.css
@@ -0,0 +1,3 @@
+ at import url("MatrixView_rtl.css");
+
+ at import url("ColumnView_rtl.css");
diff --git a/dojox/calendar/themes/iphone/Calendar_rtl.less b/dojox/calendar/themes/iphone/Calendar_rtl.less
new file mode 100644
index 0000000..25ef90d
--- /dev/null
+++ b/dojox/calendar/themes/iphone/Calendar_rtl.less
@@ -0,0 +1,3 @@
+ at import url("MatrixView_rtl.css");
+ at import url("ColumnView_rtl.css");
+
diff --git a/dojox/calendar/themes/iphone/ColumnView.css b/dojox/calendar/themes/iphone/ColumnView.css
new file mode 100644
index 0000000..4408dec
--- /dev/null
+++ b/dojox/calendar/themes/iphone/ColumnView.css
@@ -0,0 +1,504 @@
+.dojoxCalendarColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.dojoxCalendarColumnView .dojoxCalendarHeader {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 30px;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 72px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarColumnView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+}
+.dojoxCalendarColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.dojoxCalendarColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarColumnView td.hour {
+  border-top: 1px solid #cccccc;
+}
+.dojoxCalendarColumnView td.halfhour {
+  border-top: dotted 1px #cccccc;
+}
+.dojoxCalendarColumnView td.quarterhour {
+  border-top: dotted 1px #cccccc;
+}
+.dojoxCalendarColumnView span.hour {
+  color: #555555;
+  background-color: #ffffff;
+}
+.claro .dojoxCalendarColumnView span.halfhour,
+.claro .dojoxCalendarColumnView span.quarterhour {
+  color: #888888;
+  background-color: #ffffff;
+}
+.dojoxCalendarColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  cursor: default;
+}
+.dojoxCalendarColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.dojoxCalendarColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.dojoxCalendarColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 0;
+  margin-right: 9px;
+}
+.dojoxCalendarColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarColumnView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 0;
+  width: 70px;
+  top: 0;
+  text-align: center;
+  color: #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  color: #cccccc;
+}
+.dojoxCalendarColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 70px;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  color: #cccccc;
+  color: #cccccc;
+  border-right: 1px solid transparent;
+  border-top: 1px solid transparent;
+  border-bottom: 1px solid #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+  color: #295bb3;
+}
+.dojoxCalendarColumnView .dojoxCalendarRowHeader {
+  position: absolute;
+  width: 70px;
+  cursor: default;
+  border-right: 1px solid #cccccc;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderLabelContainer {
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+}
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel {
+  right: 4px;
+  position: absolute;
+}
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td {
+  vertical-align: top;
+  text-align: right;
+  color: #cccccc;
+  border-top: 1px solid transparent;
+}
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td span {
+  padding-top: 2px;
+  padding-right: 4px;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9F0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 10px;
+  left: 3px;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarEvent .resizeHandle div {
+  position: absolute;
+  left: 3px;
+  right: 3px;
+  top: 2px;
+  height: 24px;
+  background-color: #fff;
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+}
+.dojoxCalendarEvent .resizeHandle div:active {
+  filter: alpha(opacity=60);
+  opacity: 0.6;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 30px;
+  z-index: 2;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  height: 30px;
+  z-index: 2;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.dojoxCalendarColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.dojoxCalendarEvent.Edited dd {
+  margin-top: 7px;
+}
+.dojoxCalendarColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 72px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 30px;
+  height: 39px;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  bottom: 0;
+  cursor: default;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 70px;
+  bottom: 0;
+  border-right: none;
+  border-left: none;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+  text-align: right;
+  vertical-align: top;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td {
+  border-bottom: 1px solid #cccccc;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+  border-top: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxHorizontal .labels {
+  position: absolute;
+  left: 3px;
+  right: 1px;
+  bottom: 2px;
+  overflow: hidden;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxHorizontal.Edited .labels {
+  left: 33px;
+  right: 31px;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxLabel .labels {
+  position: absolute;
+  left: 2px;
+  right: 2px;
+  bottom: 0;
+  overflow: hidden;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeHandle {
+  top: auto;
+  text-align: auto;
+  vertical-align: auto;
+  position: absolute;
+  width: 30px;
+  height: 100%;
+  background-color: #fff;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  color: #000;
+  text-align: center;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeHandle div {
+  position: auto;
+  width: auto;
+  height: auto;
+  left: auto;
+  right: auto;
+  top: auto;
+  bottom: auto;
+  background-color: none;
+  filter: alpha(opacity=100);
+  opacity: 1;
+  border: none;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle span {
+  position: absolute;
+  bottom: 2px;
+  left: 10px;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle span {
+  position: absolute;
+  bottom: 2px;
+  left: 10px;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  right: 0;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle {
+  right: auto;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+  right: 0px;
+  left: auto;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.Edited .resizeHandle {
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .afterIcon {
+  width: auto;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .endTime {
+  position: relative;
+  bottom: auto;
+  left: auto;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand {
+  position: absolute;
+  text-align: center;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+  position: relative;
+  margin-right: 10%;
+  margin-left: 10%;
+  border-radius: 5px;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  border: 1px solid transparent;
+  -moz-border-radius: 5px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+  background-color: #73abfa;
+  border: 1px solid #cccccc;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+  background-color: #a5d1fb;
+  border: 1px solid #cccccc;
+}
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent div {
+  white-space: nowrap;
+}
diff --git a/dojox/calendar/themes/iphone/ColumnView.less b/dojox/calendar/themes/iphone/ColumnView.less
new file mode 100644
index 0000000..555d453
--- /dev/null
+++ b/dojox/calendar/themes/iphone/ColumnView.less
@@ -0,0 +1,537 @@
+ at import "ColumnViewCommon.less";
+
+.dojoxCalendarColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarHeader {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: @column-header-height;
+	.border-box;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarScrollContainer {
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: @sheet-top;
+	position: absolute;
+	overflow-y: hidden;
+	overflow-x: hidden;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.border-box;
+}
+	
+.dojoxCalendarColumnView .dojoxCalendarGrid {
+	position: absolute;
+	left: @row-header-width;
+	right: 0;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarGridTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarGridTable td {
+	border-top: dotted 1px #B5BCC7;	
+	border-right: @outer-border;
+	.border-box;
+}
+
+.dojoxCalendarColumnView td.hour {
+	border-top: @hour-stroke;
+}
+
+.dojoxCalendarColumnView td.halfhour{
+	border-top: @half-hour-stroke;	
+}
+
+.dojoxCalendarColumnView  td.quarterhour{
+	border-top: @quarter-hour-stroke;
+}
+
+.dojoxCalendarColumnView span.hour {
+	color: @label-color;
+	background-color: @row-color;
+}
+
+.claro .dojoxCalendarColumnView span.halfhour,
+.claro .dojoxCalendarColumnView span.quarterhour{
+	color: @secondary-label-color;
+	background-color: @row-color;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarContainer {
+	position: absolute;
+	top: 0;
+	left: @row-header-width;
+	right: 0;
+	cursor: default;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarContainerTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarContainerTable td {
+	height: 100%;
+	padding: 0;
+	vertical-align: top;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarContainerColumn {
+	position:	relative;
+	margin-left: 0;
+	margin-right: 9px;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+	.select-none;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	height: @column-header-height;
+	left: 0;
+	width: @row-header-width;
+	top: 0;	
+	text-align: center;
+	.header-background;
+	.border-box;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table {
+	position:relative;
+	width:100%;
+	height:100%;	
+}
+
+.dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table td {
+	text-align: center;
+	vertical-align: middle;
+	color: @header-label-color;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarColumnHeader {
+	position: absolute;
+	height: @column-header-height;	 
+	left: @row-header-width;
+	right: 0;
+	top: 0;
+	cursor: default;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;			
+	width: 100%;
+	height: 100%;	
+}
+
+.dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td {	
+	overflow:hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	color: @header-label-color;
+	border-right: @transparent-border;
+	border-top: @transparent-border;
+	border-bottom: @outer-border;
+	.select-none;
+	.transition-duration(0.2s);
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+	color: @today-label-color;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarRowHeader {
+	position: absolute;
+	width: @row-header-width;
+	cursor: default;
+	border-right: @outer-border;
+	height: 100%;
+	.select-none;
+	.border-box;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderLabelContainer{
+	width: 100%;
+	height: 100%;
+	z-index: 10;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel{	
+	right: 4px;		
+	position: absolute;	
+}
+
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td {	
+	vertical-align: top;			
+	text-align: right;	
+	color: @header-label-color;
+	border-top: 1px solid transparent;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderTable tr:first-child td	{
+	border-top: 1px solid transparent;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td span {
+ 	padding-top: 2px;
+	padding-right: 4px;
+}
+ 
+.dojoxCalendarColumnView .dojoxCalendarEvent {
+	position: absolute;	
+	text-align: left;
+	color: #FFF;
+	cursor: default;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .bg {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: -1;
+	border: 1px solid #260000;	
+	.rounded-corners;
+	background-color: #9F0000;
+	.opacity(90);
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent.Hovered .bg {
+	background-color: #CC0000;	
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent.Selected .bg {
+	background-color: #660000;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent.Edited .bg {
+	border: dashed 1px #FFFFFF;
+	.opacity(70);
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent.Focused .bg {
+	border: dashed 1px #FFFFFF;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .summary {
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .startTime {
+	font-weight: bold;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .endTime {
+	position: absolute;		
+	font-weight: bold;	
+	bottom:10px;
+	left: 3px;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .beforeIcon {
+	text-align: center;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .afterIcon {
+	position: absolute;
+	bottom: 2px;
+	width: 100%;
+	text-align: center;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .handle {
+	.glass-view;
+}
+
+.dojoxCalendarEvent .resizeHandle div {
+	position:absolute;
+	left: 3px;
+	right: 3px;	
+	top: 2px;
+	height: 24px;	
+	background-color: #fff;
+	.opacity(30);
+	.rounded-corners(5px);	
+}
+
+.dojoxCalendarEvent .resizeHandle div:active {
+	.opacity(60);	
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .moveHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	bottom:0;
+	cursor:move;	
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .resizeStartHandle {
+	position: absolute;
+	top:0;	
+	left: 0;
+	right: 0;
+	height:30px;
+	z-index: 2;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .resizeEndHandle {
+	position: absolute;
+	bottom:0;	
+	left: 0;
+	right: 0;	
+	height:30px;
+	z-index: 2;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.dojoxCalendarEvent.Edited dd {
+	margin-top: 7px
+}
+
+.dojoxCalendarColumnView .dojoxCalendarVScrollBar {
+	position: absolute;
+	top: @sheet-top;
+	bottom: 0;
+	overflow-y: scroll;
+	overflow-x: hidden;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView {	
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: @column-header-height;
+	height: @secondary-sheet-height;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGrid {	
+	position: absolute;
+	left: @row-header-width;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	.border-box;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarContainer {	
+	position: absolute;
+	top: 0;
+	left: @row-header-width;
+	right: 0;
+	bottom: 0;
+	cursor: default;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+	position: absolute;
+	left: 0;				
+	top: 0;
+	width: @row-header-width;
+	bottom: 0;
+	
+	border-right: none;
+	border-left: none;
+	.border-box;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+	text-align: right;
+	vertical-align: top;	
+	border-top: @inner-border;
+	border-bottom: @inner-border;
+	border-right: @inner-border;
+	.border-box;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td	{
+	border-bottom: @outer-border;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child	{
+	border-right: @outer-border;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+	border-top: @inner-border;
+	border-right: @outer-border;
+	border-bottom: @outer-border;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxHorizontal .labels {
+	position: absolute;
+	left: 3px;
+	right: 1px;
+	bottom: 2px;
+	overflow: hidden;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxHorizontal.Edited .labels {
+	left: 33px;
+	right: 31px;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxLabel .labels {
+	position: absolute;
+	left: 2px;
+	right: 2px;
+	bottom: 0;
+	overflow: hidden;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeHandle {	
+	top: auto;
+	text-align: auto;
+	vertical-align: auto;
+	position: absolute;
+	width:30px;
+	height:100%;	
+	background-color: #fff;
+	.opacity(0);
+	.rounded-corners(5px);	
+	color: #000;
+	text-align: center;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeHandle div {
+	position:auto;
+	width: auto;
+	height: auto;
+	left:auto;
+	right: auto;	
+	top: auto;
+	bottom:auto;		
+	background-color: none;
+	.opacity(100);
+	border: none;	
+}
+
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle span {	
+	position: absolute;
+	bottom: 2px;
+	left: 10px;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle span {	
+	position: absolute;
+	bottom: 2px;
+	left: 10px;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+	
+	position: absolute;
+	left:0;
+	top:0;
+	bottom:0;
+	right:0;	
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle {
+	right: auto;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+	right:0px;
+	left:auto;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.Edited .resizeHandle {		
+	.opacity(30);
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .afterIcon {
+	width:auto;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .endTime {
+	position: relative;				
+	bottom:auto;
+	left: auto;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand {
+	position: absolute;
+	text-align: center;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+	position: relative;
+	margin-right: 10%;
+	margin-left: 10%;
+	border-radius: 5px;
+	height: 100%;
+	.select-none;
+	border: 1px solid transparent;
+	-moz-border-radius: 5px;
+	-webkit-transition-duration: 0.2s;
+	-moz-transition-duration: 0.2s;
+	transition-duration: 0.2s;	
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+	background-color: @expand-up-color;
+	border: @inner-border;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+	background-color: @expand-down-color;
+	border: @inner-border;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent div {
+	white-space:nowrap;
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/iphone/ColumnViewCommon.less b/dojox/calendar/themes/iphone/ColumnViewCommon.less
new file mode 100644
index 0000000..49064da
--- /dev/null
+++ b/dojox/calendar/themes/iphone/ColumnViewCommon.less
@@ -0,0 +1,10 @@
+ at import "Common.less";
+
+ at hour-stroke: 1px solid #CCCCCC;
+ at half-hour-stroke: dotted 1px #CCCCCC;
+ at quarter-hour-stroke: dotted 1px #CCCCCC;
+
+ at column-header-height: 30px;
+ at row-header-width: 70px;
+ at secondary-sheet-height: 39px;
+ at sheet-top: @secondary-sheet-height + @column-header-height + 3px;
diff --git a/dojox/calendar/themes/iphone/ColumnView_rtl.css b/dojox/calendar/themes/iphone/ColumnView_rtl.css
new file mode 100644
index 0000000..7bbbc52
--- /dev/null
+++ b/dojox/calendar/themes/iphone/ColumnView_rtl.css
@@ -0,0 +1,102 @@
+.dojoxCalendarColumnViewRtl .dojoxCalendarScrollContainer {
+  border-left: none;
+  border-right: none;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarGrid {
+  left: 0;
+  right: 70px;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarGridTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarContainer {
+  left: 0;
+  right: 70px;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarContainerColumn {
+  margin-right: 1px;
+  margin-left: 9px;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarYearColumnHeader {
+  right: 0;
+  width: 70px;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeader {
+  left: 0;
+  right: 70px;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarRowHeaderLabel {
+  right: auto;
+  left: 4px;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarEvent .summary {
+  text-align: right;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarEvent .startTime {
+  text-align: right;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarEvent .endTime {
+  text-align: right;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarVScrollBar {
+  margin-left: -1px;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+  right: 70px;
+  left: 0;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {
+  text-align: left;
+  border-bottom: 1px solid #cccccc;
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span {
+  padding-left: 2px;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+  right: 70px;
+  left: 0;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  text-align: right;
+  vertical-align: top;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+  right: 70px;
+  left: 0;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+  right: 0;
+  left: auto;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+  right: 0;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+  left: 0;
+  right: auto;
+}
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  text-align: right;
+  right: 2px;
+}
diff --git a/dojox/calendar/themes/iphone/ColumnView_rtl.less b/dojox/calendar/themes/iphone/ColumnView_rtl.less
new file mode 100644
index 0000000..a0fe89c
--- /dev/null
+++ b/dojox/calendar/themes/iphone/ColumnView_rtl.less
@@ -0,0 +1,129 @@
+ at import "ColumnViewCommon.less";
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarScrollContainer {	
+	border-left: none;
+	border-right: none;
+}
+	
+.dojoxCalendarColumnViewRtl .dojoxCalendarGrid {
+	left: 0;
+	right: @row-header-width;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarGridTable td {
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarContainer {	
+	left: 0;
+	right: @row-header-width;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarContainerColumn {
+	margin-right: 1px;
+	margin-left: 9px;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarYearColumnHeader{
+	right: 0;
+	width: @row-header-width;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeader {
+	left: 0;
+	right: @row-header-width;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarRowHeaderLabel { 	
+	right: auto;
+	left: 4px;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarEvent .summary {
+	text-align: right;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarEvent .startTime {
+	text-align: right;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarEvent .endTime {
+	text-align: right;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarVScrollBar { 	
+	margin-left: -1px;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+	right: @row-header-width;
+	left: 0;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {			
+	text-align: left;
+	border-bottom: @inner-border;
+	border-left: @inner-border;
+	border-right: none;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span{
+	padding-left: 2px;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child	{
+	border-left: @outer-border;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+	right: @row-header-width;
+	left: 0;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	text-align: right;
+	vertical-align: top;		
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	right: 0;
+	left: auto;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+	right: @row-header-width;
+	left: 0;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+	right: 0;
+	left: auto;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+	right: 0;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+	left: 0;
+	right: auto;
+}
+
+.dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	text-align: right;
+	right: 2px;
+}
\ No newline at end of file
diff --git a/dojox/dnd/tests/robot/test_selector.html b/dojox/calendar/themes/iphone/Common.css
similarity index 100%
rename from dojox/dnd/tests/robot/test_selector.html
rename to dojox/calendar/themes/iphone/Common.css
diff --git a/dojox/calendar/themes/iphone/Common.less b/dojox/calendar/themes/iphone/Common.less
new file mode 100644
index 0000000..e32d3b8
--- /dev/null
+++ b/dojox/calendar/themes/iphone/Common.less
@@ -0,0 +1,78 @@
+ at outer-border: 1px solid #CCC;
+ at inner-border: 1px solid #CCC;
+
+ at transparent-border: 1px solid transparent;
+
+ at row-color: #FFF;
+ at row-color-hover: #E5F2FE;
+ at row-color-active: #A5D1FB;
+
+ at expand-up-color: #73ABFA;
+ at expand-down-color: #A5D1FB;
+
+ at header-label-color: #CCC;
+
+ at today-color: #FFF;
+ at today-label-color: #295bb3;
+
+ at week-end-color: #EFEFEF;
+ at week-end-label-color: #CCC;
+
+ at horizontal-color: #9F0000;
+ at horizontal-hover-color: #CC0000;
+ at horizontal-selected-bg-color: #660000;
+ at horizontal-border: 1px solid #260000;
+
+ at label-color: #555;
+ at secondary-label-color: #888;
+
+.border-box(){
+	-webkit-box-sizing: border-box;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.opacity(@op){
+	filter: ~"alpha(opacity=@{op})";	
+	opacity:@op/100;
+}
+
+.transition-duration(@dur: 0s){
+	-webkit-transition-duration: @dur;
+	-moz-transition-duration: @dur;
+	transition-duration: @dur;
+}
+
+.select-none() {
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	khtml-user-select: none;
+	user-select: none;
+}
+
+.glass-view(){
+	z-index: 2;
+	background:#00FF00; 
+	.opacity(0);
+	.select-none
+}
+
+.header-background(){
+	color: @header-label-color;
+}
+
+.header-hover-background(){
+	
+}
+
+.header-active-background(){
+	
+}
+
+
+
+.rounded-corners (@radius: 5px) {
+  border-radius: @radius;
+  -webkit-border-radius: @radius;
+  -moz-border-radius: @radius;
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/iphone/MatrixView.css b/dojox/calendar/themes/iphone/MatrixView.css
new file mode 100644
index 0000000..1793a22
--- /dev/null
+++ b/dojox/calendar/themes/iphone/MatrixView.css
@@ -0,0 +1,407 @@
+.dojoxCalendarMatrixView {
+  cursor: default;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGrid {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 30px;
+  bottom: 0px;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+  text-align: right;
+  vertical-align: top;
+  border-bottom: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td span {
+  padding-right: 2px;
+  padding-top: 2px;
+  color: #cccccc;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td {
+  border-bottom: 1px solid #cccccc;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+/* 
+ * The dojoxCalendarColToday & dojoxCalendarColWeekend classes is added by the 
+ * MatrixView.styleGridCell method that can be subclassed to add/remove css classes
+ */
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td.dojoxCalendarToday {
+  color: #295bb3;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarDayDisabled {
+  background-color: #fafafa;
+  color: #838383;
+}
+.dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  left: 0px;
+  top: 0px;
+  width: 50px;
+  height: 30px;
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid transparent;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+}
+.dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid transparent;
+  border-top: 1px solid transparent;
+  border-right: 1px solid transparent;
+  color: #cccccc;
+  color: #cccccc;
+}
+.dojoxCalendarMatrixView .dojoxCalendarColumnHeader {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 0px;
+  height: 29px;
+  cursor: default;
+  border-bottom: 1px solid #cccccc;
+}
+.dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+}
+.dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  vertical-align: middle;
+  text-align: center;
+  color: #cccccc;
+  color: #cccccc;
+  border-right: 1px solid transparent;
+  border-top: 1px solid transparent;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+  position: absolute;
+  left: 0px;
+  top: 30px;
+  width: 50px;
+  bottom: 0;
+  color: #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  border-collapse: collapse;
+  table-layout: fixed;
+  margin: 0;
+  padding: 0;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+/* 
+ * The MatrixView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid transparent;
+  border-right: 1px solid #cccccc;
+  border-bottom: 1px solid transparent;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.last-child {
+  border-bottom: 1px solid #cccccc;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Hover {
+  background-color: #e5f2fe;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Active {
+  background-color: #a5d1fb;
+}
+.dojoxCalendarMatrixView .dojoxCalendarContainer {
+  position: absolute;
+  top: 30px;
+  left: 50px;
+  right: 0px;
+  bottom: 0px;
+}
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+}
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable td {
+  vertical-align: top;
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable td div.dojoxCalendarContainerRow {
+  position: relative;
+  height: 100%;
+  width: 100%;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #000000;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  white-space: nowrap;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal {
+  color: #FFF;
+  position: absolute;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .bg {
+  border: 1px solid #260000;
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  text-align: left;
+  color: #000000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9f0000;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Hovered .bg {
+  background-color: #cc0000;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Selected .bg {
+  background-color: #660000;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.Edited {
+  color: #fff;
+  font-weight: bold;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .bg {
+  border: dashed 1px #FFF;
+  filter: alpha(opacity=50);
+  opacity: 0.5;
+  filter: formatstring("alpha(opacity={0})", 50);
+  opacity: 0.5;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Focused .bg {
+  border: dashed 1px #FFF;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  position: absolute;
+  left: 3px;
+  right: 1px;
+  bottom: 2px;
+  overflow: hidden;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .labels {
+  left: 33px;
+  right: 31px;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+  position: absolute;
+  left: 2px;
+  right: 2px;
+  bottom: 0;
+  overflow: hidden;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Selected {
+  color: #F00;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Edited {
+  color: #FFF;
+  border: dashed 1px #FFF;
+  background: #600;
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+  filter: formatstring("alpha(opacity={0})", 30);
+  opacity: 0.3;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Focused {
+  border: dashed 1px #000000;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent .resizeHandle {
+  position: absolute;
+  width: 30px;
+  height: 100%;
+  background-color: #fff;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  filter: formatstring("alpha(opacity={0})", 0);
+  opacity: 0;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  color: #000;
+  text-align: center;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  right: 0;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle {
+  right: auto;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+  right: 0px;
+  left: auto;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.Edited .resizeHandle {
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+  filter: formatstring("alpha(opacity={0})", 30);
+  opacity: 0.3;
+}
+.dojoxCalendarMatrixView .dojoxCalendarExpand {
+  position: absolute;
+  text-align: center;
+}
+.dojoxCalendarMatrixView .dojoxCalendarExpand span {
+  display: inline-block;
+  vertical-align: middle;
+}
+.dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+  position: relative;
+  margin-right: 5px;
+  margin-left: 5px;
+  height: 100%;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  border: 1px solid transparent;
+}
+.dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+  background-color: #73abfa;
+  border: 1px solid #1e56a5;
+}
+.dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+  background-color: #a5d1fb;
+  border: 1px solid #507ca6;
+}
diff --git a/dojox/calendar/themes/iphone/MatrixView.less b/dojox/calendar/themes/iphone/MatrixView.less
new file mode 100644
index 0000000..8ea76bf
--- /dev/null
+++ b/dojox/calendar/themes/iphone/MatrixView.less
@@ -0,0 +1,429 @@
+ at import "MatrixViewCommon.less";
+
+ at outer-border: 1px solid #CCCCCC;
+ at inner-border: 1px solid #CCCCCC;
+
+ at transparent-border: 1px solid transparent;
+
+ at row-color-hover: #E5F2FE;
+ at row-color-active: #A5D1FB;
+
+ at today-label-color: #295BB3;
+
+ at week-end-color: #EFEFEF;
+ at disabled-day-color: #FAFAFA;
+
+ at header-label-color: #CCCCCC;
+
+ at horizontal-color: #9F0000;
+ at horizontal-hover-color: #CC0000;
+ at horizontal-selected-bg-color: #660000;
+ at horizontal-border: 1px solid #260000;
+ at expand-up-color: #73ABFA;
+ at expand-down-color: #A5D1FB;
+
+ at column-header-height: 30px;
+ at row-header-width: 50px;
+
+.border-box(){
+	-webkit-box-sizing: border-box;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.opacity(@op){
+	filter:formatstring("alpha(opacity={0})", @op);
+	opacity:@op/100;
+}
+
+.transition-duration(@dur: 0s){
+	-webkit-transition-duration: @dur;
+	-moz-transition-duration: @dur;
+	transition-duration: @dur;
+}
+
+.select-none() {
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	khtml-user-select: none;
+	user-select: none;
+}
+
+.glass-view(){
+	z-index: 2;
+	background:#00FF00; 
+	.opacity(0);
+	.select-none
+}
+
+.header-background(){
+	color: @header-label-color;
+}
+
+.rounded-corners (@radius: 5px) {
+  border-radius: @radius;
+  -webkit-border-radius: @radius;
+  -moz-border-radius: @radius;
+}
+
+.dojoxCalendarMatrixView {	
+	cursor: default;
+	.select-none;
+}
+	
+.dojoxCalendarMatrixView .dojoxCalendarGrid {
+	position: absolute;
+	left: @row-header-width;
+	right: 0px;
+	top: @column-header-height;
+	bottom: 0px;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarGridTable {
+	position: relative;
+	width: 100%;
+	height: 100%;	
+	margin: 0;
+	padding: 0;
+	border-collapse: collapse;
+	table-layout: fixed;	
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarGridTable tr{
+	.border-box;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+	text-align: right;
+	vertical-align: top;	
+	border-bottom: @inner-border;
+	border-right: @inner-border;
+	.border-box;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td span{
+	padding-right: 2px;
+	padding-top: 2px;		
+	color: @header-label-color;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td span.FirstVisibleDayOfMonth{	
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td	{
+	border-bottom: @outer-border;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child	{
+	border-right: @outer-border;
+}
+
+/* 
+ * The dojoxCalendarColToday & dojoxCalendarColWeekend classes is added by the 
+ * MatrixView.styleGridCell method that can be subclassed to add/remove css classes
+ */
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td.dojoxCalendarToday	{		
+	color: @today-label-color;
+}
+			
+
+.dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarDayDisabled {
+	background-color: @disabled-day-color;
+	color: @disabled-day-color - #777777;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	left: 0px;
+	top: 0px;
+	width: @row-header-width;
+	height: @column-header-height;			
+	text-align: center;
+	vertical-align: middle;
+	border-bottom: @transparent-border;
+	.border-box;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table{
+	position: relative;		
+	width:100%;
+	height: 100%;
+	table-layout: fixed;
+	border-collapse: collapse;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table td{
+	text-align: center;
+	vertical-align: middle;		
+	border-left: @transparent-border;
+	border-top: @transparent-border;
+	border-right: @transparent-border;
+	.header-background;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarColumnHeader {
+	position: absolute;
+	left: @row-header-width;
+	right: 0px;
+	top: 0px;
+	height: @column-header-height - 1px;
+	cursor: default;
+	border-bottom: @outer-border;	
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable {
+	position: relative;		
+	width:100%;
+	height: 100%;
+	table-layout: fixed;
+	border-collapse: collapse;		
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+	overflow:hidden;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @transparent-border;
+	border-top: @transparent-border;
+	.select-none;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+	position: absolute;
+	left: 0px;				
+	top: @column-header-height;
+	width: @row-header-width;
+	bottom: 0;
+	color: @header-label-color;
+	.select-none;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable {
+	position: relative;			
+	width: 100%;
+	height: 100%;
+	border-collapse: collapse;
+	table-layout: fixed;
+	margin: 0;
+	padding: 0;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable tr{
+	.border-box;
+}
+
+/* 
+ * The MatrixView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+	text-align: center;
+	vertical-align: middle;	
+	border-left: @transparent-border;
+	border-right: @outer-border;
+	border-bottom: @transparent-border;
+	.border-box;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.last-child {
+	border-bottom: @outer-border;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Hover {
+	background-color: @row-color-hover;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Active {
+	background-color: @row-color-active;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarContainer {
+	position: absolute;
+	top: @column-header-height;
+	left: @row-header-width;
+	right: 0px;
+	bottom: 0px;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable {
+	position: relative;
+	width: 100%;
+	height: 100%;	
+	margin: 0;
+	padding: 0;
+	border-collapse: collapse;
+	table-layout: fixed;	
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable tr{
+	.border-box;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable td{
+	vertical-align: top;
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	.border-box;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable td div.dojoxCalendarContainerRow{
+	position:relative;
+	height:100%;
+	width:100%;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+ 	.select-none;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent {	
+	position: absolute;
+	text-align: left;
+	color: #000000;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	white-space: nowrap;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal {
+	color: #FFF;
+	position: absolute;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .bg {
+	border: @horizontal-border;	
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;	
+	text-align: left;
+	color: #000000;	
+	.rounded-corners(5px);
+	background-color: @horizontal-color;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Hovered  .bg {
+	background-color: @horizontal-hover-color;	
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Selected .bg {
+	background-color: @horizontal-selected-bg-color;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.Edited {
+	color: #fff;
+	font-weight: bold;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .bg {
+	border: dashed 1px #FFF;
+	.opacity(50);
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Focused .bg {
+	border: dashed 1px #FFF;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	position: absolute;
+	left: 3px;
+	right: 1px;
+	bottom: 2px;
+	overflow: hidden;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .labels {
+	left: 33px;
+	right: 31px;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+	position: absolute;
+	left: 2px;
+	right: 2px;
+	bottom: 0;
+	overflow: hidden;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Selected {
+	color: #F00;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Edited {
+	color: #FFF;
+	border: dashed 1px #FFF;
+	background: #600;
+	.opacity(30);
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Focused {
+	border: dashed 1px #000000;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent .resizeHandle {	
+	position: absolute;
+	width:30px;
+	height:100%;	
+	background-color: #fff;
+	.opacity(0);
+	.rounded-corners(5px);	
+	color: #000;
+	text-align: center;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {	
+	position: absolute;
+	left:0;
+	top:0;
+	bottom:0;
+	right:0;	
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle {
+	right: auto;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+	right:0px;
+	left:auto;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarEvent.Edited .resizeHandle {	
+	.opacity(30);
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarExpand {
+	position: absolute;
+	text-align: center;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarExpand span {
+	display: inline-block;
+	vertical-align: middle;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+	position: relative;
+	margin-right: 5px;
+	margin-left: 5px;
+	height: 100%;
+	.rounded-corners(5px);
+	.transition-duration(0.2s);
+	.border-box;	
+	border: 1px solid transparent;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+	background-color: @expand-up-color;
+	border: 1px solid @expand-up-color - #555555;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+	background-color: @expand-down-color;
+	border: 1px solid @expand-down-color - #555555;
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/iphone/MatrixViewCommon.less b/dojox/calendar/themes/iphone/MatrixViewCommon.less
new file mode 100644
index 0000000..2736456
--- /dev/null
+++ b/dojox/calendar/themes/iphone/MatrixViewCommon.less
@@ -0,0 +1,11 @@
+ at import "Common.less";
+
+ at row-color-hover: #E5F2FE;
+ at row-color-active: #A5D1FB;
+
+ at disabled-day-color: #FAFAFA;
+
+ at header-label-color: #CCCCCC;
+
+ at column-header-height: 30px;
+ at row-header-width: 50px;
\ No newline at end of file
diff --git a/dojox/calendar/themes/iphone/MatrixView_rtl.css b/dojox/calendar/themes/iphone/MatrixView_rtl.css
new file mode 100644
index 0000000..0d56605
--- /dev/null
+++ b/dojox/calendar/themes/iphone/MatrixView_rtl.css
@@ -0,0 +1,463 @@
+.dojoxCalendarMatrixView {
+  cursor: default;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGrid {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 30px;
+  bottom: 0px;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+  text-align: right;
+  vertical-align: top;
+  border-bottom: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td span {
+  padding-right: 2px;
+  padding-top: 2px;
+  color: #cccccc;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td {
+  border-bottom: 1px solid #cccccc;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+/* 
+ * The dojoxCalendarColToday & dojoxCalendarColWeekend classes is added by the 
+ * MatrixView.styleGridCell method that can be subclassed to add/remove css classes
+ */
+.dojoxCalendarMatrixView .dojoxCalendarGridTable td.dojoxCalendarToday {
+  color: #295bb3;
+}
+.dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarDayDisabled {
+  background-color: #fafafa;
+  color: #838383;
+}
+.dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  left: 0px;
+  top: 0px;
+  width: 50px;
+  height: 30px;
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid transparent;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+}
+.dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid transparent;
+  border-top: 1px solid transparent;
+  border-right: 1px solid transparent;
+  color: #cccccc;
+  color: #cccccc;
+}
+.dojoxCalendarMatrixView .dojoxCalendarColumnHeader {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 0px;
+  height: 29px;
+  cursor: default;
+  border-bottom: 1px solid #cccccc;
+}
+.dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+}
+.dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  vertical-align: middle;
+  text-align: center;
+  color: #cccccc;
+  color: #cccccc;
+  border-right: 1px solid transparent;
+  border-top: 1px solid transparent;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+  position: absolute;
+  left: 0px;
+  top: 30px;
+  width: 50px;
+  bottom: 0;
+  color: #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  border-collapse: collapse;
+  table-layout: fixed;
+  margin: 0;
+  padding: 0;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+/* 
+ * The MatrixView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid transparent;
+  border-right: 1px solid #cccccc;
+  border-bottom: 1px solid transparent;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.last-child {
+  border-bottom: 1px solid #cccccc;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Hover {
+  background-color: #e5f2fe;
+}
+.dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Active {
+  background-color: #a5d1fb;
+}
+.dojoxCalendarMatrixView .dojoxCalendarContainer {
+  position: absolute;
+  top: 30px;
+  left: 50px;
+  right: 0px;
+  bottom: 0px;
+}
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+}
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable td {
+  vertical-align: top;
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMatrixView .dojoxCalendarContainerTable td div.dojoxCalendarContainerRow {
+  position: relative;
+  height: 100%;
+  width: 100%;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #000000;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  white-space: nowrap;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal {
+  color: #FFF;
+  position: absolute;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .bg {
+  border: 1px solid #260000;
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  text-align: left;
+  color: #000000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9f0000;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Hovered .bg {
+  background-color: #cc0000;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Selected .bg {
+  background-color: #660000;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.Edited {
+  color: #fff;
+  font-weight: bold;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .bg {
+  border: dashed 1px #FFF;
+  filter: alpha(opacity=50);
+  opacity: 0.5;
+  filter: formatstring("alpha(opacity={0})", 50);
+  opacity: 0.5;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Focused .bg {
+  border: dashed 1px #FFF;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  position: absolute;
+  left: 3px;
+  right: 1px;
+  bottom: 2px;
+  overflow: hidden;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .labels {
+  left: 33px;
+  right: 31px;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+  position: absolute;
+  left: 2px;
+  right: 2px;
+  bottom: 0;
+  overflow: hidden;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Selected {
+  color: #F00;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Edited {
+  color: #FFF;
+  border: dashed 1px #FFF;
+  background: #600;
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+  filter: formatstring("alpha(opacity={0})", 30);
+  opacity: 0.3;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Focused {
+  border: dashed 1px #000000;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent .resizeHandle {
+  position: absolute;
+  width: 30px;
+  height: 100%;
+  background-color: #fff;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  filter: formatstring("alpha(opacity={0})", 0);
+  opacity: 0;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  color: #000;
+  text-align: center;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  right: 0;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle {
+  right: auto;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+  right: 0px;
+  left: auto;
+}
+.dojoxCalendarMatrixView .dojoxCalendarEvent.Edited .resizeHandle {
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+  filter: formatstring("alpha(opacity={0})", 30);
+  opacity: 0.3;
+}
+.dojoxCalendarMatrixView .dojoxCalendarExpand {
+  position: absolute;
+  text-align: center;
+}
+.dojoxCalendarMatrixView .dojoxCalendarExpand span {
+  display: inline-block;
+  vertical-align: middle;
+}
+.dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+  position: relative;
+  margin-right: 5px;
+  margin-left: 5px;
+  height: 100%;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  border: 1px solid transparent;
+}
+.dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+  background-color: #73abfa;
+  border: 1px solid #1e56a5;
+}
+.dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+  background-color: #a5d1fb;
+  border: 1px solid #507ca6;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+  right: 50px;
+  left: 0;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {
+  text-align: left;
+  border-bottom: 1px solid #cccccc;
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span {
+  padding-left: 2px;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+  right: 50px;
+  left: 0;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  text-align: right;
+  vertical-align: top;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+  right: 50px;
+  left: 0;
+}
+.dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+  right: 0;
+  left: auto;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  text-align: right;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+  text-align: right;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+  right: 0;
+}
+.dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+  left: 0;
+  right: auto;
+}
diff --git a/dojox/calendar/themes/iphone/MatrixView_rtl.less b/dojox/calendar/themes/iphone/MatrixView_rtl.less
new file mode 100644
index 0000000..4ae88cf
--- /dev/null
+++ b/dojox/calendar/themes/iphone/MatrixView_rtl.less
@@ -0,0 +1,71 @@
+ at import "MatrixView.less";
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+	right: @row-header-width;
+	left: 0;
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {			
+	text-align: left;
+	border-bottom: @inner-border;
+	border-left: @inner-border;
+	border-right: none;
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span{
+	padding-left: 2px;
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child	{
+	border-left: @outer-border;
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+	right: @row-header-width;
+	left: 0;
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	text-align: right;
+	vertical-align: top;		
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	right: 0;
+	left: auto;
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+	right: @row-header-width;
+	left: 0;
+}
+
+.dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+	right: 0;
+	left: auto;
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	text-align: right;
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+	text-align: right;
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+	right: 0;
+}
+
+.dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+	left:0;
+	right:auto;
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/iphone/MonthColumnView.css b/dojox/calendar/themes/iphone/MonthColumnView.css
new file mode 100644
index 0000000..a97e0a4
--- /dev/null
+++ b/dojox/calendar/themes/iphone/MonthColumnView.css
@@ -0,0 +1,264 @@
+.dojoxCalendarMonthColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 30px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-bottom: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGrid {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #cccccc;
+  color: #555555;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable td span {
+  padding-left: 3px;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #ffffff;
+  font-weight: bold;
+  color: #295bb3;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarHiddenEvents {
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents {
+  background: #ffffff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.first-child {
+  border-left: 1px solid #cccccc;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #ffffff;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #efefef;
+  color: #cccccc;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #efefef;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  cursor: default;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 35px;
+  margin-right: 5px;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 0;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  color: #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #cccccc;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+  overflow: hidden;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9F0000;
+  filter: formatstring("alpha(opacity={0})", 90);
+  opacity: 0.9;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: formatstring("alpha(opacity={0})", 70);
+  opacity: 0.7;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 10px;
+  left: 3px;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: formatstring("alpha(opacity={0})", 0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.dojoxCalendarEvent .resizeHandle div {
+  position: absolute;
+  left: 3px;
+  right: 3px;
+  top: 2px;
+  height: 24px;
+  background-color: #fff;
+  filter: formatstring("alpha(opacity={0})", 30);
+  opacity: 0.3;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+}
+.dojoxCalendarEvent .resizeHandle div:active {
+  filter: formatstring("alpha(opacity={0})", 60);
+  opacity: 0.6;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 30px;
+  z-index: 2;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  height: 30px;
+  z-index: 2;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 30px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/iphone/MonthColumnView.less b/dojox/calendar/themes/iphone/MonthColumnView.less
new file mode 100644
index 0000000..18e7e30
--- /dev/null
+++ b/dojox/calendar/themes/iphone/MonthColumnView.less
@@ -0,0 +1,303 @@
+ at import "ColumnViewCommon.less";
+
+.dojoxCalendarMonthColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarScrollContainer {
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: @column-header-height;
+	position: absolute;
+	overflow-y: hidden;
+	overflow-x: hidden;	
+	border-bottom: @outer-border;
+	.border-box;
+}
+	
+.dojoxCalendarMonthColumnView .dojoxCalendarGrid {
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable td {
+	border-top: dotted 1px #B5BCC7;	
+	border-right: @inner-border;
+	color: @label-color;
+	.border-box;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable td span {
+  padding-left:3px;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td	{
+	border-top: 1px solid transparent;
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+	background-color: @today-color;
+	font-weight: bold;
+	color: @today-label-color;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarHiddenEvents	{	
+	background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;	
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents	{	
+	background: @today-color url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;	
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.last-child	{
+	border-right: @outer-border;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.first-child	{
+	border-left: @outer-border;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday	{
+	border-top: 1px solid @today-color;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+	color: @week-end-label-color;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend	{
+	border-top: 1px solid @week-end-color;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarContainer {
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+	cursor: default;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarContainerTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarContainerTable td {
+	height: 100%;
+	padding: 0;
+	vertical-align: top;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarContainerColumn {
+	position:	relative;
+	margin-left: 35px;
+	margin-right: 5px;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+	.select-none;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarColumnHeader {
+	position: absolute;
+	height: @column-header-height;	 
+	left: 0;
+	right: 0;
+	top: 0;
+	cursor: default;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;			
+	width: 100%;
+	height: 100%;	
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {	
+	overflow:hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-bottom: @outer-border;
+	.select-none;
+	color: @header-label-color;
+	.transition-duration(0.2s);
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Hover{	
+	cursor: pointer;		
+	.header-hover-background;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Active{	
+	.header-active-background;
+}
+ 
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent {
+	position: absolute;	
+	text-align: left;
+	color: #FFF;
+	cursor: default;
+	overflow: hidden;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .bg {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: -1;
+	border: 1px solid #260000;	
+	.rounded-corners;
+	background-color: #9F0000;
+	.opacity(90);
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent.Hovered .bg {
+	background-color: #CC0000;	
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent.Selected .bg {
+	background-color: #660000;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent.Edited .bg {
+	border: dashed 1px #FFFFFF;
+	.opacity(70);
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent.Focused .bg {
+	border: dashed 1px #FFFFFF;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .summary {
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .startTime {
+	font-weight: bold;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .endTime {
+	position: absolute;		
+	font-weight: bold;	
+	bottom:10px;
+	left: 3px;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .beforeIcon {
+	text-align: center;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent .afterIcon {
+	position: absolute;
+	bottom: 2px;
+	width: 100%;
+	text-align: center;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .handle {
+	.glass-view;
+}
+
+.dojoxCalendarEvent .resizeHandle div {
+	position:absolute;
+	left: 3px;
+	right: 3px;	
+	top: 2px;
+	height: 24px;	
+	background-color: #fff;
+	.opacity(30);
+	.rounded-corners(5px);	
+}
+
+.dojoxCalendarEvent .resizeHandle div:active {
+	.opacity(60);	
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .moveHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	bottom:0;
+	cursor:move;	
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .resizeStartHandle {
+	position: absolute;
+	top:0;	
+	left: 0;
+	right: 0;
+	height:30px;
+	z-index: 2;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent .resizeEndHandle {
+	position: absolute;
+	bottom:0;	
+	left: 0;
+	right: 0;	
+	height:30px;
+	z-index: 2;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.dojoxCalendarColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.dojoxCalendarEvent.Edited dd {
+	margin-top: 7px
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarVScrollBar {
+	position: absolute;
+	top: @column-header-height;
+	bottom: 0;
+	overflow-y: scroll;
+	overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/iphone/MonthColumnViewCommon.less b/dojox/calendar/themes/iphone/MonthColumnViewCommon.less
new file mode 100644
index 0000000..9bb3ec8
--- /dev/null
+++ b/dojox/calendar/themes/iphone/MonthColumnViewCommon.less
@@ -0,0 +1,7 @@
+ at import "Common.less";
+
+ at hour-stroke: 1px solid #C7BEBE;
+ at half-hour-stroke: dotted 1px #C7BEBE;
+ at quarter-hour-stroke: dotted 1px #C7BEBE;
+
+ at column-header-height: 30px;
diff --git a/dojox/calendar/themes/iphone/MonthColumnView_rtl.css b/dojox/calendar/themes/iphone/MonthColumnView_rtl.css
new file mode 100644
index 0000000..115d383
--- /dev/null
+++ b/dojox/calendar/themes/iphone/MonthColumnView_rtl.css
@@ -0,0 +1,42 @@
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td {
+  border-right: none;
+  border-left: 1px solid #cccccc;
+}
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td span {
+  padding-right: 3px;
+}
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable .dojoxCalendarHiddenEvents {
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents {
+  background: #ffffff url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;
+}
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.first-child {
+  border-right: 1px solid #cccccc;
+}
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarContainerColumn {
+  margin-left: 5px;
+  margin-right: 35px;
+}
+.dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.first-child {
+  border-right: 1px solid #cccccc;
+}
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .summary {
+  text-align: right;
+}
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .startTime {
+  text-align: right;
+}
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .endTime {
+  text-align: right;
+}
diff --git a/dojox/calendar/themes/iphone/MonthColumnView_rtl.less b/dojox/calendar/themes/iphone/MonthColumnView_rtl.less
new file mode 100644
index 0000000..fbecc7c
--- /dev/null
+++ b/dojox/calendar/themes/iphone/MonthColumnView_rtl.less
@@ -0,0 +1,57 @@
+ at import "ColumnViewCommon.less";
+
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td {
+	border-right: none;	
+	border-left: @inner-border;
+}
+
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td span {
+  padding-right:3px;
+}
+
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable .dojoxCalendarHiddenEvents	{
+	background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;	
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents	{	
+	background: @today-color url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y  right top;	
+}
+
+
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.last-child	{
+	border-left: @outer-border;	
+}
+
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.first-child	{
+	border-right: @outer-border;
+}
+
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarContainerColumn {	
+	margin-left: 5px;
+	margin-right: 35px;
+}
+
+.dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @inner-border;
+	border-right: none;	
+}
+
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-left: @outer-border;	
+}
+
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.first-child {	
+	border-right: @outer-border;	
+}
+ 
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .summary {
+	text-align: right;
+}
+
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .startTime {
+	text-align: right;
+}
+
+.dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .endTime {
+	text-align: right;
+}
diff --git a/dojox/calendar/themes/nihilo/Calendar.css b/dojox/calendar/themes/nihilo/Calendar.css
new file mode 100644
index 0000000..e8baffd
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/Calendar.css
@@ -0,0 +1,27 @@
+ at import url("MatrixView.css");
+
+ at import url("ColumnView.css");
+.nihilo .dojoxCalendar .buttonContainer {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 31px;
+}
+.nihilo .dojoxCalendar .buttonContainer .dijitToolbar {
+  border: 1px solid #B5BCC7;
+}
+.nihilo .dojoxCalendar .viewContainer {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 31px;
+  bottom: 0;
+}
+.nihilo .dojoxCalendar .view {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+}
diff --git a/dojox/calendar/themes/nihilo/Calendar.less b/dojox/calendar/themes/nihilo/Calendar.less
new file mode 100644
index 0000000..66f4fd8
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/Calendar.less
@@ -0,0 +1,33 @@
+ at button-container-height: 31px;
+
+ at import url("MatrixView.css");
+ at import url("ColumnView.css");
+
+.nihilo .dojoxCalendar .buttonContainer{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: @button-container-height;
+}
+
+.nihilo .dojoxCalendar .buttonContainer .dijitToolbar {
+	border: 1px solid #B5BCC7;
+}
+
+.nihilo .dojoxCalendar .viewContainer{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: @button-container-height;
+	bottom: 0;
+}
+
+.nihilo .dojoxCalendar .view{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+}
+
diff --git a/dojox/calendar/themes/nihilo/Calendar_rtl.css b/dojox/calendar/themes/nihilo/Calendar_rtl.css
new file mode 100644
index 0000000..106a1d6
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/Calendar_rtl.css
@@ -0,0 +1,3 @@
+ at import url("MatrixView_rtl.css");
+
+ at import url("ColumnView_rtl.css");
diff --git a/dojox/calendar/themes/nihilo/Calendar_rtl.less b/dojox/calendar/themes/nihilo/Calendar_rtl.less
new file mode 100644
index 0000000..25ef90d
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/Calendar_rtl.less
@@ -0,0 +1,3 @@
+ at import url("MatrixView_rtl.css");
+ at import url("ColumnView_rtl.css");
+
diff --git a/dojox/calendar/themes/nihilo/ColumnView.css b/dojox/calendar/themes/nihilo/ColumnView.css
new file mode 100644
index 0000000..888850d
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/ColumnView.css
@@ -0,0 +1,484 @@
+.nihilo .dojoxCalendarColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarHeader {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 29px;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 72px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #e5e5e5;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+.nihilo .dojoxCalendarColumnView td.hour {
+  border-top: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarColumnView td.halfhour {
+  border-top: dotted 1px #cccccc;
+}
+.nihilo .dojoxCalendarColumnView td.quarterhour {
+  border-top: dotted 1px #cccccc;
+}
+.nihilo .dojoxCalendarColumnView span.hour {
+  color: #293a4b;
+  background-color: #ffffff;
+}
+.nihilo .dojoxCalendarColumnView span.halfhour,
+.nihilo .dojoxCalendarColumnView span.quarterhour {
+  color: #555555;
+  background-color: #ffffff;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff2d2;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff2d2;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #f5f5f5;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #f5f5f5;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  cursor: default;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 2px;
+  margin-right: 9px;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  height: 29px;
+  left: 0;
+  width: 68px;
+  top: 0;
+  border-left: 1px solid #cccccc;
+  border-top: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #cccccc;
+  color: #293a4b;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 70px;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+  border-right: 1px solid #e5e5e5;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+  font-weight: bold;
+  color: #ff2200;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #999999;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background: #f9f9f9 url("images/accordionItemActive.png") top repeat-x;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeader {
+  position: absolute;
+  width: 68px;
+  cursor: default;
+  border-left: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabelContainer {
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel {
+  right: 4px;
+  position: absolute;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td.dummy {
+  border-top: 1px solid #ffffff;
+}
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td {
+  background-color: #ffffff;
+  color: #293a4b;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable tr:first-child td {
+  border-top: 1px solid #ffffff;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td span {
+  padding-right: 4px;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9F0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 72px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 30px;
+  height: 39px;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  bottom: 0;
+  cursor: default;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 70px;
+  bottom: 0;
+  border-right: none;
+  border-left: none;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+  text-align: right;
+  vertical-align: top;
+  border-top: 1px solid #e5e5e5;
+  border-bottom: 1px solid #e5e5e5;
+  border-right: 1px solid #e5e5e5;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td {
+  border-bottom: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+    border: 1px solid #cccccc;
+    border-top-color: #e5e5e5;
+    background-color: #ffffff;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  position: absolute;
+  width: 5px;
+  height: 100%;
+  cursor: e-resize;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+  left: 0;
+  top: 0;
+  width: 100%;
+  cursor: move;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  position: absolute;
+  left: 3px;
+  right: 1px;
+  bottom: 2px;
+  overflow: hidden;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+  right: 0px;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .afterIcon {
+  width: auto;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .endTime {
+  position: relative;
+  bottom: auto;
+  left: auto;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand {
+  position: absolute;
+  text-align: center;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+  position: relative;
+  margin-right: 10%;
+  margin-left: 10%;
+  border-radius: 5px;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  border: 1px solid transparent;
+  -moz-border-radius: 5px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+  background-color: #e5f2fe;
+  border: 1px solid #909da9;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+  background-color: #a5d1fb;
+  border: 1px solid #507ca6;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent div {
+  white-space: nowrap;
+}
diff --git a/dojox/calendar/themes/nihilo/ColumnView.less b/dojox/calendar/themes/nihilo/ColumnView.less
new file mode 100644
index 0000000..b6f193d
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/ColumnView.less
@@ -0,0 +1,518 @@
+ at import "ColumnViewCommon.less";
+
+.nihilo .dojoxCalendarColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarHeader {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: @column-header-height - 1px;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarScrollContainer {
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: @sheet-top;
+	position: absolute;
+	overflow-y: hidden;
+	overflow-x: hidden;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.border-box;
+}
+	
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGrid {
+	position: absolute;
+	left: @row-header-width;
+	right: 0;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable td {
+	border-top: dotted 1px #B5BCC7;	
+	border-right: @inner-border;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td	{
+	border-top: 1px solid transparent;
+}
+
+.nihilo .dojoxCalendarColumnView td.hour {
+	border-top: @hour-stroke;
+}
+
+.nihilo .dojoxCalendarColumnView td.halfhour{
+	border-top: @half-hour-stroke;	
+}
+
+.nihilo .dojoxCalendarColumnView  td.quarterhour{
+	border-top: @quarter-hour-stroke;
+}
+
+.nihilo .dojoxCalendarColumnView span.hour {
+	color: @label-color;
+	background-color: @row-color;
+}
+
+.nihilo .dojoxCalendarColumnView span.halfhour,
+.nihilo .dojoxCalendarColumnView span.quarterhour{
+	color: @secondary-label-color;
+	background-color: @row-color;
+}
+
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+	background-color: @today-color;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable tr td.last-child	{
+	border-right: @outer-border;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday	{
+	border-top: 1px solid @today-color;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend	{
+	border-top: 1px solid @week-end-color;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarContainer {
+	position: absolute;
+	top: 0;
+	left: @row-header-width;
+	right: 0;
+	cursor: default;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarContainerTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarContainerTable td {
+	height: 100%;
+	padding: 0;
+	vertical-align: top;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarContainerColumn {
+	position:	relative;
+	margin-left: 2px;
+	margin-right: 9px;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+	.select-none;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	height: @column-header-height - 1px;
+	left: 0;
+	width: @row-header-width - 2px;
+	top: 0;	
+	border-left: @outer-border;
+	border-top: @outer-border;
+	border-right: @outer-border;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table {
+	position:relative;
+	width:100%;
+	height:100%;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table td {
+	text-align: center;
+	vertical-align: middle;
+	border-bottom: @outer-border;	
+	color: @label-color;
+	.header-background;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeader {
+	position: absolute;
+	height: @column-header-height;	 
+	left: @row-header-width;
+	right: 0;
+	top: 0;
+	cursor: default;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;			
+	width: 100%;
+	height: 100%;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td {	
+	overflow:hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.select-none;
+	color: @label-color;
+	.transition-duration(0.2s);
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-right: @outer-border;	
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+	font-weight: bold;
+	color: @today-label-color;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+	color: @week-end-label-color;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Hover{	
+	cursor: pointer;		
+	.header-hover-background;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Active{	
+	.header-active-background;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeader {
+	position: absolute;
+	width: @row-header-width - 2px;
+	cursor: default;
+	border-left: @outer-border;
+	border-right: @outer-border;
+	height: 100%;
+	.select-none;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabelContainer{
+	width: 100%;
+	height: 100%;
+	z-index: 10;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel{	
+	right: 4px;		
+	position: absolute;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td.dummy{
+	border-top: 1px solid @row-color;
+}
+
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td {	
+	background-color: @row-color;
+	color: @label-color;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable tr:first-child td	{
+	border-top: 1px solid @row-color;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td span {
+	padding-right: 4px;
+}
+ 
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent {
+	position: absolute;	
+	text-align: left;
+	color: #FFF;
+	cursor: default;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .bg {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: -1;
+	border: 1px solid #260000;	
+	.rounded-corners;
+	background-color: #9F0000;
+	.opacity(90);
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent.Hovered .bg {
+	background-color: #CC0000;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent.Selected .bg {
+	background-color: #660000;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent.Edited .bg {
+	border: dashed 1px #FFFFFF;
+	.opacity(70);
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent.Focused .bg {
+	border: dashed 1px #FFFFFF;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .summary {
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .startTime {
+	font-weight: bold;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .endTime {
+	position: absolute;		
+	font-weight: bold;	
+	bottom:3px;
+	left: 6px;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .beforeIcon {
+	text-align: center;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .afterIcon {
+	position: absolute;
+	bottom: 2px;
+	width: 100%;
+	text-align: center;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .handle {
+	.glass-view;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .moveHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	bottom:0;
+	cursor:move;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .resizeStartHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent .resizeEndHandle {
+	position: absolute;
+	bottom:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarVScrollBar {
+	position: absolute;
+	top: @sheet-top;
+	bottom: 0;
+	overflow-y: scroll;
+	overflow-x: hidden;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView {	
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: @column-header-height;
+	height: @secondary-sheet-height;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGrid {	
+	position: absolute;
+	left: @row-header-width;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarContainer {	
+	position: absolute;
+	top: 0;
+	left: @row-header-width;
+	right: 0;
+	bottom: 0;
+	cursor: default;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+	position: absolute;
+	left: 0;				
+	top: 0;
+	width: @row-header-width;
+	bottom: 0;
+	
+	border-right: none;
+	border-left: none;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+	text-align: right;
+	vertical-align: top;	
+	border-top: @inner-border;
+	border-bottom: @inner-border;
+	border-right: @inner-border;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td	{
+	border-bottom: @outer-border;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child	{
+	border-right: @outer-border;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+	border-top: @inner-border;
+	border-left: @outer-border;
+	border-right: @outer-border;
+	border-bottom: @outer-border;
+	background-color: @row-color;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+	.glass-view;
+	position: absolute;
+	width:5px;
+	height:100%;
+	cursor:e-resize;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+	left:0;
+	top:0;
+	width:100%;
+	cursor:move;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	position: absolute;
+	left: 3px;
+	right: 1px;
+	bottom: 2px;
+	overflow: hidden;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle {
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+	right:0px;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .afterIcon {
+	width:auto;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .endTime {
+	position: relative;				
+	bottom:auto;
+	left: auto;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand {
+	position: absolute;
+	text-align: center;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+	position: relative;
+	margin-right: 10%;
+	margin-left: 10%;
+	border-radius: 5px;
+	height: 100%;
+	.select-none;
+	border: 1px solid transparent;
+	-moz-border-radius: 5px;
+	-webkit-transition-duration: 0.2s;
+	-moz-transition-duration: 0.2s;
+	transition-duration: 0.2s;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+	background-color: @expand-up-color;
+	border: 1px solid @expand-up-color - #555555;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+	background-color: @expand-down-color;
+	border: 1px solid @expand-down-color - #555555;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent div {
+	white-space:nowrap;
+}
+
+
diff --git a/dojox/calendar/themes/nihilo/ColumnViewCommon.less b/dojox/calendar/themes/nihilo/ColumnViewCommon.less
new file mode 100644
index 0000000..49064da
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/ColumnViewCommon.less
@@ -0,0 +1,10 @@
+ at import "Common.less";
+
+ at hour-stroke: 1px solid #CCCCCC;
+ at half-hour-stroke: dotted 1px #CCCCCC;
+ at quarter-hour-stroke: dotted 1px #CCCCCC;
+
+ at column-header-height: 30px;
+ at row-header-width: 70px;
+ at secondary-sheet-height: 39px;
+ at sheet-top: @secondary-sheet-height + @column-header-height + 3px;
diff --git a/dojox/calendar/themes/nihilo/ColumnView_rtl.css b/dojox/calendar/themes/nihilo/ColumnView_rtl.css
new file mode 100644
index 0000000..2610be1
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/ColumnView_rtl.css
@@ -0,0 +1,102 @@
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarScrollContainer {
+  border-left: none;
+  border-right: none;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarGrid {
+  left: 0;
+  right: 70px;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarGridTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarContainer {
+  left: 0;
+  right: 70px;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarContainerColumn {
+  margin-right: 1px;
+  margin-left: 9px;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarYearColumnHeader {
+  right: 0;
+  width: 68px;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeader {
+  left: 0;
+  right: 70px;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarRowHeaderLabel {
+  right: auto;
+  left: 4px;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .summary {
+  text-align: right;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .startTime {
+  text-align: right;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .endTime {
+  text-align: right;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarVScrollBar {
+  margin-left: -1px;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+  right: 70px;
+  left: 0;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {
+  text-align: left;
+  border-bottom: 1px solid #e5e5e5;
+  border-left: 1px solid #e5e5e5;
+  border-right: none;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span {
+  padding-left: 2px;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+  right: 70px;
+  left: 0;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  text-align: right;
+  vertical-align: top;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+  right: 70px;
+  left: 0;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+  right: 0;
+  left: auto;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+  right: 0;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+  left: 0;
+  right: auto;
+}
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  text-align: right;
+  right: 2px;
+}
diff --git a/dojox/calendar/themes/nihilo/ColumnView_rtl.less b/dojox/calendar/themes/nihilo/ColumnView_rtl.less
new file mode 100644
index 0000000..6553fcd
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/ColumnView_rtl.less
@@ -0,0 +1,129 @@
+ at import "ColumnViewCommon.less";
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarScrollContainer {	
+	border-left: none;
+	border-right: none;
+}
+	
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarGrid {
+	left: 0;
+	right: @row-header-width;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarGridTable td {
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarContainer {	
+	left: 0;
+	right: @row-header-width;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarContainerColumn {
+	margin-right: 1px;
+	margin-left: 9px;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarYearColumnHeader{
+	right: 0;
+	width: @row-header-width - 2;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeader {
+	left: 0;
+	right: @row-header-width;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarRowHeaderLabel{	
+	right: auto;
+	left: 4px;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .summary {
+	text-align: right;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .startTime {
+	text-align: right;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .endTime {
+	text-align: right;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarVScrollBar { 	
+	margin-left: -1px;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+	right: @row-header-width;
+	left: 0;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {			
+	text-align: left;
+	border-bottom: @inner-border;
+	border-left: @inner-border;
+	border-right: none;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span{
+	padding-left: 2px;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child	{
+	border-left: @outer-border;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+	right: @row-header-width;
+	left: 0;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	text-align: right;
+	vertical-align: top;		
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	right: 0;
+	left: auto;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+	right: @row-header-width;
+	left: 0;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+	right: 0;
+	left: auto;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+	right: 0;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+	left: 0;
+	right: auto;
+}
+
+.nihilo .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	text-align: right;
+	right: 2px;
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/nihilo/Common.less b/dojox/calendar/themes/nihilo/Common.less
new file mode 100755
index 0000000..93c2808
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/Common.less
@@ -0,0 +1,72 @@
+ at outer-border: 1px solid #CCC;
+ at inner-border: 1px solid #E5E5E5;
+
+ at row-color:#FFF;
+ at row-color-hover: #F5F5F5;
+ at row-color-active: #CCC;
+
+ at today-color: #FFF2D2;
+ at today-label-color: #FF2200;
+
+ at week-end-color: #F5F5F5;
+ at week-end-label-color:#999;
+
+ at expand-up-color: #E5F2FE;
+ at expand-down-color: #A5D1FB;
+
+ at label-color: #293A4B;
+ at secondary-label-color: #555;
+
+.border-box(){
+	-webkit-box-sizing: border-box;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.opacity(@op){
+	filter: ~"alpha(opacity=@{op})";	
+	opacity:@op/100;
+}
+
+.transition-duration(@dur: 0s){
+	-webkit-transition-duration: @dur;
+	-moz-transition-duration: @dur;
+	transition-duration: @dur;
+}
+
+.select-none() {
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	khtml-user-select: none;
+	user-select: none;
+}
+
+.glass-view(){
+	z-index: 2;
+	background:#00FF00; 
+	.opacity(0);
+	.select-none
+}
+
+.header-background(){
+	background: #cccccc;
+	background:#fff url("images/titleBar.png") repeat-x top left;
+	padding:3px 4px;
+	font-size: 0.9em;
+	font-weight: bold;
+	color: #6d6d6d;
+}
+
+.header-hover-background(){
+	background: #f9f9f9 url("images/accordionItemActive.png") top repeat-x;
+}
+
+.header-active-background(){
+	cursor: pointer;		
+}
+
+.rounded-corners (@radius: 5px) {
+  border-radius: @radius;
+  -webkit-border-radius: @radius;
+  -moz-border-radius: @radius;
+}
diff --git a/dojox/calendar/themes/nihilo/MatrixView.css b/dojox/calendar/themes/nihilo/MatrixView.css
new file mode 100644
index 0000000..a38be42
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/MatrixView.css
@@ -0,0 +1,364 @@
+.nihilo .dojoxCalendarMatrixView {
+  cursor: default;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGrid {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 30px;
+  bottom: 0px;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+  text-align: right;
+  vertical-align: top;
+  border-bottom: 1px solid #e5e5e5;
+  border-right: 1px solid #e5e5e5;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable td span {
+  padding-right: 2px;
+  padding-top: 2px;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td {
+  border-bottom: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+/* 
+ * The dojoxCalendarColToday & dojoxCalendarColWeekend classes is added by the 
+ * MatrixView.styleGridCell method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable td.dojoxCalendarToday {
+  background-color: #fff2d2;
+  font-weight: bold;
+  color: #ff2200;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #f5f5f5;
+  color: #999999;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarDayDisabled {
+  background-color: #f5f5f5;
+  color: #999999;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  left: 0px;
+  top: 0px;
+  width: 50px;
+  height: 29px;
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid #cccccc;
+  border-top: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+  color: #293a4b;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeader {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 0px;
+  height: 29px;
+  cursor: default;
+  border-bottom: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  vertical-align: middle;
+  text-align: center;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+  border-right: 1px solid #e5e5e5;
+  border-top: 1px solid #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+/* 
+ * The dojoxCalendarColWeekend class is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css class.
+ */
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #999999;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+  position: absolute;
+  left: 0px;
+  top: 30px;
+  width: 50px;
+  bottom: 0;
+  cursor: default;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  border-collapse: collapse;
+  table-layout: fixed;
+  margin: 0;
+  padding: 0;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+/* 
+ * The MatrixView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  border-bottom: 1px solid #e5e5e5;
+  background-color: #ffffff;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  color: #293a4b;
+  cursor: pointer;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.last-child {
+  border-bottom: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Hover {
+  background-color: #f5f5f5;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Active {
+  background-color: #cccccc;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarContainer {
+  position: absolute;
+  top: 30px;
+  left: 50px;
+  right: 0px;
+  bottom: 0px;
+  cursor: default;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarContainerTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarContainerTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarContainerTable td {
+  vertical-align: top;
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarContainerTable td div.dojoxCalendarContainerRow {
+  position: relative;
+  height: 100%;
+  width: 100%;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #000000;
+  cursor: default;
+  white-space: nowrap;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal {
+  color: #FFF;
+  position: absolute;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .bg {
+  border: 1px solid #260000;
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  color: #000000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9f0000;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Hovered .bg {
+  background-color: #cc0000;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Selected .bg {
+  background-color: #660000;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.Edited {
+  color: #fff;
+  font-weight: bold;
+  text-decoration: none;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .bg {
+  border: dashed 1px #FFF;
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Focused .bg {
+  border: dashed 1px #FFF;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Hovered {
+  color: #F40;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Selected {
+  color: #F00;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Edited {
+  border: dashed 1px #FFF;
+  background: #600;
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+  color: #FFF;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Focused {
+  border: dashed 1px #000000;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  position: absolute;
+  left: 3px;
+  right: 1px;
+  bottom: 2px;
+  overflow: hidden;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+  position: absolute;
+  left: 2px;
+  right: 2px;
+  bottom: 0;
+  overflow: hidden;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  position: absolute;
+  width: 5px;
+  height: 100%;
+  cursor: e-resize;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+  left: 0;
+  top: 0;
+  width: 100%;
+  cursor: move;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+  right: 0px;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarExpand {
+  position: absolute;
+  text-align: center;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarExpand span {
+  display: inline-block;
+  vertical-align: middle;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+  position: relative;
+  margin-right: 5px;
+  margin-left: 5px;
+  height: 100%;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  border: 1px solid transparent;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+  background-color: #e5f2fe;
+  border: 1px solid #909da9;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+  background-color: #a5d1fb;
+  border: 1px solid #507ca6;
+}
diff --git a/dojox/calendar/themes/nihilo/MatrixView.less b/dojox/calendar/themes/nihilo/MatrixView.less
new file mode 100644
index 0000000..9186f95
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/MatrixView.less
@@ -0,0 +1,373 @@
+ at import "MatrixViewCommon.less";
+
+.nihilo .dojoxCalendarMatrixView {	
+	cursor: default;
+	.select-none;
+}
+	
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGrid {
+	position: absolute;
+	left: @row-header-width;
+	right: 0px;
+	top: @column-header-height;
+	bottom: 0px;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable {
+	position: relative;
+	width: 100%;
+	height: 100%;	
+	margin: 0;
+	padding: 0;
+	border-collapse: collapse;
+	table-layout: fixed;	
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable tr{
+	.border-box;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+	text-align: right;
+	vertical-align: top;	
+	border-bottom: @inner-border;
+	border-right: @inner-border;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable td span{
+	padding-right: 2px;
+	padding-top: 2px;		
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable td span.FirstVisibleDayOfMonth{	
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td	{
+	border-bottom: @outer-border;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child	{
+	border-right: @outer-border;
+}
+
+/* 
+ * The dojoxCalendarColToday & dojoxCalendarColWeekend classes is added by the 
+ * MatrixView.styleGridCell method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable td.dojoxCalendarToday	{
+	background-color: @today-color;		
+	font-weight: bold;
+	color: @today-label-color;
+}
+			
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+	color: @week-end-label-color;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarDayDisabled {
+	background-color: @disabled-day-color;
+	color: @disabled-day-label-color;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	left: 0px;
+	top: 0px;
+	width: @row-header-width;
+	height: @column-header-height - 1px;
+	text-align: center;
+	vertical-align: middle;
+	border-bottom: @outer-border;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table{
+	position: relative;		
+	width:100%;
+	height: 100%;
+	table-layout: fixed;
+	border-collapse: collapse;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table td{
+	text-align: center;
+	vertical-align: middle;		
+	border-left: @outer-border;
+	border-top: @outer-border;
+	border-right: @outer-border;
+	.header-background;
+	color: @label-color;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeader {
+	position: absolute;
+	left: @row-header-width;
+	right: 0px;
+	top: 0px;
+	height: @column-header-height - 1px;
+	cursor: default;
+	border-bottom: @outer-border;	
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable {
+	position: relative;		
+	width:100%;
+	height: 100%;
+	table-layout: fixed;
+	border-collapse: collapse;		
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+	overflow:hidden;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	.select-none;
+	color: @label-color;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td.last-child {
+	border-right: @outer-border;
+}
+
+/* 
+ * The dojoxCalendarColWeekend class is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css class.
+ */
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+	color: @week-end-label-color;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+	position: absolute;
+	left: 0px;				
+	top: @column-header-height;
+	width: @row-header-width;
+	bottom: 0;
+	cursor: default;
+	
+	.select-none;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable {
+	position: relative;			
+	width: 100%;
+	height: 100%;
+	border-collapse: collapse;
+	table-layout: fixed;
+	margin: 0;
+	padding: 0;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable tr{
+	.border-box;
+}
+
+/* 
+ * The MatrixView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+	text-align: center;
+	vertical-align: middle;	
+	border-left: @outer-border;
+	border-right: @outer-border;
+	border-bottom: @inner-border;
+	background-color: @row-color;
+	.transition-duration(0.2s);
+	.border-box;
+	color: @label-color;
+	cursor: pointer;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.last-child {
+	border-bottom: @outer-border;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Hover {
+	background-color: @row-color-hover;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Active {
+	background-color: @row-color-active;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarContainer {
+	position: absolute;
+	top: @column-header-height;
+	left: @row-header-width;
+	right: 0px;
+	bottom: 0px;
+	cursor: default;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarContainerTable {
+	position: relative;
+	width: 100%;
+	height: 100%;	
+	margin: 0;
+	padding: 0;
+	border-collapse: collapse;
+	table-layout: fixed;	
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarContainerTable tr{
+	.border-box;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarContainerTable td{
+	vertical-align: top;
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarContainerTable td div.dojoxCalendarContainerRow{
+	position:relative;
+	height:100%;
+	width:100%;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+ 	.select-none;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent {	
+	position: absolute;
+	text-align: left;
+	color: #000000;
+	cursor: default;
+	white-space: nowrap;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal {
+	color: #FFF;
+	position: absolute;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .bg {
+	border: @horizontal-border;	
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;	
+	color: #000000;	
+	.rounded-corners(5px);
+	background-color: @horizontal-color;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Hovered  .bg {
+	background-color: @horizontal-hover-color;	
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Selected .bg {
+	background-color: @horizontal-selected-bg-color;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.Edited {
+	color: #fff;
+	font-weight: bold;
+	text-decoration: none;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .bg {
+	border: dashed 1px #FFF;
+	.opacity(30);
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Focused .bg {
+	border: dashed 1px #FFF;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Hovered {
+	color: #F40;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Selected {
+	color: #F00;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Edited {
+	border: dashed 1px #FFF;
+	background: #600;
+	.opacity(30);
+	color: #FFF;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Focused {
+	border: dashed 1px #000000;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	position: absolute;
+	left: 3px;
+	right: 1px;
+	bottom: 2px;
+	overflow: hidden;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+	position: absolute;
+	left: 2px;
+	right: 2px;
+	bottom: 0;
+	overflow: hidden;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+	.glass-view;
+	position: absolute;
+	width:5px;
+	height:100%;
+	cursor:e-resize;	
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+	left:0;
+	top:0;
+	width:100%;
+	cursor:move;	
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle {
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+	right:0px;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarExpand {
+	position: absolute;
+	text-align: center;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarExpand span {
+	display: inline-block;
+	vertical-align: middle;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+	position: relative;
+	margin-right: 5px;
+	margin-left: 5px;
+	height: 100%;
+	.rounded-corners(5px);
+	.transition-duration(0.2s);
+	.border-box;	
+	border: 1px solid transparent;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+	background-color: @expand-up-color;
+	border: 1px solid @expand-up-color - #555555;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+	background-color: @expand-down-color;
+	border: 1px solid @expand-down-color - #555555;
+}
diff --git a/dojox/calendar/themes/nihilo/MatrixViewCommon.less b/dojox/calendar/themes/nihilo/MatrixViewCommon.less
new file mode 100644
index 0000000..50f89db
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/MatrixViewCommon.less
@@ -0,0 +1,12 @@
+ at import "Common.less";
+
+ at disabled-day-color: #F5F5F5;
+ at disabled-day-label-color: #999999;
+
+ at horizontal-color: #9F0000;
+ at horizontal-hover-color: #CC0000;
+ at horizontal-selected-bg-color: #660000;
+ at horizontal-border: 1px solid #260000;
+
+ at column-header-height: 30px;
+ at row-header-width: 50px;
diff --git a/dojox/calendar/themes/nihilo/MatrixView_rtl.css b/dojox/calendar/themes/nihilo/MatrixView_rtl.css
new file mode 100644
index 0000000..639d9ea
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/MatrixView_rtl.css
@@ -0,0 +1,56 @@
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+  right: 50px;
+  left: 0;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {
+  text-align: left;
+  border-bottom: 1px solid #e5e5e5;
+  border-left: 1px solid #e5e5e5;
+  border-right: none;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span {
+  padding-left: 2px;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+  right: 50px;
+  left: 0;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  text-align: right;
+  vertical-align: top;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+  right: 50px;
+  left: 0;
+}
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+  right: 0;
+  left: auto;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  text-align: right;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+  text-align: right;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+  right: 0;
+}
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+  left: 0;
+  right: auto;
+}
diff --git a/dojox/calendar/themes/nihilo/MatrixView_rtl.less b/dojox/calendar/themes/nihilo/MatrixView_rtl.less
new file mode 100644
index 0000000..0c61741
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/MatrixView_rtl.less
@@ -0,0 +1,71 @@
+ at import "MatrixViewCommon.less";
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+	right: @row-header-width;
+	left: 0;
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {			
+	text-align: left;
+	border-bottom: @inner-border;
+	border-left: @inner-border;
+	border-right: none;
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span{
+	padding-left: 2px;
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child	{
+	border-left: @outer-border;
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+	right: @row-header-width;
+	left: 0;
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	text-align: right;
+	vertical-align: top;		
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	right: 0;
+	left: auto;
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+	right: @row-header-width;
+	left: 0;
+}
+
+.nihilo .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+	right: 0;
+	left: auto;
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	text-align: right;
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+	text-align: right;
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+	right: 0;
+}
+
+.nihilo .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+	left:0;
+	right:auto;
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/nihilo/MonthColumnView.css b/dojox/calendar/themes/nihilo/MonthColumnView.css
new file mode 100644
index 0000000..82b9acb
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/MonthColumnView.css
@@ -0,0 +1,261 @@
+.nihilo .dojoxCalendarMonthColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 30px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-bottom: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGrid {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #e5e5e5;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td span {
+  padding-left: 3px;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff2d2;
+  font-weight: bold;
+  color: #ff2200;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarHiddenEvents {
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents {
+  background: #fff2d2 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.first-child {
+  border-left: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff2d2;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #f5f5f5;
+  color: #999999;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #f5f5f5;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  cursor: default;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 35px;
+  margin-right: 5px;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 0;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+  border-right: 1px solid #e5e5e5;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.first-child {
+  border-left: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background: #f9f9f9 url("images/accordionItemActive.png") top repeat-x;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+  overflow: hidden;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9F0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 30px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/nihilo/MonthColumnView.less b/dojox/calendar/themes/nihilo/MonthColumnView.less
new file mode 100644
index 0000000..cc41e52
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/MonthColumnView.less
@@ -0,0 +1,281 @@
+ at import "ColumnViewCommon.less";
+
+.nihilo .dojoxCalendarMonthColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarScrollContainer {
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: @column-header-height;
+	position: absolute;
+	overflow-y: hidden;
+	overflow-x: hidden;	
+	border-bottom: @outer-border;
+	.border-box;
+}
+	
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGrid {
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td {
+	border-top: dotted 1px #B5BCC7;	
+	border-right: @inner-border;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td span {
+  padding-left:3px;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td	{
+	border-top: 1px solid transparent;
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+	background-color: @today-color;
+	font-weight: bold;
+	color: @today-label-color;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarHiddenEvents	{	
+	background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;	
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents	{	
+	background: @today-color url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;	
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.last-child	{
+	border-right: @outer-border;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.first-child	{
+	border-left: @outer-border;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday	{
+	border-top: 1px solid @today-color;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+	color: @week-end-label-color;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend	{
+	border-top: 1px solid @week-end-color;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarContainer {
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+	cursor: default;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable td {
+	height: 100%;
+	padding: 0;
+	vertical-align: top;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarContainerColumn {
+	position:	relative;
+	margin-left: 35px;
+	margin-right: 5px;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+	.select-none;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeader {
+	position: absolute;
+	height: @column-header-height;	 
+	left: 0;
+	right: 0;
+	top: 0;
+	cursor: default;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;			
+	width: 100%;
+	height: 100%;	
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {	
+	overflow:hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.select-none;
+	color: @label-color;
+	.transition-duration(0.2s);
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-right: @outer-border;	
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.first-child {	
+	border-left: @outer-border;	
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Hover{	
+	cursor: pointer;		
+	.header-hover-background;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Active{	
+	.header-active-background;
+}
+ 
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent {
+	position: absolute;	
+	text-align: left;
+	color: #FFF;
+	cursor: default;
+	overflow: hidden;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .bg {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: -1;
+	border: 1px solid #260000;	
+	.rounded-corners;
+	background-color: #9F0000;
+	.opacity(90);
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Hovered .bg {
+	background-color: #CC0000;	
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Selected .bg {
+	background-color: #660000;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Edited .bg {
+	border: dashed 1px #FFFFFF;
+	.opacity(70);
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Focused .bg {
+	border: dashed 1px #FFFFFF;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .summary {
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .startTime {
+	font-weight: bold;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .endTime {
+	position: absolute;		
+	font-weight: bold;	
+	bottom:3px;
+	left: 6px;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .beforeIcon {
+	text-align: center;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .afterIcon {
+	position: absolute;
+	bottom: 2px;
+	width: 100%;
+	text-align: center;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .handle {
+	.glass-view;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .moveHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	bottom:0;
+	cursor:move;	
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeStartHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeEndHandle {
+	position: absolute;
+	bottom:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarVScrollBar {
+	position: absolute;
+	top: @column-header-height;
+	bottom: 0;
+	overflow-y: scroll;
+	overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/nihilo/MonthColumnViewCommon.less b/dojox/calendar/themes/nihilo/MonthColumnViewCommon.less
new file mode 100644
index 0000000..9bb3ec8
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/MonthColumnViewCommon.less
@@ -0,0 +1,7 @@
+ at import "Common.less";
+
+ at hour-stroke: 1px solid #C7BEBE;
+ at half-hour-stroke: dotted 1px #C7BEBE;
+ at quarter-hour-stroke: dotted 1px #C7BEBE;
+
+ at column-header-height: 30px;
diff --git a/dojox/calendar/themes/nihilo/MonthColumnView_rtl.css b/dojox/calendar/themes/nihilo/MonthColumnView_rtl.css
new file mode 100644
index 0000000..a9dc249
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/MonthColumnView_rtl.css
@@ -0,0 +1,42 @@
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td {
+  border-right: none;
+  border-left: 1px solid #e5e5e5;
+}
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td span {
+  padding-right: 3px;
+}
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable .dojoxCalendarHiddenEvents {
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents {
+  background: #fff2d2 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;
+}
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.first-child {
+  border-right: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarContainerColumn {
+  margin-left: 5px;
+  margin-right: 35px;
+}
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #e5e5e5;
+  border-right: none;
+}
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.first-child {
+  border-right: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .summary {
+  text-align: right;
+}
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .startTime {
+  text-align: right;
+}
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .endTime {
+  text-align: right;
+}
diff --git a/dojox/calendar/themes/nihilo/MonthColumnView_rtl.less b/dojox/calendar/themes/nihilo/MonthColumnView_rtl.less
new file mode 100644
index 0000000..fedc233
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/MonthColumnView_rtl.less
@@ -0,0 +1,56 @@
+ at import "ColumnViewCommon.less";
+
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td {
+	border-right: none;	
+	border-left: @inner-border;
+}
+
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td span {
+  padding-right:3px;
+}
+
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable .dojoxCalendarHiddenEvents	{
+	background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;	
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents	{	
+	background: @today-color url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y  right top;	
+}
+
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.last-child	{
+	border-left: @outer-border;	
+}
+
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.first-child	{
+	border-right: @outer-border;
+}
+
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarContainerColumn {	
+	margin-left: 5px;
+	margin-right: 35px;
+}
+
+.nihilo .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @inner-border;
+	border-right: none;	
+}
+
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-left: @outer-border;	
+}
+
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.first-child {	
+	border-right: @outer-border;	
+}
+ 
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .summary {
+	text-align: right;
+}
+
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .startTime {
+	text-align: right;
+}
+
+.nihilo .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .endTime {
+	text-align: right;
+}
diff --git a/dojox/calendar/themes/nihilo/SimpleColumnView.css b/dojox/calendar/themes/nihilo/SimpleColumnView.css
new file mode 100644
index 0000000..6a779e7
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/SimpleColumnView.css
@@ -0,0 +1,356 @@
+.nihilo .dojoxCalendarSimpleColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarHeader {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 29px;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 30px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #e5e5e5;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+.nihilo .dojoxCalendarColumnView td.hour {
+  border-top: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarColumnView td.halfhour {
+  border-top: dotted 1px #cccccc;
+}
+.nihilo .dojoxCalendarColumnView td.quarterhour {
+  border-top: dotted 1px #cccccc;
+}
+.nihilo .dojoxCalendarColumnView span.hour {
+  color: #293a4b;
+  background-color: #ffffff;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff2d2;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff2d2;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #f5f5f5;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #f5f5f5;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  cursor: default;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 2px;
+  margin-right: 9px;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  height: 29px;
+  left: 0;
+  width: 68px;
+  top: 0;
+  border-left: 1px solid #cccccc;
+  border-top: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #cccccc;
+  color: #293a4b;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 70px;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+  border-right: 1px solid #e5e5e5;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+  font-weight: bold;
+  color: #ff2200;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #999999;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background: #f9f9f9 url("images/accordionItemActive.png") top repeat-x;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeader {
+  position: absolute;
+  width: 68px;
+  cursor: default;
+  border-left: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel {
+  right: 4px;
+  position: absolute;
+}
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td.dummy {
+  border-top: 1px solid #ffffff;
+}
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td {
+  vertical-align: top;
+  text-align: right;
+  border-top: 1px solid #cccccc;
+  background-color: #ffffff;
+  color: #293a4b;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable tr:first-child td {
+  border-top: 1px solid #ffffff;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9F0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 30px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/nihilo/SimpleColumnView.less b/dojox/calendar/themes/nihilo/SimpleColumnView.less
new file mode 100644
index 0000000..ebde553
--- /dev/null
+++ b/dojox/calendar/themes/nihilo/SimpleColumnView.less
@@ -0,0 +1,382 @@
+ at import "ColumnViewCommon.less";
+
+ at row-header-width: 70px;
+ at secondary-sheet-height: 0px;
+ at sheet-top: @column-header-height;
+
+.nihilo .dojoxCalendarSimpleColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarHeader {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: @column-header-height - 1px;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarScrollContainer {
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: @sheet-top;
+	position: absolute;
+	overflow-y: hidden;
+	overflow-x: hidden;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.border-box;
+}
+	
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGrid {
+	position: absolute;
+	left: @row-header-width;
+	right: 0;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable td {
+	border-top: dotted 1px #B5BCC7;	
+	border-right: @inner-border;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td	{
+	border-top: 1px solid transparent;
+}
+
+.nihilo .dojoxCalendarColumnView td.hour {
+	border-top: @hour-stroke;
+}
+
+.nihilo .dojoxCalendarColumnView td.halfhour{
+	border-top: @half-hour-stroke;	
+}
+
+.nihilo .dojoxCalendarColumnView  td.quarterhour{
+	border-top: @quarter-hour-stroke;
+}
+
+.nihilo .dojoxCalendarColumnView span.hour {
+	color: @label-color;
+	background-color: @row-color;
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+	background-color: @today-color;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr td.last-child	{
+	border-right: @outer-border;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday	{
+	border-top: 1px solid @today-color;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend	{
+	border-top: 1px solid @week-end-color;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarContainer {
+	position: absolute;
+	top: 0;
+	left: @row-header-width;
+	right: 0;
+	cursor: default;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable td {
+	height: 100%;
+	padding: 0;
+	vertical-align: top;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarContainerColumn {
+	position:	relative;
+	margin-left: 2px;
+	margin-right: 9px;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+	.select-none;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	height: @column-header-height - 1px;
+	left: 0;
+	width: @row-header-width - 2px;
+	top: 0;	
+	border-left: @outer-border;
+	border-top: @outer-border;
+	border-right: @outer-border;	
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table {
+	position:relative;
+	width:100%;
+	height:100%;	
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table td {
+	text-align: center;
+	vertical-align: middle;
+	border-bottom: @outer-border;	
+	color: @label-color;
+	.header-background;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeader {
+	position: absolute;
+	height: @column-header-height;	 
+	left: @row-header-width;
+	right: 0;
+	top: 0;
+	cursor: default;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;			
+	width: 100%;
+	height: 100%;	
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td {	
+	overflow:hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.select-none;
+	color: @label-color;
+	.transition-duration(0.2s);
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-right: @outer-border;	
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+	font-weight: bold;
+	color: @today-label-color;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+	color: @week-end-label-color;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Hover{	
+	cursor: pointer;		
+	.header-hover-background;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Active{	
+	.header-active-background;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeader {
+	position: absolute;
+	width: @row-header-width - 2px;
+	cursor: default;
+	border-left: @outer-border;
+	border-right: @outer-border;
+	height: 100%;
+	.select-none;
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel{	
+	right: 4px;		
+	position: absolute;	
+}
+
+.nihilo .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td.dummy{
+	border-top: 1px solid @row-color;
+}
+
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td {	
+	vertical-align: top;			
+	text-align: right;	
+	border-top: @outer-border; 	
+	background-color: @row-color;
+	color: @label-color;
+	.border-box;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable tr:first-child td	{
+	border-top: 1px solid @row-color;
+}
+ 
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent {
+	position: absolute;	
+	text-align: left;
+	color: #FFF;
+	cursor: default;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .bg {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: -1;
+	border: 1px solid #260000;	
+	.rounded-corners;
+	background-color: #9F0000;
+	.opacity(90);
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Hovered .bg {
+	background-color: #CC0000;	
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Selected .bg {
+	background-color: #660000;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Edited .bg {
+	border: dashed 1px #FFFFFF;
+	.opacity(70);
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Focused .bg {
+	border: dashed 1px #FFFFFF;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .summary {
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .startTime {
+	font-weight: bold;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .endTime {
+	position: absolute;		
+	font-weight: bold;	
+	bottom:3px;
+	left: 6px;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .beforeIcon {
+	text-align: center;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .afterIcon {
+	position: absolute;
+	bottom: 2px;
+	width: 100%;
+	text-align: center;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .handle {
+	.glass-view;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .moveHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	bottom:0;
+	cursor:move;	
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeStartHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeEndHandle {
+	position: absolute;
+	bottom:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.nihilo .dojoxCalendarSimpleColumnView .dojoxCalendarVScrollBar {
+	position: absolute;
+	top: @sheet-top;
+	bottom: 0;
+	overflow-y: scroll;
+	overflow-x: hidden;
+}
+
+
diff --git a/dijit/themes/nihilo/images/accordionItemActive.png b/dojox/calendar/themes/nihilo/images/accordionItemActive.png
similarity index 100%
copy from dijit/themes/nihilo/images/accordionItemActive.png
copy to dojox/calendar/themes/nihilo/images/accordionItemActive.png
diff --git a/dijit/themes/nihilo/images/titleBar.png b/dojox/calendar/themes/nihilo/images/titleBar.png
similarity index 100%
copy from dijit/themes/nihilo/images/titleBar.png
copy to dojox/calendar/themes/nihilo/images/titleBar.png
diff --git a/dojox/calendar/themes/soria/Calendar.css b/dojox/calendar/themes/soria/Calendar.css
new file mode 100644
index 0000000..658462f
--- /dev/null
+++ b/dojox/calendar/themes/soria/Calendar.css
@@ -0,0 +1,27 @@
+ at import url("MatrixView.css");
+
+ at import url("ColumnView.css");
+.soria .dojoxCalendar .buttonContainer {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 31px;
+}
+.soria .dojoxCalendar .buttonContainer .dijitToolbar {
+  border: 1px solid #B5BCC7;
+}
+.soria .dojoxCalendar .viewContainer {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 31px;
+  bottom: 0;
+}
+.soria .dojoxCalendar .view {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+}
diff --git a/dojox/calendar/themes/soria/Calendar.less b/dojox/calendar/themes/soria/Calendar.less
new file mode 100644
index 0000000..d7bbff3
--- /dev/null
+++ b/dojox/calendar/themes/soria/Calendar.less
@@ -0,0 +1,33 @@
+ at button-container-height: 31px;
+
+ at import url("MatrixView.css");
+ at import url("ColumnView.css");
+
+.soria .dojoxCalendar .buttonContainer{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: @button-container-height;
+}
+
+.soria .dojoxCalendar .buttonContainer .dijitToolbar {
+	border: 1px solid #B5BCC7;
+}
+
+.soria .dojoxCalendar .viewContainer{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: @button-container-height;
+	bottom: 0;
+}
+
+.soria .dojoxCalendar .view{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+}
+
diff --git a/dojox/calendar/themes/soria/Calendar_rtl.css b/dojox/calendar/themes/soria/Calendar_rtl.css
new file mode 100644
index 0000000..106a1d6
--- /dev/null
+++ b/dojox/calendar/themes/soria/Calendar_rtl.css
@@ -0,0 +1,3 @@
+ at import url("MatrixView_rtl.css");
+
+ at import url("ColumnView_rtl.css");
diff --git a/dojox/calendar/themes/soria/Calendar_rtl.less b/dojox/calendar/themes/soria/Calendar_rtl.less
new file mode 100644
index 0000000..25ef90d
--- /dev/null
+++ b/dojox/calendar/themes/soria/Calendar_rtl.less
@@ -0,0 +1,3 @@
+ at import url("MatrixView_rtl.css");
+ at import url("ColumnView_rtl.css");
+
diff --git a/dojox/calendar/themes/soria/ColumnView.css b/dojox/calendar/themes/soria/ColumnView.css
new file mode 100644
index 0000000..aefd59a
--- /dev/null
+++ b/dojox/calendar/themes/soria/ColumnView.css
@@ -0,0 +1,481 @@
+.soria .dojoxCalendarColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarHeader {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 29px;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 72px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-top: 1px solid #b1badf;
+  border-bottom: 1px solid #b1badf;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #bfbfbf;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+.soria .dojoxCalendarColumnView td.hour {
+  border-top: 1px solid #cccccc;
+}
+.soria .dojoxCalendarColumnView td.halfhour {
+  border-top: dotted 1px #cccccc;
+}
+.soria .dojoxCalendarColumnView td.quarterhour {
+  border-top: dotted 1px #cccccc;
+}
+.soria .dojoxCalendarColumnView span.hour {
+  color: #293a4b;
+  background-color: #fdfdfd;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff2d2;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #b1badf;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff2d2;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #fdfdfd;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #fdfdfd;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  cursor: default;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 2px;
+  margin-right: 9px;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  height: 29px;
+  left: 0;
+  width: 68px;
+  top: 0;
+  border-left: 1px solid #b1badf;
+  border-top: 1px solid #b1badf;
+  border-right: 1px solid #b1badf;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #b1badf;
+  color: #293a4b;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 70px;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+  border-right: 1px solid #bfbfbf;
+  border-top: 1px solid #b1badf;
+  border-bottom: 1px solid #b1badf;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #b1badf;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+  font-weight: bold;
+  color: #ff2200;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #999999;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background: #f9f9f9 url("images/accordionItemActive.png") top repeat-x;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeader {
+  position: absolute;
+  width: 68px;
+  cursor: default;
+  border-left: 1px solid #b1badf;
+  border-right: 1px solid #b1badf;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabelContainer {
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel {
+  right: 4px;
+  position: absolute;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td.dummy {
+  border-top: 1px solid #fdfdfd;
+}
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td {
+  background-color: #fdfdfd;
+  color: #293a4b;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable tr:first-child td {
+  border-top: 1px solid #fdfdfd;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td span {
+  padding-right: 4px;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9F0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 72px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 30px;
+  height: 39px;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  bottom: 0;
+  cursor: default;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 70px;
+  bottom: 0;
+  border-right: none;
+  border-left: none;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+  text-align: right;
+  vertical-align: top;
+  border-top: 1px solid #bfbfbf;
+  border-bottom: 1px solid #bfbfbf;
+  border-right: 1px solid #bfbfbf;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td {
+  border-bottom: 1px solid #b1badf;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child {
+  border-right: 1px solid #b1badf;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+  border-top: 1px solid #bfbfbf;
+  border-left: 1px solid #b1badf;
+  border-right: 1px solid #b1badf;
+  border-bottom: 1px solid #b1badf;
+  background-color: #fdfdfd;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  position: absolute;
+  width: 5px;
+  height: 100%;
+  cursor: e-resize;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+  left: 0;
+  top: 0;
+  width: 100%;
+  cursor: move;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  position: absolute;
+  left: 3px;
+  right: 1px;
+  bottom: 2px;
+  overflow: hidden;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+  right: 0px;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .afterIcon {
+  width: auto;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .endTime {
+  position: relative;
+  bottom: auto;
+  left: auto;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand {
+  position: absolute;
+  text-align: center;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+  position: relative;
+  margin-right: 10%;
+  margin-left: 10%;
+  border-radius: 5px;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  border: 1px solid transparent;
+  -moz-border-radius: 5px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+  background-color: #e5f2fe;
+  border: 1px solid #909da9;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+  background-color: #a5d1fb;
+  border: 1px solid #507ca6;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent div {
+  white-space: nowrap;
+}
diff --git a/dojox/calendar/themes/soria/ColumnView.less b/dojox/calendar/themes/soria/ColumnView.less
new file mode 100644
index 0000000..e5a4b18
--- /dev/null
+++ b/dojox/calendar/themes/soria/ColumnView.less
@@ -0,0 +1,511 @@
+ at import "ColumnViewCommon.less";
+
+.soria .dojoxCalendarColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarHeader {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: @column-header-height - 1px;
+	.border-box;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarScrollContainer {
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: @sheet-top;
+	position: absolute;
+	overflow-y: hidden;
+	overflow-x: hidden;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.border-box;
+}
+	
+.soria .dojoxCalendarColumnView .dojoxCalendarGrid {
+	position: absolute;
+	left: @row-header-width;
+	right: 0;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable td {
+	border-top: dotted 1px #B5BCC7;	
+	border-right: @inner-border;
+	.border-box;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td	{
+	border-top: 1px solid transparent;
+}
+
+.soria .dojoxCalendarColumnView td.hour {
+	border-top: @hour-stroke;
+}
+
+.soria .dojoxCalendarColumnView td.halfhour{
+	border-top: @half-hour-stroke;	
+}
+
+.soria .dojoxCalendarColumnView  td.quarterhour{
+	border-top: @quarter-hour-stroke;
+}
+
+.soria .dojoxCalendarColumnView span.hour {
+	color: @label-color;
+	background-color: @row-color;
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+	background-color: @today-color;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable tr td.last-child	{
+	border-right: @outer-border;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday	{
+	border-top: 1px solid @today-color;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend	{
+	border-top: 1px solid @week-end-color;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarContainer {
+	position: absolute;
+	top: 0;
+	left: @row-header-width;
+	right: 0;
+	cursor: default;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarContainerTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarContainerTable td {
+	height: 100%;
+	padding: 0;
+	vertical-align: top;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarContainerColumn {
+	position:	relative;
+	margin-left: 2px;
+	margin-right: 9px;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+	.select-none;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	height: @column-header-height - 1px;
+	left: 0;
+	width: @row-header-width - 2px;
+	top: 0;	
+	border-left: @outer-border;
+	border-top: @outer-border;
+	border-right: @outer-border;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table {
+	position:relative;
+	width:100%;
+	height:100%;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table td {
+	text-align: center;
+	vertical-align: middle;
+	border-bottom: @outer-border;	
+	color: @label-color;
+	.header-background;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeader {
+	position: absolute;
+	height: @column-header-height;	 
+	left: @row-header-width;
+	right: 0;
+	top: 0;
+	cursor: default;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;			
+	width: 100%;
+	height: 100%;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td {	
+	overflow:hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.select-none;
+	color: @label-color;
+	.transition-duration(0.2s);
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-right: @outer-border;	
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+	font-weight: bold;
+	color: @today-label-color;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+	color: @week-end-label-color;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Hover{	
+	cursor: pointer;		
+	.header-hover-background;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Active{	
+	.header-active-background;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeader {
+	position: absolute;
+	width: @row-header-width - 2px;
+	cursor: default;
+	border-left: @outer-border;
+	border-right: @outer-border;
+	height: 100%;
+	.select-none;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabelContainer{
+	width: 100%;
+	height: 100%;
+	z-index: 10;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel{	
+	right: 4px;		
+	position: absolute;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td.dummy{
+	border-top: 1px solid @row-color;
+}
+
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td {	
+	background-color: @row-color;
+	color: @label-color;
+	.border-box;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable tr:first-child td	{
+	border-top: 1px solid @row-color;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td span {
+	padding-right: 4px;
+}
+ 
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent {
+	position: absolute;	
+	text-align: left;
+	color: #FFF;
+	cursor: default;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .bg {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: -1;
+	border: 1px solid #260000;	
+	.rounded-corners;
+	background-color: #9F0000;
+	.opacity(90);
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent.Hovered .bg {
+	background-color: #CC0000;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent.Selected .bg {
+	background-color: #660000;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent.Edited .bg {
+	border: dashed 1px #FFFFFF;
+	.opacity(70);
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent.Focused .bg {
+	border: dashed 1px #FFFFFF;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .summary {
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .startTime {
+	font-weight: bold;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .endTime {
+	position: absolute;		
+	font-weight: bold;	
+	bottom:3px;
+	left: 6px;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .beforeIcon {
+	text-align: center;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .afterIcon {
+	position: absolute;
+	bottom: 2px;
+	width: 100%;
+	text-align: center;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .handle {
+	.glass-view;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .moveHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	bottom:0;
+	cursor:move;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .resizeStartHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent .resizeEndHandle {
+	position: absolute;
+	bottom:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarVScrollBar {
+	position: absolute;
+	top: @sheet-top;
+	bottom: 0;
+	overflow-y: scroll;
+	overflow-x: hidden;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView {	
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: @column-header-height;
+	height: @secondary-sheet-height;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGrid {	
+	position: absolute;
+	left: @row-header-width;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	.border-box;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarContainer {	
+	position: absolute;
+	top: 0;
+	left: @row-header-width;
+	right: 0;
+	bottom: 0;
+	cursor: default;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+	position: absolute;
+	left: 0;				
+	top: 0;
+	width: @row-header-width;
+	bottom: 0;
+	
+	border-right: none;
+	border-left: none;
+	.border-box;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+	text-align: right;
+	vertical-align: top;	
+	border-top: @inner-border;
+	border-bottom: @inner-border;
+	border-right: @inner-border;
+	.border-box;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td	{
+	border-bottom: @outer-border;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child	{
+	border-right: @outer-border;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+	border-top: @inner-border;
+	border-left: @outer-border;
+	border-right: @outer-border;
+	border-bottom: @outer-border;
+	background-color: @row-color;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+	.glass-view;
+	position: absolute;
+	width:5px;
+	height:100%;
+	cursor:e-resize;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+	left:0;
+	top:0;
+	width:100%;
+	cursor:move;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	position: absolute;
+	left: 3px;
+	right: 1px;
+	bottom: 2px;
+	overflow: hidden;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle {
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+	right:0px;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .afterIcon {
+	width:auto;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .endTime {
+	position: relative;				
+	bottom:auto;
+	left: auto;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand {
+	position: absolute;
+	text-align: center;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+	position: relative;
+	margin-right: 10%;
+	margin-left: 10%;
+	border-radius: 5px;
+	height: 100%;
+	.select-none;
+	border: 1px solid transparent;
+	-moz-border-radius: 5px;
+	-webkit-transition-duration: 0.2s;
+	-moz-transition-duration: 0.2s;
+	transition-duration: 0.2s;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+	background-color: @expand-up-color;
+	border: 1px solid @expand-up-color - #555555;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+	background-color: @expand-down-color;
+	border: 1px solid @expand-down-color - #555555;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent div {
+	white-space:nowrap;
+}
+
+
diff --git a/dojox/calendar/themes/soria/ColumnViewCommon.less b/dojox/calendar/themes/soria/ColumnViewCommon.less
new file mode 100644
index 0000000..49064da
--- /dev/null
+++ b/dojox/calendar/themes/soria/ColumnViewCommon.less
@@ -0,0 +1,10 @@
+ at import "Common.less";
+
+ at hour-stroke: 1px solid #CCCCCC;
+ at half-hour-stroke: dotted 1px #CCCCCC;
+ at quarter-hour-stroke: dotted 1px #CCCCCC;
+
+ at column-header-height: 30px;
+ at row-header-width: 70px;
+ at secondary-sheet-height: 39px;
+ at sheet-top: @secondary-sheet-height + @column-header-height + 3px;
diff --git a/dojox/calendar/themes/soria/ColumnView_rtl.css b/dojox/calendar/themes/soria/ColumnView_rtl.css
new file mode 100644
index 0000000..80af990
--- /dev/null
+++ b/dojox/calendar/themes/soria/ColumnView_rtl.css
@@ -0,0 +1,102 @@
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarScrollContainer {
+  border-left: none;
+  border-right: none;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarGrid {
+  left: 0;
+  right: 70px;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarGridTable td {
+  border-left: 1px solid #b1badf;
+  border-right: none;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarContainer {
+  left: 0;
+  right: 68px;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarContainerColumn {
+  margin-right: 1px;
+  margin-left: 9px;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarYearColumnHeader {
+  right: 0;
+  width: 70px;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeader {
+  left: 0;
+  right: 70px;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #b1badf;
+  border-right: none;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarRowHeaderLabel {
+  right: auto;
+  left: 4px;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .summary {
+  text-align: right;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .startTime {
+  text-align: right;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .endTime {
+  text-align: right;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarVScrollBar {
+  margin-left: -1px;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+  right: 70px;
+  left: 0;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {
+  text-align: left;
+  border-bottom: 1px solid #bfbfbf;
+  border-left: 1px solid #bfbfbf;
+  border-right: none;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span {
+  padding-left: 2px;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child {
+  border-left: 1px solid #b1badf;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+  right: 70px;
+  left: 0;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  text-align: right;
+  vertical-align: top;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+  right: 70px;
+  left: 0;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #b1badf;
+  border-right: none;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+  right: 0;
+  left: auto;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+  right: 0;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+  left: 0;
+  right: auto;
+}
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  text-align: right;
+  right: 2px;
+}
diff --git a/dojox/calendar/themes/soria/ColumnView_rtl.less b/dojox/calendar/themes/soria/ColumnView_rtl.less
new file mode 100644
index 0000000..a37d344
--- /dev/null
+++ b/dojox/calendar/themes/soria/ColumnView_rtl.less
@@ -0,0 +1,129 @@
+ at import "ColumnViewCommon.less";
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarScrollContainer {	
+	border-left: none;
+	border-right: none;
+}
+	
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarGrid {
+	left: 0;
+	right: @row-header-width;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarGridTable td {
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarContainer {	
+	left: 0;
+	right: @row-header-width - 2;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarContainerColumn {
+	margin-right: 1px;
+	margin-left: 9px;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarYearColumnHeader{
+	right: 0;
+	width: @row-header-width;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeader {
+	left: 0;
+	right: @row-header-width;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarRowHeaderLabel { 	
+	right: auto;
+	left: 4px;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .summary {
+	text-align: right;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .startTime {
+	text-align: right;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .endTime {
+	text-align: right;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarVScrollBar { 	
+	margin-left: -1px;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+	right: @row-header-width;
+	left: 0;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {			
+	text-align: left;
+	border-bottom: @inner-border;
+	border-left: @inner-border;
+	border-right: none;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span{
+	padding-left: 2px;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child	{
+	border-left: @outer-border;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+	right: @row-header-width;
+	left: 0;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	text-align: right;
+	vertical-align: top;		
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	right: 0;
+	left: auto;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+	right: @row-header-width;
+	left: 0;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+	right: 0;
+	left: auto;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+	right: 0;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+	left: 0;
+	right: auto;
+}
+
+.soria .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	text-align: right;
+	right: 2px;
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/soria/Common.less b/dojox/calendar/themes/soria/Common.less
new file mode 100755
index 0000000..19506a5
--- /dev/null
+++ b/dojox/calendar/themes/soria/Common.less
@@ -0,0 +1,72 @@
+ at outer-border: 1px solid #B1BADF;
+ at inner-border: 1px solid #BFBFBF;
+
+ at row-color:#FDFDFD;
+ at row-color-hover: #B9CBF1;
+ at row-color-active: #60A1EA;
+
+ at today-color: #FFF2D2;
+ at today-label-color: #FF2200;
+
+ at week-end-color: #FDFDFD;
+ at week-end-label-color:#999999;
+
+ at expand-up-color: #E5F2FE;
+ at expand-down-color: #A5D1FB;
+
+ at label-color: #293A4B;
+ at secondary-label-color: #555;
+
+.border-box(){
+	-webkit-box-sizing: border-box;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.opacity(@op){
+	filter: ~"alpha(opacity=@{op})";	
+	opacity:@op/100;
+}
+
+.transition-duration(@dur: 0s){
+	-webkit-transition-duration: @dur;
+	-moz-transition-duration: @dur;
+	transition-duration: @dur;
+}
+
+.select-none() {
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	khtml-user-select: none;
+	user-select: none;
+}
+
+.glass-view(){
+	z-index: 2;
+	background:#00FF00; 
+	.opacity(0);
+	.select-none
+}
+
+.header-background(){
+	background: #cccccc;
+	background:#fff url("images/titleBar.png") repeat-x top left;	
+	padding:3px 4px;
+	font-size: 0.9em;
+	font-weight: bold;
+	color: #6d6d6d;
+}
+
+.header-hover-background(){
+	background: #f9f9f9 url("images/accordionItemActive.png") top repeat-x;
+}
+
+.header-active-background(){
+	cursor: pointer;		
+}
+
+.rounded-corners (@radius: 5px) {
+  border-radius: @radius;
+  -webkit-border-radius: @radius;
+  -moz-border-radius: @radius;
+}
diff --git a/dojox/calendar/themes/soria/MatrixView.css b/dojox/calendar/themes/soria/MatrixView.css
new file mode 100644
index 0000000..dedcb8c
--- /dev/null
+++ b/dojox/calendar/themes/soria/MatrixView.css
@@ -0,0 +1,364 @@
+.soria .dojoxCalendarMatrixView {
+  cursor: default;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarGrid {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 30px;
+  bottom: 0px;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+  text-align: right;
+  vertical-align: top;
+  border-bottom: 1px solid #bfbfbf;
+  border-right: 1px solid #bfbfbf;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable td span {
+  padding-right: 2px;
+  padding-top: 2px;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td {
+  border-bottom: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child {
+  border-right: 1px solid #b1badf;
+}
+/* 
+ * The dojoxCalendarColToday & dojoxCalendarColWeekend classes is added by the 
+ * MatrixView.styleGridCell method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable td.dojoxCalendarToday {
+  background-color: #fff2d2;
+  font-weight: bold;
+  color: #ff2200;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #fdfdfd;
+  color: #999999;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarDayDisabled {
+  background-color: #fdfdfd;
+  color: #999999;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  left: 0px;
+  top: 0px;
+  width: 50px;
+  height: 29px;
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid #b1badf;
+  border-top: 1px solid #b1badf;
+  border-right: 1px solid #b1badf;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+  color: #293a4b;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeader {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 0px;
+  height: 29px;
+  cursor: default;
+  border-bottom: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  vertical-align: middle;
+  text-align: center;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+  border-right: 1px solid #bfbfbf;
+  border-top: 1px solid #b1badf;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #b1badf;
+}
+/* 
+ * The dojoxCalendarColWeekend class is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css class.
+ */
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #999999;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+  position: absolute;
+  left: 0px;
+  top: 30px;
+  width: 50px;
+  bottom: 0;
+  cursor: default;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  border-collapse: collapse;
+  table-layout: fixed;
+  margin: 0;
+  padding: 0;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+/* 
+ * The MatrixView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid #b1badf;
+  border-right: 1px solid #b1badf;
+  border-bottom: 1px solid #bfbfbf;
+  background-color: #fdfdfd;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  color: #293a4b;
+  cursor: pointer;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.last-child {
+  border-bottom: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Hover {
+  background-color: #b9cbf1;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Active {
+  background-color: #60a1ea;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarContainer {
+  position: absolute;
+  top: 30px;
+  left: 50px;
+  right: 0px;
+  bottom: 0px;
+  cursor: default;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarContainerTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarContainerTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarContainerTable td {
+  vertical-align: top;
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarContainerTable td div.dojoxCalendarContainerRow {
+  position: relative;
+  height: 100%;
+  width: 100%;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #000000;
+  cursor: default;
+  white-space: nowrap;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal {
+  color: #FFF;
+  position: absolute;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .bg {
+  border: 1px solid #260000;
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  color: #000000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9f0000;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Hovered .bg {
+  background-color: #cc0000;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Selected .bg {
+  background-color: #660000;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.Edited {
+  color: #fff;
+  font-weight: bold;
+  text-decoration: none;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .bg {
+  border: dashed 1px #FFF;
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Focused .bg {
+  border: dashed 1px #FFF;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Hovered {
+  color: #F40;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Selected {
+  color: #F00;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Edited {
+  border: dashed 1px #FFF;
+  background: #600;
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+  color: #FFF;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Focused {
+  border: dashed 1px #000000;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  position: absolute;
+  left: 3px;
+  right: 1px;
+  bottom: 2px;
+  overflow: hidden;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+  position: absolute;
+  left: 2px;
+  right: 2px;
+  bottom: 0;
+  overflow: hidden;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  position: absolute;
+  width: 5px;
+  height: 100%;
+  cursor: e-resize;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+  left: 0;
+  top: 0;
+  width: 100%;
+  cursor: move;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+  right: 0px;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarExpand {
+  position: absolute;
+  text-align: center;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarExpand span {
+  display: inline-block;
+  vertical-align: middle;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+  position: relative;
+  margin-right: 5px;
+  margin-left: 5px;
+  height: 100%;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  border: 1px solid transparent;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+  background-color: #e5f2fe;
+  border: 1px solid #909da9;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+  background-color: #a5d1fb;
+  border: 1px solid #507ca6;
+}
diff --git a/dojox/calendar/themes/soria/MatrixView.less b/dojox/calendar/themes/soria/MatrixView.less
new file mode 100644
index 0000000..1c336f9
--- /dev/null
+++ b/dojox/calendar/themes/soria/MatrixView.less
@@ -0,0 +1,373 @@
+ at import "MatrixViewCommon.less";
+
+.soria .dojoxCalendarMatrixView {	
+	cursor: default;
+	.select-none;
+}
+	
+.soria .dojoxCalendarMatrixView .dojoxCalendarGrid {
+	position: absolute;
+	left: @row-header-width;
+	right: 0px;
+	top: @column-header-height;
+	bottom: 0px;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable {
+	position: relative;
+	width: 100%;
+	height: 100%;	
+	margin: 0;
+	padding: 0;
+	border-collapse: collapse;
+	table-layout: fixed;	
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable tr{
+	.border-box;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+	text-align: right;
+	vertical-align: top;	
+	border-bottom: @inner-border;
+	border-right: @inner-border;
+	.border-box;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable td span{
+	padding-right: 2px;
+	padding-top: 2px;		
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable td span.FirstVisibleDayOfMonth{	
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td	{
+	border-bottom: @outer-border;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child	{
+	border-right: @outer-border;
+}
+
+/* 
+ * The dojoxCalendarColToday & dojoxCalendarColWeekend classes is added by the 
+ * MatrixView.styleGridCell method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable td.dojoxCalendarToday	{
+	background-color: @today-color;		
+	font-weight: bold;
+	color: @today-label-color;
+}
+			
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+	color: @week-end-label-color;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarDayDisabled {
+	background-color: @disabled-day-color;
+	color: @disabled-day-label-color;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	left: 0px;
+	top: 0px;
+	width: @row-header-width;
+	height: @column-header-height - 1px;
+	text-align: center;
+	vertical-align: middle;
+	border-bottom: @outer-border;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table{
+	position: relative;		
+	width:100%;
+	height: 100%;
+	table-layout: fixed;
+	border-collapse: collapse;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table td{
+	text-align: center;
+	vertical-align: middle;		
+	border-left: @outer-border;
+	border-top: @outer-border;
+	border-right: @outer-border;
+	.header-background;
+	color: @label-color;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeader {
+	position: absolute;
+	left: @row-header-width;
+	right: 0px;
+	top: 0px;
+	height: @column-header-height - 1px;
+	cursor: default;
+	border-bottom: @outer-border;	
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable {
+	position: relative;		
+	width:100%;
+	height: 100%;
+	table-layout: fixed;
+	border-collapse: collapse;		
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+	overflow:hidden;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	.select-none;
+	color: @label-color;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td.last-child {
+	border-right: @outer-border;
+}
+
+/* 
+ * The dojoxCalendarColWeekend class is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css class.
+ */
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+	color: @week-end-label-color;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+	position: absolute;
+	left: 0px;				
+	top: @column-header-height;
+	width: @row-header-width;
+	bottom: 0;
+	cursor: default;
+	
+	.select-none;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable {
+	position: relative;			
+	width: 100%;
+	height: 100%;
+	border-collapse: collapse;
+	table-layout: fixed;
+	margin: 0;
+	padding: 0;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable tr{
+	.border-box;
+}
+
+/* 
+ * The MatrixView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+	text-align: center;
+	vertical-align: middle;	
+	border-left: @outer-border;
+	border-right: @outer-border;
+	border-bottom: @inner-border;
+	background-color: @row-color;
+	.transition-duration(0.2s);
+	.border-box;
+	color: @label-color;
+	cursor: pointer;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.last-child {
+	border-bottom: @outer-border;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Hover {
+	background-color: @row-color-hover;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Active {
+	background-color: @row-color-active;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarContainer {
+	position: absolute;
+	top: @column-header-height;
+	left: @row-header-width;
+	right: 0px;
+	bottom: 0px;
+	cursor: default;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarContainerTable {
+	position: relative;
+	width: 100%;
+	height: 100%;	
+	margin: 0;
+	padding: 0;
+	border-collapse: collapse;
+	table-layout: fixed;	
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarContainerTable tr{
+	.border-box;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarContainerTable td{
+	vertical-align: top;
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	.border-box;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarContainerTable td div.dojoxCalendarContainerRow{
+	position:relative;
+	height:100%;
+	width:100%;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+ 	.select-none;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent {	
+	position: absolute;
+	text-align: left;
+	color: #000000;
+	cursor: default;
+	white-space: nowrap;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal {
+	color: #FFF;
+	position: absolute;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .bg {
+	border: @horizontal-border;	
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;	
+	color: #000000;	
+	.rounded-corners(5px);
+	background-color: @horizontal-color;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Hovered  .bg {
+	background-color: @horizontal-hover-color;	
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Selected .bg {
+	background-color: @horizontal-selected-bg-color;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.Edited {
+	color: #fff;
+	font-weight: bold;
+	text-decoration: none;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .bg {
+	border: dashed 1px #FFF;
+	.opacity(30);
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Focused .bg {
+	border: dashed 1px #FFF;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Hovered {
+	color: #F40;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Selected {
+	color: #F00;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Edited {
+	border: dashed 1px #FFF;
+	background: #600;
+	.opacity(30);
+	color: #FFF;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Focused {
+	border: dashed 1px #000000;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	position: absolute;
+	left: 3px;
+	right: 1px;
+	bottom: 2px;
+	overflow: hidden;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+	position: absolute;
+	left: 2px;
+	right: 2px;
+	bottom: 0;
+	overflow: hidden;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+	.glass-view;
+	position: absolute;
+	width:5px;
+	height:100%;
+	cursor:e-resize;	
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+	left:0;
+	top:0;
+	width:100%;
+	cursor:move;	
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle {
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+	right:0px;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarExpand {
+	position: absolute;
+	text-align: center;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarExpand span {
+	display: inline-block;
+	vertical-align: middle;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+	position: relative;
+	margin-right: 5px;
+	margin-left: 5px;
+	height: 100%;
+	.rounded-corners(5px);
+	.transition-duration(0.2s);
+	.border-box;	
+	border: 1px solid transparent;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+	background-color: @expand-up-color;
+	border: 1px solid @expand-up-color - #555555;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+	background-color: @expand-down-color;
+	border: 1px solid @expand-down-color - #555555;
+}
diff --git a/dojox/calendar/themes/soria/MatrixViewCommon.less b/dojox/calendar/themes/soria/MatrixViewCommon.less
new file mode 100644
index 0000000..a1a2efc
--- /dev/null
+++ b/dojox/calendar/themes/soria/MatrixViewCommon.less
@@ -0,0 +1,12 @@
+ at import "Common.less";
+
+ at disabled-day-color: #FDFDFD;
+ at disabled-day-label-color: #999999;
+
+ at horizontal-color: #9F0000;
+ at horizontal-hover-color: #CC0000;
+ at horizontal-selected-bg-color: #660000;
+ at horizontal-border: 1px solid #260000;
+
+ at column-header-height: 30px;
+ at row-header-width: 50px;
diff --git a/dojox/calendar/themes/soria/MatrixView_rtl.css b/dojox/calendar/themes/soria/MatrixView_rtl.css
new file mode 100644
index 0000000..f67e4ea
--- /dev/null
+++ b/dojox/calendar/themes/soria/MatrixView_rtl.css
@@ -0,0 +1,56 @@
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+  right: 50px;
+  left: 0;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {
+  text-align: left;
+  border-bottom: 1px solid #bfbfbf;
+  border-left: 1px solid #bfbfbf;
+  border-right: none;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span {
+  padding-left: 2px;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child {
+  border-left: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+  right: 50px;
+  left: 0;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  text-align: right;
+  vertical-align: top;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+  right: 50px;
+  left: 0;
+}
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #b1badf;
+  border-right: none;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+  right: 0;
+  left: auto;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  text-align: right;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+  text-align: right;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+  right: 0;
+}
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+  left: 0;
+  right: auto;
+}
diff --git a/dojox/calendar/themes/soria/MatrixView_rtl.less b/dojox/calendar/themes/soria/MatrixView_rtl.less
new file mode 100644
index 0000000..1a4aad5
--- /dev/null
+++ b/dojox/calendar/themes/soria/MatrixView_rtl.less
@@ -0,0 +1,71 @@
+ at import "MatrixViewCommon.less";
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+	right: @row-header-width;
+	left: 0;
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {			
+	text-align: left;
+	border-bottom: @inner-border;
+	border-left: @inner-border;
+	border-right: none;
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span{
+	padding-left: 2px;
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child	{
+	border-left: @outer-border;
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+	right: @row-header-width;
+	left: 0;
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	text-align: right;
+	vertical-align: top;		
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	right: 0;
+	left: auto;
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+	right: @row-header-width;
+	left: 0;
+}
+
+.soria .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+	right: 0;
+	left: auto;
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	text-align: right;
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+	text-align: right;
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+	right: 0;
+}
+
+.soria .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+	left:0;
+	right:auto;
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/soria/MonthColumnView.css b/dojox/calendar/themes/soria/MonthColumnView.css
new file mode 100644
index 0000000..ab37052
--- /dev/null
+++ b/dojox/calendar/themes/soria/MonthColumnView.css
@@ -0,0 +1,261 @@
+.soria .dojoxCalendarMonthColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 30px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-bottom: 1px solid #b1badf;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGrid {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #bfbfbf;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td span {
+  padding-left: 3px;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff2d2;
+  font-weight: bold;
+  color: #ff2200;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarHiddenEvents {
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents {
+  background: #fff2d2 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.first-child {
+  border-left: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff2d2;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #fdfdfd;
+  color: #999999;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #fdfdfd;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  cursor: default;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 35px;
+  margin-right: 5px;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 0;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+  border-right: 1px solid #bfbfbf;
+  border-top: 1px solid #b1badf;
+  border-bottom: 1px solid #b1badf;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.first-child {
+  border-left: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background: #f9f9f9 url("images/accordionItemActive.png") top repeat-x;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+  overflow: hidden;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9F0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 30px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/soria/MonthColumnView.less b/dojox/calendar/themes/soria/MonthColumnView.less
new file mode 100644
index 0000000..b3de1e3
--- /dev/null
+++ b/dojox/calendar/themes/soria/MonthColumnView.less
@@ -0,0 +1,282 @@
+ at import "ColumnViewCommon.less";
+
+.soria .dojoxCalendarMonthColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarScrollContainer {
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: @column-header-height;
+	position: absolute;
+	overflow-y: hidden;
+	overflow-x: hidden;	
+	border-bottom: @outer-border;
+	.border-box;
+}
+	
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGrid {
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td {
+	border-top: dotted 1px #B5BCC7;	
+	border-right: @inner-border;
+	.border-box;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td span {
+  padding-left:3px;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td	{
+	border-top: 1px solid transparent;
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+	background-color: @today-color;
+	font-weight: bold;
+	color: @today-label-color;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarHiddenEvents	{	
+	background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;	
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents	{	
+	background: @today-color url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;	
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.last-child	{
+	border-right: @outer-border;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.first-child	{
+	border-left: @outer-border;
+}
+
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday	{
+	border-top: 1px solid @today-color;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+	color: @week-end-label-color;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend	{
+	border-top: 1px solid @week-end-color;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarContainer {
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+	cursor: default;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable td {
+	height: 100%;
+	padding: 0;
+	vertical-align: top;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarContainerColumn {
+	position:	relative;
+	margin-left: 35px;
+	margin-right: 5px;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+	.select-none;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeader {
+	position: absolute;
+	height: @column-header-height;	 
+	left: 0;
+	right: 0;
+	top: 0;
+	cursor: default;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;			
+	width: 100%;
+	height: 100%;	
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {	
+	overflow:hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.select-none;
+	color: @label-color;
+	.transition-duration(0.2s);
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-right: @outer-border;	
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.first-child {	
+	border-left: @outer-border;	
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Hover{	
+	cursor: pointer;		
+	.header-hover-background;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Active{	
+	.header-active-background;
+}
+ 
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent {
+	position: absolute;	
+	text-align: left;
+	color: #FFF;
+	cursor: default;
+	overflow: hidden;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .bg {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: -1;
+	border: 1px solid #260000;	
+	.rounded-corners;
+	background-color: #9F0000;
+	.opacity(90);
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Hovered .bg {
+	background-color: #CC0000;	
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Selected .bg {
+	background-color: #660000;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Edited .bg {
+	border: dashed 1px #FFFFFF;
+	.opacity(70);
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Focused .bg {
+	border: dashed 1px #FFFFFF;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .summary {
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .startTime {
+	font-weight: bold;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .endTime {
+	position: absolute;		
+	font-weight: bold;	
+	bottom:3px;
+	left: 6px;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .beforeIcon {
+	text-align: center;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .afterIcon {
+	position: absolute;
+	bottom: 2px;
+	width: 100%;
+	text-align: center;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .handle {
+	.glass-view;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .moveHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	bottom:0;
+	cursor:move;	
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeStartHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeEndHandle {
+	position: absolute;
+	bottom:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarVScrollBar {
+	position: absolute;
+	top: @column-header-height;
+	bottom: 0;
+	overflow-y: scroll;
+	overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/soria/MonthColumnViewCommon.less b/dojox/calendar/themes/soria/MonthColumnViewCommon.less
new file mode 100644
index 0000000..9bb3ec8
--- /dev/null
+++ b/dojox/calendar/themes/soria/MonthColumnViewCommon.less
@@ -0,0 +1,7 @@
+ at import "Common.less";
+
+ at hour-stroke: 1px solid #C7BEBE;
+ at half-hour-stroke: dotted 1px #C7BEBE;
+ at quarter-hour-stroke: dotted 1px #C7BEBE;
+
+ at column-header-height: 30px;
diff --git a/dojox/calendar/themes/soria/MonthColumnView_rtl.css b/dojox/calendar/themes/soria/MonthColumnView_rtl.css
new file mode 100644
index 0000000..18f1533
--- /dev/null
+++ b/dojox/calendar/themes/soria/MonthColumnView_rtl.css
@@ -0,0 +1,42 @@
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td {
+  border-right: none;
+  border-left: 1px solid #bfbfbf;
+}
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td span {
+  padding-right: 3px;
+}
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable .dojoxCalendarHiddenEvents {
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents {
+  background: #fff2d2 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;
+}
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.last-child {
+  border-left: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.first-child {
+  border-right: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarContainerColumn {
+  margin-left: 5px;
+  margin-right: 35px;
+}
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #bfbfbf;
+  border-right: none;
+}
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.last-child {
+  border-left: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.first-child {
+  border-right: 1px solid #b1badf;
+}
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .summary {
+  text-align: right;
+}
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .startTime {
+  text-align: right;
+}
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .endTime {
+  text-align: right;
+}
diff --git a/dojox/calendar/themes/soria/MonthColumnView_rtl.less b/dojox/calendar/themes/soria/MonthColumnView_rtl.less
new file mode 100644
index 0000000..e101341
--- /dev/null
+++ b/dojox/calendar/themes/soria/MonthColumnView_rtl.less
@@ -0,0 +1,56 @@
+ at import "ColumnViewCommon.less";
+
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td {
+	border-right: none;	
+	border-left: @inner-border;
+}
+
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td span {
+  padding-right:3px;
+}
+
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable .dojoxCalendarHiddenEvents	{
+	background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;	
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents	{	
+	background: @today-color url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y  right top;	
+}
+
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.last-child	{
+	border-left: @outer-border;	
+}
+
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.first-child	{
+	border-right: @outer-border;
+}
+
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarContainerColumn {	
+	margin-left: 5px;
+	margin-right: 35px;
+}
+
+.soria .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @inner-border;
+	border-right: none;	
+}
+
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-left: @outer-border;	
+}
+
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.first-child {	
+	border-right: @outer-border;	
+}
+ 
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .summary {
+	text-align: right;
+}
+
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .startTime {
+	text-align: right;
+}
+
+.soria .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .endTime {
+	text-align: right;
+}
diff --git a/dojox/calendar/themes/soria/SimpleColumnView.css b/dojox/calendar/themes/soria/SimpleColumnView.css
new file mode 100644
index 0000000..faeb5ff
--- /dev/null
+++ b/dojox/calendar/themes/soria/SimpleColumnView.css
@@ -0,0 +1,356 @@
+.soria .dojoxCalendarSimpleColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarHeader {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 29px;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 30px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-top: 1px solid #b1badf;
+  border-bottom: 1px solid #b1badf;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #bfbfbf;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+.soria .dojoxCalendarColumnView td.hour {
+  border-top: 1px solid #cccccc;
+}
+.soria .dojoxCalendarColumnView td.halfhour {
+  border-top: dotted 1px #cccccc;
+}
+.soria .dojoxCalendarColumnView td.quarterhour {
+  border-top: dotted 1px #cccccc;
+}
+.soria .dojoxCalendarColumnView span.hour {
+  color: #293a4b;
+  background-color: #fdfdfd;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff2d2;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #b1badf;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff2d2;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #fdfdfd;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #fdfdfd;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  cursor: default;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 2px;
+  margin-right: 9px;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  height: 29px;
+  left: 0;
+  width: 68px;
+  top: 0;
+  border-left: 1px solid #b1badf;
+  border-top: 1px solid #b1badf;
+  border-right: 1px solid #b1badf;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #b1badf;
+  color: #293a4b;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 70px;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background: #cccccc;
+  background: #ffffff url("images/titleBar.png") repeat-x top left;
+  padding: 3px 4px;
+  font-size: 0.9em;
+  font-weight: bold;
+  color: #6d6d6d;
+  border-right: 1px solid #bfbfbf;
+  border-top: 1px solid #b1badf;
+  border-bottom: 1px solid #b1badf;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #b1badf;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+  font-weight: bold;
+  color: #ff2200;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #999999;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background: #f9f9f9 url("images/accordionItemActive.png") top repeat-x;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeader {
+  position: absolute;
+  width: 68px;
+  cursor: default;
+  border-left: 1px solid #b1badf;
+  border-right: 1px solid #b1badf;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel {
+  right: 4px;
+  position: absolute;
+}
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td.dummy {
+  border-top: 1px solid #fdfdfd;
+}
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td {
+  vertical-align: top;
+  text-align: right;
+  border-top: 1px solid #b1badf;
+  background-color: #fdfdfd;
+  color: #293a4b;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable tr:first-child td {
+  border-top: 1px solid #fdfdfd;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9F0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 30px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/soria/SimpleColumnView.less b/dojox/calendar/themes/soria/SimpleColumnView.less
new file mode 100644
index 0000000..40914c0
--- /dev/null
+++ b/dojox/calendar/themes/soria/SimpleColumnView.less
@@ -0,0 +1,382 @@
+ at import "ColumnViewCommon.less";
+
+ at row-header-width: 70px;
+ at secondary-sheet-height: 0px;
+ at sheet-top: @column-header-height;
+
+.soria .dojoxCalendarSimpleColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarHeader {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: @column-header-height - 1px;
+	.border-box;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarScrollContainer {
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: @sheet-top;
+	position: absolute;
+	overflow-y: hidden;
+	overflow-x: hidden;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.border-box;
+}
+	
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGrid {
+	position: absolute;
+	left: @row-header-width;
+	right: 0;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable td {
+	border-top: dotted 1px #B5BCC7;	
+	border-right: @inner-border;
+	.border-box;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td	{
+	border-top: 1px solid transparent;
+}
+
+.soria .dojoxCalendarColumnView td.hour {
+	border-top: @hour-stroke;
+}
+
+.soria .dojoxCalendarColumnView td.halfhour{
+	border-top: @half-hour-stroke;	
+}
+
+.soria .dojoxCalendarColumnView  td.quarterhour{
+	border-top: @quarter-hour-stroke;
+}
+
+.soria .dojoxCalendarColumnView span.hour {
+	color: @label-color;
+	background-color: @row-color;
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+	background-color: @today-color;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr td.last-child	{
+	border-right: @outer-border;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday	{
+	border-top: 1px solid @today-color;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend	{
+	border-top: 1px solid @week-end-color;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarContainer {
+	position: absolute;
+	top: 0;
+	left: @row-header-width;
+	right: 0;
+	cursor: default;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable td {
+	height: 100%;
+	padding: 0;
+	vertical-align: top;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarContainerColumn {
+	position:	relative;
+	margin-left: 2px;
+	margin-right: 9px;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+	.select-none;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	height: @column-header-height - 1px;
+	left: 0;
+	width: @row-header-width - 2px;
+	top: 0;	
+	border-left: @outer-border;
+	border-top: @outer-border;
+	border-right: @outer-border;	
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table {
+	position:relative;
+	width:100%;
+	height:100%;	
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table td {
+	text-align: center;
+	vertical-align: middle;
+	border-bottom: @outer-border;	
+	color: @label-color;
+	.header-background;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeader {
+	position: absolute;
+	height: @column-header-height;	 
+	left: @row-header-width;
+	right: 0;
+	top: 0;
+	cursor: default;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;			
+	width: 100%;
+	height: 100%;	
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td {	
+	overflow:hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.select-none;
+	color: @label-color;
+	.transition-duration(0.2s);
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-right: @outer-border;	
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+	font-weight: bold;
+	color: @today-label-color;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+	color: @week-end-label-color;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Hover{	
+	cursor: pointer;		
+	.header-hover-background;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Active{	
+	.header-active-background;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeader {
+	position: absolute;
+	width: @row-header-width - 2px;
+	cursor: default;
+	border-left: @outer-border;
+	border-right: @outer-border;
+	height: 100%;
+	.select-none;
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel{	
+	right: 4px;		
+	position: absolute;	
+}
+
+.soria .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td.dummy{
+	border-top: 1px solid @row-color;
+}
+
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td {	
+	vertical-align: top;			
+	text-align: right;	
+	border-top: @outer-border; 	
+	background-color: @row-color;
+	color: @label-color;
+	.border-box;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable tr:first-child td	{
+	border-top: 1px solid @row-color;
+}
+ 
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent {
+	position: absolute;	
+	text-align: left;
+	color: #FFF;
+	cursor: default;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .bg {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: -1;
+	border: 1px solid #260000;	
+	.rounded-corners;
+	background-color: #9F0000;
+	.opacity(90);
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Hovered .bg {
+	background-color: #CC0000;	
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Selected .bg {
+	background-color: #660000;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Edited .bg {
+	border: dashed 1px #FFFFFF;
+	.opacity(70);
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Focused .bg {
+	border: dashed 1px #FFFFFF;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .summary {
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .startTime {
+	font-weight: bold;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .endTime {
+	position: absolute;		
+	font-weight: bold;	
+	bottom:3px;
+	left: 6px;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .beforeIcon {
+	text-align: center;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .afterIcon {
+	position: absolute;
+	bottom: 2px;
+	width: 100%;
+	text-align: center;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .handle {
+	.glass-view;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .moveHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	bottom:0;
+	cursor:move;	
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeStartHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeEndHandle {
+	position: absolute;
+	bottom:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.soria .dojoxCalendarSimpleColumnView .dojoxCalendarVScrollBar {
+	position: absolute;
+	top: @sheet-top;
+	bottom: 0;
+	overflow-y: scroll;
+	overflow-x: hidden;
+}
+
+
diff --git a/dijit/themes/soria/images/accordionItemActive.png b/dojox/calendar/themes/soria/images/accordionItemActive.png
similarity index 100%
copy from dijit/themes/soria/images/accordionItemActive.png
copy to dojox/calendar/themes/soria/images/accordionItemActive.png
diff --git a/dijit/themes/soria/images/titleBar.png b/dojox/calendar/themes/soria/images/titleBar.png
similarity index 100%
copy from dijit/themes/soria/images/titleBar.png
copy to dojox/calendar/themes/soria/images/titleBar.png
diff --git a/dojox/calendar/themes/tundra/Calendar.css b/dojox/calendar/themes/tundra/Calendar.css
new file mode 100644
index 0000000..a87d964
--- /dev/null
+++ b/dojox/calendar/themes/tundra/Calendar.css
@@ -0,0 +1,27 @@
+ at import url("MatrixView.css");
+
+ at import url("ColumnView.css");
+.tundra .dojoxCalendar .buttonContainer {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 31px;
+}
+.tundra .dojoxCalendar .buttonContainer .dijitToolbar {
+  border: 1px solid #B5BCC7;
+}
+.tundra .dojoxCalendar .viewContainer {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 31px;
+  bottom: 0;
+}
+.tundra .dojoxCalendar .view {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+}
diff --git a/dojox/calendar/themes/tundra/Calendar.less b/dojox/calendar/themes/tundra/Calendar.less
new file mode 100644
index 0000000..0b63bd4
--- /dev/null
+++ b/dojox/calendar/themes/tundra/Calendar.less
@@ -0,0 +1,33 @@
+ at button-container-height: 31px;
+
+ at import url("MatrixView.css");
+ at import url("ColumnView.css");
+
+.tundra .dojoxCalendar .buttonContainer{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: @button-container-height;
+}
+
+.tundra .dojoxCalendar .buttonContainer .dijitToolbar {
+	border: 1px solid #B5BCC7;
+}
+
+.tundra .dojoxCalendar .viewContainer{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: @button-container-height;
+	bottom: 0;
+}
+
+.tundra .dojoxCalendar .view{
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+}
+
diff --git a/dojox/calendar/themes/tundra/Calendar_rtl.css b/dojox/calendar/themes/tundra/Calendar_rtl.css
new file mode 100644
index 0000000..106a1d6
--- /dev/null
+++ b/dojox/calendar/themes/tundra/Calendar_rtl.css
@@ -0,0 +1,3 @@
+ at import url("MatrixView_rtl.css");
+
+ at import url("ColumnView_rtl.css");
diff --git a/dojox/calendar/themes/tundra/Calendar_rtl.less b/dojox/calendar/themes/tundra/Calendar_rtl.less
new file mode 100644
index 0000000..25ef90d
--- /dev/null
+++ b/dojox/calendar/themes/tundra/Calendar_rtl.less
@@ -0,0 +1,3 @@
+ at import url("MatrixView_rtl.css");
+ at import url("ColumnView_rtl.css");
+
diff --git a/dojox/calendar/themes/tundra/ColumnView.css b/dojox/calendar/themes/tundra/ColumnView.css
new file mode 100644
index 0000000..5528703
--- /dev/null
+++ b/dojox/calendar/themes/tundra/ColumnView.css
@@ -0,0 +1,483 @@
+.tundra .dojoxCalendarColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarHeader {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 29px;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 72px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+.tundra .dojoxCalendarColumnView td.hour {
+  border-top: 1px solid #eeeeee;
+}
+.tundra .dojoxCalendarColumnView td.halfhour {
+  border-top: dotted 1px #eeeeee;
+}
+.tundra .dojoxCalendarColumnView td.quarterhour {
+  border-top: dotted 1px #eeeeee;
+}
+.tundra .dojoxCalendarColumnView span.hour {
+  color: #293a4b;
+  background-color: #f8f8f8;
+}
+.tundra .dojoxCalendarColumnView span.halfhour,
+.tundra .dojoxCalendarColumnView span.quarterhour {
+  color: #555555;
+  background-color: #f8f8f8;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff2d2;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff2d2;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #f8f8f8;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #f8f8f8;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  cursor: default;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 2px;
+  margin-right: 9px;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  height: 29px;
+  left: 0;
+  width: 68px;
+  top: 0;
+  border-left: 1px solid #cccccc;
+  border-top: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #cccccc;
+  color: #293a4b;
+  background: #F8F8F8;
+  background: #f8f8f8 url("images/titleBar.png") repeat-x bottom left;
+  padding: 3px 4px;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 70px;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background: #F8F8F8;
+  background: #f8f8f8 url("images/titleBar.png") repeat-x bottom left;
+  padding: 3px 4px;
+  border-right: 1px solid #cccccc;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+  font-weight: bold;
+  color: #ff2200;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #999999;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background: #f8fafd url("images/accordionItemHover.gif") bottom repeat-x;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeader {
+  position: absolute;
+  width: 68px;
+  cursor: default;
+  border-left: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabelContainer {
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel {
+  right: 4px;
+  position: absolute;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td.dummy {
+  border-top: 1px solid #f8f8f8;
+}
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td {
+  vertical-align: top;
+  text-align: right;
+  border-top: 1px solid #cccccc;
+  background-color: #f8f8f8;
+  color: #293a4b;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable tr:first-child td {
+  border-top: 1px solid #f8f8f8;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td span {
+  padding-right: 4px;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9F0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 72px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 30px;
+  height: 39px;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  bottom: 0;
+  cursor: default;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 70px;
+  bottom: 0;
+  border-right: none;
+  border-left: none;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+  text-align: right;
+  vertical-align: top;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td {
+  border-bottom: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+  border-top: 1px solid #cccccc;
+  border-left: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  background-color: #f8f8f8;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  position: absolute;
+  width: 5px;
+  height: 100%;
+  cursor: e-resize;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+  left: 0;
+  top: 0;
+  width: 100%;
+  cursor: move;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  position: absolute;
+  left: 3px;
+  right: 1px;
+  bottom: 2px;
+  overflow: hidden;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+  right: 0px;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .afterIcon {
+  width: auto;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .endTime {
+  position: relative;
+  bottom: auto;
+  left: auto;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand {
+  position: absolute;
+  text-align: center;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+  position: relative;
+  margin-right: 10%;
+  margin-left: 10%;
+  border-radius: 5px;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  border: 1px solid transparent;
+  -moz-border-radius: 5px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+  background-color: #e5f2fe;
+  border: 1px solid #909da9;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+  background-color: #a5d1fb;
+  border: 1px solid #507ca6;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent div {
+  white-space: nowrap;
+}
diff --git a/dojox/calendar/themes/tundra/ColumnView.less b/dojox/calendar/themes/tundra/ColumnView.less
new file mode 100644
index 0000000..e2e579f
--- /dev/null
+++ b/dojox/calendar/themes/tundra/ColumnView.less
@@ -0,0 +1,520 @@
+ at import "ColumnViewCommon.less";
+
+.tundra .dojoxCalendarColumnView {	
+	cursor: default;
+	-webkit-user-select: none;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarHeader {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: @column-header-height - 1px;
+	.border-box;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarScrollContainer {
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: @sheet-top;
+	position: absolute;
+	overflow-y: hidden;
+	overflow-x: hidden;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.border-box;
+}
+	
+.tundra .dojoxCalendarColumnView .dojoxCalendarGrid {
+	position: absolute;
+	left: @row-header-width;
+	right: 0;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable td {
+	border-top: dotted 1px #B5BCC7;	
+	border-right: @inner-border;
+	.border-box;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td	{
+	border-top: 1px solid transparent;
+}
+
+.tundra .dojoxCalendarColumnView td.hour {
+	border-top: @hour-stroke;
+}
+
+.tundra .dojoxCalendarColumnView td.halfhour{
+	border-top: @half-hour-stroke;	
+}
+
+.tundra .dojoxCalendarColumnView  td.quarterhour{
+	border-top: @quarter-hour-stroke;
+}
+
+.tundra .dojoxCalendarColumnView span.hour {
+	color: @label-color;
+	background-color: @row-color;
+}
+
+.tundra .dojoxCalendarColumnView span.halfhour,
+.tundra .dojoxCalendarColumnView span.quarterhour{
+	color: @secondary-label-color;
+	background-color: @row-color;
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+	background-color: @today-color;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable tr td.last-child	{
+	border-right: @outer-border;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday	{
+	border-top: 1px solid @today-color;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend	{
+	border-top: 1px solid @week-end-color;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarContainer {
+	position: absolute;
+	top: 0;
+	left: @row-header-width;
+	right: 0;
+	cursor: default;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarContainerTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarContainerTable td {
+	height: 100%;
+	padding: 0;
+	vertical-align: top;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarContainerColumn {
+	position:	relative;
+	margin-left: 2px;
+	margin-right: 9px;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+	.select-none;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	height: @column-header-height - 1px;
+	left: 0;
+	width: @row-header-width - 2px;
+	top: 0;	
+	border-left: @outer-border;
+	border-top: @outer-border;
+	border-right: @outer-border;	
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table {
+	position:relative;
+	width:100%;
+	height:100%;	
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarYearColumnHeader table td {
+	text-align: center;
+	vertical-align: middle;
+	border-bottom: @outer-border;	
+	color: @label-color;
+	.header-background;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeader {
+	position: absolute;
+	height: @column-header-height;	 
+	left: @row-header-width;
+	right: 0;
+	top: 0;
+	cursor: default;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;			
+	width: 100%;
+	height: 100%;	
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td {	
+	overflow:hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.select-none;
+	color: @label-color;
+	.transition-duration(0.2s);
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-right: @outer-border;	
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+	font-weight: bold;
+	color: @today-label-color;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+	color: @week-end-label-color;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Hover{	
+	cursor: pointer;		
+	.header-hover-background;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarColumnHeaderTable td.Active{	
+	.header-active-background;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeader {
+	position: absolute;
+	width: @row-header-width - 2px;
+	cursor: default;
+	border-left: @outer-border;
+	border-right: @outer-border;
+	height: 100%;
+	.select-none;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabelContainer{
+	width: 100%;
+	height: 100%;
+	z-index: 10;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel{	
+	right: 4px;		
+	position: absolute;	
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td.dummy{
+	border-top: 1px solid @row-color;
+}
+
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td {	
+	vertical-align: top;			
+	text-align: right;	
+	border-top: @outer-border; 	
+	background-color: @row-color;
+	color: @label-color;
+	.border-box;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable tr:first-child td	{
+	border-top: 1px solid @row-color;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderTable td span {
+	padding-right: 4px;
+}
+ 
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent {
+	position: absolute;	
+	text-align: left;
+	color: #FFF;
+	cursor: default;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .bg {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: -1;
+	border: 1px solid #260000;	
+	.rounded-corners;
+	background-color: #9F0000;
+	.opacity(90);
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent.Hovered .bg {
+	background-color: #CC0000;	
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent.Selected .bg {
+	background-color: #660000;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent.Edited .bg {
+	border: dashed 1px #FFFFFF;
+	.opacity(70);
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent.Focused .bg {
+	border: dashed 1px #FFFFFF;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .summary {
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .startTime {
+	font-weight: bold;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .endTime {
+	position: absolute;		
+	font-weight: bold;	
+	bottom:3px;
+	left: 6px;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .beforeIcon {
+	text-align: center;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .afterIcon {
+	position: absolute;
+	bottom: 2px;
+	width: 100%;
+	text-align: center;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .handle {
+	.glass-view;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .moveHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	bottom:0;
+	cursor:move;	
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .resizeStartHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent .resizeEndHandle {
+	position: absolute;
+	bottom:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarVScrollBar {
+	position: absolute;
+	top: @sheet-top;
+	bottom: 0;
+	overflow-y: scroll;
+	overflow-x: hidden;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView {	
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: @column-header-height;
+	height: @secondary-sheet-height;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGrid {	
+	position: absolute;
+	left: @row-header-width;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	.border-box;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarContainer {	
+	position: absolute;
+	top: 0;
+	left: @row-header-width;
+	right: 0;
+	bottom: 0;
+	cursor: default;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+	position: absolute;
+	left: 0;				
+	top: 0;
+	width: @row-header-width;
+	bottom: 0;
+	
+	border-right: none;
+	border-left: none;
+	.border-box;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+	text-align: right;
+	vertical-align: top;	
+	border-top: @inner-border;
+	border-bottom: @inner-border;
+	border-right: @inner-border;
+	.border-box;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td	{
+	border-bottom: @outer-border;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child	{
+	border-right: @outer-border;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+	border-top: @inner-border;
+	border-left: @outer-border;
+	border-right: @outer-border;
+	border-bottom: @outer-border;
+	background-color: @row-color;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+	.glass-view;
+	position: absolute;
+	width:5px;
+	height:100%;
+	cursor:e-resize;	
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+	left:0;
+	top:0;
+	width:100%;
+	cursor:move;	
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	position: absolute;
+	left: 3px;
+	right: 1px;
+	bottom: 2px;
+	overflow: hidden;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle {
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+	right:0px;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .afterIcon {
+	width:auto;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent .endTime {
+	position: relative;				
+	bottom:auto;
+	left: auto;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand {
+	position: absolute;
+	text-align: center;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+	position: relative;
+	margin-right: 10%;
+	margin-left: 10%;
+	border-radius: 5px;
+	height: 100%;
+	.select-none;
+	border: 1px solid transparent;
+	-moz-border-radius: 5px;
+	-webkit-transition-duration: 0.2s;
+	-moz-transition-duration: 0.2s;
+	transition-duration: 0.2s;	
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+	background-color: @expand-up-color;
+	border: 1px solid @expand-up-color - #555555;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+	background-color: @expand-down-color;
+	border: 1px solid @expand-down-color - #555555;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarMatrixView .dojoxCalendarEvent div {
+	white-space:nowrap;
+}
+
+
diff --git a/dojox/calendar/themes/tundra/ColumnViewCommon.less b/dojox/calendar/themes/tundra/ColumnViewCommon.less
new file mode 100644
index 0000000..2d68393
--- /dev/null
+++ b/dojox/calendar/themes/tundra/ColumnViewCommon.less
@@ -0,0 +1,10 @@
+ at import "Common.less";
+
+ at hour-stroke: 1px solid #EEEEEE;
+ at half-hour-stroke: dotted 1px #EEEEEE;
+ at quarter-hour-stroke: dotted 1px #EEEEEE;
+
+ at column-header-height: 30px;
+ at row-header-width: 70px;
+ at secondary-sheet-height: 39px;
+ at sheet-top: @secondary-sheet-height + @column-header-height + 3px;
diff --git a/dojox/calendar/themes/tundra/ColumnView_rtl.css b/dojox/calendar/themes/tundra/ColumnView_rtl.css
new file mode 100644
index 0000000..c459d1f
--- /dev/null
+++ b/dojox/calendar/themes/tundra/ColumnView_rtl.css
@@ -0,0 +1,102 @@
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarScrollContainer {
+  border-left: none;
+  border-right: none;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarGrid {
+  left: 0;
+  right: 70px;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarGridTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarContainer {
+  left: 0;
+  right: 70px;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarContainerColumn {
+  margin-right: 1px;
+  margin-left: 9px;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarYearColumnHeader {
+  right: 0;
+  width: 68px;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeader {
+  left: 0;
+  right: 70px;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarRowHeaderLabel {
+  right: auto;
+  left: 4px;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .summary {
+  text-align: right;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .startTime {
+  text-align: right;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .endTime {
+  text-align: right;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarVScrollBar {
+  margin-left: -1px;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+  right: 70px;
+  left: 0;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {
+  text-align: left;
+  border-bottom: 1px solid #cccccc;
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span {
+  padding-left: 2px;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+  right: 70px;
+  left: 0;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  text-align: right;
+  vertical-align: top;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+  right: 70px;
+  left: 0;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+  right: 0;
+  left: auto;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+  right: 0;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+  left: 0;
+  right: auto;
+}
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  text-align: right;
+  right: 2px;
+}
diff --git a/dojox/calendar/themes/tundra/ColumnView_rtl.less b/dojox/calendar/themes/tundra/ColumnView_rtl.less
new file mode 100644
index 0000000..5c1dc44
--- /dev/null
+++ b/dojox/calendar/themes/tundra/ColumnView_rtl.less
@@ -0,0 +1,129 @@
+ at import "ColumnViewCommon.less";
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarScrollContainer {	
+	border-left: none;
+	border-right: none;
+}
+	
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarGrid {
+	left: 0;
+	right: @row-header-width;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarGridTable td {
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarContainer {	
+	left: 0;
+	right: @row-header-width;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarContainerColumn {
+	margin-right: 1px;
+	margin-left: 9px;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarYearColumnHeader{
+	right: 0;
+	width: @row-header-width - 2;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeader {
+	left: 0;
+	right: @row-header-width;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarRowHeaderLabel {
+	right: auto; 	
+	left: 4px;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .summary {
+	text-align: right;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .startTime {
+	text-align: right;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarEvent .endTime {
+	text-align: right;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarVScrollBar { 	
+	margin-left: -1px;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+	right: @row-header-width;
+	left: 0;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {			
+	text-align: left;
+	border-bottom: @inner-border;
+	border-left: @inner-border;
+	border-right: none;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span{
+	padding-left: 2px;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child	{
+	border-left: @outer-border;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+	right: @row-header-width;
+	left: 0;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	text-align: right;
+	vertical-align: top;		
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	right: 0;
+	left: auto;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+	right: @row-header-width;
+	left: 0;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+	right: 0;
+	left: auto;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+	right: 0;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+	left: 0;
+	right: auto;
+}
+
+.tundra .dojoxCalendarColumnViewRtl .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	text-align: right;
+	right: 2px;
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/tundra/Common.less b/dojox/calendar/themes/tundra/Common.less
new file mode 100755
index 0000000..8f25802
--- /dev/null
+++ b/dojox/calendar/themes/tundra/Common.less
@@ -0,0 +1,69 @@
+ at outer-border: 1px solid #CCCCCC;
+ at inner-border: 1px solid #CCCCCC;
+
+ at row-color:#F8F8F8;
+ at row-color-hover: #E2EBF2;
+ at row-color-active: #BBC4D0;
+
+ at today-color: #FFF2D2;
+ at today-label-color: #FF2200;
+
+ at week-end-color: #F8F8F8;
+ at week-end-label-color:#999999;
+
+ at expand-up-color: #E5F2FE;
+ at expand-down-color: #A5D1FB;
+
+ at label-color: #293A4B;
+ at secondary-label-color: #555;
+
+.border-box(){
+	-webkit-box-sizing: border-box;
+	-moz-box-sizing: border-box;
+	box-sizing: border-box;
+}
+
+.opacity(@op){
+	filter: ~"alpha(opacity=@{op})";	
+	opacity:@op/100;
+}
+
+.transition-duration(@dur: 0s){
+	-webkit-transition-duration: @dur;
+	-moz-transition-duration: @dur;
+	transition-duration: @dur;
+}
+
+.select-none() {
+	-moz-user-select: none;
+	-webkit-user-select: none;
+	khtml-user-select: none;
+	user-select: none;
+}
+
+.glass-view(){
+	z-index: 2;
+	background:#00FF00; 
+	.opacity(0);
+	.select-none
+}
+
+.header-background(){
+	background: #F8F8F8;
+	background:#F8F8F8 url("images/titleBar.png") repeat-x bottom left;
+	padding:3px 4px;
+}
+
+.header-hover-background(){
+	background: #f8fafd url("images/accordionItemHover.gif") bottom repeat-x;
+}
+
+.header-active-background(){
+	cursor: pointer;		
+}
+
+.rounded-corners (@radius: 5px) {
+  border-radius: @radius;
+  -webkit-border-radius: @radius;
+  -moz-border-radius: @radius;
+}
diff --git a/dojox/calendar/themes/tundra/MatrixView.css b/dojox/calendar/themes/tundra/MatrixView.css
new file mode 100644
index 0000000..43f7017
--- /dev/null
+++ b/dojox/calendar/themes/tundra/MatrixView.css
@@ -0,0 +1,358 @@
+.tundra .dojoxCalendarMatrixView {
+  cursor: default;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGrid {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 30px;
+  bottom: 0px;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+  text-align: right;
+  vertical-align: top;
+  border-bottom: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable td span {
+  padding-right: 2px;
+  padding-top: 2px;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td {
+  border-bottom: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+/* 
+ * The dojoxCalendarColToday & dojoxCalendarColWeekend classes is added by the 
+ * MatrixView.styleGridCell method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable td.dojoxCalendarToday {
+  background-color: #fff2d2;
+  font-weight: bold;
+  color: #ff2200;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #f8f8f8;
+  color: #999999;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarDayDisabled {
+  background-color: #fdfdfd;
+  color: #999999;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  left: 0px;
+  top: 0px;
+  width: 50px;
+  height: 29px;
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid #cccccc;
+  border-top: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  background: #F8F8F8;
+  background: #f8f8f8 url("images/titleBar.png") repeat-x bottom left;
+  padding: 3px 4px;
+  color: #293a4b;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeader {
+  position: absolute;
+  left: 50px;
+  right: 0px;
+  top: 0px;
+  height: 29px;
+  cursor: default;
+  border-bottom: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  table-layout: fixed;
+  border-collapse: collapse;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  vertical-align: middle;
+  text-align: center;
+  background: #F8F8F8;
+  background: #f8f8f8 url("images/titleBar.png") repeat-x bottom left;
+  padding: 3px 4px;
+  border-right: 1px solid #cccccc;
+  border-top: 1px solid #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+/* 
+ * The dojoxCalendarColWeekend class is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css class.
+ */
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #999999;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+  position: absolute;
+  left: 0px;
+  top: 30px;
+  width: 50px;
+  bottom: 0;
+  cursor: default;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  border-collapse: collapse;
+  table-layout: fixed;
+  margin: 0;
+  padding: 0;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+/* 
+ * The MatrixView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+  text-align: center;
+  vertical-align: middle;
+  border-left: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  background-color: #f8f8f8;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  color: #293a4b;
+  cursor: pointer;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.last-child {
+  border-bottom: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Hover {
+  background-color: #e2ebf2;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Active {
+  background-color: #bbc4d0;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarContainer {
+  position: absolute;
+  top: 30px;
+  left: 50px;
+  right: 0px;
+  bottom: 0px;
+  cursor: default;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarContainerTable {
+  position: relative;
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  padding: 0;
+  border-collapse: collapse;
+  table-layout: fixed;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarContainerTable tr {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarContainerTable td {
+  vertical-align: top;
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarContainerTable td div.dojoxCalendarContainerRow {
+  position: relative;
+  height: 100%;
+  width: 100%;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #000000;
+  cursor: default;
+  white-space: nowrap;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal {
+  color: #FFF;
+  position: absolute;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .bg {
+  border: 1px solid #260000;
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  color: #000000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9f0000;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Hovered .bg {
+  background-color: #cc0000;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Selected .bg {
+  background-color: #660000;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.Edited {
+  color: #fff;
+  font-weight: bold;
+  text-decoration: none;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .bg {
+  border: dashed 1px #FFF;
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Focused .bg {
+  border: dashed 1px #FFF;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Hovered {
+  color: #F40;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Selected {
+  color: #F00;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Edited {
+  border: dashed 1px #FFF;
+  background: #600;
+  filter: alpha(opacity=30);
+  opacity: 0.3;
+  color: #FFF;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Focused {
+  border: dashed 1px #000000;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  position: absolute;
+  left: 3px;
+  right: 1px;
+  bottom: 2px;
+  overflow: hidden;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+  position: absolute;
+  left: 2px;
+  right: 2px;
+  bottom: 0;
+  overflow: hidden;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  position: absolute;
+  width: 5px;
+  height: 100%;
+  cursor: e-resize;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+  left: 0;
+  top: 0;
+  width: 100%;
+  cursor: move;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+  right: 0px;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarExpand {
+  position: absolute;
+  text-align: center;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarExpand span {
+  display: inline-block;
+  vertical-align: middle;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+  position: relative;
+  margin-right: 5px;
+  margin-left: 5px;
+  height: 100%;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  border: 1px solid transparent;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+  background-color: #e5f2fe;
+  border: 1px solid #909da9;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+  background-color: #a5d1fb;
+  border: 1px solid #507ca6;
+}
diff --git a/dojox/calendar/themes/tundra/MatrixView.less b/dojox/calendar/themes/tundra/MatrixView.less
new file mode 100644
index 0000000..c186744
--- /dev/null
+++ b/dojox/calendar/themes/tundra/MatrixView.less
@@ -0,0 +1,373 @@
+ at import "MatrixViewCommon.less";
+
+.tundra .dojoxCalendarMatrixView {	
+	cursor: default;
+	.select-none;
+}
+	
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGrid {
+	position: absolute;
+	left: @row-header-width;
+	right: 0px;
+	top: @column-header-height;
+	bottom: 0px;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable {
+	position: relative;
+	width: 100%;
+	height: 100%;	
+	margin: 0;
+	padding: 0;
+	border-collapse: collapse;
+	table-layout: fixed;	
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable tr{
+	.border-box;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable td {
+	text-align: right;
+	vertical-align: top;	
+	border-bottom: @inner-border;
+	border-right: @inner-border;
+	.border-box;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable td span{
+	padding-right: 2px;
+	padding-top: 2px;		
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable td span.FirstVisibleDayOfMonth{	
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable tr.last-child td	{
+	border-bottom: @outer-border;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable td.last-child	{
+	border-right: @outer-border;
+}
+
+/* 
+ * The dojoxCalendarColToday & dojoxCalendarColWeekend classes is added by the 
+ * MatrixView.styleGridCell method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable td.dojoxCalendarToday	{
+	background-color: @today-color;		
+	font-weight: bold;
+	color: @today-label-color;
+}
+			
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+	color: @week-end-label-color;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarGridTable .dojoxCalendarDayDisabled {
+	background-color: @disabled-day-color;
+	color: @disabled-day-label-color;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	left: 0px;
+	top: 0px;
+	width: @row-header-width;
+	height: @column-header-height - 1px;
+	text-align: center;
+	vertical-align: middle;
+	border-bottom: @outer-border;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table{
+	position: relative;		
+	width:100%;
+	height: 100%;
+	table-layout: fixed;
+	border-collapse: collapse;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarYearColumnHeader table td{
+	text-align: center;
+	vertical-align: middle;		
+	border-left: @outer-border;
+	border-top: @outer-border;
+	border-right: @outer-border;
+	.header-background;
+	color: @label-color;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeader {
+	position: absolute;
+	left: @row-header-width;
+	right: 0px;
+	top: 0px;
+	height: @column-header-height - 1px;
+	cursor: default;
+	border-bottom: @outer-border;	
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable {
+	position: relative;		
+	width:100%;
+	height: 100%;
+	table-layout: fixed;
+	border-collapse: collapse;		
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+	overflow:hidden;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	.select-none;
+	color: @label-color;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td.last-child {
+	border-right: @outer-border;
+}
+
+/* 
+ * The dojoxCalendarColWeekend class is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css class.
+ */
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+	color: @week-end-label-color;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeader {
+	position: absolute;
+	left: 0px;				
+	top: @column-header-height;
+	width: @row-header-width;
+	bottom: 0;
+	cursor: default;
+	
+	.select-none;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable {
+	position: relative;			
+	width: 100%;
+	height: 100%;
+	border-collapse: collapse;
+	table-layout: fixed;
+	margin: 0;
+	padding: 0;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable tr{
+	.border-box;
+}
+
+/* 
+ * The MatrixView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td {
+	text-align: center;
+	vertical-align: middle;	
+	border-left: @outer-border;
+	border-right: @outer-border;
+	border-bottom: @inner-border;
+	background-color: @row-color;
+	.transition-duration(0.2s);
+	.border-box;
+	color: @label-color;
+	cursor: pointer;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.last-child {
+	border-bottom: @outer-border;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Hover {
+	background-color: @row-color-hover;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarRowHeaderTable td.Active {
+	background-color: @row-color-active;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarContainer {
+	position: absolute;
+	top: @column-header-height;
+	left: @row-header-width;
+	right: 0px;
+	bottom: 0px;
+	cursor: default;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarContainerTable {
+	position: relative;
+	width: 100%;
+	height: 100%;	
+	margin: 0;
+	padding: 0;
+	border-collapse: collapse;
+	table-layout: fixed;	
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarContainerTable tr{
+	.border-box;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarContainerTable td{
+	vertical-align: top;
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	.border-box;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarContainerTable td div.dojoxCalendarContainerRow{
+	position:relative;
+	height:100%;
+	width:100%;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+ 	.select-none;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent {	
+	position: absolute;
+	text-align: left;
+	color: #000000;
+	cursor: default;
+	white-space: nowrap;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal {
+	color: #FFF;
+	position: absolute;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .bg {
+	border: @horizontal-border;	
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;	
+	color: #000000;	
+	.rounded-corners(5px);
+	background-color: @horizontal-color;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Hovered  .bg {
+	background-color: @horizontal-hover-color;	
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Selected .bg {
+	background-color: @horizontal-selected-bg-color;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.Edited {
+	color: #fff;
+	font-weight: bold;
+	text-decoration: none;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Edited .bg {
+	border: dashed 1px #FFF;
+	.opacity(30);
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal.Focused .bg {
+	border: dashed 1px #FFF;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Hovered {
+	color: #F40;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Selected {
+	color: #F00;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Edited {
+	border: dashed 1px #FFF;
+	background: #600;
+	.opacity(30);
+	color: #FFF;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel.Focused {
+	border: dashed 1px #000000;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	position: absolute;
+	left: 3px;
+	right: 1px;
+	bottom: 2px;
+	overflow: hidden;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+	position: absolute;
+	left: 2px;
+	right: 2px;
+	bottom: 0;
+	overflow: hidden;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent .handle {
+	.glass-view;
+	position: absolute;
+	width:5px;
+	height:100%;
+	cursor:e-resize;	
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent .moveHandle {
+	left:0;
+	top:0;
+	width:100%;
+	cursor:move;	
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeStartHandle {
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarEvent .resizeEndHandle {
+	right:0px;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarExpand {
+	position: absolute;
+	text-align: center;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarExpand span {
+	display: inline-block;
+	vertical-align: middle;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarExpand .bg {
+	position: relative;
+	margin-right: 5px;
+	margin-left: 5px;
+	height: 100%;
+	.rounded-corners(5px);
+	.transition-duration(0.2s);
+	.border-box;	
+	border: 1px solid transparent;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarExpand.Up .bg {
+	background-color: @expand-up-color;
+	border: 1px solid @expand-up-color - #555555;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarExpand.Down .bg {
+	background-color: @expand-down-color;
+	border: 1px solid @expand-down-color - #555555;
+}
diff --git a/dojox/calendar/themes/tundra/MatrixViewCommon.less b/dojox/calendar/themes/tundra/MatrixViewCommon.less
new file mode 100644
index 0000000..a1a2efc
--- /dev/null
+++ b/dojox/calendar/themes/tundra/MatrixViewCommon.less
@@ -0,0 +1,12 @@
+ at import "Common.less";
+
+ at disabled-day-color: #FDFDFD;
+ at disabled-day-label-color: #999999;
+
+ at horizontal-color: #9F0000;
+ at horizontal-hover-color: #CC0000;
+ at horizontal-selected-bg-color: #660000;
+ at horizontal-border: 1px solid #260000;
+
+ at column-header-height: 30px;
+ at row-header-width: 50px;
diff --git a/dojox/calendar/themes/tundra/MatrixView_rtl.css b/dojox/calendar/themes/tundra/MatrixView_rtl.css
new file mode 100644
index 0000000..09d1210
--- /dev/null
+++ b/dojox/calendar/themes/tundra/MatrixView_rtl.css
@@ -0,0 +1,56 @@
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+  right: 50px;
+  left: 0;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {
+  text-align: left;
+  border-bottom: 1px solid #cccccc;
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span {
+  padding-left: 2px;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+  right: 50px;
+  left: 0;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+  border-bottom: solid 1px transparent;
+  border-right: solid 1px transparent;
+  text-align: right;
+  vertical-align: top;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  right: 0;
+  left: auto;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+  right: 50px;
+  left: 0;
+}
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+  right: 0;
+  left: auto;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+  text-align: right;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+  text-align: right;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+  right: 0;
+}
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+  left: 0;
+  right: auto;
+}
diff --git a/dojox/calendar/themes/tundra/MatrixView_rtl.less b/dojox/calendar/themes/tundra/MatrixView_rtl.less
new file mode 100644
index 0000000..f1e01bd
--- /dev/null
+++ b/dojox/calendar/themes/tundra/MatrixView_rtl.less
@@ -0,0 +1,71 @@
+ at import "MatrixViewCommon.less";
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarGrid {
+	right: @row-header-width;
+	left: 0;
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td {			
+	text-align: left;
+	border-bottom: @inner-border;
+	border-left: @inner-border;
+	border-right: none;
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td span{
+	padding-left: 2px;
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarGridTable td.last-child	{
+	border-left: @outer-border;
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarContainer {
+	right: @row-header-width;
+	left: 0;
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarContainerTable td {
+	border-bottom: solid 1px transparent;
+	border-right: solid 1px transparent;
+	text-align: right;
+	vertical-align: top;		
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	right: 0;
+	left: auto;
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarColumnHeader {
+	right: @row-header-width;
+	left: 0;
+}
+
+.tundra .dojoxCalendarMatrixView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @outer-border;
+	border-right: none;
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarRowHeader {
+	right: 0;
+	left: auto;
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarHorizontal .labels {
+	text-align: right;
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent.dojoxCalendarLabel .labels {
+	text-align: right;
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeStartHandle {
+	right: 0;
+}
+
+.tundra .dojoxCalendarMatrixViewRtl .dojoxCalendarEvent .resizeEndHandle {
+	left:0;
+	right:auto;
+}
\ No newline at end of file
diff --git a/dojox/calendar/themes/tundra/MonthColumnView.css b/dojox/calendar/themes/tundra/MonthColumnView.css
new file mode 100644
index 0000000..6269957
--- /dev/null
+++ b/dojox/calendar/themes/tundra/MonthColumnView.css
@@ -0,0 +1,258 @@
+.tundra .dojoxCalendarMonthColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 30px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-bottom: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGrid {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td span {
+  padding-left: 3px;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff2d2;
+  font-weight: bold;
+  color: #ff2200;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarHiddenEvents {
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents {
+  background: #fff2d2 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.first-child {
+  border-left: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff2d2;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #f8f8f8;
+  color: #999999;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #f8f8f8;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  cursor: default;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 35px;
+  margin-right: 5px;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 0;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background: #F8F8F8;
+  background: #f8f8f8 url("images/titleBar.png") repeat-x bottom left;
+  padding: 3px 4px;
+  border-right: 1px solid #cccccc;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.first-child {
+  border-left: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background: #f8fafd url("images/accordionItemHover.gif") bottom repeat-x;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+  overflow: hidden;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9F0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 30px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/tundra/MonthColumnView.less b/dojox/calendar/themes/tundra/MonthColumnView.less
new file mode 100644
index 0000000..3c84bbf
--- /dev/null
+++ b/dojox/calendar/themes/tundra/MonthColumnView.less
@@ -0,0 +1,281 @@
+ at import "ColumnViewCommon.less";
+
+.tundra .dojoxCalendarMonthColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarScrollContainer {
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: @column-header-height;
+	position: absolute;
+	overflow-y: hidden;
+	overflow-x: hidden;	
+	border-bottom: @outer-border;
+	.border-box;
+}
+	
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGrid {
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td {
+	border-top: dotted 1px #B5BCC7;	
+	border-right: @inner-border;
+	.border-box;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable td span {
+  padding-left:3px;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td	{
+	border-top: 1px solid transparent;
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+	background-color: @today-color;
+	font-weight: bold;
+	color: @today-label-color;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarHiddenEvents	{	
+	background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;	
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents	{	
+	background: @today-color url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAF0lEQVQYlWP4z8Dw/1dU1H8GXGBkKAAA+IglWfcls2QAAAAASUVORK5CYII=) repeat-y;	
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.last-child	{
+	border-right: @outer-border;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr td.first-child	{
+	border-left: @outer-border;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday	{
+	border-top: 1px solid @today-color;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+	color: @week-end-label-color;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend	{
+	border-top: 1px solid @week-end-color;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarContainer {
+	position: absolute;
+	top: 0;
+	left: 0;
+	right: 0;
+	cursor: default;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarContainerTable td {
+	height: 100%;
+	padding: 0;
+	vertical-align: top;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarContainerColumn {
+	position:	relative;
+	margin-left: 35px;
+	margin-right: 5px;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+	.select-none;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeader {
+	position: absolute;
+	height: @column-header-height;	 
+	left: 0;
+	right: 0;
+	top: 0;
+	cursor: default;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;			
+	width: 100%;
+	height: 100%;	
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {	
+	overflow:hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.select-none;
+	color: @label-color;
+	.transition-duration(0.2s);
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-right: @outer-border;	
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.first-child {	
+	border-left: @outer-border;	
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Hover{	
+	cursor: pointer;		
+	.header-hover-background;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td.Active{	
+	.header-active-background;
+}
+ 
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent {
+	position: absolute;	
+	text-align: left;
+	color: #FFF;
+	cursor: default;
+	overflow: hidden;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .bg {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: -1;
+	border: 1px solid #260000;	
+	.rounded-corners;
+	background-color: #9F0000;
+	.opacity(90);
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Hovered .bg {
+	background-color: #CC0000;	
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Selected .bg {
+	background-color: #660000;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Edited .bg {
+	border: dashed 1px #FFFFFF;
+	.opacity(70);
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent.Focused .bg {
+	border: dashed 1px #FFFFFF;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .summary {
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .startTime {
+	font-weight: bold;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .endTime {
+	position: absolute;		
+	font-weight: bold;	
+	bottom:3px;
+	left: 6px;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .beforeIcon {
+	text-align: center;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .afterIcon {
+	position: absolute;
+	bottom: 2px;
+	width: 100%;
+	text-align: center;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .handle {
+	.glass-view;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .moveHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	bottom:0;
+	cursor:move;	
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeStartHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent .resizeEndHandle {
+	position: absolute;
+	bottom:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarVScrollBar {
+	position: absolute;
+	top: @column-header-height;
+	bottom: 0;
+	overflow-y: scroll;
+	overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/tundra/MonthColumnViewCommon.less b/dojox/calendar/themes/tundra/MonthColumnViewCommon.less
new file mode 100644
index 0000000..9bb3ec8
--- /dev/null
+++ b/dojox/calendar/themes/tundra/MonthColumnViewCommon.less
@@ -0,0 +1,7 @@
+ at import "Common.less";
+
+ at hour-stroke: 1px solid #C7BEBE;
+ at half-hour-stroke: dotted 1px #C7BEBE;
+ at quarter-hour-stroke: dotted 1px #C7BEBE;
+
+ at column-header-height: 30px;
diff --git a/dojox/calendar/themes/tundra/MonthColumnView_rtl.css b/dojox/calendar/themes/tundra/MonthColumnView_rtl.css
new file mode 100644
index 0000000..06ce343
--- /dev/null
+++ b/dojox/calendar/themes/tundra/MonthColumnView_rtl.css
@@ -0,0 +1,42 @@
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td {
+  border-right: none;
+  border-left: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td span {
+  padding-right: 3px;
+}
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable .dojoxCalendarHiddenEvents {
+  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents {
+  background: #fff2d2 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;
+}
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.first-child {
+  border-right: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarContainerColumn {
+  margin-left: 5px;
+  margin-right: 35px;
+}
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {
+  border-left: 1px solid #cccccc;
+  border-right: none;
+}
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.last-child {
+  border-left: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.first-child {
+  border-right: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .summary {
+  text-align: right;
+}
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .startTime {
+  text-align: right;
+}
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .endTime {
+  text-align: right;
+}
diff --git a/dojox/calendar/themes/tundra/MonthColumnView_rtl.less b/dojox/calendar/themes/tundra/MonthColumnView_rtl.less
new file mode 100644
index 0000000..3197695
--- /dev/null
+++ b/dojox/calendar/themes/tundra/MonthColumnView_rtl.less
@@ -0,0 +1,56 @@
+ at import "ColumnViewCommon.less";
+
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td {
+	border-right: none;	
+	border-left: @inner-border;
+}
+
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable td span {
+  padding-right:3px;
+}
+
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable .dojoxCalendarHiddenEvents	{
+	background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y right top;	
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarGridTable .dojoxCalendarToday.dojoxCalendarHiddenEvents	{	
+	background: @today-color url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAICAYAAADTLS5CAAAAFElEQVQImWP4z8Dw/1dU1H8GyhgANcclWWHC27gAAAAASUVORK5CYII=) repeat-y  right top;	
+}
+
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.last-child	{
+	border-left: @outer-border;	
+}
+
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarGridTable tr td.first-child	{
+	border-right: @outer-border;
+}
+
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarContainerColumn {	
+	margin-left: 5px;
+	margin-right: 35px;
+}
+
+.tundra .dojoxCalendarMonthColumnView .dojoxCalendarColumnHeaderTable td {	
+	border-left: @inner-border;
+	border-right: none;	
+}
+
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-left: @outer-border;	
+}
+
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarColumnHeaderTable td.first-child {	
+	border-right: @outer-border;	
+}
+ 
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .summary {
+	text-align: right;
+}
+
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .startTime {
+	text-align: right;
+}
+
+.tundra .dojoxCalendarMonthColumnViewRtl .dojoxCalendarEvent .endTime {
+	text-align: right;
+}
diff --git a/dojox/calendar/themes/tundra/SimpleColumnView.css b/dojox/calendar/themes/tundra/SimpleColumnView.css
new file mode 100644
index 0000000..3d74593
--- /dev/null
+++ b/dojox/calendar/themes/tundra/SimpleColumnView.css
@@ -0,0 +1,346 @@
+.tundra .dojoxCalendarSimpleColumnView {
+  cursor: default;
+  -webkit-user-select: none;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarHeader {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  height: 29px;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarScrollContainer {
+  left: 0;
+  right: 0;
+  bottom: 0;
+  top: 30px;
+  position: absolute;
+  overflow-y: hidden;
+  overflow-x: hidden;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGrid {
+  position: absolute;
+  left: 70px;
+  right: 0;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable td {
+  border-top: dotted 1px #B5BCC7;
+  border-right: 1px solid #cccccc;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td {
+  border-top: 1px solid transparent;
+}
+.tundra .dojoxCalendarColumnView td.hour {
+  border-top: 1px solid #eeeeee;
+}
+.tundra .dojoxCalendarColumnView td.halfhour {
+  border-top: dotted 1px #eeeeee;
+}
+.tundra .dojoxCalendarColumnView td.quarterhour {
+  border-top: dotted 1px #eeeeee;
+}
+.tundra .dojoxCalendarColumnView span.hour {
+  color: #293a4b;
+  background-color: #f8f8f8;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+  background-color: #fff2d2;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr td.last-child {
+  border-right: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday {
+  border-top: 1px solid #fff2d2;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+  background-color: #f8f8f8;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend {
+  border-top: 1px solid #f8f8f8;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarContainer {
+  position: absolute;
+  top: 0;
+  left: 70px;
+  right: 0;
+  cursor: default;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  width: 100%;
+  position: relative;
+  margin: 0;
+  padding: 0;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable td {
+  height: 100%;
+  padding: 0;
+  vertical-align: top;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarContainerColumn {
+  position: relative;
+  margin-left: 2px;
+  margin-right: 9px;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEventContainer {
+  position: absolute;
+  overflow: hidden;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader {
+  position: absolute;
+  height: 29px;
+  left: 0;
+  width: 68px;
+  top: 0;
+  border-left: 1px solid #cccccc;
+  border-top: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table td {
+  text-align: center;
+  vertical-align: middle;
+  border-bottom: 1px solid #cccccc;
+  color: #293a4b;
+  background: #F8F8F8;
+  background: #f8f8f8 url("images/titleBar.png") repeat-x bottom left;
+  padding: 3px 4px;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeader {
+  position: absolute;
+  height: 30px;
+  left: 70px;
+  right: 0;
+  top: 0;
+  cursor: default;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td {
+  overflow: hidden;
+  white-space: nowrap;
+  vertical-align: middle;
+  text-align: center;
+  background: #F8F8F8;
+  background: #f8f8f8 url("images/titleBar.png") repeat-x bottom left;
+  padding: 3px 4px;
+  border-right: 1px solid #cccccc;
+  border-top: 1px solid #cccccc;
+  border-bottom: 1px solid #cccccc;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+  color: #293a4b;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.last-child {
+  border-right: 1px solid #cccccc;
+}
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+  font-weight: bold;
+  color: #ff2200;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+  color: #999999;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Hover {
+  cursor: pointer;
+  background: #f8fafd url("images/accordionItemHover.gif") bottom repeat-x;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Active {
+  cursor: pointer;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeader {
+  position: absolute;
+  width: 68px;
+  cursor: default;
+  border-left: 1px solid #cccccc;
+  border-right: 1px solid #cccccc;
+  height: 100%;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabelContainer {
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+}
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel {
+  right: 4px;
+  position: absolute;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable {
+  border-collapse: collapse;
+  table-layout: fixed;
+  position: relative;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td.dummy {
+  border-top: 1px solid #f8f8f8;
+}
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td {
+  vertical-align: top;
+  text-align: right;
+  border-top: 1px solid #cccccc;
+  background-color: #f8f8f8;
+  color: #293a4b;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable tr:first-child td {
+  border-top: 1px solid #f8f8f8;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent {
+  position: absolute;
+  text-align: left;
+  color: #FFF;
+  cursor: default;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .bg {
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  bottom: 0;
+  z-index: -1;
+  border: 1px solid #260000;
+  border-radius: 5px;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  background-color: #9F0000;
+  filter: alpha(opacity=90);
+  opacity: 0.9;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Hovered .bg {
+  background-color: #CC0000;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Selected .bg {
+  background-color: #660000;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Edited .bg {
+  border: dashed 1px #FFFFFF;
+  filter: alpha(opacity=70);
+  opacity: 0.7;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Focused .bg {
+  border: dashed 1px #FFFFFF;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .startTime {
+  font-weight: bold;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .endTime {
+  position: absolute;
+  font-weight: bold;
+  bottom: 3px;
+  left: 6px;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .beforeIcon {
+  text-align: center;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .afterIcon {
+  position: absolute;
+  bottom: 2px;
+  width: 100%;
+  text-align: center;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .handle {
+  z-index: 2;
+  background: #00FF00;
+  filter: alpha(opacity=0);
+  opacity: 0;
+  -moz-user-select: none;
+  -webkit-user-select: none;
+  khtml-user-select: none;
+  user-select: none;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .moveHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  bottom: 0;
+  cursor: move;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeStartHandle {
+  position: absolute;
+  top: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeEndHandle {
+  position: absolute;
+  bottom: 0;
+  width: 100%;
+  height: 10px;
+  cursor: n-resize;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dl {
+  margin: 0;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dd {
+  margin: 0;
+  padding: 0 3px;
+  text-align: left;
+}
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarVScrollBar {
+  position: absolute;
+  top: 30px;
+  bottom: 0;
+  overflow-y: scroll;
+  overflow-x: hidden;
+}
diff --git a/dojox/calendar/themes/tundra/SimpleColumnView.less b/dojox/calendar/themes/tundra/SimpleColumnView.less
new file mode 100644
index 0000000..6a73258
--- /dev/null
+++ b/dojox/calendar/themes/tundra/SimpleColumnView.less
@@ -0,0 +1,378 @@
+ at import "ColumnViewCommon.less";
+
+ at row-header-width: 70px;
+ at secondary-sheet-height: 0px;
+ at sheet-top: @column-header-height;
+
+.tundra .dojoxCalendarSimpleColumnView {	
+  cursor: default;
+	-webkit-user-select: none;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarHeader {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: @column-header-height - 1px;
+	.border-box;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarScrollContainer {
+	left: 0;
+	right: 0;
+	bottom: 0;
+	top: @sheet-top;
+	position: absolute;
+	overflow-y: hidden;
+	overflow-x: hidden;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.border-box;
+}
+	
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGrid {
+	position: absolute;
+	left: @row-header-width;
+	right: 0;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable td {
+	border-top: dotted 1px #B5BCC7;	
+	border-right: @inner-border;
+	.border-box;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td	{
+	border-top: 1px solid transparent;
+}
+
+.tundra .dojoxCalendarColumnView td.hour {
+	border-top: @hour-stroke;
+}
+
+.tundra .dojoxCalendarColumnView td.halfhour{
+	border-top: @half-hour-stroke;	
+}
+
+.tundra .dojoxCalendarColumnView  td.quarterhour{
+	border-top: @quarter-hour-stroke;
+}
+
+.tundra .dojoxCalendarColumnView span.hour {
+	color: @label-color;
+	background-color: @row-color;
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleGridColumn method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarToday {
+	background-color: @today-color;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr td.last-child	{
+	border-right: @outer-border;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarToday	{
+	border-top: 1px solid @today-color;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable .dojoxCalendarWeekend {
+	background-color: @week-end-color;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarGridTable tr:first-child td.dojoxCalendarWeekend	{
+	border-top: 1px solid @week-end-color;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarContainer {
+	position: absolute;
+	top: 0;
+	left: @row-header-width;
+	right: 0;
+	cursor: default;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	width: 100%;
+	position: relative;
+	margin: 0;
+	padding: 0;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarContainerTable td {
+	height: 100%;
+	padding: 0;
+	vertical-align: top;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarContainerColumn {
+	position:	relative;
+	margin-left: 2px;
+	margin-right: 9px;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEventContainer {
+	position: absolute;
+	overflow: hidden;
+	.select-none;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader{
+	position: absolute;
+	height: @column-header-height - 1px;
+	left: 0;
+	width: @row-header-width - 2px;
+	top: 0;	
+	border-left: @outer-border;
+	border-top: @outer-border;
+	border-right: @outer-border;	
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table {
+	position:relative;
+	width:100%;
+	height:100%;	
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarYearColumnHeader table td {
+	text-align: center;
+	vertical-align: middle;
+	border-bottom: @outer-border;	
+	color: @label-color;
+	.header-background;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeader {
+	position: absolute;
+	height: @column-header-height;	 
+	left: @row-header-width;
+	right: 0;
+	top: 0;
+	cursor: default;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;			
+	width: 100%;
+	height: 100%;	
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td {	
+	overflow:hidden;
+	white-space: nowrap;
+	vertical-align: middle;
+	text-align: center;
+	.header-background;
+	border-right: @inner-border;
+	border-top: @outer-border;
+	border-bottom: @outer-border;
+	.select-none;
+	color: @label-color;
+	.transition-duration(0.2s);
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.last-child {	
+	border-right: @outer-border;	
+}
+
+/* 
+ * The dojoxCalendarToday & dojoxCalendarWeekend classes is added by the 
+ * ColumnView.styleColumnHeaderCell method that can be subclassed to add/remove css classes
+ */
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarToday {
+	font-weight: bold;
+	color: @today-label-color;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable .dojoxCalendarWeekend {
+	color: @week-end-label-color;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Hover{	
+	cursor: pointer;		
+	.header-hover-background;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarColumnHeaderTable td.Active{	
+	.header-active-background;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeader {
+	position: absolute;
+	width: @row-header-width - 2px;
+	cursor: default;
+	border-left: @outer-border;
+	border-right: @outer-border;
+	height: 100%;
+	.select-none;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabelContainer{
+	width: 100%;
+	height: 100%;
+	z-index: 10;
+}
+
+.tundra .dojoxCalendarColumnView .dojoxCalendarRowHeaderLabel{	
+	right: 4px;		
+	position: absolute;	
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable {
+	border-collapse: collapse;
+	table-layout: fixed;
+	position: relative;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td.dummy{
+	border-top: 1px solid @row-color;
+}
+
+/* 
+ * The ColumnView.styleRowHeaderCell method that can be subclassed to add/remove css classes per hour.
+ */
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable td {	
+	vertical-align: top;			
+	text-align: right;	
+	border-top: @outer-border; 	
+	background-color: @row-color;
+	color: @label-color;
+	.border-box;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarRowHeaderTable tr:first-child td	{
+	border-top: 1px solid @row-color;
+}
+ 
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent {
+	position: absolute;	
+	text-align: left;
+	color: #FFF;
+	cursor: default;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .bg {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	bottom: 0;
+	z-index: -1;
+	border: 1px solid #260000;	
+	.rounded-corners;
+	background-color: #9F0000;
+	.opacity(90);
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Hovered .bg {
+	background-color: #CC0000;	
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Selected .bg {
+	background-color: #660000;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Edited .bg {
+	border: dashed 1px #FFFFFF;
+	.opacity(70);
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent.Focused .bg {
+	border: dashed 1px #FFFFFF;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .summary {
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .startTime {
+	font-weight: bold;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .endTime {
+	position: absolute;		
+	font-weight: bold;	
+	bottom:3px;
+	left: 6px;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .beforeIcon {
+	text-align: center;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .afterIcon {
+	position: absolute;
+	bottom: 2px;
+	width: 100%;
+	text-align: center;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .handle {
+	.glass-view;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .moveHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	bottom:0;
+	cursor:move;	
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeStartHandle {
+	position: absolute;
+	top:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent .resizeEndHandle {
+	position: absolute;
+	bottom:0;
+	width:100%;
+	height:10px;
+	cursor:n-resize;	
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dl {
+	margin: 0;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarEvent dd {
+	margin: 0;
+	padding: 0 3px;
+	text-align: left;
+}
+
+.tundra .dojoxCalendarSimpleColumnView .dojoxCalendarVScrollBar {
+	position: absolute;
+	top: @sheet-top;
+	bottom: 0;
+	overflow-y: scroll;
+	overflow-x: hidden;
+}
+
+
diff --git a/dojox/calendar/themes/tundra/images/accordionItemHover.gif b/dojox/calendar/themes/tundra/images/accordionItemHover.gif
new file mode 100644
index 0000000..96bd3a4
Binary files /dev/null and b/dojox/calendar/themes/tundra/images/accordionItemHover.gif differ
diff --git a/dijit/themes/tundra/images/titleBar.png b/dojox/calendar/themes/tundra/images/titleBar.png
similarity index 100%
copy from dijit/themes/tundra/images/titleBar.png
copy to dojox/calendar/themes/tundra/images/titleBar.png
diff --git a/dojox/calendar/time.js b/dojox/calendar/time.js
new file mode 100644
index 0000000..f8e719d
--- /dev/null
+++ b/dojox/calendar/time.js
@@ -0,0 +1,176 @@
+define(["dojo/_base/lang", "dojo/date", "dojo/cldr/supplemental","dojo/date/stamp"], function(lang, date, cldr, stamp) {
+
+// summary: Advanced date manipulation utilities.
+
+var time = {};
+
+
+time.newDate = function(obj, dateClassObj){
+	// summary:
+	//		Creates a new Date object.
+	// obj: Object
+	//		This object can have several values:
+	//		- the time in milliseconds since gregorian epoch.
+	//		- a Date instance
+	//		- a String instance that can be decoded by the dojo/date/stamp class.
+	// dateClassObj: Object?
+	//		The Date class used, by default the native Date.
+
+	// returns: Date
+	dateClassObj = dateClassObj || Date;  
+	var d;
+	
+	if(typeof(obj) == "number"){
+		return new dateClassObj(time);
+	}else if(obj.getTime){
+		return new dateClassObj(obj.getTime());
+	}else if(obj.toGregorian){
+		d = obj.toGregorian();
+		if(dateClassObj !== Date){
+			d = new dateClassObj(d.getTime());
+		}
+		return d;
+	}else if(typeof obj == "string"){
+		d = stamp.fromISOString(obj);
+		if(d === null){
+			throw new Error("Cannot parse date string ("+obj+"), specify a \"decodeDate\" function that translates this string into a Date object"); // cannot build date
+		}else if(dateClassObj !== Date){ // from Date to dateClassObj
+			d = new dateClassObj(d.getTime());
+		}
+		return d;
+	}
+
+};
+
+time.floorToDay = function(d, reuse, dateClassObj){
+	// summary:
+	//		Floors the specified date to the start of day.
+	// date: Date
+	//		The date to floor.
+	// reuse: Boolean
+	//		Whether use the specified instance or create a new one. Default is false.
+	// dateClassObj: Object?
+	//		The Date class used, by default the native Date.	
+	// returns: Date
+	dateClassObj = dateClassObj || Date;  
+	
+	if(!reuse){
+		d = time.newDate(d, dateClassObj);
+	}
+	
+	d.setHours(0, 0, 0, 0);
+		
+	return d;
+};
+
+time.floorToMonth = function(d, reuse, dateClassObj){
+	// summary:
+	//		Floors the specified date to the start of the date's month.
+	// date: Date
+	//		The date to floor.
+	// reuse: Boolean
+	//		Whether use the specified instance or create a new one. Default is false.
+	// dateClassObj: Object?
+	//		The Date class used, by default the native Date.	
+	// returns: Date
+	dateClassObj = dateClassObj || Date;  
+	
+	if(!reuse){
+		d = time.newDate(d, dateClassObj);
+	}
+	
+	d.setDate(1);
+	d.setHours(0, 0, 0, 0);
+	
+	return d;
+};
+
+
+time.floorToWeek = function(d, dateClassObj, dateModule, firstDayOfWeek, locale){
+	// summary:
+	//		Floors the specified date to the beginning of week.
+	// d: Date
+	//		Date to floor.
+	// dateClassObj: Object?
+	//		The Date class used, by default the native Date.	
+	// dateModule: Object?
+	//		Object that contains the "add" method. By default dojo.date is used.
+	// firstDayOfWeek: Integer?
+	//		Optional day of week that overrides the one provided by the CLDR.	
+	// locale: String?
+	//		Optional locale used to determine first day of week.
+	dateClassObj = dateClassObj || Date; 
+	dateModule = dateModule || date;  	
+	
+	var fd = firstDayOfWeek == undefined || firstDayOfWeek < 0 ? cldr.getFirstDayOfWeek(locale) : firstDayOfWeek;
+	var day = d.getDay();
+	if(day == fd){
+		return d;
+	}
+	return time.floorToDay(
+		dateModule.add(d, "day", day > fd ? -day+fd : fd-day),
+		true, dateClassObj);
+};
+
+time.floor = function(date, unit, steps, reuse, dateClassObj){
+	// summary:
+	//		floors the date to the unit.
+	// date: Date
+	//		The date/time to floor.
+	// unit: String
+	//		The unit. Valid values are "minute", "hour", "day".
+	// steps: Integer
+	//		Valid for "minute" or "hour" units.
+	// reuse: Boolean
+	//		Whether use the specified instance or create a new one. Default is false.	
+	// dateClassObj: Object?
+	//		The Date class used, by default the native Date.
+	// returns: Date
+
+	var d = time.floorToDay(date, reuse, dateClassObj);
+	
+	switch(unit){
+		case "week":
+			return time.floorToWeek(d, firstDayOfWeek, dateModule, locale);
+		case "minute":
+			d.setHours(date.getHours());
+			d.setMinutes(Math.floor(date.getMinutes() /steps) * steps);
+			break;
+		case "hour":
+			d.setHours(Math.floor(date.getHours() /steps) * steps);
+			break;
+	}
+	return d;
+};
+
+time.isStartOfDay = function(d, dateClassObj, dateModule){
+	// summary:
+	//		Tests if the specified date represents the starts of day. 
+	// d: Date
+	//		The date to test.
+	// dateClassObj: Object?
+	//		The Date class used, by default the native Date.	
+	// dateModule: Object?
+	//		Object that contains the "add" method. By default dojo.date is used.
+	// returns: Boolean
+	dateModule = dateModule || date;
+	return dateModule.compare(this.floorToDay(d, false, dateClassObj), d) == 0;
+};
+
+time.isToday = function(d, dateClassObj){
+	// summary:
+	//		Returns whether the specified date is in the current day.
+	// d: Date
+	//		The date to test.
+	// dateClassObj: Object?
+	//		The Date class used, by default the native Date.
+	// returns: Boolean
+	dateClassObj = dateClassObj || Date;
+	var today = new dateClassObj();
+	return d.getFullYear() == today.getFullYear() &&
+				 d.getMonth() == today.getMonth() && 
+				 d.getDate() == today.getDate();
+};
+
+return time;
+});
\ No newline at end of file
diff --git a/dojox/charting/BidiSupport.js b/dojox/charting/BidiSupport.js
index fd99ddd..e829200 100644
--- a/dojox/charting/BidiSupport.js
+++ b/dojox/charting/BidiSupport.js
@@ -1,264 +1,4 @@
-define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/array", "dojo/_base/sniff",
-	"dojo/dom","dojo/dom-construct",
-	"dojox/gfx", "dojox/gfx/_gfxBidiSupport", "./Chart", "./axis2d/common", "dojox/string/BidiEngine", "dojox/lang/functional"], 
-	function(lang, html, arr, has, dom, domConstruct, g, gBidi, Chart, da, BidiEngine, df){
-
-	var bidiEngine = new BidiEngine();
-	
-	lang.extend(Chart, {
-		// summary:
-		//		Add support for bidi scripts.
-		// description:
-		//		Bidi stands for support for languages with a bidirectional script. 
-		//		There's a special need for displaying BIDI text in rtl direction 
-		//		in ltr GUI, sometimes needed auto support.
-		//		dojox.charting does not support control over base text direction provided in Dojo.
-
-		// textDir: String
-		//		Bi-directional support,	the main variable which is responsible for the direction of the text.
-		//		The text direction can be different than the GUI direction by using this parameter.
-		// 		Allowed values:
-		//			1. "ltr"
-		//			2. "rtl"
-		//			3. "auto" - contextual the direction of a text defined by first strong letter.
-		//		By default is as the page direction.		
-		textDir:"",
-		
-		getTextDir: function(/*String*/text){
-			// summary:
-			//		Return direction of the text. 
-			// description:
-			// 		If textDir is ltr or rtl returns the value.
-			//		If it's auto, calls to another function that responsible 
-			//		for checking the value, and defining the direction.			
-			// text:
-			//		Used in case textDir is "auto", this case the direction is according to the first
-			//		strong (directionally - which direction is strong defined) letter.
-			//	tags:
-			//		protected.
-			var textDir = this.textDir == "auto" ? bidiEngine.checkContextual(text) : this.textDir;
-			// providing default value
-			if(!textDir){
-				textDir = html.style(this.node,"direction");
-			}
-			return textDir;
-		},
-
-		postscript: function(node,args){
-			// summary:
-			//		Kicks off chart instantiation.
-			// description:
-			//		Used for setting the textDir of the chart. 
-			// tags:
-			//		private
-
-			// validate textDir
-			var textDir = args ? (args["textDir"] ? validateTextDir(args["textDir"]) : "") : "";
-			// if textDir wasn't defined or was defined wrong, apply default value
-			textDir = textDir ? textDir : html.style(this.node,"direction");
-			this.textDir = textDir;
-
-			this.surface.textDir = textDir;
-			
-			// two data structures, used for storing data for further enablement to change
-			// textDir dynamically
-			this.htmlElementsRegistry = [];
-			this.truncatedLabelsRegistry = [];
-		},
-
-		setTextDir: function(/*String*/ newTextDir, obj){
-			// summary:
-			//		Setter for the textDir attribute.
-			// description:
-			//		Allows dynamically set the textDir, goes over all the text-children and  
-			//		updates their base text direction.
-			// tags:
-			//		public
-		
-			if(newTextDir == this.textDir){
-				return this;
-			}
-			if(validateTextDir(newTextDir) != null){
-				this.textDir = newTextDir;
-				
-				// set automatically all the gfx objects that were created by this surface
-				// (groups, text objects)
-				this.surface.setTextDir(newTextDir);
-			
-				// truncated labels that were created with gfx creator need to recalculate dir
-				// for case like: "111111A" (A stands for bidi character) and the truncation
-				// is "111..." If the textDir is auto, the display should be: "...111" but in gfx
-				// case we will get "111...". Because this.surface.setTextDir will calculate the dir of truncated
-				// label, which value is "111..." but th real is "111111A".
-				// each time we created a gfx truncated label we stored it in the truncatedLabelsRegistry, so update now 
-				// the registry.
-				if(this.truncatedLabelsRegistry && newTextDir == "auto"){
-					arr.forEach(this.truncatedLabelsRegistry, function(elem){
-						var tDir = this.getTextDir(elem["label"]);
-						if(elem["element"].textDir != tDir){
-							elem["element"].setShape({textDir: tDir});
-						}
-					}, this);
-				}
-				
-				// re-render axes with html labels. for recalculation of the labels
-				// positions etc.
-				// create array of keys for all the axis in chart 
-				var axesKeyArr = df.keys(this.axes);
-				if(axesKeyArr.length > 0){
-					// iterate over the axes, and for each that have html labels render it.
-					arr.forEach(axesKeyArr, function(key, index, arr){
-						// get the axis 
-						var axis = this.axes[key];
-						// if the axis has html labels 
-						if(axis.htmlElements[0]){
-							axis.dirty = true;
-							axis.render(this.dim, this.offsets);
-						}
-					},this);
-					
-					// recreate title
-					if(this.title){
-						var forceHtmlLabels = (g.renderer == "canvas"),
-							labelType = forceHtmlLabels || !has("ie") && !has("opera") ? "html" : "gfx",
-							tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
-						// remove the title
-						domConstruct.destroy(this.chartTitle);
-						this.chartTitle =null;
-						// create the new title
-						this.chartTitle = da.createText[labelType](
-							this,
-							this.surface,
-							this.dim.width/2,
-							this.titlePos=="top" ? tsize + this.margins.t : this.dim.height - this.margins.b,
-							"middle",
-							this.title,
-							this.titleFont,
-							this.titleFontColor
-						);
-					}				
-				}else{
-				// case of pies, spiders etc.
-					arr.forEach(this.htmlElementsRegistry, function(elem, index, arr){
-						var tDir = newTextDir == "auto" ? this.getTextDir(elem[4]) : newTextDir;
-						if(elem[0].children[0] && elem[0].children[0].dir != tDir){
-							dom.destroy(elem[0].children[0]);
-							elem[0].children[0] = da.createText["html"]
-									(this, this.surface, elem[1], elem[2], elem[3], elem[4], elem[5], elem[6]).children[0];
-						}
-					},this);
-				}
-			}
-		},
-
-		truncateBidi: function(elem, label, labelType){
-			// summary:
-			//		Enables bidi support for truncated labels.
-			// description:
-			//		Can be two types of labels: html or gfx.
-			//		gfx labels: 
-			//			Need to be stored in registry to be used when the textDir will be set dynamically.
-			//			Additional work on truncated labels is needed for case as 111111A (A stands for "bidi" character rtl directioned).
-			//			let say in this case the truncation is "111..." If the textDir is auto, the display should be: "...111" but in gfx
-			//			case we will get "111...". Because this.surface.setTextDir will calculate the dir of truncated
-			//			label, which value is "111..." but th real is "111111A".
-			//			each time we created a gfx truncated label we store it in the truncatedLabelsRegistry.
-			//		html labels:
-			//			no need for repository (stored in another place). Here we only need to update the current dir according to textDir.
-			// tags:
-			//		private
-		
-			if(labelType == "gfx"){
-				// store truncated gfx labels in the data structure.
-				this.truncatedLabelsRegistry.push({element: elem, label: label});
-				if(this.textDir == "auto"){
-					elem.setShape({textDir: this.getTextDir(label)});
-				}
-			}
-			if(labelType == "html" && this.textDir == "auto"){
-				elem.children[0].dir = this.getTextDir(label);
-			}
-		}
-	});
-
-	var extendMethod = function(obj, method, bundleByPrototype, before, after){
-		// Some helper function. Used for extending method of obj.
-		// obj: Object
-		//		The obj we overriding it's method.
-		// method: String
-		//		The method that is extended, the original method is called before or after
-		//		functions that passed to extendMethod.
-		// bundleByPrototype: boolean
-		//		There's two methods to extend, using prototype or not.
-		// before: function
-		//		If defined this function will be executed before the original method.
-		// after: function
-		//		If defined this function will be executed after the original method.
-		if(bundleByPrototype){
-			var old = obj.prototype[method];
-			obj.prototype[method] = 
-				function(){
-					var rBefore;
-					if (before){
-						rBefore = before.apply(this, arguments);
-					}
-					var r = old.apply(this, rBefore);
-					if (after){
-						r = after.call(this, r, arguments);
-					}
-					return r;
-				};
-		}else{
-			var old = lang.clone(obj[method]);
-			obj[method] = 
-				function(){
-					var rBefore;
-					if (before){
-						rBefore = before.apply(this, arguments);
-					}
-					var r = old.apply(this, arguments);
-					if (after){
-						after(r, arguments);
-					}
-					return r;
-				};		
-		}
-	};
-
-	var labelPreprocess = function(elem, chart, label, truncatedLabel, font, elemType){
-		// aditional preprocessing of the labels, needed for rtl base text direction in LTR 
-		// GUI, or for ltr base text direction for RTL GUI.
-
-		var isChartDirectionRtl = (html.style(chart.node,"direction") == "rtl");
-		var isBaseTextDirRtl = (chart.getTextDir(label) == "rtl");
-
-		if(isBaseTextDirRtl && !isChartDirectionRtl){
-			label = "<span dir='rtl'>" + label +"</span>";
-		}
-		if(!isBaseTextDirRtl && isChartDirectionRtl){
-			label = "<span dir='ltr'>" + label +"</span>";
-		}
-
-		return arguments;
-	};
-
-	// connect labelPreprocess to run before labelTooltip.
-	// patch it only is available
-	if(dojox.charting.axis2d && dojox.charting.axis2d.Default){
-		extendMethod(dojox.charting.axis2d.Default,"labelTooltip",true, labelPreprocess, null);
-		//extendMethod(dijit,"showTooltip",false, labelPreprocess, null);
-	}
-
-	function htmlCreateText(r, agumentsArr){
-		// function to register HTML elements that created by html.createText, this array
-		// needed for allowing to change textDir dynamically.
-		agumentsArr[0].htmlElementsRegistry.push([r, agumentsArr[2], agumentsArr[3], agumentsArr[4], agumentsArr[5], agumentsArr[6], agumentsArr[7]]);
-	}
-
-	extendMethod(da.createText,"html", false, null, htmlCreateText);
-
-	function validateTextDir(textDir){
-		return /^(ltr|rtl|auto)$/.test(textDir) ? textDir : null;
-	}
-		
+define(["dojo/_base/kernel"],
+		function(kernel){
+		kernel.deprecated('dojox.charting.BidiSupport is deprecated,', 'set "has: {\'dojo-bidi\': true }" in data-dojo-config to enable bidi support');
 });
diff --git a/dojox/charting/BidiSupport3D.js b/dojox/charting/BidiSupport3D.js
new file mode 100644
index 0000000..84a8e5a
--- /dev/null
+++ b/dojox/charting/BidiSupport3D.js
@@ -0,0 +1,4 @@
+define(["dojo/_base/kernel"],
+		function(kernel){
+		kernel.deprecated('dojox.charting.BidiSupport3D is deprecated,', 'set "has: {\'dojo-bidi\': true }" in data-dojo-config to enable bidi support');
+});
diff --git a/dojox/charting/Chart.js b/dojox/charting/Chart.js
index afe0c4b..de4e89b 100644
--- a/dojox/charting/Chart.js
+++ b/dojox/charting/Chart.js
@@ -1,31 +1,49 @@
-define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/html", 
-	"dojo/dom", "dojo/dom-geometry", "dojo/dom-construct","dojo/_base/Color", "dojo/_base/sniff",
-	"./Element", "./Theme", "./Series", "./axis2d/common",
-	"dojox/gfx", "dojox/lang/functional", "dojox/lang/functional/fold", "dojox/lang/functional/reversed"], 
-	function(lang, arr, declare, html, 
+define(["../main", "dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/dom-style",
+	"dojo/dom", "dojo/dom-geometry", "dojo/dom-construct","dojo/_base/Color", "dojo/sniff",
+	"./Element", "./SimpleTheme", "./Series", "./axis2d/common", "dojox/gfx/shape",
+	"dojox/gfx", "dojo/has!dojo-bidi?./bidi/Chart", "dojox/lang/functional", "dojox/lang/functional/fold", "dojox/lang/functional/reversed"],
+	function(dojox, lang, arr, declare, domStyle,
 	 		 dom, domGeom, domConstruct, Color, has,
-	 		 Element, Theme, Series, common, 
-	 		 g, func, funcFold, funcReversed){
+	 		 Element, SimpleTheme, Series, common, shape,
+	 		 g, BidiChart, func){
 	/*=====
-	dojox.charting.__ChartCtorArgs = function(margins, stroke, fill, delayInMs){
-		//	summary:
+	var __ChartCtorArgs = {
+		// summary:
 		//		The keyword arguments that can be passed in a Chart constructor.
-		//
-		//	margins: Object?
+		// margins: Object?
 		//		Optional margins for the chart, in the form of { l, t, r, b}.
-		//	stroke: dojox.gfx.Stroke?
+		// stroke: dojox.gfx.Stroke?
 		//		An optional outline/stroke for the chart.
-		//	fill: dojox.gfx.Fill?
+		// fill: dojox.gfx.Fill?
 		//		An optional fill for the chart.
-		//	delayInMs: Number
+		// delayInMs: Number
 		//		Delay in ms for delayedRender(). Default: 200.
-		this.margins = margins;
-		this.stroke = stroke;
-		this.fill = fill;
-		this.delayInMs = delayInMs;
-	}
-	 =====*/
-	var dc = dojox.charting,
+	};
+	=====*/
+
+	/*=====
+	var __SeriesCtorArgs = {
+		// summary:
+		//		An optional arguments object that can be used in the Series constructor.
+		// plot: String?
+		//		The plot (by name) that this series belongs to.
+	};
+	=====*/
+
+	/*=====
+	var __BaseAxisCtorArgs = {
+		// summary:
+		//		Optional arguments used in the definition of an invisible axis.
+		// vertical: Boolean?
+		//		A flag that says whether an axis is vertical (i.e. y axis) or horizontal. Default is false (horizontal).
+		// min: Number?
+		//		The smallest value on an axis. Default is 0.
+		// max: Number?
+		//		The largest value on an axis. Default is 1.
+	};
+	=====*/
+
+	var dc = lang.getObject("charting", true, dojox),
 		clear = func.lambda("item.clear()"),
 		purge = func.lambda("item.purgeGroup()"),
 		destroy = func.lambda("item.destroy()"),
@@ -33,12 +51,12 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 		makeDirty = func.lambda("item.dirty = true"),
 		getName = func.lambda("item.name");
 
-	declare("dojox.charting.Chart", null, {
-		//	summary:
+	var Chart = declare(has("dojo-bidi")? "dojox.charting.NonBidiChart" : "dojox.charting.Chart", null, {
+		// summary:
 		//		The main chart object in dojox.charting.  This will create a two dimensional
 		//		chart based on dojox.gfx.
 		//
-		//	description:
+		// description:
 		//		dojox.charting.Chart is the primary object used for any kind of charts.  It
 		//		is simple to create--just pass it a node reference, which is used as the
 		//		container for the chart--and a set of optional keyword arguments and go.
@@ -47,90 +65,97 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 		//		designed to return a reference to the chart itself, to allow for functional
 		//		chaining.  This makes defining everything on a Chart very easy to do.
 		//
-		//	example:
+		// example:
 		//		Create an area chart, with smoothing.
-		//	|	new dojox.charting.Chart(node))
-		//	|		.addPlot("default", { type: "Areas", tension: "X" })
-		//	|		.setTheme(dojox.charting.themes.Shrooms)
-		//	|		.addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4])
-		//	|		.addSeries("Series B", [2.6, 1.8, 2, 1, 1.4, 0.7, 2])
-		//	|		.addSeries("Series C", [6.3, 1.8, 3, 0.5, 4.4, 2.7, 2])
-		//	|		.render();
+		//	|	require(["dojox/charting/Chart", "dojox/charting/themes/Shrooms", "dojox/charting/plot2d/Areas", ...],
+		// 	|		function(Chart, Shrooms, Areas, ...){
+		//	|		new Chart(node)
+		//	|			.addPlot("default", { type: Areas, tension: "X" })
+		//	|			.setTheme(Shrooms)
+		//	|			.addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4])
+		//	|			.addSeries("Series B", [2.6, 1.8, 2, 1, 1.4, 0.7, 2])
+		//	|			.addSeries("Series C", [6.3, 1.8, 3, 0.5, 4.4, 2.7, 2])
+		//	|			.render();
+		//	|	});
 		//
-		//	example:
+		// example:
 		//		The form of data in a data series can take a number of forms: a simple array,
 		//		an array of objects {x,y}, or something custom (as determined by the plot).
 		//		Here's an example of a Candlestick chart, which expects an object of
 		//		{ open, high, low, close }.
-		//	|	new dojox.charting.Chart(node))
-		//	|		.addPlot("default", {type: "Candlesticks", gap: 1})
-		//	|		.addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true})
-		//	|		.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true})
-		//	|		.addSeries("Series A", [
-		//	|				{ open: 20, close: 16, high: 22, low: 8 },
-		//	|				{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
-		//	|				{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
-		//	|				{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
-		//	|				{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
-		//	|				{ open: 24, close: 8, high: 24, low: 5 },
-		//	|				{ open: 8, close: 16, high: 22, low: 2 },
-		//	|				{ open: 16, close: 12, high: 19, low: 7 },
-		//	|				{ open: 12, close: 20, high: 22, low: 8 },
-		//	|				{ open: 20, close: 16, high: 22, low: 8 },
-		//	|				{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
-		//	|				{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
-		//	|				{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
-		//	|				{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
-		//	|				{ open: 24, close: 8, high: 24, low: 5 },
-		//	|				{ open: 8, close: 16, high: 22, low: 2 },
-		//	|				{ open: 16, close: 12, high: 19, low: 7 },
-		//	|				{ open: 12, close: 20, high: 22, low: 8 },
-		//	|				{ open: 20, close: 16, high: 22, low: 8 },
-		//	|				{ open: 16, close: 22, high: 26, low: 6 },
-		//	|				{ open: 22, close: 18, high: 22, low: 11 },
-		//	|				{ open: 18, close: 29, high: 32, low: 14 },
-		//	|				{ open: 29, close: 24, high: 29, low: 13 },
-		//	|				{ open: 24, close: 8, high: 24, low: 5 },
-		//	|				{ open: 8, close: 16, high: 22, low: 2 },
-		//	|				{ open: 16, close: 12, high: 19, low: 7 },
-		//	|				{ open: 12, close: 20, high: 22, low: 8 },
-		//	|				{ open: 20, close: 16, high: 22, low: 8 }
-		//	|			],
-		//	|			{ stroke: { color: "green" }, fill: "lightgreen" }
-		//	|		)
-		//	|		.render();
+		//	|	require(["dojox/charting/Chart", "dojox/charting/plot2d/Candlesticks", ...],
+		// 	|		function(Chart, Candlesticks, ...){
+		//	|		new Chart(node)
+		//	|			.addPlot("default", {type: Candlesticks, gap: 1})
+		//	|			.addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true})
+		//	|			.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true})
+		//	|			.addSeries("Series A", [
+		//	|					{ open: 20, close: 16, high: 22, low: 8 },
+		//	|					{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
+		//	|					{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
+		//	|					{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
+		//	|					{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
+		//	|					{ open: 24, close: 8, high: 24, low: 5 },
+		//	|					{ open: 8, close: 16, high: 22, low: 2 },
+		//	|					{ open: 16, close: 12, high: 19, low: 7 },
+		//	|					{ open: 12, close: 20, high: 22, low: 8 },
+		//	|					{ open: 20, close: 16, high: 22, low: 8 },
+		//	|					{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
+		//	|					{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
+		//	|					{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
+		//	|					{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
+		//	|					{ open: 24, close: 8, high: 24, low: 5 },
+		//	|					{ open: 8, close: 16, high: 22, low: 2 },
+		//	|					{ open: 16, close: 12, high: 19, low: 7 },
+		//	|					{ open: 12, close: 20, high: 22, low: 8 },
+		//	|					{ open: 20, close: 16, high: 22, low: 8 },
+		//	|					{ open: 16, close: 22, high: 26, low: 6 },
+		//	|					{ open: 22, close: 18, high: 22, low: 11 },
+		//	|					{ open: 18, close: 29, high: 32, low: 14 },
+		//	|					{ open: 29, close: 24, high: 29, low: 13 },
+		//	|					{ open: 24, close: 8, high: 24, low: 5 },
+		//	|					{ open: 8, close: 16, high: 22, low: 2 },
+		//	|					{ open: 16, close: 12, high: 19, low: 7 },
+		//	|					{ open: 12, close: 20, high: 22, low: 8 },
+		//	|					{ open: 20, close: 16, high: 22, low: 8 }
+		//	|				],
+		//	|				{ stroke: { color: "green" }, fill: "lightgreen" }
+		//	|			)
+		//	|			.render();
+		//	|	});
 		
-		//	theme: dojox.charting.Theme?
+		// theme: dojox/charting/SimpleTheme?
 		//		An optional theme to use for styling the chart.
-		//	axes: dojox.charting.Axis{}?
+		// axes: dojox/charting/axis2d/Base{}?
 		//		A map of axes for use in plotting a chart.
-		//	stack: dojox.charting.plot2d.Base[]
+		// stack: dojox/charting/plot2d/Base[]
 		//		A stack of plotters.
-		//	plots: dojox.charting.plot2d.Base{}
+		// plots: dojox/charting/plot2d/Base{}
 		//		A map of plotter indices
-		//	series: dojox.charting.Series[]
+		// series: dojox/charting/Series[]
 		//		The stack of data runs used to create plots.
-		//	runs: dojox.charting.Series{}
+		// runs: dojox/charting/Series{}
 		//		A map of series indices
-		//	margins: Object?
+		// margins: Object?
 		//		The margins around the chart. Default is { l:10, t:10, r:10, b:10 }.
-		//	stroke: dojox.gfx.Stroke?
+		// stroke: dojox.gfx.Stroke?
 		//		The outline of the chart (stroke in vector graphics terms).
-		//	fill: dojox.gfx.Fill?
+		// fill: dojox.gfx.Fill?
 		//		The color for the chart.
-		//	node: DOMNode
+		// node: DOMNode
 		//		The container node passed to the constructor.
-		//	surface: dojox.gfx.Surface
+		// surface: dojox/gfx/shape.Surface
 		//		The main graphics surface upon which a chart is drawn.
-		//	dirty: Boolean
+		// dirty: Boolean
 		//		A boolean flag indicating whether or not the chart needs to be updated/re-rendered.
-		//	coords: Object
-		//		The coordinates on a page of the containing node, as returned from dojo.coords.
+		// htmlLabels: Boolean
+		//		A boolean flag indicating whether or not it should try to use HTML-based labels for the title or not.
+		//		The default is true.  The only caveat is IE and Opera browsers will always use GFX-based labels.
 
-		constructor: function(/* DOMNode */node, /* dojox.charting.__ChartCtorArgs? */kwArgs){
-			//	summary:
+		constructor: function(/* DOMNode */node, /* __ChartCtorArgs? */kwArgs){
+			// summary:
 			//		The constructor for a new Chart.  Initializes all parameters used for a chart.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		The newly created chart.
 
 			// initialize parameters
@@ -145,6 +170,10 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 			this.titleFont = kwArgs.titleFont;
 			this.titleFontColor = kwArgs.titleFontColor;
 			this.chartTitle = null;
+			this.htmlLabels = true;
+			if("htmlLabels" in kwArgs){
+				this.htmlLabels = kwArgs.htmlLabels;
+			}
 
 			// default initialization
 			this.theme = null;
@@ -154,53 +183,61 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 			this.series = [];	// stack of data runs
 			this.runs = {};		// map of data run indices
 			this.dirty = true;
-			this.coords = null;
 
 			// create a surface
 			this.node = dom.byId(node);
 			var box = domGeom.getMarginBox(node);
 			this.surface = g.createSurface(this.node, box.w || 400, box.h || 300);
+			if(this.surface.declaredClass.indexOf("vml") == -1){
+				// except if vml use native clipping
+				this._nativeClip = true;
+			}
 		},
 		destroy: function(){
-			//	summary:
+			// summary:
 			//		Cleanup when a chart is to be destroyed.
-			//	returns: void
+			// returns: void
 			arr.forEach(this.series, destroy);
 			arr.forEach(this.stack,  destroy);
 			func.forIn(this.axes, destroy);
+			this.surface.destroy();
 			if(this.chartTitle && this.chartTitle.tagName){
 				// destroy title if it is a DOM node
 				domConstruct.destroy(this.chartTitle);
 			}
-			this.surface.destroy();
 		},
 		getCoords: function(){
-			//	summary:
+			// summary:
 			//		Get the coordinates and dimensions of the containing DOMNode, as
 			//		returned by dojo.coords.
-			//	returns: Object
+			// returns: Object
 			//		The resulting coordinates of the chart.  See dojo.coords for details.
-			return html.coords(this.node, true); // Object
+			var node = this.node;
+			var s = domStyle.getComputedStyle(node), coords = domGeom.getMarginBox(node, s);
+			var abs = domGeom.position(node, true);
+			coords.x = abs.x;
+			coords.y = abs.y;
+			return coords;	//	Object
 		},
 		setTheme: function(theme){
-			//	summary:
+			// summary:
 			//		Set a theme of the chart.
-			//	theme: dojox.charting.Theme
+			// theme: dojox/charting/SimpleTheme
 			//		The theme to be used for visual rendering.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			this.theme = theme.clone();
 			this.dirty = true;
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		addAxis: function(name, kwArgs){
-			//	summary:
+			// summary:
 			//		Add an axis to the chart, for rendering.
-			//	name: String
+			// name: String
 			//		The name of the axis.
-			//	kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
+			// kwArgs: __BaseAxisCtorArgs?
 			//		An optional keyword arguments object for use in defining details of an axis.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			var axis, axisType = kwArgs && kwArgs.type || "Default";
 			if(typeof axisType == "string"){
@@ -218,23 +255,23 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 			}
 			this.axes[name] = axis;
 			this.dirty = true;
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		getAxis: function(name){
-			//	summary:
+			// summary:
 			//		Get the given axis, by name.
-			//	name: String
+			// name: String
 			//		The name the axis was defined by.
-			//	returns: dojox.charting.axis2d.Default
+			// returns: dojox/charting/axis2d/Default
 			//		The axis as stored in the chart's axis map.
-			return this.axes[name];	//	dojox.charting.axis2d.Default
+			return this.axes[name];	//	dojox/charting/axis2d/Default
 		},
 		removeAxis: function(name){
-			//	summary:
+			// summary:
 			//		Remove the axis that was defined using name.
-			//	name: String
+			// name: String
 			//		The axis name, as defined in addAxis.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			if(name in this.axes){
 				// destroy the axis
@@ -243,19 +280,19 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 				// mark the chart as dirty
 				this.dirty = true;
 			}
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		addPlot: function(name, kwArgs){
-			//	summary:
+			// summary:
 			//		Add a new plot to the chart, defined by name and using the optional keyword arguments object.
 			//		Note that dojox.charting assumes the main plot to be called "default"; if you do not have
 			//		a plot called "default" and attempt to add data series to the chart without specifying the
 			//		plot to be rendered on, you WILL get errors.
-			//	name: String
+			// name: String
 			//		The name of the plot to be added to the chart.  If you only plan on using one plot, call it "default".
-			//	kwArgs: dojox.charting.plot2d.__PlotCtorArgs
+			// kwArgs: dojox.charting.plot2d.__PlotCtorArgs
 			//		An object with optional parameters for the plot in question.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			var plot, plotType = kwArgs && kwArgs.type || "Default";
 			if(typeof plotType == "string"){
@@ -276,23 +313,23 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 				this.stack.push(plot);
 			}
 			this.dirty = true;
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		getPlot: function(name){
-			//	summary:
+			// summary:
 			//		Get the given plot, by name.
-			//	name: String
+			// name: String
 			//		The name the plot was defined by.
-			//	returns: dojox.charting.plot2d.Base
+			// returns: dojox/charting/plot2d/Base
 			//		The plot.
 			return this.stack[this.plots[name]];
 		},
 		removePlot: function(name){
-			//	summary:
+			// summary:
 			//		Remove the plot defined using name from the chart's plot stack.
-			//	name: String
+			// name: String
 			//		The name of the plot as defined using addPlot.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			if(name in this.plots){
 				// get the index and remove the name
@@ -327,22 +364,22 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 				// mark the chart as dirty
 				this.dirty = true;
 			}
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		getPlotOrder: function(){
-			//	summary:
+			// summary:
 			//		Returns an array of plot names in the current order
 			//		(the top-most plot is the first).
-			//	returns: Array
+			// returns: Array
 			return func.map(this.stack, getName); // Array
 		},
 		setPlotOrder: function(newOrder){
-			//	summary:
+			// summary:
 			//		Sets new order of plots. newOrder cannot add or remove
 			//		plots. Wrong names, or dups are ignored.
-			//	newOrder: Array:
+			// newOrder: Array
 			//		Array of plot names compatible with getPlotOrder().
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			var names = {},
 				order = func.filter(newOrder, function(name){
@@ -368,14 +405,14 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 			}, this);
 			this.stack = newStack;
 			this.dirty = true;
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		movePlotToFront: function(name){
-			//	summary:
+			// summary:
 			//		Moves a given plot to front.
-			//	name: String:
+			// name: String
 			//		Plot's name to move.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			if(name in this.plots){
 				var index = this.plots[name];
@@ -383,17 +420,17 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 					var newOrder = this.getPlotOrder();
 					newOrder.splice(index, 1);
 					newOrder.unshift(name);
-					return this.setPlotOrder(newOrder);	//	dojox.charting.Chart
+					return this.setPlotOrder(newOrder);	//	dojox/charting/Chart
 				}
 			}
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		movePlotToBack: function(name){
-			//	summary:
+			// summary:
 			//		Moves a given plot to back.
-			//	name: String:
+			// name: String
 			//		Plot's name to move.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			if(name in this.plots){
 				var index = this.plots[name];
@@ -401,25 +438,25 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 					var newOrder = this.getPlotOrder();
 					newOrder.splice(index, 1);
 					newOrder.push(name);
-					return this.setPlotOrder(newOrder);	//	dojox.charting.Chart
+					return this.setPlotOrder(newOrder);	//	dojox/charting/Chart
 				}
 			}
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		addSeries: function(name, data, kwArgs){
-			//	summary:
+			// summary:
 			//		Add a data series to the chart for rendering.
-			//	name: String:
+			// name: String
 			//		The name of the data series to be plotted.
-			//	data: Array|Object:
+			// data: Array|Object
 			//		The array of data points (either numbers or objects) that
 			//		represents the data to be drawn. Or it can be an object. In
 			//		the latter case, it should have a property "data" (an array),
 			//		destroy(), and setSeriesObject().
-			//	kwArgs: dojox.charting.__SeriesCtorArgs?:
+			// kwArgs: __SeriesCtorArgs?
 			//		An optional keyword arguments object that will be mixed into
 			//		the resultant series object.
-			//	returns: dojox.charting.Chart:
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			var run = new Series(this, data, kwArgs);
 			run.name = name;
@@ -434,23 +471,23 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 			// fix min/max
 			if(!("ymin" in run) && "min" in run){ run.ymin = run.min; }
 			if(!("ymax" in run) && "max" in run){ run.ymax = run.max; }
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		getSeries: function(name){
-			//	summary:
+			// summary:
 			//		Get the given series, by name.
-			//	name: String
+			// name: String
 			//		The name the series was defined by.
-			//	returns: dojox.charting.Series
+			// returns: dojox/charting/Series
 			//		The series.
 			return this.series[this.runs[name]];
 		},
 		removeSeries: function(name){
-			//	summary:
+			// summary:
 			//		Remove the series defined by name from the chart.
-			//	name: String
+			// name: String
 			//		The name of the series as defined by addSeries.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			if(name in this.runs){
 				// get the index and remove the name
@@ -468,47 +505,55 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 				});
 				this.dirty = true;
 			}
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
-		updateSeries: function(name, data){
-			//	summary:
+		updateSeries: function(name, data, offsets){
+			// summary:
 			//		Update the given series with a new set of data points.
-			//	name: String
+			// name: String
 			//		The name of the series as defined in addSeries.
-			//	data: Array|Object:
+			// data: Array|Object
 			//		The array of data points (either numbers or objects) that
 			//		represents the data to be drawn. Or it can be an object. In
 			//		the latter case, it should have a property "data" (an array),
 			//		destroy(), and setSeriesObject().
-			//	returns: dojox.charting.Chart
+			// offsets: Boolean?
+			//		If true recomputes the offsets of the chart based on the new
+			//		data. This is useful if the range of data is drastically changing
+			//		and offsets need to be recomputed.
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			if(name in this.runs){
 				var run = this.series[this.runs[name]];
 				run.update(data);
-				this._invalidateDependentPlots(run.plot, false);
-				this._invalidateDependentPlots(run.plot, true);
+				if(offsets){
+					this.dirty = true;
+				}else{
+					this._invalidateDependentPlots(run.plot, false);
+					this._invalidateDependentPlots(run.plot, true);
+				}
 			}
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		getSeriesOrder: function(plotName){
-			//	summary:
+			// summary:
 			//		Returns an array of series names in the current order
 			//		(the top-most series is the first) within a plot.
-			//	plotName: String:
+			// plotName: String
 			//		Plot's name.
-			//	returns: Array
+			// returns: Array
 			return func.map(func.filter(this.series, function(run){
 					return run.plot == plotName;
 				}), getName);
 		},
 		setSeriesOrder: function(newOrder){
-			//	summary:
+			// summary:
 			//		Sets new order of series within a plot. newOrder cannot add
 			//		or remove series. Wrong names, or dups are ignored.
-			//	newOrder: Array:
+			// newOrder: Array
 			//		Array of series names compatible with getPlotOrder(). All
 			//		series should belong to the same plot.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			var plotName, names = {},
 				order = func.filter(newOrder, function(name){
@@ -542,14 +587,14 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 				this.runs[run.name] = i;
 			}, this);
 			this.dirty = true;
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		moveSeriesToFront: function(name){
-			//	summary:
+			// summary:
 			//		Moves a given series to front of a plot.
-			//	name: String:
+			// name: String
 			//		Series' name to move.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			if(name in this.runs){
 				var index = this.runs[name],
@@ -557,17 +602,17 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 				if(name != newOrder[0]){
 					newOrder.splice(index, 1);
 					newOrder.unshift(name);
-					return this.setSeriesOrder(newOrder);	//	dojox.charting.Chart
+					return this.setSeriesOrder(newOrder);	//	dojox/charting/Chart
 				}
 			}
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		moveSeriesToBack: function(name){
-			//	summary:
+			// summary:
 			//		Moves a given series to back of a plot.
-			//	name: String:
+			// name: String
 			//		Series' name to move.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			if(name in this.runs){
 				var index = this.runs[name],
@@ -575,54 +620,52 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 				if(name != newOrder[newOrder.length - 1]){
 					newOrder.splice(index, 1);
 					newOrder.push(name);
-					return this.setSeriesOrder(newOrder);	//	dojox.charting.Chart
+					return this.setSeriesOrder(newOrder);	//	dojox/charting/Chart
 				}
 			}
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		resize: function(width, height){
-			//	summary:
+			// summary:
 			//		Resize the chart to the dimensions of width and height.
-			//	description:
+			// description:
 			//		Resize the chart and its surface to the width and height dimensions.
-			//		If no width/height or box is provided, resize the surface to the marginBox of the chart.
-			//	width: Number
-			//		The new width of the chart.
-			//	height: Number
+			//		If a single argument of the form {w: value1, h: value2} is provided take that argument as the dimensions to use.
+			//		Finally if no argument is provided, resize the surface to the marginBox of the chart.
+			// width: Number|Object?
+			//		The new width of the chart or the box definition.
+			// height: Number?
 			//		The new height of the chart.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
-			var box;
 			switch(arguments.length){
 				// case 0, do not resize the div, just the surface
 				case 1:
 					// argument, override node box
-					box = lang.mixin({}, width);
-					domGeom.setMarginBox(this.node, box);
+					domGeom.setMarginBox(this.node, width);
 					break;
 				case 2:
-					box = {w: width, h: height};
 					// argument, override node box
-					domGeom.setMarginBox(this.node, box);
+					domGeom.setMarginBox(this.node, {w: width, h: height});
 					break;
 			}
 			// in all cases take back the computed box
-			box = domGeom.getMarginBox(this.node);
+			var box = domGeom.getMarginBox(this.node);
 			var d = this.surface.getDimensions();
 			if(d.width != box.w || d.height != box.h){
 				// and set it on the surface
 				this.surface.setDimensions(box.w, box.h);
 				this.dirty = true;
-				return this.render();	//	dojox.charting.Chart
+				return this.render();	//	dojox/charting/Chart
 			}else{
 				return this;
 			}
 		},
 		getGeometry: function(){
-			//	summary:
+			// summary:
 			//		Returns a map of information about all axes in a chart and what they represent
 			//		in terms of scaling (see dojox.charting.axis2d.Default.getScaler).
-			//	returns: Object
+			// returns: Object
 			//		An map of geometry objects, a one-to-one mapping of axes.
 			var ret = {};
 			func.forIn(this.axes, function(axis){
@@ -638,18 +681,18 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 			return ret;	//	Object
 		},
 		setAxisWindow: function(name, scale, offset, zoom){
-			//	summary:
+			// summary:
 			//		Zooms an axis and all dependent plots. Can be used to zoom in 1D.
-			//	name: String
+			// name: String
 			//		The name of the axis as defined by addAxis.
-			//	scale: Number
+			// scale: Number
 			//		The scale on the target axis.
-			//	offset: Number
+			// offset: Number
 			//		Any offest, as measured by axis tick
-			//	zoom: Boolean|Object?
+			// zoom: Boolean|Object?
 			//		The chart zooming animation trigger.  This is null by default,
 			//		e.g. {duration: 1200}, or just set true.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			var axis = this.axes[name];
 			if(axis){
@@ -660,23 +703,23 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 					}
 				});
 			}
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		setWindow: function(sx, sy, dx, dy, zoom){
-			//	summary:
+			// summary:
 			//		Zooms in or out any plots in two dimensions.
-			//	sx: Number
+			// sx: Number
 			//		The scale for the x axis.
-			//	sy: Number
+			// sy: Number
 			//		The scale for the y axis.
-			//	dx: Number
+			// dx: Number
 			//		The pixel offset on the x axis.
-			//	dy: Number
+			// dy: Number
 			//		The pixel offset on the y axis.
-			//	zoom: Boolean|Object?
+			// zoom: Boolean|Object?
 			//		The chart zooming animation trigger.  This is null by default,
 			//		e.g. {duration: 1200}, or just set true.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			if(!("plotArea" in this)){
 				this.calculateGeometry();
@@ -694,15 +737,15 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 				axis.setWindow(scale, offset);
 			});
 			arr.forEach(this.stack, function(plot){ plot.zoom = zoom; });
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
-		zoomIn:	function(name, range){
-			//	summary:
+		zoomIn:	function(name, range, delayed){
+			// summary:
 			//		Zoom the chart to a specific range on one axis.  This calls render()
 			//		directly as a convenience method.
-			//	name: String
+			// name: String
 			//		The name of the axis as defined by addAxis.
-			//	range: Array
+			// range: Array
 			//		The end points of the zoom range, measured in axis ticks.
 			var axis = this.axes[name];
 			if(axis){
@@ -714,14 +757,18 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 				scale = (bounds.upper - bounds.lower) / (upper - lower);
 				offset = lower - bounds.lower;
 				this.setAxisWindow(name, scale, offset);
-				this.render();
+				if(delayed){
+					this.delayedRender();
+				}else{
+					this.render();
+				}
 			}
 		},
 		calculateGeometry: function(){
-			//	summary:
+			// summary:
 			//		Calculate the geometry of the chart based on the defined axes of
 			//		a chart.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			if(this.dirty){
 				return this.fullGeometry();
@@ -735,14 +782,14 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 				}, this);
 			calculateAxes(dirty, this.plotArea);
 
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		fullGeometry: function(){
-			//	summary:
+			// summary:
 			//		Calculate the full geometry of the chart.  This includes passing
 			//		over all major elements of a chart (plots, axes, series, container)
 			//		in order to ensure proper rendering.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			this._makeDirty();
 
@@ -753,12 +800,13 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 
 			// set up a theme
 			if(!this.theme){
-				this.setTheme(new Theme(dojox.charting._def));
+				this.setTheme(new SimpleTheme());
 			}
 
 			// assign series
 			arr.forEach(this.series, function(run){
 				if(!(run.plot in this.plots)){
+					// TODO remove auto-assignment
 					if(!dc.plot2d || !dc.plot2d.Default){
 						throw Error("Can't find plot: Default - didn't you forget to dojo" + ".require() it?");
 					}
@@ -771,11 +819,8 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 			}, this);
 			// assign axes
 			arr.forEach(this.stack, function(plot){
-				if(plot.hAxis){
-					plot.setAxis(this.axes[plot.hAxis]);
-				}
-				if(plot.vAxis){
-					plot.setAxis(this.axes[plot.vAxis]);
+				if(plot.assignAxes){
+					plot.assignAxes(this.axes);
 				}
 			}, this);
 
@@ -789,10 +834,16 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 			calculateAxes(this.stack, dim);
 
 			// assumption: we don't have stacked axes yet
-			var offsets = this.offsets = { l: 0, r: 0, t: 0, b: 0 };
+			var offsets = this.offsets = {l: 0, r: 0, t: 0, b: 0};
+			// chart mirroring starts
+			var self = this;
 			func.forIn(this.axes, function(axis){
-				func.forIn(axis.getOffsets(), function(o, i){ offsets[i] += o; });
+				if(has("dojo-bidi")){
+					self._resetLeftBottom(axis);
+				}
+				func.forIn(axis.getOffsets(), function(o, i){ offsets[i] = Math.max(o, offsets[i]); });
 			});
+			// chart mirroring ends
 			// add title area
 			if(this.title){
 				this.titleGap = (this.titleGap==0) ? 0 : this.titleGap || this.theme.chart.titleGap || 20;
@@ -800,7 +851,7 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 				this.titleFont = this.titleFont || this.theme.chart.titleFont;
 				this.titleFontColor = this.titleFontColor || this.theme.chart.titleFontColor || "black";
 				var tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
-				offsets[this.titlePos=="top" ? "t":"b"] += (tsize + this.titleGap);
+				offsets[this.titlePos == "top" ? "t" : "b"] += (tsize + this.titleGap);
 			}
 			// add margins
 			func.forIn(this.margins, function(o, i){ offsets[i] += o; });
@@ -813,15 +864,22 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 			func.forIn(this.axes, clear);
 			calculateAxes(this.stack, this.plotArea);
 
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		render: function(){
-			//	summary:
+			// summary:
 			//		Render the chart according to the current information defined.  This should
 			//		be the last call made when defining/creating a chart, or if data within the
 			//		chart has been changed.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
+
+			// do we have a delayed renderer pending? If yes we need to clear it
+			if(this._delayedRenderHandle){
+				clearTimeout(this._delayedRenderHandle);
+				this._delayedRenderHandle = null;
+			}
+			
 			if(this.theme){
 				this.theme.clear();
 			}
@@ -840,22 +898,20 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 
 			this._makeClean();
 
-			// BEGIN FOR HTML CANVAS
-			if(this.surface.render){ this.surface.render(); };
-			// END FOR HTML CANVAS
-
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		fullRender: function(){
-			//	summary:
+			// summary:
 			//		Force a full rendering of the chart, including full resets on the chart itself.
 			//		You should not call this method directly unless absolutely necessary.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 
 			// calculate geometry
 			this.fullGeometry();
-			var offsets = this.offsets, dim = this.dim, rect;
+			var offsets = this.offsets, dim = this.dim;
+			var w = Math.max(0, dim.width  - offsets.l - offsets.r),
+				h = Math.max(0, dim.height - offsets.t - offsets.b);
 
 			// get required colors
 			//var requiredColors = func.foldl(this.stack, "z + plot.getRequiredColors()", 0);
@@ -865,102 +921,40 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 			arr.forEach(this.series, purge);
 			func.forIn(this.axes, purge);
 			arr.forEach(this.stack,  purge);
+			var children = this.surface.children;
+			// starting with 1.9 the registry is optional and thus dispose is
+			if(shape.dispose){
+				for(var i = 0; i < children.length;++i){
+					shape.dispose(children[i]);
+				}
+			}
 			if(this.chartTitle && this.chartTitle.tagName){
 				// destroy title if it is a DOM node
 			    domConstruct.destroy(this.chartTitle);
-            }
+			}
 			this.surface.clear();
 			this.chartTitle = null;
 
-			// generate shapes
-
-			// draw a plot background
-			var t = this.theme,
-				fill   = t.plotarea && t.plotarea.fill,
-				stroke = t.plotarea && t.plotarea.stroke,
-				// size might be neg if offsets are bigger that chart size this happens quite often at 
-				// initialization time if the chart widget is used in a BorderContainer
-				// this will fail on IE/VML
-				w = Math.max(0, dim.width  - offsets.l - offsets.r),
-				h = Math.max(0, dim.height - offsets.t - offsets.b),
-				rect = {
-					x: offsets.l - 1, y: offsets.t - 1,
-					width:  w + 2,
-					height: h + 2
-				};
-			if(fill){
-				fill = Element.prototype._shapeFill(Element.prototype._plotFill(fill, dim, offsets), rect);
-				this.surface.createRect(rect).setFill(fill);
-			}
-			if(stroke){
-				this.surface.createRect({
-					x: offsets.l, y: offsets.t,
-					width:  w + 1,
-					height: h + 1
-				}).setStroke(stroke);
+			this._renderChartBackground(dim, offsets);
+			if(this._nativeClip){
+				this._renderPlotBackground(dim, offsets, w, h);
+			}else{
+				// VML
+				this._renderPlotBackground(dim, offsets, w, h);
 			}
 
 			// go over the stack backwards
 			func.foldr(this.stack, function(z, plot){ return plot.render(dim, offsets), 0; }, 0);
 
-			// pseudo-clipping: matting
-			fill   = this.fill   !== undefined ? this.fill   : (t.chart && t.chart.fill);
-			stroke = this.stroke !== undefined ? this.stroke : (t.chart && t.chart.stroke);
-
-			//	TRT: support for "inherit" as a named value in a theme.
-			if(fill == "inherit"){
-				//	find the background color of the nearest ancestor node, and use that explicitly.
-				var node = this.node, fill = new Color(html.style(node, "backgroundColor"));
-				while(fill.a==0 && node!=document.documentElement){
-					fill = new Color(html.style(node, "backgroundColor"));
-					node = node.parentNode;
-				}
-			}
-
-			if(fill){
-				fill = Element.prototype._plotFill(fill, dim, offsets);
-				if(offsets.l){	// left
-					rect = {
-						width:  offsets.l,
-						height: dim.height + 1
-					};
-					this.surface.createRect(rect).setFill(Element.prototype._shapeFill(fill, rect));
-				}
-				if(offsets.r){	// right
-					rect = {
-						x: dim.width - offsets.r,
-						width:  offsets.r + 1,
-						height: dim.height + 2
-					};
-					this.surface.createRect(rect).setFill(Element.prototype._shapeFill(fill, rect));
-				}
-				if(offsets.t){	// top
-					rect = {
-						width:  dim.width + 1,
-						height: offsets.t
-					};
-					this.surface.createRect(rect).setFill(Element.prototype._shapeFill(fill, rect));
-				}
-				if(offsets.b){	// bottom
-					rect = {
-						y: dim.height - offsets.b,
-						width:  dim.width + 1,
-						height: offsets.b + 2
-					};
-					this.surface.createRect(rect).setFill(Element.prototype._shapeFill(fill, rect));
-				}
-			}
-			if(stroke){
-				this.surface.createRect({
-					width:  dim.width - 1,
-					height: dim.height - 1
-				}).setStroke(stroke);
+			if(!this._nativeClip){
+				// VML, matting-clipping
+				this._renderChartBackground(dim, offsets);
 			}
 
 			//create title: Whether to make chart title as a widget which extends dojox.charting.Element?
 			if(this.title){
-				var forceHtmlLabels = (g.renderer == "canvas"),
-					labelType = forceHtmlLabels || !has("ie") && !has("opera") ? "html" : "gfx",
+				var forceHtmlLabels = (g.renderer == "canvas") && this.htmlLabels,
+					labelType = forceHtmlLabels || !has("ie") && !has("opera") && this.htmlLabels ? "html" : "gfx",
 					tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
 				this.chartTitle = common.createText[labelType](
 					this,
@@ -979,55 +973,145 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 
 			this._makeClean();
 
-			// BEGIN FOR HTML CANVAS
-			if(this.surface.render){ this.surface.render(); };
-			// END FOR HTML CANVAS
+			return this;	//	dojox/charting/Chart
+		},
+		_renderChartBackground: function(dim, offsets){
+			var t = this.theme, rect;
+			// chart background
+			var fill   = this.fill   !== undefined ? this.fill   : (t.chart && t.chart.fill);
+			var stroke = this.stroke !== undefined ? this.stroke : (t.chart && t.chart.stroke);
 
-			return this;	//	dojox.charting.Chart
+			// TRT: support for "inherit" as a named value in a theme.
+			if(fill == "inherit"){
+				//	find the background color of the nearest ancestor node, and use that explicitly.
+				var node = this.node;
+				fill = new Color(domStyle.get(node, "backgroundColor"));
+				while(fill.a==0 && node!=document.documentElement){
+					fill = new Color(domStyle.get(node, "backgroundColor"));
+					node = node.parentNode;
+				}
+			}
+
+			if(fill){
+				if(this._nativeClip){
+					fill = Element.prototype._shapeFill(Element.prototype._plotFill(fill, dim),
+						{ x:0, y: 0, width: dim.width + 1, height: dim.height + 1 });
+					this.surface.createRect({ width: dim.width + 1, height: dim.height + 1 }).setFill(fill);
+				}else{
+					// VML
+					fill = Element.prototype._plotFill(fill, dim, offsets);
+					if(offsets.l){	// left
+						rect = {
+							x: 0,
+							y: 0,
+							width:  offsets.l,
+							height: dim.height + 1
+						};
+						this.surface.createRect(rect).setFill(Element.prototype._shapeFill(fill, rect));
+					}
+					if(offsets.r){	// right
+						rect = {
+							x: dim.width - offsets.r,
+							y: 0,
+							width:  offsets.r + 1,
+							height: dim.height + 2
+						};
+						this.surface.createRect(rect).setFill(Element.prototype._shapeFill(fill, rect));
+					}
+					if(offsets.t){	// top
+						rect = {
+							x: 0,
+							y: 0,
+							width:  dim.width + 1,
+							height: offsets.t
+						};
+						this.surface.createRect(rect).setFill(Element.prototype._shapeFill(fill, rect));
+					}
+					if(offsets.b){	// bottom
+						rect = {
+							x: 0,
+							y: dim.height - offsets.b,
+							width:  dim.width + 1,
+							height: offsets.b + 2
+						};
+						this.surface.createRect(rect).setFill(Element.prototype._shapeFill(fill, rect));
+					}
+				}
+			}
+			if(stroke){
+				this.surface.createRect({
+					width:  dim.width - 1,
+					height: dim.height - 1
+				}).setStroke(stroke);
+			}
+		},
+		_renderPlotBackground: function(dim, offsets, w, h){
+			var t = this.theme;
+
+			// draw a plot background
+			var fill   = t.plotarea && t.plotarea.fill;
+			var stroke = t.plotarea && t.plotarea.stroke;
+			// size might be neg if offsets are bigger that chart size this happens quite often at
+			// initialization time if the chart widget is used in a BorderContainer
+			// this will fail on IE/VML
+			var rect = {
+				x: offsets.l - 1, y: offsets.t - 1,
+				width:  w + 2,
+				height: h + 2
+			};
+			if(fill){
+				fill = Element.prototype._shapeFill(Element.prototype._plotFill(fill, dim, offsets), rect);
+				this.surface.createRect(rect).setFill(fill);
+			}
+			if(stroke){
+				this.surface.createRect({
+					x: offsets.l, y: offsets.t,
+					width:  w + 1,
+					height: h + 1
+				}).setStroke(stroke);
+			}
 		},
 		delayedRender: function(){
-			//	summary:
+			// summary:
 			//		Delayed render, which is used to collect multiple updates
 			//		within a delayInMs time window.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 
 			if(!this._delayedRenderHandle){
 				this._delayedRenderHandle = setTimeout(
 					lang.hitch(this, function(){
-						clearTimeout(this._delayedRenderHandle);
-						this._delayedRenderHandle = null;
 						this.render();
 					}),
 					this.delayInMs
 				);
 			}
 
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		connectToPlot: function(name, object, method){
-			//	summary:
+			// summary:
 			//		A convenience method to connect a function to a plot.
-			//	name: String
+			// name: String
 			//		The name of the plot as defined by addPlot.
-			//	object: Object
+			// object: Object
 			//		The object to be connected.
-			//	method: Function
+			// method: Function
 			//		The function to be executed.
-			//	returns: Array
+			// returns: Array
 			//		A handle to the connection, as defined by dojo.connect (see dojo.connect).
 			return name in this.plots ? this.stack[this.plots[name]].connect(object, method) : null;	//	Array
 		},
 		fireEvent: function(seriesName, eventName, index){
-			//	summary:
+			// summary:
 			//		Fires a synthetic event for a series item.
-			//	seriesName: String:
+			// seriesName: String
 			//		Series name.
-			//	eventName: String:
+			// eventName: String
 			//		Event name to simulate: onmouseover, onmouseout, onclick.
-			//	index: Number:
+			// index: Number
 			//		Valid data value index for the event.
-			//	returns: dojox.charting.Chart
+			// returns: dojox/charting/Chart
 			//		A reference to the current chart for functional chaining.
 			if(seriesName in this.runs){
 				var plotName = this.series[this.runs[seriesName]].plot;
@@ -1038,7 +1122,7 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 					}
 				}
 			}
-			return this;	//	dojox.charting.Chart
+			return this;	//	dojox/charting/Chart
 		},
 		_makeClean: function(){
 			// reset dirty flags
@@ -1073,6 +1157,13 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 					plot.dirty = true;
 				}
 			}
+		},
+		setDir : function(dir){
+			return this; 
+		},
+		_resetLeftBottom: function(axis){
+		},
+		formatTruncatedLabel: function(element, label, labelType){			
 		}
 	});
 
@@ -1125,5 +1216,5 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare", "dojo/_base/
 		});
 	}
 	
-	return dojox.charting.Chart;
+	return has("dojo-bidi")? declare("dojox.charting.Chart", [Chart, BidiChart]) : Chart;
 });
diff --git a/dojox/charting/Chart2D.js b/dojox/charting/Chart2D.js
index f425daf..f8ad9ab 100644
--- a/dojox/charting/Chart2D.js
+++ b/dojox/charting/Chart2D.js
@@ -1,16 +1,16 @@
-define(["dojo/_base/kernel", "dojox", "./Chart", 
+define(["dojo/_base/kernel", "dojo/_base/lang", "..", "./Chart",
 	"./axis2d/Default", "./axis2d/Invisible", "./plot2d/Default", "./plot2d/Lines", "./plot2d/Areas",
 	"./plot2d/Markers", "./plot2d/MarkersOnly", "./plot2d/Scatter", "./plot2d/Stacked", "./plot2d/StackedLines",
 	"./plot2d/StackedAreas", "./plot2d/Columns", "./plot2d/StackedColumns", "./plot2d/ClusteredColumns",
 	"./plot2d/Bars", "./plot2d/StackedBars", "./plot2d/ClusteredBars", "./plot2d/Grid", "./plot2d/Pie",
 	"./plot2d/Bubble", "./plot2d/Candlesticks", "./plot2d/OHLC", "./plot2d/Spider"], 
-	  function(dojo, dojox, Chart){
-	dojo.deprecated("dojox.charting.Chart2D", "Use dojo.charting.Chart instead and require all other components explicitly", "2.0");
+	  function(kernel, lang, dojox, Chart){
+	kernel.deprecated("dojox.charting.Chart2D", "Use dojox.charting.Chart instead and require all other components explicitly", "2.0");
 	// module:
 	//		dojox/charting/Chart2D
 	// summary:
 	//		This is a compatibility module which loads all charting modules that used to be automatically
 	//		loaded in versions prior to 1.6.  It is highly recommended for performance reasons that
 	//		this module no longer be referenced by applications.  Instead, use dojox/charting/Chart.
-	return dojox.charting.Chart2D = Chart;
+	return lang.setObject("dojox.charting.Chart2D", Chart);
 });
diff --git a/dojox/charting/Chart3D.js b/dojox/charting/Chart3D.js
index 8bdac03..27f5ccc 100644
--- a/dojox/charting/Chart3D.js
+++ b/dojox/charting/Chart3D.js
@@ -1,28 +1,29 @@
-define(["dojo/_base/array", "dojo/dom","dojo/_base/declare", "dojo/_base/html", "dojox/gfx", "dojox/gfx3d"], 
-	function(arr, dom, declare, html, gfx, gfx3d){
+define(["dojo/_base/array", "dojo/dom","dojo/_base/declare", "dojox/gfx", "dojox/gfx3d",
+        "dojo/has", "dojo/has!dojo-bidi?./bidi/Chart3D"],
+	function(arr, dom, declare, gfx, gfx3d, has, BidiChart3D){
 	// module:
 	//		dojox/charting/Chart3D
 	// summary:
 	//		This module provides basic 3d charting capablities (using 2d vector graphics to simulate 3d.
 
 	/*=====
-	dojox.charting.__Chart3DCtorArgs = function(node, lights, camera, theme){
-		//	summary:
+	var __Chart3DCtorArgs = function(node, lights, camera, theme){
+		// summary:
 		//		The keyword arguments that can be passed in a Chart constructor.
 		//
-		//	node: Node
+		// node: Node
 		//		The DOM node to construct the chart on.
-		//	lights: 
+		// lights:
 		//		Lighting properties for the 3d scene
-		//	camera: Object
+		// camera: Object
 		//		Camera properties describing the viewing camera position.
-		//	theme: Object
+		// theme: Object
 		//		Charting theme to use for coloring chart elements.
-	}
-	 =====*/
+	};
+	=====*/
 	var observerVector = {x: 0, y: 0, z: 1}, v = gfx3d.vector, n = gfx.normalizedLength;
 
-	return declare("dojox.charting.Chart3D", null, {
+	var Chart3D = declare(has("dojo-bidi")? "dojox.charting.NonBidiChart3D" : "dojox.charting.Chart3D", null, {
 		constructor: function(node, lights, camera, theme){
 			// setup a view
 			this.node = dom.byId(node);
@@ -94,6 +95,10 @@ define(["dojo/_base/array", "dojo/dom","dojo/_base/declare", "dojo/_base/html",
 				depth -= this.plots[i].getDepth();
 			}
 			return this;
+		},
+		setDir: function(/*String*/dir){
+			return this;
 		}
 	});
+	return has("dojo-bidi")? declare("dojox.charting.Chart3D", [Chart3D, BidiChart3D]) : Chart3D;
 });
diff --git a/dojox/charting/DataChart.js b/dojox/charting/DataChart.js
index 80de51e..8904724 100644
--- a/dojox/charting/DataChart.js
+++ b/dojox/charting/DataChart.js
@@ -38,17 +38,13 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		tension:2,
 		gap:2
 	};
-	/*=====
-	var Chart = dojox.charting.Chart;
-	=====*/
+
 	return declare("dojox.charting.DataChart", Chart, {
-		//	summary:
-		//		DataChart
+		// summary:
 		//		Extension to the 2D chart that connects to a data store in
 		//		a simple manner. Convenience methods have been added for
 		//		connecting store item labels to the chart labels.
-		//
-		//	description:
+		// description:
 		//		This code should be considered very experimental and the APIs subject
 		//		to change. This is currently an alpha version and will need some testing
 		//		and review.
@@ -67,9 +63,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		//		Currently, plot lines can only be set at initialization. Setting
 		//		a new store query will have no effect (although using setStore
 		//		may work but its untested).
-		//
-		//	example:
-		//
+		// example:
 		//	|	var chart = new dojox.charting.DataChart("myNode", {
 		//	|		displayRange:8,
 		//	|		store:dataStore,
@@ -77,93 +71,83 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		//	|		fieldName:"price"
 		//	|		type: dojox.charting.plot2d.Columns
 		//	|	});
-		//
-		//	properties:
-		//
-		//	scroll: Boolean
+
+		// scroll: Boolean
 		//		Whether live data updates and changes display, like columns moving
 		//		up and down, or whether it scrolls to the left as data is added
 		scroll:true,
-		//
-		//	comparative: Boolean
+
+		// comparative: Boolean
 		//		If false, all items are each their own series.
 		//		If true, the items are combined into one series
 		//		so that their charted properties can be compared.
 		comparative:false,
-		//
-		//		query: String
-		//			Used for fetching items. Will vary depending upon store.
+
+		// query: String
+		//		Used for fetching items. Will vary depending upon store.
 		query: "*",
-		//
-		//		queryOptions: String
-		//			Option used for fetching items
+
+		// queryOptions: String
+		//		Option used for fetching items
 		queryOptions: "",
-		//
+
 		/*=====
-			//	start:Number
+			// start:Number
 			//		first item to fetch from store
-			//	count:Number
+			// count:Number
 			//		Total amount of items to fetch from store
-			//	sort:Object
-			//		Paramaters to sort the fetched items from store
+			// sort:Object
+			//		Parameters to sort the fetched items from store
 		=====*/
-		//
-		//		fieldName: String
-		//			The field in the store item that is getting charted
+
+		// fieldName: String
+		//		The field in the store item that is getting charted
 		fieldName: "value",
-		//
-		//		chartTheme: dojox.charting.themes.*
-		//			The theme to style the chart. Defaults to PlotKit.blue.
+
+		// chartTheme: dojox.charting.themes.*
+		//		The theme to style the chart. Defaults to PlotKit.blue.
 		chartTheme: blue,
-		//
-		//		displayRange: Number
-		//			The number of major ticks to show on the xaxis
+
+		// displayRange: Number
+		//		The number of major ticks to show on the xaxis
 		displayRange:0,
-		//
-		// 		stretchToFit: Boolean
-		//			If true, chart is sized to data. If false, chart is a
-		//			fixed size. Note, is overridden by displayRange.
-		//			TODO: Stretch for the y-axis?
+
+		// stretchToFit: Boolean
+		//		If true, chart is sized to data. If false, chart is a
+		//		fixed size. Note, is overridden by displayRange.
+		//		TODO: Stretch for the y-axis?
 		stretchToFit:true,
-		//
-		//		minWidth: Number
-		//			The the smallest the chart width can be
+
+		// minWidth: Number
+		//		The the smallest the chart width can be
 		minWidth:200,
-		//
-		//		minHeight: Number
-		//			The the smallest the chart height can be
+
+		// minHeight: Number
+		//		The the smallest the chart height can be
 		minHeight:100,
-		//
-		//		showing: Boolean
-		//			Whether the chart is showing (default) on
-		//			initialization or hidden.
+
+		// showing: Boolean
+		//		Whether the chart is showing (default) on
+		//		initialization or hidden.
 		showing: true,
-		//
-		//		label: String
-		//			The name field of the store item
-		//			DO NOT SET: Set from store.labelAttribute
+
+		// label: String
+		//		The name field of the store item
+		//		DO NOT SET: Set from store.labelAttribute
 		label: "name",
 
 		constructor: function(node, kwArgs){
 			// summary:
 			//		Set up properties and initialize chart build.
-			//
-			//	arguments:
-			//		node: DomNode
-			//			The node to attach the chart to.
-			//		kwArgs:	Object
-			//			xaxis: Object
-			//				optional parameters for xaxis (see above)
-			//			yaxis: Object
-			//				optional parameters for yaxis (see above)
-			//			store: Object
-			//				dojo.data store (currently nly supports Persevere)
-			//			xaxis: Object
-			//				First query for store
-			//			grid: Object
-			//				Options for the grid plot
-			//			chartPlot: Object
-			//				Options for chart elements (lines, bars, etc)
+			// node: DomNode
+			//		The node to attach the chart to.
+			// kwArgs: Object
+			//		- xaxis: Object: optional parameters for xaxis (see above)
+			//		- yaxis: Object: optional parameters for yaxis (see above)
+			//		- store: Object: dojo.data store (currently nly supports Persevere)
+			//		- xaxis: Object: First query for store
+			//		- grid: Object: Options for the grid plot
+			//		- chartPlot: Object: Options for chart elements (lines, bars, etc)
 
 			this.domNode = dom.byId(node);
 
@@ -206,13 +190,18 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			if(!this.stretchToFit){
 				this.xaxis.to = this.displayRange;
 			}
-			this.addAxis("x", this.xaxis);
-			this.addAxis("y", this.yaxis);
-			chartPlot.type = kwArgs.type || "Markers"
+			// we don't want axis on Pie
+			var cartesian = kwArgs.type && kwArgs.type != "Pie" && kwArgs.type.prototype.declaredClass != "dojox.charting.plot2d.Pie";
+			if(cartesian){
+				this.addAxis("x", this.xaxis);
+				this.addAxis("y", this.yaxis);
+			}
+			chartPlot.type = kwArgs.type || "Markers";
 			this.addPlot("default", lang.mixin(chartPlot, kwArgs.chartPlot));
-
-			this.addPlot("grid", lang.mixin(kwArgs.grid || {}, {type: "Grid", hMinorLines: true}));
-
+			if(cartesian){
+				this.addPlot("grid", lang.mixin(kwArgs.grid || {}, {type: "Grid", hMinorLines: true}));
+			}
+			
 			if(this.showing){
 				this.render();
 			}
@@ -228,13 +217,13 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		},
 
 		setStore: function(/*Object*/store, /* ? String*/query, /* ? String*/fieldName, /* ? Object */queryOptions){
-			//	 summary:
+			// summary:
 			//		Sets the chart store and query
 			//		then does the first fetch and
 			//		connects to subsequent changes.
-			//
+
 			// TODO: Not handling resetting store
-			//
+
 			this.firstRun = true;
 			this.store = store || this.store;
 			this.query = query || this.query;
@@ -260,7 +249,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			}
 		},
 		hide: function(){
-			// 	summary:
+			// summary:
 			//		If chart is showing, hide it
 			//		Prevents rendering while hidden
 			if(this.showing){
@@ -270,12 +259,12 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		},
 
 		onSet: function(/*storeObject*/item){
-			//	summary:
+			// summary:
 			//		Fired when a store item changes.
 			//		Collects the item calls and when
 			//		done (after 200ms), sends item
 			//		array to onData().
-			//
+
 			// FIXME: Using labels instead of IDs for item
 			//	identifiers here and in the chart series. This
 			//	is obviously short sighted, but currently used
@@ -333,12 +322,12 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			return value;
 		},
 		onData: function(/*Array*/items){
-			//	summary:
+			// summary:
 			//		Called after a completed fetch
 			//		or when store items change.
 			//		On first run, sets the chart data,
 			//		then updates chart and legends.
-			//
+
 			//console.log("Store:", store);console.log("items: (", items.length+")", items);console.log("Chart:", this);
 			if(!items || !items.length){ return; }
 
@@ -367,14 +356,14 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 
 				this.seriesData[nm] = [];
 				this.seriesDataBk[nm] = [];
-				arr.forEach(items, function(m, i){
+				arr.forEach(items, function(m){
 					var field = this.getProperty(m, this.fieldName);
 					this.seriesData[nm].push(field);
 				}, this);
 
 			}else{
 
-				// each item is a seperate series.
+				// each item is a separate series.
 				arr.forEach(items, function(m, i){
 					var nm = this.store.getLabel(m);
 					if(!this.seriesData[nm]){
@@ -505,11 +494,11 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		},
 
 		resizeChart: function(/*Object*/dim){
-			//	summary:
+			// summary:
 			//		Call this function to change the chart size.
 			//		Can be connected to a layout widget that calls
 			//		resize.
-			//
+
 			var w = Math.max(dim.w, this.minWidth);
 			var h = Math.max(dim.h, this.minHeight);
 			this.resize(w, h);
diff --git a/dojox/charting/DataSeries.js b/dojox/charting/DataSeries.js
index 70dcb11..b17a5f3 100644
--- a/dojox/charting/DataSeries.js
+++ b/dojox/charting/DataSeries.js
@@ -1,16 +1,16 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base/connect", "dojox/lang/functional"], 
-	function(Lang, declare, ArrayUtil, Hub, df){
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base/connect", "dojox/lang/functional"],
+	function(Lang, declare, ArrayUtil, connect, df){
 
 	return declare("dojox.charting.DataSeries", null, {
 		constructor: function(store, kwArgs, value){
-			//	summary:
+			// summary:
 			//		Series adapter for dojo.data stores.
-			//	store: Object:
+			// store: Object
 			//		A dojo.data store object.
-			//	kwArgs: Object:
+			// kwArgs: Object
 			//		A store-specific keyword parameters used for fetching items.
-			//		See dojo.data.api.Read.fetch().
-			//	value: Function|Object|String|Null:
+			//		See dojo/data/api/Read.fetch().
+			// value: Function|Object|String
 			//		Function, which takes a store, and an object handle, and
 			//		produces an output possibly inspecting the store's item. Or
 			//		a dictionary object, which tells what names to extract from
@@ -39,25 +39,26 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	
 			if(this.store.getFeatures()["dojo.data.api.Notification"]){
 				this._events.push(
-					Hub.connect(this.store, "onNew", this, "_onStoreNew"),
-					Hub.connect(this.store, "onDelete", this, "_onStoreDelete"),
-					Hub.connect(this.store, "onSet", this, "_onStoreSet")
+					connect.connect(this.store, "onNew", this, "_onStoreNew"),
+					connect.connect(this.store, "onDelete", this, "_onStoreDelete"),
+					connect.connect(this.store, "onSet", this, "_onStoreSet")
 				);
 			}
-	
+
+			this._initialRendering = true;
 			this.fetch();
 		},
 	
 		destroy: function(){
-			//	summary:
+			// summary:
 			//		Clean up before GC.
-			ArrayUtil.forEach(this._events, Hub.disconnect);
+			ArrayUtil.forEach(this._events, connect.disconnect);
 		},
 	
 		setSeriesObject: function(series){
-			//	summary:
+			// summary:
 			//		Sets a dojox.charting.Series object we will be working with.
-			//	series: dojox.charting.Series:
+			// series: dojox.charting.Series
 			//		Our interface to the chart.
 			this.series = series;
 		},
@@ -83,7 +84,7 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 		// store fetch loop
 	
 		fetch: function(){
-			//	summary:
+			// summary:
 			//		Fetches data from the store and updates a chart.
 			if(!this._inFlight){
 				this._inFlight = true;
@@ -105,9 +106,9 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 		},
 	
 		onFetchError: function(errorData, request){
-			//	summary:
+			// summary:
 			//		As stub to process fetch errors. Provide so user can attach to
-			//		it with dojo.connect(). See dojo.data.api.Read fetch() for
+			//		it with dojo.connect(). See dojo/data/api/Read fetch() for
 			//		details: onError property.
 			this._inFlight = false;
 		},
@@ -124,7 +125,8 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	
 		_pushDataChanges: function(){
 			if(this.series){
-				this.series.chart.updateSeries(this.series.name, this);
+				this.series.chart.updateSeries(this.series.name, this, this._initialRendering);
+				this._initialRendering = false;
 				this.series.chart.delayedRender();
 			}
 		},
diff --git a/dojox/charting/Element.js b/dojox/charting/Element.js
index fa42b3d..55bfb6e 100644
--- a/dojox/charting/Element.js
+++ b/dojox/charting/Element.js
@@ -1,28 +1,28 @@
-define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/declare", "dojox/gfx", "dojox/gfx/utils", "dojox/gfx/shape"],
-	function(lang, arr, domConstruct, declare, gfx, utils, shape){
-	
+define(["dojo/_base/array", "dojo/dom-construct","dojo/_base/declare", "dojox/gfx", "dojox/gfx/shape"],
+	function(arr, domConstruct, declare, gfx, shape){
+
 	return declare("dojox.charting.Element", null, {
-		//	summary:
+		// summary:
 		//		A base class that is used to build other elements of a chart, such as
 		//		a series.
-		//	chart: dojox.charting.Chart
+		// chart: dojox/charting/Chart
 		//		The parent chart for this element.
-		//	group: dojox.gfx.Group
+		// group: dojox/gfx/shape.Group
 		//		The visual GFX group representing this element.
-		//	htmlElement: Array
+		// htmlElement: Array
 		//		Any DOMNodes used as a part of this element (such as HTML-based labels).
-		//	dirty: Boolean
+		// dirty: Boolean
 		//		A flag indicating whether or not this element needs to be rendered.
-	
+
 		chart: null,
 		group: null,
 		htmlElements: null,
 		dirty: true,
-	
+
 		constructor: function(chart){
-			//	summary:
+			// summary:
 			//		Creates a new charting element.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart that this element belongs to.
 			this.chart = chart;
 			this.group = null;
@@ -31,32 +31,41 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 			this.trailingSymbol = "...";
 			this._events = [];
 		},
-		createGroup: function(creator){
-			//	summary:
-			//		Convenience function to create a new dojox.gfx.Group.
-			//	creator: dojox.gfx.Surface?
-			//		An optional surface in which to create this group.
-			//	returns: dojox.charting.Element
-			//		A reference to this object for functional chaining.
-			if(!creator){ creator = this.chart.surface; }
-			if(!this.group){
-				this.group = creator.createGroup();
-			}
-			return this;	//	dojox.charting.Element
-		},
 		purgeGroup: function(){
-			//	summary:
+			// summary:
 			//		Clear any elements out of our group, and destroy the group.
-			//	returns: dojox.charting.Element
+			// returns: dojox/charting/Element
 			//		A reference to this object for functional chaining.
 			this.destroyHtmlElements();
 			if(this.group){
 				// since 1.7.x we need dispose shape otherwise there is a memoryleak
-				utils.forEach(this.group, function(child){
-					shape.dispose(child);
-				});
-				this.group.clear();
-				this.group.removeShape();
+				this.getGroup().removeShape();
+				var children = this.getGroup().children;
+				// starting with 1.9 the registry is optional and thus dispose is
+				if(shape.dispose){
+					for(var i = 0; i < children.length;++i){
+						shape.dispose(children[i], true);
+					}
+				}
+				if(this.getGroup().rawNode){
+					domConstruct.empty(this.getGroup().rawNode);
+				}
+				this.getGroup().clear();
+				// starting with 1.9 the registry is optional and thus dispose is
+				if(shape.dispose){
+					shape.dispose(this.getGroup(), true);
+				}
+				if(this.getGroup() != this.group){
+					// we do have an intermediary clipping group (see CartesianBase)
+					if(this.group.rawNode){
+						domConstruct.empty(this.group.rawNode);
+					}
+					this.group.clear();
+					// starting with 1.9 the registry is optional and thus dispose is
+					if(shape.dispose){
+						shape.dispose(this.group, true);
+					}
+				}
 				this.group = null;
 			}
 			this.dirty = true;
@@ -69,24 +78,42 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 			return this;	//	dojox.charting.Element
 		},
 		cleanGroup: function(creator){
-			//	summary:
+			// summary:
 			//		Clean any elements (HTML or GFX-based) out of our group, and create a new one.
-			//	creator: dojox.gfx.Surface?
+			// creator: dojox/gfx/shape.Surface?
 			//		An optional surface to work with.
-			//	returns: dojox.charting.Element
+			// returns: dojox/charting/Element
 			//		A reference to this object for functional chaining.
 			this.destroyHtmlElements();
 			if(!creator){ creator = this.chart.surface; }
 			if(this.group){
-				this.group.clear();
+				var bgnode;
+				var children = this.getGroup().children;
+				// starting with 1.9 the registry is optional and thus dispose is
+				if(shape.dispose){
+					for(var i = 0; i < children.length;++i){
+						shape.dispose(children[i], true);
+					}
+				}
+				if(this.getGroup().rawNode){
+					bgnode = this.getGroup().bgNode;
+					domConstruct.empty(this.getGroup().rawNode);
+				}
+				this.getGroup().clear();
+				if(bgnode){
+					this.getGroup().rawNode.appendChild(bgnode);
+				}
 			}else{
 				this.group = creator.createGroup();
 			}
 			this.dirty = true;
 			return this;	//	dojox.charting.Element
 		},
+		getGroup: function(){
+			return this.group;
+		},
 		destroyHtmlElements: function(){
-			//	summary:
+			// summary:
 			//		Destroy any DOMNodes that may have been created as a part of this element.
 			if(this.htmlElements.length){
 				arr.forEach(this.htmlElements, domConstruct.destroy);
@@ -94,7 +121,7 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 			}
 		},
 		destroy: function(){
-			//	summary:
+			// summary:
 			//		API addition to conform to the rest of the Dojo Toolkit's standard.
 			this.purgeGroup();
 		},
@@ -103,22 +130,22 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 			return gfx._base._getTextBox(s, {font: font}).w || 0;
 		},
 		getTextWithLimitLength: function(s, font, limitWidth, truncated){
-			//	summary:
+			// summary:
 			//		Get the truncated string based on the limited width in px(dichotomy algorithm)
-			//	s: String?
+			// s: String?
 			//		candidate text.
-			//	font: String?
+			// font: String?
 			//		text's font style.
-			//	limitWidth: Number?
+			// limitWidth: Number?
 			//		text limited width in px.
-			//	truncated: Boolean?
+			// truncated: Boolean?
 			//		whether the input text(s) has already been truncated.
-			//	returns: Object
-			//		{
-			//			text: processed text, maybe truncated or not
-			//			truncated: whether text has been truncated
-			//		}
-			if (!s || s.length <= 0) {
+			// returns: Object
+			// |	{
+			// |		text: processed text, maybe truncated or not,
+			// |		truncated: whether text has been truncated
+			// |	}
+			if(!s || s.length <= 0){
 				return {
 					text: "",
 					truncated: truncated || false
@@ -135,7 +162,7 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 				trucPercentage = 0.618,
 				minStr = s.substring(0,1) + this.trailingSymbol,
 				minWidth = this.getTextWidth(minStr, font);
-			if (limitWidth <= minWidth) {
+			if(limitWidth <= minWidth){
 				return {
 					text: minStr,
 					truncated: true
@@ -158,7 +185,7 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 						return {
 							text: (s.substring(0,begin) + this.trailingSymbol),
 							truncated: true
-						};
+							};
 					}
 					var index = begin + Math.round((end - begin) * trucPercentage),
 						widthIntercepted = this.getTextWidth(s.substring(0, index), font);
@@ -173,21 +200,21 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 			}
 		},
 		getTextWithLimitCharCount: function(s, font, wcLimit, truncated){
-			//	summary:
+			// summary:
 			//		Get the truncated string based on the limited character count(dichotomy algorithm)
-			//	s: String?
+			// s: String?
 			//		candidate text.
-			//	font: String?
+			// font: String?
 			//		text's font style.
-			//	wcLimit: Number?
+			// wcLimit: Number?
 			//		text limited character count.
-			//	truncated: Boolean?
+			// truncated: Boolean?
 			//		whether the input text(s) has already been truncated.
-			//	returns: Object
-			//		{
-			//			text: processed text, maybe truncated or not
-			//			truncated: whether text has been truncated
-			//		}
+			// returns: Object
+			// |	{
+			// |		text: processed text, maybe truncated or not,
+			// |		truncated: whether text has been truncated
+			// |	}
 			if (!s || s.length <= 0) {
 				return {
 					text: "",
@@ -211,7 +238,7 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 			if(!fill || !fill.type || !fill.space){
 				return fill;
 			}
-			var space = fill.space;
+			var space = fill.space, span;
 			switch(fill.type){
 				case "linear":
 					if(space === "plot" || space === "shapeX" || space === "shapeY"){
@@ -221,13 +248,13 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 						// process dimensions
 						if(space === "plot" || space === "shapeX"){
 							// process Y
-							var span = dim.height - offsets.t - offsets.b;
+							span = dim.height - offsets.t - offsets.b;
 							fill.y1 = offsets.t + span * fill.y1 / 100;
 							fill.y2 = offsets.t + span * fill.y2 / 100;
 						}
 						if(space === "plot" || space === "shapeY"){
 							// process X
-							var span = dim.width - offsets.l - offsets.r;
+							span = dim.width - offsets.l - offsets.r;
 							fill.x1 = offsets.l + span * fill.x1 / 100;
 							fill.x2 = offsets.l + span * fill.x2 / 100;
 						}
@@ -255,13 +282,13 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 						// process dimensions
 						if(space === "plot" || space === "shapeX"){
 							// process Y
-							var span = dim.height - offsets.t - offsets.b;
+							span = dim.height - offsets.t - offsets.b;
 							fill.y = offsets.t + span * fill.y / 100;
 							fill.height = span * fill.height / 100;
 						}
 						if(space === "plot" || space === "shapeY"){
 							// process X
-							var span = dim.width - offsets.l - offsets.r;
+							span = dim.width - offsets.l - offsets.r;
 							fill.x = offsets.l + span * fill.x / 100;
 							fill.width = span * fill.width / 100;
 						}
@@ -275,7 +302,7 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 			if(!fill || !fill.space){
 				return fill;
 			}
-			var space = fill.space;
+			var space = fill.space, span;
 			switch(fill.type){
 				case "linear":
 					if(space === "shape" || space === "shapeX" || space === "shapeY"){
@@ -285,13 +312,13 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 						// process dimensions
 						if(space === "shape" || space === "shapeX"){
 							// process X
-							var span = bbox.width;
+							span = bbox.width;
 							fill.x1 = bbox.x + span * fill.x1 / 100;
 							fill.x2 = bbox.x + span * fill.x2 / 100;
 						}
 						if(space === "shape" || space === "shapeY"){
 							// process Y
-							var span = bbox.height;
+							span = bbox.height;
 							fill.y1 = bbox.y + span * fill.y1 / 100;
 							fill.y2 = bbox.y + span * fill.y2 / 100;
 						}
@@ -317,13 +344,13 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 						// process dimensions
 						if(space === "shape" || space === "shapeX"){
 							// process X
-							var span = bbox.width;
+							span = bbox.width;
 							fill.x = bbox.x + span * fill.x / 100;
 							fill.width = span * fill.width / 100;
 						}
 						if(space === "shape" || space === "shapeY"){
 							// process Y
-							var span = bbox.height;
+							span = bbox.height;
 							fill.y = bbox.y + span * fill.y / 100;
 							fill.height = span * fill.height / 100;
 						}
@@ -358,7 +385,6 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/dom-construct","dojo/_base/
 				y2: center.y + fill.r * radius * Math.sin(angle) / 100,
 				colors: fill.colors
 			};
-			return fill;
 		}
 	});
 });
diff --git a/dojox/charting/Series.js b/dojox/charting/Series.js
index 6ee7852..df4a625 100644
--- a/dojox/charting/Series.js
+++ b/dojox/charting/Series.js
@@ -1,30 +1,27 @@
 define(["dojo/_base/lang", "dojo/_base/declare", "./Element"], 
 	function(lang, declare, Element){ 
 	/*=====
-	dojox.charting.__SeriesCtorArgs = function(plot){
-		//	summary:
+	var __SeriesCtorArgs = {
+		// summary:
 		//		An optional arguments object that can be used in the Series constructor.
-		//	plot: String?
+		// plot: String?
 		//		The plot (by name) that this series belongs to.
-		this.plot = plot;
-	}
-
-	var Element = dojox.charting.Element;
+	};
 	=====*/
 	return declare("dojox.charting.Series", Element, {
-		//	summary:
+		// summary:
 		//		An object representing a series of data for plotting on a chart.
 		constructor: function(chart, data, kwArgs){
-			//	summary:
+			// summary:
 			//		Create a new data series object for use within charting.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart that this series belongs to.
-			//	data: Array|Object:
+			// data: Array|Object
 			//		The array of data points (either numbers or objects) that
 			//		represents the data to be drawn. Or it can be an object. In
 			//		the latter case, it should have a property "data" (an array),
 			//		destroy(), and setSeriesObject().
-			//	kwArgs: dojox.charting.__SeriesCtorArgs?
+			// kwArgs: __SeriesCtorArgs?
 			//		An optional keyword arguments object to set details for this series.
 			lang.mixin(this, kwArgs);
 			if(typeof this.plot != "string"){ this.plot = "default"; }
@@ -32,15 +29,15 @@ define(["dojo/_base/lang", "dojo/_base/declare", "./Element"],
 		},
 	
 		clear: function(){
-			//	summary:
+			// summary:
 			//		Clear the calculated additional parameters set on this series.
 			this.dyn = {};
 		},
 		
 		update: function(data){
-			//	summary:
+			// summary:
 			//		Set data and make this object dirty, so it can be redrawn.
-			//	data: Array|Object:
+			// data: Array|Object
 			//		The array of data points (either numbers or objects) that
 			//		represents the data to be drawn. Or it can be an object. In
 			//		the latter case, it should have a property "data" (an array),
@@ -58,5 +55,4 @@ define(["dojo/_base/lang", "dojo/_base/declare", "./Element"],
 			this.clear();
 		}
 	});
-
 });
diff --git a/dojox/charting/SimpleTheme.js b/dojox/charting/SimpleTheme.js
new file mode 100644
index 0000000..b2ddadf
--- /dev/null
+++ b/dojox/charting/SimpleTheme.js
@@ -0,0 +1,577 @@
+define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare","dojo/_base/Color", "dojox/lang/utils", "dojox/gfx/gradutils"],
+	function(lang, arr, declare, Color, dlu, dgg){
+	
+	var SimpleTheme = declare("dojox.charting.SimpleTheme", null, {
+	// summary:
+	//		A SimpleTheme or Theme is a pre-defined object, primarily JSON-based, that makes up the definitions to
+	//		style a chart.
+	//
+	// description:
+	//		While you can set up style definitions on a chart directly (usually through the various add methods
+	//		on a dojox.charting.Chart object), a Theme simplifies this manual setup by allowing you to
+	//		pre-define all of the various visual parameters of each element in a chart.
+	//
+	//		Most of the properties of a Theme are straight-forward; if something is line-based (such as
+	//		an axis or the ticks on an axis), they will be defined using basic stroke parameters.  Likewise,
+	//		if an element is primarily block-based (such as the background of a chart), it will be primarily
+	//		fill-based.
+	//
+	//		In addition (for convenience), a Theme definition does not have to contain the entire JSON-based
+	//		structure.  Each theme is built on top of a default theme (which serves as the basis for the theme
+	//		"GreySkies"), and is mixed into the default theme object.  This allows you to create a theme based,
+	//		say, solely on colors for data series.
+	//
+	//		Defining a new theme is relatively easy; see any of the themes in dojox.charting.themes for examples
+	//		on how to define your own.
+	//
+	//		When you set a theme on a chart, the theme itself is deep-cloned.  This means that you cannot alter
+	//		the theme itself after setting the theme value on a chart, and expect it to change your chart.  If you
+	//		are looking to make alterations to a theme for a chart, the suggestion would be to create your own
+	//		theme, based on the one you want to use, that makes those alterations before it is applied to a chart.
+	//
+	//		Finally, a Theme contains a number of functions to facilitate rendering operations on a chart--the main
+	//		helper of which is the ~next~ method, in which a chart asks for the information for the next data series
+	//		to be rendered.
+	//
+	//		A note on colors:
+	//		A theme palette is usually comprised of 5 different color definitions, and
+	//		no more.  If you have a need to render a chart with more than 5 data elements, you can simply "push"
+	//		new color definitions into the theme's .color array.  Make sure that you do that with the actual
+	//		theme object from a Chart, and not in the theme itself (i.e. either do that before using .setTheme
+	//		on a chart).
+	//
+	// example:
+	//		The default theme (and structure) looks like so:
+	//	|	// all objects are structs used directly in dojox.gfx
+	//	|	chart:{
+	//	|		stroke: null,
+	//	|		fill: "white",
+	//	|		pageStyle: null // suggested page style as an object suitable for dojo.style()
+	//	|	},
+	//	|	plotarea:{
+	//	|		stroke: null,
+	//	|		fill: "white"
+	//	|	},
+	//	|	axis:{
+	//	|		stroke:	{ // the axis itself
+	//	|			color: "#333",
+	//	|			width: 1
+	//	|		},
+	//	|		tick: {	// used as a foundation for all ticks
+	//	|			color:     "#666",
+	//	|			position:  "center",
+	//	|			font:      "normal normal normal 7pt Tahoma",	// labels on axis
+	//	|			fontColor: "#333"								// color of labels
+	//	|		},
+	//	|		majorTick:	{ // major ticks on axis, and used for major gridlines
+	//	|			width:  1,
+	//	|			length: 6
+	//	|		},
+	//	|		minorTick:	{ // minor ticks on axis, and used for minor gridlines
+	//	|			width:  0.8,
+	//	|			length: 3
+	//	|		},
+	//	|		microTick:	{ // minor ticks on axis, and used for minor gridlines
+	//	|			width:  0.5,
+	//	|			length: 1
+	//	|		},
+	//	|		title: {
+	//	|			gap:  15,
+	//	|			font: "normal normal normal 11pt Tahoma",	// title font
+	//	|			fontColor: "#333",							// title font color
+	//	|			orientation: "axis"						// "axis": facing the axis, "away": facing away
+	//	|		}
+	//	|	},
+	//	|	series: {
+	//	|		stroke:  {width: 1.5, color: "#333"},		// line
+	//	|		outline: {width: 0.1, color: "#ccc"},		// outline
+	//	|		//shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]},
+	//	|		shadow: null,								// no shadow
+	//	|		//filter:  dojox/gfx/filters.createFilter(),
+	//	|		filter: null,								// no filter, to use a filter you must use gfx SVG render and require dojox/gfx/svgext
+	//	|		fill:    "#ccc",							// fill, if appropriate
+	//	|		font:    "normal normal normal 8pt Tahoma",	// if there's a label
+	//	|		fontColor: "#000"							// color of labels
+	//	|		labelWiring: {width: 1, color: "#ccc"},		// connect marker and target data item(slice, column, bar...)
+	//	|	},
+	//	|	marker: {	// any markers on a series
+	//	|		symbol:  "m-3,3 l3,-6 3,6 z",				// symbol
+	//	|		stroke:  {width: 1.5, color: "#333"},		// stroke
+	//	|		outline: {width: 0.1, color: "#ccc"},		// outline
+	//	|		shadow: null,								// no shadow
+	//	|		fill:    "#ccc",							// fill if needed
+	//	|		font:    "normal normal normal 8pt Tahoma",	// label
+	//	|		fontColor: "#000"
+	//	|	},
+	//	|	grid: {	// grid, when not present axis tick strokes are used instead
+	//	|		majorLine: {	// major grid line
+	//	|			color:     "#666",
+	//	|			width:  1,
+	//	|			length: 6
+	//	|		},
+	//	|		minorLine: {	// minor grid line
+	//	|			color:     "#666",
+	//	|			width:  0.8,
+	//	|			length: 3
+	//	|		},
+	//	|		fill: "grey",  // every other stripe
+	//	|		alternateFill: "grey" // alternate stripe
+	//	|	},
+	//	|	indicator: {
+	//	|		lineStroke:  {width: 1.5, color: "#333"},		// line
+	//	|		lineOutline: {width: 0.1, color: "#ccc"},		// line outline
+	//	|		lineShadow: null,								// no line shadow
+	//	|		lineFill: null,									// fill between lines for dual indicators
+	//	|		stroke:  {width: 1.5, color: "#333"},			// label background stroke
+	//	|		outline: {width: 0.1, color: "#ccc"},			// label background outline
+	//	|		shadow: null,									// no label background shadow
+	//	|		fill:  "#ccc",									// label background fill
+	//	|		radius: 3,										// radius of the label background
+	//	|		font:    "normal normal normal 10pt Tahoma",	// label font
+	//	|		fontColor: "#000"								// label color
+	//	|		markerFill:    "#ccc",							// marker fill
+	//	|		markerSymbol:  "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0",	// marker symbol
+	//	|		markerStroke:  {width: 1.5, color: "#333"},		// marker stroke
+	//	|		markerOutline: {width: 0.1, color: "#ccc"},		// marker outline
+	//	|		markerShadow: null,								// no marker shadow
+	//	|	}
+	//
+	// example:
+	//		Defining a new theme is pretty simple:
+	//	|	var Grasslands = new SimpleTheme({
+	//	|		colors: [ "#70803a", "#dde574", "#788062", "#b1cc5d", "#eff2c2" ]
+	//	|	});
+	//	|
+	//	|	myChart.setTheme(Grasslands);
+
+	shapeSpaces: {shape: 1, shapeX: 1, shapeY: 1},
+
+	constructor: function(kwArgs){
+		// summary:
+		//		Initialize a theme using the keyword arguments.  Note that the arguments
+		//		look like the example (above), and may include a few more parameters.
+		kwArgs = kwArgs || {};
+
+		// populate theme with defaults updating them if needed
+		var def = SimpleTheme.defaultTheme;
+		arr.forEach(["chart", "plotarea", "axis", "grid", "series", "marker", "indicator"], function(name){
+			this[name] = lang.delegate(def[name], kwArgs[name]);
+		}, this);
+
+		// personalize theme
+		if(kwArgs.seriesThemes && kwArgs.seriesThemes.length){
+			this.colors  = null;
+			this.seriesThemes = kwArgs.seriesThemes.slice(0);
+		}else{
+			this.seriesThemes = null;
+			this.colors = (kwArgs.colors || SimpleTheme.defaultColors).slice(0);
+		}
+		this.markerThemes = null;
+		if(kwArgs.markerThemes && kwArgs.markerThemes.length){
+			this.markerThemes = kwArgs.markerThemes.slice(0);
+		}
+		this.markers = kwArgs.markers ? lang.clone(kwArgs.markers) : lang.delegate(SimpleTheme.defaultMarkers);
+
+		// set flags
+		this.noGradConv = kwArgs.noGradConv;
+		this.noRadialConv = kwArgs.noRadialConv;
+		if(kwArgs.reverseFills){
+			this.reverseFills();
+		}
+
+		//	private housekeeping
+		this._current = 0;
+		this._buildMarkerArray();
+	},
+
+	clone: function(){
+		// summary:
+		//		Clone the current theme.
+		// returns: dojox.charting.SimpleTheme
+		//		The cloned theme; any alterations made will not affect the original.
+		var theme = new this.constructor({
+			// theme components
+			chart: this.chart,
+			plotarea: this.plotarea,
+			axis: this.axis,
+			grid: this.grid,
+			series: this.series,
+			marker: this.marker,
+			// individual arrays
+			colors: this.colors,
+			markers: this.markers,
+			indicator: this.indicator,
+			seriesThemes: this.seriesThemes,
+			markerThemes: this.markerThemes,
+			// flags
+			noGradConv: this.noGradConv,
+			noRadialConv: this.noRadialConv
+		});
+		// copy custom methods
+		arr.forEach(
+			["clone", "clear", "next", "skip", "addMixin", "post", "getTick"],
+			function(name){
+				if(this.hasOwnProperty(name)){
+					theme[name] = this[name];
+				}
+			},
+			this
+		);
+		return theme;	//	dojox.charting.SimpleTheme
+	},
+
+	clear: function(){
+		// summary:
+		//		Clear and reset the internal pointer to start fresh.
+		this._current = 0;
+	},
+
+	next: function(elementType, mixin, doPost){
+		// summary:
+		//		Get the next color or series theme.
+		// elementType: String?
+		//		An optional element type (for use with series themes)
+		// mixin: Object?
+		//		An optional object to mix into the theme.
+		// doPost: Boolean?
+		//		A flag to post-process the results.
+		// returns: Object
+		//		An object of the structure { series, marker, symbol }
+		var merge = dlu.merge, series, marker;
+		if(this.colors){
+			series = lang.delegate(this.series);
+			marker = lang.delegate(this.marker);
+			var color = new Color(this.colors[this._current % this.colors.length]), old;
+			// modify the stroke
+			if(series.stroke && series.stroke.color){
+				series.stroke = lang.delegate(series.stroke);
+				old = new Color(series.stroke.color);
+				series.stroke.color = new Color(color);
+				series.stroke.color.a = old.a;
+			}else{
+				series.stroke = {color: color};
+			}
+			if(marker.stroke && marker.stroke.color){
+				marker.stroke = lang.delegate(marker.stroke);
+				old = new Color(marker.stroke.color);
+				marker.stroke.color = new Color(color);
+				marker.stroke.color.a = old.a;
+			}else{
+				marker.stroke = {color: color};
+			}
+			// modify the fill
+			if(!series.fill || series.fill.type){
+				series.fill = color;
+			}else{
+				old = new Color(series.fill);
+				series.fill = new Color(color);
+				series.fill.a = old.a;
+			}
+			if(!marker.fill || marker.fill.type){
+				marker.fill = color;
+			}else{
+				old = new Color(marker.fill);
+				marker.fill = new Color(color);
+				marker.fill.a = old.a;
+			}
+		}else{
+			series = this.seriesThemes ?
+				merge(this.series, this.seriesThemes[this._current % this.seriesThemes.length]) :
+				this.series;
+			marker = this.markerThemes ?
+				merge(this.marker, this.markerThemes[this._current % this.markerThemes.length]) :
+				series;
+		}
+
+		var symbol = marker && marker.symbol || this._markers[this._current % this._markers.length];
+
+		var theme = {series: series, marker: marker, symbol: symbol};
+		
+		// advance the counter
+		++this._current;
+
+		if(mixin){
+			theme = this.addMixin(theme, elementType, mixin);
+		}
+		if(doPost){
+			theme = this.post(theme, elementType);
+		}
+
+		return theme;	//	Object
+	},
+
+	skip: function(){
+		// summary:
+		//		Skip the next internal color.
+		++this._current;
+	},
+
+	addMixin: function(theme, elementType, mixin, doPost){
+		// summary:
+		//		Add a mixin object to the passed theme and process.
+		// theme: dojox/charting/SimpleTheme
+		//		The theme to mixin to.
+		// elementType: String
+		//		The type of element in question. Can be "line", "bar" or "circle"
+		// mixin: Object|Array
+		//		The object or objects to mix into the theme.
+		// doPost: Boolean
+		//		If true, run the new theme through the post-processor.
+		// returns: dojox/charting/SimpleTheme
+		//		The new theme.
+		if(lang.isArray(mixin)){
+			arr.forEach(mixin, function(m){
+				theme = this.addMixin(theme, elementType, m);
+			}, this);
+		}else{
+			var t = {};
+			if("color" in mixin){
+				if(elementType == "line" || elementType == "area"){
+					lang.setObject("series.stroke.color", mixin.color, t);
+					lang.setObject("marker.stroke.color", mixin.color, t);
+				}else{
+					lang.setObject("series.fill", mixin.color, t);
+				}
+			}
+			arr.forEach(["stroke", "outline", "shadow", "fill", "filter", "font", "fontColor", "labelWiring"], function(name){
+				var markerName = "marker" + name.charAt(0).toUpperCase() + name.substr(1),
+					b = markerName in mixin;
+				if(name in mixin){
+					lang.setObject("series." + name, mixin[name], t);
+					if(!b){
+						lang.setObject("marker." + name, mixin[name], t);
+					}
+				}
+				if(b){
+					lang.setObject("marker." + name, mixin[markerName], t);
+				}
+			});
+			if("marker" in mixin){
+				t.symbol = mixin.marker;
+				t.symbol = mixin.marker;
+			}
+			theme = dlu.merge(theme, t);
+		}
+		if(doPost){
+			theme = this.post(theme, elementType);
+		}
+		return theme;	//	dojox/charting/SimpleTheme
+	},
+
+	post: function(theme, elementType){
+		// summary:
+		//		Process any post-shape fills.
+		// theme: dojox/charting/SimpleTheme
+		//		The theme to post process with.
+		// elementType: String
+		//		The type of element being filled.  Can be "bar" or "circle".
+		// returns: dojox/charting/SimpleTheme
+		//		The post-processed theme.
+		var fill = theme.series.fill, t;
+		if(!this.noGradConv && this.shapeSpaces[fill.space] && fill.type == "linear"){
+			if(elementType == "bar"){
+				// transpose start and end points
+				t = {
+					x1: fill.y1,
+					y1: fill.x1,
+					x2: fill.y2,
+					y2: fill.x2
+				};
+			}else if(!this.noRadialConv && fill.space == "shape" && (elementType == "slice" || elementType == "circle")){
+				// switch to radial
+				t = {
+					type: "radial",
+					cx: 0,
+					cy: 0,
+					r:  100
+				};
+			}
+			if(t){
+				return dlu.merge(theme, {series: {fill: t}});
+			}
+		}
+		return theme;	//	dojox/charting/SimpleTheme
+	},
+
+	getTick: function(name, mixin){
+		// summary:
+		//		Calculates and merges tick parameters.
+		// name: String
+		//		Tick name, can be "major", "minor", or "micro".
+		// mixin: Object?
+		//		Optional object to mix in to the tick.
+		var tick = this.axis.tick, tickName = name + "Tick",
+			merge = dlu.merge;
+		if(tick){
+			if(this.axis[tickName]){
+				tick = merge(tick, this.axis[tickName]);
+			}
+		}else{
+			tick = this.axis[tickName];
+		}
+		if(mixin){
+			if(tick){
+				if(mixin[tickName]){
+					tick = merge(tick, mixin[tickName]);
+				}
+			}else{
+				tick = mixin[tickName];
+			}
+		}
+		return tick;	//	Object
+	},
+
+	inspectObjects: function(f){
+		arr.forEach(["chart", "plotarea", "axis", "grid", "series", "marker", "indicator"], function(name){
+			f(this[name]);
+		}, this);
+		if(this.seriesThemes){
+			arr.forEach(this.seriesThemes, f);
+		}
+		if(this.markerThemes){
+			arr.forEach(this.markerThemes, f);
+		}
+	},
+
+	reverseFills: function(){
+		this.inspectObjects(function(o){
+			if(o && o.fill){
+				o.fill = dgg.reverse(o.fill);
+			}
+		});
+	},
+
+	addMarker:function(/*String*/ name, /*String*/ segment){
+		// summary:
+		//		Add a custom marker to this theme.
+		// example:
+		//	|	myTheme.addMarker("Ellipse", foo);
+		this.markers[name] = segment;
+		this._buildMarkerArray();
+	},
+
+	setMarkers:function(/*Object*/ obj){
+		// summary:
+		//		Set all the markers of this theme at once.  obj should be a
+		//		dictionary of keys and path segments.
+		//
+		// example:
+		//	|	myTheme.setMarkers({ "CIRCLE": foo });
+		this.markers = obj;
+		this._buildMarkerArray();
+	},
+
+	_buildMarkerArray: function(){
+		this._markers = [];
+		for(var p in this.markers){
+			this._markers.push(this.markers[p]);
+		}
+	}
+});
+
+lang.mixin(SimpleTheme, {
+	defaultMarkers: {
+		CIRCLE:   "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0",
+		SQUARE:   "m-3,-3 l0,6 6,0 0,-6 z",
+		DIAMOND:  "m0,-3 l3,3 -3,3 -3,-3 z",
+		CROSS:    "m0,-3 l0,6 m-3,-3 l6,0",
+		X:        "m-3,-3 l6,6 m0,-6 l-6,6",
+		TRIANGLE: "m-3,3 l3,-6 3,6 z",
+		TRIANGLE_INVERTED: "m-3,-3 l3,6 3,-6 z"
+	},
+
+	defaultColors:[
+		// gray skies
+		"#54544c", "#858e94", "#6e767a", "#948585", "#474747"
+	],
+
+	defaultTheme: {
+		// all objects are structs used directly in dojox.gfx
+		chart:{
+			stroke: null,
+			fill: "white",
+			pageStyle: null,
+			titleGap:		20,
+			titlePos:		"top",
+			titleFont:      "normal normal bold 14pt Tahoma",	// chart title
+			titleFontColor: "#333"
+		},
+		plotarea:{
+			stroke: null,
+			fill: "white"
+		},
+		// TODO: label rotation on axis
+		axis:{
+			stroke:	{ // the axis itself
+				color: "#333",
+				width: 1
+			},
+			tick: {	// used as a foundation for all ticks
+				color:     "#666",
+				position:  "center",
+				font:      "normal normal normal 7pt Tahoma",	// labels on axis
+				fontColor: "#333",								// color of labels
+				labelGap:  4                                    // gap between a tick and its label in pixels
+			},
+			majorTick:	{ // major ticks on axis, and used for major gridlines
+				width:  1,
+				length: 6
+			},
+			minorTick:	{ // minor ticks on axis, and used for minor gridlines
+				width:  0.8,
+				length: 3
+			},
+			microTick:	{ // minor ticks on axis, and used for minor gridlines
+				width:  0.5,
+				length: 1
+			},
+			title: {
+				gap:  15,
+				font: "normal normal normal 11pt Tahoma",	// title font
+				fontColor: "#333",							// title font color
+				orientation: "axis"						// "axis": facing the axis, "away": facing away
+			}
+		},
+		series: {
+			// used as a "main" theme for series, sThemes augment it
+			stroke:  {width: 1.5, color: "#333"},		// line
+			outline: {width: 0.1, color: "#ccc"},		// outline
+			//shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]},
+			shadow: null,								// no shadow
+			fill:    "#ccc",							// fill, if appropriate
+			font:    "normal normal normal 8pt Tahoma",	// if there's a label
+			fontColor: "#000",							// color of labels
+			labelWiring: {width: 1, color: "#ccc"}		// connect marker and target data item(slice, column, bar...)
+		},
+		marker: {	// any markers on a series
+			stroke:  {width: 1.5, color: "#333"},		// stroke
+			outline: {width: 0.1, color: "#ccc"},		// outline
+			//shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]},
+			shadow: null,								// no shadow
+			fill:    "#ccc",							// fill if needed
+			font:    "normal normal normal 8pt Tahoma",	// label
+			fontColor: "#000"
+		},
+		indicator: {
+			lineStroke:  {width: 1.5, color: "#333"},		
+			lineOutline: {width: 0.1, color: "#ccc"},		
+			lineShadow: null,
+			lineFill: null,
+			stroke:  {width: 1.5, color: "#333"},		
+			outline: {width: 0.1, color: "#ccc"},		
+			shadow: null,								
+			fill : "#ccc",
+			radius: 3,
+			font:    "normal normal normal 10pt Tahoma",	
+			fontColor: "#000",							
+			markerFill:    "#ccc",							
+			markerSymbol:  "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0",			
+			markerStroke:  {width: 1.5, color: "#333"},		
+			markerOutline: {width: 0.1, color: "#ccc"},		
+			markerShadow: null								
+		}
+	}
+});
+
+return SimpleTheme;
+});
diff --git a/dojox/charting/StoreSeries.js b/dojox/charting/StoreSeries.js
index 98fd850..68342b3 100644
--- a/dojox/charting/StoreSeries.js
+++ b/dojox/charting/StoreSeries.js
@@ -3,14 +3,14 @@ define(["dojo/_base/array", "dojo/_base/declare", "dojo/_base/Deferred"],
 	
 	return declare("dojox.charting.StoreSeries", null, {
 		constructor: function(store, kwArgs, value){
-			//	summary:
+			// summary:
 			//		Series adapter for dojo object stores (dojo.store).
-			//	store: Object:
+			// store: Object
 			//		A dojo object store.
-			//	kwArgs: Object:
+			// kwArgs: Object
 			//		A store-specific keyword parameters used for querying objects.
 			//		See dojo.store docs
-			//	value: Function|Object|String|Null:
+			// value: Function|Object|String
 			//		Function, which takes an object handle, and
 			//		produces an output possibly inspecting the store's item. Or
 			//		a dictionary object, which tells what names to extract from
@@ -43,22 +43,23 @@ define(["dojo/_base/array", "dojo/_base/declare", "dojo/_base/Deferred"],
 			}
 	
 			this.data = [];
-	
+
+			this._initialRendering = false;
 			this.fetch();
 		},
 	
 		destroy: function(){
-			//	summary:
+			// summary:
 			//		Clean up before GC.
 			if(this.observeHandle){
-				this.observeHandle.dismiss();
+				this.observeHandle.remove();
 			}
 		},
 	
 		setSeriesObject: function(series){
-			//	summary:
+			// summary:
 			//		Sets a dojox.charting.Series object we will be working with.
-			//	series: dojox.charting.Series:
+			// series: dojox/charting/Series
 			//		Our interface to the chart.
 			this.series = series;
 		},
@@ -66,12 +67,11 @@ define(["dojo/_base/array", "dojo/_base/declare", "dojo/_base/Deferred"],
 		// store fetch loop
 	
 		fetch: function(){
-			//	summary:
+			// summary:
 			//		Fetches data from the store and updates a chart.
-			var objects = this.objects = [];
 			var self = this;
 			if(this.observeHandle){
-				this.observeHandle.dismiss();
+				this.observeHandle.remove();
 			}
 			var results = this.store.query(this.kwArgs.query, this.kwArgs);
 			Deferred.when(results, function(objects){
@@ -91,7 +91,8 @@ define(["dojo/_base/array", "dojo/_base/declare", "dojo/_base/Deferred"],
 	
 		_pushDataChanges: function(){
 			if(this.series){
-				this.series.chart.updateSeries(this.series.name, this);
+				this.series.chart.updateSeries(this.series.name, this, this._initialRendering);
+				this._initialRendering = false;
 				this.series.chart.delayedRender();
 			}
 		}
diff --git a/dojox/charting/Theme.js b/dojox/charting/Theme.js
index 75de4c8..e70c9f9 100644
--- a/dojox/charting/Theme.js
+++ b/dojox/charting/Theme.js
@@ -1,657 +1,120 @@
-define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/declare","dojo/_base/Color",
-	    "dojox/color/_base", "dojox/color/Palette", "dojox/lang/utils", "dojox/gfx/gradutils"], 
-	function(lang, arr, declare, Color, colorX, Palette, dlu, dgg){ 
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/Color", "./SimpleTheme",
+	    "dojox/color/_base", "dojox/color/Palette", "dojox/gfx/gradutils"],
+	function(lang, declare, Color, SimpleTheme, colorX, Palette){
 	
-	var Theme = declare("dojox.charting.Theme", null, {
-	//	summary:
+	var Theme = declare("dojox.charting.Theme", SimpleTheme, {
+	// summary:
 	//		A Theme is a pre-defined object, primarily JSON-based, that makes up the definitions to
-	//		style a chart.
-	//
-	//	description:
-	//		While you can set up style definitions on a chart directly (usually through the various add methods
-	//		on a dojox.charting.Chart object), a Theme simplifies this manual setup by allowing you to
-	//		pre-define all of the various visual parameters of each element in a chart.
-	//
-	//		Most of the properties of a Theme are straight-forward; if something is line-based (such as
-	//		an axis or the ticks on an axis), they will be defined using basic stroke parameters.  Likewise,
-	//		if an element is primarily block-based (such as the background of a chart), it will be primarily
-	//		fill-based.
-	//
-	//		In addition (for convenience), a Theme definition does not have to contain the entire JSON-based
-	//		structure.  Each theme is built on top of a default theme (which serves as the basis for the theme
-	//		"GreySkies"), and is mixed into the default theme object.  This allows you to create a theme based,
-	//		say, solely on colors for data series.
-	//
-	//		Defining a new theme is relatively easy; see any of the themes in dojox.charting.themes for examples
-	//		on how to define your own.
-	//
-	//		When you set a theme on a chart, the theme itself is deep-cloned.  This means that you cannot alter
-	//		the theme itself after setting the theme value on a chart, and expect it to change your chart.  If you
-	//		are looking to make alterations to a theme for a chart, the suggestion would be to create your own
-	//		theme, based on the one you want to use, that makes those alterations before it is applied to a chart.
-	//
-	//		Finally, a Theme contains a number of functions to facilitate rendering operations on a chart--the main
-	//		helper of which is the ~next~ method, in which a chart asks for the information for the next data series
-	//		to be rendered.
-	//
-	//		A note on colors:
-	//		The Theme constructor was on the use of dojox.color.Palette (in general) for creating a visually distinct
-	//		set of colors for usage in a chart.  A palette is usually comprised of 5 different color definitions, and
-	//		no more.  If you have a need to render a chart with more than 5 data elements, you can simply "push"
-	//		new color definitions into the theme's .color array.  Make sure that you do that with the actual
-	//		theme object from a Chart, and not in the theme itself (i.e. either do that before using .setTheme
-	//		on a chart).
-	//
-	//		example:
-	//			The default theme (and structure) looks like so:
-	//	|	// all objects are structs used directly in dojox.gfx
-	//	|	chart:{
-	//	|		stroke: null,
-	//	|		fill: "white",
-	//	|		pageStyle: null // suggested page style as an object suitable for dojo.style()
-	//	|	},
-	//	|	plotarea:{
-	//	|		stroke: null,
-	//	|		fill: "white"
-	//	|	},
-	//	|	axis:{
-	//	|		stroke:	{ // the axis itself
-	//	|			color: "#333",
-	//	|			width: 1
-	//	|		},
-	//	|		tick: {	// used as a foundation for all ticks
-	//	|			color:     "#666",
-	//	|			position:  "center",
-	//	|			font:      "normal normal normal 7pt Tahoma",	// labels on axis
-	//	|			fontColor: "#333"								// color of labels
-	//	|		},
-	//	|		majorTick:	{ // major ticks on axis, and used for major gridlines
-	//	|			width:  1,
-	//	|			length: 6
-	//	|		},
-	//	|		minorTick:	{ // minor ticks on axis, and used for minor gridlines
-	//	|			width:  0.8,
-	//	|			length: 3
-	//	|		},
-	//	|		microTick:	{ // minor ticks on axis, and used for minor gridlines
-	//	|			width:  0.5,
-	//	|			length: 1
-	//	|		}
-	//	|	},
-	//	|	series: {
-	//	|		stroke:  {width: 1.5, color: "#333"},		// line
-	//	|		outline: {width: 0.1, color: "#ccc"},		// outline
-	//	|		//shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]},
-	//	|		shadow: null,								// no shadow
-	//	|		fill:    "#ccc",							// fill, if appropriate
-	//	|		font:    "normal normal normal 8pt Tahoma",	// if there's a label
-	//	|		fontColor: "#000"							// color of labels
-	//	|		labelWiring: {width: 1, color: "#ccc"},		// connect marker and target data item(slice, column, bar...)
-	//	|	},
-	//	|	marker: {	// any markers on a series
-	//	|		symbol:  "m-3,3 l3,-6 3,6 z",				// symbol
-	//	|		stroke:  {width: 1.5, color: "#333"},		// stroke
-	//	|		outline: {width: 0.1, color: "#ccc"},		// outline
-	//	|		shadow: null,								// no shadow
-	//	|		fill:    "#ccc",							// fill if needed
-	//	|		font:    "normal normal normal 8pt Tahoma",	// label
-	//	|		fontColor: "#000"
-	//	|	},
-	//	|	indicator: {
-	//	|		lineStroke:  {width: 1.5, color: "#333"},		// line
-	//	|		lineOutline: {width: 0.1, color: "#ccc"},		// line outline
-	//	|		lineShadow: null,								// no line shadow
-	//	|		stroke:  {width: 1.5, color: "#333"},			// label background stroke
-	//	|		outline: {width: 0.1, color: "#ccc"},			// label background outline
-	//	|		shadow: null,									// no label background shadow
-	//	|		fill:  "#ccc",									// label background fill
-	//	|		radius: 3,										// radius of the label background
-	//	|		font:    "normal normal normal 10pt Tahoma",	// label font
-	//	|		fontColor: "#000"								// label color
-	//	|		markerFill:    "#ccc",							// marker fill
-	//	|		markerSymbol:  "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0",	// marker symbol
-	//	|		markerStroke:  {width: 1.5, color: "#333"},		// marker stroke
-	//	|		markerOutline: {width: 0.1, color: "#ccc"},		// marker outline
-	//	|		markerShadow: null,								// no marker shadow
-	//	|	}
-	//
-	//	example:
-	//		Defining a new theme is pretty simple:
-	//	|	dojox.charting.themes.Grasslands = new dojox.charting.Theme({
-	//	|		colors: [ "#70803a", "#dde574", "#788062", "#b1cc5d", "#eff2c2" ]
-	//	|	});
-	//	|
-	//	|	myChart.setTheme(dojox.charting.themes.Grasslands);
-
-	shapeSpaces: {shape: 1, shapeX: 1, shapeY: 1},
-
-	constructor: function(kwArgs){
-		//	summary:
-		//		Initialize a theme using the keyword arguments.  Note that the arguments
-		//		look like the example (above), and may include a few more parameters.
-		kwArgs = kwArgs || {};
-
-		// populate theme with defaults updating them if needed
-		var def = Theme.defaultTheme;
-		arr.forEach(["chart", "plotarea", "axis", "series", "marker", "indicator"], function(name){
-			this[name] = lang.delegate(def[name], kwArgs[name]);
-		}, this);
-
-		// personalize theme
-		if(kwArgs.seriesThemes && kwArgs.seriesThemes.length){
-			this.colors  = null;
-			this.seriesThemes = kwArgs.seriesThemes.slice(0);
-		}else{
-			this.seriesThemes = null;
-			this.colors = (kwArgs.colors || Theme.defaultColors).slice(0);
-		}
-		this.markerThemes = null;
-		if(kwArgs.markerThemes && kwArgs.markerThemes.length){
-			this.markerThemes = kwArgs.markerThemes.slice(0);
-		}
-		this.markers = kwArgs.markers ? lang.clone(kwArgs.markers) : lang.delegate(Theme.defaultMarkers);
-
-		// set flags
-		this.noGradConv = kwArgs.noGradConv;
-		this.noRadialConv = kwArgs.noRadialConv;
-		if(kwArgs.reverseFills){
-			this.reverseFills();
-		}
-
-		//	private housekeeping
-		this._current = 0;
-		this._buildMarkerArray();
-	},
-
-	clone: function(){
-		//	summary:
-		//		Clone the current theme.
-		//	returns: dojox.charting.Theme
-		//		The cloned theme; any alterations made will not affect the original.
-		var theme = new Theme({
-			// theme components
-			chart: this.chart,
-			plotarea: this.plotarea,
-			axis: this.axis,
-			series: this.series,
-			marker: this.marker,
-			// individual arrays
-			colors: this.colors,
-			markers: this.markers,
-			indicator: this.indicator,
-			seriesThemes: this.seriesThemes,
-			markerThemes: this.markerThemes,
-			// flags
-			noGradConv: this.noGradConv,
-			noRadialConv: this.noRadialConv
-		});
-		// copy custom methods
-		arr.forEach(
-			["clone", "clear", "next", "skip", "addMixin", "post", "getTick"],
-			function(name){
-				if(this.hasOwnProperty(name)){
-					theme[name] = this[name];
-				}
-			},
-			this
-		);
-		return theme;	//	dojox.charting.Theme
-	},
-
-	clear: function(){
-		//	summary:
-		//		Clear and reset the internal pointer to start fresh.
-		this._current = 0;
-	},
-
-	next: function(elementType, mixin, doPost){
-		//	summary:
-		//		Get the next color or series theme.
-		//	elementType: String?
-		//		An optional element type (for use with series themes)
-		//	mixin: Object?
-		//		An optional object to mix into the theme.
-		//	doPost: Boolean?
-		//		A flag to post-process the results.
-		//	returns: Object
-		//		An object of the structure { series, marker, symbol }
-		var merge = dlu.merge, series, marker;
-		if(this.colors){
-			series = lang.delegate(this.series);
-			marker = lang.delegate(this.marker);
-			var color = new Color(this.colors[this._current % this.colors.length]), old;
-			// modify the stroke
-			if(series.stroke && series.stroke.color){
-				series.stroke = lang.delegate(series.stroke);
-				old = new Color(series.stroke.color);
-				series.stroke.color = new Color(color);
-				series.stroke.color.a = old.a;
-			}else{
-				series.stroke = {color: color};
-			}
-			if(marker.stroke && marker.stroke.color){
-				marker.stroke = lang.delegate(marker.stroke);
-				old = new Color(marker.stroke.color);
-				marker.stroke.color = new Color(color);
-				marker.stroke.color.a = old.a;
-			}else{
-				marker.stroke = {color: color};
-			}
-			// modify the fill
-			if(!series.fill || series.fill.type){
-				series.fill = color;
-			}else{
-				old = new Color(series.fill);
-				series.fill = new Color(color);
-				series.fill.a = old.a;
-			}
-			if(!marker.fill || marker.fill.type){
-				marker.fill = color;
-			}else{
-				old = new Color(marker.fill);
-				marker.fill = new Color(color);
-				marker.fill.a = old.a;
-			}
-		}else{
-			series = this.seriesThemes ?
-				merge(this.series, this.seriesThemes[this._current % this.seriesThemes.length]) :
-				this.series;
-			marker = this.markerThemes ?
-				merge(this.marker, this.markerThemes[this._current % this.markerThemes.length]) :
-				series;
-		}
-
-		var symbol = marker && marker.symbol || this._markers[this._current % this._markers.length];
-
-		var theme = {series: series, marker: marker, symbol: symbol};
-		
-		// advance the counter
-		++this._current;
-
-		if(mixin){
-			theme = this.addMixin(theme, elementType, mixin);
-		}
-		if(doPost){
-			theme = this.post(theme, elementType);
-		}
-
-		return theme;	//	Object
-	},
-
-	skip: function(){
-		//	summary:
-		//		Skip the next internal color.
-		++this._current;
-	},
-
-	addMixin: function(theme, elementType, mixin, doPost){
-		//	summary:
-		//		Add a mixin object to the passed theme and process.
-		//	theme: dojox.charting.Theme
-		//		The theme to mixin to.
-		//	elementType: String
-		//		The type of element in question. Can be "line", "bar" or "circle"
-		//	mixin: Object|Array
-		//		The object or objects to mix into the theme.
-		//	doPost: Boolean
-		//		If true, run the new theme through the post-processor.
-		//	returns: dojox.charting.Theme
-		//		The new theme.
-		if(lang.isArray(mixin)){
-			arr.forEach(mixin, function(m){
-				theme = this.addMixin(theme, elementType, m);
-			}, this);
-		}else{
-			var t = {};
-			if("color" in mixin){
-				if(elementType == "line" || elementType == "area"){
-					lang.setObject("series.stroke.color", mixin.color, t);
-					lang.setObject("marker.stroke.color", mixin.color, t);
-				}else{
-					lang.setObject("series.fill", mixin.color, t);
-				}
-			}
-			arr.forEach(["stroke", "outline", "shadow", "fill", "font", "fontColor", "labelWiring"], function(name){
-				var markerName = "marker" + name.charAt(0).toUpperCase() + name.substr(1),
-					b = markerName in mixin;
-				if(name in mixin){
-					lang.setObject("series." + name, mixin[name], t);
-					if(!b){
-						lang.setObject("marker." + name, mixin[name], t);
-					}
-				}
-				if(b){
-					lang.setObject("marker." + name, mixin[markerName], t);
-				}
-			});
-			if("marker" in mixin){
-				t.symbol = mixin.marker;
-			}
-			theme = dlu.merge(theme, t);
-		}
-		if(doPost){
-			theme = this.post(theme, elementType);
-		}
-		return theme;	//	dojox.charting.Theme
-	},
-
-	post: function(theme, elementType){
-		//	summary:
-		//		Process any post-shape fills.
-		//	theme: dojox.charting.Theme
-		//		The theme to post process with.
-		//	elementType: String
-		//		The type of element being filled.  Can be "bar" or "circle".
-		//	returns: dojox.charting.Theme
-		//		The post-processed theme.
-		var fill = theme.series.fill, t;
-		if(!this.noGradConv && this.shapeSpaces[fill.space] && fill.type == "linear"){
-			if(elementType == "bar"){
-				// transpose start and end points
-				t = {
-					x1: fill.y1,
-					y1: fill.x1,
-					x2: fill.y2,
-					y2: fill.x2
-				};
-			}else if(!this.noRadialConv && fill.space == "shape" && (elementType == "slice" || elementType == "circle")){
-				// switch to radial
-				t = {
-					type: "radial",
-					cx: 0,
-					cy: 0,
-					r:  100
-				};
-			}
-			if(t){
-				return dlu.merge(theme, {series: {fill: t}});
-			}
-		}
-		return theme;	//	dojox.charting.Theme
-	},
-
-	getTick: function(name, mixin){
-		//	summary:
-		//		Calculates and merges tick parameters.
-		//	name: String
-		//		Tick name, can be "major", "minor", or "micro".
-		//	mixin: Object?
-		//		Optional object to mix in to the tick.
-		var tick = this.axis.tick, tickName = name + "Tick",
-			merge = dlu.merge;
-		if(tick){
-			if(this.axis[tickName]){
-				tick = merge(tick, this.axis[tickName]);
-			}
-		}else{
-			tick = this.axis[tickName];
-		}
-		if(mixin){
-			if(tick){
-				if(mixin[tickName]){
-					tick = merge(tick, mixin[tickName]);
+	//		style a chart. It extends SimpleTheme with additional features like color definition by
+	//		palettes and gradients definition.
+	});
+
+	/*=====
+	var __DefineColorArgs = {
+		// summary:
+		//		The arguments object that can be passed to define colors for a theme.
+		// num: Number?
+		//		The number of colors to generate.  Defaults to 5.
+		// colors: String[]|dojo/_base/Color[]?
+		//		A pre-defined set of colors; this is passed through to the Theme directly.
+		// hue: Number?
+		//		A hue to base the generated colors from (a number from 0 - 359).
+		// saturation: Number?
+		//		If a hue is passed, this is used for the saturation value (0 - 100).
+		// low: Number?
+		//		An optional value to determine the lowest value used to generate a color (HSV model)
+		// high: Number?
+		//		An optional value to determine the highest value used to generate a color (HSV model)
+		// base: String|dojo/_base/Color?
+		//		A base color to use if we are defining colors using dojox.color.Palette
+		// generator: String?
+		//		The generator function name from dojox/color/Palette.
+	};
+	=====*/
+	lang.mixin(Theme, {
+
+		defineColors: function(kwArgs){
+			// summary:
+			//		Generate a set of colors for the theme based on keyword
+			//		arguments.
+			// kwArgs: __DefineColorArgs
+			//		The arguments object used to define colors.
+			// returns: dojo/_base/Color[]
+			//		An array of colors for use in a theme.
+			//
+			// example:
+			//	|	var colors = Theme.defineColors({
+			//	|		base: "#369",
+			//	|		generator: "compound"
+			//	|	});
+			//
+			// example:
+			//	|	var colors = Theme.defineColors({
+			//	|		hue: 60,
+			//	|		saturation: 90,
+			//	|		low: 30,
+			//	|		high: 80
+			//	|	});
+			kwArgs = kwArgs || {};
+			var l, c = [], n = kwArgs.num || 5;	// the number of colors to generate
+			if(kwArgs.colors){
+				// we have an array of colors predefined, so fix for the number of series.
+				l = kwArgs.colors.length;
+				for(var i = 0; i < n; i++){
+					c.push(kwArgs.colors[i % l]);
 				}
-			}else{
-				tick = mixin[tickName];
+				return c;	//	dojo.Color[]
 			}
-		}
-		return tick;	//	Object
-	},
-
-	inspectObjects: function(f){
-		arr.forEach(["chart", "plotarea", "axis", "series", "marker", "indicator"], function(name){
-			f(this[name]);
-		}, this);
-		if(this.seriesThemes){
-			arr.forEach(this.seriesThemes, f);
-		}
-		if(this.markerThemes){
-			arr.forEach(this.markerThemes, f);
-		}
-	},
-
-	reverseFills: function(){
-		this.inspectObjects(function(o){
-			if(o && o.fill){
-				o.fill = dgg.reverse(o.fill);
+			if(kwArgs.hue){
+				// single hue, generate a set based on brightness
+				var s = kwArgs.saturation || 100,	// saturation
+					st = kwArgs.low || 30,
+					end = kwArgs.high || 90;
+				// we'd like it to be a little on the darker side.
+				l = (end + st) / 2;
+				// alternately, use "shades"
+				return Palette.generate(
+					colorX.fromHsv(kwArgs.hue, s, l), "monochromatic"
+				).colors;
 			}
-		});
-	},
-
-	addMarker:function(/*String*/ name, /*String*/ segment){
-		//	summary:
-		//		Add a custom marker to this theme.
-		//	example:
-		//	|	myTheme.addMarker("Ellipse", foo);
-		this.markers[name] = segment;
-		this._buildMarkerArray();
-	},
-
-	setMarkers:function(/*Object*/ obj){
-		//	summary:
-		//		Set all the markers of this theme at once.  obj should be a
-		//		dictionary of keys and path segments.
-		//
-		//	example:
-		//	|	myTheme.setMarkers({ "CIRCLE": foo });
-		this.markers = obj;
-		this._buildMarkerArray();
-	},
-
-	_buildMarkerArray: function(){
-		this._markers = [];
-		for(var p in this.markers){
-			this._markers.push(this.markers[p]);
-		}
-	}
-});
-
-/*=====
-dojox.charting.Theme.__DefineColorArgs = function(num, colors, hue, saturation, low, high, base, generator){
-	//	summary:
-	//		The arguments object that can be passed to define colors for a theme.
-	//	num: Number?
-	//		The number of colors to generate.  Defaults to 5.
-	//	colors: String[]|dojo.Color[]?
-	//		A pre-defined set of colors; this is passed through to the Theme directly.
-	//	hue: Number?
-	//		A hue to base the generated colors from (a number from 0 - 359).
-	//	saturation: Number?
-	//		If a hue is passed, this is used for the saturation value (0 - 100).
-	//	low: Number?
-	//		An optional value to determine the lowest value used to generate a color (HSV model)
-	//	high: Number?
-	//		An optional value to determine the highest value used to generate a color (HSV model)
-	//	base: String|dojo.Color?
-	//		A base color to use if we are defining colors using dojox.color.Palette
-	//	generator: String?
-	//		The generator function name from dojox.color.Palette.
-	this.num = num;
-	this.colors = colors;
-	this.hue = hue;
-	this.saturation = saturation;
-	this.low = low;
-	this.high = high;
-	this.base = base;
-	this.generator = generator;
-}
-=====*/
-lang.mixin(Theme, {
-	defaultMarkers: {
-		CIRCLE:   "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0",
-		SQUARE:   "m-3,-3 l0,6 6,0 0,-6 z",
-		DIAMOND:  "m0,-3 l3,3 -3,3 -3,-3 z",
-		CROSS:    "m0,-3 l0,6 m-3,-3 l6,0",
-		X:        "m-3,-3 l6,6 m0,-6 l-6,6",
-		TRIANGLE: "m-3,3 l3,-6 3,6 z",
-		TRIANGLE_INVERTED: "m-3,-3 l3,6 3,-6 z"
-	},
-
-	defaultColors:[
-		// gray skies
-		"#54544c", "#858e94", "#6e767a", "#948585", "#474747"
-	],
-
-	defaultTheme: {
-		// all objects are structs used directly in dojox.gfx
-		chart:{
-			stroke: null,
-			fill: "white",
-			pageStyle: null,
-			titleGap:		20,
-			titlePos:		"top",
-			titleFont:      "normal normal bold 14pt Tahoma",	// labels on axis
-			titleFontColor: "#333"
-		},
-		plotarea:{
-			stroke: null,
-			fill: "white"
-		},
-		// TODO: label rotation on axis
-		axis:{
-			stroke:	{ // the axis itself
-				color: "#333",
-				width: 1
-			},
-			tick: {	// used as a foundation for all ticks
-				color:     "#666",
-				position:  "center",
-				font:      "normal normal normal 7pt Tahoma",	// labels on axis
-				fontColor: "#333",								// color of labels
-				titleGap:  15,
-				titleFont: "normal normal normal 11pt Tahoma",	// labels on axis
-				titleFontColor: "#333",							// color of labels
-				titleOrientation: "axis"						// "axis": facing the axis, "away": facing away
-			},
-			majorTick:	{ // major ticks on axis, and used for major gridlines
-				width:  1,
-				length: 6
-			},
-			minorTick:	{ // minor ticks on axis, and used for minor gridlines
-				width:  0.8,
-				length: 3
-			},
-			microTick:	{ // minor ticks on axis, and used for minor gridlines
-				width:  0.5,
-				length: 1
+			if(kwArgs.generator){
+				//	pass a base color and the name of a generator
+				return colorX.Palette.generate(kwArgs.base, kwArgs.generator).colors;
 			}
+			return c;	//	dojo.Color[]
 		},
-		series: {
-			// used as a "main" theme for series, sThemes augment it
-			stroke:  {width: 1.5, color: "#333"},		// line
-			outline: {width: 0.1, color: "#ccc"},		// outline
-			//shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]},
-			shadow: null,								// no shadow
-			fill:    "#ccc",							// fill, if appropriate
-			font:    "normal normal normal 8pt Tahoma",	// if there's a label
-			fontColor: "#000",							// color of labels
-			labelWiring: {width: 1, color: "#ccc"}		// connect marker and target data item(slice, column, bar...)
+
+		generateGradient: function(fillPattern, colorFrom, colorTo){
+			var fill = lang.delegate(fillPattern);
+			fill.colors = [
+				{offset: 0, color: colorFrom},
+				{offset: 1, color: colorTo}
+			];
+			return fill;
 		},
-		marker: {	// any markers on a series
-			stroke:  {width: 1.5, color: "#333"},		// stroke
-			outline: {width: 0.1, color: "#ccc"},		// outline
-			//shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]},
-			shadow: null,								// no shadow
-			fill:    "#ccc",							// fill if needed
-			font:    "normal normal normal 8pt Tahoma",	// label
-			fontColor: "#000"
+
+		generateHslColor: function(color, luminance){
+			color = new Color(color);
+			var hsl    = color.toHsl(),
+				result = colorX.fromHsl(hsl.h, hsl.s, luminance);
+			result.a = color.a;	// add missing opacity
+			return result;
 		},
-		indicator: {
-			lineStroke:  {width: 1.5, color: "#333"},		
-			lineOutline: {width: 0.1, color: "#ccc"},		
-			lineShadow: null,
-			stroke:  {width: 1.5, color: "#333"},		
-			outline: {width: 0.1, color: "#ccc"},		
-			shadow: null,								
-			fill : "#ccc",
-			radius: 3,
-			font:    "normal normal normal 10pt Tahoma",	
-			fontColor: "#000",							
-			markerFill:    "#ccc",							
-			markerSymbol:  "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0",			
-			markerStroke:  {width: 1.5, color: "#333"},		
-			markerOutline: {width: 0.1, color: "#ccc"},		
-			markerShadow: null								
-		}
-	},
 
-	defineColors: function(kwArgs){
-		//	summary:
-		//		Generate a set of colors for the theme based on keyword
-		//		arguments.
-		//	kwArgs: dojox.charting.Theme.__DefineColorArgs
-		//		The arguments object used to define colors.
-		//	returns: dojo.Color[]
-		//		An array of colors for use in a theme.
-		//
-		//	example:
-		//	|	var colors = dojox.charting.Theme.defineColors({
-		//	|		base: "#369",
-		//	|		generator: "compound"
-		//	|	});
-		//
-		//	example:
-		//	|	var colors = dojox.charting.Theme.defineColors({
-		//	|		hue: 60,
-		//	|		saturation: 90,
-		//	|		low: 30,
-		//	|		high: 80
-		//	|	});
-		kwArgs = kwArgs || {};
-		var l, c = [], n = kwArgs.num || 5;	// the number of colors to generate
-		if(kwArgs.colors){
-			// we have an array of colors predefined, so fix for the number of series.
-			l = kwArgs.colors.length;
-			for(var i = 0; i < n; i++){
-				c.push(kwArgs.colors[i % l]);
-			}
-			return c;	//	dojo.Color[]
-		}
-		if(kwArgs.hue){
-			// single hue, generate a set based on brightness
-			var s = kwArgs.saturation || 100,	// saturation
-				st = kwArgs.low || 30,
-				end = kwArgs.high || 90;
-			// we'd like it to be a little on the darker side.
-			l = (end + st) / 2;
-			// alternately, use "shades"
-			return colorX.Palette.generate(
-				colorX.fromHsv(kwArgs.hue, s, l), "monochromatic"
-			).colors;
+		generateHslGradient: function(color, fillPattern, lumFrom, lumTo){
+			color = new Color(color);
+			var hsl       = color.toHsl(),
+				colorFrom = colorX.fromHsl(hsl.h, hsl.s, lumFrom),
+				colorTo   = colorX.fromHsl(hsl.h, hsl.s, lumTo);
+			colorFrom.a = colorTo.a = color.a;	// add missing opacity
+			return Theme.generateGradient(fillPattern, colorFrom, colorTo);	// Object
 		}
-		if(kwArgs.generator){
-			//	pass a base color and the name of a generator
-			return colorX.Palette.generate(kwArgs.base, kwArgs.generator).colors;
-		}
-		return c;	//	dojo.Color[]
-	},
-	
-	generateGradient: function(fillPattern, colorFrom, colorTo){
-		var fill = lang.delegate(fillPattern);
-		fill.colors = [
-			{offset: 0, color: colorFrom},
-			{offset: 1, color: colorTo}
-		];
-		return fill;
-	},
-	
-	generateHslColor: function(color, luminance){
-		color = new Color(color);
-		var hsl    = color.toHsl(),
-			result = colorX.fromHsl(hsl.h, hsl.s, luminance);
-		result.a = color.a;	// add missing opacity
-		return result;
-	},
+	});
 
-	generateHslGradient: function(color, fillPattern, lumFrom, lumTo){
-		color = new Color(color);
-		var hsl       = color.toHsl(),
-			colorFrom = colorX.fromHsl(hsl.h, hsl.s, lumFrom),
-			colorTo   = colorX.fromHsl(hsl.h, hsl.s, lumTo);
-		colorFrom.a = colorTo.a = color.a;	// add missing opacity
-		return Theme.generateGradient(fillPattern, colorFrom, colorTo);	// Object
-	}
-});
+	// for compatibility
+	Theme.defaultMarkers = SimpleTheme.defaultMarkers;
+	Theme.defaultColors = SimpleTheme.defaultColors;
+	Theme.defaultTheme = SimpleTheme.defaultTheme;
 
-return Theme;
+	return Theme;
 });
diff --git a/dojox/charting/action2d/Base.js b/dojox/charting/action2d/Base.js
index 36cba66..e72c504 100644
--- a/dojox/charting/action2d/Base.js
+++ b/dojox/charting/action2d/Base.js
@@ -1,33 +1,33 @@
-define(["dojo/_base/lang", "dojo/_base/declare"], 
-	function(lang, declare){
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/Evented"],
+	function(lang, declare, Evented){
 
-	return declare("dojox.charting.action2d.Base", null, {
-		//	summary:
+	return declare("dojox.charting.action2d.Base", Evented, {
+		// summary:
 		//		Base action class for plot and chart actions.
 	
 		constructor: function(chart, plot){
-			//	summary:
+			// summary:
 			//		Create a new base action.  This can either be a plot or a chart action.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action applies to.
-			//	plot: String?|dojox.charting.plot2d.Base?
+			// plot: String|dojox/charting/plot2d/Base?
 			//		Optional target plot for this action.  Default is "default".
 			this.chart = chart;
 			this.plot = plot ? (lang.isString(plot) ? this.chart.getPlot(plot) : plot) : this.chart.getPlot("default");
 		},
 	
 		connect: function(){
-			//	summary:
+			// summary:
 			//		Connect this action to the plot or the chart.
 		},
 	
 		disconnect: function(){
-			//	summary:
+			// summary:
 			//		Disconnect this action from the plot or the chart.
 		},
 		
 		destroy: function(){
-			//	summary:
+			// summary:
 			//		Do any cleanup needed when destroying parent elements.
 			this.disconnect();
 		}
diff --git a/dojox/charting/action2d/ChartAction.js b/dojox/charting/action2d/ChartAction.js
index e438daf..69328ff 100644
--- a/dojox/charting/action2d/ChartAction.js
+++ b/dojox/charting/action2d/ChartAction.js
@@ -1,23 +1,21 @@
 define(["dojo/_base/connect", "dojo/_base/declare", "./Base"], 
 	function(hub, declare, Base){
-	/*=====
-	var Base = dojox.charting.action2d.Base;
-	=====*/
+
 	return declare("dojox.charting.action2d.ChartAction", Base, {
-		//	summary:
+		// summary:
 		//		Base action class for chart actions.
 	
 		constructor: function(chart, plot){
-			//	summary:
+			// summary:
 			//		Create a new base chart action.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action applies to.
-			//	plot: String?|dojox.charting.plot2d.Base?
+			// plot: String|dojox/charting/plot2d/Base?
 			//		Optional target plot for this chart action.  Default is "default".
 		},
 	
 		connect: function(){
-			//	summary:
+			// summary:
 			//		Connect this action to the chart.
 			for(var i = 0; i < this._listeners.length; ++i){
 				this._listeners[i].handle = hub.connect(this.chart.node, this._listeners[i].eventName,
@@ -26,7 +24,7 @@ define(["dojo/_base/connect", "dojo/_base/declare", "./Base"],
 		},
 	
 		disconnect: function(){
-			//	summary:
+			// summary:
 			//		Disconnect this action from the chart.
 			for(var i = 0; i < this._listeners.length; ++i){
 				hub.disconnect(this._listeners[i].handle);
diff --git a/dojox/charting/action2d/Highlight.js b/dojox/charting/action2d/Highlight.js
index acf189e..9d77b43 100644
--- a/dojox/charting/action2d/Highlight.js
+++ b/dojox/charting/action2d/Highlight.js
@@ -1,17 +1,19 @@
-define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/Color", "dojo/_base/connect", "dojox/color/_base", 
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/Color", "dojo/_base/connect", "dojox/color/_base",
 		"./PlotAction", "dojo/fx/easing", "dojox/gfx/fx"], 
-	function(dojo, lang, declare, Color, hub, c, PlotAction, dfe, dgf){
+	function(lang, declare, Color, hub, c, PlotAction, dfe, dgf){
 
 	/*=====
-	dojo.declare("dojox.charting.action2d.__HighlightCtorArgs", dojox.charting.action2d.__PlotActionCtorArgs, {
-		//	summary:
+	var __HighlightCtorArgs = {
+		// summary:
 		//		Additional arguments for highlighting actions.
-	
-		//	highlight: String|dojo.Color|Function?
+		// duration: Number?
+		//		The amount of time in milliseconds for an animation to last.  Default is 400.
+		// easing: dojo/fx/easing/*?
+		//		An easing object (see dojo.fx.easing) for use in an animation.  The
+		//		default is dojo.fx.easing.backOut.
+		// highlight: String|dojo/_base/Color|Function?
 		//		Either a color or a function that creates a color when highlighting happens.
-		highlight: null
-	});
-	var PlotAction = dojox.charting.action2d.PlotAction;
+	};
 	=====*/
 	
 	var DEFAULT_SATURATION  = 100,	// %
@@ -37,11 +39,19 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 						DEFAULT_LUMINOSITY2 : DEFAULT_LUMINOSITY1;
 				}
 			}
-			return c.fromHsl(x);
-		};
+			var rcolor = c.fromHsl(x);
+			rcolor.a = a.a;
+			return rcolor;
+		},
+
+		spiderhl = function(color){
+			var r = hl(color);
+			r.a = 0.7;
+			return r;
+		}
 
 	return declare("dojox.charting.action2d.Highlight", PlotAction, {
-		//	summary:
+		// summary:
 		//		Creates a highlighting action on a plot, where an element on that plot
 		//		has a highlight on it.
 
@@ -56,28 +66,36 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		},
 
 		constructor: function(chart, plot, kwArgs){
-			//	summary:
+			// summary:
 			//		Create the highlighting action and connect it to the plot.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action belongs to.
-			//	plot: String?
+			// plot: String?
 			//		The plot this action is attached to.  If not passed, "default" is assumed.
-			//	kwArgs: charting.action2d.__HighlightCtorArgs?
+			// kwArgs: __HighlightCtorArgs?
 			//		Optional keyword arguments object for setting parameters.
 			var a = kwArgs && kwArgs.highlight;
-			this.colorFun = a ? (lang.isFunction(a) ? a : cc(a)) : hl;
-
+			this.colorFunc = a ? (lang.isFunction(a) ? a : cc(a)) : hl;
 			this.connect();
 		},
 
 		process: function(o){
-			//	summary:
+			// summary:
 			//		Process the action on the given object.
-			//	o: dojox.gfx.Shape
+			// o: dojox/gfx/shape.Shape
 			//		The object on which to process the highlighting action.
 			if(!o.shape || !(o.type in this.overOutEvents)){ return; }
 
-			var runName = o.run.name, index = o.index, anim, startFill, endFill;
+			// if spider let's deal only with poly
+			if(o.element == "spider_circle" || o.element == "spider_plot"){
+				return;
+			}else if(o.element == "spider_poly" && this.colorFunc == hl){
+				// hardcode alpha for compatibility reasons
+				// TODO to remove in 2.0
+				this.colorFunc = spiderhl;
+			}
+
+			var runName = o.run.name, index = o.index, anim;
 
 			if(runName in this.anim){
 				anim = this.anim[runName][index];
@@ -94,7 +112,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 				}
 				this.anim[runName][index] = anim = {
 					start: color,
-					end:   this.colorFun(color)
+					end:   this.colorFunc(color)
 				};
 			}
 
diff --git a/dojox/charting/action2d/Magnify.js b/dojox/charting/action2d/Magnify.js
index b3707a9..dd0adb7 100644
--- a/dojox/charting/action2d/Magnify.js
+++ b/dojox/charting/action2d/Magnify.js
@@ -4,21 +4,23 @@ define(["dojo/_base/connect", "dojo/_base/declare",
 	function(Hub, declare, PlotAction, m, gf, df, dfe){
 
 	/*=====
-	dojo.declare("dojox.charting.action2d.__MagnifyCtorArgs", dojox.charting.action2d.__PlotActionCtorArgs, {
-		//	summary:
-		//		Additional arguments for highlighting actions.
-	
-		//	scale: Number?
+	var __MagnifyCtorArgs = {
+		// summary:
+		//		Additional arguments for magnifying actions.
+		// duration: Number?
+		//		The amount of time in milliseconds for an animation to last.  Default is 400.
+		// easing: dojo/fx/easing/*?
+		//		An easing object (see dojo.fx.easing) for use in an animation.  The
+		//		default is dojo.fx.easing.backOut.
+		// scale: Number?
 		//		The amount to magnify the given object to.  Default is 2.
-		scale: 2
-	});
-	var PlotAction = dojox.charting.action2d.PlotAction;
+	};
 	=====*/
 	
 	var DEFAULT_SCALE = 2;
 
 	return declare("dojox.charting.action2d.Magnify", PlotAction, {
-		//	summary:
+		// summary:
 		//		Create an action that magnifies the object the action is applied to.
 
 		// the data description block for the widget parser
@@ -30,13 +32,13 @@ define(["dojo/_base/connect", "dojo/_base/declare",
 		optionalParams: {},	// no optional parameters
 
 		constructor: function(chart, plot, kwArgs){
-			//	summary:
+			// summary:
 			//		Create the magnifying action.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action belongs to.
-			//	plot: String?
+			// plot: String?
 			//		The plot to apply the action to. If not passed, "default" is assumed.
-			//	kwArgs: dojox.charting.action2d.__MagnifyCtorArgs?
+			// kwArgs: __MagnifyCtorArgs?
 			//		Optional keyword arguments for this action.
 
 			// process optional named parameters
@@ -46,13 +48,18 @@ define(["dojo/_base/connect", "dojo/_base/declare",
 		},
 
 		process: function(o){
-			//	summary:
+			// summary:
 			//		Process the action on the given object.
-			//	o: dojox.gfx.Shape
+			// o: dojox/gfx/shape.Shape
 			//		The object on which to process the magnifying action.
 			if(!o.shape || !(o.type in this.overOutEvents) ||
 				!("cx" in o) || !("cy" in o)){ return; }
 
+			// if spider deal only with circle
+			if(o.element == "spider_plot" || o.element == "spider_poly"){
+				return;
+			}
+
 			var runName = o.run.name, index = o.index, vector = [], anim, init, scale;
 
 			if(runName in this.anim){
@@ -87,7 +94,7 @@ define(["dojo/_base/connect", "dojo/_base/declare",
 			if(o.shape){
 				vector.push(gf.animateTransform(kwArgs));
 			}
-			if(o.oultine){
+			if(o.outline){
 				kwArgs.shape = o.outline;
 				vector.push(gf.animateTransform(kwArgs));
 			}
diff --git a/dojox/charting/action2d/MouseIndicator.js b/dojox/charting/action2d/MouseIndicator.js
index a982d2a..8b318cc 100644
--- a/dojox/charting/action2d/MouseIndicator.js
+++ b/dojox/charting/action2d/MouseIndicator.js
@@ -1,103 +1,79 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/window", "dojo/_base/sniff",
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/window", "dojo/sniff",
 	"./ChartAction", "./_IndicatorElement", "dojox/lang/utils", "dojo/_base/event","dojo/_base/array"],
 	function(lang, declare, hub, win, has, ChartAction, IndicatorElement, du, eventUtil, arr){ 
 
 	/*=====
-	dojo.declare("dojox.charting.action2d.__MouseIndicatorCtorArgs", null, {
-		//	summary:
+	var __MouseIndicatorCtorArgs = {
+		// summary:
 		//		Additional arguments for mouse indicator.
-		
-		//	series: String
+		// series: String
 		//		Target series name for this action.
-		series: "",
-		
-		//	autoScroll: Boolean? 
+		// autoScroll: Boolean?
 		//		Whether when moving indicator the chart is automatically scrolled. Default is true.
-		autoScroll:		true,
-	
-		//	vertical: Boolean? 
+		// lines: Boolean?
+		//		Whether the indicator lines are visible or not. Default is true.
+		// labels: Boolean?
+		//		Whether the indicator label is visible or not. Default is true.
+		// markers: Boolean?
+		//		Whether the indicator markers are visible or not. Default is true.
+		// offset: {x, y}?
+		//		A pair of (x, y) pixel coordinate to specify the offset between the end of the indicator line and the
+		//		position at which the labels are rendered. Default is no offset which means it is automatically computed.
+		// start: Boolean?
+		//		Whether the label is rendered at the start or end of the indicator. Default is false meaning end of
+		//		the line.
+		// vertical: Boolean?
 		//		Whether the indicator is vertical or not. Default is true.
-		vertical:		true,
-		
-		//	fixed: Boolean?
+		// fixed: Boolean?
 		//		Whether a fixed precision must be applied to data values for display. Default is true.
-		fixed:			true,
-
-		//	precision: Number?
-		//		The precision at which to round data values for display. Default is 1.
-		precision:		0,
-		
-		//	lineStroke: dojo.gfx.Stroke?
+		// precision: Number?
+		//		The precision at which to round data values for display. Default is 0.
+		// lineStroke: dojo/gfx/Stroke?
 		//		An optional stroke to use for indicator line.
-		lineStroke:		{},
-	
-		//	lineOutline: dojo.gfx.Stroke?
+		// lineOutline: dojo/gfx/Stroke?
 		//		An optional outline to use for indicator line.
-		lineOutline:		{},
-	
-		//	lineShadow: dojo.gfx.Stroke?
+		// lineShadow: dojo/gfx/Stroke?
 		//		An optional shadow to use for indicator line.
-		lineShadow:		{},
-		
-		//	stroke: dojo.gfx.Stroke?
+		// stroke: dojo.gfx.Stroke?
 		//		An optional stroke to use for indicator label background.
-		stroke:		{},
-	
-		//	outline: dojo.gfx.Stroke?
+		// outline: dojo.gfx.Stroke?
 		//		An optional outline to use for indicator label background.
-		outline:		{},
-	
-		//	shadow: dojo.gfx.Stroke?
+		// shadow: dojo.gfx.Stroke?
 		//		An optional shadow to use for indicator label background.
-		shadow:		{},
-	
-		//	fill: dojo.gfx.Fill?
+		// fill: dojo.gfx.Fill?
 		//		An optional fill to use for indicator label background.
-		fill:			{},
-		
-		//	fillFunc: Function?
+		// fillFunc: Function?
 		//		An optional function to use to compute label background fill. It takes precedence over
 		//		fill property when available.
-		fillFunc:		null,
-		
-		//	labelFunc: Function?
+		// labelFunc: Function?
 		//		An optional function to use to compute label text. It takes precedence over
 		//		the default text when available.
-		labelFunc:		{},
-	
-		//	font: String?
+		//	|		function labelFunc(firstDataPoint, secondDataPoint, fixed, precision) {}
+		//		`firstDataPoint` is the `{x, y}` data coordinates pointed by the mouse.
+		//		`secondDataPoint` is only useful for dual touch indicators not mouse indicators.
+		//		`fixed` is true if fixed precision must be applied.
+		//		`precision` is the requested precision to be applied.
+		// font: String?
 		//		A font definition to use for indicator label background.
-		font:		"",
-	
-		//	fontColor: String|dojo.Color?
+		// fontColor: String|dojo.Color?
 		//		The color to use for indicator label background.
-		fontColor:	"",
-	
-		//	markerStroke: dojo.gfx.Stroke?
+		// markerStroke: dojo.gfx.Stroke?
 		//		An optional stroke to use for indicator marker.
-		markerStroke:		{},
-	
-		//	markerOutline: dojo.gfx.Stroke?
+		// markerOutline: dojo.gfx.Stroke?
 		//		An optional outline to use for indicator marker.
-		markerOutline:		{},
-	
-		//	markerShadow: dojo.gfx.Stroke?
+		// markerShadow: dojo.gfx.Stroke?
 		//		An optional shadow to use for indicator marker.
-		markerShadow:		{},
-	
-		//	markerFill: dojo.gfx.Fill?
+		// markerFill: dojo.gfx.Fill?
 		//		An optional fill to use for indicator marker.
-		markerFill:			{},
-		
-		//	markerSymbol: String?
+		// markerSymbol: String?
 		//		An optional symbol string to use for indicator marker.
-		markerFill:			{}	
-	});
-	var ChartAction = dojox.charting.action2d.ChartAction;
+		// mouseOver: Boolean?
+		//		Whether the mouse indicator is enabled on mouse over or on mouse drag. Default is false.
+	};
 	=====*/
 
 	return declare("dojox.charting.action2d.MouseIndicator", ChartAction, {
-		//	summary:
+		// summary:
 		//		Create a mouse indicator action. You can drag mouse over the chart to display a data indicator.
 
 		// the data description block for the widget parser
@@ -106,12 +82,16 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 			vertical: true,
 			autoScroll: true,
 			fixed: true,
-			precision: 0
+			precision: 0,
+			lines: true,
+			labels: true,
+			markers: true
 		},
 		optionalParams: {
 			lineStroke: {},
 			outlineStroke: {},
 			shadowStroke: {},
+			lineFill: {},
 			stroke:		{},
 			outline:	{},
 			shadow:		{},
@@ -124,20 +104,24 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 			markerOutline:		{},
 			markerShadow:		{},
 			markerFill:			{},
-			markerSymbol:		""
+			markerSymbol:		"",
+			offset: {},
+			start: false,
+			mouseOver: false
 		},	
 
 		constructor: function(chart, plot, kwArgs){
-			//	summary:
+			// summary:
 			//		Create an mouse indicator action and connect it.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action applies to.
-			//	kwArgs: dojox.charting.action2d.__MouseIndicatorCtorArgs?
+			// kwArgs: __MouseIndicatorCtorArgs?
 			//		Optional arguments for the chart action.
-			this._listeners = [{eventName: "onmousedown", methodName: "onMouseDown"}];
 			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+			this._listeners = this.opt.mouseOver?[{eventName: "onmousemove", methodName: "onMouseMove"}]:
+				[{eventName: "onmousedown", methodName: "onMouseDown"}];
 			this._uName = "mouseIndicator"+this.opt.series;
 			this._handles = [];
 			this.connect();
@@ -152,16 +136,16 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 		},
 
 		connect: function(){
-			//	summary:
+			// summary:
 			//		Connect this action to the chart. This adds a indicator plot
 			//		to the chart that's why Chart.render() must be called after connect.
 			this.inherited(arguments);
 			// add plot with unique name
-			this.chart.addPlot(this._uName, {type: IndicatorElement, inter: this});
+			this.chart.addPlot(this._uName, {type: IndicatorElement, inter: this });
 		},
 
 		disconnect: function(){
-			//	summary:
+			// summary:
 			//		Disconnect this action from the chart.
 			if(this._isMouseDown){
 				this.onMouseUp();
@@ -171,8 +155,16 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 			this._disconnectHandles();
 		},
 
+		onChange: function(event){
+			// summary:
+			//		Called when the indicator value changed.
+			// event:
+			//		An event with a start property containing the {x, y} data points of the mouse indicator. It also
+			// 		contains a label property containing the displayed text.
+		},
+
 		onMouseDown: function(event){
-			//	summary:
+			// summary:
 			//		Called when mouse is down on the chart.
 			this._isMouseDown = true;
 			
@@ -191,9 +183,9 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 		},
 
 		onMouseMove: function(event){
-			//	summary:
+			// summary:
 			//		Called when the mouse is moved on the chart.
-			if(this._isMouseDown){
+			if(this._isMouseDown || this.opt.mouseOver){
 				this._onMouseSingle(event);
 			}
 		},
@@ -207,7 +199,7 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 		},
 
 		onMouseUp: function(event){
-			//	summary:
+			// summary:
 			//		Called when mouse is up on the chart.
 			var plot = this.chart.getPlot(this._uName);
 			plot.stopTrack();
diff --git a/dojox/charting/action2d/MouseZoomAndPan.js b/dojox/charting/action2d/MouseZoomAndPan.js
index 37226d1..a44ac2d 100644
--- a/dojox/charting/action2d/MouseZoomAndPan.js
+++ b/dojox/charting/action2d/MouseZoomAndPan.js
@@ -1,38 +1,30 @@
-define(["dojo/_base/html", "dojo/_base/declare", "dojo/_base/window", "dojo/_base/array", "dojo/_base/event",
-	"dojo/_base/connect", "./ChartAction", "dojo/_base/sniff", "dojo/dom-prop", "dojo/keys"], 
-	function(html, declare, win, arr, eventUtil, connect, ChartAction, has, domProp, keys){
+define(["dojo/_base/declare", "dojo/_base/window", "dojo/_base/array", "dojo/_base/event",
+	"dojo/_base/connect", "dojo/mouse", "./ChartAction", "dojo/sniff", "dojo/dom-prop", "dojo/keys",
+	"dojo/has!dojo-bidi?../bidi/action2d/ZoomAndPan"],
+	function(declare, win, arr, eventUtil, connect, mouse, ChartAction, has, domProp, keys, BidiMouseZoomAndPan){
 
 	/*=====
-	dojo.declare("dojox.charting.action2d.__MouseZoomAndPanCtorArgs", null, {
-		//	summary:
+	var __MouseZoomAndPanCtorArgs = {
+		// summary:
 		//		Additional arguments for mouse zoom and pan actions.
-	
-		//	axis: String?
+		// axis: String?
 		//		Target axis name for this action.  Default is "x".
-		axis: "x",
-		//	scaleFactor: Number?
+		// scaleFactor: Number?
 		//		The scale factor applied on mouse wheel zoom.  Default is 1.2.
-		scaleFactor: 1.2,
-		//	maxScale: Number?
+		// maxScale: Number?
 		//		The max scale factor accepted by this chart action.  Default is 100.
-		maxScale: 100,
-		//	enableScroll: Boolean?
+		// enableScroll: Boolean?
 		//		Whether mouse drag gesture should scroll the chart.  Default is true.
-		enableScroll: true,
-		//	enableDoubleClickZoom: Boolean?
+		// enableDoubleClickZoom: Boolean?
 		//		Whether a double click gesture should toggle between fit and zoom on the chart.  Default is true.
-		enableDoubleClickZoom: true,
-		//	enableKeyZoom: Boolean?
+		// enableKeyZoom: Boolean?
 		//		Whether a keyZoomModifier + + or keyZoomModifier + - key press should zoom in our out on the chart.  Default is true.
-		enableKeyZoom: true,
-		//	keyZoomModifier: String?
+		// keyZoomModifier: String?
 		//		Which keyboard modifier should used for keyboard zoom in and out. This should be one of "alt", "ctrl", "shift" or "none" for no modifier. Default is "ctrl".
-		keyZoomModifier: "ctrl"
-	});
-	var ChartAction = dojox.charting.action2d.ChartAction;
+	};
 	=====*/
 
-	var sUnit = has("mozilla") ? -3 : 120;
+	var sUnit = has("mozilla") ? 3 : 120;
 	var keyTests = {
 		none: function(event){
 			return !event.ctrlKey && !event.altKey && !event.shiftKey;
@@ -48,8 +40,8 @@ define(["dojo/_base/html", "dojo/_base/declare", "dojo/_base/window", "dojo/_bas
 		}
 	};
 
-	return declare("dojox.charting.action2d.MouseZoomAndPan", ChartAction, {
-		//	summary:
+	var MouseZoomAndPan = declare(has("dojo-bidi")? "dojox.charting.action2d.NonBidiMouseZoomAndPan" : "dojox.charting.action2d.MouseZoomAndPan", ChartAction, {
+		// summary:
 		//		Create an mouse zoom and pan action.
 		//		You can zoom in or out the data window with mouse wheel. You can scroll using mouse drag gesture. 
 		//		You can toggle between zoom and fit view using double click on the chart.
@@ -67,13 +59,13 @@ define(["dojo/_base/html", "dojo/_base/declare", "dojo/_base/window", "dojo/_bas
 		optionalParams: {}, // no optional parameters
 		
 		constructor: function(chart, plot, kwArgs){
-			//	summary:
+			// summary:
 			//		Create an mouse zoom and pan action and connect it.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action applies to.
-			//	kwArgs: dojox.charting.action2d.__MouseZoomAndPanCtorArgs?
+			// kwArgs: __MouseZoomAndPanCtorArgs?
 			//		Optional arguments for the chart action.
-			this._listeners = [{eventName: !has("mozilla") ? "onmousewheel" : "DOMMouseScroll", methodName: "onMouseWheel"}];
+			this._listeners = [{eventName: mouse.wheel, methodName: "onMouseWheel"}];
 			if(!kwArgs){ kwArgs = {}; }
 			this.axis = kwArgs.axis ? kwArgs.axis : "x";
 			this.scaleFactor = kwArgs.scaleFactor ? kwArgs.scaleFactor : 1.2;
@@ -104,7 +96,7 @@ define(["dojo/_base/html", "dojo/_base/declare", "dojo/_base/window", "dojo/_bas
 		},
 		
 		connect: function(){
-			//	summary:
+			// summary:
 			//		Connect this action to the chart.
 			this.inherited(arguments);
 			if(this.enableKeyZoom){
@@ -116,7 +108,7 @@ define(["dojo/_base/html", "dojo/_base/declare", "dojo/_base/window", "dojo/_bas
 		},
 		
 		disconnect: function(){
-			//	summary:
+			// summary:
 			//		Disconnect this action from the chart.
 			this.inherited(arguments);
 			if(this.enableKeyZoom){
@@ -128,7 +120,7 @@ define(["dojo/_base/html", "dojo/_base/declare", "dojo/_base/window", "dojo/_bas
 		},
 	
 		onMouseDown: function(event){
-			//	summary:
+			// summary:
 			//		Called when mouse is down on the chart.
 			var chart = this.chart, axis = chart.getAxis(this.axis);
 			if(!axis.vertical){
@@ -154,33 +146,32 @@ define(["dojo/_base/html", "dojo/_base/declare", "dojo/_base/window", "dojo/_bas
 		},
 	
 		onMouseMove: function(event){
-			//	summary:
+			// summary:
 			//		Called when mouse is moved on the chart.
 			if(this._isPanning){
 				var chart = this.chart, axis = chart.getAxis(this.axis);
-				var delta = axis.vertical?(this._startCoord- event.pageY):(event.pageX - this._startCoord);
+				var delta = this._getDelta(event);
 				
 				var bounds = axis.getScaler().bounds,
 					s = bounds.span / (bounds.upper - bounds.lower);
 		
 				var scale = axis.getWindowScale();
-		
 				chart.setAxisWindow(this.axis, scale, this._startOffset - delta / s / scale);
 				chart.render();
 			}
 		},
 	
 		onMouseUp: function(event){
-			//	summary:
+			// summary:
 			//		Called when mouse is up on the chart.
 			this._isPanning = false;
 			this._disconnectHandles();
 		},
 		
 		onMouseWheel: function(event){
-			//	summary:
+			// summary:
 			//		Called when mouse wheel is used on the chart.
-			var scroll = event[(has("mozilla") ? "detail" : "wheelDelta")] / sUnit;
+			var scroll = event.wheelDelta / sUnit;
 			// on Mozilla the sUnit might actually not always be 3
 			// make sure we never have -1 < scroll < 1
 			if(scroll > -1 && scroll < 0){
@@ -192,7 +183,7 @@ define(["dojo/_base/html", "dojo/_base/declare", "dojo/_base/window", "dojo/_bas
 		},
 		
 		onKeyPress: function(event){
-			//	summary:
+			// summary:
 			//		Called when a key is pressed on the chart.
 			if(keyTests[this.keyZoomModifier](event)){
 				if(event.keyChar == "+" || event.keyCode == keys.NUMPAD_PLUS){
@@ -204,7 +195,7 @@ define(["dojo/_base/html", "dojo/_base/declare", "dojo/_base/window", "dojo/_bas
 		},
 		
 		onDoubleClick: function(event){
-			//	summary:
+			// summary:
 			//		Called when the mouse is double is double clicked on the chart. Toggle between zoom and fit chart.
 			var chart = this.chart, axis = chart.getAxis(this.axis);
 			var scale = 1 / this.scaleFactor;
@@ -240,6 +231,11 @@ define(["dojo/_base/html", "dojo/_base/declare", "dojo/_base/window", "dojo/_bas
 			chart.zoomIn(this.axis, [newStart, newEnd]);
 			// do not scroll browser
 			eventUtil.stop(event);
+		},
+		
+		_getDelta: function(event){
+			return this.chart.getAxis(this.axis).vertical?(this._startCoord- event.pageY):(event.pageX - this._startCoord);
 		}
-	});		
+	});
+	return has("dojo-bidi")? declare("dojox.charting.action2d.MouseZoomAndPan", [MouseZoomAndPan, BidiMouseZoomAndPan]) : MouseZoomAndPan;
 });
diff --git a/dojox/charting/action2d/MoveSlice.js b/dojox/charting/action2d/MoveSlice.js
index 8ea61d3..75b8971 100644
--- a/dojox/charting/action2d/MoveSlice.js
+++ b/dojox/charting/action2d/MoveSlice.js
@@ -1,28 +1,28 @@
-define(["dojo/_base/connect", "dojo/_base/declare", "./PlotAction", "dojo/fx/easing", "dojox/gfx/matrix", 
-	"dojox/gfx/fx", "dojox/lang/functional", "dojox/lang/functional/scan", "dojox/lang/functional/fold"], 
-	function(hub, declare, PlotAction, dfe, m, gf, df, dfs, dff){
+define(["dojo/_base/connect", "dojo/_base/declare", "dojo/_base/array", "./PlotAction", "dojo/fx/easing", "dojox/gfx/matrix",
+	"dojox/gfx/fx", "dojox/lang/functional", "dojox/lang/functional/scan", "dojox/lang/functional/fold"],
+	function(hub, declare, array, PlotAction, dfe, m, gf, df){
 
 	/*=====
-	dojo.declare("dojox.charting.action2d.__MoveSliceCtorArgs", dojox.charting.action2d.__PlotActionCtorArgs, {
-		//	summary:
-		//		Additional arguments for highlighting actions.
-	
-		//	scale: Number?
-		//		The amount to scale the pie slice.  Default is 1.05.
-		scale: 1.05,
-	
-		//	shift: Number?
-		//		The amount in pixels to shift the pie slice.  Default is 7.
-		shift: 7
-	});
-	var PlotAction = dojox.charting.action2d.PlotAction;
+	var __MoveSliceCtorArgs = {
+			// summary:
+			//		Additional arguments for move slice actions.
+			// duration: Number?
+			//		The amount of time in milliseconds for an animation to last.  Default is 400.
+			// easing: dojo/fx/easing/*?
+			//		An easing object (see dojo.fx.easing) for use in an animation.  The
+			//		default is dojo.fx.easing.backOut.
+			// scale: Number?
+			//		The amount to scale the pie slice.  Default is 1.05.
+			// shift: Number?
+			//		The amount in pixels to shift the pie slice.  Default is 7.
+	};
 	=====*/
 	
 	var DEFAULT_SCALE = 1.05,
 		DEFAULT_SHIFT = 7;	// px
 
 	return declare("dojox.charting.action2d.MoveSlice", PlotAction, {
-		//	summary:
+		// summary:
 		//		Create an action for a pie chart that moves and scales a pie slice.
 
 		// the data description block for the widget parser
@@ -35,13 +35,13 @@ define(["dojo/_base/connect", "dojo/_base/declare", "./PlotAction", "dojo/fx/eas
 		optionalParams: {},	// no optional parameters
 
 		constructor: function(chart, plot, kwArgs){
-			//	summary:
+			// summary:
 			//		Create the slice moving action and connect it to the plot.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action belongs to.
-			//	plot: String?
+			// plot: String?
 			//		The plot this action is attached to.  If not passed, "default" is assumed.
-			//	kwArgs: dojox.charting.action2d.__MoveSliceCtorArgs?
+			// kwArgs: __MoveSliceCtorArgs?
 			//		Optional keyword arguments object for setting parameters.
 			if(!kwArgs){ kwArgs = {}; }
 			this.scale = typeof kwArgs.scale == "number" ? kwArgs.scale : DEFAULT_SCALE;
@@ -51,9 +51,9 @@ define(["dojo/_base/connect", "dojo/_base/declare", "./PlotAction", "dojo/fx/eas
 		},
 
 		process: function(o){
-			//	summary:
+			// summary:
 			//		Process the action on the given object.
-			//	o: dojox.gfx.Shape
+			// o: dojox/gfx/shape.Shape
 			//		The object on which to process the slice moving action.
 			if(!o.shape || o.element != "slice" || !(o.type in this.overOutEvents)){ return; }
 
@@ -61,12 +61,15 @@ define(["dojo/_base/connect", "dojo/_base/declare", "./PlotAction", "dojo/fx/eas
 				// calculate the running total of slice angles
 				var startAngle = m._degToRad(o.plot.opt.startAngle);
 				if(typeof o.run.data[0] == "number"){
-					this.angles = df.map(df.scanl(o.run.data, "+", startAngle),
+					this.angles = df.map(df.scanl(o.run.data, "+", 0),
 						"* 2 * Math.PI / this", df.foldl(o.run.data, "+", 0));
 				}else{
-					this.angles = df.map(df.scanl(o.run.data, "a + b.y", startAngle),
+					this.angles = df.map(df.scanl(o.run.data, "a + b.y", 0),
 						"* 2 * Math.PI / this", df.foldl(o.run.data, "a + b.y", 0));
 				}
+				this.angles = array.map(this.angles, function(item){
+					return item + startAngle;
+				});
 			}
 
 			var index = o.index, anim, startScale, endScale, startOffset, endOffset,
diff --git a/dojox/charting/action2d/PlotAction.js b/dojox/charting/action2d/PlotAction.js
index 3ac5733..6197b72 100644
--- a/dojox/charting/action2d/PlotAction.js
+++ b/dojox/charting/action2d/PlotAction.js
@@ -1,39 +1,35 @@
-define(["dojo/_base/connect", "dojo/_base/declare", "./Base", "dojo/fx/easing", "dojox/lang/functional", 
-		"dojox/lang/functional/object"], 
-	function(hub, declare, Base, dfe, df, dlfo){
+define(["dojo/_base/connect", "dojo/_base/declare", "./Base", "dojo/fx/easing", "dojox/lang/functional"],
+	function(hub, declare, Base, dfe, df){
 	
 	/*=====
-	dojox.charting.action2d.__PlotActionCtorArgs = function(duration, easing){
-	 	//	summary:
+	var __PlotActionCtorArgs = {
+	 	// summary:
 		//		The base keyword arguments object for creating an action2d.
-		//	duration: Number?
+		// duration: Number?
 		//		The amount of time in milliseconds for an animation to last.  Default is 400.
-		//	easing: dojo.fx.easing.*?
+		// easing: dojo/fx/easing/*?
 		//		An easing object (see dojo.fx.easing) for use in an animation.  The
 		//		default is dojo.fx.easing.backOut.
-		this.duration = duration;
-		this.easing = easing;
-	}
-	var Base = dojox.charting.action2d.Base;
+	};
 	=====*/
 
 	var DEFAULT_DURATION = 400,	// ms
 		DEFAULT_EASING   = dfe.backOut;
 
 	return declare("dojox.charting.action2d.PlotAction", Base, {
-		//	summary:
+		// summary:
 		//		Base action class for plot actions.
 
 		overOutEvents: {onmouseover: 1, onmouseout: 1},
 
 		constructor: function(chart, plot, kwargs){
-			//	summary:
+			// summary:
 			//		Create a new base PlotAction.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action applies to.
-			//	plot: String?
+			// plot: String?
 			//		The name of the plot this action belongs to.  If none is passed "default" is assumed.
-			//	kwargs: dojox.charting.action2d.__PlotActionCtorArgs?
+			// kwargs: __PlotActionCtorArgs?
 			//		Optional arguments for the action.
 			this.anim = {};
 
@@ -44,13 +40,13 @@ define(["dojo/_base/connect", "dojo/_base/declare", "./Base", "dojo/fx/easing",
 		},
 
 		connect: function(){
-			//	summary:
+			// summary:
 			//		Connect this action to the given plot.
 			this.handle = this.chart.connectToPlot(this.plot.name, this, "process");
 		},
 
 		disconnect: function(){
-			//	summary:
+			// summary:
 			//		Disconnect this action from the given plot, if connected.
 			if(this.handle){
 				hub.disconnect(this.handle);
@@ -59,12 +55,12 @@ define(["dojo/_base/connect", "dojo/_base/declare", "./Base", "dojo/fx/easing",
 		},
 
 		reset: function(){
-			//	summary:
+			// summary:
 			//		Reset the action.
 		},
 
 		destroy: function(){
-			//	summary:
+			// summary:
 			//		Do any cleanup needed when destroying parent elements.
 			this.inherited(arguments);
 			df.forIn(this.anim, function(o){
diff --git a/dojox/charting/action2d/Shake.js b/dojox/charting/action2d/Shake.js
index 3827242..596a9c8 100644
--- a/dojox/charting/action2d/Shake.js
+++ b/dojox/charting/action2d/Shake.js
@@ -3,21 +3,23 @@ define(["dojo/_base/connect", "dojo/_base/declare", "./PlotAction",
 	function(hub, declare, PlotAction, df, dfe, m, gf){
 
 	/*=====
-	dojo.declare("dojox.charting.action2d.__ShakeCtorArgs", dojox.charting.action2d.__PlotActionCtorArgstorArgs, {
-		//	summary:
-		//		Additional arguments for highlighting actions.
-	
-		//	shift: Number?
-		//		The amount in pixels to shift the pie slice.  Default is 3.
-		shift: 3
-	});
-	var PlotAction = dojox.charting.action2d.PlotAction;
+	var __ShakeCtorArgs = {
+			// summary:
+			//		Additional arguments for shaking actions.
+			// duration: Number?
+			//		The amount of time in milliseconds for an animation to last.  Default is 400.
+			// easing: dojo/fx/easing/*?
+			//		An easing object (see dojo.fx.easing) for use in an animation.  The
+			//		default is dojo.fx.easing.backOut.
+			// shift: Number?
+			//		The amount in pixels to shift the pie slice.  Default is 3.
+	};
 	=====*/
 
 	var DEFAULT_SHIFT = 3;
 
 	return declare("dojox.charting.action2d.Shake", PlotAction, {
-		//	summary:
+		// summary:
 		//		Create a shaking action for use on an element in a chart.
 
 		// the data description block for the widget parser
@@ -30,13 +32,13 @@ define(["dojo/_base/connect", "dojo/_base/declare", "./PlotAction",
 		optionalParams: {},	// no optional parameters
 
 		constructor: function(chart, plot, kwArgs){
-			//	summary:
+			// summary:
 			//		Create the shaking action and connect it to the plot.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action belongs to.
-			//	plot: String?
+			// plot: String?
 			//		The plot this action is attached to.  If not passed, "default" is assumed.
-			//	kwArgs: dojox.charting.action2d.__ShakeCtorArgs?
+			// kwArgs: __ShakeCtorArgs?
 			//		Optional keyword arguments object for setting parameters.
 			if(!kwArgs){ kwArgs = {}; }
 			this.shiftX = typeof kwArgs.shiftX == "number" ? kwArgs.shiftX : DEFAULT_SHIFT;
@@ -46,15 +48,13 @@ define(["dojo/_base/connect", "dojo/_base/declare", "./PlotAction",
 		},
 
 		process: function(o){
-			//	summary:
+			// summary:
 			//		Process the action on the given object.
-			//	o: dojox.gfx.Shape
+			// o: dojox/gfx/shape.Shape
 			//		The object on which to process the slice moving action.
 			if(!o.shape || !(o.type in this.overOutEvents)){ return; }
 
-			var runName = o.run.name, index = o.index, vector = [], anim,
-				shiftX = o.type == "onmouseover" ? this.shiftX : -this.shiftX,
-				shiftY = o.type == "onmouseover" ? this.shiftY : -this.shiftY;
+			var runName = o.run.name, index = o.index, vector = [], anim;
 
 			if(runName in this.anim){
 				anim = this.anim[runName][index];
diff --git a/dojox/charting/action2d/Tooltip.js b/dojox/charting/action2d/Tooltip.js
index b86f6f8..751264d 100644
--- a/dojox/charting/action2d/Tooltip.js
+++ b/dojox/charting/action2d/Tooltip.js
@@ -1,70 +1,71 @@
-define(["dojo/_base/kernel", "dijit/Tooltip","dojo/_base/lang", "dojo/_base/html", "dojo/_base/declare", "./PlotAction", 
-	"dojox/gfx/matrix", "dojox/lang/functional", "dojox/lang/functional/scan", "dojox/lang/functional/fold"], 
-	function(dojo, Tooltip, lang, html, declare, PlotAction, m, df, dfs, dff){
+define(["dijit/Tooltip", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window", "dojo/_base/connect", "dojo/dom-style",
+	"./PlotAction", "dojox/gfx/matrix", "dojo/has", "dojo/has!dojo-bidi?../bidi/action2d/Tooltip", 
+	"dojox/lang/functional", "dojox/lang/functional/scan", "dojox/lang/functional/fold"],
+	function(DijitTooltip, lang, declare, win, hub, domStyle, PlotAction, m, has, BidiTooltip, df){
 	
 	/*=====
-	dojo.declare("dojox.charting.action2d.__TooltipCtorArgs", dojox.charting.action2d.__PlotActionCtorArgs, {
-		//	summary:
-		//		Additional arguments for tooltip actions.
-	
-		//	text: Function?
-		//		The function that produces the text to be shown within a tooltip.  By default this will be
-		//		set by the plot in question, by returning the value of the element.
-		text: null
-	});
-	var PlotAction = dojox.charting.action2d.PlotAction;
+	var __TooltipCtorArgs = {
+			// summary:
+			//		Additional arguments for tooltip actions.
+			// duration: Number?
+			//		The amount of time in milliseconds for an animation to last.  Default is 400.
+			// easing: dojo/fx/easing/*?
+			//		An easing object (see dojo.fx.easing) for use in an animation.  The
+			//		default is dojo.fx.easing.backOut.
+			// text: Function?
+			//		The function that produces the text to be shown within a tooltip.  By default this will be
+			//		set by the plot in question, by returning the value of the element.
+			// mouseOver: Boolean?
+            //		Whether the tooltip is enabled on mouse over or on mouse click / touch down. Default is true.
+	};
 	=====*/
 
-	var DEFAULT_TEXT = function(o){
+	var DEFAULT_TEXT = function(o, plot){
 		var t = o.run && o.run.data && o.run.data[o.index];
 		if(t && typeof t != "number" && (t.tooltip || t.text)){
 			return t.tooltip || t.text;
 		}
-		if(o.element == "candlestick"){
-			return '<table cellpadding="1" cellspacing="0" border="0" style="font-size:0.9em;">'
-				+ '<tr><td>Open:</td><td align="right"><strong>' + o.data.open + '</strong></td></tr>'
-				+ '<tr><td>High:</td><td align="right"><strong>' + o.data.high + '</strong></td></tr>'
-				+ '<tr><td>Low:</td><td align="right"><strong>' + o.data.low + '</strong></td></tr>'
-				+ '<tr><td>Close:</td><td align="right"><strong>' + o.data.close + '</strong></td></tr>'
-				+ (o.data.mid !== undefined ? '<tr><td>Mid:</td><td align="right"><strong>' + o.data.mid + '</strong></td></tr>' : '')
-				+ '</table>';
+		if(plot.tooltipFunc){
+			return plot.tooltipFunc(o);
+		}else{
+			return o.y;
 		}
-		return o.element == "bar" ? o.x : o.y;
 	};
 
 	var pi4 = Math.PI / 4, pi2 = Math.PI / 2;
 	
-	return declare("dojox.charting.action2d.Tooltip", PlotAction, {
-		//	summary:
+	var Tooltip = declare(has("dojo-bidi")? "dojox.charting.action2d.NonBidiTooltip" : "dojox.charting.action2d.Tooltip", PlotAction, {
+		// summary:
 		//		Create an action on a plot where a tooltip is shown when hovering over an element.
 
 		// the data description block for the widget parser
 		defaultParams: {
-			text: DEFAULT_TEXT	// the function to produce a tooltip from the object
+			text: DEFAULT_TEXT,	// the function to produce a tooltip from the object
+            mouseOver: true
 		},
 		optionalParams: {},	// no optional parameters
 
 		constructor: function(chart, plot, kwArgs){
-			//	summary:
+			// summary:
 			//		Create the tooltip action and connect it to the plot.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action belongs to.
-			//	plot: String?
+			// plot: String?
 			//		The plot this action is attached to.  If not passed, "default" is assumed.
-			//	kwArgs: dojox.charting.action2d.__TooltipCtorArgs?
+			// kwArgs: __TooltipCtorArgs?
 			//		Optional keyword arguments object for setting parameters.
 			this.text = kwArgs && kwArgs.text ? kwArgs.text : DEFAULT_TEXT;
-			
+			this.mouseOver = kwArgs && kwArgs.mouseOver != undefined ? kwArgs.mouseOver : true;
 			this.connect();
 		},
 		
 		process: function(o){
-			//	summary:
+			// summary:
 			//		Process the action on the given object.
-			//	o: dojox.gfx.Shape
+			// o: dojox/gfx/shape.Shape
 			//		The object on which to process the highlighting action.
 			if(o.type === "onplotreset" || o.type === "onmouseout"){
-                Tooltip.hide(this.aroundRect);
+                DijitTooltip.hide(this.aroundRect);
 				this.aroundRect = null;
 				if(o.type === "onplotreset"){
 					delete this.angles;
@@ -72,10 +73,10 @@ define(["dojo/_base/kernel", "dijit/Tooltip","dojo/_base/lang", "dojo/_base/html
 				return;
 			}
 			
-			if(!o.shape || o.type !== "onmouseover"){ return; }
+			if(!o.shape || (this.mouseOver && o.type !== "onmouseover") || (!this.mouseOver && o.type !== "onclick")){ return; }
 			
 			// calculate relative coordinates and the position
-			var aroundRect = {type: "rect"}, position = ["after", "before"];
+			var aroundRect = {type: "rect"}, position = ["after-centered", "before-centered"];
 			switch(o.element){
 				case "marker":
 					aroundRect.x = o.cx;
@@ -87,8 +88,15 @@ define(["dojo/_base/kernel", "dijit/Tooltip","dojo/_base/lang", "dojo/_base/html
 					aroundRect.y = o.cy - o.cr;
 					aroundRect.w = aroundRect.h = 2 * o.cr;
 					break;
+				case "spider_circle":
+					aroundRect.x = o.cx;
+					aroundRect.y = o.cy ;
+					aroundRect.w = aroundRect.h = 1;
+					break;
+				case "spider_plot":
+					return;
 				case "column":
-					position = ["above", "below"];
+					position = ["above-centered", "below-centered"];
 					// intentional fall down
 				case "bar":
 					aroundRect = lang.clone(o.shape.getShape());
@@ -118,15 +126,19 @@ define(["dojo/_base/kernel", "dijit/Tooltip","dojo/_base/lang", "dojo/_base/html
 					aroundRect.x = o.cx + o.cr * Math.cos(angle);
 					aroundRect.y = o.cy + o.cr * Math.sin(angle);
 					aroundRect.w = aroundRect.h = 1;
+                    // depending on startAngle we might go out of the 0-2*PI range, normalize that
+                    if(startAngle && (angle < 0 || angle > 2 * Math.PI)){
+						angle = Math.abs(2 * Math.PI  - Math.abs(angle));
+					}
 					// calculate the position
 					if(angle < pi4){
 						// do nothing: the position is right
 					}else if(angle < pi2 + pi4){
-						position = ["below", "above"];
+						position = ["below-centered", "above-centered"];
 					}else if(angle < Math.PI + pi4){
-						position = ["before", "after"];
+						position = ["before-centered", "after-centered"];
 					}else if(angle < 2 * Math.PI - pi4){
-						position = ["above", "below"];
+						position = ["above-centered", "below-centered"];
 					}
 					/*
 					else{
@@ -135,7 +147,9 @@ define(["dojo/_base/kernel", "dijit/Tooltip","dojo/_base/lang", "dojo/_base/html
 					*/
 					break;
 			}
-			
+			if(has("dojo-bidi")){
+				this._recheckPosition(o,aroundRect,position);
+			}
 			// adjust relative coordinates to absolute, and remove fractions
 			var lt = this.chart.getCoords();
 			aroundRect.x += lt.x;
@@ -146,21 +160,22 @@ define(["dojo/_base/kernel", "dijit/Tooltip","dojo/_base/lang", "dojo/_base/html
 			aroundRect.h = Math.ceil(aroundRect.h);
 			this.aroundRect = aroundRect;
 
-			var tooltip = this.text(o);
-			if(this.chart.getTextDir){
-				var isChartDirectionRtl = (html.style(this.chart.node,"direction") == "rtl");
-				var isBaseTextDirRtl = (this.chart.getTextDir(tooltip) == "rtl");
+			var tooltipText = this.text(o, this.plot);
+			if(tooltipText){
+				DijitTooltip.show(this._format(tooltipText), this.aroundRect, position);
 			}
-			if(tooltip){
-				if(isBaseTextDirRtl && !isChartDirectionRtl){
-					Tooltip.show("<span dir = 'rtl'>" + tooltip +"</span>", this.aroundRect, position);
-				}
-				else if(!isBaseTextDirRtl && isChartDirectionRtl){
-					Tooltip.show("<span dir = 'ltr'>" + tooltip +"</span>", this.aroundRect, position);
-				}else{
-					Tooltip.show(tooltip, this.aroundRect, position);
-				}
+			if(!this.mouseOver){
+				this._handle = hub.connect(win.doc, "onclick", this, "onClick");
 			}
+		},
+		onClick: function(){
+			this.process({ type: "onmouseout"});
+		},
+		_recheckPosition: function(obj,rect,position){			
+		},
+		_format: function(tooltipText){
+			return tooltipText;
 		}
 	});
+	return has("dojo-bidi")? declare("dojox.charting.action2d.Tooltip", [Tooltip, BidiTooltip]) : Tooltip;
 });
diff --git a/dojox/charting/action2d/TouchIndicator.js b/dojox/charting/action2d/TouchIndicator.js
index f8fc594..ab8431f 100644
--- a/dojox/charting/action2d/TouchIndicator.js
+++ b/dojox/charting/action2d/TouchIndicator.js
@@ -1,106 +1,76 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "./ChartAction", "./_IndicatorElement", "dojox/lang/utils"],
-	function(lang, declare, eventUtil, ChartAction, IndicatorElement, du){ 
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "dojo/touch", "./ChartAction", "./_IndicatorElement", "dojox/lang/utils"],
+	function(lang, declare, eventUtil, touch, ChartAction, IndicatorElement, du){
 	
 	/*=====
-	dojo.declare("dojox.charting.action2d.__TouchIndicatorCtorArgs", null, {
-		//	summary:
-		//		Additional arguments for Touch indicator.
-		
-		//	series: String
-		//		Target series name for this chart action.
-		series:	"",
-		
-		//	dualIndicator: Boolean? 
-		//		Whether a double touch on the chart creates a dual indicator showing data trend between the two touch points. Default is false.
-		dualIndicator:		false,
-		
-		//	autoScroll: Boolean? 
-		//		Whether when moving indicator the chart is automatically scrolled. Default is true.
-		autoScroll:		true,
-	
-		//	vertical: Boolean? 
-		//		Whether the indicator is vertical or not. Default is true.
-		vertical:		true,
-		
-		//	fixed: Boolean?
-		//		Whether a fixed precision must be applied to data values for display. Default is true.
-		fixed:			true,
-	
-		//	precision: Number?
-		//		The precision at which to round data values for display. Default is 1.
-		precision:		0,
-		
-		//	lineStroke: gfx.Stroke?
-		//		An optional stroke to use for indicator line.
-		lineStroke:		{},
-	
-		//	lineOutline: dojo.gfx.Stroke?
-		//		An optional outline to use for indicator line.
-		lineOutline:		{},
-	
-		//	lineShadow: dojo.gfx.Stroke?
-		//		An optional shadow to use for indicator line.
-		lineShadow:		{},
-		
-		//	stroke: dojo.gfx.Stroke?
-		//		An optional stroke to use for indicator label background.
-		stroke:		{},
-	
-		//	outline: dojo.gfx.Stroke?
-		//		An optional outline to use for indicator label background.
-		outline:		{},
-	
-		//	shadow: dojo.gfx.Stroke?
-		//		An optional shadow to use for indicator label background.
-		shadow:		{},
-	
-		//	fill: dojo.gfx.Fill?
-		//		An optional fill to use for indicator label background.
-		fill:			{},
-		
-		//	fillFunc: Function?
-		//		An optional function to use to compute label background fill. It takes precedence over
-		//		fill property when available.
-		fillFunc:		null,
-		
-		//	labelFunc: Function?
-		//		An optional function to use to compute label text. It takes precedence over
-		//		the default text when available.
-		labelFunc:		{},
-	
-		//	font: String?
-		//		A font definition to use for indicator label background.
-		font:		"",
-	
-		//	fontColor: String|dojo.Color?
-		//		The color to use for indicator label background.
-		fontColor:	"",
-	
-		//	markerStroke: dojo.gfx.Stroke?
-		//		An optional stroke to use for indicator marker.
-		markerStroke:		{},
-	
-		//	markerOutline: dojo.gfx.Stroke?
-		//		An optional outline to use for indicator marker.
-		markerOutline:		{},
-	
-		//	markerShadow: dojo.gfx.Stroke?
-		//		An optional shadow to use for indicator marker.
-		markerShadow:		{},
-	
-		//	markerFill: dojo.gfx.Fill?
-		//		An optional fill to use for indicator marker.
-		markerFill:			{},
-		
-		//	markerSymbol: String?
-		//		An optional symbol string to use for indicator marker.
-		markerFill:			{}	
-	});
-	var ChartAction = dojox.charting.action2d.ChartAction;
+	var __TouchIndicatorCtorArgs = {
+			// summary:
+			//		Additional arguments for touch indicator.
+			// series: String
+			//		Target series name for this action.
+			// autoScroll: Boolean?
+			//		Whether when moving indicator the chart is automatically scrolled. Default is true.
+			// lines: Boolean?
+			//		Whether the indicator lines are visible or not. Default is true.
+			// labels: Boolean?
+			//		Whether the indicator label is visible or not. Default is true.
+			// markers: Boolean?
+			//		Whether the indicator markers are visible or not. Default is true.
+			// offset: {x, y}?
+			//		A pair of (x, y) pixel coordinate to specify the offset between the end of the indicator line and the
+			//		position at which the labels are rendered. Default is no offset which means it is automatically computed.
+			// start: Boolean?
+			//		Whether the label is rendered at the start or end of the indicator. Default is false meaning end of
+			//		the line.
+			// vertical: Boolean?
+			//		Whether the indicator is vertical or not. Default is true.
+			// fixed: Boolean?
+			//		Whether a fixed precision must be applied to data values for display. Default is true.
+			// precision: Number?
+			//		The precision at which to round data values for display. Default is 0.
+			// lineStroke: dojo/gfx/Stroke?
+			//		An optional stroke to use for indicator line.
+			// lineOutline: dojo/gfx/Stroke?
+			//		An optional outline to use for indicator line.
+			// lineShadow: dojo/gfx/Stroke?
+			//		An optional shadow to use for indicator line.
+			// stroke: dojo.gfx.Stroke?
+			//		An optional stroke to use for indicator label background.
+			// outline: dojo.gfx.Stroke?
+			//		An optional outline to use for indicator label background.
+			// shadow: dojo.gfx.Stroke?
+			//		An optional shadow to use for indicator label background.
+			// fill: dojo.gfx.Fill?
+			//		An optional fill to use for indicator label background.
+			// fillFunc: Function?
+			//		An optional function to use to compute label background fill. It takes precedence over
+			//		fill property when available.
+			// labelFunc: Function?
+			//		An optional function to use to compute label text. It takes precedence over
+			//		the default text when available.
+			//	|		function labelFunc(firstDataPoint, secondDataPoint, fixed, precision) {}
+			//		`firstDataPoint` is the `{x, y}` data coordinates pointed by the touch point.
+			//		`secondDataPoint` is the data coordinates pointed by the second touch point.
+			//		`fixed` is true if fixed precision must be applied.
+			//		`precision` is the requested precision to be applied.
+			// font: String?
+			//		A font definition to use for indicator label background.
+			// fontColor: String|dojo.Color?
+			//		The color to use for indicator label background.
+			// markerStroke: dojo.gfx.Stroke?
+			//		An optional stroke to use for indicator marker.
+			// markerOutline: dojo.gfx.Stroke?
+			//		An optional outline to use for indicator marker.
+			// markerShadow: dojo.gfx.Stroke?
+			//		An optional shadow to use for indicator marker.
+			// markerFill: dojo.gfx.Fill?
+			//		An optional fill to use for indicator marker.
+			// markerSymbol: String?
+			//		An optional symbol string to use for indicator marker.
+		};
 	=====*/
 
 	return declare("dojox.charting.action2d.TouchIndicator", ChartAction, {
-		//	summary:
+		// summary:
 		//		Create a touch indicator action. You can touch over the chart to display a data indicator.
 
 		// the data description block for the widget parser
@@ -110,12 +80,16 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "./ChartAct
 			vertical: true,
 			autoScroll: true,
 			fixed: true,
-			precision: 0
+			precision: 0,
+			lines: true,
+			labels: true,
+			markers: true
 		},
 		optionalParams: {
 			lineStroke: {},
 			outlineStroke: {},
 			shadowStroke: {},
+			lineFill: {},
 			stroke:		{},
 			outline:	{},
 			shadow:		{},
@@ -128,20 +102,24 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "./ChartAct
 			markerOutline:		{},
 			markerShadow:		{},
 			markerFill:			{},
-			markerSymbol:		""
+			markerSymbol:		"",
+			offset: {},
+			start: false
 		},	
 
 		constructor: function(chart, plot, kwArgs){
-			//	summary:
+			// summary:
 			//		Create a new touch indicator action and connect it.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action applies to.
-			//	kwArgs: dojox.charting.action2d.__TouchIndicatorCtorArgs?
+			// kwArgs: __TouchIndicatorCtorArgs?
 			//		Optional arguments for the chart action.
-			this._listeners = [{eventName: "ontouchstart", methodName: "onTouchStart"},
-			                   {eventName: "ontouchmove", methodName: "onTouchMove"},
-			                   {eventName: "ontouchend", methodName: "onTouchEnd"},
-			                   {eventName: "ontouchcancel", methodName: "onTouchEnd"}];
+			this._listeners = [
+				{eventName: touch.press, methodName: "onTouchStart"},
+				{eventName: touch.move, methodName: "onTouchMove"},
+				{eventName: touch.release, methodName: "onTouchEnd"},
+				{eventName: touch.cancel, methodName: "onTouchEnd"}
+			];
 			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
@@ -150,7 +128,7 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "./ChartAct
 		},
 		
 		connect: function(){
-			//	summary:
+			// summary:
 			//		Connect this action to the chart. This adds a indicator plot
 			//		to the chart that's why Chart.render() must be called after connect.
 			this.inherited(arguments);
@@ -159,7 +137,7 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "./ChartAct
 		},
 
 		disconnect: function(){
-			//	summary:
+			// summary:
 			//		Disconnect this action from the chart.
 			var plot = this.chart.getPlot(this._uName);
 			if(plot.pageCoord){
@@ -170,36 +148,42 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "./ChartAct
 			this.inherited(arguments);
 		},
 
+		onChange: function(event){
+			// summary:
+			//		Called when the indicator value changed.
+			// event:
+			//		An event with a start and end properties containing the {x, y} data points of the first and
+			//		second (if available) touch indicators. It also contains a label property containing the displayed
+			//		text.
+		},
+
 		onTouchStart: function(event){
-			//	summary:
-			//		Called when touch is started on the chart.		
-			if(event.touches.length==1){
+			// summary:
+			//		Called when touch is started on the chart.
+			if(!event.touches || event.touches.length == 1){
 				this._onTouchSingle(event, true);
-			}else if(this.opt.dualIndicator && event.touches.length==2){
+			}else if(this.opt.dualIndicator && event.touches.length == 2){
 				this._onTouchDual(event);
 			}
 		},
 
 		onTouchMove: function(event){
-			//	summary:
+			// summary:
 			//		Called when touch is moved on the chart.
-			if(event.touches.length==1){
+			if(!event.touches || event.touches.length == 1){
 				this._onTouchSingle(event);
-			}else if(this.opt.dualIndicator && event.touches.length==2){
-				this._onTouchDual(event);	
+			}else if(this.opt.dualIndicator && event.touches.length == 2){
+				this._onTouchDual(event);
 			}
 		},
 
 		_onTouchSingle: function(event, delayed){
-			// sync
 			if(this.chart._delayedRenderHandle && !delayed){
 				// we have pending rendering from a previous call, let's sync
-				clearTimeout(this.chart._delayedRenderHandle);
-				this.chart._delayedRenderHandle = null;
 				this.chart.render();
 			}
 			var plot = this.chart.getPlot(this._uName);
-			plot.pageCoord  = {x: event.touches[0].pageX, y: event.touches[0].pageY};
+			plot.pageCoord  = {x: event.touches?event.touches[0].pageX:event.pageX, y: event.touches?event.touches[0].pageY:event.pageY};
 			plot.dirty = true;
 			if(delayed){
 				this.chart.delayedRender();
@@ -210,6 +194,11 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "./ChartAct
 		},
 		
 		_onTouchDual: function(event){
+			// sync
+			if(this.chart._delayedRenderHandle){
+				// we have pending rendering from a previous call, let's sync
+				this.chart.render();
+			}
 			var plot = this.chart.getPlot(this._uName);
 			plot.pageCoord = {x: event.touches[0].pageX, y: event.touches[0].pageY};
 			plot.secondCoord = {x: event.touches[1].pageX, y: event.touches[1].pageY};
@@ -219,7 +208,7 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "./ChartAct
 		},
 
 		onTouchEnd: function(event){
-			//	summary:
+			// summary:
 			//		Called when touch is ended or canceled on the chart.
 			var plot = this.chart.getPlot(this._uName);
 			plot.stopTrack();
diff --git a/dojox/charting/action2d/TouchZoomAndPan.js b/dojox/charting/action2d/TouchZoomAndPan.js
old mode 100644
new mode 100755
index f60b679..fe793c6
--- a/dojox/charting/action2d/TouchZoomAndPan.js
+++ b/dojox/charting/action2d/TouchZoomAndPan.js
@@ -1,9 +1,10 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "dojo/_base/sniff",
-	"./ChartAction", "../Element", "dojox/gesture/tap", "../plot2d/common"], 
-	function(lang, declare, eventUtil, has, ChartAction, Element, tap, common){
-	var GlassView = declare("dojox.charting.action2d._GlassView", [Element], {
-		//	summary: Private internal class used by TouchZoomAndPan actions.
-		//	tags:
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "dojo/sniff",
+	"./ChartAction", "../Element", "dojo/touch", "../plot2d/common", "dojo/has!dojo-bidi?../bidi/action2d/ZoomAndPan"],
+	function(lang, declare, eventUtil, has, ChartAction, Element, touch, common, BidiTouchZoomAndPan){
+	var GlassView = declare(Element, {
+		// summary:
+		//		Private internal class used by TouchZoomAndPan actions.
+		// tags:
 		//		private
 		constructor: function(chart){
 		},
@@ -14,101 +15,85 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "dojo/_base
 			this.cleanGroup();
 			this.group.createRect({width: this.chart.dim.width, height: this.chart.dim.height}).setFill("rgba(0,0,0,0)");
 		},
-		cleanGroup: function(creator){
-			//	summary:
-			//		Clean any elements (HTML or GFX-based) out of our group, and create a new one.
-			//	creator: dojox.gfx.Surface?
-			//		An optional surface to work with.
-			//	returns: dojox.charting.Element
-			//		A reference to this object for functional chaining.
-			this.inherited(arguments);
-			return this;	//	dojox.charting.Element
-		},
 		clear: function(){
-			//	summary:
+			// summary:
 			//		Clear out any parameters set on this plot.
-			//	returns: dojox.charting.action2d._IndicatorElement
+			// returns: GlassView
 			//		The reference to this plot for functional chaining.
 			this.dirty = true;
 			// glass view needs to be above
 			if(this.chart.stack[0] != this){
 				this.chart.movePlotToFront(this.name);
 			}
-			return this;	//	dojox.charting.plot2d._IndicatorElement
+			return this;	//	GlassView
 		},
 		getSeriesStats: function(){
-			//	summary:
+			// summary:
 			//		Returns default stats (irrelevant for this type of plot).
-			//	returns: Object
+			// returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
 			return lang.delegate(common.defaultStats);
 		},
 		initializeScalers: function(){
-			//	summary:
+			// summary:
 			//		Does nothing (irrelevant for this type of plot).
 			return this;
 		},
 		isDirty: function(){
-			//	summary:
+			// summary:
 			//		Return whether or not this plot needs to be redrawn.
-			//	returns: Boolean
+			// returns: Boolean
 			//		If this plot needs to be rendered, this will return true.
 			return this.dirty;
 		}
 	});
-	
+
 	/*=====
-	
-	declare("dojox.charting.action2d.__TouchZoomAndPanCtorArgs", null, {
-		//	summary:
-		//		Additional arguments for mouse zoom and pan actions.
-		
-		//	axis: String?
-		//		Target axis name for this action.  Default is "x".
-		axis: "x",
-		//	scaleFactor: Number?
-		//		The scale factor applied on double tap.  Default is 1.2.
-		scaleFactor: 1.2,
-		//	maxScale: Number?
-		//		The max scale factor accepted by this action.  Default is 100.
-		maxScale: 100,
-		//	enableScroll: Boolean?
-		//		Whether touch drag gesture should scroll the chart.  Default is true.
-		enableScroll: true,
-		//	enableZoom: Boolean?
-		//		Whether touch pinch and spread gesture should zoom out or in the chart.  Default is true.
-		enableZoom: true,
-	});
-	var ChartAction = dojox.charting.action2d.ChartAction;
+	var __TouchZoomAndPanCtorArgs = {
+			// summary:
+			//		Additional arguments for touch zoom and pan actions.
+			// axis: String?
+			//		Target axis name for this action.  Default is "x".
+			// scaleFactor: Number?
+			//		The scale factor applied on mouse wheel zoom.  Default is 1.2.
+			// maxScale: Number?
+			//		The max scale factor accepted by this chart action.  Default is 100.
+			// enableScroll: Boolean?
+			//		Whether touch drag gesture should scroll the chart.  Default is true.
+			// enableZoom: Boolean?
+			//		Whether touch pinch and spread gesture should zoom out or in the chart.  Default is true.
+	};
 	=====*/
-	
-	return declare("dojox.charting.action2d.TouchZoomAndPan", ChartAction, {
-		//	summary:
-		//		Create a touch zoom and pan action. 
-		//		You can zoom out or in the data window with pinch and spread gestures. You can scroll using drag gesture. 
+
+	var TouchZoomAndPan = declare(has("dojo-bidi")? "dojox.charting.action2d.NonBidiTouchZoomAndPan" : "dojox.charting.action2d.TouchZoomAndPan", ChartAction, {
+		// summary:
+		//		Create a touch zoom and pan action.
+		//		You can zoom out or in the data window with pinch and spread gestures except on Android 2.x and WP8 devices.
+		// 		You can scroll using drag gesture.
 		//		Finally this is possible to navigate between a fit window and a zoom one using double tap gesture.
-	
+
 		// the data description block for the widget parser
 		defaultParams: {
 			axis: "x",
-			scaleFactor: 1.2,	
+			scaleFactor: 1.2,
 			maxScale: 100,
 			enableScroll: true,
 			enableZoom: true
 		},
 		optionalParams: {},	// no optional parameters
-	
+
 		constructor: function(chart, plot, kwArgs){
-			//	summary:
+			// summary:
 			//		Create a new touch zoom and pan action and connect it.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this action applies to.
-			//	kwArgs: dojox.charting.action2d.__TouchZoomAndPanCtorArgs?
+			// kwArgs: __TouchZoomAndPanCtorArgs?
 			//		Optional arguments for the action.
-			this._listeners = [{eventName: "ontouchstart", methodName: "onTouchStart"},
-			                   {eventName: "ontouchmove", methodName: "onTouchMove"},
-			                   {eventName: "ontouchend", methodName: "onTouchEnd"},
-							   {eventName: tap.doubletap, methodName: "onDoubleTap"}];
+			this._listeners = [
+				{eventName: touch.press, methodName: "onTouchStart"},
+				{eventName: touch.move, methodName: "onTouchMove"},
+				{eventName: touch.release, methodName: "onTouchEnd"}
+			];
 			if(!kwArgs){ kwArgs = {}; }
 			this.axis = kwArgs.axis ? kwArgs.axis : "x";
 			this.scaleFactor = kwArgs.scaleFactor ? kwArgs.scaleFactor : 1.2;
@@ -118,43 +103,47 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "dojo/_base
 			this._uName = "touchZoomPan"+this.axis;
 			this.connect();
 		},
-		
+
 		connect: function(){
-			//	summary:
-			//		Connect this action to the chart. On Safari this adds a new glass view plot
+			// summary:
+			//		Connect this action to the chart. On iOS this adds a new glass view plot
 			//		to the chart that's why Chart.render() must be called after connect.
 			this.inherited(arguments);
-			// this is needed to workaround issue on Safari + SVG, because a touch start action
+			// this is needed to workaround issue on iOS Safari + SVG, because a touch start action
 			// started above a item that is removed during the touch action will stop
 			// dispatching touch events!
-			if(has("safari") && this.chart.surface.declaredClass.indexOf("svg")!=-1){
+			if(this.chart.surface.declaredClass.indexOf("svg")!=-1){
 				this.chart.addPlot(this._uName, {type: GlassView});
 			}
 		},
-		
+
 		disconnect: function(){
-			//	summary:
-			//		Disconnect this action from the chart. 
-			if(has("safari") && this.chart.surface.declaredClass.indexOf("svg")!=-1){
+			// summary:
+			//		Disconnect this action from the chart.
+			if(this.chart.surface.declaredClass.indexOf("svg")!=-1){
 				this.chart.removePlot(this._uName);
 			}
 			this.inherited(arguments);
 		},
-	
+
 		onTouchStart: function(event){
-			//	summary:
+			// summary:
 			//		Called when touch is started on the chart.
+
 			// we always want to be above regular plots and not clipped
 			var chart = this.chart, axis = chart.getAxis(this.axis);
-			var length = event.touches.length;
-			this._startPageCoord = {x: event.touches[0].pageX, y: event.touches[0].pageY};
+			var length = event.touches ? event.touches.length : 1;
+			var coord = event.touches ? event.touches[0] : event;
+			// in case we have a double tap register previous coord
+			var prevPageCoord = this._startPageCoord;
+			this._startPageCoord = {x: coord.pageX, y: coord.pageY};
 			if((this.enableZoom || this.enableScroll) && chart._delayedRenderHandle){
 				// we have pending rendering from a scroll, let's sync
-				clearTimeout(chart._delayedRenderHandle);
-				chart._delayedRenderHandle = null;
 				chart.render();
 			}
 			if(this.enableZoom && length >= 2){
+				// we reset double tap
+				this._startTime = 0;
 				this._endPageCoord =  {x: event.touches[1].pageX, y: event.touches[1].pageY};
 				var middlePageCoord = {x: (this._startPageCoord.x + this._endPageCoord.x) / 2,
 										y: (this._startPageCoord.y + this._endPageCoord.y) / 2};
@@ -164,78 +153,99 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "dojo/_base
 				this._middleCoord = t(middlePageCoord)[this.axis];
 				this._startCoord = scaler.bounds.from;
 				this._endCoord = scaler.bounds.to;
-			}else if(this.enableScroll){
-				this._startScroll(axis);
-				// needed for Android, otherwise will get a touch cancel while swiping
-				eventUtil.stop(event);
+			}else{
+				// double tap is only for single touch
+				if(!event.touches || event.touches.length == 1){
+					if(!this._startTime){
+						this._startTime = new Date().getTime();
+					}else if((new Date().getTime() - this._startTime) < 250 &&
+						Math.abs(this._startPageCoord.x - prevPageCoord.x) < 30 &&
+						Math.abs(this._startPageCoord.y - prevPageCoord.y) < 30){
+						this._startTime = 0;
+						this.onDoubleTap(event);
+					}else{
+						// we missed the doubletap, we need to re-init for next time
+						this._startTime = 0;
+					}
+				}else{
+					// we missed the doubletap, we need to re-init for next time
+					this._startTime = 0;
+				}
+				if(this.enableScroll){
+					this._startScroll(axis);
+					// needed for Android, otherwise will get a touch cancel while swiping
+					eventUtil.stop(event);
+				}
 			}
 		},
-	
+
 		onTouchMove: function(event){
-			//	summary:
+			// summary:
 			//		Called when touch is moved on the chart.
 			var chart = this.chart, axis = chart.getAxis(this.axis);
-			var length = event.touches.length;
-			var pAttr = axis.vertical?"pageY":"pageX", 
+			var length = event.touches ? event.touches.length : 1;
+			var pAttr = axis.vertical?"pageY":"pageX",
 					attr = axis.vertical?"y":"x";
+			// any move action cancel double tap
+			this._startTime = 0;
 			if(this.enableZoom && length >= 2){
 				var newMiddlePageCoord = {x: (event.touches[1].pageX + event.touches[0].pageX) / 2,
-											y: (event.touches[1].pageY + event.touches[0].pageY) / 2};		
+											y: (event.touches[1].pageY + event.touches[0].pageY) / 2};
 				var scale = (this._endPageCoord[attr] - this._startPageCoord[attr]) /
 					(event.touches[1][pAttr] - event.touches[0][pAttr]);
-	
+
 				if(this._initScale / scale > this.maxScale){
 					return;
 				}
-	
+
 				var newMiddleCoord = this._initData(newMiddlePageCoord)[this.axis];
-	
+
 				var newStart = scale * (this._startCoord - newMiddleCoord)  + this._middleCoord,
 				newEnd = scale * (this._endCoord - newMiddleCoord) + this._middleCoord;
 				chart.zoomIn(this.axis, [newStart, newEnd]);
 				// avoid browser pan
 				eventUtil.stop(event);
 			}else if(this.enableScroll){
-				var delta = axis.vertical?(this._startPageCoord[attr] - event.touches[0][pAttr]):
-					(event.touches[0][pAttr] - this._startPageCoord[attr]);
+				var delta = this._getDelta(event);
 				chart.setAxisWindow(this.axis, this._lastScale, this._initOffset - delta / this._lastFactor / this._lastScale);
 				chart.delayedRender();
 				// avoid browser pan
 				eventUtil.stop(event);
-			}		
+			}
 		},
-	
+
 		onTouchEnd: function(event){
-			//	summary:
+			// summary:
 			//		Called when touch is ended on the chart.
 			var chart = this.chart, axis = chart.getAxis(this.axis);
-			if(event.touches.length == 1 && this.enableScroll){
+			if((!event.touches || event.touches.length == 1) && this.enableScroll){
 				// still one touch available, let's start back from here for
 				// potential pan
-				this._startPageCoord = {x: event.touches[0].pageX, y: event.touches[0].pageY};
+				var coord = event.touches ? event.touches[0] : event;
+				this._startPageCoord = {x: coord.pageX, y: coord.pageY};
 				this._startScroll(axis);
 			}
 		},
-		
+
 		_startScroll: function(axis){
 			var bounds = axis.getScaler().bounds;
 			this._initOffset = axis.getWindowOffset();
 			// we keep it because of delay rendering we might now always have access to the
 			// information to compute it
 			this._lastScale = axis.getWindowScale();
-			this._lastFactor = bounds.span / (bounds.upper - bounds.lower); 
+			this._lastFactor = bounds.span / (bounds.upper - bounds.lower);
 		},
-	
+
 		onDoubleTap: function(event){
-			//	summary:
+			// summary:
 			//		Called when double tap is performed on the chart.
 			var chart = this.chart, axis = chart.getAxis(this.axis);
 			var scale = 1 / this.scaleFactor;
 			// are we fit?
 			if(axis.getWindowScale()==1){
 				// fit => zoom
-				var scaler = axis.getScaler(), start = scaler.bounds.from, end = scaler.bounds.to, 
-				oldMiddle = (start + end) / 2, newMiddle = this.plot.toData(this._startPageCoord)[this.axis], 
+				var scaler = axis.getScaler(), start = scaler.bounds.from, end = scaler.bounds.to,
+				oldMiddle = (start + end) / 2, newMiddle = this.plot.toData(this._startPageCoord)[this.axis],
 				newStart = scale * (start - oldMiddle) + newMiddle, newEnd = scale * (end - oldMiddle) + newMiddle;
 				chart.zoomIn(this.axis, [newStart, newEnd]);
 			}else{
@@ -244,6 +254,16 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "dojo/_base
 				chart.render();
 			}
 			eventUtil.stop(event);
+		},
+		
+		_getDelta: function(event){
+			var axis = this.chart.getAxis(this.axis),
+			    pAttr = axis.vertical?"pageY":"pageX",
+				attr = axis.vertical?"y":"x";
+			var coord = event.touches?event.touches[0]:event;
+			return axis.vertical?(this._startPageCoord[attr] - coord[pAttr]):
+				(coord[pAttr] - this._startPageCoord[attr]);
 		}
 	});
-});		
+	return has("dojo-bidi")? declare("dojox.charting.action2d.TouchZoomAndPan", [TouchZoomAndPan, BidiTouchZoomAndPan]) : TouchZoomAndPan;
+});
diff --git a/dojox/charting/action2d/_IndicatorElement.js b/dojox/charting/action2d/_IndicatorElement.js
index 7dc5ccf..ea8d9ee 100644
--- a/dojox/charting/action2d/_IndicatorElement.js
+++ b/dojox/charting/action2d/_IndicatorElement.js
@@ -1,108 +1,50 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "../Element", "../plot2d/common", 
-    "../axis2d/common", "dojox/gfx"], 
-	function(lang, declare, Element, dcpc, dcac, gfx){ 
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "../plot2d/Indicator",
+        "dojo/has", "../plot2d/common", "../axis2d/common", "dojox/gfx"], 
+	function(lang, array, declare, Indicator, has){
 
-	// all the code below should be removed when http://trac.dojotoolkit.org/ticket/11299 will be available
-	var getBoundingBox = function(shape){
-		return getTextBBox(shape, shape.getShape().text);
-	};
-	var getTextBBox = function(s, t){
-		var c = s.declaredClass;
-		if (c.indexOf("svg")!=-1){
-			// try/catch the FF native getBBox error. cheaper than walking up in the DOM
-			// hierarchy to check the conditions (bench show /10 )
-			try {
-				return lang.mixin({}, s.rawNode.getBBox());
-			}catch (e){
-				return null;
-			}
-		}else if(c.indexOf("vml")!=-1){
-			var rawNode = s.rawNode, _display = rawNode.style.display;
-			rawNode.style.display = "inline";
-			var w = gfx.pt2px(parseFloat(rawNode.currentStyle.width));
-			var h = gfx.pt2px(parseFloat(rawNode.currentStyle.height));
-			var sz = {x: 0, y: 0, width: w, height: h};
-			// in VML, the width/height we get are in view coordinates
-			// in our case we don't zoom the view so that is ok
-			// It's impossible to get the x/y from the currentStyle.left/top,
-			// because all negative coordinates are 'clipped' to 0.
-			// (x:0 + translate(-100) -> x=0
-			computeLocation(s, sz);
-			rawNode.style.display = _display;
-			return sz;
-		}else if(c.indexOf("silverlight")!=-1){
-			var bb = {width: s.rawNode.actualWidth, height: s.rawNode.actualHeight};
-			return computeLocation(s, bb, 0.75);
-		}else if(s.getTextWidth){
-			// canvas
-			var w = s.getTextWidth();
-			var font = s.getFont();
-			var fz = font ? font.size : gfx.defaultFont.size;
-			var h = gfx.normalizedLength(fz);
-			sz = {width: w, height: h};
-			computeLocation(s, sz, 0.75);
-			return sz;
-		}
-	};
-	var computeLocation =  function(s, sz, coef){
-		var width = sz.width, height = sz.height, sh = s.getShape(), align = sh.align;
-		switch (align) {
-		case "end":
-			sz.x = sh.x - width;
-			break;
-		case "middle":
-			sz.x = sh.x - width / 2;
-			break;
-		case "start":
-		default:
-			sz.x = sh.x;
-		break;
+	var getXYCoordinates = function(v, values, data){
+		var c2, c1 = v?{ x: values[0], y : data[0][0] } :
+					   { x : data[0][0], y : values[0] };
+		if(values.length > 1){
+			c2 = v?{ x: values[1], y : data[1][0] } :
+				   { x : data[1][0], y : values[1] };
 		}
-		coef = coef || 1;
-		sz.y = sh.y - height*coef; // rough approximation of the ascent!...
-		return sz;
+		return [c1, c2];
 	};
 
-	return declare("dojox.charting.action2d._IndicatorElement",[Element], {
-		//	summary:
+	var _IndicatorElement = declare("dojox.charting.action2d._IndicatorElement", Indicator, {
+		// summary:
 		//		Internal element used by indicator actions.
-		//	tags:
+		// tags:
 		//		private
 		constructor: function(chart, kwArgs){
 			if(!kwArgs){ kwArgs = {}; }
 			this.inter = kwArgs.inter;
 		},
 		_updateVisibility: function(cp, limit, attr){
-			var axis = attr=="x"?this.inter.plot._hAxis:this.inter.plot._vAxis;
+			var axis = attr=="x"?this._hAxis:this._vAxis;
 			var scale = axis.getWindowScale();
 			this.chart.setAxisWindow(axis.name, scale, axis.getWindowOffset() + (cp[attr] - limit[attr]) / scale);
 			this._noDirty = true;
 			this.chart.render();
 			this._noDirty = false;
-			if(!this._tracker){
-				this.initTrack();
-			}
+			this._initTrack();
 		},
 		_trackMove: function(){
 			// let's update the selector
-			this._updateIndicator(this.pageCoord);            
+			this._updateIndicator(this.pageCoord);
 			// if we reached that point once, then we don't stop until mouse up
-			if(this._initTrackPhase){
-				this._initTrackPhase = false;
-				this._tracker = setInterval(lang.hitch(this, this._trackMove), 100);
-			}
+ 			// use a recursive setTimeout to avoid intervals that might get backed up
+			this._tracker = setTimeout(lang.hitch(this, this._trackMove), 100);
 		},
-		initTrack: function(){
-			this._initTrackPhase = true;
-			this._tracker = setTimeout(lang.hitch(this, this._trackMove), 500);
+		_initTrack: function(){
+			if(!this._tracker){
+				this._tracker = setTimeout(lang.hitch(this, this._trackMove), 500);
+			}
 		},
 		stopTrack: function(){
 			if(this._tracker){
-				if(this._initTrackPhase){
-					clearTimeout(this._tracker);					
-				}else{
-					clearInterval(this._tracker);
-				}
+				clearTimeout(this._tracker);
 				this._tracker = null;
 			}
 		},
@@ -111,35 +53,100 @@ define(["dojo/_base/lang", "dojo/_base/declare", "../Element", "../plot2d/common
 				return;
 			}
 
-			this.cleanGroup();
+			var inter = this.inter, plot = inter.plot, v = inter.opt.vertical;
 
-			if (!this.pageCoord){
+			this.opt.offset = inter.opt.offset || (v?{ x:0 , y: 5}: { x: 5, y: 0});
+
+			if(inter.opt.labelFunc){
+				// adapt to indicator labelFunc format
+				this.opt.labelFunc = function(index, values, data, fixed, precision){
+					var coords = getXYCoordinates(v, values, data);
+					return inter.opt.labelFunc(coords[0], coords[1], fixed, precision);
+				};
+			}
+			if(inter.opt.fillFunc){
+				// adapt to indicator fillFunc format
+				this.opt.fillFunc = function(index, values, data){
+					var coords = getXYCoordinates(v, values, data);
+					return inter.opt.fillFunc(coords[0], coords[1]);
+				};
+			}
+
+			this.opt = lang.delegate(inter.opt, this.opt);
+
+			if(!this.pageCoord){
+				this.opt.values = null;
+				this.inter.onChange({});
+			}else{
+				// let's create a fake coordinate to not block parent render method
+				// actual coordinate will be computed in _updateCoordinates
+				this.opt.values = [];
+				this.opt.labels = this.secondCoord?"trend":"markers";
+			}
+
+			// take axis on the interactor plot and forward them onto the indicator plot
+			this.hAxis = plot.hAxis;
+			this.vAxis = plot.vAxis;
+
+			this.inherited(arguments);
+		},
+		_updateIndicator: function(){
+			var coordinates = this._updateCoordinates(this.pageCoord, this.secondCoord);
+			if(coordinates.length > 1){
+				var v = this.opt.vertical;
+				this._data= [];
+				this.opt.values = [];
+				array.forEach(coordinates, function(value){
+					if(value){
+						this.opt.values.push(v?value.x:value.y);
+						this._data.push([v?value.y:value.x]);
+					}
+				}, this);
+			}else{
+				this.inter.onChange({});
 				return;
 			}
-			
-			this._updateIndicator(this.pageCoord, this.secondCoord);
+			this.inherited(arguments);
 		},
-		_updateIndicator: function(cp1, cp2){
+		_renderText: function(g, text, t, x, y, index, values, data){
+			// render only if labels is true
+			if(this.inter.opt.labels){
+				this.inherited(arguments);
+			}
+			// send the event in all cases
+			var coords = getXYCoordinates(this.opt.vertical, values, data);
+			this.inter.onChange({
+				start: coords[0],
+				end: coords[1],
+				label: text
+			});
+		},
+		_updateCoordinates: function(cp1, cp2){
+			// chart mirroring starts
+			if(has("dojo-bidi")){
+				this._checkXCoords(cp1, cp2);
+			}
+			// chart mirroring ends
 			var inter = this.inter, plot = inter.plot, v = inter.opt.vertical;
 			var hAxis = this.chart.getAxis(plot.hAxis), vAxis = this.chart.getAxis(plot.vAxis);
 			var hn = hAxis.name, vn = vAxis.name, hb = hAxis.getScaler().bounds, vb = vAxis.getScaler().bounds;
 			var attr = v?"x":"y", n = v?hn:vn, bounds = v?hb:vb;
-			
+
 			// sort data point
 			if(cp2){
 				var tmp;
 				if(v){
-					if(cp1.x>cp2.x){
+					if(cp1.x > cp2.x){
 						tmp = cp2;
 						cp2 = cp1;
 						cp1 = tmp;
 					}
 				}else{
-					if(cp1.y>cp2.y){
+					if(cp1.y > cp2.y){
 						tmp = cp2;
 						cp2 = cp1;
 						cp1 = tmp;
-					}		
+					}
 				}
 			}
 
@@ -147,7 +154,7 @@ define(["dojo/_base/lang", "dojo/_base/declare", "../Element", "../plot2d/common
 			if(cp2){
 				cd2 = plot.toData(cp2);
 			}
-			
+
 			var o = {};
 			o[hn] = hb.from;
 			o[vn] = vb.from;
@@ -155,33 +162,39 @@ define(["dojo/_base/lang", "dojo/_base/declare", "../Element", "../plot2d/common
 			o[hn] = hb.to;
 			o[vn] = vb.to;
 			var max = plot.toPage(o);
-			
+
 			if(cd1[n] < bounds.from){
 				// do not autoscroll if dual indicator
-				if(!cd2 && inter.opt.autoScroll){
+				if(!cd2 && inter.opt.autoScroll && !inter.opt.mouseOver){
 					this._updateVisibility(cp1, min, attr);
-					return;
+					return [];
 				}else{
+					if(inter.opt.mouseOver){
+						return[];
+					}
 					cp1[attr] = min[attr];
 				}
 				// cp1 might have changed, let's update cd1
 				cd1 = plot.toData(cp1);
 			}else if(cd1[n] > bounds.to){
-				if(!cd2 && inter.opt.autoScroll){
+				if(!cd2 && inter.opt.autoScroll && !inter.opt.mouseOver){
 					this._updateVisibility(cp1, max, attr);
-					return;
+					return [];
 				}else{
+					if(inter.opt.mouseOver){
+						return[];
+					}
 					cp1[attr] = max[attr];
 				}
 				// cp1 might have changed, let's update cd1
 				cd1 = plot.toData(cp1);
-			}	
-			
-			var c1 = this._getData(cd1, attr, v), c2;
+			}
+
+			var c1 = this._snapData(cd1, attr, v), c2;
 
 			if(c1.y == null){
 				// we have no data for that point let's just return
-				return;
+				return [];
 			}
 
 			if(cp2){
@@ -190,106 +203,24 @@ define(["dojo/_base/lang", "dojo/_base/declare", "../Element", "../plot2d/common
 					cd2 = plot.toData(cp2);
 				}else if(cd2[n] > bounds.to){
 					cp2[attr] = max[attr];
-					cd2 = plot.toData(cp2);	
+					cd2 = plot.toData(cp2);
 				}
-				c2 = this._getData(cd2, attr, v);
+				c2 = this._snapData(cd2, attr, v);
 				if(c2.y == null){
 					// we have no data for that point let's pretend we have a single touch point
-					cp2 = null;
+					c2 = null;
 				}
 			}
-			
-			var t1 = this._renderIndicator(c1, cp2?1:0, hn, vn, min, max);
-			if(cp2){
-				var t2 = this._renderIndicator(c2, 2, hn, vn, min, max);
-				var delta = v?c2.y-c1.y:c2.x-c1.y;
-				var text = inter.opt.labelFunc?inter.opt.labelFunc(c1, c2, inter.opt.fixed, inter.opt.precision):
-					(dcpc.getLabel(delta, inter.opt.fixed, inter.opt.precision)+" ("+dcpc.getLabel(100*delta/(v?c1.y:c1.x), true, 2)+"%)");
-				this._renderText(text, inter, this.chart.theme, v?(t1.x+t2.x)/2:t1.x, v?t1.y:(t1.y+t2.y)/2, c1, c2);
-			};
-			
-		},
-		_renderIndicator: function(coord, index, hn, vn, min, max){
-			var t = this.chart.theme, c = this.chart.getCoords(), inter = this.inter, plot = inter.plot, v = inter.opt.vertical;
-			
-			var mark = {};
-			mark[hn] = coord.x;
-			mark[vn] = coord.y;
-			mark = plot.toPage(mark);
-
-			var cx = mark.x - c.x, cy = mark.y - c.y;
-			var x1 = v?cx:min.x - c.x, y1 = v?min.y - c.y:cy, x2 = v?x1:max.x - c.x, y2 = v?max.y - c.y:y1;
-			var sh = inter.opt.lineShadow?inter.opt.lineShadow:t.indicator.lineShadow,
-					ls = inter.opt.lineStroke?inter.opt.lineStroke:t.indicator.lineStroke,
-							ol = inter.opt.lineOutline?inter.opt.lineOutline:t.indicator.lineOutline;
-			if(sh){
-				this.group.createLine({x1: x1 + sh.dx, y1: y1 + sh.dy, x2: x2 + sh.dx, y2: y2 + sh.dy}).setStroke(sh);
-			}
-			if(ol){
-				ol = dcpc.makeStroke(ol);
-				ol.width = 2 * ol.width + ls.width;
-				this.group.createLine({x1: x1, y1: y1, x2: x2, y2: y2}).setStroke(ol);
-			}
-			this.group.createLine({x1: x1, y1: y1, x2: x2, y2: y2}).setStroke(ls);
 
-			var ms = inter.opt.markerSymbol?inter.opt.markerSymbol:t.indicator.markerSymbol,
-					path = "M" + cx + " " + cy + " " + ms;
-			sh = inter.opt.markerShadow?inter.opt.markerShadow:t.indicator.markerShadow;
-			ls = inter.opt.markerStroke?inter.opt.markerStroke:t.indicator.markerStroke;
-			ol = inter.opt.markerOutline?inter.opt.markerOutline:t.indicator.markerOutline;
-			if(sh){
-				var sp = "M" + (cx + sh.dx) + " " + (cy + sh.dy) + " " + ms;
-				this.group.createPath(sp).setFill(sh.color).setStroke(sh);
-			}
-			if(ol){
-				ol = dcpc.makeStroke(ol);
-				ol.width = 2 * ol.width + ls.width;
-				this.group.createPath(path).setStroke(ol);
-			}
-
-			var shape = this.group.createPath(path);
-			var sf = this._shapeFill(inter.opt.markerFill?inter.opt.markerFill:t.indicator.markerFill, shape.getBoundingBox());
-			shape.setFill(sf).setStroke(ls);
-
-			if(index==0){
-				var text = inter.opt.labelFunc?inter.opt.labelFunc(coord, null, inter.opt.fixed, inter.opt.precision):
-					dcpc.getLabel(v?coord.y:coord.x, inter.opt.fixed, inter.opt.precision);
-				this._renderText(text, inter, t, v?x1:x2+5, v?y2+5:y1, coord);
-			}else{
-				return v?{x: x1, y: y2+5}:{x: x2+5, y: y1};
-			}
-			
-		},
-		_renderText: function(text, inter, t, x, y, c1, c2){
-			var label = dcac.createText.gfx(
-					this.chart,
-					this.group,
-					x, y,
-					"middle",
-					text, inter.opt.font?inter.opt.font:t.indicator.font, inter.opt.fontColor?inter.opt.fontColor:t.indicator.fontColor);
-			var b = getBoundingBox(label);
-			b.x-=2; b.y-=1; b.width+=4; b.height+=2; b.r = inter.opt.radius?inter.opt.radius:t.indicator.radius;
-			sh = inter.opt.shadow?inter.opt.shadow:t.indicator.shadow;
-			ls = inter.opt.stroke?inter.opt.stroke:t.indicator.stroke;
-			ol = inter.opt.outline?inter.opt.outline:t.indicator.outline;
-			if(sh){
-				this.group.createRect(b).setFill(sh.color).setStroke(sh);
-			}
-			if(ol){
-				ol = dcpc.makeStroke(ol);
-				ol.width = 2 * ol.width + ls.width;
-				this.group.createRect(b).setStroke(ol);
-			}
-			var f = inter.opt.fillFunc?inter.opt.fillFunc(c1, c2):(inter.opt.fill?inter.opt.fill:t.indicator.fill);
-			this.group.createRect(b).setFill(this._shapeFill(f, b)).setStroke(ls);
-			label.moveToFront();
+			return [c1, c2];
 		},
-		_getData: function(cd, attr, v){
+		_snapData: function(cd, attr, v){
 			// we need to find which actual data point is "close" to the data value
 			var data = this.chart.getSeries(this.inter.opt.series).data;
 			// let's consider data are sorted because anyway rendering will be "weird" with unsorted data
 			// i is an index in the array, which is different from a x-axis value even for index based data
 			var i, r, l = data.length;
+			// first let's find which data index we are in
 			for (i = 0; i < l; ++i){
 				r = data[i];
 				if(r == null){
@@ -302,23 +233,23 @@ define(["dojo/_base/lang", "dojo/_base/declare", "../Element", "../plot2d/common
 					break;
 				}
 			}
-			var x,y,px,py;
+			var x, y, px, py;
 			if(typeof r == "number"){
 				x = i+1;
 				y = r;
-				if(i>0){
+				if(i > 0){
 					px = i;
 					py = data[i-1];
 				}
 			}else{
 				x = r.x;
 				y = r.y;
-				if(i>0){
+				if(i > 0){
 					px = data[i-1].x;
 					py = data[i-1].y;
 				}
 			}
-			if(i>0){
+			if(i > 0){
 				var m = v?(x+px)/2:(y+py)/2;
 				if(cd[attr]<=m){
 					x = px;
@@ -328,43 +259,38 @@ define(["dojo/_base/lang", "dojo/_base/declare", "../Element", "../plot2d/common
 			return {x: x, y: y};
 		},
 		cleanGroup: function(creator){
-			//	summary:
+			// summary:
 			//		Clean any elements (HTML or GFX-based) out of our group, and create a new one.
-			//	creator: dojox.gfx.Surface?
+			// creator: dojox/gfx/Surface?
 			//		An optional surface to work with.
-			//	returns: dojox.charting.Element
+			// returns: dojox/charting/Element
 			//		A reference to this object for functional chaining.
 			this.inherited(arguments);
 			// we always want to be above regular plots and not clipped
 			this.group.moveToFront();
-			return this;	//	dojox.charting.Element
-		},
-		clear: function(){
-			//	summary:
-			//		Clear out any parameters set on this plot.
-			//	returns: dojox.charting.action2d._IndicatorElement
-			//		The reference to this plot for functional chaining.
-			this.dirty = true;
-			return this;	//	dojox.charting.plot2d._IndicatorElement
-		},
-		getSeriesStats: function(){
-			//	summary:
-			//		Returns default stats (irrelevant for this type of plot).
-			//	returns: Object
-			//		{hmin, hmax, vmin, vmax} min/max in both directions.
-			return lang.delegate(dcpc.defaultStats);
-		},
-		initializeScalers: function(){
-			//	summary:
-			//		Does nothing (irrelevant for this type of plot).
-			return this;
+			return this;	//	dojox/charting/Element
 		},
 		isDirty: function(){
-			//	summary:
+			// summary:
 			//		Return whether or not this plot needs to be redrawn.
-			//	returns: Boolean
+			// returns: Boolean
 			//		If this plot needs to be rendered, this will return true.
 			return !this._noDirty && (this.dirty || this.inter.plot.isDirty());
 		}
 	});
+	if(has("dojo-bidi")){
+		_IndicatorElement.extend({
+			_checkXCoords: function(cp1, cp2){
+				if(this.chart.isRightToLeft()){
+					if(cp1){
+						cp1.x = this.chart.dim.width + (this.chart.offsets.l - this.chart.offsets.r) - cp1.x;
+					}
+					if(cp2){
+						cp2.x = this.chart.dim.width + (this.chart.offsets.l - this.chart.offsets.r) - cp2.x;
+					}
+				}			
+			}			
+		});
+	}
+	return _IndicatorElement;
 });
diff --git a/dojox/charting/axis2d/Base.js b/dojox/charting/axis2d/Base.js
index 2b1c0fc..50dc461 100644
--- a/dojox/charting/axis2d/Base.js
+++ b/dojox/charting/axis2d/Base.js
@@ -1,71 +1,83 @@
-define(["dojo/_base/declare", "../Element"], 
+define(["dojo/_base/declare", "../Element"],
 	function(declare, Element){
-/*=====
-var Element = dojox.charting.Element;
-=====*/ 
-return declare("dojox.charting.axis2d.Base", Element, {
-	//	summary:
-	//		The base class for any axis.  This is more of an interface/API
-	//		definition than anything else; see dojox.charting.axis2d.Default
-	//		for more details.
-	constructor: function(chart, kwArgs){
-		//	summary:
-		//		Return a new base axis.
-		//	chart: dojox.charting.Chart
-		//		The chart this axis belongs to.
-		//	kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
-		//		An optional arguments object to define the axis parameters.
-		this.vertical = kwArgs && kwArgs.vertical;
-	},
-	clear: function(){
-		//	summary:
-		//		Stub function for clearing the axis.
-		//	returns: dojox.charting.axis2d.Base
-		//		A reference to the axis for functional chaining.
-		return this;	//	dojox.charting.axis2d.Base
-	},
-	initialized: function(){
-		//	summary:
-		//		Return a flag as to whether or not this axis has been initialized.
-		//	returns: Boolean
-		//		If the axis is initialized or not.
-		return false;	//	Boolean
-	},
-	calculate: function(min, max, span){
-		//	summary:
-		//		Stub function to run the calcuations needed for drawing this axis.
-		//	returns: dojox.charting.axis2d.Base
-		//		A reference to the axis for functional chaining.
-		return this;	//	dojox.charting.axis2d.Base
-	},
-	getScaler: function(){
-		//	summary:
-		//		A stub function to return the scaler object created during calculate.
-		//	returns: Object
-		//		The scaler object (see dojox.charting.scaler.linear for more information)
-		return null;	//	Object
-	},
-	getTicks: function(){
-		//	summary:
-		//		A stub function to return the object that helps define how ticks are rendered.
-		//	returns: Object
-		//		The ticks object.
-		return null;	//	Object
-	},
-	getOffsets: function(){
-		//	summary:
-		//		A stub function to return any offsets needed for axis and series rendering.
-		//	returns: Object
-		//		An object of the form { l, r, t, b }.
-		return {l: 0, r: 0, t: 0, b: 0};	//	Object
-	},
-	render: function(dim, offsets){
-		//	summary:
-		//		Stub function to render this axis.
-		//	returns: dojox.charting.axis2d.Base
-		//		A reference to the axis for functional chaining.
-		this.dirty = false;
-		return this;	//	dojox.charting.axis2d.Base
-	}
-});
+	/*=====
+	var __BaseAxisCtorArgs = {
+		// summary:
+		//		Optional arguments used in the definition of an invisible axis.
+		// vertical: Boolean?
+		//		A flag that says whether an axis is vertical (i.e. y axis) or horizontal. Default is false (horizontal).
+		// min: Number?
+		//		The smallest value on an axis. Default is 0.
+		// max: Number?
+		//		The largest value on an axis. Default is 1.
+	};
+	=====*/
+	return declare("dojox.charting.axis2d.Base", Element, {
+		// summary:
+		//		The base class for any axis.  This is more of an interface/API
+		//		definition than anything else; see dojox.charting.axis2d.Default
+		//		for more details.
+		constructor: function(chart, kwArgs){
+			// summary:
+			//		Return a new base axis.
+			// chart: dojox/charting/Chart
+			//		The chart this axis belongs to.
+			// kwArgs: __BaseAxisCtorArgs?
+			//		An optional arguments object to define the axis parameters.
+			this.vertical = kwArgs && kwArgs.vertical;
+			this.opt = {};
+			this.opt.min = kwArgs && kwArgs.min;
+			this.opt.max = kwArgs && kwArgs.max;
+		},
+		clear: function(){
+			// summary:
+			//		Stub function for clearing the axis.
+			// returns: dojox/charting/axis2d/Base
+			//		A reference to the axis for functional chaining.
+			return this;	//	dojox/charting/axis2d/Base
+		},
+		initialized: function(){
+			// summary:
+			//		Return a flag as to whether or not this axis has been initialized.
+			// returns: Boolean
+			//		If the axis is initialized or not.
+			return false;	//	Boolean
+		},
+		calculate: function(min, max, span){
+			// summary:
+			//		Stub function to run the calcuations needed for drawing this axis.
+			// returns: dojox/charting/axis2d/Base
+			//		A reference to the axis for functional chaining.
+			return this;	//	dojox/charting/axis2d/Base
+		},
+		getScaler: function(){
+			// summary:
+			//		A stub function to return the scaler object created during calculate.
+			// returns: Object
+			//		The scaler object (see dojox.charting.scaler.linear for more information)
+			return null;	//	Object
+		},
+		getTicks: function(){
+			// summary:
+			//		A stub function to return the object that helps define how ticks are rendered.
+			// returns: Object
+			//		The ticks object.
+			return null;	//	Object
+		},
+		getOffsets: function(){
+			// summary:
+			//		A stub function to return any offsets needed for axis and series rendering.
+			// returns: Object
+			//		An object of the form { l, r, t, b }.
+			return {l: 0, r: 0, t: 0, b: 0};	//	Object
+		},
+		render: function(dim, offsets){
+			// summary:
+			//		Stub function to render this axis.
+			// returns: dojox/charting/axis2d/Base
+			//		A reference to the axis for functional chaining.
+			this.dirty = false;
+			return this;	//	dojox/charting/axis2d/Base
+		}
+	});
 });
diff --git a/dojox/charting/axis2d/Default.js b/dojox/charting/axis2d/Default.js
index dfef5cd..a6c163f 100644
--- a/dojox/charting/axis2d/Default.js
+++ b/dojox/charting/axis2d/Default.js
@@ -1,170 +1,155 @@
-define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/declare", 
-	"dojo/_base/connect", "dojo/_base/html", "dojo/dom-geometry", "./Invisible", 
-	"../scaler/common", "../scaler/linear", "./common", "dojox/gfx", "dojox/lang/utils"], 
-	function(lang, arr, has, declare, connect, html, domGeom, Invisible, scommon, 
-			lin, acommon, g, du){
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/sniff", "dojo/_base/declare",
+	"dojo/_base/connect", "dojo/dom-geometry", "./Invisible",
+	"../scaler/linear", "./common", "dojox/gfx", "dojox/lang/utils", "dojox/lang/functional",
+	"dojo/has!dojo-bidi?../bidi/axis2d/Default"],
+	function(lang, arr, has, declare, connect, domGeom, Invisible,
+			lin, acommon, g, du, df, BidiDefault){
 
 	/*=====
-		dojox.charting.axis2d.__AxisCtorArgs = function(
-			vertical, fixUpper, fixLower, natural, leftBottom,
-			includeZero, fixed, majorLabels, minorTicks, minorLabels, microTicks, htmlLabels,
-			min, max, from, to, majorTickStep, minorTickStep, microTickStep,
-			labels, labelFunc, maxLabelSize,
-			stroke, majorTick, minorTick, microTick, tick,
-			font, fontColor
-		){
-		//	summary:
+	var __AxisCtorArgs = {
+		// summary:
 		//		Optional arguments used in the definition of an axis.
-		//
-		//	vertical: Boolean?
+		// vertical: Boolean?
 		//		A flag that says whether an axis is vertical (i.e. y axis) or horizontal. Default is false (horizontal).
-		//	fixUpper: String?
+		// fixUpper: String?
 		//		Align the greatest value on the axis with the specified tick level. Options are "major", "minor", "micro", or "none".  Defaults to "none".
-		//	fixLower: String?
+		// fixLower: String?
 		//		Align the smallest value on the axis with the specified tick level. Options are "major", "minor", "micro", or "none".  Defaults to "none".
-		//	natural: Boolean?
+		// natural: Boolean?
 		//		Ensure tick marks are made on "natural" numbers. Defaults to false.
-		//	leftBottom: Boolean?
+		// leftBottom: Boolean?
 		//		The position of a vertical axis; if true, will be placed against the left-bottom corner of the chart.  Defaults to true.
-		//	includeZero: Boolean?
+		// includeZero: Boolean?
 		//		Include 0 on the axis rendering.  Default is false.
-		//	fixed: Boolean?
+		// fixed: Boolean?
 		//		Force all axis labels to be fixed numbers.  Default is true.
-		//	majorLabels: Boolean?
-		//		Flag to draw all labels at major ticks. Default is true.
-		//	minorTicks: Boolean?
+		// majorLabels: Boolean?
+		//		Flag to draw labels at major ticks. Default is true.
+		// minorTicks: Boolean?
 		//		Flag to draw minor ticks on an axis.  Default is true.
-		//	minorLabels: Boolean?
-		//		Flag to draw labels on minor ticks. Default is true.
-		//	microTicks: Boolean?
+		// minorLabels: Boolean?
+		//		Flag to labels on minor ticks when there is enough space. Default is true.
+		// microTicks: Boolean?
 		//		Flag to draw micro ticks on an axis. Default is false.
-		//	htmlLabels: Boolean?
+		// htmlLabels: Boolean?
 		//		Flag to use HTML (as opposed to the native vector graphics engine) to draw labels. Default is true.
-		//	min: Number?
+		// min: Number?
 		//		The smallest value on an axis. Default is 0.
-		//	max: Number?
+		// max: Number?
 		//		The largest value on an axis. Default is 1.
-		//	from: Number?
+		// from: Number?
 		//		Force the chart to render data visible from this value. Default is 0.
-		//	to: Number?
+		// to: Number?
 		//		Force the chart to render data visible to this value. Default is 1.
-		//	majorTickStep: Number?
-		//		The amount to skip before a major tick is drawn.  Default is 4.
-		//	minorTickStep: Number?
-		//		The amount to skip before a minor tick is drawn. Default is 2.
-		//	microTickStep: Number?
-		//		The amount to skip before a micro tick is drawn. Default is 1.
-		//	labels: Object[]?
+		// majorTickStep: Number?
+		//		The amount to skip before a major tick is drawn. When not set the major ticks step is computed from
+		//		the data range.
+		// minorTickStep: Number?
+		//		The amount to skip before a minor tick is drawn. When not set the minor ticks step is computed from
+		//		the data range.
+		// microTickStep: Number?
+		//		The amount to skip before a micro tick is drawn. When not set the micro ticks step is computed from
+		// labels: Object[]?
 		//		An array of labels for major ticks, with corresponding numeric values, ordered by value.
-		//	labelFunc: Function?
-		//		An optional function used to compute label values.
-		//	maxLabelSize: Number?
+		// labelFunc: Function?
+		//		An optional function to use to compute label text. It takes precedence over
+		//		the default text when available. The function must be of the following form:
+		//	|		function labelFunc(text, value, precision) {}
+		//		`text` is the already pre-formatted text. Pre-formatting is done using `dojo/number` is available, `Date.toFixed` otherwise.
+		//		`value`  is the raw axis value.
+		//		`precision` is the requested precision to be applied.
+		// maxLabelSize: Number?
 		//		The maximum size, in pixels, for a label.  To be used with the optional label function.
-		//	stroke: dojox.gfx.Stroke?
+		// stroke: dojox.gfx.Stroke?
 		//		An optional stroke to be used for drawing an axis.
-		//	majorTick: Object?
+		// majorTick: Object?
 		//		An object containing a dojox.gfx.Stroke, and a length (number) for a major tick.
-		//	minorTick: Object?
+		// minorTick: Object?
 		//		An object containing a dojox.gfx.Stroke, and a length (number) for a minor tick.
-		//	microTick: Object?
+		// microTick: Object?
 		//		An object containing a dojox.gfx.Stroke, and a length (number) for a micro tick.
-		//	tick: Object?
+		// tick: Object?
 		//		An object containing a dojox.gfx.Stroke, and a length (number) for a tick.
-		//	font: String?
+		// font: String?
 		//		An optional font definition (as used in the CSS font property) for labels.
-		//	fontColor: String|dojo.Color?
+		// fontColor: String|dojo.Color?
 		//		An optional color to be used in drawing labels.
-		//	enableCache: Boolean?
+		// titleGap: Number?
+		//		An optional grap between axis title and axis label
+		// titleFont: String?
+		//		An optional font definition for axis title
+		// titleFontColor: String?
+		//		An optional axis title color
+		// titleOrientation: String?
+		//		An optional orientation for axis title. "axis" means the title facing the axis, "away" means facing away.
+		//		If no value is set "axis" is used.
+		// enableCache: Boolean?
 		//		Whether the ticks and labels are cached from one rendering to another. This improves the rendering performance of
 		//		successive rendering but penalize the first rendering. For labels it is only working with gfx labels
 		//		not html ones.  Default false.
-	
-		this.vertical = vertical;
-		this.fixUpper = fixUpper;
-		this.fixLower = fixLower;
-		this.natural = natural;
-		this.leftBottom = leftBottom;
-		this.includeZero = includeZero;
-		this.fixed = fixed;
-		this.majorLabels = majorLabels;
-		this.minorTicks = minorTicks;
-		this.minorLabels = minorLabels;
-		this.microTicks = microTicks;
-		this.htmlLabels = htmlLabels;
-		this.min = min;
-		this.max = max;
-		this.from = from;
-		this.to = to;
-		this.majorTickStep = majorTickStep;
-		this.minorTickStep = minorTickStep;
-		this.microTickStep = microTickStep;
-		this.labels = labels;
-		this.labelFunc = labelFunc;
-		this.maxLabelSize = maxLabelSize;
-		this.stroke = stroke;
-		this.majorTick = majorTick;
-		this.minorTick = minorTick;
-		this.microTick = microTick;
-		this.tick = tick;
-		this.font = font;
-		this.fontColor = fontColor;
-		this.enableCache = enableCache;
-	}
-	var Invisible = dojox.charting.axis2d.Invisible
+		// dropLabels: Boolean?
+		//		Whether the axis automatically drops labels at regular interval or not to avoid labels overlapping.
+		//		This gives better results but require more computations.  You can disable it to save computation
+		//		time when you know your labels won't overlap. Default is true.
+		// labelSizeChange: Boolean?
+		//		Indicates to the axis whether the axis labels are changing their size on zoom. If false this allows to
+		//		optimize the axis by avoiding recomputing labels maximum size on zoom actions. Default is false.
+	};
 	=====*/
 
-	var labelGap = 4,			// in pixels
-		centerAnchorLimit = 45;	// in degrees
+	var centerAnchorLimit = 45;	// in degrees
 
-	return declare("dojox.charting.axis2d.Default", Invisible, {
-		//	summary:
+	var Default = declare(has("dojo-bidi")? "dojox.charting.axis2d.NonBidiDefault" : "dojox.charting.axis2d.Default", Invisible, {
+		// summary:
 		//		The default axis object used in dojox.charting.  See dojox.charting.Chart.addAxis for details.
-		//
-		//	defaultParams: Object
+
+		// defaultParams: Object
 		//		The default parameters used to define any axis.
-		//	optionalParams: Object
+		// optionalParams: Object
 		//		Any optional parameters needed to define an axis.
 
-		/*
-		//	TODO: the documentation tools need these to be pre-defined in order to pick them up
+		/*=====
+		// TODO: the documentation tools need these to be pre-defined in order to pick them up
 		//	correctly, but the code here is partially predicated on whether or not the properties
 		//	actually exist.  For now, we will leave these undocumented but in the code for later. -- TRT
 
-		//	opt: Object
+		// opt: Object
 		//		The actual options used to define this axis, created at initialization.
-		//	scalar: Object
+		// scaler: Object
 		//		The calculated helper object to tell charts how to draw an axis and any data.
-		//	ticks: Object
+		// ticks: Object
 		//		The calculated tick object that helps a chart draw the scaling on an axis.
-		//	dirty: Boolean
+		// dirty: Boolean
 		//		The state of the axis (whether it needs to be redrawn or not)
-		//	scale: Number
+		// scale: Number
 		//		The current scale of the axis.
-		//	offset: Number
+		// offset: Number
 		//		The current offset of the axis.
 
 		opt: null,
-		scalar: null,
+		scaler: null,
 		ticks: null,
 		dirty: true,
 		scale: 1,
 		offset: 0,
-		*/
+		=====*/
 		defaultParams: {
-			vertical:    false,		// true for vertical axis
-			fixUpper:    "none",	// align the upper on ticks: "major", "minor", "micro", "none"
-			fixLower:    "none",	// align the lower on ticks: "major", "minor", "micro", "none"
-			natural:     false,		// all tick marks should be made on natural numbers
+			vertical:	false,		// true for vertical axis
+			fixUpper:	"none",	// align the upper on ticks: "major", "minor", "micro", "none"
+			fixLower:	"none",	// align the lower on ticks: "major", "minor", "micro", "none"
+			natural:	 false,		// all tick marks should be made on natural numbers
 			leftBottom:  true,		// position of the axis, used with "vertical"
 			includeZero: false,		// 0 should be included
-			fixed:       true,		// all labels are fixed numbers
+			fixed:	   true,		// all labels are fixed numbers
 			majorLabels: true,		// draw major labels
 			minorTicks:  true,		// draw minor ticks
 			minorLabels: true,		// draw minor labels
 			microTicks:  false,		// draw micro ticks
-			rotation:    0,			// label rotation angle in degrees
+			rotation:	0,			// label rotation angle in degrees
 			htmlLabels:  true,		// use HTML to draw labels
-			enableCache: false		// whether we cache or not
+			enableCache: false,		// whether we cache or not
+			dropLabels: true,		// whether we automatically drop overlapping labels or not
+			labelSizeChange: false // whether the labels size change on zoom
 		},
 		optionalParams: {
 			min:			0,	// minimal value on this axis
@@ -175,8 +160,8 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 			minorTickStep:	2,	// minor tick step
 			microTickStep:	1,	// micro tick step
 			labels:			[],	// array of labels for major ticks
-								// with corresponding numeric values
-								// ordered by values
+			// with corresponding numeric values
+			// ordered by values
 			labelFunc:		null, // function to compute label values
 			maxLabelSize:	0,	// size in px. For use with labelFunc
 			maxLabelCharCount:	0,	// size in word count.
@@ -190,25 +175,25 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 			majorTick:		{},	// stroke + length for a tick
 			minorTick:		{},	// stroke + length for a tick
 			microTick:		{},	// stroke + length for a tick
-			tick:           {},	// stroke + length for a tick
+			tick:		   {},	// stroke + length for a tick
 			font:			"",	// font for labels
 			fontColor:		"",	// color for labels as a string
-			title:		 		"",	// axis title
-			titleGap:	 		0,		// gap between axis title and axis label
-			titleFont:	 		"",		// axis title font
-			titleFontColor:	 	"",		// axis title font color
-			titleOrientation: 	""		// "axis" means the title facing the axis, "away" means facing away
+			title:				 "",	// axis title
+			titleGap:			 0,		// gap between axis title and axis label
+			titleFont:			 "",		// axis title font
+			titleFontColor:		 "",		// axis title font color
+			titleOrientation:	 ""		// "axis" means the title facing the axis, "away" means facing away
 		},
 
 		constructor: function(chart, kwArgs){
-			//	summary:
+			// summary:
 			//		The constructor for an axis.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart the axis belongs to.
-			//	kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
+			// kwArgs: __AxisCtorArgs?
 			//		Any optional keyword arguments to be used to define this axis.
 			this.opt = lang.clone(this.defaultParams);
-            du.updateWithObject(this.opt, kwArgs);
+			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			if(this.opt.enableCache){
 				this._textFreePool = [];
@@ -216,51 +201,216 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 				this._textUsePool = [];
 				this._lineUsePool = [];
 			}
+			this._invalidMaxLabelSize = true;
+		},
+		setWindow: function(scale, offset){
+			// summary:
+			//		Set the drawing "window" for the axis.
+			// scale: Number
+			//		The new scale for the axis.
+			// offset: Number
+			//		The new offset for the axis.
+			// returns: dojox/charting/axis2d/Default
+			//		The reference to the axis for functional chaining.
+			if(scale != this.scale){
+				// if scale changed we need to recompute new max label size
+				this._invalidMaxLabelSize = true;
+			}
+			return this.inherited(arguments);
+		},
+
+		_groupLabelWidth: function(labels, font, wcLimit){
+			if(!labels.length){
+				return 0;
+			}
+			if(labels.length > 50){
+				// let's avoid degenerated cases
+				labels.length = 50;
+			}
+			if(lang.isObject(labels[0])){
+				labels = df.map(labels, function(label){ return label.text; });
+			}
+			if(wcLimit){
+				labels = df.map(labels, function(label){
+					return lang.trim(label).length == 0 ? "" : label.substring(0, wcLimit) + this.trailingSymbol;
+				}, this);
+			}
+			var s = labels.join("<br>");
+			return g._base._getTextBox(s, {font: font}).w || 0;
+		},
+
+		_getMaxLabelSize: function(min, max, span, rotation, font, size){
+			if(this._maxLabelSize == null && arguments.length == 6){
+				var o = this.opt;
+				// everything might have changed, reset the minMinorStep value
+				this.scaler.minMinorStep = this._prevMinMinorStep = 0;
+				var ob = lang.clone(o);
+				delete ob.to;
+				delete ob.from;
+				// build all the ticks from min, to max not from to to _but_ using the step
+				// that would be used if we where just displaying from to to from.
+				var sb = lin.buildScaler(min, max, span, ob, o.to - o.from);
+				sb.minMinorStep = 0;
+				this._majorStart = sb.major.start;
+				// we build all the ticks not only the ones we need to draw in order to get
+				// a correct drop rate computation that works for any offset of this scale
+				var tb = lin.buildTicks(sb, o);
+				// if there is not tick at all tb is null
+				if(size && tb){
+					var majLabelW = 0, minLabelW = 0; // non rotated versions
+					// we first collect all labels when needed
+					var tickLabelFunc = function(tick){
+						if(tick.label){
+							this.push(tick.label);
+						}
+					};
+					var labels = [];
+					if(this.opt.majorLabels){
+						arr.forEach(tb.major, tickLabelFunc, labels);
+						majLabelW = this._groupLabelWidth(labels, font, ob.maxLabelCharCount);
+						if(ob.maxLabelSize){
+							majLabelW = Math.min(ob.maxLabelSize, majLabelW);
+						}
+					}
+					// do the minor labels computation only if dropLabels is set
+					labels = [];
+					if(this.opt.dropLabels && this.opt.minorLabels){
+						arr.forEach(tb.minor, tickLabelFunc, labels);
+						minLabelW = this._groupLabelWidth(labels, font, ob.maxLabelCharCount);
+						if(ob.maxLabelSize){
+							minLabelW = Math.min(ob.maxLabelSize, minLabelW);
+						}
+					}
+					this._maxLabelSize = {
+						majLabelW: majLabelW, minLabelW: minLabelW,
+						majLabelH: size, minLabelH: size
+					};
+				}else{
+					this._maxLabelSize = null;
+				}
+			}
+			return this._maxLabelSize;
+		},
+
+		calculate: function(min, max, span){
+			this.inherited(arguments);
+			// when the scale has not changed there is no reason for minMinorStep to change
+			this.scaler.minMinorStep = this._prevMinMinorStep;
+			// we want to recompute the dropping mechanism only when the scale or the size of the axis is changing
+			// not when for example when we scroll (otherwise effect would be weird)
+			if((this._invalidMaxLabelSize || span != this._oldSpan) && (min != Infinity && max != -Infinity)){
+				this._invalidMaxLabelSize = false;
+				if(this.opt.labelSizeChange){
+					this._maxLabelSize = null;
+				}
+				this._oldSpan = span;
+				var o = this.opt;
+				var ta = this.chart.theme.axis, rotation = o.rotation % 360,
+					labelGap = this.chart.theme.axis.tick.labelGap,
+					// TODO: we use one font --- of major tick, we need to use major and minor fonts
+					font = o.font || (ta.majorTick && ta.majorTick.font) || (ta.tick && ta.tick.font),
+					size = font ? g.normalizedLength(g.splitFontString(font).size) : 0,
+					// even if we don't drop label we need to compute max size for offsets
+					labelW = this._getMaxLabelSize(min, max, span, rotation, font, size);
+				if(typeof labelGap != "number"){
+					labelGap = 4; // in pixels
+				}
+				if(labelW && o.dropLabels){
+					var cosr = Math.abs(Math.cos(rotation * Math.PI / 180)),
+						sinr = Math.abs(Math.sin(rotation * Math.PI / 180));
+					var majLabelW, minLabelW;
+					if(rotation < 0){
+						rotation += 360;
+					}
+					switch(rotation){
+						case 0:
+						case 180:
+							// trivial cases: horizontal labels
+							if(this.vertical){
+								majLabelW = minLabelW = size;
+							}else{
+								majLabelW = labelW.majLabelW;
+								minLabelW = labelW.minLabelW;
+							}
+							break;
+						case 90:
+						case 270:
+							// trivial cases: vertical
+							if(this.vertical){
+								majLabelW = labelW.majLabelW;
+								minLabelW = labelW.minLabelW;
+							}else{
+								majLabelW = minLabelW = size;
+							}
+							break;
+						default:
+							// all major labels are parallel they can't collapse except if the two ticks are
+							// closer than the height of the text * cos(90-rotation)
+							majLabelW  = this.vertical ? Math.min(labelW.majLabelW, size / cosr) : Math.min(labelW.majLabelW, size / sinr);
+							// for minor labels we need to rotated them
+							var gap1 = Math.sqrt(labelW.minLabelW * labelW.minLabelW + size * size),
+								gap2 = this.vertical ? size * cosr + labelW.minLabelW * sinr : labelW.minLabelW * cosr + size * sinr;
+							minLabelW = Math.min(gap1, gap2);
+							break;
+					}
+					// we need to check both minor and major labels fit a minor step
+					this.scaler.minMinorStep = this._prevMinMinorStep =  Math.max(majLabelW, minLabelW) + labelGap;
+					var canMinorLabel = this.scaler.minMinorStep <= this.scaler.minor.tick * this.scaler.bounds.scale;
+					if(!canMinorLabel){
+						// we can't place minor labels, let's see if we can place major ones
+						// in a major step and if not which skip interval we must follow
+						this._skipInterval = Math.floor((majLabelW + labelGap) / (this.scaler.major.tick * this.scaler.bounds.scale));
+					}else{
+						// everything fit well
+						this._skipInterval = 0;
+					}
+				}else{
+					// drop label disabled
+					this._skipInterval = 0;
+				}
+			}
+			// computes the tick subset we need for that scale/offset
+			this.ticks = lin.buildTicks(this.scaler, this.opt);
+			return this;
 		},
+
 		getOffsets: function(){
-			//	summary:
-			//		Get the physical offset values for this axis (used in drawing data series).
-			//	returns: Object
+			// summary:
+			//		Get the physical offset values for this axis (used in drawing data series). This method is not
+			//		supposed to be called by the users but internally.
+			// returns: Object
 			//		The calculated offsets in the form of { l, r, t, b } (left, right, top, bottom).
 			var s = this.scaler, offsets = { l: 0, r: 0, t: 0, b: 0 };
 			if(!s){
 				return offsets;
 			}
-			var o = this.opt, labelWidth = 0, a, b, c, d,
-				gl = scommon.getNumericLabel,
-				offset = 0, ma = s.major, mi = s.minor,
+			var o = this.opt,
 				ta = this.chart.theme.axis,
+				labelGap = this.chart.theme.axis.tick.labelGap,
 				// TODO: we use one font --- of major tick, we need to use major and minor fonts
-				taFont = o.font || (ta.majorTick && ta.majorTick.font) || (ta.tick && ta.tick.font),
-				taTitleFont = o.titleFont || (ta.tick && ta.tick.titleFont),
-				taTitleGap = (o.titleGap==0) ? 0 : o.titleGap || (ta.tick && ta.tick.titleGap) || 15,
+				taTitleFont = o.titleFont || (ta.title && ta.title.font),
+				taTitleGap = (o.titleGap==0) ? 0 : o.titleGap || (ta.title && ta.title.gap),
 				taMajorTick = this.chart.theme.getTick("major", o),
 				taMinorTick = this.chart.theme.getTick("minor", o),
-				size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
 				tsize = taTitleFont ? g.normalizedLength(g.splitFontString(taTitleFont).size) : 0,
 				rotation = o.rotation % 360, leftBottom = o.leftBottom,
 				cosr = Math.abs(Math.cos(rotation * Math.PI / 180)),
 				sinr = Math.abs(Math.sin(rotation * Math.PI / 180));
-			this.trailingSymbol = (o.trailingSymbol === undefined || o.trailingSymbol === null) ? this.trailingSymbol : o.trailingSymbol;
+			this.trailingSymbol = (o.trailingSymbol === undefined || o.trailingSymbol === null) ?
+				this.trailingSymbol : o.trailingSymbol;
+			if(typeof labelGap != "number"){
+				labelGap = 4; // in pixels
+			}
 			if(rotation < 0){
 				rotation += 360;
 			}
-
-			if(size){
-				// we need width of all labels
-				if(this.labels){
-					labelWidth = this._groupLabelWidth(this.labels, taFont, o.maxLabelCharCount);
-				}else{
-					labelWidth = this._groupLabelWidth([
-						gl(ma.start, ma.prec, o),
-						gl(ma.start + ma.count * ma.tick, ma.prec, o),
-						gl(mi.start, mi.prec, o),
-						gl(mi.start + mi.count * mi.tick, mi.prec, o)
-					], taFont, o.maxLabelCharCount);
-				}
-				labelWidth = o.maxLabelSize ? Math.min(o.maxLabelSize, labelWidth) : labelWidth;
+			var maxLabelSize = this._getMaxLabelSize(); // don't need parameters, calculate has been called before => we use cached value
+			if(maxLabelSize){
+				var side;
+				var labelWidth = Math.ceil(Math.max(maxLabelSize.majLabelW, maxLabelSize.minLabelW)) + 1,
+					size = Math.ceil(Math.max(maxLabelSize.majLabelH, maxLabelSize.minLabelH)) + 1;
 				if(this.vertical){
-					var side = leftBottom ? "l" : "r";
+					side = leftBottom ? "l" : "r";
 					switch(rotation){
 						case 0:
 						case 180:
@@ -290,9 +440,10 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 							}
 							break;
 					}
-					offsets[side] += labelGap + Math.max(taMajorTick.length, taMinorTick.length) + (o.title ? (tsize + taTitleGap) : 0);
+					offsets[side] += labelGap + Math.max(taMajorTick.length > 0?taMajorTick.length:0,
+														 taMinorTick.length > 0?taMinorTick.length:0) + (o.title ? (tsize + taTitleGap) : 0);
 				}else{
-					var side = leftBottom ? "b" : "t";
+					side = leftBottom ? "b" : "t";
 					switch(rotation){
 						case 0:
 						case 180:
@@ -306,28 +457,26 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 							break;
 						default:
 							if((90 - centerAnchorLimit) <= rotation && rotation <= 90 || (270 - centerAnchorLimit) <= rotation && rotation <= 270){
-								offsets[side] = size * sinr / 2 + labelWidth * cosr;
-								offsets[leftBottom ? "r" : "l"] = size * cosr / 2 + labelWidth * sinr;
-								offsets[leftBottom ? "l" : "r"] = size * cosr / 2;
+								offsets[side] = size * cosr / 2 + labelWidth * sinr;
+								offsets[leftBottom ? "r" : "l"] = size * sinr / 2 + labelWidth * cosr;
+								offsets[leftBottom ? "l" : "r"] = size * sinr / 2;
 							}else if(90 <= rotation && rotation <= (90 + centerAnchorLimit) || 270 <= rotation && rotation <= (270 + centerAnchorLimit)){
-								offsets[side] = size * sinr / 2 + labelWidth * cosr;
-								offsets[leftBottom ? "l" : "r"] = size * cosr / 2 + labelWidth * sinr;
-								offsets[leftBottom ? "r" : "l"] = size * cosr / 2;
-							}else if(rotation < centerAnchorLimit || (180 < rotation && rotation < (180 - centerAnchorLimit))){
-								offsets[side] = size * sinr + labelWidth * cosr;
-								offsets[leftBottom ? "r" : "l"] = size * cosr + labelWidth * sinr;
+								offsets[side] = size * cosr / 2 + labelWidth * sinr;
+								offsets[leftBottom ? "l" : "r"] = size * sinr / 2 + labelWidth * cosr;
+								offsets[leftBottom ? "r" : "l"] = size * sinr / 2;
+							}else if(rotation < centerAnchorLimit || (180 < rotation && rotation < (180 + centerAnchorLimit))){
+								offsets[side] = size * cosr + labelWidth * sinr;
+								offsets[leftBottom ? "r" : "l"] = size * sinr + labelWidth * cosr;
 							}else{
-								offsets[side] = size * sinr + labelWidth * cosr;
-								offsets[leftBottom ? "l" : "r"] = size * cosr + labelWidth * sinr;
+								offsets[side] = size * cosr + labelWidth * sinr;
+								offsets[leftBottom ? "l" : "r"] = size * sinr + labelWidth * cosr;
 							}
 							break;
 					}
-					offsets[side] += labelGap + Math.max(taMajorTick.length, taMinorTick.length) + (o.title ? (tsize + taTitleGap) : 0);
+					offsets[side] += labelGap + Math.max(taMajorTick.length > 0?taMajorTick.length:0,
+														 taMinorTick.length > 0?taMinorTick.length:0) + (o.title ? (tsize + taTitleGap) : 0);
 				}
 			}
-			if(labelWidth){
-				this._cachedLabelWidth = labelWidth;
-			}
 			return offsets;	//	Object
 		},
 		cleanGroup: function(creator){
@@ -354,7 +503,7 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 					);
 			}
 			var text;
-			if (this._textFreePool.length > 0){
+			if(this._textFreePool.length > 0){
 				text = this._textFreePool.pop();
 				text.setShape({x: x, y: y, text: textContent, align: align});
 				// For now all items share the same font, no need to re-set it
@@ -370,9 +519,9 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 						align,
 						textContent,
 						font,
-						fontColor,
-						labelWidth
-					);			}
+						fontColor						
+					);			
+			}
 			this._textUsePool.push(text);
 			return text;
 		},
@@ -392,47 +541,55 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 			return line;
 		},
 		render: function(dim, offsets){
-			//	summary:
+			// summary:
 			//		Render/draw the axis.
-			//	dim: Object
+			// dim: Object
 			//		An object of the form { width, height}.
-			//	offsets: Object
+			// offsets: Object
 			//		An object of the form { l, r, t, b }.
-			//	returns: dojox.charting.axis2d.Default
+			// returns: dojox/charting/axis2d/Default
 			//		The reference to the axis for functional chaining.
-			if(!this.dirty){
-				return this;	//	dojox.charting.axis2d.Default
+			
+			var isRtl = this._isRtl();	// chart mirroring
+			if(!this.dirty || !this.scaler){
+				return this;	//	dojox/charting/axis2d/Default
 			}
 			// prepare variable
 			var o = this.opt, ta = this.chart.theme.axis, leftBottom = o.leftBottom, rotation = o.rotation % 360,
 				start, stop, titlePos, titleRotation=0, titleOffset, axisVector, tickVector, anchorOffset, labelOffset, labelAlign,
-
+				labelGap = this.chart.theme.axis.tick.labelGap,
 				// TODO: we use one font --- of major tick, we need to use major and minor fonts
 				taFont = o.font || (ta.majorTick && ta.majorTick.font) || (ta.tick && ta.tick.font),
-				taTitleFont = o.titleFont || (ta.tick && ta.tick.titleFont),
+				taTitleFont = o.titleFont || (ta.title && ta.title.font),
 				// TODO: we use one font color --- we need to use different colors
 				taFontColor = o.fontColor || (ta.majorTick && ta.majorTick.fontColor) || (ta.tick && ta.tick.fontColor) || "black",
-				taTitleFontColor = o.titleFontColor || (ta.tick && ta.tick.titleFontColor) || "black",
-				taTitleGap = (o.titleGap==0) ? 0 : o.titleGap || (ta.tick && ta.tick.titleGap) || 15,
-				taTitleOrientation = o.titleOrientation || (ta.tick && ta.tick.titleOrientation) || "axis",
+				taTitleFontColor = o.titleFontColor || (ta.title && ta.title.fontColor) || "black",
+				taTitleGap = (o.titleGap==0) ? 0 : o.titleGap || (ta.title && ta.title.gap) || 15,
+				taTitleOrientation = o.titleOrientation || (ta.title && ta.title.orientation) || "axis",
 				taMajorTick = this.chart.theme.getTick("major", o),
 				taMinorTick = this.chart.theme.getTick("minor", o),
 				taMicroTick = this.chart.theme.getTick("micro", o),
 
-				tickSize = Math.max(taMajorTick.length, taMinorTick.length, taMicroTick.length),
 				taStroke = "stroke" in o ? o.stroke : ta.stroke,
 				size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
 				cosr = Math.abs(Math.cos(rotation * Math.PI / 180)),
 				sinr = Math.abs(Math.sin(rotation * Math.PI / 180)),
 				tsize = taTitleFont ? g.normalizedLength(g.splitFontString(taTitleFont).size) : 0;
+			if(typeof labelGap != "number"){
+				labelGap = 4; // in pixels
+			}
 			if(rotation < 0){
 				rotation += 360;
 			}
+			var cachedLabelW = this._getMaxLabelSize();
+			cachedLabelW = cachedLabelW && cachedLabelW.majLabelW;
 			if(this.vertical){
 				start = {y: dim.height - offsets.b};
 				stop  = {y: offsets.t};
 				titlePos = {y: (dim.height - offsets.b + offsets.t)/2};
-				titleOffset = size * sinr + (this._cachedLabelWidth || 0) * cosr + labelGap + Math.max(taMajorTick.length, taMinorTick.length) + tsize + taTitleGap;
+				titleOffset = size * sinr + (cachedLabelW || 0) * cosr + labelGap + Math.max(taMajorTick.length > 0?taMajorTick.length:0,
+																		 					 taMinorTick.length > 0?taMinorTick.length:0) +
+					tsize + taTitleGap;
 				axisVector = {x: 0, y: -1};
 				labelOffset = {x: 0, y: 0};
 				tickVector = {x: 1, y: 0};
@@ -502,8 +659,10 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 				start = {x: offsets.l};
 				stop  = {x: dim.width - offsets.r};
 				titlePos = {x: (dim.width - offsets.r + offsets.l)/2};
-				titleOffset = size * cosr + (this._cachedLabelWidth || 0) * sinr + labelGap + Math.max(taMajorTick.length, taMinorTick.length) + tsize + taTitleGap;
-				axisVector = {x: 1, y: 0};
+				titleOffset = size * cosr + (cachedLabelW || 0) * sinr + labelGap + Math.max(taMajorTick.length > 0?taMajorTick.length:0,
+																		 					 taMinorTick.length > 0?taMinorTick.length:0) +
+					tsize + taTitleGap;
+				axisVector = {x: isRtl ? -1 : 1, y: 0}; 	// chart mirroring
 				labelOffset = {x: 0, y: 0};
 				tickVector = {x: 0, y: 1};
 				anchorOffset = {x: 0, y: labelGap};
@@ -572,172 +731,170 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 
 			this.cleanGroup();
 
-			try{
-				var s = this.group,
-					c = this.scaler,
-					t = this.ticks,
-					canLabel,
-					f = lin.getTransformerFromModel(this.scaler),
-					// GFX Canvas now supports labels, so let's _not_ fallback to HTML anymore on canvas, just use
-					// HTML labels if explicitly asked + no rotation + no IE + no Opera
-					labelType = (!o.title || !titleRotation) && !rotation && this.opt.htmlLabels && !has("ie") && !has("opera") ? "html" : "gfx",
-					dx = tickVector.x * taMajorTick.length,
-					dy = tickVector.y * taMajorTick.length;
+			var s = this.group,
+				c = this.scaler,
+				t = this.ticks,
+				f = lin.getTransformerFromModel(this.scaler),
+				// GFX Canvas now supports labels, so let's _not_ fallback to HTML anymore on canvas, just use
+				// HTML labels if explicitly asked + no rotation + no IE + no Opera
+				labelType = (!o.title || !titleRotation) && !rotation && this.opt.htmlLabels && !has("ie") && !has("opera") ? "html" : "gfx",
+				dx = tickVector.x * taMajorTick.length,
+				dy = tickVector.y * taMajorTick.length,
+				skip = this._skipInterval;
 
-				s.createLine({
-					x1: start.x,
-					y1: start.y,
-					x2: stop.x,
-					y2: stop.y
-				}).setStroke(taStroke);
-				
-				//create axis title
-				if(o.title){
-					var axisTitle = acommon.createText[labelType](
-						this.chart,
+			s.createLine({
+				x1: start.x,
+				y1: start.y,
+				x2: stop.x,
+				y2: stop.y
+			}).setStroke(taStroke);
+
+			//create axis title
+			if(o.title){
+				var axisTitle = acommon.createText[labelType](
+					this.chart,
+					s,
+					titlePos.x,
+					titlePos.y,
+					"middle",
+					o.title,
+					taTitleFont,
+					taTitleFontColor
+				);
+				if(labelType == "html"){
+					this.htmlElements.push(axisTitle);
+				}else{
+					//as soon as rotation is provided, labelType won't be "html"
+					//rotate gfx labels
+					axisTitle.setTransform(g.matrix.rotategAt(titleRotation, titlePos.x, titlePos.y));
+				}
+			}
+
+			// go out nicely instead of try/catch
+			if(t == null){
+				this.dirty = false;
+				return this;
+			}
+
+			var rel = (t.major.length > 0)?(t.major[0].value - this._majorStart) / c.major.tick:0;
+			var canLabel = this.opt.majorLabels;
+			arr.forEach(t.major, function(tick, i){
+				var offset = f(tick.value), elem,
+					x = (isRtl ? stop.x : start.x) + axisVector.x * offset, // chart mirroring
+					y = start.y + axisVector.y * offset;
+				i += rel;
+				this.createLine(s, {
+					x1: x, y1: y,
+					x2: x + dx,
+					y2: y + dy
+				}).setStroke(taMajorTick);
+				if(tick.label && (!skip || (i - (1 + skip)) % (1 + skip) == 0)){
+					var label = o.maxLabelCharCount ? this.getTextWithLimitCharCount(tick.label, taFont, o.maxLabelCharCount) : {
+						text: tick.label,
+						truncated: false
+					};
+					label = o.maxLabelSize ? this.getTextWithLimitLength(label.text, taFont, o.maxLabelSize, label.truncated) : label;
+					elem = this.createText(labelType,
 						s,
-						titlePos.x,
-						titlePos.y,
-						"middle",
-						o.title,
-						taTitleFont,
-						taTitleFontColor
+						x + (taMajorTick.length > 0 ? dx : 0) + anchorOffset.x + (rotation ? 0 : labelOffset.x),
+						y + (taMajorTick.length > 0 ? dy : 0) + anchorOffset.y + (rotation ? 0 : labelOffset.y),
+						labelAlign,
+						label.text,
+						taFont,
+						taFontColor
+						//cachedLabelW
 					);
+					// if bidi support was required, the textDir is "auto" and truncation
+					// took place, we need to update the dir of the element for cases as:
+					// Fool label: 111111W (W for bidi character)
+					// truncated label: 11...
+					// in this case for auto textDir the dir will be "ltr" which is wrong.
+					if(label.truncated){
+						this.chart.formatTruncatedLabel(elem, tick.label, labelType);
+					}
+					label.truncated && this.labelTooltip(elem, this.chart, tick.label, label.text, taFont, labelType);
 					if(labelType == "html"){
-						this.htmlElements.push(axisTitle);
-					}else{
-						//as soon as rotation is provided, labelType won't be "html"
-						//rotate gfx labels
-						axisTitle.setTransform(g.matrix.rotategAt(titleRotation, titlePos.x, titlePos.y));
+						this.htmlElements.push(elem);
+					}else if(rotation){
+						elem.setTransform([
+							{dx: labelOffset.x, dy: labelOffset.y},
+							g.matrix.rotategAt(
+								rotation,
+								x + (taMajorTick.length > 0 ? dx : 0) + anchorOffset.x,
+								y + (taMajorTick.length > 0 ? dy : 0) + anchorOffset.y
+							)
+						]);
 					}
 				}
-				
-				// go out nicely instead of try/catch
-				if(t==null){
-					this.dirty = false;
-					return this;
-				}
-
-				arr.forEach(t.major, function(tick){
-					var offset = f(tick.value), elem,
-						x = start.x + axisVector.x * offset,
-						y = start.y + axisVector.y * offset;
-						this.createLine(s, {
-							x1: x, y1: y,
-							x2: x + dx,
-							y2: y + dy
-						}).setStroke(taMajorTick);
-						if(tick.label){
-							var label = o.maxLabelCharCount ? this.getTextWithLimitCharCount(tick.label, taFont, o.maxLabelCharCount) : {
-								text: tick.label,
-								truncated: false
-							};
-							label = o.maxLabelSize ? this.getTextWithLimitLength(label.text, taFont, o.maxLabelSize, label.truncated) : label;
-							elem = this.createText(labelType,
-								s,
-								x + dx + anchorOffset.x + (rotation ? 0 : labelOffset.x),
-								y + dy + anchorOffset.y + (rotation ? 0 : labelOffset.y),
-								labelAlign,
-								label.text,
-								taFont,
-								taFontColor
-								//this._cachedLabelWidth
-							);
-							
-							// if bidi support was required, the textDir is "auto" and truncation
-							// took place, we need to update the dir of the element for cases as: 
-							// Fool label: 111111W (W for bidi character)
-							// truncated label: 11... 
-							// in this case for auto textDir the dir will be "ltr" which is wrong.
-							if(this.chart.truncateBidi  && label.truncated){
-								this.chart.truncateBidi(elem, tick.label, labelType);
-							}
-							label.truncated && this.labelTooltip(elem, this.chart, tick.label, label.text, taFont, labelType);
-							if(labelType == "html"){
-								this.htmlElements.push(elem);
-							}else if(rotation){
-								elem.setTransform([
-									{dx: labelOffset.x, dy: labelOffset.y},
-									g.matrix.rotategAt(
-										rotation,
-										x + dx + anchorOffset.x,
-										y + dy + anchorOffset.y
-									)
-								]);
-							}
-						}
-				}, this);
+			}, this);
 
-				dx = tickVector.x * taMinorTick.length;
-				dy = tickVector.y * taMinorTick.length;
-				canLabel = c.minMinorStep <= c.minor.tick * c.bounds.scale;
-				arr.forEach(t.minor, function(tick){
-					var offset = f(tick.value), elem,
-						x = start.x + axisVector.x * offset,
-						y = start.y + axisVector.y * offset;
-						this.createLine(s, {
-							x1: x, y1: y,
-							x2: x + dx,
-							y2: y + dy
-						}).setStroke(taMinorTick);
-						if(canLabel && tick.label){
-							var label = o.maxLabelCharCount ? this.getTextWithLimitCharCount(tick.label, taFont, o.maxLabelCharCount) : {
-								text: tick.label,
-								truncated: false
-							};
-							label = o.maxLabelSize ? this.getTextWithLimitLength(label.text, taFont, o.maxLabelSize, label.truncated) : label;
-							elem = this.createText(labelType,
-								s,
-								x + dx + anchorOffset.x + (rotation ? 0 : labelOffset.x),
-								y + dy + anchorOffset.y + (rotation ? 0 : labelOffset.y),
-								labelAlign,
-								label.text,
-								taFont,
-								taFontColor
-								//this._cachedLabelWidth
-							);
-							// if bidi support was required, the textDir is "auto" and truncation
-							// took place, we need to update the dir of the element for cases as: 
-							// Fool label: 111111W (W for bidi character)
-							// truncated label: 11... 
-							// in this case for auto textDir the dir will be "ltr" which is wrong.
-							if(this.chart.getTextDir && label.truncated){
-								this.chart.truncateBidi(elem, tick.label, labelType);
-							}
-							label.truncated && this.labelTooltip(elem, this.chart, tick.label, label.text, taFont, labelType);
-							if(labelType == "html"){
-								this.htmlElements.push(elem);
-							}else if(rotation){
-								elem.setTransform([
-									{dx: labelOffset.x, dy: labelOffset.y},
-									g.matrix.rotategAt(
-										rotation,
-										x + dx + anchorOffset.x,
-										y + dy + anchorOffset.y
-									)
-								]);
-							}
-						}
-				}, this);
+			dx = tickVector.x * taMinorTick.length;
+			dy = tickVector.y * taMinorTick.length;
+			canLabel = this.opt.minorLabels && c.minMinorStep <= c.minor.tick * c.bounds.scale;
+			arr.forEach(t.minor, function(tick){
+				var offset = f(tick.value), elem,
+					x = (isRtl ? stop.x : start.x)  + axisVector.x * offset,
+					y = start.y + axisVector.y * offset; // chart mirroring
+				this.createLine(s, {
+					x1: x, y1: y,
+					x2: x + dx,
+					y2: y + dy
+				}).setStroke(taMinorTick);
+				if(canLabel && tick.label){
+					var label = o.maxLabelCharCount ? this.getTextWithLimitCharCount(tick.label, taFont, o.maxLabelCharCount) : {
+						text: tick.label,
+						truncated: false
+					};
+					label = o.maxLabelSize ? this.getTextWithLimitLength(label.text, taFont, o.maxLabelSize, label.truncated) : label;
+					elem = this.createText(labelType,
+						s,
+						x + (taMinorTick.length > 0 ? dx : 0) + anchorOffset.x + (rotation ? 0 : labelOffset.x),
+						y + (taMinorTick.length  > 0 ? dy : 0) + anchorOffset.y + (rotation ? 0 : labelOffset.y),
+						labelAlign,
+						label.text,
+						taFont,
+						taFontColor
+						//cachedLabelW
+					);
+					// if bidi support was required, the textDir is "auto" and truncation
+					// took place, we need to update the dir of the element for cases as:
+					// Fool label: 111111W (W for bidi character)
+					// truncated label: 11...
+					// in this case for auto textDir the dir will be "ltr" which is wrong.
+					if(label.truncated){
+						this.chart.formatTruncatedLabel(elem, tick.label, labelType);
+					}
+					label.truncated && this.labelTooltip(elem, this.chart, tick.label, label.text, taFont, labelType);
+					if(labelType == "html"){
+						this.htmlElements.push(elem);
+					}else if(rotation){
+						elem.setTransform([
+							{dx: labelOffset.x, dy: labelOffset.y},
+							g.matrix.rotategAt(
+								rotation,
+								x + (taMinorTick.length > 0 ? dx : 0) + anchorOffset.x,
+								y + (taMinorTick.length > 0 ? dy : 0) + anchorOffset.y
+							)
+						]);
+					}
+				}
+			}, this);
 
-				dx = tickVector.x * taMicroTick.length;
-				dy = tickVector.y * taMicroTick.length;
-				arr.forEach(t.micro, function(tick){
-					var offset = f(tick.value), elem,
-						x = start.x + axisVector.x * offset,
-						y = start.y + axisVector.y * offset;
-						this.createLine(s, {
-							x1: x, y1: y,
-							x2: x + dx,
-							y2: y + dy
-						}).setStroke(taMicroTick);
-				}, this);
-			}catch(e){
-				// squelch
-			}
+			dx = tickVector.x * taMicroTick.length;
+			dy = tickVector.y * taMicroTick.length;
+			arr.forEach(t.micro, function(tick){
+				var offset = f(tick.value),
+					x = start.x + axisVector.x * offset,
+					y = start.y + axisVector.y * offset;
+					this.createLine(s, {
+						x1: x, y1: y,
+						x2: x + dx,
+						y2: y + dy
+					}).setStroke(taMicroTick);
+			}, this);
 
 			this.dirty = false;
-			return this;	//	dojox.charting.axis2d.Default
+			return this;	//	dojox/charting/axis2d/Default
 		},
 		labelTooltip: function(elem, chart, label, truncatedLabel, font, elemType){
 			var modules = ["dijit/Tooltip"];
@@ -745,7 +902,7 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 				fontWidth = g._base._getTextBox(truncatedLabel, {font: font}).w || 0,
 				fontHeight = font ? g.normalizedLength(g.splitFontString(font).size) : 0;
 			if(elemType == "html"){
-				lang.mixin(aroundRect, html.coords(elem.firstChild, true));
+				lang.mixin(aroundRect, domGeom.position(elem.firstChild, true));
 				aroundRect.width = Math.ceil(fontWidth);
 				aroundRect.height = Math.ceil(fontHeight);
 				this._events.push({
@@ -766,7 +923,7 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 				});
 			}else{
 				var shp = elem.getShape(),
-					lt = html.coords(chart.node, true);
+					lt = chart.getCoords();
 				aroundRect = lang.mixin(aroundRect, {
 					x: shp.x - fontWidth / 2,
 					y: shp.y
@@ -794,6 +951,10 @@ define(["dojo/_base/lang", "dojo/_base/array","dojo/_base/sniff", "dojo/_base/de
 					})
 				});
 			}
+		},
+		_isRtl: function(){
+			return false;
 		}
 	});
+	return has("dojo-bidi")? declare("dojox.charting.axis2d.Default", [Default, BidiDefault]) : Default;
 });
diff --git a/dojox/charting/axis2d/Invisible.js b/dojox/charting/axis2d/Invisible.js
index b03bea0..5c12ef0 100644
--- a/dojox/charting/axis2d/Invisible.js
+++ b/dojox/charting/axis2d/Invisible.js
@@ -1,42 +1,74 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "./Base", "../scaler/linear", 
-	"dojox/gfx", "dojox/lang/utils", "dojox/lang/functional", "dojo/string"],
-	function(lang, declare, Base, lin, g, du, df, dstring){
+define(["dojo/_base/lang", "dojo/_base/declare", "./Base", "../scaler/linear",
+	"dojox/lang/utils"],
+	function(lang, declare, Base, lin, du){
+
 /*=====
-var Base = dojox.charting.axis2d.Base;
-=====*/ 
-	var merge = du.merge,
-		labelGap = 4,			// in pixels
-		centerAnchorLimit = 45;	// in degrees
+	var __InvisibleAxisCtorArgs = {
+		// summary:
+		//		Optional arguments used in the definition of an invisible axis.
+		// vertical: Boolean?
+		//		A flag that says whether an axis is vertical (i.e. y axis) or horizontal. Default is false (horizontal).
+		// fixUpper: String?
+		//		Align the greatest value on the axis with the specified tick level. Options are "major", "minor", "micro", or "none".  Defaults to "none".
+		// fixLower: String?
+		//		Align the smallest value on the axis with the specified tick level. Options are "major", "minor", "micro", or "none".  Defaults to "none".
+		// natural: Boolean?
+		//		Ensure tick marks are made on "natural" numbers. Defaults to false.
+		// leftBottom: Boolean?
+		//		The position of a vertical axis; if true, will be placed against the left-bottom corner of the chart.  Defaults to true.
+		// includeZero: Boolean?
+		//		Include 0 on the axis rendering.  Default is false.
+		// fixed: Boolean?
+		//		Force all axis labels to be fixed numbers.  Default is true.
+		// min: Number?
+		//		The smallest value on an axis. Default is 0.
+		// max: Number?
+		//		The largest value on an axis. Default is 1.
+		// from: Number?
+		//		Force the chart to render data visible from this value. Default is 0.
+		// to: Number?
+		//		Force the chart to render data visible to this value. Default is 1.
+		// majorTickStep: Number?
+		//		The amount to skip before a major tick is drawn. When not set the major ticks step is computed from
+		//		the data range.
+		// minorTickStep: Number?
+		//		The amount to skip before a minor tick is drawn. When not set the minor ticks step is computed from
+		//		the data range.
+		// microTickStep: Number?
+		//		The amount to skip before a micro tick is drawn. When not set the micro ticks step is computed from
+	};
+=====*/
 
 	return declare("dojox.charting.axis2d.Invisible", Base, {
-		//	summary:
-		//		The default axis object used in dojox.charting.  See dojox.charting.Chart.addAxis for details.
+		// summary:
+		//		A axis object used in dojox.charting.  You can use that axis if you want the axis to be invisible.
+		//		See dojox.charting.Chart.addAxis for details.
 		//
-		//	defaultParams: Object
+		// defaultParams: Object
 		//		The default parameters used to define any axis.
-		//	optionalParams: Object
+		// optionalParams: Object
 		//		Any optional parameters needed to define an axis.
 
 		/*
-		//	TODO: the documentation tools need these to be pre-defined in order to pick them up
+		// TODO: the documentation tools need these to be pre-defined in order to pick them up
 		//	correctly, but the code here is partially predicated on whether or not the properties
 		//	actually exist.  For now, we will leave these undocumented but in the code for later. -- TRT
 
-		//	opt: Object
+		// opt: Object
 		//		The actual options used to define this axis, created at initialization.
-		//	scalar: Object
+		// scaler: Object
 		//		The calculated helper object to tell charts how to draw an axis and any data.
-		//	ticks: Object
+		// ticks: Object
 		//		The calculated tick object that helps a chart draw the scaling on an axis.
-		//	dirty: Boolean
+		// dirty: Boolean
 		//		The state of the axis (whether it needs to be redrawn or not)
-		//	scale: Number
+		// scale: Number
 		//		The current scale of the axis.
-		//	offset: Number
+		// offset: Number
 		//		The current offset of the axis.
 
 		opt: null,
-		scalar: null,
+		scaler: null,
 		ticks: null,
 		dirty: true,
 		scale: 1,
@@ -49,12 +81,7 @@ var Base = dojox.charting.axis2d.Base;
 			natural:     false,		// all tick marks should be made on natural numbers
 			leftBottom:  true,		// position of the axis, used with "vertical"
 			includeZero: false,		// 0 should be included
-			fixed:       true,		// all labels are fixed numbers
-			majorLabels: true,		// draw major labels
-			minorTicks:  true,		// draw minor ticks
-			minorLabels: true,		// draw minor labels
-			microTicks:  false,		// draw micro ticks
-			rotation:    0			// label rotation angle in degrees
+			fixed:       true		// all labels are fixed numbers
 		},
 		optionalParams: {
 			min:			0,	// minimal value on this axis
@@ -63,109 +90,86 @@ var Base = dojox.charting.axis2d.Base;
 			to:				1,	// visible to this value
 			majorTickStep:	4,	// major tick step
 			minorTickStep:	2,	// minor tick step
-			microTickStep:	1,	// micro tick step
-			labels:			[],	// array of labels for major ticks
-								// with corresponding numeric values
-								// ordered by values
-			labelFunc:		null, // function to compute label values
-			maxLabelSize:	0,	// size in px. For use with labelFunc
-			maxLabelCharCount:	0,	// size in word count.
-			trailingSymbol:			null
-
-			// TODO: add support for minRange!
-			// minRange:		1,	// smallest distance from min allowed on the axis
+			microTickStep:	1	// micro tick step
 		},
 
 		constructor: function(chart, kwArgs){
-			//	summary:
-			//		The constructor for an axis.
-			//	chart: dojox.charting.Chart
+			// summary:
+			//		The constructor for an invisible axis.
+			// chart: dojox/charting/Chart
 			//		The chart the axis belongs to.
-			//	kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
+			// kwArgs: __InvisibleAxisCtorArgs?
 			//		Any optional keyword arguments to be used to define this axis.
 			this.opt = lang.clone(this.defaultParams);
             du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 		},
 		dependOnData: function(){
-			//	summary:
+			// summary:
 			//		Find out whether or not the axis options depend on the data in the axis.
 			return !("min" in this.opt) || !("max" in this.opt);	//	Boolean
 		},
 		clear: function(){
-			//	summary:
+			// summary:
 			//		Clear out all calculated properties on this axis;
-			//	returns: dojox.charting.axis2d.Default
+			// returns: dojox/charting/axis2d/Invisible
 			//		The reference to the axis for functional chaining.
 			delete this.scaler;
 			delete this.ticks;
 			this.dirty = true;
-			return this;	//	dojox.charting.axis2d.Default
+			return this;	//	dojox/charting/axis2d/Invisible
 		},
 		initialized: function(){
-			//	summary:
+			// summary:
 			//		Finds out if this axis has been initialized or not.
-			//	returns: Boolean
+			// returns: Boolean
 			//		Whether a scaler has been calculated and if the axis is not dirty.
 			return "scaler" in this && !(this.dirty && this.dependOnData());
 		},
 		setWindow: function(scale, offset){
-			//	summary:
+			// summary:
 			//		Set the drawing "window" for the axis.
-			//	scale: Number
+			// scale: Number
 			//		The new scale for the axis.
-			//	offset: Number
+			// offset: Number
 			//		The new offset for the axis.
-			//	returns: dojox.charting.axis2d.Default
+			// returns: dojox/charting/axis2d/Invisible
 			//		The reference to the axis for functional chaining.
 			this.scale  = scale;
 			this.offset = offset;
-			return this.clear();	//	dojox.charting.axis2d.Default
+			return this.clear();	//	dojox/charting/axis2d/Invisible
 		},
 		getWindowScale: function(){
-			//	summary:
+			// summary:
 			//		Get the current windowing scale of the axis.
 			return "scale" in this ? this.scale : 1;	//	Number
 		},
 		getWindowOffset: function(){
-			//	summary:
+			// summary:
 			//		Get the current windowing offset for the axis.
 			return "offset" in this ? this.offset : 0;	//	Number
 		},
-		_groupLabelWidth: function(labels, font, wcLimit){
-			if(!labels.length){
-				return 0;
-			}
-			if(lang.isObject(labels[0])){
-				labels = df.map(labels, function(label){ return label.text; });
-			}
-			if (wcLimit) {
-				labels = df.map(labels, function(label){
-					return lang.trim(label).length == 0 ? "" : label.substring(0, wcLimit) + this.trailingSymbol;
-				}, this);
-			}
-			var s = labels.join("<br>");
-			return g._base._getTextBox(s, {font: font}).w || 0;
-		},
-		calculate: function(min, max, span, labels){
-			//	summary:
+		calculate: function(min, max, span){
+			// summary:
 			//		Perform all calculations needed to render this axis.
-			//	min: Number
+			// min: Number
 			//		The smallest value represented on this axis.
-			//	max: Number
+			// max: Number
 			//		The largest value represented on this axis.
-			//	span: Number
+			// span: Number
 			//		The span in pixels over which axis calculations are made.
-			//	labels: String[]
-			//		Optional list of labels.
-			//	returns: dojox.charting.axis2d.Default
+			// returns: dojox/charting/axis2d/Invisible
 			//		The reference to the axis for functional chaining.
 			if(this.initialized()){
 				return this;
 			}
 			var o = this.opt;
-			this.labels = "labels" in o  ? o.labels : labels;
+			// we used to have a 4th function parameter to reach labels but
+			// nobody was calling it with 4 parameters.
+			this.labels = o.labels;
 			this.scaler = lin.buildScaler(min, max, span, o);
+			// store the absolute major tick start, this will be useful when dropping a label every n labels
+			// TODO: if o.lower then it does not work
 			var tsb = this.scaler.bounds;
 			if("scale" in this){
 				// calculate new range
@@ -204,80 +208,15 @@ var Base = dojox.charting.axis2d.Base;
 					delete this.offset;
 				}
 			}
-
-			var ta = this.chart.theme.axis, labelWidth = 0, rotation = o.rotation % 360,
-				// TODO: we use one font --- of major tick, we need to use major and minor fonts
-				taFont = o.font || (ta.majorTick && ta.majorTick.font) || (ta.tick && ta.tick.font),
-				size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
-				cosr = Math.abs(Math.cos(rotation * Math.PI / 180)),
-				sinr = Math.abs(Math.sin(rotation * Math.PI / 180));
-
-			if(rotation < 0){
-				rotation += 360;
-			}
-
-			if(size){
-				if(this.vertical ? rotation != 0 && rotation != 180 : rotation != 90 && rotation != 270){
-					// we need width of all labels
-					if(this.labels){
-						labelWidth = this._groupLabelWidth(this.labels, taFont, o.maxLabelCharCount);
-					}else{
-						var labelLength = Math.ceil(
-								Math.log(
-									Math.max(
-										Math.abs(tsb.from),
-										Math.abs(tsb.to)
-									)
-								) / Math.LN10
-							),
-							t = [];
-						if(tsb.from < 0 || tsb.to < 0){
-							t.push("-");
-						}
-						t.push(dstring.rep("9", labelLength));
-						var precision = Math.floor(
-							Math.log( tsb.to - tsb.from ) / Math.LN10
-						);
-						if(precision > 0){
-							t.push(".");
-							t.push(dstring.rep("9", precision));
-						}
-						labelWidth = g._base._getTextBox(
-							t.join(""),
-							{ font: taFont }
-						).w;
-					}
-					labelWidth = o.maxLabelSize ? Math.min(o.maxLabelSize, labelWidth) : labelWidth;
-				}else{
-					labelWidth = size;
-				}
-				switch(rotation){
-					case 0:
-					case 90:
-					case 180:
-					case 270:
-						// trivial cases: use labelWidth
-						break;
-					default:
-						// rotated labels
-						var gap1 = Math.sqrt(labelWidth * labelWidth + size * size),									// short labels
-							gap2 = this.vertical ? size * cosr + labelWidth * sinr : labelWidth * cosr + size * sinr;	// slanted labels
-						labelWidth = Math.min(gap1, gap2);
-						break;
-				}
-			}
-
-			this.scaler.minMinorStep = labelWidth + labelGap;
-			this.ticks = lin.buildTicks(this.scaler, o);
-			return this;	//	dojox.charting.axis2d.Default
+			return this;	//	dojox/charting/axis2d/Invisible
 		},
 		getScaler: function(){
-			//	summary:
+			// summary:
 			//		Get the pre-calculated scaler object.
 			return this.scaler;	//	Object
 		},
 		getTicks: function(){
-			//	summary:
+			// summary:
 			//		Get the pre-calculated ticks object.
 			return this.ticks;	//	Object
 		}
diff --git a/dojox/charting/axis2d/common.js b/dojox/charting/axis2d/common.js
index 6682346..6be5cf5 100644
--- a/dojox/charting/axis2d/common.js
+++ b/dojox/charting/axis2d/common.js
@@ -1,5 +1,5 @@
-define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/window", "dojo/dom-geometry", "dojox/gfx"], 
-	function(lang, html, win, domGeom, g){
+define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom-geometry", "dojox/gfx", "dojo/has"],
+	function(lang, win, domGeom, g, has){
 
 	var common = lang.getObject("dojox.charting.axis2d.common", true);
 	
@@ -29,56 +29,56 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/window", "dojo/dom-geo
 	};
 
 	return lang.mixin(common, {
-		//	summary:
+		// summary:
 		//		Common methods to be used by any axis.  This is considered "static".
 		createText: {
 			gfx: function(chart, creator, x, y, align, text, font, fontColor){
-				//	summary:
+				// summary:
 				//		Use dojox.gfx to create any text.
-				//	chart: dojox.charting.Chart
+				// chart: dojox.charting.Chart
 				//		The chart to create the text into.
-				//	creator: dojox.gfx.Surface
+				// creator: dojox.gfx.Surface
 				//		The graphics surface to use for creating the text.
-				//	x: Number
+				// x: Number
 				//		Where to create the text along the x axis (CSS left).
-				//	y: Number
+				// y: Number
 				//		Where to create the text along the y axis (CSS top).
-				//	align: String
+				// align: String
 				//		How to align the text.  Can be "left", "right", "center".
-				//	text: String
+				// text: String
 				//		The text to render.
-				//	font: String
+				// font: String
 				//		The font definition, a la CSS "font".
-				//	fontColor: String|dojo.Color
+				// fontColor: String|dojo.Color
 				//		The color of the resultant text.
-				//	returns: dojox.gfx.Text
+				// returns: dojox.gfx.Text
 				//		The resultant GFX object.
 				return creator.createText({
 					x: x, y: y, text: text, align: align
 				}).setFont(font).setFill(fontColor);	//	dojox.gfx.Text
 			},
 			html: function(chart, creator, x, y, align, text, font, fontColor, labelWidth){
-				//	summary:
+				// summary:
 				//		Use the HTML DOM to create any text.
-				//	chart: dojox.charting.Chart
+				// chart: dojox.charting.Chart
 				//		The chart to create the text into.
-				//	creator: dojox.gfx.Surface
+				// creator: dojox.gfx.Surface
 				//		The graphics surface to use for creating the text.
-				//	x: Number
+				// x: Number
 				//		Where to create the text along the x axis (CSS left).
-				//	y: Number
+				// y: Number
 				//		Where to create the text along the y axis (CSS top).
-				//	align: String
+				// align: String
 				//		How to align the text.  Can be "left", "right", "center".
-				//	text: String
+				// text: String
 				//		The text to render.
-				//	font: String
+				// font: String
 				//		The font definition, a la CSS "font".
-				//	fontColor: String|dojo.Color
+				// fontColor: String|dojo.Color
 				//		The color of the resultant text.
-				//	labelWidth: Number?
+				// labelWidth: Number?
 				//		The maximum width of the resultant DOM node.
-				//	returns: DOMNode
+				// returns: DOMNode
 				//		The resultant DOMNode (a "div" element).
 
 				// setup the text node
@@ -152,8 +152,11 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/window", "dojo/dom-geo
 				w.width = "0px";
 				w.height = "0px";
 				// insert nodes
-				wrap.appendChild(p)
+				wrap.appendChild(p);
 				chart.node.insertBefore(wrap, chart.node.firstChild);
+				if(has("dojo-bidi")){
+					chart.htmlElementsRegistry.push([wrap, x, y, align, text, font, fontColor]);
+				}
 				return wrap;	//	DOMNode
 			}
 		}
diff --git a/dojox/charting/bidi/Chart.js b/dojox/charting/bidi/Chart.js
new file mode 100644
index 0000000..7eaf8fb
--- /dev/null
+++ b/dojox/charting/bidi/Chart.js
@@ -0,0 +1,260 @@
+define(["dojox/main", "dojo/_base/declare", "dojo/_base/lang", "dojo/dom-style", "dojo/_base/array", "dojo/sniff",
+	"dojo/dom","dojo/dom-construct",
+	"dojox/gfx", "dojox/gfx/_gfxBidiSupport", "../axis2d/common", "dojox/string/BidiEngine",
+	"dojox/lang/functional","dojo/dom-attr","./_bidiutils"],
+	function(dojox, declare, lang, domStyle, arr, has, dom, domConstruct, g, gBidi, da, BidiEngine, df, domAttr,utils){
+	// module:
+	//		dojox/charting/bidi/Chart							
+	var bidiEngine = new BidiEngine();
+	var dc = lang.getObject("charting", true, dojox);
+	function validateTextDir(textDir){
+		return /^(ltr|rtl|auto)$/.test(textDir) ? textDir : null;
+	};
+	
+	return declare(null, {
+		// textDir: String
+		//		Bi-directional support,	the main variable which is responsible for the direction of the text.
+		//		The text direction can be different than the GUI direction by using this parameter.
+		//		Allowed values:
+		//
+		//		1. "ltr"
+		//		2. "rtl"
+		//		3. "auto" - contextual the direction of a text defined by first strong letter.
+		//
+		//		By default is as the page direction.
+		textDir:"",
+		
+		// dir: String
+		//		Mirroring support,	the main variable which is responsible for the direction of the chart.
+		//
+		//		Allowed values:
+		//		1. "ltr"
+		//		2. "rtl"
+		//
+		//		By default is ltr.
+		dir: "",
+		isMirrored: false,
+		
+		getTextDir: function(text){
+			// summary:
+			//		Return direction of the text. 
+			// description:
+			//		If textDir is ltr or rtl returns the value.
+			//		If it's auto, calls to another function that responsible 
+			//		for checking the value, and defining the direction.			
+			// text:
+			//		Used in case textDir is "auto", this case the direction is according to the first
+			//		strong (directionally - which direction is strong defined) letter.
+			// tags:
+			//		protected.
+			var textDir = this.textDir == "auto" ? bidiEngine.checkContextual(text) : this.textDir;
+			// providing default value
+			if(!textDir){
+				textDir = domStyle.get(this.node, "direction");
+			}
+			return textDir;
+		},
+
+		postscript: function(node,args){
+			// summary:
+			//		Kicks off chart instantiation.
+			// description:
+			//		Used for setting the textDir of the chart. 
+			// tags:
+			//		private
+
+			// validate textDir
+			var textDir = args ? (args["textDir"] ? validateTextDir(args["textDir"]) : "") : "";
+			// if textDir wasn't defined or was defined wrong, apply default value
+			textDir = textDir ? textDir : domStyle.get(this.node, "direction");
+			this.textDir = textDir;
+
+			this.surface.textDir = textDir;
+			
+			// two data structures, used for storing data for further enablement to change
+			// textDir dynamically
+			this.htmlElementsRegistry = [];
+			this.truncatedLabelsRegistry = [];
+			// chart mirroring starts
+			var chartDir = "ltr";
+			if(domAttr.has(node, "direction")){
+				chartDir = domAttr.get(node, "direction");
+			}
+			this.setDir(args ? (args.dir ? args.dir: chartDir) : chartDir);
+			// chart mirroring ends
+		},
+
+		setTextDir: function(newTextDir, obj){
+			// summary:
+			//		Setter for the textDir attribute.
+			// description:
+			//		Allows dynamically set the textDir, goes over all the text-children and  
+			//		updates their base text direction.
+			// tags:
+			//		public
+		
+			if(newTextDir == this.textDir){
+				return this;
+			}
+			if(validateTextDir(newTextDir) != null){
+				this.textDir = newTextDir;
+				
+				// set automatically all the gfx objects that were created by this surface
+				// (groups, text objects)
+				this.surface.setTextDir(newTextDir);
+			
+				// truncated labels that were created with gfx creator need to recalculate dir
+				// for case like: "111111A" (A stands for bidi character) and the truncation
+				// is "111..." If the textDir is auto, the display should be: "...111" but in gfx
+				// case we will get "111...". Because this.surface.setTextDir will calculate the dir of truncated
+				// label, which value is "111..." but th real is "111111A".
+				// each time we created a gfx truncated label we stored it in the truncatedLabelsRegistry, so update now 
+				// the registry.
+				if(this.truncatedLabelsRegistry && newTextDir == "auto"){
+					arr.forEach(this.truncatedLabelsRegistry, function(elem){
+						var tDir = this.getTextDir(elem["label"]);
+						if(elem["element"].textDir != tDir){
+							elem["element"].setShape({textDir: tDir});
+						}
+					}, this);
+				}
+				
+				// re-render axes with html labels. for recalculation of the labels
+				// positions etc.
+				// create array of keys for all the axis in chart 
+				var axesKeyArr = df.keys(this.axes);
+				if(axesKeyArr.length > 0){
+					// iterate over the axes, and for each that have html labels render it.
+					arr.forEach(axesKeyArr, function(key, index, arr){
+						// get the axis 
+						var axis = this.axes[key];
+						// if the axis has html labels 
+						if(axis.htmlElements[0]){
+							axis.dirty = true;
+							axis.render(this.dim, this.offsets);
+						}
+					},this);
+					
+					// recreate title
+					if(this.title){
+						var forceHtmlLabels = (g.renderer == "canvas"),
+							labelType = forceHtmlLabels || !has("ie") && !has("opera") ? "html" : "gfx",
+							tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
+						// remove the title
+						domConstruct.destroy(this.chartTitle);
+						this.chartTitle =null;
+						// create the new title
+						this.chartTitle = da.createText[labelType](
+							this,
+							this.surface,
+							this.dim.width/2,
+							this.titlePos=="top" ? tsize + this.margins.t : this.dim.height - this.margins.b,
+							"middle",
+							this.title,
+							this.titleFont,
+							this.titleFontColor
+						);
+					}				
+				}else{
+					// case of pies, spiders etc.
+					arr.forEach(this.htmlElementsRegistry, function(elem, index, arr){
+						var tDir = newTextDir == "auto" ? this.getTextDir(elem[4]) : newTextDir;
+						if(elem[0].children[0] && elem[0].children[0].dir != tDir){
+							domConstruct.destroy(elem[0].children[0]);
+							elem[0].children[0] = da.createText["html"]
+									(this, this.surface, elem[1], elem[2], elem[3], elem[4], elem[5], elem[6]).children[0];
+						}
+					},this);
+				}
+			}
+			return this;
+		},
+		
+		setDir : function(dir){
+			// summary:
+			//		Setter for the dir attribute.
+			// description:
+			//		Allows dynamically set the dri attribute, which will used to
+			//		updates the chart rendering direction.
+			//	dir : the desired chart direction [rtl: for right to left ,ltr: for left to right]
+ 
+			if(dir == "rtl" || dir == "ltr"){
+				if(this.dir != dir){
+					this.isMirrored = true;
+					this.dirty = true;
+				}
+				this.dir = dir;
+			}			
+			return this; 
+		},
+		
+		isRightToLeft: function(){
+			// summary:
+			//		check the direction of the chart.
+			// description:
+			//		check the dir attribute to determine the rendering direction
+			//		of the chart.
+			return this.dir == "rtl";
+        },
+        
+		applyMirroring: function(plot, dim, offsets){
+			// summary:
+			//		apply the mirroring operation to the current chart plots.
+			//
+			utils.reverseMatrix(plot, dim, offsets, this.dir == "rtl");
+			//force the direction of the node to be ltr to properly render the axes and the plots labels.
+			domStyle.set(this.node, "direction", "ltr");
+			return this;
+		},
+
+		formatTruncatedLabel: function(element, label, labelType){
+			this.truncateBidi(element, label, labelType);
+		},
+
+		truncateBidi: function(elem, label, labelType){
+			// summary:
+			//		Enables bidi support for truncated labels.
+			// description:
+			//		Can be two types of labels: html or gfx.
+			//
+			//		####gfx labels:
+			//
+			//		Need to be stored in registry to be used when the textDir will be set dynamically.
+			//		Additional work on truncated labels is needed for case as 111111A (A stands for "bidi" character rtl directioned).
+			//		let's say in this case the truncation is "111..." If the textDir is auto, the display should be: "...111" but in gfx
+			//		case we will get "111...". Because this.surface.setTextDir will calculate the dir of truncated
+			//		label, which value is "111..." but th real is "111111A".
+			//		each time we created a gfx truncated label we store it in the truncatedLabelsRegistry.
+			//
+			//		####html labels:
+			//
+			//		no need for repository (stored in another place). Here we only need to update the current dir according to textDir.
+			// tags:
+			//		private
+		
+			if(labelType == "gfx"){
+				// store truncated gfx labels in the data structure.
+				this.truncatedLabelsRegistry.push({element: elem, label: label});
+				if(this.textDir == "auto"){
+					elem.setShape({textDir: this.getTextDir(label)});
+				}
+			}
+			if(labelType == "html" && this.textDir == "auto"){
+				elem.children[0].dir = this.getTextDir(label);
+			}
+		},
+		
+		render: function(){
+			this.inherited(arguments);
+			this.isMirrored = false;
+			return this;
+		},
+		
+		_resetLeftBottom: function(axis){
+			if(axis.vertical && this.isMirrored){
+				axis.opt.leftBottom = !axis.opt.leftBottom;
+			}
+		}		
+	});
+});
+
diff --git a/dojox/charting/bidi/Chart3D.js b/dojox/charting/bidi/Chart3D.js
new file mode 100644
index 0000000..4b5b088
--- /dev/null
+++ b/dojox/charting/bidi/Chart3D.js
@@ -0,0 +1,78 @@
+define(["dojo/_base/declare", "dojo/dom-style", "dojo/dom-attr", "./_bidiutils"],
+	function(declare, domStyle, domAttr, utils){
+	// module:
+	//		dojox/charting/bidi/Chart3D
+	return declare(null, {
+		// direction: String
+		//		Mirroring support,	the main variable which is responsible for the direction of the chart.
+		//
+		//		Allowed values:
+		//		1. "ltr"
+		//		2. "rtl"
+		//
+		//		By default is ltr.
+		direction: "",
+		isMirrored: false,
+		
+		postscript: function(node, lights, camera, theme, direction){
+			// summary:
+			//		The keyword arguments that can be passed in a Chart constructor.
+			//
+			// node: Node
+			//		The DOM node to construct the chart on.
+			// lights:
+			//		Lighting properties for the 3d scene
+			// camera: Object
+			//		Camera properties describing the viewing camera position.
+			// theme: Object
+			//		Charting theme to use for coloring chart elements.
+			// direction:String
+			//		the direction used to render the chart values[rtl/ltr]
+			var chartDir = "ltr";
+			if(domAttr.has(node, "direction")){
+				chartDir = domAttr.get(node, "direction");
+			}
+			this.chartBaseDirection = direction ? direction : chartDir;
+		},
+		generate: function(){
+			this.inherited(arguments);
+			this.isMirrored = false;
+			return this;
+		},
+		applyMirroring: function(plot, dim, offsets){
+			// summary:
+			//		apply the mirroring operation to the current chart plots.
+			//
+			if(this.isMirrored){
+				utils.reverseMatrix(plot, dim, offsets, this.dir == "rtl");
+			}
+			//force the direction of the node to be ltr to properly render the axes and the plots labels.
+			domStyle.set(this.node, "direction", "ltr");
+			return this;
+		},
+		setDir: function(dir){
+			// summary:
+			//		Setter for the chartBaseDirection attribute.
+			// description:
+			//		Allows dynamically set the chartBaseDirection attribute, which will used to  
+			//		updates the chart rendering direction.
+			//	dir : the desired chart direction [rtl: for right to left ,ltr: for left to right]
+			if(dir == "rtl" || dir == "ltr"){
+				if(this.dir != dir){
+					this.isMirrored = true;
+				}
+				this.dir = dir;
+			}
+			return this; 
+		},
+		isRightToLeft: function(){
+			// summary:
+			//		check the Direction of the chart.
+			// description:
+			//		check the chartBaseDirection attribute to determine the rendering direction
+			//		of the chart.
+			return this.dir == "rtl";
+        }
+	});
+});
+
diff --git a/dojox/charting/bidi/_bidiutils.js b/dojox/charting/bidi/_bidiutils.js
new file mode 100644
index 0000000..e0ccf5f
--- /dev/null
+++ b/dojox/charting/bidi/_bidiutils.js
@@ -0,0 +1,27 @@
+  define ({
+		reverseMatrix: function(plot, dim, offsets, rtl){
+			//summary:
+			//	reverse the underlying matrix of the plots to perform the mirroring behavior.
+			//plot:
+			//  the plot which has the matrix to be reversed.
+			//dim:
+			//  the dimension (width,height) of the chart.
+			//offsets:
+			//  the offsets of the chart
+			var shift = offsets.l - offsets.r;
+			var xx = rtl? -1 : 1;
+			var xy = 0;
+			var yx = 0;
+			var yy = 1;
+			var dx = rtl? dim.width + shift : 0;
+			var dy = 0;
+			if(plot.matrix){
+				xx = xx * Math.abs(plot.matrix.xx);
+				yy = plot.matrix.yy;
+				xy = plot.matrix.xy;
+				yx = plot.matrix.yx;
+				dy = plot.matrix.xy;
+			}
+			plot.setTransform({xx: xx, xy: xy, yx: yx, yy: yy, dx: dx, dy: dy});
+ 	}
+ });
diff --git a/dojox/charting/bidi/action2d/Tooltip.js b/dojox/charting/bidi/action2d/Tooltip.js
new file mode 100644
index 0000000..e5400bc
--- /dev/null
+++ b/dojox/charting/bidi/action2d/Tooltip.js
@@ -0,0 +1,45 @@
+define(["dojo/_base/declare", "dojo/dom-style"],
+	function(declare, domStyle){
+	// module:
+	//		dojox/charting/bidi/action2d/Tooltip		
+	return declare(null, {
+		_recheckPosition: function(obj,rect,position){
+			if(!this.chart.isRightToLeft()){
+				return;
+			}
+			var shift = this.chart.offsets.l - this.chart.offsets.r;
+			if(obj.element == "marker"){
+				rect.x = this.chart.dim.width - obj.cx + shift;
+				position[0] = "before-centered";
+				position[1] = "after-centered";
+			}
+			else if(obj.element == "circle"){
+				rect.x = this.chart.dim.width - obj.cx - obj.cr + shift;
+			}
+			else if(obj.element == "bar" || obj.element == "column"){
+				rect.x = this.chart.dim.width - rect.width - rect.x + shift;
+				if(obj.element == "bar"){
+					position[0] = "before-centered";
+					position[1] = "after-centered";
+				}
+			}
+			else if(obj.element == "candlestick"){
+				rect.x = this.chart.dim.width + shift - obj.x;
+			}
+		},
+		
+		_format: function(tooltip){
+			var isChartDirectionRtl = (domStyle.get(this.chart.node, "direction") == "rtl");
+			var isBaseTextDirRtl = (this.chart.getTextDir(tooltip) == "rtl");
+			if(isBaseTextDirRtl && !isChartDirectionRtl){
+				return "<span dir = 'rtl'>" + tooltip +"</span>";
+			}
+			else if(!isBaseTextDirRtl && isChartDirectionRtl){
+				return "<span dir = 'ltr'>" + tooltip +"</span>";
+			}else{
+				return tooltip;
+			}
+		}
+	});
+});
+
diff --git a/dojox/charting/bidi/action2d/ZoomAndPan.js b/dojox/charting/bidi/action2d/ZoomAndPan.js
new file mode 100644
index 0000000..586dae3
--- /dev/null
+++ b/dojox/charting/bidi/action2d/ZoomAndPan.js
@@ -0,0 +1,11 @@
+define(["dojo/_base/declare"],
+	function(declare){
+	// module:
+	//		dojox/charting/bidi/action2d/ZoomAndPan	
+	return declare(null, {
+		_getDelta: function(event){
+			var delta = this.inherited(arguments);
+			return delta * (this.chart.isRightToLeft()? -1 : 1);				
+		}
+	});
+});
diff --git a/dojox/charting/bidi/axis2d/Default.js b/dojox/charting/bidi/axis2d/Default.js
new file mode 100644
index 0000000..db8ce74
--- /dev/null
+++ b/dojox/charting/bidi/axis2d/Default.js
@@ -0,0 +1,27 @@
+define(["dojo/_base/declare", "dojo/dom-style"],
+	function(declare, domStyle){
+	// module:
+	//		dojox/charting/bidi/axis2d/Default			
+	return declare(null, {
+		labelTooltip: function(elem, chart, label, truncatedLabel, font, elemType){
+			// additional preprocessing of the labels, needed for rtl base text direction in LTR
+			// GUI, or for ltr base text direction for RTL GUI.
+
+			var isChartDirectionRtl = (domStyle.get(chart.node,"direction") == "rtl");
+			var isBaseTextDirRtl = (chart.getTextDir(label) == "rtl");
+
+			if(isBaseTextDirRtl && !isChartDirectionRtl){
+				label = "<span dir='rtl'>" + label +"</span>";
+			}
+			if(!isBaseTextDirRtl && isChartDirectionRtl){
+				label = "<span dir='ltr'>" + label +"</span>";
+			}
+			this.inherited(arguments);
+		},
+		
+		_isRtl: function(){
+			return this.chart.isRightToLeft();
+		}
+	});
+});
+
diff --git a/dojox/charting/bidi/widget/Chart.js b/dojox/charting/bidi/widget/Chart.js
new file mode 100644
index 0000000..8691b44
--- /dev/null
+++ b/dojox/charting/bidi/widget/Chart.js
@@ -0,0 +1,29 @@
+define(["dojo/_base/declare"],
+	function(declare){
+	// module:
+	//		dojox/charting/bidi/widget/Chart						
+	function validateTextDir(textDir){
+		return /^(ltr|rtl|auto)$/.test(textDir) ? textDir : null;
+	}
+	
+	return declare(null, {
+		postMixInProperties: function(){
+			// set initial textDir of the chart, if passed in the creation use that value
+			// else use default value, following the GUI direction, this.chart doesn't exist yet
+			// so can't use set("textDir", textDir). This passed to this.chart in it's future creation.
+			this.textDir = this.params["textDir"] ? this.params["textDir"] : this.params["dir"];
+		},
+	
+		_setTextDirAttr: function(/*String*/ textDir){
+			if(validateTextDir(textDir) != null){
+				this._set("textDir", textDir);
+				this.chart.setTextDir(textDir);
+			}
+		},
+		
+		_setDirAttr: function(/*String*/ dir){
+			this._set("dir", dir);
+			this.chart.setDir(dir);			
+		}
+	});	
+});
diff --git a/dojox/charting/bidi/widget/Legend.js b/dojox/charting/bidi/widget/Legend.js
new file mode 100644
index 0000000..e572a3f
--- /dev/null
+++ b/dojox/charting/bidi/widget/Legend.js
@@ -0,0 +1,63 @@
+define(["dojo/_base/declare", "dojo/dom", "dijit/registry", "dojo/_base/connect", "dojo/_base/array", "dojo/query"],
+	function(declare, dom, widgetManager, hub, arrayUtil, query){
+	// module:
+	//		dojox/charting/bidi/widget/Legend	
+	function validateTextDir(textDir){
+		return /^(ltr|rtl|auto)$/.test(textDir) ? textDir : null;
+	}
+	
+	return declare(null, {
+		postMixInProperties: function(){
+			// summary:
+			//		Connect the setter of textDir legend to setTextDir of the chart,
+			//		so _setTextDirAttr of the legend will be called after setTextDir of the chart is called.
+			// tags:
+			//		private
+
+			// find the chart that is the owner of this legend, use it's
+			// textDir
+			if(!this.chart){
+				if(!this.chartRef){ return; }
+				var chart = widgetManager.byId(this.chartRef);
+				if(!chart){
+					var node = dom.byId(this.chartRef);
+					if(node){
+						chart = widgetManager.byNode(node);
+					}else{
+						return;
+					}
+				}
+				this.textDir = chart.chart.textDir;
+				hub.connect(chart.chart, "setTextDir", this, "_setTextDirAttr");
+
+			}else{
+				this.textDir = this.chart.textDir;
+				hub.connect(this.chart, "setTextDir", this, "_setTextDirAttr");
+
+			}
+		},
+
+		_setTextDirAttr: function(/*String*/ textDir){
+			// summary:
+			//		Setter for textDir.
+			// description:
+			//		Users shouldn't call this function; they should be calling
+			//		set('textDir', value)
+			// tags:
+			//		private
+
+			// only if new textDir is different from the old one
+			if(validateTextDir(textDir) != null){
+				if(this.textDir != textDir){
+					this._set("textDir", textDir);
+					// get array of all the labels
+					var legendLabels = query(".dojoxLegendText", this._tr);
+						// for every label calculate it's new dir.
+						arrayUtil.forEach(legendLabels, function(label){
+							label.dir = this.getTextDir(label.innerHTML, label.dir);
+					}, this);
+				}
+			}
+		}
+	});	
+});
diff --git a/dojox/charting/plot2d/Areas.js b/dojox/charting/plot2d/Areas.js
index ca9e8a8..39e3a92 100644
--- a/dojox/charting/plot2d/Areas.js
+++ b/dojox/charting/plot2d/Areas.js
@@ -1,12 +1,12 @@
 define(["dojo/_base/declare", "./Default"], 
   function(declare, Default){
-/*=====
-var Default = dojox.charting.plot2d.Default;
-=====*/
+
 	return declare("dojox.charting.plot2d.Areas", Default, {
-		//	summary:
-		//		Represents an area chart.  See dojox.charting.plot2d.Default for details.
+		// summary:
+		//		Represents an area chart.  See dojox/charting/plot2d/Default for details.
 		constructor: function(){
+			// summary:
+			//		The constructor for an Area chart.
 			this.opt.lines = true;
 			this.opt.areas = true;
 		}
diff --git a/dojox/charting/plot2d/Bars.js b/dojox/charting/plot2d/Bars.js
index aeb9a75..2c797ec 100644
--- a/dojox/charting/plot2d/Bars.js
+++ b/dojox/charting/plot2d/Bars.js
@@ -1,35 +1,65 @@
-define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Base", "./common", 
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/has", "./CartesianBase", "./_PlotEvents", "./common",
 	"dojox/gfx/fx", "dojox/lang/utils", "dojox/lang/functional", "dojox/lang/functional/reversed"], 
-	function(dojo, lang, arr, declare, Base, dc, fx, du, df, dfr){
+	function(lang, arr, declare, has, CartesianBase, _PlotEvents, dc, fx, du, df, dfr){
 		
 	/*=====
-	dojo.declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
-		//	summary:
+	declare("dojox.charting.plot2d.__BarCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
+		// summary:
 		//		Additional keyword arguments for bar charts.
 	
-		//	minBarSize: Number?
+		// minBarSize: Number?
 		//		The minimum size for a bar in pixels.  Default is 1.
 		minBarSize: 1,
 	
-		//	maxBarSize: Number?
+		// maxBarSize: Number?
 		//		The maximum size for a bar in pixels.  Default is 1.
 		maxBarSize: 1,
+
+		// stroke: dojox.gfx.Stroke?
+		//		An optional stroke to use for any series on the plot.
+		stroke:		{},
+
+		// outline: dojox.gfx.Stroke?
+		//		An optional stroke used to outline any series on the plot.
+		outline:	{},
+
+		// shadow: dojox.gfx.Stroke?
+		//		An optional stroke to use to draw any shadows for a series on a plot.
+		shadow:		{},
+
+		// fill: dojox.gfx.Fill?
+		//		Any fill to be used for elements on the plot.
+		fill:		{},
+
+		// filter: dojox.gfx.Filter?
+	 	//		An SVG filter to be used for elements on the plot. gfx SVG renderer must be used and dojox/gfx/svgext must
+	 	//		be required for this to work.
+	 	filter:		{},
+
+		// styleFunc: Function?
+		//		A function that returns a styling object for the a given data item.
+		styleFunc:	null,
+
+		// font: String?
+		//		A font definition to be used for labels and other text-based elements on the plot.
+		font:		"",
+
+		// fontColor: String|dojo.Color?
+		//		The color to be used for any text-based elements on the plot.
+		fontColor:	"",
 		
-		//	enableCache: Boolean?
+		// enableCache: Boolean?
 		//		Whether the bars rect are cached from one rendering to another. This improves the rendering performance of
 		//		successive rendering but penalize the first rendering.  Default false.
 		enableCache: false
 	});
-	var Base = dojox.charting.plot2d.Base;
 	=====*/
 	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
-	return declare("dojox.charting.plot2d.Bars", Base, {
-		//	summary:
+	return declare("dojox.charting.plot2d.Bars", [CartesianBase, _PlotEvents], {
+		// summary:
 		//		The plot object representing a bar chart (horizontal bars).
 		defaultParams: {
-			hAxis: "x",		// use a horizontal axis named "x"
-			vAxis: "y",		// use a vertical axis named "y"
 			gap:	0,		// gap between columns in pixels
 			animate: null,   // animate bars into place
 			enableCache: false
@@ -42,37 +72,36 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/
 			outline:	{},
 			shadow:		{},
 			fill:		{},
+			filter:	    {},
+			styleFunc:  null,
 			font:		"",
 			fontColor:	""
 		},
 
 		constructor: function(chart, kwArgs){
-			//	summary:
+			// summary:
 			//		The constructor for a bar chart.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this plot belongs to.
-			//	kwArgs: dojox.charting.plot2d.__BarCtorArgs?
+			// kwArgs: dojox.charting.plot2d.__BarCtorArgs?
 			//		An optional keyword arguments object to help define the plot.
-			this.opt = lang.clone(this.defaultParams);
+			this.opt = lang.clone(lang.mixin(this.opt, this.defaultParams));
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
-			this.series = [];
-			this.hAxis = this.opt.hAxis;
-			this.vAxis = this.opt.vAxis;
 			this.animate = this.opt.animate;
 		},
 
 		getSeriesStats: function(){
-			//	summary:
+			// summary:
 			//		Calculate the min/max on all attached series in both directions.
-			//	returns: Object
+			// returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
 			var stats = dc.collectSimpleStats(this.series), t;
 			stats.hmin -= 0.5;
 			stats.hmax += 0.5;
 			t = stats.hmin, stats.hmin = stats.vmin, stats.vmin = t;
 			t = stats.hmax, stats.hmax = stats.vmax, stats.vmax = t;
-			return stats;
+			return stats; // Object
 		},
 		
 		createRect: function(run, creator, params){
@@ -91,36 +120,46 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/
 			return rect;
 		},
 
+		createLabel: function(group, value, bbox, theme){
+			if(this.opt.labels && this.opt.labelStyle == "outside"){
+				var y = bbox.y + bbox.height / 2;
+				var x = bbox.x + bbox.width + this.opt.labelOffset;
+				this.renderLabel(group, x, y, this._getLabel(isNaN(value.y)?value:value.y), theme, "start");
+          	}else{
+				this.inherited(arguments);
+			}
+		},
+
 		render: function(dim, offsets){
-			//	summary:
+			// summary:
 			//		Run the calculations for any axes for this plot.
-			//	dim: Object
+			// dim: Object
 			//		An object in the form of { width, height }
-			//	offsets: Object
+			// offsets: Object
 			//		An object of the form { l, r, t, b}.
-			//	returns: dojox.charting.plot2d.Bars
+			// returns: dojox/charting/plot2d/Bars
 			//		A reference to this plot for functional chaining.
 			if(this.zoom && !this.isDataDirty()){
-				return this.performZoom(dim, offsets);
+				return this.performZoom(dim, offsets); // dojox/charting/plot2d/Bars
 			}
 			this.dirty = this.isDirty();
 			this.resetEvents();
+			var s;
 			if(this.dirty){
 				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
-				var s = this.group;
+				s = this.getGroup();
 				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
 			}
-			var t = this.chart.theme, f, gap, height,
+			var t = this.chart.theme,
 				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
 				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
 				baseline = Math.max(0, this._hScaler.bounds.lower),
 				baselineWidth = ht(baseline),
 				events = this.events();
-			f = dc.calculateBarSize(this._vScaler.bounds.scale, this.opt);
-			gap = f.gap;
-			height = f.size;
+			var bar = this.getBarProperties();
+			
 			for(var i = this.series.length - 1; i >= 0; --i){
 				var run = this.series[i];
 				if(!this.dirty && !run.dirty){
@@ -133,27 +172,55 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/
 					run._rectFreePool = (run._rectFreePool?run._rectFreePool:[]).concat(run._rectUsePool?run._rectUsePool:[]);
 					run._rectUsePool = [];
 				}
-				var theme = t.next("bar", [this.opt, run]), s = run.group,
+				var theme = t.next("bar", [this.opt, run]),
 					eventSeries = new Array(run.data.length);
-				for(var j = 0; j < run.data.length; ++j){
+				s = run.group;
+				var indexed = arr.some(run.data, function(item){
+					return typeof item == "number" || (item && !item.hasOwnProperty("x"));
+				});
+				// on indexed charts we can easily just interate from the first visible to the last visible
+				// data point to save time
+				var min = indexed?Math.max(0, Math.floor(this._vScaler.bounds.from - 1)):0;
+				var max = indexed?Math.min(run.data.length, Math.ceil(this._vScaler.bounds.to)):run.data.length;
+				for(var j = min; j < max; ++j){
 					var value = run.data[j];
-					if(value !== null){
-						var v = typeof value == "number" ? value : value.y,
-							hv = ht(v),
-							width = hv - baselineWidth,
-							w = Math.abs(width),
-							finalTheme = typeof value != "number" ?
-								t.addMixin(theme, "bar", value, true) :
-								t.post(theme, "bar");
-						if(w >= 0 && height >= 1){
+					if(value != null){
+						var val = this.getValue(value, j, i, indexed),
+							hv = ht(val.y),
+							w = Math.abs(hv - baselineWidth),
+							finalTheme,
+							sshape;
+						if(this.opt.styleFunc || typeof value != "number"){
+							var tMixin = typeof value != "number" ? [value] : [];
+							if(this.opt.styleFunc){
+								tMixin.push(this.opt.styleFunc(value));
+							}
+							finalTheme = t.addMixin(theme, "bar", tMixin, true);
+						}else{
+							finalTheme = t.post(theme, "bar");
+						}
+						if(w >= 0 && bar.height >= 1){
 							var rect = {
-								x: offsets.l + (v < baseline ? hv : baselineWidth),
-								y: dim.height - offsets.b - vt(j + 1.5) + gap,
-								width: w, height: height
+								x: offsets.l + (val.y < baseline ? hv : baselineWidth),
+								y: dim.height - offsets.b - vt(val.x + 1.5) + bar.gap + bar.thickness * (this.series.length - i - 1),
+								width: w,
+								height: bar.height
 							};
+							if(finalTheme.series.shadow){
+								var srect = lang.clone(rect);
+								srect.x += finalTheme.series.shadow.dx;
+								srect.y += finalTheme.series.shadow.dy;
+								sshape = this.createRect(run, s, srect).setFill(finalTheme.series.shadow.color).setStroke(finalTheme.series.shadow);
+								if(this.animate){
+									this._animateBar(sshape, offsets.l + baselineWidth, -w);
+								}
+							}
 							var specialFill = this._plotFill(finalTheme.series.fill, dim, offsets);
 							specialFill = this._shapeFill(specialFill, rect);
 							var shape = this.createRect(run, s, rect).setFill(specialFill).setStroke(finalTheme.series.stroke);
+							if(shape.setFilter && finalTheme.series.filter){
+								shape.setFilter(finalTheme.series.filter);
+							}
 							run.dyn.fill   = shape.getFill();
 							run.dyn.stroke = shape.getStroke();
 							if(events){
@@ -162,12 +229,22 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/
 									index:   j,
 									run:     run,
 									shape:   shape,
-									x:       v,
-									y:       j + 1.5
+									shadow:	 sshape,
+									cx:      val.y,
+									cy:      val.x + 1.5,
+									x:	     indexed?j:run.data[j].x,
+									y:	 	 indexed?run.data[j]:run.data[j].y
 								};
 								this._connectEvents(o);
 								eventSeries[j] = o;
 							}
+							// if val.py is here, this means we are stacking and we need to subtract previous
+							// value to get the high in which we will lay out the label
+							if(!isNaN(val.py) && val.py > baseline){
+								rect.x += ht(val.py);
+								rect.width -= ht(val.py);
+							}
+							this.createLabel(s, value, rect, finalTheme);
 							if(this.animate){
 								this._animateBar(shape, offsets.l + baselineWidth, -w);
 							}
@@ -178,9 +255,36 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/
 				run.dirty = false;
 			}
 			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.Bars
+			// chart mirroring starts
+			if(has("dojo-bidi")){
+				this._checkOrientation(this.group, dim, offsets);
+			}
+			// chart mirroring ends
+			return this;	//	dojox/charting/plot2d/Bars
+		},
+		getValue: function(value, j, seriesIndex, indexed){
+			var y, x;
+			if(indexed){
+				if(typeof value == "number"){
+					y = value;
+				}else{
+					y = value.y;
+				}
+				x = j;
+			}else{
+				y = value.y;
+				x = value.x -1;
+			}
+			return {y:y, x:x};
+		},
+		getBarProperties: function(){
+			var f = dc.calculateBarSize(this._vScaler.bounds.scale, this.opt);
+			return {gap: f.gap, height: f.size, thickness: 0};
 		},
 		_animateBar: function(shape, hoffset, hsize){
+			if(hsize==0){
+				hsize = 1;
+			}
 			fx.animateTransform(lang.delegate({
 				shape: shape,
 				duration: 1200,
diff --git a/dojox/charting/plot2d/Base.js b/dojox/charting/plot2d/Base.js
index 87e1674..c14bb0a 100644
--- a/dojox/charting/plot2d/Base.js
+++ b/dojox/charting/plot2d/Base.js
@@ -1,244 +1,161 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", 
-		"../Element", "./_PlotEvents", "dojo/_base/array",
-		"../scaler/primitive", "./common", "dojox/gfx/fx"],
-	function(lang, declare, hub, Element, PlotEvents, arr, primitive, common, fx){
+define(["dojo/_base/declare", "dojo/_base/array", "dojox/gfx",
+		"../Element", "./common", "../axis2d/common", "dojo/has"],
+	function(declare, arr, gfx, Element, common, ac, has){
 /*=====
-var Element = dojox.charting.Element;
-var PlotEvents = dojox.charting.plot2d._PlotEvents;
-dojox.charting.plot2d.__PlotCtorArgs = function(){
-	//	summary:
+dojox.charting.plot2d.__PlotCtorArgs = {
+	// summary:
 	//		The base keyword arguments object for plot constructors.
 	//		Note that the parameters for this may change based on the
 	//		specific plot type (see the corresponding plot type for
 	//		details).
-}
-=====*/
-return declare("dojox.charting.plot2d.Base", [Element, PlotEvents], {
-	constructor: function(chart, kwArgs){
-		//	summary:
-		//		Create a base plot for charting.
-		//	chart: dojox.chart.Chart
-		//		The chart this plot belongs to.
-		//	kwArgs: dojox.charting.plot2d.__PlotCtorArgs?
-		//		An optional arguments object to help define the plot.
-		this.zoom = null,
-		this.zoomQueue = [];	// zooming action task queue
-		this.lastWindow = {vscale: 1, hscale: 1, xoffset: 0, yoffset: 0};
-	},
-	clear: function(){
-		//	summary:
-		//		Clear out all of the information tied to this plot.
-		//	returns: dojox.charting.plot2d.Base
-		//		A reference to this plot for functional chaining.
-		this.series = [];
-		this._hAxis = null;
-		this._vAxis = null;
-		this.dirty = true;
-		return this;	//	dojox.charting.plot2d.Base
-	},
-	setAxis: function(axis){
-		//	summary:
-		//		Set an axis for this plot.
-		//	axis: dojox.charting.axis2d.Base
-		//		The axis to set.
-		//	returns: dojox.charting.plot2d.Base
-		//		A reference to this plot for functional chaining.
-		if(axis){
-			this[axis.vertical ? "_vAxis" : "_hAxis"] = axis;
-		}
-		return this;	//	dojox.charting.plot2d.Base
-	},
-	toPage: function(coord){
-		//	summary:
-		//		Compute page coordinates from plot axis data coordinates.
-		//	coord: Object?
-		//		The coordinates in plot axis data coordinate space. For cartesian charts that is of the following form:
-		//			`{ hAxisName: 50, vAxisName: 200 }`
-		//		If not provided return the tranform method instead of the result of the transformation.
-		//	returns: Object
-		//		The resulting page pixel coordinates. That is of the following form:
-		//			`{ x: 50, y: 200 }`
-		var ah = this._hAxis, av = this._vAxis, 
-			sh = ah.getScaler(), sv = av.getScaler(),  
-			th = sh.scaler.getTransformerFromModel(sh),
-			tv = sv.scaler.getTransformerFromModel(sv),
-			c = this.chart.getCoords(),
-			o = this.chart.offsets, dim = this.chart.dim;
-		var t = function(coord){
-			var r = {};
-			r.x = th(coord[ah.name]) + c.x + o.l;
-			r.y = c.y + dim.height - o.b - tv(coord[av.name]);
-			return r;
-		};
-		// if no coord return the function so that we can capture the current transforms
-		// and reuse them later on
-		return coord?t(coord):t;
-	},
-	toData: function(coord){
-		//	summary:
-		//		Compute plot axis data coordinates from page coordinates.
-		//	coord: Object
-		//		The pixel coordinate in page coordinate space. That is of the following form:
-		//			`{ x: 50, y: 200 }`
-		//		If not provided return the tranform method instead of the result of the transformation.
-		//	returns: Object
-		//		The resulting plot axis data coordinates. For cartesian charts that is of the following form:
-		//			`{ hAxisName: 50, vAxisName: 200 }`
-		var ah = this._hAxis, av = this._vAxis, 
-			sh = ah.getScaler(), sv = av.getScaler(),  
-			th = sh.scaler.getTransformerFromPlot(sh),
-			tv = sv.scaler.getTransformerFromPlot(sv),
-			c = this.chart.getCoords(),
-			o = this.chart.offsets, dim = this.chart.dim;
-		var t = function(coord){
-			var r = {};
-			r[ah.name] = th(coord.x - c.x - o.l);
-			r[av.name] = tv(c.y + dim.height - coord.y  - o.b);
-			return r;
-		};
-		// if no coord return the function so that we can capture the current transforms
-		// and reuse them later on
-		return coord?t(coord):t;
-	},
-	addSeries: function(run){
-		//	summary:
-		//		Add a data series to this plot.
-		//	run: dojox.charting.Series
-		//		The series to be added.
-		//	returns: dojox.charting.plot2d.Base
-		//		A reference to this plot for functional chaining.
-		this.series.push(run);
-		return this;	//	dojox.charting.plot2d.Base
-	},
-	getSeriesStats: function(){
-		//	summary:
-		//		Calculate the min/max on all attached series in both directions.
-		//	returns: Object
-		//		{hmin, hmax, vmin, vmax} min/max in both directions.
-		return common.collectSimpleStats(this.series);
-	},
-	calculateAxes: function(dim){
-		//	summary:
-		//		Stub function for running the axis calculations (depricated).
-		//	dim: Object
-		//		An object of the form { width, height }
-		//	returns: dojox.charting.plot2d.Base
-		//		A reference to this plot for functional chaining.
-		this.initializeScalers(dim, this.getSeriesStats());
-		return this;	//	dojox.charting.plot2d.Base
-	},
-	isDirty: function(){
-		//	summary:
-		//		Returns whether or not this plot needs to be rendered.
-		//	returns: Boolean
-		//		The state of the plot.
-		return this.dirty || this._hAxis && this._hAxis.dirty || this._vAxis && this._vAxis.dirty;	//	Boolean
-	},
-	isDataDirty: function(){
-		//	summary:
-		//		Returns whether or not any of this plot's data series need to be rendered.
-		//	returns: Boolean
-		//		Flag indicating if any of this plot's series are invalid and need rendering.
-		return arr.some(this.series, function(item){ return item.dirty; });	//	Boolean
-	},
-	performZoom: function(dim, offsets){
-		//	summary:
-		//		Create/alter any zooming windows on this plot.
-		//	dim: Object
-		//		An object of the form { width, height }.
-		//	offsets: Object
-		//		An object of the form { l, r, t, b }.
-		//	returns: dojox.charting.plot2d.Base
-		//		A reference to this plot for functional chaining.
-
-		// get current zooming various
-		var vs = this._vAxis.scale || 1,
-			hs = this._hAxis.scale || 1,
-			vOffset = dim.height - offsets.b,
-			hBounds = this._hScaler.bounds,
-			xOffset = (hBounds.from - hBounds.lower) * hBounds.scale,
-			vBounds = this._vScaler.bounds,
-			yOffset = (vBounds.from - vBounds.lower) * vBounds.scale,
-			// get incremental zooming various
-			rVScale = vs / this.lastWindow.vscale,
-			rHScale = hs / this.lastWindow.hscale,
-			rXOffset = (this.lastWindow.xoffset - xOffset)/
-				((this.lastWindow.hscale == 1)? hs : this.lastWindow.hscale),
-			rYOffset = (yOffset - this.lastWindow.yoffset)/
-				((this.lastWindow.vscale == 1)? vs : this.lastWindow.vscale),
 
-			shape = this.group,
-			anim = fx.animateTransform(lang.delegate({
-				shape: shape,
-				duration: 1200,
-				transform:[
-					{name:"translate", start:[0, 0], end: [offsets.l * (1 - rHScale), vOffset * (1 - rVScale)]},
-					{name:"scale", start:[1, 1], end: [rHScale, rVScale]},
-					{name:"original"},
-					{name:"translate", start: [0, 0], end: [rXOffset, rYOffset]}
-				]}, this.zoom));
-
-		lang.mixin(this.lastWindow, {vscale: vs, hscale: hs, xoffset: xOffset, yoffset: yOffset});
-		//add anim to zooming action queue,
-		//in order to avoid several zooming action happened at the same time
-		this.zoomQueue.push(anim);
-		//perform each anim one by one in zoomQueue
-		hub.connect(anim, "onEnd", this, function(){
-			this.zoom = null;
-			this.zoomQueue.shift();
-			if(this.zoomQueue.length > 0){
-				this.zoomQueue[0].play();
+	// tooltipFunc: Function?
+	//		An optional function used to compute tooltip text for this plot. It takes precedence over
+	//		the default function when available.
+	//	|		function tooltipFunc(o) { return "text"; }
+	//		`o`is the event object that triggered the tooltip.
+	tooltipFunc: null
+};
+=====*/
+	var Base = declare("dojox.charting.plot2d.Base", Element, {
+		// summary:
+		//		Base class for all plot types.
+		constructor: function(chart, kwArgs){
+			// summary:
+			//		Create a base plot for charting.
+			// chart: dojox/chart/Chart
+			//		The chart this plot belongs to.
+			// kwArgs: dojox.charting.plot2d.__PlotCtorArgs?
+			//		An optional arguments object to help define the plot.
+	
+			// TODO does not work in markup
+			if(kwArgs && kwArgs.tooltipFunc){
+				this.tooltipFunc = kwArgs.tooltipFunc;
 			}
-		});
-		if(this.zoomQueue.length == 1){
-			this.zoomQueue[0].play();
-		}
-		return this;	//	dojox.charting.plot2d.Base
-	},
-	render: function(dim, offsets){
-		//	summary:
-		//		Render the plot on the chart.
-		//	dim: Object
-		//		An object of the form { width, height }.
-		//	offsets: Object
-		//		An object of the form { l, r, t, b }.
-		//	returns: dojox.charting.plot2d.Base
-		//		A reference to this plot for functional chaining.
-		return this;	//	dojox.charting.plot2d.Base
-	},
-	getRequiredColors: function(){
-		//	summary:
-		//		Get how many data series we have, so we know how many colors to use.
-		//	returns: Number
-		//		The number of colors needed.
-		return this.series.length;	//	Number
-	},
-	initializeScalers: function(dim, stats){
-		//	summary:
-		//		Initializes scalers using attached axes.
-		//	dim: Object:
-		//		Size of a plot area in pixels as {width, height}.
-		//	stats: Object:
-		//		Min/max of data in both directions as {hmin, hmax, vmin, vmax}.
-		//	returns: dojox.charting.plot2d.Base
-		//		A reference to this plot for functional chaining.
-		if(this._hAxis){
-			if(!this._hAxis.initialized()){
-				this._hAxis.calculate(stats.hmin, stats.hmax, dim.width);
+		},
+		clear: function(){
+			// summary:
+			//		Clear out all of the information tied to this plot.
+			// returns: dojox.charting.plot2d.Base
+			//		A reference to this plot for functional chaining.
+			this.series = [];
+			this.dirty = true;
+			return this;	//	dojox/charting/plot2d/Base
+		},
+		setAxis: function(axis){
+			// summary:
+			//		Set an axis for this plot.
+			// axis: dojox.charting.axis2d.Base
+			//		The axis to set.
+			// returns: dojox/charting/plot2d/Base
+			//		A reference to this plot for functional chaining.
+			return this;	//	dojox/charting/plot2d/Base
+		},
+		assignAxes: function(axes){
+			// summary:
+			//		From an array of axes pick the ones that correspond to this plot and
+			//		assign them to the plot using setAxis method.
+			// axes: Array
+			//		An array of dojox/charting/axis2d/Base
+			// tags:
+			//		protected
+			arr.forEach(this.axes, function(axis){
+				if(this[axis]){
+					this.setAxis(axes[this[axis]]);
+				}
+			}, this);
+		},
+		addSeries: function(run){
+			// summary:
+			//		Add a data series to this plot.
+			// run: dojox.charting.Series
+			//		The series to be added.
+			// returns: dojox/charting/plot2d/Base
+			//		A reference to this plot for functional chaining.
+			this.series.push(run);
+			return this;	//	dojox/charting/plot2d/Base
+		},
+		getSeriesStats: function(){
+			// summary:
+			//		Calculate the min/max on all attached series in both directions.
+			// returns: Object
+			//		{hmin, hmax, vmin, vmax} min/max in both directions.
+			return common.collectSimpleStats(this.series);
+		},
+		calculateAxes: function(dim){
+			// summary:
+			//		Stub function for running the axis calculations (deprecated).
+			// dim: Object
+			//		An object of the form { width, height }
+			// returns: dojox/charting/plot2d/Base
+			//		A reference to this plot for functional chaining.
+			this.initializeScalers(dim, this.getSeriesStats());
+			return this;	//	dojox/charting/plot2d/Base
+		},
+		initializeScalers: function(){
+			// summary:
+			//		Does nothing.
+			return this;
+		},
+		isDataDirty: function(){
+			// summary:
+			//		Returns whether or not any of this plot's data series need to be rendered.
+			// returns: Boolean
+			//		Flag indicating if any of this plot's series are invalid and need rendering.
+			return arr.some(this.series, function(item){ return item.dirty; });	//	Boolean
+		},
+		render: function(dim, offsets){
+			// summary:
+			//		Render the plot on the chart.
+			// dim: Object
+			//		An object of the form { width, height }.
+			// offsets: Object
+			//		An object of the form { l, r, t, b }.
+			// returns: dojox/charting/plot2d/Base
+			//		A reference to this plot for functional chaining.
+			return this;	//	dojox/charting/plot2d/Base
+		},
+		renderLabel: function(group, x, y, label, theme, block, align){
+			var elem = ac.createText[this.opt.htmlLabels && gfx.renderer != "vml" ? "html" : "gfx"]
+				(this.chart, group, x, y, align?align:"middle", label, theme.series.font, theme.series.fontColor);
+			// if the label is inside we need to avoid catching events on it this would prevent action on
+			// chart elements
+			if(block){
+				// TODO this won't work in IE neither in VML nor in HTML
+				// a solution would be to catch the event on the label and refire it to the element
+				// possibly using elementFromPoint or having it already available
+				if(this.opt.htmlLabels && gfx.renderer != "vml"){
+					// we have HTML labels, let's use pointEvents on the HTML node
+					elem.style.pointerEvents = "none";
+				}else if(elem.rawNode){
+					// we have SVG labels, let's use pointerEvents on the SVG or VML node
+					elem.rawNode.style.pointerEvents = "none";
+				}
+				// else we have Canvas, we need do nothing, as Canvas text won't catch events
 			}
-			this._hScaler = this._hAxis.getScaler();
-		}else{
-			this._hScaler = primitive.buildScaler(stats.hmin, stats.hmax, dim.width);
-		}
-		if(this._vAxis){
-			if(!this._vAxis.initialized()){
-				this._vAxis.calculate(stats.vmin, stats.vmax, dim.height);
+			if(this.opt.htmlLabels && gfx.renderer != "vml"){
+				this.htmlElements.push(elem);
 			}
-			this._vScaler = this._vAxis.getScaler();
-		}else{
-			this._vScaler = primitive.buildScaler(stats.vmin, stats.vmax, dim.height);
+
+			return elem;
+		},
+		getRequiredColors: function(){
+			// summary:
+			//		Get how many data series we have, so we know how many colors to use.
+			// returns: Number
+			//		The number of colors needed.
+			return this.series.length;	//	Number
+		},
+		_getLabel: function(number){
+			return common.getLabel(number, this.opt.fixed, this.opt.precision);
 		}
-		return this;	//	dojox.charting.plot2d.Base
+	});
+	if(has("dojo-bidi")){
+		Base.extend({
+			_checkOrientation: function(group, dim, offsets){
+				this.chart.applyMirroring(this.group, dim, offsets);
+			}		
+		});
 	}
-});
+	return Base;
 });
diff --git a/dojox/charting/plot2d/Bubble.js b/dojox/charting/plot2d/Bubble.js
index ae7ce3b..3a02042 100644
--- a/dojox/charting/plot2d/Bubble.js
+++ b/dojox/charting/plot2d/Bubble.js
@@ -1,20 +1,15 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", 
-		"./Base", "./common", "dojox/lang/functional", "dojox/lang/functional/reversed", 
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/has", 
+		"./CartesianBase", "./_PlotEvents", "./common", "dojox/lang/functional", "dojox/lang/functional/reversed",
 		"dojox/lang/utils", "dojox/gfx/fx"], 
-	function(lang, declare, arr, Base, dc, df, dfr, du, fx){
-/*=====
-var Base = dojox.charting.plot2d.Base;
-=====*/
+	function(lang, declare, arr, has, CartesianBase, _PlotEvents, dc, df, dfr, du, fx){
 
 	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
-	return declare("dojox.charting.plot2d.Bubble", Base, {
-		//	summary:
+	return declare("dojox.charting.plot2d.Bubble", [CartesianBase, _PlotEvents], {
+		// summary:
 		//		A plot representing bubbles.  Note that data for Bubbles requires 3 parameters,
 		//		in the form of:  { x, y, size }, where size determines the size of the bubble.
 		defaultParams: {
-			hAxis: "x",		// use a horizontal axis named "x"
-			vAxis: "y",		// use a vertical axis named "y"
 			animate: null   // animate bars into place
 		},
 		optionalParams: {
@@ -23,36 +18,41 @@ var Base = dojox.charting.plot2d.Base;
 			outline:	{},
 			shadow:		{},
 			fill:		{},
+			filter:     {},
+			styleFunc:	null,
 			font:		"",
 			fontColor:	""
 		},
 
 		constructor: function(chart, kwArgs){
-			//	summary:
+			// summary:
 			//		Create a plot of bubbles.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this plot belongs to.
-			//	kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
+			// kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
 			//		Optional keyword arguments object to help define plot parameters.
-			this.opt = lang.clone(this.defaultParams);
-            du.updateWithObject(this.opt, kwArgs);
-            du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
-            this.series = [];
-			this.hAxis = this.opt.hAxis;
-			this.vAxis = this.opt.vAxis;
+			this.opt = lang.clone(lang.mixin(this.opt, this.defaultParams));
+			du.updateWithObject(this.opt, kwArgs);
+			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+			if(!this.opt.labelFunc){
+				this.opt.labelFunc = function(value, fixed, precision){
+					return this._getLabel(value.size, fixed, precision);
+				};
+			}
 			this.animate = this.opt.animate;
 		},
 
 		//	override the render so that we are plotting only circles.
 		render: function(dim, offsets){
-			//	summary:
+			// summary:
 			//		Run the calculations for any axes for this plot.
-			//	dim: Object
+			// dim: Object
 			//		An object in the form of { width, height }
-			//	offsets: Object
+			// offsets: Object
 			//		An object of the form { l, r, t, b}.
-			//	returns: dojox.charting.plot2d.Bubble
+			// returns: dojox/charting/plot2d/Bubble
 			//		A reference to this plot for functional chaining.
+			var s;
 			if(this.zoom && !this.isDataDirty()){
 				return this.performZoom(dim, offsets);
 			}
@@ -62,7 +62,7 @@ var Base = dojox.charting.plot2d.Base;
 				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
-				var s = this.group;
+				s = this.getGroup();
 				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
 			}
 
@@ -90,8 +90,9 @@ var Base = dojox.charting.plot2d.Base;
 					continue;
 				}
 
-				var theme = t.next("circle", [this.opt, run]), s = run.group,
-					points = arr.map(run.data, function(v, i){
+				s = run.group;
+				var theme = t.next("circle", [this.opt, run]),
+					points = arr.map(run.data, function(v){
 						return v ? {
 							x: ht(v.x) + offsets.l,
 							y: dim.height - offsets.b - vt(v.y),
@@ -99,13 +100,20 @@ var Base = dojox.charting.plot2d.Base;
 						} : null;
 					}, this);
 
-				var frontCircles = null, outlineCircles = null, shadowCircles = null;
+				var frontCircles = null, outlineCircles = null, shadowCircles = null, styleFunc = this.opt.styleFunc;
+
+				var getFinalTheme = function(item){
+					if(styleFunc){
+						return t.addMixin(theme, "circle", [item, styleFunc(item)], true);
+					}
+					return t.addMixin(theme, "circle", item, true);
+				};
 
 				// make shadows if needed
 				if(theme.series.shadow){
-					shadowCircles = arr.map(points, function(item){
+					shadowCircles = arr.map(points, function(item, i){
 						if(item !== null){
-							var finalTheme = t.addMixin(theme, "circle", item, true),
+							var finalTheme = getFinalTheme(run.data[i]),
 								shadow = finalTheme.series.shadow;
 							var shape = s.createCircle({
 								cx: item.x + shadow.dx, cy: item.y + shadow.dy, r: item.radius
@@ -124,9 +132,9 @@ var Base = dojox.charting.plot2d.Base;
 
 				// make outlines if needed
 				if(theme.series.outline){
-					outlineCircles = arr.map(points, function(item){
+					outlineCircles = arr.map(points, function(item, i){
 						if(item !== null){
-							var finalTheme = t.addMixin(theme, "circle", item, true),
+							var finalTheme = getFinalTheme(run.data[i]),
 								outline = dc.makeStroke(finalTheme.series.outline);
 							outline.width = 2 * outline.width + theme.series.stroke.width;
 							var shape = s.createCircle({
@@ -145,9 +153,9 @@ var Base = dojox.charting.plot2d.Base;
 				}
 
 				//	run through the data and add the circles.
-				frontCircles = arr.map(points, function(item){
+				frontCircles = arr.map(points, function(item, i){
 					if(item !== null){
-						var finalTheme = t.addMixin(theme, "circle", item, true),
+						var finalTheme = getFinalTheme(run.data[i]),
 							rect = {
 								x: item.x - item.radius,
 								y: item.y - item.radius,
@@ -159,9 +167,13 @@ var Base = dojox.charting.plot2d.Base;
 						var shape = s.createCircle({
 							cx: item.x, cy: item.y, r: item.radius
 						}).setFill(specialFill).setStroke(finalTheme.series.stroke);
+						if(shape.setFilter && finalTheme.series.filter){
+							shape.setFilter(finalTheme.series.filter);
+						}
 						if(this.animate){
 							this._animateBubble(shape, dim.height - offsets.b, item.radius);
 						}
+						this.createLabel(s, run.data[i], rect, finalTheme);
 						return shape;
 					}
 					return null;
@@ -201,7 +213,12 @@ var Base = dojox.charting.plot2d.Base;
 				run.dirty = false;
 			}
 			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.Bubble
+			// chart mirroring starts
+			if(has("dojo-bidi")){
+				this._checkOrientation(this.group, dim, offsets);
+			}
+			// chart mirroring ends
+			return this;	//	dojox/charting/plot2d/Bubble
 		},
 		_animateBubble: function(shape, offset, size){
 			fx.animateTransform(lang.delegate({
diff --git a/dojox/charting/plot2d/Candlesticks.js b/dojox/charting/plot2d/Candlesticks.js
index 0235679..d15f183 100644
--- a/dojox/charting/plot2d/Candlesticks.js
+++ b/dojox/charting/plot2d/Candlesticks.js
@@ -1,9 +1,6 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "./Base", "./common", 
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/has", "./CartesianBase", "./_PlotEvents", "./common",
 		"dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/utils", "dojox/gfx/fx"], 
-	function(lang, declare, arr, Base, dc, df, dfr, du, fx){
-/*=====
-var Base = dojox.charting.plot2d.Base;
-=====*/
+	function(lang, declare, arr, has, CartesianBase, _PlotEvents, dc, df, dfr, du, fx){
 
 	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
@@ -12,16 +9,14 @@ var Base = dojox.charting.plot2d.Base;
 	//	{ x?, open, close, high, low, mid? }
 	//	if x is not provided, the array index is used.
 	//	failing to provide the OHLC values will throw an error.
-	return declare("dojox.charting.plot2d.Candlesticks", Base, {
-		//	summary:
+	return declare("dojox.charting.plot2d.Candlesticks", [CartesianBase, _PlotEvents], {
+		// summary:
 		//		A plot that represents typical candlesticks (financial reporting, primarily).
 		//		Unlike most charts, the Candlestick expects data points to be represented by
 		//		an object of the form { x?, open, close, high, low, mid? }, where both
 		//		x and mid are optional parameters.  If x is not provided, the index of the
 		//		data array is used.
 		defaultParams: {
-			hAxis: "x",		// use a horizontal axis named "x"
-			vAxis: "y",		// use a vertical axis named "y"
 			gap:	2,		// gap between columns in pixels
 			animate: null   // animate bars into place
 		},
@@ -38,29 +33,26 @@ var Base = dojox.charting.plot2d.Base;
 		},
 
 		constructor: function(chart, kwArgs){
-			//	summary:
+			// summary:
 			//		The constructor for a candlestick chart.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this plot belongs to.
-			//	kwArgs: dojox.charting.plot2d.__BarCtorArgs?
+			// kwArgs: dojox.charting.plot2d.__BarCtorArgs?
 			//		An optional keyword arguments object to help define the plot.
 			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
-			this.series = [];
-			this.hAxis = this.opt.hAxis;
-			this.vAxis = this.opt.vAxis;
 			this.animate = this.opt.animate;
 		},
 
 		collectStats: function(series){
-			//	summary:
+			// summary:
 			//		Collect all statistics for drawing this chart.  Since the common
 			//		functionality only assumes x and y, Candlesticks must create it's own
 			//		stats (since data has no y value, but open/close/high/low instead).
-			//	series: dojox.charting.Series[]
+			// series: dojox.charting.Series[]
 			//		The data series array to be drawn on this plot.
-			//	returns: Object
+			// returns: Object
 			//		Returns an object in the form of { hmin, hmax, vmin, vmax }.
 
 			//	we have to roll our own, since we need to use all four passed
@@ -88,42 +80,41 @@ var Base = dojox.charting.plot2d.Base;
 		},
 
 		getSeriesStats: function(){
-			//	summary:
+			// summary:
 			//		Calculate the min/max on all attached series in both directions.
-			//	returns: Object
+			// returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
 			var stats = this.collectStats(this.series);
 			stats.hmin -= 0.5;
 			stats.hmax += 0.5;
-			return stats;
+			return stats; // Object
 		},
 
 		render: function(dim, offsets){
-			//	summary:
+			// summary:
 			//		Run the calculations for any axes for this plot.
-			//	dim: Object
+			// dim: Object
 			//		An object in the form of { width, height }
-			//	offsets: Object
+			// offsets: Object
 			//		An object of the form { l, r, t, b}.
-			//	returns: dojox.charting.plot2d.Candlesticks
+			// returns: dojox/charting/plot2d/Candlesticks
 			//		A reference to this plot for functional chaining.
 			if(this.zoom && !this.isDataDirty()){
 				return this.performZoom(dim, offsets);
 			}
 			this.resetEvents();
 			this.dirty = this.isDirty();
+			var s;
 			if(this.dirty){
 				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
-				var s = this.group;
+				s = this.getGroup();
 				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
 			}
 			var t = this.chart.theme, f, gap, width,
 				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
 				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
-				baseline = Math.max(0, this._vScaler.bounds.lower),
-				baselineHeight = vt(baseline),
 				events = this.events();
 			f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt);
 			gap = f.gap;
@@ -136,7 +127,8 @@ var Base = dojox.charting.plot2d.Base;
 					continue;
 				}
 				run.cleanGroup();
-				var theme = t.next("candlestick", [this.opt, run]), s = run.group,
+				s = run.group;
+				var theme = t.next("candlestick", [this.opt, run]),
 					eventSeries = new Array(run.data.length);
 				for(var j = 0; j < run.data.length; ++j){
 					var v = run.data[j];
@@ -181,7 +173,7 @@ var Base = dojox.charting.plot2d.Base;
 								}).setStroke(doFill ? "white" : finalTheme.series.stroke);
 							}
 
-							//	TODO: double check this.
+							// TODO: double check this.
 							run.dyn.fill   = finalTheme.series.fill;
 							run.dyn.stroke = finalTheme.series.stroke;
 							if(events){
@@ -211,8 +203,24 @@ var Base = dojox.charting.plot2d.Base;
 				run.dirty = false;
 			}
 			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.Candlesticks
+			// chart mirroring starts
+			if(has("dojo-bidi")){
+				this._checkOrientation(this.group, dim, offsets);
+			}
+			// chart mirroring ends
+			return this;	//	dojox/charting/plot2d/Candlesticks
+		},
+
+		tooltipFunc: function(o){
+			return '<table cellpadding="1" cellspacing="0" border="0" style="font-size:0.9em;">'
+						+ '<tr><td>Open:</td><td align="right"><strong>' + o.data.open + '</strong></td></tr>'
+						+ '<tr><td>High:</td><td align="right"><strong>' + o.data.high + '</strong></td></tr>'
+						+ '<tr><td>Low:</td><td align="right"><strong>' + o.data.low + '</strong></td></tr>'
+						+ '<tr><td>Close:</td><td align="right"><strong>' + o.data.close + '</strong></td></tr>'
+						+ (o.data.mid !== undefined ? '<tr><td>Mid:</td><td align="right"><strong>' + o.data.mid + '</strong></td></tr>' : '')
+						+ '</table>';
 		},
+
 		_animateCandlesticks: function(shape, voffset, vsize){
 			fx.animateTransform(lang.delegate({
 				shape: shape,
diff --git a/dojox/charting/plot2d/CartesianBase.js b/dojox/charting/plot2d/CartesianBase.js
new file mode 100644
index 0000000..d7ba64a
--- /dev/null
+++ b/dojox/charting/plot2d/CartesianBase.js
@@ -0,0 +1,289 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/has",
+		"./Base", "../scaler/primitive", "dojox/gfx", "dojox/gfx/fx", "dojox/lang/utils"], 
+	function(lang, declare, hub, has, Base, primitive, gfx, fx, du){
+	/*=====
+	declare("dojox.charting.plot2d.__CartesianCtorArgs", dojox.charting.plot2d.__PlotCtorArgs, {
+		// hAxis: String?
+		//		The horizontal axis name.
+		hAxis: "x",
+
+		// vAxis: String?
+		//		The vertical axis name
+		vAxis: "y",
+
+		// labels: Boolean?
+		//		For plots that support labels, whether or not to draw labels for each data item.  Default is false.
+		labels:			false,
+
+		// fixed: Boolean?
+        //		Whether a fixed precision must be applied to data values for display. Default is true.
+		fixed:			true,
+
+		// precision: Number?
+        //		The precision at which to round data values for display. Default is 0.
+		precision:		1,
+
+		// labelOffset: Number?
+		//		The amount in pixels by which to offset labels when using "outside" labelStyle.  Default is 10.
+		labelOffset:	10,
+
+		// labelStyle: String?
+		//		Options as to where to draw labels.  This must be either "inside" or "outside". By default
+		//      the labels are drawn "inside" the shape representing the data point (a column rectangle for a Columns plot
+		//      or a marker for a Line plot for instance). When "outside" is used the labels are drawn above the data point shape.
+		labelStyle:		"inside",
+
+		// htmlLabels: Boolean?
+		//		Whether or not to use HTML to render slice labels. Default is true.
+		htmlLabels:		true,
+
+		// omitLabels: Boolean?
+		//		Whether labels that do not fit in an item render are omitted or not.	This applies only when labelStyle
+		//		is "inside".	Default is false.
+		omitLabels: true,
+
+		// labelFunc: Function?
+		//		An optional function to use to compute label text. It takes precedence over
+		//		the default text when available.
+		//	|		function labelFunc(value, fixed, precision) {}
+		//		`value` is the data value to display
+		//		`fixed` is true if fixed precision must be applied.
+		//		`precision` is the requested precision to be applied.
+		labelFunc: null
+	});
+	=====*/
+
+	return declare("dojox.charting.plot2d.CartesianBase", Base, {
+		baseParams: {
+			hAxis: 			"x",
+			vAxis: 			"y",
+			labels:			false,
+			labelOffset:    10,
+			fixed:			true,
+			precision:		1,
+			labelStyle:		"inside",
+			htmlLabels:		true,		// use HTML to draw labels
+			omitLabels:		true
+        },
+
+		// summary:
+		//		Base class for cartesian plot types.
+		constructor: function(chart, kwArgs){
+			// summary:
+			//		Create a cartesian base plot for cartesian charts.
+			// chart: dojox/chart/Chart
+			//		The chart this plot belongs to.
+			// kwArgs: dojox.charting.plot2d.__CartesianCtorArgs?
+			//		An optional arguments object to help define the plot.
+			this.axes = ["hAxis", "vAxis"];
+			this.zoom = null;
+			this.zoomQueue = [];	// zooming action task queue
+			this.lastWindow = {vscale: 1, hscale: 1, xoffset: 0, yoffset: 0};
+			this.hAxis = (kwArgs && kwArgs.hAxis) || "x";
+			this.vAxis = (kwArgs && kwArgs.vAxis) || "y";
+			this.series = [];
+			this.opt = lang.clone(this.baseParams);
+			du.updateWithObject(this.opt, kwArgs);
+		},
+		clear: function(){
+			// summary:
+			//		Clear out all of the information tied to this plot.
+			// returns: dojox/charting/plot2d/CartesianBase
+			//		A reference to this plot for functional chaining.
+			this.inherited(arguments);
+			this._hAxis = null;
+			this._vAxis = null;
+			return this;	//	dojox/charting/plot2d/CartesianBase
+		},
+		cleanGroup: function(creator, noClip){
+			this.inherited(arguments);
+			if(!noClip && this.chart._nativeClip){
+				var offsets = this.chart.offsets, dim = this.chart.dim;
+				var w = Math.max(0, dim.width  - offsets.l - offsets.r),
+					h = Math.max(0, dim.height - offsets.t - offsets.b);
+				this.group.setClip({ x: offsets.l, y: offsets.t, width: w, height: h });
+				if(!this._clippedGroup){
+					this._clippedGroup = this.group.createGroup();
+				}
+			}
+		},
+		purgeGroup: function(){
+			this.inherited(arguments);
+			this._clippedGroup = null;
+		},
+		getGroup: function(){
+			return this._clippedGroup || this.group;
+		},
+		setAxis: function(axis){
+			// summary:
+			//		Set an axis for this plot.
+			// axis: dojox/charting/axis2d/Base
+			//		The axis to set.
+			// returns: dojox/charting/plot2d/CartesianBase
+			//		A reference to this plot for functional chaining.
+			if(axis){
+				this[axis.vertical ? "_vAxis" : "_hAxis"] = axis;
+			}
+			return this;	//	dojox/charting/plot2d/CartesianBase
+		},
+		toPage: function(coord){
+			// summary:
+			//		Compute page coordinates from plot axis data coordinates.
+			// coord: Object?
+			//		The coordinates in plot axis data coordinate space. For cartesian charts that is of the following form:
+			//		`{ hAxisName: 50, vAxisName: 200 }`
+			//		If not provided return the transform method instead of the result of the transformation.
+			// returns: Object
+			//		The resulting page pixel coordinates. That is of the following form:
+			//		`{ x: 50, y: 200 }`
+			var ah = this._hAxis, av = this._vAxis,
+				sh = ah.getScaler(), sv = av.getScaler(),
+				th = sh.scaler.getTransformerFromModel(sh),
+				tv = sv.scaler.getTransformerFromModel(sv),
+				c = this.chart.getCoords(),
+				o = this.chart.offsets, dim = this.chart.dim;
+			var t = function(coord){
+				var r = {};
+				r.x = th(coord[ah.name]) + c.x + o.l;
+				r.y = c.y + dim.height - o.b - tv(coord[av.name]);
+				return r;
+			};
+			// if no coord return the function so that we can capture the current transforms
+			// and reuse them later on
+			return coord?t(coord):t; // Object
+		},
+		toData: function(coord){
+			// summary:
+			//		Compute plot axis data coordinates from page coordinates.
+			// coord: Object
+			//		The pixel coordinate in page coordinate space. That is of the following form:
+			//		`{ x: 50, y: 200 }`
+			//		If not provided return the tranform method instead of the result of the transformation.
+			// returns: Object
+			//		The resulting plot axis data coordinates. For cartesian charts that is of the following form:
+			//		`{ hAxisName: 50, vAxisName: 200 }`
+			var ah = this._hAxis, av = this._vAxis,
+				sh = ah.getScaler(), sv = av.getScaler(),
+				th = sh.scaler.getTransformerFromPlot(sh),
+				tv = sv.scaler.getTransformerFromPlot(sv),
+				c = this.chart.getCoords(),
+				o = this.chart.offsets, dim = this.chart.dim;
+			var t = function(coord){
+				var r = {};
+				r[ah.name] = th(coord.x - c.x - o.l);
+				r[av.name] = tv(c.y + dim.height - coord.y  - o.b);
+				return r;
+			};
+			// if no coord return the function so that we can capture the current transforms
+			// and reuse them later on
+			return coord?t(coord):t; // Object
+		},
+		isDirty: function(){
+			// summary:
+			//		Returns whether or not this plot needs to be rendered.
+			// returns: Boolean
+			//		The state of the plot.
+			return this.dirty || this._hAxis && this._hAxis.dirty || this._vAxis && this._vAxis.dirty;	//	Boolean
+		},
+		createLabel: function(group, value, bbox, theme){
+			if(this.opt.labels){
+				var x, y, label = this.opt.labelFunc?this.opt.labelFunc.apply(this, [value, this.opt.fixed, this.opt.precision]):
+					this._getLabel(isNaN(value.y)?value:value.y);
+				if(this.opt.labelStyle == "inside"){
+					var lbox = gfx._base._getTextBox(label, { font: theme.series.font } );
+					x = bbox.x + bbox.width / 2;
+					y = bbox.y + bbox.height / 2 + lbox.h / 4;
+					if(lbox.w > bbox.width || lbox.h > bbox.height){
+						return;
+					}
+
+				}else{
+					x = bbox.x + bbox.width / 2;
+					y = bbox.y - this.opt.labelOffset;
+				}
+				this.renderLabel(group, x, y, label, theme, this.opt.labelStyle == "inside");
+			}
+		},
+		performZoom: function(dim, offsets){
+			// summary:
+			//		Create/alter any zooming windows on this plot.
+			// dim: Object
+			//		An object of the form { width, height }.
+			// offsets: Object
+			//		An object of the form { l, r, t, b }.
+			// returns: dojox/charting/plot2d/CartesianBase
+			//		A reference to this plot for functional chaining.
+
+			// get current zooming various
+			var vs = this._vAxis.scale || 1,
+				hs = this._hAxis.scale || 1,
+				vOffset = dim.height - offsets.b,
+				hBounds = this._hScaler.bounds,
+				xOffset = (hBounds.from - hBounds.lower) * hBounds.scale,
+				vBounds = this._vScaler.bounds,
+				yOffset = (vBounds.from - vBounds.lower) * vBounds.scale,
+				// get incremental zooming various
+				rVScale = vs / this.lastWindow.vscale,
+				rHScale = hs / this.lastWindow.hscale,
+				rXOffset = (this.lastWindow.xoffset - xOffset)/
+					((this.lastWindow.hscale == 1)? hs : this.lastWindow.hscale),
+				rYOffset = (yOffset - this.lastWindow.yoffset)/
+					((this.lastWindow.vscale == 1)? vs : this.lastWindow.vscale),
+
+				shape = this.getGroup(),
+				anim = fx.animateTransform(lang.delegate({
+					shape: shape,
+					duration: 1200,
+					transform:[
+						{name:"translate", start:[0, 0], end: [offsets.l * (1 - rHScale), vOffset * (1 - rVScale)]},
+						{name:"scale", start:[1, 1], end: [rHScale, rVScale]},
+						{name:"original"},
+						{name:"translate", start: [0, 0], end: [rXOffset, rYOffset]}
+					]}, this.zoom));
+
+			lang.mixin(this.lastWindow, {vscale: vs, hscale: hs, xoffset: xOffset, yoffset: yOffset});
+			//add anim to zooming action queue,
+			//in order to avoid several zooming action happened at the same time
+			this.zoomQueue.push(anim);
+			//perform each anim one by one in zoomQueue
+			hub.connect(anim, "onEnd", this, function(){
+				this.zoom = null;
+				this.zoomQueue.shift();
+				if(this.zoomQueue.length > 0){
+					this.zoomQueue[0].play();
+				}
+			});
+			if(this.zoomQueue.length == 1){
+				this.zoomQueue[0].play();
+			}
+			return this;	//	dojox/charting/plot2d/CartesianBase
+		},
+		initializeScalers: function(dim, stats){
+			// summary:
+			//		Initializes scalers using attached axes.
+			// dim: Object
+			//		Size of a plot area in pixels as {width, height}.
+			// stats: Object
+			//		Min/max of data in both directions as {hmin, hmax, vmin, vmax}.
+			// returns: dojox/charting/plot2d/CartesianBase
+			//		A reference to this plot for functional chaining.
+			if(this._hAxis){
+				if(!this._hAxis.initialized()){
+					this._hAxis.calculate(stats.hmin, stats.hmax, dim.width);
+				}
+				this._hScaler = this._hAxis.getScaler();
+			}else{
+				this._hScaler = primitive.buildScaler(stats.hmin, stats.hmax, dim.width);
+			}
+			if(this._vAxis){
+				if(!this._vAxis.initialized()){
+					this._vAxis.calculate(stats.vmin, stats.vmax, dim.height);
+				}
+				this._vScaler = this._vAxis.getScaler();
+			}else{
+				this._vScaler = primitive.buildScaler(stats.vmin, stats.vmax, dim.height);
+			}
+			return this;	//	dojox/charting/plot2d/CartesianBase
+		}
+	});
+});
diff --git a/dojox/charting/plot2d/ClusteredBars.js b/dojox/charting/plot2d/ClusteredBars.js
index 2074a41..959b7a7 100644
--- a/dojox/charting/plot2d/ClusteredBars.js
+++ b/dojox/charting/plot2d/ClusteredBars.js
@@ -1,99 +1,12 @@
-define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Bars", "./common", 
-		"dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/utils"], 
-	function(lang, arr, declare, Bars, dc, df, dfr, du){
-/*=====
-var Bars = dojox.charting.plot2d.Bars;
-=====*/
-
-	var purgeGroup = dfr.lambda("item.purgeGroup()");
+define(["dojo/_base/declare", "./Bars", "./common"], 
+	function(declare, Bars, dc){
 
 	return declare("dojox.charting.plot2d.ClusteredBars", Bars, {
-		//	summary:
+		// summary:
 		//		A plot representing grouped or clustered bars (horizontal bars)
-		render: function(dim, offsets){
-			//	summary:
-			//		Run the calculations for any axes for this plot.
-			//	dim: Object
-			//		An object in the form of { width, height }
-			//	offsets: Object
-			//		An object of the form { l, r, t, b}.
-			//	returns: dojox.charting.plot2d.ClusteredBars
-			//		A reference to this plot for functional chaining.
-			if(this.zoom && !this.isDataDirty()){
-				return this.performZoom(dim, offsets);
-			}
-			this.resetEvents();
-			this.dirty = this.isDirty();
-			if(this.dirty){
-				arr.forEach(this.series, purgeGroup);
-				this._eventSeries = {};
-				this.cleanGroup();
-				var s = this.group;
-				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
-			}
-			var t = this.chart.theme, f, gap, height, thickness,
-				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
-				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
-				baseline = Math.max(0, this._hScaler.bounds.lower),
-				baselineWidth = ht(baseline),
-				events = this.events();
-			f = dc.calculateBarSize(this._vScaler.bounds.scale, this.opt, this.series.length);
-			gap = f.gap;
-			height = thickness = f.size;
-			for(var i = this.series.length - 1; i >= 0; --i){
-				var run = this.series[i], shift = thickness * (this.series.length - i - 1);
-				if(!this.dirty && !run.dirty){
-					t.skip();
-					this._reconnectEvents(run.name);
-					continue;
-				}
-				run.cleanGroup();
-				var theme = t.next("bar", [this.opt, run]), s = run.group,
-					eventSeries = new Array(run.data.length);
-				for(var j = 0; j < run.data.length; ++j){
-					var value = run.data[j];
-					if(value !== null){
-						var v = typeof value == "number" ? value : value.y,
-							hv = ht(v),
-							width = hv - baselineWidth,
-							w = Math.abs(width),
-							finalTheme = typeof value != "number" ?
-								t.addMixin(theme, "bar", value, true) :
-								t.post(theme, "bar");
-						if(w >= 0 && height >= 1){
-							var rect = {
-								x: offsets.l + (v < baseline ? hv : baselineWidth),
-								y: dim.height - offsets.b - vt(j + 1.5) + gap + shift,
-								width: w, height: height
-							};
-							var specialFill = this._plotFill(finalTheme.series.fill, dim, offsets);
-							specialFill = this._shapeFill(specialFill, rect);
-							var shape = s.createRect(rect).setFill(specialFill).setStroke(finalTheme.series.stroke);
-							run.dyn.fill   = shape.getFill();
-							run.dyn.stroke = shape.getStroke();
-							if(events){
-								var o = {
-									element: "bar",
-									index:   j,
-									run:     run,
-									shape:   shape,
-									x:       v,
-									y:       j + 1.5
-								};
-								this._connectEvents(o);
-								eventSeries[j] = o;
-							}
-							if(this.animate){
-								this._animateBar(shape, offsets.l + baselineWidth, -width);
-							}
-						}
-					}
-				}
-				this._eventSeries[run.name] = eventSeries;
-				run.dirty = false;
-			}
-			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.ClusteredBars
+		getBarProperties: function(){
+			var f = dc.calculateBarSize(this._vScaler.bounds.scale, this.opt, this.series.length);
+			return {gap: f.gap, height: f.size, thickness: f.size};
 		}
 	});
 });
diff --git a/dojox/charting/plot2d/ClusteredColumns.js b/dojox/charting/plot2d/ClusteredColumns.js
index a5ceadb..386a118 100644
--- a/dojox/charting/plot2d/ClusteredColumns.js
+++ b/dojox/charting/plot2d/ClusteredColumns.js
@@ -1,99 +1,12 @@
-define(["dojo/_base/array", "dojo/_base/declare", "./Columns", "./common", 
-		"dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/utils"], 
-	function(arr, declare, Columns, dc, df, dfr, du){
-/*=====
-var Columns = dojox.charting.plot2d.Columns;
-=====*/
-
-	var purgeGroup = dfr.lambda("item.purgeGroup()");
+define(["dojo/_base/declare", "./Columns", "./common"], 
+	function(declare, Columns, dc){
 
 	return declare("dojox.charting.plot2d.ClusteredColumns", Columns, {
-		//	summary:
-		//		A plot representing grouped or clustered columns (vertical bars).
-		render: function(dim, offsets){
-			//	summary:
-			//		Run the calculations for any axes for this plot.
-			//	dim: Object
-			//		An object in the form of { width, height }
-			//	offsets: Object
-			//		An object of the form { l, r, t, b}.
-			//	returns: dojox.charting.plot2d.ClusteredColumns
-			//		A reference to this plot for functional chaining.
-			if(this.zoom && !this.isDataDirty()){
-				return this.performZoom(dim, offsets);
-			}
-			this.resetEvents();
-			this.dirty = this.isDirty();
-			if(this.dirty){
-				arr.forEach(this.series, purgeGroup);
-				this._eventSeries = {};
-				this.cleanGroup();
-				var s = this.group;
-				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
-			}
-			var t = this.chart.theme, f, gap, width, thickness,
-				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
-				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
-				baseline = Math.max(0, this._vScaler.bounds.lower),
-				baselineHeight = vt(baseline),
-				events = this.events();
-			f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt, this.series.length);
-			gap = f.gap;
-			width = thickness = f.size;
-			for(var i = 0; i < this.series.length; ++i){
-				var run = this.series[i], shift = thickness * i;
-				if(!this.dirty && !run.dirty){
-					t.skip();
-					this._reconnectEvents(run.name);
-					continue;
-				}
-				run.cleanGroup();
-				var theme = t.next("column", [this.opt, run]), s = run.group,
-					eventSeries = new Array(run.data.length);
-				for(var j = 0; j < run.data.length; ++j){
-					var value = run.data[j];
-					if(value !== null){
-						var v = typeof value == "number" ? value : value.y,
-							vv = vt(v),
-							height = vv - baselineHeight,
-							h = Math.abs(height),
-							finalTheme = typeof value != "number" ?
-								t.addMixin(theme, "column", value, true) :
-								t.post(theme, "column");
-						if(width >= 1 && h >= 0){
-							var rect = {
-								x: offsets.l + ht(j + 0.5) + gap + shift,
-								y: dim.height - offsets.b - (v > baseline ? vv : baselineHeight),
-								width: width, height: h
-							};
-							var specialFill = this._plotFill(finalTheme.series.fill, dim, offsets);
-							specialFill = this._shapeFill(specialFill, rect);
-							var shape = s.createRect(rect).setFill(specialFill).setStroke(finalTheme.series.stroke);
-							run.dyn.fill   = shape.getFill();
-							run.dyn.stroke = shape.getStroke();
-							if(events){
-								var o = {
-									element: "column",
-									index:   j,
-									run:     run,
-									shape:   shape,
-									x:       j + 0.5,
-									y:       v
-								};
-								this._connectEvents(o);
-								eventSeries[j] = o;
-							}
-							if(this.animate){
-								this._animateColumn(shape, dim.height - offsets.b - baselineHeight, h);
-							}
-						}
-					}
-				}
-				this._eventSeries[run.name] = eventSeries;
-				run.dirty = false;
-			}
-			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.ClusteredColumns
+		// summary:
+		//		A plot representing grouped or clustered columns (vertical bars)
+		getBarProperties: function(){
+			var f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt, this.series.length);
+			return {gap: f.gap, width: f.size, thickness: f.size};
 		}
 	});
 });
diff --git a/dojox/charting/plot2d/Columns.js b/dojox/charting/plot2d/Columns.js
index 462a24c..27dca3f 100644
--- a/dojox/charting/plot2d/Columns.js
+++ b/dojox/charting/plot2d/Columns.js
@@ -1,18 +1,13 @@
-define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Base", "./common", 
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/has", "./CartesianBase", "./_PlotEvents", "./common",
 		"dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/utils", "dojox/gfx/fx"], 
-	function(lang, arr, declare, Base, dc, df, dfr, du, fx){
+	function(lang, arr, declare, has, CartesianBase, _PlotEvents, dc, df, dfr, du, fx){
 
 	var purgeGroup = dfr.lambda("item.purgeGroup()");
-/*=====
-var Base = dojox.charting.plot2d.Base;
-=====*/
 
-	return declare("dojox.charting.plot2d.Columns", Base, {
-		//	summary:
+	return declare("dojox.charting.plot2d.Columns", [CartesianBase, _PlotEvents], {
+		// summary:
 		//		The plot object representing a column chart (vertical bars).
 		defaultParams: {
-			hAxis: "x",		// use a horizontal axis named "x"
-			vAxis: "y",		// use a vertical axis named "y"
 			gap:	0,		// gap between columns in pixels
 			animate: null,  // animate bars into place
 			enableCache: false
@@ -25,35 +20,34 @@ var Base = dojox.charting.plot2d.Base;
 			outline:	{},
 			shadow:		{},
 			fill:		{},
+			filter:     {},
+			styleFunc:  null,
 			font:		"",
 			fontColor:	""
 		},
 
 		constructor: function(chart, kwArgs){
-			//	summary:
+			// summary:
 			//		The constructor for a columns chart.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this plot belongs to.
-			//	kwArgs: dojox.charting.plot2d.__BarCtorArgs?
+			// kwArgs: dojox.charting.plot2d.__BarCtorArgs?
 			//		An optional keyword arguments object to help define the plot.
-			this.opt = lang.clone(this.defaultParams);
+			this.opt = lang.clone(lang.mixin(this.opt, this.defaultParams));
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
-			this.series = [];
-			this.hAxis = this.opt.hAxis;
-			this.vAxis = this.opt.vAxis;
 			this.animate = this.opt.animate;
 		},
 
 		getSeriesStats: function(){
-			//	summary:
+			// summary:
 			//		Calculate the min/max on all attached series in both directions.
-			//	returns: Object
+			// returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
 			var stats = dc.collectSimpleStats(this.series);
 			stats.hmin -= 0.5;
 			stats.hmax += 0.5;
-			return stats;
+			return stats; // Object
 		},
 		
 		createRect: function(run, creator, params){
@@ -73,37 +67,35 @@ var Base = dojox.charting.plot2d.Base;
 		},
 
 		render: function(dim, offsets){
-			//	summary:
+			// summary:
 			//		Run the calculations for any axes for this plot.
-			//	dim: Object
+			// dim: Object
 			//		An object in the form of { width, height }
-			//	offsets: Object
+			// offsets: Object
 			//		An object of the form { l, r, t, b}.
-			//	returns: dojox.charting.plot2d.Columns
+			// returns: dojox/charting/plot2d/Columns
 			//		A reference to this plot for functional chaining.
 			if(this.zoom && !this.isDataDirty()){
 				return this.performZoom(dim, offsets);
 			}
-			var t = this.getSeriesStats();
 			this.resetEvents();
 			this.dirty = this.isDirty();
+			var s;
 			if(this.dirty){
 				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
-				var s = this.group;
+				s = this.getGroup();
 				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
 			}
-			var t = this.chart.theme, f, gap, width,
+			var t = this.chart.theme,
 				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
 				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
 				baseline = Math.max(0, this._vScaler.bounds.lower),
 				baselineHeight = vt(baseline),
-				min = Math.max(0, Math.floor(this._hScaler.bounds.from - 1)), max = Math.ceil(this._hScaler.bounds.to),
 				events = this.events();
-			f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt);
-			gap = f.gap;
-			width = f.size;
+			var bar = this.getBarProperties();
+			
 			for(var i = this.series.length - 1; i >= 0; --i){
 				var run = this.series[i];
 				if(!this.dirty && !run.dirty){
@@ -116,28 +108,58 @@ var Base = dojox.charting.plot2d.Base;
 					run._rectFreePool = (run._rectFreePool?run._rectFreePool:[]).concat(run._rectUsePool?run._rectUsePool:[]);
 					run._rectUsePool = [];
 				}
-				var theme = t.next("column", [this.opt, run]), s = run.group,
+				var theme = t.next("column", [this.opt, run]),
 					eventSeries = new Array(run.data.length);
-				var l = Math.min(run.data.length, max);
-				for(var j = min; j < l; ++j){
+				s = run.group;
+				var indexed = arr.some(run.data, function(item){
+					return typeof item == "number" || (item && !item.hasOwnProperty("x"));
+				});
+				// on indexed charts we can easily just interate from the first visible to the last visible
+				// data point to save time
+				var min = indexed?Math.max(0, Math.floor(this._hScaler.bounds.from - 1)):0;
+				var max = indexed?Math.min(run.data.length, Math.ceil(this._hScaler.bounds.to)):run.data.length;
+				for(var j = min; j < max; ++j){
 					var value = run.data[j];
-					if(value !== null){
-						var v = typeof value == "number" ? value : value.y,
-							vv = vt(v),
-							height = vv - baselineHeight,
-							h = Math.abs(height),
-							finalTheme = typeof value != "number" ?
-								t.addMixin(theme, "column", value, true) :
-								t.post(theme, "column");
-						if(width >= 1 && h >= 0){
+					if(value != null){
+						var val = this.getValue(value, j, i, indexed),
+							vv = vt(val.y),
+							h = Math.abs(vv - baselineHeight), 
+							finalTheme,
+							sshape;
+						
+						if(this.opt.styleFunc || typeof value != "number"){
+							var tMixin = typeof value != "number" ? [value] : [];
+							if(this.opt.styleFunc){
+								tMixin.push(this.opt.styleFunc(value));
+							}
+							finalTheme = t.addMixin(theme, "column", tMixin, true);
+						}else{
+							finalTheme = t.post(theme, "column");
+						}
+						
+						if(bar.width >= 1 && h >= 0){
 							var rect = {
-								x: offsets.l + ht(j + 0.5) + gap,
-								y: dim.height - offsets.b - (v > baseline ? vv : baselineHeight),
-								width: width, height: h
+								x: offsets.l + ht(val.x + 0.5) + bar.gap + bar.thickness * i,
+								y: dim.height - offsets.b - (val.y > baseline ? vv : baselineHeight),
+								width: bar.width, 
+								height: h
 							};
+							if(finalTheme.series.shadow){
+								var srect = lang.clone(rect);
+								srect.x += finalTheme.series.shadow.dx;
+								srect.y += finalTheme.series.shadow.dy;
+								sshape = this.createRect(run, s, srect).setFill(finalTheme.series.shadow.color).setStroke(finalTheme.series.shadow);
+								if(this.animate){
+									this._animateColumn(sshape, dim.height - offsets.b + baselineHeight, h);
+								}
+							}
+							
 							var specialFill = this._plotFill(finalTheme.series.fill, dim, offsets);
 							specialFill = this._shapeFill(specialFill, rect);
 							var shape = this.createRect(run, s, rect).setFill(specialFill).setStroke(finalTheme.series.stroke);
+							if(shape.setFilter && finalTheme.series.filter){
+								shape.setFilter(finalTheme.series.filter);
+							}
 							run.dyn.fill   = shape.getFill();
 							run.dyn.stroke = shape.getStroke();
 							if(events){
@@ -146,12 +168,21 @@ var Base = dojox.charting.plot2d.Base;
 									index:   j,
 									run:     run,
 									shape:   shape,
-									x:       j + 0.5,
-									y:       v
+									shadow:  sshape,
+									cx:      val.x + 0.5,
+									cy:      val.y,
+									x:	     indexed?j:run.data[j].x,
+									y:	 	 indexed?run.data[j]:run.data[j].y
 								};
 								this._connectEvents(o);
 								eventSeries[j] = o;
 							}
+							// if val.py is here, this means we are stacking and we need to subtract previous
+							// value to get the high in which we will lay out the label
+							if(!isNaN(val.py) && val.py > baseline){
+								rect.height = vv - vt(val.py);
+							}
+							this.createLabel(s, value, rect, finalTheme);
 							if(this.animate){
 								this._animateColumn(shape, dim.height - offsets.b - baselineHeight, h);
 							}
@@ -162,9 +193,36 @@ var Base = dojox.charting.plot2d.Base;
 				run.dirty = false;
 			}
 			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.Columns
+			// chart mirroring starts
+			if(has("dojo-bidi")){
+				this._checkOrientation(this.group, dim, offsets);
+			}
+			// chart mirroring ends
+			return this;	//	dojox/charting/plot2d/Columns
+		},
+		getValue: function(value, j, seriesIndex, indexed){
+			var y,x;
+			if(indexed){
+				if(typeof value == "number"){
+					y = value;
+				}else{
+					y = value.y;
+				}
+				x = j;
+			}else{
+				y = value.y;
+				x = value.x - 1;
+			}
+			return { x: x, y: y };
+		},
+		getBarProperties: function(){
+			var f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt);
+			return {gap: f.gap, width: f.size, thickness: 0};
 		},
 		_animateColumn: function(shape, voffset, vsize){
+			if(vsize==0){
+				vsize = 1;
+			}
 			fx.animateTransform(lang.delegate({
 				shape: shape,
 				duration: 1200,
@@ -175,5 +233,6 @@ var Base = dojox.charting.plot2d.Base;
 				]
 			}, this.animate)).play();
 		}
+		
 	});
 });
diff --git a/dojox/charting/plot2d/Default.js b/dojox/charting/plot2d/Default.js
index cdaedf2..e1380f1 100644
--- a/dojox/charting/plot2d/Default.js
+++ b/dojox/charting/plot2d/Default.js
@@ -1,123 +1,136 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", 
-		"./Base", "./common", "dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/utils", "dojox/gfx/fx"], 
-	function(lang, declare, arr, Base, dc, df, dfr, du, fx){
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/has", 
+		"./CartesianBase", "./_PlotEvents", "./common", "dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/utils", "dojox/gfx/fx"],
+	function(lang, declare, arr, has, CartesianBase, _PlotEvents, dc, df, dfr, du, fx){
 
 	/*=====
-	dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__PlotCtorArgs, {
-		//	summary:
+	declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__CartesianCtorArgs, {
+		// summary:
 		//		The arguments used for any/most plots.
 	
-		//	hAxis: String?
-		//		The horizontal axis name.
-		hAxis: "x",
-	
-		//	vAxis: String?
-		//		The vertical axis name
-		vAxis: "y",
-	
-		//	lines: Boolean?
+		// lines: Boolean?
 		//		Whether or not to draw lines on this plot.  Defaults to true.
 		lines:   true,
 	
-		//	areas: Boolean?
+		// areas: Boolean?
 		//		Whether or not to draw areas on this plot. Defaults to false.
 		areas:   false,
 	
-		//	markers: Boolean?
+		// markers: Boolean?
 		//		Whether or not to draw markers at data points on this plot. Default is false.
 		markers: false,
 	
-		//	tension: Number|String?
+		// tension: Number|String?
 		//		Whether or not to apply 'tensioning' to the lines on this chart.
 		//		Options include a number, "X", "x", or "S"; if a number is used, the
 		//		simpler bezier curve calculations are used to draw the lines.  If X, x or S
 		//		is used, the more accurate smoothing algorithm is used.
 		tension: "",
 	
-		//	animate: Boolean?
-		//		Whether or not to animate the chart to place.
+		// animate: Boolean?|Number?
+		//		Whether or not to animate the chart to place. When a Number it specifies the duration of the animation.
+		//		Default is false.
 		animate: false,
 	
-		//	stroke: dojox.gfx.Stroke?
+		// stroke: dojox.gfx.Stroke?
 		//		An optional stroke to use for any series on the plot.
 		stroke:		{},
 	
-		//	outline: dojox.gfx.Stroke?
+		// outline: dojox.gfx.Stroke?
 		//		An optional stroke used to outline any series on the plot.
 		outline:	{},
 	
-		//	shadow: dojox.gfx.Stroke?
+		// shadow: dojox.gfx.Stroke?
 		//		An optional stroke to use to draw any shadows for a series on a plot.
 		shadow:		{},
 	
-		//	fill: dojox.gfx.Fill?
+		// fill: dojox.gfx.Fill?
 		//		Any fill to be used for elements on the plot (such as areas).
 		fill:		{},
+
+		// filter: dojox.gfx.Filter?
+		//		An SVG filter to be used for elements on the plot. gfx SVG renderer must be used and dojox/gfx/svgext must
+		//		be required for this to work.
+		filter:		{},
+
+		// styleFunc: Function?
+		//		A function that returns a styling object for the a given data item.
+		styleFunc:	null,
 	
-		//	font: String?
+		// font: String?
 		//		A font definition to be used for labels and other text-based elements on the plot.
 		font:		"",
 	
-		//	fontColor: String|dojo.Color?
+		// fontColor: String|dojo.Color?
 		//		The color to be used for any text-based elements on the plot.
 		fontColor:	"",
 	
-		//	markerStroke: dojo.gfx.Stroke?
+		// markerStroke: dojo.gfx.Stroke?
 		//		An optional stroke to use for any markers on the plot.
 		markerStroke:		{},
 	
-		//	markerOutline: dojo.gfx.Stroke?
+		// markerOutline: dojo.gfx.Stroke?
 		//		An optional outline to use for any markers on the plot.
 		markerOutline:		{},
 	
-		//	markerShadow: dojo.gfx.Stroke?
+		// markerShadow: dojo.gfx.Stroke?
 		//		An optional shadow to use for any markers on the plot.
 		markerShadow:		{},
 	
-		//	markerFill: dojo.gfx.Fill?
+		// markerFill: dojo.gfx.Fill?
 		//		An optional fill to use for any markers on the plot.
 		markerFill:			{},
 	
-		//	markerFont: String?
+		// markerFont: String?
 		//		An optional font definition to use for any markers on the plot.
 		markerFont:			"",
 	
-		//	markerFontColor: String|dojo.Color?
+		// markerFontColor: String|dojo.Color?
 		//		An optional color to use for any marker text on the plot.
 		markerFontColor:	"",
 		
-		//	enableCache: Boolean?
+		// enableCache: Boolean?
 		//		Whether the markers are cached from one rendering to another. This improves the rendering performance of
 		//		successive rendering but penalize the first rendering.  Default false.
-		enableCache: false
+		enableCache: false,
+
+		// interpolate: Boolean?
+		//		Whether when there is a null data point in the data the plot interpolates it or if the lines is split at that
+		//		point.	Default false.
+		interpolate: false
 	});
-	
-	var Base = dojox.charting.plot2d.Base;
 =====*/
 
 	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
 	var DEFAULT_ANIMATION_LENGTH = 1200;	// in ms
 
-	return declare("dojox.charting.plot2d.Default", Base, {
+	return declare("dojox.charting.plot2d.Default", [CartesianBase, _PlotEvents], {
+		
+		// defaultParams:
+		//		The default parameters of this plot.
 		defaultParams: {
-			hAxis: "x",		// use a horizontal axis named "x"
-			vAxis: "y",		// use a vertical axis named "y"
 			lines:   true,	// draw lines
 			areas:   false,	// draw areas
 			markers: false,	// draw markers
 			tension: "",	// draw curved lines (tension is "X", "x", or "S")
 			animate: false, // animate chart to place
-			enableCache: false 
+			enableCache: false,
+			interpolate: false
 		},
+		
+		// optionalParams:
+		//		The optional parameters of this plot.
 		optionalParams: {
 			// theme component
 			stroke:		{},
 			outline:	{},
 			shadow:		{},
 			fill:		{},
+			filter:     {},
+			styleFunc: null,
 			font:		"",
 			fontColor:	"",
+			marker:             "",
 			markerStroke:		{},
 			markerOutline:		{},
 			markerShadow:		{},
@@ -127,19 +140,15 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array",
 		},
 
 		constructor: function(chart, kwArgs){
-			//	summary:
+			// summary:
 			//		Return a new plot.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this plot belongs to.
-			//	kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
+			// kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
 			//		An optional arguments object to help define this plot.
-			this.opt = lang.clone(this.defaultParams);
-            du.updateWithObject(this.opt, kwArgs);
-            du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
-			this.series = [];
-			this.hAxis = this.opt.hAxis;
-			this.vAxis = this.opt.vAxis;
-
+			this.opt = lang.clone(lang.mixin(this.opt, this.defaultParams));
+			du.updateWithObject(this.opt, kwArgs);
+			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			// animation properties
 			this.animate = this.opt.animate;
 		},
@@ -160,14 +169,39 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array",
 			return path;
 		},
 
+		buildSegments: function(i, indexed){
+			var run = this.series[i],
+				min = indexed?Math.max(0, Math.floor(this._hScaler.bounds.from - 1)):0,
+				max = indexed?Math.min(run.data.length, Math.ceil(this._hScaler.bounds.to)):run.data.length,
+				rseg = null, segments = [];
+
+			// split the run data into dense segments (each containing no nulls)
+			// except if interpolates is false in which case ignore null between valid data
+			for(var j = min; j < max; j++){
+				if(run.data[j] != null && (indexed || run.data[j].y != null)){
+					if(!rseg){
+						rseg = [];
+						segments.push({index: j, rseg: rseg});
+					}
+					rseg.push((indexed && run.data[j].hasOwnProperty("y"))?run.data[j].y:run.data[j]);
+				}else{
+					if(!this.opt.interpolate || indexed){
+						// we break the line only if not interpolating or if we have indexed data
+						rseg = null;
+					}
+				}
+			}
+			return segments;
+		},
+
 		render: function(dim, offsets){
-			//	summary:
+			// summary:
 			//		Render/draw everything on this plot.
-			//	dim: Object
+			// dim: Object
 			//		An object of the form { width, height }
-			//	offsets: Object
+			// offsets: Object
 			//		An object of the form { l, r, t, b }
-			//	returns: dojox.charting.plot2d.Default
+			// returns: dojox/charting/plot2d/Default
 			//		A reference to this plot for functional chaining.
 
 			// make sure all the series is not modified
@@ -177,15 +211,16 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array",
 
 			this.resetEvents();
 			this.dirty = this.isDirty();
+			var s;
 			if(this.dirty){
 				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
-				this.group.setTransform(null);
-				var s = this.group;
+				this.getGroup().setTransform(null);
+				s = this.getGroup();
 				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
 			}
-			var t = this.chart.theme, stroke, outline, marker, events = this.events();
+			var t = this.chart.theme, stroke, outline, events = this.events();
 
 			for(var i = this.series.length - 1; i >= 0; --i){
 				var run = this.series[i];
@@ -206,52 +241,60 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array",
 				}
 
 				var theme = t.next(this.opt.areas ? "area" : "line", [this.opt, run], true),
-					s = run.group, rsegments = [], startindexes = [], rseg = null, lpoly,
+					lpoly,
 					ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
 					vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
 					eventSeries = this._eventSeries[run.name] = new Array(run.data.length);
+
+				s = run.group;
 				
 				// optim works only for index based case
-				var indexed = typeof run.data[0] == "number";
-				var min = indexed?Math.max(0, Math.floor(this._hScaler.bounds.from - 1)):0, 
-						max = indexed?Math.min(run.data.length, Math.ceil(this._hScaler.bounds.to)):run.data.length;
-
-                // split the run data into dense segments (each containing no nulls)
-                for(var j = min; j < max; j++){
-                    if(run.data[j] != null){
-                        if(!rseg){
-                            rseg = [];
-                            startindexes.push(j);
-                            rsegments.push(rseg);
-                        }
-                        rseg.push(run.data[j]);
-                    }else{
-                        rseg = null;
-                    }
-                }
+				var indexed = arr.some(run.data, function(item){
+					return typeof item == "number" || (item && !item.hasOwnProperty("x"));
+				});
 
-                for(var seg = 0; seg < rsegments.length; seg++){
-					if(typeof rsegments[seg][0] == "number"){
-						lpoly = arr.map(rsegments[seg], function(v, i){
+				var rsegments = this.buildSegments(i, indexed);
+				for(var seg = 0; seg < rsegments.length; seg++){
+					var rsegment = rsegments[seg];
+					if(indexed){
+						lpoly = arr.map(rsegment.rseg, function(v, i){
 							return {
-								x: ht(i + startindexes[seg] + 1) + offsets.l,
-								y: dim.height - offsets.b - vt(v)
+								x: ht(i + rsegment.index + 1) + offsets.l,
+								y: dim.height - offsets.b - vt(v),
+								data: v
 							};
 						}, this);
 					}else{
-						lpoly = arr.map(rsegments[seg], function(v, i){
+						lpoly = arr.map(rsegment.rseg, function(v){
 							return {
 								x: ht(v.x) + offsets.l,
-								y: dim.height - offsets.b - vt(v.y)
+								y: dim.height - offsets.b - vt(v.y),
+								data: v
 							};
 						}, this);
 					}
 
+					// if we are indexed & we interpolate we need to put all the segments as a single one now
+					if(indexed && this.opt.interpolate){
+						while(seg < rsegments.length) {
+							seg++;
+							rsegment = rsegments[seg];
+							if(rsegment){
+								lpoly = lpoly.concat(arr.map(rsegment.rseg, function(v, i){
+									return {
+										x: ht(i + rsegment.index + 1) + offsets.l,
+										y: dim.height - offsets.b - vt(v),
+										data: v
+									};
+								}, this));
+							}
+						}
+					} 
+
 					var lpath = this.opt.tension ? dc.curve(lpoly, this.opt.tension) : "";
 
 					if(this.opt.areas && lpoly.length > 1){
-						var fill = theme.series.fill;
-						var apoly = lang.clone(lpoly);
+						var fill = this._plotFill(theme.series.fill, dim, offsets), apoly = lang.clone(lpoly);
 						if(this.opt.tension){
 							var apath = "L" + apoly[apoly.length-1].x + "," + (dim.height - offsets.b) +
 								" L" + apoly[0].x + "," + (dim.height - offsets.b) +
@@ -297,6 +340,7 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array",
 						}
 					}
 					if(this.opt.lines && lpoly.length > 1){
+						var shape;
 						if(outline){
 							if(this.opt.tension){
 								run.dyn.outline = s.createPath(lpath).setStroke(outline).getStroke();
@@ -305,33 +349,50 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array",
 							}
 						}
 						if(this.opt.tension){
-							run.dyn.stroke = s.createPath(lpath).setStroke(stroke).getStroke();
+							run.dyn.stroke = (shape = s.createPath(lpath)).setStroke(stroke).getStroke();
 						} else {
-							run.dyn.stroke = s.createPolyline(lpoly).setStroke(stroke).getStroke();
+							run.dyn.stroke = (shape = s.createPolyline(lpoly)).setStroke(stroke).getStroke();
+						}
+						if(shape.setFilter && theme.series.filter){
+							shape.setFilter(theme.series.filter);
 						}
 					}
+					var markerBox = null;
 					if(this.opt.markers){
+						var markerTheme = theme; 
 						frontMarkers = new Array(lpoly.length);
 						outlineMarkers = new Array(lpoly.length);
 						outline = null;
-						if(theme.marker.outline){
-							outline = dc.makeStroke(theme.marker.outline);
-							outline.width = 2 * outline.width + (theme.marker.stroke ? theme.marker.stroke.width : 0);
+						if(markerTheme.marker.outline){
+							outline = dc.makeStroke(markerTheme.marker.outline);
+							outline.width = 2 * outline.width + (markerTheme.marker.stroke ? markerTheme.marker.stroke.width : 0);
 						}
 						arr.forEach(lpoly, function(c, i){
-							var path = "M" + c.x + " " + c.y + " " + theme.symbol;
+							if(this.opt.styleFunc || typeof c.data != "number"){
+								var tMixin = typeof c.data != "number" ? [c.data] : [];
+								if(this.opt.styleFunc){
+									tMixin.push(this.opt.styleFunc(c.data));
+								}
+								markerTheme = t.addMixin(theme, "marker", tMixin, true);
+							}else{
+								markerTheme = t.post(theme, "marker");
+							}
+							var path = "M" + c.x + " " + c.y + " " + markerTheme.symbol;
 							if(outline){
 								outlineMarkers[i] = this.createPath(run, s, path).setStroke(outline);
 							}
-							frontMarkers[i] = this.createPath(run, s, path).setStroke(theme.marker.stroke).setFill(theme.marker.fill);
+							frontMarkers[i] = this.createPath(run, s, path).setStroke(markerTheme.marker.stroke).setFill(markerTheme.marker.fill);
 						}, this);
-						run.dyn.markerFill = theme.marker.fill;
-						run.dyn.markerStroke = theme.marker.stroke;
+						run.dyn.markerFill = markerTheme.marker.fill;
+						run.dyn.markerStroke = markerTheme.marker.stroke;
+						if(!markerBox && this.opt.labels){
+							markerBox = frontMarkers[0].getBoundingBox();
+						}
 						if(events){
 							arr.forEach(frontMarkers, function(s, i){
 								var o = {
 									element: "marker",
-									index:   i + startindexes[seg],
+									index:   i + rsegment.index,
 									run:     run,
 									shape:   s,
 									outline: outlineMarkers[i] || null,
@@ -339,26 +400,48 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array",
 									cx:      lpoly[i].x,
 									cy:      lpoly[i].y
 								};
-								if(typeof rsegments[seg][0] == "number"){
-									o.x = i + startindexes[seg] + 1;
-									o.y = rsegments[seg][i];
+								if(indexed){
+									o.x = i + rsegment.index + 1;
+									o.y = run.data[i + rsegment.index];
 								}else{
-									o.x = rsegments[seg][i].x;
-									o.y = rsegments[seg][i].y;
+									o.x = rsegment.rseg[i].x;
+									o.y = run.data[i + rsegment.index].y;
 								}
 								this._connectEvents(o);
-								eventSeries[i + startindexes[seg]] = o;
+								eventSeries[i + rsegment.index] = o;
 							}, this);
 						}else{
 							delete this._eventSeries[run.name];
 						}
 					}
-                }
+					if(this.opt.labels){
+						var labelBoxW = markerBox?markerBox.width:2;
+						var labelBoxH = markerBox?markerBox.height:2;
+						arr.forEach(lpoly, function(c, i){
+							if(this.opt.styleFunc || typeof c.data != "number"){
+								var tMixin = typeof c.data != "number" ? [c.data] : [];
+								if(this.opt.styleFunc){
+									tMixin.push(this.opt.styleFunc(c.data));
+								}
+								markerTheme = t.addMixin(theme, "marker", tMixin, true);
+							}else{
+								markerTheme = t.post(theme, "marker");
+							}
+							this.createLabel(s, rsegment.rseg[i], { x: c.x - labelBoxW / 2, y: c.y - labelBoxH / 2,
+								width: labelBoxW , height: labelBoxH }, markerTheme);
+						}, this);
+					}
+				}
 				run.dirty = false;
 			}
+			// chart mirroring starts
+			if(has("dojo-bidi")){
+				this._checkOrientation(this.group, dim, offsets);
+			}
+			// chart mirroring ends
 			if(this.animate){
 				// grow from the bottom
-				var plotGroup = this.group;
+				var plotGroup = this.getGroup();
 				fx.animateTransform(lang.delegate({
 					shape: plotGroup,
 					duration: DEFAULT_ANIMATION_LENGTH,
@@ -370,7 +453,7 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array",
 				}, this.animate)).play();
 			}
 			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.Default
+			return this;	//	dojox/charting/plot2d/Default
 		}
 	});
 });
diff --git a/dojox/charting/plot2d/Grid.js b/dojox/charting/plot2d/Grid.js
index 154e164..6d98ade 100644
--- a/dojox/charting/plot2d/Grid.js
+++ b/dojox/charting/plot2d/Grid.js
@@ -1,195 +1,147 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/array",
-		"../Element", "./common", "dojox/lang/utils", "dojox/gfx/fx"], 
-	function(lang, declare, hub, arr, Element, dc, du, fx){
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/sniff",
+		"./CartesianBase", "./common", "dojox/lang/utils", "dojox/gfx/fx"],
+	function(lang, declare, arr, has, CartesianBase, dc, du, fx){
+
+	var sortTicks = function(a,b){return a.value - b.value};
 
 	/*=====
-	dojo.declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
-		//	summary:
+	declare("dojox.charting.plot2d.__GridCtorArgs", dojox.charting.plot2d.__CartesianCtorArgs, {
+		// summary:
 		//		A special keyword arguments object that is specific to a grid "plot".
-	
-		//	hMajorLines: Boolean?
+
+		// majorHLine: dojox.gfx.Stroke?
+		//		An optional dojox.gfx.Stroke for a major horizontal line. By default major lines use major tick stroke.
+		majorHLine:undefined,
+
+		// minorHLine: dojox.gfx.Stroke?
+		//		An optional dojox.gfx.Stroke for a minor horizontal line. By default minor lines use minor tick stroke.
+		minorHLine:undefined,
+
+		// majorVLine: dojox.gfx.Stroke?
+		//		An optional dojox.gfx.Stroke for a major vertical line. By default major lines use major tick stroke.
+		majorVLine:undefined,
+
+		// minorVLine: dojox.gfx.Stroke?
+		//		An optional dojox.gfx.Stroke for a minor vertical line. By default major lines use major tick stroke.
+		minorVLine:undefined,
+
+		// hFill: dojox.gfx.Fill?
+		//		An optional dojox.gfx.Fill used to fill every other horizontal stripe created by grid lines.
+		hFill: undefined,
+
+		// hAlternateFill: dojox.gfx.Fill?
+		//		An optional dojox.gfx.Fill used to fill alternating horizontal stripe created by grid lines not filled by `hFill`.
+		hAlternateFill: undefined,
+
+		// vFill: dojox.gfx.Fill?
+		//		An optional dojox.gfx.Fill used to fill every other vertical stripe created by grid lines.
+		vFill: undefined,
+
+		// vAlternateFill: dojox.gfx.Fill?
+		//		An optional dojox.gfx.Fill used to fill alternating vertical stripe created by grid lines not filled by `vFill`.
+		vAlternateFill: undefined,
+
+		// hMajorLines: Boolean?
 		//		Whether to show lines at the major ticks along the horizontal axis. Default is true.
 		hMajorLines: true,
-	
-		//	hMinorLines: Boolean?
+
+		// hMinorLines: Boolean?
 		//		Whether to show lines at the minor ticks along the horizontal axis. Default is false.
 		hMinorLines: false,
-	
-		//	vMajorLines: Boolean?
+
+		// vMajorLines: Boolean?
 		//		Whether to show lines at the major ticks along the vertical axis. Default is true.
 		vMajorLines: true,
-	
-		//	vMinorLines: Boolean?
+
+		// vMinorLines: Boolean?
 		//		Whether to show lines at the major ticks along the vertical axis. Default is false.
 		vMinorLines: false,
-	
-		//	hStripes: String?
-		//		Whether or not to show stripes (alternating fills) along the horizontal axis. Default is "none".
-		hStripes: "none",
-	
-		//	vStripes: String?
-		//		Whether or not to show stripes (alternating fills) along the vertical axis. Default is "none".
-		vStripes: "none",
-		
-		//	enableCache: Boolean?
+
+		// hStripes: Boolean?
+		//		Whether to show horizontal stripes. Default is false.
+		hStripes: false,
+
+		// vStripes: Boolean?
+		//		Whether to show vertical stripes. Default is false.
+		vStripes: false,
+
+		// enableCache: Boolean?
 		//		Whether the grid lines are cached from one rendering to another. This improves the rendering performance of
 		//		successive rendering but penalize the first rendering.  Default false.
-		enableCache: false
+		enableCache: false,
+
+		// renderOnAxis: Boolean?
+		//		Whether or not the grid is rendered when drawn at horizontal or vertical axis position. Default is true.
+		renderOnAxis: true
 	});
-	var Element = dojox.charting.plot2d.Element;
 	=====*/
 
-	return declare("dojox.charting.plot2d.Grid", Element, {
-		//	summary:
+	return declare("dojox.charting.plot2d.Grid", CartesianBase, {
+		// summary:
 		//		A "faux" plot that can be placed behind other plots to represent
 		//		a grid against which other plots can be easily measured.
 		defaultParams: {
-			hAxis: "x",			// use a horizontal axis named "x"
-			vAxis: "y",			// use a vertical axis named "y"
 			hMajorLines: true,	// draw horizontal major lines
 			hMinorLines: false,	// draw horizontal minor lines
 			vMajorLines: true,	// draw vertical major lines
 			vMinorLines: false,	// draw vertical minor lines
-			hStripes: "none",	// TBD
-			vStripes: "none",	// TBD
+			hStripes: false,	// draw vertical stripes
+			vStripes: false,	// draw vertical stripes
 			animate: null,   // animate bars into place
-			enableCache: false
+			enableCache: false,
+			renderOnAxis: true
+		},
+
+		optionalParams: {
+			majorHLine: {},
+			minorHLine: {},
+			majorVLine: {},
+			minorVLine: {},
+			hFill: {},
+			vFill: {},
+			hAlternateFill: {},
+			vAlternateFill: {}
 		},
-		optionalParams: {},	// no optional parameters
 
 		constructor: function(chart, kwArgs){
-			//	summary:
+			// summary:
 			//		Create the faux Grid plot.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this plot belongs to.
-			//	kwArgs: dojox.charting.plot2d.__GridCtorArgs?
+			// kwArgs: dojox.charting.plot2d.__GridCtorArgs?
 			//		An optional keyword arguments object to help define the parameters of the underlying grid.
 			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
-			this.hAxis = this.opt.hAxis;
-			this.vAxis = this.opt.vAxis;
-			this.dirty = true;
+			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.animate = this.opt.animate;
-			this.zoom = null,
-			this.zoomQueue = [];	// zooming action task queue
-			this.lastWindow = {vscale: 1, hscale: 1, xoffset: 0, yoffset: 0};
 			if(this.opt.enableCache){
 				this._lineFreePool = [];
 				this._lineUsePool = [];
+				this._rectFreePool = [];
+				this._rectUsePool = [];
 			}
 		},
-		clear: function(){
-			//	summary:
-			//		Clear out any parameters set on this plot.
-			//	returns: dojox.charting.plot2d.Grid
-			//		The reference to this plot for functional chaining.
-			this._hAxis = null;
-			this._vAxis = null;
-			this.dirty = true;
-			return this;	//	dojox.charting.plot2d.Grid
-		},
-		setAxis: function(axis){
-			//	summary:
-			//		Set an axis for this plot.
-			//	returns: dojox.charting.plot2d.Grid
-			//		The reference to this plot for functional chaining.
-			if(axis){
-				this[axis.vertical ? "_vAxis" : "_hAxis"] = axis;
-			}
-			return this;	//	dojox.charting.plot2d.Grid
-		},
 		addSeries: function(run){
-			//	summary:
+			// summary:
 			//		Ignored but included as a dummy method.
-			//	returns: dojox.charting.plot2d.Grid
+			// returns: dojox/charting/plot2d/Grid
 			//		The reference to this plot for functional chaining.
-			return this;	//	dojox.charting.plot2d.Grid
+			return this;	//	dojox/charting/plot2d/Grid
 		},
 		getSeriesStats: function(){
-			//	summary:
+			// summary:
 			//		Returns default stats (irrelevant for this type of plot).
-			//	returns: Object
+			// returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
-			return lang.delegate(dc.defaultStats);
-		},
-		initializeScalers: function(){
-			//	summary:
-			//		Does nothing (irrelevant for this type of plot).
-			return this;
-		},
-		isDirty: function(){
-			//	summary:
-			//		Return whether or not this plot needs to be redrawn.
-			//	returns: Boolean
-			//		If this plot needs to be rendered, this will return true.
-			return this.dirty || this._hAxis && this._hAxis.dirty || this._vAxis && this._vAxis.dirty;	//	Boolean
-		},
-		performZoom: function(dim, offsets){
-			//	summary:
-			//		Create/alter any zooming windows on this plot.
-			//	dim: Object
-			//		An object of the form { width, height }.
-			//	offsets: Object
-			//		An object of the form { l, r, t, b }.
-			//	returns: dojox.charting.plot2d.Grid
-			//		A reference to this plot for functional chaining.
-
-			// get current zooming various
-			var vs = this._vAxis.scale || 1,
-				hs = this._hAxis.scale || 1,
-				vOffset = dim.height - offsets.b,
-				hBounds = this._hAxis.getScaler().bounds,
-				xOffset = (hBounds.from - hBounds.lower) * hBounds.scale,
-				vBounds = this._vAxis.getScaler().bounds,
-				yOffset = (vBounds.from - vBounds.lower) * vBounds.scale,
-				// get incremental zooming various
-				rVScale = vs / this.lastWindow.vscale,
-				rHScale = hs / this.lastWindow.hscale,
-				rXOffset = (this.lastWindow.xoffset - xOffset)/
-					((this.lastWindow.hscale == 1)? hs : this.lastWindow.hscale),
-				rYOffset = (yOffset - this.lastWindow.yoffset)/
-					((this.lastWindow.vscale == 1)? vs : this.lastWindow.vscale),
-
-				shape = this.group,
-				anim = fx.animateTransform(lang.delegate({
-					shape: shape,
-					duration: 1200,
-					transform:[
-						{name:"translate", start:[0, 0], end: [offsets.l * (1 - rHScale), vOffset * (1 - rVScale)]},
-						{name:"scale", start:[1, 1], end: [rHScale, rVScale]},
-						{name:"original"},
-						{name:"translate", start: [0, 0], end: [rXOffset, rYOffset]}
-					]}, this.zoom));
-
-			lang.mixin(this.lastWindow, {vscale: vs, hscale: hs, xoffset: xOffset, yoffset: yOffset});
-			//add anim to zooming action queue,
-			//in order to avoid several zooming action happened at the same time
-			this.zoomQueue.push(anim);
-			//perform each anim one by one in zoomQueue
-			hub.connect(anim, "onEnd", this, function(){
-				this.zoom = null;
-				this.zoomQueue.shift();
-				if(this.zoomQueue.length > 0){
-					this.zoomQueue[0].play();
-				}
-			});
-			if(this.zoomQueue.length == 1){
-				this.zoomQueue[0].play();
-			}
-			return this;	//	dojox.charting.plot2d.Grid
-		},
-		getRequiredColors: function(){
-			//	summary:
-			//		Ignored but included as a dummy method.
-			//	returns: Number
-			//		Returns 0, since there are no series associated with this plot type.
-			return 0;	//	Number
+			return lang.delegate(dc.defaultStats); // Object
 		},
 		cleanGroup: function(){
 			this.inherited(arguments);
 			if(this.opt.enableCache){
 				this._lineFreePool = this._lineFreePool.concat(this._lineUsePool);
 				this._lineUsePool = [];
+				this._rectFreePool = this._rectFreePool.concat(this._rectUsePool);
+				this._rectUsePool = [];
 			}
 		},
 		createLine: function(creator, params){
@@ -207,14 +159,30 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 			}
 			return line;
 		},
+		createRect: function(creator, params){
+			var rect;
+			if(this.opt.enableCache && this._rectFreePool.length > 0){
+				rect = this._rectFreePool.pop();
+				rect.setShape(params);
+				// was cleared, add it back
+				creator.add(rect);
+			}else{
+				rect = creator.createRect(params);
+			}
+			if(this.opt.enableCache){
+				this._rectUsePool.push(rect);
+			}
+			return rect;
+		},
+		
 		render: function(dim, offsets){
-			//	summary:
+			// summary:
 			//		Render the plot on the chart.
-			//	dim: Object
+			// dim: Object
 			//		An object of the form { width, height }.
-			//	offsets: Object
+			// offsets: Object
 			//		An object of the form { l, r, t, b }.
-			//	returns: dojox.charting.plot2d.Grid
+			// returns: dojox/charting/plot2d/Grid
 			//		A reference to this plot for functional chaining.
 			if(this.zoom){
 				return this.performZoom(dim, offsets);
@@ -222,85 +190,154 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 			this.dirty = this.isDirty();
 			if(!this.dirty){ return this; }
 			this.cleanGroup();
-			var s = this.group, ta = this.chart.theme.axis;
-			// draw horizontal stripes and lines
-			try{
-				var vScaler = this._vAxis.getScaler(),
-					vt = vScaler.scaler.getTransformerFromModel(vScaler),
-					ticks = this._vAxis.getTicks();
-				if(ticks != null){
+			var s = this.getGroup(), ta = this.chart.theme, lineStroke, ticks;
+			if((has("ios") && has("ios") < 6) || has("android") || (has("safari") && !has("ios"))){
+				// clipping seems buggy in some mobile Webkit browser and Safari desktop
+				// it does not clip correctly if only lines are present => create a invisible rectangle...
+				var w = Math.max(0, dim.width  - offsets.l - offsets.r),
+					h = Math.max(0, dim.height - offsets.t - offsets.b);
+				s.createRect({ x: offsets.l, y: offsets.t, width: w, height: h});
+			}
+			if(this._vAxis){
+				// draw horizontal stripes and lines
+				ticks = this._vAxis.getTicks();
+				var vScaler = this._vAxis.getScaler();
+				if(ticks != null && vScaler != null){
+					var vt = vScaler.scaler.getTransformerFromModel(vScaler);
+					if(this.opt.hStripes){
+						this._renderHRect(ticks, ta.grid, dim, offsets, vScaler, vt);
+					}
 					if(this.opt.hMinorLines){
-						arr.forEach(ticks.minor, function(tick){
-							var y = dim.height - offsets.b - vt(tick.value);
-							var hMinorLine = this.createLine(s, {
-								x1: offsets.l,
-								y1: y,
-								x2: dim.width - offsets.r,
-								y2: y
-							}).setStroke(ta.minorTick);
-							if(this.animate){
-								this._animateGrid(hMinorLine, "h", offsets.l, offsets.r + offsets.l - dim.width);
-							}
-						}, this);
+						lineStroke = this.opt.minorHLine || (ta.grid && ta.grid.minorLine) || ta.axis.minorTick;
+						this._renderHLines(ticks.minor, lineStroke, dim, offsets, vScaler, vt);
 					}
 					if(this.opt.hMajorLines){
-						arr.forEach(ticks.major, function(tick){
-							var y = dim.height - offsets.b - vt(tick.value);
-							var hMajorLine = this.createLine(s, {
-								x1: offsets.l,
-								y1: y,
-								x2: dim.width - offsets.r,
-								y2: y
-							}).setStroke(ta.majorTick);
-							if(this.animate){
-								this._animateGrid(hMajorLine, "h", offsets.l, offsets.r + offsets.l - dim.width);
-							}
-						}, this);
+						lineStroke = this.opt.majorHLine || (ta.grid && ta.grid.majorLine) || ta.axis.majorTick;
+						this._renderHLines(ticks.major, lineStroke, dim, offsets, vScaler, vt);
 					}
 				}
-			}catch(e){
-				// squelch
+				
 			}
-			// draw vertical stripes and lines
-			try{
-				var hScaler = this._hAxis.getScaler(),
-					ht = hScaler.scaler.getTransformerFromModel(hScaler),
-					ticks = this._hAxis.getTicks();
-				if(this != null){
+			if(this._hAxis){
+				// draw vertical stripes and lines
+				ticks = this._hAxis.getTicks();
+				var hScaler = this._hAxis.getScaler();
+				if(ticks != null && hScaler != null){
+					var ht = hScaler.scaler.getTransformerFromModel(hScaler);
+					if(this.opt.vStripes){
+						this._renderVRect(ticks, ta.grid, dim, offsets, hScaler, ht);
+					}
 					if(ticks && this.opt.vMinorLines){
-						arr.forEach(ticks.minor, function(tick){
-							var x = offsets.l + ht(tick.value);
-							var vMinorLine = this.createLine(s, {
-								x1: x,
-								y1: offsets.t,
-								x2: x,
-								y2: dim.height - offsets.b
-							}).setStroke(ta.minorTick);
-							if(this.animate){
-								this._animateGrid(vMinorLine, "v", dim.height - offsets.b, dim.height - offsets.b - offsets.t);
-							}
-						}, this);
+						lineStroke = this.opt.minorVLine || (ta.grid && ta.grid.minorLine) || ta.axis.minorTick;
+						this._renderVLines(ticks.minor, lineStroke, dim, offsets, hScaler, ht);
 					}
 					if(ticks && this.opt.vMajorLines){
-						arr.forEach(ticks.major, function(tick){
-							var x = offsets.l + ht(tick.value);
-							var vMajorLine = this.createLine(s, {
-								x1: x,
-								y1: offsets.t,
-								x2: x,
-								y2: dim.height - offsets.b
-							}).setStroke(ta.majorTick);
-							if(this.animate){
-								this._animateGrid(vMajorLine, "v", dim.height - offsets.b, dim.height - offsets.b - offsets.t);
-							}
-						}, this);
+						lineStroke = this.opt.majorVLine || (ta.grid && ta.grid.majorLine) || ta.axis.majorTick;
+						this._renderVLines(ticks.major, lineStroke, dim, offsets, hScaler, ht);
 					}
+
 				}
-			}catch(e){
-				// squelch
 			}
 			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.Grid
+			return this;	//	dojox/charting/plot2d/Grid
+		},
+		_renderHLines: function(ticks, lineStroke, dim, offsets, vScaler, vt){
+			var s = this.getGroup();
+			arr.forEach(ticks, function(tick){
+				if(!this.opt.renderOnAxis && tick.value == (this._vAxis.opt.leftBottom?vScaler.bounds.from:vScaler.bounds.to)){
+					return;
+				}
+				var y = dim.height - offsets.b - vt(tick.value);
+				var hLine = this.createLine(s, {
+					x1: offsets.l,
+					y1: y,
+					x2: dim.width - offsets.r,
+					y2: y
+				}).setStroke(lineStroke);
+				if(this.animate){
+					this._animateGrid(hLine, "h", offsets.l, offsets.r + offsets.l - dim.width);
+				}
+			}, this);
+		},
+		_renderVLines: function(ticks, lineStroke, dim, offsets, hScaler, ht){
+			var s = this.getGroup();
+			arr.forEach(ticks, function(tick){
+				if(!this.opt.renderOnAxis && tick.value == (this._hAxis.opt.leftBottom?hScaler.bounds.from:hScaler.bounds.to)){
+					return;
+				}
+				var x = offsets.l + ht(tick.value);
+				var vLine = this.createLine(s, {
+					x1: x,
+					y1: offsets.t,
+					x2: x,
+					y2: dim.height - offsets.b
+				}).setStroke(lineStroke);
+				if(this.animate){
+					this._animateGrid(vLine, "v", dim.height - offsets.b, dim.height - offsets.b - offsets.t);
+				}
+			}, this);
+		},
+		_renderHRect: function(ticks, theme, dim, offsets, vScaler, vt){
+			var fill, tick, y, y2, hStripe;
+			var allTicks = ticks.major.concat(ticks.minor);
+			allTicks.sort(sortTicks);
+			if(allTicks[0].value > vScaler.bounds.from){
+				allTicks.splice(0, 0, {value: vScaler.bounds.from});
+			}
+			if(allTicks[allTicks.length - 1].value < vScaler.bounds.to){
+				allTicks.push({value: vScaler.bounds.to});
+			}
+			var s = this.getGroup();
+			for(var j = 0; j < allTicks.length - 1; j++){
+				tick = allTicks[j];
+				y = dim.height - offsets.b - vt(tick.value);
+				y2 = dim.height - offsets.b - vt(allTicks[j+1].value);
+
+				fill = (j%2 == 0)?(this.opt.hAlternateFill ||(theme && theme.alternateFill)):
+					(this.opt.hFill || (theme && theme.fill));
+				if(fill){
+					hStripe = this.createRect(s, {
+						x: offsets.l,
+						y: y,
+						width: dim.width - offsets.r,
+						height: y - y2
+					}).setFill(fill);
+					if(this.animate){
+						this._animateGrid(hStripe, "h", offsets.l, offsets.r + offsets.l - dim.width);
+					}
+				}
+			}
+		},
+		_renderVRect: function(ticks, theme, dim, offsets, hScaler, ht){
+			var fill, tick, x, x2, vStripe;
+			var allTicks = ticks.major.concat(ticks.minor);
+			allTicks.sort(sortTicks);
+			if(allTicks[0].value > hScaler.bounds.from){
+				allTicks.splice(0, 0, {value: hScaler.bounds.from});
+			}
+			if(allTicks[allTicks.length - 1].value < hScaler.bounds.to){
+				allTicks.push({value: hScaler.bounds.to});
+			}
+			var s = this.getGroup();
+			for(var j = 0; j < allTicks.length - 1; j++){
+				tick = allTicks[j];
+				x = offsets.l + ht(tick.value);
+				x2 = offsets.l + ht(allTicks[j+1].value);
+
+				fill = (j%2 == 0)?(this.opt.vAlternateFill ||(theme && theme.alternateFill)):
+					(this.opt.vFill || (theme && theme.fill));
+				if(fill){
+					vStripe = this.createRect(s, {
+						x: x,
+						y: offsets.t,
+						width: x2 - x,
+						height: dim.width - offsets.r
+					}).setFill(fill);
+					if(this.animate){
+						this._animateGrid(vStripe, "v", dim.height - offsets.b, dim.height - offsets.b - offsets.t);
+					}
+				}
+			}
 		},
 		_animateGrid: function(shape, type, offset, size){
 			var transStart = type == "h" ? [offset, 0] : [0, offset];
diff --git a/dojox/charting/plot2d/Indicator.js b/dojox/charting/plot2d/Indicator.js
new file mode 100644
index 0000000..31bd799
--- /dev/null
+++ b/dojox/charting/plot2d/Indicator.js
@@ -0,0 +1,493 @@
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./CartesianBase", "./_PlotEvents", "./common",
+    "../axis2d/common", "dojox/gfx", "dojox/lang/utils", "dojox/gfx/fx", "dojo/has"],
+	function(lang, array, declare, CartesianBase, _PlotEvents, dcpc, dcac, gfx, du, fx, has){
+
+	// all the code below should be removed when http://trac.dojotoolkit.org/ticket/11299 will be available
+	var getBoundingBox = function(shape){
+		return getTextBBox(shape, shape.getShape().text);
+	};
+	var getTextBBox = function(s, t){
+		var c = s.declaredClass;
+		var w, h;
+		if(c.indexOf("svg")!=-1){
+			// try/catch the FF native getBBox error. cheaper than walking up in the DOM
+			// hierarchy to check the conditions (bench show /10 )
+			try {
+				return lang.mixin({}, s.rawNode.getBBox());
+			}catch (e){
+				return null;
+			}
+		}else if(c.indexOf("vml")!=-1){
+			var rawNode = s.rawNode, _display = rawNode.style.display;
+			rawNode.style.display = "inline";
+			w = gfx.pt2px(parseFloat(rawNode.currentStyle.width));
+			h = gfx.pt2px(parseFloat(rawNode.currentStyle.height));
+			var sz = {x: 0, y: 0, width: w, height: h};
+			// in VML, the width/height we get are in view coordinates
+			// in our case we don't zoom the view so that is ok
+			// It's impossible to get the x/y from the currentStyle.left/top,
+			// because all negative coordinates are 'clipped' to 0.
+			// (x:0 + translate(-100) -> x=0
+			computeLocation(s, sz);
+			rawNode.style.display = _display;
+			return sz;
+		}else if(c.indexOf("silverlight")!=-1){
+			var bb = {width: s.rawNode.actualWidth, height: s.rawNode.actualHeight};
+			return computeLocation(s, bb, 0.75);
+		}else if(s.getTextWidth){
+			// canvas
+			w = s.getTextWidth();
+			var font = s.getFont();
+			var fz = font ? font.size : gfx.defaultFont.size;
+			h = gfx.normalizedLength(fz);
+			sz = {width: w, height: h};
+			computeLocation(s, sz, 0.75);
+			return sz;
+		}
+		return null;
+	};
+	var computeLocation =  function(s, sz, coef){
+		var width = sz.width, height = sz.height, sh = s.getShape(), align = sh.align;
+		switch (align) {
+		case "end":
+			sz.x = sh.x - width;
+			break;
+		case "middle":
+			sz.x = sh.x - width / 2;
+			break;
+		case "start":
+		default:
+			sz.x = sh.x;
+		break;
+		}
+		coef = coef || 1;
+		sz.y = sh.y - height*coef; // rough approximation of the ascent!...
+		return sz;
+	};
+
+	/*=====
+	declare("dojox.charting.plot2d.__IndicatorCtorArgs", dojox.charting.plot2d.__CartesianCtorArgs, {
+		// summary:
+		//		A special keyword arguments object that is specific to a indicator "plot".
+
+		// lines: Boolean?
+		//		Whether the indicator lines are visible or not. The lines are displayed for each of the
+		//		'values' of the indicator. Default is true.
+		lines: true,
+
+		// labels: String?
+		//		Describes how the indicator labels are displayed.
+		//		Possible values are:
+		//		`"line"` for displaying the value of each indicator line,
+		//		`"marker"` for displaying the values of the markers of each indicator line,
+		//		`"trend"` for displaying the percentage variation from the first to the last indicator line,
+		//		`"none"` to prevent any label to display.
+		//		Default is "line".
+		labels: "line",
+
+		// markers: Boolean?
+		//		Whether the markers on the indicator lines are visible or not. The markers are displayed for each
+		//		of the indicator lines using the series attached to the indicator plot. Default is true.
+		markers: true,
+
+		// values: Boolean
+		//		The data values at which each of the indicator line is drawn. For a single value a Number can be provided
+		//		otherwise an Array of Number is required. fault is [].
+		values: [],
+
+		// offset: {x, y}?
+		//		A pair of (x, y) pixel coordinate to specifiy the offset between the end of the indicator line and the
+		//		position at which the labels are rendered. Default is no offset.
+		offset: {},
+
+		// start: Boolean?
+		//		Whether the label is rendered at the start or end of the indicator line. Default is false meaning end of
+		//		the line.
+		start: false,
+
+		// animate: Boolean?|Number?
+		//		Whether or not to animate the chart to place. When a Number it specifies the duration of the animation.
+		//		Default is false.
+		animate: false,
+
+		// vertical: Boolean?
+		//		Whether the indicator is vertical or not. Default is true.
+		vertical: true,
+
+		// fixed: Boolean?
+		//		Whether a fixed precision must be applied to data values for display. Default is true.
+		fixed: true,
+
+		// precision: Number?
+		//		The precision at which to round data values for display. Default is 0.
+		precision: 0,
+
+		// lineStroke: dojo/gfx/Stroke?
+		//		An optional stroke to use for indicator line.
+		lineStroke: {},
+
+		// lineOutline: dojo/gfx/Stroke?
+		//		An optional outline to use for indicator line.
+		lineOutline: {},
+
+		// lineShadow: dojo/gfx/Stroke?
+		//		An optional shadow to use for indicator line.
+		lineShadow: {},
+
+		// stroke: dojo.gfx.Stroke?
+		//		An optional stroke to use for indicator label background.
+		stroke: {},
+
+		// outline: dojo.gfx.Stroke?
+		//		An optional outline to use for indicator label background.
+		outline: {},
+
+		// shadow: dojo.gfx.Stroke?
+		//		An optional shadow to use for indicator label background.
+		shadow: {},
+
+		// fill: dojo.gfx.Fill?
+		//		An optional fill to use for indicator label background.
+		fill: {},
+
+		// fillFunc: Function?
+		//		An optional function to use to compute label background fill. It takes precedence over
+		//		fill property when available.
+		//	|		function fillFunc(index, values, data) {}
+		//		`index` is the index in the values array of the label being drawn.
+		//		`values` is the entire array of values.
+		//		`data` is the entire array of marker values.
+		fillFunc: null,
+
+		// labelFunc: Function?
+		//		An optional function to use to compute label text. It takes precedence over
+		//		the default text when available.
+		//	|		function labelFunc(index, values, data, fixed, precision, labels) {}
+		//		`index` is the index in the values array of the label being drawn.
+		//		`values` is the entire array of values.
+		//		`data` is the entire array of marker values.
+		//		`fixed` is true if fixed precision must be applied.
+		//		`precision` is the requested precision to be applied.
+		//		`labels` is the labels mode of the indicator.
+		labelFunc: null,
+
+		// font: String?
+		//		A font definition to use for indicator label background.
+		font: "",
+
+		// fontColor: String|dojo.Color?
+		//		The color to use for indicator label background.
+		fontColor: "",
+
+		// markerStroke: dojo.gfx.Stroke?
+		//		An optional stroke to use for indicator marker.
+		markerStroke: {},
+
+		// markerOutline: dojo.gfx.Stroke?
+		//		An optional outline to use for indicator marker.
+		markerOutline: {},
+
+		// markerShadow: dojo.gfx.Stroke?
+		//		An optional shadow to use for indicator marker.
+		markerShadow: {},
+
+		// markerFill: dojo.gfx.Fill?
+		//		An optional fill to use for indicator marker.
+		markerFill: {},
+
+		// markerSymbol: String?
+		//		An optional symbol string to use for indicator marker.
+		markerSymbol: "",
+	});
+	=====*/
+
+	var Indicator = declare("dojox.charting.plot2d.Indicator", [CartesianBase, _PlotEvents], {
+		// summary:
+		//		A "faux" plot that can be placed behind or above other plots to represent a line or multi-line
+		//		threshold on the chart.
+		defaultParams: {
+			vertical: true,
+			fixed: true,
+			precision: 0,
+			lines: true,
+			labels: "line", // "line" | "trend" | "markers" | "none"
+			markers: true
+		},
+		optionalParams: {
+			lineStroke: {},
+			outlineStroke: {},
+			shadowStroke: {},
+			lineFill: {},
+			stroke:		{},
+			outline:	{},
+			shadow:		{},
+			fill:		{},
+			fillFunc:  null,
+			labelFunc: null,
+			font:		"",
+			fontColor:	"",
+			markerStroke:		{},
+			markerOutline:		{},
+			markerShadow:		{},
+			markerFill:			{},
+			markerSymbol:		"",
+			values: [],
+			offset: {},
+			start: false,
+			animate: false
+		},
+
+		constructor: function(chart, kwArgs){
+			// summary:
+			//		Create the faux Grid plot.
+			// chart: dojox/charting/Chart
+			//		The chart this plot belongs to.
+			// kwArgs: dojox.charting.plot2d.__GridCtorArgs?
+			//		An optional keyword arguments object to help define the parameters of the underlying grid.
+			this.opt = lang.clone(this.defaultParams);
+			du.updateWithObject(this.opt, kwArgs);
+			if(typeof kwArgs.values == "number"){
+				kwArgs.values = [ kwArgs.values ];
+			}
+			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+			this.animate = this.opt.animate;
+		},
+		render: function(dim, offsets){
+			if(this.zoom){
+				return this.performZoom(dim, offsets);
+			}
+
+			if(!this.isDirty()){
+				return this;
+			}
+
+			this.cleanGroup(null, true);
+
+			if(!this.opt.values){
+				return this;
+			}
+
+			this._updateIndicator();
+			return this;
+		},
+		_updateIndicator: function(){
+			var t = this.chart.theme;
+			var hn = this._hAxis.name, vn = this._vAxis.name,
+				hb = this._hAxis.getScaler().bounds, vb = this._vAxis.getScaler().bounds;
+			var o = {};
+			o[hn] = hb.from;
+			o[vn] = vb.from;
+			var min = this.toPage(o);
+			o[hn] = hb.to;
+			o[vn] = vb.to;
+			var max = this.toPage(o);
+			var events = this.events();
+			var results = array.map(this.opt.values, function(value, index){
+				return this._renderIndicator(value, index, hn, vn, min, max, events, this.animate);
+			}, this);
+			var length = results.length;
+			if(this.opt.labels == "trend"){
+				var v = this.opt.vertical;
+				var first = this._data[0][0];
+				var last = this._data[length - 1][0];
+				var delta = last-first;
+				var text = this.opt.labelFunc?this.opt.labelFunc(-1, this.values, this._data, this.opt.fixed, this.opt.precision):
+						(dcpc.getLabel(delta, this.opt.fixed, this.opt.precision)+" ("+dcpc.getLabel(100*delta/first, true, 2)+"%)");
+				this._renderText(this.getGroup(), text, this.chart.theme, v?(results[0].x+results[length - 1].x)/2:results[1].x,
+					v?results[0].y:(results[1].y+results[length - 1].y)/2, -1, this.opt.values, this._data);
+			}
+			var lineFill = this.opt.lineFill!=undefined?this.opt.lineFill:t.indicator.lineFill;
+			if(lineFill && length > 1){
+				var x0 = Math.min(results[0].x1, results[length - 1].x1);
+				var y0 =  Math.min(results[0].y1, results[length - 1].y1);
+				var r = this.getGroup().createRect({x: x0, y: y0, width: Math.max(results[0].x2, results[length - 1].x2) - x0,
+															 height: Math.max(results[0].y2, results[length - 1].y2) - y0}).
+					setFill(lineFill);
+				r.moveToBack();
+			}
+		},
+		_renderIndicator: function(coord, index, hn, vn, min, max, events, animate){
+			var t = this.chart.theme, c = this.chart.getCoords(), v = this.opt.vertical;
+
+			var g = this.getGroup().createGroup();
+			var mark = {};
+			mark[hn] = v?coord:0;
+			mark[vn] = v?0:coord;
+			if(has("dojo-bidi")){
+				mark.x = this._getMarkX(mark.x);
+			}
+			mark = this.toPage(mark);
+			var visible = v?mark.x >= min.x && mark.x <= max.x:mark.y >= max.y && mark.y <= min.y;
+
+			var cx = mark.x - c.x, cy = mark.y - c.y;
+			var x1 = v?cx:min.x - c.x, y1 = v?min.y - c.y:cy, x2 = v?x1:max.x - c.x, y2 = v?max.y - c.y:y1;
+
+			if(this.opt.lines && visible){
+				var sh = this.opt.hasOwnProperty("lineShadow")?this.opt.lineShadow:t.indicator.lineShadow,
+					ls = this.opt.hasOwnProperty("lineStroke")?this.opt.lineStroke:t.indicator.lineStroke,
+					ol = this.opt.hasOwnProperty("lineOutline")?this.opt.lineOutline:t.indicator.lineOutline;
+				if(sh){
+					g.createLine({x1: x1 + sh.dx, y1: y1 + sh.dy, x2: x2 + sh.dx, y2: y2 + sh.dy}).setStroke(sh);
+				}
+				if(ol){
+					ol = dcpc.makeStroke(ol);
+					ol.width = 2 * ol.width + (ls?ls.width:0);
+					g.createLine({x1: x1, y1: y1, x2: x2, y2: y2}).setStroke(ol);
+				}
+				g.createLine({x1: x1, y1: y1, x2: x2, y2: y2}).setStroke(ls);
+			}
+
+			// series items represent markers on the indicator
+			var data;
+			if(this.opt.markers && visible){
+				var d = this._data[index];
+				var self = this;
+				if(d){
+					data = array.map(d, function(value, index){
+						mark[hn] = v?coord:value;
+						mark[vn] = v?value:coord;
+						if(has("dojo-bidi")){
+							mark.x = self._getMarkX(mark.x);
+						}
+						mark = this.toPage(mark);
+						if(v?mark.y <= min.y && mark.y >= max.y:mark.x >= min.x && mark.x <= max.x){
+							cx = mark.x - c.x
+							cy = mark.y - c.y;
+							var ms = this.opt.markerSymbol?this.opt.markerSymbol:t.indicator.markerSymbol,
+								path = "M" + cx + " " + cy + " " + ms;
+							sh = this.opt.markerShadow!=undefined?this.opt.markerShadow:t.indicator.markerShadow;
+							ls = this.opt.markerStroke!=undefined?this.opt.markerStroke:t.indicator.markerStroke;
+							ol = this.opt.markerOutline!=undefined?this.opt.markerOutline:t.indicator.markerOutline;
+							if(sh){
+								var sp = "M" + (cx + sh.dx) + " " + (cy + sh.dy) + " " + ms;
+								g.createPath(sp).setFill(sh.color).setStroke(sh);
+							}
+							if(ol){
+								ol = dcpc.makeStroke(ol);
+								ol.width = 2 * ol.width + (ls?ls.width:0);
+								g.createPath(path).setStroke(ol);
+							}
+
+							var shape = g.createPath(path);
+							var sf = this._shapeFill(this.opt.markerFill != undefined?this.opt.markerFill:t.indicator.markerFill, shape.getBoundingBox());
+							shape.setFill(sf).setStroke(ls);
+						}
+						return value;
+					}, this);
+				}
+			}
+			var ctext;
+			if(this.opt.start){
+				ctext = {
+					x: v?x1:x1,
+					y: v?y1:y2
+				};
+			}else{
+				ctext = {
+					x: v?x1:x2,
+					y: v?y2:y1
+				};
+			}
+
+			if(this.opt.labels && this.opt.labels != "trend" && visible){
+				var text;
+				if(this.opt.labelFunc){
+					text = this.opt.labelFunc(index, this.opt.values, this._data,
+						this.opt.fixed, this.opt.precision, this.opt.labels);
+				}else{
+					if(this.opt.labels == "markers"){
+						text = array.map(data, function(value){
+							return dcpc.getLabel(value, this.opt.fixed, this.opt.precision);
+						}, this);
+						text = text.length != 1 ? "[ "+text.join(", ")+" ]" : text[0];
+					}else{
+						text = dcpc.getLabel(coord, this.opt.fixed, this.opt.precision);
+					}
+				}
+				this._renderText(g, text, t, ctext.x, ctext.y, index, this.opt.values, this._data);
+			}
+
+			if(events){
+				this._connectEvents({
+					element: "indicator",
+					run:     this.run?this.run[index]:undefined,
+					shape:   g,
+					value:   coord
+				});
+			}
+
+			if(animate){
+				this._animateIndicator(g, v, v?y1:x1, v?(y1 + y2):(x1 + x2), animate);
+			}
+
+			return lang.mixin(ctext, {x1: x1, y1: y1, x2: x2, y2: y2});
+		},
+		_animateIndicator: function(shape, vertical, offset, size, animate){
+			var transStart = vertical ? [0, offset] : [offset, 0];
+			var scaleStart = vertical ? [1, 1 / size] : [1 / size, 1];
+			fx.animateTransform(lang.delegate({
+				shape: shape,
+				duration: 1200,
+				transform: [
+					{name: "translate", start: transStart, end: [0, 0]},
+					{name: "scale", start: scaleStart, end: [1, 1]},
+					{name: "original"}
+				]
+			}, animate)).play();
+		},
+		clear: function(){
+			this.inherited(arguments);
+			this._data = [];
+		},
+		addSeries: function(run){
+			this.inherited(arguments);
+			this._data.push(run.data);
+		},
+		_renderText: function(g, text, t, x, y, index, values, data){
+			if(this.opt.offset){
+				x += this.opt.offset.x;
+				y += this.opt.offset.y;
+			}
+			var label = dcac.createText.gfx(
+					this.chart,
+					g,
+					x, y,
+					"middle",
+					text, this.opt.font?this.opt.font:t.indicator.font, this.opt.fontColor?this.opt.fontColor:t.indicator.fontColor);
+			var b = getBoundingBox(label);
+			b.x-=2; b.y-=1; b.width+=4; b.height+=2; b.r = this.opt.radius?this.opt.radius:t.indicator.radius;
+			var sh = this.opt.shadow!=undefined?this.opt.shadow:t.indicator.shadow,
+				ls = this.opt.stroke!=undefined?this.opt.stroke:t.indicator.stroke,
+				ol = this.opt.outline!=undefined?this.opt.outline:t.indicator.outline;
+			if(sh){
+				g.createRect(b).setFill(sh.color).setStroke(sh);
+			}
+			if(ol){
+				ol = dcpc.makeStroke(ol);
+				ol.width = 2 * ol.width + (ls?ls.width:0);
+				g.createRect(b).setStroke(ol);
+			}
+			var f = this.opt.fillFunc?this.opt.fillFunc(index, values, data):(this.opt.fill!=undefined?this.opt.fill:t.indicator.fill);
+			g.createRect(b).setFill(this._shapeFill(f, b)).setStroke(ls);
+			label.moveToFront();
+		},
+		getSeriesStats: function(){
+			// summary:
+			//		Returns default stats (irrelevant for this type of plot).
+			// returns: Object
+			//		{hmin, hmax, vmin, vmax} min/max in both directions.
+			return lang.delegate(dcpc.defaultStats);
+		}
+	});
+	if(has("dojo-bidi")){
+		Indicator.extend({
+			_getMarkX: function(x){
+				if(this.chart.isRightToLeft()){
+					return this.chart.axes.x.scaler.bounds.to + this.chart.axes.x.scaler.bounds.from - x;
+				}
+				return x;
+			}			
+		});
+	}
+	return Indicator;
+});
diff --git a/dojox/charting/plot2d/Lines.js b/dojox/charting/plot2d/Lines.js
index 38f55a8..55fb376 100644
--- a/dojox/charting/plot2d/Lines.js
+++ b/dojox/charting/plot2d/Lines.js
@@ -1,12 +1,10 @@
 define(["dojo/_base/declare", "./Default"], function(declare, Default){
-/*=====
-var Default = dojox.charting.plot2d.Default;
-=====*/
+
 	return declare("dojox.charting.plot2d.Lines", Default, {
-		//	summary:
+		// summary:
 		//		A convenience constructor to create a typical line chart.
 		constructor: function(){
-			//	summary:
+			// summary:
 			//		Preset our default plot to be line-based.
 			this.opt.lines = true;
 		}
diff --git a/dojox/charting/plot2d/Markers.js b/dojox/charting/plot2d/Markers.js
index 1757e02..ab4e52c 100644
--- a/dojox/charting/plot2d/Markers.js
+++ b/dojox/charting/plot2d/Markers.js
@@ -1,12 +1,10 @@
 define(["dojo/_base/declare", "./Default"], function(declare, Default){
-/*=====
-var Default = dojox.charting.plot2d.Default
-=====*/
+
 	return declare("dojox.charting.plot2d.Markers", Default, {
-		//	summary:
+		// summary:
 		//		A convenience plot to draw a line chart with markers.
 		constructor: function(){
-			//	summary:
+			// summary:
 			//		Set up the plot for lines and markers.
 			this.opt.markers = true;
 		}
diff --git a/dojox/charting/plot2d/MarkersOnly.js b/dojox/charting/plot2d/MarkersOnly.js
index 06c6052..e67c4c2 100644
--- a/dojox/charting/plot2d/MarkersOnly.js
+++ b/dojox/charting/plot2d/MarkersOnly.js
@@ -1,12 +1,10 @@
 define(["dojo/_base/declare", "./Default"], function(declare, Default){
-/*=====
-var Default = dojox.charting.plot2d.Default;
-=====*/
+
 	return declare("dojox.charting.plot2d.MarkersOnly", Default, {
-		//	summary:
+		// summary:
 		//		A convenience object to draw only markers (like a scatter but not quite).
 		constructor: function(){
-			//	summary:
+			// summary:
 			//		Set up our default plot to only have markers and no lines.
 			this.opt.lines   = false;
 			this.opt.markers = true;
diff --git a/dojox/charting/plot2d/OHLC.js b/dojox/charting/plot2d/OHLC.js
index 6cf7936..d44aefb 100644
--- a/dojox/charting/plot2d/OHLC.js
+++ b/dojox/charting/plot2d/OHLC.js
@@ -1,9 +1,6 @@
-define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Base", "./common", 
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/has", "./CartesianBase", "./_PlotEvents", "./common",
 	"dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/utils", "dojox/gfx/fx"],
-	function(lang, arr, declare, Base, dc, df, dfr, du, fx){
-/*=====
-var Base = dojox.charting.plot2d.Base;
-=====*/
+	function(lang, arr, declare, has, CartesianBase, _PlotEvents, dc, df, dfr, du, fx){
 
 	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
@@ -12,16 +9,14 @@ var Base = dojox.charting.plot2d.Base;
 	//	{ x?, open, close, high, low }
 	//	if x is not provided, the array index is used.
 	//	failing to provide the OHLC values will throw an error.
-	return declare("dojox.charting.plot2d.OHLC", Base, {
-		//	summary:
+	return declare("dojox.charting.plot2d.OHLC", [CartesianBase, _PlotEvents], {
+		// summary:
 		//		A plot that represents typical open/high/low/close (financial reporting, primarily).
 		//		Unlike most charts, the Candlestick expects data points to be represented by
 		//		an object of the form { x?, open, close, high, low, mid? }, where both
 		//		x and mid are optional parameters.  If x is not provided, the index of the
 		//		data array is used.
 		defaultParams: {
-			hAxis: "x",		// use a horizontal axis named "x"
-			vAxis: "y",		// use a vertical axis named "y"
 			gap:	2,		// gap between columns in pixels
 			animate: null	// animate chart to place
 		},
@@ -38,29 +33,26 @@ var Base = dojox.charting.plot2d.Base;
 		},
 
 		constructor: function(chart, kwArgs){
-			//	summary:
+			// summary:
 			//		The constructor for a candlestick chart.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this plot belongs to.
-			//	kwArgs: dojox.charting.plot2d.__BarCtorArgs?
+			// kwArgs: dojox.charting.plot2d.__BarCtorArgs?
 			//		An optional keyword arguments object to help define the plot.
 			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
-			this.series = [];
-			this.hAxis = this.opt.hAxis;
-			this.vAxis = this.opt.vAxis;
 			this.animate = this.opt.animate;
 		},
 
 		collectStats: function(series){
-			//	summary:
+			// summary:
 			//		Collect all statistics for drawing this chart.  Since the common
 			//		functionality only assumes x and y, OHLC must create it's own
 			//		stats (since data has no y value, but open/close/high/low instead).
-			//	series: dojox.charting.Series[]
+			// series: dojox/charting/Series[]
 			//		The data series array to be drawn on this plot.
-			//	returns: Object
+			// returns: Object
 			//		Returns an object in the form of { hmin, hmax, vmin, vmax }.
 
 			//	we have to roll our own, since we need to use all four passed
@@ -84,28 +76,28 @@ var Base = dojox.charting.plot2d.Base;
 				if("ymin" in run){ stats.vmin = Math.min(old_vmin, run.ymin); }
 				if("ymax" in run){ stats.vmax = Math.max(old_vmax, run.ymax); }
 			}
-			return stats;
+			return stats; // Object
 		},
 
 		getSeriesStats: function(){
-			//	summary:
+			// summary:
 			//		Calculate the min/max on all attached series in both directions.
-			//	returns: Object
+			// returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
 			var stats = this.collectStats(this.series);
 			stats.hmin -= 0.5;
 			stats.hmax += 0.5;
-			return stats;
+			return stats; // Object
 		},
 
 		render: function(dim, offsets){
-			//	summary:
+			// summary:
 			//		Run the calculations for any axes for this plot.
-			//	dim: Object
+			// dim: Object
 			//		An object in the form of { width, height }
-			//	offsets: Object
+			// offsets: Object
 			//		An object of the form { l, r, t, b}.
-			//	returns: dojox.charting.plot2d.OHLC
+			// returns: dojox/charting/plot2d/OHLC
 			//		A reference to this plot for functional chaining.
 			if(this.zoom && !this.isDataDirty()){
 				return this.performZoom(dim, offsets);
@@ -116,14 +108,12 @@ var Base = dojox.charting.plot2d.Base;
 				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
-				var s = this.group;
+				var s = this.getGroup();
 				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
 			}
 			var t = this.chart.theme, f, gap, width,
 				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
 				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
-				baseline = Math.max(0, this._vScaler.bounds.lower),
-				baselineHeight = vt(baseline),
 				events = this.events();
 			f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt);
 			gap = f.gap;
@@ -167,7 +157,7 @@ var Base = dojox.charting.plot2d.Base;
 							inner.createLine(op).setStroke(finalTheme.series.stroke);
 							inner.createLine(cl).setStroke(finalTheme.series.stroke);
 
-							//	TODO: double check this.
+							// TODO: double check this.
 							run.dyn.stroke = finalTheme.series.stroke;
 							if(events){
 								var o = {
@@ -196,7 +186,12 @@ var Base = dojox.charting.plot2d.Base;
 				run.dirty = false;
 			}
 			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.OHLC
+			// chart mirroring starts
+			if(has("dojo-bidi")){
+				this._checkOrientation(this.group, dim, offsets);
+			}
+			// chart mirroring ends
+			return this;	//	dojox/charting/plot2d/OHLC
 		},
 		_animateOHLC: function(shape, voffset, vsize){
 			fx.animateTransform(lang.delegate({
diff --git a/dojox/charting/plot2d/Pie.js b/dojox/charting/plot2d/Pie.js
index 5608c95..7b6db20 100644
--- a/dojox/charting/plot2d/Pie.js
+++ b/dojox/charting/plot2d/Pie.js
@@ -1,65 +1,84 @@
 define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare", 
-		"../Element", "./_PlotEvents", "./common", "../axis2d/common", 
-		"dojox/gfx", "dojox/gfx/matrix", "dojox/lang/functional", "dojox/lang/utils"],
-	function(lang, arr, declare, Element, PlotEvents, dc, da, g, m, df, du){
+		"./Base", "./_PlotEvents", "./common",
+		"dojox/gfx", "dojox/gfx/matrix", "dojox/lang/functional", "dojox/lang/utils","dojo/has"],
+	function(lang, arr, declare, Base, PlotEvents, dc, g, m, df, du, has){
 
 	/*=====
-	var Element = dojox.charting.Element;
-	var PlotEvents = dojox.charting.plot2d._PlotEvents;
-	dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
-		//	summary:
+	declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
+		// summary:
 		//		Specialized keyword arguments object for use in defining parameters on a Pie chart.
 	
-		//	labels: Boolean?
+		// labels: Boolean?
 		//		Whether or not to draw labels for each pie slice.  Default is true.
 		labels:			true,
 	
-		//	ticks: Boolean?
+		// ticks: Boolean?
 		//		Whether or not to draw ticks to labels within each slice. Default is false.
 		ticks:			false,
 	
-		//	fixed: Boolean?
-		//		TODO
+		// fixed: Boolean?
+		//		Whether a fixed precision must be applied to data values for display. Default is true.
 		fixed:			true,
 	
-		//	precision: Number?
-		//		The precision at which to sum/add data values. Default is 1.
+		// precision: Number?
+		//		The precision at which to round data values for display. Default is 0.
 		precision:		1,
 	
-		//	labelOffset: Number?
+		// labelOffset: Number?
 		//		The amount in pixels by which to offset labels.  Default is 20.
 		labelOffset:	20,
 	
-		//	labelStyle: String?
+		// labelStyle: String?
 		//		Options as to where to draw labels.  Values include "default", and "columns".	Default is "default".
 		labelStyle:		"default",	// default/columns
-	
-		//	htmlLabels: Boolean?
+		
+		// omitLabels: Boolean?
+		//		Whether labels of slices small to the point of not being visible are omitted.	Default false.
+		omitLabels: false,
+		
+		// htmlLabels: Boolean?
 		//		Whether or not to use HTML to render slice labels. Default is true.
 		htmlLabels:		true,
 	
-		//	radGrad: String?
+		// radGrad: String?
 		//		The type of radial gradient to use in rendering.  Default is "native".
 		radGrad:        "native",
 	
-		//	fanSize: Number?
+		// fanSize: Number?
 		//		The amount for a radial gradient.  Default is 5.
 		fanSize:		5,
 	
-		//	startAngle: Number?
+		// startAngle: Number?
 		//		Where to being rendering gradients in slices, in degrees.  Default is 0.
 		startAngle:     0,
 	
-		//	radius: Number?
+		// radius: Number?
 		//		The size of the radial gradient.  Default is 0.
-		radius:		0
+		radius:		0,
+
+		// shadow: dojox.gfx.Stroke?
+		//		An optional stroke to use to draw any shadows for a series on a plot.
+		shadow:		{},
+
+		// fill: dojox.gfx.Fill?
+		//		Any fill to be used for elements on the plot.
+		fill:		{},
+
+		// filter: dojox.gfx.Filter?
+		//		An SVG filter to be used for elements on the plot. gfx SVG renderer must be used and dojox/gfx/svgext must
+		//		be required for this to work.
+		filter:		{},
+
+		// styleFunc: Function?
+		//		A function that returns a styling object for the a given data item.
+		styleFunc:	null
 	});
 	=====*/
 
 	var FUDGE_FACTOR = 0.2; // use to overlap fans
 
-	return declare("dojox.charting.plot2d.Pie", [Element, PlotEvents], {
-		//	summary:
+	return declare("dojox.charting.plot2d.Pie", [Base, PlotEvents], {
+		// summary:
 		//		The plot that represents a typical pie chart.
 		defaultParams: {
 			labels:			true,
@@ -75,76 +94,74 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 		},
 		optionalParams: {
 			radius:		0,
+			omitLabels: false,
 			// theme components
 			stroke:		{},
 			outline:	{},
 			shadow:		{},
 			fill:		{},
+			filter:     {},
+			styleFunc:	null,
 			font:		"",
 			fontColor:	"",
 			labelWiring: {}
 		},
 
 		constructor: function(chart, kwArgs){
-			//	summary:
+			// summary:
 			//		Create a pie plot.
 			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+			this.axes = [];
 			this.run = null;
 			this.dyn = [];
 		},
 		clear: function(){
-			//	summary:
+			// summary:
 			//		Clear out all of the information tied to this plot.
-			//	returns: dojox.charting.plot2d.Pie
+			// returns: dojox/charting/plot2d/Pie
 			//		A reference to this plot for functional chaining.
-			this.dirty = true;
+			this.inherited(arguments);
 			this.dyn = [];
 			this.run = null;
-			return this;	//	dojox.charting.plot2d.Pie
+			return this;	//	dojox/charting/plot2d/Pie
 		},
 		setAxis: function(axis){
-			//	summary:
+			// summary:
 			//		Dummy method, since axes are irrelevant with a Pie chart.
-			//	returns: dojox.charting.plot2d.Pie
+			// returns: dojox/charting/plot2d/Pie
 			//		The reference to this plot for functional chaining.
-			return this;	//	dojox.charting.plot2d.Pie
+			return this;	//	dojox/charting/plot2d/Pie
 		},
 		addSeries: function(run){
-			//	summary:
+			// summary:
 			//		Add a series of data to this plot.
-			//	returns: dojox.charting.plot2d.Pie
+			// returns: dojox/charting/plot2d/Pie
 			//		The reference to this plot for functional chaining.
 			this.run = run;
-			return this;	//	dojox.charting.plot2d.Pie
+			return this;	//	dojox/charting/plot2d/Pie
 		},
 		getSeriesStats: function(){
-			//	summary:
+			// summary:
 			//		Returns default stats (irrelevant for this type of plot).
-			//	returns: Object
+			// returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
-			return lang.delegate(dc.defaultStats);
-		},
-		initializeScalers: function(){
-			//	summary:
-			//		Does nothing (irrelevant for this type of plot).
-			return this;
+			return lang.delegate(dc.defaultStats); // Object
 		},
 		getRequiredColors: function(){
-			//	summary:
+			// summary:
 			//		Return the number of colors needed to draw this plot.
 			return this.run ? this.run.data.length : 0;
 		},
-
 		render: function(dim, offsets){
-			//	summary:
+			// summary:
 			//		Render the plot on the chart.
-			//	dim: Object
+			// dim: Object
 			//		An object of the form { width, height }.
-			//	offsets: Object
+			// offsets: Object
 			//		An object of the form { l, r, t, b }.
-			//	returns: dojox.charting.plot2d.Pie
+			// returns: dojox/charting/plot2d/Pie
 			//		A reference to this plot for functional chaining.
 			if(!this.dirty){ return this; }
 			this.resetEvents();
@@ -161,45 +178,85 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 			var rx = (dim.width  - offsets.l - offsets.r) / 2,
 				ry = (dim.height - offsets.t - offsets.b) / 2,
 				r  = Math.min(rx, ry),
-				taFont = "font" in this.opt ? this.opt.font : t.axis.font,
-				size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
-				taFontColor = "fontColor" in this.opt ? this.opt.fontColor : t.axis.fontColor,
+				labelFont = "font" in this.opt ? this.opt.font : t.series.font,
+				size,
 				startAngle = m._degToRad(this.opt.startAngle),
-				start = startAngle, step, filteredRun, slices, labels, shift, labelR,
+				start = startAngle, filteredRun, slices, labels, shift, labelR,
 				run = this.run.data,
 				events = this.events();
+
+			this.dyn = [];
+
+			if("radius" in this.opt){
+				r = this.opt.radius;
+				labelR = r - this.opt.labelOffset;
+			}
+			var	circle = {
+					cx: offsets.l + rx,
+					cy: offsets.t + ry,
+					r:  r
+				};
+
+			// draw shadow
+			if(this.opt.shadow || t.shadow){
+				var shadow = this.opt.shadow || t.shadow;
+				var scircle = lang.clone(circle);
+				scircle.cx += shadow.dx;
+				scircle.cy += shadow.dy;
+				s.createCircle(scircle).setFill(shadow.color).setStroke(shadow);
+			}
+			if(s.setFilter && (this.opt.filter || t.filter)){
+				s.createCircle(circle).setFill(t.series.stroke).setFilter(this.opt.filter || t.filter);
+			}
+
 			if(typeof run[0] == "number"){
 				filteredRun = df.map(run, "x ? Math.max(x, 0) : 0");
 				if(df.every(filteredRun, "<= 0")){
+					s.createCircle(circle).setStroke(t.series.stroke);
+					this.dyn = arr.map(filteredRun, function(){
+						return {  };
+					});
 					return this;
-				}
-				slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
-				if(this.opt.labels){
-					labels = arr.map(slices, function(x){
-						return x > 0 ? this._getLabel(x * 100) + "%" : "";
-					}, this);
+				}else{
+					slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
+				 	if(this.opt.labels){
+				 		labels = arr.map(slices, function(x){
+							return x > 0 ? this._getLabel(x * 100) + "%" : "";
+						}, this);
+					}
 				}
 			}else{
 				filteredRun = df.map(run, "x ? Math.max(x.y, 0) : 0");
 				if(df.every(filteredRun, "<= 0")){
+					s.createCircle(circle).setStroke(t.series.stroke);
+					this.dyn = arr.map(filteredRun, function(){
+						return {  };
+					});
 					return this;
-				}
-				slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
-				if(this.opt.labels){
-					labels = arr.map(slices, function(x, i){
-						if(x <= 0){ return ""; }
-						var v = run[i];
-						return "text" in v ? v.text : this._getLabel(x * 100) + "%";
-					}, this);
+				}else{
+					slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
+					if(this.opt.labels){
+						labels = arr.map(slices, function(x, i){
+							if(x < 0){ return ""; }
+							var v = run[i];
+							return "text" in v ? v.text : this._getLabel(x * 100) + "%";
+						}, this);
+					}
 				}
 			}
 			var themes = df.map(run, function(v, i){
-				if(v === null || typeof v == "number"){
-					return t.next("slice", [this.opt, this.run], true);
+				var tMixin = [this.opt, this.run];
+				if(v !== null && typeof v != "number"){
+					tMixin.push(v);
 				}
-				return t.next("slice", [this.opt, this.run, v], true);
+				if(this.opt.styleFunc){
+					tMixin.push(this.opt.styleFunc(v));
+				}
+				return t.next("slice", tMixin, true);
 			}, this);
+
 			if(this.opt.labels){
+				size = labelFont ? g.normalizedLength(g.splitFontString(labelFont).size) : 0;
 				shift = df.foldl1(df.map(labels, function(label, i){
 					var font = themes[i].series.font;
 					return g._base._getTextBox(label, {font: font}).w;
@@ -209,17 +266,7 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 				}
 				labelR = r - this.opt.labelOffset;
 			}
-			if("radius" in this.opt){
-				r = this.opt.radius;
-				labelR = r - this.opt.labelOffset;
-			}
-			var	circle = {
-					cx: offsets.l + rx,
-					cy: offsets.t + ry,
-					r:  r
-				};
 
-			this.dyn = [];
 			// draw slices
 			var eventSeries = new Array(slices.length);
 			arr.some(slices, function(slice, i){
@@ -231,7 +278,7 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 				  this.dyn.push({fill: null, stroke: null});
 				  return false;
 				}
-				var v = run[i], theme = themes[i], specialFill;
+				var v = run[i], theme = themes[i], specialFill, o;
 				if(slice >= 1){
 					// whole pie
 					specialFill = this._plotFill(theme.series.fill, dim, offsets);
@@ -245,7 +292,7 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 					this.dyn.push({fill: specialFill, stroke: theme.series.stroke});
 
 					if(events){
-						var o = {
+						o = {
 							element: "slice",
 							index:   i,
 							run:     this.run,
@@ -260,7 +307,7 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 						eventSeries[i] = o;
 					}
 
-					return true;	// stop iteration
+					return false;	// we continue because we want to collect null data points for legend
 				}
 				// calculate the geometry of the slice
 				var end = start + slice * 2 * Math.PI;
@@ -282,8 +329,8 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 						var fansx = j == 0 ? x1 : circle.cx + r * Math.cos(start + (j - FUDGE_FACTOR) * delta),
 							fansy = j == 0 ? y1 : circle.cy + r * Math.sin(start + (j - FUDGE_FACTOR) * delta),
 							fanex = j == nfans - 1 ? x2 : circle.cx + r * Math.cos(start + (j + 1 + FUDGE_FACTOR) * delta),
-							faney = j == nfans - 1 ? y2 : circle.cy + r * Math.sin(start + (j + 1 + FUDGE_FACTOR) * delta),
-							fan = group.createPath().
+							faney = j == nfans - 1 ? y2 : circle.cy + r * Math.sin(start + (j + 1 + FUDGE_FACTOR) * delta);
+						group.createPath().
 								moveTo(circle.cx, circle.cy).
 								lineTo(fansx, fansy).
 								arcTo(r, r, 0, delta > Math.PI, true, fanex, faney).
@@ -307,7 +354,7 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 						lineTo(circle.cx, circle.cy).
 						closePath().
 						setStroke(theme.series.stroke);
-					var specialFill = theme.series.fill;
+					specialFill = theme.series.fill;
 					if(specialFill && specialFill.type === "radial"){
 						specialFill = this._shapeFill(specialFill, {x: circle.cx - circle.r, y: circle.cy - circle.r, width: 2 * circle.r, height: 2 * circle.r});
 						if(this.opt.radGrad === "linear"){
@@ -322,7 +369,7 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 				this.dyn.push({fill: specialFill, stroke: theme.series.stroke});
 
 				if(events){
-					var o = {
+					o = {
 						element: "slice",
 						index:   i,
 						run:     this.run,
@@ -343,7 +390,8 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 			}, this);
 			// draw labels
 			if(this.opt.labels){
-				if(this.opt.labelStyle == "default"){
+				var isRtl = has("dojo-bidi") && this.chart.isRightToLeft(); 
+				if(this.opt.labelStyle == "default"){ // inside or outside based on labelOffset
 					start = startAngle;
 					arr.some(slices, function(slice, i){
 						if(slice <= 0){
@@ -353,33 +401,28 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 						var theme = themes[i];
 						if(slice >= 1){
 							// whole pie
-							var v = run[i], elem = da.createText[this.opt.htmlLabels && g.renderer != "vml" ? "html" : "gfx"](
-									this.chart, s, circle.cx, circle.cy + size / 2, "middle", labels[i],
-									theme.series.font, theme.series.fontColor);
-							if(this.opt.htmlLabels){
-								this.htmlElements.push(elem);
-							}
+							this.renderLabel(s, circle.cx, circle.cy + size / 2, labels[i], theme, this.opt.labelOffset > 0);
 							return true;	// stop iteration
 						}
 						// calculate the geometry of the slice
-						var end = start + slice * 2 * Math.PI, v = run[i];
+						var end = start + slice * 2 * Math.PI;
 						if(i + 1 == slices.length){
 							end = startAngle + 2 * Math.PI;
 						}
+						if(this.opt.omitLabels && end-start < 0.001){
+							return false;	// continue
+						}
 						var	labelAngle = (start + end) / 2,
 							x = circle.cx + labelR * Math.cos(labelAngle),
 							y = circle.cy + labelR * Math.sin(labelAngle) + size / 2;
 						// draw the label
-						var elem = da.createText[this.opt.htmlLabels && g.renderer != "vml" ? "html" : "gfx"]
-								(this.chart, s, x, y, "middle", labels[i], theme.series.font, theme.series.fontColor);
-						if(this.opt.htmlLabels){
-							this.htmlElements.push(elem);
-						}
+						this.renderLabel(s, isRtl ? dim.width - x : x, y, labels[i], theme, this.opt.labelOffset > 0);
 						start = end;
 						return false;	// continue
 					}, this);
 				}else if(this.opt.labelStyle == "columns"){
 					start = startAngle;
+					var omitLabels = this.opt.omitLabels;
 					//calculate label angles
 					var labeledSlices = [];
 					arr.forEach(slices, function(slice, i){
@@ -393,33 +436,29 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 							left: Math.cos(labelAngle) < 0,
 							theme: themes[i],
 							index: i,
-							omit: end - start < 0.001
+							omit: omitLabels?end - start < 0.001:false
 						});
 						start = end;
 					});
 					//calculate label radius to each slice
-					var labelHeight = g._base._getTextBox("a",{font:taFont}).h;
+					var labelHeight = g._base._getTextBox("a",{ font: labelFont }).h;
 					this._getProperLabelRadius(labeledSlices, labelHeight, circle.r * 1.1);
 					//draw label and wiring
 					arr.forEach(labeledSlices, function(slice, i){
-						if (!slice.omit) {
+						if(!slice.omit){
 							var leftColumn = circle.cx - circle.r * 2,
 								rightColumn = circle.cx + circle.r * 2,
-								labelWidth = g._base._getTextBox(labels[i], {font: taFont}).w,
+								labelWidth = g._base._getTextBox(labels[i], {font: slice.theme.series.font}).w,
 								x = circle.cx + slice.labelR * Math.cos(slice.angle),
 								y = circle.cy + slice.labelR * Math.sin(slice.angle),
 								jointX = (slice.left) ? (leftColumn + labelWidth) : (rightColumn - labelWidth),
 								labelX = (slice.left) ? leftColumn : jointX;
-							var wiring = s.createPath().moveTo(circle.cx + circle.r * Math.cos(slice.angle), circle.cy + circle.r * Math.sin(slice.angle))
-							if (Math.abs(slice.labelR * Math.cos(slice.angle)) < circle.r * 2 - labelWidth) {
+							var wiring = s.createPath().moveTo(circle.cx + circle.r * Math.cos(slice.angle), circle.cy + circle.r * Math.sin(slice.angle));
+							if(Math.abs(slice.labelR * Math.cos(slice.angle)) < circle.r * 2 - labelWidth){
 								wiring.lineTo(x, y);
 							}
 							wiring.lineTo(jointX, y).setStroke(slice.theme.series.labelWiring);
-							var elem = da.createText[this.opt.htmlLabels && g.renderer != "vml" ? "html" : "gfx"](
-								this.chart, s, labelX, y, "left", labels[i], slice.theme.series.font, slice.theme.series.fontColor);
-							if (this.opt.htmlLabels) {
-								this.htmlElements.push(elem);
-							}
+							this.renderLabel(s, isRtl ? dim.width - labelWidth - labelX : labelX, y, labels[i], slice.theme, false, "left");
 						}
 					},this);
 				}
@@ -429,39 +468,44 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 			this._eventSeries[this.run.name] = df.map(run, function(v){
 				return v <= 0 ? null : eventSeries[esi++];
 			});
-			return this;	//	dojox.charting.plot2d.Pie
+			// chart mirroring starts
+			if(has("dojo-bidi")){
+				this._checkOrientation(this.group, dim, offsets);
+			}
+			// chart mirroring ends
+			return this;	//	dojox/charting/plot2d/Pie
 		},
-		
 		_getProperLabelRadius: function(slices, labelHeight, minRidius){
-			var leftCenterSlice = {},rightCenterSlice = {},leftMinSIN = 1, rightMinSIN = 1;
-			if (slices.length == 1) {
+			var leftCenterSlice, rightCenterSlice,
+				leftMinSIN = 1, rightMinSIN = 1;
+			if(slices.length == 1){
 				slices[0].labelR = minRidius;
 				return;
 			}
-			for(var i = 0;i<slices.length;i++){
+			for(var i = 0; i < slices.length; i++){
 				var tempSIN = Math.abs(Math.sin(slices[i].angle));
 				if(slices[i].left){
-					if(leftMinSIN > tempSIN){
+					if(leftMinSIN >= tempSIN){
 						leftMinSIN = tempSIN;
 						leftCenterSlice = slices[i];
 					}
 				}else{
-					if(rightMinSIN > tempSIN){
+					if(rightMinSIN >= tempSIN){
 						rightMinSIN = tempSIN;
 						rightCenterSlice = slices[i];
 					}
 				}
 			}
 			leftCenterSlice.labelR = rightCenterSlice.labelR = minRidius;
-			this._calculateLabelR(leftCenterSlice,slices,labelHeight);
-			this._calculateLabelR(rightCenterSlice,slices,labelHeight);
+			this._calculateLabelR(leftCenterSlice, slices, labelHeight);
+			this._calculateLabelR(rightCenterSlice, slices, labelHeight);
 		},
-		_calculateLabelR: function(firstSlice,slices,labelHeight){
+		_calculateLabelR: function(firstSlice, slices, labelHeight){
 			var i = firstSlice.index,length = slices.length,
-				currentLabelR = firstSlice.labelR;
+				currentLabelR = firstSlice.labelR, nextLabelR;
 			while(!(slices[i%length].left ^ slices[(i+1)%length].left)){
-				if (!slices[(i + 1) % length].omit) {
-					var nextLabelR = (Math.sin(slices[i % length].angle) * currentLabelR + ((slices[i % length].left) ? (-labelHeight) : labelHeight)) /
+				if(!slices[(i + 1) % length].omit){
+					nextLabelR = (Math.sin(slices[i % length].angle) * currentLabelR + ((slices[i % length].left) ? (-labelHeight) : labelHeight)) /
 					Math.sin(slices[(i + 1) % length].angle);
 					currentLabelR = (nextLabelR < firstSlice.labelR) ? firstSlice.labelR : nextLabelR;
 					slices[(i + 1) % length].labelR = currentLabelR;
@@ -471,8 +515,8 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 			i = firstSlice.index;
 			var j = (i == 0)?length-1 : i - 1;
 			while(!(slices[i].left ^ slices[j].left)){
-				if (!slices[j].omit) {
-					var nextLabelR = (Math.sin(slices[i].angle) * currentLabelR + ((slices[i].left) ? labelHeight : (-labelHeight))) /
+				if(!slices[j].omit){
+					nextLabelR = (Math.sin(slices[i].angle) * currentLabelR + ((slices[i].left) ? labelHeight : (-labelHeight))) /
 					Math.sin(slices[j].angle);
 					currentLabelR = (nextLabelR < firstSlice.labelR) ? firstSlice.labelR : nextLabelR;
 					slices[j].labelR = currentLabelR;
@@ -481,10 +525,6 @@ define(["dojo/_base/lang", "dojo/_base/array" ,"dojo/_base/declare",
 				i = (i < 0)?i+slices.length:i;
 				j = (j < 0)?j+slices.length:j;
 			}
-		},
-		// utilities
-		_getLabel: function(number){
-			return dc.getLabel(number, this.opt.fixed, this.opt.precision);
 		}
 	});
 });
diff --git a/dojox/charting/plot2d/Scatter.js b/dojox/charting/plot2d/Scatter.js
index d5434b7..1120d4f 100644
--- a/dojox/charting/plot2d/Scatter.js
+++ b/dojox/charting/plot2d/Scatter.js
@@ -1,17 +1,13 @@
-define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Base", "./common", 
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/has", "./CartesianBase", "./_PlotEvents", "./common",
 	"dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/utils", "dojox/gfx/fx", "dojox/gfx/gradutils"],
-	function(lang, arr, declare, Base, dc, df, dfr, du, fx, gradutils){
-/*=====
-var Base = dojox.charting.plot2d.Base;
-=====*/
+	function(lang, arr, declare, has, CartesianBase, _PlotEvents, dc, df, dfr, du, fx, gradutils){
+
 	var purgeGroup = dfr.lambda("item.purgeGroup()");
 
-	return declare("dojox.charting.plot2d.Scatter", Base, {
-		//	summary:
+	return declare("dojox.charting.plot2d.Scatter", [CartesianBase, _PlotEvents], {
+		// summary:
 		//		A plot object representing a typical scatter chart.
 		defaultParams: {
-			hAxis: "x",		// use a horizontal axis named "x"
-			vAxis: "y",		// use a vertical axis named "y"
 			shadows: null,	// draw shadows
 			animate: null	// animate chart to place
 		},
@@ -22,44 +18,43 @@ var Base = dojox.charting.plot2d.Base;
 			markerShadow:		{},
 			markerFill:			{},
 			markerFont:			"",
-			markerFontColor:	""
+			markerFontColor:	"",
+			styleFunc:			null
 		},
 
 		constructor: function(chart, kwArgs){
-			//	summary:
+			// summary:
 			//		Create the scatter plot.
-			//	chart: dojox.charting.Chart
+			// chart: dojox/charting/Chart
 			//		The chart this plot belongs to.
-			//	kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
+			// kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
 			//		An optional keyword arguments object to help define this plot's parameters.
-			this.opt = lang.clone(this.defaultParams);
-            du.updateWithObject(this.opt, kwArgs);
-            du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
-			this.series = [];
-			this.hAxis = this.opt.hAxis;
-			this.vAxis = this.opt.vAxis;
+			this.opt = lang.clone(lang.mixin(this.opt, this.defaultParams));
+			du.updateWithObject(this.opt, kwArgs);
+			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.animate = this.opt.animate;
 		},
 
 		render: function(dim, offsets){
-			//	summary:
+			// summary:
 			//		Run the calculations for any axes for this plot.
-			//	dim: Object
+			// dim: Object
 			//		An object in the form of { width, height }
-			//	offsets: Object
+			// offsets: Object
 			//		An object of the form { l, r, t, b}.
-			//	returns: dojox.charting.plot2d.Scatter
+			// returns: dojox/charting/plot2d/Scatter
 			//		A reference to this plot for functional chaining.
 			if(this.zoom && !this.isDataDirty()){
 				return this.performZoom(dim, offsets);
 			}
 			this.resetEvents();
 			this.dirty = this.isDirty();
+			var s;
 			if(this.dirty){
 				arr.forEach(this.series, purgeGroup);
 				this._eventSeries = {};
 				this.cleanGroup();
-				var s = this.group;
+				s = this.getGroup();
 				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
 			}
 			var t = this.chart.theme, events = this.events();
@@ -77,9 +72,10 @@ var Base = dojox.charting.plot2d.Base;
 					continue;
 				}
 
-				var theme = t.next("marker", [this.opt, run]), s = run.group, lpoly,
+				var theme = t.next("marker", [this.opt, run]), lpoly,
 					ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
 					vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler);
+				s = run.group;
 				if(typeof run.data[0] == "number"){
 					lpoly = arr.map(run.data, function(v, i){
 						return {
@@ -101,10 +97,17 @@ var Base = dojox.charting.plot2d.Base;
 					outlineMarkers = new Array(lpoly.length);
 
 				arr.forEach(lpoly, function(c, i){
-					var finalTheme = typeof run.data[i] == "number" ?
-							t.post(theme, "marker") :
-							t.addMixin(theme, "marker", run.data[i], true),
-						path = "M" + c.x + " " + c.y + " " + finalTheme.symbol;
+					var value = run.data[i], finalTheme;
+					if(this.opt.styleFunc || typeof value != "number"){
+						var tMixin = typeof value != "number" ? [value] : [];
+						if(this.opt.styleFunc){
+							tMixin.push(this.opt.styleFunc(value));
+						}
+						finalTheme = t.addMixin(theme, "marker", tMixin, true);
+					}else{
+						finalTheme = t.post(theme, "marker");
+					}
+					var path = "M" + c.x + " " + c.y + " " + finalTheme.symbol;
 					if(finalTheme.marker.shadow){
 						shadowMarkers[i] = s.createPath("M" + (c.x + finalTheme.marker.shadow.dx) + " " +
 							(c.y + finalTheme.marker.shadow.dy) + " " + finalTheme.symbol).
@@ -132,13 +135,18 @@ var Base = dojox.charting.plot2d.Base;
 					}else{
 						frontMarkers[i] = s.createPath(path).setStroke(stroke).setFill(fill);
 					}
+					if(this.opt.labels){
+						var markerBox = frontMarkers[i].getBoundingBox();
+						this.createLabel(s, value, markerBox, finalTheme);
+					}
 					if(this.animate){
 						this._animateScatter(frontMarkers[i], dim.height - offsets.b);
 					}
 				}, this);
 				if(frontMarkers.length){
-					run.dyn.stroke = frontMarkers[frontMarkers.length - 1].getStroke();
-					run.dyn.fill   = frontMarkers[frontMarkers.length - 1].getFill();
+					run.dyn.marker = theme.symbol;
+					run.dyn.markerStroke = frontMarkers[frontMarkers.length - 1].getStroke();
+					run.dyn.markerFill   = frontMarkers[frontMarkers.length - 1].getFill();
 				}
 
 				if(events){
@@ -171,7 +179,12 @@ var Base = dojox.charting.plot2d.Base;
 				run.dirty = false;
 			}
 			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.Scatter
+			// chart mirroring starts
+			if(has("dojo-bidi")){
+				this._checkOrientation(this.group, dim, offsets);
+			}
+			// chart mirroring ends
+			return this;	//	dojox/charting/plot2d/Scatter
 		},
 		_animateScatter: function(shape, offset){
 			fx.animateTransform(lang.delegate({
diff --git a/dojox/charting/plot2d/Spider.js b/dojox/charting/plot2d/Spider.js
index 9178e94..e5818c5 100644
--- a/dojox/charting/plot2d/Spider.js
+++ b/dojox/charting/plot2d/Spider.js
@@ -1,19 +1,15 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/html", "dojo/_base/array",
-	"dojo/dom-geometry", "dojo/_base/fx", "dojo/fx", "dojo/_base/sniff", 
-	"../Element", "./_PlotEvents", "dojo/_base/Color", "dojox/color/_base", "./common", "../axis2d/common", 
-	"../scaler/primitive", "dojox/gfx", "dojox/gfx/matrix", "dojox/gfx/fx", "dojox/lang/functional", 
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/array",
+	"dojo/dom-geometry", "dojo/_base/fx", "dojo/fx", "dojo/sniff",
+	"./Base", "./_PlotEvents", "./common", "../axis2d/common",
+	"dojox/gfx", "dojox/gfx/matrix", "dojox/gfx/fx", "dojox/lang/functional",
 	"dojox/lang/utils", "dojo/fx/easing"],
-	function(lang, declare, hub, html, arr, domGeom, baseFx, coreFx, has, 
-			Element, PlotEvents, Color, dxcolor, dc, da, primitive,
-			g, m, gfxfx, df, du, easing){
-/*=====
-var Element = dojox.charting.Element;
-var PlotEvents = dojox.charting.plot2d._PlotEvents;
-=====*/
+	function(lang, declare, hub, arr, domGeom, baseFx, coreFx, has,
+			Base, PlotEvents, dc, da, g, m, gfxfx, df, du, easing){
+
 	var FUDGE_FACTOR = 0.2; // use to overlap fans
 
-	var Spider = declare("dojox.charting.plot2d.Spider", [Element, PlotEvents], {
-		//	summary:
+	var Spider = declare("dojox.charting.plot2d.Spider", [Base, PlotEvents], {
+		// summary:
 		//		The plot that represents a typical Spider chart.
 		defaultParams: {
 			labels:			true,
@@ -47,12 +43,15 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 		},
 
 		constructor: function(chart, kwArgs){
-			//	summary:
+			// summary:
 			//		Create a Spider plot.
+			// chart: dojox/charting/Chart
+			//		The chart this plot belongs to.
+			// kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
+			//		An optional keyword arguments object to help define this plot's parameters.
 			this.opt = lang.clone(this.defaultParams);
 			du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
-			this.series = [];
 			this.dyn = [];
 			this.datas = {};
 			this.labelKey = [];
@@ -60,36 +59,46 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 			this.animations = {};
 		},
 		clear: function(){
-			//	summary:
+			// summary:
 			//		Clear out all of the information tied to this plot.
-			//	returns: dojox.charting.plot2d.Spider
+			// returns: dojox/charting/plot2d/Spider
 			//		A reference to this plot for functional chaining.
-			this.dirty = true;
+			this.inherited(arguments);
 			this.dyn = [];
-			this.series = [];
+			this.axes = [];
 			this.datas = {};
 			this.labelKey = [];
 			this.oldSeriePoints = {};
 			this.animations = {};
-			return this;	//	dojox.charting.plot2d.Spider
+			return this;	//	dojox/charting/plot2d/Spider
 		},
 		setAxis: function(axis){
-			//	summary:
-			//		Dummy method, since axes are irrelevant with a Spider chart.
-			//	returns: dojox.charting.plot2d.Spider
+			// summary:
+			//		Optionally set axis min and max property.
+			// returns: dojox/charting/plot2d/Spider
 			//		The reference to this plot for functional chaining.
-			return this;	//	dojox.charting.plot2d.Spider
+
+			// override the computed min/max with provided values if any
+			if(axis){
+				if(axis.opt.min != undefined){
+					this.datas[axis.name].min = axis.opt.min;
+				}
+				if(axis.opt.max != undefined){
+					this.datas[axis.name].max = axis.opt.max;
+				}
+			}
+			return this;	//	dojox/charting/plot2d/Spider
 		},
 		addSeries: function(run){
-			//	summary:
+			// summary:
 			//		Add a data series to this plot.
-			//	run: dojox.charting.Series
+			// run: dojox.charting.Series
 			//		The series to be added.
-			//	returns: dojox.charting.plot2d.Base
+			// returns: dojox/charting/plot2d/Base
 			//		A reference to this plot for functional chaining.
-			var matched = false;
 			this.series.push(run);
-			for(var key in run.data){
+			var key;
+			for(key in run.data){
 				var val = run.data[key],
 					data = this.datas[key];
 				if(data){
@@ -97,75 +106,34 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 					data.min = Math.min(data.min, val);
 					data.max = Math.max(data.max, val);
 				}else{
+					var axisKey = "__"+key;
+					this.axes.push(axisKey);
+					this[axisKey] = key;
 					this.datas[key] = {min: val, max: val, vlist: [val]};
 				}
 			}
-			if (this.labelKey.length <= 0) {
-				for (var key in run.data) {
+			if(this.labelKey.length <= 0){
+				for(key in run.data){
 					this.labelKey.push(key);
 				}
 			}
 			return this;	//	dojox.charting.plot2d.Base
 		},
 		getSeriesStats: function(){
-			//	summary:
+			// summary:
 			//		Calculate the min/max on all attached series in both directions.
-			//	returns: Object
+			// returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
-			return dc.collectSimpleStats(this.series);
-		},
-		calculateAxes: function(dim){
-			//	summary:
-			//		Stub function for running the axis calculations (depricated).
-			//	dim: Object
-			//		An object of the form { width, height }
-			//	returns: dojox.charting.plot2d.Base
-			//		A reference to this plot for functional chaining.
-			this.initializeScalers(dim, this.getSeriesStats());
-			return this;	//	dojox.charting.plot2d.Base
-		},
-		getRequiredColors: function(){
-			//	summary:
-			//		Get how many data series we have, so we know how many colors to use.
-			//	returns: Number
-			//		The number of colors needed.
-			return this.series.length;	//	Number
-		},
-		initializeScalers: function(dim, stats){
-			//	summary:
-			//		Initializes scalers using attached axes.
-			//	dim: Object:
-			//		Size of a plot area in pixels as {width, height}.
-			//	stats: Object:
-			//		Min/max of data in both directions as {hmin, hmax, vmin, vmax}.
-			//	returns: dojox.charting.plot2d.Base
-			//		A reference to this plot for functional chaining.
-			if(this._hAxis){
-				if(!this._hAxis.initialized()){
-					this._hAxis.calculate(stats.hmin, stats.hmax, dim.width);
-				}
-				this._hScaler = this._hAxis.getScaler();
-			}else{
-				this._hScaler = primitive.buildScaler(stats.hmin, stats.hmax, dim.width);
-			}
-			if(this._vAxis){
-				if(!this._vAxis.initialized()){
-					this._vAxis.calculate(stats.vmin, stats.vmax, dim.height);
-				}
-				this._vScaler = this._vAxis.getScaler();
-			}else{
-				this._vScaler = primitive.buildScaler(stats.vmin, stats.vmax, dim.height);
-			}
-			return this;	//	dojox.charting.plot2d.Base
+			return dc.collectSimpleStats(this.series); // Object
 		},
 		render: function(dim, offsets){
-			//	summary:
+			// summary:
 			//		Render the plot on the chart.
-			//	dim: Object
+			// dim: Object
 			//		An object of the form { width, height }.
-			//	offsets: Object
+			// offsets: Object
 			//		An object of the form { l, r, t, b }.
-			//	returns: dojox.charting.plot2d.Spider
+			// returns: dojox/charting/plot2d/Spider
 			//		A reference to this plot for functional chaining.
 			if(!this.dirty){ return this; }
 			this.dirty = false;
@@ -193,17 +161,18 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 				seriesWidth = o.seriesWidth || (ta.stroke && ta.stroke.width) || 2,
 				asize = g.normalizedLength(g.splitFontString(axisFont).size),
 				startAngle = m._degToRad(o.startAngle),
-				start = startAngle, step, filteredRun, slices, labels, shift, labelR,
+				start = startAngle, labels, shift, labelR,
 				outerPoints, innerPoints, divisionPoints, divisionRadius, labelPoints,
 				ro = o.spiderOrigin, dv = o.divisions >= 3 ? o.divisions : 3, ms = o.markerSize,
 				spt = o.spiderType, at = o.animationType, lboffset = o.labelOffset < -10 ? o.labelOffset : -10,
-				axisExtra = 0.2;
+				axisExtra = 0.2,
+				i, j, point, len, fontWidth, render, serieEntry, run, data, min, max, distance;
 			
 			if(o.labels){
 				labels = arr.map(this.series, function(s){
 					return s.name;
 				}, this);
-				shift = df.foldl1(df.map(labels, function(label, i){
+				shift = df.foldl1(df.map(labels, function(label){
 					var font = t.series.font;
 					return g._base._getTextBox(label, {
 						font: font
@@ -212,7 +181,7 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 				r = Math.min(rx - 2 * shift, ry - asize) + lboffset;
 				labelR = r - lboffset;
 			}
-			if ("radius" in o) {
+			if("radius" in o){
 				r = o.radius;
 				labelR = r - lboffset;
 			}
@@ -222,28 +191,28 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 				cy: offsets.t + ry,
 				r: r
 			};
-			
-			for (var i = this.series.length - 1; i >= 0; i--) {
-				var serieEntry = this.series[i];
-				if (!this.dirty && !serieEntry.dirty) {
+
+			for (i = this.series.length - 1; i >= 0; i--){
+				serieEntry = this.series[i];
+				if(!this.dirty && !serieEntry.dirty){
 					t.skip();
 					continue;
 				}
 				serieEntry.cleanGroup();
-				var run = serieEntry.data;
-				if (run !== null) {
-					var len = this._getObjectLength(run);
+				run = serieEntry.data;
+				if(run !== null){
+					len = this._getObjectLength(run);
 					//construct connect points
-					if (!outerPoints || outerPoints.length <= 0) {
+					if(!outerPoints || outerPoints.length <= 0){
 						outerPoints = [], innerPoints = [], labelPoints = [];
-						this._buildPoints(outerPoints, len, circle, r, start, true);
-						this._buildPoints(innerPoints, len, circle, r*ro, start, true);
-						this._buildPoints(labelPoints, len, circle, labelR, start);
+						this._buildPoints(outerPoints, len, circle, r, start, true, dim);
+						this._buildPoints(innerPoints, len, circle, r*ro, start, true, dim);
+						this._buildPoints(labelPoints, len, circle, labelR, start, false, dim);
 						if(dv > 2){
 							divisionPoints = [], divisionRadius = [];
-							for (var j = 0; j < dv - 2; j++) {
+							for (j = 0; j < dv - 2; j++){
 								divisionPoints[j] = [];
-								this._buildPoints(divisionPoints[j], len, circle, r*(ro + (1-ro)*(j+1)/(dv-1)), start, true);
+								this._buildPoints(divisionPoints[j], len, circle, r*(ro + (1-ro)*(j+1)/(dv-1)), start, true, dim);
 								divisionRadius[j] = r*(ro + (1-ro)*(j+1)/(dv-1));
 							}
 						}
@@ -255,9 +224,9 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 			//axis
 			var axisGroup = s.createGroup(), axisStroke = {color: axisColor, width: axisWidth},
 				spiderStroke = {color: spiderColor, width: spiderWidth};
-			for (var j = outerPoints.length - 1; j >= 0; --j) {
-				var point = outerPoints[j],
-					st = {
+			for (j = outerPoints.length - 1; j >= 0; --j){
+				point = outerPoints[j];
+				var st = {
 						x: point.x + (point.x - circle.cx) * axisExtra,
 						y: point.y + (point.y - circle.cy) * axisExtra
 					},
@@ -277,13 +246,13 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 			
 			// draw the label
 			var labelGroup = s.createGroup();
-			for (var j = labelPoints.length - 1; j >= 0; --j) {
-				var point = labelPoints[j],
-					fontWidth = g._base._getTextBox(this.labelKey[j], {font: axisFont}).w || 0,
-					render = this.opt.htmlLabels && g.renderer != "vml" ? "html" : "gfx",
-					elem = da.createText[render](this.chart, labelGroup, (!domGeom.isBodyLtr() && render == "html") ? (point.x + fontWidth - dim.width) : point.x, point.y,
+			for (j = labelPoints.length - 1; j >= 0; --j){
+				point = labelPoints[j];
+				fontWidth = g._base._getTextBox(this.labelKey[j], {font: axisFont}).w || 0;
+				render = this.opt.htmlLabels && g.renderer != "vml" ? "html" : "gfx";
+				var elem = da.createText[render](this.chart, labelGroup, (!domGeom.isBodyLtr() && render == "html") ? (point.x + fontWidth - dim.width) : point.x, point.y,
 							"middle", this.labelKey[j], axisFont, axisFontColor);
-				if (this.opt.htmlLabels) {
+				if(this.opt.htmlLabels){
 					this.htmlElements.push(elem);
 				}
 			}
@@ -293,32 +262,36 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 			if(spt == "polygon"){
 				spiderGroup.createPolyline(outerPoints).setStroke(spiderStroke);
 				spiderGroup.createPolyline(innerPoints).setStroke(spiderStroke);
-				if (divisionPoints.length > 0) {
-					for (var j = divisionPoints.length - 1; j >= 0; --j) {
+				if(divisionPoints.length > 0){
+					for (j = divisionPoints.length - 1; j >= 0; --j){
 						spiderGroup.createPolyline(divisionPoints[j]).setStroke(spiderStroke);
 					}
 				}
 			}else{//circle
-				var ccount = this._getObjectLength(this.datas);
 				spiderGroup.createCircle({cx: circle.cx, cy: circle.cy, r: r}).setStroke(spiderStroke);
 				spiderGroup.createCircle({cx: circle.cx, cy: circle.cy, r: r*ro}).setStroke(spiderStroke);
-				if (divisionRadius.length > 0) {
-					for (var j = divisionRadius.length - 1; j >= 0; --j) {
+				if(divisionRadius.length > 0){
+					for (j = divisionRadius.length - 1; j >= 0; --j){
 						spiderGroup.createCircle({cx: circle.cx, cy: circle.cy, r: divisionRadius[j]}).setStroke(spiderStroke);
 					}
 				}
 			}
 			//text
-			var textGroup = s.createGroup(), len = this._getObjectLength(this.datas), k = 0;
+			len = this._getObjectLength(this.datas);
+			var textGroup = s.createGroup(), k = 0;
 			for(var key in this.datas){
-				var data = this.datas[key], min = data.min, max = data.max, distance = max - min,
+				data = this.datas[key];
+				min = data.min;
+				max = data.max;
+				distance = max - min;
 					end = start + 2 * Math.PI * k / len;
-				for (var i = 0; i < dv; i++) {
-					var text = min + distance*i/(dv-1), point = this._getCoordinate(circle, r*(ro + (1-ro)*i/(dv-1)), end);
+				for (i = 0; i < dv; i++){
+					var text = min + distance*i/(dv-1);
+					point = this._getCoordinate(circle, r*(ro + (1-ro)*i/(dv-1)), end, dim);
 					text = this._getLabel(text);
-					var fontWidth = g._base._getTextBox(text, {font: axisTickFont}).w || 0,
+					fontWidth = g._base._getTextBox(text, {font: axisTickFont}).w || 0;
 						render = this.opt.htmlLabels && g.renderer != "vml" ? "html" : "gfx";
-					if (this.opt.htmlLabels) {
+					if(this.opt.htmlLabels){
 						this.htmlElements.push(da.createText[render]
 							(this.chart, textGroup, (!domGeom.isBodyLtr() && render == "html") ? (point.x + fontWidth - dim.width) : point.x, point.y,
 								"start", text, axisTickFont, axisTickFontColor));
@@ -329,16 +302,20 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 			
 			//draw series (animation)
 			this.chart.seriesShapes = {};
-			var animationConnections = [];
-			for (var i = this.series.length - 1; i >= 0; i--) {
-				var serieEntry = this.series[i], run = serieEntry.data;
-				if (run !== null) {
+			for (i = this.series.length - 1; i >= 0; i--){
+				serieEntry = this.series[i];
+				run = serieEntry.data;
+				if(run !== null){
 					//series polygon
-					var seriePoints = [], k = 0, tipData = [];
-					for(var key in run){
-						var data = this.datas[key], min = data.min, max = data.max, distance = max - min,
-							entry = run[key], end = start + 2 * Math.PI * k / len,
-							point = this._getCoordinate(circle, r*(ro + (1-ro)*(entry-min)/distance), end);
+					var seriePoints = [], tipData = [];
+					k = 0;
+					for(key in run){
+						data = this.datas[key];
+						min = data.min;
+						max = data.max;
+						distance = max - min;
+						var entry = run[key], end = start + 2 * Math.PI * k / len;
+							point = this._getCoordinate(circle, r*(ro + (1-ro)*(entry-min)/distance), end, dim);
 						seriePoints.push(point);
 						tipData.push({sname: serieEntry.name, key: key, data: entry});
 						k++;
@@ -384,8 +361,7 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 					this._connectEvents(so);
 					
 					arr.forEach(cs.circles, function(c, i){
-						var shape = c.getShape(),
-							co = {
+						var co = {
 								element: "spider_circle",
 								index:	 i,
 								id:		 "spider_circle_"+serieEntry.name+i,
@@ -403,12 +379,12 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 					}, this);
 				}
 			}
-			return this;	//	dojox.charting.plot2d.Spider
+			return this;	//	dojox/charting/plot2d/Spider
 		},
 		_createSeriesEntry: function(ts, osps, sps, f, sk, r, ro, ms, at){
 			//polygon
 			var spoly = ts.createPolyline(osps).setFill(f).setStroke(sk), scircle = [];
-			for (var j = 0; j < osps.length; j++) {
+			for (var j = 0; j < osps.length; j++){
 				var point = osps[j], cr = ms;
 				var circle = ts.createCircle({cx: point.x, cy: point.y, r: cr}).setFill(f).setStroke(sk);
 				scircle.push(circle);
@@ -462,89 +438,26 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 			return {group :ts, poly: spoly, circles: scircle};
 		},
 		plotEvent: function(o){
-			//	summary:
+			// summary:
 			//		Stub function for use by specific plots.
-			//	o: Object
+			// o: Object
 			//		An object intended to represent event parameters.
-			var runName = o.id ? o.id : "default", a;
-			if (runName in this.animations) {
-				a = this.animations[runName];
-				a.anim && a.anim.stop(true);
-			} else {
-				a = this.animations[runName] = {};
-			}
-			if(o.element == "spider_poly"){
-				if(!a.color){
-					var color = o.shape.getFill();
-					if(!color || !(color instanceof Color)){
-						return;
-					}
-					a.color = {
-						start: color,
-						end:   transColor(color)
-					};
-				}
-				var start = a.color.start, end = a.color.end;
-				if(o.type == "onmouseout"){
-					// swap colors
-					var t = start; start = end; end = t;
-				}
-				a.anim = gfxfx.animateFill({
-					shape:	  o.shape,
-					duration: 800,
-					easing:	  easing.backOut,
-					color:	  {start: start, end: end}
-				});
-				a.anim.play();
-			}else if(o.element == "spider_circle"){
-				var init, scale, defaultScale = 1.5;
-				if(o.type == "onmouseover"){
-					init  = m.identity;
-					scale = defaultScale;
-					//show tooltip
-					var aroundRect = {type: "rect"};
-					aroundRect.x = o.cx;
-					aroundRect.y = o.cy;
-					aroundRect.width = aroundRect.height = 1;
-					var lt = html.coords(this.chart.node, true);
-					aroundRect.x += lt.x;
-					aroundRect.y += lt.y;
-					aroundRect.x = Math.round(aroundRect.x);
-					aroundRect.y = Math.round(aroundRect.y);
-					aroundRect.width = Math.ceil(aroundRect.width);
-					aroundRect.height = Math.ceil(aroundRect.height);
-					this.aroundRect = aroundRect;
-					var position = ["after", "before"];
-					dc.doIfLoaded("dijit/Tooltip", dojo.hitch(this, function(Tooltip){
-						Tooltip.show(o.tdata.sname + "<br/>" + o.tdata.key + "<br/>" + o.tdata.data, this.aroundRect, position);
-					}));
-				}else{
-					init  = m.scaleAt(defaultScale, o.cx, o.cy);
-					scale = 1/defaultScale;
-					dc.doIfLoaded("dijit/Tooltip", dojo.hitch(this, function(Tooltip){
-						this.aroundRect && Tooltip.hide(this.aroundRect);
-					}));
-				}
-				var cs = o.shape.getShape(),
-					init = m.scaleAt(defaultScale, cs.cx, cs.cy),
-					kwArgs = {
-						shape: o.shape,
-						duration: 200,
-						easing:	  easing.backOut,
-						transform: [
-							{name: "scaleAt", start: [1, cs.cx, cs.cy], end: [scale, cs.cx, cs.cy]},
-							init
-						]
-					};
-				a.anim = gfxfx.animateTransform(kwArgs);
-				a.anim.play();
-			}else if(o.element == "spider_plot"){
+			if(o.element == "spider_plot"){
 				//dojo gfx function "moveToFront" not work in IE
-				if (o.type == "onmouseover" && !has("ie")) {
+				if(o.type == "onmouseover" && !has("ie")){
 					o.shape.moveToFront();
 				}
 			}
 		},
+
+		tooltipFunc: function(o){
+			if(o.element == "spider_circle"){
+				return o.tdata.sname + "<br/>" + o.tdata.key + "<br/>" + o.tdata.data;
+			}else{
+				return null;
+			}
+		},
+
 		_getBoundary: function(points){
 			var xmax = points[0].x,
 				xmin = points[0].x,
@@ -573,19 +486,23 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 			s.createPolyline([start, point2, point3]).setFill(stroke.color).setStroke(stroke);
 		},
 		
-		_buildPoints: function(points, count, circle, radius, angle, recursive){
-			for (var i = 0; i < count; i++) {
+		_buildPoints: function(points, count, circle, radius, angle, recursive, dim){
+			for(var i = 0; i < count; i++){
 				var end = angle + 2 * Math.PI * i / count;
-				points.push(this._getCoordinate(circle, radius, end));
+				points.push(this._getCoordinate(circle, radius, end, dim));
 			}
 			if(recursive){
-				points.push(this._getCoordinate(circle, radius, angle + 2 * Math.PI));
+				points.push(this._getCoordinate(circle, radius, angle + 2 * Math.PI, dim));
 			}
 		},
 		
-		_getCoordinate: function(circle, radius, angle){
+		_getCoordinate: function(circle, radius, angle, dim){
+			var x = circle.cx + radius * Math.cos(angle);
+			if(has("dojo-bidi") && this.chart.isRightToLeft() && dim){
+				x = dim.width - x;
+			}
 			return {
-				x: circle.cx + radius * Math.cos(angle),
+				x: x,
 				y: circle.cy + radius * Math.sin(angle)
 			}
 		},
@@ -605,27 +522,6 @@ var PlotEvents = dojox.charting.plot2d._PlotEvents;
 			return dc.getLabel(number, this.opt.fixed, this.opt.precision);
 		}
 	});
-	
-	function transColor(color){
-		var a = new dxcolor.Color(color),
-			x = a.toHsl();
-		if(x.s == 0){
-			x.l = x.l < 50 ? 100 : 0;
-		}else{
-			x.s = 100;
-			if(x.l < 50){
-				x.l = 75;
-			}else if(x.l > 75){
-				x.l = 50;
-			}else{
-				x.l = x.l - 50 > 75 - x.l ?
-					50 : 75;
-			}
-		}
-		var color = dxcolor.fromHsl(x);
-		color.a = 0.7;
-		return color;
-	}
-	
-	return Spider; // dojox.plot2d.Spider
+
+	return Spider; // dojox/plot2d/Spider
 });
diff --git a/dojox/charting/plot2d/Stacked.js b/dojox/charting/plot2d/Stacked.js
index 921792a..babb4a8 100644
--- a/dojox/charting/plot2d/Stacked.js
+++ b/dojox/charting/plot2d/Stacked.js
@@ -1,196 +1,44 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "./Default", "./common", 
-	"dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/functional/sequence"], 
-	function(lang, declare, arr, Default, dc, df, dfr, dfs){
-/*=====
-var Default = dojox.charting.plot2d.Default;
-=====*/
-	var purgeGroup = dfr.lambda("item.purgeGroup()");
+define(["dojo/_base/declare", "./Default", "./commonStacked"], 
+	function(declare, Default, commonStacked){
 
 	return declare("dojox.charting.plot2d.Stacked", Default, {
-		//	summary:
+		// summary:
 		//		Like the default plot, Stacked sets up lines, areas and markers
 		//		in a stacked fashion (values on the y axis added to each other)
 		//		as opposed to a direct one.
 		getSeriesStats: function(){
-			//	summary:
+			// summary:
 			//		Calculate the min/max on all attached series in both directions.
-			//	returns: Object
+			// returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
-			var stats = dc.collectStackedStats(this.series);
-			this._maxRunLength = stats.hmax;
-			return stats;
+			var stats = commonStacked.collectStats(this.series);
+			return stats; // Object
 		},
-		render: function(dim, offsets){
-			//	summary:
-			//		Run the calculations for any axes for this plot.
-			//	dim: Object
-			//		An object in the form of { width, height }
-			//	offsets: Object
-			//		An object of the form { l, r, t, b}.
-			//	returns: dojox.charting.plot2d.Stacked
-			//		A reference to this plot for functional chaining.
-			if(this._maxRunLength <= 0){
-				return this;
-			}
-
-			// stack all values
-			var acc = df.repeat(this._maxRunLength, "-> 0", 0);
-			for(var i = 0; i < this.series.length; ++i){
-				var run = this.series[i];
-				for(var j = 0; j < run.data.length; ++j){
-					var v = run.data[j];
-					if(v !== null){
-						if(isNaN(v)){ v = 0; }
-						acc[j] += v;
-					}
-				}
-			}
-			// draw runs in backwards
-			if(this.zoom && !this.isDataDirty()){
-				return this.performZoom(dim, offsets);
-			}
-			this.resetEvents();
-			this.dirty = this.isDirty();
-			if(this.dirty){
-				arr.forEach(this.series, purgeGroup);
-				this._eventSeries = {};
-				this.cleanGroup();
-				var s = this.group;
-				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
-			}
-
-			var t = this.chart.theme, events = this.events(),
-				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
-				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler);
-
-			for(var i = this.series.length - 1; i >= 0; --i){
-				var run = this.series[i];
-				if(!this.dirty && !run.dirty){
-					t.skip();
-					this._reconnectEvents(run.name);
-					continue;
-				}
-				run.cleanGroup();
-				var theme = t.next(this.opt.areas ? "area" : "line", [this.opt, run], true),
-					s = run.group, outline,
-					lpoly = arr.map(acc, function(v, i){
-						return {
-							x: ht(i + 1) + offsets.l,
-							y: dim.height - offsets.b - vt(v)
-						};
-					}, this);
-
-				var lpath = this.opt.tension ? dc.curve(lpoly, this.opt.tension) : "";
-
-				if(this.opt.areas){
-					var apoly = lang.clone(lpoly);
-					if(this.opt.tension){
-						var p=dc.curve(apoly, this.opt.tension);
-						p += " L" + lpoly[lpoly.length - 1].x + "," + (dim.height - offsets.b) +
-							" L" + lpoly[0].x + "," + (dim.height - offsets.b) +
-							" L" + lpoly[0].x + "," + lpoly[0].y;
-						run.dyn.fill = s.createPath(p).setFill(theme.series.fill).getFill();
-					} else {
-						apoly.push({x: lpoly[lpoly.length - 1].x, y: dim.height - offsets.b});
-						apoly.push({x: lpoly[0].x, y: dim.height - offsets.b});
-						apoly.push(lpoly[0]);
-						run.dyn.fill = s.createPolyline(apoly).setFill(theme.series.fill).getFill();
-					}
-				}
-				if(this.opt.lines || this.opt.markers){
-					if(theme.series.outline){
-						outline = dc.makeStroke(theme.series.outline);
-						outline.width = 2 * outline.width + theme.series.stroke.width;
-					}
-				}
-				if(this.opt.markers){
-					run.dyn.marker = theme.symbol;
-				}
-				var frontMarkers, outlineMarkers, shadowMarkers;
-				if(theme.series.shadow && theme.series.stroke){
-					var shadow = theme.series.shadow,
-						spoly = arr.map(lpoly, function(c){
-							return {x: c.x + shadow.dx, y: c.y + shadow.dy};
-						});
-					if(this.opt.lines){
-						if(this.opt.tension){
-							run.dyn.shadow = s.createPath(dc.curve(spoly, this.opt.tension)).setStroke(shadow).getStroke();
-						} else {
-							run.dyn.shadow = s.createPolyline(spoly).setStroke(shadow).getStroke();
-						}
-					}
-					if(this.opt.markers){
-						shadow = theme.marker.shadow;
-						shadowMarkers = arr.map(spoly, function(c){
-							return s.createPath("M" + c.x + " " + c.y + " " + theme.symbol).
-								setStroke(shadow).setFill(shadow.color);
-						}, this);
-					}
-				}
-				if(this.opt.lines){
-					if(outline){
-						if(this.opt.tension){
-							run.dyn.outline = s.createPath(lpath).setStroke(outline).getStroke();
-						} else {
-							run.dyn.outline = s.createPolyline(lpoly).setStroke(outline).getStroke();
-						}
-					}
-					if(this.opt.tension){
-						run.dyn.stroke = s.createPath(lpath).setStroke(theme.series.stroke).getStroke();
-					} else {
-						run.dyn.stroke = s.createPolyline(lpoly).setStroke(theme.series.stroke).getStroke();
-					}
-				}
-				if(this.opt.markers){
-					frontMarkers = new Array(lpoly.length);
-					outlineMarkers = new Array(lpoly.length);
-					outline = null;
-					if(theme.marker.outline){
-						outline = dc.makeStroke(theme.marker.outline);
-						outline.width = 2 * outline.width + (theme.marker.stroke ? theme.marker.stroke.width : 0);
-					}
-					arr.forEach(lpoly, function(c, i){
-						var path = "M" + c.x + " " + c.y + " " + theme.symbol;
-						if(outline){
-							outlineMarkers[i] = s.createPath(path).setStroke(outline);
-						}
-						frontMarkers[i] = s.createPath(path).setStroke(theme.marker.stroke).setFill(theme.marker.fill);
-					}, this);
-					if(events){
-						var eventSeries = new Array(frontMarkers.length);
-						arr.forEach(frontMarkers, function(s, i){
-							var o = {
-								element: "marker",
-								index:   i,
-								run:     run,
-								shape:   s,
-								outline: outlineMarkers[i] || null,
-								shadow:  shadowMarkers && shadowMarkers[i] || null,
-								cx:      lpoly[i].x,
-								cy:      lpoly[i].y,
-								x:       i + 1,
-								y:       run.data[i]
-							};
-							this._connectEvents(o);
-							eventSeries[i] = o;
-						}, this);
-						this._eventSeries[run.name] = eventSeries;
-					}else{
-						delete this._eventSeries[run.name];
-					}
-				}
-				run.dirty = false;
-				// update the accumulator
-				for(var j = 0; j < run.data.length; ++j){
-					var v = run.data[j];
-					if(v !== null){
-						if(isNaN(v)){ v = 0; }
-						acc[j] -= v;
+		
+		buildSegments: function(i, indexed){
+			var run = this.series[i],
+				min = indexed?Math.max(0, Math.floor(this._hScaler.bounds.from - 1)):0,
+				max = indexed?Math.min(run.data.length-1, Math.ceil(this._hScaler.bounds.to)):run.data.length-1,
+				rseg = null, segments = [];
+			// split the run data into dense segments (each containing no nulls)
+			// except if interpolates is false in which case ignore null between valid data
+			for(var j = min; j <= max; j++){
+				var value = indexed ? commonStacked.getIndexValue(this.series, i, j) : commonStacked.getValue(this.series, i, run.data[j] ?run.data[j].x: null);
+				if(value[0] != null && (indexed || value[0].y != null)){
+					if(!rseg){
+						rseg = [];
+						segments.push({index: j, rseg: rseg});
+					}
+					rseg.push(value[0]);
+				}else{
+					if(!this.opt.interpolate || indexed){
+						// we break the line only if not interpolating or if we have indexed data
+						rseg = null;
 					}
 				}
 			}
-			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.Stacked
+			return segments;
 		}
+		
 	});
 });
diff --git a/dojox/charting/plot2d/StackedAreas.js b/dojox/charting/plot2d/StackedAreas.js
index 637ae49..a022675 100644
--- a/dojox/charting/plot2d/StackedAreas.js
+++ b/dojox/charting/plot2d/StackedAreas.js
@@ -1,12 +1,10 @@
 define(["dojo/_base/declare", "./Stacked"], function(declare, Stacked){
-/*=====
-var Stacked = dojox.charting.plot2d.Stacked;
-=====*/
+
 	return declare("dojox.charting.plot2d.StackedAreas", Stacked, {
-		//	summary:
+		// summary:
 		//		A convenience object to set up a stacked area plot.
 		constructor: function(){
-			//	summary:
+			// summary:
 			//		Force our Stacked plotter to include both lines and areas.
 			this.opt.lines = true;
 			this.opt.areas = true;
diff --git a/dojox/charting/plot2d/StackedBars.js b/dojox/charting/plot2d/StackedBars.js
index 5d3923b..57ee4e1 100644
--- a/dojox/charting/plot2d/StackedBars.js
+++ b/dojox/charting/plot2d/StackedBars.js
@@ -1,134 +1,33 @@
-define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Bars", "./common", 
-	"dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/functional/sequence"], 
-	function(lang, arr, declare, Bars, dc, df, dfr, dfs){
+define(["dojo/_base/declare", "./Bars", "./commonStacked"], 
+	function(declare, Bars, commonStacked){
 
-	var	purgeGroup = dfr.lambda("item.purgeGroup()");
-/*=====
-var bars = dojox.charting.plot2d.Bars;
-=====*/
 	return declare("dojox.charting.plot2d.StackedBars", Bars, {
-		//	summary:
+		// summary:
 		//		The plot object representing a stacked bar chart (horizontal bars).
 		getSeriesStats: function(){
-			//	summary:
+			// summary:
 			//		Calculate the min/max on all attached series in both directions.
-			//	returns: Object
+			// returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
-			var stats = dc.collectStackedStats(this.series), t;
-			this._maxRunLength = stats.hmax;
+			var stats = commonStacked.collectStats(this.series), t;
 			stats.hmin -= 0.5;
 			stats.hmax += 0.5;
 			t = stats.hmin, stats.hmin = stats.vmin, stats.vmin = t;
 			t = stats.hmax, stats.hmax = stats.vmax, stats.vmax = t;
-			return stats;
+			return stats; // Object
 		},
-		render: function(dim, offsets){
-			//	summary:
-			//		Run the calculations for any axes for this plot.
-			//	dim: Object
-			//		An object in the form of { width, height }
-			//	offsets: Object
-			//		An object of the form { l, r, t, b}.
-			//	returns: dojox.charting.plot2d.StackedBars
-			//		A reference to this plot for functional chaining.
-			if(this._maxRunLength <= 0){
-				return this;
+		getValue: function(value, index, seriesIndex, indexed){
+			var y,x;
+			if(indexed){
+				x = index;
+				y = commonStacked.getIndexValue(this.series, seriesIndex, x);
+			}else{
+				x = value.x - 1;
+				y = commonStacked.getValue(this.series, seriesIndex, value.x);
+				y = [  y[0]?y[0].y:null, y[1]?y[1]:null ];
 			}
-
-			// stack all values
-			var acc = df.repeat(this._maxRunLength, "-> 0", 0);
-			for(var i = 0; i < this.series.length; ++i){
-				var run = this.series[i];
-				for(var j = 0; j < run.data.length; ++j){
-					var value = run.data[j];
-					if(value !== null){
-						var v = typeof value == "number" ? value : value.y;
-						if(isNaN(v)){ v = 0; }
-						acc[j] += v;
-					}
-				}
-			}
-			// draw runs in backwards
-			if(this.zoom && !this.isDataDirty()){
-				return this.performZoom(dim, offsets);
-			}
-			this.resetEvents();
-			this.dirty = this.isDirty();
-			if(this.dirty){
-				arr.forEach(this.series, purgeGroup);
-				this._eventSeries = {};
-				this.cleanGroup();
-				var s = this.group;
-				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
-			}
-			var t = this.chart.theme, f, gap, height,
-				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
-				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
-				events = this.events();
-			f = dc.calculateBarSize(this._vScaler.bounds.scale, this.opt);
-			gap = f.gap;
-			height = f.size;
-			for(var i = this.series.length - 1; i >= 0; --i){
-				var run = this.series[i];
-				if(!this.dirty && !run.dirty){
-					t.skip();
-					this._reconnectEvents(run.name);
-					continue;
-				}
-				run.cleanGroup();
-				var theme = t.next("bar", [this.opt, run]), s = run.group,
-					eventSeries = new Array(acc.length);
-				for(var j = 0; j < acc.length; ++j){
-					var value = run.data[j];
-					if(value !== null){
-						var v = acc[j],
-							width = ht(v),
-							finalTheme = typeof value != "number" ?
-								t.addMixin(theme, "bar", value, true) :
-								t.post(theme, "bar");
-						if(width >= 0 && height >= 1){
-							var rect = {
-								x: offsets.l,
-								y: dim.height - offsets.b - vt(j + 1.5) + gap,
-								width: width, height: height
-							};
-							var specialFill = this._plotFill(finalTheme.series.fill, dim, offsets);
-							specialFill = this._shapeFill(specialFill, rect);
-							var shape = s.createRect(rect).setFill(specialFill).setStroke(finalTheme.series.stroke);
-							run.dyn.fill   = shape.getFill();
-							run.dyn.stroke = shape.getStroke();
-							if(events){
-								var o = {
-									element: "bar",
-									index:   j,
-									run:     run,
-									shape:   shape,
-									x:       v,
-									y:       j + 1.5
-								};
-								this._connectEvents(o);
-								eventSeries[j] = o;
-							}
-							if(this.animate){
-								this._animateBar(shape, offsets.l, -width);
-							}
-						}
-					}
-				}
-				this._eventSeries[run.name] = eventSeries;
-				run.dirty = false;
-				// update the accumulator
-				for(var j = 0; j < run.data.length; ++j){
-					var value = run.data[j];
-					if(value !== null){
-						var v = typeof value == "number" ? value : value.y;
-						if(isNaN(v)){ v = 0; }
-						acc[j] -= v;
-					}
-				}
-			}
-			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.StackedBars
+			// in py we return the previous stack value as we need it to position labels on columns
+			return { x: x, y: y[0], py: y[1] };
 		}
 	});
 });
diff --git a/dojox/charting/plot2d/StackedColumns.js b/dojox/charting/plot2d/StackedColumns.js
index 551e99e..f4d5e0b 100644
--- a/dojox/charting/plot2d/StackedColumns.js
+++ b/dojox/charting/plot2d/StackedColumns.js
@@ -1,132 +1,31 @@
-define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "./Columns", "./common", 
-	"dojox/lang/functional", "dojox/lang/functional/reversed", "dojox/lang/functional/sequence"], 
-	function(lang, arr, declare, Columns, dc, df, dfr, dfs){
+define(["dojo/_base/declare", "./Columns", "./commonStacked"], 
+	function( declare, Columns, commonStacked){
 
-	var	purgeGroup = dfr.lambda("item.purgeGroup()");
-/*=====
-var Columns = dojox.charting.plot2d.Columns;
-=====*/
 	return declare("dojox.charting.plot2d.StackedColumns", Columns, {
-		//	summary:
+		// summary:
 		//		The plot object representing a stacked column chart (vertical bars).
 		getSeriesStats: function(){
-			//	summary:
+			// summary:
 			//		Calculate the min/max on all attached series in both directions.
-			//	returns: Object
+			// returns: Object
 			//		{hmin, hmax, vmin, vmax} min/max in both directions.
-			var stats = dc.collectStackedStats(this.series);
-			this._maxRunLength = stats.hmax;
+			var stats = commonStacked.collectStats(this.series);
 			stats.hmin -= 0.5;
 			stats.hmax += 0.5;
-			return stats;
+			return stats; // Object
 		},
-		render: function(dim, offsets){
-			//	summary:
-			//		Run the calculations for any axes for this plot.
-			//	dim: Object
-			//		An object in the form of { width, height }
-			//	offsets: Object
-			//		An object of the form { l, r, t, b}.
-			//	returns: dojox.charting.plot2d.StackedColumns
-			//		A reference to this plot for functional chaining.
-			if(this._maxRunLength <= 0){
-				return this;
+		getValue: function(value, index, seriesIndex, indexed){
+			var x, y;
+			if(indexed){
+				x = index;
+				y = commonStacked.getIndexValue(this.series, seriesIndex, x);
+			}else{
+				x = value.x - 1;
+				y = commonStacked.getValue(this.series, seriesIndex, value.x);
+				y = [  y[0]?y[0].y:null, y[1]?y[1]:null ];
 			}
-
-			// stack all values
-			var acc = df.repeat(this._maxRunLength, "-> 0", 0);
-			for(var i = 0; i < this.series.length; ++i){
-				var run = this.series[i];
-				for(var j = 0; j < run.data.length; ++j){
-					var value = run.data[j];
-					if(value !== null){
-						var v = typeof value == "number" ? value : value.y;
-						if(isNaN(v)){ v = 0; }
-						acc[j] += v;
-					}
-				}
-			}
-			// draw runs in backwards
-			if(this.zoom && !this.isDataDirty()){
-				return this.performZoom(dim, offsets);
-			}
-			this.resetEvents();
-			this.dirty = this.isDirty();
-			if(this.dirty){
-				arr.forEach(this.series, purgeGroup);
-				this._eventSeries = {};
-				this.cleanGroup();
-				var s = this.group;
-				df.forEachRev(this.series, function(item){ item.cleanGroup(s); });
-			}
-			var t = this.chart.theme, f, gap, width,
-				ht = this._hScaler.scaler.getTransformerFromModel(this._hScaler),
-				vt = this._vScaler.scaler.getTransformerFromModel(this._vScaler),
-				events = this.events();
-			f = dc.calculateBarSize(this._hScaler.bounds.scale, this.opt);
-			gap = f.gap;
-			width = f.size;
-			for(var i = this.series.length - 1; i >= 0; --i){
-				var run = this.series[i];
-				if(!this.dirty && !run.dirty){
-					t.skip();
-					this._reconnectEvents(run.name);
-					continue;
-				}
-				run.cleanGroup();
-				var theme = t.next("column", [this.opt, run]), s = run.group,
-					eventSeries = new Array(acc.length);
-				for(var j = 0; j < acc.length; ++j){
-					var value = run.data[j];
-					if(value !== null){
-						var v = acc[j],
-							height = vt(v),
-							finalTheme = typeof value != "number" ?
-								t.addMixin(theme, "column", value, true) :
-								t.post(theme, "column");
-						if(width >= 1 && height >= 0){
-							var rect = {
-								x: offsets.l + ht(j + 0.5) + gap,
-								y: dim.height - offsets.b - vt(v),
-								width: width, height: height
-							};
-							var specialFill = this._plotFill(finalTheme.series.fill, dim, offsets);
-							specialFill = this._shapeFill(specialFill, rect);
-							var shape = s.createRect(rect).setFill(specialFill).setStroke(finalTheme.series.stroke);
-							run.dyn.fill   = shape.getFill();
-							run.dyn.stroke = shape.getStroke();
-							if(events){
-								var o = {
-									element: "column",
-									index:   j,
-									run:     run,
-									shape:   shape,
-									x:       j + 0.5,
-									y:       v
-								};
-								this._connectEvents(o);
-								eventSeries[j] = o;
-							}
-							if(this.animate){
-								this._animateColumn(shape, dim.height - offsets.b, height);
-							}
-						}
-					}
-				}
-				this._eventSeries[run.name] = eventSeries;
-				run.dirty = false;
-				// update the accumulator
-				for(var j = 0; j < run.data.length; ++j){
-					var value = run.data[j];
-					if(value !== null){
-						var v = typeof value == "number" ? value : value.y;
-						if(isNaN(v)){ v = 0; }
-						acc[j] -= v;
-					}
-				}
-			}
-			this.dirty = false;
-			return this;	//	dojox.charting.plot2d.StackedColumns
+			// in py we return the previous stack value as we need it to position labels on columns
+			return { x: x, y: y[0], py: y[1] };
 		}
 	});
 });
diff --git a/dojox/charting/plot2d/StackedLines.js b/dojox/charting/plot2d/StackedLines.js
index 03f0b4d..0d84385 100644
--- a/dojox/charting/plot2d/StackedLines.js
+++ b/dojox/charting/plot2d/StackedLines.js
@@ -1,12 +1,10 @@
 define(["dojo/_base/declare", "./Stacked"], function(declare, Stacked){
-/*=====
-var Stacked = dojox.charting.plot2d.Stacked;
-=====*/
+
 	return declare("dojox.charting.plot2d.StackedLines", Stacked, {
-		//	summary:
+		// summary:
 		//		A convenience object to create a stacked line chart.
 		constructor: function(){
-			//	summary:
+			// summary:
 			//		Force our Stacked base to be lines only.
 			this.opt.lines = true;
 		}
diff --git a/dojox/charting/plot2d/_PlotEvents.js b/dojox/charting/plot2d/_PlotEvents.js
index 76c7ef0..92a11fe 100644
--- a/dojox/charting/plot2d/_PlotEvents.js
+++ b/dojox/charting/plot2d/_PlotEvents.js
@@ -7,21 +7,21 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/_base
 			this._eventSeries = {};
 		},
 		destroy: function(){
-			//	summary:
+			// summary:
 			//		Destroy any internal elements and event handlers.
 			this.resetEvents();
 			this.inherited(arguments);
 		},
 		plotEvent: function(o){
-			//	summary:
+			// summary:
 			//		Stub function for use by specific plots.
-			//	o: Object
+			// o: Object
 			//		An object intended to represent event parameters.
 		},
 		raiseEvent: function(o){
-			//	summary:
+			// summary:
 			//		Raises events in predefined order
-			//	o: Object
+			// o: Object
 			//		An object intended to represent event parameters.
 			this.plotEvent(o);
 			var t = lang.delegate(o);
@@ -36,26 +36,26 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/_base
 			}, this);
 		},
 		connect: function(object, method){
-			//	summary:
+			// summary:
 			//		Helper function to connect any object's method to our plotEvent.
-			//	object: Object
+			// object: Object
 			//		The object to connect to.
-			//	method: String|Function
+			// method: String|Function
 			//		The method to fire when our plotEvent is fired.
-			//	returns: Array
+			// returns: Array
 			//		The handle as returned from dojo.connect (see dojo.connect).
 			this.dirty = true;
 			return hub.connect(this, "plotEvent", object, method);	//	Array
 		},
 		events: function(){
-			//	summary:
+			// summary:
 			//		Find out if any event handlers have been connected to our plotEvent.
-			//	returns: Boolean
+			// returns: Boolean
 			//		A flag indicating that there are handlers attached.
 			return !!this.plotEvent.after;
 		},
 		resetEvents: function(){
-			//	summary:
+			// summary:
 			//		Reset all events attached to our plotEvent (i.e. disconnect).
 			if(this._shapeEvents.length){
 				arr.forEach(this._shapeEvents, function(item){
@@ -95,16 +95,16 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/_base
 			}
 		},
 		fireEvent: function(seriesName, eventName, index, eventObject){
-			//	summary:
+			// summary:
 			//		Emulates firing an event for a given data value (specified by
 			//		an index) of a given series.
-			//	seriesName: String:
+			// seriesName: String
 			//		Series name.
-			//	eventName: String:
+			// eventName: String
 			//		Event name to emulate.
-			//	index:	Number:
+			// index: Number
 			//		Valid data value index used to raise an event.
-			//	eventObject: Object?:
+			// eventObject: Object?
 			//		Optional event object. Especially useful for synthetic events.
 			//		Default: null.
 			var s = this._eventSeries[seriesName];
diff --git a/dojox/charting/plot2d/common.js b/dojox/charting/plot2d/common.js
index 858138f..8e38a9f 100644
--- a/dojox/charting/plot2d/common.js
+++ b/dojox/charting/plot2d/common.js
@@ -118,12 +118,12 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color",
 				// 2nd pass: stack values
 				for(var i = 0; i < stats.hmax; ++i){
 					var v = series[0].data[i];
-                    v = v && (typeof v == "number" ? v : v.y);
+					v = v && (typeof v == "number" ? v : v.y);
 					if(isNaN(v)){ v = 0; }
 					stats.vmin = Math.min(stats.vmin, v);
 					for(var j = 1; j < series.length; ++j){
 						var t = series[j].data[i];
-                        t = t && (typeof t == "number" ? t : t.y);
+						t = t && (typeof t == "number" ? t : t.y);
 						if(isNaN(t)){ t = 0; }
 						v += t;
 					}
@@ -139,7 +139,7 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color",
 			//		program ;)
 			var array = a.slice(0);
 			if(tension == "x") {
-				array[array.length] = arr[0];   // add a last element equal to the first, closing the loop
+				array[array.length] = array[0];   // add a last element equal to the first, closing the loop
 			}
 			var p=arr.map(array, function(item, i){
 				if(i==0){ return "M" + item.x + "," + item.y; }
diff --git a/dojox/charting/plot2d/commonStacked.js b/dojox/charting/plot2d/commonStacked.js
new file mode 100644
index 0000000..a28cdc5
--- /dev/null
+++ b/dojox/charting/plot2d/commonStacked.js
@@ -0,0 +1,71 @@
+define([
+	"dojo/_base/lang",
+	"./common"
+], function(lang, common){
+	
+	var commonStacked = lang.getObject("dojox.charting.plot2d.commonStacked", true);
+	return lang.mixin(commonStacked, {
+		collectStats: function(series){
+			var stats = lang.delegate(common.defaultStats);
+			for(var i = 0; i < series.length; ++i){
+				var run = series[i];
+				for(var j = 0; j < run.data.length; j++){
+					var x, y;
+					if(run.data[j] !== null){
+						if(typeof run.data[j] == "number" || !run.data[j].hasOwnProperty("x")){
+							y = commonStacked.getIndexValue(series, i, j)[0];
+							x = j+1;
+						}else{
+							x = run.data[j].x;
+							if(x !== null){
+								y = commonStacked.getValue(series, i, x)[0];
+								y = y != null && y.y ? y.y:null; 
+							}
+						}
+						stats.hmin = Math.min(stats.hmin, x);
+						stats.hmax = Math.max(stats.hmax, x);
+						stats.vmin = Math.min(stats.vmin, y);
+						stats.vmax = Math.max(stats.vmax, y);
+					}
+				}
+			}
+			return stats;
+		},
+		getIndexValue: function(series, i, index){
+			var value = 0, v, j, pvalue;
+			for(j = 0; j <= i; ++j){
+				pvalue = value;
+				v = series[j].data[index];
+				if(v != null){
+					if(isNaN(v)){ v = v.y || 0; }
+					value += v;
+				}
+			}
+			return [value , pvalue];
+		},
+		getValue: function(series, i, x){
+			var value = null, j, z, v, pvalue;
+			for(j = 0; j <= i; ++j){
+				for(z = 0; z < series[j].data.length; z++){
+					pvalue = value;
+					v = series[j].data[z];
+					if(v !== null){
+						if(v.x == x){
+							if(!value){
+								value = {x: x};
+							}
+							if(v.y != null){
+								if(value.y == null){
+									value.y = 0;
+								}
+								value.y += v.y;
+							}
+							break;
+						}else if(v.x > x){break;}
+					}
+				}
+			}
+			return [value, pvalue];
+		}
+	});
+});
diff --git a/dojox/charting/plot3d/Bars.js b/dojox/charting/plot3d/Bars.js
index 7cceece..cc8fe70 100644
--- a/dojox/charting/plot3d/Bars.js
+++ b/dojox/charting/plot3d/Bars.js
@@ -1,18 +1,17 @@
-define(["dojox/gfx3d", "dojo/_base/window", "dojo/_base/declare", "dojo/_base/Color", "./Base"], 
-	function(gfx3d, win, declare, Color, Base) {
+define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/_base/Color", "dojo/has", "./Base"],
+	function(kernel, declare, Color, has, Base) {
 
 	// reduce function borrowed from dojox.fun
 	var reduce = function(/*Array*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-		// summary: repeatedly applies a binary function to an array from left
-		//	to right; returns the final value.
-		a = typeof a == "string" ? a.split("") : a; o = o || win.global;
+		// summary:
+		//		repeatedly applies a binary function to an array from left
+		//		to right; returns the final value.
+		a = typeof a == "string" ? a.split("") : a; o = o || kernel.global;
 		var z = a[0];
 		for(var i = 1; i < a.length; z = f.call(o, z, a[i++]));
 		return z;	// Object
 	};
-	/*=====
-	var Base = dojox.charting.plot3d.Base;
-	=====*/
+
 	return declare("dojox.charting.plot3d.Bars", Base, {
 		constructor: function(width, height, kwArgs){
 			this.depth = "auto";
@@ -56,6 +55,9 @@ define(["dojox/gfx3d", "dojo/_base/window", "dojo/_base/declare", "dojo/_base/Co
 					})
 					.setFill(this.material);
 			}
+			if(has("dojo-bidi")){
+				this._checkOrientation(chart);
+			}
 		}
 	});
 });
diff --git a/dojox/charting/plot3d/Base.js b/dojox/charting/plot3d/Base.js
index ab1b536..f9309a7 100644
--- a/dojox/charting/plot3d/Base.js
+++ b/dojox/charting/plot3d/Base.js
@@ -1,6 +1,6 @@
-define(["dojo/_base/declare"], 
-  function(declare) {
-	return declare("dojox.charting.plot3d.Base", null, {
+define(["dojo/_base/declare", "dojo/has"], 
+  function(declare, has) {
+	var Base = declare("dojox.charting.plot3d.Base", null, {
 		constructor: function(width, height, kwArgs){
 			this.width  = width;
 			this.height = height;
@@ -15,5 +15,15 @@ define(["dojo/_base/declare"],
 		generate: function(chart, creator){
 		}
 	});
+	if(has("dojo-bidi")){
+		Base.extend({
+			_checkOrientation: function(chart){
+				if(chart.isMirrored){
+					chart.applyMirroring(chart.view, {width: this.width, height: this.height}, {l: 0, r: 0, t: 0, b: 0});
+				}			
+			}			
+		});
+	}
+	return Base;
 });
 
diff --git a/dojox/charting/plot3d/Cylinders.js b/dojox/charting/plot3d/Cylinders.js
index 8b63668..741f219 100644
--- a/dojox/charting/plot3d/Cylinders.js
+++ b/dojox/charting/plot3d/Cylinders.js
@@ -1,18 +1,17 @@
-define(["dojox/gfx3d", "dojox/gfx3d/matrix", "dojo/_base/declare", "dojo/_base/Color", "dojo/_base/window", "./Base"], 
-	function(gfx3d, matrix3d, declare, Color, win, Base) {
+define(["dojox/gfx3d/matrix", "dojo/_base/declare", "dojo/_base/Color", "dojo/_base/kernel", "dojo/has", "./Base"],
+	function(matrix3d, declare, Color, kernel, has, Base) {
 
 	// reduce function borrowed from dojox.fun
 	var reduce = function(/*Array*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-		// summary: repeatedly applies a binary function to an array from left
-		//	to right; returns the final value.
-		a = typeof a == "string" ? a.split("") : a; o = o || win.global;
+		// summary:
+		//		repeatedly applies a binary function to an array from left
+		//		to right; returns the final value.
+		a = typeof a == "string" ? a.split("") : a; o = o || kernel.global;
 		var z = a[0];
 		for(var i = 1; i < a.length; z = f.call(o, z, a[i++]));
 		return z;	// Object
 	};
-	/*=====
-	var Base = dojox.charting.plot3d.Base;
-	=====*/
+
 	return declare("dojox.charting.plot3d.Cylinders", Base, {
 		constructor: function(width, height, kwArgs){
 			this.depth = "auto";
@@ -59,6 +58,9 @@ define(["dojox/gfx3d", "dojox/gfx3d/matrix", "dojo/_base/declare", "dojo/_base/C
 					.setTransform(matrix3d.rotateXg(-90))
 					.setFill(this.material).setStroke(this.outline);
 			}
+			if(has("dojo-bidi")){
+				this._checkOrientation(chart);
+			}
 		}
 	});
 });
diff --git a/dojox/charting/scaler/common.js b/dojox/charting/scaler/common.js
index af353cb..f7285d9 100644
--- a/dojox/charting/scaler/common.js
+++ b/dojox/charting/scaler/common.js
@@ -1,7 +1,8 @@
 define(["dojo/_base/lang"], function(lang){
 
 	var eq = function(/*Number*/ a, /*Number*/ b){
-		// summary: compare two FP numbers for equality
+		// summary:
+		//		compare two FP numbers for equality
 		return Math.abs(a - b) <= 1e-6 * (Math.abs(a) + Math.abs(b));	// Boolean
 	};
 	
@@ -24,13 +25,6 @@ define(["dojo/_base/lang"], function(lang){
 				return ifnotloaded();
 			}
 		},
-		findString: function(/*String*/ val, /*Array*/ text){
-			val = val.toLowerCase();
-			for(var i = 0; i < text.length; ++i){
-				if(val == text[i]){ return true; }
-			}
-			return false;
-		},
 		getNumericLabel: function(/*Number*/ number, /*Number*/ precision, /*Object*/ kwArgs){
 			var def = "";
 			common.doIfLoaded("dojo/number", function(numberLib){
@@ -46,6 +40,7 @@ define(["dojo/_base/lang"], function(lang){
 			}
 			if(kwArgs.labels){
 				// classic binary search
+				// TODO: working only if the array is sorted per value should be better documented or sorted automatically
 				var l = kwArgs.labels, lo = 0, hi = l.length;
 				while(lo < hi){
 					var mid = Math.floor((lo + hi) / 2), val = l[mid].value;
diff --git a/dojox/charting/scaler/linear.js b/dojox/charting/scaler/linear.js
index cb22f62..4d0ad23 100644
--- a/dojox/charting/scaler/linear.js
+++ b/dojox/charting/scaler/linear.js
@@ -3,8 +3,17 @@ define(["dojo/_base/lang", "./common"],
 	var linear = lang.getObject("dojox.charting.scaler.linear", true);
 	
 	var deltaLimit = 3,	// pixels
-		findString = common.findString,
 		getLabel = common.getNumericLabel;
+
+		function findString(/*String*/ val, /*Array*/ text){
+			val = val.toLowerCase();
+			for(var i = text.length - 1; i >= 0; --i){
+				if(val === text[i]){
+					return true;
+				}
+			}
+			return false;
+		}
 	
 	var calcTicks = function(min, max, kwArgs, majorTick, minorTick, microTick, span){
 		kwArgs = lang.delegate(kwArgs);
@@ -92,13 +101,14 @@ define(["dojo/_base/lang", "./common"],
 	};
 	
 	return lang.mixin(linear, {
-		buildScaler: function(/*Number*/ min, /*Number*/ max, /*Number*/ span, /*Object*/ kwArgs){
+		buildScaler: function(/*Number*/ min, /*Number*/ max, /*Number*/ span, /*Object*/ kwArgs, /*Number?*/ delta, /*Number?*/ minorDelta){
 			var h = {fixUpper: "none", fixLower: "none", natural: false};
 			if(kwArgs){
 				if("fixUpper" in kwArgs){ h.fixUpper = String(kwArgs.fixUpper); }
 				if("fixLower" in kwArgs){ h.fixLower = String(kwArgs.fixLower); }
 				if("natural"  in kwArgs){ h.natural  = Boolean(kwArgs.natural); }
 			}
+			minorDelta = !minorDelta || minorDelta < deltaLimit ? deltaLimit : minorDelta;
 			
 			// update bounds
 			if("min" in kwArgs){ min = kwArgs.min; }
@@ -125,8 +135,10 @@ define(["dojo/_base/lang", "./common"],
 			if(max <= min){
 				return calcTicks(min, max, h, 0, 0, 0, span);	// Object
 			}
-			
-			var mag = Math.floor(Math.log(max - min) / Math.LN10),
+			if(!delta){
+				delta = max - min;
+			}
+			var mag = Math.floor(Math.log(delta) / Math.LN10),
 				major = kwArgs && ("majorTickStep" in kwArgs) ? kwArgs.majorTickStep : Math.pow(10, mag),
 				minor = 0, micro = 0, ticks;
 				
@@ -138,17 +150,17 @@ define(["dojo/_base/lang", "./common"],
 					minor = major / 10;
 					if(!h.natural || minor > 0.9){
 						ticks = calcTicks(min, max, h, major, minor, 0, span);
-						if(ticks.bounds.scale * ticks.minor.tick > deltaLimit){ break; }
+						if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }
 					}
 					minor = major / 5;
 					if(!h.natural || minor > 0.9){
 						ticks = calcTicks(min, max, h, major, minor, 0, span);
-						if(ticks.bounds.scale * ticks.minor.tick > deltaLimit){ break; }
+						if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }
 					}
 					minor = major / 2;
 					if(!h.natural || minor > 0.9){
 						ticks = calcTicks(min, max, h, major, minor, 0, span);
-						if(ticks.bounds.scale * ticks.minor.tick > deltaLimit){ break; }
+						if(ticks.bounds.scale * ticks.minor.tick > minorDelta){ break; }
 					}
 					return calcTicks(min, max, h, major, 0, 0, span);	// Object
 				}while(false);
diff --git a/dojox/charting/tests/BidiSupport/bidi_ChartAxisTitle.html b/dojox/charting/tests/BidiSupport/bidi_ChartAxisTitle.html
index 9f2a968..946c1d3 100644
--- a/dojox/charting/tests/BidiSupport/bidi_ChartAxisTitle.html
+++ b/dojox/charting/tests/BidiSupport/bidi_ChartAxisTitle.html
@@ -40,7 +40,7 @@
 				-moz-transform: rotate(-90deg);
 			}
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
 			<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("doh.runner");
@@ -59,8 +59,6 @@
 			dojo.require("dijit.form.Button");
 			dojo.require("dijit.form.NumberSpinner");
 
-			dojo.require("dojox.charting.BidiSupport");
-
 			var chart1;
 
 			var updateAxis = function(){
diff --git a/dojox/charting/tests/BidiSupport/bidi_DataSeries.html b/dojox/charting/tests/BidiSupport/bidi_DataSeries.html
index afe6ff3..e2ec8a7 100644
--- a/dojox/charting/tests/BidiSupport/bidi_DataSeries.html
+++ b/dojox/charting/tests/BidiSupport/bidi_DataSeries.html
@@ -74,7 +74,7 @@
 			}
 		</style>
 
-		<script src="../../../../dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true"></script>
+		<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug: false, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
 
 		<script>
 			dojo.require("dojo.parser");
@@ -98,9 +98,6 @@
 
 			dojo.require("dijit.form.NumberSpinner");
 			
-			dojo.require("dojox.charting.BidiSupport");	
-			dojo.require("dojox.charting.widget.BidiSupport");
-		
 			var store = new dojo.data.ItemFileWriteStore({url: "stockHebrew.json"});
 			
 			function addLegend(chart, node){
diff --git a/dojox/charting/tests/BidiSupport/bidi_DeclerativeChart.html b/dojox/charting/tests/BidiSupport/bidi_DeclerativeChart.html
index 4029daa..5bc2b5e 100644
--- a/dojox/charting/tests/BidiSupport/bidi_DeclerativeChart.html
+++ b/dojox/charting/tests/BidiSupport/bidi_DeclerativeChart.html
@@ -26,7 +26,7 @@
 			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
 			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi':true}"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
@@ -40,8 +40,6 @@
             dojo.require("dojox.charting.action2d.Tooltip");
 			dojo.require("dojox.charting.widget.Legend");
 			dojo.require("dojox.data.HtmlStore");
-			dojo.require("dojox.charting.BidiSupport");
-			dojo.require("dojox.charting.widget.BidiSupport");
 			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 			
 			seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
@@ -70,7 +68,7 @@
 	<body class="tundra">
 		<h1>Chart 2D</h1>
 		<p>Examples of charts using widgets.</p>
-		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" jsId="tableStore"></div>
+		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" data-dojo-id="tableStore"></div>
 		<table id="tableExample" style="display: none;">
 			<thead>
 				<tr><th>value</th></tr>
diff --git a/dojox/charting/tests/BidiSupport/bidi_Event2d.html b/dojox/charting/tests/BidiSupport/bidi_Event2d.html
index fcd321d..6cd4b15 100644
--- a/dojox/charting/tests/BidiSupport/bidi_Event2d.html
+++ b/dojox/charting/tests/BidiSupport/bidi_Event2d.html
@@ -26,7 +26,7 @@
 			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
 			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
 			<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("doh.runner");
@@ -54,9 +54,6 @@
 			dojo.require("dojo.colors");
 			dojo.require("dojo.fx.easing");
 
-			dojo.require("dojox.charting.BidiSupport");
-			dojo.require("dojox.charting.widget.BidiSupport");
-			
 			var dc = dojox.charting;
 
 			var dur = 450;
diff --git a/dojox/charting/tests/BidiSupport/bidi_Label_shortening.html b/dojox/charting/tests/BidiSupport/bidi_Label_shortening.html
index 5630cfa..369b750 100644
--- a/dojox/charting/tests/BidiSupport/bidi_Label_shortening.html
+++ b/dojox/charting/tests/BidiSupport/bidi_Label_shortening.html
@@ -21,7 +21,7 @@
 			@import "../../../../dijit/tests/css/dijitTests.css";
 			@import "../../../../dijit/themes/claro/claro.css";
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("doh.runner");
@@ -40,9 +40,6 @@
 			dojo.require("dojox.charting.widget.Legend");
 			dojo.require("dojox.data.HtmlStore");
 
-			dojo.require("dojox.charting.BidiSupport");
-			dojo.require("dojox.charting.widget.BidiSupport");
-
 			var seriesB = [260, 180, 200, 100, 140, 70, 200]
 				, chart1, chart2, chart3, chart4;
 			
@@ -195,7 +192,7 @@ textDir = rtl.</h2>
 		<div id="test4" style="width: 300px; height: 200px;"></div>
 		<h2>5: Label shortening for HTML declared chart
 textDir = auto.</h2>
-		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" jsId="tableStore"></div>
+		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" data-dojo-id="tableStore"></div>
 		<table id="tableExample" style="display: none;">
 			<thead>
 				<tr><th>value</th></tr>
diff --git a/dojox/charting/tests/BidiSupport/bidi_Pie_smart_label.html b/dojox/charting/tests/BidiSupport/bidi_Pie_smart_label.html
index 9e70b2b..819cfc4 100644
--- a/dojox/charting/tests/BidiSupport/bidi_Pie_smart_label.html
+++ b/dojox/charting/tests/BidiSupport/bidi_Pie_smart_label.html
@@ -22,7 +22,7 @@
 			@import "../../../../dijit/themes/claro/claro.css";
 			@import "../../resources/Legend.css";
         </style>
-        <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad:true">
+        <script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, has:{'dojo-bidi': true}">
         </script>
         <script type="text/javascript">
  			dojo.require("dojo.parser");
@@ -36,9 +36,6 @@
 			dojo.require("dojox.charting.themes.Tom");
             dojo.require("dojox.charting.widget.Legend");
 			
-			dojo.require("dojox.charting.BidiSupport");
-			dojo.require("dojox.charting.widget.BidiSupport");
-
             var pieChart = null;
 			var legend = null;
             dojo.addOnLoad(function(){
diff --git a/dojox/charting/tests/BidiSupport/bidi_Pies.html b/dojox/charting/tests/BidiSupport/bidi_Pies.html
index 9eedbc5..00bd362 100644
--- a/dojox/charting/tests/BidiSupport/bidi_Pies.html
+++ b/dojox/charting/tests/BidiSupport/bidi_Pies.html
@@ -20,7 +20,7 @@
 			@import "../../../../dojo/resources/dojo.css";
 			@import "../../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad:true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad:true, has:{'dojo-bidi': true}"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("doh.runner");
@@ -34,8 +34,6 @@
 			dojo.require("dojox.charting.themes.Algae");
 			dojo.require("dojox.charting.action2d.Tooltip");
 
-			dojo.require("dojox.charting.BidiSupport");
-
 			var chart1, chart2, chart8;
 			makeObjects = function(){
 				chart1 = new dojox.charting.Chart("test1", {textDir:"rtl"});
@@ -49,7 +47,6 @@
 				});
 				chart1.addSeries("Series A", [{y: 4, text: "\u05e9\u05dc\u05d5\u05dd big world!"}, {y: 2, text: "Hello \u05e2\u05d5\u05dc\u05dd\u0020\u05d2\u05d3\u05d5\u05dc!"}, {y: 1, text: "Blue."}, {y: 1, text: "Other..."}]);
 				   new dojox.charting.action2d.Tooltip(chart1);
-			 
 				chart1.render();
 
 				chart2 = new dojox.charting.Chart("test2", {textDir:"auto"});
diff --git a/dojox/charting/tests/BidiSupport/bidi_RotatedLabels.html b/dojox/charting/tests/BidiSupport/bidi_RotatedLabels.html
index 3840717..b1c3723 100644
--- a/dojox/charting/tests/BidiSupport/bidi_RotatedLabels.html
+++ b/dojox/charting/tests/BidiSupport/bidi_RotatedLabels.html
@@ -21,7 +21,7 @@
 			@import "../../../../dijit/tests/css/dijitTests.css";
 			@import "../../../../dijit/themes/tundra/tundra.css";
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 			dojo.require("doh.runner");
@@ -34,8 +34,6 @@
 			dojo.require("dojox.charting.plot2d.Default");
 			dojo.require("dojox.charting.themes.PrimaryColors");
 
-			dojo.require("dojox.charting.BidiSupport");	
-
 			var chart;
 
 			makeObjects = function(){
diff --git a/dojox/charting/tests/BidiSupport/bidi_SelectableLegend.html b/dojox/charting/tests/BidiSupport/bidi_SelectableLegend.html
index 25a6a91..6f80baf 100644
--- a/dojox/charting/tests/BidiSupport/bidi_SelectableLegend.html
+++ b/dojox/charting/tests/BidiSupport/bidi_SelectableLegend.html
@@ -41,7 +41,7 @@
 			}
         </style>
 
-        <script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+        <script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
         <script type="text/javascript">
  			dojo.require("dojo.parser");
 			dojo.require("doh.runner");
@@ -63,9 +63,6 @@
 			dojo.require("dojox.charting.widget.SelectableLegend");
 			dojo.require("dojox.charting.action2d.Highlight");
 			
-			dojo.require("dojox.charting.BidiSupport");
-			dojo.require("dojox.charting.widget.BidiSupport");
-			
 			var bars;
         	dojo.addOnLoad(function(){
 				 bars = new dojox.charting.Chart("bars").
diff --git a/dojox/charting/tests/BidiSupport/bidi_SetTextDir.html b/dojox/charting/tests/BidiSupport/bidi_SetTextDir.html
index 27159fc..9a71f63 100644
--- a/dojox/charting/tests/BidiSupport/bidi_SetTextDir.html
+++ b/dojox/charting/tests/BidiSupport/bidi_SetTextDir.html
@@ -47,7 +47,7 @@
 			}
 
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("doh.runner");
@@ -76,10 +76,6 @@
 			dojo.require("dijit.form.NumberSpinner");
 			dojo.require("dojo.parser");
 
-
-			dojo.require("dojox.charting.BidiSupport");
-			dojo.require("dojox.charting.widget.BidiSupport");
-
 			var chart1, legend1, pie, pieLegend;
 			seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
 
@@ -315,7 +311,7 @@
 		  
 
 		<h2>HTML declared chart.</h2>
-		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" jsId="tableStore"></div>
+		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" data-dojo-id="tableStore"></div>
 		<table id="tableExample" style="display: none;">
 			<thead>
 				<tr><th>value</th></tr>
diff --git a/dojox/charting/tests/BidiSupport/bidi_Spider2d.html b/dojox/charting/tests/BidiSupport/bidi_Spider2d.html
index 38580fe..c489a1a 100644
--- a/dojox/charting/tests/BidiSupport/bidi_Spider2d.html
+++ b/dojox/charting/tests/BidiSupport/bidi_Spider2d.html
@@ -53,7 +53,7 @@
 				padding: 1px 3px 0 3px;
 			}
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("doh.runner");
@@ -68,9 +68,6 @@
 			dojo.require("dojox.gfx.fx");
 			dojo.require("dojox.charting.widget.SelectableLegend");
 
-			dojo.require("dojox.charting.BidiSupport");
-			dojo.require("dojox.charting.widget.BidiSupport");
-			
 			var dc = dojox.charting,
 				divisions = 7,
 				stype = "polygon",
@@ -271,4 +268,4 @@
 	<div id="test1" style="width: 500px; height: 500px;"></div>
 	<p/>
 	</body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dojox/charting/tests/BidiSupport/charting.js b/dojox/charting/tests/BidiSupport/charting.js
new file mode 100644
index 0000000..d97915d
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/charting.js
@@ -0,0 +1,3 @@
+define([
+    	"dojox/charting/tests/Theme",
+], 1);
diff --git a/dojox/charting/tests/BidiSupport/data/goog_prices.csv b/dojox/charting/tests/BidiSupport/data/goog_prices.csv
new file mode 100644
index 0000000..901a6d2
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/data/goog_prices.csv
@@ -0,0 +1,796 @@
+Date,Open,High,Low,Close,Volume,Adj Close
+2008-02-29,471.87,479.74,464.65,471.18,9425400,471.18
+2008-02-28,470.50,479.09,467.36,475.39,6586900,475.39
+2008-02-27,460.13,475.49,459.64,472.86,10121900,472.86
+2008-02-26,461.20,466.47,446.85,464.19,23287300,464.19
+2008-02-25,505.95,506.50,485.74,486.44,8350800,486.44
+2008-02-22,502.06,509.00,497.55,507.80,5515900,507.80
+2008-02-21,512.85,513.21,499.50,502.86,5677800,502.86
+2008-02-20,503.51,511.01,498.82,509.00,6662200,509.00
+2008-02-19,534.94,535.06,506.50,508.95,6350400,508.95
+2008-02-15,528.31,532.66,524.33,529.64,5240100,529.64
+2008-02-14,538.35,541.04,531.00,532.25,6476700,532.25
+2008-02-13,522.50,534.99,518.69,534.62,6624700,534.62
+2008-02-12,523.39,530.60,513.03,518.09,6662300,518.09
+2008-02-11,520.52,523.71,513.40,521.16,5826000,521.16
+2008-02-08,509.41,517.73,508.70,516.69,6828900,516.69
+2008-02-07,496.86,514.19,494.76,504.95,7928900,504.95
+2008-02-06,511.14,511.17,497.93,501.71,7636400,501.71
+2008-02-05,489.43,509.00,488.52,506.80,11203300,506.80
+2008-02-04,509.07,512.78,492.55,495.43,13157100,495.43
+2008-02-01,528.67,536.67,510.00,515.90,17600500,515.90
+2008-01-31,539.01,573.00,534.29,564.30,14871300,564.30
+2008-01-30,549.19,560.43,543.51,548.27,7939600,548.27
+2008-01-29,560.47,561.33,540.67,550.52,6283000,550.52
+2008-01-28,570.97,572.24,548.60,555.98,5816700,555.98
+2008-01-25,591.81,595.00,566.18,566.40,6966000,566.40
+2008-01-24,558.80,579.69,554.14,574.49,9400900,574.49
+2008-01-23,560.71,568.00,519.00,548.62,16965700,548.62
+2008-01-22,562.03,597.50,561.20,584.35,9501500,584.35
+2008-01-18,608.36,609.99,598.45,600.25,8539600,600.25
+2008-01-17,620.76,625.74,598.01,600.79,8216800,600.79
+2008-01-16,628.97,639.99,601.93,615.95,10560000,615.95
+2008-01-15,645.90,649.05,635.38,637.65,5568200,637.65
+2008-01-14,651.14,657.40,645.25,653.82,4447500,653.82
+2008-01-11,642.70,649.47,630.11,638.25,4977000,638.25
+2008-01-10,645.01,657.20,640.11,646.73,6334200,646.73
+2008-01-09,630.04,653.34,622.51,653.20,6739700,653.20
+2008-01-08,653.00,659.96,631.00,631.68,5339100,631.68
+2008-01-07,653.94,662.28,637.35,649.25,6403400,649.25
+2008-01-04,679.69,680.96,655.00,657.00,5359800,657.00
+2008-01-03,685.26,686.85,676.52,685.33,3252500,685.33
+2008-01-02,692.87,697.37,677.73,685.19,4306900,685.19
+2007-12-31,698.57,702.49,690.58,691.48,2376200,691.48
+2007-12-28,704.93,707.95,696.54,702.53,2562700,702.53
+2007-12-27,707.07,716.00,700.74,700.74,2942500,700.74
+2007-12-26,698.99,713.22,698.21,710.84,2530000,710.84
+2007-12-24,694.99,700.73,693.06,700.73,1628400,700.73
+2007-12-21,697.88,699.26,693.24,696.69,5382000,696.69
+2007-12-20,685.83,691.00,680.61,689.69,4422200,689.69
+2007-12-19,674.21,679.50,669.00,677.37,4421100,677.37
+2007-12-18,674.16,676.71,652.50,673.35,7166700,673.35
+2007-12-17,688.00,695.42,663.67,669.23,5486000,669.23
+2007-12-14,687.51,699.70,687.26,689.96,3673500,689.96
+2007-12-13,696.31,697.62,681.21,694.05,5040800,694.05
+2007-12-12,714.00,714.32,688.50,699.35,6159100,699.35
+2007-12-11,719.94,720.99,698.78,699.20,6139100,699.20
+2007-12-10,715.99,724.80,714.00,718.42,3856200,718.42
+2007-12-07,714.99,718.00,710.50,714.87,3852100,714.87
+2007-12-06,697.80,716.56,697.01,715.26,4909000,715.26
+2007-12-05,692.73,698.93,687.50,698.51,4209600,698.51
+2007-12-04,678.31,692.00,677.12,684.16,4231800,684.16
+2007-12-03,691.01,695.00,681.14,681.53,4325100,681.53
+2007-11-30,711.00,711.06,682.11,693.00,7895500,693.00
+2007-11-29,690.75,702.79,687.77,697.00,6208000,697.00
+2007-11-28,682.11,694.30,672.14,692.26,7916500,692.26
+2007-11-27,674.80,676.43,650.26,673.57,8904500,673.57
+2007-11-26,680.20,693.40,665.00,666.00,6790100,666.00
+2007-11-23,670.00,678.28,668.11,676.70,2738700,676.70
+2007-11-21,643.77,669.97,642.08,660.52,7013500,660.52
+2007-11-20,636.48,659.10,632.87,648.54,9840600,648.54
+2007-11-19,629.59,636.77,618.50,625.85,5527400,625.85
+2007-11-16,633.94,635.49,616.02,633.63,9042800,633.63
+2007-11-15,638.57,647.50,624.00,629.65,6967700,629.65
+2007-11-14,673.28,675.49,636.27,641.68,8094700,641.68
+2007-11-13,644.99,660.92,632.07,660.55,8426100,660.55
+2007-11-12,657.74,669.93,626.21,632.07,10227300,632.07
+2007-11-09,675.78,681.88,661.21,663.97,11388100,663.97
+2007-11-08,734.60,734.89,677.18,693.84,16512200,693.84
+2007-11-07,741.13,747.24,723.14,732.94,8252900,732.94
+2007-11-06,737.56,741.79,725.00,741.79,8436300,741.79
+2007-11-05,706.99,730.23,706.07,725.65,8883700,725.65
+2007-11-02,710.51,713.58,697.34,711.25,5841500,711.25
+2007-11-01,702.79,713.72,701.78,703.21,6527200,703.21
+2007-10-31,700.69,707.00,696.04,707.00,6876800,707.00
+2007-10-30,677.51,699.91,677.51,694.77,6900600,694.77
+2007-10-29,677.77,680.00,672.09,679.23,3066300,679.23
+2007-10-26,674.03,676.54,668.06,674.60,3353900,674.60
+2007-10-25,678.68,678.97,663.55,668.51,5795500,668.51
+2007-10-24,672.71,677.47,659.56,675.82,7404200,675.82
+2007-10-23,661.25,677.60,660.00,675.77,6793700,675.77
+2007-10-22,638.67,655.00,636.28,650.75,6664400,650.75
+2007-10-19,654.56,658.49,643.23,644.71,15789000,644.71
+2007-10-18,635.41,641.37,628.50,639.62,12289200,639.62
+2007-10-17,630.45,634.00,621.59,633.48,6030500,633.48
+2007-10-16,618.49,625.92,611.99,616.00,6025300,616.00
+2007-10-15,638.47,639.86,615.55,620.11,6943800,620.11
+2007-10-12,623.98,638.40,618.24,637.39,6823700,637.39
+2007-10-11,633.64,641.41,609.00,622.00,11799000,622.00
+2007-10-10,621.36,625.68,616.80,625.39,5385600,625.39
+2007-10-09,615.11,623.78,608.39,615.18,8767800,615.18
+2007-10-08,595.00,610.26,593.95,609.62,5028000,609.62
+2007-10-05,587.11,596.00,587.01,594.05,5068700,594.05
+2007-10-04,585.09,585.09,577.06,579.03,2986700,579.03
+2007-10-03,586.25,588.99,580.36,584.02,3879500,584.02
+2007-10-02,583.38,596.81,580.01,584.39,7067500,584.39
+2007-10-01,569.97,584.35,569.61,582.55,4711300,582.55
+2007-09-28,567.00,569.55,564.12,567.27,2639500,567.27
+2007-09-27,571.73,571.74,565.78,567.50,2056300,567.50
+2007-09-26,570.40,571.79,563.81,568.16,3346100,568.16
+2007-09-25,564.00,569.56,562.86,569.00,2730600,569.00
+2007-09-24,561.00,571.46,560.00,568.02,5297000,568.02
+2007-09-21,556.34,560.79,552.83,560.10,8011700,560.10
+2007-09-20,547.00,556.80,546.03,552.83,5525000,552.83
+2007-09-19,539.27,549.45,538.86,546.85,5526900,546.85
+2007-09-18,526.52,537.25,524.27,535.27,4215700,535.27
+2007-09-17,526.53,529.28,524.07,525.30,2197500,525.30
+2007-09-14,523.20,530.27,522.22,528.75,2764900,528.75
+2007-09-13,524.06,527.21,523.22,524.78,1891100,524.78
+2007-09-12,520.53,527.98,519.00,522.65,2986000,522.65
+2007-09-11,516.99,521.65,515.73,521.33,2703600,521.33
+2007-09-10,521.28,522.07,510.88,514.48,3225800,514.48
+2007-09-07,517.86,521.24,516.80,519.35,3663600,519.35
+2007-09-06,529.36,529.83,518.24,523.52,3625900,523.52
+2007-09-05,523.40,529.48,522.25,527.80,3312900,527.80
+2007-09-04,515.02,528.00,514.62,525.15,3693700,525.15
+2007-08-31,513.10,516.50,511.47,515.25,2977600,515.25
+2007-08-30,512.36,515.40,510.58,511.40,2651700,511.40
+2007-08-29,507.84,513.30,507.23,512.88,2549300,512.88
+2007-08-28,511.53,514.98,505.79,506.40,3273900,506.40
+2007-08-27,514.43,517.45,511.40,513.26,2325100,513.26
+2007-08-24,512.61,515.55,508.50,515.00,2472700,515.00
+2007-08-23,516.00,516.13,507.00,512.19,3076700,512.19
+2007-08-22,509.96,516.25,509.25,512.75,3252700,512.75
+2007-08-21,498.94,508.16,497.77,506.61,3610600,506.61
+2007-08-20,502.46,502.56,496.00,497.92,2697300,497.92
+2007-08-17,497.44,501.00,491.65,500.04,5479400,500.04
+2007-08-16,492.02,496.43,480.46,491.52,8645600,491.52
+2007-08-15,509.00,511.69,496.71,497.55,5409500,497.55
+2007-08-14,515.72,517.40,508.00,508.60,3633700,508.60
+2007-08-13,519.54,519.75,513.03,515.50,3179300,515.50
+2007-08-10,510.18,518.72,505.63,515.75,5875200,515.75
+2007-08-09,520.80,526.82,514.63,514.73,4846500,514.73
+2007-08-08,519.34,525.78,517.09,525.78,4068800,525.78
+2007-08-07,509.75,519.88,509.04,516.02,4264300,516.02
+2007-08-06,503.00,510.15,502.50,510.00,3651500,510.00
+2007-08-03,510.05,513.20,503.00,503.00,3176200,503.00
+2007-08-02,513.72,514.99,509.00,511.01,3154900,511.01
+2007-08-01,510.50,516.51,508.14,512.94,4421500,512.94
+2007-07-31,520.23,520.44,510.00,510.00,4270500,510.00
+2007-07-30,512.92,519.34,510.50,516.11,3963300,516.11
+2007-07-27,508.53,516.62,505.50,511.89,5509100,511.89
+2007-07-26,508.74,512.59,498.88,508.00,6883400,508.00
+2007-07-25,516.98,517.02,505.56,509.76,5545000,509.76
+2007-07-24,509.30,518.69,507.11,514.00,5572100,514.00
+2007-07-23,519.01,520.00,512.15,512.51,6356700,512.51
+2007-07-20,511.90,523.18,509.50,520.12,17772300,520.12
+2007-07-19,553.46,553.52,542.24,548.59,11127200,548.59
+2007-07-18,553.89,554.50,543.81,549.50,6080000,549.50
+2007-07-17,555.04,557.73,552.38,555.00,4328600,555.00
+2007-07-16,550.30,558.58,549.31,552.99,6599500,552.99
+2007-07-13,547.91,552.67,547.25,552.16,5237100,552.16
+2007-07-12,545.86,547.32,540.22,545.33,3441600,545.33
+2007-07-11,543.61,546.50,540.01,544.47,3309300,544.47
+2007-07-10,543.79,547.00,541.65,543.34,3856000,543.34
+2007-07-09,543.00,548.74,540.26,542.56,3729800,542.56
+2007-07-06,541.25,543.87,538.73,539.40,2747000,539.40
+2007-07-05,535.56,544.40,532.15,541.63,4942900,541.63
+2007-07-03,531.06,534.40,527.50,534.34,1871800,534.34
+2007-07-02,525.49,531.85,524.20,530.38,3487600,530.38
+2007-06-29,526.02,527.40,519.46,522.70,3880600,522.70
+2007-06-28,524.88,529.50,523.80,525.01,4168400,525.01
+2007-06-27,525.00,527.99,519.56,526.29,6123100,526.29
+2007-06-26,532.73,533.20,526.24,530.26,5689500,530.26
+2007-06-25,528.98,534.99,523.38,527.42,7925000,527.42
+2007-06-22,516.42,524.99,516.10,524.98,7203700,524.98
+2007-06-21,510.98,515.29,506.28,514.11,4409700,514.11
+2007-06-20,516.96,518.75,509.06,509.97,4338200,509.97
+2007-06-19,514.01,517.25,511.54,514.31,4355300,514.31
+2007-06-18,506.18,516.00,504.24,515.20,4835900,515.20
+2007-06-15,508.19,509.00,501.23,505.89,6174100,505.89
+2007-06-14,505.38,505.88,501.70,502.84,4621200,502.84
+2007-06-13,507.09,508.54,498.69,505.24,7034000,505.24
+2007-06-12,508.71,511.67,503.17,504.77,6419500,504.77
+2007-06-11,514.02,518.25,510.00,511.34,4647700,511.34
+2007-06-08,516.20,519.64,509.46,515.49,6358200,515.49
+2007-06-07,519.75,526.50,512.51,515.06,10630500,515.06
+2007-06-06,516.75,520.78,515.26,518.25,7886700,518.25
+2007-06-05,509.75,519.00,506.61,518.84,10447100,518.84
+2007-06-04,497.91,510.51,497.59,507.07,7101000,507.07
+2007-06-01,501.00,505.02,497.93,500.40,4799000,500.40
+2007-05-31,500.56,508.78,497.06,497.91,8924300,497.91
+2007-05-30,484.50,498.84,483.00,498.60,7245800,498.60
+2007-05-29,485.00,491.80,484.00,487.11,5218000,487.11
+2007-05-25,479.70,484.95,477.27,483.52,5348500,483.52
+2007-05-24,475.15,479.20,471.50,474.33,4173600,474.33
+2007-05-23,480.82,483.41,473.75,473.97,5060200,473.97
+2007-05-22,473.00,479.01,473.00,475.86,3839000,475.86
+2007-05-21,469.53,479.20,466.72,470.60,6159300,470.60
+2007-05-18,472.03,472.70,469.75,470.32,3695900,470.32
+2007-05-17,472.46,475.22,470.81,470.96,4660600,470.96
+2007-05-16,462.00,473.14,459.02,472.61,6554200,472.61
+2007-05-15,461.96,462.54,457.41,458.00,4119000,458.00
+2007-05-14,465.48,467.51,460.00,461.78,3872700,461.78
+2007-05-11,461.83,467.00,461.00,466.74,2944100,466.74
+2007-05-10,467.04,469.49,461.02,461.47,3686300,461.47
+2007-05-09,466.15,471.73,463.88,469.25,3889900,469.25
+2007-05-08,466.13,468.17,464.73,466.81,2905100,466.81
+2007-05-07,472.14,472.82,466.47,467.27,3020100,467.27
+2007-05-04,470.12,474.84,465.88,471.12,3950000,471.12
+2007-05-03,466.22,474.07,465.29,473.23,3594200,473.23
+2007-05-02,468.65,471.08,465.73,465.78,3062700,465.78
+2007-05-01,472.19,472.81,464.17,469.00,3658200,469.00
+2007-04-30,479.15,481.35,471.38,471.38,3641200,471.38
+2007-04-27,480.07,482.40,478.33,479.01,2925700,479.01
+2007-04-26,478.10,484.45,477.11,481.18,4124900,481.18
+2007-04-25,480.00,481.37,476.11,477.99,3966800,477.99
+2007-04-24,478.61,479.98,475.55,477.53,3694700,477.53
+2007-04-23,480.10,485.00,478.26,479.08,5674600,479.08
+2007-04-20,490.52,492.50,482.02,482.48,12161500,482.48
+2007-04-19,474.50,481.95,469.59,471.65,11009600,471.65
+2007-04-18,471.26,479.90,469.53,476.01,5670500,476.01
+2007-04-17,473.80,476.39,471.60,472.80,3210100,472.80
+2007-04-16,468.46,476.99,468.15,474.27,5077900,474.27
+2007-04-13,468.45,468.77,463.36,466.29,2794800,466.29
+2007-04-12,464.00,468.00,462.24,467.39,2707900,467.39
+2007-04-11,466.06,469.40,462.61,464.53,3812000,464.53
+2007-04-10,467.09,470.79,465.16,466.50,2979300,466.50
+2007-04-09,472.98,473.00,465.59,468.21,3062100,468.21
+2007-04-05,471.30,472.09,469.62,471.51,2715800,471.51
+2007-04-04,472.14,473.00,469.58,471.02,3778800,471.02
+2007-04-03,464.05,474.25,464.00,472.60,6501800,472.60
+2007-04-02,457.76,458.53,452.12,458.53,3448500,458.53
+2007-03-30,462.10,463.40,456.14,458.16,3380200,458.16
+2007-03-29,464.55,466.00,455.00,460.92,3988500,460.92
+2007-03-28,461.87,465.44,460.15,461.88,4591600,461.88
+2007-03-27,463.55,465.23,460.34,463.62,3741200,463.62
+2007-03-26,460.55,465.00,455.62,465.00,4710300,465.00
+2007-03-23,461.45,463.39,457.08,461.83,4111300,461.83
+2007-03-22,455.61,462.17,452.53,462.04,5680700,462.04
+2007-03-21,445.30,456.57,445.21,456.55,5798300,456.55
+2007-03-20,445.79,447.60,443.60,445.28,3421500,445.28
+2007-03-19,443.25,448.50,440.63,447.23,5197700,447.23
+2007-03-16,445.65,446.70,439.89,440.85,5659100,440.85
+2007-03-15,447.86,449.82,443.94,446.19,3944200,446.19
+2007-03-14,443.23,448.66,439.00,448.00,8016900,448.00
+2007-03-13,450.11,451.93,442.83,443.03,6377300,443.03
+2007-03-12,452.57,455.25,451.11,454.75,3465400,454.75
+2007-03-09,458.00,458.40,450.10,452.96,4977700,452.96
+2007-03-08,459.22,465.50,454.10,454.72,5362800,454.72
+2007-03-07,462.69,463.14,454.29,455.64,6534100,455.64
+2007-03-06,447.47,459.00,447.38,457.55,7533700,457.55
+2007-03-05,437.02,445.50,437.00,440.95,6355100,440.95
+2007-03-02,445.11,448.70,438.68,438.68,6583600,438.68
+2007-03-01,442.67,452.42,440.00,448.23,8685200,448.23
+2007-02-28,450.41,453.67,443.04,449.45,8032300,449.45
+2007-02-27,455.00,459.80,447.17,448.77,9312800,448.77
+2007-02-26,472.83,475.25,463.75,464.93,3969900,464.93
+2007-02-23,475.75,476.95,467.80,470.62,3882600,470.62
+2007-02-22,478.69,484.24,474.39,475.85,5743900,475.85
+2007-02-21,469.84,478.68,467.74,475.86,5640600,475.86
+2007-02-20,468.47,472.75,464.71,472.10,4067600,472.10
+2007-02-16,462.80,470.15,462.06,469.94,6177000,469.94
+2007-02-15,466.00,466.13,460.72,461.47,4042400,461.47
+2007-02-14,460.00,469.13,459.22,465.93,5698800,465.93
+2007-02-13,459.15,462.78,457.26,459.10,4062600,459.10
+2007-02-12,460.68,462.39,455.02,458.29,5754500,458.29
+2007-02-09,471.65,472.68,461.50,461.89,4858600,461.89
+2007-02-08,468.05,473.75,465.15,471.03,4076700,471.03
+2007-02-07,473.82,474.35,468.78,470.01,4119800,470.01
+2007-02-06,468.10,473.30,467.26,471.48,5321900,471.48
+2007-02-05,477.50,478.00,466.19,467.16,7206900,467.16
+2007-02-02,482.61,485.00,477.81,481.50,6286500,481.50
+2007-02-01,506.00,506.01,481.53,481.75,15658700,481.75
+2007-01-31,496.49,505.00,495.51,501.50,12206100,501.50
+2007-01-30,494.00,498.00,491.22,494.32,4180500,494.32
+2007-01-29,498.00,498.75,490.50,492.47,4775700,492.47
+2007-01-26,490.93,497.90,487.03,495.84,5496500,495.84
+2007-01-25,501.00,504.50,485.66,488.09,6368500,488.09
+2007-01-24,484.45,499.54,483.29,499.07,6059300,499.07
+2007-01-23,480.79,484.75,477.29,479.05,4665500,479.05
+2007-01-22,492.50,492.65,478.50,480.84,5404300,480.84
+2007-01-19,487.98,490.76,486.74,489.75,4978300,489.75
+2007-01-18,494.52,496.48,487.43,487.83,5932000,487.83
+2007-01-17,503.39,507.77,494.38,497.28,6699100,497.28
+2007-01-16,507.55,513.00,503.30,504.28,7568900,504.28
+2007-01-12,501.99,505.00,500.00,505.00,4473700,505.00
+2007-01-11,497.20,501.75,496.18,499.72,7208200,499.72
+2007-01-10,484.43,493.55,482.04,489.46,5968500,489.46
+2007-01-09,485.45,488.25,481.20,485.50,5381400,485.50
+2007-01-08,487.69,489.87,482.20,483.58,4754400,483.58
+2007-01-05,482.50,487.50,478.11,487.19,6872100,487.19
+2007-01-04,469.00,483.95,468.35,483.26,7887600,483.26
+2007-01-03,466.00,476.66,461.11,467.59,7706500,467.59
+2006-12-29,462.10,464.47,459.86,460.48,2559200,460.48
+2006-12-28,467.12,468.58,462.25,462.56,3116200,462.56
+2006-12-27,460.00,468.08,459.10,468.03,4231500,468.03
+2006-12-26,456.52,459.47,454.59,457.53,2074300,457.53
+2006-12-22,457.50,458.64,452.73,455.58,3988300,455.58
+2006-12-21,464.18,465.25,452.34,456.20,6953300,456.20
+2006-12-20,470.00,471.50,462.33,462.90,4367800,462.90
+2006-12-19,461.72,469.31,458.50,468.63,6587000,468.63
+2006-12-18,482.51,482.74,460.72,462.80,8016600,462.80
+2006-12-15,482.64,484.11,479.84,480.30,5190800,480.30
+2006-12-14,480.25,483.75,477.26,482.12,4748900,482.12
+2006-12-13,484.69,485.50,477.02,478.99,4662100,478.99
+2006-12-12,483.85,486.36,480.28,481.78,4181000,481.78
+2006-12-11,484.92,488.90,483.80,483.93,3263400,483.93
+2006-12-08,481.94,488.60,480.00,484.11,3974900,484.11
+2006-12-07,490.23,491.80,482.42,482.64,4664300,482.64
+2006-12-06,486.96,492.40,484.52,488.71,4450300,488.71
+2006-12-05,487.40,489.44,484.89,487.00,4103000,487.00
+2006-12-04,483.00,487.43,479.35,484.85,4899900,484.85
+2006-12-01,485.98,488.39,478.50,480.80,5631400,480.80
+2006-11-30,484.19,490.40,481.55,484.81,5577500,484.81
+2006-11-29,494.24,494.74,482.25,484.65,6315300,484.65
+2006-11-28,481.13,489.86,477.03,489.50,7797600,489.50
+2006-11-27,501.37,501.78,484.75,484.75,7324700,484.75
+2006-11-24,504.50,507.50,504.00,505.00,1732700,505.00
+2006-11-22,510.97,513.00,505.78,508.01,4500700,508.01
+2006-11-21,496.54,510.00,495.83,509.65,8427500,509.65
+2006-11-20,498.40,498.40,492.65,495.05,5124500,495.05
+2006-11-17,493.25,499.66,493.00,498.79,5511000,498.79
+2006-11-16,495.00,497.68,492.56,495.90,5092600,495.90
+2006-11-15,493.43,499.85,491.93,491.93,8370700,491.93
+2006-11-14,480.70,489.95,480.50,489.30,7223400,489.30
+2006-11-13,474.90,481.17,474.14,481.03,4341900,481.03
+2006-11-10,473.78,474.72,470.29,473.55,2796700,473.55
+2006-11-09,476.50,479.49,471.86,472.63,4879200,472.63
+2006-11-08,470.35,481.74,468.60,475.00,7965000,475.00
+2006-11-07,476.95,479.02,471.77,472.57,4897100,472.57
+2006-11-06,473.77,479.66,472.33,476.95,4991500,476.95
+2006-11-03,472.23,473.75,465.06,471.80,4907700,471.80
+2006-11-02,467.50,473.73,466.38,469.91,5236700,469.91
+2006-11-01,478.76,479.13,465.26,467.50,5426300,467.50
+2006-10-31,478.06,482.16,473.84,476.39,6285400,476.39
+2006-10-30,474.82,480.46,470.01,476.57,6563100,476.57
+2006-10-27,483.90,485.24,472.49,475.20,6604000,475.20
+2006-10-26,487.68,491.96,484.20,485.10,7031700,485.10
+2006-10-25,477.49,488.50,475.11,486.60,9187500,486.60
+2006-10-24,476.28,477.86,471.41,473.31,8660200,473.31
+2006-10-23,462.28,484.64,460.37,480.78,15104500,480.78
+2006-10-20,458.99,460.10,453.59,459.67,11647900,459.67
+2006-10-19,420.23,429.50,419.57,426.06,11503500,426.06
+2006-10-18,422.99,424.75,417.50,419.31,6017300,419.31
+2006-10-17,420.30,423.75,416.70,420.64,5211000,420.64
+2006-10-16,427.70,429.20,421.34,421.75,4319400,421.75
+2006-10-13,427.76,429.50,425.56,427.30,3622500,427.30
+2006-10-12,428.56,429.68,424.00,427.44,4844000,427.44
+2006-10-11,425.02,429.91,423.76,426.50,5635400,426.50
+2006-10-10,431.56,437.85,422.39,426.65,9788600,426.65
+2006-10-09,424.80,431.95,423.42,429.00,7583300,429.00
+2006-10-06,410.22,421.91,409.75,420.50,7336500,420.50
+2006-10-05,414.70,418.24,410.86,411.81,5789800,411.81
+2006-10-04,404.97,415.77,403.05,415.70,6661800,415.70
+2006-10-03,401.29,406.46,398.19,404.04,5464700,404.04
+2006-10-02,401.90,406.00,400.80,401.44,3651900,401.44
+2006-09-29,405.13,405.62,401.41,401.90,3310900,401.90
+2006-09-28,404.08,406.98,400.54,403.58,5107400,403.58
+2006-09-27,406.30,411.22,402.37,402.92,5876700,402.92
+2006-09-26,405.50,407.68,401.77,406.87,5289400,406.87
+2006-09-25,405.58,409.45,402.50,403.98,5737300,403.98
+2006-09-22,404.98,407.45,401.36,403.78,4649600,403.78
+2006-09-21,400.30,408.45,399.86,406.85,10692100,406.85
+2006-09-20,407.10,407.39,394.62,397.00,9147800,397.00
+2006-09-19,415.46,415.49,392.74,403.81,14292900,403.81
+2006-09-18,410.00,418.69,409.47,414.69,7106700,414.69
+2006-09-15,407.48,410.05,406.74,409.88,7838200,409.88
+2006-09-14,404.30,406.28,401.93,403.98,5366100,403.98
+2006-09-13,395.15,406.76,395.10,406.57,9768200,406.57
+2006-09-12,385.00,392.73,384.88,391.90,5442200,391.90
+2006-09-11,378.26,384.69,377.77,384.09,4529200,384.09
+2006-09-08,376.72,380.79,376.72,377.85,3083400,377.85
+2006-09-07,379.39,381.75,377.40,378.49,3842000,378.49
+2006-09-06,382.10,383.19,379.66,380.14,3724100,380.14
+2006-09-05,379.87,385.40,377.44,384.36,4074300,384.36
+2006-09-01,380.99,381.28,377.19,378.60,2672900,378.60
+2006-08-31,381.49,382.15,378.20,378.53,2959900,378.53
+2006-08-30,379.21,384.65,378.51,380.75,4044400,380.75
+2006-08-29,380.78,382.32,377.20,378.95,4460000,378.95
+2006-08-28,375.61,380.95,375.00,380.95,4164000,380.95
+2006-08-25,373.08,375.32,372.50,373.26,2466700,373.26
+2006-08-24,374.44,376.40,372.26,373.73,3482500,373.73
+2006-08-23,377.64,378.27,372.66,373.43,3642300,373.43
+2006-08-22,377.73,379.26,374.84,378.29,4164100,378.29
+2006-08-21,378.10,379.00,375.22,377.30,4023300,377.30
+2006-08-18,386.31,387.09,380.75,383.36,4952200,383.36
+2006-08-17,386.39,390.00,383.92,385.80,5080200,385.80
+2006-08-16,383.48,388.45,382.12,387.72,5853200,387.72
+2006-08-15,374.11,381.67,372.60,380.97,6698200,380.97
+2006-08-14,371.50,375.13,368.67,369.43,4968300,369.43
+2006-08-11,374.40,375.28,368.00,368.50,3766500,368.50
+2006-08-10,373.88,377.67,372.46,374.20,4261900,374.20
+2006-08-09,382.80,384.68,376.36,376.94,4311000,376.94
+2006-08-08,382.82,384.50,379.09,381.00,5743200,381.00
+2006-08-07,371.50,379.73,371.15,377.95,3946900,377.95
+2006-08-04,379.56,380.68,371.75,373.85,5095200,373.85
+2006-08-03,364.98,377.91,363.36,375.39,6327000,375.39
+2006-08-02,375.60,377.17,365.20,367.23,7097800,367.23
+2006-08-01,385.11,385.77,375.51,375.51,5463200,375.51
+2006-07-31,388.00,389.17,383.31,386.60,4595300,386.60
+2006-07-28,382.00,389.56,381.73,388.12,4083600,388.12
+2006-07-27,387.37,387.49,377.95,382.40,5641100,382.40
+2006-07-26,388.20,391.91,383.00,385.50,5531900,385.50
+2006-07-25,385.02,391.31,383.80,389.36,5761100,389.36
+2006-07-24,392.82,393.89,381.21,390.90,8086100,390.90
+2006-07-21,386.14,391.75,377.69,390.11,11754600,390.11
+2006-07-20,404.28,404.44,385.66,387.12,12538700,387.12
+2006-07-19,395.01,401.14,394.66,399.00,8518500,399.00
+2006-07-18,409.75,410.57,397.74,403.05,8536800,403.05
+2006-07-17,404.63,411.00,403.72,407.89,5811900,407.89
+2006-07-14,410.33,411.49,398.61,403.50,7552100,403.50
+2006-07-13,414.00,418.34,406.83,408.83,6924500,408.83
+2006-07-12,422.09,422.74,416.73,417.25,4906700,417.25
+2006-07-11,418.51,425.05,413.03,424.56,5971300,424.56
+2006-07-10,423.44,425.23,416.38,418.20,4436400,418.20
+2006-07-07,426.05,427.89,415.88,420.45,6041900,420.45
+2006-07-06,423.38,425.38,421.98,423.19,3687100,423.19
+2006-07-05,421.52,422.80,415.64,421.46,4985600,421.46
+2006-07-03,420.04,423.77,419.45,423.20,2156700,423.20
+2006-06-30,415.60,419.33,412.33,419.33,6258000,419.33
+2006-06-29,407.99,418.20,405.82,417.81,6658200,417.81
+2006-06-28,404.01,406.48,401.13,406.11,3710500,406.11
+2006-06-27,405.71,408.00,401.01,402.32,4107100,402.32
+2006-06-26,406.75,408.30,403.25,404.22,3551200,404.22
+2006-06-23,402.76,409.75,400.74,404.86,5314800,404.86
+2006-06-22,401.58,406.00,388.00,399.95,5911900,399.95
+2006-06-21,391.06,404.00,389.75,402.13,8744400,402.13
+2006-06-20,388.03,391.87,386.51,387.17,4039900,387.17
+2006-06-19,390.85,394.80,386.98,388.14,7633100,388.14
+2006-06-16,389.10,390.93,388.00,390.70,5304600,390.70
+2006-06-15,386.62,392.25,383.00,391.00,6785700,391.00
+2006-06-14,389.83,391.10,378.52,384.39,7772000,384.39
+2006-06-13,380.90,387.00,378.12,386.52,7659100,386.52
+2006-06-12,388.34,390.49,381.00,381.54,5019100,381.54
+2006-06-09,392.19,395.43,385.35,386.57,6157500,386.57
+2006-06-08,387.75,394.27,378.59,393.30,10359500,393.30
+2006-06-07,393.24,394.86,386.50,386.51,8911300,386.51
+2006-06-06,376.58,390.00,376.30,389.99,10259800,389.99
+2006-06-05,376.18,381.45,374.15,374.44,5558500,374.44
+2006-06-02,386.84,387.08,377.45,379.44,6386400,379.44
+2006-06-01,373.54,382.99,371.60,382.62,6278000,382.62
+2006-05-31,373.80,378.25,366.78,371.82,7981300,371.82
+2006-05-30,378.28,381.00,371.45,371.94,4316000,371.94
+2006-05-26,384.55,385.88,380.03,381.35,3667000,381.35
+2006-05-25,379.08,383.00,372.31,382.99,8194600,382.99
+2006-05-24,377.35,383.44,371.61,381.25,9553800,381.25
+2006-05-23,374.21,383.88,373.56,375.58,8983000,375.58
+2006-05-22,367.85,373.03,365.25,370.95,8604400,370.95
+2006-05-19,373.28,374.50,360.57,370.02,11398200,370.02
+2006-05-18,378.78,381.81,370.71,370.99,5835000,370.99
+2006-05-17,370.61,379.84,370.22,374.50,10643800,374.50
+2006-05-16,375.99,376.86,369.89,371.30,6491100,371.30
+2006-05-15,375.93,380.15,368.25,376.20,8590100,376.20
+2006-05-12,383.54,384.87,373.55,374.13,10087600,374.13
+2006-05-11,403.42,404.71,384.98,387.00,8892800,387.00
+2006-05-10,408.31,411.71,401.86,402.98,6187200,402.98
+2006-05-09,395.70,409.00,393.75,408.80,9140600,408.80
+2006-05-08,395.11,397.12,390.05,394.78,5118600,394.78
+2006-05-05,397.60,400.68,391.78,394.30,6065000,394.30
+2006-05-04,395.03,398.87,392.21,394.75,4652000,394.75
+2006-05-03,396.35,401.50,390.88,394.17,8072200,394.17
+2006-05-02,401.08,402.49,388.40,394.80,13104300,394.80
+2006-05-01,418.47,419.44,398.55,398.90,10361200,398.90
+2006-04-28,418.63,425.73,416.30,417.94,7421300,417.94
+2006-04-27,422.91,426.91,419.39,420.03,8337900,420.03
+2006-04-26,427.74,430.04,423.53,425.97,7277800,425.97
+2006-04-25,439.63,441.04,426.00,427.16,9569000,427.16
+2006-04-24,439.40,444.70,436.52,440.50,8836400,440.50
+2006-04-21,448.90,450.72,436.17,437.10,22551300,437.10
+2006-04-20,411.01,416.00,408.20,415.00,12271500,415.00
+2006-04-19,412.57,413.64,406.73,410.50,6781700,410.50
+2006-04-18,407.93,409.83,401.50,404.24,8137600,404.24
+2006-04-17,403.45,412.50,400.84,406.82,8259500,406.82
+2006-04-13,408.63,409.76,400.50,402.16,6552900,402.16
+2006-04-12,409.00,411.33,405.19,408.95,6017000,408.95
+2006-04-11,416.42,419.10,406.22,409.66,11107200,409.66
+2006-04-10,407.08,417.17,405.25,416.38,9320100,416.38
+2006-04-07,412.41,412.85,404.02,406.16,7025900,406.16
+2006-04-06,406.49,413.89,405.43,411.18,8598500,411.18
+2006-04-05,408.20,414.57,402.82,407.99,13410500,407.99
+2006-04-04,389.90,404.90,388.14,404.34,15715700,404.34
+2006-04-03,389.53,392.47,387.93,389.70,8122700,389.70
+2006-03-31,388.74,391.87,384.03,390.00,36521400,390.00
+2006-03-30,389.19,393.50,383.61,388.44,14711700,388.44
+2006-03-29,379.94,399.00,379.51,394.98,19027500,394.98
+2006-03-28,371.71,377.86,371.17,377.20,8945800,377.20
+2006-03-27,367.09,371.71,365.00,369.69,7023700,369.69
+2006-03-24,368.62,370.09,362.51,365.80,15180600,365.80
+2006-03-23,342.35,345.75,340.20,341.89,7434700,341.89
+2006-03-22,339.75,344.10,337.50,340.22,7596000,340.22
+2006-03-21,350.01,351.66,339.08,339.92,9831100,339.92
+2006-03-20,342.34,350.09,341.54,348.19,10407600,348.19
+2006-03-17,338.80,341.78,334.93,339.79,8551700,339.79
+2006-03-16,348.61,348.75,337.90,338.77,10016700,338.77
+2006-03-15,350.77,352.30,340.53,344.50,12768800,344.50
+2006-03-14,337.14,352.37,332.62,351.16,18450700,351.16
+2006-03-13,340.93,346.10,335.45,337.06,13642400,337.06
+2006-03-10,343.50,344.50,331.55,337.50,19325600,337.50
+2006-03-09,355.39,358.53,341.50,343.00,13910400,343.00
+2006-03-08,353.93,360.03,350.54,353.88,11745600,353.88
+2006-03-07,365.02,368.45,358.15,364.45,10378800,364.45
+2006-03-06,380.91,383.40,367.14,368.10,8939700,368.10
+2006-03-03,384.30,387.24,375.76,378.18,11962000,378.18
+2006-03-02,364.28,381.10,362.20,376.45,18330300,376.45
+2006-03-01,368.56,369.45,361.30,364.80,12061200,364.80
+2006-02-28,393.20,397.54,338.51,362.62,39437600,362.62
+2006-02-27,381.27,391.70,380.28,390.38,10212200,390.38
+2006-02-24,377.30,380.07,373.49,377.40,6484300,377.40
+2006-02-23,365.61,381.24,365.39,378.07,12551600,378.07
+2006-02-22,367.15,368.95,363.86,365.49,6476200,365.49
+2006-02-21,366.44,373.54,365.11,366.59,8686000,366.59
+2006-02-17,369.86,372.14,363.62,368.75,14320200,368.75
+2006-02-16,345.67,367.00,344.49,366.46,21315500,366.46
+2006-02-15,341.27,346.00,337.83,342.38,12947000,342.38
+2006-02-14,345.33,351.69,342.40,343.32,14654000,343.32
+2006-02-13,346.64,350.60,341.89,345.70,19717800,345.70
+2006-02-10,361.95,364.50,353.14,362.61,15223500,362.61
+2006-02-09,371.20,374.40,356.11,358.77,11912400,358.77
+2006-02-08,368.48,370.69,354.67,369.08,20804100,369.08
+2006-02-07,382.99,383.70,363.35,367.92,16630200,367.92
+2006-02-06,385.31,389.90,379.56,385.10,8940400,385.10
+2006-02-03,393.62,393.90,372.57,381.55,18281800,381.55
+2006-02-02,403.82,406.50,395.98,396.04,11807700,396.04
+2006-02-01,389.03,402.00,387.52,401.78,27122500,401.78
+2006-01-31,430.57,439.60,423.97,432.66,22066000,432.66
+2006-01-30,429.23,433.28,425.00,426.82,8588900,426.82
+2006-01-27,435.00,438.22,428.98,433.49,8452200,433.49
+2006-01-26,439.54,439.99,423.56,434.27,12926100,434.27
+2006-01-25,451.26,454.23,429.22,433.00,18739800,433.00
+2006-01-24,436.03,444.95,434.48,443.03,15464600,443.03
+2006-01-23,407.38,428.39,405.73,427.50,22741400,427.50
+2006-01-20,438.70,440.03,394.74,399.46,41116700,399.46
+2006-01-19,451.17,453.49,433.00,436.45,14537300,436.45
+2006-01-18,447.30,457.36,443.25,444.91,20485700,444.91
+2006-01-17,463.06,469.90,462.53,467.11,8270300,467.11
+2006-01-13,464.31,466.89,461.61,466.25,7656600,466.25
+2006-01-12,473.72,474.99,461.50,463.63,10125300,463.63
+2006-01-11,471.27,475.11,469.18,471.63,9007400,471.63
+2006-01-10,464.42,470.25,462.04,469.76,9097100,469.76
+2006-01-09,466.41,473.40,460.94,466.90,12791900,466.90
+2006-01-06,456.87,470.50,453.24,465.66,17756900,465.66
+2006-01-05,446.00,451.55,441.50,451.24,10808300,451.24
+2006-01-04,443.90,448.96,439.75,445.24,15286400,445.24
+2006-01-03,422.52,435.67,418.22,435.23,13121200,435.23
+2005-12-30,417.27,418.21,413.74,414.86,7587100,414.86
+2005-12-29,427.98,428.73,419.17,420.15,6945800,420.15
+2005-12-28,424.34,427.78,421.26,426.69,7117900,426.69
+2005-12-27,431.86,431.86,422.76,424.64,6702800,424.64
+2005-12-23,432.15,432.50,428.78,430.93,4595100,430.93
+2005-12-22,431.77,432.86,425.93,432.04,7546600,432.04
+2005-12-21,433.55,436.86,420.71,426.33,11221900,426.33
+2005-12-20,427.86,432.20,424.67,429.74,10084700,429.74
+2005-12-19,432.20,446.21,420.11,424.60,21936800,424.60
+2005-12-16,425.34,432.50,422.75,430.15,16330500,430.15
+2005-12-15,419.11,423.14,416.50,422.55,6045800,422.55
+2005-12-14,417.04,419.73,415.49,418.96,6630400,418.96
+2005-12-13,412.50,418.00,411.64,417.49,8157000,417.49
+2005-12-12,414.63,415.21,409.95,412.61,6950100,412.61
+2005-12-09,415.00,415.78,408.56,409.20,7643400,409.20
+2005-12-08,405.30,410.65,402.64,410.65,8910100,410.65
+2005-12-07,406.16,406.70,399.01,404.22,11665900,404.22
+2005-12-06,408.70,416.41,401.70,404.54,15114700,404.54
+2005-12-05,417.00,417.50,404.28,405.85,10289400,405.85
+2005-12-02,416.94,419.53,413.86,417.70,7543500,417.70
+2005-12-01,409.20,415.44,408.29,414.09,9744900,414.09
+2005-11-30,404.26,408.45,395.56,404.91,15596600,404.91
+2005-11-29,424.46,426.40,402.14,403.54,21495800,403.54
+2005-11-28,429.82,431.24,422.44,423.48,11008400,423.48
+2005-11-25,425.78,428.75,425.30,428.62,4840100,428.62
+2005-11-23,417.04,424.72,415.78,422.86,10085000,422.86
+2005-11-22,408.65,417.31,406.23,416.47,9596000,416.47
+2005-11-21,399.17,409.98,393.49,409.36,10335100,409.36
+2005-11-18,403.49,404.50,399.85,400.21,7025700,400.21
+2005-11-17,401.80,403.81,399.53,403.45,9212200,403.45
+2005-11-16,396.20,398.85,394.11,398.15,8695200,398.15
+2005-11-15,394.38,397.00,390.95,392.80,8624900,392.80
+2005-11-14,392.12,398.22,391.53,396.97,7807900,396.97
+2005-11-11,395.12,396.90,388.85,390.40,7063900,390.40
+2005-11-10,378.36,391.35,377.43,391.10,9128700,391.10
+2005-11-09,386.67,388.29,378.03,379.15,10466900,379.15
+2005-11-08,394.25,395.59,388.58,389.90,7897500,389.90
+2005-11-07,395.10,397.47,392.15,395.03,9591500,395.03
+2005-11-04,389.98,391.79,385.45,390.43,8824900,390.43
+2005-11-03,382.41,386.58,381.38,385.95,7448400,385.95
+2005-11-02,381.70,385.00,377.17,379.68,10565400,379.68
+2005-11-01,371.86,383.90,369.01,379.38,16356100,379.38
+2005-10-31,360.24,374.75,359.51,372.14,14342900,372.14
+2005-10-28,355.27,358.95,355.02,358.17,5903500,358.17
+2005-10-27,356.60,357.09,351.68,353.06,5134400,353.06
+2005-10-26,346.28,356.00,346.19,355.44,8907500,355.44
+2005-10-25,345.78,347.40,342.86,346.91,6878300,346.91
+2005-10-24,343.37,349.30,342.19,348.65,9431700,348.65
+2005-10-21,345.80,346.43,333.00,339.90,22892400,339.90
+2005-10-20,309.99,311.13,301.21,303.20,13911700,303.20
+2005-10-19,304.00,309.87,303.96,308.70,7010700,308.70
+2005-10-18,304.96,307.96,302.74,303.28,7077800,303.28
+2005-10-17,297.50,305.20,294.56,305.00,7566700,305.00
+2005-10-14,299.90,300.23,292.54,296.14,8519100,296.14
+2005-10-13,302.00,302.00,290.68,297.44,10567700,297.44
+2005-10-12,305.20,307.19,299.00,300.97,9306200,300.97
+2005-10-11,310.61,312.65,304.86,306.10,8542600,306.10
+2005-10-10,313.31,314.82,309.15,310.65,5572200,310.65
+2005-10-07,314.79,316.67,310.54,312.99,6770300,312.99
+2005-10-06,314.14,314.48,310.09,312.75,7993800,312.75
+2005-10-05,312.69,314.90,308.00,310.71,8328400,310.71
+2005-10-04,319.95,321.28,310.74,311.00,9144300,311.00
+2005-10-03,313.63,320.11,312.79,318.68,9160300,318.68
+2005-09-30,314.22,317.50,312.29,316.46,9151300,316.46
+2005-09-29,306.68,310.72,306.08,309.62,5613800,309.62
+2005-09-28,314.22,315.10,305.60,306.00,7997400,306.00
+2005-09-27,314.95,318.41,313.38,313.94,6873100,313.94
+2005-09-26,319.50,320.95,312.56,314.28,9894400,314.28
+2005-09-23,313.00,317.21,312.59,315.36,8483800,315.36
+2005-09-22,311.50,319.22,310.17,311.37,13006400,311.37
+2005-09-21,308.41,313.76,305.96,311.90,10119700,311.90
+2005-09-20,306.15,311.30,305.23,307.91,9351000,307.91
+2005-09-19,301.00,306.00,300.71,303.79,5761900,303.79
+2005-09-16,304.02,304.50,299.87,300.20,7579800,300.20
+2005-09-15,299.52,306.75,297.91,302.62,15466200,302.62
+2005-09-14,308.73,313.28,300.30,303.00,11275800,303.00
+2005-09-13,309.00,315.53,306.17,311.68,10299900,311.68
+2005-09-12,301.75,311.42,301.00,309.74,10386500,309.74
+2005-09-09,297.28,299.10,296.56,299.09,4390500,299.09
+2005-09-08,294.83,299.28,293.36,295.39,6613300,295.39
+2005-09-07,285.89,295.50,285.28,294.87,7499500,294.87
+2005-09-06,289.00,289.39,286.80,287.11,4212300,287.11
+2005-09-02,286.51,289.99,286.44,288.45,3434500,288.45
+2005-09-01,285.91,287.50,285.00,286.25,2742100,286.25
+2005-08-31,288.23,288.50,284.36,286.00,5034000,286.00
+2005-08-30,287.39,289.51,285.88,287.27,4792000,287.27
+2005-08-29,282.24,289.12,282.24,288.45,5903000,288.45
+2005-08-26,283.48,285.02,282.66,283.58,3755300,283.58
+2005-08-25,282.55,284.00,279.97,282.59,4376600,282.59
+2005-08-24,277.57,284.75,276.45,282.57,8593100,282.57
+2005-08-23,276.16,279.74,274.12,279.58,5821700,279.58
+2005-08-22,281.24,281.47,273.35,274.01,6813000,274.01
+2005-08-19,280.99,281.45,279.62,280.00,5542900,280.00
+2005-08-18,275.91,280.50,275.00,279.99,11872800,279.99
+2005-08-17,285.51,286.57,284.00,285.10,3883300,285.10
+2005-08-16,284.88,287.79,283.34,285.65,7109200,285.65
+2005-08-15,289.80,292.77,283.77,284.00,8174700,284.00
+2005-08-12,283.36,290.20,281.64,289.72,6585900,289.72
+2005-08-11,285.89,286.58,280.62,284.05,7514900,284.05
+2005-08-10,291.30,292.33,284.88,285.68,6879000,285.68
+2005-08-09,291.96,292.68,288.51,291.57,5779300,291.57
+2005-08-08,293.60,295.65,290.49,291.25,4481800,291.25
+2005-08-05,297.50,298.51,291.31,292.35,5939700,292.35
+2005-08-04,295.55,299.00,295.25,297.73,5236500,297.73
+2005-08-03,298.00,299.72,295.60,297.30,5930600,297.30
+2005-08-02,291.60,299.52,291.12,299.19,7290200,299.19
+2005-08-01,288.12,292.50,288.10,291.61,5662400,291.61
+2005-07-29,292.14,292.84,286.99,287.76,8363300,287.76
+2005-07-28,297.41,297.41,293.28,293.50,5925600,293.50
+2005-07-27,297.74,298.23,292.40,296.93,7217900,296.93
+2005-07-26,295.01,298.00,292.09,296.09,9816900,296.09
+2005-07-25,302.39,303.29,294.96,295.85,9658800,295.85
+2005-07-22,306.37,309.25,296.33,302.40,23386800,302.40
+2005-07-21,314.05,317.80,311.21,313.94,19789400,313.94
+2005-07-20,305.57,312.61,301.80,312.00,14310400,312.00
+2005-07-19,302.10,310.35,301.80,309.90,12621400,309.90
+2005-07-18,300.00,301.90,297.75,299.54,6207800,299.54
+2005-07-15,301.24,303.40,299.78,301.19,8438400,301.19
+2005-07-14,305.34,306.75,300.07,300.89,10667700,300.89
+2005-07-13,292.51,299.24,292.10,298.86,11437900,298.86
+2005-07-12,293.39,294.40,290.93,291.78,5864900,291.78
+2005-07-11,296.40,296.60,291.02,293.35,8390300,293.35
+2005-07-08,296.25,297.50,294.05,296.23,7457600,296.23
+2005-07-07,289.39,295.80,288.51,295.54,10672100,295.54
+2005-07-06,297.30,297.60,291.38,291.52,8000300,291.52
+2005-07-05,292.10,295.98,290.23,295.71,7494000,295.71
+2005-07-01,295.04,296.24,289.22,291.25,9227600,291.25
+2005-06-30,294.34,298.93,291.04,294.15,15094400,294.15
+2005-06-29,302.50,304.38,292.15,292.72,18298700,292.72
+2005-06-28,306.28,309.25,302.00,302.00,19036500,302.00
+2005-06-27,298.90,304.47,293.86,304.10,17802900,304.10
+2005-06-24,290.90,298.00,289.58,297.25,17771200,297.25
+2005-06-23,288.00,294.81,286.50,289.71,14056400,289.71
+2005-06-22,289.67,292.32,288.67,289.30,10474000,289.30
+2005-06-21,288.07,290.30,284.97,287.84,15132300,287.84
+2005-06-20,276.09,287.67,271.73,286.70,21024700,286.70
+2005-06-17,279.00,280.30,275.90,280.30,10434400,280.30
+2005-06-16,274.26,278.30,273.07,277.44,12462400,277.44
+2005-06-15,275.00,277.30,267.43,274.80,20883100,274.80
+2005-06-14,278.59,281.24,277.75,278.35,10091900,278.35
+2005-06-13,279.82,284.19,276.52,282.75,12803200,282.75
+2005-06-10,286.99,287.28,280.02,282.50,12696600,282.50
+2005-06-09,284.72,288.50,280.56,286.31,16441100,286.31
+2005-06-08,292.85,293.19,278.00,279.56,25700900,279.56
+2005-06-07,297.10,299.59,290.30,293.12,24323000,293.12
+2005-06-06,282.39,293.75,281.83,290.94,22525900,290.94
+2005-06-03,286.79,289.30,277.41,280.26,18782300,280.26
+2005-06-02,288.73,289.78,284.60,287.90,17974100,287.90
+2005-06-01,283.20,292.89,282.02,288.00,35191700,288.00
+2005-05-31,269.43,278.40,269.37,277.27,22236800,277.27
+2005-05-27,260.46,266.05,259.25,266.00,12184100,266.00
+2005-05-26,260.96,263.76,258.30,259.20,13546600,259.20
+2005-05-25,252.73,260.98,250.63,260.81,18057900,260.81
+2005-05-24,256.96,265.44,253.50,256.00,29043100,256.00
+2005-05-23,243.16,258.10,242.71,255.45,21388300,255.45
+2005-05-20,241.21,241.67,239.65,241.61,8163500,241.61
+2005-05-19,240.34,241.17,238.27,239.18,9716500,239.18
+2005-05-18,233.61,239.97,233.52,239.16,12312000,239.16
+2005-05-17,230.56,233.45,230.20,233.13,7808900,233.13
+2005-05-16,229.68,231.62,228.57,231.05,5681400,231.05
+2005-05-13,229.18,231.09,227.32,229.24,7415500,229.24
+2005-05-12,230.81,232.23,228.20,228.72,8948200,228.72
+2005-05-11,228.97,231.98,227.93,231.29,11478800,231.29
+2005-05-10,225.47,227.80,224.72,227.80,6345800,227.80
+2005-05-09,228.00,228.50,225.43,226.02,5536800,226.02
+2005-05-06,228.40,229.25,226.47,228.02,6763900,228.02
+2005-05-05,228.62,228.62,225.88,226.98,7509600,226.98
+2005-05-04,227.23,229.88,227.00,228.50,12083500,228.50
+2005-05-03,221.85,228.15,221.32,226.19,17780200,226.19
+2005-05-02,222.05,223.70,220.21,222.29,9767400,222.29
+2005-04-29,221.91,222.25,217.82,220.00,9170200,220.00
+2005-04-28,219.50,222.08,217.71,219.45,8682800,219.45
+2005-04-27,217.99,220.85,216.74,219.78,10264800,219.78
+2005-04-26,220.22,222.00,218.29,218.75,17272000,218.75
+2005-04-25,217.82,224.74,217.52,223.53,19840000,223.53
+2005-04-22,222.90,224.00,214.26,215.81,33205100,215.81
+2005-04-21,200.42,205.00,199.32,204.22,17751900,204.22
+2005-04-20,198.58,200.50,195.91,198.10,15451500,198.10
+2005-04-19,189.33,192.00,188.03,191.40,8430000,191.40
+2005-04-18,184.58,187.88,183.49,186.97,6550300,186.97
+2005-04-15,190.10,190.34,184.66,185.00,11577400,185.00
+2005-04-14,193.27,194.36,190.10,191.45,6152700,191.45
+2005-04-13,193.47,194.32,189.73,192.93,6555800,192.93
+2005-04-12,193.00,194.42,189.41,193.96,7319600,193.96
+2005-04-11,193.09,194.80,192.32,193.23,5410500,193.23
+2005-04-08,193.69,195.10,191.45,192.05,5116600,192.05
+2005-04-07,188.78,194.62,188.64,193.76,9692200,193.76
+2005-04-06,189.24,189.65,187.58,189.22,5252600,189.22
+2005-04-05,187.73,190.26,187.57,188.57,8736700,188.57
+2005-04-04,179.95,185.32,179.84,185.29,8076400,185.29
+2005-04-01,181.76,182.95,179.99,180.04,6182000,180.04
+2005-03-31,177.95,181.39,177.64,180.51,6768600,180.51
+2005-03-30,180.64,181.45,179.60,180.45,6236100,180.45
+2005-03-29,181.05,183.28,178.07,179.57,6473000,179.57
+2005-03-28,181.68,184.80,180.95,181.42,8738000,181.42
+2005-03-24,180.70,180.86,179.20,179.25,3705200,179.25
+2005-03-23,177.97,180.24,177.97,178.98,4845000,178.98
+2005-03-22,181.18,181.94,177.85,178.60,5631700,178.60
+2005-03-21,179.27,182.17,177.25,180.88,7483700,180.88
+2005-03-18,178.81,180.40,178.31,180.04,7090000,180.04
+2005-03-17,177.13,179.64,175.80,179.29,8260600,179.29
+2005-03-16,176.70,178.61,175.01,175.60,7106300,175.60
+2005-03-15,175.30,180.00,174.21,178.61,10422100,178.61
+2005-03-14,178.33,178.40,172.57,174.99,11146600,174.99
+2005-03-11,180.44,180.95,177.15,177.80,8028300,177.80
+2005-03-10,181.01,181.20,177.40,179.98,10960500,179.98
+2005-03-09,184.21,184.65,180.16,181.35,11360400,181.35
+2005-03-08,189.10,189.85,184.97,185.20,8046100,185.20
+2005-03-07,187.78,189.60,187.03,188.81,8667400,188.81
+2005-03-04,186.70,187.25,185.07,185.90,6774100,185.90
+2005-03-03,186.13,187.75,184.31,187.01,7608600,187.01
+2005-03-02,185.95,187.67,184.36,185.18,7285500,185.18
+2005-03-01,189.29,189.75,182.00,186.06,9311200,186.06
+2005-02-28,186.00,189.87,185.85,187.99,7818400,187.99
+2005-02-25,189.15,189.92,185.51,185.87,9973500,185.87
+2005-02-24,183.37,189.85,182.23,188.89,25814300,188.89
+2005-02-23,193.30,194.48,188.66,193.95,15586000,193.95
+2005-02-22,196.50,198.90,190.39,191.37,13483700,191.37
+2005-02-18,198.51,198.84,196.66,197.95,8485900,197.95
+2005-02-17,197.83,199.75,196.81,197.90,10414400,197.90
+2005-02-16,194.70,199.33,194.30,198.41,16532300,198.41
+2005-02-15,193.60,199.84,193.08,195.23,25782800,195.23
+2005-02-14,182.85,193.08,181.00,192.99,38562200,192.99
+2005-02-11,186.66,192.32,186.07,187.40,13116000,187.40
+2005-02-10,191.97,192.21,185.25,187.98,18982700,187.98
+2005-02-09,200.76,201.60,189.46,191.58,17171500,191.58
+2005-02-08,196.96,200.02,194.53,198.64,11480000,198.64
+2005-02-07,205.26,206.40,195.51,196.03,12960400,196.03
+2005-02-04,206.47,207.75,202.60,204.36,14819300,204.36
+2005-02-03,205.99,213.37,205.81,210.86,12988100,210.86
+2005-02-02,215.55,216.80,203.66,205.96,32799300,205.96
+2005-02-01,194.38,196.66,190.63,191.90,18839000,191.90
+2005-01-31,193.69,196.36,191.72,195.62,9596700,195.62
+2005-01-28,190.02,194.70,186.34,190.34,12208200,190.34
+2005-01-27,188.76,188.86,185.20,188.08,6627400,188.08
+2005-01-26,179.27,189.41,179.15,189.24,12307900,189.24
+2005-01-25,181.94,182.24,176.29,177.12,10659200,177.12
+2005-01-24,188.69,189.33,180.32,180.72,14022700,180.72
+2005-01-21,194.54,195.36,188.12,188.28,9258400,188.28
+2005-01-20,192.50,196.25,192.00,193.92,9001600,193.92
+2005-01-19,204.65,205.30,196.71,197.30,11257700,197.30
+2005-01-18,200.97,205.02,198.66,203.90,13172600,203.90
+2005-01-14,196.00,200.01,194.13,199.97,9640300,199.97
+2005-01-13,195.38,197.39,194.05,195.33,6849400,195.33
+2005-01-12,194.33,195.93,190.50,195.38,8177800,195.38
+2005-01-11,195.62,197.71,193.18,193.54,6958700,193.54
+2005-01-10,194.50,198.10,191.83,195.06,7539600,195.06
+2005-01-07,190.64,194.25,188.78,193.85,9662900,193.85
+2005-01-06,195.08,195.90,187.72,188.55,10387100,188.55
+2005-01-05,193.45,196.90,192.23,193.51,8236600,193.51
+2005-01-04,201.40,202.93,193.48,194.50,13755900,194.50
+2005-01-03,197.40,203.64,195.46,202.71,15844200,202.71
diff --git a/dojox/charting/tests/BidiSupport/data/msft_prices.csv b/dojox/charting/tests/BidiSupport/data/msft_prices.csv
new file mode 100644
index 0000000..a0c1e90
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/data/msft_prices.csv
@@ -0,0 +1,796 @@
+Date,Open,High,Low,Close,Volume,Adj Close
+2008-02-29,27.69,27.83,27.02,27.20,117394000,27.20
+2008-02-28,28.02,28.27,27.80,27.93,83002900,27.93
+2008-02-27,28.19,28.68,28.10,28.26,75187200,28.26
+2008-02-26,27.74,28.86,27.67,28.38,108923500,28.38
+2008-02-25,27.65,28.24,27.48,27.84,109945200,27.84
+2008-02-22,28.24,28.39,27.20,27.68,125705400,27.68
+2008-02-21,28.62,28.96,27.96,28.10,98776500,28.10
+2008-02-20,28.15,28.26,27.92,28.22,92830000,28.22
+2008-02-19,28.80,28.84,28.07,28.17,68261200,28.17
+2008-02-15,28.31,28.64,28.25,28.42,68166100,28.31
+2008-02-14,28.88,29.04,28.46,28.50,68191600,28.39
+2008-02-13,28.62,29.05,28.53,28.96,88986200,28.85
+2008-02-12,28.43,28.62,28.11,28.34,84365900,28.23
+2008-02-11,28.52,28.61,27.91,28.21,156814100,28.10
+2008-02-08,28.29,29.08,28.24,28.56,124872000,28.45
+2008-02-07,28.34,28.78,27.90,28.12,164964900,28.01
+2008-02-06,29.28,29.35,28.29,28.52,138315600,28.41
+2008-02-05,29.91,29.94,28.89,29.07,137534100,28.96
+2008-02-04,30.49,30.72,30.11,30.19,119998600,30.07
+2008-02-01,31.06,33.25,30.25,30.45,291138900,30.33
+2008-01-31,31.91,32.74,31.72,32.60,103642200,32.47
+2008-01-30,32.56,32.80,32.05,32.20,106432600,32.08
+2008-01-29,32.85,32.89,32.35,32.60,68023000,32.47
+2008-01-28,33.02,33.10,32.42,32.72,81019000,32.59
+2008-01-25,34.90,35.00,32.87,32.94,196992300,32.81
+2008-01-24,32.35,33.36,32.12,33.25,155640400,33.12
+2008-01-23,31.48,32.05,31.04,31.93,137597400,31.81
+2008-01-22,31.54,32.53,31.50,31.96,108521400,31.84
+2008-01-18,33.16,34.00,32.97,33.01,117062000,32.88
+2008-01-17,33.54,33.80,32.97,33.11,94247800,32.98
+2008-01-16,33.42,33.65,32.51,33.23,120778500,33.10
+2008-01-15,34.03,34.38,34.00,34.00,61606200,33.87
+2008-01-14,34.46,34.57,34.08,34.39,52792200,34.26
+2008-01-11,34.14,34.24,33.72,33.91,55187900,33.78
+2008-01-10,34.35,34.50,33.78,34.33,72446000,34.20
+2008-01-09,33.36,34.54,33.35,34.44,74305500,34.31
+2008-01-08,34.71,34.71,33.40,33.45,79148300,33.32
+2008-01-07,34.55,34.80,34.25,34.61,80164300,34.48
+2008-01-04,35.19,35.20,34.09,34.38,72090800,34.25
+2008-01-03,35.22,35.65,34.86,35.37,49599600,35.23
+2008-01-02,35.79,35.96,35.00,35.22,63004200,35.08
+2007-12-31,35.90,35.99,35.52,35.60,35229700,35.46
+2007-12-28,36.10,36.23,35.67,36.12,33447200,35.98
+2007-12-27,36.35,36.55,35.94,35.97,33311100,35.83
+2007-12-26,36.41,36.64,36.26,36.61,30252400,36.47
+2007-12-24,36.13,36.72,36.05,36.58,29622600,36.44
+2007-12-21,35.90,36.06,35.75,36.06,83240500,35.92
+2007-12-20,35.29,35.79,35.08,35.52,59345000,35.38
+2007-12-19,34.69,35.14,34.38,34.79,58469100,34.66
+2007-12-18,34.64,35.00,34.21,34.74,52791800,34.61
+2007-12-17,35.03,35.13,34.36,34.39,58121200,34.26
+2007-12-14,35.05,35.84,35.01,35.31,71126200,35.17
+2007-12-13,34.48,35.45,34.28,35.22,73913200,35.08
+2007-12-12,34.61,35.09,33.93,34.47,63345400,34.34
+2007-12-11,34.73,34.99,33.93,34.10,55070700,33.97
+2007-12-10,34.64,34.95,34.47,34.76,36083500,34.63
+2007-12-07,34.61,34.70,34.22,34.53,40771000,34.40
+2007-12-06,34.26,34.61,33.87,34.55,49209700,34.42
+2007-12-05,33.14,34.52,33.03,34.15,84894700,34.02
+2007-12-04,32.74,33.24,32.63,32.77,54801500,32.64
+2007-12-03,33.50,33.64,32.68,32.92,61770600,32.79
+2007-11-30,33.92,34.12,33.19,33.60,71027800,33.47
+2007-11-29,33.58,33.93,33.31,33.59,53633600,33.46
+2007-11-28,33.38,33.89,32.90,33.70,88585000,33.57
+2007-11-27,33.27,33.60,32.68,33.06,84178400,32.93
+2007-11-26,34.09,34.37,32.93,32.97,80335000,32.84
+2007-11-23,34.36,34.44,33.71,34.11,33467200,33.98
+2007-11-21,34.40,34.73,34.18,34.23,89518700,34.10
+2007-11-20,34.23,34.97,34.10,34.58,100009400,34.45
+2007-11-19,33.96,34.24,33.87,33.96,63000300,33.83
+2007-11-16,33.86,34.26,33.71,34.09,71113800,33.96
+2007-11-15,33.76,34.10,33.55,33.76,63111200,33.63
+2007-11-14,34.62,34.75,33.75,33.93,83840100,33.80
+2007-11-13,33.54,34.67,33.38,34.46,104261100,34.33
+2007-11-12,33.32,33.71,33.02,33.38,84719000,33.14
+2007-11-09,34.18,34.54,33.65,33.73,125111400,33.49
+2007-11-08,35.60,35.90,34.40,34.74,133742400,34.49
+2007-11-07,36.04,36.16,35.45,35.52,74873600,35.27
+2007-11-06,36.59,36.66,35.87,36.41,100966700,36.15
+2007-11-05,36.76,37.10,36.63,36.73,75485400,36.47
+2007-11-02,37.22,37.50,36.42,37.06,96389800,36.79
+2007-11-01,36.53,37.49,36.36,37.06,152078800,36.79
+2007-10-31,35.52,37.00,35.51,36.81,185635800,36.55
+2007-10-30,34.37,35.59,34.35,35.57,107297300,35.32
+2007-10-29,34.85,35.29,34.45,34.57,114655600,34.32
+2007-10-26,36.01,36.03,34.56,35.03,287270900,34.78
+2007-10-25,31.57,32.22,31.49,31.99,169588700,31.76
+2007-10-24,30.85,31.30,30.50,31.25,77979200,31.03
+2007-10-23,30.71,31.12,30.71,30.90,49956200,30.68
+2007-10-22,30.12,30.70,30.12,30.51,58785100,30.29
+2007-10-19,31.09,31.09,30.11,30.17,75200200,29.95
+2007-10-18,31.22,31.23,30.63,31.16,49208600,30.94
+2007-10-17,30.75,31.23,30.65,31.08,86092400,30.86
+2007-10-16,30.24,30.58,30.23,30.32,56286200,30.10
+2007-10-15,30.10,30.33,30.00,30.04,47150500,29.83
+2007-10-12,30.03,30.40,29.95,30.17,31121100,29.95
+2007-10-11,30.30,30.63,29.79,29.91,50788400,29.70
+2007-10-10,30.04,30.37,30.03,30.23,32251500,30.01
+2007-10-09,30.03,30.39,30.00,30.10,63603100,29.88
+2007-10-08,29.66,29.85,29.60,29.84,30265400,29.63
+2007-10-05,29.89,29.99,29.73,29.84,45012300,29.63
+2007-10-04,29.56,29.77,29.44,29.71,37868000,29.50
+2007-10-03,29.71,29.85,29.29,29.45,37633900,29.24
+2007-10-02,29.70,29.85,29.57,29.70,33700900,29.49
+2007-10-01,29.46,29.79,29.41,29.77,43875100,29.56
+2007-09-28,29.49,29.69,29.23,29.46,45819100,29.25
+2007-09-27,29.70,29.72,29.44,29.49,43407100,29.28
+2007-09-26,29.68,29.85,29.48,29.50,60337000,29.29
+2007-09-25,29.14,29.56,29.11,29.56,75621000,29.35
+2007-09-24,28.81,29.61,28.80,29.08,104459800,28.87
+2007-09-21,28.69,28.81,28.44,28.65,135636100,28.45
+2007-09-20,28.48,28.58,28.34,28.42,67168900,28.22
+2007-09-19,28.87,28.91,28.30,28.67,94242200,28.46
+2007-09-18,28.70,28.97,28.27,28.93,77462400,28.72
+2007-09-17,28.79,28.88,28.62,28.73,39536500,28.52
+2007-09-14,28.98,29.11,28.88,29.04,33496600,28.83
+2007-09-13,29.12,29.26,28.96,29.16,35288600,28.95
+2007-09-12,28.81,29.17,28.80,28.93,42364700,28.72
+2007-09-11,28.63,28.95,28.58,28.93,34380800,28.72
+2007-09-10,28.67,28.75,28.41,28.48,37247600,28.28
+2007-09-07,28.62,28.83,28.32,28.44,52160900,28.24
+2007-09-06,28.56,29.01,28.55,28.91,45430800,28.70
+2007-09-05,28.65,28.73,28.42,28.48,47669800,28.28
+2007-09-04,28.50,29.10,28.48,28.81,45689600,28.60
+2007-08-31,28.70,28.92,28.36,28.73,42511900,28.52
+2007-08-30,28.42,28.93,28.32,28.45,33690700,28.25
+2007-08-29,28.13,28.61,27.82,28.59,45753700,28.39
+2007-08-28,28.30,28.49,27.91,27.93,43924400,27.73
+2007-08-27,28.61,28.77,28.40,28.49,32789500,28.29
+2007-08-24,28.21,28.84,28.07,28.81,45158900,28.60
+2007-08-23,28.28,28.33,28.10,28.30,33886600,28.10
+2007-08-22,28.27,28.32,28.01,28.22,44763500,28.02
+2007-08-21,28.10,28.32,27.87,28.07,50786200,27.87
+2007-08-20,28.18,28.49,28.08,28.26,49952000,28.06
+2007-08-17,28.09,28.25,27.82,28.25,76747700,28.05
+2007-08-16,27.88,28.35,27.51,27.81,81447400,27.61
+2007-08-15,28.24,28.99,28.05,28.10,48117700,27.90
+2007-08-14,28.77,28.89,28.20,28.27,42944100,28.07
+2007-08-13,28.94,28.99,28.44,28.63,55492300,28.33
+2007-08-10,28.90,29.05,28.26,28.71,76576200,28.41
+2007-08-09,29.64,30.10,28.92,29.30,72964500,28.99
+2007-08-08,29.72,30.01,29.21,30.00,52898600,29.68
+2007-08-07,29.33,29.79,29.05,29.55,49163000,29.24
+2007-08-06,29.05,29.54,28.75,29.54,59530500,29.23
+2007-08-03,29.45,29.78,28.90,28.96,61535500,28.65
+2007-08-02,29.19,29.79,29.02,29.52,47938300,29.21
+2007-08-01,28.95,29.55,28.82,29.30,80006300,28.99
+2007-07-31,29.71,29.72,28.98,28.99,66554000,28.68
+2007-07-30,29.41,29.49,28.95,29.40,67499600,29.09
+2007-07-27,29.93,30.00,29.36,29.39,69214600,29.08
+2007-07-26,30.24,30.53,29.51,29.98,87025300,29.66
+2007-07-25,30.99,31.30,30.37,30.71,54950100,30.38
+2007-07-24,31.01,31.48,30.71,30.80,59729300,30.47
+2007-07-23,31.36,31.52,31.12,31.19,48910600,30.86
+2007-07-20,31.15,31.20,30.79,31.16,98292600,30.83
+2007-07-19,31.05,31.84,30.93,31.51,121159300,31.18
+2007-07-18,30.51,30.97,30.50,30.92,64414400,30.59
+2007-07-17,30.02,30.88,30.01,30.78,77539600,30.45
+2007-07-16,29.76,30.24,29.72,30.03,48023200,29.71
+2007-07-13,29.94,30.02,29.66,29.82,42173000,29.50
+2007-07-12,29.56,30.11,29.44,30.07,54302400,29.75
+2007-07-11,29.24,29.65,29.21,29.49,48017000,29.18
+2007-07-10,29.70,29.99,29.18,29.33,66013500,29.02
+2007-07-09,29.86,29.95,29.81,29.87,33831400,29.55
+2007-07-06,29.91,30.04,29.66,29.97,57541000,29.65
+2007-07-05,30.05,30.22,29.83,29.99,47838500,29.67
+2007-07-03,29.79,30.22,29.78,30.02,35202600,29.70
+2007-07-02,29.67,29.80,29.49,29.74,47316000,29.42
+2007-06-29,29.87,29.93,29.04,29.47,71193900,29.16
+2007-06-28,29.86,29.97,29.68,29.83,46055200,29.51
+2007-06-27,29.36,29.95,29.36,29.87,53468600,29.55
+2007-06-26,29.55,29.80,29.50,29.52,48340300,29.21
+2007-06-25,29.47,29.77,29.38,29.49,53905800,29.18
+2007-06-22,30.00,30.10,29.45,29.49,86219900,29.18
+2007-06-21,29.98,30.30,29.91,30.22,56564800,29.90
+2007-06-20,30.44,30.51,29.96,30.01,46861600,29.69
+2007-06-19,30.48,30.66,30.38,30.46,46802600,30.14
+2007-06-18,30.69,30.72,30.42,30.51,45412600,30.19
+2007-06-15,30.86,30.88,30.43,30.49,100933000,30.17
+2007-06-14,30.35,30.71,30.30,30.52,59065700,30.20
+2007-06-13,29.97,30.41,29.85,30.39,64435600,30.07
+2007-06-12,29.96,30.24,29.77,29.85,56981800,29.53
+2007-06-11,29.94,30.25,29.93,30.02,48467400,29.70
+2007-06-08,29.58,30.06,29.41,30.05,61346200,29.73
+2007-06-07,30.02,30.29,29.59,29.62,71971400,29.31
+2007-06-06,30.37,30.53,30.25,30.29,38217500,29.97
+2007-06-05,30.62,30.63,30.33,30.58,44265000,30.26
+2007-06-04,30.42,30.76,30.40,30.72,41434500,30.39
+2007-06-01,30.79,30.90,30.55,30.59,39469400,30.27
+2007-05-31,31.12,31.16,30.61,30.69,85290500,30.36
+2007-05-30,30.55,31.13,30.51,31.11,57376800,30.78
+2007-05-29,30.49,30.83,30.39,30.79,42373100,30.46
+2007-05-25,30.28,30.66,30.18,30.48,47726500,30.16
+2007-05-24,30.54,30.80,29.96,30.17,64046400,29.85
+2007-05-23,30.84,30.84,30.57,30.58,46322500,30.26
+2007-05-22,30.90,30.93,30.66,30.69,39999500,30.36
+2007-05-21,30.73,31.16,30.73,31.05,41836400,30.72
+2007-05-18,30.97,30.99,30.58,30.83,58453000,30.50
+2007-05-17,31.03,31.14,30.96,30.98,41045600,30.65
+2007-05-16,31.00,31.09,30.81,31.07,45833600,30.74
+2007-05-15,30.90,31.09,30.84,30.90,75013900,30.57
+2007-05-14,30.84,30.99,30.81,30.97,70188500,30.54
+2007-05-11,30.57,30.98,30.55,30.89,43425300,30.46
+2007-05-10,30.68,30.93,30.53,30.58,55398600,30.16
+2007-05-09,30.70,30.93,30.57,30.78,51735000,30.35
+2007-05-08,30.68,30.94,30.58,30.75,60551700,30.33
+2007-05-07,30.52,30.76,30.48,30.71,59889100,30.29
+2007-05-04,30.68,30.70,30.29,30.56,104385900,30.14
+2007-05-03,30.60,31.00,30.53,30.97,82036800,30.54
+2007-05-02,30.39,30.69,30.30,30.61,80686700,30.19
+2007-05-01,29.94,30.42,29.90,30.40,73539300,29.98
+2007-04-30,30.13,30.37,29.94,29.94,67788800,29.53
+2007-04-27,30.17,30.74,30.00,30.12,128298800,29.70
+2007-04-26,29.09,29.35,28.91,29.10,68760300,28.70
+2007-04-25,28.86,29.00,28.69,28.99,39475000,28.59
+2007-04-24,28.79,28.96,28.59,28.79,34236700,28.39
+2007-04-23,28.96,28.99,28.67,28.78,41739100,28.38
+2007-04-20,28.98,29.10,28.70,29.02,60311500,28.62
+2007-04-19,28.34,28.89,28.26,28.69,43648800,28.29
+2007-04-18,28.61,28.67,28.36,28.60,41778400,28.20
+2007-04-17,28.63,28.89,28.56,28.85,33170200,28.45
+2007-04-16,28.60,28.75,28.21,28.73,30740100,28.33
+2007-04-13,28.43,28.70,28.10,28.61,36002900,28.21
+2007-04-12,28.06,28.62,28.04,28.54,43762100,28.15
+2007-04-11,28.30,28.57,27.99,28.11,44050200,27.72
+2007-04-10,28.50,28.64,28.22,28.40,38643100,28.01
+2007-04-09,28.58,28.72,28.39,28.57,31384600,28.18
+2007-04-05,28.32,28.65,28.30,28.55,30131200,28.16
+2007-04-04,28.01,28.78,27.90,28.50,63244200,28.11
+2007-04-03,27.86,28.06,27.75,27.87,39821300,27.48
+2007-04-02,27.89,27.93,27.56,27.74,41977600,27.36
+2007-03-30,27.75,27.95,27.50,27.87,47061000,27.48
+2007-03-29,27.84,27.85,27.49,27.75,42629900,27.37
+2007-03-28,27.58,28.00,27.40,27.64,46947000,27.26
+2007-03-27,28.04,28.16,27.65,27.72,58979800,27.34
+2007-03-26,27.94,28.22,27.70,28.22,47491500,27.83
+2007-03-23,28.22,28.27,27.80,28.02,50519800,27.63
+2007-03-22,28.52,28.55,28.01,28.27,47934900,27.88
+2007-03-21,27.90,28.52,27.56,28.52,72808200,28.13
+2007-03-20,27.93,28.16,27.76,27.84,47902400,27.46
+2007-03-19,27.34,27.83,27.20,27.83,49412000,27.45
+2007-03-16,27.35,27.48,27.20,27.33,65055300,26.95
+2007-03-15,27.32,27.47,27.20,27.28,51757100,26.90
+2007-03-14,26.82,27.40,26.73,27.40,75730300,27.02
+2007-03-13,27.25,27.40,26.71,26.72,75169500,26.35
+2007-03-12,27.18,27.48,27.13,27.44,36516400,27.06
+2007-03-09,27.42,27.48,27.03,27.29,80125000,26.91
+2007-03-08,27.72,27.85,26.60,27.32,72175200,26.94
+2007-03-07,27.76,27.90,27.55,27.61,52044700,27.23
+2007-03-06,27.80,27.94,27.65,27.83,49361800,27.45
+2007-03-05,27.49,27.91,27.41,27.55,56454300,27.17
+2007-03-02,28.02,28.16,27.76,27.76,63254700,27.38
+2007-03-01,27.82,28.33,27.73,28.09,80175700,27.70
+2007-02-28,27.95,28.25,27.92,28.17,86333300,27.78
+2007-02-27,28.71,28.97,27.79,27.87,87143300,27.48
+2007-02-26,28.96,29.09,28.82,29.07,63481900,28.67
+2007-02-23,29.22,29.28,28.89,28.90,63787100,28.50
+2007-02-22,29.31,29.54,29.16,29.39,57754400,28.98
+2007-02-21,28.75,29.39,28.74,29.35,68604900,28.94
+2007-02-20,28.63,28.86,28.47,28.83,53978200,28.43
+2007-02-16,28.91,28.94,28.65,28.74,109340300,28.34
+2007-02-15,29.58,29.65,29.22,29.46,63858100,29.05
+2007-02-14,29.17,29.69,29.15,29.40,55588600,28.99
+2007-02-13,29.04,29.20,28.96,29.01,50348100,28.61
+2007-02-12,28.89,29.09,28.83,28.94,52774400,28.44
+2007-02-09,29.35,29.40,28.93,28.98,69823100,28.48
+2007-02-08,29.24,29.80,29.20,29.26,48749000,28.76
+2007-02-07,29.64,29.70,29.25,29.37,65145500,28.86
+2007-02-06,29.59,29.75,29.22,29.51,79281100,29.00
+2007-02-05,29.97,30.02,29.41,29.61,99102100,29.10
+2007-02-02,30.82,30.84,30.13,30.19,60401700,29.67
+2007-02-01,30.84,30.94,30.37,30.56,55355800,30.03
+2007-01-31,30.41,31.10,30.35,30.86,73968400,30.33
+2007-01-30,30.57,30.64,30.14,30.48,61900400,29.96
+2007-01-29,30.65,30.78,30.34,30.53,57605900,30.00
+2007-01-26,31.22,31.23,30.60,30.60,96103700,30.07
+2007-01-25,31.08,31.48,30.45,30.45,97378700,29.93
+2007-01-24,30.78,31.30,30.65,31.09,58527800,30.55
+2007-01-23,30.63,30.96,30.52,30.74,49171200,30.21
+2007-01-22,31.06,31.12,30.51,30.72,56143900,30.19
+2007-01-19,30.73,31.11,30.69,31.11,75826900,30.57
+2007-01-18,31.15,31.37,30.80,31.00,56364300,30.47
+2007-01-17,31.26,31.44,31.01,31.10,58519600,30.56
+2007-01-16,31.26,31.45,31.03,31.16,62379600,30.62
+2007-01-12,30.65,31.39,30.64,31.21,103972500,30.67
+2007-01-11,29.76,30.75,29.65,30.70,99464300,30.17
+2007-01-10,29.80,29.89,29.43,29.66,55017400,29.15
+2007-01-09,30.00,30.18,29.73,29.96,44636600,29.44
+2007-01-08,29.65,30.10,29.53,29.93,50220200,29.41
+2007-01-05,29.63,29.75,29.45,29.64,44607200,29.13
+2007-01-04,29.70,29.97,29.44,29.81,45774500,29.30
+2007-01-03,29.91,30.25,29.40,29.86,76935100,29.35
+2006-12-29,29.86,30.15,29.83,29.86,41739800,29.35
+2006-12-28,29.86,30.03,29.81,29.98,26690600,29.46
+2006-12-27,29.99,30.13,29.91,30.02,31248400,29.50
+2006-12-26,29.53,30.00,29.40,29.99,37098300,29.47
+2006-12-22,29.83,29.86,29.62,29.64,37971700,29.13
+2006-12-21,30.13,30.14,29.89,29.98,32270500,29.46
+2006-12-20,29.99,30.24,29.97,30.09,31202100,29.57
+2006-12-19,29.71,30.17,29.53,29.99,53822100,29.47
+2006-12-18,30.19,30.26,29.78,29.89,56986800,29.38
+2006-12-15,30.14,30.23,30.03,30.19,102783700,29.67
+2006-12-14,29.54,30.08,29.52,30.07,85866500,29.55
+2006-12-13,29.60,29.60,29.32,29.55,46002500,29.04
+2006-12-12,29.56,29.63,29.22,29.43,68529400,28.92
+2006-12-11,29.19,29.75,29.11,29.54,107712000,29.03
+2006-12-08,28.82,29.40,28.80,29.40,108854900,28.89
+2006-12-07,28.96,29.07,28.81,28.85,46831100,28.35
+2006-12-06,29.10,29.13,28.87,28.99,48564100,28.49
+2006-12-05,29.36,29.40,29.03,29.13,45606000,28.63
+2006-12-04,29.23,29.52,29.17,29.33,55123400,28.82
+2006-12-01,29.23,29.30,28.90,29.12,72257000,28.62
+2006-11-30,29.42,29.57,29.33,29.36,53297400,28.85
+2006-11-29,29.44,29.78,29.43,29.57,58775100,29.06
+2006-11-28,29.34,29.42,29.13,29.39,52602300,28.88
+2006-11-27,29.69,29.74,29.33,29.48,72722100,28.97
+2006-11-24,29.66,29.84,29.64,29.76,20456700,29.25
+2006-11-22,29.97,30.00,29.82,29.92,43907200,29.40
+2006-11-21,29.91,30.00,29.79,29.92,66446600,29.40
+2006-11-20,29.52,30.00,29.50,29.89,85703800,29.38
+2006-11-17,29.31,29.54,29.28,29.40,49356700,28.89
+2006-11-16,29.14,29.64,29.13,29.47,64328500,28.96
+2006-11-15,29.13,29.36,29.11,29.12,63943200,28.62
+2006-11-14,29.28,29.42,29.07,29.23,63012500,28.73
+2006-11-13,29.19,29.46,29.16,29.35,47271800,28.75
+2006-11-10,29.17,29.29,29.15,29.24,37855100,28.64
+2006-11-09,29.11,29.40,29.00,29.26,89407500,28.66
+2006-11-08,28.78,29.23,28.66,28.98,77403300,28.38
+2006-11-07,28.86,29.07,28.80,28.95,56511200,28.35
+2006-11-06,28.77,29.05,28.76,28.84,60446200,28.25
+2006-11-03,28.85,28.93,28.61,28.73,41124500,28.14
+2006-11-02,28.71,28.86,28.58,28.77,58674400,28.18
+2006-11-01,28.78,28.99,28.70,28.81,75895900,28.22
+2006-10-31,28.66,28.85,28.56,28.71,61861700,28.12
+2006-10-30,28.35,28.84,28.32,28.53,47296800,27.94
+2006-10-27,28.49,28.79,28.25,28.34,89060100,27.76
+2006-10-26,28.33,28.41,28.04,28.35,69964200,27.77
+2006-10-25,28.28,28.46,28.14,28.31,40717100,27.73
+2006-10-24,28.43,28.43,28.13,28.28,61409600,27.70
+2006-10-23,28.30,28.69,28.18,28.45,48525000,27.86
+2006-10-20,28.48,28.49,28.17,28.43,48887800,27.85
+2006-10-19,28.35,28.45,28.12,28.29,44730800,27.71
+2006-10-18,28.50,28.70,28.26,28.52,40630800,27.93
+2006-10-17,28.24,28.51,28.17,28.44,40122600,27.85
+2006-10-16,28.48,28.60,28.33,28.45,49744800,27.86
+2006-10-13,28.34,28.69,28.31,28.37,129751900,27.79
+2006-10-12,27.58,28.29,27.54,28.22,120174900,27.64
+2006-10-11,27.46,27.67,27.42,27.54,37219600,26.97
+2006-10-10,27.69,27.75,27.44,27.69,34598500,27.12
+2006-10-09,27.80,27.93,27.62,27.72,33366300,27.15
+2006-10-06,27.76,28.00,27.65,27.87,36452200,27.30
+2006-10-05,27.92,28.11,27.78,27.92,81967200,27.35
+2006-10-04,27.39,27.96,27.37,27.94,82191200,27.37
+2006-10-03,27.37,27.48,27.21,27.37,39386200,26.81
+2006-10-02,27.32,27.49,27.15,27.36,52908100,26.80
+2006-09-29,27.35,27.42,27.21,27.35,34283500,26.79
+2006-09-28,27.47,27.52,27.26,27.40,44179700,26.84
+2006-09-27,27.18,27.47,27.12,27.44,66233900,26.88
+2006-09-26,26.91,27.32,26.88,27.20,54766500,26.64
+2006-09-25,26.81,27.19,26.79,26.95,67903900,26.40
+2006-09-22,26.83,26.85,26.48,26.66,47712500,26.11
+2006-09-21,27.24,27.25,26.85,26.90,58495100,26.35
+2006-09-20,27.01,27.23,26.99,27.18,71676400,26.62
+2006-09-19,26.74,26.94,26.72,26.86,43039100,26.31
+2006-09-18,26.74,27.04,26.67,26.79,49135000,26.24
+2006-09-15,26.58,26.94,26.49,26.85,126057700,26.30
+2006-09-14,25.99,26.50,25.98,26.33,74324500,25.79
+2006-09-13,25.82,26.10,25.82,25.98,37706700,25.45
+2006-09-12,25.90,25.98,25.72,25.93,52248800,25.40
+2006-09-11,25.43,25.95,25.42,25.91,55608200,25.38
+2006-09-08,25.53,25.79,25.46,25.60,36866800,25.07
+2006-09-07,25.48,25.70,25.39,25.43,51266900,24.91
+2006-09-06,25.51,25.72,25.51,25.61,50160400,25.08
+2006-09-05,25.69,25.96,25.56,25.61,44222400,25.08
+2006-09-01,25.89,25.97,25.64,25.84,31594600,25.31
+2006-08-31,25.87,25.98,25.68,25.70,26380500,25.17
+2006-08-30,25.85,25.89,25.64,25.80,30283100,25.27
+2006-08-29,25.92,25.98,25.63,25.84,42711200,25.31
+2006-08-28,25.84,26.00,25.69,25.95,34190900,25.42
+2006-08-25,25.71,26.00,25.69,25.85,33115900,25.32
+2006-08-24,25.82,25.86,25.50,25.74,35933300,25.21
+2006-08-23,25.65,25.95,25.52,25.67,44648500,25.14
+2006-08-22,26.01,26.25,25.62,25.62,89312400,25.09
+2006-08-21,25.66,26.13,25.56,26.12,88398300,25.58
+2006-08-18,25.05,25.80,24.98,25.79,128414800,25.26
+2006-08-17,24.70,24.75,24.61,24.70,45674800,24.19
+2006-08-16,24.61,24.73,24.47,24.70,52373600,24.19
+2006-08-15,24.55,24.65,24.44,24.62,48994500,24.11
+2006-08-14,24.52,24.60,24.35,24.53,47831900,23.94
+2006-08-11,24.43,24.45,24.20,24.43,30255500,23.84
+2006-08-10,24.37,24.60,24.34,24.46,31753400,23.87
+2006-08-09,24.49,24.64,24.34,24.44,44405700,23.85
+2006-08-08,24.39,24.52,24.20,24.34,58171300,23.75
+2006-08-07,24.28,24.48,24.19,24.22,36862400,23.63
+2006-08-04,24.40,24.49,24.15,24.29,45690400,23.70
+2006-08-03,24.19,24.48,24.15,24.21,43155300,23.62
+2006-08-02,24.12,24.40,24.03,24.30,46462000,23.71
+2006-08-01,24.02,24.20,23.85,23.99,49168700,23.41
+2006-07-31,24.07,24.42,24.01,24.06,40254400,23.48
+2006-07-28,24.08,24.28,24.06,24.25,51705800,23.66
+2006-07-27,24.58,24.60,23.77,23.87,85386800,23.29
+2006-07-26,24.12,24.53,24.10,24.37,54942100,23.78
+2006-07-25,24.00,24.29,23.90,24.22,60075800,23.63
+2006-07-24,24.01,24.11,23.79,24.00,59586700,23.42
+2006-07-21,24.08,24.15,23.00,23.87,175483800,23.29
+2006-07-20,23.44,23.45,22.78,22.85,76605200,22.30
+2006-07-19,22.82,23.46,22.72,23.40,82188200,22.83
+2006-07-18,22.59,22.76,22.48,22.74,65047300,22.19
+2006-07-17,22.29,22.61,22.26,22.48,37053500,21.94
+2006-07-14,22.28,22.55,22.23,22.29,67499400,21.75
+2006-07-13,22.37,22.61,22.25,22.26,73099500,21.72
+2006-07-12,22.79,22.88,22.62,22.64,77379300,22.09
+2006-07-11,23.37,23.37,22.74,23.10,88676300,22.54
+2006-07-10,23.43,23.66,23.38,23.50,50565100,22.93
+2006-07-07,23.39,23.55,23.30,23.30,63168800,22.74
+2006-07-06,23.45,23.61,23.42,23.48,44775200,22.91
+2006-07-05,23.48,23.52,23.30,23.35,53093500,22.79
+2006-07-03,23.53,23.72,23.45,23.70,25711400,23.13
+2006-06-30,23.54,23.65,23.30,23.30,73048800,22.74
+2006-06-29,23.32,23.63,23.22,23.47,121395500,22.90
+2006-06-28,22.96,23.25,22.91,23.16,71906500,22.60
+2006-06-27,22.89,23.16,22.84,22.86,84759100,22.31
+2006-06-26,22.65,22.89,22.63,22.82,53644100,22.27
+2006-06-23,22.85,22.87,22.50,22.50,60532600,21.96
+2006-06-22,23.06,23.17,22.78,22.88,76590600,22.33
+2006-06-21,22.61,23.15,22.53,23.08,91660300,22.52
+2006-06-20,22.54,22.76,22.50,22.56,90598500,22.01
+2006-06-19,22.14,22.60,22.12,22.55,129640900,22.01
+2006-06-16,21.97,22.28,21.79,22.10,147506500,21.57
+2006-06-15,22.01,22.13,21.80,22.07,121577300,21.54
+2006-06-14,21.59,21.94,21.55,21.88,86081500,21.35
+2006-06-13,21.73,22.03,21.46,21.51,113175300,20.99
+2006-06-12,21.96,22.10,21.70,21.71,74309700,21.19
+2006-06-09,22.15,22.19,21.89,21.92,52573800,21.39
+2006-06-08,22.03,22.21,21.97,22.11,104126900,21.58
+2006-06-07,22.15,22.39,22.01,22.04,73827500,21.51
+2006-06-06,22.55,22.56,21.98,22.13,126601300,21.60
+2006-06-05,22.72,22.73,22.49,22.50,63914100,21.96
+2006-06-02,22.87,22.99,22.67,22.76,73935600,22.21
+2006-06-01,22.74,22.84,22.62,22.82,80230800,22.27
+2006-05-31,23.26,23.35,22.65,22.65,120202000,22.10
+2006-05-30,23.55,23.76,23.14,23.15,52497500,22.59
+2006-05-26,23.77,23.88,23.56,23.72,46861600,23.15
+2006-05-25,23.57,23.92,23.54,23.74,83052700,23.17
+2006-05-24,22.99,23.54,22.98,23.50,107356700,22.93
+2006-05-23,23.11,23.38,22.77,22.79,79986300,22.24
+2006-05-22,22.48,23.02,22.45,22.88,87322300,22.33
+2006-05-19,22.79,22.90,22.52,22.56,100071200,22.01
+2006-05-18,22.84,23.14,22.76,22.83,95476400,22.28
+2006-05-17,22.89,23.08,22.73,22.73,98598300,22.18
+2006-05-16,23.16,24.00,22.91,23.01,82095100,22.45
+2006-05-15,23.10,23.23,23.03,23.15,67314800,22.59
+2006-05-12,23.14,23.37,23.05,23.17,83115900,22.52
+2006-05-11,23.71,23.79,23.15,23.22,92916700,22.57
+2006-05-10,23.67,23.79,23.59,23.77,76563300,23.11
+2006-05-09,23.75,24.00,23.49,23.62,75345900,22.96
+2006-05-08,23.85,25.00,23.51,23.73,80693500,23.07
+2006-05-05,23.66,23.95,23.52,23.80,131604300,23.13
+2006-05-04,23.35,23.67,23.14,23.44,171257400,22.78
+2006-05-03,23.99,24.02,23.15,23.17,211527100,22.52
+2006-05-02,24.49,25.00,23.90,24.01,190533500,23.34
+2006-05-01,24.32,25.00,24.09,24.29,174800900,23.61
+2006-04-28,24.23,24.50,24.00,24.15,591052200,23.47
+2006-04-27,26.97,27.63,26.94,27.25,96509600,26.49
+2006-04-26,27.08,27.23,27.00,27.10,39190000,26.34
+2006-04-25,27.09,27.21,27.02,27.11,49222500,26.35
+2006-04-24,27.07,27.25,26.98,27.11,42318400,26.35
+2006-04-21,27.05,27.39,27.00,27.15,58528000,26.39
+2006-04-20,27.05,27.19,26.70,27.03,45648300,26.27
+2006-04-19,27.11,27.19,26.96,27.03,45111100,26.27
+2006-04-18,26.94,27.50,26.82,27.22,56272700,26.46
+2006-04-17,27.03,27.05,26.73,26.84,35796200,26.09
+2006-04-13,27.08,27.20,27.00,27.07,28160000,26.31
+2006-04-12,27.10,27.20,26.97,27.20,32183000,26.44
+2006-04-11,27.29,27.32,27.00,27.13,42953400,26.37
+2006-04-10,27.23,27.44,27.20,27.29,39432000,26.53
+2006-04-07,27.61,27.72,27.23,27.25,47249400,26.49
+2006-04-06,27.66,27.72,27.37,27.56,51885500,26.79
+2006-04-05,27.88,27.94,27.64,27.74,41539300,26.96
+2006-04-04,27.60,27.80,27.47,27.64,45470000,26.87
+2006-04-03,27.67,27.73,27.44,27.56,57605300,26.79
+2006-03-31,27.30,27.54,27.21,27.21,62190500,26.45
+2006-03-30,27.03,27.39,27.00,27.23,54612000,26.47
+2006-03-29,26.95,27.20,26.92,27.02,53150300,26.26
+2006-03-28,27.01,27.21,26.81,26.90,58520500,26.15
+2006-03-27,27.01,27.30,27.00,27.01,59908600,26.25
+2006-03-24,26.71,27.21,26.62,27.01,69157600,26.25
+2006-03-23,27.08,27.10,26.66,26.85,73682900,26.10
+2006-03-22,27.08,27.50,26.80,27.15,145696100,26.39
+2006-03-21,27.74,28.22,27.68,27.74,73199600,26.96
+2006-03-20,27.70,27.99,27.67,27.89,67094100,27.11
+2006-03-17,27.35,27.66,27.27,27.50,120615000,26.73
+2006-03-16,27.34,27.48,27.22,27.27,73793700,26.51
+2006-03-15,27.20,27.45,27.01,27.36,57152000,26.60
+2006-03-14,27.04,27.38,26.99,27.23,39821800,26.47
+2006-03-13,27.18,27.29,26.94,27.11,40342600,26.35
+2006-03-10,27.06,27.22,26.88,27.17,41297200,26.41
+2006-03-09,27.27,27.42,27.00,27.00,45360700,26.25
+2006-03-08,26.99,27.50,26.97,27.25,57547400,26.49
+2006-03-07,26.90,27.10,26.81,27.06,51613900,26.30
+2006-03-06,26.92,27.15,26.83,26.91,53054100,26.16
+2006-03-03,26.81,27.16,26.74,26.93,45218800,26.18
+2006-03-02,27.02,27.10,26.90,26.97,41850300,26.22
+2006-03-01,26.98,27.20,26.95,27.14,53061200,26.38
+2006-02-28,26.95,27.30,26.87,26.87,65036100,26.12
+2006-02-27,26.75,27.26,26.67,27.05,51301500,26.29
+2006-02-24,26.59,26.74,26.52,26.63,44753800,25.89
+2006-02-23,26.73,26.89,26.54,26.66,47359100,25.91
+2006-02-22,26.53,26.86,26.47,26.72,43043100,25.97
+2006-02-21,26.72,26.72,26.34,26.54,50216100,25.80
+2006-02-17,26.67,26.81,26.56,26.70,41513200,25.95
+2006-02-16,26.85,26.90,26.57,26.81,48868500,26.06
+2006-02-15,26.60,26.93,26.50,26.88,62808900,26.13
+2006-02-14,26.41,26.68,26.35,26.65,58432900,25.82
+2006-02-13,26.63,26.70,26.34,26.39,46707000,25.57
+2006-02-10,26.62,26.89,26.51,26.69,52127000,25.86
+2006-02-09,26.96,27.03,26.65,26.66,52861700,25.83
+2006-02-08,27.01,27.08,26.71,26.91,51795200,26.07
+2006-02-07,26.95,27.15,26.81,26.94,72159500,26.10
+2006-02-06,27.51,27.54,27.09,27.17,60170500,26.32
+2006-02-03,27.48,27.70,27.34,27.54,75022700,26.68
+2006-02-02,27.97,27.99,27.55,27.68,55073400,26.82
+2006-02-01,27.96,28.07,27.76,28.04,68448800,27.16
+2006-01-31,27.91,28.38,27.87,28.15,94841300,27.27
+2006-01-30,27.82,28.18,27.78,28.00,103999200,27.13
+2006-01-27,27.23,27.95,27.19,27.79,134520700,26.92
+2006-01-26,26.56,26.72,26.31,26.50,69509300,25.67
+2006-01-25,26.41,26.57,26.23,26.40,59072100,25.58
+2006-01-24,26.34,26.45,26.22,26.28,63040700,25.46
+2006-01-23,26.41,26.53,26.30,26.35,47925600,25.53
+2006-01-20,27.01,27.01,26.26,26.41,79165900,25.58
+2006-01-19,26.87,27.24,26.85,27.02,60367600,26.18
+2006-01-18,26.74,26.98,26.70,26.83,52376200,25.99
+2006-01-17,26.90,27.19,26.90,26.99,58566600,26.15
+2006-01-13,27.03,27.25,27.01,27.19,41418000,26.34
+2006-01-12,27.25,27.26,26.97,27.14,45994800,26.29
+2006-01-11,27.01,27.39,26.90,27.29,70120700,26.44
+2006-01-10,26.65,27.02,26.59,27.00,64921900,26.16
+2006-01-09,26.93,27.07,26.76,26.86,55625000,26.02
+2006-01-06,26.89,27.00,26.49,26.91,100963000,26.07
+2006-01-05,26.96,27.13,26.91,26.99,48245500,26.15
+2006-01-04,26.77,27.08,26.77,26.97,57975600,26.13
+2006-01-03,26.25,27.00,26.10,26.84,79973000,26.00
+2005-12-30,26.15,26.31,26.10,26.15,49044600,25.33
+2005-12-29,26.41,26.50,26.26,26.27,34495500,25.45
+2005-12-28,26.51,26.66,26.35,26.39,35444400,25.57
+2005-12-27,26.68,26.85,26.45,26.46,37819000,25.63
+2005-12-23,26.52,26.67,26.44,26.64,30689200,25.81
+2005-12-22,26.71,26.78,26.42,26.59,91276900,25.76
+2005-12-21,26.87,26.91,26.71,26.73,75800900,25.89
+2005-12-20,26.76,26.88,26.67,26.86,62960600,26.02
+2005-12-19,26.82,26.87,26.65,26.83,68680100,25.99
+2005-12-16,26.88,27.08,26.81,26.90,88542500,26.06
+2005-12-15,27.08,27.11,26.81,26.92,79018100,26.08
+2005-12-14,27.00,27.24,26.85,27.09,65076200,26.24
+2005-12-13,27.29,27.43,27.00,27.13,104285500,26.28
+2005-12-12,27.70,27.75,27.33,27.45,63757200,26.59
+2005-12-09,27.71,27.83,27.64,27.71,48467000,26.84
+2005-12-08,27.71,27.81,27.60,27.69,63931600,26.83
+2005-12-07,27.67,27.75,27.55,27.75,55583200,26.88
+2005-12-06,27.90,27.92,27.68,27.69,65980000,26.83
+2005-12-05,27.93,28.02,27.71,27.85,47517300,26.98
+2005-12-02,27.82,28.10,27.79,28.01,42319600,27.14
+2005-12-01,27.73,28.10,27.73,27.89,61006100,27.02
+2005-11-30,27.68,27.77,27.63,27.68,55904700,26.82
+2005-11-29,27.79,27.79,27.60,27.68,62220400,26.82
+2005-11-28,27.79,27.85,27.53,27.75,57517200,26.88
+2005-11-25,27.80,27.94,27.47,27.76,44082500,26.89
+2005-11-23,27.92,28.09,27.74,27.92,70541300,27.05
+2005-11-22,28.06,28.08,27.86,27.91,104253300,27.04
+2005-11-21,28.07,28.24,27.84,28.16,65794400,27.28
+2005-11-18,28.12,28.25,27.90,28.07,75431200,27.19
+2005-11-17,27.85,28.00,27.76,27.97,91351000,27.10
+2005-11-16,27.48,27.88,27.44,27.74,86277000,26.87
+2005-11-15,27.33,27.54,27.25,27.50,65081000,26.64
+2005-11-14,27.36,27.44,27.20,27.37,67152200,26.44
+2005-11-11,27.15,27.39,27.13,27.28,51945600,26.35
+2005-11-10,26.94,27.15,26.64,27.09,73314800,26.17
+2005-11-09,26.98,27.15,26.94,26.96,59562100,26.04
+2005-11-08,26.94,27.18,26.77,27.05,60091700,26.13
+2005-11-07,26.72,27.08,26.70,27.01,77104800,26.09
+2005-11-04,26.53,26.71,26.45,26.66,57464000,25.75
+2005-11-03,26.60,26.64,26.25,26.44,73421600,25.54
+2005-11-02,25.93,26.50,25.93,26.46,75067100,25.56
+2005-11-01,25.61,26.10,25.61,25.96,71370400,25.08
+2005-10-31,25.61,25.80,25.50,25.70,75122100,24.82
+2005-10-28,25.10,25.60,25.10,25.53,106559300,24.66
+2005-10-27,25.22,25.27,24.85,24.85,61566100,24.00
+2005-10-26,24.97,25.33,24.93,25.11,58178100,24.25
+2005-10-25,24.95,25.13,24.83,25.03,41310500,24.18
+2005-10-24,24.89,25.10,24.68,25.10,51868000,24.24
+2005-10-21,24.91,25.00,24.57,24.78,69431200,23.94
+2005-10-20,25.05,25.13,24.74,24.79,58830600,23.95
+2005-10-19,24.56,25.09,24.50,25.09,66574500,24.24
+2005-10-18,24.49,24.83,24.45,24.57,69328200,23.73
+2005-10-17,24.68,24.69,24.44,24.53,46924400,23.69
+2005-10-14,24.71,24.73,24.50,24.67,53846700,23.83
+2005-10-13,24.31,24.73,24.27,24.59,70192000,23.75
+2005-10-12,24.49,24.70,24.27,24.30,71294400,23.47
+2005-10-11,24.51,24.55,24.25,24.41,76567300,23.58
+2005-10-10,24.67,24.68,24.35,24.46,48880900,23.63
+2005-10-07,24.77,24.84,24.52,24.59,50768700,23.75
+2005-10-06,24.66,24.95,24.53,24.73,81724600,23.89
+2005-10-05,25.04,25.05,24.67,24.67,73684700,23.83
+2005-10-04,25.36,25.39,24.75,24.98,151666300,24.13
+2005-10-03,25.71,25.73,25.44,25.50,55341300,24.63
+2005-09-30,25.91,25.95,25.61,25.73,57644500,24.85
+2005-09-29,25.61,26.00,25.50,25.94,66807100,25.06
+2005-09-28,25.39,25.87,25.38,25.67,71019400,24.80
+2005-09-27,25.37,25.45,25.30,25.34,48797900,24.48
+2005-09-26,25.40,25.49,25.21,25.27,56203700,24.41
+2005-09-23,25.31,25.54,25.12,25.27,66396800,24.41
+2005-09-22,25.49,25.60,25.15,25.34,71314900,24.48
+2005-09-21,25.80,25.90,25.43,25.49,68281800,24.62
+2005-09-20,26.07,26.22,25.69,25.84,61043400,24.96
+2005-09-19,26.09,26.27,25.86,26.00,61832300,25.11
+2005-09-16,26.34,26.40,25.97,26.07,187384300,25.18
+2005-09-15,26.37,26.43,26.22,26.27,60357200,25.37
+2005-09-14,26.52,26.64,26.30,26.31,54969600,25.41
+2005-09-13,26.54,26.76,26.37,26.48,63422900,25.58
+2005-09-12,26.62,26.75,26.52,26.61,40550500,25.70
+2005-09-09,26.62,26.82,26.53,26.58,41515800,25.67
+2005-09-08,26.80,26.88,26.52,26.61,52552300,25.70
+2005-09-07,26.94,27.11,26.82,26.85,44656100,25.94
+2005-09-06,27.06,27.29,26.98,27.00,46089000,26.08
+2005-09-02,27.21,27.27,26.97,27.02,52047500,26.10
+2005-09-01,27.38,27.39,27.15,27.20,75974500,26.27
+2005-08-31,27.17,27.44,27.04,27.38,65210200,26.45
+2005-08-30,27.06,27.23,26.96,27.18,55163200,26.25
+2005-08-29,26.81,27.23,26.81,27.15,52307700,26.22
+2005-08-26,27.06,27.08,26.87,26.97,36774600,26.05
+2005-08-25,26.90,27.09,26.85,27.03,39306300,26.11
+2005-08-24,26.84,27.16,26.78,26.81,63645000,25.90
+2005-08-23,26.84,27.07,26.74,26.87,48296700,25.95
+2005-08-22,26.79,27.17,26.77,26.91,41691700,25.99
+2005-08-19,26.85,26.91,26.70,26.72,36043500,25.81
+2005-08-18,26.89,27.08,26.80,26.82,40861900,25.91
+2005-08-17,26.82,27.15,26.66,26.95,52413100,26.03
+2005-08-16,27.03,27.14,26.70,26.74,46894600,25.83
+2005-08-15,26.98,27.30,26.69,27.13,45976600,26.21
+2005-08-12,27.08,27.14,26.90,27.05,52006500,26.05
+2005-08-11,26.98,27.30,26.89,27.27,48646800,26.26
+2005-08-10,27.41,27.50,26.85,26.95,62818800,25.95
+2005-08-09,27.22,27.51,27.01,27.35,64761800,26.34
+2005-08-08,27.80,27.84,27.08,27.13,77207200,26.13
+2005-08-05,27.29,27.94,27.25,27.76,82212400,26.73
+2005-08-04,27.16,27.50,27.05,27.32,91461400,26.31
+2005-08-03,26.76,27.43,26.73,27.25,139422400,26.24
+2005-08-02,25.90,26.90,25.87,26.81,137510100,25.82
+2005-08-01,25.81,26.05,25.76,25.92,61346800,24.96
+2005-07-29,25.78,26.00,25.59,25.61,59524400,24.66
+2005-07-28,25.75,25.85,25.66,25.75,44738700,24.80
+2005-07-27,25.61,25.80,25.53,25.72,57977300,24.77
+2005-07-26,25.72,25.74,25.53,25.54,51476400,24.60
+2005-07-25,25.69,25.90,25.65,25.69,45174600,24.74
+2005-07-22,25.99,26.34,25.63,25.68,97558900,24.73
+2005-07-21,26.30,26.48,26.00,26.44,112932100,25.46
+2005-07-20,26.00,26.23,25.88,26.19,71424800,25.22
+2005-07-19,25.79,26.25,25.75,26.16,113290100,25.19
+2005-07-18,25.71,25.79,25.55,25.55,39668000,24.61
+2005-07-15,26.04,26.10,25.75,25.79,56472800,24.84
+2005-07-14,25.79,26.10,25.79,25.97,69506800,25.01
+2005-07-13,25.53,25.75,25.48,25.66,44749200,24.71
+2005-07-12,25.24,25.62,25.20,25.61,63384800,24.66
+2005-07-11,25.15,25.38,25.11,25.29,61525400,24.36
+2005-07-08,24.64,25.12,24.63,25.09,56104000,24.16
+2005-07-07,24.58,24.71,24.50,24.65,80082900,23.74
+2005-07-06,24.97,25.08,24.69,24.70,64214600,23.79
+2005-07-05,24.66,25.19,24.62,24.98,61883500,24.06
+2005-07-01,24.85,24.99,24.67,24.71,69718400,23.80
+2005-06-30,25.06,25.14,24.82,24.84,82018200,23.92
+2005-06-29,25.22,25.32,25.00,25.09,55859900,24.16
+2005-06-28,25.09,25.20,25.03,25.07,53058100,24.14
+2005-06-27,25.07,25.25,25.03,25.05,61636200,24.12
+2005-06-24,25.22,25.40,25.04,25.04,57970700,24.12
+2005-06-23,25.17,25.62,25.15,25.31,105159800,24.38
+2005-06-22,25.11,25.26,25.03,25.07,60492700,24.14
+2005-06-21,25.08,25.19,25.04,25.15,81084000,24.22
+2005-06-20,24.98,25.28,24.93,25.11,50538900,24.18
+2005-06-17,25.27,25.29,24.92,25.04,90821300,24.12
+2005-06-16,25.22,25.23,24.95,25.04,65918800,24.12
+2005-06-15,25.40,25.41,25.11,25.26,50764800,24.33
+2005-06-14,25.31,25.44,25.24,25.36,44243300,24.42
+2005-06-13,25.36,25.49,25.26,25.31,49104100,24.38
+2005-06-10,25.49,25.52,25.34,25.43,39459800,24.49
+2005-06-09,25.40,25.61,25.35,25.51,52767900,24.57
+2005-06-08,25.55,25.62,25.34,25.40,45369700,24.46
+2005-06-07,25.33,25.83,25.31,25.51,54511400,24.57
+2005-06-06,25.38,25.50,25.31,25.37,40756900,24.43
+2005-06-03,25.70,25.81,25.34,25.43,79659500,24.49
+2005-06-02,25.71,25.86,25.64,25.79,27212500,24.84
+2005-06-01,25.73,26.00,25.61,25.81,54621000,24.86
+2005-05-31,25.99,26.03,25.75,25.80,46131100,24.85
+2005-05-27,25.83,26.09,25.81,26.07,54978000,25.11
+2005-05-26,25.75,26.00,25.73,25.90,50579200,24.94
+2005-05-25,25.68,25.77,25.50,25.71,35749000,24.76
+2005-05-24,25.80,25.88,25.72,25.75,61287700,24.80
+2005-05-23,25.74,26.07,25.74,25.85,75421100,24.90
+2005-05-20,25.88,25.92,25.73,25.74,64444500,24.79
+2005-05-19,25.75,26.05,25.70,25.92,52120800,24.96
+2005-05-18,25.50,25.84,25.42,25.70,71182400,24.75
+2005-05-17,25.31,25.50,25.25,25.46,39983200,24.52
+2005-05-16,25.23,25.50,25.19,25.49,50577300,24.55
+2005-05-13,25.03,25.38,24.99,25.30,77204300,24.29
+2005-05-12,24.84,25.11,24.83,25.00,74540700,24.00
+2005-05-11,24.89,24.97,24.64,24.91,59463300,23.91
+2005-05-10,25.04,25.08,24.82,24.90,62235100,23.90
+2005-05-09,25.23,25.33,25.05,25.11,61872400,24.11
+2005-05-06,25.33,25.48,25.19,25.22,64322600,24.21
+2005-05-05,25.20,25.33,25.08,25.23,59362300,24.22
+2005-05-04,25.34,25.40,25.11,25.21,86864200,24.20
+2005-05-03,25.13,25.40,25.09,25.36,67867800,24.35
+2005-05-02,25.23,25.36,24.95,25.23,54376700,24.22
+2005-04-29,24.88,25.30,24.79,25.30,98641200,24.29
+2005-04-28,24.82,24.92,24.44,24.45,83623100,23.47
+2005-04-27,24.66,25.15,24.63,24.99,47732800,23.99
+2005-04-26,24.95,25.25,24.74,24.76,60464300,23.77
+2005-04-25,25.07,25.28,24.86,24.99,75457900,23.99
+2005-04-22,25.05,25.25,24.78,24.98,80087500,23.98
+2005-04-21,24.48,25.39,24.47,25.28,93562300,24.27
+2005-04-20,24.66,24.70,24.30,24.32,91923500,23.35
+2005-04-19,24.71,24.80,24.45,24.63,65956200,23.65
+2005-04-18,24.45,24.84,24.40,24.65,75766400,23.66
+2005-04-15,24.58,24.90,24.41,24.46,100251600,23.48
+2005-04-14,25.01,25.14,24.83,24.84,66754400,23.85
+2005-04-13,25.23,25.45,24.99,25.04,60929300,24.04
+2005-04-12,24.92,25.35,24.80,25.32,67517800,24.31
+2005-04-11,25.03,25.11,24.86,24.97,47791800,23.97
+2005-04-08,25.07,25.25,24.91,24.94,47956300,23.94
+2005-04-07,24.66,25.13,24.63,25.10,77451500,24.10
+2005-04-06,24.47,24.94,24.45,24.67,78020200,23.68
+2005-04-05,24.22,24.50,24.12,24.47,73549600,23.49
+2005-04-04,24.11,24.26,23.94,24.23,62196400,23.26
+2005-04-01,24.24,24.35,24.10,24.12,64619600,23.16
+2005-03-31,24.25,24.31,24.12,24.17,62382300,23.20
+2005-03-30,24.04,24.19,24.00,24.16,59585700,23.19
+2005-03-29,24.14,24.24,23.82,23.92,74231700,22.96
+2005-03-28,24.40,24.47,24.18,24.20,49802000,23.23
+2005-03-24,24.24,24.47,24.20,24.28,78820900,23.31
+2005-03-23,23.99,24.39,23.96,24.18,79293300,23.21
+2005-03-22,24.19,24.27,23.96,23.99,102113300,23.03
+2005-03-21,24.35,24.36,24.15,24.20,71446200,23.23
+2005-03-18,24.53,24.91,24.28,24.31,135904000,23.34
+2005-03-17,24.64,24.68,24.53,24.54,60573200,23.56
+2005-03-16,24.82,24.97,24.56,24.63,74841400,23.65
+2005-03-15,25.10,25.24,24.89,24.91,71469400,23.91
+2005-03-14,25.08,25.15,24.96,25.11,65550500,24.11
+2005-03-11,25.45,25.48,25.06,25.09,60617900,24.09
+2005-03-10,25.43,25.48,25.25,25.43,59132900,24.41
+2005-03-09,25.39,25.57,25.28,25.31,62991800,24.30
+2005-03-08,25.40,25.62,25.34,25.40,52871800,24.38
+2005-03-07,25.17,25.79,25.16,25.47,80407400,24.45
+2005-03-04,25.21,25.30,25.13,25.17,63058200,24.16
+2005-03-03,25.30,25.31,25.14,25.17,52183600,24.16
+2005-03-02,25.19,25.48,25.16,25.26,67739000,24.25
+2005-03-01,25.19,25.41,25.13,25.28,56394800,24.27
+2005-02-28,25.22,25.37,25.13,25.16,82728000,24.15
+2005-02-25,25.33,25.38,25.15,25.25,62467700,24.24
+2005-02-24,25.18,25.44,25.15,25.37,85236300,24.36
+2005-02-23,25.24,25.35,25.17,25.20,83689400,24.19
+2005-02-22,25.25,25.49,25.20,25.23,96419200,24.22
+2005-02-18,25.64,25.65,25.40,25.48,77091100,24.46
+2005-02-17,25.71,25.86,25.60,25.65,67024800,24.62
+2005-02-16,25.87,25.93,25.67,25.79,57506600,24.76
+2005-02-15,26.00,26.08,25.86,25.93,76551600,24.89
+2005-02-14,25.93,26.12,25.91,26.01,58694000,24.89
+2005-02-11,26.03,26.12,25.81,25.97,83835900,24.86
+2005-02-10,26.10,26.13,26.00,26.06,71796400,24.94
+2005-02-09,26.25,26.31,26.04,26.07,77874800,24.95
+2005-02-08,26.19,26.34,26.16,26.24,61343700,25.11
+2005-02-07,26.27,26.30,26.06,26.16,57763400,25.04
+2005-02-04,26.17,26.37,26.14,26.32,61246500,25.19
+2005-02-03,26.37,26.40,26.10,26.18,62545400,25.06
+2005-02-02,26.42,26.50,26.28,26.46,79329500,25.32
+2005-02-01,26.25,26.43,26.22,26.39,57981700,25.26
+2005-01-31,26.35,26.52,26.16,26.28,71442100,25.15
+2005-01-28,26.54,26.65,25.96,26.18,110466500,25.06
+2005-01-27,25.95,26.16,25.85,26.11,93204100,24.99
+2005-01-26,26.07,26.17,25.90,26.01,64974500,24.89
+2005-01-25,25.76,26.19,25.75,26.02,67580700,24.90
+2005-01-24,25.76,26.00,25.64,25.67,69010900,24.57
+2005-01-21,25.95,26.13,25.64,25.65,76501000,24.55
+2005-01-20,25.84,26.10,25.74,25.86,58380100,24.75
+2005-01-19,26.21,26.26,25.92,25.98,58114100,24.86
+2005-01-18,26.03,26.35,25.84,26.32,69146400,25.19
+2005-01-14,26.40,26.45,26.04,26.12,92180800,25.00
+2005-01-13,26.68,26.80,26.16,26.27,89861600,25.14
+2005-01-12,26.77,26.85,26.62,26.78,72940600,25.63
+2005-01-11,26.69,26.82,26.61,26.73,64712000,25.58
+2005-01-10,26.60,26.86,26.54,26.80,70376600,25.65
+2005-01-07,26.82,26.89,26.62,26.67,68723300,25.53
+2005-01-06,26.85,27.06,26.64,26.75,76890500,25.60
+2005-01-05,26.84,27.10,26.76,26.78,72463500,25.63
+2005-01-04,26.87,27.10,26.66,26.84,109442100,25.69
+2005-01-03,26.80,26.95,26.65,26.74,65002900,25.59
diff --git a/dojox/charting/tests/BidiSupport/data/yahoo_prices.csv b/dojox/charting/tests/BidiSupport/data/yahoo_prices.csv
new file mode 100644
index 0000000..261889b
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/data/yahoo_prices.csv
@@ -0,0 +1,796 @@
+Date,Open,High,Low,Close,Volume,Adj Close
+2008-02-29,27.94,28.41,27.50,27.78,23860500,27.78
+2008-02-28,27.98,28.82,27.96,28.15,30113200,28.15
+2008-02-27,28.33,28.49,27.75,28.37,27664100,28.37
+2008-02-26,27.93,28.55,27.81,28.22,26013000,28.22
+2008-02-25,28.42,28.57,27.75,28.13,32470600,28.13
+2008-02-22,28.36,28.64,27.98,28.42,26157800,28.42
+2008-02-21,28.76,29.17,28.25,28.42,34494000,28.42
+2008-02-20,28.71,29.04,28.39,28.83,29274700,28.83
+2008-02-19,29.34,29.42,28.75,29.01,38679600,29.01
+2008-02-15,29.95,30.15,29.43,29.66,40125200,29.66
+2008-02-14,29.98,30.25,29.75,29.98,38045600,29.98
+2008-02-13,29.78,30.07,29.60,29.88,57047700,29.88
+2008-02-12,29.81,29.84,29.40,29.57,42445600,29.57
+2008-02-11,29.89,30.05,29.32,29.87,67253700,29.87
+2008-02-08,28.98,29.22,28.71,29.20,55618900,29.20
+2008-02-07,28.63,29.19,28.60,29.04,44248800,29.04
+2008-02-06,29.11,29.33,28.53,28.57,55648800,28.57
+2008-02-05,28.78,29.57,28.75,28.98,68583700,28.98
+2008-02-04,28.33,29.50,28.33,29.33,144814000,29.33
+2008-02-01,28.68,29.83,27.34,28.38,438248800,28.38
+2008-01-31,18.87,19.35,18.72,19.18,41449800,19.18
+2008-01-30,18.62,20.81,18.58,19.05,115993300,19.05
+2008-01-29,20.87,20.90,20.05,20.81,79230000,20.81
+2008-01-28,21.56,21.90,20.42,20.78,32473100,20.78
+2008-01-25,22.24,22.37,21.32,21.94,28386800,21.94
+2008-01-24,20.44,21.75,20.42,21.69,39823300,21.69
+2008-01-23,19.25,20.34,18.72,20.01,42064200,20.01
+2008-01-22,19.29,21.03,19.26,19.86,38126200,19.86
+2008-01-18,21.27,21.61,20.07,20.78,41239300,20.78
+2008-01-17,22.00,22.17,21.14,21.22,28812600,21.22
+2008-01-16,22.20,22.75,21.73,21.95,38155300,21.95
+2008-01-15,23.00,23.49,22.57,22.91,31911000,22.91
+2008-01-14,23.51,23.76,23.18,23.70,18552900,23.70
+2008-01-11,23.81,24.13,22.98,23.36,27297400,23.36
+2008-01-10,23.19,24.57,22.83,24.09,52342100,24.09
+2008-01-09,22.47,22.80,21.37,22.56,46662700,22.56
+2008-01-08,23.28,23.65,22.50,22.61,22974000,22.61
+2008-01-07,23.12,23.56,22.73,23.18,24769400,23.18
+2008-01-04,23.81,23.81,23.10,23.16,20745800,23.16
+2008-01-03,23.86,24.19,23.70,23.84,20179700,23.84
+2008-01-02,23.80,24.15,23.60,23.72,25671700,23.72
+2007-12-31,23.22,23.43,23.11,23.26,14782600,23.26
+2007-12-28,23.66,23.71,23.21,23.45,13773000,23.45
+2007-12-27,23.60,24.15,23.57,23.71,16041500,23.71
+2007-12-26,23.85,24.25,23.85,23.96,9821600,23.96
+2007-12-24,24.01,24.19,23.94,24.05,24861800,24.05
+2007-12-21,23.88,24.10,23.74,24.01,24094600,24.01
+2007-12-20,23.50,23.80,23.24,23.64,21030700,23.64
+2007-12-19,22.92,23.69,22.92,23.31,26547300,23.31
+2007-12-18,23.22,23.35,22.80,23.02,27735600,23.02
+2007-12-17,23.80,24.03,22.94,23.04,37877100,23.04
+2007-12-14,24.13,24.47,24.00,24.06,15125500,24.06
+2007-12-13,24.39,24.75,24.19,24.38,23787400,24.38
+2007-12-12,24.82,25.00,24.11,24.54,20241200,24.54
+2007-12-11,25.15,25.65,24.36,24.47,28579100,24.47
+2007-12-10,25.51,25.57,24.92,25.20,26074900,25.20
+2007-12-07,25.86,26.11,25.50,25.63,11443200,25.63
+2007-12-06,25.88,26.02,25.39,25.96,19236500,25.96
+2007-12-05,26.63,26.73,25.73,25.98,21170900,25.98
+2007-12-04,26.14,26.73,26.11,26.42,14668800,26.42
+2007-12-03,26.64,27.20,26.56,26.61,15250100,26.61
+2007-11-30,26.96,27.33,26.51,26.81,23994000,26.81
+2007-11-29,26.01,26.71,25.91,26.63,17929700,26.63
+2007-11-28,26.03,26.70,25.93,26.20,23239300,26.20
+2007-11-27,25.18,26.00,25.17,25.59,19484500,25.59
+2007-11-26,26.08,26.25,25.20,25.22,24174600,25.22
+2007-11-23,25.98,26.40,25.76,26.13,9249400,26.13
+2007-11-21,26.11,26.58,25.52,25.71,23320100,25.71
+2007-11-20,26.93,27.25,25.98,26.72,25672500,26.72
+2007-11-19,27.11,27.35,26.35,26.76,33066200,26.76
+2007-11-16,25.66,27.13,25.10,26.82,53013100,26.82
+2007-11-15,24.94,25.75,24.90,25.42,27920800,25.42
+2007-11-14,26.42,26.44,25.00,25.07,38154800,25.07
+2007-11-13,25.53,26.24,25.30,26.10,34123300,26.10
+2007-11-12,25.80,26.20,24.69,24.78,31264200,24.78
+2007-11-09,26.13,26.38,25.40,25.79,45199700,25.79
+2007-11-08,28.11,28.24,25.82,26.70,58160600,26.70
+2007-11-07,29.27,29.30,27.56,27.63,57069800,27.63
+2007-11-06,31.76,31.79,29.00,29.93,63664400,29.93
+2007-11-05,30.71,32.37,30.35,31.36,43520300,31.36
+2007-11-02,30.54,31.21,29.64,31.11,34090300,31.11
+2007-11-01,30.86,31.10,30.04,30.22,26913300,30.22
+2007-10-31,31.50,31.75,30.50,31.10,34762000,31.10
+2007-10-30,31.55,31.64,30.12,30.83,52417300,30.83
+2007-10-29,34.07,34.08,31.18,31.79,83685800,31.79
+2007-10-26,32.43,33.99,31.61,33.63,66018100,33.63
+2007-10-25,30.75,31.62,30.50,31.34,38706600,31.34
+2007-10-24,30.68,30.98,30.00,30.68,33603100,30.68
+2007-10-23,30.12,30.88,30.03,30.64,45406200,30.64
+2007-10-22,28.93,30.00,28.80,29.85,27750100,29.85
+2007-10-19,29.36,29.96,28.85,29.03,41933000,29.03
+2007-10-18,28.59,29.60,28.47,29.35,28152200,29.35
+2007-10-17,29.10,29.20,28.00,28.82,75067700,28.82
+2007-10-16,27.37,27.48,26.55,26.69,56275300,26.69
+2007-10-15,28.32,28.40,27.46,27.86,22994100,27.86
+2007-10-12,27.76,28.51,27.65,28.48,22130500,28.48
+2007-10-11,28.44,28.68,27.50,27.65,25298300,27.65
+2007-10-10,28.43,28.70,27.90,28.36,14847100,28.36
+2007-10-09,28.35,28.76,27.94,28.37,19539500,28.37
+2007-10-08,28.01,28.17,27.75,28.05,15060700,28.05
+2007-10-05,27.78,28.16,27.75,27.88,28389600,27.88
+2007-10-04,27.19,27.29,26.90,27.15,19203600,27.15
+2007-10-03,27.16,27.38,26.82,27.17,18052500,27.17
+2007-10-02,27.20,27.24,26.62,26.95,15133400,26.95
+2007-10-01,26.76,27.10,26.73,27.04,16938700,27.04
+2007-09-28,26.49,26.89,26.20,26.84,22155600,26.84
+2007-09-27,26.95,26.95,26.17,26.27,21365200,26.27
+2007-09-26,26.70,27.07,26.50,26.70,18692400,26.70
+2007-09-25,25.70,26.65,25.63,26.51,33721300,26.51
+2007-09-24,26.13,26.40,25.51,25.73,27597800,25.73
+2007-09-21,25.54,26.21,25.29,26.05,53074900,26.05
+2007-09-20,25.28,25.61,25.16,25.29,17312000,25.29
+2007-09-19,25.09,25.37,24.81,25.29,25867900,25.29
+2007-09-18,25.06,25.21,24.53,25.06,28121000,25.06
+2007-09-17,24.50,25.10,24.38,24.95,20594000,24.95
+2007-09-14,23.69,25.00,23.65,24.73,28868600,24.73
+2007-09-13,23.60,23.96,23.60,23.72,10309000,23.72
+2007-09-12,23.64,23.94,23.53,23.56,16553700,23.56
+2007-09-11,23.31,23.84,23.31,23.71,17207500,23.71
+2007-09-10,23.85,23.85,23.10,23.30,15246000,23.30
+2007-09-07,23.76,24.05,23.60,23.76,12591900,23.76
+2007-09-06,24.22,24.32,23.62,24.15,13922100,24.15
+2007-09-05,24.10,24.40,23.91,24.10,23071000,24.10
+2007-09-04,23.30,24.50,23.20,23.97,43598600,23.97
+2007-08-31,22.81,22.83,22.51,22.73,13052500,22.73
+2007-08-30,22.49,22.91,22.38,22.61,18172500,22.61
+2007-08-29,22.60,22.69,22.27,22.55,24599900,22.55
+2007-08-28,22.95,23.10,22.50,22.52,18030600,22.52
+2007-08-27,23.59,23.76,23.01,23.03,16523800,23.03
+2007-08-24,23.03,23.73,23.03,23.59,11191100,23.59
+2007-08-23,23.35,23.36,22.95,23.13,15603000,23.13
+2007-08-22,23.22,23.52,23.18,23.23,18763700,23.23
+2007-08-21,23.25,23.48,22.91,23.04,25962900,23.04
+2007-08-20,23.64,23.74,23.18,23.34,13338900,23.34
+2007-08-17,23.26,23.63,22.76,23.54,19528200,23.54
+2007-08-16,23.00,23.15,22.50,22.76,29652200,22.76
+2007-08-15,23.56,24.00,23.25,23.32,18767700,23.32
+2007-08-14,24.69,24.70,23.69,23.72,18707100,23.72
+2007-08-13,24.21,24.74,24.01,24.57,21317600,24.57
+2007-08-10,23.93,24.22,23.52,23.94,22939800,23.94
+2007-08-09,23.67,24.45,23.51,23.80,24052500,23.80
+2007-08-08,23.46,23.87,23.43,23.87,17198000,23.87
+2007-08-07,22.75,23.70,22.69,23.44,20075300,23.44
+2007-08-06,23.03,23.15,22.44,22.97,28948000,22.97
+2007-08-03,23.20,23.39,22.87,22.92,19702100,22.92
+2007-08-02,22.65,23.70,22.65,23.36,21098900,23.36
+2007-08-01,23.17,23.40,22.85,23.25,22030400,23.25
+2007-07-31,23.88,23.93,23.24,23.25,21575800,23.25
+2007-07-30,23.55,23.88,23.38,23.62,20976600,23.62
+2007-07-27,23.98,24.49,23.47,23.49,35783800,23.49
+2007-07-26,24.40,24.49,23.62,24.03,33373300,24.03
+2007-07-25,25.01,25.32,24.59,24.68,21882400,24.68
+2007-07-24,24.80,25.34,24.73,24.84,28981000,24.84
+2007-07-23,25.43,25.46,24.98,24.99,26631500,24.99
+2007-07-20,25.70,25.89,25.20,25.35,38056100,25.35
+2007-07-19,26.32,26.34,25.92,26.03,29537900,26.03
+2007-07-18,26.07,26.72,26.02,26.20,65125900,26.20
+2007-07-17,26.74,27.80,26.70,27.53,53656100,27.53
+2007-07-16,26.48,26.74,26.13,26.70,30804500,26.70
+2007-07-13,26.87,26.97,26.50,26.58,18522700,26.58
+2007-07-12,26.70,26.97,26.34,26.96,20082300,26.96
+2007-07-11,27.03,27.05,26.55,26.69,21970700,26.69
+2007-07-10,27.09,27.57,26.96,26.97,24635500,26.97
+2007-07-09,26.92,27.33,26.82,27.20,17515800,27.20
+2007-07-06,27.01,27.14,26.93,27.10,12284500,27.10
+2007-07-05,26.92,27.14,26.90,26.99,16071900,26.99
+2007-07-03,26.95,27.25,26.90,27.00,11643400,27.00
+2007-07-02,27.19,27.27,26.76,26.86,21011000,26.86
+2007-06-29,27.21,27.38,26.93,27.13,13842500,27.13
+2007-06-28,27.44,27.49,27.12,27.25,17124500,27.25
+2007-06-27,27.51,27.66,27.40,27.58,13997000,27.58
+2007-06-26,27.73,28.18,27.36,27.71,25324000,27.71
+2007-06-25,27.60,27.77,27.34,27.64,21232200,27.64
+2007-06-22,27.68,27.79,27.31,27.38,33796900,27.38
+2007-06-21,27.69,27.94,27.55,27.67,17885800,27.67
+2007-06-20,27.89,28.17,27.66,27.66,33496400,27.66
+2007-06-19,29.40,29.40,27.54,27.63,65967500,27.63
+2007-06-18,27.72,28.34,27.50,28.12,70919400,28.12
+2007-06-15,27.49,27.52,27.19,27.31,23816900,27.31
+2007-06-14,27.38,27.64,27.15,27.30,18919400,27.30
+2007-06-13,27.12,27.41,26.61,27.38,31210700,27.38
+2007-06-12,27.30,27.66,26.98,27.05,22203600,27.05
+2007-06-11,27.27,27.52,27.15,27.35,14856500,27.35
+2007-06-08,27.02,27.45,26.96,27.39,18618500,27.39
+2007-06-07,27.34,27.73,26.98,26.98,34232300,26.98
+2007-06-06,28.05,28.11,27.30,27.44,33508200,27.44
+2007-06-05,28.40,28.59,28.10,28.23,20494800,28.23
+2007-06-04,28.60,28.78,28.40,28.59,13428800,28.59
+2007-06-01,28.90,29.13,28.61,28.78,12398800,28.78
+2007-05-31,28.76,28.85,28.49,28.70,15859100,28.70
+2007-05-30,28.19,28.38,28.00,28.38,16046800,28.38
+2007-05-29,28.36,28.73,28.20,28.40,13981500,28.40
+2007-05-25,28.44,28.73,28.34,28.58,10334600,28.58
+2007-05-24,28.65,28.88,28.25,28.41,19122900,28.41
+2007-05-23,29.10,29.37,28.53,28.61,27964400,28.61
+2007-05-22,29.33,29.35,28.78,28.92,19131300,28.92
+2007-05-21,29.62,29.86,29.32,29.35,18955900,29.35
+2007-05-18,28.90,29.80,28.78,29.75,35487200,29.75
+2007-05-17,28.99,29.13,28.49,28.57,23535000,28.57
+2007-05-16,28.89,29.37,28.25,29.21,32944800,29.21
+2007-05-15,29.16,29.42,28.75,28.81,22226800,28.81
+2007-05-14,29.79,30.00,29.08,29.31,20895900,29.31
+2007-05-11,29.62,30.08,29.53,30.05,13838800,30.05
+2007-05-10,30.52,30.69,29.61,29.70,26570200,29.70
+2007-05-09,30.17,30.44,29.95,30.22,23533100,30.22
+2007-05-08,30.24,31.10,30.21,30.41,28018200,30.41
+2007-05-07,30.13,30.98,29.86,30.38,41243900,30.38
+2007-05-04,33.27,33.61,29.58,30.98,245611400,30.98
+2007-05-03,28.25,28.50,28.01,28.18,20119500,28.18
+2007-05-02,27.72,28.26,27.72,28.12,16911800,28.12
+2007-05-01,28.25,28.35,27.53,27.73,18310900,27.73
+2007-04-30,28.32,28.50,28.00,28.04,17596300,28.04
+2007-04-27,28.35,28.86,28.17,28.34,21097000,28.34
+2007-04-26,27.98,28.65,27.73,28.49,32331000,28.49
+2007-04-25,28.22,28.27,27.68,28.06,35568600,28.06
+2007-04-24,28.03,28.26,27.69,28.02,25964000,28.02
+2007-04-23,27.53,28.14,27.37,27.88,27262400,27.88
+2007-04-20,27.86,27.86,27.37,27.46,39123300,27.46
+2007-04-19,28.10,28.23,27.46,27.51,45664700,27.51
+2007-04-18,28.42,28.90,27.89,28.31,127875300,28.31
+2007-04-17,31.98,32.14,31.71,32.09,43223800,32.09
+2007-04-16,31.68,31.79,31.24,31.61,14359100,31.61
+2007-04-13,31.15,31.50,30.96,31.41,12006300,31.41
+2007-04-12,31.26,31.42,31.10,31.21,13904800,31.21
+2007-04-11,31.65,31.73,30.90,31.17,16141100,31.17
+2007-04-10,31.64,32.02,31.60,31.69,12797600,31.69
+2007-04-09,32.01,32.24,31.60,31.64,12408000,31.64
+2007-04-05,32.00,32.09,31.72,31.96,13878100,31.96
+2007-04-04,31.61,31.87,31.48,31.62,7836200,31.62
+2007-04-03,31.41,32.00,31.41,31.72,12324600,31.72
+2007-04-02,31.22,31.40,30.93,31.28,8668800,31.28
+2007-03-30,31.21,31.60,31.02,31.29,9425000,31.29
+2007-03-29,31.71,31.73,30.83,31.34,13815000,31.34
+2007-03-28,31.45,31.70,31.25,31.41,13162500,31.41
+2007-03-27,31.56,31.66,31.24,31.55,9403100,31.55
+2007-03-26,31.25,31.74,31.24,31.66,12907000,31.66
+2007-03-23,31.33,31.70,31.16,31.36,12727900,31.36
+2007-03-22,31.36,31.44,30.85,31.26,12989800,31.26
+2007-03-21,30.33,31.39,30.21,31.29,26667300,31.29
+2007-03-20,30.00,30.35,29.94,30.33,12203800,30.33
+2007-03-19,30.00,30.19,29.92,30.03,9983800,30.03
+2007-03-16,30.02,30.11,29.72,29.88,19799300,29.88
+2007-03-15,29.81,30.07,29.78,30.06,15440900,30.06
+2007-03-14,29.63,30.04,29.26,29.86,23604900,29.86
+2007-03-13,29.77,30.24,29.42,29.56,18263800,29.56
+2007-03-12,29.30,30.11,29.29,29.99,35991600,29.99
+2007-03-09,29.85,30.15,28.79,29.12,72749900,29.12
+2007-03-08,30.82,31.04,30.58,30.71,13715100,30.71
+2007-03-07,30.95,31.03,30.33,30.39,16014300,30.39
+2007-03-06,30.89,31.06,30.52,30.80,33472600,30.80
+2007-03-05,30.18,31.90,30.14,30.31,21469000,30.31
+2007-03-02,30.54,30.89,30.28,30.42,18136600,30.42
+2007-03-01,30.13,31.23,30.00,30.86,24012900,30.86
+2007-02-28,30.86,31.47,30.09,30.86,30487800,30.86
+2007-02-27,31.38,31.64,30.24,30.95,31505200,30.95
+2007-02-26,32.80,32.84,30.85,32.11,28295200,32.11
+2007-02-23,31.60,32.18,31.41,32.10,21533500,32.10
+2007-02-22,31.60,32.08,31.32,31.60,15485100,31.60
+2007-02-21,31.74,31.77,31.22,31.65,27999200,31.65
+2007-02-20,31.80,32.21,31.39,32.01,20026500,32.01
+2007-02-16,31.00,32.00,31.00,31.91,36774800,31.91
+2007-02-15,30.82,31.65,30.69,31.25,28160300,31.25
+2007-02-14,29.69,30.86,29.64,30.66,30821100,30.66
+2007-02-13,29.37,29.68,29.26,29.56,12802300,29.56
+2007-02-12,29.29,29.77,29.05,29.17,18316200,29.17
+2007-02-09,30.07,30.16,29.51,29.74,18172200,29.74
+2007-02-08,29.75,30.24,29.73,30.08,15561700,30.08
+2007-02-07,29.35,30.15,29.12,29.89,29162600,29.89
+2007-02-06,28.61,29.56,28.60,29.35,24506800,29.35
+2007-02-05,28.67,28.80,28.36,28.56,11163300,28.56
+2007-02-02,28.57,28.92,28.45,28.77,16483100,28.77
+2007-02-01,28.68,28.71,28.15,28.35,17905200,28.35
+2007-01-31,28.04,28.48,27.82,28.31,14100300,28.31
+2007-01-30,27.87,28.39,27.61,28.04,13576600,28.04
+2007-01-29,28.05,28.21,27.73,27.87,16859000,27.87
+2007-01-26,28.33,28.52,27.96,28.04,21334800,28.04
+2007-01-25,28.68,29.05,28.13,28.21,28356200,28.21
+2007-01-24,28.34,29.20,28.22,28.94,81017500,28.94
+2007-01-23,27.42,27.54,26.88,26.96,43728100,26.96
+2007-01-22,27.85,27.90,27.18,27.42,23199800,27.42
+2007-01-19,27.93,28.34,27.55,27.64,24757700,27.64
+2007-01-18,28.92,28.99,27.82,28.12,23869400,28.12
+2007-01-17,29.40,29.40,28.81,29.05,17796100,29.05
+2007-01-16,29.88,29.88,28.79,29.29,24448400,29.29
+2007-01-12,28.98,29.50,28.49,29.45,20971100,29.45
+2007-01-11,28.76,29.37,28.70,29.20,28457500,29.20
+2007-01-10,27.48,28.92,27.44,28.70,40240000,28.70
+2007-01-09,28.00,28.05,27.41,27.58,25621500,27.58
+2007-01-08,27.70,28.04,27.43,27.92,25713700,27.92
+2007-01-05,26.70,27.87,26.66,27.74,64264600,27.74
+2007-01-04,25.64,26.92,25.52,26.85,32512200,26.85
+2007-01-03,25.85,26.26,25.26,25.61,26352700,25.61
+2006-12-29,25.42,25.82,25.33,25.54,16297800,25.54
+2006-12-28,25.62,25.72,25.30,25.36,11908400,25.36
+2006-12-27,25.47,25.88,25.45,25.75,12421800,25.75
+2006-12-26,25.49,25.61,25.34,25.45,8400500,25.45
+2006-12-22,25.67,25.88,25.45,25.55,14666100,25.55
+2006-12-21,25.71,25.75,25.13,25.48,27050600,25.48
+2006-12-20,26.24,26.31,25.54,25.59,24905600,25.59
+2006-12-19,26.05,26.50,25.91,26.41,18973800,26.41
+2006-12-18,26.89,26.97,26.07,26.30,19431200,26.30
+2006-12-15,27.00,27.22,26.76,26.90,27227300,26.90
+2006-12-14,26.63,26.97,26.50,26.87,14400300,26.87
+2006-12-13,27.05,27.23,26.51,26.60,20428600,26.60
+2006-12-12,26.63,27.38,26.60,26.75,31971600,26.75
+2006-12-11,26.37,26.70,26.12,26.49,12916900,26.49
+2006-12-08,26.65,26.78,26.27,26.34,19262200,26.34
+2006-12-07,26.95,27.16,26.60,26.63,22407000,26.63
+2006-12-06,27.25,27.45,26.60,26.86,35202800,26.86
+2006-12-05,26.87,27.61,26.86,27.43,27118200,27.43
+2006-12-04,26.49,27.30,26.49,26.89,28012700,26.89
+2006-12-01,27.00,27.25,26.00,26.49,20055800,26.49
+2006-11-30,27.00,27.15,26.73,27.01,14916300,27.01
+2006-11-29,27.40,27.40,26.71,27.04,19375100,27.04
+2006-11-28,27.03,27.24,26.85,27.00,14940800,27.00
+2006-11-27,27.50,28.50,27.17,27.27,19922300,27.27
+2006-11-24,28.22,28.49,27.70,28.03,9384400,28.03
+2006-11-22,27.51,28.56,27.29,28.49,32055800,28.49
+2006-11-21,26.50,27.34,26.50,27.14,21138300,27.14
+2006-11-20,26.96,27.04,26.63,26.72,20272000,26.72
+2006-11-17,26.68,27.05,26.63,26.91,17955200,26.91
+2006-11-16,27.31,27.33,26.20,26.64,38508500,26.64
+2006-11-15,27.18,27.50,27.03,27.15,22112700,27.15
+2006-11-14,27.40,27.50,27.11,27.24,20145700,27.24
+2006-11-13,27.17,27.62,27.15,27.40,16876500,27.40
+2006-11-10,27.40,27.50,27.03,27.39,21366600,27.39
+2006-11-09,27.18,27.65,26.96,27.45,27428600,27.45
+2006-11-08,26.36,27.25,26.31,26.90,23384800,26.90
+2006-11-07,26.69,27.15,26.58,26.61,28442700,26.61
+2006-11-06,26.34,26.70,26.10,26.59,22563600,26.59
+2006-11-03,26.63,26.70,26.04,26.18,15313800,26.18
+2006-11-02,25.94,26.60,25.77,26.53,34824500,26.53
+2006-11-01,26.50,26.62,25.82,25.99,26300200,25.99
+2006-10-31,26.44,26.70,26.10,26.34,33492800,26.34
+2006-10-30,25.87,26.40,25.66,25.95,35295800,25.95
+2006-10-27,25.23,25.60,24.90,25.34,29647200,25.34
+2006-10-26,24.70,25.33,24.36,25.28,38435800,25.28
+2006-10-25,23.73,24.64,23.69,24.49,40110600,24.49
+2006-10-24,23.35,23.64,23.15,23.53,31704000,23.53
+2006-10-23,23.14,23.50,23.10,23.37,26301200,23.37
+2006-10-20,23.22,23.27,22.65,23.21,49795600,23.21
+2006-10-19,23.02,23.59,23.00,23.14,42280400,23.14
+2006-10-18,24.57,24.75,22.88,22.99,111660900,22.99
+2006-10-17,23.74,24.35,23.68,24.15,67417200,24.15
+2006-10-16,24.34,24.52,23.75,24.18,36496400,24.18
+2006-10-13,23.90,24.50,23.57,24.42,51338900,24.42
+2006-10-12,24.32,24.38,24.10,24.12,25824500,24.12
+2006-10-11,24.29,24.64,23.80,24.24,39356300,24.24
+2006-10-10,24.94,25.03,24.32,24.47,30371900,24.47
+2006-10-09,25.45,25.72,25.00,25.03,15729500,25.03
+2006-10-06,25.09,25.50,25.01,25.47,20847000,25.47
+2006-10-05,25.16,25.25,24.88,25.18,17634000,25.18
+2006-10-04,24.89,25.26,24.74,25.21,21717900,25.21
+2006-10-03,24.81,25.00,24.70,24.84,21148300,24.84
+2006-10-02,25.45,25.46,24.75,24.88,19641300,24.88
+2006-09-29,25.50,25.59,25.24,25.28,18982600,25.28
+2006-09-28,24.87,25.50,24.84,25.33,35331200,25.33
+2006-09-27,25.00,25.01,24.60,24.65,29835900,24.65
+2006-09-26,25.44,25.48,24.81,25.05,34950100,25.05
+2006-09-25,25.64,25.87,25.20,25.29,19992400,25.29
+2006-09-22,25.34,25.69,25.18,25.52,20667400,25.52
+2006-09-21,25.53,25.95,25.21,25.34,28584500,25.34
+2006-09-20,26.04,26.09,25.38,25.64,55636600,25.64
+2006-09-19,29.09,29.13,25.10,25.75,127718600,25.75
+2006-09-18,29.37,29.39,28.58,29.00,15685000,29.00
+2006-09-15,29.30,29.57,29.22,29.32,19550300,29.32
+2006-09-14,29.10,29.24,28.89,29.03,9565500,29.03
+2006-09-13,29.06,29.37,28.80,29.17,15248400,29.17
+2006-09-12,28.55,29.22,28.46,29.09,10005000,29.09
+2006-09-11,28.05,28.73,27.67,28.61,12936000,28.61
+2006-09-08,28.04,28.32,27.97,28.14,9781800,28.14
+2006-09-07,28.40,28.51,27.82,27.86,18434400,27.86
+2006-09-06,28.94,29.01,28.49,28.50,12800600,28.50
+2006-09-05,29.45,29.48,28.95,29.07,11425600,29.07
+2006-09-01,28.91,29.53,28.91,29.49,11573600,29.49
+2006-08-31,28.99,29.02,28.59,28.83,8879300,28.83
+2006-08-30,29.00,29.14,28.71,29.02,13119300,29.02
+2006-08-29,28.86,29.01,28.51,28.96,9888800,28.96
+2006-08-28,28.75,29.25,28.70,28.91,10404700,28.91
+2006-08-25,28.95,29.28,28.74,28.77,6203800,28.77
+2006-08-24,28.75,29.13,28.70,28.99,8983600,28.99
+2006-08-23,29.34,29.47,28.68,28.70,8837400,28.70
+2006-08-22,28.84,29.65,28.80,29.26,10891800,29.26
+2006-08-21,29.22,29.52,28.83,28.90,11575200,28.90
+2006-08-18,28.90,29.97,28.77,29.78,19611300,29.78
+2006-08-17,28.38,29.32,28.34,28.91,17251600,28.91
+2006-08-16,28.35,28.46,27.97,28.39,12589400,28.39
+2006-08-15,27.58,28.20,27.48,28.17,15298500,28.17
+2006-08-14,27.71,27.80,27.00,27.26,10640100,27.26
+2006-08-11,27.52,27.72,27.40,27.50,9252200,27.50
+2006-08-10,26.95,27.80,26.85,27.49,12597900,27.49
+2006-08-09,27.75,27.85,27.00,27.22,14736100,27.22
+2006-08-08,26.95,27.70,26.63,27.44,19332800,27.44
+2006-08-07,26.92,27.11,26.58,27.08,12847200,27.08
+2006-08-04,27.20,27.58,26.83,26.99,11607900,26.99
+2006-08-03,26.50,27.05,26.40,26.90,15468500,26.90
+2006-08-02,27.01,27.10,26.45,26.63,18116200,26.63
+2006-08-01,27.06,27.12,26.74,26.94,18613100,26.94
+2006-07-31,27.46,27.55,26.99,27.14,16492600,27.14
+2006-07-28,26.90,27.50,26.33,27.47,21584800,27.47
+2006-07-27,27.35,27.50,26.64,26.70,25153000,26.70
+2006-07-26,26.78,27.51,26.57,27.08,20073800,27.08
+2006-07-25,26.75,27.19,26.57,26.95,21388800,26.95
+2006-07-24,26.24,27.23,25.89,26.94,42631300,26.94
+2006-07-21,24.99,26.06,24.91,25.89,36187100,25.89
+2006-07-20,25.55,26.21,24.91,25.27,54659700,25.27
+2006-07-19,26.41,26.70,25.04,25.20,204339000,25.20
+2006-07-18,32.08,32.26,31.25,32.24,39767700,32.24
+2006-07-17,31.98,32.40,31.69,31.84,16369600,31.84
+2006-07-14,32.34,32.48,31.85,32.08,12484700,32.08
+2006-07-13,32.85,33.16,32.07,32.23,19463500,32.23
+2006-07-12,33.03,33.74,32.99,33.38,18708400,33.38
+2006-07-11,32.79,33.35,32.32,33.17,11285900,33.17
+2006-07-10,32.91,33.14,32.73,32.85,15317600,32.85
+2006-07-07,32.94,33.05,32.37,32.50,12372500,32.50
+2006-07-06,32.77,33.22,32.70,33.11,13801500,33.11
+2006-07-05,32.85,32.99,32.33,32.47,13453900,32.47
+2006-07-03,32.90,33.44,32.90,33.30,8067100,33.30
+2006-06-30,33.01,33.12,32.54,33.00,22566600,33.00
+2006-06-29,32.26,33.00,32.20,32.97,15745900,32.97
+2006-06-28,31.75,32.17,31.70,31.92,14032800,31.92
+2006-06-27,31.85,32.22,31.32,31.51,16589400,31.51
+2006-06-26,31.45,31.70,31.16,31.55,11457000,31.55
+2006-06-23,31.08,31.76,30.82,31.37,17378500,31.37
+2006-06-22,30.85,31.16,30.44,30.68,11500300,30.68
+2006-06-21,30.77,31.54,30.65,31.06,18252900,31.06
+2006-06-20,30.42,30.65,30.10,30.60,12613200,30.60
+2006-06-19,30.51,30.75,30.06,30.35,12236700,30.35
+2006-06-16,30.70,30.86,30.15,30.36,12951700,30.36
+2006-06-15,29.98,30.96,29.72,30.79,22375000,30.79
+2006-06-14,29.81,30.00,29.25,29.62,19257500,29.62
+2006-06-13,29.77,30.20,29.51,29.65,16435700,29.65
+2006-06-12,30.37,30.65,29.66,29.78,14344600,29.78
+2006-06-09,30.70,30.80,30.23,30.37,10044700,30.37
+2006-06-08,30.43,30.99,29.83,30.45,20538600,30.45
+2006-06-07,30.80,31.25,30.36,30.54,17470100,30.54
+2006-06-06,30.83,30.97,30.35,30.70,15615600,30.70
+2006-06-05,31.19,31.43,30.79,30.82,17188500,30.82
+2006-06-02,32.11,32.19,31.30,31.52,16470900,31.52
+2006-06-01,31.83,32.00,31.49,31.99,16652400,31.99
+2006-05-31,32.19,32.32,31.11,31.59,21306700,31.59
+2006-05-30,32.73,32.89,31.79,32.00,16247600,32.00
+2006-05-26,32.86,33.02,32.35,33.02,13842600,33.02
+2006-05-25,32.94,33.50,32.50,32.92,34732700,32.92
+2006-05-24,30.95,32.02,30.71,31.79,27286300,31.79
+2006-05-23,31.04,31.63,30.76,30.76,28583400,30.76
+2006-05-22,30.42,30.98,29.89,30.46,35089300,30.46
+2006-05-19,29.05,29.75,28.60,29.53,33121900,29.53
+2006-05-18,30.10,30.36,28.93,29.00,38254000,29.00
+2006-05-17,30.61,31.26,30.04,30.11,39847500,30.11
+2006-05-16,31.10,31.22,30.63,30.97,15333700,30.97
+2006-05-15,30.85,31.25,30.60,31.03,13350700,31.03
+2006-05-12,30.71,31.18,30.38,30.81,16745600,30.81
+2006-05-11,31.96,32.17,30.87,30.99,24277000,30.99
+2006-05-10,32.48,32.56,32.00,32.09,13797500,32.09
+2006-05-09,32.68,34.00,32.35,32.49,13396400,32.49
+2006-05-08,33.09,33.43,32.63,32.87,18188200,32.87
+2006-05-05,32.63,32.75,32.22,32.66,14689200,32.66
+2006-05-04,32.40,32.56,32.08,32.19,10402300,32.19
+2006-05-03,32.40,33.00,31.75,32.17,23292600,32.17
+2006-05-02,32.20,32.91,31.72,31.85,16276000,31.85
+2006-05-01,32.99,33.10,31.86,32.08,19752200,32.08
+2006-04-28,32.88,33.45,32.78,32.78,13283500,32.78
+2006-04-27,32.79,33.50,32.40,33.20,19635700,33.20
+2006-04-26,32.30,33.09,32.10,33.00,24426400,33.00
+2006-04-25,32.99,33.06,31.88,31.99,22363200,31.99
+2006-04-24,33.01,33.45,32.90,33.01,15441600,33.01
+2006-04-21,33.36,34.09,32.70,32.89,25215000,32.89
+2006-04-20,33.48,33.70,32.93,33.37,23403900,33.37
+2006-04-19,33.47,33.98,32.76,33.54,77253600,33.54
+2006-04-18,31.17,31.38,30.53,31.30,38604500,31.30
+2006-04-17,31.16,31.79,30.66,30.97,18239900,30.97
+2006-04-13,31.14,31.40,30.85,31.13,15609800,31.13
+2006-04-12,31.44,31.50,30.89,31.10,14926900,31.10
+2006-04-11,32.45,32.60,31.15,31.39,22105600,31.39
+2006-04-10,32.28,32.63,32.12,32.55,9618000,32.55
+2006-04-07,32.85,32.97,32.21,32.27,12980200,32.27
+2006-04-06,32.12,33.14,32.11,32.79,21572600,32.79
+2006-04-05,32.30,32.50,31.96,32.11,11982500,32.11
+2006-04-04,31.69,32.25,31.66,32.10,16232700,32.10
+2006-04-03,32.41,32.53,31.79,31.89,14887900,31.89
+2006-03-31,32.45,32.63,32.01,32.26,12677300,32.26
+2006-03-30,32.75,32.83,32.09,32.42,14314000,32.42
+2006-03-29,32.44,32.91,32.14,32.56,25508200,32.56
+2006-03-28,31.45,32.50,31.41,32.39,25981500,32.39
+2006-03-27,31.84,32.08,31.30,31.45,14858500,31.45
+2006-03-24,32.28,32.31,31.53,31.77,17816500,31.77
+2006-03-23,31.52,31.95,31.48,31.83,33834000,31.83
+2006-03-22,30.33,30.91,30.31,30.75,23147400,30.75
+2006-03-21,30.11,30.78,30.02,30.11,18876400,30.11
+2006-03-20,30.38,30.93,30.20,30.44,21455200,30.44
+2006-03-17,30.35,30.36,29.83,30.07,23629700,30.07
+2006-03-16,30.77,30.88,30.10,30.13,17108000,30.13
+2006-03-15,31.25,31.28,30.47,30.53,20758000,30.53
+2006-03-14,30.10,31.00,30.10,30.99,19294700,30.99
+2006-03-13,30.72,30.97,30.12,30.15,18437700,30.15
+2006-03-10,30.40,31.10,29.75,30.58,28991400,30.58
+2006-03-09,31.05,31.32,30.25,30.28,18277000,30.28
+2006-03-08,31.31,31.55,30.82,30.99,20910200,30.99
+2006-03-07,31.42,32.20,31.31,31.43,23365100,31.43
+2006-03-06,31.53,31.94,31.45,31.57,17211200,31.57
+2006-03-03,31.70,32.07,31.38,31.45,23196000,31.45
+2006-03-02,32.01,32.11,31.58,31.70,23487300,31.70
+2006-03-01,32.21,32.42,31.72,32.18,18466100,32.18
+2006-02-28,32.63,32.98,31.34,32.06,39926200,32.06
+2006-02-27,33.11,33.21,32.57,32.74,11821900,32.74
+2006-02-24,33.20,33.34,32.92,33.01,10136400,33.01
+2006-02-23,33.01,33.66,32.88,33.15,14947600,33.15
+2006-02-22,32.49,33.34,32.40,33.16,18433500,33.16
+2006-02-21,32.90,33.07,32.38,32.39,14328100,32.39
+2006-02-17,32.88,33.14,32.71,32.76,12620200,32.76
+2006-02-16,33.30,33.40,32.60,32.75,19500100,32.75
+2006-02-15,32.62,33.33,32.55,33.02,19542100,33.02
+2006-02-14,32.14,32.83,32.05,32.72,26198600,32.72
+2006-02-13,32.21,32.44,31.70,32.04,26139300,32.04
+2006-02-10,32.58,32.60,32.10,32.51,19628600,32.51
+2006-02-09,33.01,33.36,32.40,32.50,25335200,32.50
+2006-02-08,33.24,33.40,32.51,33.00,28112900,33.00
+2006-02-07,33.01,33.10,32.32,33.02,37236800,33.02
+2006-02-06,33.90,33.95,32.78,32.92,23523100,32.92
+2006-02-03,34.00,34.05,33.26,33.54,32639600,33.54
+2006-02-02,35.01,35.10,34.10,34.25,18323500,34.25
+2006-02-01,34.45,35.00,34.35,35.00,43600400,35.00
+2006-01-31,35.20,35.20,34.31,34.38,36538000,34.38
+2006-01-30,35.09,35.23,34.88,35.05,29030600,35.05
+2006-01-27,35.26,35.27,34.66,35.09,24317400,35.09
+2006-01-26,34.94,35.25,34.49,35.17,28471400,35.17
+2006-01-25,35.43,35.48,34.38,34.49,23779200,34.49
+2006-01-24,34.55,35.20,34.51,34.87,31667800,34.87
+2006-01-23,34.22,34.40,33.98,34.17,30887600,34.17
+2006-01-20,34.44,34.66,33.21,33.74,57644600,33.74
+2006-01-19,35.82,35.84,34.24,34.33,60913000,34.33
+2006-01-18,35.01,36.16,34.74,35.18,118556100,35.18
+2006-01-17,39.09,40.39,38.96,40.11,41797000,40.11
+2006-01-13,41.00,41.08,39.62,39.90,30960800,39.90
+2006-01-12,41.92,41.99,40.76,40.89,18921700,40.89
+2006-01-11,42.19,42.31,41.72,41.87,26191400,41.87
+2006-01-10,42.96,43.34,42.34,42.98,16287200,42.98
+2006-01-09,43.10,43.66,42.82,43.42,16266900,43.42
+2006-01-06,42.88,43.57,42.80,43.21,29418400,43.21
+2006-01-05,40.93,41.73,40.85,41.53,12829100,41.53
+2006-01-04,41.22,41.90,40.77,40.97,20549000,40.97
+2006-01-03,39.69,41.22,38.79,40.91,24227700,40.91
+2005-12-30,39.40,39.56,39.05,39.18,12233000,39.18
+2005-12-29,40.25,40.35,39.41,39.56,10116600,39.56
+2005-12-28,40.10,40.48,39.77,40.25,11567900,40.25
+2005-12-27,40.65,40.94,39.85,39.94,11672900,39.94
+2005-12-23,41.09,41.10,40.45,40.63,5070200,40.63
+2005-12-22,40.69,41.68,40.55,40.83,9548300,40.83
+2005-12-21,40.52,41.05,40.35,40.47,11626900,40.47
+2005-12-20,41.26,41.36,40.48,40.68,15269500,40.68
+2005-12-19,42.16,42.89,40.88,41.05,18563700,41.05
+2005-12-16,41.86,42.67,41.75,42.32,21805000,42.32
+2005-12-15,41.23,41.84,41.14,41.75,20900800,41.75
+2005-12-14,41.12,41.68,40.84,41.30,23034200,41.30
+2005-12-13,40.01,41.40,40.00,41.20,17264700,41.20
+2005-12-12,40.41,40.54,39.81,40.08,9776300,40.08
+2005-12-09,40.50,40.87,40.20,40.31,11116900,40.31
+2005-12-08,40.25,40.54,39.95,40.35,12851600,40.35
+2005-12-07,40.31,40.63,39.57,40.11,15644900,40.11
+2005-12-06,40.78,41.18,40.12,40.19,16356800,40.19
+2005-12-05,40.88,41.03,40.37,40.47,15389400,40.47
+2005-12-02,41.22,41.85,40.89,41.21,14411400,41.21
+2005-12-01,40.74,41.25,40.54,41.07,20069600,41.07
+2005-11-30,39.38,40.84,39.09,40.23,31608700,40.23
+2005-11-29,41.01,41.59,39.82,40.19,28698200,40.19
+2005-11-28,41.63,41.77,40.66,41.11,23190900,41.11
+2005-11-25,42.71,42.84,41.94,42.13,8253000,42.13
+2005-11-23,42.21,43.45,42.17,42.50,21471000,42.50
+2005-11-22,41.73,42.65,41.65,42.36,26389500,42.36
+2005-11-21,41.26,42.98,41.21,42.27,27915500,42.27
+2005-11-18,42.04,42.41,41.29,41.54,30747600,41.54
+2005-11-17,40.32,42.50,40.03,42.23,44796000,42.23
+2005-11-16,37.90,40.07,37.86,40.04,39464600,40.04
+2005-11-15,38.26,38.61,37.54,37.65,11981600,37.65
+2005-11-14,38.43,38.72,37.96,38.45,10112500,38.45
+2005-11-11,38.69,39.05,38.34,38.49,12234400,38.49
+2005-11-10,37.52,38.75,37.52,38.69,13722400,38.69
+2005-11-09,37.76,38.04,37.43,37.75,12217600,37.75
+2005-11-08,37.75,38.50,37.60,37.97,14434400,37.97
+2005-11-07,37.69,38.18,37.41,37.90,11652700,37.90
+2005-11-04,37.59,37.99,37.37,37.87,11656100,37.87
+2005-11-03,38.26,38.28,37.33,37.45,16880800,37.45
+2005-11-02,37.49,38.04,37.43,37.99,17886200,37.99
+2005-11-01,36.62,38.71,36.59,37.72,41932100,37.72
+2005-10-31,35.60,37.27,35.60,36.97,24867100,36.97
+2005-10-28,35.62,35.92,35.25,35.58,14123800,35.58
+2005-10-27,35.34,35.66,35.30,35.45,11605000,35.45
+2005-10-26,35.06,35.75,34.97,35.46,17125600,35.46
+2005-10-25,35.19,35.38,34.89,35.12,14441100,35.12
+2005-10-24,35.30,35.49,34.94,35.28,19591900,35.28
+2005-10-21,35.99,36.33,35.19,35.29,28423400,35.29
+2005-10-20,35.90,36.94,35.05,35.26,29267000,35.26
+2005-10-19,34.62,35.94,34.59,35.91,63254000,35.91
+2005-10-18,34.40,34.76,33.64,33.70,35010300,33.70
+2005-10-17,33.85,34.30,33.80,34.16,21994600,34.16
+2005-10-14,33.62,33.62,32.77,33.52,17425200,33.52
+2005-10-13,33.80,33.85,32.97,33.37,16254600,33.37
+2005-10-12,33.99,34.71,33.91,33.93,16089600,33.93
+2005-10-11,34.55,34.84,33.66,34.10,16504700,34.10
+2005-10-10,34.20,34.90,34.12,34.53,15227800,34.53
+2005-10-07,34.03,34.29,33.97,34.16,12253200,34.16
+2005-10-06,33.95,34.30,33.54,33.80,21836100,33.80
+2005-10-05,33.79,33.93,33.36,33.49,14642000,33.49
+2005-10-04,33.75,34.37,33.51,33.57,14331000,33.57
+2005-10-03,33.80,34.12,33.71,33.77,13184500,33.77
+2005-09-30,33.59,34.10,33.56,33.84,15697000,33.84
+2005-09-29,32.40,33.70,32.12,33.46,22209100,33.46
+2005-09-28,32.67,32.80,32.27,32.35,11622800,32.35
+2005-09-27,32.17,32.61,32.17,32.48,12246900,32.48
+2005-09-26,32.48,32.55,31.99,32.18,13548200,32.18
+2005-09-23,32.12,32.25,31.75,32.13,14903700,32.13
+2005-09-22,32.09,32.41,31.76,32.04,18259400,32.04
+2005-09-21,32.53,33.10,31.60,31.97,21896000,31.97
+2005-09-20,32.88,33.11,32.36,32.64,14578900,32.64
+2005-09-19,33.27,33.47,32.25,32.75,15429900,32.75
+2005-09-16,33.74,33.77,33.05,33.17,20858300,33.17
+2005-09-15,33.95,33.99,33.50,33.57,10404800,33.57
+2005-09-14,34.30,34.50,33.64,33.80,15017400,33.80
+2005-09-13,33.93,34.71,33.73,34.30,19346600,34.30
+2005-09-12,33.42,34.34,33.41,33.91,18580300,33.91
+2005-09-09,33.35,33.60,33.02,33.46,15247900,33.46
+2005-09-08,33.74,33.93,33.20,33.34,17464400,33.34
+2005-09-07,33.50,34.26,33.30,34.06,12545300,34.06
+2005-09-06,33.18,33.78,33.18,33.68,12513300,33.68
+2005-09-02,33.20,33.37,33.10,33.17,6849000,33.17
+2005-09-01,33.28,33.51,33.04,33.24,11848500,33.24
+2005-08-31,33.23,33.39,32.99,33.32,13035500,33.32
+2005-08-30,33.50,33.67,33.00,33.18,13496000,33.18
+2005-08-29,33.40,33.78,33.31,33.68,11427600,33.68
+2005-08-26,33.51,33.81,33.38,33.57,9833400,33.57
+2005-08-25,33.54,33.62,33.20,33.48,12564900,33.48
+2005-08-24,32.92,33.68,32.88,33.47,23249500,33.47
+2005-08-23,33.29,33.33,32.65,33.11,16912700,33.11
+2005-08-22,34.07,34.10,33.07,33.20,21054400,33.20
+2005-08-19,34.39,34.47,33.98,34.00,12810400,34.00
+2005-08-18,34.13,34.73,34.12,34.36,12154200,34.36
+2005-08-17,34.30,34.73,34.23,34.39,10443700,34.39
+2005-08-16,34.57,34.66,34.21,34.23,11867100,34.23
+2005-08-15,34.80,34.87,34.49,34.60,11244500,34.60
+2005-08-12,34.86,34.88,34.45,34.60,13306100,34.60
+2005-08-11,34.54,35.00,34.32,34.94,22391900,34.94
+2005-08-10,34.28,34.77,34.00,34.19,18047900,34.19
+2005-08-09,34.15,34.32,33.91,34.06,9987400,34.06
+2005-08-08,33.86,34.18,33.66,33.94,13066200,33.94
+2005-08-05,34.09,34.28,33.49,33.52,11873800,33.52
+2005-08-04,34.26,34.60,34.00,34.06,11143400,34.06
+2005-08-03,33.75,34.68,33.73,34.51,18240600,34.51
+2005-08-02,33.46,34.20,33.39,33.88,17581900,33.88
+2005-08-01,33.63,33.69,33.31,33.33,12637100,33.33
+2005-07-29,34.01,34.06,33.34,33.34,16236100,33.34
+2005-07-28,34.23,34.31,33.98,34.01,11871600,34.01
+2005-07-27,34.22,34.37,33.95,34.29,20497500,34.29
+2005-07-26,34.05,34.30,33.91,34.15,16819200,34.15
+2005-07-25,33.88,34.08,33.59,33.85,23252600,33.85
+2005-07-22,33.35,33.77,33.17,33.53,27561500,33.53
+2005-07-21,33.75,33.76,32.75,32.94,37778500,32.94
+2005-07-20,34.21,34.35,33.31,33.40,82623300,33.40
+2005-07-19,37.02,38.02,36.56,37.73,32685500,37.73
+2005-07-18,36.45,36.78,36.37,36.58,11019300,36.58
+2005-07-15,37.05,37.16,36.50,36.58,12372200,36.58
+2005-07-14,37.40,37.50,36.77,36.86,14722200,36.86
+2005-07-13,36.42,36.98,36.41,36.73,16897500,36.73
+2005-07-12,36.20,36.49,35.94,36.23,19665800,36.23
+2005-07-11,34.90,35.81,34.78,35.76,20233000,35.76
+2005-07-08,34.77,34.87,34.25,34.62,15515400,34.62
+2005-07-07,33.87,34.77,33.72,34.63,16354300,34.63
+2005-07-06,34.64,34.97,34.03,34.12,13585700,34.12
+2005-07-05,34.25,35.08,34.20,34.60,16086700,34.60
+2005-07-01,34.76,34.85,34.22,34.44,9861600,34.44
+2005-06-30,34.84,35.17,34.44,34.65,16699500,34.65
+2005-06-29,35.80,35.94,34.88,34.94,16481900,34.94
+2005-06-28,35.95,36.24,35.51,35.80,13346200,35.80
+2005-06-27,35.88,36.11,35.20,35.68,12044700,35.68
+2005-06-24,36.26,36.40,35.60,36.09,13468200,36.09
+2005-06-23,36.85,37.31,36.20,36.20,15547700,36.20
+2005-06-22,36.91,37.32,36.84,36.90,12148100,36.90
+2005-06-21,36.37,37.31,36.36,36.95,16219200,36.95
+2005-06-20,35.96,36.84,35.79,36.45,12753200,36.45
+2005-06-17,36.76,36.98,36.12,36.30,15952800,36.30
+2005-06-16,36.46,36.74,36.22,36.40,12228700,36.40
+2005-06-15,36.97,37.11,35.91,36.32,22753900,36.32
+2005-06-14,36.56,37.05,36.43,36.80,12781200,36.80
+2005-06-13,36.66,37.51,36.53,36.90,11586300,36.90
+2005-06-10,37.48,37.50,36.32,36.81,14216900,36.81
+2005-06-09,36.81,37.48,36.38,37.45,18455100,37.45
+2005-06-08,37.42,37.45,36.32,36.63,20121100,36.63
+2005-06-07,38.72,38.95,37.32,37.44,22848300,37.44
+2005-06-06,37.79,38.74,37.75,38.52,12416000,38.52
+2005-06-03,38.24,38.79,37.60,37.92,12813300,37.92
+2005-06-02,38.20,38.71,38.13,38.50,13150700,38.50
+2005-06-01,37.31,38.90,37.17,38.42,28153800,38.42
+2005-05-31,37.03,37.35,36.85,37.20,12498300,37.20
+2005-05-27,36.98,37.47,36.95,37.27,10256600,37.27
+2005-05-26,36.45,37.19,36.35,37.14,15547700,37.14
+2005-05-25,36.25,36.42,36.06,36.27,14995100,36.27
+2005-05-24,36.87,37.10,36.45,36.63,17421300,36.63
+2005-05-23,36.10,37.10,36.04,36.80,21616200,36.80
+2005-05-20,36.60,36.64,36.13,36.33,13771900,36.33
+2005-05-19,36.13,36.99,36.11,36.75,21267100,36.75
+2005-05-18,35.79,36.58,35.69,35.95,23769000,35.95
+2005-05-17,35.20,35.80,35.14,35.68,13178400,35.68
+2005-05-16,34.78,35.50,34.74,35.45,15473900,35.45
+2005-05-13,34.71,35.35,34.35,34.82,15855900,34.82
+2005-05-12,34.95,35.37,34.54,34.71,18906700,34.71
+2005-05-11,34.09,34.88,33.69,34.88,19537100,34.88
+2005-05-10,34.30,34.37,33.86,34.06,13227000,34.06
+2005-05-09,34.48,34.65,34.25,34.59,9991700,34.59
+2005-05-06,35.00,35.08,34.45,34.52,14202200,34.52
+2005-05-05,35.10,35.29,34.43,34.71,16926300,34.71
+2005-05-04,34.43,35.50,34.38,35.18,23410900,35.18
+2005-05-03,34.05,34.60,33.90,34.28,22042800,34.28
+2005-05-02,34.44,34.85,34.03,34.38,13231500,34.38
+2005-04-29,34.60,34.75,33.92,34.50,15666100,34.50
+2005-04-28,34.70,34.93,34.02,34.33,16159300,34.33
+2005-04-27,34.70,35.14,34.59,34.95,14861300,34.95
+2005-04-26,35.12,35.42,34.80,35.00,17921200,35.00
+2005-04-25,34.58,35.59,34.58,35.49,23883600,35.49
+2005-04-22,35.21,35.88,34.50,34.87,31869800,34.87
+2005-04-21,35.12,35.91,34.71,35.87,27731600,35.87
+2005-04-20,34.96,35.25,34.36,34.65,50104400,34.65
+2005-04-19,32.96,33.33,32.42,33.22,34158500,33.22
+2005-04-18,32.43,33.09,32.40,32.55,19201200,32.55
+2005-04-15,32.96,33.41,32.29,32.46,27008500,32.46
+2005-04-14,33.63,34.20,33.40,33.46,19855300,33.46
+2005-04-13,34.16,34.46,33.40,33.60,16886100,33.60
+2005-04-12,34.35,34.50,33.74,34.28,22681900,34.28
+2005-04-11,34.97,35.09,34.54,34.60,11758500,34.60
+2005-04-08,35.04,35.14,34.65,34.76,11106300,34.76
+2005-04-07,34.45,35.25,34.45,35.07,20575000,35.07
+2005-04-06,35.14,35.42,34.12,34.49,23574000,34.49
+2005-04-05,35.15,35.40,34.84,35.15,20275900,35.15
+2005-04-04,34.34,35.27,33.75,35.07,27853300,35.07
+2005-04-01,34.18,34.77,34.15,34.28,27955400,34.28
+2005-03-31,33.55,34.20,33.20,33.90,25390000,33.90
+2005-03-30,32.31,33.60,32.27,33.48,28267900,33.48
+2005-03-29,32.18,32.84,31.79,32.16,23544700,32.16
+2005-03-28,32.21,32.50,32.10,32.25,20624400,32.25
+2005-03-24,31.94,32.09,31.41,31.41,23162000,31.41
+2005-03-23,30.91,31.33,30.85,30.87,13917100,30.87
+2005-03-22,31.70,31.98,30.86,30.99,19570600,30.99
+2005-03-21,31.29,31.77,30.98,31.62,18449400,31.62
+2005-03-18,31.53,31.73,30.91,31.11,20796400,31.11
+2005-03-17,31.80,31.98,31.54,31.61,13760200,31.61
+2005-03-16,31.87,32.35,31.40,31.58,17952000,31.58
+2005-03-15,31.61,32.28,31.53,31.94,20880800,31.94
+2005-03-14,31.74,31.83,30.65,31.32,19762000,31.32
+2005-03-11,31.86,32.21,31.65,31.65,13364800,31.65
+2005-03-10,32.43,32.56,31.60,31.91,19381200,31.91
+2005-03-09,33.01,33.15,32.01,32.32,21824400,32.32
+2005-03-08,33.55,33.73,33.14,33.16,17839300,33.16
+2005-03-07,32.40,33.31,32.36,33.09,17679200,33.09
+2005-03-04,32.36,32.57,31.76,32.36,17499800,32.36
+2005-03-03,32.25,32.48,31.80,32.31,17896100,32.31
+2005-03-02,32.07,32.60,31.75,32.23,15357200,32.23
+2005-03-01,32.37,32.67,32.05,32.30,20222500,32.30
+2005-02-28,31.74,33.77,31.62,32.27,25266400,32.27
+2005-02-25,31.53,31.96,31.43,31.73,20114900,31.73
+2005-02-24,30.43,31.49,30.30,31.48,55457300,31.48
+2005-02-23,32.82,32.92,31.40,32.12,34757100,32.12
+2005-02-22,33.25,33.82,32.66,32.79,18142600,32.79
+2005-02-18,33.84,33.98,33.38,33.60,12436100,33.60
+2005-02-17,34.42,34.79,33.76,33.82,16203500,33.82
+2005-02-16,33.81,34.82,33.75,34.42,22176200,34.42
+2005-02-15,34.34,34.92,33.81,33.98,20391900,33.98
+2005-02-14,34.01,34.41,33.78,34.33,20065300,34.33
+2005-02-11,33.45,34.70,33.31,34.15,20005800,34.15
+2005-02-10,33.72,33.72,32.47,33.44,32637400,33.44
+2005-02-09,34.60,34.66,33.45,33.59,18285100,33.59
+2005-02-08,34.64,34.91,34.32,34.36,17321500,34.36
+2005-02-07,35.07,35.19,34.36,34.47,14588900,34.47
+2005-02-04,34.71,35.30,34.71,35.02,16850200,35.02
+2005-02-03,35.27,35.67,35.00,35.09,16742400,35.09
+2005-02-02,36.02,36.34,35.29,35.54,33495200,35.54
+2005-02-01,35.13,35.28,34.46,34.75,18633600,34.75
+2005-01-31,35.04,35.44,34.53,35.21,20712200,35.21
+2005-01-28,34.90,35.24,34.12,34.62,17853700,34.62
+2005-01-27,35.38,35.49,34.35,34.73,21450800,34.73
+2005-01-26,34.71,35.74,34.39,35.47,25767500,35.47
+2005-01-25,34.55,34.76,33.94,34.04,26521400,34.04
+2005-01-24,35.48,35.52,33.75,33.93,31477400,33.93
+2005-01-21,36.07,36.11,35.29,35.30,26608000,35.30
+2005-01-20,35.39,36.42,35.05,35.78,30239100,35.78
+2005-01-19,38.08,38.20,36.42,36.45,44303200,36.45
+2005-01-18,37.10,37.46,36.60,37.18,42709600,37.18
+2005-01-14,35.86,36.70,35.83,36.70,27697700,36.70
+2005-01-13,36.12,36.32,35.26,35.33,18526500,35.33
+2005-01-12,35.88,36.18,34.80,36.14,23274700,36.14
+2005-01-11,36.31,36.58,35.39,35.66,19711900,35.66
+2005-01-10,36.00,36.76,35.51,36.32,17482800,36.32
+2005-01-07,35.99,36.46,35.41,35.96,18596300,35.96
+2005-01-06,36.32,36.50,35.21,35.43,20835300,35.43
+2005-01-05,36.69,36.98,36.06,36.13,18469100,36.13
+2005-01-04,38.45,38.54,36.46,36.58,26625300,36.58
+2005-01-03,38.36,38.90,37.65,38.18,25482800,38.18
diff --git a/dojox/charting/tests/BidiSupport/mirror_ChartAxisTitle.html b/dojox/charting/tests/BidiSupport/mirror_ChartAxisTitle.html
new file mode 100644
index 0000000..6e2b8d7
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_ChartAxisTitle.html
@@ -0,0 +1,192 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Chart2D Title</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			
+			.axisTitleRotation90 {
+				transform: rotate(90deg);
+				-o-transform: rotate(90deg);
+				-webkit-transform: rotate(90deg);
+				-moz-transform: rotate(90deg);
+			}
+			.axisTitleRotation180 {
+				transform: rotate(180deg);
+				-o-transform: rotate(180deg);
+				-webkit-transform: rotate(180deg);
+				-moz-transform: rotate(180deg);
+			}
+			.axisTitleRotation270 {
+				transform: rotate(-90deg);
+				-o-transform: rotate(-90deg);
+				-webkit-transform: rotate(-90deg);
+				-moz-transform: rotate(-90deg);
+			}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+			<script type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("doh.runner");
+
+			dojo.require("dojox.charting.Chart");
+			dojo.require("dojox.charting.axis2d.Default");
+			dojo.require("dojox.charting.plot2d.Lines");
+			dojo.require("dojox.charting.plot2d.Markers");
+			dojo.require("dojox.charting.plot2d.Columns");
+			dojo.require("dojox.charting.themes.PlotKit.blue");
+			dojo.require("dojox.charting.themes.PlotKit.cyan");
+			dojo.require("dojox.charting.themes.PlotKit.green");
+			dojo.require("dojox.charting.themes.PlotKit.orange");
+			dojo.require("dojox.charting.themes.PlotKit.purple");
+			dojo.require("dojox.charting.themes.PlotKit.red");
+			dojo.require("dijit.form.Button");
+			dojo.require("dijit.form.NumberSpinner");
+
+			var chart1;
+
+			var updateAxis = function(){
+				var gap = dijit.byId("axisTitleGap").get("value"),
+					rotation = dijit.byId("rotation").get("value"),
+					orientation = dojo.byId("orientation").value || "axis";
+				chart1.addAxis("x", {
+							title: "Quarter \u05dc\u05e9\u05e0\u05ea 2010.",
+							titleGap: gap, 
+							titleFontColor: "orange",
+							titleOrientation: orientation,
+							rotation: rotation,
+							includeZero: true, natural: true, fixLower: "major", fixUpper: "major", 
+							labels: [
+								{value: 0, text: ""},{value: 1, text: "1 Qtr"},{value: 2, text: "2 Qtr"},
+								{value: 3, text: "3 Qtr."},{value: 4, text: "\u05e8\u05d1\u05e2\u05d5\u05df 4."},{value: 5, text: "End."}
+							]
+						}).
+						addAxis("y", {
+							title: "\u05ea\u05e9\u05d5\u05d0\u05d4 \u0028\u05d1\u05de\u05dc\u05d9\u05d5\u05e0\u05d9\u05dd\u0029.", 
+							titleGap: gap, 
+							titleFontColor: "orange",
+							titleOrientation: orientation,
+							rotation: rotation,
+							vertical: true, includeZero: true, natural: true, fixLower: "major", fixUpper: "major", majorTickStep: 2,
+							labels: [
+								{value: 0, text: ""},{value: 1, text: "One."},{value: 2, text: "\u05e9\u05ea\u05d9\u05d9\u05dd."},
+								{value: 3, text: "My name: \u05d8\u05dc."},{value: 4, text: "\u05e7\u05d5\u05e8\u05d0\u05d9\u05dd\u0020\u05dc\u05d9: Tal."},{value: 5, text: "Five"},{value: 6, text: "Six"}
+							]
+						}).
+						addAxis("x2", {
+							title: "\u05e8\u05d1\u05e2\u05d5\u05df of 2010.",
+							titleGap: gap, 
+							titleFontColor: "blue",
+							titleOrientation: orientation,
+							rotation: rotation,
+							leftBottom: false,
+							includeZero: true, natural: true, fixLower: "major", fixUpper: "major"
+						}).
+						addAxis("y2", {
+							title: "Quantity(ton).", 
+							titleGap: gap, 
+							titleFontColor: "blue",
+							titleOrientation: orientation,
+							rotation: rotation,
+							leftBottom: false,
+							vertical: true, includeZero: true, natural: true, fixLower: "major", fixUpper: "major", majorTickStep: 2
+						}).
+						setDir("rtl").
+						render();
+			};
+
+			makeObjects = function(){
+				chart1 = new dojox.charting.Chart("test1",{textDir:"auto",title:"\u05d0\u05e0\u05d9\u0020\u05db\u05d5\u05ea\u05e8\u05ea of the chart."
+					, titleFontColor: "blue"}).
+					addPlot("default", {type: "Lines"}).
+					addSeries("Series A", [3, 5, 3, 4, 2], {stroke: {color: "orange"}, fill: "yellow"}).
+					addPlot("default2", {type: "Columns", gap: 15, hAxis: "x2", vAxis: "y2"}).
+					addSeries("Series B", [12, 8, 15, 20], {plot: "default2", stroke: {color: "blue"}, fill: "lightblue"});
+				updateAxis();
+
+				var chart2 = new dojox.charting.Chart("test2",{title:"\u05d0\u05e0\u05d9\u0020\u05db\u05d5\u05ea\u05e8\u05ea of the chart."
+					, titleFontColor: "blue"
+					, titlePos: "bottom"
+					, titleFont: "normal normal normal 15pt Arial"
+				}).
+					addAxis("x", {
+						title: "\u05d7\u05d5\u05d3\u05e9 of 2010.", 
+						titleGap: 20, 
+						titleFont: "normal normal normal 10pt Arial",
+						titleFontColor: "green",
+						titleOrientation: "away",
+						rotation: 30,
+						includeZero: true, natural: true, fixLower: "major", fixUpper: "major", 
+						labels: [
+							{value: 0, text: ""},{value: 1, text: "\u05d9\u05e0\u05d5\u05d0\u05e8."},{value: 2, text: "Feb."},
+							{value: 3, text: "\u05de\u05e8\u05e5."},{value: 4, text: "Aprl."},{value: 5, text: "May."}
+						]
+					}).
+					addAxis("y", {
+						title: "Production(Quantity).", 
+						titleGap: 15, 
+						titleFont: "normal normal normal 10pt Arial",
+						titleFontColor: "orange",
+						titleOrientation: "axis",
+						vertical: true, includeZero: true, natural: true,
+						fixLower: "major", fixUpper: "major", majorTickStep: 30000
+					}).
+					addPlot("default", {type: "Markers"}).
+					addSeries("Series A", [200000, 80000, 120000, 140000, 150000], {stroke: {color: "red"}, fill: "lightpink"}).
+					addSeries("Series B", [30000, 60000, 90000, 120000, 200000], {stroke: {color: "blue"}, fill: "lightblue"}).
+					setDir("rtl").
+					render();
+			};
+
+			dojo.addOnLoad(function(){
+				makeObjects();
+
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
+	
+				doh.run();
+			});
+
+		</script>
+	</head>
+	<body class="tundra">
+	<h1>Chart2D Titles</h1>
+	<p>Column chart with axis title peeeep</p>
+	<p>
+		Axis Title Gap: 
+		<input dojoType="dijit.form.NumberSpinner" id="axisTitleGap" value="15" constraints="{min: 0, max: 50, fractional: false}" style="width: 8em;">
+		  
+		Axis Rotation
+		<input dojoType="dijit.form.NumberSpinner" id="rotation" value="0" constraints="{min: 0, max: 360, fractional: false}" style="width: 8em;">
+		     
+		<select id="orientation">
+			<option value="axis">axis title facing the axis</option>
+			<option value="away">axis title facing away</option>
+		</select>
+		     
+		<button dojoType="dijit.form.Button" onClick="updateAxis()">Apply</button>
+	</p>
+	     
+	<h2>Line chart, textDir = auto</h2>
+	<div id="test1" style="width: 500px; height: 400px;"></div>
+	<h2>Line chart, default textDir (inherited from UI)</h2>
+	<div id="test2" style="width: 500px; height: 400px;"></div>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_DataSeries.html b/dojox/charting/tests/BidiSupport/mirror_DataSeries.html
new file mode 100644
index 0000000..5078281
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_DataSeries.html
@@ -0,0 +1,237 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>DataSeries Test</title>
+
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../../dijit/themes/dijit.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			
+			#spinners{
+				clear:both;
+			}
+			#spinners label{
+				width:60px;
+				line-height:30px;
+				margin-top:10px;
+			}
+			.tundra #spinners .dijitSpinner	{
+				width:70px !important;
+				margin:5px !important;
+			}
+			.tundra #spinners .dijitSpinner{
+				width:80px !important;
+			}
+			.dijitSpinner{
+				padding:0px !important;
+			}
+			#spinners .dijitSpinnerButtonContainer{
+				line-height:23px;
+			}
+			.dj_ie #spinners .dijitSpinnerButtonContainer{
+				height:25px;
+			}
+			.dijitInputLayoutContainer .dijitInputField input{
+				padding:5px 0px 0px 5px;
+			}
+			.dj_webkit .dijitInputLayoutContainer .dijitInputField input{
+				padding:10px 0px 0px 5px;
+			}
+
+			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px;}
+			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+			
+			#charts {
+				clear: both;
+				margin-bottom: 50px;
+			}
+			.chart-area {
+				float: left;
+				border: 1px solid #ccc;
+				width:  450px;
+				height: 350px;
+				margin: 3px;
+			}
+			.chart {
+				width:  450px;
+				height: 300px;
+			}
+		</style>
+
+		<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug: false, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script>
+			dojo.require("dojo.parser");
+			dojo.require("doh.runner");
+			
+			dojo.require("dojox.charting.Chart2D");
+			dojo.require("dojox.charting.DataSeries");
+			dojo.require("dojox.charting.themes.ThreeD");
+			dojo.require("dojox.charting.widget.Legend");
+			
+			dojo.require("dojox.charting.plot2d.Markers");
+			dojo.require("dojox.charting.plot2d.Columns");
+			dojo.require("dojox.charting.plot2d.Pie");
+			
+			dojo.require("dojox.charting.action2d.Tooltip");
+			dojo.require("dojox.charting.action2d.MoveSlice");
+			dojo.require("dojox.charting.action2d.Magnify");
+			dojo.require("dojox.charting.action2d.Shake");
+
+			dojo.require("dojo.data.ItemFileWriteStore");
+
+			dojo.require("dijit.form.NumberSpinner");
+			
+			var store = new dojo.data.ItemFileWriteStore({url: "stockHebrew.json"});
+			
+			function addLegend(chart, node){
+				var legend = new dojox.charting.widget.Legend({chart: chart}, node);
+				dojo.connect(chart, "render", legend, "refresh");
+			}
+			
+			var templates = {
+				low:   "<strong>{0}</strong>: <strong>low {1}</strong> – {2} – {3}",
+				price: "<span dir='ltr'><strong>{0}</strong>: {1} – <strong>price {2}</strong> – {3}</span>",
+				high:  "<strong>{0}</strong>: {1} – {2} – <strong>high {3}</strong>"
+			};
+			
+			function valTrans(value, store, item){
+				return {
+					y: store.getValue(item, value),
+					tooltip: dojo.replace(
+						templates[value],
+						dojo.map(["symbol", "low", "price", "high"], function(field){
+							return store.getValue(item, field);
+						})
+					)
+				};
+			}
+			
+			var chartL, chartC, chartP;
+			
+			makeCharts = function(){
+				chartL = new dojox.charting.Chart2D("lines",{textDir:"auto", dir:"rtl"}).
+						setTheme(dojox.charting.themes.ThreeD).
+						addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 5}).
+						addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
+						addPlot("default", {type: dojox.charting.plot2d.Markers}).
+						addSeries("Price.", new dojox.charting.DataSeries(
+							store, {query: {symbol: "*"}}, "price")).
+						setDir("rtl").
+						render();
+				addLegend(chartL, "lines_legend");
+				new dojox.charting.action2d.Magnify(chartL);
+				new dojox.charting.action2d.Tooltip(chartL);
+
+				chartC = new dojox.charting.Chart2D("cols",{textDir:"rtl"}).
+						setTheme(dojox.charting.themes.ThreeD).
+						addAxis("x", {natural: true}).
+						addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
+						addPlot("default", {type: dojox.charting.plot2d.Columns}).
+						addSeries("Low.", new dojox.charting.DataSeries(
+							store, {query: {symbol: "*"}}, dojo.hitch(null, valTrans, "low"))).
+						addSeries("\u05de\u05d7\u05d9\u05e8.", new dojox.charting.DataSeries(
+							store, {query: {symbol: "*"}}, dojo.hitch(null, valTrans, "price"))).
+						addSeries("High.", new dojox.charting.DataSeries(
+							store, {query: {symbol: "*"}}, dojo.hitch(null, valTrans, "high"))).
+						setDir("rtl").
+						render();
+				addLegend(chartC, "cols_legend");
+				new dojox.charting.action2d.Shake(chartC, "default", {shiftY: 0});
+				new dojox.charting.action2d.Tooltip(chartC);
+				
+				chartP = new dojox.charting.Chart2D("pie",{textDir:"auto",htmlLabels:true}).
+						setTheme(dojox.charting.themes.ThreeD).
+						addPlot("default", {type: dojox.charting.plot2d.Pie, radius: 125}).
+						addSeries("Price", new dojox.charting.DataSeries(
+							store, {query: {symbol: "*"}}, {y: "price", text: "symbol", tooltip: "price"})).
+							setDir("rtl").
+						render();
+				addLegend(chartP, "pie_legend");
+				new dojox.charting.action2d.Tooltip(chartP);
+				new dojox.charting.action2d.MoveSlice(chartP);
+			};
+
+			makeSpinners = function(items){
+				dojo.forEach(items, function(m){
+					var nm = store.getLabel(m);
+					var num = store.getValue(m, "price");
+					console.log(nm, num);
+					var w = new dijit.form.NumberSpinner({
+						onChange: function(val){
+							val = val===0 ? 0.01 : val; //HACKS the no label-when-zero bug
+							console.log("OC:", nm, val);
+							store.setValue(m, "price", val);
+							//store.setValues(m, "historicPrice", store.getValues("historicPrice").push(val));
+							console.log("OC:", nm, val);
+						},
+						value: num,
+						constraints: {min:0, max:10,places:2},
+						className: "myField",
+						intermediateChanges: true
+					});
+					dojo.place('<label>'+nm+'</label>', dojo.byId("spinners"), "last")
+					dojo.place(w.domNode, "spinners", "last")
+				});
+				
+				var labels = dojo.map(items, function(item, index){
+						return {
+							value: index + 1,
+							text:  store.getLabel(item)
+						}
+					});
+				chartC.addAxis("x", {natural: true, labels: labels}).render();
+			}
+
+			dojo.addOnLoad(function(){
+				makeCharts();
+				store.fetch({query:{symbol:"*"}, onComplete: makeSpinners, onError:function(err){console.error(err)}})
+
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
+
+				doh.run();
+			});
+		</script>
+
+	</head>
+
+	<body class="tundra" dir ="ltr">
+		<h1>DataSeries Test</h1>
+		<p>
+			Use the spinner fields at the bottom to change the data. The charts listen to store changes an update automatically.
+		</p>
+		<div id="charts">
+			<div class="chart-area">
+				<div id="lines_legend"></div>
+				<div id="lines" class="chart"></div>
+			</div>
+			<div class="chart-area" data-dojo-textdir="rtl">
+				<div id="cols_legend"></div>
+				<div id="cols" class="chart"></div>
+			</div>	
+			<div class="chart-area">
+				<div id="pie_legend"></div>
+				<div id="pie" class="chart"></div>
+			</div>
+		</div>
+		<div id="spinners"></div>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_DeclerativeChart.html b/dojox/charting/tests/BidiSupport/mirror_DeclerativeChart.html
new file mode 100644
index 0000000..ea380e2
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_DeclerativeChart.html
@@ -0,0 +1,105 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Chart 2D</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../../dijit/themes/tundra/tundra.css">
+		<style>
+			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
+			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("doh.runner");
+
+			dojo.require("dijit.dijit");
+            dojo.require("dojox.charting.widget.Chart");
+            dojo.require("dojox.charting.axis2d.Default");
+            dojo.require("dojox.charting.plot2d.Areas");
+            dojo.require("dojox.charting.plot2d.Grid");
+            dojo.require("dojox.charting.action2d.Tooltip");
+			dojo.require("dojox.charting.widget.Legend");
+			dojo.require("dojox.data.HtmlStore");
+			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+			
+			seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
+
+			dojo.addOnLoad(function(){
+
+				doh.register("test textDir", [
+					{
+						name: "Declarative chart",
+
+						runTest: function(){
+							var node = dojo.byId("chart1");
+							var chart = dijit.byNode(node);
+							doh.is("rtl", chart.textDir, "textDir of : chart");
+
+						}
+					}	
+				]);		
+				
+				doh.run();
+			});
+			
+		</script>
+
+	</head>
+	<body class="tundra">
+		<h1>Chart 2D</h1>
+		<p>Examples of charts using widgets.</p>
+		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" data-dojo-id="tableStore"></div>
+		<table id="tableExample" style="display: none;">
+			<thead>
+				<tr><th>value</th></tr>
+			</thead>
+			<tbody>
+				<tr><td>6.3</td></tr>
+				<tr><td>1.8</td></tr>
+				<tr><td>3  </td></tr>
+				<tr><td>0.5</td></tr>
+				<tr><td>4.4</td></tr>
+				<tr><td>2.7</td></tr>
+				<tr><td>2  </td></tr>
+			</tbody>
+		</table>
+		<table border="0" cellspacing="30">
+			<tr>
+				<td>
+					<div dojoType="dojox.charting.widget.Chart" id="chart1" textDir="rtl" style="width: 500px; height: 500px;" direction="rtl">
+						<div class="axis" name="x" title="קוראים לי ציר X." titleOrientation= "away" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" title="קוראים לי ציר Y." vertical="true" fixUpper="major" includeZero="true" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Areas"></div>
+						<div class="plot" name="grid" type="Grid"></div>
+						<div class="series" name="סדרה 1." data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+						<div class="series" name="Run B." array="seriesB" ></div>
+						<div class="series" name="Run C." store="tableStore" valueFn="Number(x)"></div>
+					</div>
+					<div dojoType="dojox.charting.widget.Legend" chartRef="chart1"></div>
+				</td>
+			</tr>
+		</table>
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_Event2d.html b/dojox/charting/tests/BidiSupport/mirror_Event2d.html
new file mode 100644
index 0000000..6ba4b1d
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_Event2d.html
@@ -0,0 +1,251 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Event 2D</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../../dijit/themes/claro/claro.css">
+		<style>
+			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
+			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+			<script type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("doh.runner");
+
+			dojo.require("dojox.charting.Chart");
+			dojo.require("dojox.charting.axis2d.Default");
+			dojo.require("dojox.charting.plot2d.Default");
+			dojo.require("dojox.charting.plot2d.Columns");
+			dojo.require("dojox.charting.plot2d.ClusteredColumns");
+			dojo.require("dojox.charting.plot2d.Bars");
+			dojo.require("dojox.charting.plot2d.Bubble");
+			dojo.require("dojox.charting.plot2d.Grid");
+			dojo.require("dojox.charting.plot2d.Pie");
+
+			dojo.require("dojox.charting.themes.PlotKit.green");
+
+			dojo.require("dojox.charting.action2d.Highlight");
+			dojo.require("dojox.charting.action2d.Magnify");
+			dojo.require("dojox.charting.action2d.MoveSlice");
+			dojo.require("dojox.charting.action2d.Shake");
+			dojo.require("dojox.charting.action2d.Tooltip");
+
+			dojo.require("dojox.charting.widget.Legend");
+
+			dojo.require("dojo.colors");
+			dojo.require("dojo.fx.easing");
+
+			var dc = dojox.charting;
+
+			var dur = 450;
+
+			var chart1, legend1, chart3, legend3, chart6, legend6, chart9, legend9,
+				chart10, legend10;
+			
+			makeObjects = function(){
+				chart1 = new dc.Chart("test1",{textDir:"rtl", title:"\u05d6\u05d4\u05d5\u0020\u05ea\u05e8\u05e9\u05d9\u05dd\u0020\u05de\u05d4\u05de\u05dd."});
+				chart1.setTheme(dc.themes.PlotKit.green);
+				chart1.addPlot("default", {type: "Default", lines: true, markers: true, tension:2});
+				chart1.addAxis("x", {min: 0, max: 6, majorTick: {stroke: "black", length: 3}, minorTick: {stroke: "gray", length: 3}
+					, labels: [
+						//{value: 0, text: "zero"},
+						{value: 2, text: "\u05e9\u05ea\u05d9\u05d9\u05dd."},
+						{value: 4, text: "four."}
+					]
+					, title:"\u05e6\u05d9\u05e8 x."
+					, titleGap: 20
+					, titleFont: "normal normal normal 10pt Arial"
+					, titleOrientation: "away"
+				});
+				chart1.addAxis("y", {vertical: true, min: 0, max: 10, majorTick: {stroke: "black", length: 3}, minorTick: {stroke: "gray", length: 3}, title:"\u05e6\u05d9\u05e8 y."});
+				chart1.addSeries("\u05e1\u05d3\u05e8\u05d4\u0020\u05d0\u0027.", [{x: 0.5,value:"Name." ,y: 5, tooltip:"My name is \u05e8\u05d1\u05e7\u05d4\u0020\u05d1\u05ea\u0020\u05de\u05e9\u05d4."}, {x: 1.5, y: 1.5, tooltip:"\u05e7\u05d5\u05e8\u05d0\u05d9\u05dd\u0020\u05dc\u05d9 Dvora."}, {x: 2, y: 9, tooltip:"My name is \u05e8\u05d1\u05e7\u05d4\u0020\u05d1\u05ea\u0020\u05de\u05e9\u05d4."}, {x: 5, y: 0.3, tooltip:"\u05e7\u05d5\u05e8\u05d0\u05d9\u05dd\u0020\u05dc\u05d9 Dvora."}]);
+				chart1.addSeries("Series B.", [{x: 0.3, y: 8, tooltip:"My name is \u05e8\u05d1\u05e7\u05d4\u0020\u05d1\u05ea\u0020\u05de\u05e9\u05d4."}, {x: 4, y: 6, tooltip: "Custom tooltip"}, {x: 5.5, y: 2, tooltip:"\u05e7\u05d5\u05e8\u05d0\u05d9\u05dd\u0020\u05dc\u05d9 Dvora."}]);
+				var anim1a = new dc.action2d.Magnify(chart1, "default");
+				var anim1b = new dc.action2d.Tooltip(chart1, "default");
+				chart1.setDir("rtl");
+				chart1.render();
+				legend1 = new dojox.charting.widget.Legend({chart: chart1, horizontal: false}, "legend1");
+
+				chart3 = new dc.Chart("test3",{textDir:"auto", title:"\u05d6\u05d4\u05d5\u0020\u05ea\u05e8\u05e9\u05d9\u05dd\u0020\u05de\u05d4\u05de\u05dd."});
+				chart3.setTheme(dc.themes.PlotKit.green);
+				chart3.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major",
+					labels: [
+						{value: 1, text: "one."},
+						{value: 2, text: "\u05e9\u05ea\u05d9\u05d9\u05dd."},
+						{value: 4, text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."}
+					]	
+				});
+				chart3.addPlot("default", {type: "Columns", gap: 2, htmlLabels:false});
+				chart3.addSeries("\u05e1\u05d3\u05e8\u05d4\u0020\u05d0\u0027.", [1, 2, 3, 4, 5], {stroke: {color: "black"}, fill: "red"});
+				chart3.addSeries("Series B.", [{y:5, tooltip:"My name is \u05e8\u05d1\u05e7\u05d4\u0020\u05d1\u05ea\u0020\u05de\u05e9\u05d4."}, {y:4, tooltip:"My name is \u05e8\u05d1\u05e7\u05d4\u0020\u05d1\u05ea\u0020\u05de\u05e9\u05d4."}, {y:3, tooltip:"My name is \u05e8\u05d1\u05e7\u05d4\u0020\u05d1\u05ea\u0020\u05de\u05e9\u05d4."}, {y:2, tooltip:"My name is \u05e8\u05d1\u05e7\u05d4\u0020\u05d1\u05ea\u0020\u05de\u05e9\u05d4."}, {y:1, tooltip:"My name is \u05e8\u05d1\u05e7\u05d4\u0020\u05d1\u05ea\ [...]
+				var anim3a = new dc.action2d.Highlight(chart3, "default");
+				var anim3b = new dc.action2d.Tooltip(chart3, "default");
+				chart3.setDir("rtl");
+				chart3.render();
+				legend3 = new dojox.charting.widget.Legend({chart: chart3, horizontal: false}, "legend3");
+
+				chart6 = new dc.Chart("test6",{title:"\u05d6\u05d4\u05d5\u0020\u05ea\u05e8\u05e9\u05d9\u05dd\u0020\u05de\u05d4\u05de\u05dd.",textDir:"auto"});
+				chart6.setTheme(dc.themes.PlotKit.green);
+				chart6.addAxis("x",{
+					labels: [
+						//{value: 0, text: "zero"},
+						{value: 2, text: "\u05e9\u05ea\u05d9\u05d9\u05dd."},
+						{value: 4, text: "four."}
+					]
+					, title:"\u05e6\u05d9\u05e8 x."
+					, titleGap: 20
+					, titleFont: "normal normal normal 10pt Arial"
+					, titleOrientation: "away"
+			});
+				chart6.addAxis("y", {vertical: true,
+					labels: [
+						{value: 1, text: "one."},
+						{value: 2, text: "\u05e9\u05ea\u05d9\u05d9\u05dd."},
+						{value: 4, text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."}
+					],
+					title:"\u05e6\u05d9\u05e8 y."
+
+				
+			});
+				chart6.addPlot("default", {type: "ClusteredColumns", gap: 10});
+				chart6.addPlot("grid", {type: "Grid"});
+				chart6.addSeries("\u05e1\u05d3\u05e8\u05d4\u0020\u05d0\u0027.", [{y:2, tooltip:"I work at \u05d9\u05d1\u05de in Israel."}, {y:1, tooltip:"I work at \u05d9\u05d1\u05de in Israel."}, {y:0.5, tooltip:"I work at \u05d9\u05d1\u05de in Israel."},{y: -1, tooltip:"I work at \u05d9\u05d1\u05de in Israel."},{y: -2,tooltip:"\u05d0\u05e0\u05d9\u0020\u05e2\u05d5\u05d1\u05d3\u05ea\u0020\u05d1\u002d IBM \u05d9\u05e9\u05e8\u05d0\u05dc."}], {stroke: {color: "black"}, fill: "red"});
+				chart6.addSeries("Series B.", [{y: -2,tooltip:"\u05d0\u05e0\u05d9\u0020\u05e2\u05d5\u05d1\u05d3\u05ea\u0020\u05d1\u002d IBM \u05d9\u05e9\u05e8\u05d0\u05dc."}, {y:-1,tooltip:"\u05d0\u05e0\u05d9\u0020\u05e2\u05d5\u05d1\u05d3\u05ea\u0020\u05d1\u002d IBM \u05d9\u05e9\u05e8\u05d0\u05dc."}, {y:-0.5,tooltip:"\u05d0\u05e0\u05d9\u0020\u05e2\u05d5\u05d1\u05d3\u05ea\u0020\u05d1\u002d IBM \u05d9\u05e9\u05e8\u05d0\u05dc."}, {y:1,tooltip:"\u05d0\u05e0\u05d9\u0020\u05e2\u05d5\u05d1\u05d3\u05ea\u002 [...]
+				chart6.addSeries("Series C", [1, 0.5, -1, -2, -3], {stroke: {color: "black"}, fill: "green"});
+				var anim6a = new dc.action2d.Highlight(chart6, "default", {
+					duration: dur,
+					easing:   dojo.fx.easing.sineOut
+				});
+				var anim6b = new dc.action2d.Shake(chart6, "default");
+				var anim6c = new dc.action2d.Tooltip(chart6, "default");
+				chart6.setDir("rtl");
+				chart6.render();
+				legend6 = new dojox.charting.widget.Legend({chart: chart6}, "legend6");
+
+				chart9 = new dc.Chart("test9", {textDir:"", title:"This is some \u05ea\u05e8\u05e9\u05d9\u05dd."});
+				chart9.setTheme(dc.themes.PlotKit.green);
+				chart9.addPlot("default", {type: "Bubble", shadows: {dx: 2, dy: 2, dw: 2}});
+				chart9.addAxis("x", {min: 0, max: 6, majorTick: {stroke: "black", length: 3}, minorTick: {stroke: "gray", length: 3},
+					labels: [
+						{value: 1, text: "one."},
+						{value: 2, text: "\u05e9\u05ea\u05d9\u05d9\u05dd."},
+						{value: 4, text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."}
+					]	});
+				chart9.addAxis("y", {vertical: true, min: 0, max: 10, majorTick: {stroke: "black", length: 3}, minorTick: {stroke: "gray", length: 3},
+					labels: [
+						{value: 1, text: "one."},
+						{value: 2, text: "\u05e9\u05ea\u05d9\u05d9\u05dd."},
+						{value: 4, text: "\u05d4\u05ea\u05d7\u05dc\u05d4 end."}
+					]	});
+				chart9.addSeries("\u05e1\u05d3\u05e8\u05d4\u0020\u05d0\u0027.", [{x: 0.5, y: 5, size: 1.4}, {x: 1.5, y: 1.5, size:4.5}, {x: 2, y: 9, size:1.5}, {x: 5, y: 0.3, size:0.8}],
+					{stroke: {color: "black"}, fill: "red"});
+				chart9.addSeries("Series B.", [{x: 0.3, y: 8, size: 2.5, tooltip:"My name is \u05e8\u05d1\u05e7\u05d4\u0020\u05d1\u05ea\u0020\u05de\u05e9\u05d4."}, {x: 4, y: 6, size:1.1, tooltip:"\u05d0\u05e0\u05d9\u0020\u05e2\u05d5\u05d1\u05d3\u05ea\u0020\u05d1\u002d IBM \u05d9\u05e9\u05e8\u05d0\u05dc."}, {x: 5.5, y: 2, size: 3.2, tooltip:"I work at \u05d9\u05d1\u05de in Israel."}],
+					{stroke: {color: "black"}, fill: "blue"});
+				var anim9a = new dc.action2d.Magnify(chart9, "default", {
+					scale: 1.1
+				});
+				var anim9b = new dc.action2d.Highlight(chart9, "default");
+				var anim9c = new dc.action2d.Tooltip(chart9, "default");
+				chart9.setDir("rtl");
+				chart9.render();
+				legend9 = new dojox.charting.widget.Legend({chart: chart9, horizontal: false}, "legend9");
+
+				chart10 = new dc.Chart("test10", {title:"Pie.",textDir:"rtl"});
+				chart10.setTheme(dc.themes.PlotKit.green);
+				chart10.addPlot("default", {
+					type: "Pie", 
+					font: "normal normal 11pt Tahoma", 
+					fontColor: "black", 
+					labelOffset: -30,
+					radius: 150,
+					startAngle: 45
+				});
+				chart10.addSeries("\u05e1\u05d3\u05e8\u05d4\u0020\u05d0\u0027.", [
+					{y: 4, text: "My color is - \u05d0\u05d3\u05d5\u05dd.",   color: "red",   stroke: "black", tooltip: "\u05d4\u05e6\u05d1\u05e2\u0020\u05e9\u05dc\u05d9\u0020\u05d4\u05d5\u05d0: red, \u05d5\u05d0\u05e0\u05d9\u0020\u05ea\u05d5\u05e4\u05e1 50% \u05de\u05d4\u05e2\u05d5\u05d2\u05d4!!!"},
+					{y: 2, text: "\u05d4\u05e6\u05d1\u05e2\u0020\u05e9\u05dc\u05d9\u0020\u05d4\u05d5\u05d0: green.", color: "green", stroke: "black", tooltip: "Green is \u05d4\u05e6\u05d1\u05e2\u0020\u05d4\u05d0\u05d4\u05d5\u05d1\u0020\u05e2\u05dc\u05d9, because that's the color of my team!!"},
+					{y: 1, text: "Blue.",  color: "blue",  stroke: "black", tooltip: "I am feeling Blue!"},
+					{y: 1, text: "Other.", color: "white", stroke: "black", tooltip: "Mighty <strong>\u05d7\u05d6\u05e7</strong><br>With two lines!"}
+				]);
+				var anim10a = new dc.action2d.MoveSlice(chart10, "default");
+				var anim10b = new dc.action2d.Highlight(chart10, "default");
+				var anim10c = new dc.action2d.Tooltip(chart10, "default");
+				chart10.setDir("rtl");
+				chart10.render();
+				legend10 = new dojox.charting.widget.Legend({chart: chart10}, "legend10");
+			};
+
+			dojo.addOnLoad(function(){
+				makeObjects();
+
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
+
+				doh.register("test textDir", [
+					{
+						name: "initial.",
+
+						runTest: function(){
+							doh.is("rtl", chart1.textDir, "textDir of : chart1");
+							doh.is("rtl", legend1.textDir, "textDir of : legend1");
+							
+							doh.is("auto", chart3.textDir, "textDir of : chart3");
+							doh.is("auto", legend3.textDir, "textDir of : legend3");
+							
+							doh.is("auto", chart6.textDir, "textDir of : chart6");
+							doh.is("auto", legend6.textDir, "textDir of : legend6");
+							
+							doh.is("ltr", chart9.textDir, "textDir of : chart9");
+							doh.is("ltr", legend9.textDir, "textDir of : legend9");
+							
+							doh.is("rtl", chart10.textDir, "textDir of : chart10");
+							doh.is("rtl", legend10.textDir, "textDir of : legend10");
+						}
+					}	
+				]);						
+				doh.run();
+			});
+
+		</script>
+	</head>
+	<body class="claro">
+	<h1>Event 2D</h1>
+	<!--<p><button onclick="makeObjects();">Go</button></p>-->
+	<p>Hover over markers, bars, columns, slices, and so on.</p>
+	<h2>1: textDir = "rtl"</h2>
+	<div id="test1" style="width: 500px; height: 300px;"></div>
+	<div id="legend1"></div>
+	<h2>2: textDir = "auto"</h2>
+	<div id="test3" style="width: 500px; height: 300px;"></div>
+	<div id="legend3"></div>
+	<h2>3: textDir = "auto"</h2>
+	<div id="test6" style="width: 500px; height: 300px;"></div>
+	<div id="legend6"></div>
+	<h2>4: textDir inherited from UI</h2>
+	<div id="test9" style="width: 500px; height: 300px;"></div>
+	<div id="legend9"></div>
+	<h2>5: textDir = "rtl"</h2>
+	<div id="test10" style="width: 500px; height: 500px;"></div>
+	<div id="legend10"></div>
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_Label_shortening.html b/dojox/charting/tests/BidiSupport/mirror_Label_shortening.html
new file mode 100644
index 0000000..b342b1c
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_Label_shortening.html
@@ -0,0 +1,234 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Chart 2D labels shortening</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+		<script type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("doh.runner");
+
+			dojo.require("dojox.charting.Chart");
+			dojo.require("dojox.charting.axis2d.Default");
+			dojo.require("dojox.charting.plot2d.Bars");
+			dojo.require("dojox.charting.plot2d.Columns");
+			dojo.require("dojox.charting.plot2d.Lines");
+			dojo.require("dojox.charting.plot2d.Areas");
+			dojo.require("dijit.Tooltip");
+
+			dojo.require("dijit.dijit");
+			dojo.require("dojox.charting.widget.Chart");
+			dojo.require("dojox.charting.plot2d.Grid");
+			dojo.require("dojox.charting.widget.Legend");
+			dojo.require("dojox.data.HtmlStore");
+
+			var seriesB = [260, 180, 200, 100, 140, 70, 200]
+				, chart1, chart2, chart3, chart4;
+			
+			makeObjects = function(){
+				chart1 = new dojox.charting.Chart("test1", {textDir:"auto"}).
+						addAxis("x", {
+							fixLower: "major", fixUpper: "major", includeZero: true, 
+							labels: [
+								{value: 0, text: "11111111111\u05d0."},
+								{value: 2, text: "\u05e9\u05ea\u05d9\u05d9\u05dd\u0020\u05e9\u05dc\u05d5\u05e9\u0020\u05d0\u05e8\u05d1\u05e2\u05e2\u05e2\u05e2."},
+								{value: 3, text: "11111111111\u05d0."},
+								{value: 5, text: "\u05d0."}
+							],
+							maxLabelSize: 20,
+							trailingSymbol: ".",
+							htmlLabels: true
+						}).
+						addAxis("y", {
+							vertical: true, fixLower: "major", fixUpper: "major", natural: true,
+							labels: [{value: 0, text: ""},
+								{value: 1, text: "\u05d9\u05e0\u05d5\u05d0\u05e8."}, {value: 2, text: "February."},
+								{value: 3, text: "March."}, {value: 4, text: "\u05d0\u05e4\u05e8\u05d9\u05dc."},
+								{value: 5, text: "May."}, {value: 6, text: "11111111111\u05d0."}
+							],
+							maxLabelSize: 20
+						}).
+						addPlot("default", {type: "Bars"}).
+						addSeries("Series A.", [1, 2, 3, 4, 5], {stroke: {color: "red"}, fill: "lightpink"}).
+						addSeries("Series B.", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"}).
+						setDir("rtl").
+						render();
+
+				chart2 = new dojox.charting.Chart("test2").
+						addAxis("x", {
+							fixLower: "major", fixUpper: "major", includeZero: true, 
+							labels: [
+								{value: 0, text: "first start point."},
+								{value: 2, text: "two."},
+								{value: 5, text: "111111111111111\u05d0."}
+							],
+							rotation: 180,
+							maxLabelSize: 30
+						}).
+						addAxis("y", {
+							vertical: true, fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 2,
+							labels: [{value: 0, text: ""},
+								{value: 1, text: "\u05d9\u05e0\u05d5\u05d0\u05e8."}, {value: 2, text: "February."},
+								{value: 3, text: "March."}, {value: 4, text: "\u05d0\u05e4\u05e8\u05d9\u05dc."},
+								{value: 5, text: "May."}, {value: 6, text: "June."}
+							],
+							rotation: -30,
+							maxLabelSize: 20
+						}).
+						addPlot("default", {type: "Columns"}).
+						addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "red"}, fill: "lightpink"}).
+						addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"}).
+						setDir("rtl").
+						render();
+						
+				chart3 = new dojox.charting.Chart("test3").
+						addAxis("x", {
+							fixLower: "major", fixUpper: "major", includeZero: true, 
+							labels: [
+								{value: 0, text: "first start point"},
+								{value: 2, text: "two"},
+								{value: 5, text: "1111111111111111111111111111\u05d0"}
+							],
+							maxLabelCharCount: 5
+						}).
+						addAxis("y", {
+							vertical: true, fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 2,
+							labels: [{value: 0, text: ""},
+								{value: 1, text: "\u05d9\u05e0\u05d5\u05d0\u05e8."}, {value: 2, text: "February."},
+								{value: 3, text: "March."}, {value: 4, text: "\u05d0\u05e4\u05e8\u05d9\u05dc."},
+								{value: 5, text: "May."}, {value: 6, text: "June."}
+							],
+							maxLabelCharCount: 2,
+							trailingSymbol: "__"
+						}).
+						addPlot("default", {type: "Lines"}).
+						addSeries("Series A.", [1, 2, 3, 4, 5], {stroke: {color: "red"}, fill: "lightpink"}).
+						addSeries("Series B.", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"}).
+						setDir("rtl").
+						render();
+						
+				chart4 = new dojox.charting.Chart("test4", {textDir:"rtl"}).
+						addAxis("x", {
+							fixLower: "major", fixUpper: "major", includeZero: true, 
+							labels: [
+								{value: 0, text: "\u05e8\u05d0\u05e9\u05d5\u05df\u0020\u05e9\u05e0\u05d9\u0020\u05e9\u05dc\u05d9\u05e9\u05d9\u05e9"},
+								{value: 2, text: "second middle point"},
+								{value: 5, text: "1111111111111111111111111111\u05d0."}
+							],
+							maxLabelCharCount: 20,
+							maxLabelSize: 30
+						}).
+						addAxis("y", {
+							vertical: true, fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 2,
+							labels: [{value: 0, text: ""},
+								{value: 1, text: "\u05d9\u05e0\u05d5\u05d0\u05e8"}, {value: 2, text: "February"},
+								{value: 3, text: "March"}, {value: 4, text: "\u05d0\u05e4\u05e8\u05d9\u05dc."},
+								{value: 5, text: "May"}, {value: 6, text: "June"}
+							],
+							maxLabelCharCount: 2,
+							maxLabelSize: 40
+						}).
+						addPlot("default", {type: "Areas"}).
+						addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "red"}, fill: "lightpink"}).
+						addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"}).
+						setDir("rtl").
+						render();
+			};
+
+			dojo.addOnLoad(function(){
+				makeObjects();
+				
+				doh.register("test textDir", [
+					{
+						name: "Pies textDir",
+
+						runTest: function(){
+							doh.is("auto", chart1.textDir, "textDir of : chart1");
+							doh.is("ltr", chart2.textDir, "textDir of : chart2");
+							doh.is("ltr", chart3.textDir, "textDir of : chart3");
+							doh.is("rtl", chart4.textDir, "textDir of : chart4");
+							
+							var node = dojo.byId("chart5");
+							var chart5 = dijit.byNode(node);
+							doh.is("auto", chart5.textDir, "textDir of : chart4");
+
+						}
+					}	
+				]);		
+
+				doh.run();
+			});
+
+		</script>
+	</head>
+	<body class="claro">
+		<h1>Chart 2D labels shortening</h1>
+		<h2>Hover on the truncated label(end with default trailing Symbol: "..." or your customized trailing symbols) you will see the whole label on tooltip</h2>
+		<h2>1: Label shortening.(x axis customized trailing Symbol)
+textDir = auto</h2>
+		<div id="test1" style="width: 300px; height: 200px;"></div>
+		<h2>2: Label shortening with rotation
+textDir inherited.</h2>
+		<div id="test2" style="width: 300px; height: 200px;"></div>
+		<h2>3: Label shortening with limited character.(y axis customized trailing Symbol)
+textDir inherited</h2>
+		<div id="test3" style="width: 300px; height: 200px;"></div>
+		<h2>4: Label shortening with both limited character and limited length in px
+textDir = rtl.</h2>
+		<div id="test4" style="width: 300px; height: 200px;"></div>
+		<h2>5: Label shortening for HTML declared chart
+textDir = auto.</h2>
+		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" data-dojo-id="tableStore"></div>
+		<table id="tableExample" style="display: none;">
+			<thead>
+				<tr><th>value</th></tr>
+			</thead>
+			<tbody>
+				<tr><td>350</td></tr>
+				<tr><td>275</td></tr>
+				<tr><td>350  </td></tr>
+				<tr><td>400</td></tr>
+				<tr><td>250</td></tr>
+				<tr><td>350</td></tr>
+				<tr><td>200  </td></tr>
+			</tbody>
+		</table>
+		<table border="0" cellspacing="30">
+			<tr>
+				<td>
+					<div dojoType="dojox.charting.widget.Chart" id="chart5" textDir="auto" style="width: 500px; height: 500px;" direction="rtl">
+						<div class="axis" name="x" maxLabelCharCount= 2 title="קוראים לי ציר X." titleOrientation= "away"  font="italic normal normal 8pt Tahoma" labels="[{value:1, text:'First.'},{value:2, text:'שתיים שלוש.'},{value:4, text:'111111111ת.'}]"></div>
+						<div class="axis" name="y" maxLabelCharCount= 2 title="קוראים לי ציר Y." vertical="true" fixUpper="major" includeZero="true" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Areas"></div>
+						<div class="plot" name="grid" type="Grid"></div>
+						<div class="series" name="סדרה 1." data="100, 200, 50, 15, 100, 28, 40"></div>
+						<div class="series" name="Run B." array="seriesB" ></div>
+						<div class="series" name="Run C." store="tableStore" valueFn="Number(x)"></div>
+					</div>
+					<div dojoType="dojox.charting.widget.Legend" chartRef="chart5"></div>
+				</td>
+			</tr>
+		</table>
+
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_Pie_smart_label.html b/dojox/charting/tests/BidiSupport/mirror_Pie_smart_label.html
new file mode 100644
index 0000000..3db7e60
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_Pie_smart_label.html
@@ -0,0 +1,169 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+        <title>Pie 2D: Smart Label</title>
+        <style type="text/css">
+        	@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+			@import "../../resources/Legend.css";
+        </style>
+        <script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, has:{'dojo-bidi': true}">
+        </script>
+        <script type="text/javascript">
+ 			dojo.require("dojo.parser");
+			dojo.require("doh.runner");
+
+			dojo.require("dojox.charting.Chart");
+            dojo.require("dojox.charting.plot2d.Pie");
+            dojo.require("dojox.charting.action2d.Highlight");
+            dojo.require("dojox.charting.action2d.MoveSlice");
+            dojo.require("dojox.charting.action2d.Tooltip");
+			dojo.require("dojox.charting.themes.Tom");
+            dojo.require("dojox.charting.widget.Legend");
+			
+            var pieChart = null;
+			var legend = null;
+            dojo.addOnLoad(function(){
+                var dc = dojox.charting;
+                pieChart = new dc.Chart("pieChart", {textDir:"rtl"});
+                pieChart.setTheme(dc.themes.Tom).addPlot("default", {
+                    type: "Pie",
+                    font: "normal normal 10pt Tahoma",
+					fontColor: "#ccc",
+					labelWiring: "#ccc",
+                    radius: 100,
+					labelStyle: "columns",
+					htmlLabels: true,
+					startAngle: -10
+                }).addSeries("Series A", [{
+                    y: 12.1,
+                    text: "The country is \u05e1\u05d9\u05df.",
+                    tooltip: "1,210 \u05de\u05dc\u05d9\u05d5\u05df."
+                },{
+                    y: 9.52,
+                    text: "\u05d4\u05de\u05d3\u05d9\u05e0\u05d4\u0020\u05d4\u05d9\u05d0 India.",
+                    tooltip: "952 million."
+                }, {
+                    y: 2.66,
+                    text: "\u05d0\u05e8\u05d4\u0022\u05d1.",
+                    tooltip: "266 \u05de\u05dc\u05d9\u05d5\u05df."
+                }, {
+                    y: 2.06,
+                    text: "Indonisia.",
+                    tooltip: "206 million."
+                }, {
+                    y: 1.63,
+                    text: "Brazil.",
+                    tooltip: "163 million."
+                },{
+                    y: 1.48,
+                    text: "Russian.",
+                    tooltip: "148 million."
+                },{
+                    y: 1.29,
+                    text: "Pakistan.",
+                    tooltip: "129 million."
+                },{
+                    y: 1.25,
+                    text: "Japan.",
+                    tooltip: "125 million."
+                },{
+                    y: 1.23,
+                    text: "Bangladesh.",
+                    tooltip: "123 million."
+                },{
+                    y: 1.04,
+                    text: "Nigeria.",
+                    tooltip: "104 million."
+                },{
+                    y: 0.96,
+                    text: "Mexico.",
+                    tooltip: "96 million."
+                },{
+                    y: 0.84,
+                    text: "Germany.",
+                    tooltip: "84 million."
+                },{
+                    y: 0.74,
+                    text: "Phillippines.",
+                    tooltip: "74 million."
+                },{
+                    y: 0.74,
+                    text: "Viet Nam.",
+                    tooltip: "74 million."
+                },{
+                    y: 0.66,
+                    text: "Iran.",
+                    tooltip: "66 million."
+                },{
+                    y: 0.64,
+                    text: "Egypt.",
+                    tooltip: "64 million."
+				}]);
+				var anim_b = new dc.action2d.Highlight(pieChart, "default");
+				var anim_c = new dc.action2d.Tooltip(pieChart, "default");
+				pieChart.setDir("rtl");
+				pieChart.render();
+				legend = new dojox.charting.widget.Legend({
+					chart: pieChart,
+					horizontal:false
+				}, "legend");
+
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
+
+				doh.register("test textDir", [
+					{
+						name: "Pies textDir",
+
+						runTest: function(){
+							doh.is("rtl", pieChart.textDir, "pieChart: internal labels");
+							doh.is("rtl", legend.textDir, "legend: external labels");
+						}
+					}	
+				]);		
+				
+				doh.run();
+				
+			});
+			function refreshChart(){
+				var newData = [];
+				for(var i = 0; i < 16; i++){
+					newData.push(Math.random()*10);
+				}
+				newData.sort(function(v1,v2){return v2 - v1});
+				pieChart.updateSeries("Series A", newData);
+				pieChart.setDir("rtl");
+				pieChart.render();
+				legend.refresh();
+			}
+        </script>
+    </head>
+    <body class="claro">
+    	<h1>Pie 2D: Smart Label</h1>
+		<p>Example of Pie chart using smart label:</p>
+        <div style="margin:20px">
+            <div id="pieChart" style="width: 470px; height: 350px; float:left;">
+            </div>
+            <div id="legend">
+            </div>
+        </div>
+		<button onclick="refreshChart()">Random Data Test</button>
+    </body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_Pies.html b/dojox/charting/tests/BidiSupport/mirror_Pies.html
new file mode 100644
index 0000000..90600ad
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_Pies.html
@@ -0,0 +1,124 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Pie 2D</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad:true, has:{'dojo-bidi': true}"></script>
+		<script type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("doh.runner");
+
+			dojo.require("dojox.charting.Chart");
+			dojo.require("dojox.charting.plot2d.Pie");
+			dojo.require("dojox.charting.themes.PlotKit.blue");
+			dojo.require("dojox.charting.themes.PlotKit.green");
+			dojo.require("dojox.charting.themes.PlotKit.red");
+			dojo.require("dojox.charting.themes.Adobebricks");
+			dojo.require("dojox.charting.themes.Algae");
+			dojo.require("dojox.charting.action2d.Tooltip");
+
+			var chart1, chart2, chart8;
+			makeObjects = function(){
+				chart1 = new dojox.charting.Chart("test1", {textDir:"rtl"});
+				chart1.setTheme(dojox.charting.themes.PlotKit.blue);
+				chart1.addPlot("default", {
+					type: "Pie",
+					font: "normal normal bold 12pt Tahoma",
+					fontColor: "black",
+					labelOffset: 40,
+					htmlLabels: false
+				});
+				chart1.addSeries("Series A", [{y: 4, text: "\u05e9\u05dc\u05d5\u05dd big world!"}, {y: 2, text: "Hello \u05e2\u05d5\u05dc\u05dd\u0020\u05d2\u05d3\u05d5\u05dc!"}, {y: 1, text: "Blue."}, {y: 1, text: "Other..."}]);
+				   new dojox.charting.action2d.Tooltip(chart1);
+			 
+				chart1.setDir("rtl");
+				chart1.render();
+
+				chart2 = new dojox.charting.Chart("test2", {textDir:"auto"});
+				chart2.setTheme(dojox.charting.themes.PlotKit.blue);
+				chart2.addPlot("default", {
+					type: "Pie",
+					font: "normal normal bold 12pt Tahoma",
+					fontColor: "black",
+					labelOffset: -25,
+					precision: 0,
+					radius: 100,
+					htmlLabels: false
+				});
+				chart2.addSeries("Series A", [{y: 4, text: "\u05e9\u05dc\u05d5\u05dd!"}, {y: 2, text: "Hello!"}, {y: 1, text: "Blue!"}, {y: 1, text: "Other!"}]);
+				chart2.setDir("rtl");
+				chart2.render();
+
+
+				chart8 = new dojox.charting.Chart("test8");
+				chart8.setTheme(dojox.charting.themes.Algae);
+				chart8.addPlot("default", {
+					type: "Pie",
+					font: "normal normal bold 12pt Tahoma",
+					fontColor: "white",
+					radius: 80,
+					htmlLabels: false
+				});
+				chart8.addSeries("Series A", [
+					{y: -1, text: "Red", color: "red"},
+					{y: 5, text: "\u05e9\u05dc\u05d5\u05dd!", color: "green"},
+					{y: 0, text: "Blue", color: "blue"},
+					{y: 0, text: "Other", color: "white", fontColor: "black"}
+				]);
+				chart8.setDir("rtl");
+				chart8.render();
+			};
+
+			dojo.addOnLoad(function(){
+				makeObjects();
+				
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
+
+				doh.register("test textDir", [
+					{
+						name: "Pies textDir",
+
+						runTest: function(){
+							doh.is("rtl", chart1.textDir, "chart1: internal labels");
+							doh.is("auto", chart2.textDir, "chart2: external labels");
+							doh.is("ltr", chart8.textDir, "chart8: Degenerated pie, textDir inherited");
+						}
+					}	
+				]);		
+
+				doh.run();
+			});
+		</script>
+	</head>
+	<body>
+		<h1>Pie 2D</h1>
+		<table border="1"><tr>
+			<td><p>1: Pie with internal labels.</p>
+				<div id="test1" style="width: 300px; height: 300px;"></div></td>
+			<td><p>2: Pie with external labels.</p>
+				<div id="test2" style="width: 300px; height: 300px;"></div></td>
+			<td><p>3: Degenerated pie with 1 positive elements (out of 5).</p>
+				<div id="test8" style="width: 200px; height: 200px;"></div></td>
+		</tr></table>
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_RotatedLabels.html b/dojox/charting/tests/BidiSupport/mirror_RotatedLabels.html
new file mode 100644
index 0000000..d4b9c3e
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_RotatedLabels.html
@@ -0,0 +1,121 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Chart 2D rotated labels</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+		<script type="text/javascript">
+			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+			dojo.require("doh.runner");
+
+			dojo.require("dijit.form.Button");
+			dojo.require("dijit.form.NumberSpinner");
+
+			dojo.require("dojox.charting.Chart");
+			dojo.require("dojox.charting.axis2d.Default");
+			dojo.require("dojox.charting.plot2d.Default");
+			dojo.require("dojox.charting.themes.PrimaryColors");
+
+			var chart;
+
+			makeObjects = function(){
+				chart = new dojox.charting.Chart("test1",{textDir:"rtl"}).
+					setTheme(dojox.charting.themes.PrimaryColors).
+					addPlot("default").
+					addSeries("Series A", [1, 3, 2, 5, 4]).
+					addPlot("default2", {hAxis: "x2", vAxis: "y2"}).
+					addSeries("Series B", [5, 3, 4, 1, 2], {plot: "default2"});
+				updateAxes();
+			 
+			};
+
+			 dojo.addOnLoad(function(){
+				makeObjects();
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
+				
+				doh.register("test textDir", [
+					{
+						name: "initial textDir of chart",
+
+						runTest: function(){
+							doh.is("rtl",chart.textDir, "direction of : chart");
+						}
+					}	
+				]);				
+					
+				doh.run();
+
+			});
+
+			updateAxes = function(){
+				var rotation = dijit.byId("rotation").get("value");
+				chart.
+					addAxis("x", {
+						htmlLabels: false, fixLower: "major", fixUpper: "major", min: 0, max: 6,
+						labels: [
+							{value: 0, text: "\u05d0\u05e4\u05e1."},
+							{value: 1, text: "one."},
+							{value: 2, text: "two."},
+							{value: 3, text: "three."},
+							{value: 4, text: "four."},
+							{value: 5, text: "five."},
+							{value: 6, text: "My Name is: \u05e9\u05dc\u05d2\u05d9\u05d4."}
+						],
+						rotation: rotation
+					}).
+					addAxis("y", {
+						htmlLabels: false, vertical: true, fixLower: "major", fixUpper: "major", natural: true,  min: 0, max: 6,
+						labels: [{value: 0, text: ""},
+							{value: 1, text: "\u05d9\u05e0\u05d5\u05d0\u05e8."}, {value: 2, text: "February."},
+							{value: 3, text: "March."}, {value: 4, text: "\u05d0\u05e4\u05e8\u05d9\u05dc."},
+							{value: 5, text: "May."}, {value: 6, text: "June."}
+						],
+						rotation: rotation
+					}).
+					addAxis("x2", {
+						htmlLabels: false, fixLower: "major", fixUpper: "major", min: 0, max: 6, leftBottom: false,
+						rotation: rotation
+					}).
+					addAxis("y2", {
+						htmlLabels: false, vertical: true, fixLower: "major", fixUpper: "major", min: 0, max: 6, leftBottom: false,
+						rotation: rotation
+					}).
+					setDir("rtl").
+					render();
+			}
+
+		</script>
+	</head>
+	<body class="tundra">
+	<h1>Chart 2D rotated labels</h1>
+	<!--<p><button onclick="makeObjects();">Go</button></p>-->
+	<p>
+		Rotation: 
+		<input dojoType="dijit.form.NumberSpinner" id="rotation" value="0" constraints="{min: 0, max: 360, fractional: false}" style="width: 8em;">
+		 
+		<button dojoType="dijit.form.Button" onClick="updateAxes()">Apply</button>
+	</p>
+	<div id="test1" style="width: 600px; height: 400px;"></div>
+	<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_SelectableLegend.html b/dojox/charting/tests/BidiSupport/mirror_SelectableLegend.html
new file mode 100644
index 0000000..e3d19fb
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_SelectableLegend.html
@@ -0,0 +1,209 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+        <title>Chart: Selectable Legend test</title>
+        <style type="text/css">
+            @import "../../../../dojo/resources/dojo.css";
+            @import "../../../../dijit/tests/css/dijitTests.css";
+            @import "../../../../dijit/themes/claro/claro.css";
+			@import "../../resources/Legend.css";
+        </style>
+        <style>
+			.bars{
+				width:300px;
+				height:200px;
+			}
+			.columns{
+				width:300px;
+				height:250px;
+			}
+			.pie {
+				width:500px;
+				height:300px;
+			}
+			.bubble{
+				width:320px;
+				height:300px;
+			}
+        </style>
+
+        <script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+        <script type="text/javascript">
+ 			dojo.require("dojo.parser");
+			dojo.require("doh.runner");
+
+			dojo.require("dijit.dijit");
+            dojo.require("dojox.charting.Chart");
+            dojo.require("dojox.charting.axis2d.Default");
+            dojo.require("dojox.charting.plot2d.Lines");
+            dojo.require("dojox.charting.plot2d.StackedAreas");
+            dojo.require("dojox.charting.plot2d.Bars");
+            dojo.require("dojox.charting.plot2d.ClusteredBars");
+            dojo.require("dojox.charting.plot2d.StackedBars");
+            dojo.require("dojox.charting.plot2d.Columns");
+            dojo.require("dojox.charting.plot2d.ClusteredColumns");
+            dojo.require("dojox.charting.plot2d.StackedColumns");
+            dojo.require("dojox.charting.plot2d.Bubble");
+            dojo.require("dojox.charting.plot2d.Pie");
+			dojo.require("dojox.charting.themes.MiamiNice");
+			dojo.require("dojox.charting.widget.SelectableLegend");
+			dojo.require("dojox.charting.action2d.Highlight");
+			
+			var bars;
+        	dojo.addOnLoad(function(){
+				 bars = new dojox.charting.Chart("bars").
+					setTheme(dojox.charting.themes.MiamiNice).
+					addPlot("default",{type: "Bars",gap:2}).
+					addAxis("x",{natural: true, includeZero: true}).
+					addAxis("y",{natural: true, vertical:true}).
+					addSeries("\u05e1\u05d9\u05df\u002e",[1,3,5,7,2,4,6]).
+					setDir("rtl").
+					render();
+				var barsLegend = new dojox.charting.widget.SelectableLegend({chart: bars},"barsLegend");
+								
+				var linesColumns = new dojox.charting.Chart("linesColumns", {textDir:"rtl"}).
+					setTheme(dojox.charting.themes.MiamiNice).
+					addPlot("lines",{type: "Lines",markers:true}).
+					addPlot("default",{type: "Columns",gap:2}).
+					addAxis("y",{natural: true, vertical:true,includeZero: true}).
+					addAxis("x",{natural: true,includeZero: true}).
+					addSeries("\u05e1\u05d9\u05df\u002e",[2,4,6,8,3,5,7]).
+					addSeries("India.",[1,3,5,7,2,4,6],{plot:"lines"}).
+					setDir("rtl").
+					render();
+				var linesColumnsLegend = new dojox.charting.widget.SelectableLegend({chart: linesColumns},"linesColumnsLegend");
+				
+				var pie = new dojox.charting.Chart("pie",{textDir:"auto"}).
+					setTheme(dojox.charting.themes.MiamiNice).
+					addPlot("default",{type:"Pie",radius:100,font: "normal normal 10pt Tahoma",htmlLabels:true,labelOffset:-20}).
+					addSeries("\u05d0\u05e3\u002e",[{
+	                    y: 12.1,
+	                    text: "\u05e1\u05d9\u05df\u002e"
+	                },{
+	                    y: 9.52,
+	                    text: "India."
+	                }, {
+	                    y: 2.66,
+	                    text: "USA."
+	                }, {
+	                    y: 2.06,
+	                    text: "Indonesia."
+	                }, {
+	                    y: 1.63,
+	                    text: "Brazil."
+	                },{
+	                    y: 1.48,
+	                    text: "Russian."
+	                },{
+	                    y: 1.29,
+	                    text: "Pakistan."
+	                },{
+	                    y: 1.25,
+	                    text: "Japan."
+	                }]).
+					setDir("rtl").
+					render();
+				var ainm = new dojox.charting.action2d.Highlight(pie,"default");
+				var pieLegend = new dojox.charting.widget.SelectableLegend({chart: pie,horizontal:false, outline: true},"pieLegend");
+				
+				var bubble = new dojox.charting.Chart("bubble").
+					setTheme(dojox.charting.themes.MiamiNice).
+					addPlot("default",{type:"Bubble"}).
+					addAxis("x",{natual:true, includeZero: true, max:7}).
+					addAxis("y",{natual:true, vertical: true, includeZero: true,max:10}).
+					addSeries("\u05e1\u05d9\u05df\u002e",[{x:3,y:5,size:1},{x:1,y:7,size:1},{x:4,y:2,size:3}]).
+					addSeries("India.",[{x:5,y:5,size:2},{x:2,y:3,size:4},{x:6,y:2,size:1}]).
+					addSeries("C.",[{x:2,y:7,size:3},{x:6,y:8,size:3}]).
+					setDir("rtl").
+					render();
+				var bubbleLegend = new dojox.charting.widget.SelectableLegend({chart: bubble, horizontal:false, outline:true},"bubbleLegend");
+
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
+
+				doh.register("test textDir", [
+					{
+						name: "textDir inherited",
+
+						runTest: function(){
+							doh.is("ltr", bars.textDir, "bars: inherited from GUI");
+							doh.is("rtl", bubble.textDir, "bubble inherited from html container");
+						}
+					},	
+					{
+						name: "textDir in constructor",
+
+						runTest: function(){
+							doh.is("rtl", linesColumns.textDir, "direction of : linesColumns");
+							doh.is("auto", pie.textDir, "direction of : pie");
+						}
+					},	
+					{
+						name: "textDir of legends",
+
+						runTest: function(){
+							doh.is(bars.textDir, barsLegend.textDir, "direction of : barsLegend");
+							doh.is(linesColumns.textDir, linesColumnsLegend.textDir, "direction of : linesColumnsLegend");
+							doh.is(bubble.textDir, bubbleLegend.textDir, "direction of : bubbleLegend");
+							doh.is(pie.textDir, pieLegend.textDir, "direction of : pieLegend");
+						}
+					}					
+				]);					
+				doh.run();
+			});
+        
+        </script>
+    </head>
+    <body class="claro">
+		<h1>Chart: Selectable Legend</h1>
+		<h3>Click the legends</h3>
+		<div style="clear:both;">
+		<div style="float:left;">
+		<h2>1.Bars</h2>
+		<div id="bars" class="bars"></div>
+		<div id="barsLegend"></div>
+		</div>
+		<div style="float:left;">
+		
+		
+		<div style="float:left;">
+		<h2>2.Lines&Columns</h2>
+		<div id="linesColumns" class="columns"></div>
+		<div id="linesColumnsLegend"></div>
+		</div>
+		</div>
+		
+		<div style="clear:both;">
+		<div style="float:left;">
+		<h2>3.Pie</h2>
+		<div id="pie" class="pie" style="float:left;" ></div>
+		<div style="float:left;">
+		<div id="pieLegend"></div>
+		</div>
+		</div>
+		<div style="float:left;margin-left:40px">
+		<h2>4.Bubble</h2>
+		<div id="bubble" class="bubble" style="float:left;" dir="rtl"></div>
+		<div style="float:left;">
+		<div id="bubbleLegend"></div>
+		</div>
+		</div>
+		</div>
+
+    </body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_SetTextDir.html b/dojox/charting/tests/BidiSupport/mirror_SetTextDir.html
new file mode 100644
index 0000000..1d18f6e
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_SetTextDir.html
@@ -0,0 +1,353 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Chart2D Title</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			@import "../../resources/Legend.css";
+
+			
+			.axisTitleRotation90 {
+				transform: rotate(90deg);
+				-o-transform: rotate(90deg);
+				-webkit-transform: rotate(90deg);
+				-moz-transform: rotate(90deg);
+			}
+			.axisTitleRotation180 {
+				transform: rotate(180deg);
+				-o-transform: rotate(180deg);
+				-webkit-transform: rotate(180deg);
+				-moz-transform: rotate(180deg);
+			}
+			.axisTitleRotation270 {
+				transform: rotate(-90deg);
+				-o-transform: rotate(-90deg);
+				-webkit-transform: rotate(-90deg);
+				-moz-transform: rotate(-90deg);
+			}
+			.pie {
+				width:500px;
+				height:500px;
+			}
+
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+		<script type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("doh.runner");
+
+			dojo.require("dojox.charting.Chart");
+			dojo.require("dojox.charting.axis2d.Default");
+			dojo.require("dojox.charting.plot2d.Lines");
+			dojo.require("dojox.charting.plot2d.Columns");
+			dojo.require("dojox.charting.themes.PlotKit.orange");
+			dojo.require("dojox.charting.action2d.Shake");
+			dojo.require("dojox.charting.action2d.Tooltip");
+			dojo.require("dojox.charting.widget.SelectableLegend");
+
+			dojo.require("dijit.dijit");
+			dojo.require("dojox.charting.widget.Chart");
+			dojo.require("dojox.charting.plot2d.Grid");
+			dojo.require("dojox.data.HtmlStore");
+			dojo.require("dojox.charting.plot2d.Areas");
+ 			dojo.require("dojox.charting.widget.Legend");
+			
+			dojo.require("dojox.charting.plot2d.Pie");
+			dojo.require("dojox.charting.themes.MiamiNice");
+			dojo.require("dojox.charting.action2d.Highlight");
+
+
+			dojo.require("dijit.form.NumberSpinner");
+			dojo.require("dojo.parser");
+
+			var chart1, legend1, pie, pieLegend;
+			seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
+
+			updateAxis = function(){
+				var gap = 25,
+					rotation = 0,
+					orientation = "away";
+				chart1.addAxis("x", {
+							title: "Quarter \u05dc\u05e9\u05e0\u05ea 2010.",
+							titleGap: gap, 
+							titleFontColor: "orange",
+							titleOrientation: orientation,
+							rotation: rotation,
+							includeZero: true, natural: true, fixLower: "major", fixUpper: "major", 
+							labels: [
+								{value: 0, text: ""},{value: 1, text: "1 Qtr."},{value: 2, text: "2 Qtr."},
+								{value: 3, text: "3 Qtr."},{value: 4, text: "\u05e8\u05d1\u05e2\u05d5\u05df 4."},{value: 5, text: "End."}
+							]
+						}).
+						addAxis("y", {
+							title: "\u05ea\u05e9\u05d5\u05d0\u05d4 \u0028\u05d1\u05de\u05dc\u05d9\u05d5\u05e0\u05d9\u05dd\u0029.", 
+							titleGap: gap, 
+							titleFontColor: "orange",
+							titleOrientation: orientation,
+							rotation: rotation,
+							vertical: true, includeZero: true, natural: true, fixLower: "major", fixUpper: "major", majorTickStep: 2,
+							labels: [
+								{value: 0, text: ""},{value: 1, text: "One."},{value: 2, text: "\u05e9\u05ea\u05d9\u05d9\u05dd."},
+								{value: 3, text: "My name: \u05d8\u05dc."},{value: 4, text: "\u05e7\u05d5\u05e8\u05d0\u05d9\u05dd\u0020\u05dc\u05d9: Tal."},{value: 5, text: "Five."},{value: 6, text: "Six."}
+							]
+						}).
+						addAxis("x2", {
+							title: "\u05e8\u05d1\u05e2\u05d5\u05df of 2010.",
+							titleGap: gap, 
+							titleFontColor: "blue",
+							titleOrientation: orientation,
+							rotation: rotation,
+							leftBottom: false,
+							includeZero: true, natural: true, fixLower: "major", fixUpper: "major"
+						}).
+						addAxis("y2", {
+							title: "Quantity(ton).", 
+							titleGap: gap, 
+							titleFontColor: "blue",
+							titleOrientation: orientation,
+							rotation: rotation,
+							leftBottom: false,
+							vertical: true, includeZero: true, natural: true, fixLower: "major", fixUpper: "major", majorTickStep: 2
+						});
+						var anim6b = new dojox.charting.action2d.Shake(chart1, "default2");
+						var anim6c = new dojox.charting.action2d.Tooltip(chart1, "default2");
+						chart1.setDir("rtl");
+						chart1.render();
+						legend1 = new dojox.charting.widget.SelectableLegend({chart: chart1}, "legend1");
+
+
+					};
+
+			makeObjects = function(){
+				chart1 = new dojox.charting.Chart("test1",{textDir:"auto",title:"\u05d0\u05e0\u05d9\u0020\u05db\u05d5\u05ea\u05e8\u05ea of the chart."
+					, titleFontColor: "blue"}).
+					addPlot("default", {type: "Lines"}).
+					addSeries("\u05e1\u05d3\u05e8\u05d4\u0020\u05d0\u0027.", [3, 5, 3, 4, 2], {stroke: {color: "orange"}, fill: "yellow"}).//[{x:3}, {x:5}, {x:3}, {x:4}, {x:2}], {stroke: {color: "orange"}, fill: "yellow"}).
+					addPlot("default2", {type: "Columns", gap: 15, hAxis: "x2", vAxis: "y2"}).
+					addSeries("Series B.", [{y:12,tooltip:"I'm working at \u05d9\u05d1\u05de in Israel."}, {y:8,tooltip:"\u05d0\u05e0\u05d9\u0020\u05e2\u05d5\u05d1\u05d3\u05ea\u0020\u05d1- IBM \u05d9\u05e9\u05e8\u05d0\u05dc."}, {y:15,tooltip:"I'm working at \u05d9\u05d1\u05de in Israel."}, {y:20,tooltip:"\u05d0\u05e0\u05d9\u0020\u05e2\u05d5\u05d1\u05d3\u05ea\u0020\u05d1- IBM \u05d9\u05e9\u05e8\u05d0\u05dc."}], {plot: "default2", stroke: {color: "blue"}, fill: "lightblue"});
+				updateAxis();
+						pie = new dojox.charting.Chart("pie",{textDir:"rtl"}).
+							setTheme(dojox.charting.themes.MiamiNice).
+							addPlot("default",{type:"Pie",radius:100,font: "normal normal 10pt Tahoma",htmlLabels:true,labelOffset:-20}).
+							addSeries("\u05d0\u05e3\u002e",[{
+								y: 12.1,
+								text: "\u05e1\u05d9\u05df\u002e"
+							},{
+								y: 9.52,
+								text: "India."
+							}, {
+								y: 2.66,
+								text: "USA."
+							}, {
+								y: 2.06,
+								text: "Indonesia."
+							}, {
+								y: 1.63,
+								text: "Brazil."
+							},{
+								y: 1.48,
+								text: "Russian."
+							},{
+								y: 1.29,
+								text: "Pakistan."
+							},{
+								y: 1.25,
+								text: "Japan."
+							}]).
+							setDir("rtl").
+							render();
+						var ainm = new dojox.charting.action2d.Highlight(pie,"default");
+						pieLegend = new dojox.charting.widget.SelectableLegend({chart: pie,horizontal:false, outline: true},"pieLegend");
+			};
+
+			dojo.addOnLoad(function(){
+				makeObjects();
+
+				var buttonRtl
+					, buttonLtr
+					, buttonAuto
+					, chart5
+					, legend5;
+					
+				doh.register("test dynamic change of textDir.", [
+					{
+						name: "initial textDir of the chart",
+
+						setUp: function(){
+							buttonRtl = dojo.byId("buttonRtl");
+							buttonLtr = dojo.byId("buttonLtr");
+							buttonAuto = dojo.byId("buttonAuto");
+							chart5 = dijit.byId('chart5');
+							legend5 = dijit.byId('legend5');
+						},
+						
+						runTest: function(){
+							doh.is("auto", chart1.textDir, "textDir of : chart1");
+							doh.is("auto", chart1.surface.textDir, "textDir of : chart1.surface");
+							doh.is("auto", legend1.textDir, "textDir of : legend1");
+
+							doh.is("rtl", pie.textDir, "textDir of : pie");
+							doh.is("rtl", pie.surface.textDir, "textDir of : pie.surface");
+							doh.is("rtl", pieLegend.textDir, "textDir of : pieLegend");
+
+							doh.is("ltr", chart5.textDir, "textDir of : chart5");
+							doh.is("ltr", chart5.chart.textDir, "textDir of : chart5");
+							doh.is("ltr", chart5.chart.surface.textDir, "textDir of : chart5.surface");
+							doh.is("ltr", legend5.textDir, "textDir of : legend5");
+							
+						}
+					},
+					{
+						name: "set textDir to RTL.",
+
+						runTest: function(){
+							buttonRtl.click();
+							doh.is("rtl", chart1.textDir, "textDir of : chart");
+							doh.is("rtl", chart1.surface.textDir, "textDir of : chart");
+							doh.is("rtl", legend1.textDir, "textDir of : legend1");
+
+							doh.is("rtl", pie.textDir, "textDir of : pie");
+							doh.is("rtl", pie.surface.textDir, "textDir of : pie.surface");
+							doh.is("rtl", pieLegend.textDir, "textDir of : pieLegend");
+
+							doh.is("rtl", chart5.textDir, "textDir of : chart5");
+							doh.is("rtl", chart5.chart.textDir, "textDir of : chart5");
+							doh.is("rtl", chart5.chart.surface.textDir, "textDir of : chart5.surface");
+							doh.is("rtl", legend5.textDir, "textDir of : legend5");
+
+						}
+					},
+					{
+						name: "set textDir to LTR.",
+
+						runTest: function(){
+							buttonLtr.click();
+							doh.is("ltr", chart1.textDir, "textDir of : chart");
+							doh.is("ltr", chart1.surface.textDir, "textDir of : chart");
+							doh.is("ltr", legend1.textDir, "textDir of : legend1");
+
+							doh.is("ltr", pie.textDir, "textDir of : pie");
+							doh.is("ltr", pie.surface.textDir, "textDir of : pie.surface");
+							doh.is("ltr", pieLegend.textDir, "textDir of : pieLegend");
+
+							doh.is("ltr", chart5.textDir, "textDir of : chart5");
+							doh.is("ltr", chart5.chart.textDir, "textDir of : chart5");
+							doh.is("ltr", chart5.chart.surface.textDir, "textDir of : chart5.surface");
+							doh.is("ltr", legend5.textDir, "textDir of : legend5");
+						}
+					},
+					{
+						name: "set textDir to AUTO.",
+
+						runTest: function(){
+							buttonAuto.click();
+							doh.is("auto", chart1.textDir, "textDir of : chart");
+							doh.is("auto", chart1.surface.textDir, "textDir of : chart");
+							doh.is("auto", legend1.textDir, "textDir of : legend1");
+
+							doh.is("auto", pie.textDir, "textDir of : pie");
+							doh.is("auto", pie.surface.textDir, "textDir of : pie.surface");
+							doh.is("auto", pieLegend.textDir, "textDir of : pieLegend");
+
+							doh.is("auto", chart5.textDir, "textDir of : chart5");
+							doh.is("auto", chart5.chart.textDir, "textDir of : chart5");
+							doh.is("auto", chart5.chart.surface.textDir, "textDir of : chart5.surface");
+							doh.is("auto", legend5.textDir, "textDir of : legend5");
+						}
+					}					
+					
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Chart2D Titles</h1>
+		<p>Column chart with axis title</p>
+		<p>
+		<input id="buttonRtl" 
+			onClick="
+				chart1.setTextDir('rtl'); 
+				dijit.byId('chart5').set('textDir','rtl');
+				pie.setTextDir('rtl');
+			" 
+			type="button" value="RTL"/>
+		<input id="buttonLtr" 
+			onClick="
+				chart1.setTextDir('ltr'); 
+				dijit.byId('chart5').set('textDir','ltr');
+				pie.setTextDir('ltr');
+			" 
+			type="button" value="LTR"/>
+		<input id="buttonAuto" 
+			onClick="
+				chart1.setTextDir('auto'); 
+				dijit.byId('chart5').set('textDir','auto');
+				pie.setTextDir('auto');
+			" 
+			type="button" value="AUTO"/>
+			
+		  
+
+		<h2>Programmatically created chart.</h2>
+		<div id="legend1"></div>
+		<p/>
+		<div id="test1" style="width: 600px; height: 400px;"></div>
+		  
+
+		<h2>HTML declared chart.</h2>
+		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" data-dojo-id="tableStore"></div>
+		<table id="tableExample" style="display: none;">
+			<thead>
+				<tr><th>value</th></tr>
+			</thead>
+			<tbody>
+				<tr><td >6.3</td></tr>
+				<tr><td>1.8</td></tr>
+				<tr><td>3  </td></tr>
+				<tr><td>0.5</td></tr>
+				<tr><td>4.4</td></tr>
+				<tr><td>2.7</td></tr>
+				<tr><td>2  </td></tr>
+			</tbody>
+		</table>
+		<table border="0" cellspacing="30">
+			<tr>
+				<td>
+					<div dojoType="dojox.charting.widget.Chart" id="chart5" textDir="ltr" style="width: 600px; height: 400px;" direction="rtl">
+						<div class="axis" name="x" maxLabelCharCount= 2 title="קוראים לי ציר X." titleOrientation= "away"  font="italic normal normal 8pt Tahoma" labels="[{value:1, text:'First.'},{value:2, text:'שתיים שלוש.'},{value:4, text:'444444444444ש.'}]"></div>
+						<div class="axis" name="y" maxLabelCharCount= 2 title="קוראים לי ציר Y." vertical="true" fixUpper="major" includeZero="true" labels="[{value:2, text:'שתיים שלוש.'},{value:3, text:'Third.'},{value:4, text:'444444444444ש.'}]"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Areas"></div>
+						<div class="plot" name="grid" type="Grid"></div>
+						<div class="series" name="סדרה 1." data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+						<div class="series" name="Run B." array="seriesB" ></div>
+						<div class="series" name="Run C." store="tableStore" valueFn="Number(x)"></div>
+					</div>
+					<div id="legend5" dojoType="dojox.charting.widget.Legend" chartRef="chart5"></div>
+				</td>
+			</tr>
+		</table>
+		<h2>3.Pie</h2>
+		<div id="pie" class="pie" style="float:left;"></div>
+		<div style="float:left;">
+		<div id="pieLegend"></div>
+		
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_Spider2d.html b/dojox/charting/tests/BidiSupport/mirror_Spider2d.html
new file mode 100644
index 0000000..1b84477
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_Spider2d.html
@@ -0,0 +1,272 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Spider 2D</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+			@import "../../resources/Legend.css";
+			
+			.dojoxLegendItem{
+				padding: 3px 5px 2px 5px;
+			}
+			.dojoxLegendItem .dojoxLegendText{
+				float: right;
+				margin-top: 2px;
+			}
+			.dojoxLegendItem .dojoxLegendIcon{
+				float: left;
+			}
+			.dojoxLegendItemRtl{
+				padding: 3px 5px 2px 5px;
+			}
+			.dojoxLegendItemRtl .dojoxLegendText{
+				float: left;
+				margin-top: 2px;
+			}
+			.dojoxLegendItemRtl .dojoxLegendIcon{
+				float: right;
+			}
+			.dojoxLegendHover{
+				background-color: #afd9ff;
+				cursor: pointer;
+				padding: 3px 5px 2px 5px;
+			}
+			.dojoxLegendActive{
+				cursor: pointer;
+				border: 2px solid #7dbefa;
+				padding: 1px 3px 0 3px;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+		<script type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("doh.runner");
+
+			dojo.require("dojox.charting.Chart");
+			dojo.require("dojox.charting.plot2d.Spider");
+			dojo.require("dojox.charting.themes.PlotKit.blue");
+			dojo.require("dijit.form.CheckBox");
+			dojo.require("dijit.form.RadioButton");
+			dojo.require("dijit.form.Form");
+			dojo.require("dojo.fx.easing");
+			dojo.require("dojox.gfx.fx");
+			dojo.require("dojox.charting.widget.SelectableLegend");
+
+			var dc = dojox.charting,
+				divisions = 7,
+				stype = "polygon",
+				easing = dojo.fx.easing.backOut;
+			var empty = {};
+			var populateSelect = function(from, select){
+				var module = dojo.getObject(from);
+				for(var name in module){
+					if(name in empty){ continue; }
+					var fun = module[name];
+					if(dojo.isFunction(fun)){
+						dojo.create("option", {
+							value:     from + "." + name,
+							selected:  name == "backOut",
+							innerHTML: from + "." + name
+						}, select);
+					}
+				}
+			};
+			
+			var chart1, legend1;
+			makeObjects = function(){
+				chart1 = new dojox.charting.Chart("test1",{textDir:"rtl"});
+				chart1.setTheme(dojox.charting.themes.PlotKit.blue);
+				chart1.addPlot("default", {
+					type: "Spider",
+					labelOffset: -10,
+					divisions: divisions,
+					axisColor:      "lightgray",
+					spiderColor:    "silver",
+					seriesFillAlpha: 0.2,
+					spiderOrigin:	 0.16,
+					markerSize:  	 3,
+					precision:		 0,
+					spiderType:	 	 stype
+				});
+				chart1.addSeries("China.", {data: {"GDP.": 2,"area.": 6,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 2000,"inflation.": 15,"growth.": 12}}, { fill: "blue" });
+				chart1.addSeries("\u05e6\u05e8\u05e4\u05ea.", {data: {"GDP.": 6,"area.": 15,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 500,"inflation.": 5,"growth.": 6}}, { fill: "red" });
+				chart1.addSeries("USA.", {data: {"GDP.": 3,"area.": 20,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 1500,"inflation.": 10,"growth.": 3}}, { fill: "green" });
+				chart1.addSeries("Start \u05e1\u05d5\u05e3.", {data: {"GDP.": 4,"area.": 2,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 1000,"inflation.": 20,"growth.": 2}}, { fill: "yellow" });
+				chart1.addSeries("\u05d4\u05ea\u05d7\u05dc\u05d4 end.", {data: {"GDP.": 10,"area.": 10,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 800,"inflation.": 2,"growth.": 18}}, { fill: "orange" });
+				chart1.addSeries("Canada.", {data: {"GDP.": 1,"area.": 18,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 300,"inflation.": 3,"growth.": 15}}, { fill: "purple" });
+				chart1.setDir("rtl");
+				chart1.render();
+				
+				legend1 = new dc.widget.SelectableLegend({chart: chart1, horizontal: true}, "legend1");
+				
+				// prepare and enable controls
+				populateSelect("dojo.fx.easing", "easing");
+			};
+			
+			dojo.addOnLoad(function(){
+				makeObjects();
+
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
+
+				doh.register("test textDir", [
+					{
+						name: "Spider chart and legend.",
+
+						runTest: function(){
+							doh.is("rtl", chart1.textDir, "textDir of : chart1");
+							doh.is("rtl", legend1.textDir, "textDir of : legend1");
+
+						}
+					}	
+				]);		
+
+				doh.run();
+				
+			});
+
+		</script>
+
+		<script type="text/javascript">
+			function switchData(val){
+				if(val == "b1"){
+					chart1.updateSeries("China", {data: {"GDP.": 2,"area.": 6,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 2000,"inflation.": 15,"growth.": 12}}, { fill: "blue" });
+					chart1.updateSeries("\u05e6\u05e8\u05e4\u05ea.", {data: {"GDP.": 6,"area.": 15,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 500,"inflation.": 5,"growth.": 6}}, { fill: "red" });
+					chart1.updateSeries("USA.", {data: {"GDP.": 3,"area.": 20,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 1500,"inflation.": 10,"growth.": 3}}, { fill: "green" });
+					chart1.updateSeries("Start \u05e1\u05d5\u05e3.", {data: {"GDP.": 4,"area.": 2,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 1000,"inflation.": 20,"growth.": 2}}, { fill: "yellow" });
+					chart1.updateSeries("\u05d4\u05ea\u05d7\u05dc\u05d4 end.", {data: {"GDP.": 10,"area.": 10,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 800,"inflation.": 2,"growth.": 18}}, { fill: "orange" });
+					chart1.updateSeries("Canada.", {data: {"GDP.": 1,"area.": 18,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 300,"inflation.": 3,"growth.": 15}}, { fill: "purple" });
+				}else{
+					chart1.updateSeries("China", {data: {"GDP.": 8,"area.": 2,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 500,"inflation.": 2,"growth.": 18}}, { fill: "blue" });
+					chart1.updateSeries("\u05e6\u05e8\u05e4\u05ea.", {data: {"GDP.": 10,"area.": 6,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 1000,"inflation.": 20,"growth.": 12}}, { fill: "red" });
+					chart1.updateSeries("USA.", {data: {"GDP.": 2,"area.": 5,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 1500,"inflation.": 12,"growth.": 6}}, { fill: "green" });
+					chart1.updateSeries("Start \u05e1\u05d5\u05e3.", {data: {"GDP.": 1,"area.": 20,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 500,"inflation.": 5,"growth.": 11}}, { fill: "yellow" });
+					chart1.updateSeries("\u05d4\u05ea\u05d7\u05dc\u05d4 end.", {data: {"GDP.": 4,"area.": 2,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 2000,"inflation.": 16,"growth.": 8}}, { fill: "orange" });
+					chart1.updateSeries("Canada.", {data: {"GDP.": 6,"area.": 10,"\u05d0\u05d5\u05db\u05dc\u05d5\u05e1\u05d9\u05d4.": 300,"inflation.": 3,"growth.": 2}}, { fill: "purple" });
+				}
+				chart1.render();
+				legend1 && legend1.refresh && legend1.refresh();
+			}
+
+		</script>
+
+		<script type="text/javascript">
+			function switchSpider(val){
+				stype = document.getElementById("b11").checked ? "polygon" : "circle";
+				if(val == "b11"){
+					chart1.addPlot("default", {
+						type: "Spider",
+						divisions: 		divisions,
+						spiderType: 	stype
+					});
+				}else{
+					chart1.addPlot("default", {
+						type: "Spider",
+						divisions: 		divisions,
+						spiderType: 	stype
+					});
+				}
+				chart1.render();
+				legend1 && legend1.refresh && legend1.refresh();
+			}
+
+		</script>
+
+		<script type="text/javascript">
+			function switchDivisions(val){
+				if(val == "b111"){
+					divisions = 7;
+					chart1.addPlot("default", {
+						type: "Spider",
+						divisions: 		divisions,
+						spiderType: 	stype
+					});
+				}else{
+					divisions = 3;
+					chart1.addPlot("default", {
+						type: "Spider",
+						divisions: 		divisions,
+						spiderType: 	stype
+					});
+				}
+				chart1.render();
+				legend1 && legend1.refresh && legend1.refresh();
+			}
+
+		</script>
+		<script type="text/javascript">
+			function switchAnimation(val){
+				easing = dojo.getObject(dojo.byId("easing").value);
+				chart1.addPlot("default", {
+					type: "Spider",
+					divisions: 		divisions,
+					spiderType: 	stype,
+					animationType:	easing
+				});
+				chart1.render();
+				legend1 && legend1.refresh && legend1.refresh();
+			}
+
+		</script>
+
+	</head>
+	<body class="claro">
+	<h1>Spider 2D</h1>
+
+	<h2>
+	Spider 2D Demo:
+	</h2>
+	<p>
+	<span>
+		<span>Switch Year:</span>
+		<span>
+			<input dojoType="dijit.form.RadioButton" type=radio checked="checked" onClick="switchData(this.id)" name='a1' id='b1' value="1"/><label for='b1'> Figures in 2008 </label>
+			     <input dojoType="dijit.form.RadioButton" type=radio name='a1' onClick="switchData(this.id)" id='b2' value="2"/><label for='b2'> Figures in 2009 </label>
+			                              
+			<span><label>Animation Type: </label><select id="easing" onchange="switchAnimation()"></select></span> 
+		</span>
+	</span>
+	</p>
+	<p>
+	<span>
+		<span>Switch Spider Type:</span>
+		<span>
+			<input dojoType="dijit.form.RadioButton" type=radio checked="checked" onClick="switchSpider(this.id)" name='a11' id='b11' value="polygon"/><label for='b11'> Polygon </label>
+			     <input dojoType="dijit.form.RadioButton" type=radio name='a11' onClick="switchSpider(this.id)" id='b22' value="circle"/><label for='b22'> Circle </label>
+		</span>
+	</span>
+	                              
+	<span>
+		<span>Switch Divisions:</span>
+		<span>
+			<input dojoType="dijit.form.RadioButton" type=radio checked="checked" onClick="switchDivisions(this.id)" name='a111' id='b111' value="1"/><label for='b111'> Divisions = 7 </label>
+			     <input dojoType="dijit.form.RadioButton" type=radio name='a111' onClick="switchDivisions(this.id)" id='b222' value="2"/><label for='b222'> Divisions = 3 </label>
+		</span>
+	</span>
+	</p>
+	<h5>
+		The following legends are selectable:
+	</h5>
+	<div id="legend1"></div>
+	<p/>
+	<div id="test1" style="width: 500px; height: 500px;"></div>
+	<p/>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_StoreSeries.html b/dojox/charting/tests/BidiSupport/mirror_StoreSeries.html
new file mode 100644
index 0000000..f9a64c8
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_StoreSeries.html
@@ -0,0 +1,202 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>StoreSeries Test</title>
+<link rel="stylesheet" href="../../../../dijit/themes/claro/document.css"/>
+<link rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+<link rel="stylesheet" href="../../../../dijit/tests/css/dijitTests.css"/>
+
+<style>
+    .dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px;}
+    .dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+    
+	#charts {
+		clear: both;
+		margin-bottom: 50px;
+	}
+	.chart-area {
+		float: left;
+		border: 1px solid #ccc;
+		width:  450px;
+        height: 350px;
+		margin: 3px;
+	}
+	.chart {
+		width:  450px;
+		height: 300px;
+	}
+</style>
+
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug: false, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+<script>
+    
+    dojo.require("dojox.charting.Chart");
+    dojo.require("dojox.charting.StoreSeries");
+    dojo.require("dojox.charting.themes.ThreeD");
+    dojo.require("dojox.charting.widget.Legend");
+    dojo.require("dojox.charting.axis2d.Default");
+
+    dojo.require("dojox.charting.plot2d.Markers");
+    dojo.require("dojox.charting.plot2d.Columns");
+    dojo.require("dojox.charting.plot2d.Pie");
+    
+    dojo.require("dojox.charting.action2d.Tooltip");
+    dojo.require("dojox.charting.action2d.MoveSlice");
+    dojo.require("dojox.charting.action2d.Magnify");
+    dojo.require("dojox.charting.action2d.Shake");
+
+    dojo.require("dojo.store.Memory");
+    dojo.require("dojo.store.Observable");
+
+    dojo.require("dijit.form.NumberSpinner");
+    
+    dojo.xhrGet({
+    	url: "stock.json",
+    	sync: true,
+    	handleAs: "json"
+    }).then(function(data){
+    	store = dojo.store.Observable(new dojo.store.Memory({data:data}));
+    });
+    
+    function addLegend(chart, node){
+        var legend = new dojox.charting.widget.Legend({chart: chart}, node);
+        dojo.connect(chart, "render", legend, "refresh");
+    }
+    
+    var templates = {
+        low:   "<strong>{0}</strong>: <strong>low {1}</strong> – {2} – {3}",
+        price: "<strong>{0}</strong>: {1} – <strong>price {2}</strong> – {3}",
+        high:  "<strong>{0}</strong>: {1} – {2} – <strong>high {3}</strong>"
+    };
+    
+    function valTrans(value, object){
+        return {
+            y: object[value],
+            tooltip: dojo.replace(
+                templates[value],
+                dojo.map(["symbol", "low", "price", "high"], function(field){
+                    return object[field];
+                })
+            )
+        };
+    }
+    
+    var chartL, chartC, chartP;
+    
+    makeCharts = function(){
+        chartL = new dojox.charting.Chart("lines").
+                setTheme(dojox.charting.themes.ThreeD).
+                addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 5}).
+                addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
+                addPlot("default", {type: dojox.charting.plot2d.Markers}).
+                addSeries("Price", new dojox.charting.StoreSeries(
+                    store, {query: {}}, "price")).setDir("rtl").
+                render();
+        addLegend(chartL, "lines_legend");
+        new dojox.charting.action2d.Magnify(chartL);
+        new dojox.charting.action2d.Tooltip(chartL);
+
+        chartC = new dojox.charting.Chart("cols").
+                setTheme(dojox.charting.themes.ThreeD).
+                addAxis("x", {natural: true}).
+                addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
+                addPlot("default", {type: dojox.charting.plot2d.Columns}).
+                addSeries("Low", new dojox.charting.StoreSeries(
+                    store, {query: {}}, dojo.hitch(null, valTrans, "low"))).
+                addSeries("Price", new dojox.charting.StoreSeries(
+                    store, {query: {}}, dojo.hitch(null, valTrans, "price"))).
+                addSeries("High", new dojox.charting.StoreSeries(
+                    store, {query: {}}, dojo.hitch(null, valTrans, "high"))).setDir("rtl").
+                render();
+        addLegend(chartC, "cols_legend");
+        new dojox.charting.action2d.Shake(chartC, "default", {shiftY: 0});
+        new dojox.charting.action2d.Tooltip(chartC);
+        
+        chartP = new dojox.charting.Chart("pie").
+                setTheme(dojox.charting.themes.ThreeD).
+                addPlot("default", {type: dojox.charting.plot2d.Pie, radius: 125}).
+                addSeries("Price", new dojox.charting.StoreSeries(
+                    store, {query: {}}, {y: "price", text: "symbol", tooltip: "price"})).setDir("rtl").
+                render();
+        addLegend(chartP, "pie_legend");
+        new dojox.charting.action2d.Tooltip(chartP);
+        new dojox.charting.action2d.MoveSlice(chartP);
+    };
+
+    makeSpinners = function(objects){
+        dojo.forEach(objects, function(m){
+            var nm = m.symbol;
+            var num = m.price;
+            console.log(nm, num);
+            var w = new dijit.form.NumberSpinner({
+                onChange: function(val){
+                    val = val===0 ? 0.01 : val; //HACKS the no label-when-zero bug
+                    console.log("OC:", nm, val);
+                    m.price = val;
+                    store.put(m);
+                    //store.setValues(m, "historicPrice", store.getValues("historicPrice").push(val));
+                    console.log("OC:", nm, val);
+                },
+                value: num,
+                constraints: {min:0, max:10,places:2},
+                className: "myField",
+                intermediateChanges: true
+            });
+            dojo.place('<label>'+nm+'</label>', dojo.byId("spinners"), "last")
+            dojo.place(w.domNode, "spinners", "last")
+        });
+        
+        var labels = dojo.map(objects, function(object, index){
+                return {
+                    value: index + 1,
+                    text:  object.symbol
+                }
+            });
+        chartC.addAxis("x", {natural: true, labels: labels}).render();
+    }
+
+    dojo.addOnLoad(function(){
+        makeCharts();
+        makeSpinners(store.query({}));
+    });
+</script>
+
+</head>
+
+<body class="claro">
+	<h1>StoreSeries Test</h1>
+	<p>
+		Use the spinner fields at the bottom to change the data. The charts listen to store changes an update automatically.
+	</p>
+	<div id="charts">
+		<div class="chart-area">
+            <div id="lines_legend"></div>
+			<div id="lines" class="chart"></div>
+		</div>
+		<div class="chart-area">
+            <div id="cols_legend"></div>
+			<div id="cols" class="chart"></div>
+		</div>	
+		<div class="chart-area">
+            <div id="pie_legend"></div>
+			<div id="pie" class="chart"></div>
+		</div>
+	</div>
+	<div id="spinners"></div>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_anim2d.html b/dojox/charting/tests/BidiSupport/mirror_anim2d.html
new file mode 100644
index 0000000..62ddf02
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_anim2d.html
@@ -0,0 +1,133 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+	<title>Chart 2D: Animation tests</title>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+	<script type="text/javascript">
+
+        dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.ClusteredColumns");
+        dojo.require("dojox.charting.plot2d.StackedAreas");
+		dojo.require("dojox.charting.plot2d.Grid");
+		dojo.require("dojox.charting.plot2d.Indicator");
+
+		dojo.require("dojox.charting.themes.Shrooms");
+		dojo.require("dojox.charting.themes.PlotKit.blue");
+		dojo.require("dojox.charting.themes.PlotKit.cyan");
+		dojo.require("dojox.charting.themes.PlotKit.green");
+		dojo.require("dojox.charting.themes.Ireland");
+		dojo.require("dojox.charting.themes.SageToLime");
+		dojo.require("dojox.charting.themes.Minty");
+		dojo.require("dojox.charting.themes.Tufte");
+
+		dojo.require("dojox.dtl");
+		dojo.require("dojox.dtl.Context");
+		
+		charts = [
+			{
+				description: "Columns, grid and indicators.",
+				makeChart: function(node){
+					(new dojox.charting.Chart(node)).
+						setTheme(dojox.charting.themes.Tufte).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true }).
+						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
+						addPlot("default", { type: "ClusteredColumns", gap: 10, animate: { duration: 1000 } }).
+						addPlot("indicator", { type: "Indicator", values: 1.5, lineStroke: { color: "red" }, precision: 1, animate: { duration: 1000 } }).
+						addPlot("grid", { type: "Grid", animate: { duration: 1000 } }).
+						addSeries("Series A", [ 2, 1, 0.5, -1, -2 ] ).
+						addSeries("Series B", [ -2, -1, -0.5, 1, 2 ] ).
+						addSeries("Series C", [ 1, 0.5, -1, -2, -3 ] ).
+						addSeries("Series D", [ 0.7, 1.5, -1.2, -1.25, 3 ] ).
+						setDir("rtl").
+						render();
+				}
+			},
+			{
+				description: "Clustered columns with positive and negative values, readable theme, 1-second animate-in.",
+				makeChart: function(node){
+					(new dojox.charting.Chart(node)).
+						setTheme(dojox.charting.themes.Tufte).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true }).
+						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
+						addPlot("default", { type: "ClusteredColumns", gap: 10, animate: { duration: 1000 } }).
+						addSeries("Series A", [ 2, 1, 0.5, -1, -2 ] ).
+						addSeries("Series B", [ -2, -1, -0.5, 1, 2 ] ).
+						addSeries("Series C", [ 1, 0.5, -1, -2, -3 ] ).
+						addSeries("Series D", [ 0.7, 1.5, -1.2, -1.25, 3 ] ).
+						setDir("rtl").
+						render();
+				}
+			},
+			
+			{
+				description: "StackedAreas 3-second animate-in.",
+				makeChart: function(node){
+					(new dojox.charting.Chart(node)).
+						setTheme(dojox.charting.themes.Tufte).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true }).
+						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
+						addPlot("default", { type: "StackedAreas", gap: 10, animate: { duration: 3000 } }).
+						addSeries("Series A", [ 2, 1, 0.5, 1, 1.5 ] ).
+						addSeries("Series B", [ 0, 1, 0.5, 1, 0.5 ] ).
+						addSeries("Series C", [ 1, 0.5, 0, 2, 3 ] ).
+						addSeries("Series D", [ 0.7, 1.5, 1.2, 1.25, 1 ] ).
+						setDir("rtl").
+						render();
+				}
+			}
+
+
+		];
+		var now = function(){
+			return (new Date()).getTime();
+		};
+
+
+		dojo.addOnLoad(function(){
+			var defaultStyle = { width: "400px", height: "200px" };
+			var tmpl = new dojox.dtl.Template(dojo.byId("template").value);
+			var context = new dojox.dtl.Context({ charts: charts });
+			dojo.byId("charts").innerHTML = tmpl.render(context);
+
+			dojo.forEach(charts, function(item, idx){
+				var start = now();
+				var n = dojo.byId("chart_"+idx);
+				dojo.style(n, item.style||defaultStyle);
+				item.makeChart(n);
+				console.debug((now()-start), "ms to create:", (idx+1)+":", item.description);
+			});
+		});
+
+	</script>
+</head>
+<body>
+	<textarea id="template" style="display: none;">
+		{% for item in charts %}
+			<p>{{ forloop.counter }}: {{ item.description }}</p>
+			<div  id="chart_{{ forloop.counter0 }}"></div>
+		{% endfor %}
+	</textarea>
+
+	<h1>Chart 2D: Animation tests</h1>
+
+	<div id="charts"></div>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_axes.html b/dojox/charting/tests/BidiSupport/mirror_axes.html
new file mode 100644
index 0000000..59335a9
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_axes.html
@@ -0,0 +1,100 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Testing Axes</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+</style>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+<script>
+
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Invisible");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Markers");
+dojo.require("dojox.charting.themes.ThreeD");
+
+makeObjects = function(){
+    dojo.query("button").style("disabled", true);
+    
+    var customTheme = dojox.charting.themes.ThreeD.clone();
+    customTheme.plotarea.fill = "#fed";
+
+	var chart1 = new dojox.charting.Chart("test1").
+            setTheme(customTheme).
+            addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, majorTick: { length: -10}}).
+            addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
+            addPlot("default", {type: "Markers"}).
+            addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
+            addSeries("Series B", [{x: 3, y: 2}, {x: 4, y: 3}, {x: 5, y: 2}]).
+            addSeries("Series C", [{x: 5, y: 3}, {x: 6, y: 4}, {x: 7, y: 3}]).
+			setDir("rtl").
+            render();
+
+	var chart2 = new dojox.charting.Chart("test2").
+            setTheme(customTheme).
+            addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, majorTick: { length: 10}}).
+            addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true, majorTick: {length: -5}, minorTicks: false}).
+            addPlot("p1", {type: "Markers"}).
+            addPlot("p2", {type: "Markers"}).
+            addPlot("p3", {type: "Markers"}).
+            addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}], {plot: "p1"}).
+            addSeries("Series B", [{x: 3, y: 2}, {x: 4, y: 3}, {x: 5, y: 2}], {plot: "p2"}).
+            addSeries("Series C", [{x: 5, y: 3}, {x: 6, y: 4}, {x: 7, y: 3}], {plot: "p3"}).
+			setDir("rtl").
+            render();
+
+	var chart3 = new dojox.charting.Chart("test3").
+            setTheme(customTheme).
+            addAxis("x", {type: "Invisible", fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
+            addAxis("y", {type: "Invisible",vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
+            addPlot("default", {type: "Markers"}).
+            addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
+            addSeries("Series B", [{x: 3, y: 2}, {x: 4, y: 3}, {x: 5, y: 2}]).
+            addSeries("Series C", [{x: 5, y: 3}, {x: 6, y: 4}, {x: 7, y: 3}]).
+			setDir("rtl").
+            render();
+
+	var chart4 = new dojox.charting.Chart("test4").
+            setTheme(customTheme).
+            addPlot("default", {type: "Markers"}).
+            addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
+            addSeries("Series B", [{x: 3, y: 2}, {x: 4, y: 3}, {x: 5, y: 2}]).
+            addSeries("Series C", [{x: 5, y: 3}, {x: 6, y: 4}, {x: 7, y: 3}]).
+			setDir("rtl").
+            render();
+};
+
+dojo.ready(makeObjects);
+
+</script>
+</head>
+<body>
+<h1>Testing Axes</h1>
+<!--<p><button onclick="makeObjects();">Go</button></p>-->
+<p>1: Shared axes and three series</p>
+<div id="test1" style="width: 200px; height: 200px;"></div>
+<p>2: Shared axes and three plots.</p>
+<div id="test2" style="width: 200px; height: 200px;"></div>
+<p>3: Like #1 but invisible axes.</p>
+<div id="test3" style="width: 200px; height: 200px;"></div>
+<p>4: Like #1 but no axes.</p>
+<div id="test4" style="width: 200px; height: 200px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_axisZoomControl.html b/dojox/charting/tests/BidiSupport/mirror_axisZoomControl.html
new file mode 100644
index 0000000..1faa081
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_axisZoomControl.html
@@ -0,0 +1,131 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<title>Axis Zoom Control</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../form/resources/RangeSlider.css";
+			#hrXAxisSlider .dijitSliderProgressBar{
+				height: 12px;
+				overflow: visible;
+				margin-top: -5px;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+		<script type="text/javascript">
+			var chart1, zoomAxis;
+
+			require(["dojo/dom", "dojo/ready", "dojox/charting/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Lines",
+				"dojox/charting/plot2d/StackedAreas", "dojox/charting/plot2d/Grid",
+				"dojox/charting/themes/PlotKit/orange", "dojox/charting/action2d/Tooltip",
+				"dojox/charting/action2d/Magnify", "dojo/parser", "dojox/form/RangeSlider"], function(dom, ready, Chart, Default, Lines, StackedAreas,
+					Grid, orange, Tooltip, Magnify){
+				zoomXAxis = function(){
+					chart1.zoomIn("x", arguments[0]);
+					chart2.zoomIn("x", arguments[0]);
+					dom.byId('minValue').value = arguments[0][0];
+					dom.byId('maxValue').value = arguments[0][1];
+				}
+				ready(function(){
+					chart1 = new Chart("chart1");
+					chart1.setTheme(orange);
+					chart1.addAxis("x", {fixLower: "minor", natural: true, stroke: "grey",
+						majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+					chart1.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 5, minorTickStep: 1, stroke: "grey",
+						majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+					chart1.addPlot("default", {type: Lines, markers: true});
+					chart1.addSeries("Series A", [
+						 8,  7,  3,  2,  5,  7,  9, 10,  2, 10,
+						14, 16, 18, 13, 16, 15, 20, 19, 15, 12,
+						24, 20, 20, 26, 28, 26, 28, 29, 24, 29,
+						31, 35, 37, 31, 35, 37, 37, 36, 31, 30,
+						50, 49, 42, 46, 44, 40, 47, 43, 48, 47,
+						51, 52, 52, 51, 54, 57, 58, 50, 54, 51,
+						62, 68, 67, 62, 62, 65, 61, 66, 65, 62,
+						74, 78, 78, 77, 74, 74, 72, 74, 70, 78,
+						84, 83, 85, 86, 86, 89, 89, 85, 86, 86,
+						98, 97, 93, 91, 92, 92, 99, 93, 94, 92
+					]);
+					chart1.addPlot("grid", {type: Grid, hMinorLines:true});
+					new Tooltip(chart1, "default");
+					new Magnify(chart1,"default");
+					chart1.setDir("rtl");
+					chart1.render();
+					chart2 = new Chart("chart2");
+					chart2.setTheme(orange);
+					chart2.addAxis("x", {fixLower: "minor", natural: true, stroke: "grey",
+						majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+					chart2.addAxis("y", {vertical: true, min: 0, max: 200, majorTickStep: 5, minorTickStep: 1, stroke: "grey",
+							majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+					chart2.addPlot("default", {type: StackedAreas });
+					chart2.addSeries("Series A", [
+							 8,  7,  3,  2,  5,  7,  9, 10,  2, 10,
+							14, 16, 18, 13, 16, 15, 20, 19, 15, 12,
+							24, 20, 20, 26, 28, 26, 28, 29, 24, 29,
+							31, 35, 37, 31, 35, 37, 37, 36, 31, 30,
+							50, 49, 42, 46, 44, 40, 47, 43, 48, 47,
+							51, 52, 52, 51, 54, 57, 58, 50, 54, 51,
+							62, 68, 67, 62, 62, 65, 61, 66, 65, 62,
+							74, 78, 78, 77, 74, 74, 72, 74, 70, 78,
+							84, 83, 85, 86, 86, 89, 89, 85, 86, 86,
+							98, 97, 93, 91, 92, 92, 99, 93, 94, 92
+						]);
+					chart2.addSeries("Series B", [
+							 8,  7,  3,  2,  5,  7,  9, 10,  2, 10,
+							14, 16, 18, 13, 16, 15, 20, 19, 15, 12,
+							24, 20, 20, 26, 28, 26, 28, 29, 24, 29,
+							31, 35, 37, 31, 35, 37, 37, 36, 31, 30,
+							50, 49, 42, 46, 44, 40, 47, 43, 48, 47,
+							51, 52, 52, 51, 54, 57, 58, 50, 54, 51,
+							62, 68, 67, 62, 62, 65, 61, 66, 65, 62,
+							74, 78, 78, 77, 74, 74, 72, 74, 70, 78,
+							84, 83, 85, 86, 86, 89, 89, 85, 86, 86,
+							98, 97, 93, 91, 92, 92, 99, 93, 94, 92
+						]);
+						chart2.setDir("rtl");
+					chart2.render();
+				});
+			});
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Axis Zoom Control</h1>
+		 Try to drag the slider endpoints and the bar to zoom X axis of the chart.
+		<div style="margin:20px">
+			<div id="chart1" style="width: 800px; height: 400px;"></div>
+			<div id="chart2" style="width: 800px; height: 400px;"></div>
+			<div id="hrXAxisSlider"
+				discreteValues="21"
+				onChange="zoomXAxis"
+				intermediateChanges="false"
+				data-dojo-type="dojox.form.HorizontalRangeSlider"
+				showButtons="false"
+				style="width:748px;margin-left:40px"
+				value="0,100">
+				<ol data-dojo-type="dijit/form/HorizontalRuleLabels" container="topDecoration" style="height:1.2em;font-size:75%;color:gray;" count="11">
+					<li>0</li><li>10</li><li>20</li><li>30</li><li>40</li><li>50</li><li>60</li><li>70</li><li>80</li><li>90</li><li>100</li>
+				</ol>
+				<div data-dojo-type="dijit/form/HorizontalRule" container="topDecoration" count=11 style="height:10px;"></div>
+			</div>
+		</div>
+		<p>X Axis Lower Value: <input readonly id="minValue" size="10" value="0"/></p>
+		<p>X Axis Upper Value: <input readonly id="maxValue" size="10" value="100"/></p>
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_axisoffsets.html b/dojox/charting/tests/BidiSupport/mirror_axisoffsets.html
new file mode 100644
index 0000000..5e5b2a2
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_axisoffsets.html
@@ -0,0 +1,45 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+		<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true, has:{'dojo-bidi': true}"></script>
+	 <script type="text/javascript">
+	 
+	require(["dojo/ready", "dojox/charting/Chart", "dojox/charting/axis2d/Default",
+		"dojox/charting/plot2d/Markers", "dojox/charting/themes/PlotKit/blue"], function(ready, Chart, Default, Markers,
+																						  blue){
+		ready(function(){
+			var chart = new Chart("chartDiv").
+				setTheme(blue).
+	 			addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true,
+					majorTickStep: 0.5, minorTickStep: 0.1, dropLabels: true }).
+				addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true,
+						labels: [{ value: 0, text: "0" }, { value: 1, text: "long label1" }, { value: 2, text: "long label2" },
+							{ value: 3, text: "long label3" }, { value: 4, text: "4" } ]
+					}).
+				addPlot("default", {type: Markers}).
+				addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
+				addSeries("Series B", [{x: 5, y: 2}, {x: 6, y: 3}, {x: 7, y: 2}]).
+				addSeries("Series C", [{x: 9, y: 3}, {x: 10, y: 4}, {x: 11, y: 3}]).
+				setDir("rtl").
+				render();
+		});
+	});
+    </script>
+	</head>
+<body>
+	<div id="chartDiv" style="width: 400px; height: 250px;"></div>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_bars.html b/dojox/charting/tests/BidiSupport/mirror_bars.html
new file mode 100644
index 0000000..a1f2d03
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_bars.html
@@ -0,0 +1,72 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Bar chart</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+
+dojo.require("dojox.charting.Chart3D");
+dojo.require("dojox.charting.plot3d.Bars");
+
+makeObjects = function(){
+	var m = dojox.gfx3d.matrix;
+	var chart = new dojox.charting.Chart3D("test", 
+		{
+			lights:   [{direction: {x: 5, y: 5, z: -5}, color: "white"}],
+			ambient:  {color:"white", intensity: 2},
+			specular: "white"
+		},
+		[m.cameraRotateXg(10), m.cameraRotateYg(-10), m.scale(0.8), m.cameraTranslate(-50, -50, 0)]
+	);
+	
+	var plot1 = new dojox.charting.plot3d.Bars(500, 500, {gap: 10, material: "yellow"});
+	plot1.setData([1,2,3,2,1,2,3,4,5]);
+	chart.addPlot(plot1);
+	
+	var plot2 = new dojox.charting.plot3d.Bars(500, 500, {gap: 10, material: "red"});
+	plot2.setData([2,3,4,3,2,3,4,5,5]);
+	chart.addPlot(plot2);
+	
+	var plot3 = new dojox.charting.plot3d.Bars(500, 500, {gap: 10, material: "blue"});
+	plot3.setData([3,4,5,4,3,4,5,5,5]);
+	chart.addPlot(plot3);
+	chart.setDir("rtl");
+	chart.generate().render();
+	
+	//dojo.byId("out1").value = dojo.byId("test").innerHTML;
+	//dojo.byId("out2").value = dojox.gfx.utils.toJson(surface, true);
+};
+
+dojo.addOnLoad(makeObjects);
+
+</script>
+</head>
+<body>
+<h1>Bar chart</h1>
+<div id="test" style="width: 500px; height: 500px;"></div>
+<!--
+<p><button onclick="makeObjects();">Go</button></p>
+<p><textarea id="out1" cols="40" rows="5"></textarea></p>
+<p><textarea id="out2" cols="40" rows="5"></textarea></p>
+-->
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_chart2d-amd.html b/dojox/charting/tests/BidiSupport/mirror_chart2d-amd.html
new file mode 100644
index 0000000..9bb0709
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_chart2d-amd.html
@@ -0,0 +1,863 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+	<title>Chart 2D</title>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+	</style>
+	<!-- NOTE: This test uses amd style modules and loading, but must run in sync loading mode because it uses DTL which does not work async-->
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, has:{'dojo-bidi': true}"></script>
+	<script type="text/javascript">
+		require([
+		"dojo/_base/array",
+		"dojo/dom",
+		"dojo/dom-style",
+		"dojo/ready",
+		"dojox/charting/Chart",
+		"dojox/charting/themes/Shrooms",
+		"dojox/charting/themes/PlotKit/blue",
+		"dojox/charting/themes/PlotKit/cyan",
+		"dojox/charting/themes/PlotKit/green",
+		"dojox/charting/themes/Ireland",
+		"dojox/charting/themes/SageToLime",
+		"dojox/charting/themes/Minty",
+		"dojox/charting/themes/Tufte",
+		"dojox/dtl",
+		"dojox/dtl/Context",
+		"dojox/dtl/tag/logic",
+		"dojox/charting/axis2d/Default",
+		"dojox/charting/plot2d/Default",
+		"dojox/charting/plot2d/Areas",
+		"dojox/charting/plot2d/Markers",
+		"dojox/charting/plot2d/MarkersOnly",
+		"dojox/charting/plot2d/StackedLines",
+		"dojox/charting/plot2d/StackedAreas",
+		"dojox/charting/plot2d/Bars",
+		"dojox/charting/plot2d/ClusteredBars",
+		"dojox/charting/plot2d/StackedBars",
+		"dojox/charting/plot2d/ClusteredColumns",
+		"dojox/charting/plot2d/StackedColumns",
+		"dojox/charting/plot2d/Bubble",
+		"dojox/charting/plot2d/Grid",
+		"dojox/charting/plot2d/Candlesticks",
+		"dojox/charting/plot2d/OHLC",
+		"dojox/charting/plot2d/Scatter"],
+		function(arr, dom, domStyle, ready, Chart, Shrooms, blue, cyan, green, Ireland, SageToLime, Minty, Tufte,
+			dtl, Context){
+		
+		var charts = [
+			{
+				description: "Clustered columns with positive and negative values, readable theme.",
+				makeChart: function(node){
+					(new Chart(node)).
+						setTheme(Tufte).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true }).
+						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
+						addPlot("default", { type: "ClusteredColumns", gap: 10 }).
+						addSeries("Series A", [ 2, 1, 0.5, -1, -2 ] ).
+						addSeries("Series B", [ -2, -1, -0.5, 1, 2 ] ).
+						addSeries("Series C", [ 1, 0.5, -1, -2, -3 ] ).
+						addSeries("Series D", [ 0.7, 1.5, -1.2, -1.25, 3 ] ).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Bubble chart, green theme.",
+				makeChart: function(node){
+					(new Chart(node)).
+						setTheme(SageToLime).
+						addPlot("default", { type: "Bubble", shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]} }).
+						addAxis("x", {
+							min: 0,
+							max: 6,
+							majorTick: { stroke: "black", length: 3 },
+							minorTick: { stroke: "gray", length: 3 }
+						}).
+						addAxis("y", {
+							vertical: true,
+							min: 0,
+							max: 10,
+							majorTick: { stroke: "black", length: 3 },
+							minorTick: { stroke: "gray", length: 3 }
+						}).
+						addSeries("Series A", [
+							{ x: 0.5, y: 5, size: 1.4 },
+							{ x: 1.5, y: 1.5, size: 4.5 },
+							{ x: 2, y: 9, size:1.5 },
+							{ x: 5, y: 0.3, size:0.8 }
+						]).
+						addSeries("Series B", [
+							{ x: 0.3, y: 8, size: 2.5 },
+							{ x: 4, y: 6, size:1.1 },
+							{ x: 5.5, y: 2, size: 3.2 }
+						]).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Lines, calculated labels",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x", {
+							majorLabels: true, 
+							minorLabels: true, 
+							includeZero: true, 
+							minorTicks: false, 
+							microTicks: false,
+							majorTickStep: 2,
+							htmlLabels: true,																	 
+							labelFunc: function(value){
+								return value + " s";
+							},
+							maxLabelSize: 30,
+							fixUpper: "major", fixLower: "major",												 
+							majorTick: { length: 3 }
+						}).
+						addAxis("y", {
+							labelFunc: function(value){
+								return value + " thingers";
+							},
+							maxLabelSize: 50,
+							vertical: true,
+							// htmlLabels: false,
+							microTicks: true,
+							minorTicks: true, 
+							majorTick: { stroke: "black", length: 3 }
+						}).
+						addSeries("Series A", [ 1, 2, 1, 2, 1, 2, 1 ]).
+						addSeries("Series B", [ 2, 1, 2, 1, 2, 1, 2 ]).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Lines, pre-computed labels",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x", {
+							majorLabels: true, 
+							minorLabels: true, 
+							includeZero: true, 
+							minorTicks: false, 
+							microTicks: false,
+							majorTickStep: 2,
+							labels: [
+								{ value: 0, text: "nada" },
+								{ value: 2, text: "2 units" },
+								{ value: 4, text: "4 units" },
+								{ value: 8, text: "2*4 units" }
+							],
+							htmlLabels: true,																	 
+							fixUpper: "major", fixLower: "major",												 
+							majorTick: { length: 3 }
+						}).
+						addAxis("y", {
+							labels: [
+								{ value: 0, text: "nada" },
+								{ value: 1.1, text: "hrmm" },
+								{ value: 1.2, text: "?" },
+								{ value: 2, text: "2!" }
+							],
+							vertical: true,
+							// htmlLabels: false,
+							microTicks: true,
+							minorTicks: true, 
+							majorTick: { stroke: "black", length: 3 }
+						}).
+						addSeries("Series A", [ 1, 2, 1, 2, 1, 2, 1 ]).
+						addSeries("Series B", [ 2, 1, 2, 1, 2, 1, 2 ]).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Defaults: lines, no axes.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addSeries("Series A", [ 1, 2, 1, 2, 1, 2, 1 ]).
+						addSeries("Series B", [ 2, 1, 2, 1, 2, 1, 2 ]).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Defaults: lines, no axes, and custom strokes.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addSeries("Series A", [ 1, 2, 1, 2, 1, 2, 1 ], {stroke: "red"}).
+						addSeries("Series B", [ 2, 1, 2, 1, 2, 1, 2 ], {stroke: "blue"}).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Areas, Happy theme, no axes.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addPlot("default", {type: "Areas", tension:"X"}).
+						setTheme(Shrooms).
+						addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4]).
+						addSeries("Series B", [2.6, 1.8, 2, 1, 1.4, 0.7, 2]).
+						addSeries("Series C", [6.3, 1.8, 3, 0.5, 4.4, 2.7, 2]).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Areas, no axes, custom strokes and fills.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addPlot("default", {type: "Areas"}).
+						addSeries("Series A",
+							[1, 2, 1, 2, 1, 2, 1],
+							{
+								stroke: {color: "red", width: 2 },
+								fill: "lightpink"
+							}
+						).
+						addSeries("Series B",
+							[ 2, 1, 2, 1, 2, 1, 2 ],
+							{
+								stroke: { color: "blue", width: 2 },
+								fill: "lightblue"
+							}
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Lines, axes, blue theme.",
+				makeChart: function(node){
+					(new Chart(node)).
+						setTheme(blue).
+						addAxis("x").
+						addAxis("y", {vertical: true}).
+						addSeries("Series A", [1, 2, 1, 2, 1, 2, 1]).
+						addSeries("Series B", [2, 1, 2, 1, 2, 1, 2]).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Lines, axes (aligned on minor ticks), cyan theme.",
+				makeChart: function(node){
+					(new Chart(node)).
+						setTheme(cyan).
+						addAxis("x", {
+							fixLower: "minor", fixUpper: "minor"
+						}).
+						addAxis("y", {
+							vertical: true, fixLower: "minor", fixUpper: "minor"
+						}).
+						addSeries("Series A", [1, 2, 1, 2, 1, 2, 1]).
+						addSeries("Series B", [2, 1, 2, 1, 2, 1, 2]).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Lines, axes (aligned on major ticks), green theme.",
+				makeChart: function(node){
+					(new Chart(node)).
+						setTheme(green).
+						addAxis("x", {
+							fixLower: "major", fixUpper: "major"
+						}).
+						addAxis("y", {
+							vertical: true, fixLower: "major", fixUpper: "major"
+						}).
+						addSeries("Series A", [1, 2, 1, 2, 1, 2, 1]).
+						addSeries("Series B", [2, 1, 2, 1, 2, 1, 2]).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Lines and markers, no axes, purple theme, custom min/max.",
+				makeChart: function(node){
+					(new Chart(node)).
+						setTheme(SageToLime).
+						addPlot("default", {type: "Markers"}).
+						addSeries("Series A", [1, 2, 1, 2, 1, 2, 1], {min: 0, max: 3}).
+						addSeries("Series B", [2, 1, 2, 1, 2, 1, 2]).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Markers only, no axes, custom theme, custom markers, custom min/max.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addPlot("default", { type: "MarkersOnly" }).
+						addSeries("Series A",
+							[ 1, 2, 1, 2, 1, 2, 1 ],
+							{
+								min: 0,
+								max: 3,
+								stroke: {color: "red", width: 2},
+								fill:	"red",
+								marker: "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0"
+							}
+						).
+						addSeries("Series B",
+							[ 2, 1, 2, 1, 2, 1, 2 ],
+							{
+								stroke: {color: "blue", width: 2},
+								fill:	"blue",
+								marker: "m-3,-3 l0,6 6,0 0,-6 z"
+							}
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Lines and markers, shadows, no axes, custom theme, custom markers, custom min/max.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addPlot("default", {
+							type: "Markers", shadow:  {dx: 1, dy: 1, width: 5, color: [100, 0, 0, 1]}
+						}).
+						addSeries("Series A",
+							[ 1, 2, 1, 2, 1, 2, 1 ],
+							{
+								min: 0,
+								max: 3,
+								stroke: {color: "red", width: 2, join: "round"},
+								fill:	"red",
+								marker: "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0"
+							}
+						).
+						addSeries("Series B",
+							[ 2, 1, 2, 1, 2, 1, 2 ],
+							{
+								stroke: {color: "blue", width: 2, join: "round"},
+								fill:	"blue",
+								marker: "m-3,-3 l0,6 6,0 0,-6 z"
+							}
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Stacked lines, markers, shadows, no axes, custom strokes, fills, and markers.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addPlot("default", {
+							type: "StackedLines",
+							markers: true,
+							tension:"S",
+							shadow:	 {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]}
+						}).
+						addSeries("Series A",
+							[ 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6 ],
+							{
+								stroke: { color: "red", width: 2 },
+								fill: "lightpink",
+								marker: "m-3,-3 l0,6 6,0 0,-6 z"
+							}
+						).
+						addSeries("Series B",
+							[ 1, 1.6, 1.3, 1.4, 1.1, 1.5, 1.1 ],
+							{
+								stroke: { color: "blue", width: 2 },
+								fill: "lightblue",
+								marker: "m-3,0 c0,-4 6,-4 6,0 m-6,0 c0,4 6,4 6,0"
+							}
+						).
+						addSeries("Series C",
+							[ 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6 ],
+							{
+								stroke: { color: "green", width: 2 },
+								fill: "lightgreen",
+								marker: "m0,-3 l3,3 -3,3 -3,-3 z"
+							}
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Stacked areas, axes (aligned on major ticks), custom strokes and fills.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x", {fixLower: "major", fixUpper: "major"}).
+						addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", min: 0}).
+						addPlot("default", { type: "StackedAreas", tension:"S" }).
+						addSeries("Series A",
+							[ -2, 1.1, 1.2, 1.3, 1.4, 1.5, -1.6 ],
+							{ stroke: {color: "red", width: 2}, fill: "lightpink" }
+						).
+						addSeries("Series B",
+							[ 1, 1.6, 1.3, 1.4, 1.1, 1.5, 1.1 ],
+							{ stroke: {color: "blue", width: 2}, fill: "lightblue" }
+						).
+						addSeries("Series C",
+							[ 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6 ],
+							{ stroke: {color: "green", width: 2}, fill: "lightgreen" }
+						).setDir("rtl").render();
+				}
+			},
+			{
+				description: "Candlesticks with gaps, custom strokes and fills, optional mid points.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addPlot("default", {type: "Candlesticks", gap: 1}).
+						addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true}).
+						addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
+						addSeries("Series A", [
+								{ open: 20, close: 16, high: 22, low: 8 },
+								{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
+								{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
+								{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
+								{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
+								{ open: 24, close: 8, high: 24, low: 5 },
+								{ open: 8, close: 16, high: 22, low: 2 },
+								{ open: 16, close: 12, high: 19, low: 7 },
+								{ open: 12, close: 20, high: 22, low: 8 },
+								{ open: 20, close: 16, high: 22, low: 8 },
+								{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
+								{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
+								{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
+								{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
+								{ open: 24, close: 8, high: 24, low: 5 },
+								{ open: 8, close: 16, high: 22, low: 2 },
+								{ open: 16, close: 12, high: 19, low: 7 },
+								{ open: 12, close: 20, high: 22, low: 8 },
+								{ open: 20, close: 16, high: 22, low: 8 },
+								{ open: 16, close: 22, high: 26, low: 6 },
+								{ open: 22, close: 18, high: 22, low: 11 },
+								{ open: 18, close: 29, high: 32, low: 14 },
+								{ open: 29, close: 24, high: 29, low: 13 },
+								{ open: 24, close: 8, high: 24, low: 5 },
+								{ open: 8, close: 16, high: 22, low: 2 },
+								{ open: 16, close: 12, high: 19, low: 7 },
+								{ open: 12, close: 20, high: 22, low: 8 },
+								{ open: 20, close: 16, high: 22, low: 8 }
+							],
+							{ stroke: { color: "green" }, fill: "lightgreen" }
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Open/High/Low/Close with gaps, custom strokes and fills.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addPlot("default", {type: "OHLC", gap: 2}).
+						addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true}).
+						addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
+						addSeries("Series A", [
+								{ open: 20, close: 16, high: 22, low: 8 },
+								{ open: 16, close: 22, high: 26, low: 6 },
+								{ open: 22, close: 18, high: 22, low: 11 },
+								{ open: 18, close: 29, high: 32, low: 14 },
+								{ open: 29, close: 24, high: 29, low: 13 },
+								{ open: 24, close: 8, high: 24, low: 5 },
+								{ open: 8, close: 16, high: 22, low: 2 },
+								{ open: 16, close: 12, high: 19, low: 7 },
+								{ open: 12, close: 20, high: 22, low: 8 },
+								{ open: 20, close: 16, high: 22, low: 8 },
+								{ open: 16, close: 22, high: 26, low: 6 },
+								{ open: 22, close: 18, high: 22, low: 11 },
+								{ open: 18, close: 29, high: 32, low: 14 },
+								{ open: 29, close: 24, high: 29, low: 13 },
+								{ open: 24, close: 8, high: 24, low: 5 },
+								{ open: 8, close: 16, high: 22, low: 2 },
+								{ open: 16, close: 12, high: 19, low: 7 },
+								{ open: 12, close: 20, high: 22, low: 8 },
+								{ open: 20, close: 16, high: 22, low: 8 },
+								{ open: 16, close: 22, high: 26, low: 6 },
+								{ open: 22, close: 18, high: 22, low: 11 },
+								{ open: 18, close: 29, high: 32, low: 14 },
+								{ open: 29, close: 24, high: 29, low: 13 },
+								{ open: 24, close: 8, high: 24, low: 5 },
+								{ open: 8, close: 16, high: 22, low: 2 },
+								{ open: 16, close: 12, high: 19, low: 7 },
+								{ open: 12, close: 20, high: 22, low: 8 },
+								{ open: 20, close: 16, high: 22, low: 8 }
+							],
+							{ stroke: { color: "blue" }, fill: "blue" }
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Columns, no axes, custom strokes and fills.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addPlot("default", {type: "Columns"}).
+						addSeries("Series A", [ 1, 2, 3, 4, 5 ], { stroke: { color: "red" }, fill: "lightpink" }).
+						addSeries("Series B", [ 5, 4, 3, 2, 1 ], { stroke: {color: "blue"}, fill: "lightblue" }).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Columns with gaps beetwen them, vertical axis aligned on major ticks, custom strokes, fills.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major"}).
+						addPlot("default", {type: "Columns", gap: 2}).
+						addSeries("Series A", [ 1, 2, 3, 4, 5 ], { stroke: {color: "red"}, fill: "lightpink" }).
+						addSeries("Series B", [ 5, 4, 3, 2, 1 ], { stroke: {color: "blue"}, fill: "lightblue" }).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Stacked columns, no axes, custom strokes and fills.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addPlot("default", {type: "StackedColumns"}).
+						addSeries("Series A", [ 1, 2, 3, 4, 5 ], {stroke: { color: "red" }, fill: "lightpink" }).
+						addSeries("Series B", [ 2, 1, 2, 1, 2 ], {stroke: { color: "blue" }, fill: "lightblue" }).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Bars, axes aligned on major ticks, no minor ticks, custom strokes and fills.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true}).
+						addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
+						addPlot("default", {type: "Bars"}).
+						addSeries("Series A",
+							[1, 2, 3, 4, 5],
+							{ stroke: {color: "red"}, fill: "lightpink" }
+						).
+						addSeries("Series B",
+							[5, 4, 3, 2, 1],
+							{ stroke: {color: "blue"}, fill: "lightblue" }
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Stacked bars, no axes, custom strokes and fills.",
+				makeChart: function(node){
+					(new Chart(node)).setTheme(blue).
+						addPlot("default", {type: "StackedBars"}).
+						addSeries("Series A", [ 1, 2, 3, 4, 5 ], { stroke: { color: "red" }, fill: "lightpink" }).
+						addSeries("Series B", [ 2, 1, 2, 1, 2 ], { stroke: { color: "blue" }, fill: "lightblue" }).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Clustered columns, custom axes, custom strokes, fills, and gap.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x", {
+							fixLower: "minor", fixUpper: "minor", natural: true
+						}).
+						addAxis("y", {
+							vertical: true, fixLower: "major", fixUpper: "major", includeZero: true
+						}).
+						addPlot("default", {type: "ClusteredColumns", gap: 10}).
+						addSeries("Series A",
+							[ 1, 2, 3, 4, 5 ],
+							{ stroke: {color: "red"}, fill: "lightpink" }
+						).
+						addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"}).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Clustered bars, custom axes, custom strokes, fills, and gap.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true}).
+						addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true}).
+						addPlot("default", { type: "ClusteredBars", gap: 5 }).
+						addSeries("Series A", [ 1, 2, 3, 4, 5 ], { stroke: { color: "red" }, fill: "lightpink" }).
+						addSeries("Series B", [ 2, 1, 2, 1, 2 ], { stroke: { color: "blue" }, fill: "lightblue" }).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Columns with gaps beetwen them, grids, custom strokes, fills, axes.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true }).
+						addAxis("y", {
+							vertical: true,
+							fixLower: "major",
+							fixUpper: "major",
+							minorTicks: false,
+							includeZero: true
+						}).
+						addPlot("front_grid", { type: "Grid", hMajorLines: true, vMajorLines: false }).
+						addPlot("default", { type: "Columns", gap: 10 }).
+						addPlot("back_grid", { type: "Grid", hMajorLines: false, vMajorLines: true }).
+						addSeries("Series A",
+							[ 1, 2, 3, 4, 5 ],
+							{ stroke: { color: "red" }, fill: "lightpink" }
+						).
+						addSeries("Series B",
+							[ 5, 4, 3, 2, 1 ],
+							{ stroke: { color: "blue" }, fill: "lightblue" }
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Columns with gaps beetwen them, grids, custom strokes, fills, axes, with min=0, max=8, and manually specified ticks on the vertical axis.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x", {fixLower: "minor", fixUpper: "minor", natural: true}).
+						addAxis("y", {
+							vertical: true, fixLower: "major", fixUpper: "major",
+							includeZero: true, min: 0, max: 8, minorLabels: false,
+							majorTicks: true, minorTicks: true, microTicks: false,
+							majorTickStep: 2, minorTickStep: 1, microTickStep: 0.5
+						}).
+						addPlot("front_grid", {
+							type: "Grid", hMajorLines: true, vMajorLines: false
+						}).
+						addPlot("default", {type: "Columns", gap: 10}).
+						addPlot("back_grid", {
+							type: "Grid", hMajorLines: false, vMajorLines: true
+						}).
+						addSeries("Series A",
+							[ 1, 2, 3, 4, 5 ],
+							{ stroke: {color: "red"}, fill: "lightpink" }
+						).
+						addSeries("Series B",
+							[ 5, 4, 3, 2, 1 ],
+							{ stroke: {color: "blue"}, fill: "lightblue" }
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Columns with positive and negative values, axes, and grid.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x").
+						addAxis("y", { vertical: true }).
+						addPlot("default", { type: "Columns", gap: 10 }).
+						addPlot("grid", { type: "Grid" }).
+						addSeries("Series A",
+							[ 2, 1, 0.5, -1, -2 ],
+							{ stroke: {color: "red"}, fill: "lightpink" }
+						).
+						addSeries("Series B",
+							[ -2, -1, -0.5, 1, 2 ],
+							{ stroke: {color: "blue"}, fill: "lightblue" }
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Clustered columns with positive and negative values, axes, and grid.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x").
+						addAxis("y", { vertical: true }).
+						addPlot("default", { type: "ClusteredColumns", gap: 10 }).
+						addPlot("grid", { type: "Grid" }).
+						addSeries("Series A",
+							[ 2, 1, 0.5, -1, -2 ],
+							{ stroke: {color: "red"}, fill: "lightpink" }
+						).
+						addSeries("Series B",
+							[ -2, -1, -0.5, 1, 2 ],
+							{ stroke: {color: "blue"}, fill: "lightblue" }
+						).
+						addSeries("Series C",
+							[ 1, 0.5, -1, -2, -3 ],
+							{ stroke: {color: "green"}, fill: "lightgreen" }
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Bars with positive and negative values, axes, and grid.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x").
+						addAxis("y", { vertical: true }).
+						addPlot("default", { type: "Bars", gap: 10 }).
+						addPlot("grid", { type: "Grid" }).
+						addSeries("Series A",
+							[ 2, 1, 0.5, -1, -2 ],
+							{ stroke: {color: "red"}, fill: "lightpink" }
+						).
+						addSeries("Series B",
+							[ -2, -1, -0.5, 1, 2 ],
+							{ stroke: {color: "blue"}, fill: "lightblue" }
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Clustered bars with positive and negative values, axes, and grid.",
+				makeChart: function(node){
+					(new Chart(node)).
+						addAxis("x").
+						addAxis("y", { vertical: true }).
+						addPlot("default", { type: "ClusteredBars", gap: 10 }).
+						addPlot("grid", { type: "Grid" }).
+						addSeries("Series A",
+							[ 2, 1, 0.5, -1, -2 ],
+							{ stroke: { color: "red" }, fill: "lightpink" }
+						).
+						addSeries("Series B",
+							[ -2, -1, -0.5, 1, 2 ],
+							{ stroke: { color: "blue" }, fill: "lightblue" }
+						).
+						addSeries("Series C",
+							[ 1, 0.5, -1, -2, -3 ],
+							{ stroke: { color: "green" }, fill: "lightgreen" }
+						).
+						setDir("rtl").render();
+				}
+			},
+			{
+				description: "Default lines with 2D data, custom axis, red theme.",
+				makeChart: function(node){
+					(new Chart(node)).
+						setTheme(Minty).
+						addAxis("x", {
+							min: 0,
+							max: 6,
+							majorTick: { stroke: "black", length: 3 },
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
+						}).
+						addAxis("y", {
+							vertical: true,
+							min: 0,
+							max: 10,
+							majorTick: { stroke: "black", length: 3 },
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
+						}).
+						addSeries("Series A", [
+							{ x: 0.5, y: 5 },
+							{ x: 1.5, y: 1.5 },
+							{ x: 2, y: 9 },
+							{ x: 5, y: 0.3 }
+						]).
+						addSeries("Series B", [
+							{ x: 0.3, y: 8 },
+							{ x: 4, y: 6 },
+							{ x: 5.5, y: 2 }
+						]).
+						setDir("rtl").render();
+				}
+			},
+			
+			{
+				description: "Scatter chart, custom axis, purple theme.",
+				makeChart: function(node){
+					(new Chart(node)).
+						setTheme(Ireland).
+						addPlot("default", {type: "Scatter"}).
+						addAxis("x", {
+							min: 0,
+							max: 6,
+							majorTick: { stroke: "black", length: 3 },
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
+						}).
+						addAxis("y", {
+							vertical: true,
+							min: 0,
+							max: 10,
+							majorTick: { stroke: "black", length: 3 },
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
+						}).
+						addSeries("Series A", [
+							{ x: 0.5, y: 5 },
+							{ x: 1.5, y: 1.5 },
+							{ x: 2, y: 9 },
+							{ x: 5, y: 0.3 }
+						]).
+						addSeries("Series B", [
+							{ x: 0.3, y: 8 },
+							{ x: 4, y: 6 },
+							{ x: 5.5, y: 2 }
+						]).
+						setDir("rtl").render();
+				}
+			},
+			
+			{
+				description: "Markers, lines, 2D data, custom axis, blue theme.",
+				makeChart: function(node){
+					(new Chart(node)).
+						setTheme(blue).
+						addPlot("default", {
+							type: "Default",
+							lines: true,
+							markers: true,
+							tension: 2
+						}).
+						addAxis("x", {
+							min: 0,
+							max: 6,
+							majorTick: { stroke: "black", length: 3 },
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
+						}).
+						addAxis("y", {
+							vertical: true,
+							min: 0,
+							max: 10,
+							majorTick: { stroke: "black", length: 3 },
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
+						}).
+						addSeries("Series A", [
+							{ x: 0.5, y: 5 },
+							{ x: 1.5, y: 1.5 },
+							{ x: 2, y: 9 },
+							{ x: 5, y: 0.3 }
+						]).
+						addSeries("Series B", [
+							{ x: 0.3, y: 8 },
+							{ x: 4, y: 6 },
+							{ x: 5.5, y: 2 }
+						]).
+						setDir("rtl").render();
+				}
+			}
+		];
+		var now = function(){
+			return (new Date()).getTime();
+		};
+
+
+		ready(function(){
+			var defaultStyle = { width: "400px", height: "200px" };
+			var tmpl = new dtl.Template(dom.byId("template").value);
+			var context = new Context({ charts: charts });
+			dom.byId("charts").innerHTML = tmpl.render(context);
+
+			arr.forEach(charts, function(item, idx){
+				var start = now();
+				var n = dom.byId("chart_"+idx);
+				domStyle.set(n, item.style||defaultStyle);
+				item.makeChart(n);
+				console.debug((now()-start), "ms to create:", (idx+1)+":", item.description);
+			});
+		});
+	});
+	</script>
+</head>
+<body>
+	<textarea id="template" style="display: none;">
+		{% for item in charts %}
+			<p>{{ forloop.counter }}: {{ item.description }}</p>
+			<div id="chart_{{ forloop.counter0 }}"></div>
+		{% endfor %}
+	</textarea>
+
+	<h1>Chart 2D</h1>
+
+	<div id="charts"></div>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_chart2d_dynamics.html b/dojox/charting/tests/BidiSupport/mirror_chart2d_dynamics.html
new file mode 100644
index 0000000..ec93e0e
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_chart2d_dynamics.html
@@ -0,0 +1,261 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Chart 2D: dynamics</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+	@import "../../../../dijit/themes/tundra/tundra.css";
+
+	.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
+	.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.CheckBox");
+dojo.require("dijit.form.ComboBox");
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Columns");
+dojo.require("dojox.charting.plot2d.ClusteredColumns");
+dojo.require("dojox.charting.plot2d.StackedColumns");
+dojo.require("dojox.charting.plot2d.Bars");
+dojo.require("dojox.charting.plot2d.ClusteredBars");
+dojo.require("dojox.charting.plot2d.StackedBars");
+dojo.require("dojox.charting.plot2d.Areas");
+dojo.require("dojox.charting.plot2d.StackedAreas");
+dojo.require("dojox.charting.plot2d.Pie");
+dojo.require("dojox.charting.plot2d.Grid");
+dojo.require("dojox.charting.themes.CubanShirts");
+dojo.require("dojox.charting.widget.Legend");
+
+dojo.require("dojox.lang.functional.sequence");
+
+dojo.require("dojo.parser");
+
+var chart, legend, size = 10, magnitude = 30;
+
+var getData = function(){
+	var data = new Array(size);
+	for(var i = 0; i < size; ++i){
+		data[i] = Math.random() * magnitude;
+	}
+	return data;
+};
+
+var getZeroes = function(){
+	return dojox.lang.functional.repeat(size, "-> 0", 0);
+};
+
+var makeObjects = function(){
+	chart = new dojox.charting.Chart("test");
+	chart.setTheme(dojox.charting.themes.CubanShirts);
+
+	if(dijit.byId("hAxis").get("checked")){
+		chart.addAxis("x", {natural: true, includeZero: true, fixUpper: "minor"});
+	}
+
+	if(dijit.byId("vAxis").get("checked")){
+		chart.addAxis("y", {vertical: true, natural: true, includeZero: true, fixUpper: "minor"});
+	}
+
+	chart.addPlot("default", {type: dijit.byId("plot").get("value"), gap: 2});
+
+	if(dijit.byId("grid").get("checked")){
+		chart.addPlot("grid", {type: "Grid", hMinorLines: true, vMinorLines: true});
+	}
+
+	for(var i = 1; i <= 5; ++i){
+		if(dijit.byId("s" + i).get("checked")){
+			chart.addSeries("Series " + i, getData(), {stroke: {color: "black", width: 1}});
+		}
+	}
+	if(dijit.byId("s6").get("checked")){
+		chart.addSeries("Series 6", getZeroes(), {stroke: {color: "black", width: 1}});
+	}
+
+	chart.setDir("rtl");chart.render();
+	
+	legend = new dojox.charting.widget.Legend({chart: chart}, "legend");
+};
+
+dojo.addOnLoad(makeObjects);
+
+changePlot = function(){
+	var type = dijit.byId("plot").get("value");
+	chart.addPlot("default", {type: type, gap: 2});
+	chart.setDir("rtl");chart.render();
+	legend.refresh();
+};
+
+changeGrid = function(){
+	if(dijit.byId("grid").get("checked")){
+		chart.addPlot("grid", {type: "Grid", hMinorLines: true, vMinorLines: true});
+	}else{
+		chart.removePlot("grid");
+	}
+	chart.setDir("rtl");chart.render();
+};
+
+changeX = function(){
+	if(dijit.byId("hAxis").get("checked")){
+		chart.addAxis("x", {natural: true, includeZero: true, fixUpper: "minor"});
+	}else{
+		chart.removeAxis("x");
+	}
+	chart.setDir("rtl");chart.render();
+};
+
+changeY = function(){
+	if(dijit.byId("vAxis").get("checked")){
+		chart.addAxis("y", {vertical: true, natural: true, includeZero: true, fixUpper: "minor"});
+	}else{
+		chart.removeAxis("y");
+	}
+	chart.setDir("rtl");chart.render();
+};
+
+changeSeries = function(n){
+	if(n == 6){
+		// special case
+		if(dijit.byId("s6").get("checked")){
+			chart.addSeries("Series 6", getZeroes(), {stroke: {color: "black", width: 1}});
+		}else{
+			chart.removeSeries("Series 6");
+		}
+	}else{
+		if(dijit.byId("s" + n).get("checked")){
+			chart.addSeries("Series " + n, getData(), {stroke: {color: "black", width: 1}});
+			dijit.byId("sb" + n).get("disabled", false);
+		}else{
+			chart.removeSeries("Series " + n);
+			dijit.byId("sb" + n).get("disabled", true);
+		}
+	}
+	chart.setDir("rtl");chart.render();
+	legend.refresh();
+};
+
+addSeries = function(n){
+	chart.addSeries("Series " + n, getData(), {stroke: {color: "black", width: 1}});
+	chart.setDir("rtl");chart.render();
+	legend.refresh();
+};
+
+</script>
+</head>
+<body class="tundra">
+<h1>Chart 2D: dynamics</h1>
+		<button id="reset1" type="reset" dojoType="dijit.form.Button">Reset with no onClick handler should reset</button>
+
+<table>
+	<tr>
+		<td>Plot:</td>
+		<td>
+			<select dojoType="dijit.form.ComboBox" id="plot" onChange="changePlot()">
+				<option value="Columns">Columns</option>
+				<option value="ClusteredColumns">ClusteredColumns</option>
+				<option value="StackedColumns">StackedColumns</option>
+				<option value="Bars">Bars</option>
+				<option value="ClusteredBars">ClusteredBars</option>
+				<option value="StackedBars">StackedBars</option>
+				<option value="Areas">Areas</option>
+				<option value="StackedAreas">StackedAreas</option>
+				<option value="Pie">Pie</option>
+			</select>
+		</td>
+	</tr>
+	<tr>
+		<td>Grid:</td>
+		<td>
+			<input type="checkbox" dojoType="dijit.form.CheckBox" checked="true" id="grid" onChange="changeGrid()">
+			<label for="grid">include</label>
+		</td>
+	</tr>
+	<tr>
+		<td>X axis:</td>
+		<td>
+			<input type="checkbox" dojoType="dijit.form.CheckBox" checked="true" id="hAxis" onChange="changeX()">
+			<label for="hAxis">include</label>
+		</td>
+	</tr>
+	<tr>
+		<td>Y axis:</td>
+		<td>
+			<input type="checkbox" dojoType="dijit.form.CheckBox" checked="true" id="vAxis" onChange="changeY()">
+			<label for="vAxis">include</label>
+		</td>
+	</tr>
+	<tr>
+		<td>Series 1:</td>
+		<td>
+			<input type="checkbox" dojoType="dijit.form.CheckBox" checked="true" id="s1" onChange="changeSeries(1)">
+			<label for="s1">include</label>
+			 
+			<button dojoType="dijit.form.Button" id="sb1" onClick="addSeries(1)">Randomize</button>
+		</td>
+	</tr>
+	<tr>
+		<td>Series 2:</td>
+		<td>
+			<input type="checkbox" dojoType="dijit.form.CheckBox" checked="true" id="s2" onChange="changeSeries(2)">
+			<label for="s2">include</label>
+			 
+			<button dojoType="dijit.form.Button" id="sb2" onClick="addSeries(2)">Randomize</button>
+		</td>
+	</tr>
+	<tr>
+		<td>Series 3:</td>
+		<td>
+			<input type="checkbox" dojoType="dijit.form.CheckBox" checked="true" id="s3" onChange="changeSeries(3)">
+			<label for="s3">include</label>
+			 
+			<button dojoType="dijit.form.Button" id="sb3" onClick="addSeries(3)">Randomize</button>
+		</td>
+	</tr>
+	<tr>
+		<td>Series 4:</td>
+		<td>
+			<input type="checkbox" dojoType="dijit.form.CheckBox" checked="true" id="s4" onChange="changeSeries(4)">
+			<label for="s4">include</label>
+			 
+			<button dojoType="dijit.form.Button" id="sb4" onClick="addSeries(4)">Randomize</button>
+		</td>
+	</tr>
+	<tr>
+		<td>Series 5:</td>
+		<td>
+			<input type="checkbox" dojoType="dijit.form.CheckBox" checked="true" id="s5" onChange="changeSeries(5)">
+			<label for="s5">include</label>
+			 
+			<button dojoType="dijit.form.Button" id="sb5" onClick="addSeries(5)">Randomize</button>
+		</td>
+	</tr>
+	<tr>
+		<td>Series 6:</td>
+		<td>
+			<input type="checkbox" dojoType="dijit.form.CheckBox" checked="false" id="s6" onChange="changeSeries(6)">
+			<label for="s6">include</label>
+			 this series contains all 0 values
+		</td>
+	</tr>
+</table>
+<div id="test" style="width: 600px; height: 400px;"></div>
+<div id="legend"></div>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_chart2d_updating.html b/dojox/charting/tests/BidiSupport/mirror_chart2d_updating.html
new file mode 100644
index 0000000..dfd3c9d
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_chart2d_updating.html
@@ -0,0 +1,107 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+	<title>Chart 2D</title>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+	<script type="text/javascript">
+
+        dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Areas");
+        dojo.require("dojox.charting.plot2d.Grid");
+		dojo.require("dojox.charting.themes.PlotKit.orange");
+		dojo.require("dojox.charting.themes.Tufte");
+
+		var chart, limit = 10, magnitude = 30, counter = [0, 0, 0];
+
+		var randomValue = function(nCounter){
+			return {x: ++counter[nCounter], y: Math.random() * magnitude};
+		};
+
+		var makeSeries = function(len, nCounter){
+			var s = [];
+			do{
+				s.push(randomValue(nCounter));
+			}while(s.length < len);
+			return s;
+		};
+
+		var seriesA = makeSeries(limit, 0),
+			seriesB = makeSeries(limit, 1),
+			seriesC = makeSeries(limit, 2);
+
+		var makeObjects = function(){
+			chart = new dojox.charting.Chart("test");
+			chart.setTheme(dojox.charting.themes.Tufte);
+			chart.addAxis("x", {
+				fixLower: "minor", 
+				natural: true
+			});
+			chart.addAxis("y", {
+				vertical: true, 
+				min: 0, 
+				max: 30, 
+				majorTickStep: 5, 
+				minorTickStep: 1
+			});
+			chart.addPlot("default", {type: "Areas"});
+			chart.addSeries("Series A", seriesA);
+			chart.addSeries("Series B", seriesB);
+			chart.addSeries("Series C", seriesC);
+			chart.addPlot("grid", {
+				type: "Grid", hMinorLines: true
+			});
+			chart.setDir("rtl");
+			chart.render();
+
+			setInterval(function(){updateTest();}, 500);
+		};
+
+		var updateTest = function(){
+			seriesA.shift();
+			seriesA.push(randomValue(0));
+			chart.updateSeries("Series A", seriesA);
+
+			seriesB.shift();
+			seriesB.push(randomValue(1));
+			chart.updateSeries("Series B", seriesB);
+
+			seriesC.shift();
+			seriesC.push(randomValue(2));
+			chart.updateSeries("Series C", seriesC);
+
+			chart.setDir("rtl");
+			chart.render();
+		};
+
+		dojo.addOnLoad(makeObjects);
+
+	</script>
+</head>
+<body>
+	<h1>Chart 2D Updating Data</h1>
+	<p>
+		Areas, grey theme, axes, grid. Very crude example to show a chart
+		with updating values.
+	</p>
+	<div id="test" style="width: 400px; height: 400px;"></div>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_chartTitle.html b/dojox/charting/tests/BidiSupport/mirror_chartTitle.html
new file mode 100644
index 0000000..3f0bec6
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_chartTitle.html
@@ -0,0 +1,108 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Chart2D Title</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+	@import "../../../../dijit/themes/tundra/tundra.css";
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Lines");
+dojo.require("dojox.charting.plot2d.Columns");
+dojo.require("dojox.charting.themes.PlotKit.blue");
+dojo.require("dojox.charting.themes.PlotKit.cyan");
+dojo.require("dojox.charting.themes.PlotKit.green");
+dojo.require("dojox.charting.themes.PlotKit.orange");
+dojo.require("dojox.charting.themes.PlotKit.purple");
+dojo.require("dojox.charting.themes.PlotKit.red");
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.NumberSpinner");
+dojo.require("dojo.parser");
+
+var chart1;
+
+updateTitleGap = function(){
+	chart1.titleGap = dijit.byId("titleGap").get("value");
+	chart1.fullRender();
+}
+
+makeObjects = function(){
+	chart1 = new dojox.charting.Chart("test1", {title: "Production(ton)"}).
+			addAxis("x", {
+				includeZero: true, natural: true, fixLower: "major", fixUpper: "major",
+				labels: [
+					{value: 0, text: ""},{value: 1, text: "Jan"},{value: 2, text: "Feb"},
+					{value: 3, text: "Mar"},{value: 4, text: "Aprl"},{value: 5, text: "May"}
+				]
+			}).
+			addAxis("y", {
+				vertical: true, includeZero: true, natural: true, fixLower: "major", fixUpper: "major", majorTickStep: 2
+			}).
+			addPlot("default", {type: "Columns"}).
+			addSeries("Series A", [2, 6, 14, 3, 3], {stroke: {color: "orange"}, fill: "yellow"}).
+			addSeries("Series B", [2, 8, 8, 8, 6], {stroke: {color: "green"}, fill: "lightgreen"}).
+			setDir("rtl").
+			render();
+
+	var chart2 = new dojox.charting.Chart("test2", {
+				title: "Production(Quantity)", 
+				titlePos: "bottom", 
+				titleGap: 25,
+				titleFont: "normal normal normal 15pt Arial",
+				titleFontColor: "orange"
+			}).
+			addAxis("x", {
+				includeZero: true, natural: true, fixLower: "major", fixUpper: "major",
+				labels: [
+					{value: 0, text: ""},{value: 1, text: "Jan"},{value: 2, text: "Feb"},
+					{value: 3, text: "Mar"},{value: 4, text: "Aprl"},{value: 5, text: "May"}
+				]
+			}).
+			addAxis("y", {
+				vertical: true, includeZero: true, natural: true, fixLower: "major", fixUpper: "major", majorTickStep: 200
+			}).
+			addPlot("default", {type: "Lines"}).
+			addSeries("Series A", [400, 800, 200, 600, 600], {stroke: {color: "red"}, fill: "lightpink"}).
+			addSeries("Series B", [200, 300, 500, 700, 800], {stroke: {color: "blue"}, fill: "lightblue"}).
+			setDir("rtl").
+			render();
+};
+
+dojo.addOnLoad(makeObjects);
+
+</script>
+</head>
+<body class="tundra">
+<h1>Chart2D Title</h1>
+<p>Column chart with chart title</p>
+<p>
+    Title Gap: 
+    <input dojoType="dijit.form.NumberSpinner" id="titleGap" value="20" constraints="{min: 0, max: 100, fractional: false}" style="width: 8em;">
+     
+    <button dojoType="dijit.form.Button" onClick="updateTitleGap()">Apply</button>
+</p>
+<div id="test1" style="width: 400px; height: 300px;"></div>
+<p>Line chart with customized chart title</p>
+<div id="test2" style="width: 400px; height: 300px;"></div>
+
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_chartingsize.html b/dojox/charting/tests/BidiSupport/mirror_chartingsize.html
new file mode 100644
index 0000000..31285bd
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_chartingsize.html
@@ -0,0 +1,44 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<title>Test charting sizing</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<script type="text/javascript"
+				src="../../../../dojo/dojo.js"
+				data-dojo-config="isDebug:true,  parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+		<script type="text/javascript">
+			dojo.require("dojo.parser");
+		
+			dojo.require("dijit.layout.BorderContainer");
+			dojo.require("dojox.charting.widget.Chart");
+		    dojo.require("dojox.charting.axis2d.Default");
+		    dojo.require("dojox.charting.plot2d.Lines");
+		    dojo.require("dojox.charting.themes.PlotKit.orange");
+		</script>
+	</head>
+	<body style="width:90%;height:480px">
+		<div dojoType="dijit.layout.BorderContainer" gutters="true" id="borderContainer" style="width:100%;height:100%">
+     		<div dojoType="dojox.charting.widget.Chart" id="lineChart" direction="rtl"
+	    		theme="dojox.charting.themes.PlotKit.orange" region="center">
+				<div class="axis" name="x" font="italic normal bold 10pt Tahoma"></div>
+				<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true" font="italic normal bold 10pt Tahoma"></div>
+				<div class="plot" name="default" type="dojox.charting.plot2d.Lines"></div>
+				<div class="series" name="Series A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4, 7, 3, 4, 2, 1, 4, 4, 5"></div>
+				<div class="series" name="Series B" data="2, 1, 0.5, 1, 3, 8, 4, 1.7, 1.3, 4.1, 1, 5, 1, 2, 3"></div>
+            </div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_cylinders.html b/dojox/charting/tests/BidiSupport/mirror_cylinders.html
new file mode 100644
index 0000000..2d7edf7
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_cylinders.html
@@ -0,0 +1,72 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Cylinder chart</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+
+dojo.require("dojox.charting.Chart3D");
+dojo.require("dojox.charting.plot3d.Cylinders");
+
+makeObjects = function(){
+	var m = dojox.gfx3d.matrix;
+	var chart = new dojox.charting.Chart3D("test", 
+		{
+			lights:   [{direction: {x: 5, y: 5, z: -5}, color: "white"}],
+			ambient:  {color:"white", intensity: 2},
+			specular: "white"
+		},
+		[m.cameraRotateXg(10), m.cameraRotateYg(-10), m.scale(0.8), m.cameraTranslate(-50, -50, 0)]
+	);
+	
+	var plot1 = new dojox.charting.plot3d.Cylinders(500, 500, {gap: 10, material: "yellow"});
+	plot1.setData([1,2,3,2,1,2,3,4,5]);
+	chart.addPlot(plot1);
+	
+	var plot2 = new dojox.charting.plot3d.Cylinders(500, 500, {gap: 10, material: "red"});
+	plot2.setData([2,3,4,3,2,3,4,5,5]);
+	chart.addPlot(plot2);
+	
+	var plot3 = new dojox.charting.plot3d.Cylinders(500, 500, {gap: 10, material: "blue"});
+	plot3.setData([3,4,5,4,3,4,5,5,5]);
+	chart.addPlot(plot3);
+	chart.setDir("rtl");
+	chart.generate().render();
+	
+	//dojo.byId("out1").value = dojo.byId("test").innerHTML;
+	//dojo.byId("out2").value = dojox.gfx.utils.toJson(surface, true);
+};
+
+dojo.addOnLoad(makeObjects);
+
+</script>
+</head>
+<body>
+<h1>Cylinder chart</h1>
+<div id="test" style="width: 500px; height: 500px;"></div>
+<!--
+<p><button onclick="makeObjects();">Go</button></p>
+<p><textarea id="out1" cols="40" rows="5"></textarea></p>
+<p><textarea id="out2" cols="40" rows="5"></textarea></p>
+-->
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_dropLabels.html b/dojox/charting/tests/BidiSupport/mirror_dropLabels.html
new file mode 100644
index 0000000..b58c017
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_dropLabels.html
@@ -0,0 +1,122 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>	 
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Testing Axes</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+var chart1a, chart1b;
+function rotationXChanged(value){
+	value = parseInt(value);
+	chart1a.getAxis("x").opt.rotation = value;
+	chart1a.dirty = true;
+	chart1a.setDir("rtl").render();
+	chart1b.getAxis("x").opt.rotation = value;
+	chart1b.dirty = true;
+	chart1b.setDir("rtl").render();
+}
+function rotationYChanged(value){
+	value = parseInt(value);
+	chart1a.getAxis("y").opt.rotation = value;
+	chart1a.dirty = true;
+	chart1a.setDir("rtl").render();
+	chart1b.getAxis("y").opt.rotation = value;
+	chart1b.dirty = true;
+	chart1b.setDir("rtl").render();
+}
+require(["dojo/ready", "dojox/charting/Chart", "dojox/charting/axis2d/Default",
+	"dojox/charting/plot2d/Markers", "dojox/charting/action2d/MouseZoomAndPan", "dojox/charting/Theme"],
+		function(ready, Chart, Default, Markers,
+			MouseZoomAndPan, Theme){
+	ready(function(){
+
+		var myLabelFunc = function(text, value){
+			return text+" make it even longer";
+		};
+		chart1a = new Chart("test1a").
+        	    addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, font: "14px helvetica",
+					minorTickStep: 0.5, labelFunc: myLabelFunc, rotation: 30}).
+    	        addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true, labelFunc: myLabelFunc}).
+        	    addPlot("default", {type: Markers}).
+	            addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
+    	        addSeries("Series B", [{x: 3, y: 2}, {x: 4, y: 3}, {x: 5, y: 2}]).
+        	    addSeries("Series C", [{x: 5, y: 3}, {x: 6, y: 4}, {x: 7, y: 3}]).
+           		setDir("rtl").render();
+		new MouseZoomAndPan(chart1a);
+
+		chart1b = new Chart("test1b").
+        	    addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, font: "14px helvetica",
+					minorTickStep: 0.5, labelFunc: myLabelFunc, rotation: 30, leftBottom: false}).
+    	        addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true, labelFunc: myLabelFunc, leftBottom: false}).
+        	    addPlot("default", {type: Markers}).
+	            addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
+    	        addSeries("Series B", [{x: 3, y: 2}, {x: 4, y: 3}, {x: 5, y: 2}]).
+        	    addSeries("Series C", [{x: 5, y: 3}, {x: 6, y: 4}, {x: 7, y: 3}]).
+           		setDir("rtl").render();
+		new MouseZoomAndPan(chart1b);
+
+		var chart2 = new Chart("test2").
+        	    addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, font: "14px helvetica",
+					majorTickStep: 2, minorTickStep: 1,
+						labels: [ {value: 0, text:"this is a very very long label"},
+							{ value: 1, text:"sm"},
+							{ value: 2, text:"short" },
+							{ value: 3, text: "minor" },
+							{ value: 4, text:"la" },
+							{ value: 5, text: "label" },
+							{ value: 6, text: "el" }
+						]}).
+            	addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
+            	addPlot("default", {type: Markers}).
+            	addSeries("Series A", [{x: 0, y: 1}, {x: 2, y: 2}, {x: 4, y: 1}]).
+            	addSeries("Series B", [{x: 2, y: 2}, {x: 4, y: 3}, {x: 6, y: 2}]).
+            	addSeries("Series C", [{x: 4, y: 3}, {x: 6, y: 4}, {x: 8, y: 3}]).
+            	setDir("rtl").render();
+		new MouseZoomAndPan(chart2);
+
+
+		var chart3 = new Chart("test3").
+        	    addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, font: "14px helvetica",
+					majorTickStep: 0.5, minorTickStep: 0.1 }).
+            	addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
+            	addPlot("default", {type: Markers}).
+            	addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
+            	addSeries("Series B", [{x: 5, y: 2}, {x: 6, y: 3}, {x: 7, y: 2}]).
+            	addSeries("Series C", [{x: 9, y: 3}, {x: 10, y: 4}, {x: 11, y: 3}]).
+           		setDir("rtl").render();
+		new MouseZoomAndPan(chart3);
+	});
+});
+</script>
+</head>
+<body>
+<h1>Testing Axes drop labels</h1>
+<p>1: Axes with rotation & labelFunc</p>
+X Axis Label Rotation: <input onchange="rotationXChanged(this.value)" value="30"/>
+Y Axis Label Rotation: <input onchange="rotationYChanged(this.value)" value="0"/>
+<div id="test1a" style="width: 600px; height: 400px;"></div>
+<div id="test1b" style="width: 600px; height: 400px;"></div>
+<p>2: Axes with labels array.</p>
+<div id="test2" style="width: 600px; height: 200px;"></div>
+<p>3: Numeric axis.</p>
+<div id="test3" style="width: 320px; height: 180px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_fillstroke.html b/dojox/charting/tests/BidiSupport/mirror_fillstroke.html
new file mode 100644
index 0000000..1a0478e
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_fillstroke.html
@@ -0,0 +1,138 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Chart Fill & Stroke</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../../dijit/themes/tundra/tundra.css">
+		<style>
+			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
+			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+
+		<script type="text/javascript">
+			dojo.require("dojo.parser");	
+            dojo.require("dojox.charting.widget.Chart");
+            dojo.require("dojox.charting.axis2d.Default");
+            dojo.require("dojox.charting.plot2d.Pie");
+			dojo.require("dojox.charting.themes.PlotKit.base");
+            dojo.require("dojox.charting.themes.PlotKit.orange");
+            
+			seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
+			
+			blueColor =  "blue";
+			blackColor = "black";
+			nullColor = null;
+            
+            dojo.addOnLoad(function(){
+
+				(function(){
+					var dc = dojox.charting, pk = dc.themes.PlotKit;
+					pk.myorange = pk.base.clone();
+					pk.myorange.chart.fill =  "#f5eee6";
+					pk.orange.plotarea.fill = "#ff0000"; 
+					pk.myorange.colors = dc.Theme.defineColors({hue: 31, saturation: 60, low: 40, high: 88});
+				})();
+				
+				dojo.parser.parse();
+				
+				var chart3 = new dojox.charting.Chart("nchart3");
+				chart3.setTheme(dojox.charting.themes.PlotKit.myorange);
+				chart3.addPlot("default", {
+					type: "Pie",
+					fontColor: "white",
+					radius: 100
+				});
+				chart3.addSeries("Series B", seriesB);
+				chart3.render();
+				
+				var chart4 = new dojox.charting.Chart("nchart4", {fill : blueColor, black: blackColor });
+				chart4.setTheme(dojox.charting.themes.PlotKit.myorange);
+				chart4.addPlot("default", {
+					type: "Pie",
+					fontColor: "white",
+					radius: 100
+				});
+				chart4.addSeries("Series B", seriesB);
+				chart4.render();
+				
+				var chart5 = new dojox.charting.Chart("nchart5", {fill : nullColor});
+				chart5.setTheme(dojox.charting.themes.PlotKit.myorange);
+				chart5.addPlot("default", {
+					type: "Pie",
+					fontColor: "white",
+					radius: 100
+				});
+				chart5.addSeries("Series B", seriesB);
+				chart5.render();
+			
+            });
+			
+		</script>
+
+	</head>
+	<body class="tundra">
+		<h1>Chart Fill & Stroke</h1>
+		<table border="0" cellspacing="30">
+			<tr>
+				<td>
+				    <!-- orange theme must be used by default -->
+					<div dojoType="dojox.charting.widget.Chart" id="chart1" theme="dojox.charting.themes.PlotKit.myorange"
+							 style="width: 300px; border: black 1px">
+						<div class="plot" name="default" type="Pie" radius="100" fontColor="white"></div>
+						<div class="series" name="Series B" array="seriesB"></div>
+					</div>
+				</td>
+				<td>
+					<!--  fill & stroke must override orange theme -->
+					<div dojoType="dojox.charting.widget.Chart" id="chart2" theme="dojox.charting.themes.PlotKit.myorange"
+							 style="width: 300px; height: 300px;" fill="blueColor" stroke="blackColor">
+						<div class="plot" name="default" type="Pie" radius="100" fontColor="white"></div>
+						<div class="series" name="Series B" array="seriesB"></div>
+					</div>
+				</td>
+				<td>
+					<!--  fill must override remove orange theme chart fill by null color -->
+					<div dojoType="dojox.charting.widget.Chart" id="chart3" theme="dojox.charting.themes.PlotKit.myorange"
+							 style="width: 300px; height: 300px;" fill="nullColor">
+						<div class="plot" name="default" type="Pie" radius="100" fontColor="white"></div>
+						<div class="series" name="Series B" array="seriesB"></div>
+					</div>
+				</td>
+				
+			</tr>
+			<tr>
+				<td>
+					<div id="nchart3" style="width: 300px; height: 300px;">
+					</div>
+				</td>
+				<td>
+					<div id="nchart4" style="width: 300px; height: 300px;">
+					</div>
+				</td>
+				<td>
+					<div id="nchart5" style="width: 300px; height: 300px;">
+					</div>
+				</td>
+			</tr>
+		</table>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_fireEvent.html b/dojox/charting/tests/BidiSupport/mirror_fireEvent.html
new file mode 100644
index 0000000..d071646
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_fireEvent.html
@@ -0,0 +1,227 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Chart 2D: fireEvent test</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+	@import "../../../../dijit/themes/tundra/tundra.css";
+
+	.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
+	.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+
+    .events {font-size: 11pt;}
+    .events th, .events td {padding: 0.25em 1em;}
+    .events th {font-weight: bold;}
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.Select");
+dojo.require("dijit.form.NumberSpinner");
+
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Columns");
+dojo.require("dojox.charting.plot2d.ClusteredColumns");
+dojo.require("dojox.charting.plot2d.StackedColumns");
+dojo.require("dojox.charting.plot2d.Bars");
+dojo.require("dojox.charting.plot2d.ClusteredBars");
+dojo.require("dojox.charting.plot2d.StackedBars");
+dojo.require("dojox.charting.plot2d.Lines");
+dojo.require("dojox.charting.plot2d.StackedAreas");
+dojo.require("dojox.charting.plot2d.Pie");
+dojo.require("dojox.charting.plot2d.Grid");
+dojo.require("dojox.charting.themes.CubanShirts");
+dojo.require("dojox.charting.widget.Legend");
+dojo.require("dojox.charting.action2d.Base");
+dojo.require("dojox.charting.action2d.Highlight");
+dojo.require("dojox.charting.action2d.Magnify");
+dojo.require("dojox.charting.action2d.MoveSlice");
+dojo.require("dojox.charting.action2d.Shake");
+dojo.require("dojox.charting.action2d.Tooltip");
+
+dojo.require("dojox.lang.functional.sequence");
+
+dojo.require("dojo.parser");
+
+var chart, legend, size = 10, magnitude = 30, none = "<em>none</em>";
+
+
+var Listener = dojo.declare(dojox.charting.action2d.Base, {
+    constructor: function(chart, plot, tr){
+        this.tr = dojo.byId(tr);
+        this.connect();
+    },
+
+    process: function(o){
+        var t = [
+                o.plot ? o.plot.name : none,
+                o.type === "onindirect" ? o.type + " (" + (o.originalPlot ? o.originalPlot.name : none) + " : " + o.originalEvent + ")" : o.type,
+                o.event ? "object" : none,
+                o.hAxis || none,
+                o.vAxis || none,
+                o.run ? o.run.name : none,
+                "index" in o ? o.index : none,
+                "x" in o ? o.x : none,
+                "y" in o ? o.y : none
+            ];
+        dojo.query("td", this.tr).forEach(function(td, i){
+            td.innerHTML = t[i] + "";
+        });
+    }
+});
+
+function getData(){
+	var data = new Array(size);
+	for(var i = 0; i < size; ++i){
+		data[i] = Math.random() * magnitude;
+	}
+	return data;
+};
+
+function getZeroes(){
+	return dojox.lang.functional.repeat(size, "-> 0", 0);
+};
+
+var actions = [];
+
+function addActions(chart){
+	dojox.lang.functional.forEach(actions, ".disconnect()");
+	actions = [
+		new dojox.charting.action2d.Highlight(chart),
+		new dojox.charting.action2d.Magnify(chart),
+		new dojox.charting.action2d.MoveSlice(chart),
+		new dojox.charting.action2d.Tooltip(chart),
+		new Listener(chart, "default", "def")
+	];
+}
+
+function makeObjects(){
+	chart = new dojox.charting.Chart("test");
+	chart.setTheme(dojox.charting.themes.CubanShirts);
+
+	chart.addAxis("x", {natural: true, includeZero: true, fixUpper: "minor"});
+
+	chart.addAxis("y", {vertical: true, natural: true, includeZero: true, fixUpper: "minor"});
+
+	chart.addPlot("default", {type: dijit.byId("plot").get("value"), gap: 2});
+    addActions(chart);
+
+	chart.addPlot("empty"); // just to see indirect events
+    new Listener(chart, "empty", "emp");
+
+
+	chart.addPlot("grid", {type: "Grid", hMinorLines: true, vMinorLines: true});
+
+	for(var i = 1; i <= 5; ++i){
+		chart.addSeries("Series " + i, getData(), {stroke: {color: "black", width: 1}});
+	}
+
+	chart.setDir("rtl");chart.render();
+
+	legend = new dojox.charting.widget.Legend({chart: chart}, "legend");
+};
+
+dojo.addOnLoad(makeObjects);
+
+changePlot = function(){
+	var type = dijit.byId("plot").get("value"),
+        opts = {type: type, gap: 2};
+    switch(type){
+        case "Lines":
+        case "StackedAreas":
+            opts.markers = true;
+            break;
+        case "Pie":
+            opts.radius = 150;
+            break;
+    }
+	chart.addPlot("default", opts);
+    addActions(chart);
+	chart.setDir("rtl");chart.render();
+	legend.refresh();
+};
+
+fireEvent = function(type){
+    chart.fireEvent(
+        dijit.byId("series").get("value"),
+        type,
+        dijit.byId("index").get("value")
+    );
+}
+
+</script>
+</head>
+<body class="tundra">
+
+<h1>Chart 2D: fireEvent test</h1>
+
+<p>
+    <span>Plot: </span>
+    <select dojoType="dijit.form.Select" id="plot" onChange="changePlot()">
+        <option value="Columns">Columns</option>
+        <option value="ClusteredColumns">ClusteredColumns</option>
+        <option value="StackedColumns">StackedColumns</option>
+        <option value="Bars">Bars</option>
+        <option value="ClusteredBars">ClusteredBars</option>
+        <option value="StackedBars">StackedBars</option>
+        <option value="Lines">Lines</option>
+        <option value="StackedAreas">StackedAreas</option>
+        <option value="Pie">Pie</option>
+    </select>
+</p>
+
+<table class="events" border="1">
+    <thead>
+        <tr>
+            <th>Plot</th><th>Event</th><th>Event Object</th><th>H. axis</th><th>V. axis</th><th>Series</th><th>Index</th><th>X value</th><th>Y value</th>
+        </tr>
+    </thead>
+    <tbody>
+        <tr id="def">
+            <td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td>
+        </tr>
+        <tr id="emp">
+            <td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td><td> </td>
+        </tr>
+    </tbody>
+</table>
+
+<p>
+    <span>Fire event: </span>
+    <select dojoType="dijit.form.Select" id="series">
+        <option value="Series 1">Series 1</option>
+        <option value="Series 2">Series 2</option>
+        <option value="Series 3">Series 3</option>
+        <option value="Series 4">Series 4</option>
+        <option value="Series 5">Series 5</option>
+    </select>
+    <span> on index: </span>
+	<input dojoType="dijit.form.NumberSpinner" id="index" value="0" constraints="{min: 0, max: 9, fractional: false}" style="width: 5em;">
+     <button dojoType="dijit.form.Button" onClick="fireEvent('onmouseover')">onmouseover</button>
+     <button dojoType="dijit.form.Button" onClick="fireEvent('onmouseout')">onmouseout</button>
+     <button dojoType="dijit.form.Button" onClick="fireEvent('onclick')">onclick</button>
+</p>
+
+<p><em>Warning: the pie chart shows only the last series (Series 5).</em></p>
+
+<div id="test" style="width: 600px; height: 400px;"></div>
+<div id="legend"></div>
+
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_grid.html b/dojox/charting/tests/BidiSupport/mirror_grid.html
new file mode 100644
index 0000000..8985759
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_grid.html
@@ -0,0 +1,48 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+	<title>Chart 2D</title>
+	<style type="text/css">
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, has:{'dojo-bidi': true}"></script>
+	<script type="text/javascript">
+		require([
+		"dojo/ready",
+		"dojo/dom",
+		"dojox/charting/Chart",
+		"dojox/charting/axis2d/Default",
+		"dojox/charting/plot2d/Lines",	
+		"dojox/charting/plot2d/Grid"],
+		function(ready, dom, Chart, Axis, Lines, Grid){
+			ready(function(){
+				var chart = new Chart(dom.byId("chart")).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true  }).
+						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
+						addPlot("default", { type: Lines }).
+						addPlot("grid", { type: Grid, renderOnAxis: false, majorVLine: { color: "green", width: 3 }, majorHLine: { color: "red", width: 3 } }).
+						addSeries("Series A", [ 2, 1, 0.5, -1, -2 ] ).setDir("rtl").
+						render();
+			});
+	});
+	</script>
+	</head>
+	<body>
+		<h1>Grid</h1>
+			<div id="chart" style="width:400px; height:300px"></div>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_itemcolor.html b/dojox/charting/tests/BidiSupport/mirror_itemcolor.html
new file mode 100644
index 0000000..750fa83
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_itemcolor.html
@@ -0,0 +1,150 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Chart 2D</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../../dijit/themes/tundra/tundra.css">
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script type="text/javascript">
+			source = [
+				{x: 1, y: 2.6, size: 0.3, fill: "orange"},
+				{x: 2, y: 1.8, size: 0.4, fill: "orange"},
+				{x: 3, y: 2, size: 0.1 },
+				{x: 4, y: 1, size: 0.6},
+				{x: 5, y: 1.4, size: 0.5},
+				{x: 6, y: 0.7, size: 0.3},
+				{x: 7, y: 2, size: 0.6}
+			];
+			var styleFunc, changeLimits;
+			require([
+			
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/charting/widget/Chart",
+			"dojox/charting/axis2d/Default",
+			"dojox/charting/plot2d/Bars",
+			"dojox/charting/plot2d/Columns",
+			"dojox/charting/plot2d/Bubble",
+			"dojox/charting/plot2d/Areas",
+			"dojox/charting/plot2d/Scatter",
+			"dojox/charting/plot2d/Pie",
+			"dojox/charting/themes/PlotKit/orange",
+			"dojox/charting/themes/PlotKit/blue",
+			"dojox/charting/themes/PlotKit/green", "dojo/parser"], function(dom, registry){
+				changeLimits = function(){
+					registry.byId("chart1").chart.getPlot("default").dirty = true;
+					registry.byId("chart1").chart.render();
+					registry.byId("chart2").chart.getPlot("default").dirty = true;
+					registry.byId("chart2").chart.render();
+					registry.byId("chart3").chart.getPlot("default").dirty = true;
+					registry.byId("chart3").chart.render();
+					registry.byId("chart4").chart.getPlot("default").dirty = true;
+					registry.byId("chart4").chart.render();
+					registry.byId("chart5").chart.getPlot("default").dirty = true;
+					registry.byId("chart5").chart.render();
+					registry.byId("chart6").chart.getPlot("default").dirty = true;
+					registry.byId("chart6").chart.render();
+				};
+ 				styleFunc = function(item){
+					if(item.y < dom.byId("low").value){
+						return { fill : "red" };
+					}else if(item.y > dom.byId("high").value){
+						return { fill: "green" };
+					}
+					return {};
+				};
+			});
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Test Chart Item Coloring</h1>
+		<table border="0" cellspacing="30">
+			<tr>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart1" style="width: 300px; height: 300px;"
+							theme="dojox.charting.themes.PlotKit.blue">
+						<div class="axis" name="x" fixUpper="major" includeZero="true" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Bars" styleFunc="styleFunc" fill="'yellow'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart2" theme="dojox.charting.themes.PlotKit.orange"
+							fill="'lightgrey'" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal bold 10pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true" minorLabels="false"
+							font="italic normal bold 10pt Tahoma"></div>
+						<div class="plot" name="default" type="Columns" styleFunc="styleFunc" fill="'yellow'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart3" theme="dojox.charting.themes.PlotKit.green"
+							 style="width: 300px; height: 300px;">
+						<div class="plot" name="default" type="Pie" radius="100" fontColor="white" styleFunc="styleFunc" fill="'yellow'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart4" theme="dojox.charting.themes.PlotKit.orange"
+							fill="'lightgrey'" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal bold 10pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal bold 10pt Tahoma"></div>
+						<div class="plot" name="default" type="Bubble" styleFunc="styleFunc" fill="'yellow'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart5" theme="dojox.charting.themes.PlotKit.orange"
+							fill="'lightgrey'" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal bold 10pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal bold 10pt Tahoma"></div>
+						<div class="plot" name="default" type="Scatter" styleFunc="styleFunc" markerFill="'yellow'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart6" theme="dojox.charting.themes.PlotKit.orange"
+							fill="'lightgrey'" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal bold 10pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal bold 10pt Tahoma"></div>
+						<div class="plot" name="default" type="Areas" styleFunc="styleFunc" markerFill="'yellow'" markers="true" fill="'blue'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+			</tr>
+		</table>
+		<label>Low Limit</label>
+		<input id="low" type="text" onchange="changeLimits()" value="1"></input>
+		<label>High Limit</label>
+		<input id="high" type="text" onchange="changeLimits()" value="2"></input>
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_labels2d.html b/dojox/charting/tests/BidiSupport/mirror_labels2d.html
new file mode 100644
index 0000000..d7b4fd9
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_labels2d.html
@@ -0,0 +1,197 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Chart 2D labels</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Bars");
+
+makeObjects = function(){
+	var chart1 = new dojox.charting.Chart("test1");
+	chart1.addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true});
+	chart1.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true});
+	chart1.addPlot("default", {type: "Bars"});
+	chart1.addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "red"}, fill: "lightpink"});
+	chart1.addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"});
+	chart1.setDir("rtl");
+	chart1.render();
+	
+	var chart2 = new dojox.charting.Chart("test2");
+	chart2.addAxis("x", {
+		fixLower: "major", fixUpper: "major", includeZero: true, 
+		labels: [
+			//{value: 0, text: "zero"},
+			{value: 2, text: "two"},
+			{value: 4, text: "four"}
+		]
+	});
+	chart2.addAxis("y", {
+		vertical: true, fixLower: "major", fixUpper: "major", natural: true,
+		labels: [{value: 0, text: ""},
+			{value: 1, text: "Jan"}, {value: 2, text: "Feb"},
+			{value: 3, text: "Mar"}, {value: 4, text: "Apr"},
+			{value: 5, text: "May"}, {value: 6, text: "Jun"}]
+	});
+	chart2.addPlot("default", {type: "Bars"});
+	chart2.addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "red"}, fill: "lightpink"});
+	chart2.addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"});
+	chart2.setDir("rtl");
+	chart2.render();
+
+	
+	var chart3 = new dojox.charting.Chart("test3");
+	chart3.addAxis("x", {
+		fixLower: "major", fixUpper: "major", includeZero: true, 
+		labels: [{value: 0, text: "z e r o"}, {value: 2, text: "t w o"}, {value: 4, text: "f o u r"}]
+	});
+	chart3.addAxis("y", {
+		vertical: true, fixLower: "major", fixUpper: "major", natural: true,
+		labels: [{value: 0, text: ""},
+			{value: 1, text: "J A N"}, {value: 2, text: "F E B"},
+			{value: 3, text: "M A R"}, {value: 4, text: "A P R"},
+			{value: 5, text: "M A Y"}, {value: 6, text: "J U N"}]
+	});
+	chart3.addPlot("default", {type: "Bars"});
+	chart3.addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "red"}, fill: "lightpink"});
+	chart3.addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"});
+	chart3.setDir("rtl");
+	chart3.render();
+	
+	var chart4 = new dojox.charting.Chart("test4");
+	chart4.addAxis("x", {
+		majorLabels: false,
+		includeZero: true, 
+		minorTicks: false, 
+		microTicks: false, 
+		majorTick: { length: 0 }
+	});
+	chart4.addAxis("y", {
+		vertical: true, 
+		fixLower: "none", 
+		fixUpper: "none", 
+		natural: true,
+		majorTick: { length: 3 },
+		labels: [
+			{value: 0, text: ""},
+			{value: 1, text: "January"}, 
+			{value: 2, text: "Febuary"},
+			{value: 3, text: "March"}, 
+			{value: 4, text: "April"},
+			{value: 5, text: "May"} 
+		]
+	});
+	chart4.addPlot("default", { type: "Bars", gap: 3 });
+	chart4.addSeries(
+		"Series A", 
+		[ 1, 6, 9, 4, 5, 2 ],
+		{
+			stroke: {width: 0}, 
+			// fill: "#ffcc2d",
+			fill: {
+				type: "linear",
+				x1: 0, y1: 0,
+				x2: 150, y2: 0,
+				colors: [
+					{ offset: 0,   color: "#ffe495" },
+					{ offset: 1,   color: "#ffcc2d" }
+				]
+			}
+		}
+	);
+	chart4.setDir("rtl");
+	chart4.render();
+
+	var chart5 = new dojox.charting.Chart("test5").
+			addAxis("x", {
+				fixLower: "major", fixUpper: "major", includeZero: true, 
+				labels: [
+					{value: 0, text: "zero"},
+					{value: 2, text: "two"},
+					{value: 4, text: "four"}
+				],
+				rotation: 30
+			}).
+			addAxis("y", {
+				vertical: true, fixLower: "major", fixUpper: "major", natural: true,
+				labels: [{value: 0, text: ""},
+					{value: 1, text: "January"}, {value: 2, text: "February"},
+					{value: 3, text: "March"}, {value: 4, text: "April"},
+					{value: 5, text: "May"}, {value: 6, text: "June"}
+				],
+				rotation: -30
+			}).
+			addPlot("default", {type: "Bars"}).
+			addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "red"}, fill: "lightpink"}).
+			addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"}).
+			setDir("rtl").
+			render();
+
+	var chart6 = new dojox.charting.Chart("test6").
+			addAxis("x", {
+				fixLower: "major", fixUpper: "major", includeZero: true, 
+				labels: [
+					{value: 0, text: "zero"},
+					{value: 2, text: "two"},
+					{value: 4, text: "four"}
+				],
+				rotation: 180
+			}).
+			addAxis("y", {
+				vertical: true, fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 2,
+				labels: [{value: 0, text: ""},
+					{value: 1, text: "January"}, {value: 2, text: "February"},
+					{value: 3, text: "March"}, {value: 4, text: "April"},
+					{value: 5, text: "May"}, {value: 6, text: "June"}
+				],
+				rotation: 90
+			}).
+			addPlot("default", {type: "Bars"}).
+			addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "red"}, fill: "lightpink"}).
+			addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"}).
+			setDir("rtl").
+			render();
+};
+
+dojo.addOnLoad(makeObjects);
+
+</script>
+</head>
+<body>
+<h1>Chart 2D labels</h1>
+<!--<p><button onclick="makeObjects();">Go</button></p>-->
+<p>1: Bars, axes aligned on major ticks, no minor ticks, custom strokes and fills.</p>
+<div id="test1" style="width: 200px; height: 200px;"></div>
+<p>2: Bars, axes aligned on major ticks, no minor ticks, custom strokes and fills, custom labels.</p>
+<div id="test2" style="width: 200px; height: 200px;"></div>
+<p>3: Bars, axes aligned on major ticks, no minor ticks, custom strokes and fills, custom labels with spaces.</p>
+<div id="test3" style="width: 200px; height: 200px;"></div>
+<p>4: Trying to make it look good.</p>
+<div id="test4" style="width: 200px; height: 200px;"></div>
+<p>5: Label rotation.</p>
+<div id="test5" style="width: 200px; height: 200px;"></div>
+<p>6: Label rotation (opposite).</p>
+<div id="test6" style="width: 200px; height: 200px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_legend.html b/dojox/charting/tests/BidiSupport/mirror_legend.html
new file mode 100644
index 0000000..60fa29e
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_legend.html
@@ -0,0 +1,73 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Chart 2D</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../../dijit/themes/tundra/tundra.css">
+		<style>
+			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
+			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script type="text/javascript">
+			var seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
+			var onClick;
+			require([
+			"dijit/registry",
+			"dijit/form/Button",
+			"dojox/charting/widget/Chart",
+			"dojox/charting/axis2d/Default",
+			"dojox/charting/plot2d/Default",
+			"dojox/charting/widget/Legend",
+			"dojo/parser"], function(registry){
+				onClick = function(){
+					var chart = registry.byId("chart1").chart;
+					chart.addSeries("Run B", [6.2, 1.4, 1, 2, 4.1, 6.3, 5]);
+					chart.render();
+					registry.byId("legend1").refresh();
+				}
+			});
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Legend</h1>
+
+		<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart1" style="width: 300px; height: 300px;">
+			<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+			<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+				font="italic normal normal 8pt Tahoma"></div>
+			<div class="plot" name="default" type="Default" markers="true" markerFill="'red'"></div>
+			<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+		</div>
+		<div direction="rtl" data-dojo-type="dojox.charting.widget.Legend" chartRef="chart1" id="legend1"></div>
+
+		<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart2" style="width: 300px; height: 300px;">
+			<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+			<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+				font="italic normal normal 8pt Tahoma"></div>
+			<div class="plot" name="default" type="Default" markers="true" lines="false" markerFill="'red'"></div>
+			<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+		</div>
+		<div direction="rtl" data-dojo-type="dojox.charting.widget.Legend" chartRef="chart2"></div>
+		<button data-dojo-type="dijit.form.Button" onclick="onClick()">Click me</button>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_missingPoints.html b/dojox/charting/tests/BidiSupport/mirror_missingPoints.html
new file mode 100644
index 0000000..b604e98
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_missingPoints.html
@@ -0,0 +1,221 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Test Missing point interpolation</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../../dijit/themes/tundra/tundra.css">
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script type="text/javascript">
+			var seriesA = [
+				{ x: 1, y : null },
+				{ x: 2, y : 2 },
+				{ x: 3, y : 2 },
+				{ x: 4, y: null },
+				{ x: 5, y: null },
+				{ x: 6, y: 3 },
+				{ x: 7, y: 4 },
+				{ x: 8, y: null },
+				{ x: 9, y: 5 },
+				{ x: 10, y: 6 },
+				{ x: 13, y: 7 },
+				{ x: 14, y: 8 }
+				
+			];
+			var seriesB = [null, 3, 3, null, null, 4, 5, null, 6, 7, 7, 8];
+			var seriesC = [
+				{ x: 2, y: 4 },
+				{ x: 3, y: 4 },
+				{ x: 6, y: 5 },
+				{ x: 7, y: 6 },
+				{ x: 9, y: 7 },
+				{ x: 10, y: 8 },
+				{ x: 13, y: 9 },
+				{ x: 14, y: 10 }
+			];
+			// in theory this should not happen, this is really invalid data set...
+			var seriesD = [
+				null,
+				{ x: 2, y : 5 },
+				{ x: 3, y : 5 },
+				null,
+				null,
+				{ x: 6, y: 6 },
+				{ x: 7, y: 7 },
+			    null,
+				{ x: 9, y: 8 },
+				{ x: 10, y: 9 },
+				null, null
+			];
+			require([
+			"dojox/charting/widget/Chart",
+			"dojox/charting/axis2d/Default",
+			"dojox/charting/plot2d/Lines",
+			"dojox/charting/plot2d/StackedLines",
+			"dojox/charting/plot2d/Columns",
+			"dojox/charting/plot2d/StackedColumns",
+			"dojox/charting/plot2d/ClusteredColumns",
+			"dojox/charting/plot2d/Bars",
+			"dojox/charting/plot2d/StackedBars",
+			"dojox/charting/plot2d/ClusteredBars",
+			"dojox/charting/themes/Adobebricks",
+			"dojo/parser"]);
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Chart with missing data points</h1>
+		<table border="0" cellspacing="30">
+			<tr>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox/charting/widget/Chart" id="chart1" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Lines"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run B" array="seriesB"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox/charting/widget/Chart" id="chart2" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Lines" interpolate="true"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run B" array="seriesB"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox/charting/widget/Chart" id="chart3" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="StackedLines"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox/charting/widget/Chart" id="chart4" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="StackedLines" interpolate="true"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox/charting/widget/Chart" id="chart5" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Columns"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox/charting/widget/Chart" id="chart6" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="y" font="italic normal normal 8pt Tahoma" fixUpper="major" ></div>
+						<div class="axis" name="x" vertical="true" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Bars"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox/charting/widget/Chart" id="chart7" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major"  
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="StackedColumns"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox/charting/widget/Chart" id="chart8" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="y" font="italic normal normal 8pt Tahoma" fixUpper="major" ></div>
+						<div class="axis" name="x" vertical="true" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="StackedBars"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox/charting/widget/Chart" id="chart9" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="ClusteredColumns"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox/charting/widget/Chart" id="chart10" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="y" font="italic normal normal 8pt Tahoma" fixUpper="major"></div>
+						<div class="axis" name="x" vertical="true"  
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="ClusteredBars"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+			</tr>
+		</table>
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_mouseIndicator.html b/dojox/charting/tests/BidiSupport/mirror_mouseIndicator.html
new file mode 100644
index 0000000..644d1de
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_mouseIndicator.html
@@ -0,0 +1,65 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<title>Mouse Indicator</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style type="text/css">
+ at import "../../../../dojo/resources/dojo.css";
+
+ at import "../../../../dijit/themes/tundra/tundra.css";
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js"
+	data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+			dojo.require("dojo.parser");
+
+			dojo.require("dojox.charting.Chart");
+            dojo.require("dojox.charting.axis2d.Default");
+            dojo.require("dojox.charting.plot2d.Lines");
+			dojo.require("dojox.charting.action2d.MouseIndicator");
+			
+			var chart;
+			makeObjects = function(){
+				chart = new dojox.charting.Chart("chart");
+				chart.addAxis("x", {type : "Default", fixLower: "minor", natural: true, stroke: "gray",
+					majorTick: {color: "red", length: 4}, minorTick: {color: "blue", length: 2}});
+				chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 10, minorTickStep: 5, stroke: "gray",
+					majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+				chart.addPlot("default", {type: "Default", markers: false});
+				chart.addSeries("Series A", [
+					 8,  7,  3,  2,  5,  7,  9, 10,  2, 10,
+					14, 16, 18, 13, 16, 15, 20, 19, 15, 12,
+					24, 20, 20, 26, 28, 26, 28, 29, 24, 29,
+					31, 35, 37, 31, 35, 37, 37, 36, 31, 30,
+					50, 49, 42, 46, 44, 40, 47, 43, 48, 47,
+					51, 52, 52, 51, 54, 57, 58, 50, 54, 51,
+					62, 68, 67, 62, 62, 65, 61, 66, 65, 62,
+					74, 78, 78, 77, 74, 74, 72, 74, 70, 78,
+					84, 83, 85, 86, 86, 89, 89, 85, 86, 86,
+					98, 97, 93, 91, 92, 92, 99, 93, 94, 92
+				]);
+				new dojox.charting.action2d.MouseIndicator(chart, "default", { series : "Series A", mouseOver: true  });
+				chart.setDir("rtl");chart.render();
+			};
+		
+			dojo.addOnLoad(makeObjects);
+			
+		</script>
+</head>
+<body class="tundra" style="height: 100%; width: 100%">
+    	<div id="chart" style="width:640px;height:480px"></div>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_mouseIndicator2.html b/dojox/charting/tests/BidiSupport/mirror_mouseIndicator2.html
new file mode 100644
index 0000000..c3fb1c6
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_mouseIndicator2.html
@@ -0,0 +1,69 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<title>Mouse Indicator</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+		<script type="text/javascript">
+			require(["dojo/ready", "dojo/on", "dojox/charting/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Lines",
+				"dojox/charting/action2d/MouseZoomAndPan", "dojox/charting/action2d/MouseIndicator"],
+				function(ready, on, Chart, Default, Lines, MouseZoomAndPan, MouseIndicator){
+
+				ready(function(){
+					var chart = new Chart("chart", { margins : {l :20, t:10, b:10, r: 50}});
+					chart.addAxis("x", {fixLower: "minor", natural: true, stroke: "gray",
+						majorTick: {color: "red", length: 4}, minorTick: {color: "blue", length: 2}});
+					chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 10, minorTickStep: 5, stroke: "gray",
+						majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+					chart.addPlot("default", {type: Lines, markers: false});
+					chart.addSeries("Series A", [
+						{ x: 1, y: 8},{ x: 2, y: 7},{ x: 3, y: 3},{ x: 4, y: 2},{ x: 5, y: 5},{ x: 6, y: 7},{ x: 7, y: 9},{ x: 8, y: 10},{ x: 9, y: 2},{ x: 10, y: 10},
+						{ x: 15, y: 14},{ x: 16, y: 16},{ x: 17, y: 18},{ x: 18, y: 13},{ x: 19, y: 16},{ x: 20, y: 15},{ x: 21, y: 20},{ x: 22, y: 19},{ x: 23, y: 15},{ x: 24, y: 12},
+						{ x: 25, y: 24},{ x: 26, y: 20},{ x: 27, y: 20},{ x: 28, y: 26},{ x: 29, y: 28},{ x: 30, y: 26},{ x: 31, y: 28},{ x: 32, y: 29},{ x: 33, y: 24},{ x: 34, y: 29},
+						{ x: 35, y: 31},{ x: 36, y: 35},{ x: 37, y: 37},{ x: 38, y: 31},{ x: 39, y: 35},{ x: 40, y: 37},{ x: 41, y: 37},{ x: 42, y: 36},{ x: 43, y: 31},{ x: 44, y: 30},
+						{ x: 45, y: 50},{ x: 46, y: 49},{ x: 47, y: 42},{ x: 48, y: 46},{ x: 49, y: 44},{ x: 50, y: 40},{ x: 51, y: 47},{ x: 52, y: 43},{ x: 53, y: 48},{ x: 54, y: 47},
+						{ x: 55, y: 51},{ x: 56, y: 52},{ x: 57, y: 52},{ x: 58, y: 51},{ x: 59, y: 54},{ x: 60, y: 57},{ x: 61, y: 58},{ x: 62, y: 50},{ x: 63, y: 54},{ x: 64, y: 51},
+						{ x: 65, y: 62},{ x: 66, y: 68},{ x: 67, y: 67},{ x: 68, y: 62},{ x: 69, y: 62},{ x: 70, y: 65},{ x: 71, y: 61},{ x: 72, y: 66},{ x: 73, y: 65},{ x: 74, y: 62},
+						{ x: 75, y: 74},{ x: 76, y: 78},{ x: 77, y: 78},{ x: 78, y: 77},{ x: 79, y: 74},{ x: 80, y: 74},{ x: 81, y: 72},{ x: 82, y: 74},{ x: 83, y: 70},{ x: 84, y: 78},
+						{ x: 85, y: 84},{ x: 86, y: 83},{ x: 87, y: 85},{ x: 88, y: 86},{ x: 89, y: 86},{ x: 90, y: 89},{ x: 91, y: 89},{ x: 92, y: 85},{ x: 93, y: 86},{ x: 94, y: 86},
+						{ x: 95, y: 98},{ x: 96, y: 97},{ x: 97, y: 93},{ x: 98, y: 91},{ x: 99, y: 92},{ x: 100, y: 92}
+					]);
+					new MouseZoomAndPan(chart, "default", { axis: "x", enableScroll: false });
+					var i = MouseIndicator(chart, "default", { series: "Series A",
+						font: "normal normal bold 12pt Tahoma",	fillFunc: function(v){
+								return v.y>55?"green":"red";
+							}, 	labelFunc: function(v){
+								return "x: "+v.x+", y:"+v.y;
+							}});
+					on(i, "Change", function(evt){
+						if(evt.label){
+							console.log(evt.label+" ("+evt.start.x+", "+evt.start.y+")");
+						}
+					});
+					chart.setDir("rtl");
+					chart.render();
+				})
+			});
+		</script>
+	</head>
+	<body class="tundra" style="height:100%;width:100%">
+    	<div id="chart" style="width:640px;height:480px"></div>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_mouseZoomAndPan.html b/dojox/charting/tests/BidiSupport/mirror_mouseZoomAndPan.html
new file mode 100644
index 0000000..1ebdbae
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_mouseZoomAndPan.html
@@ -0,0 +1,81 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<title>Mouse Zoom And Pan</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+		<script type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("dojox.charting.Chart");
+            dojo.require("dojox.charting.axis2d.Default");
+            dojo.require("dojox.charting.plot2d.Lines");
+			dojo.require("dojox.charting.themes.PlotKit.orange");
+			dojo.require("dojox.charting.action2d.MouseZoomAndPan");
+			
+			var chart;
+			makeObjects = function(){
+				chart = new dojox.charting.Chart("chart");
+				chart.setTheme(dojox.charting.themes.PlotKit.orange);
+				chart.addAxis("x", {type : "Default", fixLower: "minor", natural: true, stroke: "gray", enableCache: true,
+									htmlLabels: false, majorTick: {color: "red", length: 4}, minorTick: {color: "blue", length: 2}});
+				chart.addAxis("alternate", {type : "Default", fixLower: "minor", natural: true, stroke: "gray", enableCache: true,
+					htmlLabels: false, majorTick: {color: "red", length: 4}, minorTick: {color: "blue", length: 2}, leftBottom: false});
+				chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 10, minorTickStep: 5, stroke: "gray",
+					majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+				chart.addPlot("default", {type: "Default", markers: false});
+				chart.addPlot("second", {type: "Default", markers: false, hAxis:"alternate"});
+				chart.addSeries("Series A", [
+					 8,  7,  3,  2,  5,  7,  9, 10,  2, 10,
+					14, 16, 18, 13, 16, 15, 20, 19, 15, 12,
+					24, 20, 20, 26, 28, 26, 28, 29, 24, 29,
+					31, 35, 37, 31, 35, 37, 37, 36, 31, 30,
+					50, 49, 42, 46, 44, 40, 47, 43, 48, 47,
+					51, 52, 52, 51, 54, 57, 58, 50, 54, 51,
+					62, 68, 67, 62, 62, 65, 61, 66, 65, 62,
+					74, 78, 78, 77, 74, 74, 72, 74, 70, 78,
+					84, 83, 85, 86, 86, 89, 89, 85, 86, 86,
+					98, 97, 93, 91, 92, 92, 99, 93, 94, 92
+				]);
+				chart.addSeries("Series B", [
+					 3,  1,  3,  2,  4,  7,  9, 10,  2, 9,
+					14, 16, 18, 15, 13, 14, 21, 18, 17, 14,
+					24, 20, 25, 22, 28, 26, 28, 29, 24, 29,
+					31, 35, 37, 31, 34, 37, 37, 34, 39, 30,
+				 	48, 44, 47, 48, 41, 41, 43, 49, 44, 45,
+					52, 56, 52, 51, 58, 56, 57, 59, 54, 51,
+					61, 63, 63, 62, 61, 61, 61, 63, 64, 63,
+					73, 70, 79, 76, 73, 73, 74, 75, 75, 75,
+					85, 88, 81, 81, 85, 85, 81, 83, 84, 84,
+					95, 96, 93, 88, 97, 93, 91, 95, 98, 92
+				], {plot: "second"});
+				new dojox.charting.action2d.MouseZoomAndPan(chart, "default", { axis: "x", keyZoomModifier: dojo.isIE?"none":"ctrl" });
+				new dojox.charting.action2d.MouseZoomAndPan(chart, "second", { axis: "alternate", keyZoomModifier: dojo.isIE?"none":"ctrl" });
+				chart.setDir("rtl");
+				chart.render();
+			};
+		
+			dojo.addOnLoad(makeObjects);
+			
+		</script>
+	</head>
+	<body class="tundra" style="height:100%;width:100%">
+    	<div id="chart" style="width:640px;height:480px"></div>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_nulls.html b/dojox/charting/tests/BidiSupport/mirror_nulls.html
new file mode 100644
index 0000000..972877a
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_nulls.html
@@ -0,0 +1,115 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<title>Chart 2D nulls</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<style>
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+</style>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+<script>
+
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Lines");
+dojo.require("dojox.charting.plot2d.Areas");
+dojo.require("dojox.charting.plot2d.Markers");
+dojo.require("dojox.charting.plot2d.StackedLines");
+dojo.require("dojox.charting.plot2d.StackedAreas");
+dojo.require("dojox.charting.plot2d.Bars");
+dojo.require("dojox.charting.plot2d.ClusteredBars");
+dojo.require("dojox.charting.plot2d.StackedBars");
+dojo.require("dojox.charting.plot2d.ClusteredColumns");
+dojo.require("dojox.charting.plot2d.StackedColumns");
+dojo.require("dojox.charting.plot2d.Bubble");
+dojo.require("dojox.charting.plot2d.Candlesticks");
+dojo.require("dojox.charting.plot2d.Pie");
+
+makeObjects = function(){
+
+	var types = [ "Areas", "Bars", "ClusteredBars", "ClusteredColumns", "Lines", "Markers", "StackedAreas", "StackedBars", "StackedColumns", "StackedLines" ];
+
+	dojo.forEach(types, function(type, i){
+		new dojox.charting.Chart("test" + (i + 1))
+		.addAxis("x", { vertical: false, min: 0, max: 15 })
+		.addAxis("y", { vertical: true, min: 0, max: 15 })
+		.addPlot("default", { type: type })
+		.addSeries("Series A", [3, 5, null, 4, 0, 4, null, 1, 6, 5], { stroke: {color: "blue"}, fill: "lightblue" })
+		.addSeries("Series B", [6, 9, null, 5, 10, 7, 6, 3, 8, 6], { stroke: {color: "red"}, fill: "lightpink" })
+		.setDir("rtl").render();
+	});
+	
+	new dojox.charting.Chart("test10")
+	.addAxis("x", { vertical: false, min: 0, max: 15 })
+	.addAxis("y", { vertical: true, min: 0, max: 15 })
+	.addPlot("default", { type: "Candlesticks" })
+	.addSeries("Series A", [
+		{ low: 2, open: 3, close: 4, high: 9 },
+		{ low: 2, open: 5, close: 7, high: 8 },
+		null, 
+		{ low: 2, open: 4, close: 2, high: 5 },
+		{ low: 0, open: 0, close: 3, high: 3 },
+		{ low: 3, open: 4, close: 6, high: 7 },
+		null, 
+		{ low: 1, open: 1, close: 1, high: 1 },
+		{ low: 2, open: 6, close: 3, high: 8 },
+		{ low: 3, open: 5, close: 9, high: 10 }
+	], { stroke: {color: "blue"}, fill: "lightblue" })
+	.setDir("rtl").render();
+	
+	new dojox.charting.Chart("test11")
+	.addPlot("default", { type: "Pie" })
+	.addSeries("Series A", [3, 5, null, 4, 0, 4, null, 1, 6, 5])
+	.setDir("rtl").render();
+	
+	new dojox.charting.Chart("test12")
+	.addAxis("x", { vertical: false, min: 0, max: 15 })
+	.addAxis("y", { vertical: true, min: 0, max: 15 })
+	.addPlot("default", { type: "Bubble" })
+	.addSeries("Series A", [
+		{ x: 2, y: 5, size: 2 },
+		null,
+		{ x: 8, y: 6, size: 5 },
+		{ x: 5, y: 9, size: 4 },
+		null,
+		{ x: 5, y: 1, size: 1 }
+	])
+	.setDir("rtl").render();
+	
+};
+
+dojo.addOnLoad(makeObjects);
+
+</script>
+</head>
+<body>
+<h1>Chart 2D nulls in series</h1>
+<div id="test1" style="width: 200px; height: 200px;"></div>
+<div id="test2" style="width: 200px; height: 200px;"></div>
+<div id="test3" style="width: 200px; height: 200px;"></div>
+<div id="test4" style="width: 200px; height: 200px;"></div>
+<div id="test5" style="width: 200px; height: 200px;"></div>
+<div id="test6" style="width: 200px; height: 200px;"></div>
+<div id="test7" style="width: 200px; height: 200px;"></div>
+<div id="test8" style="width: 200px; height: 200px;"></div>
+<div id="test9" style="width: 200px; height: 200px;"></div>
+<div id="test10" style="width: 200px; height: 200px;"></div>
+<div id="test11" style="width: 200px; height: 200px;"></div>
+<div id="test12" style="width: 200px; height: 200px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_pie2d.html b/dojox/charting/tests/BidiSupport/mirror_pie2d.html
new file mode 100644
index 0000000..4724784
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_pie2d.html
@@ -0,0 +1,166 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Pie 2D</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.plot2d.Pie");
+dojo.require("dojox.charting.themes.PlotKit.blue");
+dojo.require("dojox.charting.themes.PlotKit.green");
+dojo.require("dojox.charting.themes.PlotKit.red");
+dojo.require("dojox.charting.themes.Adobebricks");
+dojo.require("dojox.charting.themes.Algae");
+
+makeObjects = function(){
+	var chart1 = new dojox.charting.Chart("test1");
+	chart1.setTheme(dojox.charting.themes.PlotKit.blue);
+	chart1.addPlot("default", {
+		type: "Pie",
+		font: "normal normal bold 12pt Tahoma",
+		fontColor: "white",
+		labelOffset: 40
+	});
+	chart1.addSeries("Series A", [4, 2, 1, 1]);
+	chart1.setDir("rtl");
+	chart1.render();
+
+	var chart2 = new dojox.charting.Chart("test2");
+	chart2.setTheme(dojox.charting.themes.PlotKit.blue);
+	chart2.addPlot("default", {
+		type: "Pie",
+		font: "normal normal bold 12pt Tahoma",
+		fontColor: "black",
+		labelOffset: -25,
+		precision: 0
+	});
+	chart2.addSeries("Series A", [4, 2, 1, 1]);
+	chart2.render();
+
+	var chart3 = new dojox.charting.Chart("test3");
+	chart3.setTheme(dojox.charting.themes.PlotKit.green);
+	chart3.addPlot("default", {
+		type: "Pie",
+		font: "normal normal bold 10pt Tahoma",
+		fontColor: "white",
+		labelOffset: 25,
+		radius: 90
+	});
+	chart3.addSeries("Series A", [4, 2, 1, 1]);
+	chart3.render();
+
+	var chart4 = new dojox.charting.Chart("test4");
+	chart4.setTheme(dojox.charting.themes.PlotKit.green);
+	chart4.addPlot("default", {
+		type: "Pie",
+		font: "normal normal bold 10pt Tahoma",
+		fontColor: "black",
+		labelOffset: -25,
+		radius: 90
+	});
+	chart4.addSeries("Series A", [4, 2, 1, 1]);
+	chart4.render();
+
+	var chart5 = new dojox.charting.Chart("test5");
+	chart5.setTheme(dojox.charting.themes.PlotKit.red);
+	chart5.addPlot("default", {
+		type: "Pie",
+		font: "normal normal bold 14pt Tahoma",
+		fontColor: "white",
+		labelOffset: 40
+	});
+	chart5.addSeries("Series A", [{y: 4, text: "Red"}, {y: 2, text: "Green"}, {y: 1, text: "Blue"}, {y: 1, text: "Other"}]);
+	chart5.render();
+
+	var chart6 = new dojox.charting.Chart("test6");
+	chart6.setTheme(dojox.charting.themes.PlotKit.red);
+	chart6.addPlot("default", {
+		type: "Pie",
+		font: "normal normal bold 14pt Tahoma",
+		fontColor: "white",
+		labelOffset: 40,
+		startAngle: -45
+	});
+	chart6.addSeries("Series A", [
+		{y: 4, text: "Red", color: "red"},
+		{y: 2, text: "Green", color: "green"},
+		{y: 1, text: "Blue", color: "blue"},
+		{y: 1, text: "Other", color: "white", fontColor: "black"}
+	]);
+	chart6.render();
+
+	var chart7 = new dojox.charting.Chart("test7");
+	chart7.setTheme(dojox.charting.themes.Adobebricks);
+	chart7.addPlot("default", {
+		type: "Pie",
+		font: "normal normal bold 12pt Tahoma",
+		fontColor: "white",
+		radius: 80
+	});
+	chart7.addSeries("Series A", [4]);
+	chart7.render();
+
+	var chart8 = new dojox.charting.Chart("test8");
+	chart8.setTheme(dojox.charting.themes.Algae);
+	chart8.addPlot("default", {
+		type: "Pie",
+		font: "normal normal bold 12pt Tahoma",
+		fontColor: "white",
+		radius: 80
+	});
+	chart8.addSeries("Series A", [
+		{y: -1, text: "Red", color: "red"},
+		{y: 5, text: "Green", color: "green"},
+		{y: 0, text: "Blue", color: "blue"},
+		{y: 0, text: "Other", color: "white", fontColor: "black"}
+	]);
+	chart8.render();
+};
+
+dojo.addOnLoad(makeObjects);
+
+</script>
+</head>
+<body>
+<h1>Pie 2D</h1>
+<!--<p><button onclick="makeObjects();">Go</button></p>-->
+<p>1: Pie with internal labels.</p>
+<div id="test1" style="width: 300px; height: 300px;"></div>
+<p>2: Pie with external labels and precision=0.</p>
+<div id="test2" style="width: 300px; height: 300px;"></div>
+<p>3/4: Two pies with internal and external labels with a constant radius.</p>
+<table border="1"><tr>
+	<td><div id="test3" style="width: 300px; height: 300px;"></div></td>
+	<td><div id="test4" style="width: 300px; height: 300px;"></div></td>
+</tr></table>
+<p>5/6: Pie with internal custom labels and custom colors (#6 is rotated).</p>
+<table border="1"><tr>
+	<td><div id="test5" style="width: 300px; height: 300px;"></div></td>
+	<td><div id="test6" style="width: 300px; height: 300px;"></div></td>
+</tr></table>
+<p>7: Degenerated pie with 1 element.</p>
+<div id="test7" style="width: 200px; height: 200px;"></div>
+<p>8: Degenerated pie with 1 positive elements (out of 5).</p>
+<div id="test8" style="width: 200px; height: 200px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_pie2d_5050.html b/dojox/charting/tests/BidiSupport/mirror_pie2d_5050.html
new file mode 100644
index 0000000..8affc7f
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_pie2d_5050.html
@@ -0,0 +1,67 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Pie 2D</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.widget.Legend");
+dojo.require("dojox.charting.plot2d.Pie");
+dojo.require("dojox.charting.themes.PlotKit.blue");
+dojo.require("dojox.charting.themes.PlotKit.green");
+dojo.require("dojox.charting.themes.PlotKit.red");
+dojo.require("dojox.charting.themes.Adobebricks");
+dojo.require("dojox.charting.themes.Algae");
+makeObjects = function(){
+	var chart1 = new dojox.charting.Chart("test1");
+	chart1.setTheme(dojox.charting.themes.PlotKit.blue);
+	chart1.addPlot("default", {
+		type: "Pie",
+		font: "normal normal bold 12pt Tahoma",
+		fontColor: "blue",
+		radius: 70,
+		labelOffset: 5,
+		labelStyle: "columns",
+		labelWiring: "ccc"
+	});
+	chart1.addSeries("Series A", [4, 4]);
+	chart1.setDir("rtl");
+	chart1.render();
+	
+	var legend = new dojox.charting.widget.Legend({
+        	            chart: chart1,
+							horizontal:false
+                	}, "legend");
+};
+
+dojo.addOnLoad(makeObjects);
+
+</script>
+</head>
+<body>
+<h1>Pie</h1>
+<p>Pie with 2 50% slices</p>
+<div id="test1" style="width: 300px; height: 300px;"></div>
+<div id="legend"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_pie2d_zeroslice.html b/dojox/charting/tests/BidiSupport/mirror_pie2d_zeroslice.html
new file mode 100644
index 0000000..3e665a3
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_pie2d_zeroslice.html
@@ -0,0 +1,65 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Pie 2D</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.widget.Legend");
+dojo.require("dojox.charting.plot2d.Pie");
+dojo.require("dojox.charting.themes.PlotKit.blue");
+dojo.require("dojox.charting.themes.PlotKit.green");
+dojo.require("dojox.charting.themes.PlotKit.red");
+dojo.require("dojox.charting.themes.Adobebricks");
+dojo.require("dojox.charting.themes.Algae");
+makeObjects = function(){
+	var chart1 = new dojox.charting.Chart("test1");
+	chart1.setTheme(dojox.charting.themes.PlotKit.blue);
+	chart1.addPlot("default", {
+		type: "Pie",
+		font: "normal normal bold 12pt Tahoma",
+		fontColor: "white",
+		labelOffset: 40
+	});
+	chart1.addSeries("Series A", [4, 3, 0, 2]);
+	chart1.setDir("rtl");
+	chart1.render();
+	
+	var legend = new dojox.charting.widget.Legend({
+        	            chart: chart1,
+							horizontal:false
+                	}, "legend");
+};
+
+dojo.addOnLoad(makeObjects);
+
+</script>
+</head>
+<body>
+<h1>Pie 2D</h1>
+<!--<p><button onclick="makeObjects();">Go</button></p>-->
+<p>Pie with a 0 slice</p>
+<div id="test1" style="width: 300px; height: 300px;"></div>
+<div id="legend"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_pie_omitLabels.html b/dojox/charting/tests/BidiSupport/mirror_pie_omitLabels.html
new file mode 100644
index 0000000..69c08f9
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_pie_omitLabels.html
@@ -0,0 +1,77 @@
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if !(IE 8)]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+	<![endif]>
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+	</head>
+	
+	<body>
+		<script type="text/javascript">
+	    dojo.require("dojox.charting.Chart2D");
+	    dojo.require("dojox.charting.themes.PrimaryColors");
+	    var chartData = [10000,1,10000,1,10000,1];
+	    dojo.ready(function() {
+	        var pieChart1 = new dojox.charting.Chart2D("chartNode1");
+	        pieChart1.setTheme(dojox.charting.themes.PrimaryColors);
+	        pieChart1.addPlot("default", {
+	            type:       "Pie",
+	            omitLabels: true,
+	            radius:     100
+	        });
+	        pieChart1.addSeries("test",chartData);
+	        pieChart1.setDir("rtl");
+	        pieChart1.render();
+	        
+	        var pieChart2 = new dojox.charting.Chart2D("chartNode2");
+	        pieChart2.setTheme(dojox.charting.themes.PrimaryColors);
+	        pieChart2.addPlot("default", {
+	            type:       "Pie",
+	            radius:     100
+	        });
+	        pieChart2.addSeries("test",chartData);
+	        pieChart2.setDir("rtl");
+	        pieChart2.render();
+	        
+	        var pieChart3 = new dojox.charting.Chart2D("chartNode3");
+	        pieChart3.setTheme(dojox.charting.themes.PrimaryColors);
+	        pieChart3.addPlot("default", {
+	            type:       "Pie",
+	        	labelStyle: "columns",
+	        	omitLabels: true,
+	        	radius:     100
+	        });
+	        pieChart3.addSeries("test",chartData);
+	        pieChart3.setDir("rtl");
+	        pieChart3.render();
+	        
+	        var pieChart4 = new dojox.charting.Chart2D("chartNode4");
+	        pieChart4.setTheme(dojox.charting.themes.PrimaryColors);
+	        pieChart4.addPlot("default", {
+	            type:       "Pie",
+	        	labelStyle: "columns",
+	        	radius:     100
+	        });
+	        pieChart4.addSeries("test",chartData);
+	        pieChart4.setDir("rtl");
+	        pieChart4.render();
+	    });
+	    </script>
+		<p>Omit true</p>
+		<div id="chartNode1" style="width: 400px; height: 300px;"></div>
+		<p>Omit false<p>
+		<div id="chartNode2" style="width: 400px; height: 300px;"></div>
+		<p>Omit true</p>
+		<div id="chartNode3" style="width: 400px; height: 300px;"></div>
+		<p>Omit false</p>
+		<div id="chartNode4" style="width: 400px; height: 300px;"></div>
+	
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_plot_order.html b/dojox/charting/tests/BidiSupport/mirror_plot_order.html
new file mode 100644
index 0000000..a5c67f2
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_plot_order.html
@@ -0,0 +1,113 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Testing plot order</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dojo/resources/dnd.css";
+	@import "../../../../dojo/tests/dnd/dndDefault.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+</style>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+<script>
+
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Bubble");
+dojo.require("dojox.charting.themes.ThreeD");
+dojo.require("dojox.charting.widget.Legend");
+
+dojo.require("dojo.dnd.Source");
+
+makeObjects = function(){
+    dojo.query("button").style("disabled", true);
+    
+	var chart1 = new dojox.charting.Chart("chart1").
+            setTheme(dojox.charting.themes.ThreeD).
+            addAxis("x", {min: 0, max: 10}).
+            addAxis("y", {vertical: true, min: 0, max: 10}).
+            addPlot("Plot 1", {type: "Bubble"}).
+            addSeries("Plot 1 / Series A", [{x: 3, y: 3, size: 4}], {plot: "Plot 1"}).
+            addPlot("Plot 2", {type: "Bubble"}).
+            addSeries("Plot 2 / Series B", [{x: 5, y: 5, size: 4}], {plot: "Plot 2"}).
+            //addSeries("Plot 2 / Series B1", [{x: 5, y: 6, size: 3}], {plot: "Plot 2"}).
+            //addSeries("Plot 2 / Series B2", [{x: 4, y: 4, size: 3}], {plot: "Plot 2"}).
+            //addSeries("Plot 2 / Series B3", [{x: 6, y: 4, size: 3}], {plot: "Plot 2"}).
+            addPlot("Plot 3", {type: "Bubble"}).
+            addSeries("Plot 3 / Series C", [{x: 7, y: 7, size: 4}], {plot: "Plot 3"}).
+			setDir("rtl").
+            render();
+
+	var legend1 = new dojox.charting.widget.Legend({chart: chart1, horizontal: false}, "legend1");
+    dojo.connect(chart1, "render", legend1, "refresh");
+    
+    var plots = new dojo.dnd.Source("dnd1"), noUpdate = false;
+    plots.insertNodes(false, chart1.getPlotOrder());
+    dojo.connect(plots, "onDropInternal", function(){
+        var newOrder = this.getAllNodes().map(function(node){
+                return node.innerHTML;
+            })
+        chart1.setPlotOrder(newOrder);
+        noUpdate = true;
+        chart1.render();
+        noUpdate = false;
+    });
+    dojo.connect(chart1, "render", function(){
+        if(!noUpdate){
+            plots.getAllNodes().orphan();
+            plots.sync();
+            plots.insertNodes(false, chart1.getPlotOrder());
+        }
+    });
+
+    dojo.forEach(["p1", "p2", "p3"], function(id, i){
+        dojo.query("button", id).forEach(function(btn){
+            if(btn.innerHTML == "Front"){
+                dojo.connect(btn, "onclick", function(){
+                    chart1.movePlotToFront("Plot " + (i + 1));
+					chart1.setDir("rtl");
+                    chart1.render();
+                });
+            }else{
+                dojo.connect(btn, "onclick", function(){
+                    chart1.movePlotToBack("Plot " + (i + 1));
+					chart1.setDir("rtl");
+                    chart1.render();
+                });
+            }
+        });
+    });
+};
+
+dojo.ready(makeObjects);
+
+</script>
+</head>
+<body>
+<h1>Testing plot order</h1>
+<!--<p><button onclick="makeObjects();">Go</button></p>-->
+<p>Chart:</p>
+<div id="chart1" style="width: 200px; height: 200px;"></div>
+<div id="legend1"></div>
+<p id="p1">Plot 1: <button>Front</button> <button>Back</button></p>
+<p id="p2">Plot 2: <button>Front</button> <button>Back</button></p>
+<p id="p3">Plot 3: <button>Front</button> <button>Back</button></p>
+<p>Plots (rearrange using drag-and-drop):</p>
+<div id="dnd1" class="container"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_series_order.html b/dojox/charting/tests/BidiSupport/mirror_series_order.html
new file mode 100644
index 0000000..4a2fa44
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_series_order.html
@@ -0,0 +1,102 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Testing series order</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dojo/resources/dnd.css";
+	@import "../../../../dojo/tests/dnd/dndDefault.css";
+	@import "../../../../dijit/tests/css/dijitTests.css";
+</style>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+<script>
+
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Bubble");
+dojo.require("dojox.charting.themes.ThreeD");
+dojo.require("dojox.charting.widget.Legend");
+dojo.require("dojo.dnd.Source");
+
+makeObjects = function(){
+    dojo.query("button").style("disabled", true);
+    
+	var chart1 = new dojox.charting.Chart("chart1").
+            setTheme(dojox.charting.themes.ThreeD).
+            addAxis("x", {min: 0, max: 10}).
+            addAxis("y", {vertical: true, min: 0, max: 10}).
+            addPlot("Plot 1", {type: "Bubble"}).
+            addSeries("Series A", [{x: 3, y: 3, size: 4}], {plot: "Plot 1", color: "red"}).
+            addSeries("Series B", [{x: 5, y: 5, size: 4}], {plot: "Plot 1", color: "green"}).
+            addSeries("Series C", [{x: 7, y: 7, size: 4}], {plot: "Plot 1", color: "blue"}).
+            setDir("rtl").
+            render();
+
+    var series = new dojo.dnd.Source("dnd1"), noUpdate = false;
+    series.insertNodes(false, chart1.getSeriesOrder("Plot 1"));
+    dojo.connect(series, "onDropInternal", function(){
+        var newOrder = this.getAllNodes().map(function(node){
+                return node.innerHTML;
+            })
+        chart1.setSeriesOrder(newOrder);
+        noUpdate = true;
+        chart1.render();
+        noUpdate = false;
+    });
+    dojo.connect(chart1, "render", function(){
+        if(!noUpdate){
+            series.getAllNodes().orphan();
+            series.sync();
+            series.insertNodes(false, chart1.getSeriesOrder("Plot 1"));
+        }
+    });
+
+    dojo.forEach(["s1", "s2", "s3"], function(id, i){
+        dojo.query("button", id).forEach(function(btn){
+            if(btn.innerHTML == "Front"){
+                dojo.connect(btn, "onclick", function(){
+                    chart1.moveSeriesToFront("Series " + "ABCDEFG".charAt(i));
+                    chart1.render();
+                });
+            }else{
+                dojo.connect(btn, "onclick", function(){
+                    chart1.moveSeriesToBack("Series " + "ABCDEFG".charAt(i));
+                    chart1.render();
+                });
+            }
+        });
+    });
+};
+
+dojo.ready(makeObjects);
+
+</script>
+</head>
+<body>
+<h1>Testing series order</h1>
+<!--<p><button onclick="makeObjects();">Go</button></p>-->
+<p>Chart:</p>
+<div id="chart1" style="width: 200px; height: 200px;"></div>
+<div id="legend1"></div>
+<p id="s1">Series A: <button>Front</button> <button>Back</button></p>
+<p id="s2">Series B: <button>Front</button> <button>Back</button></p>
+<p id="s3">Series C: <button>Front</button> <button>Back</button></p>
+<p>Series (rearrange using drag-and-drop):</p>
+<div id="dnd1" class="container"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_shadow.html b/dojox/charting/tests/BidiSupport/mirror_shadow.html
new file mode 100644
index 0000000..fd2df7a
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_shadow.html
@@ -0,0 +1,95 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Shadows</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../../dijit/themes/tundra/tundra.css">
+		<style>
+			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
+			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script type="text/javascript">
+			var seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
+			require([
+			"dojox/charting/widget/Chart",
+			"dojox/charting/axis2d/Default",
+			"dojox/charting/plot2d/Columns",
+			"dojox/charting/plot2d/Bars",
+			"dojox/charting/plot2d/Default",
+			"dojox/charting/plot2d/Pie",
+			"dojox/charting/action2d/Shake",
+			"dojox/charting/themes/PlotKit/orange",
+			"dojox/charting/themes/PlotKit/blue",
+			"dojox/charting/themes/PlotKit/green",
+			"dojo/parser"]);
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Shadows</h1>
+		<p>Testing charts shadows</p>
+		<table border="0" cellspacing="30">
+			<tr>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart1" style="width: 300px; height: 300px;">
+						<div class="axis" name="y" font="italic normal normal 8pt Tahoma" natural="true" fixLower="major" fixUpper="major"></div>
+						<div class="axis" name="x" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Bars" fill="'red'" stroke="null" shadow="{dx: 2, dy: 2, width: 2, color: [ 150, 0, 0, 0.7 ]}" gap="5" animate="true"></div>
+						<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+						<div class="action" type="Shake"></div>
+					</div>
+				</td>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart2" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma" natural="true" fixLower="major" fixUpper="major"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Columns" fill="'red'" stroke="null" shadow="{dx: 2, dy: 2, width: 2, color: [ 150, 0, 0, 0.7 ]}" gap="5" animate="true"></div>
+						<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+						<div class="action" type="Shake"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart3" theme="dojox.charting.themes.PlotKit.blue"
+							 style="width: 300px; height: 300px;">
+						<div class="plot" name="default" type="Pie" radius="100" fontColor="white" shadow="{dx: 3, dy: 3, width: 3, color: [ 0, 0, 0, 0.3 ]}" animate="true"></div>
+						<div class="series" name="Series B" array="seriesB"></div>
+						<div class="action" type="Shake"></div>
+					</div>
+				</td>
+				<td>
+					<div direction="rtl" data-dojo-type="dojox.charting.widget.Chart" id="chart4" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma" natural="true" fixLower="major" fixUpper="major"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Default" stroke="{width: 4, color: 'red'}" shadow="{dx: 2, dy: 2, width:3,  color: [ 0, 0, 0, 0.3 ]}" animate="true"></div>
+						<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+					</div>
+				</td>
+			</tr>
+		</table>
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_spidersingle.html b/dojox/charting/tests/BidiSupport/mirror_spidersingle.html
new file mode 100644
index 0000000..262c8d7
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_spidersingle.html
@@ -0,0 +1,62 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Test a Spider Chart with a single series</title>
+<style type="text/css">
+	@import "../../../../dojo/resources/dojo.css";
+	@import "../../../../dijit/themes/claro/claro.css";
+</style>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+require(["dojo/ready", "dojox/charting/Chart", "dojox/charting/plot2d/Spider", "dojox/charting/themes/PlotKit/blue",
+		"dijit/Tooltip", "dojox/charting/axis2d/Base"], function(ready, Chart, Spider, blue, Tooltip, Base){
+	ready(function(){
+		var chart = new Chart("test");
+		chart.setTheme(blue);
+		chart.addPlot("default", {
+			type: Spider,
+			labelOffset: -10,
+			axisColor:      "lightgray",
+			spiderColor:    "silver",
+            seriesFillAlpha: 0.2,
+			spiderOrigin:	 0.16,
+			markerSize:  	 3,
+			precision:		 0
+		});
+		var data= [ {"Sales":73,"Marketing":226,"Development":125,"Administration":135,"Support":105},
+				    {"Sales":73,"Marketing":206,"Development":155,"Administration":235,"Support":87},
+				    {"Sales":53,"Marketing":326,"Development":225,"Administration":145,"Support":55} ];
+
+		// we define several axis (optional step for the general case)
+		chart.addAxis("Sales", { type: Base, min: 0, max: 100 });
+		chart.addAxis("Marketing", { type: Base, min: 100, max: 400});
+		chart.addAxis("Development", { type: Base, min: 0, max: 250 });
+		chart.addAxis("Administration", { type: Base, min: 0, max: 250});
+		chart.addAxis("Support", { type: Base, min: 0, max:150 });
+		chart.setDir("rtl");
+		// we add a single series, without axis definitions we won't be able to compute data axis min/max
+		chart.addSeries("China", {data: data[0] }, { fill: "blue" });
+
+		chart.render();
+	});
+});
+</script>
+</head>
+<body class="claro">
+<div id="test" style="width: 500px; height: 500px;"></div>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_stacked.html b/dojox/charting/tests/BidiSupport/mirror_stacked.html
new file mode 100644
index 0000000..eb39295
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_stacked.html
@@ -0,0 +1,177 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<link rel="stylesheet" href="../../../../dijit/themes/tundra/tundra.css">
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true, has:{'dojo-bidi': true}"></script>
+<script type="text/javascript">
+
+require(["dojo/ready","dojox/charting/Chart", "dojox/charting/widget/Legend", "dojox/charting/axis2d/Default",
+	"dojox/charting/plot2d/StackedAreas", "dojox/charting/plot2d/StackedLines", "dojox/charting/plot2d/StackedColumns",
+	"dojox/charting/plot2d/StackedBars"],
+	function(ready, Chart, Legend, Default, StackedAreas, StackedLines, StackedColumns, StackedBars){
+
+	ready(function(){
+		// StackedAreas, array of objects
+		var chart1 = new Chart("StackedAreas_objects");
+		chart1.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart1.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart1.addPlot("default", {type: StackedAreas, gap: 5});
+		chart1.addSeries("Series A", [{y:1}, {y:2}, {y:3}, {y:4}, {y:5}], {stroke: {color: "black"}, fill: "red"});
+		chart1.addSeries("Series B", [{y:5}, {y:4}, {y:3}, {y:2}, {y:1}], {stroke: {color: "black"}, fill: "blue"});
+		chart1.setDir("rtl");chart1.render();
+		new Legend({chart: chart1, horizontal: true}, "StackedAreas_objects_l");
+	
+		// StackedLines, array of objects
+		var chart2 = new Chart("StackedLines_objects");
+		chart2.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart2.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart2.addPlot("default", {type: StackedLines, gap: 5});
+		chart2.addSeries("Series A", [{y:1}, {y:2}, {y:3}, {y:4}, {y:5}], {stroke: {color: "red"}});
+		chart2.addSeries("Series B", [{y:5}, {y:4}, {y:3}, {y:2}, {y:1}], {stroke: {color: "blue"}});
+		chart2.setDir("rtl");
+		chart2.render();
+		new Legend({chart: chart2, horizontal: true}, "StackedLines_objects_l");
+
+		// StackedColumns, array of objects
+		var chart3 = new Chart("StackedColumns_objects");
+		chart3.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart3.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart3.addPlot("default", {type: StackedColumns, gap: 5});
+		chart3.addSeries("Series A", [{y:1}, {y:2}, {y:3}, {y:4}, {y:5}], {fill: "red"});
+		chart3.addSeries("Series B", [{y:5}, {y:4}, {y:3}, {y:2}, {y:1}], {fill: "blue"});
+		chart3.setDir("rtl");
+		chart3.render();
+		new Legend({chart: chart3, horizontal: true}, "StackedColumns_objects_l");
+
+		// StackedBars, array of objects
+		var chart7 = new Chart("StackedBars_objects");
+		chart7.addAxis("y", {fixLower: "major", fixUpper: "major", includeZero: true});
+		chart7.addAxis("x", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true});
+		chart7.addPlot("default", {type: StackedBars, gap: 5});
+		chart7.addSeries("Series A", [{y:1}, {y:2}, {y:3}, {y:4}, {y:5}], {fill: "red"});
+		chart7.addSeries("Series B", [{y:5}, {y:4}, {y:3}, {y:2}, {y:1}], {fill: "blue"});
+		chart7.setDir("rtl");
+		chart7.render();
+		new Legend({chart: chart7, horizontal: true}, "StackedBars_objects_l");
+	
+		// StackedAreas, array of numbers
+		var chart4 = new Chart("StackedAreas_numbers");
+		chart4.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart4.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart4.addPlot("default", {type: StackedAreas, gap: 5});
+		chart4.addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "black"}, fill: "red"});
+		chart4.addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "black"}, fill: "blue"});
+		chart4.setDir("rtl");
+		chart4.render();
+		new Legend({chart: chart4, horizontal: true}, "StackedAreas_numbers_l");
+	
+		// StackedLines, array of numbers
+		var chart5 = new Chart("StackedLines_numbers");
+		chart5.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart5.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart5.addPlot("default", {type: StackedLines, gap: 5});
+		chart5.addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "red"}});
+		chart5.addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}});
+		chart5.setDir("rtl");
+		chart5.render();
+		new Legend({chart: chart5, horizontal: true}, "StackedLines_numbers_l");
+
+		// StackedColumns, array of numbers
+		var chart6 = new Chart("StackedColumns_numbers");
+		chart6.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart6.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart6.addPlot("default", {type: StackedColumns, gap: 5});
+		chart6.addSeries("Series A", [1, 2, 3, 4, 5], {fill: "red"});
+		chart6.addSeries("Series B", [5, 4, 3, 2, 1], {fill: "blue"});
+		chart6.setDir("rtl");
+		chart6.render();
+		new Legend({chart: chart6, horizontal: true}, "StackedColumns_numbers_l");
+
+		// StackedBars, array of numbers
+		var chart8 = new Chart("StackedBars_numbers");
+		chart8.addAxis("y", {fixLower: "major", fixUpper: "major", includeZero: true});
+		chart8.addAxis("x", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true});
+		chart8.addPlot("default", {type: StackedBars, gap: 5});
+		chart8.addSeries("Series A", [1, 2, 3, 4, 5], {fill: "red"});
+		chart8.addSeries("Series B", [5, 4, 3, 2, 1], {fill: "blue"});
+		chart8.setDir("rtl");
+		chart8.render();
+		new Legend({chart: chart8, horizontal: true}, "StackedBars_numbers_l");
+	});
+});
+</script>
+</head>
+<body class="tundra">
+<table>
+<tr>
+	<td>StackedAreas, array of objects</td>
+	<td>StackedAreas, array of numbers</td>
+</tr>
+<tr>
+	<td>
+	<div id="StackedAreas_objects" style="width: 400px; height: 200px;"></div>
+	<div id="StackedAreas_objects_l"></div>
+	</td>
+	<td>
+	<div id="StackedAreas_numbers" style="width: 400px; height: 200px;"></div>
+	<div id="StackedAreas_numbers_l"></div>
+	</td>
+</tr>
+<tr>
+	<td>StackedLines, array of objects</td>
+	<td>StackedLines, array of numbers</td>
+</tr>
+<tr>
+	<td>
+	<div id="StackedLines_objects" style="width: 400px; height: 200px;"></div>
+	<div id="StackedLines_objects_l"></div>
+	</td>
+	<td>
+	<div id="StackedLines_numbers" style="width: 400px; height: 200px;"></div>
+	<div id="StackedLines_numbers_l"></div>
+	</td>
+</tr>
+<tr>
+	<td>StackedColumns, array of objects</td>
+	<td>StackedColumns, array of numbers</td>
+</tr>
+<tr>
+	<td>
+	<div id="StackedColumns_objects" style="width: 400px; height: 200px;"></div>
+	<div id="StackedColumns_objects_l"></div>
+	</td>
+	<td>
+	<div id="StackedColumns_numbers" style="width: 400px; height: 200px;"></div>
+	<div id="StackedColumns_numbers_l"></div>
+	</td>
+</tr>
+<tr>
+	<td>StackedBars, array of objects</td>
+	<td>StackedBars, array of numbers</td>
+</tr>
+<tr>
+	<td>
+	<div id="StackedBars_objects" style="width: 400px; height: 200px;"></div>
+	<div id="StackedBars_objects_l"></div>
+	</td>
+	<td>
+	<div id="StackedBars_numbers" style="width: 400px; height: 200px;"></div>
+	<div id="StackedBars_numbers_l"></div>
+	</td>
+</tr>
+</table>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/mirror_tension.html b/dojox/charting/tests/BidiSupport/mirror_tension.html
new file mode 100644
index 0000000..674383c
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/mirror_tension.html
@@ -0,0 +1,71 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>Tension test.</title>
+    <style>
+        @import "../../../../dojo/resources/dojo.css";
+        @import "../../../../dijit/themes/tundra/tundra.css";
+        @import "../../../../dijit/tests/css/dijitTests.css";
+    </style>
+    <style>
+        .dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
+        .dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+    </style>
+    <script src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, has:{'dojo-bidi': true}"></script>
+    <script>
+        dojo.require("dojox.charting.Chart");
+		dojo.require("dojox.charting.Theme");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Default");
+        dojo.require("dojox.charting.widget.Legend");
+        
+        var data = [{x: 1, y: 1}, {x: 1, y: 2}, {x: 2, y: 2}, {x: 2, y: 1}];
+        
+        makeObjects = function(){
+            var theme = new dojox.charting.Theme({
+                    chart:    {fill: null}, // no background
+                    plotarea: {fill: null}, // no background
+                    colors: ["red", "green", "blue", "orange"]
+                });
+            var chart = new dojox.charting.Chart("test_chart").
+                    setTheme(theme).
+                    addAxis("x", {natural: true, min: 0, max: 3}).
+                    addAxis("y", {vertical: true, natural: true, min: 0, max: 3}).
+                    addPlot("S tension", {tension: "S"}).
+                    addSeries("\"S\" tension", data, {plot: "S tension"}).
+                    addPlot("x tension", {tension: "x"}).
+                    addSeries("\"x\" tension", data, {plot: "x tension"}).
+                    addPlot("X tension", {tension: "X"}).
+                    addSeries("\"X\" tension", data, {plot: "X tension"}).
+                    addPlot("no tension", {markers: true, tension: ""}).
+                    addSeries("No Tension", data, {plot: "no tension"}).
+					setDir("rtl").
+                    render();
+            var legend = new dojox.charting.widget.Legend({chart: chart}, "test_legend");
+        };
+        
+        dojo.addOnLoad(makeObjects);
+    </script>
+</head>
+<body class="tundra">
+    <h1>Tension test.</h1>
+    <!--<p><button onclick="makeObjects();">Go</button></p>-->
+    <div id="test_chart" style="width: 400px; height: 400px;"></div>
+    <div id="test_legend"></div>
+    <p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/BidiSupport/stock.json b/dojox/charting/tests/BidiSupport/stock.json
new file mode 100644
index 0000000..746d025
--- /dev/null
+++ b/dojox/charting/tests/BidiSupport/stock.json
@@ -0,0 +1,8 @@
+{ "identifier": "symbol", "idAttribute":"symbol", "label": "symbol","items": [
+	{ "symbol":"ANDT", "name":"Anduct",           	"historicPrice":[0.01,3.52,3.66,3.11,3.90,3.11,3.11], "open":3.13,  "price":3.52, "updown":"^",  "change":"+0.39 (+21%)", "low":3.13, "high":3.69 },
+	{ "symbol":"ATEU", "name":"Ations Europe",		"historicPrice":[6.72,6.76,6.61,6.41,6.31,6.99,7.20], "open":6.72,  "price":6.76, "updown":"^",  "change":"+0.04 (+01%)", "low":6.56, "high":6.77 },
+	{ "symbol":"BGCN", "name":"Bagies Consulting",	"historicPrice":[4.11,3.98,4.05,4.20,4.16,4.22,3.80], "open":4.11,  "price":3.98, "updown":"v",  "change":"-0.13 (-05%)", "low":3.77, "high":4.11 },
+	{ "symbol":"BAYC", "name":"BAY Corporation",	"historicPrice":[9.79,9.60,9.50,2.23,9.45,9.76,9.99], "open":9.79,  "price":9.60, "updown":"v",  "change":"-0.19 (+14%)", "low":9.60, "high":9.81 },
+	{ "symbol":"CRCR", "name":"Corcor PLC",			"historicPrice":[8.44,8.44,8.54,8.60,9.65,8.42,8.44], "open":8.44,  "price":8.44, "updown":"--", "change":"+0.00 (+00%)", "low":8.22, "high":8.44 },
+	{ "symbol":"DTOA", "name":"Datio PLC",			"historicPrice":[2.11,2.47,3.11,3.06,3.01,3.01,3.00], "open":2.11,  "price":2.47, "updown":"^",  "change":"+0.36 (+36%)", "low":2.11, "high":3.01 }
+]}
diff --git a/dojox/charting/tests/Theme.js b/dojox/charting/tests/Theme.js
index 17c4f7b..df10f11 100644
--- a/dojox/charting/tests/Theme.js
+++ b/dojox/charting/tests/Theme.js
@@ -1,11 +1,6 @@
-dojo.provide("dojox.charting.tests.Theme");
-dojo.require("dojox.charting.Theme");
-dojo.require("dojox.charting.themes.PlotKit.blue");
-
-(function(){
-	var dxc=dojox.charting, Theme = dxc.Theme;
-	var blue=dxc.themes.PlotKit.blue;
-	tests.register("dojox.charting.tests.Theme", [
+define(["doh", "dojox/charting/Theme", "dojox/charting/themes/PlotKit/blue"], 
+	function(doh, Theme, blue){
+	doh.register("dojox.charting.tests.Theme", [
 		function testDefineColor(t){
 			var args={ num:16, cache:false };
 			Theme.defineColors(args);
@@ -64,4 +59,4 @@ dojo.require("dojox.charting.themes.PlotKit.blue");
 			doh.debug(s);
 		}
 	]);
-})();
+});
diff --git a/dojox/charting/tests/charting.js b/dojox/charting/tests/charting.js
index f9cff0a..d97915d 100644
--- a/dojox/charting/tests/charting.js
+++ b/dojox/charting/tests/charting.js
@@ -1,7 +1,3 @@
-dojo.provide("dojox.charting.tests.charting");
-
-try{
-	dojo.require("dojox.charting.tests.Theme");
-}catch(e){
-	doh.debug(e);
-}
+define([
+    	"dojox/charting/tests/Theme",
+], 1);
diff --git a/dojox/charting/tests/gradients/test_grad_bars1.html b/dojox/charting/tests/gradients/test_grad_bars1.html
index e76be3a..65f4cf3 100644
--- a/dojox/charting/tests/gradients/test_grad_bars1.html
+++ b/dojox/charting/tests/gradients/test_grad_bars1.html
@@ -15,13 +15,14 @@
 	<head>
 <![endif]>
     <title>Gradient: Bars #1</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
         dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Bars");
         dojo.require("dojox.charting.plot2d.ClusteredBars");
         dojo.require("dojox.charting.plot2d.StackedBars");
+		dojo.require("dojox.charting.Theme");
 
         run = function(){
             dojo.attr("start", "disabled", true);
diff --git a/dojox/charting/tests/gradients/test_grad_bars2.html b/dojox/charting/tests/gradients/test_grad_bars2.html
index d80a23c..01a1c3d 100644
--- a/dojox/charting/tests/gradients/test_grad_bars2.html
+++ b/dojox/charting/tests/gradients/test_grad_bars2.html
@@ -16,14 +16,15 @@
 <![endif]>
 <![endif]>
     <title>Gradient: Bars #2</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Bars");
         dojo.require("dojox.charting.plot2d.ClusteredBars");
         dojo.require("dojox.charting.plot2d.StackedBars");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_bars3.html b/dojox/charting/tests/gradients/test_grad_bars3.html
index b141962..5eed4bf 100644
--- a/dojox/charting/tests/gradients/test_grad_bars3.html
+++ b/dojox/charting/tests/gradients/test_grad_bars3.html
@@ -15,14 +15,15 @@
 	<head>
 <![endif]>
     <title>Gradient: Bars #3</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Bars");
         dojo.require("dojox.charting.plot2d.ClusteredBars");
         dojo.require("dojox.charting.plot2d.StackedBars");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_bars4.html b/dojox/charting/tests/gradients/test_grad_bars4.html
index ff142fc..a4928b0 100644
--- a/dojox/charting/tests/gradients/test_grad_bars4.html
+++ b/dojox/charting/tests/gradients/test_grad_bars4.html
@@ -15,14 +15,15 @@
 	<head>
 <![endif]>
     <title>Gradient: Bars #4</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Bars");
         dojo.require("dojox.charting.plot2d.ClusteredBars");
         dojo.require("dojox.charting.plot2d.StackedBars");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_bars5.html b/dojox/charting/tests/gradients/test_grad_bars5.html
index 7050854..b792f22 100644
--- a/dojox/charting/tests/gradients/test_grad_bars5.html
+++ b/dojox/charting/tests/gradients/test_grad_bars5.html
@@ -15,14 +15,15 @@
 	<head>
 <![endif]>
     <title>Gradient: Bars #5</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Bars");
         dojo.require("dojox.charting.plot2d.ClusteredBars");
         dojo.require("dojox.charting.plot2d.StackedBars");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_bubble1.html b/dojox/charting/tests/gradients/test_grad_bubble1.html
index 0a2970b..440c8e8 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble1.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble1.html
@@ -15,12 +15,13 @@
 	<head>
 <![endif]>
     <title>Gradient: Bubble #1</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Bubble");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_bubble2.html b/dojox/charting/tests/gradients/test_grad_bubble2.html
index 1a8e564..198174d 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble2.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble2.html
@@ -15,12 +15,13 @@
 	<head>
 <![endif]>
     <title>Gradient: Bubble #2</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Bubble");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_bubble3.html b/dojox/charting/tests/gradients/test_grad_bubble3.html
index ad32f44..d661e85 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble3.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble3.html
@@ -15,12 +15,13 @@
 	<head>
 <![endif]>
     <title>Gradient: Bubble #3</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Bubble");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_bubble4.html b/dojox/charting/tests/gradients/test_grad_bubble4.html
index 824cc02..f78df64 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble4.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble4.html
@@ -15,12 +15,13 @@
 	<head>
 <![endif]>
     <title>Gradient: Bubble #4</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Bubble");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_bubble6.html b/dojox/charting/tests/gradients/test_grad_bubble6.html
index f68daf9..4391a83 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble6.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble6.html
@@ -15,12 +15,13 @@
 	<head>
 <![endif]>
     <title>Gradient: Bubble #6</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Bubble");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_columns1.html b/dojox/charting/tests/gradients/test_grad_columns1.html
index 32aa555..c0f2eaf 100644
--- a/dojox/charting/tests/gradients/test_grad_columns1.html
+++ b/dojox/charting/tests/gradients/test_grad_columns1.html
@@ -15,13 +15,14 @@
 	<head>
 <![endif]>
     <title>Gradient: Columns #1</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Columns");
         dojo.require("dojox.charting.plot2d.ClusteredColumns");
         dojo.require("dojox.charting.plot2d.StackedColumns");
+		dojo.require("dojox.charting.Theme");
 
         run = function(){
             dojo.attr("start", "disabled", true);
diff --git a/dojox/charting/tests/gradients/test_grad_columns2.html b/dojox/charting/tests/gradients/test_grad_columns2.html
index a0f759e..13618b1 100644
--- a/dojox/charting/tests/gradients/test_grad_columns2.html
+++ b/dojox/charting/tests/gradients/test_grad_columns2.html
@@ -15,14 +15,15 @@
 	<head>
 <![endif]>
     <title>Gradient: Columns #2</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Columns");
         dojo.require("dojox.charting.plot2d.ClusteredColumns");
         dojo.require("dojox.charting.plot2d.StackedColumns");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_columns3.html b/dojox/charting/tests/gradients/test_grad_columns3.html
index cf3d5e1..fde4aef 100644
--- a/dojox/charting/tests/gradients/test_grad_columns3.html
+++ b/dojox/charting/tests/gradients/test_grad_columns3.html
@@ -15,14 +15,15 @@
 	<head>
 <![endif]>
     <title>Gradient: Columns #3</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Columns");
         dojo.require("dojox.charting.plot2d.ClusteredColumns");
         dojo.require("dojox.charting.plot2d.StackedColumns");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_columns4.html b/dojox/charting/tests/gradients/test_grad_columns4.html
index cf8f404..d9e458f 100644
--- a/dojox/charting/tests/gradients/test_grad_columns4.html
+++ b/dojox/charting/tests/gradients/test_grad_columns4.html
@@ -15,14 +15,15 @@
 	<head>
 <![endif]>
     <title>Gradient: Columns #4</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Columns");
         dojo.require("dojox.charting.plot2d.ClusteredColumns");
         dojo.require("dojox.charting.plot2d.StackedColumns");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_columns5.html b/dojox/charting/tests/gradients/test_grad_columns5.html
index 72e0edd..005e488 100644
--- a/dojox/charting/tests/gradients/test_grad_columns5.html
+++ b/dojox/charting/tests/gradients/test_grad_columns5.html
@@ -15,14 +15,15 @@
 	<head>
 <![endif]>
     <title>Gradient: Columns #5</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Columns");
         dojo.require("dojox.charting.plot2d.ClusteredColumns");
         dojo.require("dojox.charting.plot2d.StackedColumns");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_pie1.html b/dojox/charting/tests/gradients/test_grad_pie1.html
index efa2120..d5f1f7b 100644
--- a/dojox/charting/tests/gradients/test_grad_pie1.html
+++ b/dojox/charting/tests/gradients/test_grad_pie1.html
@@ -15,11 +15,12 @@
 	<head>
 <![endif]>
     <title>Gradient: Pie #1</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.plot2d.Pie");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_pie2.html b/dojox/charting/tests/gradients/test_grad_pie2.html
index accfc7c..e2b5e8b 100644
--- a/dojox/charting/tests/gradients/test_grad_pie2.html
+++ b/dojox/charting/tests/gradients/test_grad_pie2.html
@@ -15,11 +15,12 @@
 	<head>
 <![endif]>
     <title>Gradient: Pie #2</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.plot2d.Pie");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_pie3.html b/dojox/charting/tests/gradients/test_grad_pie3.html
index f6cd7b2..6ca91d1 100644
--- a/dojox/charting/tests/gradients/test_grad_pie3.html
+++ b/dojox/charting/tests/gradients/test_grad_pie3.html
@@ -15,11 +15,12 @@
 	<head>
 <![endif]>
     <title>Gradient: Pie #3</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.plot2d.Pie");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_pie4.html b/dojox/charting/tests/gradients/test_grad_pie4.html
index a39816f..bb86c60 100644
--- a/dojox/charting/tests/gradients/test_grad_pie4.html
+++ b/dojox/charting/tests/gradients/test_grad_pie4.html
@@ -15,11 +15,12 @@
 	<head>
 <![endif]>
     <title>Gradient: Pie #4</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.plot2d.Pie");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_pie7.html b/dojox/charting/tests/gradients/test_grad_pie7.html
index 4d13781..4fb2124 100644
--- a/dojox/charting/tests/gradients/test_grad_pie7.html
+++ b/dojox/charting/tests/gradients/test_grad_pie7.html
@@ -15,11 +15,12 @@
 	<head>
 <![endif]>
     <title>Gradient: Pie #7</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.plot2d.Pie");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_pie8.html b/dojox/charting/tests/gradients/test_grad_pie8.html
index 8b8d2a3..09f415f 100644
--- a/dojox/charting/tests/gradients/test_grad_pie8.html
+++ b/dojox/charting/tests/gradients/test_grad_pie8.html
@@ -15,11 +15,12 @@
 	<head>
 <![endif]>
     <title>Gradient: Pie #8</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.plot2d.Pie");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_pie9.html b/dojox/charting/tests/gradients/test_grad_pie9.html
index 1330106..428ad17 100644
--- a/dojox/charting/tests/gradients/test_grad_pie9.html
+++ b/dojox/charting/tests/gradients/test_grad_pie9.html
@@ -15,11 +15,12 @@
 	<head>
 <![endif]>
     <title>Gradient: Pie #9</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.plot2d.Pie");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_pieA.html b/dojox/charting/tests/gradients/test_grad_pieA.html
index 7c84bd5..606aaeb 100644
--- a/dojox/charting/tests/gradients/test_grad_pieA.html
+++ b/dojox/charting/tests/gradients/test_grad_pieA.html
@@ -15,10 +15,11 @@
 	<head>
 <![endif]>
     <title>Gradient: Pie #A</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.plot2d.Pie");
+		dojo.require("dojox.charting.Theme");
 
         run = function(){
             dojo.attr("start", "disabled", true);
diff --git a/dojox/charting/tests/gradients/test_grad_scatter1.html b/dojox/charting/tests/gradients/test_grad_scatter1.html
index c74ad93..a55def3 100644
--- a/dojox/charting/tests/gradients/test_grad_scatter1.html
+++ b/dojox/charting/tests/gradients/test_grad_scatter1.html
@@ -15,11 +15,12 @@
 	<head>
 <![endif]>
     <title>Gradient: Scatter #1</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Scatter");
+		dojo.require("dojox.charting.Theme");
 
         run = function(){
             dojo.attr("start", "disabled", true);
diff --git a/dojox/charting/tests/gradients/test_grad_scatter2.html b/dojox/charting/tests/gradients/test_grad_scatter2.html
index 677773f..b3d0f39 100644
--- a/dojox/charting/tests/gradients/test_grad_scatter2.html
+++ b/dojox/charting/tests/gradients/test_grad_scatter2.html
@@ -15,12 +15,13 @@
 	<head>
 <![endif]>
     <title>Gradient: Scatter #2</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Scatter");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/gradients/test_grad_scatterB.html b/dojox/charting/tests/gradients/test_grad_scatterB.html
index 07dd891..bdc9a62 100644
--- a/dojox/charting/tests/gradients/test_grad_scatterB.html
+++ b/dojox/charting/tests/gradients/test_grad_scatterB.html
@@ -15,12 +15,13 @@
 	<head>
 <![endif]>
     <title>Gradient: Scatter #2</title>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
 		dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Scatter");
-        
+		dojo.require("dojox.charting.Theme");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
diff --git a/dojox/charting/tests/runTests.html b/dojox/charting/tests/runTests.html
index 6e13c2a..929abd5 100644
--- a/dojox/charting/tests/runTests.html
+++ b/dojox/charting/tests/runTests.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html>
     <head>
-    <title>Dojox.wire Unit Test Runner</title>
+    <title>dojox.charting Unit Test Runner</title>
     <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojox.charting.tests.charting"></HEAD>
     <BODY>
         Redirecting to D.O.H runner.
diff --git a/dojox/charting/tests/test_DataChart.html b/dojox/charting/tests/test_DataChart.html
index d319e67..fe7d98d 100644
--- a/dojox/charting/tests/test_DataChart.html
+++ b/dojox/charting/tests/test_DataChart.html
@@ -19,7 +19,7 @@
 <link rel="stylesheet" href="../../../dijit/themes/claro/document.css"/>
 <link rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 <link rel="stylesheet" href="../../../dijit/tests/css/dijitTests.css"/>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: false, parseOnLoad:true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: false, parseOnLoad:true"></script>
 <script type="text/javascript">
 dojo.require("dojo.parser");
 dojo.require("dojox.charting.DataChart");
diff --git a/dojox/charting/tests/test_DataSeries.html b/dojox/charting/tests/test_DataSeries.html
index 6a32de6..7f93f66 100644
--- a/dojox/charting/tests/test_DataSeries.html
+++ b/dojox/charting/tests/test_DataSeries.html
@@ -41,7 +41,7 @@
 	}
 </style>
 
-<script src="../../../dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true"></script>
+<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: false, parseOnLoad: true"></script>
 
 <script>
     
diff --git a/dojox/charting/tests/test_StoreSeries-amd.html b/dojox/charting/tests/test_StoreSeries-amd.html
index 8ab5e45..e6a2057 100644
--- a/dojox/charting/tests/test_StoreSeries-amd.html
+++ b/dojox/charting/tests/test_StoreSeries-amd.html
@@ -41,15 +41,15 @@
 </style>
 <script src="../../../dojo/dojo.js" data-dojo-config="isDebug: false, async: true"></script>
 <script>
-	require(["dojox/charting/Chart", "dojox/charting/StoreSeries", "dojox/charting/themes/ThreeD",
+	require(["dojo/ready", "dojox/charting/Chart", "dojox/charting/StoreSeries", "dojox/charting/themes/ThreeD",
 	"dojox/charting/widget/Legend", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Markers",
 	"dojox/charting/plot2d/Columns", "dojox/charting/plot2d/Pie", "dojox/charting/action2d/Tooltip",
 	"dojox/charting/action2d/MoveSlice", "dojox/charting/action2d/Magnify", "dojox/charting/action2d/Shake",
 	"dojo/store/Memory", "dojo/store/Observable","dijit/form/NumberSpinner", "dojo/_base/lang", "dojo/_base/array",
-	"dojo/_base/xhr", "dojo/dom-construct", "dojo/aspect"],
-	function(Chart, StoreSeries, ThreeD, Legend, Default, Markers, Columns, Pie, Tooltip, MoveSlice, Magnify, Shake,
+	"dojo/_base/xhr", "dojo/dom-construct", "dojo/dom", "dojo/aspect"],
+	function(ready, Chart, StoreSeries, ThreeD, Legend, Default, Markers, Columns, Pie, Tooltip, MoveSlice, Magnify, Shake,
 		Memory, Observable, NumberSpinner,
-		lang, arr, xhr, domConstruct, aspect){
+		lang, arr, xhr, domConstruct, dom, aspect){
 	
 	xhr.get({
 		url: "stock.json",
@@ -91,11 +91,11 @@
 				addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
 				addPlot("default", {type: Markers}).
 				addSeries("Price", new StoreSeries(
-					store, {query: {}}, "price")).
-				render();
-		addLegend(chartL, "lines_legend");
+					store, {query: {}}, "price"));
 		new Magnify(chartL);
 		new Tooltip(chartL);
+		chartL.render();
+		addLegend(chartL, "lines_legend");
 
 		chartC = new Chart("cols").
 				setTheme(ThreeD).
@@ -107,21 +107,21 @@
 				addSeries("Price", new StoreSeries(
 					store, {query: {}}, lang.hitch(null, valTrans, "price"))).
 				addSeries("High", new StoreSeries(
-					store, {query: {}}, lang.hitch(null, valTrans, "high"))).
-				render();
+					store, {query: {}}, lang.hitch(null, valTrans, "high")));
+		new Shake(chartC, "default", {shiftY: 0});
+		new Tooltip(chartC);
+		chartC.render();
 		addLegend(chartC, "cols_legend");
-		new dojox.charting.action2d.Shake(chartC, "default", {shiftY: 0});
-		new dojox.charting.action2d.Tooltip(chartC);
 		
 		chartP = new dojox.charting.Chart("pie").
 				setTheme(ThreeD).
 				addPlot("default", {type: Pie, radius: 125}).
 				addSeries("Price", new StoreSeries(
-					store, {query: {}}, {y: "price", text: "symbol", tooltip: "price"})).
-				render();
-		addLegend(chartP, "pie_legend");
+					store, {query: {}}, {y: "price", text: "symbol", tooltip: "price"}));
 		new Tooltip(chartP);
 		new MoveSlice(chartP);
+		chartP.render();
+		addLegend(chartP, "pie_legend");
 	};
 
 	makeSpinners = function(objects){
@@ -143,7 +143,7 @@
 				className: "myField",
 				intermediateChanges: true
 			});
-			domConstruct.place('<label>'+nm+'</label>', dojo.byId("spinners"), "last")
+			domConstruct.place('<label>'+nm+'</label>', dom.byId("spinners"), "last")
 			domConstruct.place(w.domNode, "spinners", "last")
 		});
 		
@@ -155,9 +155,11 @@
 			});
 		chartC.addAxis("x", {natural: true, labels: labels}).render();
 	};
-	
-	makeCharts();
-	makeSpinners(store.query({}));
+
+	ready(function(){
+		makeCharts();
+		makeSpinners(store.query({}));
+	});
 });
 </script>
 
diff --git a/dojox/charting/tests/test_StoreSeries.html b/dojox/charting/tests/test_StoreSeries.html
index d96d68d..e42916a 100644
--- a/dojox/charting/tests/test_StoreSeries.html
+++ b/dojox/charting/tests/test_StoreSeries.html
@@ -41,7 +41,7 @@
 	}
 </style>
 
-<script src="../../../dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true"></script>
+<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: false, parseOnLoad: true"></script>
 
 <script>
     
diff --git a/dojox/charting/tests/test_anim2d.html b/dojox/charting/tests/test_anim2d.html
index de28697..4aec0b7 100644
--- a/dojox/charting/tests/test_anim2d.html
+++ b/dojox/charting/tests/test_anim2d.html
@@ -19,12 +19,15 @@
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 
         dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.ClusteredColumns");
+        dojo.require("dojox.charting.plot2d.StackedAreas");
+		dojo.require("dojox.charting.plot2d.Grid");
+		dojo.require("dojox.charting.plot2d.Indicator");
 
 		dojo.require("dojox.charting.themes.Shrooms");
 		dojo.require("dojox.charting.themes.PlotKit.blue");
@@ -39,6 +42,23 @@
 		dojo.require("dojox.dtl.Context");
 		charts = [
 			{
+				description: "Columns, grid and indicators.",
+				makeChart: function(node){
+					(new dojox.charting.Chart(node)).
+						setTheme(dojox.charting.themes.Tufte).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true }).
+						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
+						addPlot("default", { type: "ClusteredColumns", gap: 10, animate: { duration: 1000 } }).
+						addPlot("indicator", { type: "Indicator", values: 1.5, lineStroke: { color: "red" }, precision: 1, animate: { duration: 1000 } }).
+						addPlot("grid", { type: "Grid", vStripes: true, vFill: [200, 0, 0, 0.6], vAlternateFill: [0, 200, 0, 0.6], animate: { duration: 1000 } }).
+						addSeries("Series A", [ 2, 1, 0.5, -1, -2 ] ).
+						addSeries("Series B", [ -2, -1, -0.5, 1, 2 ] ).
+						addSeries("Series C", [ 1, 0.5, -1, -2, -3 ] ).
+						addSeries("Series D", [ 0.7, 1.5, -1.2, -1.25, 3 ] ).
+						render();
+				}
+			},
+			{
 				description: "Clustered columns with positive and negative values, readable theme, 1-second animate-in.",
 				makeChart: function(node){
 					(new dojox.charting.Chart(node)).
@@ -52,7 +72,25 @@
 						addSeries("Series D", [ 0.7, 1.5, -1.2, -1.25, 3 ] ).
 						render();
 				}
+			},
+			
+			{
+				description: "StackedAreas 3-second animate-in.",
+				makeChart: function(node){
+					(new dojox.charting.Chart(node)).
+						setTheme(dojox.charting.themes.Tufte).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true }).
+						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
+						addPlot("default", { type: "StackedAreas", gap: 10, animate: { duration: 3000 } }).
+						addSeries("Series A", [ 2, 1, 0.5, 1, 1.5 ] ).
+						addSeries("Series B", [ 0, 1, 0.5, 1, 0.5 ] ).
+						addSeries("Series C", [ 1, 0.5, 0, 2, 3 ] ).
+						addSeries("Series D", [ 0.7, 1.5, 1.2, 1.25, 1 ] ).
+						render();
+				}
 			}
+
+
 		];
 		var now = function(){
 			return (new Date()).getTime();
diff --git a/dojox/charting/tests/test_axes.html b/dojox/charting/tests/test_axes.html
index 8e04038..550030c 100644
--- a/dojox/charting/tests/test_axes.html
+++ b/dojox/charting/tests/test_axes.html
@@ -20,7 +20,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script>
 
 dojo.require("dojox.charting.Chart");
@@ -37,7 +37,7 @@ makeObjects = function(){
 
 	var chart1 = new dojox.charting.Chart("test1").
             setTheme(customTheme).
-            addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
+            addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, majorTick: { length: -10}}).
             addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
             addPlot("default", {type: "Markers"}).
             addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
@@ -47,8 +47,8 @@ makeObjects = function(){
 
 	var chart2 = new dojox.charting.Chart("test2").
             setTheme(customTheme).
-            addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
-            addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
+            addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, majorTick: { length: 10}}).
+            addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true, majorTick: {length: -5}, minorTicks: false}).
             addPlot("p1", {type: "Markers"}).
             addPlot("p2", {type: "Markers"}).
             addPlot("p3", {type: "Markers"}).
diff --git a/dojox/charting/tests/test_axes_dates.html b/dojox/charting/tests/test_axes_dates.html
new file mode 100644
index 0000000..1ce5a7c
--- /dev/null
+++ b/dojox/charting/tests/test_axes_dates.html
@@ -0,0 +1,58 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Testing Axes with Date Labels</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+	</head>
+	<body class="claro">
+		<div id="simplechart" style="width: 600px; height: 200px;"></div>
+		<script src='../../../dojo/dojo.js' data-dojo-config="async:1, isDebug:1"></script>
+		<script>
+			require([
+				"dojo/date",
+				"dojo/date/locale",
+				"dojox/charting/Chart",
+				"dojox/charting/themes/Claro",
+				"dojox/charting/plot2d/Lines",
+				"dojox/charting/axis2d/Default",
+				"dojo/domReady!"
+			], function (date, locale, Chart, Claro) {
+
+				function makeLabel(index){
+					var idx = index - 1;
+					var d = date.add(new Date(), 'month', idx);
+					return locale.format(d, {datePattern:'MM-dd-yyyy', selector:'date'});
+				}
+
+				var chart = new Chart("simplechart");
+
+				chart.setTheme(Claro);
+				chart.addPlot("myPlot", {type: "Lines"});
+				chart.addAxis("x", {labelFunc:makeLabel, minorTicks:false});
+				chart.addAxis("y", {vertical: true, leftBottom: true, includeZero:true});
+
+				chart.addSeries("Series 1", [2, 2, 2, 3, 4, 5, 5, 7]);
+
+				chart.render();
+			});
+		</script>
+	</body>
+</html>
diff --git a/dojox/charting/tests/test_axisZoomControl.html b/dojox/charting/tests/test_axisZoomControl.html
index 547ed7f..3d2bd8a 100644
--- a/dojox/charting/tests/test_axisZoomControl.html
+++ b/dojox/charting/tests/test_axisZoomControl.html
@@ -27,71 +27,99 @@
 				margin-top: -5px;
 			}
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		<script type="text/javascript">
-			dojo.require("dojo.parser");
-			dojo.require("dojox.charting.Chart");
-            dojo.require("dojox.charting.axis2d.Default");
-            dojo.require("dojox.charting.plot2d.Lines");
-            dojo.require("dojox.charting.plot2d.Grid");
-			dojo.require("dojox.charting.themes.PlotKit.orange");
-			dojo.require("dojox.charting.action2d.Tooltip");
-			dojo.require("dojox.charting.action2d.Magnify");
-			dojo.require("dojox.form.RangeSlider");
-			dojo.require("dijit.form.HorizontalRuleLabels");
-			dojo.require("dijit.form.HorizontalRule");
-			
-			var chart;
-			makeObjects = function(){
-				chart = new dojox.charting.Chart("chart");
-				chart.setTheme(dojox.charting.themes.PlotKit.orange);
-				chart.addAxis("x", {fixLower: "minor", natural: true, stroke: "grey",
-					majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
-				chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 5, minorTickStep: 1, stroke: "grey",
-					majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
-				chart.addPlot("default", {type: "Lines",markers: true});
-				chart.addSeries("Series A", [
-					 8,  7,  3,  2,  5,  7,  9, 10,  2, 10,
-					14, 16, 18, 13, 16, 15, 20, 19, 15, 12,
-					24, 20, 20, 26, 28, 26, 28, 29, 24, 29,
-					31, 35, 37, 31, 35, 37, 37, 36, 31, 30,
-					50, 49, 42, 46, 44, 40, 47, 43, 48, 47,
-					51, 52, 52, 51, 54, 57, 58, 50, 54, 51,
-					62, 68, 67, 62, 62, 65, 61, 66, 65, 62,
-					74, 78, 78, 77, 74, 74, 72, 74, 70, 78,
-					84, 83, 85, 86, 86, 89, 89, 85, 86, 86,
-					98, 97, 93, 91, 92, 92, 99, 93, 94, 92
-				]);
-				chart.addPlot("grid", {type:"Grid", hMinorLines:true});
-				new dojox.charting.action2d.Tooltip(chart, "default");
-				new dojox.charting.action2d.Magnify(chart,"default");
-				chart.render();
-			};
-			zoomXAxis = function(){
-				chart.zoomIn("x",arguments[0]);
-				dojo.byId('minValue').value = arguments[0][0];
-				dojo.byId('maxValue').value = arguments[0][1];
-			}
-			dojo.addOnLoad(makeObjects);
+			var chart1, zoomAxis;
+
+			require(["dojo/dom", "dojo/ready", "dojox/charting/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Lines",
+				"dojox/charting/plot2d/StackedAreas", "dojox/charting/plot2d/Grid",
+				"dojox/charting/themes/PlotKit/orange", "dojox/charting/action2d/Tooltip",
+				"dojox/charting/action2d/Magnify", "dojo/parser", "dojox/form/RangeSlider"], function(dom, ready, Chart, Default, Lines, StackedAreas,
+					Grid, orange, Tooltip, Magnify){
+				zoomXAxis = function(){
+					chart1.zoomIn("x", arguments[0]);
+					chart2.zoomIn("x", arguments[0]);
+					dom.byId('minValue').value = arguments[0][0];
+					dom.byId('maxValue').value = arguments[0][1];
+				}
+				ready(function(){
+					chart1 = new Chart("chart1");
+					chart1.setTheme(orange);
+					chart1.addAxis("x", {fixLower: "minor", natural: true, stroke: "grey",
+						majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+					chart1.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 5, minorTickStep: 1, stroke: "grey",
+						majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+					chart1.addPlot("default", {type: Lines, markers: true});
+					chart1.addSeries("Series A", [
+						 8,  7,  3,  2,  5,  7,  9, 10,  2, 10,
+						14, 16, 18, 13, 16, 15, 20, 19, 15, 12,
+						24, 20, 20, 26, 28, 26, 28, 29, 24, 29,
+						31, 35, 37, 31, 35, 37, 37, 36, 31, 30,
+						50, 49, 42, 46, 44, 40, 47, 43, 48, 47,
+						51, 52, 52, 51, 54, 57, 58, 50, 54, 51,
+						62, 68, 67, 62, 62, 65, 61, 66, 65, 62,
+						74, 78, 78, 77, 74, 74, 72, 74, 70, 78,
+						84, 83, 85, 86, 86, 89, 89, 85, 86, 86,
+						98, 97, 93, 91, 92, 92, 99, 93, 94, 92
+					]);
+					chart1.addPlot("grid", {type: Grid, hMinorLines:true});
+					new Tooltip(chart1, "default");
+					new Magnify(chart1,"default");
+					chart1.render();
+					chart2 = new Chart("chart2");
+					chart2.setTheme(orange);
+					chart2.addAxis("x", {fixLower: "minor", natural: true, stroke: "grey",
+						majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+					chart2.addAxis("y", {vertical: true, min: 0, max: 200, majorTickStep: 5, minorTickStep: 1, stroke: "grey",
+							majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+					chart2.addPlot("default", {type: StackedAreas });
+					chart2.addSeries("Series A", [
+							 8,  7,  3,  2,  5,  7,  9, 10,  2, 10,
+							14, 16, 18, 13, 16, 15, 20, 19, 15, 12,
+							24, 20, 20, 26, 28, 26, 28, 29, 24, 29,
+							31, 35, 37, 31, 35, 37, 37, 36, 31, 30,
+							50, 49, 42, 46, 44, 40, 47, 43, 48, 47,
+							51, 52, 52, 51, 54, 57, 58, 50, 54, 51,
+							62, 68, 67, 62, 62, 65, 61, 66, 65, 62,
+							74, 78, 78, 77, 74, 74, 72, 74, 70, 78,
+							84, 83, 85, 86, 86, 89, 89, 85, 86, 86,
+							98, 97, 93, 91, 92, 92, 99, 93, 94, 92
+						]);
+					chart2.addSeries("Series B", [
+							 8,  7,  3,  2,  5,  7,  9, 10,  2, 10,
+							14, 16, 18, 13, 16, 15, 20, 19, 15, 12,
+							24, 20, 20, 26, 28, 26, 28, 29, 24, 29,
+							31, 35, 37, 31, 35, 37, 37, 36, 31, 30,
+							50, 49, 42, 46, 44, 40, 47, 43, 48, 47,
+							51, 52, 52, 51, 54, 57, 58, 50, 54, 51,
+							62, 68, 67, 62, 62, 65, 61, 66, 65, 62,
+							74, 78, 78, 77, 74, 74, 72, 74, 70, 78,
+							84, 83, 85, 86, 86, 89, 89, 85, 86, 86,
+							98, 97, 93, 91, 92, 92, 99, 93, 94, 92
+						]);
+					chart2.render();
+				});
+			});
 		</script>
 	</head>
 	<body class="tundra">
 		<h1>Axis Zoom Control</h1>
 		 Try to drag the slider endpoints and the bar to zoom X axis of the chart.
 		<div style="margin:20px">
-			<div id="chart" style="width: 800px; height: 400px;"></div>
+			<div id="chart1" style="width: 800px; height: 400px;"></div>
+			<div id="chart2" style="width: 800px; height: 400px;"></div>
 			<div id="hrXAxisSlider"
 				discreteValues="21"
 				onChange="zoomXAxis"
 				intermediateChanges="false"
-				dojoType="dojox.form.HorizontalRangeSlider"
+				data-dojo-type="dojox.form.HorizontalRangeSlider"
 				showButtons="false"
 				style="width:748px;margin-left:40px"
 				value="0,100">
-				<ol dojoType="dijit.form.HorizontalRuleLabels" container="topDecoration" style="height:1.2em;font-size:75%;color:gray;" count="11">
+				<ol data-dojo-type="dijit/form/HorizontalRuleLabels" container="topDecoration" style="height:1.2em;font-size:75%;color:gray;" count="11">
 					<li>0</li><li>10</li><li>20</li><li>30</li><li>40</li><li>50</li><li>60</li><li>70</li><li>80</li><li>90</li><li>100</li>
 				</ol>
-				<div dojoType="dijit.form.HorizontalRule" container="topDecoration" count=11 style="height:10px;"></div>
+				<div data-dojo-type="dijit/form/HorizontalRule" container="topDecoration" count=11 style="height:10px;"></div>
 			</div>
 		</div>
 		<p>X Axis Lower Value: <input readonly id="minValue" size="10" value="0"/></p>
diff --git a/dojox/charting/tests/test_axisoffsets.html b/dojox/charting/tests/test_axisoffsets.html
new file mode 100644
index 0000000..f78a6ed
--- /dev/null
+++ b/dojox/charting/tests/test_axisoffsets.html
@@ -0,0 +1,43 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+		<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true"></script>
+	 <script type="text/javascript">
+	require(["dojo/ready", "dojox/charting/Chart", "dojox/charting/axis2d/Default",
+		"dojox/charting/plot2d/Markers", "dojox/charting/themes/PlotKit/blue"], function(ready, Chart, Default, Markers,
+																						  blue){
+		ready(function(){
+			var chart = new Chart("chartDiv").
+				setTheme(blue).
+	 			addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true,
+					majorTickStep: 0.5, minorTickStep: 0.1, dropLabels: true }).
+				addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true,
+						labels: [{ value: 0, text: "0" }, { value: 1, text: "long label1" }, { value: 2, text: "long label2" },
+							{ value: 3, text: "long label3" }, { value: 4, text: "4" } ]
+					}).
+				addPlot("default", {type: Markers}).
+				addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
+				addSeries("Series B", [{x: 5, y: 2}, {x: 6, y: 3}, {x: 7, y: 2}]).
+				addSeries("Series C", [{x: 9, y: 3}, {x: 10, y: 4}, {x: 11, y: 3}]).
+				render();
+		});
+	});
+    </script>
+	</head>
+<body>
+	<div id="chartDiv" style="width: 400px; height: 250px;"></div>
+</body>
+</html>
\ No newline at end of file
diff --git a/dojox/charting/tests/test_bars.html b/dojox/charting/tests/test_bars.html
index d4ef677..a81c9db 100644
--- a/dojox/charting/tests/test_bars.html
+++ b/dojox/charting/tests/test_bars.html
@@ -20,7 +20,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.Chart3D");
diff --git a/dojox/charting/tests/test_chart2d-amd.html b/dojox/charting/tests/test_chart2d-amd.html
index bf7f2e1..f7e8387 100644
--- a/dojox/charting/tests/test_chart2d-amd.html
+++ b/dojox/charting/tests/test_chart2d-amd.html
@@ -59,7 +59,7 @@
 		function(arr, dom, domStyle, ready, Chart, Shrooms, blue, cyan, green, Ireland, SageToLime, Minty, Tufte,
 			dtl, Context){
 		
-		charts = [
+		var charts = [
 			{
 				description: "Clustered columns with positive and negative values, readable theme.",
 				makeChart: function(node){
@@ -78,9 +78,9 @@
 			{
 				description: "Bubble chart, green theme.",
 				makeChart: function(node){
-					(new dojox.charting.Chart(node)).
-						setTheme(dojox.charting.themes.SageToLime).
-						addPlot("default", { type: "Bubble", shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]} }).
+					(new Chart(node)).
+						setTheme(SageToLime).
+						addPlot("default", { type: "Bubble", shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]}, labels: true }).
 						addAxis("x", {
 							min: 0,
 							max: 6,
@@ -111,7 +111,7 @@
 			{
 				description: "Lines, calculated labels",
 				makeChart: function(node){
-					(new dojox.charting.Chart(node)).
+					(new Chart(node)).
 						addAxis("x", {
 							majorLabels: true, 
 							minorLabels: true, 
@@ -146,7 +146,7 @@
 			{
 				description: "Lines, pre-computed labels",
 				makeChart: function(node){
-					(new dojox.charting.Chart(node)).
+					(new Chart(node)).
 						addAxis("x", {
 							majorLabels: true, 
 							minorLabels: true, 
@@ -185,7 +185,7 @@
 			{
 				description: "Defaults: lines, no axes.",
 				makeChart: function(node){
-					(new dojox.charting.Chart(node)).
+					(new Chart(node)).
 						addSeries("Series A", [ 1, 2, 1, 2, 1, 2, 1 ]).
 						addSeries("Series B", [ 2, 1, 2, 1, 2, 1, 2 ]).
 						render();
@@ -194,7 +194,7 @@
 			{
 				description: "Defaults: lines, no axes, and custom strokes.",
 				makeChart: function(node){
-					(new dojox.charting.Chart(node)).
+					(new Chart(node)).
 						addSeries("Series A", [ 1, 2, 1, 2, 1, 2, 1 ], {stroke: "red"}).
 						addSeries("Series B", [ 2, 1, 2, 1, 2, 1, 2 ], {stroke: "blue"}).
 						render();
@@ -203,7 +203,7 @@
 			{
 				description: "Areas, Happy theme, no axes.",
 				makeChart: function(node){
-					(new dojox.charting.Chart(node)).
+					(new Chart(node)).
 						addPlot("default", {type: "Areas", tension:"X"}).
 						setTheme(Shrooms).
 						addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4]).
@@ -215,7 +215,7 @@
 			{
 				description: "Areas, no axes, custom strokes and fills.",
 				makeChart: function(node){
-					(new dojox.charting.Chart(node)).
+					(new Chart(node)).
 						addPlot("default", {type: "Areas"}).
 						addSeries("Series A",
 							[1, 2, 1, 2, 1, 2, 1],
@@ -237,7 +237,7 @@
 			{
 				description: "Lines, axes, blue theme.",
 				makeChart: function(node){
-					(new dojox.charting.Chart(node)).
+					(new Chart(node)).
 						setTheme(blue).
 						addAxis("x").
 						addAxis("y", {vertical: true}).
@@ -320,7 +320,7 @@
 				makeChart: function(node){
 					(new Chart(node)).
 						addPlot("default", {
-							type: "Markers", shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]}
+							type: "Markers", shadow:  {dx: 1, dy: 1, width: 5, color: [100, 0, 0, 1]}
 						}).
 						addSeries("Series A",
 							[ 1, 2, 1, 2, 1, 2, 1 ],
@@ -490,7 +490,7 @@
 				description: "Columns, no axes, custom strokes and fills.",
 				makeChart: function(node){
 					(new Chart(node)).
-						addPlot("default", {type: "Columns"}).
+						addPlot("default", {type: "Columns" }).
 						addSeries("Series A", [ 1, 2, 3, 4, 5 ], { stroke: { color: "red" }, fill: "lightpink" }).
 						addSeries("Series B", [ 5, 4, 3, 2, 1 ], { stroke: {color: "blue"}, fill: "lightblue" }).
 						render();
@@ -538,7 +538,7 @@
 			{
 				description: "Stacked bars, no axes, custom strokes and fills.",
 				makeChart: function(node){
-					(new Chart(node)).
+					(new Chart(node)).setTheme(blue).
 						addPlot("default", {type: "StackedBars"}).
 						addSeries("Series A", [ 1, 2, 3, 4, 5 ], { stroke: { color: "red" }, fill: "lightpink" }).
 						addSeries("Series B", [ 2, 1, 2, 1, 2 ], { stroke: { color: "blue" }, fill: "lightblue" }).
@@ -555,7 +555,7 @@
 						addAxis("y", {
 							vertical: true, fixLower: "major", fixUpper: "major", includeZero: true
 						}).
-						addPlot("default", {type: "ClusteredColumns", gap: 10}).
+						addPlot("default", {type: "ClusteredColumns", gap: 10, labels: true}).
 						addSeries("Series A",
 							[ 1, 2, 3, 4, 5 ],
 							{ stroke: {color: "red"}, fill: "lightpink" }
@@ -724,14 +724,16 @@
 							min: 0,
 							max: 6,
 							majorTick: { stroke: "black", length: 3 },
-							minorTick: { stroke: "gray", length: 3 }
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
 						}).
 						addAxis("y", {
 							vertical: true,
 							min: 0,
 							max: 10,
 							majorTick: { stroke: "black", length: 3 },
-							minorTick: { stroke: "gray", length: 3 }
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
 						}).
 						addSeries("Series A", [
 							{ x: 0.5, y: 5 },
@@ -751,20 +753,22 @@
 				description: "Scatter chart, custom axis, purple theme.",
 				makeChart: function(node){
 					(new Chart(node)).
-						setTheme(dojox.charting.themes.Ireland).
+						setTheme(Ireland).
 						addPlot("default", {type: "Scatter"}).
 						addAxis("x", {
 							min: 0,
 							max: 6,
 							majorTick: { stroke: "black", length: 3 },
-							minorTick: { stroke: "gray", length: 3 }
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
 						}).
 						addAxis("y", {
 							vertical: true,
 							min: 0,
 							max: 10,
 							majorTick: { stroke: "black", length: 3 },
-							minorTick: { stroke: "gray", length: 3 }
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
 						}).
 						addSeries("Series A", [
 							{ x: 0.5, y: 5 },
@@ -784,7 +788,7 @@
 				description: "Markers, lines, 2D data, custom axis, blue theme.",
 				makeChart: function(node){
 					(new Chart(node)).
-						setTheme(dojox.charting.themes.PlotKit.blue).
+						setTheme(blue).
 						addPlot("default", {
 							type: "Default",
 							lines: true,
@@ -795,14 +799,16 @@
 							min: 0,
 							max: 6,
 							majorTick: { stroke: "black", length: 3 },
-							minorTick: { stroke: "gray", length: 3 }
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
 						}).
 						addAxis("y", {
 							vertical: true,
 							min: 0,
 							max: 10,
 							majorTick: { stroke: "black", length: 3 },
-							minorTick: { stroke: "gray", length: 3 }
+							minorTick: { stroke: "gray", length: 3 },
+							minorLabels: false
 						}).
 						addSeries("Series A", [
 							{ x: 0.5, y: 5 },
diff --git a/dojox/charting/tests/test_chart2d.html b/dojox/charting/tests/test_chart2d.html
index e2567ad..2feb1f6 100644
--- a/dojox/charting/tests/test_chart2d.html
+++ b/dojox/charting/tests/test_chart2d.html
@@ -19,7 +19,7 @@
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
         dojo.require("dojox.charting.Chart");
         dojo.require("dojox.charting.axis2d.Default");
diff --git a/dojox/charting/tests/test_chart2d_dynamics.html b/dojox/charting/tests/test_chart2d_dynamics.html
index a7f634b..094bfad 100644
--- a/dojox/charting/tests/test_chart2d_dynamics.html
+++ b/dojox/charting/tests/test_chart2d_dynamics.html
@@ -24,7 +24,7 @@
 	.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
 	.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 dojo.require("dijit.form.Button");
 dojo.require("dijit.form.CheckBox");
diff --git a/dojox/charting/tests/test_chart2d_updating.html b/dojox/charting/tests/test_chart2d_updating.html
index 873296a..620c80f 100644
--- a/dojox/charting/tests/test_chart2d_updating.html
+++ b/dojox/charting/tests/test_chart2d_updating.html
@@ -20,7 +20,7 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 
         dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_chartAxisTitle.html b/dojox/charting/tests/test_chartAxisTitle.html
index 8038af6..1d68806 100644
--- a/dojox/charting/tests/test_chartAxisTitle.html
+++ b/dojox/charting/tests/test_chartAxisTitle.html
@@ -40,7 +40,7 @@
 		-moz-transform: rotate(-90deg);
 	}
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_chartTitle.html b/dojox/charting/tests/test_chartTitle.html
index 962967e..9abfc60 100644
--- a/dojox/charting/tests/test_chartTitle.html
+++ b/dojox/charting/tests/test_chartTitle.html
@@ -21,7 +21,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 	@import "../../../dijit/themes/tundra/tundra.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_chartingsize.html b/dojox/charting/tests/test_chartingsize.html
index 5c8288e..8fa05d3 100644
--- a/dojox/charting/tests/test_chartingsize.html
+++ b/dojox/charting/tests/test_chartingsize.html
@@ -18,7 +18,7 @@
 		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 		<script type="text/javascript"
 				src="../../../dojo/dojo.js"
-				djConfig="isDebug:true,  parseOnLoad: true"></script>		
+				data-dojo-config="isDebug:true,  parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 		
@@ -29,9 +29,8 @@
 		    dojo.require("dojox.charting.themes.PlotKit.orange");
 		</script>
 	</head>
-	<body>
-		<div dojoType="dijit.layout.BorderContainer" design="sidebar" gutters="false"
-			style="width: 100%; height: 100%;">
+	<body style="width:90%;height:480px">
+		<div dojoType="dijit.layout.BorderContainer" gutters="true" id="borderContainer" style="width:100%;height:100%">
      		<div dojoType="dojox.charting.widget.Chart" id="lineChart"
 	    		theme="dojox.charting.themes.PlotKit.orange" region="center">
 				<div class="axis" name="x" font="italic normal bold 10pt Tahoma"></div>
@@ -39,7 +38,7 @@
 				<div class="plot" name="default" type="dojox.charting.plot2d.Lines"></div>
 				<div class="series" name="Series A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4, 7, 3, 4, 2, 1, 4, 4, 5"></div>
 				<div class="series" name="Series B" data="2, 1, 0.5, 1, 3, 8, 4, 1.7, 1.3, 4.1, 1, 5, 1, 2, 3"></div>
-			</div> 
+            </div>
 		</div>
 	</body>
 </html>
\ No newline at end of file
diff --git a/dojox/charting/tests/test_cylinders.html b/dojox/charting/tests/test_cylinders.html
index c8c358c..ba16e2a 100644
--- a/dojox/charting/tests/test_cylinders.html
+++ b/dojox/charting/tests/test_cylinders.html
@@ -20,7 +20,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.Chart3D");
diff --git a/dojox/charting/tests/test_dropLabels.html b/dojox/charting/tests/test_dropLabels.html
new file mode 100644
index 0000000..0be6385
--- /dev/null
+++ b/dojox/charting/tests/test_dropLabels.html
@@ -0,0 +1,122 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>	 
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Testing Axes</title>
+<style type="text/css">
+	@import "../../../dojo/resources/dojo.css";
+	@import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true"></script>
+<script type="text/javascript">
+var chart1a, chart1b;
+function rotationXChanged(value){
+	value = parseInt(value);
+	chart1a.getAxis("x").opt.rotation = value;
+	chart1a.dirty = true;
+	chart1a.render();
+	chart1b.getAxis("x").opt.rotation = value;
+	chart1b.dirty = true;
+	chart1b.render();
+}
+function rotationYChanged(value){
+	value = parseInt(value);
+	chart1a.getAxis("y").opt.rotation = value;
+	chart1a.dirty = true;
+	chart1a.render();
+	chart1b.getAxis("y").opt.rotation = value;
+	chart1b.dirty = true;
+	chart1b.render();
+}
+require(["dojo/ready", "dojox/charting/Chart", "dojox/charting/axis2d/Default",
+	"dojox/charting/plot2d/Markers", "dojox/charting/action2d/MouseZoomAndPan", "dojox/charting/Theme"],
+		function(ready, Chart, Default, Markers,
+			MouseZoomAndPan, Theme){
+	ready(function(){
+
+		var myLabelFunc = function(text, value){
+			return text+" make it even longer";
+		};
+		chart1a = new Chart("test1a").
+        	    addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, font: "14px helvetica",
+					minorTickStep: 0.5, labelFunc: myLabelFunc, rotation: 30}).
+    	        addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true, labelFunc: myLabelFunc}).
+        	    addPlot("default", {type: Markers}).
+	            addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
+    	        addSeries("Series B", [{x: 3, y: 2}, {x: 4, y: 3}, {x: 5, y: 2}]).
+        	    addSeries("Series C", [{x: 5, y: 3}, {x: 6, y: 4}, {x: 7, y: 3}]).
+           		render();
+		new MouseZoomAndPan(chart1a);
+
+		chart1b = new Chart("test1b").
+        	    addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, font: "14px helvetica",
+					minorTickStep: 0.5, labelFunc: myLabelFunc, rotation: 30, leftBottom: false}).
+    	        addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true, labelFunc: myLabelFunc, leftBottom: false}).
+        	    addPlot("default", {type: Markers}).
+	            addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
+    	        addSeries("Series B", [{x: 3, y: 2}, {x: 4, y: 3}, {x: 5, y: 2}]).
+        	    addSeries("Series C", [{x: 5, y: 3}, {x: 6, y: 4}, {x: 7, y: 3}]).
+           		render();
+		new MouseZoomAndPan(chart1b);
+
+		var chart2 = new Chart("test2").
+        	    addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, font: "14px helvetica",
+					majorTickStep: 2, minorTickStep: 1,
+						labels: [ {value: 0, text:"this is a very very long label"},
+							{ value: 1, text:"sm"},
+							{ value: 2, text:"short" },
+							{ value: 3, text: "minor" },
+							{ value: 4, text:"la" },
+							{ value: 5, text: "label" },
+							{ value: 6, text: "el" }
+						]}).
+            	addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
+            	addPlot("default", {type: Markers}).
+            	addSeries("Series A", [{x: 0, y: 1}, {x: 2, y: 2}, {x: 4, y: 1}]).
+            	addSeries("Series B", [{x: 2, y: 2}, {x: 4, y: 3}, {x: 6, y: 2}]).
+            	addSeries("Series C", [{x: 4, y: 3}, {x: 6, y: 4}, {x: 8, y: 3}]).
+            	render();
+		new MouseZoomAndPan(chart2);
+
+
+		var chart3 = new Chart("test3").
+        	    addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true, font: "14px helvetica",
+					majorTickStep: 0.5, minorTickStep: 0.1 }).
+            	addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
+            	addPlot("default", {type: Markers}).
+            	addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
+            	addSeries("Series B", [{x: 5, y: 2}, {x: 6, y: 3}, {x: 7, y: 2}]).
+            	addSeries("Series C", [{x: 9, y: 3}, {x: 10, y: 4}, {x: 11, y: 3}]).
+           		render();
+		new MouseZoomAndPan(chart3);
+	});
+});
+</script>
+</head>
+<body>
+<h1>Testing Axes drop labels</h1>
+<p>1: Axes with rotation & labelFunc</p>
+X Axis Label Rotation: <input onchange="rotationXChanged(this.value)" value="30"/>
+Y Axis Label Rotation: <input onchange="rotationYChanged(this.value)" value="0"/>
+<div id="test1a" style="width: 600px; height: 400px;"></div>
+<div id="test1b" style="width: 600px; height: 400px;"></div>
+<p>2: Axes with labels array.</p>
+<div id="test2" style="width: 600px; height: 200px;"></div>
+<p>3: Numeric axis.</p>
+<div id="test3" style="width: 320px; height: 180px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/test_event2d.html b/dojox/charting/tests/test_event2d.html
index c89fd15..269e39f 100644
--- a/dojox/charting/tests/test_event2d.html
+++ b/dojox/charting/tests/test_event2d.html
@@ -26,7 +26,7 @@
 .dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
 .dojoxLegendText {vertical-align: text-top; padding-right: 10px}
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_fillstroke.html b/dojox/charting/tests/test_fillstroke.html
index c904611..6bc9e13 100644
--- a/dojox/charting/tests/test_fillstroke.html
+++ b/dojox/charting/tests/test_fillstroke.html
@@ -26,7 +26,7 @@
 			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
 			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojo.parser");	
diff --git a/dojox/charting/tests/test_filter.html b/dojox/charting/tests/test_filter.html
new file mode 100644
index 0000000..a1f99d2
--- /dev/null
+++ b/dojox/charting/tests/test_filter.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Filters</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../dijit/themes/tundra/tundra.css">
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript">
+			var seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
+			var dropShadow;
+			var dropShadowBar;
+			var dropShadowLine;
+			require([
+			"dojox/gfx/filters",
+			"dojox/gfx/svgext",
+			"dojox/charting/widget/Chart",
+			"dojox/charting/axis2d/Default",
+			"dojox/charting/plot2d/Columns",
+			"dojox/charting/plot2d/Bars",
+			"dojox/charting/plot2d/Default",
+			"dojox/charting/plot2d/Pie",
+			"dojox/charting/action2d/Shake",
+			"dojox/charting/themes/PlotKit/orange",
+			"dojox/charting/themes/PlotKit/blue",
+			"dojox/charting/themes/PlotKit/green",
+			"dojo/parser"], function(filters){
+					dropShadow = filters.shadows.dropShadow({id: "ds" });
+					dropShadowBar = filters.createFilter({ id: "dsb",
+						x: "-10%", y: "-10%", width: "125%", height: "125%" },
+							[
+								filters.feGaussianBlur({"in":"SourceAlpha","stdDeviation":4}),
+								filters.feOffset({"dx":-5,"dy":5,"result":"offsetBlur"}),
+								filters.feMerge("offsetBlur","SourceGraphic")
+							]);
+					dropShadowLine = filters.createFilter({ id: "dsl",
+							x: "2%", y: "2%", width: "98%", height: "98%" },
+						[
+							filters.feGaussianBlur({"in":"SourceAlpha","stdDeviation":2}),
+							filters.feOffset({"dx":2,"dy":2,"result":"offsetBlur"}),
+							filters.feMerge("offsetBlur","SourceGraphic")
+						]);
+			});;
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Shadows</h1>
+		<p>Testing charts shadows</p>
+		<table border="0" cellspacing="30">
+			<tr>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart1" style="width: 300px; height: 300px;">
+						<div class="axis" name="y" font="italic normal normal 8pt Tahoma" natural="true" fixLower="major" fixUpper="major"></div>
+						<div class="axis" name="x" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Bars" fill="'red'" filter="dropShadowBar" stroke="null" gap="5" animate="true"></div>
+						<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+						<div class="action" type="Shake"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart2" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma" natural="true" fixLower="major" fixUpper="major"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Columns" fill="'red'" filter="dropShadow" stroke="null" gap="5" animate="true"></div>
+						<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+						<div class="action" type="Shake"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart3" theme="dojox.charting.themes.PlotKit.blue"
+							 style="width: 300px; height: 300px;">
+						<div class="plot" name="default" type="Pie" radius="100" fontColor="white" filter="dropShadow" animate="true"></div>
+						<div class="series" name="Series B" array="seriesB"></div>
+						<div class="action" type="Shake"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart4" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma" natural="true" fixLower="major" fixUpper="major"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Default" stroke="{width: 4, color: 'red'}" filter="dropShadowLine" animate="true"></div>
+						<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+					</div>
+				</td>
+			</tr>
+		</table>
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/test_fireEvent.html b/dojox/charting/tests/test_fireEvent.html
index 3cf97e6..5933d2d 100644
--- a/dojox/charting/tests/test_fireEvent.html
+++ b/dojox/charting/tests/test_fireEvent.html
@@ -28,7 +28,7 @@
     .events th, .events td {padding: 0.25em 1em;}
     .events th {font-weight: bold;}
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 dojo.require("dijit.form.Button");
 dojo.require("dijit.form.Select");
diff --git a/dojox/charting/tests/test_grid.html b/dojox/charting/tests/test_grid.html
new file mode 100644
index 0000000..5efeaed
--- /dev/null
+++ b/dojox/charting/tests/test_grid.html
@@ -0,0 +1,78 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+	<title>Chart 2D</title>
+	<style type="text/css">
+	    @import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+	</style>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
+	<script type="text/javascript">
+		require([
+		"dojo/ready",
+		"dojo/dom",
+		"dojo/_base/Color",
+		"dojox/charting/Chart",
+		"dojox/charting/axis2d/Default",
+		"dojox/charting/plot2d/Lines",	
+		"dojox/charting/plot2d/Grid"],
+		function(ready, dom, Color, Chart, Axis, Lines, Grid){
+			ready(function(){
+				var chart = new Chart(dom.byId("chart")).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true  }).
+						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
+						addPlot("default", { type: Lines }).
+						addPlot("grid", { type: Grid, renderOnAxis: false, majorVLine: { color: "green", width: 3 }, majorHLine: { color: "red", width: 3 } }).
+						addSeries("Series A", [ 2, 1, 0.5, -1, -2 ] ).
+						render();
+				var color = new Color({ r:246, g:249, b:253, a:0.8 });
+				var color2 = new Color({ r:146, g:149, b:153, a:0.8 });
+				var chart = new Chart(dom.byId("chartH")).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true  }).
+						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
+						addPlot("default", { type: Lines }).
+						addPlot("grid", { type: Grid, renderOnAxis: false, majorVLine: { color: color, width: 1 }, hMajorLines: false,
+                            hFill: color, hAlternateFill: color2, hStripes: true }).
+						addSeries("Series A", [ 2, 1, 0.5, -1, -2 ] ).
+						render();
+
+				var chart = new Chart(dom.byId("chartV")).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true  }).
+						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
+						addPlot("default", { type: Lines }).
+						addPlot("grid", { type: Grid, renderOnAxis: false, majorHLine: { color: color, width: 1 }, vMajorLines: false, vFill: color, vStripes: true }).
+						addSeries("Series A", [ 2, 1, 0.5, -1, -2 ] ).
+						render();
+				color = new Color({ r:246, g:249, b:253, a:0.3 });
+				var chart = new Chart(dom.byId("chartScot")).
+						addAxis("x", { fixLower: "minor", fixUpper: "minor", minorTickStep: 0.2 }).
+						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true , minorTickStep: 0.2 }).
+						addPlot("default", { type: Lines }).
+						addPlot("grid", { type: Grid, renderOnAxis: false, hFill: color, vFill: color, hMajorLines: false, vMajorLines: false, hStripes: true, vStripes: true }).
+						addSeries("Series A", [ 2, 1, 0.5, -1, -2 ] ).
+						render();
+			});
+	});
+	</script>
+	</head>
+	<body>
+		<h1>Grid</h1>
+		<div id="chart" style="width:400px; height:300px"></div>
+		<div id="chartH" style="width:400px; height:300px"></div>
+		<div id="chartV" style="width:400px; height:300px"></div>
+		<div id="chartScot" style="width:400px; height:300px"></div>
+	</body>
+</html>
diff --git a/dojox/charting/tests/test_itemcolor.html b/dojox/charting/tests/test_itemcolor.html
new file mode 100644
index 0000000..ababe26
--- /dev/null
+++ b/dojox/charting/tests/test_itemcolor.html
@@ -0,0 +1,149 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Chart 2D</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../dijit/themes/tundra/tundra.css">
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript">
+			source = [
+				{x: 1, y: 2.6, size: 0.3, fill: "orange"},
+				{x: 2, y: 1.8, size: 0.4, fill: "orange"},
+				{x: 3, y: 2, size: 0.1 },
+				{x: 4, y: 1, size: 0.6},
+				{x: 5, y: 1.4, size: 0.5},
+				{x: 6, y: 0.7, size: 0.3},
+				{x: 7, y: 2, size: 0.6}
+			];
+			var styleFunc, changeLimits;
+			require([
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/charting/widget/Chart",
+			"dojox/charting/axis2d/Default",
+			"dojox/charting/plot2d/Bars",
+			"dojox/charting/plot2d/Columns",
+			"dojox/charting/plot2d/Bubble",
+			"dojox/charting/plot2d/Areas",
+			"dojox/charting/plot2d/Scatter",
+			"dojox/charting/plot2d/Pie",
+			"dojox/charting/themes/PlotKit/orange",
+			"dojox/charting/themes/PlotKit/blue",
+			"dojox/charting/themes/PlotKit/green", "dojo/parser"], function(dom, registry){
+				changeLimits = function(){
+					registry.byId("chart1").chart.getPlot("default").dirty = true;
+					registry.byId("chart1").chart.render();
+					registry.byId("chart2").chart.getPlot("default").dirty = true;
+					registry.byId("chart2").chart.render();
+					registry.byId("chart3").chart.getPlot("default").dirty = true;
+					registry.byId("chart3").chart.render();
+					registry.byId("chart4").chart.getPlot("default").dirty = true;
+					registry.byId("chart4").chart.render();
+					registry.byId("chart5").chart.getPlot("default").dirty = true;
+					registry.byId("chart5").chart.render();
+					registry.byId("chart6").chart.getPlot("default").dirty = true;
+					registry.byId("chart6").chart.render();
+				};
+ 				styleFunc = function(item){
+					if(item.y < dom.byId("low").value){
+						return { fill : "red" };
+					}else if(item.y > dom.byId("high").value){
+						return { fill: "green" };
+					}
+					return {};
+				};
+			});
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Test Chart Item Coloring</h1>
+		<table border="0" cellspacing="30">
+			<tr>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart1" style="width: 300px; height: 300px;"
+							theme="dojox.charting.themes.PlotKit.blue">
+						<div class="axis" name="x" fixUpper="major" includeZero="true" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Bars" styleFunc="styleFunc" fill="'yellow'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart2" theme="dojox.charting.themes.PlotKit.orange" 
+							fill="'lightgrey'" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal bold 10pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true" minorLabels="false"
+							font="italic normal bold 10pt Tahoma"></div>
+						<div class="plot" name="default" type="Columns" styleFunc="styleFunc" fill="'yellow'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart3" theme="dojox.charting.themes.PlotKit.green"
+							 style="width: 300px; height: 300px;">
+						<div class="plot" name="default" type="Pie" radius="100" fontColor="white" styleFunc="styleFunc" fill="'yellow'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart4" theme="dojox.charting.themes.PlotKit.orange"
+							fill="'lightgrey'" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal bold 10pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal bold 10pt Tahoma"></div>
+						<div class="plot" name="default" type="Bubble" styleFunc="styleFunc" fill="'yellow'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart5" theme="dojox.charting.themes.PlotKit.orange"
+							fill="'lightgrey'" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal bold 10pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal bold 10pt Tahoma"></div>
+						<div class="plot" name="default" type="Scatter" styleFunc="styleFunc" markerFill="'yellow'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart6" theme="dojox.charting.themes.PlotKit.orange"
+							fill="'lightgrey'" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal bold 10pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal bold 10pt Tahoma"></div>
+						<div class="plot" name="default" type="Areas" styleFunc="styleFunc" markerFill="'yellow'" markers="true" fill="'blue'"></div>
+						<div class="series" name="Run A" array="source"></div>
+					</div>
+				</td>
+			</tr>
+		</table>
+		<label>Low Limit</label>
+		<input id="low" type="text" onchange="changeLimits()" value="1"></input>
+		<label>High Limit</label>
+		<input id="high" type="text" onchange="changeLimits()" value="2"></input>
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/test_label_shortening.html b/dojox/charting/tests/test_label_shortening.html
index c017740..5931289 100644
--- a/dojox/charting/tests/test_label_shortening.html
+++ b/dojox/charting/tests/test_label_shortening.html
@@ -21,7 +21,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 	@import "../../../dijit/themes/claro/claro.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_labels2d.html b/dojox/charting/tests/test_labels2d.html
index 44b1f5d..fff63a3 100644
--- a/dojox/charting/tests/test_labels2d.html
+++ b/dojox/charting/tests/test_labels2d.html
@@ -20,7 +20,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_legend.html b/dojox/charting/tests/test_legend.html
new file mode 100644
index 0000000..dbcc06c
--- /dev/null
+++ b/dojox/charting/tests/test_legend.html
@@ -0,0 +1,73 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Chart 2D</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../dijit/themes/tundra/tundra.css">
+		<style>
+			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
+			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript">
+			var seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
+			var onClick;
+			require([
+			"dijit/registry",
+			"dijit/form/Button",
+			"dojox/charting/widget/Chart",
+			"dojox/charting/axis2d/Default",
+			"dojox/charting/plot2d/Default",
+			"dojox/charting/widget/Legend",
+			"dojo/parser"], function(registry){
+				onClick = function(){
+					var chart = registry.byId("chart1").chart;
+					chart.addSeries("Run B", [6.2, 1.4, 1, 2, 4.1, 6.3, 5]);
+					chart.render();
+					registry.byId("legend1").refresh();
+				}
+			});
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Legend</h1>
+
+		<div data-dojo-type="dojox.charting.widget.Chart" id="chart1" style="width: 300px; height: 300px;">
+			<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+			<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+				font="italic normal normal 8pt Tahoma"></div>
+			<div class="plot" name="default" type="Default" markers="true" markerFill="'red'"></div>
+			<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+		</div>
+		<div data-dojo-type="dojox.charting.widget.Legend" chartRef="chart1" id="legend1"></div>
+
+		<div data-dojo-type="dojox.charting.widget.Chart" id="chart2" style="width: 300px; height: 300px;">
+			<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+			<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+				font="italic normal normal 8pt Tahoma"></div>
+			<div class="plot" name="default" type="Default" markers="true" lines="false" markerFill="'red'"></div>
+			<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+		</div>
+		<div data-dojo-type="dojox.charting.widget.Legend" chartRef="chart2"></div>
+		<button data-dojo-type="dijit.form.Button" onclick="onClick()">Click me</button>
+	</body>
+</html>
diff --git a/dojox/charting/tests/test_missingPoints.html b/dojox/charting/tests/test_missingPoints.html
new file mode 100644
index 0000000..8be5137
--- /dev/null
+++ b/dojox/charting/tests/test_missingPoints.html
@@ -0,0 +1,221 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Test Missing point interpolation</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../dijit/themes/tundra/tundra.css">
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript">
+			var seriesA = [
+				{ x: 1, y : null },
+				{ x: 2, y : 2 },
+				{ x: 3, y : 2 },
+				{ x: 4, y: null },
+				{ x: 5, y: null },
+				{ x: 6, y: 3 },
+				{ x: 7, y: 4 },
+				{ x: 8, y: null },
+				{ x: 9, y: 5 },
+				{ x: 10, y: 6 },
+				{ x: 13, y: 7 },
+				{ x: 14, y: 8 }
+				
+			];
+			var seriesB = [null, 3, 3, null, null, 4, 5, null, 6, 7, 7, 8];
+			var seriesC = [
+				{ x: 2, y: 4 },
+				{ x: 3, y: 4 },
+				{ x: 6, y: 5 },
+				{ x: 7, y: 6 },
+				{ x: 9, y: 7 },
+				{ x: 10, y: 8 },
+				{ x: 13, y: 9 },
+				{ x: 14, y: 10 }
+			];
+			// in theory this should not happen, this is really invalid data set...
+			var seriesD = [
+				null,
+				{ x: 2, y : 5 },
+				{ x: 3, y : 5 },
+				null,
+				null,
+				{ x: 6, y: 6 },
+				{ x: 7, y: 7 },
+			    null,
+				{ x: 9, y: 8 },
+				{ x: 10, y: 9 },
+				null, null
+			];
+			require([
+			"dojox/charting/widget/Chart",
+			"dojox/charting/axis2d/Default",
+			"dojox/charting/plot2d/Lines",
+			"dojox/charting/plot2d/StackedLines",
+			"dojox/charting/plot2d/Columns",
+			"dojox/charting/plot2d/StackedColumns",
+			"dojox/charting/plot2d/ClusteredColumns",
+			"dojox/charting/plot2d/Bars",
+			"dojox/charting/plot2d/StackedBars",
+			"dojox/charting/plot2d/ClusteredBars",
+			"dojox/charting/themes/Adobebricks",
+			"dojo/parser"]);
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Chart with missing data points</h1>
+		<table border="0" cellspacing="30">
+			<tr>
+				<td>
+					<div data-dojo-type="dojox/charting/widget/Chart" id="chart1" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Lines"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run B" array="seriesB"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox/charting/widget/Chart" id="chart2" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Lines" interpolate="true"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run B" array="seriesB"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div data-dojo-type="dojox/charting/widget/Chart" id="chart3" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="StackedLines"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox/charting/widget/Chart" id="chart4" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="StackedLines" interpolate="true"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div data-dojo-type="dojox/charting/widget/Chart" id="chart5" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Columns"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox/charting/widget/Chart" id="chart6" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="y" font="italic normal normal 8pt Tahoma" fixUpper="major" ></div>
+						<div class="axis" name="x" vertical="true" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Bars"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div data-dojo-type="dojox/charting/widget/Chart" id="chart7" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major"  
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="StackedColumns"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox/charting/widget/Chart" id="chart8" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="y" font="italic normal normal 8pt Tahoma" fixUpper="major" ></div>
+						<div class="axis" name="x" vertical="true" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="StackedBars"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div data-dojo-type="dojox/charting/widget/Chart" id="chart9" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" 
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="ClusteredColumns"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox/charting/widget/Chart" id="chart10" style="width: 400px; height: 400px;"
+							theme="dojox.charting.themes.Adobebricks">
+						<div class="axis" name="y" font="italic normal normal 8pt Tahoma" fixUpper="major"></div>
+						<div class="axis" name="x" vertical="true"  
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="ClusteredBars"></div>
+						<div class="series" name="Run A" array="seriesA"></div>
+						<div class="series" name="Run C" array="seriesC"></div>
+						<div class="series" name="Run D" array="seriesD"></div>
+					</div>
+				</td>
+			</tr>
+		</table>
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/test_mouseIndicator.html b/dojox/charting/tests/test_mouseIndicator.html
index 6ce0e79..081a4d3 100644
--- a/dojox/charting/tests/test_mouseIndicator.html
+++ b/dojox/charting/tests/test_mouseIndicator.html
@@ -22,7 +22,7 @@
 @import "../../../dijit/themes/tundra/tundra.css";
 </style>
 <script type="text/javascript" src="../../../dojo/dojo.js"
-	djConfig="isDebug: true, parseOnLoad: true"></script>
+	data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 			dojo.require("dojo.parser");
 
@@ -34,11 +34,11 @@
 			var chart;
 			makeObjects = function(){
 				chart = new dojox.charting.Chart("chart");
-				chart.addAxis("x", {type : "Default", fixLower: "minor", natural: true, stroke: "grey",
+				chart.addAxis("x", {type : "Default", fixLower: "minor", natural: true, stroke: "gray",
 					majorTick: {color: "red", length: 4}, minorTick: {color: "blue", length: 2}});
-				chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 10, minorTickStep: 5, stroke: "grey",
+				chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 10, minorTickStep: 5, stroke: "gray",
 					majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
-				chart.addPlot("default", {type: "Default",markers: false});
+				chart.addPlot("default", {type: "Default", markers: false});
 				chart.addSeries("Series A", [
 					 8,  7,  3,  2,  5,  7,  9, 10,  2, 10,
 					14, 16, 18, 13, 16, 15, 20, 19, 15, 12,
@@ -51,7 +51,7 @@
 					84, 83, 85, 86, 86, 89, 89, 85, 86, 86,
 					98, 97, 93, 91, 92, 92, 99, 93, 94, 92
 				]);
-				new dojox.charting.action2d.MouseIndicator(chart, "default", { series : "Series A" });
+				new dojox.charting.action2d.MouseIndicator(chart, "default", { series : "Series A", mouseOver: true  });
 				chart.render();
 			};
 		
diff --git a/dojox/charting/tests/test_mouseIndicator2.html b/dojox/charting/tests/test_mouseIndicator2.html
index 0bd61d4..e1272a4 100644
--- a/dojox/charting/tests/test_mouseIndicator2.html
+++ b/dojox/charting/tests/test_mouseIndicator2.html
@@ -20,48 +20,46 @@
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dijit/themes/tundra/tundra.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
-			dojo.require("dojo.parser");
+			require(["dojo/ready", "dojo/on", "dojox/charting/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Lines",
+				"dojox/charting/action2d/MouseZoomAndPan", "dojox/charting/action2d/MouseIndicator"],
+				function(ready, on, Chart, Default, Lines, MouseZoomAndPan, MouseIndicator){
 
-			dojo.require("dojox.charting.Chart");
-            dojo.require("dojox.charting.axis2d.Default");
-            dojo.require("dojox.charting.plot2d.Lines");
-			dojo.require("dojox.charting.action2d.MouseZoomAndPan");
-			dojo.require("dojox.charting.action2d.MouseIndicator");
-			
-			var chart;
-			makeObjects = function(){
-				chart = new dojox.charting.Chart("chart", { margins : {l :20, t:10, b:10, r: 50}});
-				chart.addAxis("x", {type : "Default", fixLower: "minor", natural: true, stroke: "grey",
-					majorTick: {color: "red", length: 4}, minorTick: {color: "blue", length: 2}});
-				chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 10, minorTickStep: 5, stroke: "grey",
-					majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
-				chart.addPlot("default", {type: "Default",markers: false});
-				chart.addSeries("Series A", [
-					 { x: 1, y: 8},{ x: 2, y: 7},{ x: 3, y: 3},{ x: 4, y: 2},{ x: 5, y: 5},{ x: 6, y: 7},{ x: 7, y: 9},{ x: 8, y: 10},{ x: 9, y: 2},{ x: 10, y: 10},
-					{ x: 15, y: 14},{ x: 16, y: 16},{ x: 17, y: 18},{ x: 18, y: 13},{ x: 19, y: 16},{ x: 20, y: 15},{ x: 21, y: 20},{ x: 22, y: 19},{ x: 23, y: 15},{ x: 24, y: 12},
-					{ x: 25, y: 24},{ x: 26, y: 20},{ x: 27, y: 20},{ x: 28, y: 26},{ x: 29, y: 28},{ x: 30, y: 26},{ x: 31, y: 28},{ x: 32, y: 29},{ x: 33, y: 24},{ x: 34, y: 29},
-					{ x: 35, y: 31},{ x: 36, y: 35},{ x: 37, y: 37},{ x: 38, y: 31},{ x: 39, y: 35},{ x: 40, y: 37},{ x: 41, y: 37},{ x: 42, y: 36},{ x: 43, y: 31},{ x: 44, y: 30},
-					{ x: 45, y: 50},{ x: 46, y: 49},{ x: 47, y: 42},{ x: 48, y: 46},{ x: 49, y: 44},{ x: 50, y: 40},{ x: 51, y: 47},{ x: 52, y: 43},{ x: 53, y: 48},{ x: 54, y: 47},
-					{ x: 55, y: 51},{ x: 56, y: 52},{ x: 57, y: 52},{ x: 58, y: 51},{ x: 59, y: 54},{ x: 60, y: 57},{ x: 61, y: 58},{ x: 62, y: 50},{ x: 63, y: 54},{ x: 64, y: 51},
-					{ x: 65, y: 62},{ x: 66, y: 68},{ x: 67, y: 67},{ x: 68, y: 62},{ x: 69, y: 62},{ x: 70, y: 65},{ x: 71, y: 61},{ x: 72, y: 66},{ x: 73, y: 65},{ x: 74, y: 62},
-					{ x: 75, y: 74},{ x: 76, y: 78},{ x: 77, y: 78},{ x: 78, y: 77},{ x: 79, y: 74},{ x: 80, y: 74},{ x: 81, y: 72},{ x: 82, y: 74},{ x: 83, y: 70},{ x: 84, y: 78},
-					{ x: 85, y: 84},{ x: 86, y: 83},{ x: 87, y: 85},{ x: 88, y: 86},{ x: 89, y: 86},{ x: 90, y: 89},{ x: 91, y: 89},{ x: 92, y: 85},{ x: 93, y: 86},{ x: 94, y: 86},
-					{ x: 95, y: 98},{ x: 96, y: 97},{ x: 97, y: 93},{ x: 98, y: 91},{ x: 99, y: 92},{ x: 100, y: 92}
-				]);
-				new dojox.charting.action2d.MouseZoomAndPan(chart, "default", { axis: "x", enableScroll: false });
-				new dojox.charting.action2d.MouseIndicator(chart, "default", { series: "Series A", 
-					font: "normal normal bold 12pt Tahoma",	fillFunc: function(v){
-							return v.y>55?"green":"red";
-						}, 	labelFunc: function(v){
-							return "x: "+v.x+", y:"+v.y;
-						}});
-				chart.render();
-			};
-		
-			dojo.addOnLoad(makeObjects);
-			
+				ready(function(){
+					var chart = new Chart("chart", { margins : {l :20, t:10, b:10, r: 50}});
+					chart.addAxis("x", {fixLower: "minor", natural: true, stroke: "gray",
+						majorTick: {color: "red", length: 4}, minorTick: {color: "blue", length: 2}});
+					chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 10, minorTickStep: 5, stroke: "gray",
+						majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
+					chart.addPlot("default", {type: Lines, markers: false});
+					chart.addSeries("Series A", [
+						{ x: 1, y: 8},{ x: 2, y: 7},{ x: 3, y: 3},{ x: 4, y: 2},{ x: 5, y: 5},{ x: 6, y: 7},{ x: 7, y: 9},{ x: 8, y: 10},{ x: 9, y: 2},{ x: 10, y: 10},
+						{ x: 15, y: 14},{ x: 16, y: 16},{ x: 17, y: 18},{ x: 18, y: 13},{ x: 19, y: 16},{ x: 20, y: 15},{ x: 21, y: 20},{ x: 22, y: 19},{ x: 23, y: 15},{ x: 24, y: 12},
+						{ x: 25, y: 24},{ x: 26, y: 20},{ x: 27, y: 20},{ x: 28, y: 26},{ x: 29, y: 28},{ x: 30, y: 26},{ x: 31, y: 28},{ x: 32, y: 29},{ x: 33, y: 24},{ x: 34, y: 29},
+						{ x: 35, y: 31},{ x: 36, y: 35},{ x: 37, y: 37},{ x: 38, y: 31},{ x: 39, y: 35},{ x: 40, y: 37},{ x: 41, y: 37},{ x: 42, y: 36},{ x: 43, y: 31},{ x: 44, y: 30},
+						{ x: 45, y: 50},{ x: 46, y: 49},{ x: 47, y: 42},{ x: 48, y: 46},{ x: 49, y: 44},{ x: 50, y: 40},{ x: 51, y: 47},{ x: 52, y: 43},{ x: 53, y: 48},{ x: 54, y: 47},
+						{ x: 55, y: 51},{ x: 56, y: 52},{ x: 57, y: 52},{ x: 58, y: 51},{ x: 59, y: 54},{ x: 60, y: 57},{ x: 61, y: 58},{ x: 62, y: 50},{ x: 63, y: 54},{ x: 64, y: 51},
+						{ x: 65, y: 62},{ x: 66, y: 68},{ x: 67, y: 67},{ x: 68, y: 62},{ x: 69, y: 62},{ x: 70, y: 65},{ x: 71, y: 61},{ x: 72, y: 66},{ x: 73, y: 65},{ x: 74, y: 62},
+						{ x: 75, y: 74},{ x: 76, y: 78},{ x: 77, y: 78},{ x: 78, y: 77},{ x: 79, y: 74},{ x: 80, y: 74},{ x: 81, y: 72},{ x: 82, y: 74},{ x: 83, y: 70},{ x: 84, y: 78},
+						{ x: 85, y: 84},{ x: 86, y: 83},{ x: 87, y: 85},{ x: 88, y: 86},{ x: 89, y: 86},{ x: 90, y: 89},{ x: 91, y: 89},{ x: 92, y: 85},{ x: 93, y: 86},{ x: 94, y: 86},
+						{ x: 95, y: 98},{ x: 96, y: 97},{ x: 97, y: 93},{ x: 98, y: 91},{ x: 99, y: 92},{ x: 100, y: 92}
+					]);
+					new MouseZoomAndPan(chart, "default", { axis: "x", enableScroll: false });
+					var i = MouseIndicator(chart, "default", { series: "Series A",
+						font: "normal normal bold 12pt Tahoma",	fillFunc: function(v){
+								return v.y>55?"green":"red";
+							}, 	labelFunc: function(v){
+								return "x: "+v.x+", y:"+v.y;
+							}});
+					on(i, "Change", function(evt){
+						if(evt.label){
+							console.log(evt.label+" ("+evt.start.x+", "+evt.start.y+")");
+						}
+					});
+					chart.render();
+				})
+			});
 		</script>
 	</head>
 	<body class="tundra" style="height:100%;width:100%">
diff --git a/dojox/charting/tests/test_mouseZoomAndPan.html b/dojox/charting/tests/test_mouseZoomAndPan.html
index b48edca..ad1e6ab 100644
--- a/dojox/charting/tests/test_mouseZoomAndPan.html
+++ b/dojox/charting/tests/test_mouseZoomAndPan.html
@@ -20,7 +20,7 @@
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dijit/themes/tundra/tundra.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("dojox.charting.Chart");
@@ -33,11 +33,11 @@
 			makeObjects = function(){
 				chart = new dojox.charting.Chart("chart");
 				chart.setTheme(dojox.charting.themes.PlotKit.orange);
-				chart.addAxis("x", {type : "Default", fixLower: "minor", natural: true, stroke: "grey", enableCache: true, 
+				chart.addAxis("x", {type : "Default", fixLower: "minor", natural: true, stroke: "gray", enableCache: true,
 									htmlLabels: false, majorTick: {color: "red", length: 4}, minorTick: {color: "blue", length: 2}});
-				chart.addAxis("alternate", {type : "Default", fixLower: "minor", natural: true, stroke: "grey", enableCache: true,
+				chart.addAxis("alternate", {type : "Default", fixLower: "minor", natural: true, stroke: "gray", enableCache: true,
 					htmlLabels: false, majorTick: {color: "red", length: 4}, minorTick: {color: "blue", length: 2}, leftBottom: false});
-				chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 10, minorTickStep: 5, stroke: "grey",
+				chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 10, minorTickStep: 5, stroke: "gray",
 					majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
 				chart.addPlot("default", {type: "Default", markers: false});
 				chart.addPlot("second", {type: "Default", markers: false, hAxis:"alternate"});
diff --git a/dojox/charting/tests/test_nulls.html b/dojox/charting/tests/test_nulls.html
index d2c8ffd..65df525 100644
--- a/dojox/charting/tests/test_nulls.html
+++ b/dojox/charting/tests/test_nulls.html
@@ -20,7 +20,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script>
 
 dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_pie2d.html b/dojox/charting/tests/test_pie2d.html
index 6142bf4..6e0d339 100644
--- a/dojox/charting/tests/test_pie2d.html
+++ b/dojox/charting/tests/test_pie2d.html
@@ -20,7 +20,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_pie2d_5050.html b/dojox/charting/tests/test_pie2d_5050.html
new file mode 100644
index 0000000..452fa70
--- /dev/null
+++ b/dojox/charting/tests/test_pie2d_5050.html
@@ -0,0 +1,67 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Pie 2D</title>
+<style type="text/css">
+	@import "../../../dojo/resources/dojo.css";
+	@import "../../../dijit/tests/css/dijitTests.css";
+</style>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
+<script type="text/javascript">
+
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.widget.Legend");
+dojo.require("dojox.charting.plot2d.Pie");
+dojo.require("dojox.charting.themes.PlotKit.blue");
+dojo.require("dojox.charting.themes.PlotKit.green");
+dojo.require("dojox.charting.themes.PlotKit.red");
+dojo.require("dojox.charting.themes.Adobebricks");
+dojo.require("dojox.charting.themes.Algae");
+
+makeObjects = function(){
+	var chart1 = new dojox.charting.Chart("test1");
+	chart1.setTheme(dojox.charting.themes.PlotKit.blue);
+	chart1.addPlot("default", {
+		type: "Pie",
+		font: "normal normal bold 12pt Tahoma",
+		fontColor: "blue",
+		radius: 70,
+		labelOffset: 5,
+		labelStyle: "columns",
+		labelWiring: "ccc"
+	});
+	chart1.addSeries("Series A", [4, 4]);
+	chart1.render();
+	
+	var legend = new dojox.charting.widget.Legend({
+        	            chart: chart1,
+							horizontal:false
+                	}, "legend");
+};
+
+dojo.addOnLoad(makeObjects);
+
+</script>
+</head>
+<body>
+<h1>Pie</h1>
+<p>Pie with 2 50% slices</p>
+<div id="test1" style="width: 300px; height: 300px;"></div>
+<div id="legend"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/test_pie2d_zeroslice.html b/dojox/charting/tests/test_pie2d_zeroslice.html
index 3b3d20e..1199385 100644
--- a/dojox/charting/tests/test_pie2d_zeroslice.html
+++ b/dojox/charting/tests/test_pie2d_zeroslice.html
@@ -20,7 +20,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_pie_omitLabels.html b/dojox/charting/tests/test_pie_omitLabels.html
new file mode 100644
index 0000000..1912898
--- /dev/null
+++ b/dojox/charting/tests/test_pie_omitLabels.html
@@ -0,0 +1,74 @@
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if !(IE 8)]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+	<![endif]>
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true"></script>
+	</head>
+	
+	<body>
+		<script type="text/javascript">
+	    dojo.require("dojox.charting.Chart2D");
+	    dojo.require("dojox.charting.themes.PrimaryColors");
+	
+	    var chartData = [10000,1,10000,1,10000,1];
+	    dojo.ready(function() {
+	        var pieChart1 = new dojox.charting.Chart2D("chartNode1");
+	        pieChart1.setTheme(dojox.charting.themes.PrimaryColors);
+	        pieChart1.addPlot("default", {
+	            type:       "Pie",
+	            omitLabels: true,
+	            radius:     100
+	        });
+	        pieChart1.addSeries("test",chartData);
+	        pieChart1.render();
+	        
+	        var pieChart2 = new dojox.charting.Chart2D("chartNode2");
+	        pieChart2.setTheme(dojox.charting.themes.PrimaryColors);
+	        pieChart2.addPlot("default", {
+	            type:       "Pie",
+	            radius:     100
+	        });
+	        pieChart2.addSeries("test",chartData);
+	        pieChart2.render();
+	        
+	        var pieChart3 = new dojox.charting.Chart2D("chartNode3");
+	        pieChart3.setTheme(dojox.charting.themes.PrimaryColors);
+	        pieChart3.addPlot("default", {
+	            type:       "Pie",
+	        	labelStyle: "columns",
+	        	omitLabels: true,
+	        	radius:     100
+	        });
+	        pieChart3.addSeries("test",chartData);
+	        pieChart3.render();
+	        
+	        var pieChart4 = new dojox.charting.Chart2D("chartNode4");
+	        pieChart4.setTheme(dojox.charting.themes.PrimaryColors);
+	        pieChart4.addPlot("default", {
+	            type:       "Pie",
+	        	labelStyle: "columns",
+	        	radius:     100
+	        });
+	        pieChart4.addSeries("test",chartData);
+	        pieChart4.render();
+	    });
+	    </script>
+		<p>Omit true</p>
+		<div id="chartNode1" style="width: 400px; height: 300px;"></div>
+		<p>Omit false<p>
+		<div id="chartNode2" style="width: 400px; height: 300px;"></div>
+		<p>Omit true</p>
+		<div id="chartNode3" style="width: 400px; height: 300px;"></div>
+		<p>Omit false</p>
+		<div id="chartNode4" style="width: 400px; height: 300px;"></div>
+	
+	</body>
+</html>
diff --git a/dojox/charting/tests/test_pie_smart_label.html b/dojox/charting/tests/test_pie_smart_label.html
index 0521aac..51208ce 100644
--- a/dojox/charting/tests/test_pie_smart_label.html
+++ b/dojox/charting/tests/test_pie_smart_label.html
@@ -22,13 +22,11 @@
 			@import "../../../dijit/themes/claro/claro.css";
 			@import "../resources/Legend.css";
         </style>
-        <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:true">
+        <script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true">
         </script>
         <script type="text/javascript">
             dojo.require("dojox.charting.Chart");
             dojo.require("dojox.charting.plot2d.Pie");
-            dojo.require("dojox.charting.action2d.Highlight");
-            dojo.require("dojox.charting.action2d.MoveSlice");
             dojo.require("dojox.charting.action2d.Tooltip");
 			dojo.require("dojox.charting.themes.Tom");
             dojo.require("dojox.charting.widget.Legend");
@@ -112,7 +110,6 @@
                     text: "Egypt",
                     tooltip: "64 million"
                 }]);
-                var anim_b = new dc.action2d.Highlight(pieChart, "default");
                 var anim_c = new dc.action2d.Tooltip(pieChart, "default");
                 pieChart.render();
                 legend = new dojox.charting.widget.Legend({
diff --git a/dojox/charting/tests/test_plot_order.html b/dojox/charting/tests/test_plot_order.html
index a56ebbe..7b11b64 100644
--- a/dojox/charting/tests/test_plot_order.html
+++ b/dojox/charting/tests/test_plot_order.html
@@ -22,7 +22,7 @@
 	@import "../../../dojo/tests/dnd/dndDefault.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script>
 
 dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_rotatedLabels.html b/dojox/charting/tests/test_rotatedLabels.html
index 063f177..934e4ad 100644
--- a/dojox/charting/tests/test_rotatedLabels.html
+++ b/dojox/charting/tests/test_rotatedLabels.html
@@ -21,7 +21,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 	@import "../../../dijit/themes/tundra/tundra.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 
 dojo.require("dijit.form.Button");
diff --git a/dojox/charting/tests/test_scaler.html b/dojox/charting/tests/test_scaler.html
index 5402d33..66b43b6 100644
--- a/dojox/charting/tests/test_scaler.html
+++ b/dojox/charting/tests/test_scaler.html
@@ -20,7 +20,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.scaler.linear");
diff --git a/dojox/charting/tests/test_selectableLegend.html b/dojox/charting/tests/test_selectableLegend.html
index b3828a5..3e6f0cf 100644
--- a/dojox/charting/tests/test_selectableLegend.html
+++ b/dojox/charting/tests/test_selectableLegend.html
@@ -41,7 +41,7 @@
 			}
         </style>
 
-        <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+        <script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
         <script type="text/javascript">
             dojo.require("dijit.dijit");
             dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_series_order.html b/dojox/charting/tests/test_series_order.html
index c3cbfd3..860a24c 100644
--- a/dojox/charting/tests/test_series_order.html
+++ b/dojox/charting/tests/test_series_order.html
@@ -22,7 +22,7 @@
 	@import "../../../dojo/tests/dnd/dndDefault.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script>
 
 dojo.require("dojox.charting.Chart");
diff --git a/dojox/charting/tests/test_shadow.html b/dojox/charting/tests/test_shadow.html
new file mode 100644
index 0000000..6bb915f
--- /dev/null
+++ b/dojox/charting/tests/test_shadow.html
@@ -0,0 +1,95 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>Shadows</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<!-- required for Tooltip: a default dijit theme: -->
+		<link rel="stylesheet" href="../../../dijit/themes/tundra/tundra.css">
+		<style>
+			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
+			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript">
+			var seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
+			require([
+			"dojox/charting/widget/Chart",
+			"dojox/charting/axis2d/Default",
+			"dojox/charting/plot2d/Columns",
+			"dojox/charting/plot2d/Bars",
+			"dojox/charting/plot2d/Default",
+			"dojox/charting/plot2d/Pie",
+			"dojox/charting/action2d/Shake",
+			"dojox/charting/themes/PlotKit/orange",
+			"dojox/charting/themes/PlotKit/blue",
+			"dojox/charting/themes/PlotKit/green",
+			"dojo/parser"]);
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Shadows</h1>
+		<p>Testing charts shadows</p>
+		<table border="0" cellspacing="30">
+			<tr>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart1" style="width: 300px; height: 300px;">
+						<div class="axis" name="y" font="italic normal normal 8pt Tahoma" natural="true" fixLower="major" fixUpper="major"></div>
+						<div class="axis" name="x" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Bars" fill="'red'" stroke="null" shadow="{dx: 2, dy: 2, width: 2, color: [ 150, 0, 0, 0.7 ]}" gap="5" animate="true"></div>
+						<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+						<div class="action" type="Shake"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart2" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma" natural="true" fixLower="major" fixUpper="major"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Columns" fill="'red'" stroke="null" shadow="{dx: 2, dy: 2, width: 2, color: [ 150, 0, 0, 0.7 ]}" gap="5" animate="true"></div>
+						<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+						<div class="action" type="Shake"></div>
+					</div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart3" theme="dojox.charting.themes.PlotKit.blue"
+							 style="width: 300px; height: 300px;">
+						<div class="plot" name="default" type="Pie" radius="100" fontColor="white" shadow="{dx: 3, dy: 3, width: 3, color: [ 0, 0, 0, 0.3 ]}" animate="true"></div>
+						<div class="series" name="Series B" array="seriesB"></div>
+						<div class="action" type="Shake"></div>
+					</div>
+				</td>
+				<td>
+					<div data-dojo-type="dojox.charting.widget.Chart" id="chart4" style="width: 300px; height: 300px;">
+						<div class="axis" name="x" font="italic normal normal 8pt Tahoma" natural="true" fixLower="major" fixUpper="major"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
+							font="italic normal normal 8pt Tahoma"></div>
+						<div class="plot" name="default" type="Default" stroke="{width: 4, color: 'red'}" shadow="{dx: 2, dy: 2, width:3,  color: [ 0, 0, 0, 0.3 ]}" animate="true"></div>
+						<div class="series" name="Run A" data="1, 2, 0.5, 1.5, 1, 2.8, 0.4"></div>
+					</div>
+				</td>
+			</tr>
+		</table>
+		<p>That's all Folks!</p>
+	</body>
+</html>
diff --git a/dojox/charting/tests/test_sparklines.html b/dojox/charting/tests/test_sparklines.html
index 6341da4..5e8eacc 100644
--- a/dojox/charting/tests/test_sparklines.html
+++ b/dojox/charting/tests/test_sparklines.html
@@ -26,7 +26,7 @@
 			}
 		</style>
 		<script type="text/javascript" src="../../../dojo/dojo.js" 
-			djConfig="isDebug: false, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: false, parseOnLoad: true"></script>
 		<script type="text/javascript">
             dojo.require("dojox.charting.plot2d.Lines");
             dojo.require("dojox.charting.plot2d.Areas");
@@ -44,7 +44,7 @@
 		<p><em>This is a particularly brutal example with <strong>lots and lots</strong> of data. 
 			It may cause laggyness in lesser browsers.</em></p>
 		
-		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" jsId="tableStore"></div>
+		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" data-dojo-id="tableStore"></div>
 		<table id="tableExample" style="display: none;">
 			<thead>
 				<tr><th>value</th></tr>
@@ -84,7 +84,7 @@
 				</td>
 				<td>
 
-					<div dojoType="dojox.data.CsvStore" jsId="googStore" 
+					<div dojoType="dojox.data.CsvStore" data-dojo-id="googStore"
 						url="data/goog_prices.csv"></div>
 					<div dojoType="dojox.charting.widget.Chart" 
 						theme="dojox.charting.themes.Tufte" 
@@ -123,7 +123,7 @@
 				</td>
 				<td>
 
-					<div dojoType="dojox.data.CsvStore" jsId="yahooStore" 
+					<div dojoType="dojox.data.CsvStore" data-dojo-id="yahooStore"
 						url="data/yahoo_prices.csv"></div>
 					<div dojoType="dojox.charting.widget.Chart" 
 						theme="dojox.charting.themes.Tufte" 
@@ -160,7 +160,7 @@
 					<a href="http://finance.google.com/finance?q=Microsoft">Microsoft</a> Closing Price & <span class="volume">Volume</span>:
 				</td>
 				<td>
-					<div dojoType="dojox.data.CsvStore" jsId="msftStore" 
+					<div dojoType="dojox.data.CsvStore" data-dojo-id="msftStore"
 						url="data/msft_prices.csv"></div>
 					<div dojoType="dojox.charting.widget.Chart" 
 						theme="dojox.charting.themes.Tufte" 
diff --git a/dojox/charting/tests/test_spider2d.html b/dojox/charting/tests/test_spider2d.html
index e549cdc..55fc318 100644
--- a/dojox/charting/tests/test_spider2d.html
+++ b/dojox/charting/tests/test_spider2d.html
@@ -53,75 +53,39 @@
 		padding: 1px 3px 0 3px;
 	}
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
-	dojo.require("dojox.charting.Chart");
-	dojo.require("dojox.charting.plot2d.Spider");
-	dojo.require("dojox.charting.themes.PlotKit.blue");
-	dojo.require("dijit.Tooltip");
-	dojo.require("dijit.form.CheckBox");
-	dojo.require("dijit.form.RadioButton");
-	dojo.require("dijit.form.Form");
-	dojo.require("dojo.fx.easing");
-	dojo.require("dojox.gfx.fx");
-	dojo.require("dojox.charting.widget.SelectableLegend");
-	
-	var dc = dojox.charting,
-		divisions = 7,
+	var switchData, switchSpider, switchDivisions, switchAnimation;
+
+	require(["dojo/_base/kernel", "dojo/dom", "dojo/dom-construct", "dojo/ready", "dojox/charting/Chart", "dojox/charting/plot2d/Spider", "dojox/charting/themes/PlotKit/blue",
+		"dojox/charting/action2d/Tooltip", "dojox/charting/action2d/Highlight", "dojox/charting/action2d/Magnify",
+		"dijit/form/CheckBox", "dijit/form/RadioButton", "dijit/form/Form", "dojox/charting/widget/SelectableLegend",
+		"dojo/fx/easing"],
+			function(kernel, dom, domConstruct, ready, Chart, Spider, blue, Tooltip, Highlight, Magnify, CheckBox,
+					 RadioButton, Form, SelectableLegend, easing){
+
+	var divisions = 7,
 		stype = "polygon",
-		easing = dojo.fx.easing.backOut;
+		easing = easing.backOut;
 	var empty = {};
     var populateSelect = function(from, select){
-        var module = dojo.getObject(from);
+        var module = kernel.getObject(from);
         for(var name in module){
             if(name in empty){ continue; }
             var fun = module[name];
-            if(dojo.isFunction(fun)){
-                dojo.create("option", {
-                    value:     from + "." + name,
-                    selected:  name == "backOut",
-                    innerHTML: from + "." + name
-                }, select);
+            if(kernel.isFunction(fun)){
+				domConstruct.create("option", {
+					value:     from + "." + name,
+					selected:  name == "backOut",
+					innerHTML: from + "." + name
+				}, select);
+			}
             }
         }
-    };
-	
-	var chart1, legend1;
-	makeObjects = function(){
-		chart1 = new dojox.charting.Chart("test1");
-		chart1.setTheme(dojox.charting.themes.PlotKit.blue);
-		chart1.addPlot("default", {
-			type: "Spider",
-			labelOffset: -10,
-			divisions: divisions,
-			axisColor:      "lightgray",
-			spiderColor:    "silver",
-            seriesFillAlpha: 0.2,
-			spiderOrigin:	 0.16,
-			markerSize:  	 3,
-			precision:		 0,
-			spiderType:	 	 stype
-		});
-		chart1.addSeries("China", {data: {"GDP": 2,"area": 6,"population": 2000,"inflation": 15,"growth": 12}}, { fill: "blue" });
-		chart1.addSeries("France", {data: {"GDP": 6,"area": 15,"population": 500,"inflation": 5,"growth": 6}}, { fill: "red" });
-		chart1.addSeries("USA", {data: {"GDP": 3,"area": 20,"population": 1500,"inflation": 10,"growth": 3}}, { fill: "green" });
-		chart1.addSeries("Japan", {data: {"GDP": 4,"area": 2,"population": 1000,"inflation": 20,"growth": 2}}, { fill: "yellow" });
-		chart1.addSeries("Korean", {data: {"GDP": 10,"area": 10,"population": 800,"inflation": 2,"growth": 18}}, { fill: "orange" });
-		chart1.addSeries("Canada", {data: {"GDP": 1,"area": 18,"population": 300,"inflation": 3,"growth": 15}}, { fill: "purple" });
-		chart1.render();
-		
-		legend1 = new dc.widget.SelectableLegend({chart: chart1, horizontal: true}, "legend1");
-		
-		// prepare and enable controls
-        populateSelect("dojo.fx.easing", "easing");
-	};
-	
-	dojo.addOnLoad(makeObjects);
 
-</script>
+	var chart1, legend1;
 
-<script type="text/javascript">
-	function switchData(val){
+	switchData = function(val){
 		if(val == "b1"){
 			chart1.updateSeries("China", {data: {"GDP": 2,"area": 6,"population": 2000,"inflation": 15,"growth": 12}}, { fill: "blue" });
 			chart1.updateSeries("France", {data: {"GDP": 6,"area": 15,"population": 500,"inflation": 5,"growth": 6}}, { fill: "red" });
@@ -141,10 +105,7 @@
 		legend1 && legend1.refresh && legend1.refresh();
 	}
 
-</script>
-
-<script type="text/javascript">
-	function switchSpider(val){
+	switchSpider = function(val){
 		stype = document.getElementById("b11").checked ? "polygon" : "circle";
 		if(val == "b11"){
 			chart1.addPlot("default", {
@@ -163,10 +124,7 @@
 		legend1 && legend1.refresh && legend1.refresh();
 	}
 
-</script>
-
-<script type="text/javascript">
-	function switchDivisions(val){
+	switchDivisions = function(val){
 		if(val == "b111"){
 			divisions = 7;
 			chart1.addPlot("default", {
@@ -186,10 +144,8 @@
 		legend1 && legend1.refresh && legend1.refresh();
 	}
 
-</script>
-<script type="text/javascript">
-	function switchAnimation(val){
-		easing = dojo.getObject(dojo.byId("easing").value);
+	switchAnimation = function(val){
+		easing = kernel.getObject(dom.byId("easing").value);
 		chart1.addPlot("default", {
 			type: "Spider",
 			divisions: 		divisions,
@@ -200,6 +156,42 @@
 		legend1 && legend1.refresh && legend1.refresh();
 	}
 
+	ready(function(){
+		chart1 = new Chart("test1");
+		chart1.setTheme(blue);
+		chart1.addPlot("default", {
+			type: Spider,
+			labelOffset: -10,
+			divisions: divisions,
+			axisColor:      "lightgray",
+			spiderColor:    "silver",
+            seriesFillAlpha: 0.2,
+			spiderOrigin:	 0.16,
+			markerSize:  	 3,
+			precision:		 0,
+			spiderType:	 	 stype
+		});
+		chart1.addSeries("China", {data: {"GDP": 2,"area": 6,"population": 2000,"inflation": 15,"growth": 12}}, { fill: "blue" });
+		chart1.addSeries("France", {data: {"GDP": 6,"area": 15,"population": 500,"inflation": 5,"growth": 6}}, { fill: "red" });
+		chart1.addSeries("USA", {data: {"GDP": 3,"area": 20,"population": 1500,"inflation": 10,"growth": 3}}, { fill: "green" });
+		chart1.addSeries("Japan", {data: {"GDP": 4,"area": 2,"population": 1000,"inflation": 20,"growth": 2}}, { fill: "yellow" });
+		chart1.addSeries("Korean", {data: {"GDP": 10,"area": 10,"population": 800,"inflation": 2,"growth": 18}}, { fill: "orange" });
+		chart1.addSeries("Canada", {data: {"GDP": 1,"area": 18,"population": 300,"inflation": 3,"growth": 15}}, { fill: "purple" });
+		new Tooltip(chart1);
+		new Highlight(chart1);
+		new Magnify(chart1, "default", {duration: 800, scale: 1.5});
+		chart1.render();
+		
+		legend1 = new SelectableLegend({chart: chart1, horizontal: true}, "legend1");
+		
+		// prepare and enable controls
+        populateSelect("dojo.fx.easing", "easing");
+	});
+});
+</script>
+
+<script type="text/javascript">
+
 </script>
 
 </head>
diff --git a/dojox/charting/tests/test_spidersingle.html b/dojox/charting/tests/test_spidersingle.html
new file mode 100644
index 0000000..7a982ff
--- /dev/null
+++ b/dojox/charting/tests/test_spidersingle.html
@@ -0,0 +1,62 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Test a Spider Chart with a single series</title>
+<style type="text/css">
+	@import "../../../dojo/resources/dojo.css";
+	@import "../../../dijit/themes/claro/claro.css";
+</style>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
+<script type="text/javascript">
+require(["dojo/ready", "dojox/charting/Chart", "dojox/charting/plot2d/Spider", "dojox/charting/themes/PlotKit/blue",
+		"dijit/Tooltip", "dojox/charting/axis2d/Base"], function(ready, Chart, Spider, blue, Tooltip, Base){
+	ready(function(){
+		var chart = new Chart("test");
+		chart.setTheme(blue);
+		chart.addPlot("default", {
+			type: Spider,
+			labelOffset: -10,
+			axisColor:      "lightgray",
+			spiderColor:    "silver",
+            seriesFillAlpha: 0.2,
+			spiderOrigin:	 0.16,
+			markerSize:  	 3,
+			precision:		 0
+		});
+		var data= [ {"Sales":73,"Marketing":226,"Development":125,"Administration":135,"Support":105},
+				    {"Sales":73,"Marketing":206,"Development":155,"Administration":235,"Support":87},
+				    {"Sales":53,"Marketing":326,"Development":225,"Administration":145,"Support":55} ];
+
+		// we define several axis (optional step for the general case)
+		chart.addAxis("Sales", { type: Base, min: 0, max: 100 });
+		chart.addAxis("Marketing", { type: Base, min: 100, max: 400});
+		chart.addAxis("Development", { type: Base, min: 0, max: 250 });
+		chart.addAxis("Administration", { type: Base, min: 0, max: 250});
+		chart.addAxis("Support", { type: Base, min: 0, max:150 });
+
+		// we add a single series, without axis definitions we won't be able to compute data axis min/max
+		chart.addSeries("China", {data: data[0] }, { fill: "blue" });
+
+		chart.render();
+	});
+});
+</script>
+</head>
+<body class="claro">
+<div id="test" style="width: 500px; height: 500px;"></div>
+</body>
+</html>
\ No newline at end of file
diff --git a/dojox/charting/tests/test_stacked.html b/dojox/charting/tests/test_stacked.html
new file mode 100644
index 0000000..6a1e471
--- /dev/null
+++ b/dojox/charting/tests/test_stacked.html
@@ -0,0 +1,170 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+<link rel="stylesheet" href="../../../dijit/themes/tundra/tundra.css">
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true"></script>
+<script type="text/javascript">
+
+require(["dojo/ready","dojox/charting/Chart", "dojox/charting/widget/Legend", "dojox/charting/axis2d/Default",
+	"dojox/charting/plot2d/StackedAreas", "dojox/charting/plot2d/StackedLines", "dojox/charting/plot2d/StackedColumns",
+	"dojox/charting/plot2d/StackedBars"],
+	function(ready, Chart, Legend, Default, StackedAreas, StackedLines, StackedColumns, StackedBars){
+
+	ready(function(){
+		// StackedAreas, array of objects
+		var chart1 = new Chart("StackedAreas_objects");
+		chart1.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart1.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart1.addPlot("default", {type: StackedAreas, gap: 5});
+		chart1.addSeries("Series A", [{y:1}, {y:2}, {y:3}, {y:4}, {y:5}], {stroke: {color: "black"}, fill: "red"});
+		chart1.addSeries("Series B", [{y:5}, {y:4}, {y:3}, {y:2}, {y:1}], {stroke: {color: "black"}, fill: "blue"});
+		chart1.render();
+		new Legend({chart: chart1, horizontal: true}, "StackedAreas_objects_l");
+	
+		// StackedLines, array of objects
+		var chart2 = new Chart("StackedLines_objects");
+		chart2.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart2.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart2.addPlot("default", {type: StackedLines, gap: 5});
+		chart2.addSeries("Series A", [{y:1}, {y:2}, {y:3}, {y:4}, {y:5}], {stroke: {color: "red"}});
+		chart2.addSeries("Series B", [{y:5}, {y:4}, {y:3}, {y:2}, {y:1}], {stroke: {color: "blue"}});
+		chart2.render();
+		new Legend({chart: chart2, horizontal: true}, "StackedLines_objects_l");
+
+		// StackedColumns, array of objects
+		var chart3 = new Chart("StackedColumns_objects");
+		chart3.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart3.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart3.addPlot("default", {type: StackedColumns, gap: 5});
+		chart3.addSeries("Series A", [{y:1}, {y:2}, {y:3}, {y:4}, {y:5}], {fill: "red"});
+		chart3.addSeries("Series B", [{y:5}, {y:4}, {y:3}, {y:2}, {y:1}], {fill: "blue"});
+		chart3.render();
+		new Legend({chart: chart3, horizontal: true}, "StackedColumns_objects_l");
+
+		// StackedBars, array of objects
+		var chart7 = new Chart("StackedBars_objects");
+		chart7.addAxis("y", {fixLower: "major", fixUpper: "major", includeZero: true});
+		chart7.addAxis("x", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true});
+		chart7.addPlot("default", {type: StackedBars, gap: 5});
+		chart7.addSeries("Series A", [{y:1}, {y:2}, {y:3}, {y:4}, {y:5}], {fill: "red"});
+		chart7.addSeries("Series B", [{y:5}, {y:4}, {y:3}, {y:2}, {y:1}], {fill: "blue"});
+		chart7.render();
+		new Legend({chart: chart7, horizontal: true}, "StackedBars_objects_l");
+	
+		// StackedAreas, array of numbers
+		var chart4 = new Chart("StackedAreas_numbers");
+		chart4.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart4.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart4.addPlot("default", {type: StackedAreas, gap: 5});
+		chart4.addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "black"}, fill: "red"});
+		chart4.addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "black"}, fill: "blue"});
+		chart4.render();
+		new Legend({chart: chart4, horizontal: true}, "StackedAreas_numbers_l");
+	
+		// StackedLines, array of numbers
+		var chart5 = new Chart("StackedLines_numbers");
+		chart5.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart5.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart5.addPlot("default", {type: StackedLines, gap: 5});
+		chart5.addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "red"}});
+		chart5.addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}});
+		chart5.render();
+		new Legend({chart: chart5, horizontal: true}, "StackedLines_numbers_l");
+
+		// StackedColumns, array of numbers
+		var chart6 = new Chart("StackedColumns_numbers");
+		chart6.addAxis("x", {fixLower: "major", fixUpper: "major"});
+		chart6.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true, includeZero: true});
+		chart6.addPlot("default", {type: StackedColumns, gap: 5});
+		chart6.addSeries("Series A", [1, 2, 3, 4, 5], {fill: "red"});
+		chart6.addSeries("Series B", [5, 4, 3, 2, 1], {fill: "blue"});
+		chart6.render();
+		new Legend({chart: chart6, horizontal: true}, "StackedColumns_numbers_l");
+
+		// StackedBars, array of numbers
+		var chart8 = new Chart("StackedBars_numbers");
+		chart8.addAxis("y", {fixLower: "major", fixUpper: "major", includeZero: true});
+		chart8.addAxis("x", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true});
+		chart8.addPlot("default", {type: StackedBars, gap: 5});
+		chart8.addSeries("Series A", [1, 2, 3, 4, 5], {fill: "red"});
+		chart8.addSeries("Series B", [5, 4, 3, 2, 1], {fill: "blue"});
+		chart8.render();
+		new Legend({chart: chart8, horizontal: true}, "StackedBars_numbers_l");
+	});
+});
+</script>
+</head>
+<body class="tundra">
+<table>
+<tr>
+	<td>StackedAreas, array of objects</td>
+	<td>StackedAreas, array of numbers</td>
+</tr>
+<tr>
+	<td>
+	<div id="StackedAreas_objects" style="width: 400px; height: 200px;"></div>
+	<div id="StackedAreas_objects_l"></div>
+	</td>
+	<td>
+	<div id="StackedAreas_numbers" style="width: 400px; height: 200px;"></div>
+	<div id="StackedAreas_numbers_l"></div>
+	</td>
+</tr>
+<tr>
+	<td>StackedLines, array of objects</td>
+	<td>StackedLines, array of numbers</td>
+</tr>
+<tr>
+	<td>
+	<div id="StackedLines_objects" style="width: 400px; height: 200px;"></div>
+	<div id="StackedLines_objects_l"></div>
+	</td>
+	<td>
+	<div id="StackedLines_numbers" style="width: 400px; height: 200px;"></div>
+	<div id="StackedLines_numbers_l"></div>
+	</td>
+</tr>
+<tr>
+	<td>StackedColumns, array of objects</td>
+	<td>StackedColumns, array of numbers</td>
+</tr>
+<tr>
+	<td>
+	<div id="StackedColumns_objects" style="width: 400px; height: 200px;"></div>
+	<div id="StackedColumns_objects_l"></div>
+	</td>
+	<td>
+	<div id="StackedColumns_numbers" style="width: 400px; height: 200px;"></div>
+	<div id="StackedColumns_numbers_l"></div>
+	</td>
+</tr>
+<tr>
+	<td>StackedBars, array of objects</td>
+	<td>StackedBars, array of numbers</td>
+</tr>
+<tr>
+	<td>
+	<div id="StackedBars_objects" style="width: 400px; height: 200px;"></div>
+	<div id="StackedBars_objects_l"></div>
+	</td>
+	<td>
+	<div id="StackedBars_numbers" style="width: 400px; height: 200px;"></div>
+	<div id="StackedBars_numbers_l"></div>
+	</td>
+</tr>
+</table>
+</body>
+</html>
diff --git a/dojox/charting/tests/test_tension.html b/dojox/charting/tests/test_tension.html
index 3f95b68..e3e1fe5 100644
--- a/dojox/charting/tests/test_tension.html
+++ b/dojox/charting/tests/test_tension.html
@@ -25,9 +25,10 @@
         .dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
         .dojoxLegendText {vertical-align: text-top; padding-right: 10px}
     </style>
-    <script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+    <script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script>
         dojo.require("dojox.charting.Chart");
+		dojo.require("dojox.charting.Theme");
         dojo.require("dojox.charting.axis2d.Default");
         dojo.require("dojox.charting.plot2d.Default");
         dojo.require("dojox.charting.widget.Legend");
diff --git a/dojox/charting/tests/test_themes-amd.html b/dojox/charting/tests/test_themes-amd.html
index cab1ba7..6cbe009 100644
--- a/dojox/charting/tests/test_themes-amd.html
+++ b/dojox/charting/tests/test_themes-amd.html
@@ -4,7 +4,7 @@
 	<head>
 <![endif]-->
 <!--[if IE 8]>
-<!DOCTYPE>
+<!DOCTYPE HTML>
 <html lang="en">
     <head>
            <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
@@ -42,7 +42,10 @@
 	#candle, #columns, #ohlc {
 		top: 440px;
 	}
-
+	#candle svg,
+	#ohlc svg {
+		shape-rendering: crispEdges;
+	}
 </style>
 <script src="../../../dojo/dojo.js" data-dojo-config="isDebug: false, async: true, gfxRenderer: 'svg,silverlight,vml,canvas'"></script>
 <script>
diff --git a/dojox/charting/tests/test_themes.html b/dojox/charting/tests/test_themes.html
index b8ed78a..f92ca23 100644
--- a/dojox/charting/tests/test_themes.html
+++ b/dojox/charting/tests/test_themes.html
@@ -44,7 +44,7 @@
 	}
 
 </style>
-<script src="../../../dojo/dojo.js" djConfig="isDebug: false, gfxRenderer: 'svg,silverlight,vml,canvas'"></script>
+<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: false, gfxRenderer: 'svg,silverlight,vml,canvas'"></script>
 <script>
     dojo.require("dojox.charting.Chart");
     dojo.require("dojox.charting.axis2d.Default");
diff --git a/dojox/charting/tests/test_threshold.html b/dojox/charting/tests/test_threshold.html
new file mode 100644
index 0000000..c3a68ce
--- /dev/null
+++ b/dojox/charting/tests/test_threshold.html
@@ -0,0 +1,144 @@
+<!--[if IE 7]>
+<!DOCTYPE>
+<html lang="en">
+	<head>
+<![endif]-->
+<!--[if IE 8]>
+<!DOCTYPE>
+<html lang="en">
+    <head>
+           <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+<![endif]>
+		<title>Threshold Indicator</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/themes/tundra/tundra.css";
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js"
+			data-dojo-config="isDebug: true"></script>
+		<script type="text/javascript">
+			require(["dojo/ready", "dojox/charting/Chart", "dojox/charting/axis2d/Default", "dojox/charting/plot2d/Default",
+					 "dojox/charting/action2d/MouseZoomAndPan", "dojox/charting/plot2d/Indicator", "dojox/charting/action2d/PlotAction"],
+					function(ready, Chart, Axis, Plot, MouseZoomAndPan, Indicator, PlotAction){
+				ready(function(){
+					var chart = new Chart("chart", { margins : {l :20, t:30, b:10, r: 50} });
+					chart.addAxis("x", {
+						type : Axis,
+						font: "normal normal normal 14pt Tahoma",
+						fixLower : "minor",
+						natural : true,
+						stroke : "gray",
+						majorTick : {
+							color : "red",
+							length : 4
+						},
+						minorTick : {
+							color : "blue",
+							length : 2
+						}
+					});
+					chart.addAxis("y", {
+						vertical : true,
+						font: "normal normal normal 14pt Tahoma",
+						min : 0,
+						max : 100,
+						majorTickStep : 10,
+						minorTickStep : 5,
+						stroke : "gray",
+						majorTick : {
+							stroke : "black",
+							length : 4
+						},
+						minorTick : {
+							stroke : "gray",
+							length : 2
+						}
+					});
+					chart.addPlot("default", {
+						type : Plot
+					});
+					chart.addPlot("thresholdh", {
+						type: Indicator,
+						vertical: false,
+						lineStroke: { color: "red", style: "ShortDash"},
+						stroke: null,
+						outline: null,
+						fill: null,
+						offset: { y: -7, x: -10 },
+						values: 15
+					});
+					chart.addPlot("thresholdv", {
+						type: Indicator,
+						lineStroke: { color: "blue", style: "ShortDash"},
+						stroke: null,
+						outline: null,
+						fill: null,
+						offset: { y: -7, x: 0 },
+						values: 5
+					});
+					chart.addPlot("thresholdhb", {
+						type: Indicator,
+						vertical: false,
+						lineStroke: { color: "red", style: "ShortDash"},
+						stroke: null,
+						outline: null,
+						fill: null,
+						offset: { y: -7, x: 10 },
+						start: true,
+						values: [35]
+					});
+					chart.addPlot("thresholdvb", {
+						type: Indicator,
+						lineStroke: { color: "blue", style: "ShortDash"},
+						stroke: null,
+						outline: null,
+						fill: null,
+						start: true,
+						offset: { y: -7, x: -40 },
+						labels: "markers",
+						values: [20]
+					});
+					chart.addPlot("thresholdual", {
+						type: Indicator,
+						vertical: false,
+						lineStroke: { color: "blue", width: 2},
+						color: "red",
+						stroke: null,
+						outline: null,
+						fill: null,
+						offset: { y: -7, x: -10 },
+						lineFill: [0, 10, 50, 0.4],
+						values: [50, 90]
+					});
+					chart.addSeries("markers 1", [ 8, 17, 30 ], { plot: "thresholdvb" });
+					chart.addSeries("markers 2", [ 8, 17, 30 ], { plot: "thresholdhb" });
+					chart.addSeries("Series A", [ 8, 7, 3, 2, 5, 7, 9, 10, 2, 10, 14, 16,
+							29, 13, 16, 15, 20, 19, 15, 12, 24, 20, 20, 26, 28, 26, 28, 14,
+							24, 29, 31, 35, 37, 31, 35, 37, 37, 36, 31, 30, 50, 49, 42, 46,
+							44, 40, 47, 43, 48, 47, 51, 52, 52, 51, 54, 57, 58, 50, 54, 51,
+							74, 68, 67, 62, 62, 65, 61, 66, 65, 62, 74, 78, 78, 77, 74, 62,
+							72, 74, 70, 78, 84, 83, 85, 86, 86, 89, 89, 85, 86, 86, 98, 73,
+							93, 91, 92, 92, 99, 93, 94, 92 ]);
+					new MouseZoomAndPan(chart, "default", { axis: "x" });
+					var action = new PlotAction(chart, "thresholdh");
+					action.process = function(o){
+						if(o.type == "onclick"){
+							console.log("down on thresholdh");
+						}
+					};
+					action.connect();
+					chart.render();
+				});
+			})
+		</script>
+	</head>
+	<body class="tundra" style="height: 100%; width: 100%">
+		<div id="chart" style="width: 100%; height: 100%;"></div>
+	</body>
+</html>
diff --git a/dojox/charting/tests/test_touchIndicator.html b/dojox/charting/tests/test_touchIndicator.html
index 7ed067b..0b73862 100644
--- a/dojox/charting/tests/test_touchIndicator.html
+++ b/dojox/charting/tests/test_touchIndicator.html
@@ -18,11 +18,11 @@
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 		<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
-		
 		@import "../../../dijit/themes/tundra/tundra.css";
+		body { -ms-touch-action: none; }
 		</style>
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			
@@ -40,7 +40,7 @@
 					font: "normal normal normal 14pt Tahoma",
 					fixLower : "minor",
 					natural : true,
-					stroke : "grey",
+					stroke : "gray",
 					majorTick : {
 						color : "red",
 						length : 4
@@ -57,7 +57,7 @@
 					max : 100,
 					majorTickStep : 10,
 					minorTickStep : 5,
-					stroke : "grey",
+					stroke : "gray",
 					majorTick : {
 						stroke : "black",
 						length : 4
diff --git a/dojox/charting/tests/test_touchZoomAndPan.html b/dojox/charting/tests/test_touchZoomAndPan.html
index fb85165..817d84a 100644
--- a/dojox/charting/tests/test_touchZoomAndPan.html
+++ b/dojox/charting/tests/test_touchZoomAndPan.html
@@ -20,8 +20,9 @@
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dijit/themes/tundra/tundra.css";
+			body { -ms-touch-action: none; }
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.mobile.parser");
 
@@ -33,9 +34,9 @@
 			var chart;
 			makeObjects = function(){
 				chart = new dojox.charting.Chart("chart");
-				chart.addAxis("x", {type : "Default", fixLower: "minor", natural: true, stroke: "grey", enableCache: true,
+				chart.addAxis("x", {type : "Default", fixLower: "minor", natural: true, stroke: "gray", enableCache: true,
 					htmlLabels: false, majorTick: {color: "red", length: 4}, minorTick: {color: "blue", length: 2}});
-				chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 10, minorTickStep: 5, stroke: "grey",
+				chart.addAxis("y", {vertical: true, min: 0, max: 100, majorTickStep: 10, minorTickStep: 5, stroke: "gray",
 					majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
 				chart.addPlot("default", {type: "Default",markers: false, areas: true });
 				chart.addSeries("Series A", [
diff --git a/dojox/charting/tests/test_widget2d-amd.html b/dojox/charting/tests/test_widget2d-amd.html
index b51175c..3a813bc 100644
--- a/dojox/charting/tests/test_widget2d-amd.html
+++ b/dojox/charting/tests/test_widget2d-amd.html
@@ -49,7 +49,7 @@
 	<body class="tundra">
 		<h1>Chart 2D</h1>
 		<p>Examples of charts using widgets.</p>
-		<div data-dojo-type="dojox.data.HtmlStore" dataId="tableExample" jsId="tableStore"></div>
+		<div data-dojo-type="dojox.data.HtmlStore" dataId="tableExample" data-dojo-id="tableStore"></div>
 		<table id="tableExample" style="display: none;">
 			<thead>
 				<tr><th>value</th></tr>
@@ -83,8 +83,8 @@
 				<td>
 					<div data-dojo-type="dojox.charting.widget.Chart" id="chart2" theme="dojox.charting.themes.PlotKit.orange" 
 							fill="'lightgrey'" style="width: 300px; height: 300px;">
-						<div class="axis" name="x" font="italic normal bold 10pt Tahoma"></div>
-						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true" 
+						<div class="axis" name="x" font="italic normal bold 10pt Tahoma" minorLabels="false" labelSizeChange="true"></div>
+						<div class="axis" name="y" vertical="true" fixUpper="major" includeZero="true"
 							font="italic normal bold 10pt Tahoma"></div>
 						<div class="plot" name="default" type="Areas"></div>
 						<div class="plot" name="grid" type="Grid"></div>
diff --git a/dojox/charting/tests/test_widget2d.html b/dojox/charting/tests/test_widget2d.html
index 4252d13..d10a9dd 100644
--- a/dojox/charting/tests/test_widget2d.html
+++ b/dojox/charting/tests/test_widget2d.html
@@ -26,7 +26,7 @@
 			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
 			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.dijit");
@@ -53,7 +53,7 @@
 	<body class="tundra">
 		<h1>Chart 2D</h1>
 		<p>Examples of charts using widgets.</p>
-		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" jsId="tableStore"></div>
+		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" data-dojo-id="tableStore"></div>
 		<table id="tableExample" style="display: none;">
 			<thead>
 				<tr><th>value</th></tr>
diff --git a/dojox/charting/tests/test_widget2d_deprecated.html b/dojox/charting/tests/test_widget2d_deprecated.html
index 3274dee..094f619 100644
--- a/dojox/charting/tests/test_widget2d_deprecated.html
+++ b/dojox/charting/tests/test_widget2d_deprecated.html
@@ -26,7 +26,7 @@
 			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
 			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.dijit");
@@ -46,7 +46,7 @@
 	<body class="tundra">
 		<h1>Chart 2D</h1>
 		<p>Examples of charts using widgets.</p>
-		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" jsId="tableStore"></div>
+		<div dojoType="dojox.data.HtmlStore" dataId="tableExample" data-dojo-id="tableStore"></div>
 		<table id="tableExample" style="display: none;">
 			<thead>
 				<tr><th>value</th></tr>
diff --git a/dojox/charting/tests/test_win2d.html b/dojox/charting/tests/test_win2d.html
index 3183eb5..20b7977 100644
--- a/dojox/charting/tests/test_win2d.html
+++ b/dojox/charting/tests/test_win2d.html
@@ -21,7 +21,7 @@
 	@import "../../../dijit/themes/tundra/tundra.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 
 dojo.require("dijit.form.HorizontalSlider");
diff --git a/dojox/charting/tests/theme_preview.html b/dojox/charting/tests/theme_preview.html
index 0409e7d..d347788 100644
--- a/dojox/charting/tests/theme_preview.html
+++ b/dojox/charting/tests/theme_preview.html
@@ -44,7 +44,7 @@
 			div.container div.title a { text-decoration: none; }
 			div.container div.title a:hover { text-decoration: underline; }
 		</style>
-<script src="../../../dojo/dojo.js" djConfig="isDebug: false, gfxRenderer: 'svg,silverlight,vml,canvas'"></script>
+<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: false, gfxRenderer: 'svg,silverlight,vml,canvas'"></script>
 <script type="text/javascript">
     dojo.require("dojox.charting.Chart");
     dojo.require("dojox.charting.plot2d.Pie");
diff --git a/dojox/charting/themes/Adobebricks.js b/dojox/charting/themes/Adobebricks.js
index db3dd99..224e424 100644
--- a/dojox/charting/themes/Adobebricks.js
+++ b/dojox/charting/themes/Adobebricks.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-
-	themes.Adobebricks=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.Adobebricks = new SimpleTheme({
 		colors: [
 			"#7f2518",
 			"#3e170c",
@@ -9,6 +8,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#8c271c"
 		]
 	});
-	
 	return themes.Adobebricks;
 });
diff --git a/dojox/charting/themes/Algae.js b/dojox/charting/themes/Algae.js
index 7a809ac..800256c 100644
--- a/dojox/charting/themes/Algae.js
+++ b/dojox/charting/themes/Algae.js
@@ -1,5 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	themes.Algae = new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.Algae = new SimpleTheme({
 		colors: [
 			"#57808f",
 			"#506885",
diff --git a/dojox/charting/themes/Bahamation.js b/dojox/charting/themes/Bahamation.js
index 6132766..9901b96 100644
--- a/dojox/charting/themes/Bahamation.js
+++ b/dojox/charting/themes/Bahamation.js
@@ -1,5 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	themes.Bahamation=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.Bahamation = new SimpleTheme({
 		colors: [
 			"#3f9998",
 			"#3fc0c3",
diff --git a/dojox/charting/themes/BlueDusk.js b/dojox/charting/themes/BlueDusk.js
index 7762bdd..3f6302e 100644
--- a/dojox/charting/themes/BlueDusk.js
+++ b/dojox/charting/themes/BlueDusk.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-
-	themes.BlueDusk=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.BlueDusk = new SimpleTheme({
 		colors: [
 			"#292e76",
 			"#3e56a6",
diff --git a/dojox/charting/themes/Claro.js b/dojox/charting/themes/Claro.js
index e4f3e40..44fa9eb 100644
--- a/dojox/charting/themes/Claro.js
+++ b/dojox/charting/themes/Claro.js
@@ -67,28 +67,28 @@ define(["../Theme", "dojox/gfx/gradutils", "./common"], function(Theme, gradutil
 	});
 	
 	themes.Claro.next = function(elementType, mixin, doPost){
-		var isLine = elementType == "line";
+		var isLine = elementType == "line",
+			s, theme;
 		if(isLine || elementType == "area"){
 			// custom processing for lines: substitute colors
-			var s = this.seriesThemes[this._current % this.seriesThemes.length],
-				m = this.markerThemes[this._current % this.markerThemes.length];
+			s = this.seriesThemes[this._current % this.seriesThemes.length];
+			var m = this.markerThemes[this._current % this.markerThemes.length];
 			s.fill.space = "plot";
 			if(isLine){
 				s.stroke  = { width: 4, color: s.fill.colors[0].color};
 			}
 			m.outline = { width: 1.25, color: m.fill };
-			var theme = Theme.prototype.next.apply(this, arguments);
+			theme = Theme.prototype.next.apply(this, arguments);
 			// cleanup
 			delete s.outline;
 			delete s.stroke;
 			s.fill.space = "shape";
 			return theme;
-		}
-		else if(elementType == "candlestick"){
-			var s = this.seriesThemes[this._current % this.seriesThemes.length];
+		}else if(elementType == "candlestick"){
+			s = this.seriesThemes[this._current % this.seriesThemes.length];
 			s.fill.space = "plot";
 			s.stroke  = { width: 1, color: s.fill.colors[0].color};
-			var theme = Theme.prototype.next.apply(this, arguments);
+			theme = Theme.prototype.next.apply(this, arguments);
 			return theme;
 		}
 		return Theme.prototype.next.apply(this, arguments);
diff --git a/dojox/charting/themes/CubanShirts.js b/dojox/charting/themes/CubanShirts.js
index 7591e91..0c8ef0f 100644
--- a/dojox/charting/themes/CubanShirts.js
+++ b/dojox/charting/themes/CubanShirts.js
@@ -1,8 +1,7 @@
-define(["../Theme", "./common"], function(Theme, themes){
-
-	//	notes: colors generated by moving in 30 degree increments around the hue circle,
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	// notes: colors generated by moving in 30 degree increments around the hue circle,
 	//		at 90% saturation, using a B value of 75 (HSB model).
-	themes.CubanShirts=new Theme({
+	themes.CubanShirts = new SimpleTheme({
 		colors: [
 			"#d42d2a",
 			"#004f80",
@@ -11,6 +10,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#7f7f33"
 		]
 	});
-	
 	return themes.CubanShirts;
 });
diff --git a/dojox/charting/themes/Desert.js b/dojox/charting/themes/Desert.js
index cab2e75..d0099d6 100644
--- a/dojox/charting/themes/Desert.js
+++ b/dojox/charting/themes/Desert.js
@@ -1,8 +1,7 @@
-define(["../Theme", "./common"], function(Theme, themes){
-
-	//	notes: colors generated by moving in 30 degree increments around the hue circle,
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	// notes: colors generated by moving in 30 degree increments around the hue circle,
 	//		at 90% saturation, using a B value of 75 (HSB model).
-	themes.Desert=new Theme({
+	themes.Desert = new SimpleTheme({
 		colors: [
 			"#ffebd5",
 			"#806544",
@@ -11,6 +10,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#cda26e"
 		]
 	});
-	
 	return themes.Desert;
 });
diff --git a/dojox/charting/themes/Distinctive.js b/dojox/charting/themes/Distinctive.js
index eaeb239..0ace8f6 100644
--- a/dojox/charting/themes/Distinctive.js
+++ b/dojox/charting/themes/Distinctive.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.Distinctive=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.Distinctive = new SimpleTheme({
 		colors: [
 			"#497c91",
 			"#ada9d6",
@@ -37,6 +36,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 		
 		]
 	});
-	
 	return themes.Distinctive;
 });
diff --git a/dojox/charting/themes/Dollar.js b/dojox/charting/themes/Dollar.js
index 36790c4..72d0e01 100644
--- a/dojox/charting/themes/Dollar.js
+++ b/dojox/charting/themes/Dollar.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.Dollar=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.Dollar = new SimpleTheme({
 		colors: [
 			"#A4CE67",
 			"#739363",
@@ -9,6 +8,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#636563"
 		]
 	});
-	
 	return themes.Dollar;
 });
diff --git a/dojox/charting/themes/Grasshopper.js b/dojox/charting/themes/Grasshopper.js
index a5e182d..ddea3bf 100644
--- a/dojox/charting/themes/Grasshopper.js
+++ b/dojox/charting/themes/Grasshopper.js
@@ -1,5 +1,5 @@
-define(["dojo/_base/lang","../Theme", "./common"], function(lang, Theme, themes){
-	themes.Grasshopper=new Theme({
+define(["dojo/_base/lang","../SimpleTheme", "./common"], function(lang, SimpleTheme, themes){
+	themes.Grasshopper = new SimpleTheme({
 		colors: [
 			"#208040",
 			"#40b657",
diff --git a/dojox/charting/themes/Grasslands.js b/dojox/charting/themes/Grasslands.js
index 5c53dbf..25b0ac1 100644
--- a/dojox/charting/themes/Grasslands.js
+++ b/dojox/charting/themes/Grasslands.js
@@ -1,8 +1,7 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	//	notes: colors generated by moving in 30 degree increments around the hue circle,
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	// notes: colors generated by moving in 30 degree increments around the hue circle,
 	//		at 90% saturation, using a B value of 75 (HSB model).
-	themes.Grasslands=new Theme({
+	themes.Grasslands = new SimpleTheme({
 		colors: [
 			"#70803a",
 			"#dde574",
@@ -11,6 +10,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#eff2c2"
 		]
 	});
-	
 	return themes.Grasslands;
 });
diff --git a/dojox/charting/themes/GreySkies.js b/dojox/charting/themes/GreySkies.js
index 7864e99..134b49f 100644
--- a/dojox/charting/themes/GreySkies.js
+++ b/dojox/charting/themes/GreySkies.js
@@ -1,6 +1,4 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.GreySkies=new Theme(Theme._def);
-	
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.GreySkies = new SimpleTheme();
 	return themes.GreySkies;
 });
diff --git a/dojox/charting/themes/Harmony.js b/dojox/charting/themes/Harmony.js
index 7fbe9a7..cf80e0f 100644
--- a/dojox/charting/themes/Harmony.js
+++ b/dojox/charting/themes/Harmony.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.Harmony=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.Harmony = new SimpleTheme({
 		colors: [
 			"#497c91",
 			"#59a0bd",
@@ -36,6 +35,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#d8d8d8"
 		]
 	});
-	
 	return themes.Harmony;
 });
diff --git a/dojox/charting/themes/IndigoNation.js b/dojox/charting/themes/IndigoNation.js
index f3d131a..828e10d 100644
--- a/dojox/charting/themes/IndigoNation.js
+++ b/dojox/charting/themes/IndigoNation.js
@@ -1,8 +1,7 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	//	notes: colors generated by moving in 30 degree increments around the hue circle,
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	// notes: colors generated by moving in 30 degree increments around the hue circle,
 	//		at 90% saturation, using a B value of 75 (HSB model).
-	themes.IndigoNation=new Theme({
+	themes.IndigoNation = new SimpleTheme({
 		colors: [
 			"#93a4d0",
 			"#3b4152",
@@ -11,6 +10,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#8290b8"
 		]
 	});
-	
 	return themes.IndigoNation;
 });
diff --git a/dojox/charting/themes/Ireland.js b/dojox/charting/themes/Ireland.js
index 82ac126..1fc3f61 100644
--- a/dojox/charting/themes/Ireland.js
+++ b/dojox/charting/themes/Ireland.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.Ireland=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.Ireland = new SimpleTheme({
 		colors: [
 			"#abdbcb",
 			"#435a51",
@@ -9,6 +8,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#5f8074"
 		]
 	});
-	
 	return themes.Ireland;
 });
diff --git a/dojox/charting/themes/Julie.js b/dojox/charting/themes/Julie.js
index 79c4a15..cb651bb 100644
--- a/dojox/charting/themes/Julie.js
+++ b/dojox/charting/themes/Julie.js
@@ -1,8 +1,8 @@
-define(["../Theme", "dojox/gfx/gradutils", "./common"], function(Theme, gradutils){
+define(["../Theme", "dojox/gfx/gradutils", "./common"], function(Theme, gradutils, themes){
 
 	// created by Julie Santilli (Claro-based theme)
 	
-	var themes = dojox.charting.themes, g = Theme.generateGradient,
+	var g = Theme.generateGradient,
 		defaultFill = {type: "linear", space: "shape", x1: 0, y1: 0, x2: 0, y2: 100};
 	
 	themes.Julie = new Theme({
diff --git a/dojox/charting/themes/MiamiNice.js b/dojox/charting/themes/MiamiNice.js
index 1739fee..b1a66fd 100644
--- a/dojox/charting/themes/MiamiNice.js
+++ b/dojox/charting/themes/MiamiNice.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.MiamiNice=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.MiamiNice = new SimpleTheme({
 		colors: [
 			"#7f9599",
 			"#45b8cc",
@@ -9,6 +8,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#cc4482"
 		]
 	});
-	
 	return themes.MiamiNice;
 });
diff --git a/dojox/charting/themes/Midwest.js b/dojox/charting/themes/Midwest.js
index a122974..38c366c 100644
--- a/dojox/charting/themes/Midwest.js
+++ b/dojox/charting/themes/Midwest.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.Midwest=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.Midwest=new SimpleTheme({
 		colors: [
 			"#927b51",
 			"#a89166",
@@ -9,6 +8,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#aebc21"
 		]
 	});
-	
 	return themes.Midwest;
 });
diff --git a/dojox/charting/themes/Minty.js b/dojox/charting/themes/Minty.js
index 89a1dd5..c528a7f 100644
--- a/dojox/charting/themes/Minty.js
+++ b/dojox/charting/themes/Minty.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.Minty=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.Minty = new SimpleTheme({
 		colors: [
 			"#80ccbb",
 			"#539e8b",
@@ -9,6 +8,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#68c5ad"
 		]
 	});
-	
 	return themes.Minty;
 });
diff --git a/dojox/charting/themes/PlotKit/base.js b/dojox/charting/themes/PlotKit/base.js
index ff6e700..4fb0bca 100644
--- a/dojox/charting/themes/PlotKit/base.js
+++ b/dojox/charting/themes/PlotKit/base.js
@@ -1,5 +1,5 @@
-define(["dojo/_base/kernel","dojo/_base/lang","../../Theme", "../common"], 
-	function(dojo, lang, Theme, themes){
+define(["dojo/_base/lang", "dojo/_base/Color", "../../Theme", "../common"],
+	function(lang, Color, Theme, themes){
 
 	// the baseline theme for all PlotKIt themes
 	var pk = lang.getObject("PlotKit", true, themes);
@@ -41,9 +41,11 @@ define(["dojo/_base/kernel","dojo/_base/lang","../../Theme", "../common"],
 			theme.marker.outline = {width: 2, color: "#fff"};
 			theme.series.stroke.width = 3.5;
 			theme.marker.stroke.width = 2;
-		} else if (elementType == "candlestick"){
+		}else if(elementType == "candlestick"){
 			theme.series.stroke.width = 1;
-		} else {
+		}else if(theme.series.stroke.color && (theme.series.stroke.color.toString() ==
+				new Color(this.colors[(this._current-1) % this.colors.length]).toString())){
+			// if the user did not override the stroke, let's force blank
 			theme.series.stroke.color = "#fff";
 		}
 		return theme;
diff --git a/dojox/charting/themes/PurpleRain.js b/dojox/charting/themes/PurpleRain.js
index 2e43efb..08274b5 100644
--- a/dojox/charting/themes/PurpleRain.js
+++ b/dojox/charting/themes/PurpleRain.js
@@ -1,8 +1,7 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	//	notes: colors generated by moving in 30 degree increments around the hue circle,
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	// notes: colors generated by moving in 30 degree increments around the hue circle,
 	//		at 90% saturation, using a B value of 75 (HSB model).
-	themes.PurpleRain=new Theme({
+	themes.PurpleRain = new SimpleTheme({
 		colors: [
 			"#4879bc",
 			"#ef446f",
@@ -11,6 +10,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#4956a6"
 		]
 	});
-	
 	return themes.PurpleRain;
 });
diff --git a/dojox/charting/themes/RoyalPurples.js b/dojox/charting/themes/RoyalPurples.js
index c424a32..a9b16f9 100644
--- a/dojox/charting/themes/RoyalPurples.js
+++ b/dojox/charting/themes/RoyalPurples.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.RoyalPurples=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.RoyalPurples = new SimpleTheme({
 		colors: [
 			"#473980",
 			"#685aa7",
@@ -9,6 +8,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#7267ae"
 		]
 	});
-	
 	return themes.RoyalPurples;
 });
diff --git a/dojox/charting/themes/SageToLime.js b/dojox/charting/themes/SageToLime.js
index e18020f..0b75568 100644
--- a/dojox/charting/themes/SageToLime.js
+++ b/dojox/charting/themes/SageToLime.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.SageToLime=new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.SageToLime = new SimpleTheme({
 		colors: [
 			"#abdbcb",
 			"#435a51",
@@ -14,6 +13,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#68c5ad"
 		]
 	});
-	
 	return themes.SageToLime;
 });
diff --git a/dojox/charting/themes/Shrooms.js b/dojox/charting/themes/Shrooms.js
index bd43a8e..8694911 100644
--- a/dojox/charting/themes/Shrooms.js
+++ b/dojox/charting/themes/Shrooms.js
@@ -1,7 +1,7 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	//	notes: colors generated by moving in 30 degree increments around the hue circle,
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	// notes: colors generated by moving in 30 degree increments around the hue circle,
 	//		at 90% saturation, using a B value of 75 (HSB model).
-	themes.Shrooms = new Theme({
+	themes.Shrooms = new SimpleTheme({
 		colors: [
 			"#bf1313", // 0
 			"#69bf13", // 90
@@ -17,6 +17,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#bf1369"  // 330
 		]
 	});
-	
 	return themes.Shrooms;
 });
diff --git a/dojox/charting/themes/ThreeD.js b/dojox/charting/themes/ThreeD.js
index a58a830..a41807b 100644
--- a/dojox/charting/themes/ThreeD.js
+++ b/dojox/charting/themes/ThreeD.js
@@ -1,5 +1,5 @@
-define(["dojox","dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "../Theme", "./gradientGenerator", "./PrimaryColors", "dojo/colors" /* for sanitize */, "./common"], 
-	function(dojox, kernel, lang, ArrayUtil, Theme, gradientGenerator, PrimaryColors, themes){
+define(["dojo/_base/lang", "dojo/_base/array", "../Theme", "./gradientGenerator", "./PrimaryColors", "dojo/colors" /* for sanitize */, "./common"],
+	function(lang, ArrayUtil, Theme, gradientGenerator, PrimaryColors, themes){
 
 	var colors = ["#f00", "#0f0", "#00f", "#ff0", "#0ff", "#f0f", "./common"],	// the same is in PrimaryColors
 		defaultFill = {type: "linear", space: "shape", x1: 0, y1: 0, x2: 100, y2: 0},
@@ -9,7 +9,7 @@ define(["dojox","dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "../
 			{o: 0.39, i: 221}, {o: 0.49, i: 206}, {o: 0.58, i: 187}, {o: 0.68, i: 165},
 			{o: 0.80, i: 128}, {o: 0.90, i: 102}, {o: 1.00, i: 174}
 		],
-		hiliteIndex = 2, hiliteIntensity = 100, lumStroke = 50,
+		hiliteIndex = 2, hiliteIntensity = 100,
 		cyl3dFills = ArrayUtil.map(colors, function(c){
 			var fill = lang.delegate(defaultFill),
 				colors = fill.colors = gradientGenerator.generateGradientByIntensity(c, cyl3dMap),
diff --git a/dojox/charting/themes/Tufte.js b/dojox/charting/themes/Tufte.js
index 0792185..8998131 100644
--- a/dojox/charting/themes/Tufte.js
+++ b/dojox/charting/themes/Tufte.js
@@ -1,9 +1,9 @@
-define(["../Theme", "dojo/_base/Color", "./common"], function(Theme, Color, themes){
+define(["../SimpleTheme", "dojo/_base/Color", "./common"], function(SimpleTheme, Color, themes){
 	/*
 		A charting theme based on the principles championed by
 		Edward Tufte.  By Alex Russell, Dojo Project Lead.
 	*/
-	themes.Tufte = new Theme({
+	themes.Tufte = new SimpleTheme({
 		chart: {
 			stroke: null,
 			fill: "inherit"
diff --git a/dojox/charting/themes/WatersEdge.js b/dojox/charting/themes/WatersEdge.js
index 08b1fb9..68331e6 100644
--- a/dojox/charting/themes/WatersEdge.js
+++ b/dojox/charting/themes/WatersEdge.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.WatersEdge = new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.WatersEdge = new SimpleTheme({
 		colors: [
 			"#437cc0",
 			"#6256a5",
@@ -9,6 +8,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#4b66b0"
 		]
 	});
-	
 	return  themes.WatersEdge;
 });
diff --git a/dojox/charting/themes/Wetland.js b/dojox/charting/themes/Wetland.js
index ec1a43e..298fbff 100644
--- a/dojox/charting/themes/Wetland.js
+++ b/dojox/charting/themes/Wetland.js
@@ -1,6 +1,5 @@
-define(["../Theme", "./common"], function(Theme, themes){
-	
-	themes.Wetland = new Theme({
+define(["../SimpleTheme", "./common"], function(SimpleTheme, themes){
+	themes.Wetland = new SimpleTheme({
 		colors: [
 			"#bfbc64",
 			"#737130",
@@ -9,6 +8,5 @@ define(["../Theme", "./common"], function(Theme, themes){
 			"#8d3c42"
 		]
 	});
-	
 	return themes.Wetland;
 });
diff --git a/dojox/charting/themes/gradientGenerator.js b/dojox/charting/themes/gradientGenerator.js
index d4994f8..791ea77 100644
--- a/dojox/charting/themes/gradientGenerator.js
+++ b/dojox/charting/themes/gradientGenerator.js
@@ -4,15 +4,15 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color", "../Theme", "
 	var gg = lang.getObject("gradientGenerator", true, themes);
 
 	gg.generateFills = function(colors, fillPattern, lumFrom, lumTo){
-		//	summary:
+		// summary:
 		//		generates 2-color gradients using pure colors, a fill pattern, and two luminance values
-		//	colors: Array:
+		// colors: Array
 		//		Array of colors to generate gradients for each.
-		//	fillPattern: Object:
+		// fillPattern: Object
 		//		Gradient fill descriptor which colors list will be generated.
-		//	lumFrom: Number:
+		// lumFrom: Number
 		//		Initial luminance value (0-100).
-		//	lumTo: Number:
+		// lumTo: Number
 		//		Final luminance value (0-100).
 		return arr.map(colors, function(c){	// Array
 			return Theme.generateHslGradient(c, fillPattern, lumFrom, lumTo);
@@ -20,15 +20,15 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color", "../Theme", "
 	};
 	
 	gg.updateFills = function(themes, fillPattern, lumFrom, lumTo){
-		//	summary:
+		// summary:
 		//		transforms solid color fills into 2-color gradients using a fill pattern, and two luminance values
-		//	themes: Array:
+		// themes: Array
 		//		Array of mini-themes (usually series themes or marker themes), which fill will be transformed.
-		//	fillPattern: Object:
+		// fillPattern: Object
 		//		Gradient fill descriptor which colors list will be generated.
-		//	lumFrom: Number:
+		// lumFrom: Number
 		//		Initial luminance value (0-100).
-		//	lumTo: Number:
+		// lumTo: Number
 		//		Final luminance value (0-100).
 		arr.forEach(themes, function(t){
 			if(t.fill && !t.fill.type){
@@ -38,33 +38,33 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color", "../Theme", "
 	};
 	
 	gg.generateMiniTheme = function(colors, fillPattern, lumFrom, lumTo, lumStroke){
-		//	summary:
+		// summary:
 		//		generates mini-themes with 2-color gradients using colors, a fill pattern, and three luminance values
-		//	colors: Array:
+		// colors: Array
 		//		Array of colors to generate gradients for each.
-		//	fillPattern: Object:
+		// fillPattern: Object
 		//		Gradient fill descriptor which colors list will be generated.
-		//	lumFrom: Number:
+		// lumFrom: Number
 		//		Initial luminance value (0-100).
-		//	lumTo: Number:
+		// lumTo: Number
 		//		Final luminance value (0-100).
-		//	lumStroke: Number:
+		// lumStroke: Number
 		//		Stroke luminance value (0-100).
 		return arr.map(colors, function(c){	// Array
 			c = new dxcolor.Color(c);
 			return {
 				fill:   Theme.generateHslGradient(c, fillPattern, lumFrom, lumTo),
 				stroke: {color: Theme.generateHslColor(c, lumStroke)}
-			}
+			};
 		});
 	};
 	
 	gg.generateGradientByIntensity = function(color, intensityMap){
-		//	summary:
+		// summary:
 		//		generates gradient colors using an intensity map
-		//	color: dojo.Color:
+		// color: dojo.Color
 		//		Color to use to generate gradients.
-		//	intensityMap: Array:
+		// intensityMap: Array
 		//		Array of tuples {o, i}, where o is a gradient offset (0-1),
 		//		and i is an intensity (0-255).
 		color = new Color(color);
@@ -75,7 +75,7 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color", "../Theme", "
 				color:  new Color([color.r * s, color.g * s, color.b * s, color.a])
 			};
 		});
-	}
+	};
 	
 	return gg;
 });
diff --git a/dojox/charting/widget/BidiSupport.js b/dojox/charting/widget/BidiSupport.js
index 015c794..41cc191 100644
--- a/dojox/charting/widget/BidiSupport.js
+++ b/dojox/charting/widget/BidiSupport.js
@@ -1,92 +1,4 @@
-define(["dojo/dom", "dojo/_base/lang", "dojo/_base/html", "dojo/_base/array",  "dojo/_base/connect", "dojo/query",
-	"dijit/_BidiSupport", "../BidiSupport", "dijit/registry", "./Chart", "./Legend"], 
-	function(dom, lang, html, arrayUtil, hub, query, dBidi, cBidi, widgetManager, Chart, Legend){
-
-	// patch only if present
-	if( Legend ){
-		lang.extend(Legend, {
-			// summary:
-			//		Add support for bidi scripts in legend.
-			// description:
-			//		Since dojox.charting.widget.Legend inherits from _Widget use the bidi support
-			//		that introduced there.
-
-			postMixInProperties: function(){
-				// summary:
-				//		Connect the setter of textDir legend to setTextDir of the chart,
-				//		so _setTextDirAttr of the legend will be called after setTextDir of the chart is called.
-				// tags:
-				//		private
-
-				// find the chart that is the owner of this legend, use it's 
-				// textDir
-				if(!this.chart){
-					if(!this.chartRef){ return; }
-					var chart = widgetManager.byId(this.chartRef);
-					if(!chart){
-						var node = dom.byId(this.chartRef);
-						if(node){
-							chart = widgetManager.byNode(node);
-						}else{
-							return;
-						}
-					}
-					this.textDir = chart.chart.textDir;
-					hub.connect(chart.chart, "setTextDir", this, "_setTextDirAttr");
-
-				}else{
-					this.textDir = this.chart.textDir;
-					hub.connect(this.chart, "setTextDir", this, "_setTextDirAttr");
-
-				}
-			},
-
-			_setTextDirAttr: function(/*String*/ textDir){
-				// summary:
-				//		Setter for textDir. 
-				// description:
-				//		Users shouldn't call this function; they should be calling
-				//		set('textDir', value)
-				// tags:
-				//		private
-				
-				// only if new textDir is different from the old one
-				if(validateTextDir(textDir) != null){
-					if(this.textDir != textDir){
-						this._set("textDir", textDir);
-						// get array of all the labels
-						var legendLabels = query(".dojoxLegendText", this._tr);
-							// for every label calculate it's new dir.
-							arrayUtil.forEach(legendLabels, function(label){
-								label.dir = this.getTextDir(label.innerHTML, label.dir);
-						}, this);					
-					}
-				}
-			}
-		});
-	}
-	
-	// patch only if present
-	if( Chart ){
-		lang.extend( Chart ,{
-			postMixInProperties: function(){
-				// set initial textDir of the chart, if passed in the creation use that value
-				// else use default value, following the GUI direction, this.chart doesn't exist yet
-				// so can't use set("textDir", textDir). This passed to this.chart in it's future creation.
-				this.textDir = this.params["textDir"] ? this.params["textDir"] : this.params["dir"];
-			},
-
-			_setTextDirAttr: function(/*String*/ textDir){
-				if(validateTextDir(textDir) != null){
-					this._set("textDir", textDir);
-					this.chart.setTextDir(textDir);
-				}
-			}
-		});
-	}
-
-	function validateTextDir(textDir){
-		return /^(ltr|rtl|auto)$/.test(textDir) ? textDir : null;
-	}
-		
+define(["dojo/_base/kernel"],
+		function(kernel){
+		kernel.deprecated('dojox.charting.widget.BidiSupport is deprecated,', 'set "has: {\'dojo-bidi\': true }" in data-dojo-config to enable bidi support');
 });
diff --git a/dojox/charting/widget/Chart.js b/dojox/charting/widget/Chart.js
index 7492a4a..40031d8 100644
--- a/dojox/charting/widget/Chart.js
+++ b/dojox/charting/widget/Chart.js
@@ -1,130 +1,14 @@
-define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/html","dojo/_base/declare", "dojo/query",
-	"dijit/_Widget", "../Chart", "dojox/lang/utils", "dojox/lang/functional","dojox/lang/functional/lambda",
-	"dijit/_base/manager"], 
-	function(kernel, lang, arr, html, declare, query, Widget, Chart, du, df, dfl){
-/*=====
-var Widget = dijit._Widget;
-=====*/
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/dom-attr","dojo/_base/declare", "dojo/query",
+	"dijit/_WidgetBase", "../Chart", "dojo/has", "dojo/has!dojo-bidi?../bidi/widget/Chart", 
+	"dojox/lang/utils", "dojox/lang/functional","dojox/lang/functional/lambda"],
+	function(kernel, lang, arr, domAttr, declare, query, _WidgetBase, ChartBase, has, BidiChart, du, df, dfl){
+
 	var collectParams, collectAxisParams, collectPlotParams,
 		collectActionParams, collectDataParams,
 		notNull = function(o){ return o; },
 		dc = lang.getObject("dojox.charting");
-	
-	var ChartWidget = declare("dojox.charting.widget.Chart", Widget, {
-		// parameters for the markup
-		
-		// theme for the chart
-		theme: null,
-		
-		// margins for the chart: {l: 10, r: 10, t: 10, b: 10}
-		margins: null,
-		
-		// chart area, define them as undefined to:
-		// allow the parser to take them into account
-		// but make sure they have no defined value to not override theme
-		stroke: undefined,
-		fill:   undefined,
-		
-		// methods
-		
-		buildRendering: function(){
-			this.inherited(arguments);
-			
-			n = this.domNode;
-			
-			// collect chart parameters
-			var axes    = query("> .axis", n).map(collectAxisParams).filter(notNull),
-				plots   = query("> .plot", n).map(collectPlotParams).filter(notNull),
-				actions = query("> .action", n).map(collectActionParams).filter(notNull),
-				series  = query("> .series", n).map(collectDataParams).filter(notNull);
-			
-			// build the chart
-			n.innerHTML = "";
-			var c = this.chart = new Chart(n, {
-				margins: this.margins,
-				stroke:  this.stroke,
-				fill:    this.fill,
-				textDir: this.textDir
-			});
-			
-			// add collected parameters
-			if(this.theme){
-				c.setTheme(this.theme);
-			}
-			axes.forEach(function(axis){
-				c.addAxis(axis.name, axis.kwArgs);
-			});
-			plots.forEach(function(plot){
-				c.addPlot(plot.name, plot.kwArgs);
-			});
-			
-			this.actions = actions.map(function(action){
-				return new action.action(c, action.plot, action.kwArgs);
-			});
-			
-			var render = df.foldl(series, function(render, series){
-				if(series.type == "data"){
-					c.addSeries(series.name, series.data, series.kwArgs);
-					render = true;
-				}else{
-					c.addSeries(series.name, [0], series.kwArgs);
-					var kw = {};
-					du.updateWithPattern(
-						kw,
-						series.kwArgs,
-						{
-							"query": "",
-							"queryOptions": null,
-							"start": 0,
-							"count": 1 //,
-							// "sort": []
-						},
-						true
-					);
-					if(series.kwArgs.sort){
-						// sort is a complex object type and doesn't survive coercian
-						kw.sort = lang.clone(series.kwArgs.sort);
-					}
-					lang.mixin(kw, {
-						onComplete: function(data){
-							var values;
-							if("valueFn" in series.kwArgs){
-								var fn = series.kwArgs.valueFn;
-								values = arr.map(data, function(x){
-									return fn(series.data.getValue(x, series.field, 0));
-								});
-							}else{
-								values = arr.map(data, function(x){
-									return series.data.getValue(x, series.field, 0);
-								});
-							}
-							c.addSeries(series.name, values, series.kwArgs).render();
-						}
-					});
-					series.data.fetch(kw);
-				}
-				return render;
-			}, false);
-			if(render){ c.render(); }
-		},
-		destroy: function(){
-			// summary: properly destroy the widget
-			this.chart.destroy();
-			this.inherited(arguments);
-		},
-		resize: function(box){
-			//	summary:
-			//		Resize the widget.
-			//	description:
-			//		Resize the domNode and the widget surface to the dimensions of a box of the following form:
-			//			`{ l: 50, t: 200, w: 300: h: 150 }`
-			//		If no box is provided, resize the surface to the marginBox of the domNode.
-			//	box:
-			//		If passed, denotes the new size of the widget.
-			this.chart.resize(box);
-		}
-	});
-	
+
+
 	collectParams = function(node, type, kw){
 		var dp = eval("(" + type + ".prototype.defaultParams)");
 		var x, attr;
@@ -142,19 +26,19 @@ var Widget = dijit._Widget;
 			}
 		}
 	};
-	
+
 	collectAxisParams = function(node){
 		var name = node.getAttribute("name"), type = node.getAttribute("type");
 		if(!name){ return null; }
 		var o = {name: name, kwArgs: {}}, kw = o.kwArgs;
 		if(type){
 			if(dc.axis2d[type]){
-				type = dojo._scopeName + "x.charting.axis2d." + type;
+				type = kernel._scopeName + "x.charting.axis2d." + type;
 			}
 			var axis = eval("(" + type + ")");
 			if(axis){ kw.type = axis; }
 		}else{
-			type = dojo._scopeName + "x.charting.axis2d.Default";
+			type = kernel._scopeName + "x.charting.axis2d.Default";
 		}
 		collectParams(node, type, kw);
 		// compatibility conversions
@@ -171,7 +55,7 @@ var Widget = dijit._Widget;
 		}
 		return o;
 	};
-	
+
 	collectPlotParams = function(node){
 		// var name = d.attr(node, "name"), type = d.attr(node, "type");
 		var name = node.getAttribute("name"), type = node.getAttribute("type");
@@ -179,17 +63,28 @@ var Widget = dijit._Widget;
 		var o = {name: name, kwArgs: {}}, kw = o.kwArgs;
 		if(type){
 			if(dc.plot2d && dc.plot2d[type]){
-				type = dojo._scopeName + "x.charting.plot2d." + type;
+				type = kernel._scopeName + "x.charting.plot2d." + type;
 			}
 			var plot = eval("(" + type + ")");
 			if(plot){ kw.type = plot; }
 		}else{
-			type = dojo._scopeName + "x.charting.plot2d.Default";
+			type = kernel._scopeName + "x.charting.plot2d.Default";
 		}
 		collectParams(node, type, kw);
+		// TODO
+		// we have factorized axis & label management in CartesianBase and thus is is not anymore
+		// accessible to the default collect mechanism. Longer term we must get rid of that
+		// and leverage dojo/parser
+		var dp = eval("(" + type + ".prototype.baseParams)");
+		var x, attr;
+		for(x in dp){
+			if(x in kw){ continue; }
+			attr = node.getAttribute(x);
+			kw[x] = du.coerceType(dp[x], attr == null || typeof attr == "undefined" ? dp[x] : attr);
+		}
 		return o;
 	};
-	
+
 	collectActionParams = function(node){
 		// var plot = d.attr(node, "plot"), type = d.attr(node, "type");
 		var plot = node.getAttribute("plot"), type = node.getAttribute("type");
@@ -197,7 +92,7 @@ var Widget = dijit._Widget;
 		var o = {plot: plot, kwArgs: {}}, kw = o.kwArgs;
 		if(type){
 			if(dc.action2d[type]){
-				type = dojo._scopeName + "x.charting.action2d." + type;
+				type = kernel._scopeName + "x.charting.action2d." + type;
 			}
 			var action = eval("(" + type + ")");
 			if(!action){ return null; }
@@ -210,7 +105,7 @@ var Widget = dijit._Widget;
 	};
 
 	collectDataParams = function(node){
-		var ga = lang.partial(html.attr, node);
+		var ga = lang.partial(domAttr.get, node);
 		var name = ga("name");
 		if(!name){ return null; }
 		var o = { name: name, kwArgs: {} }, kw = o.kwArgs, t;
@@ -267,5 +162,130 @@ var Widget = dijit._Widget;
 		return null;
 	};
 	
-	return ChartWidget;
+	var Chart = declare(has("dojo-bidi")? "dojox.charting.widget.NonBidiChart" : "dojox.charting.widget.Chart", _WidgetBase, {
+		// summary:
+		//		A chart widget.  This is leveraging dojox/charting/Chart as a Dijit widget.
+
+		// parameters for the markup
+
+		// theme: dojox/charting/SimpleTheme?
+		//		An optional theme to use for styling the chart.
+		theme: null,
+		
+		// margins: Object?
+		//		The margins around the chart. Default is { l:10, t:10, r:10, b:10 }.
+		margins: null,
+		
+		// chart area, define them as undefined to:
+		// allow the parser to take them into account
+		// but make sure they have no defined value to not override theme
+
+		// stroke: dojox.gfx.Stroke?
+		//		The outline of the chart (stroke in vector graphics terms).
+		stroke: undefined,
+		// fill: dojox.gfx.Fill?
+		//		The color for the chart.
+		fill:   undefined,
+		
+		// methods
+		
+		buildRendering: function(){
+			this.inherited(arguments);
+			
+			var n = this.domNode;
+			
+			// collect chart parameters
+			var axes    = query("> .axis", n).map(collectAxisParams).filter(notNull),
+				plots   = query("> .plot", n).map(collectPlotParams).filter(notNull),
+				actions = query("> .action", n).map(collectActionParams).filter(notNull),
+				series  = query("> .series", n).map(collectDataParams).filter(notNull);
+			
+			// build the chart
+			n.innerHTML = "";
+			var c = this.chart = new ChartBase(n, {
+				margins: this.margins,
+				stroke:  this.stroke,
+				fill:    this.fill,
+				textDir: this.textDir
+			});
+			
+			// add collected parameters
+			if(this.theme){
+				c.setTheme(this.theme);
+			}
+			axes.forEach(function(axis){
+				c.addAxis(axis.name, axis.kwArgs);
+			});
+			plots.forEach(function(plot){
+				c.addPlot(plot.name, plot.kwArgs);
+			});
+			
+			this.actions = actions.map(function(action){
+				return new action.action(c, action.plot, action.kwArgs);
+			});
+			
+			var render = df.foldl(series, function(render, series){
+				if(series.type == "data"){
+					c.addSeries(series.name, series.data, series.kwArgs);
+					render = true;
+				}else{
+					c.addSeries(series.name, [0], series.kwArgs);
+					var kw = {};
+					du.updateWithPattern(
+						kw,
+						series.kwArgs,
+						{
+							"query": "",
+							"queryOptions": null,
+							"start": 0,
+							"count": 1 //,
+							// "sort": []
+						},
+						true
+					);
+					if(series.kwArgs.sort){
+						// sort is a complex object type and doesn't survive coercian
+						kw.sort = lang.clone(series.kwArgs.sort);
+					}
+					lang.mixin(kw, {
+						onComplete: function(data){
+							var values;
+							if("valueFn" in series.kwArgs){
+								var fn = series.kwArgs.valueFn;
+								values = arr.map(data, function(x){
+									return fn(series.data.getValue(x, series.field, 0));
+								});
+							}else{
+								values = arr.map(data, function(x){
+									return series.data.getValue(x, series.field, 0);
+								});
+							}
+							c.addSeries(series.name, values, series.kwArgs).render();
+						}
+					});
+					series.data.fetch(kw);
+				}
+				return render;
+			}, false);
+			if(render){ c.render(); }
+		},
+		destroy: function(){
+			// summary:
+			//		properly destroy the widget
+			this.chart.destroy();
+			this.inherited(arguments);
+		},
+		resize: function(box){
+			// summary:
+			//		Resize the widget.
+			// description:
+			//		Resize the domNode and the widget surface to the dimensions of a box of the following form:
+			//		`{ l: 50, t: 200, w: 300: h: 150 }`
+			//		If no box is provided, resize the surface to the marginBox of the domNode.
+			// box:
+			//		If passed, denotes the new size of the widget.
+			this.chart.resize.apply(this.chart, arguments);
+		}
+	});
+	return has("dojo-bidi")? declare("dojox.charting.widget.Chart", [Chart, BidiChart]) : Chart;
 });
diff --git a/dojox/charting/widget/Chart2D.js b/dojox/charting/widget/Chart2D.js
index 2e37762..421430e 100644
--- a/dojox/charting/widget/Chart2D.js
+++ b/dojox/charting/widget/Chart2D.js
@@ -1,6 +1,6 @@
-define(["dojo/_base/kernel", "./Chart", "../Chart2D",
+define(["dojo/_base/kernel", "dojo/_base/lang", "./Chart", "../Chart2D",
 	"../action2d/Highlight", "../action2d/Magnify", 
-	"../action2d/MoveSlice", "../action2d/Shake", "../action2d/Tooltip"], function(dojo, Chart) {
-	dojo.deprecated("dojox.charting.widget.Chart2D", "Use dojo.charting.widget.Chart instead and require all other components explicitly", "2.0");
-	return dojox.charting.widget.Chart2D = Chart;
+	"../action2d/MoveSlice", "../action2d/Shake", "../action2d/Tooltip"], function(kernel, lang, Chart) {
+	kernel.deprecated("dojox.charting.widget.Chart2D", "Use dojo.charting.widget.Chart instead and require all other components explicitly", "2.0");
+	return lang.setObject("dojox.charting.widget.Chart2D", Chart);
 });
diff --git a/dojox/charting/widget/Legend.js b/dojox/charting/widget/Legend.js
index f358749..92e1769 100644
--- a/dojox/charting/widget/Legend.js
+++ b/dojox/charting/widget/Legend.js
@@ -1,27 +1,22 @@
-define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/declare", "dijit/_Widget", "dojox/gfx","dojo/_base/array", 
-		"dojox/lang/functional", "dojox/lang/functional/array", "dojox/lang/functional/fold",
-		"dojo/dom", "dojo/dom-construct", "dojo/dom-class","dijit/_base/manager"], 
-		function(lang, html, declare, Widget, gfx, arrayUtil, df, dfa, dff, 
-				dom, domFactory, domClass, widgetManager){
-/*=====
-var Widget = dijit._Widget;
-=====*/
+define(["dojo/_base/declare", "dijit/_WidgetBase", "dojox/gfx","dojo/_base/array", "dojo/has", "dojo/has!dojo-bidi?../bidi/widget/Legend",
+		"dojox/lang/functional", "dojo/dom", "dojo/dom-construct", "dojo/dom-class","dijit/registry"],
+		function(declare, _WidgetBase, gfx, arr, has, BidiLegend, df,
+				dom, domConstruct, domClass, registry){
 
-	var REVERSED_SERIES = /\.(StackedColumns|StackedAreas|ClusteredBars)$/;
-
-	return declare("dojox.charting.widget.Legend", Widget, {
-		// summary: A legend for a chart. A legend contains summary labels for
-		// each series of data contained in the chart.
-		//
-		// Set the horizontal attribute to boolean false to layout legend labels vertically.
-		// Set the horizontal attribute to a number to layout legend labels in horizontal
-		// rows each containing that number of labels (except possibly the last row).
-		//
-		// (Line or Scatter charts (colored lines with shape symbols) )
-		// -o- Series1		-X- Series2		-v- Series3
-		//
-		// (Area/Bar/Pie charts (letters represent colors))
-		// [a] Series1		[b] Series2		[c] Series3
+	var Legend = declare(has("dojo-bidi")? "dojox.charting.widget.NonBidiLegend" : "dojox.charting.widget.Legend", _WidgetBase, {
+		// summary:
+		//		A legend for a chart. A legend contains summary labels for
+		//		each series of data contained in the chart.
+		//		
+		//		Set the horizontal attribute to boolean false to layout legend labels vertically.
+		//		Set the horizontal attribute to a number to layout legend labels in horizontal
+		//		rows each containing that number of labels (except possibly the last row).
+		//		
+		//		(Line or Scatter charts (colored lines with shape symbols) )
+		//		-o- Series1		-X- Series2		-v- Series3
+		//		
+		//		(Area/Bar/Pie charts (letters represent colors))
+		//		[a] Series1		[b] Series2		[c] Series3
 
 		chartRef:   "",
 		horizontal: true,
@@ -30,53 +25,54 @@ var Widget = dijit._Widget;
 		legendBody: null,
 
 		postCreate: function(){
-			if(!this.chart){
-				if(!this.chartRef){ return; }
-				this.chart = widgetManager.byId(this.chartRef);
+			if(!this.chart && this.chartRef){
+				this.chart = registry.byId(this.chartRef) || registry.byNode(dom.byId(this.chartRef));
 				if(!this.chart){
-					var node = dom.byId(this.chartRef);
-					if(node){
-						this.chart = widgetManager.byNode(node);
-					}else{
-						console.log("Could not find chart instance with id: " + this.chartRef);
-						return;
-					}
+					console.log("Could not find chart instance with id: " + this.chartRef);
 				}
-				this.series = this.chart.chart.series;
-			}else{
-				this.series = this.chart.series;
 			}
-
+			// we want original chart
+			this.chart = this.chart.chart || this.chart;
 			this.refresh();
 		},
 		buildRendering: function(){
-			this.domNode = domFactory.create("table",
+			this.domNode = domConstruct.create("table",
 					{role: "group", "aria-label": "chart legend", "class": "dojoxLegendNode"});
-			this.legendBody = domFactory.create("tbody", null, this.domNode);
+			this.legendBody = domConstruct.create("tbody", null, this.domNode);
+			this.inherited(arguments);
+		},
+		destroy: function(){
+			if(this._surfaces){
+				arr.forEach(this._surfaces, function(surface){
+					surface.destroy();
+				});
+			}
 			this.inherited(arguments);
 		},
 		refresh: function(){
-			// summary: regenerates the legend to reflect changes to the chart
+			// summary:
+			//		regenerates the legend to reflect changes to the chart
 
 			// cleanup
 			if(this._surfaces){
-				arrayUtil.forEach(this._surfaces, function(surface){
+				arr.forEach(this._surfaces, function(surface){
 					surface.destroy();
 				});
 			}
 			this._surfaces = [];
 			while(this.legendBody.lastChild){
-				domFactory.destroy(this.legendBody.lastChild);
+				domConstruct.destroy(this.legendBody.lastChild);
 			}
 
 			if(this.horizontal){
 				domClass.add(this.domNode, "dojoxLegendHorizontal");
 				// make a container <tr>
-				this._tr = domFactory.create("tr", null, this.legendBody);
+				this._tr = domConstruct.create("tr", null, this.legendBody);
 				this._inrow = 0;
 			}
 
-			var s = this.series;
+			// keep trying to reach this.series for compatibility reasons in case the user set them, but could be removed
+			var s = this.series || this.chart.series;
 			if(s.length == 0){
 				return;
 			}
@@ -84,33 +80,27 @@ var Widget = dijit._Widget;
 				var t = s[0].chart.stack[0];
 				if(typeof t.run.data[0] == "number"){
 					var filteredRun = df.map(t.run.data, "Math.max(x, 0)");
-					if(df.every(filteredRun, "<= 0")){
-						return;
-					}
 					var slices = df.map(filteredRun, "/this", df.foldl(filteredRun, "+", 0));
-					arrayUtil.forEach(slices, function(x, i){
+					arr.forEach(slices, function(x, i){
 						this._addLabel(t.dyn[i], t._getLabel(x * 100) + "%");
 					}, this);
 				}else{
-					arrayUtil.forEach(t.run.data, function(x, i){
+					arr.forEach(t.run.data, function(x, i){
 						this._addLabel(t.dyn[i], x.legend || x.text || x.y);
 					}, this);
 				}
 			}else{
-				if(this._isReversal()){
-					s = s.slice(0).reverse();
-				}
-				arrayUtil.forEach(s, function(x){
+				arr.forEach(s, function(x){
 					this._addLabel(x.dyn, x.legend || x.name);
 				}, this);
 			}
 		},
 		_addLabel: function(dyn, label){
 			// create necessary elements
-			var wrapper = domFactory.create("td"),
-				icon = domFactory.create("div", null, wrapper),
-				text = domFactory.create("label", null, wrapper),
-				div  = domFactory.create("div", {
+			var wrapper = domConstruct.create("td"),
+				icon = domConstruct.create("div", null, wrapper),
+				text = domConstruct.create("label", null, wrapper),
+				div  = domConstruct.create("div", {
 					style: {
 						"width": this.swatchSize + "px",
 						"height":this.swatchSize + "px",
@@ -125,19 +115,21 @@ var Widget = dijit._Widget;
 				this._tr.appendChild(wrapper);
 				if(++this._inrow === this.horizontal){
 					// make a fresh container <tr>
-					this._tr = domFactory.create("tr", null, this.legendBody);
+					this._tr = domConstruct.create("tr", null, this.legendBody);
 					this._inrow = 0;
 				}
 			}else{
 				// vertical
-				var tr = domFactory.create("tr", null, this.legendBody);
+				var tr = domConstruct.create("tr", null, this.legendBody);
 				tr.appendChild(wrapper);
 			}
 
 			// populate the skeleton
 			this._makeIcon(div, dyn);
 			text.innerHTML = String(label);
-			text.dir = this.getTextDir(label, text.dir);
+			if(has("dojo-bidi")){
+				text.dir = this.getTextDir(label, text.dir);
+			}
 		},
 		_makeIcon: function(div, dyn){
 			var mb = { h: this.swatchSize, w: this.swatchSize };
@@ -156,13 +148,8 @@ var Widget = dijit._Widget;
 				if(dyn.marker){
 					// draw marker on top
 					var c = {x: mb.w / 2, y: mb.h / 2};
-					if(dyn.stroke){
-						surface.createPath({path: "M" + c.x + " " + c.y + " " + dyn.marker}).
-							setFill(dyn.stroke.color).setStroke(dyn.stroke);
-					}else{
-						surface.createPath({path: "M" + c.x + " " + c.y + " " + dyn.marker}).
-							setFill(dyn.color).setStroke(dyn.color);
-					}
+					surface.createPath({path: "M" + c.x + " " + c.y + " " + dyn.marker}).
+						setFill(dyn.markerFill).setStroke(dyn.markerStroke);
 				}
 			}else{
 				// nothing
@@ -171,11 +158,8 @@ var Widget = dijit._Widget;
 				surface.createLine({x1: 2, y1: 2, x2: mb.w - 2, y2: mb.h - 2}).setStroke("black");
 				surface.createLine({x1: 2, y1: mb.h - 2, x2: mb.w - 2, y2: 2}).setStroke("black");
 			}
-		},
-		_isReversal: function(){
-			return (!this.horizontal) && arrayUtil.some(this.chart.stack, function(item){
-				return REVERSED_SERIES.test(item.declaredClass);
-			});
 		}
 	});
+	return has("dojo-bidi")? declare("dojox.charting.widget.Legend", [Legend, BidiLegend]) : Legend;
+	
 });
diff --git a/dojox/charting/widget/SelectableLegend.js b/dojox/charting/widget/SelectableLegend.js
index 490e189..11e0122 100644
--- a/dojox/charting/widget/SelectableLegend.js
+++ b/dojox/charting/widget/SelectableLegend.js
@@ -1,16 +1,16 @@
-define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/query", "dojo/_base/html", 
+define(["dojo/_base/array", "dojo/_base/declare", "dojo/query",
 		"dojo/_base/connect", "dojo/_base/Color", "./Legend", "dijit/form/CheckBox", "../action2d/Highlight",
-		"dojox/lang/functional", "dojox/gfx/fx", "dojo/keys", "dojo/_base/event", "dojo/dom-construct",
+		"dojox/lang/functional", "dojox/gfx/fx", "dojo/keys", "dojo/dom-construct",
 		"dojo/dom-prop"], 
-	function(lang, arrayUtil, declare, query, html, hub, Color, Legend, CheckBox, 
-			 Highlight, df, fx, keys, event, dom, domProp){
-/*=====
-var Legend = dojox.charting.widget.Legend;
-=====*/
+	function(arrayUtil, declare, query, hub, Color, Legend, CheckBox,
+			 Highlight, df, fx, keys, dom, domProp){
+
 	var FocusManager = declare(null, {
-		//	summary:
+		// summary:
 		//		It will take legend as a tab stop, and using
 		//		cursor keys to navigate labels within the legend.
+		// tags:
+		//		private
 		constructor: function(legend){
 			this.legend = legend;
 			this.index = 0;
@@ -80,8 +80,8 @@ var Legend = dojox.charting.widget.Legend;
 		}
 	});
 			
-	declare("dojox.charting.widget.SelectableLegend", Legend, {
-		//	summary:
+	var SelectableLegend = declare("dojox.charting.widget.SelectableLegend", Legend, {
+		// summary:
 		//		An enhanced chart legend supporting interactive events on data series
 		
 		//	theme component
@@ -92,14 +92,22 @@ var Legend = dojox.charting.widget.Legend;
 		postCreate: function(){
 			this.legends = [];
 			this.legendAnim = {};
+			this._cbs = [];
 			this.inherited(arguments);
 		},
 		refresh: function(){
 			this.legends = [];
+			this._clearLabels();
 			this.inherited(arguments);
 			this._applyEvents();
 			new FocusManager(this);
 		},
+		_clearLabels: function(){
+			var cbs = this._cbs;
+			while(cbs.length){
+				cbs.pop().destroyRecursive();
+			}
+		},
 		_addLabel: function(dyn, label){
 			this.inherited(arguments);
 			//	create checkbox
@@ -107,15 +115,17 @@ var Legend = dojox.charting.widget.Legend;
 			var currentLegendNode = legendNodes[legendNodes.length - 1];
 			this.legends.push(currentLegendNode);
 			var checkbox = new CheckBox({checked: true});
+			this._cbs.push(checkbox);
 			dom.place(checkbox.domNode, currentLegendNode, "first");
 			// connect checkbox and existed label
-			var label = query("label", currentLegendNode)[0];
-			domProp.set(label, "for", checkbox.id);
+			var clabel = query("label", currentLegendNode)[0];
+			domProp.set(clabel, "for", checkbox.id);
 		},
 		_applyEvents: function(){
 			// summary:
 			//		Apply click-event on checkbox and hover-event on legend icon,
 			//		highlight data series or toggle it.
+			
 			// if the chart has not yet been refreshed it will crash here (targetData.group == null)
 			if(this.chart.dirty){
 				return;
@@ -209,6 +219,9 @@ var Legend = dojox.charting.widget.Legend;
 		_getAnim: function(plotName){
 			if(!this.legendAnim[plotName]){
 				this.legendAnim[plotName] = new Highlight(this.chart, plotName);
+				// calling this is marking the plot dirty however here this is a "fake" highlight action
+				// we don't want to re-render the chart, _highlight is the in charge of running the animation
+				this.chart.getPlot(plotName).dirty = false;
 			}
 			return this.legendAnim[plotName];
 		},
@@ -221,16 +234,21 @@ var Legend = dojox.charting.widget.Legend;
 			return null;
 		},
 		_getFilledShape: function(shapes){
-			//	summary:
+			// summary:
 			//		Get filled shape in legend icon which would be highlighted when hovered
 			var i = 0;
 			while(shapes[i]){
 				if(shapes[i].getFill())return shapes[i];
 				i++;
 			}
+			return null;
 		},
 		_isPie: function(){
 			return this.chart.stack[0].declaredClass == "dojox.charting.plot2d.Pie";
+		},
+		destroy: function(){
+			this._clearLabels();
+			this.inherited(arguments);
 		}
 	});
 	
@@ -240,5 +258,5 @@ var Legend = dojox.charting.widget.Legend;
 		return "on" + type;
 	}
 
-	return dojox.charting.widget.SelectableLegend;
+	return SelectableLegend;
 });
diff --git a/dojox/charting/widget/Sparkline.js b/dojox/charting/widget/Sparkline.js
index 9466ccd..54dee5a 100644
--- a/dojox/charting/widget/Sparkline.js
+++ b/dojox/charting/widget/Sparkline.js
@@ -1,58 +1,54 @@
-define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/_base/html", "dojo/query", 
-	"./Chart", "../themes/GreySkies", "../plot2d/Lines", "dojo/dom-prop"], 
-	function(lang, arrayUtil, declare, html, query, Chart, GreySkies, Lines, domProp){
-/*=====
-var Chart = dojox.charting.widget.Chart;
-=====*/
+define(["dojo/_base/array", "dojo/_base/declare", "dojo/query",
+	"./Chart", "../themes/GreySkies", "../plot2d/Lines", "dojo/dom-prop"],
+	function(arrayUtil, declare, query, Chart, GreySkies, Lines, domProp){
 
 	declare("dojox.charting.widget.Sparkline", Chart, {
-			theme: GreySkies,
-			margins: { l: 0, r: 0, t: 0, b: 0 },
-			type: "Lines",
-			valueFn: "Number(x)",
-			store: "",
-			field: "",
-			query: "",
-			queryOptions: "",
-			start: "0",
-			count: "Infinity",
-			sort: "",
-			data: "",
-			name: "default",
-			buildRendering: function(){
-				var n = this.srcNodeRef;
-				if(	!n.childNodes.length || // shortcut the query
-					!query("> .axis, > .plot, > .action, > .series", n).length){
-					var plot = document.createElement("div");
-					domProp.set(plot, {
-						"class": "plot",
-						"name": "default",
-						"type": this.type
-					});
-					n.appendChild(plot);
+		theme: GreySkies,
+		margins: { l: 0, r: 0, t: 0, b: 0 },
+		type: "Lines",
+		valueFn: "Number(x)",
+		store: "",
+		field: "",
+		query: "",
+		queryOptions: "",
+		start: "0",
+		count: "Infinity",
+		sort: "",
+		data: "",
+		name: "default",
+		buildRendering: function(){
+			var n = this.srcNodeRef;
+			if(	!n.childNodes.length || // shortcut the query
+				!query("> .axis, > .plot, > .action, > .series", n).length){
+				var plot = document.createElement("div");
+				domProp.set(plot, {
+					"class": "plot",
+					"name": "default",
+					"type": this.type
+				});
+				n.appendChild(plot);
 
-					var series = document.createElement("div");
-					domProp.set(series, {
-						"class": "series",
-						plot: "default",
-						name: this.name,
-						start: this.start,
-						count: this.count,
-						valueFn: this.valueFn
-					});
-					arrayUtil.forEach(
-						["store", "field", "query", "queryOptions", "sort", "data"],
-						function(i){
-							if(this[i].length){
-								domProp.set(series, i, this[i]);
-							}
-						},
-						this
-					);
-					n.appendChild(series);
-				}
-				this.inherited(arguments);
+				var series = document.createElement("div");
+				domProp.set(series, {
+					"class": "series",
+					plot: "default",
+					name: this.name,
+					start: this.start,
+					count: this.count,
+					valueFn: this.valueFn
+				});
+				arrayUtil.forEach(
+					["store", "field", "query", "queryOptions", "sort", "data"],
+					function(i){
+						if(this[i].length){
+							domProp.set(series, i, this[i]);
+						}
+					},
+					this
+				);
+				n.appendChild(series);
 			}
+			this.inherited(arguments);
 		}
-	);
+	});
 });
diff --git a/dojox/collections.js b/dojox/collections.js
index c7f14c5..0797b99 100644
--- a/dojox/collections.js
+++ b/dojox/collections.js
@@ -1,3 +1,9 @@
 define(["./collections/_base"], function(collections){
-	return collections;
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/collections modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/	return collections;
 });
diff --git a/dojox/collections/ArrayList.js b/dojox/collections/ArrayList.js
index 915fae7..453aaf0 100644
--- a/dojox/collections/ArrayList.js
+++ b/dojox/collections/ArrayList.js
@@ -1,22 +1,20 @@
 define(["dojo/_base/kernel", "dojo/_base/array", "./_base"], function(dojo, darray, dxc){
-/*=====
-var dxc = dojox.collections;
-=====*/
-	dxc.ArrayList=function(/* array? */arr){
-		//	summary
-		//	Returns a new object of type dojox.collections.ArrayList
+
+	dxc.ArrayList=function(/*array?*/ arr){
+		// summary:
+		//		Returns a new object of type dojox.collections.ArrayList
 		var items=[];
 		if(arr) items=items.concat(arr);
 		this.count=items.length;
-		this.add=function(/* object */obj){
-			//	summary
-			//	Add an element to the collection.
+		this.add=function(/*object*/ obj){
+			// summary:
+			//		Add an element to the collection.
 			items.push(obj);
 			this.count=items.length;
 		};
-		this.addRange=function(/* array */a){
-			//	summary
-			//	Add a range of objects to the ArrayList
+		this.addRange=function(/*array*/ a){
+			// summary:
+			//		Add a range of objects to the ArrayList
 			if(a.getIterator){
 				var e=a.getIterator();
 				while(!e.atEnd()){
@@ -31,19 +29,19 @@ var dxc = dojox.collections;
 			}
 		};
 		this.clear=function(){
-			//	summary
-			//	Clear all elements out of the collection, and reset the count.
+			// summary:
+			//		Clear all elements out of the collection, and reset the count.
 			items.splice(0, items.length);
 			this.count=0;
 		};
 		this.clone=function(){
-			//	summary
-			//	Clone the array list
+			// summary:
+			//		Clone the array list
 			return new dxc.ArrayList(items);	//	dojox.collections.ArrayList
 		};
-		this.contains=function(/* object */obj){
-			//	summary
-			//	Check to see if the passed object is a member in the ArrayList
+		this.contains=function(/*object*/ obj){
+			// summary:
+			//		Check to see if the passed object is a member in the ArrayList
 			for(var i=0; i < items.length; i++){
 				if(items[i] == obj) {
 					return true;	//	bool
@@ -51,19 +49,19 @@ var dxc = dojox.collections;
 			}
 			return false;	//	bool
 		};
-		this.forEach=function(/* function */ fn, /* object? */ scope){
-			//	summary
-			//	functional iterator, following the mozilla spec.
+		this.forEach=function(/*function*/ fn, /*object?*/ scope){
+			// summary:
+			//		functional iterator, following the mozilla spec.
 			dojo.forEach(items, fn, scope);
 		};
 		this.getIterator=function(){
-			//	summary
-			//	Get an Iterator for this object
+			// summary:
+			//		Get an Iterator for this object
 			return new dxc.Iterator(items);	//	dojox.collections.Iterator
 		};
-		this.indexOf=function(/* object */obj){
-			//	summary
-			//	Return the numeric index of the passed object; will return -1 if not found.
+		this.indexOf=function(/*object*/ obj){
+			// summary:
+			//		Return the numeric index of the passed object; will return -1 if not found.
 			for(var i=0; i < items.length; i++){
 				if(items[i] == obj) {
 					return i;	//	int
@@ -71,60 +69,60 @@ var dxc = dojox.collections;
 			}
 			return -1;	// int
 		};
-		this.insert=function(/* int */ i, /* object */ obj){
-			//	summary
-			//	Insert the passed object at index i
+		this.insert=function(/*int*/ i, /*object*/ obj){
+			// summary:
+			//		Insert the passed object at index i
 			items.splice(i,0,obj);
 			this.count=items.length;
 		};
-		this.item=function(/* int */ i){
-			//	summary
-			//	return the element at index i
+		this.item=function(/*int*/ i){
+			// summary:
+			//		return the element at index i
 			return items[i];	//	object
 		};
-		this.remove=function(/* object */obj){
-			//	summary
-			//	Look for the passed object, and if found, remove it from the internal array.
+		this.remove=function(/*object*/ obj){
+			// summary:
+			//		Look for the passed object, and if found, remove it from the internal array.
 			var i=this.indexOf(obj);
 			if(i >=0) {
 				items.splice(i,1);
 			}
 			this.count=items.length;
 		};
-		this.removeAt=function(/* int */ i){
-			//	summary
-			//	return an array with function applied to all elements
+		this.removeAt=function(/*int*/ i){
+			// summary:
+			//		Remove the element located at the given index.
 			items.splice(i,1);
 			this.count=items.length;
 		};
 		this.reverse=function(){
-			//	summary
-			//	Reverse the internal array
+			// summary:
+			//		Reverse the internal array
 			items.reverse();
 		};
-		this.sort=function(/* function? */ fn){
-			//	summary
-			//	sort the internal array
+		this.sort=function(/*function?*/ fn){
+			// summary:
+			//		sort the internal array
 			if(fn){
 				items.sort(fn);
 			}else{
 				items.sort();
 			}
 		};
-		this.setByIndex=function(/* int */ i, /* object */ obj){
-			//	summary
-			//	Set an element in the array by the passed index.
+		this.setByIndex=function(/*int*/ i, /*object*/ obj){
+			// summary:
+			//		Set an element in the array by the passed index.
 			items[i]=obj;
 			this.count=items.length;
 		};
 		this.toArray=function(){
-			//	summary
-			//	Return a new array with all of the items of the internal array concatenated.
+			// summary:
+			//		Return a new array with all of the items of the internal array concatenated.
 			return [].concat(items);
-		}
-		this.toString=function(/* string */ delim){
-			//	summary
-			//	implementation of toString, follows [].toString();
+		};
+		this.toString=function(/*string*/ delim){
+			// summary:
+			//		implementation of toString, follows [].toString();
 			return items.join((delim||","));
 		};
 	};
diff --git a/dojox/collections/BinaryTree.js b/dojox/collections/BinaryTree.js
index 08638d4..c3efa42 100644
--- a/dojox/collections/BinaryTree.js
+++ b/dojox/collections/BinaryTree.js
@@ -1,7 +1,5 @@
 define(["dojo/_base/kernel", "dojo/_base/array", "./_base"], function(dojo, darray, dxc){
-/*=====
-var dxc = dojox.collections;
-=====*/
+
 	dxc.BinaryTree=function(data){
 		function node(data, rnode, lnode){
 			this.value=data||null;
diff --git a/dojox/collections/Dictionary.js b/dojox/collections/Dictionary.js
index 1332a15..e687c0f 100644
--- a/dojox/collections/Dictionary.js
+++ b/dojox/collections/Dictionary.js
@@ -1,19 +1,17 @@
 define(["dojo/_base/kernel", "dojo/_base/array", "./_base"], function(dojo, darray, dxc){
-/*=====
-var dxc = dojox.collections;
-=====*/
-	dxc.Dictionary=function(/* dojox.collections.Dictionary? */dictionary){
-		//	summary
-		//	Returns an object of type dojox.collections.Dictionary
+
+	dxc.Dictionary=function(/*dojox.collections.Dictionary?*/ dictionary){
+		// summary:
+		//		Returns an object of type dojox.collections.Dictionary
 		var items={};
 		this.count=0;
 
 		//	comparator for property addition and access.
 		var testObject={};
 
-		this.add=function(/* string */k, /* object */v){
-			//	summary
-			//	Add a new item to the Dictionary.
+		this.add=function(/*string*/ k, /*object*/ v){
+			// summary:
+			//		Add a new item to the Dictionary.
 			var b=(k in items);
 			items[k]=new dxc.DictionaryEntry(k,v);
 			if(!b){
@@ -21,27 +19,27 @@ var dxc = dojox.collections;
 			}
 		};
 		this.clear=function(){
-			//	summary
-			//	Clears the internal dictionary.
+			// summary:
+			//		Clears the internal dictionary.
 			items={};
 			this.count=0;
 		};
 		this.clone=function(){
-			//	summary
-			//	Returns a new instance of dojox.collections.Dictionary; note the the dictionary is a clone but items might not be.
+			// summary:
+			//		Returns a new instance of dojox.collections.Dictionary; note the the dictionary is a clone but items might not be.
 			return new dxc.Dictionary(this);	//	dojox.collections.Dictionary
 		};
-		this.contains=this.containsKey=function(/* string */k){
-			//	summary
-			//	Check to see if the dictionary has an entry at key "k".
+		this.contains=this.containsKey=function(/*string*/ k){
+			// summary:
+			//		Check to see if the dictionary has an entry at key "k".
 			if(testObject[k]){
 				return false;			// bool
 			}
 			return (items[k]!=null);	//	bool
 		};
-		this.containsValue=function(/* object */v){
-			//	summary
-			//	Check to see if the dictionary has an entry with value "v".
+		this.containsValue=function(/*object*/ v){
+			// summary:
+			//		Check to see if the dictionary has an entry with value "v".
 			var e=this.getIterator();
 			while(e.get()){
 				if(e.element.value==v){
@@ -50,14 +48,14 @@ var dxc = dojox.collections;
 			}
 			return false;	//	bool
 		};
-		this.entry=function(/* string */k){
-			//	summary
-			//	Accessor method; similar to dojox.collections.Dictionary.item but returns the actual Entry object.
+		this.entry=function(/*string*/ k){
+			// summary:
+			//		Accessor method; similar to dojox.collections.Dictionary.item but returns the actual Entry object.
 			return items[k];	//	dojox.collections.DictionaryEntry
 		};
-		this.forEach=function(/* function */ fn, /* object? */ scope){
-			//	summary
-			//	functional iterator, following the mozilla spec.
+		this.forEach=function(/*function*/ fn, /*object?*/ scope){
+			// summary:
+			//		functional iterator, following the mozilla spec.
 			var a=[];	//	Create an indexing array
 			for(var p in items) {
 				if(!testObject[p]){
@@ -67,35 +65,35 @@ var dxc = dojox.collections;
 			dojo.forEach(a, fn, scope);
 		};
 		this.getKeyList=function(){
-			//	summary
-			//	Returns an array of the keys in the dictionary.
+			// summary:
+			//		Returns an array of the keys in the dictionary.
 			return (this.getIterator()).map(function(entry){
 				return entry.key;
 			});	//	array
 		};
 		this.getValueList=function(){
-			//	summary
-			//	Returns an array of the values in the dictionary.
+			// summary:
+			//		Returns an array of the values in the dictionary.
 			return (this.getIterator()).map(function(entry){
 				return entry.value;
 			});	//	array
 		};
-		this.item=function(/* string */k){
-			//	summary
-			//	Accessor method.
+		this.item=function(/*string*/ k){
+			// summary:
+			//		Accessor method.
 			if(k in items){
 				return items[k].valueOf();	//	object
 			}
 			return undefined;	//	object
 		};
 		this.getIterator=function(){
-			//	summary
-			//	Gets a dojox.collections.DictionaryIterator for iteration purposes.
+			// summary:
+			//		Gets a dojox.collections.DictionaryIterator for iteration purposes.
 			return new dxc.DictionaryIterator(items);	//	dojox.collections.DictionaryIterator
 		};
-		this.remove=function(/* string */k){
-			//	summary
-			//	Removes the item at k from the internal collection.
+		this.remove=function(/*string*/ k){
+			// summary:
+			//		Removes the item at k from the internal collection.
 			if(k in items && !testObject[k]){
 				delete items[k];
 				this.count--;
diff --git a/dojox/collections/Queue.js b/dojox/collections/Queue.js
index 3394162..80e2e97 100644
--- a/dojox/collections/Queue.js
+++ b/dojox/collections/Queue.js
@@ -1,29 +1,27 @@
 define(["dojo/_base/kernel", "dojo/_base/array", "./_base"], function(dojo, darray, dxc){
-/*=====
-var dxc = dojox.collections;
-=====*/
-	dxc.Queue=function(/* array? */arr){
-		//	summary
-		//	return an object of type dojox.collections.Queue
+
+	dxc.Queue=function(/*array?*/ arr){
+		// summary:
+		//		return an object of type dojox.collections.Queue
 		var q=[];
 		if (arr){
 			q=q.concat(arr);
 		}
 		this.count=q.length;
 		this.clear=function(){
-			//	summary
-			//	clears the internal collection
+			// summary:
+			//		clears the internal collection
 			q=[];
 			this.count=q.length;
 		};
 		this.clone=function(){
-			//	summary
-			//	creates a new Queue based on this one
+			// summary:
+			//		creates a new Queue based on this one
 			return new dxc.Queue(q);	//	dojox.collections.Queue
 		};
-		this.contains=function(/* object */ o){
-			//	summary
-			//	Check to see if the passed object is an element in this queue
+		this.contains=function(/*object*/ o){
+			// summary:
+			//		Check to see if the passed object is an element in this queue
 			for(var i=0; i<q.length; i++){
 				if (q[i]==o){
 					return true;	//	bool
@@ -31,41 +29,41 @@ var dxc = dojox.collections;
 			}
 			return false;	//	bool
 		};
-		this.copyTo=function(/* array */ arr, /* int */ i){
-			//	summary
-			//	Copy the contents of this queue into the passed array at index i.
+		this.copyTo=function(/*array*/ arr, /*int*/ i){
+			// summary:
+			//		Copy the contents of this queue into the passed array at index i.
 			arr.splice(i,0,q);
 		};
 		this.dequeue=function(){
-			//	summary
-			//	shift the first element off the queue and return it
+			// summary:
+			//		shift the first element off the queue and return it
 			var r=q.shift();
 			this.count=q.length;
 			return r;	//	object
 		};
-		this.enqueue=function(/* object */ o){
-			//	summary
-			//	put the passed object at the end of the queue
+		this.enqueue=function(/*object*/ o){
+			// summary:
+			//		put the passed object at the end of the queue
 			this.count=q.push(o);
 		};
-		this.forEach=function(/* function */ fn, /* object? */ scope){
-			//	summary
-			//	functional iterator, following the mozilla spec.
+		this.forEach=function(/*function*/ fn, /*object?*/ scope){
+			// summary:
+			//		functional iterator, following the mozilla spec.
 			dojo.forEach(q, fn, scope);
 		};
 		this.getIterator=function(){
-			//	summary
-			//	get an Iterator based on this queue.
+			// summary:
+			//		get an Iterator based on this queue.
 			return new dxc.Iterator(q);	//	dojox.collections.Iterator
 		};
 		this.peek=function(){
-			//	summary
-			//	get the next element in the queue without altering the queue.
+			// summary:
+			//		get the next element in the queue without altering the queue.
 			return q[0];
 		};
 		this.toArray=function(){
-			//	summary
-			//	return an array based on the internal array of the queue.
+			// summary:
+			//		return an array based on the internal array of the queue.
 			return [].concat(q);
 		};
 	};
diff --git a/dojox/collections/Set.js b/dojox/collections/Set.js
index 66ac982..08ce14d 100644
--- a/dojox/collections/Set.js
+++ b/dojox/collections/Set.js
@@ -1,7 +1,5 @@
 define(["./_base", "./ArrayList"], function(dxc, ArrayList){
-/*=====
-var dxc = dojox.collections;
-=====*/
+
 	dxc.Set=new (function(){
 		function conv(arr){
 			if(arr.constructor==Array){
@@ -9,9 +7,9 @@ var dxc = dojox.collections;
 			}
 			return arr;		//	dojox.collections.ArrayList
 		}
-		this.union = function(/* array */setA, /* array */setB){
-			//	summary
-			//	Return the union of the two passed sets.
+		this.union = function(/*array*/ setA, /*array*/ setB){
+			// summary:
+			//		Return the union of the two passed sets.
 			setA=conv(setA);
 			setB=conv(setB);
 			var result = new ArrayList(setA.toArray());
@@ -24,9 +22,9 @@ var dxc = dojox.collections;
 			}
 			return result;	//	dojox.collections.ArrayList
 		};
-		this.intersection = function(/* array */setA, /* array */setB){
-			//	summary
-			//	Return the intersection of the two passed sets.
+		this.intersection = function(/*array*/ setA, /*array*/ setB){
+			// summary:
+			//		Return the intersection of the two passed sets.
 			setA=conv(setA);
 			setB=conv(setB);
 			var result = new ArrayList();
@@ -39,9 +37,9 @@ var dxc = dojox.collections;
 			}
 			return result;	//	dojox.collections.ArrayList
 		};
-		this.difference = function(/* array */setA, /* array */setB){
-			//	summary
-			//	Returns everything in setA that is not in setB.
+		this.difference = function(/*array*/ setA, /*array*/ setB){
+			// summary:
+			//		Returns everything in setA that is not in setB.
 			setA=conv(setA);
 			setB=conv(setB);
 			var result = new ArrayList();
@@ -54,9 +52,9 @@ var dxc = dojox.collections;
 			}
 			return result;	//	dojox.collections.ArrayList
 		};
-		this.isSubSet = function(/* array */setA, /* array */setB) {
-			//	summary
-			//	Returns if set B is a subset of set A.
+		this.isSubSet = function(/*array*/ setA, /*array*/ setB) {
+			// summary:
+			//		Returns if set B is a subset of set A.
 			setA=conv(setA);
 			setB=conv(setB);
 			var e = setA.getIterator();
@@ -67,9 +65,9 @@ var dxc = dojox.collections;
 			}
 			return true;	//	boolean
 		};
-		this.isSuperSet = function(/* array */setA, /* array */setB){
-			//	summary
-			//	Returns if set B is a superset of set A.
+		this.isSuperSet = function(/*array*/ setA, /*array*/ setB){
+			// summary:
+			//		Returns if set B is a superset of set A.
 			setA=conv(setA);
 			setB=conv(setB);
 			var e = setB.getIterator();
diff --git a/dojox/collections/SortedList.js b/dojox/collections/SortedList.js
index 172dedc..9fc9afc 100644
--- a/dojox/collections/SortedList.js
+++ b/dojox/collections/SortedList.js
@@ -1,11 +1,9 @@
 define(["dojo/_base/kernel", "dojo/_base/array", "./_base"], function(dojo, darray, dxc){
-/*=====
-var dxc = dojox.collections;
-=====*/
-	dxc.SortedList=function(/* object? */ dictionary){
-		//	summary
-		//	creates a collection that acts like a dictionary but is also internally sorted.
-		//	Note that the act of adding any elements forces an internal resort, making this object potentially slow.
+
+	dxc.SortedList=function(/*object?*/ dictionary){
+		// summary:
+		//		creates a collection that acts like a dictionary but is also internally sorted.
+		//		Note that the act of adding any elements forces an internal resort, making this object potentially slow.
 		var _this=this;
 		var items={};
 		var q=[];
@@ -25,9 +23,9 @@ var dxc = dojox.collections;
 		var testObject={};
 
 		this.count=q.length;
-		this.add=function(/* string */ k,/* object */v){
-			//	summary
-			//	add the passed value to the dictionary at location k
+		this.add=function(/*string*/ k,/*object*/ v){
+			// summary:
+			//		add the passed value to the dictionary at location k
 			if (!items[k]) {
 				items[k]=new dxc.DictionaryEntry(k,v);
 				this.count=q.push(items[k]);
@@ -35,28 +33,28 @@ var dxc = dojox.collections;
 			}
 		};
 		this.clear=function(){
-			//	summary
-			//	clear the internal collections
+			// summary:
+			//		clear the internal collections
 			items={};
 			q=[];
 			this.count=q.length;
 		};
 		this.clone=function(){
-			//	summary
-			//	create a clone of this sorted list
+			// summary:
+			//		create a clone of this sorted list
 			return new dxc.SortedList(this);	//	dojox.collections.SortedList
 		};
-		this.contains=this.containsKey=function(/* string */ k){
-			//	summary
-			//	Check to see if the list has a location k
+		this.contains=this.containsKey=function(/*string*/ k){
+			// summary:
+			//		Check to see if the list has a location k
 			if(testObject[k]){
 				return false;			//	bool
 			}
 			return (items[k]!=null);	//	bool
 		};
-		this.containsValue=function(/* object */ o){
-			//	summary
-			//	Check to see if this list contains the passed object
+		this.containsValue=function(/*object*/ o){
+			// summary:
+			//		Check to see if this list contains the passed object
 			var e=this.getIterator();
 			while (!e.atEnd()){
 				var item=e.get();
@@ -66,9 +64,9 @@ var dxc = dojox.collections;
 			}
 			return false;	//	bool
 		};
-		this.copyTo=function(/* array */ arr, /* int */ i){
-			//	summary
-			//	copy the contents of the list into array arr at index i
+		this.copyTo=function(/*array*/ arr, /*int*/ i){
+			// summary:
+			//		copy the contents of the list into array arr at index i
 			var e=this.getIterator();
 			var idx=i;
 			while(!e.atEnd()){
@@ -76,34 +74,34 @@ var dxc = dojox.collections;
 				idx++;
 			}
 		};
-		this.entry=function(/* string */ k){
-			//	summary
-			//	return the object at location k
+		this.entry=function(/*string*/ k){
+			// summary:
+			//		return the object at location k
 			return items[k];	//	dojox.collections.DictionaryEntry
 		};
-		this.forEach=function(/* function */ fn, /* object? */ scope){
-			//	summary
-			//	functional iterator, following the mozilla spec.
+		this.forEach=function(/*function*/ fn, /*object?*/ scope){
+			// summary:
+			//		functional iterator, following the mozilla spec.
 			dojo.forEach(q, fn, scope);
 		};
-		this.getByIndex=function(/* int */ i){
-			//	summary
-			//	return the item at index i
+		this.getByIndex=function(/*int*/ i){
+			// summary:
+			//		return the item at index i
 			return q[i].valueOf();	//	object
 		};
 		this.getIterator=function(){
-			//	summary
-			//	get an iterator for this object
+			// summary:
+			//		get an iterator for this object
 			return new dxc.DictionaryIterator(items);	//	dojox.collections.DictionaryIterator
 		};
-		this.getKey=function(/* int */ i){
-			//	summary
-			//	return the key of the item at index i
+		this.getKey=function(/*int*/ i){
+			// summary:
+			//		return the key of the item at index i
 			return q[i].key;
 		};
 		this.getKeyList=function(){
-			//	summary
-			//	return an array of the keys set in this list
+			// summary:
+			//		return an array of the keys set in this list
 			var arr=[];
 			var e=this.getIterator();
 			while (!e.atEnd()){
@@ -112,8 +110,8 @@ var dxc = dojox.collections;
 			return arr;	//	array
 		};
 		this.getValueList=function(){
-			//	summary
-			//	return an array of values in this list
+			// summary:
+			//		return an array of values in this list
 			var arr=[];
 			var e=this.getIterator();
 			while (!e.atEnd()){
@@ -121,9 +119,9 @@ var dxc = dojox.collections;
 			}
 			return arr;	//	array
 		};
-		this.indexOfKey=function(/* string */ k){
-			//	summary
-			//	return the index of the passed key.
+		this.indexOfKey=function(/*string*/ k){
+			// summary:
+			//		return the index of the passed key.
 			for (var i=0; i<q.length; i++){
 				if (q[i].key==k){
 					return i;	//	int
@@ -131,9 +129,9 @@ var dxc = dojox.collections;
 			}
 			return -1;	//	int
 		};
-		this.indexOfValue=function(/* object */ o){
-			//	summary
-			//	return the first index of object o
+		this.indexOfValue=function(/*object*/ o){
+			// summary:
+			//		return the first index of object o
 			for (var i=0; i<q.length; i++){
 				if (q[i].value==o){
 					return i;	//	int
@@ -141,33 +139,33 @@ var dxc = dojox.collections;
 			}
 			return -1;	//	int
 		};
-		this.item=function(/* string */ k){
-			// 	summary
-			//	return the value of the object at location k.
+		this.item=function(/*string*/ k){
+			// summary:
+			//		return the value of the object at location k.
 			if(k in items && !testObject[k]){
 				return items[k].valueOf();	//	object
 			}
 			return undefined;	//	object
 		};
-		this.remove=function(/* string */k){
-			// 	summary
-			//	remove the item at location k and rebuild the internal collections.
+		this.remove=function(/*string*/ k){
+			// summary:
+			//		remove the item at location k and rebuild the internal collections.
 			delete items[k];
 			build();
 			this.count=q.length;
 		};
-		this.removeAt=function(/* int */ i){
-			//	summary
-			//	remove the item at index i, and rebuild the internal collections.
+		this.removeAt=function(/*int*/ i){
+			// summary:
+			//		remove the item at index i, and rebuild the internal collections.
 			delete items[q[i].key];
 			build();
 			this.count=q.length;
 		};
-		this.replace=function(/* string */ k, /* object */ v){
-			//	summary
-			//	Replace an existing item if it's there, and add a new one if not.
+		this.replace=function(/*string*/ k, /*object*/ v){
+			// summary:
+			//		Replace an existing item if it's there, and add a new one if not.
 			if (!items[k]){
-				//	we're adding a new object, return false
+				//		we're adding a new object, return false
 				this.add(k,v);
 				return false; // bool
 			}else{
@@ -177,9 +175,9 @@ var dxc = dojox.collections;
 				return true; // bool
 			}
 		};
-		this.setByIndex=function(/* int */ i, /* object */ o){
-			//	summary
-			//	set an item by index
+		this.setByIndex=function(/*int*/ i, /*object*/ o){
+			// summary:
+			//		set an item by index
 			items[q[i].key].value=o;
 			build();
 			this.count=q.length;
diff --git a/dojox/collections/Stack.js b/dojox/collections/Stack.js
index e98e065..8e1a47e 100644
--- a/dojox/collections/Stack.js
+++ b/dojox/collections/Stack.js
@@ -1,27 +1,25 @@
 define(["dojo/_base/kernel", "dojo/_base/array", "./_base"], function(dojo, darray, dxc){
-/*=====
-var dxc = dojox.collections;
-=====*/
-	dxc.Stack=function(/* array? */arr){
-		//	summary
-		//	returns an object of type dojox.collections.Stack
+
+	dxc.Stack=function(/*array?*/ arr){
+		// summary:
+		//		returns an object of type dojox.collections.Stack
 		var q=[];
 		if (arr) q=q.concat(arr);
 		this.count=q.length;
 		this.clear=function(){
-			//	summary
-			//	Clear the internal array and reset the count
+			// summary:
+			//		Clear the internal array and reset the count
 			q=[];
 			this.count=q.length;
 		};
 		this.clone=function(){
-			//	summary
-			//	Create and return a clone of this Stack
+			// summary:
+			//		Create and return a clone of this Stack
 			return new dxc.Stack(q);
 		};
-		this.contains=function(/* object */o){
-			//	summary
-			//	check to see if the stack contains object o
+		this.contains=function(/*object*/ o){
+			// summary:
+			//		check to see if the stack contains object o
 			for (var i=0; i<q.length; i++){
 				if (q[i] == o){
 					return true;	//	bool
@@ -29,41 +27,41 @@ var dxc = dojox.collections;
 			}
 			return false;	//	bool
 		};
-		this.copyTo=function(/* array */ arr, /* int */ i){
-			//	summary
-			//	copy the stack into array arr at index i
+		this.copyTo=function(/*array*/ arr, /*int*/ i){
+			// summary:
+			//		copy the stack into array arr at index i
 			arr.splice(i,0,q);
 		};
-		this.forEach=function(/* function */ fn, /* object? */ scope){
-			//	summary
-			//	functional iterator, following the mozilla spec.
+		this.forEach=function(/*function*/ fn, /*object?*/ scope){
+			// summary:
+			//		functional iterator, following the mozilla spec.
 			dojo.forEach(q, fn, scope);
 		};
 		this.getIterator=function(){
-			//	summary
-			//	get an iterator for this collection
+			// summary:
+			//		get an iterator for this collection
 			return new dxc.Iterator(q);	//	dojox.collections.Iterator
 		};
 		this.peek=function(){
-			//	summary
-			//	Return the next item without altering the stack itself.
+			// summary:
+			//		Return the next item without altering the stack itself.
 			return q[(q.length-1)];	//	object
 		};
 		this.pop=function(){
-			//	summary
-			//	pop and return the next item on the stack
+			// summary:
+			//		pop and return the next item on the stack
 			var r=q.pop();
 			this.count=q.length;
 			return r;	//	object
 		};
-		this.push=function(/* object */ o){
-			//	summary
-			//	Push object o onto the stack
+		this.push=function(/*object*/ o){
+			// summary:
+			//		Push object o onto the stack
 			this.count=q.push(o);
 		};
 		this.toArray=function(){
-			//	summary
-			//	create and return an array based on the internal collection
+			// summary:
+			//		create and return an array based on the internal collection
 			return [].concat(q);	//	array
 		};
 	};
diff --git a/dojox/collections/_base.js b/dojox/collections/_base.js
index 3e69052..d516786 100644
--- a/dojox/collections/_base.js
+++ b/dojox/collections/_base.js
@@ -2,13 +2,9 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array"],
   function(dojo, lang, arr){
 	var collections = lang.getObject("dojox.collections", true);
 
-/*=====
-	collections = dojox.collections;
-=====*/
-
-	collections.DictionaryEntry=function(/* string */k, /* object */v){
-		//	summary
-		//	return an object of type dojox.collections.DictionaryEntry
+	collections.DictionaryEntry=function(/*string*/ k, /*object*/ v){
+		// summary:
+		//		return an object of type dojox.collections.DictionaryEntry
 		this.key=k;
 		this.value=v;
 		this.valueOf=function(){
@@ -24,33 +20,33 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array"],
 	 *	work with the Collections included in this module.  However, they *can*
 	 *	be used with arrays and objects, respectively, should one choose to do so.
 	 */
-	collections.Iterator=function(/* array */a){
-		//	summary
-		//	return an object of type dojox.collections.Iterator
+	collections.Iterator=function(/*array*/ a){
+		// summary:
+		//		return an object of type dojox.collections.Iterator
 		var position=0;
 		this.element=a[position]||null;
 		this.atEnd=function(){
-			//	summary
-			//	Test to see if the internal cursor has reached the end of the internal collection.
+			// summary:
+			//		Test to see if the internal cursor has reached the end of the internal collection.
 			return (position>=a.length);	//	bool
 		};
 		this.get=function(){
-			//	summary
-			//	Get the next member in the collection.
+			// summary:
+			//		Get the next member in the collection.
 			if(this.atEnd()){
 				return null;		//	object
 			}
 			this.element=a[position++];
 			return this.element;	//	object
 		};
-		this.map=function(/* function */fn, /* object? */scope){
-			//	summary
-			//	Functional iteration with optional scope.
+		this.map=function(/*function*/ fn, /*object?*/ scope){
+			// summary:
+			//		Functional iteration with optional scope.
 			return arr.map(a, fn, scope);
 		};
 		this.reset=function(){
-			//	summary
-			//	reset the internal cursor.
+			// summary:
+			//		reset the internal cursor.
 			position=0;
 			this.element=a[position];
 		};
@@ -61,9 +57,9 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array"],
 	 *	the reality is that you can use this to iterate over a JS object
 	 *	being used as a hashtable.
 	 */
-	collections.DictionaryIterator=function(/* object */obj){
-		//	summary
-		//	return an object of type dojox.collections.DictionaryIterator
+	collections.DictionaryIterator=function(/*object*/ obj){
+		// summary:
+		//		return an object of type dojox.collections.DictionaryIterator
 		var a=[];	//	Create an indexing array
 		var testObject={};
 		for(var p in obj){
@@ -74,27 +70,27 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array"],
 		var position=0;
 		this.element=a[position]||null;
 		this.atEnd=function(){
-			//	summary
-			//	Test to see if the internal cursor has reached the end of the internal collection.
+			// summary:
+			//		Test to see if the internal cursor has reached the end of the internal collection.
 			return (position>=a.length);	//	bool
 		};
 		this.get=function(){
-			//	summary
-			//	Get the next member in the collection.
+			// summary:
+			//		Get the next member in the collection.
 			if(this.atEnd()){
 				return null;		//	object
 			}
 			this.element=a[position++];
 			return this.element;	//	object
 		};
-		this.map=function(/* function */fn, /* object? */scope){
-			//	summary
-			//	Functional iteration with optional scope.
+		this.map=function(/*function*/ fn, /*object?*/ scope){
+			// summary:
+			//		Functional iteration with optional scope.
 			return arr.map(a, fn, scope);
 		};
 		this.reset=function() {
-			//	summary
-			//	reset the internal cursor.
+			// summary:
+			//		reset the internal cursor.
 			position=0;
 			this.element=a[position];
 		};
diff --git a/dojox/color.js b/dojox/color.js
index 12c71e1..a6113ee 100644
--- a/dojox/color.js
+++ b/dojox/color.js
@@ -1,3 +1,10 @@
 define(["./color/_base"], function(dxcolor){
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/color modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
 	return dxcolor;
 });
diff --git a/dojox/color/Colorspace.js b/dojox/color/Colorspace.js
index eb6578f..722c75b 100644
--- a/dojox/color/Colorspace.js
+++ b/dojox/color/Colorspace.js
@@ -1,7 +1,7 @@
-define(["dojo/_base/kernel", "../main", "dojo/_base/lang", "./_base", "dojox/math/matrix"], 
-	function(dojo, dojox, dlang, dxc, dxm){
+define(["./_base", "dojo/_base/lang", "dojox/math/matrix"],
+	function(dcolor, lang, dxm){
 
-dojox.color.Colorspace=new (function(){
+dcolor.Colorspace = new (function(){
 	var self=this;
 	var wpMap={
 		"2":{
@@ -201,98 +201,98 @@ dojox.color.Colorspace=new (function(){
 	};
 	var converters={
 		"CMY":{
-			"CMYK":function(obj, kwArgs){ return dxc.fromCmy(obj).toCmyk(); },
-			"HSL":function(obj, kwArgs){ return dxc.fromCmy(obj).toHsl(); },
-			"HSV":function(obj, kwArgs){ return dxc.fromCmy(obj).toHsv(); },
-			"Lab":function(obj, kwArgs){ return cMaps["XYZ"]["Lab"](dxc.fromCmy(obj).toXYZ(kwArgs)); },
+			"CMYK":function(obj, kwArgs){ return dcolor.fromCmy(obj).toCmyk(); },
+			"HSL":function(obj, kwArgs){ return dcolor.fromCmy(obj).toHsl(); },
+			"HSV":function(obj, kwArgs){ return dcolor.fromCmy(obj).toHsv(); },
+			"Lab":function(obj, kwArgs){ return cMaps["XYZ"]["Lab"](dcolor.fromCmy(obj).toXYZ(kwArgs)); },
 			"LCHab":function(obj, kwArgs){ return cMaps["Lab"]["LCHab"](converters["CMY"]["Lab"](obj)); },
-			"LCHuv":function(obj, kwArgs){ return cMaps["LCHuv"]["Luv"](cMaps["Luv"]["XYZ"](dxc.fromCmy(obj).toXYZ(kwArgs))); },
-			"Luv":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](dxc.fromCmy(obj).toXYZ(kwArgs)); },
-			"RGB":function(obj, kwArgs){ return dxc.fromCmy(obj); },
-			"XYZ":function(obj, kwArgs){ return dxc.fromCmy(obj).toXYZ(kwArgs); },
-			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dxc.fromCmy(obj).toXYZ(kwArgs)); }
+			"LCHuv":function(obj, kwArgs){ return cMaps["LCHuv"]["Luv"](cMaps["Luv"]["XYZ"](dcolor.fromCmy(obj).toXYZ(kwArgs))); },
+			"Luv":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](dcolor.fromCmy(obj).toXYZ(kwArgs)); },
+			"RGB":function(obj, kwArgs){ return dcolor.fromCmy(obj); },
+			"XYZ":function(obj, kwArgs){ return dcolor.fromCmy(obj).toXYZ(kwArgs); },
+			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dcolor.fromCmy(obj).toXYZ(kwArgs)); }
 		},
 		"CMYK":{
-			"CMY":function(obj, kwArgs){ return dxc.fromCmyk(obj).toCmy(); },
-			"HSL":function(obj, kwArgs){ return dxc.fromCmyk(obj).toHsl(); },
-			"HSV":function(obj, kwArgs){ return dxc.fromCmyk(obj).toHsv(); },
-			"Lab":function(obj, kwArgs){ return cMaps["XYZ"]["Lab"](dxc.fromCmyk(obj).toXYZ(kwArgs)); },
+			"CMY":function(obj, kwArgs){ return dcolor.fromCmyk(obj).toCmy(); },
+			"HSL":function(obj, kwArgs){ return dcolor.fromCmyk(obj).toHsl(); },
+			"HSV":function(obj, kwArgs){ return dcolor.fromCmyk(obj).toHsv(); },
+			"Lab":function(obj, kwArgs){ return cMaps["XYZ"]["Lab"](dcolor.fromCmyk(obj).toXYZ(kwArgs)); },
 			"LCHab":function(obj, kwArgs){ return cMaps["Lab"]["LCHab"](converters["CMYK"]["Lab"](obj)); },
-			"LCHuv":function(obj, kwArgs){ return cMaps["LCHuv"]["Luv"](cMaps["Luv"]["XYZ"](dxc.fromCmyk(obj).toXYZ(kwArgs))); },
-			"Luv":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](dxc.fromCmyk(obj).toXYZ(kwArgs)); },
-			"RGB":function(obj, kwArgs){ return dxc.fromCmyk(obj); },
-			"XYZ":function(obj, kwArgs){ return dxc.fromCmyk(obj).toXYZ(kwArgs); },
-			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dxc.fromCmyk(obj).toXYZ(kwArgs)); }
+			"LCHuv":function(obj, kwArgs){ return cMaps["LCHuv"]["Luv"](cMaps["Luv"]["XYZ"](dcolor.fromCmyk(obj).toXYZ(kwArgs))); },
+			"Luv":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](dcolor.fromCmyk(obj).toXYZ(kwArgs)); },
+			"RGB":function(obj, kwArgs){ return dcolor.fromCmyk(obj); },
+			"XYZ":function(obj, kwArgs){ return dcolor.fromCmyk(obj).toXYZ(kwArgs); },
+			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dcolor.fromCmyk(obj).toXYZ(kwArgs)); }
 		},
 		"HSL":{
-			"CMY":function(obj, kwArgs){ return dxc.fromHsl(obj).toCmy(); },
-			"CMYK":function(obj, kwArgs){ return dxc.fromHsl(obj).toCmyk(); },
-			"HSV":function(obj, kwArgs){ return dxc.fromHsl(obj).toHsv(); },
-			"Lab":function(obj, kwArgs){ return cMaps["XYZ"]["Lab"](dxc.fromHsl(obj).toXYZ(kwArgs)); },
+			"CMY":function(obj, kwArgs){ return dcolor.fromHsl(obj).toCmy(); },
+			"CMYK":function(obj, kwArgs){ return dcolor.fromHsl(obj).toCmyk(); },
+			"HSV":function(obj, kwArgs){ return dcolor.fromHsl(obj).toHsv(); },
+			"Lab":function(obj, kwArgs){ return cMaps["XYZ"]["Lab"](dcolor.fromHsl(obj).toXYZ(kwArgs)); },
 			"LCHab":function(obj, kwArgs){ return cMaps["Lab"]["LCHab"](converters["CMYK"]["Lab"](obj)); },
-			"LCHuv":function(obj, kwArgs){ return cMaps["LCHuv"]["Luv"](cMaps["Luv"]["XYZ"](dxc.fromHsl(obj).toXYZ(kwArgs))); },
-			"Luv":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](dxc.fromHsl(obj).toXYZ(kwArgs)); },
-			"RGB":function(obj, kwArgs){ return dxc.fromHsl(obj); },
-			"XYZ":function(obj, kwArgs){ return dxc.fromHsl(obj).toXYZ(kwArgs); },
-			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dxc.fromHsl(obj).toXYZ(kwArgs)); }
+			"LCHuv":function(obj, kwArgs){ return cMaps["LCHuv"]["Luv"](cMaps["Luv"]["XYZ"](dcolor.fromHsl(obj).toXYZ(kwArgs))); },
+			"Luv":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](dcolor.fromHsl(obj).toXYZ(kwArgs)); },
+			"RGB":function(obj, kwArgs){ return dcolor.fromHsl(obj); },
+			"XYZ":function(obj, kwArgs){ return dcolor.fromHsl(obj).toXYZ(kwArgs); },
+			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dcolor.fromHsl(obj).toXYZ(kwArgs)); }
 		},
 		"HSV":{
-			"CMY":function(obj, kwArgs){ return dxc.fromHsv(obj).toCmy(); },
-			"CMYK":function(obj, kwArgs){ return dxc.fromHsv(obj).toCmyk(); },
-			"HSL":function(obj, kwArgs){ return dxc.fromHsv(obj).toHsl(); },
-			"Lab":function(obj, kwArgs){ return cMaps["XYZ"]["Lab"](dxc.fromHsv(obj).toXYZ(kwArgs)); },
+			"CMY":function(obj, kwArgs){ return dcolor.fromHsv(obj).toCmy(); },
+			"CMYK":function(obj, kwArgs){ return dcolor.fromHsv(obj).toCmyk(); },
+			"HSL":function(obj, kwArgs){ return dcolor.fromHsv(obj).toHsl(); },
+			"Lab":function(obj, kwArgs){ return cMaps["XYZ"]["Lab"](dcolor.fromHsv(obj).toXYZ(kwArgs)); },
 			"LCHab":function(obj, kwArgs){ return cMaps["Lab"]["LCHab"](converters["CMYK"]["Lab"](obj)); },
-			"LCHuv":function(obj, kwArgs){ return cMaps["LCHuv"]["Luv"](cMaps["Luv"]["XYZ"](dxc.fromHsv(obj).toXYZ(kwArgs))); },
-			"Luv":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](dxc.fromHsv(obj).toXYZ(kwArgs)); },
-			"RGB":function(obj, kwArgs){ return dxc.fromHsv(obj); },
-			"XYZ":function(obj, kwArgs){ return dxc.fromHsv(obj).toXYZ(kwArgs); },
-			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dxc.fromHsv(obj).toXYZ(kwArgs)); }
+			"LCHuv":function(obj, kwArgs){ return cMaps["LCHuv"]["Luv"](cMaps["Luv"]["XYZ"](dcolor.fromHsv(obj).toXYZ(kwArgs))); },
+			"Luv":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](dcolor.fromHsv(obj).toXYZ(kwArgs)); },
+			"RGB":function(obj, kwArgs){ return dcolor.fromHsv(obj); },
+			"XYZ":function(obj, kwArgs){ return dcolor.fromHsv(obj).toXYZ(kwArgs); },
+			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dcolor.fromHsv(obj).toXYZ(kwArgs)); }
 		},
 		"Lab":{
-			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)).toCmy(); },
-			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)).toCmyk(); },
-			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)).toHsl(); },
-			"HSV":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)).toHsv(); },
+			"CMY":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)).toCmy(); },
+			"CMYK":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)).toCmyk(); },
+			"HSL":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)).toHsl(); },
+			"HSV":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)).toHsv(); },
 			"LCHab":function(obj, kwArgs){ return cMaps["Lab"]["LCHab"](obj, kwArgs); },
 			"LCHuv":function(obj, kwArgs){ return cMaps["Luv"]["LCHuv"](cMaps["Lab"]["XYZ"](obj, kwArgs), kwArgs); },
 			"Luv":function(obj, kwArgs){ return cMaps["XYZ"]["Luv"](cMaps["Lab"]["XYZ"](obj, kwArgs), kwArgs); },
-			"RGB":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)); },
+			"RGB":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)); },
 			"XYZ":function(obj, kwArgs){ return cMaps["Lab"]["XYZ"](obj, kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](cMaps["Lab"]["XYZ"](obj, kwArgs), kwArgs); }
 		},
 		"LCHab":{
-			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs).toCmy(); },
-			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs).toCmyk(); },
-			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs).toHsl(); },
-			"HSV":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs).toHsv(); },
+			"CMY":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs).toCmy(); },
+			"CMYK":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs).toCmyk(); },
+			"HSL":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs).toHsl(); },
+			"HSV":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs).toHsv(); },
 			"Lab":function(obj, kwArgs){ return cMaps["Lab"]["LCHab"](obj, kwArgs); },
 			"LCHuv":function(obj, kwArgs){ return cMaps["Luv"]["LCHuv"](cMaps["XYZ"]["Luv"](cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs), kwArgs);},
 			"Luv":function(obj, kwArgs){ return cMaps["XYZ"]["Luv"](cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs);},
-			"RGB":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs); },
+			"RGB":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs); },
 			"XYZ":function(obj, kwArgs){ return cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj, kwArgs), kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs); }
 		},
 		"LCHuv":{
-			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs).toCmy(); },
-			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs).toCmyk(); },
-			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs).toHsl(); },
-			"HSV":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs).toHsv(); },
+			"CMY":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs).toCmy(); },
+			"CMYK":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs).toCmyk(); },
+			"HSL":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs).toHsl(); },
+			"HSV":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs).toHsv(); },
 			"Lab":function(obj, kwArgs){ return cMaps["XYZ"]["Lab"](cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs); },
 			"LCHab":function(obj, kwArgs){ return cMaps["Lab"]["LCHab"](cMaps["XYZ"]["Lab"](cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs), kwArgs); },
 			"Luv":function(obj, kwArgs){ return cMaps["LCHuv"]["Luv"](obj, kwArgs); },
-			"RGB":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs); },
+			"RGB":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs); },
 			"XYZ":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs); }
 		},
 		"Luv":{
-			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs).toCmy(); },
-			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs).toCmyk(); },
-			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs).toHsl(); },
-			"HSV":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs).toHsv(); },
+			"CMY":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs).toCmy(); },
+			"CMYK":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs).toCmyk(); },
+			"HSL":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs).toHsl(); },
+			"HSV":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs).toHsv(); },
 			"Lab":function(obj, kwArgs){ return cMaps["XYZ"]["Lab"](cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs); },
 			"LCHab":function(obj, kwArgs){ return cMaps["Lab"]["LCHab"](cMaps["XYZ"]["Lab"](cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs), kwArgs); },
 			"LCHuv":function(obj, kwArgs){ return cMaps["Luv"]["LCHuv"](obj, kwArgs); },
-			"RGB":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs); },
+			"RGB":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs); },
 			"XYZ":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](obj, kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs); }
 		},
@@ -309,28 +309,28 @@ dojox.color.Colorspace=new (function(){
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](obj.toXYZ(kwArgs), kwArgs); }
 		},
 		"XYZ":{
-			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(obj, kwArgs).toCmy(); },
-			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(obj, kwArgs).toCmyk(); },
-			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(obj, kwArgs).toHsl(); },
-			"HSV":function(obj, kwArgs){ return dxc.fromXYZ(obj, kwArgs).toHsv(); },
+			"CMY":function(obj, kwArgs){ return dcolor.fromXYZ(obj, kwArgs).toCmy(); },
+			"CMYK":function(obj, kwArgs){ return dcolor.fromXYZ(obj, kwArgs).toCmyk(); },
+			"HSL":function(obj, kwArgs){ return dcolor.fromXYZ(obj, kwArgs).toHsl(); },
+			"HSV":function(obj, kwArgs){ return dcolor.fromXYZ(obj, kwArgs).toHsv(); },
 			"Lab":function(obj, kwArgs){ return cMaps["XYZ"]["Lab"](obj, kwArgs); },
 			"LCHab":function(obj, kwArgs){ return cMaps["Lab"]["LCHab"](cMaps["XYZ"]["Lab"](obj, kwArgs), kwArgs); },
 			"LCHuv":function(obj, kwArgs){ return cMaps["Luv"]["LCHuv"](cMaps["XYZ"]["Luv"](obj, kwArgs), kwArgs); },
 			"Luv":function(obj, kwArgs){ return cMaps["XYZ"]["Luv"](obj, kwArgs); },
-			"RGB":function(obj, kwArgs){ return dxc.fromXYZ(obj, kwArgs); },
-			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dxc.fromXYZ(obj, kwArgs), kwArgs); }
+			"RGB":function(obj, kwArgs){ return dcolor.fromXYZ(obj, kwArgs); },
+			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dcolor.fromXYZ(obj, kwArgs), kwArgs); }
 		},
 		// TODO: revisit this. xyY represents a single color, not a spectrum of colors.
 		"xyY":{
-			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs).toCmy(); },
-			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs).toCmyk(); },
-			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs).toHsl(); },
-			"HSV":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs).toHsv(); },
+			"CMY":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs).toCmy(); },
+			"CMYK":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs).toCmyk(); },
+			"HSL":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs).toHsl(); },
+			"HSV":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs).toHsv(); },
 			"Lab":function(obj, kwArgs){ return cMaps["Lab"]["XYZ"](cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs); },
 			"LCHab":function(obj, kwArgs){ return cMaps["LCHab"]["Lab"](cMaps["Lab"]["XYZ"](cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs), kwArgs); },
 			"LCHuv":function(obj, kwArgs){ return cMaps["LCHuv"]["Luv"](cMaps["Luv"]["XYZ"](cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs), kwArgs); },
 			"Luv":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs); },
-			"RGB":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs); },
+			"RGB":function(obj, kwArgs){ return dcolor.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs); },
 			"XYZ":function(obj, kwArgs){ return cMaps["xyY"]["XYZ"](obj, kwArgs); }
 		}
 	};
@@ -398,7 +398,7 @@ dojox.color.Colorspace=new (function(){
 			xg:m[5], yg:m[6], Yg:m[7],
 			xb:m[8], yb:m[9], Yb:m[10]
 		};
-		
+
 		//	convert for the whitepoint
 		if(kwArgs.whitepoint!=primary.whitepoint){
 			var r=this.convert(
@@ -512,12 +512,12 @@ dojox.color.Colorspace=new (function(){
 	};
 })();
 
-//	More dojox.color and dojox.color.Color extensions
-dojo.mixin(dojox.color, {
+//	More dcolor and dojox.color.Color extensions
+dojo.mixin(dcolor, {
 	fromXYZ: function(/* Object */xyz, /* Object?*/kwArgs){
 		kwArgs=kwArgs||{};
-		var p=dojox.color.Colorspace.primaries(kwArgs);
-		var m=dojox.color.Colorspace.matrix("RGB", p);
+		var p=dcolor.Colorspace.primaries(kwArgs);
+		var m=dcolor.Colorspace.matrix("RGB", p);
 		var rgb=dojox.math.matrix.multiply([[ xyz.X, xyz.Y, xyz.Z ]], m);
 		var r=rgb[0][0], g=rgb[0][1], b=rgb[0][2];
 		if(p.profile=="sRGB"){
@@ -527,15 +527,15 @@ dojo.mixin(dojox.color, {
 		}else{
 			var R=Math.pow(r, 1/p.gamma), G=Math.pow(g, 1/p.gamma), B=Math.pow(b, 1/p.gamma);
 		}
-		return new dojox.color.Color({ r:Math.floor(R*255), g:Math.floor(G*255), b:Math.floor(B*255) });
+		return new dcolor.Color({ r:Math.floor(R*255), g:Math.floor(G*255), b:Math.floor(B*255) });
 	}
 });
 
-dojo.extend(dojox.color.Color, {
+dojo.extend(dcolor.Color, {
 	toXYZ: function(/* Object */kwArgs){
 		kwArgs=kwArgs||{};
-		var p=dojox.color.Colorspace.primaries(kwArgs);
-		var m=dojox.color.Colorspace.matrix("XYZ", p);
+		var p=dcolor.Colorspace.primaries(kwArgs);
+		var m=dcolor.Colorspace.matrix("XYZ", p);
 		var _r=this.r/255, _g=this.g/255, _b=this.b/255;
 		if(p.profile=="sRGB"){
 			var r=(_r>0.04045) ? Math.pow(((_r+0.055)/1.055), 2.4):_r/12.92;
@@ -544,10 +544,10 @@ dojo.extend(dojox.color.Color, {
 		} else {
 			var r=Math.pow(_r, p.gamma), g=Math.pow(_g, p.gamma), b=Math.pow(_b, p.gamma);
 		}
-		var xyz=dojox.math.matrix([[ r, g, b ]], m);
+		var xyz=dxm([[ r, g, b ]], m);
 		return { X: xyz[0][0], Y: xyz[0][1], Z: xyz[0][2] };	//	Object
 	}
 });
 
-return dojox.color.Colorspace;
+return dcolor.Colorspace;
 });
diff --git a/dojox/color/MeanColorModel.js b/dojox/color/MeanColorModel.js
new file mode 100644
index 0000000..52bce75
--- /dev/null
+++ b/dojox/color/MeanColorModel.js
@@ -0,0 +1,40 @@
+define(["dojo/_base/array", "dojo/_base/declare", "./NeutralColorModel"],
+	function(arr, declare, NeutralColorModel){
+	
+	return declare("dojox.color.MeanColorModel", NeutralColorModel, {
+		// summary:
+		//		A color model that returns a color from a data value
+		//		using an interpolation between two extremum colors around the mean value.
+			
+		constructor: function(startColor, endColor){
+			// startColor: dojo/_base/Color
+			//		The start color.
+			// endColor: dojo/_base/Color?
+			//		The end color.
+		},
+			
+		computeNeutral: function(min, max, sum, values){
+			// summary:
+			//		Return the neutral value in this case the mean value of the data values.
+			// min: Number
+			//		The minimal value.
+			// max: Number
+			//		The maximum value.
+			// sum: Number
+			//		The sum of all values.
+			// values: Number[]
+			//		The sorted array of values used to compute colors.			
+			var median = min;
+			if(values.length != 0){
+				if(values.length < 3){
+					median = sum / values.length;
+				}else if((values.length & 1) == 0){
+					median = (values[values.length / 2 - 1] + values[values.length / 2]) / 2;
+				}else{
+					median = values[Math.floor(values.length / 2)];
+				}
+			}
+			return median;
+		}
+	});
+});
diff --git a/dojox/color/NeutralColorModel.js b/dojox/color/NeutralColorModel.js
new file mode 100644
index 0000000..64af58a
--- /dev/null
+++ b/dojox/color/NeutralColorModel.js
@@ -0,0 +1,79 @@
+define(["dojo/_base/array", "dojo/_base/declare", "./SimpleColorModel"],
+	function(arr, declare, SimpleColorModel){
+	
+	return declare("dojox.color.NeutralColorModel", SimpleColorModel, {
+		// summary:
+		//		Base class for color models that return a color from a data value
+		//		using an interpolation between two extremum colors around a neutral value.
+		
+		_min: 0, 
+		_max: 0, 
+		_e: 0,
+	
+		constructor: function(startColor, endColor){
+			// startColor: dojo/_base/Color
+			//		The start color.
+			// endColor: dojo/_base/Color?
+			//		The end color.
+		},
+	
+		initialize: function(items, colorFunc){
+			// summary:
+			//		Initialize the color model from a list of data items and using a function
+			//		that returns the value used to compute the color for a given item.
+			// items: Object[]
+			//		The data items. 
+			// colorFunc: Function
+			//		The function that returns the value used to compute the color for particular data item.
+			var values = [];
+			var sum = 0;
+			var min = 100000000; 
+			var max = -min; 
+			arr.forEach(items, function(item){
+				var value = colorFunc(item);
+				min = Math.min(min, value);
+				max = Math.max(max, value);
+				sum += value;
+				values.push(value);
+			});
+			values.sort(function(a,b){return a - b;});
+			var neutral = this.computeNeutral(min, max, sum, values);
+			this._min = min;
+			this._max = max;
+			if(this._min == this._max || neutral == this._min){
+				this._e = -1;
+			}else{
+				this._e = Math.log(.5) / Math.log((neutral - this._min) / (this._max - this._min));
+			}
+		},
+		
+		computeNeutral: function(min, max, sum, values){
+			// summary:
+			//		Return the neutral value. This can be for example the mean or average value.
+			//		This function must be implemented by implementations.
+			// min: Number
+			//		The minimal value.
+			// max: Number
+			//		The maximum value.
+			// sum: Number
+			//		The sum of all values.
+			// values: Number[]
+			//		The sorted array of values used to compute colors.
+		},
+		
+		getNormalizedValue: function(value){
+			// summary:
+			//		Return the normalized (between 0 and 1) value for a given data value.
+			//		This implementation uses an power function to map neutral value to 0.5
+			//		and distribute other values around it.
+			// value: Number
+			//		The data value			
+			if(this._e < 0){
+				return 0;
+			}
+			value = (value - this._min) / (this._max - this._min);
+			return Math.pow(value, this._e);
+		}
+	});
+
+});
diff --git a/dojox/color/Palette.js b/dojox/color/Palette.js
index 3305946..946c673 100644
--- a/dojox/color/Palette.js
+++ b/dojox/color/Palette.js
@@ -1,5 +1,5 @@
-define(["dojo/_base/kernel", "../main", "dojo/_base/lang", "dojo/_base/array", "./_base"], 
-	function(dojo, dojox, lang, arr, dxc){
+define(["dojo/_base/lang", "dojo/_base/array", "./_base"],
+	function(lang, arr, dxc){
 
 	/***************************************************************
 	*	dojox.color.Palette
@@ -21,9 +21,9 @@ define(["dojo/_base/kernel", "../main", "dojo/_base/lang", "dojo/_base/array", "
 
 	//	ctor ----------------------------------------------------------------------------
 	dxc.Palette = function(/* String|Array|dojox.color.Color|dojox.color.Palette */base){
-		//	summary:
+		// summary:
 		//		An object that represents a palette of colors.
-		//	description:
+		// description:
 		//		A Palette is a representation of a set of colors.  While the standard
 		//		number of colors contained in a palette is 5, it can really handle any
 		//		number of colors.
@@ -32,8 +32,8 @@ define(["dojo/_base/kernel", "../main", "dojo/_base/lang", "dojo/_base/array", "
 		//		using a simple object-based approach.  In addition, you can generate
 		//		palettes using dojox.color.Palette.generate; these generated palettes
 		//		are based on the palette generators at http://kuler.adobe.com.
-		//
-		//	colors: dojox.color.Color[]
+
+		// colors: dojox.color.Color[]
 		//		The actual color references in this palette.
 		this.colors = [];
 		if(base instanceof dxc.Palette){
@@ -143,13 +143,77 @@ define(["dojo/_base/kernel", "../main", "dojo/_base/lang", "dojo/_base/array", "
 		return high-((high-val)*((high-low)/high));
 	}
 
+/*=====
+var __transformArgs = {
+	// summary:
+	//		The keywords argument to be passed to the dojox.color.Palette.transform function.  Note that
+	//		while all arguments are optional, *some* arguments must be passed.  The basic concept is that
+	//		you pass a delta value for a specific aspect of a color model (or multiple aspects of the same
+	//		color model); for instance, if you wish to transform a palette based on the HSV color model,
+	//		you would pass one of "dh", "ds", or "dv" as a value.
+	// use: String?
+	//		Specify the color model to use for the transformation.  Can be "rgb", "rgba", "hsv", "hsl", "cmy", "cmyk".
+	// dr: Number?
+	//		The delta to be applied to the red aspect of the RGB/RGBA color model.
+	// dg: Number?
+	//		The delta to be applied to the green aspect of the RGB/RGBA color model.
+	// db: Number?
+	//		The delta to be applied to the blue aspect of the RGB/RGBA color model.
+	// da: Number?
+	//		The delta to be applied to the alpha aspect of the RGBA color model.
+	// dc: Number?
+	//		The delta to be applied to the cyan aspect of the CMY/CMYK color model.
+	// dm: Number?
+	//		The delta to be applied to the magenta aspect of the CMY/CMYK color model.
+	// dy: Number?
+	//		The delta to be applied to the yellow aspect of the CMY/CMYK color model.
+	// dk: Number?
+	//		The delta to be applied to the black aspect of the CMYK color model.
+	// dh: Number?
+	//		The delta to be applied to the hue aspect of the HSL/HSV color model.
+	// ds: Number?
+	//		The delta to be applied to the saturation aspect of the HSL/HSV color model.
+	// dl: Number?
+	//		The delta to be applied to the luminosity aspect of the HSL color model.
+	// dv: Number?
+	//		The delta to be applied to the value aspect of the HSV color model.
+};
+var __generatorArgs = {
+	// summary:
+	//		The keyword arguments object used to create a palette based on a base color.
+	// base: dojo/_base/Color
+	//		The base color to be used to generate the palette.
+};
+var __analogousArgs = {
+	// summary:
+	//		The keyword arguments object that is used to create a 5 color palette based on the
+	//		analogous rules as implemented at http://kuler.adobe.com, using the HSV color model.
+	// base: dojo/_base/Color
+	//		The base color to be used to generate the palette.
+	// high: Number?
+	//		The difference between the hue of the base color and the highest hue.  In degrees, default is 60.
+	// low: Number?
+	//		The difference between the hue of the base color and the lowest hue.  In degrees, default is 18.
+};
+var __splitComplementaryArgs = {
+	// summary:
+	//		The keyword arguments object used to create a palette based on the split complementary rules
+	//		as implemented at http://kuler.adobe.com.
+	// base: dojo/_base/Color
+	//		The base color to be used to generate the palette.
+	// da: Number?
+	//		The delta angle to be used to determine where the split for the complementary rules happen.
+	//		In degrees, the default is 30.
+};
+=====*/
+
 	//	object methods ---------------------------------------------------------------
 	lang.extend(dxc.Palette, {
-		transform: function(/* dojox.color.Palette.__transformArgs */kwArgs){
-			//	summary:
+		transform: function(/*__transformArgs*/kwArgs){
+			// summary:
 			//		Transform the palette using a specific transformation function
 			//		and a set of transformation parameters.
-			//	description:
+			// description:
 			//		{palette}.transform is a simple way to uniformly transform
 			//		all of the colors in a palette using any of 5 formulae:
 			//		RGBA, HSL, HSV, CMYK or CMY.
@@ -193,102 +257,16 @@ define(["dojo/_base/kernel", "../main", "dojo/_base/lang", "dojo/_base/array", "
 			return palette;		//	dojox.color.Palette
 		},
 		clone: function(){
-			//	summary:
+			// summary:
 			//		Clones the current palette.
 			return new dxc.Palette(this);	//	dojox.color.Palette
 		}
 	});
 
-/*=====
-dojox.color.Palette.__transformArgs = function(use, dr, dg, db, da, dc, dm, dy, dk, dh, ds, dv, dl){
-	//	summary:
-	//		The keywords argument to be passed to the dojox.color.Palette.transform function.  Note that
-	//		while all arguments are optional, *some* arguments must be passed.  The basic concept is that
-	//		you pass a delta value for a specific aspect of a color model (or multiple aspects of the same
-	//		color model); for instance, if you wish to transform a palette based on the HSV color model,
-	//		you would pass one of "dh", "ds", or "dv" as a value.
-	//
-	//	use: String?
-	//		Specify the color model to use for the transformation.  Can be "rgb", "rgba", "hsv", "hsl", "cmy", "cmyk".
-	//	dr: Number?
-	//		The delta to be applied to the red aspect of the RGB/RGBA color model.
-	//	dg: Number?
-	//		The delta to be applied to the green aspect of the RGB/RGBA color model.
-	//	db: Number?
-	//		The delta to be applied to the blue aspect of the RGB/RGBA color model.
-	//	da: Number?
-	//		The delta to be applied to the alpha aspect of the RGBA color model.
-	//	dc: Number?
-	//		The delta to be applied to the cyan aspect of the CMY/CMYK color model.
-	//	dm: Number?
-	//		The delta to be applied to the magenta aspect of the CMY/CMYK color model.
-	//	dy: Number?
-	//		The delta to be applied to the yellow aspect of the CMY/CMYK color model.
-	//	dk: Number?
-	//		The delta to be applied to the black aspect of the CMYK color model.
-	//	dh: Number?
-	//		The delta to be applied to the hue aspect of the HSL/HSV color model.
-	//	ds: Number?
-	//		The delta to be applied to the saturation aspect of the HSL/HSV color model.
-	//	dl: Number?
-	//		The delta to be applied to the luminosity aspect of the HSL color model.
-	//	dv: Number?
-	//		The delta to be applied to the value aspect of the HSV color model.
-	this.use = use;
-	this.dr = dr;
-	this.dg = dg;
-	this.db = db;
-	this.da = da;
-	this.dc = dc;
-	this.dm = dm;
-	this.dy = dy;
-	this.dk = dk;
-	this.dh = dh;
-	this.ds = ds;
-	this.dl = dl;
-	this.dv = dv;
-}
-dojox.color.Palette.__generatorArgs = function(base){
-	//	summary:
-	//		The keyword arguments object used to create a palette based on a base color.
-	//
-	//	base: dojo.Color
-	//		The base color to be used to generate the palette.
-	this.base = base;
-}
-dojox.color.Palette.__analogousArgs = function(base, high, low){
-	//	summary:
-	//		The keyword arguments object that is used to create a 5 color palette based on the
-	//		analogous rules as implemented at http://kuler.adobe.com, using the HSV color model.
-	//
-	//	base: dojo.Color
-	//		The base color to be used to generate the palette.
-	//	high: Number?
-	//		The difference between the hue of the base color and the highest hue.  In degrees, default is 60.
-	//	low: Number?
-	//		The difference between the hue of the base color and the lowest hue.  In degrees, default is 18.
-	this.base = base;
-	this.high = high;
-	this.low = low;
-}
-dojox.color.Palette.__splitComplementaryArgs = function(base, da){
-	//	summary:
-	//		The keyword arguments object used to create a palette based on the split complementary rules
-	//		as implemented at http://kuler.adobe.com.
-	//
-	//	base: dojo.Color
-	//		The base color to be used to generate the palette.
-	//	da: Number?
-	//		The delta angle to be used to determine where the split for the complementary rules happen.
-	//		In degrees, the default is 30.
-	this.base = base;
-	this.da = da;
-}
-=====*/
 	lang.mixin(dxc.Palette, {
 		generators: {
-			analogous:function(/* dojox.color.Palette.__analogousArgs */args){
-				//	summary:
+			analogous:function(/* __analogousArgs */args){
+				// summary:
 				//		Create a 5 color palette based on the analogous rules as implemented at
 				//		http://kuler.adobe.com.
 				var high=args.high||60, 	//	delta between base hue and highest hue (subtracted from base)
@@ -317,8 +295,8 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				}));		//	dojox.color.Palette
 			},
 
-			monochromatic: function(/* dojox.color.Palette.__generatorArgs */args){
-				//	summary:
+			monochromatic: function(/* __generatorArgs */args){
+				// summary:
 				//		Create a 5 color palette based on the monochromatic rules as implemented at
 				//		http://kuler.adobe.com.
 				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
@@ -340,8 +318,8 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				]);		//	dojox.color.Palette
 			},
 
-			triadic: function(/* dojox.color.Palette.__generatorArgs */args){
-				//	summary:
+			triadic: function(/* __generatorArgs */args){
+				// summary:
 				//		Create a 5 color palette based on the triadic rules as implemented at
 				//		http://kuler.adobe.com.
 				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
@@ -365,8 +343,8 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				]);		//	dojox.color.Palette
 			},
 
-			complementary: function(/* dojox.color.Palette.__generatorArgs */args){
-				//	summary:
+			complementary: function(/* __generatorArgs */args){
+				// summary:
 				//		Create a 5 color palette based on the complementary rules as implemented at
 				//		http://kuler.adobe.com.
 				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
@@ -388,8 +366,8 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				]);		//	dojox.color.Palette
 			},
 
-			splitComplementary: function(/* dojox.color.Palette.__splitComplementaryArgs */args){
-				//	summary:
+			splitComplementary: function(/* __splitComplementaryArgs */args){
+				// summary:
 				//		Create a 5 color palette based on the split complementary rules as implemented at
 				//		http://kuler.adobe.com.
 				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
@@ -414,8 +392,8 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				]);		//	dojox.color.Palette
 			},
 
-			compound: function(/* dojox.color.Palette.__generatorArgs */args){
-				//	summary:
+			compound: function(/* __generatorArgs */args){
+				// summary:
 				//		Create a 5 color palette based on the compound rules as implemented at
 				//		http://kuler.adobe.com.
 				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
@@ -440,8 +418,8 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 				]);		//	dojox.color.Palette
 			},
 
-			shades: function(/* dojox.color.Palette.__generatorArgs */args){
-				//	summary:
+			shades: function(/* __generatorArgs */args){
+				// summary:
 				//		Create a 5 color palette based on the shades rules as implemented at
 				//		http://kuler.adobe.com.
 				var base = lang.isString(args.base)?new dxc.Color(args.base):args.base,
@@ -463,7 +441,7 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 			}
 		},
 		generate: function(/* String|dojox.color.Color */base, /* Function|String */type){
-			//	summary:
+			// summary:
 			//		Generate a new Palette using any of the named functions in
 			//		dojox.color.Palette.generators or an optional function definition.  Current
 			//		generators include "analogous", "monochromatic", "triadic", "complementary",
diff --git a/dojox/color/SimpleColorModel.js b/dojox/color/SimpleColorModel.js
new file mode 100644
index 0000000..a3f7989
--- /dev/null
+++ b/dojox/color/SimpleColorModel.js
@@ -0,0 +1,69 @@
+define(["dojo/_base/array", "dojo/_base/declare", "dojox/color"], 
+	function(arr, declare, color){
+	
+	return declare("dojox.color.SimpleColorModel", null, {
+		// summary:
+		//		Base class for color models that return a color from a data value
+		//		using an interpolation between two extremum colors.
+		
+		_startColor: null, 
+		_endColor: null, 
+	
+		constructor: function(startColor, endColor){
+			// summary:
+			//		Construct a color model interpolating between start and end color.
+			//		If only start color is provided use it to compute reasonable start and end
+			//		colors from it.
+			// startColor: dojo/_base/Color
+			//		The start color. 
+			// endColor: dojo/_base/Color?
+			//		The end color.
+			if(endColor != undefined){
+				this._startColor = startColor;
+				this._endColor = endColor;
+			}else{
+				// When only one color is provided
+				// use only the hue, and compute
+				// the start/end colors by playing
+				// with the luminance...    			
+				var hsl = startColor.toHsl();
+				hsl.s = 100; 
+				hsl.l = 85; 
+				this._startColor = color.fromHsl(hsl.h, hsl.s, hsl.l);
+				this._startColor.a = startColor.a;
+				hsl.l = 15;
+				this._endColor = color.fromHsl(hsl.h, hsl.s, hsl.l);
+				this._endColor.a = startColor.a;
+			}
+		},
+		
+		_getInterpoledValue: function(from, to, value){
+			return(from + (to - from) * value);
+		},
+	
+		getNormalizedValue: function(value){
+			// summary:
+			//		Return the normalized (between 0 and 1) value for a given data value.
+			//		This function must be implemented by implementations.
+			// value: Number
+			//		The data value. 			
+		},
+	
+		getColor: function(value){
+			// summary:
+			//		return the color for a given data value.
+			// value: Number
+			//		The data value. 			
+			var completion = this.getNormalizedValue(value);
+			var hslFrom = this._startColor.toHsl();
+			var hslTo = this._endColor.toHsl();
+			var h = this._getInterpoledValue(hslFrom.h, hslTo.h, completion);
+			var s = this._getInterpoledValue(hslFrom.s, hslTo.s, completion);
+			var l = this._getInterpoledValue(hslFrom.l, hslTo.l, completion);
+			var a = this._getInterpoledValue(this._startColor.a, this._endColor.a, completion);
+			var c = color.fromHsl(h, s, l);
+			c.a = a;
+			return c;
+		}
+	});
+});
diff --git a/dojox/color/_base.js b/dojox/color/_base.js
index a826054..23870c3 100644
--- a/dojox/color/_base.js
+++ b/dojox/color/_base.js
@@ -1,7 +1,7 @@
-define(["dojo/_base/kernel", "../main", "dojo/_base/lang", "dojo/_base/Color", "dojo/colors"], 
-	function(dojo, dojox, lang, Color, colors){
+define(["../main", "dojo/_base/lang", "dojo/_base/Color", "dojo/colors"],
+	function(dojox, lang, Color, colors){
 
-var cx = lang.getObject("dojox.color", true);
+var cx = lang.getObject("color", true, dojox);
 /*===== cx = dojox.color =====*/
 		
 //	alias all the dojo.Color mechanisms
@@ -17,9 +17,9 @@ cx.greyscale=colors.makeGrey;
 
 lang.mixin(cx,{
 	fromCmy: function(/* Object|Array|int */cyan, /*int*/magenta, /*int*/yellow){
-		//	summary
-		//	Create a dojox.color.Color from a CMY defined color.
-		//	All colors should be expressed as 0-100 (percentage)
+		// summary:
+		//		Create a dojox.color.Color from a CMY defined color.
+		//		All colors should be expressed as 0-100 (percentage)
 	
 		if(lang.isArray(cyan)){
 			magenta=cyan[1], yellow=cyan[2], cyan=cyan[0];
@@ -33,9 +33,9 @@ lang.mixin(cx,{
 	},
 	
 	fromCmyk: function(/* Object|Array|int */cyan, /*int*/magenta, /*int*/yellow, /*int*/black){
-		//	summary
-		//	Create a dojox.color.Color from a CMYK defined color.
-		//	All colors should be expressed as 0-100 (percentage)
+		// summary:
+		//		Create a dojox.color.Color from a CMYK defined color.
+		//		All colors should be expressed as 0-100 (percentage)
 	
 		if(lang.isArray(cyan)){
 			magenta=cyan[1], yellow=cyan[2], black=cyan[3], cyan=cyan[0];
@@ -51,9 +51,9 @@ lang.mixin(cx,{
 	},
 		
 	fromHsl: function(/* Object|Array|int */hue, /* int */saturation, /* int */luminosity){
-		//	summary
-		//	Create a dojox.color.Color from an HSL defined color.
-		//	hue from 0-359 (degrees), saturation and luminosity 0-100.
+		// summary:
+		//		Create a dojox.color.Color from an HSL defined color.
+		//		hue from 0-359 (degrees), saturation and luminosity 0-100.
 	
 		if(lang.isArray(hue)){
 			saturation=hue[1], luminosity=hue[2], hue=hue[0];
@@ -90,9 +90,9 @@ lang.mixin(cx,{
 });
 	
 cx.fromHsv = function(/* Object|Array|int */hue, /* int */saturation, /* int */value){
-	//	summary
-	//	Create a dojox.color.Color from an HSV defined color.
-	//	hue from 0-359 (degrees), saturation and value 0-100.
+	// summary:
+	//		Create a dojox.color.Color from an HSV defined color.
+	//		hue from 0-359 (degrees), saturation and value 0-100.
 
 	if(lang.isArray(hue)){
 		saturation=hue[1], value=hue[2], hue=hue[0];
@@ -125,15 +125,15 @@ cx.fromHsv = function(/* Object|Array|int */hue, /* int */saturation, /* int */v
 };
 lang.extend(Color,{
 	toCmy: function(){
-		//	summary
-		//	Convert this Color to a CMY definition.
+		// summary:
+		//		Convert this Color to a CMY definition.
 		var cyan=1-(this.r/255), magenta=1-(this.g/255), yellow=1-(this.b/255);
 		return { c:Math.round(cyan*100), m:Math.round(magenta*100), y:Math.round(yellow*100) };		//	Object
 	},
 		
 	toCmyk: function(){
-		//	summary
-		//	Convert this Color to a CMYK definition.
+		// summary:
+		//		Convert this Color to a CMYK definition.
 		var cyan, magenta, yellow, black;
 		var r=this.r/255, g=this.g/255, b=this.b/255;
 		black = Math.min(1-r, 1-g, 1-b);
@@ -144,8 +144,8 @@ lang.extend(Color,{
 	},
 		
 	toHsl: function(){
-		//	summary
-		//	Convert this Color to an HSL definition.
+		// summary:
+		//		Convert this Color to an HSL definition.
 		var r=this.r/255, g=this.g/255, b=this.b/255;
 		var min = Math.min(r, b, g), max = Math.max(r, g, b);
 		var delta = max-min;
@@ -169,8 +169,8 @@ lang.extend(Color,{
 	},
 	
 	toHsv: function(){
-		//	summary
-		//	Convert this Color to an HSV definition.
+		// summary:
+		//		Convert this Color to an HSV definition.
 		var r=this.r/255, g=this.g/255, b=this.b/255;
 		var min = Math.min(r, b, g), max = Math.max(r, g, b);
 		var delta = max-min;
diff --git a/dojox/color/api/ColorModel.js b/dojox/color/api/ColorModel.js
new file mode 100644
index 0000000..abe0ea8
--- /dev/null
+++ b/dojox/color/api/ColorModel.js
@@ -0,0 +1,30 @@
+define(["dojo/_base/declare"], 
+	function(declare){
+	
+	return declare("dojox.color.api.ColorModel", null, {
+		// summary:
+		//		API for classes that implement a color model that returns a color from a data value.
+		
+		constructor: function(){
+			// summary:
+			//		Constructor.
+		},
+	
+		initialize: function(items, colorFunc){
+			// summary:
+			//		Optionally initialize the color model from a list of data items and using a function
+			//		that returns the value used to compute the color for a given item.
+			// items: Object[]
+			//		The data items. 
+			// colorFunc: Function
+			//		The function that returns the value used to compute the color for particular data item.			
+		},
+	
+		getColor: function(value){
+			// summary:
+			//		return the color for a given data value.
+			// value: Number
+			//		The data value. 			
+		}
+	});
+});
diff --git a/dojox/color/tests/ColorModel.js b/dojox/color/tests/ColorModel.js
new file mode 100644
index 0000000..56c3bb6
--- /dev/null
+++ b/dojox/color/tests/ColorModel.js
@@ -0,0 +1,22 @@
+define(["doh", "dojo/_base/declare", "../MeanColorModel", "..", "dijit/_WidgetBase"], 
+	function(doh, declare, MeanColorModel, color, _WidgetBase){
+	doh.register("tests.MeanColorModel", [
+		function test_Values(t){
+			var cm = new MeanColorModel(new color.Color([0, 0, 0]), new color.Color([100, 100, 100]));
+			cm.initialize([0, 10, 20], function(item){
+				return item;
+			});
+			t.is([50, 50, 50], cm.getColor(10).toRgb());
+			t.is([0, 0, 0], cm.getColor(0).toRgb());
+			t.is([99, 99, 99], cm.getColor(20).toRgb());
+			
+			cm.initialize([0, 5, 20], function(item){
+				return item;
+			});
+			t.is([50, 50, 50], cm.getColor(5).toRgb());
+			t.is([0, 0, 0], cm.getColor(0).toRgb());
+			t.is([99, 99, 99], cm.getColor(20).toRgb());
+
+		}
+	]);
+});
diff --git a/dojox/color/tests/color.js b/dojox/color/tests/color.js
index 03bc4fb..228412d 100644
--- a/dojox/color/tests/color.js
+++ b/dojox/color/tests/color.js
@@ -3,8 +3,8 @@ dojo.require("dojox.color");
 
 try{
 	dojo.require("dojox.color.tests._base");
-//	dojo.require("dojox.color.tests.Colorspace");
 	dojo.require("dojox.color.tests.Palette");
+	dojo.require("dojox.color.tests.ColorModel");
 }catch(e){
 	doh.debug(e);
 }
diff --git a/dojox/cometd.js b/dojox/cometd.js
index ad541c5..e6f32cc 100644
--- a/dojox/cometd.js
+++ b/dojox/cometd.js
@@ -1,5 +1,2 @@
+// TODO: Replace with version from CometD project
 // stub loader for the cometd module since no implementation code is allowed to live in top-level files
-dojo.provide("dojox.cometd");
-dojo.require("dojox.cometd._base");
-dojo.require("dojox.cometd.longPollTransport");
-dojo.require("dojox.cometd.callbackPollTransport");
diff --git a/dojox/cometd/HttpChannels.js b/dojox/cometd/HttpChannels.js
deleted file mode 100644
index c350e2c..0000000
--- a/dojox/cometd/HttpChannels.js
+++ /dev/null
@@ -1,32 +0,0 @@
-dojo.provide("dojox.cometd.HttpChannels");
- 
-dojo.require("dojox.io.httpParse");
-dojo.require("dojox.cometd.RestChannels");
-// Note that cometd _base is _not_ required, this can run standalone, but ifyou want
-// cometd functionality, you must explicitly load/require it elsewhere, and cometd._base
-// MUST be loaded prior to HttpChannels ifyou use it.
-
-// summary:
-// 		HttpChannels - An HTTP Based approach to Comet transport with full HTTP messaging
-// 		semantics including REST. HttpChannels is exactly the same as RestChannels, loading HttpChannels simply ensures that http parsing
-//		capabilities are present for application/http messages
-
-// description:
-// 		This can be used:
-// 		1. As a cometd transport
-// 		2. As an enhancement for the REST RPC service, to enable "live" data (real-time updates directly alter the data in indexes)
-// 		2a. With the JsonRestStore (which is driven by the REST RPC service), so this dojo.data has real-time data. Updates can be heard through the dojo.data notification API.
-// 		3. As a standalone transport. To use it as a standalone transport looks like this:
-// 	|		dojox.cometd.HttpChannels.open();
-// 	|		dojox.cometd.HttpChannels.get("/myResource",{callback:function(){
-// 	|			// this is called when the resource is first retrieved and any time the
-// 	|			// resource is changed in the future. This provides a means for retrieving a
-// 	|			// resource and subscribing to it in a single request
-// 	|		});
-// 	|	dojox.cometd.HttpChannels.subscribe("/anotherResource",{callback:function(){
-// 	|		// this is called when the resource is changed in the future
-// 	|	});
-// 		Channels HTTP can be configured to a different delays:
-// 	|	dojox.cometd.HttpChannels.autoReconnectTime = 60000; // reconnect after one minute
-//
-dojox.cometd.HttpChannels = dojox.cometd.RestChannels;
diff --git a/dojox/cometd/README b/dojox/cometd/README
index 05a42a2..986b95d 100644
--- a/dojox/cometd/README
+++ b/dojox/cometd/README
@@ -1,13 +1,13 @@
 -------------------------------------------------------------------------------
 Cometd (client)
 -------------------------------------------------------------------------------
-Version 0.4
-Release date: May 29, 2007
+Version 2.5
+Release date: June 13, 2012
 -------------------------------------------------------------------------------
 Project state: beta 
 -------------------------------------------------------------------------------
 Project authors
-	Alex Russell (alex at dojotoolkit.org)
+	Simone Bordet
 	Greg Wilkins
 -------------------------------------------------------------------------------
 Project description
diff --git a/dojox/cometd/RestChannels.js b/dojox/cometd/RestChannels.js
deleted file mode 100644
index c4fe799..0000000
--- a/dojox/cometd/RestChannels.js
+++ /dev/null
@@ -1,483 +0,0 @@
-dojo.provide("dojox.cometd.RestChannels");
-
-dojo.require("dojox.rpc.Client");
-dojo.require("dojo._base.url");
-dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener");
-
-// Note that cometd _base is _not_ required, this can run standalone, but ifyou want
-// cometd functionality, you must explicitly load/require it elsewhere, and cometd._base
-// MUST be loaded prior to RestChannels ifyou use it.
-
-// summary:
-// 		REST Channels - An HTTP/REST Based approach to Comet transport with full REST messaging
-// 		semantics
-// 		REST Channels is a efficient, reliable duplex transport for Comet
-
-// description:
-// 		This can be used:
-// 		1. As a cometd transport
-// 		2. As an enhancement for the REST RPC service, to enable "live" data (real-time updates directly alter the data in indexes)
-// 		2a. With the JsonRestStore (which is driven by the REST RPC service), so this dojo.data has real-time data. Updates can be heard through the dojo.data notification API.
-// 		3. As a standalone transport. To use it as a standalone transport looks like this:
-// 	|		dojox.cometd.RestChannels.open();
-// 	|		dojox.cometd.RestChannels.get("/myResource",{callback:function(){
-// 	|			// this is called when the resource is first retrieved and any time the
-// 	|			// resource is changed in the future. This provides a means for retrieving a
-// 	|			// resource and subscribing to it in a single request
-// 	|		});
-// 	|	dojox.cometd.RestChannels.subscribe("/anotherResource",{callback:function(){
-// 	|		// this is called when the resource is changed in the future
-// 	|	});
-// 		Channels HTTP can be configured to a different delays:
-// 	|	dojox.cometd.RestChannels.defaultInstance.autoReconnectTime = 60000; // reconnect after one minute
-//
-
-(function(){
-	dojo.declare("dojox.cometd.RestChannels", null, {
-		constructor: function(options){
-			// summary:
-			//		Initiates the REST Channels protocol
-			//	options:
-			//		Keyword arguments:
-			//	The *autoSubscribeRoot* parameter:
-			//		When this is set, all REST service requests that have this
-			// 		prefix will be auto-subscribed. The default is '/' (all REST requests).
-			//  The *url* parameter:
-			//		This is the url to connect to for server-sent messages. The default
-			//		is "/channels".
-			//	The *autoReconnectTime* parameter:
-			// 		This is amount time to wait to reconnect with a connection is broken
-			// The *reloadDataOnReconnect* parameter:
-			// 		This indicates whether RestChannels should re-download data when a connection
-			// 		is restored (value of true), or if it should re-subscribe with retroactive subscriptions
-			// 		(Subscribe-Since header) using HEAD requests (value of false). The
-			// 		default is true.
-			dojo.mixin(this,options);
-			// If we have a Rest service available and we are auto subscribing, we will augment the Rest service
-			if(dojox.rpc.Rest && this.autoSubscribeRoot){
-				// override the default Rest handler so we can add subscription requests
-				var defaultGet = dojox.rpc.Rest._get;
-				var self = this;
-				dojox.rpc.Rest._get = function(service, id){
-					// when there is a REST get, we will intercept and add our own xhr handler
-					var defaultXhrGet = dojo.xhrGet;
-					dojo.xhrGet = function(r){
-						var autoSubscribeRoot = self.autoSubscribeRoot;
-						return (autoSubscribeRoot && r.url.substring(0, autoSubscribeRoot.length) == autoSubscribeRoot) ?
-							self.get(r.url,r) : // auto-subscribe
-							defaultXhrGet(r); // plain XHR request
-					};
-
-					var result = defaultGet.apply(this,arguments);
-					dojo.xhrGet = defaultXhrGet;
-					return result;
-				};
-			}
-		},
-		absoluteUrl: function(baseUrl,relativeUrl){
-			return new dojo._Url(baseUrl,relativeUrl)+'';
-		},
-		acceptType: "application/rest+json,application/http;q=0.9,*/*;q=0.7",
-		subscriptions: {},
-		subCallbacks: {},
-		autoReconnectTime: 3000,
-		reloadDataOnReconnect: true,
-		sendAsJson: false,
-		url: '/channels',
-		autoSubscribeRoot: '/',
-		open: function(){
-			// summary:
-			// 		Startup the transport (connect to the "channels" resource to receive updates from the server).
-			//
-			// description:
-			//		Note that if there is no connection open, this is automatically called when you do a subscription,
-			// 		it is often not necessary to call this
-			//
-			this.started = true;
-			if(!this.connected){
-				this.connectionId = dojox.rpc.Client.clientId;
-				var clientIdHeader = this.createdClientId ? 'Client-Id' : 'Create-Client-Id';
-				this.createdClientId = true;
-				var headers = {Accept:this.acceptType};
-				headers[clientIdHeader] = this.connectionId;
-				var dfd = dojo.xhrPost({headers:headers, url: this.url, noStatus: true});
-		  		var self = this;
-		  		this.lastIndex = 0;
-				var onerror, onprogress = function(data){ // get all the possible event handlers
-					if(typeof dojo == 'undefined'){
-						return null;// this can be called after dojo is unloaded, just do nothing in that case
-					}
-					if(xhr && xhr.status > 400){
-						return onerror(true);
-					}
-					if(typeof data == 'string'){
-						data = data.substring(self.lastIndex);
-					}
-					var contentType = xhr && (xhr.contentType || xhr.getResponseHeader("Content-Type")) || (typeof data != 'string' && "already json");
-					var error = self.onprogress(xhr,data,contentType);
-					if(error){
-						if(onerror()){
-							return new Error(error);
-						}
-					}
-					if(!xhr || xhr.readyState==4){
-						xhr = null;
-						if(self.connected){
-							self.connected = false;
-							self.open();
-						}
-					}
-					return data;
-				};
-				onerror = function(error){
-					if(xhr && xhr.status == 409){
-						// a 409 indicates that there is a multiple connections, and we need to poll
-						console.log("multiple tabs/windows open, polling");
-						self.disconnected();
-						return null;
-					}
-					self.createdClientId = false;
-					self.disconnected();
-					return error;
-			  	};
-			  	dfd.addCallbacks(onprogress,onerror);
-			  	var xhr = dfd.ioArgs.xhr; // this may not exist if we are not using XHR, but an alternate XHR plugin
-			  	if(xhr){
-			  		// if we are doing a monitorable XHR, we want to listen to streaming events
-	  				xhr.onreadystatechange = function(){
-	  					var responseText;
-						try{
-							if(xhr.readyState == 3){// only for progress, the deferred object will handle the finished responses
-								self.readyState = 3;
-								responseText = xhr.responseText;
-							}
-						} catch(e){
-						}
-	  					if(typeof responseText=='string'){
-	  						onprogress(responseText);
-	  					}
-	  				}
-			  	}
-
-
-				if(window.attachEvent){// IE needs a little help with cleanup
-					window.attachEvent("onunload",function(){
-						self.connected= false;
-						if(xhr){
-							xhr.abort();
-						}
-					});
-				}
-
-				this.connected = true;
-			}
-		},
-		_send: function(method,args,data){
-			// fire an XHR with appropriate modification for JSON handling
-			if(this.sendAsJson){
-				// send use JSON Messaging
-				args.postData = dojo.toJson({
-					target:args.url,
-					method:method,
-					content: data,
-					params:args.content,
-					subscribe:args.headers["Subscribe"]
-				});
-				args.url = this.url;
-				method = "POST";
-			}else{
-				args.postData = dojo.toJson(data);
-			}
-			return dojo.xhr(method,args,args.postData);
-		},
-		subscribe: function(/*String*/channel, /*dojo.__XhrArgs?*/args){
-			// summary:
-			// 		Subscribes to a channel/uri, and returns a dojo.Deferred object for the response from
-			// 		the subscription request
-			//
-			// channel:
-			// 		the uri for the resource you want to monitor
-			//
-			// args:
-			// 		See dojo.xhr
-			//
-			// headers:
-			// 		These are the headers to be applied to the channel subscription request
-			//
-			// callback:
-			// 		This will be called when a event occurs for the channel
-			// 		The callback will be called with a single argument:
-			// 	|	callback(message)
-			// 		where message is an object that follows the XHR API:
-			// 		status : Http status
-			// 		statusText : Http status text
-			// 		getAllResponseHeaders() : The response headers
-			// 		getResponseHeaders(headerName) : Retrieve a header by name
-			// 		responseText : The response body as text
-			// 			with the following additional Bayeux properties
-			// 		data : The response body as JSON
-			// 		channel : The channel/url of the response
-			args = args || {};
-			args.url = this.absoluteUrl(this.url, channel);
-			if(args.headers){
-				// FIXME: combining Ranges with notifications is very complicated, we will save that for a future version
-				delete args.headers.Range;
-			}
-			var oldSince = this.subscriptions[channel];
-			var method = args.method || "HEAD"; // HEAD is the default for a subscription
-			var since = args.since;
-			var callback = args.callback;
-			var headers = args.headers || (args.headers = {});
-			this.subscriptions[channel] = since || oldSince || 0;
-			var oldCallback = this.subCallbacks[channel];
-			if(callback){
-				this.subCallbacks[channel] = oldCallback ? function(m){
-					oldCallback(m);
-					callback(m);
-				} : callback;
-			}
-			if(!this.connected){
-				this.open();
-			}
-			if(oldSince === undefined || oldSince != since){
-				headers["Cache-Control"] = "max-age=0";
-				since = typeof since == 'number' ? new Date(since).toUTCString() : since;
-				if(since){
-					headers["Subscribe-Since"] = since;
-				}
-				headers["Subscribe"] = args.unsubscribe ? 'none' : '*';
-				var dfd = this._send(method,args);
-
-				var self = this;
-				dfd.addBoth(function(result){
-					var xhr = dfd.ioArgs.xhr;
-					if(!(result instanceof Error)){
-						if(args.confirmation){
-							args.confirmation();
-						}
-					}
-					if(xhr && xhr.getResponseHeader("Subscribed")  == "OK"){
-						var lastMod = xhr.getResponseHeader('Last-Modified');
-
-						if(xhr.responseText){
-							self.subscriptions[channel] = lastMod || new Date().toUTCString();
-						}else{
-							return null; // don't process the response, the response will be received in the main channels response
-						}
-					}else if(xhr && !(result instanceof Error)){ // if the server response was successful and we have access to headers but it does indicate a subcription was successful, that means it is did not accept the subscription
-						delete self.subscriptions[channel];
-					}
-					if(!(result instanceof Error)){
-						var message = {
-							responseText:xhr && xhr.responseText,
-							channel:channel,
-							getResponseHeader:function(name){
-								return xhr.getResponseHeader(name);
-							},
-							getAllResponseHeaders:function(){
-								return xhr.getAllResponseHeaders();
-							},
-							result: result
-						};
-						if(self.subCallbacks[channel]){
-							self.subCallbacks[channel](message); // call with the fake xhr object
-						}
-					}else{
-						if(self.subCallbacks[channel]){
-							self.subCallbacks[channel](xhr); // call with the actual xhr object
-						}
-					}
-					return result;
-				});
-				return dfd;
-			}
-			return null;
-		},
-		publish: function(channel,data){
-			// summary:
-			//		Publish an event.
-			// description:
-			// 		This does a simple POST operation to the provided URL,
-			// 		POST is the semantic equivalent of publishing a message within REST/Channels
-			// channel:
-			// 		Channel/resource path to publish to
-			// data:
-			//		data to publish
-			return this._send("POST",{url:channel,contentType : 'application/json'},data);
-		},
-		_processMessage: function(message){
-			message.event = message.event || message.getResponseHeader('Event');
-			if(message.event=="connection-conflict"){
-				return "conflict"; // indicate an error
-			}
-			try{
-				message.result = message.result || dojo.fromJson(message.responseText);
-			}
-			catch(e){}
-			var self = this;
-			var loc = message.channel = new dojo._Url(this.url, message.source || message.getResponseHeader('Content-Location'))+'';//for cometd
-			if(loc in this.subscriptions && message.getResponseHeader){
-				this.subscriptions[loc] = message.getResponseHeader('Last-Modified');
-			}
-			if(this.subCallbacks[loc]){
-				setTimeout(function(){ //give it it's own stack
-					self.subCallbacks[loc](message);
-				},0);
-			}
-			this.receive(message);
-			return null;
-		},
-		onprogress: function(xhr,data,contentType){
-			// internal XHR progress handler
-			if(!contentType || contentType.match(/application\/rest\+json/)){
-				var size = data.length;
-				data = data.replace(/^\s*[,\[]?/,'['). // must start with a opening bracket
-					replace(/[,\]]?\s*$/,']'); // and end with a closing bracket
-				try{
-					// if this fails, it probably means we have an incomplete JSON object
-					var xhrs = dojo.fromJson(data);
-					this.lastIndex += size;
-				}
-				catch(e){
-				}
-			}else if(dojox.io && dojox.io.httpParse && contentType.match(/application\/http/)){
-				// do HTTP tunnel parsing
-				var topHeaders = '';
-				if(xhr && xhr.getAllResponseHeaders){
-					// mixin/inherit headers from the container response
-					topHeaders = xhr.getAllResponseHeaders();
-				}
-				xhrs = dojox.io.httpParse(data,topHeaders,xhr.readyState != 4);
-			}else if(typeof data == "object"){
-				xhrs = data;
-			}
-			if(xhrs){
-				for(var i = 0;i < xhrs.length;i++){
-					if(this._processMessage(xhrs[i])){
-						return "conflict";
-					}
-				}
-				return null;
-			}
-			if(!xhr){
-				//no streaming and we didn't get any message, must be an error
-				return "error";
-			}
-			if(xhr.readyState != 4){ // we only want finished responses here if we are not streaming
-				return null;
-			}
-			if(xhr.__proto__){// firefox uses this property, so we create an instance to shadow this property
-				xhr = {channel:"channel",__proto__:xhr};
-			}
-			return this._processMessage(xhr);
-
-		},
-
-		get: function(/*String*/channel, /*dojo.__XhrArgs?*/args){
-			// summary:
-			// 		GET the initial value of the resource and subscribe to it
-			//		See subscribe for parameter values
-			(args = args || {}).method = "GET";
-			return this.subscribe(channel,args);
-		},
-		receive: function(message){
-			// summary:
-			//		Called when a message is received from the server
-			//	message:
-			//		A cometd/XHR message
-			if(dojox.data && dojox.data.restListener){
-				dojox.data.restListener(message);
-			}
-		},
-		disconnected: function(){
-			// summary:
-			// 		called when our channel gets disconnected
-			var self = this;
-			if(this.connected){
-				this.connected = false;
-				if(this.started){ // if we are started, we shall try to reconnect
-					setTimeout(function(){ // auto reconnect
-						// resubscribe to our current subscriptions
-						var subscriptions = self.subscriptions;
-						self.subscriptions = {};
-						for(var i in subscriptions){
-							if(self.reloadDataOnReconnect && dojox.rpc.JsonRest){
-								// do a reload of the resource
-								delete dojox.rpc.Rest._index[i];
-								dojox.rpc.JsonRest.fetch(i);
-							}else{
-								self.subscribe(i,{since:subscriptions[i]});
-							}
-						}
-						self.open();
-					}, this.autoReconnectTime);
-				}
-			}
-		},
-		unsubscribe: function(/*String*/channel, /*dojo.__XhrArgs?*/args){
-			// summary:
-			// 		unsubscribes from the resource
-			//		See subscribe for parameter values
-
-			args = args || {};
-			args.unsubscribe = true;
-			this.subscribe(channel,args); // change the time frame to after 5000AD
-		},
-		disconnect: function(){
-			// summary:
-			// 		disconnect from the server
-			this.started = false;
-			this.xhr.abort();
-		}
-	});
-	var Channels = dojox.cometd.RestChannels.defaultInstance = new dojox.cometd.RestChannels();
-	if(dojox.cometd.connectionTypes){
-		// register as a dojox.cometd transport and wire everything for cometd handling
-		// below are the necessary adaptions for cometd
-		Channels.startup = function(data){ // must be able to handle objects or strings
-			Channels.open();
-			this._cometd._deliver({channel:"/meta/connect",successful:true}); // tell cometd we are connected so it can proceed to send subscriptions, even though we aren't yet
-
-		};
-		Channels.check = function(types, version, xdomain){
-			for(var i = 0; i< types.length; i++){
-				if(types[i] == "rest-channels"){
-					return !xdomain;
-				}
-			}
-			return false;
-		};
-		Channels.deliver = function(message){
-			// nothing to do
-		};
-		dojo.connect(this,"receive",null,function(message){
-			message.data = message.result;
-			this._cometd._deliver(message);
-		});
-		Channels.sendMessages = function(messages){
-			for(var i = 0; i < messages.length; i++){
-				var message = messages[i];
-				var channel = message.channel;
-				var cometd = this._cometd;
-				var args = {
-					confirmation: function(){ // send a confirmation back to cometd
-						cometd._deliver({channel:channel,successful:true});
-					}
-				};
-				if(channel == '/meta/subscribe'){
-					this.subscribe(message.subscription,args);
-				}else if(channel == '/meta/unsubscribe'){
-					this.unsubscribe(message.subscription,args);
-				}else if(channel == '/meta/connect'){
-					args.confirmation();
-				}else if(channel == '/meta/disconnect'){
-					Channels.disconnect();
-					args.confirmation();
-				}else if(channel.substring(0,6) != '/meta/'){
-					this.publish(channel,message.data);
-				}
-			}
-		};
-		dojox.cometd.connectionTypes.register("rest-channels", Channels.check, Channels,false,true);
-	}
-})();
diff --git a/dojox/cometd/_base.js b/dojox/cometd/_base.js
deleted file mode 100644
index 7190c4b..0000000
--- a/dojox/cometd/_base.js
+++ /dev/null
@@ -1,754 +0,0 @@
-dojo.provide("dojox.cometd._base");
-dojo.require("dojo.AdapterRegistry");
-
-
-/*
- * this file defines Comet protocol client. Actual message transport is
- * deferred to one of several connection type implementations. The default is a
- * long-polling implementation. A single global object named "dojox.cometd" is
- * used to mediate for these connection types in order to provide a stable
- * interface.
- *
- * extensions modules may be loaded (eg "dojox.cometd.timestamp", that use
- * the cometd._extendInList and cometd._extendOutList fields to provide functions
- * that extend and handling incoming and outgoing messages.
- *
- * By default the long-polling and callback-polling transports will be required.
- * If specific or alternative transports are required, then they can be directly
- * loaded. For example dojo.require('dojox.cometd.longPollTransportJsonEncoded')
- * will load cometd with only the json encoded variant of the long polling transport.
- */
-
-dojox.cometd = {
-	Connection: function(prefix){ // This constructor is stored as dojox.cometd.Connection
-		// summary
-		// This constructor is used to create new cometd connections. Generally, you should use
-		// one cometd connection for each server you connect to. A default connection instance is
-		// created at dojox.cometd.
-		// To connect to a new server you can create an instance like:
-		// var cometd = new dojox.cometd.Connection("/otherServer");
-		// cometd.init("http://otherServer.com/cometd");
-		//
-		// prefix is the prefix for all the events that are published in the Dojo pub/sub system.
-		// You must include this prefix, and it should start with a slash like "/myprefix".
-		
-		// cometd states:
-		// unconnected, handshaking, connecting, connected, disconnected
-		dojo.mixin(this, {
-		prefix: prefix,
-			_status: "unconnected",
-			_handshook: false,
-			_initialized: false,
-			_polling: false,
-		
-			expectedNetworkDelay: 10000, // expected max network delay
-			connectTimeout: 0,		 // If set, used as ms to wait for a connect response and sent as the advised timeout
-		
-			version:	"1.0",
-			minimumVersion: "0.9",
-			clientId: null,
-			messageId: 0,
-			batch: 0,
-		
-			_isXD: false,
-			handshakeReturn: null,
-			currentTransport: null,
-			url: null,
-			lastMessage: null,
-			_messageQ: [],
-			handleAs: "json",
-			_advice: {},
-			_backoffInterval: 0,
-			_backoffIncrement: 1000,
-			_backoffMax: 60000,
-			_deferredSubscribes: {},
-			_deferredUnsubscribes: {},
-			_subscriptions: [],
-			_extendInList: [],	// List of functions invoked before delivering messages
-			_extendOutList: []	// List of functions invoked before sending messages
-			
-		});
-	
-		this.state = function() {
-			 return this._status;
-		}
-	
-		this.init = function(	/*String*/	root,
-					/*Object?*/ props,
-					/*Object?*/ bargs){	// return: dojo.Deferred
-			//	summary:
-			//		Initialize the cometd implementation of the Bayeux protocol
-			//	description:
-			//		Initialize the cometd implementation of the Bayeux protocol by
-			//		sending a handshake message. The cometd state will be changed to CONNECTING
-			//		until a handshake response is received and the first successful connect message
-			//		has returned.
-			//		The protocol state changes may be monitored
-			//		by subscribing to the dojo topic "/prefix/meta" (typically "/cometd/meta") where
-			//		events are published in the form
-			//		   {cometd:this,action:"handshake",successful:true,state:this.state()}
-			//	root:
-			//		The URL of the cometd server. If the root is absolute, the host
-			//		is examined to determine if xd transport is needed. Otherwise the
-			//		same domain is assumed.
-			//	props:
-			//		An optional object that is used as the basis of the handshake message
-			//	bargs:
-			//		An optional object of bind args mixed in with the send of the handshake
-			//	example:
-			//	|	dojox.cometd.init("/cometd");
-			//	|	dojox.cometd.init("http://xdHost/cometd",{ext:{user:"fred",pwd:"secret"}});
-	
-			// FIXME: if the root isn't from the same host, we should automatically
-			// try to select an XD-capable transport
-			props = props || {};
-			// go ask the short bus server what we can support
-			props.version = this.version;
-			props.minimumVersion = this.minimumVersion;
-			props.channel = "/meta/handshake";
-			props.id = "" + this.messageId++;
-	
-			this.url = root || dojo.config["cometdRoot"];
-			if(!this.url){
-				throw "no cometd root";
-				return null;
-			}
-	
-			// Are we x-domain? borrowed from dojo.uri.Uri in lieu of fixed host and port properties
-			var regexp = "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$";
-			var parts = ("" + window.location).match(new RegExp(regexp));
-			if(parts[4]){
-				var tmp = parts[4].split(":");
-				var thisHost = tmp[0];
-				var thisPort = tmp[1]||"80"; // FIXME: match 443
-	
-				parts = this.url.match(new RegExp(regexp));
-				if(parts[4]){
-					tmp = parts[4].split(":");
-					var urlHost = tmp[0];
-					var urlPort = tmp[1]||"80";
-					this._isXD = ((urlHost != thisHost)||(urlPort != thisPort));
-				}
-			}
-	
-			if(!this._isXD){
-				props.supportedConnectionTypes = dojo.map(dojox.cometd.connectionTypes.pairs, "return item[0]");
-			}
-	
-			props = this._extendOut(props);
-	
-			var bindArgs = {
-				url: this.url,
-				handleAs: this.handleAs,
-				content: { "message": dojo.toJson([props]) },
-				load: dojo.hitch(this,function(msg){
-					this._backon();
-					this._finishInit(msg);
-				}),
-				error: dojo.hitch(this,function(e){
-					this._backoff();
-					this._finishInit(e);
-				}),
-				timeout: this.expectedNetworkDelay
-			};
-	
-			if(bargs){
-				dojo.mixin(bindArgs, bargs);
-			}
-			this._props = props;
-			for(var tname in this._subscriptions){
-				for(var sub in this._subscriptions[tname]){
-					if(this._subscriptions[tname][sub].topic){
-						dojo.unsubscribe(this._subscriptions[tname][sub].topic);
-					}
-				}
-			}
-			this._messageQ = [];
-			this._subscriptions = [];
-			this._initialized = true;
-			this._status = "handshaking";
-			this.batch = 0;
-			this.startBatch();
-			
-			var r;
-			// if xdomain, then we assume jsonp for handshake
-			if(this._isXD){
-				bindArgs.callbackParamName = "jsonp";
-				r = dojo.io.script.get(bindArgs);
-			}else{
-				r = dojo.xhrPost(bindArgs);
-			}
-			return r;
-		}
-		
-		this.publish = function(/*String*/ channel, /*Object*/ data, /*Object?*/ props){
-			// summary:
-			//		publishes the passed message to the cometd server for delivery
-			//		on the specified topic
-			// channel:
-			//		the destination channel for the message
-			// data:
-			//		a JSON object containing the message "payload"
-			// properties:
-			//		Optional. Other meta-data to be mixed into the top-level of the
-			//		message
-			var message = {
-				data: data,
-				channel: channel
-			};
-			if(props){
-				dojo.mixin(message, props);
-			}
-			this._sendMessage(message);
-		}
-	
-		
-		this.subscribe = function(	/*String */	channel,
-						/*Object */	objOrFunc,
-						/*String */	funcName,
-						/*Object?*/ props){ // return: dojo.Deferred
-			//	summary:
-			//		inform the server of this client's interest in channel
-			//	description:
-			//		`dojox.cometd.subscribe()` handles all the hard work of telling
-			//		the server that we want to be notified when events are
-			//		published on a particular topic. `subscribe` accepts a function
-			//		to handle messages and returns a `dojo.Deferred` object which
-			//		has an extra property added to it which makes it suitable for
-			//		passing to `dojox.cometd.unsubscribe()` as a "subscription
-			//		handle" (much like the handle object that `dojo.connect()`
-			//		produces and which `dojo.disconnect()` expects).
-			//
-			//		Note that of a subscription is registered before a connection
-			//		with the server is established, events sent before the
-			//		connection is established will not be delivered to this client.
-			//		The deferred object which `subscribe` returns will callback
-			//		when the server successfuly acknolwedges receipt of our
-			//		"subscribe" request.
-			//	channel:
-			//		name of the cometd channel to subscribe to
-			//	objOrFunc:
-			//		an object scope for funcName or the name or reference to a
-			//		function to be called when messages are delivered to the
-			//		channel
-			//	funcName:
-			//		the second half of the objOrFunc/funcName pair for identifying
-			//		a callback function to notifiy upon channel message delivery
-			//	example:
-			//		Simple subscribe use-case
-			//	|	dojox.cometd.init("http://myserver.com:8080/cometd");
-			//	|	// log out all incoming messages on /foo/bar
-			//	|	dojox.cometd.subscribe("/foo/bar", console, "debug");
-			//	example:
-			//		Subscribe before connection is initialized
-			//	|	dojox.cometd.subscribe("/foo/bar", console, "debug");
-			//	|	dojox.cometd.init("http://myserver.com:8080/cometd");
-			//	example:
-			//		Subscribe an unsubscribe
-			//	|	dojox.cometd.init("http://myserver.com:8080/cometd");
-			//	|	var h = dojox.cometd.subscribe("/foo/bar", console, "debug");
-			//	|	dojox.cometd.unsubscribe(h);
-			//	example:
-			//		Listen for successful subscription:
-			//	|	dojox.cometd.init("http://myserver.com:8080/cometd");
-			//	|	var h = dojox.cometd.subscribe("/foo/bar", console, "debug");
-			//	|	h.addCallback(function(){
-			//	|		console.debug("subscription to /foo/bar established");
-			//	|	});
-	
-			props = props||{};
-			if(objOrFunc){
-				var tname = prefix + channel;
-				var subs = this._subscriptions[tname];
-				if(!subs || subs.length == 0){
-					subs = [];
-					props.channel = "/meta/subscribe";
-					props.subscription = channel;
-					this._sendMessage(props);
-					
-					var _ds = this._deferredSubscribes;
-					if(_ds[channel]){
-						_ds[channel].cancel();
-						delete _ds[channel];
-					}
-					_ds[channel] = new dojo.Deferred();
-				}
-				
-				for(var i in subs){
-					if(subs[i].objOrFunc === objOrFunc && (!subs[i].funcName&&!funcName||subs[i].funcName==funcName) ){
-						return null;
-					}
-				}
-				
-				var topic = dojo.subscribe(tname, objOrFunc, funcName);
-				subs.push({
-					topic: topic,
-					objOrFunc: objOrFunc,
-					funcName: funcName
-				});
-				this._subscriptions[tname] = subs;
-			}
-			var ret = this._deferredSubscribes[channel] || {};
-			ret.args = dojo._toArray(arguments);
-			return ret; // dojo.Deferred
-		}
-	
-		this.unsubscribe = function(	/*String*/	channel,
-						/*Object?*/ objOrFunc,
-						/*String?*/ funcName,
-						/*Object?*/ props){
-			// summary:
-			//		inform the server of this client's disinterest in channel
-			// channel:
-			//		name of the cometd channel to unsubscribe from
-			// objOrFunc:
-			//		an object scope for funcName or the name or reference to a
-			//		function to be called when messages are delivered to the
-			//		channel. If null then all subscribers to the channel are unsubscribed.
-			// funcName:
-			//		the second half of the objOrFunc/funcName pair for identifying
-			//		a callback function to notifiy upon channel message delivery
-	
-			if(
-				(arguments.length == 1) &&
-				(!dojo.isString(channel)) &&
-				(channel.args)
-			){
-				// it's a subscription handle, unroll
-				return this.unsubscribe.apply(this, channel.args);
-			}
-			
-			var tname = prefix + channel;
-			var subs = this._subscriptions[tname];
-			if(!subs || subs.length==0){
-				return null;
-			}
-	
-			var s=0;
-			for(var i in subs){
-				var sb = subs[i];
-				if((!objOrFunc) ||
-					(
-						sb.objOrFunc===objOrFunc &&
-						(!sb.funcName && !funcName || sb.funcName==funcName)
-					)
-				){
-					dojo.unsubscribe(subs[i].topic);
-					delete subs[i];
-				}else{
-					s++;
-				}
-			}
-			
-			if(s == 0){
-				props = props || {};
-				props.channel = "/meta/unsubscribe";
-				props.subscription = channel;
-				delete this._subscriptions[tname];
-				this._sendMessage(props);
-				this._deferredUnsubscribes[channel] = new dojo.Deferred();
-				if(this._deferredSubscribes[channel]){
-					this._deferredSubscribes[channel].cancel();
-					delete this._deferredSubscribes[channel];
-				}
-			}
-			return this._deferredUnsubscribes[channel]; // dojo.Deferred
-		}
-		
-		
-		this.disconnect = function(){
-			//	summary:
-			//		Disconnect from the server.
-			//	description:
-			//		Disconnect from the server by sending a disconnect message
-			//	example:
-			//	|	dojox.cometd.disconnect();
-	
-			for(var tname in this._subscriptions){
-				for(var sub in this._subscriptions[tname]){
-					if(this._subscriptions[tname][sub].topic){
-						dojo.unsubscribe(this._subscriptions[tname][sub].topic);
-					}
-				}
-			}
-			this._subscriptions = [];
-			this._messageQ = [];
-			if(this._initialized && this.currentTransport){
-				this._initialized=false;
-				this.currentTransport.disconnect();
-			}
-			if(!this._polling) {
-				this._publishMeta("connect",false);
-			}
-			this._initialized=false;
-			this._handshook=false;
-			this._status = "disconnected"; //should be disconnecting, but we ignore the reply to this message
-			this._publishMeta("disconnect",true);
-		}
-	
-		
-		// public extension points
-		
-		this.subscribed = function(	/*String*/channel, /*Object*/message){ }
-	
-		this.unsubscribed = function(/*String*/channel, /*Object*/message){ }
-	
-	
-		// private methods (TODO name all with leading _)
-	
-		this.tunnelInit = function(childLocation, childDomain){
-			// placeholder - replaced by _finishInit
-		}
-		
-		this.tunnelCollapse = function(){
-			// placeholder - replaced by _finishInit
-		}
-		
-		this._backoff = function(){
-			if(!this._advice){
-				this._advice={reconnect:"retry",interval:0};
-			}else if(!this._advice.interval){
-				this._advice.interval = 0;
-			}
-			
-			if(this._backoffInterval < this._backoffMax){
-				this._backoffInterval += this._backoffIncrement;
-			}
-		}
-		
-		this._backon = function(){
-			this._backoffInterval=0;
-		}
-	
-		this._interval = function(){
-			var i = this._backoffInterval + (this._advice ? (this._advice.interval ? this._advice.interval : 0) : 0);
-			if (i>0){
-				console.log("Retry in interval+backoff=" + this._advice.interval + "+" + this._backoffInterval+"="+i+"ms");
-			}
-			return i;
-		}
-		
-		this._publishMeta = function(action,successful,props){
-			try {
-				var meta = {cometd:this,action:action,successful:successful,state:this.state()};
-				if (props){
-					dojo.mixin(meta, props);
-				}
-				dojo.publish(this.prefix + "/meta", [meta]);
-			} catch(e) {
-				console.log(e);
-			}
-		}
-	
-		this._finishInit = function(data){
-			//	summary:
-			//		Handle the handshake return from the server and initialize
-			//		connection if all is OK
-
-			if(this._status!="handshaking") {return;}
-
-
-			var wasHandshook = this._handshook;
-			var successful = false;
-			var metaMsg = {};
-
-			if (data instanceof Error) {
-				dojo.mixin(metaMsg,{
-					reestablish:false,
-					failure: true,
-					error: data,
-					advice: this._advice
-				});
-			} else {
-				data = data[0];
-				data = this._extendIn(data);
-				this.handshakeReturn = data;
-				// remember any advice
-				if(data["advice"]){
-					this._advice = data.advice;
-				}
-
-				successful = data.successful ? data.successful : false;
-
-				// check version
-				if(data.version < this.minimumVersion){
-					if (console.log)
-						console.log("cometd protocol version mismatch. We wanted", this.minimumVersion, "but got", data.version);
-					successful=false;
-					this._advice.reconnect="none";
-				}
-				dojo.mixin(metaMsg,{reestablish: successful && wasHandshook, response:data});
-			}
-
-			this._publishMeta("handshake",successful,metaMsg);
-			//in the meta listeners, disconnect() may have been called, so recheck it now to
-			//prevent resends or continuing with initializing the protocol
-			if(this._status!="handshaking") {return;}
-
-			// If all OK
-			if(successful){
-				this._status = "connecting";
-				this._handshook = true;
-				// pick a transport
-				this.currentTransport = dojox.cometd.connectionTypes.match(
-					data.supportedConnectionTypes,
-					data.version,
-					this._isXD
-				);
-				var transport = this.currentTransport;
-				// initialize the transport
-				transport._cometd = this;
-				transport.version = data.version;
-				this.clientId = data.clientId;
-				this.tunnelInit = transport.tunnelInit && dojo.hitch(transport, "tunnelInit");
-				this.tunnelCollapse = transport.tunnelCollapse && dojo.hitch(transport, "tunnelCollapse");
-				transport.startup(data);
-			}else{
-				// If there is a problem follow advice
-				if(!this._advice || this._advice["reconnect"] != "none"){
-					setTimeout(dojo.hitch(this, "init", this.url, this._props), this._interval());
-				}
-			}
-		}
-	
-		// FIXME: lots of repeated code...why?
-		this._extendIn = function(message){
-			// summary: Handle extensions for inbound messages
-			dojo.forEach(dojox.cometd._extendInList, function(f){
-				message = f(message) || message;
-			});
-			return message;
-		}
-	
-		this._extendOut = function(message){
-			// summary: Handle extensions for inbound messages
-			dojo.forEach(dojox.cometd._extendOutList, function(f){
-				message = f(message) || message;
-			});
-			return message;
-		}
-	
-		this.deliver = function(messages){
-			dojo.forEach(messages, this._deliver, this);
-			return messages;
-		}
-	
-		this._deliver = function(message){
-			// dipatch events along the specified path
-			
-			message = this._extendIn(message);
-	
-			if(!message["channel"]){
-				if(message["success"] !== true){
-					return;
-				}
-			}
-			this.lastMessage = message;
-	
-			if(message.advice){
-				this._advice = message.advice; // TODO maybe merge?
-			}
-	
-			// check to see if we got a /meta channel message that we care about
-			var deferred=null;
-			if(	(message["channel"]) &&
-				(message.channel.length > 5) &&
-				(message.channel.substr(0, 5) == "/meta")){
-				// check for various meta topic actions that we need to respond to
-				switch(message.channel){
-					case "/meta/connect":
-						var metaMsg = {response: message};
-						if(message.successful) {
-							if (this._status != "connected"){
-								this._status = "connected";
-								this.endBatch();
-							}
-						}
- 
-						if(this._initialized){
-							this._publishMeta("connect",message.successful, metaMsg);
-						}
-						break;
-					case "/meta/subscribe":
-						deferred = this._deferredSubscribes[message.subscription];
-						try
-						{
-							if(!message.successful){
-								if(deferred){
-									deferred.errback(new Error(message.error));
-								}
-								this.currentTransport.cancelConnect();
-								return;
-							}
-							if(deferred){
-								deferred.callback(true);
-							}
-							this.subscribed(message.subscription, message);
-						} catch(e)	{
-							log.warn(e);
-						}
-						break;
-					case "/meta/unsubscribe":
-						deferred = this._deferredUnsubscribes[message.subscription];
-						try
-						{
-							if(!message.successful){
-								if(deferred){
-									deferred.errback(new Error(message.error));
-								}
-								this.currentTransport.cancelConnect();
-								return;
-							}
-							if(deferred){
-								deferred.callback(true);
-							}
-							this.unsubscribed(message.subscription, message);
-						} catch(e)	{
-							log.warn(e);
-						}
-						break;
-					default:
-						if(message.successful && !message.successful){
-							this.currentTransport.cancelConnect();
-							return;
-						}
-				}
-			}
-			
-			// send the message down for processing by the transport
-			this.currentTransport.deliver(message);
-	
-			if(message.data){
-				// dispatch the message to any locally subscribed listeners
-				try{
-					var messages = [message];
-	
-					// Determine target topic
-					var tname = prefix + message.channel;
-	
-					// Deliver to globs that apply to target topic
-					var tnameParts = message.channel.split("/");
-					var tnameGlob = prefix;
-					for (var i = 1; i < tnameParts.length - 1; i++){
-						dojo.publish(tnameGlob + "/**", messages);
-						tnameGlob += "/" + tnameParts[i];
-					}
-					dojo.publish(tnameGlob + "/**", messages);
-					dojo.publish(tnameGlob + "/*", messages);
-		
-					// deliver to target topic
-					dojo.publish(tname,messages);
-				}catch(e){
-					console.log(e);
-				}
-			}
-		}
-	
-		this._sendMessage = function(/* object */ message){
-			if(this.currentTransport && !this.batch){
-				return this.currentTransport.sendMessages([message]);
-			}else{
-				this._messageQ.push(message);
-				return null;
-			}
-		}
-	
-		this.startBatch = function(){
-			this.batch++;
-		}
-	
-		this.endBatch = function(){
-			if(--this.batch <= 0 && this.currentTransport && this._status == "connected"){
-				this.batch = 0;
-				var messages = this._messageQ;
-				this._messageQ = [];
-				if(messages.length > 0){
-					this.currentTransport.sendMessages(messages);
-				}
-			}
-		}
-		
-		this._onUnload = function(){
-			// make this the last of the onUnload method
-			dojo.addOnUnload(dojox.cometd, "disconnect");
-		}
-	
-		this._connectTimeout = function(){
-			// summary: Return the connect timeout in ms, calculated as the minimum of the advised timeout
-			// and the configured timeout. Else 0 to indicate no client side timeout
-			var advised=0;
-			if(this._advice && this._advice.timeout && this.expectedNetworkDelay > 0){
-				advised = this._advice.timeout + this.expectedNetworkDelay;
-			}
-			
-			if(this.connectTimeout > 0 && this.connectTimeout < advised){
-				return this.connectTimeout;
-			}
-			
-			return advised;
-		}
-	},
-	// connectionTypes are shared by all cometd Connection.
-	connectionTypes : new dojo.AdapterRegistry(true)
-}
-
-// create the default instance
-dojox.cometd.Connection.call(dojox.cometd,"/cometd");
-
-/*
-
-FIXME: TODOC: this info should be part of the relevant functions and/or overview so
-the parser can find it.
-
-transport objects MUST expose the following methods:
-	- check
-	- startup
-	- sendMessages
-	- deliver
-	- disconnect
-optional, standard but transport dependent methods are:
-	- tunnelCollapse
-	- tunnelInit
-
-Transports SHOULD be namespaced under the cometd object and transports MUST
-register themselves with cometd.connectionTypes
-
-here's a stub transport defintion:
-
-cometd.blahTransport = new function(){
-	this._connectionType="my-polling";
-	this._cometd=null;
-	this.lastTimestamp = null;
-
-	this.check = function(types, version, xdomain){
-		// summary:
-		//		determines whether or not this transport is suitable given a
-		//		list of transport types that the server supports
-		return dojo.inArray(types, "blah");
-	}
-
-	this.startup = function(){
-		if(dojox.cometd._polling){ return; }
-		// FIXME: fill in startup routine here
-		dojox.cometd._polling = true;
-	}
-
-	this.sendMessages = function(message){
-		// FIXME: fill in message array sending logic
-	}
-
-	this.deliver = function(message){
-	}
-
-	this.disconnect = function(){
-		// send orderly disconnect message
-	}
-
-	this.cancelConnect = function(){
-		// cancel the current connection
-	}
-}
-cometd.connectionTypes.register("blah", cometd.blahTransport.check, cometd.blahTransport);
-*/
-
-dojo.addOnUnload(dojox.cometd, "_onUnload");
diff --git a/dojox/cometd/ack.js b/dojox/cometd/ack.js
deleted file mode 100644
index 4decdf3..0000000
--- a/dojox/cometd/ack.js
+++ /dev/null
@@ -1,50 +0,0 @@
-dojo.provide("dojox.cometd.ack");
-dojo.require("dojox.cometd._base");
-
-/*
- * This file provides the dojox cometd ack extension which
- * acknowledges the messages received in /meta/connect responses.
- * Each meta/connect is sent with the id of the last successful meta/connect
- * received.  The server uses this information to manage a queue of unacknowleged
- * messages.
- *
- * To use, add dojo.require("dojox.cometd.ack"); and if the handshake will be sent
- * with ext:{ack:true}.  If the server supports the same extension, then the
- * mechanism will be initialized.  The dojox.cometd.ackEnabled field may also be
- * used to optionally enable/disable the extension before init of cometd.
- *
- */
-dojox.cometd._ack = new function(){
-	var supportAcks = false;
-	var lastAck = -1;
-	
-	this._in = function(msg){
-		if (msg.channel == "/meta/handshake") {
-			supportAcks = msg.ext && msg.ext.ack;
-		} else if (supportAcks && msg.channel == "/meta/connect" && msg.ext && msg.ext.ack && msg.successful) {
-			var ackId = parseInt(msg.ext.ack);
-			lastAck = ackId;
-		}
-		return msg;
-	}
-	
-	this._out = function(msg){
-	
-		if (msg.channel == "/meta/handshake") {
-			if (!msg.ext)
-				msg.ext = {};
-			msg.ext.ack = dojox.cometd.ackEnabled;
-			lastAck = -1;
-		}
-		if (supportAcks && msg.channel == "/meta/connect") {
-			if (!msg.ext)
-				msg.ext = {};
-			msg.ext.ack = lastAck;
-		}
-		return msg;
-	}
-};
-
-dojox.cometd._extendInList.push(dojo.hitch(dojox.cometd._ack, "_in"));
-dojox.cometd._extendOutList.push(dojo.hitch(dojox.cometd._ack, "_out"));
-dojox.cometd.ackEnabled = true;
diff --git a/dojox/cometd/callbackPollTransport.js b/dojox/cometd/callbackPollTransport.js
deleted file mode 100644
index e9baf9c..0000000
--- a/dojox/cometd/callbackPollTransport.js
+++ /dev/null
@@ -1,102 +0,0 @@
-dojo.provide("dojox.cometd.callbackPollTransport");
-dojo.require("dojox.cometd._base");
-dojo.require("dojox.cometd.longPollTransport");
-dojo.require("dojo.io.script");
-
-dojox.cometd.callbackPollTransport = new function(){
-
-	this._connectionType = "callback-polling";
-	this._cometd = null;
-
-	this.check = function(types, version, xdomain){
-		// we handle x-domain!
-		return (dojo.indexOf(types, "callback-polling") >= 0);
-	}
-
-	this.tunnelInit = function(){
-		var message = {
-			channel:	"/meta/connect",
-			clientId:	this._cometd.clientId,
-			connectionType: this._connectionType,
-			id:	"" + this._cometd.messageId++
-		};
-		message = this._cometd._extendOut(message);
-		this.openTunnelWith([message]);
-	}
-
-	this.tunnelCollapse = dojox.cometd.longPollTransport.tunnelCollapse;
-	this._connect = dojox.cometd.longPollTransport._connect;
-	this.deliver = dojox.cometd.longPollTransport.deliver;
-
-	this.openTunnelWith = function(content, url){
-		this._cometd._polling = true;
-		var script = {
-			load: dojo.hitch(this, function(data){
-				this._cometd._polling=false;
-				this._cometd.deliver(data);
-				this._cometd._backon();
-				this.tunnelCollapse();
-			}),
-			error: dojo.hitch(this, function(err){
-				this._cometd._polling = false;
-				this._cometd._publishMeta("connect",false);
-				this._cometd._backoff();
-				this.tunnelCollapse();
-			}),
-			url: (url || this._cometd.url),
-			content: { message: dojo.toJson(content) },
-			callbackParamName: "jsonp"
-		};
-		var connectTimeout = this._cometd._connectTimeout();
-		if(connectTimeout > 0){
-			script.timeout=connectTimeout;
-		}
-		dojo.io.script.get(script);
-	}
-
-	this.sendMessages = function(/*array*/ messages){
-		for(var i = 0; i < messages.length; i++){
-			messages[i].clientId = this._cometd.clientId;
-			messages[i].id = ""+this._cometd.messageId++;
-			messages[i]=this._cometd._extendOut(messages[i]);
-		}
-
-		var bindArgs = {
-			url: this._cometd.url || dojo.config["cometdRoot"],
-			load: dojo.hitch(this._cometd, "deliver"),
-			callbackParamName: "jsonp",
-			content: { message: dojo.toJson( messages ) },
-			error: dojo.hitch(this, function(err){
-				this._cometd._publishMeta("publish",false,{messages:messages});
-			}),
-			timeout: this._cometd.expectedNetworkDelay
-		};
-		return dojo.io.script.get(bindArgs);
-	}
-
-	this.startup = function(handshakeData){
-		if(this._cometd._connected){ return; }
-		this.tunnelInit();
-	}
-
-	// FIXME: what is this supposed to do? ;)
-	this.disconnect = dojox.cometd.longPollTransport.disconnect;
-	this.disconnect = function(){
-		var message = {
-			channel: "/meta/disconnect",
-			clientId: this._cometd.clientId,
-			id: "" + this._cometd.messageId++
-		};
-		message = this._cometd._extendOut(message);
-		dojo.io.script.get({
-			url: this._cometd.url || dojo.config["cometdRoot"],
-			callbackParamName: "jsonp",
-			content: { message: dojo.toJson([message]) }
-		});
-	}
-
-	this.cancelConnect = function(){}
-}
-
-dojox.cometd.connectionTypes.register("callback-polling", dojox.cometd.callbackPollTransport.check, dojox.cometd.callbackPollTransport);
-
diff --git a/dojox/cometd/longPollTransport.js b/dojox/cometd/longPollTransport.js
deleted file mode 100644
index d7b3b39..0000000
--- a/dojox/cometd/longPollTransport.js
+++ /dev/null
@@ -1,2 +0,0 @@
-dojo.provide("dojox.cometd.longPollTransport");
-dojo.require("dojox.cometd.longPollTransportJsonEncoded");
diff --git a/dojox/cometd/longPollTransportFormEncoded.js b/dojox/cometd/longPollTransportFormEncoded.js
deleted file mode 100644
index ca0b640..0000000
--- a/dojox/cometd/longPollTransportFormEncoded.js
+++ /dev/null
@@ -1,157 +0,0 @@
-dojo.provide("dojox.cometd.longPollTransportFormEncoded");
-dojo.require("dojox.cometd._base");
-
-dojox.cometd.longPollTransportFormEncoded = new function(){
-	// This is an alternative implementation to that provided in logPollTransport.js that
-	// form encodes all messages instead of sending them as text/json
-	
-	this._connectionType = "long-polling";
-	this._cometd = null;
-
-	this.check = function(types, version, xdomain){
-		return ((!xdomain)&&(dojo.indexOf(types, "long-polling") >= 0));
-	}
-
-	this.tunnelInit = function(){
-		var message = {
-			channel: "/meta/connect",
-			clientId: this._cometd.clientId,
-			connectionType: this._connectionType,
-			id:	"" + this._cometd.messageId++
-		};
-		message = this._cometd._extendOut(message);
-		this.openTunnelWith({ message: dojo.toJson([message]) });
-	}
-
-	this.tunnelCollapse = function(){
-		// TODO handle transport specific advice
-		
-		if(!this._cometd._initialized){ return; }
-		if(this._cometd._advice && this._cometd._advice["reconnect"]=="none"){
-			return;
-		}
-		var interval = this._cometd._interval();
-		if (this._cometd._status=="connected") {
-			setTimeout(dojo.hitch(this, "_connect"), interval);
-		}else{
-			setTimeout(dojo.hitch(this._cometd, function(){
-				this.init(this.url, this._props);
-			}), interval);
-		}
-	}
-
-	this._connect = function(){
-		if(!this._cometd._initialized){ return; }
-		if(this._cometd._polling) { return; }
-			
-		if((this._cometd._advice) && (this._cometd._advice["reconnect"]=="handshake")){
-			this._cometd._status="unconnected"; //?
-			this._initialized = false;
-			this._cometd.init(this._cometd.url, this._cometd._props);
- 		}else if(this._cometd._status=="connected"){
-			var message = {
-				channel: "/meta/connect",
-				connectionType: this._connectionType,
-				clientId: this._cometd.clientId,
-				id:	"" + this._cometd.messageId++
-			};
-			if(this._cometd.connectTimeout>=this._cometd.expectedNetworkDelay){
-				message.advice = {
-					timeout: this._cometd.connectTimeout - this._cometd.expectedNetworkDelay
-				};
-			}
-			message = this._cometd._extendOut(message);
-			this.openTunnelWith({ message: dojo.toJson([message]) });
-		}
-	}
-
-	this.deliver = function(message){
-		// Nothing to do
-	}
-
-	this.openTunnelWith = function(content, url){
-		this._cometd._polling = true;
-		var post = {
-			url: (url||this._cometd.url),
-			content: content,
-			handleAs: this._cometd.handleAs,
-			load: dojo.hitch(this, function(data){
-				this._cometd._polling=false;
-				this._cometd.deliver(data);
-				this._cometd._backon();
-				this.tunnelCollapse();
-			}),
-			error: dojo.hitch(this, function(err){
-				var metaMsg = {
-					failure: true,
-					error: err,
-					advice: this._cometd._advice
-				};
-				this._cometd._polling=false;
-				this._cometd._publishMeta("connect",false, metaMsg);
-				this._cometd._backoff();
-				this.tunnelCollapse();
-			})
-		};
-
-		var connectTimeout = this._cometd._connectTimeout();
-		if(connectTimeout > 0){
-			post.timeout = connectTimeout;
-		}
-
-		this._poll = dojo.xhrPost(post);
-	}
-
-	this.sendMessages = function(messages){
-		for(var i=0; i < messages.length; i++){
-			messages[i].clientId = this._cometd.clientId;
-			messages[i].id = "" + this._cometd.messageId++;
-			messages[i]= this._cometd._extendOut(messages[i]);
-		}
-		return dojo.xhrPost({
-			url: this._cometd.url||dojo.config["cometdRoot"],
-			handleAs: this._cometd.handleAs,
-			load: dojo.hitch(this._cometd, "deliver"),
-			content: { message: dojo.toJson(messages) },
-			error: dojo.hitch(this, function(err){
-				this._cometd._publishMeta("publish",false,{messages:messages});
-			}),
-			timeout: this._cometd.expectedNetworkDelay
-		});
-	}
-
-	this.startup = function(handshakeData){
-		if(this._cometd._status=="connected"){ return; }
-		this.tunnelInit();
-	}
-
-	this.disconnect = function(){
-		var message = {
-			channel: "/meta/disconnect",
-			clientId: this._cometd.clientId,
-			id: "" + this._cometd.messageId++
-		};
-		message = this._cometd._extendOut(message);
-		dojo.xhrPost({
-			url: this._cometd.url || dojo.config["cometdRoot"],
-			handleAs: this._cometd.handleAs,
-			content: { message: dojo.toJson([message]) }
-		});
-	}
-
-	this.cancelConnect = function(){
-		if(this._poll){
-			this._poll.cancel();
-			this._cometd._polling=false;
-			this._cometd._publishMeta("connect",false,{cancel:true});
-			this._cometd._backoff();
-			this.disconnect();
-			this.tunnelCollapse();
-		}
-	}
-}
-
-dojox.cometd.longPollTransport = dojox.cometd.longPollTransportFormEncoded;
-
-dojox.cometd.connectionTypes.register("long-polling", dojox.cometd.longPollTransport.check, dojox.cometd.longPollTransportFormEncoded);
-dojox.cometd.connectionTypes.register("long-polling-form-encoded", dojox.cometd.longPollTransport.check, dojox.cometd.longPollTransportFormEncoded);
diff --git a/dojox/cometd/longPollTransportJsonEncoded.js b/dojox/cometd/longPollTransportJsonEncoded.js
deleted file mode 100644
index b343c63..0000000
--- a/dojox/cometd/longPollTransportJsonEncoded.js
+++ /dev/null
@@ -1,159 +0,0 @@
-dojo.provide("dojox.cometd.longPollTransportJsonEncoded");
-dojo.require("dojox.cometd._base");
-
-dojox.cometd.longPollTransportJsonEncoded = new function(){
-	// This is an alternative implementation to that provided in logPollTransportFormEncoded.js
-	// that sends messages as text/json rather than form encoding them.
-	
-	this._connectionType="long-polling";
-	this._cometd=null;
-
-	this.check = function(types, version, xdomain){
-		return ((!xdomain)&&(dojo.indexOf(types, "long-polling") >= 0));
-	}
-
-	this.tunnelInit = function(){
-		var message = {
-			channel:	"/meta/connect",
-			clientId:	this._cometd.clientId,
-			connectionType: this._connectionType,
-			id:	""+this._cometd.messageId++
-		};
-		message=this._cometd._extendOut(message);
-		this.openTunnelWith([message]);
-	}
-
-	this.tunnelCollapse = function(){
-		// TODO handle transport specific advice
-		
-		if(!this._cometd._initialized){ return; }
-			
-		if(this._cometd._advice && this._cometd._advice["reconnect"]=="none"){
-			return;
-		}
-		if (this._cometd._status=="connected") {
-			setTimeout(dojo.hitch(this,function(){this._connect();}),this._cometd._interval());
-		}else{
-			setTimeout(dojo.hitch(this._cometd,function(){this.init(this.url,this._props);}),this._cometd._interval());
-		}
-	}
-
-	this._connect = function(){
-		if(!this._cometd._initialized){ return; }
-		if(this._cometd._polling) {
-			return;
-		}
-			
-		if((this._cometd._advice) && (this._cometd._advice["reconnect"]=="handshake")){
-			this._cometd._status="unconnected";
-			this._initialized = false;
-			this._cometd.init(this._cometd.url,this._cometd._props);
- 		}else if(this._cometd._status=="connected"){
-			var message={
-				channel:	"/meta/connect",
-				connectionType: this._connectionType,
-				clientId:	this._cometd.clientId,
-				id:	""+this._cometd.messageId++
-			};
-			if (this._cometd.connectTimeout>=this._cometd.expectedNetworkDelay){
-				message.advice={timeout:(this._cometd.connectTimeout-this._cometd.expectedNetworkDelay)};
-			}
-			message=this._cometd._extendOut(message);
-			this.openTunnelWith([message]);
-		}
-	}
-
-	this.deliver = function(message){
-		// Nothing to do
-	}
-
-	this.openTunnelWith = function(messages, url){
-		this._cometd._polling = true;
-		var post = {
-			url: (url||this._cometd.url),
-			postData: dojo.toJson(messages),
-			contentType: "text/json;charset=UTF-8",
-			handleAs: this._cometd.handleAs,
-			load: dojo.hitch(this, function(data){
-				this._cometd._polling=false;
-				this._cometd.deliver(data);
-				this._cometd._backon();
-				this.tunnelCollapse();
-			}),
-			error: dojo.hitch(this, function(err){
-				this._cometd._polling=false;
-				var metaMsg = {
-					failure: true,
-					error: err,
-					advice: this._cometd._advice
-				};
-				this._cometd._publishMeta("connect",false, metaMsg);
-				this._cometd._backoff();
-				this.tunnelCollapse();
-			})
-		};
-
-		var connectTimeout=this._cometd._connectTimeout();
-		if (connectTimeout>0) {
-			post.timeout=connectTimeout;
-		}
-
-		this._poll = dojo.rawXhrPost(post);
-	}
-
-	this.sendMessages = function(messages){
-		for(var i=0; i<messages.length; i++){
-			messages[i].clientId = this._cometd.clientId;
-			messages[i].id = ""+this._cometd.messageId++;
-			messages[i]=this._cometd._extendOut(messages[i]);
-		}
-		return dojo.rawXhrPost({
-			url: this._cometd.url||dojo.config["cometdRoot"],
-			handleAs: this._cometd.handleAs,
-			load: dojo.hitch(this._cometd, "deliver"),
-			postData: dojo.toJson(messages),
-			contentType: "text/json;charset=UTF-8",
-			error: dojo.hitch(this, function(err){
-				this._cometd._publishMeta("publish",false,{messages:messages});
-			}),
-			timeout: this._cometd.expectedNetworkDelay
-		});
-	}
-
-	this.startup = function(handshakeData){
-		if(this._cometd._status=="connected"){ return; }
-		this.tunnelInit();
-	}
-
-	this.disconnect = function(){
-		var message = {
-			channel: "/meta/disconnect",
-			clientId: this._cometd.clientId,
-			id:	"" + this._cometd.messageId++
-		};
-		message = this._cometd._extendOut(message);
-		dojo.rawXhrPost({
-			url: this._cometd.url || dojo.config["cometdRoot"],
-			handleAs: this._cometd.handleAs,
-			postData: dojo.toJson([message]),
-			contentType: "text/json;charset=UTF-8"
-		});
-	}
-
-	this.cancelConnect = function(){
-		if(this._poll){
-			this._poll.cancel();
-			this._cometd._polling=false;
-			this._cometd._publishMeta("connect",false,{cancel:true});
-			this._cometd._backoff();
-			this.disconnect();
-			this.tunnelCollapse();
-		}
-	}
-}
-
-dojox.cometd.longPollTransport = dojox.cometd.longPollTransportJsonEncoded;
-
-dojox.cometd.connectionTypes.register("long-polling", dojox.cometd.longPollTransport.check, dojox.cometd.longPollTransportJsonEncoded);
-dojox.cometd.connectionTypes.register("long-polling-json-encoded", dojox.cometd.longPollTransport.check, dojox.cometd.longPollTransportJsonEncoded);
-
diff --git a/dojox/cometd/tests/_base.js b/dojox/cometd/tests/_base.js
deleted file mode 100644
index ec33443..0000000
--- a/dojox/cometd/tests/_base.js
+++ /dev/null
@@ -1,31 +0,0 @@
-dojo.provide("dojox.cometd.tests._base");
-dojo.require("dojox.cometd");
-
-tests.register("dojox.cometd.tests._base", [
-
-	function basicSyntaxCheck(t){
-		// w00t, we made it! (FIXME: how to unit test basic functionality?)
-		// FIXME: gregw? include basicSyntax tests for other transports?
-		t.assertTrue(true);
-	},
-
-	function basicInitCheck(t){
-		var d = dojox.cometd.init("http://www.sitepen.com:9000/cometd");
-		if(d){
-			t.assertTrue(true);
-		}
-	},
-
-	function basicSubscribeCheck(t){
-		dojox.cometd.subscribe("/basic/unit/test", function(e){
-			console.log("message received", e);
-		});
-		t.assertTrue(true);
-	},
-
-	function basicPublishCheck(t){
-		dojox.cometd.publish("/basic/unit/test", [{ message: "unit test" }]);
-		t.assertTrue(true);
-	}
-
-]);
diff --git a/dojox/cometd/tests/all.js b/dojox/cometd/tests/all.js
deleted file mode 100644
index e681fe5..0000000
--- a/dojox/cometd/tests/all.js
+++ /dev/null
@@ -1,8 +0,0 @@
-dojo.provide("dojox.cometd.tests.all");
-dojo.require("dojox.cometd._base");
-
-try{
-	dojo.require("dojox.cometd.tests._base");
-}catch(e){
-	doh.debug(e);
-}
diff --git a/dojox/cometd/tests/runTests.html b/dojox/cometd/tests/runTests.html
deleted file mode 100644
index 9982545..0000000
--- a/dojox/cometd/tests/runTests.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-    <head>
-    <title>Dojox.wire Unit Test Runner</title>
-    <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojox.cometd.tests.all">
-	</head>
-    <body>
-        Redirecting to D.O.H runner.
-    </body>
-</html> 
diff --git a/dojox/cometd/timestamp.js b/dojox/cometd/timestamp.js
deleted file mode 100644
index d0c537e..0000000
--- a/dojox/cometd/timestamp.js
+++ /dev/null
@@ -1,8 +0,0 @@
-dojo.provide("dojox.cometd.timestamp");
-dojo.require("dojox.cometd._base");
-
-// A cometd extension that adds a timestamp to every message
-dojox.cometd._extendOutList.push(function(msg){
-	msg.timestamp = new Date().toUTCString();
-	return msg
-});
diff --git a/dojox/cometd/timesync.js b/dojox/cometd/timesync.js
deleted file mode 100644
index 99a3cbb..0000000
--- a/dojox/cometd/timesync.js
+++ /dev/null
@@ -1,141 +0,0 @@
-dojo.provide("dojox.cometd.timesync");
-dojo.require("dojox.cometd._base");
-
-/**
- * this file provides the time synchronization extension to cometd.
- * Timesync allows the client and server to exchange time information on every
- * handshake and connect message so that the client may calculate an approximate
- * offset from it's own clock epoch to that of the server.
- *
- * With each handshake or connect, the extension sends timestamps within the
- * ext field like: <code>{ext:{timesync:{tc:12345567890,l:23,o:4567},...},...}</code>
- * where:<ul>
- *  <li>tc is the client timestamp in ms since 1970 of when the message was sent.
- *  <li>l is the network lag that the client has calculated.
- *  <li>o is the clock offset that the client has calculated.
- * </ul>
- * The accuracy of the offset and lag may be calculated with tc-now-l-o,
- * which should be zero if the calculated offset and lag are perfectly
- * accurate.
- * <p>
- * A cometd server that supports timesync, should respond only if the
- * measured accuracy value is greater than accuracy target. The response
- * will be an ext field like: <code>{ext:{timesync:{tc:12345567890,ts:1234567900,p:123,a:3},...},...}</code>
- * where:<ul>
- *  <li>tc is the client timestamp of when the message was sent,
- *  <li>ts is the server timestamp of when the message was received
- *  <li>p is the poll duration in ms - ie the time the server took before sending the response.
- *  <li>a is the measured accuracy of the calculated offset and lag sent by the client
- * </ul>
- *
- * On receipt of the response, the client is able to use current time to determine
- * the total trip time, from which p is subtracted to determine an approximate
- * two way network traversal time. The measured accuracy is used to adjust the assumption
- * that the network is symmetric for traversal time, so: <ul>
- * <li>lag = (now-tc-p)/2-a
- * <li>offset = ts-tc-lag
- * </ul>
- *
- * In order to smooth over any transient fluctuations, the extension keeps a sliding
- * average of the offsets received. By default this is over 10 messages, but this can
- * be changed with the dojox.cometd.timesync._window element.
- */
-dojox.cometd.timesync = new function(){
-	this._window = 10;		// The window size for the sliding average of offset samples.
-	this._lags = [];		// The samples used to calculate the average lag.
-	this._offsets = [];		// The samples used to calculate the average offset.
-	this.lag=0;				// The calculated network lag from client to server
-	this.offset = 0;		// The offset in ms between the clients clock and the servers clock.
-	this.samples = 0; 		// The number of samples used to calculate the offset. If 0, the offset is not valid.
-	
-	this.getServerTime = function(){ // return: long
-		// Summary:
-		//	Calculate the current time on the server
-		//
-		return new Date().getTime()+this.offset;
-	}
-	
-	this.getServerDate = function(){ // return: Date
-		// Summary:
-		//	Calculate the current time on the server
-		//
-		return new Date(this.getServerTime());
-	}
-	
-	this.setTimeout = function(/*function*/call, /*long|Date*/atTimeOrDate){
-		// Summary:
-		//	Set a timeout function relative to server time
-		// call:
-		//	the function to call when the timeout occurs
-		// atTimeOrTime:
-		//	a long timestamp or a Date representing the server time at
-		//	which the timeout should occur.
-		
-		var ts = (atTimeOrDate instanceof Date) ? atTimeOrDate.getTime() : (0 + atTimeOrDate);
-		var tc = ts - this.offset;
-		var interval = tc - new Date().getTime();
-		if(interval <= 0){
-			interval = 1;
-		}
-		return setTimeout(call,interval);
-	}
-
-	this._in = function(/*Object*/msg){
-		// Summary:
-		//	Handle incoming messages for the timesync extension.
-		// description:
-		//	Look for ext:{timesync:{}} field and calculate offset if present.
-		// msg:
-		//	The incoming bayeux message
-		
-		var channel = msg.channel;
-		if(channel && channel.indexOf('/meta/') == 0){
-			if(msg.ext && msg.ext.timesync){
-				var sync = msg.ext.timesync;
-				var now = new Date().getTime();
-				var l=(now-sync.tc-sync.p)/2-sync.a;
-				var o=sync.ts-sync.tc-l;
-				
-				this._lags.push(l);
-				this._offsets.push(o);
-				if(this._offsets.length > this._window){
-					this._offsets.shift();
-					this._lags.shift();
-				}
-				this.samples++;
-				l=0;
-				o=0;
-				for(var i in this._offsets){
-					l+=this._lags[i];
-					o+=this._offsets[i];
-				}
-				this.offset = parseInt((o / this._offsets.length).toFixed());
-				this.lag = parseInt((l / this._lags.length).toFixed());
-				
-			}
-		}
-		return msg;
-	}
-
-	this._out = function(msg){
-		// Summary:
-		//	Handle outgoing messages for the timesync extension.
-		// description:
-		//	Look for handshake and connect messages and add the ext:{timesync:{}} fields
-		// msg:
-		//	The outgoing bayeux message
-		
-		var channel = msg.channel;
-		if(channel && channel.indexOf('/meta/') == 0){
-			var now = new Date().getTime();
-			if(!msg.ext){
-				msg.ext = {};
-			}
-			msg.ext.timesync = {tc:now,l:this.lag,o:this.offset};
-		}
-		return msg;
-	}
-};
-
-dojox.cometd._extendInList.push(dojo.hitch(dojox.cometd.timesync, "_in"));
-dojox.cometd._extendOutList.push(dojo.hitch(dojox.cometd.timesync, "_out"));
diff --git a/dojox/css3/README b/dojox/css3/README
index fe72cd3..c3cc87b 100644
--- a/dojox/css3/README
+++ b/dojox/css3/README
@@ -1,5 +1,5 @@
 -------------------------------------------------------------------------------
-dojox.css3
+dojox/css3
 -------------------------------------------------------------------------------
 Version: 0.1
 Release date: 03/06/2010
@@ -29,9 +29,9 @@ See the Dojo API tool (http://dojotoolkit.org/api)
 Installation instructions
 
 Grab the following from the Dojo SVN Repository:
-http://svn.dojotoolkit.org/src/dojo/dojox/trunk/css3/fx.js
+http://svn.dojotoolkit.org/src/dojo/dojox/trunk/css3/*
 
 Install into the following directory structure:
 /dojox/css3/
 
-...which should be at the same level as your Dojo checkout.
\ No newline at end of file
+...which should be at the same level as your Dojo checkout.
diff --git a/dojox/css3/fx.js b/dojox/css3/fx.js
index b447412..16114d0 100644
--- a/dojox/css3/fx.js
+++ b/dojox/css3/fx.js
@@ -1,5 +1,5 @@
 define([
-	"dojo/_base/kernel",
+	"dojo/_base/lang",
 	"dojo/_base/connect",	// dojo.connect
 	"dojo/dom-style",	// dojo.style
 	"dojo/_base/fx",
@@ -9,15 +9,17 @@ define([
 	"dojox/fx/ext-dojo/complex"],
 function(lang,connectUtil,domStyle,baseFx,coreFx,htmlUtil,htmlStyleExt,complexFx){
 	var css3fx = lang.getObject("dojox.css3.fx", true);
-	/*===== css3fx = dojox.css3.fx =====*/
-	
-	return lang.mixin(css3fx, {
-		puff: function(args){
+
+	var css3fxFunctions = {
+		// summary:
+		//		Utilities for animation effects.
+		
+		puff: function(/*Object*/args){
 			// summary:
-			//		Returns an animation that will do a "puff" effect on the given node
+			//		Returns an animation that will do a "puff" effect on the given node.
 			//
 			// description:
-			//		Fades out an element and scales it to args.endScale
+			//		Fades out an element and scales it to args.endScale.
 			//
 			return coreFx.combine([baseFx.fadeOut(args),
 				this.expand({
@@ -27,12 +29,12 @@ function(lang,connectUtil,domStyle,baseFx,coreFx,htmlUtil,htmlStyleExt,complexFx
 			]);
 		},
 
-		expand: function(args){
+		expand: function(/*Object*/args){
 			// summary:
-			//		Returns an animation that expands args.node
+			//		Returns an animation that expands args.node.
 			//
 			// description:
-			//		Scales an element to args.endScale
+			//		Scales an element to args.endScale.
 			//
 			return baseFx.animateProperty({
 				node: args.node,
@@ -42,9 +44,9 @@ function(lang,connectUtil,domStyle,baseFx,coreFx,htmlUtil,htmlStyleExt,complexFx
 			});
 		},
 
-		shrink: function(args){
+		shrink: function(/*Object*/args){
 			// summary:
-			//		Returns an animation that shrinks args.node
+			//		Returns an animation that shrinks args.node.
 			//
 			// description:
 			//		Shrinks an element, same as expand({ node: node, endScale: .01 });
@@ -55,12 +57,12 @@ function(lang,connectUtil,domStyle,baseFx,coreFx,htmlUtil,htmlStyleExt,complexFx
 			});
 		},
 
-		rotate: function(args){
+		rotate: function(/*Object*/args){
 			// summary:
-			//		Returns an animation that rotates an element
+			//		Returns an animation that rotates an element.
 			//
 			// description:
-			//		Rotates an element from args.startAngle to args.endAngle
+			//		Rotates an element from args.startAngle to args.endAngle.
 			//
 			return baseFx.animateProperty({
 				node: args.node,
@@ -71,13 +73,13 @@ function(lang,connectUtil,domStyle,baseFx,coreFx,htmlUtil,htmlStyleExt,complexFx
 			});
 		},
 
-		flip: function(args){
+		flip: function(/*Object*/args){
 			// summary:
-			//		Returns an animation that flips an element around his y axis
+			//		Returns an animation that flips an element around his y axis.
 			//
 			// description:
 			//		Flips an element around his y axis. The default is a 360deg flip
-			//		but it's possible to run a partial flip using args.whichAnims
+			//		but it is possible to run a partial flip using args.whichAnims.
 			//
 			// example:
 			//	|	// half flip
@@ -108,13 +110,13 @@ function(lang,connectUtil,domStyle,baseFx,coreFx,htmlUtil,htmlStyleExt,complexFx
 			return coreFx.chain(anims);
 		},
 
-		bounce: function(args){
+		bounce: function(/*Object*/args){
 			// summary:
-			//		Returns an animation that do a "bounce" effect on args.node
+			//		Returns an animation that does a "bounce" effect on args.node.
 			//
 			// description:
-			//		Vertical bounce animation, the scaleX, scaleY deformation and the
-			//		jump height (args.jumpHeight) can be specified
+			//		Vertical bounce animation. The scaleX, scaleY deformation and the
+			//		jump height (args.jumpHeight) can be specified.
 			//
 			var anims = [],
 				n = args.node,
@@ -187,5 +189,10 @@ function(lang,connectUtil,domStyle,baseFx,coreFx,htmlUtil,htmlStyleExt,complexFx
 
 			return coreFx.chain(anims);
 		}
-	});
+	};
+	
+	/*=====
+	return css3fxFunctions;
+	 =====*/
+	return lang.mixin(css3fx, css3fxFunctions);
 });
diff --git a/dojox/css3/transit.js b/dojox/css3/transit.js
index 203e94e..7c59322 100644
--- a/dojox/css3/transit.js
+++ b/dojox/css3/transit.js
@@ -1,30 +1,59 @@
-define(["dojo/_base/kernel", "dojo/_base/array","dojo/dom-style","dojo/DeferredList","./transition"],
-	function(dojo, darray, domStyle, DeferredList,transition){
-	var transit =  function(from, to, options){
+define(["dojo/_base/array", "dojo/dom-style", "dojo/promise/all", "dojo/sniff", "./transition"],
+	function(darray, domStyle, all, has, transition){
+	// module: 
+	//		dojox/css3/transit
+	
+	var transit = function(/*DomNode*/from, /*DomNode*/to, /*Object?*/options){
+		// summary:
+		//		Performs a transition to hide a node and show another node.
+		// description:
+		//		This module defines the transit method which is used
+		//		to transit the specific region of an application from 
+		//		one view/page to another view/page. This module relies 
+		//		on utilities provided by dojox/css3/transition for the 
+		//		transition effects.
+		// options:
+		//		The argument to specify the transit effect and direction.
+		//		The effect can be specified in options.transition. The
+		//		valid values are 'slide', 'flip', 'fade', 'none'.
+		//		The direction can be specified in options.reverse. If it
+		//		is true, the transit effects will be conducted in the
+		//		reverse direction to the default direction. Finally the duration
+		//		of the transition can be overridden by setting the duration property.
 		var rev = (options && options.reverse) ? -1 : 1;
-		if(!options || !options.transition || !transition[options.transition]){
-			domStyle.set(from,"display","none");
-			domStyle.set(to, "display", "");
+		if(!options || !options.transition || !transition[options.transition] || (has("ie") && has("ie") < 10)){
+			if(from){
+				domStyle.set(from,"display","none");
+			}
+			if(to){
+				domStyle.set(to, "display", "");
+			}
 			if(options.transitionDefs){
 				if(options.transitionDefs[from.id]){
 					options.transitionDefs[from.id].resolve(from);
 				}
 				if(options.transitionDefs[to.id]){
-								options.transitionDefs[to.id].resolve(to);
-							}
+					options.transitionDefs[to.id].resolve(to);
+				}
 			}
+			// return any empty promise/all if the options.transition="none"
+			return new all([]);
 		}else{
-			var defs=[];
-			var transit=[];
-			var duration = 250;
-			if(options.transition === "fade"){
-				duration = 600;
-			}else if (options.transition === "flip"){
-				duration = 200;
+			var defs = [];
+			var transit = [];
+			var duration = 2000;
+			if(!options.duration){
+				duration = 250;
+				if(options.transition === "fade"){
+					duration = 600;
+				}else if (options.transition === "flip"){
+					duration = 200;
+				}
+			}else{
+				duration = options.duration;
 			}
-			domStyle.set(from, "display", ""); 
-			domStyle.set(to, "display", "");
-			if (from){
+			if(from){
+				domStyle.set(from, "display", "");
 				//create transition to transit "from" out
 				var fromTransit = transition[options.transition](from, {
 					"in": false,
@@ -35,17 +64,18 @@ define(["dojo/_base/kernel", "dojo/_base/array","dojo/dom-style","dojo/DeferredL
 				defs.push(fromTransit.deferred);//every transition object should have a deferred.
 				transit.push(fromTransit);
 			}
-			
-			//create transition to transit "to" in					
-			var toTransit = transition[options.transition](to, {
-							direction: rev,
-							duration: duration,
-							deferred: (options.transitionDefs && options.transitionDefs[to.id]) ? options.transitionDefs[to.id] : null
-						});
-			defs.push(toTransit.deferred);//every transition object should have a deferred.
-			transit.push(toTransit);
-			
-			//TODO If it is flip use the chainedPlay
+			if(to){
+				domStyle.set(to, "display", "");
+				//create transition to transit "to" in
+				var toTransit = transition[options.transition](to, {
+								direction: rev,
+								duration: duration,
+								deferred: (options.transitionDefs && options.transitionDefs[to.id]) ? options.transitionDefs[to.id] : null
+							});
+				defs.push(toTransit.deferred);//every transition object should have a deferred.
+				transit.push(toTransit);
+			}
+			//If it is flip use the chainedPlay, otherwise
 			//play fromTransit and toTransit together
 			if(options.transition === "flip"){
 				transition.chainedPlay(transit);
@@ -53,8 +83,7 @@ define(["dojo/_base/kernel", "dojo/_base/array","dojo/dom-style","dojo/DeferredL
 				transition.groupedPlay(transit);
 			}
 
-			return new DeferredList(defs);
-			
+			return all(defs);
 		}
 	};
 	
diff --git a/dojox/css3/transition.js b/dojox/css3/transition.js
index 1fd9f72..5649156 100644
--- a/dojox/css3/transition.js
+++ b/dojox/css3/transition.js
@@ -1,13 +1,17 @@
-define(["dojo/_base/kernel", 
-		"dojo/_base/lang",
-		"dojo/_base/declare",
+define(["dojo/_base/lang",
 		"dojo/_base/array",
-		"dojo/_base/Deferred",
-		"dojo/DeferredList",
+		"dojo/Deferred",
+		"dojo/when",
+		"dojo/promise/all",
 		"dojo/on",
-		"dojo/_base/sniff"], 
-		function(dojo, lang, declare, array, deferred, deferredList, on, has){
-	//TODO create cross platform animation/transition effects
+		"dojo/sniff"],
+		function(lang, array, Deferred, when, all, on, has){
+	// module: 
+	//		dojox/css3/transition
+	
+	//create cross platform animation/transition effects
+	//TODO enable opera mobile when it is hardware accelerated
+	// IE10 is using standard names so this is working without any modifications
 	var transitionEndEventName = "transitionend";
 	var transitionPrefix = "t"; //by default use "t" prefix and "ransition" to make word "transition"
 	var translateMethodStart = "translate3d(";//Android 2.x does not support translateX in CSS Transition, we need to use translate3d in webkit browsers
@@ -22,13 +26,17 @@ define(["dojo/_base/kernel",
 	}
 	
 	//TODO find a way to lock the animation and prevent animation conflict
-	declare("dojox.css3.transition", null, {
-		
-
-		constructor: function(args){
-			//default config should be in animation object itself instead of its prototype
-			//otherwise, it might be easy for making mistake of modifying prototype
-			var defaultConfig = {
+	//Use the simple object inheritance
+	var transition = function(/*Object?*/args){
+		// summary:
+		//		This module defines the transition utilities which can be used
+		//		to perform transition effects based on the CSS Transition standard.
+		// args:
+		//		The arguments which will be mixed into this transition object.
+		
+		//default config should be in animation object itself instead of its prototype
+		//otherwise, it might be easy for making mistake of modifying prototype
+		var defaultConfig = {
 				startState: {},
 				endState: {},
 				node: null,
@@ -36,22 +44,25 @@ define(["dojo/_base/kernel",
 				"in": true,
 				direction: 1,
 				autoClear: true
-			};
-			
-			lang.mixin(this, defaultConfig);
-			lang.mixin(this, args);
-			
-			//create the deferred object which will resolve after the animation is finished.
-			//We can rely on "onAfterEnd" function to notify the end of a single animation,
-			//but using a deferred object is easier to wait for multiple animations end.
-			if(!this.deferred){
-				this.deferred = new deferred();
-			}
-		},
+		};
+
+		lang.mixin(this, defaultConfig);
+		lang.mixin(this, args);
+
+		//create the deferred object which will resolve after the animation is finished.
+		//We can rely on "onAfterEnd" function to notify the end of a single animation,
+		//but using a deferred object is easier to wait for multiple animations end.
+		if(!this.deferred){
+			this.deferred = new Deferred();
+		}
+	};
+	
+	lang.extend(transition, {
 		
 		play: function(){
-			//play the animation using CSS3 Transition
-			dojox.css3.transition.groupedPlay([this]);
+			// summary:
+			//		Plays the transition effect defined by this transition object.
+			transition.groupedPlay([this]);
 		},
 		
 		//method to apply the state of the transition
@@ -64,8 +75,10 @@ define(["dojo/_base/kernel",
 			}
 		},
 		
-		//method to initialize state for transition
+		
 		initState: function(){
+			// summary:
+			//		Method to initialize the state for a transition.
 			
 			//apply the immediate style change for initial state.
 			this.node.style[transitionPrefix + "ransitionProperty"] = "none";
@@ -92,28 +105,39 @@ define(["dojo/_base/kernel",
 		
 		_onAfterEnd: function(){
 			this.deferred.resolve(this.node);
-			if(this.node.id && dojox.css3.transition.playing[this.node.id]===this.deferred){
-				delete dojox.css3.transition.playing[this.node.id];
+			if(this.node.id && transition.playing[this.node.id]===this.deferred){
+				delete transition.playing[this.node.id];
 			}
 			this.onAfterEnd();
 		},
 		
 		beforeStart: function(){
-			
+			// summary:
+			//		The callback which will be called right before the start
+			//		of the transition effect.
 		},
 		
 		beforeClear: function(){
-			
+			// summary:
+			//		The callback which will be called right after the end
+			//		of the transition effect and before the final state is
+			//		cleared.
 		},
 		
 		onAfterEnd: function(){
-			
+			// summary:
+			//		The callback which will be called right after the end
+			//		of the transition effect and after the final state is
+			//		cleared.
 		},
 		
-		//method to start the transition
 		start: function(){
+			// summary:
+			//		Method to start the transition.
 			this._beforeStart();
-			
+			this._startTime = new Date().getTime(); // set transition start timestamp
+			this._cleared = false; // set clear flag to false
+
 			var self = this;
 			//change the transition duration
 			self.node.style[transitionPrefix + "ransitionProperty"] = "all";
@@ -129,11 +153,17 @@ define(["dojo/_base/kernel",
 			this._applyState(this.endState);
 		},
 		
-		//method to clear state after transition
 		clear: function(){
+			// summary:
+			//		Method to clear the state after a transition.
+			if(this._cleared) {
+				return;
+			}
+			this._cleared = true; // set clear flag to true
+
 			this._beforeClear();
 			this._removeState(this.endState);
-			console.log(this.node.id + " clear.");
+			// console.log(this.node.id + " clear.");
 			this._onAfterEnd();
 		},
 		
@@ -151,11 +181,17 @@ define(["dojo/_base/kernel",
 	
 	//TODO add the lock mechanism for all of the transition effects
 	//	   consider using only one object for one type of transition.
-	//TODO create the first animation, slide.
-	dojox.css3.transition.slide = function(node, config){
+	
+	transition.slide = function(node, config){
+		// summary:
+		//		Method which is used to create the transition object of a slide effect.
+		// node:
+		//		The node that the slide transition effect will be applied on.
+		// config:
+		//		The cofig arguments which will be mixed into this transition object.
 
-		//TODO create the return and set the startState, endState of the return
-		var ret = new dojox.css3.transition(config);
+		//create the return object and set the startState, endState of the return
+		var ret = new transition(config);
 		ret.node = node;
 		
 		var startX = "0";
@@ -175,7 +211,6 @@ define(["dojo/_base/kernel",
 			}
 		}
 		
-		
 		ret.startState[transitionPrefix + "ransform"]=translateMethodStart+startX+translateMethodEnd;
 		
 		ret.endState[transitionPrefix + "ransform"]=translateMethodStart+endX+translateMethodEnd;
@@ -183,11 +218,14 @@ define(["dojo/_base/kernel",
 		return ret;
 	};
 		
-	
-	//fade in/out animation effects
-	dojox.css3.transition.fade = function(node, config){
-		
-		var ret = new dojox.css3.transition(config);
+	transition.fade = function(node, config){
+		// summary:
+		//		Method which is used to create the transition object of fade effect.
+		// node:
+		//		The node that the fade transition effect will be applied on.
+		// config:
+		//		The cofig arguments which will be mixed into this transition object.
+		var ret = new transition(config);
 		ret.node = node;
 		
 		var startOpacity = "0";
@@ -211,10 +249,15 @@ define(["dojo/_base/kernel",
 		return ret;
 	};
 	
-  //fade in/out animation effects
-	dojox.css3.transition.flip = function(node, config){
-		
-		var ret = new dojox.css3.transition(config);
+	transition.flip = function(node, config){
+		// summary:
+		//		Method which is used to create the transition object of flip effect.
+		// node:
+		//		The node that the flip transition effect will be applied on.
+		// config:
+		//		The cofig arguments which will be mixed into this transition object.
+		
+		var ret = new transition(config);
 		ret.node = node;
 	   
 		if(ret["in"]){
@@ -250,22 +293,23 @@ define(["dojo/_base/kernel",
 		var defs = [];
 		array.forEach(nodes, function(node){
 			//check whether the node is under other animation
-			if(node.id && dojox.css3.transition.playing[node.id]){
-				//TODO hook on deferred object in dojox.css3.transition.playing
-				defs.push(dojox.css3.transition.playing[node.id]);
+			if(node.id && transition.playing[node.id]){
+				//hook on deferred object in transition.playing
+				defs.push(transition.playing[node.id]);
 			}
 			
 		});
-		return new deferredList(defs);
+		return all(defs);
 	};
 	
-	dojox.css3.transition.getWaitingList = getWaitingList;
+	transition.getWaitingList = getWaitingList;
 	
-	//TODO groupedPlay should ensure the UI update happens when
-	//all animations end.
-	//the group player to start multiple animations together
-	dojox.css3.transition.groupedPlay = function(/*Array*/args){
-		//args should be array of dojox.css3.transition
+	transition.groupedPlay = function(/*Array*/args){
+		// summary:
+		//		The method which groups multiple transitions and plays 
+		//		them together.
+		// args: 
+		//		The array of transition objects which will be played together.
 		
 		var animNodes = array.filter(args, function(item){
 			return item.node;
@@ -276,12 +320,12 @@ define(["dojo/_base/kernel",
 		//update registry with deferred objects in animations of args.
 		array.forEach(args, function(item){
 			if(item.node.id){
-				dojox.css3.transition.playing[item.node.id] = item.deferred;
+				transition.playing[item.node.id] = item.deferred;
 			}
 		});
 		
-		//TODO wait for all deferred object in deferred list to resolve
-		dojo.when(waitingList, function(){
+		//wait for all deferred object in deferred list to resolve
+		when(waitingList, function(){
 			array.forEach(args, function(item){
 				//set the start state
 				item.initState();
@@ -293,14 +337,33 @@ define(["dojo/_base/kernel",
 			setTimeout(function(){
 				array.forEach(args, function(item){
 					item.start();
-				});			   
+				});
+
+				// check and clear node if the node not cleared.
+				// 1. on Android2.2/2.3, the "fade out" transitionEnd event will be lost if the soft keyboard popup, so we need to check nodes' clear status.
+				// 2. The "fade in" transitionEnd event will before or after "fade out" transitionEnd event and it always occurs.
+				//	  We can check fade out node status in the last "fade in" node transitionEnd event callback, if node transition timeout, we clear it.
+				// NOTE: the last "fade in" transitionEnd event will always fired, so we bind on this event and check other nodes.
+				on.once(args[args.length-1].node, transitionEndEventName, function(){
+					var timeout;
+					for(var i=0; i<args.length-1; i++){
+						if(args[i].deferred.fired !== 0){
+							timeout = new Date().getTime() - args[i]._startTime;
+							if(timeout >= args[i].duration){
+								args[i].clear();
+							}
+						}
+					}
+				});
 			}, 33);
 		});		   
 	};
 	
-	//the chain player to start multiple animations one by one
-	dojox.css3.transition.chainedPlay = function(/*Array*/args){
-		//args should be array of dojox.css3.transition
+	transition.chainedPlay = function(/*Array*/args){
+		// summary:
+		//		The method which plays multiple transitions one by one.
+		// args: 
+		//		The array of transition objects which will be played in a chain.
 		
 		var animNodes = array.filter(args, function(item){
 			return item.node;
@@ -311,11 +374,11 @@ define(["dojo/_base/kernel",
 		//update registry with deferred objects in animations of args.
 		array.forEach(args, function(item){
 			if(item.node.id){
-				dojox.css3.transition.playing[item.node.id] = item.deferred;
+				transition.playing[item.node.id] = item.deferred;
 			}
 		});
 		
-		dojo.when(waitingList, function(){
+		when(waitingList, function(){
 			array.forEach(args, function(item){
 				//set the start state
 				item.initState();
@@ -338,7 +401,7 @@ define(["dojo/_base/kernel",
 	};
 	
 	//TODO complete the registry mechanism for animation handling and prevent animation conflicts
-	dojox.css3.transition.playing = {};
+	transition.playing = {};
 	
-	return dojox.css3.transition;
+	return transition;
 });
diff --git a/dojox/data/AndOrReadStore.js b/dojox/data/AndOrReadStore.js
index e8564e4..07b0ba5 100755
--- a/dojox/data/AndOrReadStore.js
+++ b/dojox/data/AndOrReadStore.js
@@ -1,209 +1,50 @@
-define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/_base/lang", "dojo/data/util/filter", "dojo/data/util/simpleFetch",
-		"dojo/_base/array", "dojo/date/stamp", "dojo/_base/json", "dojo/_base/window", "dojo/_base/xhr"], 
-  function(kernel, declare, lang, filterUtil, simpleFetch, array, dateStamp, json, winUtil, xhr) {
-
-var AndOrReadStore = declare("dojox.data.AndOrReadStore", null, {
-	//	summary:
+define(["dojo/_base/declare", "dojo/_base/lang", "dojo/data/ItemFileReadStore", "dojo/data/util/filter", "dojo/_base/array", "dojo/_base/json"],
+  function(declare, lang, ItemFileReadStore, filterUtil, array, json) {
+  
+// module:
+//		dojox/data/AndOrReadStore
+// summary:
+//		TODOC
+
+return declare("dojox.data.AndOrReadStore", [ItemFileReadStore], {
+	// summary:
 	//		AndOrReadStore uses ItemFileReadStore as a base, modifying only the query (_fetchItems) section.
 	//		Supports queries of the form: query:"id:1* OR dept:'Sales Department' || (id:2* && NOT dept:S*)"
 	//		Includes legacy/widget support via:
-	//			query:{complexQuery:"id:1* OR dept:'Sales Department' || (id:2* && NOT dept:S*)"}
-	//		The ItemFileReadStore implements the dojo.data.api.Read API and reads
+	// |		query:{complexQuery:"id:1* OR dept:'Sales Department' || (id:2* && NOT dept:S*)"}
+	//		The ItemFileReadStore implements the dojo/data/api/Read API and reads
 	//		data from JSON files that have contents in this format --
-	//		{ items: [
-	//			{ name:'Kermit', color:'green', age:12, friends:['Gonzo', {_reference:{name:'Fozzie Bear'}}]},
-	//			{ name:'Fozzie Bear', wears:['hat', 'tie']},
-	//			{ name:'Miss Piggy', pets:'Foo-Foo'}
-	//		]}
-	//		Note that it can also contain an 'identifer' property that specified which attribute on the items
+	// |	{ items: [
+	// |		{ name:'Kermit', color:'green', age:12, friends:['Gonzo', {_reference:{name:'Fozzie Bear'}}]},
+	// |		{ name:'Fozzie Bear', wears:['hat', 'tie']},
+	// |		{ name:'Miss Piggy', pets:'Foo-Foo'}
+	// |	]}
+	//		Note that it can also contain an 'identifier' property that specified which attribute on the items
 	//		in the array of items that acts as the unique identifier for that item.
-	//
-	constructor: function(/* Object */ keywordParameters){
-		//	summary: constructor
-		//	keywordParameters: {url: String}
-		//	keywordParameters: {data: jsonObject}
-		//	keywordParameters: {typeMap: object)
-		//		The structure of the typeMap object is as follows:
-		//		{
-		//			type0: function || object,
-		//			type1: function || object,
-		//			...
-		//			typeN: function || object
-		//		}
-		//		Where if it is a function, it is assumed to be an object constructor that takes the
-		//		value of _value as the initialization parameters.  If it is an object, then it is assumed
-		//		to be an object of general form:
-		//		{
-		//			type: function, //constructor.
-		//			deserialize:	function(value) //The function that parses the value and constructs the object defined by type appropriately.
-		//		}
-	
-		this._arrayOfAllItems = [];
-		this._arrayOfTopLevelItems = [];
-		this._loadFinished = false;
-		this._jsonFileUrl = keywordParameters.url;
-		this._ccUrl = keywordParameters.url;
-		this.url = keywordParameters.url;
-		this._jsonData = keywordParameters.data;
-		this.data = null;
-		this._datatypeMap = keywordParameters.typeMap || {};
-		if(!this._datatypeMap['Date']){
-			//If no default mapping for dates, then set this as default.
-			//We use the dojo.date.stamp here because the ISO format is the 'dojo way'
-			//of generically representing dates.
-			this._datatypeMap['Date'] = {
-											type: Date,
-											deserialize: function(value){
-												return dateStamp.fromISOString(value);
-											}
-										};
-		}
-		this._features = {'dojo.data.api.Read':true, 'dojo.data.api.Identity':true};
-		this._itemsByIdentity = null;
-		this._storeRefPropName = "_S"; // Default name for the store reference to attach to every item.
-		this._itemNumPropName = "_0"; // Default Item Id for isItem to attach to every item.
-		this._rootItemPropName = "_RI"; // Default Item Id for isItem to attach to every item.
-		this._reverseRefMap = "_RRM"; // Default attribute for constructing a reverse reference map for use with reference integrity
-		this._loadInProgress = false; //Got to track the initial load to prevent duelling loads of the dataset.
-		this._queuedFetches = [];
-
-		if(keywordParameters.urlPreventCache !== undefined){
-			this.urlPreventCache = keywordParameters.urlPreventCache?true:false;
-		}
-		if(keywordParameters.hierarchical !== undefined){
-			this.hierarchical = keywordParameters.hierarchical?true:false;
-		}
-		if(keywordParameters.clearOnClose){
-			this.clearOnClose = true;
-		}
-	},
-	
-	url: "", // use "" rather than undefined for the benefit of the parser (#3539)
-
-	//Internal var, crossCheckUrl.  Used so that setting either url or _jsonFileUrl, can still trigger a reload
-	//when clearOnClose and close is used.
-	_ccUrl: "",
-
-	data: null, //Make this parser settable.
-
-	typeMap: null, //Make this parser settable.
-
-	//Parameter to allow users to specify if a close call should force a reload or not.
-	//By default, it retains the old behavior of not clearing if close is called.  But
-	//if set true, the store will be reset to default state.  Note that by doing this,
-	//all item handles will become invalid and a new fetch must be issued.
-	clearOnClose: false,
-
-	//Parameter to allow specifying if preventCache should be passed to the xhrGet call or not when loading data from a url.
-	//Note this does not mean the store calls the server on each fetch, only that the data load has preventCache set as an option.
-	//Added for tracker: #6072
-	urlPreventCache: false,
-
-	//Parameter to indicate to process data from the url as hierarchical
-	//(data items can contain other data items in js form).  Default is true
-	//for backwards compatibility.  False means only root items are processed
-	//as items, all child objects outside of type-mapped objects and those in
-	//specific reference format, are left straight JS data objects.
-	hierarchical: true,
-
-	_assertIsItem: function(/* item */ item){
-		//	summary:
-		//		This function tests whether the item passed in is indeed an item in the store.
-		//	item:
-		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){
-			throw new Error("dojox.data.AndOrReadStore: Invalid item argument.");
-		}
-	},
-
-	_assertIsAttribute: function(/* attribute-name-string */ attribute){
-		//	summary:
-		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
-		//		The attribute to test for being contained by the store.
-		if(typeof attribute !== "string"){
-			throw new Error("dojox.data.AndOrReadStore: Invalid attribute argument.");
-		}
-	},
-
-	getValue: function(	/* item */ item,
-						/* attribute-name-string */ attribute,
-						/* value? */ defaultValue){
-		//	summary:
-		//		See dojo.data.api.Read.getValue()
-		var values = this.getValues(item, attribute);
-		return (values.length > 0)?values[0]:defaultValue; // mixed
-	},
-
-	getValues: function(/* item */ item,
-						/* attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.getValues()
-
-		this._assertIsItem(item);
-		this._assertIsAttribute(attribute);
-		var arr = item[attribute] || [];
-		// Clone it before returning.  refs: #10474
-		return arr.slice(0, arr.length); // Array
-	},
 
-	getAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getAttributes()
-		this._assertIsItem(item);
-		var attributes = [];
-		for(var key in item){
-			// Save off only the real item attributes, not the special id marks for O(1) isItem.
-			if((key !== this._storeRefPropName) && (key !== this._itemNumPropName) && (key !== this._rootItemPropName) && (key !== this._reverseRefMap)){
-				attributes.push(key);
-			}
-		}
-		return attributes; // Array
-	},
-
-	hasAttribute: function(	/* item */ item,
-							/* attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.hasAttribute()
-		this._assertIsItem(item);
-		this._assertIsAttribute(attribute);
-		return (attribute in item);
-	},
-
-	containsValue: function(/* item */ item,
-							/* attribute-name-string */ attribute,
-							/* anything */ value){
-		//	summary:
-		//		See dojo.data.api.Read.containsValue()
-		var regexp = undefined;
-		if(typeof value === "string"){
-			regexp = filterUtil.patternToRegExp(value, false);
-		}
-		return this._containsValue(item, attribute, value, regexp); //boolean.
-	},
-
-	_containsValue: function(	/* item */ item,
-								/* attribute-name-string */ attribute,
-								/* anything */ value,
-								/* RegExp?*/ regexp){
-		//	summary:
+	_containsValue: function(/*dojo/data/api/Item*/ item, /*attribute-name-string */ attribute, /*anything*/ value,
+			/*String|RegExp?*/ regexp){
+		// summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description:
+		// description:
 		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//
-		//	item:
+		// item:
 		//		The data item to examine for attribute values.
-		//	attribute:
+		// attribute:
 		//		The attribute to inspect.
-		//	value:
+		// value:
 		//		The value to match.
-		//	regexp:
-		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
+		// regexp:
+		//		Optional string or regular expression generated off value if value was of string type to handle wildcarding.
 		//		If present and attribute values are string, then it can be used for comparison instead of 'value'
+		//		If RegExp is a string, it is treated as an comparison statement and eval for number comparisons
 		return array.some(this.getValues(item, attribute), function(possibleValue){
-			if(possibleValue !== null && !lang.isObject(possibleValue) && regexp){
+			// if string... eval for math operator comparisons
+			if(lang.isString(regexp)){
+				return eval(regexp);
+			}else if(possibleValue !== null && !lang.isObject(possibleValue) && regexp){
 				if(possibleValue.toString().match(regexp)){
 					return true; // Boolean
 				}
@@ -215,832 +56,205 @@ var AndOrReadStore = declare("dojox.data.AndOrReadStore", null, {
 		});
 	},
 
-	isItem: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItem()
-		if(something && something[this._storeRefPropName] === this){
-			if(this._arrayOfAllItems[something[this._itemNumPropName]] === something){
-				return true;
-			}
-		}
-		return false; // Boolean
-	},
-
-	isItemLoaded: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItemLoaded()
-		return this.isItem(something); //boolean
-	},
-
-	loadItem: function(/* object */ keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Read.loadItem()
-		this._assertIsItem(keywordArgs.item);
-	},
-
-	getFeatures: function(){
-		//	summary:
-		//		See dojo.data.api.Read.getFeatures()
-		return this._features; //Object
-	},
-
-	getLabel: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
-		if(this._labelAttr && this.isItem(item)){
-			return this.getValue(item,this._labelAttr); //String
-		}
-		return undefined; //undefined
-	},
-
-	getLabelAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
-		if(this._labelAttr){
-			return [this._labelAttr]; //array
-		}
-		return null; //null
-	},
-
-	_fetchItems: function(	/* Object */ keywordArgs,
-							/* Function */ findCallback,
-							/* Function */ errorCallback){
-		//	summary:
-		//		See dojo.data.util.simpleFetch.fetch()
-		//		filter modified to permit complex queries where
-		//			logical operators are case insensitive:
-		//			, NOT AND OR ( ) ! && ||
-		//			Note:  "," included for quoted/string legacy queries.
-		var self = this;
-		var filter = function(requestArgs, arrayOfItems){
-			var items = [];
-			if(requestArgs.query){
-				//Complete copy, we may have to mess with it.
-				//Safer than clone, which does a shallow copy, I believe.
-				var query = json.fromJson(json.toJson(requestArgs.query));
-				//Okay, object form query, we have to check to see if someone mixed query methods (such as using FilteringSelect
-				//with a complexQuery).  In that case, the params need to be anded to the complex query statement.
-				//See defect #7980
-				if(typeof query == "object" ){
-					var count = 0;
-					var p;
+	filter: function(requestArgs, arrayOfItems, findCallback){
+		var items = [];
+		if(requestArgs.query){
+			//Complete copy, we may have to mess with it.
+			//Safer than clone, which does a shallow copy, I believe.
+			var query = json.fromJson(json.toJson(requestArgs.query));
+			//Okay, object form query, we have to check to see if someone mixed query methods (such as using FilteringSelect
+			//with a complexQuery).  In that case, the params need to be anded to the complex query statement.
+			//See defect #7980
+			if(typeof query == "object" ){
+				var count = 0;
+				var p;
+				for(p in query){
+					count++;
+				}
+				if(count > 1 && query.complexQuery){
+					var cq = query.complexQuery;
+					var wrapped = false;
 					for(p in query){
-						count++;
-					}
-					if(count > 1 && query.complexQuery){
-						var cq = query.complexQuery;
-						var wrapped = false;
-						for(p in query){
-							if(p !== "complexQuery"){
-								//We should wrap this in () as it should and with the entire complex query
-								//Not just part of it.
-								if(!wrapped){
-									cq = "( " + cq + " )";
-									wrapped = true;
-								}
-								//Make sure strings are quoted when going into complexQuery merge.
-								var v = requestArgs.query[p];
-								if(lang.isString(v)){
-									v = "'" + v + "'";
-								}
-								cq += " AND " + p + ":" + v;
-								delete query[p];
-								
+						if(p !== "complexQuery"){
+							//We should wrap this in () as it should and with the entire complex query
+							//Not just part of it.
+							if(!wrapped){
+								cq = "( " + cq + " )";
+								wrapped = true;
 							}
-						}
-						query.complexQuery = cq;
-					}
-				}
-
-				var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false;
-				//for complex queries only:  pattern = query[:|=]"NOT id:23* AND (type:'test*' OR dept:'bob') && !filed:true"
-				//logical operators are case insensitive:  , NOT AND OR ( ) ! && ||  // "," included for quoted/string legacy queries.
-				if(typeof query != "string"){
-					query = json.toJson(query);
-					query = query.replace(/\\\\/g,"\\"); //counter toJson expansion of backslashes, e.g., foo\\*bar test.
-				}
-				query = query.replace(/\\"/g,"\"");   //ditto, for embedded \" in lieu of " availability.
-				var complexQuery = lang.trim(query.replace(/{|}/g,"")); //we can handle these, too.
-				var pos2, i;
-				if(complexQuery.match(/"? *complexQuery *"?:/)){ //case where widget required a json object, so use complexQuery:'the real query'
-					complexQuery = lang.trim(complexQuery.replace(/"?\s*complexQuery\s*"?:/,""));
-					var quotes = ["'",'"'];
-					var pos1,colon;
-					var flag = false;
-					for(i = 0; i<quotes.length; i++){
-						pos1 = complexQuery.indexOf(quotes[i]);
-						pos2 = complexQuery.indexOf(quotes[i],1);
-						colon = complexQuery.indexOf(":",1);
-						if(pos1 === 0 && pos2 != -1 && colon < pos2){
-							flag = true;
-							break;
-						} //first two sets of quotes don't occur before the first colon.
-					}
-					if(flag){	//dojo.toJson, and maybe user, adds surrounding quotes, which we need to remove.
-						complexQuery = complexQuery.replace(/^\"|^\'|\"$|\'$/g,"");
-					}
-				} //end query="{complexQuery:'id:1* || dept:Sales'}" parsing (for when widget required json object query).
-				var complexQuerySave = complexQuery;
-				//valid logical operators.
-				var begRegExp = /^,|^NOT |^AND |^OR |^\(|^\)|^!|^&&|^\|\|/i; //trailing space on some tokens on purpose.
-				var sQuery = ""; //will be eval'ed for each i-th candidateItem, based on query components.
-				var op = "";
-				var val = "";
-				var pos = -1;
-				var err = false;
-				var key = "";
-				var value = "";
-				var tok = "";
-				pos2 = -1;
-				for(i = 0; i < arrayOfItems.length; ++i){
-					var match = true;
-					var candidateItem = arrayOfItems[i];
-					if(candidateItem === null){
-						match = false;
-					}else{
-						//process entire string for this i-th candidateItem.
-						complexQuery = complexQuerySave; //restore query for next candidateItem.
-						sQuery = "";
-						//work left to right, finding either key:value pair or logical operator at the beginning of the complexQuery string.
-						//when found, concatenate to sQuery and remove from complexQuery and loop back.
-						while(complexQuery.length > 0 && !err){
-							op = complexQuery.match(begRegExp);
-							
-							//get/process/append one or two leading logical operators.
-							while(op && !err){ //look for leading logical operators.
-								complexQuery = lang.trim(complexQuery.replace(op[0],""));
-								op = lang.trim(op[0]).toUpperCase();
-								//convert some logical operators to their javascript equivalents for later eval.
-								op = op == "NOT" ? "!" : op == "AND" || op == "," ? "&&" : op == "OR" ? "||" : op;
-								op = " " + op + " ";
-								sQuery += op;
-								op = complexQuery.match(begRegExp);
-							}//end op && !err
-							
-							//now get/process/append one key:value pair.
-							if(complexQuery.length > 0){
-								pos = complexQuery.indexOf(":");
-								if(pos == -1){
-									err = true;
-									break;
-								}else{
-									key = lang.trim(complexQuery.substring(0,pos).replace(/\"|\'/g,""));
-									complexQuery = lang.trim(complexQuery.substring(pos + 1));
-									tok = complexQuery.match(/^\'|^\"/);	//quoted?
-									if(tok){
-										tok = tok[0];
-										pos = complexQuery.indexOf(tok);
-										pos2 = complexQuery.indexOf(tok,pos + 1);
-										if(pos2 == -1){
-											err = true;
-											break;
-										}
-										value = complexQuery.substring(pos + 1,pos2);
-										if(pos2 == complexQuery.length - 1){ //quote is last character
-											complexQuery = "";
-										}else{
-											complexQuery = lang.trim(complexQuery.substring(pos2 + 1));
-										}
-										sQuery += self._containsValue(candidateItem, key, value, filterUtil.patternToRegExp(value, ignoreCase));
-									}
-									else{ //not quoted, so a space, comma, or closing parens (or the end) will be the break.
-										tok = complexQuery.match(/\s|\)|,/);
-										if(tok){
-											var pos3 = new Array(tok.length);
-											for(var j = 0;j<tok.length;j++){
-												pos3[j] = complexQuery.indexOf(tok[j]);
-											}
-											pos = pos3[0];
-											if(pos3.length > 1){
-												for(var j=1;j<pos3.length;j++){
-													pos = Math.min(pos,pos3[j]);
-												}
-											}
-											value = lang.trim(complexQuery.substring(0,pos));
-											complexQuery = lang.trim(complexQuery.substring(pos));
-										}else{ //not a space, so must be at the end of the complexQuery.
-											value = lang.trim(complexQuery);
-											complexQuery = "";
-										} //end  inner if(tok) else
-										sQuery += self._containsValue(candidateItem, key, value, filterUtil.patternToRegExp(value, ignoreCase));
-									} //end outer if(tok) else
-								} //end found ":"
-							} //end if(complexQuery.length > 0)
-						} //end while complexQuery.length > 0 && !err, so finished the i-th item.
-						match = eval(sQuery);
-					} //end else is non-null candidateItem.
-					if(match){
-						items.push(candidateItem);
-					}
-				} //end for/next of all items.
-				if(err){
-					//soft fail.
-					items = [];
-					console.log("The store's _fetchItems failed, probably due to a syntax error in query.");
-				}
-				findCallback(items, requestArgs);
-			}else{
-				// No query...
-				// We want a copy to pass back in case the parent wishes to sort the array.
-				// We shouldn't allow resort of the internal list, so that multiple callers
-				// can get lists and sort without affecting each other.  We also need to
-				// filter out any null values that have been left as a result of deleteItem()
-				// calls in ItemFileWriteStore.
-				for(var i = 0; i < arrayOfItems.length; ++i){
-					var item = arrayOfItems[i];
-					if(item !== null){
-						items.push(item);
-					}
-				}
-				findCallback(items, requestArgs);
-			} //end if there is a query.
-		}; //end filter function
+							//Make sure strings are quoted when going into complexQuery merge.
+							var v = requestArgs.query[p];
+							if(lang.isString(v)){
+								v = "'" + v + "'";
+							}
+							cq += " AND " + p + ":" + v;
+							delete query[p];
 
-		if(this._loadFinished){
-			filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions));
-		}else{
-			if(this._jsonFileUrl !== this._ccUrl){
-				kernel.deprecated("dojox.data.AndOrReadStore: ",
-								"To change the url, set the url property of the store," +
-								" not _jsonFileUrl.  _jsonFileUrl support will be removed in 2.0");
-				this._ccUrl = this._jsonFileUrl;
-				this.url = this._jsonFileUrl;
-			}else if(this.url !== this._ccUrl){
-				this._jsonFileUrl = this.url;
-				this._ccUrl = this.url;
-			}
-			//See if there was any forced reset of data.
-			if(this.data != null && this._jsonData == null){
-				this._jsonData = this.data;
-				this.data = null;
-			}
-			if(this._jsonFileUrl){
-				//If fetches come in before the loading has finished, but while
-				//a load is in progress, we have to defer the fetching to be
-				//invoked in the callback.
-				if(this._loadInProgress){
-					this._queuedFetches.push({args: keywordArgs, filter: filter});
-				}else{
-					this._loadInProgress = true;
-					var getArgs = {
-							url: self._jsonFileUrl,
-							handleAs: "json-comment-optional",
-							preventCache: this.urlPreventCache
-						};
-					var getHandler = xhr.get(getArgs);
-					getHandler.addCallback(function(data){
-						try{
-							self._getItemsFromLoadedData(data);
-							self._loadFinished = true;
-							self._loadInProgress = false;
-							
-							filter(keywordArgs, self._getItemsArray(keywordArgs.queryOptions));
-							self._handleQueuedFetches();
-						}catch(e){
-							self._loadFinished = true;
-							self._loadInProgress = false;
-							errorCallback(e, keywordArgs);
 						}
-					});
-					getHandler.addErrback(function(error){
-						self._loadInProgress = false;
-						errorCallback(error, keywordArgs);
-					});
-					
-					//Wire up the cancel to abort of the request
-					//This call cancel on the deferred if it hasn't been called
-					//yet and then will chain to the simple abort of the
-					//simpleFetch keywordArgs
-					var oldAbort = null;
-					if(keywordArgs.abort){
-						oldAbort = keywordArgs.abort;
 					}
-					keywordArgs.abort = function(){
-						var df = getHandler;
-						if(df && df.fired === -1){
-							df.cancel();
-							df = null;
-						}
-						if(oldAbort){
-							oldAbort.call(keywordArgs);
-						}
-					};
+					query.complexQuery = cq;
 				}
-			}else if(this._jsonData){
-				try{
-					this._loadFinished = true;
-					this._getItemsFromLoadedData(this._jsonData);
-					this._jsonData = null;
-					filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions));
-				}catch(e){
-					errorCallback(e, keywordArgs);
-				}
-			}else{
-				errorCallback(new Error("dojox.data.AndOrReadStore: No JSON source data was provided as either URL or a nested Javascript object."), keywordArgs);
 			}
-		} //end deferred fetching.
-	}, //end _fetchItems
 
-	_handleQueuedFetches: function(){
-		//	summary:
-		//		Internal function to execute delayed request in the store.
-		//Execute any deferred fetches now.
-		if(this._queuedFetches.length > 0){
-			for(var i = 0; i < this._queuedFetches.length; i++){
-				var fData = this._queuedFetches[i];
-				var delayedQuery = fData.args;
-				var delayedFilter = fData.filter;
-				if(delayedFilter){
-					delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions));
-				}else{
-					this.fetchItemByIdentity(delayedQuery);
-				}
+			var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false;
+			//for complex queries only:  pattern = query[:|=]"NOT id:23* AND (type:'test*' OR dept:'bob') && !filed:true"
+			//logical operators are case insensitive:  , NOT AND OR ( ) ! && ||  // "," included for quoted/string legacy queries.
+			if(typeof query != "string"){
+				query = json.toJson(query);
+				query = query.replace(/\\\\/g,"\\"); //counter toJson expansion of backslashes, e.g., foo\\*bar test.
 			}
-			this._queuedFetches = [];
-		}
-	},
-
-	_getItemsArray: function(/*object?*/queryOptions){
-		//	summary:
-		//		Internal function to determine which list of items to search over.
-		//	queryOptions: The query options parameter, if any.
-		if(queryOptions && queryOptions.deep){
-			return this._arrayOfAllItems;
-		}
-		return this._arrayOfTopLevelItems;
-	},
-
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		//	summary:
-		//		See dojo.data.api.Read.close()
-		if(this.clearOnClose &&
-			this._loadFinished &&
-			!this._loadInProgress){
-			 //Reset all internalsback to default state.  This will force a reload
-			 //on next fetch.  This also checks that the data or url param was set
-			 //so that the store knows it can get data.  Without one of those being set,
-			 //the next fetch will trigger an error.
-
-			 if(((this._jsonFileUrl == "" || this._jsonFileUrl == null) &&
-				 (this.url == "" || this.url == null)
-				) && this.data == null){
-				 console.debug("dojox.data.AndOrReadStore: WARNING!  Data reload " +
-					" information has not been provided." +
-					"  Please set 'url' or 'data' to the appropriate value before" +
-					" the next fetch");
-			 }
-			 this._arrayOfAllItems = [];
-			 this._arrayOfTopLevelItems = [];
-			 this._loadFinished = false;
-			 this._itemsByIdentity = null;
-			 this._loadInProgress = false;
-			 this._queuedFetches = [];
-		 }
-	},
-
-	_getItemsFromLoadedData: function(/* Object */ dataObject){
-		//	summary:
-		//		Function to parse the loaded data into item format and build the internal items array.
-		//	description:
-		//		Function to parse the loaded data into item format and build the internal items array.
-		//
-		//	dataObject:
-		//		The JS data object containing the raw data to convery into item format.
-		//
-		// 	returns: array
-		//		Array of items in store item format.
-		
-		// First, we define a couple little utility functions...
-		
-		var self = this;
-		function valueIsAnItem(/* anything */ aValue){
-			// summary:
-			//		Given any sort of value that could be in the raw json data,
-			//		return true if we should interpret the value as being an
-			//		item itself, rather than a literal value or a reference.
-			// example:
-			// 	|	false == valueIsAnItem("Kermit");
-			// 	|	false == valueIsAnItem(42);
-			// 	|	false == valueIsAnItem(new Date());
-			// 	|	false == valueIsAnItem({_type:'Date', _value:'May 14, 1802'});
-			// 	|	false == valueIsAnItem({_reference:'Kermit'});
-			// 	|	true == valueIsAnItem({name:'Kermit', color:'green'});
-			// 	|	true == valueIsAnItem({iggy:'pop'});
-			// 	|	true == valueIsAnItem({foo:42});
-			var isItem = (
-				(aValue !== null) &&
-				(typeof aValue === "object") &&
-				(!lang.isArray(aValue)) &&
-				(!lang.isFunction(aValue)) &&
-				(aValue.constructor == Object) &&
-				(typeof aValue._reference === "undefined") &&
-				(typeof aValue._type === "undefined") &&
-				(typeof aValue._value === "undefined") &&
-				self.hierarchical
-			);
-			return isItem;
-		}
-		
-		function addItemAndSubItemsToArrayOfAllItems(/* Item */ anItem){
-			self._arrayOfAllItems.push(anItem);
-			for(var attribute in anItem){
-				var valueForAttribute = anItem[attribute];
-				if(valueForAttribute){
-					if(lang.isArray(valueForAttribute)){
-						var valueArray = valueForAttribute;
-						for(var k = 0; k < valueArray.length; ++k){
-							var singleValue = valueArray[k];
-							if(valueIsAnItem(singleValue)){
-								addItemAndSubItemsToArrayOfAllItems(singleValue);
-							}
-						}
-					}else{
-						if(valueIsAnItem(valueForAttribute)){
-							addItemAndSubItemsToArrayOfAllItems(valueForAttribute);
-						}
-					}
+			query = query.replace(/\\"/g,"\"");   //ditto, for embedded \" in lieu of " availability.
+			var complexQuery = lang.trim(query.replace(/{|}/g,"")); //we can handle these, too.
+			var pos2, i;
+			if(complexQuery.match(/"? *complexQuery *"?:/)){ //case where widget required a json object, so use complexQuery:'the real query'
+				complexQuery = lang.trim(complexQuery.replace(/"?\s*complexQuery\s*"?:/,""));
+				var quotes = ["'",'"'];
+				var pos1,colon;
+				var flag = false;
+				for(i = 0; i<quotes.length; i++){
+					pos1 = complexQuery.indexOf(quotes[i]);
+					pos2 = complexQuery.indexOf(quotes[i],1);
+					colon = complexQuery.indexOf(":",1);
+					if(pos1 === 0 && pos2 != -1 && colon < pos2){
+						flag = true;
+						break;
+					} //first two sets of quotes don't occur before the first colon.
 				}
-			}
-		}
-
-		this._labelAttr = dataObject.label;
-
-		// We need to do some transformations to convert the data structure
-		// that we read from the file into a format that will be convenient
-		// to work with in memory.
-
-		// Step 1: Walk through the object hierarchy and build a list of all items
-		var i;
-		var item;
-		this._arrayOfAllItems = [];
-		this._arrayOfTopLevelItems = dataObject.items;
-
-		for(i = 0; i < this._arrayOfTopLevelItems.length; ++i){
-			item = this._arrayOfTopLevelItems[i];
-			addItemAndSubItemsToArrayOfAllItems(item);
-			item[this._rootItemPropName]=true;
-		}
-
-		// Step 2: Walk through all the attribute values of all the items,
-		// and replace single values with arrays.  For example, we change this:
-		//		{ name:'Miss Piggy', pets:'Foo-Foo'}
-		// into this:
-		//		{ name:['Miss Piggy'], pets:['Foo-Foo']}
-		//
-		// We also store the attribute names so we can validate our store
-		// reference and item id special properties for the O(1) isItem
-		var allAttributeNames = {};
-		var key;
-
-		for(i = 0; i < this._arrayOfAllItems.length; ++i){
-			item = this._arrayOfAllItems[i];
-			for(key in item){
-				if(key !== this._rootItemPropName){
-					var value = item[key];
-					if(value !== null){
-						if(!lang.isArray(value)){
-							item[key] = [value];
-						}
-					}else{
-						item[key] = [null];
-					}
+				if(flag){	//dojo.toJson, and maybe user, adds surrounding quotes, which we need to remove.
+					complexQuery = complexQuery.replace(/^\"|^\'|\"$|\'$/g,"");
 				}
-				allAttributeNames[key]=key;
-			}
-		}
-
-		// Step 3: Build unique property names to use for the _storeRefPropName and _itemNumPropName
-		// This should go really fast, it will generally never even run the loop.
-		while(allAttributeNames[this._storeRefPropName]){
-			this._storeRefPropName += "_";
-		}
-		while(allAttributeNames[this._itemNumPropName]){
-			this._itemNumPropName += "_";
-		}
-		while(allAttributeNames[this._reverseRefMap]){
-			this._reverseRefMap += "_";
-		}
-
-		// Step 4: Some data files specify an optional 'identifier', which is
-		// the name of an attribute that holds the identity of each item.
-		// If this data file specified an identifier attribute, then build a
-		// hash table of items keyed by the identity of the items.
-		var arrayOfValues;
-
-		var identifier = dataObject.identifier;
-		if(identifier){
-			this._itemsByIdentity = {};
-			this._features['dojo.data.api.Identity'] = identifier;
-			for(i = 0; i < this._arrayOfAllItems.length; ++i){
-				item = this._arrayOfAllItems[i];
-				arrayOfValues = item[identifier];
-				var identity = arrayOfValues[0];
-				if(!this._itemsByIdentity[identity]){
-					this._itemsByIdentity[identity] = item;
+			} //end query="{complexQuery:'id:1* || dept:Sales'}" parsing (for when widget required json object query).
+			var complexQuerySave = complexQuery;
+			//valid logical operators.
+			var begRegExp = /^>=|^<=|^<|^>|^,|^NOT |^AND |^OR |^\(|^\)|^!|^&&|^\|\|/i; //trailing space on some tokens on purpose.
+			var sQuery = ""; //will be eval'ed for each i-th candidateItem, based on query components.
+			var op = "";
+			var val = "";
+			var pos = -1;
+			var err = false;
+			var key = "";
+			var value = "";
+			var tok = "";
+			pos2 = -1;
+			for(i = 0; i < arrayOfItems.length; ++i){
+				var match = true;
+				var candidateItem = arrayOfItems[i];
+				if(candidateItem === null){
+					match = false;
 				}else{
-					if(this._jsonFileUrl){
-						throw new Error("dojox.data.AndOrReadStore:  The json data as specified by: [" + this._jsonFileUrl + "] is malformed.  Items within the list have identifier: [" + identifier + "].  Value collided: [" + identity + "]");
-					}else if(this._jsonData){
-						throw new Error("dojox.data.AndOrReadStore:  The json data provided by the creation arguments is malformed.  Items within the list have identifier: [" + identifier + "].  Value collided: [" + identity + "]");
-					}
-				}
-			}
-		}else{
-			this._features['dojo.data.api.Identity'] = Number;
-		}
-
-		// Step 5: Walk through all the items, and set each item's properties
-		// for _storeRefPropName and _itemNumPropName, so that store.isItem() will return true.
-		for(i = 0; i < this._arrayOfAllItems.length; ++i){
-			item = this._arrayOfAllItems[i];
-			item[this._storeRefPropName] = this;
-			item[this._itemNumPropName] = i;
-		}
-
-		// Step 6: We walk through all the attribute values of all the items,
-		// looking for type/value literals and item-references.
-		//
-		// We replace item-references with pointers to items.  For example, we change:
-		//		{ name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] }
-		// into this:
-		//		{ name:['Kermit'], friends:[miss_piggy] }
-		// (where miss_piggy is the object representing the 'Miss Piggy' item).
-		//
-		// We replace type/value pairs with typed-literals.  For example, we change:
-		//		{ name:['Nelson Mandela'], born:[{_type:'Date', _value:'July 18, 1918'}] }
-		// into this:
-		//		{ name:['Kermit'], born:(new Date('July 18, 1918')) }
-		//
-		// We also generate the associate map for all items for the O(1) isItem function.
-		for(i = 0; i < this._arrayOfAllItems.length; ++i){
-			item = this._arrayOfAllItems[i]; // example: { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] }
-			for(key in item){
-				arrayOfValues = item[key]; // example: [{_reference:{name:'Miss Piggy'}}]
-				for(var j = 0; j < arrayOfValues.length; ++j){
-					value = arrayOfValues[j]; // example: {_reference:{name:'Miss Piggy'}}
-					if(value !== null && typeof value == "object"){
-						if(("_type" in value) && ("_value" in value)){
-							var type = value._type; // examples: 'Date', 'Color', or 'ComplexNumber'
-							var mappingObj = this._datatypeMap[type]; // examples: Date, dojo.Color, foo.math.ComplexNumber, {type: dojo.Color, deserialize(value){ return new dojo.Color(value)}}
-							if(!mappingObj){
-								throw new Error("dojox.data.AndOrReadStore: in the typeMap constructor arg, no object class was specified for the datatype '" + type + "'");
-							}else if(lang.isFunction(mappingObj)){
-								arrayOfValues[j] = new mappingObj(value._value);
-							}else if(lang.isFunction(mappingObj.deserialize)){
-								arrayOfValues[j] = mappingObj.deserialize(value._value);
-							}else{
-								throw new Error("dojox.data.AndOrReadStore: Value provided in typeMap was neither a constructor, nor a an object with a deserialize function");
-							}
-						}
-						if(value._reference){
-							var referenceDescription = value._reference; // example: {name:'Miss Piggy'}
-							if(!lang.isObject(referenceDescription)){
-								// example: 'Miss Piggy'
-								// from an item like: { name:['Kermit'], friends:[{_reference:'Miss Piggy'}]}
-								arrayOfValues[j] = this._getItemByIdentity(referenceDescription);
+					//process entire string for this i-th candidateItem.
+					complexQuery = complexQuerySave; //restore query for next candidateItem.
+					sQuery = "";
+					//work left to right, finding either key:value pair or logical operator at the beginning of the complexQuery string.
+					//when found, concatenate to sQuery and remove from complexQuery and loop back.
+					while(complexQuery.length > 0 && !err){
+						op = complexQuery.match(begRegExp);
+
+						//get/process/append one or two leading logical operators.
+						while(op && !err){ //look for leading logical operators.
+							complexQuery = lang.trim(complexQuery.replace(op[0],""));
+							op = lang.trim(op[0]).toUpperCase();
+							//convert some logical operators to their javascript equivalents for later eval.
+							op = op == "NOT" ? "!" : op == "AND" || op == "," ? "&&" : op == "OR" ? "||" : op;
+							op = " " + op + " ";
+							sQuery += op;
+							op = complexQuery.match(begRegExp);
+						}//end op && !err
+
+						//now get/process/append one key:value pair.
+						if(complexQuery.length > 0){
+							var opsRegex = /:|>=|<=|>|</g,
+								matches = complexQuery.match(opsRegex),
+								match = matches && matches.shift(),
+								regex;
+
+							pos = complexQuery.indexOf(match);
+							if(pos == -1){
+								err = true;
+								break;
 							}else{
-								// example: {name:'Miss Piggy'}
-								// from an item like: { name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] }
-								for(var k = 0; k < this._arrayOfAllItems.length; ++k){
-									var candidateItem = this._arrayOfAllItems[k];
-									var found = true;
-									for(var refKey in referenceDescription){
-										if(candidateItem[refKey] != referenceDescription[refKey]){
-											found = false;
-										}
+								key = lang.trim(complexQuery.substring(0,pos).replace(/\"|\'/g,""));
+								complexQuery = lang.trim(complexQuery.substring(pos + match.length));
+								tok = complexQuery.match(/^\'|^\"/);	//quoted?
+								if(tok){
+									tok = tok[0];
+									pos = complexQuery.indexOf(tok);
+									pos2 = complexQuery.indexOf(tok,pos + 1);
+									if(pos2 == -1){
+										err = true;
+										break;
 									}
-									if(found){
-										arrayOfValues[j] = candidateItem;
+									value = complexQuery.substring(pos + match.length,pos2);
+									if(pos2 == complexQuery.length - 1){ //quote is last character
+										complexQuery = "";
+									}else{
+										complexQuery = lang.trim(complexQuery.substring(pos2 + 1));
 									}
+									if (match != ':') {
+										regex = this.getValue(candidateItem, key) + match + value;
+									} else {
+										regex = filterUtil.patternToRegExp(value, ignoreCase);
+									}
+									sQuery += this._containsValue(candidateItem, key, value, regex);
 								}
-							}
-							if(this.referenceIntegrity){
-								var refItem = arrayOfValues[j];
-								if(this.isItem(refItem)){
-									this._addReferenceToMap(refItem, item, key);
-								}
-							}
-						}else if(this.isItem(value)){
-							//It's a child item (not one referenced through _reference).
-							//We need to treat this as a referenced item, so it can be cleaned up
-							//in a write store easily.
-							if(this.referenceIntegrity){
-								this._addReferenceToMap(value, item, key);
-							}
-						}
-					}
+								else{ //not quoted, so a space, comma, or closing parens (or the end) will be the break.
+									tok = complexQuery.match(/\s|\)|,/);
+									if(tok){
+										var pos3 = new Array(tok.length);
+										for(var j = 0;j<tok.length;j++){
+											pos3[j] = complexQuery.indexOf(tok[j]);
+										}
+										pos = pos3[0];
+										if(pos3.length > 1){
+											for(var j=1;j<pos3.length;j++){
+												pos = Math.min(pos,pos3[j]);
+											}
+										}
+										value = lang.trim(complexQuery.substring(0,pos));
+										complexQuery = lang.trim(complexQuery.substring(pos));
+									}else{ //not a space, so must be at the end of the complexQuery.
+										value = lang.trim(complexQuery);
+										complexQuery = "";
+									} //end  inner if(tok) else
+									if (match != ':') {
+										regex = this.getValue(candidateItem, key) + match + value;
+									} else {
+										regex = filterUtil.patternToRegExp(value, ignoreCase);
+										console.log("regex value: ", value, " regex pattern: ", regex);
+									}
+									sQuery += this._containsValue(candidateItem, key, value, regex);
+								} //end outer if(tok) else
+							} //end found ":"
+						} //end if(complexQuery.length > 0)
+					} //end while complexQuery.length > 0 && !err, so finished the i-th item.
+					match = eval(sQuery);
+				} //end else is non-null candidateItem.
+				if(match){
+					items.push(candidateItem);
 				}
+			} //end for/next of all items.
+			if(err){
+				//soft fail.
+				items = [];
+				console.log("The store's _fetchItems failed, probably due to a syntax error in query.");
 			}
-		}
-	},
-
-	_addReferenceToMap: function(/*item*/ refItem, /*item*/ parentItem, /*string*/ attribute){
-		 //	summary:
-		 //		Method to add an reference map entry for an item and attribute.
-		 //	description:
-		 //		Method to add an reference map entry for an item and attribute. 		 //
-		 //	refItem:
-		 //		The item that is referenced.
-		 //	parentItem:
-		 //		The item that holds the new reference to refItem.
-		 //	attribute:
-		 //		The attribute on parentItem that contains the new reference.
-		 
-		 //Stub function, does nothing.  Real processing is in ItemFileWriteStore.
-	},
-
-	getIdentity: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Identity.getIdentity()
-		var identifier = this._features['dojo.data.api.Identity'];
-		if(identifier === Number){
-			return item[this._itemNumPropName]; // Number
 		}else{
-			var arrayOfValues = item[identifier];
-			if(arrayOfValues){
-				return arrayOfValues[0]; // Object || String
-			}
-		}
-		return null; // null
-	},
-
-	fetchItemByIdentity: function(/* Object */ keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Identity.fetchItemByIdentity()
-
-		// Hasn't loaded yet, we have to trigger the load.
-		if(!this._loadFinished){
-			var self = this;
-			if(this._jsonFileUrl !== this._ccUrl){
-				kernel.deprecated("dojox.data.AndOrReadStore: ",
-								"To change the url, set the url property of the store," +
-								" not _jsonFileUrl.  _jsonFileUrl support will be removed in 2.0");
-				this._ccUrl = this._jsonFileUrl;
-				this.url = this._jsonFileUrl;
-			}else if(this.url !== this._ccUrl){
-				this._jsonFileUrl = this.url;
-				this._ccUrl = this.url;
-			}
-			//See if there was any forced reset of data.
-			if(this.data != null && this._jsonData == null){
-				this._jsonData = this.data;
-				this.data = null;
-			}
-			if(this._jsonFileUrl){
-
-				if(this._loadInProgress){
-					this._queuedFetches.push({args: keywordArgs});
-				}else{
-					this._loadInProgress = true;
-					var getArgs = {
-							url: self._jsonFileUrl,
-							handleAs: "json-comment-optional",
-							preventCache: this.urlPreventCache
-					};
-					var getHandler = xhr.get(getArgs);
-					getHandler.addCallback(function(data){
-						var scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
-						try{
-							self._getItemsFromLoadedData(data);
-							self._loadFinished = true;
-							self._loadInProgress = false;
-							var item = self._getItemByIdentity(keywordArgs.identity);
-							if(keywordArgs.onItem){
-								keywordArgs.onItem.call(scope, item);
-							}
-							self._handleQueuedFetches();
-						}catch(error){
-							self._loadInProgress = false;
-							if(keywordArgs.onError){
-								keywordArgs.onError.call(scope, error);
-							}
-						}
-					});
-					getHandler.addErrback(function(error){
-						self._loadInProgress = false;
-						if(keywordArgs.onError){
-							var scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
-							keywordArgs.onError.call(scope, error);
-						}
-					});
+			// No query...
+			// We want a copy to pass back in case the parent wishes to sort the array.
+			// We shouldn't allow resort of the internal list, so that multiple callers
+			// can get lists and sort without affecting each other.  We also need to
+			// filter out any null values that have been left as a result of deleteItem()
+			// calls in ItemFileWriteStore.
+			for(var i = 0; i < arrayOfItems.length; ++i){
+				var item = arrayOfItems[i];
+				if(item !== null){
+					items.push(item);
 				}
-
-			}else if(this._jsonData){
-				// Passed in data, no need to xhr.
-				self._getItemsFromLoadedData(self._jsonData);
-				self._jsonData = null;
-				self._loadFinished = true;
-				var item = self._getItemByIdentity(keywordArgs.identity);
-				if(keywordArgs.onItem){
-					var scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
-					keywordArgs.onItem.call(scope, item);
-				}
-			}
-		}else{
-			// Already loaded.  We can just look it up and call back.
-			var item = this._getItemByIdentity(keywordArgs.identity);
-			if(keywordArgs.onItem){
-				var scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
-				keywordArgs.onItem.call(scope, item);
 			}
-		}
-	},
+		} //end if there is a query.
+		findCallback(items, requestArgs);
+	} //end filter function
 
-	_getItemByIdentity: function(/* Object */ identity){
-		//	summary:
-		//		Internal function to look an item up by its identity map.
-		var item = null;
-		if(this._itemsByIdentity){
-			item = this._itemsByIdentity[identity];
-		}else{
-			item = this._arrayOfAllItems[identity];
-		}
-		if(item === undefined){
-			item = null;
-		}
-		return item; // Object
-	},
-
-	getIdentityAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Identity.getIdentifierAttributes()
-		 
-		var identifier = this._features['dojo.data.api.Identity'];
-		if(identifier === Number){
-			// If (identifier === Number) it means getIdentity() just returns
-			// an integer item-number for each item.  The dojo.data.api.Identity
-			// spec says we need to return null if the identity is not composed
-			// of attributes
-			return null; // null
-		}else{
-			return [identifier]; // Array
-		}
-	},
-	
-	_forceLoad: function(){
-		//	summary:
-		//		Internal function to force a load of the store if it hasn't occurred yet.  This is required
-		//		for specific functions to work properly.
-		var self = this;
-		if(this._jsonFileUrl !== this._ccUrl){
-			kernel.deprecated("dojox.data.AndOrReadStore: ",
-							"To change the url, set the url property of the store," +
-							" not _jsonFileUrl.  _jsonFileUrl support will be removed in 2.0");
-			this._ccUrl = this._jsonFileUrl;
-			this.url = this._jsonFileUrl;
-		}else if(this.url !== this._ccUrl){
-			this._jsonFileUrl = this.url;
-			this._ccUrl = this.url;
-		}
-		//See if there was any forced reset of data.
-		if(this.data != null && this._jsonData == null){
-			this._jsonData = this.data;
-			this.data = null;
-		}
-		if(this._jsonFileUrl){
-				var getArgs = {
-					url: self._jsonFileUrl,
-					handleAs: "json-comment-optional",
-					preventCache: this.urlPreventCache,
-					sync: true
-				};
-			var getHandler = xhr.get(getArgs);
-			getHandler.addCallback(function(data){
-				try{
-					//Check to be sure there wasn't another load going on concurrently
-					//So we don't clobber data that comes in on it.  If there is a load going on
-					//then do not save this data.  It will potentially clobber current data.
-					//We mainly wanted to sync/wait here.
-					//TODO:  Revisit the loading scheme of this store to improve multi-initial
-					//request handling.
-					if(self._loadInProgress !== true && !self._loadFinished){
-						self._getItemsFromLoadedData(data);
-						self._loadFinished = true;
-					}else if(self._loadInProgress){
-						//Okay, we hit an error state we can't recover from.  A forced load occurred
-						//while an async load was occurring.  Since we cannot block at this point, the best
-						//that can be managed is to throw an error.
-						throw new Error("dojox.data.AndOrReadStore:  Unable to perform a synchronous load, an async load is in progress.");
-					}
-				}catch(e){
-					console.log(e);
-					throw e;
-				}
-			});
-			getHandler.addErrback(function(error){
-				throw error;
-			});
-		}else if(this._jsonData){
-			self._getItemsFromLoadedData(self._jsonData);
-			self._jsonData = null;
-			self._loadFinished = true;
-		}
-	}
 });
-//Mix in the simple fetch implementation to this class.
-lang.extend(AndOrReadStore, simpleFetch);
 
-return AndOrReadStore;
 });
-
-
diff --git a/dojox/data/AndOrWriteStore.js b/dojox/data/AndOrWriteStore.js
index 8c67bae..1ebe02c 100755
--- a/dojox/data/AndOrWriteStore.js
+++ b/dojox/data/AndOrWriteStore.js
@@ -1,811 +1,11 @@
-define(["dojo/_base/declare","dojo/_base/lang","dojo/_base/array", "dojo/_base/json", "dojo/date/stamp",
-		"dojo/_base/window", "./AndOrReadStore"], 
-  function(declare, lang, arrayUtil, json, dateStamp, winUtil, AndOrReadStore) {
-/*===== var AndOrReadStore = dojox.data.AndOrReadStore; =====*/
+define(["dojo/_base/declare", "dojo/data/ItemFileWriteStore", "./AndOrReadStore"],
+  function(declare, ItemFileWriteStore, AndOrReadStore){
 
-return declare("dojox.data.AndOrWriteStore", AndOrReadStore, {
-	constructor: function(/* object */ keywordParameters){
-		//	keywordParameters: {typeMap: object)
-		//		The structure of the typeMap object is as follows:
-		//		{
-		//			type0: function || object,
-		//			type1: function || object,
-		//			...
-		//			typeN: function || object
-		//		}
-		//		Where if it is a function, it is assumed to be an object constructor that takes the
-		//		value of _value as the initialization parameters.  It is serialized assuming object.toString()
-		//		serialization.  If it is an object, then it is assumed
-		//		to be an object of general form:
-		//		{
-		//			type: function, //constructor.
-		//			deserialize:	function(value) //The function that parses the value and constructs the object defined by type appropriately.
-		//			serialize:	function(object) //The function that converts the object back into the proper file format form.
-		//		}
+// module:
+//		dojox/data/AndOrWriteStore
+// summary:
+//		TODOC
 
-		// AndOrWriteStore duplicates ItemFileWriteStore, except extends AndOrReadStore, which offers complex queries.
-		// ItemFileWriteStore extends ItemFileReadStore to implement these additional dojo.data APIs
-		this._features['dojo.data.api.Write'] = true;
-		this._features['dojo.data.api.Notification'] = true;
-		
-		// For keeping track of changes so that we can implement isDirty and revert
-		this._pending = {
-			_newItems:{},
-			_modifiedItems:{},
-			_deletedItems:{}
-		};
-
-		if(!this._datatypeMap['Date'].serialize){
-			this._datatypeMap['Date'].serialize = function(obj){
-				return dateStamp.toISOString(obj, {zulu:true});
-			};
-		}
-		//Disable only if explicitly set to false.
-		if(keywordParameters && (keywordParameters.referenceIntegrity === false)){
-			this.referenceIntegrity = false;
-		}
-
-		// this._saveInProgress is set to true, briefly, from when save() is first called to when it completes
-		this._saveInProgress = false;
-	},
-
-	referenceIntegrity: true, //Flag that defaultly enabled reference integrity tracking.  This way it can also be disabled pogrammatially or declaratively.
-
-	_assert: function(/* boolean */ condition){
-		if(!condition){
-			throw new Error("assertion failed in ItemFileWriteStore");
-		}
-	},
-
-	_getIdentifierAttribute: function(){
-		var identifierAttribute = this.getFeatures()['dojo.data.api.Identity'];
-		// this._assert((identifierAttribute === Number) || (dojo.isString(identifierAttribute)));
-		return identifierAttribute;
-	},
-	
-	
-/* dojo.data.api.Write */
-
-	newItem: function(/* Object? */ keywordArgs, /* Object? */ parentInfo){
-		// summary: See dojo.data.api.Write.newItem()
-
-		this._assert(!this._saveInProgress);
-
-		if(!this._loadFinished){
-			// We need to do this here so that we'll be able to find out what
-			// identifierAttribute was specified in the data file.
-			this._forceLoad();
-		}
-
-		if(typeof keywordArgs != "object" && typeof keywordArgs != "undefined"){
-			throw new Error("newItem() was passed something other than an object");
-		}
-		var newIdentity = null;
-		var identifierAttribute = this._getIdentifierAttribute();
-		if(identifierAttribute === Number){
-			newIdentity = this._arrayOfAllItems.length;
-		}else{
-			newIdentity = keywordArgs[identifierAttribute];
-			if(typeof newIdentity === "undefined"){
-				throw new Error("newItem() was not passed an identity for the new item");
-			}
-			if(lang.isArray(newIdentity)){
-				throw new Error("newItem() was not passed an single-valued identity");
-			}
-		}
-		
-		// make sure this identity is not already in use by another item, if identifiers were
-		// defined in the file.  Otherwise it would be the item count,
-		// which should always be unique in this case.
-		if(this._itemsByIdentity){
-			this._assert(typeof this._itemsByIdentity[newIdentity] === "undefined");
-		}
-		this._assert(typeof this._pending._newItems[newIdentity] === "undefined");
-		this._assert(typeof this._pending._deletedItems[newIdentity] === "undefined");
-		
-		var newItem = {};
-		newItem[this._storeRefPropName] = this;
-		newItem[this._itemNumPropName] = this._arrayOfAllItems.length;
-		if(this._itemsByIdentity){
-			this._itemsByIdentity[newIdentity] = newItem;
-			//We have to set the identifier now, otherwise we can't look it
-			//up at calls to setValueorValues in parentInfo handling.
-			newItem[identifierAttribute] = [newIdentity];
-		}
-		this._arrayOfAllItems.push(newItem);
-
-		//We need to construct some data for the onNew call too...
-		var pInfo = null;
-		
-		// Now we need to check to see where we want to assign this thingm if any.
-		if(parentInfo && parentInfo.parent && parentInfo.attribute){
-			pInfo = {
-				item: parentInfo.parent,
-				attribute: parentInfo.attribute,
-				oldValue: undefined
-			};
-
-			//See if it is multi-valued or not and handle appropriately
-			//Generally, all attributes are multi-valued for this store
-			//So, we only need to append if there are already values present.
-			var values = this.getValues(parentInfo.parent, parentInfo.attribute);
-			if(values && values.length > 0){
-				var tempValues = values.slice(0, values.length);
-				if(values.length === 1){
-					pInfo.oldValue = values[0];
-				}else{
-					pInfo.oldValue = values.slice(0, values.length);
-				}
-				tempValues.push(newItem);
-				this._setValueOrValues(parentInfo.parent, parentInfo.attribute, tempValues, false);
-				pInfo.newValue = this.getValues(parentInfo.parent, parentInfo.attribute);
-			}else{
-				this._setValueOrValues(parentInfo.parent, parentInfo.attribute, newItem, false);
-				pInfo.newValue = newItem;
-			}
-		}else{
-			//Toplevel item, add to both top list as well as all list.
-			newItem[this._rootItemPropName]=true;
-			this._arrayOfTopLevelItems.push(newItem);
-		}
-		
-		this._pending._newItems[newIdentity] = newItem;
-		
-		//Clone over the properties to the new item
-		for(var key in keywordArgs){
-			if(key === this._storeRefPropName || key === this._itemNumPropName){
-				// Bummer, the user is trying to do something like
-				// newItem({_S:"foo"}).  Unfortunately, our superclass,
-				// ItemFileReadStore, is already using _S in each of our items
-				// to hold private info.  To avoid a naming collision, we
-				// need to move all our private info to some other property
-				// of all the items/objects.  So, we need to iterate over all
-				// the items and do something like:
-				//    item.__S = item._S;
-				//    item._S = undefined;
-				// But first we have to make sure the new "__S" variable is
-				// not in use, which means we have to iterate over all the
-				// items checking for that.
-				throw new Error("encountered bug in ItemFileWriteStore.newItem");
-			}
-			var value = keywordArgs[key];
-			if(!lang.isArray(value)){
-				value = [value];
-			}
-			newItem[key] = value;
-			if(this.referenceIntegrity){
-				for(var i = 0; i < value.length; i++){
-					var val = value[i];
-					if(this.isItem(val)){
-						this._addReferenceToMap(val, newItem, key);
-					}
-				}
-			}
-		}
-		this.onNew(newItem, pInfo); // dojo.data.api.Notification call
-		return newItem; // item
-	},
-	
-	_removeArrayElement: function(/* Array */ array, /* anything */ element){
-		var index = arrayUtil.indexOf(array, element);
-		if(index != -1){
-			array.splice(index, 1);
-			return true;
-		}
-		return false;
-	},
-	
-	deleteItem: function(/* item */ item){
-		// summary: See dojo.data.api.Write.deleteItem()
-		this._assert(!this._saveInProgress);
-		this._assertIsItem(item);
-
-		// Remove this item from the _arrayOfAllItems, but leave a null value in place
-		// of the item, so as not to change the length of the array, so that in newItem()
-		// we can still safely do: newIdentity = this._arrayOfAllItems.length;
-		var indexInArrayOfAllItems = item[this._itemNumPropName];
-		var identity = this.getIdentity(item);
-
-		//If we have reference integrity on, we need to do reference cleanup for the deleted item
-		if(this.referenceIntegrity){
-			//First scan all the attributes of this items for references and clean them up in the map
-			//As this item is going away, no need to track its references anymore.
-
-			//Get the attributes list before we generate the backup so it
-			//doesn't pollute the attributes list.
-			var attributes = this.getAttributes(item);
-
-			//Backup the map, we'll have to restore it potentially, in a revert.
-			if(item[this._reverseRefMap]){
-				item["backup_" + this._reverseRefMap] = lang.clone(item[this._reverseRefMap]);
-			}
-			
-			//TODO:  This causes a reversion problem.  This list won't be restored on revert since it is
-			//attached to the 'value'. item, not ours.  Need to back tese up somehow too.
-			//Maybe build a map of the backup of the entries and attach it to the deleted item to be restored
-			//later.  Or just record them and call _addReferenceToMap on them in revert.
-			arrayUtil.forEach(attributes, function(attribute){
-				arrayUtil.forEach(this.getValues(item, attribute), function(value){
-					if(this.isItem(value)){
-						//We have to back up all the references we had to others so they can be restored on a revert.
-						if(!item["backupRefs_" + this._reverseRefMap]){
-							item["backupRefs_" + this._reverseRefMap] = [];
-						}
-						item["backupRefs_" + this._reverseRefMap].push({id: this.getIdentity(value), attr: attribute});
-						this._removeReferenceFromMap(value, item, attribute);
-					}
-				}, this);
-			}, this);
-
-			//Next, see if we have references to this item, if we do, we have to clean them up too.
-			var references = item[this._reverseRefMap];
-			if(references){
-				//Look through all the items noted as references to clean them up.
-				for(var itemId in references){
-					var containingItem = null;
-					if(this._itemsByIdentity){
-						containingItem = this._itemsByIdentity[itemId];
-					}else{
-						containingItem = this._arrayOfAllItems[itemId];
-					}
-					//We have a reference to a containing item, now we have to process the
-					//attributes and clear all references to the item being deleted.
-					if(containingItem){
-						for(var attribute in references[itemId]){
-							var oldValues = this.getValues(containingItem, attribute) || [];
-							var newValues = arrayUtil.filter(oldValues, function(possibleItem){
-								return !(this.isItem(possibleItem) && this.getIdentity(possibleItem) == identity);
-							}, this);
-							//Remove the note of the reference to the item and set the values on the modified attribute.
-							this._removeReferenceFromMap(item, containingItem, attribute);
-							if(newValues.length < oldValues.length){
-								this._setValueOrValues(containingItem, attribute, newValues);
-							}
-						}
-					}
-				}
-			}
-		}
-
-		this._arrayOfAllItems[indexInArrayOfAllItems] = null;
-
-		item[this._storeRefPropName] = null;
-		if(this._itemsByIdentity){
-			delete this._itemsByIdentity[identity];
-		}
-		this._pending._deletedItems[identity] = item;
-		
-		//Remove from the toplevel items, if necessary...
-		if(item[this._rootItemPropName]){
-			this._removeArrayElement(this._arrayOfTopLevelItems, item);
-		}
-		this.onDelete(item); // dojo.data.api.Notification call
-		return true;
-	},
-
-	setValue: function(/* item */ item, /* attribute-name-string */ attribute, /* almost anything */ value){
-		// summary: See dojo.data.api.Write.set()
-		return this._setValueOrValues(item, attribute, value, true); // boolean
-	},
-	
-	setValues: function(/* item */ item, /* attribute-name-string */ attribute, /* array */ values){
-		// summary: See dojo.data.api.Write.setValues()
-		return this._setValueOrValues(item, attribute, values, true); // boolean
-	},
-	
-	unsetAttribute: function(/* item */ item, /* attribute-name-string */ attribute){
-		// summary: See dojo.data.api.Write.unsetAttribute()
-		return this._setValueOrValues(item, attribute, [], true);
-	},
-	
-	_setValueOrValues: function(/* item */ item, /* attribute-name-string */ attribute, /* anything */ newValueOrValues, /*boolean?*/ callOnSet){
-		this._assert(!this._saveInProgress);
-		
-		// Check for valid arguments
-		this._assertIsItem(item);
-		this._assert(lang.isString(attribute));
-		this._assert(typeof newValueOrValues !== "undefined");
-
-		// Make sure the user isn't trying to change the item's identity
-		var identifierAttribute = this._getIdentifierAttribute();
-		if(attribute == identifierAttribute){
-			throw new Error("ItemFileWriteStore does not have support for changing the value of an item's identifier.");
-		}
-
-		// To implement the Notification API, we need to make a note of what
-		// the old attribute value was, so that we can pass that info when
-		// we call the onSet method.
-		var oldValueOrValues = this._getValueOrValues(item, attribute);
-
-		var identity = this.getIdentity(item);
-		if(!this._pending._modifiedItems[identity]){
-			// Before we actually change the item, we make a copy of it to
-			// record the original state, so that we'll be able to revert if
-			// the revert method gets called.  If the item has already been
-			// modified then there's no need to do this now, since we already
-			// have a record of the original state.
-			var copyOfItemState = {};
-			for(var key in item){
-				if((key === this._storeRefPropName) || (key === this._itemNumPropName) || (key === this._rootItemPropName)){
-					copyOfItemState[key] = item[key];
-				}else if(key === this._reverseRefMap){
-					copyOfItemState[key] = lang.clone(item[key]);
-				}else{
-					copyOfItemState[key] = item[key].slice(0, item[key].length);
-				}
-			}
-			// Now mark the item as dirty, and save the copy of the original state
-			this._pending._modifiedItems[identity] = copyOfItemState;
-		}
-		
-		// Okay, now we can actually change this attribute on the item
-		var success = false;
-		
-		if(lang.isArray(newValueOrValues) && newValueOrValues.length === 0){
-			
-			// If we were passed an empty array as the value, that counts
-			// as "unsetting" the attribute, so we need to remove this
-			// attribute from the item.
-			success = delete item[attribute];
-			newValueOrValues = undefined; // used in the onSet Notification call below
-
-			if(this.referenceIntegrity && oldValueOrValues){
-				var oldValues = oldValueOrValues;
-				if(!lang.isArray(oldValues)){
-					oldValues = [oldValues];
-				}
-				for(var i = 0; i < oldValues.length; i++){
-					var value = oldValues[i];
-					if(this.isItem(value)){
-						this._removeReferenceFromMap(value, item, attribute);
-					}
-				}
-			}
-		}else{
-			var newValueArray;
-			if(lang.isArray(newValueOrValues)){
-				var newValues = newValueOrValues;
-				// Unfortunately, it's not safe to just do this:
-				//    newValueArray = newValues;
-				// Instead, we need to copy the array, which slice() does very nicely.
-				// This is so that our internal data structure won't
-				// get corrupted if the user mucks with the values array *after*
-				// calling setValues().
-				newValueArray = newValueOrValues.slice(0, newValueOrValues.length);
-			}else{
-				newValueArray = [newValueOrValues];
-			}
-
-			//We need to handle reference integrity if this is on.
-			//In the case of set, we need to see if references were added or removed
-			//and update the reference tracking map accordingly.
-			if(this.referenceIntegrity){
-				if(oldValueOrValues){
-					var oldValues = oldValueOrValues;
-					if(!lang.isArray(oldValues)){
-						oldValues = [oldValues];
-					}
-					//Use an associative map to determine what was added/removed from the list.
-					//Should be O(n) performant.  First look at all the old values and make a list of them
-					//Then for any item not in the old list, we add it.  If it was already present, we remove it.
-					//Then we pass over the map and any references left it it need to be removed (IE, no match in
-					//the new values list).
-					var map = {};
-					arrayUtil.forEach(oldValues, function(possibleItem){
-						if(this.isItem(possibleItem)){
-							var id = this.getIdentity(possibleItem);
-							map[id.toString()] = true;
-						}
-					}, this);
-					arrayUtil.forEach(newValueArray, function(possibleItem){
-						if(this.isItem(possibleItem)){
-							var id = this.getIdentity(possibleItem);
-							if(map[id.toString()]){
-								delete map[id.toString()];
-							}else{
-								this._addReferenceToMap(possibleItem, item, attribute);
-							}
-						}
-					}, this);
-					for(var rId in map){
-						var removedItem;
-						if(this._itemsByIdentity){
-							removedItem = this._itemsByIdentity[rId];
-						}else{
-							removedItem = this._arrayOfAllItems[rId];
-						}
-						this._removeReferenceFromMap(removedItem, item, attribute);
-					}
-				}else{
-					//Everything is new (no old values) so we have to just
-					//insert all the references, if any.
-					for(var i = 0; i < newValueArray.length; i++){
-						var value = newValueArray[i];
-						if(this.isItem(value)){
-							this._addReferenceToMap(value, item, attribute);
-						}
-					}
-				}
-			}
-			item[attribute] = newValueArray;
-			success = true;
-		}
-
-		// Now we make the dojo.data.api.Notification call
-		if(callOnSet){
-			this.onSet(item, attribute, oldValueOrValues, newValueOrValues);
-		}
-		return success; // boolean
-	},
-
-	_addReferenceToMap: function(/*item*/ refItem, /*item*/ parentItem, /*string*/ attribute){
-		//	summary:
-		//		Method to add an reference map entry for an item and attribute.
-		//	description:
-		//		Method to add an reference map entry for an item and attribute. 		 //
-		//	refItem:
-		//		The item that is referenced.
-		//	parentItem:
-		//		The item that holds the new reference to refItem.
-		//	attribute:
-		//		The attribute on parentItem that contains the new reference.
-		 
-		var parentId = this.getIdentity(parentItem);
-		var references = refItem[this._reverseRefMap];
-
-		if(!references){
-			references = refItem[this._reverseRefMap] = {};
-		}
-		var itemRef = references[parentId];
-		if(!itemRef){
-			itemRef = references[parentId] = {};
-		}
-		itemRef[attribute] = true;
-	},
-
-	_removeReferenceFromMap: function(/* item */ refItem, /* item */ parentItem, /*strin*/ attribute){
-		//	summary:
-		//		Method to remove an reference map entry for an item and attribute.
-		//	description:
-		//		Method to remove an reference map entry for an item and attribute.  This will
-		//		also perform cleanup on the map such that if there are no more references at all to
-		//		the item, its reference object and entry are removed.
-		//
-		//	refItem:
-		//		The item that is referenced.
-		//	parentItem:
-		//		The item holding a reference to refItem.
-		//	attribute:
-		//		The attribute on parentItem that contains the reference.
-		var identity = this.getIdentity(parentItem);
-		var references = refItem[this._reverseRefMap];
-		var itemId;
-		if(references){
-			for(itemId in references){
-				if(itemId == identity){
-					delete references[itemId][attribute];
-					if(this._isEmpty(references[itemId])){
-						delete references[itemId];
-					}
-				}
-			}
-			if(this._isEmpty(references)){
-				delete refItem[this._reverseRefMap];
-			}
-		}
-	},
-
-	_dumpReferenceMap: function(){
-		//	summary:
-		//		Function to dump the reverse reference map of all items in the store for debug purposes.
-		//	description:
-		//		Function to dump the reverse reference map of all items in the store for debug purposes.
-		var i;
-		for(i = 0; i < this._arrayOfAllItems.length; i++){
-			var item = this._arrayOfAllItems[i];
-			if(item && item[this._reverseRefMap]){
-				console.log("Item: [" + this.getIdentity(item) + "] is referenced by: " + json.toJson(item[this._reverseRefMap]));
-			}
-		}
-	},
-	
-	_getValueOrValues: function(/* item */ item, /* attribute-name-string */ attribute){
-		var valueOrValues = undefined;
-		if(this.hasAttribute(item, attribute)){
-			var valueArray = this.getValues(item, attribute);
-			if(valueArray.length == 1){
-				valueOrValues = valueArray[0];
-			}else{
-				valueOrValues = valueArray;
-			}
-		}
-		return valueOrValues;
-	},
-	
-	_flatten: function(/* anything */ value){
-		if(this.isItem(value)){
-			var item = value;
-			// Given an item, return an serializable object that provides a
-			// reference to the item.
-			// For example, given kermit:
-			//    var kermit = store.newItem({id:2, name:"Kermit"});
-			// we want to return
-			//    {_reference:2}
-			var identity = this.getIdentity(item);
-			var referenceObject = {_reference: identity};
-			return referenceObject;
-		}else{
-			if(typeof value === "object"){
-				for(var type in this._datatypeMap){
-					var typeMap = this._datatypeMap[type];
-					if(lang.isObject(typeMap) && !lang.isFunction(typeMap)){
-						if(value instanceof typeMap.type){
-							if(!typeMap.serialize){
-								throw new Error("ItemFileWriteStore:  No serializer defined for type mapping: [" + type + "]");
-							}
-							return {_type: type, _value: typeMap.serialize(value)};
-						}
-					} else if(value instanceof typeMap){
-						//SImple mapping, therefore, return as a toString serialization.
-						return {_type: type, _value: value.toString()};
-					}
-				}
-			}
-			return value;
-		}
-	},
-	
-	_getNewFileContentString: function(){
-		// summary:
-		//		Generate a string that can be saved to a file.
-		//		The result should look similar to:
-		//		http://trac.dojotoolkit.org/browser/dojo/trunk/tests/data/countries.json
-		var serializableStructure = {};
-		
-		var identifierAttribute = this._getIdentifierAttribute();
-		if(identifierAttribute !== Number){
-			serializableStructure.identifier = identifierAttribute;
-		}
-		if(this._labelAttr){
-			serializableStructure.label = this._labelAttr;
-		}
-		serializableStructure.items = [];
-		for(var i = 0; i < this._arrayOfAllItems.length; ++i){
-			var item = this._arrayOfAllItems[i];
-			if(item !== null){
-				var serializableItem = {};
-				for(var key in item){
-					if(key !== this._storeRefPropName && key !== this._itemNumPropName && key !== this._reverseRefMap && key !== this._rootItemPropName){
-						var attribute = key;
-						var valueArray = this.getValues(item, attribute);
-						if(valueArray.length == 1){
-							serializableItem[attribute] = this._flatten(valueArray[0]);
-						}else{
-							var serializableArray = [];
-							for(var j = 0; j < valueArray.length; ++j){
-								serializableArray.push(this._flatten(valueArray[j]));
-								serializableItem[attribute] = serializableArray;
-							}
-						}
-					}
-				}
-				serializableStructure.items.push(serializableItem);
-			}
-		}
-		var prettyPrint = true;
-		return json.toJson(serializableStructure, prettyPrint);
-	},
-
-	_isEmpty: function(something){
-		//	summary:
-		//		Function to determine if an array or object has no properties or values.
-		//	something:
-		//		The array or object to examine.
-		var empty = true;
-		if(lang.isObject(something)){
-			var i;
-			for(i in something){
-				empty = false;
-				break;
-			}
-		}else if(lang.isArray(something)){
-			if(something.length > 0){
-				empty = false;
-			}
-		}
-		return empty; //boolean
-	},
-	
-	save: function(/* object */ keywordArgs){
-		// summary: See dojo.data.api.Write.save()
-		this._assert(!this._saveInProgress);
-		
-		// this._saveInProgress is set to true, briefly, from when save is first called to when it completes
-		this._saveInProgress = true;
-		
-		var self = this;
-		var saveCompleteCallback = function(){
-			self._pending = {
-				_newItems:{},
-				_modifiedItems:{},
-				_deletedItems:{}
-			};
-
-			self._saveInProgress = false; // must come after this._pending is cleared, but before any callbacks
-			if(keywordArgs && keywordArgs.onComplete){
-				var scope = keywordArgs.scope || winUtil.global;
-				keywordArgs.onComplete.call(scope);
-			}
-		};
-		var saveFailedCallback = function(){
-			self._saveInProgress = false;
-			if(keywordArgs && keywordArgs.onError){
-				var scope = keywordArgs.scope || winUtil.global;
-				keywordArgs.onError.call(scope);
-			}
-		};
-		
-		if(this._saveEverything){
-			var newFileContentString = this._getNewFileContentString();
-			this._saveEverything(saveCompleteCallback, saveFailedCallback, newFileContentString);
-		}
-		if(this._saveCustom){
-			this._saveCustom(saveCompleteCallback, saveFailedCallback);
-		}
-		if(!this._saveEverything && !this._saveCustom){
-			// Looks like there is no user-defined save-handler function.
-			// That's fine, it just means the datastore is acting as a "mock-write"
-			// store -- changes get saved in memory but don't get saved to disk.
-			saveCompleteCallback();
-		}
-	},
-	
-	revert: function(){
-		// summary: See dojo.data.api.Write.revert()
-		this._assert(!this._saveInProgress);
-
-		var identity;
-		for(identity in this._pending._modifiedItems){
-			// find the original item and the modified item that replaced it
-			var copyOfItemState = this._pending._modifiedItems[identity];
-			var modifiedItem = null;
-			if(this._itemsByIdentity){
-				modifiedItem = this._itemsByIdentity[identity];
-			}else{
-				modifiedItem = this._arrayOfAllItems[identity];
-			}
-	
-			// Restore the original item into a full-fledged item again, we want to try to
-			// keep the same object instance as if we don't it, causes bugs like #9022.
-			copyOfItemState[this._storeRefPropName] = this;
-			for(key in modifiedItem){
-				delete modifiedItem[key];
-			}
-			lang.mixin(modifiedItem, copyOfItemState);
-		}
-		var deletedItem;
-		for(identity in this._pending._deletedItems){
-			deletedItem = this._pending._deletedItems[identity];
-			deletedItem[this._storeRefPropName] = this;
-			var index = deletedItem[this._itemNumPropName];
-
-			//Restore the reverse refererence map, if any.
-			if(deletedItem["backup_" + this._reverseRefMap]){
-				deletedItem[this._reverseRefMap] = deletedItem["backup_" + this._reverseRefMap];
-				delete deletedItem["backup_" + this._reverseRefMap];
-			}
-			this._arrayOfAllItems[index] = deletedItem;
-			if(this._itemsByIdentity){
-				this._itemsByIdentity[identity] = deletedItem;
-			}
-			if(deletedItem[this._rootItemPropName]){
-				this._arrayOfTopLevelItems.push(deletedItem);
-			}
-		}
-		//We have to pass through it again and restore the reference maps after all the
-		//undeletes have occurred.
-		for(identity in this._pending._deletedItems){
-			deletedItem = this._pending._deletedItems[identity];
-			if(deletedItem["backupRefs_" + this._reverseRefMap]){
-				arrayUtil.forEach(deletedItem["backupRefs_" + this._reverseRefMap], function(reference){
-					var refItem;
-					if(this._itemsByIdentity){
-						refItem = this._itemsByIdentity[reference.id];
-					}else{
-						refItem = this._arrayOfAllItems[reference.id];
-					}
-					this._addReferenceToMap(refItem, deletedItem, reference.attr);
-				}, this);
-				delete deletedItem["backupRefs_" + this._reverseRefMap];
-			}
-		}
-		
-		for(identity in this._pending._newItems){
-			var newItem = this._pending._newItems[identity];
-			newItem[this._storeRefPropName] = null;
-			// null out the new item, but don't change the array index so
-			// so we can keep using _arrayOfAllItems.length.
-			this._arrayOfAllItems[newItem[this._itemNumPropName]] = null;
-			if(newItem[this._rootItemPropName]){
-				this._removeArrayElement(this._arrayOfTopLevelItems, newItem);
-			}
-			if(this._itemsByIdentity){
-				delete this._itemsByIdentity[identity];
-			}
-		}
-
-		this._pending = {
-			_newItems:{},
-			_modifiedItems:{},
-			_deletedItems:{}
-		};
-		return true; // boolean
-	},
-	
-	isDirty: function(/* item? */ item){
-		// summary: See dojo.data.api.Write.isDirty()
-		if(item){
-			// return true if the item is dirty
-			var identity = this.getIdentity(item);
-			return new Boolean(this._pending._newItems[identity] ||
-				this._pending._modifiedItems[identity] ||
-				this._pending._deletedItems[identity]).valueOf(); // boolean
-		}else{
-			// return true if the store is dirty -- which means return true
-			// if there are any new items, dirty items, or modified items
-			if(!this._isEmpty(this._pending._newItems) ||
-				!this._isEmpty(this._pending._modifiedItems) ||
-				!this._isEmpty(this._pending._deletedItems)){
-				return true;
-			}
-			return false; // boolean
-		}
-	},
-
-/* dojo.data.api.Notification */
-
-	onSet: function(/* item */ item,
-					/*attribute-name-string*/ attribute,
-					/*object | array*/ oldValue,
-					/*object | array*/ newValue){
-		// summary: See dojo.data.api.Notification.onSet()
-		
-		// No need to do anything. This method is here just so that the
-		// client code can connect observers to it.
-	},
-
-	onNew: function(/* item */ newItem, /*object?*/ parentInfo){
-		// summary: See dojo.data.api.Notification.onNew()
-		
-		// No need to do anything. This method is here just so that the
-		// client code can connect observers to it.
-	},
-
-	onDelete: function(/* item */ deletedItem){
-		// summary: See dojo.data.api.Notification.onDelete()
-		
-		// No need to do anything. This method is here just so that the
-		// client code can connect observers to it.
-	},
-
-	close: function(/* object? */ request){
-		// summary:
-		//		Over-ride of base close function of ItemFileReadStore to add in check for store state.
-		// description:
-		//		Over-ride of base close function of ItemFileReadStore to add in check for store state.
-		//		If the store is still dirty (unsaved changes), then an error will be thrown instead of
-		//		clearing the internal state for reload from the url.
-
-		//Clear if not dirty ... or throw an error
-		if(this.clearOnClose){
-			if(!this.isDirty()){
-				this.inherited(arguments);
-			}else{
-				//Only throw an error if the store was dirty and we were loading from a url (cannot reload from url until state is saved).
-				throw new Error("dojox.data.AndOrWriteStore: There are unsaved changes present in the store.  Please save or revert the changes before invoking close.");
-			}
-		}
-	}
-});
+return declare("dojox.data.AndOrWriteStore", [ItemFileWriteStore, AndOrReadStore], {});
 
 });
diff --git a/dojox/data/AppStore.js b/dojox/data/AppStore.js
index 91b8d3d..2ef5cc1 100644
--- a/dojox/data/AppStore.js
+++ b/dojox/data/AppStore.js
@@ -2,8 +2,7 @@ define(["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter",
 
 dojo.experimental("dojox.data.AppStore");
 
-dojo.declare("dojox.data.AppStore",
-	null,{
+var AppStore = dojo.declare("dojox.data.AppStore", null, {
 
 	// url: [public] string
 	//		So the parser can instantiate the store via markup.
@@ -32,11 +31,11 @@ dojo.declare("dojox.data.AppStore",
 		// description:
 		//		The APP Store is instantiated either in markup or programmatically by supplying a
 		//		url of the Collection to be used.
-		//
 		// args:
 		//		An anonymous object to initialize properties.  It expects the following values:
-		//		url:		The url of the Collection to load.
-		//		urlPreventCache:	Whether or not to append on cache prevention params (as defined by dojo.xhr*)
+		//
+		//		- url:				The url of the Collection to load.
+		//		- urlPreventCache:	Whether or not to append on cache prevention params (as defined by dojo.xhr*)
 		
 		if(args && args.url){
 			this.url = args.url;
@@ -57,7 +56,6 @@ dojo.declare("dojox.data.AppStore",
 		//		a property to the entries to track that they belong to this store. It
 		//		also parses stored requests (since we were waiting on a callback) and
 		//		executes those as well.
-		//
 		// feed: dojox.atom.io.model.Feed object
 		//		The Feed to use for this data store.
 		// data: unused
@@ -89,7 +87,6 @@ dojo.declare("dojox.data.AppStore",
 		//		Function to return all entries in the Feed as an array of items.
 		// description:
 		//		Function to return all entries in the Feed as an array of items.
-		//
 		// returns:
 		//		Array of all entries in the feed.
 		var items = [];
@@ -105,7 +102,6 @@ dojo.declare("dojox.data.AppStore",
 		// description:
 		//		This function tests whether the item passed in is indeed an item
 		//		in the store.
-		//
 		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
@@ -124,7 +120,6 @@ dojo.declare("dojox.data.AppStore",
 		//		'attribute' like type for the store.
 		// attribute:
 		//		The attribute to test for being contained by the store.
-		//
 		// returns:
 		//		Returns a boolean indicating whether this is a valid attribute.
 		if(typeof attribute !== "string"){
@@ -145,7 +140,6 @@ dojo.declare("dojox.data.AppStore",
 		//		Internal function to add an updated entry to our updates array
 		// description:
 		//		Internal function to add an updated entry to our updates array
-		//
 		// update: dojox.atom.io.model.Entry object
 		//		The updated Entry we've changed.
 		if(!this._updates){
@@ -156,22 +150,22 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 /***************************************
-     dojo.data.api.Read API
+     dojo/data/api/Read API
 ***************************************/
 	
 	getValue: function(	/* item */ item,
 						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
 		// summary:
-		//      See dojo.data.api.Read.getValue()
+		//		See dojo/data/api/Read.getValue()
 		var values = this.getValues(item, attribute);
-		return (values.length > 0)?values[0]:defaultValue; //Object || int || Boolean
+		return (values.length > 0)?values[0]:defaultValue; // Object|Number|Boolean
 	},
 
 	getValues: function(/* item */ item,
 						/* attribute-name-string */ attribute){
 		// summary:
-		//		See dojo.data.api.Read.getValues()
+		//		See dojo/data/api/Read.getValues()
 
 		this._assertIsItem(item);
 		var flag = this._assertIsAttribute(attribute);
@@ -196,7 +190,7 @@ dojo.declare("dojox.data.AppStore",
 
 	getAttributes: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Read.getAttributes()
+		//		See dojo/data/api/Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
 		for(var key in dojox.atom.io.model._actions){
@@ -210,7 +204,7 @@ dojo.declare("dojox.data.AppStore",
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
 		// summary:
-		//		See dojo.data.api.Read.hasAttribute()
+		//		See dojo/data/api/Read.hasAttribute()
 		return this.getValues(item, attribute).length > 0;
 	},
 
@@ -218,7 +212,7 @@ dojo.declare("dojox.data.AppStore",
 							/* attribute-name-string */ attribute,
 							/* anything */ value){
 		// summary:
-		//		See dojo.data.api.Read.containsValue()
+		//		See dojo/data/api/Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
 			regexp = dojo.data.util.filter.patternToRegExp(value, false);
@@ -237,7 +231,6 @@ dojo.declare("dojox.data.AppStore",
 		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//
 		// item:
 		//		The data item to examine for attribute values.
 		// attribute:
@@ -269,19 +262,19 @@ dojo.declare("dojox.data.AppStore",
 
 	isItem: function(/* anything */ something){
 		// summary:
-		//		See dojo.data.api.Read.isItem()
+		//		See dojo/data/api/Read.isItem()
 		return something && something.store && something.store === this; //boolean
 	},
 
 	isItemLoaded: function(/* anything */ something){
 		// summary:
-		//		See dojo.data.api.Read.isItemLoaded()
+		//		See dojo/data/api/Read.isItemLoaded()
 		return this.isItem(something);
 	},
 
 	loadItem: function(/* Object */ keywordArgs){
 		// summary:
-		//		See dojo.data.api.Read.loadItem()
+		//		See dojo/data/api/Read.loadItem()
 		this._assertIsItem(keywordArgs.item);
 	},
 	
@@ -318,7 +311,6 @@ dojo.declare("dojox.data.AppStore",
 		// description:
 		//		Internal function for finishing a fetch request.  Needed since the feed
 		//		might not have been loaded, so we finish the fetch in a callback.
-		//
 		// request:
 		//		A request object
 		// fetchHandler:
@@ -372,7 +364,7 @@ dojo.declare("dojox.data.AppStore",
 
 	getFeatures: function(){
 		// summary:
-		//		See dojo.data.api.Read.getFeatures()
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true,
 			'dojo.data.api.Write': true,
@@ -380,16 +372,17 @@ dojo.declare("dojox.data.AppStore",
 		};
 	},
 	
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
+	close: function(/*dojo/data/api/Request|Object?*/ request){
 		// summary:
-		//		See dojo.data.api.Read.close()
+		//		See dojo/data/api/Read.close()
+		
 		// nothing to do here!
 		this._feed = null;
 	},
 
 	getLabel: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Read.getLabel()
+		//		See dojo/data/api/Read.getLabel()
 		if(this.isItem(item)){
 			return this.getValue(item, "title", "No Title");
 		}
@@ -398,30 +391,30 @@ dojo.declare("dojox.data.AppStore",
 
 	getLabelAttributes: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return ["title"];
 	},
 
 /***************************************
-     dojo.data.api.Identity API
+     dojo/data/api/Identity API
 ***************************************/
 
 	getIdentity: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Identity.getIdentity()
+		//		See dojo/data/api/Identity.getIdentity()
 		this._assertIsItem(item);
 		return this.getValue(item, "id");
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		 //	summary:
-		 //		See dojo.data.api.Identity.getIdentityAttributes()
-		 return ["id"];
+		// summary:
+		//		See dojo/data/api/Identity.getIdentityAttributes()
+		return ["id"];
 	},
 
 	fetchItemByIdentity: function(keywordArgs){
 		// summary:
-		//		See dojo.data.api.Identity.fetchItemByIdentity()
+		//		See dojo/data/api/Identity.fetchItemByIdentity()
 
 		this._fetchItems({query:{id:keywordArgs.identity}, onItem: keywordArgs.onItem, scope: keywordArgs.scope},
 			function(items, request){
@@ -438,12 +431,12 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 /***************************************
-     dojo.data.api.Identity API
+     dojo/data/api/Identity API
 ***************************************/
 
 	newItem: function(/* Object? */ keywordArgs){
 		// summary:
-		//		See dojo.data.api.Write.newItem()
+		//		See dojo/data/api/Write.newItem()
 		var entry = new dojox.atom.io.model.Entry();
 		var value = null;
 		var temp = null;
@@ -527,7 +520,7 @@ dojo.declare("dojox.data.AppStore",
 
 	deleteItem: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Write.deleteItem()
+		//		See dojo/data/api/Write.deleteItem()
 		this._assertIsItem(item);
 
 		if(!this._deletes){
@@ -555,7 +548,7 @@ dojo.declare("dojox.data.AppStore",
 						/* string */ attribute,
 						/* almost anything */ value){
 		// summary:
-		//		See dojo.data.api.Write.setValue()
+		//		See dojo/data/api/Write.setValue()
 		this._assertIsItem(item);
 		
 		var update = {item: item};
@@ -633,7 +626,7 @@ dojo.declare("dojox.data.AppStore",
 						/* string */ attribute,
 						/* array */ values){
 		// summary:
-		//		See dojo.data.api.Write.setValues()
+		//		See dojo/data/api/Write.setValues()
 		if(values.length === 0){
 			return this.unsetAttribute(item, attribute);
 		}
@@ -720,7 +713,7 @@ dojo.declare("dojox.data.AppStore",
 	unsetAttribute: function(	/* item */ item,
 								/* string */ attribute){
 		// summary:
-		//		See dojo.data.api.Write.unsetAttribute()
+		//		See dojo/data/api/Write.unsetAttribute()
 		this._assertIsItem(item);
 		if(this._assertIsAttribute(attribute)){
 			if(item[attribute] !== null){
@@ -749,13 +742,13 @@ dojo.declare("dojox.data.AppStore",
 
 	save: function(/* object */ keywordArgs){
 		// summary:
-		//		See dojo.data.api.Write.save()
+		//		See dojo/data/api/Write.save()
 		// keywordArgs:
-		//		{
-		//			onComplete: function
-		//			onError: function
-		//			scope: object
-		//		}
+		// |	{
+		// |		onComplete: function
+		// |		onError: function
+		// |		scope: object
+		// |	}
 		var i;
 		for(i in this._adds){
 			this._atomIO.addEntry(this._adds[i], null, function(){}, keywordArgs.onError, false, keywordArgs.scope);
@@ -785,7 +778,7 @@ dojo.declare("dojox.data.AppStore",
 
 	revert: function(){
 		// summary:
-		//		See dojo.data.api.Write.revert()
+		//		See dojo/data/api/Write.revert()
 		var i;
 		for(i in this._adds){
 			this._feed.removeEntry(this._adds[i]);
@@ -814,7 +807,7 @@ dojo.declare("dojox.data.AppStore",
 
 	isDirty: function(/* item? */ item){
 		// summary:
-		//		See dojo.data.api.Write.isDirty()
+		//		See dojo/data/api/Write.isDirty()
 		if(item){
 			this._assertIsItem(item);
 			return item.isDirty?true:false; //boolean
@@ -822,7 +815,8 @@ dojo.declare("dojox.data.AppStore",
 		return (this._adds !== null || this._updates !== null); //boolean
 	}
 });
-dojo.extend(dojox.data.AppStore,dojo.data.util.simpleFetch);
 
-return dojox.data.AppStore;
+dojo.extend(AppStore, dojo.data.util.simpleFetch);
+
+return AppStore;
 });
diff --git a/dojox/data/AtomReadStore.js b/dojox/data/AtomReadStore.js
index 4a8f85d..644ba04 100644
--- a/dojox/data/AtomReadStore.js
+++ b/dojox/data/AtomReadStore.js
@@ -1,21 +1,22 @@
 define(["dojo", "dojox", "dojo/data/util/filter", "dojo/data/util/simpleFetch", "dojo/date/stamp"], function(dojo, dojox) {
 dojo.experimental("dojox.data.AtomReadStore");
 
-dojo.declare("dojox.data.AtomReadStore", null, {
-	//	summary:
+var AtomReadStore = dojo.declare("dojox.data.AtomReadStore", null, {
+	// summary:
 	//		A read only data store for Atom XML based services or documents
-	//	description:
+	// description:
 	//		A data store for Atom XML based services or documents.	This store is still under development
 	//		and doesn't support wildcard filtering yet.	Attribute filtering is limited to category or id.
 
 	constructor: function(/* object */ args){
-		//	summary:
+		// summary:
 		//		Constructor for the AtomRead store.
-		//	args:
+		// args:
 		//		An anonymous object to initialize properties.	It expects the following values:
-		//		url:			The url to a service or an XML document that represents the store
-		//		unescapeHTML:	A boolean to specify whether or not to unescape HTML text
-		//		sendQuery:		A boolean indicate to add a query string to the service URL
+		//
+		//		- url:			The url to a service or an XML document that represents the store
+		//		- unescapeHTML:	A boolean to specify whether or not to unescape HTML text
+		//		- sendQuery:	A boolean indicate to add a query string to the service URL
 
 		if(args){
 			this.url = args.url;
@@ -43,25 +44,26 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 
 	unescapeHTML: false,
 
-	//Configurable preventCache option for the URL.
+	// urlPreventCache: Boolean
+	//		Configurable preventCache option for the URL.
 	urlPreventCache: false,
 
-	/* dojo.data.api.Read */
+	/* dojo/data/api/Read */
 
-	getValue: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* value? */ defaultValue){
-		//	summary:
+	getValue: function(/*dojo/data/api/Item*/ item, /*attribute|attribute-name-string*/ attribute, /*anything?*/ defaultValue){
+		// summary:
 		//		Return an attribute value
-		//	description:
+		// description:
 		//		'item' must be an instance of an object created by the AtomReadStore instance.
 		//		Accepted attributes are id, subtitle, title, summary, content, author, updated,
 		//		published, category, link and alternate
-		//	item:
+		// item:
 		//		An item returned by a call to the 'fetch' method.
-		//	attribute:
+		// attribute:
 		//		A attribute of the Atom Entry
-		//	defaultValue:
+		// defaultValue:
 		//		A default value
-		//	returns:
+		// returns:
 		//		An attribute value found, otherwise 'defaultValue'
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -94,18 +96,18 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 		return retVal ? dojo.isArray(retVal) ? retVal[0]: retVal : defaultValue;
 	},
 
-	getValues: function(/* item */ item, /* attribute || attribute-name-string */ attribute){
-		//	summary:
+	getValues: function(/*dojo/data/api/Item*/ item, /*attribute|attribute-name-string*/ attribute){
+		// summary:
 		//		Return an attribute value
-		//	description:
+		// description:
 		//		'item' must be an instance of an object created by the AtomReadStore instance.
 		//		Accepted attributes are id, subtitle, title, summary, content, author, updated,
 		//		published, category, link and alternate
-		//	item:
+		// item:
 		//		An item returned by a call to the 'fetch' method.
-		//	attribute:
+		// attribute:
 		//		A attribute of the Atom Entry
-		//	returns:
+		// returns:
 		//		An array of values for the attribute value found, otherwise 'defaultValue'
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -119,10 +121,10 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 		return retVal ? ((retVal.length !== undefined && typeof(retVal) !== "string") ? retVal : [retVal]) : undefined;
 	},
 
-	getAttributes: function(/* item */ item){
-		//	summary:
+	getAttributes: function(/*dojo/data/api/Item*/ item){
+		// summary:
 		//		Return an array of attribute names
-		// 	description:
+		// description:
 		//		'item' must be have been created by the AtomReadStore instance.
 		//		tag names of child elements and XML attribute names of attributes
 		//		specified to the element are returned along with special attribute
@@ -130,9 +132,9 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 		//		if the element has child elements, "text()" if the element has
 		//		child text nodes, and attribute names in '_attributeMap' that match
 		//		the tag name of the element.
-		//	item:
+		// item:
 		//		An XML element
-		//	returns:
+		// returns:
 		//		An array of attributes found
 		this._assertIsItem(item);
 		if(!item._attribs){
@@ -146,27 +148,27 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 		return attrNames; //array
 	},
 
-	hasAttribute: function(/* item */ item, /* attribute || attribute-name-string */ attribute){
-		//	summary:
+	hasAttribute: function(/*dojo/data/api/Item*/ item, /*attribute|attribute-name-string*/ attribute){
+		// summary:
 		//		Check whether an element has the attribute
-		//	item:
+		// item:
 		//		'item' must be created by the AtomReadStore instance.
-		//	attribute:
+		// attribute:
 		//		An attribute of an Atom Entry item.
-		//	returns:
+		// returns:
 		//		True if the element has the attribute, otherwise false
 		return (this.getValue(item, attribute) !== undefined); //boolean
 	},
 
-	containsValue: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* anything */ value){
-		//	summary:
+	containsValue: function(/*dojo/data/api/Item*/ item, /*attribute|attribute-name-string*/ attribute, /* anything */ value){
+		// summary:
 		//		Check whether the attribute values contain the value
-		//	item:
+		// item:
 		//		'item' must be an instance of a dojox.data.XmlItem from the store instance.
-		//	attribute:
+		// attribute:
 		//		A tag name of a child element, An XML attribute name or one of
 		//		special names
-		//	returns:
+		// returns:
 		//		True if the attribute values contain the value, otherwise false
 		var values = this.getValues(item, attribute);
 		for(var i = 0; i < values.length; i++){
@@ -182,11 +184,11 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary:
+		// summary:
 		//		Check whether the object is an item (XML element)
-		//	item:
+		// item:
 		//		An object to check
-		// 	returns:
+		// returns:
 		//		True if the object is an XML element, otherwise false
 		if(something && something.element && something.store && something.store === this){
 			return true; //boolean
@@ -195,26 +197,26 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary:
+		// summary:
 		//		Check whether the object is an item (XML element) and loaded
-		//	item:
+		// item:
 		//		An object to check
-		//	returns:
+		// returns:
 		//		True if the object is an XML element, otherwise false
 		return this.isItem(something); //boolean
 	},
 
 	loadItem: function(/* object */ keywordArgs){
-		//	summary:
+		// summary:
 		//		Load an item (XML element)
-		//	keywordArgs:
-		//		object containing the args for loadItem.	See dojo.data.api.Read.loadItem()
+		// keywordArgs:
+		//		object containing the args for loadItem.	See dojo/data/api/Read.loadItem()
 	},
 
 	getFeatures: function(){
-		//	summary:
+		// summary:
 		//		Return supported data APIs
-		//	returns:
+		// returns:
 		//		"dojo.data.api.Read" and "dojo.data.api.Write"
 		var features = {
 			"dojo.data.api.Read": true
@@ -222,9 +224,9 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 		return features; //array
 	},
 
-	getLabel: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
+	getLabel: function(/*dojo/data/api/Item*/ item){
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		if((this.label !== "") && this.isItem(item)){
 			var label = this.getValue(item,this.label);
 			if(label && label.text){
@@ -238,9 +240,9 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 		return undefined; //undefined
 	},
 
-	getLabelAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+	getLabelAttributes: function(/*dojo/data/api/Item*/ item){
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		if(this.label !== ""){
 			return [this.label]; //array
 		}
@@ -414,9 +416,9 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 		return items;
 	},
 
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		 //	summary:
-		 //		See dojo.data.api.Read.close()
+	close: function(/*dojo/data/api/Request|Object?*/ request){
+		// summary:
+		//		See dojo/data/api/Read.close()
 	},
 
 /* internal API */
@@ -524,10 +526,10 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 		return text;
 	},
 
-	_assertIsItem: function(/* item */ item){
-		//	summary:
+	_assertIsItem: function(/*dojo/data/api/Item*/ item){
+		// summary:
 		//		This function tests whether the item passed in is indeed an item in the store.
-		//	item:
+		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
 			throw new Error("dojox.data.AtomReadStore: Invalid item argument.");
@@ -535,16 +537,17 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 	},
 
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
-		//	summary:
+		// summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+		// attribute:
 		//		The attribute to test for being contained by the store.
 		if(typeof attribute !== "string"){
 			throw new Error("dojox.data.AtomReadStore: Invalid attribute argument.");
 		}
 	}
 });
-dojo.extend(dojox.data.AtomReadStore,dojo.data.util.simpleFetch);
 
-return dojox.data.AtomReadStore;
+dojo.extend(AtomReadStore, dojo.data.util.simpleFetch);
+
+return AtomReadStore;
 });
diff --git a/dojox/data/CdfStore.js b/dojox/data/CdfStore.js
index 0d81a30..0b9be61 100755
--- a/dojox/data/CdfStore.js
+++ b/dojox/data/CdfStore.js
@@ -3,8 +3,8 @@ define(["dojo", "dojox", "dojo/data/util/sorter"], function(dojo, dojox) {
 dojox.data.ASYNC_MODE = 0;
 dojox.data.SYNC_MODE = 1;
 
-dojo.declare("dojox.data.CdfStore", null, {
-	//	summary:
+return dojo.declare("dojox.data.CdfStore", null, {
+	// summary:
 	//		IMPORTANT: The CDF Store is designed to work with Tibco GI, and references Tibco's
 	//		JSX3 JavaScript library and will not work without it.
 	//
@@ -17,39 +17,38 @@ dojo.declare("dojox.data.CdfStore", null, {
 	//
 	//		While a CDF document is an XML file, other than the initial input, all data returned
 	//		from and written to this store should be in object format.
-	//
+
 	// identity: [const] String
 	//		The unique identifier for each item. Defaults to "jsxid" which is standard for a CDF
 	//		document. Should not be changed.
 	identity: "jsxid",
-	//
-	//	url : String
+
+	// url : String
 	//		The location from which to fetch the XML (CDF) document.
 	url: "",
-	//
-	//	xmlStr: String
+
+	// xmlStr: String
 	//		A string that can be parsed into an XML document and should be formatted according
 	//		to the CDF spec.
-	//	example:
+	// example:
 	//		|	'<data jsxid="jsxroot"><record jsxtext="A"/><record jsxtext="B" jsxid="2" jsxid="2"/></data>'
 	xmlStr:"",
-	//
-	//	data:	Object
+
+	// data:	Object
 	//		A object that will be converted into the xmlStr property, and then parsed into a CDF.
 	data:null,
-	//
-	//	label:	String
+
+	// label:	String
 	//		The property within each item used to define the item.
 	label: "",
-	//
-	//	mode [const]: dojox.data.ASYNC_MODE | dojox.data.SYNC_MODE
-	//		This store supports syncronous fetches if this property is set to dojox.data.SYNC_MODE.
+
+	//	mode [const]: dojox.data.ASYNC_MODE|dojox.data.SYNC_MODE
+	//		This store supports synchronous fetches if this property is set to dojox.data.SYNC_MODE.
 	mode:dojox.data.ASYNC_MODE,
 	
 	constructor: function(/* Object */ args){
 		// summary:
 		//	Constructor for the CDF store. Instantiate a new CdfStore.
-		//
 		if(args){
 			this.url = args.url;
 			this.xmlStr = args.xmlStr || args.str;
@@ -65,36 +64,35 @@ dojo.declare("dojox.data.CdfStore", null, {
 		this.byId = this.fetchItemByIdentity;
 	},
 	
-	/* dojo.data.api.Read */
+	/* dojo/data/api/Read */
 
 	getValue: function(/* jsx3.xml.Entity */ item, /* String */ property, /* value? */ defaultValue){
-		//	summary:
+		// summary:
 		//		Return an property value of an item
-		//
+
 		return item.getAttribute(property) || defaultValue; // anything
 	},
 
 	getValues: function(/* jsx3.xml.Entity */ item, /* String */ property){
-		//	summary:
+		// summary:
 		//		Return an array of values
-		//
+
 		//	TODO!!! Can't find an example of an array in any CDF files
-		//
 		var v = this.getValue(item, property, []);
 		return dojo.isArray(v) ? v : [v];
 	},
 
 	getAttributes: function(/* jsx3.xml.Entity */ item){
-		//	summary:
+		// summary:
 		//		Return an array of property names
-		//
+
 		return item.getAttributeNames(); // Array
 	},
 
 	hasAttribute: function(/* jsx3.xml.Entity */ item, /* String */ property){
-		//	summary:
+		// summary:
 		//		Check whether an item has a property
-		//
+
 		return (this.getValue(item, property) !== undefined); // Boolean
 	},
 	
@@ -105,9 +103,9 @@ dojo.declare("dojox.data.CdfStore", null, {
 	},
 	
 	containsValue: function(/* jsx3.xml.Entity */ item, /* String */ property, /* anything */ value){
-		//	summary:
+		// summary:
 		//		Check whether an item contains a value
-		//
+
 		var values = this.getValues(item, property);
 		for(var i = 0; i < values.length; i++){
 			if(values[i] === null){ continue; }
@@ -123,9 +121,9 @@ dojo.declare("dojox.data.CdfStore", null, {
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary:
+		// summary:
 		//		Check whether the object is an item (jsx3.xml.Entity)
-		//
+
 		if(something.getClass && something.getClass().equals(jsx3.xml.Entity.jsxclass)){
 			return true; //boolean
 		}
@@ -133,23 +131,23 @@ dojo.declare("dojox.data.CdfStore", null, {
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary:
+		// summary:
 		//		Check whether the object is a jsx3.xml.Entity object and loaded
-		//
+
 		return this.isItem(something); // Boolean
 	},
 
 	loadItem: function(/* object */ keywordArgs){
-		//	summary:
+		// summary:
 		//		Load an item
-		//	description:
+		// description:
 		//		The store always loads all items, so if it's an item, then it's loaded.
 	},
 
 	getFeatures: function(){
-		//	summary:
+		// summary:
 		//		Return supported data APIs
-		//
+
 		return {
 			"dojo.data.api.Read": true,
 			"dojo.data.api.Write": true,
@@ -158,9 +156,9 @@ dojo.declare("dojox.data.CdfStore", null, {
 	},
 
 	getLabel: function(/* jsx3.xml.Entity */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
-		//
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
+
 		if((this.label !== "") && this.isItem(item)){
 			var label = this.getValue(item,this.label);
 			if(label){
@@ -171,11 +169,11 @@ dojo.declare("dojox.data.CdfStore", null, {
 	},
 
 	getLabelAttributes: function(/* jsx3.xml.Entity */ item){
-		//	summary:
+		// summary:
 		//		returns an array of what properties of the item that were used
-		//      to generate its label
-		//		See dojo.data.api.Read.getLabelAttributes()
-		//
+		//		to generate its label
+		//		See dojo/data/api/Read.getLabelAttributes()
+
 		if(this.label !== ""){
 			return [this.label]; //array
 		}
@@ -191,51 +189,59 @@ dojo.declare("dojox.data.CdfStore", null, {
 		//		If the store is in ASYNC mode, the items should be expected in an onComplete
 		//		method passed in the request object. If store is in SYNC mode, the items will
 		//		be return directly as well as within the onComplete method.
-		//	note:
+		//
+		//		note:
 		//		The mode can be set on store initialization or during a fetch as one of the
 		//		parameters.
 		//
-		//	query: String
+		//		See:
+		//
+		//		- http://www.tibco.com/devnet/resources/gi/3_7/api/html/jsx3/xml/Entity.html#method:selectNodes
+		//		- http://www.w3.org/TR/xpath
+		//		- http://msdn.microsoft.com/en-us/library/ms256086.aspx
+		//
+		//		See dojo.data.Read.fetch():
+		//
+		//		- onBegin
+		//		- onComplete
+		//		- onItem
+		//		- onError
+		//		- scope
+		//		- start
+		//		- count
+		//		- sort
+		// request: String
 		//		The items in the store are treated as objects, but this is reading an XML
 		//		document. Further, the actual querying of the items takes place in Tibco GI's
 		//		jsx3.xml.Entity. Therefore, we are using their syntax which is xpath.
-		//	Note:
+		//
+		//		Note:
 		//		As conforming to a CDF document, most, if not all nodes are considered "records"
 		//		and their tagNames are as such. The root node is named "data".
-		//
-		//	examples:
+		// example:
 		//		All items:
 		//		|	store.fetch({query:"*"});
+		// example:
 		//		Item with a jsxid attribute equal to "1" (note you could use byId for this)
 		//		|	store.fetch({query:"//record[@jsxid='1']"});
+		// example:
 		//		All items with any jsxid attribute:
 		//		|	"//record[@jsxid='*']"
+		// example:
 		//		The items with a jsxid of '1' or '4':
 		//		|	"//record[@jsxid='4' or @jsxid='1']"
+		// example:
 		//		All children within a "group" node (could be multiple group nodes):
 		//		"//group/record"
+		// example:
 		//		All children within a specific group node:
 		//		"//group[@name='mySecondGroup']/record"
+		// example:
 		//		Any record, anywhere in the document:
 		//		|	"//record"
 		//		Only the records beneath the root (data) node:
 		//		|	"//data/record"
-		//
-		//	See:
-		//	http://www.tibco.com/devnet/resources/gi/3_7/api/html/jsx3/xml/Entity.html#method:selectNodes
-		//	http://www.w3.org/TR/xpath
-		//	http://msdn.microsoft.com/en-us/library/ms256086.aspx
-		//
-		//	See dojo.data.Read.fetch():
-		//	onBegin
-		//	onComplete
-		//	onItem
-		//	onError
-		//	scope
-		//	start
-		//	count
-		//	sort
-		//
+
 		request = request || {};
 		if(!request.store){
 			request.store = this;
@@ -354,7 +360,7 @@ dojo.declare("dojox.data.CdfStore", null, {
 
 	
 	_loadCDF: function(){
-		//	summary:
+		// summary:
 		//		Internal method.
 		//		If a cdfDoc exists, return it. Otherwise, get one from JSX3,
 		//		load the data or url, and return the doc or a deferred.
@@ -399,7 +405,7 @@ dojo.declare("dojox.data.CdfStore", null, {
 		// summary:
 		//		Internal method.
 		//		Requests the items from jsx3.xml.Entity with an xpath query.
-		//
+
 		var itr = cdfDoc.selectNodes(request.query, false, 1);
 		var items = [];
 		while(itr.hasNext()){
@@ -408,18 +414,18 @@ dojo.declare("dojox.data.CdfStore", null, {
 		return items;
 	},
 
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		 //	summary:
-		 //		See dojo.data.api.Read.close()
+	close: function(/*dojo/data/api/Request|Object?*/ request){
+		// summary:
+		//		See dojo/data/api/Read.close()
 	},
 
-/* dojo.data.api.Write */
+/* dojo/data/api/Write */
 
-	newItem: function(/* object? */ keywordArgs, /* object? || String? */parentInfo){
-		//	summary:
+	newItem: function(/* object? */ keywordArgs, /* Object|String? */ parentInfo){
+		// summary:
 		//		Creates a jsx3.xml.Entity item and inserts it either inside the
 		//		parent or appends it to the root
-		//
+
 		keywordArgs = (keywordArgs || {});
 		if(keywordArgs.tagName){
 			// record tagName is automatic and this would add it
@@ -442,28 +448,29 @@ dojo.declare("dojox.data.CdfStore", null, {
 	},
 	
 	deleteItem: function(/* jsx3.xml.Entity */ item){
-		//	summary:
+		// summary:
 		//		Delete an jsx3.xml.Entity (wrapper to a XML element).
-		//
+
 		this.cdfDoc.deleteRecord(this.getIdentity(item));
 		this._makeDirty(item);
 		return true; //boolean
 	},
 	
 	setValue: function(/* jsx3.xml.Entity */ item, /* String */ property, /* almost anything */ value){
-		//	summary:
+		// summary:
 		//		Set an property value
-		//
+
 		this._makeDirty(item);
 		item.setAttribute(property, value);
 		return true; // Boolean
 	},
 		
 	setValues: function(/* jsx3.xml.Entity */ item, /* String */ property, /*array*/ values){
-		//	summary:
-		//		Set property values
+		// summary:
+		//		Set property values.
+
 		//		TODO: Needs to be fully implemented.
-		//
+
 		this._makeDirty(item);
 		console.warn("cdfStore.setValues only partially implemented.");
 		return item.setAttribute(property, values);
@@ -471,9 +478,9 @@ dojo.declare("dojox.data.CdfStore", null, {
 	},
 	
 	unsetAttribute: function(/* jsx3.xml.Entity */ item, /* String */ property){
-		//	summary:
+		// summary:
 		//		Remove an property
-		//
+
 		this._makeDirty(item);
 		item.removeAttribute(property);
 		return true; // Boolean
@@ -484,19 +491,20 @@ dojo.declare("dojox.data.CdfStore", null, {
 		//		Invalidate changes (new and/or modified elements)
 		//		Resets data by simply deleting the reference to the cdfDoc.
 		//		Subsequent fetches will load the new data.
-		// Note:
-		//		Any items outside the store will no longer be valid and may cause errors.
 		//
+		//		Note:
+		//		Any items outside the store will no longer be valid and may cause errors.
+
 		delete this.cdfDoc;
 		this._modifiedItems = {};
 		return true; //boolean
 	},
 	
 	isDirty: function(/* jsx3.xml.Entity ? */ item){
-		//	summary:
+		// summary:
 		//		Check whether an item is new, modified or deleted.
 		//		If no item is passed, checks if anything in the store has changed.
-		//
+
 		if(item){
 			return !!this._modifiedItems[this.getIdentity(item)]; // Boolean
 		}else{
@@ -523,7 +531,7 @@ dojo.declare("dojox.data.CdfStore", null, {
 		// summary:
 		//		Internal method.
 		//		Converts an object into an XML string.
-		//
+
 		var parseObj = function(obj, name){
 			var xmlStr = "";
 			var nm;
@@ -555,25 +563,25 @@ dojo.declare("dojox.data.CdfStore", null, {
 	 * Dojo.data Identity implementation *
 	 *************************************/
 	getIdentity: function(/* jsx3.xml.Entity */ item){
-		//	summary:
+		// summary:
 		//		Returns the identifier for an item.
-		//
+
 		return this.getValue(item, this.identity); // String
 	},
 
 	getIdentityAttributes: function(/* jsx3.xml.Entity */ item){
-		//	summary:
+		// summary:
 		//		Returns the property used for the identity.
-		//
+
 		return [this.identity]; // Array
 	},
 
 
-	fetchItemByIdentity: function(/* Object || String */ args){
-		//	summary:
-		//		See dojo.data.api.Identity.fetchItemByIdentity(keywordArgs)
+	fetchItemByIdentity: function(/* Object|String */ args){
+		// summary:
+		//		See dojo/data/api/Identity.fetchItemByIdentity(keywordArgs).
 		//
-		//	Note:
+		//		Note:
 		//		This method can be synchronous if mode is set.
 		//		Also, there is a more finger friendly alias of this method, byId();
 		if(dojo.isString(args)){
@@ -586,14 +594,12 @@ dojo.declare("dojox.data.CdfStore", null, {
 			if(!args.mode){args.mode = this.mode;}
 		}
 		args.byId = true;
-		return this.fetch(args); // dojo.Deferred || Array
+		return this.fetch(args); // dojo/_base/Deferred|Array
 	},
-	byId: function(/* Object || String */ args){
+	byId: function(/* Object|String */ args){
 		// stub. See fetchItemByIdentity
 	}
-	
 });
 
-return dojox.data.CdfStore;
 });
 
diff --git a/dojox/data/ClientFilter.js b/dojox/data/ClientFilter.js
index 0412299..aaebebb 100644
--- a/dojox/data/ClientFilter.js
+++ b/dojox/data/ClientFilter.js
@@ -1,7 +1,7 @@
 define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/Deferred", "dojo/data/util/filter"], 
   function(declare, lang, array, Deferred, filter) {
 
-// This is an abstract data store module for adding updateable result set functionality to an existing data store class
+// This is an abstract data store module for adding updatable result set functionality to an existing data store class
 
 	var addUpdate = function(store,create,remove){
 		// create a handler that adds to the list of notifications
@@ -20,8 +20,7 @@ define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base
 				//		This is an abstract class that data stores can extend to add updateable result set functionality
 				//		as well as client side querying capabilities. This enables
 				//		widgets to be aware of how active results change in response to the modifications/notifications.
-				//
-				//	description:
+				// description:
 				//		To a update a result set after a notification (onNew, onSet, and onDelete),
 				//		widgets can call the updateResultSet method. Widgets can use the updated
 				//		result sets to determine how to react to notifications, and how to update their displayed results
@@ -33,10 +32,11 @@ define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base
 				//		results by itself in this case. In this situations, data stores can provide a isUpdateable(request) function
 				//		and matchesQuery(item,request) function. If a data store can handle a query, it can return true from
 				//		isUpdateable and if an item matches a query, it can return true from matchesQuery. Here is
-				//		definition of isUpdateable and matchesQuery
-				//		isUpdateable(request)  - request is the keywords arguments as is passed to the fetch function.
-				//		matchesQuery(item,request) - item is the item to test, and request is the value arguments object
-				//				for the fetch function.
+				//		definition of isUpdateable and matchesQuery:
+				//
+				//		- isUpdateable(request)  - request is the keywords arguments as is passed to the fetch function.
+				//		- matchesQuery(item,request) - item is the item to test, and request is the value arguments object
+				//		for the fetch function.
 				//
 				//		You can define a property on this object instance "cacheByDefault" to a value of true that will
 				//		cause all queries to be cached by default unless the cache queryOption is explicitly set to false.
@@ -44,7 +44,7 @@ define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base
 				//
 				// example:
 				//		to make a updated-result-set data store from an existing data store:
-				//	|	dojo.declare("dojox.data.MyLiveDataStore",
+				//	|	declare("dojox.data.MyLiveDataStore",
 				//	|		dojox.data.MyDataStore,dojox.data.ClientFilter], // subclass LiveResultSets if available
 				//	|		{}
 				//	|	);
@@ -55,24 +55,25 @@ define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base
 				this._fetchCache = [];
 			},
 			clearCache: function(){
-				//	summary:
+				// summary:
 				//		Clears the cache of client side queries
 				this._fetchCache = [];
 			},
 			updateResultSet: function(/*Array*/ resultSet, /*Object*/ request){
-				//	summary:
+				// summary:
 				//		Attempts to update the given result set based on previous notifications
-				//	resultSet:
+				// resultSet:
 				//		The result set array that should be updated
-				//	request:
-				//		This object follows the same meaning as the keywordArgs passed to a dojo.data.api.Read.fetch.
-				//	description:
-				// 		This will attempt to update the provide result based on previous notification, adding new items
-				// 		from onNew calls, removing deleted items, and updating modified items, and properly removing
-				//  	and adding items as required by the query and sort parameters. This function will return:
-				//		0: Indicates it could not successfully update the result set
-				//		1: Indicates it could successfully handle all the notifications, but no changes were made to the result set
-				//		2: Indicates it successfully handled all the notifications and result set has been updated.
+				// request:
+				//		This object follows the same meaning as the keywordArgs passed to a dojo/data/api/Read.fetch.
+				// description:
+				//		This will attempt to update the provide result based on previous notification, adding new items
+				//		from onNew calls, removing deleted items, and updating modified items, and properly removing
+				//		and adding items as required by the query and sort parameters.
+				// returns:
+				//		- 0: Indicates it could not successfully update the result set
+				//		- 1: Indicates it could successfully handle all the notifications, but no changes were made to the result set
+				//		- 2: Indicates it successfully handled all the notifications and result set has been updated.
 				if(this.isUpdateable(request)){
 					// we try to avoid rerunning notification updates more than once on the same object for performance
 					for(var i = request._version || 0; i < this._updates.length;i++){
@@ -109,7 +110,7 @@ define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base
 				return 0;
 			},
 			querySuperSet: function(argsSuper, argsSub){
-				//	summary:
+				// summary:
 				//		Determines whether the provided arguments are super/sub sets of each other
 				// argsSuper:
 				//		Dojo Data Fetch arguments
@@ -178,7 +179,7 @@ define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base
 						fetchCache.push(args);
 					}
 					defResult= args._loading = this._doQuery(args);
-					 
+
 					defResult.addErrback(function(){
 						fetchCache.splice(array.indexOf(fetchCache, args), 1);
 					});
@@ -201,21 +202,19 @@ define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base
 				return defResult;
 			},
 			isUpdateable: function(/*Object*/ request){
-				//	summary:
+				// summary:
 				//		Returns whether the provide fetch arguments can be used to update an existing list
-				//	request:
-				//		See dojo.data.api.Read.fetch request
+				// request:
+				//		See dojo/data/api/Read.fetch request
 				
-				return typeof request.query == "object";
+				return !request.query || typeof request.query == "object";
 			},
 			clientSideFetch: function(/*Object*/ request,/*Array*/ baseResults){
 				// summary:
 				//		Performs a query on the client side and returns the results as an array
-				//
-				//	request:
-				//		See dojo.data.api.Read.fetch request
-				//
-				//	baseResults:
+				// request:
+				//		See dojo/data/api/Read.fetch request
+				// baseResults:
 				//		This provides the result set to start with for client side querying
 				if(request.queryOptions && request.queryOptions.results){
 					baseResults = request.queryOptions.results;
@@ -260,9 +259,9 @@ define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base
 				return true;
 			},
 			makeComparator: function(sort){
-				//	summary:
+				// summary:
 				//		returns a comparator function for the given sort order array
-				//	sort:
+				// sort:
 				//		See dojox.data.api.Read.fetch
 				var current = sort.shift();
 				if(!current){
diff --git a/dojox/data/CouchDBRestStore.js b/dojox/data/CouchDBRestStore.js
index 39a91e7..8c0fd47 100644
--- a/dojox/data/CouchDBRestStore.js
+++ b/dojox/data/CouchDBRestStore.js
@@ -1,14 +1,14 @@
 define(["dojo", "dojox", "dojox/data/JsonRestStore"], function(dojo, dojox) {
 
-// A CouchDBRestStore is an extension of JsonRestStore to handle CouchDB's idiosyncrasies, special features,
-// and deviations from standard HTTP Rest.
-// NOTE: CouchDB is not designed to be run on a public facing network. There is no access control
-// on database documents, and you should NOT rely on client side control to implement security.
-
-
-dojo.declare("dojox.data.CouchDBRestStore",
+var CouchDBRestStore = dojo.declare("dojox.data.CouchDBRestStore",
 	dojox.data.JsonRestStore,
 	{
+	// summary:
+	//		A CouchDBRestStore is an extension of JsonRestStore to handle CouchDB's idiosyncrasies, special features,
+	//		and deviations from standard HTTP Rest.
+	//		NOTE: CouchDB is not designed to be run on a public facing network. There is no access control
+	//	 	on database documents, and you should NOT rely on client side control to implement security.
+
 		save: function(kwArgs){
 			var actions = this.inherited(arguments); // do the default save and then update for version numbers
 			var prefix = this.service.servicePath;
@@ -27,10 +27,10 @@ dojo.declare("dojox.data.CouchDBRestStore",
 		},
 		fetch: function(args){
 			// summary:
-			// 		This only differs from JsonRestStore in that it, will put the query string the query part of the URL and it handles start and count
+			//		This only differs from JsonRestStore in that it, will put the query string the query part of the URL and it handles start and count
 			args.query = args.query || '_all_docs?';
 			if(args.start){
-				args.query = (args.query ? (args.query + '&') : '') + 'startkey=' + args.start;
+				args.query = (args.query ? (args.query + '&') : '') + 'skip=' + args.start;
 				delete args.start;
 			}
 			if(args.count){
@@ -61,7 +61,7 @@ dojo.declare("dojox.data.CouchDBRestStore",
 );
 
 // create a set of stores
-dojox.data.CouchDBRestStore.getStores = function(couchServerUrl){
+CouchDBRestStore.getStores = function(couchServerUrl){
 	var dfd = dojo.xhrGet({
 		url: couchServerUrl+"_all_dbs",
 		handleAs: "json",
@@ -77,6 +77,6 @@ dojox.data.CouchDBRestStore.getStores = function(couchServerUrl){
 	return stores;
 };
 
-return dojox.data.CouchDBRestStore;
+return CouchDBRestStore;
 
 });
diff --git a/dojox/data/CssClassStore.js b/dojox/data/CssClassStore.js
index 86dc71d..9f07de2 100755
--- a/dojox/data/CssClassStore.js
+++ b/dojox/data/CssClassStore.js
@@ -1,24 +1,26 @@
 define(["dojo/_base/declare","dojox/data/CssRuleStore"], 
   function(declare, CssRuleStore) {
 
-/*===== var CssRuleStore = dojox.data.CssRuleStore =====*/
-
 return declare("dojox.data.CssClassStore", CssRuleStore, {
-	//	summary:
+	// summary:
 	//		Basic store to display CSS information.
-	//	description:
+	// description:
 	//		The CssClassStore allows users to get information about active Css classes in the page running the CssClassStore.
 	//		It can also filter out classes from specific stylesheets.  The attributes it exposes on classes are as follows:
-	//			class:		The classname, including the '.'.
-	//			classSans:	The classname without the '.'.
+	//
+	//		- class:		The classname, including the '.'.
+	//		- classSans:	The classname without the '.'.
 
-	_labelAttribute: 'class', // text representation of the Item [label and identifier may need to stay due to method names]
+	// _labelAttribute:
+	//		text representation of the Item [label and identifier may need to stay due to method names]
+	_labelAttribute: 'class',
+	
 	_idAttribute: 'class',
 	_cName: "dojox.data.CssClassStore",
 
 	getFeatures: function(){
-		//	summary:
-		//		See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			"dojo.data.api.Read" : true,
 			"dojo.data.api.Identity" : true
@@ -26,15 +28,15 @@ return declare("dojox.data.CssClassStore", CssRuleStore, {
 	},
 
 	getAttributes: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.getAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		this._assertIsItem(item);
 		return ['class', 'classSans'];
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary:
-		//		See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		var values = this.getValues(item, attribute);
 		if(values && values.length > 0){
 			return values[0];
@@ -43,8 +45,8 @@ return declare("dojox.data.CssClassStore", CssRuleStore, {
 	},
 
 	getValues: function(item, attribute){
-		//	summary:
-		//		See dojo.data.api.Read.getValues()
+		// summary:
+		//		See dojo/data/api/Read.getValues()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		var value = [];
@@ -57,7 +59,7 @@ return declare("dojox.data.CssClassStore", CssRuleStore, {
 	},
 
 	_handleRule: function(rule, styleSheet, href){
-		//	summary:
+		// summary:
 		//		Handles the creation of an item based on the passed rule.  In this store, this implies
 		//		parsing out all available class names.
 		var obj = {};
@@ -82,7 +84,7 @@ return declare("dojox.data.CssClassStore", CssRuleStore, {
 	},
 
 	_handleReturn: function(){
-		//	summary:
+		// summary:
 		//		Handles the return from a fetching action.  Delegates requests to act on the resulting
 		//		item set to eitehr the _handleFetchReturn or _handleFetchByIdentityReturn depending on
 		//		where the request originated.
@@ -111,7 +113,7 @@ return declare("dojox.data.CssClassStore", CssRuleStore, {
 	},
 
 	_handleFetchByIdentityReturn: function(request){
-		//	summary:
+		// summary:
 		//		Handles a fetchByIdentity request by finding the correct item.
 		var items = request._items;
 		// Per https://bugs.webkit.org/show_bug.cgi?id=17935 , Safari 3.x always returns the selectorText
@@ -128,22 +130,22 @@ return declare("dojox.data.CssClassStore", CssRuleStore, {
 
 	/* Identity API */
 	getIdentity: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Identity.getIdentity()
+		// summary:
+		//		See dojo/data/api/Identity.getIdentity()
 		this._assertIsItem(item);
 		return this.getValue(item, this._idAttribute);
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		 //	summary:
-		 //		See dojo.data.api.Identity.getIdentityAttributes()
+		// summary:
+		//		See dojo/data/api/Identity.getIdentityAttributes()
 		this._assertIsItem(item);
 		return [this._idAttribute];
 	},
 
 	fetchItemByIdentity: function(/* request */ request){
-		//	summary:
-		//		See dojo.data.api.Identity.fetchItemByIdentity()
+		// summary:
+		//		See dojo/data/api/Identity.fetchItemByIdentity()
 		request = request || {};
 		if(!request.store){
 			request.store = this;
diff --git a/dojox/data/CssRuleStore.js b/dojox/data/CssRuleStore.js
index 6d22e25..71e9412 100755
--- a/dojox/data/CssRuleStore.js
+++ b/dojox/data/CssRuleStore.js
@@ -1,20 +1,22 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base/json","dojo/_base/window", "dojo/_base/sniff", "dojo/data/util/sorter", "dojo/data/util/filter", "./css"],
- function(lang, declare, array, jsonUtil, winUtil, has, sorter, filter, css) {
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base/json","dojo/_base/kernel", "dojo/_base/sniff", "dojo/data/util/sorter", "dojo/data/util/filter", "./css"],
+ function(lang, declare, array, jsonUtil, kernel, has, sorter, filter, css) {
 
 return declare("dojox.data.CssRuleStore", null, {
-	//	summary:
+	// summary:
 	//		Basic store to display CSS information.
-	//	description:
+	// description:
 	//		The CssRuleStore allows users to get information about active CSS rules in the page running the CssRuleStore.
 	//		It can also filter out rules from specific stylesheets.  The attributes it exposes on rules are as follows:
-	//			selector:				The selector text.
-	//			classes:				An array of classes present in this selector.
-	//			rule:					The actual DOM Rule object.
-	//			style:					The actual DOM CSSStyleDeclaration object.
-	//			cssText:				The cssText string provided on the rule object.
-	//			styleSheet:				The originating DOM Stylesheet object.
-	//			parentStyleSheet: 		The parent stylesheet to the sheet this rule originates from.
-	//			parentStyleSheetHref: 	The href of the parent stylesheet.
+	//
+	//		- selector:				The selector text.
+	//		- classes:				An array of classes present in this selector.
+	//		- rule:					The actual DOM Rule object.
+	//		- style:					The actual DOM CSSStyleDeclaration object.
+	//		- cssText:				The cssText string provided on the rule object.
+	//		- styleSheet:				The originating DOM Stylesheet object.
+	//		- parentStyleSheet:		The parent stylesheet to the sheet this rule originates from.
+	//		- parentStyleSheetHref:	The href of the parent stylesheet.
+	//
 	//		AND every style attribute denoted as style.*, such as style.textAlign or style.backgroundColor
 
 	_storeRef: '_S',
@@ -69,16 +71,16 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	getFeatures: function(){
-		//	summary:
-		//		See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			"dojo.data.api.Read" : true
 		};
 	},
 
 	isItem: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.isItem()
+		// summary:
+		//		See dojo/data/api/Read.isItem()
 		if(item && item[this._storeRef] == this){
 			return true;
 		}
@@ -86,8 +88,8 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	hasAttribute: function(item, attribute){
-		//	summary:
-		//		See dojo.data.api.Read.hasAttribute()
+		// summary:
+		//		See dojo/data/api/Read.hasAttribute()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		var attrs = this.getAttributes(item);
@@ -98,8 +100,8 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	getAttributes: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.getAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		this._assertIsItem(item);
 		var attrs = ['selector', 'classes', 'rule', 'style', 'cssText', 'styleSheet', 'parentStyleSheet', 'parentStyleSheetHref'];
 		var style = item.rule.style;
@@ -113,8 +115,8 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary:
-		//		See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		var values = this.getValues(item, attribute);
 		var value = defaultValue;
 		if(values && values.length > 0){
@@ -124,8 +126,8 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	getValues: function(item, attribute){
-		//	summary:
-		//		See dojo.data.api.Read.getValues()
+		// summary:
+		//		See dojo/data/api/Read.getValues()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		var value = null;
@@ -177,23 +179,23 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	getLabel: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		this._assertIsItem(item);
 		return this.getValue(item, this._labelAttribute);
 	},
 
 	getLabelAttributes: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return [this._labelAttribute];
 	},
 
 	containsValue: function(/* item */ item,
 							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary:
-		//		See dojo.data.api.Read.containsValue()
+		// summary:
+		//		See dojo/data/api/Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
 			regexp = filter.patternToRegExp(value, false);
@@ -202,26 +204,26 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItemLoaded()
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded()
 		return this.isItem(something); //boolean
 	},
 
 	loadItem: function(/* object */ keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Read.loadItem()
+		// summary:
+		//		See dojo/data/api/Read.loadItem()
 		this._assertIsItem(keywordArgs.item);
 	},
 
 	fetch: function(request){
-		//	summary:
-		//		See dojo.data.api.Read.fetch()
+		// summary:
+		//		See dojo/data/api/Read.fetch()
 		request = request || {};
 		if(!request.store){
 			request.store = this;
 		}
 
-		var scope = request.scope || winUtil.global;
+		var scope = request.scope || kernel.global;
 		if(this._pending && this._pending.length > 0){
 			this._pending.push({request: request, fetch: true});
 		}else{
@@ -232,9 +234,9 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	_fetch: function(request){
-		//	summary:
+		// summary:
 		//		Populates the _allItems object with unique class names
-		var scope = request.scope || winUtil.global;
+		var scope = request.scope || kernel.global;
 		if(this._allItems === null){
 			this._allItems = {};
 			try{
@@ -255,7 +257,7 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	_handleRule: function(rule, styleSheet, href){
-		//	summary:
+		// summary:
 		//		Handles the creation of an item based on the passed rule.  In this store, this implies
 		//		parsing out all available class names.
 		var selector = rule['selectorText'];
@@ -283,7 +285,7 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	_handleReturn: function(){
-		//	summary:
+		// summary:
 		//		Handles the return from a fetching action.  Delegates requests to act on the resulting
 		//		item set to eitehr the _handleFetchReturn or _handleFetchByIdentityReturn depending on
 		//		where the request originated.
@@ -313,9 +315,9 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	_handleFetchReturn: function(/*Request */ request){
-		//	summary:
+		// summary:
 		//		Handles a fetchByIdentity request by finding the correct items.
-		var scope = request.scope || winUtil.global;
+		var scope = request.scope || kernel.global;
 		var items = [];
 		//Check to see if we've looked this query up before
 		//If so, just reuse it, much faster.  Only regen if query changes.
@@ -398,8 +400,8 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	close: function(){
-		//	summary:
-		//		See dojo.data.api.Read.close()
+		// summary:
+		//		See dojo/data/api/Read.close().
 		//		Clears out the cache and allItems objects, meaning all future fetches will requery
 		//		the stylesheets.
 		this._cache = {};
@@ -407,9 +409,9 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 	
 	_assertIsItem: function(/* item */ item){
-		//	summary:
-		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item:
+		// summary:
+		//		This function tests whether the item passed in is indeed an item in the store.
+		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
 			throw new Error(this._cName + ": Invalid item argument.");
@@ -417,9 +419,9 @@ return declare("dojox.data.CssRuleStore", null, {
 	},
 
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
-		//	summary:
+		// summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+		// attribute:
 		//		The attribute to test for being contained by the store.
 		if(typeof attribute !== "string"){
 			throw new Error(this._cName + ": Invalid attribute argument.");
@@ -430,20 +432,19 @@ return declare("dojox.data.CssRuleStore", null, {
 								/* attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary:
+		// summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description:
+		// description:
 		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//
-		//	item:
+		// item:
 		//		The data item to examine for attribute values.
-		//	attribute:
+		// attribute:
 		//		The attribute to inspect.
-		//	value:
+		// value:
 		//		The value to match.
-		//	regexp:
+		// regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
 		//		If present and attribute values are string, then it can be used for comparison instead of 'value'
 		return array.some(this.getValues(item, attribute), function(possibleValue){
diff --git a/dojox/data/CsvStore.js b/dojox/data/CsvStore.js
index a16f928..12fbc30 100644
--- a/dojox/data/CsvStore.js
+++ b/dojox/data/CsvStore.js
@@ -1,9 +1,9 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/xhr", "dojo/_base/window","dojo/data/util/filter", "dojo/data/util/simpleFetch"], 
-  function(lang, declare, xhr, winUtil, filterUtil, simpleFetch) {
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/xhr", "dojo/_base/kernel","dojo/data/util/filter", "dojo/data/util/simpleFetch"],
+  function(lang, declare, xhr, kernel, filterUtil, simpleFetch) {
 
 var CsvStore = declare("dojox.data.CsvStore", null, {
 	// summary:
-	//		The CsvStore implements the dojo.data.api.Read API and reads
+	//		The CsvStore implements the dojo/data/api/Read API and reads
 	//		data from files in CSV (Comma Separated Values) format.
 	//		All values are simple string values. References to other items
 	//		are not supported as attribute values in this datastore.
@@ -24,15 +24,16 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 	constructor: function(/* Object */ keywordParameters){
 		// summary:
 		//		initializer
-		// keywordParameters: {url: String}
-		// keywordParameters: {data: String}
-		// keywordParameters: {label: String} The column label for the column to use for the label returned by getLabel.
-		// keywordParameters: {identifier: String} The column label for the column to use for the identity.  Optional.  If not set, the identity is the row number.
+		// keywordParameters:
+		//		- url: String
+		//		- data: String
+		//		- label: String: The column label for the column to use for the label returned by getLabel.
+		//		- identifier: String: The column label for the column to use for the identity.  Optional.  If not set, the identity is the row number.
 		
 		this._attributes = [];			// e.g. ["Title", "Year", "Producer"]
 		this._attributeIndexes = {};	// e.g. {Title: 0, Year: 1, Producer: 2}
- 		this._dataArray = [];			// e.g. [[<Item0>],[<Item1>],[<Item2>]]
- 		this._arrayOfAllItems = [];		// e.g. [{_csvId:0,_csvStore:store},...]
+		this._dataArray = [];			// e.g. [[<Item0>],[<Item1>],[<Item2>]]
+		this._arrayOfAllItems = [];		// e.g. [{_csvId:0,_csvStore:store},...]
 		this._loadFinished = false;
 		if(keywordParameters.url){
 			this.url = keywordParameters.url;
@@ -44,7 +45,7 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 			this.label = undefined;
 		}
 		this._storeProp = "_csvStore";	// Property name for the store reference on every item.
-		this._idProp = "_csvId"; 		// Property name for the Item Id on every item.
+		this._idProp = "_csvId";		// Property name for the Item Id on every item.
 		this._features = {
 			'dojo.data.api.Read': true,
 			'dojo.data.api.Identity': true
@@ -91,7 +92,7 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 
 	_assertIsItem: function(/* item */ item){
 		// summary:
-		//      This function tests whether the item passed in is indeed an item in the store.
+		//		This function tests whether the item passed in is indeed an item in the store.
 		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
@@ -112,15 +113,15 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 	},
 
 /***************************************
-     dojo.data.api.Read API
+     dojo/data/api/Read API
 ***************************************/
 	getValue: function(	/* item */ item,
-						/* attribute || attribute-name-string */ attribute,
+						/* attribute|attribute-name-string */ attribute,
 						/* value? */ defaultValue){
 		// summary:
-		//      See dojo.data.api.Read.getValue()
+		//		See dojo/data/api/Read.getValue()
 		//		Note that for the CsvStore, an empty string value is the same as no value,
-		// 		so the defaultValue would be returned instead of an empty string.
+		//		so the defaultValue would be returned instead of an empty string.
 		this._assertIsItem(item);
 		var itemValue = defaultValue;
 		if(typeof attribute === "string"){
@@ -136,18 +137,18 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 	},
 
 	getValues: function(/* item */ item,
-						/* attribute || attribute-name-string */ attribute){
+						/* attribute|attribute-name-string */ attribute){
 		// summary:
-		//		See dojo.data.api.Read.getValues()
-		// 		CSV syntax does not support multi-valued attributes, so this is just a
-		// 		wrapper function for getValue().
+		//		See dojo/data/api/Read.getValues()
+		//		CSV syntax does not support multi-valued attributes, so this is just a
+		//		wrapper function for getValue().
 		var value = this.getValue(item, attribute);
 		return (value ? [value] : []); //Array
 	},
 
 	getAttributes: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Read.getAttributes()
+		//		See dojo/data/api/Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
 		var itemData = this._dataArray[this._getIndex(item)];
@@ -163,10 +164,10 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
 		// summary:
-		//		See dojo.data.api.Read.hasAttribute()
-		// 		The hasAttribute test is true if attribute has an index number within the item's array length
-		// 		AND if the item has a value for that attribute. Note that for the CsvStore, an
-		// 		empty string value is the same as no value.
+		//		See dojo/data/api/Read.hasAttribute()
+		//		The hasAttribute test is true if attribute has an index number within the item's array length
+		//		AND if the item has a value for that attribute. Note that for the CsvStore, an
+		//		empty string value is the same as no value.
 		this._assertIsItem(item);
 		if(typeof attribute === "string"){
 			var attributeIndex = this._attributeIndexes[attribute];
@@ -178,10 +179,10 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 	},
 
 	containsValue: function(/* item */ item,
-							/* attribute || attribute-name-string */ attribute,
+							/* attribute|attribute-name-string */ attribute,
 							/* anything */ value){
 		// summary:
-		//		See dojo.data.api.Read.containsValue()
+		//		See dojo/data/api/Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
 			regexp = filterUtil.patternToRegExp(value, false);
@@ -190,7 +191,7 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 	},
 
 	_containsValue: function(	/* item */ item,
-								/* attribute || attribute-name-string */ attribute,
+								/* attribute|attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
 		// summary:
@@ -199,7 +200,6 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//
 		// item:
 		//		The data item to examine for attribute values.
 		// attribute:
@@ -228,7 +228,7 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 
 	isItem: function(/* anything */ something){
 		// summary:
-		//		See dojo.data.api.Read.isItem()
+		//		See dojo/data/api/Read.isItem()
 		if(something && something[this._storeProp] === this){
 			var identity = something[this._idProp];
 			//If an identifier was specified, we have to look it up via that and the mapping,
@@ -249,17 +249,18 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 
 	isItemLoaded: function(/* anything */ something){
 		// summary:
-		//		See dojo.data.api.Read.isItemLoaded()
+		//		See dojo/data/api/Read.isItemLoaded()
 		//		The CsvStore always loads all items, so if it's an item, then it's loaded.
 		return this.isItem(something); //Boolean
 	},
 
 	loadItem: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Read.loadItem()
+		//		See dojo/data/api/Read.loadItem()
 		// description:
 		//		The CsvStore always loads all items, so if it's an item, then it's loaded.
-		//		From the dojo.data.api.Read.loadItem docs:
+		//
+		//		From the dojo/data/api/Read.loadItem docs:
 		//			If a call to isItemLoaded() returns true before loadItem() is even called,
 		//			then loadItem() need not do any work at all and will not even invoke
 		//			the callback handlers.
@@ -267,13 +268,13 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 
 	getFeatures: function(){
 		// summary:
-		//		See dojo.data.api.Read.getFeatures()
+		//		See dojo/data/api/Read.getFeatures()
 		return this._features; //Object
 	},
 
 	getLabel: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Read.getLabel()
+		//		See dojo/data/api/Read.getLabel()
 		if(this.label && this.isItem(item)){
 			return this.getValue(item,this.label); //String
 		}
@@ -282,7 +283,7 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 
 	getLabelAttributes: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+		//		See dojo/data/api/Read.getLabelAttributes()
 		if(this.label){
 			return [this.label]; //array
 		}
@@ -290,7 +291,7 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 	},
 
 
-	// The dojo.data.api.Read.fetch() function is implemented as
+	// The dojo/data/api/Read.fetch() function is implemented as
 	// a mixin from dojo.data.util.simpleFetch.
 	// That mixin requires us to define _fetchItems().
 	_fetchItems: function(	/* Object */ keywordArgs,
@@ -412,9 +413,9 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 		}
 	},
 	
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		 //	summary:
-		 //		See dojo.data.api.Read.close()
+	close: function(/*dojo/data/api/Request|Object?*/  request){
+		// summary:
+		//		See dojo/data/api/Read.close()
 	},
 	
 	
@@ -433,14 +434,14 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 		//		columns in the CSV data.
 		// example:
 		//		For example, given this CSV string as input:
-		//			"Title, Year, Producer \n Alien, 1979, Ridley Scott \n Blade Runner, 1982, Ridley Scott"
+		// |		"Title, Year, Producer \n Alien, 1979, Ridley Scott \n Blade Runner, 1982, Ridley Scott"
 		//		this._dataArray will be set to:
-		//			[["Alien", "1979", "Ridley Scott"],
-		//			["Blade Runner", "1982", "Ridley Scott"]]
+		// |		[["Alien", "1979", "Ridley Scott"],
+		// |		["Blade Runner", "1982", "Ridley Scott"]]
 		//		And this._attributes will be set to:
-		//			["Title", "Year", "Producer"]
+		// |		["Title", "Year", "Producer"]
 		//		And this._attributeIndexes will be set to:
-		//			{ "Title":0, "Year":1, "Producer":2 }
+		// |		{ "Title":0, "Year":1, "Producer":2 }
 		// tags:
 		//		private
 		if(lang.isString(csvFileContents)){
@@ -468,7 +469,7 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 							listOfFields[j] = ""; //Special case empty string field.
 						}else if((firstChar == '"') &&
 								((lastChar != '"') ||
-								 ((lastChar == '"') && (secondToLastChar == '"') && (thirdToLastChar != '"')))){
+								((lastChar == '"') && (secondToLastChar == '"') && (thirdToLastChar != '"')))){
 							if(j+1 === listOfFields.length){
 								// alert("The last field in record " + i + " is corrupted:\n" + field);
 								return; //null
@@ -593,11 +594,11 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 	
 	
 /***************************************
-     dojo.data.api.Identity API
+     dojo/data/api/Identity API
 ***************************************/
 	getIdentity: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Identity.getIdentity()
+		//		See dojo/data/api/Identity.getIdentity()
 		// tags:
 		//		public
 		if(this.isItem(item)){
@@ -608,11 +609,11 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 
 	fetchItemByIdentity: function(/* Object */ keywordArgs){
 		// summary:
-		//		See dojo.data.api.Identity.fetchItemByIdentity()
+		//		See dojo/data/api/Identity.fetchItemByIdentity()
 		// tags:
 		//		public
 		var item;
-		var scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
+		var scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 		//Hasn't loaded yet, we have to trigger the load.
 		if(!this._loadFinished){
 			var self = this;
@@ -684,12 +685,12 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 
 	getIdentityAttributes: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Identity.getIdentifierAttributes()
+		//		See dojo/data/api/Identity.getIdentifierAttributes()
 		// tags:
 		//		public
-		 
-		//Identity isn't a public attribute in the item, it's the row position index.
-		//So, return null.
+
+		// Identity isn't a public attribute in the item, it's the row position index.
+		// So, return null.
 		if(this.identifier){
 			return [this.identifier];
 		}else{
@@ -703,7 +704,7 @@ var CsvStore = declare("dojox.data.CsvStore", null, {
 		// tags:
 		//		private
 
-		//Execute any deferred fetches now.
+		// Execute any deferred fetches now.
 		if(this._queuedFetches.length > 0){
 			for(var i = 0; i < this._queuedFetches.length; i++){
 				var fData = this._queuedFetches[i];
diff --git a/dojox/data/FileStore.js b/dojox/data/FileStore.js
index 566edee..ce091db 100755
--- a/dojox/data/FileStore.js
+++ b/dojox/data/FileStore.js
@@ -1,24 +1,27 @@
-define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/window", "dojo/_base/json", "dojo/_base/xhr"], 
-  function(declare, lang, winUtil, jsonUtil, xhr) {
+define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/kernel", "dojo/_base/json", "dojo/_base/xhr"],
+  function(declare, lang, kernel, jsonUtil, xhr) {
 
 return declare("dojox.data.FileStore", null, {
 	constructor: function(/*Object*/args){
-		//	summary:
+		// summary:
 		//		A simple store that provides a datastore interface to a filesystem.
-		//	description:
+		// description:
 		//		A simple store that provides a datastore interface to a filesystem.  It takes a few parameters
 		//		for initialization:
-		//			url:	The URL of the service which provides the file store serverside implementation.
-		//			label:	The attribute of the file to use as the huma-readable text.  Default is 'name'.
+		//
+		//		- url:	The URL of the service which provides the file store serverside implementation.
+		//		- label:	The attribute of the file to use as the human-readable text.  Default is 'name'.
+		//
 		//		The purpose of this store is to represent a file as a datastore item.  The
 		//		datastore item by default has the following attributes that can be examined on it.
-		//			directory:	Boolean indicating if the file item represents a directory.
-		//			name:	The filename with no path informatiom.
-		//			path:	The file complete file path including name, relative to the location the
-		//					file service scans from
-		//			size:	The size of the file, in bytes.
-		//			parentDir:	The parent directory path.
-		//			children:	Any child files contained by a directory file item.
+		//
+		//		- directory:	Boolean indicating if the file item represents a directory.
+		//		- name:	The filename with no path informatiom.
+		//		- path:	The file complete file path including name, relative to the location the
+		//			file service scans from
+		//		- size:	The size of the file, in bytes.
+		//		- parentDir:	The parent directory path.
+		//		- children:	Any child files contained by a directory file item.
 		//
 		//		Note that the store's server call pattern is RESTlike.
 		//
@@ -69,7 +72,7 @@ return declare("dojox.data.FileStore", null, {
 
 	// _attributes: [private] string
 	//		Internal variable of attributes all file items should have.
-	_attributes: ["children", "directory", "name", "path", "modified", "size", "parentDir"], //
+	_attributes: ["children", "directory", "name", "path", "modified", "size", "parentDir"],
 	
 	// pathSeparator: [public] string
 	//		The path separator to use when chaining requests for children
@@ -91,7 +94,7 @@ return declare("dojox.data.FileStore", null, {
 
 	_assertIsItem: function(/* item */ item){
 		// summary:
-		//      This function tests whether the item passed in is indeed an item in the store.
+		//		This function tests whether the item passed in is indeed an item in the store.
 		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
@@ -113,7 +116,7 @@ return declare("dojox.data.FileStore", null, {
 
 	getFeatures: function(){
 		// summary:
-		//      See dojo.data.api.Read.getFeatures()
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true, 'dojo.data.api.Identity':true
 		};
@@ -121,7 +124,7 @@ return declare("dojox.data.FileStore", null, {
 
 	getValue: function(item, attribute, defaultValue){
 		// summary:
-		//      See dojo.data.api.Read.getValue()
+		//		See dojo/data/api/Read.getValue()
 		var values = this.getValues(item, attribute);
 		if(values && values.length > 0){
 			return values[0];
@@ -131,13 +134,13 @@ return declare("dojox.data.FileStore", null, {
 
 	getAttributes: function(item){
 		// summary:
-		//      See dojo.data.api.Read.getAttributes()
+		//		See dojo/data/api/Read.getAttributes()
 		return this._attributes;
 	},
 
 	hasAttribute: function(item, attribute){
 		// summary:
-		//      See dojo.data.api.Read.hasAttribute()
+		//		See dojo/data/api/Read.hasAttribute()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		return (attribute in item);
@@ -145,33 +148,33 @@ return declare("dojox.data.FileStore", null, {
 	
 	getIdentity: function(/* item */ item){
 		// summary:
-		//		See dojo.data.api.Identity.getIdentity()
+		//		See dojo/data/api/Identity.getIdentity()
 		return this.getValue(item, this._identifier);
 	},
 	
 	getIdentityAttributes: function(item){
 		// summary:
-		//      See dojo.data.api.Read.getLabelAttributes()
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return [this._identifier];
 	},
 
 
 	isItemLoaded: function(item){
-		 //	summary:
-		 //      See dojo.data.api.Read.isItemLoaded()
-		 var loaded = this.isItem(item);
-		 if(loaded && typeof item._loaded == "boolean" && !item._loaded){
-		 	loaded = false;
-		 }
-		 return loaded;
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded()
+		var loaded = this.isItem(item);
+		if(loaded && typeof item._loaded == "boolean" && !item._loaded){
+			loaded = false;
+		}
+		return loaded;
 	},
 
 	loadItem: function(keywordArgs){
 		// summary:
-		//      See dojo.data.api.Read.loadItem()
+		//		See dojo/data/api/Read.loadItem()
 		var item = keywordArgs.item;
 		var self = this;
-		var scope = keywordArgs.scope || winUtil.global;
+		var scope = keywordArgs.scope || kernel.global;
 
 		var content = {};
 
@@ -210,19 +213,19 @@ return declare("dojox.data.FileStore", null, {
 
 	getLabel: function(item){
 		// summary:
-		//      See dojo.data.api.Read.getLabel()
+		//		See dojo/data/api/Read.getLabel()
 		return this.getValue(item,this.label);
 	},
 	
 	getLabelAttributes: function(item){
 		// summary:
-		//      See dojo.data.api.Read.getLabelAttributes()
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return [this.label];
 	},
 	
 	containsValue: function(item, attribute, value){
 		// summary:
-		//      See dojo.data.api.Read.containsValue()
+		//		See dojo/data/api/Read.containsValue()
 		var values = this.getValues(item,attribute);
 		for(var i = 0; i < values.length; i++){
 			if(values[i] == value){
@@ -234,7 +237,7 @@ return declare("dojox.data.FileStore", null, {
 
 	getValues: function(item, attribute){
 		// summary:
-		//      See dojo.data.api.Read.getValue()
+		//		See dojo/data/api/Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		
@@ -249,7 +252,7 @@ return declare("dojox.data.FileStore", null, {
 
 	isItem: function(item){
 		// summary:
-		//      See dojo.data.api.Read.isItem()
+		//		See dojo/data/api/Read.isItem()
 		if(item && item[this._storeRef] === this){
 			return true;
 		}
@@ -258,7 +261,7 @@ return declare("dojox.data.FileStore", null, {
 	
 	close: function(request){
 		// summary:
-		//      See dojo.data.api.Read.close()
+		//		See dojo/data/api/Read.close()
 	},
 
 	fetch: function(request){
@@ -272,7 +275,7 @@ return declare("dojox.data.FileStore", null, {
 			request.store = this;
 		}
 		var self = this;
-		var scope = request.scope || winUtil.global;
+		var scope = request.scope || kernel.global;
 
 		//Generate what will be sent over.
 		var reqParams = {};
@@ -320,10 +323,10 @@ return declare("dojox.data.FileStore", null, {
 
 	fetchItemByIdentity: function(keywordArgs){
 		// summary:
-		//      See dojo.data.api.Read.loadItem()
+		//		See dojo/data/api/Read.loadItem()
 		var path = keywordArgs.identity;
 		var self = this;
-		var scope = keywordArgs.scope || winUtil.global;
+		var scope = keywordArgs.scope || kernel.global;
 
 		var content = {};
 
@@ -358,50 +361,50 @@ return declare("dojox.data.FileStore", null, {
 	},
 
 	_processResult: function(data, request){
-		 var scope = request.scope || winUtil.global;
-		 try{
-			 //If the data contains a path separator, set ours
-			 if(data.pathSeparator){
-				 this.pathSeparator = data.pathSeparator;
-			 }
-			 //Invoke the onBegin handler, if any, to return the
-			 //size of the dataset as indicated by the service.
-			 if(request.onBegin){
-				 request.onBegin.call(scope, data.total, request);
-			 }
-			 //Now process all the returned items thro
-			 var items = this._processItemArray(data.items);
-			 if(request.onItem){
+		var scope = request.scope || kernel.global;
+		try{
+			//If the data contains a path separator, set ours
+			if(data.pathSeparator){
+				this.pathSeparator = data.pathSeparator;
+			}
+			//Invoke the onBegin handler, if any, to return the
+			//size of the dataset as indicated by the service.
+			if(request.onBegin){
+				request.onBegin.call(scope, data.total, request);
+			}
+			//Now process all the returned items thro
+			var items = this._processItemArray(data.items);
+			if(request.onItem){
 				var i;
 				for(i = 0; i < items.length; i++){
 					request.onItem.call(scope, items[i], request);
 				}
 				items = null;
-			 }
-			 if(request.onComplete){
-				 request.onComplete.call(scope, items, request);
-			 }
-		 }catch (e){
-			 if(request.onError){
-				 request.onError.call(scope, e, request);
-			 }else{
-				 console.log(e);
-			 }
-		 }
+			}
+			if(request.onComplete){
+				request.onComplete.call(scope, items, request);
+			}
+		}catch (e){
+			if(request.onError){
+				request.onError.call(scope, e, request);
+			}else{
+				console.log(e);
+			}
+		}
 	},
 	
 	_processItemArray: function(itemArray){
-		 //	summary:
-		 //		Internal function for processing an array of items for return.
-		 var i;
-		 for(i = 0; i < itemArray.length; i++){
-		 	this._processItem(itemArray[i]);
-		 }
-		 return itemArray;
+		// summary:
+		//		Internal function for processing an array of items for return.
+		var i;
+		for(i = 0; i < itemArray.length; i++){
+			this._processItem(itemArray[i]);
+		}
+		return itemArray;
 	},
 	
 	_processItem: function(item){
-		//	summary:
+		// summary:
 		//		Internal function for processing an item returned from the store.
 		//		It sets up the store ref as well as sets up the attributes necessary
 		//		to invoke a lazy load on a child, if there are any.
diff --git a/dojox/data/FlickrRestStore.js b/dojox/data/FlickrRestStore.js
index 325f44c..93da714 100644
--- a/dojox/data/FlickrRestStore.js
+++ b/dojox/data/FlickrRestStore.js
@@ -1,8 +1,6 @@
 define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/io/script", "dojox/data/FlickrStore", "dojo/_base/connect"], 
   function(lang, declare, array, scriptIO, FlickrStore, connect) {
 
-/*===== var FlickrStore = dojox.data.FlickrStore; =====*/
-
 var FlickrRestStore = declare("dojox.data.FlickrRestStore",
 	FlickrStore, {
 	constructor: function(/*Object*/args){
@@ -78,12 +76,13 @@ var FlickrRestStore = declare("dojox.data.FlickrRestStore",
 	_fetchItems: function(	/*Object*/ request,
 							/*Function*/ fetchHandler,
 							/*Function*/ errorHandler){
-		//	summary: Fetch flickr items that match to a query
-		//	request:
+		// summary:
+		//		Fetch flickr items that match to a query
+		// request:
 		//		A request object
-		//	fetchHandler:
+		// fetchHandler:
 		//		A function to call for fetched items
-		//	errorHandler:
+		// errorHandler:
 		//		A function to call on error
 		var query = {};
 		if(!request.query){
@@ -376,8 +375,8 @@ var FlickrRestStore = declare("dojox.data.FlickrRestStore",
 	},
 
 	getAttributes: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.getAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		return [
 			"title", "author", "imageUrl", "imageUrlSmall", "imageUrlMedium",
 			"imageUrlThumb", "imageUrlLarge", "imageUrlOriginal", "link", "dateTaken", "datePublished"
@@ -385,8 +384,8 @@ var FlickrRestStore = declare("dojox.data.FlickrRestStore",
 	},
 
 	getValues: function(item, attribute){
-		//	summary:
-		//		See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 
@@ -420,7 +419,8 @@ var FlickrRestStore = declare("dojox.data.FlickrRestStore",
 	},
 
 	_processFlickrData: function(/* Object */data, /* Object */request, /* String */ cacheKey){
-		// summary: Processes the raw data from Flickr and updates the internal cache.
+		// summary:
+		//		Processes the raw data from Flickr and updates the internal cache.
 		// data:
 		//		Data returned from Flickr
 		// request:
diff --git a/dojox/data/FlickrStore.js b/dojox/data/FlickrStore.js
index 104f112..28794dc 100644
--- a/dojox/data/FlickrStore.js
+++ b/dojox/data/FlickrStore.js
@@ -4,9 +4,9 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/data/
 
 var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	constructor: function(/*Object*/args){
-		//	summary:
+		// summary:
 		//		Initializer for the FlickrStore store.
-		//	description:
+		// description:
 		//		The FlickrStore is a Datastore interface to one of the basic services
 		//		of the Flickr service, the public photo feed.  This does not provide
 		//		access to all the services of Flickr.
@@ -28,9 +28,9 @@ var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	urlPreventCache: true,
 
 	_assertIsItem: function(/* item */ item){
-		//	summary:
-		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item:
+		// summary:
+		//		This function tests whether the item passed in is indeed an item in the store.
+		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
 			throw new Error("dojox.data.FlickrStore: a function was passed an item argument that was not an item");
@@ -38,9 +38,9 @@ var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	},
 
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
-		//	summary:
+		// summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+		// attribute:
 		//		The attribute to test for being contained by the store.
 		if(typeof attribute !== "string"){
 			throw new Error("dojox.data.FlickrStore: a function was passed an attribute argument that was not an attribute name string");
@@ -48,16 +48,16 @@ var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	},
 
 	getFeatures: function(){
-		//	summary:
-		//      See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true
 		};
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary:
-		//      See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		var values = this.getValues(item, attribute);
 		if(values && values.length > 0){
 			return values[0];
@@ -66,8 +66,8 @@ var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	},
 
 	getAttributes: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.getAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		return [
 			"title", "description", "author", "datePublished", "dateTaken",
 			"imageUrl", "imageUrlSmall", "imageUrlMedium", "tags", "link"
@@ -75,8 +75,8 @@ var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	},
 
 	hasAttribute: function(item, attribute){
-		//	summary:
-		//      See dojo.data.api.Read.hasAttributes()
+		// summary:
+		//		See dojo/data/api/Read.hasAttributes()
 		var v = this.getValue(item,attribute);
 		if(v || v === "" || v === false){
 			return true;
@@ -85,31 +85,31 @@ var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	},
 
 	isItemLoaded: function(item){
-		 //	summary:
-		 //      See dojo.data.api.Read.isItemLoaded()
-		 return this.isItem(item);
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded()
+		return this.isItem(item);
 	},
 
 	loadItem: function(keywordArgs){
-		//	summary:
-		//      See dojo.data.api.Read.loadItem()
+		// summary:
+		//		See dojo/data/api/Read.loadItem()
 	},
 
 	getLabel: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.getLabel()
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		return this.getValue(item,this.label);
 	},
 	
 	getLabelAttributes: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.getLabelAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return [this.label];
 	},
 
 	containsValue: function(item, attribute, value){
-		//	summary:
-		//      See dojo.data.api.Read.containsValue()
+		// summary:
+		//		See dojo/data/api/Read.containsValue()
 		var values = this.getValues(item,attribute);
 		for(var i = 0; i < values.length; i++){
 			if(values[i] === value){
@@ -120,8 +120,8 @@ var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	},
 
 	getValues: function(item, attribute){
-		//	summary:
-		//      See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -154,8 +154,8 @@ var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	},
 
 	isItem: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.isItem()
+		// summary:
+		//		See dojo/data/api/Read.isItem()
 		if(item && item[this._storeRef] === this){
 			return true;
 		}
@@ -163,18 +163,18 @@ var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	},
 	
 	close: function(request){
-		//	summary:
-		//      See dojo.data.api.Read.close()
+		// summary:
+		//		See dojo/data/api/Read.close()
 	},
 
 	_fetchItems: function(request, fetchHandler, errorHandler){
-		//	summary:
+		// summary:
 		//		Fetch flickr items that match to a query
-		//	request:
+		// request:
 		//		A request object
-		//	fetchHandler:
+		// fetchHandler:
 		//		A function to call for fetched items
-		//	errorHandler:
+		// errorHandler:
 		//		A function to call on error
 
 		var rq = request.query = request.query || {};
@@ -225,23 +225,23 @@ var FlickrStore = declare("dojox.data.FlickrStore", null, {
 	},
 
 	_processFlickrData: function(data){
-		 var items = [];
-		 if(data.items){
-			 items = data.items;
-			 //Add on the store ref so that isItem can work.
-			 for(var i = 0; i < data.items.length; i++){
-				 var item = data.items[i];
-				 item[this._storeRef] = this;
-			 }
-		 }
-		 return items;
+		var items = [];
+		if(data.items){
+			items = data.items;
+			//Add on the store ref so that isItem can work.
+			for(var i = 0; i < data.items.length; i++){
+				var item = data.items[i];
+				item[this._storeRef] = this;
+			}
+		}
+		return items;
 	},
 
 	_unescapeHtml: function(/*String*/ str){
 		// summary:
 		//		Utility function to un-escape XML special characters in an
 		//		HTML string.
-		//	str: String.
+		// str: String.
 		//		The string to un-escape
 		// returns:
 		//		HTML String converted back to the normal text (unescaped)
@@ -250,7 +250,7 @@ var FlickrStore = declare("dojox.data.FlickrStore", null, {
 		//TODO:
 		//		Check to see if theres already compatible escape() in
 		//		dojo.string or dojo.html
-		return 	str.replace(/&/gm, "&").
+		return	str.replace(/&/gm, "&").
 					replace(/</gm, "<").
 					replace(/>/gm, ">").
 					replace(/"/gm, "\"").
diff --git a/dojox/data/GoogleFeedStore.js b/dojox/data/GoogleFeedStore.js
index b85f7f4..125f608 100644
--- a/dojox/data/GoogleFeedStore.js
+++ b/dojox/data/GoogleFeedStore.js
@@ -3,25 +3,24 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojox/dat
 
 dojo.experimental("dojox.data.GoogleFeedStore");
 
-/*===== var Search = dojox.data.GoogleSearchStore =====*/
 var Search = GoogleSearchStore.Search;
 
 return declare("dojox.data.GoogleFeedStore", Search,{
 	// summary:
-	//	A data store for retrieving RSS and Atom feeds from Google. The
-	//  feeds can come from any source, which is specified in the "url"
-	//  parameter of the query passed to the "fetch" function.
-	//	The following attributes are supported on each item:
-	//		<ul>
-	//			<li>title - The feed entry title.</li>
-	//			<li>link - The URL for the HTML version of the feed entry.</li>
-	//			<li>content - The full content of the blog post, in HTML format</li>
-	//			<li>summary - A snippet of information about the feed entry, in plain text</li>
-	//			<li>published - The string date on which the entry was published.
-	//				You can parse the date with new Date(store.getValue(item, "published")</li>
-	//			<li>categories - An array of string tags for the entry</li>
-	//		</ul>
-	//	The query accepts one parameter: url - The URL of the feed to retrieve
+	//		A data store for retrieving RSS and Atom feeds from Google. The
+	//		feeds can come from any source, which is specified in the "url"
+	//		parameter of the query passed to the "fetch" function.
+	//		The following attributes are supported on each item:
+	//
+	//		- title - The feed entry title. 
+	//		- link - The URL for the HTML version of the feed entry. 
+	//		- content - The full content of the blog post, in HTML format 
+	//		- summary - A snippet of information about the feed entry, in plain text 
+	//		- published - The string date on which the entry was published.
+	//					You can parse the date with new Date(store.getValue(item, "published") 
+	//		- categories - An array of string tags for the entry 
+	//
+	//		The query accepts one parameter: url - The URL of the feed to retrieve
 	_type: "",
 	_googleUrl: "http://ajax.googleapis.com/ajax/services/feed/load",
 	_attributes: ["title", "link", "author", "published",
diff --git a/dojox/data/GoogleSearchStore.js b/dojox/data/GoogleSearchStore.js
index 8fb3788..75076de 100644
--- a/dojox/data/GoogleSearchStore.js
+++ b/dojox/data/GoogleSearchStore.js
@@ -1,38 +1,37 @@
-define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window", "dojo/_base/query", 
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/query",
 		"dojo/dom-construct","dojo/io/script"], 
-  function(dojo, lang, declare, winUtil, domQuery, domConstruct, scriptIO) {
+  function(kernel, lang, declare, domQuery, domConstruct, scriptIO) {
 
-dojo.experimental("dojox.data.GoogleSearchStore");
+kernel.experimental("dojox.data.GoogleSearchStore");
 
 var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
-	//	summary:
+	// summary:
 	//		A data store for retrieving search results from Google.
 	//		This data store acts as a base class for Google searches,
 	//		and has a number of child data stores that implement different
 	//		searches. This store defaults to searching the web, and is functionally
 	//		identical to the dojox.data.GoogleWebSearchStore object.
 	//		The following attributes are supported on each item:
-	//		<ul>
-	//			<li>url - The URL for the item</li>
-	//			<li>unescapedUrl - The URL for the item, with URL escaping. This is often more readable</li>
-	//			<li>visibleUrl - The URL with no protocol specified.
-	//			<li>cacheUrl - The URL to the copy of the document cached by Google
-	//			<li>title - The page title in HTML format.</li>
-	//			<li>titleNoFormatting - The page title in plain text</li>
-	//			<li>content - A snippet of information about the page</li>
-	//		</ul>
+	//
+	//		- url - The URL for the item
+	//		- unescapedUrl - The URL for the item, with URL escaping. This is often more readable
+	//		- visibleUrl - The URL with no protocol specified.
+	//		- cacheUrl - The URL to the copy of the document cached by Google
+	//		- title - The page title in HTML format.
+	//		- titleNoFormatting - The page title in plain text
+	//		- content - A snippet of information about the page
+	//
 	//		The query accepts one parameter: text - The string to search for
 	constructor: function(/*Object*/args){
-		//	summary:
+		// summary:
 		//		Initializer for the GoogleSearchStore store.
-		//	description:
+		// description:
 		//		The GoogleSearchStore is a Datastore interface to
 		//		the Google search service. The constructor accepts the following arguments:
-		//		<ul>
-		//			<li>label - the label attribute to use. Defaults to titleNoFormatting</li>
-		//			<li>key - The API key to use. This is optional</li>
-		//			<li>lang - The language locale to use. Defaults to the browser locale</li>
-		//		</ul>
+		//
+		//		- label - the label attribute to use. Defaults to titleNoFormatting
+		//		- key - The API key to use. This is optional
+		//		- lang - The language locale to use. Defaults to the browser locale
 
 		if(args){
 			if(args.label){
@@ -52,57 +51,57 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 	},
 
 	// _id: Integer
-	// A unique identifier for this store.
+	//		A unique identifier for this store.
 	_id: 0,
 
 	// _requestCount: Integer
-	// A counter for the number of requests made. This is used to define
-	// the callback function that GoogleSearchStore will use.
+	//		A counter for the number of requests made. This is used to define
+	//		the callback function that GoogleSearchStore will use.
 	_requestCount: 0,
 
 	// _googleUrl: String
-	// The URL to Googles search web service.
+	//		The URL to Googles search web service.
 	_googleUrl: "http://ajax.googleapis.com/ajax/services/search/",
 
 	// _storeRef: String
-	// The internal reference added to each item pointing at the store which owns it.
+	//		The internal reference added to each item pointing at the store which owns it.
 	_storeRef: "_S",
 
 	// _attributes: Array
-	// The list of attributes that this store supports
+	//		The list of attributes that this store supports
 	_attributes: [	"unescapedUrl", "url", "visibleUrl", "cacheUrl", "title",
 			"titleNoFormatting", "content", "estimatedResultCount"],
 
 	// _aggregtedAttributes: Hash
-	// Maps per-query aggregated attributes that this store supports to the result keys that they come from.
+	//		Maps per-query aggregated attributes that this store supports to the result keys that they come from.
 	_aggregatedAttributes: {
 		estimatedResultCount: "cursor.estimatedResultCount"
 	},
 
 	// label: String
-	// The default attribute which acts as a label for each item.
+	//		The default attribute which acts as a label for each item.
 	label: "titleNoFormatting",
 
 	// type: String
-	// The type of search. Valid values are "web", "local", "video", "blogs", "news", "books", "images".
-	// This should not be set directly. Instead use one of the child classes.
+	//		The type of search. Valid values are "web", "local", "video", "blogs", "news", "books", "images".
+	//		This should not be set directly. Instead use one of the child classes.
 	_type: "web",
 
 	// urlPreventCache: boolean
-	// Sets whether or not to pass preventCache to dojo.io.script.
+	//		Sets whether or not to pass preventCache to dojo.io.script.
 	urlPreventCache: true,
 
 
 	// _queryAttrs: Hash
-	// Maps query hash keys to Google query parameters.
+	//		Maps query hash keys to Google query parameters.
 	_queryAttrs: {
 		text: 'q'
 	},
 
 	_assertIsItem: function(/* item */ item){
-		//	summary:
+		// summary:
 		//		This function tests whether the item passed in is indeed an item in the store.
-		//	item:
+		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
 			throw new Error("dojox.data.GoogleSearchStore: a function was passed an item argument that was not an item");
@@ -110,9 +109,9 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 	},
 
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
-		//	summary:
+		// summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+		// attribute:
 		//		The attribute to test for being contained by the store.
 		if(typeof attribute !== "string"){
 			throw new Error("dojox.data.GoogleSearchStore: a function was passed an attribute argument that was not an attribute name string");
@@ -120,16 +119,16 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 	},
 
 	getFeatures: function(){
-		//	summary:
-		//		See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true
 		};
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary:
-		//		See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		var values = this.getValues(item, attribute);
 		if(values && values.length > 0){
 			return values[0];
@@ -138,14 +137,14 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 	},
 
 	getAttributes: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.getAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		return this._attributes;
 	},
 
 	hasAttribute: function(item, attribute){
-		//	summary:
-		//		See dojo.data.api.Read.hasAttributes()
+		// summary:
+		//		See dojo/data/api/Read.hasAttributes()
 		if(this.getValue(item,attribute)){
 			return true;
 		}
@@ -153,31 +152,31 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 	},
 
 	isItemLoaded: function(item){
-		 //	summary:
-		 //		See dojo.data.api.Read.isItemLoaded()
-		 return this.isItem(item);
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded()
+		return this.isItem(item);
 	},
 
 	loadItem: function(keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Read.loadItem()
+		// summary:
+		//		See dojo/data/api/Read.loadItem()
 	},
 
 	getLabel: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		return this.getValue(item,this.label);
 	},
 
 	getLabelAttributes: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return [this.label];
 	},
 
 	containsValue: function(item, attribute, value){
-		//	summary:
-		//		See dojo.data.api.Read.containsValue()
+		// summary:
+		//		See dojo/data/api/Read.containsValue()
 		var values = this.getValues(item,attribute);
 		for(var i = 0; i < values.length; i++){
 			if(values[i] === value){
@@ -188,8 +187,8 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 	},
 
 	getValues: function(item, attribute){
-		//	summary:
-		//		See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		var val = item[attribute];
@@ -203,8 +202,8 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 	},
 
 	isItem: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.isItem()
+		// summary:
+		//		See dojo/data/api/Read.isItem()
 		if(item && item[this._storeRef] === this){
 			return true;
 		}
@@ -212,8 +211,8 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 	},
 
 	close: function(request){
-		//	summary:
-		//		See dojo.data.api.Read.close()
+		// summary:
+		//		See dojo/data/api/Read.close()
 	},
 
 	_format: function(item, name){
@@ -221,17 +220,17 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 	},
 
 	fetch: function(request){
-		//	summary:
+		// summary:
 		//		Fetch Google search items that match to a query
-		//	request:
+		// request:
 		//		A request object
-		//	fetchHandler:
+		// fetchHandler:
 		//		A function to call for fetched items
-		//	errorHandler:
+		// errorHandler:
 		//		A function to call on error
 		request = request || {};
 
-		var scope = request.scope || winUtil.global;
+		var scope = request.scope || kernel.global;
 
 		if(!request.query){
 			if(request.onError){
@@ -369,7 +368,7 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 					//Process the items...
 					finished = true;
 					//Clean up the function, it should never be called again
-					winUtil.global[callbackFn] = null;
+					kernel.global[callbackFn] = null;
 					if(request.onItem){
 						request.onComplete.call(scope, null, request);
 					}else{
@@ -385,13 +384,13 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 		var lastCallback = firstRequest.start - 1;
 
 		// Attach a callback function to the global namespace, where Google can call it.
-		winUtil.global[callbackFn] = function(start, data, responseCode, errorMsg){
+		kernel.global[callbackFn] = function(start, data, responseCode, errorMsg){
 			try {
 				if(responseCode != 200){
 					if(request.onError){
 						request.onError.call(scope, new Error("Response from Google was: " + responseCode), request);
 					}
-					winUtil.global[callbackFn] = function(){};//an error occurred, do not return anything else.
+					kernel.global[callbackFn] = function(){};//an error occurred, do not return anything else.
 					return;
 				}
 	
@@ -459,37 +458,37 @@ var SearchStore = declare("dojox.data.GoogleSearchStore",null,{
 });
 
 var WebSearchStore = declare("dojox.data.GoogleWebSearchStore", SearchStore,{
-	//	Summary:
+	// summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
-	//		<ul>
-	//			<li>title - The page title in HTML format.</li>
-	//			<li>titleNoFormatting - The page title in plain text</li>
-	//			<li>content - A snippet of information about the page</li>
-	//			<li>url - The URL for the item</li>
-	//			<li>unescapedUrl - The URL for the item, with URL escaping. This is often more readable</li>
-	//			<li>visibleUrl - The URL with no protocol specified.</li>
-	//			<li>cacheUrl - The URL to the copy of the document cached by Google</li>
-	//			<li>estimatedResultCount - (aggregated per-query) estimated number of results</li>
-	//		</ul>
+	//
+	//		- title - The page title in HTML format.
+	//		- titleNoFormatting - The page title in plain text
+	//		- content - A snippet of information about the page
+	//		- url - The URL for the item
+	//		- unescapedUrl - The URL for the item, with URL escaping. This is often more readable
+	//		- visibleUrl - The URL with no protocol specified.
+	//		- cacheUrl - The URL to the copy of the document cached by Google
+	//		- estimatedResultCount - (aggregated per-query) estimated number of results
+	//
 	//		The query accepts one parameter: text - The string to search for
 });
 
 var BlogSearchStore = declare("dojox.data.GoogleBlogSearchStore", SearchStore,{
-	//	Summary:
+	// summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
-	//		<ul>
-	//			<li>title - The blog post title in HTML format.</li>
-	//			<li>titleNoFormatting - The  blog post title in plain text</li>
-	//			<li>content - A snippet of information about the blog post</li>
-	//			<li>blogUrl - The URL for the blog</li>
-	//			<li>postUrl - The URL for the a single blog post</li>
-	//			<li>visibleUrl - The URL with no protocol specified.
-	//			<li>cacheUrl - The URL to the copy of the document cached by Google
-	//			<li>author - The author of the blog post</li>
-	//			<li>publishedDate - The published date, in RFC-822 format</li>
-	//		</ul>
+	//
+	//		- title - The blog post title in HTML format.
+	//		- titleNoFormatting - The  blog post title in plain text
+	//		- content - A snippet of information about the blog post
+	//		- blogUrl - The URL for the blog
+	//		- postUrl - The URL for the a single blog post
+	//		- visibleUrl - The URL with no protocol specified.
+	//		- cacheUrl - The URL to the copy of the document cached by Google
+	//		- author - The author of the blog post
+	//		- publishedDate - The published date, in RFC-822 format
+	//
 	//		The query accepts one parameter: text - The string to search for
 	_type: "blogs",
 	_attributes: ["blogUrl", "postUrl", "title", "titleNoFormatting", "content",
@@ -499,38 +498,35 @@ var BlogSearchStore = declare("dojox.data.GoogleBlogSearchStore", SearchStore,{
 
 
 var LocalSearchStore = declare("dojox.data.GoogleLocalSearchStore", SearchStore,{
-	//	summary:
+	// summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
-	//		<ul>
-	//			<li>title - The blog post title in HTML format.</li>
-	//			<li>titleNoFormatting - The  blog post title in plain text</li>
-	//			<li>content - A snippet of information about the blog post</li>
-	//			<li>url - The URL for the item</li>
-	//			<li>lat - The latitude.</li>
-	//			<li>lng - The longtitude.</li>
-	//			<li>streetAddress - The street address</li>
-	//			<li>city - The city</li>
-	//			<li>region - The region</li>
-	//			<li>country - The country</li>
-	//			<li>phoneNumbers - Phone numbers associated with this address. Can be one or more.</li>
-	//			<li>ddUrl - A URL that can be used to provide driving directions from the center of the search results to this search results</li>
-	//			<li>ddUrlToHere - A URL that can be used to provide driving directions from this search result to a user specified location</li>
-	//			<li>staticMapUrl - The published date, in RFC-822 format</li>
-	//			<li>viewport - Recommended viewport for the query results (same for all results in a query)
-	//				<ul>
-	//					<li>center - contains lat, lng properties</li>
-	//					<li>span - lat, lng properties for the viewport span</li>
-	//					<li>ne, sw - lat, lng properties for the viewport corners<li>
-	//				</ul>
-	//			</li>
-	//		</ul>
+	//
+	//		- title - The blog post title in HTML format.
+	//		- titleNoFormatting - The  blog post title in plain text
+	//		- content - A snippet of information about the blog post
+	//		- url - The URL for the item
+	//		- lat - The latitude.
+	//		- lng - The longtitude.
+	//		- streetAddress - The street address
+	//		- city - The city
+	//		- region - The region
+	//		- country - The country
+	//		- phoneNumbers - Phone numbers associated with this address. Can be one or more.
+	//		- ddUrl - A URL that can be used to provide driving directions from the center of the search results to this search results
+	//		- ddUrlToHere - A URL that can be used to provide driving directions from this search result to a user specified location
+	//		- staticMapUrl - The published date, in RFC-822 format
+	//		- viewport - Recommended viewport for the query results (same for all results in a query)
+	//			- center - contains lat, lng properties
+	//			- span - lat, lng properties for the viewport span
+	//			- ne, sw - lat, lng properties for the viewport corners
+	//
 	//		The query accepts the following parameters:
-	//		<ul>
-	//			<li>text - The string to search for</li>
-	//			<li>centerLatLong - Comma-separated lat & long for the center of the search (e.g. "48.8565,2.3509")</li>
-	//			<li>searchSpan - Comma-separated lat & long degrees indicating the size of the desired search area (e.g. "0.065165,0.194149")</li>
-	//		</ul>
+	//
+	//		- text - The string to search for
+	//		- centerLatLong - Comma-separated lat & long for the center of the search (e.g. "48.8565,2.3509")
+	//		- searchSpan - Comma-separated lat & long degrees indicating the size of the desired search area (e.g. "0.065165,0.194149")
+
 	_type: "local",
 	_attributes: ["title", "titleNoFormatting", "url", "lat", "lng", "streetAddress",
 			"city", "region", "country", "phoneNumbers", "ddUrl", "ddUrlToHere",
@@ -546,22 +542,22 @@ var LocalSearchStore = declare("dojox.data.GoogleLocalSearchStore", SearchStore,
 });
 
 var VideoSearchStore = declare("dojox.data.GoogleVideoSearchStore", SearchStore,{
-	//	summary:
+	// summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
-	//		<ul>
-	//			<li>title - The blog post title in HTML format.</li>
-	//			<li>titleNoFormatting - The  blog post title in plain text</li>
-	//			<li>content - A snippet of information about the blog post</li>
-	//			<li>url - The URL for the item</li>
-	//			<li>published - The published date, in RFC-822 format.</li>
-	//			<li>publisher - The name of the publisher.</li>
-	//			<li>duration - The approximate duration, in seconds, of the video.</li>
-	//			<li>tbWidth - The width in pixels of the video.</li>
-	//			<li>tbHeight - The height in pixels of the video</li>
-	//			<li>tbUrl - The URL to a thumbnail representation of the video.</li>
-	//			<li>playUrl - If present, supplies the url of the flash version of the video that can be played inline on your page. To play this video simply create and <embed> element on your page using this value as the src attribute and using application/x-shockwave-flash as the type attribute. If you want the video to play right away, make sure to append &autoPlay=true to the url..</li>
-	//		</ul>
+	//
+	//		- title - The blog post title in HTML format.
+	//		- titleNoFormatting - The  blog post title in plain text
+	//		- content - A snippet of information about the blog post
+	//		- url - The URL for the item
+	//		- published - The published date, in RFC-822 format.
+	//		- publisher - The name of the publisher.
+	//		- duration - The approximate duration, in seconds, of the video.
+	//		- tbWidth - The width in pixels of the video.
+	//		- tbHeight - The height in pixels of the video
+	//		- tbUrl - The URL to a thumbnail representation of the video.
+	//		- playUrl - If present, supplies the url of the flash version of the video that can be played inline on your page. To play this video simply create and <embed> element on your page using this value as the src attribute and using application/x-shockwave-flash as the type attribute. If you want the video to play right away, make sure to append &autoPlay=true to the url..
+	//
 	//		The query accepts one parameter: text - The string to search for
 	_type: "video",
 	_attributes: ["title", "titleNoFormatting", "content", "url", "published", "publisher",
@@ -570,24 +566,23 @@ var VideoSearchStore = declare("dojox.data.GoogleVideoSearchStore", SearchStore,
 });
 
 var NewsSearchStore = declare("dojox.data.GoogleNewsSearchStore", SearchStore,{
-	//	summary:
+	// summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
-	//		<ul>
-	//			<li>title - The news story title in HTML format.</li>
-	//			<li>titleNoFormatting - The news story title in plain text</li>
-	//			<li>content - A snippet of information about the news story</li>
-	//			<li>url - The URL for the item</li>
-	//			<li>unescapedUrl - The URL for the item, with URL escaping. This is often more readable</li>
-	//			<li>publisher - The name of the publisher</li>
-	//			<li>clusterUrl - A URL pointing to a page listing related storied.</li>
-	//			<li>location - The location of the news story.</li>
-	//			<li>publishedDate - The date of publication, in RFC-822 format.</li>
-	//			<li>relatedStories - An optional array of objects specifying related stories.
-	//				Each object has the following subset of properties:
-	//				"title", "titleNoFormatting", "url", "unescapedUrl", "publisher", "location", "publishedDate".
-	//			</li>
-	//		</ul>
+	//
+	//		- title - The news story title in HTML format.
+	//		- titleNoFormatting - The news story title in plain text
+	//		- content - A snippet of information about the news story
+	//		- url - The URL for the item
+	//		- unescapedUrl - The URL for the item, with URL escaping. This is often more readable
+	//		- publisher - The name of the publisher
+	//		- clusterUrl - A URL pointing to a page listing related storied.
+	//		- location - The location of the news story.
+	//		- publishedDate - The date of publication, in RFC-822 format.
+	//		- relatedStories - An optional array of objects specifying related stories.
+	//			Each object has the following subset of properties:
+	//			"title", "titleNoFormatting", "url", "unescapedUrl", "publisher", "location", "publishedDate".
+	//
 	//		The query accepts one parameter: text - The string to search for
 	_type: "news",
 	_attributes: ["title", "titleNoFormatting", "content", "url", "unescapedUrl", "publisher",
@@ -596,19 +591,19 @@ var NewsSearchStore = declare("dojox.data.GoogleNewsSearchStore", SearchStore,{
 });
 
 var BookSearchStore = declare("dojox.data.GoogleBookSearchStore", SearchStore,{
-	// 	summary:
+	// summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
-	//		<ul>
-	//			<li>title - The book title in HTML format.</li>
-	//			<li>titleNoFormatting - The book title in plain text</li>
-	//			<li>authors - An array of authors</li>
-	//			<li>url - The URL for the item</li>
-	//			<li>unescapedUrl - The URL for the item, with URL escaping. This is often more readable</li>
-	//			<li>bookId - An identifier for the book, usually an ISBN.</li>
-	//			<li>pageCount - The number of pages in the book.</li>
-	//			<li>publishedYear - The year of publication.</li>
-	//		</ul>
+	//
+	//		- title - The book title in HTML format.
+	//		- titleNoFormatting - The book title in plain text
+	//		- authors - An array of authors
+	//		- url - The URL for the item
+	//		- unescapedUrl - The URL for the item, with URL escaping. This is often more readable
+	//		- bookId - An identifier for the book, usually an ISBN.
+	//		- pageCount - The number of pages in the book.
+	//		- publishedYear - The year of publication.
+	//
 	//		The query accepts one parameter: text - The string to search for
 	_type: "books",
 	_attributes: ["title", "titleNoFormatting", "authors", "url", "unescapedUrl", "bookId",
@@ -617,24 +612,24 @@ var BookSearchStore = declare("dojox.data.GoogleBookSearchStore", SearchStore,{
 });
 
 var ImageSearchStore = declare("dojox.data.GoogleImageSearchStore", SearchStore,{
-	//	summary:
+	// summary:
 	//		A data store for retrieving search results from Google.
 	//		The following attributes are supported on each item:
-	//		<ul>
-	//			<li>title - The image title in HTML format.</li>
-	//			<li>titleNoFormatting - The image title in plain text</li>
-	//			<li>url - The URL for the image</li>
-	//			<li>unescapedUrl - The URL for the image, with URL escaping. This is often more readable</li>
-	//			<li>tbUrl - The URL for the image thumbnail</li>
-	//			<li>visibleUrl - A shortened version of the URL associated with the result, stripped of a protocol and path</li>
-	//			<li>originalContextUrl - The URL of the page containing the image.</li>
-	//			<li>width - The width of the image in pixels.</li>
-	//			<li>height - The height of the image in pixels.</li>
-	//			<li>tbWidth - The width of the image thumbnail in pixels.</li>
-	//			<li>tbHeight - The height of the image thumbnail in pixels.</li>
-	//			<li>content - A snippet of information about the image, in HTML format</li>
-	//			<li>contentNoFormatting - A snippet of information about the image, in plain text</li>
-	//		</ul>
+	//
+	//		- title - The image title in HTML format.
+	//		- titleNoFormatting - The image title in plain text
+	//		- url - The URL for the image
+	//		- unescapedUrl - The URL for the image, with URL escaping. This is often more readable
+	//		- tbUrl - The URL for the image thumbnail
+	//		- visibleUrl - A shortened version of the URL associated with the result, stripped of a protocol and path
+	//		- originalContextUrl - The URL of the page containing the image.
+	//		- width - The width of the image in pixels.
+	//		- height - The height of the image in pixels.
+	//		- tbWidth - The width of the image thumbnail in pixels.
+	//		- tbHeight - The height of the image thumbnail in pixels.
+	//		- content - A snippet of information about the image, in HTML format
+	//		- contentNoFormatting - A snippet of information about the image, in plain text
+	//
 	//		The query accepts one parameter: text - The string to search for
 	_type: "images",
 	_attributes: ["title", "titleNoFormatting", "visibleUrl", "url", "unescapedUrl",
diff --git a/dojox/data/HtmlStore.js b/dojox/data/HtmlStore.js
index c769aad..51d7e07 100644
--- a/dojox/data/HtmlStore.js
+++ b/dojox/data/HtmlStore.js
@@ -1,12 +1,12 @@
-define(["dojo/_base/declare", "dojo/_base/array", "dojo/_base/lang", "dojo/dom", "dojo/_base/xhr", "dojo/_base/window",
+define(["dojo/_base/declare", "dojo/_base/array", "dojo/_base/lang", "dojo/dom", "dojo/_base/xhr", "dojo/_base/kernel",
 		"dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/xml/parser"], 
-  function(declare, array, lang, dom, xhr, winUtil, simpleFetch, filter, xmlParser) {
+  function(declare, array, lang, dom, xhr, kernel, simpleFetch, filter, xmlParser) {
 
 var HtmlStore = declare("dojox.data.HtmlStore", null, {
-	constructor: function(/*Object*/args){
-		//	summary:
+	constructor: function(/*Object*/ args){
+		// summary:
 		//		Initializer for the HTML table store.
-		//	description:
+		// description:
 		//		The HtmlStore can be created in one of two ways: a) by parsing an existing
 		//		table or list DOM node on the current page or b) by referencing an external url and giving
 		//		the id of the table or list in that page.  The remote url will be parsed as an html page.
@@ -32,30 +32,36 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 		//		|		</tbody>
 		//		|	</table>
 		//
-		// -or-
+		//		-or-
 		//
 		//		|	<ul id="myUnorderedList">
 		//		|		<li>Value.1</li>
 		//		|		<li>Value.2</li>
 		//		|	</ul>
 		//
-		// -or-
+		//		-or-
 		//
 		//		|	<ol id="myOrderedList">
 		//		|		<li>Value.1</li>
 		//		|		<li>Value.2</li>
 		//		|	</ol>
 		//
-		//	args:
+		// args:
 		//		An anonymous object to initialize properties.  It expects the following values:
-		//		dataId:	The id of the HTML table to use.
+		//
+		//		- dataId:	The id of the HTML table to use.
+		//
 		//		OR
-		//		url:	The url of the remote page to load
-		//		dataId:	The id of the table element in the remote page
+		//
+		//		- url:	The url of the remote page to load
+		//		- dataId:	The id of the table element in the remote page
+		//
 		//		and the option:
-		//		trimWhitespace:  Trim off any surrounding whitespace from the headers (attribute
-		//			names) and text content of the items in question.  Default is false for
-		//			backwards compatibility.
+		//
+		//		- trimWhitespace:  Trim off any surrounding whitespace from the headers (attribute
+		//		names) and text content of the items in question.  Default is false for
+		//		backwards compatibility.
+
 		if(args && "urlPreventCache" in args){
 			this.urlPreventCache = args.urlPreventCache?true:false;
 		}
@@ -101,7 +107,7 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	urlPreventCache: false,
 	
 	// fetchOnCreate: [public] boolean
-	// 		Flag to denote if it should try to load from a data id (nested in the page)
+	//		Flag to denote if it should try to load from a data id (nested in the page)
 	//		The moment the store is created, instead of waiting for first
 	//		fetch call.
 	fetchOnCreate: false,
@@ -132,10 +138,10 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	},
 
 	_getHeadings: function(){
-		//	summary:
+		// summary:
 		//		Function to load the attribute names from the table header so that the
 		//		attributes (cells in a row), can have a reasonable name.
-		//      For list items, returns single implicit heading, ["name"]
+		//		For list items, returns single implicit heading, ["name"]
 		this._headings = [];
 		if(this._rootNode.tHead){
 			array.forEach(this._rootNode.tHead.rows[0].cells, lang.hitch(this, function(th){
@@ -148,7 +154,7 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	},
 	
 	_getAllItems: function(){
-		//	summary:
+		// summary:
 		//		Function to return all rows in the table as an array of items.
 		var items = [];
 		var i;
@@ -167,9 +173,9 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	},
 	
 	_assertIsItem: function(/* item */ item){
-		//	summary:
-		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item:
+		// summary:
+		//		This function tests whether the item passed in is indeed an item in the store.
+		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
 			throw new Error("dojo.data.HtmlStore: a function was passed an item argument that was not an item");
@@ -177,37 +183,35 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	},
 
 	_assertIsAttribute: function(/* String */ attribute){
-		//	summary:
-		//      This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+		// summary:
+		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
+		// attribute:
 		//		The attribute to test for being contained by the store.
-		//
-		//	returns:
+		// returns:
 		//		Returns the index (column) that the attribute resides in the row.
 		if(typeof attribute !== "string"){
 			throw new Error("dojo.data.HtmlStore: a function was passed an attribute argument that was not an attribute name string");
-			return -1;
 		}
 		return array.indexOf(this._headings, attribute); //int
 	},
 
 /***************************************
-	 dojo.data.api.Read API
+	 dojo/data/api/Read API
 ***************************************/
 	
 	getValue: function(	/* item */ item,
 						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		//	summary:
-		//      See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		var values = this.getValues(item, attribute);
-		return (values.length > 0)?values[0]:defaultValue; //Object || int || Boolean
+		return (values.length > 0)?values[0]:defaultValue; // Object|Number|Boolean
 	},
 
 	getValues: function(/* item */ item,
 						/* attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.getValues()
+		// summary:
+		//		See dojo/data/api/Read.getValues()
 
 		this._assertIsItem(item);
 		var index = this._assertIsAttribute(attribute);
@@ -224,8 +228,8 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	},
 
 	getAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
 		for(var i=0; i<this._headings.length; i++){
@@ -237,16 +241,16 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.hasAttribute()
+		// summary:
+		//		See dojo/data/api/Read.hasAttribute()
 		return this.getValues(item, attribute).length > 0;
 	},
 
 	containsValue: function(/* item */ item,
 							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary:
-		//		See dojo.data.api.Read.containsValue()
+		// summary:
+		//		See dojo/data/api/Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
 			regexp = filter.patternToRegExp(value, false);
@@ -258,20 +262,19 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 								/* attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary:
+		// summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description:
+		// description:
 		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//
-		//	item:
+		// item:
 		//		The data item to examine for attribute values.
-		//	attribute:
+		// attribute:
 		//		The attribute to inspect.
-		//	value:
+		// value:
 		//		The value to match.
-		//	regexp:
+		// regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
 		//		If present and attribute values are string, then it can be used for comparison instead of 'value'
 		var values = this.getValues(item, attribute);
@@ -290,27 +293,27 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItem()
+		// summary:
+		//		See dojo/data/api/Read.isItem()
 		return something && dom.isDescendant(something, this._rootNode);
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItemLoaded()
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded()
 		return this.isItem(something);
 	},
 
 	loadItem: function(/* Object */ keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Read.loadItem()
+		// summary:
+		//		See dojo/data/api/Read.loadItem()
 		this._assertIsItem(keywordArgs.item);
 	},
 	
 	_fetchItems: function(request, fetchHandler, errorHandler){
-		//	summary:
+		// summary:
 		//		Fetch items (XML elements) that match to a query
-		//	description:
+		// description:
 		//		If '_fetchUrl' is specified, it is used to load an XML document
 		//		with a query string.
 		//		Otherwise and if 'url' is specified, the XML document is
@@ -319,11 +322,11 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 		//		A wildcard, "*" can be used to query values to match all
 		//		occurrences.
 		//		If '_rootItem' is specified, it is used to fetch items.
-		//	request:
+		// request:
 		//		A request object
-		//	fetchHandler:
+		// fetchHandler:
 		//		A function to call for fetched items
-		//	errorHandler:
+		// errorHandler:
 		//		A function to call on error
 		
 		if(this._rootNode){
@@ -371,7 +374,7 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	},
 	
 	_finishFetchItems: function(request, fetchHandler, errorHandler){
-		//	summary:
+		// summary:
 		//		Internal function for processing the passed in request and locating the requested items.
 		var items = [];
 		var arrayOfAllItems = this._getAllItems();
@@ -416,23 +419,24 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	},
 
 	getFeatures: function(){
-		//	summary:
-		//		See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true,
 			'dojo.data.api.Identity': true
 		};
 	},
 	
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		//	summary:
-		//		See dojo.data.api.Read.close()
+	close: function(/*dojo/data/api/Request|Object?*/ request){
+		// summary:
+		//		See dojo/data/api/Read.close()
+
 		// nothing to do here!
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		if(this.isItem(item)){
 			if(item.cells){
 				return "Item #" + this.getIdentity(item);
@@ -444,8 +448,8 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		if(item.cells){
 			return null;
 		}else{
@@ -454,30 +458,31 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 	},
 
 /***************************************
-	 dojo.data.api.Identity API
+	 dojo/data/api/Identity API
 ***************************************/
 
 	getIdentity: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Identity.getIdentity()
+		// summary:
+		//		See dojo/data/api/Identity.getIdentity()
 		this._assertIsItem(item);
 		if(this.hasAttribute(item, "name")){
-		 	return this.getValue(item,"name");
+			return this.getValue(item,"name");
 		}else{
 			return item._ident;
 		}
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		 //	summary:
-		 //		See dojo.data.api.Identity.getIdentityAttributes()
-		 //Identity isn't taken from a public attribute.
-		 return null;
+		// summary:
+		//		See dojo/data/api/Identity.getIdentityAttributes()
+
+		//Identity isn't taken from a public attribute.
+		return null;
 	},
 
 	fetchItemByIdentity: function(keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Identity.fetchItemByIdentity()
+		// summary:
+		//		See dojo/data/api/Identity.fetchItemByIdentity()
 		var identity = keywordArgs.identity;
 		var self = this;
 		var item = null;
@@ -496,7 +501,7 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 					}
 				}
 				if(keywordArgs.onItem){
-					scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
+					scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 
@@ -536,13 +541,13 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 						}
 					}
 					if(keywordArgs.onItem){
-						scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
+						scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 						keywordArgs.onItem.call(scope, item);
 					}
 				});
 				getHandler.addErrback(function(error){
 					if(keywordArgs.onError){
-						scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
+						scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 						keywordArgs.onError.call(scope, error);
 
 					}
@@ -552,7 +557,7 @@ var HtmlStore = declare("dojox.data.HtmlStore", null, {
 			if(this._rootNode.rows[identity+1]){
 				item = this._rootNode.rows[identity+1];
 				if(keywordArgs.onItem){
-					scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
+					scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 			}
diff --git a/dojox/data/HtmlTableStore.js b/dojox/data/HtmlTableStore.js
index 96d3266..84ce523 100644
--- a/dojox/data/HtmlTableStore.js
+++ b/dojox/data/HtmlTableStore.js
@@ -1,44 +1,46 @@
 define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/_base/lang", "dojo/dom", "dojo/_base/array",
-		"dojo/_base/xhr", "dojo/_base/sniff", "dojo/_base/window", "dojo/data/util/simpleFetch", 
+		"dojo/_base/xhr", "dojo/_base/sniff", "dojo/data/util/simpleFetch",
 		"dojo/data/util/filter", "dojox/xml/parser"], 
-  function(kernel, declare, lang, dom, array, xhr, has, winUtil, simpleFetch, filter, xmlParser) {
+  function(kernel, declare, lang, dom, array, xhr, has, simpleFetch, filter, xmlParser) {
 
 var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	constructor: function(/*Object*/args){
 		kernel.deprecated("dojox.data.HtmlTableStore", "Please use dojox.data.HtmlStore");
-		//	summary:
+		// summary:
 		//		Initializer for the HTML table store.
-		//	description:
+		// description:
 		//		The HtmlTableStore can be created in one of two ways: a) by parsing an existing
 		//		table DOM node on the current page or b) by referencing an external url and giving
 		//		the id of the table in that page.  The remote url will be parsed as an html page.
 		//
 		//		The HTML table should be of the following form:
-		//		<table id="myTable">
-		//			<thead>
-		//				<tr>
-		//					<th>Attribute1</th>
-		//					<th>Attribute2</th>
-		//				</tr>
-		//			</thead>
-		//			<tbody>
-		//				<tr>
-		//					<td>Value1.1</td>
-		//					<td>Value1.2</td>
-		//				</tr>
-		//				<tr>
-		//					<td>Value2.1</td>
-		//					<td>Value2.2</td>
-		//				</tr>
-		//			</tbody>
-		//		</table>
-		//
-		//	args:
+		// |		<table id="myTable">
+		// |			<thead>
+		// |				<tr>
+		// |					<th>Attribute1</th>
+		// |					<th>Attribute2</th>
+		// |				</tr>
+		// |			</thead>
+		// |			<tbody>
+		// |				<tr>
+		// |					<td>Value1.1</td>
+		// |					<td>Value1.2</td>
+		// |				</tr>
+		// |				<tr>
+		// |					<td>Value2.1</td>
+		// |					<td>Value2.2</td>
+		// |				</tr>
+		// |			</tbody>
+		// |		</table>
+		// args:
 		//		An anonymous object to initialize properties.  It expects the following values:
-		//		tableId:	The id of the HTML table to use.
+		//
+		//		- tableId:	The id of the HTML table to use.
+		//
 		//		OR
-		//		url:		The url of the remote page to load
-		//		tableId:	The id of the table element in the remote page
+		//
+		//		- url:		The url of the remote page to load
+		//		- tableId:	The id of the table element in the remote page
 		
 		if(args.url){
 			if(!args.tableId)
@@ -68,7 +70,7 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	tableId: "",
 
 	_getHeadings: function(){
-		//	summary:
+		// summary:
 		//		Function to load the attribute names from the table header so that the
 		//		attributes (cells in a row), can have a reasonable name.
 		this._headings = [];
@@ -78,7 +80,7 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	},
 	
 	_getAllItems: function(){
-		//	summary:
+		// summary:
 		//		Function to return all rows in the table as an array of items.
 		var items = [];
 		for(var i=1; i<this._rootNode.rows.length; i++){
@@ -88,9 +90,9 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	},
 	
 	_assertIsItem: function(/* item */ item){
-		//	summary:
-		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item:
+		// summary:
+		//		This function tests whether the item passed in is indeed an item in the store.
+		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
 			throw new Error("dojo.data.HtmlTableStore: a function was passed an item argument that was not an item");
@@ -98,37 +100,35 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	},
 
 	_assertIsAttribute: function(/* String */ attribute){
-		//	summary:
-		//      This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+		// summary:
+		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
+		// attribute:
 		//		The attribute to test for being contained by the store.
-		//
-		//	returns:
+		// returns:
 		//		Returns the index (column) that the attribute resides in the row.
 		if(typeof attribute !== "string"){
 			throw new Error("dojo.data.HtmlTableStore: a function was passed an attribute argument that was not an attribute name string");
-			return -1;
 		}
 		return array.indexOf(this._headings, attribute); //int
 	},
 
 /***************************************
-     dojo.data.api.Read API
+     dojo/data/api/Read API
 ***************************************/
 	
 	getValue: function(	/* item */ item,
 						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		//	summary:
-		//      See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		var values = this.getValues(item, attribute);
-		return (values.length > 0)?values[0]:defaultValue; //Object || int || Boolean
+		return (values.length > 0)?values[0]:defaultValue; // Object|Number|Boolean
 	},
 
 	getValues: function(/* item */ item,
 						/* attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.getValues()
+		// summary:
+		//		See dojo/data/api/Read.getValues()
 
 		this._assertIsItem(item);
 		var index = this._assertIsAttribute(attribute);
@@ -140,8 +140,8 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	},
 
 	getAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
 		for(var i=0; i<this._headings.length; i++){
@@ -153,16 +153,16 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.hasAttribute()
+		// summary:
+		//		See dojo/data/api/Read.hasAttribute()
 		return this.getValues(item, attribute).length > 0;
 	},
 
 	containsValue: function(/* item */ item,
 							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary:
-		//		See dojo.data.api.Read.containsValue()
+		// summary:
+		//		See dojo/data/api/Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
 			regexp = filter.patternToRegExp(value, false);
@@ -174,20 +174,19 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 								/* attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary:
+		// summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description:
+		// description:
 		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//
-		//	item:
+		// item:
 		//		The data item to examine for attribute values.
-		//	attribute:
+		// attribute:
 		//		The attribute to inspect.
-		//	value:
+		// value:
 		//		The value to match.
-		//	regexp:
+		// regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
 		//		If present and attribute values are string, then it can be used for comparison instead of 'value'
 		var values = this.getValues(item, attribute);
@@ -206,8 +205,8 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItem()
+		// summary:
+		//		See dojo/data/api/Read.isItem()
 		if(something && something.store && something.store === this){
 			return true; //boolean
 		}
@@ -215,21 +214,21 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItemLoaded()
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded()
 		return this.isItem(something);
 	},
 
 	loadItem: function(/* Object */ keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Read.loadItem()
+		// summary:
+		//		See dojo/data/api/Read.loadItem()
 		this._assertIsItem(keywordArgs.item);
 	},
 	
 	_fetchItems: function(request, fetchHandler, errorHandler){
-		//	summary:
+		// summary:
 		//		Fetch items (XML elements) that match to a query
-		//	description:
+		// description:
 		//		If '_fetchUrl' is specified, it is used to load an XML document
 		//		with a query string.
 		//		Otherwise and if 'url' is specified, the XML document is
@@ -238,11 +237,11 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 		//		A wildcard, "*" can be used to query values to match all
 		//		occurrences.
 		//		If '_rootItem' is specified, it is used to fetch items.
-		//	request:
+		// request:
 		//		A request object
-		//	fetchHandler:
+		// fetchHandler:
 		//		A function to call for fetched items
-		//	errorHandler:
+		// errorHandler:
 		//		A function to call on error
 		
 		if(this._rootNode){
@@ -294,7 +293,7 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	},
 	
 	_finishFetchItems: function(request, fetchHandler, errorHandler){
-		//	summary:
+		// summary:
 		//		Internal function for processing the passed in request and locating the requested items.
 		var items = null;
 		var arrayOfAllItems = this._getAllItems();
@@ -339,41 +338,42 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	},
 
 	getFeatures: function(){
-		//	summary:
-		//		See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true,
 			'dojo.data.api.Identity': true
 		};
 	},
 	
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		//	summary:
-		//		See dojo.data.api.Read.close()
+	close: function(/*dojo/data/api/Request|Object?*/ request){
+		// summary:
+		//		See dojo/data/api/Read.close()
+
 		// nothing to do here!
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		if(this.isItem(item))
 			return "Table Row #" + this.getIdentity(item);
 		return undefined;
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return null;
 	},
 
 /***************************************
-     dojo.data.api.Identity API
+     dojo/data/api/Identity API
 ***************************************/
 
 	getIdentity: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Identity.getIdentity()
+		// summary:
+		//		See dojo/data/api/Identity.getIdentity()
 		this._assertIsItem(item);
 		//Opera doesn't support the sectionRowIndex,
 		//So, have to call the indexOf to locate it.
@@ -386,15 +386,16 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		 //	summary:
-		 //		See dojo.data.api.Identity.getIdentityAttributes()
-		 //Identity isn't taken from a public attribute.
-		 return null;
+		// summary:
+		//		See dojo/data/api/Identity.getIdentityAttributes()
+
+		//Identity isn't taken from a public attribute.
+		return null;
 	},
 
 	fetchItemByIdentity: function(keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Identity.fetchItemByIdentity()
+		// summary:
+		//		See dojo/data/api/Identity.fetchItemByIdentity()
 		var identity = keywordArgs.identity;
 		var self = this;
 		var item = null;
@@ -409,7 +410,7 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 				}
 				item = this._rootNode.rows[identity+1];
 				if(keywordArgs.onItem){
-					scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
+					scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 
@@ -443,13 +444,13 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 					}
 					item = self._rootNode.rows[identity+1];
 					if(keywordArgs.onItem){
-						scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
+						scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 						keywordArgs.onItem.call(scope, item);
 					}
 				});
 				getHandler.addErrback(function(error){
 					if(keywordArgs.onError){
-						scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
+						scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 						keywordArgs.onError.call(scope, error);
 
 					}
@@ -459,7 +460,7 @@ var HtmlTableStore = declare("dojox.data.HtmlTableStore", null, {
 			if(this._rootNode.rows[identity+1]){
 				item = this._rootNode.rows[identity+1];
 				if(keywordArgs.onItem){
-					scope = keywordArgs.scope?keywordArgs.scope:winUtil.global;
+					scope = keywordArgs.scope?keywordArgs.scope:kernel.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 			}
diff --git a/dojox/data/ItemExplorer.js b/dojox/data/ItemExplorer.js
index 6b62fc4..47470e6 100644
--- a/dojox/data/ItemExplorer.js
+++ b/dojox/data/ItemExplorer.js
@@ -229,9 +229,9 @@ dojo.declare("dojox.data.ItemExplorer", dijit.Tree, {
 	},
 	_createEditDialog: function(){
 		this._editDialog = new dijit.Dialog({
-			 title: "Edit Property",
-			 execute: dojo.hitch(this, "_updateItem"),
-			 preload: true
+			title: "Edit Property",
+			execute: dojo.hitch(this, "_updateItem"),
+			preload: true
 		});
 		this._editDialog.placeAt(dojo.body());
 		this._editDialog.startup();
@@ -270,7 +270,7 @@ dojo.declare("dojox.data.ItemExplorer", dijit.Tree, {
 		dojo.attr(labelVal, "innerHTML", "Value (JSON):")
 		pane.appendChild(labelVal);
 
-		 // container for value fields
+		// container for value fields
 		var valueDiv = dojo.doc.createElement("div");
 		dojo.addClass(valueDiv, "value");
 
@@ -618,7 +618,6 @@ dojo.declare("dojox.data.ItemExplorer", dijit.Tree, {
 			}else{
 				showDialog();
 			}
-//
 		}
 	}
 });
diff --git a/dojox/data/JsonQueryRestStore.js b/dojox/data/JsonQueryRestStore.js
index 0f0e374..828b41a 100644
--- a/dojox/data/JsonQueryRestStore.js
+++ b/dojox/data/JsonQueryRestStore.js
@@ -1,14 +1,20 @@
-define(["dojo", "dojox", "dojox/data/JsonRestStore", "dojox/data/util/JsonQuery", "dojox/data/ClientFilter", "dojox/json/query"], function(dojo, dojox) {
+define([
+	"dojo/_base/declare",
+	"dojox/data/JsonRestStore", "dojox/data/util/JsonQuery", "dojox/data/ClientFilter",
+	"dojox/json/query"
+], function(declare, JsonRestStore, JsonQuery) {
 
-// this is an extension of JsonRestStore to convert object attribute queries to
-// JSONQuery/JSONPath syntax to be sent to the server. This also enables
-//	JSONQuery/JSONPath queries to be performed locally if dojox.data.ClientFilter
-//	has been loaded
-dojo.declare("dojox.data.JsonQueryRestStore",[dojox.data.JsonRestStore,dojox.data.util.JsonQuery],{
+// summary:
+//		this is an extension of JsonRestStore to convert object attribute queries to
+//		JSONQuery/JSONPath syntax to be sent to the server. This also enables
+//		SONQuery/JSONPath queries to be performed locally if dojox.data.ClientFilter
+//		has been loaded
+
+return declare("dojox.data.JsonQueryRestStore",[JsonRestStore, JsonQuery],{
 	matchesQuery: function(item,request){
 		return item.__id && (item.__id.indexOf("#") == -1) && this.inherited(arguments);
 	}
 });
 
-return dojox.data.JsonQueryRestStore;
+
 });
diff --git a/dojox/data/JsonRestStore.js b/dojox/data/JsonRestStore.js
index cd82c9b..5f80000 100644
--- a/dojox/data/JsonRestStore.js
+++ b/dojox/data/JsonRestStore.js
@@ -2,80 +2,87 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojox/rp
 		"dojox/rpc/JsonRest", "dojox/json/schema", "dojox/data/ServiceStore"], 
   function(lang, declare, connect, rpcRest, rpcJsonRest, jsonSchema, ServiceStore) {
 
-/*=====
-var ServiceStore = dojox.data.ServiceStore;
-=====*/
+var rpc = lang.getObject("dojox.rpc", true);
 
 var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 	{
 		constructor: function(options){
-			//summary:
+			// summary:
 			//		JsonRestStore is a Dojo Data store interface to JSON HTTP/REST web
 			//		storage services that support read and write through GET, PUT, POST, and DELETE.
 			// options:
-			// 		Keyword arguments
+			//		Keyword arguments
+			//
+			//		####The *schema* parameter
 			//
-			// The *schema* parameter
 			//		This is a schema object for this store. This should be JSON Schema format.
 			//
-			// The *service* parameter
-			// 		This is the service object that is used to retrieve lazy data and save results
-			// 		The function should be directly callable with a single parameter of an object id to be loaded
-			// 		The function should also have the following methods:
-			// 			put(id,value) - puts the value at the given id
-			// 			post(id,value) - posts (appends) the value at the given id
-			// 			delete(id) - deletes the value corresponding to the given id
+			//		####The *service* parameter
+			//
+			//		This is the service object that is used to retrieve lazy data and save results
+			//		The function should be directly callable with a single parameter of an object id to be loaded
+			//		The function should also have the following methods:
+			//
+			//		- put(id,value) - puts the value at the given id
+			//		- post(id,value) - posts (appends) the value at the given id
+			//		- delete(id) - deletes the value corresponding to the given id
+			//
 			//		Note that it is critical that the service parses responses as JSON.
 			//		If you are using dojox.rpc.Service, the easiest way to make sure this
-			// 		happens is to make the responses have a content type of
-			// 		application/json. If you are creating your own service, make sure you
+			//		happens is to make the responses have a content type of
+			//		application/json. If you are creating your own service, make sure you
 			//		use handleAs: "json" with your XHR requests.
 			//
-			// The *target* parameter
-			// 		This is the target URL for this Service store. This may be used in place
-			// 		of a service parameter to connect directly to RESTful URL without
-			// 		using a dojox.rpc.Service object.
+			//		####The *target* parameter
+			//
+			//		This is the target URL for this Service store. This may be used in place
+			//		of a service parameter to connect directly to RESTful URL without
+			//		using a dojox.rpc.Service object.
+			//
+			//		####The *idAttribute* parameter
 			//
-			// The *idAttribute* parameter
 			//		Defaults to 'id'. The name of the attribute that holds an objects id.
 			//		This can be a preexisting id provided by the server.
 			//		If an ID isn't already provided when an object
 			//		is fetched or added to the store, the autoIdentity system
 			//		will generate an id for it and add it to the index.
 			//
-			// The *syncMode* parameter
+			//		####The *syncMode* parameter
+			//
 			//		Setting this to true will set the store to using synchronous calls by default.
 			//		Sync calls return their data immediately from the calling function, so
 			//		callbacks are unnecessary
-			//
-			//	description:
+			// description:
 			//		The JsonRestStore will cause all saved modifications to be sent to the server using Rest commands (PUT, POST, or DELETE).
-			// 		When using a Rest store on a public network, it is important to implement proper security measures to
+			//		When using a Rest store on a public network, it is important to implement proper security measures to
 			//		control access to resources.
+			//
 			//		On the server side implementing a REST interface means providing GET, PUT, POST, and DELETE handlers.
-			//		GET - Retrieve an object or array/result set, this can be by id (like /table/1) or with a
-			// 			query (like /table/?name=foo).
-			//		PUT - This should modify a object, the URL will correspond to the id (like /table/1), and the body will
-			// 			provide the modified object
-			//		POST - This should create a new object. The URL will correspond to the target store (like /table/)
-			// 			and the body should be the properties of the new object. The server's response should include a
-			// 			Location header that indicates the id of the newly created object. This id will be used for subsequent
-			// 			PUT and DELETE requests. JsonRestStore also includes a Content-Location header that indicates
+			//
+			//		- GET - Retrieve an object or array/result set, this can be by id (like /table/1) or with a
+			//			query (like /table/?name=foo).
+			//		- PUT - This should modify a object, the URL will correspond to the id (like /table/1), and the body will
+			//			provide the modified object
+			//		- POST - This should create a new object. The URL will correspond to the target store (like /table/)
+			//			and the body should be the properties of the new object. The server's response should include a
+			//			Location header that indicates the id of the newly created object. This id will be used for subsequent
+			//			PUT and DELETE requests. JsonRestStore also includes a Content-Location header that indicates
 			//			the temporary randomly generated id used by client, and this location is used for subsequent
-			// 			PUT/DELETEs if no Location header is provided by the server or if a modification is sent prior
-			// 			to receiving a response from the server.
-			// 		DELETE - This should delete an object by id.
-			// 		These articles include more detailed information on using the JsonRestStore:
-			//		http://www.sitepen.com/blog/2008/06/13/restful-json-dojo-data/
-			//		http://blog.medryx.org/2008/07/24/jsonreststore-overview/
+			//			PUT/DELETEs if no Location header is provided by the server or if a modification is sent prior
+			//			to receiving a response from the server.
+			//		- DELETE - This should delete an object by id.
+			//
+			//		These articles include more detailed information on using the JsonRestStore:
 			//
-			//	example:
-			// 		A JsonRestStore takes a REST service or a URL and uses it the remote communication for a
-			// 		read/write dojo.data implementation. A JsonRestStore can be created with a simple URL like:
-			// 	|	new JsonRestStore({target:"/MyData/"});
-			//	example:
-			// 		To use a JsonRestStore with a service, you should create a
-			// 		service with a REST transport. This can be configured with an SMD:
+			//		- http://www.sitepen.com/blog/2008/06/13/restful-json-dojo-data/
+			//		- http://blog.medryx.org/2008/07/24/jsonreststore-overview/
+			// example:
+			//		A JsonRestStore takes a REST service or a URL and uses it the remote communication for a
+			//		read/write dojo.data implementation. A JsonRestStore can be created with a simple URL like:
+			//	|	new JsonRestStore({target:"/MyData/"});
+			// example:
+			//		To use a JsonRestStore with a service, you should create a
+			//		service with a REST transport. This can be configured with an SMD:
 			//	|	{
 			//	|		services: {
 			//	|			jsonRestStore: {
@@ -89,17 +96,16 @@ var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 			//	|			}
 			//	|		}
 			//	|	}
-			// 		The SMD can then be used to create service, and the service can be passed to a JsonRestStore. For example:
+			//		The SMD can then be used to create service, and the service can be passed to a JsonRestStore. For example:
 			//	|	var myServices = new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.tests.resources", "test.smd"));
 			//	|	var jsonStore = new dojox.data.JsonRestStore({service:myServices.jsonRestStore});
-			//	example:
+			// example:
 			//		The JsonRestStore also supports lazy loading. References can be made to objects that have not been loaded.
 			//		For example if a service returned:
 			//	|	{"name":"Example","lazyLoadedObject":{"$ref":"obj2"}}
-			// 		And this object has accessed using the dojo.data API:
+			//		And this object has accessed using the dojo.data API:
 			//	|	var obj = jsonStore.getValue(myObject,"lazyLoadedObject");
 			//		The object would automatically be requested from the server (with an object id of "obj2").
-			//
 
 			connect.connect(rpcRest._index,"onUpdate",this,function(obj,attrName,oldValue,newValue){
 				var prefix = this.service.servicePath;
@@ -136,26 +142,29 @@ var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 			this._index = rpcRest._index;
 		},
 		
-		// summary:
+		// loadReferencedSchema: Boolean
 		//		Will load any schemas referenced content-type header or in Link headers
 		loadReferencedSchema: true,
-		// summary:
+		
+		// idAsRef: Boolean
 		//		Treat objects in queries as partially loaded objects
 		idAsRef: false,
+		
 		referenceIntegrity: true,
 		target:"",
-		// summary:
-		// 		Allow no trailing slash on target paths. This is generally discouraged since
-		// 		it creates prevents simple scalar values from being used a relative URLs.
-		// 		Disabled by default.
+		
+		// allowNoTrailingSlash: Boolean
+		//		Allow no trailing slash on target paths. This is generally discouraged since
+		//		it creates prevents simple scalar values from being used a relative URLs.
+		//		Disabled by default.
 		allowNoTrailingSlash: false,
+		
 		//Write API Support
 		newItem: function(data, parentInfo){
 			// summary:
 			//		adds a new item to the store at the specified point.
 			//		Takes two parameters, data, and options.
-			//
-			//	data: /* object */
+			// data: Object
 			//		The data to be added in as an item.
 			data = new this._constructor(data);
 			if(parentInfo){
@@ -171,10 +180,8 @@ var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 		deleteItem: function(item){
 			// summary:
 			//		deletes item and any references to that item from the store.
-			//
-			//	item:
+			// item:
 			//		item to delete
-			//
 
 			//	If the desire is to delete only one reference, unsetAttribute or
 			//	setValue is the way to go.
@@ -250,10 +257,10 @@ var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 			rpcJsonRest.changing(item,_deleting);
 		},
 		cancelChanging : function(object){
-			//	summary:
-			// 		Removes an object from the list of dirty objects
+			// summary:
+			//		Removes an object from the list of dirty objects
 			//		This will prevent that object from being saved to the server on the next save
-			//	object:
+			// object:
 			//		The item to cancel changes on
 			if(!object.__id){
 				return;
@@ -312,39 +319,36 @@ var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 		},
 		save: function(kwArgs){
 			// summary:
-			//		Saves the dirty data using REST Ajax methods. See dojo.data.api.Write for API.
-			//
-			//	kwArgs.global:
-			//		This will cause the save to commit the dirty data for all
-			// 		JsonRestStores as a single transaction.
-			//
-			//	kwArgs.revertOnError
-			//		This will cause the changes to be reverted if there is an
-			//		error on the save. By default a revert is executed unless
-			//		a value of false is provide for this parameter.
-			//
-			//	kwArgs.incrementalUpdates
-			//		For items that have been updated, if this is enabled, the server will be sent a POST request
-			// 		with a JSON object containing the changed properties. By default this is
-			// 		not enabled, and a PUT is used to deliver an update, and will include a full
-			// 		serialization of all the properties of the item/object.
-			//		If this is true, the POST request body will consist of a JSON object with
-			// 		only the changed properties. The incrementalUpdates parameter may also
-			//		be a function, in which case it will be called with the updated and previous objects
-			//		and an object update representation can be returned.
-			//
-			//	kwArgs.alwaysPostNewItems
-			//		If this is true, new items will always be sent with a POST request. By default
-			//		this is not enabled, and the JsonRestStore will send a POST request if
-			//		the item does not include its identifier (expecting server assigned location/
-			//		identifier), and will send a PUT request if the item does include its identifier
-			//		(the PUT will be sent to the URI corresponding to the provided identifier).
+			//		Saves the dirty data using REST Ajax methods. See dojo/data/api/Write for API.
+			// kwArgs:
+			//		- global:
+			//			This will cause the save to commit the dirty data for all
+			//			JsonRestStores as a single transaction.
+			//		- revertOnError:
+			//			This will cause the changes to be reverted if there is an
+			//			error on the save. By default a revert is executed unless
+			//			a value of false is provide for this parameter.
+			//		- incrementalUpdates:
+			//			For items that have been updated, if this is enabled, the server will be sent a POST request
+			//			with a JSON object containing the changed properties. By default this is
+			//			not enabled, and a PUT is used to deliver an update, and will include a full
+			//			serialization of all the properties of the item/object.
+			//			If this is true, the POST request body will consist of a JSON object with
+			//			only the changed properties. The incrementalUpdates parameter may also
+			//			be a function, in which case it will be called with the updated and previous objects
+			//			and an object update representation can be returned.
+			//		- alwaysPostNewItems:
+			//			If this is true, new items will always be sent with a POST request. By default
+			//			this is not enabled, and the JsonRestStore will send a POST request if
+			//			the item does not include its identifier (expecting server assigned location/
+			//			identifier), and will send a PUT request if the item does include its identifier
+			//			(the PUT will be sent to the URI corresponding to the provided identifier).
 
 			if(!(kwArgs && kwArgs.global)){
 				(kwArgs = kwArgs || {}).service = this.service;
 			}
 			if("syncMode" in kwArgs ? kwArgs.syncMode : this.syncMode){
-				rpcConfig._sync = true;
+				rpc._sync = true;
 			}
 
 			var actions = rpcJsonRest.commit(kwArgs);
@@ -353,28 +357,27 @@ var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 		},
 
 		revert: function(kwArgs){
-			// summary
+			// summary:
 			//		returns any modified data to its original state prior to a save();
-			//
-			//	kwArgs.global:
-			//		This will cause the revert to undo all the changes for all
-			// 		JsonRestStores in a single operation.
-			rpcJsonRest.revert(kwArgs && kwArgs.global && this.service);
+			// kwArgs:
+			//		- global:
+			//			This will cause the revert to undo all the changes for all
+			//			JsonRestStores in a single operation.
+			rpcJsonRest.revert(!(kwArgs && kwArgs.global) && this.service);
 		},
 
 		isDirty: function(item){
-			// summary
+			// summary:
 			//		returns true if the item is marked as dirty.
 			return rpcJsonRest.isDirty(item, this);
 		},
 		isItem: function(item, anyStore){
-			//	summary:
+			// summary:
 			//		Checks to see if a passed 'item'
 			//		really belongs to this JsonRestStore.
-			//
-			//	item: /* object */
+			// item: Object
 			//		The value to test for being an item
-			//	anyStore: /* boolean*/
+			// anyStore: Boolean
 			//		If true, this will return true if the value is an item for any JsonRestStore,
 			//		not just this instance
 			return item && item.__id && (anyStore || this.service == rpcJsonRest.getServiceAndId(item.__id).service);
@@ -418,7 +421,7 @@ var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 
 		getConstructor: function(){
 			// summary:
-			// 		Gets the constructor for objects from this store
+			//		Gets the constructor for objects from this store
 			return this._constructor;
 		},
 		getIdentity: function(item){
@@ -446,11 +449,11 @@ var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 
 		onSet: function(){},
 		onNew: function(){},
-		onDelete: 	function(){},
+		onDelete: function(){},
 
 		getFeatures: function(){
 			// summary:
-			// 		return the store feature set
+			//		return the store feature set
 			var features = this.inherited(arguments);
 			features["dojo.data.api.Write"] = true;
 			features["dojo.data.api.Notification"] = true;
@@ -458,9 +461,9 @@ var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 		},
 
 		getParent: function(item){
-			//	summary:
+			// summary:
 			//		Returns the parent item (or query) for the given item
-			//	item:
+			// item:
 			//		The item to find the parent of
 
 			return item && item.__parent;
@@ -470,14 +473,14 @@ var JsonRestStore = declare("dojox.data.JsonRestStore", ServiceStore,
 	}
 );
 JsonRestStore.getStore = function(options, Class){
-	//	summary:
+	// summary:
 	//		Will retrieve or create a store using the given options (the same options
 	//		that are passed to JsonRestStore constructor. Returns a JsonRestStore instance
-	//	options:
+	// options:
 	//		See the JsonRestStore constructor
-	//	Class:
+	// Class:
 	//		Constructor to use (for creating stores from JsonRestStore subclasses).
-	// 		This is optional and defaults to JsonRestStore.
+	//		This is optional and defaults to JsonRestStore.
 	if(typeof options.target == 'string'){
 		options.target = options.target.match(/\/$/) || options.allowNoTrailingSlash ?
 				options.target : (options.target + '/');
diff --git a/dojox/data/KeyValueStore.js b/dojox/data/KeyValueStore.js
index d41e85f..b57e68d 100644
--- a/dojox/data/KeyValueStore.js
+++ b/dojox/data/KeyValueStore.js
@@ -1,24 +1,26 @@
-define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/xhr", "dojo/_base/window", 
+define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/xhr", "dojo/_base/kernel",
 		"dojo/data/util/simpleFetch", "dojo/data/util/filter"], 
-  function(declare, lang, xhr, winUtil, simpleFetch, filterUtil) {
+  function(declare, lang, xhr, kernel, simpleFetch, filterUtil) {
 
 var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
-	//	summary:
+	// summary:
 	//		This is a dojo.data store implementation.  It can take in either a Javascript
 	//		array, JSON string, or URL as the data source.  Data is expected to be in the
 	//		following format:
-	//			[
-	//				{ "key1": "value1" },
-	//				{ "key2": "value2" }
-	//			]
+	// |	[
+	// |		{ "key1": "value1" },
+	// |		{ "key2": "value2" }
+	// |	]
 	//		This is to mimic the Java Properties file format.  Each 'item' from this store
 	//		is a JS object representing a key-value pair.  If an item in the above array has
 	//		more than one key/value pair, only the first will be used/accessed.
 	constructor: function(/* Object */ keywordParameters){
-		//	summary: constructor
-		//	keywordParameters: {url: String}
-		//	keywordParameters: {data: string}
-		//	keywordParameters: {dataVar: jsonObject}
+		// summary:
+		//		constructor
+		// keywordParameters:
+		//		- {url: String}
+		//		- {data: string}
+		//		- {dataVar: jsonObject}
 		if(keywordParameters.url){
 			this.url = keywordParameters.url;
 		}
@@ -41,14 +43,14 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	url: "",
 	data: "",
 
-	//urlPreventCache: boolean
-	//Controls if urlPreventCache should be used with underlying xhrGet.
+	// urlPreventCache: boolean
+	//		Controls if urlPreventCache should be used with underlying xhrGet.
 	urlPreventCache: false,
 	
 	_assertIsItem: function(/* item */ item){
-		//	summary:
-		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item:
+		// summary:
+		//		This function tests whether the item passed in is indeed an item in the store.
+		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
 			throw new Error("dojox.data.KeyValueStore: a function was passed an item argument that was not an item");
@@ -56,9 +58,9 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	},
 	
 	_assertIsAttribute: function(/* item */ item, /* String */ attribute){
-		//	summary:
-		//      This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+		// summary:
+		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
+		// attribute:
 		//		The attribute to test for being contained by the store.
 		if(!lang.isString(attribute)){
 			throw new Error("dojox.data.KeyValueStore: a function was passed an attribute argument that was not an attribute object nor an attribute name string");
@@ -66,13 +68,13 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	},
 
 /***************************************
-     dojo.data.api.Read API
+     dojo/data/api/Read API
 ***************************************/
 	getValue: function(	/* item */ item,
 						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		//	summary:
-		//		See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(item, attribute);
 		var value;
@@ -89,24 +91,24 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 
 	getValues: function(/* item */ item,
 						/* attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.getValues()
-		// 		Key/Value syntax does not support multi-valued attributes, so this is just a
-		// 		wrapper function for getValue().
+		// summary:
+		//		See dojo/data/api/Read.getValues()
+		//		Key/Value syntax does not support multi-valued attributes, so this is just a
+		//		wrapper function for getValue().
 		var value = this.getValue(item, attribute);
 		return (value ? [value] : []); //Array
 	},
 
 	getAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		return [this._keyAttribute, this._valueAttribute, item[this._keyAttribute]];
 	},
 
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.hasAttribute()
+		// summary:
+		//		See dojo/data/api/Read.hasAttribute()
 		this._assertIsItem(item);
 		this._assertIsAttribute(item, attribute);
 		return (attribute == this._keyAttribute || attribute == this._valueAttribute || attribute == item[this._keyAttribute]);
@@ -115,8 +117,8 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	containsValue: function(/* item */ item,
 							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary:
-		//		See dojo.data.api.Read.containsValue()
+		// summary:
+		//		See dojo/data/api/Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
 			regexp = filterUtil.patternToRegExp(value, false);
@@ -125,23 +127,22 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	},
 
 	_containsValue: function(	/* item */ item,
-								/* attribute || attribute-name-string */ attribute,
+								/* attribute|attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary:
+		// summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description:
+		// description:
 		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//
-		//	item:
+		// item:
 		//		The data item to examine for attribute values.
-		//	attribute:
+		// attribute:
 		//		The attribute to inspect.
-		//	value:
+		// value:
 		//		The value to match.
-		//	regexp:
+		// regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
 		//		If present and attribute values are string, then it can be used for comparison instead of 'value'
 		var values = this.getValues(item, attribute);
@@ -160,8 +161,8 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItem()
+		// summary:
+		//		See dojo/data/api/Read.isItem()
 		if(something && something[this._storeProp] === this){
 			return true; //Boolean
 		}
@@ -169,53 +170,55 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItemLoaded()
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded()
 		//		The KeyValueStore always loads all items, so if it's an item, then it's loaded.
 		return this.isItem(something); //Boolean
 	},
 
 	loadItem: function(/* object */ keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Read.loadItem()
-		//	description:
+		// summary:
+		//		See dojo/data/api/Read.loadItem()
+		// description:
 		//		The KeyValueStore always loads all items, so if it's an item, then it's loaded.
-		//		From the dojo.data.api.Read.loadItem docs:
+		//
+		//		From the dojo/data/api/Read.loadItem docs:
+		//
 		//			If a call to isItemLoaded() returns true before loadItem() is even called,
 		//			then loadItem() need not do any work at all and will not even invoke
 		//			the callback handlers.
 	},
 
 	getFeatures: function(){
-		//	summary:
-		//		See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return this._features; //Object
 	},
 
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		//	summary:
-		//		See dojo.data.api.Read.close()
+	close: function(/*dojo/data/api/Request|Object?*/ request){
+		// summary:
+		//		See dojo/data/api/Read.close()
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		return item[this._keyAttribute];
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return [this._keyAttribute];
 	},
 	
-	// The dojo.data.api.Read.fetch() function is implemented as
+	// The dojo/data/api/Read.fetch() function is implemented as
 	// a mixin from dojo.data.util.simpleFetch.
 	// That mixin requires us to define _fetchItems().
 	_fetchItems: function(	/* Object */ keywordArgs,
 							/* Function */ findCallback,
 							/* Function */ errorCallback){
-		//	summary:
+		// summary:
 		//		See dojo.data.util.simpleFetch.fetch()
 		
 		var self = this;
@@ -312,8 +315,9 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	},
 
 	_handleQueuedFetches: function(){
-		//	summary:
+		// summary:
 		//		Internal function to execute delayed request in the store.
+		
 		//Execute any deferred fetches now.
 		if(this._queuedFetches.length > 0){
 			for(var i = 0; i < this._queuedFetches.length; i++){
@@ -351,11 +355,11 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	},
 
 /***************************************
-     dojo.data.api.Identity API
+     dojo/data/api/Identity API
 ***************************************/
 	getIdentity: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Identity.getIdentity()
+		// summary:
+		//		See dojo/data/api/Identity.getIdentity()
 		if(this.isItem(item)){
 			return item[this._keyAttribute]; //String
 		}
@@ -363,14 +367,14 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Identity.getIdentifierAttributes()
+		// summary:
+		//		See dojo/data/api/Identity.getIdentifierAttributes()
 		return [this._keyAttribute];
 	},
 
 	fetchItemByIdentity: function(/* object */ keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Identity.fetchItemByIdentity()
+		// summary:
+		//		See dojo/data/api/Identity.fetchItemByIdentity()
 		keywordArgs.oldOnItem = keywordArgs.onItem;
 		keywordArgs.onItem = null;
 		keywordArgs.onComplete = this._finishFetchItemByIdentity ;
@@ -378,7 +382,7 @@ var KeyValueStore = declare("dojox.data.KeyValueStore", null, {
 	},
 	
 	_finishFetchItemByIdentity: function(/* Array */ items, /* object */ request){
-		var scope = request.scope || winUtil.global;
+		var scope = request.scope || kernel.global;
 		if(items.length){
 			request.oldOnItem.call(scope, items[0]);
 		}else{
diff --git a/dojox/data/OpenSearchStore.js b/dojox/data/OpenSearchStore.js
index 93a4e71..09ebd40 100644
--- a/dojox/data/OpenSearchStore.js
+++ b/dojox/data/OpenSearchStore.js
@@ -1,7 +1,7 @@
 define([
 	"dojo/_base/kernel", // dojo.experimental
 	"dojo/_base/lang", // dojo.extend
-	"dojo/_base/declare", // dojo.declare
+	"dojo/_base/declare", // declare
 	"dojo/_base/xhr", // dojo.xhrGet
 	"dojo/_base/array", // dojo.forEach
 	"dojo/_base/window", // dojo.doc
@@ -12,9 +12,9 @@ kernel.experimental("dojox.data.OpenSearchStore");
 
 var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	constructor: function(/*Object*/args){
-		//	summary:
+		// summary:
 		//		Initializer for the OpenSearchStore store.
-		//	description:
+		// description:
 		//		The OpenSearchStore is a Datastore interface to any search
 		//		engine that implements the open search specifications.
 		if(args){
@@ -44,8 +44,8 @@ var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	urlElement: null,
 	iframeElement: null,
 
-	//urlPreventCache: boolean
-	//Flag denoting if xhrGet calls should use the preventCache option.
+	// urlPreventCache: boolean
+	//		Flag denoting if xhrGet calls should use the preventCache option.
 	urlPreventCache: true,
 	
 	ATOM_CONTENT_TYPE: 3,
@@ -56,9 +56,9 @@ var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	XML_CONTENT_TYPE_STRING: "xml",
 
 	_assertIsItem: function(/* item */ item){
-		//	summary:
-		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item:
+		// summary:
+		//		This function tests whether the item passed in is indeed an item in the store.
+		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
 			throw new Error("dojox.data.OpenSearchStore: a function was passed an item argument that was not an item");
@@ -66,9 +66,9 @@ var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
-		//	summary:
+		// summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+		// attribute:
 		//		The attribute to test for being contained by the store.
 		if(typeof attribute !== "string"){
 			throw new Error("dojox.data.OpenSearchStore: a function was passed an attribute argument that was not an attribute name string");
@@ -76,16 +76,16 @@ var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	getFeatures: function(){
-		//	summary:
-		//      See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true
 		};
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary:
-		//      See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		var values = this.getValues(item, attribute);
 		if(values){
 			return values[0];
@@ -94,14 +94,14 @@ var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	getAttributes: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.getAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		return ["content"];
 	},
 
 	hasAttribute: function(item, attribute){
-		//	summary:
-		//      See dojo.data.api.Read.hasAttributes()
+		// summary:
+		//		See dojo/data/api/Read.hasAttributes()
 		if(this.getValue(item,attribute)){
 			return true;
 		}
@@ -109,31 +109,31 @@ var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	isItemLoaded: function(item){
-		 //	summary:
-		 //      See dojo.data.api.Read.isItemLoaded()
-		 return this.isItem(item);
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded()
+		return this.isItem(item);
 	},
 
 	loadItem: function(keywordArgs){
-		//	summary:
-		//      See dojo.data.api.Read.loadItem()
+		// summary:
+		//		See dojo/data/api/Read.loadItem()
 	},
 
 	getLabel: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.getLabel()
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		return undefined;
 	},
 	
 	getLabelAttributes: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.getLabelAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return null;
 	},
 
 	containsValue: function(item, attribute, value){
-		//	summary:
-		//      See dojo.data.api.Read.containsValue()
+		// summary:
+		//		See dojo/data/api/Read.containsValue()
 		var values = this.getValues(item,attribute);
 		for(var i = 0; i < values.length; i++){
 			if(values[i] === value){
@@ -144,8 +144,8 @@ var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	getValues: function(item, attribute){
-		//	summary:
-		//      See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -157,8 +157,8 @@ var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	isItem: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.isItem()
+		// summary:
+		//		See dojo/data/api/Read.isItem()
 		if(item && item[this._storeRef] === this){
 			return true;
 		}
@@ -166,8 +166,8 @@ var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	},
 	
 	close: function(request){
-		//	summary:
-		//      See dojo.data.api.Read.close()
+		// summary:
+		//		See dojo/data/api/Read.close()
 	},
 	
 	process: function(data){
@@ -203,13 +203,13 @@ var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	_fetchItems: function(request, fetchHandler, errorHandler){
-		//	summary:
+		// summary:
 		//		Fetch OpenSearch items that match to a query
-		//	request:
+		// request:
 		//		A request object
-		//	fetchHandler:
+		// fetchHandler:
 		//		A function to call for fetched items
-		//	errorHandler:
+		// errorHandler:
 		//		A function to call on error
 
 		if(!request.query){
@@ -369,4 +369,4 @@ var OpenSearchStore = declare("dojox.data.OpenSearchStore", null, {
 	}
 });
 return lang.extend(OpenSearchStore,simpleFetch);
-});
\ No newline at end of file
+});
diff --git a/dojox/data/OpmlStore.js b/dojox/data/OpmlStore.js
index 22d8913..9fee3e0 100644
--- a/dojox/data/OpmlStore.js
+++ b/dojox/data/OpmlStore.js
@@ -1,19 +1,21 @@
 define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/xhr", "dojo/data/util/simpleFetch", "dojo/data/util/filter",
-		"dojo/_base/window"], 
-  function(declare, lang, xhr, simpleFetch, filterUtil, winUtil) {
+		"dojo/_base/kernel"],
+  function(declare, lang, xhr, simpleFetch, filterUtil, kernel) {
 
 var OpmlStore = declare("dojox.data.OpmlStore", null, {
-	/* summary:
-	 *   The OpmlStore implements the dojo.data.api.Read API.
-	 */
-	 
-	/* examples:
-	 *   var opmlStore = new dojo.data.OpmlStore({url:"geography.xml"});
-	 *   var opmlStore = new dojo.data.OpmlStore({url:"http://example.com/geography.xml"});
-	 */
+	// summary:
+	//		The OpmlStore implements the dojo/data/api/Read API.
+	// examples:
+	//	|	var opmlStore = new dojo.data.OpmlStore({url:"geography.xml"});
+	//	|	var opmlStore = new dojo.data.OpmlStore({url:"http://example.com/geography.xml"});
+
 	constructor: function(/* Object */ keywordParameters){
-		// summary: constructor
-		// keywordParameters: {url: String, label: String}  Where label is optional and configures what should be used as the return from getLabel()
+		// summary:
+		//		constructor
+		// keywordParameters:
+		//		- {url: String, label: String}
+		//
+		//		Where label is optional and configures what should be used as the return from getLabel()
 		this._xmlData = null;
 		this._arrayOfTopLevelItems = [];
 		this._arrayOfAllItems = [];
@@ -52,10 +54,10 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 		}
 	},
 	
-	_assertIsAttribute: function(/* item || String */ attribute){
-		//	summary:
-		//      This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+	_assertIsAttribute: function(/*dojo/data/api/Item|String */ attribute){
+		// summary:
+		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
+		// attribute:
 		//		The attribute to test for being contained by the store.
 		if(!lang.isString(attribute)){
 			throw new Error("dojox.data.OpmlStore: a function was passed an attribute argument that was not an attribute object nor an attribute name string");
@@ -116,14 +118,13 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 
 	_checkChildNodes: function(node /*Node*/){
-		//	summary:
+		// summary:
 		//		Internal function to recurse over all child nodes from the store and add them
 		//		As non-toplevel items
-		//	description:
+		// description:
 		//		Internal function to recurse over all child nodes from the store and add them
 		//		As non-toplevel items
-		//
-		//	node:
+		// node:
 		//		The child node to walk.
 		if(node.firstChild){
 			for(var i = 0; i < node.childNodes.length; i++){
@@ -139,9 +140,9 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 
 	_getItemsArray: function(/*object?*/queryOptions){
-		//	summary:
+		// summary:
 		//		Internal function to determine which list of items to search over.
-		//	queryOptions: The query options parameter, if any.
+		// queryOptions: The query options parameter, if any.
 		if(queryOptions && queryOptions.deep){
 			return this._arrayOfAllItems;
 		}
@@ -149,13 +150,13 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 
 /***************************************
-     dojo.data.api.Read API
+     dojo/data/api/Read API
 ***************************************/
 	getValue: function( /* item */ item,
-						/* attribute || attribute-name-string */ attribute,
+						/* attribute|attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		//	summary:
-		//      See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		if(attribute == 'children'){
@@ -167,9 +168,9 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 	
 	getValues: function(/* item */ item,
-						/* attribute || attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.getValues()
+						/* attribute|attribute-name-string */ attribute){
+		// summary:
+		//		See dojo/data/api/Read.getValues()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		var array = [];
@@ -184,8 +185,8 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 	
 	getAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
 		var xmlNode = item;
@@ -201,17 +202,17 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 	
 	hasAttribute: function( /* item */ item,
-							/* attribute || attribute-name-string */ attribute){
-		//	summary:
-		//		See dojo.data.api.Read.hasAttribute()
+							/* attribute|attribute-name-string */ attribute){
+		// summary:
+		//		See dojo/data/api/Read.hasAttribute()
 		return (this.getValues(item, attribute).length > 0); //Boolean
 	},
 	
 	containsValue: function(/* item */ item,
-							/* attribute || attribute-name-string */ attribute,
+							/* attribute|attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary:
-		//		See dojo.data.api.Read.containsValue()
+		// summary:
+		//		See dojo/data/api/Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
 			regexp = filterUtil.patternToRegExp(value, false);
@@ -220,23 +221,22 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 
 	_containsValue: function(	/* item */ item,
-								/* attribute || attribute-name-string */ attribute,
+								/* attribute|attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary:
+		// summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description:
+		// description:
 		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//
-		//	item:
+		// item:
 		//		The data item to examine for attribute values.
-		//	attribute:
+		// attribute:
 		//		The attribute to inspect.
-		//	value:
+		// value:
 		//		The value to match.
-		//	regexp:
+		// regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
 		//		If present and attribute values are string, then it can be used for comparison instead of 'value'
 		var values = this.getValues(item, attribute);
@@ -255,9 +255,9 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 			
 	isItem: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItem()
-		//	description:
+		// summary:
+		//		See dojo/data/api/Read.isItem()
+		// description:
 		//		Four things are verified to ensure that "something" is an item:
 		//		something can not be null, the nodeType must be an XML Element,
 		//		the tagName must be "outline", and the node must be a member of
@@ -269,25 +269,27 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 	
 	isItemLoaded: function(/* anything */ something){
-		//	summary:
-		//		See dojo.data.api.Read.isItemLoaded()
-		// 		OpmlStore loads every item, so if it's an item, then it's loaded.
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded().
+		//		OpmlStore loads every item, so if it's an item, then it's loaded.
 		return this.isItem(something); //Boolean
 	},
 	
 	loadItem: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.loadItem()
-		//	description:
+		// summary:
+		//		See dojo/data/api/Read.loadItem()
+		// description:
 		//		The OpmlStore always loads all items, so if it's an item, then it's loaded.
-		//		From the dojo.data.api.Read.loadItem docs:
+		//
+		//		From the dojo/data/api/Read.loadItem docs:
+		//
 		//			If a call to isItemLoaded() returns true before loadItem() is even called,
 		//			then loadItem() need not do any work at all and will not even invoke the callback handlers.
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		if(this.isItem(item)){
 			return this.getValue(item,this.label); //String
 		}
@@ -295,18 +297,18 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return [this.label]; //array
 	},
 
-	// The dojo.data.api.Read.fetch() function is implemented as
+	// The dojo/data/api/Read.fetch() function is implemented as
 	// a mixin from dojo.data.util.simpleFetch.
 	// That mixin requires us to define _fetchItems().
 	_fetchItems: function(	/* Object */ keywordArgs,
 							/* Function */ findCallback,
 							/* Function */ errorCallback){
-		//	summary:
+		// summary:
 		//		See dojo.data.util.simpleFetch.fetch()
 		
 		var self = this;
@@ -387,7 +389,8 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 	
 	getFeatures: function(){
-		// summary: See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		var features = {
 			'dojo.data.api.Read': true,
 			'dojo.data.api.Identity': true
@@ -396,13 +399,13 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 
 /***************************************
-     dojo.data.api.Identity API
+     dojo/data/api/Identity API
 ***************************************/
 	getIdentity: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Identity.getIdentity()
+		// summary:
+		//		See dojo/data/api/Identity.getIdentity()
 		if(this.isItem(item)){
-			//No ther way to do this other than O(n) without
+			//No other way to do this other than O(n) without
 			//complete rework of how the tree stores nodes.
 			for(var i in this._identityMap){
 				if(this._identityMap[i] === item){
@@ -414,8 +417,8 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 	},
 
 	fetchItemByIdentity: function(/* Object */ keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Identity.fetchItemByIdentity()
+		// summary:
+		//		See dojo/data/api/Identity.fetchItemByIdentity()
 
 		//Hasn't loaded yet, we have to trigger the load.
 		if(!this._loadFinished){
@@ -434,7 +437,7 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 						};
 					var getHandler = xhr.get(getArgs);
 					getHandler.addCallback(function(data){
-						var scope = keywordArgs.scope ? keywordArgs.scope : winUtil.global;
+						var scope = keywordArgs.scope ? keywordArgs.scope : kernel.global;
 						try{
 							self._processRawXmlTree(data);
 							var item = self._identityMap[keywordArgs.identity];
@@ -454,7 +457,7 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 					getHandler.addErrback(function(error){
 						this._loadInProgress = false;
 						if(keywordArgs.onError){
-							var scope = keywordArgs.scope ? keywordArgs.scope : winUtil.global;
+							var scope = keywordArgs.scope ? keywordArgs.scope : kernel.global;
 							keywordArgs.onError.call(scope, error);
 						}
 					});
@@ -467,7 +470,7 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 					item = null;
 				}
 				if(keywordArgs.onItem){
-					var scope = keywordArgs.scope ? keywordArgs.scope : winUtil.global;
+					var scope = keywordArgs.scope ? keywordArgs.scope : kernel.global;
 					keywordArgs.onItem.call(scope, item);
 				}
 			}
@@ -478,24 +481,25 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 				item = null;
 			}
 			if(keywordArgs.onItem){
-				var scope = keywordArgs.scope ? keywordArgs.scope : winUtil.global;
+				var scope = keywordArgs.scope ? keywordArgs.scope : kernel.global;
 				keywordArgs.onItem.call(scope, item);
 			}
 		}
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		 //	summary:
-		 //		See dojo.data.api.Identity.getIdentifierAttributes()
-		 
-		 //Identity isn't a public attribute in the item, it's the node count.
-		 //So, return null.
-		 return null;
+		// summary:
+		//		See dojo/data/api/Identity.getIdentifierAttributes()
+
+		//Identity isn't a public attribute in the item, it's the node count.
+		//So, return null.
+		return null;
 	},
 
 	_handleQueuedFetches: function(){
-		//	summary:
+		// summary:
 		//		Internal function to execute delayed request in the store.
+		
 		//Execute any deferred fetches now.
 		if(this._queuedFetches.length > 0){
 			for(var i = 0; i < this._queuedFetches.length; i++){
@@ -512,9 +516,9 @@ var OpmlStore = declare("dojox.data.OpmlStore", null, {
 		}
 	},
 
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		 //	summary:
-		 //		See dojo.data.api.Read.close()
+	close: function(/*dojo/data/api/Request|Object?*/ request){
+		// summary:
+		//		See dojo/data/api/Read.close()
 	}
 });
 //Mix in the simple fetch implementation to this class.
diff --git a/dojox/data/PersevereStore.js b/dojox/data/PersevereStore.js
index eea68d7..b194a5c 100644
--- a/dojox/data/PersevereStore.js
+++ b/dojox/data/PersevereStore.js
@@ -4,24 +4,24 @@ define(["dojo", "dojox", "require", "dojox/data/JsonQueryRestStore", "dojox/rpc/
 
 dojox.json.ref.serializeFunctions = true; // Persevere supports persisted functions
 
-dojo.declare("dojox.data.PersevereStore",dojox.data.JsonQueryRestStore,{
+var PersevereStore = dojo.declare("dojox.data.PersevereStore", dojox.data.JsonQueryRestStore, {
 	useFullIdInQueries: true, // in JSONQuerys use the full id
 	jsonQueryPagination: false // use the Range headers instead
 });
 
-dojox.data.PersevereStore.getStores = function(/*String?*/path,/*Boolean?*/sync){
+PersevereStore.getStores = function(/*String?*/ path,/*Boolean?*/ sync){
 	// summary:
 	//		Creates Dojo data stores for all the table/classes on a Persevere server
 	// path:
-	// 		URL of the Persevere server's root, this normally just "/"
-	// 		which is the default value if the target is not provided
+	//		URL of the Persevere server's root, this normally just "/"
+	//		which is the default value if the target is not provided
 	// sync:
-	// 		Indicates that the operation should happen synchronously.
-	// return:
-	// 		A map/object of datastores will be returned if it is performed asynchronously,
-	// 		otherwise it will return a Deferred object that will provide the map/object.
-	// 		The name of each property is a the name of a store,
-	// 		and the value is the actual data store object.
+	//		Indicates that the operation should happen synchronously.
+	// returns:
+	//		A map/object of datastores will be returned if it is performed asynchronously,
+	//		otherwise it will return a Deferred object that will provide the map/object.
+	//		The name of each property is a the name of a store,
+	//		and the value is the actual data store object.
 	path = (path && (path.match(/\/$/) ? path : (path + '/'))) || '/';
 	if(path.match(/^\w*:\/\//)){
 		// if it is cross-domain, we will use window.name for communication
@@ -32,7 +32,7 @@ dojox.data.PersevereStore.getStores = function(/*String?*/path,/*Boolean?*/sync)
 	dojo.xhr = function(method,args){
 		(args.headers = args.headers || {})['Server-Methods'] = "false";
 		return plainXhr.apply(dojo,arguments);
-	}
+	};
 	var rootService= dojox.rpc.Rest(path,true);
 	dojox.rpc._sync = sync;
 	var dfd = rootService("Class/");//dojo.xhrGet({url: target, sync:!callback, handleAs:'json'});
@@ -100,13 +100,13 @@ dojox.data.PersevereStore.getStores = function(/*String?*/path,/*Boolean?*/sync)
 	dojo.xhr = plainXhr;
 	return sync ? results : dfd;
 };
-dojox.data.PersevereStore.addProxy = function(){
+PersevereStore.addProxy = function(){
 	// summary:
 	//		Invokes the XHR proxy plugin. Call this if you will be using x-site data.
 	require("dojox/io/xhrPlugins"); // also not necessary, but we can register that Persevere supports proxying
 	dojox.io.xhrPlugins.addProxy("/proxy/");
 };
 
-return dojox.data.PersevereStore;
+return PersevereStore;
 
 });
diff --git a/dojox/data/PicasaStore.js b/dojox/data/PicasaStore.js
index ce9d892..62cd165 100644
--- a/dojox/data/PicasaStore.js
+++ b/dojox/data/PicasaStore.js
@@ -3,9 +3,9 @@ define(["dojo/_base/lang","dojo/_base/declare", "dojo/_base/connect", "dojo/io/s
 
 var PicasaStore = declare("dojox.data.PicasaStore", null, {
 	constructor: function(/*Object*/args){
-		//	summary:
+		// summary:
 		//		Initializer for the PicasaStore store.
-		//	description:
+		// description:
 		//		The PicasaStore is a Datastore interface to one of the basic services
 		//		of the Picasa service, the public photo feed.  This does not provide
 		//		access to all the services of Picasa.
@@ -29,21 +29,22 @@ var PicasaStore = declare("dojox.data.PicasaStore", null, {
 
 	_storeRef: "_S",
 
-	//label: string
-	//The attribute to use from the picasa item as its label.
+	// label: string
+	//		The attribute to use from the picasa item as its label.
 	label: "title",
 
-	//urlPreventCache: boolean
-	//Flag denoting if preventCache should be passed to io.script.
+	// urlPreventCache: boolean
+	//		Flag denoting if preventCache should be passed to io.script.
 	urlPreventCache: false,
 
-	//maxResults:  Define out how many results to return for a fetch.
+	// maxResults: Number
+	//		Define out how many results to return for a fetch.
 	maxResults: 20,
 
 	_assertIsItem: function(/* item */ item){
-		//	summary:
-		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item:
+		// summary:
+		//		This function tests whether the item passed in is indeed an item in the store.
+		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
 			throw new Error("dojox.data.PicasaStore: a function was passed an item argument that was not an item");
@@ -51,9 +52,9 @@ var PicasaStore = declare("dojox.data.PicasaStore", null, {
 	},
 
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
-		//	summary:
+		// summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+		// attribute:
 		//		The attribute to test for being contained by the store.
 		if(typeof attribute !== "string"){
 			throw new Error("dojox.data.PicasaStore: a function was passed an attribute argument that was not an attribute name string");
@@ -61,16 +62,16 @@ var PicasaStore = declare("dojox.data.PicasaStore", null, {
 	},
 
 	getFeatures: function(){
-		//	summary:
-		//      See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true
 		};
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary:
-		//      See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		var values = this.getValues(item, attribute);
 		if(values && values.length > 0){
 			return values[0];
@@ -79,17 +80,17 @@ var PicasaStore = declare("dojox.data.PicasaStore", null, {
 	},
 
 	getAttributes: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.getAttributes()
-		 return ["id", "published", "updated", "category", "title$type", "title",
-			 "summary$type", "summary", "rights$type", "rights", "link", "author",
-			 "gphoto$id", "gphoto$name", "location", "imageUrlSmall", "imageUrlMedium",
-			 "imageUrl", "datePublished", "dateTaken","description"];
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
+		return ["id", "published", "updated", "category", "title$type", "title",
+			"summary$type", "summary", "rights$type", "rights", "link", "author",
+			"gphoto$id", "gphoto$name", "location", "imageUrlSmall", "imageUrlMedium",
+			"imageUrl", "datePublished", "dateTaken","description"];
 	},
 
 	hasAttribute: function(item, attribute){
-		//	summary:
-		//      See dojo.data.api.Read.hasAttributes()
+		// summary:
+		//		See dojo/data/api/Read.hasAttributes()
 		if(this.getValue(item,attribute)){
 			return true;
 		}
@@ -97,31 +98,31 @@ var PicasaStore = declare("dojox.data.PicasaStore", null, {
 	},
 
 	isItemLoaded: function(item){
-		 //	summary:
-		 //      See dojo.data.api.Read.isItemLoaded()
-		 return this.isItem(item);
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded()
+		return this.isItem(item);
 	},
 
 	loadItem: function(keywordArgs){
-		//	summary:
-		//      See dojo.data.api.Read.loadItem()
+		// summary:
+		//		See dojo/data/api/Read.loadItem()
 	},
 
 	getLabel: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.getLabel()
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		return this.getValue(item,this.label);
 	},
 	
 	getLabelAttributes: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.getLabelAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return [this.label];
 	},
 
 	containsValue: function(item, attribute, value){
-		//	summary:
-		//      See dojo.data.api.Read.containsValue()
+		// summary:
+		//		See dojo/data/api/Read.containsValue()
 		var values = this.getValues(item,attribute);
 		for(var i = 0; i < values.length; i++){
 			if(values[i] === value){
@@ -132,8 +133,8 @@ var PicasaStore = declare("dojox.data.PicasaStore", null, {
 	},
 
 	getValues: function(item, attribute){
-		//	summary:
-		//      See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -164,8 +165,8 @@ var PicasaStore = declare("dojox.data.PicasaStore", null, {
 	},
 
 	isItem: function(item){
-		//	summary:
-		//      See dojo.data.api.Read.isItem()
+		// summary:
+		//		See dojo/data/api/Read.isItem()
 		if(item && item[this._storeRef] === this){
 			return true;
 		}
@@ -173,18 +174,18 @@ var PicasaStore = declare("dojox.data.PicasaStore", null, {
 	},
 	
 	close: function(request){
-		//	summary:
-		//      See dojo.data.api.Read.close()
+		// summary:
+		//		See dojo/data/api/Read.close()
 	},
 
 	_fetchItems: function(request, fetchHandler, errorHandler){
-		//	summary:
+		// summary:
 		//		Fetch picasa items that match to a query
-		//	request:
+		// request:
 		//		A request object
-		//	fetchHandler:
+		// fetchHandler:
 		//		A function to call for fetched items
-		//	errorHandler:
+		// errorHandler:
 		//		A function to call on error
 
 		if(!request.query){
@@ -252,13 +253,16 @@ var PicasaStore = declare("dojox.data.PicasaStore", null, {
 	},
 
 	_unescapeHtml: function(str){
-		// summary: Utility function to un-escape XML special characters in an HTML string.
-		// description: Utility function to un-escape XML special characters in an HTML string.
-		// str: String.
-		//   The string to un-escape
-		// returns: HTML String converted back to the normal text (unescaped) characters (<,>,&, ", etc,).
-		//
-		//TODO: Check to see if theres already compatible escape() in dojo.string or dojo.html
+		// summary:
+		//		Utility function to un-escape XML special characters in an HTML string.
+		// description:
+		//		Utility function to un-escape XML special characters in an HTML string.
+		// str: String
+		//		The string to un-escape
+		// returns:
+		//		HTML String converted back to the normal text (unescaped) characters (<,>,&, ", etc,).
+
+		// TODO: Check to see if theres already compatible escape() in dojo.string or dojo.html
 		if(str){
 			str = str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, "\"");
 			str = str.replace(/'/gm, "'");
diff --git a/dojox/data/QueryReadStore.js b/dojox/data/QueryReadStore.js
index 0efa0bc..8b8fa7c 100644
--- a/dojox/data/QueryReadStore.js
+++ b/dojox/data/QueryReadStore.js
@@ -1,26 +1,24 @@
 define(["dojo", "dojox", "dojo/data/util/sorter", "dojo/string"], function(dojo, dojox) {
 
-dojo.declare("dojox.data.QueryReadStore",
-	null,
-	{
-		//	summary:
+	return dojo.declare("dojox.data.QueryReadStore", null, {
+		// summary:
 		//		This class provides a store that is mainly intended to be used
 		//		for loading data dynamically from the server, used i.e. for
-		//		retreiving chunks of data from huge data stores on the server (by server-side filtering!).
+		//		retrieving chunks of data from huge data stores on the server (by server-side filtering!).
 		//		Upon calling the fetch() method of this store the data are requested from
 		//		the server if they are not yet loaded for paging (or cached).
 		//
 		//		For example used for a combobox which works on lots of data. It
-		//		can be used to retreive the data partially upon entering the
+		//		can be used to retrieve the data partially upon entering the
 		//		letters "ac" it returns only items like "action", "acting", etc.
 		//
-		// note:
+		//		note:
 		//		The field name "id" in a query is reserved for looking up data
 		//		by id. This is necessary as before the first fetch, the store
 		//		has no way of knowing which field the server will declare as
 		//		identifier.
 		//
-		//	example:
+		// example:
 		// |	// The parameter "query" contains the data that are sent to the server.
 		// |	var store = new dojox.data.QueryReadStore({url:'/search.php'});
 		// |	store.fetch({query:{name:'a'}, queryOptions:{ignoreCase:false}});
@@ -43,9 +41,8 @@ dojo.declare("dojox.data.QueryReadStore",
 		// |		model="model2"
 		// |		structure="gridLayout"
 		// |		style="height:300px; width:800px;"></div>
-	
-		//
-		//	todo:
+
+		// todo:
 		//		- there is a bug in the paging, when i set start:2, count:5 after an initial fetch() and doClientPaging:true
 		//		  it returns 6 elemetns, though count=5, try it in QueryReadStore.html
 		//		- add optional caching
@@ -64,9 +61,9 @@ dojo.declare("dojox.data.QueryReadStore",
 		// This will contain the items we have loaded from the server.
 		// The contents of this array is optimized to satisfy all read-api requirements
 		// and for using lesser storage, so the keys and their content need some explaination:
-		// 		this._items[0].i - the item itself
+		//		this._items[0].i - the item itself
 		//		this._items[0].r - a reference to the store, so we can identify the item
-		//			securly. We set this reference right after receiving the item from the
+		//			securely. We set this reference right after receiving the item from the
 		//			server.
 		_items:[],
 		
@@ -83,11 +80,11 @@ dojo.declare("dojox.data.QueryReadStore",
 		// client-side-paging.
 		lastRequestHash:null,
 		
-		// summary:
+		// doClientPaging: Boolean
 		//		By default every request for paging is sent to the server.
 		doClientPaging:false,
 	
-		// summary:
+		// doClientSorting: Boolean
 		//		By default all the sorting is done serverside before the data is returned
 		//		which is the proper place to be doing it for really large datasets.
 		doClientSorting:false,
@@ -142,8 +139,8 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 	
 		hasAttribute: function(/* item */ item,	/* attribute-name-string */ attribute){
-			//	summary:
-			//		See dojo.data.api.Read.hasAttribute()
+			// summary:
+			//		See dojo/data/api/Read.hasAttribute()
 			return this.isItem(item) && typeof item.i[attribute]!="undefined";
 		},
 		
@@ -175,7 +172,7 @@ dojo.declare("dojox.data.QueryReadStore",
 			// >>> var store = new dojox.data.QueryReadStore({});
 			// >>> store.isItem({name:"me", label:"me too"});
 			// false
-			//
+
 			if(something){
 				return typeof something.r != "undefined" && something.r == this;
 			}
@@ -197,7 +194,7 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 	
 		fetch:function(/* Object? */ request){
-			//	summary:
+			// summary:
 			//		See dojo.data.util.simpleFetch.fetch() this is just a copy and I adjusted
 			//		only the paging, since it happens on the server if doClientPaging is
 			//		false, thx to http://trac.dojotoolkit.org/ticket/4761 reporting this.
@@ -268,13 +265,13 @@ dojo.declare("dojox.data.QueryReadStore",
 			return this._features;
 		},
 	
-		close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
+		close: function(/*dojo/data/api/Request|Object?*/ request){
 			// I have no idea if this is really needed ...
 		},
 	
 		getLabel: function(/* item */ item){
-			//	summary:
-			//		See dojo.data.api.Read.getLabel()
+			// summary:
+			//		See dojo/data/api/Read.getLabel()
 			if(this._labelAttr && this.isItem(item)){
 				return this.getValue(item, this._labelAttr); //String
 			}
@@ -282,8 +279,8 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 	
 		getLabelAttributes: function(/* item */ item){
-			//	summary:
-			//		See dojo.data.api.Read.getLabelAttributes()
+			// summary:
+			//		See dojo/data/api/Read.getLabelAttributes()
 			if(this._labelAttr){
 				return [this._labelAttr]; //array
 			}
@@ -334,14 +331,16 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 		
 		_fetchItems: function(request, fetchHandler, errorHandler){
-			//	summary:
-			// 		The request contains the data as defined in the Read-API.
-			// 		Additionally there is following keyword "serverQuery".
+			// summary:
+			//		The request contains the data as defined in the Read-API.
+			//		Additionally there is following keyword "serverQuery".
+			//
+			//		####The *serverQuery* parameter, optional.
 			//
-			//	The *serverQuery* parameter, optional.
 			//		This parameter contains the data that will be sent to the server.
 			//		If this parameter is not given the parameter "query"'s
 			//		data are sent to the server. This is done for some reasons:
+			//
 			//		- to specify explicitly which data are sent to the server, they
 			//		  might also be a mix of what is contained in "query", "queryOptions"
 			//		  and the paging parameters "start" and "count" or may be even
@@ -351,17 +350,16 @@ dojo.declare("dojox.data.QueryReadStore",
 			//		  does it, it compares if the query has changed
 			//		- request.query is required by the Read-API
 			//
-			// 		I.e. the following examples might be sent via GET:
-			//		  fetch({query:{name:"abc"}, queryOptions:{ignoreCase:true}})
+			//		I.e. the following examples might be sent via GET:
+			//	|	  fetch({query:{name:"abc"}, queryOptions:{ignoreCase:true}})
 			//		  the URL will become:   /url.php?name=abc
 			//
-			//		  fetch({serverQuery:{q:"abc", c:true}, query:{name:"abc"}, queryOptions:{ignoreCase:true}})
+			//	|	  fetch({serverQuery:{q:"abc", c:true}, query:{name:"abc"}, queryOptions:{ignoreCase:true}})
 			//		  the URL will become:   /url.php?q=abc&c=true
-			//		  // The serverQuery-parameter has overruled the query-parameter
-			//		  // but the query parameter stays untouched, but is not sent to the server!
-			//		  // The serverQuery contains more data than the query, so they might differ!
-			//
-	
+			//	|	  // The serverQuery-parameter has overruled the query-parameter
+			//	|	  // but the query parameter stays untouched, but is not sent to the server!
+			//	|	  // The serverQuery contains more data than the query, so they might differ!
+
 			var serverQuery = request.serverQuery || request.query || {};
 			//Need to add start and count
 			if(!this.doClientPaging){
@@ -408,20 +406,20 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 		
 		_filterResponse: function(data){
-			//	summary:
+			// summary:
 			//		If the data from servers needs to be processed before it can be processed by this
 			//		store, then this function should be re-implemented in subclass. This default
 			//		implementation just return the data unchanged.
-			//	data:
+			// data:
 			//		The data received from server
 			return data;
 		},
 	
 		_assertIsItem: function(/* item */ item){
-			//	summary:
+			// summary:
 			//		It throws an error if item is not valid, so you can call it in every method that needs to
 			//		throw an error when item is invalid.
-			//	item:
+			// item:
 			//		The item to test for being contained by the store.
 			if(!this.isItem(item)){
 				throw new Error(this._className+": Invalid item argument.");
@@ -429,9 +427,9 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 	
 		_assertIsAttribute: function(/* attribute-name-string */ attribute){
-			//	summary:
+			// summary:
 			//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-			//	attribute:
+			// attribute:
 			//		The attribute to test for being contained by the store.
 			if(typeof attribute !== "string"){
 				throw new Error(this._className+": Invalid attribute argument ('"+attribute+"').");
@@ -439,8 +437,8 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 	
 		fetchItemByIdentity: function(/* Object */ keywordArgs){
-			//	summary:
-			//		See dojo.data.api.Identity.fetchItemByIdentity()
+			// summary:
+			//		See dojo/data/api/Identity.fetchItemByIdentity()
 	
 			// See if we have already loaded the item with that id
 			// In case there hasn't been a fetch yet, _itemsByIdentity is null
@@ -495,8 +493,8 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 		
 		getIdentity: function(/* item */ item){
-			//	summary:
-			//		See dojo.data.api.Identity.getIdentity()
+			// summary:
+			//		See dojo/data/api/Identity.getIdentity()
 			var identifier = null;
 			if(this._identifier === Number){
 				identifier = item.n; // Number
@@ -507,12 +505,10 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 		
 		getIdentityAttributes: function(/* item */ item){
-			//	summary:
-			//		See dojo.data.api.Identity.getIdentityAttributes()
+			// summary:
+			//		See dojo/data/api/Identity.getIdentityAttributes()
 			return [this._identifier];
 		}
-	}
-);
+	});
 
-return dojox.data.QueryReadStore;
 });
diff --git a/dojox/data/RailsStore.js b/dojox/data/RailsStore.js
index b573c2e..2495653 100644
--- a/dojox/data/RailsStore.js
+++ b/dojox/data/RailsStore.js
@@ -1,9 +1,9 @@
 define(["dojo", "dojox", "dojox/data/JsonRestStore"], function(dojo, dojox) {
 
 // Contains code donated by Travis Tilley under CLA
-dojo.declare("dojox.data.RailsStore", dojox.data.JsonRestStore, {
+return dojo.declare("dojox.data.RailsStore", dojox.data.JsonRestStore, {
 	constructor: function(){
-		//	summary:
+		// summary:
 		//		RailsStore is a data store for interacting with RESTful Rails controllers
 	},
 	preamble: function(options){
@@ -164,5 +164,4 @@ dojo.declare("dojox.data.RailsStore", dojox.data.JsonRestStore, {
 	}
 });
 
-return dojox.data.RailsStore;
 });
diff --git a/dojox/data/S3Store.js b/dojox/data/S3Store.js
index 10d7867..16c6ed7 100644
--- a/dojox/data/S3Store.js
+++ b/dojox/data/S3Store.js
@@ -1,11 +1,10 @@
 define(["dojo/_base/declare", "dojox/data/JsonRestStore", "dojox/rpc/ProxiedPath"], 
   function(declare, JsonRestStore, ProxiedPath) {
-
-// S3JsonRestStore is an extension of JsonRestStore to handle
-// Amazon's S3 service using JSON data
-/*===== var JsonRestStore = dojox.data.JsonRestStore =====*/
 return declare("dojox.data.S3Store", JsonRestStore,
 	{
+	// summary:
+	//		S3JsonRestStore is an extension of JsonRestStore to handle
+	//		Amazon's S3 service using JSON data
 		_processResults : function(results){
 			// unfortunately, S3 returns query results in XML form
 			var keyElements = results.getElementsByTagName("Key");
diff --git a/dojox/data/ServiceStore.js b/dojox/data/ServiceStore.js
index 29ff049..960a85f 100644
--- a/dojox/data/ServiceStore.js
+++ b/dojox/data/ServiceStore.js
@@ -1,77 +1,84 @@
-define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array"], 
-  function(declare, lang, array) {
-
-// note that dojox.rpc.Service is not required, you can create your own services
-
-// A ServiceStore is a readonly data store that provides a data.data interface to an RPC service.
-// var myServices = new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.tests.resources", "test.smd"));
-// var serviceStore = new dojox.data.ServiceStore({service:myServices.ServiceStore});
-//
-// The ServiceStore also supports lazy loading. References can be made to objects that have not been loaded.
-//	For example if a service returned:
-// {"name":"Example","lazyLoadedObject":{"$ref":"obj2"}}
-//
-// And this object has accessed using the dojo.data API:
-// var obj = serviceStore.getValue(myObject,"lazyLoadedObject");
-// The object would automatically be requested from the server (with an object id of "obj2").
-//
-
+define(["dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array"], function(declare, lang, array) {
 return declare("dojox.data.ServiceStore",
 	// ClientFilter is intentionally not required, ServiceStore does not need it, and is more
 	// lightweight without it, but if it is provided, the ServiceStore will use it.
 	lang.getObject("dojox.data.ClientFilter", 0)||null,{
+		// summary:
+		//		note that dojox.rpc.Service is not required, you can create your own services
+		//		A ServiceStore is a readonly data store that provides a data.data interface to an RPC service.
+		//		|		var myServices = new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.tests.resources", "test.smd"));
+		//		|		var serviceStore = new dojox.data.ServiceStore({service:myServices.ServiceStore});
+		//
+		//		The ServiceStore also supports lazy loading. References can be made to objects that have not been loaded.
+		//		For example if a service returned:
+		//		|		{"name":"Example","lazyLoadedObject":{"$ref":"obj2"}}
+		//
+		//		And this object has accessed using the dojo.data API:
+		//		|		var obj = serviceStore.getValue(myObject,"lazyLoadedObject");
+		//		The object would automatically be requested from the server (with an object id of "obj2").
+	
+	
+		// service: Object
+		//	This is the service object that is used to retrieve lazy data and save results
+		//	The function should be directly callable with a single parameter of an object id to be loaded
 		service: null,
+		
 		constructor: function(options){
-			//summary:
+			// summary:
 			//		ServiceStore constructor, instantiate a new ServiceStore
-			// 		A ServiceStore can be configured from a JSON Schema. Queries are just
-			// 		passed through to the underlying services
-			//
+			//		A ServiceStore can be configured from a JSON Schema. Queries are just
+			//		passed through to the underlying services
 			// options:
-			// 		Keyword arguments
-			// The *schema* parameter
+			//		Keyword arguments
+			//
+			//		####The *schema* parameter
+			//
 			//		This is a schema object for this store. This should be JSON Schema format.
 			//
-			// The *service* parameter
-			// 		This is the service object that is used to retrieve lazy data and save results
-			// 		The function should be directly callable with a single parameter of an object id to be loaded
+			//		####The *service* parameter
+			//
+			//		This is the service object that is used to retrieve lazy data and save results
+			//		The function should be directly callable with a single parameter of an object id to be loaded
+			//
+			//		####The *idAttribute* parameter
 			//
-			// The *idAttribute* parameter
 			//		Defaults to 'id'. The name of the attribute that holds an objects id.
 			//		This can be a preexisting id provided by the server.
 			//		If an ID isn't already provided when an object
 			//		is fetched or added to the store, the autoIdentity system
 			//		will generate an id for it and add it to the index.
 			//
-			// The *estimateCountFactor* parameter
-			// 		This parameter is used by the ServiceStore to estimate the total count. When
+			//		####The *estimateCountFactor* parameter
+			//
+			//		This parameter is used by the ServiceStore to estimate the total count. When
 			//		paging is indicated in a fetch and the response includes the full number of items
-			//	 	requested by the fetch's count parameter, then the total count will be estimated
+			//		requested by the fetch's count parameter, then the total count will be estimated
 			//		to be estimateCountFactor multiplied by the provided count. If this is 1, then it is assumed that the server
 			//		does not support paging, and the response is the full set of items, where the
-			// 		total count is equal to the numer of items returned. If the server does support
+			//		total count is equal to the number of items returned. If the server does support
 			//		paging, an estimateCountFactor of 2 is a good value for estimating the total count
 			//		It is also possible to override _processResults if the server can provide an exact
-			// 		total count.
+			//		total count.
+			//
+			//		####The *syncMode* parameter
 			//
-			// The *syncMode* parameter
 			//		Setting this to true will set the store to using synchronous calls by default.
 			//		Sync calls return their data immediately from the calling function, so
 			//		callbacks are unnecessary. This will only work with a synchronous capable service.
 			//
 			// description:
 			//		ServiceStore can do client side caching and result set updating if
-			// 		dojox.data.ClientFilter is loaded. Do this add:
+			//		dojox.data.ClientFilter is loaded. Do this add:
 			//	|	dojo.require("dojox.data.ClientFilter")
 			//		prior to loading the ServiceStore (ClientFilter must be loaded before ServiceStore).
 			//		To utilize client side filtering with a subclass, you can break queries into
 			//		client side and server side components by putting client side actions in
 			//		clientFilter property in fetch calls. For example you could override fetch:
 			//	|	fetch: function(args){
-				//	|		// do the sorting and paging on the client side
-	 			//	|		args.clientFilter = {start:args.start, count: args.count, sort: args.sort};
-	 			//	|		// args.query will be passed to the service object for the server side handling
-	 			//	|		return this.inherited(arguments);
+			//	|		// do the sorting and paging on the client side
+			//	|		args.clientFilter = {start:args.start, count: args.count, sort: args.sort};
+			//	|		// args.query will be passed to the service object for the server side handling
+			//	|		return this.inherited(arguments);
 			//	|	}
 			//		When extending this class, if you would like to create lazy objects, you can follow
 			//		the example from dojox.data.tests.stores.ServiceStore:
@@ -82,6 +89,7 @@ return declare("dojox.data.ServiceStore",
 			// |			callback(this);
 			// |		}
 			// |	};
+
 			//setup a byId alias to the api call
 			this.byId=this.fetchItemByIdentity;
 			this._index = {};
@@ -93,12 +101,43 @@ return declare("dojox.data.ServiceStore",
 			//	is supplied, it should be null so that auto identification takes place properly
 			this.idAttribute = (options && options.idAttribute) || (this.schema && this.schema._idAttr);
 		},
+		
+		// schema: 
+		//		This is a schema object for this store. This should be JSON Schema format.
 		schema: null,
+		
+		// idAttribute: String
+		//		Defaults to 'id'. The name of the attribute that holds an objects id.
+		//		This can be a preexisting id provided by the server.
+		//		If an ID isn't already provided when an object
+		//		is fetched or added to the store, the autoIdentity system
+		//		will generate an id for it and add it to the index.
+
 		idAttribute: "id",
 		labelAttribute: "label",
+		
+		// syncMode: Boolean
+		//		Setting this to true will set the store to using synchronous calls by default.
+		//		Sync calls return their data immediately from the calling function, so
+		//		callbacks are unnecessary. This will only work with a synchronous capable service.
 		syncMode: false,
+		
+		// estimateCountFactor:
+		//		This parameter is used by the ServiceStore to estimate the total count. When
+		//		paging is indicated in a fetch and the response includes the full number of items
+		//		requested by the fetch's count parameter, then the total count will be estimated
+		//		to be estimateCountFactor multiplied by the provided count. If this is 1, then it is assumed that the server
+		//		does not support paging, and the response is the full set of items, where the
+		//		total count is equal to the numer of items returned. If the server does support
+		//		paging, an estimateCountFactor of 2 is a good value for estimating the total count
+		//		It is also possible to override _processResults if the server can provide an exact
+		//		total count.	
 		estimateCountFactor: 1,
+		
 		getSchema: function(){
+			// summary:
+			//		Returns a reference to the JSON Schema
+			// returns: Object
 			return this.schema;
 		},
 
@@ -106,13 +145,12 @@ return declare("dojox.data.ServiceStore",
 
 		getValue: function(/*Object*/ item, /*String*/property, /*value?*/defaultValue){
 			// summary:
-			//	Gets the value of an item's 'property'
-			//
-			//	item:
+			//		Gets the value of an item's 'property'
+			// item:
 			//		The item to get the value from
-			//	property:
+			// property:
 			//		property to look up value for
-			//	defaultValue:
+			// defaultValue:
 			//		the default value
 
 			var value = item[property];
@@ -128,9 +166,8 @@ return declare("dojox.data.ServiceStore",
 			//		Gets the value of an item's 'property' and returns
 			//		it.	If this value is an array it is just returned,
 			//		if not, the value is added to an array and that is returned.
-			//
-			//	item: /* object */
-			//	property: /* string */
+			// item: Object
+			// property: String
 			//		property to look up value for
 
 			var val = this.getValue(item,property);
@@ -139,10 +176,9 @@ return declare("dojox.data.ServiceStore",
 
 		getAttributes: function(item){
 			// summary:
-			//	Gets the available attributes of an item's 'property' and returns
-			//	it as an array.
-			//
-			//	item: /* object */
+			//		Gets the available attributes of an item's 'property' and returns
+			//		it as an array.
+			// item: Object
 
 			var res = [];
 			for(var i in item){
@@ -156,19 +192,17 @@ return declare("dojox.data.ServiceStore",
 		hasAttribute: function(item,attribute){
 			// summary:
 			//		Checks to see if item has attribute
-			//
-			//	item: /* object */
-			//	attribute: /* string */
+			// item: Object
+			// attribute: String
 			return attribute in item;
 		},
 
 		containsValue: function(item, attribute, value){
 			// summary:
 			//		Checks to see if 'item' has 'value' at 'attribute'
-			//
-			//	item: /* object */
-			//	attribute: /* string */
-			//	value: /* anything */
+			// item: Object
+			// attribute: String
+			// value: Anything
 			return array.indexOf(this.getValues(item,attribute),value) > -1;
 		},
 
@@ -176,39 +210,34 @@ return declare("dojox.data.ServiceStore",
 		isItem: function(item){
 			// summary:
 			//		Checks to see if the argument is an item
-			//
-			//	item: /* object */
-			//	attribute: /* string */
+			// item: Object
 
 			// we have no way of determining if it belongs, we just have object returned from
-			// 	service queries
+			// service queries
 			return (typeof item == 'object') && item && !(item instanceof Date);
 		},
 
-		isItemLoaded: function(item){
+		isItemLoaded: function(/* object */ item){
 			// summary:
 			//		Checks to see if the item is loaded.
-			//
-			//		item: /* object */
 
 			return item && !item._loadObject;
 		},
 
 		loadItem: function(args){
 			// summary:
-			// 		Loads an item and calls the callback handler. Note, that this will call the callback
-			// 		handler even if the item is loaded. Consequently, you can use loadItem to ensure
-			// 		that an item is loaded is situations when the item may or may not be loaded yet.
-			// 		If you access a value directly through property access, you can use this to load
-			// 		a lazy value as well (doesn't need to be an item).
-			//
-			//	example:
-			//		store.loadItem({
-			//			item: item, // this item may or may not be loaded
-			//			onItem: function(item){
-			// 				// do something with the item
-			//			}
-			//		});
+			//		Loads an item and calls the callback handler. Note, that this will call the callback
+			//		handler even if the item is loaded. Consequently, you can use loadItem to ensure
+			//		that an item is loaded is situations when the item may or may not be loaded yet.
+			//		If you access a value directly through property access, you can use this to load
+			//		a lazy value as well (doesn't need to be an item).
+			// example:
+			//	|	store.loadItem({
+			//	|		item: item, // this item may or may not be loaded
+			//	|		onItem: function(item){
+			//	|			// do something with the item
+			//	|		}
+			//	|	});
 
 			var item;
 			if(args.item._loadObject){
@@ -269,16 +298,19 @@ return declare("dojox.data.ServiceStore",
 		},
 		fetch: function(args){
 			// summary:
-			//		See dojo.data.api.Read.fetch
+			//		See dojo/data/api/Read.fetch
+			// args:
+			//		####The *queryOptions.cache* parameter
 			//
-			// The *queryOptions.cache* parameter
 			//		If true, indicates that the query result should be cached for future use. This is only available
-			// 		if dojox.data.ClientFilter has been loaded before the ServiceStore
+			//		if dojox.data.ClientFilter has been loaded before the ServiceStore
+			//
+			//		####The *syncMode* parameter
 			//
-			//	The *syncMode* parameter
 			//		Indicates that the call should be fetch synchronously if possible (this is not always possible)
 			//
-			// The *clientFetch* parameter
+			//		####The *clientFetch* parameter
+			//
 			//		This is a fetch keyword argument for explicitly doing client side filtering, querying, and paging
 
 			args = args || {};
@@ -326,7 +358,7 @@ return declare("dojox.data.ServiceStore",
 		},
 		getFeatures: function(){
 			// summary:
-			// 		return the store feature set
+			//		return the store feature set
 
 			return {
 				"dojo.data.api.Read": true,
@@ -336,9 +368,9 @@ return declare("dojox.data.ServiceStore",
 		},
 
 		getLabel: function(item){
-			// summary
+			// summary:
 			//		returns the label for an item. Just gets the "label" attribute.
-			//
+
 			return this.getValue(item,this.labelAttribute);
 		},
 
diff --git a/dojox/data/SnapLogicStore.js b/dojox/data/SnapLogicStore.js
index b7b1da8..2cd1e47 100644
--- a/dojox/data/SnapLogicStore.js
+++ b/dojox/data/SnapLogicStore.js
@@ -1,6 +1,6 @@
 define(["dojo", "dojox", "dojo/io/script", "dojo/data/util/sorter"], function(dojo, dojox) {
 
-dojo.declare("dojox.data.SnapLogicStore", null, {
+return dojo.declare("dojox.data.SnapLogicStore", null, {
 	Parts: {
 		DATA: "data",
 		COUNT: "count"
@@ -9,18 +9,19 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	url: "",
 
 	constructor: function(/* Object */args){
-		//	summary:
+		// summary:
 		//		Initialize a SnapLogicStore object.
-		//	args:
+		// args:
 		//		An object that contains properties for initializing the new data store object. The
 		//		following properties are understood:
-		//			url:
-		//				A URL to the SnapLogic pipeline's output routed through PipeToHttp. Typically, this
-		//				will look like "http://<server-host>:<port>/pipe/<pipeline-url>/<pipeline-output-view>".
-		//			parameters:
-		//				An object whose properties define parameters to the pipeline. The values of these
-		//				properties will be sent to the pipeline as parameters when it run.
 		//
+		//		- url:
+		//			A URL to the SnapLogic pipeline's output routed through PipeToHttp. Typically, this
+		//			will look like `http://<server-host>:<port>/pipe/<pipeline-url>/<pipeline-output-view>`.
+		//		- parameters:
+		//			An object whose properties define parameters to the pipeline. The values of these
+		//			properties will be sent to the pipeline as parameters when it run.
+
 		if(args.url){
 			this.url = args.url;
 		}
@@ -28,19 +29,19 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 
 	_assertIsItem: function(/* item */item){
-		//	summary:
+		// summary:
 		//		This function tests whether the item passed in is indeed an item in the store.
-		//	item:
+		// item:
 		//		The item to test for being contained by the store.
 		if(!this.isItem(item)){
 			throw new Error("dojox.data.SnapLogicStore: a function was passed an item argument that was not an item");
 		}
 	},
 
-	_assertIsAttribute: function(/* attribute-name-string */ attribute){
-		//	summary:
+	_assertIsAttribute: function(/*attribute-name-string*/ attribute){
+		// summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute:
+		// attribute:
 		//		The attribute to test for being contained by the store.
 		if(typeof attribute !== "string"){
 			throw new Error("dojox.data.SnapLogicStore: a function was passed an attribute argument that was not an attribute name string");
@@ -48,16 +49,16 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 
 	getFeatures: function(){
-		//	summary:
-		//		See dojo.data.api.Read.getFeatures()
+		// summary:
+		//		See dojo/data/api/Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true
 		};
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary:
-		//		See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		var i = dojo.indexOf(item.attributes, attribute);
@@ -68,15 +69,15 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 
 	getAttributes: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.getAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getAttributes()
 		this._assertIsItem(item);
 		return item.attributes;
 	},
 
 	hasAttribute: function(item, attribute){
-		//	summary:
-		//		See dojo.data.api.Read.hasAttributes()
+		// summary:
+		//		See dojo/data/api/Read.hasAttributes()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		for(var i = 0; i < item.attributes.length; ++i){
@@ -88,37 +89,37 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 
 	isItemLoaded: function(item){
-		 //	summary:
-		 //		 See dojo.data.api.Read.isItemLoaded()
-		 return this.isItem(item);		// Boolean
+		// summary:
+		//		See dojo/data/api/Read.isItemLoaded()
+		return this.isItem(item);		// Boolean
 	},
 
 	loadItem: function(keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Read.loadItem()
+		// summary:
+		//		See dojo/data/api/Read.loadItem()
 	},
 
 	getLabel: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		return undefined;
 	},
 	
 	getLabelAttributes: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		return null;
 	},
 
 	containsValue: function(item, attribute, value){
-		//	summary:
-		//		See dojo.data.api.Read.containsValue()
+		// summary:
+		//		See dojo/data/api/Read.containsValue()
 		return this.getValue(item, attribute) === value;		// Boolean
 	},
 
 	getValues: function(item, attribute){
-		//	summary:
-		//		See dojo.data.api.Read.getValue()
+		// summary:
+		//		See dojo/data/api/Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		var i = dojo.indexOf(item.attributes, attribute);
@@ -129,8 +130,8 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 
 	isItem: function(item){
-		//	summary:
-		//		See dojo.data.api.Read.isItem()
+		// summary:
+		//		See dojo/data/api/Read.isItem()
 		if(item && item._store === this){
 			return true;
 		}
@@ -138,15 +139,15 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 	
 	close: function(request){
-		//	summary:
-		//		See dojo.data.api.Read.close()
+		// summary:
+		//		See dojo/data/api/Read.close()
 	},
 
-	_fetchHandler: function(/* Object */request){
-		//	summary:
+	_fetchHandler: function(/*Object*/ request){
+		// summary:
 		//		Process data retrieved via fetch and send it back to requester.
-		//	response:
-		//		The data returend from the I/O transport. In the normal case, it will be an array of result rows
+		// request:
+		//		The data returned from the I/O transport. In the normal case, it will be an array of result rows
 		//		from the pipeline. In the special case for record count optimization, response will be an array
 		//		with a single element containing the total pipeline result row count. See fetch() for details
 		//		on this optimization.
@@ -163,8 +164,8 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 
 			if(!response.length){
 				request.onError.call(scope,
-									 new Error("dojox.data.SnapLogicStore: invalid response of length 0"),
-									 request);
+									new Error("dojox.data.SnapLogicStore: invalid response of length 0"),
+									request);
 				return;
 			}else if(request.query != 'record count'){
 				//If this was not a record count request, the first element returned will contain
@@ -204,14 +205,14 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 		}
 	},
 		
-	_partHandler: function(/* Object */request, /* String */part, /* Object */response){
-		//	summary:
+	_partHandler: function(/*Object */ request, /* String */ part, /* Object*/ response){
+		// summary:
 		//		Handle the individual replies for both data and length requests.
-		//	request:
+		// request:
 		//		The request/handle object used with the original fetch() call.
-		//  part:
+		// part:
 		//		A value indicating which request this handler call is for (this.Parts).
-		//	response:
+		// response:
 		//		Response received from the underlying IO transport.
 
 		if(response instanceof Error){
@@ -240,11 +241,11 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 		}
 	},
 
-	fetch: function(/* Object */request){
-		//	summary:
-		//		See dojo.data.api.Read.close()
-		//	request:
-		//		See dojo.data.api.Read.close() for generic interface.
+	fetch: function(/*Object*/ request){
+		// summary:
+		//		See dojo/data/api/Read.close()
+		// request:
+		//		See dojo/data/api/Read.close() for generic interface.
 		//
 		//		In addition to the standard Read API fetch support, this store supports an optimization for
 		//		for retrieving the total count of records in the Pipeline without retrieving the data. To
@@ -323,6 +324,5 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	}
 });
 
-return dojox.data.SnapLogicStore;
 });
 
diff --git a/dojox/data/StoreExplorer.js b/dojox/data/StoreExplorer.js
index e047acc..d4733f5 100644
--- a/dojox/data/StoreExplorer.js
+++ b/dojox/data/StoreExplorer.js
@@ -173,8 +173,8 @@ dojo.declare("dojox.data.StoreExplorer", dijit.layout.BorderContainer, {
 			var retValue = defaultOnComplete.apply(this, arguments);
 
 		}
- 		grid.setStore(store);
- 		this.queryOptions = {cache:true};
+		grid.setStore(store);
+		this.queryOptions = {cache:true};
 		this.tree.setStore(store);
 	},
 	createNew: function(){
diff --git a/dojox/data/WikipediaStore.js b/dojox/data/WikipediaStore.js
index c5552c4..f2774db 100644
--- a/dojox/data/WikipediaStore.js
+++ b/dojox/data/WikipediaStore.js
@@ -4,17 +4,15 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/io/s
 
 kernel.experimental("dojox.data.WikipediaStore");
 
-/*===== var ServiceStore = dojox.data.ServiceStore; =====*/
-
 return declare("dojox.data.WikipediaStore", ServiceStore, {
-	//	summary:
+	// summary:
 	//		Initializer for the Wikipedia data store interface.
-	//	description:
+	// description:
 	//		The WikipediaStore is a data store interface to Wikipedia, using the
 	//		Wikipedia SMD spec from dojox.rpc. It currently is useful only for
 	//		finding articles that contain some particular text or grabbing single
 	//		articles by full name; no wildcards or other filtering are supported.
-	//	example:
+	// example:
 	//		|	var store = new dojox.data.WikipediaStore();
 	//		|	store.fetch({
 	//		|		query: {title:"Dojo Toolkit"},
@@ -34,17 +32,17 @@ return declare("dojox.data.WikipediaStore", ServiceStore, {
 	},
 
 	fetch: function(/* object */ request){
-		//	summary:
+		// summary:
 		//		Fetch a page or some partially-loaded search results from
 		//		Wikipedia. Note that there isn't a way to sort data coming
 		//		in from the API, so we just ignore the *sort* parameter.
-		//	example:
+		// example:
 		//		Loading a page:
 		//		|	store.fetch({
 		//		|		query: {title:"Dojo Toolkit"},
 		//		|		// define your handlers here
 		//		|	});
-		//	example:
+		// example:
 		//		Searching for pages containing "dojo":
 		//		|	store.fetch({
 		//		|		query: {
@@ -53,7 +51,7 @@ return declare("dojox.data.WikipediaStore", ServiceStore, {
 		//		|		},
 		//		|		// define your handlers here
 		//		|	});
-		//	example:
+		// example:
 		//		Searching for the next 50 pages containing "dojo":
 		//		|	store.fetch({
 		//		|		query: {
diff --git a/dojox/data/XmlItem.js b/dojox/data/XmlItem.js
index 2aee3db..f2ba60f 100644
--- a/dojox/data/XmlItem.js
+++ b/dojox/data/XmlItem.js
@@ -3,30 +3,30 @@ define(["dojo/_base/declare"],
 
 return declare("dojox.data.XmlItem", null, {
 	constructor: function(element, store, query){
-		//	summary:
+		// summary:
 		//		Initialize with an XML element
-		//	element:
+		// element:
 		//		An XML element
-		//	store:
+		// store:
 		//		The containing store, if any.
-		//	query:
+		// query:
 		//		The query to use to look up a specific element.
 		//		Usually an XPath or dojo.query statement.
 		this.element = element;
 		this.store = store;
 		this.q = query;
 	},
-	//	summary:
+	// summary:
 	//		A data item of 'XmlStore'
-	//	description:
+	// description:
 	//		This class represents an item of 'XmlStore' holding an XML element.
 	//		'element'
-	//	element:
+	// element:
 	//		An XML element
 	toString: function(){
-		//	summary:
+		// summary:
 		//		Return a value of the first text child of the element
-		// 	returns:
+		// returns:
 		//		a value of the first text child of the element
 		var str = "";
 		if(this.element){
diff --git a/dojox/data/XmlStore.js b/dojox/data/XmlStore.js
index cca77fb..967064e 100644
--- a/dojox/data/XmlStore.js
+++ b/dojox/data/XmlStore.js
@@ -1,32 +1,33 @@
 define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/xhr", "dojo/data/util/simpleFetch", 
-		"dojo/_base/query", "dojo/_base/array", "dojo/_base/window", "dojo/data/util/filter", "dojox/xml/parser",
+		"dojo/_base/query", "dojo/_base/array", "dojo/_base/kernel", "dojo/data/util/filter", "dojox/xml/parser",
 		"dojox/data/XmlItem"], 
-  function(lang, declare, xhr, simpleFetch, domQuery, array, winUtil, filter, xmlParser, XmlItem) {
+  function(lang, declare, xhr, simpleFetch, domQuery, array, kernel, filter, xmlParser, XmlItem) {
 
 var XmlStore = declare("dojox.data.XmlStore", null, {
-	//	summary:
+	// summary:
 	//		A data store for XML based services or documents
-	//	description:
+	// description:
 	//		A data store for XML based services or documents
 	
 	constructor: function(/* object */ args){
-		//	summary:
+		// summary:
 		//		Constructor for the XML store.
-		//	args:
+		// args:
 		//		An anonymous object to initialize properties.  It expects the following values:
-		//		url:		The url to a service or an XML document that represents the store
-		//		rootItem:	A tag name for root items
-		//		keyAttribute:	An attribute name for a key or an identity (unique identifier)
+		//
+		//		- url:		The url to a service or an XML document that represents the store
+		//		- rootItem:	A tag name for root items
+		//		- keyAttribute:	An attribute name for a key or an identity (unique identifier)
 		//						Required for serverside fetchByIdentity, etc.  Not required for
 		//						client side fetchItemBIdentity, as it will use an XPath-like
 		//						structure if keyAttribute was not specified.  Recommended to always
 		//						set this, though, for consistent identity behavior.
-		// 		attributeMap:   An anonymous object contains properties for attribute mapping,
+		//		- attributeMap: An anonymous object contains properties for attribute mapping,
 		//						{"tag_name.item_attribute_name": "@xml_attribute_name", ...}
-		//		sendQuery:		A boolean indicate to add a query string to the service URL.
+		//		- sendQuery:	A boolean indicate to add a query string to the service URL.
 		//						Default is false.
-		//		urlPreventCache: Parameter to indicate whether or not URL calls should apply
-		//		                 the preventCache option to the xhr request.
+		//		- urlPreventCache: Parameter to indicate whether or not URL calls should apply
+		//						 the preventCache option to the xhr request.
 		if(args){
 			this.url = args.url;
 			this.rootItem = (args.rootItem || args.rootitem || this.rootItem);
@@ -74,12 +75,12 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	//	Parameter to indicate whether or not URL calls should apply the preventCache option to the xhr request.
 	urlPreventCache: true,
 
-	/* dojo.data.api.Read */
+	/* dojo/data/api/Read */
 
-	getValue: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* value? */ defaultValue){
-		//	summary:
+	getValue: function(/*dojo/data/api/Item*/ item, /* attribute|attribute-name-string */ attribute, /* value? */ defaultValue){
+		// summary:
 		//		Return an attribute value
-		//	description:
+		// description:
 		//		'item' must be an instance of a dojox.data.XmlItem from the store instance.
 		//		If 'attribute' specifies "tagName", the tag name of the element is
 		//		returned.
@@ -94,14 +95,14 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		//		attribute is returned.
 		//		Otherwise, the first child element of the tag name specified with
 		//		'attribute' is returned.
-		//	item:
+		// item:
 		//		An XML element that holds the attribute
-		//	attribute:
+		// attribute:
 		//		A tag name of a child element, An XML attribute name or one of
-		// 		special names
-		//	defaultValue:
+		//		special names
+		// defaultValue:
 		//		A default value
-		//	returns:
+		// returns:
 		//		An attribute value found, otherwise 'defaultValue'
 		var element = item.element;
 		var i;
@@ -147,10 +148,10 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		}
 	},
 
-	getValues: function(/* item */ item, /* attribute || attribute-name-string */ attribute){
-		//	summary:
+	getValues: function(/*dojo/data/api/Item*/ item, /* attribute|attribute-name-string */ attribute){
+		// summary:
 		//		Return an array of attribute values
-		//	description:
+		// description:
 		//		'item' must be an instance of a dojox.data.XmlItem from the store instance.
 		//		If 'attribute' specifies "tagName", the tag name of the element is
 		//		returned.
@@ -164,12 +165,12 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		//		attribute is returned.
 		//		Otherwise, child elements of the tag name specified with
 		//		'attribute' are returned.
-		//	item:
+		// item:
 		//		An XML element that holds the attribute
-		//	attribute:
+		// attribute:
 		//		A tag name of child elements, An XML attribute name or one of
 		//		special names
-		//	returns:
+		// returns:
 		//		An array of attribute values found, otherwise an empty array
 		var element = item.element;
 		var values = [];
@@ -213,10 +214,10 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		}
 	},
 
-	getAttributes: function(/* item */ item){
-		//	summary:
+	getAttributes: function(/*dojo/data/api/Item*/ item){
+		// summary:
 		//		Return an array of attribute names
-		// 	description:
+		// description:
 		//		'item' must be an instance of a dojox.data.XmlItem from the store instance.
 		//		tag names of child elements and XML attribute names of attributes
 		//		specified to the element are returned along with special attribute
@@ -224,9 +225,9 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		//		if the element has child elements, "text()" if the element has
 		//		child text nodes, and attribute names in '_attributeMap' that match
 		//		the tag name of the element.
-		//	item:
+		// item:
 		//		An XML element
-		//	returns:
+		// returns:
 		//		An array of attributes found
 		var element = item.element;
 		var attributes = [];
@@ -275,28 +276,28 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		return attributes; //array
 	},
 
-	hasAttribute: function(/* item */ item, /* attribute || attribute-name-string */ attribute){
-		//	summary:
+	hasAttribute: function(/*dojo/data/api/Item*/ item, /* attribute|attribute-name-string */ attribute){
+		// summary:
 		//		Check whether an element has the attribute
-		//	item:
+		// item:
 		//		'item' must be an instance of a dojox.data.XmlItem from the store instance.
-		//	attribute:
+		// attribute:
 		//		A tag name of a child element, An XML attribute name or one of
 		//		special names
-		//	returns:
+		// returns:
 		//		True if the element has the attribute, otherwise false
 		return (this.getValue(item, attribute) !== undefined); //boolean
 	},
 
-	containsValue: function(/* item */ item, /* attribute || attribute-name-string */ attribute, /* anything */ value){
-		//	summary:
+	containsValue: function(/*dojo/data/api/Item*/ item, /* attribute|attribute-name-string */ attribute, /* anything */ value){
+		// summary:
 		//		Check whether the attribute values contain the value
-		//	item:
+		// item:
 		//		'item' must be an instance of a dojox.data.XmlItem from the store instance.
-		//	attribute:
+		// attribute:
 		//		A tag name of a child element, An XML attribute name or one of
 		//		special names
-		//	returns:
+		// returns:
 		//		True if the attribute values contain the value, otherwise false
 		var values = this.getValues(item, attribute);
 		for(var i = 0; i < values.length; i++){
@@ -312,11 +313,11 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary:
+		// summary:
 		//		Check whether the object is an item (XML element)
-		//	item:
+		// item:
 		//		An object to check
-		// 	returns:
+		// returns:
 		//		True if the object is an XML element, otherwise false
 		if(something && something.element && something.store && something.store === this){
 			return true; //boolean
@@ -325,26 +326,26 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary:
+		// summary:
 		//		Check whether the object is an item (XML element) and loaded
-		//	item:
+		// item:
 		//		An object to check
-		//	returns:
+		// returns:
 		//		True if the object is an XML element, otherwise false
 		return this.isItem(something); //boolean
 	},
 
 	loadItem: function(/* object */ keywordArgs){
-		//	summary:
+		// summary:
 		//		Load an item (XML element)
-		//	keywordArgs:
-		//		object containing the args for loadItem.  See dojo.data.api.Read.loadItem()
+		// keywordArgs:
+		//		object containing the args for loadItem.  See dojo/data/api/Read.loadItem()
 	},
 
 	getFeatures: function(){
-		//	summary:
+		// summary:
 		//		Return supported data APIs
-		//	returns:
+		// returns:
 		//		"dojo.data.api.Read" and "dojo.data.api.Write"
 		var features = {
 			"dojo.data.api.Read": true,
@@ -358,9 +359,9 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		return features; //array
 	},
 
-	getLabel: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabel()
+	getLabel: function(/*dojo/data/api/Item*/ item){
+		// summary:
+		//		See dojo/data/api/Read.getLabel()
 		if((this.label !== "") && this.isItem(item)){
 			var label = this.getValue(item,this.label);
 			if(label){
@@ -370,9 +371,9 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		return undefined; //undefined
 	},
 
-	getLabelAttributes: function(/* item */ item){
-		//	summary:
-		//		See dojo.data.api.Read.getLabelAttributes()
+	getLabelAttributes: function(/*dojo/data/api/Item*/ item){
+		// summary:
+		//		See dojo/data/api/Read.getLabelAttributes()
 		if(this.label !== ""){
 			return [this.label]; //array
 		}
@@ -380,9 +381,9 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	},
 
 	_fetchItems: function(request, fetchHandler, errorHandler){
-		//	summary:
+		// summary:
 		//		Fetch items (XML elements) that match to a query
-		//	description:
+		// description:
 		//		If 'sendQuery' is true, an XML document is loaded from
 		//		'url' with a query string.
 		//		Otherwise, an XML document is loaded and list XML elements that
@@ -391,11 +392,11 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		//		A wildcard, "*" can be used to query values to match all
 		//		occurrences.
 		//		If 'rootItem' is specified, it is used to fetch items.
-		//	request:
+		// request:
 		//		A request object
-		//	fetchHandler:
+		// fetchHandler:
 		//		A function to call for fetched items
-		//	errorHandler:
+		// errorHandler:
 		//		A function to call on error
 		var url = this._getFetchUrl(request);
 		if(!url){
@@ -425,18 +426,18 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	},
 
 	_getFetchUrl: function(request){
-		//	summary:
+		// summary:
 		//		Generate a URL for fetch
-		//	description:
+		// description:
 		//		This default implementation generates a query string in the form of
 		//		"?name1=value1&name2=value2..." off properties of 'query' object
 		//		specified in 'request' and appends it to 'url', if 'sendQuery'
 		//		is set to false.
 		//		Otherwise, 'url' is returned as is.
 		//		Sub-classes may override this method for the custom URL generation.
-		//	request:
+		// request:
 		//		A request object
-		//	returns:
+		// returns:
 		//		A fetch URL
 		if(!this.sendQuery){
 			return this.url;
@@ -472,20 +473,20 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	},
 
 	_getItems: function(document, request){
-		//	summary:
+		// summary:
 		//		Fetch items (XML elements) in an XML document based on a request
-		//	description:
+		// description:
 		//		This default implementation walks through child elements of
 		//		the document element to see if all properties of 'query' object
 		//		match corresponding attributes of the element (item).
 		//		If 'request' is not specified, all child elements are returned.
 		//		Sub-classes may override this method for the custom search in
 		//		an XML document.
-		//	document:
+		// document:
 		//		An XML document
-		//	request:
+		// request:
 		//		A request object
-		//	returns:
+		// returns:
 		//		An array of items
 		var query = null;
 		if(request){
@@ -590,7 +591,7 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	},
 
 	_flattenNodes: function(nodes){
-		//	Summary:
+		// summary:
 		//		Function used to flatten a hierarchy of XML nodes into a single list for
 		//		querying over.  Used when deep = true;
 		var flattened = [];
@@ -607,24 +608,24 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		return flattened;
 	},
 
-	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		 //	summary:
-		 //		See dojo.data.api.Read.close()
+	close: function(/*dojo/data/api/Request|Object?*/ request){
+		// summary:
+		//		See dojo/data/api/Read.close()
 	},
 
-/* dojo.data.api.Write */
+/* dojo/data/api/Write */
 
 	newItem: function(/* object? */ keywordArgs, parentInfo){
-		//	summary:
+		// summary:
 		//		Return a new dojox.data.XmlItem
-		//	description:
+		// description:
 		//		At least, 'keywordArgs' must contain "tagName" to be used for
 		//		the new	element.
 		//		Other attributes in 'keywordArgs' are set to the new element,
 		//		including "text()", but excluding "childNodes".
-		// 	keywordArgs:
+		// keywordArgs:
 		//		An object containing initial attributes
-		//	returns:
+		// returns:
 		//		An XML element
 		keywordArgs = (keywordArgs || {});
 		var tagName = keywordArgs.tagName;
@@ -691,12 +692,12 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		return item; //object
 	},
 	
-	deleteItem: function(/* item */ item){
-		//	summary:
+	deleteItem: function(/*dojo/data/api/Item*/ item){
+		// summary:
 		//		Delete an dojox.data.XmlItem (wrapper to a XML element).
-		//	item:
+		// item:
 		//		An XML element to delete
-		//	returns:
+		// returns:
 		//		True
 		var element = item.element;
 		if(element.parentNode){
@@ -709,10 +710,10 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		return true; //boolean
 	},
 	
-	setValue: function(/* item */ item, /* attribute || string */ attribute, /* almost anything */ value){
-		//	summary:
+	setValue: function(/*dojo/data/api/Item*/ item, /* attribute|String */ attribute, /* almost anything */ value){
+		// summary:
 		//		Set an attribute value
-		//	description:
+		// description:
 		//		'item' must be an instance of a dojox.data.XmlItem from the store instance.
 		//		If 'attribute' specifies "tagName", nothing is set and false is
 		//		returned.
@@ -728,14 +729,14 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		//		Otherwise, a text node is created with the value and set it to
 		//		the first child element of the tag name specified with 'attribute'.
 		//		If the child element does not exist, it is created.
-		//	item:
+		// item:
 		//		An XML element that holds the attribute
-		//	attribute:
+		// attribute:
 		//		A tag name of a child element, An XML attribute name or one of
 		//		special names
-		//	value:
+		// value:
 		//		A attribute value to set
-		//	returns:
+		// returns:
 		//		False for "tagName", otherwise true
 		if(attribute === "tagName"){
 			return false; //boolean
@@ -785,10 +786,10 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		return true; //boolean
 	},
 		
-	setValues: function(/* item */ item, /* attribute || string */ attribute, /*array*/ values){
-		//	summary:
+	setValues: function(/*dojo/data/api/Item*/ item, /* attribute|String */ attribute, /*Array*/ values){
+		// summary:
 		//		Set attribute values
-		//	description:
+		// description:
 		//		'item' must be an instance of a dojox.data.XmlItem from the store instance.
 		//		If 'attribute' specifies "tagName", nothing is set and false is
 		//		returned.
@@ -804,19 +805,19 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		//		Otherwise, child elements of the tag name specified with
 		//		'attribute' are replaced with new child elements and their
 		//		child text nodes of values.
-		//	item:
+		// item:
 		//		An XML element that holds the attribute
-		//	attribute:
+		// attribute:
 		//		A tag name of child elements, an XML attribute name or one of
 		//		special names
-		//	value:
+		// value:
 		//		A attribute value to set
-		//	notify:
+		// notify:
 		//		A non-API optional argument, used to indicate if notification API should be called
 		//		or not.
-
-		//	returns:
+		// returns:
 		//		False for "tagName", otherwise true
+
 		if(attribute === "tagName"){
 			return false; //boolean
 		}
@@ -870,10 +871,10 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		return true; //boolean
 	},
 	
-	unsetAttribute: function(/* item */ item, /* attribute || string */ attribute){
-		//	summary:
+	unsetAttribute: function(/*dojo/data/api/Item*/ item, /* attribute|String */ attribute){
+		// summary:
 		//		Remove an attribute
-		//	description:
+		// description:
 		//		'item' must be an instance of a dojox.data.XmlItem from the store instance.
 		//		'attribute' can be an XML attribute name of the element or one of
 		//		special names described below.
@@ -887,12 +888,12 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		//		Then, if 'attribute' starts with "@", the XML attribute is removed.
 		//		Otherwise, child elements of the tag name specified with
 		//		'attribute' are removed.
-		//	item:
+		// item:
 		//		An XML element that holds the attribute
-		//	attribute:
+		// attribute:
 		//		A tag name of child elements, an XML attribute name or one of
 		//		special names
-		//	returns:
+		// returns:
 		//		False for "tagName", otherwise true
 		if(attribute === "tagName"){
 			return false; //boolean
@@ -924,12 +925,12 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	},
 	
 	save: function(/* object */ keywordArgs){
-		//	summary:
+		// summary:
 		//		Save new and/or modified items (XML elements)
-		// 	description:
+		// description:
 		//		'url' is used to save XML documents for new, modified and/or
 		//		deleted XML elements.
-		// 	keywordArgs:
+		// keywordArgs:
 		//		An object for callbacks
 		if(!keywordArgs){
 			keywordArgs = {};
@@ -966,16 +967,16 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	},
 	
 	isDirty: function(/* item? */ item){
-		//	summary:
+		// summary:
 		//		Check whether an item is new, modified or deleted
-		//	description:
+		// description:
 		//		If 'item' is specified, true is returned if the item is new,
 		//		modified or deleted.
 		//		Otherwise, true is returned if there are any new, modified
 		//		or deleted items.
-		//	item:
+		// item:
 		//		An item (XML element) to check
-		//	returns:
+		// returns:
 		//		True if an item or items are new, modified or deleted, otherwise
 		//		false
 		if(item){
@@ -1002,7 +1003,7 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		}
 		if(!url){
 			if(keywordArgs.onError){
-				scope = keywordArgs.scope || winUtil.global;
+				scope = keywordArgs.scope || kernel.global;
 				keywordArgs.onError.call(scope, new Error("No URL for saving content: " + this._getPostContent(item)));
 			}
 			return;
@@ -1024,7 +1025,7 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 			saveArgs.postData = this._getPostContent(item);
 			saveHandler = xhr.post(saveArgs);
 		}
-		scope = (keywordArgs.scope || winUtil. global);
+		scope = (keywordArgs.scope || kernel. global);
 		var self = this;
 		saveHandler.addCallback(function(data){
 			self._forgetItem(item);
@@ -1040,42 +1041,42 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	},
 
 	_getPostUrl: function(item){
-		//	summary:
+		// summary:
 		//		Generate a URL for post
-		//	description:
+		// description:
 		//		This default implementation just returns 'url'.
 		//		Sub-classes may override this method for the custom URL.
-		//	item:
+		// item:
 		//		An item to save
-		//	returns:
+		// returns:
 		//		A post URL
 		return this.url; //string
 	},
 
 	_getPutUrl: function(item){
-		//	summary:
+		// summary:
 		//		Generate a URL for put
-		//	description:
+		// description:
 		//		This default implementation just returns 'url'.
 		//		Sub-classes may override this method for the custom URL.
-		//	item:
+		// item:
 		//		An item to save
-		//	returns:
+		// returns:
 		//		A put URL
 		return this.url; //string
 	},
 
 	_getDeleteUrl: function(item){
-		//	summary:
+		// summary:
 		//		Generate a URL for delete
-		// 	description:
+		// description:
 		//		This default implementation returns 'url' with 'keyAttribute'
 		//		as a query string.
 		//		Sub-classes may override this method for the custom URL based on
 		//		changes (new, deleted, or modified).
-		// 	item:
+		// item:
 		//		An item to delete
-		// 	returns:
+		// returns:
 		//		A delete URL
 		var url = this.url;
 		if(item && this.keyAttribute !== ""){
@@ -1090,31 +1091,31 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	},
 
 	_getPostContent: function(item){
-		//	summary:
+		// summary:
 		//		Generate a content to post
-		// 	description:
+		// description:
 		//		This default implementation generates an XML document for one
 		//		(the first only) new or modified element.
 		//		Sub-classes may override this method for the custom post content
 		//		generation.
-		//	item:
+		// item:
 		//		An item to save
-		//	returns:
+		// returns:
 		//		A post content
 		return "<?xml version=\'1.0\'?>" + xmlParser.innerXML(item.element); //XML string
 	},
 
 	_getPutContent: function(item){
-		//	summary:
+		// summary:
 		//		Generate a content to put
-		// 	description:
+		// description:
 		//		This default implementation generates an XML document for one
 		//		(the first only) new or modified element.
 		//		Sub-classes may override this method for the custom put content
 		//		generation.
-		//	item:
+		// item:
 		//		An item to save
-		//	returns:
+		// returns:
 		//		A post content
 		return "<?xml version='1.0'?>" + xmlParser.innerXML(item.element); //XML string
 	},
@@ -1216,9 +1217,9 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	},
 
 	_getXPath: function(element){
-		//	summary:
+		// summary:
 		//		A function to compute the xpath of a node in a DOM document.
-		//	description:
+		// description:
 		//		A function to compute the xpath of a node in a DOM document.  Used for
 		//		Client side query handling and identity.
 		var xpath = null;
@@ -1252,10 +1253,10 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 	/*************************************
 	 * Dojo.data Identity implementation *
 	 *************************************/
-	getIdentity: function(/* item */ item){
-		//	summary:
+	getIdentity: function(/*dojo/data/api/Item*/ item){
+		// summary:
 		//		Returns a unique identifier for an item.
-		//	item:
+		// item:
 		//		The XML Item from the store from which to obtain its identifier.
 		if(!this.isItem(item)){
 			throw new Error("dojox.data.XmlStore: Object supplied to getIdentity is not an item");
@@ -1276,17 +1277,17 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 		}
 	},
 
-	getIdentityAttributes: function(/* item */ item){
-		//	summary:
+	getIdentityAttributes: function(/*dojo/data/api/Item*/ item){
+		// summary:
 		//		Returns an array of attribute names that are used to generate the identity.
-		//	description:
+		// description:
 		//		For XmlStore, if sendQuery is false and no keyAttribute was set, then this function
 		//		returns null, as xpath is used for the identity, which is not a public attribute of
 		//		the item.  If sendQuery is true and keyAttribute is set, then this function
 		//		returns an array of one attribute name: keyAttribute.   This means the server side
 		//		implementation must apply a keyAttribute to a returned node that always allows
 		//		it to be looked up again.
-		//	item:
+		// item:
 		//		The item from the store from which to obtain the array of public attributes that
 		//		compose the identifier, if any.
 		if(!this.isItem(item)){
@@ -1304,8 +1305,8 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 
 
 	fetchItemByIdentity: function(/* object */ keywordArgs){
-		//	summary:
-		//		See dojo.data.api.Identity.fetchItemByIdentity(keywordArgs)
+		// summary:
+		//		See dojo/data/api/Identity.fetchItemByIdentity(keywordArgs)
 		var handleDocument = null;
 		var scope = null;
 		var self = this;
@@ -1324,7 +1325,7 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 						request.query[self.keyAttribute] = keywordArgs.identity;
 						request.queryOptions = {deep: true};
 						var items = self._getItems(data,request);
-						scope = keywordArgs.scope || winUtil.global;
+						scope = keywordArgs.scope || kernel.global;
 						if(items.length === 1){
 							if(keywordArgs.onItem){
 								keywordArgs.onItem.call(scope, items[0]);
@@ -1392,7 +1393,7 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 							}
 						}
 						if(keywordArgs.onItem){
-							scope = keywordArgs.scope || winUtil.global;
+							scope = keywordArgs.scope || kernel.global;
 							keywordArgs.onItem.call(scope, item);
 						}
 					}
@@ -1410,7 +1411,7 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 			getHandler.addCallback(handleDocument);
 			if(keywordArgs.onError){
 				getHandler.addErrback(function(error){
-					var s = keywordArgs.scope || winUtil.global;
+					var s = keywordArgs.scope || kernel.global;
 					keywordArgs.onError.call(s, error);
 				});
 			}
@@ -1429,13 +1430,13 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 							item = items[0];
 						}else{
 							if(keywordArgs.onError){
-								var scope = keywordArgs.scope || winUtil.global;
+								var scope = keywordArgs.scope || kernel.global;
 								keywordArgs.onError.call(scope, new Error("More than one item was returned from the server for the denoted identity"));
 							}
 						}
 					}
 					if(keywordArgs.onItem){
-						scope = keywordArgs.scope || winUtil.global;
+						scope = keywordArgs.scope || kernel.global;
 						keywordArgs.onItem.call(scope, item);
 					}
 				};
@@ -1451,13 +1452,13 @@ var XmlStore = declare("dojox.data.XmlStore", null, {
 				getHandler.addCallback(handleDocument);
 				if(keywordArgs.onError){
 					getHandler.addErrback(function(error){
-						var s = keywordArgs.scope || winUtil.global;
+						var s = keywordArgs.scope || kernel.global;
 						keywordArgs.onError.call(s, error);
 					});
 				}
 			}else{
 				if(keywordArgs.onError){
-					var s = keywordArgs.scope || winUtil.global;
+					var s = keywordArgs.scope || kernel.global;
 					keywordArgs.onError.call(s, new Error("XmlStore is not told that the server to provides identity support.  No keyAttribute specified."));
 				}
 			}
diff --git a/dojox/data/demos/demo_GoogleImageSearchStore_Grid.html b/dojox/data/demos/demo_GoogleImageSearchStore_Grid.html
new file mode 100644
index 0000000..0155db1
--- /dev/null
+++ b/dojox/data/demos/demo_GoogleImageSearchStore_Grid.html
@@ -0,0 +1,75 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/themes/tundra/tundra.css";
+		@import "../../../dijit/themes/tundra/tundra_rtl.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+		@import "../../../dojox/grid/resources/tundraGrid.css";
+	</style>
+
+	<title>Google Search Store with Grid</title>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dijit/dijit.js"></script>
+	<script type="text/javascript" src="../GoogleSearchStore.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.DataGrid");
+		dojo.require("dijit.form.TextBox");
+		dojo.require("dijit.form.Button");
+		dojo.require("dojox.wire.ml.Invocation");
+		dojo.require("dojox.wire.ml.Transfer");
+		dojo.require("dojox.wire.ml.Action");
+		dojo.require("dojox.data.GoogleSearchStore");
+		
+		var ImageSearch;
+		
+		dojo.ready(function(){
+			ImageSearch = { layout:[], store:{}, grid:{},  }
+			
+			ImageSearch.format = function(value, row) {
+				return "<img src=\"" + value + "\" alt=\"" + ImageSearch.grid.getItem(row).title + "\" style=\"height:80px; width:auto; margin:auto;\">";  			
+			}
+			
+			ImageSearch.layout = [
+				[
+					{ name: "Title", field: "title", width: 20 },
+					{ name: "Summary", field: "content", width: 20 },
+					{ name: "URL", field: "url", width: "auto", formatter: ImageSearch.format }
+				]
+			];
+			
+			ImageSearch.store = new dojox.data.GoogleImageSearchStore();
+			
+			ImageSearch.grid = new dojox.grid.DataGrid({
+				store: 		ImageSearch.store,
+				structure: 	ImageSearch.layout,
+				query:		{ text: 'cat' },
+				style: 		"width: 720px; height: 500px;",
+				rowsPerPage: 20,
+				escapeHTMLInData: false
+			}, "googleGrid");
+						
+			ImageSearch.grid.startup();
+			
+		});
+
+		var newQuery = {text: 'cat' }; 
+	</script>
+</head>
+<body class="tundra" style="margin:20px;">
+	<h1>dojox.data.GoogleImageSearchStore:</h1>
+	<i>Displays a list of results from a google image search.</i><br>
+	<div dojoType="dijit.form.TextBox" id="searchText" value="cat"></div> 
+	<button dojoType="dijit.form.Button" id="searchButton">Search</button>
+	<br>
+	<br>
+	<div id="googleGrid"></div>
+	<div dojoType="dojox.wire.ml.Action" trigger="searchButton" triggerEvent="onClick">
+		<div dojoType="dojox.wire.ml.Transfer" source="searchText.value" target="newQuery.text"></div>
+		<div dojoType="dojox.wire.ml.Invocation" object="ImageSearch.grid" method="setQuery" parameters="newQuery"></div>
+	</div>    
+</body>
+</html>
diff --git a/dojox/data/demos/demo_GoogleSearchStore_Grid.html b/dojox/data/demos/demo_GoogleSearchStore_Grid.html
index 99dacaa..c746de4 100644
--- a/dojox/data/demos/demo_GoogleSearchStore_Grid.html
+++ b/dojox/data/demos/demo_GoogleSearchStore_Grid.html
@@ -51,6 +51,7 @@
 		rowsPerPage="8"
 		store="googleStore" 
 		structure="layoutResults" 
+		escapeHTMLInData="false"
 		query="{ text: 'dojo ajax' }"
 		jsId="grid"
 		style="width: 800px; height: 500px;"
diff --git a/dojox/data/demos/demo_QueryReadStore_FilteringSelect.html b/dojox/data/demos/demo_QueryReadStore_FilteringSelect.html
index 6f89167..77d07e7 100644
--- a/dojox/data/demos/demo_QueryReadStore_FilteringSelect.html
+++ b/dojox/data/demos/demo_QueryReadStore_FilteringSelect.html
@@ -8,7 +8,7 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true, useCommentedJson:true"></script>
 </head>
 <body class="tundra">
 
@@ -18,6 +18,7 @@
 	<div style="float:left;">
 		<div dojoType="dojox.data.QueryReadStore"
 			jsId="store1"
+			doClientPaging="true"
 			url="../tests/stores/QueryReadStore.php"
 			requestMethod="post"></div>
 		<div dojoType="dijit.form.FilteringSelect" id="fs1" store="store1" pageSize="10" autoComplete="false"></div>
@@ -27,7 +28,7 @@
 		var w = dijit.byId("fs1");
 		<br /><input id="value1" type="text" /> = w.value
 		<br /><input id="itemId1" type="text" /> = w.item ? w.store.getValue(w.item, "id") : "-"
-		<br /><input id="displayedValue1" type="text" /> = w.getDisplayedValue()
+		<br /><input id="displayedValue1" type="text" /> = w.get('displayedValue')
 		<br /><input id="isValid1" type="text" /> = w.isValid()
 		<br /><button dojoType="dijit.form.Button" onclick="refresh1()">refresh</button>
 	</div>
@@ -36,12 +37,13 @@
 		dojo.require("dojox.data.QueryReadStore");
 		dojo.require("dijit.form.FilteringSelect");
 		dojo.require("dijit.form.Button");
+		dojo.require("dojo.parser");
 		
 		var w = null;
 		var refresh1 = function() {
 			dojo.byId("value1").value = w.value;
 			dojo.byId("itemId1").value = w.item ? w.store.getValue(w.item, "id") : "-";
-			dojo.byId("displayedValue1").value = w.getDisplayedValue();
+			dojo.byId("displayedValue1").value = w.get('displayedValue');
 			dojo.byId("isValid1").value = w.isValid();
 		};
 		dojo.addOnLoad(function() {
diff --git a/dojox/data/demos/stores/LazyLoadJSIStore.js b/dojox/data/demos/stores/LazyLoadJSIStore.js
index e811e85..266dcdf 100644
--- a/dojox/data/demos/stores/LazyLoadJSIStore.js
+++ b/dojox/data/demos/stores/LazyLoadJSIStore.js
@@ -10,11 +10,10 @@ dojo.declare("dojox.data.demos.stores.LazyLoadJSIStore", dojo.data.ItemFileReadS
 	},
 	
 	isItemLoaded: function(/*object*/ item) {
-		//	summary:
+		// summary:
 		//		Overload of the isItemLoaded function to look for items of type 'stub', which indicate
 		//		the data hasn't been loaded in yet.
-		//
-		//	item:
+		// item:
 		//		The item to examine.
 		
 		//For this store, if it has the value of stub for its type attribute,
@@ -26,13 +25,12 @@ dojo.declare("dojox.data.demos.stores.LazyLoadJSIStore", dojo.data.ItemFileReadS
 	},
 		
 	loadItem: function(keywordArgs){
-		//	summary:
+		// summary:
 		//		Overload of the loadItem function to fault in items.  This assumes the data for an item is laid out
 		//		in a RESTful sort of pattern name0/name1/data.json and so on and uses that to load the data.
 		//		It will also detect stub items in the newly loaded item and insert the stubs into the ItemFileReadStore
 		//		list so they can also be loaded in on-demand.
-		//
-		//	item:
+		// item:
 		//		The item to examine.
 
 		var item = keywordArgs.item;
@@ -92,7 +90,7 @@ dojo.declare("dojox.data.demos.stores.LazyLoadJSIStore", dojo.data.ItemFileReadS
 							//We have a stub reference here, we need to create the stub item
 							var stub = {
 								type: ["stub"],
-								name: [value["stub"]],	//
+								name: [value["stub"]],
 								parent: [itemName]		//The child stub item is parented by this item name...
 							};
 							if (parent) {
diff --git a/dojox/data/demos/stores/filestore_funcs.php b/dojox/data/demos/stores/filestore_funcs.php
index ff61139..259dc2c 100755
--- a/dojox/data/demos/stores/filestore_funcs.php
+++ b/dojox/data/demos/stores/filestore_funcs.php
@@ -65,8 +65,8 @@
 	 * @param $showHiddenFiles boolean to indicate to return hidden files as part of the list.
 	 */
 	function getAllfiles($dir, $rootDir, $recurse, $dirsOnly, $expand, $showHiddenFiles) { 
-		//  summary:
-		//      A function to obtain all the files in a particular directory (file or dir)
+		// summary:
+		//		A function to obtain all the files in a particular directory (file or dir)
 		$files = array();
 		$dirHandle = opendir($rootDir."/".$dir);
 		if ($dirHandle) {
@@ -118,8 +118,8 @@
 	 *  $file["children"] - Children files of a directory.  Empty if a standard file.
 	 */
 	function generateFileObj($file, $dir, $rootDir, $expand, $showHiddenFiles) {
-		//  summary:
-		//      Function to generate an object representation of a disk file.
+		// summary:
+		//		Function to generate an object representation of a disk file.
 		$path = $file;
 		if ($dir != "." && $dir != "./") {
 			$path = $dir."/".$file;
diff --git a/dojox/data/demos/widgets/PicasaViewList.js b/dojox/data/demos/widgets/PicasaViewList.js
index 67205a5..9102b05 100644
--- a/dojox/data/demos/widgets/PicasaViewList.js
+++ b/dojox/data/demos/widgets/PicasaViewList.js
@@ -26,8 +26,8 @@ dojo.declare("dojox.data.demos.widgets.PicasaViewList", [dijit._Widget, dijit._T
 	},
 
 	addView: function(viewData){
-		 var newView  = new dojox.data.demos.widgets.PicasaView(viewData);
-		 this.fViewWidgets.push(newView);
-		 this.list.appendChild(newView.domNode);
+		var newView  = new dojox.data.demos.widgets.PicasaView(viewData);
+		this.fViewWidgets.push(newView);
+		this.list.appendChild(newView.domNode);
 	}
 });
diff --git a/dojox/data/dom.js b/dojox/data/dom.js
index 71385a0..65985ca 100644
--- a/dojox/data/dom.js
+++ b/dojox/data/dom.js
@@ -23,13 +23,12 @@ dojo.deprecated("dojox.data.dom", "Use dojox.xml.parser instead.", "2.0");
 var dataDom = lang.getObject("dojox.data.dom",true);
 
 dataDom.createDocument = function(/*string?*/ str, /*string?*/ mimetype){
-	//	summary:
+	// summary:
 	//		cross-browser implementation of creating an XML document object.
-	//
-	//	str:
+	// str:
 	//		Optional text to create the document from.  If not provided, an empty XML document will be created.
 	//		If str is empty string "", then a new empty document will be created.
-	//	mimetype:
+	// mimetype:
 	//		Optional mimetype of the text.  Typically, this is text/xml.  Will be defaulted to text/xml if not provided.
 	dojo.deprecated("dojox.data.dom.createDocument()", "Use dojox.xml.parser.parse() instead.", "2.0");
 	try{
@@ -41,15 +40,15 @@ dataDom.createDocument = function(/*string?*/ str, /*string?*/ mimetype){
 };
 
 dataDom.textContent = function(/*Node*/node, /*string?*/text){
-	//	summary:
+	// summary:
 	//		Implementation of the DOM Level 3 attribute; scan node for text
-	//	description:
+	// description:
 	//		Implementation of the DOM Level 3 attribute; scan node for text
 	//		This function can also update the text of a node by replacing all child
 	//		content of the node.
-	//	node:
+	// node:
 	//		The node to get the text off of or set the text on.
-	//	text:
+	// text:
 	//		Optional argument of the text to apply to the node.
 	dojo.deprecated("dojox.data.dom.textContent()", "Use dojox.xml.parser.textContent() instead.", "2.0");
 	if(arguments.length> 1){
@@ -59,16 +58,16 @@ dataDom.textContent = function(/*Node*/node, /*string?*/text){
 	}
 };
 
-dataDom.replaceChildren = function(/*Element*/node, /*Node || array*/ newChildren){
-	//	summary:
+dataDom.replaceChildren = function(/*Element*/node, /*Node|Array*/ newChildren){
+	// summary:
 	//		Removes all children of node and appends newChild. All the existing
 	//		children will be destroyed.
-	//	description:
+	// description:
 	//		Removes all children of node and appends newChild. All the existing
 	//		children will be destroyed.
-	// 	node:
+	// node:
 	//		The node to modify the children on
-	//	newChildren:
+	// newChildren:
 	//		The children to add to the node.  It can either be a single Node or an
 	//		array of Nodes.
 	dojo.deprecated("dojox.data.dom.replaceChildren()", "Use dojox.xml.parser.replaceChildren() instead.", "2.0");
@@ -76,20 +75,20 @@ dataDom.replaceChildren = function(/*Element*/node, /*Node || array*/ newChildre
 };
 
 dataDom.removeChildren = function(/*Element*/node){
-	//	summary:
+	// summary:
 	//		removes all children from node and returns the count of children removed.
 	//		The children nodes are not destroyed. Be sure to call dojo._destroyElement on them
 	//		after they are not used anymore.
-	//	node:
+	// node:
 	//		The node to remove all the children from.
 	dojo.deprecated("dojox.data.dom.removeChildren()", "Use dojox.xml.parser.removeChildren() instead.", "2.0");
 	return dojox.xml.parser.removeChildren(node); //int
 };
 
 dataDom.innerXML = function(/*Node*/node){
-	//	summary:
+	// summary:
 	//		Implementation of MS's innerXML function.
-	//	node:
+	// node:
 	//		The node from which to generate the XML text representation.
 	dojo.deprecated("dojox.data.dom.innerXML()", "Use dojox.xml.parser.innerXML() instead.", "2.0");
 	return xmlParser.innerXML(node); //string||null
diff --git a/dojox/data/restListener.js b/dojox/data/restListener.js
index 02af85b..bfca7b8 100644
--- a/dojox/data/restListener.js
+++ b/dojox/data/restListener.js
@@ -2,12 +2,11 @@ dojo.provide("dojox.data.restListener");
 
 dojox.data.restListener = function(message){
 	// summary:
-	// 		this function can be used to receive REST notifications, from Comet or from another frame
-	// description:
-	//		Example:
-	// |	dojo.connect(window,"onMessage",null,function(event) {
+	//		this function can be used to receive REST notifications, from Comet or from another frame
+	// example:
+	//	|	dojo.connect(window,"onMessage",null,function(event) {
 	//	|		var data = dojo.fromJson(event.data);
-	// 	|		dojox.restListener(data);
+	//	|		dojox.restListener(data);
 	//	|	});
 	var channel = message.channel;
 	var jr = dojox.rpc.JsonRest;
@@ -37,12 +36,12 @@ dojox.data.restListener = function(message){
 				store.onNew(result); // call onNew for the store;
 				break;
 			case 'ondelete':
-		 		store.onDelete(target);
-		 		break;
-				 	// put is handled by JsonReferencing
-				 	//TODO: we may want to bring the JsonReferencing capability into here...
-				 	// that is really tricky though because JsonReferencing handles sub object,
-				 	// it would be expensive to do full object graph searches from here
+				store.onDelete(target);
+				break;
+					// put is handled by JsonReferencing
+					//TODO: we may want to bring the JsonReferencing capability into here...
+					// that is really tricky though because JsonReferencing handles sub object,
+					// it would be expensive to do full object graph searches from here
 		}
 	}
 };
diff --git a/dojox/data/tests/ClientFilter.js b/dojox/data/tests/ClientFilter.js
index 4ecbe3d..3143c75 100644
--- a/dojox/data/tests/ClientFilter.js
+++ b/dojox/data/tests/ClientFilter.js
@@ -32,7 +32,7 @@ doh.register("dojox.data.tests.ClientFilter",
 			return d;
 		},
 		function makeChanges(t) {
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on JsonRestStore of a simple query.
 			var d = new doh.Deferred();
 			jsonStore.fetch({queryOptions:{cache:true},query:{lastName:"Smith",firstName:"*"},sort:[{attribute:"firstName",descending:true}],
diff --git a/dojox/data/tests/QueryReadStore.html b/dojox/data/tests/QueryReadStore.html
index 2a70bff..605fa82 100644
--- a/dojox/data/tests/QueryReadStore.html
+++ b/dojox/data/tests/QueryReadStore.html
@@ -11,16 +11,14 @@
 	<title>Query read store</title>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-	<script type="text/javascript" src="../../../dojo/data/util/simpleFetch.js"></script>
-	<script type="text/javascript" src="../../../dojox/data/QueryReadStore.js"></script>
+
 	<script type="text/javascript">
 		dojo.require("dijit.form.ComboBox");
 		dojo.require("dijit.form.FilteringSelect");
 		dojo.require("dojox.data.QueryReadStore");
 
-		dojo.provide("ComboBoxReadStore");
 		dojo.declare("ComboBoxReadStore", dojox.data.QueryReadStore, {
-			fetch:function(request) {
+			fetch: function(request){
 				// Copy the GET/POST parameters (request.query) we need into
 				// request.serverQuery. We actually want to have
 				// the query added to the URL like so:  /url.php?q=<searchString>
@@ -39,9 +37,8 @@
 				//      }
 				// This results in a xhr request to the following URL (in case of GET):
 				//      /url.php?q=<searchString>
-				//
 
-				request.serverQuery = {q:request.query.name};
+				request.serverQuery = {q: request.query.name};
 				// If we wanted to send the queryOptions too, we could simply do:
 				//  request.serverQuery = {
 				//          q:request.query.name,
@@ -55,51 +52,51 @@
 			}
 		});
 
-		dojo.provide("ServerPagingReadStore");
 		dojo.declare("ServerPagingReadStore", dojox.data.QueryReadStore, {
-			fetch:function(request) {
-				request.serverQuery = {q:request.query.name, start:request.start, count:request.count};
+			fetch: function(request){
+				request.serverQuery = {q: request.query.name, start: request.start, count: request.count};
 				return this.inherited("fetch", arguments);
 			}
 		});
 
-		var testStore = new dojox.data.QueryReadStore({url:'stores/QueryReadStore.php'});;
-		function doSearch() {
+		var testStore = new dojox.data.QueryReadStore({url: 'stores/QueryReadStore.php'});
+		;
+		function doSearch(){
 			var queryOptions = {};
-			if (dojo.byId("ignoreCaseEnabled").checked) {
+			if(dojo.byId("ignoreCaseEnabled").checked){
 				queryOptions.ignoreCase = dojo.query("#fetchForm")[0].ignoreCase[0].checked;
 			}
-			if (dojo.byId("deepEnabled").checked) {
+			if(dojo.byId("deepEnabled").checked){
 				queryOptions.deep = dojo.query("#fetchForm")[0].deep[0].checked;
 			}
-		    
+
 			var query = {};
 			query.q = dojo.byId("searchText").value;
-			var request = {query:query, queryOptions:queryOptions};
+			var request = {query: query, queryOptions: queryOptions};
 			request.start = parseInt(dojo.query("#fetchForm")[0].pagingStart.value);
 			request.count = parseInt(dojo.query("#fetchForm")[0].pagingCount.value);
 
 			var requestMethod = "get";
 			var radioButtons = dojo.query("#fetchForm")[0].requestMethod;
-			for (var i=0; i<radioButtons.length; i++){
-				if (radioButtons[i].checked) {
+			for(var i = 0; i < radioButtons.length; i++){
+				if(radioButtons[i].checked){
 					requestMethod = radioButtons[i].value;
 				}
 			}
-			
+
 			testStore.requestMethod = requestMethod;
 			testStore.doClientPaging = dojo.query("#fetchForm")[0].doClientPaging.checked;
-			
-			if (!testStore.doClientPaging) {
+
+			if(!testStore.doClientPaging){
 				// We have to fill the serverQuery, since we also want to send the
 				// paging data "start" and "count" along with what is in query.
-				request.serverQuery = {q:request.query.q, start:request.start, count:request.count};
+				request.serverQuery = {q: request.query.q, start: request.start, count: request.count};
 			}
-			
-			request.onComplete = function (items) {
-				var s = "number of items: "+items.length+"<br /><br />";
-				for (var i=0; i<items.length; i++) {
-					s += i+": name: '"+testStore.getValue(items[i], "name")+"'<br />";
+
+			request.onComplete = function(items){
+				var s = "number of items: " + items.length + "<br /><br />";
+				for(var i = 0; i < items.length; i++){
+					s += i + ": name: '" + testStore.getValue(items[i], "name") + "'<br />";
 				}
 				//s += "<pre>"+dojo.toJson(items)+"</pre>";
 				dojo.byId("fetchOutput").innerHTML = s;
@@ -111,36 +108,45 @@
 	</script>
 
 	<style>
-	     fieldset {
-	         border:1px solid black;
-	         display:inline;
-	         padding:10px;
-	     }
-	     div.disabled {
-	         opacity:0.1;
-	     }
+		fieldset {
+			border: 1px solid black;
+			display: inline;
+			padding: 10px;
+		}
+
+		div.disabled {
+			opacity: 0.1;
+		}
 	</style>
 </head>
 <body class="tundra" style="margin:20px;">
-	<div dojoType="ComboBoxReadStore" jsId="store" url="stores/QueryReadStore.php" requestMethod="get"></div>
-	This is a ComboBox: <input id="cb" dojoType="dijit.form.ComboBox" store="store" pageSize="5" />
-	<br /><br /><hr />
-
-	This is a FilteringSelect: <input id="fs" dojoType="dijit.form.FilteringSelect" store="store" pageSize="5" />
-	<br />
-	<form id="filteringSelectForm">
-		<input id="selectById" value="0" size="3" />
-		<input type="button" value="set by id" onclick="dijit.byId('fs').setValue(dojo.byId('selectById').value)" />
-	</form>
-	
-	<br /><br /><hr />
-
-	This ComboBox uses a customized QueryReadStore, it prepares the query-string for the URL that
-	way that the paging parameters "start" and "count" are also send.<br />
-	<div dojoType="ServerPagingReadStore" jsId="serverPagingStore" url="stores/QueryReadStore.php" requestMethod="get"></div>
-	<input dojoType="dijit.form.ComboBox" store="serverPagingStore" pageSize="5" />
-	<br />
-	<a href="javascript://" onclick="var d = dojo.byId('pagingCode'); d.style.display= d.style.display=='none'?'block':'none';">Click here to  see the code!</a>
+<div dojoType="ComboBoxReadStore" jsId="store" url="stores/QueryReadStore.php" requestMethod="get"></div>
+This is a ComboBox: <input id="cb" dojoType="dijit.form.ComboBox" store="store" pageSize="5"/>
+<br/><br/>
+<hr/>
+
+This is a FilteringSelect: <input id="fs" dojoType="dijit.form.FilteringSelect" store="store" pageSize="5"/>
+<br/>
+
+<form id="filteringSelectForm">
+	<input id="selectById" value="0" size="3"/>
+	<input type="button" value="set by id" onclick="dijit.byId('fs').setValue(dojo.byId('selectById').value)"/>
+</form>
+
+<br/><br/>
+<hr/>
+
+This ComboBox uses a customized QueryReadStore, it prepares the query-string for the URL that
+way that the paging parameters "start" and "count" are also send.<br/>
+
+<div dojoType="ServerPagingReadStore" jsId="serverPagingStore" url="stores/QueryReadStore.php"
+	 requestMethod="get"></div>
+<input dojoType="dijit.form.ComboBox" store="serverPagingStore" pageSize="5"/>
+<br/>
+<a href="javascript://"
+   onclick="var d = dojo.byId('pagingCode'); d.style.display= d.style.display=='none'?'block':'none';">Click here to see
+	the code!</a>
+
 <div id="pagingCode" style="display:none;">
 	The HTML might look like this.
 	<pre>
@@ -158,64 +164,64 @@
 		});
 	</pre>
 </div>
-	<br /><br />
-	
-	<hr />
-	
-	<form id="fetchForm">
-		<fieldset title="requestMethod">
-		    <legend>requestMethod</legend>
-			get <input type="radio" value="get" checked="checked" name="requestMethod" />
-			post <input type="radio" value="post" name="requestMethod" />
-		</fieldset>
-		
-		<fieldset title="queryOptions">
-			<legend>queryOptions</legend>
-
-			<fieldset id="ignoreCaseFieldset">
-				<legend><input type="checkbox" id="ignoreCaseEnabled" /> ignoreCase</legend>
-				<div class="disabled">
-					true <input type="radio" value="0" checked="checked" name="ignoreCase" />
-					false <input type="radio" value="1" name="ignoreCase" />
-				</div>
-			</fieldset>
-			<fieldset id="deepFieldset">
-				<legend><input type="checkbox" id="deepEnabled" /> deep</legend>
-				<div class="disabled">
-					true <input type="radio" value="0" name="deep" />
-					false <input type="radio" value="1" name="deep" checked="checked" />
-				</div>
-			</fieldset>
+<br/><br/>
+
+<hr/>
+
+<form id="fetchForm">
+	<fieldset title="requestMethod">
+		<legend>requestMethod</legend>
+		get <input type="radio" value="get" checked="checked" name="requestMethod"/>
+		post <input type="radio" value="post" name="requestMethod"/>
+	</fieldset>
+
+	<fieldset title="queryOptions">
+		<legend>queryOptions</legend>
+
+		<fieldset id="ignoreCaseFieldset">
+			<legend><input type="checkbox" id="ignoreCaseEnabled"/> ignoreCase</legend>
+			<div class="disabled">
+				true <input type="radio" value="0" checked="checked" name="ignoreCase"/>
+				false <input type="radio" value="1" name="ignoreCase"/>
+			</div>
 		</fieldset>
-		<fieldset title="paging">
-			<legend>paging</legend>
-			start: <input id="pagingStart" value="0" size="3" />
-			count: <input id="pagingCount" value="10" size="3"  />
-			<br /><br />
-			do client paging: <input id="doClientPaging" type="checkbox" checked="checked" />
+		<fieldset id="deepFieldset">
+			<legend><input type="checkbox" id="deepEnabled"/> deep</legend>
+			<div class="disabled">
+				true <input type="radio" value="0" name="deep"/>
+				false <input type="radio" value="1" name="deep" checked="checked"/>
+			</div>
 		</fieldset>
-		<script>
-		    var fieldsets = ["ignoreCaseFieldset", "deepFieldset"];
-		    for (var i=0; i<fieldsets.length; i++) {
-		        dojo.connect(dojo.byId(fieldsets[i]), "onchange", toggleFieldset);
-		    }
-		    function toggleFieldset(el) {
-		        var divs = dojo.query("div", el.target.parentNode.parentNode);
-		        if (divs.length) {
-					var div = divs[0];
-					if (el.target.checked) {
-						dojo.removeClass(div, "disabled");
-					} else {
-						dojo.addClass(div, "disabled");
-					}
+	</fieldset>
+	<fieldset title="paging">
+		<legend>paging</legend>
+		start: <input id="pagingStart" value="0" size="3"/>
+		count: <input id="pagingCount" value="10" size="3"/>
+		<br/><br/>
+		do client paging: <input id="doClientPaging" type="checkbox" checked="checked"/>
+	</fieldset>
+	<script>
+		var fieldsets = ["ignoreCaseFieldset", "deepFieldset"];
+		for(var i = 0; i < fieldsets.length; i++){
+			dojo.connect(dojo.byId(fieldsets[i]), "onchange", toggleFieldset);
+		}
+		function toggleFieldset(el){
+			var divs = dojo.query("div", el.target.parentNode.parentNode);
+			if(divs.length){
+				var div = divs[0];
+				if(el.target.checked){
+					dojo.removeClass(div, "disabled");
+				}else{
+					dojo.addClass(div, "disabled");
 				}
-		    }
-		</script>
-		
-		<br /><br />
-		<input id="searchText" type="text" value="a">
-		<input id="searchButton" type="button" value="store.fetch()" onclick="doSearch()" />
-	</form>
-	<div id="fetchOutput" style="background-color:#FFDDDD; margin-top:1em; float:left;"></div>
+			}
+		}
+	</script>
+
+	<br/><br/>
+	<input id="searchText" type="text" value="a">
+	<input id="searchButton" type="button" value="store.fetch()" onclick="doSearch()"/>
+</form>
+<div id="fetchOutput" style="background-color:#FFDDDD; margin-top:1em; float:left;"></div>
 </body>
 </html>
diff --git a/dojox/data/tests/performance/CsvStore.js b/dojox/data/tests/performance/CsvStore.js
index 7dba47a..f4a597c 100755
--- a/dojox/data/tests/performance/CsvStore.js
+++ b/dojox/data/tests/performance/CsvStore.js
@@ -4,10 +4,10 @@ dojo.require("dojo.data.util.sorter");
 
 
 dojox.data.tests.performance.CsvStore.getData = function(size){
-	//	summary:
+	// summary:
 	//		This function generates a psuedorandom dataset collected
 	//		from some templated entries.
-	//	returns:
+	// returns:
 	//		A 2000 'row' CSV dataset.
 
 	var header = "Title, Year, Producer\n";
diff --git a/dojox/data/tests/stores/AndOrReadStore.js b/dojox/data/tests/stores/AndOrReadStore.js
index e054882..e5eadb5 100755
--- a/dojox/data/tests/stores/AndOrReadStore.js
+++ b/dojox/data/tests/stores/AndOrReadStore.js
@@ -6,7 +6,7 @@ dojo.require("dojo.date");
 dojo.require("dojo.date.stamp");
 
 dojo.declare("dojox.data.tests.Wrapper", null, {
-	//	summary:
+	// summary:
 	//		Simple class to use for typeMap in order to	test out
 	//		'falsy' values for _value.
 	_wrapped: null,
@@ -24,22 +24,22 @@ dojo.declare("dojox.data.tests.Wrapper", null, {
 	},
 
 	toString: function(){
-		 return "WRAPPER: [" + this._wrapped + "]";
+		return "WRAPPER: [" + this._wrapped + "]";
 	}
 });
 
 
 //The test data-sets and tests are taken from ItemFileReadStore, to show
-//  backwards compatibility.
+//	backwards compatibility.
 //Additionally, where appropriate (fetch/query), the AndOrReadStore test is immediately
-//  followed by the same query (with ", complex" in the description), but with the query
-//  being a string rather than a json object.
+//	followed by the same query (with ", complex" in the description), but with the query
+//	being a string rather than a json object.
 //Below all those tests are new ones that test the use of AND, OR, NOT, ||, &&, (, ), and ","
-//  in queries, as well as a mix of string and json object queries.
+//	in queries, as well as a mix of string and json object queries.
 //Since some widgets expect the query to be in json object form, in addition to the
-//  query="id:1234 || dept:'Sales Department' || (dept:Auto && id:2*)" programmatic syntax,
-//  query="{complexQuery:'id:1234 || dept:\"Sales Department\" || (dept:Auto && id:2*)" is
-//  tested/supported.
+//	query="id:1234 || dept:'Sales Department' || (dept:Auto && id:2*)" programmatic syntax,
+//	query="{complexQuery:'id:1234 || dept:\"Sales Department\" || (dept:Auto && id:2*)" is
+//	tested/supported.
 
 //-----------------------------------------------------
 // test data-sets
@@ -153,7 +153,7 @@ dojox.data.tests.stores.AndOrReadStore.getTestData = function(name){
 							{ count: 10,   value: false  },
 							{ count: 11,   value: [false, false]},
 							{ count: "12", value: [false, "true"]}
-					   ]
+						]
 					}
 				};
 	}else if (name === "countries_references"){
@@ -214,7 +214,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity()",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -238,9 +238,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() notFound",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
-				//	description:
+				// description:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -260,9 +260,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: getIdentityAttributes()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getIdentityAttributes function.
-				//	description:
+				// description:
 				//		Simple test of the getIdentityAttributes function.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -286,9 +286,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() commentFilteredJson",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
-				//	description:
+				// description:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				//		This tests loading a comment-filtered json file so that people using secure
 				//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
@@ -316,9 +316,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() nullValue",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the fetchItemByIdentity function of the store, checling a null value.
-				//	description:
+				// description:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a null value.
 				//		This tests handling attributes in json that were defined as null properly.
 				//		Introduced because of tracker: #3153
@@ -342,9 +342,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() booleanValue",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
-				//	description:
+				// description:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries_withBoolean"));
 	
@@ -368,9 +368,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() withoutSpecifiedIdInData",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
-				//	description:
+				// description:
 				//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries_withoutid"));
 	
@@ -392,9 +392,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getIdentity function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getIdentity function of the store.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -415,9 +415,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity() withoutSpecifiedId",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the #4691 bug
-				//	description:
+				// description:
 				//		Simple test of the #4691 bug
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries_withoutid"));
 	
@@ -438,9 +438,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity() withoutSpecifiedId, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the #4691 bug
-				//	description:
+				// description:
 				//		Simple test of the #4691 bug
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries_withoutid"));
 	
@@ -461,9 +461,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() all",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -485,9 +485,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() abort",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch abort on AndOrReadStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch abort on AndOrReadStore.
 				if(dojo.isBrowser){
 					var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
@@ -522,9 +522,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() one",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -547,9 +547,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() one, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -572,9 +572,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() shallow",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of only toplevel items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of only toplevel items.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("geography_hierarchy_small"));
 				
@@ -598,9 +598,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() shallow, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of only toplevel items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of only toplevel items.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("geography_hierarchy_small"));
 				
@@ -624,9 +624,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() Multiple",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
-				//	description:
+				// description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("geography_hierarchy_small"));
 				
@@ -668,9 +668,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() Multiple, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
-				//	description:
+				// description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("geography_hierarchy_small"));
 				
@@ -712,9 +712,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() MultipleMixedFetch",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
-				//	description:
+				// description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//		Tests an item fetch and an identity fetch.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
@@ -757,9 +757,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() MultipleMixedFetch, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
-				//	description:
+				// description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//		Tests an item fetch and an identity fetch.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
@@ -802,9 +802,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() deep",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of all items (including children (nested))
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of all items (including children (nested))
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("geography_hierarchy_small"));
 				
@@ -829,9 +829,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() deep, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of all items (including children (nested))
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of all items (including children (nested))
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("geography_hierarchy_small"));
 				
@@ -856,11 +856,11 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() hierarchy off",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
@@ -913,11 +913,11 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() hierarchy off refs still parse",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
@@ -971,9 +971,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() one_commentFilteredJson",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//		This tests loading a comment-filtered json file so that people using secure
 				//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
@@ -1001,9 +1001,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() one_commentFilteredJson, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//		This tests loading a comment-filtered json file so that people using secure
 				//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
@@ -1031,9 +1031,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() withNull",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item where some attributes are null.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item where some attributes are null.
 				//		Introduced because of tracker: #3153
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries_withNull"));
@@ -1057,9 +1057,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() withNull, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item where some attributes are null.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item where some attributes are null.
 				//		Introduced because of tracker: #3153
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries_withNull"));
@@ -1083,9 +1083,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() all_streaming",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -1121,9 +1121,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() paging",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
-				//	description:
+				// description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -1193,9 +1193,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType Match",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//		Introduced because of tracker: #4931
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("data_multitype"));
@@ -1219,9 +1219,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType Match, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//		Introduced because of tracker: #4931
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("data_multitype"));
@@ -1245,9 +1245,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType, MultiValue Match",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//		Introduced because of tracker: #4931
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("data_multitype"));
@@ -1271,9 +1271,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType, MultiValue Match, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//		Introduced because of tracker: #4931
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("data_multitype"));
@@ -1297,9 +1297,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getLabel()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -1325,9 +1325,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getLabel(), complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -1353,9 +1353,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getLabelAttributes()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -1381,9 +1381,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getLabelAttributes(), complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -1409,9 +1409,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getValue()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -1433,9 +1433,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getValues()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getValues function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValues function of the store.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -1459,9 +1459,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: isItem()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isItem function of the store
-				//	description:
+				// description:
 				//		Simple test of the isItem function of the store
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -1483,11 +1483,11 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: isItem() multistore",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isItem function of the store
 				//		to verify two different store instances do not accept
 				//		items from each other.
-				//	description:
+				// description:
 				//		Simple test of the isItem function of the store
 				//		to verify two different store instances do not accept
 				//		items from each other.
@@ -1526,9 +1526,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: hasAttribute()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute function of the store
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute function of the store
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -1559,9 +1559,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: containsValue()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue function of the store
-				//	description:
+				// description:
 				//		Simple test of the containsValue function of the store
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -1593,9 +1593,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getAttributes()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes function of the store
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -1622,9 +1622,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getFeatures()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getFeatures function of the store
-				//	description:
+				// description:
 				//		Simple test of the getFeatures function of the store
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -1636,9 +1636,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch0",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of everything starting with lowercase e
-				//	description:
+				// description:
 				//		Function to test pattern matching of everything starting with lowercase e
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -1671,9 +1671,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch0, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of everything starting with lowercase e
-				//	description:
+				// description:
 				//		Function to test pattern matching of everything starting with lowercase e
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -1706,9 +1706,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch1",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of everything with $ in it.
-				//	description:
+				// description:
 				//		Function to test pattern matching of everything with $ in it.
 	
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -1754,9 +1754,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch1, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of everything with $ in it.
-				//	description:
+				// description:
 				//		Function to test pattern matching of everything with $ in it.
 	
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -1802,9 +1802,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch2",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test exact pattern match
-				//	description:
+				// description:
 				//		Function to test exact pattern match
 	
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -1850,9 +1850,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch2, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test exact pattern match
-				//	description:
+				// description:
 				//		Function to test exact pattern match
 	
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -1898,9 +1898,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseSensitive",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of a pattern case-sensitively
-				//	description:
+				// description:
 				//		Function to test pattern matching of a pattern case-sensitively
 	
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -1941,9 +1941,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseSensitive, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of a pattern case-sensitively
-				//	description:
+				// description:
 				//		Function to test pattern matching of a pattern case-sensitively
 	
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -1984,9 +1984,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseInsensitive",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of a pattern case-insensitively
-				//	description:
+				// description:
 				//		Function to test pattern matching of a pattern case-insensitively
 	
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2027,9 +2027,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseInsensitive, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of a pattern case-insensitively
-				//	description:
+				// description:
 				//		Function to test pattern matching of a pattern case-insensitively
 	
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2070,9 +2070,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumeric",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting numerically.
-				//	description:
+				// description:
 				//		Function to test sorting numerically.
 				
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2123,9 +2123,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumericDescending",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting numerically.
-				//	description:
+				// description:
 				//		Function to test sorting numerically.
 	
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2175,9 +2175,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumericWithCount",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting numerically in descending order, returning only a specified number of them.
-				//	description:
+				// description:
 				//		Function to test sorting numerically in descending order, returning only a specified number of them.
 			
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2230,9 +2230,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabetic",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting alphabetic ordering.
-				//	description:
+				// description:
 				//		Function to test sorting alphabetic ordering.
 			
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2297,9 +2297,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabeticDescending",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting alphabetic ordering in descending mode.
-				//	description:
+				// description:
 				//		Function to test sorting alphabetic ordering in descending mode.
 			
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2365,9 +2365,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortDate",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting date.
-				//	description:
+				// description:
 				//		Function to test sorting date.
 			
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2420,9 +2420,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortDateDescending",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting date in descending order.
-				//	description:
+				// description:
 				//		Function to test sorting date in descending order.
 			
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2476,9 +2476,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortMultiple",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting on multiple attributes.
-				//	description:
+				// description:
 				//		Function to test sorting on multiple attributes.
 				
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2545,9 +2545,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortMultipleSpecialComparator",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting on multiple attributes with a custom comparator.
-				//	description:
+				// description:
 				//		Function to test sorting on multiple attributes with a custom comparator.
 	
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2615,9 +2615,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabeticWithUndefined",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting alphabetic ordering.
-				//	description:
+				// description:
 				//		Function to test sorting alphabetic ordering.
 			
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
@@ -2670,10 +2670,10 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: errorCondition_idCollision_inMemory",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
-				//	description:
+				// description:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
 	
@@ -2704,10 +2704,10 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: errorCondition_idCollision_xhr",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
-				//	description:
+				// description:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
 	
@@ -2757,7 +2757,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_Color_SimpleMapping",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test using literal values with custom datatypes
 				var dataset = {
 					identifier:'name',
@@ -2789,7 +2789,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_Color_GeneralMapping",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test using literal values with custom datatypes
 				var dataset = {
 					identifier:'name',
@@ -2827,7 +2827,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_CustomObject 0 (False) value",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test type mapping and _values that are false-like
 				var dataset = {
 					identifier:'name',
@@ -2866,7 +2866,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_CustomObject Boolean False values",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test type mapping and _values that are false-like
 				var dataset = {
 					identifier:'name',
@@ -2904,7 +2904,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_CustomObject Empty String values",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test type mapping and _values that are false-like
 				var dataset = {
 					identifier:'name',
@@ -2942,7 +2942,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_CustomObject explicit null values",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test type mapping and _values that are false-like
 				var dataset = {
 					identifier:'name',
@@ -2980,7 +2980,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_CustomObject explicit undefined value",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test type mapping and _values that are false-like
 				var dataset = {
 					identifier:'name',
@@ -3071,7 +3071,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset url.)",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
@@ -3127,7 +3127,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch, close (clearOnClose: true, reset url.)",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
@@ -3185,7 +3185,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset _jsonFileUrl.)",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
@@ -3241,9 +3241,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset data.)",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test that clear on close and reset of data works.
-				//	description:
+				// description:
 				//		Function to test that clear on close and reset of data works.
 				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 						items: [ {uniqueId: 1, value:"foo*bar"},
@@ -3362,9 +3362,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: functionConformance",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-				//	description:
+				// description:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 				var testStore = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				var readApi = new dojo.data.api.Read();
@@ -3390,9 +3390,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: functionConformance",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
-				//	description:
+				// description:
 				//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 				var testStore = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				var identityApi = new dojo.data.api.Identity();
@@ -3421,9 +3421,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, OR, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -3446,9 +3446,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND(OR, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -3471,9 +3471,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND(OR, as json object, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -3496,9 +3496,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as json object, complex, with extra attrs",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -3521,9 +3521,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as json object, complex, with extra attrs and spaces",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
@@ -3547,9 +3547,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as quoted json object, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				
diff --git a/dojox/data/tests/stores/AndOrWriteStore.js b/dojox/data/tests/stores/AndOrWriteStore.js
index 9a262d5..44cefe5 100755
--- a/dojox/data/tests/stores/AndOrWriteStore.js
+++ b/dojox/data/tests/stores/AndOrWriteStore.js
@@ -9,18 +9,18 @@ dojo.require("dojo.data.api.Notification");
 
 
 //The test data-sets and tests are taken from ItemFileReadStore, to show
-//  backwards compatibility, and from ItemFileWriteStore.
+//	backwards compatibility, and from ItemFileWriteStore.
 //Since no new write capabilities are included in AndOrWriteStore (just those from
-//  ItemFileWriteStore), no new write tests were added.
+//	ItemFileWriteStore), no new write tests were added.
 //Additionally, where appropriate (fetch/query), the ItemFileReadStore test is immediately
-//  followed by the same query (with ", complex" in the description), but with the query
-//  being a string rather than a json object.
+//	followed by the same query (with ", complex" in the description), but with the query
+//	being a string rather than a json object.
 //Below all those tests are new ones that test the use of AND, OR, NOT, ||, &&, (, ), and ","
-//  in queries, as well as a mix of string and json object queries.
+//	in queries, as well as a mix of string and json object queries.
 //Since some widgets expect the query to be in json object form, in addition to the
-//  query="id:1234 || dept:'Sales Department' || (dept:Auto && id:2*)" programmatic syntax,
-//  query="{complexQuery:'id:1234 || dept:\"Sales Department\" || (dept:Auto && id:2*)" is
-//  tested/supported.
+//	query="id:1234 || dept:'Sales Department' || (dept:Auto && id:2*)" programmatic syntax,
+//	query="{complexQuery:'id:1234 || dept:\"Sales Department\" || (dept:Auto && id:2*)" is
+//	tested/supported.
 
 //-----------------------------------------------------
 // test data-sets
@@ -220,7 +220,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity()",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -244,9 +244,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() notFound",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
-				//	description:
+				// description:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -266,9 +266,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: getIdentityAttributes()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getIdentityAttributes function.
-				//	description:
+				// description:
 				//		Simple test of the getIdentityAttributes function.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -292,9 +292,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() commentFilteredJson",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
-				//	description:
+				// description:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				//		This tests loading a comment-filtered json file so that people using secure
 				//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
@@ -322,9 +322,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() nullValue",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the fetchItemByIdentity function of the store, checling a null value.
-				//	description:
+				// description:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a null value.
 				//		This tests handling attributes in json that were defined as null properly.
 				//		Introduced because of tracker: #3153
@@ -348,9 +348,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() booleanValue",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
-				//	description:
+				// description:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries_withBoolean"));
 	
@@ -374,9 +374,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() withoutSpecifiedIdInData",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
-				//	description:
+				// description:
 				//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries_withoutid"));
 	
@@ -398,9 +398,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getIdentity function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getIdentity function of the store.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -421,9 +421,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity() withoutSpecifiedId",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the #4691 bug
-				//	description:
+				// description:
 				//		Simple test of the #4691 bug
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries_withoutid"));
 	
@@ -444,9 +444,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity() withoutSpecifiedId, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the #4691 bug
-				//	description:
+				// description:
 				//		Simple test of the #4691 bug
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries_withoutid"));
 	
@@ -467,9 +467,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() all",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -491,9 +491,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() abort",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch abort on AndOrWriteStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch abort on AndOrWriteStore.
 				if(dojo.isBrowser){
 					var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
@@ -528,9 +528,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() one",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -553,9 +553,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() one, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -578,9 +578,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() shallow",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of only toplevel items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of only toplevel items.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("geography_hierarchy_small"));
 				
@@ -604,9 +604,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() shallow, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of only toplevel items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of only toplevel items.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("geography_hierarchy_small"));
 				
@@ -630,9 +630,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() Multiple",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
-				//	description:
+				// description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("geography_hierarchy_small"));
 				
@@ -674,9 +674,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() Multiple, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
-				//	description:
+				// description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("geography_hierarchy_small"));
 				
@@ -718,9 +718,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() MultipleMixedFetch",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
-				//	description:
+				// description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//		Tests an item fetch and an identity fetch.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
@@ -763,9 +763,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() MultipleMixedFetch, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
-				//	description:
+				// description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//		Tests an item fetch and an identity fetch.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
@@ -808,9 +808,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() deep",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items (including children (nested))
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items (including children (nested))
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("geography_hierarchy_small"));
 				
@@ -835,9 +835,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() deep, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items (including children (nested))
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items (including children (nested))
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("geography_hierarchy_small"));
 				
@@ -862,11 +862,11 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() hierarchy off",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
@@ -919,11 +919,11 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() hierarchy off refs still parse",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
@@ -977,9 +977,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() one_commentFilteredJson",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//		This tests loading a comment-filtered json file so that people using secure
 				//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
@@ -1007,9 +1007,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() one_commentFilteredJson, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//		This tests loading a comment-filtered json file so that people using secure
 				//		data with this store can bypass the JavaSceipt hijack noted in Fortify's
@@ -1037,9 +1037,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() withNull",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item where some attributes are null.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item where some attributes are null.
 				//		Introduced because of tracker: #3153
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries_withNull"));
@@ -1063,9 +1063,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() withNull, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item where some attributes are null.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item where some attributes are null.
 				//		Introduced because of tracker: #3153
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries_withNull"));
@@ -1089,9 +1089,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() all_streaming",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -1127,9 +1127,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() paging",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
-				//	description:
+				// description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -1199,9 +1199,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType Match",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//		Introduced because of tracker: #4931
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("data_multitype"));
@@ -1225,9 +1225,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType Match, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//		Introduced because of tracker: #4931
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("data_multitype"));
@@ -1251,9 +1251,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType, MultiValue Match",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//		Introduced because of tracker: #4931
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("data_multitype"));
@@ -1277,9 +1277,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType, MultiValue Match, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
-				//	description:
+				// description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//		Introduced because of tracker: #4931
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("data_multitype"));
@@ -1303,9 +1303,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getLabel()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -1331,9 +1331,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getLabel(), complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -1359,9 +1359,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getLabelAttributes()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -1387,9 +1387,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getLabelAttributes(), complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -1415,9 +1415,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getValue()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -1439,9 +1439,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getValues()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getValues function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValues function of the store.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -1465,9 +1465,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: isItem()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isItem function of the store
-				//	description:
+				// description:
 				//		Simple test of the isItem function of the store
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -1489,11 +1489,11 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: isItem() multistore",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isItem function of the store
 				//		to verify two different store instances do not accept
 				//		items from each other.
-				//	description:
+				// description:
 				//		Simple test of the isItem function of the store
 				//		to verify two different store instances do not accept
 				//		items from each other.
@@ -1532,9 +1532,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: hasAttribute()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute function of the store
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute function of the store
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -1565,9 +1565,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: containsValue()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue function of the store
-				//	description:
+				// description:
 				//		Simple test of the containsValue function of the store
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -1599,9 +1599,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getAttributes()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes function of the store
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -1628,9 +1628,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getFeatures()",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getFeatures function of the store
-				//	description:
+				// description:
 				//		Simple test of the getFeatures function of the store
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -1642,9 +1642,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch0",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of everything starting with lowercase e
-				//	description:
+				// description:
 				//		Function to test pattern matching of everything starting with lowercase e
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -1677,9 +1677,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch0, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of everything starting with lowercase e
-				//	description:
+				// description:
 				//		Function to test pattern matching of everything starting with lowercase e
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -1712,9 +1712,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch1",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of everything with $ in it.
-				//	description:
+				// description:
 				//		Function to test pattern matching of everything with $ in it.
 	
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -1760,9 +1760,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch1, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of everything with $ in it.
-				//	description:
+				// description:
 				//		Function to test pattern matching of everything with $ in it.
 	
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -1808,9 +1808,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch2",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test exact pattern match
-				//	description:
+				// description:
 				//		Function to test exact pattern match
 	
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -1856,9 +1856,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch2, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test exact pattern match
-				//	description:
+				// description:
 				//		Function to test exact pattern match
 	
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -1904,9 +1904,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseSensitive",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of a pattern case-sensitively
-				//	description:
+				// description:
 				//		Function to test pattern matching of a pattern case-sensitively
 	
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -1947,9 +1947,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseSensitive, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of a pattern case-sensitively
-				//	description:
+				// description:
 				//		Function to test pattern matching of a pattern case-sensitively
 	
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -1990,9 +1990,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseInsensitive",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of a pattern case-insensitively
-				//	description:
+				// description:
 				//		Function to test pattern matching of a pattern case-insensitively
 	
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2033,9 +2033,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseInsensitive, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test pattern matching of a pattern case-insensitively
-				//	description:
+				// description:
 				//		Function to test pattern matching of a pattern case-insensitively
 	
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2076,9 +2076,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumeric",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting numerically.
-				//	description:
+				// description:
 				//		Function to test sorting numerically.
 				
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2129,9 +2129,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumericDescending",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting numerically.
-				//	description:
+				// description:
 				//		Function to test sorting numerically.
 	
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2181,9 +2181,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumericWithCount",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting numerically in descending order, returning only a specified number of them.
-				//	description:
+				// description:
 				//		Function to test sorting numerically in descending order, returning only a specified number of them.
 			
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2236,9 +2236,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabetic",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting alphabetic ordering.
-				//	description:
+				// description:
 				//		Function to test sorting alphabetic ordering.
 			
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2303,9 +2303,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabeticDescending",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting alphabetic ordering in descending mode.
-				//	description:
+				// description:
 				//		Function to test sorting alphabetic ordering in descending mode.
 			
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2371,9 +2371,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortDate",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting date.
-				//	description:
+				// description:
 				//		Function to test sorting date.
 			
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2426,9 +2426,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortDateDescending",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting date in descending order.
-				//	description:
+				// description:
 				//		Function to test sorting date in descending order.
 			
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2482,9 +2482,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortMultiple",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting on multiple attributes.
-				//	description:
+				// description:
 				//		Function to test sorting on multiple attributes.
 				
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2551,9 +2551,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortMultipleSpecialComparator",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting on multiple attributes with a custom comparator.
-				//	description:
+				// description:
 				//		Function to test sorting on multiple attributes with a custom comparator.
 	
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2621,9 +2621,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabeticWithUndefined",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test sorting alphabetic ordering.
-				//	description:
+				// description:
 				//		Function to test sorting alphabetic ordering.
 			
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
@@ -2676,10 +2676,10 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: errorCondition_idCollision_inMemory",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
-				//	description:
+				// description:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
 	
@@ -2710,10 +2710,10 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: errorCondition_idCollision_xhr",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
-				//	description:
+				// description:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
 	
@@ -2763,7 +2763,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_Color_SimpleMapping",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test using literal values with custom datatypes
 				var dataset = {
 					identifier:'name',
@@ -2795,7 +2795,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_Color_GeneralMapping",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test using literal values with custom datatypes
 				var dataset = {
 					identifier:'name',
@@ -2942,9 +2942,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: functionConformance",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-				//	description:
+				// description:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 				var testStore = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				var readApi = new dojo.data.api.Read();
@@ -2970,9 +2970,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: functionConformance",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
-				//	description:
+				// description:
 				//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 				var testStore = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				var identityApi = new dojo.data.api.Identity();
@@ -3001,9 +3001,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, OR, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -3026,9 +3026,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND(OR, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -3051,9 +3051,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as json object, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -3076,9 +3076,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as json object, complex, with extra attrs",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -3101,9 +3101,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as json object, complex, with extra attrs and spaces",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -3130,9 +3130,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as quoted json object, complex",
 	 		runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				
@@ -3155,7 +3155,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset url.)",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
@@ -3211,7 +3211,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch, close (clearOnClose: true, reset url.)",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
@@ -3269,7 +3269,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset _jsonFileUrl.)",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
@@ -3325,9 +3325,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset data.)",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Function to test that clear on close and reset of data works.
-				//	description:
+				// description:
 				//		Function to test that clear on close and reset of data works.
 				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 						items: [ {uniqueId: 1, value:"foo*bar"},
@@ -3393,9 +3393,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API:  getFeatures",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getFeatures function of the store
-				//	description:
+				// description:
 				//		Simple test of the getFeatures function of the store
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3423,9 +3423,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API:  setValue",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the setValue API
-				//	description:
+				// description:
 				//		Simple test of the setValue API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3436,15 +3436,15 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(store.containsValue(item, "capital", "Cairo"));
 					
 					// FIXME:
-					//    Okay, so this seems very odd.  Maybe I'm just being dense.
-					//    These tests works:
+					//	  Okay, so this seems very odd.  Maybe I'm just being dense.
+					//	  These tests works:
 					t.assertEqual(store.isDirty(item), false);
 					t.assertTrue(store.isDirty(item) === false);
-					//    But these seemingly equivalent tests will not work:
+					//	  But these seemingly equivalent tests will not work:
 					// t.assertFalse(store.isDirty(item));
 					// t.assertTrue(!(store.isDirty(item)));
 					//
-					//    All of which seems especially weird, given that this *does* work:
+					//	  All of which seems especially weird, given that this *does* work:
 					t.assertFalse(store.isDirty());
 					
 					
@@ -3466,9 +3466,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: setValues",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the setValues API
-				//	description:
+				// description:
 				//		Simple test of the setValues API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3497,9 +3497,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: unsetAttribute",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the unsetAttribute API
-				//	description:
+				// description:
 				//		Simple test of the unsetAttribute API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3526,9 +3526,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the newItem API
-				//	description:
+				// description:
 				//		Simple test of the newItem API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3565,9 +3565,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem with a parent assignment",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the newItem API with a parent assignment
-				//	description:
+				// description:
 				//		Simple test of the newItem API with a parent assignment
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3624,9 +3624,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem with a parent assignment multiple times",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the newItem API with a parent assignment multiple times.
-				//	description:
+				// description:
 				//		Simple test of the newItem API with a parent assignment multiple times.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3691,9 +3691,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: deleteItem",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the deleteItem API
-				//	description:
+				// description:
 				//		Simple test of the deleteItem API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3725,9 +3725,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: isDirty",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isDirty API
-				//	description:
+				// description:
 				//		Simple test of the isDirty API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3751,9 +3751,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: revert",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the revert API
-				//	description:
+				// description:
 				//		Simple test of the revert API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3791,9 +3791,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: save",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the save API
-				//	description:
+				// description:
 				//		Simple test of the save API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3815,9 +3815,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: save, verify state",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the save API
-				//	description:
+				// description:
 				//		Simple test of the save API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -3842,9 +3842,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: saveEverything",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the save API
-				//	description:
+				// description:
 				//		Simple test of the save API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				var egypt;
@@ -3887,9 +3887,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: saveEverything with Date type",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the save API	with a non-atomic type (Date) that has a type mapping.
-				//	description:
+				// description:
 				//		Simple test of the save API	with a non-atomic type (Date) that has a type mapping.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 
@@ -3931,9 +3931,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: saveEverything, with custom color simple type",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
-				//	description:
+				// description:
 				//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
 	
 				//Set up the store basics:  What data it has, and what to do when save is called for saveEverything
@@ -3989,9 +3989,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: saveEverything, with custom color type general",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
-				//	description:
+				// description:
 				//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
 	
 				//Set up the store basics:  What data it has, and what to do when save is called for saveEverything
@@ -4055,9 +4055,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem, revert",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Test for bug #5357.  Ensure that the revert properly nulls the identity position
-				//      for a new item after revert.
+				//		for a new item after revert.
 				var args = {data: {
 					label:"name",
 					items:[
@@ -4084,9 +4084,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem, modify revert",
 			runTest: function(){
-				//	summary:
+				// summary:
 				//		Test of a new item, modify it, then revert, to ensure the state remains consistent.  Added due to #9022.
-				//	description:
+				// description:
 				//		Test of a new item, modify it, then revert, to ensure the state remains consistent.  Added due to #9022.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 
@@ -4121,9 +4121,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem, modify, delete, revert",
 			runTest: function(){
-				//	summary:
+				// summary:
 				//		Test of a new item, modify it, delete it, then revert, to ensure the state remains consistent.  Added due to #9022.
-				//	description:
+				// description:
 				//		Test of a new item, modify it, delete it, then revert, to ensure the state remains consistent.  Added due to #9022.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				var i;
@@ -4195,9 +4195,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: onSet notification",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the onSet API
-				//	description:
+				// description:
 				//		Simple test of the onSet API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -4226,9 +4226,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: onNew notification",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the onNew API
-				//	description:
+				// description:
 				//		Simple test of the onNew API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -4247,9 +4247,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: onDelete notification",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the onDelete API
-				//	description:
+				// description:
 				//		Simple test of the onDelete API
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -4275,9 +4275,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: Read API conformance",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-				//	description:
+				// description:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 				var testStore = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				var readApi = new dojo.data.api.Read();
@@ -4300,9 +4300,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: Write API conformance",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
-				//	description:
+				// description:
 				//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
 				var testStore = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				var writeApi = new dojo.data.api.Write();
@@ -4325,9 +4325,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: Notification API conformance",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test Notification API conformance.  Checks to see all declared functions are actual functions on the instances.
-				//	description:
+				// description:
 				//		Simple test Notification API conformance.  Checks to see all declared functions are actual functions on the instances.
 				var testStore = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				var api = new dojo.data.api.Notification();
@@ -4350,7 +4350,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: Identity, auto-creation when missing",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Test for bug #3873. Given a datafile that does not specify an
 				//		identifier, make sure AndOrWriteStore auto-creates identities
 				//		that are unique even after calls to deleteItem() and newItem()
@@ -4406,7 +4406,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: Identity, auto-creation when missing, revert",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Test for bug #4691  Given a datafile that does not specify an
 				//		identifier, make sure AndOrWriteStore auto-creates identities
 				//		that are unique even after calls to deleteItem() and newItem()
@@ -4469,9 +4469,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, check references",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test to verify the references were properly resolved.
-				//	description:
+				// description:
 				//		Simple test to verify the references were properly resolved.
 			
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("reference_integrity"));
@@ -4541,9 +4541,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, delete referenced item",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test to verify the references were properly deleted.
-				//	description:
+				// description:
 				//		Simple test to verify the references were properly deleted.
 			
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("reference_integrity"));
@@ -4599,9 +4599,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, delete referenced item, then revert",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test to verify the references were properly deleted.
-				//	description:
+				// description:
 				//		Simple test to verify the references were properly deleted.
 			
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("reference_integrity"));
@@ -4642,10 +4642,10 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, delete multiple items with references and revert",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test to verify that a flow of deleting items with references and reverting does not damage the internal structure.
 				//		Created for tracker bug: #5743
-				//	description:
+				// description:
 				//		Simple test to verify that a flow of deleting items with references and reverting does not damage the internal structure.
 				//		Created for tracker bug: #5743
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries_references"));
@@ -4688,9 +4688,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, remove reference from attribute",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test to verify the reference removal updates the internal map.
-				//	description:
+				// description:
 				//		Simple test to verify the reference removal updates the internal map.
 			
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("reference_integrity"));
@@ -4735,9 +4735,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, delete referenced item non-parent",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test to verify the references to a non-parent item was properly deleted.
-				//	description:
+				// description:
 				//		Simple test to verify the references to a non-parent item was properly deleted.
 			
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("reference_integrity"));
@@ -4792,9 +4792,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, add reference to attribute",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test to verify the reference additions can happen.
-				//	description:
+				// description:
 				//		Simple test to verify the reference additions can happen.
 			
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("reference_integrity"));
@@ -4837,9 +4837,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, new item with parent reference",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test to verify that newItems with a parent properly record the parent's reference in the map.
-				//	description:
+				// description:
 				//		Simple test to verify that newItems with a parent properly record the parent's reference in the map.
 			
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("reference_integrity"));
@@ -4881,9 +4881,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, new item with reference to existing item",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test to verify that a new item with references to existing items properly record the references in the map.
-				//	description:
+				// description:
 				//		Simple test to verify that a new item with references to existing items properly record the references in the map.
 			
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("reference_integrity"));
@@ -4929,9 +4929,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, disable reference integrity",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test to verify reference integrity can be disabled.
-				//	description:
+				// description:
 				//		Simple test to verify reference integrity can be disabled.
 			
 				var params = dojox.data.tests.stores.AndOrWriteStore.getTestData("reference_integrity");
diff --git a/dojox/data/tests/stores/AppStore.js b/dojox/data/tests/stores/AppStore.js
index 3270438..8487218 100644
--- a/dojox/data/tests/stores/AppStore.js
+++ b/dojox/data/tests/stores/AppStore.js
@@ -12,9 +12,9 @@ dojox.data.tests.stores.AppStore.getStore = function(preventCache){
 doh.register("dojox.data.tests.stores.AppStore",
 	[
 		function testReadAPI_fetch_all(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching all items
-			//	description:
+			// description:
 			//		Simple test of fetching all items
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -30,9 +30,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_preventCache(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching all items
-			//	description:
+			// description:
 			//		Simple test of fetching all items
 			var store = dojox.data.tests.stores.AppStore.getStore(true);
 
@@ -48,9 +48,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one item
-			//	description:
+			// description:
 			//		Simple test of fetching one item
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -66,9 +66,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			//	summary:
+			// summary:
 			//		Simple test of paging
-			//	description:
+			// description:
 			//		Simple test of paging
 			var store = dojox.data.tests.stores.AppStore.getStore();
 			
@@ -127,9 +127,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern0(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one item with ? pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one item with ? pattern match
 			var store = dojox.data.tests.stores.AppStore.getStore();
 			var d = new doh.Deferred();
@@ -144,9 +144,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern1(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one item with * pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one item with * pattern match
 			var store = dojox.data.tests.stores.AppStore.getStore();
 			var d = new doh.Deferred();
@@ -161,9 +161,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseInsensitive(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one item with * pattern match case insensitive
-			//	description:
+			// description:
 			//		Simple test of fetching one item with * pattern match case insensitive
 			var store = dojox.data.tests.stores.AppStore.getStore();
 			var d = new doh.Deferred();
@@ -179,9 +179,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_getLabel(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 
 			var store = dojox.data.tests.stores.AppStore.getStore();
@@ -201,9 +201,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 			var store = dojox.data.tests.stores.AppStore.getStore();
@@ -224,9 +224,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_getValue(t){
-			 //	summary:
+			 // summary:
 			 //		Simple test of the getValue API
-			 //	description:
+			 // description:
 			 //		Simple test of the getValue API
 			 var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -245,9 +245,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			 return d; //Object
 		},
 		function testReadAPI_getValues(t){
-			 //	summary:
+			 // summary:
 			 //		Simple test of the getValues API
-			 //	description:
+			 // description:
 			 //		Simple test of the getValues API
 			 var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -268,9 +268,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem(t){
-			 //	summary:
+			 // summary:
 			 //		Simple test of the isItem API
-			 //	description:
+			 // description:
 			 //		Simple test of the isItem API
 			 var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -291,9 +291,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem_multistore(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItem API across multiple store instances.
-			//	description:
+			// description:
 			//		Simple test of the isItem API across multiple store instances.
 			var store1 = dojox.data.tests.stores.AppStore.getStore();
 			var store2 = dojox.data.tests.stores.AppStore.getStore();
@@ -323,9 +323,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary:
+			// summary:
 			//		Simple test of the hasAttribute API
-			//	description:
+			// description:
 			//		Simple test of the hasAttribute API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -347,9 +347,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_containsValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the containsValue API
-			//	description:
+			// description:
 			//		Simple test of the containsValue API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -368,9 +368,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescending(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in descending order.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in descending order.
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -403,9 +403,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscending(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in ascending order.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in ascending order.
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -438,9 +438,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_isItemLoaded(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItemLoaded API
-			//	description:
+			// description:
 			//		Simple test of the isItemLoaded API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -458,9 +458,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = dojox.data.tests.stores.AppStore.getStore();
@@ -473,9 +473,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			t.assertEqual(3, count);
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes API
-			//	description:
+			// description:
 			//		Simple test of the getAttributes API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -494,9 +494,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_newItem(t){
-			//	summary:
+			// summary:
 			//		Simple test of the newItem API
-			//	description:
+			// description:
 			//		Simple test of the newItem API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -517,9 +517,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_newItemInCallback(t){
-			//	summary:
+			// summary:
 			//		Simple test of the newItem API
-			//	description:
+			// description:
 			//		Simple test of the newItem API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -552,9 +552,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_deleteItem(t){
-			//	summary:
+			// summary:
 			//		Simple test of the deleteItem API
-			//	description:
+			// description:
 			//		Simple test of the deleteItem API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -580,9 +580,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_setValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the setValue API
-			//	description:
+			// description:
 			//		Simple test of the setValue API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -602,9 +602,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_setValues(t){
-			//	summary:
+			// summary:
 			//		Simple test of the setValues API
-			//	description:
+			// description:
 			//		Simple test of the setValues API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -628,9 +628,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_unsetAttribute(t){
-			//	summary:
+			// summary:
 			//		Simple test of the unsetAttribute API
-			//	description:
+			// description:
 			//		Simple test of the unsetAttribute API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -651,9 +651,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_isDirty(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isDirty API
-			//	description:
+			// description:
 			//		Simple test of the isDirty API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -674,9 +674,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_revert(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isDirty API
-			//	description:
+			// description:
 			//		Simple test of the isDirty API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -707,9 +707,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_revert2(t){
-			//	summary:
+			// summary:
 			//		Simple test of the revert API
-			//	description:
+			// description:
 			//		Simple test of the revert API
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -746,9 +746,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_getIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching the identity of an item.
-			//	description:
+			// description:
 			//		Simple test of fetching the identity of an item.
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -767,9 +767,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_getIdentityAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching the identity attributes off an item,
-			//	description:
+			// description:
 			//		Simple test of fetching the identity attributes off an item,
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -789,9 +789,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_fetchItemByIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one atom item through its identity
-			//	description:
+			// description:
 			//		Simple test of fetching one atom item through its identity
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -809,9 +809,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_fetchItemByIdentity_fails(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one atom item through its identity fails correctly on no id match
-			//	description:
+			// description:
 			//		Simple test of fetching one atom item through its identity fails correctly on no id match
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
@@ -828,9 +828,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			var testStore = dojox.data.tests.stores.AppStore.getStore();
 			var readApi = new dojo.data.api.Read();
@@ -851,9 +851,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			t.assertTrue(passed);
 		},
 		function testWriteAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
 			var testStore = dojox.data.tests.stores.AppStore.getStore();
 			var writeApi = new dojo.data.api.Write();
@@ -873,9 +873,9 @@ doh.register("dojox.data.tests.stores.AppStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 			var testStore = dojox.data.tests.stores.AppStore.getStore();
 			var identityApi = new dojo.data.api.Identity();
diff --git a/dojox/data/tests/stores/AtomReadStore.js b/dojox/data/tests/stores/AtomReadStore.js
index 06c71fe..609fa41 100644
--- a/dojox/data/tests/stores/AtomReadStore.js
+++ b/dojox/data/tests/stores/AtomReadStore.js
@@ -12,8 +12,9 @@ dojox.data.tests.stores.AtomReadStore.getBlog2Store = function(){
 };
 */
 dojox.data.tests.stores.AtomReadStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
+
 	//console.log("In here.");
 	//console.trace();
 	d.errback(errData);
@@ -25,9 +26,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  Fetch_One",
 			timeout:	5000, //1 second
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AtomReadStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AtomReadStore of a single item.
 
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
@@ -51,9 +52,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  Fetch_5_Streaming",
 			timeout:	5000, //1 second.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on AtomReadStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on AtomReadStore.
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
 
@@ -87,9 +88,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  Fetch_Paging",
 			timeout:	5000, //1 second.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
-				//	description:
+				// description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
@@ -166,9 +167,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  getLabel",
 			timeout:	5000, //1 second.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
@@ -194,9 +195,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  getLabelAttributes",
 			timeout:	5000, //1 second
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
@@ -224,9 +225,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  getValue",
 			timeout:	5000, //1 second
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
 
@@ -256,9 +257,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  getValue_Failure",
 			timeout:	5000, //1 second
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
 				var passed = false;
@@ -274,9 +275,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  getValues",
 			timeout:	5000, //1 second
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
 
@@ -313,9 +314,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  getValues_Failure",
 			timeout:	5000, //1 second
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
 				var passed = false;
@@ -331,9 +332,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  isItem",
 			timeout:	5000, //1 second
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the isItem function of the store
-				//	description:
+				// description:
 				//		Simple test of the isItem function of the store
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
 
@@ -361,9 +362,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  hasAttribute",
 			timeout:	5000, //1 second
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute function of the store
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute function of the store
 
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
@@ -421,9 +422,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  containsValue",
 			timeout:	5000, //1 second
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue function of the store
-				//	description:
+				// description:
 				//		Simple test of the containsValue function of the store
 
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
@@ -452,9 +453,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  getAttributes",
 			timeout:	5000, //1 second
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes function of the store
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
@@ -485,9 +486,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  fetch_Category",
 			timeout:	5000, //1 second.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Retrieve items from the store by category
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
@@ -525,9 +526,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  fetch_byID",
 			timeout:	5000, //1 second.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Retrieve items from the store by category
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
@@ -560,9 +561,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			name: "ReadAPI:  fetch_alternate",
 			timeout:	5000, //1 second.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Retrieve items from the store by category
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 
 				var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
@@ -590,9 +591,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var atomStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
@@ -606,9 +607,9 @@ doh.register("dojox.data.tests.stores.AtomReadStore",
 			t.assertTrue(count === 1);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.AtomReadStore.getBlog1Store();
diff --git a/dojox/data/tests/stores/CssClassStore.js b/dojox/data/tests/stores/CssClassStore.js
index d5a0e60..7afc375 100755
--- a/dojox/data/tests/stores/CssClassStore.js
+++ b/dojox/data/tests/stores/CssClassStore.js
@@ -4,9 +4,9 @@ dojo.require("dojo.data.api.Read");
 dojo.require("dojo.data.api.Identity");
 
 dojox.data.tests.stores.CssClassStore.createStore = function(context){
-	//  summary:
+	// summary:
 	//		A simple helper function for getting the sample data used in each of the tests.
-	//  description:
+	// description:
 	//		A simple helper function for getting the sample data used in each of the tests.
 	var store = null;
 	if(dojo.isBrowser){
@@ -50,7 +50,7 @@ dojox.data.tests.stores.CssClassStore.createStore = function(context){
 };
 
 dojox.data.tests.stores.CssClassStore.verifyItems = function(cssClassStore, items, attribute, compareArray){
-	//  summary:
+	// summary:
 	//		A helper function for validating that the items array is ordered
 	//		the same as the compareArray
 	if(items.length != compareArray.length){ return false; }
@@ -64,7 +64,7 @@ dojox.data.tests.stores.CssClassStore.verifyItems = function(cssClassStore, item
 };
 
 dojox.data.tests.stores.CssClassStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	for (var i in errData) {
 		console.log(errData[i]);
@@ -78,9 +78,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			name: "testReadAPI_fetch",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on CssClassStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on CssClassStore.
 				var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 
@@ -100,9 +100,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			}
 		},
 		function testReadAPI_fetch_all(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CssClassStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CssClassStore.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore(['dojox/data/tests/stores/test1.css', 'dojox/data/tests/stores/test2.css']);
 			
@@ -120,10 +120,11 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withinContext(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CssClassStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CssClassStore.
+			
 			//dojox.data.tests.stores.CssClassStore.loadStylesheets();
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore(['dojox/data/tests/stores/test1.css']);
 			
@@ -142,10 +143,11 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withinMultipleSheetContext(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CssClassStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CssClassStore.
+		
 			//dojox.data.tests.stores.CssClassStore.loadStylesheets();
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore(['dojox/data/tests/stores/test1.css', 'dojox/data/tests/stores/test2.css']);
 			
@@ -164,10 +166,11 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_switchContext(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CssClassStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CssClassStore.
+			
 			//dojox.data.tests.stores.CssClassStore.loadStylesheets();
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore(['dojox/data/tests/stores/test1.css', 'dojox/data/tests/stores/test2.css']);
 			
@@ -197,9 +200,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			
@@ -216,9 +219,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_sans(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			
@@ -235,9 +238,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_Multiple(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			
@@ -280,9 +283,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_MultipleMixed(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			
@@ -321,9 +324,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_streaming(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 
@@ -354,9 +357,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			 //	summary:
+			 // summary:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
-			 //	description:
+			 // description:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			
@@ -394,9 +397,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 		},
 		
 		function testReadAPI_getLabel(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			
@@ -416,9 +419,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			
@@ -438,9 +441,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_getValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 
@@ -459,9 +462,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_getValue_2(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 
@@ -480,9 +483,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_getValues(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValues function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValues function of the store.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 
@@ -503,9 +506,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_isItem(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItem function of the store
-			//	description:
+			// description:
 			//		Simple test of the isItem function of the store
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 
@@ -526,9 +529,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary:
+			// summary:
 			//		Simple test of the hasAttribute function of the store
-			//	description:
+			// description:
 			//		Simple test of the hasAttribute function of the store
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 
@@ -559,9 +562,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_containsValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the containsValue function of the store
-			//	description:
+			// description:
 			//		Simple test of the containsValue function of the store
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
  			
@@ -592,9 +595,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes function of the store
-			//	description:
+			// description:
 			//		Simple test of the getAttributes function of the store
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 
@@ -618,9 +621,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 
@@ -633,9 +636,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			t.assertTrue(count === 2);
 		},
 		function testReadAPI_fetch_patternMatch0(t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of everything swith Cla in it
-			//	description:
+			// description:
 			//		Function to test pattern matching of everything with Cla in it
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			var d = new doh.Deferred();
@@ -654,9 +657,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseInsensitive(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match with case insensitivity set.
-			//	description:
+			// description:
 			//		Function to test exact pattern match with case insensitivity set.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			var d = new doh.Deferred();
@@ -675,9 +678,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseSensitive(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match with case insensitivity set.
-			//	description:
+			// description:
 			//		Function to test exact pattern match with case insensitivity set.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			var d = new doh.Deferred();
@@ -695,9 +698,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabetic(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			var d = new doh.Deferred();
@@ -722,9 +725,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticDescending(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering in descending mode.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			var d = new doh.Deferred();
@@ -754,9 +757,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			var testStore = dojox.data.tests.stores.CssClassStore.createStore();
 			var readApi = new dojo.data.api.Read();
@@ -781,9 +784,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_fetchItemByIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			
@@ -800,9 +803,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad1(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			
@@ -819,9 +822,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad2(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			var d = new doh.Deferred();
@@ -837,9 +840,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad3(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			var d = new doh.Deferred();
@@ -855,9 +858,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testIdentityAPI_getIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			var d = new doh.Deferred();
@@ -878,9 +881,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testIdentityAPI_getIdentityAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getIdentityAttributes
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 			var d = new doh.Deferred();
diff --git a/dojox/data/tests/stores/CssRuleStore.js b/dojox/data/tests/stores/CssRuleStore.js
index b56c7a7..7ad9f37 100755
--- a/dojox/data/tests/stores/CssRuleStore.js
+++ b/dojox/data/tests/stores/CssRuleStore.js
@@ -4,9 +4,9 @@ dojo.require("dojo.data.api.Read");
 dojo.require("dojo.data.api.Identity");
 
 dojox.data.tests.stores.CssRuleStore.createStore = function(context){
-	//  summary:
+	// summary:
 	//		A simple helper function for getting the sample data used in each of the tests.
-	//  description:
+	// description:
 	//		A simple helper function for getting the sample data used in each of the tests.
 	var store = null;
 	if(dojo.isBrowser){
@@ -50,7 +50,7 @@ dojox.data.tests.stores.CssRuleStore.createStore = function(context){
 } ;
 
 dojox.data.tests.stores.CssRuleStore.verifyItems = function(cssRuleStore, items, attribute, compareArray){
-	//  summary:
+	// summary:
 	//		A helper function for validating that the items array is ordered
 	//		the same as the compareArray
 	if(items.length != compareArray.length){ return false; }
@@ -63,7 +63,7 @@ dojox.data.tests.stores.CssRuleStore.verifyItems = function(cssRuleStore, items,
 };
 
 dojox.data.tests.stores.CssRuleStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	for (var i in errData) {
 		console.log(errData[i]);
@@ -77,9 +77,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			name: "testReadAPI_fetch",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on CssRuleStorem longer timeout because initial load can sometimes take a bit..
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on CssRuleStorem longer timeout because initial load can sometimes take a bit.
 				var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 
@@ -99,9 +99,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			}
 		},
 		function testReadAPI_fetch_all(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CssRuleStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CssClassStore.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore(['dojox/data/tests/stores/test1.css', 'dojox/data/tests/stores/test2.css']);
 			
@@ -119,10 +119,11 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withinContext(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CssRuleStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CssRuleStore.
+		
 			//dojox.data.tests.stores.CssRuleStore.loadStylesheets();
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore(['dojox/data/tests/stores/test1.css']);
 			
@@ -141,10 +142,11 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withinMultipleSheetContext(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CssRuleStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CssRuleStore.
+			
 			//dojox.data.tests.stores.CssRuleStore.loadStylesheets();
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore(['dojox/data/tests/stores/test1.css', 'dojox/data/tests/stores/test2.css']);
 			
@@ -163,10 +165,11 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_switchContext(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CssRuleStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CssRuleStore.
+		
 			//dojox.data.tests.stores.CssRuleStore.loadStylesheets();
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore(['dojox/data/tests/stores/test1.css', 'dojox/data/tests/stores/test2.css']);
 			
@@ -196,9 +199,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			
@@ -215,9 +218,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_longer(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			
@@ -234,9 +237,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_Multiple(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			
@@ -279,9 +282,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_MultipleMixed(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			
@@ -320,9 +323,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_streaming(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 
@@ -353,9 +356,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			 //	summary:
+			 // summary:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
-			 //	description:
+			 // description:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			
@@ -394,9 +397,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 		},
 		
 		function testReadAPI_getLabel(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			
@@ -416,9 +419,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			
@@ -438,9 +441,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_getValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 
@@ -459,9 +462,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_getValue_2(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 
@@ -480,9 +483,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_getValues(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValues function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValues function of the store.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 
@@ -503,9 +506,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_isItem(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItem function of the store
-			//	description:
+			// description:
 			//		Simple test of the isItem function of the store
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 
@@ -526,9 +529,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary:
+			// summary:
 			//		Simple test of the hasAttribute function of the store
-			//	description:
+			// description:
 			//		Simple test of the hasAttribute function of the store
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 
@@ -559,9 +562,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_containsValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the containsValue function of the store
-			//	description:
+			// description:
 			//		Simple test of the containsValue function of the store
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
  			
@@ -592,9 +595,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes function of the store
-			//	description:
+			// description:
 			//		Simple test of the getAttributes function of the store
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 
@@ -622,9 +625,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 
@@ -637,9 +640,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			t.assertTrue(count === 1);
 		},
 		function testReadAPI_fetch_patternMatch(t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of everything swith Cla in it
-			//	description:
+			// description:
 			//		Function to test pattern matching of everything with Cla in it
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			var d = new doh.Deferred();
@@ -658,9 +661,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseInsensitive(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match with case insensitivity set.
-			//	description:
+			// description:
 			//		Function to test exact pattern match with case insensitivity set.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			var d = new doh.Deferred();
@@ -679,9 +682,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseSensitive(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match with case insensitivity set.
-			//	description:
+			// description:
 			//		Function to test exact pattern match with case insensitivity set.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			var d = new doh.Deferred();
@@ -699,9 +702,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabetic(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			var d = new doh.Deferred();
@@ -726,9 +729,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticDescending(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering in descending mode.
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			var d = new doh.Deferred();
@@ -756,9 +759,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			var testStore = dojox.data.tests.stores.CssRuleStore.createStore();
 			var readApi = new dojo.data.api.Read();
diff --git a/dojox/data/tests/stores/CsvStore.js b/dojox/data/tests/stores/CsvStore.js
index c8f5d75..8360067 100644
--- a/dojox/data/tests/stores/CsvStore.js
+++ b/dojox/data/tests/stores/CsvStore.js
@@ -4,9 +4,9 @@ dojo.require("dojo.data.api.Read");
 dojo.require("dojo.data.api.Identity");
 
 dojox.data.tests.stores.CsvStore.getDatasource = function(filepath){
-	//  summary:
+	// summary:
 	//		A simple helper function for getting the sample data used in each of the tests.
-	//  description:
+	// description:
 	//		A simple helper function for getting the sample data used in each of the tests.
 
 	var dataSource = {};
@@ -109,7 +109,7 @@ dojox.data.tests.stores.CsvStore.getDatasource = function(filepath){
 };
 
 dojox.data.tests.stores.CsvStore.verifyItems = function(csvStore, items, attribute, compareArray){
-	//  summary:
+	// summary:
 	//		A helper function for validating that the items array is ordered
 	//		the same as the compareArray
 	if(items.length != compareArray.length){ return false; }
@@ -122,7 +122,7 @@ dojox.data.tests.stores.CsvStore.verifyItems = function(csvStore, items, attribu
 };
 
 dojox.data.tests.stores.CsvStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	for (var i in errData) {
 		console.log(errData[i]);
@@ -133,9 +133,9 @@ dojox.data.tests.stores.CsvStore.error = function(t, d, errData){
 doh.register("dojox.data.tests.stores.CsvStore",
 	[
 		function testReadAPI_fetch_all(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -152,9 +152,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_empty(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore that's empty.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore that's empty.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/empty.csv");
@@ -171,9 +171,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_semicolon(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/semicolonSeparator.csv");
@@ -191,9 +191,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_pipe(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/pipeSeparator.csv");
 			args.separator = "|";
@@ -210,9 +210,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_pipe_indata(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/pipeSeparatorInData.csv");
 			args.separator = "|";
@@ -229,9 +229,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_withnewlinedCsv(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore loading a CSV file with quoted newlines.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore loading a CSV file with quoted newlines.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies3.csv");
@@ -248,9 +248,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_withEmptyStringField(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies2.csv");
@@ -267,9 +267,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -287,9 +287,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_preventcache(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -308,9 +308,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_Multiple(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -357,9 +357,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_MultipleMixed(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -395,9 +395,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_streaming(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on CsvStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on CsvStore.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -428,9 +428,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			 //	summary:
+			 // summary:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
-			 //	description:
+			 // description:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -496,9 +496,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 		
 		function testReadAPI_getLabel(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -520,9 +520,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 			 var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -544,9 +544,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d;
 		},
 		function testReadAPI_getValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -563,9 +563,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d;
 		},
 		function testReadAPI_getValue_2(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -582,9 +582,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d;
 		},
 		function testReadAPI_getValue_3(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -601,9 +601,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d;
 		},
 		function testReadAPI_getValue_4(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -621,9 +621,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testReadAPI_getValues(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValues function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValues function of the store.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -642,9 +642,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -660,9 +660,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_withDefinedIdentifier(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -679,9 +679,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_withDefinedIdentifier_bad1(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -698,9 +698,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_bad1(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -715,9 +715,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad2(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -731,9 +731,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad3(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -747,9 +747,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d;
 		},
 		function testIdentityAPI_getIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -775,9 +775,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testIdentityAPI_getIdentity_withDefinedIdentifier(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -804,9 +804,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testIdentityAPI_getIdentity_withBadDefinedIdentifier(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -827,9 +827,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testIdentityAPI_getIdentityAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getIdentityAttributes
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -845,9 +845,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		   	return d;
 		},
 		function testReadAPI_isItem(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItem function of the store
-			//	description:
+			// description:
 			//		Simple test of the isItem function of the store
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -866,9 +866,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		   	return d;
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary:
+			// summary:
 			//		Simple test of the hasAttribute function of the store
-			//	description:
+			// description:
 			//		Simple test of the hasAttribute function of the store
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -897,9 +897,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		   	return d;
 		},
 		function testReadAPI_containsValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the containsValue function of the store
-			//	description:
+			// description:
 			//		Simple test of the containsValue function of the store
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -929,9 +929,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		   	return d;
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes function of the store
-			//	description:
+			// description:
 			//		Simple test of the getAttributes function of the store
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -954,9 +954,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testReadAPI_getAttributes_onlyTwo(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes function of the store
-			//	description:
+			// description:
 			//		Simple test of the getAttributes function of the store
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -979,9 +979,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -996,9 +996,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			t.assertTrue(count === 2);
 		},
 		function testReadAPI_fetch_patternMatch0(t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of everything starting with lowercase e
-			//	description:
+			// description:
 			//		Function to test pattern matching of everything starting with lowercase e
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -1016,9 +1016,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch1(t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of everything with $ in it.
-			//	description:
+			// description:
 			//		Function to test pattern matching of everything with $ in it.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/patterns.csv");
@@ -1036,9 +1036,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch2(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match
-			//	description:
+			// description:
 			//		Function to test exact pattern match
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/patterns.csv");
@@ -1055,9 +1055,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseInsensitive(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match with case insensitivity set.
-			//	description:
+			// description:
 			//		Function to test exact pattern match with case insensitivity set.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/patterns.csv");
@@ -1074,9 +1074,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseSensitive(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match with case insensitivity set.
-			//	description:
+			// description:
 			//		Function to test exact pattern match with case insensitivity set.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/patterns.csv");
@@ -1092,9 +1092,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortNumeric(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting numerically.
-			//	description:
+			// description:
 			//		Function to test sorting numerically.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/patterns.csv");
@@ -1116,9 +1116,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortNumericDescending(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting numerically.
-			//	description:
+			// description:
 			//		Function to test sorting numerically.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/patterns.csv");
@@ -1138,9 +1138,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortNumericWithCount(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
-			//	description:
+			// description:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
 		
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/patterns.csv");
@@ -1163,9 +1163,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabetic(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering.
 		
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/patterns.csv");
@@ -1195,9 +1195,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticDescending(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering in descending mode.
 		
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/patterns.csv");
@@ -1227,9 +1227,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortMultiple(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting on multiple attributes.
-			//	description:
+			// description:
 			//		Function to test sorting on multiple attributes.
 			
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/patterns.csv");
@@ -1260,9 +1260,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortMultipleSpecialComparator(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting on multiple attributes with a custom comparator.
-			//	description:
+			// description:
 			//		Function to test sorting on multiple attributes with a custom comparator.
 
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
@@ -1312,11 +1312,11 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		{
 			name: "testReadAPI_fetch_abort",
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch abort on CsvStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch abort on CsvStore.
-				//Can only async abort in a browser, so disable this test from rhino
+				//		Can only async abort in a browser, so disable this test from rhino
 				if(dojo.isBrowser){
 					var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
 					var store = new dojox.data.CsvStore(args);
@@ -1352,9 +1352,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = new dojox.data.CsvStore(dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv"));
@@ -1380,9 +1380,9 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = new dojox.data.CsvStore(dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv"));
diff --git a/dojox/data/tests/stores/FileStore.js b/dojox/data/tests/stores/FileStore.js
index eda1177..46c7280 100755
--- a/dojox/data/tests/stores/FileStore.js
+++ b/dojox/data/tests/stores/FileStore.js
@@ -18,9 +18,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_all",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of fetching all xml items through an XML element called isbn
-				//	description:
+				// description:
 				//		Simple test of fetching all xml items through an XML element called isbn
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -40,9 +40,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_one",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of fetching one xml items through an XML element called isbn
-				//	description:
+				// description:
 				//		Simple test of fetching one xml items through an XML element called isbn
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -62,9 +62,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_paging",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of fetching a series of pages
-				//	description:
+				// description:
 				//		Simple test of fetching a series of pages
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -135,9 +135,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_pattern0",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of fetching a few files based on wildcarded name
-				//	description:
+				// description:
 				//		Simple test of fetching a few files based on wildcarded name
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 				var d = new doh.Deferred();
@@ -156,9 +156,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_pattern1",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of fetching a one files based on wildcarded name
-				//	description:
+				// description:
 				//		Simple test of fetching a one file based on wildcarded name
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 				var d = new doh.Deferred();
@@ -177,9 +177,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_pattern_caseInsensitive",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of fetching one file item case insensitively
-				//	description:
+				// description:
 				//		Simple test of fetching one file item case insensitively
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 				var d = new doh.Deferred();
@@ -198,9 +198,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_pattern_caseSensitive",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of fetching one file item case sensitively
-				//	description:
+				// description:
 				//		Simple test of fetching one file item case sensitively
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 				var d = new doh.Deferred();
@@ -219,9 +219,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_getLabel",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store
 
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
@@ -245,9 +245,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_getLabelAttributes",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
@@ -271,9 +271,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_getValue",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue API
-				//	description:
+				// description:
 				//		Simple test of the getValue API
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -296,9 +296,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_getValues",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValues API
-				//	description:
+				// description:
 				//		Simple test of the getValues API
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -323,9 +323,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_isItem",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the isItem API
-				//	description:
+				// description:
 				//		Simple test of the isItem API
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -350,9 +350,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_isItem_multistore",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the isItem API across multiple store instances.
-				//	description:
+				// description:
 				//		Simple test of the isItem API across multiple store instances.
 				var store1 = dojox.data.tests.stores.FileStore.getGeoStore();
 				var store2 = dojox.data.tests.stores.FileStore.getGeoStore();
@@ -386,9 +386,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_hasAttribute",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute API
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute API
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -411,9 +411,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_containsValue",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue API
-				//	description:
+				// description:
 				//		Simple test of the containsValue API
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -436,9 +436,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_sortDescending",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the sorting API in descending order.
-				//	description:
+				// description:
 				//		Simple test of the sorting API in descending order.
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -467,9 +467,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_sortAscending",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the sorting API in ascending order.
-				//	description:
+				// description:
 				//		Simple test of the sorting API in ascending order.
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -499,9 +499,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_isItemLoaded",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the isItemLoaded API
-				//	description:
+				// description:
 				//		Simple test of the isItemLoaded API
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -520,9 +520,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = dojox.data.tests.stores.FileStore.getGeoStore();
@@ -539,9 +539,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_getAttributes",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes API
-				//	description:
+				// description:
 				//		Simple test of the getAttributes API
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -564,9 +564,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			}
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.FileStore.getGeoStore();
@@ -596,9 +596,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testIdentityAPI_getIdentity",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes API
-				//	description:
+				// description:
 				//		Simple test of the getAttributes API
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -620,9 +620,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testIdentityAPI_getIdentityAttributes",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes API
-				//	description:
+				// description:
 				//		Simple test of the getAttributes API
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -647,9 +647,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testIdentityAPI_fetchItemByIdentity",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the fetchItemByIdentity API
-				//	description:
+				// description:
 				//		Simple test of the fetchItemByIdentity API
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
 
@@ -668,9 +668,9 @@ doh.register("dojox.data.tests.stores.FileStore",
 			}
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.FileStore.getGeoStore();
diff --git a/dojox/data/tests/stores/FlickrRestStore.js b/dojox/data/tests/stores/FlickrRestStore.js
index ef9adac..e79486f 100644
--- a/dojox/data/tests/stores/FlickrRestStore.js
+++ b/dojox/data/tests/stores/FlickrRestStore.js
@@ -4,10 +4,10 @@ dojo.require("dojo.data.api.Read");
 
 
 dojox.data.tests.stores.FlickrRestStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
-}
+};
 
 doh.register("dojox.data.tests.stores.FlickrRestStore",
 	[
@@ -15,9 +15,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  Fetch_One",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on FlickrRestStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on FlickrRestStore of a single item.
 
 				var flickrStore = new dojox.data.FlickrRestStore();
@@ -43,9 +43,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on FlickrRestStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on FlickrRestStore.
 				var flickrStore = new dojox.data.FlickrRestStore();
 
@@ -81,9 +81,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  Fetch_Paging",
 			timeout:	30000, //30 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
-				//	description:
+				// description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 
 				var flickrStore = new dojox.data.FlickrRestStore();
@@ -157,9 +157,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  getLabel",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 
 				var flickrStore = new dojox.data.FlickrRestStore();
@@ -187,9 +187,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  getLabelAttributes",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 				var flickrStore = new dojox.data.FlickrRestStore();
@@ -218,9 +218,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  getValue",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var flickrStore = new dojox.data.FlickrRestStore();
 
@@ -250,9 +250,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  getValues",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var flickrStore = new dojox.data.FlickrRestStore();
 
@@ -290,9 +290,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  isItem",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the isItem function of the store
-				//	description:
+				// description:
 				//		Simple test of the isItem function of the store
 				var flickrStore = new dojox.data.FlickrRestStore();
 
@@ -322,9 +322,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  hasAttribute",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute function of the store
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute function of the store
 
 				var flickrStore = new dojox.data.FlickrRestStore();
@@ -366,9 +366,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  containsValue",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue function of the store
-				//	description:
+				// description:
 				//		Simple test of the containsValue function of the store
 
 				var flickrStore = new dojox.data.FlickrRestStore();
@@ -396,9 +396,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  getAttributes",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes function of the store
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 
 				var flickrStore = new dojox.data.FlickrRestStore();
@@ -427,9 +427,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var flickrStore = new dojox.data.FlickrRestStore();
@@ -443,9 +443,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			t.assertTrue(count === 1);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = new dojox.data.FlickrRestStore();
diff --git a/dojox/data/tests/stores/FlickrStore.js b/dojox/data/tests/stores/FlickrStore.js
index c4e9d48..9f1ff63 100644
--- a/dojox/data/tests/stores/FlickrStore.js
+++ b/dojox/data/tests/stores/FlickrStore.js
@@ -4,10 +4,10 @@ dojo.require("dojo.data.api.Read");
 
 
 dojox.data.tests.stores.FlickrStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
-}
+};
 
 doh.register("dojox.data.tests.stores.FlickrStore",
 	[
@@ -15,9 +15,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  Fetch_One",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on FlickrStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on FlickrStore of a single item.
 
 				var flickrStore = new dojox.data.FlickrStore();
@@ -39,9 +39,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on FlickrStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on FlickrStore.
 				var flickrStore = new dojox.data.FlickrStore();
 
@@ -75,9 +75,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  Fetch_Paging",
 			timeout:	30000, //30 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
-				//	description:
+				// description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 
 				var flickrStore = new dojox.data.FlickrStore();
@@ -143,9 +143,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  getLabel",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 
 				var flickrStore = new dojox.data.FlickrStore();
@@ -169,9 +169,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  getLabelAttributes",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 				var flickrStore = new dojox.data.FlickrStore();
@@ -196,9 +196,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  getValue",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var flickrStore = new dojox.data.FlickrStore();
 
@@ -221,9 +221,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  getValues",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var flickrStore = new dojox.data.FlickrStore();
 
@@ -246,9 +246,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  isItem",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the isItem function of the store
-				//	description:
+				// description:
 				//		Simple test of the isItem function of the store
 				var flickrStore = new dojox.data.FlickrStore();
 
@@ -270,9 +270,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  hasAttribute",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute function of the store
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute function of the store
 
 				var flickrStore = new dojox.data.FlickrStore();
@@ -311,9 +311,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  containsValue",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue function of the store
-				//	description:
+				// description:
 				//		Simple test of the containsValue function of the store
 
 				var flickrStore = new dojox.data.FlickrStore();
@@ -337,9 +337,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  getAttributes",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes function of the store
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 
 				var flickrStore = new dojox.data.FlickrStore();
@@ -360,9 +360,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var flickrStore = new dojox.data.FlickrStore();
@@ -376,9 +376,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			t.assertTrue(count === 1);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = new dojox.data.FlickrStore();
diff --git a/dojox/data/tests/stores/GoogleFeedStore.js b/dojox/data/tests/stores/GoogleFeedStore.js
index 4a7f315..e350fcb 100644
--- a/dojox/data/tests/stores/GoogleFeedStore.js
+++ b/dojox/data/tests/stores/GoogleFeedStore.js
@@ -7,8 +7,9 @@ dojox.data.tests.stores.GoogleFeedStore.getStore = function(){
 };
 
 dojox.data.tests.stores.GoogleFeedStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
+
 	//console.trace();
 	d.errback(errData);
 };
@@ -19,9 +20,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  Fetch_One",
 			timeout:	10000, // 10 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on GoogleFeedStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on GoogleFeedStore of a single item.
 
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
@@ -46,9 +47,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  test_Invalid_Query",
 			timeout:	10000, // 10 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on GoogleFeedStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on GoogleFeedStore of a single item.
 
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
@@ -91,9 +92,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //20 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on GoogleFeedStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on GoogleFeedStore.
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
 
@@ -128,9 +129,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  Fetch_Paging",
 			timeout:	10000, // 10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
-				//	description:
+				// description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
@@ -200,9 +201,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  getLabel",
 			timeout:	10000, // 10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
@@ -229,9 +230,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  getLabelAttributes",
 			timeout:	10000, // 10 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
@@ -259,9 +260,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  getValue",
 			timeout:	10000, // 10 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
 
@@ -293,9 +294,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  getValue_Failure",
 			timeout:	10000, // 10 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
 				var passed = false;
@@ -311,9 +312,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  getValues",
 			timeout:	10000, // 10 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
 
@@ -361,9 +362,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  getValues_Failure",
 			timeout:	10000, // 10 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
 				var passed = false;
@@ -379,9 +380,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  isItem",
 			timeout:	10000, // 10 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the isItem function of the store
-				//	description:
+				// description:
 				//		Simple test of the isItem function of the store
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
 
@@ -410,9 +411,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  hasAttribute",
 			timeout:	10000, // 10 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute function of the store
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute function of the store
 
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
@@ -456,9 +457,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  containsValue",
 			timeout:	10000, // 10 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue function of the store
-				//	description:
+				// description:
 				//		Simple test of the containsValue function of the store
 
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
@@ -490,9 +491,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			name: "ReadAPI:  getAttributes",
 			timeout:	10000, // 10 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes function of the store
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 
 				var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
@@ -523,9 +524,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var googleStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
@@ -540,9 +541,9 @@ doh.register("dojox.data.tests.stores.GoogleFeedStore",
 			t.assertTrue(count === 1);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.GoogleFeedStore.getStore();
diff --git a/dojox/data/tests/stores/GoogleSearchStore.js b/dojox/data/tests/stores/GoogleSearchStore.js
index 5a3b231..dc7f03c 100644
--- a/dojox/data/tests/stores/GoogleSearchStore.js
+++ b/dojox/data/tests/stores/GoogleSearchStore.js
@@ -7,8 +7,9 @@ dojox.data.tests.stores.GoogleSearchStore.getStore = function(){
 };
 
 dojox.data.tests.stores.GoogleSearchStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
+
 	//console.trace();
 	d.errback(errData);
 };
@@ -19,9 +20,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  Fetch_One",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on GoogleSearchStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on GoogleSearchStore of a single item.
 
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
@@ -46,9 +47,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  test_Invalid_Query",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on GoogleSearchStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on GoogleSearchStore of a single item.
 
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
@@ -92,9 +93,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  Fetch_25_Streaming",
 			timeout:	30000, //20 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on GoogleSearchStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on GoogleSearchStore.
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
 
@@ -129,9 +130,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  Fetch_Paging",
 			timeout:	30000, // 30 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
-				//	description:
+				// description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
@@ -201,9 +202,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  getLabel",
 			timeout:	30000, // 30 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
@@ -230,9 +231,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  getLabelAttributes",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
@@ -260,9 +261,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  getValue",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
 
@@ -294,9 +295,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  getValue_Failure",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
 				var passed = false;
@@ -312,9 +313,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  getValues",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
 
@@ -362,9 +363,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  getValues_Failure",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
 				var passed = false;
@@ -380,9 +381,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  isItem",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the isItem function of the store
-				//	description:
+				// description:
 				//		Simple test of the isItem function of the store
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
 
@@ -411,9 +412,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  hasAttribute",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute function of the store
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute function of the store
 
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
@@ -458,9 +459,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  containsValue",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue function of the store
-				//	description:
+				// description:
 				//		Simple test of the containsValue function of the store
 
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
@@ -492,9 +493,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "ReadAPI:  getAttributes",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes function of the store
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
@@ -526,9 +527,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			name: "GoogleSearchStore:  DOM Cleanup",
 			timeout:	30000, // 30 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes function of the store
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 
 				var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
@@ -556,9 +557,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var googleStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
@@ -573,9 +574,9 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 			t.assertTrue(count === 1);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.GoogleSearchStore.getStore();
diff --git a/dojox/data/tests/stores/HtmlStore.js b/dojox/data/tests/stores/HtmlStore.js
index cabb060..5d99e52 100644
--- a/dojox/data/tests/stores/HtmlStore.js
+++ b/dojox/data/tests/stores/HtmlStore.js
@@ -34,9 +34,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
      dojo.data.api.Read API
 ***************************************/
 		function testReadAPI_fetch_all_table(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching all xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching all xml items through an XML element called isbn
 			var store = dojox.data.tests.stores.HtmlStore.getBooksStore();
 
@@ -52,9 +52,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_table_Whitespace(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching all table row items through an header called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching all table row items through an header called isbn
 			var store = dojox.data.tests.stores.HtmlStore.getBooksStoreWhitespace();
 
@@ -70,9 +70,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_list(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching all xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching all xml items through an XML element called isbn
 			var store = dojox.data.tests.stores.HtmlStore.getBooks3Store();
 
@@ -88,9 +88,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_table(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 
@@ -106,9 +106,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_table_Whitespace(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one item through an element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching one item through an element called isbn
 			var store = dojox.data.tests.stores.HtmlStore.getBooksStoreWhitespace();
 			var d = new doh.Deferred();
@@ -123,9 +123,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_list(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			var store = dojox.data.tests.stores.HtmlStore.getBooks3Store();
 
@@ -141,9 +141,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_list_oncreate(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			var store = dojox.data.tests.stores.HtmlStore.getBooks3StoreOnCreate();
 
@@ -159,9 +159,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_list_Whitespace(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one item through an attribute called name
-			//	description:
+			// description:
 			//		Simple test of fetching one item through an attribute called name
 			var store = dojox.data.tests.stores.HtmlStore.getBooks3StoreWhitespace();
 
@@ -177,9 +177,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			var store = dojox.data.tests.stores.HtmlStore.getBooksStore();
 			
@@ -245,9 +245,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern0(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -262,9 +262,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern1(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -279,9 +279,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern2(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -296,9 +296,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseInsensitive(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -313,9 +313,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseSensitive(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -330,9 +330,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getLabel_table(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
@@ -352,9 +352,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d;
 		},
 		function testReadAPI_getLabel_list(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 
 			var store = dojox.data.tests.stores.HtmlStore.getBooks3Store();
@@ -374,9 +374,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
@@ -396,9 +396,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 		},
 
 		function testReadAPI_getValue(t){
-			 //	summary:
+			 // summary:
 			 //		Simple test of the getValue API
-			 //	description:
+			 // description:
 			 //		Simple test of the getValue API
 			 var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 
@@ -417,9 +417,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			 return d; //Object
 		},
 		function testReadAPI_getValues(t){
-			 //	summary:
+			 // summary:
 			 //		Simple test of the getValues API
-			 //	description:
+			 // description:
 			 //		Simple test of the getValues API
 			 var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 
@@ -440,9 +440,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem(t){
-			 //	summary:
+			 // summary:
 			 //		Simple test of the isItem API
-			 //	description:
+			 // description:
 			 //		Simple test of the isItem API
 			 var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 
@@ -463,9 +463,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem_multistore(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItem API across multiple store instances.
-			//	description:
+			// description:
 			//		Simple test of the isItem API across multiple store instances.
 			var store1 = dojox.data.tests.stores.HtmlStore.getBooksStore();
 			var store2 = dojox.data.tests.stores.HtmlStore.getBooks2Store();
@@ -493,9 +493,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary:
+			// summary:
 			//		Simple test of the hasAttribute API
-			//	description:
+			// description:
 			//		Simple test of the hasAttribute API
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 
@@ -514,9 +514,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_containsValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the containsValue API
-			//	description:
+			// description:
 			//		Simple test of the containsValue API
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 
@@ -535,9 +535,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescending(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in descending order.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in descending order.
 			var store = dojox.data.tests.stores.HtmlStore.getBooksStore();
 
@@ -563,9 +563,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscending(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in ascending order.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in ascending order.
 			var store = dojox.data.tests.stores.HtmlStore.getBooksStore();
 
@@ -591,9 +591,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescendingNumeric(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
 			var store = dojox.data.tests.stores.HtmlStore.getBooksStore();
 
@@ -628,9 +628,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscendingNumeric(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
 			var store = dojox.data.tests.stores.HtmlStore.getBooksStore();
 
@@ -665,9 +665,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_isItemLoaded(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItemLoaded API
-			//	description:
+			// description:
 			//		Simple test of the isItemLoaded API
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 
@@ -685,9 +685,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
@@ -700,9 +700,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			t.assertEqual(2, count);
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes API
-			//	description:
+			// description:
 			//		Simple test of the getAttributes API
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 
@@ -724,9 +724,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.HtmlStore.getBooksStore();
@@ -751,9 +751,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
      dojo.data.api.Identity API
 ***************************************/
 		function testIdentityAPI_getIdentity_table(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes API
-			//	description:
+			// description:
 			//		Simple test of the getAttributes API
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 
@@ -771,9 +771,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_getIdentity_list(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes API
-			//	description:
+			// description:
 			//		Simple test of the getAttributes API
 			var store = dojox.data.tests.stores.HtmlStore.getBooks3Store();
 
@@ -791,9 +791,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_getIdentityAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes API
-			//	description:
+			// description:
 			//		Simple test of the getAttributes API
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 
@@ -813,9 +813,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_fetchItemByIdentity_table(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity API
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity API
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
 
@@ -833,9 +833,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_fetchItemByIdentity_list(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity API
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity API
 			var store = dojox.data.tests.stores.HtmlStore.getBooks3Store();
 
@@ -853,9 +853,9 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.HtmlStore.getBooksStore();
diff --git a/dojox/data/tests/stores/HtmlTableStore.js b/dojox/data/tests/stores/HtmlTableStore.js
index 84e09d2..f80e575 100644
--- a/dojox/data/tests/stores/HtmlTableStore.js
+++ b/dojox/data/tests/stores/HtmlTableStore.js
@@ -18,9 +18,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
      dojo.data.api.Read API
 ***************************************/
 		function testReadAPI_fetch_all(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching all xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching all xml items through an XML element called isbn
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooksStore();
 
@@ -36,9 +36,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 
@@ -54,9 +54,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooksStore();
 			
@@ -122,9 +122,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern0(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -139,9 +139,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern1(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -156,9 +156,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern2(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -173,9 +173,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseInsensitive(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -190,9 +190,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseSensitive(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -207,9 +207,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_getLabel(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
@@ -229,9 +229,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
@@ -251,9 +251,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 		},
 
 		function testReadAPI_getValue(t){
-			 //	summary:
+			 // summary:
 			 //		Simple test of the getValue API
-			 //	description:
+			 // description:
 			 //		Simple test of the getValue API
 			 var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 
@@ -272,9 +272,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			 return d; //Object
 		},
 		function testReadAPI_getValues(t){
-			 //	summary:
+			 // summary:
 			 //		Simple test of the getValues API
-			 //	description:
+			 // description:
 			 //		Simple test of the getValues API
 			 var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 
@@ -295,9 +295,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem(t){
-			 //	summary:
+			 // summary:
 			 //		Simple test of the isItem API
-			 //	description:
+			 // description:
 			 //		Simple test of the isItem API
 			 var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 
@@ -318,9 +318,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem_multistore(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItem API across multiple store instances.
-			//	description:
+			// description:
 			//		Simple test of the isItem API across multiple store instances.
 			var store1 = dojox.data.tests.stores.HtmlTableStore.getBooksStore();
 			var store2 = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
@@ -348,9 +348,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary:
+			// summary:
 			//		Simple test of the hasAttribute API
-			//	description:
+			// description:
 			//		Simple test of the hasAttribute API
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 
@@ -369,9 +369,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_containsValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the containsValue API
-			//	description:
+			// description:
 			//		Simple test of the containsValue API
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 
@@ -390,9 +390,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescending(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in descending order.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in descending order.
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooksStore();
 
@@ -418,9 +418,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscending(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in ascending order.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in ascending order.
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooksStore();
 
@@ -446,9 +446,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescendingNumeric(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooksStore();
 
@@ -483,9 +483,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscendingNumeric(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooksStore();
 
@@ -520,9 +520,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_isItemLoaded(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItemLoaded API
-			//	description:
+			// description:
 			//		Simple test of the isItemLoaded API
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 
@@ -540,9 +540,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
@@ -555,9 +555,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			t.assertEqual(2, count);
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes API
-			//	description:
+			// description:
 			//		Simple test of the getAttributes API
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 
@@ -579,9 +579,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.HtmlTableStore.getBooksStore();
@@ -606,9 +606,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
      dojo.data.api.Identity API
 ***************************************/
 		function testIdentityAPI_getIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes API
-			//	description:
+			// description:
 			//		Simple test of the getAttributes API
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 
@@ -626,9 +626,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testIdentityAPI_getIdentityAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes API
-			//	description:
+			// description:
 			//		Simple test of the getAttributes API
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 
@@ -648,9 +648,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testIdentityAPI_fetchItemByIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity API
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity API
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
 
@@ -668,9 +668,9 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.HtmlTableStore.getBooksStore();
diff --git a/dojox/data/tests/stores/JsonQueryRestStore.js b/dojox/data/tests/stores/JsonQueryRestStore.js
index a6b0572..0d06c10 100644
--- a/dojox/data/tests/stores/JsonQueryRestStore.js
+++ b/dojox/data/tests/stores/JsonQueryRestStore.js
@@ -3,10 +3,10 @@ dojo.require("dojox.data.ClientFilter");
 dojo.require("dojox.data.JsonQueryRestStore");
 
 dojox.data.tests.stores.JsonQueryRestStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
-}
+};
 testService = function(query){
 	lastQuery = query;
 	var deferred = new dojo.Deferred();
@@ -28,7 +28,7 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch using a query object",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:{name:"Car"},
@@ -45,7 +45,7 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch+Sorting using a query object",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:{name:"Car"},
@@ -63,7 +63,7 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch all items (and cache for the next tests)",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"",
@@ -83,7 +83,7 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch using a query object",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				lastQuery = null;
@@ -102,7 +102,7 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch using a JSONQuery",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				lastQuery = null;
@@ -121,7 +121,7 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch using a JSONQuery with operator",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				lastQuery = null;
@@ -140,7 +140,7 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch using a JSONQuery with operator and paging",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				lastQuery = null;
@@ -160,7 +160,7 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Sorting",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				lastQuery = null;
@@ -180,7 +180,7 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Sorting + Paging",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				jsonStore.jsonQueryPagination = true;
 				var d = new doh.Deferred();
diff --git a/dojox/data/tests/stores/JsonRestStore.js b/dojox/data/tests/stores/JsonRestStore.js
index 34e7314..25e4dca 100644
--- a/dojox/data/tests/stores/JsonRestStore.js
+++ b/dojox/data/tests/stores/JsonRestStore.js
@@ -6,10 +6,10 @@ dojo.require("dojox.json.schema");
 dojo.require("dojo.data.api.Read");
 
 dojox.data.tests.stores.JsonRestStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
-}
+};
 testServices = new dojox.rpc.Service(require.toUrl("dojox/rpc/tests/resources/test.smd"));
 testServices.jsonRestStore.servicePath = "/jsonRest.Store/"; // this makes the regex more challenging
 jsonStore = new dojox.data.JsonRestStore({service:testServices.jsonRestStore});
@@ -20,7 +20,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Fetch some items",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonRestStore of a simple query.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"query",
@@ -37,7 +37,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "fetch by id",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonRestStore of a single item.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"obj1",
@@ -57,7 +57,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Modify,save, check by id",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Fetch an item from a query, modify and save it, and check to see if it was modified correctly
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"query",
@@ -89,7 +89,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Revert",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		append/post an item, delete it, sort the lists, resort the list, saving each time.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"obj1",
@@ -115,7 +115,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Delete",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		append/post an item, delete it, sort the lists, resort the list, saving each time.
 				var d = new doh.Deferred();
 				jsonStore.fetchItemByIdentity({identity:"obj1",
@@ -138,7 +138,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Lazy loading",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		test lazy loading
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"query",
@@ -159,7 +159,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Lazy loading 2",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		test lazy loading
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"query",
@@ -182,7 +182,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Load Lazy Value",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on ServiceStore of a single item.
 				var d = new doh.Deferred();
 				jsonStore.fetchItemByIdentity({identity:"obj1",
@@ -204,7 +204,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "IdentityAPI: fetchItemByIdentity and getIdentity",
 			timeout: 30000,
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Verify the fetchItemByIdentity method works
 				var d = new doh.Deferred();
 		
@@ -222,7 +222,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Json can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		fetching with paging
 
 				var d = new doh.Deferred();
@@ -273,9 +273,9 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var readApi = new dojo.data.api.Read();
diff --git a/dojox/data/tests/stores/KeyValueStore.js b/dojox/data/tests/stores/KeyValueStore.js
index 2e40324..92f1e7e 100644
--- a/dojox/data/tests/stores/KeyValueStore.js
+++ b/dojox/data/tests/stores/KeyValueStore.js
@@ -4,9 +4,9 @@ dojo.require("dojo.data.api.Read");
 dojo.require("dojo.data.api.Identity");
 
 dojox.data.tests.stores.KeyValueStore.getDatasource = function(type){
-	//  summary:
+	// summary:
 	//		A simple helper function for getting the sample data used in each of the tests.
-	//  description:
+	// description:
 	//		A simple helper function for getting the sample data used in each of the tests.
 
 	var dataSource = {};
@@ -29,10 +29,10 @@ dojox.data.tests.stores.KeyValueStore.getDatasource = function(type){
 		dataSource.data = keyData;
 	}
 	return dataSource; //Object
-}
+};
 
 dojox.data.tests.stores.KeyValueStore.verifyItems = function(keyStore, items, attribute, compareArray){
-	//  summary:
+	// summary:
 	//		A helper function for validating that the items array is ordered
 	//		the same as the compareArray
 	if(items.length != compareArray.length){ return false; }
@@ -42,23 +42,23 @@ dojox.data.tests.stores.KeyValueStore.verifyItems = function(keyStore, items, at
 		}
 	}
 	return true; //Boolean
-}
+};
 
 dojox.data.tests.stores.KeyValueStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	for (i in errData) {
 		console.log(errData[i]);
 	}
 	d.errback(errData);
-}
+};
 
 doh.register("dojox.data.tests.stores.KeyValueStore",
 	[
 		function testReadAPI_fetch_all(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on KeyValueStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on KeyValueStore.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/properties.js");
@@ -75,9 +75,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_withEmptyStringField(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on KeyValueStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on KeyValueStore.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource();
@@ -94,9 +94,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource();
@@ -114,9 +114,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_Multiple(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource();
@@ -163,9 +163,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_MultipleMixed(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource();
@@ -202,9 +202,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_streaming(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on KeyValueStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on KeyValueStore.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource();
@@ -235,9 +235,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			 //	summary:
+			 // summary:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
-			 //	description:
+			 // description:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource();
@@ -302,9 +302,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 		},
 		
 		function testReadAPI_getLabel(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource();
@@ -325,9 +325,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 			 var args = dojox.data.tests.stores.KeyValueStore.getDatasource();
@@ -348,9 +348,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d;
 		},
 		function testReadAPI_getValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -368,9 +368,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d;
 		},
 		function testReadAPI_getValue_2(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -388,9 +388,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d;
 		},
 		function testReadAPI_getValue_3(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -408,9 +408,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d;
 		},
 		function testReadAPI_getValue_4(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -428,9 +428,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d;
 		},
 		function testReadAPI_getValues(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValues function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValues function of the store.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -449,9 +449,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -467,9 +467,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_bad1(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -484,9 +484,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad2(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -500,9 +500,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad3(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -516,9 +516,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d;
 		},
 		function testIdentityAPI_getIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -542,9 +542,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testIdentityAPI_getIdentityAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getIdentityAttributes
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -560,9 +560,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 		   	return d;
 		},
 		function testReadAPI_isItem(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItem function of the store
-			//	description:
+			// description:
 			//		Simple test of the isItem function of the store
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -581,9 +581,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 		   	return d;
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary:
+			// summary:
 			//		Simple test of the hasAttribute function of the store
-			//	description:
+			// description:
 			//		Simple test of the hasAttribute function of the store
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -613,9 +613,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 		   	return d;
 		},
 		function testReadAPI_containsValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the containsValue function of the store
-			//	description:
+			// description:
 			//		Simple test of the containsValue function of the store
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -645,9 +645,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 		   	return d;
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes function of the store
-			//	description:
+			// description:
 			//		Simple test of the getAttributes function of the store
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -670,9 +670,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 		},
 
 		function testReadAPI_getAttributes_onlyTwo(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes function of the store
-			//	description:
+			// description:
 			//		Simple test of the getAttributes function of the store
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -696,9 +696,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 		},
 
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -713,9 +713,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			t.assertTrue(count === 2);
 		},
 		function testReadAPI_fetch_patternMatch0(t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of everything starting with lowercase e
-			//	description:
+			// description:
 			//		Function to test pattern matching of everything starting with lowercase e
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -733,9 +733,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch1(t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of everything with $ in it.
-			//	description:
+			// description:
 			//		Function to test pattern matching of everything with $ in it.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/patterns.csv");
@@ -753,9 +753,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch2(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match
-			//	description:
+			// description:
 			//		Function to test exact pattern match
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/patterns.csv");
@@ -775,9 +775,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseInsensitive(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match with case insensitivity set.
-			//	description:
+			// description:
 			//		Function to test exact pattern match with case insensitivity set.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/patterns.csv");
@@ -794,9 +794,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseSensitive(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match with case insensitivity set.
-			//	description:
+			// description:
 			//		Function to test exact pattern match with case insensitivity set.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/patterns.csv");
@@ -812,9 +812,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabetic(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering.
 		
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/patterns.csv");
@@ -834,9 +834,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticDescending(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering in descending mode.
 		
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/patterns.csv");
@@ -856,9 +856,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortMultiple(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting on multiple attributes.
-			//	description:
+			// description:
 			//		Function to test sorting on multiple attributes.
 			
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/patterns.csv");
@@ -890,9 +890,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortMultipleSpecialComparator(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting on multiple attributes with a custom comparator.
-			//	description:
+			// description:
 			//		Function to test sorting on multiple attributes with a custom comparator.
 
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
@@ -939,9 +939,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = new dojox.data.KeyValueStore(dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv"));
@@ -967,9 +967,9 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = new dojox.data.KeyValueStore(dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv"));
diff --git a/dojox/data/tests/stores/OpenSearchStore.js b/dojox/data/tests/stores/OpenSearchStore.js
index c755223..1033640 100644
--- a/dojox/data/tests/stores/OpenSearchStore.js
+++ b/dojox/data/tests/stores/OpenSearchStore.js
@@ -31,9 +31,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_fetch_all_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of fetching all atom entries
-				//	description:
+				// description:
 				//		Simple test of fetching all atom entries
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 	
@@ -53,9 +53,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_fetch_all_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of fetching all atom entries
-				//	description:
+				// description:
 				//		Simple test of fetching all atom entries
 				var store = dojox.data.tests.stores.OpenSearchStore.getRSSStore();
 	
@@ -75,9 +75,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_fetch_all_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of fetching all atom entries
-				//	description:
+				// description:
 				//		Simple test of fetching all atom entries
 				var store = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
 	
@@ -97,9 +97,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_fetch_paging_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of fetching one xml items through an XML element called isbn
-				//	description:
+				// description:
 				//		Simple test of fetching one xml items through an XML element called isbn
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 
@@ -162,9 +162,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_fetch_paging_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of fetching one xml items through an XML element called isbn
-				//	description:
+				// description:
 				//		Simple test of fetching one xml items through an XML element called isbn
 				var store = dojox.data.tests.stores.OpenSearchStore.getRSSStore();
 
@@ -227,9 +227,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_fetch_paging_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of fetching one xml items through an XML element called isbn
-				//	description:
+				// description:
 				//		Simple test of fetching one xml items through an XML element called isbn
 				var store = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
 
@@ -292,9 +292,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getLabel',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				//		This test will be the same for all three types, so not bothering.
 	
@@ -317,9 +317,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getLabelAttributes',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				//		This test will be the same for all three types, so not bothering.
 	
@@ -343,9 +343,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValue_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getValue API
-				//	description:
+				// description:
 				//		Simple test of the getValue API
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 	
@@ -372,9 +372,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValue_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getValue API
-				//	description:
+				// description:
 				//		Simple test of the getValue API
 				var store = dojox.data.tests.stores.OpenSearchStore.getRSSStore();
 	
@@ -401,9 +401,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValue_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getValue API
-				//	description:
+				// description:
 				//		Simple test of the getValue API
 				var store = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
 	
@@ -432,9 +432,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValues_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getValues API
-				//	description:
+				// description:
 				//		Simple test of the getValues API
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 	
@@ -460,9 +460,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValues_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getValues API
-				//	description:
+				// description:
 				//		Simple test of the getValues API
 				var store = dojox.data.tests.stores.OpenSearchStore.getRSSStore();
 	
@@ -488,9 +488,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValues_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getValues API
-				//	description:
+				// description:
 				//		Simple test of the getValues API
 				var store = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
 	
@@ -516,9 +516,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItem_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isItem API
-				//	description:
+				// description:
 				//		Simple test of the isItem API
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 	
@@ -543,9 +543,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItem_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isItem API
-				//	description:
+				// description:
 				//		Simple test of the isItem API
 				var store = dojox.data.tests.stores.OpenSearchStore.getRSSStore();
 	
@@ -570,9 +570,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItem_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isItem API
-				//	description:
+				// description:
 				//		Simple test of the isItem API
 				var store = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
 	
@@ -597,9 +597,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItem_multistore',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isItem API across multiple store instances.
-				//	description:
+				// description:
 				//		Simple test of the isItem API across multiple store instances.
 				var store1 = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 				var store2 = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
@@ -631,9 +631,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_hasAttribute_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute API
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute API
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 	
@@ -657,9 +657,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_hasAttribute_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute API
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute API
 				var store = dojox.data.tests.stores.OpenSearchStore.getRSSStore();
 	
@@ -683,9 +683,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_hasAttribute_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute API
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute API
 				var store = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
 	
@@ -709,9 +709,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_containsValue_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue API
-				//	description:
+				// description:
 				//		Simple test of the containsValue API
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 	
@@ -734,9 +734,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_containsValue_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue API
-				//	description:
+				// description:
 				//		Simple test of the containsValue API
 				var store = dojox.data.tests.stores.OpenSearchStore.getRSSStore();
 	
@@ -759,9 +759,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_containsValue_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue API
-				//	description:
+				// description:
 				//		Simple test of the containsValue API
 				var store = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
 	
@@ -787,9 +787,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortDescending_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the sorting API in descending order.
-				//	description:
+				// description:
 				//		Simple test of the sorting API in descending order.
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 	
@@ -841,9 +841,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortDescending_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the sorting API in descending order.
-				//	description:
+				// description:
 				//		Simple test of the sorting API in descending order.
 				var store = dojox.data.tests.stores.OpenSearchStore.getRSSStore();
 	
@@ -895,9 +895,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortDescending_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the sorting API in descending order.
-				//	description:
+				// description:
 				//		Simple test of the sorting API in descending order.
 				var store = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
 	
@@ -948,9 +948,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortAscending_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the sorting API in descending order.
-				//	description:
+				// description:
 				//		Simple test of the sorting API in descending order.
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 	
@@ -1001,9 +1001,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortAscending_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the sorting API in descending order.
-				//	description:
+				// description:
 				//		Simple test of the sorting API in descending order.
 				var store = dojox.data.tests.stores.OpenSearchStore.getRSSStore();
 	
@@ -1054,9 +1054,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortAscending_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the sorting API in descending order.
-				//	description:
+				// description:
 				//		Simple test of the sorting API in descending order.
 				var store = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
 	
@@ -1107,9 +1107,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItemLoaded_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isItemLoaded API
-				//	description:
+				// description:
 				//		Simple test of the isItemLoaded API
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 	
@@ -1131,9 +1131,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItemLoaded_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isItemLoaded API
-				//	description:
+				// description:
 				//		Simple test of the isItemLoaded API
 				var store = dojox.data.tests.stores.OpenSearchStore.getRSSStore();
 	
@@ -1155,9 +1155,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItemLoaded_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the isItemLoaded API
-				//	description:
+				// description:
 				//		Simple test of the isItemLoaded API
 				var store = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
 	
@@ -1179,9 +1179,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getFeatures',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getFeatures function of the store
-				//	description:
+				// description:
 				//		Simple test of the getFeatures function of the store
 	
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
@@ -1197,9 +1197,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getAttributes_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes API
-				//	description:
+				// description:
 				//		Simple test of the getAttributes API
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
 
@@ -1224,9 +1224,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getAttributes_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes API
-				//	description:
+				// description:
 				//		Simple test of the getAttributes API
 				var store = dojox.data.tests.stores.OpenSearchStore.getRSSStore();
 
@@ -1251,9 +1251,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getAttributes_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes API
-				//	description:
+				// description:
 				//		Simple test of the getAttributes API
 				var store = dojox.data.tests.stores.OpenSearchStore.getHTMLStore();
 
@@ -1278,9 +1278,9 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_functionConformance',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-				//	description:
+				// description:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 	
 				var store = dojox.data.tests.stores.OpenSearchStore.getAtomStore();
diff --git a/dojox/data/tests/stores/OpmlStore.js b/dojox/data/tests/stores/OpmlStore.js
index 4630938..8bc3c2f 100644
--- a/dojox/data/tests/stores/OpmlStore.js
+++ b/dojox/data/tests/stores/OpmlStore.js
@@ -4,9 +4,9 @@ dojo.require("dojo.data.api.Read");
 dojo.require("dojo.data.api.Identity");
 
 dojox.data.tests.stores.OpmlStore.getDatasource = function(filepath){
-	//  summary:
+	// summary:
 	//		A simple helper function for getting the sample data used in each of the tests.
-	//  description:
+	// description:
 	//		A simple helper function for getting the sample data used in each of the tests.
 	
 	var dataSource = {};
@@ -128,10 +128,10 @@ dojox.data.tests.stores.OpmlStore.getDatasource = function(filepath){
 		dataSource.data = opmlData;
 	}
 	return dataSource; //Object
-}
+};
 
 dojox.data.tests.stores.OpmlStore.verifyItems = function(opmlStore, items, attribute, compareArray){
-	//  summary:
+	// summary:
 	//		A helper function for validating that the items array is ordered
 	//		the same as the compareArray
 	if(items.length != compareArray.length){ return false; }
@@ -141,20 +141,20 @@ dojox.data.tests.stores.OpmlStore.verifyItems = function(opmlStore, items, attri
 		}
 	}
 	return true; //Boolean
-}
+};
 
 dojox.data.tests.stores.OpmlStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
-}
+};
 
 doh.register("dojox.data.tests.stores.OpmlStore",
 	[
 		function testReadAPI_fetch_all(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on OpmlStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on OpmlStore.
 			
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -171,9 +171,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on OpmlStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on OpmlStore of a single item.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -192,9 +192,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 		},
 
 		function testReadAPI_fetch_one_Multiple(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on OpmlStore of a single item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on OpmlStore of a single item.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -231,9 +231,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 		},
 
 		function testReadAPI_fetch_one_MultipleMixed(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on OpmlStore of a single item mixing two fetch types.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on Cpmltore of a single item mixing two fetch types.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -274,9 +274,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 		},
 
 		function testReadAPI_fetch_one_deep(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on OpmlStore of a single item that's nested down as a child item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on OpmlStore of a single item that's nested down as a child item.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -296,9 +296,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 		},
 
 		function testReadAPI_fetch_one_deep_off(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on OpmlStore of a single item that's nested down as a child item.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on OpmlStore of a single item that's nested down as a child item.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -318,9 +318,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 		},
 
 		function testReadAPI_fetch_all_streaming(t){
-			//	summary:
+			// summary:
 			//		Simple test of a basic fetch on OpmlStore.
-			//	description:
+			// description:
 			//		Simple test of a basic fetch on OpmlStore.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -351,9 +351,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			 //	summary:
+			 // summary:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
-			 //	description:
+			 // description:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -418,9 +418,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 
 		},
 		function testReadAPI_getLabel(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -441,9 +441,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -465,9 +465,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 		},
 
 		function testReadAPI_getLabel_nondefault(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography_withspeciallabel.xml");
@@ -489,9 +489,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes_nondefault(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography_withspeciallabel.xml");
@@ -514,9 +514,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 		},
 
 		function testReadAPI_getValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValue function of the store.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -558,9 +558,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getValues(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValues function of the store.
-			//	description:
+			// description:
 			//		Simple test of the getValues function of the store.
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -602,9 +602,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_isItem(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItem function of the store
-			//	description:
+			// description:
 			//		Simple test of the isItem function of the store
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -629,9 +629,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary:
+			// summary:
 			//		Simple test of the hasAttribute function of the store
-			//	description:
+			// description:
 			//		Simple test of the hasAttribute function of the store
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -667,9 +667,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_containsValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the containsValue function of the store
-			//	description:
+			// description:
 			//		Simple test of the containsValue function of the store
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -710,9 +710,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes function of the store
-			//	description:
+			// description:
 			//		Simple test of the getAttributes function of the store
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -737,9 +737,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -754,9 +754,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			t.assertTrue(count === 2);
 		},
 		function testReadAPI_fetch_patternMatch0(t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of everything starting with Capital A
-			//	description:
+			// description:
 			//		Function to test pattern matching of everything starting with Capital A
 
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -774,9 +774,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch1(t){
-			//	summary:
+			// summary:
 			//		Function to test pattern matching of everything with America in it.
-			//	description:
+			// description:
 			//		Function to test pattern matching of everything with America in it.
 			
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -794,9 +794,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch2(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match
-			//	description:
+			// description:
 			//		Function to test exact pattern match
 			
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -813,9 +813,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseInsensitive(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match with case insensitivity set.
-			//	description:
+			// description:
 			//		Function to test exact pattern match with case insensitivity set.
 			
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -832,9 +832,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseSensitive(t){
-			//	summary:
+			// summary:
 			//		Function to test exact pattern match with case sensitivity set.
-			//	description:
+			// description:
 			//		Function to test exact pattern match with case sensitivity set.
 			
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -850,9 +850,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabetic(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering.
 		
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -872,9 +872,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticDescending(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
-			//	description:
+			// description:
 			//		Function to test sorting alphabetic ordering in descending mode.
 		
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -895,9 +895,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticWithCount(t){
-			//	summary:
+			// summary:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
-			//	description:
+			// description:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
 		
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -921,9 +921,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = new dojox.data.OpmlStore(dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml"));
@@ -947,9 +947,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_fetchItemByIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -965,9 +965,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_bad1(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -982,9 +982,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad2(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -998,9 +998,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad3(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -1014,9 +1014,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d;
 		},
 		function testIdentityAPI_getIdentity(t){
-			//	summary:
+			// summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
-			//	description:
+			// description:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
@@ -1041,9 +1041,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = new dojox.data.OpmlStore(dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml"));
diff --git a/dojox/data/tests/stores/PicasaStore.js b/dojox/data/tests/stores/PicasaStore.js
index 4144585..94a278a 100755
--- a/dojox/data/tests/stores/PicasaStore.js
+++ b/dojox/data/tests/stores/PicasaStore.js
@@ -4,7 +4,7 @@ dojo.require("dojo.data.api.Read");
 
 
 dojox.data.tests.stores.PicasaStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
 };
@@ -15,9 +15,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  Fetch_One",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on PicasaStore of a single item.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on PicasaStore of a single item.
 
 				var flickrStore = new dojox.data.PicasaStore();
@@ -39,9 +39,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on PicasaStore.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on PicasaStore.
 				var flickrStore = new dojox.data.PicasaStore();
 
@@ -75,9 +75,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  Fetch_Paging",
 			timeout:	30000, //30 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
-				//	description:
+				// description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 
 				var flickrStore = new dojox.data.PicasaStore();
@@ -144,9 +144,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  getLabel",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 
 				var flickrStore = new dojox.data.PicasaStore();
@@ -170,9 +170,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  getLabelAttributes",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 				var flickrStore = new dojox.data.PicasaStore();
@@ -197,9 +197,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  getValue",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var flickrStore = new dojox.data.PicasaStore();
 
@@ -222,9 +222,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  getValues",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var flickrStore = new dojox.data.PicasaStore();
 
@@ -247,9 +247,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  isItem",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the isItem function of the store
-				//	description:
+				// description:
 				//		Simple test of the isItem function of the store
 				var flickrStore = new dojox.data.PicasaStore();
 
@@ -271,9 +271,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  hasAttribute",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute function of the store
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute function of the store
 
 				var flickrStore = new dojox.data.PicasaStore();
@@ -311,9 +311,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  containsValue",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue function of the store
-				//	description:
+				// description:
 				//		Simple test of the containsValue function of the store
 
 				var flickrStore = new dojox.data.PicasaStore();
@@ -337,9 +337,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  getAttributes",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes function of the store
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 
 				var flickrStore = new dojox.data.PicasaStore();
@@ -360,9 +360,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var flickrStore = new dojox.data.PicasaStore();
@@ -377,9 +377,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			t.assertTrue(count === 1);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = new dojox.data.PicasaStore();
diff --git a/dojox/data/tests/stores/QueryReadStore.js b/dojox/data/tests/stores/QueryReadStore.js
index a01d786..5daf322 100644
--- a/dojox/data/tests/stores/QueryReadStore.js
+++ b/dojox/data/tests/stores/QueryReadStore.js
@@ -15,8 +15,8 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 	[
 		/*
 		function testDocTests(t) {
-			//	summary:
-			// 		Run all the doc comments.
+			// summary:
+			//		Run all the doc comments.
 			var doctest = new dojox.testing.DocTest();
 			doctest.run("dojox.data.QueryReadStore");
 			t.assertTrue(doctest.errors.length==0);
@@ -24,8 +24,6 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		*/
 		
 		function testReadApi_getValue(t){
-			//	summary:
-			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
 			var d = new doh.Deferred();
@@ -44,16 +42,15 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 				// the item is not an item or when the attribute is not a string.
 				t.assertError(Error, store, "getValue", ["not an item", "NOT THERE"]);
 				t.assertError(Error, store, "getValue", [item, {}]);
-				
-				d.callback(true);
 			}
-			store.fetch({query:{q:"Alabama"}, onComplete: onComplete});
+			store.fetch({
+				query:{q:"Alabama"},
+				onComplete: d.getTestCallback(onComplete)
+			});
 			return d; //Object
 		},
 
 		function testReadApi_getValues(t){
-			//	summary:
-			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
 			var d = new doh.Deferred();
@@ -77,15 +74,15 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 					errThrown = true;
 				}
 				t.assertTrue(errThrown);
-				d.callback(true);
 			}
-			store.fetch({query:{q:"Alabama"}, onComplete: onComplete});
+			store.fetch({
+				query:{q:"Alabama"},
+				onComplete: d.getTestCallback(onComplete)
+			});
 			return d; //Object
 		},
 		
 		function testReadApi_getAttributes(t){
-			//	summary:
-			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
 			var d = new doh.Deferred();
@@ -94,10 +91,11 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 				// The good case(s).
 				t.assertEqual(['id', 'name', 'label', 'abbreviation', 'capital'], store.getAttributes(item));
 				t.assertError(Error, store, "getAttributes", [{}]);
-				
-				d.callback(true);
 			}
-			store.fetch({query:{q:"Alabama"}, onComplete: onComplete});
+			store.fetch({
+				query:{q:"Alabama"},
+				onComplete: d.getTestCallback(onComplete)
+			});
 			return d; //Object
 		},
 
@@ -108,15 +106,15 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 				var item = items[0];
 				// The good cases.
 				t.assertEqual(["<img src='images/Alabama.jpg'/>Alabama"], store.getLabel(item));
-				d.callback(true);
 			}
-			store.fetch({query:{q:"Alabama"}, onComplete: onComplete});
+			store.fetch({
+				query:{q:"Alabama"},
+				onComplete: d.getTestCallback(onComplete)
+			});
 			return d; //Object
 		},
 
 		function testReadApi_hasAttribute(t){
-			//	summary:
-			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
 			var d = new doh.Deferred();
@@ -134,31 +132,30 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 				t.assertEqual(false, store.hasAttribute({}, "abbreviation"));
 				// pass in something that looks like the item with the attribute.
 				t.assertEqual(false, store.hasAttribute({name:"yo"}, "name"));
-				
-				d.callback(true);
 			}
-			store.fetch({query:{q:"Alaska"}, onComplete: onComplete});
+			store.fetch({
+				query:{q:"Alaska"},
+				onComplete: d.getTestCallback(onComplete)
+			});
 			return d; //Object
 		},
 
 		function testReadApi_containsValue(t){
-			//	summary:
-			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				var item = items[0];
 				t.assertTrue(store.containsValue(item, "name", "Alaska"));
-				d.callback(true);
 			}
-			store.fetch({query:{q:"Alaska"}, onComplete: onComplete});
+			store.fetch({
+				query:{q:"Alaska"},
+				onComplete: d.getTestCallback(onComplete)
+			});
 			return d; //Object
 		},
 
 		function testReadApi_isItem(t){
-			//	summary:
-			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
 			var d = new doh.Deferred();
@@ -169,15 +166,15 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 				t.assertEqual(false, store.isItem({}));
 				// Try to look like an item.
 				t.assertEqual(false, store.isItem({name:"Alaska", label:"Alaska", abbreviation:"AK"}));
-				d.callback(true);
 			}
-			store.fetch({query:{q:"Alaska"}, onComplete: onComplete});
+			store.fetch({
+				query:{q:"Alaska"},
+				onComplete: d.getTestCallback(onComplete)
+			});
 			return d; //Object
 		},
 
 		function testReadApi_isItemLoaded(t){
-			//	summary:
-			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
 			var d = new doh.Deferred();
@@ -185,145 +182,145 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 				var item = items[0];
 				// The good case(s).
 				t.assertTrue(store.isItemLoaded(item));
-				
-				d.callback(true);
 			}
-			store.fetch({query:{q:"Alabama"}, onComplete: onComplete});
+			store.fetch({
+				query:{q:"Alabama"},
+				onComplete: d.getTestCallback(onComplete)
+			});
 			return d; //Object
 		},
 
 		//function testReadApi_loadItem(t){
-		//	//	summary:
-		//	//	description:
+		//	// summary:
+		//	// description:
 		//	t.assertTrue(false);
 		//},
 
 		function testReadApi_fetch_all(t){
-			//	summary:
-			//		Simple test of fetching all items.
-			//	description:
+			// summary:
 			//		Simple test of fetching all items.
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 
 			var d = new doh.Deferred();
 			function onComplete(items, request) {
-				t.assertEqual(12, items.length);
-				d.callback(true);
+				t.assertEqual(9, items.length);
 			}
 			function onError(error, request) {
-				d.errback(error);
+				throw new Error(error);
 			}
-			store.fetch({query:{q:"m"}, onComplete: onComplete, onError: onError});
+			store.fetch({
+				query:{q:"m*"},
+				onComplete: d.getTestCallback(onComplete),
+				onError: d.getTestErrback(onError)
+			});
 			return d; //Object
 		},
 		
 		function testReadApi_fetch_onBegin(t){
-			//	summary:
-			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
-			//	description:
+			// summary:
 			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 
 			var d = new doh.Deferred();
-			var passed = false;
 			function onBegin(size, request){
-				t.assertEqual(12, size);
-				passed = true;
+				t.assertEqual(9, size);
 			}
 			function onComplete(items, request) {
 				t.assertEqual(5, items.length);
-				if(passed){
-					d.callback(true);
-				}else{
-					d.errback(new Error("Store did not return proper number of rows, regardless of page size"));
-				}
 			}
 			function onError(error, request) {
-				d.errback(error);
+				throw new Error(error);
 			}
-			store.fetch({query:{q:"m"}, start: 0, count: 5, onBegin: onBegin, onComplete: onComplete, onError: onError});
+			store.fetch({
+				query:{q:"m*"},
+				start: 0,
+				count: 5,
+				onBegin: d.getTestErrback(onBegin),
+				onComplete: d.getTestCallback(onComplete),
+				onError: d.getTestErrback(onError)
+			});
 			return d; //Object
 		},
 
 		function testReadApi_fetch_onBegin_ServersidePaging(t){
-			//	summary:
-			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
-			//	description:
+			// summary:
 			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 
 			var d = new doh.Deferred();
-			var passed = false;
+			var began = false;
 			function onBegin(size, request){
-				t.assertEqual(12, size);
-				passed = true;
+				t.assertEqual(9, size);
+				began = true;
 			}
 			function onComplete(items, request) {
-				t.assertEqual(5, items.length);
-				if(passed){
-					d.callback(true);
-				}else{
-					d.errback(new Error("Store did not return proper number of rows, regardless of page size"));
-				}
+				t.t(began, "onBegin was called");
+				t.assertEqual(4, items.length);	// 9 total, starting at 5, 4 left.
 			}
 			function onError(error, request) {
-				d.errback(error);
+				throw new Error(error);
 			}
-			store.fetch({query:{q:"m"}, start: 5, count: 5, onBegin: onBegin, onComplete: onComplete, onError: onError});
+
+			store.fetch({
+				query:{q:"m*"},
+				start: 5,
+				count: 5,
+				onBegin: d.getTestErrback(onBegin),
+				onComplete: d.getTestCallback(onComplete),
+				onError: d.getTestErrback(onError)
+			});
 			return d; //Object
 		},
 
 		function testReadApi_fetch_onBegin_ClientsidePaging(t){
-			//	summary:
-			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
-			//	description:
+			// summary:
 			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			store.doClientPaging = true;
 
 			var d = new doh.Deferred();
-			var passed = false;
 			function onBegin(size, request){
-				t.assertEqual(12, size);
-				passed = true;
+				t.assertEqual(9, size);
 			}
 			function onComplete(items, request) {
 				t.assertEqual(5, items.length);
-				if(passed){
-					d.callback(true);
-				}else{
-					d.errback(new Error("Store did not return proper number of rows, regardless of page size"));
-				}
 			}
 			function onError(error, request) {
-				d.errback(error);
+				throw new Error(error);
 			}
-			store.fetch({query:{q:"m"}, start: 0, count: 5, onBegin: onBegin, onComplete: onComplete, onError: onError});
+			store.fetch({
+				query:{q:"m*"},
+				start: 0,
+				count: 5,
+				onBegin: d.getTestErrback(onBegin),
+				onComplete: d.getTestCallback(onComplete),
+				onError: d.getTestErrback(onError)
+			});
 			return d; //Object
 		},
 
 		function testReadApi_fetch_one(t){
-			//	summary:
-			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
 			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(1, items.length);
-				d.callback(true);
 			}
 			function onError(error, request) {
-				d.errback(error);
+				throw new Error(error);
 			}
-			store.fetch({query:{q:"Alaska"}, onComplete: onComplete, onError: onError});
+			store.fetch({
+				query:{q:"Alaska"},
+				onComplete: d.getTestCallback(onComplete),
+				onError: d.getTestErrback(onError)
+			});
 			return d; //Object
 		},
 
 		function testReadApi_fetch_client_paging(t){
-			//	summary:
-			//		Lets test that paging on the same request does not trigger
+			// summary:
+			//		Let's test that paging on the same request does not trigger
 			//		server requests.
-			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			store.doClientPaging = true;
 
@@ -331,27 +328,32 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 			var firstItems = [];
 			var d = new doh.Deferred();
 			function onComplete(items, request) {
-				t.assertEqual(5, items.length);
+				t.assertEqual(5, items.length, "length of first fetch");
 				lastRequestHash = store.lastRequestHash;
 				firstItems = items;
 				
 				// Do the next request AFTER the previous one, so we are sure its sequential.
 				// We need to be sure so we can compare to the data from the first request.
 				function onComplete1(items, request) {
-					t.assertEqual(5, items.length);
-					t.assertEqual(lastRequestHash, store.lastRequestHash);
-					t.assertEqual(firstItems[1], items[0]);
-					d.callback(true);
+					t.assertEqual(5, items.length, "length of second fetch");
+					t.assertEqual(lastRequestHash, store.lastRequestHash, "lastRequestHash");
+					t.assertEqual(firstItems[1], items[0], "items[0]");
 				}
 				req.start = 1;
-				req.onComplete = onComplete1;
+				req.onComplete = d.getTestCallback(onComplete1);
 				store.fetch(req);
 			}
 			function onError(error, request) {
-				d.errback(error);
+				throw new Error(error);
 			}
-			var req = {query:{q:"m"}, start:0, count:5,
-						onComplete: onComplete, onError: onError};
+			var req = {
+				query:{q:"m*"},
+				start:0,
+				count:5,
+				onComplete: d.getTestErrback(onComplete),
+				onError: d.getTestErrback(onError)
+			};
+
 			store.fetch(req);
 			return d; //Object
 		},
@@ -386,16 +388,21 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 					t.assertEqual(store.getValue(firstItems[7], "name"), store.getValue(items[2], "name"));
 					t.assertEqual(store.getValue(firstItems[8], "name"), store.getValue(items[3], "name"));
 					t.assertEqual(store.getValue(firstItems[9], "name"), store.getValue(items[4], "name"));
-					d.callback(true);
 				}
 				// Init a new store, or it will use the old data, since the query has not changed.
 				store.doClientPaging = false;
 				store.fetch({start:5, count:5, onComplete: onComplete1, onError: onError});
 			}
 			function onError(error, request) {
-				d.errback(error);
+				throw new Error(error);
 			}
-			store.fetch({query:{}, start:0, count:10, onComplete: onComplete, onError: onError});
+			store.fetch({
+				query:{},
+				start:0,
+				count:10,
+				onComplete: d.getTestCallback(onComplete),
+				onError: d.getTestErrback(onError)
+			});
 			return d; //Object
 		},
 		
@@ -411,9 +418,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 			t.assertEqual(2, count);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
-			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.QueryReadStore.getStore();
diff --git a/dojox/data/tests/stores/QueryReadStore.php b/dojox/data/tests/stores/QueryReadStore.php
index 956ecaa..0126ab7 100644
--- a/dojox/data/tests/stores/QueryReadStore.php
+++ b/dojox/data/tests/stores/QueryReadStore.php
@@ -67,44 +67,48 @@ $allItems = array(
 	array('id'=>61, 'name'=>"Special chars !\"$%&/()=? <a >#'+*-_.:,; <", 'label'=>"Special chars !\"$%&/()=? <a >#'+*-_.:,;<", 'abbreviation'=>":-)", 'capital'=>'/dev/null'),
 );
 
-$q = "";
+
+// Query.   Null means no query at all (return all records), whereas any string, even the empty string,
+// is a filter.
+$q = null;
 if (array_key_exists("q", $_REQUEST)) {
 	$q = $_REQUEST['q'];
 }else if (array_key_exists("name", $_REQUEST)) {
 	$q = $_REQUEST['name'];
 }
 
-if (strlen($q) && $q[strlen($q)-1]=="*") {
+// Support wildcard search like "a*" to find all elements beginning with a, or "*" to find all elements
+// (same as no query at all)
+if ($q === "*") {
+	$q = null;	// treat it the same as no query at all
+}else if ($q && strlen($q) && $q[strlen($q)-1]=="*") {
 	$q = substr($q, 0, strlen($q)-1);
+	$wildcard = true;
 }
+
 $ret = array();
 foreach ($allItems as $item) {
 	$foundPos = -1;
-	$foundWord = false;
-	if ($q) {
-		$foundPos = strpos(strtolower($item['name']), strtolower($q));
-		$foundWord = $foundPos===0;
-		if (!$foundWord) {
-			$foundPos = strpos(strtolower($item['name']), ' '.strtolower($q));
-			if ($foundPos!==false) {
-				$foundPos += 1; // It was found, so subtract the offset the space occupied.
-				$foundWord = true;
-			}
+
+	// flag if item matches the query or not
+	$matches = true;
+
+	// If there's a query, run it, and set $matches if item matches.
+	// Allow query for empty string too, that's why it has the explicit test for null.
+	if ($q !== null) {
+		if($wildcard){
+			// query like "a*", check if item starts with "a"
+			$foundPos = strpos(strtolower($item['name']), strtolower($q));
+			$matches = $foundPos===0;
+		}else{
+			// query like "alabama", check if item matches query string exactly
+			$matches = strtolower($item['name']) == strtolower($q);
 		}
 	}
-	if (!$q || $foundWord) {
-		// Put a span around the searched characters to highlight them.
-		$resultItem = $item;
-		// Currently we dont need custom highlighting, its implemented in the client too.
-		//if ($foundWord) {
-		//	$resultItem['highlightedLabel'] = substr($item['name'], 0, $foundPos) .
-		//		'<span class="searchResult">' .
-		//		substr($item['name'], $foundPos, strlen($q)) . '</span>' .
-		//		substr($item['name'], $foundPos+strlen($q));
-		//} else {
-		//	$resultItem['highlightedLabel'] = $item['name'];
-		//}
-		$ret[] = $resultItem;
+
+	if ($matches) {
+		// Add item to result list
+		$ret[] = $item;
 	}
 }
 
diff --git a/dojox/data/tests/stores/ServiceStore.js b/dojox/data/tests/stores/ServiceStore.js
index c1da408..f6a8123 100644
--- a/dojox/data/tests/stores/ServiceStore.js
+++ b/dojox/data/tests/stores/ServiceStore.js
@@ -5,10 +5,10 @@ dojo.require("dojox.rpc.Rest");
 dojo.require("dojox.data.ServiceStore");
 dojo.require("dojo.data.api.Read");
 dojox.data.tests.stores.ServiceStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
-}
+};
 var testServices = new dojox.rpc.Service(require.toUrl("dojox/rpc/tests/resources/test.smd"));
 var jsonStore = new dojox.data.ServiceStore({service:testServices.jsonRestStore});
 
@@ -18,7 +18,7 @@ doh.register("dojox.data.tests.stores.ServiceStore",
 			name: "Fetch some items",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on ServiceStore of a simple query.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"query",
@@ -35,7 +35,7 @@ doh.register("dojox.data.tests.stores.ServiceStore",
 			name: "fetchItemByIdentity, getValue, getValues, hasAttribute,containsValue, getAttributes, getIdentity",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on ServiceStore of a single item.
 				var d = new doh.Deferred();
 				jsonStore.fetchItemByIdentity({identity:1,
@@ -62,7 +62,7 @@ doh.register("dojox.data.tests.stores.ServiceStore",
 			name: "createLazyItem",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on ServiceStore of a single item.
 				var d = new doh.Deferred();
 				var lazyItem = {
@@ -105,7 +105,7 @@ doh.register("dojox.data.tests.stores.ServiceStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Json can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		fetching with paging
 
 				var d = new doh.Deferred();
@@ -133,9 +133,9 @@ doh.register("dojox.data.tests.stores.ServiceStore",
 			}
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var readApi = new dojo.data.api.Read();
diff --git a/dojox/data/tests/stores/SnapLogicStore.js b/dojox/data/tests/stores/SnapLogicStore.js
index 25dfe29..65c04c2 100644
--- a/dojox/data/tests/stores/SnapLogicStore.js
+++ b/dojox/data/tests/stores/SnapLogicStore.js
@@ -7,10 +7,10 @@ dojox.data.tests.stores.SnapLogicStore.pipelineSize = 14;
 dojox.data.tests.stores.SnapLogicStore.attributes = ["empno", "ename", "job", "hiredate", "sal", "comm", "deptno"];
 
 dojox.data.tests.stores.SnapLogicStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
-}
+};
 
 doh.register("dojox.data.tests.stores.SnapLogicStore",
 	[
@@ -18,9 +18,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  Fetch One",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch from a SnapLogic pipeline
-				//	description:
+				// description:
 				//		Simple test of a basic fetch from a SnapLogic pipeline
 
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
@@ -41,9 +41,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  Fetch_10_Streaming",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on SnapLogic pipeline.
-				//	description:
+				// description:
 				//		Simple test of a basic fetch on SnapLogic pipeline.
 
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
@@ -78,9 +78,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  Fetch Zero",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Try fetching 0 records. A count of the items in the pipeline should be returned.
-				//	description:
+				// description:
 				//		Try fetching 0 records. A count of the items in the pipeline should be returned.
 
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
@@ -101,9 +101,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  Fetch_Paging",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
-				//	description:
+				// description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
@@ -163,9 +163,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  getLabel",
 			timeout:	3000, //3 seconds
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Test that the label function returns undefined since it's not supported.
-				//	description:
+				// description:
 				//		Test that the label function returns undefined since it's not supported.
 
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
@@ -188,9 +188,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  getLabelAttributes",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getLabelAttributes returns null since it's not supported.
-				//	description:
+				// description:
 				//		Simple test of the getLabelAttributes returns null since it's not supported.
 
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
@@ -213,9 +213,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  getValue",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
 
@@ -242,9 +242,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  getValues",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getValue function of the store.
-				//	description:
+				// description:
 				//		Simple test of the getValue function of the store.
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
 
@@ -269,9 +269,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  isItem",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the isItem function of the store
-				//	description:
+				// description:
 				//		Simple test of the isItem function of the store
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
 
@@ -295,9 +295,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  hasAttribute",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the hasAttribute function of the store
-				//	description:
+				// description:
 				//		Simple test of the hasAttribute function of the store
 
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
@@ -335,9 +335,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  containsValue",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the containsValue function of the store
-				//	description:
+				// description:
 				//		Simple test of the containsValue function of the store
 
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
@@ -362,9 +362,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  getAttributes",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of the getAttributes function of the store
-				//	description:
+				// description:
 				//		Simple test of the getAttributes function of the store
 
 				var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
@@ -389,9 +389,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
@@ -406,9 +406,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			t.assertEqual(count, 1);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
diff --git a/dojox/data/tests/stores/WikipediaStore.js b/dojox/data/tests/stores/WikipediaStore.js
index 4d30af4..4f2fb6e 100644
--- a/dojox/data/tests/stores/WikipediaStore.js
+++ b/dojox/data/tests/stores/WikipediaStore.js
@@ -9,7 +9,7 @@ dojox.data.tests.stores.WikipediaStore.getStore = function(){
 };
 
 dojox.data.tests.stores.WikipediaStore.error = function(t, d, errData){
-	//	summary:
+	// summary:
 	//		Our shared error callback
 	d.errback(errData);
 };
@@ -19,7 +19,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: containsValue",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Verify the containsValue method functions correctly.
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -41,7 +41,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: fetch (one)",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Test a single page fetch from Wikipedia
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -61,7 +61,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: fetch (query 30)",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Test a full text search from Wikipedia
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -82,7 +82,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: fetch (paged)",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Test multiple fetches on a single full text search.
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -113,7 +113,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: getAttributes",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Verify the getAttributes method functions correctly
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -135,7 +135,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: getLabel",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Test that the store correctly sets a label.
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -157,7 +157,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: getLabelAttributes",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Test that the store correctly enumerates the label attributes.
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -181,7 +181,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: getValue",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Verify that getValue does what it should.
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -206,7 +206,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: getValues",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Verify that getValues does what it should
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -231,7 +231,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: hasAttribute",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Verify the hasAttribute method
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -258,7 +258,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: isItem",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Verify the isItem method
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -282,7 +282,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: isItemLoaded",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Verify the isItemLoaded method
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -310,7 +310,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "IdentityAPI: getIdentity",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Verify the getIdentity method returns the correct value
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -332,7 +332,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "ReadAPI: loadItem",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Verify the loadItem method
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -362,7 +362,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "IdentityAPI: getIdentityAttributes",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Verify the getIdentityAttributes method functions correctly
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -384,7 +384,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 		name: "IdentityAPI: fetchItemByIdentity",
 		timeout: 30000,
 		runTest: function(t) {
-			//	summary:
+			// summary:
 			//		Verify the fetchItemByIdentity method works
 			var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 			var d = new doh.Deferred();
@@ -412,7 +412,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 	
 
 	function testIdentityAPI_getFeatures(t){
-		//	summary:
+		// summary:
 		//		Test that the store correctly advertises its capabilities
 		var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 
@@ -426,7 +426,7 @@ doh.register("dojox.data.tests.stores.WikipediaStore",[
 	},
 
 	function testIdentityAPI_functionConformance(t){
-		//	summary:
+		// summary:
 		//		Tests for Identity API conformance by checking to see that all declared functions are actual functions on the instances.
 		var ws = dojox.data.tests.stores.WikipediaStore.getStore();
 		var identityApi = new dojo.data.api.Identity();
diff --git a/dojox/data/tests/stores/XmlStore.js b/dojox/data/tests/stores/XmlStore.js
index 79a589d..c56ed2d 100644
--- a/dojox/data/tests/stores/XmlStore.js
+++ b/dojox/data/tests/stores/XmlStore.js
@@ -32,9 +32,9 @@ dojox.data.tests.stores.XmlStore.getGeographyStore = function(){
 doh.register("dojox.data.tests.stores.XmlStore",
 	[
 		function testReadAPI_fetch_all(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching all xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching all xml items through an XML element called isbn
 			var store = dojox.data.tests.stores.XmlStore.getBooksStore();
 
@@ -50,9 +50,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -71,9 +71,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			name: "testReadAPI_fetch_paging",
 			timeout: 10000,
 			runTest: function(t){
-				//	summary:
+				// summary:
 				//		Simple test of fetching one xml items through an XML element called isbn
-				//	description:
+				// description:
 				//		Simple test of fetching one xml items through an XML element called isbn
 				var store = dojox.data.tests.stores.XmlStore.getBooksStore();
 				var d = new doh.Deferred();
@@ -141,9 +141,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			}
 		},
 		function testReadAPI_fetch_pattern0(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -159,9 +159,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 		
 		function testReadAPI_fetch_pattern1(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -176,10 +176,10 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern1_preventCacheOff(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//		with preventCache off to test that it doesn't pass it when told not to.
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//		with preventCache off to test that it doesn't pass it when told not to.
 			var store = dojox.data.tests.stores.XmlStore.getBooks2StorePC();
@@ -195,9 +195,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern2(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -212,9 +212,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_multi(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items with a pattern of multiple attrs.
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items with a pattern of multiple attrs.
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -229,9 +229,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_multiValuedValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items with a pattern of multiple attrs.
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items with a pattern of multiple attrs.
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -246,9 +246,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseInsensitive(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -263,9 +263,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseSensitive(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -280,9 +280,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_regexp(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 			var d = new doh.Deferred();
@@ -297,9 +297,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_rootItem(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching all xml items through an XML element called isbn
-			//	description:
+			// description:
 			//		Simple test of fetching all xml items through an XML element called isbn
 			var store = new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books3.xml").toString(),
 				rootItem:"book"});
@@ -348,9 +348,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withAttrMap_pattern0(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books_isbnAttr2.xml").toString(),
 				attributeMap: {"book.isbn": "@isbn"}});
@@ -366,9 +366,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withAttrMap_pattern1(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books_isbnAttr2.xml").toString(),
 				attributeMap: {"book.isbn": "@isbn"}});
@@ -384,9 +384,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withAttrMap_pattern2(t){
-			//	summary:
+			// summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
-			//	description:
+			// description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = new dojox.data.XmlStore({url: require.toUrl("dojox/data/tests/stores/books_isbnAttr2.xml").toString(),
 				attributeMap: {"book.isbn": "@isbn"}});
@@ -403,9 +403,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testReadAPI_getLabel(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
@@ -425,9 +425,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
-			//	description:
+			// description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
@@ -448,9 +448,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testReadAPI_getValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getValue API
-			//	description:
+			// description:
 			//		Simple test of the getValue API
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -469,10 +469,10 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getValue_cdata(t) {
-			//	summary:
+			// summary:
+			//		Simple test of the getValue text() special attribute.
+			// description:
 			//		Simple test of the getValue text() special attribute.
-			//	description:
-			//      Simple test of the getValue text() special attribute.
 			var store = dojox.data.tests.stores.XmlStore.getCDataTestStore();
 
 			var d = new doh.Deferred();
@@ -499,10 +499,10 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testReadAPI_getValues_cdata(t) {
-			//	summary:
+			// summary:
+			//		Simple test of the getValues text() special attribute.
+			// description:
 			//		Simple test of the getValues text() special attribute.
-			//	description:
-			//      Simple test of the getValues text() special attribute.
 			var store = dojox.data.tests.stores.XmlStore.getCDataTestStore();
 
 			var d = new doh.Deferred();
@@ -528,10 +528,10 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getValue_cdata_toString(t) {
-			//	summary:
+			// summary:
+			//		Simple test of the getValue and toString of the resulting 'XmlItem' API
+			// description:
 			//		Simple test of the getValue and toString of the resulting 'XmlItem' API
-			//	description:
-			//      Simple test of the getValue and toString of the resulting 'XmlItem' API
 			var store = dojox.data.tests.stores.XmlStore.getCDataTestStore();
 
 			var d = new doh.Deferred();
@@ -558,9 +558,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testReadAPI_getValues(t){
-			 //	summary:
+			 // summary:
 			 //		Simple test of the getValues API
-			 //	description:
+			 // description:
 			 //		Simple test of the getValues API
 			 var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -581,9 +581,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem(t){
-			 //	summary:
+			 // summary:
 			 //		Simple test of the isItem API
-			 //	description:
+			 // description:
 			 //		Simple test of the isItem API
 			 var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -604,9 +604,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem_multistore(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItem API across multiple store instances.
-			//	description:
+			// description:
 			//		Simple test of the isItem API across multiple store instances.
 			var store1 = dojox.data.tests.stores.XmlStore.getBooks2Store();
 			var store2 = dojox.data.tests.stores.XmlStore.getBooks2Store();
@@ -635,9 +635,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary:
+			// summary:
 			//		Simple test of the hasAttribute API
-			//	description:
+			// description:
 			//		Simple test of the hasAttribute API
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -659,9 +659,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_containsValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the containsValue API
-			//	description:
+			// description:
 			//		Simple test of the containsValue API
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -680,9 +680,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescending(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in descending order.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in descending order.
 			var store = dojox.data.tests.stores.XmlStore.getBooksStore();
 
@@ -709,9 +709,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscending(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in ascending order.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in ascending order.
 			var store = dojox.data.tests.stores.XmlStore.getBooksStore();
 
@@ -737,9 +737,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescendingNumeric(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
 			var store = dojox.data.tests.stores.XmlStore.getBooksStore();
 
@@ -774,9 +774,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscendingNumeric(t){
-			//	summary:
+			// summary:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
-			//	description:
+			// description:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
 			var store = dojox.data.tests.stores.XmlStore.getBooksStore();
 
@@ -811,9 +811,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_isItemLoaded(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isItemLoaded API
-			//	description:
+			// description:
 			//		Simple test of the isItemLoaded API
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -831,9 +831,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getFeatures function of the store
-			//	description:
+			// description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
@@ -847,9 +847,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			t.assertEqual(3, count);
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary:
+			// summary:
 			//		Simple test of the getAttributes API
-			//	description:
+			// description:
 			//		Simple test of the getAttributes API
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -880,9 +880,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testWriteAPI_setValue(t){
-			//	summary:
+			// summary:
 			//		Simple test of the setValue API
-			//	description:
+			// description:
 			//		Simple test of the setValue API
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -902,9 +902,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testWriteAPI_setValues(t){
-			//	summary:
+			// summary:
 			//		Simple test of the setValues API
-			//	description:
+			// description:
 			//		Simple test of the setValues API
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -928,9 +928,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testWriteAPI_unsetAttribute(t){
-			//	summary:
+			// summary:
 			//		Simple test of the unsetAttribute API
-			//	description:
+			// description:
 			//		Simple test of the unsetAttribute API
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -951,9 +951,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testWriteAPI_isDirty(t){
-			//	summary:
+			// summary:
 			//		Simple test of the isDirty API
-			//	description:
+			// description:
 			//		Simple test of the isDirty API
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -974,9 +974,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testWriteAPI_revert(t){
-			//	summary:
+			// summary:
 			//		Simple test of the write revert API
-			//	description:
+			// description:
 			//		Simple test of the write revert API
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -1008,9 +1008,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_getIdentity(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API
 			 var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -1034,9 +1034,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_getIdentityAttributes(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentityAttributes API where it defaults to internal xpath (no keyAttribute)
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentityAttributes API where it defaults to internal xpath (no keyAttribute)
 			 var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -1060,9 +1060,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_getIdentityAttributes_usingKeyAttributeIdentity(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentityAttributes API where identity is specified by the keyAttribute param
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentityAttributes API where identity is specified by the keyAttribute param
 			 var store = dojox.data.tests.stores.XmlStore.getBooks3Store();
 
@@ -1087,9 +1087,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
 			 var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -1112,9 +1112,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity2(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
 			 var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -1137,9 +1137,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity3(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
 			 var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -1162,9 +1162,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_usingKeyAttributeIdentity(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
 			 var store = dojox.data.tests.stores.XmlStore.getBooks3Store();
 
@@ -1186,9 +1186,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_usingKeyAttributeIdentity2(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
 			 var store = dojox.data.tests.stores.XmlStore.getBooks3Store();
 
@@ -1210,9 +1210,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_usingKeyAttributeIdentity3(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
 			 var store = dojox.data.tests.stores.XmlStore.getBooks3Store();
 
@@ -1234,9 +1234,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_usingKeyAttributeIdentity4(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
 			 var store = dojox.data.tests.stores.XmlStore.getGeographyStore();
 
@@ -1259,9 +1259,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 
 
 		function testIdentityAPI_fetchItemByIdentity_fails(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API
 			 var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -1279,9 +1279,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_fails2(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API
 			 var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -1299,9 +1299,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_fails3(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API
 			 var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
 
@@ -1319,9 +1319,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_usingKeyAttributeIdentity_fails(t) {
-			 //	summary:
+			 // summary:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
-			 //	description:
+			 // description:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
 			 var store = dojox.data.tests.stores.XmlStore.getBooks3Store();
 
@@ -1342,9 +1342,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.XmlStore.getBooksStore();
@@ -1366,9 +1366,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			t.assertTrue(passed);
 		},
 		function testWriteAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.XmlStore.getBooksStore();
@@ -1389,9 +1389,9 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var testStore = dojox.data.tests.stores.XmlStore.getBooksStore();
diff --git a/dojox/data/tests/stores/filestore_funcs.php b/dojox/data/tests/stores/filestore_funcs.php
index 5d4408b..d21030b 100755
--- a/dojox/data/tests/stores/filestore_funcs.php
+++ b/dojox/data/tests/stores/filestore_funcs.php
@@ -65,7 +65,7 @@
 	 * @param $showHiddenFiles boolean to indicate to return hidden files as part of the list.
 	 */
 	function getAllfiles($dir, $rootDir, $recurse, $dirsOnly, $expand, $showHiddenFiles) { 
-		//  summary:
+		// summary:
 		//      A function to obtain all the files in a particular directory (file or dir)
 		$files = array();
 		$dirHandle = opendir($rootDir."/".$dir);
@@ -118,7 +118,7 @@
 	 *  $file["children"] - Children files of a directory.  Empty if a standard file.
 	 */
 	function generateFileObj($file, $dir, $rootDir, $expand, $showHiddenFiles) {
-		//  summary:
+		// summary:
 		//      Function to generate an object representation of a disk file.
 		$path = $file;
 		if ($dir != "." && $dir != "./") {
diff --git a/dojox/data/tests/stores/test_Tree_on_JsonRestStore.html b/dojox/data/tests/stores/test_Tree_on_JsonRestStore.html
index f7ce121..10b7e86 100644
--- a/dojox/data/tests/stores/test_Tree_on_JsonRestStore.html
+++ b/dojox/data/tests/stores/test_Tree_on_JsonRestStore.html
@@ -1,10 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE HTML>
 <html>
 <head>
 	<title>Dijit Tree Test</title>
 
-	<style someProperty="text/css">
+	<style>
 		@import "../../../../dojo/resources/dojo.css";
 		@import "../../../../dijit/tests/css/dijitTests.css";
 	</style>
@@ -13,13 +12,13 @@
 	<link rel="stylesheet" id="themeStyles" href="../../../../dijit/themes/tundra/tundra.css">
 
 	<!-- required: dojo.js -->
-	<script someProperty="text/javascript" src="../../../../dojo/dojo.js"
+	<script src="../../../../dojo/dojo.js"
 		djConfig="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- do not use: only for testing alternate themes -->
-	<script someProperty="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<script src="../../../../dijit/tests/_testCommon.js"></script>
 
-	<script language="JavaScript" someProperty="text/javascript">
+	<script>
 		dojo.require("dojox.data.JsonRestStore");
 		dojo.require("dijit.Tree");
 		dojo.require("dijit.Menu");
diff --git a/dojox/data/util/JsonQuery.js b/dojox/data/util/JsonQuery.js
index 96a0f4c..8b94d0f 100644
--- a/dojox/data/util/JsonQuery.js
+++ b/dojox/data/util/JsonQuery.js
@@ -1,8 +1,8 @@
-define("dojox/data/util/JsonQuery", ["dojo", "dojox"], function(dojo, dojox) {
+define(["dojo", "dojox"], function(dojo, dojox) {
 
 // this is a mixin to convert object attribute queries to
 // JSONQuery/JSONPath syntax to be sent to the server.
-dojo.declare("dojox.data.util.JsonQuery", null, {
+return dojo.declare("dojox.data.util.JsonQuery", null, {
 	useFullIdInQueries: false,
 	_toJsonQuery: function(args, jsonQueryPagination){
 		var first = true;
@@ -94,5 +94,4 @@ dojo.declare("dojox.data.util.JsonQuery", null, {
 	
 });
 
-return dojox.data.util.JsonQuery;
 });
diff --git a/dojox/date/buddhist.js b/dojox/date/buddhist.js
index 4140c73..f65a7c1 100644
--- a/dojox/date/buddhist.js
+++ b/dojox/date/buddhist.js
@@ -1,39 +1,39 @@
-define(["dojo/_base/kernel", "dojo/date", "./buddhist/Date"], function(dojo, dd, buddhistDate){
-	dojo.getObject("date.buddhist", true, dojox);
-	dojo.experimental("dojox.date.buddhist");
+define(["..", "dojo/_base/lang", "dojo/date", "./buddhist/Date"], function(dojox, lang, dd, BDate){
+	var dbuddhist = lang.getObject("date.buddhist", true, dojox);
 
 // Utility methods to do arithmetic calculations with buddhist.Dates
 
-dojox.date.buddhist.getDaysInMonth = function(/*buddhist.Date*/dateObject){
+dbuddhist.getDaysInMonth = function(/*dojox/date/buddhist/Date*/dateObject){
 	return dd.getDaysInMonth(dateObject.toGregorian());
 };
 
-dojox.date.buddhist.isLeapYear = function(/*buddhist.Date*/dateObject){
+dbuddhist.isLeapYear = function(/*dojox/date/buddhist/Date*/dateObject){
 	return dd.isLeapYear(dateObject.toGregorian());
 };
 
 //FIXME: reduce compare, add, diff also
-dojox.date.buddhist.compare = function(/*buddhist.Date*/date1, /*buddhist.Date*/date2, /*String?*/portion){
-	//	summary:
+dbuddhist.compare = function(/*dojox/date/buddhist/Date*/date1, /*dojox/date/buddhist/Date*/date2, /*String?*/portion){
+	// summary:
 	//		Compare two buddhist date objects by date, time, or both.
 	return dd.compare(date1,date2, portion); // int
 };
 
 
-dojox.date.buddhist.add = function(/*dojox.date.buddhist.Date*/date, /*String*/interval, /*int*/amount){
-	//	based on and similar to dojo.date.add
-	//	summary:
+dbuddhist.add = function(/*dojox/date/buddhist/Date*/date, /*String*/interval, /*int*/amount){
+	// summary:
 	//		Add to a Date in intervals of different size, from milliseconds to years
-	//	date: buddhist.Date
+	// date: dojox/date/buddhist/Date
 	//		Date object to start with
-	//	interval:
+	// interval:
 	//		A string representing the interval.  One of the following:
-	//			"year", "month", "day", "hour", "minute", "second",
-	//			"millisecond", "week", "weekday"
-	//	amount:
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond", "week", "weekday"
+	// amount:
 	//		How much to add to the date.
 
-	var newBuddDate = new buddhistDate(date);
+	//	based on and similar to dojo.date.add
+
+	var newBuddDate = new BDate(date);
 
 	switch(interval){
 		case "day":
@@ -98,25 +98,29 @@ dojox.date.buddhist.add = function(/*dojox.date.buddhist.Date*/date, /*String*/i
 	return newBuddDate; // dojox.date.buddhist.Date
 };
 
-dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*dojox.date.buddhist.Date?*/date2, /*String?*/interval){
-	//	based on and similar to dojo.date.difference
-	//	summary:
-	//        date2 - date1
-	//	 date2 is hebrew.Date object.  If not specified, the current hebrew.Date is used.
-	//	interval:
+dbuddhist.difference = function(/*dojox/date/buddhist/Date*/date1, /*dojox/date/buddhist/Date?*/date2, /*String?*/interval){
+	// summary:
+	//		date2 - date1
+	// date1: dojox/date/dbuddhist/Date
+	// date2: dojox/date/dbuddhist/Date
+	//		If not specified, the current dojox.date.dbuddhist.Date is used.
+	// interval:
 	//		A string representing the interval.  One of the following:
-	//			"year", "month", "day", "hour", "minute", "second",
-	//			"millisecond",  "week", "weekday"
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond",  "week", "weekday"
+	//
 	//		Defaults to "day".
-	
-	date2 = date2 || new buddhistDate();
+
+	//	based on and similar to dojo.date.difference
+
+	date2 = date2 || new BDate();
 	interval = interval || "day";
 	var yearDiff = date2.getFullYear() - date1.getFullYear();
 	var delta = 1; // Integer return value
 	switch(interval){
 		case "weekday":
-			var days = Math.round(dojox.date.buddhist.difference(date1, date2, "day"));
-			var weeks = parseInt(dojox.date.buddhist.difference(date1, date2, "week"));
+			var days = Math.round(dbuddhist.difference(date1, date2, "day"));
+			var weeks = parseInt(dbuddhist.difference(date1, date2, "week"));
 			var mod = days % 7;
 	
 			// Even number of weeks
@@ -132,7 +136,7 @@ dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*d
 				mod = days % 7;
 				// Mark the date advanced by the number of
 				// round weeks (may be zero)
-				var dtMark = new buddhistDate(date2);
+				var dtMark = new BDate(date2);
 				dtMark.setDate(dtMark.getDate(true)+(weeks*7));
 				var dayMark = dtMark.getDay();
 	
@@ -215,7 +219,7 @@ dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*d
 		case "week":
 			// Truncate instead of rounding
 			// Don't use Math.floor -- value may be negative
-			delta = parseInt(dojox.date.buddhist.difference(date1, date2, "day")/7);
+			delta = parseInt(dbuddhist.difference(date1, date2, "day")/7);
 			break;
 		case "day":
 			delta /= 24;
@@ -236,5 +240,5 @@ dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*d
 	// Round for fractional values and DST leaps
 	return Math.round(delta); // Number (integer)
 };
-return dojox.date.buddhist;
+return dbuddhist;
 });
\ No newline at end of file
diff --git a/dojox/date/buddhist/Date.js b/dojox/date/buddhist/Date.js
index 04308b5..5ec968b 100644
--- a/dojox/date/buddhist/Date.js
+++ b/dojox/date/buddhist/Date.js
@@ -1,13 +1,10 @@
 define([
-	"dojo/_base/kernel",
+	"dojo/_base/lang",
 	"dojo/_base/declare",
 	"dojo/date"
-], function(dojo, declare, dd){
+], function(lang, declare, dd){
 
-dojo.getObject("date.buddhist.Date", true, dojox);
-dojo.experimental("dojox.date.buddhist.Date");
-
-dojo.declare("dojox.date.buddhist.Date", null, {
+var BDate = declare("dojox.date.buddhist.Date", null, {
 
 	_date: 0,
 	_month: 0,
@@ -19,16 +16,15 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 	_day: 0,
 
  	constructor: function(){
-		// summary: This is the constructor
+		// summary:
+		//		This is the constructor
 		// description:
-		//	This fucntion initialize the date object values
-		//
+		//		This function initialize the date object values
 		// example:
-		// |		var date1 = new dojox.date.buddhist.Date();
-		// |
-		// |		var date2 = new dojox.date.buddhist.Date(date1);
-		// |
-		// |		var date3 = new dojox.date.buddhist.Date(2552,2,12);
+		//	|	var date1 = new dojox.date.buddhist.Date();
+		//	|	var date2 = new dojox.date.buddhist.Date(date1);
+		//	|	var date3 = new dojox.date.buddhist.Date(2552,2,12);
+
 		var len = arguments.length;
 		if(!len){// use the current date value, added "" to the similarity to date
 			this.fromGregorian(new Date());
@@ -68,61 +64,63 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 	},
 	
 	getDate: function(/*boolean?*/isNumber){
-		// summary: This function returns the date value (0 - 30)
-		//
+		// summary:
+		//		This function returns the date value (0 - 30)
 		// example:
-		// |		var date1 = new dojox.date.buddhist.Date();
-		// |
-		// |		console.log(date1.getDate());
+		//	|	var date1 = new dojox.date.buddhist.Date();
+		//	|	console.log(date1.getDate());
 		return parseInt(this._date);
 	},
 
 	getMonth: function(){
-		// summary: This function return the month value ( 0 - 11 )
-		//
+		// summary:
+		//		This function return the month value ( 0 - 11 )
 		// example:
-		// |		var date1 = new dojox.date.buddhist.Date();
-		// |
-		// |		console.log(date1.getMonth()+1);
+		//	|	var date1 = new dojox.date.buddhist.Date();
+		//	|	console.log(date1.getMonth()+1);
 		return parseInt(this._month);
 	},
 
 
 	getFullYear: function(){
-		// summary: This function return the Year value
-		//
+		// summary:
+		//		This function return the Year value
 		// example:
-		// |		var date1 = new dojox.date.buddhist.Date();
-		// |
-		// |		console.log(date1.getFullYear());
+		//	|	var date1 = new dojox.date.buddhist.Date();
+		//	|	console.log(date1.getFullYear());
 		return parseInt(this._year);
 	},
 			
 	getHours: function(){
-		//summary: returns the Hour value
+		// summary:
+		//		returns the Hour value
 		return this._hours;
 	},
 		
 	getMinutes: function(){
-		//summary: returns the Minuites value
+		// summary:
+		//		returns the Minutes value
 		return this._minutes;
 	},
 
 	getSeconds: function(){
-		//summary: returns the seconde value
+		// summary:
+		//		returns the Seconds value
 		return this._seconds;
 	},
 
 	getMilliseconds: function(){
-		//summary: returns the Milliseconds value
+		// summary:
+		//		returns the Milliseconds value
 		return this._milliseconds;
 	},
 
 	setDate: function(/*number*/date){
-		// summary: This function sets the Date
+		// summary:
+		//		This function sets the Date
 		// example:
-		// |		var date1 = new dojox.date.buddhist.Date();
-		// |		date1.setDate(2);
+		//	|	var date1 = new dojox.date.buddhist.Date();
+		//	|	date1.setDate(2);
 		date = parseInt(date);
 
 		if(date > 0 && date <= this._getDaysInMonth(this._month, this._year)){
@@ -154,28 +152,29 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 	},
 	
 	setFullYear: function(/*number*/year, /*number?*/month, /*number?*/ date){
-		// summary: This function set Year
-		//
+		// summary:
+		//		This function set Year
 		// example:
-		// |		var date1 = new dojox.date.buddhist.Date();
-		// |		date1.setFullYear(2552);
-		// |		date1.setFullYear(2552, 1, 1);
+		//	|	var date1 = new dojox.date.buddhist.Date();
+		//	|	date1.setFullYear(2552);
+		//	|	date1.setFullYear(2552, 1, 1);
 		this._year = parseInt(year);
 	},
 			
 	setMonth: function(/*number*/month){
-		// summary: This function set Month
-		//
+		// summary:
+		//		This function set Month
 		// example:
-		// |		var date1 = new dojox.date.buddhist.Date();
-		// |		date1.setMonth(0); //first month
+		//	|	var date1 = new dojox.date.buddhist.Date();
+		//	|	date1.setMonth(0); //first month
 		this._year += Math.floor(month / 12);
 		this._month = Math.floor(month % 12);
 		for(; this._month < 0; this._month = this._month+12);
 	},
 			
 	setHours: function(){
-		//summary: set the Hours  0-23
+		// summary:
+		//		set the Hours  0-23
 		var hours_arg_no = arguments.length;
 		var hours = 0;
 		if(hours_arg_no >= 1){
@@ -229,13 +228,15 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 	},
 
 	setMinutes: function(/*Number*/minutes){
-		//summary: sets the minutes (0-59) only.
+		// summary:
+		//		sets the minutes (0-59) only.
 		this._minutes = minutes % 60;
 		return this;
 	},
 
 	setSeconds: function(/*Number*/seconds){
-		//summary: sets the seconds (0-59) only.
+		// summary:
+		//		sets the seconds (0-59) only.
 		this._seconds = seconds % 60;
 		return this;
 	},
@@ -246,8 +247,10 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 	},
 
 	toString: function(){
-		// summary: This returns a string representation of the date in "dd, MM, YYYY HH:MM:SS" format
-		return this._date + ", " + this._month + ", " + this._year + "  " + this._hours + ":" + this._minutes + ":" + this._seconds; // String
+		// summary:
+		//		This returns a string representation of the date in "dd, MM, YYYY HH:MM:SS" format
+		return isNaN(this._date)?"Invalid Date":
+			this._date + ", " + this._month + ", " + this._year + "  " + this._hours + ":" + this._minutes + ":" + this._seconds; // String
 	},
 
 //FIXME: remove this and replace usage with dojox.date.buddhist.getDaysInMonth?
@@ -256,7 +259,8 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 	},
 
 	fromGregorian: function(/*Date*/gdate){
-		// summary: This function sets this Date to the Hebrew Date corresponding to the Gregorian Date
+		// summary:
+		//		This function sets this Date to the Hebrew Date corresponding to the Gregorian Date
 		var date = new Date(gdate);
 		this._date = date.getDate();
 		this._month = date.getMonth();
@@ -270,19 +274,21 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 	},
 
 	toGregorian: function(){
-		// summary: This returns the equivalent Gregorian date value as a Date object
+		// summary:
+		//		This returns the equivalent Gregorian date value as a Date object
 		return new Date(this._year-543, this._month, this._date, this._hours, this._minutes, this._seconds, this._milliseconds); // Date
 	},
 	
 	getDay: function(){
-		// summary: This function return Week Day value ( 0 - 6 )
+		// summary:
+		//		This function return Week Day value ( 0 - 6 )
 		return this.toGregorian().getDay(); // int
 	}
 });
 
-dojox.date.buddhist.Date.prototype.valueOf = function(){
+BDate.prototype.valueOf = function(){
 	return this.toGregorian().valueOf();
 };
 
-return dojox.date.buddhist.Date;
+return BDate;
 });
diff --git a/dojox/date/buddhist/locale.js b/dojox/date/buddhist/locale.js
index 91b32d7..ae62740 100644
--- a/dojox/date/buddhist/locale.js
+++ b/dojox/date/buddhist/locale.js
@@ -1,8 +1,7 @@
-define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./Date", "dojo/i18n!dojo/cldr/nls/buddhist"],
-	function(dojo, dd, i18n, regexp, string, buddhistDate){
+define(["../..", "dojo/_base/lang", "dojo/_base/array", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./Date", "dojo/i18n!dojo/cldr/nls/buddhist"],
+	function(dojox, lang, arr, dd, i18n, regexp, string, BDate){
 
-	dojo.getObject("date.buddhist.locale", true, dojox);
-	dojo.experimental("dojox.date.buddhist.locale");
+	var blocale = lang.getObject("date.buddhist.locale", true, dojox);
 
 	// Format a pattern without literals
 	function formatPattern(dateObject, bundle, locale, fullYear,  pattern){
@@ -77,7 +76,7 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 					break;
 				case 'z':
 					// We only have one timezone to offer; the one from the browser
-					s = dojo.date.getTimezoneName(dateObject.toGregorian());
+					s = dd.getTimezoneName(dateObject.toGregorian());
 					if(s){ break; }
 					l = 4;
 					// fallthrough... use GMT if tz not available
@@ -102,18 +101,20 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		});
 	}
 	
-	dojox.date.buddhist.locale.format = function(/*buddhist.Date*/dateObject, /*object?*/options){
-		// based on and similar to dojo.date.locale.format
+	blocale.format = function(/*dojox/date/buddhist/Date*/dateObject, /*object?*/options){
 		// summary:
 		//		Format a Date object as a String, using  settings.
+
+		// based on and similar to dojo.date.locale.format
+
 		options = options || {};
 
 		var locale = i18n.normalizeLocale(options.locale);
 		var formatLength = options.formatLength || 'short';
-		var bundle = dojox.date.buddhist.locale._getBuddhistBundle(locale);
+		var bundle = blocale._getBuddhistBundle(locale);
 		var str = [];
 
-		var sauce = dojo.hitch(this, formatPattern, dateObject, bundle, locale, options.fullYear);
+		var sauce = lang.hitch(this, formatPattern, dateObject, bundle, locale, options.fullYear);
 		if(options.selector == "year"){
 			var year = dateObject.getFullYear();
 			return year;
@@ -131,19 +132,21 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		return result; // String
 	};
 
-	dojox.date.buddhist.locale.regexp = function(/*Object?*/options){
-		//	based on and similar to dojo.date.locale.regexp
+	blocale.regexp = function(/*Object?*/options){
 		// summary:
 		//		Builds the regular needed to parse a buddhist.Date
-		return dojox.date.buddhist.locale._parseInfo(options).regexp; // String
+
+		//	based on and similar to dojo.date.locale.regexp
+
+		return blocale._parseInfo(options).regexp; // String
 	};
 
-	dojox.date.buddhist.locale._parseInfo = function(/*Object?*/options){
+	blocale._parseInfo = function(/*Object?*/options){
 	/* based on and similar to dojo.date.locale._parseInfo */
 
 		options = options || {};
 		var locale = i18n.normalizeLocale(options.locale);
-		var bundle = dojox.date.buddhist.locale._getBuddhistBundle(locale);
+		var bundle = blocale._getBuddhistBundle(locale);
 		var formatLength = options.formatLength || 'short';
 		var datePattern = options.datePattern || bundle["dateFormat-" + formatLength];
 		var timePattern = options.timePattern || bundle["timeFormat-" + formatLength];
@@ -159,17 +162,20 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 
 		var tokens = [];
 	
-		var re = _processPattern(pattern, dojo.hitch(this, _buildDateTimeRE, tokens, bundle, options));
+		var re = _processPattern(pattern, lang.hitch(this, _buildDateTimeRE, tokens, bundle, options));
 		return {regexp: re, tokens: tokens, bundle: bundle};
 	};
 
-	dojox.date.buddhist.locale.parse = function(/*String*/value, /*Object?*/options){
+	blocale.parse = function(/*String*/value, /*Object?*/options){
+		// summary:
+		//		This function parses string date value according to options
+
 		// based on and similar to dojo.date.locale.parse
-		// summary: This function parses string date value according to options
+
 		value =  value.replace(/[\u200E\u200F\u202A-\u202E]/g, ""); //remove special chars
 	
 		if(!options){options={};}
-		var info = dojox.date.buddhist.locale._parseInfo(options);
+		var info = blocale._parseInfo(options);
 	
 		var tokens = info.tokens, bundle = info.bundle;
 		var re = new RegExp("^" + info.regexp + "$");
@@ -178,10 +184,7 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 
 		var locale = i18n.normalizeLocale(options.locale);
 
-		if(!match){
-			console.debug("dojox.date.buddhist.locale.parse: value  "+value+" doesn't match pattern   " + re);
-			return null;
-		} // null
+		if(!match){ return null; } // null
 	
 		var date, date1;
 	
@@ -189,7 +192,7 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		var amPm = "";
 		var mLength = 0;
 		var widthList = ["abbr", "wide", "narrow"];
-		var valid = dojo.every(match, function(v, i){
+		var valid = arr.every(match, function(v, i){
 			if(!i){return true;}
 			var token=tokens[i-1];
 			var l=token.length;
@@ -204,9 +207,9 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 							//Tolerate abbreviating period in month part
 							//Case-insensitive comparison
 							v = v.replace(".","").toLowerCase();
-							months = dojo.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
+							months = arr.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
 						}
-						v = dojo.indexOf(months, v);
+						v = arr.indexOf(months, v);
 						if(v == -1){
 							return false;
 						}
@@ -266,13 +269,14 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		}else if(amPm === 'a' && hours == 12){
 			result[3] = 0; //12am -> 0
 		}
-		var dateObject = new buddhistDate(result[0], result[1], result[2], result[3], result[4], result[5], result[6]);
+		var dateObject = new BDate(result[0], result[1], result[2], result[3], result[4], result[5], result[6]);
 		return dateObject;
 	};
 
 
 	function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
-		// summary: Process a pattern with literals in it
+		// summary:
+		//		Process a pattern with literals in it
 
 		// Break up on single quotes, treat every other one as a literal, except '' which becomes '
 		var identity = function(x){return x;};
@@ -285,7 +289,7 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		var chunks = pattern.match(/(''|[^'])+/g);
 		var literal = pattern.charAt(0) == "'";
 
-		dojo.forEach(chunks, function(chunk, i){
+		arr.forEach(chunks, function(chunk, i){
 			if(!chunk){
 				chunks[i]='';
 			}else{
@@ -368,29 +372,29 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 	}
 
 	var _customFormats = [];
-	dojox.date.buddhist.locale.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){
+	blocale.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){
 		// summary:
 		//		Add a reference to a bundle containing localized custom formats to be
 		//		used by date/time formatting and parsing routines.
 		_customFormats.push({pkg:packageName,name:bundleName});
 	};
 
-	dojox.date.buddhist.locale._getBuddhistBundle = function(/*String*/locale){
+	blocale._getBuddhistBundle = function(/*String*/locale){
 		var buddhist = {};
-		dojo.forEach(_customFormats, function(desc){
+		arr.forEach(_customFormats, function(desc){
 			var bundle = i18n.getLocalization(desc.pkg, desc.name, locale);
-			buddhist = dojo.mixin(buddhist, bundle);
+			buddhist = lang.mixin(buddhist, bundle);
 		}, this);
 		return buddhist; /*Object*/
 	};
 
-	dojox.date.buddhist.locale.addCustomFormats("dojo.cldr","buddhist");
+	blocale.addCustomFormats("dojo.cldr","buddhist");
 
-	dojox.date.buddhist.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*buddhist Date Object?*/date){
+	blocale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*dojox/date/buddhist/Date?*/date){
 		// summary:
 		//		Used to get localized strings from dojo.cldr for day or month names.
 		var label;
-		var lookup = dojox.date.buddhist.locale._getBuddhistBundle(locale);
+		var lookup = blocale._getBuddhistBundle(locale);
 		var props = [item, context, type];
 		if(context == 'standAlone'){
 			var key = props.join('-');
@@ -404,4 +408,5 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		return (label || lookup[props.join('-')]).concat(); /*Array*/
 	};
 
+	return blocale;
 });
diff --git a/dojox/date/hebrew.js b/dojox/date/hebrew.js
index ab4c7b4..a33e8c9 100644
--- a/dojox/date/hebrew.js
+++ b/dojox/date/hebrew.js
@@ -1,35 +1,33 @@
-define(["dojo/_base/kernel", "dojo/date", "./hebrew/Date"], function(dojo, dd, hebrewDate){
+define(["..", "dojo/_base/lang", "dojo/date", "./hebrew/Date"], function(dojox, lang, dd, HDate){
+
+var dhebrew = lang.getObject("date.hebrew", true, dojox);
 
-dojo.getObject("date.hebrew", true, dojox);
-dojo.experimental("dojox.date.hebrew");
-	
 // Utility methods to do arithmetic calculations with hebrew.Dates
 
 // added for compat to date
-dojox.date.hebrew.getDaysInMonth = function(/*hebrew.Date*/month){
+dhebrew.getDaysInMonth = function(/*dojox/date/hebrew/Date*/month){
 	return month.getDaysInHebrewMonth(month.getMonth(), month.getFullYear());
 };
 
 //TODO: define hebrew.isLeapYear?  Or should it be invalid, since it has different meaning?
 
-dojox.date.hebrew.compare = function(/*hebrew.Date*/dateheb1, /*hebrew.Date*/dateheb2, /*String?*/portion){
-	//	summary:
+dhebrew.compare = function(/*dojox/date/hebrew/Date*/dateheb1, /*dojox/date/hebrew/Date*/dateheb2, /*String?*/portion){
+	// summary:
 	//		Compare two hebrew date objects by date, time, or both.
-	//	description:
-	//  	Returns 0 if equal, positive if a > b, else negative.
-	//	date1:
-	//		hebrew.Date object
-	//	date2:
-	//		hebrew.Date object.  If not specified, the current hebrew.Date is used.
-	//	portion:
+	// description:
+	//		Returns 0 if equal, positive if a > b, else negative.
+	// date1: dojox/date/hebrew/Date
+	// date2: dojox/date/hebrew/Date
+	//		If not specified, the current hebrew.Date is used.
+	// portion:
 	//		A string indicating the "date" or "time" portion of a Date object.
 	//		Compares both "date" and "time" by default.  One of the following:
 	//		"date", "time", "datetime"
 
-	if(dateheb1 instanceof hebrewDate){
+	if(dateheb1 instanceof HDate){
 		dateheb1 = dateheb1.toGregorian();
 	}
-	if(dateheb2 instanceof hebrewDate){
+	if(dateheb2 instanceof HDate){
 		dateheb2 = dateheb2.toGregorian();
 	}
 	
@@ -37,20 +35,21 @@ dojox.date.hebrew.compare = function(/*hebrew.Date*/dateheb1, /*hebrew.Date*/dat
 };
 
 
-dojox.date.hebrew.add = function(/*dojox.date.hebrew.Date*/date, /*String*/interval, /*int*/amount){
-	//	based on and similar to dojo.date.add
-	//	summary:
+dhebrew.add = function(/*dojox/date/hebrew/Date*/date, /*String*/interval, /*int*/amount){
+	// summary:
 	//		Add to a Date in intervals of different size, from milliseconds to years
-	//	date: hebrew.Date
+	// date: dojox/date/hebrew/Date
 	//		Date object to start with
-	//	interval:
+	// interval:
 	//		A string representing the interval.  One of the following:
-	//			"year", "month", "day", "hour", "minute", "second",
-	//			"millisecond", "week", "weekday"
-	//	amount:
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond", "week", "weekday"
+	// amount:
 	//		How much to add to the date.
 
-	var newHebrDate = new hebrewDate(date);
+	//	based on and similar to dojo.date.add
+
+	var newHebrDate = new HDate(date);
 
 	switch(interval){
 		case "day":
@@ -106,25 +105,29 @@ dojox.date.hebrew.add = function(/*dojox.date.hebrew.Date*/date, /*String*/inter
 	return newHebrDate; // dojox.date.hebrew.Date
 };
 
-dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox.date.hebrew.Date?*/date2, /*String?*/interval){
-	//	based on and similar to dojo.date.difference
-	//	summary:
-	//        date2 - date1
-	//	 date2 is hebrew.Date object.  If not specified, the current hebrew.Date is used.
-	//	interval:
+dhebrew.difference = function(/*dojox/date/hebrew/Date*/date1, /*dojox/date/hebrew/Date?*/date2, /*String?*/interval){
+	// summary:
+	//		date2 - date1
+	// date1: dojox/date/hebrew/Date
+	// date2: dojox/date/hebrew/Date
+	//		If not specified, the current dojox.date.hebrew.Date is used.
+	// interval:
 	//		A string representing the interval.  One of the following:
-	//			"year", "month", "day", "hour", "minute", "second",
-	//			"millisecond",  "week", "weekday"
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond",  "week", "weekday"
+	//
 	//		Defaults to "day".
 
-	date2 = date2 || new hebrewDate();
+	//	based on and similar to dojo.date.difference
+
+	date2 = date2 || new HDate();
 	interval = interval || "day";
 	var yearDiff = date2.getFullYear() - date1.getFullYear();
 	var delta = 1; // Integer return value
 	switch(interval){
 		case "weekday":
-			var days = Math.round(dojox.date.hebrew.difference(date1, date2, "day"));
-			var weeks = parseInt(dojox.date.hebrew.difference(date1, date2, "week"));
+			var days = Math.round(dhebrew.difference(date1, date2, "day"));
+			var weeks = parseInt(dhebrew.difference(date1, date2, "week"));
 			var mod = days % 7;
 
 			// Even number of weeks
@@ -140,7 +143,7 @@ dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox
 				mod = days % 7;
 				// Mark the date advanced by the number of
 				// round weeks (may be zero)
-				var dtMark = new hebrewDate(date1);
+				var dtMark = new HDate(date1);
 				dtMark.setDate(dtMark.getDate()+(weeks*7));
 				var dayMark = dtMark.getDay();
 	
@@ -224,7 +227,7 @@ dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox
 		case "week":
 			// Truncate instead of rounding
 			// Don't use Math.floor -- value may be negative
-			delta = parseInt(dojox.date.hebrew.difference(date1, date2, "day")/7);
+			delta = parseInt(dhebrew.difference(date1, date2, "day")/7);
 			break;
 		case "day":
 			delta /= 24;
@@ -245,5 +248,5 @@ dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox
 	// Round for fractional values and DST leaps
 	return Math.round(delta); // Number (integer)
 };
-return dojox.date.hebrew;
+return dhebrew;
 });
diff --git a/dojox/date/hebrew/Date.js b/dojox/date/hebrew/Date.js
index de291d2..3dce4d7 100644
--- a/dojox/date/hebrew/Date.js
+++ b/dojox/date/hebrew/Date.js
@@ -1,26 +1,22 @@
 define([
-	"dojo/_base/kernel",
+	"dojo/_base/lang",
 	"dojo/_base/declare",
 	"./numerals"
-], function(dojo, declare, numerals){
+], function(lang, declare, numerals){
 
-dojo.getObject("date.hebrew.Date", true, dojox);
-dojo.experimental("dojox.date.hebrew.Date");
-
-dojo.declare("dojox.date.hebrew.Date", null, {
-	// summary: A Date-like object which implements the Hebrew calendar
-	//
+var HDate = declare("dojox.date.hebrew.Date", null, {
+	// summary:
+	//		A Date-like object which implements the Hebrew calendar
 	// description:
-	//	A Date-like object which implements the Hebrew Calendar.  Because this object
-	//	implements many of the same methods as the native JavaScript Date object, which
-	//	implements the Gregorian calendar, it can often be used its place.  Note that
-	//	this object does not extend Date or use its prototype.
-	//
+	//		A Date-like object which implements the Hebrew Calendar.  Because this object
+	//		implements many of the same methods as the native JavaScript Date object, which
+	//		implements the Gregorian calendar, it can often be used its place.  Note that
+	//		this object does not extend Date or use its prototype.
 	// example:
-	// |	dojo.require("dojox.date.hebrew.Date");
-	// |
-	// |	var date = new dojox.date.hebrew.Date();
-	// |	console.log(date.getFullYear()+'\'+date.getMonth()+'\'+date.getDate());
+	//	|	dojo.require("dojox.date.hebrew.Date");
+	//	|
+	//	|	var date = new dojox.date.hebrew.Date();
+	//	|	console.log(date.getFullYear()+'\'+date.getMonth()+'\'+date.getDate());
 
 	// Hebrew date calculations are performed in terms of days, hours, and
 	// "parts" (or halakim), which are 1/1080 of an hour, or 3 1/3 seconds.
@@ -143,14 +139,12 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	_day: 0,
 
  	constructor: function(){
-		// summary: initialize the date object value
-		//
+		// summary:
+		//		initialize the date object value
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date();
-		// |
-		// |		var date2 = new dojox.date.hebrew.Date(date1);
-		// |
-		// |		var date3 = new dojox.date.hebrew.Date(5768,2,12);
+		//	|	var date1 = new dojox.date.hebrew.Date();
+		//	|	var date2 = new dojox.date.hebrew.Date(date1);
+		//	|	var date3 = new dojox.date.hebrew.Date(5768,2,12);
 
 		var len = arguments.length;
 		if(!len){// use the current date value, added "" to the similarity to date
@@ -165,7 +159,7 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 				this.fromGregorian(arg0);
 			}else if(arg0 == ""){
 				// date should be invalid.  Dijit relies on this behavior.
-				this._date = new Date(""); //TODO: should this be NaN?  _date is not a Date object
+				this._year = this._month = this._date = this._hours = this._minutes = this._seconds = this._milliseconds = NaN;
 			}else{  // this is hebrew.Date object
 				this._year = arg0._year;
 				this._month =  arg0._month;
@@ -195,97 +189,100 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	},
 	
 	getDate: function(){
-		// summary: returns the date value (1 - 30)
-		//
+		// summary:
+		//		returns the date value (1 - 30)
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date();
-		// |
-		// |		console.log(date1.getDate());
+		//	|	var date1 = new dojox.date.hebrew.Date();
+		//	|	console.log(date1.getDate());
 
 		return this._date; // int
 	},
 
 	getDateLocalized: function(/*String?*/locale){
-		// summary: returns the date value as hebrew numerals for the Hebrew locale,
+		// summary:
+		//		returns the date value as hebrew numerals for the Hebrew locale,
 		//		a number for all others.
-		//
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date();
-		// |
-		// |		console.log(date1.getDate());
+		//	|	var date1 = new dojox.date.hebrew.Date();
+		//	|	console.log(date1.getDate());
 
 		return (locale || dojo.locale).match(/^he(?:-.+)?$/) ?
 			numerals.getDayHebrewLetters(this._date) : this.getDate();
 	},
 
 	getMonth: function(){
-		// summary: returns the month value (0 - 12)
+		// summary:
+		//		returns the month value (0 - 12)
+		// description:
+		//		the result is the index in the month array:
 		//
-		// description: the result is the index in the month array:
-		//	0. Tishri
-		//	1. Heshvan
-		//	2. Kislev
-		//	3. Tevet
-		//	4. Shevat
-		//	5. Adar I (leap years only)
-		//	6. Adar
-		//	7. Nisan
-		//	8. Iyar
-		//	9. Sivan
-		//	10. Tammuz
-		//	11.	Av
-		//	12. Elul - 12
-		// For non leap years, for months after Shevat, the actual position of
-		// the month in the year (used for short format) is less than
-		// the "absolute" index by 1.
+		//		0. Tishri
+		//		1. Heshvan
+		//		2. Kislev
+		//		3. Tevet
+		//		4. Shevat
+		//		5. Adar I (leap years only)
+		//		6. Adar
+		//		7. Nisan
+		//		8. Iyar
+		//		9. Sivan
+		//		10. Tammuz
+		//		11. Av
+		//		12. Elul - 12
 		//
+		//		For non leap years, for months after Shevat, the actual position of
+		//		the month in the year (used for short format) is less than
+		//		the "absolute" index by 1.
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
-		// |
-		// |		console.log(date1.getMonth()+1);
-		// |		>> 7
+		//	|	var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
+		//	|	console.log(date1.getMonth()+1);
+		//	|	>> 7
 
 		return this._month;
 	},
 
 	getFullYear: function(){
-		// summary: returns the Year value
-		//
+		// summary:
+		//		returns the Year value
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
-		// |
-		// |		console.log(date1.getFullYear());
-		// |		>> 5769
+		//	|	var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
+		//	|	console.log(date1.getFullYear());
+		//	|	>> 5769
 		return this._year;
 	},
 			
 	getHours: function(){
- 		//summary: returns the hour value
+ 		// summary:
+ 		//		returns the hour value
 		return this._hours;
 	},
 		
 	getMinutes: function(){
-		//summary: returns the minutes value
+		// summary:
+		//		returns the minutes value
 
 		return this._minutes;
 	},
 
 	getSeconds: function(){
-		//summary: returns the seconds value
+		// summary:
+		//		returns the seconds value
 		return this._seconds;
 	},
 
 	getMilliseconds: function(){
-		//summary: returns the milliseconds value
+		// summary:
+		//		returns the milliseconds value
 
 		return this._milliseconds;
 	},
 
 	setDate: function(/*number*/date){
-		// summary: sets the date number for a given month
+		// summary:
+		//		sets the date number for a given month
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
-		// |		date1.setDate(2);
+		//	|	var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
+		//	|	date1.setDate(2);
 
 		date = +date;
 		var mdays;
@@ -310,12 +307,12 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	
 
 	setFullYear: function(/*number*/year, /*number?*/month, /*number?*/ date){
-		// summary: set the year
-		//
+		// summary:
+		//		 set the year
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date();
-		// |		date1.setFullYear(5768);
-		// |		date1.setFullYear(5768, 1, 1);
+		//	|	var date1 = new dojox.date.hebrew.Date();
+		//	|	date1.setFullYear(5768);
+		//	|	date1.setFullYear(5768, 1, 1);
 		
 		this._year = year = +year;
 		if(!this.isLeapYear(year) && this._month==5){  //incorrect month number for non leap year
@@ -335,27 +332,29 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	},
 
 	setMonth: function(/*number*/month){
-		// summary: sets the month.  You should use "absolute" index in the month array:
-		//	0. Tishri
-		//	1. Heshvan
-		//	2. Kislev
-		//	3. Tevet
-		//	4. Shevat
-		//	5. Adar I (leap years only)
-		//	6. Adar
-		//	7. Nisan
-		//	8. Iyar
-		//	9. Sivan
-		//	10. Tammuz
-		//	11.	Av
-		//	12. Elul - 12
-		//  For non leap years, for months after Shevat, the actual position of
+		// summary:
+		//		sets the month.  You should use "absolute" index in the month array:
+		//
+		//		0. Tishri
+		//		1. Heshvan
+		//		2. Kislev
+		//		3. Tevet
+		//		4. Shevat
+		//		5. Adar I (leap years only)
+		//		6. Adar
+		//		7. Nisan
+		//		8. Iyar
+		//		9. Sivan
+		//		10. Tammuz
+		//		11.	Av
+		//		12. Elul - 12
+		//
+		//	For non leap years, for months after Shevat, the actual position of
 		//	the month in the year (used for short format) is less than
 		//	the "absolute" index by 1.
-		//
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date();
-		// |		date1.setMonth(0); //first month
+		//	|	var date1 = new dojox.date.hebrew.Date();
+		//	|	date1.setMonth(0); //first month
 
 		month = +month; // coerce to a Number
 		if(!this.isLeapYear(this._year) && month == 5){month++;}
@@ -385,30 +384,30 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	},
 
 	setHours: function(){
-		//	summary: sets the hour
-		//
-		//	description: Sets the hour and optionally minutes, seconds, milliseconds also.
-		//
+		// summary:
+		//		sets the hour
+		// description:
+		//		Sets the hour and optionally minutes, seconds, milliseconds also.
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date();
-		// |		date1.setHours(12, 30, 0, 0);
+		//	|	var date1 = new dojox.date.hebrew.Date();
+		//	|	date1.setHours(12, 30, 0, 0);
 
 		var hours_arg_no = arguments.length;
 		var hours = 0;
 		if(hours_arg_no >= 1){
-			hours += +arguments[0];
+			hours = +arguments[0];
 		}
 
 		if(hours_arg_no >= 2){
-			this._minutes += +arguments[1];
+			this._minutes = +arguments[1];
 		}
 
 		if(hours_arg_no >= 3){
-			this._seconds += +arguments[2];
+			this._seconds = +arguments[2];
 		}
 
 		if(hours_arg_no == 4){
-			this._milliseconds += +arguments[3];
+			this._milliseconds = +arguments[3];
 		}
 
 		while(hours >= 24){
@@ -450,13 +449,15 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	},
 
 	setMinutes: function(/*Number*/minutes){
-		//summary: sets the minutes (0-59) only.
+		// summary:
+		//		sets the minutes (0-59) only.
 		this._minutes = minutes % 60;
 		return this;
 	},
 
 	setSeconds: function(/*Number*/seconds){
-		//summary: sets the seconds (0-59) only.
+		// summary:
+		//		sets the seconds (0-59) only.
 		this._seconds = seconds % 60;
 		return this;
 	},
@@ -476,23 +477,25 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	},
 
 	toString: function(){
-		// summary: returns a string representation of the date in "dd, MM, yyyy HH:mm:ss" format
-		//
-		// description: returns a string representation of the date in "dd, MM, yyyy HH:mm:ss" format (all numeric)
-		//	For user presentation, use dojox.date.hebrew.locale.format which will present in the appropriate language
-		//  and format.  toString() language- and culturally-specific conventions to keep this module free of
-		//	dependencies on dojox.date.locale and dojo.cldr.
-		//
+		// summary:
+		//		returns a string representation of the date in "dd, MM, yyyy HH:mm:ss" format
+		// description:
+		//		returns a string representation of the date in "dd, MM, yyyy HH:mm:ss" format (all numeric)
+		//		For user presentation, use dojox.date.hebrew.locale.format which will present in the appropriate language
+		//		and format.  toString() language- and culturally-specific conventions to keep this module free of
+		//		dependencies on dojox.date.locale and dojo.cldr.
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
-		// |		console.log(date1.toString());
-		// |		>>> "1, 6, 5769 0:0:0"
-		return this._date + ", " + this._month + ", " + this._year + "  " + this._hours + ":" + this._minutes + ":" + this._seconds; // String
+		//	|	var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
+		//	|	console.log(date1.toString());
+		//	|	>>> "1, 6, 5769 0:0:0"
+		return isNaN(this._date)?"Invalid Date":
+			this._date + ", " + this._month + ", " + this._year + "  " + this._hours + ":" + this._minutes + ":" + this._seconds; // String
 	},
 
 	// ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
 	getDaysInHebrewMonth: function(/*Number*/month, /*Number*/ year){
-		// summary: returns the number of days in the given month and year
+		// summary:
+		//		returns the number of days in the given month and year
 
 		// Aside from the leap month, these two months can vary: 1=HESHVAN, 2=KISLEV
 		// The rest are a fixed length
@@ -550,10 +553,11 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 
 	// ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
 	isLeapYear: function(/*Number*/year){
-	//	summary:
-	//		Determines if the year (argument) is a leap year
-	//	description: The Leap year contains additional month adar sheni
-	//
+		// summary:
+		//		Determines if the year (argument) is a leap year
+		// description:
+		//		The Leap year contains additional month adar sheni
+
 		//return (year * 12 + 17) % 19 >= 12;
 		var x = (year*12 + 17) % 19;
 		return x >= ((x < 0) ? -7 : 12);
@@ -561,11 +565,12 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 
 	
 	fromGregorian: function(/*Date*/gdate){
-		// summary: This function sets this Date to the Hebrew Date corresponding to the Gregorian Date
+		// summary:
+		//		This function sets this Date to the Hebrew Date corresponding to the Gregorian Date
 		// example:
-		// |		var dateHebrew = new dojox.date.hebrew.Date();
-		// |		var dateGregorian = new Date(2008,10,12);
-		// |		dateHebrew.fromGregorian(dateGregorian);
+		//	|	var dateHebrew = new dojox.date.hebrew.Date();
+		//	|	var dateGregorian = new Date(2008,10,12);
+		//	|	dateHebrew.fromGregorian(dateGregorian);
 
 		var result = (!isNaN(gdate)) ? this._computeHebrewFields(gdate) : NaN;
 		this._year = (!isNaN(gdate)) ? result[0] : NaN;
@@ -610,10 +615,11 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 
 	// ported from the Java class com.ibm.icu.util.Calendar.computeGregorianFields from ICU4J v3.6.1 at http://www.icu-project.org/
 	toGregorian: function(){
-		// summary: returns the equivalent Grogorian date value as a native Date object
+		// summary:
+		//		returns the equivalent Gregorian date value as a native Date object
 		// example:
-		// |		var dateHebrew = new dojox.date.hebrew.Date(5768,11,20);
-		// |		var dateGregorian = dateHebrew.toGregorian();
+		//	|	var dateHebrew = new dojox.date.hebrew.Date(5768,11,20);
+		//	|	var dateGregorian = dateHebrew.toGregorian();
 		
 		var hYear = this._year || 0,
 			hMonth = this._month || 0,
@@ -668,12 +674,11 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	},
 
 	getDay: function(){
-		// summary: returns weekday value (0 - 6)
-		//
+		// summary:
+		//		returns weekday value (0 - 6)
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date();
-		// |
-		// |		console.log(date1.getDay());
+		//	|	var date1 = new dojox.date.hebrew.Date();
+		//	|	console.log(date1.getDay());
 
 		var hYear = this._year,
 			hMonth = this._month,
@@ -690,7 +695,8 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 
 	// ported from the Java class com.ibm.icu.util.Calendar.computeGregorianMonthStart from ICU4J v3.6.1 at http://www.icu-project.org/
 	_getJulianDayFromGregorianDate: function(gdate){
-		//summary: returns the Julian day of a Gregorian date
+		// summary:
+		//		returns the Julian day of a Gregorian date
 
 		var year = gdate.getFullYear(),
 			month = gdate.getMonth(),
@@ -713,8 +719,8 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	}
 });
 
-dojox.date.hebrew.Date.prototype.valueOf = function(){
+HDate.prototype.valueOf = function(){
 	return this.toGregorian().valueOf();
 };
-return dojox.date.hebrew.Date;
+return HDate;
 });
diff --git a/dojox/date/hebrew/locale.js b/dojox/date/hebrew/locale.js
index 5b0e1db..7afb59f 100644
--- a/dojox/date/hebrew/locale.js
+++ b/dojox/date/hebrew/locale.js
@@ -1,12 +1,11 @@
-define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./Date", "./numerals", "dojo/i18n!dojo/cldr/nls/hebrew"],
-	function(dojo, dd, i18n, regexp, string, hebrewDate, numerals){
+define(["../..", "dojo/_base/lang", "dojo/_base/array", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./Date", "./numerals", "dojo/i18n!dojo/cldr/nls/hebrew"],
+	function(dojox, lang, arr, dd, i18n, regexp, string, HDate, numerals){
 
-	dojo.getObject("date.hebrew.locale", true, dojox);
-	dojo.experimental("dojox.date.hebrew.locale");
+	var hlocale = lang.getObject("date.hebrew.locale", true, dojox);
 
 	//Load the bundles containing localization information for
 	// names and formats
-	dojo.requireLocalization("dojo.cldr", "hebrew");
+	i18n.getLocalization("dojo.cldr", "hebrew");
 
 	// Format a pattern without literals
 	function formatPattern(dateObject, bundle, locale, fullYear,  pattern){
@@ -35,7 +34,7 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 							s = m+1; pad = true;
 						}
 					}else{
-						var monthNames = dojox.date.hebrew.locale.getNames('months',widthList[l-3], 'format', locale, dateObject);
+						var monthNames = hlocale.getNames('months',widthList[l-3], 'format', locale, dateObject);
 						s = monthNames[m];
 					}
 					break;
@@ -101,29 +100,28 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		});
 	}
 	
-	dojox.date.hebrew.locale.format = function(/*hebrew.Date*/dateObject, /*object?*/options){
-		// based on and similar to dojo.date.locale.format
-		//summary:
+	hlocale.format = function(/*dojox/date/hebrewDate*/dateObject, /*object?*/options){
+		// summary:
 		//		Format a Date object as a String, using  settings.
-		//
 		// description:
 		//		Create a string from a hebrew.Date object using a known pattern.
 		//		By default, this method formats both date and time from dateObject.
 		//		Default formatting lengths is 'short'
-		//
 		// dateObject:
 		//		the date and/or time to be formatted.  If a time only is formatted,
 		//		the values in the year, month, and day fields are irrelevant.  The
 		//		opposite is true when formatting only dates.
 
+		// based on and similar to dojo.date.locale.format
+
 		options = options || {};
 
 		var locale = i18n.normalizeLocale(options.locale);
 		var formatLength = options.formatLength || 'short';
-		var bundle = dojox.date.hebrew.locale._getHebrewBundle(locale);
+		var bundle = hlocale._getHebrewBundle(locale);
 		var str = [];
 
-		var sauce = dojo.hitch(this, formatPattern, dateObject, bundle, locale, options.fullYear);
+		var sauce = lang.hitch(this, formatPattern, dateObject, bundle, locale, options.fullYear);
 		if(options.selector == "year"){
 			var year = dateObject.getFullYear();
 			return locale.match(/^he(?:-.+)?$/) ?
@@ -142,20 +140,21 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		return result; // String
 	};
 
-	dojox.date.hebrew.locale.regexp = function(/*object?*/options){
-		//	based on and similar to dojo.date.locale.regexp
+	hlocale.regexp = function(/*object?*/options){
 		// summary:
 		//		Builds the regular needed to parse a hebrew.Date
 
-		return dojox.date.hebrew.locale._parseInfo(options).regexp; // String
+		//	based on and similar to dojo.date.locale.regexp
+
+		return hlocale._parseInfo(options).regexp; // String
 	};
 
-	dojox.date.hebrew.locale._parseInfo = function(/*oblect?*/options){
+	hlocale._parseInfo = function(/*oblect?*/options){
 	/* based on and similar to dojo.date.locale._parseInfo */
 
 		options = options || {};
 		var locale = i18n.normalizeLocale(options.locale);
-		var bundle = dojox.date.hebrew.locale._getHebrewBundle(locale);
+		var bundle = hlocale._getHebrewBundle(locale);
 
 		var formatLength = options.formatLength || 'short';
 		var datePattern = options.datePattern || bundle["dateFormat-" + formatLength];
@@ -172,32 +171,34 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 
 		var tokens = [];
 	
-		var re = _processPattern(pattern, dojo.hitch(this, _buildDateTimeRE, tokens, bundle, options));
+		var re = _processPattern(pattern, lang.hitch(this, _buildDateTimeRE, tokens, bundle, options));
 		return {regexp: re, tokens: tokens, bundle: bundle};
 	};
 
-	dojox.date.hebrew.locale.parse = function(/*String*/value, /*Object?*/options){
-			// based on and similar to dojo.date.locale.parse
-			// summary: This function parse string date value according to options
-			// example:
-			// |		var dateHebrew = dojox.date.hebrew.locale.parse('11/10/5740', {datePattern:'dd/MM/yy', selector:'date'});
-			// |		in Hebrew locale string for parsing contains Hebrew Numerals
-			// |
-			// |  options = {datePattern:'dd MMMM yy', selector:'date'};
-			// |
-			// |   y - year
-			// |   M, MM  - short month
-			// |  MMM, MMMM - long month
-			// |  d - date
-			// |  a - am, pm
-			// |   E, EE, EEE, EEEE  - week day
-			// |
-			// |    h, H, k, K, m, s, S,  -  time format
-		
+	hlocale.parse = function(/*String*/value, /*Object?*/options){
+		// summary:
+		//		This function parse string date value according to options
+		// example:
+		//	|	var dateHebrew = dojox.date.hebrew.locale.parse('11/10/5740', {datePattern:'dd/MM/yy', selector:'date'});
+		//	|	in Hebrew locale string for parsing contains Hebrew Numerals
+		//	|
+		//	|	  options = {datePattern:'dd MMMM yy', selector:'date'};
+		//	|
+		//	|	   y - year
+		//	|	   M, MM  - short month
+		//	|	  MMM, MMMM - long month
+		//	|	  d - date
+		//	|	  a - am, pm
+		//	|	   E, EE, EEE, EEEE  - week day
+		//	|
+		//	|	    h, H, k, K, m, s, S,  -  time format
+
+		// based on and similar to dojo.date.locale.parse
+
 		value =  value.replace(/[\u200E\u200F\u202A-\u202E]/g, ""); //remove special chars
 
 		if(!options){options={};}
-		var info = dojox.date.hebrew.locale._parseInfo(options);
+		var info = hlocale._parseInfo(options);
 	
 		var tokens = info.tokens, bundle = info.bundle;
 		var re = new RegExp("^" + info.regexp + "$");
@@ -206,10 +207,7 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 
 		var locale = i18n.normalizeLocale(options.locale);
 
-		if(!match){
-			console.debug("dojox.date.hebrew.locale.parse: value  "+value+" doesn't match pattern   " + re);
-			return null;
-		} // null
+		if(!match){ return null; } // null
 	
 		var date, date1;
 	
@@ -218,7 +216,7 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		var amPm = "";
 		var mLength = 0;
 		var widthList = ["abbr", "wide", "narrow"];
-		var valid = dojo.every(match, function(v, i){
+		var valid = arr.every(match, function(v, i){
 			if(!i){return true;}
 			var token=tokens[i-1];
 			var l=token.length;
@@ -234,19 +232,19 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 					//if  it is short format, month is one letter or two letter with "geresh"
 					if(l>2){
 						//we do not know here if the year is leap or not
-						var months = dojox.date.hebrew.locale.getNames('months', widthList[l-3], 'format', locale, new hebrewDate(5769, 1, 1)),
-							leapmonths = dojox.date.hebrew.locale.getNames('months', widthList[l-3], 'format', locale, new hebrewDate(5768, 1, 1));
+						var months = hlocale.getNames('months', widthList[l-3], 'format', locale, new HDate(5769, 1, 1)),
+							leapmonths = hlocale.getNames('months', widthList[l-3], 'format', locale, new HDate(5768, 1, 1));
 						if(!options.strict){
 							//Tolerate abbreviating period in month part
 							//Case-insensitive comparison
 							v = v.replace(".","").toLowerCase();
-							months = dojo.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
-							leapmonths = dojo.map(leapmonths, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
+							months = arr.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
+							leapmonths = arr.map(leapmonths, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
 						}
 						var monthName = v;
-						v = dojo.indexOf(months, monthName);
+						v = arr.indexOf(months, monthName);
 						if(v == -1){
-							v = dojo.indexOf(leapmonths, monthName);
+							v = arr.indexOf(leapmonths, monthName);
 							if(v == -1){
 								//console.debug("dojox.date.hebrew.locale.parse: Could not parse month name:  second   " + v +"'.");
 								return false;
@@ -316,7 +314,7 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		}else if(amPm === 'a' && hours == 12){
 			result[3] = 0; //12am -> 0
 		}
-		var dateObject = new hebrewDate(result[0], result[1], result[2], result[3], result[4], result[5], result[6]); // hebrew.Date
+		var dateObject = new HDate(result[0], result[1], result[2], result[3], result[4], result[5], result[6]); // hebrew.Date
 		//for non leap year, the index of the short month start from adar should be increased by 1
 		if(mLength < 3 && result[1] >= 5 && !dateObject.isLeapYear(dateObject.getFullYear())){
 			dateObject.setMonth(result[1]+1);
@@ -326,7 +324,8 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 
 
 	function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
-		//summary: Process a pattern with literals in it
+		// summary:
+		//		Process a pattern with literals in it
 
 		// Break up on single quotes, treat every other one as a literal, except '' which becomes '
 		var identity = function(x){return x;};
@@ -339,7 +338,7 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		var chunks = pattern.match(/(''|[^'])+/g);
 		var literal = pattern.charAt(0) == "'";
 
-		dojo.forEach(chunks, function(chunk, i){
+		arr.forEach(chunks, function(chunk, i){
 			if(!chunk){
 				chunks[i]='';
 			}else{
@@ -351,9 +350,8 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 	}
 
 	function _buildDateTimeRE  (tokens, bundle, options, pattern){
-			// based on and similar to dojo.date.locale._buildDateTimeRE
-			//
-	
+		// based on and similar to dojo.date.locale._buildDateTimeRE
+
 		pattern = regexp.escapeString(pattern);
 		var locale = i18n.normalizeLocale(options.locale);
 	
@@ -434,11 +432,10 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 	}
 
 	var _customFormats = [];
-	dojox.date.hebrew.locale.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){
+	hlocale.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){
 		// summary:
 		//		Add a reference to a bundle containing localized custom formats to be
 		//		used by date/time formatting and parsing routines.
-		//
 		// description:
 		//		The user may add custom localized formats where the bundle has properties following the
 		//		same naming convention used by dojo.cldr: `dateFormat-xxxx` / `timeFormat-xxxx`
@@ -449,36 +446,35 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		_customFormats.push({pkg:packageName,name:bundleName});
 	};
 
-	dojox.date.hebrew.locale._getHebrewBundle = function(/*String*/locale){
+	hlocale._getHebrewBundle = function(/*String*/locale){
 		var hebrew = {};
-		dojo.forEach(_customFormats, function(desc){
+		arr.forEach(_customFormats, function(desc){
 			var bundle = i18n.getLocalization(desc.pkg, desc.name, locale);
-			hebrew = dojo.mixin(hebrew, bundle);
+			hebrew = lang.mixin(hebrew, bundle);
 		}, this);
 		return hebrew; /*Object*/
 	};
 
-	dojox.date.hebrew.locale.addCustomFormats("dojo.cldr","hebrew");
+	hlocale.addCustomFormats("dojo.cldr","hebrew");
 
-	dojox.date.hebrew.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*dojox.date.hebrew.Date?*/date){
+	hlocale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*dojox/date/hebrew/Date?*/date){
 		// summary:
 		//		Used to get localized strings from dojo.cldr for day or month names.
-		//
 		// item:
-		//	'months' || 'days'
+		//		'months' || 'days'
 		// type:
-		//	'wide' || 'narrow' || 'abbr' (e.g. "Monday", "Mon", or "M" respectively, in English)
+		//		'wide' || 'narrow' || 'abbr' (e.g. "Monday", "Mon", or "M" respectively, in English)
 		// use:
-		//	'standAlone' || 'format' (default)
+		//		'standAlone' || 'format' (default)
 		// locale:
-		//	override locale used to find the names
+		//		override locale used to find the names
 		// date:
-		//	required for item=months to determine leap month name
-		//
+		//		required for item=months to determine leap month name
+
 		// using  var monthNames = dojox.date.hebrew.locale.getNames('months', 'wide', 'format', 'he', new hebrewDate(5768, 2, 12));
 
 		var label,
-			lookup = dojox.date.hebrew.locale._getHebrewBundle(locale),
+			lookup = hlocale._getHebrewBundle(locale),
 			props = [item, context, type];
 		if(context == 'standAlone'){
 			var key = props.join('-');
@@ -506,5 +502,5 @@ define(["dojo/main", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./
 		return result; /*Array*/
 	};
 
-	return dojox.date.hebrew.locale;
+	return hlocale;
 });
diff --git a/dojox/date/hebrew/numerals.js b/dojox/date/hebrew/numerals.js
index 9c48809..b03a2c8 100644
--- a/dojox/date/hebrew/numerals.js
+++ b/dojox/date/hebrew/numerals.js
@@ -1,8 +1,7 @@
-define(["dojo/_base/kernel", "dojo/_base/array"], function(dojo){
-	dojo.getObject("date.hebrew.numerals", true, dojox);
-	dojo.experimental("dojox.date.hebrew.numerals");
+define(["../..", "dojo/_base/lang", "dojo/_base/array"], function(dojox, lang, arr){
+	var hnumerals = lang.getObject("date.hebrew.numerals", true, dojox);
 
-//Conversion from "Hindi" numerals to Hebrew numerals and vice versa
+	//Conversion from "Hindi" numerals to Hebrew numerals and vice versa
 
 	var DIG="אבגדהוזחט";
 	var	TEN="יכלמנסעפצ";
@@ -24,7 +23,7 @@ define(["dojo/_base/kernel", "dojo/_base/array"], function(dojo){
 	 
 	var parseStrToNumber = function(str){
 		var num = 0;
-		dojo.forEach(str, function(ch){
+		arr.forEach(str, function(ch){
 			var i;
 			if((i = DIG.indexOf(ch)) != -1){
 				num += ++i;
@@ -61,13 +60,12 @@ define(["dojo/_base/kernel", "dojo/_base/array"], function(dojo){
 		return str; //String
 	};
 
-	dojox.date.hebrew.numerals.getYearHebrewLetters = function(/*Number */ year){
-		// summary: converts the year from an integer to Hebrew numerals.
-		//
+	hnumerals.getYearHebrewLetters = function(/*Number */ year){
+		// summary:
+		//		converts the year from an integer to Hebrew numerals.
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date();
-		// |
-		// |		document.writeln(dojox.date.hebrew.numerals.getYearHebrewLetters(date1.getFullYear());
+		//	|	var date1 = new dojox.date.hebrew.Date();
+		//	|	document.writeln(dojox.date.hebrew.numerals.getYearHebrewLetters(date1.getFullYear());
 		
 		var rem = year % 1000;
 		//FIXME: tests include dates outside this range and seem to pass.
@@ -75,66 +73,64 @@ define(["dojo/_base/kernel", "dojo/_base/array"], function(dojo){
 		return transformChars(convertNumberToStr(rem)); // String
 	};
 	
-	dojox.date.hebrew.numerals.parseYearHebrewLetters  = function(/*String hebrew year*/ year){
-		// summary: converts the year written in Hebrew numerals to an integer
-		//
+	hnumerals.parseYearHebrewLetters  = function(/*String hebrew year*/ year){
+		// summary:
+		//		converts the year written in Hebrew numerals to an integer
 		// example:
-		// |		var date = new dojox.date.hebrew.Date();
-		// |        	date.setFullYear(dojox.date.hebrew.numerals.parseYearHebrewLetters('\u05ea\u05e9\u05e1\u05f4\u05d7'));
+		//	|	var date = new dojox.date.hebrew.Date();
+		//	|	        	date.setFullYear(dojox.date.hebrew.numerals.parseYearHebrewLetters('\u05ea\u05e9\u05e1\u05f4\u05d7'));
 
 		return parseStrToNumber(year) + 5000; // int
 	};
 	
-	dojox.date.hebrew.numerals.getDayHebrewLetters =  function(day, /*boolean?*/ nogrsh){
-		// summary: converts an integer to a String representing the number in Hebrew numerals.   Can be formatted with or without geresh &#x05f3;
-		//
+	hnumerals.getDayHebrewLetters =  function(day, /*boolean?*/ nogrsh){
+		// summary:
+		//		 converts an integer to a String representing the number in Hebrew numerals.
+		//		Can be formatted with or without geresh &#x05f3;
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date();
-		// |
-		// |		document.writeln(dojox.date.hebrew.numerals.getDayHebrewLetters(date1.getDay());
+		//	|	var date1 = new dojox.date.hebrew.Date();
+		//	|	document.writeln(dojox.date.hebrew.numerals.getDayHebrewLetters(date1.getDay());
 
 		return transformChars(convertNumberToStr(day), nogrsh); // String
 	};
 	
-	dojox.date.hebrew.numerals.parseDayHebrewLetters =  function(/*String hebrew*/ day){
-		// summary: converts the string containing a Hebrew numeral to an integer
-		//
+	hnumerals.parseDayHebrewLetters =  function(/*String hebrew*/ day){
+		// summary:
+		//		converts the string containing a Hebrew numeral to an integer
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date();
-		// |
-		// |		date1.setDate(dojox.date.hebrew.numerals.parseDayHebrewLetters('\u05d0')); // ALEPH
+		//	|	var date1 = new dojox.date.hebrew.Date();
+		//	|	date1.setDate(dojox.date.hebrew.numerals.parseDayHebrewLetters('\u05d0')); // ALEPH
 		return parseStrToNumber(day); // int
 	};
 
-	dojox.date.hebrew.numerals.getMonthHebrewLetters =  function(/*int*/month){
-		// summary: converts an integer representing a  month to a String written in Hebrew numerals
-		//
+	hnumerals.getMonthHebrewLetters =  function(/*int*/month){
+		// summary:
+		//		converts an integer representing a  month to a String written in Hebrew numerals
 		// example:
-		// |		var date1 = new dojox.date.hebrew.Date();
-		// |
-		// |		document.writeln(dojox.date.hebrew.numerals.getMonthHebrewLetters(date1.getMonth());
+		//	|	var date1 = new dojox.date.hebrew.Date();
+		//	|	document.writeln(dojox.date.hebrew.numerals.getMonthHebrewLetters(date1.getMonth());
 
 		return transformChars(convertNumberToStr(month+1)); // String
 	};
 
-	dojox.date.hebrew.numerals.parseMonthHebrewLetters = function(/*String*/monthStr){
-		// summary: converts a Hebrew numeral string representing
-		//	a month to an integer.  The returned value
-		//	is indexed in the month name array.  To use it for
-		//	setMonth, do correction for leap year
-		//
+	hnumerals.parseMonthHebrewLetters = function(/*String*/monthStr){
+		// summary:
+		//		converts a Hebrew numeral string representing
+		//		a month to an integer.  The returned value
+		//		is indexed in the month name array.  To use it for
+		//		setMonth, do correction for leap year
 		// example:
-		// |		var date = new dojox.date.hebrew.Date();
-		// |            var number = dojox.date.hebrew.numerals.parseMonthHebrewLetters("\u05ea\u05de\u05d5\u05d6"); // Tammuz
-		// |		date.setMonth(number);
+		//	|	var date = new dojox.date.hebrew.Date();
+		//	|	            var number = dojox.date.hebrew.numerals.parseMonthHebrewLetters("\u05ea\u05de\u05d5\u05d6"); // Tammuz
+		//	|	date.setMonth(number);
 			
 		//month number from 0 to 12
-		var monnum = dojox.date.hebrew.numerals.parseDayHebrewLetters(monthStr) - 1;
+		var monnum = hnumerals.parseDayHebrewLetters(monthStr) - 1;
 
 		if(monnum == -1 || monnum > 12){
 			throw new Error("The month name is incorrect , month = " + monnum);
 		}
 		return monnum;
 	};
-	return dojox.date.hebrew.numerals;
+	return hnumerals;
 });
diff --git a/dojox/date/islamic.js b/dojox/date/islamic.js
index 590160e..b2404c3 100644
--- a/dojox/date/islamic.js
+++ b/dojox/date/islamic.js
@@ -1,55 +1,54 @@
-define(["dojo/_base/kernel", "dojo/date", "./islamic/Date"], function(dojo, dd, islamicDate){
+define(["..", "dojo/_base/lang", "dojo/date", "./islamic/Date"], function(dojox, lang, dd, IDate){
 
-dojo.getObject("date.islamic", true, dojox);
-dojo.experimental("dojox.date.islamic");
+var dislamic = lang.getObject("date.islamic", true, dojox);
 
 // Utility methods to do arithmetic calculations with islamic.Dates
 
 	// added for compat to date
-dojox.date.islamic.getDaysInMonth = function(/*islamic.Date*/month){
+dislamic.getDaysInMonth = function(/*dojox/date/islamic/Date*/month){
 	return month.getDaysInIslamicMonth(month.getMonth(), month.getFullYear());
 };
 
 //TODO: define islamic.isLeapYear?  Or should it be invalid, since it has different meaning?
 
-dojox.date.islamic.compare = function(/*islamic.Date*/date1, /*islamic.Date*/date2, /*String?*/portion){
-	//	summary:
+dislamic.compare = function(/*dojox/date/islamic/Date*/date1, /*dojox/date/islamic/Date*/date2, /*String?*/portion){
+	// summary:
 	//		Compare two islamic date objects by date, time, or both.
-	//	description:
-	//  	Returns 0 if equal, positive if a > b, else negative.
-	//	date1:
-	//		islamic.Date object
-	//	date2:
-	//		islamic.Date object.  If not specified, the current islamic.Date is used.
-	//	portion:
+	// description:
+	//		Returns 0 if equal, positive if a > b, else negative.
+	// date1: dojox/date/islamic/Date
+	// date2: dojox/date/islamic/Date
+	//		If not specified, the current islamic.Date is used.
+	// portion:
 	//		A string indicating the "date" or "time" portion of a Date object.
 	//		Compares both "date" and "time" by default.  One of the following:
 	//		"date", "time", "datetime"
 
-	if(date1 instanceof islamicDate){
+	if(date1 instanceof IDate){
 		date1 = date1.toGregorian();
 	}
-	if(date2 instanceof islamicDate){
+	if(date2 instanceof IDate){
 		date2 = date2.toGregorian();
 	}
 	
 	return dd.compare.apply(null, arguments);
 };
 
-dojox.date.islamic.add = function(/*dojox.date.islamic.Date*/date, /*String*/interval, /*int*/amount){
-	//	based on and similar to dojo.date.add
-	//	summary:
+dislamic.add = function(/*dojox/date/islamic/Date*/date, /*String*/interval, /*int*/amount){
+	// summary:
 	//		Add to a Date in intervals of different size, from milliseconds to years
-	//	date: islamic.Date
+	// date: dojox/date/islamic/Date
 	//		Date object to start with
-	//	interval:
+	// interval:
 	//		A string representing the interval.  One of the following:
-	//			"year", "month", "day", "hour", "minute", "second",
-	//			"millisecond", "week", "weekday"
-	//	amount:
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond", "week", "weekday"
+	// amount:
 	//		How much to add to the date.
 
-	var newIslamDate = new islamicDate(date);
+	//	based on and similar to dojo.date.add
+
+	var newIslamDate = new IDate(date);
 
 	switch(interval){
 		case "day":
@@ -107,25 +106,29 @@ dojox.date.islamic.add = function(/*dojox.date.islamic.Date*/date, /*String*/int
 	return newIslamDate; // dojox.date.islamic.Date
 };
 
-dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*dojox.date.islamic.Date?*/date2, /*String?*/interval){
-	//	based on and similar to dojo.date.difference
-	//	summary:
-	//        date2 - date1
-	//	 date2 is islamic.Date object.  If not specified, the current islamic.Date is used.
-	//	interval:
+dislamic.difference = function(/*dojox/date/islamic/Date*/date1, /*dojox/date/islamic/Date?*/date2, /*String?*/interval){
+	// summary:
+	//		date2 - date1
+	// date1: dojox/date/islamic/Date
+	// date2: dojox/date/islamic/Date
+	//		If not specified, the current dojox.date.islamic.Date is used.
+	// interval:
 	//		A string representing the interval.  One of the following:
-	//			"year", "month", "day", "hour", "minute", "second",
-	//			"millisecond",  "week", "weekday"
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond",  "week", "weekday"
+	//
 	//		Defaults to "day".
 
-	date2 = date2 || new islamicDate();
+	//	based on and similar to dojo.date.difference
+
+	date2 = date2 || new IDate();
 	interval = interval || "day";
 	var yearDiff = date2.getFullYear() - date1.getFullYear();
 	var delta = 1; // Integer return value
 	switch(interval){
 		case "weekday":
-			var days = Math.round(dojox.date.islamic.difference(date1, date2, "day"));
-			var weeks = parseInt(dojox.date.islamic.difference(date1, date2, "week"));
+			var days = Math.round(dislamic.difference(date1, date2, "day"));
+			var weeks = parseInt(dislamic.difference(date1, date2, "week"));
 			var mod = days % 7;
 
 			// Even number of weeks
@@ -141,7 +144,7 @@ dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*doj
 				mod = days % 7;
 				// Mark the date advanced by the number of
 				// round weeks (may be zero)
-				var dtMark = new islamicDate(date1);
+				var dtMark = new IDate(date1);
 				dtMark.setDate(dtMark.getDate()+(weeks*7));
 				var dayMark = dtMark.getDay();
 	
@@ -224,7 +227,7 @@ dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*doj
 		case "week":
 			// Truncate instead of rounding
 			// Don't use Math.floor -- value may be negative
-			delta = parseInt(dojox.date.islamic.difference(date1, date2, "day")/7);
+			delta = parseInt(dislamic.difference(date1, date2, "day")/7);
 			break;
 		case "day":
 			delta /= 24;
@@ -245,5 +248,5 @@ dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*doj
 	// Round for fractional values and DST leaps
 	return Math.round(delta); // Number (integer)
 };
-return dojox.date.islamic;
+return dislamic;
 });
\ No newline at end of file
diff --git a/dojox/date/islamic/Date.js b/dojox/date/islamic/Date.js
index 3dad685..51496e8 100644
--- a/dojox/date/islamic/Date.js
+++ b/dojox/date/islamic/Date.js
@@ -1,19 +1,13 @@
-define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/date"], function(dojo, declare, dd){
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/date"], function(lang, declare, dd){
 
-dojo.getObject("date.buddhist.Date", true, dojox);
-dojo.experimental("dojox.date.buddhist.Date");
-
-dojo.declare("dojox.date.islamic.Date", null, {
-	// summary: The component defines the Islamic (Hijri) Calendar Object
-	//
+	var IDate = declare("dojox.date.islamic.Date", null, {
+	// summary:
+	//		The component defines the Islamic (Hijri) Calendar Object
 	// description:
-	//	This module is similar to the Date() object provided by JavaScript
-	//
+	//		This module is similar to the Date() object provided by JavaScript
 	// example:
-	// |	dojo.require("dojox.date.islamic.Date");
-	// |
-	// |	var date = new dojox.date.islamic.Date();
-	// |	document.writeln(date.getFullYear()+'\'+date.getMonth()+'\'+date.getDate());
+	//	|	var date = new dojox.date.islamic.Date();
+	//	|	document.writeln(date.getFullYear()+'\'+date.getMonth()+'\'+date.getDate());
 
 
 	_date: 0,
@@ -28,18 +22,15 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	_ISLAMIC_EPOCH : 1948439.5,
 
 	constructor: function(){
-		// summary: This is the constructor
+		// summary:
+		//		This is the constructor
 		// description:
-		//	This function initialize the date object values
-		//
+		//		This function initialize the date object values
 		// example:
-		// |		var date1 = new dojox.date.islamic.Date();
-		// |
-		// |		var date2 = new dojox.date.islamic.Date("12\2\1429");
-		// |
-		// |		var date3 = new dojox.date.islamic.Date(date2);
-		// |
-		// |		var date4 = new dojox.date.islamic.Date(1429,2,12);
+		//	|	var date1 = new dojox.date.islamic.Date();
+		//	|	var date2 = new dojox.date.islamic.Date("12\2\1429");
+		//	|	var date3 = new dojox.date.islamic.Date(date2);
+		//	|	var date4 = new dojox.date.islamic.Date(1429,2,12);
 
 		var len = arguments.length;
 		if(!len){// use the current date value, added "" to the similarity to date
@@ -77,73 +68,74 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	},
 
 	getDate:function(){
-		// summary: This function returns the date value (1 - 30)
-		//
+		// summary:
+		//		This function returns the date value (1 - 30)
 		// example:
-		// |		var date1 = new dojox.date.islamic.Date();
-		// |
-		// |		document.writeln(date1.getDate);
+		//	|	var date1 = new dojox.date.islamic.Date();
+		//	|	document.writeln(date1.getDate);
 		return this._date;
 	},
 	
 	getMonth:function(){
-		// summary: This function return the month value ( 0 - 11 )
-		//
+		// summary:
+		//		This function return the month value ( 0 - 11 )
 		// example:
-		// |		var date1 = new dojox.date.islamic.Date();
-		// |
-		// |		document.writeln(date1.getMonth()+1);
+		//	|	var date1 = new dojox.date.islamic.Date();
+		//	|	document.writeln(date1.getMonth()+1);
 
 		return this._month;
 	},
 
 	getFullYear:function(){
-		// summary: This function return the Year value
-		//
+		// summary:
+		//		This function return the Year value
 		// example:
-		// |		var date1 = new dojox.date.islamic.Date();
-		// |
-		// |		document.writeln(date1.getFullYear());
+		//	|	var date1 = new dojox.date.islamic.Date();
+		//	|	document.writeln(date1.getFullYear());
 
 		return this._year;
 	},
 		
 	getDay:function(){
-		// summary: This function return Week Day value ( 0 - 6 )
-		//
+		// summary:
+		//		This function return Week Day value ( 0 - 6 )
 		// example:
-		// |		var date1 = new dojox.date.islamic.Date();
-		// |
-		// |		document.writeln(date1.getDay());
+		//	|	var date1 = new dojox.date.islamic.Date();
+		//	|	document.writeln(date1.getDay());
 
 		return this.toGregorian().getDay();
 	},
 		
 	getHours:function(){
-		//summary: returns the Hour value
+		// summary:
+		//		returns the Hour value
 		return this._hours;
 	},
 	
 	getMinutes:function(){
-		//summary: returns the Minuites value
+		// summary:
+		//		returns the Minutes value
 		return this._minutes;
 	},
 
 	getSeconds:function(){
-		//summary: returns the seconde value
+		// summary:
+		//		returns the seconds value
 		return this._seconds;
 	},
 
 	getMilliseconds:function(){
-		//summary: returns the Milliseconds value
+		// summary:
+		//		returns the Milliseconds value
 		return this._milliseconds;
 	},
 
 	setDate: function(/*number*/date){
-		// summary: This function sets the Date
+		// summary:
+		//		This function sets the Date
 		// example:
-		// |		var date1 = new dojox.date.islamic.Date();
-		// |		date1.setDate(2);
+		//	|	var date1 = new dojox.date.islamic.Date();
+		//	|	date1.setDate(2);
 
 		date = parseInt(date);
 
@@ -176,21 +168,21 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	},
 
 	setFullYear:function(/*number*/year){
-		// summary: This function set Year
-		//
+		// summary:
+		//		This function set Year
 		// example:
-		// |		var date1 = new dojox.date.islamic.Date();
-		// |		date1.setYear(1429);
+		//	|	var date1 = new dojox.date.islamic.Date();
+		//	|	date1.setYear(1429);
 
 		this._year = +year;
 	},
 
 	setMonth: function(/*number*/month) {
-		// summary: This function set Month
-		//
+		// summary:
+		//		This function set Month
 		// example:
-		// |		var date1 = new dojox.date.islamic.Date();
-		// |		date1.setMonth(2);
+		//	|	var date1 = new dojox.date.islamic.Date();
+		//	|	date1.setMonth(2);
 
 		this._year += Math.floor(month / 12);
 		if(month > 0){
@@ -201,7 +193,8 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	},
 
 	setHours:function(){
-		//summary: set the Hours
+		// summary:
+		//		set the Hours
 		var hours_arg_no = arguments.length;
 		var hours = 0;
 		if(hours_arg_no >= 1){
@@ -255,13 +248,15 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	},
 
 	setMinutes: function(/*Number*/minutes){
-		//summary: sets the minutes (0-59) only.
+		// summary:
+		//		sets the minutes (0-59) only.
 		this._minutes = minutes % 60;
 		return this;
 	},
 
 	setSeconds: function(/*Number*/seconds){
-		//summary: sets the seconds (0-59) only.
+		// summary:
+		//		sets the seconds (0-59) only.
 		this._seconds = seconds % 60;
 		return this;
 	},
@@ -272,26 +267,32 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	},
 		
 	toString:function(){
-		// summary: This returns a string representation of the date in "DDDD MMMM DD YYYY HH:MM:SS" format
+		// summary:
+		//		This returns a string representation of the date in "DDDD MMMM DD YYYY HH:MM:SS" format
 		// example:
-		// |		var date1 = new dojox.date.islamic.Date();
-		// |		document.writeln(date1.toString());
+		//	|	var date1 = new dojox.date.islamic.Date();
+		//	|	document.writeln(date1.toString());
 
 		//FIXME: TZ/DST issues?
-		var x = new Date();
-		x.setHours(this._hours);
-		x.setMinutes(this._minutes);
-		x.setSeconds(this._seconds);
-		x.setMilliseconds(this._milliseconds);
-		return this._month+" "+ this._date + " " + this._year + " " + x.toTimeString();
+		if(isNaN(this._date)){
+			return "Invalidate Date";
+		}else{
+			var x = new Date();
+			x.setHours(this._hours);
+			x.setMinutes(this._minutes);
+			x.setSeconds(this._seconds);
+			x.setMilliseconds(this._milliseconds);
+			return this._month+" "+ this._date + " " + this._year + " " + x.toTimeString();
+		}
 	},
 		
 		
 	toGregorian:function(){
-		// summary: This returns the equevalent Grogorian date value in Date object
+		// summary:
+		//		This returns the equevalent Grogorian date value in Date object
 		// example:
-		// |		var dateIslamic = new dojox.date.islamic.Date(1429,11,20);
-		// |		var dateGregorian = dateIslamic.toGregorian();
+		//	|	var dateIslamic = new dojox.date.islamic.Date(1429,11,20);
+		//	|	var dateGregorian = dateIslamic.toGregorian();
 
 		var hYear = this._year;
 		var hMonth = this._month;
@@ -340,11 +341,12 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	//TODO: would it make more sense to make this a constructor option? or a static?
 	// ported from the Java class com.ibm.icu.util.IslamicCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
 	fromGregorian:function(/*Date*/gdate){
-		// summary: This function returns the equivalent Islamic Date value for the Gregorian Date
+		// summary:
+		//		This function returns the equivalent Islamic Date value for the Gregorian Date
 		// example:
-		// |		var dateIslamic = new dojox.date.islamic.Date();
-		// |		var dateGregorian = new Date(2008,10,12);
-		// |		dateIslamic.fromGregorian(dateGregorian);
+		//	|	var dateIslamic = new dojox.date.islamic.Date();
+		//	|	var dateGregorian = new Date(2008,10,12);
+		//	|	dateIslamic.fromGregorian(dateGregorian);
 
 		var date = new Date(gdate);
 		var gYear = date.getFullYear(),
@@ -375,34 +377,39 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	},
 	
 	valueOf:function(){
-		// summary: This function returns The stored time value in milliseconds
-		// since midnight, January 1, 1970 UTC
+		// summary:
+		//		This function returns The stored time value in milliseconds
+		//		since midnight, January 1, 1970 UTC
 
 		return this.toGregorian().valueOf();
 	},
 
 	// ported from the Java class com.ibm.icu.util.IslamicCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
 	_yearStart:function(/*Number*/year){
-		//summary: return start of Islamic year
+		// summary:
+		//		return start of Islamic year
 		return (year-1)*354 + Math.floor((3+11*year)/30.0);
 	},
 
 	// ported from the Java class com.ibm.icu.util.IslamicCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
 	_monthStart:function(/*Number*/year, /*Number*/month){
-		//summary: return the start of Islamic Month
+		// summary:
+		//		return the start of Islamic Month
 		return Math.ceil(29.5*month) +
 			(year-1)*354 + Math.floor((3+11*year)/30.0);
 	},
 
 	// ported from the Java class com.ibm.icu.util.IslamicCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
 	_civilLeapYear:function(/*Number*/year){
-		//summary: return Boolean value if Islamic leap year
+		// summary:
+		//		return Boolean value if Islamic leap year
 		return (14 + 11 * year) % 30 < 11;
 	},
 
 	// ported from the Java class com.ibm.icu.util.IslamicCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
 	getDaysInIslamicMonth:function(/*Number*/month, /*Number*/ year){
-		//summary: returns the number of days in the given Islamic Month
+		// summary:
+		//		returns the number of days in the given Islamic Month
 		var length = 0;
 		length = 29 + ((month+1) % 2);
 		if(month == 11 && this._civilLeapYear(year)){
@@ -417,8 +424,8 @@ dojo.declare("dojox.date.islamic.Date", null, {
 });
 
 //TODOC
-dojox.date.islamic.Date.getDaysInIslamicMonth = function(/*dojox.date.islamic.Date*/month){
-	return new dojox.date.islamic.Date().getDaysInIslamicMonth(month.getMonth(),month.getFullYear()); // dojox.date.islamic.Date
+IDate.getDaysInIslamicMonth = function(/*dojox/date/islamic.Date*/month){
+	return new IDate().getDaysInIslamicMonth(month.getMonth(),month.getFullYear()); // dojox.date.islamic.Date
 };
-return dojox.date.islamic.Date;
+return IDate;
 });
diff --git a/dojox/date/islamic/locale.js b/dojox/date/islamic/locale.js
index caed2a8..b36f4e3 100644
--- a/dojox/date/islamic/locale.js
+++ b/dojox/date/islamic/locale.js
@@ -1,10 +1,7 @@
-define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./Date", "dojo/i18n!dojo/cldr/nls/islamic"],
-	function(dojo, dlang, darray, dd, i18n, regexp, string, islamicDate){
+define(["../..", "dojo/_base/lang", "dojo/_base/array", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./Date", "dojo/i18n!dojo/cldr/nls/islamic"],
+       function(dojox, lang, arr, dd, i18n, regexp, string, IDate, bundle){
 
-	dojo.getObject("date.islamic.locale", true, dojox);
-	dojo.experimental("dojox.date.islamic.locale");
-
-	dojo.requireLocalization("dojo.cldr", "islamic");
+	var ilocale = lang.getObject("date.islamic.locale", true, dojox);
 
 	// Format a pattern without literals
 	function formatPattern(dateObject, bundle, locale, fullYear,  pattern){
@@ -105,17 +102,17 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date",
 	}
 	
 	// based on and similar to dojo.date.locale.format
-	dojox.date.islamic.locale.format = function(/*islamic.Date*/dateObject, /*Object?*/options){
+	ilocale.format = function(/*dojox/date/islamic/Date*/dateObject, /*Object?*/options){
 		// summary:
 		//		Format a Date object as a String, using  settings.
 		options = options || {};
 
 		var locale = i18n.normalizeLocale(options.locale);
 		var formatLength = options.formatLength || 'short';
-		var bundle = dojox.date.islamic.locale._getIslamicBundle(locale);
+		var bundle = ilocale._getIslamicBundle(locale);
 		var str = [];
 
-		var sauce = dojo.hitch(this, formatPattern, dateObject, bundle, locale, options.fullYear);
+		var sauce = lang.hitch(this, formatPattern, dateObject, bundle, locale, options.fullYear);
 		if(options.selector == "year"){
 			var year = dateObject.getFullYear();
 			return year;
@@ -133,19 +130,21 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date",
 		return result; // String
 	};
 
-	dojox.date.islamic.locale.regexp = function(/*object?*/options){
-		//	based on and similar to dojo.date.locale.regexp
+	ilocale.regexp = function(/*object?*/options){
 		// summary:
 		//		Builds the regular needed to parse a islamic.Date
-		return dojox.date.islamic.locale._parseInfo(options).regexp; // String
+
+		//	based on and similar to dojo.date.locale.regexp
+
+		return ilocale._parseInfo(options).regexp; // String
 	};
 
-	dojox.date.islamic.locale._parseInfo = function(/*oblect?*/options){
+	ilocale._parseInfo = function(/*oblect?*/options){
 	/* based on and similar to dojo.date.locale._parseInfo */
 
 		options = options || {};
 		var locale = i18n.normalizeLocale(options.locale);
-		var bundle = dojox.date.islamic.locale._getIslamicBundle(locale);
+		var bundle = ilocale._getIslamicBundle(locale);
 		var formatLength = options.formatLength || 'short';
 		var datePattern = options.datePattern || bundle["dateFormat-" + formatLength];
 		var timePattern = options.timePattern || bundle["timeFormat-" + formatLength];
@@ -161,18 +160,20 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date",
 
 		var tokens = [];
 	
-		var re = _processPattern(pattern, dojo.hitch(this, _buildDateTimeRE, tokens, bundle, options));
+		var re = _processPattern(pattern, lang.hitch(this, _buildDateTimeRE, tokens, bundle, options));
 		return {regexp: re, tokens: tokens, bundle: bundle};
 	};
 
-	dojox.date.islamic.locale.parse = function(/*String*/value, /*Object?*/options){
+	ilocale.parse = function(/*String*/value, /*Object?*/options){
+		// summary:
+		//		This function parse string date value according to options
+
 		// based on and similar to dojo.date.locale.parse
-		// summary: This function parse string date value according to options
-	
+
 		value =  value.replace(/[\u200E\u200F\u202A\u202E]/g, ""); //remove bidi non-printing chars
 
 		if(!options){ options={}; }
-		var info = dojox.date.islamic.locale._parseInfo(options);
+		var info = ilocale._parseInfo(options);
 
 		var tokens = info.tokens, bundle = info.bundle;
 		var regexp = info.regexp.replace(/[\u200E\u200F\u202A\u202E]/g, ""); //remove bidi non-printing chars from the pattern
@@ -182,10 +183,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date",
 
 		var locale = i18n.normalizeLocale(options.locale);
 
-		if(!match){
-			console.debug("dojox.date.islamic.locale.parse: value  "+value+" doesn't match pattern   " + re);
-			return null;
-		} // null
+		if(!match){ return null; } // null
 	
 		var date, date1;
 	
@@ -193,7 +191,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date",
 		var amPm = "";
 		var mLength = 0;
 		var widthList = ["abbr", "wide", "narrow"];
-		var valid = dojo.every(match, function(v, i){
+		var valid = arr.every(match, function(v, i){
 			if(!i){return true;}
 			var token=tokens[i-1];
 			var l=token.length;
@@ -208,9 +206,9 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date",
 							//Tolerate abbreviating period in month part
 							//Case-insensitive comparison
 							v = v.replace(".","").toLowerCase();
-							months = dojo.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
+							months = arr.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
 						}
-						v = dojo.indexOf(months, v);
+						v = arr.indexOf(months, v);
 						if(v == -1){
 							return false;
 						}
@@ -270,12 +268,13 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date",
 		}else if(amPm === 'a' && hours == 12){
 			result[3] = 0; //12am -> 0
 		}
-		var dateObject = new islamicDate(result[0], result[1], result[2], result[3], result[4], result[5], result[6]);
+		var dateObject = new IDate(result[0], result[1], result[2], result[3], result[4], result[5], result[6]);
 		return dateObject;
 	};
 
 	function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
-		//summary: Process a pattern with literals in it
+		// summary:
+		//		Process a pattern with literals in it
 
 		// Break up on single quotes, treat every other one as a literal, except '' which becomes '
 		var identity = function(x){return x;};
@@ -288,7 +287,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date",
 		var chunks = pattern.match(/(''|[^'])+/g);
 		var literal = pattern.charAt(0) == "'";
 
-		dojo.forEach(chunks, function(chunk, i){
+		arr.forEach(chunks, function(chunk, i){
 			if(!chunk){
 				chunks[i]='';
 			}else{
@@ -300,9 +299,8 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date",
 	}
 
 	function _buildDateTimeRE  (tokens, bundle, options, pattern){
-			// based on and similar to dojo.date.locale._buildDateTimeRE
-			//
-	
+		// based on and similar to dojo.date.locale._buildDateTimeRE
+
 		pattern = regexp.escapeString(pattern);
 		var locale = i18n.normalizeLocale(options.locale);
 	
@@ -371,29 +369,29 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date",
 	}
 
 	var _customFormats = [];
-	dojox.date.islamic.locale.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){
+	ilocale.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){
 		// summary:
 		//		Add a reference to a bundle containing localized custom formats to be
 		//		used by date/time formatting and parsing routines.
 		_customFormats.push({pkg:packageName,name:bundleName});
 	};
 
-	dojox.date.islamic.locale._getIslamicBundle = function(/*String*/locale){
+	ilocale._getIslamicBundle = function(/*String*/locale){
 		var islamic = {};
-		dojo.forEach(_customFormats, function(desc){
+		arr.forEach(_customFormats, function(desc){
 			var bundle = i18n.getLocalization(desc.pkg, desc.name, locale);
-			islamic = dojo.mixin(islamic, bundle);
+			islamic = lang.mixin(islamic, bundle);
 		}, this);
 		return islamic; /*Object*/
 	};
 
-	dojox.date.islamic.locale.addCustomFormats("dojo.cldr","islamic");
+	ilocale.addCustomFormats("dojo.cldr","islamic");
 
-	dojox.date.islamic.locale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*islamic Date Object?*/date){
+	ilocale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*dojox/date/islamic/Date?*/date){
 		// summary:
 		//		Used to get localized strings from dojo.cldr for day or month names.
 		var label;
-		var lookup = dojox.date.islamic.locale._getIslamicBundle(locale);
+		var lookup = ilocale._getIslamicBundle(locale);
 		var props = [item, context, type];
 		if(context == 'standAlone'){
 			var key = props.join('-');
@@ -408,9 +406,9 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/date",
 	};
 
 
-	dojox.date.islamic.locale.weekDays = dojox.date.islamic.locale.getNames('days', 'wide', 'format');
+	ilocale.weekDays = ilocale.getNames('days', 'wide', 'format');
 
-	dojox.date.islamic.locale.months = dojox.date.islamic.locale.getNames('months', 'wide', 'format');
+	ilocale.months = ilocale.getNames('months', 'wide', 'format');
 
-	return dojox.date.islamic.locale;
-});
\ No newline at end of file
+	return ilocale;
+});
diff --git a/dojox/date/persian.js b/dojox/date/persian.js
new file mode 100644
index 0000000..1e53562
--- /dev/null
+++ b/dojox/date/persian.js
@@ -0,0 +1,252 @@
+define("dojox/date/persian", ["..", "dojo/_base/lang", "dojo/date", "./persian/Date"], function(dojox, lang, dd, IDate){
+
+var dpersian = lang.getObject("date.persian", true, dojox);
+
+// Utility methods to do arithmetic calculations with persian.Dates
+
+	// added for compat to date
+dpersian.getDaysInMonth = function(/*dojox/date/persian/Date*/month){
+	return month.getDaysInPersianMonth(month.getMonth(), month.getFullYear());
+};
+
+//TODO: define persian.isLeapYear?  Or should it be invalid, since it has different meaning?
+
+dpersian.compare = function(/*dojox/date/persian/Date*/date1, /*dojox/date/persian/Date*/date2, /*String?*/portion){
+	// summary:
+	//		Compare two persian date objects by date, time, or both.
+	// description:
+	//		Returns 0 if equal, positive if a > b, else negative.
+	// date1: dojox/date/persian/Date
+	// date2: dojox/date/persian/Date
+	//		If not specified, the current persian.Date is used.
+	// portion:
+	//		A string indicating the "date" or "time" portion of a Date object.
+	//		Compares both "date" and "time" by default.  One of the following:
+	//		"date", "time", "datetime"
+
+	if(date1 instanceof IDate){
+		date1 = date1.toGregorian();
+	}
+	if(date2 instanceof IDate){
+		date2 = date2.toGregorian();
+	}
+	
+	return dd.compare.apply(null, arguments);
+};
+
+dpersian.add = function(/*dojox/date/persian/Date*/date, /*String*/interval, /*int*/amount){
+	// summary:
+	//		Add to a Date in intervals of different size, from milliseconds to years
+	// date: dojox/date/persian/Date
+	//		Date object to start with
+	// interval:
+	//		A string representing the interval.  One of the following:
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond", "week", "weekday"
+	// amount:
+	//		How much to add to the date.
+
+	//	based on and similar to dojo.date.add
+
+	var newPersianDate = new IDate(date);
+
+	switch(interval){
+		case "day":
+			newPersianDate.setDate(date.getDate() + amount);
+			break;
+		case "weekday":
+			var day = date.getDay();
+			if(((day + amount) < 5) && ((day + amount) > 0)){
+				 newPersianDate.setDate(date.getDate() + amount);
+			}else{
+				var adddays = 0, /*weekend */
+					remdays = 0;
+				if(day == 5){//friday
+					day = 4;
+					remdays = (amount > 0) ?  -1 : 1;
+				}else if(day == 6){ //shabat
+					day = 4;
+					remdays = (amount > 0) ? -2 : 2;
+				}
+				var add = (amount > 0) ? (5 - day - 1) : -day
+				var amountdif = amount - add;
+				var div = parseInt(amountdif / 5);
+				if(amountdif % 5 != 0){
+					adddays = (amount > 0)  ? 2 : -2;
+				}
+				adddays = adddays + div * 7 + amountdif % 5 + add;
+				newPersianDate.setDate(date.getDate() + adddays +  remdays);
+			}
+			break;
+		case "year":
+			newPersianDate.setFullYear(date.getFullYear() + amount);
+			break;
+		case "week":
+			amount *= 7;
+			newPersianDate.setDate(date.getDate() + amount);
+			break;
+		case "month":
+			var month = date.getMonth();
+			newPersianDate.setMonth(month + amount);
+			break;
+		case "hour":
+			newPersianDate.setHours(date.getHours() + amount);
+			break;
+		case "minute":
+			newPersianDate._addMinutes(amount);
+			break;
+		case "second":
+			newPersianDate._addSeconds(amount);
+			break;
+		case "millisecond":
+			newPersianDate._addMilliseconds(amount);
+			break;
+	}
+
+	return newPersianDate; // dojox.date.persian.Date
+};
+
+dpersian.difference = function(/*dojox/date/persian/Date*/date1, /*dojox/date/persian/Date?*/date2, /*String?*/interval){
+	// summary:
+	//		date2 - date1
+	// date1: dojox/date/persian/Date
+	// date2: dojox/date/persian/Date
+	//		If not specified, the current dojox.date.persian.Date is used.
+	// interval:
+	//		A string representing the interval.  One of the following:
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond",  "week", "weekday"
+	//
+	//		Defaults to "day".
+
+	//	based on and similar to dojo.date.difference
+
+	date2 = date2 || new IDate();
+	interval = interval || "day";
+	var yearDiff = date2.getFullYear() - date1.getFullYear();
+	var delta = 1; // Integer return value
+	switch(interval){
+		case "weekday":
+			var days = Math.round(dpersian.difference(date1, date2, "day"));
+			var weeks = parseInt(dpersian.difference(date1, date2, "week"));
+			var mod = days % 7;
+
+			// Even number of weeks
+			if(mod == 0){
+				days = weeks*5;
+			}else{
+				// Weeks plus spare change (< 7 days)
+				var adj = 0;
+				var aDay = date1.getDay();
+				var bDay = date2.getDay();
+	
+				weeks = parseInt(days/7);
+				mod = days % 7;
+				// Mark the date advanced by the number of
+				// round weeks (may be zero)
+				var dtMark = new IDate(date1);
+				dtMark.setDate(dtMark.getDate()+(weeks*7));
+				var dayMark = dtMark.getDay();
+	
+				// Spare change days -- 6 or less
+				if(days > 0){
+					switch(true){
+						// Range starts on Fri
+						case aDay == 5:
+							adj = -1;
+							break;
+						// Range starts on Sat
+						case aDay == 6:
+							adj = 0;
+							break;
+						// Range ends on Fri
+						case bDay == 5:
+							adj = -1;
+							break;
+						// Range ends on Sat
+						case bDay == 6:
+							adj = -2;
+							break;
+						// Range contains weekend
+						case (dayMark + mod) > 5:
+							adj = -2;
+					}
+				}else if(days < 0){
+					switch(true){
+						// Range starts on Fri
+						case aDay == 5:
+							adj = 0;
+							break;
+						// Range starts on Sat
+						case aDay == 6:
+							adj = 1;
+							break;
+						// Range ends on Fri
+						case bDay == 5:
+							adj = 2;
+							break;
+						// Range ends on Sat
+						case bDay == 6:
+							adj = 1;
+							break;
+						// Range contains weekend
+						case (dayMark + mod) < 0:
+							adj = 2;
+					}
+				}
+				days += adj;
+				days -= (weeks*2);
+			}
+			delta = days;
+			break;
+		case "year":
+			delta = yearDiff;
+			break;
+		case "month":
+			var startdate =  (date2.toGregorian() > date1.toGregorian()) ? date2 : date1; // more
+			var enddate = (date2.toGregorian() > date1.toGregorian()) ? date1 : date2;
+			
+			var month1 = startdate.getMonth();
+			var month2 = enddate.getMonth();
+			
+			if (yearDiff == 0){
+				delta = startdate.getMonth() - enddate.getMonth() ;
+			}else{
+				delta = 12-month2;
+				delta +=  month1;
+				var i = enddate.getFullYear()+1;
+				var e = startdate.getFullYear();
+				for (i;   i < e;  i++){
+					delta += 12;
+				}
+			}
+			if (date2.toGregorian() < date1.toGregorian()){
+				delta = -delta;
+			}
+			break;
+		case "week":
+			// Truncate instead of rounding
+			// Don't use Math.floor -- value may be negative
+			delta = parseInt(dpersian.difference(date1, date2, "day")/7);
+			break;
+		case "day":
+			delta /= 24;
+			// fallthrough
+		case "hour":
+			delta /= 60;
+			// fallthrough
+		case "minute":
+			delta /= 60;
+			// fallthrough
+		case "second":
+			delta /= 1000;
+			// fallthrough
+		case "millisecond":
+			delta *= date2.toGregorian().getTime()- date1.toGregorian().getTime();
+	}
+
+	// Round for fractional values and DST leaps
+	return Math.round(delta); // Number (integer)
+};
+return dpersian;
+});
diff --git a/dojox/date/persian/Date.js b/dojox/date/persian/Date.js
new file mode 100644
index 0000000..9014a79
--- /dev/null
+++ b/dojox/date/persian/Date.js
@@ -0,0 +1,458 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/date"], function(lang, declare, dd){
+
+	var IDate = declare("dojox.date.persian.Date", null, {
+	// summary:
+	//		The component defines the Persian (Hijri) Calendar Object
+	// description:
+	//		This module is similar to the Date() object provided by JavaScript
+	// example:
+	//	|	var date = new dojox.date.persian.Date();
+	//	|	document.writeln(date.getFullYear()+'\'+date.getMonth()+'\'+date.getDate());
+
+
+	_date: 0,
+	_month: 0,
+	_year: 0,
+	_hours: 0,
+	_minutes: 0,
+	_seconds: 0,
+	_milliseconds: 0,
+	_day: 0,
+	_GREGORIAN_EPOCH : 1721425.5,
+	_PERSIAN_EPOCH : 1948320.5,
+	daysInMonth:[31,31,31,31,31,31,30,30,30,30,30,29 ],
+	constructor: function(){
+		// summary:
+		//		This is the constructor
+		// description:
+		//		This function initialize the date object values
+		// example:
+		//	|	var date1 = new dojox.date.persian.Date();
+		//	|	var date2 = new dojox.date.persian.Date("12\2\1429");
+		//	|	var date3 = new dojox.date.persian.Date(date2);
+		//	|	var date4 = new dojox.date.persian.Date(1429,2,12);
+
+		var len = arguments.length;
+		if(!len){// use the current date value, added "" to the similarity to date
+			this.fromGregorian(new Date());
+		}else if(len == 1){
+			var arg0 = arguments[0];
+			if(typeof arg0 == "number"){ // this is time "valueof"
+				arg0 = new Date(arg0);
+			}
+
+			if(arg0 instanceof Date){
+				this.fromGregorian(arg0);
+			}else if(arg0 == ""){
+				// date should be invalid.  Dijit relies on this behavior.
+				this._date = new Date(""); //TODO: should this be NaN?  _date is not a Date object
+			}else{  // this is Persian.Date object
+				this._year = arg0._year;
+				this._month =  arg0._month;
+				this._date = arg0._date;
+				this._hours = arg0._hours;
+				this._minutes = arg0._minutes;
+				this._seconds = arg0._seconds;
+				this._milliseconds = arg0._milliseconds;
+			}
+		}else if(len >=3){
+			// YYYY MM DD arguments passed, month is from 0-12
+			this._year += arguments[0];
+			this._month += arguments[1];
+			this._date += arguments[2];
+			this._hours += arguments[3] || 0;
+			this._minutes += arguments[4] || 0;
+			this._seconds += arguments[5] || 0;
+			this._milliseconds += arguments[6] || 0;
+		}
+	},
+
+	getDate:function(){
+		// summary:
+		//		This function returns the date value (1 - 30)
+		// example:
+		//	|	var date1 = new dojox.date.persian.Date();
+		//	|	document.writeln(date1.getDate);
+		return this._date;
+	},
+	
+	getMonth:function(){
+		// summary:
+		//		This function return the month value ( 0 - 11 )
+		// example:
+		//	|	var date1 = new dojox.date.persian.Date();
+		//	|	document.writeln(date1.getMonth()+1);
+
+		return this._month;
+	},
+
+	getFullYear:function(){
+		// summary:
+		//		This function return the Year value
+		// example:
+		//	|	var date1 = new dojox.date.persian.Date();
+		//	|	document.writeln(date1.getFullYear());
+
+		return this._year;
+	},
+		
+	getDay:function(){
+		// summary:
+		//		This function return Week Day value ( 0 - 6 )
+		// example:
+		//	|	var date1 = new dojox.date.persian.Date();
+		//	|	document.writeln(date1.getDay());
+
+		return this.toGregorian().getDay();
+	},
+		
+	getHours:function(){
+		// summary:
+		//		returns the Hour value
+		return this._hours;
+	},
+	
+	getMinutes:function(){
+		// summary:
+		//		returns the Minutes value
+		return this._minutes;
+	},
+
+	getSeconds:function(){
+		// summary:
+		//		returns the seconds value
+		return this._seconds;
+	},
+
+	getMilliseconds:function(){
+		// summary:
+		//		returns the Milliseconds value
+		return this._milliseconds;
+	},
+
+	setDate: function(/*number*/date){
+		// summary:
+		//		This function sets the Date
+		// example:
+		//	|	var date1 = new dojox.date.persian.Date();
+		//	|	date1.setDate(2);
+
+		date = parseInt(date);
+
+		if(date > 0 && date <= this.getDaysInPersianMonth(this._month, this._year)){
+			this._date = date;
+		}else{
+			var mdays;
+			if(date>0){
+				for(mdays = this.getDaysInPersianMonth(this._month, this._year);
+					date > mdays;
+						date -= mdays,mdays =this.getDaysInPersianMonth(this._month, this._year)){
+					this._month++;
+					if(this._month >= 12){this._year++; this._month -= 12;}
+				}
+
+				this._date = date;
+			}else{
+				for(mdays = this.getDaysInPersianMonth((this._month-1)>=0 ?(this._month-1) :11 ,((this._month-1)>=0)? this._year: this._year-1);
+						date <= 0;
+							mdays = this.getDaysInPersianMonth((this._month-1)>=0 ? (this._month-1) :11,((this._month-1)>=0)? this._year: this._year-1)){
+					this._month--;
+					if(this._month < 0){this._year--; this._month += 12;}
+
+					date+=mdays;
+				}
+				this._date = date;
+			}
+		}
+		return this;
+	},
+
+	setFullYear:function(/*number*/year){
+		// summary:
+		//		This function set Year
+		// example:
+		//	|	var date1 = new dojox.date.persian.Date();
+		//	|	date1.setYear(1429);
+
+		this._year = +year;
+	},
+
+	setMonth: function(/*number*/month) {
+		// summary:
+		//		This function set Month
+		// example:
+		//	|	var date1 = new dojox.date.persian.Date();
+		//	|	date1.setMonth(2);
+
+		this._year += Math.floor(month / 12);
+		if(month > 0){
+			this._month = Math.floor(month % 12);
+		}else{
+			this._month = Math.floor(((month % 12) + 12) % 12);
+		}
+	},
+
+	setHours:function(){
+		// summary:
+		//		set the Hours
+		var hours_arg_no = arguments.length;
+		var hours = 0;
+		if(hours_arg_no >= 1){
+			hours = parseInt(arguments[0]);
+		}
+
+		if(hours_arg_no >= 2){
+			this._minutes = parseInt(arguments[1]);
+		}
+
+		if(hours_arg_no >= 3){
+			this._seconds = parseInt(arguments[2]);
+		}
+
+		if(hours_arg_no == 4){
+			this._milliseconds = parseInt(arguments[3]);
+		}
+
+		while(hours >= 24){
+			this._date++;
+			var mdays = this.getDaysInPersianMonth(this._month, this._year);
+			if(this._date > mdays){
+					this._month ++;
+					if(this._month >= 12){this._year++; this._month -= 12;}
+					this._date -= mdays;
+			}
+			hours -= 24;
+		}
+		this._hours = hours;
+	},
+
+	_addMinutes: function(/*Number*/minutes){
+		minutes += this._minutes;
+		this.setMinutes(minutes);
+		this.setHours(this._hours + parseInt(minutes / 60));
+		return this;
+	},
+
+	_addSeconds: function(/*Number*/seconds){
+		seconds += this._seconds;
+		this.setSeconds(seconds);
+		this._addMinutes(parseInt(seconds / 60));
+		return this;
+	},
+
+	_addMilliseconds: function(/*Number*/milliseconds){
+		milliseconds += this._milliseconds;
+		this.setMilliseconds(milliseconds);
+		this._addSeconds(parseInt(milliseconds / 1000));
+		return this;
+	},
+
+	setMinutes: function(/*Number*/minutes){
+		// summary:
+		//		sets the minutes (0-59) only.
+		this._minutes = minutes % 60;
+		return this;
+	},
+
+	setSeconds: function(/*Number*/seconds){
+		// summary:
+		//		sets the seconds (0-59) only.
+		this._seconds = seconds % 60;
+		return this;
+	},
+
+	setMilliseconds: function(/*Number*/milliseconds){
+		this._milliseconds = milliseconds % 1000;
+		return this;
+	},
+		
+	toString:function(){
+		// summary:
+		//		This returns a string representation of the date in "DDDD MMMM DD YYYY HH:MM:SS" format
+		// example:
+		//	|	var date1 = new dojox.date.persian.Date();
+		//	|	document.writeln(date1.toString());
+
+		//FIXME: TZ/DST issues?
+		if(isNaN(this._date)){
+			return "Invalidate Date";
+		}else{
+			var x = new Date();
+			x.setHours(this._hours);
+			x.setMinutes(this._minutes);
+			x.setSeconds(this._seconds);
+			x.setMilliseconds(this._milliseconds);
+			return this._month+" "+ this._date + " " + this._year + " " + x.toTimeString();
+		}
+	},
+		
+		
+	toGregorian:function(){
+		// summary:
+		//		This returns the equevalent Grogorian date value in Date object
+		// example:
+		//	|	var datePersian = new dojox.date.persian.Date(1429,11,20);
+		//	|	var dateGregorian = datePersian.toGregorian();
+
+		var hYear = this._year;
+		var date,j;
+		j = this.persian_to_jd(this._year,this._month+1,this._date);
+		date = this.jd_to_gregorian(j,this._month+1);
+		weekday = this.jwday(j);
+		var _21=new Date(date[0],date[1]-1,date[2],this._hours,this._minutes,this._seconds,this._milliseconds);
+		return _21;
+	},
+
+	
+	// ported from the Java class com.ibm.icu.util.PersianCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
+	fromGregorian:function(/*Date*/gdate){
+		// summary:
+		//		This function returns the equivalent Persian Date value for the Gregorian Date
+		// example:
+		//	|	var datePersian = new dojox.date.persian.Date();
+		//	|	var dateGregorian = new Date(2008,10,12);
+		//	|	datePersian.fromGregorian(dateGregorian);
+
+		var _23=new Date(gdate);
+		var _24=_23.getFullYear(),_25=_23.getMonth(),_26=_23.getDate();
+		var persian = this.calcGregorian(_24,_25,_26);
+		this._date=persian[2];
+		this._month=persian[1];
+		this._year=persian[0];
+		this._hours=_23.getHours();
+		this._minutes=_23.getMinutes();
+		this._seconds=_23.getSeconds();
+		this._milliseconds=_23.getMilliseconds();
+		this._day=_23.getDay();
+		return this;
+	},
+//  calcGregorian  --  Perform calculation starting with a Gregorian date
+	calcGregorian:function (year,month,day){
+	var j, weekday;
+		    //  Update Julian day
+		j = this.gregorian_to_jd(year, month + 1, day) +(Math.floor(0 + 60 * (0 + 60 * 0) + 0.5) / 86400.0);
+		    //  Update Persian Calendar
+		perscal = this.jd_to_persian(j);
+		weekday = this.jwday(j);
+		return new Array(perscal[0], perscal[1], perscal[2],weekday);
+		},
+	//  JD_TO_PERSIAN  --  Calculate Persian date from Julian day
+		jd_to_persian: function (jd){
+		var year, month, day, depoch, cycle, cyear, ycycle, aux1, aux2, yday;
+		jd = Math.floor(jd) + 0.5;
+		depoch = jd - this.persian_to_jd(475, 1, 1);
+		cycle = Math.floor(depoch / 1029983);
+		cyear = this._mod(depoch, 1029983);
+		if (cyear == 1029982) {
+		   ycycle = 2820;
+		} else {
+		   aux1 = Math.floor(cyear / 366);
+		   aux2 = this._mod(cyear, 366);
+		   ycycle = Math.floor(((2134 * aux1) + (2816 * aux2) + 2815) / 1028522) + aux1 + 1;
+		}
+		year = ycycle + (2820 * cycle) + 474;
+		if (year <= 0) {
+		year--;
+		}
+		yday = (jd - this.persian_to_jd(year, 1, 1)) + 1;
+		month = (yday <= 186) ? Math.ceil(yday / 31) : Math.ceil((yday - 6) / 30);
+		day = (jd - this.persian_to_jd(year, month, 1)) + 1;
+
+		return new Array(year, month-1, day);
+		},
+		// PERSIAN_TO_JD  --  Determine Julian day from Persian date
+		persian_to_jd: function (year, month, day){
+		var epbase, epyear;
+		epbase = year - ((year >= 0) ? 474 : 473);
+		epyear = 474 + this._mod(epbase, 2820);
+		return day +((month <= 7) ?((month - 1) * 31) :(((month - 1) * 30) + 6)) + Math.floor(((epyear * 682) - 110) / 2816) +(epyear - 1) * 365 + Math.floor(epbase / 2820) * 1029983 +(this._PERSIAN_EPOCH - 1);
+		},
+	//  GREGORIAN_TO_JD  --  Determine Julian day number from Gregorian calendar date
+		gregorian_to_jd: function (year, month, day){
+		    return (this._GREGORIAN_EPOCH - 1) + (365 * (year - 1)) + Math.floor((year - 1) / 4) +(-Math.floor((year - 1) / 100)) + Math.floor((year - 1) / 400) + Math.floor((((367 * month) - 362) / 12) +
+		           ((month <= 2) ? 0 :(this.leap_gregorian(year) ? -1 : -2)) +day);
+		},
+		
+	//  JD_TO_GREGORIAN  --  Calculate Gregorian calendar date from Julian day
+		jd_to_gregorian : function (jd,jmonth) {
+		var wjd, depoch, quadricent, dqc, cent, dcent, quad, dquad, yindex, dyindex, year, yearday, leapadj;
+		wjd = Math.floor(jd - 0.5) + 0.5;
+		depoch = wjd - this._GREGORIAN_EPOCH;
+		quadricent = Math.floor(depoch / 146097);
+		dqc = this._mod(depoch, 146097);
+		cent = Math.floor(dqc / 36524);
+		dcent = this._mod(dqc, 36524);
+		quad = Math.floor(dcent / 1461);
+		dquad = this._mod(dcent, 1461);
+		yindex = Math.floor(dquad / 365);
+		year = (quadricent * 400) + (cent * 100) + (quad * 4) + yindex;
+		if (!((cent == 4) || (yindex == 4))) {
+		    year++;
+		}
+		yearday = wjd - this.gregorian_to_jd(year, 1, 1);
+		leapadj = ((wjd < this.gregorian_to_jd(year, 3, 1)) ? 0:(this.leap_gregorian(year) ? 1 : 2));
+		month = Math.floor((((yearday + leapadj) * 12) + 373) / 367);
+		day = (wjd - this.gregorian_to_jd(year, month, 1)) + 1;
+		return new Array(year, month, day);
+		},	valueOf:function(){
+		// summary:
+		//		This function returns The stored time value in milliseconds
+		//		since midnight, January 1, 1970 UTC
+
+		return this.toGregorian().valueOf();
+	},jwday: function (j)
+	{
+		 return this._mod(Math.floor((j + 1.5)), 7);
+		},
+
+	// ported from the Java class com.ibm.icu.util.PersianCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
+	_yearStart:function(/*Number*/year){
+		// summary:
+		//		return start of Persian year
+		return (year-1)*354 + Math.floor((3+11*year)/30.0);
+	},
+
+	// ported from the Java class com.ibm.icu.util.PersianCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
+	_monthStart:function(/*Number*/year, /*Number*/month){
+		// summary:
+		//		return the start of Persian Month
+		return Math.ceil(29.5*month) +
+			(year-1)*354 + Math.floor((3+11*year)/30.0);
+	},
+//  LEAP_GREGORIAN  --  Is a given year in the Gregorian calendar a leap year ?
+	leap_gregorian: function (year)
+	{
+	    return ((year % 4) == 0) &&
+	            (!(((year % 100) == 0) && ((year % 400) != 0)));
+	},
+
+//  LEAP_PERSIAN  --  Is a given year a leap year in the Persian calendar ?
+	isLeapYear:function(j_y,j_m,j_d){
+		// summary:
+		//		return Boolean value if Persian leap year
+		return !(j_y < 0 || j_y > 32767 || j_m < 1 || j_m > 12 || j_d < 1 || j_d >(this.daysInMonth[j_m-1] + (j_m == 12 && !((j_y-979)%33%4))));
+
+	},
+
+	// ported from the Java class com.ibm.icu.util.PersianCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
+	getDaysInPersianMonth:function(/*Number*/month, /*Number*/ year){
+		// summary:
+		//		returns the number of days in the given Persian Month
+		var days=this.daysInMonth[month];
+		if(month==11 && this.isLeapYear(year,month+1,30)){
+			days++;
+		}
+		return days;
+	},
+
+	_mod:function(a, b){
+		return a - (b * Math.floor(a / b));
+	}
+});
+
+
+IDate.getDaysInPersianMonth = function(/*dojox/date/persian.Date*/month){
+	return new IDate().getDaysInPersianMonth(month.getMonth(),month.getFullYear()); // dojox.date.persian.Date
+};
+return IDate;
+});
diff --git a/dojox/date/persian/locale.js b/dojox/date/persian/locale.js
new file mode 100644
index 0000000..e7c996c
--- /dev/null
+++ b/dojox/date/persian/locale.js
@@ -0,0 +1,414 @@
+define(["../..", "dojo/_base/lang", "dojo/_base/array", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./Date", "dojo/i18n!dojo/cldr/nls/persian"],
+       function(dojox, lang, arr, dd, i18n, regexp, string, IDate, bundle){
+
+	var ilocale = lang.getObject("date.persian.locale", true, dojox);
+
+	//	dojo.requireLocalization("dojo.cldr", "persian");
+
+	// Format a pattern without literals
+	function formatPattern(dateObject, bundle, locale, fullYear,  pattern){
+
+		return pattern.replace(/([a-z])\1*/ig, function(match){
+			var s, pad;
+			var c = match.charAt(0);
+			var l = match.length;
+			var widthList = ["abbr", "wide", "narrow"];
+			
+			switch(c){
+				case 'G':
+					s = bundle["eraAbbr"][0];
+					break;
+				case 'y':
+					s = String(dateObject.getFullYear());
+					break;
+				case 'M':
+					var m = dateObject.getMonth();
+					if(l<3){
+						s = m+1; pad = true;
+					}else{
+						var propM = ["months", "format", widthList[l-3]].join("-");
+						s = bundle[propM][m];
+					}
+					break;
+				case 'd':
+					s = dateObject.getDate(true); pad = true;
+					break;
+				case 'E':
+					var d = dateObject.getDay();
+					if(l<3){
+						s = d+1; pad = true;
+					}else{
+						var propD = ["days", "format", widthList[l-3]].join("-");
+						s = bundle[propD][d];
+					}
+					break;
+				case 'a':
+					var timePeriod = (dateObject.getHours() < 12) ? 'am' : 'pm';
+					s = bundle['dayPeriods-format-wide-' + timePeriod];
+					break;
+				case 'h':
+				case 'H':
+				case 'K':
+				case 'k':
+					var h = dateObject.getHours();
+					switch (c){
+						case 'h': // 1-12
+							s = (h % 12) || 12;
+							break;
+						case 'H': // 0-23
+							s = h;
+							break;
+						case 'K': // 0-11
+							s = (h % 12);
+							break;
+						case 'k': // 1-24
+							s = h || 24;
+							break;
+					}
+					pad = true;
+					break;
+				case 'm':
+					s = dateObject.getMinutes(); pad = true;
+					break;
+				case 's':
+					s = dateObject.getSeconds(); pad = true;
+					break;
+				case 'S':
+					s = Math.round(dateObject.getMilliseconds() * Math.pow(10, l-3)); pad = true;
+					break;
+				case 'z':
+					// We only have one timezone to offer; the one from the browser
+					s = dd.getTimezoneName(dateObject.toGregorian());
+					if(s){ break; }
+					l = 4;
+					// fallthrough... use GMT if tz not available
+				case 'Z':
+					var offset = dateObject.toGregorian().getTimezoneOffset();
+					var tz = [
+						(offset <= 0 ? "+" : "-"),
+						string.pad(Math.floor(Math.abs(offset) / 60), 2),
+						string.pad(Math.abs(offset) % 60, 2)
+					];
+					if(l == 4){
+						tz.splice(0, 0, "GMT");
+						tz.splice(3, 0, ":");
+					}
+					s = tz.join("");
+					break;
+				default:
+					throw new Error("dojox.date.persian.locale.formatPattern: invalid pattern char: "+pattern);
+			}
+			if(pad){ s = string.pad(s, l); }
+			return s;
+		});
+	}
+	
+	// based on and similar to dojo.date.locale.format
+	ilocale.format = function(/*dojox/date/persian/Date*/dateObject, /*Object?*/options){
+		// summary:
+		//		Format a Date object as a String, using  settings.
+		options = options || {};
+
+		var locale = i18n.normalizeLocale(options.locale);
+		var formatLength = options.formatLength || 'short';
+		var bundle = ilocale._getPersianBundle(locale);
+		var str = [];
+
+		var sauce = lang.hitch(this, formatPattern, dateObject, bundle, locale, options.fullYear);
+		if(options.selector == "year"){
+			var year = dateObject.getFullYear();
+			return year;
+		}
+		if(options.selector != "time"){
+			var datePattern = options.datePattern || bundle["dateFormat-"+formatLength];
+			if(datePattern){str.push(_processPattern(datePattern, sauce));}
+		}
+		if(options.selector != "date"){
+			var timePattern = options.timePattern || bundle["timeFormat-"+formatLength];
+			if(timePattern){str.push(_processPattern(timePattern, sauce));}
+		}
+		var result = str.join(" "); //TODO: use locale-specific pattern to assemble date + time
+
+		return result; // String
+	};
+
+	ilocale.regexp = function(/*object?*/options){
+		// summary:
+		//		Builds the regular needed to parse a persian.Date
+
+		//	based on and similar to dojo.date.locale.regexp
+
+		return ilocale._parseInfo(options).regexp; // String
+	};
+
+	ilocale._parseInfo = function(/*oblect?*/options){
+	/* based on and similar to dojo.date.locale._parseInfo */
+
+		options = options || {};
+		var locale = i18n.normalizeLocale(options.locale);
+		var bundle = ilocale._getPersianBundle(locale);
+		var formatLength = options.formatLength || 'short';
+		var datePattern = options.datePattern || bundle["dateFormat-" + formatLength];
+		var timePattern = options.timePattern || bundle["timeFormat-" + formatLength];
+
+		var pattern;
+		if(options.selector == 'date'){
+			pattern = datePattern;
+		}else if(options.selector == 'time'){
+			pattern = timePattern;
+		}else{
+			pattern = (typeof (timePattern) == "undefined") ? datePattern : datePattern + ' ' + timePattern;
+		}
+
+		var tokens = [];
+	
+		var re = _processPattern(pattern, lang.hitch(this, _buildDateTimeRE, tokens, bundle, options));
+		return {regexp: re, tokens: tokens, bundle: bundle};
+	};
+
+	ilocale.parse = function(/*String*/value, /*Object?*/options){
+		// summary:
+		//		This function parse string date value according to options
+
+		// based on and similar to dojo.date.locale.parse
+
+		value =  value.replace(/[\u200E\u200F\u202A\u202E]/g, ""); //remove bidi non-printing chars
+
+		if(!options){ options={}; }
+		var info = ilocale._parseInfo(options);
+
+		var tokens = info.tokens, bundle = info.bundle;
+		var regexp = info.regexp.replace(/[\u200E\u200F\u202A\u202E]/g, ""); //remove bidi non-printing chars from the pattern
+		var re = new RegExp("^" + regexp + "$");
+
+		var match = re.exec(value);
+
+		var locale = i18n.normalizeLocale(options.locale);
+
+		if(!match){ return null; } // null
+	
+		var date, date1;
+	
+		var result = [1389,0,1,0,0,0,0];  //FIXME: persian date for [1970,0,1,0,0,0,0] used in gregorian locale
+		var amPm = "";
+		var mLength = 0;
+		var widthList = ["abbr", "wide", "narrow"];
+		var valid = arr.every(match, function(v, i){
+			if(!i){return true;}
+			var token=tokens[i-1];
+			var l=token.length;
+			switch(token.charAt(0)){
+				case 'y':
+					result[0] = Number(v);
+					break;
+				case 'M':
+					if(l>2){
+						var months = bundle['months-format-' + widthList[l-3]].concat();
+						if(!options.strict){
+							//Tolerate abbreviating period in month part
+							//Case-insensitive comparison
+							v = v.replace(".","").toLowerCase();
+							months = arr.map(months, function(s){ return s ? s.replace(".","").toLowerCase() : s; } );
+						}
+						v = arr.indexOf(months, v);
+						if(v == -1){
+							return false;
+						}
+						mLength = l;
+					}else{
+						v--;
+					}
+					result[1] = Number(v);
+					break;
+				case 'D':
+					result[1] = 0;
+					// fallthrough...
+				case 'd':
+						result[2] =  Number(v);
+					break;
+				case 'a': //am/pm
+					var am = options.am || bundle['dayPeriods-format-wide-am'],
+						pm = options.pm || bundle['dayPeriods-format-wide-pm'];
+					if(!options.strict){
+						var period = /\./g;
+						v = v.replace(period,'').toLowerCase();
+						am = am.replace(period,'').toLowerCase();
+						pm = pm.replace(period,'').toLowerCase();
+					}
+					if(options.strict && v != am && v != pm){
+						return false;
+					}
+
+					// we might not have seen the hours field yet, so store the state and apply hour change later
+					amPm = (v == pm) ? 'p' : (v == am) ? 'a' : '';
+					break;
+				case 'K': //hour (1-24)
+					if(v == 24){ v = 0; }
+					// fallthrough...
+				case 'h': //hour (1-12)
+				case 'H': //hour (0-23)
+				case 'k': //hour (0-11)
+					//in the 12-hour case, adjusting for am/pm requires the 'a' part
+					//which could come before or after the hour, so we will adjust later
+					result[3] = Number(v);
+					break;
+				case 'm': //minutes
+					result[4] = Number(v);
+					break;
+				case 's': //seconds
+					result[5] = Number(v);
+					break;
+				case 'S': //milliseconds
+					result[6] = Number(v);
+			}
+			return true;
+		});
+
+		var hours = +result[3];
+		if(amPm === 'p' && hours < 12){
+			result[3] = hours + 12; //e.g., 3pm -> 15
+		}else if(amPm === 'a' && hours == 12){
+			result[3] = 0; //12am -> 0
+		}
+		var dateObject = new IDate(result[0], result[1], result[2], result[3], result[4], result[5], result[6]);
+		return dateObject;
+	};
+
+	function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
+		// summary:
+		//		Process a pattern with literals in it
+
+		// Break up on single quotes, treat every other one as a literal, except '' which becomes '
+		var identity = function(x){return x;};
+		applyPattern = applyPattern || identity;
+		applyLiteral = applyLiteral || identity;
+		applyAll = applyAll || identity;
+
+		//split on single quotes (which escape literals in date format strings)
+		//but preserve escaped single quotes (e.g., o''clock)
+		var chunks = pattern.match(/(''|[^'])+/g);
+		var literal = pattern.charAt(0) == "'";
+
+		arr.forEach(chunks, function(chunk, i){
+			if(!chunk){
+				chunks[i]='';
+			}else{
+				chunks[i]=(literal ? applyLiteral : applyPattern)(chunk);
+				literal = !literal;
+			}
+		});
+		return applyAll(chunks.join(''));
+	}
+
+	function _buildDateTimeRE  (tokens, bundle, options, pattern){
+		// based on and similar to dojo.date.locale._buildDateTimeRE
+
+		pattern = regexp.escapeString(pattern);
+		var locale = i18n.normalizeLocale(options.locale);
+	
+		return pattern.replace(/([a-z])\1*/ig, function(match){
+
+				// Build a simple regexp.  Avoid captures, which would ruin the tokens list
+				var s;
+				var c = match.charAt(0);
+				var l = match.length;
+				var p2 = '', p3 = '';
+				if(options.strict){
+					if(l > 1){ p2 = '0' + '{'+(l-1)+'}'; }
+					if(l > 2){ p3 = '0' + '{'+(l-2)+'}'; }
+				}else{
+					p2 = '0?'; p3 = '0{0,2}';
+				}
+				switch(c){
+					case 'y':
+						s = '\\d+';
+						break;
+					case 'M':
+						s = (l>2) ?  '\\S+ ?\\S+' : p2+'[1-9]|1[0-2]';
+						break;
+					case 'd':
+						s = '[12]\\d|'+p2+'[1-9]|3[01]';
+						break;
+					case 'E':
+						s = '\\S+';
+						break;
+					case 'h': //hour (1-12)
+						s = p2+'[1-9]|1[0-2]';
+						break;
+					case 'k': //hour (0-11)
+						s = p2+'\\d|1[01]';
+						break;
+					case 'H': //hour (0-23)
+						s = p2+'\\d|1\\d|2[0-3]';
+						break;
+					case 'K': //hour (1-24)
+						s = p2+'[1-9]|1\\d|2[0-4]';
+						break;
+					case 'm':
+					case 's':
+						s = p2+'\\d|[0-5]\\d';
+						break;
+					case 'S':
+						s = '\\d{'+l+'}';
+						break;
+					case 'a':
+						var am = options.am || bundle['dayPeriods-format-wide-am'],
+							pm = options.pm || bundle['dayPeriods-format-wide-pm'];
+						if(options.strict){
+							s = am + '|' + pm;
+						}else{
+							s = am + '|' + pm;
+							if(am != am.toLowerCase()){ s += '|' + am.toLowerCase(); }
+							if(pm != pm.toLowerCase()){ s += '|' + pm.toLowerCase(); }
+						}
+						break;
+					default:
+						s = ".*";
+				}
+				if(tokens){ tokens.push(match); }
+				return "(" + s + ")"; // add capture
+			}).replace(/[\xa0 ]/g, "[\\s\\xa0]"); // normalize whitespace.  Need explicit handling of \xa0 for IE. */
+	}
+
+	var _customFormats = [];
+	ilocale.addCustomFormats = function(/*String*/packageName, /*String*/bundleName){
+		// summary:
+		//		Add a reference to a bundle containing localized custom formats to be
+		//		used by date/time formatting and parsing routines.
+		_customFormats.push({pkg:packageName,name:bundleName});
+	};
+
+	ilocale._getPersianBundle = function(/*String*/locale){
+		var persian = {};
+		arr.forEach(_customFormats, function(desc){
+			var bundle = i18n.getLocalization(desc.pkg, desc.name, locale);
+			persian = lang.mixin(persian, bundle);
+		}, this);
+		return persian; /*Object*/
+	};
+
+	ilocale.addCustomFormats("dojo.cldr","persian");
+
+	ilocale.getNames = function(/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*dojox/date/persian/Date?*/date){
+		// summary:
+		//		Used to get localized strings from dojo.cldr for day or month names.
+		var label;
+		var lookup = ilocale._getPersianBundle(locale);
+		var props = [item, context, type];
+		if(context == 'standAlone'){
+			var key = props.join('-');
+			label = lookup[key];
+			// Fall back to 'format' flavor of name
+			if(label[0] == 1){ label = undefined; } // kludge, in the absence of real aliasing support in dojo.cldr
+		}
+		props[1] = 'format';
+	
+		// return by copy so changes won't be made accidentally to the in-memory model
+		return (label || lookup[props.join('-')]).concat(); /*Array*/
+	};
+	ilocale.weekDays = ilocale.getNames('days', 'wide', 'format');
+
+	ilocale.months = ilocale.getNames('months', 'wide', 'format');
+
+	return ilocale;
+});
diff --git a/dojox/date/php.js b/dojox/date/php.js
index fb22a80..ed8bea4 100644
--- a/dojox/date/php.js
+++ b/dojox/date/php.js
@@ -1,14 +1,22 @@
 define(["dojo/_base/kernel", "dojo/_base/lang","dojo/date","dojox/string/tokenize"], function(dojo,dlang,ddate,dxst){
-dojo.getObject("date.php", true, dojox);
 
-dojox.date.php.format = function(/*Date*/ date, /*String*/ format){
-	// summary: Get a formatted string for a given date object
-	var df = new dojox.date.php.DateFormat(format);
+var php = dojo.getObject("date.php", true, dojox);
+/*=====
+var php = {
+	// TODO: summary
+};
+=====*/
+
+php.format = function(/*Date*/ date, /*String*/ format){
+	// summary:
+	//		Get a formatted string for a given date object
+	var df = new php.DateFormat(format);
 	return df.format(date);
-}
+};
 
-dojox.date.php.DateFormat = function(/*String*/ format){
-	// summary: Format the internal date object
+php.DateFormat = function(/*String*/ format){
+	// summary:
+	//		Format the internal date object
 	if(!this.regex){
 		var keys = [];
 		for(var key in this.constructor.prototype){
@@ -32,8 +40,9 @@ dojox.date.php.DateFormat = function(/*String*/ format){
 	});
 
 	this.replacements = replacements;
-}
-dojo.extend(dojox.date.php.DateFormat, {
+};
+
+dojo.extend(php.DateFormat, {
 	weekdays: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
 	weekdays_3: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
 	months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
@@ -51,34 +60,40 @@ dojo.extend(dojox.date.php.DateFormat, {
 	// Day
 
 	d: function(){
-		// summary: Day of the month, 2 digits with leading zeros
+		// summary:
+		//		Day of the month, 2 digits with leading zeros
 		var j = this.j();
 		return (j.length == 1) ? "0" + j : j;
 	},
 
 	D: function(){
-		// summary: A textual representation of a day, three letters
+		// summary:
+		//		A textual representation of a day, three letters
 		return this.weekdays_3[this.date.getDay()];
 	},
 
 	j: function(){
-		// summary: Day of the month without leading zeros
+		// summary:
+		//		Day of the month without leading zeros
 		return this.date.getDate() + "";
 	},
 
 	l: function(){
-		// summary: A full textual representation of the day of the week
+		// summary:
+		//		A full textual representation of the day of the week
 		return this.weekdays[this.date.getDay()];
 	},
-	
+
 	N: function(){
-		// summary: ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0)
+		// summary:
+		//		ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0)
 		var w = this.w();
 		return (!w) ? 7 : w;
 	},
 
 	S: function(){
-		// summary: English ordinal suffix for the day of the month, 2 characters
+		// summary:
+		//		English ordinal suffix for the day of the month, 2 characters
 		switch(this.date.getDate()){
 			case 11: case 12: case 13: return "th";
 			case 1: case 21: case 31: return "st";
@@ -89,12 +104,14 @@ dojo.extend(dojox.date.php.DateFormat, {
 	},
 
 	w: function(){
-		// summary: Numeric representation of the day of the week
+		// summary:
+		//		Numeric representation of the day of the week
 		return this.date.getDay() + "";
 	},
 
 	z: function(){
-		// summary: The day of the year (starting from 0)
+		// summary:
+		//		The day of the year (starting from 0)
 		var millis = this.date.getTime() - new Date(this.date.getFullYear(), 0, 1).getTime();
 		return Math.floor(millis/86400000) + "";
 	},
@@ -102,7 +119,8 @@ dojo.extend(dojox.date.php.DateFormat, {
 	// Week
 
 	W: function(){
-		// summary: ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0)
+		// summary:
+		//		ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0)
 		var week;
 		var jan1_w = new Date(this.date.getFullYear(), 0, 1).getDay() + 1;
 		var w = this.date.getDay() + 1;
@@ -132,42 +150,48 @@ dojo.extend(dojox.date.php.DateFormat, {
 				}
 			}
 		}
-		
+
 		return week;
 	},
 
 	// Month
 
 	F: function(){
-		// summary: A full textual representation of a month, such as January or March
+		// summary:
+		//		A full textual representation of a month, such as January or March
 		return this.months[this.date.getMonth()];
 	},
 
 	m: function(){
-		// summary: Numeric representation of a month, with leading zeros
+		// summary:
+		//		Numeric representation of a month, with leading zeros
 		var n = this.n();
 		return (n.length == 1) ? "0" + n : n;
 	},
 
 	M: function(){
-		// summary: A short textual representation of a month, three letters
+		// summary:
+		//		A short textual representation of a month, three letters
 		return this.months_3[this.date.getMonth()];
 	},
 
 	n: function(){
-		// summary: Numeric representation of a month, without leading zeros
+		// summary:
+		//		Numeric representation of a month, without leading zeros
 		return this.date.getMonth() + 1 + "";
 	},
 
 	t: function(){
-		// summary: Number of days in the given month
+		// summary:
+		//		Number of days in the given month
 		return (Boolean(this.L()) && this.date.getMonth() == 1) ? 29 : this.monthdays[this.getMonth()];
 	},
 
 	// Year
 
 	L: function(){
-		// summary: Whether it's a leap year
+		// summary:
+		//		Whether it's a leap year
 		return (ddate.isLeapYear(this.date)) ? "1" : "0";
 	},
 
@@ -175,35 +199,40 @@ dojo.extend(dojox.date.php.DateFormat, {
 		// summary:
 		//		ISO-8601 year number. This has the same value as Y, except that if
 		//		the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0)
+
 		// TODO: Figure out what this means
 	},
 
 	Y: function(){
-		// summary: A full numeric representation of a year, 4 digits
+		// summary:
+		//		A full numeric representation of a year, 4 digits
 		return this.date.getFullYear() + "";
 	},
 
 	y: function(){
-		// summary: A two digit representation of a year
+		// summary:
+		//		A two digit representation of a year
 		return this.Y().slice(-2);
 	},
 
 	// Time
 
 	a: function(){
-		// summary: Lowercase Ante meridiem and Post meridiem
+		// summary:
+		//		Lowercase Ante meridian and Post meridian
 		return this.date.getHours() >= 12 ? "pm" : "am";
 	},
 
 	b: function(){
-		// summary: Uppercase Ante meridiem and Post meridiem
+		// summary:
+		//		Uppercase Ante meridian and Post meridian
 		return this.a().toUpperCase();
 	},
 
 	B: function(){
 		// summary:
-		//	Swatch Internet time
-		//	A day is 1,000 beats. All time is measured from GMT + 1
+		//		Swatch Internet time
+		//		A day is 1,000 beats. All time is measured from GMT + 1
 		var off = this.date.getTimezoneOffset() + 60;
 		var secs = (this.date.getHours() * 3600) + (this.date.getMinutes() * 60) + this.getSeconds() + (off * 60);
 		var beat = Math.abs(Math.floor(secs / 86.4) % 1000) + "";
@@ -212,35 +241,41 @@ dojo.extend(dojox.date.php.DateFormat, {
 	},
 
 	g: function(){
-		// summary: 12-hour format of an hour without leading zeros
-		return (this.date.getHours() > 12) ? this.date.getHours() - 12 + "" : this.date.getHours() + "";
+		// summary:
+		//		12-hour format of an hour without leading zeros
+		return (this.date.getHours() % 12 || 12) + "";
 	},
 
 	G: function(){
-		// summary: 24-hour format of an hour without leading zeros
+		// summary:
+		//		24-hour format of an hour without leading zeros
 		return this.date.getHours() + "";
 	},
 
 	h: function(){
-		// summary: 12-hour format of an hour with leading zeros
+		// summary:
+		//		12-hour format of an hour with leading zeros
 		var g = this.g();
 		return (g.length == 1) ? "0" + g : g;
 	},
 
 	H: function(){
-		// summary: 24-hour format of an hour with leading zeros
+		// summary:
+		//		24-hour format of an hour with leading zeros
 		var G = this.G();
 		return (G.length == 1) ? "0" + G : G;
 	},
 
 	i: function(){
-		// summary: Minutes with leading zeros
+		// summary:
+		//		Minutes with leading zeros
 		var mins = this.date.getMinutes() + "";
 		return (mins.length == 1) ? "0" + mins : mins;
 	},
 
 	s: function(){
-		// summary: Seconds, with leading zeros
+		// summary:
+		//		Seconds, with leading zeros
 		var secs = this.date.getSeconds() + "";
 		return (secs.length == 1) ? "0" + secs : secs;
 	},
@@ -248,17 +283,21 @@ dojo.extend(dojox.date.php.DateFormat, {
 	// Timezone
 
 	e: function(){
-		// summary: Timezone identifier (added in PHP 5.1.0)
+		// summary:
+		//		Timezone identifier (added in PHP 5.1.0)
 		return ddate.getTimezoneName(this.date);
 	},
 
 	I: function(){
-		// summary: Whether or not the date is in daylight saving time
+		// summary:
+		//		Whether or not the date is in daylight saving time
+
 		// TODO: Can dojo.date do this?
 	},
 
 	O: function(){
-		// summary: Difference to Greenwich time (GMT) in hours
+		// summary:
+		//		Difference to Greenwich time (GMT) in hours
 		var off = Math.abs(this.date.getTimezoneOffset());
 		var hours = Math.floor(off / 60) + "";
 		var mins = (off % 60) + "";
@@ -268,13 +307,15 @@ dojo.extend(dojox.date.php.DateFormat, {
 	},
 
 	P: function(){
-		// summary: Difference to Greenwich time (GMT) with colon between hours and minutes (added in PHP 5.1.3)
+		// summary:
+		//		Difference to Greenwich time (GMT) with colon between hours and minutes (added in PHP 5.1.3)
 		var O = this.O();
 		return O.substring(0, 2) + ":" + O.substring(2, 4);
 	},
 
 	T: function(){
-		// summary: Timezone abbreviation
+		// summary:
+		//		Timezone abbreviation
 
 		// Guess...
 		return this.e().substring(0, 3);
@@ -290,20 +331,23 @@ dojo.extend(dojox.date.php.DateFormat, {
 	// Full Date/Time
 
 	c: function(){
-		// summary: ISO 8601 date (added in PHP 5)
+		// summary:
+		//		ISO 8601 date (added in PHP 5)
 		return this.Y() + "-" + this.m() + "-" + this.d() + "T" + this.h() + ":" + this.i() + ":" + this.s() + this.P();
 	},
 
 	r: function(){
-		// summary: RFC 2822 formatted date
+		// summary:
+		//		RFC 2822 formatted date
 		return this.D() + ", " + this.d() + " " + this.M() + " " + this.Y() + " " + this.H() + ":" + this.i() + ":" + this.s() + " " + this.O();
 	},
 
 	U: function(){
-		// summary: Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
+		// summary:
+		//		Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
 		return Math.floor(this.date.getTime() / 1000);
 	}
 
 });
-return dojox.date.php;
+return php;
 });
\ No newline at end of file
diff --git a/dojox/date/posix.js b/dojox/date/posix.js
index 60da32d..070bf10 100644
--- a/dojox/date/posix.js
+++ b/dojox/date/posix.js
@@ -1,15 +1,20 @@
 define(["dojo/_base/kernel", "dojo/date", "dojo/date/locale", "dojo/string", "dojo/cldr/supplemental"],
        function(dojo, dojoDate, dojoDateLocale, dojoString, dojoCldrSupplemental){
 
-dojo.getObject("date.posix", true, dojox);
+var posix = dojo.getObject("date.posix", true, dojox);
+/*=====
+var posix = {
+	// TODO: summary
+};
+=====*/
 
-dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*String?*/locale){
-//
-// summary:
-//		Formats the date object using the specifications of the POSIX strftime function
-//
-// description:
-//		see http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html
+posix.strftime = function(/*Date*/dateObject, /*String*/format, /*String?*/locale){
+	//
+	// summary:
+	//		Formats the date object using the specifications of the POSIX strftime function
+	//
+	// description:
+	//		see http://www.opengroup.org/onlinepubs/007908799/xsh/strftime.html
 
 	// zero pad
 	var padChar = null;
@@ -134,7 +139,7 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 				      // 1 January has four or more days in the new year, then it
 				      // is considered week 1. Otherwise, it is the last week of
 				      // the previous year, and the next week is week 1.
-				return _(dojox.date.posix.getIsoWeekOfYear(dateObject));
+				return _(posix.getIsoWeekOfYear(dateObject));
 				
 			case "W": // week number of the current year as a decimal number,
 				      // starting with the first Monday as the first day of the
@@ -232,9 +237,10 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 	return string; // String
 };
 
-dojox.date.posix.getStartOfWeek = function(/*Date*/dateObject, /*Number*/firstDay){
-	// summary: Return a date object representing the first day of the given
-	//   date's week.
+posix.getStartOfWeek = function(/*Date*/dateObject, /*Number*/firstDay){
+	// summary:
+	//		Return a date object representing the first day of the given
+	//		date's week.
 	if(isNaN(firstDay)){
 		firstDay = dojoCldrSupplemental.getFirstDayOfWeek ? dojoCldrSupplemental.getFirstDayOfWeek() : 0;
 	}
@@ -247,44 +253,49 @@ dojox.date.posix.getStartOfWeek = function(/*Date*/dateObject, /*Number*/firstDa
 	var date = new Date(dateObject);
 	date.setHours(0, 0, 0, 0);
 	return dojoDate.add(date, "day", offset); // Date
-}
+};
 
-dojox.date.posix.setIsoWeekOfYear = function(/*Date*/dateObject, /*Number*/week){
-	// summary: Set the ISO8601 week number of the given date.
-	//   The week containing January 4th is the first week of the year.
+posix.setIsoWeekOfYear = function(/*Date*/dateObject, /*Number*/week){
+	// summary:
+	//		Set the ISO8601 week number of the given date.
+	//		The week containing January 4th is the first week of the year.
 	// week:
-	//   can be positive or negative: -1 is the year's last week.
+	//		can be positive or negative: -1 is the year's last week.
 	if(!week){ return dateObject; }
-	var currentWeek = dojox.date.posix.getIsoWeekOfYear(dateObject);
+	var currentWeek = posix.getIsoWeekOfYear(dateObject);
 	var offset = week - currentWeek;
 	if(week < 0){
-		var weeks = dojox.date.posix.getIsoWeeksInYear(dateObject);
+		var weeks = posix.getIsoWeeksInYear(dateObject);
 		offset = (weeks + week + 1) - currentWeek;
 	}
 	return dojoDate.add(dateObject, "week", offset); // Date
-}
+};
 
-dojox.date.posix.getIsoWeekOfYear = function(/*Date*/dateObject){
-	// summary: Get the ISO8601 week number of the given date.
-	//   The week containing January 4th is the first week of the year.
-	//   See http://en.wikipedia.org/wiki/ISO_week_date
-	var weekStart = dojox.date.posix.getStartOfWeek(dateObject, 1);
+posix.getIsoWeekOfYear = function(/*Date*/dateObject){
+	// summary:
+	//		Get the ISO8601 week number of the given date.
+	//		The week containing January 4th is the first week of the year.
+	//		See http://en.wikipedia.org/wiki/ISO_week_date
+	var weekStart = posix.getStartOfWeek(dateObject, 1);
 	var yearStart = new Date(dateObject.getFullYear(), 0, 4); // January 4th
-	yearStart = dojox.date.posix.getStartOfWeek(yearStart, 1);
+	yearStart = posix.getStartOfWeek(yearStart, 1);
 	var diff = weekStart.getTime() - yearStart.getTime();
-	if(diff < 0){ return dojox.date.posix.getIsoWeeksInYear(weekStart); } // Integer
+	if(diff < 0){ return posix.getIsoWeeksInYear(weekStart); } // Integer
 	return Math.ceil(diff / 604800000) + 1; // Integer
-}
+};
 
-dojox.date.posix.getIsoWeeksInYear = function(/*Date*/dateObject) {
-	// summary: Determine the number of ISO8601 weeks in the year of the given
-	//   date. Most years have 52 but some have 53.
-	//   See http://www.phys.uu.nl/~vgent/calendar/isocalendar_text3.htm
+posix.getIsoWeeksInYear = function(/*Date*/dateObject) {
+	// summary:
+	//		Determine the number of ISO8601 weeks in the year of the given
+	//		date. Most years have 52 but some have 53.
+	//		See http://www.phys.uu.nl/~vgent/calendar/isocalendar_text3.htm
 	function p(y) {
 		return y + Math.floor(y/4) - Math.floor(y/100) + Math.floor(y/400);
 	}
 	var y = dateObject.getFullYear();
 	return ( p(y) % 7 == 4 || p(y-1) % 7 == 3 ) ? 53 : 52;	//	Integer
-}
-	return dojox.date.posix;
+};
+
+return posix;
+
 });
\ No newline at end of file
diff --git a/dojox/date/relative.js b/dojox/date/relative.js
index f7a656d..a376900 100644
--- a/dojox/date/relative.js
+++ b/dojox/date/relative.js
@@ -1,19 +1,16 @@
-define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/date/locale", "dojo/i18n"], function(dojo, dlang, ddl, i18n){
+define(["..", "dojo/_base/lang", "dojo/date/locale", "dojo/i18n"], function(dojox, lang, ddl, i18n){
 
-dojo.getObject("date.relative", true, dojox);
+var drelative = lang.getObject("date.relative", true, dojox);
 
 /*=====
-dojox.date.relative.__FormatOptions = function(){
-//	locale: String
-//		override the locale used to determine formatting rules
-//	relativeDate: Date
-//		Date to calculate relation to (defaults to new Date())
-//	weekCheck: boolean
-//		Whether or not to display the day of week (defaults true)
-	this.locale = locale;
-	this.relativeDate = relativeDate;
-	this.weekCheck = weekCheck;
-}
+var __FormatOptions = {
+	// locale: String
+	//		override the locale used to determine formatting rules
+	// relativeDate: Date
+	//		Date to calculate relation to (defaults to new Date())
+	// weekCheck: boolean
+	//		Whether or not to display the day of week (defaults true)
+};
 =====*/
 
 var DAY = 1000*60*60*24,
@@ -28,7 +25,7 @@ function _clearTime(date){
 	return date;
 }
 
-dojox.date.relative.format = function(/*Date*/dateObject, /*dojox.date.relative.__FormatOptions?*/options){
+drelative.format = function(/*Date*/dateObject, /*__FormatOptions?*/options){
 	// summary:
 	//		Format a Date object as a String, using locale-specific settings,
 	//		relative to the current date or some other date.
@@ -88,4 +85,6 @@ dojox.date.relative.format = function(/*Date*/dateObject, /*dojox.date.relative.
 		}));
 	}
 };
+
+	return drelative;
 });
diff --git a/dojox/date/tests/HebrewDateTest1.html b/dojox/date/tests/HebrewDateTest1.html
index d6fcb7b..d3cd8bb 100644
--- a/dojox/date/tests/HebrewDateTest1.html
+++ b/dojox/date/tests/HebrewDateTest1.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
 <html>
 	<head>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="locale: 'he', parseOnLoad: true, isDebug: true, extraLocale: ['he', 'ru']"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="locale: 'he', parseOnLoad: true, isDebug: true, extraLocale: ['he', 'ru']"></script>
 		<script language="javascript" type="text/javascript">
 			dojo.require("dojox.date.hebrew");
 			dojo.require("dojox.date.hebrew.Date");
diff --git a/dojox/date/tests/hebrew/Date.js b/dojox/date/tests/hebrew/Date.js
index 2e1b94d..e293beb 100644
--- a/dojox/date/tests/hebrew/Date.js
+++ b/dojox/date/tests/hebrew/Date.js
@@ -114,8 +114,10 @@ tests.register("dojox.date.tests.hebrew.Date",
 				//test for invalid date, toGregorian and fromGregorian should return invalid date
 				var invDate = new Date("");
 				var hDate = new dojox.date.hebrew.Date(invDate);
+				var hebrInvDate = new dojox.date.hebrew.Date("");
 				t.is(true, isNaN(hDate));
 				t.is(true, isNaN(hDate.toGregorian()));
+				t.is(true, isNaN(hebrInvDate));
 				
 			}
 		},
diff --git a/dojox/date/tests/islamic/Date.js b/dojox/date/tests/islamic/Date.js
index 123fdcd..23afa02 100644
--- a/dojox/date/tests/islamic/Date.js
+++ b/dojox/date/tests/islamic/Date.js
@@ -34,18 +34,1821 @@ tests.register("dojox.date.tests.islamic.Date",
 		{
 			name: "toGregorian",
 			runTest: function(t) {
-				var dateIslamic = new dojox.date.islamic.Date(1431, 3, 6, 15, 15, 10 ); // March 22 2010 3:15:10 PM
-				var dateGregorian = dateIslamic.toGregorian();
-				t.is(0, dojo.date.compare(new Date(2010, 2, 22, 15, 15, 10), dateGregorian, "date"));
+					
+			var dateTable = [[1420,0,1,1999,3,17], [1420,0,12,1999,3,28],
+			                 [1420,0,23,1999,4,9],
+			                 [1420,1,4,1999,4,20],
+			                 [1420,1,15,1999,4,31],
+			                 [1420,1,26,1999,5,11],
+			                 [1420,2,8,1999,5,22],
+			                 [1420,2,19,1999,6,3],
+			                 [1420,2,30,1999,6,14],
+			                 [1420,3,11,1999,6,25],
+			                 [1420,3,22,1999,7,5],
+			                 [1420,4,4,1999,7,16],
+			                 [1420,4,15,1999,7,27],
+			                 [1420,4,26,1999,8,7],
+			                 [1420,5,7,1999,8,18],
+			                 [1420,5,18,1999,8,29],
+			                 [1420,5,29,1999,9,10],
+			                 [1420,6,11,1999,9,21],
+			                 [1420,6,22,1999,10,1],
+			                 [1420,7,3,1999,10,12],
+			                 [1420,7,14,1999,10,23],
+			                 [1420,8,29,2000,0,6],
+			                 [1420,9,10,2000,0,17],
+			                 [1420,9,21,2000,0,28],
+			                 [1420,10,3,2000,1,8],
+			                 [1420,10,14,2000,1,19],
+			                 [1420,10,25,2000,2,1],
+			                 [1420,11,6,2000,2,12],
+			                 [1420,11,17,2000,2,23],
+			                 [1420,11,28,2000,3,3],
+			                 [1421,0,9,2000,3,14],
+			                 [1421,0,20,2000,3,25],
+			                 [1421,1,1,2000,4,6],
+			                 [1421,1,12,2000,4,17],
+			                 [1421,1,23,2000,4,28],
+			                 [1421,2,5,2000,5,8],
+			                 [1421,2,16,2000,5,19],
+			                 [1421,2,27,2000,5,30],
+			                 [1421,3,8,2000,6,11],
+			                 [1421,3,19,2000,6,22],
+			                 [1421,4,1,2000,7,2],
+			                 [1421,4,12,2000,7,13],
+			                 [1421,4,23,2000,7,24],
+			                 [1421,5,4,2000,8,4],
+			                 [1421,5,15,2000,8,15],
+			                 [1421,5,26,2000,8,26],
+			                 [1421,6,8,2000,9,7],
+			                 [1421,6,19,2000,9,18],
+			                 [1421,6,30,2000,9,29],
+			                 [1421,7,11,2000,10,9],
+			                 [1421,7,22,2000,10,20],
+			                 [1421,9,7,2001,0,3],
+			                 [1421,9,18,2001,0,14],
+			                 [1421,9,7,2001,0,3],
+			                 [1421,9,18,2001,0,14],
+			                 [1421,9,29,2001,0,25],
+			                 [1421,10,11,2001,1,5],
+			                 [1421,10,22,2001,1,16],
+			                 [1421,11,3,2001,1,27],
+			                 [1421,11,14,2001,2,10],
+			                 [1421,11,25,2001,2,21],
+			                 [1422,0,7,2001,3,1],
+			                 [1422,0,18,2001,3,12],
+			                 [1422,0,29,2001,3,23],
+			                 [1422,1,10,2001,4,4],
+			                 [1422,1,21,2001,4,15],
+			                 [1422,2,3,2001,4,26],
+			                 [1422,2,14,2001,5,6],
+			                 [1422,2,25,2001,5,17],
+			                 [1422,3,6,2001,5,28],
+			                 [1422,3,17,2001,6,9],
+			                 [1422,3,28,2001,6,20],
+			                 [1422,4,10,2001,6,31],
+			                 [1422,4,21,2001,7,11],
+			                 [1422,5,2,2001,7,22],
+			                 [1422,5,13,2001,8,2],
+			                 [1422,5,24,2001,8,13],
+			                 [1422,6,6,2001,8,24],
+			                 [1422,6,17,2001,9,5],
+			                 [1422,6,28,2001,9,16],
+			                 [1422,7,9,2001,9,27],
+			                 [1422,7,20,2001,10,7],
+			                 [1422,8,2,2001,10,18],
+			                 [1422,8,13,2001,10,29],
+			                 [1422,8,24,2001,11,10],
+			                 [1422,9,5,2001,11,21],
+			                 [1422,9,16,2002,0,1],
+			                 [1422,9,27,2002,0,12],
+			                 [1422,10,9,2002,0,23],
+			                 [1422,10,20,2002,1,3],
+			                 [1422,11,1,2002,1,14],
+			                 [1422,11,12,2002,1,25],
+			                 [1422,11,23,2002,2,8],
+			                 [1423,0,5,2002,2,19],
+			                 [1423,0,16,2002,2,30],
+			                 [1423,0,27,2002,3,10],
+			                 [1423,1,8,2002,3,21],
+			                 [1423,1,19,2002,4,2],
+			                 [1423,2,1,2002,4,13],
+			                 [1423,2,12,2002,4,24],
+			                 [1423,2,23,2002,5,4],
+			                 [1423,3,4,2002,5,15],
+			                 [1423,3,15,2002,5,26],
+			                 [1423,3,26,2002,6,7],
+			                 [1423,4,8,2002,6,18],
+			                 [1423,4,19,2002,6,29],
+			                 [1423,4,30,2002,7,9],
+			                 [1423,5,11,2002,7,20],
+			                 [1423,5,22,2002,7,31],
+			                 [1423,6,4,2002,8,11],
+			                 [1423,6,15,2002,8,22],
+			                 [1423,6,26,2002,9,3],
+			                 [1423,7,7,2002,9,14],
+			                 [1423,7,18,2002,9,25],
+			                 [1423,7,29,2002,10,5],
+			                 [1423,8,11,2002,10,16],
+			                 [1423,8,22,2002,10,27],
+			                 [1423,9,3,2002,11,8],
+			                 [1423,9,14,2002,11,19],
+			                 [1423,9,25,2002,11,30],
+			                 [1423,10,7,2003,0,10],
+			                 [1423,10,18,2003,0,21],
+			                 [1423,10,29,2003,1,1],
+			                 [1423,11,10,2003,1,12],
+			                 [1423,11,21,2003,1,23],
+			                 [1424,0,2,2003,2,6],
+			                 [1424,0,13,2003,2,17],
+			                 [1424,0,24,2003,2,28],
+			                 [1424,1,5,2003,3,8],
+			                 [1424,1,16,2003,3,19],
+			                 [1424,1,27,2003,3,30],
+			                 [1424,2,9,2003,4,11],
+			                 [1424,2,20,2003,4,22],
+			                 [1424,3,1,2003,5,2],
+			                 [1424,3,12,2003,5,13],
+			                 [1424,3,23,2003,5,24],
+			                 [1424,4,5,2003,6,5],
+			                 [1424,4,16,2003,6,16],
+			                 [1424,4,27,2003,6,27],
+			                 [1424,5,8,2003,7,7],
+			                 [1424,5,19,2003,7,18],
+			                 [1424,6,1,2003,7,29],
+			                 [1424,6,12,2003,8,9],
+			                 [1424,6,23,2003,8,20],
+			                 [1424,7,4,2003,9,1],
+			                 [1424,7,15,2003,9,12],
+			                 [1424,7,26,2003,9,23],
+			                 [1424,8,8,2003,10,3],
+			                 [1424,8,19,2003,10,14],
+			                 [1424,8,30,2003,10,25],
+			                 [1424,10,15,2004,0,8],
+			                 [1424,10,26,2004,0,19],
+			                 [1424,11,7,2004,0,30],
+			                 [1424,11,18,2004,1,10],
+			                 [1424,11,29,2004,1,21],
+			                 [1425,0,11,2004,2,3],
+			                 [1425,0,22,2004,2,14],
+			                 [1425,1,3,2004,2,25],
+			                 [1425,1,14,2004,3,5],
+			                 [1425,1,25,2004,3,16],
+			                 [1425,2,7,2004,3,27],
+			                 [1425,2,18,2004,4,8],
+			                 [1425,2,29,2004,4,19],
+			                 [1425,3,10,2004,4,30],
+			                 [1425,3,21,2004,5,10],
+			                 [1425,4,3,2004,5,21],
+			                 [1425,4,14,2004,6,2],
+			                 [1425,4,25,2004,6,13],
+			                 [1425,5,6,2004,6,24],
+			                 [1425,5,17,2004,7,4],
+			                 [1425,5,28,2004,7,15],
+			                 [1425,6,10,2004,7,26],
+			                 [1425,6,21,2004,8,6],
+			                 [1425,7,2,2004,8,17],
+			                 [1425,7,13,2004,8,28],
+			                 [1425,7,24,2004,9,9],
+			                 [1425,8,6,2004,9,20],
+			                 [1425,8,17,2004,9,31],
+			                 [1425,8,28,2004,10,11],
+			                 [1425,9,9,2004,10,22],
+			                 [1425,10,24,2005,0,5],
+			                 [1425,11,5,2005,0,16],
+			                 [1425,11,16,2005,0,27],
+			                 [1425,11,27,2005,1,7],
+			                 [1426,0,9,2005,1,18],
+			                 [1426,0,20,2005,2,1],
+			                 [1426,1,1,2005,2,12],
+			                 [1426,1,12,2005,2,23],
+			                 [1426,1,23,2005,3,3],
+			                 [1426,2,5,2005,3,14],
+			                 [1426,2,16,2005,3,25],
+			                 [1426,2,27,2005,4,6],
+			                 [1426,3,8,2005,4,17],
+			                 [1426,3,19,2005,4,28],
+			                 [1426,4,1,2005,5,8],
+			                 [1426,4,12,2005,5,19],
+			                 [1426,4,23,2005,5,30],
+			                 [1426,5,4,2005,6,11],
+			                 [1426,5,15,2005,6,22],
+			                 [1426,5,26,2005,7,2],
+			                 [1426,6,8,2005,7,13],
+			                 [1426,6,19,2005,7,24],
+			                 [1426,6,30,2005,8,4],
+			                 [1426,7,11,2005,8,15],
+			                 [1426,7,22,2005,8,26],
+			                 [1426,8,4,2005,9,7],
+			                 [1426,8,15,2005,9,18],
+			                 [1426,8,26,2005,9,29],
+			                 [1426,9,7,2005,10,9],
+			                 [1426,9,18,2005,10,20],
+			                 [1426,9,29,2005,11,1],
+			                 [1426,10,11,2005,11,12],
+			                 [1426,10,22,2005,11,23],
+			                 [1426,11,3,2006,0,3],
+			                 [1426,11,14,2006,0,14],
+			                 [1426,11,25,2006,0,25],
+			                 [1427,0,6,2006,1,5],
+			                 [1427,0,17,2006,1,16],
+			                 [1427,0,28,2006,1,27],
+			                 [1427,1,9,2006,2,10],
+			                 [1427,1,20,2006,2,21],
+			                 [1427,2,2,2006,3,1],
+			                 [1427,2,13,2006,3,12],
+			                 [1427,2,24,2006,3,23],
+			                 [1427,3,5,2006,4,4],
+			                 [1427,3,16,2006,4,15],
+			                 [1427,3,27,2006,4,26],
+			                 [1427,4,9,2006,5,6],
+			                 [1427,4,20,2006,5,17],
+			                 [1427,5,1,2006,5,28],
+			                 [1427,5,12,2006,6,9],
+			                 [1427,5,23,2006,6,20],
+			                 [1427,6,5,2006,6,31],
+			                 [1427,6,16,2006,7,11],
+			                 [1427,6,27,2006,7,22],
+			                 [1427,7,8,2006,8,2],
+			                 [1427,7,19,2006,8,13],
+			                 [1427,8,1,2006,8,24],
+			                 [1427,8,12,2006,9,5],
+			                 [1427,8,23,2006,9,16],
+			                 [1427,9,4,2006,9,27],
+			                 [1427,9,15,2006,10,7],
+			                 [1427,9,26,2006,10,18],
+			                 [1427,10,8,2006,10,29],
+			                 [1427,10,19,2006,11,10],
+			                 [1427,10,30,2006,11,21],
+			                 [1427,11,11,2007,0,1],
+			                 [1427,11,22,2007,0,12],
+			                 [1428,0,4,2007,0,23],
+			                 [1428,0,15,2007,1,3],
+			                 [1428,0,26,2007,1,14],
+			                 [1428,1,7,2007,1,25],
+			                 [1428,1,18,2007,2,8],
+			                 [1428,1,29,2007,2,19],
+			                 [1428,2,11,2007,2,30],
+			                 [1428,2,22,2007,3,10],
+			                 [1428,3,3,2007,3,21],
+			                 [1428,3,14,2007,4,2],
+			                 [1428,3,25,2007,4,13],
+			                 [1428,4,7,2007,4,24],
+			                 [1428,4,18,2007,5,4],
+			                 [1428,4,29,2007,5,15],
+			                 [1428,5,10,2007,5,26],
+			                 [1428,5,21,2007,6,7],
+			                 [1428,6,3,2007,6,18],
+			                 [1428,6,14,2007,6,29],
+			                 [1428,6,25,2007,7,9],
+			                 [1428,7,6,2007,7,20],
+			                 [1428,7,17,2007,7,31],
+			                 [1428,7,28,2007,8,11],
+			                 [1428,8,10,2007,8,22],
+			                 [1428,8,21,2007,9,3],
+			                 [1428,9,2,2007,9,14],
+			                 [1428,9,13,2007,9,25],
+			                 [1428,9,24,2007,10,5],
+			                 [1428,10,6,2007,10,16],
+			                 [1428,10,17,2007,10,27],
+			                 [1429,0,1,2008,0,10],
+			                 [1429,0,12,2008,0,21],
+			                 [1429,0,23,2008,1,1],
+			                 [1429,1,4,2008,1,12],
+			                 [1429,1,15,2008,1,23],
+			                 [1429,1,26,2008,2,5],
+			                 [1429,2,8,2008,2,16],
+			                 [1429,2,19,2008,2,27],
+			                 [1429,2,30,2008,3,7],
+			                 [1429,3,11,2008,3,18],
+			                 [1429,3,22,2008,3,29],
+			                 [1429,4,4,2008,4,10],
+			                 [1429,4,15,2008,4,21],
+			                 [1429,4,26,2008,5,1],
+			                 [1429,5,7,2008,5,12],
+			                 [1429,5,18,2008,5,23],
+			                 [1429,5,29,2008,6,4],
+			                 [1429,6,11,2008,6,15],
+			                 [1429,6,22,2008,6,26],
+			                 [1429,7,3,2008,7,6],
+			                 [1429,7,14,2008,7,17],
+			                 [1429,7,25,2008,7,28],
+			                 [1429,8,7,2008,8,8],
+			                 [1429,8,18,2008,8,19],
+			                 [1429,8,29,2008,8,30],
+			                 [1429,9,10,2008,9,11],
+			                 [1429,9,21,2008,9,22],
+			                 [1429,10,3,2008,10,2],
+			                 [1429,10,14,2008,10,13],
+			                 [1429,10,25,2008,10,24],
+			                 [1430,0,10,2009,0,7],
+			                 [1430,0,21,2009,0,18],
+			                 [1430,1,2,2009,0,29],
+			                 [1430,1,13,2009,1,9],
+			                 [1430,1,24,2009,1,20],
+			                 [1430,2,6,2009,2,3],
+			                 [1430,2,17,2009,2,14],
+			                 [1430,2,28,2009,2,25],
+			                 [1430,3,9,2009,3,5],
+			                 [1430,3,20,2009,3,16],
+			                 [1430,4,2,2009,3,27],
+			                 [1430,4,13,2009,4,8],
+			                 [1430,4,24,2009,4,19],
+			                 [1430,5,5,2009,4,30],
+			                 [1430,5,16,2009,5,10],
+			                 [1430,5,27,2009,5,21],
+			                 [1430,6,9,2009,6,2],
+			                 [1430,6,20,2009,6,13],
+			                 [1430,7,1,2009,6,24],
+			                 [1430,7,12,2009,7,4],
+			                 [1430,7,23,2009,7,15],
+			                 [1430,8,5,2009,7,26],
+			                 [1430,8,16,2009,8,6],
+			                 [1430,8,27,2009,8,17],
+			                 [1430,9,8,2009,8,28],
+			                 [1430,9,19,2009,9,9],
+			                 [1430,10,1,2009,9,20],
+			                 [1430,10,12,2009,9,31],
+			                 [1430,10,23,2009,10,11],
+			                 [1430,11,4,2009,10,22],
+			                 [1430,11,15,2009,11,3],
+			                 [1430,11,26,2009,11,14],
+			                 [1431,0,8,2009,11,25],
+			                 [1431,0,19,2010,0,5],
+			                 [1431,0,30,2010,0,16],
+			                 [1431,1,11,2010,0,27],
+			                 [1431,1,22,2010,1,7],
+			                 [1431,2,4,2010,1,18],
+			                 [1431,2,15,2010,2,1],
+			                 [1431,2,26,2010,2,12],
+			                 [1431,3,7,2010,2,23],
+			                 [1431,3,18,2010,3,3],
+			                 [1431,3,29,2010,3,14],
+			                 [1431,4,11,2010,3,25],
+			                 [1431,4,22,2010,4,6],
+			                 [1431,5,3,2010,4,17],
+			                 [1431,5,14,2010,4,28],
+			                 [1431,5,25,2010,5,8],
+			                 [1431,6,7,2010,5,19],
+			                 [1431,6,18,2010,5,30],
+			                 [1431,6,29,2010,6,11],
+			                 [1431,7,10,2010,6,22],
+			                 [1431,7,21,2010,7,2],
+			                 [1431,8,3,2010,7,13],
+			                 [1431,8,14,2010,7,24],
+			                 [1431,8,25,2010,8,4],
+			                 [1431,9,6,2010,8,15],
+			                 [1431,9,17,2010,8,26],
+			                 [1431,9,28,2010,9,7],
+			                 [1431,10,10,2010,9,18],
+			                 [1431,10,21,2010,9,29],
+			                 [1431,11,2,2010,10,9],
+			                 [1431,11,13,2010,10,20],
+			                 [1431,11,24,2010,11,1],
+			                 [1432,0,5,2010,11,12],
+			                 [1432,0,16,2010,11,23],
+			                 [1432,0,27,2011,0,3],
+			                 [1432,1,8,2011,0,14],
+			                 [1432,1,19,2011,0,25],
+			                 [1432,2,1,2011,1,5],
+			                 [1432,2,12,2011,1,16],
+			                 [1432,2,23,2011,1,27],
+			                 [1432,3,4,2011,2,10],
+			                 [1432,3,15,2011,2,21],
+			                 [1432,3,26,2011,3,1],
+			                 [1432,4,8,2011,3,12],
+			                 [1432,4,19,2011,3,23],
+			                 [1432,4,30,2011,4,4],
+			                 [1432,5,11,2011,4,15],
+			                 [1432,5,22,2011,4,26],
+			                 [1432,6,4,2011,5,6],
+			                 [1432,6,15,2011,5,17],
+			                 [1432,6,26,2011,5,28],
+			                 [1432,7,7,2011,6,9],
+			                 [1432,7,18,2011,6,20],
+			                 [1432,7,29,2011,6,31],
+			                 [1432,8,11,2011,7,11],
+			                 [1432,8,22,2011,7,22],
+			                 [1432,9,3,2011,8,2],
+			                 [1432,9,14,2011,8,13],
+			                 [1432,9,25,2011,8,24],
+			                 [1432,10,7,2011,9,5],
+			                 [1432,10,18,2011,9,16],
+			                 [1432,10,29,2011,9,27],
+			                 [1432,11,10,2011,10,7],
+			                 [1432,11,21,2011,10,18],
+			                 [1433,0,3,2011,10,29],
+			                 [1433,1,6,2012,0,1],
+			                 [1433,1,17,2012,0,12],
+			                 [1433,1,28,2012,0,23],
+			                 [1433,2,10,2012,1,3],
+			                 [1433,2,21,2012,1,14],
+			                 [1433,3,2,2012,1,25],
+			                 [1433,3,13,2012,2,7],
+			                 [1433,3,24,2012,2,18],
+			                 [1433,4,6,2012,2,29],
+			                 [1433,4,17,2012,3,9],
+			                 [1433,4,28,2012,3,20],
+			                 [1433,5,9,2012,4,1],
+			                 [1433,5,20,2012,4,12],
+			                 [1433,6,2,2012,4,23],
+			                 [1433,6,13,2012,5,3],
+			                 [1433,6,24,2012,5,14],
+			                 [1433,7,5,2012,5,25],
+			                 [1433,7,16,2012,6,6],
+			                 [1433,7,27,2012,6,17],
+			                 [1433,8,9,2012,6,28],
+			                 [1433,8,20,2012,7,8],
+			                 [1433,9,1,2012,7,19],
+			                 [1433,9,12,2012,7,30],
+			                 [1433,9,23,2012,8,10],
+			                 [1433,10,5,2012,8,21],
+			                 [1433,10,16,2012,9,2],
+			                 [1433,10,27,2012,9,13],
+			                 [1433,11,8,2012,9,24],
+			                 [1433,11,19,2012,10,4],
+			                 [1434,0,1,2012,10,15],
+			                 [1434,0,12,2012,10,26],
+			                 [1434,1,26,2013,0,9],
+			                 [1434,2,8,2013,0,20],
+			                 [1434,2,19,2013,0,31],
+			                 [1434,2,30,2013,1,11],
+			                 [1434,3,11,2013,1,22],
+			                 [1434,3,22,2013,2,5],
+			                 [1434,4,4,2013,2,16],
+			                 [1434,4,15,2013,2,27],
+			                 [1434,4,26,2013,3,7],
+			                 [1434,5,7,2013,3,18],
+			                 [1434,5,18,2013,3,29],
+			                 [1434,5,29,2013,4,10],
+			                 [1434,6,11,2013,4,21],
+			                 [1434,6,22,2013,5,1],
+			                 [1434,7,3,2013,5,12],
+			                 [1434,7,14,2013,5,23],
+			                 [1434,7,25,2013,6,4],
+			                 [1434,8,7,2013,6,15],
+			                 [1434,8,18,2013,6,26],
+			                 [1434,8,29,2013,7,6],
+			                 [1434,9,10,2013,7,17],
+			                 [1434,9,21,2013,7,28],
+			                 [1434,10,3,2013,8,8],
+			                 [1434,10,14,2013,8,19],
+			                 [1434,10,25,2013,8,30],
+			                 [1434,11,6,2013,9,11],
+			                 [1434,11,17,2013,9,22],
+			                 [1434,11,28,2013,10,2],
+			                 [1435,0,9,2013,10,13],
+			                 [1435,0,20,2013,10,24],
+			                 [1435,1,1,2013,11,5],
+			                 [1435,1,12,2013,11,16],
+			                 [1435,1,23,2013,11,27],
+			                 [1435,2,5,2014,0,7],
+			                 [1435,2,16,2014,0,18],
+			                 [1435,2,27,2014,0,29],
+			                 [1435,3,8,2014,1,9],
+			                 [1435,3,19,2014,1,20],
+			                 [1435,4,1,2014,2,3],
+			                 [1435,4,12,2014,2,14],
+			                 [1435,4,23,2014,2,25],
+			                 [1435,5,4,2014,3,5],
+			                 [1435,5,15,2014,3,16],
+			                 [1435,5,26,2014,3,27],
+			                 [1435,6,8,2014,4,8],
+			                 [1435,6,19,2014,4,19],
+			                 [1435,6,30,2014,4,30],
+			                 [1435,7,11,2014,5,10],
+			                 [1435,7,22,2014,5,21],
+			                 [1435,8,4,2014,6,2],
+			                 [1435,8,15,2014,6,13],
+			                 [1435,8,26,2014,6,24],
+			                 [1435,9,7,2014,7,4],
+			                 [1435,9,18,2014,7,15],
+			                 [1435,9,29,2014,7,26],
+			                 [1435,10,11,2014,8,6],
+			                 [1435,10,22,2014,8,17],
+			                 [1435,11,3,2014,8,28],
+			                 [1435,11,14,2014,9,9],
+			                 [1435,11,25,2014,9,20],
+			                 [1436,0,7,2014,9,31],
+			                 [1436,0,18,2014,10,11],
+			                 [1436,0,29,2014,10,22],
+			                 [1436,1,10,2014,11,3],
+			                 [1436,1,21,2014,11,14],
+			                 [1436,2,3,2014,11,25],
+			                 [1436,2,14,2015,0,5],
+			                 [1436,2,25,2015,0,16],
+			                 [1436,3,6,2015,0,27],
+			                 [1436,3,17,2015,1,7],
+			                 [1436,3,28,2015,1,18],
+			                 [1436,4,10,2015,2,1],
+			                 [1436,4,21,2015,2,12],
+			                 [1436,5,2,2015,2,23],
+			                 [1436,5,13,2015,3,3],
+			                 [1436,5,24,2015,3,14],
+			                 [1436,6,6,2015,3,25],
+			                 [1436,6,17,2015,4,6],
+			                 [1436,6,28,2015,4,17],
+			                 [1436,7,9,2015,4,28],
+			                 [1436,7,20,2015,5,8],
+			                 [1436,8,2,2015,5,19],
+			                 [1436,8,13,2015,5,30],
+			                 [1436,8,24,2015,6,11],
+			                 [1436,9,5,2015,6,22],
+			                 [1436,9,16,2015,7,2],
+			                 [1436,9,27,2015,7,13],
+			                 [1436,10,9,2015,7,24],
+			                 [1436,10,20,2015,8,4],
+			                 [1436,11,1,2015,8,15],
+			                 [1436,11,12,2015,8,26],
+			                 [1436,11,23,2015,9,7],
+			                 [1437,0,4,2015,9,18],
+			                 [1437,0,15,2015,9,29],
+			                 [1437,0,26,2015,10,9],
+			                 [1437,1,7,2015,10,20],
+			                 [1437,2,22,2016,0,3],
+			                 [1437,3,3,2016,0,14],
+			                 [1437,3,14,2016,0,25],
+			                 [1437,3,25,2016,1,5],
+			                 [1437,4,7,2016,1,16],
+			                 [1437,4,18,2016,1,27],
+			                 [1437,4,29,2016,2,9],
+			                 [1437,5,10,2016,2,20],
+			                 [1437,5,21,2016,2,31],
+			                 [1437,6,3,2016,3,11],
+			                 [1437,6,14,2016,3,22],
+			                 [1437,6,25,2016,4,3],
+			                 [1437,7,6,2016,4,14],
+			                 [1437,7,17,2016,4,25],
+			                 [1437,7,28,2016,5,5],
+			                 [1437,8,10,2016,5,16],
+			                 [1437,8,21,2016,5,27],
+			                 [1437,9,2,2016,6,8],
+			                 [1437,9,13,2016,6,19],
+			                 [1437,9,24,2016,6,30],
+			                 [1437,10,6,2016,7,10],
+			                 [1437,10,17,2016,7,21],
+			                 [1437,10,28,2016,8,1],
+			                 [1437,11,9,2016,8,12],
+			                 [1437,11,20,2016,8,23],
+			                 [1438,0,2,2016,9,4],
+			                 [1438,0,13,2016,9,15],
+			                 [1438,0,24,2016,9,26],
+			                 [1438,1,5,2016,10,6],
+			                 [1438,1,16,2016,10,17],
+			                 [1438,1,27,2016,10,28],
+			                 [1438,3,12,2017,0,11],
+			                 [1438,3,23,2017,0,22],
+			                 [1438,4,5,2017,1,2],
+			                 [1438,4,16,2017,1,13],
+			                 [1438,4,27,2017,1,24],
+			                 [1438,5,8,2017,2,7],
+			                 [1438,5,19,2017,2,18],
+			                 [1438,6,1,2017,2,29],
+			                 [1438,6,12,2017,3,9],
+			                 [1438,6,23,2017,3,20],
+			                 [1438,7,4,2017,4,1],
+			                 [1438,7,15,2017,4,12],
+			                 [1438,7,26,2017,4,23],
+			                 [1438,8,8,2017,5,3],
+			                 [1438,8,19,2017,5,14],
+			                 [1438,8,30,2017,5,25],
+			                 [1438,9,11,2017,6,6],
+			                 [1438,9,22,2017,6,17],
+			                 [1438,10,4,2017,6,28],
+			                 [1438,10,15,2017,7,8],
+			                 [1438,10,26,2017,7,19],
+			                 [1438,11,7,2017,7,30],
+			                 [1438,11,18,2017,8,10],
+			                 [1438,11,29,2017,8,21],
+			                 [1439,0,11,2017,9,2],
+			                 [1439,0,22,2017,9,13],
+			                 [1439,1,3,2017,9,24],
+			                 [1439,1,14,2017,10,4],
+			                 [1439,1,25,2017,10,15],
+			                 [1439,2,7,2017,10,26],
+			                 [1439,2,18,2017,11,7],
+			                 [1439,2,29,2017,11,18],
+			                 [1439,3,10,2017,11,29],
+			                 [1439,3,21,2018,0,9],
+			                 [1439,4,3,2018,0,20],
+			                 [1439,4,14,2018,0,31],
+			                 [1439,4,25,2018,1,11],
+			                 [1439,5,6,2018,1,22],
+			                 [1439,5,17,2018,2,5],
+			                 [1439,5,28,2018,2,16],
+			                 [1439,6,10,2018,2,27],
+			                 [1439,6,21,2018,3,7],
+			                 [1439,7,2,2018,3,18],
+			                 [1439,7,13,2018,3,29],
+			                 [1439,7,24,2018,4,10],
+			                 [1439,8,6,2018,4,21],
+			                 [1439,8,17,2018,5,1],
+			                 [1439,8,28,2018,5,12],
+			                 [1439,9,9,2018,5,23],
+			                 [1439,9,20,2018,6,4],
+			                 [1439,10,2,2018,6,15],
+			                 [1439,10,13,2018,6,26],
+			                 [1439,10,24,2018,7,6],
+			                 [1439,11,5,2018,7,17],
+			                 [1439,11,16,2018,7,28],
+			                 [1439,11,27,2018,8,8],
+			                 [1440,0,8,2018,8,19],
+			                 [1440,0,19,2018,8,30],
+			                 [1440,0,30,2018,9,11],
+			                 [1440,1,11,2018,9,22],
+			                 [1440,1,22,2018,10,2],
+			                 [1440,2,4,2018,10,13],
+			                 [1440,2,15,2018,10,24],
+			                 [1440,2,26,2018,11,5],
+			                 [1440,3,7,2018,11,16],
+			                 [1440,3,18,2018,11,27],
+			                 [1440,3,29,2019,0,7],
+			                 [1440,4,11,2019,0,18],
+			                 [1440,4,22,2019,0,29],
+			                 [1440,5,3,2019,1,9],
+			                 [1440,5,14,2019,1,20],
+			                 [1440,5,25,2019,2,3],
+			                 [1440,6,7,2019,2,14],
+			                 [1440,6,18,2019,2,25],
+			                 [1440,6,29,2019,3,5],
+			                 [1440,7,10,2019,3,16],
+			                 [1440,7,21,2019,3,27],
+			                 [1440,8,3,2019,4,8],
+			                 [1440,8,14,2019,4,19],
+			                 [1440,8,25,2019,4,30],
+			                 [1440,9,6,2019,5,10],
+			                 [1440,9,17,2019,5,21],
+			                 [1440,9,28,2019,6,2],
+			                 [1440,10,10,2019,6,13],
+			                 [1440,10,21,2019,6,24],
+			                 [1440,11,2,2019,7,4],
+			                 [1440,11,13,2019,7,15],
+			                 [1440,11,24,2019,7,26],
+			                 [1441,0,6,2019,8,6],
+			                 [1441,0,17,2019,8,17],
+			                 [1441,0,28,2019,8,28],
+			                 [1441,1,9,2019,9,9],
+			                 [1441,1,20,2019,9,20],
+			                 [1441,2,2,2019,9,31],
+			                 [1441,2,13,2019,10,11],
+			                 [1441,2,24,2019,10,22],
+			                 [1441,4,9,2020,0,5],
+			                 [1441,4,20,2020,0,16],
+			                 [1441,5,1,2020,0,27],
+			                 [1441,5,12,2020,1,7],
+			                 [1441,5,23,2020,1,18],
+			                 [1441,6,5,2020,1,29],
+			                 [1441,6,16,2020,2,11],
+			                 [1441,6,27,2020,2,22],
+			                 [1441,7,8,2020,3,2],
+			                 [1441,7,19,2020,3,13],
+			                 [1441,8,1,2020,3,24],
+			                 [1441,8,12,2020,4,5],
+			                 [1441,8,23,2020,4,16],
+			                 [1441,9,4,2020,4,27],
+			                 [1441,9,15,2020,5,7],
+			                 [1441,9,26,2020,5,18],
+			                 [1441,10,8,2020,5,29],
+			                 [1441,10,19,2020,6,10],
+			                 [1441,10,30,2020,6,21],
+			                 [1441,11,11,2020,7,1],
+			                 [1441,11,22,2020,7,12],
+			                 [1442,0,4,2020,7,23],
+			                 [1442,0,15,2020,8,3],
+			                 [1442,0,26,2020,8,14],
+			                 [1442,1,7,2020,8,25],
+			                 [1442,1,18,2020,9,6],
+			                 [1442,1,29,2020,9,17],
+			                 [1442,2,11,2020,9,28],
+			                 [1442,2,22,2020,10,8],
+			                 [1442,3,3,2020,10,19],
+			                 [1442,3,14,2020,10,30],
+			                 [1442,4,18,2021,0,2],
+			                 [1442,4,29,2021,0,13],
+			                 [1442,5,10,2021,0,24],
+			                 [1442,5,21,2021,1,4],
+			                 [1442,6,3,2021,1,15],
+			                 [1442,6,14,2021,1,26],
+			                 [1442,6,25,2021,2,9],
+			                 [1442,7,6,2021,2,20],
+			                 [1442,7,17,2021,2,31],
+			                 [1442,7,28,2021,3,11],
+			                 [1442,8,10,2021,3,22],
+			                 [1442,8,21,2021,4,3],
+			                 [1442,9,2,2021,4,14],
+			                 [1442,9,13,2021,4,25],
+			                 [1442,9,24,2021,5,5],
+			                 [1442,10,6,2021,5,16],
+			                 [1442,10,17,2021,5,27],
+			                 [1442,10,28,2021,6,8],
+			                 [1442,11,9,2021,6,19],
+			                 [1442,11,20,2021,6,30],
+			                 [1443,0,1,2021,7,10],
+			                 [1443,0,12,2021,7,21],
+			                 [1443,0,23,2021,8,1],
+			                 [1443,1,4,2021,8,12],
+			                 [1443,1,15,2021,8,23],
+			                 [1443,1,26,2021,9,4],
+			                 [1443,2,8,2021,9,15],
+			                 [1443,2,19,2021,9,26],
+			                 [1443,2,30,2021,10,6],
+			                 [1443,3,11,2021,10,17],
+			                 [1443,3,22,2021,10,28],
+			                 [1443,5,7,2022,0,11],
+			                 [1443,5,18,2022,0,22],
+			                 [1443,5,29,2022,1,2],
+			                 [1443,6,11,2022,1,13],
+			                 [1443,6,22,2022,1,24],
+			                 [1443,7,3,2022,2,7],
+			                 [1443,7,14,2022,2,18],
+			                 [1443,7,25,2022,2,29],
+			                 [1443,8,7,2022,3,9],
+			                 [1443,8,18,2022,3,20],
+			                 [1443,8,29,2022,4,1],
+			                 [1443,9,10,2022,4,12],
+			                 [1443,9,21,2022,4,23],
+			                 [1443,10,3,2022,5,3],
+			                 [1443,10,14,2022,5,14],
+			                 [1443,10,25,2022,5,25],
+			                 [1443,11,6,2022,6,6],
+			                 [1443,11,17,2022,6,17],
+			                 [1443,11,28,2022,6,28],
+			                 [1444,0,10,2022,7,8],
+			                 [1444,0,21,2022,7,19],
+			                 [1444,1,2,2022,7,30],
+			                 [1444,1,13,2022,8,10],
+			                 [1444,1,24,2022,8,21],
+			                 [1444,2,6,2022,9,2],
+			                 [1444,2,17,2022,9,13],
+			                 [1444,2,28,2022,9,24],
+			                 [1444,3,9,2022,10,4],
+			                 [1444,3,20,2022,10,15],
+			                 [1444,4,2,2022,10,26],
+			                 [1444,5,16,2023,0,9],
+			                 [1444,5,27,2023,0,20],
+			                 [1444,6,9,2023,0,31],
+			                 [1444,6,20,2023,1,11],
+			                 [1444,7,1,2023,1,22],
+			                 [1444,7,12,2023,2,5],
+			                 [1444,7,23,2023,2,16],
+			                 [1444,8,5,2023,2,27],
+			                 [1444,8,16,2023,3,7],
+			                 [1444,8,27,2023,3,18],
+			                 [1444,9,8,2023,3,29],
+			                 [1444,9,19,2023,4,10],
+			                 [1444,10,1,2023,4,21],
+			                 [1444,10,12,2023,5,1],
+			                 [1444,10,23,2023,5,12],
+			                 [1444,11,4,2023,5,23],
+			                 [1444,11,15,2023,6,4],
+			                 [1444,11,26,2023,6,15],
+			                 [1445,0,8,2023,6,26],
+			                 [1445,0,19,2023,7,6],
+			                 [1445,0,30,2023,7,17],
+			                 [1445,1,11,2023,7,28],
+			                 [1445,1,22,2023,8,8],
+			                 [1445,2,4,2023,8,19],
+			                 [1445,2,15,2023,8,30],
+			                 [1445,2,26,2023,9,11],
+			                 [1445,3,7,2023,9,22],
+			                 [1445,3,18,2023,10,2],
+			                 [1445,3,29,2023,10,13],
+			                 [1445,4,11,2023,10,24],
+			                 [1445,5,25,2024,0,7],
+			                 [1445,6,7,2024,0,18],
+			                 [1445,6,18,2024,0,29],
+			                 [1445,6,29,2024,1,9],
+			                 [1445,7,10,2024,1,20],
+			                 [1445,7,21,2024,2,2],
+			                 [1445,8,3,2024,2,13],
+			                 [1445,8,14,2024,2,24],
+			                 [1445,8,25,2024,3,4],
+			                 [1445,9,6,2024,3,15],
+			                 [1445,9,17,2024,3,26],
+			                 [1445,9,28,2024,4,7],
+			                 [1445,10,10,2024,4,18],
+			                 [1445,10,21,2024,4,29],
+			                 [1445,11,2,2024,5,9],
+			                 [1445,11,13,2024,5,20],
+			                 [1445,11,24,2024,6,1],
+			                 [1446,0,5,2024,6,12],
+			                 [1446,0,16,2024,6,23],
+			                 [1446,0,27,2024,7,3],
+			                 [1446,1,8,2024,7,14],
+			                 [1446,1,19,2024,7,25],
+			                 [1446,2,1,2024,8,5],
+			                 [1446,2,12,2024,8,16],
+			                 [1446,2,23,2024,8,27],
+			                 [1446,3,4,2024,9,8],
+			                 [1446,3,15,2024,9,19],
+			                 [1446,3,26,2024,9,30],
+			                 [1446,4,8,2024,10,10],
+			                 [1446,4,19,2024,10,21],
+			                 [1446,6,4,2025,0,4],
+			                 [1446,6,15,2025,0,15],
+			                 [1446,6,26,2025,0,26],
+			                 [1446,7,7,2025,1,6],
+			                 [1446,7,18,2025,1,17],
+			                 [1446,7,29,2025,1,28],
+			                 [1446,8,11,2025,2,11],
+			                 [1446,8,22,2025,2,22],
+			                 [1446,9,3,2025,3,2],
+			                 [1446,9,14,2025,3,13],
+			                 [1446,9,25,2025,3,24],
+			                 [1446,10,7,2025,4,5],
+			                 [1446,10,18,2025,4,16],
+			                 [1446,10,29,2025,4,27],
+			                 [1446,11,10,2025,5,7],
+			                 [1446,11,21,2025,5,18],
+			                 [1447,0,3,2025,5,29],
+			                 [1447,0,14,2025,6,10],
+			                 [1447,0,25,2025,6,21],
+			                 [1447,1,6,2025,7,1],
+			                 [1447,1,17,2025,7,12],
+			                 [1447,1,28,2025,7,23],
+			                 [1447,2,10,2025,8,3],
+			                 [1447,2,21,2025,8,14],
+			                 [1447,3,2,2025,8,25],
+			                 [1447,3,13,2025,9,6],
+			                 [1447,3,24,2025,9,17],
+			                 [1447,4,6,2025,9,28],
+			                 [1447,4,17,2025,10,8],
+			                 [1447,4,28,2025,10,19],
+			                 [1447,5,9,2025,10,30],
+			                 [1447,6,13,2026,0,2],
+			                 [1447,6,24,2026,0,13],
+			                 [1447,7,5,2026,0,24],
+			                 [1447,7,16,2026,1,4],
+			                 [1447,7,27,2026,1,15],
+			                 [1447,8,9,2026,1,26],
+			                 [1447,8,20,2026,2,9],
+			                 [1447,9,1,2026,2,20],
+			                 [1447,9,12,2026,2,31],
+			                 [1447,9,23,2026,3,11],
+			                 [1447,10,5,2026,3,22],
+			                 [1447,10,16,2026,4,3],
+			                 [1447,10,27,2026,4,14],
+			                 [1447,11,8,2026,4,25],
+			                 [1447,11,19,2026,5,5],
+			                 [1447,11,30,2026,5,16],
+			                 [1448,0,11,2026,5,27],
+			                 [1448,0,22,2026,6,8],
+			                 [1448,1,3,2026,6,19],
+			                 [1448,1,14,2026,6,30],
+			                 [1448,1,25,2026,7,10],
+			                 [1448,2,7,2026,7,21],
+			                 [1448,2,18,2026,8,1]
+			
+			];
+			
+			var idate,gdate;
+			
+			dojo.forEach(dateTable, function(d, i) {
+				
+					console.debug(d, "at index", i);
+				
+					idate = new dojox.date.islamic.Date(d[0],d[1],d[2], 15, 15, 10);
+					gdate = idate.toGregorian();
+					
+					t.is(0, dojo.date.compare(new Date(d[3], d[4], d[5], 15, 15, 10), gdate, "date"));
+				});
+
 			}
+		
 		},
 		{
 			name: "fromGregorian",
 			runTest: function(t) {
-				var dateIslamic = new dojox.date.islamic.Date();
-				var dateGregorian = new Date(2010, 2, 22, 15, 15, 10);
-				dateIslamic.fromGregorian(dateGregorian);
-				t.is(0, dojox.date.islamic.compare(new dojox.date.islamic.Date(1431, 3, 6, 15, 15, 10), dateIslamic, "date"));
+				
+				var dateTable = [
+				                 
+				                 [1997,1,1,1417,8,23],
+				                 [1997,1,12,1417,9,4],
+				                 [1997,1,23,1417,9,15] ,
+				                 [1997,2,6,1417,9,26],
+				                 [1997,2,17,1417,10,8],
+				                 [1997,2,28,1417,10,19],
+				                 [1997,3,8,1417,10,30],
+				                 [1997,3,19,1417,11,11],
+				                 [1997,3,30,1417,11,22],
+				                 [1997,4,11,1418,0,3],
+				                 [1997,4,22,1418,0,14],
+				                 [1997,5,2,1418,0,25],
+				                 [1997,5,13,1418,1,6],
+				                 [1997,5,24,1418,1,17],
+				                 [1997,6,5,1418,1,28],
+				                 [1997,6,16,1418,2,10],
+				                 [1997,6,27,1418,2,21],
+				                 [1997,7,7,1418,3,2],
+				                 [1997,7,18,1418,3,13],
+				                 [1997,7,29,1418,3,24],
+				                 [1997,8,9,1418,4,6],
+				                 [1997,8,20,1418,4,17],
+				                 [1997,9,1,1418,4,28],
+				                 [1997,9,12,1418,5,9],
+				                 [1997,9,23,1418,5,20],
+				                 [1997,10,3,1418,6,2],
+				                 [1997,10,14,1418,6,13],
+				                 [1997,10,25,1418,6,24],
+				                 [1997,11,6,1418,7,5],
+				                 [1997,11,17,1418,7,16],
+				                 [1997,11,28,1418,7,27],
+				                 [1998,0,8,1418,8,9],
+				                 [1998,0,19,1418,8,20],
+				                 [1998,0,30,1418,9,1],
+				                 [1998,1,10,1418,9,12],
+				                 [1998,1,21,1418,9,23],
+				                 [1998,2,4,1418,10,5],
+				                 [1998,2,15,1418,10,16],
+				                 [1998,2,26,1418,10,27],
+				                 [1998,3,6,1418,11,8],
+				                 [1998,3,17,1418,11,19],
+				                 [1998,3,28,1419,0,1],
+				                 [1998,4,9,1419,0,12],
+				                 [1998,4,20,1419,0,23],
+				                 [1998,4,31,1419,1,4],
+				                 [1998,5,11,1419,1,15],
+				                 [1998,5,22,1419,1,26],
+				                 [1998,6,3,1419,2,8],
+				                 [1998,6,14,1419,2,19],
+				                 [1998,6,25,1419,2,30],
+				                 [1998,7,5,1419,3,11],
+				                 [1998,7,16,1419,3,22],
+				                 [1998,7,27,1419,4,4],
+				                 [1998,8,7,1419,4,15],
+				                 [1998,8,18,1419,4,26],
+				                 [1998,8,29,1419,5,7],
+				                 [1998,9,10,1419,5,18],
+				                 [1998,9,21,1419,5,29],
+				                 [1998,10,1,1419,6,11],
+				                 [1998,10,12,1419,6,22],
+				                 [1998,10,23,1419,7,3],
+				                 [1998,11,4,1419,7,14],
+				                 [1998,11,15,1419,7,25],
+				                 [1998,11,26,1419,8,7],
+				                 [1999,0,6,1419,8,18],
+				                 [1999,0,17,1419,8,29],
+				                 [1999,0,28,1419,9,10],
+				                 [1999,1,8,1419,9,21],
+				                 [1999,1,19,1419,10,3],
+				                 [1999,2,2,1419,10,14],
+				                 [1999,2,13,1419,10,25],
+				                 [1999,2,24,1419,11,6],
+				                 [1999,3,4,1419,11,17],
+				                 [1999,3,15,1419,11,28],
+				                 [1999,3,26,1420,0,10],
+				                 [1999,4,7,1420,0,21],
+				                 [1999,4,18,1420,1,2],
+				                 [1999,4,29,1420,1,13],
+				                 [1999,5,9,1420,1,24],
+				                 [1999,5,20,1420,2,6],
+				                 [1999,6,1,1420,2,17],
+				                 [1999,6,12,1420,2,28],
+				                 [1999,6,23,1420,3,9],
+				                 [1999,7,3,1420,3,20],
+				                 [1999,7,14,1420,4,2],
+				                 [1999,7,25,1420,4,13],
+				                 [1999,8,5,1420,4,24],
+				                 [1999,8,16,1420,5,5],
+				                 [1999,8,27,1420,5,16],
+				                 [1999,9,8,1420,5,27],
+				                 [1999,9,19,1420,6,9],
+				                 [1999,9,30,1420,6,20],
+				                 [1999,10,10,1420,7,1],
+				                 [1999,10,21,1420,7,12],
+				                 [1999,11,2,1420,7,23],
+				                 [1999,11,13,1420,8,5],
+				                 [1999,11,24,1420,8,16],
+				                 [2000,0,4,1420,8,27],
+				                 [2000,0,15,1420,9,8],
+				                 [2000,0,26,1420,9,19],
+				                 [2000,1,6,1420,10,1],
+				                 [2000,1,17,1420,10,12],
+				                 [2000,1,28,1420,10,23],
+				                 [2000,2,10,1420,11,4],
+				                 [2000,2,21,1420,11,15],
+				                 [2000,3,1,1420,11,26],
+				                 [2000,3,12,1421,0,7],
+				                 [2000,3,23,1421,0,18],
+				                 [2000,4,4,1421,0,29],
+				                 [2000,4,15,1421,1,10],
+				                 [2000,4,26,1421,1,21],
+				                 [2000,5,6,1421,2,3],
+				                 [2000,5,17,1421,2,14],
+				                 [2000,5,28,1421,2,25],
+				                 [2000,6,9,1421,3,6],
+				                 [2000,6,20,1421,3,17],
+				                 [2000,6,31,1421,3,28],
+				                 [2000,7,11,1421,4,10],
+				                 [2000,7,22,1421,4,21],
+				                 [2000,8,2,1421,5,2],
+				                 [2000,8,13,1421,5,13],
+				                 [2000,8,24,1421,5,24],
+				                 [2000,9,5,1421,6,6],
+				                 [2000,9,16,1421,6,17],
+				                 [2000,9,27,1421,6,28],
+				                 [2000,10,7,1421,7,9],
+				                 [2000,10,18,1421,7,20],
+				                 [2000,10,29,1421,8,2],
+				                 [2000,11,10,1421,8,13],
+				                 [2000,11,21,1421,8,24],
+				                 [2001,0,1,1421,9,5],
+				                 [2001,0,12,1421,9,16],
+				                 [2001,0,23,1421,9,27],
+				                 [2001,1,3,1421,10,9],
+				                 [2001,1,14,1421,10,20],
+				                 [2001,1,25,1421,11,1],
+				                 [2001,2,8,1421,11,12],
+				                 [2001,2,19,1421,11,23],
+				                 [2001,2,30,1422,0,5],
+				                 [2001,3,10,1422,0,16],
+				                 [2001,3,21,1422,0,27],
+				                 [2001,4,2,1422,1,8],
+				                 [2001,4,13,1422,1,19],
+				                 [2001,4,24,1422,2,1],
+				                 [2001,5,4,1422,2,12],
+				                 [2001,5,15,1422,2,23],
+				                 [2001,5,26,1422,3,4],
+				                 [2001,6,7,1422,3,15],
+				                 [2001,6,18,1422,3,26],
+				                 [2001,6,29,1422,4,8],
+				                 [2001,7,9,1422,4,19],
+				                 [2001,7,20,1422,4,30],
+				                 [2001,7,31,1422,5,11],
+				                 [2001,8,11,1422,5,22],
+				                 [2001,8,22,1422,6,4],
+				                 [2001,9,3,1422,6,15],
+				                 [2001,9,14,1422,6,26],
+				                 [2001,9,25,1422,7,7],
+				                 [2001,10,5,1422,7,18],
+				                 [2001,10,16,1422,7,29],
+				                 [2001,10,27,1422,8,11],
+				                 [2001,11,8,1422,8,22],
+				                 [2001,11,19,1422,9,3],
+				                 [2001,11,30,1422,9,14],
+				                 [2002,0,10,1422,9,25],
+				                 [2002,0,21,1422,10,7],
+				                 [2002,1,1,1422,10,18],
+				                 [2002,1,12,1422,10,29],
+				                 [2002,1,23,1422,11,10],
+				                 [2002,2,6,1422,11,21],
+				                 [2002,2,17,1423,0,3],
+				                 [2002,2,28,1423,0,14],
+				                 [2002,3,8,1423,0,25],
+				                 [2002,3,19,1423,1,6],
+				                 [2002,3,30,1423,1,17],
+				                 [2002,4,11,1423,1,28],
+				                 [2002,4,22,1423,2,10],
+				                 [2002,5,2,1423,2,21],
+				                 [2002,5,13,1423,3,2],
+				                 [2002,5,24,1423,3,13],
+				                 [2002,6,5,1423,3,24],
+				                 [2002,6,16,1423,4,6],
+				                 [2002,6,27,1423,4,17],
+				                 [2002,7,7,1423,4,28],
+				                 [2002,7,18,1423,5,9],
+				                 [2002,7,29,1423,5,20],
+				                 [2002,8,9,1423,6,2],
+				                 [2002,8,20,1423,6,13],
+				                 [2002,9,1,1423,6,24],
+				                 [2002,9,12,1423,7,5],
+				                 [2002,9,23,1423,7,16],
+				                 [2002,10,3,1423,7,27],
+				                 [2002,10,14,1423,8,9],
+				                 [2002,10,25,1423,8,20],
+				                 [2002,11,6,1423,9,1],
+				                 [2002,11,17,1423,9,12],
+				                 [2002,11,28,1423,9,23],
+				                 [2003,0,8,1423,10,5],
+				                 [2003,0,19,1423,10,16],
+				                 [2003,0,30,1423,10,27],
+				                 [2003,1,10,1423,11,8],
+				                 [2003,1,21,1423,11,19],
+				                 [2003,2,4,1423,11,30],
+				                 [2003,2,15,1424,0,11],
+				                 [2003,2,26,1424,0,22],
+				                 [2003,3,6,1424,1,3],
+				                 [2003,3,17,1424,1,14],
+				                 [2003,3,28,1424,1,25],
+				                 [2003,4,9,1424,2,7],
+				                 [2003,4,20,1424,2,18],
+				                 [2003,4,31,1424,2,29],
+				                 [2003,5,11,1424,3,10],
+				                 [2003,5,22,1424,3,21],
+				                 [2003,6,3,1424,4,3],
+				                 [2003,6,14,1424,4,14],
+				                 [2003,6,25,1424,4,25],
+				                 [2003,7,5,1424,5,6],
+				                 [2003,7,16,1424,5,17],
+				                 [2003,7,27,1424,5,28],
+				                 [2003,8,7,1424,6,10],
+				                 [2003,8,18,1424,6,21],
+				                 [2003,8,29,1424,7,2],
+				                 [2003,9,10,1424,7,13],
+				                 [2003,9,21,1424,7,24],
+				                 [2003,10,1,1424,8,6],
+				                 [2003,10,12,1424,8,17],
+				                 [2003,10,23,1424,8,28],
+				                 [2003,11,4,1424,9,9],
+				                 [2003,11,15,1424,9,20],
+				                 [2003,11,26,1424,10,2],
+				                 [2004,0,6,1424,10,13],
+				                 [2004,0,17,1424,10,24],
+				                 [2004,0,28,1424,11,5],
+				                 [2004,1,8,1424,11,16],
+				                 [2004,1,19,1424,11,27],
+				                 [2004,2,1,1425,0,9],
+				                 [2004,2,12,1425,0,20],
+				                 [2004,2,23,1425,1,1],
+				                 [2004,3,3,1425,1,12],
+				                 [2004,3,14,1425,1,23],
+				                 [2004,3,25,1425,2,5],
+				                 [2004,4,6,1425,2,16],
+				                 [2004,4,17,1425,2,27],
+				                 [2004,4,28,1425,3,8],
+				                 [2004,5,8,1425,3,19],
+				                 [2004,5,19,1425,4,1],
+				                 [2004,5,30,1425,4,12],
+				                 [2004,6,11,1425,4,23],
+				                 [2004,6,22,1425,5,4],
+				                 [2004,7,2,1425,5,15],
+				                 [2004,7,13,1425,5,26],
+				                 [2004,7,24,1425,6,8],
+				                 [2004,8,4,1425,6,19],
+				                 [2004,8,15,1425,6,30],
+				                 [2004,8,26,1425,7,11],
+				                 [2004,9,7,1425,7,22],
+				                 [2004,9,18,1425,8,4],
+				                 [2004,9,29,1425,8,15],
+				                 [2004,10,9,1425,8,26],
+				                 [2004,10,20,1425,9,7],
+				                 [2004,11,1,1425,9,18],
+				                 [2004,11,12,1425,9,29],
+				                 [2004,11,23,1425,10,11],
+				                 [2005,0,3,1425,10,22],
+				                 [2005,0,14,1425,11,3],
+				                 [2005,0,25,1425,11,14],
+				                 [2005,1,5,1425,11,25],
+				                 [2005,1,16,1426,0,7],
+				                 [2005,1,27,1426,0,18],
+				                 [2005,2,10,1426,0,29],
+				                 [2005,2,21,1426,1,10],
+				                 [2005,3,1,1426,1,21],
+				                 [2005,3,12,1426,2,3],
+				                 [2005,3,23,1426,2,14],
+				                 [2005,4,4,1426,2,25],
+				                 [2005,4,15,1426,3,6],
+				                 [2005,4,26,1426,3,17],
+				                 [2005,5,6,1426,3,28],
+				                 [2005,5,17,1426,4,10],
+				                 [2005,5,28,1426,4,21],
+				                 [2005,6,9,1426,5,2],
+				                 [2005,6,20,1426,5,13],
+				                 [2005,6,31,1426,5,24],
+				                 [2005,7,11,1426,6,6],
+				                 [2005,7,22,1426,6,17],
+				                 [2005,8,2,1426,6,28],
+				                 [2005,8,13,1426,7,9],
+				                 [2005,8,24,1426,7,20],
+				                 [2005,9,5,1426,8,2],
+				                 [2005,9,16,1426,8,13],
+				                 [2005,9,27,1426,8,24],
+				                 [2005,10,7,1426,9,5],
+				                 [2005,10,18,1426,9,16],
+				                 [2005,10,29,1426,9,27],
+				                 [2005,11,10,1426,10,9],
+				                 [2005,11,21,1426,10,20],
+				                 [2006,0,1,1426,11,1],
+				                 [2006,0,12,1426,11,12],
+				                 [2006,0,23,1426,11,23],
+				                 [2006,1,3,1427,0,4],
+				                 [2006,1,14,1427,0,15],
+				                 [2006,1,25,1427,0,26],
+				                 [2006,2,8,1427,1,7],
+				                 [2006,2,19,1427,1,18],
+				                 [2006,2,30,1427,1,29],
+				                 [2006,3,10,1427,2,11],
+				                 [2006,3,21,1427,2,22],
+				                 [2006,4,2,1427,3,3],
+				                 [2006,4,13,1427,3,14],
+				                 [2006,4,24,1427,3,25],
+				                 [2006,5,4,1427,4,7],
+				                 [2006,5,15,1427,4,18],
+				                 [2006,5,26,1427,4,29],
+				                 [2006,6,7,1427,5,10],
+				                 [2006,6,18,1427,5,21],
+				                 [2006,6,29,1427,6,3],
+				                 [2006,7,9,1427,6,14],
+				                 [2006,7,20,1427,6,25],
+				                 [2006,7,31,1427,7,6],
+				                 [2006,8,11,1427,7,17],
+				                 [2006,8,22,1427,7,28],
+				                 [2006,9,3,1427,8,10],
+				                 [2006,9,14,1427,8,21],
+				                 [2006,9,25,1427,9,2],
+				                 [2006,10,5,1427,9,13],
+				                 [2006,10,16,1427,9,24],
+				                 [2006,10,27,1427,10,6],
+				                 [2006,11,8,1427,10,17],
+				                 [2006,11,19,1427,10,28],
+				                 [2006,11,30,1427,11,9],
+				                 [2007,0,10,1427,11,20],
+				                 [2007,0,21,1428,0,2],
+				                 [2007,1,1,1428,0,13],
+				                 [2007,1,12,1428,0,24],
+				                 [2007,1,23,1428,1,5],
+				                 [2007,2,6,1428,1,16],
+				                 [2007,2,17,1428,1,27],
+				                 [2007,2,28,1428,2,9],
+				                 [2007,3,8,1428,2,20],
+				                 [2007,3,19,1428,3,1],
+				                 [2007,3,30,1428,3,12],
+				                 [2007,4,11,1428,3,23],
+				                 [2007,4,22,1428,4,5],
+				                 [2007,5,2,1428,4,16],
+				                 [2007,5,13,1428,4,27],
+				                 [2007,5,24,1428,5,8],
+				                 [2007,6,5,1428,5,19],
+				                 [2007,6,16,1428,6,1],
+				                 [2007,6,27,1428,6,12],
+				                 [2007,7,7,1428,6,23],
+				                 [2007,7,18,1428,7,4],
+				                 [2007,7,29,1428,7,15],
+				                 [2007,8,9,1428,7,26],
+				                 [2007,8,20,1428,8,8],
+				                 [2007,9,1,1428,8,19],
+				                 [2007,9,12,1428,8,30],
+				                 [2007,9,23,1428,9,11],
+				                 [2007,10,3,1428,9,22],
+				                 [2007,10,14,1428,10,4],
+				                 [2007,10,25,1428,10,15],
+				                 [2007,11,6,1428,10,26],
+				                 [2007,11,17,1428,11,7],
+				                 [2007,11,28,1428,11,18],
+				                 [2008,0,8,1428,11,29],
+				                 [2008,0,19,1429,0,10],
+				                 [2008,0,30,1429,0,21],
+				                 [2008,1,10,1429,1,2],
+				                 [2008,1,21,1429,1,13],
+				                 [2008,2,3,1429,1,24],
+				                 [2008,2,14,1429,2,6],
+				                 [2008,2,25,1429,2,17],
+				                 [2008,3,5,1429,2,28],
+				                 [2008,3,16,1429,3,9],
+				                 [2008,3,27,1429,3,20],
+				                 [2008,4,8,1429,4,2],
+				                 [2008,4,19,1429,4,13],
+				                 [2008,4,30,1429,4,24],
+				                 [2008,5,10,1429,5,5],
+				                 [2008,5,21,1429,5,16],
+				                 [2008,6,2,1429,5,27],
+				                 [2008,6,13,1429,6,9],
+				                 [2008,6,24,1429,6,20],
+				                 [2008,7,4,1429,7,1],
+				                 [2008,7,15,1429,7,12],
+				                 [2008,7,26,1429,7,23],
+				                 [2008,8,6,1429,8,5],
+				                 [2008,8,17,1429,8,16],
+				                 [2008,8,28,1429,8,27],
+				                 [2008,9,9,1429,9,8],
+				                 [2008,9,20,1429,9,19],
+				                 [2008,9,31,1429,10,1],
+				                 [2008,10,11,1429,10,12],
+				                 [2008,10,22,1429,10,23],
+				                 [2008,11,3,1429,11,4],
+				                 [2008,11,14,1429,11,15],
+				                 [2008,11,25,1429,11,26],
+				                 [2009,0,5,1430,0,8],
+				                 [2009,0,16,1430,0,19],
+				                 [2009,0,27,1430,0,30],
+				                 [2009,1,7,1430,1,11],
+				                 [2009,1,18,1430,1,22],
+				                 [2009,2,1,1430,2,4],
+				                 [2009,2,12,1430,2,15],
+				                 [2009,2,23,1430,2,26],
+				                 [2009,3,3,1430,3,7],
+				                 [2009,3,14,1430,3,18],
+				                 [2009,3,25,1430,3,29],
+				                 [2009,4,6,1430,4,11],
+				                 [2009,4,17,1430,4,22],
+				                 [2009,4,28,1430,5,3],
+				                 [2009,5,8,1430,5,14],
+				                 [2009,5,19,1430,5,25],
+				                 [2009,5,30,1430,6,7],
+				                 [2009,6,11,1430,6,18],
+				                 [2009,6,22,1430,6,29],
+				                 [2009,7,2,1430,7,10],
+				                 [2009,7,13,1430,7,21],
+				                 [2009,7,24,1430,8,3],
+				                 [2009,8,4,1430,8,14],
+				                 [2009,8,15,1430,8,25],
+				                 [2009,8,26,1430,9,6],
+				                 [2009,9,7,1430,9,17],
+				                 [2009,9,18,1430,9,28],
+				                 [2009,9,29,1430,10,10],
+				                 [2009,10,9,1430,10,21],
+				                 [2009,10,20,1430,11,2],
+				                 [2009,11,1,1430,11,13],
+				                 [2009,11,12,1430,11,24],
+				                 [2009,11,23,1431,0,6],
+				                 [2010,0,3,1431,0,17],
+				                 [2010,0,14,1431,0,28],
+				                 [2010,0,25,1431,1,9],
+				                 [2010,1,5,1431,1,20],
+				                 [2010,1,16,1431,2,2],
+				                 [2010,1,27,1431,2,13],
+				                 [2010,2,10,1431,2,24],
+				                 [2010,2,21,1431,3,5],
+				                 [2010,3,1,1431,3,16],
+				                 [2010,3,12,1431,3,27],
+				                 [2010,3,23,1431,4,9],
+				                 [2010,4,4,1431,4,20],
+				                 [2010,4,15,1431,5,1],
+				                 [2010,4,26,1431,5,12],
+				                 [2010,5,6,1431,5,23],
+				                 [2010,5,17,1431,6,5],
+				                 [2010,5,28,1431,6,16],
+				                 [2010,6,9,1431,6,27],
+				                 [2010,6,20,1431,7,8],
+				                 [2010,6,31,1431,7,19],
+				                 [2010,7,11,1431,8,1],
+				                 [2010,7,22,1431,8,12],
+				                 [2010,8,2,1431,8,23],
+				                 [2010,8,13,1431,9,4],
+				                 [2010,8,24,1431,9,15],
+				                 [2010,9,5,1431,9,26],
+				                 [2010,9,16,1431,10,8],
+				                 [2010,9,27,1431,10,19],
+				                 [2010,10,7,1431,10,30],
+				                 [2010,10,18,1431,11,11],
+				                 [2010,10,29,1431,11,22],
+				                 [2010,11,10,1432,0,3],
+				                 [2010,11,21,1432,0,14],
+				                 [2011,0,1,1432,0,25],
+				                 [2011,0,12,1432,1,6],
+				                 [2011,0,23,1432,1,17],
+				                 [2011,1,3,1432,1,28],
+				                 [2011,1,14,1432,2,10],
+				                 [2011,1,25,1432,2,21],
+				                 [2011,2,8,1432,3,2],
+				                 [2011,2,19,1432,3,13],
+				                 [2011,2,30,1432,3,24],
+				                 [2011,3,10,1432,4,6],
+				                 [2011,3,21,1432,4,17],
+				                 [2011,4,2,1432,4,28],
+				                 [2011,4,13,1432,5,9],
+				                 [2011,4,24,1432,5,20],
+				                 [2011,5,4,1432,6,2],
+				                 [2011,5,15,1432,6,13],
+				                 [2011,5,26,1432,6,24],
+				                 [2011,6,7,1432,7,5],
+				                 [2011,6,18,1432,7,16],
+				                 [2011,6,29,1432,7,27],
+				                 [2011,7,9,1432,8,9],
+				                 [2011,7,20,1432,8,20],
+				                 [2011,7,31,1432,9,1],
+				                 [2011,8,11,1432,9,12],
+				                 [2011,8,22,1432,9,23],
+				                 [2011,9,3,1432,10,5],
+				                 [2011,9,14,1432,10,16],
+				                 [2011,9,25,1432,10,27],
+				                 [2011,10,5,1432,11,8],
+				                 [2011,10,16,1432,11,19],
+				                 [2011,10,27,1433,0,1],
+				                 [2011,11,8,1433,0,12],
+				                 [2011,11,19,1433,0,23],
+				                 [2011,11,30,1433,1,4],
+				                 [2012,0,10,1433,1,15],
+				                 [2012,0,21,1433,1,26],
+				                 [2012,1,1,1433,2,8],
+				                 [2012,1,12,1433,2,19],
+				                 [2012,1,23,1433,2,30],
+				                 [2012,2,5,1433,3,11],
+				                 [2012,2,16,1433,3,22],
+				                 [2012,2,27,1433,4,4],
+				                 [2012,3,7,1433,4,15],
+				                 [2012,3,18,1433,4,26],
+				                 [2012,3,29,1433,5,7],
+				                 [2012,4,10,1433,5,18],
+				                 [2012,4,21,1433,5,29],
+				                 [2012,5,1,1433,6,11],
+				                 [2012,5,12,1433,6,22],
+				                 [2012,5,23,1433,7,3],
+				                 [2012,6,4,1433,7,14],
+				                 [2012,6,15,1433,7,25],
+				                 [2012,6,26,1433,8,7],
+				                 [2012,7,6,1433,8,18],
+				                 [2012,7,17,1433,8,29],
+				                 [2012,7,28,1433,9,10],
+				                 [2012,8,8,1433,9,21],
+				                 [2012,8,19,1433,10,3],
+				                 [2012,8,30,1433,10,14],
+				                 [2012,9,11,1433,10,25],
+				                 [2012,9,22,1433,11,6],
+				                 [2012,10,2,1433,11,17],
+				                 [2012,10,13,1433,11,28],
+				                 [2012,10,24,1434,0,10],
+				                 [2012,11,5,1434,0,21],
+				                 [2012,11,16,1434,1,2],
+				                 [2012,11,27,1434,1,13],
+				                 [2013,0,7,1434,1,24],
+				                 [2013,0,18,1434,2,6],
+				                 [2013,0,29,1434,2,17],
+				                 [2013,1,9,1434,2,28],
+				                 [2013,1,20,1434,3,9],
+				                 [2013,2,3,1434,3,20],
+				                 [2013,2,14,1434,4,2],
+				                 [2013,2,25,1434,4,13],
+				                 [2013,3,5,1434,4,24],
+				                 [2013,3,16,1434,5,5],
+				                 [2013,3,27,1434,5,16],
+				                 [2013,4,8,1434,5,27],
+				                 [2013,4,19,1434,6,9],
+				                 [2013,4,30,1434,6,20],
+				                 [2013,5,10,1434,7,1],
+				                 [2013,5,21,1434,7,12],
+				                 [2013,6,2,1434,7,23],
+				                 [2013,6,13,1434,8,5],
+				                 [2013,6,24,1434,8,16],
+				                 [2013,7,4,1434,8,27],
+				                 [2013,7,15,1434,9,8],
+				                 [2013,7,26,1434,9,19],
+				                 [2013,8,6,1434,10,1],
+				                 [2013,8,17,1434,10,12],
+				                 [2013,8,28,1434,10,23],
+				                 [2013,9,9,1434,11,4],
+				                 [2013,9,20,1434,11,15],
+				                 [2013,9,31,1434,11,26],
+				                 [2013,10,11,1435,0,7],
+				                 [2013,10,22,1435,0,18],
+				                 [2013,11,3,1435,0,29],
+				                 [2013,11,14,1435,1,10],
+				                 [2013,11,25,1435,1,21],
+				                 [2014,0,5,1435,2,3],
+				                 [2014,0,16,1435,2,14],
+				                 [2014,0,27,1435,2,25],
+				                 [2014,1,7,1435,3,6],
+				                 [2014,1,18,1435,3,17],
+				                 [2014,2,1,1435,3,28],
+				                 [2014,2,12,1435,4,10],
+				                 [2014,2,23,1435,4,21],
+				                 [2014,3,3,1435,5,2],
+				                 [2014,3,14,1435,5,13],
+				                 [2014,3,25,1435,5,24],
+				                 [2014,4,6,1435,6,6],
+				                 [2014,4,17,1435,6,17],
+				                 [2014,4,28,1435,6,28],
+				                 [2014,5,8,1435,7,9],
+				                 [2014,5,19,1435,7,20],
+				                 [2014,5,30,1435,8,2],
+				                 [2014,6,11,1435,8,13],
+				                 [2014,6,22,1435,8,24],
+				                 [2014,7,2,1435,9,5],
+				                 [2014,7,13,1435,9,16],
+				                 [2014,7,24,1435,9,27],
+				                 [2014,8,4,1435,10,9],
+				                 [2014,8,15,1435,10,20],
+				                 [2014,8,26,1435,11,1],
+				                 [2014,9,7,1435,11,12],
+				                 [2014,9,18,1435,11,23],
+				                 [2014,9,29,1436,0,5],
+				                 [2014,10,9,1436,0,16],
+				                 [2014,10,20,1436,0,27],
+				                 [2014,11,1,1436,1,8],
+				                 [2014,11,12,1436,1,19],
+				                 [2014,11,23,1436,2,1],
+				                 [2015,0,3,1436,2,12],
+				                 [2015,0,14,1436,2,23],
+				                 [2015,0,25,1436,3,4],
+				                 [2015,1,5,1436,3,15],
+				                 [2015,1,16,1436,3,26],
+				                 [2015,1,27,1436,4,8],
+				                 [2015,2,10,1436,4,19],
+				                 [2015,2,21,1436,4,30],
+				                 [2015,3,1,1436,5,11],
+				                 [2015,3,12,1436,5,22],
+				                 [2015,3,23,1436,6,4],
+				                 [2015,4,4,1436,6,15],
+				                 [2015,4,15,1436,6,26],
+				                 [2015,4,26,1436,7,7],
+				                 [2015,5,6,1436,7,18],
+				                 [2015,5,17,1436,7,29],
+				                 [2015,5,28,1436,8,11],
+				                 [2015,6,9,1436,8,22],
+				                 [2015,6,20,1436,9,3],
+				                 [2015,6,31,1436,9,14],
+				                 [2015,7,11,1436,9,25],
+				                 [2015,7,22,1436,10,7],
+				                 [2015,8,2,1436,10,18],
+				                 [2015,8,13,1436,10,29],
+				                 [2015,8,24,1436,11,10],
+				                 [2015,9,5,1436,11,21],
+				                 [2015,9,16,1437,0,2],
+				                 [2015,9,27,1437,0,13],
+				                 [2015,10,7,1437,0,24],
+				                 [2015,10,18,1437,1,5],
+				                 [2015,10,29,1437,1,16],
+				                 [2015,11,10,1437,1,27],
+				                 [2015,11,21,1437,2,9],
+				                 [2016,0,1,1437,2,20],
+				                 [2016,0,12,1437,3,1],
+				                 [2016,0,23,1437,3,12],
+				                 [2016,1,3,1437,3,23],
+				                 [2016,1,14,1437,4,5],
+				                 [2016,1,25,1437,4,16],
+				                 [2016,2,7,1437,4,27],
+				                 [2016,2,18,1437,5,8],
+				                 [2016,2,29,1437,5,19],
+				                 [2016,3,9,1437,6,1],
+				                 [2016,3,20,1437,6,12],
+				                 [2016,4,1,1437,6,23],
+				                 [2016,4,12,1437,7,4],
+				                 [2016,4,23,1437,7,15],
+				                 [2016,5,3,1437,7,26],
+				                 [2016,5,14,1437,8,8],
+				                 [2016,5,25,1437,8,19],
+				                 [2016,6,6,1437,8,30],
+				                 [2016,6,17,1437,9,11],
+				                 [2016,6,28,1437,9,22],
+				                 [2016,7,8,1437,10,4],
+				                 [2016,7,19,1437,10,15],
+				                 [2016,7,30,1437,10,26],
+				                 [2016,8,10,1437,11,7],
+				                 [2016,8,21,1437,11,18],
+				                 [2016,9,2,1437,11,29],
+				                 [2016,9,13,1438,0,11],
+				                 [2016,9,24,1438,0,22],
+				                 [2016,10,4,1438,1,3],
+				                 [2016,10,15,1438,1,14],
+				                 [2016,10,26,1438,1,25],
+				                 [2016,11,7,1438,2,7],
+				                 [2016,11,18,1438,2,18],
+				                 [2016,11,29,1438,2,29],
+				                 [2017,0,9,1438,3,10],
+				                 [2017,0,20,1438,3,21],
+				                 [2017,0,31,1438,4,3],
+				                 [2017,1,11,1438,4,14],
+				                 [2017,1,22,1438,4,25],
+				                 [2017,2,5,1438,5,6],
+				                 [2017,2,16,1438,5,17],
+				                 [2017,2,27,1438,5,28],
+				                 [2017,3,7,1438,6,10],
+				                 [2017,3,18,1438,6,21],
+				                 [2017,3,29,1438,7,2],
+				                 [2017,4,10,1438,7,13],
+				                 [2017,4,21,1438,7,24],
+				                 [2017,5,1,1438,8,6],
+				                 [2017,5,12,1438,8,17],
+				                 [2017,5,23,1438,8,28],
+				                 [2017,6,4,1438,9,9],
+				                 [2017,6,15,1438,9,20],
+				                 [2017,6,26,1438,10,2],
+				                 [2017,7,6,1438,10,13],
+				                 [2017,7,17,1438,10,24],
+				                 [2017,7,28,1438,11,5],
+				                 [2017,8,8,1438,11,16],
+				                 [2017,8,19,1438,11,27],
+				                 [2017,8,30,1439,0,9],
+				                 [2017,9,11,1439,0,20],
+				                 [2017,9,22,1439,1,1],
+				                 [2017,10,2,1439,1,12],
+				                 [2017,10,13,1439,1,23],
+				                 [2017,10,24,1439,2,5],
+				                 [2017,11,5,1439,2,16],
+				                 [2017,11,16,1439,2,27],
+				                 [2017,11,27,1439,3,8],
+				                 [2018,0,7,1439,3,19],
+				                 [2018,0,18,1439,4,1],
+				                 [2018,0,29,1439,4,12],
+				                 [2018,1,9,1439,4,23],
+				                 [2018,1,20,1439,5,4],
+				                 [2018,2,3,1439,5,15],
+				                 [2018,2,14,1439,5,26],
+				                 [2018,2,25,1439,6,8],
+				                 [2018,3,5,1439,6,19],
+				                 [2018,3,16,1439,6,30],
+				                 [2018,3,27,1439,7,11],
+				                 [2018,4,8,1439,7,22],
+				                 [2018,4,19,1439,8,4],
+				                 [2018,4,30,1439,8,15],
+				                 [2018,5,10,1439,8,26],
+				                 [2018,5,21,1439,9,7],
+				                 [2018,6,2,1439,9,18],
+				                 [2018,6,13,1439,9,29],
+				                 [2018,6,24,1439,10,11],
+				                 [2018,7,4,1439,10,22],
+				                 [2018,7,15,1439,11,3],
+				                 [2018,7,26,1439,11,14],
+				                 [2018,8,6,1439,11,25],
+				                 [2018,8,17,1440,0,6],
+				                 [2018,8,28,1440,0,17],
+				                 [2018,9,9,1440,0,28],
+				                 [2018,9,20,1440,1,9],
+				                 [2018,9,31,1440,1,20],
+				                 [2018,10,11,1440,2,2],
+				                 [2018,10,22,1440,2,13],
+				                 [2018,11,3,1440,2,24],
+				                 [2018,11,14,1440,3,5],
+				                 [2018,11,25,1440,3,16],
+				                 [2019,0,5,1440,3,27],
+				                 [2019,0,16,1440,4,9],
+				                 [2019,0,27,1440,4,20],
+				                 [2019,1,7,1440,5,1],
+				                 [2019,1,18,1440,5,12],
+				                 [2019,2,1,1440,5,23],
+				                 [2019,2,12,1440,6,5],
+				                 [2019,2,23,1440,6,16],
+				                 [2019,3,3,1440,6,27],
+				                 [2019,3,14,1440,7,8],
+				                 [2019,3,25,1440,7,19],
+				                 [2019,4,6,1440,8,1],
+				                 [2019,4,17,1440,8,12],
+				                 [2019,4,28,1440,8,23],
+				                 [2019,5,8,1440,9,4],
+				                 [2019,5,19,1440,9,15],
+				                 [2019,5,30,1440,9,26],
+				                 [2019,6,11,1440,10,8],
+				                 [2019,6,22,1440,10,19],
+				                 [2019,7,2,1440,10,30],
+				                 [2019,7,13,1440,11,11],
+				                 [2019,7,24,1440,11,22],
+				                 [2019,8,4,1441,0,4],
+				                 [2019,8,15,1441,0,15],
+				                 [2019,8,26,1441,0,26],
+				                 [2019,9,7,1441,1,7],
+				                 [2019,9,18,1441,1,18],
+				                 [2019,9,29,1441,1,29],
+				                 [2019,10,9,1441,2,11],
+				                 [2019,10,20,1441,2,22],
+				                 [2019,11,1,1441,3,3],
+				                 [2019,11,12,1441,3,14],
+				                 [2019,11,23,1441,3,25],
+				                 [2020,0,3,1441,4,7],
+				                 [2020,0,14,1441,4,18],
+				                 [2020,0,25,1441,4,29],
+				                 [2020,1,5,1441,5,10],
+				                 [2020,1,16,1441,5,21],
+				                 [2020,1,27,1441,6,3],
+				                 [2020,2,9,1441,6,14],
+				                 [2020,2,20,1441,6,25],
+				                 [2020,2,31,1441,7,6],
+				                 [2020,3,11,1441,7,17],
+				                 [2020,3,22,1441,7,28],
+				                 [2020,4,3,1441,8,10],
+				                 [2020,4,14,1441,8,21],
+				                 [2020,4,25,1441,9,2],
+				                 [2020,5,5,1441,9,13],
+				                 [2020,5,16,1441,9,24],
+				                 [2020,5,27,1441,10,6],
+				                 [2020,6,8,1441,10,17],
+				                 [2020,6,19,1441,10,28],
+				                 [2020,6,30,1441,11,9],
+				                 [2020,7,10,1441,11,20],
+				                 [2020,7,21,1442,0,2],
+				                 [2020,8,1,1442,0,13],
+				                 [2020,8,12,1442,0,24],
+				                 [2020,8,23,1442,1,5],
+				                 [2020,9,4,1442,1,16],
+				                 [2020,9,15,1442,1,27],
+				                 [2020,9,26,1442,2,9],
+				                 [2020,10,6,1442,2,20],
+				                 [2020,10,17,1442,3,1],
+				                 [2020,10,28,1442,3,12],
+				                 [2020,11,9,1442,3,23],
+				                 [2020,11,20,1442,4,5],
+				                 [2020,11,31,1442,4,16], 
+				                 [2021,0,11,1442,4,27],
+				                 [2021,0,22,1442,5,8],
+				                 [2021,1,2,1442,5,19],
+				                 [2021,1,13,1442,6,1],
+				                 [2021,1,24,1442,6,12],
+				                 [2021,2,7,1442,6,23],
+				                 [2021,2,18,1442,7,4],
+				                 [2021,2,29,1442,7,15],
+				                 [2021,3,9,1442,7,26],
+				                 [2021,3,20,1442,8,8],
+				                 [2021,4,1,1442,8,19],
+				                 [2021,4,12,1442,8,30],
+				                 [2021,4,23,1442,9,11],
+				                 [2021,5,3,1442,9,22],
+				                 [2021,5,14,1442,10,4],
+				                 [2021,5,25,1442,10,15],
+				                 [2021,6,6,1442,10,26],
+				                 [2021,6,17,1442,11,7],
+				                 [2021,6,28,1442,11,18],
+				                [2021,7,8,1442,11,29],
+				                 [2021,7,19,1443,0,10],
+				                 [2021,7,30,1443,0,21],
+				                 [2021,8,10,1443,1,2],
+				                 [2021,8,21,1443,1,13],
+				                 [2021,9,2,1443,1,24],
+				                 [2021,9,13,1443,2,6],
+				                 [2021,9,24,1443,2,17],
+				                 [2021,10,4,1443,2,28],
+				                 [2021,10,15,1443,3,9],
+				                 [2021,10,26,1443,3,20],
+				                 [2021,11,7,1443,4,2],
+				                 [2021,11,18,1443,4,13],
+				                 [2021,11,29,1443,4,24],
+				                 [2022,0,9,1443,5,5],
+				                 [2022,0,20,1443,5,16],
+				                 [2022,0,31,1443,5,27],
+				                 [2022,1,11,1443,6,9],
+				                 [2022,1,22,1443,6,20],
+				                 [2022,2,5,1443,7,1],
+				                 [2022,2,16,1443,7,12],
+				                 [2022,2,27,1443,7,23],
+				                 [2022,3,7,1443,8,5],
+				                 [2022,3,18,1443,8,16],
+				                 [2022,3,29,1443,8,27],
+				                 [2022,4,10,1443,9,8],
+				                 [2022,4,21,1443,9,19],
+				                 [2022,5,1,1443,10,1],
+				                 [2022,5,12,1443,10,12],
+				                 [2022,5,23,1443,10,23],
+				                 [2022,6,4,1443,11,4],
+				                 [2022,6,15,1443,11,15],
+				                 [2022,6,26,1443,11,26],
+				                 [2022,7,6,1444,0,8],
+				                 [2022,7,17,1444,0,19],
+				                 [2022,7,28,1444,0,30],
+				                 [2022,8,8,1444,1,11],
+				                 [2022,8,19,1444,1,22],
+				                 [2022,8,30,1444,2,4],
+				                 [2022,9,11,1444,2,15],
+				                 [2022,9,22,1444,2,26],
+				                 [2022,10,2,1444,3,7],
+				                 [2022,10,13,1444,3,18],
+				                 [2022,10,24,1444,3,29],
+				                 [2022,11,5,1444,4,11],
+				                 [2022,11,16,1444,4,22],
+				                 [2022,11,27,1444,5,3],
+				                 [2023,0,7,1444,5,14],
+				                 [2023,0,18,1444,5,25],
+				                 [2023,0,29,1444,6,7],
+				                 [2023,1,9,1444,6,18],
+				                 [2023,1,20,1444,6,29],
+				                 [2023,2,3,1444,7,10],
+				                 [2023,2,14,1444,7,21],
+				                 [2023,2,25,1444,8,3],
+				                 [2023,3,5,1444,8,14],
+				                 [2023,3,16,1444,8,25],
+				                 [2023,3,27,1444,9,6],
+				                 [2023,4,8,1444,9,17],
+				                 [2023,4,19,1444,9,28],
+				                 [2023,4,30,1444,10,10],
+				                 [2023,5,10,1444,10,21],
+				                 [2023,5,21,1444,11,2],
+				                 [2023,6,2,1444,11,13],
+				                 [2023,6,13,1444,11,24],
+				                 [2023,6,24,1445,0,6],
+				                 [2023,7,4,1445,0,17],
+				                 [2023,7,15,1445,0,28],
+				                 [2023,7,26,1445,1,9],
+				                 [2023,8,6,1445,1,20],
+				                 [2023,8,17,1445,2,2],
+				                 [2023,8,28,1445,2,13],
+				                 [2023,9,9,1445,2,24],
+				                 [2023,9,20,1445,3,5],
+				                 [2023,9,31,1445,3,16],
+				                 [2023,10,11,1445,3,27],
+				                 [2023,10,22,1445,4,9],
+				                 [2023,11,3,1445,4,20],
+				                 [2023,11,14,1445,5,1], 
+				                 [2023,11,25,1445,5,12],
+				                 [2024,0,5,1445,5,23],
+				                 [2024,0,16,1445,6,5],
+				                 [2024,0,27,1445,6,16],
+				                 [2024,1,7,1445,6,27],
+				                 [2024,1,18,1445,7,8],
+				                 [2024,1,29,1445,7,19],
+				                 [2024,2,11,1445,8,1],
+				                 [2024,2,22,1445,8,12],
+				                 [2024,3,2,1445,8,23],
+				                 [2024,3,13,1445,9,4],
+				                 [2024,3,24,1445,9,15],
+				                 [2024,4,5,1445,9,26],
+				                 [2024,4,16,1445,10,8],
+				                 [2024,4,27,1445,10,19], 
+				                 [2024,5,7,1445,10,30], 
+								 [2024,5,18,1445,11,11],
+				                 [2010,2,22,1431,3,6]
+				                 ];
+				
+				var idate, gdate;
+				
+				dojo.forEach(dateTable, function(d, i) {
+					
+					//console.debug(d, "at index", i);
+				
+					gdate = new Date(d[0],d[1],d[2],15,15,10);
+					
+					idate = new dojox.date.islamic.Date();
+					idate.fromGregorian(gdate);
+					
+					
+					t.is(0, dojox.date.islamic.compare(new dojox.date.islamic.Date(d[3], d[4], d[5], 15, 15, 10), idate, "date"));
+				});
 			}
 		},
 		{
@@ -58,7 +1861,14 @@ tests.register("dojox.date.tests.islamic.Date",
 					[1431, 3, 23, 4],
 					[1431, 6, 21, 6],
 					[1431, 6, 22, 0],
-					[1431, 7, 15, 2]
+					[1431, 7, 15, 2],
+					[1202,1,1,1],
+			        [1202,1,8,1],
+			        [1202,1,15,1],
+			        [1202,1,18,4],
+			        [1202,1,19,5],
+			        [1202,1,20,5]
+								
 				];
 				dojo.forEach(dateTable, function(d, i) {
 					var date = new dojox.date.islamic.Date(d[0], d[1], d[2]);
@@ -100,9 +1910,16 @@ tests.register("dojox.date.tests.islamic.Date",
 						[1431, 3, 1431, 5],
 						[1431, 3, 1431, 0],
 						[1431, 1, 1431, 2],
-						[1431, 9, 1431, 8]
+						[1431, 9, 1431, 8],
+						[1432, 7, 1432, 11],
+						[1433, 8, 1434, 0],
+						[1433, 0, 1432, 6],
+						[1434, 0, 1433, 11],
+						[1433, 0, 1432, 11],
+						[1432, 0, 1431, 11],
+						[1431, 0, 1430, 10]
 					];
-				var add = [24, 60, 12, -24, -24, 2, -2, 2, -3, 1, -1];
+				var add = [24, 60, 12, -24, -24, 2, -2, 2, -3, 1, -1, 4, 4, -6, -1, -1, -1, -2];
 
 				var dateHijriStart, dateHijriEnd, res, dateHijriRes;
 				dojo.forEach(start, function(s, i) {
@@ -127,7 +1944,8 @@ tests.register("dojox.date.tests.islamic.Date",
 				var dateIslamic = new dojox.date.islamic.Date(1431, 4, 6);
 
 
-				var amouts = [2, 5, 6, 7, 8, 12, 18, 20, 24, 50, -3, -4, -5, -6, -7, -8, -9, -10, -50, 200, -200];
+				var amouts = [2, 5, 6, 7, 8, 12, 18, 20, 24, 50, -3, -4, -5, -6, -7, -8, -9, -10, -50, 200, -200, 29, -29, 1, -1,
+				              23, 25];
 				var dateIslamicAdd;
 
 				dojo.forEach(amouts, function(amount, i) {
@@ -144,19 +1962,19 @@ tests.register("dojox.date.tests.islamic.Date",
 					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "weekday"));
 
 					dateIslamicAdd = dojox.date.islamic.add(dateIslamic, "day", amount)
-					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "day"));
-
+					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "day")); 
+			 
 					dateIslamicAdd = dojox.date.islamic.add(dateIslamic, "hour", amount);
-					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "hour"));
+					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "hour")); 
 
 					dateIslamicAdd = dojox.date.islamic.add(dateIslamic, "minute", amount);
-					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "minute"));
+					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "minute")); 
 
 					dateIslamicAdd = dojox.date.islamic.add(dateIslamic, "second", amount);
-					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "second"));
+					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "second")); 
 
 					dateIslamicAdd = dojox.date.islamic.add(dateIslamic, "millisecond", amount);
-					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "millisecond"));
+					t.is(amount, dojox.date.islamic.difference(dateIslamic, dateIslamicAdd, "millisecond")); 
 				});
 
 				var dateIslamicDiff = new dojox.date.islamic.Date(1431, 4, 7);
diff --git a/dojox/date/tests/module.js b/dojox/date/tests/module.js
index 3eeb05c..90e5c49 100644
--- a/dojox/date/tests/module.js
+++ b/dojox/date/tests/module.js
@@ -6,6 +6,7 @@ try{
 	dojo.require("dojox.date.tests.relative");
 	dojo.require("dojox.date.tests.hebrew.Date");
 	dojo.require("dojox.date.tests.islamic.Date");
+	dojo.require("dojox.date.tests.umalqura.Date");
 	dojo.require("dojox.date.tests.buddhist.Date");
 	dojo.require("dojox.date.tests.posix");
 }catch(e){
diff --git a/dojox/date/tests/relative.js b/dojox/date/tests/relative.js
index 5c204a1..cc78752 100644
--- a/dojox/date/tests/relative.js
+++ b/dojox/date/tests/relative.js
@@ -51,7 +51,7 @@ tests.register("dojox.date.tests.relative",
 				t.is("\u4e0a\u53483:32", dojox.date.relative.format(new Date(2009, 1, 1, 3, 32, 26), opts));
 				t.is("\u5468\u516d \u4e0b\u53488:32", dojox.date.relative.format(new Date(2009, 0, 31, 20, 32, 26), opts));
 				t.is("1\u67081\u65e5", dojox.date.relative.format(new Date(2009, 0, 1, 20, 32, 26), opts));
-				t.is("2008-1-1", dojox.date.relative.format(new Date(2008, 0, 1, 0), opts));
+				t.is("2008\u5e741\u67081\u65e5", dojox.date.relative.format(new Date(2008, 0, 1, 0), opts));
 			}
 		}
 	]
diff --git a/dojox/date/tests/test_DateTextBoxBuddhist.html b/dojox/date/tests/test_DateTextBoxBuddhist.html
index ce2fe11..0f437af 100644
--- a/dojox/date/tests/test_DateTextBoxBuddhist.html
+++ b/dojox/date/tests/test_DateTextBoxBuddhist.html
@@ -31,7 +31,7 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig=" isDebug: true, parseOnLoad: true, extraLocale: ['en-us', 'th']"></script>
+			data-dojo-config=" isDebug: true, parseOnLoad: true, extraLocale: ['en-us', 'th']"></script>
 
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/date/tests/test_DateTextBoxIslamic.html b/dojox/date/tests/test_DateTextBoxIslamic.html
index 12ac0e6..d31ea29 100644
--- a/dojox/date/tests/test_DateTextBoxIslamic.html
+++ b/dojox/date/tests/test_DateTextBoxIslamic.html
@@ -31,7 +31,7 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig=" isDebug: true, parseOnLoad: true, extraLocale: ['en-us', 'ar']"></script>
+			data-dojo-config=" isDebug: true, parseOnLoad: true, extraLocale: ['en-us', 'ar']"></script>
 
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/date/tests/test_DateTextBoxNewHebrewGreg.html b/dojox/date/tests/test_DateTextBoxNewHebrewGreg.html
index 9f84ddf..fdb1956 100644
--- a/dojox/date/tests/test_DateTextBoxNewHebrewGreg.html
+++ b/dojox/date/tests/test_DateTextBoxNewHebrewGreg.html
@@ -31,7 +31,7 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig=" isDebug: true, parseOnLoad: true, extraLocale: ['en-us', 'he-il']"></script>
+			data-dojo-config=" isDebug: true, parseOnLoad: true, extraLocale: ['en-us', 'he-il']"></script>
 
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/date/tests/test_DateTextBoxNewPersianGreg.html b/dojox/date/tests/test_DateTextBoxNewPersianGreg.html
new file mode 100644
index 0000000..bda05f7
--- /dev/null
+++ b/dojox/date/tests/test_DateTextBoxNewPersianGreg.html
@@ -0,0 +1,184 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<title>Date Conversions for Persian Widget</title>
+
+<style type="text/css">
+ at import "../../../dojo/resources/dojo.css";
+
+ at import "../../../dijit/tests/css/dijitTests.css";
+</style>
+
+<!-- required: the default dijit theme: -->
+<link id="themeStyles" rel="stylesheet"
+	href="../../../dijit/themes/tundra/tundra.css">
+
+<!-- required: dojo.js -->
+<script type="text/javascript" src="../../../dojo/dojo.js"
+	djConfig=" isDebug: true, parseOnLoad: true, extraLocale: ['en-us', 'fa-ir']"></script>
+<script>
+	dojo.require("dijit/form/Form");
+	dojo.require("dojo/date");
+	dojo.require("dojo/date/locale");
+	dojo.require("dojox/date/persian");
+	dojo.require("dojox/date/persian/locale");
+	dojo.require("dijit/form/DateTextBox");
+	dojo.require("dojo/parser");
+	/**
+	 * @param actualFormat -- current format
+	 * @param requiredformat-- converted Format
+	 * @param source -- Source control
+	 * @param destination -- Destination control
+	 * @return
+	 */
+	function convertPersianToGregorianDate(actualFormat, requiredformat,
+			source, destination) {
+		var value = dijit.byId(source).attr('DisplayedValue');
+		var options = {
+			datePattern : actualFormat,
+			selector : 'date'
+		};
+		var date = dojox.date.persian.locale.parse(value, options);
+		date = date.toGregorian();
+		options.datePattern = requiredformat;
+		var convertedDate = dojo.date.locale.format(date, options);
+		dojo.byId(destination).value = convertedDate;
+	}
+
+	/**
+	 * @param actualFormat -- current format
+	 * @param requiredformat-- converted Format
+	 * @param source -- Source control
+	 * @param destination -- Destination control
+	 * @return
+	 */
+	function convertGregorianToPersianDate(actualFormat, requiredformat,
+			source, destination) {
+		var value = dijit.byId(source).attr('DisplayedValue');
+		var options = {
+			datePattern : actualFormat,
+			selector : 'date'
+		};
+		var date = dojo.date.locale.parse(value, options);
+		date = new dojox.date.persian.Date(new Date(date));
+		options.datePattern = requiredformat;
+		var convertedDate = dojox.date.persian.locale.format(date, options);
+		dojo.byId(destination).value = convertedDate;
+
+	}
+</script>
+</head>
+
+<body class=" tundra ">
+<h1 class="testTitle">Test DateTextBoxNew Persian and Gregorian Widget:</h1>
+<form id="form1" dojoType='dijit.form.Form' action="" name="Persian" method="">
+
+<div class="dojoTitlePaneLabel"><label for="q1"> Persian
+Calendar </label> <span class="noticeMessage">DateTextBox class,
+datePackage = "dojox.date.persian"</span></div>
+
+<table>
+	<tr>
+		<td><label id="lpdat1"> Persian Date :</label></td>
+		<td><input type="combo" id="pDate1" name="dob"
+			dojoType="dijit.form.DateTextBox"
+			constraints="{datePattern:'yyyy/MM/dd'}" lang="fa"
+			datePackage="dojox.date.persian"
+			onchange="convertPersianToGregorianDate('yyyy/MM/dd','yyyy/MM/dd','pDate1','gDate1')"
+			value="2007-12-25" /></td>
+		<td>     </td>
+		<td><label id="lgdat1"> Gregorian Date(yyyy/MM/dd) :</label></td>
+
+		<td><input id="gDate1" size="34" disabled value="not fired yet!"
+			autocomplete="off"></td>
+		<tr rows="3"></tr>
+	</tr>
+	<tr></tr>
+	<tr></tr>
+	<tr></tr>
+	<tr></tr>
+	<tr>
+		<td><label id="lgdat2">Gregorian Date :</label></td>
+
+		<td><input type="combo" id="gDate2" name="dob"
+			dojoType="dijit.form.DateTextBox"
+			constraints="{datePattern:'yyyy/MM/dd'}"
+			onchange="convertGregorianToPersianDate('yyyy/MM/dd','yyyy/MM/dd','gDate2','pDate2')"
+			value="2007-12-25" /></td>
+		<td>     </td>
+		<td><label id="lpdat2"> Persian Date (yyyy/MM/dd) :</label></td>
+
+		<td><input id="pDate2" size="34" disabled value="not fired yet!"
+			autocomplete="off"></td>
+
+	</tr>
+	<tr></tr>
+	<tr></tr>
+	<tr></tr>
+	<tr></tr>
+	<tr>
+		<td><label id="lgdat3">Persian Date :</label></td>
+
+		<td><input type="combo" id="gDate3" name="dob"
+			dojoType="dijit.form.DateTextBox"
+			constraints="{datePattern:'yyyy/MMM/dd'}"
+			onchange="convertGregorianToPersianDate('yyyy/MMM/dd','yyyy/MMM/dd','gDate3','pDate3')"
+			value="2007-12-25" /></td>
+		<td>     </td>
+		<td><label id="lpdat3"> Gregorian Date (yyyy/MMM/dd):</label></td>
+		<td><input id="pDate3" size="34" disabled value="not fired yet!"
+			autocomplete="off"></td>
+	</tr>
+	<tr></tr>
+	<tr></tr>
+	<tr></tr>
+	<tr></tr>
+	<tr>
+		<td><label id="lgdat4"> Persian Date :</label></td>
+
+		<td><input type="combo" id="gDate4" name="dob"
+			dojoType="dijit.form.DateTextBox"
+			constraints="{datePattern:'yyyy/MMM/dd'}"
+			datePackage="dojox.date.persian"
+			onchange="convertPersianToGregorianDate('yyyy/MMM/dd','yyyy/MMM/dd','gDate4','pDate4')"
+			value="2007-12-25" /></td>
+
+		<td>     </td>
+		<td><label id="lpdat4"> Gregorian Date(yyyy/MMM/dd) </label></td>
+
+
+		<td><input id="pDate4" size="34" disabled value="not fired yet!"
+			autocomplete="off"></td>
+
+	</tr>
+	<tr></tr>
+	<tr></tr>
+	<tr></tr>
+	<tr></tr>
+	<tr>
+		<td><label id="lgdat5">Gregorian Date :</label></td>
+
+
+		<td><input type="combo" id="gDate5" name="dob"
+			dojoType="dijit.form.DateTextBox"
+			constraints="{datePattern:'yyyy/MMM/dd'}"
+			datePackage="dojox.date.persian"
+			onchange="convertPersianToGregorianDate('yyyy/MMM/dd','dd/MM/yyyy','gDate5','pDate5')"
+			value="2007-12-25" /></td>
+
+		<td>     </td>
+		<td><label id="lpdat4"> Persian Date (dd/MM/yyyy):</label></td>
+
+
+		<td><input id="pDate5" size="34" disabled value="not fired yet!"
+			autocomplete="off"></td>
+
+
+	</tr>
+</table>
+</form>
+
+</body>
+
+</html>
diff --git a/dojox/date/tests/test_DateTextBoxPersianGreg.html b/dojox/date/tests/test_DateTextBoxPersianGreg.html
new file mode 100644
index 0000000..0fe9a93
--- /dev/null
+++ b/dojox/date/tests/test_DateTextBoxPersianGreg.html
@@ -0,0 +1,148 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Test DateTextBoxNew persian Gregorian Widget</title>
+
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+
+			.testExample {
+				background-color:#fbfbfb;
+				padding:1em;
+				margin-bottom:1em;
+				border:1px solid #bfbfbf;
+			}
+
+			.noticeMessage {
+				color:#093669;
+				font-size:0.95em;
+				margin-left:0.5em;
+			}
+
+			.dojoTitlePaneLabel label {
+				font-weight:bold;
+			}
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/tundra/tundra.css">
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../dojo/dojo.js"
+			data-dojo-config=" isDebug: true, parseOnLoad: true, extraLocale: ['en-us', 'fa']"></script>
+
+		<!-- only needed for alternate theme testing: -->
+		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.dijit"); // optimize: load dijit layer
+			dojo.require("dijit.form.Form");
+			dojo.require("dojo.date.locale");
+			dojo.require("dojox.date.persian"); // TODO: think about changing this packaging so we don't have to include .locale module also
+			dojo.require("dojox.date.persian.locale");
+			dojo.require("dijit.form.DateTextBox");
+			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+
+			function eventHandler(e){
+				// use this.domNode.getAttribute('widgetId') to show "this" is the widget
+				// mouseleave/enter map to mouseout/over in all browsers except IE
+				console.log(this.domNode.getAttribute('widgetId') + ' ' + arguments[0].type);
+			}
+		</script>
+	</head>
+
+	<body class="tundra">
+
+		<h1 class="testTitle">Test DateTextBox Persian and Gregorian Widget</h1>
+		<!--	to test form submission, you'll need to create an action handler similar to
+			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
+		<form id="form1" dojoType='dijit.form.Form' action="" name="example" method="">
+			<div class="dojoTitlePaneLabel">
+				<label for="q1"> persian  Calendar </label>
+				<span class="noticeMessage">DateTextBox class, datePackage = "dojox.date.persian"</span>
+			</div>
+			<div class="testExample">
+				<input id="q1" name="noDOMvalue" value="2009-03-10" type="text" dojoType="dijit.form.DateTextBox" datePackage = "dojox.date.persian"
+					lang="fa"
+					constraints="{min:'2008-03-01',max:'2009-04-01',datePattern:'dd MMMM yyyy'}"
+					onMouseEnter="eventHandler"
+					onMouseLeave="eventHandler"
+					onKeyDown="eventHandler"
+					onChange="dojo.byId('oc1').value=''+arguments[0]"
+				>
+				onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off">
+				<nobr>
+				<button type=button onclick="dijit.byId('q1').attr('value', null);">set value to null</button>
+				<button type=button onclick="dojo.byId('gv1').value=''+dijit.byId('q1').attr('value');">get value</button>
+				<input id="gv1" size="34" disabled value="not called yet!" autocomplete="off">
+				</nobr>
+			</div>
+			<div class="dojoTitlePaneLabel">
+				<label for="q1"> Gregorian Date</label>
+				<span class="noticeMessage">DateTextBox class, Gregorian Calendar with min max  </span>
+			</div>
+			<div class="testExample">
+				<input id="Text1" name="noDOMvalue" value="2009-01-20" type="text" dojoType="dijit.form.DateTextBox"
+					lang="en"
+					constraints="{min:'2009-01-01',max:'2009-02-01', datePattern:'dd MMMM yyyy'}"
+					onMouseEnter="eventHandler"
+					onMouseLeave="eventHandler"
+					onKeyDown="eventHandler"
+					onChange="dojo.byId('oc2').value=''+arguments[0]"
+				>
+				onChange:<input id="oc2" size="34" disabled value="not fired yet!" autocomplete="off">
+				<nobr>
+				<button type=button onclick="dijit.byId('Text1').attr('value', null);" ID="Button1">set value to null</button>
+				<button type=button onclick="dojo.byId('Text3').value=''+dijit.byId('Text1').attr('value');" ID="Button2">get value</button>
+				<input id="Text3" size="34" disabled value="not called yet!" autocomplete="off" NAME="Text3">
+				</nobr>
+			</div>
+				<div class="dojoTitlePaneLabel">
+				<label for="q1"> Gregorian Date </label>
+				<span class="noticeMessage">DateTextBox class,  Gregorian Calendar</span>
+			</div>
+			<div class="testExample">
+				<input id="Text4" name="noDOMvalue" value="2009-01-20" type="text" dojoType="dijit.form.DateTextBox"
+					lang="en"
+					constraints="{datePattern:'dd MMMM yyyy'}"
+					onMouseEnter="eventHandler"
+					onMouseLeave="eventHandler"
+					onKeyDown="eventHandler"
+					onChange="dojo.byId('oc3').value=''+arguments[0]"
+				>
+				onChange:<input id="oc3" size="34" disabled value="not fired yet!" autocomplete="off">
+
+			<script>
+			// See if we can make a widget in script and attach it to the DOM ourselves.
+			dojo.addOnLoad(function(){
+		//		dojo.connect(dijit.byId('q5'), "onMouseEnter", eventHandler);
+		//		dojo.connect(dijit.byId('q5'), "onMouseLeave", eventHandler);
+		//		dojo.connect(dijit.byId('q5'), "onKeyDown", eventHandler);
+
+			});
+			</script>
+
+			<script>
+				function displayData() {
+					var f = document.getElementById("form1");
+					var s = "";
+					for (var i = 0; i < f.elements.length; i++) {
+						var elem = f.elements[i];
+						if (elem.name == "button")  { continue; }
+						s += elem.name + ": " + elem.value + "\n";
+					}
+					alert(s);
+				}
+			</script>
+
+
+			<div>
+				<button name="button" onclick="displayData(); return false;">view data</button>
+				<input type="submit" name="submit" />
+				<input type="reset" name="reset" />
+			</div>
+		</form>
+	</body>
+</html>
diff --git a/dojox/date/tests/test_DateTextBoxUmalqura.html b/dojox/date/tests/test_DateTextBoxUmalqura.html
new file mode 100644
index 0000000..9197536
--- /dev/null
+++ b/dojox/date/tests/test_DateTextBoxUmalqura.html
@@ -0,0 +1,148 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Test DateTextBoxNew Umalqura Widget</title>
+
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+
+			.testExample {
+				background-color:#fbfbfb;
+				padding:1em;
+				margin-bottom:1em;
+				border:1px solid #bfbfbf;
+			}
+
+			.noticeMessage {
+				color:#093669;
+				font-size:0.95em;
+				margin-left:0.5em;
+			}
+
+			.dojoTitlePaneLabel label {
+				font-weight:bold;
+			}
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/tundra/tundra.css">
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../dojo/dojo.js"
+			data-dojo-config=" isDebug: true, parseOnLoad: true, extraLocale: ['en-us', 'ar']"></script>
+
+		<!-- only needed for alternate theme testing: -->
+		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.dijit"); // optimize: load dijit layer
+			dojo.require("dijit.form.Form");
+			dojo.require("dojo.date.locale");
+			dojo.require("dojox.date.umalqura");
+			dojo.require("dojox.date.umalqura.Date");
+			dojo.require("dojox.date.umalqura.locale");
+			dojo.require("dijit.form.DateTextBox");
+			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+
+			function eventHandler(e){
+				// use this.domNode.getAttribute('widgetId') to show "this" is the widget
+				// mouseleave/enter map to mouseout/over in all browsers except IE
+				console.log(this.domNode.getAttribute('widgetId') + ' ' + arguments[0].type);
+}	
+</script>
+	</head>
+
+	<body c
+    lass="tundra">
+		
+		<h1 class="testTitle">Test DateTextBoxNew umalqura Widget</h1>
+		<!--	to test form submission, you'll need to create an action handler similar to
+			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
+		<form id="form1" dojoType='dijit.form.Form' action="" name="example" method="">
+			<div class="dojoTitlePaneLabel">
+				<label for="q1"> Umalqura  Calendar </label>
+				<span class="noticeMessage">DateTextBox class, datePackage="dojox.date.umalqura"</span>
+			</div>
+			<div class="testExample">
+				<input id="q1" name="noDOMvalue" value="" type="text" dojoType="dijit.form.DateTextBox" datePackage="dojox.date.umalqura"
+					lang="ar"
+					onMouseEnter="eventHandler"
+					onMouseLeave="eventHandler"
+					onKeyDown="eventHandler"
+					onChange="dojo.byId('oc1').value=''+arguments[0]"
+				>
+				onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off">
+				<nobr>
+				<button type=button onclick="dijit.byId('q1').attr('value', null);">set value to null</button>
+				<button type=button onclick="dojo.byId('gv1').value=''+dijit.byId('q1').attr('value');">get value</button>
+				<input id="gv1" size="34" disabled value="not called yet!" autocomplete="off">
+				</nobr>
+			</div>
+			<div class="dojoTitlePaneLabel">
+				<label for="q1"> Gregorian Date</label>
+				<span class="noticeMessage">DateTextBox class, Gregorian Calendar with min max  </span>
+			</div>
+			<div class="testExample">
+				<input id="Text1" name="noDOMvalue" value="2009-01-20" type="text" dojoType="dijit.form.DateTextBox" 
+					lang="en"
+					constraints="{min:'2009-01-01',max:'2009-02-01', datePattern:'dd MMMM yyyy'}"
+					onMouseEnter="eventHandler"
+					onMouseLeave="eventHandler"
+					onKeyDown="eventHandler"
+					onChange="dojo.byId('oc2').value=''+arguments[0]"
+				>
+				onChange:<input id="oc2" size="34" disabled value="not fired yet!" autocomplete="off">
+				<nobr>
+				<button type=button onclick="dijit.byId('Text1').attr('value', null);" ID="Button1">set value to null</button>
+				<button type=button onclick="dojo.byId('Text3').value=''+dijit.byId('Text1').attr('value');" ID="Button2">get value</button>
+				<input id="Text3" size="34" disabled value="not called yet!" autocomplete="off" NAME="Text3">
+				</nobr>
+			</div>
+				<div class="dojoTitlePaneLabel">
+				<label for="q1"> Gregorian Date </label>
+				<span class="noticeMessage">DateTextBox class,  Gregorian Calendar</span>
+			</div>
+			<div class="testExample">
+				<input id="Text4" name="noDOMvalue" value="2009-01-20" type="text" dojoType="dijit.form.DateTextBox" 
+					lang="en"
+					onMouseEnter="eventHandler"
+					onMouseLeave="eventHandler"
+					onKeyDown="eventHandler"
+					onChange="dojo.byId('oc3').value=''+arguments[0]"
+				>
+				onChange:<input id="oc3" size="34" disabled value="not fired yet!" autocomplete="off">
+
+			<script>
+			// See if we can make a widget in script and attach it to the DOM ourselves.
+			dojo.addOnLoad(function(){
+		//		dojo.connect(dijit.byId('q5'), "onMouseEnter", eventHandler);
+		//		dojo.connect(dijit.byId('q5'), "onMouseLeave", eventHandler);
+		//		dojo.connect(dijit.byId('q5'), "onKeyDown", eventHandler);
+
+			});
+			</script>
+
+			<script>
+				function displayData() {
+					var f = document.getElementById("form1");
+					var s = "";
+					for (var i = 0; i < f.elements.length; i++) {
+						var elem = f.elements[i];
+						if (elem.name == "button")  { continue; }
+						s += elem.name + ": " + elem.value + "\n";
+					}
+					alert(s);
+				}
+			</script>
+
+			
+			<div>
+				<button name="button" onclick="displayData(); return false;">view data</button>
+				<input type="submit" name="submit" />
+				<input type="reset" name="reset" />
+			</div>
+		</form>
+	</body>
+</html>
diff --git a/dojox/date/tests/timezoneFormatting.js b/dojox/date/tests/timezoneFormatting.js
index 8d93c07..96c2797 100644
--- a/dojox/date/tests/timezoneFormatting.js
+++ b/dojox/date/tests/timezoneFormatting.js
@@ -29,7 +29,7 @@ tests.register("dojox.date.tests.timezoneFormatting",
 					
 				//////////////////////
 				//  Custom Selector:
-				var selectorOpts = {datePattern: "EEEE, MMMM d, y 'at'", timePattern: "HH:mm:ss z", locale: "en-us"};
+				var selectorOpts = {formatLength: "long", datePattern: "EEEE, MMMM d, y", timePattern: "HH:mm:ss z", locale: "en-us"};
 				doh.is("Friday, August 11, 2006 at 00:55:12 GMT", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone: 'GMT'})));
 				doh.is("Thursday, August 10, 2006 at 18:55:12 MDT", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone: 'America/Denver'})));
 				doh.is("Thursday, August 10, 2006 at 16:55:12 AKDT", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone: 'America/Anchorage'})));
@@ -43,40 +43,40 @@ tests.register("dojox.date.tests.timezoneFormatting",
 				//////////////////////
 				//  Full Selectors:
 				// New York (in en-us)
-				doh.is("Thursday, August 10, 2006 8:55:12 PM EDT", dojo.date.locale.format(date, {formatLength:'full',locale:'en-us',timezone:'America/New_York'}));
+				doh.is("Thursday, August 10, 2006 at 8:55:12 PM EDT", dojo.date.locale.format(date, {formatLength:'full',locale:'en-us',timezone:'America/New_York'}));
 				// Tokyo (in ja-jp)
-				doh.is("2006\u5e748\u670811\u65e5\u91d1\u66dc\u65e59\u664255\u520612\u79d2 JST", dojo.date.locale.format(date, {formatLength:'full',locale:'ja-jp',timezone:'Asia/Tokyo'}));
+				doh.is("2006\u5e748\u670811\u65e5\u91d1\u66dc\u65e5 9\u664255\u520612\u79d2 JST", dojo.date.locale.format(date, {formatLength:'full',locale:'ja-jp',timezone:'Asia/Tokyo'}));
 				// Shanghai (in zh-cn)
-				doh.is("2006\u5e748\u670811\u65e5\u661f\u671f\u4e94CST\u4e0a\u53488\u65f655\u520612\u79d2", dojo.date.locale.format(date, {formatLength:'full',locale:'zh-cn',timezone:'Asia/Shanghai'}));
+				doh.is("2006\u5e748\u670811\u65e5\u661f\u671f\u4e94CST\u4e0a\u53488:55:12", dojo.date.locale.format(date, {formatLength:'full',locale:'zh-cn',timezone:'Asia/Shanghai'}));
 				// Paris (in fr-fr)
 				doh.is("vendredi 11 août 2006 02:55:12 CEST", dojo.date.locale.format(date, {formatLength:'full',locale:'fr-fr',timezone:'Europe/Paris'}));
 				// Vienna (in de-at)
 				doh.is("Freitag, 11. August 2006 02:55:12 CEST", dojo.date.locale.format(date, {formatLength:'full',locale:'de-at',timezone:'Europe/Vienna'}));
 				// Madrid (in es)
-				doh.is("viernes 11 de agosto de 2006 02:55:12 CEST", dojo.date.locale.format(date, {formatLength:'full',locale:'es',timezone:'Europe/Madrid'}));
+				doh.is("viernes, 11 de agosto de 2006 02:55:12 CEST", dojo.date.locale.format(date, {formatLength:'full',locale:'es',timezone:'Europe/Madrid'}));
 				
 				//////////////////////
 				//  Tricky Dates:
 				date = new Date(1225605599000); // 1 second before New York goes off DST - NY and LA are 3 hours apart
 				selectorOpts = {formatLength: "full", locale: "en-us"};
-				doh.is("Sunday, November 2, 2008 1:59:59 AM EDT", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/New_York'})));
-				doh.is("Saturday, November 1, 2008 10:59:59 PM PDT", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Los_Angeles'})));
+				doh.is("Sunday, November 2, 2008 at 1:59:59 AM EDT", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/New_York'})));
+				doh.is("Saturday, November 1, 2008 at 10:59:59 PM PDT", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Los_Angeles'})));
 				
 				date = new Date(1225605600000); // New York goes off DST - NY and LA are 2 hours apart
-				doh.is("Sunday, November 2, 2008 1:00:00 AM EST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/New_York'})));
-				doh.is("Saturday, November 1, 2008 11:00:00 PM PDT", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Los_Angeles'})));
+				doh.is("Sunday, November 2, 2008 at 1:00:00 AM EST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/New_York'})));
+				doh.is("Saturday, November 1, 2008 at 11:00:00 PM PDT", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Los_Angeles'})));
 				
 				date = new Date(1225616400000); // LA goes off DST - NY and LA are 3 hours apart again
-				doh.is("Sunday, November 2, 2008 4:00:00 AM EST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/New_York'})));
-				doh.is("Sunday, November 2, 2008 1:00:00 AM PST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Los_Angeles'})));
+				doh.is("Sunday, November 2, 2008 at 4:00:00 AM EST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/New_York'})));
+				doh.is("Sunday, November 2, 2008 at 1:00:00 AM PST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Los_Angeles'})));
 				
 				date = new Date(1257062399000); // Denver on DST - Denver is 1 hr ahead of Phoenix
-				doh.is("Sunday, November 1, 2009 1:59:59 AM MDT", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Denver'})));
-				doh.is("Sunday, November 1, 2009 12:59:59 AM MST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Phoenix'})));
+				doh.is("Sunday, November 1, 2009 at 1:59:59 AM MDT", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Denver'})));
+				doh.is("Sunday, November 1, 2009 at 12:59:59 AM MST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Phoenix'})));
 				
 				date = new Date(1257062400000); // Denver off DST - Denver is same time as Phoenix
-				doh.is("Sunday, November 1, 2009 1:00:00 AM MST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Denver'})));
-				doh.is("Sunday, November 1, 2009 1:00:00 AM MST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Phoenix'})));
+				doh.is("Sunday, November 1, 2009 at 1:00:00 AM MST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Denver'})));
+				doh.is("Sunday, November 1, 2009 at 1:00:00 AM MST", dojo.date.locale.format(date, dojo.delegate(selectorOpts, {timezone:'America/Phoenix'})));
 			}
 		}
 	]
diff --git a/dojox/date/tests/umalqura/Date.js b/dojox/date/tests/umalqura/Date.js
new file mode 100644
index 0000000..d2f788d
--- /dev/null
+++ b/dojox/date/tests/umalqura/Date.js
@@ -0,0 +1,2719 @@
+dojo.provide("dojox.date.tests.umalqura.Date");
+dojo.require("dojox.date.umalqura.Date");
+dojo.require("dojox.date.umalqura.locale");
+dojo.require("dojox.date.umalqura");
+dojo.require("dojox.date.islamic.Date");
+dojo.require("dojox.date.islamic.locale");
+dojo.require("dojox.date.islamic");
+
+dojo.require("dojo.date");
+
+dojo.requireLocalization("dojo.cldr", "gregorian");
+dojo.requireLocalization("dojo.cldr", "islamic");
+
+tests.register("dojox.date.tests.umalqura.Date",
+	[
+		{
+		    // Test formatting and parsing of dates in various locales pre-built in dojo.cldr
+		    // NOTE: we can't set djConfig.extraLocale before bootstrapping unit tests, so directly
+		    // load resources here for specific locales:
+
+		    name: "setup",
+		    setUp: function () {
+		        var partLocaleList = ["ar", "en"];
+
+		        dojo.forEach(partLocaleList, function (locale) {
+		            dojo.requireLocalization("dojo.cldr", "islamic", locale);
+		        });
+		    },
+		    runTest: function (t) {
+		    },
+		    tearDown: function () {
+		        //Clean up bundles that should not exist if
+		        //the test is re-run.
+		        //				delete dojo.cldr.nls.islamic;
+		    }
+		},
+		{
+		    name: "conversion",
+		    runTest: function (t) {
+		        var dates = [
+
+                [1400, 0, 1, 1979, 10, 20],
+                [1400, 1, 1, 1979, 11, 19],
+                [1400, 2, 1, 1980, 0, 18],
+                [1400, 3, 1, 1980, 1, 16],
+                [1400, 4, 1, 1980, 2, 17],
+                [1400, 5, 1, 1980, 3, 15]
+		        ];
+
+		        var idate1, idate2, gdate1, gdate2;
+		        var diff;
+		        idate1 = new dojox.date.umalqura.Date(1400, 0, 1);
+		        gdate1 = new Date(1979, 10, 20);
+		        idate2 = new dojox.date.umalqura.Date();
+
+		        gdate2 = idate1.toGregorian();
+		        diff = dojo.date.compare(gdate1, gdate2, "date");
+		        t.is(diff, 0, "error in converting to Gregorian");
+
+		        idate2.fromGregorian(gdate1);
+
+		        var errMsg = "error in converting from Gregorian";
+		        diff = idate1.getFullYear() - idate2.getFullYear();
+		        t.is(diff, 0, errMsg + " error in year");
+		        diff = idate1.getMonth() - idate2.getMonth();
+		        t.is(diff, 0, errMsg + " error in Month");
+		        diff = idate1.getDate() - idate2.getDate();
+		        t.is(diff, 0, errMsg + " error in Date");
+
+		        //Case 2
+		        {
+		            var idate1, idate2, gdate1, gdate2;
+		            var diff;
+		            idate1 = new dojox.date.umalqura.Date(1400, 0, 1);
+		            gdate1 = new Date(1979, 10, 20);
+		            idate2 = new dojox.date.umalqura.Date();
+
+		            gdate2 = idate1.toGregorian();
+		            diff = dojo.date.compare(gdate1, gdate2, "date");
+
+		            idate2.fromGregorian(gdate1);
+
+		            var errMsg = "error in converting from Gregorian";
+		            diff = idate1.getFullYear() - idate2.getFullYear();
+		            t.is(diff, 0, errMsg + " error in year");
+		            diff = idate1.getMonth() - idate2.getMonth();
+		            t.is(diff, 0, errMsg + " error in Month");
+		            diff = idate1.getDate() - idate2.getDate();
+		            t.is(diff, 0, errMsg + " error in Date");
+		        }
+
+		        //Case 3
+		        {
+
+		            var idate1, idate2, gdate1, gdate2;
+		            var diff;
+		            idate1 = new dojox.date.umalqura.Date(1400, 0, 2);
+		            gdate1 = new Date(1979, 10, 21);
+		            idate2 = new dojox.date.umalqura.Date();
+
+		            gdate2 = idate1.toGregorian();
+		            diff = dojo.date.compare(gdate1, gdate2, "date");
+
+		            idate2.fromGregorian(gdate1);
+
+		            var errMsg = "error in converting from Gregorian";
+		            diff = idate1.getFullYear() - idate2.getFullYear();
+		            t.is(diff, 0, errMsg + " error in year");
+		            diff = idate1.getMonth() - idate2.getMonth();
+		            t.is(diff, 0, errMsg + " error in Month");
+		            diff = idate1.getDate() - idate2.getDate();
+		            t.is(diff, 0, errMsg + " error in Date");
+		        }
+
+		        //Case 4
+		        {
+		            var idate1, idate2, gdate1, gdate2;
+		            var diff;
+		            idate1 = new dojox.date.umalqura.Date(1405, 0, 1);
+		            gdate1 = new Date(1984, 8, 26);
+		            idate2 = new dojox.date.umalqura.Date();
+
+		            gdate2 = idate1.toGregorian();
+		            diff = dojo.date.compare(gdate1, gdate2, "date");
+
+		            idate2.fromGregorian(gdate1);
+
+		            var errMsg = "error in converting from Gregorian";
+		            diff = idate1.getFullYear() - idate2.getFullYear();
+		            t.is(diff, 0, errMsg + " error in year");
+		            diff = idate1.getMonth() - idate2.getMonth();
+		            t.is(diff, 0, errMsg + " error in Month");
+		            diff = idate1.getDate() - idate2.getDate();
+		            t.is(diff, 0, errMsg + " error in Date");
+		        }
+
+		        //Case 5
+		        {
+		            var idate1, idate2, gdate1, gdate2;
+		            var diff;
+		            idate1 = new dojox.date.umalqura.Date(1410, 0, 1);
+		            gdate1 = new Date(1989, 7, 3);
+		            idate2 = new dojox.date.umalqura.Date();
+
+		            gdate2 = idate1.toGregorian();
+		            diff = dojo.date.compare(gdate1, gdate2, "date");
+
+		            idate2.fromGregorian(gdate1);
+
+		            var errMsg = "error in converting from Gregorian";
+		            diff = idate1.getFullYear() - idate2.getFullYear();
+		            t.is(diff, 0, errMsg + " error in year");
+		            diff = idate1.getMonth() - idate2.getMonth();
+		            t.is(diff, 0, errMsg + " error in Month");
+		            diff = idate1.getDate() - idate2.getDate();
+		            t.is(diff, 0, errMsg + " error in Date");
+		        }
+
+		        //Case 6
+		        {
+		            var idate1, idate2, gdate1, gdate2;
+		            var diff;
+		            idate1 = new dojox.date.umalqura.Date(1400, 0, 1);
+		            gdate1 = new Date(1979, 10, 20);
+		            idate2 = new dojox.date.umalqura.Date();
+
+		            gdate2 = idate1.toGregorian();
+		            diff = dojo.date.compare(gdate1, gdate2, "date");
+
+		            idate2.fromGregorian(gdate1);
+
+		            var errMsg = "error in converting from Gregorian";
+		            diff = idate1.getFullYear() - idate2.getFullYear();
+		            diff = idate1.getMonth() - idate2.getMonth();
+		            diff = idate1.getDate() - idate2.getDate();
+
+		            dates = [
+                                [1400, 0, 1, 1979, 10, 20],
+                                [1400, 0, 2, 1979, 10, 21],
+		            ];
+		            dojo.forEach(dates, function (d, i) {
+		                idate1 = new dojox.date.umalqura.Date(d[0], d[1], d[2]);
+		                gdate1 = new Date(d[3], d[4], d[5]);
+		                idate2 = new dojox.date.umalqura.Date();
+		                idate2.fromGregorian(gdate1);
+		                var errMsg = "error in converting from Gregorian at Year : " + d[0] + " Month: " + d[1] + " Day: " + d[2];
+		                diff = idate1.getFullYear() - idate2.getFullYear();
+		                t.is(diff, 0, errMsg + " error in year");
+		                diff = idate1.getMonth() - idate2.getMonth();
+		                t.is(diff, 0, errMsg + " error in Month");
+		                diff = idate1.getDate() - idate2.getDate();
+		                t.is(diff, 0, errMsg + " error in Date");
+		            });
+
+		        }
+
+		        //Case 7
+		        {
+		            var idate1, idate2, gdate1, gdate2;
+		            var diff;
+		            idate1 = new dojox.date.umalqura.Date(1405, 0, 2);
+		            gdate1 = new Date(1984, 8, 27);
+		            idate2 = new dojox.date.umalqura.Date();
+
+		            gdate2 = idate1.toGregorian();
+		            diff = dojo.date.compare(gdate1, gdate2, "date");
+
+		            idate2.fromGregorian(gdate1);
+
+		            var errMsg = "error in converting from Gregorian";
+		            diff = idate1.getFullYear() - idate2.getFullYear();
+		            t.is(diff, 0, errMsg + " error in year");
+		            diff = idate1.getMonth() - idate2.getMonth();
+		            t.is(diff, 0, errMsg + " error in Month");
+		            diff = idate1.getDate() - idate2.getDate();
+		            t.is(diff, 0, errMsg + " error in Date");
+		        }
+
+		        //Case 8
+		        {
+		            var idate1, idate2, gdate1, gdate2;
+		            var diff;
+		            idate1 = new dojox.date.umalqura.Date(1410, 0, 2);
+		            gdate1 = new Date(1989, 7, 4);
+		            idate2 = new dojox.date.umalqura.Date();
+
+		            gdate2 = idate1.toGregorian();
+		            diff = dojo.date.compare(gdate1, gdate2, "date");
+
+		            idate2.fromGregorian(gdate1);
+
+		            var errMsg = "error in converting from Gregorian";
+		            diff = idate1.getFullYear() - idate2.getFullYear();
+		            t.is(diff, 0, errMsg + " error in year");
+		            diff = idate1.getMonth() - idate2.getMonth();
+		            t.is(diff, 0, errMsg + " error in Month");
+		            diff = idate1.getDate() - idate2.getDate();
+		            t.is(diff, 0, errMsg + " error in Date");
+		        }
+
+		        //Case 9
+		        {
+		            var idate1, idate2, gdate1, gdate2;
+		            var diff;
+		            idate1 = new dojox.date.umalqura.Date(1415, 0, 2);
+		            gdate1 = new Date(1994, 5, 11);
+		            idate2 = new dojox.date.umalqura.Date();
+
+		            gdate2 = idate1.toGregorian();
+		            diff = dojo.date.compare(gdate1, gdate2, "date");
+
+		            idate2.fromGregorian(gdate1);
+
+		            var errMsg = "error in converting from Gregorian";
+		            diff = idate1.getFullYear() - idate2.getFullYear();
+		            t.is(diff, 0, errMsg + " error in year");
+		            diff = idate1.getMonth() - idate2.getMonth();
+		            t.is(diff, 0, errMsg + " error in Month");
+		            diff = idate1.getDate() - idate2.getDate();
+		            t.is(diff, 0, errMsg + " error in Date");
+		        }
+
+		        //Case 10
+		        {
+
+		            var idate1, idate2, gdate1, gdate2;
+		            var diff;
+		            idate1 = new dojox.date.umalqura.Date(1400, 2, 2);
+		            gdate1 = new Date(1980, 0, 19);
+		            idate2 = new dojox.date.umalqura.Date();
+
+		            gdate2 = idate1.toGregorian();
+		            diff = dojo.date.compare(gdate1, gdate2, "date");
+		            t.is(diff, 0, "error in converting to Gregorian");
+		        }
+
+		        //Case 11
+		        {
+		            var idate1, idate2, gdate1, gdate2;
+		            var diff;
+		            idate1 = new dojox.date.umalqura.Date(1400, 3, 1);
+		            gdate1 = new Date(1980, 1, 16);
+
+		            gdate2 = idate1.toGregorian();
+		            diff = dojo.date.compare(gdate1, gdate2, "date");
+		            t.is(diff, 0, "error in converting to Gregorian");
+		        }
+		    }
+		},
+
+		{
+		    name: "toGregorian",
+		    runTest: function (t) {
+
+		        var dateIslamic = new dojox.date.umalqura.Date(1431, 3, 6); // March 22 2010
+		        var dateGregorian = dateIslamic.toGregorian();
+		        t.is(0, dojo.date.compare(new Date(2010, 2, 22), dateGregorian, "date"));
+		        var dates = [
+
+				           		[1400, 1, 1, 1979, 11, 19],
+								[1400, 2, 1, 1980, 0, 18],
+								[1400, 3, 1, 1980, 1, 16],
+								[1400, 4, 1, 1980, 2, 17],
+								[1400, 5, 1, 1980, 3, 15],
+								[1400, 6, 1, 1980, 4, 14],
+								[1400, 7, 1, 1980, 5, 13],
+								[1400, 8, 1, 1980, 6, 12],
+								[1400, 9, 1, 1980, 7, 11],
+								[1400, 10, 1, 1980, 8, 9],
+								[1400, 11, 1, 1980, 9, 9],
+								[1401, 0, 1, 1980, 10, 8],
+								[1401, 1, 1, 1980, 11, 7],
+								[1401, 2, 1, 1981, 0, 6],
+								[1401, 3, 1, 1981, 1, 5],
+								[1401, 4, 1, 1981, 2, 6],
+								[1401, 5, 1, 1981, 3, 5],
+								[1401, 6, 1, 1981, 4, 4],
+								[1401, 7, 1, 1981, 5, 2],
+								[1401, 8, 1, 1981, 6, 2],
+								[1401, 9, 1, 1981, 6, 31],
+								[1401, 10, 1, 1981, 7, 29],
+								[1401, 11, 1, 1981, 8, 28],
+								[1402, 0, 1, 1981, 9, 28],
+								[1402, 1, 1, 1981, 10, 26],
+								[1402, 2, 1, 1981, 11, 26],
+								[1405, 4, 1, 1985, 0, 22],
+								[1405, 5, 1, 1985, 1, 21],
+								[1406, 2, 1, 1985, 10, 14],
+								[1406, 3, 1, 1985, 11, 13],
+								[1406, 4, 1, 1986, 0, 12],
+								[1406, 5, 1, 1986, 1, 10],
+								[1406, 6, 1, 1986, 2, 12],
+								[1406, 7, 1, 1986, 3, 10],
+								[1406, 8, 1, 1986, 4, 10],
+								[1406, 9, 1, 1986, 5, 8],
+								[1406, 10, 1, 1986, 6, 8],
+								[1406, 11, 1, 1986, 7, 7],
+								[1407, 0, 1, 1986, 8, 5],
+								[1407, 1, 1, 1986, 9, 5],
+								[1407, 2, 1, 1986, 10, 3],
+								[1407, 3, 1, 1986, 11, 3],
+								[1407, 4, 1, 1987, 0, 1],
+								[1407, 5, 1, 1987, 0, 31],
+								[1407, 6, 1, 1987, 2, 1],
+								[1407, 7, 1, 1987, 2, 30],
+								[1407, 8, 1, 1987, 3, 29],
+								[1407, 9, 1, 1987, 4, 28],
+								[1408, 5, 1, 1988, 0, 20],
+								[1408, 6, 1, 1988, 1, 19],
+								[1408, 7, 1, 1988, 2, 19],
+								[1408, 8, 1, 1988, 3, 17],
+								[1408, 9, 1, 1988, 4, 17],
+								[1408, 10, 1, 1988, 5, 15],
+								[1408, 11, 1, 1988, 6, 15],
+								[1409, 0, 1, 1988, 7, 13],
+								[1409, 1, 1, 1988, 8, 12],
+								[1409, 2, 1, 1988, 9, 12],
+								[1409, 3, 1, 1988, 10, 11],
+								[1409, 4, 1, 1988, 11, 10],
+								[1409, 5, 1, 1989, 0, 9],
+								[1411, 1, 1, 1990, 7, 22],
+								[1411, 2, 1, 1990, 8, 20],
+								[1411, 8, 1, 1991, 2, 17],
+								[1411, 9, 1, 1991, 3, 16],
+								[1411, 10, 1, 1991, 4, 15],
+								[1411, 11, 1, 1991, 5, 13],
+								[1412, 0, 1, 1991, 6, 13],
+								[1412, 1, 1, 1991, 7, 11],
+								[1412, 2, 1, 1991, 8, 10],
+								[1412, 3, 1, 1991, 9, 9],
+								[1412, 4, 1, 1991, 10, 8],
+								[1412, 5, 1, 1991, 11, 7],
+								[1412, 6, 1, 1992, 0, 6],
+								[1412, 7, 1, 1992, 1, 5],
+								[1412, 8, 1, 1992, 2, 6],
+								[1412, 9, 1, 1992, 3, 4],
+								[1412, 10, 1, 1992, 4, 4],
+								[1412, 11, 1, 1992, 5, 2],
+								[1413, 0, 1, 1992, 6, 1],
+								[1413, 1, 1, 1992, 6, 31],
+								[1413, 2, 1, 1992, 7, 29],
+								[1413, 3, 1, 1992, 8, 28],
+								[1413, 4, 1, 1992, 9, 27],
+								[1413, 5, 1, 1992, 10, 25],
+								[1414, 2, 1, 1993, 7, 19],
+								[1414, 3, 1, 1993, 8, 17],
+								[1414, 4, 1, 1993, 9, 17],
+								[1414, 5, 1, 1993, 10, 15],
+								[1414, 6, 1, 1993, 11, 14],
+								[1414, 7, 1, 1994, 0, 13],
+								[1414, 8, 1, 1994, 1, 12],
+								[1414, 9, 1, 1994, 2, 13],
+								[1414, 10, 1, 1994, 3, 12],
+								[1414, 11, 1, 1994, 4, 12],
+								[1415, 0, 1, 1994, 5, 10],
+								[1415, 1, 1, 1994, 6, 10],
+								[1415, 2, 1, 1994, 7, 9],
+								[1415, 3, 1, 1994, 8, 7],
+								[1415, 4, 1, 1994, 9, 6],
+								[1415, 5, 1, 1994, 10, 5],
+								[1415, 6, 1, 1994, 11, 4],
+								[1415, 7, 1, 1995, 0, 2],
+								[1415, 8, 1, 1995, 1, 1],
+								[1415, 9, 1, 1995, 2, 2],
+								[1415, 10, 1, 1995, 3, 1],
+								[1415, 11, 1, 1995, 4, 1],
+								[1416, 0, 1, 1995, 4, 30],
+								[1416, 1, 1, 1995, 5, 29],
+								[1416, 2, 1, 1995, 6, 29],
+								[1416, 3, 1, 1995, 7, 27],
+								[1416, 4, 1, 1995, 8, 26],
+								[1416, 5, 1, 1995, 9, 25],
+								[1416, 6, 1, 1995, 10, 24],
+								[1416, 7, 1, 1995, 11, 23],
+								[1416, 8, 1, 1996, 0, 21],
+								[1416, 9, 1, 1996, 1, 20],
+								[1416, 10, 1, 1996, 2, 20],
+								[1416, 11, 1, 1996, 3, 19],
+								[1417, 0, 1, 1996, 4, 18],
+								[1417, 1, 1, 1996, 5, 17],
+								[1417, 2, 1, 1996, 6, 17],
+								[1417, 3, 1, 1996, 7, 16],
+								[1417, 4, 1, 1996, 8, 14],
+								[1417, 5, 1, 1996, 9, 13],
+								[1417, 6, 1, 1996, 10, 12],
+								[1417, 7, 1, 1996, 11, 12],
+								[1417, 8, 1, 1997, 0, 10],
+								[1417, 9, 1, 1997, 1, 9],
+								[1417, 10, 1, 1997, 2, 10],
+								[1417, 11, 1, 1997, 3, 8],
+								[1418, 0, 1, 1997, 4, 8],
+								[1418, 1, 1, 1997, 5, 6],
+								[1418, 2, 1, 1997, 6, 6],
+								[1418, 3, 1, 1997, 7, 5],
+								[1418, 4, 1, 1997, 8, 3],
+								[1418, 5, 1, 1997, 9, 3],
+								[1418, 6, 1, 1997, 10, 1],
+								[1418, 7, 1, 1997, 11, 1],
+								[1418, 8, 1, 1997, 11, 31],
+								[1418, 9, 1, 1998, 0, 29],
+								[1418, 10, 1, 1998, 1, 28],
+								[1418, 11, 1, 1998, 2, 29],
+								[1419, 0, 1, 1998, 3, 27],
+								[1419, 1, 1, 1998, 4, 27],
+								[1419, 2, 1, 1998, 5, 25],
+								[1419, 3, 1, 1998, 6, 25],
+								[1419, 4, 1, 1998, 7, 23],
+								[1419, 5, 1, 1998, 8, 22],
+								[1419, 6, 1, 1998, 9, 21],
+								[1419, 7, 1, 1998, 10, 20],
+								[1419, 8, 1, 1998, 11, 20],
+								[1419, 9, 1, 1999, 0, 19],
+								[1419, 10, 1, 1999, 1, 17],
+								[1419, 11, 1, 1999, 2, 19],
+								[1420, 0, 1, 1999, 3, 17],
+								[1420, 1, 1, 1999, 4, 16],
+								[1420, 2, 1, 1999, 5, 15],
+								[1420, 3, 1, 1999, 6, 14],
+								[1420, 4, 1, 1999, 7, 12],
+								[1420, 5, 1, 1999, 8, 11],
+								[1420, 6, 1, 1999, 9, 10],
+								[1420, 7, 1, 1999, 10, 9],
+								[1420, 8, 1, 1999, 11, 9],
+								[1420, 9, 1, 2000, 0, 8],
+								[1420, 10, 1, 2000, 1, 7],
+								[1420, 11, 1, 2000, 2, 7],
+								[1421, 0, 1, 2000, 3, 6],
+								[1421, 1, 1, 2000, 4, 5],
+								[1421, 2, 1, 2000, 5, 3],
+								[1421, 3, 1, 2000, 6, 3],
+								[1421, 4, 1, 2000, 7, 1],
+								[1421, 5, 1, 2000, 7, 30],
+								[1421, 6, 1, 2000, 8, 28],
+								[1421, 7, 1, 2000, 9, 28],
+								[1421, 8, 1, 2000, 10, 27],
+								[1421, 9, 1, 2000, 11, 27],
+								[1421, 10, 1, 2001, 0, 26],
+								[1421, 11, 1, 2001, 1, 24],
+								[1422, 0, 1, 2001, 2, 26],
+								[1422, 1, 1, 2001, 3, 25],
+								[1422, 2, 1, 2001, 4, 24],
+								[1422, 3, 1, 2001, 5, 22],
+								[1422, 4, 1, 2001, 6, 22],
+								[1422, 5, 1, 2001, 7, 20],
+								[1423, 9, 1, 2002, 11, 5],
+								[1423, 10, 1, 2003, 0, 4],
+								[1423, 11, 1, 2003, 1, 2],
+								[1424, 0, 1, 2003, 2, 4],
+								[1424, 1, 1, 2003, 3, 3],
+								[1424, 2, 1, 2003, 4, 2],
+								[1424, 3, 1, 2003, 5, 1],
+								[1424, 4, 1, 2003, 6, 1],
+								[1424, 5, 1, 2003, 6, 30],
+								[1424, 6, 1, 2003, 7, 29],
+								[1424, 7, 1, 2003, 8, 27],
+								[1424, 8, 1, 2003, 9, 26],
+								[1424, 9, 1, 2003, 10, 25],
+								[1424, 10, 1, 2003, 11, 24],
+								[1424, 11, 1, 2004, 0, 23],
+								[1425, 0, 1, 2004, 1, 21],
+								[1425, 1, 1, 2004, 2, 22],
+								[1425, 2, 1, 2004, 3, 20],
+								[1425, 3, 1, 2004, 4, 20],
+								[1426, 2, 1, 2005, 3, 10],
+								[1426, 3, 1, 2005, 4, 9],
+								[1426, 4, 1, 2005, 5, 8],
+								[1426, 5, 1, 2005, 6, 7],
+								[1426, 6, 1, 2005, 7, 6],
+								[1428, 9, 1, 2007, 9, 13],
+								[1428, 10, 1, 2007, 10, 11],
+								[1428, 11, 1, 2007, 11, 11],
+								[1429, 0, 1, 2008, 0, 10],
+								[1429, 1, 1, 2008, 1, 8],
+								[1429, 2, 1, 2008, 2, 9],
+								[1480, 0, 1, 2057, 6, 3],
+								[1480, 1, 1, 2057, 7, 1],
+								[1480, 2, 1, 2057, 7, 31],
+								[1480, 3, 1, 2057, 8, 30],
+								[1480, 4, 1, 2057, 9, 29],
+								[1480, 5, 1, 2057, 10, 27],
+								[1480, 6, 1, 2057, 11, 27],
+								[1480, 7, 1, 2058, 0, 25],
+								[1480, 8, 1, 2058, 1, 24],
+								[1480, 9, 1, 2058, 2, 25],
+								[1480, 10, 1, 2058, 3, 24],
+								[1480, 11, 1, 2058, 4, 23]
+		        ];
+		        var idate, gdate;
+		        var dateIslamic;
+		        var diff;
+		        dojo.forEach(dates, function (d, i) {
+		            idate = new dojox.date.umalqura.Date(d[0], d[1], d[2]);
+		            gdate = new Date(d[3], d[4], d[5]);
+
+		            t.is(0, dojo.date.compare(idate.toGregorian(), gdate, "date"));
+
+		            dateIslamic = new dojox.date.umalqura.Date();
+		            dateIslamic.fromGregorian(gdate);
+
+		            diff = dojox.date.umalqura.compare(dateIslamic, idate, "date");
+
+		            var errorMsg = "year: " + d[0] + " month: " + d[1] + " day: " + d[2] + ",";
+
+		            var yearDiff = dateIslamic.getFullYear() - idate.getFullYear();
+		            t.is(dateIslamic.getFullYear(), idate.getFullYear(), "error at year " + errorMsg);
+
+		            var monthDiff = dateIslamic.getMonth() - idate.getMonth();
+		            t.is(0, monthDiff, "error at month " + errorMsg);
+
+		            var dayDiff = dateIslamic.getDate() - idate.getDate();
+		            t.is(0, dayDiff, "error at day " + errorMsg + dateIslamic);
+		        });
+		    }
+		},
+
+		{
+		    name: "fromGregorian",
+		    runTest: function (t) {
+		        var dateIslamic = new dojox.date.umalqura.Date();
+		        var dateGregorian = new Date(2010, 2, 22);
+		        var iDate, gDate;
+		        dateIslamic.fromGregorian(dateGregorian);
+		        var inputDate = new dojox.date.umalqura.Date(1431, 3, 6);
+		        t.is(0, dojox.date.umalqura.compare(inputDate, dateIslamic, "date"));
+
+		        t.is(0, dojo.date.compare(new Date(2010, 2, 22), dateGregorian, "date"));
+		        var dates = [
+			 	         [1431, 3, 6, 2010, 2, 22],
+			 	         [1400, 0, 1, 1979, 10, 20],
+			 	         [1400, 1, 1, 1979, 11, 19],
+			 	         [1400, 2, 1, 1980, 0, 18],
+			 	         [1400, 3, 1, 1980, 1, 16],
+			 	         [1400, 4, 1, 1980, 2, 17],
+			 	         [1400, 5, 1, 1980, 3, 15],
+			 	         [1400, 6, 1, 1980, 4, 14],
+			 	         [1400, 7, 1, 1980, 5, 13],
+			 	         [1400, 8, 1, 1980, 6, 12],
+			 	         [1400, 9, 1, 1980, 7, 11],
+			 	         [1400, 10, 1, 1980, 8, 9],
+			 	         [1400, 11, 1, 1980, 9, 9],
+			 	         [1401, 0, 1, 1980, 10, 8],
+			 	         [1401, 1, 1, 1980, 11, 7],
+			 	         [1401, 2, 1, 1981, 0, 6],
+			 	         [1401, 3, 1, 1981, 1, 5],
+			 	         [1401, 4, 1, 1981, 2, 6],
+			 	         [1401, 5, 1, 1981, 3, 5],
+			 	         [1401, 6, 1, 1981, 4, 4],
+			 	         [1401, 7, 1, 1981, 5, 2],
+			 	         [1401, 8, 1, 1981, 6, 2],
+			 	         [1401, 9, 1, 1981, 6, 31],
+			 	         [1401, 10, 1, 1981, 7, 29],
+			 	         [1401, 11, 1, 1981, 8, 28],
+			 	         [1402, 0, 1, 1981, 9, 28],
+			 	         [1402, 1, 1, 1981, 10, 26],
+			 	         [1402, 2, 1, 1981, 11, 26],
+			 	         [1402, 3, 1, 1982, 0, 24],
+			 	         [1402, 4, 1, 1982, 1, 23],
+			 	         [1402, 5, 1, 1982, 2, 25],
+			 	         [1402, 6, 1, 1982, 3, 23],
+			 	         [1402, 7, 1, 1982, 4, 23],
+			 	         [1402, 8, 1, 1982, 5, 22],
+			 	         [1402, 9, 1, 1982, 6, 21],
+			 	         [1402, 10, 1, 1982, 7, 20],
+			 	         [1402, 11, 1, 1982, 8, 18],
+			 	         [1403, 0, 1, 1982, 9, 18],
+			 	         [1403, 1, 1, 1982, 10, 16],
+			 	         [1403, 2, 1, 1982, 11, 15],
+			 	         [1403, 3, 1, 1983, 0, 14],
+			 	         [1403, 4, 1, 1983, 1, 12],
+			 	         [1403, 5, 1, 1983, 2, 14],
+			 	         [1403, 6, 1, 1983, 3, 12],
+			 	         [1403, 7, 1, 1983, 4, 12],
+			 	         [1403, 8, 1, 1983, 5, 11],
+			 	         [1403, 9, 1, 1983, 6, 10],
+			 	         [1403, 10, 1, 1983, 7, 9],
+			 	         [1403, 11, 1, 1983, 8, 8],
+			 	         [1404, 0, 1, 1983, 9, 7],
+			 	         [1404, 1, 1, 1983, 10, 6],
+			 	         [1404, 2, 1, 1983, 11, 5],
+			 	         [1404, 3, 1, 1984, 0, 4],
+			 	         [1404, 4, 1, 1984, 1, 3],
+			 	         [1404, 5, 1, 1984, 2, 4],
+			 	         [1404, 6, 1, 1984, 3, 2],
+			 	         [1404, 7, 1, 1984, 4, 2],
+			 	         [1404, 8, 1, 1984, 5, 1],
+			 	         [1404, 9, 1, 1984, 5, 30],
+			 	         [1404, 10, 1, 1984, 6, 29],
+			 	         [1404, 11, 1, 1984, 7, 28],
+			 	         [1405, 0, 1, 1984, 8, 26],
+			 	         [1405, 1, 1, 1984, 9, 25],
+			 	         [1405, 2, 1, 1984, 10, 24],
+			 	         [1405, 3, 1, 1984, 11, 24],
+			 	         [1405, 4, 1, 1985, 0, 22],
+			 	         [1405, 5, 1, 1985, 1, 21],
+			 	         [1405, 6, 1, 1985, 2, 22],
+			 	         [1405, 7, 1, 1985, 3, 21],
+			 	         [1405, 8, 1, 1985, 4, 21],
+			 	         [1405, 9, 1, 1985, 5, 19],
+			 	         [1405, 10, 1, 1985, 6, 19],
+			 	         [1405, 11, 1, 1985, 7, 17],
+			 	         [1406, 0, 1, 1985, 8, 16],
+			 	         [1406, 1, 1, 1985, 9, 15],
+			 	         [1406, 2, 1, 1985, 10, 14],
+			 	         [1406, 3, 1, 1985, 11, 13],
+			 	         [1406, 4, 1, 1986, 0, 12],
+			 	         [1406, 5, 1, 1986, 1, 10],
+			 	         [1406, 6, 1, 1986, 2, 12],
+			 	         [1406, 7, 1, 1986, 3, 10],
+			 	         [1406, 8, 1, 1986, 4, 10],
+			 	         [1406, 9, 1, 1986, 5, 8],
+			 	         [1406, 10, 1, 1986, 6, 8],
+			 	         [1406, 11, 1, 1986, 7, 7],
+			 	         [1407, 0, 1, 1986, 8, 5],
+			 	         [1407, 1, 1, 1986, 9, 5],
+			 	         [1407, 2, 1, 1986, 10, 3],
+			 	         [1407, 3, 1, 1986, 11, 3],
+			 	         [1407, 4, 1, 1987, 0, 1],
+			 	         [1407, 5, 1, 1987, 0, 31],
+			 	         [1407, 6, 1, 1987, 2, 1],
+			 	         [1407, 7, 1, 1987, 2, 30],
+			 	         [1407, 8, 1, 1987, 3, 29],
+			 	         [1407, 9, 1, 1987, 4, 28],
+			 	         [1407, 10, 1, 1987, 5, 27],
+			 	         [1407, 11, 1, 1987, 6, 27],
+			 	         [1408, 0, 1, 1987, 7, 25],
+			 	         [1408, 1, 1, 1987, 8, 24],
+			 	         [1408, 2, 1, 1987, 9, 24],
+			 	         [1408, 3, 1, 1987, 10, 22],
+			 	         [1408, 4, 1, 1987, 11, 22],
+			 	         [1408, 5, 1, 1988, 0, 20],
+			 	         [1408, 6, 1, 1988, 1, 19],
+			 	         [1408, 7, 1, 1988, 2, 19],
+			 	         [1408, 8, 1, 1988, 3, 17],
+			 	         [1408, 9, 1, 1988, 4, 17],
+			 	         [1408, 10, 1, 1988, 5, 15],
+			 	         [1408, 11, 1, 1988, 6, 15],
+			 	         [1409, 0, 1, 1988, 7, 13],
+			 	         [1409, 1, 1, 1988, 8, 12],
+			 	         [1409, 2, 1, 1988, 9, 12],
+			 	         [1409, 3, 1, 1988, 10, 11],
+			 	         [1409, 4, 1, 1988, 11, 10],
+			 	         [1409, 5, 1, 1989, 0, 9],
+			 	         [1409, 6, 1, 1989, 1, 7],
+			 	         [1409, 7, 1, 1989, 2, 9],
+			 	         [1409, 8, 1, 1989, 3, 7],
+			 	         [1409, 9, 1, 1989, 4, 6],
+			 	         [1409, 10, 1, 1989, 5, 5],
+			 	         [1409, 11, 1, 1989, 6, 4],
+			 	         [1410, 0, 1, 1989, 7, 3],
+			 	         [1410, 1, 1, 1989, 8, 1],
+			 	         [1410, 2, 1, 1989, 9, 1],
+			 	         [1410, 3, 1, 1989, 9, 31],
+			 	         [1410, 4, 1, 1989, 10, 30],
+			 	         [1410, 5, 1, 1989, 11, 29],
+			 	         [1410, 6, 1, 1990, 0, 28],
+			 	         [1410, 7, 1, 1990, 1, 26],
+			 	         [1410, 8, 1, 1990, 2, 28],
+			 	         [1410, 9, 1, 1990, 3, 26],
+			 	         [1410, 10, 1, 1990, 4, 25],
+			 	         [1410, 11, 1, 1990, 5, 24],
+			 	         [1411, 0, 1, 1990, 6, 23],
+			 	         [1411, 1, 1, 1990, 7, 22],
+			 	         [1411, 2, 1, 1990, 8, 20],
+			 	         [1411, 3, 1, 1990, 9, 20],
+			 	         [1411, 4, 1, 1990, 10, 19],
+			 	         [1411, 5, 1, 1990, 11, 18],
+			 	         [1411, 6, 1, 1991, 0, 17],
+			 	         [1411, 7, 1, 1991, 1, 16],
+			 	         [1411, 8, 1, 1991, 2, 17],
+			 	         [1411, 9, 1, 1991, 3, 16],
+			 	         [1411, 10, 1, 1991, 4, 15],
+			 	         [1411, 11, 1, 1991, 5, 13],
+			 	         [1412, 0, 1, 1991, 6, 13],
+			 	         [1412, 1, 1, 1991, 7, 11],
+			 	         [1412, 2, 1, 1991, 8, 10],
+			 	         [1412, 3, 1, 1991, 9, 9],
+			 	         [1412, 4, 1, 1991, 10, 8],
+			 	         [1412, 5, 1, 1991, 11, 7],
+			 	         [1412, 6, 1, 1992, 0, 6],
+			 	         [1412, 7, 1, 1992, 1, 5],
+			 	         [1412, 8, 1, 1992, 2, 6],
+			 	         [1412, 9, 1, 1992, 3, 4],
+			 	         [1412, 10, 1, 1992, 4, 4],
+			 	         [1412, 11, 1, 1992, 5, 2],
+			 	         [1413, 0, 1, 1992, 6, 1],
+			 	         [1413, 1, 1, 1992, 6, 31],
+			 	         [1413, 2, 1, 1992, 7, 29],
+			 	         [1413, 3, 1, 1992, 8, 28],
+			 	         [1413, 4, 1, 1992, 9, 27],
+			 	         [1413, 5, 1, 1992, 10, 25],
+			 	         [1413, 6, 1, 1992, 11, 25],
+			 	         [1413, 7, 1, 1993, 0, 24],
+			 	         [1413, 8, 1, 1993, 1, 22],
+			 	         [1413, 9, 1, 1993, 2, 24],
+			 	         [1413, 10, 1, 1993, 3, 23],
+			 	         [1413, 11, 1, 1993, 4, 22],
+			 	         [1414, 0, 1, 1993, 5, 21],
+			 	         [1414, 1, 1, 1993, 6, 21],
+			 	         [1414, 2, 1, 1993, 7, 19],
+			 	         [1414, 3, 1, 1993, 8, 17],
+			 	         [1414, 4, 1, 1993, 9, 17],
+			 	         [1414, 5, 1, 1993, 10, 15],
+			 	         [1414, 6, 1, 1993, 11, 14],
+			 	         [1414, 7, 1, 1994, 0, 13],
+			 	         [1414, 8, 1, 1994, 1, 12],
+			 	         [1414, 9, 1, 1994, 2, 13],
+			 	         [1414, 10, 1, 1994, 3, 12],
+			 	         [1414, 11, 1, 1994, 4, 12],
+			 	         [1415, 0, 1, 1994, 5, 10],
+			 	         [1415, 1, 1, 1994, 6, 10],
+			 	         [1415, 2, 1, 1994, 7, 9],
+			 	         [1415, 3, 1, 1994, 8, 7],
+			 	         [1415, 4, 1, 1994, 9, 6],
+			 	         [1415, 5, 1, 1994, 10, 5],
+			 	         [1415, 6, 1, 1994, 11, 4],
+			 	         [1415, 7, 1, 1995, 0, 2],
+			 	         [1415, 8, 1, 1995, 1, 1],
+			 	         [1415, 9, 1, 1995, 2, 2],
+			 	         [1415, 10, 1, 1995, 3, 1],
+			 	         [1415, 11, 1, 1995, 4, 1],
+			 	         [1416, 0, 1, 1995, 4, 30],
+			 	         [1416, 1, 1, 1995, 5, 29],
+			 	         [1416, 2, 1, 1995, 6, 29],
+			 	         [1416, 3, 1, 1995, 7, 27],
+			 	         [1416, 4, 1, 1995, 8, 26],
+			 	         [1416, 5, 1, 1995, 9, 25],
+			 	         [1416, 6, 1, 1995, 10, 24],
+			 	         [1416, 7, 1, 1995, 11, 23],
+			 	         [1416, 8, 1, 1996, 0, 21],
+			 	         [1416, 9, 1, 1996, 1, 20],
+			 	         [1416, 10, 1, 1996, 2, 20],
+			 	         [1416, 11, 1, 1996, 3, 19],
+			 	         [1417, 0, 1, 1996, 4, 18],
+			 	         [1417, 1, 1, 1996, 5, 17],
+			 	         [1417, 2, 1, 1996, 6, 17],
+			 	         [1417, 3, 1, 1996, 7, 16],
+			 	         [1417, 4, 1, 1996, 8, 14],
+			 	         [1417, 5, 1, 1996, 9, 13],
+			 	         [1417, 6, 1, 1996, 10, 12],
+			 	         [1417, 7, 1, 1996, 11, 12],
+			 	         [1417, 8, 1, 1997, 0, 10],
+			 	         [1417, 9, 1, 1997, 1, 9],
+			 	         [1417, 10, 1, 1997, 2, 10],
+			 	         [1417, 11, 1, 1997, 3, 8],
+			 	         [1418, 0, 1, 1997, 4, 8],
+			 	         [1418, 1, 1, 1997, 5, 6],
+			 	         [1418, 2, 1, 1997, 6, 6],
+			 	         [1418, 3, 1, 1997, 7, 5],
+			 	         [1418, 4, 1, 1997, 8, 3],
+			 	         [1418, 5, 1, 1997, 9, 3],
+			 	         [1418, 6, 1, 1997, 10, 1],
+			 	         [1423, 7, 1, 2002, 9, 7],
+			 	         [1423, 8, 1, 2002, 10, 6],
+			 	         [1423, 9, 1, 2002, 11, 5],
+			 	         [1423, 10, 1, 2003, 0, 4],
+			 	         [1423, 11, 1, 2003, 1, 2],
+			 	         [1424, 0, 1, 2003, 2, 4],
+			 	         [1424, 1, 1, 2003, 3, 3],
+			 	         [1424, 2, 1, 2003, 4, 2],
+			 	         [1424, 3, 1, 2003, 5, 1],
+			 	         [1424, 4, 1, 2003, 6, 1],
+			 	         [1424, 5, 1, 2003, 6, 30],
+			 	         [1424, 6, 1, 2003, 7, 29],
+			 	         [1424, 7, 1, 2003, 8, 27],
+			 	         [1424, 8, 1, 2003, 9, 26],
+			 	         [1424, 9, 1, 2003, 10, 25],
+			 	         [1424, 10, 1, 2003, 11, 24],
+			 	         [1424, 11, 1, 2004, 0, 23],
+			 	         [1425, 0, 1, 2004, 1, 21],
+			 	         [1425, 1, 1, 2004, 2, 22],
+			 	         [1425, 2, 1, 2004, 3, 20],
+			 	         [1425, 3, 1, 2004, 4, 20],
+			 	         [1425, 4, 1, 2004, 5, 19],
+			 	         [1425, 5, 1, 2004, 6, 18],
+			 	         [1425, 6, 1, 2004, 7, 17],
+			 	         [1425, 7, 1, 2004, 8, 15],
+			 	         [1425, 8, 1, 2004, 9, 15],
+			 	         [1425, 9, 1, 2004, 10, 14],
+			 	         [1425, 10, 1, 2004, 11, 13],
+			 	         [1425, 11, 1, 2005, 0, 12],
+			 	         [1426, 0, 1, 2005, 1, 10],
+			 	         [1426, 1, 1, 2005, 2, 11],
+			 	         [1426, 2, 1, 2005, 3, 10],
+			 	         [1426, 3, 1, 2005, 4, 9],
+			 	         [1426, 4, 1, 2005, 5, 8],
+			 	         [1426, 5, 1, 2005, 6, 7],
+			 	         [1426, 6, 1, 2005, 7, 6],
+			 	         [1426, 7, 1, 2005, 8, 5],
+			 	         [1426, 8, 1, 2005, 9, 4],
+			 	         [1426, 9, 1, 2005, 10, 3],
+			 	         [1426, 10, 1, 2005, 11, 3],
+			 	         [1426, 11, 1, 2006, 0, 1],
+			 	         [1427, 0, 1, 2006, 0, 31],
+			 	         [1427, 1, 1, 2006, 2, 1],
+			 	         [1427, 2, 1, 2006, 2, 30],
+			 	         [1427, 3, 1, 2006, 3, 29],
+			 	         [1427, 4, 1, 2006, 4, 28],
+			 	         [1427, 5, 1, 2006, 5, 27],
+			 	         [1427, 6, 1, 2006, 6, 26],
+			 	         [1427, 7, 1, 2006, 7, 25],
+			 	         [1427, 8, 1, 2006, 8, 24],
+			 	         [1427, 9, 1, 2006, 9, 23],
+			 	         [1427, 10, 1, 2006, 10, 22],
+			 	         [1427, 11, 1, 2006, 11, 22],
+			 	         [1428, 0, 1, 2007, 0, 20],
+			 	         [1428, 1, 1, 2007, 1, 19],
+			 	         [1428, 2, 1, 2007, 2, 20],
+			 	         [1428, 3, 1, 2007, 3, 18],
+			 	         [1428, 4, 1, 2007, 4, 18],
+			 	         [1428, 5, 1, 2007, 5, 16],
+			 	         [1428, 6, 1, 2007, 6, 15],
+			 	         [1428, 7, 1, 2007, 7, 14],
+			 	         [1428, 8, 1, 2007, 8, 13],
+			 	         [1428, 9, 1, 2007, 9, 13],
+			 	         [1428, 10, 1, 2007, 10, 11],
+			 	         [1428, 11, 1, 2007, 11, 11],
+			 	         [1429, 0, 1, 2008, 0, 10],
+			 	         [1429, 1, 1, 2008, 1, 8],
+			 	         [1429, 2, 1, 2008, 2, 9],
+			 	         [1429, 3, 1, 2008, 3, 7],
+			 	         [1429, 4, 1, 2008, 4, 6],
+			 	         [1429, 5, 1, 2008, 5, 5],
+			 	         [1429, 6, 1, 2008, 6, 4],
+			 	         [1429, 7, 1, 2008, 7, 2],
+			 	         [1429, 8, 1, 2008, 8, 1],
+			 	         [1429, 9, 1, 2008, 9, 1],
+			 	         [1429, 10, 1, 2008, 9, 30],
+			 	         [1429, 11, 1, 2008, 10, 29],
+			 	         [1430, 0, 1, 2008, 11, 29],
+			 	         [1430, 1, 1, 2009, 0, 27],
+			 	         [1430, 2, 1, 2009, 1, 26],
+			 	         [1430, 3, 1, 2009, 2, 28],
+			 	         [1430, 4, 1, 2009, 3, 26],
+			 	         [1430, 5, 1, 2009, 4, 25],
+			 	         [1430, 6, 1, 2009, 5, 24],
+			 	         [1430, 7, 1, 2009, 6, 23],
+			 	         [1430, 8, 1, 2009, 7, 22],
+			 	         [1430, 9, 1, 2009, 8, 20],
+			 	         [1430, 10, 1, 2009, 9, 20],
+			 	         [1430, 11, 1, 2009, 10, 18],
+			 	         [1431, 0, 1, 2009, 11, 18],
+			 	         [1431, 1, 1, 2010, 0, 16],
+			 	         [1431, 2, 1, 2010, 1, 15],
+			 	         [1431, 3, 1, 2010, 2, 17],
+			 	         [1431, 4, 1, 2010, 3, 15],
+			 	         [1431, 5, 1, 2010, 4, 15],
+			 	         [1431, 6, 1, 2010, 5, 13],
+			 	         [1431, 7, 1, 2010, 6, 13],
+			 	         [1431, 8, 1, 2010, 7, 11],
+			 	         [1431, 9, 1, 2010, 8, 10],
+			 	         [1431, 10, 1, 2010, 9, 9],
+			 	         [1431, 11, 1, 2010, 10, 7],
+			 	         [1432, 0, 1, 2010, 11, 7],
+			 	         [1432, 1, 1, 2011, 0, 5],
+			 	         [1432, 2, 1, 2011, 1, 4],
+			 	         [1432, 3, 1, 2011, 2, 6],
+			 	         [1432, 4, 1, 2011, 3, 5],
+			 	         [1432, 5, 1, 2011, 4, 4],
+			 	         [1432, 6, 1, 2011, 5, 3],
+			 	         [1432, 7, 1, 2011, 6, 2],
+			 	         [1432, 8, 1, 2011, 7, 1],
+			 	         [1432, 9, 1, 2011, 7, 30],
+			 	         [1432, 10, 1, 2011, 8, 29],
+			 	         [1432, 11, 1, 2011, 9, 28],
+			 	         [1433, 0, 1, 2011, 10, 26],
+			 	         [1433, 1, 1, 2011, 11, 26],
+			 	         [1433, 2, 1, 2012, 0, 24],
+			 	         [1433, 3, 1, 2012, 1, 23],
+			 	         [1433, 4, 1, 2012, 2, 24],
+			 	         [1433, 5, 1, 2012, 3, 22],
+			 	         [1433, 6, 1, 2012, 4, 22],
+			 	         [1433, 7, 1, 2012, 5, 21],
+			 	         [1433, 8, 1, 2012, 6, 20],
+			 	         [1433, 9, 1, 2012, 7, 19],
+			 	         [1433, 10, 1, 2012, 8, 17],
+			 	         [1433, 11, 1, 2012, 9, 17],
+			 	         [1434, 0, 1, 2012, 10, 15],
+			 	         [1434, 1, 1, 2012, 11, 14],
+			 	         [1434, 2, 1, 2013, 0, 13],
+			 	         [1434, 3, 1, 2013, 1, 11],
+			 	         [1434, 4, 1, 2013, 2, 13],
+			 	         [1434, 5, 1, 2013, 3, 11],
+			 	         [1434, 6, 1, 2013, 4, 11],
+			 	         [1434, 7, 1, 2013, 5, 10],
+			 	         [1434, 8, 1, 2013, 6, 9],
+			 	         [1434, 9, 1, 2013, 7, 8],
+			 	         [1434, 10, 1, 2013, 8, 7],
+			 	         [1434, 11, 1, 2013, 9, 6],
+			 	         [1435, 0, 1, 2013, 10, 4],
+			 	         [1435, 1, 1, 2013, 11, 4],
+			 	         [1435, 2, 1, 2014, 0, 2],
+			 	         [1435, 3, 1, 2014, 1, 1],
+			 	         [1435, 4, 1, 2014, 2, 2],
+			 	         [1435, 5, 1, 2014, 3, 1],
+			 	         [1435, 6, 1, 2014, 3, 30],
+			 	         [1435, 7, 1, 2014, 4, 30],
+			 	         [1435, 8, 1, 2014, 5, 28],
+			 	         [1435, 9, 1, 2014, 6, 28],
+			 	         [1435, 10, 1, 2014, 7, 27],
+			 	         [1435, 11, 1, 2014, 8, 25],
+			 	         [1436, 0, 1, 2014, 9, 25],
+			 	         [1436, 1, 1, 2014, 10, 23],
+			 	         [1436, 2, 1, 2014, 11, 23],
+			 	         [1436, 3, 1, 2015, 0, 21],
+			 	         [1436, 4, 1, 2015, 1, 20],
+			 	         [1436, 5, 1, 2015, 2, 21],
+			 	         [1436, 6, 1, 2015, 3, 20],
+			 	         [1436, 7, 1, 2015, 4, 19],
+			 	         [1436, 8, 1, 2015, 5, 18],
+			 	         [1436, 9, 1, 2015, 6, 17],
+			 	         [1436, 10, 1, 2015, 7, 16],
+			 	         [1436, 11, 1, 2015, 8, 14],
+			 	         [1437, 0, 1, 2015, 9, 14],
+			 	         [1437, 1, 1, 2015, 10, 13],
+			 	         [1437, 2, 1, 2015, 11, 12],
+			 	         [1437, 3, 1, 2016, 0, 11],
+			 	         [1437, 4, 1, 2016, 1, 10],
+			 	         [1437, 5, 1, 2016, 2, 10],
+			 	         [1437, 6, 1, 2016, 3, 8],
+			 	         [1437, 7, 1, 2016, 4, 8],
+			 	         [1437, 8, 1, 2016, 5, 6],
+			 	         [1437, 9, 1, 2016, 6, 6],
+			 	         [1437, 10, 1, 2016, 7, 4],
+			 	         [1437, 11, 1, 2016, 8, 2],
+			 	         [1438, 0, 1, 2016, 9, 2],
+			 	         [1438, 1, 1, 2016, 10, 1],
+			 	         [1438, 2, 1, 2016, 10, 30],
+			 	         [1438, 3, 1, 2016, 11, 30],
+			 	         [1438, 4, 1, 2017, 0, 29],
+			 	         [1444, 10, 1, 2023, 4, 21],
+			 	         [1444, 11, 1, 2023, 5, 19],
+			 	         [1445, 0, 1, 2023, 6, 19],
+			 	         [1445, 1, 1, 2023, 7, 17],
+			 	         [1445, 2, 1, 2023, 8, 16],
+			 	         [1445, 3, 1, 2023, 9, 16],
+			 	         [1445, 4, 1, 2023, 10, 15],
+			 	         [1445, 5, 1, 2023, 11, 14],
+			 	         [1445, 6, 1, 2024, 0, 13],
+			 	         [1445, 7, 1, 2024, 1, 11],
+			 	         [1445, 8, 1, 2024, 2, 11],
+			 	         [1445, 9, 1, 2024, 3, 10],
+			 	         [1445, 10, 1, 2024, 4, 9],
+			 	         [1445, 11, 1, 2024, 5, 7],
+			 	         [1446, 0, 1, 2024, 6, 7],
+			 	         [1446, 1, 1, 2024, 7, 5],
+			 	         [1446, 2, 1, 2024, 8, 4],
+			 	         [1446, 3, 1, 2024, 9, 4],
+			 	         [1446, 4, 1, 2024, 10, 3],
+			 	         [1446, 5, 1, 2024, 11, 2],
+			 	         [1446, 6, 1, 2025, 0, 1],
+			 	         [1446, 7, 1, 2025, 0, 31],
+			 	         [1446, 8, 1, 2025, 2, 1],
+			 	         [1446, 9, 1, 2025, 2, 30],
+			 	         [1446, 10, 1, 2025, 3, 29],
+			 	         [1446, 11, 1, 2025, 4, 28],
+			 	         [1447, 0, 1, 2025, 5, 26],
+			 	         [1447, 1, 1, 2025, 6, 26],
+			 	         [1447, 2, 1, 2025, 7, 24],
+			 	         [1447, 3, 1, 2025, 8, 23],
+			 	         [1447, 4, 1, 2025, 9, 23],
+			 	         [1451, 11, 1, 2030, 3, 4],
+			 	         [1452, 0, 1, 2030, 4, 3],
+			 	         [1452, 1, 1, 2030, 5, 2],
+			 	         [1452, 2, 1, 2030, 6, 2],
+			 	         [1452, 3, 1, 2030, 7, 1],
+			 	         [1452, 4, 1, 2030, 7, 30],
+			 	         [1452, 5, 1, 2030, 8, 29],
+			 	         [1452, 6, 1, 2030, 9, 28],
+			 	         [1452, 7, 1, 2030, 10, 26],
+			 	         [1452, 8, 1, 2030, 11, 26],
+			 	         [1452, 9, 1, 2031, 0, 24],
+			 	         [1452, 10, 1, 2031, 1, 23],
+			 	         [1452, 11, 1, 2031, 2, 24],
+			 	         [1453, 0, 1, 2031, 3, 23],
+			 	         [1453, 1, 1, 2031, 4, 22],
+			 	         [1453, 2, 1, 2031, 5, 21],
+			 	         [1453, 3, 1, 2031, 6, 21],
+			 	         [1453, 4, 1, 2031, 7, 20],
+			 	         [1453, 5, 1, 2031, 8, 18],
+			 	         [1453, 6, 1, 2031, 9, 17],
+			 	         [1453, 7, 1, 2031, 10, 16],
+			 	         [1453, 8, 1, 2031, 11, 15],
+			 	         [1453, 9, 1, 2032, 0, 14],
+			 	         [1453, 10, 1, 2032, 1, 12],
+			 	         [1453, 11, 1, 2032, 2, 13],
+			 	         [1454, 0, 1, 2032, 3, 11],
+			 	         [1454, 1, 1, 2032, 4, 10],
+			 	         [1454, 2, 1, 2032, 5, 9],
+			 	         [1454, 3, 1, 2032, 6, 9],
+			 	         [1454, 4, 1, 2032, 7, 8],
+			 	         [1454, 5, 1, 2032, 8, 6],
+			 	         [1454, 6, 1, 2032, 9, 6],
+			 	         [1454, 7, 1, 2032, 10, 4],
+			 	         [1454, 8, 1, 2032, 11, 4],
+			 	         [1454, 9, 1, 2033, 0, 2],
+			 	         [1454, 10, 1, 2033, 1, 1],
+			 	         [1454, 11, 1, 2033, 2, 2],
+			 	         [1455, 0, 1, 2033, 3, 1],
+			 	         [1455, 1, 1, 2033, 3, 30],
+			 	         [1455, 2, 1, 2033, 4, 29],
+			 	         [1455, 3, 1, 2033, 5, 28],
+			 	         [1455, 4, 1, 2033, 6, 28],
+			 	         [1455, 5, 1, 2033, 7, 26],
+			 	         [1455, 6, 1, 2033, 8, 25],
+			 	         [1455, 7, 1, 2033, 9, 24],
+			 	         [1455, 8, 1, 2033, 10, 23],
+			 	         [1455, 9, 1, 2033, 11, 23],
+			 	         [1455, 10, 1, 2034, 0, 21],
+			 	         [1455, 11, 1, 2034, 1, 20],
+			 	         [1456, 0, 1, 2034, 2, 21],
+			 	         [1456, 1, 1, 2034, 3, 20],
+			 	         [1456, 2, 1, 2034, 4, 19],
+			 	         [1456, 3, 1, 2034, 5, 17],
+			 	         [1456, 4, 1, 2034, 6, 17],
+			 	         [1456, 5, 1, 2034, 7, 15],
+			 	         [1456, 6, 1, 2034, 8, 14],
+			 	         [1456, 7, 1, 2034, 9, 13],
+			 	         [1456, 8, 1, 2034, 10, 12],
+			 	         [1456, 9, 1, 2034, 11, 12],
+			 	         [1456, 10, 1, 2035, 0, 11],
+			 	         [1456, 11, 1, 2035, 1, 9],
+			 	         [1457, 0, 1, 2035, 2, 11],
+			 	         [1457, 1, 1, 2035, 3, 9],
+			 	         [1458, 9, 1, 2036, 10, 19],
+			 	         [1458, 10, 1, 2036, 11, 19],
+			 	         [1458, 11, 1, 2037, 0, 17],
+			 	         [1459, 0, 1, 2037, 1, 16],
+			 	         [1459, 1, 1, 2037, 2, 18],
+			 	         [1459, 2, 1, 2037, 3, 17],
+			 	         [1459, 3, 1, 2037, 4, 16],
+			 	         [1459, 4, 1, 2037, 5, 15],
+			 	         [1459, 5, 1, 2037, 6, 14],
+			 	         [1459, 6, 1, 2037, 7, 12],
+			 	         [1459, 7, 1, 2037, 8, 11],
+			 	         [1459, 8, 1, 2037, 9, 10],
+			 	         [1468, 1, 1, 2045, 11, 10],
+			 	         [1468, 2, 1, 2046, 0, 8],
+			 	         [1468, 3, 1, 2046, 1, 7],
+			 	         [1468, 4, 1, 2046, 2, 9],
+			 	         [1468, 5, 1, 2046, 3, 7],
+			 	         [1468, 6, 1, 2046, 4, 7],
+			 	         [1468, 7, 1, 2046, 5, 5],
+			 	         [1468, 8, 1, 2046, 6, 5],
+			 	         [1468, 9, 1, 2046, 7, 3],
+			 	         [1468, 10, 1, 2046, 8, 2],
+			 	         [1468, 11, 1, 2046, 9, 1],
+			 	         [1469, 0, 1, 2046, 9, 31],
+			 	         [1469, 1, 1, 2046, 10, 29],
+			 	         [1469, 2, 1, 2046, 11, 28],
+			 	         [1469, 3, 1, 2047, 0, 27],
+			 	         [1469, 4, 1, 2047, 1, 26],
+			 	         [1469, 5, 1, 2047, 2, 27],
+			 	         [1469, 6, 1, 2047, 3, 26],
+			 	         [1469, 7, 1, 2047, 4, 26],
+			 	         [1469, 8, 1, 2047, 5, 24],
+			 	         [1469, 9, 1, 2047, 6, 24],
+			 	         [1469, 10, 1, 2047, 7, 23],
+			 	         [1469, 11, 1, 2047, 8, 21],
+			 	         [1470, 0, 1, 2047, 9, 20],
+			 	         [1470, 1, 1, 2047, 10, 19],
+			 	         [1470, 2, 1, 2047, 11, 18],
+			 	         [1470, 3, 1, 2048, 0, 16],
+			 	         [1470, 4, 1, 2048, 1, 15],
+			 	         [1470, 5, 1, 2048, 2, 16],
+			 	         [1470, 6, 1, 2048, 3, 14],
+			 	         [1470, 7, 1, 2048, 4, 14],
+			 	         [1470, 8, 1, 2048, 5, 12],
+			 	         [1470, 9, 1, 2048, 6, 12],
+			 	         [1470, 10, 1, 2048, 7, 11],
+			 	         [1470, 11, 1, 2048, 8, 10],
+			 	         [1471, 0, 1, 2048, 9, 9],
+			 	         [1471, 1, 1, 2048, 10, 7],
+			 	         [1471, 2, 1, 2048, 11, 7],
+			 	         [1471, 3, 1, 2049, 0, 5],
+			 	         [1471, 4, 1, 2049, 1, 3],
+			 	         [1471, 5, 1, 2049, 2, 5],
+			 	         [1471, 6, 1, 2049, 3, 3],
+			 	         [1471, 7, 1, 2049, 4, 3],
+			 	         [1471, 8, 1, 2049, 5, 2],
+			 	         [1471, 9, 1, 2049, 6, 1],
+			 	         [1471, 10, 1, 2049, 6, 31],
+			 	         [1471, 11, 1, 2049, 7, 30],
+			 	         [1472, 0, 1, 2049, 8, 28],
+			 	         [1472, 1, 1, 2049, 9, 28],
+			 	         [1472, 2, 1, 2049, 10, 26],
+			 	         [1473, 10, 1, 2051, 6, 9],
+			 	         [1473, 11, 1, 2051, 7, 8],
+			 	         [1474, 0, 1, 2051, 8, 6],
+			 	         [1474, 1, 1, 2051, 9, 6],
+			 	         [1474, 2, 1, 2051, 10, 5],
+			 	         [1474, 3, 1, 2051, 11, 4],
+			 	         [1474, 4, 1, 2052, 0, 3],
+			 	         [1474, 5, 1, 2052, 1, 2],
+			 	         [1474, 6, 1, 2052, 2, 2],
+			 	         [1474, 7, 1, 2052, 3, 1],
+			 	         [1474, 8, 1, 2052, 3, 30],
+			 	         [1474, 9, 1, 2052, 4, 29],
+			 	         [1474, 10, 1, 2052, 5, 28],
+			 	         [1474, 11, 1, 2052, 6, 27],
+			 	         [1475, 0, 1, 2052, 7, 26],
+			 	         [1475, 1, 1, 2052, 8, 24],
+			 	         [1475, 2, 1, 2052, 9, 24],
+			 	         [1475, 3, 1, 2052, 10, 22],
+			 	         [1475, 4, 1, 2052, 11, 22],
+			 	         [1475, 5, 1, 2053, 0, 21],
+			 	         [1475, 6, 1, 2053, 1, 20],
+			 	         [1475, 7, 1, 2053, 2, 21],
+			 	         [1475, 8, 1, 2053, 3, 20],
+			 	         [1475, 9, 1, 2053, 4, 19],
+			 	         [1475, 10, 1, 2053, 5, 17],
+			 	         [1475, 11, 1, 2053, 6, 17],
+			 	         [1476, 0, 1, 2053, 7, 15],
+			 	         [1476, 1, 1, 2053, 8, 13],
+			 	         [1476, 2, 1, 2053, 9, 13],
+			 	         [1476, 3, 1, 2053, 10, 11],
+			 	         [1476, 4, 1, 2053, 11, 11],
+			 	         [1477, 3, 1, 2054, 10, 1],
+			 	         [1477, 4, 1, 2054, 10, 30],
+			 	         [1477, 5, 1, 2054, 11, 30],
+			 	         [1477, 6, 1, 2055, 0, 29],
+			 	         [1477, 7, 1, 2055, 1, 27],
+			 	         [1477, 8, 1, 2055, 2, 29],
+			 	         [1477, 9, 1, 2055, 3, 28],
+			 	         [1477, 10, 1, 2055, 4, 28],
+			 	         [1477, 11, 1, 2055, 5, 26],
+			 	         [1478, 0, 1, 2055, 6, 25],
+			 	         [1478, 1, 1, 2055, 7, 24],
+			 	         [1479, 7, 1, 2057, 1, 5],
+			 	         [1479, 8, 1, 2057, 2, 6],
+			 	         [1479, 9, 1, 2057, 3, 5],
+			 	         [1479, 10, 1, 2057, 4, 5],
+			 	         [1479, 11, 1, 2057, 5, 3],
+			 	         [1480, 0, 1, 2057, 6, 3],
+			 	         [1480, 1, 1, 2057, 7, 1],
+			 	         [1480, 2, 1, 2057, 7, 31],
+			 	         [1480, 3, 1, 2057, 8, 30],
+			 	         [1480, 4, 1, 2057, 9, 29],
+			 	         [1480, 5, 1, 2057, 10, 27],
+			 	         [1480, 6, 1, 2057, 11, 27],
+			 	         [1480, 7, 1, 2058, 0, 25],
+			 	         [1480, 8, 1, 2058, 1, 24],
+			 	         [1480, 9, 1, 2058, 2, 25],
+			 	         [1480, 10, 1, 2058, 3, 24],
+			 	         [1480, 11, 1, 2058, 4, 23],
+
+			 	         //Special Case #1
+						 [1475, 5, 1, 2053, 0, 21],
+						 [1475, 5, 11, 2053, 0, 31],
+						 [1475, 5, 12, 2053, 1, 1],
+						 [1475, 5, 22, 2053, 1, 11],
+						 [1475, 5, 29, 2053, 1, 18],
+						 [1475, 5, 30, 2053, 1, 19]
+		        ];
+		        var idate, gdate, idate_expected;
+		        dateIslamic.fromGregorian(dateGregorian);
+		        var inputDate = new dojox.date.umalqura.Date(1431, 3, 6);
+		        t.is(0, dojox.date.umalqura.compare(inputDate, dateIslamic, "date"));
+		        dojo.forEach(dates, function (d, i) {
+
+		            idate = new dojox.date.umalqura.Date();
+		            idate_expected = new dojox.date.umalqura.Date(d[0], d[1], d[2]);
+		            gdate = new Date(d[3], d[4], d[5]);
+		            idate = new dojox.date.umalqura.Date();
+		            idate.fromGregorian(gdate);
+		            var errorMsg = "error at date Year=" + d[0] + " month= " + d[1] + " day= " + d[2];
+
+		            t.is(idate.getFullYear(), d[0], errorMsg + " error at Year");
+		            t.is(idate.getMonth(), d[1], errorMsg + " error at Month");
+		            t.is(idate.getDate(), d[2], errorMsg + " error at Day");
+
+		            t.is(0, dojo.date.compare(idate.fromGregorian(gdate), idate_expected, "date"), "year: " + d[0] + " month:" + d[1] + " day:" + d[2]);
+		        });
+
+		        //Special Case #2
+		        {
+		            var hYear, hMonth, hDay;
+		            var gYear, gMonth, gDay;
+		            hYear = 1400;
+		            hMonth = 0;
+		            hDay = 1;
+
+		            gYear = 1979;
+		            gMonth = 10;
+		            gDay = 20;
+
+		            var dateIslamic = new dojox.date.umalqura.Date();
+		            var dateGregorian = new Date(gYear, gMonth, gDay);
+		            var iDate, gDate;
+		            dateIslamic.fromGregorian(dateGregorian);
+		            var inputDate = new dojox.date.umalqura.Date(hYear, hMonth, hDay);
+
+		            t.is(inputDate.getFullYear(), hYear, "error in year");
+		            t.is(inputDate.getMonth(), hMonth, "error in month");
+		            t.is(inputDate.getDate(), hDay, "error in day");
+
+		            t.is(dateIslamic.getFullYear(), hYear, "error in conversion in year");
+		            t.is(dateIslamic.getMonth(), hMonth, "error in conversion in month");
+		            t.is(dateIslamic.getDate(), hDay, "error in conversion in Day");
+		            t.is(0, dojox.date.umalqura.compare(inputDate, dateIslamic, "date"));
+
+		        }
+		    }
+		},
+		{
+		    name: "getDay",
+		    runTest: function (t) {
+		        var dateTable = [
+					[1431, 0, 11, 1],
+					[1431, 1, 3, 1],
+					[1431, 2, 10, 3],
+					[1431, 3, 23, 4],
+					[1431, 6, 21, 6],
+					[1431, 6, 22, 0],
+					[1431, 7, 15, 2]
+		        ];
+		        dojo.forEach(dateTable, function (d, i) {
+		            var date = new dojox.date.umalqura.Date(d[0], d[1], d[2]);
+		            var gday = date.getDay();
+		            t.is(d[3], gday);
+		        });
+
+		    }
+		},
+		{
+		    name: "getDaysInIslamicMonth",
+		    runTest: function (t) {
+
+		        var dateTable = [
+					[1399, 11, 29]
+		        ];
+
+		        dojo.forEach(dateTable, function (d, i) {
+		            var date = new dojox.date.umalqura.Date(d[0], d[1], 1);
+		            t.is(d[2], dojox.date.umalqura.getDaysInMonth(date));
+		        });
+		    }
+		},
+		{
+		    name: "add_month",
+		    runTest: function (t) {
+		        var start = [
+						[1420, 1, 1422, 1],
+						[1430, 2, 1435, 2],
+						[1433, 0, 1434, 0],
+						[1422, 2, 1420, 2],
+						[1429, 3, 1427, 3],
+						[1431, 4, 1431, 6],
+						[1429, 7, 1429, 5],
+						[1431, 3, 1431, 5],
+						[1431, 3, 1431, 0],
+						[1431, 1, 1431, 2],
+						[1431, 9, 1431, 8]
+		        ];
+		        var add = [24, 60, 12, -24, -24, 2, -2, 2, -3, 1, -1];
+
+		        var dateHijriStart, dateHijriEnd, res, dateHijriRes;
+		        dojo.forEach(start, function (s, i) {
+		            dateHijriStart = new dojox.date.umalqura.Date(s[0], s[1], 1);
+		            dateHijriRes = dojox.date.umalqura.add(dateHijriStart, "month", add[i]);
+
+		            t.is(0, dateHijriRes.getMonth() - s[3]);
+		            t.is(0, dateHijriRes.getFullYear() - s[2]);
+		        });
+		    }
+		},
+        {
+	    name: "difference_month",
+		runTest: function (t) {
+		    var start = [
+                    [1420, 1, 1422, 1],
+                    [1430, 2, 1435, 2],
+                    [1433, 0, 1434, 0],
+                    [1422, 2, 1420, 2],
+                    [1429, 3, 1427, 3],
+                    [1431, 4, 1431, 6],
+                    [1429, 7, 1429, 5],
+                    [1431, 3, 1431, 5],
+                    [1431, 3, 1431, 0],
+                    [1431, 1, 1431, 2],
+                    [1431, 9, 1431, 8]
+		    ];
+		    var add = [24, 60, 12, -24, -24, 2, -2, 2, -3, 1, -1];
+
+		    var dateHijriStart, dateHijriEnd, res, dateHijriRes;
+		    dojo.forEach(start, function (s, i) {
+		        dateHijriStart = new dojox.date.umalqura.Date(s[0], s[1], 1);
+		        dateHijriRes = new dojox.date.umalqura.Date(s[2], s[3], 1);		        
+		        t.is(dojox.date.umalqura.difference(dateHijriStart, dateHijriRes, "month"), add[i]);
+		    });
+		}
+		},
+
+		{
+		    name: "getters",
+		    runTest: function (t) {
+
+		        var dates = [
+				           [1400, 1, 1],
+			 	           [1400, 0, 1, 1979, 10, 20],
+				           [1400, 1, 0, 1979, 11, 19],
+ 				           [1400, 2, 0, 1980, 0, 18],
+				           [1400, 3, 0, 1980, 1, 16],
+				           [1400, 4, 0, 1980, 2, 17],
+				           [1400, 5, 0, 1980, 3, 15],
+				           [1400, 6, 0, 1980, 4, 14],
+				           [1400, 7, 0, 1980, 5, 13],
+				           [1400, 8, 0, 1980, 6, 12],
+				           [1400, 9, 0, 1980, 7, 11],
+				           [1400, 10, 0, 1980, 8, 9],
+				           [1400, 11, 0, 1980, 9, 9],
+				           [1401, 0, 0, 1980, 10, 8],
+				           [1401, 1, 0, 1980, 11, 7],
+				           [1401, 2, 0, 1981, 0, 6],
+				           [1401, 3, 0, 1981, 1, 5],
+				           [1401, 4, 0, 1981, 2, 6],
+				           [1401, 5, 0, 1981, 3, 5],
+				           [1401, 6, 0, 1981, 4, 4],
+				           [1401, 7, 0, 1981, 5, 2],
+				           [1401, 8, 0, 1981, 6, 2],
+				           [1401, 9, 0, 1981, 6, 31],
+				           [1401, 10, 0, 1981, 7, 29],
+				           [1401, 11, 0, 1981, 8, 28],
+				           [1402, 0, 0, 1981, 9, 28],
+				           [1402, 1, 0, 1981, 10, 26],
+				           [1402, 2, 0, 1981, 11, 26],
+				           [1402, 3, 0, 1982, 0, 24],
+				           [1402, 4, 0, 1982, 1, 23],
+				           [1402, 5, 0, 1982, 2, 25],
+				           [1402, 6, 0, 1982, 3, 23],
+				           [1402, 7, 0, 1982, 4, 23],
+				           [1402, 8, 0, 1982, 5, 22],
+				           [1402, 9, 0, 1982, 6, 21],
+				           [1402, 10, 0, 1982, 7, 20],
+				           [1402, 11, 0, 1982, 8, 18],
+				           [1403, 0, 0, 1982, 9, 18],
+				           [1403, 1, 0, 1982, 10, 16],
+				           [1403, 2, 0, 1982, 11, 15],
+				           [1403, 3, 0, 1983, 0, 14],
+				           [1403, 4, 0, 1983, 1, 12],
+				           [1403, 5, 0, 1983, 2, 14],
+				           [1403, 6, 0, 1983, 3, 12],
+				           [1403, 7, 0, 1983, 4, 12],
+				           [1403, 8, 0, 1983, 5, 11],
+				           [1403, 9, 0, 1983, 6, 10],
+				           [1403, 10, 0, 1983, 7, 9],
+				           [1403, 11, 0, 1983, 8, 8],
+				           [1404, 0, 0, 1983, 9, 7],
+				           [1404, 1, 0, 1983, 10, 6],
+				           [1404, 2, 0, 1983, 11, 5],
+                           [1404, 3, 0, 1984, 0, 4],
+				           [1404, 4, 0, 1984, 1, 3],
+				           [1404, 5, 0, 1984, 2, 4],
+				           [1404, 6, 0, 1984, 3, 2],
+				           [1404, 7, 0, 1984, 4, 2],
+				           [1404, 8, 0, 1984, 5, 1],
+				           [1404, 9, 0, 1984, 5, 30],
+				           [1404, 10, 0, 1984, 6, 29],
+				           [1404, 11, 0, 1984, 7, 28],
+		                   [1405, 0, 0, 1984, 8, 26],
+				           [1405, 1, 0, 1984, 9, 25],
+				           [1405, 2, 0, 1984, 10, 24],
+				           [1405, 3, 0, 1984, 11, 24],
+				           [1405, 4, 0, 1985, 0, 22],
+				           [1405, 5, 0, 1985, 1, 21],
+				           [1405, 6, 0, 1985, 2, 22],
+				           [1405, 7, 0, 1985, 3, 21],
+				           [1405, 8, 0, 1985, 4, 21],
+				           [1405, 9, 0, 1985, 5, 19],
+				           [1405, 10, 0, 1985, 6, 19],
+				           [1405, 11, 0, 1985, 7, 17],
+				           [1406, 0, 0, 1985, 8, 16],
+				           [1406, 1, 0, 1985, 9, 15],
+				           [1406, 2, 0, 1985, 10, 14],
+				           [1406, 3, 0, 1985, 11, 13],
+				           [1406, 4, 0, 1986, 0, 12],
+				           [1406, 5, 0, 1986, 1, 10],
+				           [1406, 6, 0, 1986, 2, 12],
+				           [1406, 7, 0, 1986, 3, 10],
+				           [1406, 8, 0, 1986, 4, 10],
+				           [1406, 9, 0, 1986, 5, 8],
+				           [1406, 10, 0, 1986, 6, 8],
+				           [1406, 11, 0, 1986, 7, 7],
+				           [1407, 0, 0, 1986, 8, 5],
+				           [1407, 1, 0, 1986, 9, 5],
+				           [1407, 2, 0, 1986, 10, 3],
+				           [1407, 3, 0, 1986, 11, 3],
+				           [1407, 4, 0, 1987, 0, 1],
+				           [1407, 5, 0, 1987, 0, 31],
+				           [1407, 6, 0, 1987, 2, 1],
+				           [1407, 7, 0, 1987, 2, 30],
+				           [1407, 8, 0, 1987, 3, 29],
+				           [1407, 9, 0, 1987, 4, 28],
+				           [1407, 10, 0, 1987, 5, 27],
+				           [1407, 11, 0, 1987, 6, 27],
+				           [1408, 0, 0, 1987, 7, 25],
+				           [1408, 1, 0, 1987, 8, 24],
+				           [1408, 2, 0, 1987, 9, 24],
+				           [1408, 3, 0, 1987, 10, 22],
+				           [1408, 4, 0, 1987, 11, 22],
+				           [1408, 5, 0, 1988, 0, 20],
+				           [1408, 6, 0, 1988, 1, 19],
+				           [1408, 7, 0, 1988, 2, 19],
+				           [1408, 8, 0, 1988, 3, 17],
+				           [1408, 9, 0, 1988, 4, 17],
+				           [1408, 10, 0, 1988, 5, 15],
+				           [1408, 11, 0, 1988, 6, 15],
+				           [1409, 0, 0, 1988, 7, 13],
+				           [1409, 1, 0, 1988, 8, 12],
+				           [1409, 2, 0, 1988, 9, 12],
+				           [1409, 3, 0, 1988, 10, 11],
+				           [1409, 4, 0, 1988, 11, 10],
+				           [1409, 5, 0, 1989, 0, 9],
+				           [1409, 6, 0, 1989, 1, 7],
+				           [1409, 7, 0, 1989, 2, 9],
+				           [1409, 8, 0, 1989, 3, 7],
+				           [1409, 9, 0, 1989, 4, 6],
+				           [1409, 10, 0, 1989, 5, 5],
+				           [1409, 11, 0, 1989, 6, 4],
+				           [1410, 0, 0, 1989, 7, 3],
+				           [1410, 1, 0, 1989, 8, 1],
+				           [1410, 2, 0, 1989, 9, 1],
+				           [1410, 3, 0, 1989, 9, 31],
+				           [1410, 4, 0, 1989, 10, 30],
+				           [1410, 5, 0, 1989, 11, 29],
+				           [1410, 6, 0, 1990, 0, 28],
+				           [1410, 7, 0, 1990, 1, 26],
+				           [1410, 8, 0, 1990, 2, 28],
+				           [1410, 9, 0, 1990, 3, 26],
+				           [1410, 10, 0, 1990, 4, 25],
+				           [1410, 11, 0, 1990, 5, 24],
+				           [1411, 0, 0, 1990, 6, 23],
+				           [1411, 1, 0, 1990, 7, 22],
+				           [1411, 2, 0, 1990, 8, 20],
+				           [1411, 3, 0, 1990, 9, 20],
+				           [1411, 4, 0, 1990, 10, 19],
+				           [1411, 5, 0, 1990, 11, 18],
+				           [1411, 6, 0, 1991, 0, 17],
+				           [1411, 7, 0, 1991, 1, 16],
+				           [1411, 8, 0, 1991, 2, 17],
+				           [1411, 9, 0, 1991, 3, 16],
+				           [1411, 10, 0, 1991, 4, 15],
+				           [1411, 11, 0, 1991, 5, 13],
+				           [1412, 0, 0, 1991, 6, 13],
+				           [1412, 1, 0, 1991, 7, 11],
+				           [1412, 2, 0, 1991, 8, 10],
+				           [1412, 3, 0, 1991, 9, 9],
+				           [1412, 4, 0, 1991, 10, 8],
+				           [1412, 5, 0, 1991, 11, 7],
+				           [1412, 6, 0, 1992, 0, 6],
+				           [1412, 7, 0, 1992, 1, 5],
+				           [1412, 8, 0, 1992, 2, 6],
+				           [1412, 9, 0, 1992, 3, 4],
+				           [1412, 10, 0, 1992, 4, 4],
+				           [1412, 11, 0, 1992, 5, 2],
+				           [1413, 0, 0, 1992, 6, 1],
+				           [1413, 1, 0, 1992, 6, 31],
+				           [1413, 2, 0, 1992, 7, 29],
+				           [1413, 3, 0, 1992, 8, 28],
+				           [1413, 4, 0, 1992, 9, 27],
+				           [1413, 5, 0, 1992, 10, 25],
+				           [1413, 6, 0, 1992, 11, 25],
+				           [1413, 7, 0, 1993, 0, 24],
+				           [1413, 8, 0, 1993, 1, 22],
+				           [1413, 9, 0, 1993, 2, 24],
+				           [1413, 10, 0, 1993, 3, 23],
+				           [1413, 11, 0, 1993, 4, 22],
+				           [1414, 0, 0, 1993, 5, 21],
+				           [1414, 1, 0, 1993, 6, 21],
+				           [1414, 2, 0, 1993, 7, 19],
+				           [1414, 3, 0, 1993, 8, 17],
+				           [1414, 4, 0, 1993, 9, 17],
+				           [1414, 5, 0, 1993, 10, 15],
+				           [1414, 6, 0, 1993, 11, 14],
+				           [1414, 7, 0, 1994, 0, 13],
+				           [1414, 8, 0, 1994, 1, 12],
+				           [1414, 9, 0, 1994, 2, 13],
+				           [1414, 10, 0, 1994, 3, 12],
+				           [1414, 11, 0, 1994, 4, 12],
+				           [1415, 0, 0, 1994, 5, 10],
+				           [1415, 1, 0, 1994, 6, 10],
+				           [1415, 2, 0, 1994, 7, 9],
+				           [1415, 3, 0, 1994, 8, 7],
+				           [1415, 4, 0, 1994, 9, 6],
+				           [1415, 5, 0, 1994, 10, 5],
+				           [1415, 6, 0, 1994, 11, 4],
+				           [1415, 7, 0, 1995, 0, 2],
+				           [1415, 8, 0, 1995, 1, 1],
+				           [1415, 9, 0, 1995, 2, 2],
+				           [1415, 10, 0, 1995, 3, 1],
+				           [1415, 11, 0, 1995, 4, 1],
+				           [1416, 0, 0, 1995, 4, 30],
+				           [1416, 1, 0, 1995, 5, 29],
+				           [1416, 2, 0, 1995, 6, 29],
+				           [1416, 3, 0, 1995, 7, 27],
+				           [1416, 4, 0, 1995, 8, 26],
+				           [1416, 5, 0, 1995, 9, 25],
+				           [1416, 6, 0, 1995, 10, 24],
+				           [1416, 7, 0, 1995, 11, 23],
+				           [1416, 8, 0, 1996, 0, 21],
+				           [1416, 9, 0, 1996, 1, 20],
+				           [1416, 10, 0, 1996, 2, 20],
+				           [1416, 11, 0, 1996, 3, 19],
+				           [1417, 0, 0, 1996, 4, 18],
+				           [1417, 1, 0, 1996, 5, 17],
+				           [1417, 2, 0, 1996, 6, 17],
+				           [1417, 3, 0, 1996, 7, 16],
+				           [1417, 4, 0, 1996, 8, 14],
+				           [1417, 5, 0, 1996, 9, 13],
+				           [1417, 6, 0, 1996, 10, 12],
+				           [1417, 7, 0, 1996, 11, 12],
+				           [1417, 8, 0, 1997, 0, 10],
+				           [1417, 9, 0, 1997, 1, 9],
+				           [1417, 10, 0, 1997, 2, 10],
+				           [1417, 11, 0, 1997, 3, 8],
+				           [1418, 0, 0, 1997, 4, 8],
+				           [1418, 1, 0, 1997, 5, 6],
+				           [1418, 2, 0, 1997, 6, 6],
+				           [1418, 3, 0, 1997, 7, 5],
+				           [1418, 4, 0, 1997, 8, 3],
+				           [1418, 5, 0, 1997, 9, 3],
+				           [1418, 6, 0, 1997, 10, 1],
+				           [1418, 7, 0, 1997, 11, 1],
+				           [1418, 8, 0, 1997, 11, 31],
+				           [1418, 9, 0, 1998, 0, 29],
+				           [1418, 10, 0, 1998, 1, 28],
+				           [1418, 11, 0, 1998, 2, 29],
+				           [1419, 0, 0, 1998, 3, 27],
+				           [1419, 1, 0, 1998, 4, 27],
+				           [1419, 2, 0, 1998, 5, 25],
+				           [1419, 3, 0, 1998, 6, 25],
+				           [1419, 4, 0, 1998, 7, 23],
+				           [1419, 5, 0, 1998, 8, 22],
+				           [1419, 6, 0, 1998, 9, 21],
+				           [1419, 7, 0, 1998, 10, 20],
+				           [1419, 8, 0, 1998, 11, 20],
+				           [1419, 9, 0, 1999, 0, 19],
+				           [1419, 10, 0, 1999, 1, 17],
+				           [1419, 11, 0, 1999, 2, 19],
+				           [1420, 0, 0, 1999, 3, 17],
+				           [1420, 1, 0, 1999, 4, 16],
+				           [1420, 2, 0, 1999, 5, 15],
+				           [1420, 3, 0, 1999, 6, 14],
+				           [1420, 4, 0, 1999, 7, 12],
+				           [1420, 5, 0, 1999, 8, 11],
+				           [1420, 6, 0, 1999, 9, 10],
+				           [1420, 7, 0, 1999, 10, 9],
+				           [1420, 8, 0, 1999, 11, 9],
+				           [1420, 9, 0, 2000, 0, 8],
+				           [1420, 10, 0, 2000, 1, 7],
+				           [1420, 11, 0, 2000, 2, 7],
+				           [1421, 0, 0, 2000, 3, 6],
+				           [1421, 1, 0, 2000, 4, 5],
+				           [1421, 2, 0, 2000, 5, 3],
+				           [1421, 3, 0, 2000, 6, 3],
+				           [1421, 4, 0, 2000, 7, 1],
+				           [1421, 5, 0, 2000, 7, 30],
+				           [1421, 6, 0, 2000, 8, 28],
+				           [1421, 7, 0, 2000, 9, 28],
+				           [1421, 8, 0, 2000, 10, 27],
+				           [1421, 9, 0, 2000, 11, 27],
+				           [1421, 10, 0, 2001, 0, 26],
+				           [1421, 11, 0, 2001, 1, 24],
+				           [1422, 0, 0, 2001, 2, 26],
+				           [1422, 1, 0, 2001, 3, 25],
+				           [1422, 2, 0, 2001, 4, 24],
+				           [1422, 3, 0, 2001, 5, 22],
+				           [1422, 4, 0, 2001, 6, 22],
+				           [1422, 5, 0, 2001, 7, 20],
+				           [1422, 6, 0, 2001, 8, 18],
+				           [1422, 7, 0, 2001, 9, 17],
+				           [1422, 8, 0, 2001, 10, 16],
+				           [1422, 9, 0, 2001, 11, 16],
+				           [1422, 10, 0, 2002, 0, 15],
+				           [1422, 11, 0, 2002, 1, 13],
+				           [1423, 0, 0, 2002, 2, 15],
+				           [1423, 1, 0, 2002, 3, 14],
+				           [1423, 2, 0, 2002, 4, 13],
+				           [1423, 3, 0, 2002, 5, 12],
+				           [1423, 4, 0, 2002, 6, 11],
+				           [1423, 5, 0, 2002, 7, 10],
+				           [1423, 6, 0, 2002, 8, 8],
+				           [1423, 7, 0, 2002, 9, 7],
+				           [1423, 8, 0, 2002, 10, 6],
+				           [1423, 9, 0, 2002, 11, 5],
+				           [1423, 10, 0, 2003, 0, 4],
+				           [1423, 11, 0, 2003, 1, 2],
+				           [1424, 0, 0, 2003, 2, 4],
+				           [1424, 1, 0, 2003, 3, 3],
+				           [1424, 2, 0, 2003, 4, 2],
+				           [1424, 3, 0, 2003, 5, 1],
+				           [1424, 4, 0, 2003, 6, 1],
+				           [1424, 5, 0, 2003, 6, 30],
+				           [1424, 6, 0, 2003, 7, 29],
+				           [1424, 7, 0, 2003, 8, 27],
+				           [1424, 8, 0, 2003, 9, 26],
+				           [1424, 9, 0, 2003, 10, 25],
+				           [1424, 10, 0, 2003, 11, 24],
+				           [1424, 11, 0, 2004, 0, 23],
+				           [1425, 0, 0, 2004, 1, 21],
+				           [1425, 1, 0, 2004, 2, 22],
+				           [1425, 2, 0, 2004, 3, 20],
+				           [1425, 3, 0, 2004, 4, 20],
+				           [1425, 4, 0, 2004, 5, 19],
+				           [1425, 5, 0, 2004, 6, 18],
+				           [1425, 6, 0, 2004, 7, 17],
+				           [1425, 7, 0, 2004, 8, 15],
+				           [1425, 8, 0, 2004, 9, 15],
+				           [1425, 9, 0, 2004, 10, 14],
+				           [1425, 10, 0, 2004, 11, 13],
+				           [1425, 11, 0, 2005, 0, 12],
+				           [1426, 0, 0, 2005, 1, 10],
+				           [1426, 1, 0, 2005, 2, 11],
+				           [1426, 2, 0, 2005, 3, 10],
+				           [1426, 3, 0, 2005, 4, 9],
+				           [1426, 4, 0, 2005, 5, 8],
+				           [1426, 5, 0, 2005, 6, 7],
+				           [1426, 6, 0, 2005, 7, 6],
+				           [1426, 7, 0, 2005, 8, 5],
+				           [1426, 8, 0, 2005, 9, 4],
+				           [1426, 9, 0, 2005, 10, 3],
+				           [1426, 10, 0, 2005, 11, 3],
+				           [1426, 11, 0, 2006, 0, 1],
+				           [1427, 0, 0, 2006, 0, 31],
+				           [1427, 1, 0, 2006, 2, 1],
+				           [1427, 2, 0, 2006, 2, 30],
+				           [1427, 3, 0, 2006, 3, 29],
+				           [1427, 4, 0, 2006, 4, 28],
+				           [1427, 5, 0, 2006, 5, 27],
+				           [1427, 6, 0, 2006, 6, 26],
+				           [1427, 7, 0, 2006, 7, 25],
+				           [1427, 8, 0, 2006, 8, 24],
+				           [1427, 9, 0, 2006, 9, 23],
+				           [1427, 10, 0, 2006, 10, 22],
+				           [1427, 11, 0, 2006, 11, 22],
+				           [1428, 0, 0, 2007, 0, 20],
+				           [1428, 1, 0, 2007, 1, 19],
+				           [1428, 2, 0, 2007, 2, 20],
+				           [1428, 3, 0, 2007, 3, 18],
+				           [1428, 4, 0, 2007, 4, 18],
+				           [1428, 5, 0, 2007, 5, 16],
+				           [1428, 6, 0, 2007, 6, 15],
+				           [1428, 7, 0, 2007, 7, 14],
+				           [1428, 8, 0, 2007, 8, 13],
+				           [1428, 9, 0, 2007, 9, 13],
+				           [1428, 10, 0, 2007, 10, 11],
+				           [1428, 11, 0, 2007, 11, 11],
+				           [1429, 0, 0, 2008, 0, 10],
+				           [1429, 1, 0, 2008, 1, 8],
+				           [1429, 2, 0, 2008, 2, 9],
+				           [1429, 3, 0, 2008, 3, 7],
+				           [1429, 4, 0, 2008, 4, 6],
+				           [1429, 5, 0, 2008, 5, 5],
+				           [1429, 6, 0, 2008, 6, 4],
+				           [1429, 7, 0, 2008, 7, 2],
+				           [1429, 8, 0, 2008, 8, 1],
+				           [1429, 9, 0, 2008, 9, 1],
+				           [1429, 10, 0, 2008, 9, 30],
+				           [1429, 11, 0, 2008, 10, 29],
+				           [1430, 0, 0, 2008, 11, 29],
+				           [1430, 1, 0, 2009, 0, 27],
+				           [1430, 2, 0, 2009, 1, 26],
+				           [1430, 3, 0, 2009, 2, 28],
+				           [1430, 4, 0, 2009, 3, 26],
+				           [1430, 5, 0, 2009, 4, 25],
+				           [1430, 6, 0, 2009, 5, 24],
+				           [1430, 7, 0, 2009, 6, 23],
+				           [1430, 8, 0, 2009, 7, 22],
+				           [1430, 9, 0, 2009, 8, 20],
+				           [1430, 10, 0, 2009, 9, 20],
+				           [1430, 11, 0, 2009, 10, 18],
+				           [1431, 0, 0, 2009, 11, 18],
+				           [1431, 1, 0, 2010, 0, 16],
+				           [1431, 2, 0, 2010, 1, 15],
+				           [1431, 3, 0, 2010, 2, 17],
+				           [1431, 4, 0, 2010, 3, 15],
+				           [1431, 5, 0, 2010, 4, 15],
+				           [1431, 6, 0, 2010, 5, 13],
+				           [1431, 7, 0, 2010, 6, 13],
+				           [1431, 8, 0, 2010, 7, 11],
+				           [1431, 9, 0, 2010, 8, 10],
+				           [1431, 10, 0, 2010, 9, 9],
+				           [1431, 11, 0, 2010, 10, 7],
+				           [1432, 0, 0, 2010, 11, 7],
+				           [1432, 1, 0, 2011, 0, 5],
+				           [1432, 2, 0, 2011, 1, 4],
+				           [1432, 3, 0, 2011, 2, 6],
+				           [1432, 4, 0, 2011, 3, 5],
+				           [1432, 5, 0, 2011, 4, 4],
+				           [1432, 6, 0, 2011, 5, 3],
+				           [1432, 7, 0, 2011, 6, 2],
+				           [1432, 8, 0, 2011, 7, 1],
+				           [1432, 9, 0, 2011, 7, 30],
+				           [1432, 10, 0, 2011, 8, 29],
+				           [1432, 11, 0, 2011, 9, 28],
+				           [1433, 0, 0, 2011, 10, 26],
+				           [1433, 1, 0, 2011, 11, 26],
+				           [1433, 2, 0, 2012, 0, 24],
+				           [1433, 3, 0, 2012, 1, 23],
+				           [1433, 4, 0, 2012, 2, 24],
+				           [1433, 5, 0, 2012, 3, 22],
+				           [1433, 6, 0, 2012, 4, 22],
+				           [1433, 7, 0, 2012, 5, 21],
+				           [1433, 8, 0, 2012, 6, 20],
+				           [1433, 9, 0, 2012, 7, 19],
+				           [1433, 10, 0, 2012, 8, 17],
+				           [1433, 11, 0, 2012, 9, 17],
+				           [1434, 0, 0, 2012, 10, 15],
+				           [1434, 1, 0, 2012, 11, 14],
+				           [1434, 2, 0, 2013, 0, 13],
+				           [1434, 3, 0, 2013, 1, 11],
+				           [1434, 4, 0, 2013, 2, 13],
+				           [1434, 5, 0, 2013, 3, 11],
+				           [1434, 6, 0, 2013, 4, 11],
+				           [1434, 7, 0, 2013, 5, 10],
+				           [1434, 8, 0, 2013, 6, 9],
+				           [1434, 9, 0, 2013, 7, 8],
+				           [1434, 10, 0, 2013, 8, 7],
+				           [1434, 11, 0, 2013, 9, 6],
+				           [1435, 0, 0, 2013, 10, 4],
+				           [1435, 1, 0, 2013, 11, 4],
+				           [1435, 2, 0, 2014, 0, 2],
+				           [1435, 3, 0, 2014, 1, 1],
+				           [1435, 4, 0, 2014, 2, 2],
+				           [1435, 5, 0, 2014, 3, 1],
+				           [1435, 6, 0, 2014, 3, 30],
+				           [1435, 7, 0, 2014, 4, 30],
+				           [1435, 8, 0, 2014, 5, 28],
+				           [1435, 9, 0, 2014, 6, 28],
+				           [1435, 10, 0, 2014, 7, 27],
+				           [1435, 11, 0, 2014, 8, 25],
+				           [1436, 0, 0, 2014, 9, 25],
+				           [1436, 1, 0, 2014, 10, 23],
+				           [1436, 2, 0, 2014, 11, 23],
+				           [1436, 3, 0, 2015, 0, 21],
+				           [1436, 4, 0, 2015, 1, 20],
+				           [1436, 5, 0, 2015, 2, 21],
+				           [1436, 6, 0, 2015, 3, 20],
+				           [1436, 7, 0, 2015, 4, 19],
+				           [1436, 8, 0, 2015, 5, 18],
+				           [1436, 9, 0, 2015, 6, 17],
+				           [1436, 10, 0, 2015, 7, 16],
+				           [1436, 11, 0, 2015, 8, 14],
+				           [1437, 0, 0, 2015, 9, 14],
+				           [1437, 1, 0, 2015, 10, 13],
+				           [1437, 2, 0, 2015, 11, 12],
+				           [1437, 3, 0, 2016, 0, 11],
+				           [1437, 4, 0, 2016, 1, 10],
+				           [1437, 5, 0, 2016, 2, 10],
+				           [1437, 6, 0, 2016, 3, 8],
+				           [1437, 7, 0, 2016, 4, 8],
+				           [1437, 8, 0, 2016, 5, 6],
+				           [1437, 9, 0, 2016, 6, 6],
+				           [1437, 10, 0, 2016, 7, 4],
+				           [1437, 11, 0, 2016, 8, 2],
+				           [1438, 0, 0, 2016, 9, 2],
+				           [1438, 1, 0, 2016, 10, 1],
+				           [1438, 2, 0, 2016, 10, 30],
+				           [1438, 3, 0, 2016, 11, 30],
+				           [1438, 4, 0, 2017, 0, 29],
+				           [1438, 5, 0, 2017, 1, 28],
+				           [1438, 6, 0, 2017, 2, 29],
+				           [1438, 7, 0, 2017, 3, 27],
+				           [1438, 8, 0, 2017, 4, 27],
+				           [1438, 9, 0, 2017, 5, 25],
+				           [1438, 10, 0, 2017, 6, 24],
+				           [1438, 11, 0, 2017, 7, 23],
+				           [1439, 0, 0, 2017, 8, 21],
+				           [1439, 1, 0, 2017, 9, 21],
+				           [1439, 2, 0, 2017, 10, 19],
+				           [1439, 3, 0, 2017, 11, 19],
+				           [1439, 4, 0, 2018, 0, 18],
+				           [1439, 5, 0, 2018, 1, 17],
+				           [1439, 6, 0, 2018, 2, 18],
+				           [1439, 7, 0, 2018, 3, 17],
+				           [1439, 8, 0, 2018, 4, 16],
+				           [1439, 9, 0, 2018, 5, 15],
+				           [1439, 10, 0, 2018, 6, 14],
+				           [1439, 11, 0, 2018, 7, 12],
+				           [1440, 0, 0, 2018, 8, 11],
+				           [1440, 1, 0, 2018, 9, 10],
+				           [1440, 2, 0, 2018, 10, 9],
+				           [1440, 3, 0, 2018, 11, 8],
+				           [1440, 4, 0, 2019, 0, 7],
+				           [1440, 5, 0, 2019, 1, 6],
+				           [1440, 6, 0, 2019, 2, 8],
+				           [1440, 7, 0, 2019, 3, 6],
+				           [1440, 8, 0, 2019, 4, 6],
+				           [1440, 9, 0, 2019, 5, 4],
+				           [1440, 10, 0, 2019, 6, 4],
+				           [1440, 11, 0, 2019, 7, 2],
+				           [1441, 0, 0, 2019, 7, 31],
+				           [1441, 1, 0, 2019, 8, 30],
+				           [1441, 2, 0, 2019, 9, 29],
+				           [1441, 3, 0, 2019, 10, 28],
+				           [1441, 4, 0, 2019, 11, 27],
+				           [1441, 5, 0, 2020, 0, 26],
+				           [1441, 6, 0, 2020, 1, 25],
+				           [1441, 7, 0, 2020, 2, 25],
+				           [1441, 8, 0, 2020, 3, 24],
+				           [1441, 9, 0, 2020, 4, 24],
+				           [1441, 10, 0, 2020, 5, 22],
+				           [1441, 11, 0, 2020, 6, 22],
+				           [1442, 0, 0, 2020, 7, 20],
+				           [1442, 1, 0, 2020, 8, 18],
+				           [1442, 2, 0, 2020, 9, 18],
+				           [1442, 3, 0, 2020, 10, 16],
+				           [1442, 4, 0, 2020, 11, 16],
+				           [1442, 5, 0, 2021, 0, 14],
+				           [1442, 6, 0, 2021, 1, 13],
+				           [1442, 7, 0, 2021, 2, 14],
+				           [1442, 8, 0, 2021, 3, 13],
+				           [1442, 9, 0, 2021, 4, 13],
+				           [1442, 10, 0, 2021, 5, 11],
+				           [1442, 11, 0, 2021, 6, 11],
+				           [1443, 0, 0, 2021, 7, 9],
+				           [1443, 1, 0, 2021, 8, 8],
+				           [1443, 2, 0, 2021, 9, 7],
+				           [1443, 3, 0, 2021, 10, 6],
+				           [1443, 4, 0, 2021, 11, 5],
+				           [1443, 5, 0, 2022, 0, 4],
+				           [1443, 6, 0, 2022, 1, 2],
+				           [1443, 7, 0, 2022, 2, 4],
+				           [1443, 8, 0, 2022, 3, 2],
+				           [1443, 9, 0, 2022, 4, 2],
+				           [1443, 10, 0, 2022, 4, 31],
+				           [1443, 11, 0, 2022, 5, 30],
+				           [1444, 0, 0, 2022, 6, 30],
+				           [1444, 1, 0, 2022, 7, 28],
+				           [1444, 2, 0, 2022, 8, 27],
+				           [1444, 3, 0, 2022, 9, 26],
+				           [1444, 4, 0, 2022, 10, 25],
+				           [1444, 5, 0, 2022, 11, 25],
+				           [1444, 6, 0, 2023, 0, 23],
+				           [1444, 7, 0, 2023, 1, 21],
+				           [1444, 8, 0, 2023, 2, 23],
+				           [1444, 9, 0, 2023, 3, 21],
+				           [1444, 10, 0, 2023, 4, 21],
+				           [1444, 11, 0, 2023, 5, 19],
+				           [1445, 0, 0, 2023, 6, 19],
+				           [1445, 1, 0, 2023, 7, 17],
+				           [1445, 2, 0, 2023, 8, 16],
+				           [1445, 3, 0, 2023, 9, 16],
+				           [1445, 4, 0, 2023, 10, 15],
+				           [1445, 5, 0, 2023, 11, 14],
+				           [1445, 6, 0, 2024, 0, 13],
+				           [1445, 7, 0, 2024, 1, 11],
+				           [1445, 8, 0, 2024, 2, 11],
+				           [1445, 9, 0, 2024, 3, 10],
+				           [1445, 10, 0, 2024, 4, 9],
+				           [1445, 11, 0, 2024, 5, 7],
+				           [1446, 0, 0, 2024, 6, 7],
+				           [1446, 1, 0, 2024, 7, 5],
+				           [1446, 2, 0, 2024, 8, 4],
+				           [1446, 3, 0, 2024, 9, 4],
+				           [1446, 4, 0, 2024, 10, 3],
+				           [1446, 5, 0, 2024, 11, 2],
+				           [1446, 6, 0, 2025, 0, 1],
+				           [1446, 7, 0, 2025, 0, 31],
+				           [1446, 8, 0, 2025, 2, 1],
+				           [1446, 9, 0, 2025, 2, 30],
+				           [1446, 10, 0, 2025, 3, 29],
+				           [1446, 11, 0, 2025, 4, 28],
+				           [1447, 0, 0, 2025, 5, 26],
+				           [1447, 1, 0, 2025, 6, 26],
+				           [1447, 2, 0, 2025, 7, 24],
+				           [1447, 3, 0, 2025, 8, 23],
+				           [1447, 4, 0, 2025, 9, 23],
+				           [1447, 5, 0, 2025, 10, 22],
+				           [1447, 6, 0, 2025, 11, 21],
+				           [1447, 7, 0, 2026, 0, 20],
+				           [1447, 8, 0, 2026, 1, 18],
+				           [1447, 9, 0, 2026, 2, 20],
+				           [1447, 10, 0, 2026, 3, 18],
+				           [1447, 11, 0, 2026, 4, 18],
+				           [1448, 0, 0, 2026, 5, 16],
+				           [1448, 1, 0, 2026, 6, 15],
+				           [1448, 2, 0, 2026, 7, 14],
+				           [1448, 3, 0, 2026, 8, 12],
+				           [1448, 4, 0, 2026, 9, 12],
+				           [1448, 5, 0, 2026, 10, 11],
+				           [1448, 6, 0, 2026, 11, 10],
+				           [1448, 7, 0, 2027, 0, 9],
+				           [1448, 8, 0, 2027, 1, 8],
+				           [1448, 9, 0, 2027, 2, 9],
+				           [1448, 10, 0, 2027, 3, 8],
+				           [1448, 11, 0, 2027, 4, 7],
+				           [1449, 0, 0, 2027, 5, 6],
+				           [1449, 1, 0, 2027, 6, 5],
+				           [1449, 2, 0, 2027, 7, 3],
+				           [1449, 3, 0, 2027, 8, 2],
+				           [1449, 4, 0, 2027, 9, 1],
+				           [1449, 5, 0, 2027, 9, 31],
+				           [1449, 6, 0, 2027, 10, 29],
+				           [1449, 7, 0, 2027, 11, 29],
+				           [1449, 8, 0, 2028, 0, 28],
+				           [1449, 9, 0, 2028, 1, 26],
+				           [1449, 10, 0, 2028, 2, 27],
+				           [1449, 11, 0, 2028, 3, 26],
+				           [1450, 0, 0, 2028, 4, 25],
+				           [1450, 1, 0, 2028, 5, 24],
+				           [1450, 2, 0, 2028, 6, 23],
+				           [1450, 3, 0, 2028, 7, 22],
+				           [1450, 4, 0, 2028, 8, 20],
+				           [1450, 5, 0, 2028, 9, 19],
+				           [1450, 6, 0, 2028, 10, 18],
+				           [1450, 7, 0, 2028, 11, 17],
+				           [1450, 8, 0, 2029, 0, 16],
+				           [1450, 9, 0, 2029, 1, 14],
+				           [1450, 10, 0, 2029, 2, 16],
+				           [1450, 11, 0, 2029, 3, 15],
+				           [1451, 0, 0, 2029, 4, 14],
+				           [1451, 1, 0, 2029, 5, 13],
+				           [1451, 2, 0, 2029, 6, 13],
+				           [1451, 3, 0, 2029, 7, 11],
+				           [1451, 4, 0, 2029, 8, 10],
+				           [1451, 5, 0, 2029, 9, 9],
+				           [1451, 6, 0, 2029, 10, 7],
+				           [1451, 7, 0, 2029, 11, 7],
+				           [1451, 8, 0, 2030, 0, 5],
+				           [1451, 9, 0, 2030, 1, 4],
+				           [1451, 10, 0, 2030, 2, 5],
+				           [1451, 11, 0, 2030, 3, 4],
+				           [1452, 0, 0, 2030, 4, 3],
+				           [1452, 1, 0, 2030, 5, 2],
+				           [1452, 2, 0, 2030, 6, 2],
+				           [1452, 3, 0, 2030, 7, 1],
+				           [1452, 4, 0, 2030, 7, 30],
+				           [1452, 5, 0, 2030, 8, 29],
+				           [1452, 6, 0, 2030, 9, 28],
+				           [1452, 7, 0, 2030, 10, 26],
+				           [1452, 8, 0, 2030, 11, 26],
+				           [1452, 9, 0, 2031, 0, 24],
+				           [1452, 10, 0, 2031, 1, 23],
+				           [1452, 11, 0, 2031, 2, 24],
+				           [1453, 0, 0, 2031, 3, 23],
+				           [1453, 1, 0, 2031, 4, 22],
+				           [1453, 2, 0, 2031, 5, 21],
+				           [1453, 3, 0, 2031, 6, 21],
+				           [1453, 4, 0, 2031, 7, 20],
+				           [1453, 5, 0, 2031, 8, 18],
+				           [1453, 6, 0, 2031, 9, 17],
+				           [1453, 7, 0, 2031, 10, 16],
+				           [1453, 8, 0, 2031, 11, 15],
+				           [1453, 9, 0, 2032, 0, 14],
+				           [1453, 10, 0, 2032, 1, 12],
+				           [1453, 11, 0, 2032, 2, 13],
+				           [1454, 0, 0, 2032, 3, 11],
+				           [1454, 1, 0, 2032, 4, 10],
+				           [1454, 2, 0, 2032, 5, 9],
+				           [1454, 3, 0, 2032, 6, 9],
+				           [1454, 4, 0, 2032, 7, 8],
+				           [1454, 5, 0, 2032, 8, 6],
+				           [1454, 6, 0, 2032, 9, 6],
+				           [1454, 7, 0, 2032, 10, 4],
+				           [1454, 8, 0, 2032, 11, 4],
+				           [1454, 9, 0, 2033, 0, 2],
+				           [1454, 10, 0, 2033, 1, 1],
+				           [1454, 11, 0, 2033, 2, 2],
+				           [1455, 0, 0, 2033, 3, 1],
+				           [1455, 1, 0, 2033, 3, 30],
+				           [1455, 2, 0, 2033, 4, 29],
+				           [1455, 3, 0, 2033, 5, 28],
+				           [1455, 4, 0, 2033, 6, 28],
+				           [1455, 5, 0, 2033, 7, 26],
+				           [1455, 6, 0, 2033, 8, 25],
+				           [1455, 7, 0, 2033, 9, 24],
+				           [1455, 8, 0, 2033, 10, 23],
+				           [1455, 9, 0, 2033, 11, 23],
+				           [1455, 10, 0, 2034, 0, 21],
+				           [1455, 11, 0, 2034, 1, 20],
+				           [1456, 0, 0, 2034, 2, 21],
+				           [1456, 1, 0, 2034, 3, 20],
+				           [1456, 2, 0, 2034, 4, 19],
+				           [1456, 3, 0, 2034, 5, 17],
+				           [1456, 4, 0, 2034, 6, 17],
+				           [1456, 5, 0, 2034, 7, 15],
+				           [1456, 6, 0, 2034, 8, 14],
+				           [1456, 7, 0, 2034, 9, 13],
+				           [1456, 8, 0, 2034, 10, 12],
+				           [1456, 9, 0, 2034, 11, 12],
+				           [1456, 10, 0, 2035, 0, 11],
+				           [1456, 11, 0, 2035, 1, 9],
+				           [1457, 0, 0, 2035, 2, 11],
+				           [1457, 1, 0, 2035, 3, 9],
+				           [1457, 2, 0, 2035, 4, 9],
+				           [1457, 3, 0, 2035, 5, 7],
+				           [1457, 4, 0, 2035, 6, 6],
+				           [1457, 5, 0, 2035, 7, 5],
+				           [1457, 6, 0, 2035, 8, 3],
+				           [1457, 7, 0, 2035, 9, 2],
+				           [1457, 8, 0, 2035, 10, 1],
+				           [1457, 9, 0, 2035, 11, 1],
+				           [1457, 10, 0, 2035, 11, 30],
+				           [1457, 11, 0, 2036, 0, 29],
+				           [1458, 0, 0, 2036, 1, 28],
+				           [1458, 1, 0, 2036, 2, 29],
+				           [1458, 2, 0, 2036, 3, 27],
+				           [1458, 3, 0, 2036, 4, 27],
+				           [1458, 4, 0, 2036, 5, 25],
+				           [1458, 5, 0, 2036, 6, 24],
+				           [1458, 6, 0, 2036, 7, 23],
+				           [1458, 7, 0, 2036, 8, 21],
+				           [1458, 8, 0, 2036, 9, 20],
+				           [1458, 9, 0, 2036, 10, 19],
+				           [1458, 10, 0, 2036, 11, 19],
+				           [1458, 11, 0, 2037, 0, 17],
+				           [1459, 0, 0, 2037, 1, 16],
+				           [1459, 1, 0, 2037, 2, 18],
+				           [1459, 2, 0, 2037, 3, 17],
+				           [1459, 3, 0, 2037, 4, 16],
+				           [1459, 4, 0, 2037, 5, 15],
+				           [1459, 5, 0, 2037, 6, 14],
+				           [1459, 6, 0, 2037, 7, 12],
+				           [1459, 7, 0, 2037, 8, 11],
+				           [1459, 8, 0, 2037, 9, 10],
+				           [1459, 9, 0, 2037, 10, 8],
+				           [1459, 10, 0, 2037, 11, 8],
+				           [1459, 11, 0, 2038, 0, 7],
+				           [1460, 0, 0, 2038, 1, 5],
+				           [1460, 1, 0, 2038, 2, 7],
+				           [1460, 2, 0, 2038, 3, 6],
+				           [1460, 3, 0, 2038, 4, 5],
+				           [1460, 4, 0, 2038, 5, 4],
+				           [1460, 5, 0, 2038, 6, 3],
+				           [1460, 6, 0, 2038, 7, 2],
+				           [1460, 7, 0, 2038, 7, 31],
+				           [1460, 8, 0, 2038, 8, 30],
+				           [1460, 9, 0, 2038, 9, 29],
+				           [1460, 10, 0, 2038, 10, 27],
+				           [1460, 11, 0, 2038, 11, 27],
+				           [1461, 0, 0, 2039, 0, 26],
+				           [1461, 1, 0, 2039, 1, 24],
+				           [1461, 2, 0, 2039, 2, 26],
+				           [1461, 3, 0, 2039, 3, 24],
+				           [1461, 4, 0, 2039, 4, 24],
+				           [1461, 5, 0, 2039, 5, 23],
+				           [1461, 6, 0, 2039, 6, 22],
+				           [1461, 7, 0, 2039, 7, 21],
+				           [1461, 8, 0, 2039, 8, 19],
+				           [1461, 9, 0, 2039, 9, 19],
+				           [1461, 10, 0, 2039, 10, 17],
+				           [1461, 11, 0, 2039, 11, 17],
+				           [1462, 0, 0, 2040, 0, 15],
+				           [1462, 1, 0, 2040, 1, 14],
+				           [1462, 2, 0, 2040, 2, 14],
+				           [1462, 3, 0, 2040, 3, 13],
+				           [1462, 4, 0, 2040, 4, 12],
+				           [1462, 5, 0, 2040, 5, 11],
+				           [1462, 6, 0, 2040, 6, 10],
+				           [1462, 7, 0, 2040, 7, 9],
+				           [1462, 8, 0, 2040, 8, 7],
+				           [1462, 9, 0, 2040, 9, 7],
+				           [1462, 10, 0, 2040, 10, 6],
+				           [1462, 11, 0, 2040, 11, 5],
+				           [1463, 0, 0, 2041, 0, 4],
+				           [1463, 1, 0, 2041, 1, 2],
+				           [1463, 2, 0, 2041, 2, 4],
+				           [1463, 3, 0, 2041, 3, 2],
+				           [1463, 4, 0, 2041, 4, 1],
+				           [1463, 5, 0, 2041, 4, 31],
+				           [1463, 6, 0, 2041, 5, 29],
+				           [1463, 7, 0, 2041, 6, 29],
+				           [1463, 8, 0, 2041, 7, 28],
+				           [1463, 9, 0, 2041, 8, 26],
+				           [1463, 10, 0, 2041, 9, 26],
+				           [1463, 11, 0, 2041, 10, 25],
+				           [1464, 0, 0, 2041, 11, 24],
+				           [1464, 1, 0, 2042, 0, 23],
+				           [1464, 2, 0, 2042, 1, 21],
+				           [1464, 3, 0, 2042, 2, 23],
+				           [1464, 4, 0, 2042, 3, 21],
+				           [1464, 5, 0, 2042, 4, 20],
+				           [1464, 6, 0, 2042, 5, 19],
+				           [1464, 7, 0, 2042, 6, 18],
+				           [1464, 8, 0, 2042, 7, 17],
+				           [1464, 9, 0, 2042, 8, 15],
+				           [1464, 10, 0, 2042, 9, 15],
+				           [1464, 11, 0, 2042, 10, 14],
+				           [1465, 0, 0, 2042, 11, 14],
+				           [1465, 1, 0, 2043, 0, 12],
+				           [1465, 2, 0, 2043, 1, 11],
+				           [1465, 3, 0, 2043, 2, 12],
+				           [1465, 4, 0, 2043, 3, 11],
+				           [1465, 5, 0, 2043, 4, 10],
+				           [1465, 6, 0, 2043, 5, 8],
+				           [1465, 7, 0, 2043, 6, 8],
+				           [1465, 8, 0, 2043, 7, 6],
+				           [1465, 9, 0, 2043, 8, 4],
+				           [1465, 10, 0, 2043, 9, 4],
+				           [1465, 11, 0, 2043, 10, 3],
+				           [1466, 0, 0, 2043, 11, 3],
+				           [1466, 1, 0, 2044, 0, 2],
+				           [1466, 2, 0, 2044, 0, 31],
+				           [1466, 3, 0, 2044, 2, 1],
+				           [1466, 4, 0, 2044, 2, 30],
+				           [1466, 5, 0, 2044, 3, 29],
+				           [1466, 6, 0, 2044, 4, 28],
+				           [1466, 7, 0, 2044, 5, 26],
+				           [1466, 8, 0, 2044, 6, 26],
+				           [1466, 9, 0, 2044, 7, 24],
+				           [1466, 10, 0, 2044, 8, 23],
+				           [1466, 11, 0, 2044, 9, 22],
+				           [1467, 0, 0, 2044, 10, 21],
+				           [1467, 1, 0, 2044, 11, 21],
+				           [1467, 2, 0, 2045, 0, 19],
+				           [1467, 3, 0, 2045, 1, 18],
+				           [1467, 4, 0, 2045, 2, 20],
+				           [1467, 5, 0, 2045, 3, 18],
+				           [1467, 6, 0, 2045, 4, 18],
+				           [1467, 7, 0, 2045, 5, 16],
+				           [1467, 8, 0, 2045, 6, 15],
+				           [1467, 9, 0, 2045, 7, 14],
+				           [1467, 10, 0, 2045, 8, 12],
+				           [1467, 11, 0, 2045, 9, 12],
+				           [1468, 0, 0, 2045, 10, 10],
+				           [1468, 1, 0, 2045, 11, 10],
+				           [1468, 2, 0, 2046, 0, 8],
+				           [1468, 3, 0, 2046, 1, 7],
+				           [1468, 4, 0, 2046, 2, 9],
+				           [1468, 5, 0, 2046, 3, 7],
+				           [1468, 6, 0, 2046, 4, 7],
+				           [1468, 7, 0, 2046, 5, 5],
+				           [1468, 8, 0, 2046, 6, 5],
+				           [1468, 9, 0, 2046, 7, 3],
+				           [1468, 10, 0, 2046, 8, 2],
+				           [1468, 11, 0, 2046, 9, 1],
+				           [1469, 0, 0, 2046, 9, 31],
+				           [1469, 1, 0, 2046, 10, 29],
+				           [1469, 2, 0, 2046, 11, 28],
+				           [1469, 3, 0, 2047, 0, 27],
+				           [1469, 4, 0, 2047, 1, 26],
+				           [1469, 5, 0, 2047, 2, 27],
+				           [1469, 6, 0, 2047, 3, 26],
+				           [1469, 7, 0, 2047, 4, 26],
+				           [1469, 8, 0, 2047, 5, 24],
+				           [1469, 9, 0, 2047, 6, 24],
+				           [1469, 10, 0, 2047, 7, 23],
+				           [1469, 11, 0, 2047, 8, 21],
+				           [1470, 0, 0, 2047, 9, 20],
+				           [1470, 1, 0, 2047, 10, 19],
+				           [1470, 2, 0, 2047, 11, 18],
+				           [1470, 3, 0, 2048, 0, 16],
+				           [1470, 4, 0, 2048, 1, 15],
+				           [1470, 5, 0, 2048, 2, 16],
+				           [1470, 6, 0, 2048, 3, 14],
+				           [1470, 7, 0, 2048, 4, 14],
+				           [1470, 8, 0, 2048, 5, 12],
+				           [1470, 9, 0, 2048, 6, 12],
+				           [1470, 10, 0, 2048, 7, 11],
+				           [1470, 11, 0, 2048, 8, 10],
+				           [1471, 0, 0, 2048, 9, 9],
+				           [1471, 1, 0, 2048, 10, 7],
+				           [1471, 2, 0, 2048, 11, 7],
+				           [1471, 3, 0, 2049, 0, 5],
+				           [1471, 4, 0, 2049, 1, 3],
+				           [1471, 5, 0, 2049, 2, 5],
+				           [1471, 6, 0, 2049, 3, 3],
+				           [1471, 7, 0, 2049, 4, 3],
+				           [1471, 8, 0, 2049, 5, 2],
+				           [1471, 9, 0, 2049, 6, 1],
+				           [1471, 10, 0, 2049, 6, 31],
+				           [1471, 11, 0, 2049, 7, 30],
+				           [1472, 0, 0, 2049, 8, 28],
+				           [1472, 1, 0, 2049, 9, 28],
+				           [1472, 2, 0, 2049, 10, 26],
+				           [1472, 3, 0, 2049, 11, 26],
+				           [1472, 4, 0, 2050, 0, 24],
+				           [1472, 5, 0, 2050, 1, 23],
+				           [1472, 6, 0, 2050, 2, 24],
+				           [1472, 7, 0, 2050, 3, 22],
+				           [1472, 8, 0, 2050, 4, 22],
+				           [1472, 9, 0, 2050, 5, 20],
+				           [1472, 10, 0, 2050, 6, 20],
+				           [1472, 11, 0, 2050, 7, 19],
+				           [1473, 0, 0, 2050, 8, 17],
+				           [1473, 1, 0, 2050, 9, 17],
+				           [1473, 2, 0, 2050, 10, 15],
+				           [1473, 3, 0, 2050, 11, 15],
+				           [1473, 4, 0, 2051, 0, 14],
+				           [1473, 5, 0, 2051, 1, 12],
+				           [1473, 6, 0, 2051, 2, 14],
+				           [1473, 7, 0, 2051, 3, 12],
+				           [1473, 8, 0, 2051, 4, 11],
+				           [1473, 9, 0, 2051, 5, 10],
+				           [1473, 10, 0, 2051, 6, 9],
+				           [1473, 11, 0, 2051, 7, 8],
+				           [1474, 0, 0, 2051, 8, 6],
+				           [1474, 1, 0, 2051, 9, 6],
+				           [1474, 2, 0, 2051, 10, 5],
+				           [1474, 3, 0, 2051, 11, 4],
+				           [1474, 4, 0, 2052, 0, 3],
+				           [1474, 5, 0, 2052, 1, 2],
+				           [1474, 6, 0, 2052, 2, 2],
+				           [1474, 7, 0, 2052, 3, 1],
+				           [1474, 8, 0, 2052, 3, 30],
+				           [1474, 9, 0, 2052, 4, 29],
+				           [1474, 10, 0, 2052, 5, 28],
+				           [1474, 11, 0, 2052, 6, 27],
+				           [1475, 0, 0, 2052, 7, 26],
+				           [1475, 1, 0, 2052, 8, 24],
+				           [1475, 2, 0, 2052, 9, 24],
+				           [1475, 3, 0, 2052, 10, 22],
+				           [1475, 4, 0, 2052, 11, 22],
+				           [1475, 5, 0, 2053, 0, 21],
+				           [1475, 6, 0, 2053, 1, 20],
+				           [1475, 7, 0, 2053, 2, 21],
+				           [1475, 8, 0, 2053, 3, 20],
+				           [1475, 9, 0, 2053, 4, 19],
+				           [1475, 10, 0, 2053, 5, 17],
+				           [1475, 11, 0, 2053, 6, 17],
+				           [1476, 0, 0, 2053, 7, 15],
+				           [1476, 1, 0, 2053, 8, 13],
+				           [1476, 2, 0, 2053, 9, 13],
+				           [1476, 3, 0, 2053, 10, 11],
+				           [1476, 4, 0, 2053, 11, 11],
+				           [1476, 5, 0, 2054, 0, 10],
+				           [1476, 6, 0, 2054, 1, 9],
+				           [1476, 7, 0, 2054, 2, 10],
+				           [1476, 8, 0, 2054, 3, 9],
+				           [1476, 9, 0, 2054, 4, 9],
+				           [1476, 10, 0, 2054, 5, 7],
+				           [1476, 11, 0, 2054, 6, 6],
+				           [1477, 0, 0, 2054, 7, 5],
+				           [1477, 1, 0, 2054, 8, 3],
+				           [1477, 2, 0, 2054, 9, 2],
+				           [1477, 3, 0, 2054, 10, 1],
+				           [1477, 4, 0, 2054, 10, 30],
+				           [1477, 5, 0, 2054, 11, 30],
+				           [1477, 6, 0, 2055, 0, 29],
+				           [1477, 7, 0, 2055, 1, 27],
+				           [1477, 8, 0, 2055, 2, 29],
+				           [1477, 9, 0, 2055, 3, 28],
+				           [1477, 10, 0, 2055, 4, 28],
+				           [1477, 11, 0, 2055, 5, 26],
+				           [1478, 0, 0, 2055, 6, 25],
+				           [1478, 1, 0, 2055, 7, 24],
+				           [1478, 2, 0, 2055, 8, 22],
+				           [1478, 3, 0, 2055, 9, 21],
+				           [1478, 4, 0, 2055, 10, 20],
+				           [1478, 5, 0, 2055, 11, 19],
+				           [1478, 6, 0, 2056, 0, 18],
+				           [1478, 7, 0, 2056, 1, 17],
+				           [1478, 8, 0, 2056, 2, 17],
+				           [1478, 9, 0, 2056, 3, 16],
+				           [1478, 10, 0, 2056, 4, 16],
+				           [1478, 11, 0, 2056, 5, 14],
+				           [1479, 0, 0, 2056, 6, 14],
+				           [1479, 1, 0, 2056, 7, 12],
+				           [1479, 2, 0, 2056, 8, 11],
+				           [1479, 3, 0, 2056, 9, 10],
+				           [1479, 4, 0, 2056, 10, 8],
+				           [1479, 5, 0, 2056, 11, 8],
+				           [1479, 6, 0, 2057, 0, 6],
+				           [1479, 7, 0, 2057, 1, 5],
+				           [1479, 8, 0, 2057, 2, 6],
+				           [1479, 9, 0, 2057, 3, 5],
+				           [1479, 10, 0, 2057, 4, 5],
+				           [1479, 11, 0, 2057, 5, 3],
+				           [1480, 0, 1, 2057, 6, 3]
+		        ];
+		        var iDate;
+		        var iDate2;
+		        var diffDay, diffMonth, diffYear;
+		        diffDay = 0;
+		        diffMonth = 0;
+		        diffYear = 0;
+		        dojo.forEach(dates, function (d, i) {
+		            if (d[2] == 0) {
+		                d[2] = 1;
+		            }
+
+		            iDate = new dojox.date.umalqura.Date(d[0], d[1], d[2]);
+		            t.is(iDate.getFullYear(), d[0]);
+		            t.is(iDate.getDate(), d[2]);
+		            iDate2 = new dojox.date.umalqura.Date(0, 0, 0);
+		            iDate2.setFullYear(d[0]);
+		            iDate2.setMonth(d[1]);
+		            iDate2.setDate(d[2]);
+		            diffDay = dojox.date.umalqura.difference(iDate, iDate2, "year");
+		            diffMonth = dojox.date.umalqura.difference(iDate, iDate2, "month");
+		            diffYear = dojox.date.umalqura.difference(iDate, iDate2, "day");
+		        });
+
+
+		        //Special Case #1
+		        {
+		            var iDate, iDate2, year, month, day;
+		            year = 1202;
+		            month = 1;
+		            day = 29;
+		            weekday = 1;
+		            iDate = new dojox.date.umalqura.Date(year, month, day);
+		            iDate.setFullYear(year);
+		            iDate.setMonth(month);
+		            iDate.setDate(day);
+
+		            t.is(year, iDate.getFullYear());
+		            t.is(month, iDate.getMonth());
+		            t.is(day, iDate.getDate());
+		        }
+		        //Special Case #2
+		        {
+		            var iDate, iDate2, year, month, day;
+		            year = 1202;
+		            month = 1;
+		            day = 29;
+		            weekday = 1;
+		            iDate = new dojox.date.umalqura.Date(year, month, day);
+		            iDate.setFullYear(year);
+		            iDate.setMonth(month);
+		            iDate.setDate(day);
+
+		            t.is(year, iDate.getFullYear());
+		            t.is(month, iDate.getMonth());
+		            t.is(day, iDate.getDate());
+		        }
+		        //Special Case #3
+		        {
+		            var iDate, iDate2, year, month, day;
+		            year = 1202;
+		            month = 1;
+		            day = 29;
+		            weekday = 1;
+		            iDate = new dojox.date.umalqura.Date(year, month, day);
+		            iDate.setFullYear(year);
+		            iDate.setMonth(month);
+		            iDate.setDate(day);
+
+		            t.is(year, iDate.getFullYear());
+		            t.is(month, iDate.getMonth());
+		            t.is(day, iDate.getDate());
+		        }
+		        //Special Case #4
+		        {
+		            var iDate, iDate2, year, month, day;
+		            year = 1202;
+		            month = 1;
+		            day = 29;
+		            weekday = 1;
+		            iDate = new dojox.date.umalqura.Date(year, month, day);
+		            iDate.setFullYear(year);
+		            iDate.setMonth(month);
+		            iDate.setDate(day);
+
+		            t.is(year, iDate.getFullYear());
+		            t.is(month, iDate.getMonth());
+		            t.is(day, iDate.getDate());
+		        }
+		    }
+		},
+
+		{
+		    name: "consistency_of_add_and_difference",
+		    runTest: function (t) {
+		        var dateIslamicAdd;
+		        var dateDiff;
+		        var dateIslamicAdd;
+		        var dateIslamic;
+		        var dateIslamicAdd2;
+		        var inputDates = [];
+		        var tmpDate1;
+		        tmpDate1 = new dojox.date.umalqura.Date(1420, 11, 30);
+
+		        var tmpDate2 = new dojox.date.umalqura.Date(1421, 0, 1);
+		        var tmpDateDiff = dojox.date.umalqura.difference(tmpDate1, tmpDate2, "day");
+
+		        dateIslamic = new dojox.date.umalqura.Date(1480, 11, 30);
+		        dateIslamic = tmpDate1;
+		        dateIslamicAdd = dojox.date.umalqura.add(dateIslamic, "day", 0);
+		        dateDiff = dojox.date.umalqura.difference(dateIslamicAdd, dateIslamic, "day");
+		        var dateDiff2 = dojox.date.umalqura.difference(dateIslamic, dateIslamic, "day");
+		        var amouts = [-1, 0, 1, 2, 5, 6, 7, 8, 12, 18, 20, 24, 50, -3, -4, -5, -6, -7, -8, -9, -10,
+				              -50, 200, -200];
+		        var units = [
+				           "year",
+				           "month",
+				           "day",
+    			           "weekday",
+				           "hour",
+				           "minute",
+				           "second",
+				           "millisecond"
+		        ];
+		        dojo.forEach(inputDates, function (inDate, i) {
+		            dojo.forEach(amouts, function (amount, j) {
+		                dojo.forEach(units, function (unit, k) {
+		                    dateIslamic = new dojox.date.umalqura.Date(inDate[0], inDate[1], inDate[2]);
+		                    dateIslamicAdd = dojox.date.umalqura.add(dateIslamic, unit, amount);
+		                    dateDiff = dojox.date.umalqura.difference(dateIslamicAdd, dateIslamic, unit);
+		                    t.is(dateDiff, amount);
+		                });
+
+		                dateIslamic = new dojox.date.umalqura.Date(inDate[0], inDate[1], inDate[2]);
+
+		                dateIslamicAdd = dojox.date.umalqura.add(dateIslamic, "month", amount);
+		                dateDiff = dojox.date.umalqura.difference(dateIslamicAdd, dateIslamic, "month");
+		                t.is(dateDiff, amount);
+
+		                dateIslamicAdd = dojox.date.umalqura.add(dateIslamic, "year", amount);
+		                dateDiff = dojox.date.umalqura.difference(dateIslamicAdd, dateIslamic, "year");
+		                t.is(dateDiff, amount);
+
+		                dateIslamicAdd = dojox.date.umalqura.add(dateIslamic, "day", amount);
+		                dateDiff = dojox.date.umalqura.difference(dateIslamicAdd, dateIslamic, "day");
+		                t.is(dateDiff, amount);
+
+		                dateIslamicAdd = dojox.date.umalqura.add(dateIslamic, "weekday", amount);
+		                dateDiff = dojox.date.umalqura.difference(dateIslamicAdd, dateIslamic, "weekday");
+		                t.is(dateDiff, amount);
+		            });
+		        });
+
+		        var tmpDate1;
+		        var x = 9;
+		        var month = 4;
+		        var year = 1480 + x;
+		        var day1 = 3;
+		        var day2 = 4;
+		        var tmpDate1 = new dojox.date.umalqura.Date(year, month, 3);
+		        var tmpDate2 = new dojox.date.umalqura.Date(year, month, 4);
+
+		        var tmpDateDiff = dojox.date.umalqura.difference(tmpDate1, tmpDate2, "day");
+		        t.is(tmpDate2.getFullYear(), year);
+		        t.is(tmpDate2.getMonth(), month);
+		    }
+
+		},
+		{
+		    name: "set_get_date_after_1480",
+		    runTest: function (t) {
+		        var tmpDate1;
+		        var x = 9;
+		        var month = 4;
+		        var year = 1480 + x;
+		        var day1 = 3;
+		        var day2 = 4;
+		        var tmpDate2 = new dojox.date.umalqura.Date(year, month, day2);
+
+		        t.is(tmpDate2.getFullYear(), year);
+		        t.is(tmpDate2.getMonth(), month);
+		        t.is(tmpDate2.getDate(), day2);
+		    }
+		},
+
+		{
+		    name: "get_date",
+		    runTest: function (t) {
+		        dates = [
+                        [1350, 2, 16],
+                        [1351, 11, 18],
+                        [1352, 4, 12],
+                        [1353, 3, 15],
+                        [1354, 9, 14],
+                        [1355, 9, 17],
+                        [1356, 11, 18],
+                        [1357, 11, 16],
+                        [1358, 1, 10],
+                        [1359, 0, 16],
+                        [1360, 7, 15],
+                        [1361, 10, 14],
+                        [1362, 10, 21],
+                        [1363, 4, 19],
+                        [1364, 4, 14],
+                        [1365, 3, 20],
+                        [1366, 11, 16],
+                        [1367, 0, 20],
+                        [1368, 3, 10],
+                        [1369, 9, 21],
+                        [1370, 6, 21],
+                        [1371, 4, 11],
+                        [1372, 0, 19],
+                        [1373, 8, 14],
+                        [1374, 4, 18],
+                        [1375, 4, 13],
+                        [1376, 3, 13],
+                        [1377, 11, 16],
+                        [1378, 4, 15],
+                        [1379, 6, 11],
+                        [1380, 11, 11],
+                        [1381, 3, 19],
+                        [1382, 6, 13],
+                        [1383, 6, 17],
+                        [1384, 6, 19],
+                        [1385, 10, 18],
+                        [1386, 1, 14],
+                        [1387, 5, 16],
+                        [1388, 11, 12],
+                        [1389, 9, 13],
+                        [1390, 3, 16],
+                        [1391, 10, 14],
+                        [1392, 2, 10],
+                        [1393, 8, 14],
+                        [1394, 0, 13],
+                        [1395, 1, 21],
+                        [1396, 5, 10],
+                        [1397, 7, 14],
+                        [1398, 5, 17],
+                        [1399, 7, 13],
+                        [1400, 5, 13],
+                        [1401, 6, 11],
+                        [1402, 2, 11],
+                        [1403, 4, 10],
+                        [1404, 8, 13],
+                        [1405, 11, 17],
+                        [1406, 11, 21],
+                        [1407, 0, 17],
+                        [1408, 7, 19],
+                        [1409, 6, 13],
+                        [1410, 0, 13],
+                        [1411, 4, 18],
+                        [1412, 10, 19],
+                        [1413, 2, 18],
+                        [1414, 3, 19],
+                        [1415, 8, 14],
+                        [1416, 11, 16],
+                        [1417, 2, 16],
+                        [1418, 10, 20],
+                        [1419, 7, 15],
+                        [1420, 4, 16],
+                        [1421, 7, 20],
+                        [1422, 3, 13],
+                        [1423, 6, 15],
+                        [1424, 10, 17],
+                        [1425, 7, 13],
+                        [1426, 9, 10],
+                        [1427, 9, 19],
+                        [1428, 11, 18],
+                        [1429, 10, 18],
+                        [1430, 0, 21],
+                        [1431, 4, 10],
+                        [1432, 1, 17],
+                        [1433, 10, 18],
+                        [1434, 11, 19],
+                        [1435, 7, 15],
+                        [1436, 2, 15],
+                        [1437, 5, 16],
+                        [1438, 4, 21],
+                        [1439, 3, 17],
+                        [1440, 1, 16],
+                        [1441, 5, 20],
+                        [1442, 5, 21],
+                        [1443, 11, 11],
+                        [1444, 2, 10],
+                        [1445, 2, 12],
+                        [1446, 2, 14],
+                        [1447, 1, 10],
+                        [1448, 0, 15],
+                        [1449, 4, 13],
+                        [1450, 10, 11],
+                        [1451, 2, 16],
+                        [1452, 10, 20],
+                        [1453, 7, 11],
+                        [1454, 7, 11],
+                        [1455, 1, 15],
+                        [1456, 3, 13],
+                        [1457, 1, 13],
+                        [1458, 2, 13],
+                        [1459, 7, 12],
+                        [1460, 4, 10],
+                        [1461, 4, 21],
+                        [1462, 7, 18],
+                        [1463, 7, 16],
+                        [1464, 9, 10],
+                        [1465, 6, 21],
+                        [1466, 1, 21],
+                        [1467, 0, 16],
+                        [1468, 9, 17],
+                        [1469, 7, 16],
+                        [1470, 10, 19],
+                        [1471, 10, 21],
+                        [1472, 8, 16],
+                        [1473, 10, 16],
+                        [1474, 3, 12],
+                        [1475, 6, 21],
+                        [1476, 2, 10],
+                        [1477, 0, 12],
+                        [1478, 0, 14],
+                        [1479, 7, 20],
+                        [1480, 0, 1],
+                        [1480, 11, 29],
+                        [1480, 11, 30],
+                        [1481, 0, 1],
+                        [1480, 0, 2],
+                        [1481, 0, 11],
+                        [1482, 7, 18],
+                        [1483, 7, 21],
+                        [1484, 1, 10],
+                        [1485, 3, 15],
+                        [1486, 10, 16],
+                        [1487, 5, 10],
+                        [1488, 4, 21],
+                        [1489, 5, 19],
+                        [1490, 1, 21],
+                        [1491, 0, 19],
+                        [1492, 1, 18],
+                        [1493, 2, 13],
+                        [1494, 4, 17],
+                        [1495, 3, 19],
+                        [1496, 9, 10],
+                        [1497, 3, 14],
+                        [1498, 1, 13],
+                        [1499, 3, 13]
+		        ];
+		        var currentDate;
+		        dojo.forEach(dates, function (cDate, i) {
+		            currentDate = new dojox.date.umalqura.Date(cDate[0], cDate[1], cDate[2]);
+		            t.is(currentDate.getFullYear(), cDate[0]);
+		            t.is(currentDate.getMonth(), cDate[1]);
+		            t.is(currentDate.getDate(), cDate[2]);
+		        });
+		    }
+		},
+
+		{
+		    name: "getMonth_setMonth",
+		    runTest: function (t) {
+		        var dateIslamic = new dojox.date.umalqura.Date(1420, 1, 1);
+		        for (var year = 1420; year < 1430; year++) {
+		            dateIslamic.setFullYear(year);
+		            t.is(year, dateIslamic.getFullYear());
+		            dateIslamic.setMonth(11);
+		            t.is(11, dateIslamic.getMonth());
+		            dateIslamic.setMonth(6);
+		            t.is(6, dateIslamic.getMonth());
+
+		        }
+		    }
+		},
+		{
+		    name: "parse_and_format",
+		    runTest: function (t) {
+
+		        //test Islamic and English locale
+		        var dates = [
+							[1430, 5, 1],
+							[1428, 1, 28],
+							[1431, 5, 16],
+							[1431, 11, 2],
+							[1433, 0, 2]
+		        ];
+
+		        var dateIslamic, dateIslamic1;
+		        dojo.forEach(dates, function (date, i) {
+		            dateIslamic = new dojox.date.umalqura.Date(date[0], date[1], date[2]);
+
+		            var options = [{ formatLength: 'full', locale: 'ar' }, { formatLength: 'long', locale: 'ar' }, { formatLength: 'medium', locale: 'ar' }, { formatLength: 'short', locale: 'ar' },
+						{ formatLength: 'full', locale: 'en' }, { formatLength: 'long', locale: 'en' }, { formatLength: 'medium', locale: 'en' }, { formatLength: 'short', locale: 'en' }];
+		            dojo.forEach(options, function (opt, i) {
+		                str = dojox.date.umalqura.locale.format(dateIslamic, opt);
+		                var option = "{" + opt + ", locale:'ar'}";
+		                dateIslamic1 = dojox.date.umalqura.locale.parse(str, opt);
+		                t.is(0, dojo.date.compare(dateIslamic.toGregorian(), dateIslamic1.toGregorian(), 'date'));
+		            });
+
+		            var pattern = ['d M yy', 'dd/MM/yy h:m:s', 'dd#MM#yy HH$mm$ss', 'dd MMMM yyyy'];
+		            dojo.forEach(pattern, function (pat, i) {
+		                options = { datePattern: pat, selector: 'date', locale: 'ar' };
+		                str = dojox.date.umalqura.locale.format(dateIslamic, options);
+		                dateIslamic1 = dojox.date.umalqura.locale.parse(str, options);
+		                t.is(0, dojo.date.compare(dateIslamic.toGregorian(), dateIslamic1.toGregorian(), 'date'));
+		            });
+		        });
+
+		        dateIslamic = new dojox.date.umalqura.Date(1431, 6, 3, 15, 3, 59);
+		        pattern = 'HH$mm$ss';
+		        options = { timePattern: pattern, selector: 'time' };
+		        str = dojox.date.umalqura.locale.format(dateIslamic, options);
+		        dateIslamic1 = dojox.date.umalqura.locale.parse(str, options);
+		        var gregDate = dojo.date.locale.parse(str, options);
+		        t.is(0, dojo.date.compare(gregDate, dateIslamic1.toGregorian(), 'time'));
+
+		        pattern = "h:m:s";
+		        options = { timePattern: pattern, selector: 'time' };
+		        str = dojox.date.umalqura.locale.format(dateIslamic, options);
+		        t.is(str, "3:3:59");
+		    }
+		},
+	]
+);
diff --git a/dojox/date/timezone.js b/dojox/date/timezone.js
index 4cdd7dc..77bb7fe 100644
--- a/dojox/date/timezone.js
+++ b/dojox/date/timezone.js
@@ -30,11 +30,6 @@ define(["dojo", "dojo/date", "dojo/date/locale", "dojo/_base/array", "dojo/_base
 		_loadedRanges = {},
 		_rules = {};
 	
-	// timezoneFileBasePath: String
-	//		A different location to pull zone files from
-	var timezoneFileBasePath = cfg.timezoneFileBasePath ||
-								dojo.moduleUrl("dojox.date", "zoneinfo");
-	
 	// loadingScheme: String
 	//		One of "preloadAll", "lazyLoad" (Defaults "lazyLoad")
 	var loadingScheme = cfg.timezoneLoadingScheme || "preloadAll";
@@ -101,7 +96,6 @@ define(["dojo", "dojo/date", "dojo/date/locale", "dojo/_base/array", "dojo/_base
 	function loadZoneData(/* Object */ data){
 		// summary:
 		//		Loads the given data object into the zone database
-		//
 		// data: Object
 		//		The data to load - contains "zones" and "rules" parameters
 		data = data || {};
@@ -121,7 +115,7 @@ define(["dojo", "dojo/date", "dojo/date/locale", "dojo/_base/array", "dojo/_base
 		//		Using dojo.xhrGet?
 		_loadedZones[fileName] = true;
 		dojo.xhrGet({
-			url: timezoneFileBasePath + "/" + fileName,
+			url: require.toUrl((cfg.timezoneFileBasePath || "dojox/date/zoneinfo") + "/" + fileName),
 			sync: true, // Needs to be synchronous so we can return values
 			handleAs: "olson-zoneinfo",
 			load: loadZoneData,
@@ -600,44 +594,44 @@ define(["dojo", "dojo/date", "dojo/date/locale", "dojo/_base/array", "dojo/_base
 	}
 	
 /*=====
+
+// TODO: none of this is AMD friendly.   It's setting global variables in dojox,and not returning anything from the module.
+// Plus, the override of dojo/date/locale's format() and _getZone() below.   This needs to be refactored.
+
 dojox.date.timezone = function(){
 	// summary:
-	//	mix-in to dojo.date to provide timezones based on
-	//	the Olson timezone data
-	//
+	//		mix-in to dojo.date to provide timezones based on
+	//		the Olson timezone data
 	// description:
-	//	mix-in to dojo.date to provide timezones based on
-	//	the Olson timezone data.
-	//	If you pass "timezone" as a parameter to your format options,
-	//	then you get the date formatted (and offset) for that timezone
+	//		mix-in to dojo.date to provide timezones based on
+	//		the Olson timezone data.
+	//		If you pass "timezone" as a parameter to your format options,
+	//		then you get the date formatted (and offset) for that timezone
 
 //TODOC
 };
 
 dojox.date.timezone.getTzInfo = function(dt, tz){
 	// summary:
-	//	Returns the timezone information for the given date and
-	//	timezone string
-	//
+	//		Returns the timezone information for the given date and
+	//		timezone string
 	// dt: Date
-	//	The Date - a "proxyDate"
-	//
+	//		The Date - a "proxyDate"
 	// tz: String
-	//	String representation of the timezone you want to get info
-	//	for date
+	//		String representation of the timezone you want to get info
+	//		for date
 };
 
 dojox.date.timezone.loadZoneData = function(data){
 	// summary:
 	//		Loads the given data object into the zone database
-	//
 	// data: Object
 	//		The data to load - contains "zones" and "rules" parameters
 };
 
 dojox.date.timezone.getAllZones = function(){
 	// summary:
-	//	Returns an array of zones that have been loaded
+	//		Returns an array of zones that have been loaded
 };
 =====*/
 	dojo.setObject("dojox.date.timezone", {
@@ -716,4 +710,11 @@ dojox.date.timezone.getAllZones = function(){
 		}
 		return oGetZone.call(this, dateObject, getName, options);
 	};
+
+	/*=====
+	// Hide these enhancements from the doc parser because they obscure the original definition of _getZone() and
+	// format.   TODO: change above overrides to around() advice so that original definitions aren't changed.
+	 _ddl.format = oLocaleFmt;
+	 _ddl._getZone = oGetZone;
+	=====*/
 });
diff --git a/dojox/date/umalqura.js b/dojox/date/umalqura.js
new file mode 100644
index 0000000..d28d463
--- /dev/null
+++ b/dojox/date/umalqura.js
@@ -0,0 +1,253 @@
+define(["..", "dojo/_base/lang", "dojo/date", "./umalqura/Date"], function(dojox, lang, dd, IDate){
+
+var dumalqura = lang.getObject("date.umalqura", true, dojox);
+
+// Utility methods to do arithmetic calculations with umalqura.Dates
+
+	// added for compat to date
+dumalqura.getDaysInMonth = function(/*dojox/date/umalqura/Date*/month){
+	return month.getDaysInIslamicMonth(month.getMonth(), month.getFullYear());
+};
+
+//TODO: define umalqura.isLeapYear?  Or should it be invalid, since it has different meaning?
+
+dumalqura.compare = function(/*dojox/date/umalqura/Date*/date1, /*dojox/date/umalqura/Date*/date2, /*String?*/portion){
+	// summary:
+	//		Compare two umalqura date objects by date, time, or both.
+	// description:
+	//		Returns 0 if equal, positive if a > b, else negative.
+	// date1: dojox/date/umalqura/Date
+	// date2: dojox/date/umalqura/Date
+	//		If not specified, the current umalqura.Date is used.
+	// portion:
+	//		A string indicating the "date" or "time" portion of a Date object.
+	//		Compares both "date" and "time" by default.  One of the following:
+	//		"date", "time", "datetime"
+
+	if(date1 instanceof IDate){
+		date1 = date1.toGregorian();
+	}
+	if(date2 instanceof IDate){
+		date2 = date2.toGregorian();
+	}
+	
+	return dd.compare.apply(null, arguments);
+};
+
+dumalqura.add = function(/*dojox/date/umalqura/Date*/date, /*String*/interval, /*int*/amount){
+	// summary:
+	//		Add to a Date in intervals of different size, from milliseconds to years
+	// date: dojox/date/umalqura/Date
+	//		Date object to start with
+	// interval:
+	//		A string representing the interval.  One of the following:
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond", "week", "weekday"
+	// amount:
+	//		How much to add to the date.
+
+	//	based on and similar to dojo.date.add
+
+	var newIslamDate = new IDate(date);
+
+	switch(interval){
+		case "day":
+			newIslamDate.setDate(date.getDate() + amount);
+			break;
+		case "weekday":
+			var day = date.getDay();
+			if(((day + amount) < 5) && ((day + amount) > 0)){
+				 newIslamDate.setDate(date.getDate() + amount);
+			}else{
+				var adddays = 0, /*weekend */
+					remdays = 0;
+				if(day == 5){//friday
+					day = 4;
+					remdays = (amount > 0) ?  -1 : 1;
+				}else if(day == 6){ //shabat
+					day = 4;
+					remdays = (amount > 0) ? -2 : 2;
+				}
+				var add = (amount > 0) ? (5 - day - 1) : -day
+				var amountdif = amount - add;
+				var div = parseInt(amountdif / 5);
+				if(amountdif % 5 != 0){
+					adddays = (amount > 0)  ? 2 : -2;
+				}
+				adddays = adddays + div * 7 + amountdif % 5 + add;
+				newIslamDate.setDate(date.getDate() + adddays +  remdays);
+			}
+			break;
+		case "year":
+			newIslamDate.setFullYear(date.getFullYear() + amount);
+			break;
+		case "week":
+			amount *= 7;
+			newIslamDate.setDate(date.getDate() + amount);
+			break;
+		case "month":
+			var month = date.getMonth();
+			newIslamDate.setMonth(month + amount);
+			break;
+		case "hour":
+			newIslamDate.setHours(date.getHours() + amount);
+			break;
+		case "minute":
+			newIslamDate._addMinutes(amount);
+			break;
+		case "second":
+			newIslamDate._addSeconds(amount);
+			break;
+		case "millisecond":
+			newIslamDate._addMilliseconds(amount);
+			break;
+	}
+
+	return newIslamDate; // dojox.date.umalqura.Date
+};
+
+dumalqura.difference = function(/*dojox/date/umalqura/Date*/date1, /*dojox/date/umalqura/Date?*/date2, /*String?*/interval){
+	// summary:
+	//		date2 - date1
+	// date1: dojox/date/umalqura/Date
+	// date2: dojox/date/umalqura/Date
+	//		If not specified, the current dojox.date.umalqura.Date is used.
+	// interval:
+	//		A string representing the interval.  One of the following:
+	//		"year", "month", "day", "hour", "minute", "second",
+	//		"millisecond",  "week", "weekday"
+	//
+	//		Defaults to "day".
+
+	//	based on and similar to dojo.date.difference
+
+	date2 = date2 || new IDate();
+	interval = interval || "day";
+	var yearDiff = date2.getFullYear() - date1.getFullYear();
+	var delta = 1; // Integer return value
+	switch(interval){
+		case "weekday":
+			var days = Math.round(dumalqura.difference(date1, date2, "day"));
+			var weeks = parseInt(dumalqura.difference(date1, date2, "week"));
+			var mod = days % 7;
+
+			// Even number of weeks
+			if(mod == 0){
+				days = weeks*5;
+			}else{
+				// Weeks plus spare change (< 7 days)
+				var adj = 0;
+				var aDay = date1.getDay();
+				var bDay = date2.getDay();
+	
+				weeks = parseInt(days/7);
+				mod = days % 7;
+				// Mark the date advanced by the number of
+				// round weeks (may be zero)
+				var dtMark = new IDate(date1);
+				dtMark.setDate(dtMark.getDate()+(weeks*7));
+				var dayMark = dtMark.getDay();
+	
+				// Spare change days -- 6 or less
+				if(days > 0){
+					switch(true){
+						// Range starts on Fri
+						case aDay == 5:
+							adj = -1;
+							break;
+						// Range starts on Sat
+						case aDay == 6:
+							adj = 0;
+							break;
+						// Range ends on Fri
+						case bDay == 5:
+							adj = -1;
+							break;
+						// Range ends on Sat
+						case bDay == 6:
+							adj = -2;
+							break;
+						// Range contains weekend
+						case (dayMark + mod) > 5:
+							adj = -2;
+					}
+				}else if(days < 0){
+					switch(true){
+						// Range starts on Fri
+						case aDay == 5:
+							adj = 0;
+							break;
+						// Range starts on Sat
+						case aDay == 6:
+							adj = 1;
+							break;
+						// Range ends on Fri
+						case bDay == 5:
+							adj = 2;
+							break;
+						// Range ends on Sat
+						case bDay == 6:
+							adj = 1;
+							break;
+						// Range contains weekend
+						case (dayMark + mod) < 0:
+							adj = 2;
+					}
+				}
+				days += adj;
+				days -= (weeks*2);
+			}
+			delta = days;
+			break;
+		case "year":
+			delta = yearDiff;
+			break;
+		case "month":
+			var startdate =  (date2.toGregorian() > date1.toGregorian()) ? date2 : date1; // more
+			var enddate = (date2.toGregorian() > date1.toGregorian()) ? date1 : date2;
+			
+			var month1 = startdate.getMonth();
+			var month2 = enddate.getMonth();
+			
+			if (yearDiff == 0){
+				delta = startdate.getMonth() - enddate.getMonth() ;
+			}else{
+				delta = 12-month2;
+				delta +=  month1;
+				var i = enddate.getFullYear()+1;
+				var e = startdate.getFullYear();
+				for (i;   i < e;  i++){
+					delta += 12;
+				}
+			}
+			if (date2.toGregorian() < date1.toGregorian()){
+				delta = -delta;
+			}
+			break;
+		case "week":
+			// Truncate instead of rounding
+			// Don't use Math.floor -- value may be negative
+			delta = parseInt(dumalqura.difference(date1, date2, "day")/7);
+			break;
+		case "day":
+			delta /= 24;
+			// fallthrough
+		case "hour":
+			delta /= 60;
+			// fallthrough
+		case "minute":
+			delta /= 60;
+			// fallthrough
+		case "second":
+			delta /= 1000;
+			// fallthrough
+		case "millisecond":
+			delta *= date2.toGregorian().getTime()- date1.toGregorian().getTime();
+	}
+
+	// Round for fractional values and DST leaps
+	return Math.round(delta); // Number (integer)
+};
+return dumalqura;
+});
+
diff --git a/dojox/date/umalqura/Date.js b/dojox/date/umalqura/Date.js
new file mode 100644
index 0000000..0c5f2d6
--- /dev/null
+++ b/dojox/date/umalqura/Date.js
@@ -0,0 +1,706 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/date"],
+ function(lang, declare, dd){
+
+	var IDate = declare("dojox.date.umalqura.Date", null, {	
+	
+	// summary:
+	//		The component defines the UmAlqura (Hijri) Calendar Object according to Umalqura calculations
+    //		This module is similar to the Date() object provided by JavaScript
+    // example:
+    // |	var date = new dojox.date.umalqura.Date();
+    // |	document.writeln(date.getFullYear()+'\'+date.getMonth()+'\'+date.getDate());
+
+
+    _MONTH_LENGTH: [
+    //1400 -1404 
+    "010100101011", "011010010011", "010110110101", "001010110110", "101110110010",
+    //1405 -1409
+    "011010110101", "010101010110", "101010010110", "110101001010", "111010100101",
+    //1410 -1414
+     "011101010010", "101101101001", "010101110100", "101001101101", "100100110110",
+    //1415 -1419
+     "110010010110", "110101001010", "111001101001", "011010110100", "101010111010",
+    //1420 -1424
+    "010010111101", "001000111101", "100100011101", "101010010101", "101101001010",
+    //1425 -1429
+    "101101011010", "010101101101", "001010110110", "100100111011", "010010011011",
+    //1430 -1434
+     "011001010101", "011010101001", "011101010100", "101101101010", "010101101100",
+    //1435 -1439
+    "101010101101", "010101010101", "101100101001", "101110010010", "101110101001",
+    //1440 -1444
+     "010111010100", "101011011010", "010101011010", "101010101011", "010110010101",
+    //1445 -1449
+     "011101001001", "011101100100", "101110101010", "010110110101", "001010110110",
+    //1450 -1454 
+     "101001010110", "110100101010", "111010010101", "011100101010", "011101010101",
+    //1455 -1459
+     "001101011010", "100101011101", "010010011011", "101001001101", "110100100110",
+    //1460 -1464
+     "110101010011", "010110101010", "101010101101", "010010110110", "101001010111",
+    //1465 -1469
+     "010100100111", "101010010101", "101101001010", "101101010101", "001101101100",
+    //1470 -1474
+     "100110101110", "010010110110", "101010010110", "101101001010", "110110100101",
+    //1475 -1479
+     "010111010010", "010111011001", "001011011100", "100101101101", "010010101101",
+    //1480
+     "011001010101"],
+
+    _hijriBegin: 1400,
+    _hijriEnd: 1480,
+    _date: 0,
+    _month: 0,
+    _year: 0,
+    _hours: 0,
+    _minutes: 0,
+    _seconds: 0,
+    _milliseconds: 0,
+    _day: 0,
+
+    constructor: function(){
+        // summary:
+        //		This function initialize the date object values
+
+        var len = arguments.length;
+        if(!len){// use the current date value, added "" to the similarity to date
+            this.fromGregorian(new Date());
+        }else if(len == 1){
+            var arg0 = arguments[0];
+            if(typeof arg0 == "number"){ // this is time "valueof"
+                arg0 = new Date(arg0);
+            }
+
+            if(arg0 instanceof Date){
+                this.fromGregorian(arg0);
+            }else if(arg0 == ""){
+                // date should be invalid.  Dijit relies on this behavior.
+                this._date = new Date(""); //TODO: should this be NaN?  _date is not a Date object
+            }else{  // this is umalqura.Date object
+                this._year = arg0._year;
+                this._month = arg0._month;
+                this._date = arg0._date;
+                this._hours = arg0._hours;
+                this._minutes = arg0._minutes;
+                this._seconds = arg0._seconds;
+                this._milliseconds = arg0._milliseconds;
+            }
+        }else if(len >= 3){
+            // YYYY MM DD arguments passed, month is from 0-12
+            this._year += arguments[0];
+            this._month += arguments[1];
+            this._date += arguments[2];
+            this._hours += arguments[3] || 0;
+            this._minutes += arguments[4] || 0;
+            this._seconds += arguments[5] || 0;
+            this._milliseconds += arguments[6] || 0;
+        }
+    },
+
+    getDate: function(){
+        // summary:
+        //		This function returns the date value (1 - 30)
+        // example:
+        // |	var date1 = new dojox.date.umalqura.Date();
+        // |
+        // |	document.writeln(date1.getDate);
+        return this._date;
+    },
+
+    getMonth: function(){
+        // summary:
+        //		This function return the month value ( 0 - 11 )
+        // example:
+        // |	var date1 = new dojox.date.umalqura.Date();
+        // |
+        // |	document.writeln(date1.getMonth()+1);
+
+        return this._month;
+    },
+
+    getFullYear: function(){
+        // summary:
+        //		This function return the year value
+        // example:
+        // |	var date1 = new dojox.date.umalqura.Date();
+        // |
+        // |	document.writeln(date1.getFullYear());
+
+        return this._year;
+    },
+
+    getDay: function(){
+        // summary:
+        //		This function returns the week day value ( 0 - 6 )
+        //		sunday is 0, monday is 1,...etc
+        // example:
+        // |	var date1 = new dojox.date.umalqura.Date();
+        // |
+        // |	document.writeln(date1.getDay());
+        var d = this.toGregorian();
+        var dd = d.getDay();
+        return dd;
+    },
+
+    getHours: function(){
+        // summary:
+        //		returns the hour value
+        return this._hours;
+    },
+
+    getMinutes: function(){
+        // summary:
+        //		returns the minutes value
+        return this._minutes;
+    },
+
+    getSeconds: function(){
+        // summary:
+        //		returns the seconds value
+        return this._seconds;
+    },
+
+    getMilliseconds: function(){
+        // summary:
+        //		returns the milliseconds value
+        return this._milliseconds;
+    },
+
+    setDate: function(/*number*/ date){
+        // summary:
+        //		This function sets the date
+        // example:
+        // |	var date1 = new dojox.date.umalqura.Date();
+        // |	date1.setDate(2);
+
+        date = parseInt(date);
+
+        if(date > 0 && date <= this.getDaysInIslamicMonth(this._month, this._year)){
+            this._date = date;
+        }else{
+            var mdays;
+            if(date > 0){
+                for(mdays = this.getDaysInIslamicMonth(this._month, this._year);
+					date > mdays;
+						date -= mdays, mdays = this.getDaysInIslamicMonth(this._month, this._year)){
+                    this._month++;
+                    if(this._month >= 12){ this._year++; this._month -= 12; }
+                }
+
+                this._date = date;
+            }else{
+                for(mdays = this.getDaysInIslamicMonth((this._month - 1) >= 0 ? (this._month - 1) : 11, ((this._month - 1) >= 0) ? this._year : this._year - 1);
+						date <= 0;
+							mdays = this.getDaysInIslamicMonth((this._month - 1) >= 0 ? (this._month - 1) : 11, ((this._month - 1) >= 0) ? this._year : this._year - 1)){
+                    this._month--;
+                    if(this._month < 0){ this._year--; this._month += 12; }
+
+                    date += mdays;
+                }
+                this._date = date;
+            }
+        }
+        return this;
+    },
+
+    setFullYear: function(/*number*/ year){
+        // summary:
+        //		This function set Year
+        // example:
+        // |	var date1 = new dojox.date.umalqura.Date();
+        // |	date1.setYear(1429);
+
+        this._year = +year;
+    },
+
+    setMonth: function(/*number*/ month){
+        // summary:
+        //		This function sets the month
+        // example:
+        // |	var date1 = new dojox.date.umalqura.Date();
+        // |	date1.setMonth(2);
+
+        this._year += Math.floor(month / 12);
+        if(month > 0){
+            this._month = Math.floor(month % 12);
+        }else{
+            this._month = Math.floor(((month % 12) + 12) % 12);
+        }
+    },
+
+    setHours: function(){
+        // summary:
+        //		set the hours
+        var hours_arg_no = arguments.length;
+        var hours = 0;
+        if(hours_arg_no >= 1){
+            hours = parseInt(arguments[0]);
+        }
+
+        if(hours_arg_no >= 2){
+            this._minutes = parseInt(arguments[1]);
+        }
+
+        if(hours_arg_no >= 3){
+            this._seconds = parseInt(arguments[2]);
+        }
+
+        if(hours_arg_no == 4){
+            this._milliseconds = parseInt(arguments[3]);
+        }
+
+        while (hours >= 24){
+            this._date++;
+            var mdays = this.getDaysInIslamicMonth(this._month, this._year);
+            if(this._date > mdays){
+                this._month++;
+                if(this._month >= 12){ this._year++; this._month -= 12; }
+                this._date -= mdays;
+            }
+            hours -= 24;
+        }
+        this._hours = hours;
+    },
+
+	_addMinutes: function(/*Number*/ minutes){
+		minutes += this._minutes;
+		this.setMinutes(minutes);
+		this.setHours(this._hours + parseInt(minutes / 60));
+		return this;
+	},
+
+	_addSeconds: function(/*Number*/ seconds){
+		seconds += this._seconds;
+		this.setSeconds(seconds);
+		this._addMinutes(parseInt(seconds / 60));
+		return this;
+	},
+
+	_addMilliseconds: function(/*Number*/ milliseconds){
+		milliseconds += this._milliseconds;
+		this.setMilliseconds(milliseconds);
+		this._addSeconds(parseInt(milliseconds / 1000));
+		return this;
+	},
+
+    setMinutes: function(/*number*/ minutes){
+        // summary:
+        //		set the minutes
+
+        while (minutes >= 60){
+            this._hours++;
+            if(this._hours >= 24){
+                this._date++;
+                this._hours -= 24;
+                var mdays = this.getDaysInIslamicMonth(this._month, this._year);
+                if(this._date > mdays){
+                    this._month++;
+                    if(this._month >= 12){ this._year++; this._month -= 12; }
+                    this._date -= mdays;
+                }
+            }
+            minutes -= 60;
+        }
+        this._minutes = minutes;
+    },
+
+
+    setSeconds: function(/*number*/ seconds){
+        // summary:
+        //		set seconds
+        while (seconds >= 60){
+            this._minutes++;
+            if(this._minutes >= 60){
+                this._hours++;
+                this._minutes -= 60;
+                if(this._hours >= 24){
+                    this._date++;
+                    this._hours -= 24;
+                    var mdays = this.getDaysInIslamicMonth(this._month, this._year);
+                    if(this._date > mdays){
+                        this._month++;
+                        if(this._month >= 12){ this._year++; this._month -= 12; }
+                        this._date -= mdays;
+                    }
+                }
+            }
+            seconds -= 60;
+        }
+        this._seconds = seconds;
+    },
+
+    setMilliseconds: function(/*number*/ milliseconds){
+        // summary:
+        //		set the milliseconds
+        while (milliseconds >= 1000){
+            this.setSeconds++;
+            if(this.setSeconds >= 60){
+                this._minutes++;
+                this.setSeconds -= 60;
+                if(this._minutes >= 60){
+                    this._hours++;
+                    this._minutes -= 60;
+                    if(this._hours >= 24){
+                        this._date++;
+                        this._hours -= 24;
+                        var mdays = this.getDaysInIslamicMonth(this._month, this._year);
+                        if(this._date > mdays){
+                            this._month++;
+                            if(this._month >= 12){ this._year++; this._month -= 12; }
+                            this._date -= mdays;
+                        }
+                    }
+                }
+            }
+            milliseconds -= 1000;
+        }
+        this._milliseconds = milliseconds;
+    },
+
+
+    toString: function(){
+        // summary:
+        //		This returns a string representation of the date in "DDDD MMMM DD YYYY HH:MM:SS" format
+        // example:
+        // |		var date1 = new dojox.date.umalqura.Date();
+        // |		document.writeln(date1.toString());
+
+        //FIXME: TZ/DST issues?
+        var x = new Date();
+        x.setHours(this._hours);
+        x.setMinutes(this._minutes);
+        x.setSeconds(this._seconds);
+        x.setMilliseconds(this._milliseconds);
+        return this._month + " " + this._date + " " + this._year + " " + x.toTimeString();
+    },
+
+
+    toGregorian: function(){
+        // summary:
+        //		This returns the equivalent gregorian date value in Date object
+        // example:
+        // |	var dateIslamic = new dojox.date.umalqura.Date(1429,11,20);
+        // |	var dateGregorian = dateIslamic.toGregorian();
+
+
+
+        var hYear = this._year;
+        var hMonth = this._month;
+        var hDate = this._date;
+        var gdate = new Date();
+        if(hYear >= this._hijriBegin && hYear <= this._hijriEnd){
+            var gregorianRef = new Array(17);
+            gregorianRef[0] = new Date(1979, 10, 20, 0, 0, 0, 0);
+            gregorianRef[1] = new Date(1984, 8, 26, 0, 0, 0, 0);
+            gregorianRef[2] = new Date(1989, 7, 3, 0, 0, 0, 0);
+            gregorianRef[3] = new Date(1994, 5, 10, 0, 0, 0, 0);
+            gregorianRef[4] = new Date(1999, 3, 17, 0, 0, 0, 0);
+            gregorianRef[5] = new Date(2004, 1, 21, 0, 0, 0, 0);
+            gregorianRef[6] = new Date(2008, 11, 29, 0, 0, 0, 0);
+            gregorianRef[7] = new Date(2013, 10, 4, 0, 0, 0, 0);
+            gregorianRef[8] = new Date(2018, 8, 11, 0, 0, 0, 0);
+            gregorianRef[9] = new Date(2023, 6, 19, 0, 0, 0, 0);
+            gregorianRef[10] = new Date(2028, 4, 25, 0, 0, 0, 0);
+            gregorianRef[11] = new Date(2033, 3, 1, 0, 0, 0, 0);
+            gregorianRef[12] = new Date(2038, 1, 5, 0, 0, 0, 0);
+            gregorianRef[13] = new Date(2042, 11, 14, 0, 0, 0, 0);
+            gregorianRef[14] = new Date(2047, 9, 20, 0, 0, 0, 0);
+            gregorianRef[15] = new Date(2052, 7, 26, 0, 0, 0, 0);
+			gregorianRef[16] = new Date(2057, 6, 3, 0, 0, 0, 0);
+            var i = (hYear - this._hijriBegin);
+            var a = Math.floor(i / 5);
+            var b = i % 5;
+            var days = 0;
+            var m = b;
+            var temp = a * 5;
+            var l = 0;
+            var h = 0;
+
+            if(b == 0){
+                for(h = 0; h <= hMonth - 1; h++){
+                    if(this._MONTH_LENGTH[i].charAt(h) == '1') days = days + 30;
+                    else if(this._MONTH_LENGTH[i].charAt(h) == '0') days = days + 29;
+                }
+                days = days + (hDate - 1);
+            }else{
+                for(k = temp; k <= (temp + b); k++){
+                    for(l = 0; m > 0 && l < 12; l++){
+                        if(this._MONTH_LENGTH[k].charAt(l) == '1') days = days + 30;
+                        else if(this._MONTH_LENGTH[k].charAt(l) == '0') days = days + 29;
+                    }
+                    m--;
+                    if(m == 0){
+                        for(h = 0; h <= hMonth - 1; h++){
+                            if(this._MONTH_LENGTH[i].charAt(h) == '1') days = days + 30;
+                            else if(this._MONTH_LENGTH[i].charAt(h) == '0') days = days + 29;
+                        }
+                    }
+                }
+                days = days + (hDate - 1);
+            }
+            var gregRef = new Date(gregorianRef[a]);
+            gregRef.setHours(this._hours, this._minutes, this._seconds, this._milliseconds);
+            //gdate = dojo.date.add(gregRef, "day", days);
+            gdate = dd.add(gregRef, "day", days);
+        }
+
+        else{
+            var islamicDate = new dojox.date.islamic.Date(this._year, this._month, this._date, this._hours, this._minutes, this._seconds, this._milliseconds);
+            gdate = new Date(islamicDate.toGregorian());
+        }
+        return gdate;
+    },
+
+    //TODO: would it make more sense to make this a constructor option? or a static?
+    fromGregorian: function(/*Date*/ gdate){
+        // summary:
+        //		This function returns the equivalent UmAlqura Date value for the Gregorian Date
+        // example:
+        // |		var dateIslamic = new dojox.date.umalqura.Date();
+        // |		var dateGregorian = new Date(2008,10,12);
+        // |		dateIslamic.fromGregorian(dateGregorian);
+
+
+        var date = new Date(gdate);
+            date.setHours(0, 0, 0, 0);
+        var gYear = date.getFullYear(),
+			gMonth = date.getMonth(),
+			gDay = date.getDate();
+
+        var gregorianRef = new Array(17);
+        gregorianRef[0] = new Date(1979, 10, 20, 0, 0, 0, 0);
+        gregorianRef[1] = new Date(1984, 8, 26, 0, 0, 0, 0);
+        gregorianRef[2] = new Date(1989, 7, 3, 0, 0, 0, 0);
+        gregorianRef[3] = new Date(1994, 5, 10, 0, 0, 0, 0);
+        gregorianRef[4] = new Date(1999, 3, 17, 0, 0, 0, 0);
+        gregorianRef[5] = new Date(2004, 1, 21, 0, 0, 0, 0);
+        gregorianRef[6] = new Date(2008, 11, 29, 0, 0, 0, 0);
+        gregorianRef[7] = new Date(2013, 10, 4, 0, 0, 0, 0);
+        gregorianRef[8] = new Date(2018, 8, 11, 0, 0, 0, 0);
+        gregorianRef[9] = new Date(2023, 6, 19, 0, 0, 0, 0);
+        gregorianRef[10] = new Date(2028, 4, 25, 0, 0, 0, 0);
+        gregorianRef[11] = new Date(2033, 3, 1, 0, 0, 0, 0);
+        gregorianRef[12] = new Date(2038, 1, 5, 0, 0, 0, 0);
+        gregorianRef[13] = new Date(2042, 11, 14, 0, 0, 0, 0);
+        gregorianRef[14] = new Date(2047, 9, 20, 0, 0, 0, 0);
+        gregorianRef[15] = new Date(2052, 7, 26, 0, 0, 0, 0);
+		gregorianRef[16] = new Date(2057, 6, 3, 0, 0, 0, 0);
+		
+		var gregorianLastRef=new Date(2058, 5, 21, 0, 0, 0, 0);
+
+        //if(dojo.date.compare(date, gregorianRef[0]) >= 0 && dojo.date.compare(date, gregorianRef[15]) <= 0){
+        //if(dd.compare(date, gregorianRef[0]) >= 0 && dd.compare(date, gregorianRef[16]) <= 0){
+		if(dd.compare(date, gregorianRef[0]) >= 0 && dd.compare(date, gregorianLastRef) <= 0){
+		var diff;
+			if(dd.compare(date, gregorianRef[16]) <= 0){
+				var count = 0;
+				var pos = 0;
+				var isRef=0;
+				for(count = 0; count < gregorianRef.length; count++){
+					//if(dojo.date.compare(date, gregorianRef[count], "date") == 0){
+					if(dd.compare(date, gregorianRef[count], "date") == 0){                	
+						pos = count;
+						isRef=1;
+						break;
+					}
+					else{
+
+						//if(dojo.date.compare(date, gregorianRef[count], "date") < 0){
+						if(dd.compare(date, gregorianRef[count], "date") < 0){
+							pos = count - 1; break;
+						}
+					}
+				}
+				var j = 0; var flag = 0; var monthL = 0;
+				if(isRef==1){
+					this._date = 1;
+					this._month = 0;
+					this._year = this._hijriBegin + pos*5;
+					this._hours = gdate.getHours();
+					this._minutes = gdate.getMinutes();
+					this._seconds = gdate.getSeconds();
+					this._milliseconds = gdate.getMilliseconds();
+					this._day = gregorianRef[pos].getDay();
+				}
+				else{
+				
+					//var diff = dojo.date.difference(gregorianRef[pos], date, "day");
+					diff = dd.difference(gregorianRef[pos], date, "day");
+					pos = pos * 5;
+					for(i = pos; i < pos + 5; i++){
+						for(j = 0; j <= 11; j++){
+							if(this._MONTH_LENGTH[i].charAt(j) == '1') monthL = 30;
+							else if(this._MONTH_LENGTH[i].charAt(j) == '0') monthL = 29;
+
+							if(diff > monthL) diff = diff - monthL;
+							else{
+								flag = 1;
+								break;
+							}
+						}
+
+						if(flag == 1){
+							if(diff == 0){
+								diff = 1; 
+
+								if(j == 11){
+									j = 1; ++i;
+								}
+								else ++j;
+								break;
+							}
+							else{
+								if(diff==monthL){
+									diff=0;
+									if(j == 11){
+										j = 0;
+										++i;
+									}
+									else ++j;
+								}
+								diff++;
+								break;
+							}
+						}
+					}
+					this._date = diff;
+					this._month = j;
+					this._year = this._hijriBegin + i;
+					this._hours = gdate.getHours();
+					this._minutes = gdate.getMinutes();
+					this._seconds = gdate.getSeconds();
+					this._milliseconds = gdate.getMilliseconds();
+					this._day = gdate.getDay();
+				}
+			}
+			else{
+	//			if((dd.compare(date, gregorianRef[16]) > 0)&& (dd.compare(date,gregorianLastRef)<=0)){
+				//Date is in year 1480
+				diff=dd.difference(gregorianRef[16],date,"day");
+				var x=dd.difference(new Date(2057, 6, 3, 0, 0, 0, 0),new Date(2057, 6, 1, 0, 0, 0, 0),"date");
+				//alert (x);
+				for( j=0;j<=11;j++){
+					if(this._MONTH_LENGTH[80].charAt(j) == '1') monthL = 30;
+					else if(this._MONTH_LENGTH[80].charAt(j) == '0') monthL = 29;
+
+					if(diff > monthL) diff = diff - monthL;
+					else{
+						flag = 1;
+						break;
+					}
+						
+				}
+					
+				if(flag == 1){
+					if(diff == 0){
+						diff = 1;
+
+							if(j == 11){
+								j = 1; ++i;
+							}
+							else ++j;
+							//break;
+					}
+					else{
+						if(diff==monthL){
+							diff=0;
+							if(j == 11){
+								j = 0;
+								++i;
+							}
+							else ++j;
+						}
+							diff++;
+							//break;
+					}
+				}
+				this._date = diff;
+				this._month = j;
+				this._year = 1480;
+				this._hours = gdate.getHours();
+				this._minutes = gdate.getMinutes();
+				this._seconds = gdate.getSeconds();
+				this._milliseconds = gdate.getMilliseconds();
+				this._day = gdate.getDay();
+					
+	//        	}
+			}
+			
+			
+
+		}
+
+        else{
+        	
+			
+            var islamicDate = new dojox.date.islamic.Date(date);
+            this._date = islamicDate.getDate();
+            this._month = islamicDate.getMonth();
+            this._year = islamicDate.getFullYear();
+            this._hours = gdate.getHours();
+            this._minutes = gdate.getMinutes();
+            this._seconds = gdate.getSeconds();
+            this._milliseconds = gdate.getMilliseconds();
+            this._day = gdate.getDay();
+			
+        }
+
+        return this;
+    },
+
+    valueOf: function(){
+        // summary:
+        //		This function returns the stored time value in milliseconds
+        //		since midnight, January 1, 1970 UTC
+
+        return (this.toGregorian()).valueOf();
+    },
+
+    // ported from the Java class com.ibm.icu.util.IslamicCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
+    _yearStart: function(/*Number*/year){
+        // summary:
+        //		return start of Islamic year
+        return (year - 1) * 354 + Math.floor((3 + 11 * year) / 30.0); //1078
+    },
+
+    // ported from the Java class com.ibm.icu.util.IslamicCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
+    _monthStart: function(/*Number*/year, /*Number*/month){
+        // summary:
+        //		return the start of Islamic Month
+        return Math.ceil(29.5 * month) +
+			(year - 1) * 354 + Math.floor((3 + 11 * year) / 30.0);
+    },
+
+    // ported from the Java class com.ibm.icu.util.IslamicCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
+    _civilLeapYear: function(/*Number*/year){
+        // summary:
+        //		return Boolean value if Islamic leap year
+        return (14 + 11 * year) % 30 < 11;
+    },
+
+
+    getDaysInIslamicMonth: function(/*Number*/ month, /*Number*/ year){
+        // summary:
+        //		returns the number of days in the given Islamic month
+        if(year >= this._hijriBegin && year <= this._hijriEnd){
+            var pos = year - this._hijriBegin;
+            var length = 0;
+            if(this._MONTH_LENGTH[pos].charAt(month) == 1)
+                length = 30;
+            else length = 29;
+        }else{
+            var islamicDate = new dojox.date.islamic.Date();
+            length = islamicDate.getDaysInIslamicMonth(month, year);
+        }
+        return length;
+    }
+});
+
+//TODOC
+IDate.getDaysInIslamicMonth = function(/*dojox.date.umalqura.Date*/month){
+	return new IDate().getDaysInIslamicMonth(month.getMonth(),month.getFullYear()); // dojox.date.islamic.Date
+};
+
+return IDate;
+});
+
diff --git a/dojox/date/umalqura/locale.js b/dojox/date/umalqura/locale.js
new file mode 100644
index 0000000..c9fff06
--- /dev/null
+++ b/dojox/date/umalqura/locale.js
@@ -0,0 +1,415 @@
+define(["../..", "dojo/_base/lang", "dojo/_base/array", "dojo/date", "dojo/i18n", "dojo/regexp", "dojo/string", "./Date", "dojo/i18n!dojo/cldr/nls/islamic"],
+       function (dojox, lang, arr, dd, i18n, regexp, string, IDate, bundle) {
+
+           var ilocale = lang.getObject("date.umalqura.locale", true, dojox);
+
+           // Format a pattern without literals
+           function formatPattern(dateObject, bundle, locale, fullYear, pattern) {
+
+               return pattern.replace(/([a-z])\1*/ig, function (match) {
+                   var s, pad;
+                   var c = match.charAt(0);
+                   var l = match.length;
+                   var widthList = ["abbr", "wide", "narrow"];
+
+                   switch (c) {
+                       case 'G':
+                           s = bundle["eraAbbr"][0];
+                           break;
+                       case 'y':
+                           s = String(dateObject.getFullYear());
+                           break;
+                       case 'M':
+                           var m = dateObject.getMonth();
+                           if (l < 3) {
+                               s = m + 1; pad = true;
+                           } else {
+                               var propM = ["months", "format", widthList[l - 3]].join("-");
+                               s = bundle[propM][m];
+                           }
+                           break;
+                       case 'd':
+                           s = dateObject.getDate(true); pad = true;
+                           break;
+                       case 'E':
+                           var d = dateObject.getDay();
+                           if (l < 3) {
+                               s = d + 1; pad = true;
+                           } else {
+                               var propD = ["days", "format", widthList[l - 3]].join("-");
+                               s = bundle[propD][d];
+                           }
+                           break;
+                       case 'a':
+                           var timePeriod = (dateObject.getHours() < 12) ? 'am' : 'pm';
+                           s = bundle['dayPeriods-format-wide-' + timePeriod];
+                           break;
+                       case 'h':
+                       case 'H':
+                       case 'K':
+                       case 'k':
+                           var h = dateObject.getHours();
+                           switch (c) {
+                               case 'h': // 1-12
+                                   s = (h % 12) || 12;
+                                   break;
+                               case 'H': // 0-23
+                                   s = h;
+                                   break;
+                               case 'K': // 0-11
+                                   s = (h % 12);
+                                   break;
+                               case 'k': // 1-24
+                                   s = h || 24;
+                                   break;
+                           }
+                           pad = true;
+                           break;
+                       case 'm':
+                           s = dateObject.getMinutes(); pad = true;
+                           break;
+                       case 's':
+                           s = dateObject.getSeconds(); pad = true;
+                           break;
+                       case 'S':
+                           s = Math.round(dateObject.getMilliseconds() * Math.pow(10, l - 3)); pad = true;
+                           break;
+                       case 'z':
+                           // We only have one timezone to offer; the one from the browser
+                           s = dd.getTimezoneName(dateObject.toGregorian());
+                           if (s) { break; }
+                           l = 4;
+                           // fallthrough... use GMT if tz not available
+                       case 'Z':
+                           var offset = dateObject.toGregorian().getTimezoneOffset();
+                           var tz = [
+                               (offset <= 0 ? "+" : "-"),
+                               string.pad(Math.floor(Math.abs(offset) / 60), 2),
+                               string.pad(Math.abs(offset) % 60, 2)
+                           ];
+                           if (l == 4) {
+                               tz.splice(0, 0, "GMT");
+                               tz.splice(3, 0, ":");
+                           }
+                           s = tz.join("");
+                           break;
+                       default:
+                           throw new Error("dojox.date.umalqura.locale.formatPattern: invalid pattern char: " + pattern);
+                   }
+                   if (pad) { s = string.pad(s, l); }
+                   return s;
+               });
+           }
+
+           // based on and similar to dojo.date.locale.format
+           ilocale.format = function (/*dojox/date/umalqura/Date*/dateObject, /*Object?*/options) {
+               // summary:
+               //		Format a Date object as a String, using  settings.
+               options = options || {};
+
+               var locale = i18n.normalizeLocale(options.locale);
+               var formatLength = options.formatLength || 'short';
+               var bundle = ilocale._getIslamicBundle(locale);
+               var str = [];
+
+               var sauce = lang.hitch(this, formatPattern, dateObject, bundle, locale, options.fullYear);
+               if (options.selector == "year") {
+                   var year = dateObject.getFullYear();
+                   return year;
+               }
+               if (options.selector != "time") {
+                   var datePattern = options.datePattern || bundle["dateFormat-" + formatLength];
+                   if (datePattern) { str.push(_processPattern(datePattern, sauce)); }
+               }
+               if (options.selector != "date") {
+                   var timePattern = options.timePattern || bundle["timeFormat-" + formatLength];
+                   if (timePattern) { str.push(_processPattern(timePattern, sauce)); }
+               }
+               var result = str.join(" "); //TODO: use locale-specific pattern to assemble date + time
+
+               return result; // String
+           };
+
+           ilocale.regexp = function (/*object?*/options) {
+               // summary:
+               //		Builds the regular needed to parse a umalqura.Date
+
+               //	based on and similar to dojo.date.locale.regexp
+
+               return ilocale._parseInfo(options).regexp; // String
+           };
+
+           ilocale._parseInfo = function (/*oblect?*/options) {
+               /* based on and similar to dojo.date.locale._parseInfo */
+
+               options = options || {};
+               var locale = i18n.normalizeLocale(options.locale);
+               var bundle = ilocale._getIslamicBundle(locale);
+               var formatLength = options.formatLength || 'short';
+               var datePattern = options.datePattern || bundle["dateFormat-" + formatLength];
+               var timePattern = options.timePattern || bundle["timeFormat-" + formatLength];
+
+               var pattern;
+               if (options.selector == 'date') {
+                   pattern = datePattern;
+               } else if (options.selector == 'time') {
+                   pattern = timePattern;
+               } else {
+                   pattern = (typeof (timePattern) == "undefined") ? datePattern : datePattern + ' ' + timePattern;
+               }
+
+               var tokens = [];
+
+               var re = _processPattern(pattern, lang.hitch(this, _buildDateTimeRE, tokens, bundle, options));
+               return { regexp: re, tokens: tokens, bundle: bundle };
+           };
+
+           ilocale.parse = function (/*String*/value, /*Object?*/options) {
+               // summary:
+               //		This function parse string date value according to options
+
+               // based on and similar to dojo.date.locale.parse
+
+               value = value.replace(/[\u200E\u200F\u202A\u202E]/g, ""); //remove bidi non-printing chars
+
+               if (!options) { options = {}; }
+               var info = ilocale._parseInfo(options);
+
+               var tokens = info.tokens, bundle = info.bundle;
+               var regexp = info.regexp.replace(/[\u200E\u200F\u202A\u202E]/g, ""); //remove bidi non-printing chars from the pattern
+               var re = new RegExp("^" + regexp + "$");
+
+               var match = re.exec(value);
+
+               var locale = i18n.normalizeLocale(options.locale);
+
+               if (!match) { return null; } // null
+
+               var date, date1;
+
+               var result = [1389, 0, 1, 0, 0, 0, 0];  //FIXME: umalqura date for [1970,0,1,0,0,0,0] used in gregorian locale
+               var amPm = "";
+               var mLength = 0;
+               var widthList = ["abbr", "wide", "narrow"];
+               var valid = arr.every(match, function (v, i) {
+                   if (!i) { return true; }
+                   var token = tokens[i - 1];
+                   var l = token.length;
+                   switch (token.charAt(0)) {
+                       case 'y':
+                           result[0] = Number(v);
+                           break;
+                       case 'M':
+                           if (l > 2) {
+                               var months = bundle['months-format-' + widthList[l - 3]].concat();
+                               if (!options.strict) {
+                                   //Tolerate abbreviating period in month part
+                                   //Case-insensitive comparison
+                                   v = v.replace(".", "").toLowerCase();
+                                   months = arr.map(months, function (s) { return s ? s.replace(".", "").toLowerCase() : s; });
+                               }
+                               v = arr.indexOf(months, v);
+                               if (v == -1) {
+                                   return false;
+                               }
+                               mLength = l;
+                           } else {
+                               v--;
+                           }
+                           result[1] = Number(v);
+                           break;
+                       case 'D':
+                           result[1] = 0;
+                           // fallthrough...
+                       case 'd':
+                           result[2] = Number(v);
+                           break;
+                       case 'a': //am/pm
+                           var am = options.am || bundle['dayPeriods-format-wide-am'],
+                               pm = options.pm || bundle['dayPeriods-format-wide-pm'];
+                           if (!options.strict) {
+                               var period = /\./g;
+                               v = v.replace(period, '').toLowerCase();
+                               am = am.replace(period, '').toLowerCase();
+                               pm = pm.replace(period, '').toLowerCase();
+                           }
+                           if (options.strict && v != am && v != pm) {
+                               return false;
+                           }
+
+                           // we might not have seen the hours field yet, so store the state and apply hour change later
+                           amPm = (v == pm) ? 'p' : (v == am) ? 'a' : '';
+                           break;
+                       case 'K': //hour (1-24)
+                           if (v == 24) { v = 0; }
+                           // fallthrough...
+                       case 'h': //hour (1-12)
+                       case 'H': //hour (0-23)
+                       case 'k': //hour (0-11)
+                           //in the 12-hour case, adjusting for am/pm requires the 'a' part
+                           //which could come before or after the hour, so we will adjust later
+                           result[3] = Number(v);
+                           break;
+                       case 'm': //minutes
+                           result[4] = Number(v);
+                           break;
+                       case 's': //seconds
+                           result[5] = Number(v);
+                           break;
+                       case 'S': //milliseconds
+                           result[6] = Number(v);
+                   }
+                   return true;
+               });
+
+               var hours = +result[3];
+               if (amPm === 'p' && hours < 12) {
+                   result[3] = hours + 12; //e.g., 3pm -> 15
+               } else if (amPm === 'a' && hours == 12) {
+                   result[3] = 0; //12am -> 0
+               }
+               var dateObject = new IDate(result[0], result[1], result[2], result[3], result[4], result[5], result[6]);
+               return dateObject;
+           };
+
+           function _processPattern(pattern, applyPattern, applyLiteral, applyAll) {
+               // summary:
+               //		Process a pattern with literals in it
+
+               // Break up on single quotes, treat every other one as a literal, except '' which becomes '
+               var identity = function (x) { return x; };
+               applyPattern = applyPattern || identity;
+               applyLiteral = applyLiteral || identity;
+               applyAll = applyAll || identity;
+
+               //split on single quotes (which escape literals in date format strings)
+               //but preserve escaped single quotes (e.g., o''clock)
+               var chunks = pattern.match(/(''|[^'])+/g);
+               var literal = pattern.charAt(0) == "'";
+
+               arr.forEach(chunks, function (chunk, i) {
+                   if (!chunk) {
+                       chunks[i] = '';
+                   } else {
+                       chunks[i] = (literal ? applyLiteral : applyPattern)(chunk);
+                       literal = !literal;
+                   }
+               });
+               return applyAll(chunks.join(''));
+           }
+
+           function _buildDateTimeRE(tokens, bundle, options, pattern) {
+               // based on and similar to dojo.date.locale._buildDateTimeRE
+
+               pattern = regexp.escapeString(pattern);
+               var locale = i18n.normalizeLocale(options.locale);
+
+               return pattern.replace(/([a-z])\1*/ig, function (match) {
+
+                   // Build a simple regexp.  Avoid captures, which would ruin the tokens list
+                   var s;
+                   var c = match.charAt(0);
+                   var l = match.length;
+                   var p2 = '', p3 = '';
+                   if (options.strict) {
+                       if (l > 1) { p2 = '0' + '{' + (l - 1) + '}'; }
+                       if (l > 2) { p3 = '0' + '{' + (l - 2) + '}'; }
+                   } else {
+                       p2 = '0?'; p3 = '0{0,2}';
+                   }
+                   switch (c) {
+                       case 'y':
+                           s = '\\d+';
+                           break;
+                       case 'M':
+                           s = (l > 2) ? '\\S+ ?\\S+' : p2 + '[1-9]|1[0-2]';
+                           break;
+                       case 'd':
+                           s = '[12]\\d|' + p2 + '[1-9]|3[01]';
+                           break;
+                       case 'E':
+                           s = '\\S+';
+                           break;
+                       case 'h': //hour (1-12)
+                           s = p2 + '[1-9]|1[0-2]';
+                           break;
+                       case 'k': //hour (0-11)
+                           s = p2 + '\\d|1[01]';
+                           break;
+                       case 'H': //hour (0-23)
+                           s = p2 + '\\d|1\\d|2[0-3]';
+                           break;
+                       case 'K': //hour (1-24)
+                           s = p2 + '[1-9]|1\\d|2[0-4]';
+                           break;
+                       case 'm':
+                       case 's':
+                           s = p2 + '\\d|[0-5]\\d';
+                           break;
+                       case 'S':
+                           s = '\\d{' + l + '}';
+                           break;
+                       case 'a':
+                           var am = options.am || bundle['dayPeriods-format-wide-am'],
+                               pm = options.pm || bundle['dayPeriods-format-wide-pm'];
+                           if (options.strict) {
+                               s = am + '|' + pm;
+                           } else {
+                               s = am + '|' + pm;
+                               if (am != am.toLowerCase()) { s += '|' + am.toLowerCase(); }
+                               if (pm != pm.toLowerCase()) { s += '|' + pm.toLowerCase(); }
+                           }
+                           break;
+                       default:
+                           s = ".*";
+                   }
+                   if (tokens) { tokens.push(match); }
+                   return "(" + s + ")"; // add capture
+               }).replace(/[\xa0 ]/g, "[\\s\\xa0]"); // normalize whitespace.  Need explicit handling of \xa0 for IE. */
+           }
+
+           var _customFormats = [];
+           ilocale.addCustomFormats = function (/*String*/packageName, /*String*/bundleName) {
+               // summary:
+               //		Add a reference to a bundle containing localized custom formats to be
+               //		used by date/time formatting and parsing routines.
+               _customFormats.push({ pkg: packageName, name: bundleName });
+           };
+
+           ilocale._getIslamicBundle = function (/*String*/locale) {
+               var islamic = {};
+               arr.forEach(_customFormats, function (desc) {
+                   var bundle = i18n.getLocalization(desc.pkg, desc.name, locale);
+                   islamic = lang.mixin(islamic, bundle);
+               }, this);
+               return islamic; /*Object*/
+           };
+
+           ilocale.addCustomFormats("dojo.cldr", "islamic");
+
+           ilocale.getNames = function (/*String*/item, /*String*/type, /*String?*/context, /*String?*/locale, /*dojox/date/umalqura/Date?*/date) {
+               // summary:
+               //		Used to get localized strings from dojo.cldr for day or month names.
+               var label;
+               var lookup = ilocale._getIslamicBundle(locale);
+               var props = [item, context, type];
+               if (context == 'standAlone') {
+                   var key = props.join('-');
+                   label = lookup[key];
+                   // Fall back to 'format' flavor of name
+                   if (label[0] == 1) { label = undefined; } // kludge, in the absence of real aliasing support in dojo.cldr
+               }
+               props[1] = 'format';
+
+               // return by copy so changes won't be made accidentally to the in-memory model
+               return (label || lookup[props.join('-')]).concat(); /*Array*/
+           };
+
+
+           ilocale.weekDays = ilocale.getNames('days', 'wide', 'format');
+
+           ilocale.months = ilocale.getNames('months', 'wide', 'format');
+
+           return ilocale;
+       });
+
diff --git a/dojox/dgauges/CONTRIBUTING.md b/dojox/dgauges/CONTRIBUTING.md
new file mode 100755
index 0000000..5ae012f
--- /dev/null
+++ b/dojox/dgauges/CONTRIBUTING.md
@@ -0,0 +1,3 @@
+All contributions to this repository must:
+- be done under the Dojo Contributor License Agreement (CLA, http://dojofoundation.org/about/claForm) that you must sign
+- follow the Dojo style guide (https://dojotoolkit.org/community/styleGuide)
diff --git a/dojox/dgauges/CircularGauge.js b/dojox/dgauges/CircularGauge.js
new file mode 100755
index 0000000..4e794f7
--- /dev/null
+++ b/dojox/dgauges/CircularGauge.js
@@ -0,0 +1,58 @@
+define(["dojo/_base/declare", "dojo/dom-geometry", "dojox/gfx", "./GaugeBase"], function(declare, domGeom, gfx, GaugeBase){
+	return declare("dojox.dgauges.CircularGauge", GaugeBase, {
+		// summary:
+		//		The base class for circular gauges.
+		//		You can create custom circular or semi-circular gauges by extending this class.
+		//		See dojox.dgauges.components.default.CircularLinearGauge.js for an example of circular gauge.
+		
+		_transformProperties: null,
+		
+		refreshRendering: function(){
+			if(this._widgetBox.w <= 0 || this._widgetBox.h <= 0){
+				return;
+			}
+			
+			for(var key in this._elementsIndex){
+				this._elementsRenderers[key] = this._elementsIndex[key].refreshRendering();
+			}
+			
+			// Maximize the drawing area and center the gauge
+			var bb = this._computeBoundingBox(this._gfxGroup);
+			
+			var naturalRatio = (bb.x + bb.width) / (bb.y + bb.height);
+			var widgetWidth = this._widgetBox.w;
+			var widgetHeight = this._widgetBox.h;
+			var widgetRatio = this._widgetBox.w / this._widgetBox.h;
+			
+			var xpos = 0;
+			var ypos = 0;
+			var h = 0;
+			var w = 0;
+			if(naturalRatio > widgetRatio){
+				w = widgetWidth;
+				h = w / naturalRatio;
+				ypos = (widgetHeight - h) / 2;
+			}else{
+				h = widgetHeight;
+				w = h * naturalRatio;
+				xpos = (widgetWidth - w) / 2;
+			}
+			var scaleFactor = Math.max(w / (bb.x + bb.width), h / (bb.y + bb.height));
+			this._transformProperties = {scale:scaleFactor, tx:xpos, ty:ypos};
+			this._gfxGroup.setTransform([gfx.matrix.scale(scaleFactor), gfx.matrix.translate(xpos / scaleFactor, ypos / scaleFactor)]);
+		},
+		
+		_gaugeToPage: function(px, py){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(this._transformProperties){
+				var np = domGeom.position(this.domNode, true);
+				return {x: np.x + px * this._transformProperties.scale + this._transformProperties.tx, y: np.y + py * this._transformProperties.scale + this._transformProperties.ty};
+			}else{
+				return null;
+			}
+		}
+	});
+});
diff --git a/dojox/dgauges/CircularRangeIndicator.js b/dojox/dgauges/CircularRangeIndicator.js
new file mode 100755
index 0000000..e2f60b3
--- /dev/null
+++ b/dojox/dgauges/CircularRangeIndicator.js
@@ -0,0 +1,247 @@
+define(["dojo/_base/declare", "./ScaleIndicatorBase", "./_circularUtils", "dojo/_base/event"],
+	function(declare, ScaleIndicatorBase, _circularUtils, eventUtil){
+	return declare("dojox.dgauges.CircularRangeIndicator", ScaleIndicatorBase, {
+		// summary:
+		//		A CircularRangeIndicator is used to represent a range of values on a scale.
+		//		Use the addIndicator method of CircularScale to use it.
+		//		It is represented as a donut slice.
+		
+		// start: Number
+		//		The start value of the range indicator.
+		start: 0,
+		// radius: Number
+		//		The outer radius in pixels of the range indicator.
+		radius: NaN,
+		// startThickness: Number
+		//		The start thickness of the donut slice in pixels. 
+		startThickness: 6,
+		// endThickness: Number
+		//		The end thickness of the donut slice in pixels. 
+		endThickness: 6,
+		// fill: Object
+		//		A fill object that will be passed to the setFill method of GFX.
+		fill: null,
+		// stroke: Object
+		//		A stroke object that will be passed to the setStroke method of GFX.
+		stroke: null,
+		constructor: function(){
+			this.indicatorShapeFunc = null;
+			this.fill = [255, 120, 0];
+			this.stroke = {
+				color: "black",
+				width: .2
+			};
+			this.interactionMode = "none";
+			
+			this.addInvalidatingProperties(["start", "radius", "startThickness", "endThickness", "fill", "stroke"]);
+		},
+		
+		_interpolateColor: function(from, dest, n){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var fr = (from >> 16) & 0xff;
+			var fg = (from >> 8) & 0xff;
+			var fb = from & 0xff;
+			
+			var tr = (dest >> 16) & 0xff;
+			var tg = (dest >> 8) & 0xff;
+			var tb = dest & 0xff;
+			
+			var r = ((1 - n) * fr + n * tr) & 0xff;
+			var g = ((1 - n) * fg + n * tg) & 0xff;
+			var b = ((1 - n) * fb + n * tb) & 0xff;
+			
+			return r << 16 | g << 8 | b;
+		},
+		
+		_colorsInterpolation: function(colors, ratios, len){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var ret = [];
+			var ilen = 0;
+			
+			for(var i = 0; i < colors.length - 1; i++){
+				ilen = (ratios[i + 1] - ratios[i]) * len;
+				ilen = Math.round(ilen);
+				ret = ret.concat(_colorInterpolation(colors[i], colors[i + 1], ilen));
+			}
+			return ret;
+		},
+		
+		_alphasInterpolation: function(alphas, positions, len){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var ret = [];
+			var ilen = 0;
+			for(var i = 0; i < alphas.length - 1; i++){
+				ilen = (positions[i + 1] - positions[i]) * len;
+				ilen = Math.round(ilen);
+				ret = ret.concat(_alphaInterpolation(alphas[i], alphas[i + 1], ilen));
+			}
+			return ret;
+		},
+		
+		_alphaInterpolation: function(c1, c2, len){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var step = (c2 - c1) / (len - 1);
+			var ret = [];
+			for(var i = 0; i < len; i++){
+				ret.push(c1 + i * step);
+			}
+			return ret;
+		},
+		
+		_colorInterpolation: function(c1, c2, len){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var ret = [];
+			for (var i = 0; i < len; i++){
+				ret.push(_interpolateColor(c1, c2, i / (len - 1)));
+			}
+			return ret;
+		},
+		
+		_getEntriesFor: function(entries, attr){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var ret = [];
+			var e;
+			var val;
+			for(var i = 0; i < entries.length; i++){
+				e = entries[i];
+				if(e[attr] == null || isNaN(e[attr])) {
+					val = i / (entries.length - 1);
+				}
+				else{
+					val = e[attr];
+				}
+				ret.push(val);
+			}
+			return ret;
+		},
+		
+		_drawColorTrack: function(g, ox, oy, radius, orientation, startAngleRadians, endAngleRadians, sWeight, eWeight, fill, stroke, clippingAngleRadians){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var angleStep = 0.05;
+			var totalAngle;
+			
+			totalAngle = 6.28318530718 - _circularUtils.computeAngle(startAngleRadians, endAngleRadians, orientation);
+			if(!isNaN(clippingAngleRadians)){
+				var deltaAngle = _circularUtils.computeAngle(startAngleRadians, clippingAngleRadians, orientation);
+				eWeight *= deltaAngle / totalAngle;
+				totalAngle = deltaAngle;
+			}
+			var iterCount = Math.max(2, Math.floor(totalAngle / angleStep));
+			
+			angleStep = totalAngle / iterCount;
+			var innerRadius;
+			var outerRadius;
+			var outerStep = 0;
+			var innerStep = 0;
+			var px;
+			var py;
+			innerRadius = -sWeight;
+			outerRadius = 0;
+			innerStep = (sWeight - eWeight) / iterCount;
+			
+			var angle;
+			var i;
+			if(orientation == "clockwise"){
+				angleStep = -angleStep;
+			}
+			
+			var gp = [];
+			
+			px = ox + Math.cos(startAngleRadians) * (radius + innerRadius);
+			py = oy - Math.sin(startAngleRadians) * (radius + innerRadius);
+			gp.push(px, py);
+			for(i = 0; i < iterCount; i++){
+				angle = startAngleRadians + i * angleStep;
+				px = ox + Math.cos(angle + angleStep) * (radius + innerRadius + i * innerStep);
+				py = oy - Math.sin(angle + angleStep) * (radius + innerRadius + i * innerStep);
+				gp.push(px, py);
+			}
+			if(isNaN(angle)){
+				angle = startAngleRadians;
+			}
+			px = ox + Math.cos(angle + angleStep) * (radius + outerRadius + (iterCount - 1) * outerStep);
+			py = oy - Math.sin(angle + angleStep) * (radius + outerRadius + (iterCount - 1) * outerStep);
+			gp.push(px, py);
+			for(i = iterCount - 1; i >= 0; i--){
+				angle = startAngleRadians + i * angleStep;
+				px = ox + Math.cos(angle + angleStep) * (radius + outerRadius + i * outerStep);
+				py = oy - Math.sin(angle + angleStep) * (radius + outerRadius + i * outerStep);
+				gp.push(px, py);
+			}
+			px = ox + Math.cos(startAngleRadians) * (radius + outerRadius);
+			py = oy - Math.sin(startAngleRadians) * (radius + outerRadius);
+			gp.push(px, py);
+			
+			px = ox + Math.cos(startAngleRadians) * (radius + innerRadius);
+			py = oy - Math.sin(startAngleRadians) * (radius + innerRadius);
+			gp.push(px, py);
+			g.createPolyline(gp).setFill(fill).setStroke(stroke);
+		},
+		
+		refreshRendering: function(){
+			this.inherited(arguments);
+
+			var g = this._gfxGroup;
+			g.clear();
+			var ox = this.scale.originX;
+			var oy = this.scale.originY;
+			var radius = isNaN(this.radius) ? this.scale.radius  : this.radius;
+			var orientation = this.scale.orientation;
+			var startAngleRadians = _circularUtils.toRadians(360 - this.scale.positionForValue(this.start));
+			var v = isNaN(this._transitionValue) ? this.value : this._transitionValue;
+			var endAngleRadians = _circularUtils.toRadians(360 - this.scale.positionForValue(v));
+			var sWeight = this.startThickness;
+			var eWeight = this.endThickness;
+			var clippingAngleRadians = NaN;
+			
+			this._drawColorTrack(g, ox, oy, radius, orientation, startAngleRadians, endAngleRadians, sWeight, eWeight, this.fill, this.stroke, clippingAngleRadians);
+		},
+		
+		_onMouseDown: function(event){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			var origin = this.scale._gauge._gaugeToPage(this.scale.originX, this.scale.originY);
+			var angle = ((Math.atan2(event.pageY - origin.y, event.pageX - origin.x)) * 180) / (Math.PI);
+			this.set("value", this.scale.valueForPosition(angle));
+
+			// prevent the browser from selecting text
+			eventUtil.stop(event);
+		},
+		
+		_onMouseMove: function(event){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			
+			var origin = this.scale._gauge._gaugeToPage(this.scale.originX, this.scale.originY);
+			var angle = ((Math.atan2(event.pageY - origin.y, event.pageX - origin.x)) * 180) / (Math.PI);
+			this.set("value", this.scale.valueForPosition(angle));
+		}
+	});
+});
diff --git a/dojox/dgauges/CircularScale.js b/dojox/dgauges/CircularScale.js
new file mode 100755
index 0000000..f533cb1
--- /dev/null
+++ b/dojox/dgauges/CircularScale.js
@@ -0,0 +1,276 @@
+define(["dojo/_base/declare", "dojox/gfx", "./ScaleBase", "./_circularUtils"], function(declare, gfx, ScaleBase, _circularUtils){
+	return declare("dojox.dgauges.CircularScale", ScaleBase, {
+		// summary:
+		//		The circular scale. A scaler must be set to use this class.
+
+		// originX: Number
+		//		The origin x-coordinate of the scale in pixels.
+		originX: 50,
+		// originY: Number
+		//		The origin y-coordinate of the scale in pixels.
+		originY: 50,
+		// radius: Number
+		//		The outer radius in pixels of the scale.
+		radius: 50,
+		// startAngle: Number
+		//		The start angle of the scale in degrees.
+		startAngle: 0,
+		// endAngle: Number
+		//		The end angle of the scale in degrees.
+		endAngle: 180,
+		// orientation: String
+		//		The orientation of the scale. Can be "clockwise" or "cclockwise".
+		//		The default value is "clockwise".
+		orientation: "clockwise",
+		
+		constructor: function(){
+
+			this.labelPosition = "inside";
+			
+			this.addInvalidatingProperties(["originX", "originY", "radius", "startAngle", "endAngle", "orientation"]);
+		},
+		
+		_getOrientationNum: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			return this.orientation == "cclockwise" ? -1 : 1;
+		},
+		
+		positionForValue: function(/* Number */value){
+			// summary:
+			//		Transforms a value into an angle using the associated scaler.
+			// returns: Number
+			//		An angle in degrees.
+			var totalAngle = _circularUtils.computeTotalAngle(this.startAngle, this.endAngle, this.orientation);
+			var relativePos = this.scaler.positionForValue(value);
+			return _circularUtils.modAngle(this.startAngle + this._getOrientationNum() * totalAngle * relativePos, 360);
+		},
+		
+		_positionForTickItem: function(tickItem){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var totalAngle = _circularUtils.computeTotalAngle(this.startAngle, this.endAngle, this.orientation);
+			return _circularUtils.modAngle(this.startAngle + this._getOrientationNum() * totalAngle * tickItem.position, 360);
+		},
+		
+		valueForPosition: function(/* Number */angle){
+			// summary:
+			//		Transforms an angle in degrees into a value using the associated scaler.
+			// returns: Number
+			//		The value represented by angle. 
+			if(!this.positionInRange(angle)){
+				var min1 = _circularUtils.modAngle(this.startAngle - angle, 360);
+				var min2 = 360 - min1;
+				var max1 = _circularUtils.modAngle(this.endAngle - angle, 360);
+				var max2 = 360 - max1;
+				var pos;
+				if(Math.min(min1, min2) < Math.min(max1, max2)){
+					pos = 0;
+				}else{
+					pos = 1;
+				}
+			}else{
+				var relativeAngle = _circularUtils.modAngle(this._getOrientationNum() * (angle - this.startAngle), 360);
+				var totalAngle = _circularUtils.computeTotalAngle(this.startAngle, this.endAngle, this.orientation);
+				pos = relativeAngle / totalAngle;
+			}
+			return this.scaler.valueForPosition(pos);
+		},
+		
+		positionInRange: function(/* Number */value){
+			// summary:
+			//		Returns true if the value parameter is between the accepted scale positions.
+			// returns: Boolean
+			//		True if the value parameter is between the accepted scale positions.
+			if(this.startAngle == this.endAngle){
+				return true;
+			}
+			value = _circularUtils.modAngle(value, 360);
+			if(this._getOrientationNum() == 1){
+				if(this.startAngle < this.endAngle){
+					return value >= this.startAngle && value <= this.endAngle;
+				}else{
+					return !(value > this.endAngle && value < this.startAngle);
+				}
+			}else{
+				if(this.startAngle < this.endAngle){
+					return !(value > this.startAngle && value < this.endAngle);
+				}else{
+					return value >= this.endAngle && value <= this.startAngle;
+				}
+			}
+		},
+		
+		_distance: function(x1, y1, x2, y2){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
+		},
+		
+		_layoutLabel: function(label, txt, ox, oy, lrad, angle, labelPlacement){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var font = this._getFont();
+			var box = gfx._base._getTextBox(txt, {
+				font: gfx.makeFontString(gfx.makeParameters(gfx.defaultFont, font))
+			});
+			var tw = box.w;
+			var fz = font.size;
+			var th = gfx.normalizedLength(fz);
+			
+			var tfx = ox + Math.cos(angle) * lrad - tw / 2;
+			var tfy = oy - Math.sin(angle) * lrad - th / 2;
+			var side;
+			
+			var intersections = [];
+			
+			// Intersection with top segment
+			side = tfx;
+			var ipx = side;
+			var ipy = -Math.tan(angle) * side + oy + Math.tan(angle) * ox;
+			// Verify if intersection is on segment
+			if(ipy >= tfy && ipy <= tfy + th){
+				intersections.push({
+					x: ipx,
+					y: ipy
+				});
+			}
+			
+			// Intersection with bottom segment
+			side = tfx + tw;
+			ipx = side;
+			ipy = -Math.tan(angle) * side + oy + Math.tan(angle) * ox;
+			// Verify if intersection is on segment
+			if(ipy >= tfy && ipy <= tfy + th){
+				intersections.push({
+					x: ipx,
+					y: ipy
+				});
+			}
+			// Intersection with left segment
+			side = tfy;
+			ipx = -1 / Math.tan(angle) * side + ox + 1 / Math.tan(angle) * oy;
+			ipy = side;
+			// Verify if intersection is on segment
+			if(ipx >= tfx && ipx <= tfx + tw){
+				intersections.push({
+					x: ipx,
+					y: ipy
+				});
+			}
+			// Intersection with right segment
+			side = tfy + th;
+			ipx = -1 / Math.tan(angle) * side + ox + 1 / Math.tan(angle) * oy;
+			ipy = side;
+			// Verify if intersection is on segment
+			if(ipx >= tfx && ipx <= tfx + tw){
+				intersections.push({
+					x: ipx,
+					y: ipy
+				});
+			}
+			var dif;
+			if(labelPlacement == "inside"){
+				for(var it = 0; it < intersections.length; it++){
+					var ip = intersections[it];
+					dif = this._distance(ip.x, ip.y, ox, oy) - lrad;
+					if(dif >= 0){
+						// Place reference intersection point on reference circle
+						tfx = ox + Math.cos(angle) * (lrad - dif) - tw / 2;
+						tfy = oy - Math.sin(angle) * (lrad - dif) - th / 2;
+						break;
+					}
+				}
+			}else{// "outside" placement
+				for(it = 0; it < intersections.length; it++){
+					ip = intersections[it];
+					dif = this._distance(ip.x, ip.y, ox, oy) - lrad;
+					if(dif <= 0){
+						// Place reference intersection point on reference circle
+						tfx = ox + Math.cos(angle) * (lrad - dif) - tw / 2;
+						tfy = oy - Math.sin(angle) * (lrad - dif) - th / 2;
+						
+						break;
+					}
+				}
+			}
+			if(label){
+				label.setTransform([{
+					dx: tfx + tw / 2,
+					dy: tfy + th
+				}]);
+			}
+		},
+		
+		refreshRendering: function(){
+			this.inherited(arguments);
+			if(!this._gfxGroup || !this.scaler){
+				return;
+			}
+			
+			// Normalize angles
+			this.startAngle = _circularUtils.modAngle(this.startAngle, 360);
+			this.endAngle = _circularUtils.modAngle(this.endAngle, 360);
+			
+			this._ticksGroup.clear();
+			
+			var renderer;
+			var label;
+			var labelText;
+			
+			// Layout ticks
+			var allTicks = this.scaler.computeTicks();
+			
+			var tickBB;
+			for(var i = 0; i < allTicks.length; i++){
+				var tickItem = allTicks[i];
+				renderer = this.tickShapeFunc(this._ticksGroup, this, tickItem);
+				
+				tickBB = this._gauge._computeBoundingBox(renderer);
+				var a;
+				if(tickItem.position){
+					a = this._positionForTickItem(tickItem);
+				}else{
+					a = this.positionForValue(tickItem.value);
+				}
+				if(renderer){
+					renderer.setTransform([{
+						dx: this.originX,
+						dy: this.originY
+					}, gfx.matrix.rotateg(a), {
+						dx: this.radius - tickBB.width - 2 * tickBB.x,
+						dy: 0
+					}]);
+				}
+				labelText = this.tickLabelFunc(tickItem);
+				if(labelText){
+					label = this._ticksGroup.createText({
+						x: 0,
+						y: 0,
+						text: labelText,
+						align: "middle"
+					}).setFont(this._getFont()).setFill(this._getFont().color ? this._getFont().color : "black");
+					var rad = this.radius;
+					if(this.labelPosition == "inside"){
+						rad -= (tickBB.width + this.labelGap);
+					}else{
+						rad += this.labelGap;
+					}
+					this._layoutLabel(label, labelText, this.originX, this.originY, rad, _circularUtils.toRadians(360 - a), this.labelPosition);
+				}
+			}
+			
+			for(var key in this._indicatorsIndex){
+				this._indicatorsRenderers[key] = this._indicatorsIndex[key].invalidateRendering();
+			}
+		}
+	});
+});
diff --git a/dojox/dgauges/CircularValueIndicator.js b/dojox/dgauges/CircularValueIndicator.js
new file mode 100755
index 0000000..b7192e1
--- /dev/null
+++ b/dojox/dgauges/CircularValueIndicator.js
@@ -0,0 +1,62 @@
+define(["dojo/_base/declare", "dojox/gfx", "./ScaleIndicatorBase", "dojo/_base/event"], function(declare, gfx, ScaleIndicatorBase, eventUtil){
+	return declare("dojox.dgauges.CircularValueIndicator", ScaleIndicatorBase, {
+		// summary:
+		//		The circular value indicator, typically used for creating needles.
+
+		indicatorShapeFunc: function(group, indicator){
+			// summary:
+			//		Draws the indicator. The rotation center is at (0, 0).
+			// group: dojox/gfx/Group
+			//		A GFX group for drawing. 
+			// indicator: dojox/dgauges/IndicatorBase
+			//		A reference to this indicator.
+			// returns: dojox/gfx/shape.Shape
+			//		A GFX shape retrievable using the getIndicatorRenderer method of the associated scale. 
+			return group.createLine({
+				x1: 0,
+				y1: 0,
+				x2: 40,
+				y2: 0
+			}).setStroke({
+				color: "black",
+				width: 1
+			});
+		},
+		
+		refreshRendering: function(){
+			this.inherited(arguments);
+			var v = isNaN(this._transitionValue) ? this.value : this._transitionValue;
+			var angle = this.scale.positionForValue(v);
+			
+			this._gfxGroup.setTransform([{
+				dx: this.scale.originX,
+				dy: this.scale.originY
+			}, gfx.matrix.rotateg(angle)]);
+		},
+		
+		_onMouseDown: function(event){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			var origin = this.scale._gauge._gaugeToPage(this.scale.originX, this.scale.originY);
+			var angle = ((Math.atan2(event.pageY - origin.y, event.pageX - origin.x)) * 180) / (Math.PI);
+			this.set("value", this.scale.valueForPosition(angle));
+
+			// prevent the browser from selecting text
+			eventUtil.stop(event);
+		},
+		
+		_onMouseMove: function(event){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			var origin = this.scale._gauge._gaugeToPage(this.scale.originX, this.scale.originY);
+			var angle = ((Math.atan2(event.pageY - origin.y, event.pageX - origin.x)) * 180) / (Math.PI);
+			this.set("value", this.scale.valueForPosition(angle));
+		}
+	});
+});
diff --git a/dojox/dgauges/GaugeBase.js b/dojox/dgauges/GaugeBase.js
new file mode 100755
index 0000000..140ab99
--- /dev/null
+++ b/dojox/dgauges/GaugeBase.js
@@ -0,0 +1,295 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/dom-geometry", "dijit/registry", "dijit/_WidgetBase", "dojo/_base/html", 
+		"dojo/_base/event", "dojox/gfx", "dojox/widget/_Invalidating","./ScaleBase", "dojox/gfx/matrix"],
+	function(lang, // lang.extend
+		declare, domGeom,  WidgetRegistry, _WidgetBase, html, event, gfx, _Invalidating, ScaleBase, matrix){
+	return declare("dojox.dgauges.GaugeBase", [_WidgetBase, _Invalidating], {
+		// summary: 
+		//		This class is the base class for the circular and 
+		//		rectangular (horizontal and vertical) gauge components.
+		//		A gauge is a composition of elements added to the gauge using the addElement method.
+		//		Elements are drawn from back to front in the same order they are added (using addElement).
+		//		An elements can be: 
+		//
+		//		- A GFX drawing functions typically used for defining the style of the gauge.
+		//		- A scale: CircularScale or RectangularScale depending on the type of gauge.
+		//		- A text, using the TextIndicator
+		//		Note: Indicator classes (value indicators, range indicators) are sub-elements of scales
+		//		To create a custom gauge, subclass CircularGauge or RectangularGauge and
+		//		configure its elements in the constructor.
+		//		Ready to use, predefined gauges are available in dojox/dgauges/components/
+		//		They are good examples of gauges built on top of the framework.
+		
+		_elements: null,
+		_scales: null,
+		_elementsIndex: null,
+		_elementsRenderers: null,
+		_gfxGroup: null,
+		_mouseShield: null,
+		_widgetBox: null,
+		_node: null,
+
+		// value: Number
+		//		This property acts as a top-level wrapper for the value of the first indicator added to 
+		//		its scale with the name "indicator", i.e. myScale.addIndicator("indicator", myIndicator).
+		//		This property must be manipulated with get("value") and set("value", xxx).
+		value: 0,
+		_mainIndicator: null,
+		
+		_getValueAttr: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private			
+			if(this._mainIndicator){
+				return this._mainIndicator.get("value");
+			}else{
+				this._setMainIndicator();
+				if(this._mainIndicator){
+					return this._mainIndicator.get("value");
+				}
+			}
+			return this.value;
+		},
+		
+		_setValueAttr: function(value){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private			
+			this._set("value", value);
+			if(this._mainIndicator){
+				this._mainIndicator.set("value", value);
+			}else{
+				this._setMainIndicator();
+				if(this._mainIndicator){
+					this._mainIndicator.set("value", value);
+				}
+			}
+		},
+		
+		_setMainIndicator: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private	
+			var indicator;
+			for(var i=0; i<this._scales.length; i++){
+				indicator = this._scales[i].getIndicator("indicator");
+				if(indicator){
+					this._mainIndicator = indicator;
+				}
+			}
+		},
+		
+		_resetMainIndicator: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this._mainIndicator = null;
+		},
+		
+		// font: Object
+		//		The font of the gauge used by elements if not overridden.
+		font: null,
+		
+		constructor: function(/* Object */args, /* DOMNode */ node){
+			this.font = {
+				family: "Helvetica",
+				style: "normal",
+				variant: "small-caps",
+				weight: "bold",
+				size: "10pt",
+				color: "black"
+			};
+			this._elements = [];
+			this._scales = [];
+			this._elementsIndex = {};
+			this._elementsRenderers = {};
+			this._node = WidgetRegistry.byId(node);
+			var box = html.getMarginBox(node);
+
+			this.surface = gfx.createSurface(this._node, box.w || 1, box.h || 1);
+			this._widgetBox = box;
+			// _baseGroup is a workaround for http://bugs.dojotoolkit.org/ticket/14471
+			this._baseGroup = this.surface.createGroup();
+			this._mouseShield = this._baseGroup.createGroup();
+			this._gfxGroup = this._baseGroup.createGroup();
+		},
+		
+		_setCursor: function(type){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(this._node)
+				this._node.style.cursor = type;
+		},
+		
+		_computeBoundingBox: function(/* Object */element){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			return element ? element.getBoundingBox() : {x:0, y:0, width:0, height:0};
+		},
+		
+		destroy: function(){
+			// summary:
+			//		Cleanup when a gauge is to be destroyed.
+			this.surface.destroy();
+			this.inherited(arguments);
+		},
+
+		resize: function(width, height){
+			// summary:
+			//		Resize the gauge to the dimensions of width and height.
+			// description:
+			//		Resize the gauge and its surface to the width and height dimensions.
+			//		If a single argument of the form {w: value1, h: value2} is provided take that argument as the dimensions to use.
+			//		Finally if no argument is provided, resize the surface to the marginBox of the gauge.
+			// width: Number|Object?
+			//		The new width of the gauge or the box definition.
+			// height: Number?
+			//		The new height of the gauge.
+			// returns: dojox/dgauges/GaugeBase
+			//		A reference to the current gauge for functional chaining.
+			switch(arguments.length){
+				// case 0, do not resize the div, just the surface
+				case 1:
+					// argument, override node box
+					domGeom.setMarginBox(this._node, width);
+					break;
+				case 2:
+
+					// argument, override node box
+					domGeom.setMarginBox(this._node, {w: width, h: height});
+					break;
+			}
+			// in all cases take back the computed box
+			var box = domGeom.getMarginBox(this._node);
+			this._widgetBox = box;
+			var d = this.surface.getDimensions();
+			if(d.width != box.w || d.height != box.h){
+				// and set it on the surface
+				this.surface.setDimensions(box.w, box.h);
+				this._mouseShield.clear();
+				this._mouseShield.createRect({x:0,y:0,width:box.w,height:box.h}).setFill([0, 0, 0, 0]);
+				return this.invalidateRendering();
+			}else{
+				return this;
+			}
+		},
+		
+		addElement: function(/* String */name, /* Object */ element){
+			// summary:
+			//		Adds a element to the gauge.
+			// name: String
+			//		The name of the element to be added.
+			// element: Object
+			//		This parameter can be:
+			//
+			//		- A function which takes on argument of type GFX Group and return null or a
+			//		GFX element retrievable using the getElementRenderer() method.
+			//		- A Scale instance, i.e. CircularScale or RectangularScale.
+			//		- A TextIndicator instance.
+			if(this._elementsIndex[name] && this._elementsIndex[name] != element){
+				this.removeElement(name);
+			}
+			
+			if(lang.isFunction(element)){
+				var gfxHolder = {};
+				lang.mixin(gfxHolder, new _Invalidating());
+				gfxHolder._name = name;
+				gfxHolder._gfxGroup = this._gfxGroup.createGroup();
+				gfxHolder.width = 0;
+				gfxHolder.height = 0;
+				gfxHolder._isGFX = true;
+				gfxHolder.refreshRendering = function(){
+					gfxHolder._gfxGroup.clear();
+					return element(gfxHolder._gfxGroup, gfxHolder.width, gfxHolder.height);
+				};
+				this._elements.push(gfxHolder);
+				this._elementsIndex[name] = gfxHolder;
+			}else{
+				element._name = name;
+				element._gfxGroup = this._gfxGroup.createGroup();
+				element._gauge = this;
+				this._elements.push(element);
+				this._elementsIndex[name] = element;
+				
+				if(element instanceof ScaleBase){
+					this._scales.push(element);
+				}
+			}
+			return this.invalidateRendering();
+		},
+		
+		removeElement: function(/* String */name){
+			// summary:
+			//		Remove the element defined by name from the gauge.
+			// name: String
+			//		The name of the element as defined using addElement.
+			// returns: Object
+			//		A reference to the removed element.
+			
+			var element = this._elementsIndex[name];
+			
+			if(element){
+				element._gfxGroup.removeShape();
+				var idx = this._elements.indexOf(element);
+				this._elements.splice(idx, 1);
+				
+				if(element instanceof ScaleBase){
+					var idxs = this._scales.indexOf(element);
+					this._scales.splice(idxs, 1);
+					this._resetMainIndicator();
+				}
+				delete this._elementsIndex[name];
+				delete this._elementsRenderers[name];
+			}
+			this.invalidateRendering();
+			return element;
+		},
+		
+		getElement: function(/* String */name){
+			// summary:
+			//		Get the given element, by name.
+			// name: String
+			//		The name of the element as defined using addElement.
+			// returns: Object
+			//		The element.
+			return this._elementsIndex[name];
+		},
+		
+		getElementRenderer: function(/* String */name){
+			// summary:
+			//		Get the given element renderer, by name.
+			// name: String
+			//		The name of the element as defined using addElement.
+			// returns: Object
+			//		The element renderer returned by the
+			//		drawing function or by the refreshRendering() method
+			//		in the case of framework classes.
+			return this._elementsRenderers[name];
+		},
+		
+		onStartEditing: function(event){
+			// summary:
+			//		Called when an interaction begins (keyboard, mouse or gesture).
+			// event:
+			//		On object with a unique member "indicator". This member is a reference to the modified indicator.
+			// tags:
+			//		callback
+		},
+		
+		onEndEditing: function(event){
+			// summary:
+			//		Called when an interaction ends (keyboard, mouse or gesture).
+			// event:
+			//		On object with a unique member "indicator". This member is a reference to the modified indicator.
+			// tags:
+			//		callback
+		}
+	})
+});
diff --git a/dojox/dgauges/IndicatorBase.js b/dojox/dgauges/IndicatorBase.js
new file mode 100755
index 0000000..ce299c8
--- /dev/null
+++ b/dojox/dgauges/IndicatorBase.js
@@ -0,0 +1,10 @@
+define(["dojo/_base/declare", "dojox/widget/_Invalidating"], function(declare, _Invalidating){
+	return declare("dojox.dgauges.IndicatorBase", _Invalidating, {
+		// summary:
+		//		The base class for indicators. Basically, an indicator is used to render a value.
+
+		// value: Number
+		//		The value of this indicator.
+		value: null
+	});
+});
diff --git a/dojox/dgauges/LICENSE b/dojox/dgauges/LICENSE
new file mode 100755
index 0000000..7631b14
--- /dev/null
+++ b/dojox/dgauges/LICENSE
@@ -0,0 +1,195 @@
+Dojo is available under *either* the terms of the modified BSD license *or* the
+Academic Free License version 2.1. As a recipient of Dojo, you may choose which
+license to receive this code under (except as noted in per-module LICENSE
+files). Some modules may not be the copyright of the Dojo Foundation. These
+modules contain explicit declarations of copyright in both the LICENSE files in
+the directories in which they reside and in the code itself. No external
+contributions are allowed under licenses which are fundamentally incompatible
+with the AFL or BSD licenses that Dojo is distributed under.
+
+The text of the AFL and BSD licenses is reproduced below. 
+
+-------------------------------------------------------------------------------
+The "New" BSD License:
+**********************
+
+Copyright (c) 2005-2013, The Dojo Foundation
+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 the Dojo Foundation 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
+
+-------------------------------------------------------------------------------
+The Academic Free License, v. 2.1:
+**********************************
+
+This Academic Free License (the "License") applies to any original work of
+authorship (the "Original Work") whose owner (the "Licensor") has placed the
+following notice immediately following the copyright notice for the Original
+Work:
+
+Licensed under the Academic Free License version 2.1
+
+1) Grant of Copyright License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license to do the
+following:
+
+a) to reproduce the Original Work in copies;
+
+b) to prepare derivative works ("Derivative Works") based upon the Original
+Work;
+
+c) to distribute copies of the Original Work and Derivative Works to the
+public;
+
+d) to perform the Original Work publicly; and
+
+e) to display the Original Work publicly.
+
+2) Grant of Patent License. Licensor hereby grants You a world-wide,
+royalty-free, non-exclusive, perpetual, sublicenseable license, under patent
+claims owned or controlled by the Licensor that are embodied in the Original
+Work as furnished by the Licensor, to make, use, sell and offer for sale the
+Original Work and Derivative Works.
+
+3) Grant of Source Code License. The term "Source Code" means the preferred
+form of the Original Work for making modifications to it and all available
+documentation describing how to modify the Original Work. Licensor hereby
+agrees to provide a machine-readable copy of the Source Code of the Original
+Work along with each copy of the Original Work that Licensor distributes.
+Licensor reserves the right to satisfy this obligation by placing a
+machine-readable copy of the Source Code in an information repository
+reasonably calculated to permit inexpensive and convenient access by You for as
+long as Licensor continues to distribute the Original Work, and by publishing
+the address of that information repository in a notice immediately following
+the copyright notice that applies to the Original Work.
+
+4) Exclusions From License Grant. Neither the names of Licensor, nor the names
+of any contributors to the Original Work, nor any of their trademarks or
+service marks, may be used to endorse or promote products derived from this
+Original Work without express prior written permission of the Licensor. Nothing
+in this License shall be deemed to grant any rights to trademarks, copyrights,
+patents, trade secrets or any other intellectual property of Licensor except as
+expressly stated herein. No patent license is granted to make, use, sell or
+offer to sell embodiments of any patent claims other than the licensed claims
+defined in Section 2. No right is granted to the trademarks of Licensor even if
+such marks are included in the Original Work. Nothing in this License shall be
+interpreted to prohibit Licensor from licensing under different terms from this
+License any Original Work that Licensor otherwise would have a right to
+license.
+
+5) This section intentionally omitted.
+
+6) Attribution Rights. You must retain, in the Source Code of any Derivative
+Works that You create, all copyright, patent or trademark notices from the
+Source Code of the Original Work, as well as any notices of licensing and any
+descriptive text identified therein as an "Attribution Notice." You must cause
+the Source Code for any Derivative Works that You create to carry a prominent
+Attribution Notice reasonably calculated to inform recipients that You have
+modified the Original Work.
+
+7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that
+the copyright in and to the Original Work and the patent rights granted herein
+by Licensor are owned by the Licensor or are sublicensed to You under the terms
+of this License with the permission of the contributor(s) of those copyrights
+and patent rights. Except as expressly stated in the immediately proceeding
+sentence, the Original Work is provided under this License on an "AS IS" BASIS
+and WITHOUT WARRANTY, either express or implied, including, without limitation,
+the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.
+This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No
+license to Original Work is granted hereunder except under this disclaimer.
+
+8) Limitation of Liability. Under no circumstances and under no legal theory,
+whether in tort (including negligence), contract, or otherwise, shall the
+Licensor be liable to any person for any direct, indirect, special, incidental,
+or consequential damages of any character arising as a result of this License
+or the use of the Original Work including, without limitation, damages for loss
+of goodwill, work stoppage, computer failure or malfunction, or any and all
+other commercial damages or losses. This limitation of liability shall not
+apply to liability for death or personal injury resulting from Licensor's
+negligence to the extent applicable law prohibits such limitation. Some
+jurisdictions do not allow the exclusion or limitation of incidental or
+consequential damages, so this exclusion and limitation may not apply to You.
+
+9) Acceptance and Termination. If You distribute copies of the Original Work or
+a Derivative Work, You must make a reasonable effort under the circumstances to
+obtain the express assent of recipients to the terms of this License. Nothing
+else but this License (or another written agreement between Licensor and You)
+grants You permission to create Derivative Works based upon the Original Work
+or to exercise any of the rights granted in Section 1 herein, and any attempt
+to do so except under the terms of this License (or another written agreement
+between Licensor and You) is expressly prohibited by U.S. copyright law, the
+equivalent laws of other countries, and by international treaty. Therefore, by
+exercising any of the rights granted to You in Section 1 herein, You indicate
+Your acceptance of this License and all of its terms and conditions.
+
+10) Termination for Patent Action. This License shall terminate automatically
+and You may no longer exercise any of the rights granted to You by this License
+as of the date You commence an action, including a cross-claim or counterclaim,
+against Licensor or any licensee alleging that the Original Work infringes a
+patent. This termination provision shall not apply for an action alleging
+patent infringement by combinations of the Original Work with other software or
+hardware.
+
+11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this
+License may be brought only in the courts of a jurisdiction wherein the
+Licensor resides or in which Licensor conducts its primary business, and under
+the laws of that jurisdiction excluding its conflict-of-law provisions. The
+application of the United Nations Convention on Contracts for the International
+Sale of Goods is expressly excluded. Any use of the Original Work outside the
+scope of this License or after its termination shall be subject to the
+requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et
+seq., the equivalent laws of other countries, and international treaty. This
+section shall survive the termination of this License.
+
+12) Attorneys Fees. In any action to enforce the terms of this License or
+seeking damages relating thereto, the prevailing party shall be entitled to
+recover its costs and expenses, including, without limitation, reasonable
+attorneys' fees and costs incurred in connection with such action, including
+any appeal of such action. This section shall survive the termination of this
+License.
+
+13) Miscellaneous. This License represents the complete agreement concerning
+the subject matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent necessary to
+make it enforceable.
+
+14) Definition of "You" in This License. "You" throughout this License, whether
+in upper or lower case, means an individual or a legal entity exercising rights
+under, and complying with all of the terms of, this License. For legal
+entities, "You" includes any entity that controls, is controlled by, or is
+under common control with you. For purposes of this definition, "control" means
+(i) the power, direct or indirect, to cause the direction or management of such
+entity, whether by contract or otherwise, or (ii) ownership of fifty percent
+(50%) or more of the outstanding shares, or (iii) beneficial ownership of such
+entity.
+
+15) Right to Use. You may use the Original Work in all ways not otherwise
+restricted or conditioned by this License or by law, and Licensor promises not
+to interfere with or be responsible for such uses by You.
+
+This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.
+Permission is hereby granted to copy and distribute this license without
+modification. This license may not be modified without the express written
+permission of its copyright owner.
\ No newline at end of file
diff --git a/dojox/dgauges/LinearScaler.js b/dojox/dgauges/LinearScaler.js
new file mode 100755
index 0000000..ffdc3e1
--- /dev/null
+++ b/dojox/dgauges/LinearScaler.js
@@ -0,0 +1,161 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/Stateful"], function(lang, declare, Stateful){
+	return declare("dojox.dgauges.LinearScaler", Stateful, {
+		// summary:
+		//		The linear scaler. This scaler creates major and minor ticks regularly between 
+		//		a minimum and a maximum.
+		//		Scalers are responsible for tick generation and various data-transform operations.		
+		
+		// minimum: Number
+		//		The minimum value of the scaler. Default is 0.
+		minimum: 0,
+		// maximum: Number
+		//		The maximum value of the scaler. Default is 100.
+		maximum: 100,
+		// snapInterval:
+		//		Specifies the increment value to be used as snap values on this scale 
+		//		during user interaction.
+		//		Default is 1.
+		snapInterval: 1,
+		// majorTickInterval: Number
+		//		The interval between two major ticks.
+		majorTickInterval: NaN,
+		// minorTickInterval: Number
+		//		The interval between two minor ticks.
+		minorTickInterval: NaN,
+		// minorTicksEnabled: Boolean
+		//		If false, minor ticks are not generated. Default is true.
+		minorTicksEnabled: true,
+		// majorTicks:
+		//		The array of generated major ticks. You should not set this
+		//		property when using the scaler.
+		majorTicks: null,
+		// minorTicks:
+		//		The array of generated minor ticks. You should not set this
+		//		property when using the scaler.
+		minorTicks: null,
+
+		_computedMajorTickInterval: NaN,
+		_computedMinorTickInterval: NaN,
+		
+		constructor: function(){
+			this.watchedProperties = ["minimum", "maximum", "majorTickInterval", "minorTickInterval", "snapInterval", "minorTicksEnabled"];
+		},
+
+		_buildMinorTickItems: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var mt = this.majorTicks;
+			var minorTickCache = [];
+			if(this.maximum > this.minimum){
+				var majorTickCount = Math.floor((this.maximum - this.minimum) / this.getComputedMajorTickInterval()) + 1;
+				var minorTickCount = Math.floor(this.getComputedMajorTickInterval() / this.getComputedMinorTickInterval());
+				var data;
+				for(var i = 0; i < majorTickCount - 1; i++){
+					for(var j = 1; j < minorTickCount; j++){
+						data = {scaler: this};
+						data.isMinor = true;
+						data.value = mt[i].value + j * this.getComputedMinorTickInterval();
+						data.position = (Number(data.value) - this.minimum) / (this.maximum - this.minimum);
+						minorTickCache.push(data);
+					}
+				}
+			}
+			return minorTickCache;
+		},
+		
+		_buildMajorTickItems: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var majorTickCache = [];
+			if(this.maximum > this.minimum){
+				var majorTickCount = Math.floor((this.maximum - this.minimum) / this.getComputedMajorTickInterval()) + 1;
+				var data;
+				for(var i = 0; i < majorTickCount; i++){
+					data = {scaler: this};
+					data.isMinor = false;
+					data.value = this.minimum + i * this.getComputedMajorTickInterval();
+					data.position = (Number(data.value) - this.minimum) / (this.maximum - this.minimum);
+					majorTickCache.push(data);
+				}
+			}
+			return majorTickCache;
+		},
+		
+		getComputedMajorTickInterval: function(){
+			// summary:
+			//		The computed or user defined major tick interval.
+			// returns: Number
+			//		The major tick interval used for ticks generation.
+			if(!isNaN(this.majorTickInterval)){
+				return this.majorTickInterval;
+			}
+			if(isNaN(this._computedMajorTickInterval)){
+				this._computedMajorTickInterval = (this.maximum - this.minimum) / 10;
+			}
+			return this._computedMajorTickInterval;
+		},
+		
+		getComputedMinorTickInterval: function(){
+			// summary:
+			//		The computed or user defined minor tick interval.
+			// returns: Number
+			//		The minor tick interval used for ticks generation.
+			if(!isNaN(this.minorTickInterval)){
+				return this.minorTickInterval;
+			}
+			if(isNaN(this._computedMinorTickInterval)){
+				this._computedMinorTickInterval = this.getComputedMajorTickInterval() / 5;
+			}
+			return this._computedMinorTickInterval;
+		},
+		
+		computeTicks: function(){
+			// summary:
+			//		Creates or re-creates the ticks for this scaler.
+			// returns: Array
+			//		An array containing all ticks (major then minor ticks).
+			this.majorTicks = this._buildMajorTickItems();
+			this.minorTicks = this.minorTicksEnabled ? this._buildMinorTickItems() : [];
+			return this.majorTicks.concat(this.minorTicks);
+		},
+		
+		positionForValue: function(value){
+			// summary:
+			//		Transforms a value into a relative position between 0 and 1.
+			// value: Number
+			//		A value to transform.
+			// returns: Number
+			//		The position between 0 and 1.
+			var position;
+			if(value == null || isNaN(value) || value <= this.minimum){
+				position = 0;
+			}
+			if(value >= this.maximum){
+				position = 1;
+			}
+			if(isNaN(position)){
+				position = (value - this.minimum) / (this.maximum - this.minimum);
+			}
+			return position;
+		},
+		
+		valueForPosition: function(position){
+			// summary:
+			//		Transforms a relative position (between 0 and 1) into a value.
+			// position: Number
+			//		A relative position to transform.
+			// returns: Number
+			//		The transformed value between minimum and maximum.
+			var range = Math.abs(this.minimum - this.maximum);
+			var value = this.minimum + range * position;
+			if(!isNaN(this.snapInterval) && this.snapInterval > 0){
+				value = Math.round((value - this.minimum) / this.snapInterval) * this.snapInterval + this.minimum;
+			}
+			return value;
+		}
+	});
+});
diff --git a/dojox/dgauges/LogScaler.js b/dojox/dgauges/LogScaler.js
new file mode 100755
index 0000000..0df5a8f
--- /dev/null
+++ b/dojox/dgauges/LogScaler.js
@@ -0,0 +1,120 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/Stateful"], function(lang, declare, Stateful){
+	return declare("dojox.dgauges.LogScaler", Stateful, {
+		// summary:
+		//		The LogScaler maps numeric values evenly
+		//		between a minimum and a maximum value along a gauge scale.
+		//		If no multiplier is specified, the scale will place
+		//		a tick on each power of 10 value (1, 10, 100, 1000, and so on) between
+		//		the minimum and maximum values.
+		
+		// minimum: Number
+		//		The minimum value of the scaler. Default is 0.
+		minimum: 0,
+		// maximum: Number
+		//		The maximum value of the scaler. Default is 1000.
+		maximum: 1000,
+		// multiplier: Number
+		//		The interval between two major ticks.
+		multiplier: 10,
+		// majorTicks:
+		//		The array of generated major ticks. You should not set this
+		//		property when using the scaler.
+		majorTicks: null,
+		
+		_computedMultiplier: NaN,
+		
+		constructor: function(){
+			this.watchedProperties = ["minimum", "maximum", "multiplier"];
+		},
+		_buildMajorTickItems: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var majorTickCache = [];
+			this._computedMinimum = this.getComputedMinimum();
+			this._computedMaximum = this.getComputedMaximum();
+			this._computedMultiplier = this.getComputedMultiplier();
+			
+			if(this._computedMaximum > this._computedMinimum){
+				var start = Math.max(0, Math.floor(Math.log(this._computedMinimum + 0.000000001) / Math.LN10));
+				var end = Math.max(0, Math.floor(Math.log(this._computedMaximum + 0.000000001) / Math.LN10));
+				var data;
+				for(var i = start; i <= end; i += this._computedMultiplier){
+					data = {};
+					data.value = Math.pow(10, i);
+					data.position = (i - start) / (end - start);
+					majorTickCache.push(data);
+				}
+			}
+			return majorTickCache;
+		},
+		
+		getComputedMinimum: function(){
+			// summary:
+			//		The computed minimum value of the scale. If the minimum value is not
+			//		an even power of 10, the scale computes a new minimum so that it maps to 
+			//		an even power of 10.
+			return Math.pow(10, Math.max(0, Math.floor(Math.log(this.minimum + 0.000000001) / Math.LN10)));
+		},
+		
+		getComputedMaximum: function(){
+			// summary:
+			//		The computed maximum value of the scale. If the maximum value is not
+			//		an even power of 10, the scale computes a new maximum so that it maps to 
+			//		an even power of 10.
+			return Math.pow(10, Math.max(0, Math.floor(Math.log(this.maximum + 0.000000001) / Math.LN10)));
+		},
+		
+		
+		getComputedMultiplier: function(){
+			// summary:
+			//		The computed multiplier value of the scale. If the multiplier value is not
+			//		an even power of 10, the scale computes a new multiplier so that it maps to 
+			//		an even power of 10.
+			return Math.max(1, Math.floor(Math.log(this.multiplier + 0.000000001) / Math.LN10));
+			
+		},
+		
+		computeTicks: function(){
+			// summary:
+			//		Creates or re-creates the ticks for this scaler.
+			// returns: Array
+			//		An array containing ticks.
+			this.majorTicks = this._buildMajorTickItems();
+			return this.majorTicks.concat();
+		},
+		
+		positionForValue: function(value){
+			// summary:
+			//		Transforms a value into a relative position between 0 and 1.
+			// value: Number
+			//		A value to transform.
+			// returns: Number
+			//		The position between 0 and 1.
+			
+			if(this._computedMaximum < this._computedMinimum || value <= this._computedMinimum || value < 1 || isNaN(value)){
+				value = this._computedMinimum;
+			}
+			if(value >= this._computedMaximum){
+				value = this._computedMaximum;
+			}
+			value = Math.log(value) / Math.LN10;
+			var sv = Math.log(this._computedMinimum) / Math.LN10;
+			var ev = Math.log(this._computedMaximum) / Math.LN10;
+			return (value - sv) / (ev - sv);
+		},
+		
+		valueForPosition: function(position){
+			// summary:
+			//		Transforms a relative position (between 0 and 1) into a value.
+			// position: Number
+			//		A relative position to transform.
+			// returns: Number
+			//		The transformed value between minimum and maximum.
+			var sv = Math.log(this._computedMinimum) / Math.LN10;
+			var ev = Math.log(this._computedMaximum) / Math.LN10;
+			return Math.pow(10, sv + position * (ev - sv));
+		}
+	});
+});
diff --git a/dojox/dgauges/MultiLinearScaler.js b/dojox/dgauges/MultiLinearScaler.js
new file mode 100755
index 0000000..6ae9d5c
--- /dev/null
+++ b/dojox/dgauges/MultiLinearScaler.js
@@ -0,0 +1,149 @@
+define(["dojo/_base/declare", "dojo/Stateful"], function(declare, Stateful){
+	return declare("dojox.dgauges.MultiLinearScaler", Stateful, {
+		// summary:
+		//		The multi-linear scaler. This scaler maps numeric values according 
+		//		to the majorTickValues content. 
+		//		This allows display of very large value intervals that are difficult to render 
+		//		with a linear scale. For example, if majorTickValues contains [0, 10, 50, 500, 2000], 
+		//		the scale will show five major ticks with these values. 
+		//		Note that this is not a logarithmic scale, the interpolation is linear between 
+		//		two contiguous major ticks.
+		//		Scalers are responsible for tick generation and various data-transform operations.	
+
+		// majorTickValues: Array
+		//		An array of Number for creating major ticks.
+		//		This array must be sorted in ascendant order.
+		majorTickValues: null,
+		// minorTickCount: Array
+		//		The number of minor ticks between two contiguous major ticks.
+		//		The default value is 4.
+		minorTickCount: 4,
+		// majorTicks:
+		//		The array of generated major ticks. You should not set this
+		//		property when using the scaler.
+		majorTicks: null,
+		// minorTicks:
+		//		The array of generated minor ticks. You should not set this
+		//		property when using the scaler.
+		minorTicks: null,
+		_snapIntervalPrecision: null,
+		_snapCount: 4,
+		_snapIntervalPrecision: 6,
+		
+		constructor: function(){
+			this.watchedProperties = ["majorTickValues", "snapCount", "minorTickCount"];
+		},
+				
+		computeTicks: function(){
+			// summary:
+			//		Creates or re-creates the ticks for this scaler.
+			// returns: Array
+			//		An array containing all ticks (major then minor ticks).			
+			this.majorTicks = [];
+			this.minorTicks = [];
+			var ti;
+			var step = 1 / (this.majorTickValues.length - 1);
+			var minorStep = step / (this.minorTickCount + 1);
+			var currentIndex = 0;
+			var minorInterval;
+			var currentMajorValue;
+			var v;
+			for(var i = 0; i < this.majorTickValues.length; i++){
+				v = this.majorTickValues[i];
+				ti = {scaler: this};
+				ti.position = currentIndex * step;
+				ti.value = v;
+				ti.isMinor = false;
+				this.majorTicks.push(ti);
+				if(currentIndex < this.majorTickValues.length - 1){
+					currentMajorValue = Number(v);
+					minorInterval = (Number(this.majorTickValues[i + 1]) - currentMajorValue) / (this.minorTickCount + 1);
+					for(var j = 1; j <= this.minorTickCount; j++){
+						ti = {scaler: this};
+						ti.isMinor = true;
+						ti.position = currentIndex * step + j * minorStep;
+						ti.value = currentMajorValue + minorInterval * j;
+						this.minorTicks.push(ti);
+					}
+				}
+				currentIndex++;
+			}
+			return this.majorTicks.concat(this.minorTicks);
+		},
+		
+		positionForValue: function(value){
+			// summary:
+			//		Transforms a value into a relative position between 0 and 1.
+			// value: Number
+			//		A value to transform.
+			// returns: Number
+			//		The position between 0 and 1.			
+			if(!this.majorTickValues){
+				return 0;
+			}
+			
+			if(!this.majorTicks){
+				this.computeTicks();
+			}
+			
+			var minmax = this._getMinMax(value);
+			var position = (value - minmax[0].value) / (minmax[1].value - minmax[0].value);
+			return minmax[0].position + position * (minmax[1].position - minmax[0].position);
+		},
+		
+		valueForPosition: function(position){
+			// summary:
+			//		Transforms a relative position (between 0 and 1) into a value.
+			// position: Number
+			//		A relative position to transform.
+			// returns: Number
+			//		The transformed value.
+			if(this.majorTicks == null){
+				return 0;
+			}
+			var minmax = this._getMinMax(position, "position");
+			var value = (position - minmax[0].position) / (minmax[1].position - minmax[0].position);
+			return minmax[0].value + value * (minmax[1].value - minmax[0].value);
+		},
+		
+		_getMinMax: function(v, property){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(!property){
+				property = "value";
+			}
+			var res = [];
+			var pre;
+			var post;
+			var left = 0;
+			var right = this.majorTicks.length - 1;
+			var center;
+			
+			if(v <= this.majorTicks[0][property] || v >= this.majorTicks[right][property]){
+				res[0] = this.majorTicks[0];
+				res[1] = this.majorTicks[right];
+				return res;
+			}
+			
+			while (true){
+				center = Math.floor((left + right) / 2);
+				
+				if(this.majorTicks[center][property] <= v){
+					if(this.majorTicks[center + 1][property] >= v){
+						res[0] = this.majorTicks[center];
+						res[1] = this.majorTicks[center + 1];
+						return res;
+					}else{
+						left = center + 1;
+						continue;
+					}
+				}else{
+					right = center;
+					continue;
+				}
+			}
+		}
+	});
+});
diff --git a/dojox/dgauges/README b/dojox/dgauges/README
new file mode 100755
index 0000000..196f33b
--- /dev/null
+++ b/dojox/dgauges/README
@@ -0,0 +1,22 @@
+-------------------------------------------------------------------------------
+dojox.dgauges
+-------------------------------------------------------------------------------
+Project state: stable
+-------------------------------------------------------------------------------
+Credits:
+	Damien Mandrioli
+	Philippe Toussaint
+	Romain Raugi
+	Emmanuel Tissandier
+	Christophe Jolif
+	Eric Durocher
+-------------------------------------------------------------------------------
+Project description:
+Gauges framework for Dojo 1.8+
+-------------------------------------------------------------------------------
+Dependencies:
+Dojo Core, Dijit, dojox.color, dojox.widget, dojox.gfx
+-------------------------------------------------------------------------------
+Documentation:
+    http://docs.dojocampus.org/dojox/dgauges
+-------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/dojox/dgauges/RectangularGauge.js b/dojox/dgauges/RectangularGauge.js
new file mode 100755
index 0000000..5cb3e5a
--- /dev/null
+++ b/dojox/dgauges/RectangularGauge.js
@@ -0,0 +1,208 @@
+define(["dojo/_base/declare", "./GaugeBase", "dojox/gfx/matrix"], function(declare, GaugeBase, matrix){
+	return declare("dojox.dgauges.RectangularGauge", GaugeBase, {
+		// summary:
+		//		The base class for rectangular gauges.
+		//		You can create custom horizontal or vertical gauges by extending this class.
+		//		See dojox/dgauges/components/default/HorinzontalLinearGauge.js for an example of rectangular gauge.
+
+		// orientation: "horizontal"|"vertical"
+		//		The orientation of the gauge. Default is "horizontal".	
+		orientation: "horizontal",
+		
+		// leading, middle and trailing graphical parts
+		_middleParts: null,
+		_leadingParts: null,
+		_trailingParts: null,
+		_baseParts: null,
+		_classParts: null,
+		_layoutInfos: {},
+		constructor: function(){
+		
+			this.orientation = "horizontal";
+			
+			this._middleParts = [];
+			this._leadingParts = [];
+			this._trailingParts = [];
+			this._baseParts = [];
+			this._classParts = [];
+			
+			this._layoutInfos = {
+				leading: {
+					x: 0,
+					y: 0,
+					w: 0,
+					h: 0
+				},
+				middle: {
+					x: 0,
+					y: 0,
+					w: 0,
+					h: 0
+				},
+				trailing: {
+					x: 0,
+					y: 0,
+					w: 0,
+					h: 0
+				}
+			};
+			this.addInvalidatingProperties(["orientation"]);
+			
+		},
+		
+		addElement: function(name, element, location){
+			// summary:
+			//		Adds a element to the gauge.
+			// name: String
+			//		The name of the element to be added.
+			// element: Object
+			//		This parameter can be:
+			//		- A function which takes on argument of type GFX Group and return null or a
+			//		GFX element retrievable using the getElementRenderer() method.
+			//		- A Scale instance, i.e. CircularScale or RectangularScale.
+			//		- A TextIndicator instance.
+			// location: String
+			//		The area to place the element. Valid values are "leading"|"middle"|"trailing". Leading and trailing areas are fixed size. The
+			//		middle area use the remaining size. If not specified, the element's refreshRendering 
+			//		is called with the whole gauge size as argument.
+
+			this.inherited(arguments);
+			
+			var obj = this._elements[this._elements.length - 1];
+			
+			if(location == "middle"){
+				this._middleParts.push(obj);
+			}else if(location == "leading"){
+				this._leadingParts.push(obj);
+			}else if(location == "trailing"){
+				this._trailingParts.push(obj);
+			}else{
+				if(obj._isGFX){
+					this._baseParts.push(obj);
+				}else{
+					this._classParts.push(obj);
+				}
+			}
+		},
+		
+		removeElement: function(name){
+			// summary:
+			//		Remove the element defined by name from the gauge.
+			// name: String
+			//		The name of the element as defined using addElement.
+			// returns: Object
+			//		A reference to the removed element.		
+			var obj = this.getElement(name);
+			if(obj){
+				if(this._middleParts && this._middleParts.indexOf(obj) >= 0){
+					this._middleParts.splice(this._middleParts.indexOf(obj), 1);
+				}else if(this._leadingParts && this._leadingParts.indexOf(obj) >= 0){
+					this._leadingParts.splice(this._leadingParts.indexOf(obj), 1);
+				}else if(this._trailingParts && this._trailingParts.indexOf(obj) >= 0){
+					this._trailingParts.splice(this._trailingParts.indexOf(obj), 1);
+				}else if(this._baseParts && this._baseParts.indexOf(obj) >= 0){
+					this._baseParts.splice(this._baseParts.indexOf(obj), 1);
+				}else if(this._classParts && this._classParts.indexOf(obj) >= 0){
+					this._classParts.splice(this._classParts.indexOf(obj), 1);
+				}
+			}
+			
+			this.inherited(arguments);
+		},
+		
+		_computeArrayBoundingBox: function(elements){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(elements.length == 0){
+				return {x: 0, y: 0, w: 0, h: 0};
+			}
+			var bbox = null;
+			var minX, minY, maxX, maxY;
+			minX = minY = +Infinity;
+			maxX = maxY = -Infinity;
+			for(var i = 0; i < elements.length; i++){
+				bbox = this._computeBoundingBox(elements[i]._gfxGroup);
+				if(minX > bbox.x){
+					minX = bbox.x;
+				}
+				if(minY > bbox.y){
+					minY = bbox.y;
+				}
+				if(maxX < bbox.x + bbox.width){
+					maxX = bbox.x + bbox.width;
+				}
+				if(maxY < bbox.y + bbox.height){
+					maxY = bbox.y + bbox.height;
+				}
+			}
+			return {x: minX, y:minY, w: maxX-minX, h: maxY-minY};
+		},
+		
+		refreshRendering: function(){
+			if(this._widgetBox.w <= 0 || this._widgetBox.h <= 0){
+				return;
+			}
+			var i;
+			if(this._baseParts){
+				for(i = 0; i < this._baseParts.length; i++){
+					this._baseParts[i].width = this._widgetBox.w;
+					this._baseParts[i].height = this._widgetBox.h;
+					this._elementsRenderers[this._baseParts[i]._name] = this._baseParts[i].refreshRendering();
+				}
+			}
+			
+			if(this._leadingParts){
+				for(i = 0; i < this._leadingParts.length; i++){
+					this._elementsRenderers[this._leadingParts[i]._name] = this._leadingParts[i].refreshRendering();
+				}
+			}
+			
+			if(this._trailingParts){
+				for(i = 0; i < this._trailingParts.length; i++){
+					this._elementsRenderers[this._trailingParts[i]._name] = this._trailingParts[i].refreshRendering();
+				}
+			}
+			
+			var leadingBoundingBox = this._computeArrayBoundingBox(this._leadingParts);
+			var trailingBoundingBox = this._computeArrayBoundingBox(this._trailingParts);
+			var middleBoundingBox = {};
+			
+			if(this.orientation == "horizontal"){
+				middleBoundingBox.x = leadingBoundingBox.x + leadingBoundingBox.w;
+				middleBoundingBox.y = 0;
+				middleBoundingBox.w = this._widgetBox.w - leadingBoundingBox.w - trailingBoundingBox.w;
+				middleBoundingBox.h = this._widgetBox.h;
+			}else{
+				middleBoundingBox.x = 0;
+				middleBoundingBox.y = leadingBoundingBox.y + leadingBoundingBox.h;
+				middleBoundingBox.w = this._widgetBox.w; 
+				middleBoundingBox.h = this._widgetBox.h - leadingBoundingBox.h - trailingBoundingBox.h;
+			}
+			
+			this._layoutInfos = {
+				leading: leadingBoundingBox,
+				middle: middleBoundingBox,
+				trailing: trailingBoundingBox
+			};
+			
+			// translates middle part
+			for(i = 0; i < this._middleParts.length; i++){
+				this._middleParts[i]._gfxGroup.setTransform([matrix.translate(middleBoundingBox.x, middleBoundingBox.y)]);
+			}
+			
+			// translates trailing part
+			if(this._trailingParts){
+				for(i = 0; i < this._trailingParts.length; i++){
+					this._trailingParts[i]._gfxGroup.setTransform(matrix.translate(this._widgetBox.w - trailingBoundingBox.w, 0));
+				}
+			}
+			
+			// Render remaining elements (scales, ...)
+			for(i = 0; i < this._classParts.length; i++){
+				this._elementsRenderers[this._classParts[i]._name] = this._classParts[i].refreshRendering();
+			}
+		}
+	})
+});
diff --git a/dojox/dgauges/RectangularRangeIndicator.js b/dojox/dgauges/RectangularRangeIndicator.js
new file mode 100755
index 0000000..73c53f9
--- /dev/null
+++ b/dojox/dgauges/RectangularRangeIndicator.js
@@ -0,0 +1,146 @@
+define(["dojo/_base/declare", "dojox/gfx", "./ScaleIndicatorBase", "dojo/_base/event", "dojo/dom-geometry"],
+	function(declare, gfx, ScaleIndicatorBase, eventUtil, domGeom){
+	return declare("dojox.dgauges.RectangularRangeIndicator", ScaleIndicatorBase, {
+		// summary:
+		//		A RectangularRangeIndicator is used to represent a range of values on a scale.
+		//		For adding this kind of indicator instance to the gauge, use the addIndicator 
+		//		method of RectangularScale.
+
+		// start: Number
+		//		The start value of the range. Default is 0.
+		start: 0,
+		// startThickness: Number
+		//		The thickness in pixels of the shape at the position defined by the start property.
+		//		Default is 10.
+		startThickness: 10,
+		// endThickness: Number
+		//		The thickness in pixels of the shape at the position defined by the value property.
+		//		Default is 10.
+		endThickness: 10,
+		// fill: Object
+		//		A fill object that will be passed to the setFill method of GFX.
+		fill: null,
+		// stroke: Object
+		//		A stroke object that will be passed to the setStroke method of GFX.
+		stroke: null,
+		// paddingLeft: Number
+		//		The left padding. Not used for horizontal gauges.
+		paddingLeft: 10,
+		// paddingTop: Number
+		//		The top padding. Not used for vertical gauges.
+		paddingTop: 10,
+		// paddingRight: Number
+		//		The right padding. Not used for horizontal gauges.
+		paddingRight: 10,
+		// paddingBottom: Number
+		//		The bottom padding. Not used for vertical gauges.
+		paddingBottom: 10,
+		
+		constructor: function(){
+			this.fill = [255, 120, 0];
+			this.stroke = {
+				color: "black",
+				width: .2
+			};
+			this.interactionMode = "none";
+			
+			this.addInvalidatingProperties(["start", "startThickness", "endThickness", "fill", "stroke"]);
+		},
+
+		_defaultHorizontalShapeFunc: function(indicator, group, scale, startX, startY, endPosition, startThickness, endThickness, fill, stroke){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var gp = [startX, startY, endPosition, startY, endPosition, startY + endThickness, startX, startY + startThickness, startX, startY]
+			if(fill && fill.colors){
+				// Configure gradient
+				fill.x1 = startX;
+				fill.y1 = startY;
+				fill.x2 = endPosition;
+				fill.y2 = startY;
+			}
+			return group.createPolyline(gp).setFill(fill).setStroke(stroke);
+		},
+
+		_defaultVerticalShapeFunc: function(indicator, group, scale, startX, startY, endPosition, startThickness, endThickness, fill, stroke){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var gp = [startX, startY, startX, endPosition, startX + endThickness, endPosition, startX + startThickness, startY, startX, startY]
+			if(fill && fill.colors){
+				// Configure gradient
+				fill.x1 = startX;
+				fill.y1 = startY;
+				fill.x2 = startX;
+				fill.y2 = endPosition;
+			}
+			return group.createPolyline(gp).setFill(fill).setStroke(stroke);
+		},
+				
+		_shapeFunc: function(indicator, group, scale, startX, startY, endPosition, startThickness, endThickness, fill, stroke){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(this.scale._gauge.orientation == "horizontal"){
+				this._defaultHorizontalShapeFunc(indicator, group, scale, startX, startY, endPosition, startThickness, endThickness, fill, stroke);
+			}else{
+				this._defaultVerticalShapeFunc(indicator, group, scale, startX, startY, endPosition, startThickness, endThickness, fill, stroke);
+			}
+		},
+		
+		refreshRendering: function(){
+			this.inherited(arguments);
+			
+			if(this._gfxGroup == null || this.scale == null){
+				return;
+			}
+			// gets position corresponding to the values
+			var spos = this.scale.positionForValue(this.start);
+			var v = isNaN(this._transitionValue) ? this.value : this._transitionValue;
+			var pos = this.scale.positionForValue(v);
+			this._gfxGroup.clear();
+			
+			var startX;
+			var startY;
+			var endPosition;
+			if(this.scale._gauge.orientation == "horizontal"){
+				startX = spos;
+				startY = this.paddingTop;
+				endPosition = pos;
+			}else{
+				startX = this.paddingLeft;
+				startY = spos;
+				endPosition = pos;
+			}
+			this._shapeFunc(this, this._gfxGroup, this.scale, startX, startY, endPosition, this.startThickness, this.endThickness, this.fill, this.stroke);
+		},
+
+		_onMouseDown: function(event){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this.inherited(arguments);
+
+			var np = domGeom.position(this.scale._gauge.domNode, true);
+			this.set("value", this.scale.valueForPosition({x: event.pageX - np.x, y: event.pageY - np.y}));
+
+			// prevent the browser from selecting text
+			eventUtil.stop(event);
+		},
+		
+		_onMouseMove: function(event){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			
+			var np = domGeom.position(this.scale._gauge.domNode, true);
+			this.set("value", this.scale.valueForPosition({x: event.pageX - np.x, y: event.pageY - np.y}));
+		}
+	})
+});
diff --git a/dojox/dgauges/RectangularScale.js b/dojox/dgauges/RectangularScale.js
new file mode 100755
index 0000000..2e313b7
--- /dev/null
+++ b/dojox/dgauges/RectangularScale.js
@@ -0,0 +1,176 @@
+define(["dojo/_base/declare", "dojox/gfx", "./ScaleBase"], function(declare, gfx, ScaleBase){
+	return declare("dojox.dgauges.RectangularScale", ScaleBase, {
+		// summary:
+		//		The rectangular scale. A scaler must be set to use this class.
+
+		// paddingLeft: Number
+		//		The left padding.
+		paddingLeft: 15,
+		// paddingTop: Number
+		//		The top padding.
+		paddingTop: 12,
+		// paddingRight: Number
+		//		The right padding.
+		paddingRight: 15,
+		// paddingBottom: Number
+		//		The bottom padding.
+		paddingBottom: 0,
+		_contentBox: null,		
+		constructor: function(){
+			this.labelPosition = "leading";
+			this.addInvalidatingProperties(["paddingTop", "paddingLeft", "paddingRight", "paddingBottom"]);
+		},
+		
+		positionForValue: function(value){
+			// summary:
+			//		Transforms a value into a position using the associated scaler.
+			// value:
+			//		The value to transform.
+			// returns: Number
+			//		A position in pixels.
+			var relativePos = 0;
+			var position;
+			var spos = 0;
+			var length = 0;
+			if(this._contentBox){
+				if(this._gauge.orientation == "horizontal"){
+					spos = this._contentBox.x;
+					length = this._contentBox.w;
+				}else{
+					spos = this._contentBox.y;
+					length = this._contentBox.h;
+				}
+			}
+			relativePos = this.scaler.positionForValue(value);
+			position = spos + (relativePos * length);
+			return position;
+		},
+		
+		valueForPosition: function(pos){
+			// summary:
+			//		Transforms a position in pixels into a value using the associated scaler.
+			// pos:
+			//		The position to transform.
+			// returns: Number
+			//		The value represented by pos. 
+			var value = this.scaler.minimum;
+			var position = NaN;
+			var spos = 0;
+			var epos = 0;
+			
+			if(this._gauge.orientation == "horizontal"){
+				position = pos.x;
+				spos = this._contentBox.x;
+				epos = this._contentBox.x + this._contentBox.w;
+			}else{
+				position = pos.y;
+				spos = this._contentBox.y;
+				epos = this._contentBox.y + this._contentBox.h;
+			}
+			
+			if(position <= spos){
+				value = this.scaler.minimum;
+			}else if(position >= epos){
+				value = this.scaler.maximum;
+			}else {
+				value = this.scaler.valueForPosition((position - spos)/(epos - spos));
+			}
+			return value;
+			
+		},
+		
+		refreshRendering: function(){
+			this.inherited(arguments);
+			if(!this._gfxGroup || !this.scaler) 
+				return;
+			
+			this._ticksGroup.clear();
+			
+			// variables for ticks rendering
+			var middleBox = this._gauge._layoutInfos.middle;
+			
+			this._contentBox = {};
+			
+			this._contentBox.x = middleBox.x + this.paddingLeft;
+			this._contentBox.y = middleBox.y + this.paddingTop;
+			this._contentBox.w = middleBox.w - (this.paddingLeft + this.paddingRight);
+			this._contentBox.h = middleBox.h - (this.paddingBottom + this.paddingTop);
+			var renderer;
+			
+			// variables for tick labels
+			var labelText;
+			var font = this._getFont();
+			
+			// Layout ticks
+			var allTicks = this.scaler.computeTicks();
+			
+			for(var i = 0; i < allTicks.length; i++){
+				var tickItem = allTicks[i];
+				renderer = this.tickShapeFunc(this._ticksGroup, this, tickItem);
+				
+				if(renderer){
+					var a = this.positionForValue(tickItem.value);
+					var tickSize = this._gauge._computeBoundingBox(renderer).width;
+					
+					var x1 = 0, y1 = 0, angle = 0;
+					if(this._gauge.orientation == "horizontal"){
+						x1 = a;
+						y1 = this._contentBox.y;
+						angle = 90;
+					}else{
+						x1 = this._contentBox.x;
+						y1 = a;
+					}
+					
+					renderer.setTransform([{
+						dx: x1,
+						dy: y1
+					}, gfx.matrix.rotateg(angle)]);
+				}
+				
+				labelText = this.tickLabelFunc(tickItem);
+				
+				if(labelText){
+					var tbox = gfx._base._getTextBox(labelText, {
+						font: gfx.makeFontString(gfx.makeParameters(gfx.defaultFont, font))
+					});
+					var tw = tbox.w;
+					var th = tbox.h;
+					var al = "start";
+					var xt = x1;
+					var yt = y1;
+					
+					if(this._gauge.orientation == "horizontal"){
+						xt = x1;
+						if(this.labelPosition == "trailing"){
+							yt = y1 + tickSize + this.labelGap + th;
+						}else{
+							yt = y1 - this.labelGap;
+						}
+						al = "middle";
+					}else{
+						if(this.labelPosition == "trailing"){
+							xt = x1 + tickSize + this.labelGap;
+						}else{
+							xt = x1 - this.labelGap - tw;
+						}
+						yt = y1 + th / 2;
+					}
+					
+					var t = this._ticksGroup.createText({
+						x: xt,
+						y: yt,
+						text: labelText,
+						align: al
+					});
+					t.setFill(font.color ? font.color : "black");
+					t.setFont(font);
+				}
+			}
+			
+			for(var key in this._indicatorsIndex){
+				this._indicatorsRenderers[key] = this._indicatorsIndex[key].invalidateRendering();
+			}
+		}
+	})
+});
diff --git a/dojox/dgauges/RectangularSegmentedRangeIndicator.js b/dojox/dgauges/RectangularSegmentedRangeIndicator.js
new file mode 100755
index 0000000..0c9ad74
--- /dev/null
+++ b/dojox/dgauges/RectangularSegmentedRangeIndicator.js
@@ -0,0 +1,268 @@
+define(["dojo/_base/declare", "dojo/on", "dojox/gfx", "./IndicatorBase"], function(declare, on, gfx, IndicatorBase){
+	return declare("dojox.dgauges.RectangularSegmentedRangeIndicator", IndicatorBase, {
+		// summary:
+		//		A segmented-style range indicator for rectangular gauges.
+		//		This class will be replaced by a cleaner implementation in a future version.
+		
+		start: 0,
+		startThickness: 10,
+		endThickness: 10,
+		fill: null,
+		stroke: null,
+		paddingLeft: 0,
+		paddingTop: 0,
+		paddingRight: 0,
+		paddingBottom: 0,
+		
+		// segments: Number
+		//		The number of segments making the indicator.
+		//		By default it is 10.
+		segments: 10,
+
+		// segmentSpacing: Number
+		//		The blank space between two segments. The default value is 2
+		segmentSpacing: 2,
+		
+		// rounded: Boolean
+		//		Indicates if the extremity segments are rounded.
+		//		Default is true.		
+		rounded: true,
+		
+		// ranges: Array
+		//		An array containing objects to define color ranges. Example [{color:"#FF0000", size:20}, {color:"#FF8800", size:50}].
+		ranges: null,
+		
+		constructor: function(){
+			// summary:
+			//		Constructor.
+			// description:
+			//		Creates a segmented range indicator.
+			this.fill = [255, 120, 0];
+			this.stroke = {
+				color: "black",
+				width: .2
+			};
+			
+			this.addInvalidatingProperties(["start", "startThickness", "endThickness", "fill", "stroke","segments","segmentSpacing","ranges"]);
+		},
+
+		_defaultHorizontalShapeFunc: function(indicator, group, scale, startX, startY, endPosition, startThickness, endThickness, fill, stroke){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var length = scale._contentBox.w ;
+			var shape, i, gp, radius;
+			
+			if(this.ranges){
+				// Configure gradient to represent the ranges
+				fill = {type:"linear", colors:[]};
+				fill.x1 = startX;
+				fill.y1 = startY;
+				fill.x2 = startX + length;
+				fill.y2 = startY;
+				
+				var rangeStart = this.start;
+				
+				for(i = 0; i < this.ranges.length; i++){
+					var entry1 = {
+						color:this.ranges[i].color,
+						offset: scale.scaler.positionForValue(rangeStart)
+					};
+					var entry2 = {
+						color:this.ranges[i].color,
+						offset: scale.scaler.positionForValue(rangeStart+this.ranges[i].size)
+					};
+					fill.colors.push(entry1);
+					fill.colors.push(entry2);
+					rangeStart += this.ranges[i].size;
+				}
+			}else if(fill && fill.colors){
+				// Configure gradient
+				fill.x1 = startX;
+				fill.y1 = startY;
+				fill.x2 = startX + length;
+				fill.y2 = startY;
+			}
+			
+			var x = startX;
+			var y = startY;
+			var chicklet = (length / this.segments) - this.segmentSpacing;
+			var visibleSegments = Math.abs( (endPosition - startX) / (chicklet+this.segmentSpacing) );
+			var sw = this.startThickness;
+			var inc = (this.endThickness - this.startThickness) /this.segments
+			var ew = sw+inc;			
+			var remain = visibleSegments - Math.floor(visibleSegments);
+			
+			for(i = 0; i < Math.floor(visibleSegments); i++){
+				var path = group.createPath();
+				
+				if(i == 0 && this.rounded && (sw/2) < chicklet){ // first segment rounded
+					radius = sw/2;
+					path.moveTo(x + radius, y);
+					path.lineTo(x + chicklet, y);
+					path.lineTo(x + chicklet, y + ew);
+					path.lineTo(x + radius, y + sw);
+					path.arcTo(radius, radius, 0, 0, 1, x + radius, y)
+				}else{
+					if(i == Math.floor(visibleSegments) - 1 && (remain == 0) && this.rounded && (ew/2) < chicklet){ // last segment rounded
+						radius = ew/2;
+						path.moveTo(x, y);
+						path.lineTo(x + chicklet - radius, y);
+						path.arcTo(radius, radius, 0, 0, 1, x + chicklet - radius, y + ew)
+						path.lineTo(x, y + sw);
+						path.lineTo(x, y);
+					}else{
+						path.moveTo(x, y);
+						path.lineTo(x + chicklet, y);
+						path.lineTo(x + chicklet, y + ew);
+						path.lineTo(x, y + sw);
+						path.lineTo(x, y);
+					}
+				}
+				
+				path.setFill(fill).setStroke(stroke);
+				sw = ew;
+				ew += inc;
+				x += chicklet + this.segmentSpacing;
+			}
+			
+			// draw the remaining segment part
+			if(remain > 0){
+				ew = sw+( (ew-sw)*remain );
+				gp = [x, y, x+(chicklet*remain), y, x+(chicklet*remain), y  + ew, x, y + sw, x, y]
+				shape = group.createPolyline(gp).setFill(fill).setStroke(stroke);
+			}
+			
+			return shape;
+		},
+
+		_defaultVerticalShapeFunc: function(indicator, group, scale, startX, startY, endPosition, startThickness, endThickness, fill, stroke){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var length = scale._contentBox.h ;
+			var shape, i,gp,radius;
+			if(this.ranges){
+				// Configure gradient to represent the ranges
+				fill = {type:"linear", colors:[]};				
+				fill.x1 = startX;
+				fill.y1 = startY;
+				fill.x2 = startX;
+				fill.y2 = startY + length;
+				
+				var rangeStart = 0;
+				
+				for(i = 0; i < this.ranges.length; i++){
+					var entry1 = {
+						color:this.ranges[i].color,
+						offset: scale.scaler.positionForValue(rangeStart)
+					};
+					var entry2 = {
+						color:this.ranges[i].color,
+						offset: scale.scaler.positionForValue(rangeStart+this.ranges[i].size)
+					};
+					fill.colors.push(entry1);
+					fill.colors.push(entry2);
+					rangeStart += this.ranges[i].size
+				}
+			}else if(fill && fill.colors){
+				// Configure gradient
+				fill.x1 = startX;
+				fill.y1 = startY;
+				fill.x2 = startX;
+				fill.y2 = startY + length;
+			}
+			
+			var x = startX;
+			var y = startY;
+			var chicklet = (length / this.segments) - this.segmentSpacing;
+			var visibleSegments = Math.abs( (endPosition - startY) / (chicklet+this.segmentSpacing) );
+			var sw = this.startThickness;
+			var inc = (this.endThickness - this.startThickness) /this.segments
+			var ew = sw+inc;			
+			var remain = visibleSegments - Math.floor(visibleSegments);
+			
+			for(i = 0; i < Math.floor(visibleSegments); i++){
+				var path = group.createPath();
+				
+				if(i == 0 && this.rounded && (sw/2) < chicklet){ // first segment rounded
+					radius = sw/2;
+					path.moveTo(x , y+ radius);
+					path.lineTo(x , y+ chicklet);
+					path.lineTo(x + ew, y + chicklet);
+					path.lineTo(x + sw, y + radius);
+					path.arcTo(radius, radius, 0, 0, 0, x , y+ radius)
+				}else{
+					if(i == Math.floor(visibleSegments) - 1 && (remain == 0) && this.rounded && (ew/2) < chicklet){ // last segment rounded
+						radius = ew/2;
+						path.moveTo(x, y);
+						path.lineTo(x , y+ chicklet - radius);
+						path.arcTo(radius, radius, 0, 0, 0, x + ew, y + chicklet - radius)
+						path.lineTo(x+ sw, y );
+						path.lineTo(x, y);
+					}else{
+						path.moveTo(x, y);
+						path.lineTo(x , y+ chicklet);
+						path.lineTo(x + ew, y + chicklet);
+						path.lineTo(x+ sw, y );
+						path.lineTo(x, y);
+					}
+				}
+
+				path.setFill(fill).setStroke(stroke);
+				sw = ew;
+				ew += inc;
+				y += chicklet + this.segmentSpacing;
+			}
+			
+			// draw the remaining segment part
+			if(remain > 0){
+				ew = sw+( (ew-sw)*remain );
+				gp = [x, y, x, y+(chicklet*remain), x+ ew, y+(chicklet*remain), x+ sw, y , x, y];
+				shape = group.createPolyline(gp).setFill(fill).setStroke(stroke);
+			}
+			
+			return shape;
+		},
+				
+		indicatorShapeFunc: function(group, indicator, startX, startY, endPosition, startThickness, endThickness, fill, stroke){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			
+			if(indicator.scale._gauge.orientation == "horizontal"){
+				this._defaultHorizontalShapeFunc(indicator, group, indicator.scale, startX, startY, endPosition, startThickness, endThickness, fill, stroke);
+			}else{
+				this._defaultVerticalShapeFunc(indicator, group, indicator.scale, startX, startY, endPosition, startThickness, endThickness, fill, stroke);
+			}
+		},
+		
+		refreshRendering: function(){
+		
+			if(this._gfxGroup == null || this.scale == null){
+				return;
+			}
+			// gets position corresponding to the values
+			var spos = this.scale.positionForValue(this.start);
+			var pos = this.scale.positionForValue(this.value);
+			this._gfxGroup.clear();
+			
+			var startX;
+			var startY;
+			var endPosition;
+			if(this.scale._gauge.orientation == "horizontal"){
+				startX = spos;
+				startY = this.paddingTop;
+				endPosition = pos;
+			}else{
+				startX = this.paddingLeft;
+				startY = spos ;
+				endPosition = pos;			
+			}
+			this.indicatorShapeFunc(this._gfxGroup, this, startX, startY, endPosition, this.startThickness, this.endThickness, this.fill, this.stroke);
+		}
+	})
+});
diff --git a/dojox/dgauges/RectangularValueIndicator.js b/dojox/dgauges/RectangularValueIndicator.js
new file mode 100755
index 0000000..32c5fcc
--- /dev/null
+++ b/dojox/dgauges/RectangularValueIndicator.js
@@ -0,0 +1,92 @@
+define(["dojo/_base/declare", "./ScaleIndicatorBase", "dojox/gfx", "dojo/_base/event", "dojo/dom-geometry"],
+	function(declare, ScaleIndicatorBase, gfx, eventUtil, domGeom){
+	return declare("dojox.dgauges.RectangularValueIndicator", ScaleIndicatorBase, {
+		// summary:
+		//		The rectangular value indicator, typically used for creating markers or thumbs.
+
+		// paddingLeft: Number
+		//		The left padding.
+		paddingLeft: 0,
+		// paddingTop: Number
+		//		The top padding.
+		paddingTop: 0,
+		// paddingRight: Number
+		//		The right padding.
+		paddingRight: 0,
+		// paddingBottom: Number
+		//		The bottom padding.
+		paddingBottom: 0,
+
+		
+		constructor: function(){
+			this.addInvalidatingProperties(["paddingTop", "paddingLeft", "paddingRight", "paddingBottom"]);
+		},
+		
+		indicatorShapeFunc: function(group, indicator){
+			// summary:
+			//		Draws the indicator.
+			// group: dojox/gfx/Group
+			//		A GFX group for drawing. The indicator is always centered horizontally and is
+			//		automatically rotated if the scale is vertical.
+			// indicator: dojox/dgauges/IndicatorBase
+			//		A reference to this indicator.
+			// returns: dojox/gfx/shape.Shape
+			//		A GFX shape retrievable using the getIndicatorRenderer method of the associated scale. 
+			return group.createPolyline([0, 0, 10, 0, 0, 10, -10, 0, 0, 0]).setStroke({
+					color: "black",
+					width: 1
+				});
+		},
+				
+		refreshRendering: function(){
+			this.inherited(arguments);
+
+			// get position corresponding to the value
+			var v = isNaN(this._transitionValue) ? this.value : this._transitionValue;
+			var pos = this.scale.positionForValue(v);
+			
+			// computes offsets to move the indicator
+			var dx = 0, dy = 0;
+			var angle = 0;
+			if(this.scale._gauge.orientation == "horizontal"){
+				dx = pos;
+				dy = this.paddingTop;
+			}else{
+				dx = this.paddingLeft;
+				dy = pos;
+				angle = 90;
+			}
+			
+			// translate the indicator
+			
+			this._gfxGroup.setTransform([{
+				dx: dx,
+				dy: dy
+			}, gfx.matrix.rotateg(angle)]);
+		},
+		
+		_onMouseDown: function(event){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			var np = domGeom.position(this.scale._gauge.domNode, true);
+			this.set("value", this.scale.valueForPosition({x: event.pageX - np.x, y: event.pageY - np.y}));
+
+			// prevent the browser from selecting text
+			eventUtil.stop(event);
+		},
+		
+		_onMouseMove: function(event){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			
+			var np = domGeom.position(this.scale._gauge.domNode, true);
+			this.set("value", this.scale.valueForPosition({x: event.pageX - np.x, y: event.pageY - np.y}));
+		}
+	})
+});
diff --git a/dojox/dgauges/ScaleBase.js b/dojox/dgauges/ScaleBase.js
new file mode 100755
index 0000000..bfb348a
--- /dev/null
+++ b/dojox/dgauges/ScaleBase.js
@@ -0,0 +1,239 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojox/gfx", "dojo/_base/array", "dojox/widget/_Invalidating", "dojo/_base/sniff"],
+	function(lang, declare, gfx, array, _Invalidating, has){
+	return declare("dojox.dgauges.ScaleBase", _Invalidating, {
+		// summary:
+		//		The ScaleBase class is the base class for the circular and rectangular scales.
+		//		A scaler must be set to use this class. A scaler is responsible for
+		//		tick generation and various data-transform operations.	
+
+		// scaler: Object
+		//		The scaler used for tick generation and data-transform operations.
+		//		This property is mandatory for using the scale.
+		scaler: null,
+		// font: Object
+		//		The font used for the ticks labels.
+		//		This is null by default which means this scale use the font defined 
+		//		on the gauge.
+		font: null,
+		// labelPosition: String
+		//		See CircularScale and RectangularScale for valid values.
+		labelPosition: null,
+		// labelGap: Number
+		//		The label gap between the ticks and their labels. Default value is 1.
+		labelGap: 1,
+		// tickStroke: Object
+		//		The GFX stroke used by the default tickShapeFunc implementation.
+		tickStroke: null,
+		_gauge: null,
+		_gfxGroup: null,
+		_bgGroup: null,
+		_fgGroup: null,
+		_indicators: null,
+		_indicatorsIndex: null,
+		_indicatorsRenderers: null,
+		
+		constructor: function(){
+			this._indicators = [];
+			this._indicatorsIndex = {};
+			this._indicatorsRenderers = {};
+			this._gauge = null;
+			this._gfxGroup = null;
+			// Fix for #1, IE<9 don't render correctly stroke with width<1
+			this.tickStroke = {color: "black", width: has("ie") <= 8 ? 1 : 0.5};
+			
+			this.addInvalidatingProperties(["scaler", "font", "labelGap", "labelPosition", "tickShapeFunc", "tickLabelFunc", "tickStroke"]);
+			
+			this.watch("scaler", lang.hitch(this, this._watchScaler));
+		},
+
+		postscript: function(mixin){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			if(mixin && mixin.scaler){
+				this._watchScaler("scaler", null, mixin.scaler);
+			}
+		},
+		
+		_watchers: null,
+
+		_watchScaler: function(name, oldValue, newValue){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			array.forEach(this._watchers, lang.hitch(this, function(entry){
+				entry.unwatch();
+			}));
+
+			// Get the properties declared by the watched object
+			var props = newValue.watchedProperties;
+			this._watchers = [];
+			array.forEach(props, lang.hitch(this, function(entry){
+				this._watchers.push(newValue.watch(entry, lang.hitch(this, this.invalidateRendering)));
+			}));
+		},
+		
+		_getFont: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var font = this.font;
+			if(!font){
+				font = this._gauge.font;
+			}
+			if(!font){
+				font = gfx.defaultFont;
+			}
+			return font;
+		},
+		
+		positionForValue: function(value){
+			// summary:
+			//		See CircularScale and Rectangular for more informations.
+			// value: Number
+			//		The value to convert.
+			// returns: Number
+			//		The position corresponding to the value.
+			return 0;
+		},
+		
+		valueForPosition: function(position){
+			// summary:
+			//		See CircularScale and Rectangular for more informations.
+			// position: Number
+			//		The position to convert.
+			// returns: Number
+			//		The value corresponding to the position.
+		},
+		
+		tickLabelFunc: function(tickItem){
+			// summary:
+			//		Customize the text of ticks labels.
+			// tickItem: Object
+			//		An object containing the tick informations.
+			// returns: String
+			//		The text to be aligned with the tick. If null, the tick has no label.
+			if(tickItem.isMinor){
+				return null;
+			}else{
+				return String(tickItem.value);
+			}
+		},
+		
+		tickShapeFunc: function(group, scale, tickItem){
+			// summary:
+			//		Customize the shape of ticks.
+			// group: dojox/gfx/Group
+			//		The GFX group used for drawing the tick.
+			// scale: dojox/dgauges/ScaleBase
+			//		The scale being processed.
+			// tickItem: Object
+			//		An object containing the tick informations.
+			return group.createLine({
+				x1: 0,
+				y1: 0,
+				x2: tickItem.isMinor ? 6 : 10,
+				y2: 0
+			}).setStroke(this.tickStroke);
+		},
+		
+		getIndicatorRenderer: function(name){
+			// summary:
+			//		Gets the GFX shape of an indicator.
+			// name: String
+			//		The name of the indicator as defined using addIndicator.
+			// returns: dojox/gfx/canvas/Shape
+			//		The GFX shape of the indicator.
+			return this._indicatorsRenderers[name];
+		},
+		
+		removeIndicator: function(name){
+			// summary:
+			//		Removes an indicator.
+			// name: String
+			//		The name of the indicator as defined using addIndicator.
+			// returns: IndicatorBase
+			//		The removed indicator.
+			var indicator = this._indicatorsIndex[name];
+			if(indicator){
+				indicator._gfxGroup.removeShape();
+				var idx = this._indicators.indexOf(indicator);
+				this._indicators.splice(idx, 1);
+				
+				indicator._disconnectListeners();
+				
+				delete this._indicatorsIndex[name];
+				delete this._indicatorsRenderers[name];
+			}
+			if(this._gauge){
+				this._gauge._resetMainIndicator();
+			}
+			this.invalidateRendering();
+			return indicator;
+		},
+		
+		getIndicator: function(name){
+			// summary:
+			//		Get an indicator instance.
+			// name: String
+			//		The name of the indicator as defined using addIndicator.
+			// returns: IndicatorBase
+			//		The indicator associated with the name parameter.
+			return this._indicatorsIndex[name];
+		},
+		
+		addIndicator: function(name, indicator, behindScale){
+			// summary:
+			//		Add an indicator to the scale. Before calling this function, ensure 
+			//		this scale has already been added to a gauge using the addElement method
+			//		of the gauge.
+			// name: String
+			//		The name of the indicator to be added.
+			// indicator: dojox/dgauges/IndicatorBase
+			//		The indicator to add to this scale.
+			// behindScale: Boolean
+			//		If true, this indicator is drawn behind the scale. Default value is false.	
+			if(this._indicatorsIndex[name] && this._indicatorsIndex[name] != indicator){
+				this.removeIndicator(name);
+			}
+			
+			this._indicators.push(indicator);
+			this._indicatorsIndex[name] = indicator;
+			
+			if(!this._ticksGroup){
+				this._createSubGroups();
+			}
+			
+			var group = behindScale ? this._bgGroup : this._fgGroup;
+			indicator._gfxGroup = group.createGroup();
+			
+			indicator.scale = this;
+			
+			return this.invalidateRendering();
+		},
+		
+		_createSubGroups: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(!this._gfxGroup || this._ticksGroup){
+				return;
+			}
+			this._bgGroup = this._gfxGroup.createGroup();
+			this._ticksGroup = this._gfxGroup.createGroup();
+			this._fgGroup = this._gfxGroup.createGroup();
+		},
+		
+		refreshRendering: function(){
+			if(!this._ticksGroup){
+				this._createSubGroups();
+			}
+		}
+	});
+});
+
diff --git a/dojox/dgauges/ScaleIndicatorBase.js b/dojox/dgauges/ScaleIndicatorBase.js
new file mode 100755
index 0000000..417346a
--- /dev/null
+++ b/dojox/dgauges/ScaleIndicatorBase.js
@@ -0,0 +1,319 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window", "dojo/on", "dojo/touch", "dojo/_base/fx", "dojox/gfx", "dojox/widget/_Invalidating", "./IndicatorBase"],
+	function(lang, declare, win, on, touch, fx, gfx, _Invalidating, IndicatorBase){
+	return declare("dojox.dgauges.ScaleIndicatorBase", IndicatorBase, {
+		// summary:
+		//		The base class for indicators that rely on a scale for their rendering.
+		//		Typically, value indicators and range indicators are subclasses of ScaleIndicatorBase.
+
+		// summary:
+		//		The scale associated with this indicator.
+		scale: null,
+		// summary:
+		//		The value of the indicator. Default is 0.
+		value: 0,
+		
+		// interactionArea: String
+		//		How to interact with the indicator using mouse or touch interactions.
+		//		Can be "indicator", "gauge", "area" or "none". The default value is "gauge".
+		//		If set to "indicator", the indicator shape reacts to mouse and touch events.
+		//		If set to "gauge", the whole gauge reacts to mouse and touch events.
+		//		If set to "area", the whole bounding box of the widget reacts to mouse and touch events.
+		//		If "none", interactions are disabled.
+		interactionArea: "gauge",
+
+		// interactionMode: String
+		//		Deprecated. Can be "mouse" or "touch".
+		interactionMode: "mouse",
+
+		// animationDuration: Number
+		//		The duration of the value change animation in milliseconds. Default is 0.
+		//		The animation occurs on both user interactions and programmatic value changes.
+		//		Set this property to 0 to disable animation.
+		animationDuration: 0,
+
+		// animationEaser: Object
+		//		The easer function of the value change animation. Default is fx._defaultEasing.
+		animationEaser: null,
+
+		_indicatorShapeFuncFlag: true,
+		
+		_interactionAreaFlag: true,
+		
+		_downListeners: null,
+		
+		_cursorListeners: null,
+		
+		_moveAndUpListeners: null,
+		
+		_transitionValue: NaN,
+		
+		_preventAnimation: false,
+		
+		_animation: null,
+		
+		constructor: function(){
+		
+			// watches changed happening on the "value" property
+			this.watch("value", lang.hitch(this, function(){
+				this.valueChanged(this);
+			}));
+			this.watch("value", lang.hitch(this, this._startAnimation));
+			
+			this.watch("interactionArea", lang.hitch(this, function(){
+				this._interactionAreaFlag = true;
+			}));
+			this.watch("interactionMode", lang.hitch(this, function(){
+				this._interactionAreaFlag = true;
+			}));
+			
+			this.watch("indicatorShapeFunc", lang.hitch(this, function(){
+				this._indicatorShapeFuncFlag = true;
+			}));
+			
+			this.addInvalidatingProperties(["scale", "value", "indicatorShapeFunc", "interactionArea", "interactionMode"]);
+			
+			this._downListeners = [];
+			this._moveAndUpListeners = [];
+			this._cursorListeners = [];
+		},
+		
+		_startAnimation: function(prop, oldValue, newValue){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(this.animationDuration == 0){
+				return;
+			}
+			if(this._animation && (this._preventAnimation || oldValue == newValue)){
+				this._animation.stop();
+				return;
+			}
+			this._animation = new fx.Animation({curve: [oldValue, newValue], 
+										duration: this.animationDuration, 
+										easing: this.animationEaser ? this.animationEaser : fx._defaultEasing,
+										onAnimate: lang.hitch(this, this._updateAnimation),
+										onEnd: lang.hitch(this, this._endAnimation),
+										onStop: lang.hitch(this, this._endAnimation)});
+			
+			this._animation.play();
+		},
+		
+		_updateAnimation: function(v){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this._transitionValue = v;
+			this.invalidateRendering();
+		},
+		
+		_endAnimation: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this._transitionValue = NaN; 
+			this.invalidateRendering();			
+		},
+		
+		refreshRendering: function(){
+			if(this._gfxGroup == null || this.scale == null){
+				return;
+			}else{
+				if(this._indicatorShapeFuncFlag && lang.isFunction(this.indicatorShapeFunc)){
+					this._gfxGroup.clear();
+					this.indicatorShapeFunc(this._gfxGroup, this);
+					this._indicatorShapeFuncFlag = false;
+				}
+				
+				if(this._interactionAreaFlag){
+					this._interactionAreaFlag = this._connectDownListeners();
+				}
+			}
+		},
+		
+		valueChanged: function(indicator){
+			// summary:
+			//		Invoked when the value of the indicator changes.
+			//		User can connect an listener on this function: 
+			// |	theIndicator.on("valueChanged", lang.hitch(this, function(){
+			// |		//do something
+			// |	}));
+			on.emit(this, "valueChanged", {
+				target: this,
+				bubbles: true,
+				cancelable: true
+			});
+		},
+		
+		_disconnectDownListeners: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			for(var i = 0; i < this._downListeners.length; i++){
+				this._downListeners[i].remove();
+			}
+			this._downListeners = [];
+		},
+		
+		_disconnectMoveAndUpListeners: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			for(var i = 0; i < this._moveAndUpListeners.length; i++){
+				this._moveAndUpListeners[i].remove();
+			}
+			this._moveAndUpListeners = [];
+		},
+		
+		_disconnectListeners: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this._disconnectDownListeners();
+			this._disconnectMoveAndUpListeners();
+			this._disconnectCursorListeners();
+		},
+		
+		_connectCursorListeners: function(target){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var listener = target.on(touch.over , lang.hitch(this, function(){
+				this.scale._gauge._setCursor("pointer");
+			}));
+			this._cursorListeners.push(listener);
+			listener = target.on(touch.out, lang.hitch(this, function(event){
+					this.scale._gauge._setCursor("");
+				}
+			));
+			this._cursorListeners.push(listener);
+		},
+		
+		_disconnectCursorListeners: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			for(var i = 0; i < this._cursorListeners.length; i++){
+				this._cursorListeners[i].remove();
+			}
+			this._cursorListeners = [];
+		},
+
+		_connectDownListeners: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this._disconnectDownListeners();
+			this._disconnectCursorListeners();
+			var listener = null;
+
+			if(this.interactionMode == "mouse" || this.interactionMode == "touch"){
+				if(this.interactionArea == "indicator"){
+					listener = this._gfxGroup.on(touch.press, lang.hitch(this, this._onMouseDown));
+					this._downListeners.push(listener);
+					this._connectCursorListeners(this._gfxGroup);
+				}else if(this.interactionArea == "gauge"){
+					if(!this.scale || !this.scale._gauge || !this.scale._gauge._gfxGroup){
+						return true;
+					}
+					listener = this.scale._gauge._gfxGroup.on(touch.press, lang.hitch(this, this._onMouseDown));
+					this._downListeners.push(listener);
+					listener = this._gfxGroup.on(touch.press, lang.hitch(this, this._onMouseDown));
+					this._downListeners.push(listener);
+					this._connectCursorListeners(this.scale._gauge._gfxGroup);
+				}else if(this.interactionArea == "area"){
+					if(!this.scale || !this.scale._gauge || !this.scale._gauge._baseGroup){
+						return true;
+					}
+					listener = this.scale._gauge._baseGroup.on(touch.press, lang.hitch(this, this._onMouseDown));
+					this._downListeners.push(listener);
+					listener = this._gfxGroup.on(touch.press, lang.hitch(this, this._onMouseDown));
+					this._downListeners.push(listener);
+						this._connectCursorListeners(this.scale._gauge._baseGroup);
+				}
+			}
+			return false;
+		},
+		
+		_connectMoveAndUpListeners: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var listener = null;
+
+			listener = on(win.doc, touch.move, lang.hitch(this, this._onMouseMove));
+			this._moveAndUpListeners.push(listener);
+			
+			listener = on(win.doc, touch.release, lang.hitch(this, this._onMouseUp));
+			this._moveAndUpListeners.push(listener);
+		},
+
+		_onMouseDown: function(event){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this._connectMoveAndUpListeners();
+			this._startEditing();
+		},
+
+		_onMouseMove: function(event){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this._preventAnimation = true;
+			if(this._animation){
+				this._animation.stop();
+			}
+		},
+
+		_onMouseUp: function(event){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this._disconnectMoveAndUpListeners();
+			this._preventAnimation = false;
+			this._endEditing();
+		},
+
+		_startEditing: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(!this.scale || !this.scale._gauge){
+				return;
+			}else{
+				this.scale._gauge.onStartEditing({
+					indicator: this
+				});
+			}
+		},
+		
+		_endEditing: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(!this.scale || !this.scale._gauge){
+				return;
+			}else{
+				this.scale._gauge.onEndEditing({
+					indicator: this
+				});
+			}
+		}
+		
+	});
+});
diff --git a/dojox/dgauges/TextIndicator.js b/dojox/dgauges/TextIndicator.js
new file mode 100755
index 0000000..7850a79
--- /dev/null
+++ b/dojox/dgauges/TextIndicator.js
@@ -0,0 +1,144 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/sniff", "dojo/_base/array", "dojo/on", "dojox/gfx", "./IndicatorBase"],
+	function(lang, declare, has, array, on, gfx, IndicatorBase){
+	return declare("dojox.dgauges.TextIndicator", IndicatorBase, {
+		// summary:
+		//		This type of indicator is used to render text.
+		//		To render an arbitrary text, set the value property.
+		//		To render the value of a value indicator or a range indicator, set the indicator property.
+		//		Setting the indicator property takes precedence on setting the value property.
+		//		When the indicator property is set, the text is automatically updated on value changes.
+
+		// font: Object
+		//		Font used by this element.
+		font: null,
+		// x: Number
+		//		The text anchor x-position. Default is 0.
+		x: 0,
+		// y: Number
+		//		The text anchor y-position. Default is 0.
+		y: 0,
+		// align: String
+		//		An alignment of a text in regards to the anchor position:
+		//
+		//		- "start": A text's baseline starts at the anchor. 
+		//		This is the default value of the align attribute.
+		//		- "middle": A text's baseline is centered on the anchor point.
+		//		- "end": A text's baseline ends at the anchor point.
+		align: "middle",
+		// color: Object
+		//		The color of the text.
+		color: "black",
+		// indicator: dojox/dgauges/IndicatorBase
+		//		If this property is set, the value of the indicator is automatically
+		//		rendered by this text element.
+		indicator: null,
+		// labelFunc: Object
+		//		If set, this method allows to format the value of this text indicator.
+		//		A label function takes the text to render as argument and returns a String. 
+		labelFunc: null,
+		
+		constructor: function(){
+			this.addInvalidatingProperties(["indicator"]);
+
+			var resetProps = ["x", "y", "font", "align", "color", "labelFunc"];
+			array.forEach(resetProps, lang.hitch(this, function(entry){
+				this.watch(entry, this._resetText);
+			}));
+			
+			this.watch("indicator", lang.hitch(this, this._indicatorChanged));
+		},
+
+		postscript: function(mixin){
+			// summary:
+			//		Internal method
+			// tags:
+			//		private
+			this.inherited(arguments);
+			if(mixin && mixin.indicator){
+				this._indicatorChanged("indicator", null, mixin.indicator);
+			}
+		},
+		
+		_resetText: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			this._textCreated = false;
+			this.invalidateRendering();
+		},
+		
+		_valueWatcher: null,
+		
+		_indicatorChanged: function(name, oldValue, newValue){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(this._valueWatcher){
+				this._valueWatcher.unwatch();
+			}
+			this._valueWatcher = newValue.watch("value", lang.hitch(this, this.refreshRendering));
+		},
+		
+		_getFont: function(){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var font = this.font;
+			if(!font && this._gauge){
+				font = this._gauge.font;
+			}
+			if(!font){
+				font = gfx.defaultFont;
+			}
+			return font;
+		},
+		
+		_textCreated: false,
+		_textInstance: null,
+		
+		_createText: function(group, font, color, text, x, y, align){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			var gfxText = group.createText({
+				x: x,
+				y: y,
+				text: text,
+				align: align
+			}).setFont(font).setFill(color);
+			return gfxText;
+		},
+		
+		refreshRendering: function(){
+			if(this._gfxGroup == null){
+				return;
+			}
+			var text;
+			if(this.indicator){
+				text = this.indicator.value;
+			}else{
+				text = this.value;
+			}
+			if(this.labelFunc){
+				text = this.labelFunc(text);
+			}
+			var iOsVersion = has("iphone");
+			// Workaround for a bug on iOS version < 5.0: Recreate the text every times
+			if(!this._textCreated || (iOsVersion != undefined && iOsVersion < 5)){
+				this._gfxGroup.clear();
+				var font = this._getFont();
+				this._textInstance = this._createText(this._gfxGroup, font, font.color ? font.color : this.color, "", this.x, this.y, this.align);
+				this._textCreated = true;
+			}
+			this._textInstance.setShape({
+				text: text
+			});
+			
+			return this._textInstance;
+		}
+	})
+});
diff --git a/dojox/dgauges/_circularUtils.js b/dojox/dgauges/_circularUtils.js
new file mode 100755
index 0000000..361e0f0
--- /dev/null
+++ b/dojox/dgauges/_circularUtils.js
@@ -0,0 +1,91 @@
+define(function(){
+	// module:
+	//		dojox/dgauges/components/_circularUtils
+	// summary:
+	//		Internal circular utilities.
+	// tags:
+	//		private
+
+	return {
+		computeTotalAngle: function(start, end, orientation){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(start == end){
+				return 360;
+			}else{
+				return this.computeAngle(start, end, orientation, 360);
+			}
+		},
+		
+		modAngle: function(angle, base){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(base == undefined){
+				base = 6.28318530718;
+			}
+			if(angle >= base){
+				do {
+					angle -= base;
+				}
+				while (angle >= base);
+			}else{
+				while (angle < 0){
+					angle += base;
+				}
+			}
+			return angle;
+		},
+		
+		computeAngle: function(startAngle, endAngle, orientation, base){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			if(base == undefined){
+				base = 6.28318530718;
+			}
+			
+			var totalAngle;
+			
+			if(endAngle == startAngle){
+				return base;
+			}
+			
+			if(orientation == "clockwise"){
+				if(endAngle < startAngle){
+					totalAngle = base - (startAngle - endAngle);
+				}else{
+					totalAngle = endAngle - startAngle;
+				}
+			}
+			else{
+				if(endAngle < startAngle){
+					totalAngle = startAngle - endAngle;
+				}else{
+					totalAngle = base - (endAngle - startAngle);
+				}
+			}
+			return this.modAngle(totalAngle, base);
+		},
+		
+		toRadians: function(deg){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			return deg * Math.PI / 180;
+		},
+		
+		toDegrees: function(rad){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			return rad * 180 / Math.PI;
+		}
+	}
+});
diff --git a/dojox/dgauges/components/DefaultPropertiesMixin.js b/dojox/dgauges/components/DefaultPropertiesMixin.js
new file mode 100755
index 0000000..225043f
--- /dev/null
+++ b/dojox/dgauges/components/DefaultPropertiesMixin.js
@@ -0,0 +1,89 @@
+define(["dojo/_base/declare", "dojo/_base/Color"], function(declare, Color){
+	return declare("dojox.dgauges.components.DefaultPropertiesMixin", null, {
+		// summary:
+		//		This class defines default properties of predefined gauges.
+
+		// minimum: Number
+		//		The minimum value of the scaler. Default is 0.
+		minimum: 0,
+		// maximum: Number
+		//		The maximum value of the scaler. Default is 100.
+		maximum: 100,
+		// snapInterval:
+		//		Specifies the increment value to be used as snap values on this scale 
+		//		during user interaction.
+		//		Default is 1.
+		snapInterval: 1,
+		// majorTickInterval: Number
+		//		The interval between two major ticks.
+		majorTickInterval: NaN,
+		// minorTickInterval: Number
+		//		The interval between two minor ticks.
+		minorTickInterval: NaN,
+		// minorTicksEnabled: Boolean
+		//		If false, minor ticks are not generated. Default is true.
+		minorTicksEnabled: true,
+
+		// summary:
+		//		The value of the indicator. Default is 0.
+		value: 0,
+		
+		// interactionArea: String
+		//		How to interact with the indicator using mouse or touch interactions.
+		//		Can be "indicator", "gauge" or "none". The default value is "gauge".
+		//		If set to "indicator", the indicator shape reacts to mouse and touch events.
+		//		If set to "gauge", the whole gauge reacts to mouse and touch events.
+		//		If "none", interactions are disabled.
+		interactionArea: "gauge",
+
+		// interactionMode: String
+		//		Can be "mouse" or "touch".
+		interactionMode: "mouse",
+
+		// animationDuration: Number
+		//		The duration of the value change animation in milliseconds. Default is 0.
+		//		The animation occurs on both user interactions and programmatic value changes.
+		//		Set this property to 0 to disable animation.
+		animationDuration: 0,
+
+		_setMinimumAttr: function(v){
+			this.getElement("scale").scaler.set("minimum", v);
+		},
+		_setMaximumAttr: function(v){
+			this.getElement("scale").scaler.set("maximum", v);
+		},
+		_setSnapIntervalAttr: function(v){
+			this.getElement("scale").scaler.set("snapInterval", v);
+		},
+		_setMajorTickIntervalAttr: function(v){
+			this.getElement("scale").scaler.set("majorTickInterval", v);
+		},
+		_setMinorTickIntervalAttr: function(v){
+			this.getElement("scale").scaler.set("minorTickInterval", v);
+		},
+		_setMinorTicksEnabledAttr: function(v){
+			this.getElement("scale").scaler.set("minorTicksEnabled", v);
+		},
+		_setInteractionAreaAttr: function(v){
+			this.getElement("scale").getIndicator("indicator").set("interactionArea", v);
+		},
+		_setInteractionModeAttr: function(v){
+			this.getElement("scale").getIndicator("indicator").set("interactionMode", v);
+		},
+		_setAnimationDurationAttr: function(v){
+			this.getElement("scale").getIndicator("indicator").set("animationDuration", v);
+		},
+		_setBorderColorAttr: function(v){
+			this.borderColor = new Color(v);
+			this.invalidateRendering();
+		},
+		_setFillColorAttr: function(v){
+			this.fillColor = new Color(v);
+			this.invalidateRendering();
+		},
+		_setIndicatorColorAttr: function(v){
+			this.indicatorColor = new Color(v);
+			this.invalidateRendering();
+		}
+	});
+});
diff --git a/dojox/dgauges/components/black/CircularLinearGauge.js b/dojox/dgauges/components/black/CircularLinearGauge.js
new file mode 100755
index 0000000..35de2a4
--- /dev/null
+++ b/dojox/dgauges/components/black/CircularLinearGauge.js
@@ -0,0 +1,154 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare", 
+		"dojo/_base/Color", 
+		"../../CircularGauge", 
+		"../../LinearScaler", 
+		"../../CircularScale", 
+		"../../CircularValueIndicator", 
+		"../../CircularRangeIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, CircularRangeIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.black.CircularLinearGauge", [CircularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A circular gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#000000".
+			borderColor: "#000000",
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#000000".
+			fillColor: "#000000",
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#A4A4A4".
+			indicatorColor: "#A4A4A4",
+			constructor: function(){
+				// Base colors
+				this.borderColor = new Color(this.borderColor);
+				this.fillColor = new Color(this.fillColor);
+				this.indicatorColor = new Color(this.indicatorColor);
+				
+				var scaler = new LinearScaler();
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+				var scale = new CircularScale();
+				scale.set("scaler", scaler);
+				scale.set("radius", 149.82183);
+				scale.set("originX", 186.9446);
+				scale.set("originY", 184.74838);
+				scale.set("startAngle", 130.16044);
+				scale.set("endAngle", 50.25444);
+				scale.set("orientation", "clockwise");
+				scale.set("labelGap", 8);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "14pt",
+					color: "#CECECE"
+				});
+				scale.set("tickShapeFunc", function(group, scale, tick){
+					return group.createCircle({
+						r: tick.isMinor ? 2 : 4
+					}).setFill("#CECECE");
+				});
+				this.addElement("scale", scale);
+				var indicator = new CircularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+					
+					return group.createPolyline([0, -12, indicator.scale.radius - 2, 0, 0, 12, 0, -12]).setStroke({
+						color: [70, 70, 70],
+						width: 1
+					}).setFill(this.indicatorColor);
+
+				}));
+				scale.addIndicator("indicator", indicator);
+				this.addElement("foreground", lang.hitch(this, this.drawForeground));
+			},
+			drawBackground: function(g){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// tags:
+				//		protected
+				g.createPath({
+					path: "M372.9962 186.58 C373.0312 289.5712 289.57 373.0888 186.5787 373.1237 C83.5887 373.16 0.07 289.6975 0.035 186.7062 L0.035 186.58 C-0 83.5888 83.4625 0.0712 186.4524 0.0362 C289.4425 -0 372.9611 83.4625 372.9962 186.4525 L372.9962 186.58 Z"
+				}).setFill(this.borderColor);
+				g.createPath({
+					path: "M358.7902 186.5795 C358.8253 281.7258 281.7202 358.8808 186.574 358.9145 C91.4277 358.9471 14.2715 281.842 14.239 186.6957 L14.239 186.5795 C14.2077 91.4332 91.3127 14.2782 186.4565 14.2445 C281.6027 14.2132 358.759 91.317 358.7902 186.4633 L358.7902 186.5795 Z"
+				}).setFill({
+					type: "linear",
+					x1: 14.23897,
+					y1: 358.91452,
+					x2: 14.23897,
+					y2: 221.04652,
+					colors: [
+						{offset: 0, color: [100,100,100]},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g.createPath({
+					path: "M358.749 182.9033 C356.8202 89.4033 280.4165 14.2132 186.4615 14.2445 C92.5465 14.277 16.2165 89.4533 14.289 182.9008 C66.884 197.0646 127.4052 168.8146 188.7977 168.8146 C250.209 168.8146 306.3027 197.0708 358.749 182.9033"
+				}).setFill({
+					type: "linear",
+					x1: 14.28899,
+					y1: 186.87839,
+					x2: 14.28899,
+					y2: 14.24451,
+					colors: [
+						{offset: 0, color: this.fillColor},
+						{offset: 1, color: [200,200,200]}
+					]
+				});
+				g.createPath({
+					path: "M358.7457 182.9033 C356.817 89.4033 280.4132 14.2133 186.4582 14.2445 C92.5432 14.277 16.2132 89.4533 14.2857 182.9008 C66.8807 197.0646 127.402 168.8146 188.7945 168.8146 C250.2057 168.8146 306.2995 197.0708 358.7457 182.9033"
+				}).setFill([255,255,255,0.12157]);
+			},
+
+			drawForeground: function(g){
+				// summary:
+				//		Draws the foreground shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the foreground. 
+				// tags:
+				//		protected
+				var g1 = g.createGroup();
+				g1.createPath({
+					path: "M214.9859 185.33 C214.9909 201.0537 202.2496 213.8037 186.5259 213.81 C170.7996 213.815 158.0496 201.0725 158.0446 185.35 L158.0446 185.33 C158.0384 169.6062 170.7821 156.8562 186.5071 156.85 C202.2296 156.845 214.9809 169.5875 214.9859 185.3113 L214.9859 185.33 Z"
+				}).setFill(this.borderColor);
+				g1.createPath({
+					path: "M211.4015 185.3295 C211.4052 199.0745 200.2689 210.2183 186.524 210.2232 C172.7802 210.2282 161.6352 199.0908 161.6302 185.347 L161.6302 185.3295 C161.6252 171.5858 172.7628 160.4408 186.5065 160.4358 C200.2515 160.4308 211.3965 171.5695 211.4015 185.3133 L211.4015 185.3295 Z"
+				}).setFill({
+					type: "linear",
+					x1: 161.63024,
+					y1: 210.22326,
+					x2: 161.63024,
+					y2: 185.32952,
+					colors: [
+						{offset: 0, color: [100,100,100]},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g1.createPath({
+					path: "M211.3952 184.7995 C211.1165 171.2933 200.0802 160.4308 186.5077 160.4358 C172.9415 160.4408 161.9152 171.2995 161.6377 184.7995 C169.234 186.8446 177.9752 182.7645 186.8465 182.7645 C195.7165 182.7645 203.819 186.8458 211.3952 184.7995"
+				}).setFill({
+					type: "linear",
+					x1: 161.63772,
+					y1: 185.37364,
+					x2: 161.63772,
+					y2: 160.43577,
+					colors: [
+						{offset: 0, color: this.fillColor},
+						{offset: 1, color: [150,150,150]}
+					]
+				});
+				g1.createPath({
+					path: "M211.3946 184.799 C211.1158 171.2928 200.0796 160.4315 186.5084 160.4365 C172.9409 160.4415 161.9159 171.3003 161.6371 184.799 C169.2334 186.844 177.9759 182.764 186.8458 182.764 C195.7158 182.764 203.8184 186.8465 211.3946 184.799"
+				}).setFill([255,255,255,0.12157]);
+			}
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/black/HorizontalLinearGauge.js b/dojox/dgauges/components/black/HorizontalLinearGauge.js
new file mode 100755
index 0000000..952fcc4
--- /dev/null
+++ b/dojox/dgauges/components/black/HorizontalLinearGauge.js
@@ -0,0 +1,125 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../../RectangularGauge", 
+		"../../LinearScaler", 
+		"../../RectangularScale", 
+		"../../RectangularValueIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.black.HorizontalLinearGauge", [RectangularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A horizontal gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#000000".
+			borderColor: "#000000",
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#000000".
+			fillColor: "#000000",
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#A4A4A4".
+			indicatorColor: "#A4A4A4",
+			constructor: function(){
+				// Base colors
+				this.borderColor = new Color(this.borderColor);
+				this.fillColor = new Color(this.fillColor);
+				this.indicatorColor = new Color(this.indicatorColor);
+
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+
+				// Scaler
+				var scaler = new LinearScaler();
+				
+				// Scale
+				var scale = new RectangularScale();
+				scale.set("scaler", scaler);
+				scale.set("labelPosition", "leading");
+				scale.set("paddingLeft", 30);
+				scale.set("paddingRight", 30);
+				scale.set("paddingTop", 34);
+				scale.set("labelGap", 8);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "7pt",
+					color: "#CECECE"
+				});
+				scale.set("tickShapeFunc", function(group, scale, tick){
+					return group.createCircle({
+						r: tick.isMinor ? 0.5 : 3
+					}).setFill("#CECECE");
+				});
+				this.addElement("scale", scale);
+				
+				var indicator = new RectangularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("paddingTop", 30);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+					return group.createPolyline([0, 0, -10, -20, 10, -20, 0, 0]).setFill(this.indicatorColor).setStroke({
+						color: [70, 70, 70],
+						width: 1,
+						style: "Solid",
+						cap: "butt",
+						join: 20.0
+					});
+
+				}));
+				scale.addIndicator("indicator", indicator);
+			},
+
+			drawBackground: function(g, w, h){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// w: Number
+				//		The width of the gauge.
+				// h: Number
+				//		The height of the gauge.
+				// tags:
+				//		protected
+				g.createRect({
+					x: 0,
+					y: 0,
+					width: w,
+					height: 50,
+					r: 15
+				}).setFill(this.borderColor);
+				g.createRect({
+					x: 4,
+					y: 4,
+					width: w - 8,
+					height: 42,
+					r: 12
+				}).setFill({
+					type: "linear",
+					x1: 0,
+					y1: 50,
+					x2: 0,
+					y2: 30,
+					colors: [
+						{offset: 0, color: [100,100,100]},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g.createPath().moveTo(4, 25).vLineTo(14).smoothCurveTo(4, 4, 18, 4).hLineTo(w - 16).smoothCurveTo(w - 4, 4, w - 4, 16).closePath().setFill({
+					type: "linear",
+					x1: 0,
+					y1: 0,
+					x2: 0,
+					y2: 20,
+					colors: [
+						{offset: 0, color: [150,150,150]},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g.createPath().moveTo(4, 25).vLineTo(14).smoothCurveTo(4, 4, 18, 4).hLineTo(w - 16).smoothCurveTo(w - 4, 4, w - 4, 16).closePath().setFill([255,255,255,0.05]);
+			}
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/black/SemiCircularLinearGauge.js b/dojox/dgauges/components/black/SemiCircularLinearGauge.js
new file mode 100755
index 0000000..c2b1f71
--- /dev/null
+++ b/dojox/dgauges/components/black/SemiCircularLinearGauge.js
@@ -0,0 +1,162 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/Color", 
+		"../../CircularGauge", 
+		"../../LinearScaler", 
+		"../../CircularScale", 
+		"../../CircularValueIndicator", 
+		"../../CircularRangeIndicator",
+		"../DefaultPropertiesMixin"
+	],
+	function(lang, declare, Color, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, CircularRangeIndicator, DefaultPropertiesMixin){
+	return declare("dojox.dgauges.components.black.SemiCircularLinearGauge", [CircularGauge, DefaultPropertiesMixin], {
+		// summary:
+		//		A semi circular gauge widget.
+
+		// borderColor: Object|Array|int
+		//		The border color. Default is "#000000".
+		borderColor: "#000000",
+		// fillColor: Object|Array|int
+		//		The background color. Default is "#000000".
+		fillColor: "#000000",
+		// indicatorColor: Object|Array|int
+		//		The indicator fill color. Default is "#A4A4A4".
+		indicatorColor: "#A4A4A4",
+		constructor: function(){
+			// Base colors
+			this.borderColor = new Color(this.borderColor);
+			this.fillColor = new Color(this.fillColor);
+			this.indicatorColor = new Color(this.indicatorColor);
+
+			var scaler = new LinearScaler();
+			this.addElement("background", lang.hitch(this, this.drawBackground));
+			var scale = new CircularScale();
+			scale.set("scaler", scaler);
+			scale.set("originX", 186.46999);
+			scale.set("originY", 184.74814);			
+			scale.set("radius", 149.82183);
+			scale.set("startAngle", -180);
+			scale.set("endAngle", 0);
+			scale.set("orientation", "clockwise");
+			scale.set("labelGap", 8);
+			scale.set("font", {
+				family: "Helvetica",
+				weight: "bold",
+				size: "14pt",
+				color: "#CECECE"
+			});
+			scale.set("tickShapeFunc", function(group, scale, tick){
+				return group.createCircle({
+					r: tick.isMinor ? 2 : 4
+				}).setFill("#CECECE");
+			});
+			this.addElement("scale", scale);
+			var indicator = new CircularValueIndicator();
+			indicator.set("interactionArea", "gauge");
+			indicator.set("value", scaler.minimum);
+			indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+				return group.createPolyline([0, -12, indicator.scale.radius - 2, 0, 0, 12, 0, -12]).setStroke({
+					color: [70, 70, 70],
+					width: 1
+				}).setFill(this.indicatorColor);
+				
+			}));
+			scale.addIndicator("indicator", indicator);
+			this.addElement("foreground", lang.hitch(this, this.drawForeground));
+		},
+		
+		drawBackground: function(g){
+			// summary:
+			//		Draws the background shape of the gauge.
+			// g: dojox/gfx/Group
+			//		The group used to draw the background. 
+			// tags:
+			//		protected
+			g.createPath({
+				path: "M372.8838 205.5688 C372.9125 204.4538 372.93 194.135 372.94 185.6062 C372.4475 83.0063 289.1138 -0 186.4063 0.035 C83.7 0.0713 0.4225 83.1325 0 185.7325 C0.01 194.2175 0.0275 204.4638 0.0563 205.5763 C0.235 212.3488 5.7763 217.7462 12.5525 217.7462 L360.3888 217.7462 C367.1663 217.7462 372.71 212.3438 372.8838 205.5688"
+			}).setFill(this.borderColor);
+			g.createPath({
+				path: "M358.6738 203.9965 C358.7188 202.3627 358.7463 188.224 358.745 186.579 L358.745 186.4627 C358.7138 91.3165 281.5575 14.2127 186.4113 14.244 C91.2675 14.2777 14.1625 91.4327 14.1938 186.579 C14.1938 186.6177 14.2213 202.4015 14.2663 203.9965 L358.6738 203.9965 Z"
+			}).setFill({
+				type: "linear",
+				x1: 14.19376,
+				y1: 260.92225,
+				x2: 14.19376,
+				y2: 156.55837,
+				colors: [{
+					offset: 0,
+					color: [100, 100, 100]
+				}, {
+					offset: 1,
+					color: this.fillColor
+				}]
+			});
+			g.createPath({
+				path: "M358.7038 182.9027 C356.775 89.4027 280.3713 14.2127 186.4163 14.244 C92.5013 14.2765 16.1713 89.4527 14.2438 182.9002 C66.8388 197.064 127.36 168.814 188.7525 168.814 C250.1638 168.814 306.2575 197.0703 358.7038 182.9027"
+			}).setFill({
+				type: "linear",
+				x1: 14.24378,
+				y1: 186.87786,
+				x2: 14.24378,
+				y2: 14.24398,
+				colors: [{
+					offset: 0,
+					color: this.fillColor
+				}, {
+					offset: 1,
+					color: [200, 200, 200]
+				}]
+			});
+			g.createPath({
+				path: "M358.953 183.1553 C357.0243 89.6553 280.6205 14.4653 186.6655 14.4966 C92.7505 14.5291 16.4205 89.7053 14.493 183.1528 C67.088 197.3166 127.6093 169.0666 189.0018 169.0666 C250.413 169.0666 306.5068 197.3228 358.953 183.1553"
+			}).setFill([255, 255, 255, 0.12157]);
+		},
+		
+		drawForeground: function(g){
+			// summary:
+			//		Draws the foreground shape of the gauge.
+			// g: dojox/gfx/Group
+			//		The group used to draw the foreground. 
+			// tags:
+			//		protected
+			var g1 = g.createGroup();
+			g1.createPath({
+				path: "M214.9406 185.3295 C214.9456 201.0533 202.2044 213.8033 186.4806 213.8095 C170.7544 213.8145 158.0044 201.072 157.9994 185.3495 L157.9994 185.3295 C157.9931 169.6057 170.7369 156.8557 186.4619 156.8495 C202.1844 156.8445 214.9356 169.587 214.9406 185.3108 L214.9406 185.3295 Z"
+			}).setFill(this.borderColor);
+			g1.createPath({
+				path: "M211.3563 185.329 C211.36 199.074 200.2238 210.2177 186.4787 210.2228 C172.735 210.2277 161.59 199.0902 161.585 185.3465 L161.585 185.329 C161.58 171.5852 172.7175 160.4402 186.4613 160.4352 C200.2063 160.4303 211.3513 171.569 211.3563 185.3128 L211.3563 185.329 Z"
+			}).setFill({
+				type: "linear",
+				x1: 161.58503,
+				y1: 210.22273,
+				x2: 161.58503,
+				y2: 185.32899,
+				colors: [{
+					offset: 0,
+					color: [100, 100, 100]
+				}, {
+					offset: 1,
+					color: this.fillColor
+				}]
+			});
+			g1.createPath({
+				path: "M211.35 184.799 C211.0713 171.2928 200.035 160.4303 186.4625 160.4352 C172.8963 160.4402 161.87 171.299 161.5925 184.799 C169.1888 186.844 177.93 182.764 186.8013 182.764 C195.6712 182.764 203.7738 186.8452 211.35 184.799"
+			}).setFill({
+				type: "linear",
+				x1: 161.59251,
+				y1: 185.37311,
+				x2: 161.59251,
+				y2: 160.43524,
+				colors: [{
+					offset: 0,
+					color: this.fillColor
+				}, {
+					offset: 1,
+					color: [150, 150, 150]
+				}]
+			});
+			g1.createPath({
+				path: "M211.3494 184.7985 C211.0706 171.2923 200.0344 160.431 186.4632 160.436 C172.8956 160.441 161.8707 171.2997 161.5919 184.7985 C169.1881 186.8435 177.9306 182.7635 186.8006 182.7635 C195.6706 182.7635 203.7731 186.846 211.3494 184.7985"
+			}).setFill([255, 255, 255, 0.12157]);
+		}
+	});
+});
+
diff --git a/dojox/dgauges/components/black/VerticalLinearGauge.js b/dojox/dgauges/components/black/VerticalLinearGauge.js
new file mode 100755
index 0000000..854ecca
--- /dev/null
+++ b/dojox/dgauges/components/black/VerticalLinearGauge.js
@@ -0,0 +1,126 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../../RectangularGauge", 
+		"../../LinearScaler", 
+		"../../RectangularScale", 
+		"../../RectangularValueIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.black.VerticalLinearGauge", [RectangularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A vertical gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#000000".
+			borderColor: "#000000",
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#000000".
+			fillColor: "#000000",
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#A4A4A4".
+			indicatorColor: "#A4A4A4",
+			constructor: function(){
+				this.orientation = "vertical";
+				// Base colors
+				this.borderColor = new Color(this.borderColor);
+				this.fillColor = new Color(this.fillColor);
+				this.indicatorColor = new Color(this.indicatorColor);
+				
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+
+				// Scaler
+				var scaler = new LinearScaler();
+				
+				// Scale
+				var scale = new RectangularScale();
+				scale.set("scaler", scaler);
+				scale.set("labelPosition", "trailing");
+				scale.set("paddingTop", 30);
+				scale.set("paddingBottom", 30);
+				scale.set("paddingLeft", 15);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "7pt",
+					color: "#CECECE"
+				});
+				scale.set("tickShapeFunc", function(group, scale, tick){
+					return group.createCircle({
+						r: tick.isMinor ? 0.5 : 3
+					}).setFill("#CECECE");
+				});
+				this.addElement("scale", scale);
+				
+				var indicator = new RectangularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("paddingLeft", 18);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group){
+					return group.createPolyline([0, 0, -10, -20, 10, -20, 0, 0]).setFill(this.indicatorColor).setStroke({
+						color: [69,69,69],
+						width: 1,
+						style: "Solid",
+						cap: "butt",
+						join: 20.0
+					});
+
+				}));
+				scale.addIndicator("indicator", indicator);
+			},
+
+			drawBackground: function(g, w, h){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// w: Number
+				//		The width of the gauge.
+				// h: Number
+				//		The height of the gauge.
+				// tags:
+				//		protected
+				g.createRect({
+					x: 0,
+					y: 0,
+					width: 50,
+					height: h,
+					r: 15
+				}).setFill(this.borderColor);
+				g.createRect({
+					x: 4,
+					y: 4,
+					width: 42,
+					height: h - 8,
+					r: 12
+				}).setFill({
+					type: "linear",
+					x1: 5,
+					y1: 0,
+					x2: 20,
+					y2: 0,
+					colors: [
+						{offset: 0, color: [100,100,100]},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g.createPath().moveTo(25, 4).hLineTo(36).smoothCurveTo(46, 4, 46, 18).vLineTo(h - 20).smoothCurveTo(46, h - 4, 36, h - 4).closePath().setFill({
+					type: "linear",
+					x1: 70,
+					y1: 0,
+					x2: 25,
+					y2: 0,
+					colors: [
+						{offset: 0, color: [150,150,150]},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g.createPath().moveTo(25, 4).hLineTo(36).smoothCurveTo(46, 4, 46, 18).vLineTo(h - 20).smoothCurveTo(46, h - 4, 36, h - 4).closePath().setFill([255,255,255,0.05]);
+			}
+
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/classic/CircularLinearGauge.js b/dojox/dgauges/components/classic/CircularLinearGauge.js
new file mode 100755
index 0000000..05cac81
--- /dev/null
+++ b/dojox/dgauges/components/classic/CircularLinearGauge.js
@@ -0,0 +1,173 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color", 
+		"../../CircularGauge", 
+		"../../LinearScaler", 
+		"../../CircularScale", 
+		"../../CircularValueIndicator", 
+		"../../CircularRangeIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, CircularRangeIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.classic.CircularLinearGauge", [CircularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A circular gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#797E86".
+			borderColor: [121,126,134],
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#9498A1".
+			fillColor: [148,152,161],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#FFFFFF".
+			indicatorColor: "#FFFFFF",
+			constructor: function(){
+				this.borderColor = new Color(this.borderColor);
+				this.fillColor = new Color(this.fillColor);
+				this.indicatorColor = new Color(this.indicatorColor);
+				
+				var scaler = new LinearScaler();
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+				var scale = new CircularScale();
+				scale.set("scaler", scaler);
+				scale.set("originX", 81.94991);
+				scale.set("originY", 87.99015);
+				scale.set("radius", 66.34219);
+				scale.set("startAngle", 115.9);
+				scale.set("endAngle", 61.6);
+				scale.set("orientation", "clockwise");
+				scale.set("labelGap", 2);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "6pt"
+				});
+				this.addElement("scale", scale);
+				var indicator = new CircularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+
+					var l = indicator.scale.radius - 2;
+					return group.createPath().moveTo(0, 0).smoothCurveTo(l / 2, -10, l, 0).lineTo(l, 0).smoothCurveTo(l / 2, 10, 0, 0).closePath().setStroke({
+						color: this.borderColor,
+						width: 1,
+						join: 10
+					}).setFill({
+						type: "linear",
+						x1: 0,
+						y1: 0,
+						x2: l,
+						y2: 0,
+						colors: [
+							{offset: 0, color: [208,208,208]},
+							{offset: 1, color: this.indicatorColor}
+						]
+					});
+
+				}));
+				scale.addIndicator("indicator", indicator);
+				this.addElement("foreground", lang.hitch(this, this.drawForeground));
+			},
+
+			drawBackground: function(g){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// tags:
+				//		protected
+				g.createPath({
+					path: "M81.9213 6.4012 C36.7458 6.4012 0 43.1469 0 88.3225 C0 133.498 36.7458 170.2438 81.9213 170.2438 C127.0968 170.2438 163.8426 133.498 163.8425 88.3225 C163.8425 43.147 127.0968 6.4012 81.9213 6.4012 ZM81.9213 14.6771 C122.6195 14.6771 155.5666 47.6241 155.5666 88.3225 C155.5667 129.0207 122.6195 161.9678 81.9213 161.9678 C41.223 161.9678 8.2759 129.0207 8.2759 88.3225 C8.2759 47.6242 41.223 14.6771 81.9213 14.6771 Z"
+				}).setFill(this.borderColor);
+				g.createPath({
+					path: "M131.7007 23.859 C123.1609 16.836 112.7669 11.9131 100.5479 9.0902 C61.2014 0 20.5795 20.6702 9.8522 55.1976 C9.3592 56.9339 12.7501 58.0358 13.6957 55.5238 C24.6274 24.4073 64.5764 6.1932 100.6316 14.523 C118.2575 18.5951 131.7906 27.3347 141.2184 40.7415 C143.0075 43.6629 146.9334 42.1265 145.2492 39.0652 C141.4153 33.222 136.9106 28.1434 131.7007 23.859 Z"
+				}).setFill({
+					type: "linear",
+					x1: 9.8035,
+					y1: 6.94738,
+					x2: 9.8035,
+					y2: 31.97231,
+					colors: [
+						{offset: 0, color: [235,235,235]},
+						{offset: 1, color: this.borderColor}
+					]
+				});
+				g.createPath({
+					path: "M128.7453 148.5681 C120.6736 155.591 110.8493 160.5139 99.3 163.3368 C62.1102 172.427 23.715 151.7568 13.5757 117.2294 C13.1097 115.4931 16.3147 114.3912 17.2085 116.9032 C27.541 148.0197 65.3002 166.2338 99.3792 157.904 C116.0389 153.8319 128.8303 145.0923 137.7413 131.6855 C139.4323 128.7641 143.143 130.3005 141.5511 133.3618 C137.9274 139.205 133.6696 144.2836 128.7453 148.5681 Z"
+				}).setFill({
+					type: "linear",
+					x1: 13.52963,
+					y1: 165.47966,
+					x2: 13.52963,
+					y2: 140.45474,
+					colors: [
+						{offset: 0, color: [235,235,235]},
+						{offset: 1, color: this.borderColor}
+					]
+				});
+				g.createPath({
+					path: "M155.481 88.3136 C155.481 129.2951 122.5479 162.5169 81.9228 162.5169 C41.2978 162.5169 8.3647 129.2951 8.3647 88.3136 C8.3647 47.3323 41.2978 14.1102 81.9228 14.1102 C122.5479 14.1102 155.481 47.3323 155.481 88.3136 Z"
+				}).setFill({
+					type: "linear",
+					x1: 8.3647,
+					y1: 14.11022,
+					x2: 155.48103,
+					y2: 162.51695,
+					colors: [
+						{offset: 0, color: "white"},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g.createPath({
+					path: "M81.9229 13.2351 C40.8398 13.2351 7.4925 46.8859 7.4925 88.3295 C7.4925 129.7729 40.8398 163.3921 81.9229 163.3921 C123.006 163.3921 156.3532 129.7729 156.3532 88.3295 C156.3532 46.8859 123.006 13.2351 81.9229 13.2351 ZM81.9229 14.7211 C122.1911 14.7211 154.8672 47.708 154.8672 88.3295 C154.8672 128.951 122.1911 161.906 81.9229 161.906 C41.6546 161.906 8.9786 128.951 8.9786 88.3295 C8.9786 47.708 41.6546 14.7211 81.9229 14.7211 Z"
+				}).setFill({
+					type: "linear",
+					x1: 7.4925,
+					y1: 13.23515,
+					x2: 7.4925,
+					y2: 163.39214,
+					colors: [
+						{offset: 0, color: "white"},
+						{offset: 1, color: [148,152,161]}
+					]
+				});
+			},
+
+			drawForeground: function(g){
+				// summary:
+				//		Draws the foreground shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the foreground. 
+				// tags:
+				//		protected
+				g.createEllipse({
+					cx: 81.85091,
+					cy: 87.72405,
+					rx: 9.25,
+					ry: 9.25
+				}).setFill({
+					type: "radial",
+					cx: 81.85093,
+					cy: 84.02408,
+					r: 18.5,
+					colors: [
+						{offset: 0, color: [149,149,149]},
+						{offset: 0.5, color: "black"},
+						{offset: 1, color: "black"}
+					]
+				}).setStroke({
+					color: "black",
+					width: 0.1,
+					style: "Solid",
+					cap: "butt",
+					join: 4.0
+				});
+			}
+
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/classic/HorizontalLinearGauge.js b/dojox/dgauges/components/classic/HorizontalLinearGauge.js
new file mode 100755
index 0000000..344e22c
--- /dev/null
+++ b/dojox/dgauges/components/classic/HorizontalLinearGauge.js
@@ -0,0 +1,147 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../../RectangularGauge", 
+		"../../LinearScaler", 
+		"../../RectangularScale", 
+		"../../RectangularValueIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.classic.HorizontalLinearGauge", [RectangularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A horizontal gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#797E86".
+			borderColor: [121,126,134],
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#9498A1".
+			fillColor: [148,152,161],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#FFFFFF".
+			indicatorColor: "#FFFFFF",
+			constructor: function(){
+				// Base colors
+				this.borderColor = new Color(this.borderColor);
+				this.fillColor = new Color(this.fillColor);
+				this.indicatorColor = new Color(this.indicatorColor);
+
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+
+				// Scaler
+				var scaler = new LinearScaler();
+				
+				// Scale
+				var scale = new RectangularScale();
+				scale.set("scaler", scaler);
+				scale.set("labelPosition", "leading");
+				scale.set("paddingLeft", 30);
+				scale.set("paddingRight", 30);
+				scale.set("paddingTop", 32);
+				scale.set("labelGap", 8);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "7pt"
+				});
+				scale.set("tickShapeFunc", function(group, scale, tick){
+					return group.createCircle({
+						r: tick.isMinor ? 0.5 : 2
+					}).setFill("black");
+				});
+				this.addElement("scale", scale);
+				
+				var indicator = new RectangularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("paddingTop", 30);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+					
+					return group.createPolyline([0, 0, -10, -20, 10, -20, 0, 0]).setFill(this.indicatorColor).setStroke({
+						color: [121,126,134],
+						width: 1,
+						style: "Solid",
+						cap: "butt",
+						join: 20.0
+					});
+
+				}));
+				scale.addIndicator("indicator", indicator);
+			},
+
+			drawBackground: function(g, w, h){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// w: Number
+				//		The width of the gauge.
+				// h: Number
+				//		The height of the gauge.
+				// tags:
+				//		protected
+				g.createRect({
+					x: 0,
+					y: 0,
+					width: w,
+					height: 50,
+					r: 8
+				}).setFill(this.borderColor);
+				g.createRect({
+					x: 2,
+					y: 2,
+					width: w - 4,
+					height: 32,
+					r: 6
+				}).setFill({
+					type: "linear",
+					x1: 0,
+					y1: 2,
+					x2: 0,
+					y2: 15,
+					colors: [
+						{offset: 0, color: [235,235,235]},
+						{offset: 1, color: this.borderColor}
+					]
+				});
+				g.createRect({
+					x: 6,
+					y: 6,
+					width: w - 12,
+					height: 38,
+					r: 5
+				}).setFill({
+					type: "linear",
+					x1: 0,
+					y1: 6,
+					x2: 0,
+					y2: 38,
+					colors: [
+						{offset: 0, color: [220,220,220]},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g.createRect({
+					x: 7,
+					y: 7,
+					width: w - 14,
+					height: 36,
+					r: 3
+				}).setFill({
+					type: "linear",
+					x1: 0,
+					y1: 7,
+					x2: 0,
+					y2: 36,
+					colors: [
+						{offset: 0, color: this.fillColor},
+						{offset: 1, color: [220,220,220]}
+					]
+				});
+			}
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/classic/SemiCircularLinearGauge.js b/dojox/dgauges/components/classic/SemiCircularLinearGauge.js
new file mode 100755
index 0000000..73d18d0
--- /dev/null
+++ b/dojox/dgauges/components/classic/SemiCircularLinearGauge.js
@@ -0,0 +1,159 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color", 
+		"../../CircularGauge", 
+		"../../LinearScaler", 
+		"../../CircularScale", 
+		"../../CircularValueIndicator", 
+		"../../CircularRangeIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, CircularRangeIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.classic.SemiCircularLinearGauge", [CircularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A semi circular gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#797E86".
+			borderColor: [121,126,134],
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#9498A1".
+			fillColor: [148,152,161],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#FFFFFF".
+			indicatorColor: "#FFFFFF",
+			constructor: function(){
+				this.borderColor = new Color(this.borderColor);
+				this.fillColor = new Color(this.fillColor);
+				this.indicatorColor = new Color(this.indicatorColor);
+				
+				var scaler = new LinearScaler();
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+				var scale = new CircularScale();
+				scale.set("scaler", scaler);
+				scale.set("originX", 82.5469);
+				scale.set("originY", 86.56135);
+				scale.set("radius", 68.2182);
+				scale.set("startAngle", -179.9);
+				scale.set("endAngle", -0.1);
+				scale.set("orientation", "clockwise");
+				scale.set("labelGap", 2);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "6pt"
+				});
+				this.addElement("scale", scale);
+				var indicator = new CircularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+
+					var l = indicator.scale.radius - 2;
+					return group.createPath().moveTo(0, 0).smoothCurveTo(l / 2, -10, l, 0).lineTo(l, 0).smoothCurveTo(l / 2, 10, 0, 0).closePath().setStroke({
+						color: this.borderColor,
+						width: 1,
+						join: 10
+					}).setFill({
+						type: "linear",
+						x1: 0,
+						y1: 0,
+						x2: l,
+						y2: 0,
+						colors: [
+							{offset: 0, color: [208,208,208]},
+							{offset: 1, color: this.indicatorColor}
+						]
+					});
+
+				}));
+				scale.addIndicator("indicator", indicator);
+				this.addElement("foreground", lang.hitch(this, this.drawForeground));
+			},
+
+			drawBackground: function(g){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// tags:
+				//		protected
+				g.createPath({
+					path: "M82.4061 4.2361 C36.9308 4.2361 0 41.1357 0 86.6111 C0 92.8402 0.719 98.9014 2.0311 104.7361 L162.75 104.7361 C164.0621 98.9014 164.7812 92.8402 164.7812 86.6111 C164.7812 41.1357 127.8816 4.2361 82.4061 4.2361 Z"
+				}).setFill([121,126,134,1]);
+				g.createPath({
+					path: "M132.1809 21.8379 C109.1471 3.3761 75.6533 -0 48.8591 11.9106 C31.1385 19.6122 16.0526 34.4656 10.3325 53.1765 C13.128 58.4642 15.6567 49.646 16.9008 47.1352 C27.4881 26.5761 49.7822 14.215 72.1729 11.227 C95.4142 8.1002 121.0126 14.95 136.9788 32.7778 C139.4356 34.8999 143.5455 43.9915 146.1132 38.1149 C142.8197 31.7999 137.5776 26.4561 132.1809 21.8379 Z"
+				}).setFill({
+					type: "linear",
+					x1: 10.3325,
+					y1: 4.93862,
+					x2: 10.3325,
+					y2: 29.8873,
+					colors: [
+						{offset: 0, color: [235,235,235]},
+						{offset: 1, color: this.borderColor}
+					]
+				});
+				g.createPath({
+					path: "M82.2469 11.4202 C54.147 11.0778 26.9953 28.2183 14.7503 53.4303 C7.835 67.2286 5.3186 83.1515 7.5166 98.4202 C57.3367 98.4202 107.1569 98.4202 156.9772 98.4202 C161.2359 70.7787 148.7651 41.4452 125.8445 25.4041 C113.2386 16.3396 97.7752 11.3718 82.2469 11.4202 Z"
+				}).setFill({
+					type: "linear",
+					x1: 6.74398,
+					y1: 11.41516,
+					x2: 6.74398,
+					y2: 98.4202,
+					colors: [
+						{offset: 0, color: "white"},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g.createPath({
+					path: "M82.2469 12.4202 C53.2167 12.031 25.1734 30.4906 13.8879 57.2103 C8.3968 69.7668 6.5444 83.863 8.5064 97.4202 C57.6668 97.4202 106.827 97.4202 155.9873 97.4202 C160.2416 70.0807 147.542 41.1134 124.6241 25.6326 C112.2794 17.0413 97.2852 12.377 82.2469 12.4202 L82.2469 12.4202 Z"
+				}).setFill({
+					type: "linear",
+					x1: 7.74645,
+					y1: 12.41416,
+					x2: 156.8018,
+					y2: 97.4202,
+					colors: [
+						{offset: 0, color: "white"},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+			},
+
+			drawForeground: function(g){
+				// summary:
+				//		Draws the foreground shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the foreground. 
+				// tags:
+				//		protected
+				g.createEllipse({
+					cx: 82.2187,
+					cy: 86.0486,
+					rx: 9.25,
+					ry: 9.25
+				}).setFill({
+					type: "radial",
+					cx: 82.21872,
+					cy: 82.34862,
+					r: 18.5,
+					colors: [
+						{offset: 0, color: [149,149,149]},
+						{offset: 0.5, color: "black"},
+						{offset: 1, color: "black"}
+					]
+				}).setStroke({
+					color: "black",
+					width: 0.1,
+					style: "Solid",
+					cap: "butt",
+					join: 4.0
+				});
+			}
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/classic/VerticalLinearGauge.js b/dojox/dgauges/components/classic/VerticalLinearGauge.js
new file mode 100755
index 0000000..e77da1f
--- /dev/null
+++ b/dojox/dgauges/components/classic/VerticalLinearGauge.js
@@ -0,0 +1,148 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../../RectangularGauge", 
+		"../../LinearScaler", 
+		"../../RectangularScale", 
+		"../../RectangularValueIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.classic.VerticalLinearGauge", [RectangularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A vertical gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#797E86".
+			borderColor: [121,126,134],
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#9498A1".
+			fillColor: [148,152,161],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#FFFFFF".
+			indicatorColor: "#FFFFFF",
+			constructor: function(){
+				this.orientation = "vertical";
+				// Base colors
+				this.borderColor = new Color(this.borderColor);
+				this.fillColor = new Color(this.fillColor);
+				this.indicatorColor = new Color(this.indicatorColor);
+				
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+
+				// Scaler
+				var scaler = new LinearScaler();
+				
+				// Scale
+				var scale = new RectangularScale();
+				scale.set("scaler", scaler);
+				scale.set("labelPosition", "trailing");
+				scale.set("paddingTop", 30);
+				scale.set("paddingBottom", 30);
+				scale.set("paddingLeft", 17);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "7pt"
+				});
+				scale.set("tickShapeFunc", function(group, scale, tick){
+					return group.createCircle({
+						r: tick.isMinor ? 0.5 : 2
+					}).setFill("black");
+				});
+				this.addElement("scale", scale);
+				
+				var indicator = new RectangularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("paddingLeft", 18);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group){
+					
+					return group.createPolyline([0, 0, -10, -20, 10, -20, 0, 0]).setFill(this.indicatorColor).setStroke({
+						color: [121,126,134],
+						width: 1,
+						style: "Solid",
+						cap: "butt",
+						join: 20.0
+					});
+
+				}));
+				scale.addIndicator("indicator", indicator);
+			},
+
+			drawBackground: function(g, w, h){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// w: Number
+				//		The width of the gauge.
+				// h: Number
+				//		The height of the gauge.
+				// tags:
+				//		protected
+				g.createRect({
+					x: 0,
+					y: 0,
+					width: 50,
+					height: h,
+					r: 8
+				}).setFill(this.borderColor);
+				g.createRect({
+					x: 2,
+					y: 2,
+					width: 46,
+					height: h / 2,
+					r: 6
+				}).setFill({
+					type: "linear",
+					x1: 0,
+					y1: 2,
+					x2: 0,
+					y2: h / 2,
+					colors: [
+						{offset: 0, color: [235,235,235]},
+						{offset: 1, color: this.borderColor}
+					]
+				});
+				g.createRect({
+					x: 6,
+					y: 6,
+					width: 38,
+					height: h - 12,
+					r: 5
+				}).setFill({
+					type: "linear",
+					x1: 6,
+					y1: 0,
+					x2: 38,
+					y2: 0,
+					colors: [
+						{offset: 0, color: this.fillColor},
+						{offset: 1, color: [220,220,220]}
+					]
+				});
+				g.createRect({
+					x: 7,
+					y: 7,
+					width: 36,
+					height: h - 14,
+					r: 3
+				}).setFill({
+					type: "linear",
+					x1: 7,
+					y1: 0,
+					x2: 36,
+					y2: 0,
+					colors: [
+						{offset: 0, color: [220,220,220]},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+			}
+
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/default/CircularLinearGauge.js b/dojox/dgauges/components/default/CircularLinearGauge.js
new file mode 100755
index 0000000..7c7f0dd
--- /dev/null
+++ b/dojox/dgauges/components/default/CircularLinearGauge.js
@@ -0,0 +1,176 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare", 
+		"dojo/_base/Color", 
+		"../utils",
+		"../../CircularGauge", 
+		"../../LinearScaler", 
+		"../../CircularScale", 
+		"../../CircularValueIndicator",
+		"../../TextIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, utils, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, TextIndicator, DefaultPropertiesMixin){
+	return declare("dojox.dgauges.components.default.CircularLinearGauge", [CircularGauge, DefaultPropertiesMixin], {
+		// summary:
+		//		A circular gauge widget.
+
+		// _radius: Number
+		_radius: 100,
+		// borderColor: Object|Array|int
+		//		The border color. Default is "#C9DFF2".
+		borderColor: "#C9DFF2",
+		// fillColor: Object|Array|int
+		//		The background color. Default is "#FCFCFF".
+		fillColor: "#FCFCFF",
+		// indicatorColor: Object|Array|int
+		//		The indicator fill color. Default is "#F01E28".
+		indicatorColor: "#F01E28",
+		constructor: function(){
+			
+			// Base colors
+			this.borderColor = new Color(this.borderColor);
+			this.fillColor = new Color(this.fillColor);
+			this.indicatorColor = new Color(this.indicatorColor);
+
+			// Draw background
+			this.addElement("background", lang.hitch(this, this.drawBackground));
+			
+			// Scaler
+			var scaler = new LinearScaler();
+			
+			// Scale
+			var scale = new CircularScale();
+			scale.set("scaler", scaler);
+			this.addElement("scale", scale);
+			
+			// Value indicator
+			var indicator = new CircularValueIndicator();
+			scale.addIndicator("indicator", indicator);
+			
+			// Gauge Foreground (needle cap)
+			this.addElement("foreground", lang.hitch(this, this.drawForeground));
+			
+			// Indicator Text
+			var indicatorText = new TextIndicator();
+			indicatorText.set("indicator", indicator);
+			indicatorText.set("x", 100);
+			indicatorText.set("y", 150);
+			this.addElement("indicatorText", indicatorText);
+			
+			utils.genericCircularGauge(scale, indicator, this._radius, this._radius, 0.65 * this._radius, 130, 50, null, null, "outside");
+		},
+		
+		drawBackground: function(g){
+			// summary:
+			//		Draws the background shape of the gauge.
+			// g: dojox/gfx/Group
+			//		The group used to draw the background. 
+			// tags:
+			//		protected
+			var r = this._radius;
+			var w = 2 * r;
+			var h = w;
+			var entries = utils.createGradient([0, utils.brightness(this.borderColor, 70), 1, utils.brightness(this.borderColor, -40)]);
+			g.createEllipse({
+				cx: r,
+				cy: r,
+				rx: r,
+				ry: r
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: w,
+				y1: 0,
+				x2: 0,
+				y2: h
+			}, entries)).setStroke({
+				color: "#A5A5A5",
+				width: 0.2
+			});
+			
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 70), 1, utils.brightness(this.borderColor, -50)]);
+			g.createEllipse({
+				cx: r,
+				cy: r,
+				rx: r * 0.99,
+				ry: r * 0.99
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: 0,
+				y1: 0,
+				x2: w,
+				y2: h
+			}, entries));
+			
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 60), 1, utils.brightness(this.borderColor, -40)]);
+			g.createEllipse({
+				cx: r,
+				cy: r,
+				rx: r * 0.92,
+				ry: r * 0.92
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: 0,
+				y1: 0,
+				x2: w,
+				y2: h
+			}, entries));
+			
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 70), 1, utils.brightness(this.borderColor, -40)]);
+			g.createEllipse({
+				cx: r,
+				cy: r,
+				rx: r * 0.9,
+				ry: r * 0.9
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: w,
+				y1: 0,
+				x2: 0,
+				y2: h
+			}, entries));
+			
+			entries = utils.createGradient([0, [255, 255, 255, 220], 0.8, utils.brightness(this.fillColor, -5), 1, utils.brightness(this.fillColor, -30)]);
+			g.createEllipse({
+				cx: r,
+				cy: r,
+				rx: r * 0.9,
+				ry: r * 0.9
+			}).setFill(lang.mixin({
+				type: "radial",
+				cx: r,
+				cy: r,
+				r: r
+			}, entries)).setStroke({
+				color: utils.brightness(this.fillColor, -40),
+				width: 0.4
+			});
+			
+		},
+		
+		drawForeground: function(g){
+			// summary:
+			//		Draws the foreground shape of the gauge.
+			// g: dojox/gfx/Group
+			//		The group used to draw the foreground. 
+			// tags:
+			//		protected
+			var r = 0.07 * this._radius;
+			var entries = utils.createGradient([0, this.borderColor, 1, utils.brightness(this.borderColor, -20)]);
+			g.createEllipse({
+				cx: this._radius,
+				cy: this._radius,
+				rx: r,
+				ry: r
+			}).setFill(lang.mixin({
+				type: "radial",
+				cx: 0.96 * this._radius,
+				cy: 0.96 * this._radius,
+				r: r
+			}, entries)).setStroke({
+				color: utils.brightness(this.fillColor, -50),
+				width: 0.4
+			});
+		}
+	});
+});
diff --git a/dojox/dgauges/components/default/HorizontalLinearGauge.js b/dojox/dgauges/components/default/HorizontalLinearGauge.js
new file mode 100755
index 0000000..2347ab5
--- /dev/null
+++ b/dojox/dgauges/components/default/HorizontalLinearGauge.js
@@ -0,0 +1,190 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color", 
+		"../utils",
+		"../../RectangularGauge", 
+		"../../LinearScaler", 
+		"../../RectangularScale", 
+		"../../RectangularValueIndicator", 
+		"../../TextIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, utils, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator, TextIndicator, DefaultPropertiesMixin){
+	return declare("dojox.dgauges.components.default.HorizontalLinearGauge", [RectangularGauge, DefaultPropertiesMixin], {
+		// summary:
+		//		A horizontal gauge widget.
+
+		// borderColor: Object|Array|int
+		//		The border color. Default is "#C9DFF2".
+		borderColor: "#C9DFF2",
+		// fillColor: Object|Array|int
+		//		The background color. Default is "#FCFCFF".
+		fillColor: "#FCFCFF",
+		// indicatorColor: Object|Array|int
+		//		The indicator fill color. Default is "#F01E28".
+		indicatorColor: "#F01E28",
+		constructor: function(){
+			// Base colors
+			this.borderColor = new Color(this.borderColor);
+			this.fillColor = new Color(this.fillColor);
+			this.indicatorColor = new Color(this.indicatorColor);
+			
+			// Draw background
+			this.addElement("background", lang.hitch(this, this.drawBackground));
+			
+			// Scaler			
+			var scaler = new LinearScaler();
+			
+			// Scale
+			var scale = new RectangularScale();
+			scale.set("scaler", scaler);
+			scale.set("labelPosition", "trailing");
+			scale.set("paddingTop", 15);
+			scale.set("paddingRight", 23);
+			
+			this.addElement("scale", scale);
+			
+			// Value indicator
+			var indicator = new RectangularValueIndicator();			
+			indicator.indicatorShapeFunc = lang.hitch(this, function(group){
+				var indic = group.createPolyline([0, 0, 10, 0, 0, 10, -10, 0, 0, 0]).setStroke({
+					color: "blue",
+					width: 0.25
+				}).setFill(this.indicatorColor);
+				
+				return indic;
+			});
+			indicator.set("paddingTop", 5);
+			indicator.set("interactionArea", "gauge");
+			scale.addIndicator("indicator", indicator);
+			
+			// Indicator Text Border
+			this.addElement("indicatorTextBorder", lang.hitch(this, this.drawTextBorder), "leading");
+			
+			// Indicator Text
+			var indicatorText = new TextIndicator();
+			indicatorText.set("indicator", indicator);
+			indicatorText.set("x", 32.5);
+			indicatorText.set("y", 30);
+			this.addElement("indicatorText", indicatorText);
+
+		},
+		
+		drawBackground: function(g, w, h){
+			// summary:
+			//		Draws the background shape of the gauge.
+			// g: dojox/gfx/Group
+			//		The group used to draw the background. 
+			// w: Number
+			//		The width of the gauge.
+			// h: Number
+			//		The height of the gauge.
+			// tags:
+			//		protected
+			h = 49;
+			var gap = 0;
+			var cr = 3;
+			var entries = utils.createGradient([0, utils.brightness(this.borderColor, -20), 0.1, utils.brightness(this.borderColor, -40)]);
+			g.createRect({
+				x: 0,
+				y: 0,
+				width: w,
+				height: h,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: 0,
+				y1: 0,
+				x2: w,
+				y2: h
+			}, entries)).setStroke({
+				color: "#A5A5A5",
+				width: 0.2
+			});
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 70), 1, utils.brightness(this.borderColor, -50)]);
+			gap = 4;
+			cr = 2
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: 0,
+				y1: 0,
+				x2: w,
+				y2: h
+			}, entries));
+			gap = 6;
+			cr = 1
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 60), 1, utils.brightness(this.borderColor, -40)]);
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: 0,
+				y1: 0,
+				x2: w,
+				y2: h
+			}, entries));
+			
+			gap = 7;
+			cr = 0
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 70), 1, utils.brightness(this.borderColor, -40)]);
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: w,
+				y1: 0,
+				x2: 0,
+				y2: h
+			}, entries));
+			gap = 5;
+			cr = 0
+			entries = utils.createGradient([0, [255, 255, 255, 220], 0.8, utils.brightness(this.fillColor, -5), 1, utils.brightness(this.fillColor, -30)]);
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "radial",
+				cx: w / 2,
+				cy: 0,
+				r: w
+			}, entries)).setStroke({
+				color: utils.brightness(this.fillColor, -40),
+				width: 0.4
+			});
+			
+		},
+		drawTextBorder: function(g){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			return g.createRect({
+				x: 5,
+				y: 5,
+				width: 60,
+				height: 39
+			}).setStroke({
+				color: "#CECECE",
+				width: 1
+			});
+		}
+	});
+});
diff --git a/dojox/dgauges/components/default/SemiCircularLinearGauge.js b/dojox/dgauges/components/default/SemiCircularLinearGauge.js
new file mode 100755
index 0000000..991b71e
--- /dev/null
+++ b/dojox/dgauges/components/default/SemiCircularLinearGauge.js
@@ -0,0 +1,208 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare", 
+		"dojo/_base/Color", 
+		"../utils",
+		"../../CircularGauge", 
+		"../../LinearScaler", 
+		"../../CircularScale", 
+		"../../CircularValueIndicator", 
+		"../../TextIndicator",
+		"../DefaultPropertiesMixin"
+		], 
+	function(lang, declare, Color, utils, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, TextIndicator, DefaultPropertiesMixin){
+	return declare("dojox.dgauges.components.default.SemiCircularLinearGauge", [CircularGauge, DefaultPropertiesMixin], {
+		// summary:
+		//		A semi circular gauge widget.
+
+		_radius: 88,
+		_width: 200,
+		_height: 123,
+		// borderColor: Object|Array|int
+		//		The border color. Default is "#C9DFF2".
+		borderColor: "#C9DFF2",
+		// fillColor: Object|Array|int
+		//		The background color. Default is "#FCFCFF".
+		fillColor: "#FCFCFF",
+		// indicatorColor: Object|Array|int
+		//		The indicator fill color. Default is "#F01E28".
+		indicatorColor: "#F01E28",
+		constructor: function(){
+			
+			// Base colors
+			this.borderColor = new Color(this.borderColor);
+			this.fillColor = new Color(this.fillColor);
+			this.indicatorColor = new Color(this.indicatorColor);
+
+			// Draw background
+			this.addElement("background", lang.hitch(this, this.drawBackground));
+			
+			// Scaler
+			var scaler = new LinearScaler();
+			
+			// Scale
+			var scale = new CircularScale();
+			scale.set("scaler", scaler);
+			this.addElement("scale", scale);
+			
+			// Value indicator
+			var indicator = new CircularValueIndicator();
+			scale.addIndicator("indicator", indicator);
+			
+			// Gauge Foreground (needle cap)
+			this.addElement("foreground", lang.hitch(this, this.drawForeground));
+			
+			// Indicator Text Border
+			this.addElement("indicatorTextBorder", lang.hitch(this, this.drawTextBorder), "leading");
+			
+			// Indicator Text
+			var indicatorText = new TextIndicator();
+			indicatorText.set("indicator", indicator);
+			indicatorText.set("x", 100);
+			indicatorText.set("y", 115);
+			this.addElement("indicatorText", indicatorText);			
+			
+			utils.genericCircularGauge(scale, indicator, this._width / 2, 0.76 * this._height, this._radius, 166, 14, null, null, "inside");
+		},
+		
+		drawBackground: function(g){
+			// summary:
+			//		Draws the background shape of the gauge.
+			// g: dojox/gfx/Group
+			//		The group used to draw the background. 
+			// tags:
+			//		protected
+			var w = this._width;
+			var h = this._height;
+			var gap = 0;
+			var cr = 3;
+			var entries = utils.createGradient([0, utils.brightness(this.borderColor, -20), 0.1, utils.brightness(this.borderColor, -40)]);
+			g.createRect({
+				x: 0,
+				y: 0,
+				width: w,
+				height: h,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: 0,
+				y1: 0,
+				x2: w,
+				y2: h
+			}, entries)).setStroke({
+				color: "#A5A5A5",
+				width: 0.2
+			});
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 70), 1, utils.brightness(this.borderColor, -50)]);
+			gap = 4;
+			cr = 2
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: 0,
+				y1: 0,
+				x2: w,
+				y2: h
+			}, entries));
+			gap = 6;
+			cr = 1
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 60), 1, utils.brightness(this.borderColor, -40)]);
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: 0,
+				y1: 0,
+				x2: w,
+				y2: h
+			}, entries));
+			
+			gap = 7;
+			cr = 0
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 70), 1, utils.brightness(this.borderColor, -40)]);
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: w,
+				y1: 0,
+				x2: 0,
+				y2: h
+			}, entries));
+			gap = 5;
+			cr = 0			
+			entries = utils.createGradient([0, [255, 255, 255, 220], 0.8, utils.brightness(this.fillColor, -5), 1, utils.brightness(this.fillColor, -30)]);
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "radial",
+				cx: w/2,
+				cy: h/2,
+				r: h
+			}, entries)).setStroke({
+				color: utils.brightness(this.fillColor, -40),
+				width: 0.4
+			});
+			
+		},
+		
+		drawForeground: function(g){
+			// summary:
+			//		Draws the foreground shape of the gauge.
+			// g: dojox/gfx/Group
+			//		The group used to draw the foreground. 
+			// tags:
+			//		protected
+			var r = 0.07 * this._radius;
+			var entries = utils.createGradient([0, this.borderColor, 1, utils.brightness(this.borderColor, -20)]);
+			g.createEllipse({
+				cx: this._width / 2,
+				cy: 0.76 * this._height,
+				rx: r,
+				ry: r
+			}).setFill(lang.mixin({
+				type: "radial",
+				cx: this._width / 2 - 5,
+				cy: this._height * 0.76 - 5,
+				r: r
+			}, entries)).setStroke({
+				color: utils.brightness(this.fillColor, -50),
+				width: 0.4
+			});
+		},
+		
+		drawTextBorder: function(g){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			return g.createRect({
+				x: this._width / 2 - 12,
+				y: this._height - 20,
+				width: 24,
+				height: 14
+			}).setStroke({
+				color: utils.brightness(this.fillColor, -20),
+				width: 0.3
+			});
+		}
+	});
+});
+
diff --git a/dojox/dgauges/components/default/VerticalLinearGauge.js b/dojox/dgauges/components/default/VerticalLinearGauge.js
new file mode 100755
index 0000000..8b7a61b
--- /dev/null
+++ b/dojox/dgauges/components/default/VerticalLinearGauge.js
@@ -0,0 +1,194 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color", 
+		"../utils",
+		"../../RectangularGauge", 
+		"../../LinearScaler", 
+		"../../RectangularScale", 
+		"../../RectangularValueIndicator", 
+		"../../RectangularRangeIndicator",
+		"../../TextIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, utils, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator, RectangularRangeIndicator, TextIndicator, DefaultPropertiesMixin){
+	return declare("dojox.dgauges.components.default.VerticalLinearGauge", [RectangularGauge, DefaultPropertiesMixin], {
+		// summary:
+		//		A vertical gauge widget.
+
+		// borderColor: Object|Array|int
+		//		The border color. Default is "#C9DFF2".
+		borderColor: "#C9DFF2",
+		// fillColor: Object|Array|int
+		//		The background color. Default is "#FCFCFF".
+		fillColor: "#FCFCFF",
+		// indicatorColor: Object|Array|int
+		//		The indicator fill color. Default is "#F01E28".
+		indicatorColor: "#F01E28",
+		constructor: function(){
+			this.orientation = "vertical";
+			// Base colors
+			this.borderColor = new Color(this.borderColor);
+			this.fillColor = new Color(this.fillColor);
+			this.indicatorColor = new Color(this.indicatorColor);
+			
+			// Draw background
+			this.addElement("background", lang.hitch(this, this.drawBackground));
+			
+			
+			// Scaler
+			var scaler = new LinearScaler();
+			
+			// Scale
+			var scale = new RectangularScale();
+			scale.set("scaler", scaler);
+			scale.set("labelPosition", "leading");
+			scale.set("paddingBottom", 20);
+			scale.set("paddingLeft", 25);
+			
+			this.addElement("scale", scale);
+			
+			// Value indicator
+			var indicator = new RectangularValueIndicator();
+			
+			indicator.indicatorShapeFunc = lang.hitch(this, function(group){
+				var indic = group.createPolyline([0, 0, 10, 0, 0, 10, -10, 0, 0, 0]).setStroke({
+					color: "blue",
+					width: 0.25
+				}).setFill(this.indicatorColor);
+				
+				return indic;
+			});
+			indicator.set("paddingLeft", 45);
+			indicator.set("interactionArea", "gauge");
+			scale.addIndicator("indicator", indicator);
+
+			
+			// Indicator Text Border
+			this.addElement("indicatorTextBorder", lang.hitch(this, this.drawTextBorder), "leading");
+			
+			// Indicator Text
+			var indicatorText = new TextIndicator();
+			indicatorText.set("indicator", indicator);
+			indicatorText.set("x", 22.5);
+			indicatorText.set("y", 30);
+			this.addElement("indicatorText", indicatorText);
+		},
+		
+		drawBackground: function(g, w, h){
+			// summary:
+			//		Draws the background shape of the gauge.
+			// g: dojox/gfx/Group
+			//		The group used to draw the background. 
+			// w: Number
+			//		The width of the gauge.
+			// h: Number
+			//		The height of the gauge.
+			// tags:
+			//		protected
+			w = 49;
+			var gap = 0;
+			var cr = 3;
+			var entries = utils.createGradient([0, utils.brightness(this.borderColor, -20), 0.1, utils.brightness(this.borderColor, -40)]);
+			g.createRect({
+				x: 0,
+				y: 0,
+				width: w,
+				height: h,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: 0,
+				y1: 0,
+				x2: w,
+				y2: h
+			}, entries)).setStroke({
+				color: "#A5A5A5",
+				width: 0.2
+			});
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 70), 1, utils.brightness(this.borderColor, -50)]);
+			gap = 4;
+			cr = 2
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: 0,
+				y1: 0,
+				x2: w,
+				y2: h
+			}, entries));
+			gap = 6;
+			cr = 1
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 60), 1, utils.brightness(this.borderColor, -40)]);
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: 0,
+				y1: 0,
+				x2: w,
+				y2: h
+			}, entries));
+			
+			gap = 7;
+			cr = 0
+			entries = utils.createGradient([0, utils.brightness(this.borderColor, 70), 1, utils.brightness(this.borderColor, -40)]);
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "linear",
+				x1: w,
+				y1: 0,
+				x2: 0,
+				y2: h
+			}, entries));
+			gap = 5;
+			cr = 0
+			entries = utils.createGradient([0, [255, 255, 255, 220], 0.8, utils.brightness(this.fillColor, -5), 1, utils.brightness(this.fillColor, -30)]);
+			g.createRect({
+				x: gap,
+				y: gap,
+				width: w - 2 * gap,
+				height: h - 2 * gap,
+				r: cr
+			}).setFill(lang.mixin({
+				type: "radial",
+				cx: 0,
+				cy: h / 2,
+				r: h
+			}, entries)).setStroke({
+				color: utils.brightness(this.fillColor, -40),
+				width: 0.4
+			});
+			
+		},
+		drawTextBorder: function(g){
+			// summary:
+			//		Internal method.
+			// tags:
+			//		private
+			return g.createRect({
+				x: 5,
+				y: 5,
+				width: 40,
+				height: 40
+			}).setStroke({
+				color: "#CECECE",
+				width: 1
+			});
+		}
+	});
+});
diff --git a/dojox/dgauges/components/green/CircularLinearGauge.js b/dojox/dgauges/components/green/CircularLinearGauge.js
new file mode 100755
index 0000000..47ec531
--- /dev/null
+++ b/dojox/dgauges/components/green/CircularLinearGauge.js
@@ -0,0 +1,162 @@
+define([
+		"dojo/_base/lang",
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../utils",
+		"../../CircularGauge",
+		"../../LinearScaler",
+		"../../CircularScale",
+		"../../CircularValueIndicator",
+		"../../CircularRangeIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, utils, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, CircularRangeIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.green.CircularLinearGauge", [CircularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A circular gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#323232".
+			borderColor: [50,50,50],
+			// fillColor: Object|Array|int
+			//		The fill color. Default is "#6DB713".
+			fillColor: [109,183,19],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#000000".
+			indicatorColor: [0,0,0],
+			constructor: function(){
+				var scaler = new LinearScaler();
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+				var scale = new CircularScale();
+				scale.set("scaler", scaler);
+				scale.set("originX", 132);
+				scale.set("originY", 133.5);
+				scale.set("radius", 100);
+				scale.set("startAngle", 120);
+				scale.set("endAngle", 60);
+				scale.set("orientation", "clockwise");
+				scale.set("labelGap", 6);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "8pt"
+				});
+				this.addElement("scale", scale);
+				var indicator = new CircularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+
+					var l = indicator.scale.radius - 2;
+					group.createPath().moveTo(-20, 0).lineTo(-20, -5).lineTo(l, 0).lineTo(-20, 5).closePath().setFill(this.indicatorColor);
+					return group;
+
+				}));
+				scale.addIndicator("indicator", indicator);
+				this.addElement("foreground", lang.hitch(this, this.drawForeground));
+			},
+
+			drawBackground: function(g){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// tags:
+				//		protected
+				var lighterFillColor = utils.brightness(new Color(this.fillColor), 100);
+				g.createEllipse({
+					cx: 132.2528,
+					cy: 133.617,
+					rx: 132.2528,
+					ry: 131.9046
+				}).setFill(this.borderColor);
+				g.createPath({
+					path: "M260.5056 133.617 C260.5188 179.3085 236.0769 221.5348 196.39 244.3844 C156.703 267.234 107.8027 267.234 68.1158 244.3844 C28.4287 221.5348 3.9866 179.3085 4 133.617 C3.9866 87.9255 28.4287 45.6992 68.1158 22.8496 C107.8027 0 156.703 0 196.39 22.8496 C236.0769 45.6992 260.5188 87.9255 260.5056 133.617 Z"
+				}).setFill({
+					type: "linear",
+					x1: 4.00002,
+					y1: 5.71243,
+					x2: 183.55392,
+					y2: 261.52156,
+					colors: [
+						{offset: 0, color: [226,226,221]},
+						{offset: 0.5, color: [239,239,236]},
+						{offset: 1, color: "white"}
+					]
+				});
+				g.createPath({
+					path: "M132.2358 5.7124 C61.4417 5.7124 4 63.0164 4 133.617 C4 204.2176 61.4417 261.5216 132.2358 261.5216 C203.0297 261.5216 260.5056 204.2176 260.5056 133.617 C260.5056 63.0164 203.0297 5.7124 132.2358 5.7124 ZM132.2358 29.5811 C189.165 29.5811 235.3862 76.19 235.3862 133.617 C235.3862 191.0441 189.165 237.653 132.2358 237.653 C75.3064 237.653 29.1195 191.0441 29.1195 133.617 C29.1195 76.19 75.3064 29.5811 132.2358 29.5811 Z"
+				}).setFill({
+					type: "linear",
+					x1: 4.00003,
+					y1: 5.71235,
+					x2: 4.00003,
+					y2: 261.52154,
+					colors: [
+						{offset: 0, color: lighterFillColor},
+						{offset: 0.25, color: this.fillColor},
+						{offset: 0.5, color: this.fillColor},
+						{offset: 0.75, color: this.fillColor},
+						{offset: 1, color: lighterFillColor}
+					]
+				});
+				g.createPath({
+					path: "M-389.2685 91.1524 C-389.2685 194.5704 -473.1053 278.4072 -576.5233 278.4072 C-679.9412 278.4072 -763.778 194.5704 -763.778 91.1524 C-763.778 -12.2655 -679.9412 -96.1024 -576.5233 -96.1024 C-473.1053 -96.1024 -389.2685 -12.2655 -389.2685 91.1524 Z"
+				}).setTransform({
+					xx: 0.1,
+					xy: 0.46404,
+					yx: -0.46637,
+					yy: 0.1005,
+					dx: 147.5,
+					dy: -144.5
+				}).setStroke({
+					color: "white",
+					width: 3.04506,
+					style: "Solid",
+					cap: "butt",
+					join: 4.0
+				});
+			},
+
+			drawForeground: function(g){
+				// summary:
+				//		Draws the foreground shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the foreground. 
+				// tags:
+				//		protected
+				var g1 = g.createGroup();
+				g1.createEllipse({
+					cx: 132,
+					cy: 133.5,
+					rx: 18,
+					ry: 18
+				}).setFill(this.fillColor);
+				g1.createEllipse({
+					cx: 132,
+					cy: 133.5,
+					rx: 17,
+					ry: 17
+				}).setFill({
+					type: "linear",
+					x1: 116.09304,
+					y1: 118.09373,
+					x2: 116.09304,
+					y2: 149.2857,
+					colors: [
+						{offset: 0, color: [255,255,246]},
+						{offset: 0.17857, color: [252,251,236]},
+						{offset: 0.25755, color: [250,247,230]},
+						{offset: 0.77747, color: [246,243,224]},
+						{offset: 1, color: [227,209,184]}
+					]
+				});
+				g.createPath({
+					path: "M235.494 63.7584 C235.494 87.4242 189.2719 51.6605 132.3194 51.6605 C75.367 51.6605 29.1447 87.4242 29.1447 63.7584 C29.1447 40.0927 75.367 2.531 132.3194 2.531 C189.2719 2.531 235.494 40.0927 235.494 63.7584 Z"
+				}).setFill([255,255,255,0.19608]);
+			}
+
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/green/HorizontalLinearGauge.js b/dojox/dgauges/components/green/HorizontalLinearGauge.js
new file mode 100755
index 0000000..7bdc62a
--- /dev/null
+++ b/dojox/dgauges/components/green/HorizontalLinearGauge.js
@@ -0,0 +1,122 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../utils",
+		"../../RectangularGauge", 
+		"../../LinearScaler", 
+		"../../RectangularScale", 
+		"../../RectangularValueIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, utils, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.green.HorizontalLinearGauge", [RectangularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A horizontal gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#323232".
+			borderColor: [50,50,50],
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#6DB713".
+			fillColor: [109,183,19],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#000000".
+			indicatorColor: [0,0,0],
+			constructor: function(){
+				// Base colors
+				this.borderColor = new Color(this.borderColor);
+				this.fillColor = new Color(this.fillColor);
+				this.indicatorColor = new Color(this.indicatorColor);
+
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+
+				// Scaler
+				var scaler = new LinearScaler();
+				
+				// Scale
+				var scale = new RectangularScale();
+				scale.set("scaler", scaler);
+				scale.set("labelPosition", "leading");
+				scale.set("paddingLeft", 30);
+				scale.set("paddingRight", 30);
+				scale.set("paddingTop", 28);
+				scale.set("labelGap", 2);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "7pt"
+				});
+				this.addElement("scale", scale);
+				
+				var indicator = new RectangularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("paddingTop", 32);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+
+					return group.createPolyline([0, 0, -10, -20, 10, -20, 0, 0]).setFill(this.indicatorColor);
+
+				}));
+				scale.addIndicator("indicator", indicator);
+			},
+
+			drawBackground: function(g, w, h){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// w: Number
+				//		The width of the gauge.
+				// h: Number
+				//		The height of the gauge.
+				// tags:
+				//		protected
+				var lighterFillColor = utils.brightness(new Color(this.fillColor), 100);
+				g.createRect({
+					x: 0,
+					y: 0,
+					width: w,
+					height: 50,
+					r: 10
+				}).setFill(this.borderColor);
+				g.createRect({
+					x: 3,
+					y: 3,
+					width: w - 6,
+					height: 44,
+					r: 7
+				}).setFill({
+					type: "linear",
+					x1: 0,
+					y1: 2,
+					x2: 0,
+					y2: 30,
+					colors: [
+						{offset: 0, color: lighterFillColor},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g.createRect({
+					x: 6,
+					y: 6,
+					width: w - 12,
+					height: 38,
+					r: 5
+				}).setFill({
+					type: "linear",
+					x1: 0,
+					y1: 6,
+					x2: 0,
+					y2: 38,
+					colors: [
+						{offset: 0, color: [226,226,221]},
+						{offset: 0.5, color: [239,239,236]},
+						{offset: 1, color: "white"}
+					]
+				});
+			}
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/green/SemiCircularLinearGauge.js b/dojox/dgauges/components/green/SemiCircularLinearGauge.js
new file mode 100755
index 0000000..d5acd82
--- /dev/null
+++ b/dojox/dgauges/components/green/SemiCircularLinearGauge.js
@@ -0,0 +1,155 @@
+define([
+		"dojo/_base/lang",
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../utils",
+		"../../CircularGauge",
+		"../../LinearScaler",
+		"../../CircularScale",
+		"../../CircularValueIndicator",
+		"../../CircularRangeIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, utils, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, CircularRangeIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.green.SemiCircularLinearGauge", [CircularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A semi circular gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#323232".
+			borderColor: [50,50,50],
+			// fillColor: Object|Array|int
+			//		The fill color. Default is "#6DB713".
+			fillColor: [109,183,19],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#000000".
+			indicatorColor: [0,0,0],
+			constructor: function(){
+				var scaler = new LinearScaler({
+					majorTickInterval: 25,
+					minorTickInterval: 5
+				});
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+				var scale = new CircularScale();
+				scale.set("scaler", scaler);
+				scale.set("originX", 131);
+				scale.set("originY", 149.5);
+				scale.set("radius", 108.66756);
+				scale.set("startAngle", -136);
+				scale.set("endAngle", -43);
+				scale.set("orientation", "clockwise");
+				scale.set("labelGap", 2);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "10pt"
+				});
+				this.addElement("scale", scale);
+				var indicator = new CircularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+
+					var l = indicator.scale.radius - 2;
+					group.createPath().moveTo(-20, 0).lineTo(-20, -5).lineTo(l, 0).lineTo(-20, 5).closePath().setFill(this.indicatorColor);
+					return group;
+
+				}));
+				scale.addIndicator("indicator", indicator);
+				this.addElement("foreground", lang.hitch(this, this.drawForeground));
+			},
+
+			drawBackground: function(g){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// tags:
+				//		protected
+				var lighterFillColor = utils.brightness(new Color(this.fillColor), 100);
+				g.createPath({
+					path: "M260.7431 100.826 C260.7431 172.7911 202.3367 200.1975 130.3716 200.1975 C58.4065 200.1975 -0 172.7911 -0 100.826 C-0 28.8609 58.4065 0.4545 130.3716 0.4545 C202.3367 0.4545 260.7431 28.8609 260.7431 100.826 Z"
+				}).setFill(this.borderColor);
+				g.createPath({
+					path: "M258.2581 100.819 C258.2581 171.0137 200.9626 197.7459 130.3662 197.7459 C59.7698 197.7459 2.4742 171.0137 2.4742 100.819 C2.4742 30.6244 59.7698 2.9168 130.3662 2.9168 C200.9626 2.9168 258.2581 30.6244 258.2581 100.819 Z"
+				}).setFill({
+					type: "linear",
+					x1: 2.47421,
+					y1: 2.91677,
+					x2: 181.52295,
+					y2: 197.74595,
+					colors: [
+						{offset: 0, color: [226,226,221]},
+						{offset: 0.5, color: [239,239,236]},
+						{offset: 1, color: "white"}
+					]
+				});
+				g.createPath({
+					path: "M130.3762 2.9168 C59.9006 2.9168 2.4742 30.3335 2.4742 100.8214 C2.4742 171.3093 59.9006 197.7459 130.3762 197.7459 C200.8516 197.7459 258.2581 171.3093 258.2581 100.8214 C258.2581 30.3335 200.8516 2.9168 130.3762 2.9168 ZM130.3762 25.2846 C188.7428 25.2846 235.8942 42.4445 235.8942 100.8214 C235.8942 159.1984 188.7428 175.3581 130.3762 175.3581 C72.0095 175.3581 24.858 159.1984 24.858 100.8214 C24.858 42.4445 72.0095 25.2846 130.3762 25.2846 Z"
+				}).setFill({
+					type: "linear",
+					x1: 2.47417,
+					y1: 2.91681,
+					x2: 2.47417,
+					y2: 197.74593,
+					colors: [
+						{offset: 0, color: lighterFillColor},
+						{offset: 0.25, color: this.fillColor},
+						{offset: 0.5, color: this.fillColor},
+						{offset: 0.75, color: this.fillColor},
+						{offset: 1, color: lighterFillColor}
+					]
+				});
+				g.createPath({
+					path: "M128.9903 34.9775 C177.3318 33.7519 217.6275 49.1301 218.936 97.6431 C220.2445 146.1562 182.0729 160.5238 133.7314 161.7494 C85.39 162.975 45.0943 150.5968 43.7858 102.0838 C42.4772 53.5708 80.6489 36.2031 128.9903 34.9775 Z"
+				}).setStroke({
+					color: "white",
+					width: 1.42712,
+					style: "Solid",
+					cap: "butt",
+					join: 4.0
+				});
+			},
+
+			drawForeground: function(g){
+				// summary:
+				//		Draws the foreground shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the foreground. 
+				// tags:
+				//		protected
+				var g1 = g.createGroup();
+				g1.createEllipse({
+					cx: 131,
+					cy: 149.5,
+					rx: 18,
+					ry: 18
+				}).setFill(this.fillColor);
+				g1.createEllipse({
+					cx: 131,
+					cy: 149.5,
+					rx: 17,
+					ry: 17
+				}).setFill({
+					type: "linear",
+					x1: 114.63479,
+					y1: 133.63361,
+					x2: 114.63479,
+					y2: 164.82557,
+					colors: [
+						{offset: 0, color: [255,255,246]},
+						{offset: 0.17857, color: [252,251,236]},
+						{offset: 0.25755, color: [250,247,230]},
+						{offset: 0.77747, color: [246,243,224]},
+						{offset: 1, color: [227,209,184]}
+					]
+				});
+				g.createPath({
+					path: "M244.8093 59.9472 C244.8093 82.7317 193.7605 47.2998 130.8612 47.2998 C67.9619 47.2998 16.9132 81.7317 16.9132 58.9472 C16.9132 36.1628 67.9619 0 130.8612 0 C193.7605 0 244.8093 37.1628 244.8093 59.9472 Z"
+				}).setFill([255,255,255,0.19608]);
+			}
+
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/green/VerticalLinearGauge.js b/dojox/dgauges/components/green/VerticalLinearGauge.js
new file mode 100755
index 0000000..a4058de
--- /dev/null
+++ b/dojox/dgauges/components/green/VerticalLinearGauge.js
@@ -0,0 +1,124 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../utils",
+		"../../RectangularGauge", 
+		"../../LinearScaler", 
+		"../../RectangularScale", 
+		"../../RectangularValueIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, utils, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.green.VerticalLinearGauge", [RectangularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A vertical gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#323232".
+			borderColor: [50,50,50],
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#6DB713".
+			fillColor: [109,183,19],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#000000".
+			indicatorColor: [0,0,0],
+			constructor: function(){
+				this.orientation = "vertical";
+				// Base colors
+				this.borderColor = new Color(this.borderColor);
+				this.fillColor = new Color(this.fillColor);
+				this.indicatorColor = new Color(this.indicatorColor);
+				
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+
+				// Scaler
+				var scaler = new LinearScaler();
+				
+				// Scale
+				var scale = new RectangularScale();
+				scale.set("scaler", scaler);
+				scale.set("labelPosition", "trailing");
+				scale.set("paddingTop", 30);
+				scale.set("paddingBottom", 30);
+				scale.set("paddingLeft", 15);
+				scale.set("labelGap", 2);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "7pt"
+				});
+				this.addElement("scale", scale);
+				
+				var indicator = new RectangularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("paddingLeft", 18);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group){
+
+					return group.createPolyline([0, 0, -10, -20, 10, -20, 0, 0]).setFill(this.indicatorColor);
+
+				}));
+				scale.addIndicator("indicator", indicator);
+			},
+
+			drawBackground: function(g, w, h){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// w: Number
+				//		The width of the gauge.
+				// h: Number
+				//		The height of the gauge.
+				// tags:
+				//		protected
+				var lighterFillColor = utils.brightness(new Color(this.fillColor), 100);
+				g.createRect({
+					x: 0,
+					y: 0,
+					width: 50,
+					height: h,
+					r: 10
+				}).setFill(this.borderColor);
+				g.createRect({
+					x: 3,
+					y: 3,
+					width: 44,
+					height: h - 6,
+					r: 7
+				}).setFill({
+					type: "linear",
+					x1: 6,
+					y1: 0,
+					x2: 38,
+					y2: 0,
+					colors: [
+						{offset: 0, color: lighterFillColor},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g.createRect({
+					x: 6,
+					y: 6,
+					width: 38,
+					height: h - 12,
+					r: 6
+				}).setFill({
+					type: "linear",
+					x1: 7,
+					y1: 0,
+					x2: 36,
+					y2: 0,
+					colors: [
+						{offset: 0, color: [226,226,221]},
+						{offset: 0.5, color: [239,239,236]},
+						{offset: 1, color: "white"}
+					]
+				});
+			}
+
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/grey/CircularLinearGauge.js b/dojox/dgauges/components/grey/CircularLinearGauge.js
new file mode 100755
index 0000000..a388a8b
--- /dev/null
+++ b/dojox/dgauges/components/grey/CircularLinearGauge.js
@@ -0,0 +1,139 @@
+define([
+		"dojo/_base/lang",
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../utils",
+		"../../CircularGauge",
+		"../../LinearScaler",
+		"../../CircularScale",
+		"../../CircularValueIndicator",
+		"../../CircularRangeIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, utils, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, CircularRangeIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.grey.CircularLinearGauge", [CircularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A circular gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#9498A1".
+			borderColor: [148,152,161],
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#9498A1".
+			fillColor: [148,152,161],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#3F3F3F".
+			indicatorColor: [63,63,63],
+			constructor: function(args, node){
+				var scaler = new LinearScaler();
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+				var scale = new CircularScale();
+				scale.set("scaler", scaler);
+				scale.set("originX", 73.4);
+				scale.set("originY", 74.10297);
+				scale.set("radius", 61.44239);
+				scale.set("startAngle", 130.16044);
+				scale.set("endAngle", 50.25444);
+				scale.set("orientation", "clockwise");
+				scale.set("labelGap", 2);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "8pt"
+				});
+				this.addElement("scale", scale);
+				var indicator = new CircularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+
+					var l = indicator.scale.radius - 2;
+					group.createPath().moveTo(0, 0).lineTo(0, -5).lineTo(l, 0).lineTo(0, 0).closePath().setFill(this.indicatorColor);
+					var lighterColor = utils.brightness(new Color(this.indicatorColor), 70);
+					group.createPath().moveTo(0, 0).lineTo(0, 5).lineTo(l, 0).lineTo(0, 0).closePath().setFill(lighterColor);
+					return group;
+
+				}));
+				scale.addIndicator("indicator", indicator);
+				this.addElement("foreground", lang.hitch(this, this.drawForeground));
+			},
+
+			drawBackground: function(g){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// tags:
+				//		protected
+				g.createEllipse({
+					cx: 73.5,
+					cy: 73.75,
+					rx: 73.5,
+					ry: 73.75
+				}).setFill(this.borderColor);
+				g.createEllipse({
+					cx: 73.5,
+					cy: 73.75,
+					rx: 71.5,
+					ry: 71.75
+				}).setFill({
+					type: "linear",
+					x1: 2,
+					y1: 2,
+					x2: 2,
+					y2: 174.2,
+					colors: [
+						{offset: 0, color: this.fillColor},
+						{offset: 1, color: "white"}
+					]
+				});
+				g.createPath({
+					path: "M71.7134 2.3627 C35.3338 3.0547 6.0025 32.818 6.0025 69.3621 C6.0025 69.7225 5.9968 70.0836 6.0025 70.4427 C26.4442 78.2239 50.1913 82.6622 75.4956 82.6622 C98.7484 82.6622 120.6538 78.8779 139.918 72.2299 C139.9587 71.2717 140.0011 70.3303 140.0011 69.3621 C140.0011 32.3847 109.9791 2.3627 73.0018 2.3627 C72.5685 2.3627 72.1447 2.3545 71.7133 2.3627 Z"
+				}).setFill({
+					type: "linear",
+					x1: 6,
+					y1: 2.3591,
+					x2: 6,
+					y2: 150,
+					colors: [
+						{offset: 0, color: "white"},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+			},
+
+			drawForeground: function(g){
+				// summary:
+				//		Draws the foreground shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the foreground. 
+				// tags:
+				//		protected
+				g.createEllipse({
+					cx: 73.3,
+					cy: 73.8,
+					rx: 9.25,
+					ry: 9.25
+				}).setFill({
+					type: "radial",
+					cx: 73.30003,
+					cy: 70.10003,
+					r: 18.5,
+					colors: [
+						{offset: 0, color: [149,149,149]},
+						{offset: 0.5, color: "black"},
+						{offset: 1, color: "black"}
+					]
+				}).setStroke({
+					color: "black",
+					width: 0.1,
+					style: "Solid",
+					cap: "butt",
+					join: 4.0
+				});
+			}
+
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/grey/HorizontalLinearGauge.js b/dojox/dgauges/components/grey/HorizontalLinearGauge.js
new file mode 100755
index 0000000..7b11161
--- /dev/null
+++ b/dojox/dgauges/components/grey/HorizontalLinearGauge.js
@@ -0,0 +1,119 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../../RectangularGauge", 
+		"../../LinearScaler", 
+		"../../RectangularScale", 
+		"../../RectangularValueIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.grey.HorizontalLinearGauge", [RectangularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A horizontal gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#9498A1".
+			borderColor: [148,152,161],
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#9498A1".
+			fillColor: [148,152,161],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#3F3F3F".
+			indicatorColor: [63,63,63],
+			constructor: function(){
+				// Base colors
+				this.borderColor = new Color(this.borderColor);
+				this.fillColor = new Color(this.fillColor);
+				this.indicatorColor = new Color(this.indicatorColor);
+
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+
+				// Scaler
+				var scaler = new LinearScaler();
+				
+				// Scale
+				var scale = new RectangularScale();
+				scale.set("scaler", scaler);
+				scale.set("labelPosition", "leading");
+				scale.set("paddingLeft", 30);
+				scale.set("paddingRight", 30);
+				scale.set("paddingTop", 28);
+				scale.set("labelGap", 8);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "7pt"
+				});
+				this.addElement("scale", scale);
+				
+				var indicator = new RectangularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("paddingTop", 32);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+
+					return group.createPolyline([0, 0, -10, -20, 10, -20, 0, 0]).setFill(this.indicatorColor).setStroke({
+						color: [70, 70, 70],
+						width: 1,
+						style: "Solid",
+						cap: "butt",
+						join: 20.0
+					});
+
+				}));
+				scale.addIndicator("indicator", indicator);
+			},
+
+			drawBackground: function(g, w, h){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// w: Number
+				//		The width of the gauge.
+				// h: Number
+				//		The height of the gauge.
+				// tags:
+				//		protected
+				g.createRect({
+					x: 0,
+					y: 0,
+					width: w,
+					height: 50,
+					r: 13.5
+				}).setFill(this.borderColor);
+				g.createRect({
+					x: 2,
+					y: 2,
+					width: w - 4,
+					height: 46,
+					r: 11.5
+				}).setFill({
+					type: "linear",
+					x1: 0,
+					y1: -2,
+					x2: 0,
+					y2: 60,
+					colors: [
+						{offset: 0, color: this.fillColor},
+						{offset: 1, color: "white"}
+					]
+				});
+				g.createPath().moveTo(2, 25).vLineTo(12).smoothCurveTo(2, 2, 16, 2).hLineTo(w - 12).smoothCurveTo(w - 2, 2, w - 2, 16).closePath().setFill({
+					type: "linear",
+					x1: 0,
+					y1: -5,
+					x2: 0,
+					y2: 40,
+					colors: [
+						{offset: 0, color: "white"},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+			}
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/grey/SemiCircularLinearGauge.js b/dojox/dgauges/components/grey/SemiCircularLinearGauge.js
new file mode 100755
index 0000000..03ca420
--- /dev/null
+++ b/dojox/dgauges/components/grey/SemiCircularLinearGauge.js
@@ -0,0 +1,136 @@
+define([
+		"dojo/_base/lang",
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../utils",
+		"../../CircularGauge",
+		"../../LinearScaler",
+		"../../CircularScale",
+		"../../CircularValueIndicator",
+		"../../CircularRangeIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, utils, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, CircularRangeIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.grey.SemiCircularLinearGauge", [CircularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A semi circular gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#9498A1".
+			borderColor: [148,152,161],
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#9498A1".
+			fillColor: [148,152,161],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#3F3F3F".
+			indicatorColor: [63,63,63],
+			constructor: function(args, node){
+				var scaler = new LinearScaler({
+					majorTickInterval: 25,
+					minorTickInterval: 5
+				});
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+				var scale = new CircularScale();
+				scale.set("scaler", scaler);
+				scale.set("originX", 118.80925);
+				scale.set("originY", 172.98112);
+				scale.set("radius", 160.62904);
+				scale.set("startAngle", -127.30061);
+				scale.set("endAngle", -53);
+				scale.set("orientation", "clockwise");
+				scale.set("labelGap", 2);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "8pt"
+				});
+				this.addElement("scale", scale);
+				var indicator = new CircularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group, indicator){
+
+					var l = indicator.scale.radius - 2;
+					group.createPath().moveTo(0, 0).lineTo(0, -5).lineTo(l, 0).lineTo(0, 0).closePath().setFill(this.indicatorColor);
+					var lighterColor = utils.brightness(new Color(this.indicatorColor), 70);
+					group.createPath().moveTo(0, 0).lineTo(0, 5).lineTo(l, 0).lineTo(0, 0).closePath().setFill(lighterColor);
+					return group;
+
+				}));
+				scale.addIndicator("indicator", indicator);
+				this.addElement("foreground", lang.hitch(this, this.drawForeground));
+			},
+
+			drawBackground: function(g){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// tags:
+				//		protected
+				g.createPath({
+					path: "M116.4449 0.014 C82.013 -0 48.0666 7.3389 14.6499 22.4862 C6.1025 25.6372 0 33.8658 0 43.5028 C0 49.8823 2.677 55.6345 6.9637 59.713 L99.9834 180.9853 C99.9859 180.9893 99.9914 180.9917 99.9939 180.9957 C103.9488 187.329 110.9778 191.5406 118.9895 191.5406 C126.8965 191.5406 133.8563 187.4321 137.8385 181.2366 C137.8426 181.2301 137.8448 181.222 137.849 181.2157 L231.3295 59.4197 C235.4368 55.3611 237.9789 49.7288 237.9789 43.5028 C237.9789 33.7053 231.6713 25.3703 222.8998 2 [...]
+				}).setFill(this.borderColor);
+				g.createPath({
+					path: "M116.224 1.014 C82.301 1.0002 48.8563 8.2306 15.9334 23.1541 C7.5123 26.2585 1.5 34.3655 1.5 43.8601 C1.5 50.1453 4.1374 55.8125 8.3608 59.8307 L100.0058 179.3108 C100.0083 179.3148 100.0137 179.3171 100.0162 179.3211 C103.9126 185.5608 110.8377 189.7102 118.731 189.7102 C126.5212 189.7102 133.3781 185.6624 137.3015 179.5584 C137.3055 179.552 137.3077 179.5441 137.3118 179.5378 L229.4108 59.5418 C233.4574 55.5432 235.962 49.9941 235.962 43.8601 C235.962 34.2074 229.7476 25.99 [...]
+				}).setFill({
+					type: "linear",
+					x1: 1.5,
+					y1: 1.01397,
+					x2: 1.5,
+					y2: 227.44943,
+					colors: [
+						{offset: 0, color: this.fillColor},
+						{offset: 1, color: "white"}
+					]
+				});
+				g.createPath({
+					path: "M117.848 3.0148 C83.3161 3.3066 42.2685 15.8301 16.4018 27.4452 C5.957 32.4174 9.5019 48.0401 18.3827 57.3539 C46.55 86.8947 80.5357 90.0379 118.4979 90.0379 C118.5432 90.0379 118.5868 90.0379 118.6321 90.0379 C118.7622 90.0379 118.8943 90.038 119.0241 90.0379 C119.0686 90.0379 119.1137 90.0379 119.1582 90.0379 C153.5091 90.0379 191.1062 86.8947 219.2735 57.3539 C228.1543 48.0401 231.6992 32.4174 221.2543 27.4452 C195.2041 15.7477 153.7583 3.1333 119.0757 3.0148 C119.0485 3.0 [...]
+				}).setFill({
+					type: "linear",
+					x1: 10.0001,
+					y1: 3.01406,
+					x2: 10.0001,
+					y2: 150,
+					colors: [
+						{offset: 0, color: "white"},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+			},
+
+			drawForeground: function(g){
+				// summary:
+				//		Draws the foreground shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the foreground. 
+				// tags:
+				//		protected
+				g.createEllipse({
+					cx: 118.80001,
+					cy: 172.81399,
+					rx: 9.25,
+					ry: 9.25
+				}).setFill({
+					type: "radial",
+					cx: 118.80003,
+					cy: 169.11402,
+					r: 18.5,
+					colors: [
+						{offset: 0, color: [149,149,149]},
+						{offset: 0.5, color: "black"},
+						{offset: 1, color: "black"}
+					]
+				}).setStroke({
+					color: "black",
+					width: 0.1,
+					style: "Solid",
+					cap: "butt",
+					join: 4.0
+				});
+			}
+
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/grey/VerticalLinearGauge.js b/dojox/dgauges/components/grey/VerticalLinearGauge.js
new file mode 100755
index 0000000..4dfa13d
--- /dev/null
+++ b/dojox/dgauges/components/grey/VerticalLinearGauge.js
@@ -0,0 +1,116 @@
+define([
+		"dojo/_base/lang", 
+		"dojo/_base/declare",
+		"dojo/_base/Color",
+		"../../RectangularGauge", 
+		"../../LinearScaler", 
+		"../../RectangularScale", 
+		"../../RectangularValueIndicator",
+		"../DefaultPropertiesMixin"
+	], 
+	function(lang, declare, Color, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator, DefaultPropertiesMixin){
+		return declare("dojox.dgauges.components.grey.VerticalLinearGauge", [RectangularGauge, DefaultPropertiesMixin], {
+			// summary:
+			//		A vertical gauge widget.
+
+			// borderColor: Object|Array|int
+			//		The border color. Default is "#9498A1".
+			borderColor: [148,152,161],
+			// fillColor: Object|Array|int
+			//		The background color. Default is "#9498A1".
+			fillColor: [148,152,161],
+			// indicatorColor: Object|Array|int
+			//		The indicator fill color. Default is "#3F3F3F".
+			indicatorColor: [63,63,63],
+			constructor: function(){
+				this.orientation = "vertical";
+				// Base colors
+				this.borderColor = new Color(this.borderColor);
+				this.fillColor = new Color(this.fillColor);
+				this.indicatorColor = new Color(this.indicatorColor);
+				
+				this.addElement("background", lang.hitch(this, this.drawBackground));
+
+				// Scaler
+				var scaler = new LinearScaler();
+				
+				// Scale
+				var scale = new RectangularScale();
+				scale.set("scaler", scaler);
+				scale.set("labelPosition", "trailing");
+				scale.set("paddingTop", 30);
+				scale.set("paddingBottom", 30);
+				scale.set("paddingLeft", 15);
+				scale.set("labelGap", 4);
+				scale.set("font", {
+					family: "Helvetica",
+					weight: "bold",
+					size: "7pt"
+				});
+				this.addElement("scale", scale);
+				
+				var indicator = new RectangularValueIndicator();
+				indicator.set("interactionArea", "gauge");
+				indicator.set("value", scaler.minimum);
+				indicator.set("paddingLeft", 22);
+				indicator.set("indicatorShapeFunc", lang.hitch(this, function(group){
+					
+					group.createPath().moveTo(0, 0).lineTo(-10, -20).lineTo(10, -20).lineTo(0, 0).closePath().setFill(this.indicatorColor);
+					return group;
+
+				}));
+				scale.addIndicator("indicator", indicator);
+			},
+
+			drawBackground: function(g, w, h){
+				// summary:
+				//		Draws the background shape of the gauge.
+				// g: dojox/gfx/Group
+				//		The group used to draw the background. 
+				// w: Number
+				//		The width of the gauge.
+				// h: Number
+				//		The height of the gauge.
+				// tags:
+				//		protected
+				g.createRect({
+					x: 0,
+					y: 0,
+					width: 50,
+					height: h,
+					r: 13.5
+				}).setFill(this.borderColor);
+				g.createRect({
+					x: 2,
+					y: 2,
+					width: 46,
+					height: h - 4,
+					r: 11.5
+				}).setFill({
+					type: "linear",
+					x1: -2,
+					y1: 0,
+					x2: 60,
+					y2: 0,
+					colors: [
+						{offset: 0, color: "white"},
+						{offset: 1, color: this.fillColor}
+					]
+				});
+				g.createPath().moveTo(25, 2).hLineTo(38).smoothCurveTo(48, 2, 48, 18).vLineTo(h - 16).smoothCurveTo(48, h - 2, 38, h - 2).closePath().setFill({
+					type: "linear",
+					x1: -10,
+					y1: 0,
+					x2: 60,
+					y2: 0,
+					colors: [
+						{offset: 0, color: this.fillColor},
+						{offset: 1, color: "white"}
+					]
+				});
+			}
+
+		});
+	}
+);
+
diff --git a/dojox/dgauges/components/utils.js b/dojox/dgauges/components/utils.js
new file mode 100755
index 0000000..034e6cd
--- /dev/null
+++ b/dojox/dgauges/components/utils.js
@@ -0,0 +1,133 @@
+define(["dojo/_base/lang", "dojo/_base/Color"], function(lang, Color){
+	// module:
+	//		dojox/dgauges/components/utils
+	// summary:
+	//		Gauge utilities.
+	// tags:
+	//		public
+
+	var utils = {};
+
+	lang.mixin(utils, {
+		brightness: function(col, b){
+			// summary:
+			//		Adjusts the brightness of a color.
+			// col: Number
+			//		The base color
+			// b: Number
+			//		A positive or negative value to adjust the brightness
+			// returns: Number
+			//		The modified color			
+			var res = lang.mixin(null, col);
+			res.r = Math.max(Math.min(res.r + b, 255), 0);
+			res.g = Math.max(Math.min(res.g + b, 255), 0);
+			res.b = Math.max(Math.min(res.b + b, 255), 0);
+			return res;
+		},
+		
+		createGradient: function(entries){
+			// summary:
+			//		Creates a gradient object
+			// entries: Array
+			//		An array of numbers representing colors
+			// returns: Number
+			//		The modified color			
+			var res = {
+				colors: []
+			};
+			var obj;
+			for(var i = 0; i < entries.length; i++){
+				if(i % 2 == 0){
+					obj = {
+						offset: entries[i]
+					};
+				} else {
+					obj.color = entries[i];
+					res.colors.push(obj);
+				}
+			}
+			return res;
+		},
+		
+		_setter: function(obj, attributes, values){
+			for(var i = 0; i < attributes.length; i++){
+				obj[attributes[i]] = values[i];
+			}
+		},
+		
+		genericCircularGauge: function(scale, indicator, originX, originY, radius, startAngle, endAngle, orientation, font, labelPosition, tickShapeFunc){
+			// summary:
+			//		A helper method for configuring a circular gauge.
+			// scale: CircularScale
+			//		A circular scale
+			// indicator: IndicatorBase
+			//		A circular indicator
+			// originX: Number
+			//		The x-coordinate of the center of the scale (in pixels) 
+			// originY: Number
+			//		The y-coordinate of the center of the scale (in pixels)
+			// radius: Number
+			//		The radius of the scale (in pixels)
+			// startAngle: Number
+			//		The start angle of the scale (in degrees)
+			// endAngle: Number
+			//		The end angle of the scale (in degrees)
+			// orientation: String?
+			//		The orientation of the scale, can be "clockwise" or "cclockwise"
+			// font: Object?
+			//		The font used for the gauge
+			// labelPosition: String?
+			//		The position of the labels regarding   
+			// tickShapeFunc: Object?
+			//		A drawing function for the ticks
+			// returns: Number
+			//		The modified color	
+			var attributes = ["originX", "originY", "radius", "startAngle", "endAngle", "orientation", "font", "labelPosition", "tickShapeFunc"];
+			if(!orientation){
+				orientation = "clockwise";
+			}
+			if(!font){
+				font = {
+					family: "Helvetica",
+					style: "normal",
+					size: "10pt",
+					color: "#555555"
+				};
+			}
+			if(!labelPosition){
+				labelPosition = "inside";
+			}
+			if(!tickShapeFunc){
+				tickShapeFunc = function(group, scale, tick){
+					var stroke = scale.tickStroke;
+					var majorStroke;
+					var minorStroke;
+					if(stroke){
+						majorStroke = {color:stroke.color ? stroke.color : "#000000", width:stroke.width ? stroke.width : 0.5};
+						var col = new Color(stroke.color).toRgb();
+						minorStroke = {color:stroke.color ? utils.brightness({r:col[0], g:col[1], b:col[2]},51) : "#000000", width:stroke.width ? stroke.width * 0.6 : 0.3};
+					}
+					return group.createLine({
+						x1: tick.isMinor ? 2 : 0,
+						y1: 0,
+						x2: tick.isMinor ? 8 : 10,
+						y2: 0
+					}).setStroke(tick.isMinor ? minorStroke : majorStroke);
+				};
+			}
+			
+			this._setter(scale, attributes, [originX, originY, radius, startAngle, endAngle, orientation, font, labelPosition, tickShapeFunc]);
+			
+			indicator.set("interactionArea", "gauge");
+			// Needle shape
+			indicator.set("indicatorShapeFunc", function(group, indicator){
+				return group.createPolyline([0, -5, indicator.scale.radius - 6, 0, 0, 5, 0, -5]).setStroke({
+					color: "#333333",
+					width: 0.25
+				}).setFill(scale._gauge.indicatorColor);
+			});
+		}
+	});
+
+	return utils;
+});
diff --git a/dojox/dgauges/tests/gauges/AircraftGauge.js b/dojox/dgauges/tests/gauges/AircraftGauge.js
new file mode 100755
index 0000000..668533a
--- /dev/null
+++ b/dojox/dgauges/tests/gauges/AircraftGauge.js
@@ -0,0 +1,221 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojox/dgauges/CircularGauge", "dojox/dgauges/LinearScaler",
+	"dojox/dgauges/CircularScale", "dojox/dgauges/CircularValueIndicator", "dojox/dgauges/CircularRangeIndicator",
+	"dojox/dgauges/TextIndicator"],
+	function(lang, declare, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, CircularRangeIndicator,
+		 TextIndicator){
+	return declare("dojox.dgauges.tests.gauges.AircraftGauge", CircularGauge, {
+		_radius: 100,
+		constructor: function(){
+			this.font = {
+				family: "Helvetica",
+				style: "normal",
+				size: "10pt",
+				color: "#EFEFEF"
+			};
+			
+			// Draws a triangle, used by 2 indicators
+			var sharedIndicatorShapeFunc = function(group){
+				return group.createPolyline([40, -6, 60, 0, 40, 6, 40, -6]).setFill("#EFEFEF");
+			};
+			
+			// Draws the background
+			this.addElement("background", lang.hitch(this, this.drawBackground));
+			
+			// The left scaler
+			var scaler = new LinearScaler({
+				minimum: 10,
+				maximum: 40,
+				majorTickInterval: 5,
+				minorTickInterval: 1
+			});
+			
+			// The left scale
+			var scale = new CircularScale({
+				scaler: scaler,
+				originX: 100,
+				originY: 100,
+				startAngle: 110,
+				endAngle: 250,
+				radius: 70,
+				labelPosition: "outside",
+				tickShapeFunc: function(group, scale, tick){
+					return group.createLine({
+						x1: tick.isMinor ? 2 : 0,
+						y1: 0,
+						x2: tick.isMinor ? 8 : 12,
+						y2: 0
+					}).setStroke({
+						color: "#EFEFEF",
+						width: tick.isMinor ? 1 : 1
+					})
+				}
+			});
+			this.addElement("scale", scale);
+			
+			// The left value indicator
+			var indicator = new CircularValueIndicator({
+				interactionArea: "indicator",
+				indicatorShapeFunc: sharedIndicatorShapeFunc,
+				value: 27
+			});
+			scale.addIndicator("indicator", indicator);
+			
+			// The left range indicator (green)
+			var rangeIndicator = new CircularRangeIndicator({
+				start: 15,
+				value: 23,
+				radius: 68,
+				fill: "#0BCD2F",
+				interactionMode: "none"
+			});
+			scale.addIndicator("rangeIndicator", rangeIndicator, true);
+			
+			// The right scaler		
+			var scaler2 = new LinearScaler({
+				minimum: 0,
+				maximum: 10,
+				majorTickInterval: 1,
+				minorTickInterval: 0.5
+			});
+			
+			// The right scale
+			var scale2 = new CircularScale({
+				scaler: scaler2,
+				originX: 100,
+				originY: 100,
+				startAngle: 70,
+				endAngle: 290,
+				orientation: "cclockwise",
+				radius: 70,
+				labelPosition: "outside",
+				tickShapeFunc: function(group, scale, tick){
+					var x1, x2, color, width = 1;
+					// Strong red tick
+					if (tick.value == 0.5 || tick.value == 8){
+						x1 = -2;
+						x2 = 14;
+						color = "#FB0F00";
+						width = 2;
+					}else if(tick.isMinor){
+						// minor ticks
+						x1 = 2;
+						x2 = 8;
+							color = "#EFEFEF";
+					}else{
+						// Major tick
+						x1 = 0;
+						x2 = 12;
+						color = "#EFEFEF";
+					}
+					
+					return group.createLine({
+						x1: x1,
+						y1: 0,
+						x2: x2,
+						y2: 0
+					}).setStroke({
+						color: color,
+						width: width
+					})
+				},
+				// Label filter
+				tickLabelFunc: function(tick){
+					return (tick.value % 2) == 0 ? (tick.value).toString() : ""
+				}
+			});
+			this.addElement("scale2", scale2);
+			
+			// The right value indicator
+			var indicator2 = new CircularValueIndicator({
+				interactionArea: "indicator",
+				indicatorShapeFunc: sharedIndicatorShapeFunc,
+				value: 8
+			});
+			scale2.addIndicator("indicator2", indicator2);
+			
+			// The right range indicator (green)
+			var rangeIndicator2 = new CircularRangeIndicator({
+				start: 0.5,
+				value: 8,
+				radius: 68,
+				fill: "#0BCD2F",
+				interactionMode: "none"
+			});
+			scale2.addIndicator("rangeIndicator2", rangeIndicator2, true);
+			
+			// Indicator Text: "MAN"
+			this.addElement("text1", this._createText("MAN", 97, 90, 9, "end"));
+			
+			// Indicator Text: "PRESS"
+			this.addElement("text2", this._createText("PRESS", 97, 100, 9, "end"));
+			
+			// Indicator Text: "IN HG"
+			this.addElement("text3", this._createText("IN HG", 97, 113, 8, "end"));
+			
+			// Indicator Text: "FUEL
+			this.addElement("text4", this._createText("FUEL", 103, 90, 9, "start"));
+			
+			// Indicator Text: "PRESS"
+			this.addElement("text5", this._createText("PRESS", 103, 100, 9, "start"));
+			
+			// Indicator Text: "PSI"
+			this.addElement("text6", this._createText("PSI", 103, 113, 8, "start"));
+		},
+		_createText: function(text, x, y, size, align){
+			return new TextIndicator({
+				value: text,
+				x: x,
+				y: y,
+				color: "white",
+				font: {
+					family: "Helvetica",
+					size: size
+				},
+				align: align
+			});
+		},
+		
+		drawBackground: function(g){
+			var r = this._radius;
+			var w = 2 * r;
+			var h = w;
+			g.createEllipse({
+				cx: r,
+				cy: r,
+				rx: r,
+				ry: r
+			}).setFill("#000000");
+			
+			g.createEllipse({
+				cx: r,
+				cy: r,
+				rx: r * 0.99,
+				ry: r * 0.99
+			}).setFill("#505050");
+			
+			g.createEllipse({
+				cx: r,
+				cy: r,
+				rx: r * 0.92,
+				ry: r * 0.92
+			}).setFill("#333333").setStroke({
+				color: "#000000",
+				width: 0.5
+			});
+			
+			g.createRect({
+				x: 99,
+				y: 20,
+				width: 4,
+				height: 50
+			}).setFill("#EFEFEF");
+			
+			g.createRect({
+				x: 99,
+				y: 130,
+				width: 4,
+				height: 50
+			}).setFill("#EFEFEF");
+		}
+	});
+});
diff --git a/dojox/dgauges/tests/gauges/BulletGraph.js b/dojox/dgauges/tests/gauges/BulletGraph.js
new file mode 100755
index 0000000..9ff83c0
--- /dev/null
+++ b/dojox/dgauges/tests/gauges/BulletGraph.js
@@ -0,0 +1,107 @@
+define(["dojo/_base/declare", "dojox/dgauges/RectangularGauge", "dojox/dgauges/LinearScaler",
+	"dojox/dgauges/RectangularScale", "dojox/dgauges/RectangularValueIndicator",
+	"dojox/dgauges/RectangularRangeIndicator", "dojox/color"],
+	function(declare, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator,
+			 RectangularRangeIndicator, color){
+	return declare("dojox.dgauges.tests.gauges.BulletGraph", RectangularGauge, {
+		target: 50,
+		high: 100,
+		value: 50,
+		medium: 75,
+		low: 50,
+
+		constructor: function(){
+			var scaler = new LinearScaler({
+				maximum: this.high
+			});
+			this._scale = new RectangularScale({
+				scaler: scaler,
+				labelPosition: "trailing",
+				paddingTop: 30,
+				paddingBottom: 23
+			});
+			this.addElement("scale", this._scale);
+
+			var high = new RectangularRangeIndicator({
+				start: 0,
+				value: this.high,
+				interactionMode: "none",
+				fill: color.fromHsv(0, 0, 90),
+				stroke: null,
+				paddingTop: 0,
+				startThickness: 30,
+				endThickness: 30
+			});
+			this._scale.addIndicator("high", high);
+
+			var medium = new RectangularRangeIndicator({
+				start: 0,
+				value: this.medium,
+				interactionMode: "none",
+				fill: color.fromHsv(0, 0, 60),
+				stroke: null,
+				paddingTop: 0,
+				startThickness: 30,
+				endThickness: 30
+			});
+			this._scale.addIndicator("medium", medium);
+
+			var low = new RectangularRangeIndicator({
+				start: 0,
+				value: this.low,
+				interactionMode: "none",
+				fill: color.fromHsv(0, 0, 40),
+				stroke: null,
+				paddingTop: 0,
+				startThickness: 30,
+				endThickness: 30
+			});
+			this._scale.addIndicator("low", low);
+
+			var measure = new RectangularRangeIndicator({
+				start: 0,
+				value: this.value,
+				interactionMode: "none",
+				fill: [0, 0, 0],
+				stroke: null,
+				paddingTop: 10,
+				startThickness: 10,
+				endThickness: 10
+			});
+			this._scale.addIndicator("measure", measure);
+
+			var target = new RectangularValueIndicator({
+				paddingTop: 7,
+				interactionMode: "none",
+				value: this.target
+			});
+			
+			target.indicatorShapeFunc = function(group){
+				return group.createLine({
+					x1: 0,
+					y1: 0,
+					x2: 0,
+					y2: 16
+				}).setStroke({
+					color: "black",
+					width: 3
+				}).setFill([250, 0, 0]);
+			};
+
+			this._scale.addIndicator("target", target);
+
+			this.addInvalidatingProperties(["target", "value", "low", "medium", "high"]);
+		},
+
+		refreshRendering: function(){
+			this.inherited(arguments);
+			
+			this._scale.scaler.set("maximum", this.high);
+			this._scale.getIndicator("target").set("value", this.target);
+			this._scale.getIndicator("measure").set("value", this.value);
+			this._scale.getIndicator("low").set("value", this.low);
+			this._scale.getIndicator("medium").set("value", this.medium);
+			this._scale.getIndicator("high").set("value", this.high);
+		}
+	});
+});
diff --git a/dojox/dgauges/tests/gauges/SimpleCircularGauge.js b/dojox/dgauges/tests/gauges/SimpleCircularGauge.js
new file mode 100755
index 0000000..7475b7f
--- /dev/null
+++ b/dojox/dgauges/tests/gauges/SimpleCircularGauge.js
@@ -0,0 +1,87 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojox/dgauges/CircularGauge", "dojox/dgauges/LinearScaler",
+	"dojox/dgauges/CircularScale", "dojox/dgauges/CircularValueIndicator", "dojox/dgauges/CircularRangeIndicator",
+	"dojox/dgauges/TextIndicator"],
+	function(lang, declare, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, CircularRangeIndicator,
+		 TextIndicator){
+	return declare("dojox.dgauges.tests.gauges.SimpleCircularGauge", CircularGauge, {
+		constructor: function(){
+
+			// Changes the font
+			this.font = {
+				family: "Helvetica",
+				style: "normal",
+				size: "10pt",
+				color: "white"
+			};
+			
+			// Draws the background
+			this.addElement("background", function(g){
+				g.createEllipse({
+					cx: 100,
+					cy: 100,
+					rx: 100,
+					ry: 100
+				}).setFill("#444444");
+			});
+			
+			// The scaler
+			var scaler = new LinearScaler({
+				minimum: -100,
+				maximum: 100,
+				majorTickInterval: 20,
+				minorTickInterval: 5
+			});
+			
+			// The scale
+			var scale = new CircularScale({
+				scaler: scaler,
+				originX: 100,
+				originY: 100,
+				startAngle: 110,
+				endAngle: 70,
+				radius: 75,
+				labelPosition: "outside",
+				tickShapeFunc: function(group, scale, tick){
+					return group.createLine({
+						x1: tick.isMinor ? 2 : 0,
+						y1: 0,
+						x2: tick.isMinor ? 8 : 12,
+						y2: 0
+					}).setStroke({
+						color: tick.isMinor ? "black" : "white",
+						width: tick.isMinor ? 0.5 : 1
+					})
+				}
+			});
+			this.addElement("scale", scale);
+			
+			// A value indicator
+			var indicator = new CircularValueIndicator({
+				interactionArea: "indicator",
+				indicatorShapeFunc: function(group){
+					return group.createPolyline([20, -6, 60, 0, 20, 6, 20, -6]).setFill("black").setStroke("white");
+				},
+				value: 50
+			});
+			scale.addIndicator("indicator", indicator);
+			
+			// A green range indicator
+			var rangeIndicator = new CircularRangeIndicator({
+				start: 0,
+				value: 100,
+				radius: 62,
+				startThickness:10,
+				endThickness: 30,
+				fill: "green",
+				interactionMode: "none"
+			});
+			scale.addIndicator("rangeIndicator", rangeIndicator, true);
+			
+			
+			// Indicator Text"
+			this.addElement("text", new TextIndicator({
+				value: "G", x:100, y:100
+			}));
+		}	
+	});
+});
diff --git a/dojox/dgauges/tests/gauges/SimpleRectangularGauge.js b/dojox/dgauges/tests/gauges/SimpleRectangularGauge.js
new file mode 100755
index 0000000..923f760
--- /dev/null
+++ b/dojox/dgauges/tests/gauges/SimpleRectangularGauge.js
@@ -0,0 +1,120 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojox/dgauges/RectangularGauge", "dojox/dgauges/LinearScaler",
+	"dojox/dgauges/RectangularScale", "dojox/dgauges/RectangularValueIndicator",
+	"dojox/dgauges/RectangularRangeIndicator", "dojox/dgauges/TextIndicator"],
+	function(lang, declare, RectangularGauge, LinearScaler, RectangularScale, RectangularValueIndicator,
+			 RectangularRangeIndicator, TextIndicator){
+	return declare("dojox.dgauges.tests.gauges.SimpleRectangularGauge", RectangularGauge, {
+		constructor: function(){
+			// Draw background
+			this.addElement("background", function(g, w){
+				return g.createRect({
+					x: 1,
+					y: 1,
+					width: w - 2,
+					height: 50,
+					r: 3
+				}).setFill("#CBCBCB").setStroke({
+					color: "black",
+					width: 2
+				});
+			});
+			
+			this.addElement("leadingArea", function(g, w){
+				return g.createRect({
+					x: 1,
+					y: 1,
+					width: 60,
+					height: 50,
+					r: 3
+				}).setFill("#ABABAB").setStroke({
+					color: "black",
+					width: 2
+				});
+			}, "leading");
+			
+			this.addElement("trailingArea", function(g, w){
+				// A spacer to take into account the width of the stroke on the right;
+				g.createLine({
+					x2: 62
+				});
+				return g.createRect({
+					x: 1,
+					y: 1,
+					width: 60,
+					height: 50,
+					r: 3
+				}).setFill("#ABABAB").setStroke({
+					color: "black",
+					width: 2
+				});
+			}, "trailing");
+			
+			// Scale
+			var scale = new RectangularScale({
+				scaler: new LinearScaler({
+					minimum: -100
+				}),
+				labelPosition: "trailing",
+				paddingTop: 15
+
+			});
+			this.addElement("scale", scale);
+			
+			// Value indicator
+			var indicator = new RectangularValueIndicator();
+			indicator.indicatorShapeFunc = lang.hitch(this, function(group){
+				group.createPolyline([-5, 0, 5, 0, 0, 10, -5, 0]).setFill("black");
+				return group;
+			});
+			indicator.set("paddingTop", 5);
+			indicator.set("interactionArea", "gauge");
+			scale.addIndicator("indicator", indicator);
+			
+			// Indicator Text
+			var trailingText = new TextIndicator({
+				x: 30,
+				y: 30,
+				indicator: indicator,
+				labelFunc: function(v){
+					return v + " °C"
+				}
+			});
+			
+			this.addElement("trailingText", trailingText, "trailing");
+			var leadingText = new TextIndicator({
+				x: 30,
+				y: 30,
+				indicator: indicator,
+				labelFunc: function(v){
+					return ((9 / 5) * v + 32).toFixed() + " °F"
+				}
+			});
+			this.addElement("leadingText", leadingText, "leading");
+			
+			scale.addIndicator("gradientIndicator", new RectangularRangeIndicator({
+				start: -100,
+				value: 100,
+				paddingTop: 15,
+				stroke: null,
+				fill: {
+					type: "linear",
+					x1: 0,
+					y1: 0,
+					x2: 1,
+					y2: 0,
+					colors: [{
+						color: "#7FB2F0",
+						offset: 0
+					}, {
+						color: "#FFFFFF",
+						offset: .5
+					}, {
+						color: "#F03221",
+						offset: 1
+					}]
+				}
+			}), true);
+			
+		}
+	});
+});
diff --git a/dojox/dgauges/tests/gauges/SimpleSemiCircularGauge.js b/dojox/dgauges/tests/gauges/SimpleSemiCircularGauge.js
new file mode 100644
index 0000000..6869deb
--- /dev/null
+++ b/dojox/dgauges/tests/gauges/SimpleSemiCircularGauge.js
@@ -0,0 +1,108 @@
+define(["dojo/_base/lang", "dojo/_base/declare", "dojox/dgauges/CircularGauge", "dojox/dgauges/LinearScaler",
+	"dojox/dgauges/CircularScale", "dojox/dgauges/CircularValueIndicator", "dojox/dgauges/CircularRangeIndicator",
+	"dojox/dgauges/TextIndicator"],
+	function(lang, declare, CircularGauge, LinearScaler, CircularScale, CircularValueIndicator, CircularRangeIndicator,
+			 TextIndicator){
+
+		return declare("dojox.dgauges.tests.gauges.SimpleSemiCircularGauge", CircularGauge, {
+			constructor: function(){
+				// Changes the font
+				this.font = {
+					family: "Helvetica",
+					style: "normal",
+					size: "10pt",
+					color: "black"
+				};
+
+				// Draws a transparent bounding box
+				this.addElement("background", function(g){
+					g.createRect({
+						width: 200,
+						height: 100
+					});
+				});
+
+				// The scaler
+				var scaler = new LinearScaler({
+					minimum: 0,
+					maximum: 100
+				});
+
+				// The scale
+				var scale = new CircularScale({
+					scaler: scaler,
+					originX: 100,
+					originY: 85,
+					startAngle: 180,
+					endAngle: 0,
+					tickLabelFunc: function(){return null;},
+					tickShapeFunc: function(){return null;}
+				});
+				this.addElement("scale", scale);
+
+				// The background range indicator
+				var backgroundRange = new CircularRangeIndicator({
+					start: 0,
+					value: 100,
+					radius: 85,
+					startThickness:30,
+					endThickness: 30,
+					fill:{
+						type: "radial",
+						cx: 100,
+						cy: 85,
+						colors: [
+							{ offset: 0,   color: "black" },
+							{ offset: 0.8, color: "#FAFAFA" },
+							{ offset: 1,   color: "#AAAAAA" }
+						]
+					},
+					stroke: null,
+					interactionMode: "none"
+				});
+				scale.addIndicator("backgroundIndicator", backgroundRange);
+
+				// The value range indicator
+				var rangeIndicator = new CircularRangeIndicator({
+					start: 0,
+					value: 65,
+					radius: 85,
+					startThickness:30,
+					endThickness: 30,
+					fill:{
+						type: "radial",
+						cx: 100,
+						cy: 85,
+						rx: 85,
+						ry: 85,
+						colors: [
+							{ offset: 0,   color: "FF0000" },
+							{ offset: 0.8, color: "red" },
+							{ offset: 1,   color: "#FFFAFA" }
+						]
+					},
+					stroke: null,
+					interactionMode: "mouse"
+				});
+				scale.addIndicator("rangeIndicator", rangeIndicator);
+
+
+				// Labels
+				this.addElement("text", new TextIndicator({
+					indicator: rangeIndicator, x:100, y:75, font: {family: "Helvetica", color: "black", size:"16pt"}
+				}));
+
+				this.addElement("text2", new TextIndicator({
+					value: "units", x:100, y:82, fill: "#CECECE", font: {family: "Helvetica", color: "#CECECE", size:"5pt"}
+				}));
+
+				this.addElement("text3", new TextIndicator({
+					value: "0", x:30, y:97
+				}));
+
+				this.addElement("text4", new TextIndicator({
+					value: "100", x:170, y:97
+				}));
+			}
+		});
+	});
diff --git a/dojox/dgauges/tests/style.css b/dojox/dgauges/tests/style.css
new file mode 100755
index 0000000..d48254f
--- /dev/null
+++ b/dojox/dgauges/tests/style.css
@@ -0,0 +1,2 @@
+ body, html { width:100%; height:100%; margin:0; padding:0; overflow:hidden; }
+#borderContainer { width: 100%; height: 100%;}
diff --git a/dojox/dgauges/tests/test_AircraftGauge.html b/dojox/dgauges/tests/test_AircraftGauge.html
new file mode 100755
index 0000000..8780ba9
--- /dev/null
+++ b/dojox/dgauges/tests/test_AircraftGauge.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+	<title>Aircraft Gauge</title>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/themes/claro/claro.css";
+		@import "style.css";
+	</style>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, async: true">
+	</script>
+	<script type="text/javascript">
+		require(["dojo/_base/kernel", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
+			"dojox/dgauges/tests/gauges/AircraftGauge"]);
+	</script>
+	</head>
+	<body class="claro">
+	<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+		<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #FFFFFF;" splitter="true" region="center">
+			<div id="g1" data-dojo-type="dojox.dgauges.tests.gauges.AircraftGauge"></div>
+		</div>
+	</div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/dgauges/tests/test_Black_CircularLinearGauge.html b/dojox/dgauges/tests/test_Black_CircularLinearGauge.html
new file mode 100755
index 0000000..31c25c4
--- /dev/null
+++ b/dojox/dgauges/tests/test_Black_CircularLinearGauge.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>CircularLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+	  			"dojox/dgauges/components/black/CircularLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+				<div id="g1" data-dojo-type="dojox.dgauges.components.black.CircularLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Black_HorizontalLinearGauge.html b/dojox/dgauges/tests/test_Black_HorizontalLinearGauge.html
new file mode 100755
index 0000000..1029111
--- /dev/null
+++ b/dojox/dgauges/tests/test_Black_HorizontalLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>HorizontalLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/components/black/HorizontalLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+			<div id="g1" data-dojo-type="dojox.dgauges.components.black.HorizontalLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Black_SemiCircularLinearGauge.html b/dojox/dgauges/tests/test_Black_SemiCircularLinearGauge.html
new file mode 100755
index 0000000..feb107b
--- /dev/null
+++ b/dojox/dgauges/tests/test_Black_SemiCircularLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>SemiCircularLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/components/black/SemiCircularLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+			<div id="g1" data-dojo-type="dojox.dgauges.components.black.SemiCircularLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Black_VerticalLinearGauge.html b/dojox/dgauges/tests/test_Black_VerticalLinearGauge.html
new file mode 100755
index 0000000..af6f83d
--- /dev/null
+++ b/dojox/dgauges/tests/test_Black_VerticalLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>VerticalLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+      			"dojox/dgauges/components/black/VerticalLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+        		<div id="g1" data-dojo-type="dojox.dgauges.components.black.VerticalLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_BulletGraph.html b/dojox/dgauges/tests/test_BulletGraph.html
new file mode 100755
index 0000000..7003120
--- /dev/null
+++ b/dojox/dgauges/tests/test_BulletGraph.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+	<title>Bullet Graph</title>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/themes/claro/claro.css";
+		@import "style.css";
+	</style>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, async: true">
+	</script>
+	<script type="text/javascript">
+		require(["dojo/_base/kernel", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
+			"dojox/dgauges/tests/gauges/BulletGraph"]);
+	</script>
+	</head>
+	<body class="claro">
+	<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+		<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+			<div id="g1" data-dojo-type="dojox.dgauges.tests.gauges.BulletGraph" style="height:60px"></div>
+			<div id="g2" data-dojo-type="dojox.dgauges.tests.gauges.BulletGraph" style="height:60px" value="270" target="260" low="200" medium="250" high="300"></div>
+		</div>
+	</div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/dgauges/tests/test_Classic_CircularLinearGauge.html b/dojox/dgauges/tests/test_Classic_CircularLinearGauge.html
new file mode 100755
index 0000000..6e2858d
--- /dev/null
+++ b/dojox/dgauges/tests/test_Classic_CircularLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>CircularLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/components/classic/CircularLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+				<div id="g1" data-dojo-type="dojox.dgauges.components.classic.CircularLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Classic_HorizontalLinearGauge.html b/dojox/dgauges/tests/test_Classic_HorizontalLinearGauge.html
new file mode 100755
index 0000000..3f9b86f
--- /dev/null
+++ b/dojox/dgauges/tests/test_Classic_HorizontalLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>HorizontalLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/components/classic/HorizontalLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+			<div id="g1" data-dojo-type="dojox.dgauges.components.classic.HorizontalLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Classic_SemiCircularLinearGauge.html b/dojox/dgauges/tests/test_Classic_SemiCircularLinearGauge.html
new file mode 100755
index 0000000..72d8150
--- /dev/null
+++ b/dojox/dgauges/tests/test_Classic_SemiCircularLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>SemiCircularLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/components/classic/SemiCircularLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+				<div id="g1" data-dojo-type="dojox.dgauges.components.classic.SemiCircularLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Classic_VerticalLinearGauge.html b/dojox/dgauges/tests/test_Classic_VerticalLinearGauge.html
new file mode 100755
index 0000000..8752849
--- /dev/null
+++ b/dojox/dgauges/tests/test_Classic_VerticalLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>VerticalLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/components/classic/VerticalLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+			<div id="g1" data-dojo-type="dojox.dgauges.components.classic.VerticalLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Default_CircularLinearGauge.html b/dojox/dgauges/tests/test_Default_CircularLinearGauge.html
new file mode 100755
index 0000000..d92a787
--- /dev/null
+++ b/dojox/dgauges/tests/test_Default_CircularLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>CircularLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/components/default/CircularLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+				<div id="g1" data-dojo-type="dojox.dgauges.components.default.CircularLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Default_SemiCircularLinearGauge.html b/dojox/dgauges/tests/test_Default_SemiCircularLinearGauge.html
new file mode 100755
index 0000000..f0df5d5
--- /dev/null
+++ b/dojox/dgauges/tests/test_Default_SemiCircularLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>CircularLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/components/default/SemiCircularLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+				<div id="g1" data-dojo-type="dojox.dgauges.components.default.SemiCircularLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Green_CircularLinearGauge.html b/dojox/dgauges/tests/test_Green_CircularLinearGauge.html
new file mode 100755
index 0000000..55efa2d
--- /dev/null
+++ b/dojox/dgauges/tests/test_Green_CircularLinearGauge.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>CircularLinearGauge</title> 
+	    <style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+      			"dojox/dgauges/components/green/CircularLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+        		<div id="g1" data-dojo-type="dojox.dgauges.components.green.CircularLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Green_HorizontalLinearGauge.html b/dojox/dgauges/tests/test_Green_HorizontalLinearGauge.html
new file mode 100755
index 0000000..eccfce1
--- /dev/null
+++ b/dojox/dgauges/tests/test_Green_HorizontalLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>HorizontalLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/components/green/HorizontalLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+			<div id="g1" data-dojo-type="dojox.dgauges.components.green.HorizontalLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Green_SemiCircularLinearGauge.html b/dojox/dgauges/tests/test_Green_SemiCircularLinearGauge.html
new file mode 100755
index 0000000..d2d097b
--- /dev/null
+++ b/dojox/dgauges/tests/test_Green_SemiCircularLinearGauge.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>SemiCircularLinearGauge</title> 
+	    <style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+      			"dojox/dgauges/components/green/SemiCircularLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+        		<div id="g1" data-dojo-type="dojox.dgauges.components.green.SemiCircularLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Green_VerticalLinearGauge.html b/dojox/dgauges/tests/test_Green_VerticalLinearGauge.html
new file mode 100755
index 0000000..6fe90c7
--- /dev/null
+++ b/dojox/dgauges/tests/test_Green_VerticalLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>VerticalLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+      			"dojox/dgauges/components/green/VerticalLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+        		<div id="g1" data-dojo-type="dojox.dgauges.components.green.VerticalLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Grey_CircularLinearGauge.html b/dojox/dgauges/tests/test_Grey_CircularLinearGauge.html
new file mode 100755
index 0000000..f12b950
--- /dev/null
+++ b/dojox/dgauges/tests/test_Grey_CircularLinearGauge.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>CircularLinearGauge</title> 
+	    <style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+      			"dojox/dgauges/components/grey/CircularLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+        		<div id="g1" data-dojo-type="dojox.dgauges.components.grey.CircularLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Grey_HorizontalLinearGauge.html b/dojox/dgauges/tests/test_Grey_HorizontalLinearGauge.html
new file mode 100755
index 0000000..bfbf637
--- /dev/null
+++ b/dojox/dgauges/tests/test_Grey_HorizontalLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>HorizontalLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/components/grey/HorizontalLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+			<div id="g1" data-dojo-type="dojox.dgauges.components.grey.HorizontalLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Grey_SemiCircularLinearGauge.html b/dojox/dgauges/tests/test_Grey_SemiCircularLinearGauge.html
new file mode 100755
index 0000000..7f67f23
--- /dev/null
+++ b/dojox/dgauges/tests/test_Grey_SemiCircularLinearGauge.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>SemiCircularLinearGauge</title> 
+	    <style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+      			"dojox/dgauges/components/grey/SemiCircularLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+        		<div id="g1" data-dojo-type="dojox.dgauges.components.grey.SemiCircularLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_Grey_VerticalLinearGauge.html b/dojox/dgauges/tests/test_Grey_VerticalLinearGauge.html
new file mode 100755
index 0000000..dead4d4
--- /dev/null
+++ b/dojox/dgauges/tests/test_Grey_VerticalLinearGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+    	<title>VerticalLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+      			"dojox/dgauges/components/grey/VerticalLinearGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+        		<div id="g1" data-dojo-type="dojox.dgauges.components.grey.VerticalLinearGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_SimpleCircularGauge.html b/dojox/dgauges/tests/test_SimpleCircularGauge.html
new file mode 100755
index 0000000..c5313e8
--- /dev/null
+++ b/dojox/dgauges/tests/test_SimpleCircularGauge.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>CircularLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/tests/gauges/SimpleCircularGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+				<div id="g1" data-dojo-type="dojox.dgauges.tests.gauges.SimpleCircularGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_SimpleRectangularGauge.html b/dojox/dgauges/tests/test_SimpleRectangularGauge.html
new file mode 100755
index 0000000..b577aee
--- /dev/null
+++ b/dojox/dgauges/tests/test_SimpleRectangularGauge.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>RectangularLinearGauge</title> 
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/_base/kernel", 
+				"dojo/parser", 
+				"dijit/layout/BorderContainer", 
+				"dijit/layout/ContentPane", 
+				"dojox/dgauges/tests/gauges/SimpleRectangularGauge"
+			]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+				<div id="g1" data-dojo-type="dojox.dgauges.tests.gauges.SimpleRectangularGauge"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_SimpleSemiCircularGauge.html b/dojox/dgauges/tests/test_SimpleSemiCircularGauge.html
new file mode 100644
index 0000000..4251d9f
--- /dev/null
+++ b/dojox/dgauges/tests/test_SimpleSemiCircularGauge.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>CircularLinearGauge</title>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/themes/claro/claro.css";
+		@import "style.css";
+	</style>
+	<script type="text/javascript">
+		var djConfig = {
+			parseOnLoad: true,
+			async: true
+		}
+	</script>
+	<script type="text/javascript" src="../../../dojo/dojo.js">
+	</script>
+	<script type="text/javascript">
+		require([
+			"dojo/_base/kernel",
+			"dojo/parser",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dojox/dgauges/tests/gauges/SimpleSemiCircularGauge"
+		]);
+	</script>
+</head>
+<body class="claro">
+<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+	<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+		<div id="g1" data-dojo-type="dojox.dgauges.tests.gauges.SimpleSemiCircularGauge"></div>
+	</div>
+</div>
+</body>
+</html>
diff --git a/dojox/dgauges/tests/test_all.html b/dojox/dgauges/tests/test_all.html
new file mode 100755
index 0000000..07a1328
--- /dev/null
+++ b/dojox/dgauges/tests/test_all.html
@@ -0,0 +1,150 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Gauges Gallery</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+		<script type="text/javascript">
+			require(["dojo/_base/kernel", 
+					 "dojo/parser", 
+					 "dijit/layout/TabContainer", 
+					 "dijit/layout/BorderContainer", 
+					 "dijit/layout/ContentPane", 
+					 "dojox/dgauges/components/default/CircularLinearGauge",
+					 "dojox/dgauges/components/default/SemiCircularLinearGauge",
+					 "dojox/dgauges/components/default/HorizontalLinearGauge",
+					 "dojox/dgauges/components/default/VerticalLinearGauge",
+					 "dojox/dgauges/components/black/CircularLinearGauge",
+					 "dojox/dgauges/components/black/SemiCircularLinearGauge",
+					 "dojox/dgauges/components/black/HorizontalLinearGauge",
+					 "dojox/dgauges/components/black/VerticalLinearGauge",
+					 "dojox/dgauges/components/classic/CircularLinearGauge",
+					 "dojox/dgauges/components/classic/SemiCircularLinearGauge",
+					 "dojox/dgauges/components/classic/HorizontalLinearGauge",
+					 "dojox/dgauges/components/classic/VerticalLinearGauge",
+					 "dojox/dgauges/components/green/CircularLinearGauge",
+					 "dojox/dgauges/components/green/SemiCircularLinearGauge",
+					 "dojox/dgauges/components/green/HorizontalLinearGauge",
+					 "dojox/dgauges/components/green/VerticalLinearGauge",
+					 "dojox/dgauges/components/grey/CircularLinearGauge",
+					 "dojox/dgauges/components/grey/SemiCircularLinearGauge",
+					 "dojox/dgauges/components/grey/HorizontalLinearGauge",
+					 "dojox/dgauges/components/grey/VerticalLinearGauge"]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.TabContainer" id="tabContainer" style="width:600px; height:400px">
+			<div data-dojo-type="dijit.layout.ContentPane" title="Default">
+				<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true">
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+						<div data-dojo-type="dojox.dgauges.components.default.CircularLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; width:200px" splitter="true" region="left">
+						<div data-dojo-type="dojox.dgauges.components.default.SemiCircularLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; width:52px" splitter="true" region="right">
+						<div data-dojo-type="dojox.dgauges.components.default.VerticalLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; height:52px" splitter="true" region="bottom">
+						<div data-dojo-type="dojox.dgauges.components.default.HorizontalLinearGauge">
+						</div>
+					</div>
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" title="Black">
+				<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true">
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+						<div data-dojo-type="dojox.dgauges.components.black.CircularLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; width:200px" splitter="true" region="left">
+						<div data-dojo-type="dojox.dgauges.components.black.SemiCircularLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; width:52px" splitter="true" region="right">
+						<div data-dojo-type="dojox.dgauges.components.black.VerticalLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; height:52px" splitter="true" region="bottom">
+						<div data-dojo-type="dojox.dgauges.components.black.HorizontalLinearGauge">
+						</div>
+					</div>
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" title="Classic">
+				<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true">
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+						<div data-dojo-type="dojox.dgauges.components.classic.CircularLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; width:200px" splitter="true" region="left">
+						<div data-dojo-type="dojox.dgauges.components.classic.SemiCircularLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; width:52px" splitter="true" region="right">
+				    <div data-dojo-type="dojox.dgauges.components.classic.VerticalLinearGauge">
+						</div>
+          </div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; height:52px" splitter="true" region="bottom">
+				    <div data-dojo-type="dojox.dgauges.components.classic.HorizontalLinearGauge">
+						</div>
+          </div>
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" title="Green">
+				<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true">
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+						<div data-dojo-type="dojox.dgauges.components.green.CircularLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; width:200px" splitter="true" region="left">
+						<div data-dojo-type="dojox.dgauges.components.green.SemiCircularLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; width:52px" splitter="true" region="right">
+						<div data-dojo-type="dojox.dgauges.components.green.VerticalLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; height:52px" splitter="true" region="bottom">
+						<div data-dojo-type="dojox.dgauges.components.green.HorizontalLinearGauge">
+						</div>
+					</div>
+				</div>
+			</div>			
+			<div data-dojo-type="dijit.layout.ContentPane" title="Grey">
+				<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true">
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+						<div data-dojo-type="dojox.dgauges.components.grey.CircularLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; width:200px" splitter="true" region="left">
+						<div data-dojo-type="dojox.dgauges.components.grey.SemiCircularLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; width:52px" splitter="true" region="right">
+						<div data-dojo-type="dojox.dgauges.components.grey.VerticalLinearGauge">
+						</div>
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; height:52px" splitter="true" region="bottom">
+						<div data-dojo-type="dojox.dgauges.components.grey.HorizontalLinearGauge">
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_circular_gauge.html b/dojox/dgauges/tests/test_circular_gauge.html
new file mode 100755
index 0000000..8f488cd
--- /dev/null
+++ b/dojox/dgauges/tests/test_circular_gauge.html
@@ -0,0 +1,199 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Dojo Gauge Test</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+		<script type="text/javascript">
+			require(["dojo/on", "dojo/_base/kernel", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojox/dgauges/components/default/CircularLinearGauge", "dojox/dgauges/components/default/SemiCircularLinearGauge", "dojox/dgauges/CircularRangeIndicator", "dijit/form/Button"]);
+		</script>
+	</head>
+	<body class="claro">
+		<div data-dojo-type="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+				<div id="g1" data-dojo-type="dojox.dgauges.components.default.CircularLinearGauge">
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" style="background-color: #fafafa; width:800px" splitter="true" region="right">
+				<div id="g2" data-dojo-type="dojox.dgauges.components.default.SemiCircularLinearGauge">
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" splitter="true" region="top" style="height:30;">
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Set 15
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								registry.byId("g1").set("value", 15);
+								registry.byId("g2").set("value", 15);
+							}
+						);
+					</script>
+				</button>
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Alert current values
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								alert(registry.byId("g1").get("value") + " and " + registry.byId("g2").get("value"));
+							}
+						);
+					</script>
+				</button>
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Change Scale Props.
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								var gauge = registry.byId("g1");
+								gauge.getElement("scale").set("startAngle", 0);
+								gauge.getElement("scale").set("endAngle", 180);
+								gauge.getElement("scale").set("orientation", "cclockwise");
+							}
+						);
+					</script>
+				</button>
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Change tick stroke
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								var gauge = registry.byId("g1");
+								gauge.getElement("scale").set("tickStroke", {color:"#999999", width:1});
+							}
+						);
+					</script>
+				</button>				
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Change Scaler Props.
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								var gauge = registry.byId("g1");
+								gauge.getElement("scale").scaler.set("minorTicksEnabled", false);
+								gauge.getElement("scale").scaler.set("minimum", 50);
+								gauge.getElement("scale").scaler.set("maximum", 250);
+								gauge.getElement("scale").scaler.set("majorTickInterval", 20);
+							}
+						);
+					</script>
+				</button>
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Add range indicator
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								var gauge = registry.byId("g1");
+								var ri = new dojox.dgauges.CircularRangeIndicator();
+								ri.set("start", 60);
+								ri.set("value", 100);
+								ri.set("radius", 60);
+								gauge.getElement("scale").addIndicator("ri", ri, false);
+							}
+						);
+					</script>
+				</button>
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Change needle
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								var gauge = registry.byId("g1");
+								gauge.getElement("scale").getIndicator("indicator").set("indicatorShapeFunc", 
+									function(group, indicator){
+										return group.createPolyline([0, -5, indicator.scale.radius - 2, 0, 0, 5, 0, -5]).setStroke({
+											color: "#333333", 
+											width: 0.25}).setFill([0, 0, 220]);
+									});  
+							}
+						); 
+					</script>
+				</button>
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Remove needle
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								var gauge = registry.byId("g1");
+								gauge.getElement("scale").removeIndicator("indicator");
+							}
+						);
+					</script>
+				</button>
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Listen for events
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								var gauge = registry.byId("g1");
+								gauge.on("startEditing", function(event){console.log(event.indicator.value);});
+								gauge.on("endEditing", function(event){console.log(event.indicator.value);});
+							}
+						);
+					</script>
+				</button>
+				<button data-dojo-type="dijit.form.Button" type="button">
+					No interaction
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								var gauge = registry.byId("g1");
+								gauge.getElement("scale").getIndicator("indicator").set("interactionMode", "none");
+							}
+						);
+					</script>
+				</button>
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Indicator interaction
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								var gauge = registry.byId("g1");
+								gauge.getElement("scale").getIndicator("indicator").set("interactionMode", "mouse"); 
+								gauge.getElement("scale").getIndicator("indicator").set("interactionArea", "indicator");
+							}
+						);
+					</script>
+				</button>
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Gauge interaction
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								var gauge = registry.byId("g1");
+								gauge.getElement("scale").getIndicator("indicator").set("interactionMode", "mouse"); 
+								gauge.getElement("scale").getIndicator("indicator").set("interactionArea", "gauge");
+							}
+						);
+					</script>
+				</button>
+				<button data-dojo-type="dijit.form.Button" type="button">
+					Change background colors
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+						require(["dijit/registry"],
+							function(registry) {
+								var gauge = registry.byId("g1");
+								gauge.set("borderColor", "#FF7800");
+								gauge.set("fillColor", "#FFFF00");
+								gauge = registry.byId("g2"); 
+								gauge.set("borderColor", "#FF7800");
+								gauge.set("fillColor", "#FFFF00");
+							}
+						);
+					</script>
+				</button>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_horizontal_gauge.html b/dojox/dgauges/tests/test_horizontal_gauge.html
new file mode 100755
index 0000000..c7a64f7
--- /dev/null
+++ b/dojox/dgauges/tests/test_horizontal_gauge.html
@@ -0,0 +1,40 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Dojo Gauge Test</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "style.css";
+		</style>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+
+		<script type="text/javascript">
+			require(["dojo/_base/kernel", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojox/dgauges/components/default/HorizontalLinearGauge", "dijit/form/Button",
+			"dojox/dgauges/components/default/VerticalLinearGauge"]);
+		</script>
+	</head>
+	<body class="claro">
+		<div dojoType="dijit.layout.BorderContainer" gutters="true" liveSplitters="true" id="borderContainer">
+			<div dojoType="dijit.layout.ContentPane" style="background-color: #fafafa;" splitter="true" region="center">
+				<div id="g1" dojoType="dojox.dgauges.components.default.HorizontalLinearGauge">
+				</div>
+			</div>
+			<div dojoType="dijit.layout.ContentPane" style="background-color: #fafafa; width:80px" splitter="true" region="left">
+				<div id="g3" dojoType="dojox.dgauges.components.default.VerticalLinearGauge">
+				</div>
+			</div>
+			<div dojoType="dijit.layout.ContentPane" style="background-color: #fafafa; width:50%" splitter="true" region="right">
+				<div id="g2" dojoType="dojox.dgauges.components.default.HorizontalLinearGauge">
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_mobile.html b/dojox/dgauges/tests/test_mobile.html
new file mode 100755
index 0000000..b71e90b
--- /dev/null
+++ b/dojox/dgauges/tests/test_mobile.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Gauge Mobile Sample</title>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+		<script language="JavaScript" type="text/javascript">
+			require(["dojox/mobile", "dojox/mobile/parser", "dojox/mobile/compat", "dojox/mobile/deviceTheme", 
+			"dojox/dgauges/components/default/CircularLinearGauge",
+			"dojox/dgauges/components/default/SemiCircularLinearGauge",
+			"dojox/dgauges/components/default/VerticalLinearGauge",
+			"dojox/dgauges/components/default/HorizontalLinearGauge",
+			"dojox/dgauges/components/black/CircularLinearGauge",
+			"dojox/dgauges/components/black/SemiCircularLinearGauge",
+			"dojox/dgauges/components/black/VerticalLinearGauge",
+			"dojox/dgauges/components/black/HorizontalLinearGauge",
+			"dojox/dgauges/components/green/CircularLinearGauge",
+			"dojox/dgauges/components/green/SemiCircularLinearGauge",
+			"dojox/dgauges/components/green/VerticalLinearGauge",
+			"dojox/dgauges/components/green/HorizontalLinearGauge",
+			"dojox/dgauges/components/grey/CircularLinearGauge",
+			"dojox/dgauges/components/grey/SemiCircularLinearGauge",
+			"dojox/dgauges/components/grey/VerticalLinearGauge",
+			"dojox/dgauges/components/grey/HorizontalLinearGauge",
+			"dojox/dgauges/components/classic/CircularLinearGauge",
+			"dojox/dgauges/components/classic/SemiCircularLinearGauge",
+			"dojox/dgauges/components/classic/VerticalLinearGauge",
+			"dojox/dgauges/components/classic/HorizontalLinearGauge"]);
+		</script>
+	</head>
+	<body style="-webkit-user-select: none; outline: none; visibility:hidden;">
+
+		<div id="home" data-dojo-type="dojox.mobile.View" selected="true">
+			<h1 data-dojo-type="dojox.mobile.Heading">Gauges</h1>
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Gauges Themes</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem" moveTo="defaultGauges" transition="slide">
+					Default 
+				</li>
+				<li class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem" moveTo="classicGauges" transition="slide">
+					Classic 
+				</li>
+				<li class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem" moveTo="blackGauges" transition="slide">
+					Black
+				</li>
+				<li class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem" moveTo="greyGauges" transition="slide">
+					Grey 
+				</li>
+				<li class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem" moveTo="greenGauges" transition="slide">
+					Green 
+				</li>
+			</ul>
+		</div>
+
+		<div id="defaultGauges" data-dojo-type="dojox.mobile.View">
+			<h1 data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="#home">Default Theme</h1>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.default.CircularLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:200px"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.default.SemiCircularLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:150px;"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.default.HorizontalLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:50px;"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.default.VerticalLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:300px;"></div>
+		</div>
+		<div id="classicGauges" data-dojo-type="dojox.mobile.View">
+			<h1 data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="#home">Classic Theme</h1>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.classic.CircularLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:200px"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.classic.SemiCircularLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:150px;"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.classic.HorizontalLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:50px;"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.classic.VerticalLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:300px;"></div>
+		</div>
+		<div id="blackGauges" data-dojo-type="dojox.mobile.View">
+			<h1 data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="#home">Black Theme</h1>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.black.CircularLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:200px"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.black.SemiCircularLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:150px;"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.black.HorizontalLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:50px;"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.black.VerticalLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:300px;"></div>
+		</div>
+		<div id="greyGauges" data-dojo-type="dojox.mobile.View">
+			<h1 data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="#home">Grey Theme</h1>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.grey.CircularLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:200px"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.grey.SemiCircularLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:150px;"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.grey.HorizontalLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:50px;"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.grey.VerticalLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:300px;"></div>
+		</div>
+		<div id="greenGauges" data-dojo-type="dojox.mobile.View">
+			<h1 data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="#home">Green Theme</h1>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.green.CircularLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:200px"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.green.SemiCircularLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:150px;"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.green.HorizontalLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:50px;"></div>
+			<br/>
+			<div data-dojo-type="dojox.dgauges.components.green.VerticalLinearGauge" interactionMode="touch" style="-webkit-user-select: none; outline: none; height:300px;"></div>
+		</div>			
+	</body>
+</html>
diff --git a/dojox/dgauges/tests/test_programmatic.html b/dojox/dgauges/tests/test_programmatic.html
new file mode 100644
index 0000000..d4142b8
--- /dev/null
+++ b/dojox/dgauges/tests/test_programmatic.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Programmatic Gauges</title>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad: true,
+				async: true
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js">
+		</script>
+		<script type="text/javascript">
+			require([
+						"dojo/ready", 
+						"dojo/dom",
+						"dojox/dgauges/components/black/CircularLinearGauge", 
+						"dojox/dgauges/components/black/VerticalLinearGauge"], 
+						function(ready, dom, CircularLinearGauge, VerticalLinearGauge){
+				ready(function(){
+					new CircularLinearGauge({
+						maximum: 50,
+						value: 50
+					}, dom.byId("circularGauge"));
+					new VerticalLinearGauge({
+						maximum: 50,
+						value: 50
+					}, dom.byId("verticalGauge"));
+				});
+			});
+		</script>
+	</head>
+	<body>
+		<div id="circularGauge" style="width:250px; height:250px">
+		</div>
+		<div id="verticalGauge" style="width:250px; height:250px;"/>
+		</div>
+	</body>
+</html>
diff --git a/dojox/dnd/BoundingBoxController.js b/dojox/dnd/BoundingBoxController.js
index 574655c..01e4479 100644
--- a/dojox/dnd/BoundingBoxController.js
+++ b/dojox/dnd/BoundingBoxController.js
@@ -2,9 +2,10 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 
 	return dojo.declare('dojox.dnd.BoundingBoxController', null, {
 
-			// summary: Allows the user draw bounding boxes around nodes on the page.
-			// Publishes to the "/dojox/dnd/bounding" topic to tell the selector to check
-			// to see whether any dnd items fall within the coordinates of the bounding box
+			// summary:
+			//		Allows the user draw bounding boxes around nodes on the page.
+			//		Publishes to the "/dojox/dnd/bounding" topic to tell the selector to check
+			//		to see whether any dnd items fall within the coordinates of the bounding box
 
 			// x,y start and end coordinates for the bounding box
 			_startX: null,
@@ -13,13 +14,13 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 			_endY: null,
 
 			constructor: function(sources, domNode) {
-				//	summary:
+				// summary:
 				//		Sets mouse handlers for the document to capture when a user
 				//		is trying to draw a bounding box.
-				//	sources: Array:
+				// sources: dojox/dnd/Selector[]
 				//		an array of dojox.dnd.Selectors which need to be aware of
 				//		the positioning of the bounding box.
-				//	domNode: String|DomNode:
+				// domNode: String|DomNode
 				//		the DOM node or id which represents the bounding box on the page.
 				this.events = [
 					dojo.connect(dojo.doc, 'onmousedown', this, '_onMouseDown'),
@@ -57,28 +58,34 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 			},
 
 			shouldStartDrawingBox: function(evt) {
-				// summary: Override-able by the client as an extra check to ensure that a bounding
-				// box should begin to be drawn. If the client has any preconditions to when a
-				// bounding box should be drawn, they should be included in this method.
-				// evt: Object: the mouse event which caused this callback to fire.
+				// summary:
+				//		Override-able by the client as an extra check to ensure that a bounding
+				//		box should begin to be drawn. If the client has any preconditions to when a
+				//		bounding box should be drawn, they should be included in this method.
+				// evt: Object
+				//		the mouse event which caused this callback to fire.
 				return true;
 			},
 
 			boundingBoxIsViable: function(evt) {
-				// summary: Override-able by the client as an extra check to ensure that a bounding
-				// box is viable. In some instances, it might not make sense that
-				// a mouse down -> mouse move -> mouse up interaction represents a bounding box.
-				// For example, if a dialog is open the client might want to suppress a bounding
-				// box. This function could be used by the client to ensure that a bounding box is only
-				// drawn on the document when certain conditions are met.
-				// evt: Object: the mouse event which caused this callback to fire.
+				// summary:
+				//		Override-able by the client as an extra check to ensure that a bounding
+				//		box is viable. In some instances, it might not make sense that
+				//		a mouse down -> mouse move -> mouse up interaction represents a bounding box.
+				//		For example, if a dialog is open the client might want to suppress a bounding
+				//		box. This function could be used by the client to ensure that a bounding box is only
+				//		drawn on the document when certain conditions are met.
+				// evt: Object
+				//		the mouse event which caused this callback to fire.
 				return true;
 			},
 
 			_onMouseDown: function(evt) {
-				// summary: Executed when the user mouses down on the document. Resets the
-				// this._startX and this._startY member variables.
-				// evt: Object: the mouse event which caused this callback to fire.
+				// summary:
+				//		Executed when the user mouses down on the document. Resets the
+				//		this._startX and this._startY member variables.
+				// evt: Object
+				//		the mouse event which caused this callback to fire.
 				if (this.shouldStartDrawingBox(evt) && dojo.mouseButtons.isLeft(evt)) {
 					if (this._startX == null) {
 						this._startX = evt.clientX;
@@ -91,21 +98,25 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 			},
 
 			_onMouseMove: function(evt) {
-				// summary: Executed when the user moves the mouse over the document. Delegates to
-				// this._drawBoundingBox if the user is trying to draw a bounding box.
-				 // whether the user was drawing a bounding box and publishes to the
-				 // "/dojox/dnd/bounding" topic if the user is finished drawing their bounding box.
-				// evt: Object: the mouse event which caused this callback to fire.
+				// summary:
+				//		Executed when the user moves the mouse over the document. Delegates to
+				//		this._drawBoundingBox if the user is trying to draw a bounding box.
+				//		whether the user was drawing a bounding box and publishes to the
+				//		"/dojox/dnd/bounding" topic if the user is finished drawing their bounding box.
+				// evt: Object
+				//		the mouse event which caused this callback to fire.
 				this._endX = evt.clientX;
 				this._endY = evt.clientY;
 				this._drawBoundingBox();
 			},
 
 			_onMouseUp: function(evt) {
-				// summary: Executed when the users mouses up on the document. Checks to see
-				 // whether the user was drawing a bounding box and publishes to the
-				 // "/dojox/dnd/bounding" topic if the user is finished drawing their bounding box.
-				// evt: Object: the mouse event which caused this callback to fire.
+				// summary:
+				//		Executed when the users mouses up on the document. Checks to see
+				//		whether the user was drawing a bounding box and publishes to the
+				//		"/dojox/dnd/bounding" topic if the user is finished drawing their bounding box.
+				// evt: Object
+				//		the mouse event which caused this callback to fire.
 				if (this._endX !== null && this.boundingBoxIsViable(evt)) {
 					// the user has moused up ... tell the selector to check to see whether
 					// any nodes within the bounding box need to be selected.
@@ -115,7 +126,8 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 			},
 
 			_finishSelecting: function() {
-				// summary: hide the bounding box and reset for the next time around
+				// summary:
+				//		hide the bounding box and reset for the next time around
 				if (this._startX !== null) {
 					dojo.disconnect(this.events.pop());
 					dojo.style(this.domNode, 'display', 'none');
@@ -125,7 +137,8 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 			},
 
 			_drawBoundingBox: function() {
-				// summary: draws the bounding box over the document.
+				// summary:
+				//		draws the bounding box over the document.
 				dojo.style(this.domNode, {
 					left: Math.min(this._startX, this._endX) + 'px',
 					top: Math.min(this._startY, this._endY) + 'px',
diff --git a/dojox/dnd/Selector.js b/dojox/dnd/Selector.js
index 2eaa7b7..8a8d160 100644
--- a/dojox/dnd/Selector.js
+++ b/dojox/dnd/Selector.js
@@ -5,9 +5,9 @@ define(["dojo", "dojox", "dojo/dnd/Selector"], function(dojo, dojox) {
 			conservative: true,
 			
 			isSelected: function(node) {
-				//	summary:
+				// summary:
 				//		checks if node is selected
-				//	node: String|DomNode:
+				// node: String|DomNode
 				//		Node to check (id or DOM Node)
 				var id = dojo.isString(node) ? node : node.id,
 					item = this.getItem(id);
@@ -15,11 +15,11 @@ define(["dojo", "dojox", "dojo/dnd/Selector"], function(dojo, dojox) {
 			},
 
 			selectNode: function(node, add) {
-				//	summary:
+				// summary:
 				//		selects a node
-				//	node: String|DomNode:
+				// node: String|DomNode
 				//		Node to select (id or DOM Node)
-				//	add: Boolean?:
+				// add: Boolean?
 				//		If true, node is added to selection, otherwise current
 				//		selection is removed, and node will be the only selection.
 				if (!add) {
@@ -38,9 +38,9 @@ define(["dojo", "dojox", "dojo/dnd/Selector"], function(dojo, dojox) {
 			},
 
 			deselectNode: function(node) {
-				//	summary:
+				// summary:
 				//		deselects a node
-				//	node: String|DomNode:
+				// node: String|DomNode
 				//		Node to deselect (id or DOM Node)
 				var id = dojo.isString(node) ? node : node.id,
 					item = this.getItem(id);
@@ -55,17 +55,17 @@ define(["dojo", "dojox", "dojo/dnd/Selector"], function(dojo, dojox) {
 			},
 
 			selectByBBox: function(left, top, right, bottom, add) {
-				//	summary:
+				// summary:
 				//		selects nodes by bounding box
-				//	left: Number:
+				// left: Number
 				//		Left coordinate of the bounding box
-				//	top: Number:
+				// top: Number
 				//		Top coordinate of the bounding box
-				//	right: Number:
+				// right: Number
 				//		Right coordinate of the bounding box
-				//	bottom: Number:
+				// bottom: Number
 				//		Bottom coordinate of the bounding box
-				//	add: Boolean?:
+				// add: Boolean?
 				//		If true, node is added to selection, otherwise current
 				//		selection is removed, and node will be the only selection.
 
@@ -84,30 +84,30 @@ define(["dojo", "dojox", "dojo/dnd/Selector"], function(dojo, dojox) {
 			},
 
 			_isBoundedByBox: function(node, left, top, right, bottom) {
-				//	summary:
+				// summary:
 				//		figures out whether certain coodinates bound a particular
 				//		dom node.
-				//	node: String|DomNode:
+				// node: String|DomNode
 				//		Node to check (id or DOM Node)
-				//	left: Number:
+				// left: Number
 				//		Left coordinate of the bounding box
-				//	top: Number:
+				// top: Number
 				//		Top coordinate of the bounding box
-				//	right: Number:
+				// right: Number
 				//		Right coordinate of the bounding box
-				//	bottom: Number:
+				// bottom: Number
 				//		Bottom coordinate of the bounding box
 				return this.conservative ? this._conservativeBBLogic(node, left, top, right, bottom) : this._liberalBBLogic(node, left, top, right, bottom);
 			},
 
 			shift: function(toNext, add) {
-				//	summary:
+				// summary:
 				//		shifts the currently selected dnd item forwards and backwards.
 				//		One possible use would be to allow a user select different
 				//		dnd items using the right and left keys.
-				//	toNext: Boolean:
+				// toNext: Boolean
 				//		If true, we select the next node, otherwise the previous one.
-				//	add: Boolean?:
+				// add: Boolean?
 				//		If true, add to selection, otherwise current selection is
 				//		removed before adding any nodes.
 				var selectedNodes = this.getSelectedNodes();
@@ -120,11 +120,11 @@ define(["dojo", "dojox", "dojo/dnd/Selector"], function(dojo, dojox) {
 			},
 
 			_getNodeId: function(nodeId, toNext) {
-				//	summary:
+				// summary:
 				//		finds a next/previous node in relation to nodeId
-				//	nodeId: String:
+				// nodeId: String
 				//		the id of the node to use as the base node
-				//	toNext: Boolean:
+				// toNext: Boolean
 				//		If true, we select the next node, otherwise the previous one.
 				var allNodes = this.getAllNodes(), newId = nodeId;
 				for (var i = 0, l = allNodes.length; i < l; ++i) {
@@ -143,7 +143,7 @@ define(["dojo", "dojox", "dojo/dnd/Selector"], function(dojo, dojox) {
 			},
 
 			_conservativeBBLogic: function(node, left, top, right, bottom) {
-				//	summary:
+				// summary:
 				//		logic which determines whether a node is bounded by the
 				//		left,top,right,bottom parameters. This function returns true
 				//		only if the coordinates of the node parameter are fully
@@ -164,7 +164,7 @@ define(["dojo", "dojox", "dojo/dnd/Selector"], function(dojo, dojox) {
 			},
 
 			_liberalBBLogic: function(node, left, top, right, bottom) {
-				//	summary:
+				// summary:
 				//		logic which determines whether a node is bounded by the
 				//		left,top,right,bottom parameters. Allows for the case where
 				//		any section of the box determined by the left,top,right,bottom parameters
diff --git a/dojox/dnd/tests/test_boundingBoxController.html b/dojox/dnd/tests/test_boundingBoxController.html
index 7a2ea77..7f26659 100644
--- a/dojox/dnd/tests/test_boundingBoxController.html
+++ b/dojox/dnd/tests/test_boundingBoxController.html
@@ -16,7 +16,7 @@
 				z-index:19999;
 			}
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.dnd.BoundingBoxController");
 			dojo.require("dojox.dnd.Selector");
diff --git a/dojox/dnd/tests/test_selector.html b/dojox/dnd/tests/test_selector.html
index 6ee2341..bd54b17 100644
--- a/dojox/dnd/tests/test_selector.html
+++ b/dojox/dnd/tests/test_selector.html
@@ -8,7 +8,7 @@
 			@import "../../../dojo/tests/dnd/dndDefault.css";
 			body { padding: 20px; }
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.dnd.Selector");
 			dojo.require("doh.runner");
diff --git a/dojox/dojox.profile.js b/dojox/dojox.profile.js
index dab25e0..d279bbb 100644
--- a/dojox/dojox.profile.js
+++ b/dojox/dojox.profile.js
@@ -5,34 +5,35 @@ var profile = (function(){
 			var list = {
 				"dojox/dojox.profile":1,
 				"dojox/package.json":1,
-				"dojox/mobile/themes/common/compile":1
+				"dojox/mobile/themes/utils/compile":1,
+				"dojox/mobile/themes/utils/cleanup":1,
+				"dojox/app/tests/layoutApp/build.profile": 1,
+				"dojox/app/tests/globalizedApp/build.profile": 1
 			};
-			return (mid in list) || /^dojox\/resources\//.test(mid) || /(png|jpg|jpeg|gif|tiff)$/.test(filename);
+			return (mid in list) || /^dojox\/resources\//.test(mid) || /(png|jpg|jpeg|gif|tiff)$/.test(filename) || /dojox\/app\/build\//.test(mid);
 		},
 
 		excludes = [
 			"secure",
-			"cometd",
 			"data/(demos|ItemExplorer|StoreExplorer|restListener)",
-			"drawing",
+			"drawing/plugins/drawing/Silverlight",
 			"editor/plugins/(ResizeTableColumn|SpellCheck)",
 			"embed/(IE)",
-			"flash",
-			"gantt",
+			"flash/_base",
 			"help",
 			"image/(Gallery|SlideShow|ThumbnailPicker)",
 			"jq",
-			"jsonPath",
+			"jsonPath/query",
 			"lang/(aspect|async|docs|observable|oo|typed|functional/(binrec|curry|linrec|listcomp|multirec|numrec|tailrec|util|zip))",
 			"layout/(BorderContainer|dnd|ext-dijit)",
 			"mobile/app/",
 			"rails",
 			"robot",
 			"socket/Reconnect",
-			"storage",
-			"sql",
-			"widget/(AnalogGauge|AutoRotator|BarGauge|Calendar|CalendarFx|CalendarViews|DataPresentation|DocTester|DynamicTooltip|FeedPortlet|FilePicker|FisheyeList|gauge|Iterator|Loader|Pager|Portlet|RollingList|Rotator|rotator|SortList|UpgradeBar)",
-			"wire",
+			"sql/",
+			"storage/",
+			"widget/(AnalogGauge|BarGauge|DataPresentation|DocTester|DynamicTooltip|FeedPortlet|FilePicker|gauge|Iterator|Loader|RollingList|SortList)",
+			"wire/",
 			"xmpp"
 		],
 
@@ -59,10 +60,6 @@ var profile = (function(){
 			miniExclude: function(filename, mid){
 				return 0;
 			}
-		},
-
-		trees:[
-			[".", ".", /(\/\.)|(~$)/]
-		]
+		}
 	};
 })();
diff --git a/dojox/drawing.js b/dojox/drawing.js
index af74383..d7159d8 100644
--- a/dojox/drawing.js
+++ b/dojox/drawing.js
@@ -1,2 +1,9 @@
-dojo.provide("dojox.drawing");
-dojo.require("dojox.drawing._base");
\ No newline at end of file
+define(['./drawing/_base'],function(){
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/drawing modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
+});
diff --git a/dojox/drawing/Drawing.js b/dojox/drawing/Drawing.js
index f812a63..5573cac 100755
--- a/dojox/drawing/Drawing.js
+++ b/dojox/drawing/Drawing.js
@@ -1,10 +1,8 @@
-dojo.provide("dojox.drawing.Drawing");
-
-(function(){
-	
-	var _plugsInitialized = false;
-	
-	dojo.declare("dojox.drawing.Drawing", [], {
+define(["dojo", "./defaults", "./manager/_registry", "./manager/keys", "./manager/Mouse",
+"./manager/Canvas","./manager/Undo","./manager/Anchors","./manager/Stencil","./manager/StencilUI",
+  "./util/common"], 
+function(dojo, defaults, registry, keys, Mouse, Canvas, Undo, Anchors, Stencil, StencilUI, utilCommon){
+	return dojo.declare("dojox.drawing.Drawing", [], {
 		// summary:
 		//		Drawing is a project that sits on top of DojoX GFX and uses SVG and
 		//		VML vector graphics to draw and display.
@@ -13,64 +11,55 @@ dojo.provide("dojox.drawing.Drawing");
 		//		extendable and customizable.
 		//		Drawing currently only initiates from HTML although it's technically not
 		//		a Dijit to keep the file size light. But if Dijit is available, Drawing
-		//		will register itself with it and can be accessed dijit.byId('myDrawing')
+		//		will register itself with it and can be accessed with registry.byId('myDrawing')
+		//		(by requiring dijit/registry)
 		//
-		//	NOTES:
+		//		NOTES:
 		//		Although not Drawing and Toolbar, all other objects are created with a custom
 		//		declare. See dojox.drawing.util.oo
 		//
-		//The files are laid out as such:
-		//		- Drawing
-		//			The master class. More than one instance of a Drawing can be placed
+		//		The files are laid out as such:
+		//
+		//		- Drawing: The master class. More than one instance of a Drawing can be placed
 		//			on a page at one time (although this has not yet been tested). Plugins
 		//			can be added in markup.
-		// 	- Toolbar
-		//			Like Drawing, Toolbar is a psudeo Dijit that does not need Dijit. It is
+		//		- Toolbar: Like Drawing, Toolbar is a psudeo Dijit that does not need Dijit. It is
 		//			optional. It can be oriented horizontal or vertical by placing one of
 		//			those params in the class (at least one is required).  Plugins
 		//			can be added in markup. A drawingId is required to point toolbar to
 		//			the drawing.
-		//		- defaults
-		//			Contains the default styles and dimensions for Stencils. An individual
+		//		- defaults: Contains the default styles and dimensions for Stencils. An individual
 		//			Stencil can be changed by calling stencil.att({color obj}); To change
 		//			all styles, a custom defaults file should be used.
-		//		-Stencils
-		//			Drawing uses a concept of 'Stencils' to avoid confusion between a
+		//		- Stencils: Drawing uses a concept of 'Stencils' to avoid confusion between a
 		//			Dojox Shape and a Drawing Shape. The classes in the 'stencils' package
 		//			are display only, they are not used for actually drawing (see 'tools').
 		//			This package contains _Base from which stencils inherit most of their
-		//			methods.(Path and Image are display only and not found in Tools)
-		//		- Tools
-		//			The Tools package contains Stencils that are attached to mouse events
+		//			methods. (Path and Image are display only and not found in Tools)
+		//		- Tools: The Tools package contains Stencils that are attached to mouse events
 		//			and can be used for drawing. Items in this package can also be selected
 		//			and modified.
-		//		- Tools / Custom
-		//			Holds tools that do not directly extend Stencil base classes and often
+		//		- Tools / Custom: Holds tools that do not directly extend Stencil base classes and often
 		//			have very custom code.
-		//		- Library (not implemented)
-		//			The Library package, which is not yet implemented, will be the place to
+		//		- Library (not implemented): The Library package, which is not yet implemented, will be the place to
 		//			hold stencils that have very specific data points that result in a picture.
 		//			Flag-like-banners, fancy borders, or other complex shapes would go here.
-		//		- Annotations
-		//			Annotations 'decorate' and attach to other Stencils, such as a 'Label'
+		//		- Annotations: Annotations 'decorate' and attach to other Stencils, such as a 'Label'
 		//			that can show text on a stencil, or an 'Angle' that shows while dragging
 		//			or modifying a Vector, or an Arrow head that is attached to the beginning
 		//			or end of a line.
-		//		- Manager
-		//			Contains classes that control functionality of a Drawing.
-		//		- Plugins
-		//			Contains optional classes that are 'plugged into' a Drawing. There are two
+		//		- Manager: Contains classes that control functionality of a Drawing.
+		//		- Plugins: Contains optional classes that are 'plugged into' a Drawing. There are two
 		//			types: 'drawing' plugins that modify the canvas, and 'tools' which would
 		//			show in the toolbar.
-		//		- Util
-		//			A collection of common tasks.
+		//		- Util: A collection of common tasks.
 		//
 		// example:
-		//		|	<div dojoType="dojox.drawing.Drawing" id="drawing" defaults="myCustom.defaults"
+		//		|	<div data-dojo-type="dojox.drawing.Drawing" id="drawing" defaults="myCustom.defaults"
 		//		|		plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}}]">
 		//		|   </div>
 		//
-		//	example:
+		// example:
 		//		|	<div dojoType="dojox.drawing.Toolbar" drawingId="drawing" class="drawingToolbar vertical">
 		//		|		<div tool="dojox.drawing.tools.Line" selected="false">Line</div>
 		//		|		<div tool="dojox.drawing.tools.Rect" selected="false">Rect</div>
@@ -80,52 +69,50 @@ dojo.provide("dojox.drawing.Drawing");
 		//		|		<div plugin="dojox.drawing.plugins.tools.Pan" options="{}">Pan</div>
 		//		|		<div plugin="dojox.drawing.plugins.tools.Zoom" options="{zoomInc:.1,minZoom:.5,maxZoom:2}">Zoom</div>
 		//		|	</div>
-		//
-		//
+
 		// ready: Boolean
-		//	Whether or not the canvas has been created and Stencils can be added
+		//		Whether or not the canvas has been created and Stencils can be added
 		ready:false,
+
 		// mode: [optional] String
 		//		Changes the functionality of the drawing
 		mode: "",
+
 		// width: Number
 		//		Width of the canvas
 		width:0,
-		//
+
 		// height: Number
 		//		Height of the canvas
 		height:0,
-		//
+
 		// defaults : Object
 		//		Optional replacements for native defaults.
+
 		// plugins: Object
 		//		Key values of plugins that apply to canvas.
-		//
+
 		constructor: function(/* Object */props, /* HTMLNode */node){
 			// summary:
 			//		Drawing is not a Dijit. This is the master method.
-			//		NOTE:
-			// 			props is always null since this is not a real widget
-			//			Will change when Drawing can be created programmatically.
 			//
+			//		NOTE:
+			//		props is always null since this is not a real widget
+			//		Will change when Drawing can be created programmatically.
+
 			var def = dojo.attr(node, "defaults");
-			if(def){
-				dojox.drawing.defaults =  dojo.getObject(def);
-			}
-			this.defaults =  dojox.drawing.defaults;
-			
-			this.id = node.id;
-			dojox.drawing.register(this, "drawing");
+			this.defaults =  def ? (typeof def === 'string' ? dojo.getObject(def) : def) : defaults;
+
+			this.id = node.id || dijit.getUniqueId('dojox_drawing_Drawing');
+			registry.register(this, "drawing");
 			this.mode = (props.mode || dojo.attr(node, "mode") || "").toLowerCase();
 			var box = dojo.contentBox(node);
-			this.width = box.w;
-			this.height = box.h;
-			this.util = dojox.drawing.util.common;
-			this.util.register(this); // So Toolbar can find this Drawing DEPRECATED
-			this.keys = dojox.drawing.manager.keys;
-			this.mouse = new dojox.drawing.manager.Mouse({util:this.util, keys:this.keys, id:this.mode=="ui"?"MUI":"mse"});
+			this.width = props.width || box.w;
+			this.height = props.height || box.h;
+			utilCommon.register(this); // So Toolbar can find this Drawing DEPRECATED
+			this.mouse = new Mouse({util:utilCommon, keys:keys, id:this.mode=="ui"?"MUI":"mse"});
 			this.mouse.setEventMode(this.mode);
-			
+
 			this.tools = {};
 			this.stencilTypes = {};
 			this.stencilTypeMap = {};
@@ -136,7 +123,7 @@ dojo.provide("dojox.drawing.Drawing");
 			}else{
 				this.plugins = [];
 			}
-			
+
 			this.widgetId = this.id;
 			dojo.attr(this.domNode, "widgetId", this.widgetId);
 			// If Dijit is available in the page, register with it
@@ -158,40 +145,41 @@ dojo.provide("dojox.drawing.Drawing");
 				};
 				dijit.registry.add(this);
 			}
-			
-			var stencils = dojox.drawing.getRegistered("stencil");
+
+			var stencils = registry.getRegistered("stencil");
 			for(var nm in stencils){
 				this.registerTool(stencils[nm].name);
 			}
-			var tools = dojox.drawing.getRegistered("tool");
+			var tools = registry.getRegistered("tool");
 			for(nm in tools){
 				this.registerTool(tools[nm].name);
 			}
-			var plugs = dojox.drawing.getRegistered("plugin");
+			var plugs = registry.getRegistered("plugin");
 			for(nm in plugs){
 				this.registerTool(plugs[nm].name);
 			}
 			this._createCanvas();
-			
+
 		},
-		
+
 		_createCanvas: function(){
 			console.info("drawing create canvas...");
-			this.canvas = new dojox.drawing.manager.Canvas({
+			this.canvas = new Canvas({
 				srcRefNode:this.domNode,
-				util:this.util,
+				util:utilCommon,
 				mouse:this.mouse,
+				width: this.width, height: this.height,
 				callback: dojo.hitch(this, "onSurfaceReady")
 			});
 			this.initPlugins();
 		},
-		
+
 		resize: function(/* Object */box){
 			// summary:
 			//		Resizes the canvas.
 			//		If within a ContentPane this will get called automatically.
 			//		Can also be called directly.
-			//
+
 			box && dojo.style(this.domNode, {
 				width:box.w+"px",
 				height:box.h+"px"
@@ -202,29 +190,29 @@ dojo.provide("dojox.drawing.Drawing");
 				this.canvas.resize(box.w, box.h);
 			}
 		},
-		
+
 		startup: function(){
 			//console.info("drawing startup")
 		},
-		
+
 		getShapeProps: function(/* Object */data, mode){
 			// summary:
-			// 		The common objects that are mixed into
+			//		The common objects that are mixed into
 			//		a new Stencil. Mostly internal, but could be used.
-			//
+
 			var surface = data.stencilType;
 			var ui = this.mode=="ui" || mode=="ui";
 			return dojo.mixin({
 				container: ui && !surface ? this.canvas.overlay.createGroup() : this.canvas.surface.createGroup(),
-				util:this.util,
-				keys:this.keys,
+				util:utilCommon,
+				keys:keys,
 				mouse:this.mouse,
 				drawing:this,
 				drawingType: ui && !surface ? "ui" : "stencil",
 				style:this.defaults.copy()
 			}, data || {});
 		},
-		
+
 		addPlugin: function(/* Object */plugin){
 			// summary:
 			//		Add a toolbar plugin object to plugins array
@@ -234,11 +222,11 @@ dojo.provide("dojox.drawing.Drawing");
 				this.initPlugins();
 			}
 		},
-		
+
 		initPlugins: function(){
 			// summary:
-			// 		Called from Toolbar after a plugin has been loaded
-			// 		The call to this coming from toobar is a bit funky as the timing
+			//		Called from Toolbar after a plugin has been loaded
+			//		The call to this coming from toolbar is a bit funky as the timing
 			//		of IE for canvas load is different than other browsers
 			if(!this.canvas || !this.canvas.surfaceReady){
 				var c = dojo.connect(this, "onSurfaceReady", this, function(){
@@ -249,8 +237,8 @@ dojo.provide("dojox.drawing.Drawing");
 			}
 			dojo.forEach(this.plugins, function(p, i){
 				var props = dojo.mixin({
-					util:this.util,
-					keys:this.keys,
+					util:utilCommon,
+					keys:keys,
 					mouse:this.mouse,
 					drawing:this,
 					stencils:this.stencils,
@@ -266,31 +254,30 @@ dojo.provide("dojox.drawing.Drawing");
 				}
 			}, this);
 			this.plugins = [];
-			_plugsInitialized = true;
 			// In IE, because the timing is different we have to get the
 			// canvas position after everything has drawn. *sigh*
 			this.mouse.setCanvas();
 		},
-		
+
 		onSurfaceReady: function(){
 			// summary:
 			//		Event that to which can be connected.
 			//		Fired when the canvas is ready and can be drawn to.
-			//
+
 			this.ready = true;
 			//console.info("Surface ready")
 			this.mouse.init(this.canvas.domNode);
-			this.undo = new dojox.drawing.manager.Undo({keys:this.keys});
-			this.anchors = new dojox.drawing.manager.Anchors({drawing:this, mouse:this.mouse, undo:this.undo, util:this.util});
+			this.undo = new Undo({keys:keys});
+			this.anchors = new Anchors({drawing:this, mouse:this.mouse, undo:this.undo, util:utilCommon});
 			if(this.mode == "ui"){
-				this.uiStencils = new dojox.drawing.manager.StencilUI({canvas:this.canvas, surface:this.canvas.surface, mouse:this.mouse, keys:this.keys});
+				this.uiStencils = new StencilUI({canvas:this.canvas, surface:this.canvas.surface, mouse:this.mouse, keys:keys});
 			}else{
-				this.stencils = new dojox.drawing.manager.Stencil({canvas:this.canvas, surface:this.canvas.surface, mouse:this.mouse, undo:this.undo, keys:this.keys, anchors:this.anchors});
-				this.uiStencils = new dojox.drawing.manager.StencilUI({canvas:this.canvas, surface:this.canvas.surface, mouse:this.mouse, keys:this.keys});
+				this.stencils = new Stencil({canvas:this.canvas, surface:this.canvas.surface, mouse:this.mouse, undo:this.undo, keys:keys, anchors:this.anchors});
+				this.uiStencils = new StencilUI({canvas:this.canvas, surface:this.canvas.surface, mouse:this.mouse, keys:keys});
 			}
 			if(dojox.gfx.renderer=="silverlight"){
 				try{
-				new dojox.drawing.plugins.drawing.Silverlight({util:this.util, mouse:this.mouse, stencils:this.stencils, anchors:this.anchors, canvas:this.canvas});
+				new dojox.drawing.plugins.drawing.Silverlight({util:utilCommon, mouse:this.mouse, stencils:this.stencils, anchors:this.anchors, canvas:this.canvas});
 				}catch(e){
 					throw new Error("Attempted to install the Silverlight plugin, but it was not found.");
 				}
@@ -298,25 +285,26 @@ dojo.provide("dojox.drawing.Drawing");
 			dojo.forEach(this.plugins, function(p){
 				p.onSurfaceReady && p.onSurfaceReady();
 			});
-		
+
 		},
-		
+
 		addUI: function(/* String */type, /* Object */options){
 			// summary:
 			//		Use this method to programmatically add Stencils that display on
 			//		the canvas.
+			//
 			//		FIXME: Currently only supports Stencils that have been registered,
-			//			which is items in the toolbar, and the additional Stencils at the
-			//			end of onSurfaceReady. This covers all Stencils, but you can't
-			//			use 'display only' Stencils for Line, Rect, and Ellipse.
-			//		arguments:
-			//			type: String
-			//				The final name of the tool, lower case: 'image', 'line', 'textBlock'
-			//		options:
-			//			type: Object
-			//				The parameters used to draw the object. See stencil._Base and each
-			//				tool for specific parameters of teh data or points objects.
+			//		which is items in the toolbar, and the additional Stencils at the
+			//		end of onSurfaceReady. This covers all Stencils, but you can't
+			//		use 'display only' Stencils for Line, Rect, and Ellipse.
+			// type: String
+			//		The final name of the tool, lower case: 'image', 'line', 'textBlock'
+			// options:
+			//		- type: Object
 			//
+			//		The parameters used to draw the object. See stencil._Base and each
+			//		tool for specific parameters of teh data or points objects.
+
 			if(!this.ready){
 				var c = dojo.connect(this, "onSurfaceReady", this, function(){
 					dojo.disconnect(c);
@@ -336,24 +324,23 @@ dojo.provide("dojox.drawing.Drawing");
 			var s = this.uiStencils.register( new this.stencilTypes[type](this.getShapeProps(options, "ui")));
 			return s;
 		},
-		
-		
+
+
 		addStencil: function(/* String */type, /* Object */options){
 			// summary:
 			//		Use this method to programmatically add Stencils that display on
 			//		the canvas.
-			//		FIXME: Currently only supports Stencils that have been registered,
-			//			which is items in the toolbar, and the additional Stencils at the
-			//			end of onSurfaceReady. This covers all Stencils, but you can't
-			//			use 'display only' Stencils for Line, Rect, and Ellipse.
-			//		arguments:
-			//			type: String
-			//				The final name of the tool, lower case: 'image', 'line', 'textBlock'
-			//		options:
-			//			type: Object
-			//				The parameters used to draw the object. See stencil._Base and each
-			//				tool for specific parameters of teh data or points objects.
 			//
+			//		FIXME: Currently only supports Stencils that have been registered,
+			//		which is items in the toolbar, and the additional Stencils at the
+			//		end of onSurfaceReady. This covers all Stencils, but you can't
+			//		use 'display only' Stencils for Line, Rect, and Ellipse.
+			// type: String
+			//		The final name of the tool, lower case: 'image', 'line', 'textBlock'
+			// options: Object
+			//		The parameters used to draw the object. See stencil._Base and each
+			//		tool for specific parameters of teh data or points objects.
+
 			if(!this.ready){
 				var c = dojo.connect(this, "onSurfaceReady", this, function(){
 					dojo.disconnect(c);
@@ -370,40 +357,39 @@ dojo.provide("dojox.drawing.Drawing");
 			this.currentStencil && this.currentStencil.moveToFront();
 			return s;
 		},
-		
+
 		removeStencil: function(/* Object */stencil){
 			// summary:
 			//		Use this method to programmatically remove Stencils from the canvas.
-			// 	arguments:
-			//		Stencil: Object
-			//			The Stencil to be removed
-			//
+			// stencil: Object
+			//		The Stencil to be removed
+
 			this.stencils.unregister(stencil);
 			stencil.destroy();
 		},
-		
+
 		removeAll: function(){
 			// summary:
 			//		Deletes all Stencils on the canvas.
 			this.stencils.removeAll();
 		},
-		
+
 		selectAll: function(){
 			// summary:
 			//		Selects all stencils
 			this.stencils.selectAll();
 		},
-		
-		toSelected: function(/*String*/func /*[args, ...]*/){
+
+		toSelected: function(/*String*/func /*any...*/){
 			// summary:
 			//		Call a function within all selected Stencils
 			//		like attr()
 			// example:
 			//		|	myDrawing.toSelected('attr', {x:10})
-			//
+
 			this.stencils.toSelected.apply(this.stencils, arguments);
 		},
-		
+
 		exporter: function(){
 			// summary:
 			//		Collects all Stencil data and returns an
@@ -411,7 +397,7 @@ dojo.provide("dojox.drawing.Drawing");
 			console.log("this.stencils", this.stencils);
 			return this.stencils.exporter();  //Array
 		},
-		
+
 		importer: function(/* Array */objects){
 			// summary:
 			//		Handles an Array of stencil data and imports the objects
@@ -420,21 +406,20 @@ dojo.provide("dojox.drawing.Drawing");
 				this.addStencil(m.type, m);
 			}, this);
 		},
-		
-		changeDefaults: function(/*Object*/newStyle,/*boolean*/value){
+
+		changeDefaults: function(/*Object*/newStyle,/*Boolean*/value){
 			// summary:
 			//		Change the defaults so that all Stencils from this
-			// 		point on will use the newly changed style.
-			// arguments:
-			//		newStyle: Object
-			//			An object that represents one of the objects in
-			//			drawing.style that will be mixed in. Not all
-			//			properties are necessary. Only one object may
-			//			be changed at a time. The object boolean parameter
-			//			is not required and if not set objects will automatically
-			//			be changed.
-			//			Changing non-objects like angleSnap requires value
-			//			to be true.
+			//		point on will use the newly changed style.
+			// newStyle: Object
+			//		An object that represents one of the objects in
+			//		drawing.style that will be mixed in. Not all
+			//		properties are necessary. Only one object may
+			//		be changed at a time. The object boolean parameter
+			//		is not required and if not set objects will automatically
+			//		be changed.
+			//		Changing non-objects like angleSnap requires value
+			//		to be true.
 			// example:
 			//		|	myDrawing.changeDefaults({
 			//		|		norm:{
@@ -443,7 +428,7 @@ dojo.provide("dojox.drawing.Drawing");
 			//		|			color:"#ffff00"
 			//		|		}
 			//		|	});
-			//
+
 			//console.log("----->>> changeDefault: ",newStyle, " value?: ",value);
 			if(value!=undefined && value){
 				for(var nm in newStyle){
@@ -457,20 +442,20 @@ dojo.provide("dojox.drawing.Drawing");
 					}
 				}
 			}
-			
+
 			if(this.currentStencil!=undefined && (!this.currentStencil.created || this.defaults.clickMode)){
 				this.unSetTool();
 				this.setTool(this.currentType);
 			}
 		},
-		
+
 		onRenderStencil: function(/* Object */stencil){
 			// summary:
 			//		Event that fires when a stencil is drawn. Does not fire from
 			//		'addStencil'.
-			//
+
 			//console.info("--------------------------------------dojox.drawing.onRenderStencil:", stencil.id);
-			
+
 			this.stencils.register(stencil);
 			this.unSetTool();
 			if(!this.defaults.clickMode){
@@ -479,16 +464,16 @@ dojo.provide("dojox.drawing.Drawing");
 				this.defaults.clickable = true;
 			}
 		},
-		
+
 		onDeleteStencil: function(/* Object */stencil){
 			// summary:
 			//		Event fired from a stencil that has destroyed itself
 			//	 	will also be called when it is removed by "removeStencil"
 			//	 	or stencils.onDelete.
-			//
+
 			this.stencils.unregister(stencil);
 		},
-		
+
 		registerTool: function(/* String */type){
 			// summary:
 			//		 Registers a tool that can be accessed. Internal.
@@ -496,24 +481,24 @@ dojo.provide("dojox.drawing.Drawing");
 			var constr = dojo.getObject(type);
 			//console.log("constr:", type)
 			this.tools[type] = constr;
-			var abbr = this.util.abbr(type);
+			var abbr = utilCommon.abbr(type);
 			this.stencilTypes[abbr] = constr;
 			this.stencilTypeMap[abbr] = type;
 		},
-		
+
 		getConstructor: function(/*String*/abbr){
 			// summary:
 			//		Returns a Stencil constructor base on
 			//		abbreviation
 			return this.stencilTypes[abbr];
 		},
-		
+
 		setTool: function(/* String */type){
 			// summary:
 			//		Sets up a new class to be used to draw. Called from Toolbar,
 			//		and this class... after a tool is used a new one of the same
 			//		type is initialized. Could be called externally.
-			//
+
 			if(this.mode=="ui"){ return; }
 			if(!this.canvas || !this.canvas.surface){
 				var c = dojo.connect(this, "onSurfaceReady", this, function(){
@@ -525,12 +510,12 @@ dojo.provide("dojox.drawing.Drawing");
 			if(this.currentStencil){
 				this.unSetTool();
 			}
-			
+
 			this.currentType = this.tools[type] ? type : this.stencilTypeMap[type];
 			//console.log("new tool arg:", type, "curr:", this.currentType, "mode:", this.mode, "tools:", this.tools)
-			
+
 			try{
-				this.currentStencil = new this.tools[this.currentType]({container:this.canvas.surface.createGroup(), util:this.util, mouse:this.mouse, keys:this.keys});
+				this.currentStencil = new this.tools[this.currentType]({container:this.canvas.surface.createGroup(), util:utilCommon, mouse:this.mouse, keys:keys});
 				console.log("new tool is:", this.currentStencil.id, this.currentStencil);
 				if(this.defaults.clickMode){ this.defaults.clickable = false; }
 				this.currentStencil.connect(this.currentStencil, "onRender", this, "onRenderStencil");
@@ -541,22 +526,26 @@ dojo.provide("dojox.drawing.Drawing");
 				//console.trace();
 			}
 		},
-		
+
 		set: function(name, value){
 			// summary:
 			//		Drawing registers as a widget and needs to support
 			//		widget's api.
 			console.info("Attempting to set ",name," to: ",value,". Set currently not fully supported in Drawing");
 		},
-		
+
+		get: function(name){
+			return;
+		},
+
 		unSetTool: function(){
 			// summary:
 			//		Destroys current tool
 			if(!this.currentStencil.created){
 				this.currentStencil.destroy();
 			}
-			
+
 		}
 	});
-	
-})();
\ No newline at end of file
+
+});
diff --git a/dojox/drawing/_base.js b/dojox/drawing/_base.js
index 0056158..9e3ba1b 100644
--- a/dojox/drawing/_base.js
+++ b/dojox/drawing/_base.js
@@ -1,36 +1,6 @@
-dojo.provide("dojox.drawing._base");
+define(["dojo", "./annotations/Label", "./Drawing"
+  ],function(dojo, L, Drawing){
 dojo.experimental("dojox.drawing");
+return Drawing;
+});
 
-dojo.require("dojox.drawing.manager._registry");
-dojo.require("dojox.gfx");
-dojo.require("dojox.drawing.Drawing");
-dojo.require("dojox.drawing.util.oo");
-dojo.require("dojox.drawing.util.common");
-dojo.require("dojox.drawing.util.typeset");
-dojo.require("dojox.drawing.defaults");
-dojo.require("dojox.drawing.manager.Canvas");
-
-// interactive managers
-dojo.require("dojox.drawing.manager.Undo");
-dojo.require("dojox.drawing.manager.keys");
-dojo.require("dojox.drawing.manager.Mouse");
-dojo.require("dojox.drawing.manager.Stencil");
-dojo.require("dojox.drawing.manager.StencilUI"); // plugin? or as a require? good here? in toolbar?
-dojo.require("dojox.drawing.manager.Anchors");
-
-// standard stencils
-dojo.require("dojox.drawing.stencil._Base");
-dojo.require("dojox.drawing.stencil.Line");
-dojo.require("dojox.drawing.stencil.Rect");
-dojo.require("dojox.drawing.stencil.Ellipse");
-dojo.require("dojox.drawing.stencil.Path");
-dojo.require("dojox.drawing.stencil.Text");
-dojo.require("dojox.drawing.stencil.Image");
-
-// annotations are built within stencil/_Base.js
-// would like to optionally include them, but for
-// now it's mandatory.
-dojo.require("dojox.drawing.annotations.Label");
-dojo.require("dojox.drawing.annotations.Angle");
-dojo.require("dojox.drawing.annotations.Arrow");
-dojo.require("dojox.drawing.annotations.BoxShadow");
\ No newline at end of file
diff --git a/dojox/drawing/annotations/Angle.js b/dojox/drawing/annotations/Angle.js
index d80c22d..bfec993 100755
--- a/dojox/drawing/annotations/Angle.js
+++ b/dojox/drawing/annotations/Angle.js
@@ -1,21 +1,12 @@
-dojo.provide("dojox.drawing.annotations.Angle");
+define(["dojo", "../util/oo", "../util/positioning"], 
+function(dojo, oo, positioning){
 
-dojox.drawing.annotations.Angle = dojox.drawing.util.oo.declare(
-	// summary:
-	//	When initiated, an HTML box will hover near the Stencil,
-	//	displaying it's angle while drawn or modified. Currently
-	//	only works with Vector, Line, Arrow, and Axes.
-	// description:
-	//	Annotation is positioned with dojox.drawing.util.positioning.angle
-	//	That method should be overwritten for custom placement.
-	//	Called internally. To initiaize:
-	//	TODO: currently always on
-	//
-	function(/*Object*/options){
-		// arguments:
-		//	options: Object
+//dojox.drawing.annotations.Angle = 
+return oo.declare(
+	function(/*Object*/ options){
+		// options: Object
 		//		One key value: the stencil that called this.
-		//
+
 		this.stencil = options.stencil;
 		this.util = options.stencil.util;
 		this.mouse = options.stencil.mouse;
@@ -29,13 +20,22 @@ dojox.drawing.annotations.Angle = dojox.drawing.util.oo.declare(
 		]);
 	},
 	{
+		// summary:
+		//		When initiated, an HTML box will hover near the Stencil,
+		//		displaying it's angle while drawn or modified. Currently
+		//		only works with Vector, Line, Arrow, and Axes.
+		// description:
+		//		Annotation is positioned with dojox.drawing.util.positioning.angle
+		//		That method should be overwritten for custom placement.
+		//		Called internally.
+
 		type:"dojox.drawing.tools.custom",
 		angle:0,
 
 		showAngle: function(){
-			//	summary:
+			// summary:
 			//		Called to display angle
-			//
+
 			if(!this.stencil.selected && this.stencil.created){ return; }
 			if(this.stencil.getRadius() < this.stencil.minimumSize){
 				this.hideAngle();
@@ -43,7 +43,7 @@ dojox.drawing.annotations.Angle = dojox.drawing.util.oo.declare(
 			}
 			var node = this.getAngleNode();
 			var d = this.stencil.pointsToData();
-			var pt = dojox.drawing.util.positioning.angle({x:d.x1,y:d.y1},{x:d.x2,y:d.y2});
+			var pt = positioning.angle({x:d.x1,y:d.y1},{x:d.x2,y:d.y2});
 			var sc = this.mouse.scrollOffset();
 			var mx = this.stencil.getTransform();
 			var dx = mx.dx / this.mouse.zoom;
@@ -73,7 +73,7 @@ dojox.drawing.annotations.Angle = dojox.drawing.util.oo.declare(
 		},
 
 		getAngleNode: function(){
-			//	summary:
+			// summary:
 			//		Gets or creates HTMLNode used for display
 			if(!this._angleNode){
 				this._angleNode = dojo.create("span", null, dojo.body());
@@ -84,9 +84,9 @@ dojox.drawing.annotations.Angle = dojox.drawing.util.oo.declare(
 		},
 
 		hideAngle: function(){
-			//	summary:
+			// summary:
 			//		Turns display off.
-			//
+
 			if(this._angleNode && dojo.style(this._angleNode, "opacity")>0.9){
 
 				dojo.fadeOut({node:this._angleNode,
@@ -100,5 +100,5 @@ dojox.drawing.annotations.Angle = dojox.drawing.util.oo.declare(
 
 		}
 	}
-
-);
\ No newline at end of file
+);
+});
diff --git a/dojox/drawing/annotations/Arrow.js b/dojox/drawing/annotations/Arrow.js
index 877be7b..6e34964 100755
--- a/dojox/drawing/annotations/Arrow.js
+++ b/dojox/drawing/annotations/Arrow.js
@@ -1,16 +1,11 @@
-dojo.provide("dojox.drawing.annotations.Arrow");
-dojo.require("dojox.drawing.stencil.Path");
+define(["../util/oo", "../stencil/Path"], 
+function(oo, Path){
 
-dojox.drawing.annotations.Arrow = dojox.drawing.util.oo.declare(
-	// summary:
-	//	An annotation called internally to put an arrowhead
-	//	on ether end of a Line. Initiated in Arrow (and Vector)
-	//	with the optional params: arrowStart and arrowEnd. Both
-	//	default true for Axes.
-	//
-	dojox.drawing.stencil.Path,
+//dojox.drawing.annotations.Arrow =
+return oo.declare(
+
+	Path,
 	function(/* dojox.__stencilArgs */options){
-		// arguments: See stencil._Base
 		this.stencil.connectMult([
 			[this.stencil, "select", this, "select"],
 			[this.stencil, "deselect", this, "deselect"],
@@ -30,6 +25,12 @@ dojox.drawing.annotations.Arrow = dojox.drawing.util.oo.declare(
 		
 	},
 	{
+		// summary:
+		//		An annotation called internally to put an arrowhead
+		//		on ether end of a Line. Initiated in Arrow (and Vector)
+		//		with the optional params: arrowStart and arrowEnd. Both
+		//		default true for Axes.
+
 		idx1:0,
 		idx2:1,
 		
@@ -39,8 +40,8 @@ dojox.drawing.annotations.Arrow = dojox.drawing.util.oo.declare(
 		
 		arrowHead: function(x1, y1, x2, y2, style){
 			// summary:
-			//	Creates data used to draw arrow head.
-			//
+			//		Creates data used to draw arrow head.
+
 			var obj = {
 				start:{
 					x:x1,
@@ -68,4 +69,5 @@ dojox.drawing.annotations.Arrow = dojox.drawing.util.oo.declare(
 		}
 		
 	}
-);
\ No newline at end of file
+);
+});
diff --git a/dojox/drawing/annotations/BoxShadow.js b/dojox/drawing/annotations/BoxShadow.js
index 5baf525..ab869e6 100644
--- a/dojox/drawing/annotations/BoxShadow.js
+++ b/dojox/drawing/annotations/BoxShadow.js
@@ -1,19 +1,7 @@
-dojo.provide("dojox.drawing.annotations.BoxShadow");
+define(["dojo", "dojo/_base/Color", "../util/oo"], 
+function(dojo, Color, oo){
 
-dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Creates a box shadow under solid objects. Can change the
-	//		shadow direction, color, size, and intensity. Can center
-	//		the shadow and make it a Glow.
-	// description:
-	//		This is a psuedo shadow, created by duplicating the
-	//		original stencil and increasing the line weight while
-	//		reducing the opacity. Therefore it will not work with
-	//		text. Also won't look very good if the Stencil has no
-	//		fill or is transparent. Can't do knockouts or inner
-	//		shadows. Currently can't do paths - while doable, it
-	//		will most likely choke IE into certain death.
-	//
+return oo.declare(
 	function(/*Object*/options){
 		this.stencil = options.stencil;
 		this.util = options.stencil.util;
@@ -24,39 +12,52 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 			// summary:
 			//		When passing a shadow object into a stencil, that shadow
 			//		object will be mixed in with these defaults.
-			//
-			// size: Number, mult: Number
-			//		These two props work together. Both affect the size and quality
+
+			// size: Number
+			//		Works together with mult. Both affect the size and quality
 			//		of the shadow. size affects the actual size and mult affects the
 			//		lineWidths that overlap to make the shadow. Generally you want a
 			//		bigger 'size' than 'mult'. The defaults are good for a shadow, but
 			//		you will want to increase them when making a glow.
-			//	TODO: Make this more clear or use other properties.
+			//		TODO: Make this more clear or use other properties.
 			size:6,
+
+			// mult: Number
+			//		Works together with size.  Both affect the size and quality
+			//		of the shadow. size affects the actual size and mult affects the
+			//		lineWidths that overlap to make the shadow. Generally you want a
+			//		bigger 'size' than 'mult'. The defaults are good for a shadow, but
+			//		you will want to increase them when making a glow.
+			//		TODO: Make this more clear or use other properties.
 			mult:4,
+
 			// alpha: Float
 			//		Affects the alpha of the shadow. Because this is multiple shapes
 			//		overlapped, you want much less than you may think. .1 is pretty
 			//		dark and . is black. Higher numbers also give a sharper edge.
 			alpha:.05,
-			//	place: String
+
+			// place: String
 			//		Tells the position of the shadow:
-			//			B: bottom
-			//			T: top
-			//			L: left
-			//			R: right
-			//			C: center, or a glow
+			//
+			//		- B: bottom
+			//		- T: top
+			//		- L: left
+			//		- R: right
+			//		- C: center, or a glow
+			//
 			//		Can be used in combinations such as BR, BL, L, T, etc. 'C' should
 			//		be used by itself.
 			place:"BR",
-			//	color: String
+
+			// color: String
 			//		The color of the shadow or glow.
 			color:"#646464"
-		}
+		};
 		
 		delete options.stencil;
 		this.options = dojo.mixin(shadowDefaults, options);
-		this.options.color = new dojo.Color(this.options.color)
+		this.options.color = new Color(this.options.color)
 		this.options.color.a = this.options.alpha;
 		switch(this.stencil.shortType){
 			case "image":
@@ -86,6 +87,19 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 		}
 	},
 	{
+		// summary:
+		//		Creates a box shadow under solid objects. Can change the
+		//		shadow direction, color, size, and intensity. Can center
+		//		the shadow and make it a Glow.
+		// description:
+		//		This is a pseudo shadow, created by duplicating the
+		//		original stencil and increasing the line weight while
+		//		reducing the opacity. Therefore it will not work with
+		//		text. Also won't look very good if the Stencil has no
+		//		fill or is transparent. Can't do knockouts or inner
+		//		shadows. Currently can't do paths - while doable, it
+		//		will most likely choke IE into certain death.
+
 		showing:true,
 		render: function(){
 			if(this.container){
@@ -208,8 +222,8 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 		
 		arrowPoints: function(){
 			// summary:
-			//	Creates data used to draw arrow head.
-			//
+			//		Creates data used to draw arrow head.
+
 			var d = this.stencil.data;
 			var radius = this.stencil.getRadius();
 			var angle = this.style.zAngle + 30;
@@ -290,8 +304,7 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 			
 			}
 		},
-		
-		
+
 		onTransform: function(){
 			this.render();
 		},
@@ -304,4 +317,6 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 			}
 		}
 	}
-);
\ No newline at end of file
+);
+
+});
diff --git a/dojox/drawing/annotations/Label.js b/dojox/drawing/annotations/Label.js
index c9cb302..5f7c967 100755
--- a/dojox/drawing/annotations/Label.js
+++ b/dojox/drawing/annotations/Label.js
@@ -1,23 +1,17 @@
-dojo.provide("dojox.drawing.annotations.Label");
-dojo.require("dojox.drawing.stencil.Text");
+define(["exports", "dojo/_base/lang", "../util/oo", "../stencil/Text"],
+function(exports, lang, oo, Text){
 
-dojox.drawing.annotations.Label = dojox.drawing.util.oo.declare(
-	// summary:
-	// 	An annotation called internally to label an Stencil.
-	// description:
-	//	Annotation is positioned with dojox.drawing.util.positioning.label
-	//	That method should be overwritten for custom placement. Or,
-	//	add a 'setLabelCustom' method to the Stencil and it will be used.
-	//
-	dojox.drawing.stencil.Text,
+// TODO: why not just return Label?
+
+exports.Label = oo.declare(
+	Text,
 	function(/*Object*/options){
-		// arguments:
-		//	options: Object
+		// options: Object
 		//		One key value: the stencil that called this.
-		//
+
 		this.master = options.stencil;
 		this.labelPosition = options.labelPosition || "BR"; // TL, TR, BR, BL, or function
-		if(dojo.isFunction(this.labelPosition)){
+		if(lang.isFunction(this.labelPosition)){
 			this.setLabel = this.setLabelCustom;
 		}
 		this.setLabel(options.text || "");
@@ -28,14 +22,21 @@ dojox.drawing.annotations.Label = dojox.drawing.util.oo.declare(
 			this.connect(this.master, "attr", this, "beforeAttr");
 		}
 	},{
+		// summary:
+		//		An annotation called internally to label an Stencil.
+		// description:
+		//		Annotation is positioned with dojox.drawing.util.positioning.label
+		//		That method should be overwritten for custom placement. Or,
+		//		add a 'setLabelCustom' method to the Stencil and it will be used.
+
 		_align:"start",
 		drawingType:"label",
 		
 		setLabelCustom: function(/* ? String */text){
 			// summary:
-			//	Attaches to custom positioning within a Stencil
-			//
-			var d = dojo.hitch(this.master, this.labelPosition)();
+			//		Attaches to custom positioning within a Stencil
+
+			var d = lang.hitch(this.master, this.labelPosition)();
 			this.setData({
 				x:d.x,
 				y:d.y,
@@ -51,9 +52,9 @@ dojox.drawing.annotations.Label = dojox.drawing.util.oo.declare(
 		
 		setLabel: function(/* String */text){
 			// summary:
-			//	Sets the text of the label. Not called directly. Should
-			//	be called within Stencil. See stencil._Base
-			//
+			//		Sets the text of the label. Not called directly. Should
+			//		be called within Stencil. See stencil._Base
+
 			// onTransform will pass an object here
 			var x, y, box = this.master.getBounds();
 			
@@ -109,4 +110,5 @@ dojox.drawing.annotations.Label = dojox.drawing.util.oo.declare(
 		}
 	}
 
-);
\ No newline at end of file
+);
+});
diff --git a/dojox/drawing/defaults.js b/dojox/drawing/defaults.js
index e0f34d4..f6dcaf8 100755
--- a/dojox/drawing/defaults.js
+++ b/dojox/drawing/defaults.js
@@ -1,6 +1,4 @@
-dojo.provide("dojox.drawing.defaults");
-
-dojox.drawing.defaults = {
+define({
 	// summary:
 	//		Styles and defaults used for Drawing stencils and text.
 	// description:
@@ -9,16 +7,18 @@ dojox.drawing.defaults = {
 	//		To change all these styles, create a copy of this file
 	//		and point to it in the Drawing properties:
 	//		|	<div dojoType="dojox.drawing.Drawing" id="drawing" defaults="MyCustom.defaults"></div>
-	// See:
-	//		Drawing.changeDefaults
 	//
-	//  Determines whether in draw or edit mode (whether stencils
-	//  are clickable.  If clickMode is false, the original
-	//  functionality of silently switching between select modes
-	//  is enabled.  If clickMode is true, it allows powerpoint-
-	//  like functionality.  Clickable is used by powerpoint to
-	//  distinguish when things can be selected and when they can't
+	//		See: Drawing.changeDefaults
+
+	// clickMode: Boolean
+	//		Determines whether in draw or edit mode (whether stencils
+	//		are clickable.  If clickMode is false, the original
+	//		functionality of silently switching between select modes
+	//		is enabled.  If clickMode is true, it allows powerpoint-
+	//		like functionality.  Clickable is used by powerpoint to
+	//		distinguish when things can be selected and when they can't
 	clickMode:true,
+
 	clickable:true,
 
 	// current: Object
@@ -29,15 +29,15 @@ dojox.drawing.defaults = {
 	currentHit:null,
 
 	// angleSnap: Number
-	// 		Line, arrows, vector and axes will all snap to this angle on mouse up
-	// 		shown angle also reflects the snap
-	// 		currently cannot accept less than 1 degree
+	//		Line, arrows, vector and axes will all snap to this angle on mouse up
+	//		shown angle also reflects the snap
+	//		currently cannot accept less than 1 degree
 	angleSnap:1,
 
 	// zAxis:  Boolean
-    // 		If true, draw current object in z-direction.
+    //		If true, draw current object in z-direction.
 	// zAxisEnabled: Boolean
-    // 		If true, render axes with Z-axis included, allow objects drawn in z-direction.
+    //		If true, render axes with Z-axis included, allow objects drawn in z-direction.
 	//		If false the z-axis button will not show up.
 	zAxis: false,
 	zAxisEnabled: true,
@@ -45,13 +45,13 @@ dojox.drawing.defaults = {
 	
 	// renderHitLines: Boolean
 	//		If true, renders a second, larger layer for lines to make
-	// 		them more easily clickable.
+	//		them more easily clickable.
 	renderHitLines: true,
-	//
+
 	// renderHitLayer:
-	// 		If true, renders a second layer for each Stencil, one
-	// 		acting as a 'hit' object for a wider mouse-click area.
-	// 		It also doubles as a hilight. If true, overrides
+	//		If true, renders a second layer for each Stencil, one
+	//		acting as a 'hit' object for a wider mouse-click area.
+	//		It also doubles as a hilight. If true, overrides
 	//		renderHitLines setting.
 	renderHitLayer:true,
 
@@ -60,14 +60,13 @@ dojox.drawing.defaults = {
 	//		Stencil's line color.
 	labelSameColor:false,
 
-	//
 	useSelectedStyle: true,
 
 	norm:{
 		// summary:
-		// 		Normal style of all shapes
-		// 		will get overridden by
-		// 		above andes styles
+		//		Normal style of all shapes
+		//		will get overridden by
+		//		above andes styles
 		width:1,
 		color:"#000000",
 		style:"Solid",
@@ -77,8 +76,8 @@ dojox.drawing.defaults = {
 
 	selected:{
 		// summary:
-		// 		Selected style of all shapes
-		// 		styles not shown will used from
+		//		Selected style of all shapes
+		//		styles not shown will used from
 		//	norm
 		width:6,
 		color:"#00FF00"
@@ -86,8 +85,8 @@ dojox.drawing.defaults = {
 
 	highlighted:{
 		// summary:
-		// 		Highlighted style of all shapes
-		// 		NOT CURRENTLY BEING USED
+		//		Highlighted style of all shapes
+		//		NOT CURRENTLY BEING USED
 		width:6,
 		color:"#FF00FF",
 		style:"Solid",
@@ -97,7 +96,7 @@ dojox.drawing.defaults = {
 
 	disabled:{
 		// summary:
-		// 		Disabled or "locked" or "fade" style of all shapes
+		//		Disabled or "locked" or "fade" style of all shapes
 		width:1,
 		color:"#666666",
 		style:"solid",
@@ -109,7 +108,6 @@ dojox.drawing.defaults = {
 	// that is usually larger than the object to give a
 	// larger 'target' to click upon. These hit objects
 	// double as highlights.
-	//
 	hitNorm:{
 		// summary:
 		//		Normal style of a hit area
@@ -141,7 +139,7 @@ dojox.drawing.defaults = {
 
 	anchors:{
 		// summary:
-		// 		Style for the anchor resize-points
+		//		Style for the anchor resize-points
 		size:10,
 		width:2,
 		color:"#999",
@@ -153,16 +151,16 @@ dojox.drawing.defaults = {
 	},
 	arrows:{
 		// summary:
-		// 		Size of arrows on vectors.
-		// 		length is in pixels
-		// 		width is actually an angle
-		// 		but is close to pixels in size
+		//		Size of arrows on vectors.
+		//		length is in pixels
+		//		width is actually an angle
+		//		but is close to pixels in size
 		length:30,
 		width:16
 	},
 	text:{
 		// summary:
-		// 		Style of text
+		//		Style of text
 		minWidth:100,
 		deleteEmptyCreate:true,
 		deleteEmptyModify:true,
@@ -174,7 +172,7 @@ dojox.drawing.defaults = {
 	},
 	textDisabled:{
 		// summary:
-		// 		Style of disabled text
+		//		Style of disabled text
 		size:"18px",
 		family:"sans-serif",
 		weight:"normal",
@@ -183,7 +181,7 @@ dojox.drawing.defaults = {
 
 	textMode:{
 		// summary:
-		// 		These styles apply to the containing
+		//		These styles apply to the containing
 		//		text box (edit mode), and not the text itself
 		create:{
 			width:2,
@@ -249,11 +247,11 @@ dojox.drawing.defaults = {
 	},
 
 	copy: function(){
-		// summary
+		// summary:
 		//		Each shape gets its own copy
 		//		of these styles so that instances
-		// 		do not change each other's styles
-		//
+		//		do not change each other's styles
+
 		var cpy = function(obj){
 				if(typeof(obj)!="object" || obj===null || obj===undefined){
 					return obj;
@@ -277,7 +275,7 @@ dojox.drawing.defaults = {
 				}
 			}
 			return o;
-		}
+		};
 		var o = cpy(this);
 		o.current = o.norm;
 		o.currentHit = o.hitNorm;
@@ -285,4 +283,4 @@ dojox.drawing.defaults = {
 		return o;
 	}
 
-};
+});
diff --git a/dojox/drawing/library/greek.js b/dojox/drawing/library/greek.js
index a0e816f..96f2a27 100644
--- a/dojox/drawing/library/greek.js
+++ b/dojox/drawing/library/greek.js
@@ -1,6 +1,4 @@
-dojo.provide("dojox.drawing.library.greek");
-
-dojox.drawing.library.greek = {
+define({
 	// summary:
 	//		Greek characters used by typesetter and greekPalette.
 	// description:
@@ -9,58 +7,57 @@ dojox.drawing.library.greek = {
 	//		can be included here and it will automatically be added
 	//		to the palette and converted by typesetter
         
-        "alpha": 945,   //alpha,     U+03B1 ISOgrk3 -->
-        "beta": 946,   //beta, U+03B2 ISOgrk3 -->
-        "gamma": 947,   //gamma,  U+03B3 ISOgrk3 -->
-        "delta": 948,   //delta,        U+03B4 ISOgrk3 -->
-        "epsilon": 949,   //epsilon,    U+03B5 ISOgrk3 -->
-        "zeta": 950,   //zeta, U+03B6 ISOgrk3 -->
-        "eta": 951,   //eta, U+03B7 ISOgrk3 -->
-        "theta": 952,   //theta,   U+03B8 ISOgrk3 -->
-        "iota": 953,   //iota, U+03B9 ISOgrk3 -->
-        "kappa": 954,   //kappa,   U+03BA ISOgrk3 -->
-        "lambda": 955,   //lambda,    U+03BB ISOgrk3 -->
-        "mu": 956,   //mu, U+03BC ISOgrk3 -->
-        "nu": 957,   //nu, U+03BD ISOgrk3 -->
-        "xi": 958,   //xi, U+03BE ISOgrk3 -->
-        "omicron": 959,   //omicron, U+03BF NEW -->
-        "pi": 960,   //pi, U+03C0 ISOgrk3 -->
-        "rho": 961,   //rho, U+03C1 ISOgrk3 -->
-        "sigmaf": 962,   //final sigma,  U+03C2 ISOgrk3 -->
-        "sigma": 963,   //sigma,  U+03C3 ISOgrk3 -->
-        "tau": 964,   //tau, U+03C4 ISOgrk3 -->
-        "upsilon": 965,   //upsilon,   U+03C5 ISOgrk3 -->
-        "phi": 966,   //phi, U+03C6 ISOgrk3 -->
-        "chi": 967,   //chi, U+03C7 ISOgrk3 -->
-        "psi": 968,   //psi, U+03C8 ISOgrk3 -->
-        "omega": 969,   //omega,      U+03C9 ISOgrk3 -->
-        "thetasym": 977,   //theta symbol,  U+03D1 NEW -->
-        "upsih": 978,     // upsilon with hook symbol,  U+03D2 NEW -->
-        "piv": 982,     // greek pi symbol, U+03D6 ISOgrk3 -->
-        "Alpha": 913,    // alpha, U+0391 -->
-        "Beta": 914,      // beta, U+0392 -->
-        "Gamma": 915,    //gamma, U+0393 ISOgrk3 -->
-        "Delta": 916,    //delta,           U+0394 ISOgrk3 -->
-        "Epsilon": 917,    //epsilon, U+0395 -->
-        "Zeta": 918,    //zeta, U+0396 -->
-        "Eta": 919,    //eta, U+0397 -->
-        "Theta": 920,    //theta,           U+0398 ISOgrk3 -->
-        "Iota": 921,    //iota, U+0399 -->
-        "Kappa": 922,    //kappa, U+039A -->
-        "Lambda": 923,    //lambda,      U+039B ISOgrk3 -->
-        "Mu": 924,    //mu, U+039C -->
-        "Nu": 925,    //nu, U+039D -->
-        "Xi": 926,    //xi, U+039E ISOgrk3 -->
-        "Omicron": 927,    //omicron, U+039F -->
-        "Pi": 928,    //pi, U+03A0 ISOgrk3 -->
-        "Rho": 929,    //rho, U+03A1 -->
-        "Sigma": 931,    //sigma,     U+03A3 ISOgrk3 -->
-        "Tau": 932,    //tau, U+03A4 -->
-        "Upsilon": 933,    //upsilon,   U+03A5 ISOgrk3 -->
-        "Phi": 934,    //phi, U+03A6 ISOgrk3 -->
-        "Chi": 935,    //chi, U+03A7 -->
-        "Psi": 936,    //psi,   U+03A8 ISOgrk3 -->
-        "Omega": 937    //omega,     U+03A9 ISOgrk3 -->
-};
-    
-    
\ No newline at end of file
+	"alpha": 945,   //alpha,     U+03B1 ISOgrk3 -->
+	"beta": 946,   //beta, U+03B2 ISOgrk3 -->
+	"gamma": 947,   //gamma,  U+03B3 ISOgrk3 -->
+	"delta": 948,   //delta,        U+03B4 ISOgrk3 -->
+	"epsilon": 949,   //epsilon,    U+03B5 ISOgrk3 -->
+	"zeta": 950,   //zeta, U+03B6 ISOgrk3 -->
+	"eta": 951,   //eta, U+03B7 ISOgrk3 -->
+	"theta": 952,   //theta,   U+03B8 ISOgrk3 -->
+	"iota": 953,   //iota, U+03B9 ISOgrk3 -->
+	"kappa": 954,   //kappa,   U+03BA ISOgrk3 -->
+	"lambda": 955,   //lambda,    U+03BB ISOgrk3 -->
+	"mu": 956,   //mu, U+03BC ISOgrk3 -->
+	"nu": 957,   //nu, U+03BD ISOgrk3 -->
+	"xi": 958,   //xi, U+03BE ISOgrk3 -->
+	"omicron": 959,   //omicron, U+03BF NEW -->
+	"pi": 960,   //pi, U+03C0 ISOgrk3 -->
+	"rho": 961,   //rho, U+03C1 ISOgrk3 -->
+	"sigmaf": 962,   //final sigma,  U+03C2 ISOgrk3 -->
+	"sigma": 963,   //sigma,  U+03C3 ISOgrk3 -->
+	"tau": 964,   //tau, U+03C4 ISOgrk3 -->
+	"upsilon": 965,   //upsilon,   U+03C5 ISOgrk3 -->
+	"phi": 966,   //phi, U+03C6 ISOgrk3 -->
+	"chi": 967,   //chi, U+03C7 ISOgrk3 -->
+	"psi": 968,   //psi, U+03C8 ISOgrk3 -->
+	"omega": 969,   //omega,      U+03C9 ISOgrk3 -->
+	"thetasym": 977,   //theta symbol,  U+03D1 NEW -->
+	"upsih": 978,     // upsilon with hook symbol,  U+03D2 NEW -->
+	"piv": 982,     // greek pi symbol, U+03D6 ISOgrk3 -->
+	"Alpha": 913,    // alpha, U+0391 -->
+	"Beta": 914,      // beta, U+0392 -->
+	"Gamma": 915,    //gamma, U+0393 ISOgrk3 -->
+	"Delta": 916,    //delta,           U+0394 ISOgrk3 -->
+	"Epsilon": 917,    //epsilon, U+0395 -->
+	"Zeta": 918,    //zeta, U+0396 -->
+	"Eta": 919,    //eta, U+0397 -->
+	"Theta": 920,    //theta,           U+0398 ISOgrk3 -->
+	"Iota": 921,    //iota, U+0399 -->
+	"Kappa": 922,    //kappa, U+039A -->
+	"Lambda": 923,    //lambda,      U+039B ISOgrk3 -->
+	"Mu": 924,    //mu, U+039C -->
+	"Nu": 925,    //nu, U+039D -->
+	"Xi": 926,    //xi, U+039E ISOgrk3 -->
+	"Omicron": 927,    //omicron, U+039F -->
+	"Pi": 928,    //pi, U+03A0 ISOgrk3 -->
+	"Rho": 929,    //rho, U+03A1 -->
+	"Sigma": 931,    //sigma,     U+03A3 ISOgrk3 -->
+	"Tau": 932,    //tau, U+03A4 -->
+	"Upsilon": 933,    //upsilon,   U+03A5 ISOgrk3 -->
+	"Phi": 934,    //phi, U+03A6 ISOgrk3 -->
+	"Chi": 935,    //chi, U+03A7 -->
+	"Psi": 936,    //psi,   U+03A8 ISOgrk3 -->
+	"Omega": 937    //omega,     U+03A9 ISOgrk3 -->
+});
+
diff --git a/dojox/drawing/library/icons.js b/dojox/drawing/library/icons.js
index ea73d08..d72b528 100644
--- a/dojox/drawing/library/icons.js
+++ b/dojox/drawing/library/icons.js
@@ -1,161 +1,256 @@
-dojo.provide("dojox.drawing.library.icons");
-
-dojox.drawing.library.icons = {
+define({
 	// summary:
 	//		A collection of icon Stencils for use with the buttons in the ui/Toolbar.
 	// description:
-	//		Each icon name coresponds to a Stencil or a Plugin. One can be inserted
+	//		Each icon name corresponds to a Stencil or a Plugin. One can be inserted
 	//		into a button by adding the property: 'icon', which points to one of
 	//		these Stencil objects.
-	line:{
-		type:"line",
-		borderWidth:1,
-		x1:20,
-		y1:20,
-		x2:80,
-		y2:80
-	},
-	ellipse:{
-		type:"ellipse",
-		borderWidth:1,
-		cx:50,
-		cy:50,
-		rx:35,
-		ry:20
-	},
-	rect:{
-		type:"rect",
-		borderWidth:1,
-		x:10,
-		y:30,
-		width:80,
-		height:40
-	},
-	triangle:{
-		type:"path",
-		borderWidth:1,
-		closePath:true,
-		points:[{x:50, y:10}, {x:10, y:90}, {x:90, y:90}]
-	},
-	path:{
-		type:"path",
-		borderWidth:0,
-		closePath:true,
-		points:[ { x:20, y:80 }, { x:26, y:20 }, { x:80, y:32 }, { x:32, y:50 }, { x:56, y:62 } ]
-	},
-	arrow:{
-		type:"path",
-		borderWidth:1,
-		closePath:false,
-		points:[ { x:20, y:20 }, { x:80, y:80 }, { t:'M', x:74, y:56 }, { x:80, y:80 }, { x:56, y:74 } ]
-	},
-	textBlock:{
-		type:"path",
-		borderWidth:0,
-		closePath:true,
-		points:[ { x:20, y:20 }, { x:80, y:20 }, { x:80, y:38 }, { x:80, y:38 }, { x:74, y:32 }, { x:68, y:26 }, { x:56, y:20 }, { x:56, y:68 }, { x:56, y:74 }, { x:62, y:80 }, { x:68, y:80 }, { x:68, y:80 }, { x:32, y:80 }, { x:32, y:80 }, { x:38, y:80 }, { x:44, y:74 }, { x:44, y:68 }, { x:44, y:20 }, { x:32, y:26 }, { x:26, y:32 }, { x:20, y:38 }, { x:20, y:38 } ]
-	},
-	
-	equation:{
-		type:"path",
-		borderWidth:2,
-		closePath:false,
-		points:[ {x:20, y:60 }, { x:80, y:60 }, {t:'M', x:20, y:40 }, { x:80, y:40 } ]
-	},
-	
-	axes:{
-		type:"path",
-		borderWidth:1,
-		closePath:false,
-		points:[ { x:20, y:32 }, { x:26, y:20 }, { x:32, y:32 }, { t:'M', x:26, y:20 }, { x:26, y:74 }, { x:80, y:74 }, { t:'M', x:68, y:68 }, { x:80, y:74 }, { x:68, y:80 } ]
-	},
-	vector:{
-		type:"path",
-		borderWidth:1,
-		closePath:false,
-		points:[ { x:20, y:80 }, { x:80, y:20 }, { t:'M', x:62, y:26 }, { x:80, y:20 }, { x:73, y:40 }, { t:'M', x:56, y:56 }, { x:62, y:68 }, { x:62, y:74 } ]
-	},
-	pan:{
-		type:"path",
-		borderWidth:1,
-		closePath:true,
-		points:[ { x:38, y:80 }, { x:26, y:68 }, { x:20, y:50 }, { x:26, y:44 }, { x:26, y:44 }, { x:38, y:56 }, { x:32, y:32 }, { x:32, y:26 }, { x:38, y:26 }, { x:44, y:44 }, { x:44, y:20 }, { x:50, y:20 }, { x:56, y:20 }, { x:56, y:44 }, { x:56, y:26 }, { x:62, y:26 }, { x:68, y:26 }, { x:68, y:50 }, { x:68, y:32 }, { x:74, y:32 }, { x:80, y:38 }, { x:80, y:50 }, { x:74, y:68 }, { x:68, y:80 } ]
-	},
-	
-	plus:{
-		type:"path",
-		borderWidth:3,
-		closePath:false,
-		points:[ { x:50, y:20 }, { x:50, y:80 }, { t:"M", x:20, y:50 }, { x:80, y:50 } ]
-	},
-	zoomIn:{
-		type:"path",
-		borderWidth:3,
-		closePath:false,
-		points:[ { x:50, y:20 }, { x:50, y:80 }, { t:"M", x:20, y:50 }, { x:80, y:50 } ]
-	},
-	zoomOut:{
-		type:"path",
-		borderWidth:3,
-		closePath:false,
-		points:[ {x:20, y:50 }, { x:80, y:50 } ]
-	},
-	zoom100:{
-		type:"text",
-		text:"100%"
-	},
-	iconize:{
-		type:"path",
-		borderWidth:0,
-		closePath:true,
-		points:
-		
-[
-{	x:20,		y:38	},
-{	x:32,		y:26	},
-{	x:44,		y:26	},
-{	x:56,		y:38	},
-{	x:56,		y:50	},
-{	x:44,		y:62	},
-{	x:32,		y:62	},
-{	x:20,		y:56	},
-{	t:'Z'	},
-{	t:'M', x:38,		y:44	},
-{	x:68,		y:44	},
-{	x:68,		y:80	},
-{	x:38,		y:80	},
-{	t:'Z'	},
-{	t:'M', x:56,		y:62	},
-{	x:68,		y:20	},
-{	x:80,		y:62	}
-]
-		
-	},
-	pencil:{
-		type:"path",
-		borderWidth:0,
-		closePath:true,
-		points:
-		
-[
-{	x:20,		y:80	},
-{	x:26,		y:68	},
-{	x:68,		y:20	},
-{	x:80,		y:20	},
-{	x:80,		y:32	},
-{	x:38,		y:74	},
-{	t:'Z'	},
-{	t:'M', x:62,		y:32	},
-{	x:68,		y:26	},
-{	x:74,		y:26	},
-{	x:74,		y:32	},
-{	x:68,		y:38	},
-{	x:68,		y:32	},
-{	t:'Z'	},
-{	t:'M', x:56,		y:38	},
-{	x:62,		y:38	},
-{	x:32,		y:68	},
-{	x:32,		y:68	}
-]
+	line: {
+		type: "line",
+		borderWidth: 1,
+		x1: 20,
+		y1: 20,
+		x2: 80,
+		y2: 80
+	},
+	ellipse: {
+		type: "ellipse",
+		borderWidth: 1,
+		cx: 50,
+		cy: 50,
+		rx: 35,
+		ry: 20
+	},
+	rect: {
+		type: "rect",
+		borderWidth: 1,
+		x: 10,
+		y: 30,
+		width: 80,
+		height: 40
+	},
+	triangle: {
+		type: "path",
+		borderWidth: 1,
+		closePath: true,
+		points: [
+			{x: 50, y: 10},
+			{x: 10, y: 90},
+			{x: 90, y: 90}
+		]
+	},
+	path: {
+		type: "path",
+		borderWidth: 0,
+		closePath: true,
+		points: [
+			{ x: 20, y: 80 },
+			{ x: 26, y: 20 },
+			{ x: 80, y: 32 },
+			{ x: 32, y: 50 },
+			{ x: 56, y: 62 }
+		]
+	},
+	arrow: {
+		type: "path",
+		borderWidth: 1,
+		closePath: false,
+		points: [
+			{ x: 20, y: 20 },
+			{ x: 80, y: 80 },
+			{ t: 'M', x: 74, y: 56 },
+			{ x: 80, y: 80 },
+			{ x: 56, y: 74 }
+		]
+	},
+	textBlock: {
+		type: "path",
+		borderWidth: 0,
+		closePath: true,
+		points: [
+			{ x: 20, y: 20 },
+			{ x: 80, y: 20 },
+			{ x: 80, y: 38 },
+			{ x: 80, y: 38 },
+			{ x: 74, y: 32 },
+			{ x: 68, y: 26 },
+			{ x: 56, y: 20 },
+			{ x: 56, y: 68 },
+			{ x: 56, y: 74 },
+			{ x: 62, y: 80 },
+			{ x: 68, y: 80 },
+			{ x: 68, y: 80 },
+			{ x: 32, y: 80 },
+			{ x: 32, y: 80 },
+			{ x: 38, y: 80 },
+			{ x: 44, y: 74 },
+			{ x: 44, y: 68 },
+			{ x: 44, y: 20 },
+			{ x: 32, y: 26 },
+			{ x: 26, y: 32 },
+			{ x: 20, y: 38 },
+			{ x: 20, y: 38 }
+		]
+	},
+
+	equation: {
+		type: "path",
+		borderWidth: 2,
+		closePath: false,
+		points: [
+			{x: 20, y: 60 },
+			{ x: 80, y: 60 },
+			{t: 'M', x: 20, y: 40 },
+			{ x: 80, y: 40 }
+		]
+	},
+
+	axes: {
+		type: "path",
+		borderWidth: 1,
+		closePath: false,
+		points: [
+			{ x: 20, y: 32 },
+			{ x: 26, y: 20 },
+			{ x: 32, y: 32 },
+			{ t: 'M', x: 26, y: 20 },
+			{ x: 26, y: 74 },
+			{ x: 80, y: 74 },
+			{ t: 'M', x: 68, y: 68 },
+			{ x: 80, y: 74 },
+			{ x: 68, y: 80 }
+		]
+	},
+	vector: {
+		type: "path",
+		borderWidth: 1,
+		closePath: false,
+		points: [
+			{ x: 20, y: 80 },
+			{ x: 80, y: 20 },
+			{ t: 'M', x: 62, y: 26 },
+			{ x: 80, y: 20 },
+			{ x: 73, y: 40 },
+			{ t: 'M', x: 56, y: 56 },
+			{ x: 62, y: 68 },
+			{ x: 62, y: 74 }
+		]
+	},
+	pan: {
+		type: "path",
+		borderWidth: 1,
+		closePath: true,
+		points: [
+			{ x: 38, y: 80 },
+			{ x: 26, y: 68 },
+			{ x: 20, y: 50 },
+			{ x: 26, y: 44 },
+			{ x: 26, y: 44 },
+			{ x: 38, y: 56 },
+			{ x: 32, y: 32 },
+			{ x: 32, y: 26 },
+			{ x: 38, y: 26 },
+			{ x: 44, y: 44 },
+			{ x: 44, y: 20 },
+			{ x: 50, y: 20 },
+			{ x: 56, y: 20 },
+			{ x: 56, y: 44 },
+			{ x: 56, y: 26 },
+			{ x: 62, y: 26 },
+			{ x: 68, y: 26 },
+			{ x: 68, y: 50 },
+			{ x: 68, y: 32 },
+			{ x: 74, y: 32 },
+			{ x: 80, y: 38 },
+			{ x: 80, y: 50 },
+			{ x: 74, y: 68 },
+			{ x: 68, y: 80 }
+		]
+	},
+
+	plus: {
+		type: "path",
+		borderWidth: 3,
+		closePath: false,
+		points: [
+			{ x: 50, y: 20 },
+			{ x: 50, y: 80 },
+			{ t: "M", x: 20, y: 50 },
+			{ x: 80, y: 50 }
+		]
+	},
+	zoomIn: {
+		type: "path",
+		borderWidth: 3,
+		closePath: false,
+		points: [
+			{ x: 50, y: 20 },
+			{ x: 50, y: 80 },
+			{ t: "M", x: 20, y: 50 },
+			{ x: 80, y: 50 }
+		]
+	},
+	zoomOut: {
+		type: "path",
+		borderWidth: 3,
+		closePath: false,
+		points: [
+			{x: 20, y: 50 },
+			{ x: 80, y: 50 }
+		]
+	},
+	zoom100: {
+		type: "text",
+		text: "100%"
+	},
+	iconize: {
+		type: "path",
+		borderWidth: 0,
+		closePath: true,
+		points: [
+			{    x: 20, y: 38    },
+			{    x: 32, y: 26    },
+			{    x: 44, y: 26    },
+			{    x: 56, y: 38    },
+			{    x: 56, y: 50    },
+			{    x: 44, y: 62    },
+			{    x: 32, y: 62    },
+			{    x: 20, y: 56    },
+			{    t: 'Z'    },
+			{    t: 'M', x: 38, y: 44    },
+			{    x: 68, y: 44    },
+			{    x: 68, y: 80    },
+			{    x: 38, y: 80    },
+			{    t: 'Z'    },
+			{    t: 'M', x: 56, y: 62    },
+			{    x: 68, y: 20    },
+			{    x: 80, y: 62    }
+		]
+
+	},
+	pencil: {
+		type: "path",
+		borderWidth: 0,
+		closePath: true,
+		points: [
+			{    x: 20, y: 80    },
+			{    x: 26, y: 68    },
+			{    x: 68, y: 20    },
+			{    x: 80, y: 20    },
+			{    x: 80, y: 32    },
+			{    x: 38, y: 74    },
+			{    t: 'Z'    },
+			{    t: 'M', x: 62, y: 32    },
+			{    x: 68, y: 26    },
+			{    x: 74, y: 26    },
+			{    x: 74, y: 32    },
+			{    x: 68, y: 38    },
+			{    x: 68, y: 32    },
+			{    t: 'Z'    },
+			{    t: 'M', x: 56, y: 38    },
+			{    x: 62, y: 38    },
+			{    x: 32, y: 68    },
+			{    x: 32, y: 68    }
+		]
 	}
-};
\ No newline at end of file
+});
diff --git a/dojox/drawing/manager/Anchors.js b/dojox/drawing/manager/Anchors.js
index ef5ae39..9109196 100755
--- a/dojox/drawing/manager/Anchors.js
+++ b/dojox/drawing/manager/Anchors.js
@@ -1,209 +1,15 @@
-dojo.provide("dojox.drawing.manager.Anchors");
+define(["dojo", "../util/oo", "../defaults"], 
+function(dojo, oo, defaults){
 
-dojox.drawing.manager.Anchors = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Creates and manages the anchor points that are attached to
-	//		(usually) the corners of a Stencil.
-	// description:
-	//		Used internally, but there are some things that should be known:
-	//		Anchors attach to a Stencil's 'points' (See stencil.points)
-	//		To not display an anchor on a certain point, add noAnchor:true
-	//		to the point.
-	
-	function(/* dojox.__stencilArgs */options){
-		// arguments: See stencil._Base
-		this.mouse = options.mouse;
-		this.undo = options.undo;
-		this.util = options.util;
-		this.drawing = options.drawing;
-		this.items = {};
-	},
-	{
-		onAddAnchor: function(/*Anchor*/anchor){
-			// summary:
-			//		Event fires when anchor is created
-		},
-		
-		
-		onReset: function(/*Stencil*/stencil){
-			// summary:
-			//		Event fires when an anchor's reset method is called
-			//
-			// a desperate hack in order to get the anchor point to reset.
-			// FIXME: Is this still used? I think its item.deselect();item.select();
-			var st = this.util.byId("drawing").stencils;
-			st.onDeselect(stencil);
-			st.onSelect(stencil);
-		},
-		
-		onRenderStencil: function(){
-			// summary:
-			//		Event fires when an anchor calls a Stencil's render method
-			//
-			for(var nm in this.items){
-				dojo.forEach(this.items[nm].anchors, function(a){
-					a.shape.moveToFront();
-				});
-			}
-		},
-		
-		onTransformPoint: function(/*Anchor*/anchor){
-			// summary:
-			//		Event fired on anchor drag
-			//
-			//		If anchors are a "group", it's corresponding anchor
-			//		is set. All anchors then moved to front.
-			var anchors = this.items[anchor.stencil.id].anchors;
-			var item = this.items[anchor.stencil.id].item;
-			var pts = [];
-			dojo.forEach(anchors, function(a, i){
-				
-				
-				if(anchor.id == a.id || anchor.stencil.anchorType!="group"){
-					// nothing
-				}else{
-					if(anchor.org.y == a.org.y){
-						a.setPoint({
-							dx: 0,
-							dy: anchor.shape.getTransform().dy - a.shape.getTransform().dy
-						});
-					}else if(anchor.org.x == a.org.x){
-						a.setPoint({
-							dx: anchor.shape.getTransform().dx - a.shape.getTransform().dx,
-							dy: 0
-						});
-					}
-					a.shape.moveToFront();
-				}
-				
-				var mx = a.shape.getTransform();
-				pts.push({x:mx.dx + a.org.x, y:mx.dy+ a.org.y});
-				
-				if(a.point.t){
-					pts[pts.length-1].t = a.point.t;
-				}
-				
-			}, this);
-			item.setPoints(pts);
-			item.onTransform(anchor);
-			this.onRenderStencil();
-		},
-		
-		onAnchorUp: function(/*Anchor*/anchor){
-			// summary:
-			//		Event fired on anchor mouseup
-		},
-		
-		onAnchorDown: function(/*Anchor*/anchor){
-			// summary:
-			//		Event fired on anchor mousedown
-		},
-		
-		onAnchorDrag: function(/*Anchor*/anchor){
-			// summary:
-			//		Event fired when anchor is moved
-		},
-		
-		onChangeStyle: function(/*Object*/stencil){
-			// summary:
-			// 		if the Stencil changes color while were's selected
-			// 		this moves the anchors to the back. Fix it.
-			
-			for(var nm in this.items){
-				dojo.forEach(this.items[nm].anchors, function(a){
-					a.shape.moveToFront();
-				});
-			}
-		},
-		
-		add: function(/*Stencil*/item){
-			// summary:
-			//		Creates anchor points on a Stencil, based on the
-			//		Stencil's points.
-			//
-			this.items[item.id] = {
-				item:item,
-				anchors:[]
-			};
-			if(item.anchorType=="none"){ return; }
-			var pts = item.points;
-			dojo.forEach(pts, function(p, i){
-				if(p.noAnchor){ return; }
-				if(i==0 || i == item.points.length-1){
-					console.log("ITEM TYPE:", item.type, item.shortType);
-				}
-				var a = new dojox.drawing.manager.Anchor({stencil:item, point:p, pointIdx:i, mouse:this.mouse, util:this.util});
-				this.items[item.id]._cons = [
-					dojo.connect(a, "onRenderStencil", this, "onRenderStencil"),
-					dojo.connect(a, "reset", this, "onReset"),
-					dojo.connect(a, "onAnchorUp", this, "onAnchorUp"),
-					dojo.connect(a, "onAnchorDown", this, "onAnchorDown"),
-					dojo.connect(a, "onAnchorDrag", this, "onAnchorDrag"),
-					dojo.connect(a, "onTransformPoint", this, "onTransformPoint"),
-					// FIXME: this will fire for each anchor. yech.
-					dojo.connect(item, "onChangeStyle", this, "onChangeStyle")
-				];
-				
-				this.items[item.id].anchors.push(a);
-				this.onAddAnchor(a);
-			}, this);
-			
-			if(item.shortType=="path"){
-				// check if we have a double-point of a closed-curve-path
-				var f = pts[0], l = pts[pts.length-1], a = this.items[item.id].anchors;
-				if(f.x ==l.x && f.y==l.y){
-					console.warn("LINK ANVHROS", a[0], a[a.length-1]);
-					a[0].linkedAnchor = a[a.length-1];
-					a[a.length-1].linkedAnchor = a[0];
-				}
-			}
-			
-			if(item.anchorType=="group"){
-				dojo.forEach(this.items[item.id].anchors, function(anchor){
-					dojo.forEach(this.items[item.id].anchors, function(a){
-						if(anchor.id != a.id){
-							if(anchor.org.y == a.org.y){
-								anchor.x_anchor = a;
-							}else if(anchor.org.x == a.org.x){
-								anchor.y_anchor = a;
-							}
-						}
-					},this);
-				},this);
-				
-			}
-		},
-		
-		remove: function(/*Stencil*/item){
-			// summary:
-			//		Destroys the anchor points for a Stencil.
-			//
-			if(!this.items[item.id]){
-				return;
-			}
-			dojo.forEach(this.items[item.id].anchors, function(a){
-				a.destroy();
-			});
-			dojo.forEach(this.items[item.id]._cons, dojo.disconnect, dojo);
-			this.items[item.id].anchors = null;
-			delete this.items[item.id];
-		}
-	}
-);
-
-dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
-	// summary:
-	//		An anchor point that is attached to (usually) one of the
-	//		corners of a Stencil.
-	//		Used internally.
-	function(/* Object */options){
+var Anchor = oo.declare(
+	function(/* Object */ options){
 		// summary:
 		//		constructor.
-		//		arguments:
-		//			dojox.__stencilArgs plus some additional
-		//			data, like which point this is (pointIdx)
-		//
-		this.defaults = dojox.drawing.defaults.copy();
+		// options:
+		//		dojox.__stencilArgs plus some additional
+		//		data, like which point this is (pointIdx)
+
+		this.defaults = defaults.copy();
 		this.mouse = options.mouse;
 		this.point = options.point;
 		this.pointIdx = options.pointIdx;
@@ -222,13 +28,18 @@ dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
 		this.connectMouse();
 	},
 	{
+		// summary:
+		//		An anchor point that is attached to (usually) one of the
+		//		corners of a Stencil.
+		//		Used internally.
+
 		y_anchor:null,
 		x_anchor:null,
 		render: function(){
 			// summary:
 			//		Creates the anchor point. Unlike most render methods
 			//		in Drawing, this is only called once.
-			//
+
 			this.shape && this.shape.removeShape();
 			var d = this.defaults.anchors,
 				z = this.mouse.zoom,
@@ -347,10 +158,7 @@ dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
 						y = conT;
 					}
 				}
-				
-				
-				
-				
+
 				if(this.x_anchor){
 					// prevent x overlap of opposite anchor
 					
@@ -462,3 +270,194 @@ dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
 		}
 	}
 );
+
+//dojox.drawing.manager.Anchors = 
+return oo.declare(
+	// summary:
+	//		Creates and manages the anchor points that are attached to
+	//		(usually) the corners of a Stencil.
+	// description:
+	//		Used internally, but there are some things that should be known:
+	//		Anchors attach to a Stencil's 'points' (See stencil.points)
+	//		To not display an anchor on a certain point, add noAnchor:true
+	//		to the point.
+	
+	function(/* dojox.__stencilArgs */options){
+		this.mouse = options.mouse;
+		this.undo = options.undo;
+		this.util = options.util;
+		this.drawing = options.drawing;
+		this.items = {};
+	},
+	{
+		onAddAnchor: function(/*Anchor*/anchor){
+			// summary:
+			//		Event fires when anchor is created
+		},
+		
+		
+		onReset: function(/*Stencil*/stencil){
+			// summary:
+			//		Event fires when an anchor's reset method is called
+
+			// a desperate hack in order to get the anchor point to reset.
+			// FIXME: Is this still used? I think its item.deselect();item.select();
+			var st = this.util.byId("drawing").stencils;
+			st.onDeselect(stencil);
+			st.onSelect(stencil);
+		},
+		
+		onRenderStencil: function(){
+			// summary:
+			//		Event fires when an anchor calls a Stencil's render method
+
+			for(var nm in this.items){
+				dojo.forEach(this.items[nm].anchors, function(a){
+					a.shape.moveToFront();
+				});
+			}
+		},
+		
+		onTransformPoint: function(/*Anchor*/anchor){
+			// summary:
+			//		Event fired on anchor drag
+
+			// If anchors are a "group", it's corresponding anchor
+			// is set. All anchors then moved to front.
+			var anchors = this.items[anchor.stencil.id].anchors;
+			var item = this.items[anchor.stencil.id].item;
+			var pts = [];
+			dojo.forEach(anchors, function(a, i){
+				if(anchor.id == a.id || anchor.stencil.anchorType!="group"){
+					// nothing
+				}else{
+					if(anchor.org.y == a.org.y){
+						a.setPoint({
+							dx: 0,
+							dy: anchor.shape.getTransform().dy - a.shape.getTransform().dy
+						});
+					}else if(anchor.org.x == a.org.x){
+						a.setPoint({
+							dx: anchor.shape.getTransform().dx - a.shape.getTransform().dx,
+							dy: 0
+						});
+					}
+					a.shape.moveToFront();
+				}
+				
+				var mx = a.shape.getTransform();
+				pts.push({x:mx.dx + a.org.x, y:mx.dy+ a.org.y});
+				
+				if(a.point.t){
+					pts[pts.length-1].t = a.point.t;
+				}
+				
+			}, this);
+			item.setPoints(pts);
+			item.onTransform(anchor);
+			this.onRenderStencil();
+		},
+		
+		onAnchorUp: function(/*Anchor*/anchor){
+			// summary:
+			//		Event fired on anchor mouseup
+		},
+		
+		onAnchorDown: function(/*Anchor*/anchor){
+			// summary:
+			//		Event fired on anchor mousedown
+		},
+		
+		onAnchorDrag: function(/*Anchor*/anchor){
+			// summary:
+			//		Event fired when anchor is moved
+		},
+		
+		onChangeStyle: function(/*Object*/stencil){
+			// summary:
+			//		if the Stencil changes color while were's selected
+			//		this moves the anchors to the back. Fix it.
+			
+			for(var nm in this.items){
+				dojo.forEach(this.items[nm].anchors, function(a){
+					a.shape.moveToFront();
+				});
+			}
+		},
+		
+		add: function(/*Stencil*/item){
+			// summary:
+			//		Creates anchor points on a Stencil, based on the
+			//		Stencil's points.
+
+			this.items[item.id] = {
+				item:item,
+				anchors:[]
+			};
+			if(item.anchorType=="none"){ return; }
+			var pts = item.points;
+			dojo.forEach(pts, function(p, i){
+				if(p.noAnchor){ return; }
+				if(i==0 || i == item.points.length-1){
+					console.log("ITEM TYPE:", item.type, item.shortType);
+				}
+				var a = new Anchor({stencil:item, point:p, pointIdx:i, mouse:this.mouse, util:this.util});
+				this.items[item.id]._cons = [
+					dojo.connect(a, "onRenderStencil", this, "onRenderStencil"),
+					dojo.connect(a, "reset", this, "onReset"),
+					dojo.connect(a, "onAnchorUp", this, "onAnchorUp"),
+					dojo.connect(a, "onAnchorDown", this, "onAnchorDown"),
+					dojo.connect(a, "onAnchorDrag", this, "onAnchorDrag"),
+					dojo.connect(a, "onTransformPoint", this, "onTransformPoint"),
+					// FIXME: this will fire for each anchor. yech.
+					dojo.connect(item, "onChangeStyle", this, "onChangeStyle")
+				];
+				
+				this.items[item.id].anchors.push(a);
+				this.onAddAnchor(a);
+			}, this);
+			
+			if(item.shortType=="path"){
+				// check if we have a double-point of a closed-curve-path
+				var f = pts[0], l = pts[pts.length-1], a = this.items[item.id].anchors;
+				if(f.x ==l.x && f.y==l.y){
+					console.warn("LINK ANVHROS", a[0], a[a.length-1]);
+					a[0].linkedAnchor = a[a.length-1];
+					a[a.length-1].linkedAnchor = a[0];
+				}
+			}
+			
+			if(item.anchorType=="group"){
+				dojo.forEach(this.items[item.id].anchors, function(anchor){
+					dojo.forEach(this.items[item.id].anchors, function(a){
+						if(anchor.id != a.id){
+							if(anchor.org.y == a.org.y){
+								anchor.x_anchor = a;
+							}else if(anchor.org.x == a.org.x){
+								anchor.y_anchor = a;
+							}
+						}
+					},this);
+				},this);
+				
+			}
+		},
+		
+		remove: function(/*Stencil*/item){
+			// summary:
+			//		Destroys the anchor points for a Stencil.
+
+			if(!this.items[item.id]){
+				return;
+			}
+			dojo.forEach(this.items[item.id].anchors, function(a){
+				a.destroy();
+			});
+			dojo.forEach(this.items[item.id]._cons, dojo.disconnect, dojo);
+			this.items[item.id].anchors = null;
+			delete this.items[item.id];
+		}
+	}
+);
+
+});
diff --git a/dojox/drawing/manager/Canvas.js b/dojox/drawing/manager/Canvas.js
index 47df302..b63c3de 100755
--- a/dojox/drawing/manager/Canvas.js
+++ b/dojox/drawing/manager/Canvas.js
@@ -1,24 +1,14 @@
-dojo.provide("dojox.drawing.manager.Canvas");
+define(["dojo", "../util/oo", "dojox/gfx"], 
+function(dojo, oo, gfx){
 
-(function(){
-	
-	dojox.drawing.manager.Canvas = dojox.drawing.util.oo.declare(
-		// summary:
-		//		Creates a dojox.gfx.surface to be used for Drawing. Note that
-		//		The 'surface' that Drawing uses is actually a dojox.gfx.group.
-		//		This allows for more versatility.
-		//
-		//		Called internally from a dojox.Drawing.
-		//
-		//		Note: Surface creation is asynchrous. Connect to
-		//  		onSurfaceReady in Drawing.
-		//
+	//dojox.drawing.manager.Canvas = 
+	return oo.declare(
 		function(/*Object*/options){
 			dojo.mixin(this, options);
 			
 			var dim = dojo.contentBox(this.srcRefNode);
-			this.height = this.parentHeight = dim.h;
-			this.width = this.parentWidth = dim.w;
+			this.height = this.parentHeight = options.height || dim.h;
+			this.width = this.parentWidth = options.width || dim.w;
 			this.domNode = dojo.create("div", {id:"canvasNode"}, this.srcRefNode);
 			dojo.style(this.domNode, {
 				width:this.width,
@@ -30,13 +20,13 @@ dojo.provide("dojox.drawing.manager.Canvas");
 			this.id = this.id || this.util.uid("surface");
 			
 			console.info("create canvas");
-			this.gfxSurface = dojox.gfx.createSurface(this.domNode, this.width, this.height);
+			this.gfxSurface = gfx.createSurface(this.domNode, this.width, this.height);
 			this.gfxSurface.whenLoaded(this, function(){
 				setTimeout(dojo.hitch(this, function(){
 					this.surfaceReady = true;
 					if(dojo.isIE){
 						//this.gfxSurface.rawNode.parentNode.id = this.id;
-					}else if(dojox.gfx.renderer == "silverlight"){
+					}else if(gfx.renderer == "silverlight"){
 						this.id = this.domNode.firstChild.id
 					}else{
 						//this.gfxSurface.rawNode.id = this.id;
@@ -56,8 +46,18 @@ dojo.provide("dojox.drawing.manager.Canvas");
 			this._mouseHandle = this.mouse.register(this);
 		},
 		{
+			// summary:
+			//		Creates a dojox.gfx.surface to be used for Drawing. Note that
+			//		The 'surface' that Drawing uses is actually a dojox.gfx.group.
+			//		This allows for more versatility.
+			//
+			//		Called internally from a dojox.Drawing.
+			//
+			//		Note: Surface creation is asynchronous. Connect to
+			//		onSurfaceReady in Drawing.
+
 			// zoom: [readonly] Number
-			//	The amount the canvas is zoomed
+			//		The amount the canvas is zoomed
 			zoom:1,
 						
 			useScrollbars: true,
@@ -68,7 +68,7 @@ dojo.provide("dojox.drawing.manager.Canvas");
 				//		Method used to change size of canvas. Potentially
 				//		called from a container like ContentPane. May be
 				//		called directly.
-				//
+
 				this.parentWidth = width;
 				this.parentHeight = height;
 				this.setDimensions(width, height);
@@ -78,7 +78,7 @@ dojo.provide("dojox.drawing.manager.Canvas");
 				// summary:
 				//		Internal. Changes canvas size and sets scroll position.
 				//		Do not call this, use resize().
-				//
+
 				// changing the size of the surface and setting scroll
 				// if items are off screen
 				var sw = this.getScrollWidth(); //+ 10;
@@ -140,8 +140,8 @@ dojo.provide("dojox.drawing.manager.Canvas");
 			getScrollWidth: function(){
 				// summary:
 				//		Special method used to detect the width (and height)
-				// 		of the browser scrollbars. Becomes memoized.
-				//
+				//		of the browser scrollbars. Becomes memoized.
+
 				var p = dojo.create('div');
 				p.innerHTML = '<div style="width:50px;height:50px;overflow:hidden;position:absolute;top:0;left:-1000px;"><div style="height:100px;"></div>';
 				var div = p.firstChild;
@@ -158,4 +158,4 @@ dojo.provide("dojox.drawing.manager.Canvas");
 		}
 	);
 	
-})();
\ No newline at end of file
+});
diff --git a/dojox/drawing/manager/Mouse.js b/dojox/drawing/manager/Mouse.js
index 1e91eef..1e27a95 100755
--- a/dojox/drawing/manager/Mouse.js
+++ b/dojox/drawing/manager/Mouse.js
@@ -1,22 +1,8 @@
-dojo.provide("dojox.drawing.manager.Mouse");
+define(["dojo", "../util/oo", "../defaults"], 
+function(dojo, oo, defaults){
 
-dojox.drawing.manager.Mouse = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Master object (instance) that tracks mouse
-	//		events. A new instance is created for each
-	//		Drawing object.
-	// description:
-	//		You could connect to any method or event in this
-	//		class, but it is designed to have the object
-	//		'registered'. All objects with the current event
-	//		will be called directly.
-	//
-	//		Custom events are used often. In addition to
-	//		standard events onDown, onUp, onDrag, etc, if
-	//		a certain object is clicked upon (or dragged, etc),
-	//		that object's drawingType will create the custom event,
-	//		such as onAnchorDown, or onStencilDown.
-	//
+//dojox.drawing.manager.Mouse = 
+return oo.declare(
 	function(/* Object */options){
 		this.util = options.util;
 		this.keys = options.keys;
@@ -26,6 +12,23 @@ dojox.drawing.manager.Mouse = dojox.drawing.util.oo.declare(
 	},
 	
 	{
+		// summary:
+		//		Master object (instance) that tracks mouse
+		//		events. A new instance is created for each
+		//		Drawing object.
+		// description:
+		//		You could connect to any method or event in this
+		//		class, but it is designed to have the object
+		//		'registered'. All objects with the current event
+		//		will be called directly.
+		//
+		//		Custom events are used often. In addition to
+		//		standard events onDown, onUp, onDrag, etc, if
+		//		a certain object is clicked upon (or dragged, etc),
+		//		that object's drawingType will create the custom event,
+		//		such as onAnchorDown, or onStencilDown.
+
+
 		// doublClickSpeed: Number
 		//		Milliseconds between clicks to
 		//		register as for onDoubleClick
@@ -38,86 +41,84 @@ dojox.drawing.manager.Mouse = dojox.drawing.util.oo.declare(
 		__reg:0,
 		_downOnCanvas:false,
 		
-/*=====
-CustomEventMethod: function(){
-	// summary:
-	//		The custom event method that an Object that has
-	//		registered with manager.Mouse can receive.
-	//		Can contain any or all of the following methods
-	//		and they will be called as mouse events. All events
-	//		will be sent a EventObject event object.
-	//	NOTE:
-	//		Events happen anywhere in the document unless
-	//		otherwise noted.
-	//
-	//	onMove
-	//		Fires on mousemove when mouse is up
-	//	onDown
-	//		Fires on mousedown *on the canvas*
-	//	onDrag
-	//		Fires on mousemove when mouse is down
-	//	onUp
-	//		Fires on mouseup, anywhere in the document
-	//	onStencilDown
-	//		Fired on mousedown on a Stencil
-	//	onStencilDrag
-	//		Fired when mouse moves and mose is down on a Stencil
-	//	onStencilUp
-	//		Fired on mouseup off of a Stencil
-	//	on[Custom]Up|Down|Move
-	//		Custom events can bet set and fired by setting a
-	//		different drawingType on a Stencil, or by calling
-	//		setEventMode(customEventName)
-},
-EventObject: function(){
-	// summary:
-	//		The custom event object that is sent to registered objects
-	//		and their respective methods.
-	//	NOTE: Most event objects are the same with the exception
-	//		of the onDown events, which have fewer.
-	//
-	// All event properties included onDown:
-	//
-	//	id: String
-	//		Id of the focused object
-	//	pageX: Number
-	//		The X coordinate of the mouse from the left side of
-	//		the document.
-	//	pageY: Number
-	//		The Y coordinate of the mouse from the top of
-	//		the document.
-	//	x:	Number
-	//		The X coordinate of the mouse from the left side
-	//		of the canvas
-	//	y:	Number
-	//		The Y coordinate of the mouse from the top
-	//		of the canvas
-	//
-	// These event properties are *not* in onDown:
-	//
-	//	last:	Object
-	//		The x and y coordinates of the last mousemove
-	//		relative to the canvas
-	//	move: Object
-	//		The x and y amounts the mouse moved since the last event
-	//	orgX:	Number
-	//		The left side of the canvas from the side of the document
-	//	orgY:	Number
-	//		The top of the canvas from the top of the document
-	//	scroll: Object
-	//		The 'top' and 'left' scroll amounts of the canvas.
-	//	start:	Object
-	//		The x and y coordinates of the mousedown event
-	//	withinCanvas: Boolean
-	//		Whether the event happened within the Canvas or not
-	
-},
-=====*/
+		/*=====
+		CustomEventMethod: {
+			// summary:
+			//		The custom event methods that an Object that has
+			//		registered with manager.Mouse can receive.
+			//		Can contain any or all of the following methods
+			//		and they will be called on mouse events. All events
+			//		will be sent a EventObject event object.
+			//
+			//		NOTE:
+			//		Events happen anywhere in the document unless
+			//		otherwise noted.
+
+			// onMove: Function
+			//		Fires on mousemove when mouse is up
+			// onDown: Function
+			//		Fires on mousedown *on the canvas*
+			// onDrag: Function
+			//		Fires on mousemove when mouse is down
+			// onUp: Function
+			//		Fires on mouseup, anywhere in the document
+			// onStencilDown: Function
+			//		Fired on mousedown on a Stencil
+			// onStencilDrag: Function
+			//		Fired when mouse moves and mose is down on a Stencil
+			// onStencilUp: Function
+			//		Fired on mouseup off of a Stencil
+			// on[Custom]Up|Down|Move: Function
+			//		Custom events can bet set and fired by setting a
+			//		different drawingType on a Stencil, or by calling
+			//		setEventMode(customEventName)
+		},
+		EventObject: function(){
+			// summary:
+			//		The custom event object that is sent to registered objects
+			//		and their respective methods.
+			//
+			//		NOTE: Most event objects are the same with the exception
+			//		of the onDown events, which have fewer.
+
+			// id: String
+			//		Id of the focused object (included in onDown)
+			// pageX: Number
+			//		The X coordinate of the mouse from the left side of
+			//		the document. (included in onDown)
+			// pageY: Number
+			//		The Y coordinate of the mouse from the top of
+			//		the document. (included in onDown)
+			// x: Number
+			//		The X coordinate of the mouse from the left side
+			//		of the canvas (included in onDown)
+			// y: Number
+			//		The Y coordinate of the mouse from the top
+			//		of the canvas (included in onDown)
+
+			// last:	Object
+			//		The x and y coordinates of the last mousemove
+			//		relative to the canvas (not included in onDown)
+			// move: Object
+			//		The x and y amounts the mouse moved since the last event
+			//		(not included in onDown)
+			// orgX:	Number
+			//		The left side of the canvas from the side of the document (not included in onDown)
+			// orgY:	Number
+			//		The top of the canvas from the top of the document (not included in onDown)
+			// scroll: Object
+			//		The 'top' and 'left' scroll amounts of the canvas. (not included in onDown)
+			// start:	Object
+			//		The x and y coordinates of the mousedown event (not included in onDown)
+			// withinCanvas: Boolean
+			//		Whether the event happened within the Canvas or not (not included in onDown)
+		},
+		=====*/
 			
 		init: function(/* HTMLNode*/node){
-			//	summary:
+			// summary:
 			//		Internal. Initializes mouse.
-			//
+
 			this.container = node;
 			this.setCanvas();
 			var c;
@@ -157,7 +158,7 @@ EventObject: function(){
 		setCanvas: function(){
 			// summary:
 			//		Internal. Sets canvas position
-			var pos = dojo.coords(this.container.parentNode);
+			var pos = dojo.position(this.container.parentNode);
 			this.origin = dojo.clone(pos);
 		},
 		
@@ -177,24 +178,24 @@ EventObject: function(){
 			}
 		},
 
-		register: function(/* Object*/scope){
+		register: function(/* CustomEventMethod*/scope){
 			// summary:
 			//		All objects (Stencils) should register here if they
 			//		use mouse events. When registering, the object will
 			//		be called if it has that method.
-			//	argument:
+			//		See: CustomEventMethod and EventObject
+			// scope:
 			//		The object to be called
-			//	Returns: handle
+			// returns: handle
 			//		Keep the handle to be used for disconnection.
-			// See: CustomEventMethod and EventObject
-			//
+
 			var handle = scope.id || "reg_"+(this.__reg++);
 			if(!this.registered[handle]){ this.registered[handle] = scope; }
 			return handle; // String
 		},
 		unregister: function(handle){
 			// summary:
-			// 		Disconnects object. Mouse events are no longer
+			//		Disconnects object. Mouse events are no longer
 			//		called for it.
 			if(!this.registered[handle]){ return; }
 			delete this.registered[handle];
@@ -203,7 +204,7 @@ EventObject: function(){
 		_broadcastEvent:function(strEvt, obj){
 			// summary:
 			//		Fire events to all registered objects.
-			//
+
 			//console.log("mouse.broadcast:", strEvt, obj)
 			for(var nm in this.registered){
 				if(this.registered[nm][strEvt]) this.registered[nm][strEvt](obj);
@@ -212,17 +213,18 @@ EventObject: function(){
 		
 		onDown: function(obj){
 			// summary:
-			// 		Create on[xx]Down event and send to broadcaster.
+			//		Create on[xx]Down event and send to broadcaster.
 			//		Could be connected to.
+			
 			//console.info("onDown:", this.eventName("down"))
 			this._broadcastEvent(this.eventName("down"), obj);
 		},
 		
 		onDrag: function(obj){
 			// summary:
-			// 		Create on[xx]Drag event and send to broadcaster.
+			//		Create on[xx]Drag event and send to broadcaster.
 			//		Could be connected to.
-			//
+
 			var nm = this.eventName("drag");
 			if(this._selected && nm == "onDrag"){
 				nm = "onStencilDrag"
@@ -232,18 +234,18 @@ EventObject: function(){
 		
 		onMove: function(obj){
 			// summary:
-			// 		Create onMove event and send to broadcaster.
+			//		Create onMove event and send to broadcaster.
 			//		Could be connected to.
 			//		Note: onMove never uses a custom event
 			//		Note: onMove is currently not enabled in the app.
-			//
+
 			this._broadcastEvent("onMove", obj);
 		},
 		
 		overName: function(obj,evt){
 			var nm = obj.id.split(".");
 			evt = evt.charAt(0).toUpperCase() + evt.substring(1);
-			if(nm[0] == "dojox" && (dojox.drawing.defaults.clickable || !dojox.drawing.defaults.clickMode)){
+			if(nm[0] == "dojox" && (defaults.clickable || !defaults.clickMode)){
 				return "onStencil"+evt;
 			}else{
 				return "on"+evt;
@@ -252,22 +254,18 @@ EventObject: function(){
 		},
 		
 		onOver: function(obj){
-			// summary:
-			//
 			this._broadcastEvent(this.overName(obj,"over"), obj);
 		},
 		
 		onOut: function(obj){
-			// summary:
-			//
 			this._broadcastEvent(this.overName(obj,"out"), obj);
 		},
 		
 		onUp: function(obj){
 			// summary:
-			// 		Create on[xx]Up event and send to broadcaster.
+			//		Create on[xx]Up event and send to broadcaster.
 			//		Could be connected to.
-			//
+			
 			// 	blocking first click-off (deselect), largely for TextBlock
 			// 	TODO: should have param to make this optional?
 			var nm = this.eventName("up");
@@ -305,7 +303,7 @@ EventObject: function(){
 		zoom: 1,
 		setZoom: function(zoom){
 			// summary:
-			// 		Internal. Sets the mouse zoom percentage to
+			//		Internal. Sets the mouse zoom percentage to
 			//		that of the canvas
 			this.zoom = 1/zoom;
 		},
@@ -314,17 +312,17 @@ EventObject: function(){
 			// summary:
 			//		Sets the mouse mode s that custom events can be called.
 			//		Also can 'disable' events by using a bogus mode:
-			// 		|	mouse.setEventMode("DISABLED")
+			// |	mouse.setEventMode("DISABLED")
 			//		(unless any object subscribes to this event,
 			//		it is effectively disabled)
-			//
+
 			this.mode = mode ? "on" + mode.charAt(0).toUpperCase() + mode.substring(1) :  "";
 		},
 		
 		eventName: function(name){
 			// summary:
 			//		Internal. Determine the event name
-			//
+
 			name = name.charAt(0).toUpperCase() + name.substring(1);
 			if(this.mode){
 				if(this.mode == "onPathEdit"){
@@ -336,7 +334,7 @@ EventObject: function(){
 				return this.mode + name;
 			}else{
 				//Allow a mode where stencils aren't clickable
-				if(!dojox.drawing.defaults.clickable && dojox.drawing.defaults.clickMode){return "on"+name;}
+				if(!defaults.clickable && defaults.clickMode){return "on"+name;}
 				var dt = !this.drawingType || this.drawingType=="surface" || this.drawingType=="canvas" ? "" : this.drawingType;
 				var t = !dt ? "" : dt.charAt(0).toUpperCase() + dt.substring(1);
 				return "on"+t+name;
@@ -346,14 +344,14 @@ EventObject: function(){
 		up: function(evt){
 			// summary:
 			//		Internal. Create onUp event
-			//
+
 			this.onUp(this.create(evt));
 		},
 		
 		down: function(evt){
 			// summary:
 			//		Internal. Create onDown event
-			//
+
 			this._downOnCanvas = true;
 			var sc = this.scrollOffset();
 			var dim = this._getXY(evt);
@@ -397,19 +395,19 @@ EventObject: function(){
 		over: function(obj){
 			// summary:
 			//		Internal.
-			//
+
 			this.onOver(obj);
 		},
 		out: function(obj){
 			// summary:
 			//		Internal.
-			//
+
 			this.onOut(obj);
 		},
 		move: function(evt){
 			// summary:
 			//		Internal.
-			//
+
 			var obj = this.create(evt);
 			if(this.id=="MUI"){
 				//console.log("obj.id:", obj.id, "was:", this.currentNodeId)
@@ -436,7 +434,7 @@ EventObject: function(){
 		create: function(evt, squelchErrors){
 			// summary:
 			//		Internal. Create EventObject
-			//
+
 			var sc = this.scrollOffset();
 			var dim = this._getXY(evt);
 			
@@ -512,3 +510,4 @@ EventObject: function(){
 		}
 	}
 );
+});
diff --git a/dojox/drawing/manager/Stencil.js b/dojox/drawing/manager/Stencil.js
index f8a59c3..dfbe11d 100755
--- a/dojox/drawing/manager/Stencil.js
+++ b/dojox/drawing/manager/Stencil.js
@@ -1,24 +1,17 @@
-dojo.provide("dojox.drawing.manager.Stencil");
+define(["dojo", "../util/oo", "../defaults"], 
+function(dojo, oo, defaults){
 
-(function(){
 	var surface, surfaceNode;
-	dojox.drawing.manager.Stencil = dojox.drawing.util.oo.declare(
-		// summary:
-		//		The main class for tracking Stencils that are cretaed, added,
-		//		selected, or deleted. Also handles selections, multiple
-		//		selections, adding and removing from selections, and dragging
-		//		selections. It's this class that triggers the anchors to
-		//		appear on a Stencil and whther there are anchor on a multiple
-		//		select or not (currently not)
-		//
+	//dojox.drawing.manager.Stencil = 
+	return oo.declare(
 		function(options){
-			//
+
 			// TODO: mixin props
-			//
+
 			surface = options.surface;
 			this.canvas = options.canvas;
 			
-			this.defaults = dojox.drawing.defaults.copy();
+			//this.defaults = defaults.copy();
 			this.undo = options.undo;
 			this.mouse = options.mouse;
 			this.keys = options.keys;
@@ -33,6 +26,14 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			
 		},
 		{
+			// summary:
+			//		The main class for tracking Stencils that are cretaed, added,
+			//		selected, or deleted. Also handles selections, multiple
+			//		selections, adding and removing from selections, and dragging
+			//		selections. It's this class that triggers the anchors to
+			//		appear on a Stencil and whther there are anchor on a multiple
+			//		select or not (currently not)
+
 			_dragBegun: false,
 			_wasDragged:false,
 			_secondClick:false,
@@ -58,7 +59,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				//		can be added to the canvas without adding
 				//		them to this, but they won't have selection
 				//		or drag ability.
-				//
+
 				console.log("Selection.register ::::::", stencil.id);
 				if(stencil.isText && !stencil.editMode && stencil.deleteEmptyCreate && !stencil.getText()){
 					// created empty text field
@@ -108,8 +109,8 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				// summary:
 				//		Method for removing Stencils from the manager.
 				//		This doesn't delete them, only removes them from
-				// 		the list.
-				//
+				//		the list.
+
 				console.log("Selection.unregister ::::::", stencil.id, "sel:", stencil.selected);
 				if(stencil){
 					stencil.selected && this.onDeselect(stencil);
@@ -119,8 +120,8 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			
 			onArrow: function(/*Key Event*/evt){
 				// summary:
-				// 		Moves selection based on keyboard arrow keys
-				//
+				//		Moves selection based on keyboard arrow keys
+
 				// FIXME: Check constraints
 				if(this.hasSelected()){
 					this.saveThrottledState();
@@ -136,8 +137,8 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			saveMoveState: function(){
 				// summary:
 				//		Internal. Used for the prototype undo stack.
-				// 		Saves selection position.
-				//
+				//		Saves selection position.
+
 				var mx = this.group.getTransform();
 				if(mx.dx == this._lastmxx && mx.dy == this._lastmxy){ return; }
 				this._lastmxx = mx.dx;
@@ -153,7 +154,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				//		Internal. Used for the prototype undo stack.
 				//		Prevents an undo point on every mouse move.
 				//		Only does a point when the mouse hesitates.
-				//
+
 				clearTimeout(this._throttleVrl);
 				clearInterval(this._throttleVrl);
 				this._throttleVrl = setTimeout(dojo.hitch(this, function(){
@@ -169,7 +170,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			unDelete: function(/*Array*/stencils){
 				// summary:
 				//		Undeletes a stencil. Used in undo stack.
-				//
+
 				console.log("unDelete:", stencils);
 				for(var s in stencils){
 					stencils[s].render();
@@ -179,7 +180,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			onDelete: function(/*Boolean*/noundo){
 				// summary:
 				//		Event fired on deletion of a stencil
-				//
+
 				console.log("Stencil onDelete", noundo);
 				if(noundo!==true){
 					this.undo.add({
@@ -201,7 +202,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				// summary:
 				//		Deletes a stencil.
 				//		NOTE: supports limited undo.
-				//
+
 				// manipulating the selection to fire onDelete properly
 				if(this.hasSelected()){
 					// there is a selection
@@ -247,7 +248,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				// summary:
 				//		Internal. Creates a new selection group
 				//		used to hold selected stencils.
-				//
+
 				this.withSelected(function(m){
 					this.onDeselect(m, true);
 				});
@@ -270,7 +271,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				//		Internal. Gets all selected stencils' coordinates
 				//		and determines how far left and up the selection
 				//		can go without going below zero
-				//
+
 				var t = Infinity, l = Infinity;
 				this.withSelected(function(m){
 					var o = m.getBounds();
@@ -285,7 +286,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			onDeselect: function(stencil, keepObject){
 				// summary:
 				//		Event fired on deselection of a stencil
-				//
+
 				if(!keepObject){
 					delete this.selectedStencils[stencil.id];
 				}
@@ -301,7 +302,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			deselectItem: function(/*Object*/stencil){
 				// summary:
 				//		Deselect passed stencil
-				//
+
 				// note: just keeping with standardized methods
 				this.onDeselect(stencil);
 			},
@@ -309,7 +310,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			deselect: function(){ // all stencils
 				// summary:
 				//		Deselect all stencils
-				//
+
 				this.withSelected(function(m){
 					this.onDeselect(m);
 				});
@@ -320,7 +321,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			onSelect: function(/*Object*/stencil){
 				// summary:
 				//		Event fired on selection of a stencil
-				//
+
 				//console.log("stencil.onSelect", stencil);
 				if(!stencil){
 					console.error("null stencil is not selected:", this.stencils)
@@ -349,7 +350,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			selectItem: function(/*String|Object*/ idOrItem){
 				// summary:
 				//		Method used to select a stencil.
-				//
+
 				var id = typeof(idOrItem)=="string" ? idOrItem : idOrItem.id;
 				var stencil = this.stencils[id];
 				this.setSelectionGroup();
@@ -371,7 +372,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			onStencilDoubleClick: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired on the double-click of a stencil
-				//
+
 				console.info("mgr.onStencilDoubleClick:", obj);
 				if(this.selectedStencils[obj.id]){
 					if(this.selectedStencils[obj.id].edit){
@@ -396,7 +397,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			onStencilDown: function(/*EventObject*/obj, evt){
 				// summary:
 				//		Event fired on mousedown on a stencil
-				//
+
 				console.info(" >>> onStencilDown:", obj.id, this.keys.meta);
 				if(!this.stencils[obj.id]){ return; }
 				this.setRecentStencil(this.stencils[obj.id]);
@@ -451,7 +452,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				this._isBusy = false;
 				
 				// TODO:
-				//  dojo.style(surfaceNode, "cursor", "pointer");
+				//	dojo.style(surfaceNode, "cursor", "pointer");
 				
 				// TODO:
 				this.undo.add({
@@ -469,6 +470,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				//		Event fired on mousedown of a stencil's label
 				//		Because it's an annotation the id will be the
 				//		master stencil.
+				
 				//console.info("===============>>>Label click: ",obj, " evt: ",evt);
 				this.onStencilDown(obj,evt);
 			},
@@ -476,7 +478,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			onStencilUp: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired on mouseup off of a stencil
-				//
+
 			},
 			
 			onLabelUp: function(/*EventObject*/obj){
@@ -486,7 +488,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			onStencilDrag: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired on every mousemove of a stencil drag
-				//
+
 				if(!this._dragBegun){
 					// bug, in FF anyway - first mouse move shows x=0
 					// the 'else' fixes it
@@ -498,7 +500,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 					var x = obj.x - obj.last.x,
 						y = obj.y - obj.last.y,
 						c = this.constrain,
-						mz = this.defaults.anchors.marginZero;
+						mz = defaults.anchors.marginZero;
 					
 					
 					x = obj.x - this._offx;
@@ -527,20 +529,20 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			onDragEnd: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired at the end of a stencil drag
-				//
+
 				this._dragBegun = false;
 			},
 			onBeginDrag: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired at the beginning of a stencil drag
-				//
+
 				this._wasDragged = true;
 			},
 			
 			onDown: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired on mousedown on the canvas
-				//
+
 				this.deselect();
 			},
 						
@@ -549,6 +551,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				// summary:
 				//		This changes the cursor when hovering over
 				//		a selectable stencil.
+				
 				//console.log("OVER")
 				dojo.style(obj.id, "cursor", "move");
 			},
@@ -556,6 +559,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			onStencilOut: function(obj){
 				// summary:
 				//		This restores the cursor.
+				
 				//console.log("OUT")
 				dojo.style(obj.id, "cursor", "crosshair");
 			},
@@ -618,9 +622,9 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			
 			hasSelected: function(){
 				// summary:
-				// 		Returns number of selected (generally used
+				//		Returns number of selected (generally used
 				//		as truthy or falsey)
-				//
+
 				// FIXME: should be areSelected?
 				var ln = 0;
 				for(var m in this.selectedStencils){ ln++; }
@@ -637,4 +641,4 @@ dojo.provide("dojox.drawing.manager.Stencil");
 		}
 		
 	);
-})();
+});
diff --git a/dojox/drawing/manager/StencilUI.js b/dojox/drawing/manager/StencilUI.js
index 70e6932..b5feb9b 100644
--- a/dojox/drawing/manager/StencilUI.js
+++ b/dojox/drawing/manager/StencilUI.js
@@ -1,29 +1,29 @@
-dojo.provide("dojox.drawing.manager.StencilUI");
-
-(function(){
+define(["dojo", "../util/oo"],//, "../defaults"], 
+function(dojo, oo){
 	var surface, surfaceNode;
-	dojox.drawing.manager.StencilUI = dojox.drawing.util.oo.declare(
-		// summary:
-		//		Used for handling Stencils as UI components.
-		// description:
-		//		Replaces manager.Stencil. Handles basic UI mouse
-		//		events like onmouseover. Does not handle selections
-		//		or support delete, etc.
-		//
+	//dojox.drawing.manager.StencilUI = 
+	return oo.declare(
 		function(options){
-			//
+
 			// TODO: mixin props
-			//
+
 			surface = options.surface;
 			this.canvas = options.canvas;
 			
-			this.defaults = dojox.drawing.defaults.copy();
+			//this.defaults = defaults.copy();
 			this.mouse = options.mouse;
 			this.keys = options.keys;
 			this._mouseHandle = this.mouse.register(this);
 			this.stencils = {};
 		},
 		{
+			// summary:
+			//		Used for handling Stencils as UI components.
+			// description:
+			//		Replaces manager.Stencil. Handles basic UI mouse
+			//		events like onmouseover. Does not handle selections
+			//		or support delete, etc.
+
 			register: function(/*Object*/stencil){
 				this.stencils[stencil.id] = stencil;
 				return stencil;
@@ -31,28 +31,28 @@ dojo.provide("dojox.drawing.manager.StencilUI");
 			onUiDown: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired on mousedown on a stencil
-				//
+
 				if(!this._isStencil(obj)){ return; }
 				this.stencils[obj.id].onDown(obj);
 			},
 			onUiUp: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired on mousedown on a stencil
-				//
+
 				if(!this._isStencil(obj)){ return; }
 				this.stencils[obj.id].onUp(obj);
 			},
 			onOver: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired on mousedown on a stencil
-				//
+
 				if(!this._isStencil(obj)){ return; }
 				this.stencils[obj.id].onOver(obj);
 			},
 			onOut: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired on mousedown on a stencil
-				//
+
 				if(!this._isStencil(obj)){ return; }
 				this.stencils[obj.id].onOut(obj);
 			},
@@ -62,4 +62,4 @@ dojo.provide("dojox.drawing.manager.StencilUI");
 		}
 	);
 	
-})();
\ No newline at end of file
+});
diff --git a/dojox/drawing/manager/Undo.js b/dojox/drawing/manager/Undo.js
index 917381a..824869a 100755
--- a/dojox/drawing/manager/Undo.js
+++ b/dojox/drawing/manager/Undo.js
@@ -1,11 +1,8 @@
-dojo.provide("dojox.drawing.manager.Undo");
+define(["dojo", "../util/oo"],//, "../defaults"], 
+function(dojo, oo){
 
-dojox.drawing.manager.Undo = dojox.drawing.util.oo.declare(
-	// summary
-	//	Handles the Undo in drawing.
-	//	NOTE: Only partially implemented!!! There is very
-	//		little actual undo functionality!
-	//
+//dojox.drawing.manager.Undo = 
+return oo.declare(
 	function(options){
 		this.keys = options.keys;
 		this.undostack = [];
@@ -13,8 +10,13 @@ dojox.drawing.manager.Undo = dojox.drawing.util.oo.declare(
 		dojo.connect(this.keys, "onKeyDown", this, "onKeyDown");
 	},
 	{
+		// summary:
+		//		Handles the Undo in drawing.
+		//		NOTE: Only partially implemented!!! There is very
+		//		little actual undo functionality!
+
 		onKeyDown: function(evt){
-			if(!evt.cmmd){ return; }
+			if(!evt.cmmd && !evt.ctrl){ return; }
 			
 			if(evt.keyCode==90 && !evt.shift){
 				this.undo();
@@ -54,4 +56,5 @@ dojox.drawing.manager.Undo = dojox.drawing.util.oo.declare(
 			this.undostack.push(o);
 		}
 	}
-);
\ No newline at end of file
+);
+});
diff --git a/dojox/drawing/manager/_registry.js b/dojox/drawing/manager/_registry.js
index 29fad89..f10e73f 100644
--- a/dojox/drawing/manager/_registry.js
+++ b/dojox/drawing/manager/_registry.js
@@ -1,7 +1,4 @@
-dojo.provide("dojox.drawing.manager._registry");
-
-(function(){
-	
+define([], function(){
 	var _registered = {
 		tool:{},
 		stencil:{},
@@ -10,22 +7,23 @@ dojo.provide("dojox.drawing.manager._registry");
 		button:{}
 	};
 	
-	dojox.drawing.register = function(item, type){
-		if(type=="drawing"){
-			_registered.drawing[item.id] = item;
-		}else if(type=="tool"){
-			_registered.tool[item.name] = item;
-		}else if(type=="stencil"){
-			_registered.stencil[item.name] = item;
-		}else if(type=="plugin"){
-			_registered.plugin[item.name] = item;
-		}else if(type=="button"){
-			_registered.button[item.toolType] = item;
+	return {
+		register: function(item, type){
+			if(type=="drawing"){
+				_registered.drawing[item.id] = item;
+			}else if(type=="tool"){
+				_registered.tool[item.name] = item;
+			}else if(type=="stencil"){
+				_registered.stencil[item.name] = item;
+			}else if(type=="plugin"){
+				_registered.plugin[item.name] = item;
+			}else if(type=="button"){
+				_registered.button[item.toolType] = item;
+			}
+		},
+		
+		getRegistered: function(type, id){
+			return id ? _registered[type][id] : _registered[type];
 		}
 	};
-	
-	dojox.drawing.getRegistered = function(type, id){
-		return id ? _registered[type][id] : _registered[type];
-	}
-	
-})();
\ No newline at end of file
+});
diff --git a/dojox/drawing/manager/keys.js b/dojox/drawing/manager/keys.js
index 6fb5837..32dd6db 100755
--- a/dojox/drawing/manager/keys.js
+++ b/dojox/drawing/manager/keys.js
@@ -1,6 +1,5 @@
-dojo.provide("dojox.drawing.manager.keys");
-
-(function(){
+define(["dojo", "../util/common"], 
+function(dojo, utilCommon){
 	
 	// Ref: isEdit allows events to happen in Drawing, like TextBlocks
 	var isEdit = false;
@@ -10,42 +9,43 @@ dojo.provide("dojox.drawing.manager.keys");
 	
 	var alphabet = "abcdefghijklmnopqrstuvwxyz";
 	
-	dojox.drawing.manager.keys = {
+	//dojox.drawing.manager.keys = 
+	var keys = {
 		// summary:
 		//		A singleton, master object that detects
 		//		keyboard keys and events
-		// 		Connect to it like:
-		//		dojo.connect(this.keys, "onEnter", ....);
-		//
-		// arrowIncrement:Number
+		//		Connect to it like:
+		//	|	dojo.connect(this.keys, "onEnter", ....);
+
+		// arrowIncrement: Number
 		//		The amount, in pixels, a selected Stencil will
 		//		move on an arrow key event
 		arrowIncrement:1,
-		//
-		//	arrowShiftIncrement: Number
+
+		// arrowShiftIncrement: Number
 		//		The amount, in pixels, a selected Stencil will
 		//		move on an arrow key + SHIFT event
 		arrowShiftIncrement:10,
-		//
+
 		// shift: [readonly] Boolean
 		//		Indicates whether the Shift key is currently pressed
 		shift:false,
-		//
+
 		// ctrl: [readonly] Boolean
 		//		Indicates whether the Control key is currently pressed
 		ctrl:false,
-		//
+
 		// alt: [readonly] Boolean
 		//		Indicates whether the Alt or Option key is currently pressed
 		alt:false,
-		//
+
 		// cmmd: [readonly] Boolean
 		//		Indicates whether the Apple Command key is currently pressed
 		cmmd:false, // apple key
-		//
+
 		// meta: [readonly] Boolean
 		//		Indicates whether any 'meta' key is currently pressed:
-		//			shift || ctrl || cmmd || alt
+		//		shift || ctrl || cmd || alt
 		meta:false, // any meta key
 		
 		onDelete: function(/* Event */evt){
@@ -82,8 +82,8 @@ dojo.provide("dojox.drawing.manager.keys");
 			//		of events.
 			//		NOTE: Not really used in code, but should work.
 			//		See manager.mouse for similar usage
-			//
-			var _handle = dojox.drawing.util.common.uid("listener");
+
+			var _handle = utilCommon.uid("listener");
 			this.listeners.push({
 				handle:_handle,
 				scope: options.scope || window,
@@ -106,6 +106,7 @@ dojo.provide("dojox.drawing.manager.keys");
 			evt.shift = this.shift;
 			evt.alt = this.alt;
 			evt.cmmd = this.cmmd;
+			evt.ctrl = this.ctrl;
 			evt.letter = this._getLetter(evt);
 			return evt;
 		},
@@ -113,7 +114,7 @@ dojo.provide("dojox.drawing.manager.keys");
 		editMode: function(_isedit){
 			// summary:
 			//		Relinquishes control of events to another portion
-			// 		of Drawing; namely the TextBlock.
+			//		of Drawing; namely the TextBlock.
 			isEdit = _isedit;
 		},
 		
@@ -133,7 +134,7 @@ dojo.provide("dojox.drawing.manager.keys");
 			//		Scans the document for inputs
 			//		and calls this automatically. However you may need
 			//		to call this if you create inputs after the fact.
-			//
+
 			if(this._fieldCons){
 				dojo.forEach(this._fieldCons, dojo.disconnect, dojo);
 			}
@@ -154,7 +155,7 @@ dojo.provide("dojox.drawing.manager.keys");
 		init: function(){
 			// summary:
 			//		Initialize the keys object
-			//
+
 			// a little extra time is needed in some browsers
 			setTimeout(dojo.hitch(this, "scanForFields"), 500);
 			
@@ -230,22 +231,23 @@ dojo.provide("dojox.drawing.manager.keys");
 			
 			dojo.connect(document, "keypress", this, function(evt){
 				if(!enabled){ return; }
-				var inc = this.shift ? this.arrowIncrement*this.arrowShiftIncrement : this.arrowIncrement;
+				var inc = this.shift ? this.arrowIncrement*this.arrowShiftIncrement : this.arrowIncrement,
+					altOrOption = evt.alt || this.cmmd;
 				
 				var x =0, y =0;
 				if(evt.keyCode==32 && !isEdit){ //space
 					dojo.stopEvent(evt);
 				}
-				if(evt.keyCode==37){ //left
+				if(evt.keyCode==37 && !altOrOption){ //left
 					x = -inc;
 				}
-				if(evt.keyCode==38){ //up
+				if(evt.keyCode==38 && !altOrOption){ //up
 					y = -inc;
 				}
-				if(evt.keyCode==39){ //right
+				if(evt.keyCode==39 && !altOrOption){ //right
 					x = inc;
 				}
-				if(evt.keyCode==40){ //down
+				if(evt.keyCode==40 && !altOrOption){ //down
 					y = inc;
 				}
 				if(x || y){
@@ -260,5 +262,6 @@ dojo.provide("dojox.drawing.manager.keys");
 			});
 		}
 	};
-	dojo.addOnLoad(dojox.drawing.manager.keys, "init");
-})();
+	dojo.addOnLoad(keys, "init");
+	return keys;
+});
diff --git a/dojox/drawing/plugins/_Plugin.js b/dojox/drawing/plugins/_Plugin.js
index 2fc6425..1dd9da7 100755
--- a/dojox/drawing/plugins/_Plugin.js
+++ b/dojox/drawing/plugins/_Plugin.js
@@ -1,11 +1,8 @@
-dojo.provide("dojox.drawing.plugins._Plugin");
+define(["dojo", "../util/oo"],
+function(dojo, oo){
 
-dojox.drawing.plugins._Plugin = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Base class for plugins.
-	// description:
-	//		When creating a plugin, use this class as the
-	//		base to ensure full functionality.
+//dojox.drawing.plugins._Plugin = 
+return oo.declare(
 	function(options){
 		this._cons = [];
 		dojo.mixin(this, options);
@@ -14,6 +11,12 @@ dojox.drawing.plugins._Plugin = dojox.drawing.util.oo.declare(
 		}
 	},
 	{
+		// summary:
+		//		Base class for plugins.
+		// description:
+		//		When creating a plugin, use this class as the
+		//		base to ensure full functionality.
+
 		util:null,
 		keys:null,
 		mouse:null,
@@ -27,7 +30,7 @@ dojox.drawing.plugins._Plugin = dojox.drawing.util.oo.declare(
 		connect: function(){
 			this._cons.push(dojo.connect.apply(dojo, arguments));
 		},
-		disconnect: function(/*handle | Array*/handles){
+		disconnect: function(/*Handle|Array*/ handles){
 			// summary:
 			//		Removes connections based on passed
 			//		handles arguments
@@ -36,4 +39,5 @@ dojox.drawing.plugins._Plugin = dojox.drawing.util.oo.declare(
 			dojo.forEach(handles, dojo.disconnect, dojo);
 		}
 	}
-);
\ No newline at end of file
+);
+});
diff --git a/dojox/drawing/plugins/drawing/GreekPalette.js b/dojox/drawing/plugins/drawing/GreekPalette.js
index 0e7ec95..b214807 100644
--- a/dojox/drawing/plugins/drawing/GreekPalette.js
+++ b/dojox/drawing/plugins/drawing/GreekPalette.js
@@ -1,16 +1,40 @@
-dojo.provide("dojox.drawing.plugins.drawing.GreekPalette");
+define(["dojo","dijit/popup","../../library/greek","dijit/focus","dijit/_Widget","dijit/_TemplatedMixin",
+"dijit/_PaletteMixin","dojo/i18n!dojox/editor/plugins/nls/latinEntities"],
+function(dojo, popup, greek, focus, Widget, TemplatedMixin, PaletteMixin, latinEntities){
 
-dojo.require("dojox.drawing.library.greek");
-dojo.require("dijit.focus");
-dojo.require("dijit._Widget");
-dojo.require("dijit._TemplatedMixin");
-dojo.require("dijit._PaletteMixin");
-dojo.require("dojo.i18n");
+//dojo.requireLocalization("dojox.editor.plugins", "latinEntities");
 
-dojo.requireLocalization("dojox.editor.plugins", "latinEntities");
+var Greeks = dojo.declare(null,
+{
+	// summary:
+	//		Represents a character.
+	//		Initialized using an alias for the character (like cent) rather
+	//		than with the character itself.
+
+	constructor: function(/*String*/ alias){
+		// summary:
+		//	 Construct JS object representing an entity (associated w/a cell
+		//		in the palette)
+		// value: String
+		//		alias name: 'cent', 'pound' ..
+		this._alias = alias;
+	},
 
-dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
-	[dijit._Widget, dijit._TemplatedMixin, dijit._PaletteMixin],
+	getValue: function(){
+		// summary:
+		//		Returns HTML representing the character, like &
+
+		return this._alias;
+	},
+
+	fillCell: function(/*DOMNode*/ cell){
+		// Deal with entities that have keys which are reserved words.
+		cell.innerHTML = "&"+this._alias+";";
+	}
+});
+
+return dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
+  [Widget, TemplatedMixin, PaletteMixin],
 	{
 	// summary:
 	//		This plugin uses the palette dijit in order to give tips for
@@ -31,14 +55,13 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 	//		so it calls show (all actual popup management happens here).
 	//		In order to activate the plugin require it and then include the
 	//		markup in the example:
-	//
 	// example:
 	// |	<!--Because this is a widget it is included in markup and NOT like the other plugins-->
 	// |	<div dojoType="dojox.drawing.plugins.drawing.GreekPalette" id="greekPalette"></div>
 	
 	postMixInProperties: function(){
 		// Convert hash of entities into two-dimensional rows/columns table (array of arrays)
-		var choices = dojox.drawing.library.greek;
+		var choices = greek;//dojox.drawing.library.greek;
 		var numChoices = 0;
 		var entityKey;
 		for(entityKey in choices){numChoices++;}
@@ -63,12 +86,12 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 	
 	show: function(obj){
 		dojo.mixin(obj, {popup: this});
-		dijit.popup.open(obj);
+		popup.open(obj);
 	},
 	
 	onChange: function(val){
 		var textBlock = this._textBlock;
-		dijit.popup.hide(this);
+		popup.hide(this);
 		textBlock.insertText(this._pushChangeTo,val);
 		textBlock._dropMode = false;
 	},
@@ -76,7 +99,7 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 	onCancel: function(/*Boolean*/ closeAll){
 		// summary:
 		//		attach point for notification about when the user cancels the current menu
-		dijit.popup.hide(this);
+		popup.hide(this);
 		this._textBlock._dropMode = false;
 	},
 
@@ -115,7 +138,7 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 	//	  Whether the preview pane will be displayed, to show details about the selected entity.
 	showPreview: true,
 
-	dyeClass: 'dojox.drawing.plugins.Greeks',
+	dyeClass: Greeks, //'dojox.drawing.plugins.Greeks',
 
 	// domNodeClass [protected] String
 	paletteClass: 'editorLatinEntityPalette',
@@ -125,7 +148,7 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 	buildRendering: function(){
 		this.inherited(arguments);
 
-		var i18n = dojo.i18n.getLocalization("dojox.editor.plugins", "latinEntities");
+		var i18n = latinEntities;//dojo.i18n.getLocalization("dojox.editor.plugins", "latinEntities");
 
 		this._preparePalette(
 			this._palette,
@@ -168,7 +191,7 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 		// Use setTimeout because IE doesn't like changing focus inside of an event handler.
 		this._setCurrent(target);
 		setTimeout(dojo.hitch(this, function(){
-			dijit.focus(target);
+			focus(target);
 			this._setValueAttr(value, true);
 		}));
 
@@ -185,7 +208,7 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 		if(!this.showPreview){
 			dojo.style(this.previewNode,"display","none");
 		}
-		dijit.popup.moveOffScreen(this);
+		popup.moveOffScreen(this);
 	},
 
 	_setCurrent: function(/*DOMNode*/ node){
@@ -194,7 +217,7 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 		// description:
    		//		At any point in time there's exactly one
 		//		cell with tabIndex != -1.   If focus is inside the palette then
-		// 		focus is on that cell.
+		//		focus is on that cell.
 		//
 		//		After calling this method, arrow key handlers and mouse click handlers
 		//		should focus the cell in a setTimeout().
@@ -244,7 +267,7 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 		this._cells = [];
 		var url = this._blankGif;
 		
-		var dyeClassObj = dojo.getObject(this.dyeClass);
+		var dyeClassObj = typeof this.dyeClass === 'string' ? dojo.getObject(this.dyeClass) : this.dyeClass;
 
 		for(var row=0; row < choices.length; row++){
 			var rowNode = dojo.create("tr", {tabIndex: "-1"}, this.gridNode);
@@ -267,7 +290,7 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 
 					dojo.place(cellNode, rowNode);
 
-					cellNode.index = this._cells.length;
+					cellNode.idx = this._cells.length;
 
 					// save cell info into _cells
 					this._cells.push({node:cellNode, dye:cellObject});
@@ -282,9 +305,9 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 	_navigateByArrow: function(evt){
 		// summary:
 		// 	  	This is a departure from the dijit, the textBlock needs
-		// 		navigation without losing focus, this allows that
+		//		navigation without losing focus, this allows that
 		// increment:
-		// 		How much the key is navigated.
+		//		How much the key is navigated.
 		// tags:
 		//		private
 		var keyIncrementMap = {
@@ -297,7 +320,7 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 		};
 		
 		var increment = keyIncrementMap[evt.keyCode];
-		var newFocusIndex = this._currentFocus.index + increment;
+		var newFocusIndex = this._currentFocus.idx + increment;
 		if(newFocusIndex < this._cells.length && newFocusIndex > -1){
 			var focusNode = this._cells[newFocusIndex].node;
 			this._setCurrent(focusNode);
@@ -305,32 +328,4 @@ dojo.declare("dojox.drawing.plugins.drawing.GreekPalette",
 	}
 });
 
-dojo.declare("dojox.drawing.plugins.Greeks",
-        null,
-{
-	// summary:
-	//		Represents a character.
-	//		Initialized using an alias for the character (like cent) rather
-	//		than with the character itself.
-
-	constructor: function(/*String*/ alias){
-		// summary:
-		//	 Construct JS object representing an entity (associated w/a cell
-		//		in the palette)
-		// value: String
-		//		alias name: 'cent', 'pound' ..
-		this._alias = alias;
-	},
-
-	getValue: function(){
-		// summary:
-		//   Returns HTML representing the character, like &
-		//
-		return this._alias;
-	},
-
-	fillCell: function(/*DOMNode*/ cell){
-		// Deal with entities that have keys which are reserved words.
-		cell.innerHTML = "&"+this._alias+";";
-	}
-});
\ No newline at end of file
+});
diff --git a/dojox/drawing/plugins/drawing/Grid.js b/dojox/drawing/plugins/drawing/Grid.js
index 24b730e..184cf1a 100755
--- a/dojox/drawing/plugins/drawing/Grid.js
+++ b/dojox/drawing/plugins/drawing/Grid.js
@@ -1,15 +1,8 @@
-dojo.provide("dojox.drawing.plugins.drawing.Grid");
-dojo.require("dojox.drawing.plugins._Plugin");
+define(["dojo", "../../util/oo", "../_Plugin"],
+function(dojo, oo, Plugin){
 
-dojox.drawing.plugins.drawing.Grid = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Plugin that displays a grid on the Drawing canvas.
-	// example:
-	//		|	<div dojoType="dojox.drawing.Drawing" id="drawingNode"
-	//		|		plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:50}}]">
-	//		|	</div>
-	//
-	dojox.drawing.plugins._Plugin,
+var Grid = oo.declare(
+	Plugin,
 	function(options){
 		if(options.gap){
 			this.major = options.gap;
@@ -21,22 +14,29 @@ dojox.drawing.plugins.drawing.Grid = dojox.drawing.util.oo.declare(
 		dojo.connect(this.canvas, "setZoom", this, "setZoom");
 	},
 	{
+		// summary:
+		//		Plugin that displays a grid on the Drawing canvas.
+		// example:
+		//		|	<div dojoType="dojox.drawing.Drawing" id="drawingNode"
+		//		|		plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:50}}]">
+		//		|	</div>
+
 		type:"dojox.drawing.plugins.drawing.Grid",
-		//
+
 		// gap: Number
 		//		How far apart to set the grid lines
 		gap:100,
 		major:100,
 		minor:0,
-		//
+
 		// majorColor: String
 		//		Major lines color
 		majorColor: "#00ffff",
-		//
+
 		// minorColor: String
 		//		Minor lines color
 		minorColor: "#d7ffff",
-		//
+
 		// zoom: [readonly] Number
 		//		The current zoom of the grid
 		zoom:1,
@@ -50,11 +50,11 @@ dojox.drawing.plugins.drawing.Grid = dojox.drawing.util.oo.declare(
 		setGrid: function(options){
 			// summary:
 			//		Renders grid
-			//
+
 			// TODO: major minor lines
-			//	minors dont show on zoom out
+			//	minors don't show on zoom out
 			//	draw minors first
-			//
+
 			var mjr = Math.floor(this.major * this.zoom);
 			var mnr = this.minor ? Math.floor(this.minor * this.zoom) : mjr;
 			
@@ -74,8 +74,8 @@ dojox.drawing.plugins.drawing.Grid = dojox.drawing.util.oo.declare(
 			
 			// horz
 			for(i=1,len = h/mnr; i<len; i++){
-				x1 = 0, x2 = w;
-				y1 = mnr*i, y2 = y1;
+				x1 = 0; x2 = w;
+				y1 = mnr*i; y2 = y1;
 				
 				
 				clr = y1%mjr ? mn : mj;
@@ -83,8 +83,8 @@ dojox.drawing.plugins.drawing.Grid = dojox.drawing.util.oo.declare(
 			}
 			// vert
 			for(i=1,len = w/mnr; i<len; i++){
-				y1 = 0, y2 = h;
-				x1 = mnr*i, x2 = x1;
+				y1 = 0; y2 = h;
+				x1 = mnr*i; x2 = x1;
 				clr = x1%mjr ? mn : mj;
 				createGridLine(x1,y1,x2,y2, clr);
 			}
@@ -95,4 +95,8 @@ dojox.drawing.plugins.drawing.Grid = dojox.drawing.util.oo.declare(
 			return s;
 		}
 	}
-);
\ No newline at end of file
+);
+
+dojo.setObject("dojox.drawing.plugins.drawing.Grid", Grid);
+return Grid;
+});
diff --git a/dojox/drawing/plugins/drawing/Silverlight.js b/dojox/drawing/plugins/drawing/Silverlight.js
index a6baf4d..6d9a54c 100755
--- a/dojox/drawing/plugins/drawing/Silverlight.js
+++ b/dojox/drawing/plugins/drawing/Silverlight.js
@@ -1,31 +1,25 @@
 dojo.provide("dojox.drawing.plugins.drawing.Silverlight");
 
 dojox.drawing.plugins.drawing.Silverlight = dojox.drawing.util.oo.declare(
-	// summary:
-	// 	"Plugin" to allow the Silverlight plugin to work
-	//	with DojoX Drawing.
-	//
 	//	WARNING: This is not completely implemented. For the most
 	//	part, DojoX Drawing does not support Silverlight. This class
 	//	was created in an attempt for support, but there were too many
 	//	obstacles and not enough time. The basic functionality is here
 	//	and there's a good head start if anyone elase wishes to pick up
 	//	where I left off.
-	//
+
 	function(options){
 		// summary:
-		//	The constructor is the only method in this class.
-		//	What is happening here is other methods in other
-		//	classes are being overridden to adapt to Silverlight.
-		//
- 		
+		//		The constructor is the only method in this class.
+		//		What is happening here is other methods in other
+		//		classes are being overridden to adapt to Silverlight.
+
 		if(dojox.gfx.renderer != "silverlight"){ return; }
 		this.mouse = options.mouse;
 		this.stencils = options.stencils;
 		this.anchors = options.anchors;
 		this.canvas = options.canvas;
 		this.util = options.util;
-	
 		
 		dojo.connect(this.stencils, "register", this, function(item){
 			var c1, c2, c3, c4, c5, self = this;
@@ -38,7 +32,7 @@ dojox.drawing.plugins.drawing.Silverlight = dojox.drawing.util.oo.declare(
 					evt.superTarget = item;
 					self.mouse.down(evt);
 				});
-			}
+			};
 			conMouse();
 			
 			c2 = dojo.connect(item, "setTransform", this, function(){
@@ -106,7 +100,7 @@ dojox.drawing.plugins.drawing.Silverlight = dojox.drawing.util.oo.declare(
 			
 			// throws errors in IE silverlight. Oddness.
 			//dojo.stopEvent(evt);
-		}
+		};
 		
 		this.mouse.down = function(evt){
 			clearTimeout(this.__downInv);
@@ -117,9 +111,7 @@ dojox.drawing.plugins.drawing.Silverlight = dojox.drawing.util.oo.declare(
 				return;
 			}
 			this._down(evt);
-			
-			
-		}
+		};
 		
 		this.mouse._getXY =  function(evt){
 			
@@ -140,11 +132,11 @@ dojox.drawing.plugins.drawing.Silverlight = dojox.drawing.util.oo.declare(
 			}else{
 				return {x:evt.pageX, y:evt.pageY};
 			}
-		}
+		};
 		
 		this.mouse._getId = function(evt){
 			return this.util.attr(evt, "id");
-		}
+		};
 		
 		this.util.attr = function(/* Object */ elem, /* property */ prop, /* ? value */ value, squelchErrors){
 			if(!elem){ return false; }
@@ -188,6 +180,8 @@ dojox.drawing.plugins.drawing.Silverlight = dojox.drawing.util.oo.declare(
 		}
 	},
 	{
-		
+		// summary:
+		//		"Plugin" to allow the Silverlight plugin to work
+		//		with DojoX Drawing.
 	}
 );
\ No newline at end of file
diff --git a/dojox/drawing/plugins/tools/Iconize.js b/dojox/drawing/plugins/tools/Iconize.js
index e0957e5..1666b4f 100644
--- a/dojox/drawing/plugins/tools/Iconize.js
+++ b/dojox/drawing/plugins/tools/Iconize.js
@@ -1,17 +1,18 @@
-dojo.provide("dojox.drawing.plugins.tools.Iconize");
-dojo.require("dojox.drawing.plugins._Plugin");
+define(["dojo", "../../util/oo", "../_Plugin", "../../manager/_registry"],
+function(dojo, oo, Plugin, registry){
 
-dojox.drawing.plugins.tools.Iconize = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Somewhat of internal use...
-	//		Outputs a path to be used as an icon. Will end up being a
-	//		sub-icon under Export options
-	
-	dojox.drawing.plugins._Plugin,
+//dojox.drawing.plugins.tools.Iconize = 
+var Iconize = oo.declare(
+	Plugin,
 	function(options){
 	
 	},
 	{
+		// summary:
+		//		Somewhat of internal use...
+		//		Outputs a path to be used as an icon. Will end up being a
+		//		sub-icon under Export options
+
 		onClick: function(){
 			var item;
 			for(var nm in this.stencils.stencils){
@@ -91,10 +92,13 @@ dojox.drawing.plugins.tools.Iconize = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.plugins.tools.Iconize.setup = {
+Iconize.setup = {
 	name:"dojox.drawing.plugins.tools.Iconize",
 	tooltip:"Iconize Tool",
 	iconClass:"iconPan"
 };
+dojo.setObject('dojox.drawing.plugins.tools.Iconize', Iconize);
+registry.register(Iconize.setup, "plugin");
 
-dojox.drawing.register(dojox.drawing.plugins.tools.Iconize.setup, "plugin");
\ No newline at end of file
+return Iconize;
+});
diff --git a/dojox/drawing/plugins/tools/Pan.js b/dojox/drawing/plugins/tools/Pan.js
index 5b9d78b..a268de3 100755
--- a/dojox/drawing/plugins/tools/Pan.js
+++ b/dojox/drawing/plugins/tools/Pan.js
@@ -1,20 +1,8 @@
-dojo.provide("dojox.drawing.plugins.tools.Pan");
-dojo.require("dojox.drawing.plugins._Plugin");
+define(["dojo/_base/lang", "../../util/oo", "../_Plugin", "../../manager/_registry"],
+function(lang, oo, Plugin, registry){
 
-dojox.drawing.plugins.tools.Pan = dojox.drawing.util.oo.declare(
-	// summary:
-	//		A plugin that allows for a scrolling canvas. An action
-	//		tool is added to the toolbar that allows for panning. Holding
-	//		the space bar is a shortcut to that action. The canvas will
-	//		only pan and scroll if there are objects out of the viewable
-	//		area.
-	// example:
-	//		|	<div dojoType="dojox.drawing.Toolbar" drawingId="drawingNode" class="drawingToolbar vertical">
-	//		|		<div tool="dojox.drawing.tools.Line" selected="true">Line</div>
-	//		|		<div plugin="dojox.drawing.plugins.tools.Pan" options="{}">Pan</div>
-	//		|	</div>
-	//
-	dojox.drawing.plugins._Plugin,
+var Pan = oo.declare(
+	Plugin,
 	function(options){
 		this.domNode = options.node;
 		var _scrollTimeout;
@@ -35,13 +23,25 @@ dojox.drawing.plugins.tools.Pan = dojox.drawing.util.oo.declare(
 				return;
 			}
 			_scrollTimeout && clearTimeout(_scrollTimeout);
-			_scrollTimeout = setTimeout(dojo.hitch(this, "checkBounds"), 200);
+			_scrollTimeout = setTimeout(lang.hitch(this, "checkBounds"), 200);
 		});
 		this._mouseHandle = this.mouse.register(this);
 		// This HAS to be called after setting initial objects or things get screwy.
 		//this.checkBounds();
 		
 	},{
+		// summary:
+		//		A plugin that allows for a scrolling canvas. An action
+		//		tool is added to the toolbar that allows for panning. Holding
+		//		the space bar is a shortcut to that action. The canvas will
+		//		only pan and scroll if there are objects out of the viewable
+		//		area.
+		// example:
+		//		|	<div dojoType="dojox.drawing.Toolbar" drawingId="drawingNode" class="drawingToolbar vertical">
+		//		|		<div tool="dojox.drawing.tools.Line" selected="true">Line</div>
+		//		|		<div plugin="dojox.drawing.plugins.tools.Pan" options="{}">Pan</div>
+		//		|	</div>
+
 		selected:false,
 		keyScroll:false,
 		type:"dojox.drawing.plugins.tools.Pan",
@@ -73,13 +73,13 @@ dojox.drawing.plugins.tools.Pan = dojox.drawing.util.oo.declare(
 		
 		onArrow: function(evt){
 			if(this._timer){ clearInterval(this._timer); }
-			this._timer = setInterval(dojo.hitch(this,function(evt){
+			this._timer = setInterval(lang.hitch(this,function(evt){
 				this.canvas.domNode.parentNode.scrollLeft += evt.x*10;
 				this.canvas.domNode.parentNode.scrollTop += evt.y*10;
 			},evt), this.interval);
 		},
 		
-		onSetPan: function(/*Boolean | Event*/ bool){
+		onSetPan: function(/*Boolean|Event*/ bool){
 			if(bool === true || bool === false){
 				this.selected = !bool;
 			}
@@ -128,10 +128,10 @@ dojox.drawing.plugins.tools.Pan = dojox.drawing.util.oo.declare(
 			
 			// summary:
 			//		Scans all items on the canvas and checks if they are out of
-			// 		bounds. If so, a scroll bar (in Canvas) is shown. If the position
-			// 		is left or top, the canvas is scrolled all items are relocated
-			// 		the distance of the scroll. Ideally, it should look as if the
-			// 		items do not move.
+			//		bounds. If so, a scroll bar (in Canvas) is shown. If the position
+			//		is left or top, the canvas is scrolled all items are relocated
+			//		the distance of the scroll. Ideally, it should look as if the
+			//		items do not move.
 			
 			// logging stuff here so it can be turned on and off. This method is
 			// very high maintenance.
@@ -232,11 +232,15 @@ dojox.drawing.plugins.tools.Pan = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.plugins.tools.Pan.setup = {
+Pan.setup = {
 	name:"dojox.drawing.plugins.tools.Pan",
 	tooltip:"Pan Tool",
 	iconClass:"iconPan",
 	button:false
 };
 
-dojox.drawing.register(dojox.drawing.plugins.tools.Pan.setup, "plugin");
\ No newline at end of file
+lang.setObject("dojox.drawing.plugins.tools.Pan", Pan);
+registry.register(Pan.setup, "plugin");
+return Pan;
+
+});
diff --git a/dojox/drawing/plugins/tools/Zoom.js b/dojox/drawing/plugins/tools/Zoom.js
index de85f9b..00d0fbf 100755
--- a/dojox/drawing/plugins/tools/Zoom.js
+++ b/dojox/drawing/plugins/tools/Zoom.js
@@ -1,43 +1,31 @@
-dojo.provide("dojox.drawing.plugins.tools.Zoom");
-dojo.require("dojox.drawing.plugins._Plugin");
+define(["dojo/_base/lang", "../../util/oo", "../_Plugin", "../../manager/_registry"],
+function(lang, oo, Plugin, registry){
 
-(function(){
-	//
-	// 	zoomInc: Float
+	// zoomInc: Float
 	//		The amount of zoom that will occur upon each click.
 	var zoomInc = Math.pow(2.0,0.25),
-	//
-	//	maxZoom: Number
+
+	// maxZoom: Number
 	//		The maximum the canvas can be zoomed in. 10 = 1000%
 	maxZoom = 10,
-	//
-	//	minZoom: Float
+
+	// minZoom: Float
 	//		The most the canvas can be zoomed out. .1 = 10%
 	minZoom = 0.1,
-	//
-	//	zoomFactor: [readonly] Float
+
+	// zoomFactor: [readonly] Float
 	//		The current zoom amount
-	zoomFactor = 1,
+	zoomFactor = 1, 
+	dt;
 	
+	if(!lang.getObject('dojox.drawing.plugins.tools')){
+		lang.setObject('dojox.drawing.plugins.tools', {});
+	}
 	dt = dojox.drawing.plugins.tools;
 	
-	dt.ZoomIn = dojox.drawing.util.oo.declare(
-		// summary:
-		//		A plugin that allows for zooming the canvas in and out. An
-		//		action-tool is added to the toolbar with plus, minus and 100%
-		//		buttons.
-		//
-		function(options){
-			// mix in private vars
-			
-		},
-		{}
-	);
-	
-	
-	dt.ZoomIn = dojox.drawing.util.oo.declare(
+	dt.ZoomIn = oo.declare(
 		// summary:
-		dojox.drawing.plugins._Plugin,
+		Plugin,
 		function(options){
 			
 		},
@@ -46,7 +34,7 @@ dojo.require("dojox.drawing.plugins._Plugin");
 			onZoomIn: function(){
 				// summary:
 				//		Handles zoom in.
-				//
+
 				zoomFactor *= zoomInc;
 				zoomFactor = Math.min(zoomFactor, maxZoom);
 				this.canvas.setZoom(zoomFactor);
@@ -58,9 +46,9 @@ dojo.require("dojox.drawing.plugins._Plugin");
 		}
 	);
 	
-	dt.Zoom100 = dojox.drawing.util.oo.declare(
+	dt.Zoom100 = oo.declare(
 		// summary:
-		dojox.drawing.plugins._Plugin,
+		Plugin,
 		function(options){
 			
 		},
@@ -69,7 +57,7 @@ dojo.require("dojox.drawing.plugins._Plugin");
 			onZoom100: function(){
 				// summary:
 				//		Zooms to 100%
-				//
+
 				zoomFactor = 1;
 				this.canvas.setZoom(zoomFactor);
 				this.mouse.setZoom(zoomFactor);
@@ -80,9 +68,9 @@ dojo.require("dojox.drawing.plugins._Plugin");
 		}
 	);
 	
-	dt.ZoomOut = dojox.drawing.util.oo.declare(
+	dt.ZoomOut = oo.declare(
 		// summary:
-		dojox.drawing.plugins._Plugin,
+		Plugin,
 		function(options){
 			
 		},
@@ -91,7 +79,7 @@ dojo.require("dojox.drawing.plugins._Plugin");
 			onZoomOut: function(){
 				// summary:
 				//		Handles zoom out.
-				//
+
 				zoomFactor /= zoomInc;
 				zoomFactor = Math.max(zoomFactor, minZoom);
 				this.canvas.setZoom(zoomFactor);
@@ -108,18 +96,20 @@ dojo.require("dojox.drawing.plugins._Plugin");
 		name:"dojox.drawing.plugins.tools.ZoomIn",
 		tooltip:"Zoom In"
 	};
-	dojox.drawing.register(dt.ZoomIn.setup, "plugin");
+	registry.register(dt.ZoomIn.setup, "plugin");
 	
 	dt.Zoom100.setup = {
 		name:"dojox.drawing.plugins.tools.Zoom100",
 		tooltip:"Zoom to 100%"
 	};
-	dojox.drawing.register(dt.Zoom100.setup, "plugin");
+	registry.register(dt.Zoom100.setup, "plugin");
 	
 	dt.ZoomOut.setup = {
 		name:"dojox.drawing.plugins.tools.ZoomOut",
 		tooltip:"Zoom In"
 	};
-	dojox.drawing.register(dt.ZoomOut.setup, "plugin");
+	registry.register(dt.ZoomOut.setup, "plugin");
+
+	return dt;
 
-})();
\ No newline at end of file
+});
diff --git a/dojox/drawing/stencil/Ellipse.js b/dojox/drawing/stencil/Ellipse.js
index f831b24..71889fb 100755
--- a/dojox/drawing/stencil/Ellipse.js
+++ b/dojox/drawing/stencil/Ellipse.js
@@ -1,42 +1,36 @@
-dojo.provide("dojox.drawing.stencil.Ellipse");
+define(["dojo/_base/lang", "../util/oo", "./_Base", "../manager/_registry"], 
+function(lang, oo, Base, registry){
 
 /*=====
-__StencilData = {
+var __StencilData = {
 	// summary:
 	//		the data used to create the dojox.gfx Shape
-	//
-
-	// 	cx: Number
+	// cx: Number
 	//		Center point x
-	cx:0,
-	// 	cy: Number
+	// cy: Number
 	//		Center point y
-	cy:0,
-	// 	rx: Number
+	// rx: Number
 	//		Horizontal radius
-	rx:0,
-	// 	ry: Number
+	// ry: Number
 	//		Vertical radius
-	ry:0
-}
+};
 =====*/
 
-dojox.drawing.stencil.Ellipse = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Creates a dojox.gfx Ellipse based on data or points provided.
-	//
-	dojox.drawing.stencil._Base,
+var Ellipse = oo.declare(
+	Base,
 	function(options){
 		// summary:
 		//		constructor
 	},
 	{
-		
+		// summary:
+		//		Creates a dojox.gfx Ellipse based on data or points provided.
+
 		type:"dojox.drawing.stencil.Ellipse",
 		anchorType: "group",
 		baseRender:true,
 		dataToPoints: function(/*Object*/o){
-			//summary:
+			// summary:
 			//		Converts data to points.
 			o = o || this.data;
 			var x = o.cx - o.rx,
@@ -73,7 +67,7 @@ dojox.drawing.stencil.Ellipse = dojox.drawing.util.oo.declare(
 			//		Creates a dojox.gfx.shape based on passed arguments.
 			//		Can be called many times by implementation to create
 			//		multiple shapes in one stencil.
-			//
+
 			this.remove(this[shp]);
 			this[shp] = this.container.createEllipse(d)
 				.setStroke(sty)
@@ -86,7 +80,7 @@ dojox.drawing.stencil.Ellipse = dojox.drawing.util.oo.declare(
 			//		Renders the 'hit' object (the shape used for an expanded
 			//		hit area and for highlighting) and the'shape' (the actual
 			//		display object).
-			//
+
 			this.onBeforeRender(this);
 			this.renderHit && this._create("hit", this.data, this.style.currentHit);
 			this._create("shape", this.data, this.style.current);
@@ -95,6 +89,10 @@ dojox.drawing.stencil.Ellipse = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.register({
+lang.setObject("dojox.drawing.stencil.Ellipse", Ellipse);
+registry.register({
 	name:"dojox.drawing.stencil.Ellipse"
-}, "stencil");
\ No newline at end of file
+}, "stencil");
+
+return Ellipse;
+});
diff --git a/dojox/drawing/stencil/Image.js b/dojox/drawing/stencil/Image.js
index fdc13d2..b9ce4f8 100755
--- a/dojox/drawing/stencil/Image.js
+++ b/dojox/drawing/stencil/Image.js
@@ -1,53 +1,46 @@
-dojo.provide("dojox.drawing.stencil.Image");
+define(["dojo", "../util/oo", "./_Base", "../manager/_registry"], 
+function(dojo, oo, Base, registry){
 
-
-dojox.drawing.stencil.Image = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Creates an dojox.gfx Image based on the data
-	//		provided.
-	//
-	dojox.drawing.stencil._Base,
+var Image = oo.declare(
+	Base,
 	function(options){
 		// summary:
 		//		constructor
 	},
 	{
+		// summary:
+		//		Creates an dojox.gfx Image based on the data
+		//		provided.
+
 		type:"dojox.drawing.stencil.Image",
 		anchorType: "group",
 		baseRender:true,
 		
-/*=====
-StencilData: {
-	// summary:
-	//		The data used to create the dojox.gfx Shape
-	// 	x: Number
-	//		Left point x
-	// 	y: Number
-	//		Top point y
-	// 	width: ? Number
-	//		Optional width of Image. If not provided, it is obtained
-	// 	height: ? Number
-	//		Optional height of Image. If not provided, it is obtained
-	// 	src: String
-	//		The location of the source image
-},
+		/*=====
+		StencilData: {
+			// summary:
+			//		The data used to create the dojox.gfx Shape
+			// x: Number
+			//		Left point x
+			// y: Number
+			//		Top point y
+			// width: Number?
+			//		Optional width of Image. If not provided, it is obtained
+			// height: Number?
+			//		Optional height of Image. If not provided, it is obtained
+			// src: String
+			//		The location of the source image
+		},
 
-StencilPoints: [
-	// summary:
-	//		An Array of dojox.__StencilPoint objects that describe the Stencil
-	// 	0: Object
-	//		Top left point
-	// 	1: Object
-	//		Top right point
-	// 	2: Object
-	//		Bottom right point
-	// 	3: Object
-	//		Bottom left point
-],
-=====*/
+		StencilPoints: [
+			// summary:
+			//		An Array of dojox.__StencilPoint objects that describe the Stencil
+			//		[Top left point, Top right point, Bottom right point, Bottom left point]
+		],
+		=====*/
 		
 		dataToPoints: function(/*Object*/o){
-			//summary:
+			// summary:
 			//		Converts data to points.
 			o = o || this.data;
 			this.points = [
@@ -91,7 +84,7 @@ StencilPoints: [
 			//		Creates a dojox.gfx.shape based on passed arguments.
 			//		Can be called many times by implementation to create
 			//		multiple shapes in one stencil.
-			//
+
 			this.remove(this[shp]);
 			var s = this.container.getParent();
 			this[shp] = s.createImage(d)
@@ -106,7 +99,7 @@ StencilPoints: [
 			//		display object). Image is slightly different than other
 			//		implementations. Instead of calling render twice, it calls
 			//		_createHilite for the 'hit'
-			//
+
 			if(this.data.width == "auto" || isNaN(this.data.width)){
 				this.getImageSize(true);
 				console.warn("Image size not provided. Acquiring...")
@@ -121,7 +114,7 @@ StencilPoints: [
 			//		Internal. If no image size is passed in with the data
 			//		create a dom node, insert and image, gets its dimensions
 			//		record them - then destroy everything.
-			//
+
 			if(this._gettingSize){ return; } // IE gets it twice (will need to mod if src changes)
 			this._gettingSize = true;
 			var img = dojo.create("img", {src:this.data.src}, dojo.body());
@@ -149,7 +142,10 @@ StencilPoints: [
 	}
 );
 
-
-dojox.drawing.register({
+dojo.setObject("dojox.drawing.stencil.Image", Image);
+registry.register({
 	name:"dojox.drawing.stencil.Image"
-}, "stencil");
\ No newline at end of file
+}, "stencil");
+
+return Image;
+});
diff --git a/dojox/drawing/stencil/Line.js b/dojox/drawing/stencil/Line.js
index 32e5d1d..94380da 100755
--- a/dojox/drawing/stencil/Line.js
+++ b/dojox/drawing/stencil/Line.js
@@ -1,15 +1,15 @@
-dojo.provide("dojox.drawing.stencil.Line");
-
-dojox.drawing.stencil.Line = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Creates a dojox.gfx Line based on data or points provided.
-	//
-	dojox.drawing.stencil._Base,
+define(["dojo/_base/lang", "../util/oo", "./_Base", "../manager/_registry"], 
+function(lang, oo, Base, registry){
+var Line = oo.declare(
+	Base,
 	function(options){
 		// summary:
 		//		constructor
 	},
 	{
+		// summary:
+		//		Creates a dojox.gfx Line based on data or points provided.
+
 		type:"dojox.drawing.stencil.Line",
 		anchorType: "single",
 		baseRender:true,
@@ -17,40 +17,39 @@ dojox.drawing.stencil.Line = dojox.drawing.util.oo.declare(
 /*=====
 StencilData: {
 	// summary:
-	//		The data used to create the dojox.gfx Shape
-	// 	x1: Number
+	//		The data used to create the dojox.gfx Shape, specify
+	//		x1,y1,x2,y2, or x,y,angle,radius
+
+	// x1: Number
 	//		First point x
-	// 	y1: Number
+	// y1: Number
 	//		First point y
-	// 	x2: Number
+	// x2: Number
 	//		Second point x
-	// 	y2: Number
+	// y2: Number
 	//		Second point y
 	
 	// ALTERNATIVE:
 	
-	// 	x: Number
+	// x: Number
 	//		First point x
-	// 	y: Number
+	// y: Number
 	//		First point y
-	// 	angle: Number
+	// angle: Number
 	//		angle of line
-	// 	radius: Number
+	// radius: Number
 	//		length of line
 },
 
 StencilPoints: [
 	// summary:
 	//		An Array of dojox.__StencilPoint objects that describe the Stencil
-	// 	0: Object
-	//		First point
-	// 	1: Object
-	//		Second point
+	//		[First point, Second point]
 ],
 =====*/
 		
 		dataToPoints: function(o){
-			//summary:
+			// summary:
 			//		Converts data to points.
 			o = o || this.data;
 			if(o.radius || o.angle){
@@ -91,7 +90,7 @@ StencilPoints: [
 			//		Creates a dojox.gfx.shape based on passed arguments.
 			//		Can be called many times by implementation to create
 			//		multiple shapes in one stencil.
-			//
+
 			this.remove(this[shp]);
 			this[shp] = this.container.createLine(d)
 				.setStroke(sty);
@@ -103,7 +102,7 @@ StencilPoints: [
 			//		Renders the 'hit' object (the shape used for an expanded
 			//		hit area and for highlighting) and the'shape' (the actual
 			//		display object).
-			//
+
 			this.onBeforeRender(this);
 			this.renderHit && this._create("hit", this.data, this.style.currentHit);
 			this._create("shape", this.data, this.style.current);
@@ -113,6 +112,10 @@ StencilPoints: [
 	}
 );
 
-dojox.drawing.register({
+lang.setObject("dojox.drawing.stencil.Line", Line);
+registry.register({
 	name:"dojox.drawing.stencil.Line"
-}, "stencil");
\ No newline at end of file
+}, "stencil");
+
+return Line;
+});
diff --git a/dojox/drawing/stencil/Path.js b/dojox/drawing/stencil/Path.js
index 3542c90..a966547 100755
--- a/dojox/drawing/stencil/Path.js
+++ b/dojox/drawing/stencil/Path.js
@@ -1,15 +1,14 @@
-dojo.provide("dojox.drawing.stencil.Path");
-
-
-dojox.drawing.stencil.Path = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Creates a dojox.gfx Path based on points provided.
-	//
-	dojox.drawing.stencil._Base,
+define(["dojo", "dojo/_base/array", "../util/oo", "./_Base", "../manager/_registry"], 
+function(lang, array, oo, Base, registry){
+//console.log('base is', lang.isFunction(Base));
+var Path = oo.declare(
+	Base,
 	function(options){
-		dojo.disconnect(this._postRenderCon);
 	},
 	{
+		// summary:
+		//		Creates a dojox.gfx Path based on points provided.
+
 		type:"dojox.drawing.stencil.Path",
 		closePath: true,
 		baseRender:true,
@@ -24,9 +23,6 @@ StencilData: {
 StencilPoints: [
 	// summary:
 	//		An Array of StencilPoint objects that describe the Stencil
-	// 	0: Object
-	//		First point
-	// 	[1, 2, 3...] more points
 ],
 =====*/
 		
@@ -35,7 +31,7 @@ StencilPoints: [
 			//		Creates a dojox.gfx.shape based on passed arguments.
 			//		Can be called many times by implementation to create
 			//		multiple shapes in one stencil.
-			//
+
 			this.remove(this[shp]);
 			if(!this.points.length){ return; }
 	
@@ -44,7 +40,7 @@ StencilPoints: [
 				// In order to avoid the Safari d="" errors,
 				// we'll need to build a string and set that.
 				var strAr = [];
-				dojo.forEach(this.points, function(o, i){
+				array.forEach(this.points, function(o, i){
 					if(!o.skip){
 						if(i==0){
 							strAr.push("M " + o.x +" "+ o.y);
@@ -73,7 +69,7 @@ StencilPoints: [
 				
 				this.closePath && this[shp].setFill(sty.fill);
 				
-				dojo.forEach(this.points, function(o, i){
+				array.forEach(this.points, function(o, i){
 					if(!o.skip){
 						if(i==0 || o.t=="M"){
 							this[shp].moveTo(o.x, o.y);
@@ -96,7 +92,7 @@ StencilPoints: [
 			//		Renders the 'hit' object (the shape used for an expanded
 			//		hit area and for highlighting) and the'shape' (the actual
 			//		display object).
-			//
+
 			this.onBeforeRender(this);
 			this.renderHit && this._create("hit", this.style.currentHit);
 			this._create("shape", this.style.current);
@@ -107,10 +103,10 @@ StencilPoints: [
 		},
 		getBounds: function(/* ? Boolean*/absolute){
 			// summary:
-			//	Overwriting _Base.getBounds. Not sure how absolute should
-			//	work for a path.
+			//		Overwriting _Base.getBounds. Not sure how absolute should
+			//		work for a path.
 			var minx = 10000, miny = 10000, maxx = 0, maxy = 0;
-			dojo.forEach(this.points, function(p){
+			array.forEach(this.points, function(p){
 				if(p.x!==undefined && !isNaN(p.x)){
 					minx = Math.min(minx, p.x);
 					miny = Math.min(miny, p.y);
@@ -140,7 +136,7 @@ StencilPoints: [
 			//		drawable tools that extend it. Note that those tools
 			//		need to remove the shape created: this.closeGuide, or
 			//		add arg: remove
-			//
+
 			var dist = this.util.distance(firstPt.x, firstPt.y, currPt.x, currPt.y);
 			if(this.points.length>1){
 				if(dist<this.closeRadius && !this.closeGuide && !remove){
@@ -164,6 +160,10 @@ StencilPoints: [
 	}
 );
 
-dojox.drawing.register({
+lang.setObject("dojox.drawing.stencil.Path", Path);
+registry.register({
 	name:"dojox.drawing.stencil.Path"
-}, "stencil");
\ No newline at end of file
+}, "stencil");
+
+return Path;
+});
diff --git a/dojox/drawing/stencil/Rect.js b/dojox/drawing/stencil/Rect.js
index 79e29af..e382554 100755
--- a/dojox/drawing/stencil/Rect.js
+++ b/dojox/drawing/stencil/Rect.js
@@ -1,11 +1,8 @@
-dojo.provide("dojox.drawing.stencil.Rect");
+define(["dojo/_base/lang", "../util/oo", "./_Base", "../manager/_registry"], 
+function(lang, oo, Base, registry){
 
-
-dojox.drawing.stencil.Rect = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Creates a dojox.gfx rectangle based on data or points provided.
-	//
-	dojox.drawing.stencil._Base,
+var Rect = oo.declare(
+	Base,
 	function(options){
 		// summary:
 		//		constructor
@@ -14,12 +11,15 @@ dojox.drawing.stencil.Rect = dojox.drawing.util.oo.declare(
 		}
 	},
 	{
+		// summary:
+		//		Creates a dojox.gfx rectangle based on data or points provided.
+
 		type:"dojox.drawing.stencil.Rect",
 		anchorType: "group",
 		baseRender:true,
 		
 		dataToPoints: function(/*Object*/d){
-			//summary:
+			// summary:
 			//		Converts data to points.
 			d = d || this.data;
 			this.points = [
@@ -53,7 +53,7 @@ dojox.drawing.stencil.Rect = dojox.drawing.util.oo.declare(
 			//		Creates a dojox.gfx.shape based on passed arguments.
 			//		Can be called many times by implementation to create
 			//		multiple shapes in one stencil.
-			//
+
 			//console.log("render rect", d)
 			//console.log("rect sty:", sty)
 			this.remove(this[shp]);
@@ -69,7 +69,7 @@ dojox.drawing.stencil.Rect = dojox.drawing.util.oo.declare(
 			//		Renders the 'hit' object (the shape used for an expanded
 			//		hit area and for highlighting) and the'shape' (the actual
 			//		display object).
-			//
+
 			this.onBeforeRender(this);
 			this.renderHit && this._create("hit", this.data, this.style.currentHit);
 			this._create("shape", this.data, this.style.current);
@@ -77,6 +77,10 @@ dojox.drawing.stencil.Rect = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.register({
+lang.setObject("dojox.drawing.stencil.Rect", Rect);
+registry.register({
 	name:"dojox.drawing.stencil.Rect"
-}, "stencil");
\ No newline at end of file
+}, "stencil");
+
+return Rect;
+});
diff --git a/dojox/drawing/stencil/Text.js b/dojox/drawing/stencil/Text.js
index cdbfbf9..7f63869 100755
--- a/dojox/drawing/stencil/Text.js
+++ b/dojox/drawing/stencil/Text.js
@@ -1,88 +1,82 @@
-dojo.provide("dojox.drawing.stencil.Text");
-
-dojox.drawing.stencil.Text = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Creates a dojox.gfx Text (SVG or VML) based on data provided.
-	// description:
-	//		There are two text classes. TextBlock extends this one and
-	//		adds editable functionality, discovers text width etc.
-	//		This class displays text only. There is no line wrapping.
-	//		Multiple lines can be acheived by inserting \n linebreaks
-	//		in the text.
-	//
-	dojox.drawing.stencil._Base,
+define(["dojo", "../util/oo", "./_Base", "../manager/_registry", "../util/typeset"],
+function(dojo, oo, Base, registry, typeset){
+
+var Text = oo.declare(
+	Base,
 	function(options){
 		// summary:
 		//		constructor.
 	},
 	{
+		// summary:
+		//		Creates a dojox.gfx Text (SVG or VML) based on data provided.
+		// description:
+		//		There are two text classes. TextBlock extends this one and
+		//		adds editable functionality, discovers text width etc.
+		//		This class displays text only. There is no line wrapping.
+		//		Multiple lines can be achieved by inserting \n linebreaks
+		//		in the text.
+
 		type:"dojox.drawing.stencil.Text",
 		anchorType:"none",
 		baseRender:true,
-		
+
 		// align: String
-		//	Text horizontal alignment.
+		//		Text horizontal alignment.
 		//		Options: start, middle, end
 		align:"start",
-		//
-		// valign:String
-		//	Text vertical alignment
+
+		// valign: String
+		//		Text vertical alignment
 		//		Options: top, middle, bottom (FIXME: bottom not supported)
 		valign:"top",
-		//
+
 		// _lineHeight: [readonly] Number
 		// 	The height of each line of text. Based on style information
-		//	and font size.
+		//		and font size.
 		_lineHeight:1,
-		
-/*=====
-StencilData: {
-	// summary:
-	//		The data used to create the dojox.gfx Text
-	// 	x: Number
-	//		Left point x
-	// 	y: Number
-	//		Top point y
-	// 	width: ? Number
-	//		Optional width of Text. Not required but reccommended.
-	//		for auto-sizing, use TextBlock
-	// 	height: ? Number
-	//		Optional height of Text. If not provided, _lineHeight is used.
-	// 	text: String
-	//		The string content. If not provided, may auto-delete depending on defaults.
-},
-
-StencilPoints: [
-	// summary:
-	//		An Array of dojox.__StencilPoint objects that describe the Stencil
-	// 	0: Object
-	//		Top left point
-	// 	1: Object
-	//		Top right point
-	// 	2: Object
-	//		Bottom right point
-	// 	3: Object
-	//		Bottom left point
-],
-=====*/
+
+		/*=====
+		StencilData: {
+			// summary:
+			//		The data used to create the dojox.gfx Text
+			// x: Number
+			//		Left point x
+			// y: Number
+			//		Top point y
+			// width: ? Number
+			//		Optional width of Text. Not required but reccommended.
+			//		for auto-sizing, use TextBlock
+			// height: ? Number
+			//		Optional height of Text. If not provided, _lineHeight is used.
+			// text: String
+			//		The string content. If not provided, may auto-delete depending on defaults.
+		},
+
+		StencilPoints: [
+			// summary:
+			//		An Array of dojox.__StencilPoint objects that describe the Stencil
+			//		[Top left point, Top right point, Bottom right point, Bottom left point]
+		],
+		=====*/
 
 		typesetter: function(text){
 			// summary:
 			//		Register raw text, returning typeset form.
 			//		Uses function dojox.drawing.stencil.Text.typeset
 			//		for typesetting, if it exists.
-			//
-			if(dojox.drawing.util.typeset){
+
+			//if(dojox.drawing.util.typeset){
 				this._rawText = text;
-				return dojox.drawing.util.typeset.convertLaTeX(text);
-			}
-			return text;
+				return typeset.convertLaTeX(text);
+			//}
+			//return text;
 		},
 
 		setText: function(text){
 			// summary:
 			//		Setter for text.
-			//
+
 			// Only apply typesetting to objects that the user can modify.
 			// Else, it is assumed that typesetting is done elsewhere.
 			if(this.enabled){
@@ -94,16 +88,16 @@ StencilPoints: [
 			this._textArray = [];
 			this.created && this.render(text);
 		},
-		
+
 		getText: function(){
 			// summary:
 			//		Getter for text.
-			//
+
 			return this._rawText || this._text;
 		},
-		
+
 		dataToPoints: function(/*Object*/o){
-			//summary:
+			// summary:
 			//		Converts data to points.
 			o = o || this.data;
 			var w = o.width =="auto" ? 1 : o.width;
@@ -130,7 +124,7 @@ StencilPoints: [
 			};
 			return this.data;
 		},
-		
+
 		render: function(/* String*/text){
 			// summary:
 			//		Renders the 'hit' object (the shape used for an expanded
@@ -138,11 +132,10 @@ StencilPoints: [
 			//		display object). Text is slightly different than other
 			//		implementations. Instead of calling render twice, it calls
 			//		_createHilite for the 'hit'
-			// arguments:
-			//		text String
-			//			Changes text if sent. Be sure to use the setText and
-			//			not to call this directly.
-			//
+			// text: String
+			//		Changes text if sent. Be sure to use the setText and
+			//		not to call this directly.
+
 			this.remove(this.shape, this.hit);
 			//console.log("text render, outline:", !this.annotation, this.renderHit, (!this.annotation && this.renderHit))
 			!this.annotation && this.renderHit && this._renderOutline();
@@ -150,7 +143,7 @@ StencilPoints: [
 				this._text = text;
 				this._textArray = this._text.split("\n");
 			}
-			
+
 			var d = this.pointsToData();
 			var h = this._lineHeight;
 			var x = d.x + this.style.text.pad*2;
@@ -159,7 +152,7 @@ StencilPoints: [
 				y -= h/2;
 			}
 			this.shape = this.container.createGroup();
-			
+
 			/*console.log("    render ", this.type, this.id)
 			console.log("    render Y:", d.y, "textSize:", this.textSize, "LH:", this._lineHeight)
 			console.log("    render text:", y, " ... ", this._text, "enabled:", this.enabled);
@@ -169,22 +162,22 @@ StencilPoints: [
 				var tb = this.shape.createText({x: x, y: y+(h*i), text: unescape(txt), align: this.align})
 					.setFont(this.style.currentText)
 					.setFill(this.style.currentText.color);
-				
+
 				this._setNodeAtts(tb);
-			
+
 			}, this);
-			
+
 			this._setNodeAtts(this.shape);
-			
+
 		},
 		_renderOutline: function(){
 			// summary:
 			//		Create the hit and highlight area
 			//		for the Text.
-			//
+
 			if(this.annotation){ return; }
 			var d = this.pointsToData();
-			
+
 			if(this.align=="middle"){
 				d.x -= d.width/2 - this.style.text.pad * 2;
 			}else if(this.align=="start"){
@@ -192,16 +185,16 @@ StencilPoints: [
 			}else if(this.align=="end"){
 				d.x -= d.width - this.style.text.pad * 3;
 			}
-			
+
 			if(this.valign=="middle"){
 				d.y -= (this._lineHeight )/2 - this.style.text.pad;
 			}
-			
+
 			this.hit = this.container.createRect(d)
 				.setStroke(this.style.currentHit)
 				.setFill(this.style.currentHit.fill);
 				//.setFill("#ffff00");
-			
+
 			this._setNodeAtts(this.hit);
 			this.hit.moveToBack();
 		},
@@ -218,11 +211,15 @@ StencilPoints: [
 			sz--;
 			var box = dojo.marginBox(span);
 			dojo.destroy(span);
-			
+
 			return {size:sz, box:box};
 		}
 	}
 );
-dojox.drawing.register({
+
+dojo.setObject("dojox.drawing.stencil.Text", Text);
+registry.register({
 	name:"dojox.drawing.stencil.Text"
-}, "stencil");
\ No newline at end of file
+}, "stencil");
+return Text;
+});
diff --git a/dojox/drawing/stencil/_Base.js b/dojox/drawing/stencil/_Base.js
index 2b57eeb..79d28ff 100755
--- a/dojox/drawing/stencil/_Base.js
+++ b/dojox/drawing/stencil/_Base.js
@@ -1,58 +1,59 @@
-dojo.provide("dojox.drawing.stencil._Base");
-dojo.require("dojo.fx.easing");
+define(["dojo", "dojo/fx/easing", "../util/oo", "../annotations/BoxShadow", 
+  "../annotations/Angle", "../annotations/Label", "../defaults"], 
+function(dojo, easing, oo, BoxShadow, Angle, LabelExports, defaults){
 
 /*=====
-StencilArgs = {
-//	container: [readonly] dojo.gfx.group
+var StencilArgs = {
+// container: [readonly] dojo.gfx.group
 //		The parent shape that contains all
 //		shapes used in a Stencil
 container:null,
-//
-//	anchorType: String
+
+// anchorType: String
 //		Optionally blank or 'group'. 'group' tells
 //		an anchor point that it must constrain
 //		itself to other anchor points.
 anchorType:"",
-//
-// 	isText: Boolean
+
+// isText: Boolean
 //		Whether this is a text object or not
 //		(either stencil.text or tools.TextBlock)
 isText:false,
-//
-// 	shortType: String
+
+// shortType: String
 //		The type of stencil that corresponds with the types and
 //		constructors used in Drawing.registerTool
 shortType:"",
-//
-//	annotation: Boolean
+
+// annotation: Boolean
 //		A Stencil used within a Stencil. An annotation
 //		is not selectable or clickable. A Label would
 //		be one example.
 annotation:false,
-//
-//	subShape: Boolean
+
+// subShape: Boolean
 //		A Stencil used within a Stencil. A subShape
 //		is clickable. An arrow head would be an example.
 subShape:false,
-//
-//	style: Object
+
+// style: Object
 //		An instance of the styles and defaults used within
 //		the Stencil.
 style:null,
-//
-//	util: Object
+
+// util: Object
 //		Pointer to util.common
 util:null,
-//
-//	mouse: Object
+
+// mouse: Object
 //		Pointer to the mouse instance
 mouse:null,
-//
-//	keys: Object
+
+// keys: Object
 //		Pointer to the keys class
 keys:null,
-//
-//	points: StencilPoints
+
+// points: StencilPoints
 //		Points is an array of objects that make up the
 //		description of a Stencil. The points to a Rect
 //		that is 100x100 and at x:10 and y:10 would look like:
@@ -61,11 +62,11 @@ keys:null,
 //		they would go in the order that the Stencil would be drawn.
 //		Always when the points Array is set, a data Object is created
 //		as well. So never set points directly, always use setPoints().
-//	See:
-//		setPoints()
-points:[],
 //
-//	data: StencilData
+//		See: setPoints()
+points:[],
+
+// data: StencilData
 //		A data object typically (but not always) resembles the data
 //		that is used to create the dojox.gfx Shape. The same Rect
 //		example shown in points above would look like:
@@ -77,79 +78,73 @@ points:[],
 //		it doesn't provide much benefit.
 //		Always when a data object is set, a set of points is created
 //		as well. So never set data directly, always use setData().
-//	See:
-//		setData()
-data:null,
 //
-// 	marginZero [readonly] Number
-// 		How closely shape can get to y:0 or x:0. Less than zero has
+//		See: setData()
+data:null,
+
+// marginZero [readonly] Number
+//		How closely shape can get to y:0 or x:0. Less than zero has
 //		bugs in VML. This is set with defaults, and should be equal
 //		to half the size of an anchor point (5 px)
 marginZero:0,
-//
-//	created [readonly] Boolean
+
+// created: [readonly] Boolean
 //		Whether the Stencil has been rendered for the first time or
 //		not.
 created: false,
-//
-//	highlighted [readonly] Boolean
+
+// highlighted: [readonly] Boolean
 //		Whether the Stencil is highlighted or not.
 highlighted:false,
-//
-//	selected [readonly] Boolean
+
+// selected: [readonly] Boolean
 //		Whether the Stencil is selected or not.
 selected:false,
-//
-//	draws [readonly] Boolean
+
+// draws: [readonly] Boolean
 //		Whether the Stencil can draw with a mouse drag or can just
 //		be created programmtically. If the Stencil comes from the
 //		stencil package, it should be draw:false. If it comes from
 //		the tools package it should be draw:true.
 draws:false
-}
+};
 
-StencilPoint = {
+var StencilPoint = {
 // summary:
-//	One point Object in the points Array
-//	x: Number
+//		One point Object in the points Array
+// x: Number
 //		x position of point
-//	y: Number
+// y: Number
 //		y position of point
-}
+};
 
-ToolsSetup = {
+var ToolsSetup = {
 // summary:
-//	An object attached to a Tool's constructor
-//	used to inform the toolbar of its information
-//	and properties.
+//		An object attached to a Tool's constructor
+//		used to inform the toolbar of its information
+//		and properties.
 // description:
-//	This object is inserted into the *function* of
-//	a tool (not a stencil). Like: function.ToolsSetup
-//	It must be attached after constructr creation, so
-//	this object is found at the botton of the file.
-//
-//	name:String
+//		This object is inserted into the *function* of
+//		a tool (not a stencil). Like: function.ToolsSetup
+//		It must be attached after constructr creation, so
+//		this object is found at the botton of the file.
+
+// name: String
 //		Fully qualified name of constructor
-//	tooltip: Stirng
+// tooltip: String
 //		Text to display on toolbar button hover
-//	iconClass: String
+// iconClass: String
 //		CSS class with icon information to attach
 //		to toolbar button.
-}
+};
 =====*/
 
-dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
-	// summary:
-	//		The base class used for all Stencils.
-	// description:
-	//		All stencils extend this base class.
-	//		Most methods and events can be found here.
-	//
+var Base = oo.declare(
 	function(options){
 		//console.log("______Base", this.type, options)
 		// clone style so changes are reflected in future shapes
 		dojo.mixin(this, options);
-		this.style = options.style || dojox.drawing.defaults.copy();
+		this.style = options.style || defaults.copy();
 		if(options.stencil){
 			this.stencil = options.stencil;
 			this.util = options.stencil.util;
@@ -215,7 +210,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 
 			// TODO: thinner text selection
 			//this.style.hitSelected.width *= 0.5;
-			//
+
 			// ouch. how verbose. My mixin is weak....
 			this.deleteEmptyCreate = options.deleteEmptyCreate!==undefined ? options.deleteEmptyCreate : this.style.text.deleteEmptyCreate;
 			this.deleteEmptyModify = options.deleteEmptyModify!==undefined ? options.deleteEmptyModify : this.style.text.deleteEmptyModify;
@@ -264,7 +259,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			this._postRenderCon = dojo.connect(this, "render", this, "_onPostRender");
 		}
 		if(this.showAngle){
-			this.angleLabel = new dojox.drawing.annotations.Angle({stencil:this});
+			this.angleLabel = new Angle({stencil:this});
 		}
 
 		if(!this.enabled){
@@ -276,19 +271,24 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 
 	},
 	{
+		// summary:
+		//		The base class used for all Stencils.
+		// description:
+		//		All stencils extend this base class.
+		//		Most methods and events can be found here.
 
 		// type: String
 		//		The type of Stencil this is. Should be overridden
 		//		by extending classes.
-		//	FIXME: should this be declaredClass?
+		//		FIXME: should this be declaredClass?
 		type:"dojox.drawing.stencil",
-		//
-		//	minimumSize: Number
+
+		// minimumSize: Number
 		//		The minimum size allowed for a render. If the size
 		//		is less, the shape is destroyed.
 		minimumSize:10,
-		//
-		//	enabled [readonly] Boolean
+
+		// enabled: [readonly] Boolean
 		//		Whether the Stencil is enabled or not.
 		enabled:true,
 
@@ -332,38 +332,38 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		onModify: function(/*Object*/stencil){
 			// summary:
 			//		Stub - fires on change of any property,
-			// including style properties
+			//		including style properties
 
 		},
 
 		onChangeData: function(/*Object*/ stencil){
 			// summary:
 			//		Stub - fires on change of dimensional
-			//	properties or a text change
+			//		properties or a text change
 		},
 
 		onChangeText: function(value){ // value or 'this' ?
 			// summary:
 			//		Stub - fires on change of text in a
-			//	TextBlock tool only
+			//		TextBlock tool only
 		},
 
 		onRender: function(/*Object*/ stencil){
 			// summary:
 			//		Stub - Fires on creation.
-			// 		Drawing connects to this (once!) to be
-			// 		notified of drag completion. But only if it
+			//		Drawing connects to this (once!) to be
+			//		notified of drag completion. But only if it
 			//		was registered as a Tool. Creating Stencil in and of
-			// 		itself does not register it.
-			//
-			// 		This should fire
-			// 		at the *end* of creation (not during drag)
+			//		itself does not register it.
 			//
+			//		This should fire
+			//		at the *end* of creation (not during drag)
+
 			//	FIXME:
 			//		This should probably be onCreate. It should
 			//		only fire once. But the mechanism for determining
 			//		this is more complicated than it sounds.
-			//
+
 			this._postRenderCon = dojo.connect(this, "render", this, "_onPostRender");
 			this.created = true;
 			this.disconnectMouse();
@@ -381,7 +381,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		onChangeStyle: function(/*Object*/stencil){
 			// summary:
 			//		Fires when styles of shape has changed
-			//
+
 			this._isBeingModified = true; // need this to prevent onRender
 			if(!this.enabled){
 				this.style.current = this.style.disabled;
@@ -408,7 +408,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			}
 
 			// NOTE: Can't just change props like setStroke
-			//	because Silverlight throws error
+			// because Silverlight throws error
 			this.render();
 		},
 
@@ -416,7 +416,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			console.warn("ANIMATE..........................")
 			var d = 	options.d || options.duration || 1000;
 			var ms = 	options.ms || 20;
-			var ease = 	options.ease || dojo.fx.easing.linear;
+			var ease = 	options.ease || easing.linear;
 			var steps = options.steps;
 			var ts = 	new Date().getTime();
 			var w = 	100;
@@ -478,13 +478,13 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			}), ms);
 		},
 
-		attr: function(/*String | Object*/key, /* ? String | Number */value){
-			// summary
+		attr: function(/*String|Object*/ key, /*String|Number?*/value){
+			// summary:
 			//		Changes properties in the style or disabled styles,
 			//		depending on whether the object is enabled.
 			//		Also can be used to change most position and size props.
 
-			// NOTE: JUST A SETTTER!! TODO!
+			// NOTE: JUST A SETTER!! TODO!
 
 			// WARNING:
 			//	Not doing any Stencil-type checking here. Setting a height
@@ -623,7 +623,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		exporter: function(){
 			// summary:
 			//		Exports Stencil data
-			//
+
 			var type = this.type.substring(this.type.lastIndexOf(".")+1).charAt(0).toLowerCase()
 				+ this.type.substring(this.type.lastIndexOf(".")+2);
 			var o = dojo.clone(this.style.norm);
@@ -651,9 +651,9 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 
 
 		//	TODO:
-		// 		Makes these all called by att()
+		//		Makes these all called by att()
 		//		Should points and data be?
-		//
+
 		disable: function(){
 			// summary:
 			//		Disables Stencil so it is not selectable.
@@ -680,7 +680,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			//		calling this just sets the style to the 'selected'
 			//		theme. 'manager.Stencil' should be used for selecting
 			//		Stencils.
-			//
+
 			this.selected = true;
 			this.onChangeStyle(this);
 		},
@@ -692,11 +692,9 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			//		calling this just sets the style to the current
 			//		theme. 'manager.Stencil' should be used for selecting
 			//		and deselecting Stencils.
-			//
-			//	arguments:
-			//		useDelay: Boolean
-			//			Adds  slight delay before the style is set.
-			//
+			// useDelay: Boolean
+			//		Adds  slight delay before the style is set.
+
 			// should not have to render here because the deselection
 			// re-renders after the transform
 			// but... oh well.
@@ -748,21 +746,21 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			// summary:
 			//		Fired at the start of a transform. This would be
 			//		an anchor drag or a selection.
-			//
+
 			this._isBeingModified = true;
 		},
 
 		onTransformEnd: function(/* manager.Anchor */anchor){
 			// summary:
-			// 		Called from anchor point up mouse up
+			//		Called from anchor point up mouse up
 			this._isBeingModified = false;
 			this.onModify(this);
 		},
 
 		onTransform: function(/* ? manager.Anchor */anchor){
 			// summary:
-			// 		Called from anchor point mouse drag
-			// 		also called from plugins.Pan.checkBounds
+			//		Called from anchor point mouse drag
+			//		also called from plugins.Pan.checkBounds
 			if(!this._isBeingModified){
 				this.onTransformBegin();
 			}
@@ -777,10 +775,9 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			//		Moves object to a new X Y location
 			//		mx is additive. So mx.dx=1 will move the stencil
 			//		1 pixel to the right from wherever it was.
-			//
+
 			// An attempt is made to prevent < 0 errors, but
 			// this won't work on all shapes (like Axes)
-			//
 			if(!mx.dx && !mx.dy){
 				// no change
 				return;
@@ -805,16 +802,16 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		applyTransform: function(mx){
 			// summary:
 			//		Applies the transform to the stencil
-			//		NOTE: PARTIALLY IMPLEMENTED
-			//			Only applies x y coords
+			//
+			//		NOTE: PARTIALLY IMPLEMENTED.  Only applies x y coords.
 			this.transformPoints(mx);
 		},
 
 		setTransform: function(/*Object*/mx){
 			// summary:
 			//		Sets the transform to the stencil
-			//		NOTE: PARTIALLY IMPLEMENTED
-			//			Only applies x y coords
+			//
+			//		NOTE: PARTIALLY IMPLEMENTED.  Only applies x y coords.
 			this.attr({
 				x:mx.dx,
 				y:mx.dy
@@ -831,7 +828,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		addShadow: function(/*Object*/args){
 			args = args===true ? {} : args;
 			args.stencil = this;
-			this.shadow = new dojox.drawing.annotations.BoxShadow(args);
+			this.shadow = new BoxShadow(args);
 		},
 
 		removeShadow: function(){
@@ -844,12 +841,10 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			//		If Stencil contains a labelPosition method, that will
 			//		be used for positioning. Otherwise
 			//		dojox.drawing.util.positioning.label is used.
-			// arguments:
-			//		text: String
-			//			The text to set as the label.
-			//
+			// text: String
+			//		The text to set as the label.
 			if(!this._label){
-				this._label = new dojox.drawing.annotations.Label({
+				this._label = new LabelExports.Label({
 					text:text,
 					util:this.util,
 					mouse:this.mouse,
@@ -866,7 +861,6 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		getLabel: function(){
 			// summary:
 			//		Get the text of the label.
-			//
 			if(this._label){
 				return this._label.getText(); // String
 			}
@@ -876,7 +870,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		getAngle: function(){
 			// summary:
 			//		Gets angle of Stencil
-			// NOTE: Only works for Lines, Arrows, Vectors and Axes
+			//		NOTE: Only works for Lines, Arrows, Vectors and Axes
 			//		(works on points, not transforms)
 			var d = this.pointsToData();
 			var obj = {
@@ -894,10 +888,10 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		},
 		getRadius: function(){
 			// summary:
-			//		Gets radius (length) of Stencil
-			// NOTE: Only works for Lines, Arrows and Vectors
-			//	(not for Ellipse, Axes has its own version)
+			//		Gets radius (length) of Stencil.
 			//
+			//		NOTE: Only works for Lines, Arrows and Vectors
+			//		(not for Ellipse, Axes has its own version)
 			var box = this.getBounds(true);
 			var line = {start:{x:box.x1, y:box.y1}, x:box.x2, y:box.y2};
 			return this.util.length(line);
@@ -906,16 +900,16 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			// summary:
 			//		Returns the coordinates of the Stencil. This is often
 			//		different than the data or the points.
-			//		arguments:
-			//			absolute: Boolean
-			//				Keeps lines from flipping (see note).
 			//
-			// NOTE: Won't work for paths or annotations (labels, Axes, arrow tips)
+			//		NOTE: Won't work for paths or annotations (labels, Axes, arrow tips)
 			//		They should overwrite.
-			// NOTE: Primarily used for checking for if shape is off
+			//
+			//		NOTE: Primarily used for checking for if shape is off
 			//		canvas. Therefore Lines could get flipped. Use absolute
 			//		to prevent this.
-			//
+			// absolute: Boolean
+			//		Keeps lines from flipping (see note).
+
 			var p = this.points, x1, y1, x2, y2;
 			if(p.length==2){
 				if(absolute){
@@ -958,7 +952,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			// summary:
 			//		Internal. Prevent item from being drawn/rendered less
 			//		than zero on the X or Y.
-			//
+
 			// if being modified anchors will prevent less than zero.
 			if(this._isBeingModified){ return; }
 			// FIXME: why is this sometimes empty?
@@ -996,7 +990,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			//		Drag-create or programmatic create calls onRender
 			//		and afterwards, _onPostRender is called and
 			//		manages further events.
-			//
+
 			// TODO: can this be onModify? Is that more clear?
 			//
 			//console.info("...........post render.....");
@@ -1026,7 +1020,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			// summary:
 			//		Internal. Sets the rawNode attribute. (Or in Silverlight
 			//		an "object attribute". "stencil" is
-			// 		used by the application to determine if
+			//		used by the application to determine if
 			//		something is selectable or not. This also
 			//		sets the mouse custom events like:
 			//		"onStencilUp". To disable the selectability,
@@ -1041,10 +1035,11 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		destroy: function(){
 			// summary:
 			//		Destroys this Stencil
+
 			// Note:
 			//		Can connect to this, but it's better to
 			//		connect to onDelete
-			//
+
 			// prevent loops:
 			if(this.destroyed){ return; }
 			if(this.data || this.points && this.points.length){
@@ -1061,11 +1056,11 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		remove: function(/*Shape...*/){
 			// summary:
 			//		Removes shape(s), typically before a re-render
-			// 		No args defaults to this.shape
+			//		No args defaults to this.shape
 			//		Pass in multiple args to remove multiple shapes
-			//
+
 			// FIXME: Use an Array of all shapes
-			//
+
 			var a = arguments;
 			if(!a.length){
 				if(!this.shape){ return; }
@@ -1081,9 +1076,9 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		connectMult: function(/*dojo.connect args */){
 			// summary:
 			//		Convenience method for batches of quick connects
-			// 		Handles are not returned and therefore cannot be
+			//		Handles are not returned and therefore cannot be
 			//		disconnected until Shape destroy time
-			//
+
 			if(arguments.length>1){
 				// arguments are the connect params
 				this._cons.push(this.connect.apply(this, arguments));
@@ -1109,7 +1104,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			//		If true, the connection happens only
 			//		once then disconnects. Five args are required
 			//		for this functionality.
-			//
+
 			var c;
 			if(typeof(o)!="object"){
 				if(s){
@@ -1138,7 +1133,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			return c;
 		},
 
-		disconnect: function(/*handle | Array*/handles){
+		disconnect: function(/*Handle|Array*/handles){
 			// summary:
 			//		Removes connections based on passed
 			//		handles arguments
@@ -1163,8 +1158,8 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		// Should be overwritten by sub class:
 		render: function(){
 			// summary:
-			// 	This Stencil's render description. Often
-			//	calls 'sub render' methods.
+			//		This Stencil's render description. Often
+			//		calls 'sub render' methods.
 		},
 		//renderOutline: function(){},
 		dataToPoints: function(/*Object*/data){
@@ -1178,7 +1173,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		onDown: function(/*EventObject*/obj){
 			// summary:
 			//		Mouse event, fired on mousedown on canvas
-			//
+
 			// by default, object is ready to accept data
 			// turn this off for dragging or onRender will
 			// keep firing and register the shape
@@ -1196,7 +1191,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		onDrag: function(/*EventObject*/obj){
 			// summary:
 			//		Mouse event, fired on mousemove while mouse
-			// 		is down on canvas
+			//		is down on canvas
 		},
 		onUp: function(/*EventObject*/obj){
 			// summary:
@@ -1204,4 +1199,6 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 		}
 	}
 );
-
+dojo.setObject("dojox.drawing.stencil._Base", Base);
+return Base;
+});
diff --git a/dojox/drawing/tests/drawing.html b/dojox/drawing/tests/drawing.html
index e190525..910f51c 100755
--- a/dojox/drawing/tests/drawing.html
+++ b/dojox/drawing/tests/drawing.html
@@ -29,37 +29,29 @@
 		}
 	</style>
 
+	<script src="../../../dojo/dojo.js" data-dojo-config="async:1"></script>
 	<script>
-		djConfig = {
-			isDebug:false,
-			parseOnLoad:true
-		};
-	</script>
-	<script src="../../../dojo/dojo.js"></script>
-	<script>
-		dojo.require("dojo.parser");
-		dojo.require("dojox.drawing");
-		// custom Tools and Plugins need to be required
-		dojo.require("dojox.drawing.ui.dom.Toolbar");
-		dojo.require("dojox.drawing.tools.TextBlock");
-		dojo.require("dojox.drawing.tools.Rect");
-		dojo.require("dojox.drawing.tools.Ellipse");
-		dojo.require("dojox.drawing.tools.Line");
-		dojo.require("dojox.drawing.tools.Path");
-
-		dojo.require("dojox.drawing.annotations.Label");
-		dojo.require("dojox.drawing.annotations.Angle");
-		dojo.require("dojox.drawing.annotations.Arrow");
-		dojo.require("dojox.drawing.annotations.BoxShadow");
-
-		dojo.require("dojox.drawing.tools.custom.Vector");
-		dojo.require("dojox.drawing.tools.custom.Axes");
-		dojo.require("dojox.drawing.tools.Arrow");
-		dojo.require("dojox.drawing.ui.dom.Pan");
-		dojo.require("dojox.drawing.ui.dom.Zoom");
-		dojo.require("dojox.drawing.plugins.drawing.Grid");
-		dojo.require("dojox.drawing.plugins.drawing.GreekPalette");
-
+		require(["dojo/parser", "dojox/drawing", 
+			// custom Tools and Plugins need to be required
+			"dojox/drawing/tools/TextBlock",
+			"dojox/drawing/tools/Rect",
+			"dojox/drawing/tools/Ellipse",
+			"dojox/drawing/tools/Line",
+			"dojox/drawing/tools/Path",
+			"dojox/drawing/tools/Pencil",
+			"dojox/drawing/tools/custom/Vector",
+			"dojox/drawing/tools/custom/Axes",
+			"dojox/drawing/tools/Arrow",
+			"dojox/drawing/plugins/tools/Pan",
+			"dojox/drawing/plugins/tools/Zoom",
+			"dojox/drawing/plugins/tools/Iconize",
+			"dojox/drawing/plugins/drawing/GreekPalette",
+			"dojox/drawing/plugins/drawing/Grid",
+			"dojox/drawing/ui/dom/Toolbar",
+			"dojox/drawing/ui/dom/Pan",
+			"dojox/drawing/ui/dom/Zoom",
+			"dojo/domReady!"], function(parser){
+				parser.parse();
 
 		var doExport = function(){
 			var o = myDrawing.exporter();
@@ -77,10 +69,7 @@
 			myDrawing.removeAll();
 		}
 
-		dojo.addOnLoad(function(){
-
-
-			// myDrawing referenced by jsId
+			// myDrawing referenced by data-dojo-id
 			dojo.connect(myDrawing, "onSurfaceReady", function(){
 
 				var rect = myDrawing.addStencil("rect", {data:{x:50, y:275, width:100, height:100}});
@@ -161,7 +150,7 @@
 
 		</div>
 
-		<div dojoType="dojox.drawing.Drawing" id="drawingNode" jsId="myDrawing" drawingType="canvas" class="drawing"
+		<div dojoType="dojox.drawing.Drawing" id="drawingNode" data-dojo-id="myDrawing" drawingType="canvas" class="drawing"
 			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}}]">
 
 		</div>
diff --git a/dojox/drawing/tests/test_drawing.html b/dojox/drawing/tests/test_drawing.html
index 0297378..e48eb9e 100644
--- a/dojox/drawing/tests/test_drawing.html
+++ b/dojox/drawing/tests/test_drawing.html
@@ -34,102 +34,89 @@
 		}
 	</style>
 
+	<script src="../../../dojo/dojo.js" data-dojo-config="async:1"></script>
 	<script>
-		djConfig = {
-			isDebug:false,
-			parseOnLoad:true
-		};
-	</script>
-	<script src="../../../dojo/dojo.js"></script>
-	<script>
-		dojo.require("dojo.parser");
-		dojo.require("dojox.drawing");
-
-
-		// custom Tools and Plugins need to be required
-		dojo.require("dojox.drawing.tools.TextBlock");
-		dojo.require("dojox.drawing.tools.Rect");
-		dojo.require("dojox.drawing.tools.Ellipse");
-		dojo.require("dojox.drawing.tools.Line");
-		dojo.require("dojox.drawing.tools.Path");
-		dojo.require("dojox.drawing.tools.Pencil");
-
-		dojo.require("dojox.drawing.tools.custom.Vector");
-		dojo.require("dojox.drawing.tools.custom.Axes");
-		dojo.require("dojox.drawing.tools.Arrow");
-
-		dojo.require("dojox.drawing.plugins.tools.Pan");
-		dojo.require("dojox.drawing.plugins.tools.Zoom");
-		dojo.require("dojox.drawing.plugins.tools.Iconize");
-
-		dojo.require("dojox.drawing.plugins.drawing.GreekPalette");
-		dojo.require("dojox.drawing.plugins.drawing.Grid");
-		
-		dojo.require("dojox.drawing.ui.Toolbar");
-		dojo.require("dojox.drawing.ui.Button");
-		//dojo.require("dojox.drawing.ui.Tooltip");
-
-		var doExport = function(){
-			var o = myDrawing.exporter();
-			console.log("EXPORT:")
-			console.dir(o)
-			console.log(dojo.toJson(o));
-			dojo.byId("data").value = dojo.toJson(o, true);
-		}
-
-		var doImport = function(){
-			myDrawing.importer(dojo.fromJson(dojo.byId("data").value));
-		}
-
-		var doClear = function(){
-			myDrawing.removeAll();
-		}
+		require(["dojo/parser", "dojox/drawing", 
+			// custom Tools and Plugins need to be required
+			"dojox/drawing/tools/TextBlock",
+			"dojox/drawing/tools/Rect",
+			"dojox/drawing/tools/Ellipse",
+			"dojox/drawing/tools/Line",
+			"dojox/drawing/tools/Path",
+			"dojox/drawing/tools/Pencil",
+			"dojox/drawing/tools/custom/Vector",
+			"dojox/drawing/tools/custom/Axes",
+			"dojox/drawing/tools/Arrow",
+			"dojox/drawing/plugins/tools/Pan",
+			"dojox/drawing/plugins/tools/Zoom",
+			"dojox/drawing/plugins/tools/Iconize",
+			"dojox/drawing/plugins/drawing/GreekPalette",
+			"dojox/drawing/plugins/drawing/Grid",
+			"dojox/drawing/ui/Toolbar",
+			"dojox/drawing/ui/Button",
+			"dojo/domReady!"], function(parser){
+				parser.parse();
+				var doExport = function(){
+					var o = myDrawing.exporter();
+					console.log("EXPORT:")
+					console.dir(o)
+					console.log(dojo.toJson(o));
+					dojo.byId("data").value = dojo.toJson(o, true);
+				}
+
+				var doImport = function(){
+					myDrawing.importer(dojo.fromJson(dojo.byId("data").value));
+				}
+
+				var doClear = function(){
+					myDrawing.removeAll();
+				}
+
+				dojo.connect(myDrawing, "onSurfaceReady", function(){
+					new dojox.drawing.ui.Toolbar({
+						drawing:myDrawing,
+						tools:"all",
+						plugs:"all",
+						selected:"",
+						size:30,
+						radius:2,
+						margin:5
+					});
 
-		dojo.addOnLoad(function(){
-			dojo.connect(myDrawing, "onSurfaceReady", function(){
-				new dojox.drawing.ui.Toolbar({
-					drawing:myDrawing,
-					tools:"all",
-					plugs:"all",
-					selected:"",
-					size:30,
-					radius:2,
-					margin:5
 				});
 
-			});
-
-			dojo.connect(dojo.byId("import"), "click", doImport);
-			dojo.connect(dojo.byId("export"), "click", doExport);
-			dojo.connect(dojo.byId("clear"), "click", doClear);
-			dojo.connect(dojo.byId("selectall"), "click", function(){
-				myDrawing.selectAll();
-			});
+				dojo.connect(dojo.byId("import"), "click", doImport);
+				dojo.connect(dojo.byId("export"), "click", doExport);
+				dojo.connect(dojo.byId("clear"), "click", doClear);
+				dojo.connect(dojo.byId("selectall"), "click", function(){
+					myDrawing.selectAll();
+				});
 
-			dojo.connect(dojo.byId("red"), "click", function(){
-				myDrawing.changeDefaults({
-					norm:{
-						fill:"#ff0000",
-						width:5,
-						color:"#ff00ff"
-					}
+				dojo.connect(dojo.byId("red"), "click", function(){
+					myDrawing.changeDefaults({
+						norm:{
+							fill:"#ff0000",
+							width:5,
+							color:"#ff00ff"
+						}
+					});
 				});
-			});
-			dojo.connect(dojo.byId("blue"), "click", function(){
-				myDrawing.changeDefaults({
-					norm:{
-						fill:"#0000ff",
-						width:5,
-						color:"#ffff00"
-					}
+				dojo.connect(dojo.byId("blue"), "click", function(){
+					myDrawing.changeDefaults({
+						norm:{
+							fill:"#0000ff",
+							width:5,
+							color:"#ffff00"
+						}
+					});
 				});
-			});
-			dojo.connect(dojo.byId("yellow"), "click", function(){
-				myDrawing.toSelected("attr", {
-					fill:"#ffff00"
+				dojo.connect(dojo.byId("yellow"), "click", function(){
+					myDrawing.toSelected("attr", {
+						fill:"#ffff00"
+					});
 				});
 			});
-		})
+
 	</script>
 
 </head>
@@ -137,7 +124,7 @@
     <h2>Drawing Test</h2>
 	<div id="conEdit" contenteditable="true"></div>
 	<div id="wrapper">
-		<div dojoType="dojox.drawing.Drawing" id="drawingNode" jsId="myDrawing" class="drawing"
+		<div dojoType="dojox.drawing.Drawing" id="drawingNode" data-dojo-id="myDrawing" class="drawing"
 			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{minor:20, major:100}}]">
 		</div>
 	</div>
diff --git a/dojox/drawing/tests/test_drawing_toolbar.html b/dojox/drawing/tests/test_drawing_toolbar.html
index c53f356..c9d70dd 100644
--- a/dojox/drawing/tests/test_drawing_toolbar.html
+++ b/dojox/drawing/tests/test_drawing_toolbar.html
@@ -94,7 +94,7 @@
 		
 		<div dojoType="dojox.drawing.ui.Toolbar" id="gfxToolbarNode" drawingId="drawingNode" class="gfxToolbar" tools="all" plugs="all" selected="ellipse"></div>
 		
-		<div dojoType="dojox.drawing.Drawing" id="drawingNode" jsId="myDrawing" class="drawing"
+		<div dojoType="dojox.drawing.Drawing" id="drawingNode" data-dojo-id="myDrawing" class="drawing"
 			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}}]">
 		</div>
 	</div>
diff --git a/dojox/drawing/tests/test_paths.html b/dojox/drawing/tests/test_paths.html
index 65acf96..d24b2f7 100644
--- a/dojox/drawing/tests/test_paths.html
+++ b/dojox/drawing/tests/test_paths.html
@@ -109,7 +109,7 @@
 		
 		<div dojoType="dojox.drawing.ui.Toolbar" id="gfxToolbarNode" drawingId="drawingNode" class="gfxToolbar" orient="H" tools="all" plugs="all" selected="pencil"></div>
 		
-		<div dojoType="dojox.drawing.Drawing" id="drawingNode" jsId="myDrawing" class="drawing"
+		<div dojoType="dojox.drawing.Drawing" id="drawingNode" data-dojo-id="myDrawing" class="drawing"
 			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{minor:20, major:100}}]">
 		</div>
 	</div>
diff --git a/dojox/drawing/tests/test_shadows.html b/dojox/drawing/tests/test_shadows.html
index a9b8e9c..65953fb 100644
--- a/dojox/drawing/tests/test_shadows.html
+++ b/dojox/drawing/tests/test_shadows.html
@@ -90,7 +90,7 @@
 
 		<!--<div dojoType="dojox.drawing.ui.Toolbar" id="gfxToolbarNode" drawingId="drawingNode" class="gfxToolbar" tools="all" plugs="all" selected="ellipse"></div>-->
 
-		<div dojoType="dojox.drawing.Drawing" id="drawingNode" jsId="myDrawing" class="drawing"
+		<div dojoType="dojox.drawing.Drawing" id="drawingNode" data-dojo-id="myDrawing" class="drawing"
 			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{minor:20, major:100}}]">
 		</div>
 	</div>
diff --git a/dojox/drawing/tools/Arrow.js b/dojox/drawing/tools/Arrow.js
index c874f75..e6edf09 100755
--- a/dojox/drawing/tools/Arrow.js
+++ b/dojox/drawing/tools/Arrow.js
@@ -1,18 +1,17 @@
-dojo.provide("dojox.drawing.tools.Arrow");
+define(["dojo/_base/lang", "../util/oo", "../manager/_registry", "./Line", 
+"../annotations/Arrow", "../util/positioning"],
+function(lang, oo, registry, Line, AnnotationArrow, positioning){
 
-dojox.drawing.tools.Arrow = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Extends stencil.Line and adds an arrow head
-	//		to the end and or start.
-	//
-	dojox.drawing.tools.Line,
+var Arrow = oo.declare(
+	Line,
 	function(options){
-		// summary: constructor
+		// summary:
+		//		constructor
 		if(this.arrowStart){
-			this.begArrow = new dojox.drawing.annotations.Arrow({stencil:this, idx1:0, idx2:1});
+			this.begArrow = new AnnotationArrow({stencil:this, idx1:0, idx2:1});
 		}
 		if(this.arrowEnd){
-			this.endArrow = new dojox.drawing.annotations.Arrow({stencil:this, idx1:1, idx2:0});
+			this.endArrow = new AnnotationArrow({stencil:this, idx1:1, idx2:0});
 		}
 		if(this.points.length){
 			// This is protecting against cases when there are no points
@@ -23,6 +22,10 @@ dojox.drawing.tools.Arrow = dojox.drawing.util.oo.declare(
 		}
 	},
 	{
+		// summary:
+		//		Extends stencil.Line and adds an arrow head
+		//		to the end and or start.
+
 		draws:true,
 		type:"dojox.drawing.tools.Arrow",
 		baseRender:false,
@@ -30,7 +33,7 @@ dojox.drawing.tools.Arrow = dojox.drawing.util.oo.declare(
 		// arrowStart: Boolean
 		//		Whether or not to place an arrow on start.
 		arrowStart:false,
-		//
+
 		// arrowEnd: Boolean
 		//		Whether or not to place an arrow on end.
 		arrowEnd:true,
@@ -38,9 +41,9 @@ dojox.drawing.tools.Arrow = dojox.drawing.util.oo.declare(
 		labelPosition: function(){
 			// summary:
 			//		The custom position used for the label
-			//
+
 			var d = this.data;
-			var pt = dojox.drawing.util.positioning.label({x:d.x1,y:d.y1},{x:d.x2,y:d.y2});
+			var pt = positioning.label({x:d.x1,y:d.y1},{x:d.x2,y:d.y2});
 			return {
 				x:pt.x,
 				y:pt.y
@@ -48,8 +51,6 @@ dojox.drawing.tools.Arrow = dojox.drawing.util.oo.declare(
 		},
 		
 		onUp: function(/*EventObject*/obj){
-			// summary: See stencil._Base.onUp
-			//
 			if(this.created || !this.shape){ return; }
 			
 			// if too small, need to reset
@@ -72,12 +73,14 @@ dojox.drawing.tools.Arrow = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.tools.Arrow.setup = {
-	// summary: See stencil._Base ToolsSetup
-	//
+lang.setObject("dojox.drawing.tools.Arrow", Arrow);
+Arrow.setup = {
 	name:"dojox.drawing.tools.Arrow",
 	tooltip:"Arrow Tool",
 	iconClass:"iconArrow"
 };
 
-dojox.drawing.register(dojox.drawing.tools.Arrow.setup, "tool");
\ No newline at end of file
+registry.register(Arrow.setup, "tool");
+
+return Arrow;
+});
diff --git a/dojox/drawing/tools/Ellipse.js b/dojox/drawing/tools/Ellipse.js
index 93ee548..fff236b 100755
--- a/dojox/drawing/tools/Ellipse.js
+++ b/dojox/drawing/tools/Ellipse.js
@@ -1,18 +1,19 @@
-dojo.provide("dojox.drawing.tools.Ellipse");
+define(["dojo/_base/lang", "../util/oo", "../manager/_registry", "../stencil/Ellipse"],
+function(lang, oo, registry, StencilEllipse){
 
-dojox.drawing.tools.Ellipse = dojox.drawing.util.oo.declare(
-	// summary:
-	//		A drawable Ellipse.
-	//
-	dojox.drawing.stencil.Ellipse,
+//dojox.drawing.tools.Ellipse = 
+var Ellipse = oo.declare(
+	StencilEllipse,
 	function(){
-		// summary: constructor
+		// summary:
+		//		constructor
 	},
 	{
+		// summary:
+		//		A drawable Ellipse.
+
 		draws:true,
 		onDrag: function(/*EventObject*/obj){
-			// summary: See stencil._Base.onDrag
-			//
 			var s = obj.start, e = obj;
 			var	x = s.x < e.x ? s.x : e.x,
 				y = s.y < e.y ? s.y : e.y,
@@ -37,8 +38,6 @@ dojox.drawing.tools.Ellipse = dojox.drawing.util.oo.declare(
 		},
 		
 		onUp: function(/*EventObject*/obj){
-			// summary: See stencil._Base.onUp
-			//
 			if(this.created || !this._downOnCanvas){ return; }
 			this._downOnCanvas = false;
 			//Default shape on single click
@@ -68,12 +67,14 @@ dojox.drawing.tools.Ellipse = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.tools.Ellipse.setup = {
-	// summary: See stencil._Base ToolsSetup
-	//
+lang.setObject("dojox.drawing.tools.Ellipse", Ellipse);
+Ellipse.setup = {
 	name:"dojox.drawing.tools.Ellipse",
 	tooltip:"Ellipse Tool",
 	iconClass:"iconEllipse"
 };
 
-dojox.drawing.register(dojox.drawing.tools.Ellipse.setup, "tool");
\ No newline at end of file
+registry.register(Ellipse.setup, "tool");
+
+return Ellipse;
+});
diff --git a/dojox/drawing/tools/Line.js b/dojox/drawing/tools/Line.js
index 8db1f45..2c4974c 100755
--- a/dojox/drawing/tools/Line.js
+++ b/dojox/drawing/tools/Line.js
@@ -1,19 +1,20 @@
-dojo.provide("dojox.drawing.tools.Line");
+define(["dojo/_base/lang", "../util/oo", "../manager/_registry", "../stencil/Line"],
+function(lang, oo, registry, StencilLine){
 
-dojox.drawing.tools.Line = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Class for a drawable Line
-	dojox.drawing.stencil.Line,
+//dojox.drawing.tools.Line 
+var Line = oo.declare(
+	StencilLine,
 	function(){
-		// summary: constructor
+		// summary:
+		//		constructor
 	},
 	{
+		// summary:
+		//		Class for a drawable Line
+
 		draws:true,
 		showAngle:true,
 		onTransformEnd: function(/*manager.Anchor*/anchor){
-			// summary:
-			//	Overwrites _Base.onTransformEnd
-			//
 			this._toggleSelected();
 			if(this.getRadius()<this.minimumSize){
 				var p = this.points;
@@ -36,8 +37,6 @@ dojox.drawing.tools.Line = dojox.drawing.util.oo.declare(
 		},
 		
 		onDrag: function(/*EventObject*/obj){
-			// summary: See stencil._Base.onDrag
-			//
 			if(this.created){ return; }
 			var x1 = obj.start.x,
 				y1 = obj.start.y,
@@ -72,8 +71,6 @@ dojox.drawing.tools.Line = dojox.drawing.util.oo.declare(
 		},
 		
 		onUp: function(/*EventObject*/obj){
-			// summary: See stencil._Base.onUp
-			//
 			if(this.created || !this._downOnCanvas){ return; }
 			this._downOnCanvas = false;
 			//Default shape on single click
@@ -107,12 +104,14 @@ dojox.drawing.tools.Line = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.tools.Line.setup = {
-	// summary: See stencil._Base ToolsSetup
-	//
+lang.setObject("dojox.drawing.tools.Line", Line);
+Line.setup = {
 	name:"dojox.drawing.tools.Line",
 	tooltip:"Line Tool",
 	iconClass:"iconLine"
 };
 
-dojox.drawing.register(dojox.drawing.tools.Line.setup, "tool");
\ No newline at end of file
+registry.register(Line.setup, "tool");
+
+return Line;
+});
diff --git a/dojox/drawing/tools/Path.js b/dojox/drawing/tools/Path.js
index 55f9584..9ad9c4b 100644
--- a/dojox/drawing/tools/Path.js
+++ b/dojox/drawing/tools/Path.js
@@ -1,12 +1,12 @@
-dojo.provide("dojox.drawing.tools.Path");
+define(["dojo/_base/lang", "../util/oo", "../manager/_registry", "../stencil/Path"],
+function(lang, oo, registry, StencilPath){
 
-dojox.drawing.tools.Path = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Class for a drawable Path
-	//
-	dojox.drawing.stencil.Path,
+//dojox.drawing.tools.Path
+var Path = oo.declare(
+	StencilPath,
 	function(){
-		// summary: constructor
+		// summary:
+		//		constructor
 		
 		this.pathMode = "";
 		this.currentPathMode = "";
@@ -15,6 +15,9 @@ dojox.drawing.tools.Path = dojox.drawing.util.oo.declare(
 		
 	},
 	{
+		// summary:
+		//		Class for a drawable Path
+
 		draws:true,
 		onDown: function(obj){
 			if(!this._started){
@@ -192,12 +195,14 @@ dojox.drawing.tools.Path = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.tools.Path.setup = {
-	// summary: See Base ToolsSetup
-	//
+lang.setObject("dojox.drawing.tools.Path", Path);
+Path.setup = {
 	name:"dojox.drawing.tools.Path",
 	tooltip:"Path Tool",
 	iconClass:"iconLine"
 };
 
-dojox.drawing.register(dojox.drawing.tools.Path.setup, "tool");
\ No newline at end of file
+registry.register(Path.setup, "tool");
+
+return Path;
+});
diff --git a/dojox/drawing/tools/Pencil.js b/dojox/drawing/tools/Pencil.js
index ba1efae..2afc3c7 100644
--- a/dojox/drawing/tools/Pencil.js
+++ b/dojox/drawing/tools/Pencil.js
@@ -1,16 +1,20 @@
-dojo.provide("dojox.drawing.tools.Pencil");
+define(["dojo/_base/lang", "../util/oo", "../manager/_registry", "../stencil/Path"],
+function(lang, oo, registry, StencilPath){
 
-dojox.drawing.tools.Pencil = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Class for a drawable, continous Path
-	//
-	dojox.drawing.stencil.Path,
+//dojox.drawing.tools.Pencil 
+var Pencil = oo.declare(
+	StencilPath,
 	function(){
-		// summary: constructor
+		// summary:
+		//		constructor
 		this._started = false;
 	},
 	{
+		// summary:
+		//		Class for a drawable, continuous Path
+
 		draws:true,
+
 		// minDist: Number
 		//		The distance the mouse must travel before rendering
 		//		a path segment. Lower number is a higher definition
@@ -72,12 +76,14 @@ dojox.drawing.tools.Pencil = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.tools.Pencil.setup = {
-	// summary: See Base ToolsSetup
-	//
+lang.setObject("dojox.drawing.tools.Pencil", Pencil);
+Pencil.setup = {
 	name:"dojox.drawing.tools.Pencil",
 	tooltip:"Pencil Tool",
 	iconClass:"iconLine"
 };
 
-dojox.drawing.register(dojox.drawing.tools.Pencil.setup, "tool");
\ No newline at end of file
+registry.register(Pencil.setup, "tool");
+
+return Pencil;
+});
diff --git a/dojox/drawing/tools/Rect.js b/dojox/drawing/tools/Rect.js
index 66db50f..7051770 100755
--- a/dojox/drawing/tools/Rect.js
+++ b/dojox/drawing/tools/Rect.js
@@ -1,19 +1,20 @@
-dojo.provide("dojox.drawing.tools.Rect");
+define(["dojo/_base/lang", "../util/oo", "../manager/_registry", "../stencil/Rect"],
+function(lang, oo, registry, StencilRect){
 
-dojox.drawing.tools.Rect = dojox.drawing.util.oo.declare(
-	// summary:
-	// 		Class for a drawable rectangle
-	//
-	dojox.drawing.stencil.Rect,
+//dojox.drawing.tools.Rect 
+var Rect = oo.declare(
+	StencilRect,
 	function(){
-		// summary: constructor
+		// summary:
+		//		constructor
 	},
 	{
+		// summary:
+		//		Class for a drawable rectangle
+
 		draws:true,
 		
 		onDrag: function(/*EventObject*/obj){
-			// summary: See stencil._Base.onDrag
-			//
 			var s = obj.start, e = obj;
 			var	x = s.x < e.x ? s.x : e.x,
 				y = s.y < e.y ? s.y : e.y,
@@ -37,8 +38,6 @@ dojox.drawing.tools.Rect = dojox.drawing.util.oo.declare(
 		},
 		
 		onUp: function(/*EventObject*/obj){
-			// summary: See stencil._Base.onUp
-			//
 			if(this.created || !this._downOnCanvas){ return; }
 			this._downOnCanvas = false;
 			
@@ -68,12 +67,14 @@ dojox.drawing.tools.Rect = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.tools.Rect.setup = {
-	// summary: See stencil._Base ToolsSetup
-	//
+lang.setObject("dojox.drawing.tools.Rect", Rect);
+Rect.setup = {
 	name:"dojox.drawing.tools.Rect",
 	tooltip:'<span class="drawingTipTitle">Rectangle Tool</span><br/>'
 		+ '<span class="drawingTipDesc">SHIFT - constrain to square</span>',
 	iconClass:"iconRect"
 };
-dojox.drawing.register(dojox.drawing.tools.Rect.setup, "tool");
\ No newline at end of file
+registry.register(Rect.setup, "tool");
+
+return Rect;
+});
diff --git a/dojox/drawing/tools/TextBlock.js b/dojox/drawing/tools/TextBlock.js
index e4ee99b..9f37716 100755
--- a/dojox/drawing/tools/TextBlock.js
+++ b/dojox/drawing/tools/TextBlock.js
@@ -1,7 +1,6 @@
-dojo.provide("dojox.drawing.tools.TextBlock");
-dojo.require("dojox.drawing.stencil.Text");
+define(["dojo", "dijit/registry", "../util/oo", "../manager/_registry", "../stencil/Text"],
+function(dojo, dijit, oo, registry, StencilText){
 
-(function(){
 	var conEdit;
 	dojo.addOnLoad(function(){
 		//		In order to use VML in IE, it's necessary to remove the
@@ -10,7 +9,7 @@ dojo.require("dojox.drawing.stencil.Text");
 		//		The solution is to include one in the main document
 		//		that can be appended and removed as necessary:
 		//		<div id="conEdit" contenteditable="true"></div>
-		//
+
 		// console.log("Removing conedit");
 		conEdit = dojo.byId("conEdit");
 		if(!conEdit){
@@ -20,28 +19,18 @@ dojo.require("dojox.drawing.stencil.Text");
 		}
 	});
 	
-	dojox.drawing.tools.TextBlock = dojox.drawing.util.oo.declare(
-		// summary:
-		//		A tool to create text fields on a canvas.
-		// description:
-		//		Extends stencil.Text by adding an HTML layer that
-		//		can be dragged out to a certain size, and accept
-		//		a text entry. Will wrap text to the width of the
-		//		html field.
-		//		When created programmtically, use 'auto' to shrink
-		//		the width to the size of the text. Use line breaks
-		//		( \n ) to create new lines.
-		//
+	var TextBlock = oo.declare(
 		// TODO - disable zoom while showing?
-		//
+
 		// FIXME:
 		//		Handles width: auto, align:middle, etc. but for
 		//		display only, edit is out of whack
-		//
-		dojox.drawing.stencil.Text,
+
+		StencilText,
 		function(options){
-			// summary: constructor
-			//
+			// summary:
+			//		constructor
+
 			if(options.data){
 				var d = options.data;
 				var text = d.text ? this.typesetter(d.text) : d.text;
@@ -53,7 +42,7 @@ dojo.require("dojox.drawing.stencil.Text");
 					w = o.w;
 					h = o.h;
 				}else{
-					//	w = this.style.text.minWidth;
+					// w = this.style.text.minWidth;
 					this._text = "";
 				}
 				
@@ -97,6 +86,17 @@ dojo.require("dojox.drawing.stencil.Text");
 			//console.log("TextBlock:", this.id)
 		},
 		{
+			// summary:
+			//		A tool to create text fields on a canvas.
+			// description:
+			//		Extends stencil.Text by adding an HTML layer that
+			//		can be dragged out to a certain size, and accept
+			//		a text entry. Will wrap text to the width of the
+			//		html field.
+			//		When created programmtically, use 'auto' to shrink
+			//		the width to the size of the text. Use line breaks
+			//		( \n ) to create new lines.
+
 			draws:true,
 			baseRender:false,
 			type:"dojox.drawing.tools.TextBlock",
@@ -108,16 +108,16 @@ dojo.require("dojox.drawing.stencil.Text");
 StencilData: {
 	// summary:
 	//		The data used to create the dojox.gfx Text
-	// 	x: Number
+	// x: Number
 	//		Left point x
-	// 	y: Number
+	// y: Number
 	//		Top point y
-	// 	width: ? Number|String
-	//		Optional width of Text. Not required but reccommended.
+	// width: Number|String?
+	//		Optional width of Text. Not required but recommended.
 	//		for auto-sizing, use 'auto'
-	// 	height: ? Number
+	// height: Number?
 	//		Optional height of Text. If not provided, _lineHeight is used.
-	// 	text: String
+	// text: String
 	//		The string content. If not provided, may auto-delete depending on defaults.
 },
 =====*/
@@ -126,15 +126,13 @@ StencilData: {
 			//		Whether the Stencil is selected when the text field
 			//		is executed or not
 			selectOnExec:true,
-			//
+
 			// showEmpty: Boolean
 			//		If true and there is no text in the data, the TextBlock
 			//		Is displayed and focused and awaits input.
 			showEmpty: false,
 			
 			onDrag: function(/*EventObject*/obj){
-				// summary: See stencil._Base.onDrag
-				//
 				if(!this.parentNode){
 					this.showParent(obj);
 				}
@@ -147,9 +145,6 @@ StencilData: {
 			},
 			
 			onUp: function(/*EventObject*/obj){
-				// summary: See stencil._Base.onUp
-				//
-
 				if(!this._downOnCanvas){ return; }
 				this._downOnCanvas = false;
 				
@@ -169,7 +164,7 @@ StencilData: {
 				// summary:
 				//		Internal. Builds the parent node for the
 				//		contenteditable HTML node.
-				//
+
 				if(this.parentNode){ return; }
 				var x = obj.pageX || 10;
 				var y = obj.pageY || 10;
@@ -201,7 +196,7 @@ StencilData: {
 				// summary:
 				//		Internal. Inserts the contenteditable HTML node
 				//		into its parent node, and styles it.
-				//
+
 				// style parent
 				var d = this.style.textMode.edit;
 				this._box.border = d.width+"px "+d.style+" "+d.color;
@@ -225,7 +220,7 @@ StencilData: {
 				// summary:
 				//		Internal. Creates the connections to the
 				//		contenteditable HTML node.
-				//
+
 				if(this._textConnected){ return; } // good ol' IE and its double events
 				// FIXME:
 				// Ouch-getting greekPalette by id.  At the minimum this should
@@ -281,8 +276,8 @@ StencilData: {
 					if(evt.keyCode==13 || evt.keyCode==27){ // TODO: make escape an option
 						dojo.stopEvent(evt);
 					}
-					//	if backslash, user is inputting a special character
-					//	This gives popup help.
+					// if backslash, user is inputting a special character
+					// This gives popup help.
 					if(evt.keyCode==220){
 						if(!greekHelp){
 							console.info("For greek letter assistance instantiate: dojox.drawing.plugins.drawing.GreekPalette");
@@ -376,7 +371,7 @@ StencilData: {
 				// summary:
 				//		Internal. Method fired when text is executed,
 				//		via mouse-click-off, ESC key or Enter key.
-				//
+
 				var d = dojo.marginBox(this.parentNode);
 				var w = Math.max(d.w, this.style.text.minWidth);
 				
@@ -425,7 +420,7 @@ StencilData: {
 				// summary:
 				//		Internal?
 				//		Method used to instantiate the contenteditable HTML node.
-				//
+
 				this.editMode = true;
 				var text = this.getText() || "";
 				console.log("EDIT TEXT:",text, " ",text.replace("/n", " "));
@@ -456,7 +451,7 @@ StencilData: {
 			cleanText: function(/*String*/txt, /*Boolean*/removeBreaks){
 				// summary:
 				//		Cleans text. Strings HTML chars and double spaces
-				//  	and optionally removes line breaks.
+				//		and optionally removes line breaks.
 				var replaceHtmlCodes = function(str){
 					var chars = {
 						"<":"<",
@@ -489,18 +484,17 @@ StencilData: {
 				//		height of a block of text. This method creates an
 				//		HTML text block and those measurements are used for
 				//		displaying the SVG/VML text.
-				// arguments:
-				//		str: String
-				//			The text to display and measure.
-				//		width: [optional] Number
-				//			If the width is not provided, it will be assumed
-				//			that the text is one line and the width will be
-				//			measured and the _lineHeight used for th height.
-				//			If width is provided, word-wrap is assumed, and
-				//			line breaks will be inserted into the text at each
-				//			point where a word wraps in the HTML. The height is
-				//			then measured.
-				//
+				// str: String
+				//		The text to display and measure.
+				// width: [optional] Number
+				//		If the width is not provided, it will be assumed
+				//		that the text is one line and the width will be
+				//		measured and the _lineHeight used for th height.
+				//		If width is provided, word-wrap is assumed, and
+				//		line breaks will be inserted into the text at each
+				//		point where a word wraps in the HTML. The height is
+				//		then measured.
+
 				var r = "(<br\\s*/*>)|(\\n)|(\\r)";
 				this.showParent({width:width || "auto", height:"auto"});
 				this.createTextField(str);
@@ -558,8 +552,6 @@ StencilData: {
 			
 			_downOnCanvas:false,
 			onDown: function(/*EventObject*/obj){
-				// summary: See stencil._Base.onDown
-				//
 				this._startdrag = {
 					x: obj.pageX,
 					y: obj.pageY
@@ -574,7 +566,7 @@ StencilData: {
 				//		Internal. Creates HTML nodes at each corner
 				//		of the contenteditable div. These nodes are
 				//		draggable and will resize the div horizontally.
-				//
+
 				this._anchors = {};
 				var self = this;
 				var d = this.style.anchors,
@@ -670,7 +662,7 @@ StencilData: {
 				//		Uses saved caret position to insert text
 				//		into position and place caret at the end of
 				//		insertion
-				//
+
 				var t, text = node.innerHTML;
 				var caret = this.getSavedCaret();
 				
@@ -688,10 +680,9 @@ StencilData: {
 				//		in the contentEditable div (conEdit).
 				//		NOTE: Doesn't work with html nodes inside
 				//		the div.
-				//
+
 				var start, end;
 				if(dojo.doc.selection){
-					//debugger;
 					var r = dojo.doc.selection.createRange();
 					var rs = dojo.body().createTextRange();
 					rs.moveToElementText(node);
@@ -713,10 +704,9 @@ StencilData: {
 				//		Used for placing the cursor during edits and character help.
 				//		Takes the values: end, beg, start, all or any numerical value
 				//		(in which case the number will constitute the caret position)
-				//
+
 				console.warn("setSelection:");
 				if(dojo.doc.selection){ // IE
-					//debugger;
 					var rs = dojo.body().createTextRange();
 					rs.moveToElementText(node);
 					
@@ -739,7 +729,7 @@ StencilData: {
 							rs.moveStart("character",this._caretStart);
 							rs.moveEnd("character",dif);
 							break;
-					};
+					}
 					rs.select();
 					
 				}else{
@@ -751,15 +741,15 @@ StencilData: {
 								children.push(n);
 							}else if(n.tagName && n.tagName.toLowerCase()=="img"){
 								children.push(n);
-							};
+							}
 								
 							if(n.childNodes && n.childNodes.length){
 								getAllChildren(n, children);
-							};
+							}
 						}
 						return children;
 					};
-					console.log("ff node:", node)
+					console.log("ff node:", node);
 					node.focus();
 					var selection = dojo.global.getSelection();
 					selection.removeAllRanges();
@@ -790,14 +780,13 @@ StencilData: {
 			}
 		}
 	);
-	
-	dojox.drawing.tools.TextBlock.setup = {
-		// summary: See stencil._Base ToolsSetup
-		//
+	dojo.setObject("dojox.drawing.tools.TextBlock", TextBlock);
+	TextBlock.setup = {
 		name:"dojox.drawing.tools.TextBlock",
 		tooltip:"Text Tool",
 		iconClass:"iconText"
 	};
-	dojox.drawing.register(dojox.drawing.tools.TextBlock.setup, "tool");
-	
-})();
+	registry.register(TextBlock.setup, "tool");
+
+	return TextBlock;
+});
diff --git a/dojox/drawing/tools/custom/Axes.js b/dojox/drawing/tools/custom/Axes.js
index 69b085e..f873b86 100755
--- a/dojox/drawing/tools/custom/Axes.js
+++ b/dojox/drawing/tools/custom/Axes.js
@@ -1,22 +1,14 @@
-dojo.provide("dojox.drawing.tools.custom.Axes");
-dojo.require("dojox.drawing.stencil.Path");
+define(["dojo/_base/lang", "../../util/oo", "../../manager/_registry", "../../stencil/Path",
+	"../../annotations/Arrow", "../../annotations/Label", "../../tools/custom/Vector"],
+function(lang, oo, registry, StencilPath, Arrow, Label, Vector){
 
-
-dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Draws a right-angle Axes (shaped like an L, not a +)
-	// description:
-	//		This Stencil is created with a Path so that the L shape
-	//		is one continuous piece. Arrow heads are placed at the end
-	// 		of each axis. The Axes can be rotated. There are custom
-	// 		label methods.
-	//
-	dojox.drawing.stencil.Path,
+var Axes = oo.declare(
+	StencilPath,
 	function(options){
 		this.closePath = false;
 
-		this.xArrow = new dojox.drawing.annotations.Arrow({stencil:this, idx1:0, idx2:1});
-		this.yArrow = new dojox.drawing.annotations.Arrow({stencil:this, idx1:2, idx2:1});
+		this.xArrow = new Arrow({stencil:this, idx1:0, idx2:1});
+		this.yArrow = new Arrow({stencil:this, idx1:2, idx2:1});
 		if(options.data){
 			//Allows import of z-axis in non-enabled canvas and xy-axis in
 			//enabled canvas
@@ -28,8 +20,8 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 			// there is no switching back and forth for the axis, only for vectors.
 			this.data.cosphi = 1;
 			var ops = {};
-			dojo.mixin(ops,options);
-			dojo.mixin(ops,{
+			lang.mixin(ops,options);
+			lang.mixin(ops,{
 				container:this.container.createGroup(),
 				style: this.style,
 				showAngle: false,
@@ -40,7 +32,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 				ops.data.y2 = ops.data.y4;
 			}
 			ops.style.zAxis = true;
-			this.zAxis = new dojox.drawing.tools.custom.Vector(ops);
+			this.zAxis = new Vector(ops);
 			this.zAxis.minimumSize = 5;
 			//console.log("-----constructing axes: ",this.zAxis);
 			this.connectMult([
@@ -53,7 +45,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 				[this.zAxis, "onBeforeRender", this, "zSet"],
 				[this, "_onPostRender", this.zAxis, "render"]
 			]);
-			
+
 		}
 
 		if(this.points && this.points.length){
@@ -66,6 +58,14 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		}
 	},
 	{
+		// summary:
+		//		Draws a right-angle Axes (shaped like an L, not a +)
+		// description:
+		//		This Stencil is created with a Path so that the L shape
+		//		is one continuous piece. Arrow heads are placed at the end
+		//		of each axis. The Axes can be rotated. There are custom
+		//		label methods.
+
 		draws:true,
 		type:"dojox.drawing.tools.custom.Axes",
 		minimumSize:30,
@@ -73,7 +73,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		closePath:false,
 		baseRender:false,
 		zScale:.5,
-		
+
 		zPoint: function(obj){
 			// summary:
 			//		Finds the point for the z axis.
@@ -81,7 +81,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 			var pt = this.util.pointOnCircle(obj.start.x, obj.start.y, obj.radius*this.zScale, this.style.zAngle);
 			return {x:pt.x, y:pt.y, skip:true, noAnchor:true};
 		},
-		
+
 		zSet: function(){
 			if(!this.zAxis){ return; };
 			var c = this.points[1];
@@ -94,21 +94,21 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 			len > this.zAxis.minimumSize ? this.zAxis.setPoints(p) : false;
 			this.zAxis.cosphi = 1;
 		},
-		
+
 		createLabels: function(){
 			// summary:
 			//		Creates the label for each axis.
-			//
+
 			// NOTE: Not passing style into text because it's changing it
 			var props = {align:"middle", valign:"middle", util:this.util, annotation:true, container:this.container, mouse:this.mouse, stencil:this};
-			this.labelX = new dojox.drawing.annotations.Label(dojo.mixin(props,{
+			this.labelX = new Label(lang.mixin(props,{
 				labelPosition:this.setLabelX
 			}));
-			this.labelY = new dojox.drawing.annotations.Label(dojo.mixin(props,{
+			this.labelY = new Label(lang.mixin(props,{
 				labelPosition:this.setLabelY
 			}));
 			if(this.style.zAxisEnabled){
-				this.labelZ = new dojox.drawing.annotations.Label(dojo.mixin(props,{
+				this.labelZ = new Label(lang.mixin(props,{
 					labelPosition:this.setLabelZ
 				}));
 			}
@@ -118,7 +118,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		setLabelX: function(){
 			// summary:
 			//		Custom placement for x-axis label
-			//
+
 			var ax = this.points[0];
 			var c =  this.points[1];
 
@@ -140,7 +140,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		setLabelY: function(){
 			// summary:
 			//		Custom placement for y-axis label
-			//
+
 			var c =  this.points[1];
 			var ay = this.points[2];
 
@@ -160,10 +160,10 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		setLabelZ: function(){
 			// summary:
 			//		Custom placement for z-axis label
-			//
+
 			var c = this.points[1];
 			var z = this.points[3];
-			
+
 			var dist = 40;
 			var offdist = 20;
 			var pt, px, py, pt2;
@@ -171,7 +171,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 			px = pt.x + (pt.y - z.y);
 			py = pt.y + (z.x - pt.x);
 			pt2 = this.util.lineSub(pt.x, pt.y, px, py, (dist-offdist));
-			
+
 			return {
 				x:pt2.x,
 				y:pt2.y,
@@ -182,13 +182,12 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 			// summary:
 			//		Set the text of the labels. The text would be
 			//		broken up into the two labels.
-			// arguments:
-			//		value: [optional] String
-			//			If no argument is passed, defaults to two labels
-			//			'x' and 'y'. If an argument is passed, that
-			//			text will be split on the word 'and' to determine
-			//			the two labels.
-			//
+			// value: [optional] String
+			//		If no argument is passed, defaults to two labels
+			//		'x' and 'y'. If an argument is passed, that
+			//		text will be split on the word 'and' to determine
+			//		the two labels.
+
 			if(this._labelsCreated){ return; }
 			!this.labelX && this.createLabels();
 			var x = "x";
@@ -224,7 +223,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		getLabel: function(){
 			// summary:
 			//		Getter for the labels. returns an object.
-			//
+
 			if(!this.labelX){ return null; }
 			return {
 				x:this.labelX.getText(),
@@ -237,8 +236,8 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 			// summary:
 			//		Gets called from anchor to check if its current
 			//		position is ok. If not, its x or y transform will
-			// 		be changed until this passes.
-			//
+			//		be changed until this passes.
+
 			var pm = this.container.getParent().getTransform();
 			var am = anchor.shape.getTransform();
 
@@ -259,7 +258,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		onTransformBegin: function(/*manager.Anchor*/anchor){
 			// summary:
 			//		Overwrites _Base.onTransformBegin
-			//
+
 			// called from anchor point up mouse down
 			this._isBeingModified = true;
 		},
@@ -267,12 +266,12 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		onTransformEnd: function(/*manager.Anchor*/anchor){
 			// summary:
 			//		Overwrites _Base.onTransformEnd
-			//
+
 			// Gets called on anchor mouseup
-			//	also gets called by checkBounds - we don't want that.
+			// also gets called by checkBounds - we don't want that.
 			if(!anchor){ return; }
 
-			//	tell anchor to go to prev point if wrong
+			// tell anchor to go to prev point if wrong
 			// called from anchor point up mouse up
 
 			this._isBeingModified = false;
@@ -310,7 +309,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 			}
 
 			// we're outside of the constraint. Set to the low or high.
-			this.points[0].x = pt.x
+			this.points[0].x = pt.x;
 			this.points[0].y = pt.y;
 			o = this.points[0];
 
@@ -338,7 +337,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		getBounds: function(/*Boolean*/absolute){
 			// summary:
 			//		Custom getBounds overwrites _Base.getBounds
-			//
+
 			var px = this.points[0],
 			    pc = this.points[1],
 			    py = this.points[2];
@@ -381,9 +380,9 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 
 		_postSetPoints: function(/*Array*/pts){
 			// summary:
-			// 		Because Axes only has one anchor,
-			// 		we substitute a special setPoints method
-			//
+			//		Because Axes only has one anchor,
+			//		we substitute a special setPoints method
+
 			this.points[0] = pts[0];
 			if(this.pointsToData){
 				this.data = this.pointsToData();
@@ -393,7 +392,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		onTransform: function(/*Number*/anchor){
 			// summary:
 			//		Overwrites _Base.onTransform
-			//
+
 			// the xaxis point has changed - the center will not.
 			// need to find the yaxis point.
 			var o = this.points[0];
@@ -415,7 +414,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		},
 
 		pointsToData: function(){
-			//summary:
+			// summary:
 			//		Converts points to data.
 			var p = this.points;
 			var d = {
@@ -432,11 +431,11 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 				d.cosphi = 1;
 			}
 			return d;
-			
+
 		},
-		
+
 		getRadius: function(){
-			//summary:
+			// summary:
 			//		Possibility of z-axis makes bounds unreliable.
 			//		Use these points instead.
 			var p = this.points;
@@ -445,7 +444,7 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		},
 
 		dataToPoints: function(/* ? Object*/o){
-			//summary:
+			// summary:
 			//		Converts data to points.
 			o = o || this.data;
 			if(o.radius || o.angle){
@@ -483,8 +482,9 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		},
 
 		onDrag: function(/*EventObject*/obj){
-			// summary: See stencil._Base.onDrag
-			//
+			// summary:
+			//		See stencil._Base.onDrag
+
 			var pt = this.util.constrainAngle(obj, 0, 89);
 			obj.x = pt.x;
 			obj.y = pt.y;
@@ -505,8 +505,9 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 		},
 
 		onUp: function(/*EventObject*/obj){
-			// summary: See stencil._Base.onUp
-			//
+			// summary:
+			//		See stencil._Base.onUp
+
 			if(!this._downOnCanvas){ return; }
 			this._downOnCanvas = false;
 			var p = this.points;
@@ -563,11 +564,16 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.tools.custom.Axes.setup = {
-	// summary: See stencil._Base ToolsSetup
-	//
+lang.setObject("dojox.drawing.tools.custom.Axes", Axes);
+Axes.setup = {
+	// summary:
+	//		See stencil._Base ToolsSetup
+
 	name:"dojox.drawing.tools.custom.Axes",
 	tooltip:"Axes Tool",
 	iconClass:"iconAxes"
 };
-dojox.drawing.register(dojox.drawing.tools.custom.Axes.setup, "tool");
\ No newline at end of file
+registry.register(Axes.setup, "tool");
+
+return Axes;
+});
diff --git a/dojox/drawing/tools/custom/Equation.js b/dojox/drawing/tools/custom/Equation.js
index 5cd3a20..0c96590 100644
--- a/dojox/drawing/tools/custom/Equation.js
+++ b/dojox/drawing/tools/custom/Equation.js
@@ -1,12 +1,12 @@
-dojo.provide("dojox.drawing.tools.custom.Equation");
-dojo.require("dojox.drawing.tools.TextBlock");
+define(["dojo/_base/lang", "../../util/oo", "../../manager/_registry", "../TextBlock"],
+function(lang, oo, registry, TextBlock){
 
-dojox.drawing.tools.custom.Equation = dojox.drawing.util.oo.declare(
+var Equation = oo.declare(
 	// summary:
 	//		Essentially the same as the TextBlock tool, but
 	//		allows for a different icon and tooltip title.
-	//
-	dojox.drawing.tools.TextBlock,
+
+	TextBlock,
 	function(options){
 	
 	},
@@ -16,11 +16,16 @@ dojox.drawing.tools.custom.Equation = dojox.drawing.util.oo.declare(
 	
 );
 
-dojox.drawing.tools.custom.Equation.setup = {
-	// summary: See stencil._Base ToolsSetup
-	//
+lang.setObject("dojox.drawing.tools.custom.Equation", Equation);
+Equation.setup = {
+	// summary:
+	//		See stencil._Base ToolsSetup
+
 	name:"dojox.drawing.tools.custom.Equation",
 	tooltip:"Equation Tool",
 	iconClass:"iconEq"
 };
-dojox.drawing.register(dojox.drawing.tools.custom.Equation.setup, "tool");
\ No newline at end of file
+registry.register(Equation.setup, "tool");
+
+return Equation;
+});
diff --git a/dojox/drawing/tools/custom/Vector.js b/dojox/drawing/tools/custom/Vector.js
index 65ab116..68489d4 100755
--- a/dojox/drawing/tools/custom/Vector.js
+++ b/dojox/drawing/tools/custom/Vector.js
@@ -1,22 +1,20 @@
-dojo.provide("dojox.drawing.tools.custom.Vector");
-dojo.require("dojox.drawing.tools.Arrow");
-dojo.require("dojox.drawing.util.positioning");
+define(["dojo", "../../util/oo", "../../manager/_registry", "../../util/positioning", "../Arrow"],
+function(dojo, oo, registry, positioning, Arrow){
 
-dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
-	// summary:
-	//		Creates a Vector Stencil.
-	// description:
-	//		Generally the same as an arrow, except that the arrow
-	//		head is only at the end. There is additionaly functionality
-	//		to allow for a 'zero vector' - one with no length.
-	//
-	//
-	dojox.drawing.tools.Arrow,
+var Vector = oo.declare(
+	Arrow,
 	function(options){
 		this.minimumSize = this.style.arrows.length;
 		this.addShadow({size:3, mult:2});
 	},
 	{
+		// summary:
+		//		Creates a Vector Stencil.
+		// description:
+		//		Generally the same as an arrow, except that the arrow
+		//		head is only at the end. There is additionaly functionality
+		//		to allow for a 'zero vector' - one with no length.
+
 		draws:true,
 		type:"dojox.drawing.tools.custom.Vector",
 		minimumSize:30,
@@ -25,7 +23,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 		
 		
 		changeAxis: function(cosphi){
-			//	summary:
+			// summary:
 			//		Converts a vector to and from the z axis.
 			//		If passed a cosphi value that is used to set
 			//		the axis, otherwise it is the opp of what it is.
@@ -48,7 +46,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 		_createZeroVector: function(shp, d, sty){
 			// summary:
 			//		Special creation function for the zero-vector shape
-			//
+
 			var s = shp=="hit" ? this.minimumSize : this.minimumSize/6;
 			var f = shp=="hit" ? sty.fill : null;
 			d = {
@@ -70,7 +68,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 			//		Creates a dojox.gfx.shape based on passed arguments.
 			//		Can be called many times by implementation to create
 			//		multiple shapes in one stencil.
-			//
+
 			this.remove(this[shp]);
 			this[shp] = this.container.createLine(d)
 				.setStroke(sty);
@@ -78,8 +76,9 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 		},
 		
 		onDrag: function(/*EventObject*/obj){
-			// summary: See stencil._Base.onDrag
-			//
+			// summary:
+			//		See stencil._Base.onDrag
+
 			if(this.created){ return; }
 			
 			var x1 = obj.start.x,
@@ -95,7 +94,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 			
 			if(this.keys.alt){
 				// FIXME:
-				//	should double the length of the line
+				// should double the length of the line
 				// FIXME:
 				//	if alt dragging past ZERO it seems to work
 				//	but select/deselect shows bugs
@@ -122,8 +121,8 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 		
 		onTransform: function(/* ? manager.Anchor */anchor){
 			// summary:
-			// 		Called from anchor point mouse drag
-			// 		also called from plugins.Pan.checkBounds
+			//		Called from anchor point mouse drag
+			//		also called from plugins.Pan.checkBounds
 			if(!this._isBeingModified){
 				this.onTransformBegin();
 			}
@@ -135,7 +134,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 		},
 		
 		anchorConstrain: function(x, y){
-			//	summary:
+			// summary:
 			//		Called from anchor point mouse drag
 			if(!this.style.zAxis){ return null; }
 			var radians = this.style.zAngle*Math.PI/180;
@@ -147,7 +146,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 		},
 		
 		zPoint: function(obj){
-			//	summary:
+			// summary:
 			//		Takes any point and converts it to
 			//		be on the z-axis.
 			if(obj===undefined){
@@ -163,7 +162,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 				};
 			}
 			var radius = this.util.length(obj);
-			var angle = this.util.angle(obj);
+			var angle = positioning.angle(obj.start, obj);
 			angle<0 ? angle = 360 + angle : angle;
 			
 			angle = angle > 135 && angle < 315 ? this.style.zAngle : this.util.oppAngle(this.style.zAngle);
@@ -179,7 +178,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 			var obj = {start:{x:p[0].x, y:p[0].y}, x:p[1].x, y:p[1].y};
 			if(this.style.zAxis && (this.util.length(obj)>this.minimumSize)){
 				
-				var angle = this.util.angle(obj);
+				var angle = positioning.angle(obj.start, obj);
 				angle<0 ? angle = 360 + angle : angle;
 				cosphi = angle > 135 && angle < 315 ? 1 : -1;
 			}
@@ -194,7 +193,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 		},
 		
 		dataToPoints: function(o){
-			//summary:
+			// summary:
 			//		Converts data to points.
 			o = o || this.data;
 			if(o.radius || o.angle){
@@ -229,7 +228,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 			//		hit area and for highlighting) and the'shape' (the actual
 			//		display object). Additionally checks if Vector should be
 			//		drawn as an arrow or a circle (zero-length)
-			//
+
 			this.onBeforeRender(this);
 			if(this.getRadius() >= this.minimumSize){
 				this._create("hit", this.data, this.style.currentHit);
@@ -242,8 +241,9 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 			}
 		},
 		onUp: function(/*EventObject*/obj){
-			// summary: See stencil._Base.onUp
-			//
+			// summary:
+			//		See stencil._Base.onUp
+
 			if(this.created || !this._downOnCanvas){ return; }
 			this._downOnCanvas = false;
 			//Default vector for single click
@@ -281,15 +281,18 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 	
 );
 
-dojox.drawing.tools.custom.Vector.setup = {
-	// summary: See stencil._Base ToolsSetup
-	//
+dojo.setObject("dojox.drawing.tools.custom.Vector", Vector);
+Vector.setup = {
+	// summary:
+	//		See stencil._Base ToolsSetup
+
 	name:"dojox.drawing.tools.custom.Vector",
 	tooltip:"Vector Tool",
 	iconClass:"iconVector"
 };
 
-if(dojox.drawing.defaults.zAxisEnabled){
+//TODO
+if(0 && dojox.drawing.defaults.zAxisEnabled){
 	dojox.drawing.tools.custom.Vector.setup.secondary = {
 		// summary:
 		//		Creates a secondary tool for the Vector Stencil.
@@ -385,4 +388,6 @@ if(dojox.drawing.defaults.zAxisEnabled){
 		}
 	};
 }
-dojox.drawing.register(dojox.drawing.tools.custom.Vector.setup, "tool");
\ No newline at end of file
+registry.register(Vector.setup, "tool");
+return Vector;
+});
diff --git a/dojox/drawing/ui/Button.js b/dojox/drawing/ui/Button.js
index 8b79e65..d208684 100644
--- a/dojox/drawing/ui/Button.js
+++ b/dojox/drawing/ui/Button.js
@@ -1,11 +1,9 @@
-dojo.provide("dojox.drawing.ui.Button");
+define(["dojo", "../util/oo", "../stencil/Rect", "../stencil/Ellipse",
+"../stencil/Text", "../manager/_registry"],
+  function(dojo, oo, Rect, Ellipse, Text, registry){
 
-dojox.drawing.ui.Button =  dojox.drawing.util.oo.declare(
-	// summary:
-	//		Creates a clickable button in "UI" mode of the drawing.
-	// description:
-	//		Creates a 4-state button: normal, hover, active, selected.
-	//		Optionally may include button text or an icon.
+//dojox.drawing.ui.Button = 
+var Button = oo.declare(
 	function(options){
 		options.subShape = true;
 		dojo.mixin(this, options);
@@ -13,7 +11,7 @@ dojox.drawing.ui.Button =  dojox.drawing.util.oo.declare(
 		this.width = options.data.width || options.data.rx*2;
 		this.height = options.data.height || options.data.ry*2;
 		this.y = options.data.y || options.data.cy - options.data.ry;
-		//
+
 		this.id = this.id || this.util.uid(this.type);
 		this.util.attr(this.container, "id", this.id);
 		if(this.callback){
@@ -26,9 +24,9 @@ dojox.drawing.ui.Button =  dojox.drawing.util.oo.declare(
 		options.drawingType="ui";
 		// Choose between rectangle and ellipse based on options
 		if(options.data.width && options.data.height){
-			this.shape = new dojox.drawing.stencil.Rect(options);
+			this.shape = new Rect(options);
 		}else{
-			this.shape = new dojox.drawing.stencil.Ellipse(options);
+			this.shape = new Ellipse(options);
 		}
 		
 		var setGrad = function(s, p, v){
@@ -59,7 +57,7 @@ dojox.drawing.ui.Button =  dojox.drawing.util.oo.declare(
 			o = this.makeOptions(options.text || options.icon.text);
 			o.data.color = this.style.button.icon.norm.color; //= o.data.fill;
 			this.style.button.icon.selected.color = this.style.button.icon.selected.fill;
-			this.icon = new dojox.drawing.stencil.Text(o);
+			this.icon = new Text(o);
 			this.icon.attr({
 				height:	this.icon._lineHeight,
 				y:((this.height-this.icon._lineHeight)/2)+this.y
@@ -74,7 +72,12 @@ dojox.drawing.ui.Button =  dojox.drawing.util.oo.declare(
 		this.onOut();
 		
 	},{
-		
+		// summary:
+		//		Creates a clickable button in "UI" mode of the drawing.
+		// description:
+		//		Creates a 4-state button: normal, hover, active, selected.
+		//		Optionally may include button text or an icon.
+
 		callback:null,
 		scope:null,
 		hitched:null,
@@ -221,6 +224,11 @@ dojox.drawing.ui.Button =  dojox.drawing.util.oo.declare(
 	
 );
 
-dojox.drawing.register({
+dojo.setObject("dojox.drawing.ui.Button", Button);
+
+registry.register({
 	name:"dojox.drawing.ui.Button"
-}, "stencil");
\ No newline at end of file
+}, "stencil");
+
+return Button;
+});
diff --git a/dojox/drawing/ui/Toolbar.js b/dojox/drawing/ui/Toolbar.js
index b2ea79a..35cfb65 100644
--- a/dojox/drawing/ui/Toolbar.js
+++ b/dojox/drawing/ui/Toolbar.js
@@ -1,18 +1,18 @@
-dojo.provide("dojox.drawing.ui.Toolbar");
-dojo.require("dojox.drawing.library.icons");
+define(["dojo", "../library/icons", "../util/common", "../Drawing", "../manager/_registry"], 
+function(dojo, icons, utilCommon, Drawing, registry){
 
-dojo.declare("dojox.drawing.ui.Toolbar", [], {
+return dojo.declare("dojox.drawing.ui.Toolbar", [], {
 	// summary:
 	//		A Toolbar used for holding buttons; typically representing the Stencils
 	//		used for a DojoX Drawing.
 	// description:
-	//		Creates a GFX-based toobar that holds GFX-based buttons. Can be either created
-	//		within the actual drawing or within a seperate DOM element. When within the
+	//		Creates a GFX-based toolbar that holds GFX-based buttons. Can be either created
+	//		within the actual drawing or within a separate DOM element. When within the
 	//		drawing, the toolbar will cover a portion of the drawing; hence the option.
 	//
-	//		A Toolbar can be created programmtically or in markup. Currently markup is as
-	//		a separate DOM element and programmtic is within the drawing.
-	// examples:
+	//		A Toolbar can be created programmatically or in markup. Currently markup is as
+	//		a separate DOM element and programmatic is within the drawing.
+	// example:
 	//		|	dojo.connect(myDrawing, "onSurfaceReady", function(){
 	//		|		new dojox.drawing.ui.Toolbar({
 	//		|			drawing:myDrawing,
@@ -24,11 +24,10 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 	//
 	//		| <div dojoType="dojox.drawing.ui.Toolbar" id="gfxToolbarNode" drawingId="drawingNode"
 	//		|		class="gfxToolbar" tools="all" plugs="all" selected="ellipse" orient="H"></div>
-	//
-	//
+
+
 	constructor: function(props, node){
 		//console.warn("GFX Toolbar:", props, node)
-		this.util = dojox.drawing.util.common;
 		
 		// no mixin. painful.
 		if(props.drawing){
@@ -52,7 +51,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 			this.strTools = dojo.attr(node, "tools");
 			this.strPlugs = dojo.attr(node, "plugs");
 			this._mixprops(["padding", "margin", "size", "radius"], node);
-			this.toolDrawing = new dojox.drawing.Drawing({mode:"ui"}, node);
+			this.toolDrawing = new Drawing({mode:"ui"}, node);
 			this.orient = dojo.attr(node, "orient");
 		}
 		
@@ -65,7 +64,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 			var c = dojo.connect(this.toolDrawing, "onSurfaceReady", this, function(){
 				//console.log("TB built")
 				dojo.disconnect(c);
-				this.drawing = dojox.drawing.getRegistered("drawing", dojo.attr(node, "drawingId")); //
+				this.drawing = registry.getRegistered("drawing", dojo.attr(node, "drawingId"));
 				this.makeButtons();
 				if(!this.strSelected && this.drawing.defaults.clickMode){
 					var c = dojo.connect(this.drawing, "onSurfaceReady", this, function(){
@@ -90,19 +89,21 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 	// radius: Number
 	//		The size of the button's rounded corner
 	radius:3,
-	//
+
 	// toolPlugGap: number
-	//		The distnce between the tool buttons and plug buttons
+	//		The distance between the tool buttons and plug buttons
 	toolPlugGap:20,
 	
-	//	strSlelected | selected: String
+	// strSelected: String
 	//		The button that should be selected at startup.
 	strSelected:"",
-	//	strTools | tools: String
+
+	// strTools: String
 	//		A comma delineated list of the Stencil-tools to include in the Toolbar.
 	//		If "all" is used, all registered tools are included.
 	strTools:"",
-	//	strPlugs | plugs: String
+
+	// strPlugs: String
 	//		A comma delineated list of the plugins to include in the Toolbar.
 	//		If "all" is used, all registered plugins are included.
 	strPlugs:"",
@@ -114,19 +115,19 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 		this.plugins = [];
 	
 		var x = this.padding, y = this.padding, w = this.size, h = this.size, r = this.radius, g = this.margin,
-				 sym = dojox.drawing.library.icons,
+				 sym = icons,
 				 s = {place:"BR", size:2, mult:4};
 				 
 		if(this.strTools){
 			var toolAr = [];
-			var tools = dojox.drawing.getRegistered("tool");
+			var tools = registry.getRegistered("tool");
 			var toolMap = {};
 			for(var nm in tools){
-				var tool = this.util.abbr(nm);
+				var tool = utilCommon.abbr(nm);
 				toolMap[tool] = tools[nm];
 				if(this.strTools=="all"){
 					toolAr.push(tool);
-					var details = dojox.drawing.getRegistered("tool",nm);
+					var details = registry.getRegistered("tool",nm);
 					if(details.secondary){
 						toolAr.push(details.secondary.name);
 					}
@@ -137,7 +138,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 				dojo.forEach(toolTmp, function(tool){
 					tool = dojo.trim(tool);
 					toolAr.push(tool);
-					var details = dojox.drawing.getRegistered("tool",toolMap[tool].name);
+					var details = registry.getRegistered("tool",toolMap[tool].name);
 					if(details.secondary){
 						toolAr.push(details.secondary.name);
 					}
@@ -150,7 +151,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 				var secondary = false;
 				if(t.indexOf("Secondary")>-1){
 					var prim = t.substring(0,t.indexOf("Secondary"));
-					var sec = dojox.drawing.getRegistered("tool",toolMap[prim].name).secondary;
+					var sec = registry.getRegistered("tool",toolMap[prim].name).secondary;
 					var label = sec.label;
 					this[t] = sec.funct;
 					if(sec.setup){ dojo.hitch(this, sec.setup)(); };
@@ -160,7 +161,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 				} else {
 					var btn = this.toolDrawing.addUI("button", {data:{x:x, y:y, width:w, height:h, r:r}, toolType:t, icon:sym[t], shadow:s, scope:this, callback:"onToolClick"});
 				}
-				dojox.drawing.register(btn, "button");
+				registry.register(btn, "button");
 				this.buttons.push(btn);
 				if(this.strSelected==t){
 					btn.select();
@@ -184,10 +185,10 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 		
 		if(this.strPlugs){
 			var plugAr = [];
-			var plugs = dojox.drawing.getRegistered("plugin");
+			var plugs = registry.getRegistered("plugin");
 			var plugMap = {};
 			for(var nm in plugs){
-				var abbr = this.util.abbr(nm);
+				var abbr = utilCommon.abbr(nm);
 				plugMap[abbr] = plugs[nm];
 				if(this.strPlugs=="all"){ plugAr.push(abbr); }
 			}
@@ -201,7 +202,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 				//console.log("   plugin:", p);
 				if(plugMap[p].button != false){
 					var btn = this.toolDrawing.addUI("button", {data:{x:x, y:y, width:w, height:h, r:r}, toolType:t, icon:sym[t], shadow:s, scope:this, callback:"onPlugClick"});
-					dojox.drawing.register(btn, "button");
+					registry.register(btn, "button");
 					this.plugins.push(btn);
 					
 					if(this.horizontal){
@@ -248,7 +249,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 	onToolClick: function(/*Object*/button){
 		// summary:
 		//		Tool click event. May be connected to.
-		//
+
 		if(this.drawing.defaults.clickMode){ this.drawing.mouse.setCursor("crosshair"); }
 		dojo.forEach(this.buttons, function(b){
 			if(b.id==button.id){
@@ -266,7 +267,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 		//		Plugin click event. May be connected to.
 	},
 	
-	_mixprops: function(/*Array*/props, /*Object | Node*/objNode){
+	_mixprops: function(/*Array*/ props, /*Object|Node*/ objNode){
 		// summary:
 		//		Internally used for mixing in props from an object or
 		//		from a dom node.
@@ -277,4 +278,5 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 		}, this);
 	}
 	
-});
\ No newline at end of file
+});
+});
diff --git a/dojox/drawing/ui/Tooltip.js b/dojox/drawing/ui/Tooltip.js
index a565945..f4bd23c 100644
--- a/dojox/drawing/ui/Tooltip.js
+++ b/dojox/drawing/ui/Tooltip.js
@@ -1,21 +1,17 @@
-dojo.provide("dojox.drawing.ui.Tooltip");
-dojo.require("dojox.drawing.plugins._Plugin");
-
-
-(function(){
+define(["dojo", "../util/oo", "../plugins/_Plugin", "../manager/_registry"], 
+function(dojo, oo, Plugin, registry){
 	
-	//	summary:
-	//		Used for UI tooltips. Buttons in the toolbar.
-	// 		This file is not complete.
-	//
 	var master = null;
-	var MasterC = dojox.drawing.util.oo.declare(
-		
-		dojox.drawing.plugins._Plugin,
+	var MasterC = oo.declare(
+		Plugin,
 		function(options){
 			this.createDom();
 		},
 		{
+			// summary:
+			//		Used for UI tooltips. Buttons in the toolbar.
+			//		This file is not complete.
+
 			show: function(button, text){
 				this.domNode.innerHTML = text;
 				
@@ -80,9 +76,9 @@ dojo.require("dojox.drawing.plugins._Plugin");
 		}
 	);
 	
-	dojox.drawing.ui.Tooltip =  dojox.drawing.util.oo.declare(
+	var Tooltip =  oo.declare(
 		
-		dojox.drawing.plugins._Plugin,
+		Plugin,
 		function(options){
 			if(!master){
 				master = new MasterC(options);
@@ -108,8 +104,9 @@ dojo.require("dojox.drawing.plugins._Plugin");
 			}
 		}
 	);
-	
-	dojox.drawing.register({
+	dojo.setObject('dojox.drawing.ui.Tooltip', Tooltip);
+	registry.register({
 		name:"dojox.drawing.ui.Tooltip"
 	}, "stencil");
-})();
\ No newline at end of file
+	return Tooltip;
+});
diff --git a/dojox/drawing/ui/dom/Pan.js b/dojox/drawing/ui/dom/Pan.js
index 773e5a1..b113cf7 100644
--- a/dojox/drawing/ui/dom/Pan.js
+++ b/dojox/drawing/ui/dom/Pan.js
@@ -1,13 +1,13 @@
-dojo.provide("dojox.drawing.ui.dom.Pan");
-dojo.require("dojox.drawing.plugins._Plugin");
+define(["dojo", "../../util/oo", "../../plugins/_Plugin", "../../manager/_registry"], 
+function(dojo, oo, Plugin, registry){
 dojo.deprecated("dojox.drawing.ui.dom.Pan", "It may not even make it to the 1.4 release.", 1.4);
 
-dojox.drawing.ui.dom.Pan = dojox.drawing.util.oo.declare(
+var Pan = oo.declare(
 	// NOTE:
-	//			dojox.drawing.ui.dom.Pan is DEPRECATED.
-	//			This was a temporary DOM solution. Use the non-dom
-	//			tools for Toobar and Plugins.
-	//
+	//		dojox.drawing.ui.dom.Pan is DEPRECATED.
+	//		This was a temporary DOM solution. Use the non-dom
+	//		tools for Toolbar and Plugins.
+
 	// summary:
 	//		A plugin that allows for a scrolling canvas. An action
 	//		tool is added to the toolbar that allows for panning. Holding
@@ -19,8 +19,8 @@ dojox.drawing.ui.dom.Pan = dojox.drawing.util.oo.declare(
 	//		|		<div tool="dojox.drawing.tools.Line" selected="true">Line</div>
 	//		|		<div plugin="dojox.drawing.ui.dom.Pan" options="{}">Pan</div>
 	//		|	</div>
-	//
-	dojox.drawing.plugins._Plugin,
+
+	Plugin,
 	function(options){
 		
 		this.domNode = options.node;
@@ -59,7 +59,7 @@ dojox.drawing.ui.dom.Pan = dojox.drawing.util.oo.declare(
 			}
 		},
 		
-		onSetPan: function(/*Boolean | Event*/ bool){
+		onSetPan: function(/*Boolean|Event*/ bool){
 			if(bool === true || bool === false){
 				this.selected = !bool;
 			}
@@ -93,17 +93,16 @@ dojox.drawing.ui.dom.Pan = dojox.drawing.util.oo.declare(
 		},
 		
 		checkBounds: function(){
-			
-			//watch("CHECK BOUNDS DISABLED", true); return;
-			
-			
 			// summary:
 			//		Scans all items on the canvas and checks if they are out of
-			// 		bounds. If so, a scroll bar (in Canvas) is shown. If the position
-			// 		is left or top, the canvas is scrolled all items are relocated
-			// 		the distance of the scroll. Ideally, it should look as if the
-			// 		items do not move.
-			
+			//		bounds. If so, a scroll bar (in Canvas) is shown. If the position
+			//		is left or top, the canvas is scrolled all items are relocated
+			//		the distance of the scroll. Ideally, it should look as if the
+			//		items do not move.
+
+			//watch("CHECK BOUNDS DISABLED", true); return;
+
+
 			// logging stuff here so it can be turned on and off. This method is
 			// very high maintenance.
 			var log = function(){
@@ -200,10 +199,14 @@ dojox.drawing.ui.dom.Pan = dojox.drawing.util.oo.declare(
 	}
 );
 
-dojox.drawing.ui.dom.Pan.setup = {
+dojo.setObject("dojox.drawing.ui.dom.Pan", Pan);
+Pan.setup = {
 	name:"dojox.drawing.ui.dom.Pan",
 	tooltip:"Pan Tool",
 	iconClass:"iconPan"
 };
 
-dojox.drawing.register(dojox.drawing.ui.dom.Pan.setup, "plugin");
\ No newline at end of file
+registry.register(Pan.setup, "plugin");
+
+return Pan;
+});
diff --git a/dojox/drawing/ui/dom/Toolbar.js b/dojox/drawing/ui/dom/Toolbar.js
index 8331619..f22128b 100644
--- a/dojox/drawing/ui/dom/Toolbar.js
+++ b/dojox/drawing/ui/dom/Toolbar.js
@@ -1,27 +1,25 @@
-dojo.provide("dojox.drawing.ui.dom.Toolbar");
+define(["dojo", "../../util/common"], function(dojo, commonUtil){
 dojo.deprecated("dojox.drawing.ui.dom.Toolbar", "It may not even make it to the 1.4 release.", 1.4);
 
-(function(){
-	
-	dojo.declare("dojox.drawing.ui.dom.Toolbar", [], {
+return dojo.declare("dojox.drawing.ui.dom.Toolbar", [], {
 		// NOTE:
-		//			dojox.drawing.Toolbar is DEPRECATED.
-		//			The intention never was to use HTML as buttons for a Drawing.
-		//			This was implemented in order to finish the project for which
-		//			Drawing was developed.
-		//			Instead use: drawing/ui/Toolbar.js
-		//
+		//		dojox.drawing.Toolbar is DEPRECATED.
+		//		The intention never was to use HTML as buttons for a Drawing.
+		//		This was implemented in order to finish the project for which
+		//		Drawing was developed.
+		//		Instead use: drawing/ui/Toolbar.js
+
 		// summary:
-		//	Creates a Toolbar to be used with a DojoX Drawing.
+		//		Creates a Toolbar to be used with a DojoX Drawing.
 		// description:
-		//	Currently works in markup only. A class is required with
-		//	either horizontal or vertical as a class (IE prevented using
-		//	either as a default). Assign an attribute of 'drawingId' with
-		//	the id of the DojoX Drawing to which this is assigned.
-		//	The node children will be assigned as the Tools in the toolbar.
-		//	Plugins can also be assigned.
-		//	The Toolbar is largely self contained and has no real public
-		//	methods or events. the Drawing object should be used.
+		//		Currently works in markup only. A class is required with
+		//		either horizontal or vertical as a class (IE prevented using
+		//		either as a default). Assign an attribute of 'drawingId' with
+		//		the id of the DojoX Drawing to which this is assigned.
+		//		The node children will be assigned as the Tools in the toolbar.
+		//		Plugins can also be assigned.
+		//		The Toolbar is largely self contained and has no real public
+		//		methods or events. the Drawing object should be used.
 		//
 		// example:
 		//	|	<div dojoType="dojox.drawing.Toolbar" drawingId="drawing" class="drawingToolbar vertical">
@@ -29,21 +27,23 @@ dojo.deprecated("dojox.drawing.ui.dom.Toolbar", "It may not even make it to the
 		//	|		<div tool="dojox.drawing.tools.Rect" 				selected="true">	Rect</div>
 		//	|		<div plugin="dojox.drawing.plugins.tools.Zoom" options="{zoomInc:.1,minZoom:.5,maxZoom:2}">Zoom</div>
 		//	|	</div>
-		//
+
 		// TODO: Toolbar works in markup only. Need programmatic.
 		// NOTE: There are plans to make the toolbar out of dojox.gfx vectors.
 		//		 This may change the APIs in the future.
-		//
-		//	baseClass:String
+
+		// baseClass:String
 		//		The CSS style to apply to the toolbar node
 		baseClass:"drawingToolbar",
-		//	buttonClass:String
+
+		// buttonClass:String
 		//		The CSS style to apply to each button node
 		buttonClass:"drawingButton",
-		//	iconClass:String
+
+		// iconClass:String
 		//		The CSS style to apply to each button icon node
 		iconClass:"icon",
-		//
+
 		constructor: function(props, node){
 			// props is null from markup
 			dojo.addOnLoad(this, function(){
@@ -53,18 +53,17 @@ dojo.deprecated("dojox.drawing.ui.dom.Toolbar", "It may not even make it to the
 			});
 		},
 		
-		createIcon: function(/*HTMLNode*/node, /* ? Function*/constr){
+		createIcon: function(/*HTMLNode*/node, /*Function?*/constr){
 			// summary:
-			//	Internal. Creates an icon node for each button.
-			// arguments:
-			//	node: HTMLNode
+			//		Internal. Creates an icon node for each button.
+			// node:
 			//		The button node.
-			//	constr: [optional] Function
+			// constr:
 			//		Optional. If not supplied, an icon is not created.
 			//		Information for each icon is derived from
 			//		the ToolsSetup object defined at the end
 			//		of each tool. See: stencil._Base
-			//
+
 			var setup = constr && constr.setup ? constr.setup : {};
 			if(setup.iconClass){
 				var icon = setup.iconClass ? setup.iconClass : "iconNone";
@@ -96,13 +95,12 @@ dojo.deprecated("dojox.drawing.ui.dom.Toolbar", "It may not even make it to the
 		
 		createTool: function(/*HTMLNode*/node){
 			// summary:
-			//	Creates a button on the Toolbar that is
-			//  a Tool, not a Plugin. Tools draw Stencils,
-			//	Plugins do actions.
-			// arguments:
-			//	node: HTMLNode
+			//		Creates a button on the Toolbar that is
+			//		a Tool, not a Plugin. Tools draw Stencils,
+			//		Plugins do actions.
+			// node: HTMLNode
 			//		The button node.
-			//
+
 			node.innerHTML = "";
 			var type = dojo.attr(node, "tool");
 			this.toolNodes[type] = node;
@@ -134,15 +132,18 @@ dojo.deprecated("dojox.drawing.ui.dom.Toolbar", "It may not even make it to the
 		
 		parse: function(){
 			// summary:
-			//	Initializing method that reads the dom node and its
-			//	children for tools and plugins.
-			//
+			//		Initializing method that reads the dom node and its
+			//		children for tools and plugins.
+
 			var drawingId = dojo.attr(this.domNode, "drawingId");
-			this.drawing = dojox.drawing.util.common.byId(drawingId);
+			this.drawing = commonUtil.byId(drawingId);
 			!this.drawing && console.error("Drawing not found based on 'drawingId' in Toolbar. ");
 			this.toolNodes = {};
 			var _sel;
-			dojo.query(">", this.domNode).forEach(function(node, i){
+			dojo.forEach(this.domNode.childNodes, function(node, i){
+				if(node.nodeType!==1){
+					return;
+				}
 				node.className = this.buttonClass;
 				var tool = dojo.attr(node, "tool");
 				var action = dojo.attr(node, "action");
@@ -154,10 +155,6 @@ dojo.deprecated("dojox.drawing.ui.dom.Toolbar", "It may not even make it to the
 					this.createTool(node);
 					
 				}else if(plugin){
-					
-					
-					
-					
 					var p = {name:plugin, options:{}},
 						opt = dojo.attr(node, "options");
 					if(opt){
@@ -165,12 +162,7 @@ dojo.deprecated("dojox.drawing.ui.dom.Toolbar", "It may not even make it to the
 					}
 					p.options.node = node;
 					node.innerHTML = "";
-			this.drawing.addPlugin(p);
-					
-					
-					
-					
-					
+					this.drawing.addPlugin(p);
 					this.createIcon(node, dojo.getObject(dojo.attr(node, "plugin")));
 				}
 				
@@ -181,17 +173,16 @@ dojo.deprecated("dojox.drawing.ui.dom.Toolbar", "It may not even make it to the
 		},
 		onClick: function(/*String*/type){
 			// summary:
-			//	Event fired from clicking a Tool, not a PLugin.
-			//	Plugin clicks are handled within the plugin's class.
-			// arguments:
-			//	type: Fully qualified name of class. ex:
-			//			dojox.drawing.tools.Ellipse
-			//
+			//		Event fired from clicking a Tool, not a PLugin.
+			//		Plugin clicks are handled within the plugin's class.
+			// type:
+			//		Fully qualified name of class. ex: dojox.drawing.tools.Ellipse
+
 			this.drawing.setTool(type);
 		},
 		onSetTool: function(/*String*/type){
 			// summary:
-			// handles buttons clicks and selects or deselects
+			//		handles buttons clicks and selects or deselects
 			for(var n in this.toolNodes){
 				if(n == type){
 					dojo.addClass(this.toolNodes[type], "selected");
@@ -204,4 +195,4 @@ dojo.deprecated("dojox.drawing.ui.dom.Toolbar", "It may not even make it to the
 		}
 	});
 	
-})();
\ No newline at end of file
+});
diff --git a/dojox/drawing/ui/dom/Zoom.js b/dojox/drawing/ui/dom/Zoom.js
index 1a64272..189a253 100644
--- a/dojox/drawing/ui/dom/Zoom.js
+++ b/dojox/drawing/ui/dom/Zoom.js
@@ -1,12 +1,12 @@
-dojo.provide("dojox.drawing.ui.dom.Zoom");
-dojo.require("dojox.drawing.plugins._Plugin");
+define(["dojo", "../../util/oo", "../../plugins/_Plugin"], 
+function(dojo, oo, Plugin){
 
-dojox.drawing.ui.dom.Zoom = dojox.drawing.util.oo.declare(
+var Zoom = oo.declare(
 	// NOTE:
-	//			dojox.drawing.ui.dom.Zoom is DEPRECATED.
-	//			This was a temporary DOM solution. Use the non-dom
-	//			tools for Toobar and Plugins.
-	//
+	//		dojox.drawing.ui.dom.Zoom is DEPRECATED.
+	//		This was a temporary DOM solution. Use the non-dom
+	//		tools for Toolbar and Plugins.
+
 	// summary:
 	//		A plugin that allows for zooming the canvas in and out. An
 	//		action-tool is added to the toolbar with plus, minus and 100%
@@ -16,8 +16,8 @@ dojox.drawing.ui.dom.Zoom = dojox.drawing.util.oo.declare(
 	//		|		<div tool="dojox.drawing.tools.Line" selected="true">Line</div>
 	//		|		<div plugin="dojox.drawing.ui.dom.Zoom" options="{zoomInc:.1,minZoom:.5,maxZoom:2}">Zoom</div>
 	//		|	</div>
-	//
-	dojox.drawing.plugins._Plugin,
+
+	Plugin,
 	function(options){
 		var cls = options.node.className;
 		var txt = options.node.innerHTML;
@@ -30,43 +30,43 @@ dojox.drawing.ui.dom.Zoom = dojox.drawing.util.oo.declare(
 	},
 	{
 		type:"dojox.drawing.ui.dom.Zoom",
-		//
-		// 	zoomInc: Float
+
+		// zoomInc: Float
 		//		The amount of zoom that will occur upon each click.
 		zoomInc:.1,
-		//
-		//	maxZoom: Number
+
+		// maxZoom: Number
 		//		The maximum the canvas can be zoomed in. 10 = 1000%
 		maxZoom:10,
-		//
-		//	minZoom: Float
+
+		// minZoom: Float
 		//		The most the canvas can be zoomed out. .1 = 10%
 		minZoom:.1,
-		//
-		//	zoomFactor: [readonly] Float
+
+		// zoomFactor: [readonly] Float
 		//		The current zoom amount
 		zoomFactor:1,
-		//
-		//	baseClass: String
+
+		// baseClass: String
 		//		The CSS class added to the Toolbar buttons
 		baseClass:"drawingButton",
-		//
-		//	topClass: String
+
+		// topClass: String
 		//		The CSS class added to the top (or left) Toolbar button
 		topClass:"toolComboTop",
-		//
-		//	midClass: String
+
+		// midClass: String
 		//		The CSS class added to the middle Toolbar button
 		midClass:"toolComboMid",
-		//
-		//	botClass: String
+
+		// botClass: String
 		//		The CSS class added to the bottom (or right) Toolbar button
 		botClass:"toolComboBot",
-		//
+
 		makeButton: function(name, cls){
 			// summary:
 			//		Internal. Creates one of the buttons in the zoom-button set.
-			//
+
 			var node = dojo.create("div", {id:"btn"+name, "class":this.baseClass+" "+cls,
 				innerHTML:'<div title="Zoom In" class="icon icon'+name+'"></div>'}, this.domNode);
 			
@@ -98,7 +98,7 @@ dojox.drawing.ui.dom.Zoom = dojox.drawing.util.oo.declare(
 		onZoomIn: function(/*Mouse Event*/evt){
 			// summary:
 			//		Handles zoom in.
-			//
+
 			this.zoomFactor += this.zoomInc;
 			this.zoomFactor = Math.min(this.zoomFactor, this.maxZoom);
 			this.canvas.setZoom(this.zoomFactor);
@@ -107,7 +107,7 @@ dojox.drawing.ui.dom.Zoom = dojox.drawing.util.oo.declare(
 		onZoom100: function(/*Mouse Event*/evt){
 			// summary:
 			//		Zooms to 100%
-			//
+
 			this.zoomFactor = 1;
 			this.canvas.setZoom(this.zoomFactor);
 			this.mouse.setZoom(this.zoomFactor);
@@ -115,7 +115,7 @@ dojox.drawing.ui.dom.Zoom = dojox.drawing.util.oo.declare(
 		onZoomOut: function(/*Mouse Event*/evt){
 			// summary:
 			//		Handles zoom out.
-			//
+
 			this.zoomFactor -= this.zoomInc;
 			this.zoomFactor = Math.max(this.zoomFactor, this.minZoom);
 			this.canvas.setZoom(this.zoomFactor);
@@ -124,6 +124,8 @@ dojox.drawing.ui.dom.Zoom = dojox.drawing.util.oo.declare(
 	}
 );
 
-
+dojo.setObject("dojox.drawing.ui.dom.Zoom", Zoom);
 //dojox.drawing.register(dojox.drawing.plugins.tools.Pan, "plugin");
 
+return Zoom;
+});
diff --git a/dojox/drawing/util/common.js b/dojox/drawing/util/common.js
index 30706c3..b94ccd3 100755
--- a/dojox/drawing/util/common.js
+++ b/dojox/drawing/util/common.js
@@ -1,16 +1,14 @@
-dojo.provide("dojox.drawing.util.common");
-dojo.require("dojox.math.round");
+define(["dojo", "dojox/math/round"], function(dojo, round){
 
-(function(){
-	
 	var uidMap = {};
 	var start = 0;
-	dojox.drawing.util.common	= {
+	//dojox.drawing.util.common	= 
+	return {
 		// summary:
 		//		A collection of common methods used for DojoX Drawing.
 		//		This singleton is accessible in most Drawing classes
 		//		as this.util
-		//
+
 		// NOTE:
 		//		A lot of functions use a EventObject
 		//		as an argument. An attempt was made to accept
@@ -27,37 +25,36 @@ dojo.require("dojox.math.round");
 		//				x: Number,		// end x
 		//				y:Number		// end y
 		//			}
-		//
-		//
-		radToDeg: function(/*Numer*/n){
+
+
+		radToDeg: function(/*Number*/n){
 			// summary:
 			//		Convert the passed number to degrees.
 			return (n*180)/Math.PI;	//	Number
 		},
 		
-		degToRad: function(/*Numer*/n){
+		degToRad: function(/*Number*/n){
 			// summary:
 			//		Convert the passed number to radians.
 			return (n*Math.PI)/180;	// Number
 		},
 		
-		angle: function(/*EventObject*/obj, /* ? Float */snap){
+		angle: function(/*EventObject*/obj, /*Float?*/snap){
 			// summary:
 			//		Return angle based on mouse object
-			// arguments:
-			//		obj: EventObject
-			//			Manager.Mouse event.
-			// 		snap: Float
-			//			Returns nearest angle within snap limits
-			//
+			// obj:
+			//		Manager.Mouse event.
+			// snap:
+			//		Returns nearest angle within snap limits
+
 			//obj = this.argsToObj.apply(this, arguments);
 			if(snap){
 				snap = snap/180;
 				var radians = this.radians(obj),
 					seg = Math.PI * snap,
-					rnd = dojox.math.round(radians/seg),
+					rnd = round(radians/seg),
 					new_radian = rnd*seg;
-				return dojox.math.round(this.radToDeg(new_radian)); // Whole Number
+				return round(this.radToDeg(new_radian)); // Whole Number
 			
 			}else{
 				return this.radToDeg(this.radians(obj)); // Float
@@ -73,7 +70,7 @@ dojo.require("dojox.math.round");
 			// summary:
 			//		Return the radians derived from the coordinates
 			//		in the Mouse object.
-			//
+
 			//var o = this.argsToObj.apply(this, arguments);
 			return Math.atan2(o.start.y-o.y,o.x-o.start.x);
 		},
@@ -82,7 +79,7 @@ dojo.require("dojox.math.round");
 			// summary:
 			//		Return the length derived from the coordinates
 			//		in the Mouse object.
-			//
+
 			return Math.sqrt(Math.pow(o.start.x-o.x, 2)+Math.pow(o.start.y-o.y, 2));
 		},
 		
@@ -92,7 +89,7 @@ dojo.require("dojox.math.round");
 			// description:
 			//		x1,y1,x2,y2 represents the Line. 'amt' represents the amount
 			//		to subtract from it.
-			//
+
 			var len = this.distance(this.argsToObj.apply(this, arguments));
 			len = len < amt ? amt : len;
 			var pc = (len-amt)/len;
@@ -106,7 +103,7 @@ dojo.require("dojox.math.round");
 			//		Attempts to determine in a Mouse Object
 			//		was passed or indiviual numbers. Returns
 			//		an object.
-			//
+
 			var a = arguments;
 			if(a.length < 4){ return a[0]; }
 			return {
@@ -125,7 +122,7 @@ dojo.require("dojox.math.round");
 			//		Return the length derived from the coordinates
 			//		in the Mouse object. Different from util.length
 			//		in that this always returns an absolute value.
-			//
+
 			var o = this.argsToObj.apply(this, arguments);
 			return Math.abs(Math.sqrt(Math.pow(o.start.x-o.x, 2)+Math.pow(o.start.y-o.y, 2))); // Number
 		},
@@ -142,7 +139,7 @@ dojo.require("dojox.math.round");
 			//		A *very* helpful method. If you know the center
 			//		(or starting) point, length and angle, find the
 			//		x,y point at the end of that line.
-			//
+
 			var radians =  angle * Math.PI / 180.0;
 			var x = radius * Math.cos(radians);
 			var y = radius * Math.sin(radians);
@@ -157,7 +154,7 @@ dojo.require("dojox.math.round");
 			//		Ensures the angle in the Mouse Object is within the
 			//		min and max limits. If not one of those limits is used.
 			//		Returns an x,y point for the angle used.
-			//
+
 			var angle = this.angle(obj);
 			if(angle >= min && angle <= max){
 				return obj;	 // Object
@@ -167,16 +164,17 @@ dojo.require("dojox.math.round");
 			return this.pointOnCircle(obj.start.x,obj.start.y,radius, new_angle); // Object
 		},
 		
-		snapAngle: function(/*EventObject*/obj, /*Float*/ca){
+		snapAngle: function(/*EventObject*/ obj, /*Float*/ ca){
 			// summary:
 			//		Snaps a line to the nearest angle
-			//			obj: Mouse object (see dojox.drawing.Mouse)
-			//			ca: Fractional amount to snap to
-			//				A decimal number fraction of a half circle
-			//				.5 would snap to 90 degrees
-			//				.25  would snap to 45 degrees
-			//				.125 would snap to 22.5 degrees, etc.
+			// obj: Mouse object (see dojox.drawing.Mouse)
+			// ca: Fractional amount to snap to
+			//		A decimal number fraction of a half circle.
 			//
+			//		- .5 would snap to 90 degrees
+			//		- .25  would snap to 45 degrees
+			//		- .125 would snap to 22.5 degrees, etc.
+
 			var radians = this.radians(obj),
 				radius = this.length(obj),
 				seg = Math.PI * ca,
@@ -192,14 +190,13 @@ dojo.require("dojox.math.round");
 			start=num;
 		},
 		
-		uid: function(/* ? String */str){
+		uid: function(/*String?*/ str){
 			// summary:
 			//		Creates a unique ID.
-			// arguments:
-			//		str: String
-			//			If provided, kept in a map, incremented
-			//			and used in the id. Otherwise 'shape' is used.
-			//
+			// str: String
+			//		If provided, kept in a map, incremented
+			//		and used in the id. Otherwise 'shape' is used.
+
 			str = str || "shape";
 			uidMap[str] = uidMap[str]===undefined ? start : uidMap[str] + 1;
 			return str + uidMap[str]; // String
@@ -230,13 +227,13 @@ dojo.require("dojox.math.round");
 		byId: function(/*String*/id){
 			// summary:
 			//		Get an object that was registered with util.register
-			//
+
 			return this.objects[id];
 		},
 		attr: function(/* Object */ elem, /* property */ prop, /* ? value */ value, squelchErrors){
 			// summary:
 			//		Helper function to attach attributes to SVG and VML raw nodes.
-			//
+
 			
 			if(!elem){ return false; }
 			try{
@@ -250,10 +247,10 @@ dojo.require("dojox.math.round");
 				if(!value && prop=="id" && elem.target){
 			
 					var n = elem.target;
-					while(!dojo.attr(n, "id")){
+					while(n && !dojo.attr(n, "id")){
 						n = n.parentNode;
 					}
-					return dojo.attr(n, "id");
+					return n && dojo.attr(n, "id");
 				}
 				
 				if(elem.rawNode || elem.target){
@@ -277,4 +274,4 @@ dojo.require("dojox.math.round");
 		}
 	};
 	
-})();
\ No newline at end of file
+});
diff --git a/dojox/drawing/util/oo.js b/dojox/drawing/util/oo.js
index c0303b9..675d83a 100755
--- a/dojox/drawing/util/oo.js
+++ b/dojox/drawing/util/oo.js
@@ -1,9 +1,8 @@
-dojo.provide("dojox.drawing.util.oo");
-
+define([], function(){
 // TODO:
 // allow a declare without a mixin
 
-dojox.drawing.util.oo = {
+return {
 	// summary:
 	//		Inheritance utilities used in DojoX Drawing
 	// description:
@@ -11,33 +10,33 @@ dojox.drawing.util.oo = {
 	//		There were designed in a effort to make Drawing as
 	//		fast as possible - especially in a case where thousands
 	//		of objects are being loaded. Drawing declare performs
-	//		about 3 times faster than Dojo declare and 2 times
+	//		about 3 times faster than declare and 2 times
 	//		faster than Dojox declare. This is not to say Drawing
-	//		declare is wthout limitations. It doesn't have the same
-	//		syntatic sugar and extensibility of the other two. You
-	//		can't inhert methods. It won't work with Dijit. But it
+	//		declare is without limitations. It doesn't have the same
+	//		syntactic sugar and extensibility of the other two. You
+	//		can't inherit methods. It won't work with Dijit. But it
 	//		is simple and effective.
-	//
+
 	declare: function(){
 		// summary:
 		//		Creates a constructor Function from a
 		//		Function, and collection of methods, and
 		//		more Functions that are extended.
 		// description:
-		//		Similar in look and feel to Dojo declare as
+		//		Similar in look and feel to declare as
 		//		far as order and number of arguments, although
 		//		constructed a little closer to prototypical
 		//		inheritance. All arguments passed into the
 		//		constructor are passed into all sub constructors.
-		// arguments:
-		//		Function, [Object|Function....]
-		//			The first argument is always the base
-		//			constructor. The last argument is always
-		//			an object of methods (or empty object) to
-		//			be mixed in (in the future would like to
-		//			make that object optional). Remaining
-		//			arguments are other constructors mixed in
-		//			using extend() (See below).
+		//
+		//		Arguments are: Function, [Object|Function....]
+		//		The first argument is always the base
+		//		constructor. The last argument is always
+		//		an object of methods (or empty object) to
+		//		be mixed in (in the future would like to
+		//		make that object optional). Remaining
+		//		arguments are other constructors mixed in
+		//		using extend() (See below).
 		// example:
 		//		|	MyFunction = dojox.drawing.util.oo.declare(
 		//		|		MyOtherFunction,
@@ -55,7 +54,7 @@ dojox.drawing.util.oo = {
 		//		|	);
 		//		|
 		//		|	var f = new MyFunction();
-		//
+
 		var f, o, ext=0, a = arguments;
 				
 		if(a.length<2){ console.error("drawing.util.oo.declare; not enough arguments")}
@@ -85,19 +84,18 @@ dojox.drawing.util.oo = {
 		//		part of declare(). Could be used by itself
 		//		however, to mix together two or more
 		//		constructors.
-		// arguments:
-		//		Function, [ Function...]
-		//			Any number of arguments, all must be
-		//			function constructors. The first is
-		//			considered the base object and its
-		//			constructor will fire first.
+		//
+		//		Any number of arguments, all must be
+		//		function constructors. The first is
+		//		considered the base object and its
+		//		constructor will fire first.
 		// example:
 		//		|	var A = function(){};
 		//		|	var B = function(){};
 		//		|	var C = function(){};
-		// 		|	var D = dojox.drawing.util.oo.extend(A, B, C);
+		//		|	var D = dojox.drawing.util.oo.extend(A, B, C);
 		//		|	var e = new D();
-		//
+
 		var a = arguments, sub = a[0];
 		if(a.length<2){ console.error("drawing.util.oo.extend; not enough arguments")}
 		var f = function (){
@@ -107,7 +105,7 @@ dojox.drawing.util.oo = {
 			// sub should fire last
 			sub.prototype.constructor.apply(this, arguments);
 			
-		}
+		};
 		for(var i=1;i<a.length;i++){
 			for(var n in a[i].prototype){
 				f.prototype[n] = a[i].prototype[n];
@@ -119,4 +117,5 @@ dojox.drawing.util.oo = {
 		}
 		return f; // Function
 	}
-};
\ No newline at end of file
+};
+});
diff --git a/dojox/drawing/util/positioning.js b/dojox/drawing/util/positioning.js
index 72a8425..6992db8 100755
--- a/dojox/drawing/util/positioning.js
+++ b/dojox/drawing/util/positioning.js
@@ -1,12 +1,10 @@
-dojo.provide("dojox.drawing.util.positioning");
-
-(function(){
+define(['./common'], function(common){
 	
 	var textOffset = 4;  // distance from line to text box
 	var textYOffset = 20;  // height of text box
 	
-	
-	dojox.drawing.util.positioning.label = function(/*Object*/start, /*Object*/end){
+	var positioning = {};
+	positioning.label = function(/*Object*/start, /*Object*/end){
 		// summary:
 		//		Returns the optimal text positions for annotations.Label.
 		
@@ -15,7 +13,7 @@ dojo.provide("dojox.drawing.util.positioning");
 		var y = 0.5*(start.y+end.y);
 		
 		// move label a set distance from the line
-		var slope = dojox.drawing.util.common.slope(start, end);
+		var slope = common.slope(start, end);
 		var deltay = textOffset/Math.sqrt(1.0+slope*slope);
 		
 		if(end.y>start.y && end.x>start.x || end.y<start.y && end.x<start.x){
@@ -34,15 +32,16 @@ dojo.provide("dojox.drawing.util.positioning");
 		return { x:x, y:y, foo:"bar", align:align}; // Object
 	};
 	
-	dojox.drawing.util.positioning.angle = function(/*Object*/start, /*Object*/end){
+	positioning.angle = function(/*Object*/start, /*Object*/end){
 		// summary:
 		//		Returns the optimal position for annotations.Angle.
-		//
+
 		// angle at first third of vector
-	        var x = 0.7*start.x+0.3*end.x;
-	        var y = 0.7*start.y+0.3*end.y;
+		var x = 0.7*start.x+0.3*end.x;
+		var y = 0.7*start.y+0.3*end.y;
+
 		// move label a set distance from the line
-		var slope = dojox.drawing.util.common.slope(start, end);
+		var slope = common.slope(start, end);
 		var deltay = textOffset/Math.sqrt(1.0+slope*slope);
 		
 		if(end.x<start.x){deltay = -deltay;}
@@ -56,9 +55,8 @@ dojo.provide("dojox.drawing.util.positioning");
 	        y += end.x > start.x ? 0.5*textYOffset :  -0.5*textYOffset;
 		
 		return { x:x, y:y, align:align}; // Object
-	}
+	};
 	
-})();
-
-
+	return positioning;
+});
 
diff --git a/dojox/drawing/util/typeset.js b/dojox/drawing/util/typeset.js
index c1bd6e2..8bc812a 100644
--- a/dojox/drawing/util/typeset.js
+++ b/dojox/drawing/util/typeset.js
@@ -1,19 +1,15 @@
-dojo.provide("dojox.drawing.util.typeset");
-dojo.require("dojox.drawing.library.greek");
-// Summary:
+define(["../library/greek"], function(greeks){
+// summary:
 //		Singleton used for converting characters and typsetting.  Required by _base.
-//
-// Description:
+// description:
 //		Eventually, this is supposed to turn input strings of mathematical
 //		expressions into typeset expressions that can be displayed on the
 //		canvas.  For now, we just generate Greek letters based on LaTeX style
 //		entity codes.
 
-(function(){
 	
-	var greeks = dojox.drawing.library.greek;
-	
-	dojox.drawing.util.typeset = {
+	//dojox.drawing.util.typeset = 
+	return {
 
 		convertHTML: function(inText){
 			if(inText){
@@ -64,4 +60,4 @@ dojo.require("dojox.drawing.library.greek");
 
 	};
 
-})();
+});
diff --git a/dojox/dtl.js b/dojox/dtl.js
index d58d4cc..cdedbad 100644
--- a/dojox/dtl.js
+++ b/dojox/dtl.js
@@ -1,3 +1,10 @@
 define(["./dtl/_base"], function(dxdtl){
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/dtl modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
 	return dxdtl;
 });
\ No newline at end of file
diff --git a/dojox/dtl/Context.js b/dojox/dtl/Context.js
index 88a27c3..e9f9ff3 100644
--- a/dojox/dtl/Context.js
+++ b/dojox/dtl/Context.js
@@ -2,23 +2,16 @@ define([
 	"dojo/_base/lang",
 	"./_base"
 ], function(lang,dd){
-	/*=====
-		dd = dojox.dtl;
-	=====*/
-	
-	/*=====
-	 dd.Context = function(dict){
-	 	// summary: Represents a runtime context used by DTL templates.
-	 }
-	 
-	=====*/
-	dd.Context = lang.extend(function(dict){
+	return dd.Context = lang.extend(function(/*Object*/dict){
+	 	// summary:
+	 	//		Represents a runtime context used by DTL templates.
 		this._this = {};
-		dd._Context.call(this, dict);
-	}, dd._Context.prototype,
+		dd._Context.call(this, dict);	// TODO: huh?
+	}, dd._Context.prototype,		// TODO: huh?
 	{
 		getKeys: function(){
-			// summary: Returns the set of keys exported by this context.
+			// summary:
+			//		Returns the set of keys exported by this context.
 			var keys = [];
 			for(var key in this){
 				if(this.hasOwnProperty(key) && key != "_this"){
@@ -27,14 +20,16 @@ define([
 			}
 			return keys;
 		},
-		extend: function(/*dojox.dtl.Context|Object*/ obj){
-			// summary: Returns a clone of this context object, with the items from the
-			//		passed objecct mixed in.
+		extend: function(/*dojox/dtl/Context|Object*/ obj){
+			// summary:
+			//		Returns a clone of this context object, with the items from the passed objecct mixed in.
+			// obj:
+			//		The object to extend.
 			return  lang.delegate(this, obj);
 		},
-		filter: function(/*dojox.dtl.Context|Object|String...*/ filter){
-			// summary: Returns a clone of this context, only containing the items
-			//		defined in the filter.
+		filter: function(/*dojox/dtl/Context|Object|String...*/ filter){
+			// summary:
+			//		Returns a clone of this context, only containing the items defined in the filter.
 			var context = new dd.Context();
 			var keys = [];
 			var i, arg;
@@ -58,18 +53,23 @@ define([
 
 			return context;
 		},
-		setThis: function(/*Object*/ _this){
-			// summary: Sets the object on which to perform operations. 
-			// _this: the this ref.
-			this._this = _this;
+		setThis: function(/*Object*/ scope){
+			// summary:
+			//		Sets the object on which to perform operations. 
+			// scope:
+			//		the this ref.
+			this._this = scope;
 		},
 		getThis: function(){
-			// summary: Gets the object on which to perform operations. 
+			// summary:
+			//		Gets the object on which to perform operations. 
 			return this._this;
 		},
 		hasKey: function(/*String*/key){
-			// summary: Indicates whether the specified key is defined on this context.
-			// key: The key to look up.
+			// summary:
+			//		Indicates whether the specified key is defined on this context.
+			// key:
+			//		The key to look up.
 			if(this._getter){
 				var got = this._getter(key);
 				if(typeof got != "undefined"){
@@ -82,7 +82,6 @@ define([
 			}
 
 		return false;
-	}
-});
-return dojox.dtl.Context; 
+		}
+	});
 });
\ No newline at end of file
diff --git a/dojox/dtl/DomInline.js b/dojox/dtl/DomInline.js
index e41bc58..d8f7c53 100644
--- a/dojox/dtl/DomInline.js
+++ b/dojox/dtl/DomInline.js
@@ -4,40 +4,36 @@ define([
 	"./_base",
 	"dijit/_WidgetBase"
 ], function(lang,ddd,dd,Widget){
-	/*=====
-		dd = dojox.dtl;
-		Widget = dijit._WidgetBase;
-	=====*/ 
-	dd.DomInline = lang.extend(function(args, node){
-		this.create(args, node);
-	},
-	Widget.prototype,
-	{
-		context: null,
-		render: function(/*dojox.dtl.Context?*/ context){
-			this.context = context || this.context;
-			this.postMixInProperties();
-			var root = this.template.render(this.context).getRootNode();
-			if(root != this.containerNode){
-				this.containerNode.parentNode.replaceChild(root, this.containerNode);
-				this.containerNode = root;
-			}
-		},
-		declaredClass: "dojox.dtl.Inline",
-		buildRendering: function(){
-			var div = this.domNode = document.createElement("div");
-			this.containerNode = div.appendChild(document.createElement("div"));
-			var node = this.srcNodeRef;
-			if(node.parentNode){
-				node.parentNode.replaceChild(div, node);
-			}
 
-			this.template = new dojox.dtl.DomTemplate(lang.trim(node.text), true);
-			this.render();
+	return dd.DomInline = lang.extend(function(args, node){
+			this.create(args, node);
 		},
-		postMixInProperties: function(){
-			this.context = (this.context.get === dojox.dtl._Context.prototype.get) ? this.context : new dojox.dtl.Context(this.context);
-		}
-	});
-	return dojox.dtl.DomInline;
+		Widget.prototype,
+		{
+			context: null,
+			render: function(/*dojox/dtl/Context?*/ context){
+				this.context = context || this.context;
+				this.postMixInProperties();
+				var root = this.template.render(this.context).getRootNode();
+				if(root != this.containerNode){
+					this.containerNode.parentNode.replaceChild(root, this.containerNode);
+					this.containerNode = root;
+				}
+			},
+			declaredClass: "dojox.dtl.Inline",
+			buildRendering: function(){
+				var div = this.domNode = document.createElement("div");
+				this.containerNode = div.appendChild(document.createElement("div"));
+				var node = this.srcNodeRef;
+				if(node.parentNode){
+					node.parentNode.replaceChild(div, node);
+				}
+	
+				this.template = new dojox.dtl.DomTemplate(lang.trim(node.text), true);
+				this.render();
+			},
+			postMixInProperties: function(){
+				this.context = (this.context.get === dojox.dtl._Context.prototype.get) ? this.context : new dojox.dtl.Context(this.context);
+			}
+		});
 });
\ No newline at end of file
diff --git a/dojox/dtl/Inline.js b/dojox/dtl/Inline.js
index 4d36d20..eb552d8 100644
--- a/dojox/dtl/Inline.js
+++ b/dojox/dtl/Inline.js
@@ -4,37 +4,32 @@ define([
 	"dijit/_WidgetBase",
 	"dojo/query" // dojo.query
 ], function(lang,dd,Widget,Query){
-	/*=====
-		Widget = dijit._WidgetBase;
-		Query = dojo.query;
-		dd = dojox.dtl;
-	=====*/ 
-	dd.Inline = lang.extend(function(args, node){
-		this.create(args, node);
-	},
-	Widget.prototype,
-	{
-		context: null,
-		render: function(/*Object|dojox.dtl.Context?*/ context){
-			this.context = context || this.context;
-			this.postMixInProperties();
-			Query("*", this.domNode).orphan();
-			this.domNode.innerHTML = this.template.render(this.context);
-		},
-		declaredClass: "dojox.dtl.Inline",
-		buildRendering: function(){
-			var div = this.domNode = document.createElement("div");
-			var node = this.srcNodeRef;
-			if(node.parentNode){
-				node.parentNode.replaceChild(div, node);
-			}
 
-			this.template = new dd.Template(lang.trim(node.text), true);
-			this.render();
+	return dd.Inline = lang.extend(function(args, node){
+			this.create(args, node);
 		},
-		postMixInProperties: function(){
-			this.context = (this.context.get === dd._Context.prototype.get) ? this.context : new dd._Context(this.context);
-		}
-	});
-	return dojox.dtl.Inline;
+		Widget.prototype,
+		{
+			context: null,
+			render: function(/*Object|dojox/dtl/Context?*/ context){
+				this.context = context || this.context;
+				this.postMixInProperties();
+				Query("*", this.domNode).orphan();
+				this.domNode.innerHTML = this.template.render(this.context);
+			},
+			declaredClass: "dojox.dtl.Inline",
+			buildRendering: function(){
+				var div = this.domNode = document.createElement("div");
+				var node = this.srcNodeRef;
+				if(node.parentNode){
+					node.parentNode.replaceChild(div, node);
+				}
+	
+				this.template = new dd.Template(lang.trim(node.text), true);
+				this.render();
+			},
+			postMixInProperties: function(){
+				this.context = (this.context.get === dd._Context.prototype.get) ? this.context : new dd._Context(this.context);
+			}
+		});
 });
\ No newline at end of file
diff --git a/dojox/dtl/_DomTemplated.js b/dojox/dtl/_DomTemplated.js
index bdc4c94..5a1916c 100644
--- a/dojox/dtl/_DomTemplated.js
+++ b/dojox/dtl/_DomTemplated.js
@@ -6,25 +6,24 @@ define([
 	"dojo/cache",
 	"dijit/_TemplatedMixin"
 	], function(domConstruct,dtl,ddcd,ddrd,cache,TemplatedMixin){
-	/*=====
-		dtl = dojox.dtl;
-		cache = dojo.cache;
-		TemplatedMixin = dijit._TemplatedMixin
-	=====*/
-	dtl._DomTemplated = function(){};
+
+	dtl._DomTemplated = function(){
+		// summary:
+		//		The base class for DOM-based templating.
+	};
 	dtl._DomTemplated.prototype = {
 		_dijitTemplateCompat: false,
 		buildRendering: function(){
-			//	summary:
-			//		Construct the UI for this widget, setting this.domNode.
-
+			// summary:
+			//		Constructs the DOM representation.
+			
 			//render needs a domNode to work with
-			this.domNode = this.srcNodeRef;
+			this.domNode = this.srcNodeRef || dojo.create('div');
 
 			if(!this._render){
 				var old = ddcd.widgetsInTemplate;
 				ddcd.widgetsInTemplate = this.widgetsInTemplate;
-				this.template = this.template || this._getCachedTemplate(this.templatePath, this.templateString);
+				this.template = this.template && this.template !== true ? this.template : this._getCachedTemplate(this.templatePath, this.templateString);
 				this._render = new ddrd.Render(this.domNode, this.template);
 				ddcd.widgetsInTemplate = old;
 			}
@@ -41,10 +40,11 @@ define([
 				delete this.srcNodeRef;
 			}
 		},
-		setTemplate: function(/*String|dojo._Url*/ template, /*dojox.dtl.Context?*/ context){
+		setTemplate: function(/*String|dojo/url*/ template, /*dojox/dtl/Context?*/ context){
 			// summary:
 			//		Quickly switch between templated by location
-			// template: The new template.
+			// template:
+			//		The new template.
 			// context:
 			//		The runtime context.
 			if(dojox.dtl.text._isTemplate(template)){
@@ -54,7 +54,7 @@ define([
 			}
 			this.render(context);
 		},
-		render: function(/*dojox.dtl.Context?*/ context, /*dojox.dtl.DomTemplate?*/ tpl){
+		render: function(/*dojox/dtl/Context?*/ context, /*dojox/dtl/DomTemplate?*/ tpl){
 			// summary:
 			//		Renders this template.
 			// context:
@@ -94,6 +94,6 @@ define([
 			));
 		}
 	};
-	return dojox.dtl._DomTemplated;
+	return dtl._DomTemplated;
 });
 
diff --git a/dojox/dtl/_Templated.js b/dojox/dtl/_Templated.js
index a39749b..80dae80 100644
--- a/dojox/dtl/_Templated.js
+++ b/dojox/dtl/_Templated.js
@@ -1,4 +1,5 @@
 define([
+	"dojo/aspect",
 	"dojo/_base/declare",
 	"./_base",
 	"dijit/_TemplatedMixin",
@@ -6,22 +7,16 @@ define([
 	"dojo/cache",
 	"dojo/_base/array",
 	"dojo/string",
-	"dojo/parser",
-	"dijit/_base/manager"
-], function(declare,dd,TemplatedMixin, domConstruct,Cache,Array,dString,Parser,dijitMgr){
-	/*=====
-		Cache = dojo.cache;
-		dString = dojo.string;
-		Parser = dojo.parser;
-		TemplatedMixin = dijit._TemplatedMixin;
-		dd = dojox.dtl;
-	=====*/
+	"dojo/parser"
+], function(aspect,declare,dd,TemplatedMixin, domConstruct,Cache,Array,dString,Parser){
+
 	return declare("dojox.dtl._Templated", TemplatedMixin, {
-		// summary: The base-class for DTL-templated widgets.
+		// summary:
+		//		The base-class for DTL-templated widgets.
 
 		_dijitTemplateCompat: false,
+		
 		buildRendering: function(){
-			// summary: The method overrides dijit._TemplatedMixin.startup.
 			var node;
 
 			if(this.domNode && !this._template){
@@ -37,7 +32,7 @@ define([
 				if(t instanceof dd.Template) {
 					this._template = t;
 				}else{
-					node = t;
+					node = t.cloneNode(true);
 				}
 			}
 			if(!node){
@@ -63,9 +58,7 @@ define([
 					node = nodes;
 				}
 			}
-			this._attachTemplateNodes(node, function(n,p){
-				return n.getAttribute(p);
-			});
+			this._attachTemplateNodes(node);
 			if(this.widgetsInTemplate){
 				//Make sure dojoType is used for parsing widgets in template.
 				//The Parser.query could be changed from multiversion support.
@@ -89,11 +82,21 @@ define([
 					parser._attrName = attr;
 				}
 
-				this._supportingWidgets = dijitMgr.findWidgets(node);
-
-				this._attachTemplateNodes(cw, function(n,p){
-					return n[p];
-				});
+				// Hook up attach points and events for nodes that were converted to widgets
+				for(var i = 0; i < cw.length; i++){
+					this._processTemplateNode(cw[i], function(n,p){
+						return n[p];
+					}, function(widget, type, callback){
+						// function to do data-dojo-attach-event to a widget
+						if(type in widget){
+							// back-compat, remove for 2.0
+							return aspect.after(widget, type, callback, true);
+						}else{
+							// 1.x may never hit this branch, but it's the default for 2.0
+							return widget.on(type, callback, true);
+						}
+					});
+				}
 			}
 
 			if(this.domNode){
@@ -105,6 +108,18 @@ define([
 
 			this._fillContent(this.srcNodeRef);
 		},
+
+		_processTemplateNode: function(/*DOMNode|Widget*/ baseNode, getAttrFunc, attachFunc){
+			// Override _AttachMixin._processNode to skip nodes with data-dojo-type set.   They are handled separately
+			// in the buildRendering() code above.
+
+			if(this.widgetsInTemplate && (getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type"))){
+				return true;
+			}
+
+			this.inherited(arguments);
+		},
+
 		_templateCache: {},
 		getCachedTemplate: function(templatePath, templateString, alwaysUseString){
 			// summary:
@@ -131,11 +146,11 @@ define([
 			}
 		},
 		render: function(){
-			// summary: Renders the widget.
+			// summary:
+			//		Renders the widget.
 			this.buildRendering();
 		},
 		startup: function(){
-			// summary: The method overrides dijit._TemplatedMixin.startup.
 			Array.forEach(this._startupWidgets, function(w){
 				if(w && !w._started && w.startup){
 					w.startup();
@@ -144,4 +159,4 @@ define([
 			this.inherited(arguments);
 		}
 	});
-});
\ No newline at end of file
+});
diff --git a/dojox/dtl/_base.js b/dojox/dtl/_base.js
index c509f53..6f684f2 100644
--- a/dojox/dtl/_base.js
+++ b/dojox/dtl/_base.js
@@ -8,29 +8,26 @@ define([
 	"dojox/string/Builder",
 	"dojo/_base/Deferred"], 
 	function(kernel, lang, Tokenize, json, dom, xhr, StringBuilder, deferred){
-	/*=====
-		Tokenize = dojox.string.tokenize;
-		StringBuilder = dojox.string.Builder;
-	=====*/
+
 	kernel.experimental("dojox.dtl");
+
 	var dd = lang.getObject("dojox.dtl", true);
+/*=====
+	dd = {
+		// TODO: summary
+	};
+=====*/
+
 	dd._base = {};
-	/*=====
-		dd = dojox.dtl;
-	=====*/
 
 	dd.TOKEN_BLOCK = -1;
 	dd.TOKEN_VAR = -2;
 	dd.TOKEN_COMMENT = -3;
 	dd.TOKEN_TEXT = 3;
 
-	/*=====
-		dd._Context = function(dict){
-			// summary: Pass one of these when rendering a template to tell the template what values to use.
-		}
-	=====*/
 	dd._Context = lang.extend(function(dict){
-		// summary: Pass one of these when rendering a template to tell the template what values to use.
+		// summary:
+		//		Pass one of these when rendering a template to tell the template what values to use.
 		if(dict){
 			lang._mixin(this, dict);
 			if(dict.get){
@@ -110,16 +107,18 @@ define([
 		}
 		parts.push(this.slice(lastIndex));
 		return parts;
-	}
+	};
 
 	dd.Token = function(token_type, contents){
+		// tags:
+		//		private
 		this.token_type = token_type;
 		this.contents = new String(lang.trim(contents));
 		this.contents.split = split;
 		this.split = function(){
 			return String.prototype.split.apply(this.contents, arguments);
 		}
-	}
+	};
 	dd.Token.prototype.split_contents = function(/*Integer?*/ limit){
 		var bit, bits = [], i = 0;
 		limit = limit || 999;
@@ -134,11 +133,12 @@ define([
 			}
 		}
 		return bits;
-	}
+	};
 
 	var ddt = dd.text = {
 		_get: function(module, name, errorless){
-			// summary: Used to find both tags and filters
+			// summary:
+			//		Used to find both tags and filters
 			var params = dd.register.get(module, name.toLowerCase(), errorless);
 			if(!params){
 				if(!errorless){
@@ -237,40 +237,16 @@ define([
 				return [dd.TOKEN_BLOCK, tag];
 			}
 		}
-	}
+	};
 
-	/*=====
-		dd.Template = function(template, isString){
-			// summary: 
-			// 		The base class for text-based templates.
-			// template: String|dojo._Url
-			//		The string or location of the string to
-			//		use as a template
-			// isString: Boolean
-			//		Indicates whether the template is a string or a url.
-		};
-		dd.Template.prototype.update= function(node, context){
-			// summary:
-			//		Updates this template according to the given context.
-			// node: DOMNode|String|dojo.NodeList
-			//		A node reference or set of nodes
-			// context: dojo._Url|String|Object
-			//		The context object or location
-			}
-		dd.Template.prototype.render= function(context, buffer){
-			// summary:
-			//		Renders this template.
-			// context: Object
-			//		The runtime context.
-			// buffer: StringBuilder?
-			//		A string buffer.
-		}
-		
-	=====*/
 	dd.Template = lang.extend(function(/*String|dojo._Url*/ template, /*Boolean*/ isString){
-		// template:
+		// summary:
+		//		The base class for text-based templates.
+		// template: String|dojo/_base/url
 		//		The string or location of the string to
 		//		use as a template
+		// isString: Boolean
+		//		Indicates whether the template is a string or a url.
 		var str = isString ? template : ddt._resolveTemplateArg(template, true) || "";
 		var tokens = ddt.tokenize(str);
 		var parser = new dd._Parser(tokens);
@@ -280,9 +256,9 @@ define([
 		update: function(node, context){
 			// summary:
 			//		Updates this template according to the given context.
-			// node: DOMNode|String|dojo.NodeList
+			// node: DOMNode|String|dojo/NodeList
 			//		A node reference or set of nodes
-			// context: dojo._Url|String|Object
+			// context: dojo/base/url|String|Object
 			//		The context object or location
 			return ddt._resolveContextArg(context).addCallback(this, function(contextObject){
 				var content = this.render(new dd._Context(contextObject));
@@ -296,7 +272,13 @@ define([
 				return this;
 			});
 		},
-		render: function(context, /*concatenatable?*/ buffer){
+		render: function(context, buffer){
+			// summary:
+			//		Renders this template.
+			// context: Object
+			//		The runtime context.
+			// buffer: StringBuilder?
+			//		A string buffer.
 			buffer = buffer || this.getBuffer();
 			context = context || new dd._Context({});
 			return this.nodelist.render(context, buffer) + "";
@@ -317,7 +299,7 @@ define([
 				return new dd._Filter(token);
 			}));
 		}
-	}
+	};
 
 	dd._QuickNodeList = lang.extend(function(contents){
 		this.contents = contents;
@@ -338,7 +320,8 @@ define([
 	});
 
 	dd._Filter = lang.extend(function(token){
-		// summary: Uses a string to find (and manipulate) a variable
+		// summary:
+		//		Uses a string to find (and manipulate) a variable
 		if(!token) throw new Error("Filter must be called with variable name");
 		this.contents = token;
 
@@ -493,7 +476,8 @@ define([
 	});
 
 	dd._TextNode = dd._Node = lang.extend(function(/*Object*/ obj){
-		// summary: Basic catch-all node
+		// summary:
+		//		Basic catch-all node
 		this.contents = obj;
 	},
 	{
@@ -502,7 +486,8 @@ define([
 			return this;
 		},
 		render: function(context, buffer){
-			// summary: Adds content onto the buffer
+			// summary:
+			//		Adds content onto the buffer
 			return buffer.concat(this.contents);
 		},
 		isEmpty: function(){
@@ -512,13 +497,15 @@ define([
 	});
 
 	dd._NodeList = lang.extend(function(/*Node[]*/ nodes){
-		// summary: Allows us to render a group of nodes
+		// summary:
+		//		Allows us to render a group of nodes
 		this.contents = nodes || [];
 		this.last = "";
 	},
 	{
 		push: function(node){
-			// summary: Add a new node to the list
+			// summary:
+			//		Add a new node to the list
 			this.contents.push(node);
 			return this;
 		},
@@ -527,7 +514,8 @@ define([
 			return this;
 		},
 		render: function(context, buffer){
-			// summary: Adds all content onto the buffer
+			// summary:
+			//		Adds all content onto the buffer
 			for(var i = 0; i < this.contents.length; i++){
 				buffer = this.contents[i].render(context, buffer);
 				if(!buffer) throw new Error("Template must return buffer");
@@ -554,7 +542,8 @@ define([
 	});
 
 	dd._VarNode = lang.extend(function(str){
-		// summary: A node to be processed as a variable
+		// summary:
+		//		A node to be processed as a variable
 		this.contents = new dd._Filter(str);
 	},
 	{
@@ -568,20 +557,24 @@ define([
 	});
 
 	dd._noOpNode = new function(){
-		// summary: Adds a no-op node. Useful in custom tags
+		// summary:
+		//		Adds a no-op node. Useful in custom tags
 		this.render = this.unrender = function(){ return arguments[1]; }
 		this.clone = function(){ return this; }
-	}
+	};
 
 	dd._Parser = lang.extend(function(tokens){
-		// summary: Parser used during initialization and for tag groups.
+		// summary:
+		//		Parser used during initialization and for tag groups.
 		this.contents = tokens;
 	},
 	{
 		i: 0,
 		parse: function(/*Array?*/ stop_at){
-			// summary: Turns tokens into nodes
-			// description: Steps into tags are they're found. Blocks use the parse object
+			// summary:
+			//		Turns tokens into nodes
+			// description:
+			//		Steps into tags are they're found. Blocks use the parse object
 			//		to find their closing tag (the stop_at array). stop_at is inclusive, it
 			//		returns the node that matched.
 			var terminators = {}, token;
@@ -625,7 +618,8 @@ define([
 			return nodelist;
 		},
 		next_token: function(){
-			// summary: Returns the next token in the list.
+			// summary:
+			//		Returns the next token in the list.
 			var token = this.contents[this.i++];
 			return new dd.Token(token[0], token[1]);
 		},
@@ -653,12 +647,17 @@ define([
 	});
 
 	dd.register = {
+		// summary:
+		//		A register for filters and tags.
+		
 		_registry: {
 			attributes: [],
 			tags: [],
 			filters: []
 		},
 		get: function(/*String*/ module, /*String*/ name){
+			// tags:
+			//		private
 			var registry = dd.register._registry[module + "s"];
 			for(var i = 0, entry; entry = registry[i]; i++){
 				if(typeof entry[0] == "string"){
@@ -671,6 +670,8 @@ define([
 			}
 		},
 		getAttributeTags: function(){
+			// tags:
+			//		private
 			var tags = [];
 			var registry = dd.register._registry.attributes;
 			for(var i = 0, entry; entry = registry[i]; i++){
@@ -713,9 +714,31 @@ define([
 			}
 		},
 		tags: function(/*String*/ base, /*Object*/ locations){
+			// summary:
+			//		Register the specified tag libraries.
+			// description:
+			//		The locations parameter defines the contents of each library as a hash whose keys are the library names and values 
+			//		an array of the tags exported by the library. For example, the tags exported by the logic library would be:
+			//	|	{ logic: ["if", "for", "ifequal", "ifnotequal"] }
+			// base:
+			//		The base path of the libraries.
+			// locations:
+			//		An object defining the tags for each library as a hash whose keys are the library names and values 
+			//		an array of the tags or filters exported by the library.
 			dd.register._any("tags", base, locations);
 		},
 		filters: function(/*String*/ base, /*Object*/ locations){
+			// summary:
+			//		Register the specified filter libraries.
+			// description:
+			//		The locations parameter defines the contents of each library as a hash whose keys are the library names and values 
+			//		an array of the filters exported by the library. For example, the filters exported by the date library would be:
+			//	|	{ "dates": ["date", "time", "timesince", "timeuntil"] }
+			// base:
+			//		The base path of the libraries.
+			// locations:
+			//		An object defining the filters for each library as a hash whose keys are the library names and values 
+			//		an array of the filters exported by the library.
 			dd.register._any("filters", base, locations);
 		}
 	}
@@ -726,9 +749,10 @@ define([
 	var escapeqt = /'/g;
 	var escapedblqt = /"/g;
 	dd._base.escape = function(value){
-		// summary: Escapes a string's HTML
+		// summary:
+		//		Escapes a string's HTML
 		return dd.mark_safe(value.replace(escapeamp, '&').replace(escapelt, '<').replace(escapegt, '>').replace(escapedblqt, '"').replace(escapeqt, '''));
-	}
+	};
 
 	dd._base.safe = function(value){
 		if(typeof value == "string"){
@@ -738,7 +762,7 @@ define([
 			value.safe = true;
 		}
 		return value;
-	}
+	};
 	dd.mark_safe = dd._base.safe;
 
 	dd.register.tags("dojox.dtl.tag", {
@@ -760,6 +784,7 @@ define([
 	dd.register.filters("dojox.dtl", {
 		"_base": ["escape", "safe"]
 	});
+
 	return dd;
 });
 
diff --git a/dojox/dtl/contrib/data.js b/dojox/dtl/contrib/data.js
index 7be2653..212f2da 100644
--- a/dojox/dtl/contrib/data.js
+++ b/dojox/dtl/contrib/data.js
@@ -4,12 +4,14 @@ define([
 	"../_base",
 	"dojo/_base/array"
 ], function(kernel,lang,dd,array){
-	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.contrib.data", true);
 
-	var ddcd = dd.contrib.data;
+	var ddcd = lang.getObject("contrib.data", true, dd);
+/*=====
+	ddcd = {
+		// TODO: summary
+	};
+=====*/
+
 	var first = true;
 
 	ddcd._BoundItem = lang.extend(function(item, store){
@@ -124,10 +126,11 @@ define([
 			}
 		},
 		bind_data: function(parser, token){
-			// summary: Turns a list of data store items into DTL compatible items
+			// summary:
+			//		Turns a list of data store items into DTL compatible items
 			// example:
-			//	`contextItems` and `contextStore` should be an item list
-			//	and a data store that get assigned to `newVariable`
+			//		`contextItems` and `contextStore` should be an item list
+			//		and a data store that get assigned to `newVariable`
 			//
 			//	|	{% bind_data contextItems to contextStore as newVariable %}
 			var parts = token.contents.split();
@@ -139,12 +142,13 @@ define([
 			return new ddcd.BindDataNode(parts[1], null, parts[3], parts[5]);
 		},
 		bind_query: function(parser, token){
-			// summary: Queries a data store and makes the returned items DTL compatible
+			// summary:
+			//		Queries a data store and makes the returned items DTL compatible
 			// example:
-			//	You can only use this with data stores that work in a synchronous
-			//	way (meaning that `onComplete` is fired during the `fetch` call).
-			//	A `sync` flag is sent to the fetch call so that stores that usually
-			//	work asynchronously make themselves syncrhonous if possible.
+			//		You can only use this with data stores that work in a synchronous
+			//		way (meaning that `onComplete` is fired during the `fetch` call).
+			//		A `sync` flag is sent to the fetch call so that stores that usually
+			//		work asynchronously make themselves syncrhonous if possible.
 			//	|	{% bind_query contextQuery to contextStore as newVariable %}
 			var parts = token.contents.split();
 
@@ -160,5 +164,6 @@ define([
 	dd.register.tags("dojox.dtl.contrib", {
 		"data": ["bind_data", "bind_query"]
 	});
-	return dojox.dtl.contrib.data;
+
+	return ddcd;
 });
\ No newline at end of file
diff --git a/dojox/dtl/contrib/dijit.js b/dojox/dtl/contrib/dijit.js
index 0d33a33..ac7544c 100644
--- a/dojox/dtl/contrib/dijit.js
+++ b/dojox/dtl/contrib/dijit.js
@@ -7,14 +7,15 @@ define([
 	"../dom",
 	"dojo/parser",
 	"dojo/_base/sniff"
-], function(lang,connect,array,Query,dd,dxdom,Parser,has){
-	/*=====
-		Query = dojo.query;
-		Parser = dojo.parser;
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.contrib.dijit", true);
-	var ddcd = dd.contrib.dijit;
+], function(lang,connect,array,query,dd,dxdom,parser,has){
+
+	var ddcd = lang.getObject("contrib.dijit", true, dd);
+/*=====
+	ddcd = {
+		// TODO: summary
+	};
+=====*/
+
 	ddcd.AttachNode = lang.extend(function(keys, object){
 		this._keys = keys;
 		this._object = object;
@@ -101,6 +102,12 @@ define([
 					if(!this._object){
 						this._rendered[i] = buffer.addEvent(context, type, fn, args);
 					}else{
+						var resolved = fn; 
+						if(lang.isArray(args)){ 
+							resolved = function(e){ 
+								this[fn].apply(this, [e].concat(args)); 
+							} 
+						} 
 						this._rendered[i] = connect.connect(this._object, type, context.getThis(), fn);
 					}
 				}
@@ -123,7 +130,7 @@ define([
 	function cloneNode(n1){
 		var n2 = n1.cloneNode(true);
 		if(has("ie")){
-			Query("script", n2).forEach("item.text = this[index].text;", Query("script", n1));
+			query("script", n2).forEach("item.text = this[index].text;", query("script", n1));
 		}
 		return n2;
 	}
@@ -142,7 +149,7 @@ define([
 		}
 
 		if(!parsed){
-			this._dijit = Parser.instantiate([cloneNode(node)])[0];
+			this._dijit = parser.instantiate([cloneNode(node)])[0];
 		}else{
 			node = cloneNode(node);
 			var old = ddcd.widgetsInTemplate;
@@ -166,7 +173,7 @@ define([
 					if(this._dijit){
 						this._dijit.destroyRecursive();
 					}
-					this._dijit = Parser.instantiate([root])[0];
+					this._dijit = parser.instantiate([root])[0];
 				}
 			}
 
@@ -216,7 +223,8 @@ define([
 			return new dd.AttributeNode("data-dojo-type", dojoType);
 		},
 		on: function(parser, token){
-			// summary: Associates an event type to a function (on the current widget) by name
+			// summary:
+			//		Associates an event type to a function (on the current widget) by name
 			var parts = token.contents.split();
 			return new ddcd.EventNode(parts[0] + ":" + parts.slice(1).join(" "));
 		}
@@ -229,5 +237,6 @@ define([
 	dd.register.tags("dojox.dtl.contrib", {
 		"dijit": ["attr:dojoType", "attr:data-dojo-type", "attr:dojoAttachPoint", "attr:data-dojo-attach-point", ["attr:attach", "dojoAttachPoint"], ["attr:attach", "data-dojo-attach-point"], "attr:dojoAttachEvent", "attr:data-dojo-attach-event", [/(attr:)?on(click|key(up))/i, "on"]]
 	});
-	return dojox.dtl.contrib.dijit;
+
+	return ddcd;
 });
diff --git a/dojox/dtl/contrib/dom.js b/dojox/dtl/contrib/dom.js
index d657f28..64e9174 100644
--- a/dojox/dtl/contrib/dom.js
+++ b/dojox/dtl/contrib/dom.js
@@ -7,10 +7,13 @@ define([
 	"../_base",
 	"../dom"
 ], function(kernel,lang,connect,domStyle,domConstruct,dd,dddom){
-	/*=====
-		dd = dojox.dtl;
-	=====*/
-	var ddch = lang.getObject("dojox.dtl.contrib.dom", true);
+
+	var ddch = lang.getObject("contrib.dom", true, dd);
+/*=====
+	ddch = {
+		// TODO: summary
+	};
+=====*/
 
 	var simple = {render: function(){ return this.contents; }};
 
@@ -114,7 +117,7 @@ define([
 		buffer: function(parser, token){
 			// summary:
 			//		Buffer large DOM manipulations during re-render.
-			//	description:
+			// description:
 			//		When using DomTemplate, wrap any content
 			//		that you expect to change often during
 			//		re-rendering. It will then remove its parent
@@ -130,11 +133,11 @@ define([
 			// example:
 			//		You can explicitly declare options:
 			//
-			//			* node: Watch node removal/addition
-			//			* class: Watch for a classname to be changed
-			//			* text: Watch for any text to be changed
+			//		- node: Watch node removal/addition
+			//		- class: Watch for a classname to be changed
+			//		- text: Watch for any text to be changed
 			//
-			//		|	{% buffer node class %}{% for item in items %}<li>{{ item }}</li>{% endfor %}{% endbuffer %}
+			//	|	{% buffer node class %}{% for item in items %}<li>{{ item }}</li>{% endfor %}{% endbuffer %}
 			var parts = token.contents.split().slice(1);
 			var options = {};
 			var found = false;
@@ -172,5 +175,6 @@ define([
 	dd.register.tags("dojox.dtl.contrib", {
 		"dom": ["html", "attr:style", "buffer"]
 	});
-	return dojox.dtl.contrib.dom;
+
+	return ddch;
 });
\ No newline at end of file
diff --git a/dojox/dtl/contrib/objects.js b/dojox/dtl/contrib/objects.js
index 56e7a7d..8c0cf29 100644
--- a/dojox/dtl/contrib/objects.js
+++ b/dojox/dtl/contrib/objects.js
@@ -2,12 +2,15 @@ define([
 	"dojo/_base/lang",
 	"../_base"	
 ], function(lang,dd){
-	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.contrib.objects", true);
 
-	lang.mixin(dd.contrib.objects, {
+	var objects = lang.getObject("contrib.objects", true, dd);
+/*=====
+	objects = {
+		// TODO: summary
+	};
+=====*/
+
+	lang.mixin(objects, {
 		key: function(value, arg){
 			return value[arg];
 		}
@@ -16,5 +19,6 @@ define([
 	dd.register.filters("dojox.dtl.contrib", {
 		"objects": ["key"]
 	});
-	return dojox.dtl.contrib.objects;
+
+	return objects;
 });
\ No newline at end of file
diff --git a/dojox/dtl/demos/json/blog/get_blog_1.json b/dojox/dtl/demos/json/blog/get_blog_1.json
index 9c7dd9f..b0cc88b 100644
--- a/dojox/dtl/demos/json/blog/get_blog_1.json
+++ b/dojox/dtl/demos/json/blog/get_blog_1.json
@@ -1 +1 @@
-{"teaser":"I'd be able to write a lot faster.","body":"I think I wouldn't be able to think.","date":1189125242601,"author":"jim"}
\ No newline at end of file
+{"teaser":"I'd be able to write a lot faster.","body":"I think I wouldn't be able to think.","date":1189125242601,"author":"jim"}
diff --git a/dojox/dtl/demos/json/blog/get_blog_3.json b/dojox/dtl/demos/json/blog/get_blog_3.json
index 7c0a937..7dda897 100644
--- a/dojox/dtl/demos/json/blog/get_blog_3.json
+++ b/dojox/dtl/demos/json/blog/get_blog_3.json
@@ -1 +1 @@
-{"teaser":"There was SO much sand","body":"I tried to walk so fast that I wouldn't leave foot prints.","date":1190245842601,"author":"jim"}
\ No newline at end of file
+{"teaser":"There was SO much sand","body":"I tried to walk so fast that I wouldn't leave foot prints.","date":1190245842601,"author":"jim"}
diff --git a/dojox/dtl/demos/json/blog/get_blog_list.json b/dojox/dtl/demos/json/blog/get_blog_list.json
index 40f14a7..c1ee04d 100644
--- a/dojox/dtl/demos/json/blog/get_blog_list.json
+++ b/dojox/dtl/demos/json/blog/get_blog_list.json
@@ -1 +1 @@
-{"blog_list":{"3":{"title":"My Trip to the Beach"},"1":{"title":"If I Were a Robot"}}}
\ No newline at end of file
+{"blog_list":{"3":{"title":"My Trip to the Beach"},"1":{"title":"If I Were a Robot"}}}
diff --git a/dojox/dtl/demos/json/blog/get_page_about.json b/dojox/dtl/demos/json/blog/get_page_about.json
index 05ddb9c..e1aa39e 100644
--- a/dojox/dtl/demos/json/blog/get_page_about.json
+++ b/dojox/dtl/demos/json/blog/get_page_about.json
@@ -1 +1 @@
-{"title":"About Jim","body":"<p>Jim is an avid golfer, enjoys long walks on the beach, and eating hot pockets</p><p>When he's not scalding his mouth, you'll find him throwing rocks at pigeons.</p>"}
\ No newline at end of file
+{"title":"About Jim","body":"<p>Jim is an avid golfer, enjoys long walks on the beach, and eating hot pockets</p><p>When he's not scalding his mouth, you'll find him throwing rocks at pigeons.</p>"}
diff --git a/dojox/dtl/demos/json/fruit.json b/dojox/dtl/demos/json/fruit.json
index e7a0bf8..3b6293b 100644
--- a/dojox/dtl/demos/json/fruit.json
+++ b/dojox/dtl/demos/json/fruit.json
@@ -1 +1 @@
-{ items: ["apple", "banana", "pear"] }
\ No newline at end of file
+{ items: ["apple", "banana", "pear"] }
diff --git a/dojox/dtl/demos/json/morefruit.json b/dojox/dtl/demos/json/morefruit.json
index 6a8beea..18afd74 100644
--- a/dojox/dtl/demos/json/morefruit.json
+++ b/dojox/dtl/demos/json/morefruit.json
@@ -1 +1 @@
-{ items: ["pineapple", "orange", "tomato"] }
\ No newline at end of file
+{ items: ["pineapple", "orange", "tomato"] }
diff --git a/dojox/dtl/dom.js b/dojox/dtl/dom.js
index 6124f28..cbd7d8b 100755
--- a/dojox/dtl/dom.js
+++ b/dojox/dtl/dom.js
@@ -10,10 +10,7 @@ define([
 	"dojo/_base/connect",
 	"dojo/_base/sniff"
 ], function(lang,dd,Tokenize,context,dom,domconstruct,html,array,connect,has){
-	/*=====
-		Tokenize = dojox.string.tokenize;
-		dd = dojox.dtl;
-	=====*/
+
 	dd.BOOLS = {checked: 1, disabled: 1, readonly: 1};
 	dd.TOKEN_CHANGE = -11;
 	dd.TOKEN_ATTR = -12;
@@ -344,8 +341,9 @@ define([
 		}
 	};
 
-	dd.DomTemplate = lang.extend(function(/*String|DOMNode|dojo._Url*/ obj){
-		// summary: The template class for DOM templating.
+	dd.DomTemplate = lang.extend(function(/*String|DOMNode|dojo/Url*/ obj){
+		// summary:
+		//		The template class for DOM templating.
 		if(!obj.nodes){
 			var node = dom.byId(obj);
 			if(node && node.nodeType == 1){
@@ -375,19 +373,23 @@ define([
 		_count: 0,
 		_re: /\bdojo:([a-zA-Z0-9_]+)\b/g,
 		setClass: function(/*String*/str){
-			// summary: Sets the specified class name on the root node.
+			// summary:
+			//		Sets the specified class name on the root node.
 			this.getRootNode().className = str;
 		},
 		getRootNode: function(){
-			// summary: Returns the template root node.
+			// summary:
+			//		Returns the template root node.
 			return this.buffer.rootNode;
 		},
 		getBuffer: function(){
-			// summary: Returns a new buffer.
+			// summary:
+			//		Returns a new buffer.
 			return new dd.DomBuffer();
 		},
-		render: function(/*dojox.dtl.Context?*/context, /*concatenable?*/buffer){
-			// summary: Renders this template.
+		render: function(/*dojox/dtl/Context?*/context, /*concatenable?*/buffer){
+			// summary:
+			//		Renders this template.
 			buffer = this.buffer = buffer || this.getBuffer();
 			this.rootNode = null;
 			var output = this.nodelist.render(context || new dd.Context({}), buffer);
@@ -404,10 +406,13 @@ define([
 	});
 
 	dd.DomBuffer = lang.extend(function(/*Node*/ parent){
-		// summary: Allows the manipulation of DOM
+		// summary:
+		//		Allows the manipulation of DOM
 		// description:
 		//		Use this to append a child, change the parent, or
 		//		change the attribute of the current node.
+		// parent:
+		//		The parent node.
 		this._parent = parent;
 		this._cache = [];
 	},
@@ -560,30 +565,38 @@ define([
 		/*=====
 		,
 		onSetParent: function(node, up){
-			// summary: Stub called when setParent is used.
+			// summary:
+			//		Stub called when setParent is used.
 		},
 		onAddNode: function(node){
-			// summary: Stub called before new nodes are added
+			// summary:
+			//		Stub called before new nodes are added
 		},
 		onAddNodeComplete: function(node){
-			// summary: Stub called after new nodes are added
+			// summary:
+			//		Stub called after new nodes are added
 		},
 		onRemoveNode: function(node){
-			// summary: Stub called when nodes are removed
+			// summary:
+			//		Stub called when nodes are removed
 		},
 		onChangeAttribute: function(node, attribute, old, updated){
-			// summary: Stub called when an attribute is changed
+			// summary:
+			//		Stub called when an attribute is changed
 		},
 		onChangeData: function(node, old, updated){
-			// summary: Stub called when a data in a node is changed
+			// summary:
+			//		Stub called when a data in a node is changed
 		},
 		onClone: function(from, to){
-			// summary: Stub called when a node is duplicated
+			// summary:
+			//		Stub called when a node is duplicated
 			// from: DOMNode
 			// to: DOMNode
 		},
 		onAddEvent: function(node, type, description){
-			// summary: Stub to call when you're adding an event
+			// summary:
+			//		Stub to call when you're adding an event
 			// node: DOMNode
 			// type: String
 			// description: String
@@ -592,7 +605,8 @@ define([
 	});
 
 	dd._DomNode = lang.extend(function(node){
-		// summary: Places a node into DOM
+		// summary:
+		//		Places a node into DOM
 		this.contents = node;
 	},
 	{
@@ -613,7 +627,8 @@ define([
 	});
 
 	dd._DomNodeList = lang.extend(function(/*Node[]*/ nodes){
-		// summary: A list of any DOM-specific node objects
+		// summary:
+		//		A list of any DOM-specific node objects
 		// description:
 		//		Any object that's used in the constructor or added
 		//		through the push function much implement the
@@ -643,7 +658,8 @@ define([
 			return buffer;
 		},
 		dummyRender: function(context, buffer, asNode){
-			// summary: A really expensive way of checking to see how a rendering will look.
+			// summary:
+			//		A really expensive way of checking to see how a rendering will look.
 			//		Used in the ifchanged tag
 			var div = document.createElement("div");
 
@@ -731,7 +747,8 @@ define([
 	});
 
 	dd._DomVarNode = lang.extend(function(str){
-		// summary: A node to be processed as a variable
+		// summary:
+		//		A node to be processed as a variable
 		// description:
 		//		Will render an object that supports the render function
 		// 		and the getRootNode function
@@ -853,7 +870,8 @@ define([
 	});
 
 	dd.ChangeNode = lang.extend(function(node, /*Boolean?*/ up, /*Bookean*/ root){
-		// summary: Changes the parent during render/unrender
+		// summary:
+		//		Changes the parent during render/unrender
 		this.contents = node;
 		this.up = up;
 		this.root = root;
@@ -874,7 +892,8 @@ define([
 	});
 
 	dd.AttributeNode = lang.extend(function(key, value){
-		// summary: Works on attributes
+		// summary
+		//		Works on attributes
 		this.key = key;
 		this.value = value;
 		this.contents = value;
@@ -913,7 +932,8 @@ define([
 	});
 
 	dd._DomTextNode = lang.extend(function(str){
-		// summary: Adds a straight text node without any processing
+		// summary
+		//		Adds a straight text node without any processing
 		this.contents = document.createTextNode(str);
 		this.upcoming = str;
 	},
@@ -942,10 +962,11 @@ define([
 	});
 
 	dd._DomParser = lang.extend(function(tokens){
-		// summary: Turn a simple array into a set of objects
+		// summary:
+		//		Turn a simple array into a set of objects
 		// description:
-		//	This is also used by all tags to move through
-		//	the list of nodes.
+		//		This is also used by all tags to move through
+		//		the list of nodes.
 		this.contents = tokens;
 	},
 	{
@@ -990,7 +1011,7 @@ define([
 					var fn = ddt.getTag("node:" + value.tagName.toLowerCase(), true);
 					if(fn){
 						// TODO: We need to move this to tokenization so that it's before the
-						// 				node and the parser can be passed here instead of null
+						//				node and the parser can be passed here instead of null
 						nodelist.push(fn(null, new dd.Token(type, value), value.tagName.toLowerCase()));
 					}
 					nodelist.push(new dd._DomNode(value));
@@ -1025,7 +1046,8 @@ define([
 			return nodelist;
 		},
 		next_token: function(){
-			// summary: Returns the next token in the list.
+			// summary:
+			//		Returns the next token in the list.
 			var token = this.contents[this.i++];
 			return new dd.Token(token[0], token[1]);
 		},
@@ -1045,5 +1067,6 @@ define([
 			return new dd.DomTemplate(ddh.getTemplate(loc));
 		}
 	});
-	return dojox.dtl.dom;
+
+	return ddh;
 });
diff --git a/dojox/dtl/ext-dojo/NodeList.js b/dojox/dtl/ext-dojo/NodeList.js
index 99ffbce..170211c 100755
--- a/dojox/dtl/ext-dojo/NodeList.js
+++ b/dojox/dtl/ext-dojo/NodeList.js
@@ -1,21 +1,19 @@
 define([
 	"dojo/_base/lang",
-	"dojo/_base/NodeList",
+	"dojo/query",
 	"../_base"
-], function(lang,Nodelist,dd){
-	/*=====
-		Nodelist = dojo.Nodelist;
-		dd = dojox.dtl;
-	=====*/
-	
+], function(lang, query, dd){
 	var nl = lang.getObject("dojox.dtl.ext-dojo.NodeList", true);
 
-	lang.extend(Nodelist, {
+	var NodeList = query.NodeList;
+
+	lang.extend(NodeList, {
 		dtl: function(template, context){
-			// summary: Renders the specified template in each of the Nodelist entries.
-			// template: dojox.dtl.__StringArgs|String
+			// summary:
+			//		Renders the specified template in each of the NodeList entries.
+			// template: dojox/dtl/__StringArgs|String
 			//		The template string or location
-			// context: dojox.dtl.__ObjectArgs|Object
+			// context: dojox/dtl/__ObjectArgs|Object
 			//		The context object or location
 			var d = dd, self = this;
 			
@@ -24,7 +22,7 @@ define([
 				self.forEach(function(node){
 					node.innerHTML = content;
 				});
-			}
+			};
 
 			d.text._resolveTemplateArg(template).addCallback(function(templateString){
 				template = new d.Template(templateString);
@@ -36,5 +34,5 @@ define([
 			return this;
 		}
 	});
-	return nl;
+	return NodeList;
 });
\ No newline at end of file
diff --git a/dojox/dtl/filter/dates.js b/dojox/dtl/filter/dates.js
index 6d34fa4..d8b0fa5 100644
--- a/dojox/dtl/filter/dates.js
+++ b/dojox/dtl/filter/dates.js
@@ -3,12 +3,14 @@ define([
 	"../_base",	
 	"../utils/date"
 ], function(lang,dd,ddud){
-	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.filter.dates", true);
 
-	var ddfd = dd.filter.dates;
+	var ddfd = lang.getObject("filter.dates", true, dd);
+/*=====
+	ddfd = {
+		// TODO: summary
+	};
+=====*/
+
 	lang.mixin(ddfd, {
 		_toDate: function(value){
 			if(value instanceof Date){
@@ -21,7 +23,8 @@ define([
 			return value;
 		},
 		date: function(value, arg){
-			// summary: Formats a date according to the given format
+			// summary:
+			//		Formats a date according to the given format
 			value = ddfd._toDate(value);
 			if(!value){
 				return "";
@@ -30,7 +33,8 @@ define([
 			return ddud.format(value, arg);
 		},
 		time: function(value, arg){
-			// summary: Formats a time according to the given format
+			// summary:
+			//		Formats a time according to the given format
 			value = ddfd._toDate(value);
 			if(!value){
 				return "";
@@ -39,7 +43,8 @@ define([
 			return ddud.format(value, arg);
 		},
 		timesince: function(value, arg){
-			// summary: Formats a date as the time since that date (i.e. "4 days, 6 hours")
+			// summary:
+			//		Formats a date as the time since that date (i.e. "4 days, 6 hours")
 			value = ddfd._toDate(value);
 			if(!value){
 				return "";
@@ -51,7 +56,8 @@ define([
 			return timesince(value);
 		},
 		timeuntil: function(value, arg){
-			// summary: Formats a date as the time until that date (i.e. "4 days, 6 hours")
+			// summary:
+			//		Formats a date as the time until that date (i.e. "4 days, 6 hours")
 			value = ddfd._toDate(value);
 			if(!value){
 				return "";
@@ -63,5 +69,6 @@ define([
 			return timesince(new Date(), value);
 		}
 	});
-	return dojox.dtl.filter.dates;
+
+	return ddfd;
 });
\ No newline at end of file
diff --git a/dojox/dtl/filter/htmlstrings.js b/dojox/dtl/filter/htmlstrings.js
index 7dd9f1e..4574372 100644
--- a/dojox/dtl/filter/htmlstrings.js
+++ b/dojox/dtl/filter/htmlstrings.js
@@ -2,12 +2,15 @@ define([
 	"dojo/_base/lang",
 	"../_base"
 ], function(lang,dd){
-	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.filter.htmlstrings", true);
 
-	lang.mixin(dd.filter.htmlstrings, {
+	var htmlstrings = lang.getObject("filter.htmlstrings", true, dd);
+/*=====
+	htmlstrings = {
+		// TODO: summary
+	};
+=====*/
+
+	lang.mixin(htmlstrings, {
 		_linebreaksrn: /(\r\n|\n\r)/g,
 		_linebreaksn: /\n{2,}/g,
 		_linebreakss: /(^\s+|\s+$)/g,
@@ -15,9 +18,10 @@ define([
 		_removetagsfind: /[a-z0-9]+/g,
 		_striptags: /<[^>]*?>/g,
 		linebreaks: function(value){
-			// summary: Converts newlines into <p> and <br />s
+			// summary:
+			//		Converts newlines into `<p>` and `<br />`s
 			var output = [];
-			var dh = dd.filter.htmlstrings;
+			var dh = htmlstrings;
 			value = value.replace(dh._linebreaksrn, "\n");
 			var parts = value.split(dh._linebreaksn);
 			for(var i = 0; i < parts.length; i++){
@@ -28,13 +32,15 @@ define([
 			return output.join("\n\n");
 		},
 		linebreaksbr: function(value){
-			// summary: Converts newlines into <br />s
-			var dh = dd.filter.htmlstrings;
+			// summary:
+			//		Converts newlines into `<br />`s
+			var dh = htmlstrings;
 			return value.replace(dh._linebreaksrn, "\n").replace(dh._linebreaksbr, "<br />");
 		},
 		removetags: function(value, arg){
-			// summary: Removes a space separated list of [X]HTML tags from the output"
-			var dh = dd.filter.htmlstrings;
+			// summary:
+			//		Removes a space separated list of [X]HTML tags from the output"
+			var dh = htmlstrings;
 			var tags = [];
 			var group;
 			while(group = dh._removetagsfind.exec(arg)){
@@ -44,9 +50,11 @@ define([
 			return value.replace(new RegExp("</?\s*" + tags + "\s*[^>]*>", "gi"), "");
 		},
 		striptags: function(value){
-			// summary: Strips all [X]HTML tags
+			// summary:
+			//		Strips all [X]HTML tags
 			return value.replace(dojox.dtl.filter.htmlstrings._striptags, "");
 		}
 	});
-	return dojox.dtl.filter.htmlstrings;
+
+	return htmlstrings;
 });
\ No newline at end of file
diff --git a/dojox/dtl/filter/integers.js b/dojox/dtl/filter/integers.js
index 92a6265..ea32970 100644
--- a/dojox/dtl/filter/integers.js
+++ b/dojox/dtl/filter/integers.js
@@ -2,12 +2,15 @@ define([
 	"dojo/_base/lang",
 	"../_base"
 ], function(lang,dd){
+
+	var integers = lang.getObject("filter.integers", true, dd);
 	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.filter.integers", true);
+	 integers = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
-	lang.mixin(dd.filter.integers, {
+	lang.mixin(integers, {
 		add: function(value, arg){
 			value = parseInt(value, 10);
 			arg = parseInt(arg, 10);
@@ -33,5 +36,6 @@ define([
 			return (isNaN(value) ? 0 : value);
 		}
 	});
-	return dojox.dtl.filter.integers;
+
+	return integers;
 });
\ No newline at end of file
diff --git a/dojox/dtl/filter/lists.js b/dojox/dtl/filter/lists.js
index a55b26e..04f5521 100644
--- a/dojox/dtl/filter/lists.js
+++ b/dojox/dtl/filter/lists.js
@@ -2,12 +2,15 @@ define([
 	"dojo/_base/lang",
 	"../_base"
 ], function(lang,dd){
+
+	var lists = lang.getObject("filter.lists", true, dd);
 	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.filter.lists", true);
+	 lists = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
-	lang.mixin(dd.filter.lists, {
+	lang.mixin(lists, {
 		_dictsort: function(a, b){
 			if(a[0] == b[0]){
 				return 0;
@@ -15,7 +18,8 @@ define([
 			return (a[0] < b[0]) ? -1 : 1;
 		},
 		dictsort: function(value, arg){
-			// summary: Takes a list of dicts, returns that list sorted by the property given in the argument.
+			// summary:
+			//		Takes a list of dicts, returns that list sorted by the property given in the argument.
 			if(!arg){
 				return value;
 			}
@@ -38,18 +42,21 @@ define([
 			return output;
 		},
 		dictsortreversed: function(value, arg){
-			// summary: Takes a list of dicts, returns that list sorted in reverse order by the property given in the argument.
+			// summary:
+			//		Takes a list of dicts, returns that list sorted in reverse order by the property given in the argument.
 			if(!arg) return value;
 
 			var dictsort = dojox.dtl.filter.lists.dictsort(value, arg);
 			return dictsort.reverse();
 		},
 		first: function(value){
-			// summary: Returns the first item in a list
+			// summary:
+			//		Returns the first item in a list
 			return (value.length) ? value[0] : "";
 		},
 		join: function(value, arg){
-			// summary: Joins a list with a string, like Python's ``str.join(list)``
+			// summary:
+			//		Joins a list with a string, like Python's ``str.join(list)``
 			// description:
 			//		Django throws a compile error, but JS can't do arg checks
 			//		so we're left with run time errors, which aren't wise for something
@@ -57,22 +64,26 @@ define([
 			return value.join(arg || ",");
 		},
 		length: function(value){
-			// summary: Returns the length of the value - useful for lists
+			// summary:
+			//		Returns the length of the value - useful for lists
 			return (isNaN(value.length)) ? (value + "").length : value.length;
 		},
 		length_is: function(value, arg){
-			// summary: Returns a boolean of whether the value's length is the argument
+			// summary:
+			//		Returns a boolean of whether the value's length is the argument
 			return value.length == parseInt(arg);
 		},
 		random: function(value){
-			// summary: Returns a random item from the list
+			// summary:
+			//		Returns a random item from the list
 			return value[Math.floor(Math.random() * value.length)];
 		},
 		slice: function(value, arg){
-			// summary: Returns a slice of the list.
+			// summary:
+			//		Returns a slice of the list.
 			// description:
 			//		Uses the same syntax as Python's list slicing; see
-			//		http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice
+			//		http://www.diveintopython.net/native_data_types/lists.html#odbchelper.list.slice
 			//		for an introduction.
 			//		Also uses the optional third value to denote every X item.
 			arg = arg || "";
@@ -120,8 +131,8 @@ define([
 		unordered_list: function(value){
 			// summary:
 			//		Recursively takes a self-nested list and returns an HTML unordered list --
-			//		WITHOUT opening and closing <ul> tags.
-			//	description:
+			//		WITHOUT opening and closing `<ul>` tags.
+			// description:
 			//		The list is assumed to be in the proper format. For example, if ``var`` contains
 			//		``['States', [['Kansas', [['Lawrence', []], ['Topeka', []]]], ['Illinois', []]]]``,
 			//		then ``{{ var|unordered_list }}`` would return::
@@ -137,8 +148,9 @@ define([
 			//		|		<li>Illinois</li>
 			//		|	</ul>
 			//		|	</li>
-			return dojox.dtl.filter.lists._unordered_list(value, 1);
+			return lists._unordered_list(value, 1);
 		}
 	});
-	return dojox.dtl.filter.lists;
+
+	return lists;
 });
\ No newline at end of file
diff --git a/dojox/dtl/filter/logic.js b/dojox/dtl/filter/logic.js
index 94cf950..f2acdcf 100644
--- a/dojox/dtl/filter/logic.js
+++ b/dojox/dtl/filter/logic.js
@@ -2,22 +2,28 @@ define([
 	"dojo/_base/lang",
 	"../_base"
 ], function(lang,dd){
+
+	var logic = lang.getObject("filter.logic", true, dd);
 	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.filter.logic", true);
+	 logic = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
-	lang.mixin(dd.filter.logic, {
+	lang.mixin(logic, {
 		default_: function(value, arg){
-			// summary: If value is unavailable, use given default
+			// summary:
+			//		If value is unavailable, use given default
 			return value || arg || "";
 		},
 		default_if_none: function(value, arg){
-			// summary: If value is null, use given default
+			// summary:
+			//		If value is null, use given default
 			return (value === null) ? arg || "" : value || "";
 		},
 		divisibleby: function(value, arg){
-			// summary: Returns true if the value is devisible by the argument"
+			// summary:
+			//		Returns true if the value is divisible by the argument"
 			return (parseInt(value, 10) % parseInt(arg, 10)) === 0;
 		},
 		_yesno: /\s*,\s*/g,
@@ -41,5 +47,6 @@ define([
 			return parts[2];
 		}
 	});
-	return dojox.dtl.filter.logic;
+
+	return logic;
 });
\ No newline at end of file
diff --git a/dojox/dtl/filter/misc.js b/dojox/dtl/filter/misc.js
index 3c8d0e7..f337c2d 100644
--- a/dojox/dtl/filter/misc.js
+++ b/dojox/dtl/filter/misc.js
@@ -3,14 +3,18 @@ define([
 	"dojo/_base/json",	// dojo.toJson
 	"../_base"
 ], function(lang,json,dd){
+
+	var misc = lang.getObject("filter.misc", true, dd);
 	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.filter.misc", true);
+	 misc = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
-	lang.mixin(dd.filter.misc, {
+	lang.mixin(misc, {
 		filesizeformat: function(value){
-			// summary: Format the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, 102bytes, etc).
+			// summary:
+			//		Format the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, 102bytes, etc).
 			value = parseFloat(value);
 			if(value < 1024){
 				return (value == 1) ? value + " byte" : value + " bytes";
@@ -24,7 +28,7 @@ define([
 		pluralize: function(value, arg){
 			// summary:
 			//		Returns a plural suffix if the value is not 1, for '1 vote' vs. '2 votes'
-			//	description:
+			// description:
 			//		By default, 's' is used as a suffix; if an argument is provided, that string
 			//		is used instead. If the provided argument contains a comma, the text before
 			//		the comma is used for the singular case.
@@ -46,7 +50,8 @@ define([
 		},
 		_phone2numeric: { a: 2, b: 2, c: 2, d: 3, e: 3, f: 3, g: 4, h: 4, i: 4, j: 5, k: 5, l: 5, m: 6, n: 6, o: 6, p: 7, r: 7, s: 7, t: 8, u: 8, v: 8, w: 9, x: 9, y: 9 },
 		phone2numeric: function(value){
-			// summary: Takes a phone number and converts it in to its numerical equivalent
+			// summary:
+			//		Takes a phone number and converts it in to its numerical equivalent
 			var dm = dd.filter.misc;
 			value = value + "";
 			var output = "";
@@ -57,9 +62,11 @@ define([
 			return output;
 		},
 		pprint: function(value){
-			// summary: A wrapper around toJson unless something better comes along
+			// summary:
+			//		A wrapper around toJson unless something better comes along
 			return json.toJson(value);
 		}
 	});
-	return dojox.dtl.filter.misc;
+
+	return misc;
 });
diff --git a/dojox/dtl/filter/strings.js b/dojox/dtl/filter/strings.js
index 205869c..2e9b944 100644
--- a/dojox/dtl/filter/strings.js
+++ b/dojox/dtl/filter/strings.js
@@ -6,14 +6,15 @@ define([
 	"../filter/htmlstrings",
 	"../_base"
 ], function(lang,array,Tokenize,Sprintf,htmlstrings,dd){
+
+	var strings = lang.getObject("filter.strings", true, dd);
 	/*=====
-		dd = dojox.dtl;
-		Tokenize = dojox.string.tokenize;
-		Sprintf = dojox.string.sprintf;
-	=====*/
-	lang.getObject("dojox.dtl.filter.strings", true);
+	 strings = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
-	lang.mixin(dd.filter.strings, {
+	lang.mixin(strings, {
 		_urlquote: function(/*String*/ url, /*String?*/ safe){
 			if(!safe){
 				safe = "/";
@@ -23,23 +24,30 @@ define([
 					if(token == " "){
 						return "+";
 					}else{
-						return "%" + token.charCodeAt(0).toString(16).toUpperCase();
+						var hex = token.charCodeAt(0).toString(16).toUpperCase();
+						while(hex.length < 2){
+							hex = "0" + hex;
+						}
+						return "%" + hex;
 					}
 				}
 				return token;
 			}).join("");
 		},
 		addslashes: function(value){
-			// summary: Adds slashes - useful for passing strings to JavaScript, for example.
+			// summary:
+			//		Adds slashes - useful for passing strings to JavaScript, for example.
 			return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/'/g, "\\'");
 		},
 		capfirst: function(value){
-			// summary: Capitalizes the first character of the value
+			// summary:
+			//		Capitalizes the first character of the value
 			value = "" + value;
 			return value.charAt(0).toUpperCase() + value.substring(1);
 		},
 		center: function(value, arg){
-			// summary: Centers the value in a field of a given width
+			// summary:
+			//		Centers the value in a field of a given width
 			arg = arg || value.length;
 			value = value + "";
 			var diff = arg - value.length;
@@ -53,18 +61,21 @@ define([
 			return value;
 		},
 		cut: function(value, arg){
-			// summary: Removes all values of arg from the given string
+			// summary:
+			//		Removes all values of arg from the given string
 			arg = arg + "" || "";
 			value = value + "";
 			return value.replace(new RegExp(arg, "g"), "");
 		},
 		_fix_ampersands: /&(?!(\w+|#\d+);)/g,
 		fix_ampersands: function(value){
-			// summary: Replaces ampersands with ``&`` entities
-			return value.replace(dojox.dtl.filter.strings._fix_ampersands, "&");
+			// summary:
+			//		Replaces ampersands with ``&`` entities
+			return value.replace(strings._fix_ampersands, "&");
 		},
 		floatformat: function(value, arg){
-			// summary: Format a number according to arg
+			// summary:
+			//		Format a number according to arg
 			// description:
 			//		If called without an argument, displays a floating point
 			//		number as 34.2 -- but only if there's a point to be displayed.
@@ -82,10 +93,11 @@ define([
 			return (arg < 0) ? parseFloat(value) + "" : value;
 		},
 		iriencode: function(value){
-			return dojox.dtl.filter.strings._urlquote(value, "/#%[]=:;$&()+,!");
+			return strings._urlquote(value, "/#%[]=:;$&()+,!");
 		},
 		linenumbers: function(value){
-			// summary: Displays text with line numbers
+			// summary:
+			//		Displays text with line numbers
 			var df = dojox.dtl.filter;
 			var lines = value.split("\n");
 			var output = [];
@@ -105,7 +117,8 @@ define([
 			return value;
 		},
 		lower: function(value){
-			// summary: Converts a string into all lowercase
+			// summary:
+			//		Converts a string into all lowercase
 			return (value + "").toLowerCase();
 		},
 		make_list: function(value){
@@ -139,7 +152,8 @@ define([
 			return value;
 		},
 		slugify: function(value){
-			// summary: Converts to lowercase, removes
+			// summary:
+			//		Converts to lowercase, removes
 			//		non-alpha chars and converts spaces to hyphens
 			value = value.replace(/[^\w\s-]/g, "").toLowerCase();
 			return value.replace(/[\-\s]+/g, "-");
@@ -148,17 +162,18 @@ define([
 		stringformat: function(value, arg){
 			// summary:
 			//		Formats the variable according to the argument, a string formatting specifier.
-			//		This specifier uses Python string formating syntax, with the exception that
+			//		This specifier uses Python string formatting syntax, with the exception that
 			//		the leading "%" is dropped.
 			arg = "" + arg;
-			var strings = dojox.dtl.filter.strings._strings;
-			if(!strings[arg]){
-				strings[arg] = new Sprintf.Formatter("%" + arg);
+			var strs = strings._strings;
+			if(!strs[arg]){
+				strs[arg] = new Sprintf.Formatter("%" + arg);
 			}
-			return strings[arg].format(value);
+			return strs[arg].format(value);
 		},
 		title: function(value){
-			// summary: Converts a string into titlecase
+			// summary:
+			//		Converts a string into titlecase
 			var last, title = "";
 			for(var i = 0, current; i < value.length; i++){
 				current = value.charAt(i);
@@ -173,7 +188,8 @@ define([
 		},
 		_truncatewords: /[ \n\r\t]/,
 		truncatewords: function(value, arg){
-			// summary: Truncates a string after a certain number of words
+			// summary:
+			//		Truncates a string after a certain number of words
 			// arg: Integer
 			//		Number of words to truncate after
 			arg = parseInt(arg, 10);
@@ -183,14 +199,14 @@ define([
 
 			for(var i = 0, j = value.length, count = 0, current, last; i < value.length; i++){
 				current = value.charAt(i);
-				if(dojox.dtl.filter.strings._truncatewords.test(last)){
-					if(!dojox.dtl.filter.strings._truncatewords.test(current)){
+				if(strings._truncatewords.test(last)){
+					if(!strings._truncatewords.test(current)){
 						++count;
 						if(count == arg){
-							return value.substring(0, j + 1);
+							return value.substring(0, j + 1) + ' ...';
 						}
 					}
-				}else if(!dojox.dtl.filter.strings._truncatewords.test(current)){
+				}else if(!strings._truncatewords.test(current)){
 					j = i;
 				}
 				last = current;
@@ -207,7 +223,6 @@ define([
 				return "";
 			}
 
-			var strings = dojox.dtl.filter.strings;
 			var words = 0;
 			var open = [];
 
@@ -254,17 +269,17 @@ define([
 			return value.toUpperCase();
 		},
 		urlencode: function(value){
-			return dojox.dtl.filter.strings._urlquote(value);
+			return strings._urlquote(value);
 		},
 		_urlize: /^((?:[(>]|<)*)(.*?)((?:[.,)>\n]|>)*)$/,
 		_urlize2: /^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$/,
 		urlize: function(value){
-			return dojox.dtl.filter.strings.urlizetrunc(value);
+			return strings.urlizetrunc(value);
 		},
 		urlizetrunc: function(value, arg){
 			arg = parseInt(arg);
 			return Tokenize(value, /(\S+)/g, function(word){
-				var matches = dojox.dtl.filter.strings._urlize.exec(word);
+				var matches = strings._urlize.exec(word);
 				if(!matches){
 					return word;
 				}
@@ -289,7 +304,7 @@ define([
 					return '<a href="http://' + middle + '" rel="nofollow">' + trimmed + '</a>';
 				}else if(startsHttp || startsHttps){
 					return '<a href="' + middle + '" rel="nofollow">' + trimmed + '</a>';
-				}else if(hasAt && !startsWww && !hasColon && dojox.dtl.filter.strings._urlize2.test(middle)){
+				}else if(hasAt && !startsWww && !hasColon && strings._urlize2.test(middle)){
 					return '<a href="mailto:' + middle + '">' + middle + '</a>';
 				}
 				return word;
@@ -302,7 +317,8 @@ define([
 		},
 		wordwrap: function(value, arg){
 			arg = parseInt(arg);
-			// summary: Wraps words at specified line length
+			// summary:
+			//		Wraps words at specified line length
 			var output = [];
 			var parts = value.split(/\s+/g);
 			if(parts.length){
@@ -332,5 +348,6 @@ define([
 			return output.join("");
 		}
 	});
-	return dojox.dtl.filter.strings;
+
+	return strings;
 });
\ No newline at end of file
diff --git a/dojox/dtl/render/dom.js b/dojox/dtl/render/dom.js
index 583d884..0760b65 100644
--- a/dojox/dtl/render/dom.js
+++ b/dojox/dtl/render/dom.js
@@ -5,20 +5,23 @@ define([
 	"../dom",
 	"../_base"
 ], function(lang,dom,ddc,dddom,dd){
+
+	var ddrd = lang.getObject("render.dom", true, dd);
 	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.render.dom", true);
+	 ddrd = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
-	dd.render.dom.Render = function(/*DOMNode?*/ attachPoint, /*dojox.dtl.DomTemplate?*/ tpl){
+	ddrd.Render = function(/*DOMNode?*/ attachPoint, /*dojox/dtl/DomTemplate?*/ tpl){
 		this._tpl = tpl;
 		this.domNode = dom.byId(attachPoint);
-	}
-	lang.extend(dd.render.dom.Render, {
+	};
+	lang.extend(ddrd.Render, {
 		setAttachPoint: function(/*Node*/ node){
 			this.domNode = node;
 		},
-		render: function(/*Object*/ context, /*dojox.dtl.DomTemplate?*/ tpl, /*dojox.dtl.DomBuffer?*/ buffer){
+		render: function(/*Object*/ context, /*dojox/dtl/DomTemplate?*/ tpl, /*dojox/dtl/DomBuffer?*/ buffer){
 			if(!this.domNode){
 				throw new Error("You cannot use the Render object without specifying where you want to render it");
 			}
@@ -33,10 +36,13 @@ define([
 			}
 
 			if(this.domNode !== frag){
-				this.domNode.parentNode.replaceChild(frag, this.domNode);
+				if(this.domNode.parentNode){
+					this.domNode.parentNode.replaceChild(frag, this.domNode);
+				}
 				this.domNode = frag;
 			}
 		}
 	});
-	return dojox.dtl.render.dom;
-});
\ No newline at end of file
+
+	return ddrd;
+});
diff --git a/dojox/dtl/render/html.js b/dojox/dtl/render/html.js
index 55963f4..6f51e5d 100644
--- a/dojox/dtl/render/html.js
+++ b/dojox/dtl/render/html.js
@@ -3,11 +3,15 @@ define([
 	"../render/dom",
 	"../_base"
 ], function(lang,ddrd,dd){
+
+	var ddrh = lang.getObject("render.html", true, dd);
 	/*=====
-		dd = dojox.dtl;
-	=====*/ 
-	lang.getObject("dojox.dtl.render.html", true);
+	 ddrh = {
+	 	// TODO: summary
+	 };
+	 =====*/
+
+	ddrh.Render = ddrd.Render;
 
-	dd.render.html.Render = ddrd.Render;
-	return dojox.dtl.render.html;
+	return ddrh;
 });
diff --git a/dojox/dtl/tag/date.js b/dojox/dtl/tag/date.js
index f41ed8a..7ac7e36 100644
--- a/dojox/dtl/tag/date.js
+++ b/dojox/dtl/tag/date.js
@@ -3,17 +3,20 @@ define([
 	"../_base",
 	"../utils/date"
 ], function(lang,dd,ddud){
+
+	var date = lang.getObject("tag.date", true, dd);
 	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.tag.date", true);
+	 date = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
-	dojox.dtl.tag.date.NowNode = function(format, node){
+	date.NowNode = function(format, node){
 		this._format = format;
 		this.format = new ddud.DateFormat(format);
 		this.contents = node;
-	}
-	lang.extend(dd.tag.date.NowNode, {
+	};
+	lang.extend(date.NowNode, {
 		render: function(context, buffer){
 			this.contents.set(this.format.format(new Date()));
 			return this.contents.render(context, buffer);
@@ -26,13 +29,14 @@ define([
 		}
 	});
 
-	dojox.dtl.tag.date.now = function(parser, token){
+	date.now = function(parser, token){
 		// Split by either :" or :'
 		var parts = token.split_contents();
 		if(parts.length != 2){
 			throw new Error("'now' statement takes one argument");
 		}
-		return new dojox.dtl.tag.date.NowNode(parts[1].slice(1, -1), parser.create_text_node());
+		return new date.NowNode(parts[1].slice(1, -1), parser.create_text_node());
 	};
-	return dojox.dtl.tag.date;
+
+	return date;
 });
diff --git a/dojox/dtl/tag/loader.js b/dojox/dtl/tag/loader.js
index 4d16aee..7097f19 100644
--- a/dojox/dtl/tag/loader.js
+++ b/dojox/dtl/tag/loader.js
@@ -4,12 +4,13 @@ define([
 	"dojo/_base/array",
 	"dojo/_base/connect"
 ], function(lang,dd,array,connect){
-	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.tag.loader", true);
 
-	var ddtl = dd.tag.loader;
+	var ddtl = lang.getObject("tag.loader", true, dd);
+	/*=====
+	 ddtl = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
 	ddtl.BlockNode = lang.extend(function(name, nodelist){
 		this.name = name;
@@ -299,5 +300,6 @@ define([
 			return node;
 		}
 	});
-	return dojox.dtl.tag.loader;
+
+	return ddtl;
 });
\ No newline at end of file
diff --git a/dojox/dtl/tag/logic.js b/dojox/dtl/tag/logic.js
index b085f57..1d712f4 100644
--- a/dojox/dtl/tag/logic.js
+++ b/dojox/dtl/tag/logic.js
@@ -2,13 +2,15 @@ define([
 	"dojo/_base/lang",
 	"../_base"
 ], function(lang, dd){
+
+	var ddtl = lang.getObject("tag.logic", true, dd);
 	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.tag.logic", true);
+	 ddtl = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
 	var ddt = dd.text;
-	var ddtl = dd.tag.logic;
 
 	ddtl.IfNode = lang.extend(function(bools, trues, falses, type){
 		this.bools = bools;
@@ -127,12 +129,6 @@ define([
 			}
 
 			var items = this.loop.resolve(context) || [];
-			for(i = items.length; i < this.pool.length; i++){
-				this.pool[i].unrender(context, buffer, this);
-			}
-			if(this.reversed){
-				items = items.slice(0).reverse();
-			}
 
 			var isObject = lang.isObject(items) && !lang.isArrayLike(items);
 			var arred = [];
@@ -144,6 +140,13 @@ define([
 				arred = items;
 			}
 
+			for(i = arred.length; i < this.pool.length; i++){
+				this.pool[i].unrender(context, buffer, this);
+			}
+			if(this.reversed){
+				arred = arred.slice(0).reverse();
+			}
+
 			var forloop = context.forloop = {
 				parentloop: context.get("forloop", {})
 			};
@@ -276,5 +279,6 @@ define([
 			return new ddtl.ForNode(loopvars, parts[parts.length + index + 1], reversed, nodelist);
 		}
 	});
-	return dojox.dtl.tag.logic;
+
+	return ddtl;
 });
\ No newline at end of file
diff --git a/dojox/dtl/tag/loop.js b/dojox/dtl/tag/loop.js
index 717df7a..c49465b 100644
--- a/dojox/dtl/tag/loop.js
+++ b/dojox/dtl/tag/loop.js
@@ -5,13 +5,13 @@ define([
 	"../_base",
 	"dojox/string/tokenize"
 ], function(lang,array,json,dd,Tokenize){
-	/*=====
-		Tokenize = dojox.string.tokenize;
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.tag.loop", true);
 
-	var ddtl = dd.tag.loop;
+	var ddtl = lang.getObject("tag.loop", true, dd);
+	/*=====
+	 ddtl = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
 	ddtl.CycleNode = lang.extend(function(cyclevars, name, text, shared){
 		this.cyclevars = cyclevars;
@@ -135,7 +135,8 @@ define([
 
 	lang.mixin(ddtl, {
 		cycle: function(parser, token){
-			// summary: Cycle among the given strings each time this tag is encountered
+			// summary:
+			//		Cycle among the given strings each time this tag is encountered
 			var args = token.split_contents();
 
 			if(args.length < 2){
@@ -197,5 +198,6 @@ define([
 			return new ddtl.RegroupNode(expression, key, alias);
 		}
 	});
-	return dojox.dtl.tag.loop;
+
+	return ddtl;
 });
\ No newline at end of file
diff --git a/dojox/dtl/tag/misc.js b/dojox/dtl/tag/misc.js
index 9b4c8b8..b67846b 100644
--- a/dojox/dtl/tag/misc.js
+++ b/dojox/dtl/tag/misc.js
@@ -4,12 +4,13 @@ define([
 	"dojo/_base/connect",
 	"../_base"
 ], function(lang,array,connect,dd){
-	/*=====
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.tag.misc", true);
 
-	var ddtm = dd.tag.misc;
+	var ddtm = lang.getObject("tag.misc", true, dd);
+	/*=====
+	 ddtm = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
 	ddtm.DebugNode = lang.extend(function(text){
 		this.text = text;
@@ -224,16 +225,19 @@ define([
 
 	lang.mixin(ddtm, {
 		comment: function(parser, token){
-			// summary: Ignore everything between {% comment %} and {% endcomment %}
+			// summary:
+			//		Ignore everything between {% comment %} and {% endcomment %}
 			parser.skip_past("endcomment");
 			return dd._noOpNode;
 		},
 		debug: function(parser, token){
-			// summary: Output the current context, maybe add more stuff later.
+			// summary:
+			//		Output the current context, maybe add more stuff later.
 			return new ddtm.DebugNode(parser.create_text_node());
 		},
 		filter: function(parser, token){
-			// summary: Filter the contents of the blog through variable filters.
+			// summary:
+			//		Filter the contents of the blog through variable filters.
 			var rest = token.contents.split(null, 1)[1];
 			var varnode = parser.create_variable_node("var|" + rest);
 			var nodelist = parser.parse(["endfilter"]);
@@ -289,5 +293,6 @@ define([
 			return new ddtm.WithNode(parts[1], parts[3], nodelist);
 		}
 	});
-	return dojox.dtl.tag.misc;
+
+	return ddtm;
 });
\ No newline at end of file
diff --git a/dojox/dtl/tests/module.js b/dojox/dtl/tests/module.js
index f91da1c..96934be 100644
--- a/dojox/dtl/tests/module.js
+++ b/dojox/dtl/tests/module.js
@@ -6,6 +6,7 @@ try{
 	dojo.require("dojox.dtl.tests.dom.tag");
 	dojo.require("dojox.dtl.tests.dom.buffer");
 	dojo.require("dojox.dtl.tests.context");
+	dojo.require("dojox.dtl.tests.templated");
 }catch(e){
 	doh.debug(e);
-}
\ No newline at end of file
+}
diff --git a/dojox/dtl/tests/templated.js b/dojox/dtl/tests/templated.js
new file mode 100644
index 0000000..e75a679
--- /dev/null
+++ b/dojox/dtl/tests/templated.js
@@ -0,0 +1,25 @@
+define(["doh","dojo/_base/declare","dijit/_WidgetBase","dojox/dtl/_Templated"], function(doh, declare, _WidgetBase, _Templated) {
+	var Test = declare([_WidgetBase, _Templated], {
+		templateString: "<div>foo</div>"
+	});
+	doh.register("dojox.dtl.tests._Templated", [
+		function test_create(t) {
+			var ui = Test();
+			t.is("foo", ui.domNode.innerHTML);
+			ui.destroy();
+		},
+		
+		function test_create_multiple(t) {
+			var root = document.createElement("div");
+			var ui1 = Test();
+			var ui2 = Test();
+			ui1.placeAt(root, "last");
+			ui2.placeAt(root, "last");
+			t.is("foo", ui1.domNode.innerHTML);
+			t.is("foo", ui2.domNode.innerHTML);
+			t.is(2, root.children.length, "root should have two children");
+			ui1.destroy();
+			ui2.destroy();
+		}
+	]);
+});
\ No newline at end of file
diff --git a/dojox/dtl/tests/templates/base.html b/dojox/dtl/tests/templates/base.html
index 30b731b..3f66b93 100644
--- a/dojox/dtl/tests/templates/base.html
+++ b/dojox/dtl/tests/templates/base.html
@@ -1 +1 @@
-<div>BaseBefore{% block base %}foo{% endblock %}BaseAfter</div>
\ No newline at end of file
+<div>BaseBefore{% block base %}foo{% endblock %}BaseAfter</div>
diff --git a/dojox/dtl/tests/templates/hello.html b/dojox/dtl/tests/templates/hello.html
index 18e4c1a..0f8c6d9 100644
--- a/dojox/dtl/tests/templates/hello.html
+++ b/dojox/dtl/tests/templates/hello.html
@@ -1 +1 @@
-Hello, <span>{{ person }}</span>
\ No newline at end of file
+Hello, <span>{{ person }}</span>
diff --git a/dojox/dtl/tests/templates/pocket.html b/dojox/dtl/tests/templates/pocket.html
index f78c520..c49ad05 100644
--- a/dojox/dtl/tests/templates/pocket.html
+++ b/dojox/dtl/tests/templates/pocket.html
@@ -1 +1 @@
-{% block pocket %}Hot{% endblock %} Pocket
\ No newline at end of file
+{% block pocket %}Hot{% endblock %} Pocket
diff --git a/dojox/dtl/tests/templates/pocket2.html b/dojox/dtl/tests/templates/pocket2.html
index 547f9a2..6fb3b28 100755
--- a/dojox/dtl/tests/templates/pocket2.html
+++ b/dojox/dtl/tests/templates/pocket2.html
@@ -1 +1 @@
-{% for item in items %}({% block pocket %}Hot{% endblock %}) {% endfor %}Pocket
\ No newline at end of file
+{% for item in items %}({% block pocket %}Hot{% endblock %}) {% endfor %}Pocket
diff --git a/dojox/dtl/tests/text/filter.js b/dojox/dtl/tests/text/filter.js
index 1887efe..bddd023 100644
--- a/dojox/dtl/tests/text/filter.js
+++ b/dojox/dtl/tests/text/filter.js
@@ -165,7 +165,7 @@ doh.register("dojox.dtl.text.filter",
 
 			tpl = new dd.Template('{{ now|date:"z" }}');
 			t.is("0", tpl.render(context));
-		
+
 			tpl = new dd.Template('{{ now|date:"W" }}');
 			t.is("1", tpl.render(context));
 		},
@@ -544,6 +544,8 @@ doh.register("dojox.dtl.text.filter",
 
 			tpl = new dd.Template('{{ now|time }}');
 			t.is(dojox.dtl.utils.date.format(context.now, "P"), tpl.render(context));
+			tpl = new dd.Template('{{ now|time:"g" }}');
+			t.is('12', tpl.render(context));
 		},
 		function test_filter_timesince(t){
 			var dd = dojox.dtl;
@@ -592,17 +594,17 @@ doh.register("dojox.dtl.text.filter",
 			t.is(context.word, tpl.render(context));
 
 			tpl = new dd.Template('{{ word|truncatewords:"1" }}');
-			t.is("potted", tpl.render(context));
+			t.is("potted ...", tpl.render(context));
 
 			tpl = new dd.Template('{{ word|truncatewords:"2" }}');
-			t.is("potted meat", tpl.render(context));
+			t.is("potted meat ...", tpl.render(context));
 
 			tpl = new dd.Template('{{ word|truncatewords:20" }}');
 			t.is(context.word, tpl.render(context));
 
 			context.word = "potted \nmeat   \nwrites  a lot of tests";
 			tpl = new dd.Template('{{ word|truncatewords:"3" }}');
-			t.is("potted \nmeat   \nwrites", tpl.render(context));
+			t.is("potted \nmeat   \nwrites ...", tpl.render(context));
 		},
 		function test_filter_truncatewords_html(t){
 			var dd = dojox.dtl;
@@ -637,6 +639,10 @@ doh.register("dojox.dtl.text.filter",
 
 			var tpl = new dd.Template('{{ "http://homepage.com/~user"|urlencode }}');
 			t.is("http%3A//homepage.com/%7Euser", tpl.render());
+
+			// see http://bugs.dojotoolkit.org/ticket/12932
+			tpl = new dd.Template('{{ "\t"|urlencode }}');
+			t.is("\t", decodeURIComponent(tpl.render()));
 		},
 		function test_filter_urlize(t){
 			var dd = dojox.dtl;
diff --git a/dojox/dtl/tests/text/tag.js b/dojox/dtl/tests/text/tag.js
index 3ec4496..60a3c94 100644
--- a/dojox/dtl/tests/text/tag.js
+++ b/dojox/dtl/tests/text/tag.js
@@ -3,6 +3,13 @@ dojo.provide("dojox.dtl.tests.text.tag");
 dojo.require("dojox.dtl");
 dojo.require("dojox.dtl.Context");
 
+if(!("_getTemplateString" in dojox.dtl.text)){
+	dojox.dtl.text._getTemplateString = dojox.dtl.text.getTemplateString;
+	dojox.dtl.text.getTemplateString = function(file){
+		return dojox.dtl.text._getTemplateString(file).replace(/(\r?\n)$/, ''); // remove optional trailing newline from template HTML file to make testing consistent
+	};
+}
+
 doh.register("dojox.dtl.text.tag",
 	[
 		function test_tag_block_and_extends(t){
diff --git a/dojox/dtl/utils/date.js b/dojox/dtl/utils/date.js
index 6046185..19c79eb 100644
--- a/dojox/dtl/utils/date.js
+++ b/dojox/dtl/utils/date.js
@@ -3,14 +3,16 @@ define([
 	"dojox/date/php",
 	"../_base"
 ], function(lang,ddp,dd){
+
+	var date = lang.getObject("utils.date", true, dd);
 	/*=====
-		ddp = dojox.data.php;
-		dd = dojox.dtl;
-	=====*/
-	lang.getObject("dojox.dtl.utils.date", true);
+	 date = {
+	 	// TODO: summary
+	 };
+	 =====*/
 
-	dd.utils.date.DateFormat = ddp.DateFormat;
-	lang.extend(dd.utils.date.DateFormat, ddp.DateFormat.prototype, {
+	date.DateFormat = ddp.DateFormat;
+	lang.extend(date.DateFormat, ddp.DateFormat.prototype, {
 		f: function(){
 			// summary:
 			//		Time, in 12-hour hours and minutes, with minutes left off if they're zero.
@@ -20,8 +22,9 @@ define([
 			return (!this.date.getMinutes()) ? this.g() : this.g() + ":" + this.i();
 		},
 		N: function(){
-			// summary: Month abbreviation in Associated Press style. Proprietary extension.
-			return dojox.dtl.utils.date._months_ap[this.date.getMonth()];
+			// summary:
+			//		Month abbreviation in Associated Press style. Proprietary extension.
+			return date._months_ap[this.date.getMonth()];
 		},
 		P: function(){
 			// summary:
@@ -75,5 +78,6 @@ define([
 		],
 		_months_ap: ["Jan.", "Feb.", "March", "April", "May", "June", "July", "Aug.", "Sept.", "Oct.", "Nov.", "Dec."]
 	});
-	return dojox.dtl.utils.date;
+
+	return date;
 });
diff --git a/dojox/editor/plugins/AutoSave.js b/dojox/editor/plugins/AutoSave.js
index 2ac43f7..d5f10d4 100644
--- a/dojox/editor/plugins/AutoSave.js
+++ b/dojox/editor/plugins/AutoSave.js
@@ -24,11 +24,13 @@ define([
 	"dojo/string",
 	"dojox/editor/plugins/Save",
 	"dojo/i18n!dojox/editor/plugins/nls/AutoSave"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, manager, popup, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin,
+	Dialog, MenuItem, Menu, Button, ComboButton, ComboBox, _TextBoxMixin, TextBox, TooltipDialog, _Plugin,
+	connect, declare, locale, i18n, string, Save) {
 
 dojo.experimental("dojox.editor.plugins.AutoSave");
 
-dojo.declare("dojox.editor.plugins._AutoSaveSettingDialog", [dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
+var AutoSaveSettingDialog = dojo.declare("dojox.editor.plugins._AutoSaveSettingDialog", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
 	
 	// dialogTitle [public] String
 	//		The tile of the Auto-Save setting dialog
@@ -99,7 +101,7 @@ dojo.declare("dojox.editor.plugins._AutoSaveSettingDialog", [dijit._Widget, diji
 	},
 	
 	hide: function(){
-		// summray:
+		// summary:
 		//		Hide the setting dialog.
 		// tags:
 		//		public
@@ -125,7 +127,7 @@ dojo.declare("dojox.editor.plugins._AutoSaveSettingDialog", [dijit._Widget, diji
 	_onKeyDown: function(evt){
 		// summary:
 		//		Handle the keydown event
-		//	tags:
+		// tags:
 		//		private
 		if(evt.keyCode == dojo.keys.ENTER){
 			this.onOk();
@@ -145,10 +147,10 @@ dojo.declare("dojox.editor.plugins._AutoSaveSettingDialog", [dijit._Widget, diji
 	},
 	
 	_setValueAttr: function(/*String*/ val){
-		//	summary:
+		// summary:
 		//		Set the value attribute if it is acceptable
 		// val:
-		//		The invertal value
+		//		The interval value
 		// tags:
 		//		private
 		if(this._isValidValue(val)){
@@ -175,31 +177,31 @@ dojo.declare("dojox.editor.plugins._AutoSaveSettingDialog", [dijit._Widget, diji
 	}
 });
 
-dojo.declare("dojox.editor.plugins.AutoSave", dojox.editor.plugins.Save, {
+var AutoSave = dojo.declare("dojox.editor.plugins.AutoSave", Save, {
 	// summary:
 	//		This plugin provides the auto save capability to the editor. The
 	//		plugin saves the content of the editor in interval. When
 	//		the save action is performed, the document in the editor frame
 	//		will be posted to the URL provided, or none, if none provided.
 	
-	// url [public]	String
+	// url: [public] String
 	//		The URL to POST the content back to.  Used by the save function.
 	url: "",
 
-	// logErrors [public] boolean
+	// logResults: [public] Boolean
 	//		Boolean flag to indicate that the default action for save and
 	//		error handlers is to just log to console.  Default is true.
 	logResults: true,
 	
-	// interval [public] Number
+	// interval: [public] Number
 	//		The interval to perform the save action.
 	interval: 0,
 	
-	// _iconClassPrefix [private] String
+	// _iconClassPrefix: [private] String
 	//		This prefix of the CSS class
 	_iconClassPrefix: "dijitEditorIconAutoSave",
 	
-	// _MIN [private const] Number
+	// _MIN: [private const] Number
 	//		Default 1 minute
 	_MIN: 60000,
 	
@@ -233,7 +235,7 @@ dojo.declare("dojox.editor.plugins.AutoSave", dojox.editor.plugins.Save, {
 		this._strings = dojo.i18n.getLocalization("dojox.editor.plugins", "AutoSave");
 		this._initButton();
 		
-		this._saveSettingDialog = new dojox.editor.plugins._AutoSaveSettingDialog({
+		this._saveSettingDialog = new AutoSaveSettingDialog({
 			"dialogTitle": this._strings["saveSettingdialogTitle"],
 			"dialogDescription": this._strings["saveSettingdialogDescription"],
 			"paramName": this._strings["saveSettingdialogParamName"],
@@ -417,12 +419,15 @@ dojo.declare("dojox.editor.plugins.AutoSave", dojox.editor.plugins.Save, {
 	}
 });
 
+// For monkey patching
+AutoSave._AutoSaveSettingDialog = AutoSaveSettingDialog;
+
 // Register this plugin.
 dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name == "autosave"){
-		o.plugin = new dojox.editor.plugins.AutoSave({
+		o.plugin = new AutoSave({
 			url: ("url" in o.args) ? o.args.url : "",
 			logResults: ("logResults" in o.args) ? o.args.logResults : true,
 			interval: ("interval" in o.args) ? o.args.interval : 5
@@ -430,6 +435,6 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	}
 });
 
-return dojox.editor.plugins.AutoSave;
+return AutoSave;
 
 });
diff --git a/dojox/editor/plugins/AutoUrlLink.js b/dojox/editor/plugins/AutoUrlLink.js
index 7df79a3..05bc336 100644
--- a/dojox/editor/plugins/AutoUrlLink.js
+++ b/dojox/editor/plugins/AutoUrlLink.js
@@ -2,22 +2,19 @@ define([
 	"dojo",
 	"dijit",
 	"dojox",
-	"dijit/_editor/range",
-	"dijit/_editor/selection",
 	"dijit/_editor/_Plugin",
 	"dijit/form/Button",
-	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/string"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin) {
 
-dojo.declare("dojox.editor.plugins.AutoUrlLink", [dijit._editor._Plugin], {
-	//summary:
+var AutoUrlLink = dojo.declare("dojox.editor.plugins.AutoUrlLink", [_Plugin], {
+	// summary:
 	//		This plugin can recognize a URL like string
 	//		(such as http://www.website.com) and turn it into
 	//		a hyperlink that points to that URL.
 	
-	// _template [private] String
+	// _template: [private] String
 	//		The link template
 	_template: "<a _djrealurl='${url}' href='${url}'>${url}</a>",
 	
@@ -77,6 +74,7 @@ dojo.declare("dojox.editor.plugins.AutoUrlLink", [dijit._editor._Plugin], {
 			isEnter = args ? args.enter : false,
 			ed = this.editor,
 			selection = ed.window.getSelection();
+		console.log("_recognize: isEnter = ", isEnter, ", selection is ", selection,  selection.anchorNode, this._findLastEditingNode(selection.anchorNode))
 			if(selection){
 				var node = isEnter ? this._findLastEditingNode(selection.anchorNode) :
 								(this._saved || selection.anchorNode),
@@ -114,7 +112,7 @@ dojo.declare("dojox.editor.plugins.AutoUrlLink", [dijit._editor._Plugin], {
 					range.setEnd(bm, bmOff);
 					selection.removeAllRanges();
 					selection.addRange(range);
-					dojo.withGlobal(ed.window, "collapse", dijit._editor.selection, []);
+					ed._sCall("collapse", []);
 				}catch(e){}
 			}
 		}
@@ -122,9 +120,9 @@ dojo.declare("dojox.editor.plugins.AutoUrlLink", [dijit._editor._Plugin], {
 	
 	_inLink: function(/*DomNode*/ node){
 		// summary:
-		//		Check if the node is already embraced within a <a>...</a> tag.
+		//		Check if the node is already embraced within a `<a>...</a>` tag.
 		// node:
-		//		The node to be examed.
+		//		The node to be examined.
 		// tags:
 		//		private
 		var editNode = this.editor.editNode,
@@ -225,10 +223,10 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name ===  "autourllink"){
-		o.plugin = new dojox.editor.plugins.AutoUrlLink();
+		o.plugin = new AutoUrlLink();
 	}
 });
 
-return dojox.editor.plugins.AutoUrlLink;
+return AutoUrlLink;
 
 });
diff --git a/dojox/editor/plugins/Blockquote.js b/dojox/editor/plugins/Blockquote.js
index 456e9a2..b97da5b 100755
--- a/dojox/editor/plugins/Blockquote.js
+++ b/dojox/editor/plugins/Blockquote.js
@@ -2,19 +2,17 @@ define([
 	"dojo",
 	"dijit",
 	"dojox",
-	"dijit/_editor/range",
-	"dijit/_editor/selection",
 	"dijit/_editor/_Plugin",
 	"dijit/form/ToggleButton",
 	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/i18n!dojox/editor/plugins/nls/Blockquote"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin) {
 
-dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
-	//	summary:
-	//		This plugin provides Blockquote cabability to the editor.
+var Blockquote = dojo.declare("dojox.editor.plugins.Blockquote", _Plugin, {
+	// summary:
+	//		This plugin provides Blockquote capability to the editor.
 	//		window/tab
 
 	// iconClassPrefix: [const] String
@@ -129,10 +127,8 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 							}
 						}
 						if(bq){
-							dojo.withGlobal(ed.window,
-								"selectElementChildren", dijit._editor.selection, [bq]);
-							dojo.withGlobal(ed.window,
-								"collapse", dijit._editor.selection, [true]);
+							ed._sCall("selectElementChildren", [bq]);
+							ed._sCall("collapse", [true]);
 						}
 					}else{
 						var curNode;
@@ -150,8 +146,7 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 
 						// Try to find the end node.  We have to check the selection junk
 						curNode = start;
-						while(curNode.nextSibling && dojo.withGlobal(ed.window,
-							"inSelection", dijit._editor.selection, [curNode])){
+						while(curNode.nextSibling && ed._sCall("inSelection", [curNode])){
 							curNode = curNode.nextSibling;
 						}
 						end = curNode;
@@ -236,10 +231,8 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 							if(this._isEmpty(bq)){
 								bq.parentNode.removeChild(bq);
 							}else{
-								dojo.withGlobal(ed.window,
-									"selectElementChildren", dijit._editor.selection, [bq]);
-								dojo.withGlobal(ed.window,
-									"collapse", dijit._editor.selection, [true]);
+								ed._sCall("selectElementChildren", [bq]);
+								ed._sCall("collapse", [true]);
 							}
 							bq = null;
 						}
@@ -265,10 +258,8 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 							}
 							elem.parentNode.removeChild(elem);
 							if(lastChild){
-								dojo.withGlobal(ed.window,
-									"selectElementChildren", dijit._editor.selection, [lastChild]);
-								dojo.withGlobal(ed.window,
-									"collapse", dijit._editor.selection, [true]);
+								ed._sCall("selectElementChildren", [lastChild]);
+								ed._sCall("collapse", [true]);
 							}
 						}
 					}else{
@@ -280,8 +271,7 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 						}
 						var selectedNodes = [];
 						var cNode = start;
-						while(cNode && cNode.nextSibling && dojo.withGlobal(ed.window,
-							"inSelection", dijit._editor.selection, [cNode])){
+						while(cNode && cNode.nextSibling && ed._sCall("inSelection", [cNode])){
 							if(cNode.parentNode && this._getTagName(cNode.parentNode) === "blockquote"){
 								cNode = cNode.parentNode;
 							}
@@ -354,7 +344,7 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 
 	_findBlockQuotes: function(nodeList){
 		// summary:
-		//		function to find a ll the blocknode elements in a collection of
+		//		function to find all the blocknode elements in a collection of
 		//		nodes
 		// nodeList:
 		//		The list of nodes.
@@ -514,10 +504,10 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "blockquote"){
-		o.plugin = new dojox.editor.plugins.Blockquote({});
+		o.plugin = new Blockquote({});
 	}
 });
 
-return dojox.editor.plugins.Blockquote;
+return Blockquote;
 
 });
diff --git a/dojox/editor/plugins/Breadcrumb.js b/dojox/editor/plugins/Breadcrumb.js
index a16f32c..1650e74 100755
--- a/dojox/editor/plugins/Breadcrumb.js
+++ b/dojox/editor/plugins/Breadcrumb.js
@@ -4,12 +4,11 @@ define([
 	"dojox",
 	"dijit/_Widget",
 	"dijit/_TemplatedMixin",
+	"dijit/_Contained",
 	"dijit/Toolbar",
 	"dijit/Menu",
 	"dijit/MenuItem",
 	"dijit/MenuSeparator",
-	"dijit/_editor/range",
-	"dijit/_editor/selection",
 	"dijit/_editor/_Plugin",
 	"dijit/form/Button",
 	"dijit/form/ComboButton",
@@ -18,13 +17,14 @@ define([
 	"dojo/i18n",
 	"dojo/string",
 	"dojo/i18n!dojox/editor/plugins/nls/Breadcrumb"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Widget, _TemplatedMixin, _Contained, Toolbar, Menu, MenuItem,
+	MenuSeparator, _Plugin) {
 
 dojo.experimental("dojox.editor.plugins.Breadcrumb");
 
-dojo.declare("dojox.editor.plugins._BreadcrumbMenuTitle",[dijit._Widget, dijit._TemplatedMixin, dijit._Contained],{
+var BreadcrumbMenuTitle = dojo.declare("dojox.editor.plugins._BreadcrumbMenuTitle",[_Widget, _TemplatedMixin, _Contained],{
 	// summary:
-	//		SImple internal, non-clickable, menu entry to act as a menu title bar.
+	//		Simple internal, non-clickable, menu entry to act as a menu title bar.
 	templateString: "<tr><td dojoAttachPoint=\"title\" colspan=\"4\" class=\"dijitToolbar\" style=\"font-weight: bold; padding: 3px;\"></td></tr>",
 
 	menuTitle: "",
@@ -44,17 +44,16 @@ dojo.declare("dojox.editor.plugins._BreadcrumbMenuTitle",[dijit._Widget, dijit._
 });
 
 
-dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
+var Breadcrumb = dojo.declare("dojox.editor.plugins.Breadcrumb", _Plugin,{
 	// summary:
-	//		This plugin provides Breadcrumb cabability to the editor.  When
-	//		As you move around the editor, it updates with your current indention
-	//		depth.
+	//		This plugin provides Breadcrumb capability to the editor. As you move
+	//		around the editor, it updates with your current indention depth.
 
-	//	_menu: [private]
+	// _menu: [private] Object
 	//		The popup menu that is displayed.
 	_menu: null,
 
-	//	breadcrumbBar: [protected]
+	// breadcrumbBar: [protected] dijit/Toolbar
 	//		The toolbar containing the breadcrumb.
 	breadcrumbBar: null,
 
@@ -87,7 +86,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 			});
 			
 			// Build the menu
-			this._menuTitle = new dojox.editor.plugins._BreadcrumbMenuTitle({menuTitle: strings.nodeActions});
+			this._menuTitle = new BreadcrumbMenuTitle({menuTitle: strings.nodeActions});
 			this._selCMenu = new dijit.MenuItem({label: strings.selectContents, onClick: dojo.hitch(this, this._selectContents)});
 			this._delCMenu = new dijit.MenuItem({label: strings.deleteContents, onClick: dojo.hitch(this, this._deleteContents)});
 			this._selEMenu = new dijit.MenuItem({label: strings.selectElement, onClick: dojo.hitch(this, this._selectElement)});
@@ -145,10 +144,8 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 						break;
 				default:
 					try{
-						dojo.withGlobal(this.editor.window,
-							"collapse", dijit._editor.selection, [null]);
-						dojo.withGlobal(this.editor.window,
-							"selectElementChildren", dijit._editor.selection, [this._menuTarget]);
+						this.editor._sCall("collapse", [null]);
+						this.editor._sCall("selectElementChildren", [this._menuTarget]);
 						this.editor.onDisplayChanged();
 					}catch(e){/*squelch*/}
 			}
@@ -161,8 +158,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		if(this._menuTarget){
 			this.editor.beginEditing();
 			this._selectContents();
-			dojo.withGlobal(this.editor.window,
-				"remove", dijit._editor.selection, [this._menuTarget]);
+			this.editor._sCall("remove", [this._menuTarget]);
 			this.editor.endEditing();
 			this._updateBreadcrumb();
 			this.editor.onDisplayChanged();
@@ -174,10 +170,8 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		//		Internal function for selecting the contents of a node.
 		this.editor.focus();
 		if(this._menuTarget){
-			dojo.withGlobal(this.editor.window,
-				"collapse", dijit._editor.selection, [null]);
-			dojo.withGlobal(this.editor.window,
-				"selectElement", dijit._editor.selection, [this._menuTarget]);
+			this.editor._sCall("collapse", [null]);
+			this.editor._sCall("selectElement", [this._menuTarget]);
 			this.editor.onDisplayChanged();
 			
 		}
@@ -189,8 +183,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		if(this._menuTarget){
 			this.editor.beginEditing();
 			this._selectElement();
-			dojo.withGlobal(this.editor.window,
-				"remove", dijit._editor.selection, [this._menuTarget]);
+			this.editor._sCall("remove", [this._menuTarget]);
 			this.editor.endEditing();
 			this._updateBreadcrumb();
 			this.editor.onDisplayChanged();
@@ -203,8 +196,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		this.editor.focus();
 		if(this._menuTarget){
 			this._selectContents();
-			dojo.withGlobal(this.editor.window,
-				"collapse", dijit._editor.selection, [true]);
+			this.editor._sCall("collapse", [true]);
 		}
 	},
 
@@ -214,8 +206,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		this.editor.focus();
 		if(this._menuTarget){
 			this._selectContents();
-			dojo.withGlobal(this.editor.window,
-				"collapse", dijit._editor.selection, [false]);
+			this.editor._sCall("collapse", [false]);
 		}
 	},
 
@@ -231,8 +222,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 				var range = sel.getRangeAt(0);
                 
 				// Check the getSelectedElement call.  Needed when dealing with img tags.
-				var node = dojo.withGlobal(ed.window,
-					"getSelectedElement", dijit._editor.selection) || range.startContainer;
+				var node = ed._sCall("getSelectedElement", []) || range.startContainer;
 				//var node = range.startContainer;
 				var bcList = [];
 
@@ -348,15 +338,18 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 	}
 });
 
+// For monkey patching
+Breadcrumb._BreadcrumbMenuTitle = BreadcrumbMenuTitle;
+
 // Register this plugin.
 dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "breadcrumb"){
-		o.plugin = new dojox.editor.plugins.Breadcrumb({});
+		o.plugin = new Breadcrumb({});
 	}
 });
 
-return dojox.editor.plugins.Breadcrumb;
+return Breadcrumb;
 
 });
diff --git a/dojox/editor/plugins/CollapsibleToolbar.js b/dojox/editor/plugins/CollapsibleToolbar.js
index de45e75..0a3698c 100644
--- a/dojox/editor/plugins/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/CollapsibleToolbar.js
@@ -11,9 +11,9 @@ define([
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/i18n!dojox/editor/plugins/nls/CollapsibleToolbar"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Widget, _TemplatedMixin, _Plugin) {
 
-dojo.declare("dojox.editor.plugins._CollapsibleToolbarButton", [dijit._Widget, dijit._TemplatedMixin], {
+var CollapsibleToolbarButton = dojo.declare("dojox.editor.plugins._CollapsibleToolbarButton", [_Widget, _TemplatedMixin], {
 	// summary:
 	//		Simple internal widget for representing a clickable button for expand/collapse
 	//		with A11Y support.
@@ -45,14 +45,13 @@ dojo.declare("dojox.editor.plugins._CollapsibleToolbarButton", [dijit._Widget, d
 	}
 });
 
-
-dojo.declare("dojox.editor.plugins.CollapsibleToolbar",dijit._editor._Plugin,{
+var CollapsibleToolbar = dojo.declare("dojox.editor.plugins.CollapsibleToolbar", _Plugin, {
 	// summary:
 	//		This plugin provides a weappable toolbar container to allow expand/collapse
 	//		of the editor toolbars.  This plugin should be registered first in most cases to
 	//		avoid conflicts in toolbar construction.
 
-	// _myWidgets: [private] array
+	// _myWidgets: [private] Array
 	//		Container for widgets I allocate that will need to be destroyed.
 	_myWidgets: null,
 
@@ -84,14 +83,14 @@ dojo.declare("dojox.editor.plugins.CollapsibleToolbar",dijit._editor._Plugin,{
 		var menuTd = dojo.create("td", {style: { width: "100%" }, tabindex: -1}, row);
 		var m = dojo.create("span", {style: { width: "100%" }, tabindex: -1}, menuTd);
 
-		var collapseButton = new dojox.editor.plugins._CollapsibleToolbarButton({
+		var collapseButton = new CollapsibleToolbarButton({
 			buttonClass: "dojoxCollapsibleToolbarCollapse",
 			title: strings.collapse,
 			text: "-",
 			textClass: "dojoxCollapsibleToolbarCollapseText"
 		});
 		dojo.place(collapseButton.domNode, openTd);
-		var expandButton = new dojox.editor.plugins._CollapsibleToolbarButton({
+		var expandButton = new CollapsibleToolbarButton({
 			buttonClass: "dojoxCollapsibleToolbarExpand",
 			title: strings.expand,
 			text: "+",
@@ -171,15 +170,18 @@ dojo.declare("dojox.editor.plugins.CollapsibleToolbar",dijit._editor._Plugin,{
 	}
 });
 
+// For monkey patching
+CollapsibleToolbar._CollapsibleToolbarButton = CollapsibleToolbarButton;
+
 // Register this plugin.
 dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "collapsibletoolbar"){
-		o.plugin = new dojox.editor.plugins.CollapsibleToolbar({});
+		o.plugin = new CollapsibleToolbar({});
 	}
 });
 
-return dojox.editor.plugins.CollapsibleToolbar;
+return CollapsibleToolbar;
 
 });
diff --git a/dojox/editor/plugins/EntityPalette.js b/dojox/editor/plugins/EntityPalette.js
index 54f14e1..bb488fe 100755
--- a/dojox/editor/plugins/EntityPalette.js
+++ b/dojox/editor/plugins/EntityPalette.js
@@ -9,25 +9,16 @@ define([
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/i18n!dojox/editor/plugins/nls/latinEntities"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Widget, _TemplatedMixin, _PaletteMixin) {
 
 dojo.experimental("dojox.editor.plugins.EntityPalette");
 
-dojo.declare("dojox.editor.plugins.EntityPalette",
-	[dijit._Widget, dijit._TemplatedMixin, dijit._PaletteMixin],
-	{
+var EntityPalette = dojo.declare("dojox.editor.plugins.EntityPalette", [_Widget, _TemplatedMixin, _PaletteMixin], {
 	// summary:
 	//		A keyboard accessible HTML entity-picking widget (for inserting symbol characters)
 	// description:
 	//		Grid showing various entities, so the user can pick a certain entity.
 	//		Can be used standalone, or as a popup.
-	//
-	// example:
-	// |	<div dojoType="dojox.editor.plugins.EntityPalette"></div>
-	//
-	// example:
-	// |	var picker = new dojox.editor.plugins.EntityPalette({ },srcNode);
-	// |	picker.startup();
 
 	// templateString: [protected] String
 	//		The basic template used to render the palette.
@@ -73,11 +64,11 @@ dojo.declare("dojox.editor.plugins.EntityPalette",
 	//	  Whether the preview pane will be displayed, to show details about the selected entity.
 	showPreview: true,
 
-	// showCode: [public] boolean
+	// showCode: [public] Boolean
 	//		Show the character code for the entity.
 	showCode: false,
 
-	// showentityName: [public] boolean
+	// showEntityName: [public] Boolean
 	//		Show the entity name for the entity.
 	showEntityName: false,
 
@@ -93,7 +84,8 @@ dojo.declare("dojox.editor.plugins.EntityPalette",
 	cellClass: "dojoxEntityPaletteCell",
 
 	postMixInProperties: function(){
-		// Convert hash of entities into two-dimensional rows/columns table (array of arrays)
+		// summary:
+		//		Convert hash of entities into two-dimensional rows/columns table (array of arrays)
 		var choices = dojo.i18n.getLocalization("dojox.editor.plugins", "latinEntities");
 		var numChoices = 0;
 		var entityKey;
@@ -118,7 +110,8 @@ dojo.declare("dojox.editor.plugins.EntityPalette",
 	},
 
 	buildRendering: function(){
-		// Instantiate the template, which makes a skeleton table which we'll insert the entities
+		// summary:
+		//		Instantiate the template, which makes a skeleton table which we'll insert the entities
 		this.inherited(arguments);
 
 		var i18n = dojo.i18n.getLocalization("dojox.editor.plugins", "latinEntities");
@@ -195,7 +188,7 @@ dojo.declare("dojox.editor.plugins.EntityPalette",
 	}
 });
 
-dojo.declare("dojox.editor.plugins.LatinEntity",
+EntityPalette.LatinEntity = dojo.declare("dojox.editor.plugins.LatinEntity",
 	null,
 	{
 		// summary:
@@ -215,8 +208,7 @@ dojo.declare("dojox.editor.plugins.LatinEntity",
 
 		getValue: function(){
 			// summary:
-			//   Returns HTML representing the character, like &
-			//
+			//		Returns HTML representing the character, like &
 			return "&" + this._alias + ";";
 		},
 
@@ -226,6 +218,6 @@ dojo.declare("dojox.editor.plugins.LatinEntity",
 		}
 });
 
-return dojox.editor.plugins.EntityPalette;
+return EntityPalette;
 
 });
diff --git a/dojox/editor/plugins/FindReplace.js b/dojox/editor/plugins/FindReplace.js
index 1352952..c4107c1 100755
--- a/dojox/editor/plugins/FindReplace.js
+++ b/dojox/editor/plugins/FindReplace.js
@@ -17,17 +17,20 @@ define([
 	"dijit/form/Button",
 	"dijit/form/DropDownButton",
 	"dijit/form/ToggleButton",
-	"dojox/editor/plugins/ToolbarLineBreak",
+	"./ToolbarLineBreak",
 	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/string",
 	"dojo/i18n!dojox/editor/plugins/nls/FindReplace"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, manager, popup,
+			_Widget, _TemplatedMixin, _KeyNavContainer, _WidgetsInTemplateMixin, TooltipDialog,
+			Toolbar, CheckBox, _TextBoxMixin, TextBox, _Plugin) {
 
 dojo.experimental("dojox.editor.plugins.FindReplace");
 
-dojo.declare("dojox.editor.plugins._FindReplaceCloseBox", [dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
+var FindReplaceCloseBox = dojo.declare("dojox.editor.plugins._FindReplaceCloseBox",
+	[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
 	// summary:
 	//		Base class for widgets that contains a button labeled X
 	//		to close the tool bar.
@@ -56,8 +59,8 @@ dojo.declare("dojox.editor.plugins._FindReplaceCloseBox", [dijit._Widget, dijit.
 });
 
 
-dojo.declare("dojox.editor.plugins._FindReplaceTextBox",
-	[dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin],{
+var FindReplaceTextBox = dojo.declare("dojox.editor.plugins._FindReplaceTextBox",
+	[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{
 	// summary:
 	//		Base class for widgets that contains a label (like "Font:")
 	//		and a TextBox to pick a value.
@@ -162,8 +165,8 @@ dojo.declare("dojox.editor.plugins._FindReplaceTextBox",
 });
 
 
-dojo.declare("dojox.editor.plugins._FindReplaceCheckBox",
-	[dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin],{
+var FindReplaceCheckBox = dojo.declare("dojox.editor.plugins._FindReplaceCheckBox",
+	[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{
 	// summary:
 	//		Base class for widgets that contains a label (like "Match case: ")
 	//		and a checkbox to indicate if it is checked or not.
@@ -243,7 +246,7 @@ dojo.declare("dojox.editor.plugins._FindReplaceCheckBox",
 });
 
 
-dojo.declare("dojox.editor.plugins._FindReplaceToolbar", dijit.Toolbar, {
+var FindReplaceToolbar = dojo.declare("dojox.editor.plugins._FindReplaceToolbar", Toolbar, {
 	// summary:
 	//		A toolbar that derived from dijit.Toolbar, which
 	//		eliminates some unnecessary event response such as LEFT_ARROW pressing
@@ -274,13 +277,13 @@ dojo.declare("dojox.editor.plugins._FindReplaceToolbar", dijit.Toolbar, {
 	}
 });
 
-dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
-	//	summary:
-	//		This plugin provides a Find/Replace cabability for the editor.
+var FindReplace = dojo.declare("dojox.editor.plugins.FindReplace",[_Plugin],{
+	// summary:
+	//		This plugin provides a Find/Replace capability for the editor.
 	//		Note that this plugin is NOT supported on Opera currently, as opera
 	//		does not implement a window.find or equiv function.
 
-	//	buttonClass: [protected]
+	// buttonClass: [protected]
 	//		Define the class of button the editor uses.
 	buttonClass: dijit.form.ToggleButton,
 
@@ -343,7 +346,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 	_strings: null,
 
 	_initButton: function(){
-		//	summary:
+		// summary:
 		//		Over-ride for creation of the resize button.
 		this._strings = dojo.i18n.getLocalization("dojox.editor.plugins", "FindReplace");
 		this.button = new dijit.form.ToggleButton({
@@ -429,7 +432,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 		//		private
 		var ed = this.editor;
 		var win = ed.window;
-		var selectedTxt = dojo.withGlobal(ed.window, "getSelectedText", dijit._editor.selection, [null]);
+		var selectedTxt = ed._sCall("getSelectedText", [null]);
 		if(this._findField && this._findField.textBox){
 			if(selectedTxt){
 				this._findField.textBox.set("value", selectedTxt);
@@ -448,7 +451,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 		//		public
 		this.inherited(arguments);
 		if(!dojo.isOpera){
-			var _tb = (this._frToolbar = new dojox.editor.plugins._FindReplaceToolbar());
+			var _tb = (this._frToolbar = new FindReplaceToolbar());
 			dojo.style(_tb.domNode, "display", "none");
 			dojo.place(_tb.domNode, toolbar.domNode, "after");
 			_tb.startup();
@@ -456,15 +459,15 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 			// IE6 will put the close box in a new line when its style is "float: right".
 			// So place the close box ahead of the other fields, which makes it align with
 			// the other components.
-			this._closeBox = new dojox.editor.plugins._FindReplaceCloseBox();
+			this._closeBox = new FindReplaceCloseBox();
 			_tb.addChild(this._closeBox);
 			
 			// Define the search/replace fields.
-			this._findField = new dojox.editor.plugins._FindReplaceTextBox(
+			this._findField = new FindReplaceTextBox(
 				{label: this._strings["findLabel"], tooltip: this._strings["findTooltip"]});
 			_tb.addChild(this._findField);
 			
-			this._replaceField = new dojox.editor.plugins._FindReplaceTextBox(
+			this._replaceField = new FindReplaceTextBox(
 				{label: this._strings["replaceLabel"], tooltip: this._strings["replaceTooltip"]});
 			_tb.addChild(this._replaceField);
 
@@ -487,11 +490,11 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 			_tb.addChild(this._replaceAllButton);
 			
 			// Define the option checkboxes.
-			this._caseSensitive = new dojox.editor.plugins._FindReplaceCheckBox(
+			this._caseSensitive = new FindReplaceCheckBox(
 				{label: this._strings["matchCase"], tooltip: this._strings["matchCaseTooltip"]});
 			_tb.addChild(this._caseSensitive);
 			
-			this._backwards = new dojox.editor.plugins._FindReplaceCheckBox(
+			this._backwards = new FindReplaceCheckBox(
 				{label: this._strings["backwards"], tooltip: this._strings["backwardsTooltip"]});
 			_tb.addChild(this._backwards);
 
@@ -611,7 +614,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 			var backwards = this._backwards.get("value");
 			
 			//Replace the current selected text if it matches the pattern
-			var selected = dojo.withGlobal(ed.window, "getSelectedText", dijit._editor.selection, [null]);
+			var selected = ed._sCall("getSelectedText", [null]);
 			// Handle checking/replacing current selection.  For some reason on Moz
 			// leading whitespace is trimmed, so we have to trim it down on this check
 			// or we don't always replace.  Moz bug!
@@ -629,7 +632,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 					// Move to the beginning of the replaced text
 					// to avoid the infinite recursive replace
 					this._findText(repTxt, caseSensitive, backwards);
-					dojo.withGlobal(ed.window, "collapse", dijit._editor.selection, [true]);
+					ed._sCall("collapse", [true]);
 				}
 			}
 			
@@ -756,25 +759,27 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 		// description:
 		//		Returns a regular expression object that conforms to the defined conversion rules.
 		//		For example:
-		//			ca*   -> /^ca.*$/
-		//			*ca*  -> /^.*ca.*$/
-		//			*c\*a*  -> /^.*c\*a.*$/
-		//			*c\*a?*  -> /^.*c\*a..*$/
-		//			and so on.
 		//
+		//		- ca*   -> /^ca.*$/
+		//		- *ca*  -> /^.*ca.*$/
+		//		- *c\*a*  -> /^.*c\*a.*$/
+		//		- *c\*a?*  -> /^.*c\*a..*$/
+		//
+		//		and so on.
 		// pattern: string
 		//		A simple matching pattern to convert that follows basic rules:
-		//			* Means match anything, so ca* means match anything starting with ca
-		//			? Means match single character.  So, b?b will match to bob and bab, and so on.
-		//			\ is an escape character.  So for example, \* means do not treat * as a match, but literal character *.
-		//				To use a \ as a character in the string, it must be escaped.  So in the pattern it should be
-		//				represented by \\ to be treated as an ordinary \ character instead of an escape.
 		//
-		//	ignoreCase:
+		//		- * Means match anything, so ca* means match anything starting with ca
+		//		- ? Means match single character.  So, b?b will match to bob and bab, and so on.
+		//		- \ is an escape character.  So for example, \* means do not treat * as a match, but literal character *.
+		//		  To use a \ as a character in the string, it must be escaped.  So in the pattern it should be
+		//		  represented by \\ to be treated as an ordinary \ character instead of an escape.
+		// ignoreCase:
 		//		An optional flag to indicate if the pattern matching should be treated as case-sensitive or not when comparing
 		//		By default, it is assumed case sensitive.
 		// tags:
 		//		private
+
 		var rxp = "";
 		var c = null;
 		for(var i = 0; i < pattern.length; i++){
@@ -837,16 +842,21 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 	}
 });
 
+// For monkey patching
+FindReplace._FindReplaceCloseBox = FindReplaceCloseBox;
+FindReplace._FindReplaceTextBox = FindReplaceTextBox;
+FindReplace._FindReplaceCheckBox = FindReplaceCheckBox;
+FindReplace._FindReplaceToolbar = FindReplaceToolbar;
 
 // Register this plugin.
 dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name ===  "findreplace"){
-		o.plugin = new dojox.editor.plugins.FindReplace({});
+		o.plugin = new FindReplace({});
 	}
 });
 
-return dojox.editor.plugins.FindReplace;
+return FindReplace;
 
 });
diff --git a/dojox/editor/plugins/InsertAnchor.js b/dojox/editor/plugins/InsertAnchor.js
index 55a81b3..f77b5f6 100755
--- a/dojox/editor/plugins/InsertAnchor.js
+++ b/dojox/editor/plugins/InsertAnchor.js
@@ -2,6 +2,7 @@ define([
 	"dojo",
 	"dijit",
 	"dojox",
+	"dijit/_editor/_Plugin",
 	"dijit/_base/manager",	// TODO: change to dijit/registry, and change dijit.byId to registry.byId
 	"dijit/_editor/range",
 	"dijit/_Templated",
@@ -10,26 +11,24 @@ define([
 	"dijit/form/Select",
 	"dijit/form/Button",
 	"dijit/form/DropDownButton",
-	"dijit/_editor/range",
-	"dijit/_editor/selection",
-	"dijit/_editor/_Plugin",
-	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/string",
+	"dojo/NodeList-dom",
 	"dojox/editor/plugins/ToolbarLineBreak",
 	"dojo/i18n!dojox/editor/plugins/nls/InsertAnchor",
 	"dojo/i18n!dijit/nls/common"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin ) {
 
-dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
+var InsertAnchor = dojo.declare("dojox.editor.plugins.InsertAnchor", _Plugin, {
 	// summary:
 	//		This plugin provides the basis for an insert anchor dialog for the
 	//		dijit.Editor
 	//
 	// description:
 	//		The command provided by this plugin is:
-	//		* insertAnchor
+	//
+	//		- insertAnchor
 
 	// htmlTemplate: [protected] String
 	//		String used for templating the HTML to insert at the desired point.
@@ -42,7 +41,7 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 	// linkDialogTemplate: [private] String
 	//		Template for contents of TooltipDialog to pick URL
 	_template: [
-		"<table><tr><td>",
+		"<table role='presentation'><tr><td>",
 		"<label for='${id}_anchorInput'>${anchor}</label>",
 		"</td><td>",
 		"<input dojoType='dijit.form.ValidationTextBox' required='true' " +
@@ -60,7 +59,8 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 	].join(""),
 
 	_initButton: function(){
-		// Override _Plugin._initButton() to initialize DropDownButton and TooltipDialog.
+		// summary:
+		//		Override _Plugin._initButton() to initialize DropDownButton and TooltipDialog.
 		var _this = this;
 		var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "InsertAnchor", this.lang);
 
@@ -284,8 +284,7 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 			if(a && (a.nodeName && a.nodeName.toLowerCase() !== "a")){
 				// Stll nothing, one last thing to try on IE, as it might be 'img'
 				// and thus considered a control.
-				a = dojo.withGlobal(this.editor.window,
-					"getSelectedElement", dijit._editor.selection, ["a"]);
+				a = this.editor._sCall("getSelectedElement", ["a"]);
 			}
 			if(a && (a.nodeName && a.nodeName.toLowerCase() === "a")){
 				// Okay, we do have a match.  IE, for some reason, sometimes pastes before
@@ -295,8 +294,7 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 				if(this.editor.queryCommandEnabled("unlink")){
 					// Select all the link childent, then unlink.  The following insert will
 					// then replace the selected text.
-					dojo.withGlobal(this.editor.window,
-						"selectElementChildren", dijit._editor.selection, [a]);
+					this.editor._sCall("selectElementChildren", [a]);
 					this.editor.execCommand("unlink");
 				}
 			}
@@ -324,9 +322,9 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 		if(a && a.tagName.toLowerCase() === "a" && dojo.attr(a, "name")){
 			anchor = dojo.attr(a, "name");
 			text = a.textContent || a.innerText;
-			dojo.withGlobal(this.editor.window, "selectElement", dijit._editor.selection, [a, true]);
+			this.editor._sCall("selectElement", [a, true]);
 		}else{
-			text = dojo.withGlobal(this.editor.window, dijit._editor.selection.getSelectedText);
+			text = this.editor._sCall("getSelectedText");
 		}
 		return {anchorInput: anchor || '', textInput: text || ''}; //Object;
 	},
@@ -351,12 +349,10 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 			if(a && (a.nodeName && a.nodeName.toLowerCase() !== "a")){
 				// Stll nothing, one last thing to try on IE, as it might be 'img'
 				// and thus considered a control.
-				a = dojo.withGlobal(this.editor.window,
-					"getSelectedElement", dijit._editor.selection, ["a"]);
+				a = this.editor._sCall("getSelectedElement", ["a"]);
 			}
 		}else{
-			a = dojo.withGlobal(this.editor.window,
-				"getAncestorElement", dijit._editor.selection, ["a"]);
+			a = this.editor._sCall("getAncestorElement", ["a"]);
 		}
 		this.dropDown.reset();
 		this._setButton.set("disabled", true);
@@ -377,9 +373,7 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 			var tg = t.tagName? t.tagName.toLowerCase() : "";
 			if(tg === "a" && dojo.attr(t, "name")){
 				this.editor.onDisplayChanged();
-				dojo.withGlobal(this.editor.window,
-					 "selectElement",
-					 dijit._editor.selection, [t]);
+				this.editor._sCall("selectElement", [t]);
 				setTimeout(dojo.hitch(this, function(){
 					// Focus shift outside the event handler.
 					// IE doesn't like focus changes in event handles.
@@ -401,16 +395,8 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 		//		The node to search from.
 		// tags:
 		//		private
-		var ed = this.editor;
-		dojo.withGlobal(ed.window, function(){
-			dojo.query("a", ed.editNode).forEach(function(a){
-				if(dojo.attr(a, "name") && !dojo.attr(a, "href")){
-					if(!dojo.hasClass(a,"dijitEditorPluginInsertAnchorStyle")){
-						dojo.addClass(a, "dijitEditorPluginInsertAnchorStyle");
-					}
-				}
-			});
-		});
+
+		dojo.query("a[name]:not([href])", this.editor.editNode).addClass("dijitEditorPluginInsertAnchorStyle");
 	},
 
 	_postDomFilter: function(node){
@@ -422,16 +408,9 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 		//		The node to search from.
 		// tags:
 		//		private
-		var ed = this.editor;
-		dojo.withGlobal(ed.window, function(){
-			dojo.query("a", node).forEach(function(a){
-				if(dojo.attr(a, "name") && !dojo.attr(a, "href")){
-					if(dojo.hasClass(a,"dijitEditorPluginInsertAnchorStyle")){
-						dojo.removeClass(a, "dijitEditorPluginInsertAnchorStyle");
-					}
-				}
-			});
-		});
+		if(node){	// avoid error when Editor.get("value") called before editor's iframe initialized
+			dojo.query("a[name]:not([href])", node).removeClass("dijitEditorPluginInsertAnchorStyle");
+		}
 		return node;
 	}
 });
@@ -443,10 +422,10 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	var name = o.args.name;
 	if(name) { name = name.toLowerCase(); }
 	if(name === "insertanchor"){
-		o.plugin = new dojox.editor.plugins.InsertAnchor();
+		o.plugin = new InsertAnchor();
 	}
 });
 
-return dojox.editor.plugins.InsertAnchor;
+return InsertAnchor;
 
 });
diff --git a/dojox/editor/plugins/InsertEntity.js b/dojox/editor/plugins/InsertEntity.js
index 0b9cb8c..c7eb4c0 100755
--- a/dojox/editor/plugins/InsertEntity.js
+++ b/dojox/editor/plugins/InsertEntity.js
@@ -2,8 +2,8 @@ define([
 	"dojo",
 	"dijit",
 	"dojox",
-	"dijit/TooltipDialog",
 	"dijit/_editor/_Plugin",
+	"dijit/TooltipDialog",
 	"dijit/form/DropDownButton",
 	"dojo/_base/connect",
 	"dojo/_base/declare",
@@ -11,9 +11,9 @@ define([
 	"dojox/html/entities",
 	"dojox/editor/plugins/EntityPalette",
 	"dojo/i18n!dojox/editor/plugins/nls/InsertEntity"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin) {
 
-dojo.declare("dojox.editor.plugins.InsertEntity",dijit._editor._Plugin,{
+var InsertEntity = dojo.declare("dojox.editor.plugins.InsertEntity", _Plugin,{
 	// summary:
 	//		This plugin allows the user to select from standard Symbols (HTML Entities)
 	//		to insert at the current cursor position.  It binds to the key pattern:
@@ -21,7 +21,8 @@ dojo.declare("dojox.editor.plugins.InsertEntity",dijit._editor._Plugin,{
 	//
 	// description:
 	//		The commands provided by this plugin are:
-	//		* insertEntity - inserts the selected HTML entity character
+	//
+	//		- insertEntity - inserts the selected HTML entity character
 
 	// iconClassPrefix: [const] String
 	//		The CSS class name for the button node is formed from `iconClassPrefix` and `command`
@@ -95,12 +96,12 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name? o.args.name.toLowerCase() : "";
 	if(name === "insertentity"){
-		o.plugin = new dojox.editor.plugins.InsertEntity({
+		o.plugin = new InsertEntity({
 			showCode: ("showCode" in o.args)?o.args.showCode:false,
 			showEntityName: ("showEntityName" in o.args)?o.args.showEntityName:false
 		});
 	}
 });
 
-return dojox.editor.plugins.InsertEntity;
+return InsertEntity;
 });
diff --git a/dojox/editor/plugins/LocalImage.js b/dojox/editor/plugins/LocalImage.js
index 05a7651..3b9050c 100644
--- a/dojox/editor/plugins/LocalImage.js
+++ b/dojox/editor/plugins/LocalImage.js
@@ -24,70 +24,71 @@ var LocalImage = dojo.declare("dojox.editor.plugins.LocalImage", LinkDialog.ImgL
 	//		This plugin provides an enhanced image link dialog that
 	//		not only insert the online images, but upload the local image files onto
 	//		to server then insert them as well.
-	// Dependencies:
+	//
+	//		Dependencies:
 	//		This plugin depends on dojox.form.FileUploader to upload the images on the local driver.
 	//		Do the regression test whenever FileUploader is upgraded.
 	
-	// uploadable [public] Boolean
+	// uploadable: [public] Boolean
 	//		Indicate whether the user can upload a local image file onto the server.
 	//		If it is set to true, the Browse button will be available.
 	uploadable: false,
 	
-	// uploadUrl [public] String
+	// uploadUrl: [public] String
 	//		The url targeted for uploading. Both absolute and relative URLs are OK.
 	uploadUrl: "",
 	
-	// baseImageUrl [public] String
+	// baseImageUrl: [public] String
 	//		The prefix of the image url on the server.
-	//		For example, an image is uploaded and stored at the following location
-	//			http://www.myhost.com/images/uploads/test.jpg.
+	//		For example, an image is uploaded and stored at
+	//		`http://www.myhost.com/images/uploads/test.jpg`.
 	//		When the image is uploaded, the server returns "uploads/test.jpg" as the
 	//		relative path. So the baseImageUrl should be set to "http://www.myhost.com/images/"
 	//		so that the client can retrieve the image from the server.
 	//		If the image file is located on the same domain as that of the current web page,
 	//		baseImageUrl can be a relative path. For example:
-	//			baseImageUrl = images/
+	// |	baseImageUrl = images/
 	//		and the server returns uploads/test.jpg
 	//		The complete URL of the image file is images/upload/test.jpg
 	baseImageUrl: "",
 	
-	// fileMask [public] String
+	// fileMask: [public] String
 	//		Specify the types of images that are allowed to be uploaded.
 	//		Note that the type checking on server is also very important!
 	fileMask: "*.jpg;*.jpeg;*.gif;*.png;*.bmp",
 	
-	// urlRegExp [protected] String
+	// urlRegExp: [protected] String
 	//		Used to validate if the input is a valid image URL.
 	urlRegExp: "",
 	
-	// htmlFieldName [private] htmlFieldName
+	// htmlFieldName: [private] htmlFieldName
 	htmlFieldName:"uploadedfile",
 	
-	// _isLocalFile [private] Boolean
+	// _isLocalFile: [private] Boolean
 	//		Indicate if a local file is to be uploaded to the server
 	//		If false, the text of _urlInput field is regarded as the
 	//		URL of the online image
 	_isLocalFile: false,
 	
-	// _messages [private] Array<String>
+	// _messages: [private] Array<String>
 	//		Contains i18n strings.
 	_messages: "",
 	
-	// _cssPrefix [private] String
+	// _cssPrefix: [private] String
 	//		The prefix of the CSS style
 	_cssPrefix: "dijitEditorEilDialog",
 	
-	// _closable [private] Boolean
+	// _closable: [private] Boolean
 	//		Indicate if the tooltip dialog can be closed. Used to workaround Safari 5 bug
 	//		where the file dialog doesn't pop up in modal until after the first click.
 	_closable: true,
 	
-	// linkDialogTemplate [protected] String
+	// linkDialogTemplate: [protected] String
 	//		Over-ride for template since this is an enhanced image dialog.
 	linkDialogTemplate: [
 		"<div style='border-bottom: 1px solid black; padding-bottom: 2pt; margin-bottom: 4pt;'></div>", // <hr/> breaks the dialog in IE6
 		"<div class='dijitEditorEilDialogDescription'>${prePopuTextUrl}${prePopuTextBrowse}</div>",
-		"<table><tr><td colspan='2'>",
+		"<table role='presentation'><tr><td colspan='2'>",
 		"<label for='${id}_urlInput' title='${prePopuTextUrl}${prePopuTextBrowse}'>${url}</label>",
 		"</td></tr><tr><td class='dijitEditorEilDialogField'>",
 		"<input dojoType='dijit.form.ValidationTextBox' class='dijitEditorEilDialogField'" +
@@ -286,13 +287,13 @@ var LocalImage = dojo.declare("dojox.editor.plugins.LocalImage", LinkDialog.ImgL
 	},
 	
 	_checkAndFixInput: function(){
-		// summray:
+		// summary:
 		//		Over-ride the original method
 		this._setButton.set("disabled", !this._isValid());
 	},
 	
 	_isValid: function(){
-		// summray:
+		// summary:
 		//		Invalid cases: URL is not ended with the suffix listed
 		return this._urlInput.isValid();
 	},
@@ -303,7 +304,7 @@ var LocalImage = dojo.declare("dojox.editor.plugins.LocalImage", LinkDialog.ImgL
 	},
 	
 	_checkAndSetValue: function(){
-		// summray:
+		// summary:
 		//		Determine if a local file is to be uploaded.
 		//		If a local file is to be uploaded, do not close the dialog
 		//		until the file uploading is finished. Else, insert the image directly into the editor.
@@ -334,8 +335,7 @@ var LocalImage = dojo.declare("dojox.editor.plugins.LocalImage", LinkDialog.ImgL
 	}
 });
 
-// Register this plugin.
-_Plugin.registry["LocalImage"] = function(args){
+var plugin = function(args){
 	return new LocalImage({
 		command: "insertImage",
 		uploadable: ("uploadable" in args) ? args.uploadable : false,
@@ -346,6 +346,11 @@ _Plugin.registry["LocalImage"] = function(args){
 	});
 };
 
+// Register the plugin and some name varients.
+_Plugin.registry["LocalImage"] = plugin;
+_Plugin.registry["localImage"] = plugin;
+_Plugin.registry["localimage"] = plugin;
+
 return LocalImage;
 
 });
diff --git a/dojox/editor/plugins/NormalizeIndentOutdent.js b/dojox/editor/plugins/NormalizeIndentOutdent.js
index 62a8baa..e7db50f 100755
--- a/dojox/editor/plugins/NormalizeIndentOutdent.js
+++ b/dojox/editor/plugins/NormalizeIndentOutdent.js
@@ -2,14 +2,11 @@ define([
 	"dojo",
 	"dijit",
 	"dojox",
-	"dijit/_editor/range",
-	"dijit/_editor/selection",
 	"dijit/_editor/_Plugin",
-	"dojo/_base/connect",
 	"dojo/_base/declare"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin) {
 
-dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin,{
+var NormalizeIndentOutdent = dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent", _Plugin, {
 	// summary:
 	//		This plugin provides improved indent and outdent handling to
 	//		the editor.  It tries to generate valid HTML, as well as be
@@ -190,10 +187,8 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 							end = div.nextSibling;
 						}
 						this._indentElement(div);
-						dojo.withGlobal(ed.window,
-							"selectElementChildren", dijit._editor.selection, [div]);
-						dojo.withGlobal(ed.window,
-							"collapse", dijit._editor.selection, [true]);
+						ed._sCall("selectElementChildren", [div]);
+						ed._sCall("collapse", [true]);
 					}
 				}else{
 					while(node && node !== ed.document && node !== ed.editNode){
@@ -229,7 +224,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 					// that is safely in the range.
 					curNode = start;
 					while(curNode.nextSibling &&
-						dojo.withGlobal(ed.window, "inSelection", dijit._editor.selection, [curNode])){
+						ed._sCall("inSelection", [curNode])){
 						curNode = curNode.nextSibling;
 					}
 					end = curNode;
@@ -530,10 +525,8 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 				}
 
 				// Move cursor.
-				dojo.withGlobal(ed.window,
-					"selectElementChildren", dijit._editor.selection, [listItem]);
-				dojo.withGlobal(ed.window,
-					"collapse", dijit._editor.selection, [true]);
+				ed._sCall("selectElementChildren", [listItem]);
+				ed._sCall("collapse", [true]);
 			}
 		}
 	},
@@ -661,10 +654,8 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 			}
 			
 			// Move our cursor to the list item we moved.
-			dojo.withGlobal(ed.window,
-				"selectElementChildren", dijit._editor.selection, [listItem]);
-			dojo.withGlobal(ed.window,
-				"collapse", dijit._editor.selection, [true]);
+			ed._sCall("selectElementChildren", [listItem]);
+			ed._sCall("collapse", [true]);
 		}else{
 			// Not in a nested list, so we can just defer to the
 			// browser and hope it outdents right.
@@ -767,10 +758,8 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 		// tags:
 		//		private
 		var editDoc = this.editor.document.body;
-		return dojo.withGlobal(this.editor.window, function(){
-			var cs = dojo.getComputedStyle(editDoc);
-			return cs ? cs.direction == "ltr" : true;
-		});
+		var cs = dojo.getComputedStyle(editDoc);
+		return cs ? cs.direction == "ltr" : true;
 	},
 
 	_isInlineFormat: function(tag){
@@ -865,7 +854,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "normalizeindentoutdent"){
-		o.plugin = new dojox.editor.plugins.NormalizeIndentOutdent({
+		o.plugin = new NormalizeIndentOutdent({
 			indentBy: ("indentBy" in o.args) ?
 				(o.args.indentBy > 0 ? o.args.indentBy : 40) :
 				40,
@@ -876,6 +865,6 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	}
 });
 
-return dojox.editor.plugins.NormalizeIndentOutdent;
+return NormalizeIndentOutdent;
 
 });
diff --git a/dojox/editor/plugins/NormalizeStyle.js b/dojox/editor/plugins/NormalizeStyle.js
index 8f1b8c2..33e2490 100755
--- a/dojox/editor/plugins/NormalizeStyle.js
+++ b/dojox/editor/plugins/NormalizeStyle.js
@@ -2,26 +2,26 @@ define([
 	"dojo",
 	"dijit",
 	"dojox",
-	"dijit/_editor/html",
 	"dijit/_editor/_Plugin",
+	"dijit/_editor/html",
 	"dojo/_base/connect",
 	"dojo/_base/declare"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin, editorHtml) {
 
-dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
+var NormalizeStyle = dojo.declare("dojox.editor.plugins.NormalizeStyle", _Plugin,{
 	// summary:
-	//		This plugin provides NormalizeStyle cabability to the editor.  It is
+	//		This plugin provides NormalizeStyle capability to the editor.  It is
 	//		a headless plugin that tries to normalize how content is styled when
 	//		it comes out of th editor ('b' or css).   It also auto-converts
 	//		incoming content to the proper one expected by the browser as well so
 	//		that the native styling buttons work.
 
-	// mode [public] String
+	// mode: [public] String
 	//		A String variable indicating if it should use semantic tags 'b', 'i', etc, or
 	//		CSS styling.  The default is semantic.
 	mode: "semantic",
 
-	// condenseSpans [public] Boolean
+	// condenseSpans: [public] Boolean
 	//		A boolean variable indicating if it should try to condense
 	//		'span''span''span' styles  when in css mode
 	//		The default is true, it will try to combine where it can.
@@ -78,7 +78,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 		// tags:
 		//		private
 		if(node){
-			var w = this.editor.window;
+			var doc = this.editor.document;
 			var self = this;
 			var convertNode = function(cNode){
 				if(cNode.nodeType == 1){
@@ -119,14 +119,14 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 								case "700":
 								case "800":
 								case "900":
-									sTag = dojo.withGlobal(w, "create", dojo, ["b", {}] );
+									sTag = doc.createElement("b");
 									cNode.style.fontWeight = "";
 									break;
 							}
 							cNode = wrapNodes(sTag, cNode);
 							sTag = null;
 							if(fs == "italic"){
-								sTag = dojo.withGlobal(w, "create", dojo, ["i", {}] );
+								sTag = doc.createElement("i");
 								cNode.style.fontStyle = "";
 							}
 							cNode = wrapNodes(sTag, cNode);
@@ -137,10 +137,10 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 								dojo.forEach(da, function(s){
 									switch(s){
 										case "underline":
-											sTag = dojo.withGlobal(w, "create", dojo, ["u", {}] );
+											sTag = doc.createElement("u");
 											break;
 										case "line-through":
-											sTag = dojo.withGlobal(w, "create", dojo, ["strike", {}] );
+											sTag = doc.createElement("strike");
 											break;
 									}
 									count++;
@@ -208,7 +208,8 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 								if(!size){
 									size = 3;
 								}
-								sTag = dojo.withGlobal(w, "create", dojo, ["font", {size: size}] );
+								sTag = doc.createElement("font");
+								sTag.setAttribute("size", size);
 								cNode.style.fontSize = "";
 							}
 							cNode = wrapNodes(sTag, cNode);
@@ -218,13 +219,15 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 								// Also, don't move it in if the background color is set on a block style node,
 								// as it won't color properly once put on inline font.
 								bc = new dojo.Color(bc).toHex();
-								sTag = dojo.withGlobal(w, "create", dojo, ["font", {style: {backgroundColor: bc}}] );
+								sTag = doc.createElement("font");
+								sTag.style.backgroundColor = bc;
 								cNode.style.backgroundColor = "";
 							}
 							if(c && tag !== "font"){
 								// IE doesn't like non-font background color crud.
 								c = new dojo.Color(c).toHex();
-								sTag = dojo.withGlobal(w, "create", dojo, ["font", {color: c}] );
+								sTag = doc.createElement("font");
+								sTag.setAttribute("color", c);
 								cNode.style.color = "";
 							}
 							cNode = wrapNodes(sTag, cNode);
@@ -253,35 +256,30 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 		// tags:
 		//		Protected.
 		var w = this.editor.window;
-		var nodes = dojo.withGlobal(w, function() {
-			return dojo.query("em,s,strong", node);
-		});
-		if(nodes && nodes.length){
-			dojo.forEach(nodes, function(n){
-				if(n){
-					var tag = n.tagName?n.tagName.toLowerCase():"";
-					var tTag;
-					switch(tag){
-						case "s":
-								tTag = "strike";
-								break;
-						case "em":
-								tTag = "i";
-								break;
-						case "strong":
-								tTag = "b";
-								break;
-					}
-					if(tTag){
-						var nNode = dojo.withGlobal(w, "create", dojo, [tTag, null, n, "before"] );
-						while(n.firstChild){
-							nNode.appendChild(n.firstChild);
-						}
-						n.parentNode.removeChild(n);
-					}
+		var doc = this.editor.document;
+		dojo.query("em,s,strong", node).forEach(function(n){
+			var tag = n.tagName?n.tagName.toLowerCase():"";
+			var tTag;
+			switch(tag){
+				case "s":
+						tTag = "strike";
+						break;
+				case "em":
+						tTag = "i";
+						break;
+				case "strong":
+						tTag = "b";
+						break;
+			}
+			if(tTag){
+				var nNode = doc.createElement(tTag);
+				dojo.place("<"+tTag+">", n, "before");
+				while(n.firstChild){
+					nNode.appendChild(n.firstChild);
 				}
-			});
-		}
+				n.parentNode.removeChild(n);
+			}
+		});
 		return node;
 	},
 
@@ -295,7 +293,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 		// tags:
 		//		private
 		if(node){
-			var w = this.editor.window;
+			var doc = this.editor.document;
 			var convertNode = function(cNode) {
 				if(cNode.nodeType == 1){
 					if(cNode.id !== "dijitEditorBody"){
@@ -305,18 +303,22 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 							switch(tag){
 								case "b":
 								case "strong": // Mainly IE
-									span = dojo.withGlobal(w, "create", dojo, ["span", {style: {"fontWeight": "bold"}}] );
+									span = doc.createElement("span");
+									span.style.fontWeight = "bold";
 									break;
 								case "i":
 								case "em": // Mainly IE
-									span = dojo.withGlobal(w, "create", dojo, ["span", {style: {"fontStyle": "italic"}}] );
+									span = doc.createElement("span");
+									span.style.fontStyle = "italic";
 									break;
 								case "u":
-									span = dojo.withGlobal(w, "create", dojo, ["span", {style: {"textDecoration": "underline"}}] );
+									span = doc.createElement("span");
+									span.style.textDecoration = "underline";
 									break;
 								case "strike":
 								case "s": // Mainly WebKit.
-									span = dojo.withGlobal(w, "create", dojo, ["span", {style: {"textDecoration": "line-through"}}] );
+									span = doc.createElement("span");
+									span.style.textDecoration = "line-through";
 									break;
 								case "font": // Try to deal with colors
 									var styles = {};
@@ -344,7 +346,8 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 									if(dojo.attr(cNode, "size")){
 										styles.fontSize = sizeMap[dojo.attr(cNode, "size")];
 									}
-									span = dojo.withGlobal(w, "create", dojo, ["span", {style: styles}] );
+									span = doc.createElement("span");
+									dojo.style(span, styles);
 									break;
 							}
 							if(span){
@@ -524,10 +527,11 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 		// tags:
 		//		private
 		if(html){
-			var div = this.editor.document.createElement("div");
+			var doc = this.editor.document;
+			var div = doc.createElement("div");
 			div.innerHTML = html;
 			div = this._browserFilter(div);
-			html = dijit._editor.getChildrenHtml(div);
+			html = editorHtml.getChildrenHtml(div);
 			div.innerHTML = "";
 
 			// Call the over-ride, or if not available, just execute it.
@@ -546,13 +550,13 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "normalizestyle"){
-		o.plugin = new dojox.editor.plugins.NormalizeStyle({
+		o.plugin = new NormalizeStyle({
 			mode: ("mode" in o.args)?o.args.mode:"semantic",
 			condenseSpans: ("condenseSpans" in o.args)?o.args.condenseSpans:true
 		});
 	}
 });
 
-return dojox.editor.plugins.NormalizeStyle;
+return NormalizeStyle;
 
 });
diff --git a/dojox/editor/plugins/PageBreak.js b/dojox/editor/plugins/PageBreak.js
index 59cafbe..a4405d2 100755
--- a/dojox/editor/plugins/PageBreak.js
+++ b/dojox/editor/plugins/PageBreak.js
@@ -2,23 +2,22 @@ define([
 	"dojo",
 	"dijit",
 	"dojox",
-	"dijit/form/Button",
 	"dijit/_editor/_Plugin",
+	"dijit/form/Button",
 	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/i18n!dojox/editor/plugins/nls/PageBreak"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin) {
 
-dojo.declare("dojox.editor.plugins.PageBreak",dijit._editor._Plugin,{
-	//	summary:
+var PageBreak = dojo.declare("dojox.editor.plugins.PageBreak", _Plugin, {
+	// summary:
 	//		This plugin provides a simple CSS page break plugin that
-	//		lets you insert browser pring recognizable page breaks in
+	//		lets your insert browser print recognizable page breaks in
 	//		the document.
 	//		This plugin registers the hotkey command: CTRL-SHIFT-ENTER
 
-	//	useDefaultCommand [protected]
-	//		Over-ride indicating that the command processing is done all by this plugin.
+	// Over-ride indicating that the command processing is done all by this plugin.
 	useDefaultCommand: false,
 
 	// iconClassPrefix: [const] String
@@ -35,7 +34,7 @@ dojo.declare("dojox.editor.plugins.PageBreak",dijit._editor._Plugin,{
 	_pbContent: "<hr style='page-break-after: always;' class='dijitEditorPageBreak'>",
 
 	_initButton: function(){
-		//	summary:
+		// summary:
 		//		Over-ride for creation of the resize button.
 		var ed = this.editor;
 		var strings = dojo.i18n.getLocalization("dojox.editor.plugins", "PageBreak");
@@ -149,7 +148,7 @@ dojo.declare("dojox.editor.plugins.PageBreak",dijit._editor._Plugin,{
 		//		private
 		var ed = this.editor;
 		var doc = ed.document;
-		var node = ed._sCall("getSelectedElement", null) || ed._sCall("getParentElement", null);
+		var node = ed._sCall("getSelectedElement", []) || ed._sCall("getParentElement", []);
 		while(node && node !== doc.body && node !== doc.html){
 			if(ed._sCall("isTag", [node, this._unbreakableNodes])){
 				return false;
@@ -165,10 +164,10 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "pagebreak"){
-		o.plugin = new dojox.editor.plugins.PageBreak({});
+		o.plugin = new PageBreak({});
 	}
 });
 
-return dojox.editor.plugins.PageBreak;
+return PageBreak;
 
 });
diff --git a/dojox/editor/plugins/PasteFromWord.js b/dojox/editor/plugins/PasteFromWord.js
index e3af559..5aefe73 100755
--- a/dojox/editor/plugins/PasteFromWord.js
+++ b/dojox/editor/plugins/PasteFromWord.js
@@ -2,8 +2,8 @@ define([
 	"dojo",
 	"dijit",
 	"dojox",
-	"dijit/_base/manager",
 	"dijit/_editor/_Plugin",
+	"dijit/_base/manager",
 	"dijit/_editor/RichText",
 	"dijit/form/Button",
 	"dijit/Dialog",
@@ -12,12 +12,14 @@ define([
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/string",
-	"dojo/i18n!dojox/editor/plugins/nls/PasteFromWord"
-], function(dojo, dijit, dojox) {
+	"dojo/i18n!dojox/editor/plugins/nls/PasteFromWord",
+	"dojo/i18n!dijit/nls/common",
+	"dojo/i18n!dijit/_editor/nls/commands"
+], function(dojo, dijit, dojox, _Plugin) {
 
-dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
+var PasteFromWord = dojo.declare("dojox.editor.plugins.PasteFromWord", _Plugin, {
 	// summary:
-	//		This plugin provides PasteFromWord cabability to the editor.  When
+	//		This plugin provides PasteFromWord capability to the editor.  When
 	//		clicked, a dialog opens with a spartan RichText instance to paste
 	//		word content into via the keyboard commands.  The contents are
 	//		then filtered to remove word style classes and other meta-junk
@@ -45,7 +47,7 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 							"<td align='center'>",
 								"<button type='button' dojoType='dijit.form.Button' id='${uId}_paste'>${paste}</button>",
 								" ",
-								"<button type='button' dojoType='dijit.form.Button' id='${uId}_cancel'>${cancel}</button>",
+								"<button type='button' dojoType='dijit.form.Button' id='${uId}_cancel'>${buttonCancel}</button>",
 							"</td>",
 						"</tr>",
 					"</tbody>",
@@ -70,15 +72,19 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 		// Strip out styles containing mso defs and margins, as likely added in IE and are not good to have as it mangles presentation.
 		{regexp: /(style="[^"]*mso-[^;][^"]*")|(style="margin:\s*[^;"]*;")/gi, handler: ""},
 		// Scripts (if any)
-		{regexp: /(<\s*script[^>]*>((.|\s)*?)<\\?\/\s*script\s*>)|(<\s*script\b([^<>]|\s)*>?)|(<[^>]*=(\s|)*[("|')]javascript:[^$1][(\s|.)]*[$1][^>]*>)/ig, handler: ""}
+		{regexp: /(<\s*script[^>]*>((.|\s)*?)<\\?\/\s*script\s*>)|(<\s*script\b([^<>]|\s)*>?)|(<[^>]*=(\s|)*[("|')]javascript:[^$1][(\s|.)]*[$1][^>]*>)/ig, handler: ""},
+		// Word 10 odd o:p tags.
+		{regexp: /<(\/?)o\:p[^>]*>/gi, handler: ""}
 	],
 
 	_initButton: function(){
-		this._filters = this._filters.slice(0); 
-		
 		// summary:
 		//		Over-ride for creation of the save button.
+		this._filters = this._filters.slice(0); 
+			
 		var strings = dojo.i18n.getLocalization("dojox.editor.plugins", "PasteFromWord");
+		dojo.mixin(strings, dojo.i18n.getLocalization("dijit", "common"));
+		dojo.mixin(strings, dojo.i18n.getLocalization("dijit._editor", "commands"));
 		this.button = new dijit.form.Button({
 			label: strings["pasteFromWord"],
 			showLabel: false,
@@ -97,7 +103,7 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 		this._dialog.set("content", dojo.string.substitute(this._template, strings));
 
 		// Make it translucent so we can fade in the window when the RTE is created.
-		// the RTE has to be created 'visible, and this is a ncie trick to make the creation
+		// the RTE has to be created 'visible, and this is a nice trick to make the creation
 		// 'pretty'.
 		dojo.style(dojo.byId(this._uId + "_rte"), "opacity", 0.001);
 
@@ -133,6 +139,7 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 			// dialog is showing up.
 			setTimeout(dojo.hitch(this, function() {
 				this._rte = new dijit._editor.RichText({height: this.height || "300px"}, this._uId + "_rte");
+				this._rte.startup();
 				this._rte.onLoadDeferred.addCallback(dojo.hitch(this, function() {
 					dojo.animateProperty({
 						node: this._rte.domNode, properties: { opacity: { start: 0.001, end: 1.0 } }
@@ -168,6 +175,7 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 		content = dojox.html.format.prettyPrint(content);
 
 		// Paste it in.
+		this.editor.focus();
 		this.editor.execCommand("inserthtml", content);
 	},
 
@@ -212,12 +220,12 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "pastefromword"){
-		o.plugin = new dojox.editor.plugins.PasteFromWord({
+		o.plugin = new PasteFromWord({
 			width: ("width" in o.args)?o.args.width:"400px",
 			height: ("height" in o.args)?o.args.width:"300px"
 		});
 	}
 });
 
-return dojox.editor.plugins.PasteFromWord;
+return PasteFromWord;
 });
diff --git a/dojox/editor/plugins/PrettyPrint.js b/dojox/editor/plugins/PrettyPrint.js
index 9acc489..268cbaf 100755
--- a/dojox/editor/plugins/PrettyPrint.js
+++ b/dojox/editor/plugins/PrettyPrint.js
@@ -6,31 +6,30 @@ define([
 	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojox/html/format"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin) {
 
-dojo.declare("dojox.editor.plugins.PrettyPrint",dijit._editor._Plugin,{
+var PrettyPrint = dojo.declare("dojox.editor.plugins.PrettyPrint", _Plugin,{
 	// summary:
 	//		This plugin provides a mechanism by which to 'beautify HTML'
 	//		generated by the editor.  It is by no means perfect.
 
-	// indentBy [public] Integer
+	// indentBy: [public] Integer
 	//		The indentBy property configures if the plugin should use a
 	//		set number of spaces for indent (between 1-5), or just tab.
 	//		The default value is -1, which means tab.
 	indentBy: -1,
 
-	// lineLength [public] Integer
+	// lineLength: [public] Integer
 	//		The lineLength property configures if the plugin should break up long
 	//		text lines into N lines of 'lineLength' length.  This parameter does not
 	//		take into account indention depth, only text line length.  The default is -1
 	//		which means unlimited line length.
 	lineLength: -1,
 
-	//	useDefaultCommand [protected]
-	//		Over-ride indicating that the command processing is done all by this plugin.
+	// Over-ride indicating that the command processing is done all by this plugin.
 	useDefaultCommand: false,
 	
-	// map [public] Array
+	// map: [public] Array
 	//		An array of arrays that define out entity character to encoding mappings.
 	//		see the dojox.html.entities definitions for more details.  The default is
 	//		HTML + cent, pound, yen, ellipsis, copyright, registered trademark.
@@ -91,7 +90,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "prettyprint"){
-		o.plugin = new dojox.editor.plugins.PrettyPrint({
+		o.plugin = new PrettyPrint({
 			indentBy: ("indentBy" in o.args)?o.args.indentBy:-1,
 			lineLength: ("lineLength" in o.args)?o.args.lineLength:-1,
 			entityMap: ("entityMap" in o.args)?o.args.entityMap:dojox.html.entities.html.concat([
@@ -104,4 +103,6 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	}
 });
 
+return PrettyPrint;
+
 });
diff --git a/dojox/editor/plugins/Preview.js b/dojox/editor/plugins/Preview.js
index ef200ce..8ace90b 100755
--- a/dojox/editor/plugins/Preview.js
+++ b/dojox/editor/plugins/Preview.js
@@ -2,22 +2,21 @@ define([
 	"dojo",
 	"dijit",
 	"dojox",
-	"dijit/form/Button",
 	"dijit/_editor/_Plugin",
+	"dijit/form/Button",
 	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/i18n!dojox/editor/plugins/nls/Preview"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin) {
 
-dojo.declare("dojox.editor.plugins.Preview",dijit._editor._Plugin,{
-	//	summary:
-	//		This plugin provides Preview cabability to the editor.  When
+var Preview = dojo.declare("dojox.editor.plugins.Preview", _Plugin, {
+	// summary:
+	//		This plugin provides Preview capability to the editor.  When
 	//		clicked, the document in the editor frame will displayed in a separate
 	//		window/tab
 
-	//	useDefaultCommand [protected]
-	//		Over-ride indicating that the command processing is done all by this plugin.
+	// Over-ride indicating that the command processing is done all by this plugin.
 	useDefaultCommand: false,
 
 	// styles: [public] String
@@ -95,13 +94,13 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "preview"){
-		o.plugin = new dojox.editor.plugins.Preview({
+		o.plugin = new Preview({
 			styles: ("styles" in o.args)?o.args.styles:"",
 			stylesheets: ("stylesheets" in o.args)? o.args.stylesheets:null
 		});
 	}
 });
 
-return dojox.editor.plugins.Preview;
+return Preview;
 
 });
diff --git a/dojox/editor/plugins/ResizeTableColumn.js b/dojox/editor/plugins/ResizeTableColumn.js
index 0079243..b8f18ca 100644
--- a/dojox/editor/plugins/ResizeTableColumn.js
+++ b/dojox/editor/plugins/ResizeTableColumn.js
@@ -1,9 +1,13 @@
-dojo.provide("dojox.editor.plugins.ResizeTableColumn");
+define([
+	"dojo",
+	"dijit",
+	"dojox",
+	"./TablePlugins"
+], function(dojo, dijit, dojox, TablePlugins) {
 
-dojo.require("dojox.editor.plugins.TablePlugins");
 
-dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.TablePlugins, {
-		
+	var ResizeTableColumn = dojo.declare("dojox.editor.plugins.ResizeTableColumn",	TablePlugins, {
+
 		constructor: function(){
 			// summary:
 			//		Because IE will ignore the cursor style when the editMode of the document is on,
@@ -31,7 +35,7 @@ dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.Tabl
 			// should be called when it is loaded.
 			editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
 				this.connect(this.editor.editNode, "onmousemove", function(evt){
-					var editorCoords = dojo.coords(editor.iframe, true),
+					var editorCoords = dojo.position(editor.iframe, true),
 						ex = editorCoords.x, cx = evt.clientX;
 					
 					if(!this.isDragging){
@@ -41,7 +45,7 @@ dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.Tabl
 						var obj = evt.target;
 						
 						if(obj.tagName && obj.tagName.toLowerCase() == "td"){
-							var objCoords = dojo.coords(obj), ox = objCoords.x, ow = objCoords.w,
+							var objCoords = dojo.position(obj), ox = objCoords.x, ow = objCoords.w,
 								pos = ex + objCoords.x - 2;
 							if(this.isLtr){
 								ruleDiv.headerColumn = true;
@@ -73,13 +77,13 @@ dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.Tabl
 					}else{
 						// Begin to drag&drop
 						var activeCell = this.activeCell,
-							activeCoords = dojo.coords(activeCell), ax = activeCoords.x, aw = activeCoords.w,
+							activeCoords = dojo.position(activeCell), ax = activeCoords.x, aw = activeCoords.w,
 							sibling = nextSibling(activeCell), siblingCoords, sx, sw,
-							containerCoords = dojo.coords(getTable(activeCell).parentNode),
+							containerCoords = dojo.position(getTable(activeCell).parentNode),
 							ctx = containerCoords.x, ctw = containerCoords.w;
 						
 						if(sibling){
-							siblingCoords = dojo.coords(sibling);
+							siblingCoords = dojo.position(sibling);
 							sx = siblingCoords.x;
 							sw = siblingCoords.w;
 						}
@@ -97,8 +101,8 @@ dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.Tabl
 				});
 				
 				this.connect(ruleDiv, "onmousedown", function(evt){
-					var editorCoords = dojo.coords(editor.iframe, true),
-						tableCoords = dojo.coords(getTable(this.activeCell));
+					var editorCoords = dojo.position(editor.iframe, true),
+						tableCoords = dojo.position(getTable(this.activeCell));
 					
 					this.isDragging = true;
 					dojo.style(editor.editNode, {cursor: "col-resize"});
@@ -113,10 +117,10 @@ dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.Tabl
 				
 				this.connect(ruleDiv, "onmouseup", function(evt){
 					var activeCell = this.activeCell,
-						activeCoords = dojo.coords(activeCell), aw = activeCoords.w, ax = activeCoords.x,
+						activeCoords = dojo.position(activeCell), aw = activeCoords.w, ax = activeCoords.x,
 						sibling = nextSibling(activeCell), siblingCoords, sx, sw,
-						editorCoords = dojo.coords(editor.iframe), ex = editorCoords.x,
-						table = getTable(activeCell), tableCoords = dojo.coords(table),
+						editorCoords = dojo.position(editor.iframe), ex = editorCoords.x,
+						table = getTable(activeCell), tableCoords = dojo.position(table),
 						cs = table.getAttribute("cellspacing"),
 						cx = evt.clientX,
 						headerCell = getHeaderCell(activeCell), headerSibling,
@@ -125,7 +129,7 @@ dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.Tabl
 					if(!cs || (cs = parseInt(cs, 10)) < 0){ cs = 2; }
 					
 					if(sibling){
-						siblingCoords = dojo.coords(sibling);
+						siblingCoords = dojo.position(sibling);
 						sx = siblingCoords.x;
 						sw = siblingCoords.w;
 						headerSibling = getHeaderCell(sibling);
@@ -161,9 +165,9 @@ dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.Tabl
 					}
 					// Do it again to consolidate the result,
 					// because maybe the cell cannot be so narrow as you specified.
-					marginBox(headerCell, dojo.coords(activeCell).w);
+					marginBox(headerCell, dojo.position(activeCell).w);
 					if(sibling){
-						marginBox(headerSibling, dojo.coords(sibling).w);
+						marginBox(headerSibling, dojo.position(sibling).w);
 					}
 					dojo.style(editor.editNode, {cursor: "auto"});
 					dojo.style(ruleDiv, {display: "none", top: "-10000px"});
@@ -180,7 +184,7 @@ dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.Tabl
 				// b:
 				//		Indicate if the cell node is compared with the first coluln
 				//		or the last column
-				var nodes = dojo.withGlobal(editor.window, "query", dojo, ["> td", n.parentNode]);
+				var nodes = dojo.query("> td", n.parentNode);
 				switch(b){
 					case "first":
 						return nodes[0] == n;
@@ -221,10 +225,10 @@ dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.Tabl
 				//		column with the node t.
 				// t:
 				//		The node of the table cell
-				var tds = dojo.withGlobal(editor.window, "query", dojo, ["td", getTable(t)]),
+				var tds = dojo.query("td", getTable(t)),
 					len = tds.length;
 				for(var i = 0; i < len; i++){
-					if(dojo.coords(tds[i]).x == dojo.coords(t).x){
+					if(dojo.position(tds[i]).x == dojo.position(t).x){
 						return tds[i];
 					}
 				}
@@ -276,15 +280,18 @@ dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.Tabl
 				}
 			}
 		}
-});
+	});
 
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	// make first character lower case
-	if(o.args && o.args.command){
-		var cmd = o.args.command.charAt(0).toLowerCase() + o.args.command.substring(1, o.args.command.length);
-		if(cmd == "resizeTableColumn"){
-			o.plugin = new dojox.editor.plugins.ResizeTableColumn({commandName: cmd});
+	dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+		if(o.plugin){ return; }
+		// make first character lower case
+		if(o.args && o.args.command){
+			var cmd = o.args.command.charAt(0).toLowerCase() + o.args.command.substring(1, o.args.command.length);
+			if(cmd == "resizeTableColumn"){
+				o.plugin = new ResizeTableColumn({commandName: cmd});
+			}
 		}
-	}
+	});
+
+	return ResizeTableColumn;
 });
\ No newline at end of file
diff --git a/dojox/editor/plugins/SafePaste.js b/dojox/editor/plugins/SafePaste.js
index 231ac3f..4eb105c 100644
--- a/dojox/editor/plugins/SafePaste.js
+++ b/dojox/editor/plugins/SafePaste.js
@@ -2,18 +2,18 @@ define([
 	"dojo",
 	"dijit",
 	"dojox",
+	"dojox/editor/plugins/PasteFromWord",
 	"dijit/Dialog",
 	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/string",
-	"dojox/editor/plugins/PasteFromWord",
 	"dojo/i18n!dojox/editor/plugins/nls/SafePaste",
 	"dojo/i18n!dijit/nls/common",
 	"dojo/i18n!dijit/_editor/nls/commands"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, PasteFromWord) {
 
-dojo.declare("dojox.editor.plugins.SafePaste", [dojox.editor.plugins.PasteFromWord],{
+var SafePaste = dojo.declare("dojox.editor.plugins.SafePaste", [PasteFromWord],{
 	// summary:
 	//		This plugin extends from the PasteFromWord plugin and provides
 	//		'safe pasting', meaning that it will not allow keyboard/menu pasting
@@ -29,7 +29,6 @@ dojo.declare("dojox.editor.plugins.SafePaste", [dojox.editor.plugins.PasteFromWo
 		this._filters = this._filters.slice(0); 
 		var strings = dojo.i18n.getLocalization("dojox.editor.plugins", "SafePaste");
 		dojo.mixin(strings, dojo.i18n.getLocalization("dijit", "common"));
-		strings.cancel = strings.buttonCancel;
 		dojo.mixin(strings, dojo.i18n.getLocalization("dijit._editor", "commands"));
 
 		this._uId = dijit.getUniqueId(this.editor.id);
@@ -73,6 +72,7 @@ dojo.declare("dojox.editor.plugins.SafePaste", [dojox.editor.plugins.PasteFromWo
 		//		Overrides _Plugin.updateState(). 
 		// tags:
 		//		protected
+		
 		// Do nothing.
 	},
 	
@@ -102,7 +102,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "safepaste"){
-		o.plugin = new dojox.editor.plugins.SafePaste({
+		o.plugin = new SafePaste({
 			width: (o.args.hasOwnProperty("width"))?o.args.width:"400px",
 			height: (o.args.hasOwnProperty("height"))?o.args.width:"300px",
 			stripTags: (o.args.hasOwnProperty("stripTags"))?o.args.stripTags:null 
@@ -110,6 +110,6 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	}
 });
 
-return dojox.editor.plugins.SafePaste;
+return SafePaste;
 
 });
diff --git a/dojox/editor/plugins/Save.js b/dojox/editor/plugins/Save.js
index e012fdb..2edfff3 100755
--- a/dojox/editor/plugins/Save.js
+++ b/dojox/editor/plugins/Save.js
@@ -2,18 +2,18 @@ define([
 	"dojo",
 	"dijit",
 	"dojox",
-	"dijit/form/Button",
 	"dijit/_editor/_Plugin",
+	"dijit/form/Button",
 	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/i18n!dojox/editor/plugins/nls/Save"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin) {
 
-dojo.declare("dojox.editor.plugins.Save",dijit._editor._Plugin,{
+var Save = dojo.declare("dojox.editor.plugins.Save", _Plugin, {
 	// summary:
-	//		This plugin provides Save cabability to the editor.  When
-	//		clicked, the document in the editor frame will be osted to the URL
+	//		This plugin provides Save capability to the editor.  When
+	//		clicked, the document in the editor frame will be posted to the URL
 	//		provided, or none, if none provided.  Users who desire a different save
 	//		function can extend this plugin (via dojo.extend) and over-ride the
 	//		save method	while save is in process, the save button is disabled.
@@ -23,11 +23,11 @@ dojo.declare("dojox.editor.plugins.Save",dijit._editor._Plugin,{
 	//		and `command`
 	iconClassPrefix: "dijitAdditionalEditorIcon",
 
-	// url [public]	String
+	// url: [public] String
 	//		The URL to POST the content back to.  Used by the save function.
 	url: "",
 
-	// logErrors [public] boolean
+	// logResults: [public] boolean
 	//		Boolean flag to indicate that the default action for save and
 	//		error handlers is to just log to console.  Default is true.
 	logResults: true,
@@ -132,13 +132,13 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "save"){
-		o.plugin = new dojox.editor.plugins.Save({
+		o.plugin = new Save({
 			url: ("url" in o.args)?o.args.url:"",
 			logResults: ("logResults" in o.args)?o.args.logResults:true
 		});
 	}
 });
 
-return dojox.editor.plugins.Save;
+return Save;
 
 });
diff --git a/dojox/editor/plugins/ShowBlockNodes.js b/dojox/editor/plugins/ShowBlockNodes.js
index f1c74cd..8fc5a6b 100755
--- a/dojox/editor/plugins/ShowBlockNodes.js
+++ b/dojox/editor/plugins/ShowBlockNodes.js
@@ -9,30 +9,29 @@ define([
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/i18n!dojox/editor/plugins/nls/ShowBlockNodes"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin) {
 
-dojo.declare("dojox.editor.plugins.ShowBlockNodes",dijit._editor._Plugin,{
+var ShowBlockNodes = dojo.declare("dojox.editor.plugins.ShowBlockNodes", _Plugin, {
 	// summary:
-	//		This plugin provides ShowBlockNodes cabability to the editor.  When
+	//		This plugin provides ShowBlockNodes capability to the editor.  When
 	//		clicked, the document in the editor will apply a class to specific
 	//		block nodes to make them visible in the layout.  This info is not
 	//		exposed/extracted when the editor value is obtained, it is purely for help
 	//		while working on the page.
 
-	// useDefaultCommand [protected] boolean
-	//		Over-ride indicating that the command processing is done all by this plugin.
+	// Over-ride indicating that the command processing is done all by this plugin.
 	useDefaultCommand: false,
 
 	// iconClassPrefix: [const] String
 	//		The CSS class name for the button node is formed from `iconClassPrefix` and `command`
 	iconClassPrefix: "dijitAdditionalEditorIcon",
 
-	// _styled [private] boolean
+	// _styled: [private] boolean
 	//		Flag indicating the document has had the style updates applied.
 	_styled: false,
 
 	_initButton: function(){
-		//	summary:
+		// summary:
 		//		Over-ride for creation of the preview button.
 		var strings = dojo.i18n.getLocalization("dojox.editor.plugins", "ShowBlockNodes");
 		this.button = new dijit.form.ToggleButton({
@@ -178,10 +177,10 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name ===  "showblocknodes"){
-		o.plugin = new dojox.editor.plugins.ShowBlockNodes();
+		o.plugin = new ShowBlockNodes();
 	}
 });
 
-return dojox.editor.plugins.ShowBlockNodes;
+return ShowBlockNodes;
 
 });
diff --git a/dojox/editor/plugins/Smiley.js b/dojox/editor/plugins/Smiley.js
index 7e5183b..fbcf7a0 100644
--- a/dojox/editor/plugins/Smiley.js
+++ b/dojox/editor/plugins/Smiley.js
@@ -10,34 +10,33 @@ define([
 	"dojox/editor/plugins/_SmileyPalette",
 	"dojox/html/format",
 	"dojo/i18n!dojox/editor/plugins/nls/Smiley"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin) {
 
 dojo.experimental("dojox.editor.plugins.Smiley");
 
-dojo.declare("dojox.editor.plugins.Smiley", dijit._editor._Plugin, {
+var Smiley = dojo.declare("dojox.editor.plugins.Smiley", _Plugin, {
 	// summary:
 	//		This plugin allows the user to select from emoticons or "smileys"
 	//		to insert at the current cursor position.
-	//
 	// description:
 	//		The commands provided by this plugin are:
-	//		* smiley - inserts the selected emoticon
+	//
+	//		- smiley - inserts the selected emoticon
 
 	// iconClassPrefix: [const] String
 	//		The CSS class name for the button node is formed from `iconClassPrefix` and `command`
 	iconClassPrefix: "dijitAdditionalEditorIcon",
 
-	// a marker for emoticon wrap like [:-)] for regexp convienent
-	// when a message which contains an emoticon stored in a database or view source, this marker include also
-	// but when user enter an emoticon by key board, user don't need to enter this marker.
-	// also emoticon definition character set can not contains this marker
+	// emoticonMarker:
+	//		a marker for emoticon wrap like [:-)] for regexp convienent
+	//		when a message which contains an emoticon stored in a database or view source, this marker include also
+	//		but when user enter an emoticon by key board, user don't need to enter this marker.
+	//		also emoticon definition character set can not contains this marker
 	emoticonMarker: '[]',
 
 	emoticonImageClass: 'dojoEditorEmoticon',
 
 	_initButton: function(){
-		// summary:
-		//
 		this.dropDown = new dojox.editor.plugins._SmileyPalette();
 		this.connect(this.dropDown, "onChange", function(ascii){
 			this.button.closeDropDown();
@@ -98,23 +97,26 @@ dojo.declare("dojox.editor.plugins.Smiley", dijit._editor._Plugin, {
 		}
 	},
 
-	_preFilterEntities: function(/*String content passed in*/ value){
+	_preFilterEntities: function(/*String*/ value){
 		// summary:
 		//		A function to filter out emoticons into their UTF-8 character form
 		//		displayed in the editor.  It gets registered with the preFilters
 		//		of the editor.
+		// value: String
+		//		content passed in
 		// tags:
 		//		private.
-		//
-		//
+
 		return value.replace(/\[([^\]]*)\]/g, dojo.hitch(this, this._decode));
 	},
 
-	_postFilterEntities: function(/*String content passed in*/ value){
+	_postFilterEntities: function(/*String*/ value){
 		// summary:
 		//		A function to filter out emoticons into encoded form so they
 		//		are properly displayed in the editor.  It gets registered with the
 		//		postFilters of the editor.
+		// value: String
+		//		content passed in
 		// tags:
 		//		private.
 		return value.replace(/<img [^>]*>/gi, dojo.hitch(this, this._encode));
@@ -122,14 +124,14 @@ dojo.declare("dojox.editor.plugins.Smiley", dijit._editor._Plugin, {
 
 	_decode: function(str, ascii){
 		// summary:
-		//		Pre-filter for editor to convert strings like [:-)] into an <img> of the corresponding smiley
+		//		Pre-filter for editor to convert strings like [:-)] into an `<img>` of the corresponding smiley
 		var emoticon = dojox.editor.plugins.Emoticon.fromAscii(ascii);
 		return emoticon ? emoticon.imgHtml(this.emoticonImageClass) : str;
 	},
 
 	_encode: function(str){
 		// summary:
-		//		Post-filter for editor to convert <img> nodes of smileys into strings like [:-)]
+		//		Post-filter for editor to convert `<img>` nodes of smileys into strings like [:-)]
 		
 		// Each <img> node has an alt tag with it's ascii representation, so just use that.
 		// TODO: wouldn't this be easier as a postDomFilter ?
@@ -146,10 +148,10 @@ dojo.declare("dojox.editor.plugins.Smiley", dijit._editor._Plugin, {
 dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	if(o.args.name === "smiley"){
-		o.plugin = new dojox.editor.plugins.Smiley();
+		o.plugin = new Smiley();
 	}
 });
 
-return dojox.editor.plugins.Smiley;
+return Smiley;
 
 });
diff --git a/dojox/editor/plugins/SpellCheck.js b/dojox/editor/plugins/SpellCheck.js
index 7c6923c..b2be1b0 100644
--- a/dojox/editor/plugins/SpellCheck.js
+++ b/dojox/editor/plugins/SpellCheck.js
@@ -1,27 +1,29 @@
-dojo.provide("dojox.editor.plugins.SpellCheck");
-
-dojo.require("dijit._base.popup");
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit.form.TextBox");
-dojo.require("dijit.form.DropDownButton");
-dojo.require("dijit.TooltipDialog");
-dojo.require("dijit.form.MultiSelect");
-dojo.require("dojo.io.script");
-dojo.require("dijit.Menu");
-
-dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");
+define([
+	"dojo",
+	"dijit",
+	"dojo/io/script",
+	"dijit/popup",
+	"dijit/_Widget",
+	"dijit/_Templated",
+	"dijit/_editor/_Plugin",
+	"dijit/form/TextBox",
+	"dijit/form/DropDownButton",
+	"dijit/TooltipDialog",
+	"dijit/form/MultiSelect",
+	"dijit/Menu",
+	"dojo/i18n!dojox/editor/plugins/nls/SpellCheck"
+], function(dojo, dijit, script, popup, _Widget, _Templated, _Plugin){
 
 dojo.experimental("dojox.editor.plugins.SpellCheck");
 
-dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
+var SpellCheckControl = dojo.declare("dojox.editor.plugins._spellCheckControl", [_Widget, _Templated], {
 	// summary:
 	//		The widget that is used for the UI of the batch spelling check
-	
+
 	widgetsInTemplate: true,
-	
+
 	templateString:
-		"<table class='dijitEditorSpellCheckTable'>" +
+		"<table role='presentation' class='dijitEditorSpellCheckTable'>" +
 			"<tr><td colspan='3' class='alignBottom'><label for='${textId}' id='${textId}_label'>${unfound}</label>" +
 				"<div class='dijitEditorSpellCheckBusyIcon' id='${id}_progressIcon'></div></td></tr>" +
 			"<tr>" +
@@ -51,7 +53,7 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 				"<td></td>" +
 			"</tr>" +
 		"</table>",
-	
+
 	/*************************************************************************/
 	/**                      Framework Methods                              **/
 	/*************************************************************************/
@@ -65,16 +67,16 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 		// Indicate if the dialog can be closed
 		this.closable = true;
 	},
-	
+
 	postMixInProperties: function(){
 		this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
 		this.textId = this.id + "_textBox";
 		this.selectId = this.id + "_select";
 	},
-	
+
 	postCreate: function(){
 		var select = this.suggestionSelect;
-		
+
 		// Customize multi-select to single select
 		dojo.removeAttr(select.domNode, "multiple");
 		select.addItems = function(/*Array*/ items){
@@ -102,7 +104,7 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 			//		public
 			dojo.empty(this.domNode);
 		};
-	
+
 		select.deselectAll = function(){
 			// summary:
 			//		De-select all the selected items
@@ -110,7 +112,7 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 			//		public
 			this.containerNode.selectedIndex = -1;
 		};
-		
+
 		// Connect up all the controls with their event handler
 		this.connect(this, "onKeyPress", "_cancel");
 		this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
@@ -123,39 +125,39 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 		this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
 		this.connect(this.cancelButton, "onClick", "onCancel");
 	},
-	
+
 	/*************************************************************************/
 	/**                      Public Methods                                 **/
 	/*************************************************************************/
-	
+
 	onSkip: function(){
 		// Stub for the click event of the skip button.
 	},
-	
+
 	onSkipAll: function(){
 		// Stub for the click event of the skipAll button.
 	},
-	
+
 	onAddToDic: function(){
 		// Stub for the click event of the toDic button.
 	},
-	
+
 	onReplace: function(){
 		// Stub for the click event of the replace button.
 	},
-	
+
 	onReplaceAll: function(){
 		// Stub for the click event of the replaceAll button.
 	},
-	
+
 	onCancel: function(){
 		// Stub for the click event of the cancel button.
 	},
-	
+
 	onEnter: function(){
 		// Stub for the enter event of the unFound textbox.
 	},
-	
+
 	focus: function(){
 		// summary:
 		//		Set the focus of the control
@@ -163,11 +165,11 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 		//		public
 		this.unfoundTextBox.focus();
 	},
-	
+
 	/*************************************************************************/
 	/**                      Private Methods                                **/
 	/*************************************************************************/
-	
+
 	_cancel: function(/*Event*/ evt){
 		// summary:
 		//		Handle the cancel event
@@ -180,7 +182,7 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 			dojo.stopEvent(evt);
 		}
 	},
-	
+
 	_enter: function(/*Event*/ evt){
 		// summary:
 		//		Handle the enter event
@@ -193,7 +195,7 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 			dojo.stopEvent(evt);
 		}
 	},
-	
+
 	_unfoundTextBoxChange: function(){
 		// summary:
 		//		Indicate that the Not Found textbox is changed or not
@@ -208,7 +210,7 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 			dojo.byId(id).innerHTML = this["unfound"];
 		}
 	},
-	
+
 	_setUnfoundWordAttr: function(/*String*/ value){
 		// summary:
 		//		Set the value of the Not Found textbox
@@ -219,7 +221,7 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 		value = value || "";
 		this.unfoundTextBox.set("value", value);
 	},
-	
+
 	_getUnfoundWordAttr: function(){
 		// summary:
 		//		Get the value of the Not Found textbox
@@ -227,7 +229,7 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 		//		private
 		return this.unfoundTextBox.get("value");
 	},
-	
+
 	_setSuggestionListAttr: function(/*Array*/ values){
 		// summary:
 		//		Set the items of the suggestion list
@@ -240,7 +242,7 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 		select.removeItems();
 		select.addItems(values);
 	},
-	
+
 	_getSelectedWordAttr: function(){
 		// summary:
 		//		Get the suggested word.
@@ -255,7 +257,7 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 			return this.unfoundTextBox.get("value");
 		}
 	},
-	
+
 	_setDisabledAttr: function(/*Boolean*/ disabled){
 		// summary:
 		//		Enable/disable the control
@@ -267,65 +269,64 @@ dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._T
 		this.replaceButton.set("disabled", disabled);
 		this.replaceAllButton.set("disabled", disabled);
 	},
-	
+
 	_setInProgressAttr: function(/*Boolean*/ show){
 		// summary:
 		//		Set the visibility of the progress icon
 		// tags:
 		//		private
-		var id = this.id + "_progressIcon",
-			cmd = show ? "removeClass" : "addClass";
-			dojo[cmd](id, "hidden");
+		var id = this.id + "_progressIcon";
+		dojo.toggleClass(id, "hidden", !show);
 	}
 });
 
-dojo.declare("dojox.editor.plugins._SpellCheckScriptMultiPart", null, {
+var SpellCheckScriptMultiPart = dojo.declare("dojox.editor.plugins._SpellCheckScriptMultiPart", null, {
 	// summary:
 	//		It is a base network service component. It transfers text to a remote service port
 	//		with cross domain ability enabled. It can split text into specified pieces and send
 	//		them out one by one so that it can handle the case when the service has a limitation of
 	//		the capability.
 	//		The encoding is UTF-8.
-	
+
 	// ACTION [public const] String
 	//		Actions for the server-side piece to take
 	ACTION_QUERY: "query",
 	ACTION_UPDATE: "update",
-	
+
 	// callbackHandle [public] String
 	//		The callback name of JSONP
 	callbackHandle: "callback",
-	
+
 	// maxBufferLength [public] Number
-	//		The max number of charactors that send to the service at one time.
+	//		The max number of characters that send to the service at one time.
 	maxBufferLength: 100,
-	
+
 	// delimiter [public] String
 	//		A token that is used to identify the end of a word (a complete unit). It prevents the service from
 	//		cutting a single word into two parts. For example:
-	//			"Dojo toolkit is a ajax framework. It helps the developers buid their web applications."
+	// |		"Dojo toolkit is a ajax framework. It helps the developers buid their web applications."
 	//		Without the delimiter, the sentence might be split into the follow pieces which is absolutely
 	//		not the result we want.
-	//			"Dojo toolkit is a ajax fram", "ework It helps the developers bu", "id their web applications"
+	// |		"Dojo toolkit is a ajax fram", "ework It helps the developers bu", "id their web applications"
 	//		Having " " as the delimiter, we get the following correct pieces.
-	//			"Dojo toolkit is a ajax framework", " It helps the developers buid", " their web applications"
+	// |		"Dojo toolkit is a ajax framework", " It helps the developers buid", " their web applications"
 	delimiter: " ",
-	
+
 	// label [public] String
 	//		The leading label of the JSON response. The service will return the result like this:
-	//		{response: [
-	//				{
-	//					text: "teest",
-	//					suggestion: ["test","treat"]
-	//				}
-	//			]}
+	// |	{response: [
+	// |		{
+	// |			text: "teest",
+	// |			suggestion: ["test","treat"]
+	// |		}
+	// |	]}
 	label: "response",
-	
-	// _timeout [private] Number
+
+	// _timeout: [private] Number
 	//		Set JSONP timeout period
 	_timeout: 30000,
 	SEC: 1000,
-	
+
 	constructor: function(){
 		// The URL of the target service
 		this.serviceEndPoint = "";
@@ -340,7 +341,7 @@ dojo.declare("dojox.editor.plugins._SpellCheckScriptMultiPart", null, {
 		// assemble the final result.
 		this._counter = 0;
 	},
-	
+
 	send: function(/*String*/ content, /*String?*/ action){
 		// summary:
 		//		Send the content to the service port with the specified action
@@ -360,8 +361,8 @@ dojo.declare("dojox.editor.plugins._SpellCheckScriptMultiPart", null, {
 			comms = this.exArgs,
 			timeout = this._timeout,
 			l = 0, r = 0;
-		
-		// Temparary list that holds the result returns from the service, which will be
+
+		// Temporary list that holds the result returns from the service, which will be
 		// assembled into a completed one.
 		if(!this._result) {
 			this._result = [];
@@ -428,14 +429,14 @@ dojo.declare("dojox.editor.plugins._SpellCheckScriptMultiPart", null, {
 				});
 			}
 		};
-	
+
 		if(!_this.isWorking){
 			batchSend();
 		}else{
 			_this._queue.push(batchSend);
 		}
 	},
-	
+
 	_finalizeCollection: function(action){
 		// summary:
 		//		Assemble the responses into one result.
@@ -456,99 +457,99 @@ dojo.declare("dojox.editor.plugins._SpellCheckScriptMultiPart", null, {
 		this._counter = 0;
 		this._result = [];
 	},
-	
+
 	onLoad: function(/*String*/ data){
 		// Stub method for a sucessful call
 	},
-	
+
 	setWaitingTime: function(/*Number*/ seconds){
 		this._timeout = seconds * this.SEC;
 	}
 });
 
-dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
-	//	summary:
-	//		This plugin provides a spelling check cabability for the editor.
-	
-	// url [public] String
+var SpellCheck = dojo.declare("dojox.editor.plugins.SpellCheck", [_Plugin], {
+	// summary:
+	//		This plugin provides a spelling check capability for the editor.
+
+	// url: [public] String
 	//		The url of the spelling check service
 	url: "",
-	
-	// bufferLength [public] Number
+
+	// bufferLength: [public] Number
 	//		The max length of each XHR request. It is used to divide the large
 	//		text into pieces so that the server-side piece can hold.
 	bufferLength: 100,
-	
-	// interactive [public] Boolean
+
+	// interactive: [public] Boolean
 	//		Indicate if the interactive spelling check is enabled
 	interactive: false,
-	
-	// timeout [public] Number
+
+	// timeout: [public] Number
 	//		The minutes to waiting for the response. The default value is 30 seconds.
 	timeout: 30,
-	
-	// button [protected] dijit.form.DropDownButton
+
+	// button: [protected] dijit/form/DropDownButton
 	//		The button displayed on the editor's toolbar
 	button: null,
-	
-	// _editor [private] dijit.Editor
+
+	// _editor: [private] dijit/Editor
 	//		The reference to the editor the plug-in belongs to.
 	_editor: null,
-	
-	// exArgs [private] Object
+
+	// exArgs: [private] Object
 	//		The object that holds all the parametes passed into the constructor
 	exArgs: null,
-	
-	// _cursorSpan [private] String
+
+	// _cursorSpan: [private] String
 	//		The span that holds the current position of the cursor
 	_cursorSpan:
 		"<span class=\"cursorPlaceHolder\"></span>",
-	
-	// _cursorSelector [private] String
+
+	// _cursorSelector: [private] String
 	//		The CSS selector of the cursor span
 	_cursorSelector:
 		"cursorPlaceHolder",
-	
-	// _incorrectWordsSpan [private] String
+
+	// _incorrectWordsSpan: [private] String
 	//		The wrapper that marks the incorrect words
 	_incorrectWordsSpan:
 		"<span class='incorrectWordPlaceHolder'>${text}</span>",
-		
-	// _ignoredIncorrectStyle [private] Object
+
+	// _ignoredIncorrectStyle: [private] Object
 	//		The style of the ignored incorrect words
 	_ignoredIncorrectStyle:
 		{"cursor": "inherit", "borderBottom": "none", "backgroundColor": "transparent"},
-		
-	// _normalIncorrectStyle [private] Object
+
+	// _normalIncorrectStyle: [private] Object
 	//		The style of the marked incorrect words.
 	_normalIncorrectStyle:
 		{"cursor": "pointer", "borderBottom": "1px dotted red", "backgroundColor": "yellow"},
-	
-	// _highlightedIncorrectStyle [private] Object
+
+	// _highlightedIncorrectStyle: [private] Object
 	//		The style of the highlighted incorrect words
 	_highlightedIncorrectStyle:
 		{"borderBottom": "1px dotted red", "backgroundColor": "#b3b3ff"},
-	
-	// _selector [private] String
+
+	// _selector: [private] String
 	//		An empty CSS class that identifies the incorrect words
 	_selector: "incorrectWordPlaceHolder",
-	
-	// _maxItemNumber [private] Number
+
+	// _maxItemNumber: [private] Number
 	//		The max number of the suggestion list items
 	_maxItemNumber: 3,
-	
+
 	/*************************************************************************/
 	/**                      Framework Methods                              **/
 	/*************************************************************************/
-	
+
 	constructor: function(){
 		// A list that holds all the spans that contains the incorrect words
 		// It is used to select/replace the specified word.
 		this._spanList = [];
 		// The cache that stores all the words. It looks like the following
 		// {
-		//   "word": [],
-		//   "wrd": ["word", "world"]
+		//	 "word": [],
+		//	 "wrd": ["word", "world"]
 		// }
 		this._cache = {};
 		// Indicate if this plugin is enabled or not
@@ -556,18 +557,18 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		// The index of the _spanList
 		this._iterator = 0;
 	},
-	
+
 	setEditor: function(/*dijit.Editor*/ editor){
 		this._editor = editor;
 		this._initButton();
 		this._setNetwork();
 		this._connectUp();
 	},
-	
+
 	/*************************************************************************/
 	/**                      Private Methods                                **/
 	/*************************************************************************/
-	
+
 	_initButton: function(){
 		// summary:
 		//		Initialize the button displayed on the editor's toolbar
@@ -576,8 +577,8 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		var _this = this,
 			strings = (this._strings = dojo.i18n.getLocalization("dojox.editor.plugins", "SpellCheck")),
 			dialogPane = (this._dialog = new dijit.TooltipDialog());
-		
-		dialogPane.set("content", (this._dialogContent = new dojox.editor.plugins._spellCheckControl({
+
+		dialogPane.set("content", (this._dialogContent = new SpellCheckControl({
 			unfound: strings["unfound"],
 			skip: strings["skip"],
 			skipAll: strings["skipAll"],
@@ -588,7 +589,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			replaceAll: strings["replaceAll"],
 			cancel: strings["cancel"]
 		})));
-		
+
 		this.button = new dijit.form.DropDownButton({
 			label: strings["widgetLabel"],
 			showLabel: false,
@@ -607,7 +608,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 						}
 					}
 					if(this._opened){
-						dijit.popup.close(this.dropDown);
+						popup.close(this.dropDown);
 						if(focus){ this.focus(); }
 						this._opened = false;
 						this.state = "";
@@ -616,19 +617,19 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			}
 		});
 		_this._dialogContent.isOpen = false;
-		
+
 		dialogPane.domNode.setAttribute("aria-label", this._strings["widgetLabel"]);
 	},
-	
+
 	_setNetwork: function(){
 		// summary:
 		//		Set up the underlying network service
 		// tags:
 		//		private
 		var comms = this.exArgs;
-		
+
 		if(!this._service){
-			var service = (this._service = new dojox.editor.plugins._SpellCheckScriptMultiPart());
+			var service = (this._service = new SpellCheckScriptMultiPart());
 			service.serviceEndPoint = this.url;
 			service.maxBufferLength = this.bufferLength;
 			service.setWaitingTime(this.timeout);
@@ -642,7 +643,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			}
 		}
 	},
-	
+
 	_connectUp: function(){
 		// summary:
 		//		Connect up all the events with their event handlers
@@ -650,7 +651,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		//		private
 		var editor = this._editor,
 			cont = this._dialogContent;
-		
+
 		this.connect(this.button, "set", "_disabled");
 		this.connect(this._service, "onLoad", "_loadData");
 		this.connect(this._dialog, "onOpen", "_openDialog");
@@ -663,7 +664,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		this.connect(cont, "onReplaceAll", "_replaceAll");
 		this.connect(cont, "onCancel", "_cancel");
 		this.connect(cont, "onEnter", "_enter");
-		
+
 		editor.contentPostFilters.push(this._spellCheckFilter); // Register the filter
 		dojo.publish(dijit._scopeName + ".Editor.plugin.SpellCheck.getParser", [this]); // Get the language parser
 		if(!this.parser){
@@ -674,7 +675,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 	/*************************************************************************/
 	/**                      Event Handlers                                 **/
 	/*************************************************************************/
-	
+
 	_disabled: function(name, disabled){
 		// summary:
 		//		When the plugin is disabled (the button is disabled), reset all to their initial status.
@@ -695,7 +696,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			this._enabled = !disabled;
 		}
 	},
-	
+
 	_keyPress: function(evt){
 		// summary:
 		//		The handler of the onKeyPress event of the editor
@@ -711,7 +712,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			}
 		}
 	},
-	
+
 	_loadData: function(/*Array*/ data){
 		// summary:
 		//		Apply the query result to the content
@@ -722,9 +723,9 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		var cache = this._cache,
 			html = this._editor.get("value"),
 			cont = this._dialogContent;
-		
+
 		this._iterator = 0;
-		
+
 		// Update the local cache
 		dojo.forEach(data, function(d){
 			cache[d.text] = d.suggestion;
@@ -736,34 +737,34 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			cont.closable = false;
 			this._markIncorrectWords(html, cache);
 			cont.closable = true;
-			
+
 			if(this._dialogContent.isOpen){
 				this._iterator = -1;
 				this._skip();
 			}
 		}
 	},
-	
+
 	_openDialog: function(){
 		// summary:
 		//		The handler of the onOpen event
 		var cont = this._dialogContent;
-		
+
 		// Clear dialog content and disable it first
 		cont.ignoreChange = true;
 		cont.set("unfoundWord", "");
 		cont.set("suggestionList", null);
 		cont.set("disabled", true);
 		cont.set("inProgress", true);
-		
+
 		cont.isOpen = true; // Indicate that the dialog is open
 		cont.closable = false;
-		
+
 		this._submitContent();
-		
+
 		cont.closable = true;
 	},
-	
+
 	_skip: function(/*Event?*/ evt, /*Boolean?*/ noUpdate){
 		// summary:
 		//		Ignore this word and move to the next unignored one.
@@ -777,16 +778,16 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			list = this._spanList || [],
 			len = list.length,
 			iter = this._iterator;
-		
+
 		cont.closable = false;
 		cont.isChanged = false;
 		cont.ignoreChange = true;
-		
+
 		// Skip the current word
 		if(!noUpdate && iter >= 0 && iter < len){
 			this._skipWord(iter);
 		}
-		
+
 		// Move to the next
 		while(++iter < len && list[iter].edited == true){ /* do nothing */}
 		if(iter < len){
@@ -801,7 +802,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			cont.set("disabled", true);
 			cont.set("inProgress", false);
 		}
-		
+
 		setTimeout(function(){
 			// When moving the focus out of the iframe in WebKit browsers, we
 			// need to focus something else first. So the textbox
@@ -812,7 +813,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			cont.closable = true;
 		}, 0);
 	},
-	
+
 	_skipAll: function(){
 		// summary:
 		//		Ignore all the same words
@@ -822,20 +823,20 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		this._skipWordAll(this._iterator);
 		this._skip();
 	},
-	
+
 	_add: function(){
 		// summary:
 		//		Add the unrecognized word into the dictionary
 		// tags:
 		//		private
 		var cont = this._dialogContent;
-		
+
 		cont.closable = false;
 		cont.isOpen = true;
 		this._addWord(this._iterator, cont.get("unfoundWord"));
 		this._skip();
 	},
-	
+
 	_replace: function(){
 		// summary:
 		//		Replace the incorrect word with the selected one,
@@ -845,12 +846,12 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		var cont = this._dialogContent,
 			iter = this._iterator,
 			targetWord = cont.get("selectedWord");
-		
+
 		cont.closable = false;
 		this._replaceWord(iter, targetWord);
 		this._skip(null, true);
 	},
-	
+
 	_replaceAll: function(){
 		// summary:
 		//		Replace all the words with the same text
@@ -861,7 +862,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			len = list.length,
 			word = list[this._iterator].innerHTML.toLowerCase(),
 			targetWord = cont.get("selectedWord");
-		
+
 		cont.closable = false;
 		for(var iter = 0; iter < len; iter++){
 			// If this word is not ignored and is the same as the source word,
@@ -870,10 +871,10 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 				this._replaceWord(iter, targetWord);
 			}
 		}
-		
+
 		this._skip(null, true);
 	},
-	
+
 	_cancel: function(){
 		// summary:
 		//		Cancel this check action
@@ -882,7 +883,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		this._dialogContent.closable = true;
 		this._editor.focus();
 	},
-	
+
 	_enter: function(){
 		// summary:
 		//		Handle the ENTER event
@@ -894,11 +895,11 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			this._skip();
 		}
 	},
-	
+
 	/*************************************************************************/
 	/**                              Utils                                  **/
 	/*************************************************************************/
-	
+
 	_query: function(/*String*/ html){
 		// summary:
 		//		Send the query text to the service. The query text is a string of words
@@ -926,13 +927,13 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			this._loadData([]);
 		}
 	},
-	
+
 	_html2Text: function(html){
 		// summary:
 		//		Substitute the tag with white charactors so that the server
 		//		can easily process the text. For example:
-		//		"<a src="sample.html">Hello, world!</a>" ==>
-		//		"                     Hello, world!    "
+		// |	"<a src="sample.html">Hello, world!</a>" ==>
+		// |	"                     Hello, world!    "
 		// html:
 		//		The html code
 		// tags:
@@ -940,7 +941,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		var text = [],
 			isTag = false,
 			len = html ? html.length : 0;
-		
+
 		for(var i = 0; i < len; i++){
 			if(html.charAt(i) == "<"){ isTag = true; }
 			if(isTag == true){
@@ -949,11 +950,11 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 				text.push(html.charAt(i));
 			}
 			if(html.charAt(i) == ">"){ isTag = false; }
-			
+
 		}
 		return text.join("");
 	},
-	
+
 	_getBookmark: function(/*String*/ eValue){
 		// summary:
 		//		Get the cursor position. It is the index of the characters
@@ -971,14 +972,14 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		while(++i < index && eValue.charAt(i) == nv.charAt(i)){ /* do nothing */}
 		return i;
 	},
-	
+
 	_moveToBookmark: function(){
 		// summary:
 		//		Move to the position when the cursor was.
 		// tags:
 		//		private
 		var ed = this._editor,
-			cps = dojo.withGlobal(ed.window, "query", dojo, ["." + this._cursorSelector]),
+			cps = dojo.query("." + this._cursorSelector, ed.document),
 			cursorSpan = cps && cps[0];
 		// Find the cursor place holder
 		if(cursorSpan){
@@ -988,7 +989,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			if(parent){ parent.removeChild(cursorSpan); }
 		}
 	},
-	
+
 	_submitContent: function(/*Boolean?*/ delay){
 		// summary:
 		//		Functions to submit the content of the editor
@@ -1008,7 +1009,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			this._query(this._editor.get("value"));
 		}
 	},
-	
+
 	_populateDialog: function(index){
 		// summary:
 		//		Populate the content of the dailog
@@ -1019,7 +1020,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		var list = this._spanList,
 			cache = this._cache,
 			cont = this._dialogContent;
-		
+
 		cont.set("disabled", false);
 		if(index < list.length && list.length > 0){
 			var word = list[index].innerHTML;
@@ -1028,7 +1029,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			cont.set("inProgress", false);
 		}
 	},
-	
+
 	_markIncorrectWords: function(/*String*/ html, /*Object*/ cache){
 		// summary:
 		//		Mark the incorrect words and set up menus if available
@@ -1052,7 +1053,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			bmMarked = false,
 			cArray = html.split(""),
 			spanList = null;
-		
+
 		// Mark the incorrect words and cursor position
 		for(var i = words.length - 1; i >= 0; i--){
 			var word = words[i];
@@ -1077,20 +1078,20 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			cArray.splice(bmpos, 0, bookmark);
 			bmMarked = true;
 		}
-		
+
 		editor.set("value", cArray.join(""));
 		editor._cursorToStart = false; // HACK! But really necessary here.
-		
+
 		this._moveToBookmark();
-		
+
 		// Get the incorrect words <span>
-		spanList = this._spanList = dojo.withGlobal(editor.window, "query", dojo, ["." + this._selector]);
-		dojo.forEach(spanList, function(span, i){ span.id = selector + i; });
-		
+		spanList = this._spanList = dojo.query("." + this._selector, editor.document);
+		spanList.forEach(function(span, i){ span.id = selector + i; });
+
 		// Set them to the incorrect word style
 		if(!this.interactive){ delete nstyle.cursor; }
 		spanList.style(nstyle);
-		
+
 		if(this.interactive){
 			// Build the context menu
 			if(_this._contextMenu){
@@ -1099,40 +1100,40 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			}
 			_this._contextMenu = new dijit.Menu({
 				targetNodeIds: [editor.iframe],
-				
+
 				bindDomNode: function(/*String|DomNode*/ node){
 					// summary:
 					//		Attach menu to given node
 					node = dojo.byId(node);
-			
+
 					var cn;	// Connect node
-			
+
 					// Support context menus on iframes.   Rather than binding to the iframe itself we need
 					// to bind to the <body> node inside the iframe.
 					var iframe, win;
 					if(node.tagName.toLowerCase() == "iframe"){
 						iframe = node;
 						win = this._iframeContentWindow(iframe);
-						cn = dojo.withGlobal(win, dojo.body);
+						cn = dojo.body(editor.document)
 					}else{
-						
+
 						// To capture these events at the top level, attach to <html>, not <body>.
 						// Otherwise right-click context menu just doesn't work.
 						cn = (node == dojo.body() ? dojo.doc.documentElement : node);
 					}
-			
-			
+
+
 					// "binding" is the object to track our connection to the node (ie, the parameter to bindDomNode())
 					var binding = {
 						node: node,
 						iframe: iframe
 					};
-			
+
 					// Save info about binding in _bindings[], and make node itself record index(+1) into
 					// _bindings[] array.   Prefix w/_dijitMenu to avoid setting an attribute that may
 					// start with a number, which fails on FF/safari.
 					dojo.attr(node, "_dijitMenu" + this.id, this._bindings.push(binding));
-			
+
 					// Setup the connections to monitor click etc., unless we are connecting to an iframe which hasn't finished
 					// loading yet, in which case we need to wait for the onload event first, and then connect
 					// On linux Shift-F10 produces the oncontextmenu event, but on Windows it doesn't, so
@@ -1147,14 +1148,14 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 								// Schedule context menu to be opened unless it's already been scheduled from onkeydown handler
 								if(dojo.hasClass(target, selector) && !target.edited){ // Click on the incorrect word
 									dojo.stopEvent(evt);
-									
+
 									// Build the on-demand menu items
 									var maxNumber = _this._maxItemNumber,
 										id = target.id,
 										index = id.substring(selector.length),
 										suggestions = cache[target.innerHTML.toLowerCase()],
 										slen = suggestions.length;
-										
+
 									// Add the suggested words menu items
 									this.destroyDescendants();
 									if(slen == 0){
@@ -1176,7 +1177,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 											}));
 										}
 									}
-									
+
 									//Add the other action menu items
 									this.addChild(new dijit.MenuSeparator());
 									this.addChild(new dijit.MenuItem({
@@ -1201,7 +1202,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 											editor.focus();
 										}
 									}));
-									
+
 									this._scheduleOpen(target, iframe, {x: evt.pageX, y: evt.pageY});
 								}
 							}),
@@ -1214,19 +1215,19 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 						];
 					});
 					binding.connects = cn ? doConnects(cn) : [];
-			
+
 					if(iframe){
 						// Setup handler to [re]bind to the iframe when the contents are initially loaded,
 						// and every time the contents change.
 						// Need to do this b/c we are actually binding to the iframe's <body> node.
 						// Note: can't use dojo.connect(), see #9609.
-			
+
 						binding.onloadHandler = dojo.hitch(this, function(){
 							// want to remove old connections, but IE throws exceptions when trying to
 							// access the <body> node because it's already gone, or at least in a state of limbo
-			
-							var win = this._iframeContentWindow(iframe);
-								cn = dojo.withGlobal(win, dojo.body);
+
+							var win = this._iframeContentWindow(iframe),
+								cn = dojo.body(editor.document);
 							binding.connects = doConnects(cn);
 						});
 						if(iframe.addEventListener){
@@ -1239,7 +1240,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			});
 		}
 	},
-	
+
 	_selectWord: function(index){
 		// summary:
 		//		Select the incorrect word. Move to it and highlight it
@@ -1247,12 +1248,12 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		//		The index of the span list
 		// tags:
 		//		private
-		var list = this._spanList,
-			win = this._editor.window;
-		
+		var ed = this._editor,
+			list = this._spanList;
+
 		if(index < list.length && list.length > 0){
-			dojo.withGlobal(win, "selectElement", dijit._editor.selection, [list[index]]);
-			dojo.withGlobal(win, "collapse", dijit._editor.selection, [true]);
+			ed._sCall("selectElement", [list[index]]);
+			ed._sCall("collapse", [true]);
 			this._findText(list[index].innerHTML, false, false);
 			if(dojo.isIE){
 				// Because the selection in the iframe will be lost when the outer window get the
@@ -1261,7 +1262,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 			}
 		}
 	},
-	
+
 	_replaceWord: function(index, text){
 		// summary:
 		//		Replace the word at the given index with the text
@@ -1272,12 +1273,12 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		// tags:
 		//		private
 		var list = this._spanList;
-		
+
 		list[index].innerHTML = text;
 		dojo.style(list[index], this._ignoredIncorrectStyle);
 		list[index].edited = true;
 	},
-	
+
 	_skipWord: function(index){
 		// summary:
 		//		Skip the word at the index
@@ -1286,12 +1287,12 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		// tags:
 		//		private
 		var list = this._spanList;
-		
+
 		dojo.style(list[index], this._ignoredIncorrectStyle);
 		this._cache[list[index].innerHTML.toLowerCase()].correct = true;
 		list[index].edited = true;
 	},
-	
+
 	_skipWordAll: function(index, /*String?*/word){
 		// summary:
 		//		Skip the all the word that have the same text as the word at the index
@@ -1306,14 +1307,14 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		var list = this._spanList,
 			len = list.length;
 		word = word || list[index].innerHTML.toLowerCase();
-			
+
 		for(var i = 0; i < len; i++){
 			if(!list[i].edited && list[i].innerHTML.toLowerCase() == word){
 				this._skipWord(i);
 			}
 		}
 	},
-	
+
 	_addWord: function(index, /*String?*/word){
 		// summary:
 		//		Add the word at the index to the dictionary
@@ -1328,7 +1329,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		service.send(word || this._spanList[index].innerHTML.toLowerCase(), service.ACTION_UPDATE);
 		this._skipWordAll(index, word);
 	},
-	
+
 	_findText: function(/*String*/ txt, /*Boolean*/ caseSensitive, /*Boolean*/ backwards){
 		// summary:
 		//		This function invokes a find with specific options
@@ -1378,7 +1379,7 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 		}
 		return found;
 	},
-	
+
 	_spellCheckFilter: function(/*String*/ value){
 		// summary:
 		//		Filter out the incorrect word style so that the value of the edtior
@@ -1392,12 +1393,16 @@ dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
 	}
 });
 
+// For monkey patching
+SpellCheck._SpellCheckControl = SpellCheckControl;
+SpellCheck._SpellCheckScriptMultiPart = SpellCheckScriptMultiPart;
+
 // Register this plugin.
 dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name ===  "spellcheck"){
-		o.plugin = new dojox.editor.plugins.SpellCheck({
+		o.plugin = new SpellCheck({
 			url: ("url" in o.args) ? o.args.url : "",
 			interactive: ("interactive" in o.args) ? o.args.interactive : false,
 			bufferLength: ("bufferLength" in o.args) ? o.args.bufferLength: 100,
@@ -1406,3 +1411,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		});
 	}
 });
+
+return SpellCheck;
+
+});
diff --git a/dojox/editor/plugins/StatusBar.js b/dojox/editor/plugins/StatusBar.js
index ea93133..68fffaa 100755
--- a/dojox/editor/plugins/StatusBar.js
+++ b/dojox/editor/plugins/StatusBar.js
@@ -8,10 +8,11 @@ define([
 	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojox/layout/ResizeHandle"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Widget, _TemplatedMixin, _Plugin) {
 
 dojo.experimental("dojox.editor.plugins.StatusBar");
-dojo.declare("dojox.editor.plugins._StatusBar", [dijit._Widget, dijit._TemplatedMixin],{
+
+var _StatusBar = dojo.declare("dojox.editor.plugins._StatusBar", [_Widget, _TemplatedMixin],{
 	// templateString: String
 	//		Template for the widget.  Currently using table to get the alignment behavior and
 	//		bordering I wanted.  Would prefer not to use table, though.
@@ -50,9 +51,9 @@ dojo.declare("dojox.editor.plugins._StatusBar", [dijit._Widget, dijit._Templated
 	}
 });
 
-dojo.declare("dojox.editor.plugins.StatusBar",dijit._editor._Plugin,{
+var StatusBar = dojo.declare("dojox.editor.plugins.StatusBar", _Plugin, {
 	// summary:
-	//		This plugin provides StatusBar cabability to the editor.
+	//		This plugin provides StatusBar capability to the editor.
 	//		Basically a footer bar where status can be published.  It also
 	//		puts a resize handle on the status bar, allowing you to resize the
 	//		editor via mouse.
@@ -73,7 +74,7 @@ dojo.declare("dojox.editor.plugins.StatusBar",dijit._editor._Plugin,{
 		// editor: Object
 		//		The editor to configure for this plugin to use.
 		this.editor = editor;
-		this.statusBar = new dojox.editor.plugins._StatusBar();
+		this.statusBar = new _StatusBar();
 		if(this.resizer){
 			this.resizeHandle = new dojox.layout.ResizeHandle({targetId: this.editor, activeResize: true}, this.statusBar.handle);
 			this.resizeHandle.startup();
@@ -165,16 +166,19 @@ dojo.declare("dojox.editor.plugins.StatusBar",dijit._editor._Plugin,{
 	}
 });
 
+// For monkey patching
+StatusBar._StatusBar = _StatusBar;
+
 // Register this plugin.
 dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name === "statusbar"){
 		var resizer = ("resizer" in o.args)?o.args.resizer:true;
-		o.plugin = new dojox.editor.plugins.StatusBar({resizer: resizer});
+		o.plugin = new StatusBar({resizer: resizer});
 	}
 });
 
-return dojox.editor.plugins.StatusBar;
+return StatusBar;
 
 });
diff --git a/dojox/editor/plugins/TablePlugins.js b/dojox/editor/plugins/TablePlugins.js
index 0743d75..0516a33 100644
--- a/dojox/editor/plugins/TablePlugins.js
+++ b/dojox/editor/plugins/TablePlugins.js
@@ -1,59 +1,66 @@
 define([
-	"dojo",
-	"dijit",
-	"dojox",
-	"dijit/_base/popup",
-	"dijit/_Widget",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/Color",
+	"dojo/aspect",
+	"dojo/dom-attr",
+	"dojo/dom-style",
+	"dijit/_editor/_Plugin",
+	"dijit/_WidgetBase",
 	"dijit/_TemplatedMixin",
 	"dijit/_WidgetsInTemplateMixin",
+	"dijit/Dialog",
 	"dijit/Menu",
 	"dijit/MenuItem",
 	"dijit/MenuSeparator",
+	"dijit/ColorPalette",
+	"dojox/widget/ColorPicker",
+	"dojo/text!./resources/insertTable.html",
+	"dojo/text!./resources/modifyTable.html",
+	"dojo/i18n!./nls/TableDialog",
+	"dijit/_base/popup",
+	"dijit/popup",
+	"dojo/_base/connect",
 	"dijit/TooltipDialog",
 	"dijit/form/Button",
 	"dijit/form/DropDownButton",
-	"dijit/Dialog",
 	"dijit/form/TextBox",
-	"dijit/form/FilteringSelect",
-	"dijit/popup",
-	"dijit/_editor/_Plugin",
-	"dijit/_editor/range",
-	"dijit/_editor/selection",
-	"dijit/ColorPalette",
-	"dojox/widget/ColorPicker",
-	"dojo/_base/connect",
-	"dojo/_base/declare",
-	"dojo/i18n",
-	"dojo/i18n!dojox/editor/plugins/nls/TableDialog"
-], function(dojo, dijit, dojox) {
+	"dijit/form/FilteringSelect"
+], function(
+	declare,
+	array,
+	Color,
+	aspect,
+	domAttr,
+	domStyle,
+	_Plugin,
+	_WidgetBase,
+	_TemplatedMixin,
+	_WidgetsInTemplateMixin,
+	Dialog,
+	Menu,
+	MenuItem,
+	MenuSeparator,
+	ColorPalette,
+	ColorPicker,
+	insertTableTemplate,
+	modifyTableTemplate,
+	tableDialogStrings
+) {
 
 dojo.experimental("dojox.editor.plugins.TablePlugins");
 
-// summary:
-//		A series of plugins that give the Editor the ability to create and edit
-//		HTML tables. See the end of this document for all avaiable plugins
-//		and dojox/editorPlugins/tests/editorTablePlugs.html for an example
-//
-// example:
-//		|	<div dojoType="dijit.Editor" plugins="[
-//		|			'bold','italic','|',
-//		|			{name: 'dojox.editor.plugins.TablePlugins', command: 'insertTable'},
-//		|			{name: 'dojox.editor.plugins.TablePlugins', command: 'modifyTable'}
-//		|		]">
-//		|		Editor text is here
-//		|	</div>
-//
 // TODO:
 //		Currently not supporting merging or splitting cells
 //
-// FIXME:	Undo is very buggy, and therefore unimeplented in all browsers
+// FIXME:	Undo is very buggy, and therefore unimplemented in all browsers
 //			except IE - which itself has only been lightly tested.
 //
 // FIXME:	Selecting multiple table cells in Firefox looks to be impossible.
 //			This affect the 'colorTableCell' plugin. Cells can still be
 //			colored individually or in rows.
 
-dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
+var TableHandler = declare(_Plugin, {
 	// summary:
 	//		A global object that handles common tasks for all the plugins. Since
 	//		there are several plugins that are all calling common methods, it's preferable
@@ -75,20 +82,20 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		
 		dojo.mixin(this.editor,{
 			getAncestorElement: function(tagName){
-				return dojo.withGlobal(this.window, "getAncestorElement",dijit._editor.selection, [tagName]);
+				return this._sCall("getAncestorElement", [tagName]);
 			},
 			hasAncestorElement: function(tagName){
-				return dojo.withGlobal(this.window, "hasAncestorElement",dijit._editor.selection, [tagName]);
+				return this._sCall("hasAncestorElement", [tagName]);
 			},
 			selectElement: function(elem){
-				dojo.withGlobal(this.window, "selectElement",dijit._editor.selection, [elem]);
+				this._sCall("selectElement", [elem]);
 			},
 			byId: function(id){
-				return dojo.withGlobal(this.window, "byId", dojo, [id]);
+				return dojo.byId(id, this.document);
 			},
 			query: function(arg, scope, returnFirstOnly){
 				// this shortcut is dubious - not sure scoping is necessary
-				var ar = dojo.withGlobal(this.window, "query", dojo, [arg, scope]);
+				var ar = dojo.query(arg, scope || this.document);
 				return (returnFirstOnly) ? ar[0] : ar;
 			}
 		});
@@ -118,13 +125,21 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		//editor to init at the right time.
 		editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
 			this.editorDomNode = this.editor.editNode || this.editor.iframe.document.body.firstChild;
-			
+
 			// RichText should have a mouseup connection to recognize drag-selections
 			// Example would be selecting multiple table cells
-			this._myListeners = [];
-			this._myListeners.push(dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"));
-			this._myListeners.push(dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"));
-			this._myListeners.push(dojo.connect(this.editor, "onBlur", this, "checkAvailable"));
+			this._myListeners = [
+				dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"),
+				dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"),
+				dojo.connect(this.editor, "onBlur", this, "checkAvailable"),
+				dojo.connect(this.editor, "_saveSelection", this, function(){
+					// because on IE, the selection is lost when the iframe goes out of focus
+					this._savedTableInfo = this.getTableInfo();
+				}),
+				dojo.connect(this.editor, "_restoreSelection", this, function(){
+					delete this._savedTableInfo;
+				})
+			];
 			this.doMixins();
 			this.connectDraggable();
 		}));
@@ -135,6 +150,12 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		//		Gets the table in focus
 		//		Collects info on the table - see return params
 		//
+
+		if(this._savedTableInfo){
+			// Avoid trying to query the table info when the iframe is blurred; doesn't work on IE.
+			return this._savedTableInfo;
+		}
+
 		if(forceNewData){ this._tempStoreTableData(false); }
 		if(this.tableData){
 			// tableData is set for a short amount of time, so that all
@@ -142,35 +163,41 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 			//console.log("returning current tableData:", this.tableData);
 			return this.tableData;
 		}
-		var tr, trs, td, tds, tbl, cols, tdIndex, trIndex;
+		var tr, trs, td, tds, tbl, cols, tdIndex, trIndex, o;
 
 		td = this.editor.getAncestorElement("td");
 		if(td){ tr = td.parentNode; }
 		
 		tbl = this.editor.getAncestorElement("table");
 		//console.log("td:", td);console.log("tr:", tr);console.log("tbl:", tbl)
-		
-		tds = dojo.query("td", tbl);
-		tds.forEach(function(d, i){
-			if(td==d){tdIndex = i;}
-		});
-		trs = dojo.query("tr", tbl);
-		trs.forEach(function(r, i){
-			if(tr==r){trIndex = i;}
-		});
-		cols = tds.length/trs.length;
-		var o = {
-			tbl:tbl,		// focused table
-			td:td,			// focused TD
-			tr:tr,			// focused TR
-			trs:trs,		// rows
-			tds:tds,		// cells
-			rows:trs.length,// row amount
-			cols:cols,		// column amount
-			tdIndex:tdIndex,// index of focused cell
-			trIndex:trIndex,	// index of focused row
-			colIndex:tdIndex%cols
-		};
+
+		if(tbl){
+			tds = dojo.query("td", tbl);
+			tds.forEach(function(d, i){
+				if(td==d){tdIndex = i;}
+			});
+			trs = dojo.query("tr", tbl);
+			trs.forEach(function(r, i){
+				if(tr==r){trIndex = i;}
+			});
+			cols = tds.length/trs.length;
+
+			o = {
+				tbl:tbl,		// focused table
+				td:td,			// focused TD
+				tr:tr,			// focused TR
+				trs:trs,		// rows
+				tds:tds,		// cells
+				rows:trs.length,// row amount
+				cols:cols,		// column amount
+				tdIndex:tdIndex,// index of focused cell
+				trIndex:trIndex,	// index of focused row
+				colIndex:tdIndex%cols
+			};
+		}else{
+			// Means there's no table in focus.   Use {} not null so that this._savedTableInfo is non-null
+			o = {};
+		}
 		//console.log("NEW tableData:",o);
 		this.tableData = o;
 		this._tempStoreTableData(500);
@@ -205,7 +232,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		tbl.addEventListener("drag", dojo.hitch(this, "onDragStart2"), false);
 		tbl.addEventListener("dragend", dojo.hitch(this, "onDragStart3"), false);
 	
-		dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]);
+		this.editor._sCall("selectElement", [tbl]);
 		
 		tbl.ondragstart = function(){
 			//console.log("ondragstart");
@@ -237,7 +264,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		var e = window.event;
 		var node = e.srcElement;
 		var id = node.id;
-		var win = this.editor.window;
+		var doc = this.editor.document;
 		//console.log("NODE:", node.tagName, node.id,  dojo.attr(node, "align"));
 		
 		// clearing a table's align attr
@@ -245,7 +272,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		//	should move to its own method
 		if(node.tagName.toLowerCase()=="table"){
 			setTimeout(function(){
-				var node =  dojo.withGlobal(win, "byId", dojo, [id]);
+				var node = dojo.byId(id, doc);
 				dojo.removeAttr(node, "align");
 				//console.log("set", node.tagName, dojo.attr(node, "align"))
 			}, 100);
@@ -273,10 +300,11 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 			//console.log(" return always available")
 			return true;
 		}
-		
+
 		// Only return available if the editor is focused.
-		this.currentlyAvailable = this.editor.focused ? this.editor.hasAncestorElement("table") : false;
-		
+		this.currentlyAvailable = this.editor.focused && (this._savedTableInfo ? this._savedTableInfo.tbl :
+			this.editor.hasAncestorElement("table"));
+
 		if(this.currentlyAvailable){
 			this.connectTableKeys();
 		}else{
@@ -284,7 +312,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		}
 		
 		this._tempAvailability(500);
-		
+
 		dojo.publish(this.editor.id + "_tablePlugins", [ this.currentlyAvailable ]);
 		return this.currentlyAvailable;
 	},
@@ -448,12 +476,10 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 	}
 });
 
-dojo.declare("dojox.editor.plugins.TablePlugins",
-	dijit._editor._Plugin,
-	{
-		//summary:
+var TablePlugins = declare("dojox.editor.plugins.TablePlugins", _Plugin, {
+		// summary:
 		//		A collection of Plugins for inserting and modifying tables in the Editor
-		//		See end of this document for all avaiable plugs
+		//		See end of this document for all available plugs
 		//		and dojox/editorPlugins/tests/editorTablePlugs.html for an example
 		//
 		//		NOT IMPLEMENTED: Not handling cell merge, span or split
@@ -468,9 +494,10 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 		undoEnabled:true,
 		
 		onDisplayChanged: function(withinTable){
-			// subscribed to from the global object's publish method
-			//
-			//console.log("onDisplayChanged", this.commandName);
+			// summary:
+			//	 	subscribed to from the global object's publish method
+			
+			//console.log("onDisplayChanged", this.name);
 			if(!this.alwaysAvailable){
 				this.available = withinTable;
 				this.button.set('disabled', !this.available);
@@ -489,7 +516,7 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 				// Create it and init it off the editor.  This
 				// will create the _tablePluginHandler reference on
 				// the dijit.Editor instance.  This avoids a global.
-				var tablePluginHandler = new dojox.editor.plugins._TableHandler();
+				var tablePluginHandler = new TableHandler();
 				tablePluginHandler.initialize(this.editor);
 			}else{
 				this.editor._tablePluginHandler.initialize(this.editor);
@@ -500,42 +527,43 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 			// selects table that is in focus
 			var o = this.getTableInfo();
 			if(o && o.tbl){
-				dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [o.tbl]);
+				this.editor._sCall("selectElement", [o.tbl]);
 			}
 		},
 		
 		_initButton: function(){
-			this.command = this.commandName;
+			this.command = this.name;
 			
 			this.label = this.editor.commands[this.command] = this._makeTitle(this.command);
 			this.inherited(arguments);
 			delete this.command;
-			
+
 			this.connect(this.button, "onClick", "modTable");
-			
+
 			this.onDisplayChanged(false);
 		},
 		
 		modTable: function(cmd, args){
 			// summary:
-			//		Where each plugin performs its action
+			//		Where each plugin performs its action.
 			//		Note: not using execCommand. In spite of their presence in the
 			//		Editor as query-able plugins, I was not able to find any evidence
 			//		that they are supported (especially in NOT IE). If they are
 			//		supported in other browsers, it may help with the undo problem.
-			//
-			this.begEdit();
-			var o = this.getTableInfo();
-			var sw = (dojo.isString(cmd))?cmd : this.commandName;
-			var r, c, i;
-			var adjustColWidth = false;
-			//console.log("modTable:", sw)
 
 			if(dojo.isIE){
 				// IE can lose selections on focus changes, so focus back
 				// in order to restore it.
 				this.editor.focus();
 			}
+
+			this.begEdit();
+			var o = this.getTableInfo();
+			var sw = (dojo.isString(cmd))?cmd : this.name;
+			var r, c, i;
+			var adjustColWidth = false;
+			//console.log("modTable:", sw)
+
 			switch(sw){
 				case "insertTableRowBefore":
 					r = o.tbl.insertRow(o.trIndex);
@@ -619,10 +647,10 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 		},
 		
 		makeColumnsEven: function(){
-			//summary:
+			// summary:
 			//		After changing column amount, change widths to
 			//		keep columns even
-			//
+			
 			// the timeout helps prevent an occasional snafu
 			setTimeout(dojo.hitch(this, function(){
 				var o = this.getTableInfo(true);
@@ -641,25 +669,19 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 			return this.editor._tablePluginHandler.getTableInfo(forceNewData);
 		},
 		_makeTitle: function(str){
-			// Parses the commandName into a Title
-			//	based on camelCase
-			var ns = [];
-			dojo.forEach(str, function(c, i){
-				if(c.charCodeAt(0)<91 && i>0 && ns[i-1].charCodeAt(0)!=32){
-					ns.push(" ");
-				}
-				if(i===0){ c = c.toUpperCase();}
-				ns.push(c);
-			});
-			return ns.join("");
+			// Uses the commandName to get the localized Title
+			this._strings = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog");
+			var title = this._strings[str+"Title"] || this._strings[str+"Label"] || str;
+			return title;
 		},
 		
 		
 		
 		getSelectedCells: function(){
 			// summary:
-			//		Gets the selected cells from the passed table
-			//		Returns: array of TDs or empty array
+			//		Gets the selected cells from the passed table.
+			// returns:
+			//		array of TDs or empty array
 			var cells = [];
 			var tbl = this.getTableInfo().tbl;
 			this.editor._tablePluginHandler._prepareTable(tbl);
@@ -667,7 +689,7 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 
 			// Lets do this the way IE originally was (Looking up ids).  Walking the selection
 			// is inconsistent in the browsers (and painful), so going by ids is simpler.
-			var text = dojo.withGlobal(e.window, "getSelectedHtml",dijit._editor.selection, [null]);
+			var text = e._sCall("getSelectedHtml", [null]);
 			var str = text.match(/id="*\w*"*/g);
 			dojo.forEach(str, function(a){
 				var id = a.substring(3, a.length);
@@ -728,9 +750,7 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 	}
 );
 
-dojo.declare("dojox.editor.plugins.TableContextMenu",
-	dojox.editor.plugins.TablePlugins,
-	{
+var TableContextMenu = declare(TablePlugins, {
 		constructor: function(){
 			// summary:
 			//		Initialize certain plugins
@@ -756,237 +776,40 @@ dojo.declare("dojox.editor.plugins.TableContextMenu",
 		
 		_initButton: function(){
 			this.inherited(arguments);
-			if(this.commandName=="tableContextMenu"){ this.button.domNode.display = "none";}
+			if(this.name==="tableContextMenu"){ this.button.domNode.display = "none";}
 		},
 		
 		_createContextMenu: function(){
-			// summary
+			// summary:
 			//		Building context menu for right-click shortcuts within a table
-			//
 		
-			var pMenu = new dijit.Menu({targetNodeIds:[this.editor.iframe]});
-			var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang);
-			pMenu.addChild(new dijit.MenuItem({label: messages.selectTableLabel, onClick: dojo.hitch(this, "selectTable")}));
-			pMenu.addChild(new dijit.MenuSeparator());
+			var pMenu = new Menu({targetNodeIds:[this.editor.iframe]});
+			var messages = tableDialogStrings;
+			pMenu.addChild(new MenuItem({label: messages.selectTableLabel, onClick: dojo.hitch(this, "selectTable")}));
+			pMenu.addChild(new MenuSeparator());
 			
-			pMenu.addChild(new dijit.MenuItem({label: messages.insertTableRowBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowBefore" )}));
-			pMenu.addChild(new dijit.MenuItem({label: messages.insertTableRowAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowAfter" )}));
-			pMenu.addChild(new dijit.MenuItem({label: messages.insertTableColumnBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnBefore" )}));
-			pMenu.addChild(new dijit.MenuItem({label: messages.insertTableColumnAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnAfter" )}));
-			pMenu.addChild(new dijit.MenuSeparator());
-			pMenu.addChild(new dijit.MenuItem({label: messages.deleteTableRowLabel, onClick: dojo.hitch(this, "modTable", "deleteTableRow" )}));
-			pMenu.addChild(new dijit.MenuItem({label: messages.deleteTableColumnLabel, onClick: dojo.hitch(this, "modTable", "deleteTableColumn" )}));
+			pMenu.addChild(new MenuItem({label: messages.insertTableRowBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowBefore" )}));
+			pMenu.addChild(new MenuItem({label: messages.insertTableRowAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableRowAfter" )}));
+			pMenu.addChild(new MenuItem({label: messages.insertTableColumnBeforeLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnBefore" )}));
+			pMenu.addChild(new MenuItem({label: messages.insertTableColumnAfterLabel, onClick: dojo.hitch(this, "modTable", "insertTableColumnAfter" )}));
+			pMenu.addChild(new MenuSeparator());
+			pMenu.addChild(new MenuItem({label: messages.deleteTableRowLabel, onClick: dojo.hitch(this, "modTable", "deleteTableRow" )}));
+			pMenu.addChild(new MenuItem({label: messages.deleteTableColumnLabel, onClick: dojo.hitch(this, "modTable", "deleteTableColumn" )}));
 
 			this.menu = pMenu;
 		}
 });
 
-dojo.declare("dojox.editor.plugins.InsertTable",
-	dojox.editor.plugins.TablePlugins,
-	{
-		alwaysAvailable: true,
-					
-		modTable: function(){
-			var w = new dojox.editor.plugins.EditorTableDialog({});
-			w.show();
-			var c = dojo.connect(w, "onBuildTable", this, function(obj){
-				dojo.disconnect(c);
-				
-				var res = this.editor.execCommand('inserthtml', obj.htmlText);
-				
-				// commenting this line, due to msg below
-				//var td = this.editor.query("td", this.editor.byId(obj.id));
-				
-				//HMMMM.... This throws a security error now. didn't used to.
-				//this.editor.selectElement(td);
-			});
-		}
-});
-
-dojo.declare("dojox.editor.plugins.ModifyTable",
-	dojox.editor.plugins.TablePlugins,
-	{
-		modTable: function(){
-			if (!this.editor._tablePluginHandler.checkAvailable()) {return;}
-			var o = this.getTableInfo();
-			//console.log("LAUNCH DIALOG");
-			var w = new dojox.editor.plugins.EditorModifyTableDialog({table:o.tbl});
-			w.show();
-			this.connect(w, "onSetTable", function(color){
-				// uhm... not sure whats going on here...
-				var o = this.getTableInfo();
-				//console.log("set color:", color);
-				dojo.attr(o.td, "bgcolor", color);
-			});
-		}
-});
-
-dojo.declare("dojox.editor.plugins._CellColorDropDown", [dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
-	// summary:
-	//		A smple widget that uses/creates a dropdown with a dojox.widget.ColorPicker.  Also provides
-	//		passthroughs to the value of the color picker and convenient hook points.
-	// tags:
-	//		private
-
-	// templateString: String
-	//		The template used to create the ColorPicker.
-	templateString:
-		"<div style='display: none; position: absolute; top: -10000; z-index: -10000'>" +
-			"<div dojoType='dijit.TooltipDialog' dojoAttachPoint='dialog' class='dojoxEditorColorPicker'>" +
-				"<div dojoType='dojox.widget.ColorPicker' dojoAttachPoint='_colorPicker'></div>" +
-				"<div style='margin: 0.5em 0em 0em 0em'>" +
-					"<button dojoType='dijit.form.Button' type='button' dojoAttachPoint='_setButton'>${buttonSet}</button>" +
-					" " +
-					"<button dojoType='dijit.form.Button' type='button' dojoAttachPoint='_cancelButton'>${buttonCancel}</button>" +
-				"</div>" +
-			"</div>" +
-		"</div>",
-
-	// widgetsInTemplate: Boolean
-	//		Flag denoting widgets are contained in the template.
-	widgetsInTemplate: true,
-
-	constructor: function(){
-		// summary:
-		//		Constructor over-ride so that the translated strings are mixsed in so
-		//		the template fills out.
-		var strings = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog");
-		dojo.mixin(this, strings);
-	},
-
-	startup: function(){
-		// summary:
-		//		Over-ride of startup to do the basic connect setups and such.
-		if(!this._started){
-			this.inherited(arguments);
-			this.connect(this._setButton, "onClick", function(){
-				this.onChange(this.get("value"));
-			});
-			this.connect(this._cancelButton, "onClick", function(){
-				dijit.popup.close(this.dialog);
-				this.onCancel();
-			});
-			// Fully statred, so go ahead and remove the hide.
-			dojo.style(this.domNode, "display", "block");
-		}
-	},
-
-	_setValueAttr: function(value, priorityChange){
-		// summary:
-		//		Passthrough function for the color picker value.
-		// value: String
-		//		The value to set in the color picker
-		// priorityChange:
-		//		Value to indicate whether or not to trigger an onChange event.
-		this._colorPicker.set("value", value, priorityChange);
-	},
-
-	_getValueAttr: function(){
-		// summary:
-		//		Passthrough function for the color picker value.
-		return this._colorPicker.get("value");
-	},
-
-	setColor: function(/*String*/ color){
-		this._colorPicker.setColor(color, false);
-	},
-	
-	onChange: function(value){
-		// summary:
-		//		Hook point to get the value when the color picker value is selected.
-		// value: String
-		//		The value from the color picker.
-	},
-
-	onCancel: function(){
-		// summary:
-		//		Hook point to get when the dialog is canceled.
-	}
-});
-
-dojo.declare("dojox.editor.plugins.ColorTableCell", dojox.editor.plugins.TablePlugins, {
-		constructor: function(){
-			// summary:
-			//		Initialize ColorTableCell plugin
-			this.closable = true;
-			this.buttonClass = dijit.form.DropDownButton;
-			var picker = new dojox.editor.plugins._CellColorDropDown();
-			dojo.body().appendChild(picker.domNode);
-			picker.startup();
-			this.dropDown = picker.dialog;
-			this.connect(picker, "onChange", function(color){
-				this.modTable(null, color);
-				this.editor.focus();
-			});
-			this.connect(picker, "onCancel", function(color){
-				this.editor.focus();
-			});
-			this.connect(picker.dialog, "onOpen", function(){
-				var o = this.getTableInfo(),
-					tds = this.getSelectedCells(o.tbl);
-				if(tds && tds.length > 0){
-					var t = tds[0] == this.lastObject ? tds[0] : tds[tds.length - 1],
-						color;
-					while(t && ((color = dojo.style(t, "backgroundColor")) == "transparent" || color.indexOf("rgba") == 0)){
-						t = t.parentNode;
-					}
-					color = dojo.style(t, "backgroundColor");
-					if(color != "transparent" && color.indexOf("rgba") != 0){
-						picker.setColor(color);
-					}
-				}
-			});
-			this.connect(this, "setEditor", function(editor){
-				editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
-					this.connect(this.editor.editNode, "onmouseup", function(evt){
-						this.lastObject = evt.target;
-					});
-				}));
-			});
-		},
-		
-		_initButton: function(){
-			this.command = this.commandName;
-			
-			this.label = this.editor.commands[this.command] = this._makeTitle(this.command);
-			this.inherited(arguments);
-			delete this.command;
-
-			this.onDisplayChanged(false);
-		},
-        
-		modTable: function(cmd, args){
-			// summary
-			//	Where each plugin performs its action
-			//	Note: not using execCommand. In spite of their presence in the
-			//	Editor as query-able plugins, I was not able to find any evidence
-			//	that they are supported (especially in NOT IE). If they are
-			//	supported in other browsers, it may help with the undo problem.
-			//
-			this.begEdit();
-			var o = this.getTableInfo();
-			// The one plugin that really needs use of the very verbose
-			//	getSelectedCells()
-			var tds = this.getSelectedCells(o.tbl);
-			//console.debug("SELECTED CELLS ", tds , " FOR ", o);
-			dojo.forEach(tds, function(td){
-				dojo.style(td, "backgroundColor", args);
-			});
-			this.endEdit();
-		}
-});
-
-dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
+var EditorTableDialog = declare("dojox.editor.plugins.EditorTableDialog", [Dialog, _TemplatedMixin, _WidgetsInTemplateMixin], {
 	// summary:
 	//		Dialog box with options for table creation
 
 	baseClass:"EditorTableDialog",
-				
-	templateString: dojo.cache("dojox.editor.plugins", "resources/insertTable.html"),
+
+	templateString: insertTableTemplate,
 
 	postMixInProperties: function(){
-		var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang);
-		dojo.mixin(this, messages);
+		dojo.mixin(this, tableDialogStrings);
 		this.inherited(arguments);
 	},
 
@@ -997,7 +820,7 @@ dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog, dijit._Tem
 
 	onInsert: function(){
 		console.log("insert");
-		
+
 		var rows =		this.selectRow.get("value") || 1,
 			cols =		this.selectCol.get("value") || 1,
 			width =		this.selectWidth.get("value"),
@@ -1007,7 +830,7 @@ dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog, dijit._Tem
 			space =		this.selectSpace.get("value"),
 			_id =		"tbl_"+(new Date().getTime()),
 			t = '<table id="'+_id+'"width="'+width+((widthType=="percent")?'%':'')+'" border="'+border+'" cellspacing="'+space+'" cellpadding="'+pad+'">\n';
-		
+
 		for(var r=0;r<rows;r++){
 			t += '\t<tr>\n';
 			for(var c=0;c<cols;c++){
@@ -1016,9 +839,7 @@ dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog, dijit._Tem
 			t += '\t</tr>\n';
 		}
 		t += '</table><br />';
-		
-		//console.log(t);
-		this.onBuildTable({htmlText:t, id:_id});
+
 		var cl = dojo.connect(this, "onHide", function(){
 			dojo.disconnect(cl);
 			var self = this;
@@ -1027,6 +848,9 @@ dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog, dijit._Tem
 			}, 10);
 		});
 		this.hide();
+
+		//console.log(t);
+		this.onBuildTable({htmlText:t, id:_id});
 	},
 
 	onCancel: function(){
@@ -1047,30 +871,50 @@ dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog, dijit._Tem
 	}
 });
 
-dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
-	
+var InsertTable = declare("dojox.editor.plugins.InsertTable", TablePlugins, {
+	alwaysAvailable: true,
+
+	modTable: function(){
+		var w = new EditorTableDialog({});
+		w.show();
+		var c = dojo.connect(w, "onBuildTable", this, function(obj){
+			dojo.disconnect(c);
+
+			this.editor.focus();
+			var res = this.editor.execCommand('inserthtml', obj.htmlText);
+
+			// commenting this line, due to msg below
+			//var td = this.editor.query("td", this.editor.byId(obj.id));
+
+			//HMMMM.... This throws a security error now. didn't used to.
+			//this.editor.selectElement(td);
+		});
+	}
+});
+
+var EditorModifyTableDialog = declare([Dialog, _TemplatedMixin, _WidgetsInTemplateMixin], {
+
 	// summary:
 	//		Dialog box with options for editing a table
 	//
-	
+
 	baseClass:"EditorTableDialog",
 
 	table:null, //html table to be modified
 	tableAtts:{},
-	templateString: dojo.cache("dojox.editor.plugins", "resources/modifyTable.html"),
+	templateString: modifyTableTemplate,
 
 	postMixInProperties: function(){
-		var messages = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog", this.lang);
-		dojo.mixin(this, messages);
+		dojo.mixin(this, tableDialogStrings);
 		this.inherited(arguments);
 	},
 
 	postCreate: function(){
 		dojo.addClass(this.domNode, this.baseClass); //FIXME - why isn't Dialog accepting the baseClass?
 		this.inherited(arguments);
-		this._cleanupWidgets = [];
-		var w1 = new dijit.ColorPalette({});
+		var w1 = new this.colorPicker({params: this.params});
 		this.connect(w1, "onChange", function(color){
+			if(!this._started){ return; } // not during startup()
 			dijit.popup.close(w1);
 			this.setBrdColor(color);
 		});
@@ -1078,11 +922,14 @@ dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog, diji
 			dijit.popup.close(w1);
 		});
 		this.connect(this.borderCol, "click", function(){
+			w1.set('value', this.brdColor, false);
 			dijit.popup.open({popup:w1, around:this.borderCol});
 			w1.focus();
 		});
-		var w2 = new dijit.ColorPalette({});
+		var w2 = new this.colorPicker({params: this.params});
+
 		this.connect(w2, "onChange", function(color){
+			if(!this._started){ return; } // not during startup()
 			dijit.popup.close(w2);
 			this.setBkColor(color);
 		});
@@ -1090,15 +937,16 @@ dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog, diji
 			dijit.popup.close(w2);
 		});
 		this.connect(this.backgroundCol, "click", function(){
-            dijit.popup.open({popup:w2, around:this.backgroundCol});
+			w2.set('value', this.bkColor, false);
+			dijit.popup.open({popup:w2, around:this.backgroundCol});
 			w2.focus();
 		});
-		this._cleanupWidgets.push(w1);
-		this._cleanupWidgets.push(w2);
-		
-		this.setBrdColor(dojo.attr(this.table, "bordercolor"));
-		this.setBkColor(dojo.attr(this.table, "bgcolor"));
-		var w = dojo.attr(this.table, "width");
+		this.own(w1, w2);
+		this.pickers = [ w1, w2 ];
+
+		this.setBrdColor(domStyle.get(this.table, "borderColor"));
+		this.setBkColor(domStyle.get(this.table, "backgroundColor"));
+		var w = domAttr.get(this.table, "width");
 		if(!w){
 			w = this.table.style.width;
 		}
@@ -1107,7 +955,7 @@ dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog, diji
 			p = "percent";
 			w = w.replace(/%/, "");
 		}
-		
+
 		if(w){
 			this.selectWidth.set("value", w);
 			this.selectWidthType.set("value", p);
@@ -1115,34 +963,38 @@ dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog, diji
 			this.selectWidth.set("value", "");
 			this.selectWidthType.set("value", "percent");
 		}
-		
-		this.selectBorder.set("value", dojo.attr(this.table, "border"));
-		this.selectPad.set("value", dojo.attr(this.table, "cellPadding"));
-		this.selectSpace.set("value", dojo.attr(this.table, "cellSpacing"));
-		this.selectAlign.set("value", dojo.attr(this.table, "align"));
+
+		this.selectBorder.set("value", domAttr.get(this.table, "border"));
+		this.selectPad.set("value", domAttr.get(this.table, "cellPadding"));
+		this.selectSpace.set("value", domAttr.get(this.table, "cellSpacing"));
+		this.selectAlign.set("value", domAttr.get(this.table, "align"));
 	},
-	
+	startup: function() {
+		array.forEach(this.pickers, function(picker){ picker.startup(); });
+		this.inherited(arguments);
+	},
+
 	setBrdColor: function(color){
 		this.brdColor = color;
-		dojo.style(this.borderCol, "backgroundColor", color);
+		domStyle.set(this.borderCol, "backgroundColor", color);
 	},
-	
+
 	setBkColor: function(color){
 		this.bkColor = color;
-		dojo.style(this.backgroundCol, "backgroundColor", color);
+		domStyle.set(this.backgroundCol, "backgroundColor", color);
 	},
 	onSet: function(){
-		dojo.attr(this.table, "borderColor", this.brdColor);
-		dojo.attr(this.table, "bgColor", this.bkColor);
+		domStyle.set(this.table, "borderColor", this.brdColor);
+		domStyle.set(this.table, "backgroundColor", this.bkColor);
 		if(this.selectWidth.get("value")){
 			// Just in case, remove it from style since we're setting it as a table attribute.
-			dojo.style(this.table, "width", "");
-			dojo.attr(this.table, "width", (this.selectWidth.get("value") + ((this.selectWidthType.get("value")=="pixels")?"":"%") ));
+			domStyle.set(this.table, "width", "");
+			domAttr.set(this.table, "width", (this.selectWidth.get("value") + ((this.selectWidthType.get("value")=="pixels")?"":"%") ));
 		}
-		dojo.attr(this.table, "border", this.selectBorder.get("value"));
-		dojo.attr(this.table, "cellPadding", this.selectPad.get("value"));
-		dojo.attr(this.table, "cellSpacing", this.selectSpace.get("value"));
-		dojo.attr(this.table, "align", this.selectAlign.get("value"));
+		domAttr.set(this.table, "border", this.selectBorder.get("value"));
+		domAttr.set(this.table, "cellPadding", this.selectPad.get("value"));
+		domAttr.set(this.table, "cellSpacing", this.selectSpace.get("value"));
+		domAttr.set(this.table, "align", this.selectAlign.get("value"));
 		var c = dojo.connect(this, "onHide", function(){
 			dojo.disconnect(c);
 			var self = this;
@@ -1168,56 +1020,242 @@ dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog, diji
 
 	onSetTable: function(tableText){
 		//stub
+	}
+});
+
+var ModifyTable = declare("dojox.editor.plugins.ModifyTable", TablePlugins, {
+	// colorPicker: Constructor
+	//		The color picker dijit to use, defaults to dijit/form/ColorPalette
+	colorPicker: ColorPalette,
+
+	modTable: function(){
+		if (!this.editor._tablePluginHandler.checkAvailable()) {return;}
+		var o = this.getTableInfo();
+		//console.log("LAUNCH DIALOG");
+
+		var w = new EditorModifyTableDialog({
+			table:o.tbl,
+			colorPicker: typeof this.colorPicker === 'string' ? require(this.colorPicker) : this.colorPicker,
+			params: this.params
+		});
+		w.show();
+		this.connect(w, "onSetTable", function(color){
+			// uhm... not sure whats going on here...
+			var o = this.getTableInfo();
+			//console.log("set color:", color);
+			domStyle.set(o.td, "backgroundColor", color);
+		});
+	}
+});
+
+var CellColorDropDown = declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+	// summary:
+	//		A simple widget that uses/creates a dropdown with a customisable color picker.  Also provides
+	//		passthroughs to the value of the color picker and convenient hook points.
+	// tags:
+	//		private
+
+	// colorPicker: Constructor
+	//		The color picker dijit to use, defaults to dojox/widget/ColorPicker
+	colorPicker: ColorPicker,
+
+	// templateString: String
+	//		The template used to create the ColorPicker.
+	templateString:
+		"<div style='display: none; position: absolute; top: -10000; z-index: -10000'>" +
+			"<div dojoType='dijit.TooltipDialog' dojoAttachPoint='dialog' class='dojoxEditorColorPicker'>" +
+				"<div dojoAttachPoint='_colorPicker'></div>" +
+				"<div style='margin: 0.5em 0em 0em 0em'>" +
+					"<button dojoType='dijit.form.Button' type='submit' dojoAttachPoint='_setButton'>${buttonSet}</button>" +
+					" " +
+					"<button dojoType='dijit.form.Button' type='button' dojoAttachPoint='_cancelButton'>${buttonCancel}</button>" +
+				"</div>" +
+			"</div>" +
+		"</div>",
+
+	// widgetsInTemplate: Boolean
+	//		Flag denoting widgets are contained in the template.
+	widgetsInTemplate: true,
+
+	constructor: function(){
+		// summary:
+		//		Constructor over-ride so that the translated strings are mixed in so
+		//		the template fills out.
+		dojo.mixin(this, tableDialogStrings);
+	},
+	postCreate: function() {
+		// summary:
+		//		Create color picker dynamically rather than hardcode in template.
+		var ColorPicker = typeof this.colorPicker == "string" ? require(this.colorPicker) : this.colorPicker;
+		this._colorPicker = new ColorPicker({
+			params: this.params
+		}, this._colorPicker);
 	},
 
-	destroy: function(){
+	startup: function(){
 		// summary:
-		//		Cleanup function.
-		this.inherited(arguments);
-		dojo.forEach(this._cleanupWidgets, function(w){
-			if(w && w.destroy){
-				w.destroy();
-			}
-		});
-		delete this._cleanupWidgets;
+		//		Over-ride of startup to do the basic connect setups and such.
+		if(!this._started){
+			this.inherited(arguments);
+			this.connect(this.dialog, "execute", function(){
+				this.onChange(this.get("value"));
+			});
+			this.connect(this._cancelButton, "onClick", function(){
+				dijit.popup.close(this.dialog);
+			});
+			this.connect(this.dialog, "onCancel", "onCancel");
+
+			// Fully started, so go ahead and remove the hide.
+			dojo.style(this.domNode, "display", "block");
+		}
+	},
+
+	_setValueAttr: function(value, priorityChange){
+		// summary:
+		//		Passthrough function for the color picker value.
+		// value: String
+		//		The value to set in the color picker
+		// priorityChange:
+		//		Value to indicate whether or not to trigger an onChange event.
+		this._colorPicker.set("value", value, priorityChange);
+	},
+
+	_getValueAttr: function(){
+		// summary:
+		//		Passthrough function for the color picker value.
+		return this._colorPicker.get("value");
+	},
+
+	onChange: function(value){
+		// summary:
+		//		Hook point to get the value when the color picker value is selected.
+		// value: String
+		//		The value from the color picker.
+	},
+
+	onCancel: function(){
+		// summary:
+		//		Hook point to get when the dialog is canceled.
 	}
 });
 
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	// make first character lower case
-	if(o.args && o.args.command){
-		var cmd = o.args.command.charAt(0).toLowerCase()+o.args.command.substring(1,o.args.command.length);
-		
-		switch(cmd){
-			case "insertTableRowBefore":
-			case "insertTableRowAfter":
-			case "insertTableColumnBefore":
-			case "insertTableColumnAfter":
-			case "deleteTableRow":
-			case "deleteTableColumn":
-				o.plugin = new dojox.editor.plugins.TablePlugins({commandName: cmd});
-				break;
-
-			case "colorTableCell":
-				o.plugin = new dojox.editor.plugins.ColorTableCell({commandName: cmd});
-				break;
-
-			case "modifyTable":
-				o.plugin = new dojox.editor.plugins.ModifyTable({commandName: cmd});
-				break;
-
-			case "insertTable":
-				o.plugin = new dojox.editor.plugins.InsertTable({commandName: cmd});
-				break;
-
-			case "tableContextMenu":
-				o.plugin = new dojox.editor.plugins.TableContextMenu({commandName: cmd});
-				break;
+var ColorTableCell = declare("dojox.editor.plugins.ColorTableCell", TablePlugins, {
+	// colorPicker: Constructor
+	//		The color picker dijit to use, defaults to dojox/widget/ColorPicker
+	colorPicker: ColorPicker,
+
+	constructor: function(){
+		// summary:
+		//		Initialize ColorTableCell plugin
+		this.closable = true;
+		this.buttonClass = dijit.form.DropDownButton;
+
+		var self = this,
+			picker,
+			pickerInit = {
+				colorPicker: this.colorPicker,
+				params: this.params
+			};
+
+		// We may have been given the dropdown to use, or we can use a default.
+		if(!this.dropDown){
+			// Create our default dropdown dialog
+			picker = new CellColorDropDown(pickerInit);
+			picker.startup(); // we don't have startup so just invoke it now
+
+			// In this case the dropdown isn't the thing firing events, its
+			//  dialog is.
+			this.dropDown = picker.dialog;
+		}else{
+			// Assume the dropdown we've been given is the picker we should attach to.
+			picker = this.dropDown;
+			picker.set(pickerInit);
 		}
+		this.connect(picker, "onChange", function(color){
+			this.editor.focus();
+			this.modTable(null, color);
+		});
+		this.connect(picker, "onCancel", function(){
+			this.editor.focus();
+		});
+		// Calculate and assign value before onOpen fires, so onOpen may rely on
+		//  having a value when it runs.
+		aspect.before(this.dropDown, "onOpen", function(){
+			var o = self.getTableInfo(),
+				tds = self.getSelectedCells(o.tbl);
+			if(tds && tds.length > 0){
+				var t = tds[0] === self.lastObject ? tds[0] : tds[tds.length - 1],
+					color;
+				while(t && t !== self.editor.document && ((color = dojo.style(t, "backgroundColor")) === "transparent" || color.indexOf("rgba") === 0)){
+					t = t.parentNode;
+				}
+				if(color !== "transparent" && color.indexOf("rgba") !== 0){
+					picker.set('value', Color.fromString(color).toHex());
+				}
+			}
+		});
+		this.connect(this, "setEditor", function(editor){
+			editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+				this.connect(this.editor.editNode, "onmouseup", function(evt){
+					this.lastObject = evt.target;
+				});
+			}));
+		});
+	},
+	
+	_initButton: function(){
+		this.command = this.name;
+
+		this.label = this.editor.commands[this.command] = this._makeTitle(this.command);
+		this.inherited(arguments);
+		delete this.command;
+
+		this.onDisplayChanged(false);
+	},
+
+	modTable: function(cmd, args){
+		// summary:
+		//		Where each plugin performs its action.
+		//		Note: not using execCommand. In spite of their presence in the
+		//		Editor as query-able plugins, I was not able to find any evidence
+		//		that they are supported (especially in NOT IE). If they are
+		//		supported in other browsers, it may help with the undo problem.
+
+		this.begEdit();
+		var o = this.getTableInfo();
+		// The one plugin that really needs use of the very verbose
+		//	getSelectedCells()
+		var tds = this.getSelectedCells(o.tbl);
+		//console.debug("SELECTED CELLS ", tds , " FOR ", o);
+		dojo.forEach(tds, function(td){
+			dojo.style(td, "backgroundColor", args);
+		});
+		this.endEdit();
 	}
 });
 
-return dojox.editor.plugins.TablePlugins;
+// Register these plugins.
+function registerGeneric(args) {
+	return new TablePlugins(args);
+}
+_Plugin.registry["insertTableRowBefore"] = registerGeneric;
+_Plugin.registry["insertTableRowAfter"] = registerGeneric;
+_Plugin.registry["insertTableColumnBefore"] = registerGeneric;
+_Plugin.registry["insertTableColumnAfter"] = registerGeneric;
+_Plugin.registry["deleteTableRow"] = registerGeneric;
+_Plugin.registry["deleteTableColumn"] = registerGeneric;
+_Plugin.registry["colorTableCell"] = function(args) {
+	return new ColorTableCell(args);
+};
+_Plugin.registry["modifyTable"] = function(args) {
+	return new ModifyTable(args);
+};
+_Plugin.registry["insertTable"] = function(args) {
+	return new InsertTable(args);
+};
+_Plugin.registry["tableContextMenu"] = function(args) {
+	return new TableContextMenu(args);
+};
 
+return TablePlugins;
 });
diff --git a/dojox/editor/plugins/TextColor.js b/dojox/editor/plugins/TextColor.js
index 1ebc8e9..7172e59 100755
--- a/dojox/editor/plugins/TextColor.js
+++ b/dojox/editor/plugins/TextColor.js
@@ -6,21 +6,22 @@ define([
 	"dijit/_Widget",
 	"dijit/_TemplatedMixin",
 	"dijit/_WidgetsInTemplateMixin",
+	"dijit/_editor/_Plugin",
 	"dijit/TooltipDialog",
 	"dijit/form/Button",
 	"dijit/form/DropDownButton",
-	"dijit/_editor/_Plugin",
 	"dojox/widget/ColorPicker",
 	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/i18n!dojox/editor/plugins/nls/TextColor"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, popup, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _Plugin) {
 
 dojo.experimental("dojox.editor.plugins.TextColor");
-dojo.declare("dojox.editor.plugins._TextColorDropDown", [dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
+
+var TextColorDropDown = dojo.declare("dojox.editor.plugins._TextColorDropDown", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
 	// summary:
-	//		A smple widget that uses/creates a dropdown with a dojox.widget.ColorPicker.  Also provides
+	//		A sample widget that uses/creates a dropdown with a dojox.widget.ColorPicker.  Also provides
 	//		passthroughs to the value of the color picker and convenient hook points.
 	// tags:
 	//		private
@@ -98,25 +99,25 @@ dojo.declare("dojox.editor.plugins._TextColorDropDown", [dijit._Widget, dijit._T
 });
 
 
-dojo.declare("dojox.editor.plugins.TextColor", dijit._editor._Plugin, {
+var TextColor = dojo.declare("dojox.editor.plugins.TextColor", _Plugin, {
 	// summary:
 	//		This plugin provides dropdown color pickers for setting text color and background color
 	//		and makes use of the nicer-looking (though not entirely accessible), dojox.widget.ColorPicker.
 	//
 	// description:
 	//		The commands provided by this plugin are:
-	//		* foreColor - sets the text color
-	//		* hiliteColor - sets the background color
+	//
+	//		- foreColor - sets the text color
+	//		- hiliteColor - sets the background color
 	
 	// Override _Plugin.buttonClass to use DropDownButton (with ColorPalette) to control this plugin
 	buttonClass: dijit.form.DropDownButton,
 	
-	// useDefaultCommand: Boolean
-	//		False as we do not use the default editor command/click behavior.
+	// False as we do not use the default editor command/click behavior.
 	useDefaultCommand: false,
 
 	constructor: function(){
-		this._picker = new dojox.editor.plugins._TextColorDropDown();
+		this._picker = new TextColorDropDown();
 		dojo.body().appendChild(this._picker.domNode);
 		this._picker.startup();
 		this.dropDown = this._picker.dialog;
@@ -189,6 +190,9 @@ dojo.declare("dojox.editor.plugins.TextColor", dijit._editor._Plugin, {
 	}
 });
 
+// For monkey-patching
+TextColor._TextColorDropDown = TextColorDropDown;
+
 // Register this plugin.  Uses the same name as the dijit one, so you
 // use one or the other, not both.
 dojo.subscribe(dijit._scopeName + ".Editor.getPlugin", null, function(o){
@@ -198,12 +202,12 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin", null, function(o){
 	switch(o.args.name){
 		case "foreColor":
 		case "hiliteColor":
-			o.plugin = new dojox.editor.plugins.TextColor({
+			o.plugin = new TextColor({
 				command: o.args.name
 			});
 	}
 });
 
-return dojox.editor.plugins.TextColor;
+return TextColor;
 
 });
diff --git a/dojox/editor/plugins/ToolbarLineBreak.js b/dojox/editor/plugins/ToolbarLineBreak.js
index 8c47c62..b40f2e1 100755
--- a/dojox/editor/plugins/ToolbarLineBreak.js
+++ b/dojox/editor/plugins/ToolbarLineBreak.js
@@ -5,18 +5,19 @@ define([
 	"dijit/_Widget",
 	"dijit/_TemplatedMixin",
 	"dijit/_editor/_Plugin",
-	"dojo/_base/connect",
 	"dojo/_base/declare"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Widget, _TemplatedMixin, _Plugin, declare) {
 
-dojo.declare("dojox.editor.plugins.ToolbarLineBreak",
-	[ dijit._Widget, dijit._TemplatedMixin ],
+var ToolbarLineBreak = declare("dojox.editor.plugins.ToolbarLineBreak",
+	[ _Widget, _TemplatedMixin ],
 	{
 	// summary:
 	//		A 'line break' between two `dijit.Toolbar` items so that very
 	//		long toolbars can be organized a bit.
 	templateString: "<span class='dijit dijitReset'><br></span>",
-	postCreate: function(){ dojo.setSelectable(this.domNode, false); },
+	postCreate: function(){
+		dojo.setSelectable(this.domNode, false);
+	},
 	isFocusable: function(){
 		// summary:
 		//		This widget isn't focusable, so pass along that fact.
@@ -32,8 +33,8 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	var name = o.args.name.toLowerCase();
 	if(name ===  "||" || name === "toolbarlinebreak"){
-		o.plugin = new dijit._editor._Plugin({
-			button: new dojox.editor.plugins.ToolbarLineBreak(),
+		o.plugin = new _Plugin({
+			button: new ToolbarLineBreak(),
 			setEditor: function(editor){
 				this.editor = editor;
 			}
@@ -41,6 +42,6 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	}
 });
 
-return dojox.editor.plugins.ToolbarLineBreak;
+return ToolbarLineBreak;
 
 });
diff --git a/dojox/editor/plugins/UploadImage.js b/dojox/editor/plugins/UploadImage.js
index 0fc294e..3f76f27 100644
--- a/dojox/editor/plugins/UploadImage.js
+++ b/dojox/editor/plugins/UploadImage.js
@@ -7,17 +7,15 @@ define([
 	"dojo/_base/declare",
 	"dojox/form/FileUploader",
 	"dijit/_editor/_Plugin"
-], function(dojo, dijit, dojox) {
+], function(dojo, dijit, dojox, _Plugin) {
 
-dojo.experimental("dojox.editor.plugins.UploadImage");
+	dojo.experimental("dojox.editor.plugins.UploadImage");
 
-dojo.declare("dojox.editor.plugins.UploadImage",
-	dijit._editor._Plugin,
-	{
-		//summary:
-		// 	Adds an icon to the Editor toolbar that when clicked, opens a system dialog
-		//	Although the toolbar icon is a tiny "image" the uploader could be used for
-		//	any file type
+	var UploadImage = dojo.declare("dojox.editor.plugins.UploadImage", _Plugin, {
+		// summary:
+		// 		Adds an icon to the Editor toolbar that when clicked, opens a system dialog
+		//		Although the toolbar icon is a tiny "image" the uploader could be used for
+		//		any file type
 		
 		tempImageUrl: "",
 		iconClassPrefix: "editorIcon",
@@ -51,7 +49,7 @@ dojo.declare("dojox.editor.plugins.UploadImage",
 				height:"20px",
 				paddingLeft:"8px",
 				paddingRight:"8px"
-			})
+			});
 			this.button = new dojox.form.FileUploader({
 				isDebug:true,
 				//force:"html",
@@ -70,7 +68,7 @@ dojo.declare("dojox.editor.plugins.UploadImage",
 		onComplete: function(data,ioArgs,widgetRef){
 			data = data[0];
 			// Image is ready to insert
-			var tmpImgNode = dojo.withGlobal(this.editor.window, "byId", dojo, [this.currentImageId]);
+			var tmpImgNode = dojo.byId(this.currentImageId, this.editor.document);
 			var file;
 			// download path is mainly used so we can access a PHP script
 			// not relative to this file. The server *should* return a qualified path.
@@ -90,24 +88,22 @@ dojo.declare("dojox.editor.plugins.UploadImage",
 		},
 		
 		insertTempImage: function(){
-			// inserting a "busy" image to show something is hapening
-			//	during upload and download of the image.
+			// summary:
+			//		inserting a "busy" image to show something is hapening
+			//		during upload and download of the image.
 			this.currentImageId = "img_"+(new Date().getTime());
 			var iTxt = '<img id="'+this.currentImageId+'" src="'+this.tempImageUrl+'" width="32" height="32"/>';
 			this.editor.execCommand('inserthtml', iTxt);
 		}
-		
-	}
-);
+	});
 
-dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-	if(o.plugin){ return; }
-	switch(o.args.name){
-	case "uploadImage":
-		o.plugin = new dojox.editor.plugins.UploadImage({url: o.args.url});
-	}
-});
-
-return dojox.editor.plugins.UploadImage;
+	dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+		if(o.plugin){ return; }
+		switch(o.args.name){
+		case "uploadImage":
+			o.plugin = new UploadImage({url: o.args.url});
+		}
+	});
 
+	return UploadImage;
 });
diff --git a/dojox/editor/plugins/_SmileyPalette.js b/dojox/editor/plugins/_SmileyPalette.js
index 070cee7..53281f8 100644
--- a/dojox/editor/plugins/_SmileyPalette.js
+++ b/dojox/editor/plugins/_SmileyPalette.js
@@ -9,141 +9,135 @@ define([
 	"dojo/_base/declare",
 	"dojo/i18n",
 	"dojo/i18n!dojox/editor/plugins/nls/Smiley"
-], function(dojo, dijit, dojox) {
-
-dojo.experimental("dojox.editor.plugins._SmileyPalette");
-
-dojo.declare("dojox.editor.plugins._SmileyPalette",
-	[dijit._Widget, dijit._TemplatedMixin, dijit._PaletteMixin],
-	{
-	// summary:
-	//		A keyboard accessible emoticon-picking widget (for inserting smiley characters)
-	// description:
-	//		Grid showing various emoticons.
-	//		Can be used standalone, or as a popup.
-	//
-	// example:
-	// |	<div dojoType="dojox.editor.plugins._SmileyPalette"></div>
-	//
-	// example:
-	// |	var picker = new dojox.editor.plugins._SmileyPalette({ },srcNode);
-	// |	picker.startup();
-
-	//		The template of this widget.
-	templateString:
-		'<table class="dijitInline dijitEditorSmileyPalette dijitPaletteTable"' +
-		' cellSpacing=0 cellPadding=0><tbody dojoAttachPoint="gridNode"></tbody></table>',
-
-	baseClass: "dijitEditorSmileyPalette",
-
-	_palette: [
+], function(dojo, dijit, dojox, _Widget, _TemplatedMixin, _PaletteMixin) {
+
+	dojo.experimental("dojox.editor.plugins._SmileyPalette");
+
+	var Emoticon = dojo.declare("dojox.editor.plugins.Emoticon",
+		null,
+		{
+			// summary:
+			//		JS Object representing an emoticon
+
+			constructor: function(/*String*/ id){
+				// summary:
+				//	 Create emoticon object from an id (like "smile")
+				// value: String
+				//		alias name 'smile', 'cool' ..
+				this.id = id;
+			},
+
+			getValue: function(){
+				// summary:
+				//		Returns a emoticon string in ascii representation, ex: :-)
+				return Emoticon.ascii[this.id];
+			},
+
+			imgHtml: function(/*String*/ clazz){
+				// summary:
+				//		Return the HTML string for an `<img>` node that shows this smiley
+				var eId = "emoticon" + this.id.substr(0,1).toUpperCase() + this.id.substr(1),
+					src = dojo.moduleUrl("dojox.editor.plugins", "resources/emoticons/" + eId + ".gif"),
+					label = dojo.i18n.getLocalization("dojox.editor.plugins", "Smiley")[eId],
+						html = ['<img src=\"',
+						src,
+						'\" class=\"',
+						clazz,
+						'\" alt=\"',
+						this.getValue(),
+						'\" title=\"',
+						label,
+						'\">'];
+				return html.join("");
+			},
+
+			fillCell: function(/*DOMNode*/cell, /*String*/ blankGif){
+				dojo.place(this.imgHtml("dijitPaletteImg"), cell);
+			}
+	});
+
+	Emoticon.ascii = {
+		smile: ":-)",
+		laughing: "lol",
+		wink: ";-)",
+		grin: ":-D",
+		cool: "8-)",
+		angry: ":-@",
+		half: ":-/",
+		eyebrow: "/:)",
+		frown: ":-(",
+		shy: ":-$",
+		goofy: ":-S",
+		oops: ":-O",
+		tongue: ":-P",
+		idea: "(i)",
+		yes: "(y)",
+		no: "(n)",
+		angel: "0:-)",
+		crying: ":'(",
+		happy: "=)"
+	};
+
+	Emoticon.fromAscii = function(/*String*/str){
+		// summary:
+		//		Factory to create Emoticon object based on string like ":-)" rather than id like "smile"
+		var ascii = Emoticon.ascii;
+		for(var i in ascii){
+			if(str == ascii[i]){
+				return new Emoticon(i);
+			}
+		}
+		return null;
+	};
+
+	var SmileyPalette = dojo.declare("dojox.editor.plugins._SmileyPalette", [_Widget, _TemplatedMixin, _PaletteMixin], {
+		// summary:
+		//		A keyboard accessible emoticon-picking widget (for inserting smiley characters)
+		// description:
+		//		Grid showing various emoticons.
+		//		Can be used standalone, or as a popup.
+
+		// templateString:
+		//		The template of this widget.
+		templateString:
+			'<table class="dijitInline dijitEditorSmileyPalette dijitPaletteTable"' +
+				' cellSpacing=0 cellPadding=0><tbody dojoAttachPoint="gridNode"></tbody></table>',
+
+		baseClass: "dijitEditorSmileyPalette",
+
+		_palette: [
 			["smile", "laughing", "wink", "grin"],
 			["cool", "angry", "half", "eyebrow"],
 			["frown", "shy", "goofy", "oops"],
 			["tongue", "idea", "angel", "happy"],
 			["yes", "no", "crying", ""]
-	],
-
-	dyeClass: 'dojox.editor.plugins.Emoticon',
-
-	buildRendering: function(){
-		// Instantiate the template, which makes a skeleton into which we'll insert a bunch of
-		// <img> nodes
-		this.inherited(arguments);
-
-		var i18n = dojo.i18n.getLocalization("dojox.editor.plugins", "Smiley");
-		
-		// Generate hash from emoticon standard name (like "smile") to translation
-		var emoticonI18n = {};
-		for(var name in i18n){
-			if(name.substr(0,8) == "emoticon"){
-				emoticonI18n[name.substr(8).toLowerCase()] = i18n[name];
-			}
-		}
-        this._preparePalette(
-			this._palette,
-			emoticonI18n
-		);
-	}
-});
+		],
 
-dojo.declare("dojox.editor.plugins.Emoticon",
-	null,
-	{
-		// summary:
-		//		JS Object representing an emoticon
+		dyeClass: Emoticon,
 
-		constructor: function(/*String*/ id){
-			// summary:
-			//	 Create emoticon object from an id (like "smile")
-			// value: String
-			//		alias name 'smile', 'cool' ..
-			this.id = id;
-		},
+		buildRendering: function(){
+			// Instantiate the template, which makes a skeleton into which we'll insert a bunch of
+			// <img> nodes
+			this.inherited(arguments);
 
-		getValue: function(){
-			// summary:
-			//   Returns a emoticon string in ascii representation, ex: :-)
-			return dojox.editor.plugins.Emoticon.ascii[this.id];
-		},
+			var i18n = dojo.i18n.getLocalization("dojox.editor.plugins", "Smiley");
 
-		imgHtml: function(/*String*/ clazz){
-			// summary:
-			//		Return the HTML string for an <img> node that shows this smiley
-			var eId = "emoticon" + this.id.substr(0,1).toUpperCase() + this.id.substr(1),
-				src = dojo.moduleUrl("dojox.editor.plugins", "resources/emoticons/" + eId + ".gif"),
-				label = dojo.i18n.getLocalization("dojox.editor.plugins", "Smiley")[eId],
-					html = ['<img src=\"',
-					src,
-					'\" class=\"',
-					clazz,
-					'\" alt=\"',
-					this.getValue(),
-					'\" title=\"',
-					label,
-					'\">'];
-			return html.join("");
-		},
-
-		fillCell: function(/*DOMNode*/cell, /*String*/ blankGif){
-			dojo.place(this.imgHtml("dijitPaletteImg"), cell);
-		}
-});
-
-dojox.editor.plugins.Emoticon.ascii = {
-	smile: ":-)",
-	laughing: "lol",
-	wink: ";-)",
-	grin: ":-D",
-	cool: "8-)",
-	angry: ":-@",
-	half: ":-/",
-	eyebrow: "/:)",
-	frown: ":-(",
-	shy: ":-$",
-	goofy: ":-S",
-	oops: ":-O",
-	tongue: ":-P",
-	idea: "(i)",
-	yes: "(y)",
-	no: "(n)",
-	angel: "0:-)",
-	crying: ":'(",
-	happy: "=)"
-};
-
-dojox.editor.plugins.Emoticon.fromAscii = function(/*String*/str){
-	// summary:
-	//		Factory to create Emoticon object based on string like ":-)" rather than id like "smile"
-	var ascii = dojox.editor.plugins.Emoticon.ascii;
-	for(var i in ascii){
-		if(str == ascii[i]){
-			return new dojox.editor.plugins.Emoticon(i);
+			// Generate hash from emoticon standard name (like "smile") to translation
+			var emoticonI18n = {};
+			for(var name in i18n){
+				if(name.substr(0,8) == "emoticon"){
+					emoticonI18n[name.substr(8).toLowerCase()] = i18n[name];
+				}
+			}
+			this._preparePalette(
+				this._palette,
+				emoticonI18n
+			);
 		}
-	}
-	return null;
-};
+	});
 
-return dojox.editor.plugins._SmileyPalette;
+	// For monkey-patching
+	SmileyPalette.Emoticon = Emoticon;
 
+	return SmileyPalette;
 });
diff --git a/dojox/editor/plugins/_SpellCheckParser.js b/dojox/editor/plugins/_SpellCheckParser.js
index 4dfd975..aaf3eed 100644
--- a/dojox/editor/plugins/_SpellCheckParser.js
+++ b/dojox/editor/plugins/_SpellCheckParser.js
@@ -5,7 +5,7 @@ define([
 	"dojo/_base/declare"
 ], function(dojo, dojox) {
 
-dojo.declare("dojox.editor.plugins._SpellCheckParser", null, {
+var SpellCheckParser = dojo.declare("dojox.editor.plugins._SpellCheckParser", null, {
 	lang: "english",
 	
 	parseIntoWords: function(/*String*/ text){
@@ -29,7 +29,7 @@ dojo.declare("dojox.editor.plugins._SpellCheckParser", null, {
 		
 		while(index < length){
 			var ch;
-			// Skip the white charactor and need to treat HTML entity respectively
+			// Skip the white character and need to treat HTML entity respectively
 			while(index < length && !isCharExt(ch = text.charAt(index)) && ch != "&"){ index++; }
 			if(ch == "&"){ // An HTML entity, skip it
 				while(++index < length && (ch = text.charAt(index)) != ";" && isCharExt(ch)){}
@@ -60,9 +60,9 @@ dojo.declare("dojox.editor.plugins._SpellCheckParser", null, {
 // Register this parser in the SpellCheck plugin.
 dojo.subscribe(dijit._scopeName + ".Editor.plugin.SpellCheck.getParser", null, function(sp){
 	if(sp.parser){ return; }
-	sp.parser = new dojox.editor.plugins._SpellCheckParser();
+	sp.parser = new SpellCheckParser();
 });
 
-return dojox.editor.plugins._SpellCheckParser;
+return SpellCheckParser;
 
 });
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/AutoSave.js b/dojox/editor/plugins/nls/AutoSave.js
index 35706b9..b9d1efd 100644
--- a/dojox/editor/plugins/nls/AutoSave.js
+++ b/dojox/editor/plugins/nls/AutoSave.js
@@ -13,10 +13,11 @@ define({ root:
 	"saveMessageSuccess": "Saved at ${0}",
 	"saveMessageFail": "Failed to save at ${0}"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -44,5 +45,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/Blockquote.js b/dojox/editor/plugins/nls/Blockquote.js
index 6459f62..2eba7dc 100755
--- a/dojox/editor/plugins/nls/Blockquote.js
+++ b/dojox/editor/plugins/nls/Blockquote.js
@@ -3,10 +3,11 @@ define({ root:
 ({
 	"blockquote": "Blockquote"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -34,5 +35,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/Breadcrumb.js b/dojox/editor/plugins/nls/Breadcrumb.js
index 2a58313..0a9aca5 100755
--- a/dojox/editor/plugins/nls/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/Breadcrumb.js
@@ -9,10 +9,11 @@ define({ root:
 	"moveStart": "Move cursor to start",
 	"moveEnd": "Move cursor to end"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -40,5 +41,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/CollapsibleToolbar.js b/dojox/editor/plugins/nls/CollapsibleToolbar.js
index ebfdb3d..93a425e 100755
--- a/dojox/editor/plugins/nls/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/CollapsibleToolbar.js
@@ -4,10 +4,11 @@ define({ root:
 	"collapse": "Collapse Editor Toolbar",
 	"expand": "Expand Editor Toolbar"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -35,5 +36,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/FindReplace.js b/dojox/editor/plugins/nls/FindReplace.js
index 7584948..710ee21 100755
--- a/dojox/editor/plugins/nls/FindReplace.js
+++ b/dojox/editor/plugins/nls/FindReplace.js
@@ -21,10 +21,11 @@ define({ root:
 	"eofDialogTextFind": "found",
 	"eofDialogTextReplace": "replaced"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -52,5 +53,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/InsertAnchor.js b/dojox/editor/plugins/nls/InsertAnchor.js
index 12eabe8..1799b44 100755
--- a/dojox/editor/plugins/nls/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/InsertAnchor.js
@@ -8,10 +8,11 @@ define({ root:
 	set: "Set",
 	cancel: "Cancel"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -39,5 +40,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/InsertEntity.js b/dojox/editor/plugins/nls/InsertEntity.js
index 7c70ee0..0c3468f 100755
--- a/dojox/editor/plugins/nls/InsertEntity.js
+++ b/dojox/editor/plugins/nls/InsertEntity.js
@@ -3,10 +3,11 @@ define({ root:
 ({
 	insertEntity: "Insert Symbol"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -34,5 +35,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/LocalImage.js b/dojox/editor/plugins/nls/LocalImage.js
index 646901b..81b5d9b 100644
--- a/dojox/editor/plugins/nls/LocalImage.js
+++ b/dojox/editor/plugins/nls/LocalImage.js
@@ -10,10 +10,11 @@ define({ root:
 	prePopuTextUrl: "Enter an image URL",
 	prePopuTextBrowse: " or browse to a local file."
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -41,5 +42,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/PageBreak.js b/dojox/editor/plugins/nls/PageBreak.js
index ebfbe39..2cadf5b 100755
--- a/dojox/editor/plugins/nls/PageBreak.js
+++ b/dojox/editor/plugins/nls/PageBreak.js
@@ -3,10 +3,11 @@ define({ root:
 ({
 	"pageBreak": "Page Break"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -34,5 +35,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/PasteFromWord.js b/dojox/editor/plugins/nls/PasteFromWord.js
index da39440..ad1ac73 100755
--- a/dojox/editor/plugins/nls/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/PasteFromWord.js
@@ -2,13 +2,13 @@ define({ root:
 //begin v1.x content
 ({
 	"pasteFromWord": "Paste From Word",
-	"paste": "Paste",
-	"cancel": "Cancel",
 	"instructions": "Paste the content from Word into the text box below.  Once you are satisfied with the content to insert, press the paste button.  To abort inserting text, press the cancel button."
-}),
+})
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -36,5 +36,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/Preview.js b/dojox/editor/plugins/nls/Preview.js
index 82752e5..e801cc4 100755
--- a/dojox/editor/plugins/nls/Preview.js
+++ b/dojox/editor/plugins/nls/Preview.js
@@ -3,10 +3,11 @@ define({ root:
 ({
 	"preview": "Preview"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -34,5 +35,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/SafePaste.js b/dojox/editor/plugins/nls/SafePaste.js
index 876836c..167b759 100644
--- a/dojox/editor/plugins/nls/SafePaste.js
+++ b/dojox/editor/plugins/nls/SafePaste.js
@@ -7,6 +7,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -24,6 +25,7 @@ define({ root:
 "it": true,
 "hu": true,
 "hr": true,
+"he": true,
 "fr": true,
 "fi": true,
 "es": true,
@@ -31,5 +33,6 @@ define({ root:
 "de": true,
 "da": true,
 "cs": true,
-"ca": true
+"ca": true,
+"bg": true
 });
diff --git a/dojox/editor/plugins/nls/Save.js b/dojox/editor/plugins/nls/Save.js
index 2284a04..e37270d 100755
--- a/dojox/editor/plugins/nls/Save.js
+++ b/dojox/editor/plugins/nls/Save.js
@@ -3,10 +3,11 @@ define({ root:
 ({
 	"save": "Save"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -34,5 +35,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/ShowBlockNodes.js b/dojox/editor/plugins/nls/ShowBlockNodes.js
index 0508a4d..4eef724 100755
--- a/dojox/editor/plugins/nls/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ShowBlockNodes.js
@@ -3,10 +3,11 @@ define({ root:
 ({
 	"showBlockNodes": "Show HTML Block Elements"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -34,5 +35,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/Smiley.js b/dojox/editor/plugins/nls/Smiley.js
index c2a4cfb..af52876 100644
--- a/dojox/editor/plugins/nls/Smiley.js
+++ b/dojox/editor/plugins/nls/Smiley.js
@@ -22,10 +22,11 @@ define({ root:
 	emoticonCrying: "crying",
 	emoticonHappy: "happy"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -53,5 +54,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/SpellCheck.js b/dojox/editor/plugins/nls/SpellCheck.js
index b0ce6c0..06467b6 100644
--- a/dojox/editor/plugins/nls/SpellCheck.js
+++ b/dojox/editor/plugins/nls/SpellCheck.js
@@ -16,10 +16,11 @@ define({ root:
 	iSkipAll: "Skip all like this",
 	iMsg: "No spelling suggestions"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -47,5 +48,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/TableDialog.js b/dojox/editor/plugins/nls/TableDialog.js
index 0a23cf1..2279adf 100644
--- a/dojox/editor/plugins/nls/TableDialog.js
+++ b/dojox/editor/plugins/nls/TableDialog.js
@@ -28,12 +28,17 @@ define({ root:
 	insertTableColumnBeforeLabel: "Add Column Before",
 	insertTableColumnAfterLabel: "Add Column After",
 	deleteTableRowLabel: "Delete Row",
-	deleteTableColumnLabel: "Delete Column"
+	deleteTableColumnLabel: "Delete Column",
+	
+	colorTableCellTitle: "Background Color Table Cell",
+	tableContextMenuTitle: "Table Context Menu"
+	
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -61,6 +66,7 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/TextColor.js b/dojox/editor/plugins/nls/TextColor.js
index d1672d9..b1d59b3 100755
--- a/dojox/editor/plugins/nls/TextColor.js
+++ b/dojox/editor/plugins/nls/TextColor.js
@@ -4,10 +4,11 @@ define({ root:
 	"setButtonText": "Set",
 	"cancelButtonText": "Cancel"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -35,5 +36,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/ar/AutoSave.js b/dojox/editor/plugins/nls/ar/AutoSave.js
index ce79d42..3d569c4 100644
--- a/dojox/editor/plugins/nls/ar/AutoSave.js
+++ b/dojox/editor/plugins/nls/ar/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "حفظ",
 	"saveSettingLabelOn": "تحديد الفترة الزمنية للحفظ الآلي...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "تم الحفظ في ${0}",
 	"saveMessageFail": "فشل في الحفظ في ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/Blockquote.js b/dojox/editor/plugins/nls/ar/Blockquote.js
index c708330..42bf482 100644
--- a/dojox/editor/plugins/nls/ar/Blockquote.js
+++ b/dojox/editor/plugins/nls/ar/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "علامة تنصيص الفقرة"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/Breadcrumb.js b/dojox/editor/plugins/nls/ar/Breadcrumb.js
index c4b7513..9be8d08 100644
--- a/dojox/editor/plugins/nls/ar/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ar/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} تصرفات",
 	"selectContents": "تحديد المحتويات",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "نقل المؤشر للبداية",
 	"moveEnd": "نقل المؤشر للنهاية"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ar/CollapsibleToolbar.js
index de9d828..d3db5e0 100644
--- a/dojox/editor/plugins/nls/ar/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ar/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "طي خط أدوات المحرر",
 	"expand": "توسيع خط أدوات المحرر"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/FindReplace.js b/dojox/editor/plugins/nls/ar/FindReplace.js
index 4ecdb29..cc7c606 100644
--- a/dojox/editor/plugins/nls/ar/FindReplace.js
+++ b/dojox/editor/plugins/nls/ar/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "ايجاد:",
 	"findTooltip": "ادخال نص لايجاد",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "موجودة",
 	"eofDialogTextReplace": "مستبدل"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/InsertAnchor.js b/dojox/editor/plugins/nls/ar/InsertAnchor.js
index acaa18a..428873f 100644
--- a/dojox/editor/plugins/nls/ar/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ar/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "ادراج نقطة التثبيت",
 	title: "خصائص نقطة التثبيت",
@@ -8,6 +7,4 @@ define(
 	set: "تحديد",
 	cancel: "الغاء"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/InsertEntity.js b/dojox/editor/plugins/nls/ar/InsertEntity.js
index 4b3cbc1..b957db9 100644
--- a/dojox/editor/plugins/nls/ar/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ar/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "ادراج رمز"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/LocalImage.js b/dojox/editor/plugins/nls/ar/LocalImage.js
index 147ef33..a69464f 100644
--- a/dojox/editor/plugins/nls/ar/LocalImage.js
+++ b/dojox/editor/plugins/nls/ar/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "ادراج صورة",
 	url: "صورة",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "ادخل عنوان URL لصورة",
 	prePopuTextBrowse: " أو تصفح الى ملف محلي."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/PageBreak.js b/dojox/editor/plugins/nls/ar/PageBreak.js
index 2d11a5a..7639e13 100644
--- a/dojox/editor/plugins/nls/ar/PageBreak.js
+++ b/dojox/editor/plugins/nls/ar/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "فاصل الصفحات"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/PasteFromWord.js b/dojox/editor/plugins/nls/ar/PasteFromWord.js
index 7a19b66..e566ddb 100644
--- a/dojox/editor/plugins/nls/ar/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ar/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "لصق من Word",
-	"paste": "لصق",
-	"cancel": "الغاء",
 	"instructions": "لصق المحتويات من Word الى مربع النص بأسفل. بمجرد أن تكون راضيا عن المحتوى المراد ادراجه، اضغط على اختيار لصق. للتوقف عن ادراج النص، اضغط  اختيار الغاء."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/Preview.js b/dojox/editor/plugins/nls/ar/Preview.js
index 717daa3..55502db 100644
--- a/dojox/editor/plugins/nls/ar/Preview.js
+++ b/dojox/editor/plugins/nls/ar/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "معاينة"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/SafePaste.js b/dojox/editor/plugins/nls/ar/SafePaste.js
new file mode 100644
index 0000000..989290b
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "تم الغاء اتاحة خاصية اللصق المباشر. برجاء لصق المحتويات في مربع الحوار هذا باستخدام لوحة مفاتيح برنامج الاستعراض القياسية أو تحكمات اللصق للقائمة. وبمجرد التحقق من المحتويات التي سيتم ادراجها، اضغط على الاختيار لصق. لايقاف ادراج المحتويات، اضغط على الاختيار الغاء. "
+})
+);
diff --git a/dojox/editor/plugins/nls/ar/Save.js b/dojox/editor/plugins/nls/ar/Save.js
index f193609..d161d2c 100644
--- a/dojox/editor/plugins/nls/ar/Save.js
+++ b/dojox/editor/plugins/nls/ar/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "حفظ"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/ShowBlockNodes.js b/dojox/editor/plugins/nls/ar/ShowBlockNodes.js
index 43a4968..8a5f56c 100644
--- a/dojox/editor/plugins/nls/ar/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ar/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "عرض عناصر كتلة HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/Smiley.js b/dojox/editor/plugins/nls/ar/Smiley.js
index aac1581..0475452 100644
--- a/dojox/editor/plugins/nls/ar/Smiley.js
+++ b/dojox/editor/plugins/nls/ar/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "ادراج شكل متحرك",
 	emoticonSmile: "ابتسامة",
@@ -19,8 +18,7 @@ define(
 	emoticonYes: "نعم",
 	emoticonNo: "لا",
 	emoticonAngel: "ملاك",
-	emoticonCrying: "يبكي"
+	emoticonCrying: "يبكي",
+	emoticonHappy: "سعيد"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/SpellCheck.js b/dojox/editor/plugins/nls/ar/SpellCheck.js
index 7c1cc84..dec08de 100644
--- a/dojox/editor/plugins/nls/ar/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ar/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "فحص هجاء دفعي",
 	unfound: "غير موجودة",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "تخطي كل المماثل لهذا",
 	iMsg: "لا توجد اقتراحات للهجاء"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/TableDialog.js b/dojox/editor/plugins/nls/ar/TableDialog.js
index dd64023..f8769f2 100644
--- a/dojox/editor/plugins/nls/ar/TableDialog.js
+++ b/dojox/editor/plugins/nls/ar/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "‏ادراج جدول‏",
 	modifyTableTitle: "تعديل جدول",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "عرض الجدول:",
 	backgroundColor: "لون الخلفية:",
 	borderColor: "لون الحدود:",
-	borderThickness: "سمك الحدود",
+	borderThickness: "سمك الحدود:",
 	percent: "نسبة مئوية",
 	pixels: "عنصر صورة",
 	"default": "المفترض",
@@ -20,15 +19,15 @@ define(
 	right: "لليمين",
 	buttonSet: "تحديد", // translated elsewhere?
 	buttonInsert: "‏ادراج‏",
-	buttonCancel: "الغاء",
-
+	buttonCancel: "الغاء الأمر",
 	selectTableLabel: "تحديد جدول",
 	insertTableRowBeforeLabel: "اضافة صف قبل",
 	insertTableRowAfterLabel: "اضافة صف بعد",
 	insertTableColumnBeforeLabel: "اضافة عمود قبل",
 	insertTableColumnAfterLabel: "اضافة عمود بعد",
 	deleteTableRowLabel: "حذف صف",
-	deleteTableColumnLabel: "حذف عمود"
+	deleteTableColumnLabel: "حذف عمود",
+	colorTableCellTitle: "لون خلفية خانة الجدول",
+	tableContextMenuTitle: "قائمة سياق الجدول"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/TextColor.js b/dojox/editor/plugins/nls/ar/TextColor.js
index 9acb9d2..749f6a8 100644
--- a/dojox/editor/plugins/nls/ar/TextColor.js
+++ b/dojox/editor/plugins/nls/ar/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "تحديد",
 	"cancelButtonText": "الغاء"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ar/latinEntities.js b/dojox/editor/plugins/nls/ar/latinEntities.js
index 6072590..bdf40b4 100644
--- a/dojox/editor/plugins/nls/ar/latinEntities.js
+++ b/dojox/editor/plugins/nls/ar/latinEntities.js
@@ -1,50 +1,49 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"علامة تعجب معكوسة",
 	cent:"علامة السنت",
 	pound:"علامة الجنيه",
 	curren:"علامة العملة",
-	yen:"علامة نعم\nعلامة nyuan",
-	brvbar:"خط مكسور\nخط أفقي مكسور",
+	yen:"علامة الين n\ علامة اليوان",
+	brvbar:"الشريط الفاصل n\ الشريط الرأسي الفاصل",
 	sect:"علامة القسم",
-	uml:"تقسيم\nتباعد التقسيم",
+	uml:"علامة (..) n\ تباعد علامة(..)",
 	copy:"علامة حقوق النشر",
 	ordf:"مؤشر ترتيبي أنثوي",
-	laquo:"علامة تنصيص بزاوية مزدوجة تشير الى اليسار\nعلامة تنصيص تشير الى اليسار ",
+	laquo:"علامة أقتباس مزدوجة بزاوية لليسار n\ فاصلة معكوسة لليسار",
 	not:"ليست علامة",
-	shy:"وصلة قصيرة لينة\nوصلة قصيرة تقديرية",
-	reg:"علامة مسجلة\nعلامة تجارية مسجلة",
-	macr:"علامة المد\nتباعد علامة المد\nكتابة فوق السطر\nكتابة فوق سطر APL",
+	shy:"شرطة وصل يمكن تجاوزها n\ شرطة وصل تقديرية",
+	reg:"علامة تسجيل n\ العلامة التجارية المسجلة",
+	macr:"علامة المد n\ تباعد علامة المد n\ خط علوي n\ شريط علوي - APL",
 	deg:"علامة الدرجة",
-	plusmn:"علامة زائد-ناقص\nعلامة زائد-أو-ناقص",
-	sup2:"رمز علوي اثنان\nعدد الرمز العلوي اثنان\nمربع",
-	sup3:"رمز علوي ثلاثة\nعدد الرمز العلوي ثلاثة\nمكعب",
-	acute:"علامة النطق الحادة\nتباعد الحادة",
+	plusmn:"علامة جمع-طرح n\ علامة جمع-أو-طرح",
+	sup2:"الرمز العلوي اثنان n\ الرمز العلوي للرقم اثنان n\ مربع",
+	sup3:"الرمز العلوي ثلاثة n\ الرمز العلوي للرقم ثلاثة n\ مكعب",
+	acute:"تشكيل حاد n\ تباعد حاد",
 	micro:"علامة الصغر المتناهي",
-	para:"علامة الفقرة\nعلامة الفقرة",
-	middot:"النقطة الوسطى\nفاصلة جورجية\nنقطة وسطى يونانية",
-	cedil:"علامة السديلة\nتباعد علامة السديلة",
-	sup1:"رمز علوي واحد\nعدد رمز علوي واحد",
+	para:"علامة  (¶) n\ علامة الفقرة",
+	middot:"النقطة الوسطى n\ الفاصلة الجريجورية n\ النقطة الوسطى الأغريقية",
+	cedil:"علامة السديلة n\ تباعد علامة السديلة",
+	sup1:"الرمز العلوي واحد n\ الرمز العلوي للرقم واحد",
 	ordm:"مؤشر ترتيبي مذكر",
-	raquo:"علامة تنصيص بزاوية مزدوجة تشير الى اليمين\nعلامة تنصيص تشير الى اليمين ",
-	frac14:"جزء عام ربع واحد\nجزء ربع واحد",
-	frac12:"جزء عام نصف واحد\nجزء نصف واحد",
-	frac34:"جزء عام ثلاثة أرباع\nجزء ثلاثة أرباع",
-	iquest:"علامة استفهام معكوسة\nعلامة استفهام متحولة",
-	Agrave:"حرف لاتيني كبير A مع حفر\nحرف لاتيني كبير A حفر",
+	raquo:"علامة أقتباس مزدوجة بزاوية لليمين n\ فاصلة معكوسة لليمين",
+	frac14:"الكسر العادي للربع n\ كسر الربع",
+	frac12:"الكسر العادي للنصف n\ كسر النصف",
+	frac34:"كسر عادي للثلاث أرباع n\ كسر الثلاثة أرباع",
+	iquest:"علامة أستفهام عكسية n\ علامة أستفهام عكسية",
+	Agrave:"حرف لاتيني كبير A مع علامة مائلة لليمين n\ حرف لاتيني كبير A مع علامة مائلة لليمين",
 	Aacute:"حرف لاتيني كبير A حاد",
 	Acirc:"حرف لاتيني كبير A مع علامة صوتية",
 	Atilde:"حرف لاتيني كبير A مع علامة التلدة",
 	Auml:"حرف لاتيني كبير A مع علامة حرف العلة",
-	Aring:"حرف لاتيني كبير A مع حلقة فوقه\nحرف لاتيني كبير A حلقة",
-	AElig:"حرف لاتيني كبير AE\nحرف لاتيني كبير مع الحرف المزدوج AE",
+	Aring:"حرف لاتيني كبير A مع علامة دائرية أعلاه n\ حرف لاتيني كبير A مع علامة دائرية أعلاه",
+	AElig:"حرف لاتيني كبير AE n\ حرف لاتيني كبير موصول AE",
 	Ccedil:"حرف لاتيني كبير C مع علامة السديلة",
 	Egrave:"حرف لاتيني كبير  E مع حفر",
 	Eacute:"حرف لاتيني كبير E حاد",
@@ -62,21 +61,21 @@ define(
 	Otilde:"حرف لاتيني كبير O مع علامة التلدة",
 	Ouml:"حرف لاتيني كبير O مع علامة حرف العلة",
 	times:"علامة الضرب",
-	Oslash:"حرف لاتيني كبير O مع حركة منتظمة متكررة\nحرف لاتيني كبير O شرطة مائلة",
+	Oslash:"حرف لاتيني كبير O مع علامة شرطة n\ حرف لاتيني كبير O مع شرطة مائلة",
 	Ugrave:"حرف لاتيني كبير  U مع حفر",
 	Uacute:"حرف لاتيني كبير U حاد",
 	Ucirc:"حرف لاتيني كبير U مع علامة صوتية",
 	Uuml:"حرف لاتيني كبير U مع علامة حرف العلة",
 	Yacute:"حرف لاتيني كبير Y حاد",
 	THORN:"حرف لاتيني كبير THORN",
-	szlig:"حرف لاتيني صغير حاد s\ness-zed",
-	agrave:"حرف لاتيني صغير a مع حفر\nحرف لاتيني صغير a حفر",
+	szlig:"حرف لاتيني صغير حاد s\ ness-zed",
+	agrave:"حرف لاتيني صغير a مع علامة مائلة لليمين n\ حرف لاتيني صغير a مع علامة مائلة لليمين",
 	aacute:"حرف لاتيني صغير a حاد",
 	acirc:"حرف لاتيني صغير a مع علامة صوتية",
 	atilde:"حرف لاتيني صغير a مع علامة التلدة",
 	auml:"حرف لاتيني صغير a مع علامة حرف العلة",
-	aring:"حرف لاتيني صغير a مع حلقة فوقه\nحرف لاتيني صغير a حلقة",
-	aelig:"حرف لاتيني صغير ae\nحرف لاتيني صغير مزدوج ae",
+	aring:"حرف لاتيني صغير a مع علامة دائرية أعلاه n\ حرف لاتيني صغير a مع علامة دائرية أعلاه",
+	aelig:"حرف لاتيني صغير ae n\ حرف لاتيني صغير موصول ae",
 	ccedil:"حرف لاتيني صغير c مع علامة السديلة",
 	egrave:"حرف لاتيني صغير e مع حفر",
 	eacute:"حرف لاتيني صغير e حاد",
@@ -94,7 +93,7 @@ define(
 	otilde:"حرف لاتيني صغير o مع علامة التلدة",
 	ouml:"حرف لاتيني صغير o مع علامة حرف العلة",
 	divide:"علامة القسمة",
-	oslash:"حرف لاتيني صغير o مع حركة منتظمة متكررة\nحرف لاتيني صغير o شرطة مائلة",
+	oslash:"حرف لاتيني صغير o مع علامة شرطة n\ حرف لاتيني صغير o مع شرطة مائلة",
 	ugrave:"حرف لاتيني صغير u مع حفر",
 	uacute:"حرف لاتيني صغير u حاد",
 	ucirc:"حرف لاتيني صغير u مع علامة صوتية",
@@ -102,9 +101,8 @@ define(
 	yacute:"حرف لاتيني صغير y حاد",
 	thorn:"حرف لاتيني صغير طنان",
 	yuml:"حرف لاتيني صغير y مع علامة حرف العلة",
-
 // Greek Characters and Symbols
-	fnof:"حرف لاتيني صغير f مع التواء\nوظيفة\nفلورين",
+	fnof:"الحرف اللاتيني الصغير f مع علامة عقف n\ وظيفة n\ العملة الهولندية",
 	Alpha:"حرف يوناني كبير الفا",
 	Beta:"حرف يوناني كبير beta",
 	Gamma:"حرف يوناني كبير جاما",
@@ -157,23 +155,23 @@ define(
 	thetasym:"حرف يوناني صغير رمز theta",
 	upsih:"upsilon يوناني مع رمز الالتواء",
 	piv:"رمز pi اليوناني",
-	bull:"نقطة\nدائرة سوداء صغيرة",
-	hellip:"علامة حذف أفقية\nافتتاحية بثلاث نقاط",
-	prime:"أولي\nدقائق\nقدم",
-	Prime:"أولي مزدوج\nثواني\nبوصات",
-	oline:"كتابة فوق سطر\nتباعد شطب السطر",
+	bull:"تعداد نقطي n\ دائرة صغيرة سوداء",
+	hellip:"النقاط الأفقية للكلام المحذوف في الجملة n\ النقاط الثلاثة الرئيسية",
+	prime:"أولي n\ دقائق n\ قدم",
+	Prime:"عدد أولي مزدوج n\ ثواني n\ بوصات",
+	oline:"خط علوي n\ تباعد الشرطة العلوية ",
 	frasl:"شرطة مائلة لجزء",
-	weierp:"حرف كبير P للنص\nتحديد الطاقة\nWeierstrass p",
-	image:"حرف كبير أسود I\nجزء تخيلي",
-	real:"حرف كبير أسود R\nرمز الجزء الحقيقي",
+	weierp:"الحرف الكبير P الاستهلالي النصي n\ مجموعة القوة n\ وظيفة p لفيرستراس",
+	image:"الحرف الأسود الكبير I n\ جزء تخيلي",
+	real:"الحرف الأسود الكبير R n\ رمز الجزء الحقيقي",
 	trade:"علامة تجارية",
-	alefsym:"رمز alef\nما وراء المحدود الأساسي الأول",
+	alefsym:"رمز الألف n\ الرقم الأصلي الأول اللانهائي",
 	larr:"سهم متجه لليسار",
 	uarr:"سهم متجه لأعلى",
 	rarr:"سهم متجه لليمين",
 	darr:"سهم متجه لأسفل",
 	harr:"سهم يسار يمين",
-	crarr:"سهم متجه لأسفل مع الاتجاه لليسار بزاوية\nارجاع النقل",
+	crarr:"سهم لأسفل مع زاوية لليسار n\ علامة ادخال",
 	lArr:"سهم مزدوج متجه لليسار",
 	uArr:"سهم مزدوج متجه لأعلى",
 	rArr:"سهم مزدوج متجه لليمين",
@@ -182,27 +180,27 @@ define(
 	forall:"للكل",
 	part:"الفارق الجزئي",
 	exist:"يوجد هناك",
-	empty:"مجموعة خالية\nمجموعة صفرية\nالقطر",
-	nabla:"nabla\nاختلاف عكسي",
+	empty:"مجموعة خالية n\ مجموعة صفرية n\ قطر",
+	nabla:"علامة سهم لأسفل n\ اختلاف عكسي",
 	isin:"عنصر من",
 	notin:"ليس عنصر من",
 	ni:"يتضمن كعضو",
-	prod:"منتج n-ary\nعلامة المنتج",
+	prod:"منتج n-ary n\ علامة المنتج",
 	sum:"جمع n-ary",
 	minus:"علامة الطرح",
 	lowast:"معامل علامة النجمة",
-	radic:"الجذر التربيعي\nعلامة الجذر",
+	radic:"الجذر التربيعي n\ علامة الجذر",
 	prop:"تناسبي الى",
 	infin:"لا نهائي",
 	ang:"زاوية",
-	and:"منطقي و\nعلامة قبعة معكوسة",
-	or:"منطقي أو\nمخروطي",
-	cap:"نقطة تقاطع\ncap",
-	cup:"اتحاد\nكأس","int":"صحيح",
+	and:"منطقي And n\  مثلث متوازي",
+	or:"منطقي Or n\ شكل مخروطي",
+	cap:"تقاطع n\ حرف علوي",
+	cup:"توحيد n\ كأس","int":"صحيح",
 	there4:"لذلك",
-	sim:"معامل علامة التلدة\nيتغير مع\nمماثل مع",
+	sim:"معامل التلدة n\ يختلف مع n\ مماثل الى",
 	cong:"تقريبا مساو الى",
-	asymp:"تقريبا يساوي\nمقارب الى",
+	asymp:"تقريبا مساوي الى n\ مقارب الى",
 	ne:"لا يساوي",
 	equiv:"مماثل الى",
 	le:"أقل من أو يساوي",
@@ -212,20 +210,20 @@ define(
 	nsub:"ليس فرعية من",
 	sube:"فرعية من أو تساوي",
 	supe:"مجاميع من أو تساوي",
-	oplus:"علامة زائد في دائرة\nمجموع مباشر",
-	otimes:"أضعاف في دائرة\nمنتج nvector",
-	perp:"تثبيت لأعلى\nمتعامد على\nعمودي",
+	oplus:"علامة زائد دائرية n\ جمع مباشر",
+	otimes:"علامة ضرب دائرية n\ منتج متجه",
+	perp:"نقطة تعليم لأعلى \n عمودى على \n عمودي",
 	sdot:"معامل النقطة",
-	lceil:"حد أعلى يسار\nAPL upstile",
+	lceil:"حد أعلى يسار n\ حرف APL لأعلى",
 	rceil:"حد أعلى يمين",
-	lfloor:"الطابق الأيسر\nAPL downstile",
+	lfloor:"الطابق اليسار n\ حرف APL لأسفل",
 	rfloor:"الطابق الأيمن",
 	lang:"قوس مربع يشير الى اليسار",
 	rang:"قوس مربع يشير الى اليمين",
 	loz:"المعين",
 	spades:"بدلة بستوني أسود",
-	clubs:"بدلة نادي سوداء\nshamrock",
-	hearts:"بدلة قلب أسود\nvalentine",
+	clubs:"بدلة نادي سوداء n\ شامروك",
+	hearts:"بدلة القلب السوداء n\ عيد الحب",
 	diams:"بدلة شكل معين سوداء",
 	OElig:"حرف لاتيني كبير مزدوج OE",
 	oelig:"حرف لاتيني صغير مزدوج oe",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"علامة تنصيص زاوية منفردة تشير الى اليمين",
 	euro:"علامة اليورو"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/bg/AutoSave.js b/dojox/editor/plugins/nls/bg/AutoSave.js
new file mode 100644
index 0000000..95c3ab2
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/AutoSave.js
@@ -0,0 +1,15 @@
+define(
+({
+	"saveLabel": "Запази",
+	"saveSettingLabelOn": "Задай интервал за автоматично запазване...",
+	"saveSettingLabelOff": "Изключи автоматичното запазване",
+	"saveSettingdialogTitle": "Автоматично запазване",
+	"saveSettingdialogDescription": "Укажи интервал за автоматично запазване",
+	"saveSettingdialogParamName": "Интервал за автоматично запазване",
+	"saveSettingdialogParamLabel": "мин",
+	"saveSettingdialogButtonOk": "Задай интервал",
+	"saveSettingdialogButtonCancel": "Отмени",
+	"saveMessageSuccess": "Запазено в ${0}",
+	"saveMessageFail": "Неуспешно запазване в ${0}"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/Blockquote.js b/dojox/editor/plugins/nls/bg/Blockquote.js
new file mode 100644
index 0000000..4650cb7
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/Blockquote.js
@@ -0,0 +1,5 @@
+define(
+({
+	"blockquote": "Блоков цитат"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/Breadcrumb.js b/dojox/editor/plugins/nls/bg/Breadcrumb.js
new file mode 100644
index 0000000..7c18f83
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/Breadcrumb.js
@@ -0,0 +1,11 @@
+define(
+({
+	"nodeActions": "${nodeName} Действия",
+	"selectContents": "Избери съдържание",
+	"selectElement": "Избери елемент",
+	"deleteElement": "Изтрий елемент",
+	"deleteContents": "Изтрий съдържание",
+	"moveStart": "Премести курсора в началото",
+	"moveEnd": "Премести курсора в края"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/CollapsibleToolbar.js b/dojox/editor/plugins/nls/bg/CollapsibleToolbar.js
new file mode 100644
index 0000000..6c3a64b
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/CollapsibleToolbar.js
@@ -0,0 +1,6 @@
+define(
+({
+	"collapse": "Свиване на лентата с инструменти на редактора",
+	"expand": "Разгъване на лентата с инструменти на редактора"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/FindReplace.js b/dojox/editor/plugins/nls/bg/FindReplace.js
new file mode 100644
index 0000000..0751b77
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/FindReplace.js
@@ -0,0 +1,23 @@
+define(
+({
+	"findLabel": "Намери:",
+	"findTooltip": "Въведи текст за търсене",
+	"replaceLabel": "Подмени с:",
+	"replaceTooltip": "Въведете текст, който да бъде подменен с",
+	"findReplace": "Намери и подмени",
+	"matchCase": "С малки и главни букви",
+	"matchCaseTooltip": "С малки и главни букви",
+	"backwards": "Обратно",
+	"backwardsTooltip": "Обратно търсене за текст",
+	"replaceAllButton": "Подмени всички",
+	"replaceAllButtonTooltip": "Подмени целия текст",
+	"findButton": "Намери",
+	"findButtonTooltip": "Намери текста",
+	"replaceButton": "Подмени",
+	"replaceButtonTooltip": "Подмени текста",
+	"replaceDialogText": "Подменени ${0} прояви.",
+	"eofDialogText": "Последна проява ${0}",
+	"eofDialogTextFind": "намерени",
+	"eofDialogTextReplace": "подменени"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/InsertAnchor.js b/dojox/editor/plugins/nls/bg/InsertAnchor.js
new file mode 100644
index 0000000..dec4d21
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/InsertAnchor.js
@@ -0,0 +1,10 @@
+define(
+({
+	insertAnchor: "Вмъкване на котва",
+	title: "Свойства на котва",
+	anchor: "Име:",
+	text: "Описание:",
+	set: "Задай",
+	cancel: "Отмени"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/InsertEntity.js b/dojox/editor/plugins/nls/bg/InsertEntity.js
new file mode 100644
index 0000000..f7e8708
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/InsertEntity.js
@@ -0,0 +1,5 @@
+define(
+({
+	insertEntity: "Вмъкни символ"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/LocalImage.js b/dojox/editor/plugins/nls/bg/LocalImage.js
new file mode 100644
index 0000000..f2d1f60
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/LocalImage.js
@@ -0,0 +1,12 @@
+define(
+({
+	insertImageTitle: "Вмъкни изображение",
+	url: "Изображение",
+	browse: "Прегледай...",
+	text: "Описание",
+	set: "Вмъкни",
+	invalidMessage: "Невалиден тип на файл на изображение",
+	prePopuTextUrl: "Въведи URL на изображение",
+	prePopuTextBrowse: " или прегледай за локален файл."
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/PageBreak.js b/dojox/editor/plugins/nls/bg/PageBreak.js
new file mode 100644
index 0000000..85adb2a
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/PageBreak.js
@@ -0,0 +1,5 @@
+define(
+({
+	"pageBreak": "Прекъсване на страница"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/PasteFromWord.js b/dojox/editor/plugins/nls/bg/PasteFromWord.js
new file mode 100644
index 0000000..b6ab4f6
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/PasteFromWord.js
@@ -0,0 +1,6 @@
+define(
+({
+	"pasteFromWord": "Постави от Word",
+	"instructions": "Постави съдържанието от Word в текстовото поле по-долу. Когато сте удовлетворени със съдържанието, което вмъкване, натиснете бутона. За да прекратите вмъкването на текст, натиснете бутона за отказ."
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/Preview.js b/dojox/editor/plugins/nls/bg/Preview.js
new file mode 100644
index 0000000..fa9dbbc
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/Preview.js
@@ -0,0 +1,5 @@
+define(
+({
+	"preview": "Предварителен преглед"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/SafePaste.js b/dojox/editor/plugins/nls/bg/SafePaste.js
new file mode 100644
index 0000000..76e72f8
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Директното поставяне е деактивирано. Моля, поставете съдържанието в този диалогов прозорец като ползвате стандартната клавиатура на браузъра или контролите за поставяне в менюто. Когато сте удовлетворени със съдържанието, което вмъкване, натиснете бутона. За да прекратите вмъкването на съдържание, натиснете бутона."
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/Save.js b/dojox/editor/plugins/nls/bg/Save.js
new file mode 100644
index 0000000..ff62a3d
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/Save.js
@@ -0,0 +1,5 @@
+define(
+({
+	"save": "Запази"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/ShowBlockNodes.js b/dojox/editor/plugins/nls/bg/ShowBlockNodes.js
new file mode 100644
index 0000000..7f8673e
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/ShowBlockNodes.js
@@ -0,0 +1,5 @@
+define(
+({
+	"showBlockNodes": "Покажи HTML блокови елементи"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/Smiley.js b/dojox/editor/plugins/nls/bg/Smiley.js
new file mode 100644
index 0000000..185f2c5
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/Smiley.js
@@ -0,0 +1,24 @@
+define(
+({
+	smiley: "Вмъкни емотикон",
+	emoticonSmile: "усмивка",
+	emoticonLaughing: "смях",
+	emoticonWink: "намигане",
+	emoticonGrin: "хилене",
+	emoticonCool: "готин",
+	emoticonAngry: "ядосан",
+	emoticonHalf: "половин усмивка",
+	emoticonEyebrow: "повдигната вежда",
+	emoticonFrown: "смръщен",
+	emoticonShy: "срамежлив",
+	emoticonGoofy: "глупав",
+	emoticonOops: "упс",
+	emoticonTongue: "изплезен",
+	emoticonIdea: "идея",
+	emoticonYes: "да",
+	emoticonNo: "не",
+	emoticonAngel: "ангел",
+	emoticonCrying: "плачещ",
+	emoticonHappy: "щастлив"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/SpellCheck.js b/dojox/editor/plugins/nls/bg/SpellCheck.js
new file mode 100644
index 0000000..7c99bbc
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/SpellCheck.js
@@ -0,0 +1,18 @@
+define(
+({
+	widgetLabel: "Проверка на правопис на групи",
+	unfound: "Не е намерено",
+	skip: "Пропусни",
+	skipAll: "Пропусни всички",
+	toDic: "Добави към речника",
+	suggestions: "Предложения",
+	replace: "Подмени",
+	replaceWith: "Подмени с",
+	replaceAll: "Подмени всички",
+	cancel: "Отмени",
+	msg: "Не са намерени грешки в правописа",
+	iSkip: "Пропусни това",
+	iSkipAll: "Пропусни всички като тези",
+	iMsg: "Няма предложения за изписване"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/TableDialog.js b/dojox/editor/plugins/nls/bg/TableDialog.js
new file mode 100644
index 0000000..1dd414d
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/TableDialog.js
@@ -0,0 +1,33 @@
+define(
+({
+	insertTableTitle: "Вмъкни таблица",
+	modifyTableTitle: "Промени таблица",
+	rows: "Редове:",
+	columns: "Колони:",
+	align: "Подравни:",
+	cellPadding: "Попълване на клетки:",
+	cellSpacing: "Разстояние на клетки:",
+	tableWidth: "Ширина на таблица:",
+	backgroundColor: "Цвят на фон:",
+	borderColor: "Цвят на граница:",
+	borderThickness: "Дебелина на граница:",
+	percent: "процент",
+	pixels: "пиксели",
+	"default": "по подразбиране",
+	left: "ляво",
+	center: "централно",
+	right: "дясно",
+	buttonSet: "Задай", // translated elsewhere?
+	buttonInsert: "Вмъкни",
+	buttonCancel: "Отмени",
+	selectTableLabel: "Избери таблица",
+	insertTableRowBeforeLabel: "Добави ред преди",
+	insertTableRowAfterLabel: "Добави ред след",
+	insertTableColumnBeforeLabel: "Добави колона преди",
+	insertTableColumnAfterLabel: "Добави колона след",
+	deleteTableRowLabel: "Изтрий ред",
+	deleteTableColumnLabel: "Изтрий колона",
+	colorTableCellTitle: "Цвят на фон на клетка на таблица",
+	tableContextMenuTitle: "Контекстно меню на таблица"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/TextColor.js b/dojox/editor/plugins/nls/bg/TextColor.js
new file mode 100644
index 0000000..ef6bd88
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/TextColor.js
@@ -0,0 +1,6 @@
+define(
+({
+	"setButtonText": "Задай",
+	"cancelButtonText": "Отмени"
+})
+);
diff --git a/dojox/editor/plugins/nls/bg/latinEntities.js b/dojox/editor/plugins/nls/bg/latinEntities.js
new file mode 100644
index 0000000..4970b27
--- /dev/null
+++ b/dojox/editor/plugins/nls/bg/latinEntities.js
@@ -0,0 +1,257 @@
+define(
+({
+	/* These are already handled in the default RTE
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
+	*/
+	iexcl:"обърнат удивителен знак",
+	cent:"знак за цент",
+	pound:"знак за паунд",
+	curren:"знак за валута",
+	yen:"yen знак\nyuan знак",
+	brvbar:"начупена линия\nbroken вертикална линия",
+	sect:"знак за избор",
+	uml:"трема\nspacing трема",
+	copy:"знак за авторско право",
+	ordf:"индикатор за поредност от женски род",
+	laquo:"насочени наляво двойни ъглови кавички\nнасочени наляво ъглови кавички",
+	not:"not знак",
+	shy:"меко тире\nдискреционно тире",
+	reg:"регистриран знак\nзнак за регистриран търговски знак",
+	macr:"знак за дължина над гласна\nгорна черта с разстояние\nгорна черта\nAPL горна черта",
+	deg:"знак за степен",
+	plusmn:"знак плюс-минус\nзнак плюс или минус",
+	sup2:"горен индекс две\nгорен индекс цифра две\nна квадрат",
+	sup3:"горен индекс три\nгорен индекс цифра три\nна трета",
+	acute:"остро ударение\nударение с разстояние",
+	micro:"микро знак",
+	para:"знак за параграф\nзнак за параграф",
+	middot:"средна точка\nгрузинска запетая\nгръцка средна точка",
+	cedil:"селил\nселил с разстояние",
+	sup1:"горен индекс едно\nгорен индекс цифра едно",
+	ordm:"индикатор за поредност от мъжки род",
+	raquo:"насочени надясно двойни ъглови кавички\nнасочени надясно ъглови кавички",
+	frac14:"простра дроб една четвърт\nдроб една четвърт",
+	frac12:"проста дроб една втора\nдроб една втора",
+	frac34:"проста дроб три четвърти\nдроб три четвърти",
+	iquest:"обърнат въпросителен знак\nобърнат въпросителен знак",
+	Agrave:"Латиница, главна буква A с тежко ударение\nЛатиница, главна буква A с тежко ударение",
+	Aacute:"Латиница, главна буква A с остро ударение",
+	Acirc:"Латиница, главна буква A със сложно ударение",
+	Atilde:"Латиница, главна буква A с тилда",
+	Auml:"Латиница, главна буква A с трема",
+	Aring:"Латиница, главна буква A с кръгче отгоре\nЛатиница, главна буква A с кръгче",
+	AElig:"Латиница, главна буква AE\nЛатиница, главна буква AE",
+	Ccedil:"Латиница, главна буква C със селил",
+	Egrave:"Латиница, главна буква E с тежко ударение",
+	Eacute:"Латиница, главна буква E с остро ударение",
+	Ecirc:"Латиница, главна буква E със сложно ударение",
+	Euml:"Латиница, главна буква E с трема",
+	Igrave:"Латиница, главна буква I с тежко ударение",
+	Iacute:"Латиница, главна буква I с остро ударение",
+	Icirc:"Латиница, главна буква I със сложно ударение",
+	Iuml:"Латиница, главна буква I с трема",
+	ETH:"Латиница, главна буква ETH",
+	Ntilde:"Латиница, главна буква N с тилда",
+	Ograve:"Латиница, главна буква O с тежко ударение",
+	Oacute:"Латиница, главна буква O с остро ударение",
+	Ocirc:"Латиница, главна буква O със сложно ударение",
+	Otilde:"Латиница, главна буква O с тилда",
+	Ouml:"Латиница, главна буква O с трема",
+	times:"знак за умножение",
+	Oslash:"Латиница, главна буква O с черта\nЛатиница, главна буква O с наклонена черта",
+	Ugrave:"Латиница, главна буква U с тежко ударение",
+	Uacute:"Латиница, главна буква U с остро ударение",
+	Ucirc:"Латиница, главна буква U със сложно ударение",
+	Uuml:"Латиница, главна буква U с трема",
+	Yacute:"Латиница, главна буква Y с остро ударение",
+	THORN:"Латиница, главна буква THORN",
+	szlig:"Латиница, малка остра буква s\nесцет",
+	agrave:"Латиница, малка буква с тежко ударение\nЛатиница, малка буква с тежко ударение",
+	aacute:"Латиница, малка буква с остро ударение",
+	acirc:"Латиница, малка буква със сложно ударение",
+	atilde:"Латиница, малка буква с тилда",
+	auml:"Латиница, малка буква с трема",
+	aring:"Латиница, малка буква с кръгче отгоре\nЛатиница, малка буква a, кръгче",
+	aelig:"Латиница, малка буква ae\nЛатиница, Латиница, малка легатура ae",
+	ccedil:"Латиница, малка буква c със селил",
+	egrave:"Латиница, малка буква e с тежко ударение",
+	eacute:"Латиница, малка буква e с остро ударение",
+	ecirc:"Латиница, малка буква e със сложно ударение",
+	euml:"Латиница, малка буква e с трема",
+	igrave:"Латиница, малка буква i с тежко ударение",
+	iacute:"Латиница, малка буква i с остро ударение",
+	icirc:"Латиница, малка буква i със сложно ударение",
+	iuml:"Латиница, малка буква i с трема",
+	eth:"Латиница, малка буква eth",
+	ntilde:"Латиница, малка буква n с тилда",
+	ograve:"Латиница, малка буква o с тежко ударение",
+	oacute:"Латиница, малка буква o с остро ударение",
+	ocirc:"Латиница, малка буква o със сложно ударение",
+	otilde:"Латиница, малка буква o с тилда",
+	ouml:"Латиница, малка буква o с трема",
+	divide:"знак за деление",
+	oslash:"Латиница, малка буква o с черта\nЛатиница, малка буква o, наклонена черта",
+	ugrave:"Латиница, малка буква u с тежко ударение",
+	uacute:"Латиница, малка буква u с остро ударение",
+	ucirc:"Латиница, малка буква u със сложно ударение",
+	uuml:"Латиница, малка буква u с трема",
+	yacute:"Латиница, малка буква y с остро ударение",
+	thorn:"Латиница, малка буква thorn",
+	yuml:"Латиница, малка буква y с трема",
+// Greek Characters and Symbols
+	fnof:"Латиница, малка буква f с кукичка\nфункция\nзнак florin",
+	Alpha:"Гръцка главна буква алфа",
+	Beta:"Гръцка главна буква бета",
+	Gamma:"Гръцка главна буква гама",
+	Delta:"Гръцка главна буква делта",
+	Epsilon:"Гръцка главна буква епсилон",
+	Zeta:"Гръцка главна буква зета",
+	Eta:"Гръцка главна буква ета",
+	Theta:"Гръцка главна буква тета",
+	Iota:"Гръцка главна буква йота",
+	Kappa:"Гръцка главна буква капа",
+	Lambda:"Гръцка главна буква ламбда",
+	Mu:"Гръцка главна буква му",
+	Nu:"Гръцка главна буква ну",
+	Xi:"Гръцка главна буква кси",
+	Omicron:"Гръцка главна буква омикрон",
+	Pi:"Гръцка главна буква пи",
+	Rho:"Гръцка главна буква ро",
+	Sigma:"Гръцка главна буква сигма",
+	Tau:"Гръцка главна буква тау",
+	Upsilon:"Гръцка главна буква упсилон",
+	Phi:"Гръцка главна буква фи",
+	Chi:"Гръцка главна буква чи",
+	Psi:"Гръцка главна буква пси",
+	Omega:"Гръцка главна буква омега",
+	alpha:"Гръцка малка буква алфа",
+	beta:"Гръцка малка буква бета",
+	gamma:"Гръцка малка буква гама",
+	delta:"Гръцка малка буква делта",
+	epsilon:"Гръцка малка буква епсилон",
+	zeta:"Гръцка малка буква зета",
+	eta:"Гръцка малка буква ета",
+	theta:"Гръцка малка буква тета",
+	iota:"Гръцка малка буква йота",
+	kappa:"Гръцка малка буква капа",
+	lambda:"Гръцка малка буква ламбда",
+	mu:"Гръцка малка буква му",
+	nu:"Гръцка малка буква ну",
+	xi:"Гръцка малка буква кси",
+	omicron:"Гръцка малка буква омикрон",
+	pi:"Гръцка малка буква пи",
+	rho:"Гръцка малка буква ро",
+	sigmaf:"Гръцка малка буква крайна сигма",
+	sigma:"Гръцка малка буква сигма",
+	tau:"Гръцка малка буква тау",
+	upsilon:"Гръцка малка буква упсилон",
+	phi:"Гръцка малка буква фи",
+	chi:"Гръцка малка буква чи",
+	psi:"Гръцка малка буква пси",
+	omega:"Гръцка малка буква омега",
+	thetasym:"Гръцка малка буква символ тета",
+	upsih:"Гръцки упсилон със символ кукичка",
+	piv:"Гръцки символ пи",
+	bull:"точка\nчерен малък кръг",
+	hellip:"хоризонтална елипса\nзапълващ знак с три точки",
+	prime:"прим\nминути\nфута",
+	Prime:"двоен прим\nсекунди\nинчове",
+	oline:"горна черта\nразделяща горна черта",
+	frasl:"наклонена дробна черта",
+	weierp:"скрипт главно P\nмножество\nWeierstrass p",
+	image:"главна черна буква I\nимагинерна част",
+	real:"главна черна буква R\nсимвол за реална част",
+	trade:"знам за търговска марка",
+	alefsym:"символ алеф\nпърви трансфинитен кардинал",
+	larr:"ляво насочена стрелка",
+	uarr:"нагоре насочена стрелка",
+	rarr:"дясно насочена стрелка",
+	darr:"надолу насочена стрелка",
+	harr:"лява, дясна стрелка",
+	crarr:"надолу насочена стрелка с ъгъл наляво\nвръщане в началото на реда",
+	lArr:"ляво насочена двойна стрелка",
+	uArr:"нагоре насочена двойна стрелка",
+	rArr:"дясно насочена двойна стрелка",
+	dArr:"надолу насочена двойна стрелка",
+	hArr:"лява, дясна двойна стрелка",
+	forall:"за всички",
+	part:"частен диференциал",
+	exist:"съществува",
+	empty:"празно множество\nнулево множество\nдиаметър",
+	nabla:"набла\nобратна разлика",
+	isin:"елемент от",
+	notin:"не е елемент от",
+	ni:"съдържа като член",
+	prod:"n-арен продукт\nзнак за продукт",
+	sum:"n-арно сумиране",
+	minus:"знак минус",
+	lowast:"оператор звездичка",
+	radic:"корен квадратен\nзнак за радикал",
+	prop:"пропорционално на",
+	infin:"безкрайност",
+	ang:"ъгъл",
+	and:"логически и\nклинобразен знак",
+	or:"логически или\nс триъгълен профил",
+	cap:"сечение\nвръх",
+	cup:"съюз\nчаша","int":"интеграл",
+	there4:"следователно",
+	sim:"оператор тилда\nсе изменя с\nподобно на",
+	cong:"почти равен на",
+	asymp:"почти равен н а\nасимптотичен на",
+	ne:"не е равен на",
+	equiv:"идентичен на",
+	le:"по-малък от или равен на",
+	ge:"по-голям от или равен на",
+	sub:"подмножество от",
+	sup:"разширено множество от",
+	nsub:"не е подмножество от",
+	sube:"подмножество равно от или равно на",
+	supe:"разширено множество равно или равно на",
+	oplus:"Плюс в кръг\nдиректна сума",
+	otimes:"време в кръг\nвекторен продукт",
+	perp:"горен так\nортогонално на\nперпендикулярно",
+	sdot:"оператор точка",
+	lceil:"лява горна граница\nAPL стъпало надолу",
+	rceil:"дясна горна граница",
+	lfloor:"лява долна граница\nAPL стъпало надолу",
+	rfloor:"дясна долна граница",
+	lang:"насочена наляво ъглова скоба",
+	rang:"насочена надясно ъглова скоба",
+	loz:"ромб",
+	spades:"черна пика",
+	clubs:"черна спатия\nдетелина",
+	hearts:"черно сърце\nвалентинка",
+	diams:"черен диамант",
+	OElig:"Латиница, главна лигатура OE",
+	oelig:"Латиница, малка лигатура oe",
+	Scaron:"Латиница, главна буква S със сложно ударение",
+	scaron:"Латиница, малка буква s със сложно ударение",
+	Yuml:"Латиница, главна буква Y с трема",
+	circ:"сложно ударение на изменяща се буква",
+	tilde:"малка тилда",
+	ensp:"N пространство",
+	emsp:"M пространство",
+	thinsp:"тясно пространство",
+	zwnj:"не-съединител с нулева ширина",
+	zwj:"съединител с нулева ширина",
+	lrm:"знак от ляво на дясно",
+	rlm:"знак от дясно на ляво",
+	ndash:"N тире",
+	mdash:"M тире",
+	lsquo:"лява единична кавичка",
+	rsquo:"дясна единична кавичка",
+	sbquo:"единична кавичка ниско-9",
+	ldquo:"лява двойна кавичка",
+	rdquo:"дясна двойна кавичка",
+	bdquo:"двойна кавичка ниско-9",
+	dagger:"дагер",
+	Dagger:"двоен дагер",
+	permil:"знак за промил",
+	lsaquo:"единична насочена наляво ъглова кавичка",
+	rsaquo:"единична насочена надясно ъглова кавичка",
+	euro:"знак за евро"
+})
+);
diff --git a/dojox/editor/plugins/nls/ca/AutoSave.js b/dojox/editor/plugins/nls/ca/AutoSave.js
index 92dd5ea..36d8bf3 100644
--- a/dojox/editor/plugins/nls/ca/AutoSave.js
+++ b/dojox/editor/plugins/nls/ca/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Desa",
 	"saveSettingLabelOn": "Estableix l'interval per desar automàticament...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Desat a les ${0}",
 	"saveMessageFail": "No s'ha pogut desar a les ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/Blockquote.js b/dojox/editor/plugins/nls/ca/Blockquote.js
index e54a9ba..bed9ca8 100644
--- a/dojox/editor/plugins/nls/ca/Blockquote.js
+++ b/dojox/editor/plugins/nls/ca/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Blockquote"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/Breadcrumb.js b/dojox/editor/plugins/nls/ca/Breadcrumb.js
index 2e34c2a..c8ac82b 100644
--- a/dojox/editor/plugins/nls/ca/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ca/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} - Accions",
 	"selectContents": "Selecciona contingut",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Mou el cursor a l'inici",
 	"moveEnd": "Mou el cursor al final"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ca/CollapsibleToolbar.js
index e5bd268..01098c1 100644
--- a/dojox/editor/plugins/nls/ca/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ca/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Redueix la barra d'eines de l'editor",
 	"expand": "Expandeix la barra d'eines de l'editor"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/FindReplace.js b/dojox/editor/plugins/nls/ca/FindReplace.js
index 6a7bb4c..67f28ff 100644
--- a/dojox/editor/plugins/nls/ca/FindReplace.js
+++ b/dojox/editor/plugins/nls/ca/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Cerca:",
 	"findTooltip": "Especifiqueu el text que voleu trobar",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "trobat",
 	"eofDialogTextReplace": "substituït"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/InsertAnchor.js b/dojox/editor/plugins/nls/ca/InsertAnchor.js
index 86704f9..5722def 100644
--- a/dojox/editor/plugins/nls/ca/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ca/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Insereix una àncora",
 	title: "Propietats de l'àncora",
@@ -8,6 +7,4 @@ define(
 	set: "Defineix",
 	cancel: "Cancel·la"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/InsertEntity.js b/dojox/editor/plugins/nls/ca/InsertEntity.js
index e96234b..131e315 100644
--- a/dojox/editor/plugins/nls/ca/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ca/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Insereix símbol"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/LocalImage.js b/dojox/editor/plugins/nls/ca/LocalImage.js
index fdc1957..9053247 100644
--- a/dojox/editor/plugins/nls/ca/LocalImage.js
+++ b/dojox/editor/plugins/nls/ca/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Insereix imatge",
 	url: "Imatge",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Especifiqueu un URL d\'imatge",
 	prePopuTextBrowse: " o navegueu fins un fitxer local."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/PageBreak.js b/dojox/editor/plugins/nls/ca/PageBreak.js
index d7c2e36..23aaa05 100644
--- a/dojox/editor/plugins/nls/ca/PageBreak.js
+++ b/dojox/editor/plugins/nls/ca/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Salt de pàgina"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/PasteFromWord.js b/dojox/editor/plugins/nls/ca/PasteFromWord.js
index 3ddc705..df321ee 100644
--- a/dojox/editor/plugins/nls/ca/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ca/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Enganxa des de Word",
-	"paste": "Enganxa",
-	"cancel": "Cancel·la",
 	"instructions": "Enganxa el contingut de Word al quadre de text següent. Un cop esteu satisfets amb el contingut que voleu inserir, feu clic al botó Enganxa. Per cancel·lar la inserció de text, feu clic al botó Cancel·la."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/Preview.js b/dojox/editor/plugins/nls/ca/Preview.js
index 1049be0..869ef07 100644
--- a/dojox/editor/plugins/nls/ca/Preview.js
+++ b/dojox/editor/plugins/nls/ca/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Visualització prèvia"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/Save.js b/dojox/editor/plugins/nls/ca/Save.js
index 1fb2c0d..38b1cc1 100644
--- a/dojox/editor/plugins/nls/ca/Save.js
+++ b/dojox/editor/plugins/nls/ca/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Desa"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/ShowBlockNodes.js b/dojox/editor/plugins/nls/ca/ShowBlockNodes.js
index cd7e8fd..c506798 100644
--- a/dojox/editor/plugins/nls/ca/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ca/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Mostra elements de bloc HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/Smiley.js b/dojox/editor/plugins/nls/ca/Smiley.js
index 4205666..7d9a50c 100644
--- a/dojox/editor/plugins/nls/ca/Smiley.js
+++ b/dojox/editor/plugins/nls/ca/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Insereix emoticona",
 	emoticonSmile: "somriure",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "plorant",
 	emoticonHappy: "content"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/SpellCheck.js b/dojox/editor/plugins/nls/ca/SpellCheck.js
index c438188..59bb07f 100644
--- a/dojox/editor/plugins/nls/ca/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ca/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Correcció ortogràfica per lots",
 	unfound: "No trobat",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Saltar tots els que són com aquest",
 	iMsg: "No hi ha suggeriments ortogràfics"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/TableDialog.js b/dojox/editor/plugins/nls/ca/TableDialog.js
index eb55edb..1eb81f5 100644
--- a/dojox/editor/plugins/nls/ca/TableDialog.js
+++ b/dojox/editor/plugins/nls/ca/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Insereix taula",
 	modifyTableTitle: "Modifica taula",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Amplada de taula:",
 	backgroundColor: "Color de fons:",
 	borderColor: "Color del contorn",
-	borderThickness: "Gruix del contorn",
+	borderThickness: "Gruix del contorn:",
 	percent: "percentatge",
 	pixels: "píxels",
 	"default": "default",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Defineix", // translated elsewhere?
 	buttonInsert: "Insereix",
 	buttonCancel: "Cancel·la",
-
 	selectTableLabel: "Selecciona taula",
 	insertTableRowBeforeLabel: "Afegeix fila abans",
 	insertTableRowAfterLabel: "Afegeix fila després",
 	insertTableColumnBeforeLabel: "Afegeix columna abans",
 	insertTableColumnAfterLabel: "Afegeix columna després",
 	deleteTableRowLabel: "Suprimeix fila",
-	deleteTableColumnLabel: "Suprimeix columna"
+	deleteTableColumnLabel: "Suprimeix columna",
+	colorTableCellTitle: "Cel·la de taula del color de fons",
+	tableContextMenuTitle: "Menú contextual de la taula"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/TextColor.js b/dojox/editor/plugins/nls/ca/TextColor.js
index ded7693..96307f6 100644
--- a/dojox/editor/plugins/nls/ca/TextColor.js
+++ b/dojox/editor/plugins/nls/ca/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Defineix",
 	"cancelButtonText": "Cancel·la"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ca/latinEntities.js b/dojox/editor/plugins/nls/ca/latinEntities.js
index a39d4e1..0a2852c 100644
--- a/dojox/editor/plugins/nls/ca/latinEntities.js
+++ b/dojox/editor/plugins/nls/ca/latinEntities.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"signe d'exclamació obert",
 	cent:"signe de cèntims",
@@ -14,23 +13,23 @@ define(
 	yen:"signe de ien\nsigne de iuan",
 	brvbar:"barra partida\nbarra vertical partida",
 	sect:"signe de secció",
-	uml:"dièresi\ndièresi d'espai",
+	uml:"dièresi\ndièresi de l'espaiat",
 	copy:"signe de copyright",
 	ordf:"indicador ordinal femení",
 	laquo:"cometes llatines apuntant cap a l'esquerra\ncometes llatines cap a l'esquerra",
 	not:"signe de negació",
 	shy:"guió tou\nguió opcional",
 	reg:"signe de registrat\nsigne de marca comercial registrada",
-	macr:"macron\nmacron d'espaiat\nsobre-ratllat\nguió alt",
+	macr:"macró\nmacró espaiat\nguió alt\nguionet alt APL",
 	deg:"signe de graus",
 	plusmn:"signe de més-menys\nsigne de més-o-menys",
-	sup2:"dos en superíndex\nnúmero dos en superíndex\nal quadrat",
-	sup3:"tres en superíndex\nnúmero tres en superíndex\nal cub",
+	sup2:"superíndex dos\nsuperíndex de dos dígits\nquadrats",
+	sup3:"superíndex tres\nsuperíndex de tres dígits\nelevat al cub",
 	acute:"accent agut\nespaiat agut",
 	micro:"signe de micro",
-	para:"signe de paràgrafn\nsigne de canvi de paràgraf",
+	para:"signe de paràgraf\nsigne de canvi de paràgraf",
 	middot:"punt volat\ncoma georgiana\npunt volat grec",
-	cedil:"ce trencada\nespai de ce trencada",
+	cedil:"c trencada\nc trencada amb espai",
 	sup1:"ú en superíndex\nnúmero ú en superíndex",
 	ordm:"indicador d'ordinal masculí",
 	raquo:"cometes llatines apuntant cap a la dreta\ncometes llatines cap a la dreta",
@@ -44,7 +43,7 @@ define(
 	Atilde:"lletra llatina A majúscula amb titlla",
 	Auml:"lletra llatina A majúscula amb dièresi",
 	Aring:"lletra llatina A majúscula amb anell al damunt\nA majúscula amb anell",
-	AElig:"lletra llatina AE majúscula\n Lligatura llatina AE majúscula",
+	AElig:"lletra llatina AE majúscula\nLligatura llatina AE majúscula",
 	Ccedil:"lletra llatina C trencada majúscula",
 	Egrave:"lletra llatina E majúscula amb accent greu",
 	Eacute:"lletra llatina E majúscula amb accent agut",
@@ -69,14 +68,14 @@ define(
 	Uuml:"lletra llatina U majúscula amb dièresi",
 	Yacute:"lletra llatina Y majúscula amb accent agut",
 	THORN:"lletra llatina THORN majúscula",
-	szlig:"lletra llatina s fina\nesze alemanya",
+	szlig:"lletra llatina s fina\nalemanya",
 	agrave:"Lletra llatina a minúscula amb accent greu\na minúscula amb accent greu",
 	aacute:"lletra llatina a minúscula amb accent agut",
 	acirc:"lletra llatina a minúscula amb circumflex",
 	atilde:"lletra llatina a minúscula amb titlla",
 	auml:"lletra llatina a minúscula amb dièresi",
-	aring:"Lletra llatina a minúscula amb anell\na minúscula amb anell",
-	aelig:"lletra llatina AE minúscula\n Lligatura llatina AE minúscula",
+	aring:"Lletra llatina a minúscula amb anell\nlletra llatina a minúscula amb anell",
+	aelig:"lletra llatina AE minúscula\nLligatura llatina AE minúscula",
 	ccedil:"lletra llatina c trencada minúscula",
 	egrave:"lletra llatina e minúscula amb accent greu",
 	eacute:"lletra llatina e minúscula amb accent agut",
@@ -102,7 +101,6 @@ define(
 	yacute:"lletra llatina y minúscula amb accent agut",
 	thorn:"lletra llatina thorn minúscula",
 	yuml:"lletra llatina y minúscula amb dièresi",
-
 // Greek Characters and Symbols
 	fnof:"lletra llatina f minúscula amb ganxet\nfunció\nflorí",
 	Alpha:"lletra grega alfa majúscula",
@@ -159,15 +157,15 @@ define(
 	piv:"símbol grec de pi",
 	bull:"vinyeta\npetit cercle negre",
 	hellip:"el·lipsi horitzontal\nguia de tres punts",
-	prime:"prima\nminuts\npeus",
-	Prime:"doble prima\nsegons\npolzades",
-	oline:"sobre-ratllat\nespai de guió alt",
+	prime:"cometa simple\nminuts\npeus",
+	Prime:"cometa doble\nsegons\npolzades",
+	oline:"guió alt\nsubratllat espaiat",
 	frasl:"barra de fracció",
-	weierp:"lletra P majúscula de script\nconjunt de potència\np de Weierstrass",
+	weierp:"P estilitzada\nconjunt de potència\np de Weierstrass",
 	image:"I majúscula negra\npart imaginària",
 	real:"R majúscula negra\nsímbol de part real",
 	trade:"signe de marca registrada",
-	alefsym:"símbol d'alef\nprimer cardinal transfinit",
+	alefsym:"símbol àlef\nprimer cardinal transfinit",
 	larr:"fletxa cap a l'esquerra",
 	uarr:"fletxa cap amunt",
 	rarr:"fletxa cap a la dreta",
@@ -182,25 +180,25 @@ define(
 	forall:"per a tot",
 	part:"diferencial parcial",
 	exist:"existeix",
-	empty:"conjunt buit\nconjunt nul\ndiàmetre",
-	nabla:"nabla\ndiferència cap enrere",
+	empty:"conjunt buit\nconjunt de mesura nul·la\ndiàmetre",
+	nabla:"nabla\ndiferència inversa",
 	isin:"és element de",
 	notin:"no és element de",
 	ni:"conté com a membre",
-	prod:"producte n-ari\nsigne de producte",
+	prod:"producte n-ari\nsigne multiplicació",
 	sum:"sumatori n-ari",
 	minus:"signe menys",
 	lowast:"operador asterisc",
-	radic:"arrel quadrada\nsigne de radical",
+	radic:"arrel quadrada\nsigne d'arrel",
 	prop:"proporcional a",
 	infin:"infinit",
 	ang:"angle",
-	and:"i lògic\nfalca",
-	or:"o lògica\nvall",
-	cap:"intersecció\nbarret",
-	cup:"unió\ncopa","int":"integral",
+	and:"lògic i\nconjunció lògica",
+	or:"lògic o\ndisjunció lògica",
+	cap:"intersecció\nU invertida",
+	cup:"unió\nU","int":"integral",
 	there4:"per tant",
-	sim:"operador de titlla\nvaria amb\nsemblant a",
+	sim:"operador de titlla\nvaria amb\nsimilar a",
 	cong:"aproximadament igual que",
 	asymp:"gairebé igual que\nasintòtic amb",
 	ne:"no igual que",
@@ -212,20 +210,20 @@ define(
 	nsub:"no és un sots-conjunt de",
 	sube:"sots-conjunt de o igual que",
 	supe:"super-conjunt de o igual que",
-	oplus:"més encerclat\nsuma directa",
-	otimes:"multiplicació encerclada\nproducte de vectors",
-	perp:"clau aixecat\nortogonal a\nperpendicular",
+	oplus:"cercle amb suma\nsuma directa",
+	otimes:"cercle amb producte\nproducte vectorial",
+	perp:"xinxeta cap amunt\nortogonal\nperpendicular",
 	sdot:"operador de punt",
-	lceil:"sostre esquerre\nAPL amunt",
+	lceil:"sostre esquerre\nL invertida APL",
 	rceil:"sostre dret",
-	lfloor:"terra esquerre\nAPL avall",
+	lfloor:"terra esquerre\nL APL",
 	rfloor:"terra dret",
 	lang:"claudàtor angular apuntant a l'esquerra",
 	rang:"claudàtor angular apuntant a la dreta",
 	loz:"rombe",
 	spades:"pal de piques negre",
 	clubs:"pal de trèbols negre\ntrèbol",
-	hearts:"pal de cors negre\nsant valentí",
+	hearts:"pal de cors negres\nant valentí",
 	diams:"pal de diamants negre",
 	OElig:"lligatura llatina OE majúscula",
 	oelig:"lligatura llatina oe minúscula",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"marca de citació en angle senzilla dreta",
 	euro:"signe de l'euro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/AutoSave.js b/dojox/editor/plugins/nls/cs/AutoSave.js
index 38710b6..45f1e2e 100644
--- a/dojox/editor/plugins/nls/cs/AutoSave.js
+++ b/dojox/editor/plugins/nls/cs/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Uložit",
 	"saveSettingLabelOn": "Nastavit interval pro automatické uložení",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Uloženo v ${0}",
 	"saveMessageFail": "Selhalo uložení v ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/Blockquote.js b/dojox/editor/plugins/nls/cs/Blockquote.js
index 671219c..0a9080d 100644
--- a/dojox/editor/plugins/nls/cs/Blockquote.js
+++ b/dojox/editor/plugins/nls/cs/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Citace v bloku"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/Breadcrumb.js b/dojox/editor/plugins/nls/cs/Breadcrumb.js
index d05a639..1cea26a 100644
--- a/dojox/editor/plugins/nls/cs/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/cs/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "Akce uzlu ${nodeName}",
 	"selectContents": "Vybrat obsah",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Přesunout ukazatel na začátek",
 	"moveEnd": "Přesunout ukazatel na konec"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/CollapsibleToolbar.js b/dojox/editor/plugins/nls/cs/CollapsibleToolbar.js
index 0ee257b..9f5201a 100644
--- a/dojox/editor/plugins/nls/cs/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/cs/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Sbalit panel nástrojů editoru",
 	"expand": "Rozbalit panel nástrojů editoru"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/FindReplace.js b/dojox/editor/plugins/nls/cs/FindReplace.js
index 2689f4c..4390d81 100644
--- a/dojox/editor/plugins/nls/cs/FindReplace.js
+++ b/dojox/editor/plugins/nls/cs/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Najít:",
 	"findTooltip": "Zadejte hledaný text.",
@@ -21,5 +20,4 @@ define(
 	"eofDialogTextFind": "byl nalezen",
 	"eofDialogTextReplace": "byl nahrazen"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/InsertAnchor.js b/dojox/editor/plugins/nls/cs/InsertAnchor.js
index 86cc6ad..33b0e83 100644
--- a/dojox/editor/plugins/nls/cs/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/cs/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Vložit kotvu",
 	title: "Vlastnosti kotvy",
@@ -8,6 +7,4 @@ define(
 	set: "Nastavit",
 	cancel: "Storno"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/InsertEntity.js b/dojox/editor/plugins/nls/cs/InsertEntity.js
index b291fdd..9eab7f7 100644
--- a/dojox/editor/plugins/nls/cs/InsertEntity.js
+++ b/dojox/editor/plugins/nls/cs/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Vložit symbol"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/LocalImage.js b/dojox/editor/plugins/nls/cs/LocalImage.js
index a5e34e9..1cd446a 100644
--- a/dojox/editor/plugins/nls/cs/LocalImage.js
+++ b/dojox/editor/plugins/nls/cs/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Vložit obrázek",
 	url: "Obrázek",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Zadejte adresu URL obrázku",
 	prePopuTextBrowse: " nebo vyhledejte lokální soubor."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/PageBreak.js b/dojox/editor/plugins/nls/cs/PageBreak.js
index f83f61f..c1b27a0 100644
--- a/dojox/editor/plugins/nls/cs/PageBreak.js
+++ b/dojox/editor/plugins/nls/cs/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Zalomení stránky"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/PasteFromWord.js b/dojox/editor/plugins/nls/cs/PasteFromWord.js
index 6f743dd..24a7ad8 100644
--- a/dojox/editor/plugins/nls/cs/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/cs/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Vložit z aplikace Word",
-	"paste": "Vložit",
-	"cancel": "Storno",
 	"instructions": "Vložte obsah z aplikace Word do zobrazeného textového pole. Jakmile jste s vkládaným obsahem spokojeni, stiskněte tlačítko Vložit. Pomocí tlačítka Storno vkládání zrušíte."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/Preview.js b/dojox/editor/plugins/nls/cs/Preview.js
index 987a780..2bc5833 100644
--- a/dojox/editor/plugins/nls/cs/Preview.js
+++ b/dojox/editor/plugins/nls/cs/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Náhled"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/Save.js b/dojox/editor/plugins/nls/cs/Save.js
index dc8988a..733d55f 100644
--- a/dojox/editor/plugins/nls/cs/Save.js
+++ b/dojox/editor/plugins/nls/cs/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Uložit"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/ShowBlockNodes.js b/dojox/editor/plugins/nls/cs/ShowBlockNodes.js
index 85093c4..5e2cc41 100644
--- a/dojox/editor/plugins/nls/cs/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/cs/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Zobrazit prvky bloku kódu HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/Smiley.js b/dojox/editor/plugins/nls/cs/Smiley.js
index 045e968..3b1a190 100644
--- a/dojox/editor/plugins/nls/cs/Smiley.js
+++ b/dojox/editor/plugins/nls/cs/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Vložit emotikonu",
 	emoticonSmile: "úsměv",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "pláč",
 	emoticonHappy: "veselý"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/SpellCheck.js b/dojox/editor/plugins/nls/cs/SpellCheck.js
index e07ef93..b0fb9d6 100644
--- a/dojox/editor/plugins/nls/cs/SpellCheck.js
+++ b/dojox/editor/plugins/nls/cs/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Dávková kontrola pravopisu",
 	unfound: "Nenalezeno",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Přeskočit všechny podobné výskyty",
 	iMsg: "Žádné návrhy pravopisu"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/TableDialog.js b/dojox/editor/plugins/nls/cs/TableDialog.js
index 3d9a484..33f7a1b 100644
--- a/dojox/editor/plugins/nls/cs/TableDialog.js
+++ b/dojox/editor/plugins/nls/cs/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Vložit tabulku",
 	modifyTableTitle: "Upravit tabulku",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Šířka tabulky:",
 	backgroundColor: "Barva pozadí:",
 	borderColor: "Barva ohraničení:",
-	borderThickness: "TloušťkaOhraničení",
+	borderThickness: "Tloušťka ohraničení:",
 	percent: "procent",
 	pixels: "pixelů",
 	"default": "výchozí",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Nastavit", // translated elsewhere?
 	buttonInsert: "Vložit",
 	buttonCancel: "Storno",
-
 	selectTableLabel: "Vybrat tabulku",
 	insertTableRowBeforeLabel: "Přidat řádek před",
 	insertTableRowAfterLabel: "Přidat řádek za",
 	insertTableColumnBeforeLabel: "Přidat sloupec před",
 	insertTableColumnAfterLabel: "Přidat sloupec za",
 	deleteTableRowLabel: "Odstranit řádek",
-	deleteTableColumnLabel: "Odstranit sloupec"
+	deleteTableColumnLabel: "Odstranit sloupec",
+	colorTableCellTitle: "Buňka tabulky barev pozadí",
+	tableContextMenuTitle: "Kontextová nabídka tabulky"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/TextColor.js b/dojox/editor/plugins/nls/cs/TextColor.js
index 7cfd1e8..5a15e4e 100644
--- a/dojox/editor/plugins/nls/cs/TextColor.js
+++ b/dojox/editor/plugins/nls/cs/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Nastavit",
 	"cancelButtonText": "Storno"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/cs/latinEntities.js b/dojox/editor/plugins/nls/cs/latinEntities.js
index 962063e..e732f0e 100644
--- a/dojox/editor/plugins/nls/cs/latinEntities.js
+++ b/dojox/editor/plugins/nls/cs/latinEntities.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"obrácený vykřičník",
 	cent:"znak cent",
@@ -14,24 +13,24 @@ define(
 	yen:"znak yen\nznak yuan",
 	brvbar:"přerušená čára\npřerušená svislá čára",
 	sect:"znak paragraf",
-	uml:"vodorovná dvojtečka\npřehláska",
+	uml:"dvě tečky nad\npřehláska",
 	copy:"znak copyright",
 	ordf:"indikátor ženského rodu",
 	laquo:"dvojitá levá šipka",
 	not:"znak negace",
 	shy:"spojovník\nrozdělovník",
 	reg:"znak registrováno\nznak registrovaná ochranná známka",
-	macr:"nadtržítko",
+	macr:"macron\nmezerový macron\npomlčka nad\npruh nahoře APL",
 	deg:"znak stupeň",
 	plusmn:"znak plus-minus\nznak plus nebo minus",
-	sup2:"2, horní index\ndruhá mocnina\nplošná míra",
-	sup3:"3, horní index\ntřetí mocnina\nkrychlová míra",
+	sup2:"dvojka jako horní index\nčíslice dvě jako horní index\nčtvereční",
+	sup3:"trojka jako horní index\nčíslice tři jako horní index\nkrychlový",
 	acute:"čárka nahoře",
 	micro:"znak mikro",
 	para:"znak konec odstavce",
-	middot:"tečka uprostřed",
-	cedil:"cedilla\nspodní háček",
-	sup1:"1, horní index",
+	middot:"tečka uprostřed\ngeorgiánská čárka\nřecká tečka uprostřed",
+	cedil:"cedilla\nocásek vlevo",
+	sup1:"jednička jako horní index\nčíslice jedna jako horní index",
 	ordm:"indikátor mužského rodu",
 	raquo:"dvojitá pravá šipka",
 	frac14:"jednoduchý zlomek jedna čtvrtina\nzlomek jedna čtvrtina",
@@ -102,7 +101,6 @@ define(
 	yacute:"malé písmeno y s čárkou",
 	thorn:"malé písmeno thorn",
 	yuml:"malé písmeno y s přehláskou",
-
 // Greek Characters and Symbols
 	fnof:"malé písmeno f se zahnutým háčkem\nfunkce\nflorin",
 	Alpha:"velké řecké písmeno alfa",
@@ -159,11 +157,11 @@ define(
 	piv:"řecký symbol pí",
 	bull:"odrážka\nmalý černý kroužek",
 	hellip:"vodorovná výpustka\ntři tečky",
-	prime:"čárka nahoře\nminuty\nstopy",
-	Prime:"dvojitá čárka nahoře\nsekundy\npalce",
-	oline:"nadtržítko\npruh",
+	prime:"horní čárka\nminuty\nstopy",
+	Prime:"dvojitá horní čárka\nsekundy\npalce",
+	oline:"čára nahoře\nmezerová čára nahoře",
 	frasl:"lomítko u zlomků",
-	weierp:"stylizované velké písmeno P\npotenční množina\nWeierstrassovo písmeno p",
+	weierp:"velké psací písmeno P\npotenční množina\nWeierstrassovo p",
 	image:"velké písmeno I, švabach\nimaginární část",
 	real:"velké písmeno R, švabach\nsymbol reálné části",
 	trade:"znak ochranná známka",
@@ -183,24 +181,24 @@ define(
 	part:"parciální diferenciál",
 	exist:"existuje",
 	empty:"prázdná množina\nnulová množina\nprůměr",
-	nabla:"nabla\nzpětná diference",
+	nabla:"nabla\nzpětný rozdíl",
 	isin:"prvek množiny",
 	notin:"není prvkem množiny",
 	ni:"obsahuje jako člena",
-	prod:"n-ární součin\nznak součin",
+	prod:"n-ární součin\nznak součinu",
 	sum:"n-ární součet",
 	minus:"znak minus",
 	lowast:"operátor hvězdička",
-	radic:"druhá odmocnina",
+	radic:"druhá odmocnina\nznak kořene",
 	prop:"úměrné",
 	infin:"nekonečno",
 	ang:"úhel",
-	and:"logický operátor a\nklín s hrotem nahoru",
-	or:"logický operátor nebo\nklín s hrotem dolů",
-	cap:"průnik\noblouk vypouklý nahoru",
-	cup:"sjednocení\noblouk vypouklý dolů","int":"integrál",
+	and:"logické a\nklín",
+	or:"logické nebo\nvé",
+	cap:"průnik\nuzávěr",
+	cup:"sjednocení\nnádoba","int":"integrál",
 	there4:"a proto",
-	sim:"operátor tilda\nzměna podle\npodobné",
+	sim:"operátor vlnovka\nliší se\npodobné",
 	cong:"přibližně rovno",
 	asymp:"téměř rovno\nasymptotické k",
 	ne:"není rovno",
@@ -212,13 +210,13 @@ define(
 	nsub:"není podmnožinou",
 	sube:"podmnožina nebo shodné s",
 	supe:"nadmnožina nebo shodné s",
-	oplus:"znak plus v kroužku\npřímý součet",
-	otimes:"znak násobení v kroužku\nvektorový součin",
-	perp:"kolmice\nortogonální k\nkolmé na",
+	oplus:"plus v kroužku\npřímý součet",
+	otimes:"krát v kroužku\nvektorový součin",
+	perp:"směr nahoru\nv pravém úhlu k\nkolmé",
 	sdot:"operátor tečka",
-	lceil:"levá horní celá část",
+	lceil:"levá horní mez",
 	rceil:"pravá horní celá část",
-	lfloor:"levá dolní celá část",
+	lfloor:"levá dolní mez",
 	rfloor:"pravá dolní celá část",
 	lang:"levá lomená závorka",
 	rang:"pravá lomená závorka",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"pravá šipka",
 	euro:"znak euro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/AutoSave.js b/dojox/editor/plugins/nls/da/AutoSave.js
index f4eaf08..0ec8fec 100644
--- a/dojox/editor/plugins/nls/da/AutoSave.js
+++ b/dojox/editor/plugins/nls/da/AutoSave.js
@@ -1,18 +1,15 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Gem",
 	"saveSettingLabelOn": "Angiv interval for automatisk lagring...",
 	"saveSettingLabelOff": "Deaktivér automatisk lagring",
-	"saveSettingdialogTitle": "Gem automatisk",
+	"saveSettingdialogTitle": "Automatisk lagring",
 	"saveSettingdialogDescription": "Angiv interval for automatisk lagring",
 	"saveSettingdialogParamName": "Interval for automatisk lagring",
-	"saveSettingdialogParamLabel": "min.",
+	"saveSettingdialogParamLabel": "min",
 	"saveSettingdialogButtonOk": "Angiv interval",
 	"saveSettingdialogButtonCancel": "Annullér",
-	"saveMessageSuccess": "Gemt i ${0}",
-	"saveMessageFail": "Ikke gemt i ${0}"
+	"saveMessageSuccess": "Gemt ${0}",
+	"saveMessageFail": "Ikke gemt ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/Blockquote.js b/dojox/editor/plugins/nls/da/Blockquote.js
index c49cea9..ad21a28 100644
--- a/dojox/editor/plugins/nls/da/Blockquote.js
+++ b/dojox/editor/plugins/nls/da/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
-	"blockquote": "Citat"
+	"blockquote": "Blokanførselstegn"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/Breadcrumb.js b/dojox/editor/plugins/nls/da/Breadcrumb.js
index 385943f..f69e32d 100644
--- a/dojox/editor/plugins/nls/da/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/da/Breadcrumb.js
@@ -1,7 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"nodeActions": "${nodeName} - handlinger",
+	"nodeActions": "Handlinger for ${nodeName}",
 	"selectContents": "Vælg indhold",
 	"selectElement": "Vælg element",
 	"deleteElement": "Slet element",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Flyt markør til start",
 	"moveEnd": "Flyt markør til slut"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/CollapsibleToolbar.js b/dojox/editor/plugins/nls/da/CollapsibleToolbar.js
index c066bad..48efdbb 100644
--- a/dojox/editor/plugins/nls/da/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/da/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Skjul editorværktøjslinje",
 	"expand": "Udvid editorværktøjslinje"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/FindReplace.js b/dojox/editor/plugins/nls/da/FindReplace.js
index 93d833d..cc167f7 100644
--- a/dojox/editor/plugins/nls/da/FindReplace.js
+++ b/dojox/editor/plugins/nls/da/FindReplace.js
@@ -1,26 +1,23 @@
 define(
-//begin v1.x content
 ({
-	"findLabel": "Søg efter:",
-	"findTooltip": "Indtast tekst, der skal søges efter",
+	"findLabel": "Søg:",
+	"findTooltip": "Indtast tekst, du vil søge efter",
 	"replaceLabel": "Erstat med:",
-	"replaceTooltip": "Indtast tekst, der skal erstattes med",
+	"replaceTooltip": "Indtast tekst, du vil erstatte med",
 	"findReplace": "Søg og erstat",
-	"matchCase": "Store/små bogstaver",
-	"matchCaseTooltip": "Store/små bogstaver",
-	"backwards": "Tilbage",
-	"backwardsTooltip": "Søg baglæns efter tekst",
+	"matchCase": "Forskel på store og små bogstaver",
+	"matchCaseTooltip": "Forskel på store og små bogstaver",
+	"backwards": "Baglæns",
+	"backwardsTooltip": "Søg baglæns i teksten",
 	"replaceAllButton": "Erstat alle",
-	"replaceAllButtonTooltip": "Erstat alle forekomster i teksten",
+	"replaceAllButtonTooltip": "Erstat i hele teksten",
 	"findButton": "Søg",
 	"findButtonTooltip": "Find teksten",
 	"replaceButton": "Erstat",
 	"replaceButtonTooltip": "Erstat teksten",
-	"replaceDialogText": "Erstattet ${0} forekomster.",
+	"replaceDialogText": "${0} forekomster erstattet.",
 	"eofDialogText": "Sidste forekomst ${0}",
 	"eofDialogTextFind": "fundet",
 	"eofDialogTextReplace": "erstattet"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/InsertAnchor.js b/dojox/editor/plugins/nls/da/InsertAnchor.js
index a8fdeae..6dfc079 100644
--- a/dojox/editor/plugins/nls/da/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/da/InsertAnchor.js
@@ -1,13 +1,10 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Indsæt anker",
-	title: "Ankeregenskaber",
+	title: "Egenskaber for anker",
 	anchor: "Navn:",
 	text: "Beskrivelse:",
 	set: "Definér",
 	cancel: "Annullér"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/InsertEntity.js b/dojox/editor/plugins/nls/da/InsertEntity.js
index 07be1cd..09e141a 100644
--- a/dojox/editor/plugins/nls/da/InsertEntity.js
+++ b/dojox/editor/plugins/nls/da/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Indsæt symbol"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/LocalImage.js b/dojox/editor/plugins/nls/da/LocalImage.js
index 50a5933..83d6400 100644
--- a/dojox/editor/plugins/nls/da/LocalImage.js
+++ b/dojox/editor/plugins/nls/da/LocalImage.js
@@ -1,15 +1,12 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Indsæt billede",
 	url: "Billede",
 	browse: "Gennemse...",
 	text: "Beskrivelse",
 	set: "Indsæt",
-	invalidMessage: "Ugyldig billedfiltype",
+	invalidMessage: "Ugyldig type af billedfil",
 	prePopuTextUrl: "Angiv en billed-URL",
 	prePopuTextBrowse: " eller søg efter en lokal fil."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/PageBreak.js b/dojox/editor/plugins/nls/da/PageBreak.js
index a4dd6e6..dafab0d 100644
--- a/dojox/editor/plugins/nls/da/PageBreak.js
+++ b/dojox/editor/plugins/nls/da/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Sideskift"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/PasteFromWord.js b/dojox/editor/plugins/nls/da/PasteFromWord.js
index 8859661..e8b5230 100644
--- a/dojox/editor/plugins/nls/da/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/da/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"pasteFromWord": "Sæt ind fra Word",
-	"paste": "Sæt ind",
-	"cancel": "Annullér",
-	"instructions": "Indsæt indholdet fra Word i tekstfeltet nedenfor. Klik på knappen Sæt ind, når du er tilfreds med indholdet. Klik på knappen Annullér for at annullere indsættelse af tekst."
+	"pasteFromWord": "Indsæt fra Word",
+	"instructions": "Indsæt indholdet fra Word i tekstfeltet nedenfor. Klik på knappen Indsæt, når du er tilfreds med indholdet. Tryk på knappen Annullér for at fortryde indsættelsen."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/Preview.js b/dojox/editor/plugins/nls/da/Preview.js
index 45e3968..ec82680 100644
--- a/dojox/editor/plugins/nls/da/Preview.js
+++ b/dojox/editor/plugins/nls/da/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Eksempel"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/Save.js b/dojox/editor/plugins/nls/da/Save.js
index 802b706..204c496 100644
--- a/dojox/editor/plugins/nls/da/Save.js
+++ b/dojox/editor/plugins/nls/da/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Gem"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/ShowBlockNodes.js b/dojox/editor/plugins/nls/da/ShowBlockNodes.js
index 34da4af..092083e 100644
--- a/dojox/editor/plugins/nls/da/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/da/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Vis HTML-blokelementer"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/Smiley.js b/dojox/editor/plugins/nls/da/Smiley.js
index 4ad8191..1f8a4b9 100644
--- a/dojox/editor/plugins/nls/da/Smiley.js
+++ b/dojox/editor/plugins/nls/da/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Indsæt humørikon",
 	emoticonSmile: "smil",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "græder",
 	emoticonHappy: "glad"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/SpellCheck.js b/dojox/editor/plugins/nls/da/SpellCheck.js
index 4c0f4f9..0912d2f 100644
--- a/dojox/editor/plugins/nls/da/SpellCheck.js
+++ b/dojox/editor/plugins/nls/da/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Bundtvis stavekontrol",
 	unfound: "Ikke fundet",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Spring alle disse over",
 	iMsg: "Ingen forslag til stavning"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/TableDialog.js b/dojox/editor/plugins/nls/da/TableDialog.js
index 65c699c..dafe96d 100644
--- a/dojox/editor/plugins/nls/da/TableDialog.js
+++ b/dojox/editor/plugins/nls/da/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Indsæt tabel",
 	modifyTableTitle: "Revidér tabel",
@@ -11,8 +10,8 @@ define(
 	tableWidth: "Tabelbredde:",
 	backgroundColor: "Baggrundsfarve:",
 	borderColor: "Kantfarve:",
-	borderThickness: "Kanttykkelse",
-	percent: "procent",
+	borderThickness: "Kanttykkelse:",
+	percent: "percent",
 	pixels: "pixel",
 	"default": "standard",
 	left: "venstre",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Definér", // translated elsewhere?
 	buttonInsert: "Indsæt",
 	buttonCancel: "Annullér",
-
 	selectTableLabel: "Markér tabel",
 	insertTableRowBeforeLabel: "Tilføj række før",
 	insertTableRowAfterLabel: "Tilføj række efter",
 	insertTableColumnBeforeLabel: "Tilføj kolonne før",
 	insertTableColumnAfterLabel: "Tilføj kolonne efter",
 	deleteTableRowLabel: "Slet række",
-	deleteTableColumnLabel: "Slet kolonne"
+	deleteTableColumnLabel: "Slet kolonne",
+	colorTableCellTitle: "Baggrundsfarve i tabelcelle:",
+	tableContextMenuTitle: "Tabel - kontekstmenu"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/TextColor.js b/dojox/editor/plugins/nls/da/TextColor.js
index dbdfb23..18bcc7e 100644
--- a/dojox/editor/plugins/nls/da/TextColor.js
+++ b/dojox/editor/plugins/nls/da/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Definér",
 	"cancelButtonText": "Annullér"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/da/latinEntities.js b/dojox/editor/plugins/nls/da/latinEntities.js
index d512430..4fc811b 100644
--- a/dojox/editor/plugins/nls/da/latinEntities.js
+++ b/dojox/editor/plugins/nls/da/latinEntities.js
@@ -1,261 +1,257 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
-	iexcl:"inverted exclamation mark",
-	cent:"cent sign",
-	pound:"pound sign",
-	curren:"currency sign",
-	yen:"yen sign\nyuan sign",
-	brvbar:"broken bar\nbroken vertical bar",
-	sect:"section sign",
-	uml:"diaeresis\nspacing diaeresis",
-	copy:"copyright sign",
-	ordf:"feminine ordinal indicator",
-	laquo:"left-pointing double angle quotation mark\nleft pointing guillemet",
-	not:"not sign",
-	shy:"soft hyphen\ndiscretionary hyphen",
-	reg:"registered sign\nregistered trade mark sign",
-	macr:"macron\nspacing macron\noverline\nAPL overbar",
-	deg:"degree sign",
-	plusmn:"plus-minus sign\nplus-or-minus sign",
-	sup2:"superscript two\nsuperscript digit two\nsquared",
-	sup3:"superscript three\nsuperscript digit three\ncubed",
-	acute:"acute accent\nspacing acute",
-	micro:"micro sign",
-	para:"pilcrow sign\nparagraph sign",
-	middot:"middle dot\nGeorgian comma\nGreek middle dot",
-	cedil:"cedilla\nspacing cedilla",
-	sup1:"superscript one\nsuperscript digit one",
-	ordm:"masculine ordinal indicator",
-	raquo:"right-pointing double angle quotation mark\nright pointing guillemet",
-	frac14:"vulgar fraction one quarter\nfraction one quarter",
-	frac12:"vulgar fraction one half\nfraction one half",
-	frac34:"vulgar fraction three quarters\nfraction three quarters",
-	iquest:"inverted question mark\nturned question mark",
-	Agrave:"Latin capital letter A with grave\nLatin capital letter A grave",
-	Aacute:"Latin capital letter A with acute",
-	Acirc:"Latin capital letter A with circumflex",
-	Atilde:"Latin capital letter A with tilde",
-	Auml:"Latin capital letter A with diaeresis",
-	Aring:"Latin capital letter A with ring above\nLatin capital letter A ring",
-	AElig:"Latin capital letter AE\nLatin capital ligature AE",
-	Ccedil:"Latin capital letter C with cedilla",
-	Egrave:"Latin capital letter E with grave",
-	Eacute:"Latin capital letter E with acute",
-	Ecirc:"Latin capital letter E with circumflex",
-	Euml:"Latin capital letter E with diaeresis",
-	Igrave:"Latin capital letter I with grave",
-	Iacute:"Latin capital letter I with acute",
-	Icirc:"Latin capital letter I with circumflex",
-	Iuml:"Latin capital letter I with diaeresis",
-	ETH:"Latin capital letter ETH",
-	Ntilde:"Latin capital letter N with tilde",
-	Ograve:"Latin capital letter O with grave",
-	Oacute:"Latin capital letter O with acute",
-	Ocirc:"Latin capital letter O with circumflex",
-	Otilde:"Latin capital letter O with tilde",
-	Ouml:"Latin capital letter O with diaeresis",
-	times:"multiplication sign",
-	Oslash:"Latin capital letter O with stroke\nLatin capital letter O slash",
-	Ugrave:"Latin capital letter U with grave",
-	Uacute:"Latin capital letter U with acute",
-	Ucirc:"Latin capital letter U with circumflex",
-	Uuml:"Latin capital letter U with diaeresis",
-	Yacute:"Latin capital letter Y with acute",
-	THORN:"Latin capital letter THORN",
-	szlig:"Latin small letter sharp s\ness-zed",
-	agrave:"Latin small letter a with grave\nLatin small letter a grave",
-	aacute:"Latin small letter a with acute",
-	acirc:"Latin small letter a with circumflex",
-	atilde:"Latin small letter a with tilde",
-	auml:"Latin small letter a with diaeresis",
-	aring:"Latin small letter a with ring above\nLatin small letter a ring",
-	aelig:"Latin small letter ae\nLatin small ligature ae",
-	ccedil:"Latin small letter c with cedilla",
-	egrave:"Latin small letter e with grave",
-	eacute:"Latin small letter e with acute",
-	ecirc:"Latin small letter e with circumflex",
-	euml:"Latin small letter e with diaeresis",
-	igrave:"Latin small letter i with grave",
-	iacute:"Latin small letter i with acute",
-	icirc:"Latin small letter i with circumflex",
-	iuml:"Latin small letter i with diaeresis",
-	eth:"Latin small letter eth",
-	ntilde:"Latin small letter n with tilde",
-	ograve:"Latin small letter o with grave",
-	oacute:"Latin small letter o with acute",
-	ocirc:"Latin small letter o with circumflex",
-	otilde:"Latin small letter o with tilde",
-	ouml:"Latin small letter o with diaeresis",
-	divide:"division sign",
-	oslash:"Latin small letter o with stroke\nLatin small letter o slash",
-	ugrave:"Latin small letter u with grave",
-	uacute:"Latin small letter u with acute",
-	ucirc:"Latin small letter u with circumflex",
-	uuml:"Latin small letter u with diaeresis",
-	yacute:"Latin small letter y with acute",
-	thorn:"Latin small letter thorn",
-	yuml:"Latin small letter y with diaeresis",
-
+	iexcl:"omvendt udråbstegn",
+	cent:"cent-tegn",
+	pound:"pund-tegn",
+	curren:"valutategn",
+	yen:"yen-tegn\nyuan-tegn",
+	brvbar:"pipe-tegn\npipe-tegn",
+	sect:"afsnitstegn",
+	uml:"Trema\nafstandstrema",
+	copy:"copyright-tegn",
+	ordf:"ordinalindikator for femininum",
+	laquo:"dobbelt vinkelanførselstegn pegende mod venstre\nvenstre fransk anførselstegn",
+	not:"ikke-tegn",
+	shy:"blød bindestreg\ndiskret bindestreg",
+	reg:"registreret-tegn\ntegn for registreret varemærke",
+	macr:"makron\nafstandsmakron\nstreg over\nAPL-overstreg",
+	deg:"gradtegn",
+	plusmn:"plus-minus-tegn\nplus-eller-minus-tegn",
+	sup2:"hævet total\ntallet to hævet\nkvadrat",
+	sup3:"hævet tretal\ntallet tre hævet\nkubik",
+	acute:"accent aigu\nafstands-aigu",
+	micro:"mikro-tegn",
+	para:"afsnitstegn\nafsnitstegn",
+	middot:"mellemprik\ngeorgisk komma\ngræsk mellemprik",
+	cedil:"cedille\nafstands-cedille",
+	sup1:"hævet ettal\ntallet et hævet",
+	ordm:"ordinalindikator for maskulinum",
+	raquo:"dobbelt vinkelanførselstegn pegende mod højre\nhøjre fransk anførselstegn",
+	frac14:"forskudt brøk en kvart\nbrøk en kvart",
+	frac12:"forskudt brøk en halv\nbrøk en halv",
+	frac34:"forskudt brøk en tre kvart\nbrøk tre kvart",
+	iquest:"omvendt spørgsmålstegn\ndrejet spørgsmålstegn",
+	Agrave:"stort latinsk A med accent grave\nstort latinsk A med accent grave",
+	Aacute:"stort latinsk A med accent aigu",
+	Acirc:"stort latinsk A med cirkumfleks",
+	Atilde:"stort latinsk A med tilde",
+	Auml:"stort latinsk A med trema",
+	Aring:"stort latinsk A med bolle over\nstort latinsk A med bolle",
+	AElig:"stort latinsk AE\nstort latinsk AE",
+	Ccedil:"stort latinsk C med cedille",
+	Egrave:"stort latinsk E med accent grave",
+	Eacute:"stort latinsk E med accent aigu",
+	Ecirc:"stort latinsk E med cirkumfleks",
+	Euml:"stort latinsk E med trema",
+	Igrave:"stort latinsk I med accent grave",
+	Iacute:"stort latinsk I med accent aigu",
+	Icirc:"stort latinsk I med cirkumfleks",
+	Iuml:"stort latinsk I med trema",
+	ETH:"stort latinsk ETH",
+	Ntilde:"stort latinsk N med tilde",
+	Ograve:"stort latinsk O med accent grave",
+	Oacute:"stort latinsk O med accent aigu",
+	Ocirc:"stort latinsk O med cirkumfleks",
+	Otilde:"stort latinsk O med tilde",
+	Ouml:"stort latinsk O med trema",
+	times:"multiplikationstegn",
+	Oslash:"stort latinsk O med streg\nstort latinsk O med skråstreg",
+	Ugrave:"stort latinsk U med accent grave",
+	Uacute:"stort latinsk U med accent aigu",
+	Ucirc:"stort latinsk U med cirkumfleks",
+	Uuml:"stort latinsk U med trema",
+	Yacute:"stort latinsk Y med accent aigu",
+	THORN:"stort latinsk THORN",
+	szlig:"lille latinsk skarpt s\ndobbelt-S",
+	agrave:"lille latinsk a med accent grave\nlille latinsk a med accent grave",
+	aacute:"lille latinsk a med accent aigu",
+	acirc:"lille latinsk a med cirkumfleks",
+	atilde:"lille latinsk a med tilde",
+	auml:"lille latinsk a med trema",
+	aring:"lille latinsk a med bolle over\nlille latinsk a med bolle",
+	aelig:"lille latinsk ae\nlille latinsk ae",
+	ccedil:"lille latinsk c med cedille",
+	egrave:"lille latinsk e med accent grave",
+	eacute:"lille latinsk e med accent aigu",
+	ecirc:"lille latinsk e med cirkumfleks",
+	euml:"lille latinsk e med trema",
+	igrave:"lille latinsk i med accent grave",
+	iacute:"lille latinsk i med accent aigu",
+	icirc:"lille latinsk i med cirkumfleks",
+	iuml:"lille latinsk i med trema",
+	eth:"lille latinsk eth",
+	ntilde:"lille latinsk n med tilde",
+	ograve:"lille latinsk o med accent grave",
+	oacute:"lille latinsk o med accent aigu",
+	ocirc:"lille latinsk o med cirkumfleks",
+	otilde:"lille latinsk o med tilde",
+	ouml:"lille latinsk o med trema",
+	divide:"divisionstegn",
+	oslash:"lille latinsk o med streg\nlille latinsk o med skråstreg",
+	ugrave:"lille latinsk u med accent grave",
+	uacute:"lille latinsk u med accent aigu",
+	ucirc:"lille latinsk u med cirkumfleks",
+	uuml:"lille latinsk u med trema",
+	yacute:"lille latinsk y med accent aigu",
+	thorn:"lille latinsk thorn",
+	yuml:"lille latinsk y med trema",
 // Greek Characters and Symbols
-	fnof:"Latin small f with hook\nfunction\nflorin",
-	Alpha:"Greek capital letter alpha",
-	Beta:"Greek capital letter beta",
-	Gamma:"Greek capital letter gamma",
-	Delta:"Greek capital letter delta",
-	Epsilon:"Greek capital letter epsilon",
-	Zeta:"Greek capital letter zeta",
-	Eta:"Greek capital letter eta",
-	Theta:"Greek capital letter theta",
-	Iota:"Greek capital letter iota",
-	Kappa:"Greek capital letter kappa",
-	Lambda:"Greek capital letter lambda",
-	Mu:"Greek capital letter mu",
-	Nu:"Greek capital letter nu",
-	Xi:"Greek capital letter xi",
-	Omicron:"Greek capital letter omicron",
-	Pi:"Greek capital letter pi",
-	Rho:"Greek capital letter rho",
-	Sigma:"Greek capital letter sigma",
-	Tau:"Greek capital letter tau",
-	Upsilon:"Greek capital letter upsilon",
-	Phi:"Greek capital letter phi",
-	Chi:"Greek capital letter chi",
-	Psi:"Greek capital letter psi",
-	Omega:"Greek capital letter omega",
-	alpha:"Greek small letter alpha",
-	beta:"Greek small letter beta",
-	gamma:"Greek small letter gamma",
-	delta:"Greek small letter delta",
-	epsilon:"Greek small letter epsilon",
-	zeta:"Greek small letter zeta",
-	eta:"Greek small letter eta",
-	theta:"Greek small letter theta",
-	iota:"Greek small letter iota",
-	kappa:"Greek small letter kappa",
-	lambda:"Greek small letter lambda",
-	mu:"Greek small letter mu",
-	nu:"Greek small letter nu",
-	xi:"Greek small letter xi",
-	omicron:"Greek small letter omicron",
-	pi:"Greek small letter pi",
-	rho:"Greek small letter rho",
-	sigmaf:"Greek small letter final sigma",
-	sigma:"Greek small letter sigma",
-	tau:"Greek small letter tau",
-	upsilon:"Greek small letter upsilon",
-	phi:"Greek small letter phi",
-	chi:"Greek small letter chi",
-	psi:"Greek small letter psi",
-	omega:"Greek small letter omega",
-	thetasym:"Greek small letter theta symbol",
-	upsih:"Greek upsilon with hook symbol",
-	piv:"Greek pi symbol",
-	bull:"bullet\nblack small circle",
-	hellip:"horizontal ellipsis\nthree dot leader",
-	prime:"prime\nminutes\nfeet",
-	Prime:"double prime\nseconds\ninches",
-	oline:"overline\nspacing overscore",
-	frasl:"fraction slash",
-	weierp:"script capital P\npower set\nWeierstrass p",
-	image:"blackletter capital I\nimaginary part",
-	real:"blackletter capital R\nreal part symbol",
-	trade:"trade mark sign",
-	alefsym:"alef symbol\nfirst transfinite cardinal",
-	larr:"leftwards arrow",
-	uarr:"upwards arrow",
-	rarr:"rightwards arrow",
-	darr:"downwards arrow",
-	harr:"left right arrow",
-	crarr:"downwards arrow with corner leftwards\ncarriage return",
-	lArr:"leftwards double arrow",
-	uArr:"upwards double arrow",
-	rArr:"rightwards double arrow",
-	dArr:"downwards double arrow",
-	hArr:"left right double arrow",
-	forall:"for all",
-	part:"partial differential",
-	exist:"there exists",
-	empty:"empty set\nnull set\ndiameter",
-	nabla:"nabla\nbackward difference",
-	isin:"element of",
-	notin:"not an element of",
-	ni:"contains as member",
-	prod:"n-ary product\nproduct sign",
-	sum:"n-ary sumation",
-	minus:"minus sign",
-	lowast:"asterisk operator",
-	radic:"square root\nradical sign",
-	prop:"proportional to",
-	infin:"infinity",
-	ang:"angle",
-	and:"logical and\nwedge",
-	or:"logical or\nvee",
-	cap:"intersection\ncap",
-	cup:"union\ncup","int":"integral",
-	there4:"therefore",
-	sim:"tilde operator\nvaries with\nsimilar to",
-	cong:"approximately equal to",
-	asymp:"almost equal to\nasymptotic to",
-	ne:"not equal to",
-	equiv:"identical to",
-	le:"less-than or equal to",
-	ge:"greater-than or equal to",
-	sub:"subset of",
-	sup:"superset of",
-	nsub:"not a subset of",
-	sube:"subset of or equal to",
-	supe:"superset of or equal to",
-	oplus:"circled plus\ndirect sum",
-	otimes:"circled times\nvector product",
-	perp:"up tack\northogonal to\nperpendicular",
-	sdot:"dot operator",
-	lceil:"left ceiling\nAPL upstile",
-	rceil:"right ceiling",
-	lfloor:"left floor\nAPL downstile",
-	rfloor:"right floor",
-	lang:"left-pointing angle bracket",
-	rang:"right-pointing angle bracket",
-	loz:"lozenge",
-	spades:"black spade suit",
-	clubs:"black club suit\nshamrock",
-	hearts:"black heart suit\nvalentine",
-	diams:"black diamond suit",
-	OElig:"Latin capital ligature OE",
-	oelig:"Latin small ligature oe",
-	Scaron:"Latin capital letter S with caron",
-	scaron:"Latin small letter s with caron",
-	Yuml:"Latin capital letter Y with diaeresis",
-	circ:"modifier letter circumflex accent",
-	tilde:"small tilde",
-	ensp:"en space",
-	emsp:"em space",
-	thinsp:"thin space",
-	zwnj:"zero width non-joiner",
-	zwj:"zero width joiner",
-	lrm:"left-to-right mark",
-	rlm:"right-to-left mark",
-	ndash:"en dash",
-	mdash:"em dash",
-	lsquo:"left single quotation mark",
-	rsquo:"right single quotation mark",
-	sbquo:"single low-9 quotation mark",
-	ldquo:"left double quotation mark",
-	rdquo:"right double quotation mark",
-	bdquo:"double low-9 quotation mark",
-	dagger:"dagger",
-	Dagger:"double dagger",
-	permil:"per mille sign",
-	lsaquo:"single left-pointing angle quotation mark",
-	rsaquo:"single right-pointing angle quotation mark",
-	euro:"euro sign"
+	fnof:"lille latinsk f med krumning\nfunktion\nflorin",
+	Alpha:"stort græsk alfa",
+	Beta:"stort græsk beta",
+	Gamma:"stort græsk gamma",
+	Delta:"stort græsk delta",
+	Epsilon:"stort græsk epsilon",
+	Zeta:"stort græsk zeta",
+	Eta:"stort græsk eta",
+	Theta:"stort græsk theta",
+	Iota:"stort græsk iota",
+	Kappa:"stort græsk kappa",
+	Lambda:"stort græsk lambda",
+	Mu:"stort græsk my",
+	Nu:"stort græsk ny",
+	Xi:"stort græsk ksi",
+	Omicron:"stort græsk omikron",
+	Pi:"stort græsk pi",
+	Rho:"stort græsk rho",
+	Sigma:"stort græsk sigma",
+	Tau:"stort græsk tau",
+	Upsilon:"stort græsk ypsilon",
+	Phi:"stort græsk phi",
+	Chi:"stort græsk chi",
+	Psi:"stort græsk psi",
+	Omega:"stort græsk omega",
+	alpha:"lille græsk alfa",
+	beta:"lille græsk beta",
+	gamma:"lille græsk gamma",
+	delta:"lille græsk delta",
+	epsilon:"lille græsk epsilon",
+	zeta:"lille græsk zeta",
+	eta:"lille græsk eta",
+	theta:"lille græsk theta",
+	iota:"lille græsk iota",
+	kappa:"lille græsk kappa",
+	lambda:"lille græsk lambda",
+	mu:"lille græsk my",
+	nu:"lille græsk ny",
+	xi:"lille græsk ksi",
+	omicron:"lille græsk omikron",
+	pi:"lille græsk pi",
+	rho:"lille græsk rho",
+	sigmaf:"lille græsk sigma (slut)",
+	sigma:"lille græsk sigma",
+	tau:"lille græsk tau",
+	upsilon:"lille græsk ypsilon",
+	phi:"lille græsk phi",
+	chi:"lille græsk chi",
+	psi:"lille græsk psi",
+	omega:"lille græsk omega",
+	thetasym:"lille græsk theta-symbol",
+	upsih:"græsk ypsilon med krumning",
+	piv:"græsk pi-symbol",
+	bull:"punkt\nsort lille cirkel",
+	hellip:"vandret ellipse\ntre prikker",
+	prime:"citationstegn\nminutter\nfod",
+	Prime:"dobbelt citationstegn\nsekunder\ntommer",
+	oline:"streg over\nafstandsoverstregning",
+	frasl:"brøkskråstreg",
+	weierp:"håndskrevet stort P\npowerset\nWeierstrass-p",
+	image:"stort blackletter-I\nimaginær del",
+	real:"stort blackletter-R\nreel del-symbol",
+	trade:"varemærketegn",
+	alefsym:"alef-symbol\nførste transfinitte kardinaltal",
+	larr:"pil mod venstre",
+	uarr:"pil opad",
+	rarr:"pil mod højre",
+	darr:"pil nedad",
+	harr:"pil højre-venstre",
+	crarr:"pil nedad med hjørne venstre\nlinjeskift",
+	lArr:"dobbeltpil mod venstre",
+	uArr:"dobbeltpil opad",
+	rArr:"dobbeltpil mod højre",
+	dArr:"dobbeltpil nedad",
+	hArr:"dobbeltpil højre-venstre",
+	forall:"for alle",
+	part:"partielt afledet",
+	exist:"findes",
+	empty:"tomt sæt\nNULL-sæt\ndiameter",
+	nabla:"nabla\nbaglæns difference",
+	isin:"element af",
+	notin:"ikke et element af",
+	ni:"indeholder som medlem",
+	prod:"n-ær-produkt\nprodukttegn",
+	sum:"n-ær-summering",
+	minus:"minustegn",
+	lowast:"stjerneoperator",
+	radic:"kvadratrod\nrodtegn",
+	prop:"proportional med",
+	infin:"uendelig",
+	ang:"vinkel",
+	and:"logisk og\nkile",
+	or:"logisk eller\nvee",
+	cap:"fællesmængde\nhat",
+	cup:"foreningsmængde\nkop","int":"integral",
+	there4:"derfor",
+	sim:"tilde-operator\nvarierer med\nligner",
+	cong:"tilnærmet lig med",
+	asymp:"næsten lig med\nasymptotisk med",
+	ne:"ikke lig med",
+	equiv:"identisk med",
+	le:"mindre end eller lig med",
+	ge:"større end eller lig med",
+	sub:"delmængde af",
+	sup:"supersæt af",
+	nsub:"ikke en delmængde af",
+	sube:"delmængde af eller lig med",
+	supe:"supersæt af eller lig med",
+	oplus:"cirkel med plus\ndirekte sum",
+	otimes:"cirkel med gangetegn\nvektorprodukt",
+	perp:"vinkelret op\nortogonal på\nretvinklet",
+	sdot:"prik-operator",
+	lceil:"venstre loft\nAPL upstile",
+	rceil:"højre loft",
+	lfloor:"venstre gulv\nAPL downstile",
+	rfloor:"højre gulv",
+	lang:"venstre vinkelparentes",
+	rang:"højre vinkelparentes",
+	loz:"rombe",
+	spades:"sort spar",
+	clubs:"sort klør\ntrekløver",
+	hearts:"sort hjerter\nvalentin",
+	diams:"sort ruder",
+	OElig:"stort latinsk OE",
+	oelig:"lille latinsk oe",
+	Scaron:"stort latinsk S med hacek",
+	scaron:"lille latinsk s med hacek",
+	Yuml:"stort latinsk Y med trema",
+	circ:"accent cirkumfleks",
+	tilde:"lille tilde",
+	ensp:"kort mellemrum",
+	emsp:"langt mellemrum",
+	thinsp:"lille mellemrum",
+	zwnj:"valgfrit mellemrum uden bredde",
+	zwj:"hårdt mellemrum uden bredde",
+	lrm:"venstre mod højre-mærke",
+	rlm:"højre mod venstre-mærke",
+	ndash:"kort tankestreg",
+	mdash:"lang tankestreg",
+	lsquo:"venstre enkelt anførselstegn",
+	rsquo:"højre enkelt anførselstegn",
+	sbquo:"enkelt nedre anførselstegn",
+	ldquo:"venstre dobbelt anførselstegn",
+	rdquo:"højre dobbelt anførselstegn",
+	bdquo:"dobbelt nedre anførselstegn",
+	dagger:"kors",
+	Dagger:"dobbelt kors",
+	permil:"promilletegn",
+	lsaquo:"enkelt venstre vinkelanførselstegn",
+	rsaquo:"enkelt højre vinkelanførselstegn",
+	euro:"eurotegn"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/AutoSave.js b/dojox/editor/plugins/nls/de/AutoSave.js
index c1f0946..4198fc5 100644
--- a/dojox/editor/plugins/nls/de/AutoSave.js
+++ b/dojox/editor/plugins/nls/de/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Speichern",
 	"saveSettingLabelOn": "Intervall für automatisches Speichern festlegen",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Gespeichert um ${0}",
 	"saveMessageFail": "Konnte nicht um ${0} gespeichert werden"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/Blockquote.js b/dojox/editor/plugins/nls/de/Blockquote.js
index 7b05205..75174f9 100644
--- a/dojox/editor/plugins/nls/de/Blockquote.js
+++ b/dojox/editor/plugins/nls/de/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Blockzitat"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/Breadcrumb.js b/dojox/editor/plugins/nls/de/Breadcrumb.js
index 872947a..5634c54 100644
--- a/dojox/editor/plugins/nls/de/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/de/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "Aktionen für ${nodeName}",
 	"selectContents": "Inhalt auswählen",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Cursor an Anfang verschieben",
 	"moveEnd": "Cursor an Ende verschieben"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/CollapsibleToolbar.js b/dojox/editor/plugins/nls/de/CollapsibleToolbar.js
index 1b29f90..da7b79c 100644
--- a/dojox/editor/plugins/nls/de/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/de/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Editor-Symbolleiste ausblenden",
 	"expand": "Editor-Symbolleiste einblenden"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/FindReplace.js b/dojox/editor/plugins/nls/de/FindReplace.js
index cf8cf8e..0780a67 100644
--- a/dojox/editor/plugins/nls/de/FindReplace.js
+++ b/dojox/editor/plugins/nls/de/FindReplace.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
-	"findLabel": "Suchbegriff:",
+	"findLabel": "Suchen:",
 	"findTooltip": "Text zum Suchen eingeben",
 	"replaceLabel": "Ersetzen durch:",
 	"replaceTooltip": "Text zum Ersetzen eingeben",
-	"findReplace": "Suchen/Ersetzen",
+	"findReplace": "Suchen und ersetzen",
 	"matchCase": "Groß- und Kleinschreibung abgleichen",
 	"matchCaseTooltip": "Groß- und Kleinschreibung abgleichen",
 	"backwards": "Zurück",
@@ -16,11 +15,9 @@ define(
 	"findButtonTooltip": "Text suchen",
 	"replaceButton": "Ersetzen",
 	"replaceButtonTooltip": "Text ersetzen",
-	"replaceDialogText": "Es wurden ${0} Vorkommen ersetzt.",
+	"replaceDialogText": "${0} Vorkommen ersetzt.",
 	"eofDialogText": "Letztes Vorkommen ${0}",
 	"eofDialogTextFind": "gefunden",
 	"eofDialogTextReplace": "ersetzt"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/InsertAnchor.js b/dojox/editor/plugins/nls/de/InsertAnchor.js
index 72c1a42..915f08f 100644
--- a/dojox/editor/plugins/nls/de/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/de/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Anker einfügen",
 	title: "Eigenschaften des Ankers",
@@ -8,6 +7,4 @@ define(
 	set: "Festlegen",
 	cancel: "Abbrechen"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/InsertEntity.js b/dojox/editor/plugins/nls/de/InsertEntity.js
index b50e564..b4b4191 100644
--- a/dojox/editor/plugins/nls/de/InsertEntity.js
+++ b/dojox/editor/plugins/nls/de/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Symbol einfügen"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/LocalImage.js b/dojox/editor/plugins/nls/de/LocalImage.js
index 0c6a60c..3844def 100644
--- a/dojox/editor/plugins/nls/de/LocalImage.js
+++ b/dojox/editor/plugins/nls/de/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Grafik einfügen",
 	url: "Grafik",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Geben Sie eine gültige Grafik-URL ein",
 	prePopuTextBrowse: "oder blättern Sie zu einer lokalen Datei."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/PageBreak.js b/dojox/editor/plugins/nls/de/PageBreak.js
index 26ca51d..218fc5e 100644
--- a/dojox/editor/plugins/nls/de/PageBreak.js
+++ b/dojox/editor/plugins/nls/de/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Seitenumbruch"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/PasteFromWord.js b/dojox/editor/plugins/nls/de/PasteFromWord.js
index 7578607..e506c97 100644
--- a/dojox/editor/plugins/nls/de/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/de/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Aus Word einfügen",
-	"paste": "Einfügen",
-	"cancel": "Abbrechen",
 	"instructions": "Fügt den Inhalt aus Word in das Textfeld unten ein. Wenn Sie mit dem einzufügenden Inhalt zufrieden sind, klicken Sie auf die Schaltfläche zum Einfügen. Um das Einfügen von Text abzubrechen, klicken Sie auf die Schaltfläche zum Abbrechen. "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/Preview.js b/dojox/editor/plugins/nls/de/Preview.js
index 19c89b3..14adc2d 100644
--- a/dojox/editor/plugins/nls/de/Preview.js
+++ b/dojox/editor/plugins/nls/de/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Vorschau"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/SafePaste.js b/dojox/editor/plugins/nls/de/SafePaste.js
index 17b1a74..2661765 100644
--- a/dojox/editor/plugins/nls/de/SafePaste.js
+++ b/dojox/editor/plugins/nls/de/SafePaste.js
@@ -1,5 +1,5 @@
 define(
 ({
-	"instructions": "Direktes Einfügen ist inaktiviert. Fügen Sie Inhalte in diesen Dialog mithilfe der Standardsteuerelemente ein, die im Browser über die Tastatur oder über die Menüs zum Einfügen zur Verfügung stehen. Wenn der einzufügende Inhalt korrekt ist, drücken Sie die Einfügetaste. Zum Abbrechen der Einfügeoperation drücken Sie die Abbruchtaste."
+	"instructions": "Direktes Einfügen ist inaktiviert. Fügen Sie Inhalt in diesem Dialog über Tastaturbefehle oder Menüeinträge für Einfügeoperationen Ihres Standardbrowsers ein. Wenn Sie mit dem einzufügenden Inhalt zufrieden sind, klicken Sie auf die Schaltfläche Einfügen. Wenn Sie das Einfügen des Inhalts abbrechen möchten, klicken Sie auf die Schaltfläche Abbrechen."
 })
 );
diff --git a/dojox/editor/plugins/nls/de/Save.js b/dojox/editor/plugins/nls/de/Save.js
index f635309..684e47a 100644
--- a/dojox/editor/plugins/nls/de/Save.js
+++ b/dojox/editor/plugins/nls/de/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Speichern"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/ShowBlockNodes.js b/dojox/editor/plugins/nls/de/ShowBlockNodes.js
index 1c684b8..fd525e4 100644
--- a/dojox/editor/plugins/nls/de/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/de/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "HTML-Blockelemente anzeigen"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/Smiley.js b/dojox/editor/plugins/nls/de/Smiley.js
index 226cf64..db9469b 100644
--- a/dojox/editor/plugins/nls/de/Smiley.js
+++ b/dojox/editor/plugins/nls/de/Smiley.js
@@ -1,15 +1,14 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Emoticon einfügen",
 	emoticonSmile: "Lächeln",
 	emoticonLaughing: "Lachen",
-	emoticonWink: "Augenzwinkern",
+	emoticonWink: "Zwinkern",
 	emoticonGrin: "Grinsen",
 	emoticonCool: "Cool",
-	emoticonAngry: "Zornig",
-	emoticonHalf: "Halb",
-	emoticonEyebrow: "Hochgezogene Augenbraue",
+	emoticonAngry: "Wütend",
+	emoticonHalf: "Halbes Lächeln",
+	emoticonEyebrow: "Augenbraue",
 	emoticonFrown: "Stirnrunzeln",
 	emoticonShy: "Schüchtern",
 	emoticonGoofy: "Albern",
@@ -20,8 +19,6 @@ define(
 	emoticonNo: "Nein",
 	emoticonAngel: "Engel",
 	emoticonCrying: "Weinen",
-	emoticonHappy: "Fröhlich"
+	emoticonHappy: "Glücklich"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/SpellCheck.js b/dojox/editor/plugins/nls/de/SpellCheck.js
index 5f504a5..c74fe45 100644
--- a/dojox/editor/plugins/nls/de/SpellCheck.js
+++ b/dojox/editor/plugins/nls/de/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Batchrechtschreibprüfung",
 	unfound: "Nicht gefunden",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Alle entsprechenden Funde überspringen",
 	iMsg: "Keine Rechtschreibvorschläge"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/TableDialog.js b/dojox/editor/plugins/nls/de/TableDialog.js
index a4284d0..3e94088 100644
--- a/dojox/editor/plugins/nls/de/TableDialog.js
+++ b/dojox/editor/plugins/nls/de/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Tabelle einfügen",
 	modifyTableTitle: "Tabelle ändern",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Tabellenbreite:",
 	backgroundColor: "Hintergrundfarbe:",
 	borderColor: "Randfarbe:",
-	borderThickness: "Randbreite",
+	borderThickness: "Umrandungsstärke:",
 	percent: "Prozent",
 	pixels: "Pixel",
 	"default": "Standard",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Festlegen", // translated elsewhere?
 	buttonInsert: "Einfügen",
 	buttonCancel: "Abbrechen",
-
 	selectTableLabel: "Tabelle auswählen",
 	insertTableRowBeforeLabel: "Zeile oberhalb einfügen",
 	insertTableRowAfterLabel: "Zeile unterhalb einfügen",
 	insertTableColumnBeforeLabel: "Spalte oberhalb einfügen",
 	insertTableColumnAfterLabel: "Spalte unterhalb einfügen",
 	deleteTableRowLabel: "Zeile löschen",
-	deleteTableColumnLabel: "Spalte löschen"
+	deleteTableColumnLabel: "Spalte löschen",
+	colorTableCellTitle: "Hintergrundfarbe für Tabellenzelle",
+	tableContextMenuTitle: "Kontextmenü für Tabelle"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/TextColor.js b/dojox/editor/plugins/nls/de/TextColor.js
index f2c42d6..70eca9b 100644
--- a/dojox/editor/plugins/nls/de/TextColor.js
+++ b/dojox/editor/plugins/nls/de/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Festlegen",
 	"cancelButtonText": "Abbrechen"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/de/latinEntities.js b/dojox/editor/plugins/nls/de/latinEntities.js
index 8a963ae..a49ebb5 100644
--- a/dojox/editor/plugins/nls/de/latinEntities.js
+++ b/dojox/editor/plugins/nls/de/latinEntities.js
@@ -1,36 +1,35 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"Umgekehrtes Ausrufezeichen",
 	cent:"Cent-Zeichen",
 	pound:"Nummernzeichen",
 	curren:"Währungssymbol",
-	yen:"Yen-Zeichen\Nyuan-Zeichen",
+	yen:"Yen-Zeichen\nYuan-Zeichen",
 	brvbar:"Unterbrochener Balken\nUnterbrochener vertikaler Balken",
 	sect:"Abschnittszeichen",
-	uml:"Trema\nLeerzeichen mit Trema",
+	uml:"Trema\nPünktchen oben",
 	copy:"Copyrightzeichen",
 	ordf:"Weibliches Ordinalzeichen",
 	laquo:"Doppelte, winklige Anführungszeichen, die nach links weisen\linke französische Anführungszeichen",
 	not:"Nicht-Zeichen",
-	shy:"Veränderlicher Silbentrennstrich\nbedingter Trennstrich",
-	reg:"Registrierte Handelsmarke\nregistriertes Markenzeichen",
-	macr:"Makron\nLeerzeichen mit Makron\nÜberstrich\nQuerstrich über dem Buchstaben",
+	shy:"Veränderlicher Silbentrennstrich\nWeicher Bindestrich",
+	reg:"Registrierte Handelsmarke\nRegistriertes Markenzeichen",
+	macr:"Makron\nLängestrich\nÜberstrich\nKurzer Überstrich über einem Buchstaben",
 	deg:"Gradzeichen",
 	plusmn:"Plus-Minus-Zeichen\nPlus-oder-Minus-Zeichen",
-	sup2:"Hochgestellte Zwei\nHoch 2\nzum Quadrat",
+	sup2:"Hochgestellte Zwei\nHoch 2\nZum Quadrat",
 	sup3:"Hochgestellte Drei\nHoch 3\nKubik",
-	acute:"Akut\nsLeerzeichen mit Akut",
+	acute:"Akut\nAkutzeichen",
 	micro:"Micro-Zeichen",
-	para:"Pilcrow-Zeichen (engl.)\nAbsatzzeichen",
+	para:"Pilcrow-Zeichen\nAbsatzzeichen",
 	middot:"Multiplikationszeichen\nGeorgisches Komma\nGriechisches Multiplikationszeichen",
-	cedil:"Cedilla\nLeerzeichen mit Cedilla",
+	cedil:"Cedille\nC mit Häkchen",
 	sup1:"Hochgestellte Eins\nHoch 1",
 	ordm:"Männliches Ordinalzeichen",
 	raquo:"Doppelte, winklige Anführungszeichen, die nach rechts weisen\nRechtes französisches Anführungszeichen",
@@ -102,9 +101,8 @@ define(
 	yacute:"Kleinbuchstabe y mit Aktut",
 	thorn:"Kleines thorn",
 	yuml:"Kleinbuchstabe y mit Trema",
-
 // Greek Characters and Symbols
-	fnof:"Kleines mit Haken\nFunction\nFlorin",
+	fnof:"Kleines f mit Haken\nFunction\nFlorin",
 	Alpha:"Griechischer Großbuchstabe Alpha",
 	Beta:"Griechischer Großbuchstabe Beta",
 	Gamma:"Griechischer Großbuchstabe Gamma",
@@ -160,14 +158,14 @@ define(
 	bull:"Rundes Aufzählungszeichen\nSchwarzer kleiner Kreis",
 	hellip:"Auslassung\nDrei kleine Punkte",
 	prime:"Prime\nMinuten\nFuß",
-	Prime:"Doppelter Prime\nSekunden\nZoll",
-	oline:"Hochgestellter Querstrich\nLeerzeichen mit Oberstrich",
+	Prime:"Doppelstrich\nSekunden\nZoll",
+	oline:"Überstrich\nÜberstreichungszeichen",
 	frasl:"Schrägstrich für Bruch",
-	weierp:"Kleines p in Schreibschrift\nPotenz\nWeierstrass'sche Ellipsen-Funktion",
+	weierp:"Kleines p in Schreibschrift\nPotenz\nWeierstraß-p",
 	image:"Großes I in Frakturschrift\nImaginärteil",
 	real:"Großes R in Frakturschrift\nRealteilsymbol",
 	trade:"Markenzeichen",
-	alefsym:"Alef-Symbol\nerste Transfinite Kardinalzahl",
+	alefsym:"Aleph-Symbol\nErste transfinite Kardinalzahl",
 	larr:"Linkspfeil",
 	uarr:"Aufwärtspfeil",
 	rarr:"Rechtspfeil",
@@ -182,27 +180,27 @@ define(
 	forall:"Für alle",
 	part:"Partielle Differenzialgleichung",
 	exist:"Es existiert",
-	empty:"Leermenge\nNullmenge\nDurchmesser",
-	nabla:"Nabla\nAbsteigende Differenz",
+	empty:"Leere Menge\nNullmenge\nDurchmesser",
+	nabla:"Nabla\nRückwärtsdifferenz",
 	isin:"Element von",
 	notin:"Kein Element von",
 	ni:"Enthält als Member",
-	prod:"unäres Produkt\nProduktzeichen",
-	sum:"unäre Summation",
+	prod:"Unäres Produkt\nProduktzeichen",
+	sum:"Unäre Summation",
 	minus:"Minuszeichen",
 	lowast:"Sternoperator",
 	radic:"Quadratwurzel\nWurzelzeichen",
 	prop:"proportional zu",
 	infin:"Unendlich",
 	ang:"Winkel",
-	and:"Logisches Und\nKeil",
-	or:"Logisches Oder\nv-förmig",
-	cap:"Schnittpunkt\nHütchen",
-	cup:"Vereinigungsmenge\nCup","int":"Integral",
+	and:"Logisches UND\nHatschek",
+	or:"Logisches ODER\nV",
+	cap:"Schnittmenge\nBogen mit Öffnung oben",
+	cup:"Vereinigungsmenge\nBogen mit Öffnung unten","int":"Integral",
 	there4:"Deshalb",
-	sim:"Tilde (Operator)\nvariiert mit\nähnlich wie",
+	sim:"Tildenoperator\nVariiert mit\nÄhnlich wie",
 	cong:"Etwa gleich mit",
-	asymp:"Ungefähr gleich mit\nasymptotisch",
+	asymp:"Ungefähr gleich mit\nAsymptotisch",
 	ne:"Nicht gleich mit",
 	equiv:"Identisch mit",
 	le:"Kleiner-gleich",
@@ -212,13 +210,13 @@ define(
 	nsub:"Kein Teil von",
 	sube:"Teilmenge oder gleich mit",
 	supe:"Obermenge oder gleich mit",
-	oplus:"Pluszeichen mit Kreis\ndirekte Summe",
-	otimes:"Multiplikationszeichen mit Kreis\nVektorprodukt",
-	perp:"Senkrecht\nSenkrecht zu\nLotrecht",
+	oplus:"In Kreis eingeschlossenes Pluszeichen\nDirekte Summe",
+	otimes:"In Kreis eingeschlossenes X\nVektorprodukt",
+	perp:"Senkrecht\nOrthogonal zu\nPerpendikulär",
 	sdot:"Punktoperator",
-	lceil:"Linke Ecke oben\nAPL upstile",
+	lceil:"Linke Ecke oben\nSenkrechter Winkel mit Ecke links oben",
 	rceil:"Rechte Ecke oben",
-	lfloor:"Linke Ecke unten\nAPL downstile",
+	lfloor:"Linke Ecke unten\nSenkrechter Winkel mit Ecke links unten",
 	rfloor:"Rechte Ecke unten",
 	lang:"Linke spitze Klammer",
 	rang:"Rechte spitze Klammer",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"Einfaches rechtes Anführungszeichen",
 	euro:"Euro-Zeichen"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/AutoSave.js b/dojox/editor/plugins/nls/el/AutoSave.js
index 855c06f..ea90403 100644
--- a/dojox/editor/plugins/nls/el/AutoSave.js
+++ b/dojox/editor/plugins/nls/el/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Αποθήκευση",
 	"saveSettingLabelOn": "Ορισμός διαστήματος αυτόματης αποθήκευσης...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Αποθηκεύτηκε στις ${0}",
 	"saveMessageFail": "Απέτυχε η αποθήκευση στις ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/Blockquote.js b/dojox/editor/plugins/nls/el/Blockquote.js
index a36e467..e63bce4 100644
--- a/dojox/editor/plugins/nls/el/Blockquote.js
+++ b/dojox/editor/plugins/nls/el/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Ενότητα παράθεσης"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/Breadcrumb.js b/dojox/editor/plugins/nls/el/Breadcrumb.js
index 754271f..4c16f15 100644
--- a/dojox/editor/plugins/nls/el/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/el/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} - Ενέργειες",
 	"selectContents": "Επιλογή περιεχομένων",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Μετακίνηση δρομέα στην αρχή",
 	"moveEnd": "Μετακίνηση δρομέα στο τέλος"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/CollapsibleToolbar.js b/dojox/editor/plugins/nls/el/CollapsibleToolbar.js
index e2dfb45..92688d6 100644
--- a/dojox/editor/plugins/nls/el/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/el/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Σύμπτυξη γραμμής εργαλείων λειτουργίας επεξεργασίας",
 	"expand": "Ανάπτυξη γραμμής εργαλείων λειτουργίας επεξεργασίας"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/FindReplace.js b/dojox/editor/plugins/nls/el/FindReplace.js
index a5fd0f7..95f6b3c 100644
--- a/dojox/editor/plugins/nls/el/FindReplace.js
+++ b/dojox/editor/plugins/nls/el/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Εύρεση:",
 	"findTooltip": "Καταχωρήστε το κείμενο που θέλετε να εντοπίσετε",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "εντοπίστηκε",
 	"eofDialogTextReplace": "αντικαταστάθηκε"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/InsertAnchor.js b/dojox/editor/plugins/nls/el/InsertAnchor.js
index f506414..36c68da 100644
--- a/dojox/editor/plugins/nls/el/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/el/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Εισαγωγή αγκίστρωσης",
 	title: "Ιδιότητες αγκίστρωσης",
@@ -8,6 +7,4 @@ define(
 	set: "Ορισμός",
 	cancel: "Ακύρωση"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/InsertEntity.js b/dojox/editor/plugins/nls/el/InsertEntity.js
index 8a130fd..ea3c065 100644
--- a/dojox/editor/plugins/nls/el/InsertEntity.js
+++ b/dojox/editor/plugins/nls/el/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Εισαγωγή συμβόλου"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/LocalImage.js b/dojox/editor/plugins/nls/el/LocalImage.js
index a0404da..2c014c8 100644
--- a/dojox/editor/plugins/nls/el/LocalImage.js
+++ b/dojox/editor/plugins/nls/el/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Εισαγωγή εικόνας",
 	url: "Εικόνα",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Καταχωρήστε τη διεύθυνση URL μιας εικόνας",
 	prePopuTextBrowse: " ή επιλέξτε ένα τοπικό αρχείο."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/PageBreak.js b/dojox/editor/plugins/nls/el/PageBreak.js
index 56e2990..b3b3249 100644
--- a/dojox/editor/plugins/nls/el/PageBreak.js
+++ b/dojox/editor/plugins/nls/el/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Αλλαγή σελίδας"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/PasteFromWord.js b/dojox/editor/plugins/nls/el/PasteFromWord.js
index f8d32be..88cd025 100644
--- a/dojox/editor/plugins/nls/el/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/el/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Επικόλληση από το Word",
-	"paste": "Επικόλληση",
-	"cancel": "Ακύρωση",
 	"instructions": "Επικολλήστε το περιεχόμενο από το Word στο παρακάτω πλαίσιο. Όταν το κείμενο για εισαγωγή είναι σωστό, πατήστε το κουμπί Επικόλληση. Για να ακυρώσετε την εισαγωγή κειμένου, πατήστε το κουμπί Ακύρωση."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/Preview.js b/dojox/editor/plugins/nls/el/Preview.js
index eb9b7b3..d030e32 100644
--- a/dojox/editor/plugins/nls/el/Preview.js
+++ b/dojox/editor/plugins/nls/el/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Προεπισκόπηση"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/Save.js b/dojox/editor/plugins/nls/el/Save.js
index 9ec635a..d85068e 100644
--- a/dojox/editor/plugins/nls/el/Save.js
+++ b/dojox/editor/plugins/nls/el/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Αποθήκευση"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/ShowBlockNodes.js b/dojox/editor/plugins/nls/el/ShowBlockNodes.js
index ca7a605..0203ab7 100644
--- a/dojox/editor/plugins/nls/el/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/el/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Εμφάνιση στοιχείων ενότητας HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/Smiley.js b/dojox/editor/plugins/nls/el/Smiley.js
index 53bd0ac..e810094 100644
--- a/dojox/editor/plugins/nls/el/Smiley.js
+++ b/dojox/editor/plugins/nls/el/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Εισαγωγή εικονιδίου συναισθήματος",
 	emoticonSmile: "Χαμόγελο",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "Κλάμα",
 	emoticonHappy: "Ευτυχία"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/SpellCheck.js b/dojox/editor/plugins/nls/el/SpellCheck.js
index 4753341..0f87c49 100644
--- a/dojox/editor/plugins/nls/el/SpellCheck.js
+++ b/dojox/editor/plugins/nls/el/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Συνολικός ορθογραφικός έλεγχος",
 	unfound: "Δεν εντοπίστηκε",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Παράλειψη όλων των όμοιων",
 	iMsg: "Δεν υπάρχουν προτάσεις ορθογραφίας"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/TableDialog.js b/dojox/editor/plugins/nls/el/TableDialog.js
index 5e95d11..89817e4 100644
--- a/dojox/editor/plugins/nls/el/TableDialog.js
+++ b/dojox/editor/plugins/nls/el/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Εισαγωγή πίνακα",
 	modifyTableTitle: "Τροποποίηση πίνακα",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Πλάτος πίνακα:",
 	backgroundColor: "Χρώμα φόντου:",
 	borderColor: "Χρώμα περιγράμματος:",
-	borderThickness: "Πάχος περιγράμματος",
+	borderThickness: "Πάχος περιγράμματος:",
 	percent: "ποσοστό",
 	pixels: "εικονοστοιχεία",
 	"default": "προεπιλογή",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Ορισμός", // translated elsewhere?
 	buttonInsert: "Εισαγωγή",
 	buttonCancel: "Ακύρωση",
-
 	selectTableLabel: "Επιλογή πίνακα",
 	insertTableRowBeforeLabel: "Προσθήκη γραμμής πριν",
 	insertTableRowAfterLabel: "Προσθήκη γραμμής μετά",
 	insertTableColumnBeforeLabel: "Προσθήκη στήλης πριν",
 	insertTableColumnAfterLabel: "Προσθήκη στήλης μετά",
 	deleteTableRowLabel: "Διαγραφή γραμμής",
-	deleteTableColumnLabel: "Διαγραφή στήλης"
+	deleteTableColumnLabel: "Διαγραφή στήλης",
+	colorTableCellTitle: "Χρώμα φόντου",
+	tableContextMenuTitle: "Μενού περιβάλλοντος πίνακα"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/TextColor.js b/dojox/editor/plugins/nls/el/TextColor.js
index db99be9..cdaacb9 100644
--- a/dojox/editor/plugins/nls/el/TextColor.js
+++ b/dojox/editor/plugins/nls/el/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Ορισμός",
 	"cancelButtonText": "Ακύρωση"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/el/latinEntities.js b/dojox/editor/plugins/nls/el/latinEntities.js
index 94c0f21..a82ef88 100644
--- a/dojox/editor/plugins/nls/el/latinEntities.js
+++ b/dojox/editor/plugins/nls/el/latinEntities.js
@@ -1,17 +1,16 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"Αντεστραμμένο θαυμαστικό",
 	cent:"Σύμβολο λεπτού δολαρίου (σεντ)",
 	pound:"Σύμβολο λίρας",
 	curren:"Σύμβολο νομίσματος",
-	yen:"Σύμβολο γιεν\Σύμβολο γιουάν",
+	yen:"Σύμβολο γιεν/Σύμβολο γιουάν",
 	brvbar:"Διακεκομμένη κάθετος",
 	sect:"Σύμβολο εδαφίου/παραγράφου",
 	uml:"Διαλυτικά",
@@ -24,8 +23,8 @@ define(
 	macr:"Σύμβολο μακρού",
 	deg:"Σύμβολο βαθμού/μοίρας",
 	plusmn:"Σύμβολο συν-πλην",
-	sup2:"Εκθέτης 2",
-	sup3:"Εκθέτης 3",
+	sup2:"Εκθέτης 2\nΤετράγωνο",
+	sup3:"Εκθέτης 3\nΚύβος",
 	acute:"Οξεία",
 	micro:"Σύμβολο 'μίκρο'",
 	para:"Σύμβολο παραγράφου",
@@ -102,7 +101,6 @@ define(
 	yacute:"Πεζό λατινικό γράμμα y με οξεία",
 	thorn:"Πεζό λατινικό γράμμα thorn",
 	yuml:"Πεζό λατινικό γράμμα y με διαλυτικά",
-
 // Greek Characters and Symbols
 	fnof:"Πεζό λατινικό γράμμα f με άγκιστρο\nΣύμβολο συνάρτησης",
 	Alpha:"Κεφαλαίο ελληνικό γράμμα Α",
@@ -161,7 +159,7 @@ define(
 	hellip:"Αποσιωπητικά\nΟριζόντια έλλειψη",
 	prime:"Τόνος\nΛεπτά\nΠόδια",
 	Prime:"Διπλός τόνος\nΔευτερόλεπτα\nΊντσες",
-	oline:"Άνω γραμμή",
+	oline:"Επιγράμμιση/Άνω γραμμή",
 	frasl:"Κάθετος κλάσματος",
 	weierp:"Καλλιγραφικό κεφαλαίο P\nΔυναμοσύνολο\np-συνάρτηση του Weierstrass",
 	image:"Κεφαλαίο I γοτθικού στυλ (black-letter)\nΣύμβολο φανταστικού μέρους",
@@ -187,7 +185,7 @@ define(
 	isin:"Σύμβολο 'ανήκει'",
 	notin:"Σύμβολο 'δεν ανήκει'",
 	ni:"Σύμβολο 'περιλαμβάνει ως μέλος'",
-	prod:"Γινόμενο",
+	prod:"Σύμβολο παραγώγου ν-συνόλου\nΓινόμενο",
 	sum:"Άθροισμα",
 	minus:"Σύμβολο πλην",
 	lowast:"Αστερίσκος",
@@ -200,7 +198,7 @@ define(
 	cap:"Τομή",
 	cup:"Ένωση","int":"Ολοκλήρωμα",
 	there4:"Σύμβολο 'συνεπώς'",
-	sim:"Σύμβολο σχέσεως ισοδυναμίας",
+	sim:"Σύμβολο σχέσεως ισοδυναμίας\nΣύμβολο τελεστή περισπωμένης",
 	cong:"Περίπου ίσο με",
 	asymp:"Σχεδόν ίσο με",
 	ne:"Όχι ίσο με",
@@ -214,7 +212,7 @@ define(
 	supe:"Υπερσύνολο του ή ίσο με",
 	oplus:"Κυκλωμένο συν\nΆμεσο άθροισμα",
 	otimes:"Κυκλωμένο επί\nΔιανυσματικό γινόμενο",
-	perp:"Ορθογώνιο προς\nΚάθετο",
+	perp:"Ορθογώνιο προς\nΣύμβολο καθέτου",
 	sdot:"Τελεστής κουκίδας",
 	lceil:"Αριστερή οροφή",
 	rceil:"Δεξιά οροφή",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"Δεξιό μονό ελληνικό εισαγωγικό",
 	euro:"Σύμβολο ευρώ"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/AutoSave.js b/dojox/editor/plugins/nls/es/AutoSave.js
index 2f43e97..053378b 100644
--- a/dojox/editor/plugins/nls/es/AutoSave.js
+++ b/dojox/editor/plugins/nls/es/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Guardar",
 	"saveSettingLabelOn": "Definir intervalo de guardado automático...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Guardado a las ${0}",
 	"saveMessageFail": "No se ha podido guardar a las ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/Blockquote.js b/dojox/editor/plugins/nls/es/Blockquote.js
index 3179f23..a79475f 100644
--- a/dojox/editor/plugins/nls/es/Blockquote.js
+++ b/dojox/editor/plugins/nls/es/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Cita en bloque"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/Breadcrumb.js b/dojox/editor/plugins/nls/es/Breadcrumb.js
index 5a31f80..ad5c4d3 100644
--- a/dojox/editor/plugins/nls/es/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/es/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "Acciones de ${nodeName}",
 	"selectContents": "Seleccionar contenido",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Mover cursor al inicio",
 	"moveEnd": "Mover cursor al final"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/CollapsibleToolbar.js b/dojox/editor/plugins/nls/es/CollapsibleToolbar.js
index ef6701d..1263412 100644
--- a/dojox/editor/plugins/nls/es/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/es/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Contraer barra de herramientas del editor",
 	"expand": "Expandir barra de herramientas del editor"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/FindReplace.js b/dojox/editor/plugins/nls/es/FindReplace.js
index 16b6dff..5aa453f 100644
--- a/dojox/editor/plugins/nls/es/FindReplace.js
+++ b/dojox/editor/plugins/nls/es/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Buscar:",
 	"findTooltip": "Especifique el texto que desee buscar",
@@ -21,5 +20,4 @@ define(
 	"eofDialogTextFind": "encontrado",
 	"eofDialogTextReplace": "sustituido"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/InsertAnchor.js b/dojox/editor/plugins/nls/es/InsertAnchor.js
index 52be2ca..d8ab793 100644
--- a/dojox/editor/plugins/nls/es/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/es/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Insertar ancla",
 	title: "Propiedades del ancla",
@@ -8,6 +7,4 @@ define(
 	set: "Establecer",
 	cancel: "Cancelar"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/InsertEntity.js b/dojox/editor/plugins/nls/es/InsertEntity.js
index 44e4452..10030f9 100644
--- a/dojox/editor/plugins/nls/es/InsertEntity.js
+++ b/dojox/editor/plugins/nls/es/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Insertar símbolo"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/LocalImage.js b/dojox/editor/plugins/nls/es/LocalImage.js
index 314e5f4..f40efbf 100644
--- a/dojox/editor/plugins/nls/es/LocalImage.js
+++ b/dojox/editor/plugins/nls/es/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Insertar imagen",
 	url: "Imagen",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Especifique un URL de imagen",
 	prePopuTextBrowse: " o seleccione un archivo local."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/PageBreak.js b/dojox/editor/plugins/nls/es/PageBreak.js
index 3522235..393f307 100644
--- a/dojox/editor/plugins/nls/es/PageBreak.js
+++ b/dojox/editor/plugins/nls/es/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Salto de página"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/PasteFromWord.js b/dojox/editor/plugins/nls/es/PasteFromWord.js
index 3ccd13c..d4e55cb 100644
--- a/dojox/editor/plugins/nls/es/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/es/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Pegar desde Word",
-	"paste": "Pegar",
-	"cancel": "Cancelar",
 	"instructions": "Pegue el contenido de Word en el siguiente recuadro de texto. Cuando esté satisfecho con el contenido que se debe insertar, pulse el botón pegar. Para abortar la inserción de texto, pulse el botón cancelar."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/Preview.js b/dojox/editor/plugins/nls/es/Preview.js
index d2aca5c..e658bb7 100644
--- a/dojox/editor/plugins/nls/es/Preview.js
+++ b/dojox/editor/plugins/nls/es/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Previsualización"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/Save.js b/dojox/editor/plugins/nls/es/Save.js
index 4e8a379..55bc847 100644
--- a/dojox/editor/plugins/nls/es/Save.js
+++ b/dojox/editor/plugins/nls/es/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Guardar"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/ShowBlockNodes.js b/dojox/editor/plugins/nls/es/ShowBlockNodes.js
index c4a40fb..bffea66 100644
--- a/dojox/editor/plugins/nls/es/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/es/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Mostrar elementos de bloque HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/Smiley.js b/dojox/editor/plugins/nls/es/Smiley.js
index ac56e83..da67844 100644
--- a/dojox/editor/plugins/nls/es/Smiley.js
+++ b/dojox/editor/plugins/nls/es/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Insertar emoticono",
 	emoticonSmile: "sonrisa",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "llorando",
 	emoticonHappy: "feliz"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/SpellCheck.js b/dojox/editor/plugins/nls/es/SpellCheck.js
index 6225d0c..3dd050f 100644
--- a/dojox/editor/plugins/nls/es/SpellCheck.js
+++ b/dojox/editor/plugins/nls/es/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Corrector ortográfico por lotes",
 	unfound: "No encontrado",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Saltar todos los casos como este",
 	iMsg: "No hay sugerencias de ortografía"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/TableDialog.js b/dojox/editor/plugins/nls/es/TableDialog.js
index 5d9087a..bd802fb 100644
--- a/dojox/editor/plugins/nls/es/TableDialog.js
+++ b/dojox/editor/plugins/nls/es/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Insertar tabla",
 	modifyTableTitle: "Modificar tabla",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Ancho de tabla:",
 	backgroundColor: "Color de fondo:",
 	borderColor: "Color de borde:",
-	borderThickness: "Ancho de borde",
+	borderThickness: "Grosor del borde:",
 	percent: "por ciento",
 	pixels: "píxeles",
 	"default": "default",
@@ -21,16 +20,14 @@ define(
 	buttonSet: "Establecer", // translated elsewhere?
 	buttonInsert: "Insertar",
 	buttonCancel: "Cancelar",
-
 	selectTableLabel: "Seleccionar tabla",
 	insertTableRowBeforeLabel: "Añadir fila antes",
 	insertTableRowAfterLabel: "Añadir fila después",
 	insertTableColumnBeforeLabel: "Añadir columna antes",
 	insertTableColumnAfterLabel: "Añadir columna después",
 	deleteTableRowLabel: "Suprimir fila",
-	deleteTableColumnLabel: "Suprimir columna"
+	deleteTableColumnLabel: "Suprimir columna",
+	colorTableCellTitle: "Celda de tabla de color de fondo",
+	tableContextMenuTitle: "Menú contextual de la tabla"
 })
-	
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/TextColor.js b/dojox/editor/plugins/nls/es/TextColor.js
index cad4ae2..6047d00 100644
--- a/dojox/editor/plugins/nls/es/TextColor.js
+++ b/dojox/editor/plugins/nls/es/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Establecer",
 	"cancelButtonText": "Cancelar"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/es/latinEntities.js b/dojox/editor/plugins/nls/es/latinEntities.js
index 7cce9a6..e949cc4 100644
--- a/dojox/editor/plugins/nls/es/latinEntities.js
+++ b/dojox/editor/plugins/nls/es/latinEntities.js
@@ -1,17 +1,16 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"signo de exclamación inicial",
 	cent:"símbolo de centavos",
 	pound:"símbolo libra esterlina",
 	curren:"símbolo monetario",
-	yen:"símbolo del yen\nsímbolo de yuan",
+	yen:"símbolo del yen\nsímbolo del yuan",
 	brvbar:"barra dividida\nbarra vertical dividida",
 	sect:"signo de sección",
 	uml:"diéresis\ndiéresis de espaciado",
@@ -21,15 +20,15 @@ define(
 	not:"signo de negación",
 	shy:"signo de guión corto",
 	reg:"símbolo de registrado\nsímbolo de marca registrada",
-	macr:"macrón\ndiacrítico largo\nlínea superior\nbarra superior APL",
+	macr:"macron\nmacro de espaciado\nsobrelínea\nsobrebarra APL",
 	deg:"signo de grados",
 	plusmn:"signo de más-menos\nsigno de más o menos",
-	sup2:"superíndice dos\nsuperíndice de dígito dos\nelevado al cuadrado",
-	sup3:"superíndice tres\nsuperíndice de dígito tres\nelevado al cubo",
+	sup2:"superíndice dos\nsuperíndice de dígito dos\nal guardado",
+	sup3:"superíndice tres\nsuperíndice de dígito tres\nal cubo",
 	acute:"acento agudo\nagudo de espaciado",
 	micro:"signo de micro",
 	para:"signo de párrafo",
-	middot:"punto medio\ncoma georgiana\npunto medio griego",
+	middot:"punto medio\ncoma georgina\npunto medio griego",
 	cedil:"cedilla\ncedilla de espaciado",
 	sup1:"superíndice uno\nsuperíndice de dígito uno",
 	ordm:"indicador de ordinal masculino",
@@ -102,7 +101,6 @@ define(
 	yacute:"letra y latina minúscula con acento agudo",
 	thorn:"letra thorn latina minúscula",
 	yuml:"letra y latina minúscula con diéresis",
-
 // Greek Characters and Symbols
 	fnof:"letra f latina minúscula con gancho\nfunción\nflorín",
 	Alpha:"letra alpha griega mayúscula",
@@ -159,15 +157,15 @@ define(
 	piv:"símbolo pi griego",
 	bull:"viñeta\ncírculo negro pequeño",
 	hellip:"puntos suspensivos",
-	prime:"símbolo primo\nminutos\npies",
-	Prime:"símbolo primo doble\nsegundos\npulgadas",
-	oline:"sobrelínea\nsobre la letra",
+	prime:"primero\nminutos\npie",
+	Prime:"primero doble\nsegundos\npulgadas",
+	oline:"sobrelínea\nsobresubrayado de espaciado",
 	frasl:"barra de fracción",
-	weierp:"letra P mayúscula cursiva",
-	image:"letra I mayúscula\nnúmeros imaginarios",
-	real:"letra R mayúscula\nnúmeros reales",
+	weierp:"P mayúsculas de script\nvalor nominal\nWeierstrass p",
+	image:"letra I gótica\nnúmeros imaginarios",
+	real:"letra R gótica\nsímbolo real",
 	trade:"símbolo de marca registrada",
-	alefsym:"símbolo alef\nprimer número transfinito",
+	alefsym:"símbolo alef\nprimer cardinal transfinito",
 	larr:"flecha a la izquierda",
 	uarr:"flecha hacia arriba",
 	rarr:"flecha a la derecha",
@@ -183,26 +181,26 @@ define(
 	part:"derivada parcial",
 	exist:"existe",
 	empty:"conjunto vacío\nconjunto nulo\ndiámetro",
-	nabla:"nabla\ngradiente",
+	nabla:"nabla\ndiferencia hacia atrás",
 	isin:"pertenece",
 	notin:"no pertenece",
 	ni:"está incluido",
-	prod:"productoria\nmultiplicatoria",
+	prod:"producto núm. n\nsímbolo de multiplicación",
 	sum:"sumatoria",
 	minus:"signo menos",
 	lowast:"operador asterisco",
-	radic:"raíz cuadrada\nsigno radical",
+	radic:"raíz cuadrada\nsímbolo de radical",
 	prop:"proporcional",
 	infin:"infinito",
 	ang:"ángulo",
 	and:"y lógico\ncuña",
-	or:"o lógico\nuve",
-	cap:"intersección\nconjuntos",
-	cup:"unión\nconjuntos","int":"integral",
+	or:"o lógico\nvee",
+	cap:"intersección\ncap",
+	cup:"unión\ncup","int":"integral",
 	there4:"por lo tanto",
-	sim:"operador de tilde\nno lógico\nparecido a",
+	sim:"operador de tilde\nvaría con\nsimilar a",
 	cong:"aproximadamente igual a",
-	asymp:"parecido\ncasi igual a",
+	asymp:"casi igual a\nasimtótico a",
 	ne:"no igual a",
 	equiv:"idéntico a",
 	le:"menor o igual que",
@@ -213,12 +211,12 @@ define(
 	sube:"subconjunto de o igual a",
 	supe:"superconjunto de o igual a",
 	oplus:"más en círculo\nsuma directa",
-	otimes:"cruz en círculo\nproducto vectorial",
-	perp:"ortogonal a\nperpendicular",
+	otimes:"veces en círculo\nproducto de vector",
+	perp:"tachuela arriba\nortogonal a\nperpendicular",
 	sdot:"operador punto",
-	lceil:"parte superior de corchete abierto",
+	lceil:"límite superior izquierdo\nmontante arriba APL",
 	rceil:"parte superior de corchete cerrado",
-	lfloor:"parte inferior de corchete abierto",
+	lfloor:"límite inferior derecho\nmontaje abajo APL",
 	rfloor:"parte inferior de corchete abierto",
 	lang:"corchete angular hacia la izquierda",
 	rang:"corchete angular hacia la derecha",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"comilla simple angular cerrada",
 	euro:"signo del euro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/AutoSave.js b/dojox/editor/plugins/nls/fi/AutoSave.js
index c2949c3..1c4fc36 100644
--- a/dojox/editor/plugins/nls/fi/AutoSave.js
+++ b/dojox/editor/plugins/nls/fi/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Tallenna",
 	"saveSettingLabelOn": "Aseta automaattisen tallennuksen väli...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Tallennusaika ${0}",
 	"saveMessageFail": "Tallennus epäonnistui ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/Blockquote.js b/dojox/editor/plugins/nls/fi/Blockquote.js
index 757ba92..bed9ca8 100644
--- a/dojox/editor/plugins/nls/fi/Blockquote.js
+++ b/dojox/editor/plugins/nls/fi/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
-	"blockquote": "Sitaatti"
+	"blockquote": "Blockquote"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/Breadcrumb.js b/dojox/editor/plugins/nls/fi/Breadcrumb.js
index b43fa7b..0176567 100644
--- a/dojox/editor/plugins/nls/fi/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/fi/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} - Toiminnot",
 	"selectContents": "Valitse sisältö",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Siirrä kohdistin alkuun",
 	"moveEnd": "Siirrä kohdistin loppuun"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/CollapsibleToolbar.js b/dojox/editor/plugins/nls/fi/CollapsibleToolbar.js
index f1fe530..bbc27e3 100644
--- a/dojox/editor/plugins/nls/fi/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/fi/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Pienennä muokkausohjelman työkalurivi",
 	"expand": "Laajenna muokkausohjelman työkalurivi"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/FindReplace.js b/dojox/editor/plugins/nls/fi/FindReplace.js
index c8af94c..3e40c2b 100644
--- a/dojox/editor/plugins/nls/fi/FindReplace.js
+++ b/dojox/editor/plugins/nls/fi/FindReplace.js
@@ -1,9 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Etsi:",
 	"findTooltip": "Anna etsittävä teksti",
-	"replaceLabel": "Korvaava:",
+	"replaceLabel": "Korvaa seuraavalla:",
 	"replaceTooltip": "Anna korvaava teksti",
 	"findReplace": "Etsi ja korvaa",
 	"matchCase": "Sama kirjainkoko",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "löytynyt",
 	"eofDialogTextReplace": "korvattu"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/InsertAnchor.js b/dojox/editor/plugins/nls/fi/InsertAnchor.js
index 7e25d59..3f75d73 100644
--- a/dojox/editor/plugins/nls/fi/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/fi/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Lisää ankkuri",
 	title: "Ankkurin ominaisuudet",
@@ -8,6 +7,4 @@ define(
 	set: "Aseta",
 	cancel: "Peruuta"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/InsertEntity.js b/dojox/editor/plugins/nls/fi/InsertEntity.js
index 35863a5..d37483e 100644
--- a/dojox/editor/plugins/nls/fi/InsertEntity.js
+++ b/dojox/editor/plugins/nls/fi/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Lisää symboli"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/LocalImage.js b/dojox/editor/plugins/nls/fi/LocalImage.js
index d6e5b5a..d8e0d8d 100644
--- a/dojox/editor/plugins/nls/fi/LocalImage.js
+++ b/dojox/editor/plugins/nls/fi/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Lisää kuva",
 	url: "Kuva",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Anna kuvan URL-osoite",
 	prePopuTextBrowse: " tai selaa paikalliseen tiedostoon."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/PageBreak.js b/dojox/editor/plugins/nls/fi/PageBreak.js
index 3b0e71e..c3260be 100644
--- a/dojox/editor/plugins/nls/fi/PageBreak.js
+++ b/dojox/editor/plugins/nls/fi/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Sivunvaihto"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/PasteFromWord.js b/dojox/editor/plugins/nls/fi/PasteFromWord.js
index d7fdadd..0014793 100644
--- a/dojox/editor/plugins/nls/fi/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/fi/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Liitä Word-ohjelmasta",
-	"paste": "Liitä",
-	"cancel": "Peruuta",
 	"instructions": "Liitä sisältö Word-tiedostosta alla olevaan tekstikenttään. Kun lisättävä sisältö on mielestäsi valmis, napsauta Liitä-painiketta. Voit peruuttaa lisäyksen napsauttamalla Peruuta-painiketta."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/Preview.js b/dojox/editor/plugins/nls/fi/Preview.js
index 20dec44..68101a3 100644
--- a/dojox/editor/plugins/nls/fi/Preview.js
+++ b/dojox/editor/plugins/nls/fi/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Esikatselu"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/Save.js b/dojox/editor/plugins/nls/fi/Save.js
index 2ba78f8..d7ef9a0 100644
--- a/dojox/editor/plugins/nls/fi/Save.js
+++ b/dojox/editor/plugins/nls/fi/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Tallenna"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/ShowBlockNodes.js b/dojox/editor/plugins/nls/fi/ShowBlockNodes.js
index bfb3bc9..0dc3f0f 100644
--- a/dojox/editor/plugins/nls/fi/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/fi/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Näytä HTML-lohkoelementit"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/Smiley.js b/dojox/editor/plugins/nls/fi/Smiley.js
index 13b2802..64602ba 100644
--- a/dojox/editor/plugins/nls/fi/Smiley.js
+++ b/dojox/editor/plugins/nls/fi/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Lisää hymiö",
 	emoticonSmile: "hymyillä",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "itkeä",
 	emoticonHappy: "iloinen"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/SpellCheck.js b/dojox/editor/plugins/nls/fi/SpellCheck.js
index 0eb9833..c985b90 100644
--- a/dojox/editor/plugins/nls/fi/SpellCheck.js
+++ b/dojox/editor/plugins/nls/fi/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Eräoikoluku",
 	unfound: "Ei löydy",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Ohita kaikki samanlaiset",
 	iMsg: "Ei oikeinkirjoitusehdotuksia"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/TableDialog.js b/dojox/editor/plugins/nls/fi/TableDialog.js
index 80eb46f..f8d3525 100644
--- a/dojox/editor/plugins/nls/fi/TableDialog.js
+++ b/dojox/editor/plugins/nls/fi/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Lisää taulukko",
 	modifyTableTitle: "Muokkaa taulukkoa",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Taulukon leveys:",
 	backgroundColor: "Taustaväri:",
 	borderColor: "Kehyksen väri:",
-	borderThickness: "Kehyksen paksuus",
+	borderThickness: "Kehyksen paksuus:",
 	percent: "prosenttia",
 	pixels: "kuvapistettä",
 	"default": "oletus",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Aseta", // translated elsewhere?
 	buttonInsert: "Lisää",
 	buttonCancel: "Peruuta",
-
 	selectTableLabel: "Valitse taulukko",
 	insertTableRowBeforeLabel: "Lisää rivi ennen",
 	insertTableRowAfterLabel: "Lisää rivi jälkeen",
 	insertTableColumnBeforeLabel: "Lisää sarake ennen",
 	insertTableColumnAfterLabel: "Lisää sarake jälkeen",
 	deleteTableRowLabel: "Poista rivi",
-	deleteTableColumnLabel: "Poista sarake"
+	deleteTableColumnLabel: "Poista sarake",
+	colorTableCellTitle: "Taulukon solun taustaväri",
+	tableContextMenuTitle: "Taulukon pikavalikko"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/TextColor.js b/dojox/editor/plugins/nls/fi/TextColor.js
index 1ac9697..a8655bd 100644
--- a/dojox/editor/plugins/nls/fi/TextColor.js
+++ b/dojox/editor/plugins/nls/fi/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Aseta",
 	"cancelButtonText": "Peruuta"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fi/latinEntities.js b/dojox/editor/plugins/nls/fi/latinEntities.js
index 462ce1d..8ced70b 100644
--- a/dojox/editor/plugins/nls/fi/latinEntities.js
+++ b/dojox/editor/plugins/nls/fi/latinEntities.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -102,7 +101,6 @@ define(
 	yacute:"pieni y ja akuutti\ngemena y ja akuutti\npieni y ja akuuttiaksentti",
 	thorn:"pieni thorn\ngemena thorn",
 	yuml:"pieni y ja treema\ngemena y ja treema",
-
 // Greek Characters and Symbols
 	fnof:"pieni f, jossa koukku\ngemena f, jossa koukku\nfunktio\nguldeni",
 	Alpha:"iso alfa\nversaali alfa",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"oikealle osoittava kulmapuolilainausmerkki",
 	euro:"euron merkki"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/AutoSave.js b/dojox/editor/plugins/nls/fr/AutoSave.js
index dc8fac1..7e7fea7 100644
--- a/dojox/editor/plugins/nls/fr/AutoSave.js
+++ b/dojox/editor/plugins/nls/fr/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Enregistrer",
 	"saveSettingLabelOn": "Définir l'intervalle d'enregistrement automatique...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Enregistré à ${0}",
 	"saveMessageFail": "Echec de l'enregistrement à ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/Blockquote.js b/dojox/editor/plugins/nls/fr/Blockquote.js
index 8e0ecb1..f305d12 100644
--- a/dojox/editor/plugins/nls/fr/Blockquote.js
+++ b/dojox/editor/plugins/nls/fr/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Bloc de citation"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/Breadcrumb.js b/dojox/editor/plugins/nls/fr/Breadcrumb.js
index 3e4b0b1..57289ed 100644
--- a/dojox/editor/plugins/nls/fr/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/fr/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "Actions ${nodeName}",
 	"selectContents": "Sélection de contenus",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Déplacer le curseur vers le début",
 	"moveEnd": "Déplacer le curseur vers la fin"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/CollapsibleToolbar.js b/dojox/editor/plugins/nls/fr/CollapsibleToolbar.js
index 9e24571..99876cb 100644
--- a/dojox/editor/plugins/nls/fr/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/fr/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Réduire la barre d'outils de l'éditeur",
 	"expand": "Développer la barre d'outils de l'éditeur"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/FindReplace.js b/dojox/editor/plugins/nls/fr/FindReplace.js
index 63e56d9..07876ca 100644
--- a/dojox/editor/plugins/nls/fr/FindReplace.js
+++ b/dojox/editor/plugins/nls/fr/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Rechercher :",
 	"findTooltip": "Entrez le texte à rechercher",
@@ -21,5 +20,4 @@ define(
 	"eofDialogTextFind": "trouvé",
 	"eofDialogTextReplace": "remplacé"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/InsertAnchor.js b/dojox/editor/plugins/nls/fr/InsertAnchor.js
index 7ba6b6b..bfa2097 100644
--- a/dojox/editor/plugins/nls/fr/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/fr/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Insérer un point d'ancrage",
 	title: "Propriétés du point d'ancrage",
@@ -8,6 +7,4 @@ define(
 	set: "Définir",
 	cancel: "Annuler"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/InsertEntity.js b/dojox/editor/plugins/nls/fr/InsertEntity.js
index ffea02a..2714ab2 100644
--- a/dojox/editor/plugins/nls/fr/InsertEntity.js
+++ b/dojox/editor/plugins/nls/fr/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Insertion d'un symbole"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/LocalImage.js b/dojox/editor/plugins/nls/fr/LocalImage.js
index 64c3fe5..035da53 100644
--- a/dojox/editor/plugins/nls/fr/LocalImage.js
+++ b/dojox/editor/plugins/nls/fr/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Insérer une image",
 	url: "Image",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Entrez une URL d'image",
 	prePopuTextBrowse: " ou sélectionnez un fichier local."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/PageBreak.js b/dojox/editor/plugins/nls/fr/PageBreak.js
index 8290b8e..d6bd428 100644
--- a/dojox/editor/plugins/nls/fr/PageBreak.js
+++ b/dojox/editor/plugins/nls/fr/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Saut de page"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/PasteFromWord.js b/dojox/editor/plugins/nls/fr/PasteFromWord.js
index 2a0d546..e0cfaaa 100644
--- a/dojox/editor/plugins/nls/fr/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/fr/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Coller depuis Word",
-	"paste": "Coller",
-	"cancel": "Annuler",
 	"instructions": "Collez le contenu Word dans la zone de texte ci-dessous. Quand le contenu à insérer vous convient, appuyez sur le bouton Coller. Pour annuler l'insertion du texte, utilisez le bouton Annuler."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/Preview.js b/dojox/editor/plugins/nls/fr/Preview.js
index cf58ce8..d295402 100644
--- a/dojox/editor/plugins/nls/fr/Preview.js
+++ b/dojox/editor/plugins/nls/fr/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Aperçu"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/Save.js b/dojox/editor/plugins/nls/fr/Save.js
index 564c5a8..97c9fd7 100644
--- a/dojox/editor/plugins/nls/fr/Save.js
+++ b/dojox/editor/plugins/nls/fr/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
-	"save": "Sauvegarder"
+	"save": "Enregistrer"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/ShowBlockNodes.js b/dojox/editor/plugins/nls/fr/ShowBlockNodes.js
index 38f3a4c..c32a59e 100644
--- a/dojox/editor/plugins/nls/fr/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/fr/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Affichage des éléments de bloc HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/Smiley.js b/dojox/editor/plugins/nls/fr/Smiley.js
index 107705c..c2995dc 100644
--- a/dojox/editor/plugins/nls/fr/Smiley.js
+++ b/dojox/editor/plugins/nls/fr/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Insérer une émoticône",
 	emoticonSmile: "sourire",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "pleurs",
 	emoticonHappy: "sourire"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/SpellCheck.js b/dojox/editor/plugins/nls/fr/SpellCheck.js
index 83b586e..df29ae7 100644
--- a/dojox/editor/plugins/nls/fr/SpellCheck.js
+++ b/dojox/editor/plugins/nls/fr/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Vérification orthographique par lots",
 	unfound: "Introuvable",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Ignorer chaque fois",
 	iMsg: "Aucune suggestion orthographique"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/TableDialog.js b/dojox/editor/plugins/nls/fr/TableDialog.js
index f096094..5a6083a 100644
--- a/dojox/editor/plugins/nls/fr/TableDialog.js
+++ b/dojox/editor/plugins/nls/fr/TableDialog.js
@@ -1,35 +1,33 @@
 define(
-//begin v1.x content
 ({
-	insertTableTitle: "Insérer une table",
-	modifyTableTitle: "Modifier une table",
+	insertTableTitle: "Insertion d'une table",
+	modifyTableTitle: "Modification d'une table",
 	rows: "Lignes :",
 	columns: "Colonnes :",
 	align: "Aligner :",
-	cellPadding: "Remplissage des cellules :",
+	cellPadding: "Remplissage des cellules",
 	cellSpacing: "Espacement des cellules :",
-	tableWidth: "Largeur de table :",
+	tableWidth: "Largeur de la table :",
 	backgroundColor: "Couleur d'arrière-plan :",
-	borderColor: "Couleur des bordures :",
-	borderThickness: "Epaisseur des bordures",
+	borderColor: "Couleur de la bordure :",
+	borderThickness: "Epaisseur des bordures :",
 	percent: "pourcentage",
 	pixels: "pixels",
-	"default": "par défaut",
-	left: "aligné à gauche",
-	center: "centré",
-	right: "aligné à droite",
+	"default": "valeur par défaut",
+	left: "à gauche",
+	center: "au centre",
+	right: "à droite",
 	buttonSet: "Définir", // translated elsewhere?
 	buttonInsert: "Insérer",
 	buttonCancel: "Annuler",
-
-	selectTableLabel: "Sélectionner une table",
+	selectTableLabel: "Sélection d'une table",
 	insertTableRowBeforeLabel: "Ajouter une ligne avant",
 	insertTableRowAfterLabel: "Ajouter une ligne après",
 	insertTableColumnBeforeLabel: "Ajouter une colonne avant",
 	insertTableColumnAfterLabel: "Ajouter une colonne après",
-	deleteTableRowLabel: "Supprimer la ligne",
-	deleteTableColumnLabel: "Supprimer la colonne"
+	deleteTableRowLabel: "Supprimer une ligne",
+	deleteTableColumnLabel: "Supprimer une colonne",
+	colorTableCellTitle: "Cellule de la table (couleur d'arrière-plan)",
+	tableContextMenuTitle: "Menu contextuel de la table"
 })
-	
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/TextColor.js b/dojox/editor/plugins/nls/fr/TextColor.js
index 82d0e41..75fa021 100644
--- a/dojox/editor/plugins/nls/fr/TextColor.js
+++ b/dojox/editor/plugins/nls/fr/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Définir",
 	"cancelButtonText": "Annuler"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/fr/latinEntities.js b/dojox/editor/plugins/nls/fr/latinEntities.js
index 905a581..ab60472 100644
--- a/dojox/editor/plugins/nls/fr/latinEntities.js
+++ b/dojox/editor/plugins/nls/fr/latinEntities.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"point d'exclamation inversé",
 	cent:"signe cent",
@@ -29,7 +28,7 @@ define(
 	acute:"accent aigu\naccent aigu d'espacement",
 	micro:"signe micro",
 	para:"symbole de paragraphe",
-	middot:"point médian\nvirgule géorgiennea\npoint médian grec",
+	middot:"point médian\nvirgule géorgienne\npoint médian grec",
 	cedil:"cédille\ncédille d'espacement",
 	sup1:"exposant un\npuissance un",
 	ordm:"indicateur ordinal masculin",
@@ -102,7 +101,6 @@ define(
 	yacute:"Latin - y minuscule avec accent aigu",
 	thorn:"Latin - thorn minuscule",
 	yuml:"Latin - y minuscule avec tréma",
-
 // Greek Characters and Symbols
 	fnof:"Latin - f minuscule avec crochet\nfonction\nflorin",
 	Alpha:"Grec - alpha majuscule",
@@ -163,7 +161,7 @@ define(
 	Prime:"double apostrophe\nsecondes\npouces",
 	oline:"surligné\nbarre supérieure d'espacement",
 	frasl:"barre de fraction",
-	weierp:"P majuscule scripte\nensemble de puissances\nfonction elliptique de Weierstrass",
+	weierp:"P majuscule script\nensemble de puissances\nfonction elliptique de Weierstrass",
 	image:"I majuscule noir\npartie imaginaire",
 	real:"R majuscule noir\npartie réelle",
 	trade:"signe de marque commerciale",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"guillemet simple orienté vers la droite",
 	euro:"signe euro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/AutoSave.js b/dojox/editor/plugins/nls/he/AutoSave.js
index a2f6363..734b7bc 100644
--- a/dojox/editor/plugins/nls/he/AutoSave.js
+++ b/dojox/editor/plugins/nls/he/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "שמירה",
 	"saveSettingLabelOn": "הגדרת מרווח שמירה אוטומטית...‏",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "נשמר ${0}",
 	"saveMessageFail": "כשל בשמירה ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/Blockquote.js b/dojox/editor/plugins/nls/he/Blockquote.js
index ae3d5f9..b0f263c 100644
--- a/dojox/editor/plugins/nls/he/Blockquote.js
+++ b/dojox/editor/plugins/nls/he/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "ציטוט"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/Breadcrumb.js b/dojox/editor/plugins/nls/he/Breadcrumb.js
index 3f8f245..8855b3a 100644
--- a/dojox/editor/plugins/nls/he/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/he/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "פעולות ${nodeName} ",
 	"selectContents": "בחירת תוכן ",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "העברת הסמן להתחלה ",
 	"moveEnd": "העברת הסמן לסוף "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/CollapsibleToolbar.js b/dojox/editor/plugins/nls/he/CollapsibleToolbar.js
index cb2a641..909e3c8 100644
--- a/dojox/editor/plugins/nls/he/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/he/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "כיווץ סרגל הכלים של העורך ",
 	"expand": "הרחבת סרגל הכלים של העורך"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/FindReplace.js b/dojox/editor/plugins/nls/he/FindReplace.js
index d0c1fae..560ed2a 100644
--- a/dojox/editor/plugins/nls/he/FindReplace.js
+++ b/dojox/editor/plugins/nls/he/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "חיפוש: ",
 	"findTooltip": "ציינו תמליל לחיפוש",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "נמצאו",
 	"eofDialogTextReplace": "הוחלפו "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/InsertAnchor.js b/dojox/editor/plugins/nls/he/InsertAnchor.js
index 33ba4c0..9444a8c 100644
--- a/dojox/editor/plugins/nls/he/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/he/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "הוספת עוגן ",
 	title: "תכונות עוגן ",
@@ -8,6 +7,4 @@ define(
 	set: "הגדרה",
 	cancel: "ביטול"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/InsertEntity.js b/dojox/editor/plugins/nls/he/InsertEntity.js
index 2a8dbf9..4b61250 100644
--- a/dojox/editor/plugins/nls/he/InsertEntity.js
+++ b/dojox/editor/plugins/nls/he/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "הוספת סמל "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/LocalImage.js b/dojox/editor/plugins/nls/he/LocalImage.js
index 7c0b981..c540816 100644
--- a/dojox/editor/plugins/nls/he/LocalImage.js
+++ b/dojox/editor/plugins/nls/he/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "הוספת תמונה",
 	url: "תמונה",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "ציינו URL של תמונה",
 	prePopuTextBrowse: " או נווטו לקובץ מקומי. "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/PageBreak.js b/dojox/editor/plugins/nls/he/PageBreak.js
index 83fe084..2295502 100644
--- a/dojox/editor/plugins/nls/he/PageBreak.js
+++ b/dojox/editor/plugins/nls/he/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "מעבר עמוד"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/PasteFromWord.js b/dojox/editor/plugins/nls/he/PasteFromWord.js
index bb5d05a..f30f83e 100644
--- a/dojox/editor/plugins/nls/he/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/he/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "הדבקה מתוך Word",
-	"paste": "הדבקה",
-	"cancel": "ביטול",
 	"instructions": "הדביקו את התוכן מתוך Word לתוך תיבת התמליל למטה. לאחר שתהיו מרוצים מהתוכן להוספה, לחצו על לחצן ההדבקה. כדי לבטל את הוספת התמליל, לחצו על לחצן הביטול. "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/Preview.js b/dojox/editor/plugins/nls/he/Preview.js
index e332bea..eec4940 100644
--- a/dojox/editor/plugins/nls/he/Preview.js
+++ b/dojox/editor/plugins/nls/he/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "תצוגה מקדימה"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/SafePaste.js b/dojox/editor/plugins/nls/he/SafePaste.js
new file mode 100644
index 0000000..50858c8
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "הדבקה ישירה מושבתת. הדביקו תוכן בדו-שיח זה באמצעות בקרות ההדבקה הסטנדריות של הדפדפן במקלדת או בתפריט. לאחר שתהיו מרוצים מהתוכן להוספה, לחצו על לחצן ההדבקה.   כדי לבטל את הוספת התמליל, לחצו על לחצן הביטול. "
+})
+);
diff --git a/dojox/editor/plugins/nls/he/Save.js b/dojox/editor/plugins/nls/he/Save.js
index 946c8ff..058f3a5 100644
--- a/dojox/editor/plugins/nls/he/Save.js
+++ b/dojox/editor/plugins/nls/he/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "שמירה"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/ShowBlockNodes.js b/dojox/editor/plugins/nls/he/ShowBlockNodes.js
index cc6439e..234121f 100644
--- a/dojox/editor/plugins/nls/he/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/he/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "הצגת מרכיבי Block של HTML "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/Smiley.js b/dojox/editor/plugins/nls/he/Smiley.js
index 11bad8f..09a226b 100644
--- a/dojox/editor/plugins/nls/he/Smiley.js
+++ b/dojox/editor/plugins/nls/he/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "הוספת רגשון",
 	emoticonSmile: "חיוך",
@@ -19,8 +18,7 @@ define(
 	emoticonYes: "כן",
 	emoticonNo: "לא",
 	emoticonAngel: "מלאך ",
-	emoticonCrying: "בוכה"
+	emoticonCrying: "בוכה",
+	emoticonHappy: "שמח"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/SpellCheck.js b/dojox/editor/plugins/nls/he/SpellCheck.js
index 50b5c9c..fb85428 100644
--- a/dojox/editor/plugins/nls/he/SpellCheck.js
+++ b/dojox/editor/plugins/nls/he/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "בדיקת איות באצווה ",
 	unfound: "לא נמצא ",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "דילוג על כל הערכים הדומים לערך זה ",
 	iMsg: "אין הצעות איות "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/TableDialog.js b/dojox/editor/plugins/nls/he/TableDialog.js
index 8cb38c9..4c1edd4 100644
--- a/dojox/editor/plugins/nls/he/TableDialog.js
+++ b/dojox/editor/plugins/nls/he/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "הוספת טבלה",
 	modifyTableTitle: "שינוי טבלה",
@@ -8,11 +7,11 @@ define(
 	align: "יישור:",
 	cellPadding: "ריפוד תאים:",
 	cellSpacing: "ריווח תאים:",
-	tableWidth: "רוחב טבלה:‏",
+	tableWidth: "רוחב טבלה:",
 	backgroundColor: "צבע רקע:",
 	borderColor: "צבע גבול:",
-	borderThickness: "עובי גבול",
-	percent: "אחוזים",
+	borderThickness: "עובי גבול:",
+	percent: "אחוז",
 	pixels: "פיקסלים",
 	"default": "ברירת מחדל",
 	left: "ימין",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "הגדרה", // translated elsewhere?
 	buttonInsert: "הוספה",
 	buttonCancel: "ביטול",
-
 	selectTableLabel: "בחירת טבלה",
 	insertTableRowBeforeLabel: "הוספת שורה לפני",
 	insertTableRowAfterLabel: "הוספת שורה אחרי",
 	insertTableColumnBeforeLabel: "הוספת עמודה לפני",
 	insertTableColumnAfterLabel: "הוספת עמודה אחרי",
 	deleteTableRowLabel: "מחיקת שורה",
-	deleteTableColumnLabel: "מחיקת עמודה"
+	deleteTableColumnLabel: "מחיקת עמודה",
+	colorTableCellTitle: "צבע רקע של תא בטבלה",
+	tableContextMenuTitle: "תפריט הקשר של טבלה"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/TextColor.js b/dojox/editor/plugins/nls/he/TextColor.js
index 912de00..57a7846 100644
--- a/dojox/editor/plugins/nls/he/TextColor.js
+++ b/dojox/editor/plugins/nls/he/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "הגדרה",
 	"cancelButtonText": "ביטול"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/he/latinEntities.js b/dojox/editor/plugins/nls/he/latinEntities.js
index cc1257c..66570dc 100644
--- a/dojox/editor/plugins/nls/he/latinEntities.js
+++ b/dojox/editor/plugins/nls/he/latinEntities.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -102,7 +101,6 @@ define(
 	yacute:"Latin small letter y with acute",
 	thorn:"Latin small letter thorn",
 	yuml:"Latin small letter y with diaeresis",
-
 // Greek Characters and Symbols
 	fnof:"Latin small f with hook\nfunction\nflorin",
 	Alpha:"Greek capital letter alpha",
@@ -256,5 +254,4 @@ define(
 	rsaquo:"single right-pointing angle quotation mark",
 	euro:"euro sign"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hr/PasteFromWord.js b/dojox/editor/plugins/nls/hr/PasteFromWord.js
index 6e1add5..88e82ec 100644
--- a/dojox/editor/plugins/nls/hr/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/hr/PasteFromWord.js
@@ -1,8 +1,6 @@
 define(
 ({
 	"pasteFromWord": "Zalijepi iz Worda",
-	"paste": "Zalijepi",
-	"cancel": "Opoziv",
-	"instructions": "Zalijepite sadržaj iz Worda u donji tekstni okvir. Kada ste zadovoljni sa sadržajem za umetanje, pritisnite tipku Zalijepi.  Za prekid umetanja teksta, pritisnite tipku Opoziv."
+	"instructions": "Zalijepite sadržaj iz Worda u donji tekstni okvir. Kad ste zadovoljni sa sadržajem za umetanje, pritisnite tipku Zalijepi.  Za prekid umetanja teksta, pritisnite tipku Opoziv."
 })
 );
diff --git a/dojox/editor/plugins/nls/hr/SafePaste.js b/dojox/editor/plugins/nls/hr/SafePaste.js
index 817bf8d..a696060 100644
--- a/dojox/editor/plugins/nls/hr/SafePaste.js
+++ b/dojox/editor/plugins/nls/hr/SafePaste.js
@@ -1,5 +1,5 @@
 define(
 ({
-	"instructions": "Izravno lijepljenje je onemogućeno.  Molimo zalijepite sadržaj u ovom dijaloškom okviru pomoću kontrola za lijepljenje na tipkovnici ili izborniku standardnog preglednika.   Kada ste zadovoljni sa sadržajem za umetanje, pritisnite tipku Zalijepi.  Za prekid umetanja sadržaja, pritisnite tipku Opoziv."
+	"instructions": "Izravno lijepljenje je onemogućeno.  Molimo zalijepite sadržaj u ovom dijaloškom okviru pomoću kontrola za lijepljenje na tipkovnici ili izborniku standardnog preglednika.   Kad ste zadovoljni sa sadržajem za umetanje, pritisnite tipku Zalijepi.  Za prekid umetanja sadržaja, pritisnite tipku Opoziv."
 })
 );
diff --git a/dojox/editor/plugins/nls/hr/ShowBlockNodes.js b/dojox/editor/plugins/nls/hr/ShowBlockNodes.js
index 17fe691..3ff5a69 100644
--- a/dojox/editor/plugins/nls/hr/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/hr/ShowBlockNodes.js
@@ -1,5 +1,5 @@
 define(
 ({
-	"showBlockNodes": "Prikaži elemente HTML bloka"
+	"showBlockNodes": "Pokaži elemente HTML bloka"
 })
 );
diff --git a/dojox/editor/plugins/nls/hr/Smiley.js b/dojox/editor/plugins/nls/hr/Smiley.js
index e992c36..7a1fd11 100644
--- a/dojox/editor/plugins/nls/hr/Smiley.js
+++ b/dojox/editor/plugins/nls/hr/Smiley.js
@@ -8,7 +8,7 @@ define(
 	emoticonCool: "staložen",
 	emoticonAngry: "ljut",
 	emoticonHalf: "indiferentan",
-	emoticonEyebrow: "namigivanje",
+	emoticonEyebrow: "podignuta obrva",
 	emoticonFrown: "namršten",
 	emoticonShy: "stidljiv",
 	emoticonGoofy: "budalast",
diff --git a/dojox/editor/plugins/nls/hr/SpellCheck.js b/dojox/editor/plugins/nls/hr/SpellCheck.js
index 6eeb49a..24fc437 100644
--- a/dojox/editor/plugins/nls/hr/SpellCheck.js
+++ b/dojox/editor/plugins/nls/hr/SpellCheck.js
@@ -10,7 +10,7 @@ define(
 	replaceWith: "Zamijeni s",
 	replaceAll: "Zamijeni sve",
 	cancel: "Opoziv",
-	msg: "Nisu nađene pogreške u pisanju",
+	msg: "Nisu nađene greške u pisanju",
 	iSkip: "Preskoči ovo",
 	iSkipAll: "Preskoči sve poput ovog",
 	iMsg: "Nema prijedloga pravopisa"
diff --git a/dojox/editor/plugins/nls/hr/TableDialog.js b/dojox/editor/plugins/nls/hr/TableDialog.js
index b5c833a..4be37db 100644
--- a/dojox/editor/plugins/nls/hr/TableDialog.js
+++ b/dojox/editor/plugins/nls/hr/TableDialog.js
@@ -21,11 +21,13 @@ define(
 	buttonInsert: "Umetni",
 	buttonCancel: "Opoziv",
 	selectTableLabel: "Označi tablicu",
-	insertTableRowBeforeLabel: "Dodaj redak prije",
-	insertTableRowAfterLabel: "Dodaj redak nakon",
+	insertTableRowBeforeLabel: "Dodaj red prije",
+	insertTableRowAfterLabel: "Dodaj red nakon",
 	insertTableColumnBeforeLabel: "Dodaj stupac prije",
 	insertTableColumnAfterLabel: "Dodaj stupac nakon",
-	deleteTableRowLabel: "Izbriši redak",
-	deleteTableColumnLabel: "Izbriši stupac"
+	deleteTableRowLabel: "Izbriši red",
+	deleteTableColumnLabel: "Izbriši stupac",
+	colorTableCellTitle: "pozadinska boja ćelije tablice",
+	tableContextMenuTitle: "Kontekstni izbornik tablice"
 })
 );
diff --git a/dojox/editor/plugins/nls/hr/latinEntities.js b/dojox/editor/plugins/nls/hr/latinEntities.js
index e4a9a81..22d3c8e 100644
--- a/dojox/editor/plugins/nls/hr/latinEntities.js
+++ b/dojox/editor/plugins/nls/hr/latinEntities.js
@@ -1,106 +1,106 @@
 define(
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"obrnuti uskličnik",
 	cent:"znak centa",
 	pound:"znak funte",
 	curren:"znak valute",
-	yen:"znak yena\nznak yuana",
+	yen:"znak jena\n znak juana",
 	brvbar:"isprekidana crta\nisprekidana okomita crta",
 	sect:"znak odlomka",
-	uml:"dijareza\nprored dijareze",
+	uml:"dijereza\nprored dijereze",
 	copy:"znak autorskog prava",
 	ordf:"indikator rednog broja ženskog roda",
-	laquo:"navodnik okrenut prema lijevo s dvostrukom strelicom\nnavodnik sa strelicama okrenutim prema lijevo",
+	laquo:"lijevo usmjereni dvostruki kutni navodnik\nlijevo usmjereni guillemet",
 	not:"znak ne",
 	shy:"meka crtica\ndiskrecijska crtica",
-	reg:"znak za registrirano\nznak za registrirani zaštitni znak",
-	macr:"makron\nprored makrona\nnadvučeno\nAPL crta iznad",
+	reg:"znak registrirano\nznak registriranog zaštitnog znaka",
+	macr:"makron\nprored makrona\ncrta iznad\nAPL traka iznad",
 	deg:"znak stupnja",
-	plusmn:"znak plus-minus\nplus-ili-minus znak",
-	sup2:"superskript dva\nsuperskript broj dva\nkvadriran",
-	sup3:"superskript tri\nsuperskript broj tri\nkuban",
-	acute:"jednostruki navodnik\nprored jednostrukog navodnika",
+	plusmn:"znak plus-minus\nznak plus-ili-minus",
+	sup2:"superskript dva\nsuperskript sa znamenkom dva\nkvadrat",
+	sup3:"superskript tri\nsuperskript sa znamenkom tri\nkub",
+	acute:"akut\nprored akuta",
 	micro:"znak mikro",
 	para:"znak odlomka\nznak paragrafa",
-	middot:"srednja točka\ngeorgijanski zarez\ngrčka srednja točka",
-	cedil:"sedija\nprored sedije",
-	sup1:"superskript jedan\nsuperskript broj jedan",
+	middot:"srednja točka\ngregorijanski zarez\ngrčka srednja točka",
+	cedil:"sedilja\nprored sedilje",
+	sup1:"superskript jedan\nsuperskript sa znamenkom jedan",
 	ordm:"indikator rednog broja muškog roda",
-	raquo:"navodnik okrenut prema desno s dvostrukom strelicom\nnavodnik sa strelicama okrenutim prema desno",
-	frac14:"prost razlomak jedne četvrtine\nrazlomak jedna četvrtina",
-	frac12:"prost razlomak jedne polovine\nrazlomak jedna polovina",
+	raquo:"desno usmjereni dvostruki kutni navodnik\ndesno usmjereni guillemet",
+	frac14:"prost razlomak jedna četvrtina\nrazlomak jedna četvrtina",
+	frac12:"prost razlomak jedna polovina\nrazlomak jedna polovina",
 	frac34:"prost razlomak tri četvrtine\nrazlomak tri četvrtine",
-	iquest:"preokrenuti upitnik\nokrenut upitnik",
-	Agrave:"Latinsko veliko slovo A s grav akcentom\nLatinsko veliko slovo A grav",
+	iquest:"preokrenuti upitnik\nobrnuti upitnik",
+	Agrave:"Latinsko veliko slovo A s grav akcentom\nLatinsko veliko slovo A s grav akcentom",
 	Aacute:"Latinsko veliko slovo A s akutnim akcentom",
-	Acirc:"Latinsko veliko slovo A sa cirkumfleksom",
+	Acirc:"Latinsko veliko slovo A s cirkumfleksom",
 	Atilde:"Latinsko veliko slovo A s tildom",
-	Auml:"Latinsko veliko slovo A s dijarezom",
-	Aring:"Latinsko veliko slovo A s prstenom iznad\nLatinsko veliko slovo A prsten iznad",
+	Auml:"Latinsko veliko slovo A s dijerezom",
+	Aring:"Latinsko veliko slovo A s krugom iznad\nLatinsko veliko slovo A s krugom",
 	AElig:"Latinsko veliko slovo AE\nLatinsko veliko spojeno slovo AE",
-	Ccedil:"Latinsko veliko slovo C sa sedijom",
+	Ccedil:"Latinsko veliko slovo C sa sediljom",
 	Egrave:"Latinsko veliko slovo E s grav akcentom",
 	Eacute:"Latinsko veliko slovo E s akutnim akcentom",
-	Ecirc:"Latinsko veliko slovo E sa cirkumfleksom",
-	Euml:"Latinsko veliko slovo E s dijarezom",
+	Ecirc:"Latinsko veliko slovo E s cirkumfleksom",
+	Euml:"Latinsko veliko slovo E s dijerezom",
 	Igrave:"Latinsko veliko slovo I s grav akcentom",
 	Iacute:"Latinsko veliko slovo I s akutnim akcentom",
-	Icirc:"Latinsko veliko slovo I sa cirkumfleksom",
-	Iuml:"Latinsko veliko slovo I s dijarezom",
+	Icirc:"Latinsko veliko slovo I s cirkumfleksom",
+	Iuml:"Latinsko veliko slovo I s dijerezom",
 	ETH:"Latinsko veliko slovo ETH",
 	Ntilde:"Latinsko veliko slovo N s tildom",
 	Ograve:"Latinsko veliko slovo O s grav akcentom",
 	Oacute:"Latinsko veliko slovo O s akutnim akcentom",
-	Ocirc:"Latinsko veliko slovo O sa cirkumfleksom",
+	Ocirc:"Latinsko veliko slovo O s cirkumfleksom",
 	Otilde:"Latinsko veliko slovo O s tildom",
-	Ouml:"Latinsko veliko slovo O s dijarezom",
+	Ouml:"Latinsko veliko slovo O s dijerezom",
 	times:"znak množenja",
-	Oslash:"Latinsko veliko slovo O s kosom crtom\nLatinsko veliko slovo O kosa crta",
+	Oslash:"Latinsko veliko slovo O s crtom\nLatinsko veliko slovo O s kosom crtom",
 	Ugrave:"Latinsko veliko slovo U s grav akcentom",
 	Uacute:"Latinsko veliko slovo U s akutnim akcentom",
-	Ucirc:"Latinsko veliko slovo U sa cirkumfleksom",
-	Uuml:"Latinsko veliko slovo U s dijarezom",
+	Ucirc:"Latinsko veliko slovo U s cirkumfleksom",
+	Uuml:"Latinsko veliko slovo U s dijerezom",
 	Yacute:"Latinsko veliko slovo Y s akutnim akcentom",
 	THORN:"Latinsko veliko slovo THORN",
 	szlig:"Latinsko malo slovo oštro s\ness-zed",
-	agrave:"Latinsko malo slovo a s grav akcentom\nLatinsko malo slovo a grav akcent",
+	agrave:"Latinsko malo slovo a s grav akcentom\nLatinsko malo slovo a s grav akcentom",
 	aacute:"Latinsko malo slovo a s akutnim akcentom",
-	acirc:"Latinsko malo slovo a sa cirkumfleksom",
+	acirc:"Latinsko malo slovo a s cirkumfleksom",
 	atilde:"Latinsko malo slovo a s tildom",
-	auml:"Latinsko malo slovo a s dijarezom",
-	aring:"Latinsko malo slovo a s prstenom iznad\nLatinsko malo slovo a prsten iznad",
+	auml:"Latinsko malo slovo a s dijerezom",
+	aring:"Latinsko malo slovo a s krugom iznad\nLatinsko malo slovo a s krugom",
 	aelig:"Latinsko malo slovo ae\nLatinsko malo spojeno slovo ae",
-	ccedil:"Latinsko malo slovo c sa sedijom",
+	ccedil:"Latinsko malo slovo c sa sediljom",
 	egrave:"Latinsko malo slovo e s grav akcentom",
 	eacute:"Latinsko malo slovo e s akutnim akcentom",
-	ecirc:"Latinsko malo slovo e sa cirkumfleksom",
-	euml:"Latinsko malo slovo e s dijarezom",
+	ecirc:"Latinsko malo slovo e s cirkumfleksom",
+	euml:"Latinsko malo slovo e s dijerezom",
 	igrave:"Latinsko malo slovo i s grav akcentom",
 	iacute:"Latinsko malo slovo i s akutnim akcentom",
-	icirc:"Latinsko malo slovo i sa cirkumfleksom",
-	iuml:"Latinsko malo slovo i s dijarezom",
+	icirc:"Latinsko malo slovo i s cirkumfleksom",
+	iuml:"Latinsko malo slovo i s dijerezom",
 	eth:"Latinsko malo slovo eth",
 	ntilde:"Latinsko malo slovo n s tildom",
 	ograve:"Latinsko malo slovo o s grav akcentom",
 	oacute:"Latinsko malo slovo o s akutnim akcentom",
-	ocirc:"Latinsko malo slovo o sa cirkumfleksom",
+	ocirc:"Latinsko malo slovo o s cirkumfleksom",
 	otilde:"Latinsko malo slovo o s tildom",
-	ouml:"Latinsko malo slovo o s dijarezom",
+	ouml:"Latinsko malo slovo o s dijerezom",
 	divide:"znak dijeljenja",
-	oslash:"Latinsko malo slovo o s kosom crtom\nLatinsko malo slovo o kosa crta",
+	oslash:"Latinsko malo slovo o s crtom\nLatinsko malo slovo o s kosom crtom",
 	ugrave:"Latinsko malo slovo u s grav akcentom",
 	uacute:"Latinsko malo slovo u s akutnim akcentom",
-	ucirc:"Latinsko malo slovo u sa cirkumfleksom",
-	uuml:"Latinsko malo slovo u s dijarezom",
+	ucirc:"Latinsko malo slovo u s cirkumfleksom",
+	uuml:"Latinsko malo slovo u s dijerezom",
 	yacute:"Latinsko malo slovo y s akutnim akcentom",
 	thorn:"Latinsko malo slovo thorn",
-	yuml:"Latinsko malo slovo y s dijarezom",
+	yuml:"Latinsko malo slovo y s dijerezom",
 // Greek Characters and Symbols
 	fnof:"Latinsko malo f s kvačicom\nfunkcija\nflorin",
 	Alpha:"Grčko veliko slovo alfa",
@@ -155,23 +155,23 @@ define(
 	thetasym:"Grčko malo slovo simbol theta",
 	upsih:"Grčki ipsilon sa simbolom kvačice",
 	piv:"Grčki simbol pi",
-	bull:"grafička oznaka\ncrni mali krug",
-	hellip:"vodoravne tri točkice\ntri točkice",
-	prime:"prost\nminute\nstopalo",
-	Prime:"dvostruko prost\nsekunde\ninči",
-	oline:"nadvučeno\nprored crtice iznad",
+	bull:"grafička oznaka\nmali crni krug",
+	hellip:"vodoravne tri točke\ntri točke na kraju",
+	prime:"prime\nminute\nstope",
+	Prime:"dvostruki prime\nsekunde\ninči",
+	oline:"crta iznad\nprored crte iznad",
 	frasl:"kosa crta razlomka",
-	weierp:"skriptno veliko slovo P\nnadskup\nWeierstrass p",
-	image:"veliko slovo I gotskog pisma\nzamišljeni dio",
-	real:"veliko slovo R gotskog pisma\nsimbol stvarnog dijela",
+	weierp:"skriptno veliko P\nnadskup\nWeierstrass p",
+	image:"Veliko I gotičkog pisma\nimaginaran dio",
+	real:"Veliko R gotičkog pisma\nsimbol realnog dijela",
 	trade:"znak zaštitnog znaka",
-	alefsym:"simbol alef\nprvi transfinitni prost broj",
+	alefsym:"simbol alef\nprvi transfinitan kardinalni broj",
 	larr:"strelica ulijevo",
 	uarr:"strelica prema gore",
 	rarr:"strelica udesno",
 	darr:"strelica prema dolje",
 	harr:"strelica lijevo desno",
-	crarr:"strelica prema dolje s lijevim kutom\noznaka kraja reda",
+	crarr:"strelica prema dolje koja zavija lijevo\noznaka kraja retka",
 	lArr:"dvostruka strelica ulijevo",
 	uArr:"dvostruka strelica prema gore",
 	rArr:"dvostruka strelica udesno",
@@ -180,27 +180,27 @@ define(
 	forall:"za sve",
 	part:"djelomični diferencijal",
 	exist:"tamo postoji",
-	empty:"prazan skup\nnull skup\ndijametar",
+	empty:"prazan skup\nnull skup\npromjer",
 	nabla:"nabla\npovratna razlika",
 	isin:"element od",
 	notin:"nije element od",
 	ni:"sadrži kao član",
-	prod:"n-ski proizvod\nsnak proizvoda",
-	sum:"n-ski zbroj",
+	prod:"n-arni produkt\nznak produkta",
+	sum:"n-arni zbroj",
 	minus:"znak minusa",
 	lowast:"operator zvjezdica",
-	radic:"kvadratni korijen\nznak korijena",
+	radic:"kvadratni korijen\noznaka korijena",
 	prop:"proporcionalan s",
 	infin:"beskonačno",
 	ang:"kut",
-	and:"logički i\nukliješten",
-	or:"logički ili\nv",
-	cap:"presjek\nkapa",
-	cup:"unija\nkup","int":"integral",
+	and:"logičko i\nwedge",
+	or:"logičko ili\nvee",
+	cap:"presjek\ncap",
+	cup:"unija\ncup","int":"integral",
 	there4:"prema tome",
-	sim:"operator tilda\nmijenja se s\nsličan",
+	sim:"operator tilde\nvarira s\nslično",
 	cong:"približno jednako",
-	asymp:"pretežno jednako\nasimptotski",
+	asymp:"približno jednako\nasimptotski",
 	ne:"nije jednako",
 	equiv:"identično",
 	le:"manje ili jednako",
@@ -209,10 +209,10 @@ define(
 	sup:"nadskup",
 	nsub:"nije podskup",
 	sube:"podskup ili jednak",
-	supe:"nadskup oli jednak",
+	supe:"nadskup ili jednak",
 	oplus:"zaokruženi plus\nizravna suma",
-	otimes:"zaokružen znak umnoška\numnožak vektora",
-	perp:"čvao prema gore\nortogonalan\nvertikalan",
+	otimes:"zaokruženo puta\nvektorski produkt",
+	perp:"čavlić prema gore\nortogonalno na\nokomito",
 	sdot:"operator točka",
 	lceil:"lijevi stropni\nAPL lijevi stropni",
 	rceil:"desni stropni",
@@ -223,13 +223,13 @@ define(
 	loz:"dijamant",
 	spades:"boja crni pik",
 	clubs:"boja crni tref\ndjetelina",
-	hearts:"boja crni herc\nsrce",
+	hearts:"boja crno srce\nvalentine",
 	diams:"boja crni karo",
 	OElig:"Latinsko veliko spojeno slovo OE",
 	oelig:"Latinsko malo spojeno slovo oe",
 	Scaron:"Latinsko veliko slovo S s invertiranim cirkumfleksom",
 	scaron:"Latinsko malo slovo s s invertiranim cirkumfleksom",
-	Yuml:"Latinsko veliko slovo Y s dijarezom",
+	Yuml:"Latinsko veliko slovo Y s dijerezom",
 	circ:"cirkumfleks akcent slova modifikatora",
 	tilde:"mala tilda",
 	ensp:"en prostor",
diff --git a/dojox/editor/plugins/nls/hu/AutoSave.js b/dojox/editor/plugins/nls/hu/AutoSave.js
index 820d04c..ee06847 100644
--- a/dojox/editor/plugins/nls/hu/AutoSave.js
+++ b/dojox/editor/plugins/nls/hu/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Mentés",
 	"saveSettingLabelOn": "Automatikus mentés időközének beállítása...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Mentés: ${0}",
 	"saveMessageFail": "Sikertelen mentés: ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/Blockquote.js b/dojox/editor/plugins/nls/hu/Blockquote.js
index a6b3111..1a70d53 100644
--- a/dojox/editor/plugins/nls/hu/Blockquote.js
+++ b/dojox/editor/plugins/nls/hu/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Idézet"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/Breadcrumb.js b/dojox/editor/plugins/nls/hu/Breadcrumb.js
index fc306ed..34b8cc9 100644
--- a/dojox/editor/plugins/nls/hu/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/hu/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} műveletek",
 	"selectContents": "Tartalom kiválasztása",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Kurzor mozgatása az elejére",
 	"moveEnd": "Kurzor mozgatása a végére"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/CollapsibleToolbar.js b/dojox/editor/plugins/nls/hu/CollapsibleToolbar.js
index 7f84883..4ffb33c 100644
--- a/dojox/editor/plugins/nls/hu/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/hu/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Szerkesztő eszköztár összezárása",
 	"expand": "Szerkesztő eszköztár kibontása"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/FindReplace.js b/dojox/editor/plugins/nls/hu/FindReplace.js
index c146db0..5adc3c1 100644
--- a/dojox/editor/plugins/nls/hu/FindReplace.js
+++ b/dojox/editor/plugins/nls/hu/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Keresés:",
 	"findTooltip": "Adja meg a keresett szöveget",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "találat",
 	"eofDialogTextReplace": "cserélve"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/InsertAnchor.js b/dojox/editor/plugins/nls/hu/InsertAnchor.js
index 242fe0b..1a28c0f 100644
--- a/dojox/editor/plugins/nls/hu/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/hu/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Horgony beszúrása",
 	title: "Horgony tulajdonságai",
@@ -8,6 +7,4 @@ define(
 	set: "Beállítás",
 	cancel: "Mégse"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/InsertEntity.js b/dojox/editor/plugins/nls/hu/InsertEntity.js
index 8744bbd..8099636 100644
--- a/dojox/editor/plugins/nls/hu/InsertEntity.js
+++ b/dojox/editor/plugins/nls/hu/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Szimbólum beszúrása"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/LocalImage.js b/dojox/editor/plugins/nls/hu/LocalImage.js
index 4e0f2cb..d692040 100644
--- a/dojox/editor/plugins/nls/hu/LocalImage.js
+++ b/dojox/editor/plugins/nls/hu/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Kép beszúrása",
 	url: "Kép",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Adja meg a kép URL címét",
 	prePopuTextBrowse: " vagy tallózással válasszon ki egy helyi fájlt."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/PageBreak.js b/dojox/editor/plugins/nls/hu/PageBreak.js
index 12b4b38..16c7e6f 100644
--- a/dojox/editor/plugins/nls/hu/PageBreak.js
+++ b/dojox/editor/plugins/nls/hu/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Oldaltörés"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/PasteFromWord.js b/dojox/editor/plugins/nls/hu/PasteFromWord.js
index a515fec..cbfb138 100644
--- a/dojox/editor/plugins/nls/hu/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/hu/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Beillesztés Word alkalmazásból",
-	"paste": "Beillesztés",
-	"cancel": "Mégse",
 	"instructions": "Illessze be a Word alkalmazás tartalmát az alábbi szövegmezőbe. Ha elégedett a beszúrandó tartalommal, akkor nyomja meg a beillesztés gombot. Szöveg beszúrásának megszakításához nyomja meg a mégse gombot."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/Preview.js b/dojox/editor/plugins/nls/hu/Preview.js
index 0d05ae2..0d690bb 100644
--- a/dojox/editor/plugins/nls/hu/Preview.js
+++ b/dojox/editor/plugins/nls/hu/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Előzetes"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/Save.js b/dojox/editor/plugins/nls/hu/Save.js
index 07a7ffc..9956739 100644
--- a/dojox/editor/plugins/nls/hu/Save.js
+++ b/dojox/editor/plugins/nls/hu/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Mentés"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/ShowBlockNodes.js b/dojox/editor/plugins/nls/hu/ShowBlockNodes.js
index 2f1d299..cffc7c3 100644
--- a/dojox/editor/plugins/nls/hu/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/hu/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "HTML blokk elemek megjelenítése"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/Smiley.js b/dojox/editor/plugins/nls/hu/Smiley.js
index cff7a2a..6479c36 100644
--- a/dojox/editor/plugins/nls/hu/Smiley.js
+++ b/dojox/editor/plugins/nls/hu/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Hangulatjel beszúrása",
 	emoticonSmile: "mosoly",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "sírás",
 	emoticonHappy: "boldog"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/SpellCheck.js b/dojox/editor/plugins/nls/hu/SpellCheck.js
index bd1d7ed..eb2598e 100644
--- a/dojox/editor/plugins/nls/hu/SpellCheck.js
+++ b/dojox/editor/plugins/nls/hu/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Kötegelt helyesírás-ellenőrzés",
 	unfound: "Nem található",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Összes hasonlót kihagyja",
 	iMsg: "Nincsenek helyesírási javaslatok"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/TableDialog.js b/dojox/editor/plugins/nls/hu/TableDialog.js
index d736041..7894d14 100644
--- a/dojox/editor/plugins/nls/hu/TableDialog.js
+++ b/dojox/editor/plugins/nls/hu/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Táblázat beszúrása",
 	modifyTableTitle: "Táblázat módosítása",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Táblázat szélessége:",
 	backgroundColor: "Háttérszín:",
 	borderColor: "Szegélyszín:",
-	borderThickness: "Szegély vastagsága",
+	borderThickness: "Szegélyvastagság:",
 	percent: "százalék",
 	pixels: "képpont",
 	"default": "alapértelmezett",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Beállítás", // translated elsewhere?
 	buttonInsert: "Beszúrás",
 	buttonCancel: "Mégse",
-
 	selectTableLabel: "Táblázat kijelölése",
 	insertTableRowBeforeLabel: "Sor hozzáadása előtte",
 	insertTableRowAfterLabel: "Sor hozzáadása utána",
 	insertTableColumnBeforeLabel: "Oszlop hozzáadása előtte",
 	insertTableColumnAfterLabel: "Oszlop hozzáadása utána",
 	deleteTableRowLabel: "Sor törlése",
-	deleteTableColumnLabel: "Oszlop törlése"
+	deleteTableColumnLabel: "Oszlop törlése",
+	colorTableCellTitle: "Háttérszín táblázatcella",
+	tableContextMenuTitle: "Táblázat előugró menü"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/TextColor.js b/dojox/editor/plugins/nls/hu/TextColor.js
index 9e7f122..b877b31 100644
--- a/dojox/editor/plugins/nls/hu/TextColor.js
+++ b/dojox/editor/plugins/nls/hu/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Beállítás",
 	"cancelButtonText": "Mégse"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/hu/latinEntities.js b/dojox/editor/plugins/nls/hu/latinEntities.js
index 536051c..c363041 100644
--- a/dojox/editor/plugins/nls/hu/latinEntities.js
+++ b/dojox/editor/plugins/nls/hu/latinEntities.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"fordított felkiáltójel",
 	cent:"cent jel",
@@ -14,29 +13,29 @@ define(
 	yen:"jen jel\nyuan jel",
 	brvbar:"megszakított vonal\nmegszakított függőleges vonal",
 	sect:"paragrafusjel",
-	uml:"dupla ékezet\numlaut",
+	uml:"tréma\nkalapos tréma",
 	copy:"copyright jel",
 	ordf:"nőnemű sorszámnév jelzése a felső indexben",
 	laquo:"balra mutató dupla hegyes idézőjel\nbalra mutató belső idézőjel",
 	not:"nem jel",
 	shy:"lágy kötőjel\nfeltételes kötőjel",
 	reg:"védjegy jel\nbejegyzett védjegy jel",
-	macr:"föléhúzás jel\nAPL felülhúzás",
+	macr:"ékezet\nkalapos ékezet\nfelső vonal\nAPL felső csík",
 	deg:"fok jel",
 	plusmn:"plus-mínusz jel\nplusz-vagy-mínusz jel",
-	sup2:"2 felső indexben\nfelső indexbe írt kettes számjegy\nnégyzetre emelés",
-	sup3:"3 felső indexben\nfelső indexbe írt hármas számjegy\nköbre emelés",
+	sup2:"kettő a felső indexben\nfelső indexbe írt kettes számjegy\nnégyzetre emelt",
+	sup3:"három a felső indexben\nfelső indexbe írt hármas számjegy\nharmadik hatványra emelt",
 	acute:"hegyes ékezet\nkalapos ékezet",
 	micro:"mikro jel",
 	para:"sorvége jel\nbekezdés jel",
-	middot:"középső pont\nGregorián vessző\nGörög középső pont",
-	cedil:"cedill\nbalra hajló alsó hurok",
+	middot:"középső pont\nGrúz vessző\nGörög középső pont",
+	cedil:"cédille\nkalapos cédille",
 	sup1:"1 a felső indexben\nfelső indexbe írt egyes számjegy",
 	ordm:"hímnemű sorszámnév jelzése a felső indexben",
 	raquo:"jobbra mutató dupla hegyes idézőjel\njobbra mutató belső idézőjel",
-	frac14:"közönséges egynegyed tört\nnegyed",
-	frac12:"közönséges fél tört\nfél",
-	frac34:"közönséges háromnegyed tört\nháromnegyed",
+	frac14:"közönséges egynegyed\ntörtnegyed",
+	frac12:"közönséges fél\ntörtfél",
+	frac34:"közönséges háromnegyed\ntörtháromnegyed",
 	iquest:"fordított kérdőjel\nmegfordított kérdőjel",
 	Agrave:"Latin nagy A betű tompa ékezettel\nTompa ékezetes latin nagy A betű",
 	Aacute:"Latin nagy A betű éles ékezettel",
@@ -69,7 +68,7 @@ define(
 	Uuml:"Latin kétpontos nagy U betű",
 	Yacute:"Latin nagy Y betű éles ékezettel",
 	THORN:"Latin nagy THORN betű",
-	szlig:"Latin kis sharfes s\neszett",
+	szlig:"Latin kis sharfes\nseszett",
 	agrave:"Latin kis a betű tompa ékezettel\nTompa ékezetes latin kis a betű",
 	aacute:"Latin kis a betű éles ékezettel",
 	acirc:"Latin kalapos kis a betű",
@@ -102,9 +101,8 @@ define(
 	yacute:"Latin kis y éles ékezettel",
 	thorn:"Latin kis thorn betű",
 	yuml:"Latin kétpontos kis y",
-
 // Greek Characters and Symbols
-	fnof:"Latin kis f horoggal\nfüggvény\nforint",
+	fnof:"Latin kis f horoggal\nfüggvényforint",
 	Alpha:"Görög nagy alfa betű",
 	Beta:"Görög nagy béta betű",
 	Gamma:"Görög nagy gamma betű",
@@ -157,23 +155,23 @@ define(
 	thetasym:"Görög kis théta betű szimbólum",
 	upsih:"Görög üpszilon horog szimbólummal",
 	piv:"Görög pí szimbólum",
-	bull:"pont felsorolásjel\nkis fekete kör",
-	hellip:"vízszintes hármaspont\nbevezető hármas pont",
-	prime:"szimpla egyenes idézőjel\nperc\nláb",
-	Prime:"dupla egyenes idézőjel\nmásodperc\nhüvelyk",
-	oline:"felső vonal\nfelülvonás",
+	bull:"felsorolásjel\nkis fekete kör",
+	hellip:"vízszintes kihagyás\nbevezető hármas pont",
+	prime:"prím\nperc\nláb",
+	Prime:"dupla pontosságú prím\nmásodperc\nhüvelyk",
+	oline:"felsővonal\nkalapos felső vonal",
 	frasl:"tört osztásjel",
-	weierp:"írott nagy P\nhatványhalmaz\nWeierstrass p",
+	weierp:"indexbe írt nagy P\nhatványkitevő\nWeierstrass p",
 	image:"megtört nagy I\nképzetes (imaginárius) rész",
 	real:"megtört nagy R\nvalós rész szimbólum",
 	trade:"védjegy jel",
-	alefsym:"alef szimbólum\nelső transzfinit pozitív egész szám",
+	alefsym:"álef jel\nelső kvázi végtelen pozitív egész",
 	larr:"balra mutató nyíl",
 	uarr:"felfelé mutató nyíl",
 	rarr:"jobbra mutató nyíl",
 	darr:"lefelé mutató nyíl",
 	harr:"balra-jobbra mutató nyíl",
-	crarr:"lefelé mutató nyíl bal oldalon sarokkal\nsoremelés",
+	crarr:"lefelé mutató nyíl bal oldalon sarokkal\nkocsi vissza",
 	lArr:"balra mutató dupla nyíl",
 	uArr:"felfelé mutató dupla nyíl",
 	rArr:"jobbra mutató dupla nyíl",
@@ -183,11 +181,11 @@ define(
 	part:"részleges differenciál",
 	exist:"létezik",
 	empty:"üres halmaz\nnull halmaz\nátmérő",
-	nabla:"nabla\nfordított különbség",
+	nabla:"nabla\nvisszamutató eltérés",
 	isin:"eleme",
 	notin:"nem eleme",
 	ni:"tagként tartalmazza",
-	prod:"n-tagú Descartes szorzat\nszorzatjel",
+	prod:"n-tagú termék\ntermék jel",
 	sum:"n-tagú összegzés",
 	minus:"mínusz jel",
 	lowast:"csillag operátor",
@@ -195,12 +193,12 @@ define(
 	prop:"arányos",
 	infin:"végtelen",
 	ang:"szög",
-	and:"logikai és\nék",
-	or:"logikai vagy\nv-alak",
-	cap:"metszet",
-	cup:"unió","int":"integrál",
+	and:"logikai és\nfordított V",
+	or:"logikai vagy\nV",
+	cap:"metszet\nkalap",
+	cup:"unió\nU jel","int":"integrál",
 	there4:"ezért",
-	sim:"hullám operátor\nváltakozik\nhasonló",
+	sim:"hullám operátor\negyütt változik\nhasonló",
 	cong:"megközelítőleg egyenlő",
 	asymp:"majdnem egyenlő\naszimptotikus",
 	ne:"nem egyenlő",
@@ -212,13 +210,13 @@ define(
 	nsub:"nem részhalmaza",
 	sube:"részhalmaza vagy egyenlő",
 	supe:"bővített halmaza vagy egyenlő",
-	oplus:"bekarikázott plusz jel\nközvetlen összeg",
-	otimes:"bekarikázott x\nvektor szorzat",
-	perp:"merőleges\nortogonális",
+	oplus:"plusz jel körben\ndirekt összegzés",
+	otimes:"szorzás jel körben\nvektoriális szorzat",
+	perp:"falsum\nortogonális\nmerőleges",
 	sdot:"pont operátor",
-	lceil:"bal szögletes zárójel felső sarok\nAPL felső keret",
+	lceil:"jobb szögletes zárójel felső sarok\nAPL upstile",
 	rceil:"jobb szögletes zárójel felső sarok",
-	lfloor:"bal szögletes zárójel alsó sarok\nAPL alsó keret",
+	lfloor:"jobb szögletes zárójel alsó sarok\nAPL downstile",
 	rfloor:"jobb szögletes zárójel alsó sarok",
 	lang:"balra mutató hegyes zárójel",
 	rang:"jobbra mutató hegyes zárójel",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"szimpla jobbra mutató hegyes idézőjel",
 	euro:"euro jel"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/AutoSave.js b/dojox/editor/plugins/nls/it/AutoSave.js
index dcc1292..622bc16 100644
--- a/dojox/editor/plugins/nls/it/AutoSave.js
+++ b/dojox/editor/plugins/nls/it/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Salva",
 	"saveSettingLabelOn": "Imposta intervallo di salvataggio automatico...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Salvato alle ${0}",
 	"saveMessageFail": "Salvataggio alle ${0} non riuscito"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/Blockquote.js b/dojox/editor/plugins/nls/it/Blockquote.js
index e54a9ba..bed9ca8 100644
--- a/dojox/editor/plugins/nls/it/Blockquote.js
+++ b/dojox/editor/plugins/nls/it/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Blockquote"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/Breadcrumb.js b/dojox/editor/plugins/nls/it/Breadcrumb.js
index 862df3f..6d6992a 100644
--- a/dojox/editor/plugins/nls/it/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/it/Breadcrumb.js
@@ -1,14 +1,11 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "Azioni ${nodeName}",
-	"selectContents": "Seleziona contenuto",
+	"selectContents": "Seleziona contenuti",
 	"selectElement": "Seleziona elemento",
 	"deleteElement": "Elimina elemento",
-	"deleteContents": "Elimina contenuto",
-	"moveStart": "Sposta il cursore per iniziare",
-	"moveEnd": "Sposta il cursore per terminare"
+	"deleteContents": "Elimina contenuti",
+	"moveStart": "Sposta cursore all'inizio",
+	"moveEnd": "Sposta cursore alla fine"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/CollapsibleToolbar.js b/dojox/editor/plugins/nls/it/CollapsibleToolbar.js
index 5daf5c6..9ee8efc 100644
--- a/dojox/editor/plugins/nls/it/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/it/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"collapse": "Comprimi la barra degli strumenti dell'editor",
-	"expand": "Espandi la barra degli strumenti dell'editor"
+	"collapse": "Comprimi barra degli strumenti dell'editor",
+	"expand": "Espandi barra degli strumenti dell'editor"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/FindReplace.js b/dojox/editor/plugins/nls/it/FindReplace.js
index 4d1320c..136986b 100644
--- a/dojox/editor/plugins/nls/it/FindReplace.js
+++ b/dojox/editor/plugins/nls/it/FindReplace.js
@@ -1,26 +1,23 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Trova:",
-	"findTooltip": "Immettere il testo da trovare",
+	"findTooltip": "Immettere il testo da ricercare",
 	"replaceLabel": "Sostituisci con:",
-	"replaceTooltip": "Immettere il testo sostitutivo",
+	"replaceTooltip": "Immettere il testo con cui sostituire",
 	"findReplace": "Trova e sostituisci",
-	"matchCase": "Maiuscole/minuscole",
-	"matchCaseTooltip": "Maiuscole/minuscole",
+	"matchCase": "Corrispondenza maiuscolo/minuscolo",
+	"matchCaseTooltip": "Corrispondenza maiuscolo/minuscolo",
 	"backwards": "Indietro",
-	"backwardsTooltip": "Cerca testo indietro",
-	"replaceAllButton": "Sostituisci tutto",
+	"backwardsTooltip": "Ricercare il testo all'indietro",
+	"replaceAllButton": "Sostituisci tutti",
 	"replaceAllButtonTooltip": "Sostituisci tutto il testo",
 	"findButton": "Trova",
 	"findButtonTooltip": "Trova il testo",
 	"replaceButton": "Sostituisci",
 	"replaceButtonTooltip": "Sostituisci il testo",
-	"replaceDialogText": "${0} ricorrenze sostituite.",
-	"eofDialogText": "Ultima ricorrenza ${0}",
+	"replaceDialogText": "Sostituite ${0} ricorrenze.",
+	"eofDialogText": "Ultime ${0} ricorrenze",
 	"eofDialogTextFind": "trovato",
 	"eofDialogTextReplace": "sostituito"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/InsertAnchor.js b/dojox/editor/plugins/nls/it/InsertAnchor.js
index ac095b2..0550a8f 100644
--- a/dojox/editor/plugins/nls/it/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/it/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Inserisci ancoraggio",
 	title: "Proprietà ancoraggio",
@@ -8,6 +7,4 @@ define(
 	set: "Imposta",
 	cancel: "Annulla"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/InsertEntity.js b/dojox/editor/plugins/nls/it/InsertEntity.js
index 32e3afc..4a75792 100644
--- a/dojox/editor/plugins/nls/it/InsertEntity.js
+++ b/dojox/editor/plugins/nls/it/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Inserisci simbolo"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/LocalImage.js b/dojox/editor/plugins/nls/it/LocalImage.js
index 664bf37..80383b2 100644
--- a/dojox/editor/plugins/nls/it/LocalImage.js
+++ b/dojox/editor/plugins/nls/it/LocalImage.js
@@ -1,15 +1,12 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Inserisci immagine",
 	url: "Immagine",
 	browse: "Sfoglia...",
 	text: "Descrizione",
 	set: "Inserisci",
-	invalidMessage: "Tipo di file immagine non valido",
+	invalidMessage: "Tipo file immagine non valido",
 	prePopuTextUrl: "Immettere un URL immagine",
-	prePopuTextBrowse: " o individuare un file locale."
+	prePopuTextBrowse: " o selezionare un file locale."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/PageBreak.js b/dojox/editor/plugins/nls/it/PageBreak.js
index 277463f..f1f10d6 100644
--- a/dojox/editor/plugins/nls/it/PageBreak.js
+++ b/dojox/editor/plugins/nls/it/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
-	"pageBreak": "Interruzione di pagina"
+	"pageBreak": "Interruzione pagina"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/PasteFromWord.js b/dojox/editor/plugins/nls/it/PasteFromWord.js
index 0aff219..455a459 100644
--- a/dojox/editor/plugins/nls/it/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/it/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Incolla da Word",
-	"paste": "Incolla",
-	"cancel": "Annulla",
-	"instructions": "Incolla il contenuto da Word nella casella di testo sottostante. Al termine dell'inserimento del contenuto, premere il pulsante Incolla. Per annullare l'inserimento del testo, premere il pulsante Annulla."
+	"instructions": "Incollare i contenuti da Word nella seguente casella di testo. Quando si è deciso quali contenuti inserire, fare clic sul pulsante incolla. Per interrompere l'inserimento del testo premere il pulsante annulla."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/Preview.js b/dojox/editor/plugins/nls/it/Preview.js
index 6415dfd..4ad087b 100644
--- a/dojox/editor/plugins/nls/it/Preview.js
+++ b/dojox/editor/plugins/nls/it/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Anteprima"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/Save.js b/dojox/editor/plugins/nls/it/Save.js
index dd9f6aa..c9415c7 100644
--- a/dojox/editor/plugins/nls/it/Save.js
+++ b/dojox/editor/plugins/nls/it/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Salva"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/ShowBlockNodes.js b/dojox/editor/plugins/nls/it/ShowBlockNodes.js
index 42dfb82..433bc4a 100644
--- a/dojox/editor/plugins/nls/it/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/it/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Mostra elementi blocco HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/Smiley.js b/dojox/editor/plugins/nls/it/Smiley.js
index b73a8a8..05cb47c 100644
--- a/dojox/editor/plugins/nls/it/Smiley.js
+++ b/dojox/editor/plugins/nls/it/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Inserisci emoticon",
 	emoticonSmile: "sorriso",
@@ -16,12 +15,10 @@ define(
 	emoticonOops: "ops",
 	emoticonTongue: "linguaccia",
 	emoticonIdea: "idea",
-	emoticonYes: "yes",
+	emoticonYes: "sì",
 	emoticonNo: "no",
 	emoticonAngel: "angelo",
 	emoticonCrying: "in lacrime",
 	emoticonHappy: "felice"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/SpellCheck.js b/dojox/editor/plugins/nls/it/SpellCheck.js
index b37311d..77d747c 100644
--- a/dojox/editor/plugins/nls/it/SpellCheck.js
+++ b/dojox/editor/plugins/nls/it/SpellCheck.js
@@ -1,21 +1,18 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Controllo ortografico batch",
 	unfound: "Non trovato",
 	skip: "Ignora",
 	skipAll: "Ignora tutto",
-	toDic: "Aggiungi al dizionario",
+	toDic: "Aggiungi a dizionario",
 	suggestions: "Suggerimenti",
 	replace: "Sostituisci",
 	replaceWith: "Sostituisci con",
-	replaceAll: "Sostituisci tutto",
+	replaceAll: "Sostituisci tutti",
 	cancel: "Annulla",
-	msg: "Nessun errore di ortografia trovato",
-	iSkip: "Ignora",
-	iSkipAll: "Ignora tutto",
+	msg: "Nessun errore ortografico",
+	iSkip: "Ignora questo",
+	iSkipAll: "Ignora tutti quelli uguali a questo",
 	iMsg: "Nessun suggerimento ortografico"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/TableDialog.js b/dojox/editor/plugins/nls/it/TableDialog.js
index 42859cd..de4c61e 100644
--- a/dojox/editor/plugins/nls/it/TableDialog.js
+++ b/dojox/editor/plugins/nls/it/TableDialog.js
@@ -1,18 +1,17 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Inserisci tabella",
 	modifyTableTitle: "Modifica tabella",
 	rows: "Righe:",
 	columns: "Colonne:",
 	align: "Allinea:",
-	cellPadding: "Padding celle:",
+	cellPadding: "Riempimento cella:",
 	cellSpacing: "Spaziatura celle:",
-	tableWidth: "Larghezza tabelle:",
-	backgroundColor: "Colore di sfondo:",
-	borderColor: "Colore bordi:",
-	borderThickness: "Spessore bordi",
-	percent: "percentuale",
+	tableWidth: "Larghezza tabella:",
+	backgroundColor: "Colore sfondo:",
+	borderColor: "Colore bordo:",
+	borderThickness: "Spessore bordo:",
+	percent: "percento",
 	pixels: "pixel",
 	"default": "predefinito",
 	left: "sinistra",
@@ -21,16 +20,14 @@ define(
 	buttonSet: "Imposta", // translated elsewhere?
 	buttonInsert: "Inserisci",
 	buttonCancel: "Annulla",
-
 	selectTableLabel: "Seleziona tabella",
-	insertTableRowBeforeLabel: "Aggiungi riga prima",
-	insertTableRowAfterLabel: "Aggiungi riga dopo",
+	insertTableRowBeforeLabel: "Inserisci riga prima",
+	insertTableRowAfterLabel: "Inserisci riga dopo",
 	insertTableColumnBeforeLabel: "Aggiungi colonna prima",
 	insertTableColumnAfterLabel: "Aggiungi colonna dopo",
 	deleteTableRowLabel: "Elimina riga",
-	deleteTableColumnLabel: "Elimina colonna"
+	deleteTableColumnLabel: "Elimina colonna",
+	colorTableCellTitle: "Cella tabella colore sfondo",
+	tableContextMenuTitle: "Menu di contesto tabella"
 })
-	
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/TextColor.js b/dojox/editor/plugins/nls/it/TextColor.js
index 1b9c6d7..b731ad7 100644
--- a/dojox/editor/plugins/nls/it/TextColor.js
+++ b/dojox/editor/plugins/nls/it/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Imposta",
 	"cancelButtonText": "Annulla"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/it/latinEntities.js b/dojox/editor/plugins/nls/it/latinEntities.js
index 1737571..3bb677f 100644
--- a/dojox/editor/plugins/nls/it/latinEntities.js
+++ b/dojox/editor/plugins/nls/it/latinEntities.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"punto esclamativo capovolto",
 	cent:"simbolo del centesimo",
@@ -33,7 +32,7 @@ define(
 	cedil:"cediglia\ncediglia con spazio",
 	sup1:"esponente uno\nnumero uno in esponente",
 	ordm:"indicatore ordinale maschile",
-	raquo:"virgolette doppie angolari indicanti a destra\n guillemet indicante a destra",
+	raquo:"virgolette doppie angolari indicanti a destra\nguillemet indicante a destra",
 	frac14:"frazione semplice un quarto\nfrazione un quarto",
 	frac12:"frazione semplice un mezzo\nfrazione un mezzo",
 	frac34:"frazione semplice tre quarti\nfrazione tre quarti",
@@ -69,7 +68,7 @@ define(
 	Uuml:"lettera latina U maiuscola con dieresi",
 	Yacute:"lettera latina Y maiuscola con accento acuto",
 	THORN:"lettera latina THORN maiuscola",
-	szlig:"lettera latina s minuscola sonora\nesse-zeta",
+	szlig:"lettera latina s minuscola sonora\esse-zeta",
 	agrave:"lettera latina a minuscola con accento grave\nlettera latina a minuscola grave",
 	aacute:"lettera latina a minuscola con accento acuto",
 	acirc:"lettera latina a minuscola con accento circonflesso",
@@ -94,7 +93,7 @@ define(
 	otilde:"lettera latina o minuscola con tilde",
 	ouml:"lettera latina o minuscola con dieresi",
 	divide:"segno di divisione",
-	oslash:"lettera latina o minuscola con barra obliqua\nlettera latina o minuscola barrata",
+	oslash:"lettera latina o minuscola con barra obliqua1nlettera latina o minuscola barrata",
 	ugrave:"lettera latina u minuscola con accento grave",
 	uacute:"lettera latina u minuscola con accento acuto",
 	ucirc:"lettera latina u minuscola con accento circonflesso",
@@ -102,7 +101,6 @@ define(
 	yacute:"lettera latina y minuscola con accento acuto",
 	thorn:"lettera latina thorn minuscola",
 	yuml:"lettera latina y minuscola con dieresi",
-
 // Greek Characters and Symbols
 	fnof:"f latina minuscola con uncino\nfunzione\nfiorino",
 	Alpha:"lettera greca maiuscola alpha",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"virgoletta angolare singola rivolta a destra",
 	euro:"simbolo dell'euro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/AutoSave.js b/dojox/editor/plugins/nls/ja/AutoSave.js
index c259643..5838efe 100644
--- a/dojox/editor/plugins/nls/ja/AutoSave.js
+++ b/dojox/editor/plugins/nls/ja/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "保存",
 	"saveSettingLabelOn": "自動保存間隔の設定...",
@@ -13,5 +12,4 @@ define(
 	"saveMessageSuccess": "${0} に保存されました",
 	"saveMessageFail": "${0} に保存に失敗しました"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/Blockquote.js b/dojox/editor/plugins/nls/ja/Blockquote.js
index afe5edb..cefdfae 100644
--- a/dojox/editor/plugins/nls/ja/Blockquote.js
+++ b/dojox/editor/plugins/nls/ja/Blockquote.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "引用"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/Breadcrumb.js b/dojox/editor/plugins/nls/ja/Breadcrumb.js
index f2a80ad..76eba90 100644
--- a/dojox/editor/plugins/nls/ja/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ja/Breadcrumb.js
@@ -1,14 +1,11 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} アクション",
-	"selectContents": "内容の選択",
-	"selectElement": "要素の選択",
-	"deleteElement": "要素の削除",
-	"deleteContents": "内容の削除",
-	"moveStart": "開始するためにカーソルを移動",
-	"moveEnd": "終了するためにカーソルを移動"
+	"selectContents": "コンテンツの選択",
+	"selectElement": "エレメントの選択",
+	"deleteElement": "エレメントの削除",
+	"deleteContents": "コンテンツの削除",
+	"moveStart": "カーソルを先頭に移動",
+	"moveEnd": "カーソルを最後尾に移動"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ja/CollapsibleToolbar.js
index 59fc19a..6b7e7e6 100644
--- a/dojox/editor/plugins/nls/ja/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ja/CollapsibleToolbar.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"collapse": "エディターのツールバーを省略",
-	"expand": "エディターのツールバーを展開"
+	"collapse": "エディター・ツールバーを省略",
+	"expand": "エディター・ツールバーを展開"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/FindReplace.js b/dojox/editor/plugins/nls/ja/FindReplace.js
index ec7332c..338237f 100644
--- a/dojox/editor/plugins/nls/ja/FindReplace.js
+++ b/dojox/editor/plugins/nls/ja/FindReplace.js
@@ -1,13 +1,12 @@
 define(
-//begin v1.x content
 ({
-	"findLabel": "検索内容:",
+	"findLabel": "検索:",
 	"findTooltip": "検索するテキストを入力",
-	"replaceLabel": "次で置換:",
+	"replaceLabel": "置換後:",
 	"replaceTooltip": "置換するテキストを入力",
-	"findReplace": "検索/置換の切り替え",
+	"findReplace": "検索と置換",
 	"matchCase": "大/小文字の区別",
-	"matchCaseTooltip": "大/小文字を区別",
+	"matchCaseTooltip": "大/小文字の区別",
 	"backwards": "後方",
 	"backwardsTooltip": "テキストを後方検索",
 	"replaceAllButton": "すべてを置換",
@@ -21,5 +20,4 @@ define(
 	"eofDialogTextFind": "見つかりました",
 	"eofDialogTextReplace": "置換されました"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/InsertAnchor.js b/dojox/editor/plugins/nls/ja/InsertAnchor.js
index 8ad3b62..1e5f57e 100644
--- a/dojox/editor/plugins/nls/ja/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ja/InsertAnchor.js
@@ -1,12 +1,10 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "アンカーの挿入",
-	title: "アンカー・プロパティー",
+	title: "アンカープロパティ",
 	anchor: "名前:",
 	text: "説明:",
 	set: "設定",
 	cancel: "キャンセル"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/InsertEntity.js b/dojox/editor/plugins/nls/ja/InsertEntity.js
index 9907681..80a852e 100644
--- a/dojox/editor/plugins/nls/ja/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ja/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "記号の挿入"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/LocalImage.js b/dojox/editor/plugins/nls/ja/LocalImage.js
index 2f3cfb2..de247ee 100644
--- a/dojox/editor/plugins/nls/ja/LocalImage.js
+++ b/dojox/editor/plugins/nls/ja/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "イメージの挿入",
 	url: "イメージ",
@@ -7,8 +6,7 @@ define(
 	text: "説明",
 	set: "挿入",
 	invalidMessage: "無効なイメージ・ファイル・タイプです",
-	prePopuTextUrl: "イメージ URL を入力するか、",
-	prePopuTextBrowse: "ローカル・ファイルを参照してください。"
+	prePopuTextUrl: "イメージ URL を入力してください",
+	prePopuTextBrowse: "またはローカル・ファイルを参照してください"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/PageBreak.js b/dojox/editor/plugins/nls/ja/PageBreak.js
index 44e5b61..a6c6cc3 100644
--- a/dojox/editor/plugins/nls/ja/PageBreak.js
+++ b/dojox/editor/plugins/nls/ja/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "改ページ"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/PasteFromWord.js b/dojox/editor/plugins/nls/ja/PasteFromWord.js
index ec21e28..e288a36 100644
--- a/dojox/editor/plugins/nls/ja/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ja/PasteFromWord.js
@@ -1,10 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"pasteFromWord": "Word からの貼り付け",
-	"paste": "貼り付け",
-	"cancel": "キャンセル",
-	"instructions": "Word のコンテンツを以下のテキスト・ボックスに貼り付けてください。挿入するコンテンツを確認したら、貼り付けボタンを押します。テキストの挿入を中止するには、キャンセル・ボタンを押します。"
+	"pasteFromWord": "Word から貼り付け",
+	"instructions": "Word のコンテンツを以下のテキスト・ボックスに貼り付けてください。コンテンツを確認して問題がなければ、貼り付けボタンを押してコンテンツを挿入してください。挿入しない場合は、キャンセル・ボタンを押してください。"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/Preview.js b/dojox/editor/plugins/nls/ja/Preview.js
index b1121a6..0c1dad3 100644
--- a/dojox/editor/plugins/nls/ja/Preview.js
+++ b/dojox/editor/plugins/nls/ja/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "プレビュー"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/Save.js b/dojox/editor/plugins/nls/ja/Save.js
index 16e07aa..c199361 100644
--- a/dojox/editor/plugins/nls/ja/Save.js
+++ b/dojox/editor/plugins/nls/ja/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "保存"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/ShowBlockNodes.js b/dojox/editor/plugins/nls/ja/ShowBlockNodes.js
index cdf1cfa..55b0b7d 100644
--- a/dojox/editor/plugins/nls/ja/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ja/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "HTML ブロック要素の表示"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/Smiley.js b/dojox/editor/plugins/nls/ja/Smiley.js
index ea92ec0..e29c66a 100644
--- a/dojox/editor/plugins/nls/ja/Smiley.js
+++ b/dojox/editor/plugins/nls/ja/Smiley.js
@@ -1,27 +1,24 @@
 define(
-//begin v1.x content
 ({
 	smiley: "顔文字の挿入",
-	emoticonSmile: "微笑",
-	emoticonLaughing: "笑い",
+	emoticonSmile: "笑顔",
+	emoticonLaughing: "大笑い",
 	emoticonWink: "ウィンク",
-	emoticonGrin: "笑顔",
-	emoticonCool: "無愛想",
+	emoticonGrin: "にやり",
+	emoticonCool: "クール",
 	emoticonAngry: "怒り",
-	emoticonHalf: "半分",
-	emoticonEyebrow: "眉毛",
-	emoticonFrown: "眉をひそめる",
-	emoticonShy: "はにかんだ",
-	emoticonGoofy: "おろかな",
-	emoticonOops: "おっと",
+	emoticonHalf: "やや不満",
+	emoticonEyebrow: "驚き",
+	emoticonFrown: "しかめ面",
+	emoticonShy: "戸惑い",
+	emoticonGoofy: "おやおや",
+	emoticonOops: "しまった",
 	emoticonTongue: "舌を出す",
-	emoticonIdea: "アイデア",
+	emoticonIdea: "ひらめき",
 	emoticonYes: "はい",
 	emoticonNo: "いいえ",
-	emoticonAngel: "エンジェル",
-	emoticonCrying: "泣く",
+	emoticonAngel: "天使",
+	emoticonCrying: "泣き顔",
 	emoticonHappy: "幸せ"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/SpellCheck.js b/dojox/editor/plugins/nls/ja/SpellCheck.js
index b87055a..65b1862 100644
--- a/dojox/editor/plugins/nls/ja/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ja/SpellCheck.js
@@ -1,8 +1,7 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "一括スペル・チェック",
-	unfound: "見つかりません",
+	unfound: "未検出",
 	skip: "スキップ",
 	skipAll: "すべてをスキップ",
 	toDic: "辞書に追加",
@@ -16,5 +15,4 @@ define(
 	iSkipAll: "これと類似のものをスキップ",
 	iMsg: "スペルの修正候補はありません"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/TableDialog.js b/dojox/editor/plugins/nls/ja/TableDialog.js
index 4be4c85..08e66b8 100644
--- a/dojox/editor/plugins/nls/ja/TableDialog.js
+++ b/dojox/editor/plugins/nls/ja/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "テーブルの挿入",
 	modifyTableTitle: "テーブルの変更",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "テーブル幅:",
 	backgroundColor: "背景色:",
 	borderColor: "ボーダーの色:",
-	borderThickness: "ボーダーの太さ",
+	borderThickness: "ボーダーの太さ:",
 	percent: "パーセント",
 	pixels: "ピクセル",
 	"default": "デフォルト",
@@ -21,15 +20,14 @@ define(
 	buttonSet: "設定", // translated elsewhere?
 	buttonInsert: "挿入",
 	buttonCancel: "キャンセル",
-
-	selectTableLabel: "テーブルの選択",
+	selectTableLabel: "表の選択",
 	insertTableRowBeforeLabel: "前に行を追加",
 	insertTableRowAfterLabel: "後ろに行を追加",
 	insertTableColumnBeforeLabel: "前に列を追加",
 	insertTableColumnAfterLabel: "後ろに列を追加",
 	deleteTableRowLabel: "行の削除",
-	deleteTableColumnLabel: "列の削除"
+	deleteTableColumnLabel: "列の削除",
+	colorTableCellTitle: "背景色のテーブル・セル",
+	tableContextMenuTitle: "テーブルのコンテキスト・メニュー"
 })
-	
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/TextColor.js b/dojox/editor/plugins/nls/ja/TextColor.js
index df114fa..eaea029 100644
--- a/dojox/editor/plugins/nls/ja/TextColor.js
+++ b/dojox/editor/plugins/nls/ja/TextColor.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "設定",
 	"cancelButtonText": "キャンセル"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ja/latinEntities.js b/dojox/editor/plugins/nls/ja/latinEntities.js
index 579c710..3f37584 100644
--- a/dojox/editor/plugins/nls/ja/latinEntities.js
+++ b/dojox/editor/plugins/nls/ja/latinEntities.js
@@ -1,16 +1,15 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"逆感嘆符",
 	cent:"セント記号",
 	pound:"ポンド記号",
-	curren:"通貨記号",
+	curren:"不特定通貨記号",
 	yen:"円記号\n元記号",
 	brvbar:"破線バー\n破線垂直バー",
 	sect:"セクション記号",
@@ -20,23 +19,23 @@ define(
 	laquo:"左二重角引用符\n左ギュメ",
 	not:"否定記号",
 	shy:"ソフト・ハイフン\n任意ハイフン",
-	reg:"登録記号\n登録商標",
-	macr:"長音記号\n間隔長音記号\n上線\nAPL 上線",
-	deg:"角度記号",
-	plusmn:"正符号\n正または負符号",
-	sup2:"上付き文字 2\n上付き文字数字 2\n平方",
-	sup3:"上付き文字 3\n上付き文字数字 3\n立方",
+	reg:"登録商標\n登録商標記号",
+	macr:"長音符号\n間隔長音符号\n上線\nAPL 上線",
+	deg:"度記号",
+	plusmn:"プラス・マイナス記号\n正負符号",
+	sup2:"上付き 2\n上付き数字 2\n二乗",
+	sup3:"上付き 3\n上付き数字 3\n三乗",
 	acute:"揚音アクセント\n間隔揚音",
 	micro:"マイクロ記号",
-	para:"段落記号\n段落記号",
-	middot:"中間ドット\nグルジア語のコンマ\nギリシャ語の中間ドット",
+	para:"段落記号\nパラグラフ記号",
+	middot:"中黒\nギリシャ語コンマ\nギリシャ語中黒",
 	cedil:"セディーユ\n間隔セディーユ",
-	sup1:"上付き文字 1\n上付き文字数字 1",
+	sup1:"上付き 1\n上付き数字 1",
 	ordm:"男性序数標識",
 	raquo:"右二重角引用符\n右ギュメ",
-	frac14:"分数の 4 分の 1\n分数の 4 分の 1",
-	frac12:"分数の 2 分の 1\n分数の 2 分の 1",
-	frac34:"分数の 4 分の 3\n分数の 4 分の 3",
+	frac14:"分数 4 分の 1\n4 分の 1",
+	frac12:"分数 2 分の 1\n2 分の 1",
+	frac34:"分数 4 分の 3\n4 分の 3",
 	iquest:"逆疑問符\n反転疑問符",
 	Agrave:"ラテン語の抑音付き大文字 A\nラテン語の抑音付き大文字 A",
 	Aacute:"ラテン語の揚音付き大文字 A",
@@ -69,7 +68,7 @@ define(
 	Uuml:"ラテン語の分音符号付き大文字 U",
 	Yacute:"ラテン語の揚音付き大文字 Y",
 	THORN:"ラテン語の大文字 THORN",
-	szlig:"ラテン語の小文字のシャープ s\n s 字形",
+	szlig:"ラテン語の小文字のシャープ s\nエスツェット",
 	agrave:"ラテン語の抑音付き小文字 a\nラテン語の抑音付き小文字 a",
 	aacute:"ラテン語の揚音付き小文字 a",
 	acirc:"ラテン語の曲折アクセント記号付き小文字 a",
@@ -102,7 +101,6 @@ define(
 	yacute:"ラテン語の揚音付き小文字 y",
 	thorn:"ラテン語の小文字 thorn",
 	yuml:"ラテン語の分音符号付き小文字 y",
-
 // Greek Characters and Symbols
 	fnof:"ラテン語のフック付き小文字 f\n関数\nフロリン",
 	Alpha:"ギリシャ語の大文字アルファ",
@@ -119,7 +117,7 @@ define(
 	Mu:"ギリシャ語の大文字ミュー",
 	Nu:"ギリシャ語の大文字ニュー",
 	Xi:"ギリシャ語の大文字クシー",
-	Omicron:"ギリシャ語の大文字オミクロン",
+	Omicron:"ギリシャ語大文字オミクロン",
 	Pi:"ギリシャ語の大文字パイ",
 	Rho:"ギリシャ語の大文字ロー",
 	Sigma:"ギリシャ語の大文字シグマ",
@@ -158,12 +156,12 @@ define(
 	upsih:"ギリシャ語のフック記号付きユプシロン",
 	piv:"ギリシャ語のパイ記号",
 	bull:"黒丸\n黒い小さな円",
-	hellip:"水平省略符号\n3 つのドット・リーダー",
-	prime:"プライム記号\n分\nフィート",
-	Prime:"二重プライム記号\n秒\nインチ",
-	oline:"上線\n間隔上線",
+	hellip:"水平省略符号\n3 点ドット・リーダー",
+	prime:"プライム符号\n分\nフィート",
+	Prime:"二重プライム符号\n秒\nインチ",
+	oline:"上線\n間隔オーバースコア",
 	frasl:"分数のスラッシュ",
-	weierp:"添え字の大文字 P\n累乗集合\nWeierstrass p",
+	weierp:"スクリプト体の大文字 P\n累乗集合\nWeierstrass の P 関数",
 	image:"ドイツ字体の大文字 I\n虚数部",
 	real:"ドイツ字体の大文字 R\n実数部記号",
 	trade:"商標",
@@ -173,48 +171,48 @@ define(
 	rarr:"右矢印",
 	darr:"下矢印",
 	harr:"左右矢印",
-	crarr:"角が左向きの下矢印\復帰",
+	crarr:"リターン・キー記号\nキャリッジ・リターン",
 	lArr:"左二重矢印",
 	uArr:"上二重矢印",
 	rArr:"右二重矢印",
 	dArr:"下二重矢印",
 	hArr:"左右二重矢印",
-	forall:"すべてについて",
+	forall:"すべての",
 	part:"偏微分",
-	exist:"存在",
-	empty:"空集合\nヌル集合\n直径",
+	exist:"存在する",
+	empty:"空集合\nNULL セット\n直径記号",
 	nabla:"ナブラ\n後方の差分",
-	isin:"右辺の要素である",
-	notin:"右辺の要素でない",
-	ni:"メンバーとして含まれる",
-	prod:"n 乗\n積符号",
-	sum:"n 回加算",
-	minus:"減算記号",
+	isin:"属する",
+	notin:"属さない",
+	ni:"元として含む",
+	prod:"n 乗\n乗算記号",
+	sum:"n 項の加算",
+	minus:"負符号",
 	lowast:"アスタリスク演算子",
-	radic:"平方根\nルート記号",
+	radic:"平方根\n根号",
 	prop:"比例",
-	infin:"無限",
-	ang:"角度",
-	and:"論理積\nくさび形",
+	infin:"無限大",
+	ang:"角",
+	and:"論理積\nくさび",
 	or:"論理和\nV 字形",
-	cap:"集合の積\nキャップ形",
-	cup:"和集合\カップ形","int":"積分",
-	there4:"したがって",
-	sim:"チルド演算子\n多様性\n類似性",
-	cong:"おおよそ等しい",
-	asymp:"ほぼ等しい\n漸近",
+	cap:"積集合\nキャップ",
+	cup:"和集合\nカップ","int":"積分",
+	there4:"ゆえに",
+	sim:"チルド演算子\n波形記号\n相似",
+	cong:"ほとんど等しい",
+	asymp:"近似\n同相",
 	ne:"等しくない",
 	equiv:"同一",
-	le:"小さいか等しい",
-	ge:"大きいか等しい",
-	sub:"左辺は右辺の部分集合",
-	sup:"左辺は右辺を包含する",
-	nsub:"部分集合でない",
-	sube:"部分集合または等しい",
-	supe:"包含集合または等しい",
-	oplus:"ベクトル和\n直和",
-	otimes:"ベクトル積\nベクトル積",
-	perp:"直角\n直交\n垂直",
+	le:"小なりイコール",
+	ge:"大なりイコール",
+	sub:"真部分集合 (含まれる)",
+	sup:"真部分集合 (含む)",
+	nsub:"真部分集合 (含まれない)",
+	sube:"部分集合 (含まれる)",
+	supe:"部分集合 (含む)",
+	oplus:"丸付きプラス記号\n直和",
+	otimes:"丸付き乗算記号\nベクトル積",
+	perp:"上向き鋲\n直角\n垂直",
 	sdot:"ドット演算子",
 	lceil:"左上限\nAPL 上限",
 	rceil:"右上限",
@@ -223,39 +221,37 @@ define(
 	lang:"左角括弧",
 	rang:"右角括弧",
 	loz:"ひし形",
-	spades:"トランプの黒のスペードの組",
-	clubs:"トランプの黒のクラブの組\nシャムロック",
-	hearts:"トランプの黒のハートの組\nバレンタイン",
-	diams:"トランプの黒のダイヤモンドの組",
+	spades:"スペード",
+	clubs:"クラブ\n三つ葉",
+	hearts:"ハート\nバレンタイン",
+	diams:"ダイヤ",
 	OElig:"ラテン語の大文字の合字 OE",
 	oelig:"ラテン語の小文字の合字 oe",
 	Scaron:"ラテン語のキャロン付き大文字 S",
 	scaron:"ラテン語のキャロン付き小文字 s",
 	Yuml:"ラテン語の分音符号付き大文字 Y",
-	circ:"修飾文字の曲折アクセント記号アクセント",
+	circ:"曲折アクセント記号の修飾文字",
 	tilde:"小文字の波形記号",
-	ensp:"en スペース",
-	emsp:"em スペース",
-	thinsp:"薄いスペース",
-	zwnj:"結合なしで幅ゼロ",
-	zwj:"結合ありで幅ゼロ",
-	lrm:"左から右へのマーク",
-	rlm:"右から左へのマーク",
-	ndash:"en ダッシュ",
-	mdash:"em ダッシュ",
+	ensp:"n 幅の空白 (半角スペース)",
+	emsp:"m 幅の空白 (全角スペース)",
+	thinsp:"細い空白",
+	zwnj:"合字の防止",
+	zwj:"合字の強制",
+	lrm:"記述方向制御 (左から右)",
+	rlm:"記述方向制御 (右から左)",
+	ndash:"n 幅のダッシュ (半角ダッシュ)",
+	mdash:"m 幅のダッシュ (全角ダッシュ)",
 	lsquo:"左単一引用符",
 	rsquo:"右単一引用符",
-	sbquo:"単一下付き右引用符",
+	sbquo:"単一下付き引用符",
 	ldquo:"左二重引用符",
 	rdquo:"右二重引用符",
-	bdquo:"二重下付き右引用符",
-	dagger:"剣標",
-	Dagger:"二重剣標",
+	bdquo:"二重下付き引用符",
+	dagger:"ダガー",
+	Dagger:"ダブル・ダガー",
 	permil:"パーミル記号",
-	lsaquo:"単一左角引用符",
-	rsaquo:"単一右角引用符",
+	lsaquo:"左単一山括弧",
+	rsaquo:"右単一山括弧",
 	euro:"ユーロ記号"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/AutoSave.js b/dojox/editor/plugins/nls/kk/AutoSave.js
index 15c8ff3..e46aeea 100644
--- a/dojox/editor/plugins/nls/kk/AutoSave.js
+++ b/dojox/editor/plugins/nls/kk/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Сақтау",
 	"saveSettingLabelOn": "Автосақтау аралығын орнату...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "${0} сақталды",
 	"saveMessageFail": "${0} сақталмады"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/Blockquote.js b/dojox/editor/plugins/nls/kk/Blockquote.js
index e54a9ba..bed9ca8 100644
--- a/dojox/editor/plugins/nls/kk/Blockquote.js
+++ b/dojox/editor/plugins/nls/kk/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Blockquote"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/Breadcrumb.js b/dojox/editor/plugins/nls/kk/Breadcrumb.js
index 2f05e88..38a22af 100644
--- a/dojox/editor/plugins/nls/kk/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/kk/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} Әрекеттер",
 	"selectContents": "Мазмұнын таңдау",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Жүгіргіні басына жылжыту",
 	"moveEnd": "Жүгіргіні аяғына жылжыту"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/CollapsibleToolbar.js b/dojox/editor/plugins/nls/kk/CollapsibleToolbar.js
index a17abb2..907fbc4 100644
--- a/dojox/editor/plugins/nls/kk/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/kk/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Өңдегіш құралдар тақтасын тасалау",
 	"expand": "Өңдегіш құралдар тақтасын шығарып алу"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/FindReplace.js b/dojox/editor/plugins/nls/kk/FindReplace.js
index 6392848..a27a1be 100644
--- a/dojox/editor/plugins/nls/kk/FindReplace.js
+++ b/dojox/editor/plugins/nls/kk/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Табу:",
 	"findTooltip": "Табылатын мәтінді енгізу",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "табылды",
 	"eofDialogTextReplace": "ауыстырылды"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/InsertAnchor.js b/dojox/editor/plugins/nls/kk/InsertAnchor.js
index f6d2654..3338aac 100644
--- a/dojox/editor/plugins/nls/kk/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/kk/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Бетбелгі кірістіру",
 	title: "Бетбелгі сипаттары",
@@ -8,6 +7,4 @@ define(
 	set: "Орнату",
 	cancel: "Болдырмау"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/InsertEntity.js b/dojox/editor/plugins/nls/kk/InsertEntity.js
index 5b424c1..96fe502 100644
--- a/dojox/editor/plugins/nls/kk/InsertEntity.js
+++ b/dojox/editor/plugins/nls/kk/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Нышанды кірістіру"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/LocalImage.js b/dojox/editor/plugins/nls/kk/LocalImage.js
index d4ac2ff..cd2176d 100644
--- a/dojox/editor/plugins/nls/kk/LocalImage.js
+++ b/dojox/editor/plugins/nls/kk/LocalImage.js
@@ -1,8 +1,7 @@
 define(
-//begin v1.x content
 ({
-	insertImageTitle: "Сурет кірістіру",
-	url: "Кескін",
+	insertImageTitle: "Суретті кірістіру",
+	url: "Сурет",
 	browse: "Шолу...",
 	text: "Сипаттама",
 	set: "Кірістіру",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Кескіннің URL мекен-жайын енгізіңіз",
 	prePopuTextBrowse: " немесе жергілікті файлға өтіңіз."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/PageBreak.js b/dojox/editor/plugins/nls/kk/PageBreak.js
index ecbcd75..f31d50e 100644
--- a/dojox/editor/plugins/nls/kk/PageBreak.js
+++ b/dojox/editor/plugins/nls/kk/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Бет үзілімі"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/PasteFromWord.js b/dojox/editor/plugins/nls/kk/PasteFromWord.js
index 745ce31..bc88cfb 100644
--- a/dojox/editor/plugins/nls/kk/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/kk/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Word бағдарламасынан қою",
-	"paste": "Қою",
-	"cancel": "Болдырмау",
 	"instructions": "Мазмұнды Word бағдарламасынан төмендегі мәтін ұясына қойыңыз.  Кірістірілетін мазмұн дұрыс болса, қою түймешігін басыңыз.  Мәтінді кірістіруді доғару үшін болдырмау түймешігін басыңыз."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/Preview.js b/dojox/editor/plugins/nls/kk/Preview.js
index 35b9025..6bec253 100644
--- a/dojox/editor/plugins/nls/kk/Preview.js
+++ b/dojox/editor/plugins/nls/kk/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Алдын ала қарау"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/Save.js b/dojox/editor/plugins/nls/kk/Save.js
index 347c126..27e49f2 100644
--- a/dojox/editor/plugins/nls/kk/Save.js
+++ b/dojox/editor/plugins/nls/kk/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Сақтау"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/ShowBlockNodes.js b/dojox/editor/plugins/nls/kk/ShowBlockNodes.js
index 958a69d..2ffdb7f 100644
--- a/dojox/editor/plugins/nls/kk/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/kk/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "HTML блогы элементтерін көрсету"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/Smiley.js b/dojox/editor/plugins/nls/kk/Smiley.js
index c84a840..2004de4 100644
--- a/dojox/editor/plugins/nls/kk/Smiley.js
+++ b/dojox/editor/plugins/nls/kk/Smiley.js
@@ -1,27 +1,24 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Эмограмма енгізу",
 	emoticonSmile: "күлімсіреу",
 	emoticonLaughing: "күлу",
-	emoticonWink: "көз қысу",
+	emoticonWink: "кірпік қағу",
 	emoticonGrin: "ақситу",
-	emoticonCool: "салқын",
+	emoticonCool: "байсалды",
 	emoticonAngry: "ашулы",
 	emoticonHalf: "жарты",
 	emoticonEyebrow: "қас",
 	emoticonFrown: "қабағы түйілу",
 	emoticonShy: "ұялшақ",
-	emoticonGoofy: "ақымақ",
+	emoticonGoofy: "аңқау",
 	emoticonOops: "ой",
 	emoticonTongue: "тіл",
-	emoticonIdea: "ой",
+	emoticonIdea: "пікір",
 	emoticonYes: "иә",
-	emoticonNo: "ешбір",
+	emoticonNo: "жоқ",
 	emoticonAngel: "періште",
 	emoticonCrying: "жылау",
 	emoticonHappy: "бақыт"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/SpellCheck.js b/dojox/editor/plugins/nls/kk/SpellCheck.js
index b063e6f..06e3af8 100644
--- a/dojox/editor/plugins/nls/kk/SpellCheck.js
+++ b/dojox/editor/plugins/nls/kk/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Бума емлесін тексеру",
 	unfound: "Табылмады",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Осы сияқты барлығын өткізіп жіберу",
 	iMsg: "Емле ұсыныстары жоқ"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/TableDialog.js b/dojox/editor/plugins/nls/kk/TableDialog.js
index 5ee0d74..bc5eb79 100644
--- a/dojox/editor/plugins/nls/kk/TableDialog.js
+++ b/dojox/editor/plugins/nls/kk/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Кесте кірістіру",
 	modifyTableTitle: "Кестені өзгерту",
@@ -11,26 +10,24 @@ define(
 	tableWidth: "Кесте ені:",
 	backgroundColor: "Өң түсі:",
 	borderColor: "Жиек түсі:",
-	borderThickness: "Жиек қалыңдығы",
+	borderThickness: "Жиек қалыңдығы:",
 	percent: "пайыз",
-	pixels: "нүктелер",
+	pixels: "нүкте",
 	"default": "әдепкі",
-	left: "сол жақ",
+	left: "сол жағы",
 	center: "ортасы",
 	right: "оң жақ",
 	buttonSet: "Орнату", // translated elsewhere?
 	buttonInsert: "Кірістіру",
 	buttonCancel: "Болдырмау",
-
 	selectTableLabel: "Кестені таңдау",
 	insertTableRowBeforeLabel: "Жолды алдына қосу",
 	insertTableRowAfterLabel: "Жолды артына қосу",
 	insertTableColumnBeforeLabel: "Бағанды алдына қосу",
 	insertTableColumnAfterLabel: "Бағанды артына қосу",
 	deleteTableRowLabel: "Жолды жою",
-	deleteTableColumnLabel: "Бағанды жою"
+	deleteTableColumnLabel: "Бағанды жою",
+	colorTableCellTitle: "Өң түсінің кесте ұяшығы",
+	tableContextMenuTitle: "Кесте мазмұнының мәзірі"
 })
-	
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/TextColor.js b/dojox/editor/plugins/nls/kk/TextColor.js
index 1328e29..f22db75 100644
--- a/dojox/editor/plugins/nls/kk/TextColor.js
+++ b/dojox/editor/plugins/nls/kk/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Орнату",
 	"cancelButtonText": "Болдырмау"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/kk/latinEntities.js b/dojox/editor/plugins/nls/kk/latinEntities.js
index 600f9b6..c7762a8 100644
--- a/dojox/editor/plugins/nls/kk/latinEntities.js
+++ b/dojox/editor/plugins/nls/kk/latinEntities.js
@@ -1,50 +1,49 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"аударылған леп белгісі",
 	cent:"цент белгісі",
 	pound:"фунт белгісі",
 	curren:"ақша белгісі",
-	yen:"йен белгісі\nюань белгісі",
-	brvbar:"үзілген сызық\nүзілген тік сызық",
+	yen:"йена белгісі\nюань белгісі",
+	brvbar:"сынған жолақ\nсынған тік жолақ",
 	sect:"бөлім белгісі",
-	uml:"диэреза\nаралық диэрезасы",
+	uml:"diaeresis\nspacing diaeresis",
 	copy:"авторлық құқық белгісі",
-	ordf:"реттік көрсеткіш",
-	laquo:"сол жақты көрсететін қос бұрышты тырнақша\nсол жақты көрсететін кайра",
+	ordf:"әйелдердің реттік көрсеткіші",
+	laquo:"сол жаққа бағытталған қос бұрыш тырнақша\nсол жаққа бағытталған тырнақша",
 	not:"not белгісі",
-	shy:"тасымалдау белгісі\nеркін тасымалдау",
-	reg:"тіркелген белгісі\nтіркелген сауда белгісінің белгісі",
-	macr:"созылыңқы белгісі\nаралық созылыңқы белгісі\noсызылған\nүстін сызу",
+	shy:"тасмалдау белгісі\nдискрециялық сызықшалар",
+	reg:"тіркелген белгі\nтіркелген сауда маркасының белгісі",
+	macr:"ұзақтық белгісі\nұзақтық арасы\noverline\nAPL сызық үстінен",
 	deg:"градус белгісі",
-	plusmn:"қосу-алу белгісі\nқосу-немесе-алу белгісі",
-	sup2:"жол үсті екі\nжол үсті сан екі\nшаршы",
-	sup3:"жол үсті үш\nжол үсті сан үш\nтекше",
-	acute:"диакритика белгісі\nаралық диакритика белгісі",
+	plusmn:"қосу алу белгісі\nқосу немесе алу белгісі",
+	sup2:"жолүсті екі\nжолүсті саны екі\nквадрат",
+	sup3:"жолүсті үш\nжолүсті саны үш\nтекшеленген",
+	acute:"екпін белгісі\nекпін белгісінің аралығы",
 	micro:"шағын белгісі",
-	para:"pilcrow белгісі\nеже белгісі",
-	middot:"ортаңғы нүкте\nГрузиялық нүктесі\nГрек ортаңғы нүктесі",
-	cedil:"седиль\nаралық седиль",
-	sup1:"жол үсті бір\nжол үсті сан бір",
-	ordm:"реттік көрсеткіш",
-	raquo:"оң жақты көрсететін қос бұрышты тырнақша\nоң жақты көрсететін кайра",
-	frac14:"жай бөлшек бір ширек\nбөлшек бір ширек",
-	frac12:"жай бөлшек бір жарым\nбөлшек бір жарым",
-	frac34:"жай бөлшек үш ширек\nбөлшек үш ширек",
-	iquest:"аударылған сұрақ белгісі\nбұрылған сұрақ белгісі",
-	Agrave:"Екпін түсетін латын A бас әрпі\nЕкпін түсетін латын A бас әрпі",
+	para:"жаңа жол белгісі\nпараграф белгісі",
+	middot:"ортаңғы нүкте\nГрузия үтірі\nГрек ортаңғы нүктесі",
+	cedil:"седиль\nседиль кеңістігі",
+	sup1:"жолүсті бір\nжолүсті саны бір",
+	ordm:"ерлердің реттік көрсеткіші",
+	raquo:"оң жаққа бағытталған қос бұрыш тырнақша\nоң жаққа бағытталған тырнақша",
+	frac14:"тұрпайы бөлшек бірде төрт\nбөлшек бірде төрт",
+	frac12:"тұрпайы бөлшек бір жарым\nбөлшек бір жарым",
+	frac34:"тұрпайы бөлшек үш те төрт\nбөлшек үш те төрт",
+	iquest:"төңкерілген сұрау белгісі\nтеріс бұрылған сұрау белгісі",
+	Agrave:"Әлсіз екпінді A Латын бас әріпі\nA әлсіз екпінді Латын бас әріпі",
 	Aacute:"Диакритика белгісі бар латын A бас әрпі",
 	Acirc:"Циркумфлекс белгісі бар латын A бас әрпі",
 	Atilde:"Тильда белгісі бар латын A бас әрпі",
 	Auml:"Диэреза белгісі бар латын A бас әрпі",
-	Aring:"Үстінде сақина бар латын A бас әрпі\nСақина бар латын A бас әрпі",
-	AElig:"Латын AE бас әрпі\nЛатын AE бас әріп лигатурасы",
+	Aring:"Латын жоғарысында дөңгелегі бар А бас әріпі\nЛатын A дөңгелекті бас әріпі",
+	AElig:"Латын AE бас әріпі\nЛатын AE бас лигатура",
 	Ccedil:"Седиль белгісі бар латын С бас әрпі",
 	Egrave:"Екпін түсетін латын E бас әрпі",
 	Eacute:"Диакритика белгісі бар латын E бас әрпі",
@@ -62,21 +61,21 @@ define(
 	Otilde:"Тильда белгісі бар латын O бас әрпі",
 	Ouml:"Диэреза белгісі бар латын O бас әрпі",
 	times:"көбейту белгісі",
-	Oslash:"Қиғаш сызықпен латын O бас әрпі\nҚиғаш сызықпен латын O бас әрпі",
+	Oslash:"Қиғаш сызықшасы бар Латын O бас әріпі\nЛатын қиғаш O бас әріпі",
 	Ugrave:"Екпін түсетін латын U бас әрпі",
 	Uacute:"Диакритика белгісі бар латын U бас әрпі",
 	Ucirc:"Циркумфлекс белгісі бар латын U бас әрпі",
 	Uuml:"Диэреза белгісі бар латын U бас әрпі",
 	Yacute:"Диакритика белгісі бар латын Y бас әрпі",
 	THORN:"Латын THORN бас әрпі",
-	szlig:"Латын sharp s\ness-zed кіші әрпі",
-	agrave:"Екпін түсетін латын кіші әрпі\nЕкпін түсетін латын кіші әрпі",
+	szlig:"Латын кішкентай түзу s әріпі\ness-zed",
+	agrave:"Латын әлсіз екпінді кішкентай a әріпі\nЛатын әлсіз екпінді кішкентай a әріпі",
 	aacute:"Диакритика белгісі бар латын кіші әрпі",
 	acirc:"Циркумфлекс белгісі бар латын кіші әрпі",
 	atilde:"Тильда белгісі бар латын кіші әрпі",
 	auml:"Диэреза белгісі бар латын кіші әрпі",
-	aring:"Үстінде сақина бар латын кіші әрпі\nСақина бар латын кіші әрпі",
-	aelig:"Латын ae кіші әрпі\nЛатын ae кіші лигатурасы",
+	aring:"Латын кішкентай жоғарысында дөңгелегі бар a әріпі\nЛатын кішкентай a дөңгелек әріпі",
+	aelig:"Латын кішкентай ae әріпі\nЛатын кішкентай ae лигатурасы",
 	ccedil:"Седиль белгісі бар латын c кіші әрпі",
 	egrave:"Екпін түсетін латын e кіші әрпі",
 	eacute:"Диакритика белгісі бар латын e кіші әрпі",
@@ -94,7 +93,7 @@ define(
 	otilde:"Тильда белгісі бар латын o кіші әрпі",
 	ouml:"Диэреза белгісі бар латын o кіші әрпі",
 	divide:"бөлу белгісі",
-	oslash:"Қиғаш сызықпен латын o кіші әрпі\nҚиғаш сызықпен латын o кіші әрпі",
+	oslash:"Латын кішкентай қиғаш сызықпен o әріпі\nЛатын кішкентай қиғаш o кіші әріпі",
 	ugrave:"Екпін түсетін латын u кіші әрпі",
 	uacute:"Диакритика белгісі бар латын u кіші әрпі",
 	ucirc:"Циркумфлекс белгісі бар латын u кіші әрпі",
@@ -102,9 +101,8 @@ define(
 	yacute:"Диакритика белгісі бар латын y кіші әрпі",
 	thorn:"Латын thorn кіші әрпі",
 	yuml:"Диэреза белгісі бар латын y кіші әрпі",
-
 // Greek Characters and Symbols
-	fnof:"Тырнақшаға алынған латын f кіші әрпі\nфункция\nфлорин",
+	fnof:"Латын кішкентай ілгегі бар f әріпі\nфункция\nфлорин",
 	Alpha:"Грек альфа бас әрпі",
 	Beta:"Грек бета бас әрпі",
 	Gamma:"Грек гамма бас әрпі",
@@ -157,23 +155,23 @@ define(
 	thetasym:"Грек кіші әрпі тэта нышаны",
 	upsih:"Ілмек нышанымен грек упсилоны",
 	piv:"Грек пи нышаны",
-	bull:"байрақша\nқара кіші дөңгелек",
-	hellip:"көлденең эллипсис\nүш нүкте толтырғышы",
-	prime:"прим\nминут\nфут",
-	Prime:"қос прим\nсекунд\nдюйм",
-	oline:"үстінен сызу\nаралық сызу",
+	bull:"оқ\nқара кішкентай дөңгелек",
+	hellip:"көлденең эллипси\nүш нүктелі басқарушы",
+	prime:"негізгі\nминут\nфут",
+	Prime:"қос негізгі\nсекунд\nдюйм",
+	oline:"жоғарғы сызық\nжоғарғы көрсеткіш аралығы",
 	frasl:"бөлшек қиғаш сызығы",
-	weierp:"сценарийдің P бас әрпі\nдәреже көптігі\nВейерштрасс p",
-	image:"ескі I бас әрпі\nжорымал бөлік",
-	real:"ескі R бас әрпі\nнақты бөлік нышаны",
+	weierp:"сценарий P бас әріпі\nорнату қуаты\nВейерштрасс p",
+	image:"ескі баспалы I бас әріпі\nжалған бөлік",
+	real:"ескі баспалы R бас әріпі\nшын бөлік белгішесі",
 	trade:"сауда белгісінің белгісі",
-	alefsym:"alef нышаны\nбірінші шексіз кардинал саны",
+	alefsym:"алэф белгішесі\nбірінші трансфинитті кардинал сан",
 	larr:"солға қарай көрсеткі",
 	uarr:"жоғары қарай көрсеткі",
 	rarr:"оңға қарай көрсеткі",
 	darr:"төменге қарай көрсеткі",
 	harr:"солдан оңға қарай көрсеткі",
-	crarr:"бұрышы солға қарайтын төменге қарай көрсеткі\nкаретканы қайтару",
+	crarr:"солға бұрылған төменге көрсеткі\nжылжыма бөлікті қайтару",
 	lArr:"солға қарай қос көрсеткі",
 	uArr:"жоғары қарай қос көрсеткі",
 	rArr:"оңға қарай қос көрсеткі",
@@ -182,27 +180,27 @@ define(
 	forall:"барлығына",
 	part:"жартылай дифференциал",
 	exist:"бар",
-	empty:"бос жиын\nбос жиын\nдиаметр",
-	nabla:"набла\nсолға қарай айырмашылық",
+	empty:"бос орнату\nнөлдік орнату\nдиаметр",
+	nabla:"набла\nартқа айырмашылығы",
 	isin:"элементі",
 	notin:"элементі емес",
 	ni:"құрамында мүше ретінде",
-	prod:"n-ary өнімі\nөнім белгісі",
-	sum:"n-ary қосу",
+	prod:"и-дық өнім\nөнім белгісі",
+	sum:"и-дық қосу",
 	minus:"алу белгісі",
 	lowast:"жұлдызша амалдағышы",
-	radic:"квадрат түбір\nтүбір белгісі",
+	radic:"квадрат түбір\nрадикал белгісі",
 	prop:"пропорционалды",
 	infin:"шексіздік",
 	ang:"бұрыш",
-	and:"логикалық және\nүшбұрыш призма",
-	or:"логикалық немесе\nүшбұрыш",
-	cap:"қиылысу\nконус",
-	cup:"байланыс\nбіріктіру белгісі","int":"интеграл",
+	and:"логикалық және\nайналма симметриялы",
+	or:"логикалық немесе\nv әрпі",
+	cap:"қиылыс\nнүкте",
+	cup:"біріккен\nнүкте","int":"интеграл",
 	there4:"сондықтан",
-	sim:"тильда амалдағышы\nөзгеріп отырады\nұқсас",
+	sim:"тильда операторs\nтүрленбелі\nбірдей",
 	cong:"шамамен тең",
-	asymp:"тең дерлік\nасимптотикалық",
+	asymp:"тең шамасында\nасимптотикалық",
 	ne:"тең емес",
 	equiv:"бірдей",
 	le:"аздау немесе тең",
@@ -212,20 +210,20 @@ define(
 	nsub:"ішкі жиыны емес",
 	sube:"ішкі жиыны немесе тең",
 	supe:"көптігі немесе тең",
-	oplus:"дөңгелектелген плюс\nтікелей сома",
-	otimes:"дөңгелектелген уақыттар\nвектор көбейтіндісі",
-	perp:"жоғары түймесі\nтік бұрышты\nперпендикулярлық",
+	oplus:"дөңгелектелген қосу\nтікелей сумма",
+	otimes:"дөңгелектелген уақыт\nвектор өнімі",
+	perp:"up tack\nортогональды to\nперпендикуляр",
 	sdot:"нүкте амалдағышы",
-	lceil:"сол жақ шегі\nAPL жоғарғы деңгейі",
+	lceil:"сол жақ төбе\nAPL жоғары өту",
 	rceil:"оң жақ шегі",
-	lfloor:"сол жақ төменгі деңгейі\nAPL төменгі деңгейі",
+	lfloor:"сол жақ едені\nAPL төменге өту",
 	rfloor:"оң жақ төменгі деңгейі",
 	lang:"сол жақты көрсететін бұрыштық жақша",
 	rang:"оң жақты көрсететін бұрыштық жақша",
 	loz:"ромб",
 	spades:"қара қалақ дестесі",
-	clubs:"қара клуб дестесі\nүшқұлақ",
-	hearts:"қара жүрек дестесі\nвалентин",
+	clubs:"қара клуб түсі\nүшқұлақ",
+	hearts:"қара карта түсі\nвалентин",
 	diams:"қара алмас дестесі",
 	OElig:"Латын OE бас әріп лигатурасы",
 	oelig:"Латын oe кіші әріп лигатурасы",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"бір оң жақты көрсететін бұрыштық тырнақша",
 	euro:"еуро белгісі"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/AutoSave.js b/dojox/editor/plugins/nls/ko/AutoSave.js
index 5b4e120..d13f8d2 100644
--- a/dojox/editor/plugins/nls/ko/AutoSave.js
+++ b/dojox/editor/plugins/nls/ko/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "저장",
 	"saveSettingLabelOn": "자동 저장 간격 설정...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "${0}에 저장됨",
 	"saveMessageFail": "${0}에 저장 실패"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/Blockquote.js b/dojox/editor/plugins/nls/ko/Blockquote.js
index e54a9ba..bed9ca8 100644
--- a/dojox/editor/plugins/nls/ko/Blockquote.js
+++ b/dojox/editor/plugins/nls/ko/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Blockquote"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/Breadcrumb.js b/dojox/editor/plugins/nls/ko/Breadcrumb.js
index 51badb5..9948b0b 100755
--- a/dojox/editor/plugins/nls/ko/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ko/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} 조치",
 	"selectContents": "컨텐츠 선택",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "커서를 이동하여 시작",
 	"moveEnd": "커서를 이동하여 종료"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ko/CollapsibleToolbar.js
index 93b51c3..6879ef0 100644
--- a/dojox/editor/plugins/nls/ko/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ko/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "편집기 도구 모음 접기",
 	"expand": "편집기 도구 모음 펼치기"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/FindReplace.js b/dojox/editor/plugins/nls/ko/FindReplace.js
index 1d59185..14a9a67 100755
--- a/dojox/editor/plugins/nls/ko/FindReplace.js
+++ b/dojox/editor/plugins/nls/ko/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "찾기:",
 	"findTooltip": "찾을 텍스트 입력",
@@ -10,16 +9,15 @@ define(
 	"matchCaseTooltip": "대소문자 구분",
 	"backwards": "뒤로",
 	"backwardsTooltip": "텍스트 역방향 검색",
-	"replaceAllButton": "모두 바꾸기",
-	"replaceAllButtonTooltip": "텍스트 모두 바꾸기",
+	"replaceAllButton": "모두 대체",
+	"replaceAllButtonTooltip": "텍스트 모두 대체",
 	"findButton": "찾기",
 	"findButtonTooltip": "텍스트 찾기",
 	"replaceButton": "바꾸기",
-	"replaceButtonTooltip": "텍스트 바꾸기",
+	"replaceButtonTooltip": "텍스트 대체",
 	"replaceDialogText": "${0}개를 대체했습니다.",
 	"eofDialogText": "마지막 발생 ${0}",
 	"eofDialogTextFind": "찾음",
 	"eofDialogTextReplace": "대체됨"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/InsertAnchor.js b/dojox/editor/plugins/nls/ko/InsertAnchor.js
index 6c5a5b1..621cec3 100644
--- a/dojox/editor/plugins/nls/ko/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ko/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "기준 위치 삽입",
 	title: "기준 위치 특성",
@@ -8,6 +7,4 @@ define(
 	set: "설정",
 	cancel: "취소"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/InsertEntity.js b/dojox/editor/plugins/nls/ko/InsertEntity.js
index 4e59b4c..f511753 100755
--- a/dojox/editor/plugins/nls/ko/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ko/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "기호 삽입"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/LocalImage.js b/dojox/editor/plugins/nls/ko/LocalImage.js
index 6711b28..177150e 100644
--- a/dojox/editor/plugins/nls/ko/LocalImage.js
+++ b/dojox/editor/plugins/nls/ko/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "이미지 삽입",
 	url: "이미지",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "이미지 URL 입력",
 	prePopuTextBrowse: "또는 로컬 파일 찾아보기"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/PageBreak.js b/dojox/editor/plugins/nls/ko/PageBreak.js
index c79a3a4..c4efd13 100755
--- a/dojox/editor/plugins/nls/ko/PageBreak.js
+++ b/dojox/editor/plugins/nls/ko/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "페이지 나누기"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/PasteFromWord.js b/dojox/editor/plugins/nls/ko/PasteFromWord.js
index 8ee9e7e..9df3228 100644
--- a/dojox/editor/plugins/nls/ko/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ko/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "단어에서 붙여넣기",
-	"paste": "붙여넣기",
-	"cancel": "취소",
 	"instructions": "단어에서 아래 텍스트 상자로 컨텐츠를 붙여 넣으십시오. 삽입할 컨텐츠가 준비되면 붙여넣기 단추를 누르십시오. 텍스트 삽입을 중단하려면 취소 단추를 누르십시오. "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/Preview.js b/dojox/editor/plugins/nls/ko/Preview.js
index 6ceb255..46abf1f 100755
--- a/dojox/editor/plugins/nls/ko/Preview.js
+++ b/dojox/editor/plugins/nls/ko/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "미리보기"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/Save.js b/dojox/editor/plugins/nls/ko/Save.js
index ba3095b..bd3d1c2 100755
--- a/dojox/editor/plugins/nls/ko/Save.js
+++ b/dojox/editor/plugins/nls/ko/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "저장"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/ShowBlockNodes.js b/dojox/editor/plugins/nls/ko/ShowBlockNodes.js
index 7f4f76f..f3b4822 100755
--- a/dojox/editor/plugins/nls/ko/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ko/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "HTML 블록 요소 표시"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/Smiley.js b/dojox/editor/plugins/nls/ko/Smiley.js
index c72b291..a18c93f 100644
--- a/dojox/editor/plugins/nls/ko/Smiley.js
+++ b/dojox/editor/plugins/nls/ko/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "이모티콘 삽입",
 	emoticonSmile: "미소",
@@ -22,5 +21,4 @@ define(
 	emoticonCrying: "울음",
 	emoticonHappy: "기쁜"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/SpellCheck.js b/dojox/editor/plugins/nls/ko/SpellCheck.js
index 3ef51df..591b3f1 100644
--- a/dojox/editor/plugins/nls/ko/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ko/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "맞춤법 검사 일괄처리",
 	unfound: "찾을 수 없음",
@@ -7,15 +6,13 @@ define(
 	skipAll: "모두 건너뛰기",
 	toDic: "사전에 추가",
 	suggestions: "제안",
-	replace: "바꾸기",
-	replaceWith: "다음으로 바꾸기",
-	replaceAll: "모두 바꾸기",
+	replace: "대체",
+	replaceWith: "다음으로 대체",
+	replaceAll: "모두 대체",
 	cancel: "취소",
 	msg: "맞춤법 오류 없음",
 	iSkip: "이 항목 건너뛰기",
 	iSkipAll: "다음과 같이 모두 건너뛰기",
 	iMsg: "맞춤법 제안 없음"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/TableDialog.js b/dojox/editor/plugins/nls/ko/TableDialog.js
index 37f53f0..49a5135 100644
--- a/dojox/editor/plugins/nls/ko/TableDialog.js
+++ b/dojox/editor/plugins/nls/ko/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "테이블 삽입",
 	modifyTableTitle: "테이블 수정",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "테이블 너비:",
 	backgroundColor: "배경색:",
 	borderColor: "테두리 색:",
-	borderThickness: "테두리 굵기",
+	borderThickness: "테두리 두께",
 	percent: "백분율",
 	pixels: "픽셀",
 	"default": "기본값",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "설정", // translated elsewhere?
 	buttonInsert: "삽입",
 	buttonCancel: "취소",
-
 	selectTableLabel: "테이블 선택",
 	insertTableRowBeforeLabel: "사전 행 추가",
 	insertTableRowAfterLabel: "사후 행 추가",
 	insertTableColumnBeforeLabel: "사전 열 추가",
 	insertTableColumnAfterLabel: "사후 열 추가",
 	deleteTableRowLabel: "행 삭제",
-	deleteTableColumnLabel: "열 삭제"
+	deleteTableColumnLabel: "열 삭제",
+	colorTableCellTitle: "배경색 테이블 셀",
+	tableContextMenuTitle: "테이블 컨텍스트 메뉴"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/TextColor.js b/dojox/editor/plugins/nls/ko/TextColor.js
index f4113e2..5255ef9 100644
--- a/dojox/editor/plugins/nls/ko/TextColor.js
+++ b/dojox/editor/plugins/nls/ko/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "설정",
 	"cancelButtonText": "취소"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ko/latinEntities.js b/dojox/editor/plugins/nls/ko/latinEntities.js
index 7f81478..1590580 100644
--- a/dojox/editor/plugins/nls/ko/latinEntities.js
+++ b/dojox/editor/plugins/nls/ko/latinEntities.js
@@ -1,210 +1,208 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
-	iexcl:"거꾸로 느낌표",
+	iexcl:"역느낌표",
 	cent:"센트 기호",
 	pound:"파운드 기호",
 	curren:"통화 기호",
-	yen:"엔화 기호\n엔화 기호",
-	brvbar:"수직 바\n수직 바",
+	yen:"엔 기호\n위안 기호",
+	brvbar:"분할된 막대\n분할된 세로 막대",
 	sect:"섹션 기호",
-	uml:"두점 표시\n두점 표시",
-	copy:"저작권",
-	ordf:"줄 위의 소문자 a",
-	laquo:"이중 꺾어 열음\n이중 꺾어 열음",
-	not:"not 기호",
-	shy:"부드러운 하이픈\n부드러운 하이픈",
-	reg:"등록 상표 기호\n등록 상표 기호",
-	macr:"장음 기호\n장음 기호\n장음 기호\n장음 기호",
-	deg:"도 기호",
-	plusmn:"플러스 마이너스\n플러스 마이너스",
-	sup2:"위첨자 2\n위첨자 2\n위첨자 2",
-	sup3:"위첨자 3\n위첨자 3\n위첨자 3",
-	acute:"양음 액센트\n양음 액센트",
+	uml:"분음 기호\n간격 분음 기호",
+	copy:"저작권 기호",
+	ordf:"여성형 서수 기호",
+	laquo:"여는 이중 꺾쇠괄호\n여는 이중 꺾쇠괄호",
+	not:"부정 기호",
+	shy:"소프트 하이픈\n임의 하이픈",
+	reg:"등록상표 기호\n등록 TM(Trade Mark) 기호",
+	macr:"장음 기호\n간격 장음 기호\n윗줄\nAPL 윗막대",
+	deg:"온도 기호",
+	plusmn:"플러스 마이너스 기호\n플러스 또는 마이너스 기호",
+	sup2:"위첨자 2\n위첨자 숫자 2\n제곱",
+	sup3:"위첨자 3\n위첨자 숫자 3\n세제곱",
+	acute:"양음 부호\n간격 양음 부호",
 	micro:"마이크로 기호",
-	para:"문단 기호\n문단 기호",
-	middot:"중앙 점\n중앙 점\n중앙 점",
-	cedil:"갈고리형 부호\n갈고리형 부호",
-	sup1:"위첨자 1\n위첨자 1",
-	ordm:"줄 위의 작은 원",
-	raquo:"이중 꺾어 닫음\n이중 꺾어 닫음",
-	frac14:"사분의 일\n사분의 일",
-	frac12:"이분의 일\n이분의 일",
-	frac34:"사분의 삼\n사분의 삼",
-	iquest:"거꾸로 물음표\n거꾸로 물음표",
-	Agrave:"라틴대문자 A 위 역액센트\n라틴대문자 A 위 역액센트",
-	Aacute:"라틴대문자 A 위 액센트",
-	Acirc:"라틴대문자 A 위 꺾음 표시",
-	Atilde:"라틴대문자 A 위 물결 표시",
-	Auml:"라틴대문자 A 위 두점 표시",
-	Aring:"라틴대문자 A 위 원 표시\n라틴대문자 A 위 원 표시",
-	AElig:"라틴대문자 AE\n라틴대문자 AE",
-	Ccedil:"라틴대문자 C 갈고리형 부호",
-	Egrave:"라틴대문자 E 위 역액센트",
-	Eacute:"라틴대문자 E 위 액센트",
-	Ecirc:"라틴대문자 E 위 꺾음 표시",
-	Euml:"라틴대문자 E 위 두점 표시",
-	Igrave:"라틴대문자 I 위 역액센트",
-	Iacute:"라틴대문자 I 위 액센트",
-	Icirc:"라틴대문자 I 위 꺾음 표시",
-	Iuml:"라틴대문자 I 위 두점 표시",
-	ETH:"라틴대문자 ETH",
-	Ntilde:"라틴대문자 N 위 물결 표시",
-	Ograve:"라틴대문자 O 위 역액센트",
-	Oacute:"라틴대문자 O 위 액센트",
-	Ocirc:"라틴대문자 O 위 꺾음 표시",
-	Otilde:"라틴대문자 O 위 물결 표시",
-	Ouml:"라틴대문자 O 위 두점 표시",
+	para:"단락 기호\n단락 기호",
+	middot:"가운데 점\n조지안 쉼표\n그리스 가운데 점",
+	cedil:"세디유\n간격 세디유",
+	sup1:"위첨자 1\n위첨자 숫자 1",
+	ordm:"남성형 서수 기호",
+	raquo:"닫는 이중 꺾쇠괄호\n닫는 이중 꺾쇠괄호",
+	frac14:"분수 사분의 일\n분수 사분의 일",
+	frac12:"분수 이분의 일\n분수 이분의 일",
+	frac34:"분수 사분의 삼\n분수 사분의 삼",
+	iquest:"역물음표\n역물음표",
+	Agrave:"라틴 대문자 A 위 억음 부호\n라틴 대문자 A 위 억음 부호",
+	Aacute:"라틴 대문자 A 위 액센트",
+	Acirc:"라틴 대문자 A 위 서컴플렉스",
+	Atilde:"라틴 대문자 A 위 물결 기호",
+	Auml:"라틴 대문자 A 위 분음 기호",
+	Aring:"라틴 대문자 A 위 원 표시\n라틴 대문자 A 위 원",
+	AElig:"라틴 대문자 AE\n라틴 대문자 합자 AE",
+	Ccedil:"라틴 대문자 C 세디유",
+	Egrave:"라틴 대문자 E 위 억음 부호",
+	Eacute:"라틴 대문자 E 위 액센트",
+	Ecirc:"라틴 대문자 E 위 서컴플렉스",
+	Euml:"라틴 대문자 E 위 분음 기호",
+	Igrave:"라틴 대문자 I 위 억음 부호",
+	Iacute:"라틴 대문자 I 위 액센트",
+	Icirc:"라틴 대문자 I 위 서컴플렉스",
+	Iuml:"라틴 대문자 I 위 분음 기호",
+	ETH:"라틴 대문자 ETH",
+	Ntilde:"라틴 대문자 N 위 물결 기호",
+	Ograve:"라틴 대문자 O 위 억음 부호",
+	Oacute:"라틴 대문자 O 위 액센트",
+	Ocirc:"라틴 대문자 O 위 서컴플렉스",
+	Otilde:"라틴 대문자 O 위 물결 기호",
+	Ouml:"라틴 대문자 O 위 분음 기호",
 	times:"곱셈 기호",
-	Oslash:"라틴대문자 O 슬래시 첨부",
-	Ugrave:"라틴대문자 U 위 역액센트",
-	Uacute:"라틴대문자 U 위 액센트",
-	Ucirc:"라틴대문자 U 위 꺾음 표시",
-	Uuml:"라틴대문자 U 위 두점 표시",
-	Yacute:"라틴대문자 Y 위 액센트",
-	THORN:"라틴대문자 THORN",
-	szlig:"라틴소문자 sharp\n라틴소문자 sharp",
-	agrave:"라틴소문자 a 위 역액센트\n라틴소문자 a 위 역액센트",
-	aacute:"라틴소문자 a 위 액센트",
-	acirc:"라틴소문자 a 위 꺾음 표시",
-	atilde:"라틴소문자 a 위 물결 표시",
-	auml:"라틴소문자 a 위 두점 표시",
-	aring:"라틴소문자 a 위 원 표시\n라틴소문자 a 위 원 표시",
-	aelig:"라틴소문자 ae\n라틴소문자 ae",
-	ccedil:"라틴소문자 c 갈고리형 부호",
-	egrave:"라틴소문자 e  위 역액센트",
-	eacute:"라틴소문자 e 위 액센트",
-	ecirc:"라틴소문자 e 위 꺾음 표시",
-	euml:"라틴소문자 e 위 두점 표시",
-	igrave:"라틴소문자 i 위 역액센트",
-	iacute:"라틴소문자 i 액센트",
-	icirc:"라틴소문자 i 위 꺾음 표시",
-	iuml:"라틴소문자 i 위 두점 표시",
-	eth:"라틴소문자 eth",
-	ntilde:"라틴소문자 n 위 물결 표시",
-	ograve:"라틴소문자 o 위 역액센트",
-	oacute:"라틴소문자 o 위 액센트",
-	ocirc:"라틴소문자 o 위 꺾음 표시",
-	otilde:"라틴소문자 o 위 물결 표시",
-	ouml:"라틴소문자 o 위 두점 표시",
+	Oslash:"스트로크가 있는 라틴 대문자 O\n라틴 대문자 O 슬래시",
+	Ugrave:"라틴 대문자 U 위 억음 부호",
+	Uacute:"라틴 대문자 U 위 액센트",
+	Ucirc:"라틴 대문자 U 위 서컴플렉스",
+	Uuml:"라틴 대문자 U 위 분음 기호",
+	Yacute:"라틴 대문자 Y 위 액센트",
+	THORN:"라틴 대문자 THORN",
+	szlig:"라틴 소문자 sharp\라틴 소문자 sharp",
+	agrave:"라틴 소문자 a 위 억음 부호\n라틴 소문자 a 위 억음 부호",
+	aacute:"라틴 소문자 a 위 액센트",
+	acirc:"라틴 소문자 a 위 서컴플렉스",
+	atilde:"라틴 소문자 a 위 물결 기호",
+	auml:"라틴 소문자 a 위 분음 기호",
+	aring:"라틴 소문자 a 위 원\n라틴 소문자 a 위 원",
+	aelig:"라틴 소문자 ae\n라틴 소문자 합자 ae",
+	ccedil:"라틴 소문자 c 세디유",
+	egrave:"라틴 소문자 e  위 억음 부호",
+	eacute:"라틴 소문자 e 위 액센트",
+	ecirc:"라틴 소문자 e 위 서컴플렉스",
+	euml:"라틴 소문자 e 위 분음 기호",
+	igrave:"라틴 소문자 i 위 억음 부호",
+	iacute:"라틴 소문자 i 액센트",
+	icirc:"라틴 소문자 i 위 서컴플렉스",
+	iuml:"라틴 소문자 i 위 분음 기호",
+	eth:"라틴 소문자 eth",
+	ntilde:"라틴 소문자 n 위 물결 기호",
+	ograve:"라틴 소문자 o 위 억음 부호",
+	oacute:"라틴 소문자 o 위 액센트",
+	ocirc:"라틴 소문자 o 위 서컴플렉스",
+	otilde:"라틴 소문자 o 위 물결 기호",
+	ouml:"라틴 소문자 o 위 분음 기호",
 	divide:"나눗셈 기호",
-	oslash:"라틴소문자 o 슬래시 첨부\n라틴소문자 o 슬래시 첨부",
-	ugrave:"라틴소문자 u 위 역액센트",
-	uacute:"라틴소문자 u 위 액센트",
-	ucirc:"라틴소문자 u 위 꺾음 표시",
-	uuml:"라틴소문자 u 위 두점 표시",
-	yacute:"라틴소문자 y 위 액센트",
-	thorn:"라틴소문자 thorn",
-	yuml:"라틴소문자 y 위 두점 표시",
-
+	oslash:"스트로크가 있는 라틴 소문자 o\n라틴 소문자 o 슬래시",
+	ugrave:"라틴 소문자 u 위 억음 부호",
+	uacute:"라틴 소문자 u 위 액센트",
+	ucirc:"라틴 소문자 u 위 서컴플렉스",
+	uuml:"라틴 소문자 u 위 분음 기호",
+	yacute:"라틴 소문자 y 위 액센트",
+	thorn:"라틴 소문자 thorn",
+	yuml:"라틴 소문자 y 위 분음 기호",
 // Greek Characters and Symbols
-	fnof:"라틴소문자 f에 고리 첨부\n라틴소문자 f에 고리 첨부\n라틴소문자 f에 고리 첨부",
-	Alpha:"그리스대문자 alpha",
-	Beta:"그리스대문자 beta",
-	Gamma:"그리스대문자 gamma",
-	Delta:"그리스대문자 delta",
-	Epsilon:"그리스대문자 epsilon",
-	Zeta:"그리스대문자 zeta",
-	Eta:"그리스대문자 eta",
-	Theta:"그리스대문자 theta",
-	Iota:"그리스대문자 iota",
-	Kappa:"그리스대문자 kappa",
-	Lambda:"그리스대문자 lambda",
-	Mu:"그리스대문자 mu",
-	Nu:"그리스대문자 nu",
-	Xi:"그리스대문자 xi",
-	Omicron:"그리스대문자 omicron",
-	Pi:"그리스대문자 pi",
-	Rho:"그리스대문자 rho",
-	Sigma:"그리스대문자 sigma",
-	Tau:"그리스대문자 tau",
-	Upsilon:"그리스대문자 upsilon",
-	Phi:"그리스대문자 phi",
-	Chi:"그리스대문자 chi",
-	Psi:"그리스대문자 psi",
-	Omega:"그리스대문자 omega",
-	alpha:"그리스소문자 alpha",
-	beta:"그리스소문자 beta",
-	gamma:"그리스소문자 gamma",
-	delta:"그리스소문자 delta",
-	epsilon:"그리스소문자 epsilon",
-	zeta:"그리스소문자 zeta",
-	eta:"그리스소문자 eta",
-	theta:"그리스소문자 theta",
-	iota:"그리스소문자 iota",
-	kappa:"그리스소문자 kappa",
-	lambda:"그리스소문자 lambda",
-	mu:"그리스소문자 mu",
-	nu:"그리스소문자 nu",
-	xi:"그리스소문자 xi",
-	omicron:"그리스소문자 omicron",
-	pi:"그리스소문자 pi",
-	rho:"그리스소문자 rho",
-	sigmaf:"그리스소문자 final sigma",
-	sigma:"그리스소문자 sigma",
-	tau:"그리스소문자 tau",
-	upsilon:"그리스소문자 upsilon",
-	phi:"그리스소문자 phi",
-	chi:"그리스소문자 chi",
-	psi:"그리스소문자 psi",
-	omega:"그리스소문자 omega",
-	thetasym:"그리스소문자 theta symbol",
+	fnof:"라틴 소문자 f에 고리 첨부\n기능\n플로린",
+	Alpha:"그리스 대문자 alpha",
+	Beta:"그리스 대문자 beta",
+	Gamma:"그리스 대문자 gamma",
+	Delta:"그리스 대문자 delta",
+	Epsilon:"그리스 대문자 epsilon",
+	Zeta:"그리스 대문자 zeta",
+	Eta:"그리스 대문자 eta",
+	Theta:"그리스 대문자 theta",
+	Iota:"그리스 대문자 iota",
+	Kappa:"그리스 대문자 kappa",
+	Lambda:"그리스 대문자 lambda",
+	Mu:"그리스 대문자 mu",
+	Nu:"그리스 대문자 nu",
+	Xi:"그리스 대문자 xi",
+	Omicron:"그리스 대문자 omicron",
+	Pi:"그리스 대문자 pi",
+	Rho:"그리스 대문자 rho",
+	Sigma:"그리스 대문자 sigma",
+	Tau:"그리스 대문자 tau",
+	Upsilon:"그리스 대문자 upsilon",
+	Phi:"그리스 대문자 phi",
+	Chi:"그리스 대문자 chi",
+	Psi:"그리스 대문자 psi",
+	Omega:"그리스 대문자 omega",
+	alpha:"그리스 소문자 alpha",
+	beta:"그리스 소문자 beta",
+	gamma:"그리스 소문자 gamma",
+	delta:"그리스 소문자 delta",
+	epsilon:"그리스 소문자 epsilon",
+	zeta:"그리스 소문자 zeta",
+	eta:"그리스 소문자 eta",
+	theta:"그리스 소문자 theta",
+	iota:"그리스 소문자 iota",
+	kappa:"그리스 소문자 kappa",
+	lambda:"그리스 소문자 lambda",
+	mu:"그리스 소문자 mu",
+	nu:"그리스 소문자 nu",
+	xi:"그리스 소문자 xi",
+	omicron:"그리스 소문자 omicron",
+	pi:"그리스 소문자 pi",
+	rho:"그리스 소문자 rho",
+	sigmaf:"그리스 소문자 final sigma",
+	sigma:"그리스 소문자 sigma",
+	tau:"그리스 소문자 tau",
+	upsilon:"그리스 소문자 upsilon",
+	phi:"그리스 소문자 phi",
+	chi:"그리스 소문자 chi",
+	psi:"그리스 소문자 psi",
+	omega:"그리스 소문자 omega",
+	thetasym:"그리스 소문자 theta symbol",
 	upsih:"그리스 upsilon에 고리 기호",
 	piv:"그리스 pi symbol",
-	bull:"검은 원\n검은 원",
-	hellip:"수평 세 점\n수평 세 점",
-	prime:"프라임\n분\n피트",
-	Prime:"이중 프라임\n초\n인치",
-	oline:"윗 줄\n윗 줄",
-	frasl:"분수 사선",
-	weierp:"script 대문자 P\nscript 대문자 P\nscript 대문자 P",
-	image:"검정 글자 대문자 I\n검정 글자 대문자 I",
-	real:"검정 글자 대문자 R\n검정 글자 대문자 R",
+	bull:"글머리 기호\n검은색 작은 원",
+	hellip:"생략 기호\n세 점",
+	prime:"기본\n분\n피트",
+	Prime:"이중 실선 기본\n초\n인치",
+	oline:"윗 줄\n취소선",
+	frasl:"분수 슬래시",
+	weierp:"스크립트 대문자 P\n멱집합\n바이에르슈트라스 p",
+	image:"검정 글자 대문자 I\n이미지 파트",
+	real:"검정 글자 대문자 R\n실제 파트 기호",
 	trade:"TM(trade mark) 기호",
-	alefsym:"alef 기호\nalef 기호",
+	alefsym:"Alef 기호\n첫 번째 초한기수",
 	larr:"왼쪽 화살표",
 	uarr:"위쪽 화살표",
 	rarr:"오른쪽 화살표",
 	darr:"아래쪽 화살표",
 	harr:"좌우 화살표",
-	crarr:"캐리지 리턴\n캐리지 리턴]",
+	crarr:"모서리가 왼쪽으로 향하는 아래쪽 방향 화살표\n캐리지 리턴",
 	lArr:"왼쪽 이중 화살표",
 	uArr:"위쪽 이중 화살표",
-	rArr:"오른쪽 이중 화살표",
+	rArr:"두 줄짜리 오른쪽 화살표",
 	dArr:"아래쪽 이중 화살표",
-	hArr:"좌우 이중 화살표",
-	forall:"거꾸로 A",
+	hArr:"두 줄짜리 양방향 화살표",
+	forall:"모두",
 	part:"부분적으로 다름",
 	exist:"존재",
-	empty:"없음\n널\n직경",
-	nabla:"역 삼각형\n역 삼각형",
+	empty:"빈 세트\n널 세트\n지름",
+	nabla:"나블라\n후진차분",
 	isin:"..의 요소",
 	notin:"..의 요소가 아님",
 	ni:"멤버로 포함",
-	prod:"n-ary product\n결과 기호",
-	sum:"n-ary 합",
+	prod:"무한 급수\n제품 기호",
+	sum:"무한 급수 합",
 	minus:"마이너스 기호",
 	lowast:"별표 연산자",
-	radic:"제곱근 기호\n근호",
+	radic:"제곱근\n근호",
 	prop:"비례",
 	infin:"무한대",
 	ang:"각도",
-	and:"논리적 and\nwedge",
-	or:"논리적 or\nvee",
-	cap:"inter 항목\n모자",
-	cup:"유니온\n컵","int":"인티그랄",
+	and:"논리 및 \n쐐기형",
+	or:"논리 또는 \nV자형",
+	cap:"교집합\n교집합",
+	cup:"합집합\n합집합","int":"적분",
 	there4:"따라서",
-	sim:"물결 표시\n물결 표시\n유사함",
+	sim:"물결 기호 연산자\n변형\n유사",
 	cong:"대략 같다",
-	asymp:"거의 같다\n거의 같다",
+	asymp:"근사값 기호\n점근",
 	ne:"같지 않다",
-	equiv:"합동, 같다",
+	equiv:"합동 기호",
 	le:"적거나 같다",
 	ge:"크거나 같다",
 	sub:"부분 집합",
@@ -212,50 +210,48 @@ define(
 	nsub:"부분 집합이 아님",
 	sube:"부분 집합이거나 같다",
 	supe:"상위 집합이거나 같다",
-	oplus:"circled plus\ndirect sum",
-	otimes:"circled times\nvector product",
-	perp:"수직\n수직\n수직",
-	sdot:"도트 연산자",
-	lceil:"왼쪽 씰링\nAPL 업스타일",
-	rceil:"오른쪽 씰링",
-	lfloor:"왼쪽 플로어\nAPL 다운스타일",
-	rfloor:"오른쪽 플로어",
-	lang:"왼쪽 열린 각도",
-	rang:"오른쪽 열린 각도",
+	oplus:"원 안의 플러스\n직합",
+	otimes:"원 안의 곱하기 기호\n벡터적",
+	perp:"업 택\n직교\n수직",
+	sdot:"점 연산자",
+	lceil:"왼쪽 윗면\nAPL 업스타일",
+	rceil:"오른쪽 윗면",
+	lfloor:"왼쪽 밑면\nAPL 다운스타일",
+	rfloor:"오른쪽 밑면",
+	lang:"여는 꺾쇠괄호",
+	rang:"닫는 꺾쇠괄호",
 	loz:"마름모",
 	spades:"블랙 스페이드",
-	clubs:"블랙 크로버\n블랙 크로버",
-	hearts:"블랙 하트\n블랙 하트",
+	clubs:"블랙 크로버\n크로버",
+	hearts:"블랙 하트\n발렌타인",
 	diams:"블랙 다이아몬드",
-	OElig:"라틴대문자 ligature OE",
-	oelig:"라틴소문자 ligature oe",
-	Scaron:"라틴대문자 S 위 v 표 ",
-	scaron:"라틴소문자 s 위 v 표",
-	Yuml:"라틴대문자 Y 위 두점 표시",
+	OElig:"라틴 대문자 합자 OE",
+	oelig:"라틴 소문자 합자 oe",
+	Scaron:"라틴 대문자 S 위 v 표 ",
+	scaron:"라틴 소문자 s 위 v 표",
+	Yuml:"라틴 대문자 Y 위 분음 기호",
 	circ:"위 꺾기",
-	tilde:"소문자 위 물결 표시",
+	tilde:"소문자 위 물결 기호",
 	ensp:"en 공간",
 	emsp:"em 공간",
 	thinsp:"씬 공간",
-	zwnj:"제로 너비 비조이너",
-	zwj:"제로 너비 조이너",
+	zwnj:"폭이 0이고, 연결자 없음",
+	zwj:"폭이 0인 연결자",
 	lrm:"왼쪽에서 오른쪽으로 표시",
 	rlm:"오른쪽에서 왼쪽으로 표시",
 	ndash:"en 대시 ",
 	mdash:"em 대시",
-	lsquo:"왼쪽 단일 따옴표",
-	rsquo:"오른쪽 단일 따옴표",
-	sbquo:"단일 바닥 따옴표",
-	ldquo:"왼쪽 이중 따옴표",
-	rdquo:"오른쪽 이중 따옴표",
-	bdquo:"이중 바닥 따옴표",
-	dagger:"dagger",
-	Dagger:"이중 dagger",
+	lsquo:"여는 작은 따옴표",
+	rsquo:"닫는 작은 따옴표",
+	sbquo:"하부 작은 따옴표",
+	ldquo:"여는 큰 따옴표",
+	rdquo:"닫는 큰 따옴표",
+	bdquo:"하부 큰 따옴표",
+	dagger:"칼 모양",
+	Dagger:"이중 칼 모양",
 	permil:"퍼밀 기호",
-	lsaquo:"단일 왼쪽으로 각 따옴",
-	rsaquo:"단일 오른쪽으로 각 따옴",
+	lsaquo:"여는 단일 꺾쇠괄호",
+	rsaquo:"닫는 단일 꺾쇠괄호",
 	euro:"euro 기호"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/latinEntities.js b/dojox/editor/plugins/nls/latinEntities.js
index a95ac2e..cad6dc8 100644
--- a/dojox/editor/plugins/nls/latinEntities.js
+++ b/dojox/editor/plugins/nls/latinEntities.js
@@ -256,10 +256,11 @@ define({ root:
 	rsaquo:"single right-pointing angle quotation mark",
 	euro:"euro sign"
 })
-,
 //end v1.x content
+,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -287,5 +288,6 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "ar": true
 });
diff --git a/dojox/editor/plugins/nls/nb/AutoSave.js b/dojox/editor/plugins/nls/nb/AutoSave.js
index 87dfccc..fd4783a 100644
--- a/dojox/editor/plugins/nls/nb/AutoSave.js
+++ b/dojox/editor/plugins/nls/nb/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Lagre",
 	"saveSettingLabelOn": "Angi intervall for automatisk lagring...",
@@ -13,5 +12,4 @@ define(
 	"saveMessageSuccess": "Lagret klokken ${0}",
 	"saveMessageFail": "Mislykket lagring klokken ${0}"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/Blockquote.js b/dojox/editor/plugins/nls/nb/Blockquote.js
index 87e18cd..94ebf84 100644
--- a/dojox/editor/plugins/nls/nb/Blockquote.js
+++ b/dojox/editor/plugins/nls/nb/Blockquote.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Blokksitat"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/Breadcrumb.js b/dojox/editor/plugins/nls/nb/Breadcrumb.js
index 1f2b107..a3e292f 100644
--- a/dojox/editor/plugins/nls/nb/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/nb/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} Handlinger",
 	"selectContents": "Velg innhold",
@@ -9,5 +8,4 @@ define(
 	"moveStart": "Flytt markør til start",
 	"moveEnd": "Flytt markør til slutt"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/CollapsibleToolbar.js b/dojox/editor/plugins/nls/nb/CollapsibleToolbar.js
index 6c5adf6..ac2e581 100644
--- a/dojox/editor/plugins/nls/nb/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/nb/CollapsibleToolbar.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Komprimer verktøylinje for redigeringsprogram",
 	"expand": "Utvid verktøylinje for redigeringsprogram"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/FindReplace.js b/dojox/editor/plugins/nls/nb/FindReplace.js
index 6d09123..56e698d 100644
--- a/dojox/editor/plugins/nls/nb/FindReplace.js
+++ b/dojox/editor/plugins/nls/nb/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Søk:",
 	"findTooltip": "Skriv inn teksten du vil søke etter",
@@ -21,5 +20,4 @@ define(
 	"eofDialogTextFind": "funnet",
 	"eofDialogTextReplace": "erstattet"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/InsertAnchor.js b/dojox/editor/plugins/nls/nb/InsertAnchor.js
index b03c87f..9a07d3a 100644
--- a/dojox/editor/plugins/nls/nb/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/nb/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Sett inn anker",
 	title: "Ankeregenskaper",
@@ -8,5 +7,4 @@ define(
 	set: "Definer",
 	cancel: "Avbryt"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/InsertEntity.js b/dojox/editor/plugins/nls/nb/InsertEntity.js
index 371a8e7..326ec80 100644
--- a/dojox/editor/plugins/nls/nb/InsertEntity.js
+++ b/dojox/editor/plugins/nls/nb/InsertEntity.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Sett inn symbol"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/LocalImage.js b/dojox/editor/plugins/nls/nb/LocalImage.js
index 65d116d..c783ff7 100644
--- a/dojox/editor/plugins/nls/nb/LocalImage.js
+++ b/dojox/editor/plugins/nls/nb/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Sett inn bilde",
 	url: "Bilde",
@@ -10,5 +9,4 @@ define(
 	prePopuTextUrl: "Angi en bilde-URL",
 	prePopuTextBrowse: " eller bla gjennom til en lokal fil."
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/PageBreak.js b/dojox/editor/plugins/nls/nb/PageBreak.js
index 87355c1..dafab0d 100644
--- a/dojox/editor/plugins/nls/nb/PageBreak.js
+++ b/dojox/editor/plugins/nls/nb/PageBreak.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Sideskift"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/PasteFromWord.js b/dojox/editor/plugins/nls/nb/PasteFromWord.js
index 5e11b2d..89dc771 100644
--- a/dojox/editor/plugins/nls/nb/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/nb/PasteFromWord.js
@@ -1,10 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Lim inn fra Word",
-	"paste": "Lim inn",
-	"cancel": "Avbryt",
 	"instructions": "Lim inn innhold fra Word til tekstboksen nedenfor. Når du er fornøyd med innholdet du skal sette inn, trykker du på innlimingsknappen. Hvis du vil avbryte innsettingen av teksten, trykker du på avbruddsknappen."
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/Preview.js b/dojox/editor/plugins/nls/nb/Preview.js
index 3572550..4702dc9 100644
--- a/dojox/editor/plugins/nls/nb/Preview.js
+++ b/dojox/editor/plugins/nls/nb/Preview.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Forhåndsvis"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/Save.js b/dojox/editor/plugins/nls/nb/Save.js
index f6af5ef..64c71ac 100644
--- a/dojox/editor/plugins/nls/nb/Save.js
+++ b/dojox/editor/plugins/nls/nb/Save.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Lagre"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/ShowBlockNodes.js b/dojox/editor/plugins/nls/nb/ShowBlockNodes.js
index 86bc92a..732fb28 100644
--- a/dojox/editor/plugins/nls/nb/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/nb/ShowBlockNodes.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Vis HTML-blokkelementer"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/Smiley.js b/dojox/editor/plugins/nls/nb/Smiley.js
index b96df2a..2c5a635 100644
--- a/dojox/editor/plugins/nls/nb/Smiley.js
+++ b/dojox/editor/plugins/nls/nb/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Sett inn uttrykksikon",
 	emoticonSmile: "smil",
@@ -10,7 +9,7 @@ define(
 	emoticonAngry: "sint",
 	emoticonHalf: "halv",
 	emoticonEyebrow: "øyebryn",
-	emoticonFrown: "streng",
+	emoticonFrown: "trist",
 	emoticonShy: "sjenert",
 	emoticonGoofy: "tåpelig",
 	emoticonOops: "ops",
@@ -22,5 +21,4 @@ define(
 	emoticonCrying: "gråt",
 	emoticonHappy: "glad"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/SpellCheck.js b/dojox/editor/plugins/nls/nb/SpellCheck.js
index b074bab..356a186 100644
--- a/dojox/editor/plugins/nls/nb/SpellCheck.js
+++ b/dojox/editor/plugins/nls/nb/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Satsvis stavekontroll",
 	unfound: "Ikke funnet",
@@ -16,5 +15,4 @@ define(
 	iSkipAll: "Hopp over alle slike",
 	iMsg: "Ingen staveforslag"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/TableDialog.js b/dojox/editor/plugins/nls/nb/TableDialog.js
index 9d4adbe..84d8bb1 100644
--- a/dojox/editor/plugins/nls/nb/TableDialog.js
+++ b/dojox/editor/plugins/nls/nb/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Sett inn tabell",
 	modifyTableTitle: "Endre tabell",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Tabellbredde:",
 	backgroundColor: "Bakgrunnsfarge:",
 	borderColor: "Kantlinjefarge:",
-	borderThickness: "Kanttykkelse",
+	borderThickness: "Kantlinjetykkelse:",
 	percent: "prosent",
 	pixels: "piksler",
 	"default": "standard",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Definer", // translated elsewhere?
 	buttonInsert: "Sett inn",
 	buttonCancel: "Avbryt",
-
 	selectTableLabel: "Velg tabell",
 	insertTableRowBeforeLabel: "Legg til rad foran",
 	insertTableRowAfterLabel: "Legg til rad etter",
 	insertTableColumnBeforeLabel: "Legg til kolonne foran",
 	insertTableColumnAfterLabel: "Legg til kolonne etter",
 	deleteTableRowLabel: "Slett rad",
-	deleteTableColumnLabel: "Slett kolonne"
+	deleteTableColumnLabel: "Slett kolonne",
+	colorTableCellTitle: "Tabellcelle for bakgrunnsfarge",
+	tableContextMenuTitle: "Tabellhurtigmeny"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/TextColor.js b/dojox/editor/plugins/nls/nb/TextColor.js
index ef90e55..ee50812 100644
--- a/dojox/editor/plugins/nls/nb/TextColor.js
+++ b/dojox/editor/plugins/nls/nb/TextColor.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Definer",
 	"cancelButtonText": "Avbryt"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nb/latinEntities.js b/dojox/editor/plugins/nls/nb/latinEntities.js
index a9ea4ec..6577994 100644
--- a/dojox/editor/plugins/nls/nb/latinEntities.js
+++ b/dojox/editor/plugins/nls/nb/latinEntities.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -102,7 +101,6 @@ define(
 	yacute:"Liten bokstav y med aigu",
 	thorn:"Liten bokstav thorn",
 	yuml:"Liten bokstav y med dieresis",
-
 // Greek Characters and Symbols
 	fnof:"Liten bokstav f med krok\nfunksjon\nflorin",
 	Alpha:"Gresk stor bokstav alfa",
@@ -251,10 +249,9 @@ define(
 	bdquo:"double low-9 quotation mark",
 	dagger:"dolk",
 	Dagger:"dobbelt dolk",
-	permil:"per mille sign",
+	permil:"promilletegn",
 	lsaquo:"single left-pointing angle quotation mark",
 	rsaquo:"single right-pointing angle quotation mark",
 	euro:"euro-tegn"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/AutoSave.js b/dojox/editor/plugins/nls/nl/AutoSave.js
index e4f458c..16a4c82 100644
--- a/dojox/editor/plugins/nls/nl/AutoSave.js
+++ b/dojox/editor/plugins/nls/nl/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Opslaan",
 	"saveSettingLabelOn": "Interval voor automatisch opslaan instellen...",
@@ -10,9 +9,7 @@ define(
 	"saveSettingdialogParamLabel": "min",
 	"saveSettingdialogButtonOk": "Interval instellen",
 	"saveSettingdialogButtonCancel": "Annuleren",
-	"saveMessageSuccess": "Opgeslagen op ${0}",
-	"saveMessageFail": "Opslaan mislukt op ${0}"
+	"saveMessageSuccess": "Opgeslagen om ${0}",
+	"saveMessageFail": "Opslaan mislukt om ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/Blockquote.js b/dojox/editor/plugins/nls/nl/Blockquote.js
index e54a9ba..bed9ca8 100644
--- a/dojox/editor/plugins/nls/nl/Blockquote.js
+++ b/dojox/editor/plugins/nls/nl/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Blockquote"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/Breadcrumb.js b/dojox/editor/plugins/nls/nl/Breadcrumb.js
index 252cf2d..0e56fd4 100644
--- a/dojox/editor/plugins/nls/nl/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/nl/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} Acties",
 	"selectContents": "Inhoud selecteren",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Cursor verplaatsen naar start",
 	"moveEnd": "Cursor verplaatsen naar eind"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/CollapsibleToolbar.js b/dojox/editor/plugins/nls/nl/CollapsibleToolbar.js
index 8cbb506..f04dbcb 100644
--- a/dojox/editor/plugins/nls/nl/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/nl/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Editor-werkbalk samenvouwen",
 	"expand": "Editor-werkbalk uitvouwen"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/FindReplace.js b/dojox/editor/plugins/nls/nl/FindReplace.js
index d3c2a38..c0be3f3 100644
--- a/dojox/editor/plugins/nls/nl/FindReplace.js
+++ b/dojox/editor/plugins/nls/nl/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Zoeken:",
 	"findTooltip": "Geef de zoektekst op",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "gevonden",
 	"eofDialogTextReplace": "vervangen"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/InsertAnchor.js b/dojox/editor/plugins/nls/nl/InsertAnchor.js
index 71e26f4..0f75663 100644
--- a/dojox/editor/plugins/nls/nl/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/nl/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Anker invoegen",
 	title: "Ankereigenschappen",
@@ -8,6 +7,4 @@ define(
 	set: "Instellen",
 	cancel: "Annuleren"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/InsertEntity.js b/dojox/editor/plugins/nls/nl/InsertEntity.js
index 65fd62b..1532a20 100644
--- a/dojox/editor/plugins/nls/nl/InsertEntity.js
+++ b/dojox/editor/plugins/nls/nl/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Symbool invoegen"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/LocalImage.js b/dojox/editor/plugins/nls/nl/LocalImage.js
index d115c23..b5e1995 100644
--- a/dojox/editor/plugins/nls/nl/LocalImage.js
+++ b/dojox/editor/plugins/nls/nl/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Afbeelding invoegen",
 	url: "Afbeelding",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Geef een afbeeldings-URL op",
 	prePopuTextBrowse: " of navigeer naar een lokaal bestand."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/PageBreak.js b/dojox/editor/plugins/nls/nl/PageBreak.js
index a454a4c..7777e48 100644
--- a/dojox/editor/plugins/nls/nl/PageBreak.js
+++ b/dojox/editor/plugins/nls/nl/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Paginaeinde"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/PasteFromWord.js b/dojox/editor/plugins/nls/nl/PasteFromWord.js
index dab82ba..9922387 100644
--- a/dojox/editor/plugins/nls/nl/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/nl/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Plakken vanuit Word",
-	"paste": "Plakken",
-	"cancel": "Annuleren",
 	"instructions": "Plak de content vanuit Word in het tekstvak hieronder. Klik als u klaar bent op de knop Plakken. Kies Annuleren als u de invoeging van tekst wilt afbreken."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/Preview.js b/dojox/editor/plugins/nls/nl/Preview.js
index 1b5c179..c757669 100644
--- a/dojox/editor/plugins/nls/nl/Preview.js
+++ b/dojox/editor/plugins/nls/nl/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Preview"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/SafePaste.js b/dojox/editor/plugins/nls/nl/SafePaste.js
index adbc3e2..28ec915 100644
--- a/dojox/editor/plugins/nls/nl/SafePaste.js
+++ b/dojox/editor/plugins/nls/nl/SafePaste.js
@@ -1,5 +1,5 @@
 define(
 ({
-	"instructions": "Rechtstreeks plakken is uitgeschakeld. Plak de inhoud in dit dialoogvenster met behulp van de standaardtoetsen van de browser of via menuopties. Klik als u klaar bent op de knop Plakken. Kies Annuleren als u de invoeging van inhoud wilt afbreken."
+	"instructions": "Rechtstreeks plakken is niet mogelijk. U kunt in dit dialoogvenster content met de standaardknoppen of -toetsen van de browser plakken. Als u tevreden bent met de content die u wilt plakken, klikt u op de knop Plakken. Kies Annuleren als u de invoeging van content wilt afbreken."
 })
 );
diff --git a/dojox/editor/plugins/nls/nl/Save.js b/dojox/editor/plugins/nls/nl/Save.js
index 472d7ef..31f0693 100644
--- a/dojox/editor/plugins/nls/nl/Save.js
+++ b/dojox/editor/plugins/nls/nl/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Opslaan"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/ShowBlockNodes.js b/dojox/editor/plugins/nls/nl/ShowBlockNodes.js
index e319e83..951052a 100644
--- a/dojox/editor/plugins/nls/nl/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/nl/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "HTML-blokelementen afbeelden"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/Smiley.js b/dojox/editor/plugins/nls/nl/Smiley.js
index 847d98e..ca46162 100644
--- a/dojox/editor/plugins/nls/nl/Smiley.js
+++ b/dojox/editor/plugins/nls/nl/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Emoticon invoegen",
 	emoticonSmile: "glimlach",
@@ -20,8 +19,6 @@ define(
 	emoticonNo: "nee",
 	emoticonAngel: "engel",
 	emoticonCrying: "bedroefd",
-	emoticonHappy: "vrolijk"
+	emoticonHappy: "blij"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/SpellCheck.js b/dojox/editor/plugins/nls/nl/SpellCheck.js
index 931667e..e9d366a 100644
--- a/dojox/editor/plugins/nls/nl/SpellCheck.js
+++ b/dojox/editor/plugins/nls/nl/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Groepsgewijze spellingcontrole",
 	unfound: "Niet gevonden",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Al deze overslaan",
 	iMsg: "Geen spellingsuggesties"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/TableDialog.js b/dojox/editor/plugins/nls/nl/TableDialog.js
index 88c0d7d..04ce550 100644
--- a/dojox/editor/plugins/nls/nl/TableDialog.js
+++ b/dojox/editor/plugins/nls/nl/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Tabel invoegen",
 	modifyTableTitle: "Tabel wijzigen",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Tabelbreedte:",
 	backgroundColor: "Achtergrondkleur:",
 	borderColor: "Randkleur",
-	borderThickness: "Randdikte",
+	borderThickness: "Randdikte:",
 	percent: "percent",
 	pixels: "pixels",
 	"default": "standaard",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Instellen", // translated elsewhere?
 	buttonInsert: "invoegen",
 	buttonCancel: "Annuleren",
-
 	selectTableLabel: "Tabel selecteren",
 	insertTableRowBeforeLabel: "Rij boven toevoegen",
 	insertTableRowAfterLabel: "Rij onder toevoegen",
 	insertTableColumnBeforeLabel: "Kolom voor toevoegen",
 	insertTableColumnAfterLabel: "Kolom achter toevoegen",
 	deleteTableRowLabel: "Rij wissen",
-	deleteTableColumnLabel: "Kolom wissen"
+	deleteTableColumnLabel: "Kolom wissen",
+	colorTableCellTitle: "Achtergrondkleur van tabelcel",
+	tableContextMenuTitle: "Contextmenu voor tabel"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/TextColor.js b/dojox/editor/plugins/nls/nl/TextColor.js
index 33fda27..0067b1e 100644
--- a/dojox/editor/plugins/nls/nl/TextColor.js
+++ b/dojox/editor/plugins/nls/nl/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Instellen",
 	"cancelButtonText": "Annuleren"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/nl/latinEntities.js b/dojox/editor/plugins/nls/nl/latinEntities.js
index 7a3b45f..d21b0bd 100644
--- a/dojox/editor/plugins/nls/nl/latinEntities.js
+++ b/dojox/editor/plugins/nls/nl/latinEntities.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -102,7 +101,6 @@ define(
 	yacute:"kleine letter y met accent aigu",
 	thorn:"kleine letter thorn",
 	yuml:"kleine letter y met trema",
-
 // Greek Characters and Symbols
 	fnof:"cursieve f\nfunctie\ngulden",
 	Alpha:"Griekse hoofdletter alpha",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"enkele rechtswijzend aanhalingsteken",
 	euro:"euro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/AutoSave.js b/dojox/editor/plugins/nls/pl/AutoSave.js
index bce25dc..7ea8458 100644
--- a/dojox/editor/plugins/nls/pl/AutoSave.js
+++ b/dojox/editor/plugins/nls/pl/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Zapisz",
 	"saveSettingLabelOn": "Ustaw odstęp czasu automatycznego zapisywania...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Zapisano: ${0}",
 	"saveMessageFail": "Zapisanie nie powiodło się: ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/Blockquote.js b/dojox/editor/plugins/nls/pl/Blockquote.js
index ef57d5d..50ded29 100644
--- a/dojox/editor/plugins/nls/pl/Blockquote.js
+++ b/dojox/editor/plugins/nls/pl/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Cytat blokowy"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/Breadcrumb.js b/dojox/editor/plugins/nls/pl/Breadcrumb.js
index c4114bc..f30a84b 100644
--- a/dojox/editor/plugins/nls/pl/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/pl/Breadcrumb.js
@@ -1,7 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"nodeActions": "${nodeName} - działania",
+	"nodeActions": "${nodeName}Czynności",
 	"selectContents": "Zaznacz treść",
 	"selectElement": "Zaznacz element",
 	"deleteElement": "Usuń element",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Przenieś kursor na początek",
 	"moveEnd": "Przenieś kursor na koniec"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/CollapsibleToolbar.js b/dojox/editor/plugins/nls/pl/CollapsibleToolbar.js
index 0a9b0e6..c2e528b 100644
--- a/dojox/editor/plugins/nls/pl/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/pl/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Zwiń pasek narzędzi edytora",
 	"expand": "Rozwiń pasek narzędzi edytora"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/FindReplace.js b/dojox/editor/plugins/nls/pl/FindReplace.js
index ffa9499..440badf 100644
--- a/dojox/editor/plugins/nls/pl/FindReplace.js
+++ b/dojox/editor/plugins/nls/pl/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Znajdź:",
 	"findTooltip": "Wprowadź szukany tekst",
@@ -10,7 +9,7 @@ define(
 	"matchCaseTooltip": "Uwzględnij wielkość liter",
 	"backwards": "Do tyłu",
 	"backwardsTooltip": "Wyszukaj tekst wstecz",
-	"replaceAllButton": "Zastąp wszystkie",
+	"replaceAllButton": "Zastąp wszystko",
 	"replaceAllButtonTooltip": "Zastąp cały tekst",
 	"findButton": "Znajdź",
 	"findButtonTooltip": "Znajdź tekst",
@@ -19,8 +18,6 @@ define(
 	"replaceDialogText": "Zastąpione wystąpienia: ${0}.",
 	"eofDialogText": "Ostatnie wystąpienie: ${0}",
 	"eofDialogTextFind": "znaleziono",
-	"eofDialogTextReplace": "zastąpiono"
+	"eofDialogTextReplace": "zastąpione"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/InsertAnchor.js b/dojox/editor/plugins/nls/pl/InsertAnchor.js
index 844652f..73bdf35 100644
--- a/dojox/editor/plugins/nls/pl/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/pl/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Wstaw zakotwiczenie",
 	title: "Właściwości zakotwiczenia",
@@ -8,6 +7,4 @@ define(
 	set: "Ustaw",
 	cancel: "Anuluj"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/InsertEntity.js b/dojox/editor/plugins/nls/pl/InsertEntity.js
index ffba573..843839b 100644
--- a/dojox/editor/plugins/nls/pl/InsertEntity.js
+++ b/dojox/editor/plugins/nls/pl/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Wstaw symbol"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/LocalImage.js b/dojox/editor/plugins/nls/pl/LocalImage.js
index 8f53eb0..306edfa 100644
--- a/dojox/editor/plugins/nls/pl/LocalImage.js
+++ b/dojox/editor/plugins/nls/pl/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Wstaw obraz",
 	url: "Obraz",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Wprowadź adres URL obrazu",
 	prePopuTextBrowse: " lub wskaż plik lokalny. "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/PageBreak.js b/dojox/editor/plugins/nls/pl/PageBreak.js
index 3c34f1b..4ec3807 100644
--- a/dojox/editor/plugins/nls/pl/PageBreak.js
+++ b/dojox/editor/plugins/nls/pl/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Podział strony"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/PasteFromWord.js b/dojox/editor/plugins/nls/pl/PasteFromWord.js
index c283aac..9afff4f 100644
--- a/dojox/editor/plugins/nls/pl/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/pl/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Wklej z programu Word",
-	"paste": "Wklej",
-	"cancel": "Anuluj",
-	"instructions": "Wklej tekst z programu Word do poniższego pola tekstowego. Po uzyskaniu odpowiedniej treści do wstawienia kliknij przycisk Wklej. Aby przerwać wstawianie tekstu, kliknij przycisk Anuluj. "
+	"instructions": "Wklej tekst z programu Word do poniższego pola tekstowego. Po uzyskaniu odpowiedniej treści do wstawienia kliknij przycisk Wklej. Aby przerwać wstawianie treści, kliknij przycisk Anuluj."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/Preview.js b/dojox/editor/plugins/nls/pl/Preview.js
index 46d51a1..f4ce638 100644
--- a/dojox/editor/plugins/nls/pl/Preview.js
+++ b/dojox/editor/plugins/nls/pl/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Podgląd"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/Save.js b/dojox/editor/plugins/nls/pl/Save.js
index 73389c3..3e700d4 100644
--- a/dojox/editor/plugins/nls/pl/Save.js
+++ b/dojox/editor/plugins/nls/pl/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Zapisz"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/ShowBlockNodes.js b/dojox/editor/plugins/nls/pl/ShowBlockNodes.js
index cbb67d6..265b89b 100644
--- a/dojox/editor/plugins/nls/pl/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/pl/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Pokaż elementy bloków HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/Smiley.js b/dojox/editor/plugins/nls/pl/Smiley.js
index 4aa54a0..395c700 100644
--- a/dojox/editor/plugins/nls/pl/Smiley.js
+++ b/dojox/editor/plugins/nls/pl/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Wstaw emotikon",
 	emoticonSmile: "uśmiech",
@@ -16,12 +15,10 @@ define(
 	emoticonOops: "ups",
 	emoticonTongue: "pokazywanie języka",
 	emoticonIdea: "pomysł",
-	emoticonYes: "Tak",
-	emoticonNo: "Nie",
+	emoticonYes: "tak",
+	emoticonNo: "nie",
 	emoticonAngel: "anioł",
 	emoticonCrying: "płacz",
 	emoticonHappy: "radość"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/SpellCheck.js b/dojox/editor/plugins/nls/pl/SpellCheck.js
index 39dcfab..1d95e8d 100644
--- a/dojox/editor/plugins/nls/pl/SpellCheck.js
+++ b/dojox/editor/plugins/nls/pl/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Wsadowe sprawdzanie pisowni",
 	unfound: "Nie znaleziono",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Pomiń wszystkie pozycje podobne do tej",
 	iMsg: "Brak propozycji pisowni"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/TableDialog.js b/dojox/editor/plugins/nls/pl/TableDialog.js
index 85af1c8..06c1d49 100644
--- a/dojox/editor/plugins/nls/pl/TableDialog.js
+++ b/dojox/editor/plugins/nls/pl/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Wstawianie tabeli",
 	modifyTableTitle: "Modyfikowanie tabeli",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Szerokość tabeli:",
 	backgroundColor: "Kolor tła:",
 	borderColor: "Kolor ramki:",
-	borderThickness: "Grubość ramki",
+	borderThickness: "Grubość krawędzi:",
 	percent: "procent",
 	pixels: "piksle",
 	"default": "domyślna",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Ustaw", // translated elsewhere?
 	buttonInsert: "Wstaw",
 	buttonCancel: "Anuluj",
-
 	selectTableLabel: "Wybierz tabelę",
 	insertTableRowBeforeLabel: "Dodaj wiersz przed",
 	insertTableRowAfterLabel: "Dodaj wiersz po",
 	insertTableColumnBeforeLabel: "Dodaj kolumnę przed",
 	insertTableColumnAfterLabel: "Dodaj kolumnę po",
 	deleteTableRowLabel: "Usuń wiersz",
-	deleteTableColumnLabel: "Usuń kolumnę"
+	deleteTableColumnLabel: "Usuń kolumnę",
+	colorTableCellTitle: "Kolor tła - komórka tabeli",
+	tableContextMenuTitle: "Menu kontekstowe tabeli"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/TextColor.js b/dojox/editor/plugins/nls/pl/TextColor.js
index a73aa0e..cc807a3 100644
--- a/dojox/editor/plugins/nls/pl/TextColor.js
+++ b/dojox/editor/plugins/nls/pl/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Ustaw",
 	"cancelButtonText": "Anuluj"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pl/latinEntities.js b/dojox/editor/plugins/nls/pl/latinEntities.js
index 92bd804..2dac76f 100644
--- a/dojox/editor/plugins/nls/pl/latinEntities.js
+++ b/dojox/editor/plugins/nls/pl/latinEntities.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"odwrócony wykrzyknik",
 	cent:"znak centa",
@@ -13,96 +12,95 @@ define(
 	curren:"znak waluty",
 	yen:"znak jena\nznak yuana",
 	brvbar:"przerwana kreska\nprzerwana pionowa kreska",
-	sect:"znak sekcji",
+	sect:"znak paragrafu",
 	uml:"diereza\ndiereza rozdzielająca",
 	copy:"znak praw autorskich",
-	ordf:"znak liczby rodzaju żeńskiego",
-	laquo:"lewy cudzysłów trójkątny\nlewy guillemet",
+	ordf:"wskaźnik rodzaju żeńskiego liczebnika porządkowego",
+	laquo:"lewy podwójny cudzysłów ostrokątny\nlewy cudzysłów francuski",
 	not:"znak negacji",
 	shy:"łącznik miękki\nłącznik opcjonalny",
 	reg:"symbol zastrzeżenia\nsymbol zastrzeżonego znaku towarowego",
-	macr:"makron\nmakron rozdzielający\nnadkreślenie\nkreska górna APL",
+	macr:"makron\nmakron rozdzielający\nnadkreślenie\ngórna linia APL",
 	deg:"znak stopni",
 	plusmn:"znak plus-minus\nznak zakresu wartości przybliżonej",
-	sup2:"indeks górny dwa\ncyfra dwa w indeksie górnym\nkwadrat",
-	sup3:"indeks górny trzy\ncyfra trzy w indeksie górnym\nsześcian",
-	acute:"akcent ostry\nodstęp ostry",
+	sup2:"dwa w indeksie górnym\ncyfra 2 w indeksie górnym\ndruga potęga",
+	sup3:"trzy w indeksie górnym\ncyfra 3 w indeksie górnym\ntrzecia potęga",
+	acute:"akcent ostry\nakut rozdzielający",
 	micro:"znak mikro",
 	para:"znak pilcrow\nznak akapitu",
 	middot:"kropka środkowa\ngruziński przecinek\ngrecka kropka środkowa",
-	cedil:"cedilla\nodstęp cedilla",
-	sup1:"indeks górny jeden\ncyfra jeden w indeksie górnym",
-	ordm:"znak liczby rodzaju męskiego",
-	raquo:"prawy cudzysłów trójkątny\nprawy guillemet",
-	frac14:"znak ułamka jedna czwarta\nułamek jedna czwarta",
-	frac12:"znak ułamka jedna druga\nułamek jedna druga",
-	frac34:"znak ułamka trzy czwarte\nułamek trzy czwarte",
+	cedil:"cedilla\ncedilla rozdzielająca",
+	sup1:"jeden w indeksie górnym\ncyfra 1 w indeksie górnym",
+	ordm:"wskaźnik męskiego rodzaju liczebnika porządkowego",
+	raquo:"prawy podwójny cudzysłów ostrokątny\nprawy cudzysłów francuski",
+	frac14:"ułamek zwykły jedna czwarta\nułamek jedna czwarta",
+	frac12:"ułamek zwykły jedna druga\nułamek jedna druga",
+	frac34:"ułamek zwykły trzy czwarte\nułamek trzy czwarte",
 	iquest:"odwrócony znak zapytania\nodwrotny znak zapytania",
-	Agrave:"łacińska wielka litera A z symbolem gravis\nłacińska wielka litera A z akcentem ciężkim",
+	Agrave:"łacińska wielka litera A z grawisem\nłacińska wielka litera A z akcentem ciężkim",
 	Aacute:"łacińska wielka litera A z akcentem ostrym",
 	Acirc:"łacińska wielka litera A z daszkiem",
 	Atilde:"łacińska wielka litera A z tyldą",
-	Auml:"łacińska wielka litera A z diarezą",
-	Aring:"łacińska wielka litera A z pierścieniem powyżej\nłacińska wielka litera A z pierścieniem",
+	Auml:"łacińska wielka litera A z dierezą",
+	Aring:"łacińska wielka litera A z kółkiem powyżej\nłacińska wielka litera A z kółkiem",
 	AElig:"łacińska wielka litera AE\nłacińska ligatura wielkich liter AE",
 	Ccedil:"łacińska wielka litera C z cedillą",
 	Egrave:"łacińska wielka litera E z akcentem ciężkim",
 	Eacute:"łacińska wielka litera E z akcentem ostrym",
 	Ecirc:"łacińska wielka litera E z daszkiem",
-	Euml:"łacińska wielka litera E z diarezą",
+	Euml:"łacińska wielka litera E z dierezą",
 	Igrave:"łacińska wielka litera I z akcentem ciężkim",
 	Iacute:"łacińska wielka litera I z akcentem ostrym",
 	Icirc:"łacińska wielka litera I z daszkiem",
-	Iuml:"łacińska wielka litera I z diarezą",
+	Iuml:"łacińska wielka litera I z dierezą",
 	ETH:"łacińska wielka litera ETH",
 	Ntilde:"łacińska wielka litera N z tyldą",
 	Ograve:"łacińska wielka litera O z akcentem ciężkim",
 	Oacute:"łacińska wielka litera O z akcentem ostrym",
 	Ocirc:"łacińska wielka litera O z daszkiem",
 	Otilde:"łacińska wielka litera O z tyldą",
-	Ouml:"łacińska wielka litera O z diarezą",
+	Ouml:"łacińska wielka litera O z dierezą",
 	times:"znak mnożenia",
 	Oslash:"łacińska wielka litera O z przekreśleniem\nłacińska wielka litera O z ukośnikiem",
 	Ugrave:"łacińska wielka litera U z akcentem ciężkim",
 	Uacute:"łacińska wielka litera U z akcentem ostrym",
 	Ucirc:"łacińska wielka litera U z daszkiem",
-	Uuml:"łacińska wielka litera U z diarezą",
+	Uuml:"łacińska wielka litera U z dierezą",
 	Yacute:"łacińska wielka litera Y z akcentem ostrym",
 	THORN:"łacińska wielka litera THORN",
-	szlig:"łacińska mała litera ostre s\ness-zed",
-	agrave:"łacińska mała litera a z symbolem gravis\nłacińska mała litera a z akcentem ciężkim",
+	szlig:"łacińska mała litera ostre s\nes-zet",
+	agrave:"łacińska mała litera a z grawisem\nłacińska mała litera a z akcentem ciężkim",
 	aacute:"łacińska mała litera a z akcentem ostrym",
 	acirc:"łacińska mała litera a z daszkiem",
 	atilde:"łacińska mała litera a z tyldą",
-	auml:"łacińska mała litera a z diarezą",
-	aring:"łacińska mała litera a z pierścieniem powyżej\nłacińska mała litera a z pierścieniem",
+	auml:"łacińska mała litera a z dierezą",
+	aring:"łacińska mała litera a z kółkiem powyżej\nłacińska mała litera a z kółkiem",
 	aelig:"łacińska mała litera ae\nłacińska ligatura małych liter ae",
 	ccedil:"łacińska mała litera c z cedillą",
 	egrave:"łacińska mała litera e z akcentem ciężkim",
 	eacute:"łacińska mała litera e z akcentem ostrym",
 	ecirc:"łacińska mała litera e z daszkiem",
-	euml:"łacińska mała litera e z diarezą",
+	euml:"łacińska mała litera e z dierezą",
 	igrave:"łacińska mała litera i z akcentem ciężkim",
 	iacute:"łacińska mała litera i z akcentem ostrym",
 	icirc:"łacińska mała litera i z daszkiem",
-	iuml:"łacińska mała litera i z diarezą",
+	iuml:"łacińska mała litera i z dierezą",
 	eth:"łacińska mała litera eth",
 	ntilde:"łacińska mała litera n z tyldą",
 	ograve:"łacińska mała litera o z akcentem ciężkim",
 	oacute:"łacińska mała litera o z akcentem ostrym",
 	ocirc:"łacińska mała litera o z daszkiem",
 	otilde:"łacińska mała litera o z tyldą",
-	ouml:"łacińska mała litera o z diarezą",
+	ouml:"łacińska mała litera o z dierezą",
 	divide:"znak dzielenia",
 	oslash:"łacińska mała litera o z przekreśleniem\nłacińska mała litera o z ukośnikiem",
 	ugrave:"łacińska mała litera u z akcentem ciężkim",
 	uacute:"łacińska mała litera u z akcentem ostrym",
 	ucirc:"łacińska mała litera u z daszkiem",
-	uuml:"łacińska mała litera u z diarezą",
+	uuml:"łacińska mała litera u z dierezą",
 	yacute:"łacińska mała litera y z akcentem ostrym",
 	thorn:"łacińska mała litera thorn",
-	yuml:"łacińska mała litera y z diarezą",
-
+	yuml:"łacińska mała litera y z dierezą",
 // Greek Characters and Symbols
 	fnof:"łacińska mała litera f z haczykiem\nfunkcja\nfloren",
 	Alpha:"grecka wielka litera alfa",
@@ -161,19 +159,19 @@ define(
 	hellip:"wielokropek\ntrzy kropki",
 	prime:"prim\nminuty\nstopy",
 	Prime:"bis\nsekundy\ncale",
-	oline:"nadkreślenie\nnadkreślenie tworzące odstęp",
+	oline:"nadkreślenie\nnadkreślenie rozdzielające",
 	frasl:"kreska ułamkowa",
-	weierp:"odręcznie pisana wielka litera P\nzbiór potęgowy\nP Weierstrassa",
-	image:"gotycka wielka litera I\nczęść urojona liczby zespolonej",
+	weierp:"pisane wielkie P\nmoc zbioru\np Weierstrassa",
+	image:"gotycka wielka litera I\nsymbol części urojonej liczby zespolonej",
 	real:"gotycka wielka litera R\nsymbol części rzeczywistej liczby zespolonej",
 	trade:"symbol znaku zastrzeżonego",
-	alefsym:"znak alef\npoczątkowa liczba porządkowa",
+	alefsym:"symbol alef\npierwsza nieskończona liczba",
 	larr:"strzałka w lewo",
 	uarr:"strzałka w górę",
 	rarr:"strzałka w prawo",
 	darr:"strzałka w dół",
 	harr:"strzałka w lewo i w prawo",
-	crarr:"strzałka w dół z rogiem w lewo\npowrót karetki",
+	crarr:"strzałka w dół ze skrętem w lewo\npowrót karetki",
 	lArr:"podwójna strzałka w lewo",
 	uArr:"podwójna strzałka w górę",
 	rArr:"podwójna strzałka w prawo",
@@ -182,25 +180,25 @@ define(
 	forall:"dla każdego",
 	part:"pochodna cząstkowa",
 	exist:"istnieje",
-	empty:"zbiór pusty\nzbiór miary zero\nśrednica",
-	nabla:"nabla\nkoneksja",
+	empty:"zbiór pusty\nzbiór o wartości NULL\nśrednica",
+	nabla:"nabla\nróżnica wsteczna",
 	isin:"należy do",
 	notin:"nie należy do",
 	ni:"zawiera",
-	prod:"iloczyn n elementów\nznak iloczynu",
+	prod:"iloczyn uogólniony\nznak iloczynu",
 	sum:"suma n elementów",
 	minus:"znak minus",
 	lowast:"operator gwiazdka",
-	radic:"pierwiastek kwadratowy\nznak pierwiastka",
+	radic:"pierwiastek kwadratowy\nsymbol pierwiastkowania",
 	prop:"proporcjonalnie do",
 	infin:"nieskończoność",
 	ang:"kąt",
-	and:"iloczyn logiczny\nklin",
-	or:"suma logiczna\nlitera v",
-	cap:"część wspólna zbiorów\nczepek",
-	cup:"suma zbiorów\nfiliżanka","int":"całka",
+	and:"logiczne I\nklin",
+	or:"logiczne LUB\nsymbol V",
+	cap:"część wspólna zbiorów\nprzekrój",
+	cup:"połączenie zbiorów\nsuma zbiorów","int":"całka",
 	there4:"dlatego",
-	sim:"operator tylda\nzmienia się w granicach\nokoło",
+	sim:"operator tylda\nróżni się od\npodobne do",
 	cong:"równa się w przybliżeniu",
 	asymp:"prawie równa się\nasymptotyczne do",
 	ne:"nie równa się",
@@ -212,13 +210,13 @@ define(
 	nsub:"nie jest podzbiorem",
 	sube:"jest podzbiorem lub równa się",
 	supe:"jest nadzbiorem lub równa się",
-	oplus:"znak plus w okręgu\nsuma bezpośrednia",
-	otimes:"znak mnożenia w okręgu\niloczyn wektorów",
-	perp:"odwrócona litera T\nprostopadłe do\nprostopadłe",
+	oplus:"plus w kółku\nsuma bezpośrednia",
+	otimes:"znak mnożenia w kółku\niloczyn tensorowy",
+	perp:"ortogonalne do\njest prostopadłe do",
 	sdot:"operator kropka",
-	lceil:"lewy sufit\nhaczyk górny APL",
+	lceil:"lewy sufit\nlewe ograniczenie górne APL",
 	rceil:"prawy sufit",
-	lfloor:"lewa podłoga\nhaczyk dolny APL",
+	lfloor:"lewa podłoga\nprawe ograniczenie górne APL",
 	rfloor:"prawa podłoga",
 	lang:"lewy nawias trójkątny",
 	rang:"prawy nawias trójkątny",
@@ -252,10 +250,8 @@ define(
 	dagger:"krzyżyk",
 	Dagger:"podwójny krzyżyk",
 	permil:"promile",
-	lsaquo:"pojedynczy lewy cudzysłów trójkątny",
-	rsaquo:"pojedynczy prawy cudzysłów trójkątny",
+	lsaquo:"pojedynczy lewy cudzysłów ostrokątny",
+	rsaquo:"pojedynczy prawy cudzysłów ostrokątny",
 	euro:"znak euro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/AutoSave.js b/dojox/editor/plugins/nls/pt-pt/AutoSave.js
index 0d85628..0181f1e 100644
--- a/dojox/editor/plugins/nls/pt-pt/AutoSave.js
+++ b/dojox/editor/plugins/nls/pt-pt/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Guardar",
 	"saveSettingLabelOn": "Definir intervalo de gravação automática...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Guardado às ${0}",
 	"saveMessageFail": "Falha ao guardar às ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/Blockquote.js b/dojox/editor/plugins/nls/pt-pt/Blockquote.js
index e54a9ba..bed9ca8 100644
--- a/dojox/editor/plugins/nls/pt-pt/Blockquote.js
+++ b/dojox/editor/plugins/nls/pt-pt/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Blockquote"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/Breadcrumb.js b/dojox/editor/plugins/nls/pt-pt/Breadcrumb.js
index e3ebb20..aac276b 100644
--- a/dojox/editor/plugins/nls/pt-pt/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/pt-pt/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "Acções de ${nodeName}",
 	"selectContents": "Seleccionar conteúdo",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Mover cursor para o início",
 	"moveEnd": "Mover cursor para o fim"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/CollapsibleToolbar.js b/dojox/editor/plugins/nls/pt-pt/CollapsibleToolbar.js
index 73deb07..3975ed3 100644
--- a/dojox/editor/plugins/nls/pt-pt/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/pt-pt/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Contrair barra de ferramentas do editor",
 	"expand": "Expandir barra de ferramentas do editor"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/FindReplace.js b/dojox/editor/plugins/nls/pt-pt/FindReplace.js
index 6ebf27f..6cd824d 100644
--- a/dojox/editor/plugins/nls/pt-pt/FindReplace.js
+++ b/dojox/editor/plugins/nls/pt-pt/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Localizar:",
 	"findTooltip": "Introduzir texto a localizar",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "localizado",
 	"eofDialogTextReplace": "substituído"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/InsertAnchor.js b/dojox/editor/plugins/nls/pt-pt/InsertAnchor.js
index 39f7c2a..2b7f3aa 100644
--- a/dojox/editor/plugins/nls/pt-pt/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/pt-pt/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Inserir âncora",
 	title: "Propriedades da âncora",
@@ -8,6 +7,4 @@ define(
 	set: "Definir",
 	cancel: "Cancelar"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/InsertEntity.js b/dojox/editor/plugins/nls/pt-pt/InsertEntity.js
index 628bd32..e7c2886 100644
--- a/dojox/editor/plugins/nls/pt-pt/InsertEntity.js
+++ b/dojox/editor/plugins/nls/pt-pt/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Inserir símbolo"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/LocalImage.js b/dojox/editor/plugins/nls/pt-pt/LocalImage.js
index 8b2a3de..685eb37 100644
--- a/dojox/editor/plugins/nls/pt-pt/LocalImage.js
+++ b/dojox/editor/plugins/nls/pt-pt/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Inserir imagem",
 	url: "Imagem",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Introduzir um URL de imagem",
 	prePopuTextBrowse: " ou navegar até um ficheiro local."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/PageBreak.js b/dojox/editor/plugins/nls/pt-pt/PageBreak.js
index 191d70e..83c997d 100644
--- a/dojox/editor/plugins/nls/pt-pt/PageBreak.js
+++ b/dojox/editor/plugins/nls/pt-pt/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Quebra de página"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/PasteFromWord.js b/dojox/editor/plugins/nls/pt-pt/PasteFromWord.js
index ef129c8..7e8ab56 100644
--- a/dojox/editor/plugins/nls/pt-pt/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/pt-pt/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Colar do Word",
-	"paste": "Colar",
-	"cancel": "Cancelar",
 	"instructions": "Cole o conteúdo do Word na caixa de texto abaixo. Após estar satisfeito com o conteúdo a inserir, prima o botão de colagem. Para cancelar a inserção de texto, prima o botão de cancelamento."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/Preview.js b/dojox/editor/plugins/nls/pt-pt/Preview.js
index e9f7e64..b46534f 100644
--- a/dojox/editor/plugins/nls/pt-pt/Preview.js
+++ b/dojox/editor/plugins/nls/pt-pt/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Pré-visualizar"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/SafePaste.js b/dojox/editor/plugins/nls/pt-pt/SafePaste.js
new file mode 100644
index 0000000..1465250
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Colar directamente não está activado. Cole o conteúdo nesta caixa de diálogo utilizando o teclado do browser standard ou os controlos do menu Colar. Quando estiver satisfeito com o conteúdo a inserir, prima o botão Colar. Para cancelar a inserção de texto, prima o botão Cancelar."
+})
+);
diff --git a/dojox/editor/plugins/nls/pt-pt/Save.js b/dojox/editor/plugins/nls/pt-pt/Save.js
index 4e8a379..55bc847 100644
--- a/dojox/editor/plugins/nls/pt-pt/Save.js
+++ b/dojox/editor/plugins/nls/pt-pt/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Guardar"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/ShowBlockNodes.js b/dojox/editor/plugins/nls/pt-pt/ShowBlockNodes.js
index 2a30351..9ab5f64 100644
--- a/dojox/editor/plugins/nls/pt-pt/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/pt-pt/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Mostrar elementos do bloco HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/Smiley.js b/dojox/editor/plugins/nls/pt-pt/Smiley.js
index 978713e..b388a55 100644
--- a/dojox/editor/plugins/nls/pt-pt/Smiley.js
+++ b/dojox/editor/plugins/nls/pt-pt/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Inserir ícone emotivo",
 	emoticonSmile: "sorriso",
@@ -19,8 +18,7 @@ define(
 	emoticonYes: "sim",
 	emoticonNo: "não",
 	emoticonAngel: "anjo",
-	emoticonCrying: "a chorar"
+	emoticonCrying: "a chorar",
+	emoticonHappy: "feliz"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/SpellCheck.js b/dojox/editor/plugins/nls/pt-pt/SpellCheck.js
index 39a3ecc..69bc897 100644
--- a/dojox/editor/plugins/nls/pt-pt/SpellCheck.js
+++ b/dojox/editor/plugins/nls/pt-pt/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Verificação ortográfica por grupo",
 	unfound: "Não localizado",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Ignorar semelhantes",
 	iMsg: "Sem sugestões de ortografia"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/TableDialog.js b/dojox/editor/plugins/nls/pt-pt/TableDialog.js
index 072b0f1..b6f0f27 100644
--- a/dojox/editor/plugins/nls/pt-pt/TableDialog.js
+++ b/dojox/editor/plugins/nls/pt-pt/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Inserir tabela",
 	modifyTableTitle: "Modificar tabela",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Largura da tabela:",
 	backgroundColor: "Cor de segundo plano:",
 	borderColor: "Cor do contorno:",
-	borderThickness: "Espessura do contorno",
+	borderThickness: "Espessura do contorno:",
 	percent: "percentagem",
 	pixels: "píxeis",
 	"default": "predefinição",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Definir", // translated elsewhere?
 	buttonInsert: "Inserir",
 	buttonCancel: "Cancelar",
-
 	selectTableLabel: "Seleccionar tabela",
 	insertTableRowBeforeLabel: "Adicionar linha antes",
 	insertTableRowAfterLabel: "Adicionar linha depois",
 	insertTableColumnBeforeLabel: "Adicionar coluna antes",
 	insertTableColumnAfterLabel: "Adicionar coluna depois",
 	deleteTableRowLabel: "Eliminar linha",
-	deleteTableColumnLabel: "Eliminar coluna"
+	deleteTableColumnLabel: "Eliminar coluna",
+	colorTableCellTitle: "Cor de segundo plano da célula de tabela",
+	tableContextMenuTitle: "Menu contextual da tabela"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/TextColor.js b/dojox/editor/plugins/nls/pt-pt/TextColor.js
index d839c4b..a261198 100644
--- a/dojox/editor/plugins/nls/pt-pt/TextColor.js
+++ b/dojox/editor/plugins/nls/pt-pt/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Definir",
 	"cancelButtonText": "Cancelar"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt-pt/latinEntities.js b/dojox/editor/plugins/nls/pt-pt/latinEntities.js
index afd76ae..514bc8e 100644
--- a/dojox/editor/plugins/nls/pt-pt/latinEntities.js
+++ b/dojox/editor/plugins/nls/pt-pt/latinEntities.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"ponto de exclamação invertido",
 	cent:"símbolo de cêntimo",
@@ -14,24 +13,24 @@ define(
 	yen:"símbolo do iene\nsímbolo do yuan",
 	brvbar:"barra quebrada\nbarra vertical quebrada",
 	sect:"símbolo de secção",
-	uml:"trema\ntrema de espaço",
+	uml:"trema\ntrema de espaçamento",
 	copy:"símbolo de direitos de autor",
 	ordf:"indicador ordinal feminino",
 	laquo:"aspas esquerdas em ângulo\naspas esquerdas",
 	not:"sinal de negação",
-	shy:"hífen virtual\nhífen discricionário",
+	shy:"hífen de sílaba\nhífen discricionário",
 	reg:"símbolo de marca registada\nsímbolo de marca comercial registada",
-	macr:"mácron\nmácron de espaço\nlinha sobreposta\nbarra superior de APL",
+	macr:"macro\nmacro de espaçamento\nlinha sobreposta\nbarra superior de APL",
 	deg:"sinal de graus",
 	plusmn:"sinal de adição-subtracção\nsinal de adição ou subtracção",
-	sup2:"expoente dois\nexpoente algarismo dois\nao quadrado",
-	sup3:"expoente três\nexpoente algarismo três\nao cubo",
+	sup2:"superior à linha dois\nsuperior à linha do segundo algarismo\nao quadrado",
+	sup3:"superior à linha três\nsuperior à linha do terceiro algarismo\nao cubo",
 	acute:"acento agudo\nacento agudo de espaço",
 	micro:"sinal de micro",
 	para:"sinal de parágrafo\nsímbolo de parágrafo",
-	middot:"ponto central\nvírgula georgina\nGrego - Ponto central",
-	cedil:"cedilha\ncedilha de espaço",
-	sup1:"expoente um\nexpoente algarismo um",
+	middot:"ponto centrado\nvírgula Georgiana\nponto centrado Grego",
+	cedil:"cedilha\ncedilha de espaçamento",
+	sup1:"superior à linha um\nsuperior à linha do primeiro algarismo",
 	ordm:"indicador ordinal masculino",
 	raquo:"aspas direitas em ângulo\naspas direitas",
 	frac14:"fracção comum - um quarto\nfracção - um quarto",
@@ -40,7 +39,7 @@ define(
 	iquest:"ponto de interrogação invertido",
 	Agrave:"Latim - Letra maiúscula A com acento grave\nLatim - Letra maiúscula A grave",
 	Aacute:"Latim - Letra maiúscula A com acento agudo",
-	Acirc:"Latim - Letra maiúscula A com acento circumflexo",
+	Acirc:"Latim - Letra maiúscula A com acento circunflexo",
 	Atilde:"Latim - Letra maiúscula A com til",
 	Auml:"Latim - Letra maiúscula A com trema",
 	Aring:"Latim - Letra maiúscula A com círculo por cima\nLatim - Letra maiúscula A com círculo",
@@ -69,7 +68,7 @@ define(
 	Uuml:"Latim - Letra maiúscula U com trema",
 	Yacute:"Latim - Letra maiúscula Y com acento agudo",
 	THORN:"Latim - Letra maiúscula islandesa THORN",
-	szlig:"Latim - Letra minúscula beta\ness-zett alemão",
+	szlig:"Latim - Letra minúscula beta\nS tzét alemão",
 	agrave:"Latim - Letra minúscula a com acento grave\nLatim - Letra minúscula a grave",
 	aacute:"Latim - Letra minúscula a com acento agudo",
 	acirc:"Latim - Letra minúscula a com acento circunflexo",
@@ -102,7 +101,6 @@ define(
 	yacute:"Latim - Letra minúscula y com acento agudo",
 	thorn:"Latim - Letra minúscula islandesa thorn",
 	yuml:"Latim - Letra minúscula y com trema",
-
 // Greek Characters and Symbols
 	fnof:"Latim - Letra minúscula f com gancho\nfunção\nflorim",
 	Alpha:"Grego - Letra maiúscula alfa",
@@ -159,15 +157,15 @@ define(
 	piv:"Grego - Símbolo pi",
 	bull:"marca\ncírculo pequeno preto",
 	hellip:"reticências horizontais\ntrês pontos de seguimento",
-	prime:"apóstrofo\nminutos\npés",
-	Prime:"apóstrofo duplo\nsegundos\npolegadas",
-	oline:"linha sobreposta\nlinha sobreposta de espaço",
+	prime:"número primo\nminutos\npés",
+	Prime:"número primo duplo\nsegundos\npolegadas",
+	oline:"linha sobreposta\nlinha sobreposta de espaçamento",
 	frasl:"barra de fracção",
-	weierp:"letra maiúscula P cursiva\nconjunto potência\np de Weierstrass",
+	weierp:"letra maiúscula P cursiva\nconjunto de partes\nletra p Weierstrass",
 	image:"letra maiúscula I carregada\nparte imaginária",
 	real:"letra maiúscula R carregada\nsímbolo da parte real",
 	trade:"símbolo de marca comercial",
-	alefsym:"símbolo de elif\nprimeiro cardinal transfinito",
+	alefsym:"símbolo de elif\nprimeiro transfinito cardinal",
 	larr:"seta para a esquerda",
 	uarr:"seta para cima",
 	rarr:"seta para a direita",
@@ -183,7 +181,7 @@ define(
 	part:"diferencial parcial",
 	exist:"existe",
 	empty:"conjunto vazio\nconjunto nulo\ndiâmetro",
-	nabla:"nabla\ngradiente",
+	nabla:"nabla\ndiferença retroactiva",
 	isin:"pertence a",
 	notin:"não pertence a",
 	ni:"contém como membro",
@@ -196,11 +194,11 @@ define(
 	infin:"infinito",
 	ang:"ângulo",
 	and:"E lógico\ncunha",
-	or:"OU lógico\nv",
-	cap:"intersecção\n cap",
-	cup:"união\n cup","int":"integral",
+	or:"OU lógico\nvee",
+	cap:"intersecção\ncap",
+	cup:"união\ncup","int":"integral",
 	there4:"para isso",
-	sim:"operador til\nvaria\nsemelhante a",
+	sim:"operador de til\nvaria com\nsemelhante a",
 	cong:"aproximadamente igual a",
 	asymp:"quase igual a\nassimptótico a",
 	ne:"não igual a",
@@ -216,9 +214,9 @@ define(
 	otimes:"multiplicação dentro de um círculo\nproduto vectorial",
 	perp:"tacha em cima\nortogonal a\nperpendicular",
 	sdot:"operador de ponto",
-	lceil:"limite superior à esquerda\nAPL upstile",
+	lceil:"tecto à esquerda\nbarra superior APL",
 	rceil:"limite superior à direita",
-	lfloor:"limite inferior à esquerda\nAPL downstile",
+	lfloor:"chão à esquerda\nbarra inferior APL",
 	rfloor:"limite inferior à direita",
 	lang:"parêntese esquerdo em ângulo",
 	rang:"parêntese direito em ângulo",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"plica direita em ângulo",
 	euro:"símbolo do euro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/AutoSave.js b/dojox/editor/plugins/nls/pt/AutoSave.js
index 7b2d8ca..7791b41 100644
--- a/dojox/editor/plugins/nls/pt/AutoSave.js
+++ b/dojox/editor/plugins/nls/pt/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Salvar",
 	"saveSettingLabelOn": "Configurar Intervalo de Salvamento Automático...",
@@ -13,5 +12,4 @@ define(
 	"saveMessageSuccess": "Salvo em ${0}",
 	"saveMessageFail": "Falha ao salvar em ${0}"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/Blockquote.js b/dojox/editor/plugins/nls/pt/Blockquote.js
index 95bdcda..5fc9873 100644
--- a/dojox/editor/plugins/nls/pt/Blockquote.js
+++ b/dojox/editor/plugins/nls/pt/Blockquote.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Citação de Bloco"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/Breadcrumb.js b/dojox/editor/plugins/nls/pt/Breadcrumb.js
index 77f163c..bad02fa 100644
--- a/dojox/editor/plugins/nls/pt/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/pt/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} Ações",
 	"selectContents": "Selecionar Conteúdo",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Mover Cursor para o Início",
 	"moveEnd": "Mover Cursor para o Final"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/CollapsibleToolbar.js b/dojox/editor/plugins/nls/pt/CollapsibleToolbar.js
index 6ba443d..3d2419d 100644
--- a/dojox/editor/plugins/nls/pt/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/pt/CollapsibleToolbar.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Reduzir Barra de Ferramentas do Editor",
 	"expand": "Expandir Barra de Ferramentas do Editor"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/FindReplace.js b/dojox/editor/plugins/nls/pt/FindReplace.js
index a0c1ee1..7d4fb69 100644
--- a/dojox/editor/plugins/nls/pt/FindReplace.js
+++ b/dojox/editor/plugins/nls/pt/FindReplace.js
@@ -1,13 +1,12 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Localizar:",
 	"findTooltip": "Inserir texto a ser localizado",
 	"replaceLabel": "Substituir por:",
 	"replaceTooltip": "Inserir texto a ser substituído por",
 	"findReplace": "Localizar e Substituir",
-	"matchCase": "Coincidir maiúscula/minúscula",
-	"matchCaseTooltip": "Coincidir maiúscula/minúscula",
+	"matchCase": "Diferenciar maiúsculas/minúsculas",
+	"matchCaseTooltip": "Diferenciar maiúsculas/minúsculas",
 	"backwards": "Retroceder",
 	"backwardsTooltip": "Procurar texto para trás",
 	"replaceAllButton": "Substituir Todos",
@@ -21,5 +20,4 @@ define(
 	"eofDialogTextFind": "localizado",
 	"eofDialogTextReplace": "substituído"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/InsertAnchor.js b/dojox/editor/plugins/nls/pt/InsertAnchor.js
index 1ba2a9b..f20071a 100644
--- a/dojox/editor/plugins/nls/pt/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/pt/InsertAnchor.js
@@ -1,12 +1,10 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Inserir Âncora",
 	title: "Propriedades de Âncora",
 	anchor: "Nome:",
 	text: "Descrição:",
-	set: "Definir",
+	set: "Configurar",
 	cancel: "Cancelar"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/InsertEntity.js b/dojox/editor/plugins/nls/pt/InsertEntity.js
index ca43b94..7ab8552 100644
--- a/dojox/editor/plugins/nls/pt/InsertEntity.js
+++ b/dojox/editor/plugins/nls/pt/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Inserir Símbolo"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/LocalImage.js b/dojox/editor/plugins/nls/pt/LocalImage.js
index 99002d9..241535c 100644
--- a/dojox/editor/plugins/nls/pt/LocalImage.js
+++ b/dojox/editor/plugins/nls/pt/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Inserir imagem",
 	url: "Imagem",
@@ -10,5 +9,4 @@ define(
 	prePopuTextUrl: "Insira uma URL de imagem",
 	prePopuTextBrowse: " ou navegue até um arquivo local."
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/PageBreak.js b/dojox/editor/plugins/nls/pt/PageBreak.js
index d03057a..6f52006 100644
--- a/dojox/editor/plugins/nls/pt/PageBreak.js
+++ b/dojox/editor/plugins/nls/pt/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Quebra de Página"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/PasteFromWord.js b/dojox/editor/plugins/nls/pt/PasteFromWord.js
index bb52185..21e7be6 100644
--- a/dojox/editor/plugins/nls/pt/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/pt/PasteFromWord.js
@@ -1,10 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Colar do Word",
-	"paste": "Colar",
-	"cancel": "Cancelar",
 	"instructions": "Cole o conteúdo do Word na caixa de texto a seguir. Quando estiver satisfeito com o conteúdo a ser inserido, pressione o botão para colar. Para interromper a inserção de texto, pressione o botão para cancelar."
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/Preview.js b/dojox/editor/plugins/nls/pt/Preview.js
index 189d65b..611bad2 100644
--- a/dojox/editor/plugins/nls/pt/Preview.js
+++ b/dojox/editor/plugins/nls/pt/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
-	"preview": "Visualização"
+	"preview": "Visualizar"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/Save.js b/dojox/editor/plugins/nls/pt/Save.js
index f1be7b1..8905798 100644
--- a/dojox/editor/plugins/nls/pt/Save.js
+++ b/dojox/editor/plugins/nls/pt/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Salvar"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/ShowBlockNodes.js b/dojox/editor/plugins/nls/pt/ShowBlockNodes.js
index 2eb0e15..2e9c74c 100644
--- a/dojox/editor/plugins/nls/pt/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/pt/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Mostrar Elementos de Bloco HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/Smiley.js b/dojox/editor/plugins/nls/pt/Smiley.js
index 73d191c..25b34e2 100644
--- a/dojox/editor/plugins/nls/pt/Smiley.js
+++ b/dojox/editor/plugins/nls/pt/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Inserir Emoticon",
 	emoticonSmile: "sorriso",
@@ -22,5 +21,4 @@ define(
 	emoticonCrying: "chorando",
 	emoticonHappy: "feliz"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/SpellCheck.js b/dojox/editor/plugins/nls/pt/SpellCheck.js
index d9cb6bb..edb715c 100644
--- a/dojox/editor/plugins/nls/pt/SpellCheck.js
+++ b/dojox/editor/plugins/nls/pt/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Verificação Ortográfica em Lote",
 	unfound: "Não localizado",
@@ -16,5 +15,4 @@ define(
 	iSkipAll: "Ignorar todos iguais a este",
 	iMsg: "Nenhuma sugestão de ortografia"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/TableDialog.js b/dojox/editor/plugins/nls/pt/TableDialog.js
index 79a046b..c4ba048 100644
--- a/dojox/editor/plugins/nls/pt/TableDialog.js
+++ b/dojox/editor/plugins/nls/pt/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Inserir Tabela",
 	modifyTableTitle: "Modificar Tabela",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Largura da Tabela:",
 	backgroundColor: "Cor do Plano de Fundo:",
 	borderColor: "Cor da Borda:",
-	borderThickness: "Grossura da Borda",
+	borderThickness: "Espessura da Borda:",
 	percent: "percentual",
 	pixels: "pixels",
 	"default": "default",
@@ -21,15 +20,14 @@ define(
 	buttonSet: "Configurar", // translated elsewhere?
 	buttonInsert: "Inserir",
 	buttonCancel: "Cancelar",
-
 	selectTableLabel: "Selecionar Tabela",
 	insertTableRowBeforeLabel: "Incluir Linha Antes",
 	insertTableRowAfterLabel: "Incluir Linha Depois",
 	insertTableColumnBeforeLabel: "Incluir Coluna Antes",
 	insertTableColumnAfterLabel: "Incluir Coluna Depois",
 	deleteTableRowLabel: "Excluir Linha",
-	deleteTableColumnLabel: "Excluir Coluna"
+	deleteTableColumnLabel: "Excluir Coluna",
+	colorTableCellTitle: "Célula de Tabela de Cor do Segundo Plano",
+	tableContextMenuTitle: "Menu de Contexto da Tabela"
 })
-	
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/TextColor.js b/dojox/editor/plugins/nls/pt/TextColor.js
index ee47cc4..49bcc3f 100644
--- a/dojox/editor/plugins/nls/pt/TextColor.js
+++ b/dojox/editor/plugins/nls/pt/TextColor.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"setButtonText": "Definir",
+	"setButtonText": "Configurar",
 	"cancelButtonText": "Cancelar"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/pt/latinEntities.js b/dojox/editor/plugins/nls/pt/latinEntities.js
index 2ef279c..dc59c5d 100644
--- a/dojox/editor/plugins/nls/pt/latinEntities.js
+++ b/dojox/editor/plugins/nls/pt/latinEntities.js
@@ -1,18 +1,17 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"ponto de exclamação invertido",
 	cent:"símbolo de centavo",
 	pound:"símbolo de libra",
 	curren:"símbolo de moeda",
 	yen:"símbolo de iene\símbolo de yuan",
-	brvbar:"barra interrompida\nbarra vertical de interrompida",
+	brvbar:"barra interrompida\nbarra vertical interrompida",
 	sect:"símbolo de seção",
 	uml:"trema\ntrema de espaçamento",
 	copy:"símbolo de copyright",
@@ -21,22 +20,22 @@ define(
 	not:"nenhum símbolo",
 	shy:"hífen reformatável\nhífen discricionário",
 	reg:"símbolo de marca registrada\nsímbolo de marca comercial registrada",
-	macr:"macron\nmacron de espaçamento\nlinha sobreposta\nbarra superior de APL",
+	macr:"macro\nmacro de espaçamento\nsobrelinha\nsobrebarra APL",
 	deg:"símbolo de grau",
 	plusmn:"símbolo de mais e menos\nsímbolo de mais ou menos",
-	sup2:"dois sobrescrito\ndígito dois sobrescrito\nraiz quadrada",
-	sup3:"três sobrescrito\ndígito três sobrescrito\nraiz cúbica",
-	acute:"acento agudo\nacento agudo para espaçamento",
+	sup2:"sobrescrito dois\ndígito sobrescrito dois\nquadrado",
+	sup3:"sobrescrito três\ndígito sobrescrito três\nem cubo",
+	acute:"acento agudo\nagudo para espaçamento",
 	micro:"símbolo de micro",
 	para:"símbolo pé-de-mosca\nsímbolo de parágrafo",
-	middot:"ponto mediano\nvírgula georgiana\nponto mediano grego",
-	cedil:"cedilha\ncedilha para espaçamento",
-	sup1:"um sobrescrito\ndígito um sobrescrito",
+	middot:"ponto do meio\nvírgula Georgiana\nponto do meio grego",
+	cedil:"cedilha\ncedilha de espaçamento",
+	sup1:"sobrescrito um\ndígito sobrescrito um",
 	ordm:"indicador ordinal masculino",
 	raquo:"aspas latinas duplas de abertura\nsímbolo de citação direito",
-	frac14:"fração de um quarto\nfração de um quarto",
-	frac12:"fração de um meio\nfração de um meio",
-	frac34:"fração de três quartos\nfração de três quartos",
+	frac14:"fração de um quarto comum\nfração de um quarto",
+	frac12:"fração de um meio comum\nfração de um meio",
+	frac34:"fração de três quartos comum\nfração de três quartos",
 	iquest:"ponto de interrogação invertido\nponto de interrogação invertido",
 	Agrave:"Letra latina maiúscula A com acento grave\nletra latina maiúscula A com acento grave",
 	Aacute:"Letra latina maiúscula A com acento agudo",
@@ -69,7 +68,7 @@ define(
 	Uuml:"Letra latina maiúscula U com trema",
 	Yacute:"Letra latina maiúscula Y com acento agudo",
 	THORN:"Letra latina maiúscula THORN",
-	szlig:"Letra latina minúscula scharfes S\ness-zed",
+	szlig:"Letra latina minúscula scharfes s\ness-zed",
 	agrave:"Letra latina minúscula a com acento grave\nletra latina minúscula a com acento grave",
 	aacute:"Letra latina minúscula a com acento agudo",
 	acirc:"Letra latina minúscula a com acento circunflexo",
@@ -102,7 +101,6 @@ define(
 	yacute:"Letra latina minúscula y com acento agudo",
 	thorn:"Letra latina minúscula thorn",
 	yuml:"Letra latina minúscula y com trema",
-
 // Greek Characters and Symbols
 	fnof:"Letra latina minúscula f com gancho\nfunção\nflorim",
 	Alpha:"Letra grega maiúscula alfa",
@@ -159,11 +157,11 @@ define(
 	piv:"Símbolo grego pi",
 	bull:"marcador\npequeno círculo preto",
 	hellip:"reticências horizontais\ntrês pontos",
-	prime:"linha simples\nminutos\npés",
-	Prime:"linha dupla\nsegundos\npolegadas",
-	oline:"linha sobreposta\nlinha superior para espaçamento",
+	prime:"primário\nminutos\npés",
+	Prime:"primário duplo\nsegundos\npolegadas",
+	oline:"sobrelinha\nlinha sobreposta de espaçamento",
 	frasl:"barra de fração",
-	weierp:"P maiúsculo cursivo\npotência\np de Weierstrass",
+	weierp:"script com letra P maiúscula\nconjunto de potências\nWeierstrass p",
 	image:"letra I maiúscula gótica\nparte imaginária",
 	real:"letra R maiúscula gótica\nsímbolo da parte real",
 	trade:"símbolo de marca registrada",
@@ -183,24 +181,24 @@ define(
 	part:"diferença parcial",
 	exist:"existe pelo menos",
 	empty:"conjunto vazio\nconjunto nulo\ndiâmetro",
-	nabla:"nabla\ngradiente",
+	nabla:"nabla\ndiferença de retrógrado",
 	isin:"pertence a",
 	notin:"não pertence a",
 	ni:"contém",
-	prod:"produto de n elementos\nsímbolo de produto",
+	prod:"produto n-ary\nsinal de produto",
 	sum:"somatório de n elementos",
 	minus:"sinal de menos",
 	lowast:"asterisco",
-	radic:"raiz quadrada\nsímbolo de radical",
+	radic:"raiz quadrada\nsinal de radical",
 	prop:"proporcional a",
 	infin:"infinito",
 	ang:"ângulo",
-	and:"'e' lógico\nwedge",
-	or:"'ou' lógico\nvee",
-	cap:"intersecção\nintersecção",
-	cup:"união\nreunião","int":"integral",
+	and:"lógica e\nforça",
+	or:"lógica ou\nvee",
+	cap:"limite de\nintersecção",
+	cup:"união\ncopa","int":"integral",
 	there4:"para isso",
-	sim:"operador til\nvaria com\nigual a",
+	sim:"operador de til\nvaria com\nsemelhante a",
 	cong:"aproximadamente igual a",
 	asymp:"quase igual a\nassintótico a",
 	ne:"diferente de",
@@ -212,19 +210,19 @@ define(
 	nsub:"não está contido em",
 	sube:"está contido ou é igual a",
 	supe:"contém ou é igual a",
-	oplus:"círculo mais\nsoma direta",
-	otimes:"símbolo de vezes circulado\nproduto dos vetores",
-	perp:"up tack\nortogonal a\nperpendicular",
+	oplus:"circulado mais\nsoma direta",
+	otimes:"vezes circulado\nproduto de vetor",
+	perp:"desvio para cima\nortogonal para\nperpendicular",
 	sdot:"ponto de multiplicação",
-	lceil:"chave em L com o canto voltado para cima à esquerda\nAPL com o canto voltado para cima",
+	lceil:"teto esquerdo\nlance vertical APL",
 	rceil:"chave em L com o canto voltado para cima à direita",
-	lfloor:"chave em L com o canto voltado para baixo à esquerda\nAPL com o canto voltado para baixo",
+	lfloor:"piso esquerdo\nlance para baixo APL",
 	rfloor:"chave em L com o canto voltado para baixo à direita",
 	lang:"sinal de maior e menor para esquerda",
 	rang:"sinal de maior e menor para direita",
 	loz:"losango",
 	spades:"símbolo de espadas",
-	clubs:"símbolo de paus\ntrevo",
+	clubs:"símbolo de\npaustrevo",
 	hearts:"coração negro\nsímbolo de copas",
 	diams:"diamante negro",
 	OElig:"Ligação latina maiúscula OE",
@@ -256,5 +254,4 @@ define(
 	rsaquo:"aspa latina de abertura",
 	euro:"símbolo de euro"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/AutoSave.js b/dojox/editor/plugins/nls/ro/AutoSave.js
index 80fdf56..005c59f 100644
--- a/dojox/editor/plugins/nls/ro/AutoSave.js
+++ b/dojox/editor/plugins/nls/ro/AutoSave.js
@@ -1,18 +1,15 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Salvare",
-	"saveSettingLabelOn": "Setare interval auto-salvare...",
-	"saveSettingLabelOff": "Oprire auto-salvare",
-	"saveSettingdialogTitle": "Auto-salvare",
-	"saveSettingdialogDescription": "Specificare interval auto-salvare",
-	"saveSettingdialogParamName": "Interval auto-salvare",
+	"saveSettingLabelOn": "Setare interval de salvare automată...",
+	"saveSettingLabelOff": "Dezactivare salvare automată",
+	"saveSettingdialogTitle": "Salvare automată",
+	"saveSettingdialogDescription": "Specificaţi intervalul de salvare automată",
+	"saveSettingdialogParamName": "Interval salvare automată",
 	"saveSettingdialogParamLabel": "min",
 	"saveSettingdialogButtonOk": "Setare interval",
 	"saveSettingdialogButtonCancel": "Anulare",
 	"saveMessageSuccess": "Salvat la ${0}",
-	"saveMessageFail": "A eşuat să salveze la${0}"
+	"saveMessageFail": "A eşuat salvarea la ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/Blockquote.js b/dojox/editor/plugins/nls/ro/Blockquote.js
index e54a9ba..be27574 100644
--- a/dojox/editor/plugins/nls/ro/Blockquote.js
+++ b/dojox/editor/plugins/nls/ro/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
-	"blockquote": "Blockquote"
+	"blockquote": "Bloc citat"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/Breadcrumb.js b/dojox/editor/plugins/nls/ro/Breadcrumb.js
index fe945b2..9c454a3 100644
--- a/dojox/editor/plugins/nls/ro/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ro/Breadcrumb.js
@@ -1,14 +1,11 @@
 define(
-//begin v1.x content
 ({
-	"nodeActions": "Acţiuni ${nodeName}",
+	"nodeActions": "${nodeName} Acţiuni",
 	"selectContents": "Selectare conţinut",
 	"selectElement": "Selectare element",
 	"deleteElement": "Ştergere element",
 	"deleteContents": "Ştergere conţinut",
-	"moveStart": "Mutare cursor la început",
-	"moveEnd": "Mutare cursor la sfârşit"
+	"moveStart": "Mutaţi cursorul pentru a porni",
+	"moveEnd": "Mutaţi cursorul pentru a termina"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ro/CollapsibleToolbar.js
index e9a06a6..7877656 100644
--- a/dojox/editor/plugins/nls/ro/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ro/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Restrângere bară de unelte Editor",
 	"expand": "Expandare bară de unelte Editor"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/FindReplace.js b/dojox/editor/plugins/nls/ro/FindReplace.js
index bcea70b..e97b255 100644
--- a/dojox/editor/plugins/nls/ro/FindReplace.js
+++ b/dojox/editor/plugins/nls/ro/FindReplace.js
@@ -1,26 +1,23 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Găsire:",
 	"findTooltip": "Introduceţi textul de găsit",
 	"replaceLabel": "Înlocuire cu:",
-	"replaceTooltip": "Introduceţi textul cu care se înlocuieşte",
+	"replaceTooltip": "Introduceţi textul cu care să înlocuiţi",
 	"findReplace": "Găsire şi înlocuire",
 	"matchCase": "Potrivire majuscule",
 	"matchCaseTooltip": "Potrivire majuscule",
 	"backwards": "Înapoi",
-	"backwardsTooltip": "Căutaţi înapoi pentru text",
-	"replaceAllButton": "Înlocuire toate",
+	"backwardsTooltip": "Căutare înapoi pentru text",
+	"replaceAllButton": "Înlocuire tot",
 	"replaceAllButtonTooltip": "Înlocuiţi tot textul",
 	"findButton": "Găsire",
-	"findButtonTooltip": "Găsiţi textul",
+	"findButtonTooltip": "Găsiţi text",
 	"replaceButton": "Înlocuire",
-	"replaceButtonTooltip": "Înlocuiţi textul",
+	"replaceButtonTooltip": "Înlocuiţi text",
 	"replaceDialogText": "Au fost înlocuite ${0} apariţii.",
 	"eofDialogText": "Ultima apariţie ${0}",
-	"eofDialogTextFind": "găsită",
-	"eofDialogTextReplace": "înlocuită"
+	"eofDialogTextFind": "găsit",
+	"eofDialogTextReplace": "înlocuit"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/InsertAnchor.js b/dojox/editor/plugins/nls/ro/InsertAnchor.js
index 2525185..82eefc4 100644
--- a/dojox/editor/plugins/nls/ro/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ro/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Inserare ancoră",
 	title: "Proprietăţi ancoră",
@@ -8,6 +7,4 @@ define(
 	set: "Setare",
 	cancel: "Anulare"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/InsertEntity.js b/dojox/editor/plugins/nls/ro/InsertEntity.js
index b2cbe02..512c28c 100644
--- a/dojox/editor/plugins/nls/ro/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ro/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Inserare simbol"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/LocalImage.js b/dojox/editor/plugins/nls/ro/LocalImage.js
index 3c55be0..77a70a1 100644
--- a/dojox/editor/plugins/nls/ro/LocalImage.js
+++ b/dojox/editor/plugins/nls/ro/LocalImage.js
@@ -1,15 +1,12 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Inserare imagine",
 	url: "Imagine",
 	browse: "Răsfoire...",
 	text: "Descriere",
 	set: "Inserare",
-	invalidMessage: "Tip de fişier imagine nevalid",
-	prePopuTextUrl: "Introduceţi un URL de imagine",
-	prePopuTextBrowse: "sau răsfoiţi la un fişier local."
+	invalidMessage: "Tip de fişier imagine invalid",
+	prePopuTextUrl: "Introduceţi un URL imagine",
+	prePopuTextBrowse: " sau răsfoiţi la un fişier local."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/PageBreak.js b/dojox/editor/plugins/nls/ro/PageBreak.js
index a61ffbf..279f2b9 100644
--- a/dojox/editor/plugins/nls/ro/PageBreak.js
+++ b/dojox/editor/plugins/nls/ro/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Întrerupere pagină"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/PasteFromWord.js b/dojox/editor/plugins/nls/ro/PasteFromWord.js
index 04ec6b3..b32d368 100644
--- a/dojox/editor/plugins/nls/ro/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ro/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Lipire din Word",
-	"paste": "Lipire",
-	"cancel": "Anulare",
-	"instructions": "Lipiţi conţinut din Word în caeta de text de mai jos. După ce sunteţi mulţumit de conţinutul de inserat, apăsaţi butonul Lipire. Pentru a renunţa la inserarea textului, apăsaţi butonul Anulare."
+	"instructions": "Lipiţi conţinutul din Word în caseta text de mai jos. Când sunteţi satisfăcut cu conţinutul, pentru a insera, apăsaţi butonul Lipire. Pentru a renunţa la inserarea textului, apăsaţi butonul Anulare."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/Preview.js b/dojox/editor/plugins/nls/ro/Preview.js
index ab110ab..3ab67d0 100644
--- a/dojox/editor/plugins/nls/ro/Preview.js
+++ b/dojox/editor/plugins/nls/ro/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Previzualizare"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/SafePaste.js b/dojox/editor/plugins/nls/ro/SafePaste.js
index 92215f8..d943291 100644
--- a/dojox/editor/plugins/nls/ro/SafePaste.js
+++ b/dojox/editor/plugins/nls/ro/SafePaste.js
@@ -1,5 +1,5 @@
 define(
 ({
-	"instructions": "Lipirea directă este dezactivată. Vă rugăm lipiţi conţinutul în acest dialog folosind controalele standard de tastatură sau meniu pentru lipire. "
+	"instructions": "Lipirea directă este dezactivată. Vă rugăm lipiţi conţinutul în acest dialog folosind controalele standard de tastatură sau meniu pentru lipire."
 })
 );
diff --git a/dojox/editor/plugins/nls/ro/Save.js b/dojox/editor/plugins/nls/ro/Save.js
index 43190f1..951b12d 100644
--- a/dojox/editor/plugins/nls/ro/Save.js
+++ b/dojox/editor/plugins/nls/ro/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Salvare"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/ShowBlockNodes.js b/dojox/editor/plugins/nls/ro/ShowBlockNodes.js
index ea7f475..747938f 100644
--- a/dojox/editor/plugins/nls/ro/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ro/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Afişare bloc elemente HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/Smiley.js b/dojox/editor/plugins/nls/ro/Smiley.js
index 20b1f32..5ea3ba4 100644
--- a/dojox/editor/plugins/nls/ro/Smiley.js
+++ b/dojox/editor/plugins/nls/ro/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Inserare emoticoane",
 	emoticonSmile: "zâmbet",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "plâns",
 	emoticonHappy: "fericit"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/SpellCheck.js b/dojox/editor/plugins/nls/ro/SpellCheck.js
index 3d1245d..4254900 100644
--- a/dojox/editor/plugins/nls/ro/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ro/SpellCheck.js
@@ -1,21 +1,18 @@
 define(
-//begin v1.x content
 ({
-	widgetLabel: "Verificare ortografică lot",
+	widgetLabel: "Verificare ortografică batch",
 	unfound: "Nu a fost găsit",
-	skip: "Salt",
-	skipAll: "Salt toate",
+	skip: "Salt peste",
+	skipAll: "Se sar toate",
 	toDic: "Adăugare la dicţionar",
 	suggestions: "Sugestii",
 	replace: "Înlocuire",
 	replaceWith: "Înlocuire cu",
 	replaceAll: "Înlocuire toate",
 	cancel: "Anulare",
-	msg: "Nicio greşeală de verificare ortografică nu a fost găsită.",
-	iSkip: "Salt peste acesta",
-	iSkipAll: "Salt peste toate acestea",
-	iMsg: "Nicio sugestie de verificare ortografică"
+	msg: "Nu au fost găsite greşeli de scriere",
+	iSkip: "Salt peste aceasta",
+	iSkipAll: "Se sar toate ca aceasta",
+	iMsg: "Nu există sugestii de scriere corectă"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/TableDialog.js b/dojox/editor/plugins/nls/ro/TableDialog.js
index 1c26f55..3954ec4 100644
--- a/dojox/editor/plugins/nls/ro/TableDialog.js
+++ b/dojox/editor/plugins/nls/ro/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Inserare tabel",
 	modifyTableTitle: "Modificare tabel",
@@ -21,16 +20,14 @@ define(
 	buttonSet: "Setare", // translated elsewhere?
 	buttonInsert: "Inserare",
 	buttonCancel: "Anulare",
-
 	selectTableLabel: "Selectare tabelă",
 	insertTableRowBeforeLabel: "Adăugare rând înainte",
 	insertTableRowAfterLabel: "Adăugare rând după",
 	insertTableColumnBeforeLabel: "Adăugare coloană înainte",
 	insertTableColumnAfterLabel: "Adăugare coloană după",
 	deleteTableRowLabel: "Ştergere rând",
-	deleteTableColumnLabel: "Ştergere coloană"
+	deleteTableColumnLabel: "Ştergere coloană",
+	colorTableCellTitle: "Celulă tabel culoare fundal",
+	tableContextMenuTitle: "Meniu de context tabel"
 })
-	
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/TextColor.js b/dojox/editor/plugins/nls/ro/TextColor.js
index c31e4c1..1ca017e 100644
--- a/dojox/editor/plugins/nls/ro/TextColor.js
+++ b/dojox/editor/plugins/nls/ro/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Setare",
 	"cancelButtonText": "Anulare"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ro/latinEntities.js b/dojox/editor/plugins/nls/ro/latinEntities.js
index 0d0b654..f96b338 100644
--- a/dojox/editor/plugins/nls/ro/latinEntities.js
+++ b/dojox/editor/plugins/nls/ro/latinEntities.js
@@ -1,173 +1,171 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"semnul exclamării inversat",
 	cent:"semnul cent",
 	pound:"semnul liră sterlină",
 	curren:"semnul monedă",
-	yen:"semnul yen\nsemnul nyuan",
-	brvbar:"bară ruptă\nbară verticală ruptă",
+	yen:"semnul yen\nsemnul yuan",
+	brvbar:"bară întreruptă\nbară verticală întreruptă",
 	sect:"semn secţiune",
-	uml:"tremă\ntremă de spaţiere",
+	uml:"tremă\ntremă spaţiere",
 	copy:"semnul copyright",
 	ordf:"indicator ordinal feminin",
-	laquo:"ghilimele unghi dublu arătând spre stânga\nghilimele arătând spre stânga",
+	laquo:"semn de citare paranteză unghiulară dublă la stânga\nsemn de citare la stânga",
 	not:"semn nu",
 	shy:"liniuţă de despărţire soft\nliniuţă de despărţire discreţionară",
-	reg:"semn de înregistrare\nsemn de marcă înregistrată",
-	macr:"macron\nmacron de spaţiere\nlinie deasupra\nAPL linie deasupra",
+	reg:"semnul de înregistrat\nsemnul de marcă comercială înregistrată",
+	macr:"macron\nmacron spaţiere\nsupralinie\nsuprabară APL",
 	deg:"semn de grade",
 	plusmn:"semn plus-minus\nsemn plus-sau-minus",
-	sup2:"scriere indice superior doi\nscriere indice superior cifră doi\npătrat",
-	sup3:"scriere indice superior trei\nscriere indice superior cifră trei\ncub",
-	acute:"accent acut\nspaţiere acută",
+	sup2:"doi ca indice superior\ncifra doi ca indice superior\nla pătrat",
+	sup3:"trei ca indice superior\ncifra trei ca indice superior\nla cub",
+	acute:"accent ascuţit\nascuţit spaţiere",
 	micro:"semn micro",
-	para:"semn pilcrow\nsemn paragraf",
-	middot:"punct de mijloc\nvirgulă georgiană\npunct de mijloc grec",
-	cedil:"sedila\nsedila de spaţiere",
-	sup1:"scriere indice superior unu\nscriere indice superior cifră unu",
+	para:"semn pilcrow\nsemn de paragraf",
+	middot:"punct median\nvirgulă georgiană\npunct median grecesc",
+	cedil:"sedilă\nsedilă spaţiere",
+	sup1:"unu ca indice superior\ncifra unu ca indice superior",
 	ordm:"indicator ordinal masculin",
-	raquo:"ghilimele unghi dublu arătând spre dreapta\nghilimele arătând spre dreapta",
-	frac14:"fracţie ordinară un sfert\nfracţie un sfert",
-	frac12:"fracţie ordinară o jumătate\nfracţie o jumătate",
-	frac34:"fracţie ordinară trei sferturi\nfracţie trei sferturi",
+	raquo:"semn de citare paranteză unghiulară dublă la dreapta\nsemn de citare la dreapta",
+	frac14:"fracţie obişnuită un sfert\nfracţie un sfert",
+	frac12:"fracţie obişnuită jumătate\nfracţie jumătate",
+	frac34:"fracţie obişnuită trei sferturi\nfracţie trei sferturi",
 	iquest:"semn de întrebare inversat\nsemn de întrebare răsturnat",
-	Agrave:"Literă mare latină A cu accent grav\nLiteră mare latină A grav",
-	Aacute:"Literă mare latină A cu accent acut",
-	Acirc:"Literă mare latină A cu circumflex",
-	Atilde:"Literă mare latină A cu tilda",
-	Auml:"Literă mare latină A cu tremă",
-	Aring:"Literă mare latină A cu inel deasupra\nLiteră mare latină A cu inel",
-	AElig:"Literă mare latină AE\nLigatură mare latină AE",
-	Ccedil:"Literă mare latină C cu sedilă",
-	Egrave:"Literă mare latină E cu accent grav",
-	Eacute:"Literă mare latină E cu accent acut",
-	Ecirc:"Literă mare latină E cu circumflex",
-	Euml:"Literă mare latină E cu tremă",
-	Igrave:"Literă mare latină I cu accent grav",
-	Iacute:"Literă mare latină I cu accent acut",
-	Icirc:"Literă mare latină I cu circumflex",
-	Iuml:"Literă mare latină I cu tremă",
-	ETH:"Literă mare latină ETH",
-	Ntilde:"Literă mare latină N cu tilda",
-	Ograve:"Literă mare latină O cu accent grav",
-	Oacute:"Literă mare latină O cu accent acut",
-	Ocirc:"Literă mare latină O cu circumflex",
-	Otilde:"Literă mare latină O cu tilda",
-	Ouml:"Literă mare latină O cu tremă",
-	times:"semn de înmulţire",
-	Oslash:"Literă latină majusculă O cu linie de taiere\nLiteră latină majusculă O cu o linie oblică",
-	Ugrave:"Literă mare latină U cu accent grav",
-	Uacute:"Literă mare latină U cu accent acut",
-	Ucirc:"Literă mare latină U cu circumflex",
-	Uuml:"Literă mare latină U cu tremă",
-	Yacute:"Literă mare latină Y cu accent acut",
-	THORN:"Literă mare latină THORN",
-	szlig:"Literă latină mică s diez\ness-zed",
-	agrave:"Literă latină mică a cu accent grav\nLiteră latină mică a grav",
-	aacute:"Literă latină mică a cu accent acut",
-	acirc:"Literă latină mică a cu circumflex",
-	atilde:"Literă latină mică a cu tilda",
-	auml:"Literă latină mică a cu tremă",
-	aring:"Literă latină mică a cu inel deasupra\nLiteră latină mică a cu inel",
-	aelig:"Literă latină mică ae\nLigatură latină mică ae",
-	ccedil:"Literă latină mică c cu sedilă",
-	egrave:"Literă latină mică e cu accent grav",
-	eacute:"Literă latină mică e cu accent acut",
-	ecirc:"Literă latină mică e cu circumflex",
-	euml:"Literă latină mică e cu tremă",
-	igrave:"Literă latină mică i cu accent grav",
-	iacute:"Literă latină mică i cu accent acut",
-	icirc:"Literă latină mică i cu circumflex",
-	iuml:"Literă latină mică i cu tremă",
-	eth:"Literă latină mică eth",
-	ntilde:"Literă latină mică n cu tilda",
-	ograve:"Literă latină mică o cu accent grav",
-	oacute:"Literă latină mică o cu accent acut",
-	ocirc:"Literă latină mică o cu circumflex",
-	otilde:"Literă latină mică o cu tilda",
-	ouml:"Literă latină mică o cu tremă",
-	divide:"semn împărţire",
-	oslash:"Literă latină mică o cu linie de taiere\nLiteră latină mică o cu o linie oblică",
-	ugrave:"Literă latină mică u cu accent grav",
-	uacute:"Literă latină mică u cu accent acut",
-	ucirc:"Literă latină mică u cu circumflex",
-	uuml:"Literă latină mică u cu tremă",
-	yacute:"Literă latină mică y cu accent acut",
-	thorn:"Literă latină mică thorn",
-	yuml:"Literă latină mică y cu tremă",
-
+	Agrave:"literă mare latină A cu accent grav\nliteră mare latină A grav",
+	Aacute:"literă mare latină A cu accent ascuţit",
+	Acirc:"literă mare latină A cu circumflex",
+	Atilde:"literă mare latină A cu tilda",
+	Auml:"literă mare latină A cu tremă",
+	Aring:"literă mare latină A cu cerculeţ deasupra\nliteră mare latină A cerculeţ",
+	AElig:"literă mare latină AE\nligatură mare latină AE",
+	Ccedil:"literă mare latină C cu sedilă",
+	Egrave:"literă mare latină E cu grav",
+	Eacute:"literă mare latină E cu ascuţit",
+	Ecirc:"literă mare latină E cu circumflex",
+	Euml:"literă mare latină E cu tremă",
+	Igrave:"literă mare latină I cu grav",
+	Iacute:"literă mare latină I cu ascuţit",
+	Icirc:"literă mare latină I cu circumflex",
+	Iuml:"literă mare latină I cu tremă",
+	ETH:"literă mare latină ETH",
+	Ntilde:"literă mare latină N cu tilda",
+	Ograve:"literă mare latină O cu grav",
+	Oacute:"literă mare latină O cu ascuţit",
+	Ocirc:"literă mare latină O cu circumflex",
+	Otilde:"literă mare latină O cu tilda",
+	Ouml:"literă mare latină O cu tremă",
+	times:"semnul înmulţire",
+	Oslash:"literă mare latină O cu liniuţă\nliteră mare latină O slash",
+	Ugrave:"literă mare latină U cu grav",
+	Uacute:"literă mare latină U cu ascuţit",
+	Ucirc:"literă mare latină U cu circumflex",
+	Uuml:"literă mare latină U cu tremă",
+	Yacute:"literă mare latină Y cu ascuţit",
+	THORN:"literă mare latină THORN",
+	szlig:"literă latină mică s ascuţit\ns zeta",
+	agrave:"literă latină mică a cu grav\nliteră latină mică a cu grav",
+	aacute:"literă latină mică a cu ascuţit",
+	acirc:"literă latină mică a cu circumflex",
+	atilde:"literă latină mică a cu tilda",
+	auml:"literă latină mică a cu tremă",
+	aring:"literă latină mică cu cerculeţ deasupra\nliteră latină mică cu cerculeţ",
+	aelig:"literă latină mică ae\nligatură latină mică ae",
+	ccedil:"literă latină mică c cu sedilă",
+	egrave:"literă latină mică e cu grav",
+	eacute:"literă latină mică e ascuţit",
+	ecirc:"literă latină mică e cu circumflex",
+	euml:"literă latină mică e cu tremă",
+	igrave:"literă latină mică i cu grav",
+	iacute:"literă latină mică i cu ascuţit",
+	icirc:"literă latină mică i cu circumflex",
+	iuml:"literă latină mică i cu tremă",
+	eth:"literă latină mică eth",
+	ntilde:"literă latină mică n cu tilda",
+	ograve:"literă latină mică o cu grav",
+	oacute:"literă latină mică o cu ascuţit",
+	ocirc:"literă latină mică o cu circumflex",
+	otilde:"literă latină mică o cu tilda",
+	ouml:"literă latină mică o cu tremă",
+	divide:"semnul împărţire",
+	oslash:"literă latină mică o cu liniuţă\nliteră latină mică o slash",
+	ugrave:"literă latină mică u cu grav",
+	uacute:"literă latină mică u cu ascuţit",
+	ucirc:"literă latină mică u cu circumflex",
+	uuml:"literă latină mică u cu tremă",
+	yacute:"literă latină mică y cu ascuţit",
+	thorn:"literă latină mică thorn",
+	yuml:"literă latină mică y cu tremă",
 // Greek Characters and Symbols
-	fnof:"Literă latină mică f cu cârlig\nfuncţie\nflorin",
-	Alpha:"Literă greacă mare alfa",
-	Beta:"Literă greacă mare beta",
-	Gamma:"Literă greacă mare gamma",
-	Delta:"Literă greacă mare delta",
-	Epsilon:"Literă greacă mare epsilon",
-	Zeta:"Literă greacă mare zeta",
-	Eta:"Literă greacă mare eta",
-	Theta:"Literă greacă mare theta",
-	Iota:"Literă greacă mare iota",
-	Kappa:"Literă greacă mare kappa",
-	Lambda:"Literă greacă mare lambda",
-	Mu:"Literă greacă mare miu",
-	Nu:"Literă greacă mare niu",
-	Xi:"Literă greacă mare xi",
-	Omicron:"Literă greacă mare omicron",
-	Pi:"Literă greacă mare pi",
-	Rho:"Literă greacă mare rho",
-	Sigma:"Literă greacă mare sigma",
-	Tau:"Literă greacă mare tau",
-	Upsilon:"Literă greacă mare upsilon",
-	Phi:"Literă greacă mare phi",
-	Chi:"Literă greacă mare chi",
-	Psi:"Literă greacă mare psi",
-	Omega:"Literă greacă mare omega",
-	alpha:"Literă greacă mică alfa",
-	beta:"Literă greacă mică beta",
-	gamma:"Literă greacă mică gamma",
-	delta:"Literă greacă mică delta",
-	epsilon:"Literă greacă mică epsilon",
-	zeta:"Literă greacă mică zeta",
-	eta:"Literă greacă mică eta",
-	theta:"Literă greacă mică theta",
-	iota:"Literă greacă mică iota",
-	kappa:"Literă greacă mică kappa",
-	lambda:"Literă greacă mică lambda",
-	mu:"Literă greacă mică miu",
-	nu:"Literă greacă mică niu",
-	xi:"Literă greacă mică xi",
-	omicron:"Literă greacă mică omicron",
-	pi:"Literă greacă mică pi",
-	rho:"Literă greacă mică rho",
-	sigmaf:"Literă greacă mică sigma final",
-	sigma:"Literă greacă mică sigma",
-	tau:"Literă greacă mică tau",
-	upsilon:"Literă greacă mică upsilon",
-	phi:"Literă greacă mică phi",
-	chi:"Literă greacă mică chi",
-	psi:"Literă greacă mică psi",
-	omega:"Literă greacă mică omega",
-	thetasym:"Literă greacă mică simbol theta",
-	upsih:"Simbolul grec upsilon cu cârlig",
-	piv:"Simbolul grec pi",
+	fnof:"f mic latin cu cârlig\nfuncţie\nflorin",
+	Alpha:"literă greacă mare alfa",
+	Beta:"literă greacă mare beta",
+	Gamma:"literă greacă mare gamma",
+	Delta:"literă greacă mare delta",
+	Epsilon:"literă greacă mare epsilon",
+	Zeta:"literă greacă mare zeta",
+	Eta:"literă greacă mare eta",
+	Theta:"literă greacă mare theta",
+	Iota:"literă greacă mare iota",
+	Kappa:"literă greacă mare kappa",
+	Lambda:"literă greacă mare lambda",
+	Mu:"literă greacă mare miu",
+	Nu:"literă greacă mare niu",
+	Xi:"literă greacă mare xi",
+	Omicron:"literă greacă mare omicron",
+	Pi:"literă greacă mare pi",
+	Rho:"literă greacă mare rho",
+	Sigma:"literă greacă mare sigma",
+	Tau:"literă greacă mare tau",
+	Upsilon:"literă greacă mare upsilon",
+	Phi:"literă greacă mare phi",
+	Chi:"literă greacă mare chi",
+	Psi:"literă greacă mare psi",
+	Omega:"literă greacă mare omega",
+	alpha:"literă greacă mică alfa",
+	beta:"literă greacă mică beta",
+	gamma:"literă greacă mică gamma",
+	delta:"literă greacă mică delta",
+	epsilon:"literă greacă mică epsilon",
+	zeta:"literă greacă mică zeta",
+	eta:"literă greacă mică eta",
+	theta:"literă greacă mică theta",
+	iota:"literă greacă mică iota",
+	kappa:"literă greacă mică kappa",
+	lambda:"literă greacă mică lambda",
+	mu:"literă greacă mică miu",
+	nu:"literă greacă mică niu",
+	xi:"literă greacă mică xi",
+	omicron:"literă greacă mică omicron",
+	pi:"literă greacă mică pi",
+	rho:"literă greacă mică rho",
+	sigmaf:"literă greacă mică sigma final",
+	sigma:"literă greacă mică sigma",
+	tau:"literă greacă mică tau",
+	upsilon:"literă greacă mică upsilon",
+	phi:"literă greacă mică phi",
+	chi:"literă greacă mică chi",
+	psi:"literă greacă mică psi",
+	omega:"literă greacă mică omega",
+	thetasym:"literă greacă mică simbol theta",
+	upsih:"simbolul grec upsilon cu cârlig",
+	piv:"simbolul grec pi",
 	bull:"bullet\ncerc mic negru",
-	hellip:"elipse orizontale\ntrei puncte precursoare",
+	hellip:"elipsă orizontală\ntrei puncte",
 	prime:"prim\nminute\npicioare",
-	Prime:"prim dublu\nsecunde\nţoli",
-	oline:"linie deasupra\nlinie de spaţiere deasupra",
+	Prime:"prim dublu\nsecunde\ninch",
+	oline:"supralinie\ntăiere spaţiere",
 	frasl:"linie fracţie",
-	weierp:"script capital P\nputere\np Weierstrass",
-	image:"I majusculă înnegrită\nparte imaginară",
-	real:"R majusculă înnegrită\nsimbol parte reală",
-	trade:"semn marcă înregistrată",
-	alefsym:"simbol alef\nprimul cardinal transfinit",
+	weierp:"litera P mare de mână\nmulţimea submulţimilor\np Weierstrass",
+	image:"litera I mare neagră\npartea imaginară",
+	real:"litera R mare neagră\nsimbolul părţii reale",
+	trade:"semnul de marcă înregistrată",
+	alefsym:"simbolul alef\nprimul cardinal transfinit",
 	larr:"săgeată spre stânga",
 	uarr:"săgeata în sus",
 	rarr:"săgeată spre dreapta",
@@ -182,25 +180,25 @@ define(
 	forall:"pentru toate",
 	part:"diferenţiale parţiale",
 	exist:"Există",
-	empty:"set gol\nset null\ndiametru",
-	nabla:"nabla\ndiferenţa înapoi",
+	empty:"mulţime vidă\nmulţime nulă\ndiametru",
+	nabla:"nabla\ndiferenţă înapoi",
 	isin:"element al",
 	notin:"nu este un element al",
 	ni:"conţine ca membru",
-	prod:"n produs\nsemnul produs",
-	sum:"n suma",
+	prod:"produs cu n termeni\nsemnul produs",
+	sum:"sumă cu n termeni",
 	minus:"semnul minus",
-	lowast:"operatorul asterisk",
+	lowast:"operatorul asterisc",
 	radic:"rădăcină pătrată\nsemnul radical",
 	prop:"proporţional cu",
 	infin:"infinit",
 	ang:"unghi",
-	and:"şi logic\npană",
+	and:"şi logic\ncăciulă",
 	or:"sau logic\nV",
-	cap:"intersecţie\ncăciulă",
-	cup:"reuniune\ncupă","int":"integral",
+	cap:"intersecţie\nU răsturnat",
+	cup:"uniune\nU","int":"integrală",
 	there4:"de aceea",
-	sim:"operator tilda\nvariază cu\nsimilar cu",
+	sim:"operatorul tilde\nvariază cu\nsimilar cu",
 	cong:"aproximativ egal cu",
 	asymp:"aproape egal cu\nasimptotic la",
 	ne:"nu este egal cu",
@@ -213,25 +211,25 @@ define(
 	sube:"subset al sau egal cu",
 	supe:"superset al sau egal cu",
 	oplus:"plus încercuit\nsumă directă",
-	otimes:"multiplicator încercuit\nprodus vectorial",
-	perp:"up tack\northogonal to\nperpendicular",
+	otimes:"Semnul înmulţirii încercuit\nprodus vectorial",
+	perp:"T răsturnat\nortogonal\nperpendicular",
 	sdot:"operator punct",
-	lceil:"plafon stânga\nAPL upstile",
+	lceil:"plafon stânga\nupstile APL",
 	rceil:"plafon dreapta",
-	lfloor:"podea stânga\nAPL downstile",
+	lfloor:"plafon dreapta\ndownstile APL",
 	rfloor:"podea dreapta",
 	lang:"paranteză unghiulară spre stânga",
 	rang:"paranteză unghiulară spre dreapta",
 	loz:"romb",
 	spades:"treflă neagră",
-	clubs:"pică neagră\nshamrock",
-	hearts:"inimă neagră\nvalentine",
-	diams:"romb negru",
-	OElig:"Ligatură mare latină OE",
-	oelig:"Ligatură mică latină oe",
-	Scaron:"Literă mare latină S cu caron",
-	scaron:"Literă mică latină s cu caron",
-	Yuml:"Literă mare latină Y cu tremă",
+	clubs:"pică neagră\ntrifoi",
+	hearts:"cupă neagră\ninimă",
+	diams:"caro negru",
+	OElig:"ligatură mare latină OE",
+	oelig:"ligatură mică latină oe",
+	Scaron:"literă mare latină S cu caron",
+	scaron:"literă mică latină s cu caron",
+	Yuml:"literă mare latină Y cu tremă",
 	circ:"accent circumflex modificator de literă",
 	tilde:"tilda mică",
 	ensp:"spaţiu en",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"ghilimele singure unghiulare spre dreapta",
 	euro:"semn euro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/AutoSave.js b/dojox/editor/plugins/nls/ru/AutoSave.js
index 3a4ff60..d65141d 100644
--- a/dojox/editor/plugins/nls/ru/AutoSave.js
+++ b/dojox/editor/plugins/nls/ru/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Сохранить",
 	"saveSettingLabelOn": "Задать интервал автосохранения...",
@@ -9,10 +8,8 @@ define(
 	"saveSettingdialogParamName": "Интервал автосохранения",
 	"saveSettingdialogParamLabel": "мин",
 	"saveSettingdialogButtonOk": "Задать интервал",
-	"saveSettingdialogButtonCancel": "Отменить",
+	"saveSettingdialogButtonCancel": "Отмена",
 	"saveMessageSuccess": "Сохранено ${0}",
 	"saveMessageFail": "Не удалось сохранить ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/Blockquote.js b/dojox/editor/plugins/nls/ru/Blockquote.js
index 4e4fb24..3155779 100644
--- a/dojox/editor/plugins/nls/ru/Blockquote.js
+++ b/dojox/editor/plugins/nls/ru/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Блок цитат"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/Breadcrumb.js b/dojox/editor/plugins/nls/ru/Breadcrumb.js
index e8eab41..f66be0e 100644
--- a/dojox/editor/plugins/nls/ru/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/ru/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName}: действия",
 	"selectContents": "Выбрать содержимое",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Поместить курсор в начало",
 	"moveEnd": "Поместить курсор в конец"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ru/CollapsibleToolbar.js
index ac38dcd..285913e 100644
--- a/dojox/editor/plugins/nls/ru/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/ru/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Свернуть панель редактирования",
 	"expand": "Развернуть панель редактирования"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/FindReplace.js b/dojox/editor/plugins/nls/ru/FindReplace.js
index c9f07d2..ccd4fe4 100644
--- a/dojox/editor/plugins/nls/ru/FindReplace.js
+++ b/dojox/editor/plugins/nls/ru/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Найти:",
 	"findTooltip": "Введите текст для поиска",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "найдено",
 	"eofDialogTextReplace": "заменено"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/InsertAnchor.js b/dojox/editor/plugins/nls/ru/InsertAnchor.js
index af7049d..eda986c 100644
--- a/dojox/editor/plugins/nls/ru/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/ru/InsertAnchor.js
@@ -1,13 +1,10 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Вставить метку",
 	title: "Свойства метки",
 	anchor: "Имя:",
 	text: "Описание:",
 	set: "Задать",
-	cancel: "Отменить"
+	cancel: "Отмена"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/InsertEntity.js b/dojox/editor/plugins/nls/ru/InsertEntity.js
index 7b84bd7..e5299cc 100644
--- a/dojox/editor/plugins/nls/ru/InsertEntity.js
+++ b/dojox/editor/plugins/nls/ru/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Вставить символ"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/LocalImage.js b/dojox/editor/plugins/nls/ru/LocalImage.js
index 0cd3b4a..7864635 100644
--- a/dojox/editor/plugins/nls/ru/LocalImage.js
+++ b/dojox/editor/plugins/nls/ru/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Вставить изображение",
 	url: "Изображение",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Введите URL изображения",
 	prePopuTextBrowse: " или выберите локальный файл."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/PageBreak.js b/dojox/editor/plugins/nls/ru/PageBreak.js
index db902d9..1d2a5d8 100644
--- a/dojox/editor/plugins/nls/ru/PageBreak.js
+++ b/dojox/editor/plugins/nls/ru/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Разделитель страниц"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/PasteFromWord.js b/dojox/editor/plugins/nls/ru/PasteFromWord.js
index 0516494..8c62455 100644
--- a/dojox/editor/plugins/nls/ru/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/ru/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Вставить из Word",
-	"paste": "Вставить",
-	"cancel": "Отменить",
 	"instructions": "Вставить содержимое из Word в текстовое поле ниже.  Когда выберите содержимое для вставки, нажмите кнопку Вставить.  Для отмены вставки текста нажмите кнопку Отмена."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/Preview.js b/dojox/editor/plugins/nls/ru/Preview.js
index 9a6d321..1c12239 100644
--- a/dojox/editor/plugins/nls/ru/Preview.js
+++ b/dojox/editor/plugins/nls/ru/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Предварительный просмотр"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/SafePaste.js b/dojox/editor/plugins/nls/ru/SafePaste.js
index 84575b6..72d526d 100644
--- a/dojox/editor/plugins/nls/ru/SafePaste.js
+++ b/dojox/editor/plugins/nls/ru/SafePaste.js
@@ -1,5 +1,5 @@
 define(
 ({
-	"instructions": "Прямая вставка отключена. Вставьте содержимое в этот диалог при помощи стандартной клавиатуры браузера или управляющих команд вставки в меню. Когда выберите содержимое для вставки, нажмите кнопку Вставить. Для отмены вставки содержимого нажмите кнопку Отмена."
+	"instructions": "Вставка напрямую выключена. Вставьте данные в это окно с помощью стандартной клавиатуры браузера или пунктов меню. Когда выберите содержимое для вставки, нажмите кнопку Вставить.  Для отмены вставки текста нажмите кнопку Отмена. "
 })
 );
diff --git a/dojox/editor/plugins/nls/ru/Save.js b/dojox/editor/plugins/nls/ru/Save.js
index 7b6387b..678cf07 100644
--- a/dojox/editor/plugins/nls/ru/Save.js
+++ b/dojox/editor/plugins/nls/ru/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Сохранить"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/ShowBlockNodes.js b/dojox/editor/plugins/nls/ru/ShowBlockNodes.js
index ce18788..3b59a60 100644
--- a/dojox/editor/plugins/nls/ru/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/ru/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Показать элементы блока HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/Smiley.js b/dojox/editor/plugins/nls/ru/Smiley.js
index f32aa59..397a152 100644
--- a/dojox/editor/plugins/nls/ru/Smiley.js
+++ b/dojox/editor/plugins/nls/ru/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Вставить значок настроения",
 	emoticonSmile: "улыбка",
@@ -20,8 +19,6 @@ define(
 	emoticonNo: "нет",
 	emoticonAngel: "ангел",
 	emoticonCrying: "плачь",
-	emoticonHappy: "счастлив"
+	emoticonHappy: "счастье"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/SpellCheck.js b/dojox/editor/plugins/nls/ru/SpellCheck.js
index a95cfa9..ef88451 100644
--- a/dojox/editor/plugins/nls/ru/SpellCheck.js
+++ b/dojox/editor/plugins/nls/ru/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Проверка орфографии",
 	unfound: "Не найдено",
@@ -10,12 +9,10 @@ define(
 	replace: "Заменить",
 	replaceWith: "Заменить на",
 	replaceAll: "Заменить все",
-	cancel: "Отменить",
+	cancel: "Отмена",
 	msg: "Ошибок не найдено",
 	iSkip: "Пропустить это",
-	iSkipAll: "Пропусть все схожие",
+	iSkipAll: "Пропустить все схожие",
 	iMsg: "Нет вариантов написания"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/TableDialog.js b/dojox/editor/plugins/nls/ru/TableDialog.js
index d43894e..be7f3fe 100644
--- a/dojox/editor/plugins/nls/ru/TableDialog.js
+++ b/dojox/editor/plugins/nls/ru/TableDialog.js
@@ -1,17 +1,16 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Вставить таблицу",
 	modifyTableTitle: "Изменить таблицу",
-	rows: "Строк:",
-	columns: "Столбцов:",
-	align: "Выровнять:",
+	rows: "Число строк:",
+	columns: "Число столбцов:",
+	align: "Выравнивание:",
 	cellPadding: "Отступ внутри ячеек:",
 	cellSpacing: "Расстояние между ячейками:",
 	tableWidth: "Ширина таблицы:",
 	backgroundColor: "Цвет фона:",
 	borderColor: "Цвет рамки:",
-	borderThickness: "Толщина рамки",
+	borderThickness: "Толщина рамки:",
 	percent: "процентов",
 	pixels: "пикселов",
 	"default": "по умолчанию",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Задать", // translated elsewhere?
 	buttonInsert: "Вставить",
 	buttonCancel: "Отмена",
-
 	selectTableLabel: "Выбрать таблицу",
 	insertTableRowBeforeLabel: "Добавить строку перед",
 	insertTableRowAfterLabel: "Добавить строку после",
 	insertTableColumnBeforeLabel: "Добавить столбец перед",
 	insertTableColumnAfterLabel: "Добавить столбец после",
 	deleteTableRowLabel: "Удалить строку",
-	deleteTableColumnLabel: "Удалить столбец"
+	deleteTableColumnLabel: "Удалить столбец",
+	colorTableCellTitle: "Цвет фона - ячейка таблицы",
+	tableContextMenuTitle: "Контекстное меню таблицы"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/TextColor.js b/dojox/editor/plugins/nls/ru/TextColor.js
index 2404dbf..d0846e0 100644
--- a/dojox/editor/plugins/nls/ru/TextColor.js
+++ b/dojox/editor/plugins/nls/ru/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Задать",
-	"cancelButtonText": "Отменить"
+	"cancelButtonText": "Отмена"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/ru/latinEntities.js b/dojox/editor/plugins/nls/ru/latinEntities.js
index 94ccd07..fa17304 100644
--- a/dojox/editor/plugins/nls/ru/latinEntities.js
+++ b/dojox/editor/plugins/nls/ru/latinEntities.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"инвертированный восклицательный знак",
 	cent:"символ цента",
@@ -17,7 +16,7 @@ define(
 	uml:"трема\nтрема с интервалом",
 	copy:"символ авторских прав",
 	ordf:"индикатор женского рода",
-	laquo:"левые двойный угловые кавычки\nлевые кавычки",
+	laquo:"левые двойные угловые кавычки\nлевые кавычки",
 	not:"знак отрицания",
 	shy:"мягкий перенос\nвозможный перенос",
 	reg:"символ Зарегистрирован\nсимвол зарегистрированного товарного знака",
@@ -69,7 +68,7 @@ define(
 	Uuml:"латинская прописная буква U с тремой",
 	Yacute:"латинская прописная буква Y с акутом",
 	THORN:"латинская прописная буква THORN",
-	szlig:"латинская строчная заостренная s\nэсцэт",
+	szlig:"латинская строчная заостренная эсцэт",
 	agrave:"латинская строчная буква a с грависом\nлатинская строчная a с грависом",
 	aacute:"латинская строчная буква a с акутом",
 	acirc:"латинская строчная буква a с циркумфлексом",
@@ -102,7 +101,6 @@ define(
 	yacute:"латинская строчная буква y с акутом",
 	thorn:"латинская строчная буква thorn",
 	yuml:"латинская строчная буква y с тремой",
-
 // Greek Characters and Symbols
 	fnof:"латинская строчная буква f с хвостиком\nфункция\nфлорин",
 	Alpha:"греческая прописная буква альфа",
@@ -224,7 +222,7 @@ define(
 	rang:"правая угловая скобка",
 	loz:"ромб",
 	spades:"пики",
-	clubs:"крести\nтрилистник",
+	clubs:"трефы\nтрилистник",
 	hearts:"червы\nвалентинка",
 	diams:"бубны",
 	OElig:"латинская прописная лигатура OE",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"одинарная правая угловая кавычка",
 	euro:"символ евро"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/AutoSave.js b/dojox/editor/plugins/nls/sk/AutoSave.js
index fb98ddc..2946a59 100644
--- a/dojox/editor/plugins/nls/sk/AutoSave.js
+++ b/dojox/editor/plugins/nls/sk/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Uložiť",
 	"saveSettingLabelOn": "Nastaviť interval automatického ukladania...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Uložené o ${0}",
 	"saveMessageFail": "Zlyhalo ukladanie o ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/Blockquote.js b/dojox/editor/plugins/nls/sk/Blockquote.js
index e54a9ba..8f18d04 100644
--- a/dojox/editor/plugins/nls/sk/Blockquote.js
+++ b/dojox/editor/plugins/nls/sk/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
-	"blockquote": "Blockquote"
+	"blockquote": "Blok citátu"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/Breadcrumb.js b/dojox/editor/plugins/nls/sk/Breadcrumb.js
index 8024961..fc71227 100644
--- a/dojox/editor/plugins/nls/sk/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/sk/Breadcrumb.js
@@ -1,14 +1,11 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "Akcie pre ${nodeName}",
 	"selectContents": "Vybrať obsah",
-	"selectElement": "Vybrať element",
-	"deleteElement": "Vymazať element",
+	"selectElement": "Vybrať prvok",
+	"deleteElement": "Vymazať prvok",
 	"deleteContents": "Vymazať obsah",
 	"moveStart": "Presunúť kurzor na začiatok",
 	"moveEnd": "Presunúť kurzor na koniec"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/CollapsibleToolbar.js b/dojox/editor/plugins/nls/sk/CollapsibleToolbar.js
index f33361f..6bb4adc 100644
--- a/dojox/editor/plugins/nls/sk/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/sk/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Zvinúť lištu nástrojov editora",
 	"expand": "Rozvinúť lištu nástrojov editora"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/FindReplace.js b/dojox/editor/plugins/nls/sk/FindReplace.js
index eb17817..3a494ca 100644
--- a/dojox/editor/plugins/nls/sk/FindReplace.js
+++ b/dojox/editor/plugins/nls/sk/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Hľadať:",
 	"findTooltip": "Zadajte text na nájdenie",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "nájdený",
 	"eofDialogTextReplace": "nahradený"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/InsertAnchor.js b/dojox/editor/plugins/nls/sk/InsertAnchor.js
index c0e7fd1..ab0a93d 100644
--- a/dojox/editor/plugins/nls/sk/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/sk/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Vložiť kotvu",
 	title: "Vlastnosti kotvy",
@@ -8,6 +7,4 @@ define(
 	set: "Nastaviť",
 	cancel: "Zrušiť"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/InsertEntity.js b/dojox/editor/plugins/nls/sk/InsertEntity.js
index 21b78e0..6f5869f 100644
--- a/dojox/editor/plugins/nls/sk/InsertEntity.js
+++ b/dojox/editor/plugins/nls/sk/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Vložiť symbol"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/LocalImage.js b/dojox/editor/plugins/nls/sk/LocalImage.js
index ead9996..d7b4ec5 100644
--- a/dojox/editor/plugins/nls/sk/LocalImage.js
+++ b/dojox/editor/plugins/nls/sk/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Vložiť obrázok",
 	url: "Obrázok",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Zadajte adresu URL",
 	prePopuTextBrowse: "alebo nájdite lokálny súbor."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/PageBreak.js b/dojox/editor/plugins/nls/sk/PageBreak.js
index cd8ab7f..1376075 100644
--- a/dojox/editor/plugins/nls/sk/PageBreak.js
+++ b/dojox/editor/plugins/nls/sk/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Zlom strany"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/PasteFromWord.js b/dojox/editor/plugins/nls/sk/PasteFromWord.js
index 7f55f02..5b62261 100644
--- a/dojox/editor/plugins/nls/sk/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/sk/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Prilepiť z aplikácie Word",
-	"paste": "Prilepiť",
-	"cancel": "Zrušiť",
 	"instructions": "Prilepte obsah z aplikácie Word do textového okienka dole. Keď ste spokojný s obsahom na vloženie, stlačte tlačidlo prilepenia. Ak chcete zrušiť vkladanie textu, stlačte tlačidlo zrušenia."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/Preview.js b/dojox/editor/plugins/nls/sk/Preview.js
index 5d71a73..c0788ac 100644
--- a/dojox/editor/plugins/nls/sk/Preview.js
+++ b/dojox/editor/plugins/nls/sk/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Náhľad"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/Save.js b/dojox/editor/plugins/nls/sk/Save.js
index c7f6f70..e5a2552 100644
--- a/dojox/editor/plugins/nls/sk/Save.js
+++ b/dojox/editor/plugins/nls/sk/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Uložiť"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/ShowBlockNodes.js b/dojox/editor/plugins/nls/sk/ShowBlockNodes.js
index 6501004..e614590 100644
--- a/dojox/editor/plugins/nls/sk/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/sk/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Zobraziť elementy blokov HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/Smiley.js b/dojox/editor/plugins/nls/sk/Smiley.js
index a5064f5..fd92c38 100644
--- a/dojox/editor/plugins/nls/sk/Smiley.js
+++ b/dojox/editor/plugins/nls/sk/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Vložiť emotikon",
 	emoticonSmile: "úsmev",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "plač",
 	emoticonHappy: "šťastný"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/SpellCheck.js b/dojox/editor/plugins/nls/sk/SpellCheck.js
index 95e66a6..037b990 100644
--- a/dojox/editor/plugins/nls/sk/SpellCheck.js
+++ b/dojox/editor/plugins/nls/sk/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Dávková kontrola pravopisu",
 	unfound: "Nenašlo sa",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Preskočiť všetky podobné",
 	iMsg: "Žiadne návrhy na hláskovanie"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/TableDialog.js b/dojox/editor/plugins/nls/sk/TableDialog.js
index 6931c85..8d97d98 100644
--- a/dojox/editor/plugins/nls/sk/TableDialog.js
+++ b/dojox/editor/plugins/nls/sk/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Vložiť tabuľku",
 	modifyTableTitle: "Upraviť tabuľku",
@@ -21,16 +20,14 @@ define(
 	buttonSet: "Nastaviť", // translated elsewhere?
 	buttonInsert: "Vložiť",
 	buttonCancel: "Zrušiť",
-
 	selectTableLabel: "Vybrať tabuľku",
 	insertTableRowBeforeLabel: "Pridať riadok pred",
 	insertTableRowAfterLabel: "Pridať riadok za",
 	insertTableColumnBeforeLabel: "Pridať stĺpec pred",
 	insertTableColumnAfterLabel: "Pridať stĺpec za",
 	deleteTableRowLabel: "Vymazať riadok",
-	deleteTableColumnLabel: "Vymazať stĺpec"
+	deleteTableColumnLabel: "Vymazať stĺpec",
+	colorTableCellTitle: "Farba pozadia bunky tabuľky",
+	tableContextMenuTitle: "Kontextová ponuka tabuľky"
 })
-	
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/TextColor.js b/dojox/editor/plugins/nls/sk/TextColor.js
index 168f651..21af007 100644
--- a/dojox/editor/plugins/nls/sk/TextColor.js
+++ b/dojox/editor/plugins/nls/sk/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Nastaviť",
 	"cancelButtonText": "Zrušiť"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sk/latinEntities.js b/dojox/editor/plugins/nls/sk/latinEntities.js
index c239e9d..56c48a2 100644
--- a/dojox/editor/plugins/nls/sk/latinEntities.js
+++ b/dojox/editor/plugins/nls/sk/latinEntities.js
@@ -1,17 +1,16 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"invertovaný výkričník",
 	cent:"znak centu",
 	pound:"znak libry",
 	curren:"znak meny",
-	yen:"znak yen\nznak yuan",
+	yen:"znak yenu\nznak yuanu",
 	brvbar:"prerušovaná čiara\nprerušovaná zvislá čiara",
 	sect:"znak paragraf",
 	uml:"znak prehláskovania",
@@ -102,7 +101,6 @@ define(
 	yacute:"malé latinské písmeno y s dĺžňom",
 	thorn:"malé latinské písmeno thorn",
 	yuml:"malé latinské písmeno y prehlasované",
-
 // Greek Characters and Symbols
 	fnof:"malé latinské písmeno f s háčikom",
 	Alpha:"veľké grécke písmeno alfa",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"jednoduchý pravý ukazovateľ",
 	euro:"znak euro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/AutoSave.js b/dojox/editor/plugins/nls/sl/AutoSave.js
index 587f02b..ea6f827 100644
--- a/dojox/editor/plugins/nls/sl/AutoSave.js
+++ b/dojox/editor/plugins/nls/sl/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Shrani",
 	"saveSettingLabelOn": "Nastavi interval za samodejno shranjevanje ... ",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "Shranjeno ob ${0}",
 	"saveMessageFail": "Shranjevanje ob ${0} ni uspelo "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/Blockquote.js b/dojox/editor/plugins/nls/sl/Blockquote.js
index e514eed..5981312 100644
--- a/dojox/editor/plugins/nls/sl/Blockquote.js
+++ b/dojox/editor/plugins/nls/sl/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Blokovno besedilo"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/Breadcrumb.js b/dojox/editor/plugins/nls/sl/Breadcrumb.js
index c1e4209..2296362 100644
--- a/dojox/editor/plugins/nls/sl/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/sl/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "Dejanja ${nodeName} ",
 	"selectContents": "Izberi vsebine ",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Pomakni kazalko na začetek ",
 	"moveEnd": "Pomakni kazalko na konec "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/CollapsibleToolbar.js b/dojox/editor/plugins/nls/sl/CollapsibleToolbar.js
index 9828391..ddc134a 100644
--- a/dojox/editor/plugins/nls/sl/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/sl/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Strni orodno vrstico urejevalnika ",
 	"expand": "Razširi orodno vrstico urejevalnika "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/FindReplace.js b/dojox/editor/plugins/nls/sl/FindReplace.js
index b7689f2..9912dbe 100644
--- a/dojox/editor/plugins/nls/sl/FindReplace.js
+++ b/dojox/editor/plugins/nls/sl/FindReplace.js
@@ -1,26 +1,23 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Najdi:",
 	"findTooltip": "Vnesite besedilo za iskanje",
-	"replaceLabel": "Zamenjaj z: ",
-	"replaceTooltip": "Vnesite besedilo za zamenjavo ",
+	"replaceLabel": "Zamenjaj z:",
+	"replaceTooltip": "Vnesite besedilo za zamenjavo",
 	"findReplace": "Najdi in zamenjaj",
 	"matchCase": "Razlikuj velike in male črke",
 	"matchCaseTooltip": "Razlikuj velike in male črke",
 	"backwards": "Nazaj",
-	"backwardsTooltip": "Vzvratno iskanje besedila ",
+	"backwardsTooltip": "Vzvratno iskanje besedila",
 	"replaceAllButton": "Zamenjaj vse",
-	"replaceAllButtonTooltip": "Zamenjaj celotno besedilo ",
+	"replaceAllButtonTooltip": "Zamenjaj celotno besedilo",
 	"findButton": "Najdi",
-	"findButtonTooltip": "Najdi besedilo ",
-	"replaceButton": "Zamenjaj ",
-	"replaceButtonTooltip": "Zamenjaj besedilo ",
-	"replaceDialogText": "Zamenjanih ${0} pojavitev. ",
+	"findButtonTooltip": "Najdi besedilo",
+	"replaceButton": "Zamenjaj",
+	"replaceButtonTooltip": "Zamenjaj besedilo",
+	"replaceDialogText": "Zamenjanih ${0} pojavitev.",
 	"eofDialogText": "Zadnja pojavitev ${0}",
-	"eofDialogTextFind": "najdeno ",
-	"eofDialogTextReplace": "zamenjano "
+	"eofDialogTextFind": "najdeno",
+	"eofDialogTextReplace": "zamenjano"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/InsertAnchor.js b/dojox/editor/plugins/nls/sl/InsertAnchor.js
index 611ba89..fa8a0f1 100644
--- a/dojox/editor/plugins/nls/sl/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/sl/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Vstavi sidro",
 	title: "Lastnosti sidra",
@@ -8,6 +7,4 @@ define(
 	set: "Nastavi",
 	cancel: "Prekliči"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/InsertEntity.js b/dojox/editor/plugins/nls/sl/InsertEntity.js
index 457cb07..8ba7c07 100644
--- a/dojox/editor/plugins/nls/sl/InsertEntity.js
+++ b/dojox/editor/plugins/nls/sl/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Vstavi simbol "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/LocalImage.js b/dojox/editor/plugins/nls/sl/LocalImage.js
index 7a3bbb0..e0c5326 100644
--- a/dojox/editor/plugins/nls/sl/LocalImage.js
+++ b/dojox/editor/plugins/nls/sl/LocalImage.js
@@ -1,15 +1,12 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Vstavi sliko",
-	url: "Slika ",
-	browse: "Prebrskaj ... ",
-	text: "Opis ",
-	set: "Vstavi ",
-	invalidMessage: "Neveljavna vrsta slikovne datoteke ",
-	prePopuTextUrl: "Vnesite URL slike",
-	prePopuTextBrowse: " ali prebrskajte in izberite lokalno datoteko. "
+	url: "Slika",
+	browse: "Prebrskaj ...",
+	text: "Opis",
+	set: "Vstavi",
+	invalidMessage: "Neveljaven tip slikovne datoteke",
+	prePopuTextUrl: "Vnesi URL slike",
+	prePopuTextBrowse: " ali prebrskajte in izberite lokalno datoteko."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/PageBreak.js b/dojox/editor/plugins/nls/sl/PageBreak.js
index 3ec86ee..524e709 100644
--- a/dojox/editor/plugins/nls/sl/PageBreak.js
+++ b/dojox/editor/plugins/nls/sl/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Prelom strani"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/PasteFromWord.js b/dojox/editor/plugins/nls/sl/PasteFromWord.js
index 559d58d..c49e983 100644
--- a/dojox/editor/plugins/nls/sl/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/sl/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Prilepi iz programa Word",
-	"paste": "Prilepi",
-	"cancel": "Prekliči",
-	"instructions": "Vsebino iz programa Word prilepite v spodnje besedilno polje.  Ko ste zadovoljni z vstavljeno vsebino, pritisnite gumb Vstavi. Če želite prenehati z vstavljanjem vsebine, pritisnite gumb Prekliči. "
+	"instructions": "Vsebino iz programa Word prilepite v spodnje besedilno polje. Ko ste zadovoljni z vstavljeno vsebino, pritisnite gumb Vstavi. Če želite prenehati z vstavljanjem vsebine, pritisnite gumb Prekliči."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/Preview.js b/dojox/editor/plugins/nls/sl/Preview.js
index 5e56aa5..512f7ca 100644
--- a/dojox/editor/plugins/nls/sl/Preview.js
+++ b/dojox/editor/plugins/nls/sl/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Predogled "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/SafePaste.js b/dojox/editor/plugins/nls/sl/SafePaste.js
index 93e8a52..82b2c1b 100644
--- a/dojox/editor/plugins/nls/sl/SafePaste.js
+++ b/dojox/editor/plugins/nls/sl/SafePaste.js
@@ -1,5 +1,5 @@
 define(
 ({
-	"instructions": "Neposredno lepljenje je onemogočeno. Vsebino prilepite v to pogovorno okno s standardno tipkovnico brskalnika ali krmilnimi elementi menija za lepljenje. Ko ste zadovoljni z vsebino, ki jo želite vstaviti, pritisnite gumb za lepljenje. Če želite preklicati vstavljanje vsebine, pritisnite gumb za preklic."
+	"instructions": "Neposredno lepljenje je onemogočeno. Vsebino prilepite v to pogovorno okno s standardno tipkovnico brskalnika ali kontrolniki menija za lepljenje. Ko ste zadovoljni z vsebino, ki jo želite vstaviti, pritisnite gumb za lepljenje. Če želite preklicati vstavljanje vsebine, pritisnite gumb za preklic."
 })
 );
diff --git a/dojox/editor/plugins/nls/sl/Save.js b/dojox/editor/plugins/nls/sl/Save.js
index d9d9cc6..e487b47 100644
--- a/dojox/editor/plugins/nls/sl/Save.js
+++ b/dojox/editor/plugins/nls/sl/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Shrani"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/ShowBlockNodes.js b/dojox/editor/plugins/nls/sl/ShowBlockNodes.js
index 9ac93ea..edc9de6 100644
--- a/dojox/editor/plugins/nls/sl/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/sl/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Pokaži elemente blokade HTML-ja "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/Smiley.js b/dojox/editor/plugins/nls/sl/Smiley.js
index 80b9abb..d809bcf 100644
--- a/dojox/editor/plugins/nls/sl/Smiley.js
+++ b/dojox/editor/plugins/nls/sl/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "Vstavi čustveni simbol",
 	emoticonSmile: "smeško",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "smeško joka",
 	emoticonHappy: "smeško je vesel"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/SpellCheck.js b/dojox/editor/plugins/nls/sl/SpellCheck.js
index 1ab8dc4..9ab942e 100644
--- a/dojox/editor/plugins/nls/sl/SpellCheck.js
+++ b/dojox/editor/plugins/nls/sl/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Paketno preverjanje črkovanja ",
 	unfound: "Ni najdeno ",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Preskoči vse vnose, kot je ta ",
 	iMsg: "Ni predlogov za črkovanje "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/TableDialog.js b/dojox/editor/plugins/nls/sl/TableDialog.js
index de09528..07003fc 100644
--- a/dojox/editor/plugins/nls/sl/TableDialog.js
+++ b/dojox/editor/plugins/nls/sl/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Vstavi tabelo",
 	modifyTableTitle: "Spremeni tabelo",
@@ -21,16 +20,14 @@ define(
 	buttonSet: "Nastavi", // translated elsewhere?
 	buttonInsert: "Vstavi",
 	buttonCancel: "Prekliči",
-
 	selectTableLabel: "Izberi tabelo",
 	insertTableRowBeforeLabel: "Dodaj vrstico pred",
 	insertTableRowAfterLabel: "Dodaj vrstico za",
 	insertTableColumnBeforeLabel: "Dodaj stolpec pred",
 	insertTableColumnAfterLabel: "Dodaj stolpec za",
 	deleteTableRowLabel: "Izbriši vrstico",
-	deleteTableColumnLabel: "Izbriši stolpec"
+	deleteTableColumnLabel: "Izbriši stolpec",
+	colorTableCellTitle: "Barva ozadja celice v tabeli",
+	tableContextMenuTitle: "Kontekstni meni tabele"
 })
-	
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/TextColor.js b/dojox/editor/plugins/nls/sl/TextColor.js
index bc53cc6..4e938e5 100644
--- a/dojox/editor/plugins/nls/sl/TextColor.js
+++ b/dojox/editor/plugins/nls/sl/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Nastavi",
 	"cancelButtonText": "Prekliči"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sl/latinEntities.js b/dojox/editor/plugins/nls/sl/latinEntities.js
index cc653df..ed0ab4f 100644
--- a/dojox/editor/plugins/nls/sl/latinEntities.js
+++ b/dojox/editor/plugins/nls/sl/latinEntities.js
@@ -1,261 +1,257 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
-	iexcl:"obrnjen klicaj ",
-	cent:"znak za cent ",
-	pound:"znak za funt ",
-	curren:"znak za valuto ",
-	yen:"znak za jen\njuan ",
-	brvbar:"prekinjena črta\nprekinjena navpična črta ",
-	sect:"znak za odsek ",
-	uml:"diareza\ndiareza z razmikom ",
-	copy:"znak za avtorske pravice ",
-	ordf:"ženski ordinalni indikator ",
-	laquo:"dvojni narekovaj, ki kaže v levo smer ",
-	not:"znak za ne ",
-	shy:"pogojni deljaj ",
-	reg:"znak za registrirano\nznak za registrirano blagovno znamko ",
-	macr:"ravni preglas ",
-	deg:"znak za stopinje ",
-	plusmn:"znak plus-minus\nznak plus ali minus ",
-	sup2:"nadpisana dve\nnadpisana števka dve\nna kvadrat ",
-	sup3:"nadpisana tri\nnadpisana števka tri\nna kub ",
-	acute:"ostrivec ",
+	iexcl:"obrnjen klicaj",
+	cent:"znak za cent",
+	pound:"znak za funt",
+	curren:"znak za valuto",
+	yen:"znak za jen\nznak za juan",
+	brvbar:"prekinjena črta\nnavpična prekinjena črta",
+	sect:"znak za odsek",
+	uml:"diareza\ndiareza z razmikom",
+	copy:"znak za avtorske pravice",
+	ordf:"ženski ordinalni indikator",
+	laquo:"dvojni narekovaj, ki kaže v levo smer",
+	not:"znak za ne",
+	shy:"pogojni deljaj",
+	reg:"znak registrirano\nznak za registrirano blagovno znamko",
+	macr:"znak za dolžino samoglasnika\nznak za dolžino samoglasnika z razmikom\nnadčrtaj\nAPL overbar",
+	deg:"znak za stopinje",
+	plusmn:"znak plus-minus\nznak plus ali minus",
+	sup2:"nadpisana dve\nnadpisana števka dve\nna kvadrat",
+	sup3:"nadpisana tri\nnadpisana števka tri\nna tri",
+	acute:"ostrivec",
 	micro:"znak za mikro",
 	para:"znak za paragraf",
-	middot:"pika na sredini\nGeorgian comma\nGrška pika na sredini ",
-	cedil:"cedila ",
-	sup1:"nadpisana ena\nnadpisana števka ena ",
-	ordm:"moški ordinalni indikator ",
-	raquo:"dvojni narekovaj, ki kaže v desno smer ",
-	frac14:"pravi ulomek ena četrtina ",
-	frac12:"pravi ulomek ena polovica ",
-	frac34:"pravi ulomek tri četrtine ",
-	iquest:"obrnjen vprašaj ",
-	Agrave:"Latinska velika črka A s krativcem ",
-	Aacute:"Latinska velika črka A z ostrivcem ",
-	Acirc:"Latinska velika črka A s cirkumfleksom ",
-	Atilde:"Latinska velika črka A s tildo ",
-	Auml:"Latinska velika črka A z diarezo ",
-	Aring:"Latinska velika črka A s krogcem na vrhu ",
-	AElig:"Latinska velika črka AE ",
-	Ccedil:"Latinska velika črka C s cedilo ",
-	Egrave:"Latinska velika črka E s krativcem ",
-	Eacute:"Latinska velika črka E z ostrivcem ",
-	Ecirc:"Latinska velika črka E s cirkumfleksom ",
-	Euml:"Latinska velika črka E z diarezo ",
-	Igrave:"Latinska velika črka I s krativcem ",
-	Iacute:"Latinska velika črka I z ostrivcem ",
-	Icirc:"Latinska velika črka I s cirkumfleksom ",
-	Iuml:"Latinska velika črka I z diarezo ",
-	ETH:"Latinska velika črka ETH ",
-	Ntilde:"Latinska velika črka N s tildo ",
-	Ograve:"Latinska velika črka O s krativcem ",
-	Oacute:"Latinska velika črka O z ostrivcem ",
-	Ocirc:"Latinska velika črka O s cirkumfleksom ",
-	Otilde:"Latinska velika črka O s tildo ",
-	Ouml:"Latinska velika črka O z diarezo ",
-	times:"znak za množenje ",
-	Oslash:"Poševno prečrtana latinska velika črka O ",
-	Ugrave:"Latinska velika črka U s krativcem ",
-	Uacute:"Latinska velika črka U z ostrivcem ",
-	Ucirc:"Latinska velika črka U s cirkumfleksom ",
-	Uuml:"Latinska velika črka U z diarezo ",
-	Yacute:"Latinska velika črka Y z ostrivcem ",
-	THORN:"Latinska velika črka THORN ",
-	szlig:"Latinska majhna črka ostri s ",
-	agrave:"Latinska majhna črka a s krativcem ",
-	aacute:"Latinska majhna črka a z ostrivcem ",
-	acirc:"Latinska majhna črka a s cirkumfleksom ",
-	atilde:"Latinska majhna črka a s tildo ",
-	auml:"Latinska majhna črka a z diarezo ",
-	aring:"Latinska majhna črka a s krogcem na vrhu ",
-	aelig:"Latinska majhna črka ae ",
-	ccedil:"Latinska majhna črka c s cedilo ",
-	egrave:"Latinska majhna črka e s krativcem ",
-	eacute:"Latinska majhna črka e z ostrivcem ",
-	ecirc:"Latinska majhna črka e s cirkumfleksom ",
-	euml:"Latinska majhna črka e z diarezo ",
-	igrave:"Latinska majhna črka i s krativcem ",
-	iacute:"Latinska majhna črka i z ostrivcem ",
-	icirc:"Latinska majhna črka i s cirkumfleksom ",
-	iuml:"Latinska majhna črka i z diarezo ",
-	eth:"Latinska majhna črka eth ",
-	ntilde:"Latinska majhna črka n s tildo ",
-	ograve:"Latinska majhna črka o s krativcem ",
-	oacute:"Latinska majhna črka o z ostrivcem ",
-	ocirc:"Latinska majhna črka o s cirkumfleksom ",
-	otilde:"Latinska majhna črka o s tildo ",
-	ouml:"Latinska majhna črka o z diarezo ",
-	divide:"znak za deljenje ",
-	oslash:"Poševno prečrtana latinska majhna črka o ",
-	ugrave:"Latinska majhna črka u s krativcem ",
-	uacute:"Latinska majhna črka u z ostrivcem ",
-	ucirc:"Latinska majhna črka u s cirkumfleksom ",
-	uuml:"Latinska majhna črka u z diarezo ",
-	yacute:"Latinska majhna črka y z ostrivcem ",
-	thorn:"Latinska majhna črka thorn ",
-	yuml:"Latinska majhna črka y z diarezo ",
-
+	middot:"sredinska pika\ngruzijska vejica\ngrška sredinska pika",
+	cedil:"cedila\ncedila z razmikom",
+	sup1:"nadpisana ena\nnadpisana števka ena",
+	ordm:"moški ordinalni indikator",
+	raquo:"dvojni narekovaj, ki kaže v desno smer",
+	frac14:"pravi ulomek ena četrtina",
+	frac12:"pravi ulomek ena polovica",
+	frac34:"pravi ulomek tri četrtine",
+	iquest:"obrnjen vprašaj",
+	Agrave:"Latinska velika črka A s krativcem",
+	Aacute:"Latinska velika črka A z ostrivcem",
+	Acirc:"Latinska velika črka A s cirkumfleksom",
+	Atilde:"Latinska velika črka A s tildo",
+	Auml:"Latinska velika črka A z diarezo",
+	Aring:"Latinska velika črka A s krogcem na vrhu",
+	AElig:"Latinska velika črka AE",
+	Ccedil:"Latinska velika črka C s cedilo",
+	Egrave:"Latinska velika črka E s krativcem",
+	Eacute:"Latinska velika črka E z ostrivcem",
+	Ecirc:"Latinska velika črka E s cirkumfleksom",
+	Euml:"Latinska velika črka E z diarezo",
+	Igrave:"Latinska velika črka I s krativcem",
+	Iacute:"Latinska velika črka I z ostrivcem",
+	Icirc:"Latinska velika črka I s cirkumfleksom",
+	Iuml:"Latinska velika črka I z diarezo",
+	ETH:"Latinska velika črka ETH",
+	Ntilde:"Latinska velika črka N s tildo",
+	Ograve:"Latinska velika črka O s krativcem",
+	Oacute:"Latinska velika črka O z ostrivcem",
+	Ocirc:"Latinska velika črka O s cirkumfleksom",
+	Otilde:"Latinska velika črka O s tildo",
+	Ouml:"Latinska velika črka O z diarezo",
+	times:"znak za množenje",
+	Oslash:"Poševno prečrtana latinska velika črka O",
+	Ugrave:"Latinska velika črka U s krativcem",
+	Uacute:"Latinska velika črka U z ostrivcem",
+	Ucirc:"Latinska velika črka U s cirkumfleksom",
+	Uuml:"Latinska velika črka U z diarezo",
+	Yacute:"Latinska velika črka Y z ostrivcem",
+	THORN:"Latinska velika črka THORN",
+	szlig:"Latinska majhna črka ostri s",
+	agrave:"Latinska majhna črka a s krativcem",
+	aacute:"Latinska majhna črka a z ostrivcem",
+	acirc:"Latinska majhna črka a s cirkumfleksom",
+	atilde:"Latinska majhna črka a s tildo",
+	auml:"Latinska majhna črka a z diarezo",
+	aring:"Latinska majhna črka a s krogcem na vrhu",
+	aelig:"Latinska majhna črka ae",
+	ccedil:"Latinska majhna črka c s cedilo",
+	egrave:"Latinska majhna črka e s krativcem",
+	eacute:"Latinska majhna črka e z ostrivcem",
+	ecirc:"Latinska majhna črka e s cirkumfleksom",
+	euml:"Latinska majhna črka e z diarezo",
+	igrave:"Latinska majhna črka i s krativcem",
+	iacute:"Latinska majhna črka i z ostrivcem",
+	icirc:"Latinska majhna črka i s cirkumfleksom",
+	iuml:"Latinska majhna črka i z diarezo",
+	eth:"Latinska majhna črka eth",
+	ntilde:"Latinska majhna črka n s tildo",
+	ograve:"Latinska majhna črka o s krativcem",
+	oacute:"Latinska majhna črka o z ostrivcem",
+	ocirc:"Latinska majhna črka o s cirkumfleksom",
+	otilde:"Latinska majhna črka o s tildo",
+	ouml:"Latinska majhna črka o z diarezo",
+	divide:"znak za deljenje",
+	oslash:"Poševno prečrtana latinska majhna črka o",
+	ugrave:"Latinska majhna črka u s krativcem",
+	uacute:"Latinska majhna črka u z ostrivcem",
+	ucirc:"Latinska majhna črka u s cirkumfleksom",
+	uuml:"Latinska majhna črka u z diarezo",
+	yacute:"Latinska majhna črka y z ostrivcem",
+	thorn:"Latinska majhna črka thorn",
+	yuml:"Latinska majhna črka y z diarezo",
 // Greek Characters and Symbols
-	fnof:"Zavita latinska majhna črka f\nfunkcija ",
-	Alpha:"Grška velika črka alfa ",
-	Beta:"Grška velika črka beta ",
-	Gamma:"Grška velika črka gama ",
-	Delta:"Grška velika črka delta ",
-	Epsilon:"Grška velika črka epsilon ",
-	Zeta:"Grška velika črka zeta ",
-	Eta:"Grška velika črka eta ",
-	Theta:"Grška velika črka theta ",
-	Iota:"Grška velika črka jota ",
-	Kappa:"Grška velika črka kapa ",
-	Lambda:"Grška velika črka lambda ",
-	Mu:"Grška velika črka mu ",
-	Nu:"Grška velika črka nu ",
-	Xi:"Grška velika črka ksi ",
-	Omicron:"Grška velika črka omikron ",
-	Pi:"Grška velika črka pi ",
-	Rho:"Grška velika črka ro ",
-	Sigma:"Grška velika črka sigma ",
-	Tau:"Grška velika črka tau ",
-	Upsilon:"Grška velika črka ipsilon ",
-	Phi:"Grška velika črka fi ",
-	Chi:"Grška velika črka hi ",
-	Psi:"Grška velika črka psi ",
-	Omega:"Grška velika črka omega ",
-	alpha:"Grška majhna črka alfa ",
-	beta:"Grška majhna črka beta ",
-	gamma:"Grška majhna črka gama ",
-	delta:"Grška majhna črka delta ",
-	epsilon:"Grška majhna črka epsilon ",
-	zeta:"Grška majhna črka zeta ",
-	eta:"Grška majhna črka eta ",
-	theta:"Grška majhna črka theta ",
-	iota:"Grška majhna črka iota ",
-	kappa:"Grška majhna črka kapa ",
-	lambda:"Grška majhna črka lambda ",
-	mu:"Grška majhna črka mu ",
-	nu:"Grška majhna črka nu ",
-	xi:"Grška majhna črka ksi ",
-	omicron:"Grška majhna črka omikron ",
-	pi:"Grška majhna črka pi ",
-	rho:"Grška majhna črka ro ",
-	sigmaf:"Grška majhna črka končna sigma ",
-	sigma:"Grška majhna črka sigma ",
-	tau:"Grška majhna črka tau ",
-	upsilon:"Grška majhna črka ipsilon ",
-	phi:"Grška majhna črka fi ",
-	chi:"Grška majhna črka hi ",
-	psi:"Grška majhna črka psi ",
-	omega:"Grška majhna črka omega ",
-	thetasym:"Simbol majhne grške črke theta ",
-	upsih:"Grški zaviti simbol ipsilon ",
-	piv:"Grški simbol pi ",
-	bull:"oznaka\nmajhen črn krog ",
-	hellip:"tripičje ",
-	prime:"apostrof\nminute\nčevlji ",
-	Prime:"dvojni apostrof\nsekunde\npalci",
-	oline:"nadčrtaj ",
-	frasl:"poševnica ulomka ",
-	weierp:"potenčna množica\nWierstrassov p ",
-	image:"Gotska velika črka I\nimaginarni del ",
-	real:"Gotska velika črka R\nrealni del ",
-	trade:"znak za blagovno znamko ",
-	alefsym:"simbol alef\nprvo transfinitno kardinalno število ",
-	larr:"puščica levo ",
-	uarr:"puščica navzgor ",
-	rarr:"puščica desno ",
-	darr:"puščica navzdol ",
-	harr:"puščica levo navzgor ",
-	crarr:"puščica navzdol s kotom na levi strani\nzačetek vrstice ",
-	lArr:"dvojna puščica levo ",
-	uArr:"dvojna puščica navzgor ",
-	rArr:"dvojna puščica desno ",
-	dArr:"dvojna puščica navzdol ",
-	hArr:"dvojna puščica levo-desno ",
-	forall:"za vse ",
-	part:"delni diferencial ",
-	exist:"obstaja ",
-	empty:"prazna množica ",
-	nabla:"nabla ",
-	isin:"je element ",
-	notin:"ni element ",
-	ni:"vsebuje kot člana ",
-	prod:"n-kratni produkt ",
-	sum:"n-kratna vsota ",
-	minus:"znak za minus ",
-	lowast:"operator zvezdice ",
-	radic:"kvadratni koren ",
-	prop:"proporcialno z ",
-	infin:"neskončnost ",
-	ang:"kot ",
-	and:"logični in ",
-	or:"logični ali ",
-	cap:"presek ",
-	cup:"unija ","int":"integral ",
-	there4:"zato ",
-	sim:"operator tilda\nje podobno\nvarira z ",
-	cong:"je približno enako kot ",
-	asymp:"je skoraj enako kot\nasimptotsko glede na ",
-	ne:"ni enako ",
-	equiv:"je identično ",
-	le:"je manjše ali enako kot ",
-	ge:"je večje ali enako kot ",
-	sub:"je podmnožica ",
-	sup:"je nadmnožica ",
-	nsub:"ni podmnožnica ",
-	sube:"podmnožica ali enako ",
-	supe:"nadmnožica ali enako ",
-	oplus:"obkrožen plus\nneposredna svota ",
-	otimes:"obrkrožen krat\nvektorski produkt ",
-	perp:"žebljiček, obrnjen navzgor\npravokoten glede na ",
-	sdot:"operator pika ",
-	lceil:"levi zgornji kot ",
-	rceil:"desni zgornji kot ",
-	lfloor:"levi spodnji kot ",
-	rfloor:"desni spodnji kot ",
-	lang:"lomljeni oklepaj, ki kaže v levo ",
-	rang:"lomljeni oklepaj, ki kaže v desno ",
-	loz:"romb ",
-	spades:"črni pik ",
-	clubs:"črni križ\ndetelja ",
-	hearts:"črno srce\nvalentinovo ",
-	diams:"črni karo ",
-	OElig:"Latinska velika ligatura OE ",
-	oelig:"Latinska majhna ligatura oe ",
-	Scaron:"Latinska velika črka S s strešico ",
-	scaron:"Latinska majhna črka s s strešico ",
-	Yuml:"Latinska velika črka Y z diarezo ",
-	circ:"znak za cirkumfleks ",
-	tilde:"mala tilda ",
-	ensp:"presledek ",
-	emsp:"dolgi presledek ",
-	thinsp:"kratki presledek ",
-	zwnj:"razdruževalnik z nično širino ",
-	zwj:"združevalnik z nično širino ",
-	lrm:"oznaka od leve proti desni ",
-	rlm:"oznaka od desne proti levi ",
+	fnof:"Latinska majhna zavita črka f\nfunkcija\nflorin",
+	Alpha:"Grška velika črka alfa",
+	Beta:"Grška velika črka beta",
+	Gamma:"Grška velika črka gama",
+	Delta:"Grška velika črka delta",
+	Epsilon:"Grška velika črka epsilon",
+	Zeta:"Grška velika črka zeta",
+	Eta:"Grška velika črka eta",
+	Theta:"Grška velika črka theta",
+	Iota:"Grška velika črka jota",
+	Kappa:"Grška velika črka kapa",
+	Lambda:"Grška velika črka lambda",
+	Mu:"Grška velika črka mu",
+	Nu:"Grška velika črka nu",
+	Xi:"Grška velika črka ksi",
+	Omicron:"Grška velika črka omikron",
+	Pi:"Grška velika črka pi",
+	Rho:"Grška velika črka ro",
+	Sigma:"Grška velika črka sigma",
+	Tau:"Grška velika črka tau",
+	Upsilon:"Grška velika črka ipsilon",
+	Phi:"Grška velika črka fi",
+	Chi:"Grška velika črka hi",
+	Psi:"Grška velika črka psi",
+	Omega:"Grška velika črka omega",
+	alpha:"Grška majhna črka alfa",
+	beta:"Grška majhna črka beta",
+	gamma:"Grška majhna črka gama",
+	delta:"Grška majhna črka delta",
+	epsilon:"Grška majhna črka epsilon",
+	zeta:"Grška majhna črka zeta",
+	eta:"Grška majhna črka eta",
+	theta:"Grška majhna črka theta",
+	iota:"Grška majhna črka iota",
+	kappa:"Grška majhna črka kapa",
+	lambda:"Grška majhna črka lambda",
+	mu:"Grška majhna črka mu",
+	nu:"Grška majhna črka nu",
+	xi:"Grška majhna črka ksi",
+	omicron:"Grška majhna črka omikron",
+	pi:"Grška majhna črka pi",
+	rho:"Grška majhna črka ro",
+	sigmaf:"Grška majhna črka končna sigma",
+	sigma:"Grška majhna črka sigma",
+	tau:"Grška majhna črka tau",
+	upsilon:"Grška majhna črka ipsilon",
+	phi:"Grška majhna črka fi",
+	chi:"Grška majhna črka hi",
+	psi:"Grška majhna črka psi",
+	omega:"Grška majhna črka omega",
+	thetasym:"Simbol majhne grške črke theta",
+	upsih:"Grški zaviti simbol ipsilon",
+	piv:"Grški simbol pi",
+	bull:"naštevna oznaka\nmajhen črn krog",
+	hellip:"tripičje",
+	prime:"znak za minuto\nminute\nčevlji",
+	Prime:"znak za sekundo\nsekund\npalci",
+	oline:"nadčrtaj\nčrtica zgoraj z razmikom",
+	frasl:"poševnica ulomka",
+	weierp:"pisana velika črka P\npotenčna množica\nWeierstrassova funkcija p",
+	image:"gotska velika črka I\nimaginarni del",
+	real:"gotska velika črka R\nsimbol za realni del",
+	trade:"znak za blagovno znamko",
+	alefsym:"simbol alef\nprvo transfinitno kardinalno število",
+	larr:"puščica levo",
+	uarr:"puščica navzgor",
+	rarr:"puščica desno",
+	darr:"puščica navzdol",
+	harr:"puščica levo navzgor",
+	crarr:"puščica navzdol z levim kotom\nvračalka",
+	lArr:"dvojna puščica levo",
+	uArr:"dvojna puščica navzgor",
+	rArr:"dvojna puščica desno",
+	dArr:"dvojna puščica navzdol",
+	hArr:"dvojna puščica levo-desno",
+	forall:"za vse",
+	part:"delni diferencial",
+	exist:"obstaja",
+	empty:"prazna množica\nničelna množica\npremer",
+	nabla:"nabla\nalgoritem BDF",
+	isin:"je element",
+	notin:"ni element",
+	ni:"vsebuje kot člana",
+	prod:"n-arni produkt\nznak za produkt",
+	sum:"n-arna vsota",
+	minus:"znak za minus",
+	lowast:"operator zvezdice",
+	radic:"kvadratni koren\nkorenski znak",
+	prop:"proporcionalno z",
+	infin:"neskončnost",
+	ang:"kot",
+	and:"logični and\nkonjunkcija",
+	or:"logični or\ndisjunkcija",
+	cap:"presek\nznak za presek",
+	cup:"unija\nznak za unijo","int":"integral",
+	there4:"zato",
+	sim:"operator tilda\nvariira z\npodobno kot",
+	cong:"je približno enako kot",
+	asymp:"skoraj enako\nasimptotno glede na",
+	ne:"ni enako",
+	equiv:"je identično",
+	le:"je manjše ali enako kot",
+	ge:"je večje ali enako kot",
+	sub:"je podnabor",
+	sup:"je nadnabor",
+	nsub:"ni podnabor",
+	sube:"podnabor ali enako",
+	supe:"nadnabor ali enako",
+	oplus:"znak plus s krogcem\nneposredna vsota",
+	otimes:"znak krat s krogcem\nvektorski produkt",
+	perp:"pravokotnost\nortogonalno na\npravokotno na",
+	sdot:"operator pika",
+	lceil:"levi zgornji kot\nAPL upstile",
+	rceil:"desni zgornji kot",
+	lfloor:"levi spodnji kot\nAPL downstile",
+	rfloor:"desni spodnji kot",
+	lang:"lomljeni oklepaj, ki kaže v levo",
+	rang:"lomljeni oklepaj, ki kaže v desno",
+	loz:"romb",
+	spades:"črni pik",
+	clubs:"črni križ\ndeteljica",
+	hearts:"črno srce\nvalentinovo",
+	diams:"črni karo",
+	OElig:"Latinska velika ligatura OE",
+	oelig:"Latinska majhna ligatura oe",
+	Scaron:"Latinska velika črka S s strešico",
+	scaron:"Latinska majhna črka s s strešico",
+	Yuml:"Latinska velika črka Y z diarezo",
+	circ:"znak za cirkumfleks",
+	tilde:"mala tilda",
+	ensp:"presledek",
+	emsp:"dolgi presledek",
+	thinsp:"kratki presledek",
+	zwnj:"razdruževalnik z nično širino",
+	zwj:"združevalnik z nično širino",
+	lrm:"oznaka od leve proti desni",
+	rlm:"oznaka od desne proti levi",
 	ndash:"pomišljaj",
-	mdash:"dolgi pomišljaj ",
-	lsquo:"levi opuščaj ",
-	rsquo:"desni opuščaj ",
-	sbquo:"enojni spodnji narekovaj ",
-	ldquo:"levi dvojni narekovaj ",
-	rdquo:"desni dvojni narekovaj ",
-	bdquo:"dvojni spodnji narekovaj ",
-	dagger:"križec ",
-	Dagger:"dvojni križec ",
-	permil:"znak 'na miljo' ",
-	lsaquo:"enojni kotni narekovaj, ki kaže v levo ",
-	rsaquo:"enojni kotni narekovaj, ki kaže v desno ",
-	euro:"znak za evro "
+	mdash:"dolgi pomišljaj",
+	lsquo:"levi opuščaj",
+	rsquo:"desni opuščaj",
+	sbquo:"enojni spodnji narekovaj",
+	ldquo:"levi dvojni narekovaj",
+	rdquo:"desni dvojni narekovaj",
+	bdquo:"dvojni spodnji narekovaj",
+	dagger:"križec",
+	Dagger:"dvojni križec",
+	permil:"znak na miljo",
+	lsaquo:"enojni kotni narekovaj, ki kaže v levo",
+	rsaquo:"enojni kotni narekovaj, ki kaže v desno",
+	euro:"znak za evro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/AutoSave.js b/dojox/editor/plugins/nls/sv/AutoSave.js
index 03ee67a..7e626e0 100644
--- a/dojox/editor/plugins/nls/sv/AutoSave.js
+++ b/dojox/editor/plugins/nls/sv/AutoSave.js
@@ -1,18 +1,15 @@
 define(
-//begin v1.x content
 ({
-	"saveLabel": "Spara",
-	"saveSettingLabelOn": "Ange intervall för automatiskt sparande...",
-	"saveSettingLabelOff": "Avaktivera automatiskt sparande",
+	"saveLabel": "Spara ",
+	"saveSettingLabelOn": "Intervall för Spara automatiskt...",
+	"saveSettingLabelOff": "Stäng av Spara automatiskt",
 	"saveSettingdialogTitle": "Spara automatiskt",
-	"saveSettingdialogDescription": "Ange intervall för automatiskt sparande",
-	"saveSettingdialogParamName": "Intervall för automatiskt sparande",
-	"saveSettingdialogParamLabel": "min.",
-	"saveSettingdialogButtonOk": "Ange intervall",
+	"saveSettingdialogDescription": "Välj intervall för Spara automatiskt",
+	"saveSettingdialogParamName": "Intervall för Spara automatiskt",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Välj intervall",
 	"saveSettingdialogButtonCancel": "Avbryt",
 	"saveMessageSuccess": "Sparades ${0}",
-	"saveMessageFail": "Kunde inte sparas ${0}"
+	"saveMessageFail": "Det gick inte att spara ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/Blockquote.js b/dojox/editor/plugins/nls/sv/Blockquote.js
index 5a289b1..1cb472b 100644
--- a/dojox/editor/plugins/nls/sv/Blockquote.js
+++ b/dojox/editor/plugins/nls/sv/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Blockcitat"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/Breadcrumb.js b/dojox/editor/plugins/nls/sv/Breadcrumb.js
index 7097e34..d0d5974 100644
--- a/dojox/editor/plugins/nls/sv/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/sv/Breadcrumb.js
@@ -1,7 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"nodeActions": "${nodeName}-åtgärder",
+	"nodeActions": "Åtgärder för ${nodeName}",
 	"selectContents": "Välj innehåll",
 	"selectElement": "Välj element",
 	"deleteElement": "Ta bort element",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "Flytta markören till början",
 	"moveEnd": "Flytta markören till slutet"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/CollapsibleToolbar.js b/dojox/editor/plugins/nls/sv/CollapsibleToolbar.js
index bc430cd..2370720 100644
--- a/dojox/editor/plugins/nls/sv/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/sv/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"collapse": "Komprimera redigerarverktygsfältet",
-	"expand": "Expandera redigerarverktygsfältet"
+	"collapse": "Komprimera redigeringsverktygsfältet",
+	"expand": "Expandera redigeringsverktygsfältet"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/FindReplace.js b/dojox/editor/plugins/nls/sv/FindReplace.js
index c7652e3..76aebaa 100644
--- a/dojox/editor/plugins/nls/sv/FindReplace.js
+++ b/dojox/editor/plugins/nls/sv/FindReplace.js
@@ -1,26 +1,23 @@
 define(
-//begin v1.x content
 ({
-	"findLabel": "Sök:",
-	"findTooltip": "Ange den text du vill söka efter",
+	"findLabel": "Sök: ",
+	"findTooltip": "Skriv söktexten",
 	"replaceLabel": "Ersätt med:",
-	"replaceTooltip": "Ange den text du vill ersätta med",
+	"replaceTooltip": "Skriv ersättningstexten",
 	"findReplace": "Sök och ersätt",
-	"matchCase": "Matcha skiftläge",
-	"matchCaseTooltip": "Matcha skiftläge",
+	"matchCase": "Matcha gemener/versaler",
+	"matchCaseTooltip": "Matcha gemener/versaler",
 	"backwards": "Bakåt",
 	"backwardsTooltip": "Sök bakåt efter text",
 	"replaceAllButton": "Ersätt alla",
 	"replaceAllButtonTooltip": "Ersätt all text",
 	"findButton": "Sök",
 	"findButtonTooltip": "Sök efter texten",
-	"replaceButton": "Ersätt",
+	"replaceButton": "Erätt",
 	"replaceButtonTooltip": "Ersätt texten",
-	"replaceDialogText": "${0} förekomster ersattes.",
-	"eofDialogText": "Senaste förekomst${0}",
+	"replaceDialogText": "${0} förekomster har ersatts.",
+	"eofDialogText": "Sista förekomsten ${0}",
 	"eofDialogTextFind": "hittades",
 	"eofDialogTextReplace": "ersattes"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/InsertAnchor.js b/dojox/editor/plugins/nls/sv/InsertAnchor.js
index 72d2c11..7fd49ff 100644
--- a/dojox/editor/plugins/nls/sv/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/sv/InsertAnchor.js
@@ -1,13 +1,10 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Infoga ankare",
-	title: "Egenskaper för ankare",
+	title: "Ankaregenskaper",
 	anchor: "Namn:",
 	text: "Beskrivning:",
-	set: "Ange",
+	set: "Använd",
 	cancel: "Avbryt"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/InsertEntity.js b/dojox/editor/plugins/nls/sv/InsertEntity.js
index b38cc7c..4f1cd61 100644
--- a/dojox/editor/plugins/nls/sv/InsertEntity.js
+++ b/dojox/editor/plugins/nls/sv/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Infoga symbol"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/LocalImage.js b/dojox/editor/plugins/nls/sv/LocalImage.js
index 2cef853..010586b 100644
--- a/dojox/editor/plugins/nls/sv/LocalImage.js
+++ b/dojox/editor/plugins/nls/sv/LocalImage.js
@@ -1,15 +1,12 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Infoga bild",
 	url: "Bild",
 	browse: "Bläddra...",
-	text: "Beskrivning",
+	text: "Beksrivning",
 	set: "Infoga",
-	invalidMessage: "Ogiltigt bildfilformat",
-	prePopuTextUrl: "Ange en bild-URL-adress",
-	prePopuTextBrowse: " eller bläddra efter en lokal fil."
+	invalidMessage: "Ogiltig bildfilstyp",
+	prePopuTextUrl: "Fyll i bild-URL",
+	prePopuTextBrowse: " eller bläddra till en lokal fil."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/PageBreak.js b/dojox/editor/plugins/nls/sv/PageBreak.js
index 2f3b090..e2e5c75 100644
--- a/dojox/editor/plugins/nls/sv/PageBreak.js
+++ b/dojox/editor/plugins/nls/sv/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Sidbrytning"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/PasteFromWord.js b/dojox/editor/plugins/nls/sv/PasteFromWord.js
index 2d6e21e..f25963f 100644
--- a/dojox/editor/plugins/nls/sv/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/sv/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Klistra in från Word",
-	"paste": "Klistra in",
-	"cancel": "Avbryt",
-	"instructions": "Klistra in innehållet från Word i textfältet nedan. När du är klar klickar du på Klistra in. Om du vill avbryta klickar du på Avbryt."
+	"instructions": "Klistra in innehållet från Word i textrutan nedan. När du har valt innehåll klickar du på Klistra in. Klicka på Avbryt om du inte vill klistra in text. "
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/Preview.js b/dojox/editor/plugins/nls/sv/Preview.js
index 44b726c..836752b 100644
--- a/dojox/editor/plugins/nls/sv/Preview.js
+++ b/dojox/editor/plugins/nls/sv/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
-	"preview": "Förhandsgranska"
+	"preview": "Förhandsgranskning"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/Save.js b/dojox/editor/plugins/nls/sv/Save.js
index 1702fdf..314a760 100644
--- a/dojox/editor/plugins/nls/sv/Save.js
+++ b/dojox/editor/plugins/nls/sv/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Spara"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/ShowBlockNodes.js b/dojox/editor/plugins/nls/sv/ShowBlockNodes.js
index fc22bb3..1d72782 100644
--- a/dojox/editor/plugins/nls/sv/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/sv/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "Visa HTML-blockelement"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/Smiley.js b/dojox/editor/plugins/nls/sv/Smiley.js
index debc09f..8f0ffc3 100644
--- a/dojox/editor/plugins/nls/sv/Smiley.js
+++ b/dojox/editor/plugins/nls/sv/Smiley.js
@@ -1,27 +1,24 @@
 define(
-//begin v1.x content
 ({
-	smiley: "Infoga känslolägesikon",
-	emoticonSmile: "ler",
-	emoticonLaughing: "skrattar",
-	emoticonWink: "blinkar med ena ögat",
-	emoticonGrin: "ler stort",
-	emoticonCool: "cool",
+	smiley: "Infoga smilis",
+	emoticonSmile: "leende",
+	emoticonLaughing: "skratt",
+	emoticonWink: "blinkning",
+	emoticonGrin: "flin",
+	emoticonCool: "sval",
 	emoticonAngry: "arg",
-	emoticonHalf: "halvt leende",
-	emoticonEyebrow: "lyfter på ena ögonbrynet",
-	emoticonFrown: "rynkar pannan",
+	emoticonHalf: "halv",
+	emoticonEyebrow: "ögonbryn",
+	emoticonFrown: "sur",
 	emoticonShy: "blyg",
 	emoticonGoofy: "knasig",
 	emoticonOops: "hoppsan",
-	emoticonTongue: "räcker ut tungan",
+	emoticonTongue: "tunga",
 	emoticonIdea: "idé",
 	emoticonYes: "ja",
 	emoticonNo: "nej",
 	emoticonAngel: "ängel",
-	emoticonCrying: "gråter",
+	emoticonCrying: "gråt",
 	emoticonHappy: "glad"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/SpellCheck.js b/dojox/editor/plugins/nls/sv/SpellCheck.js
index d23fc4d..4201657 100644
--- a/dojox/editor/plugins/nls/sv/SpellCheck.js
+++ b/dojox/editor/plugins/nls/sv/SpellCheck.js
@@ -1,21 +1,18 @@
 define(
-//begin v1.x content
 ({
-	widgetLabel: "Kontrollera stavning",
-	unfound: "Hittades inte",
+	widgetLabel: "Batchstavningskontroll",
+	unfound: "Finns inte",
 	skip: "Hoppa över",
 	skipAll: "Hoppa över alla",
-	toDic: "Lägg till i ordlistan",
+	toDic: "Lägg till i ordbok",
 	suggestions: "Förslag",
 	replace: "Ersätt",
 	replaceWith: "Ersätt med",
 	replaceAll: "Ersätt alla",
 	cancel: "Avbryt",
-	msg: "Inga stavfel hittades",
-	iSkip: "Hoppa över",
-	iSkipAll: "Hoppa över alla liknande",
+	msg: "Det finns inga felstavningar",
+	iSkip: "Hoppa över det här",
+	iSkipAll: "Hoppa över alla sådana här",
 	iMsg: "Inga stavningsförslag"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/TableDialog.js b/dojox/editor/plugins/nls/sv/TableDialog.js
index 416c634..39dbe2b 100644
--- a/dojox/editor/plugins/nls/sv/TableDialog.js
+++ b/dojox/editor/plugins/nls/sv/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Infoga tabell",
 	modifyTableTitle: "Ändra tabell",
@@ -11,8 +10,8 @@ define(
 	tableWidth: "Tabellbredd:",
 	backgroundColor: "Bakgrundsfärg:",
 	borderColor: "Ramfärg:",
-	borderThickness: "Ramtjocklek",
-	percent: "%",
+	borderThickness: "Kantlinjetjocklek:",
+	percent: "procent",
 	pixels: "bildpunkter",
 	"default": "standard",
 	left: "vänsterjustera",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Ange", // translated elsewhere?
 	buttonInsert: "Infoga",
 	buttonCancel: "Avbryt",
-
 	selectTableLabel: "Välj tabell",
 	insertTableRowBeforeLabel: "Lägg till rad före",
 	insertTableRowAfterLabel: "Lägg till rad efter",
 	insertTableColumnBeforeLabel: "Lägg till kolumn före",
 	insertTableColumnAfterLabel: "Lägg till kolumn efter",
 	deleteTableRowLabel: "Ta bort rad",
-	deleteTableColumnLabel: "Ta bort kolumn"
+	deleteTableColumnLabel: "Ta bort kolumn",
+	colorTableCellTitle: "Bakgrundsfärg för tabellcell",
+	tableContextMenuTitle: "Kontextmeny för tabell"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/TextColor.js b/dojox/editor/plugins/nls/sv/TextColor.js
index 3d43fe5..4953f86 100644
--- a/dojox/editor/plugins/nls/sv/TextColor.js
+++ b/dojox/editor/plugins/nls/sv/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"setButtonText": "Ange",
+	"setButtonText": "Använd",
 	"cancelButtonText": "Avbryt"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/sv/latinEntities.js b/dojox/editor/plugins/nls/sv/latinEntities.js
index 9e7933d..527ac7d 100644
--- a/dojox/editor/plugins/nls/sv/latinEntities.js
+++ b/dojox/editor/plugins/nls/sv/latinEntities.js
@@ -1,261 +1,257 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"omvänt utropstecken",
-	cent:"centtecken",
-	pound:"pundtecken",
-	curren:"valutatecken",
-	yen:"yentecken\nyuantecken",
-	brvbar:"brutet lodrätt streck",
-	sect:"avsnittstecken",
-	uml:"trema",
-	copy:"copyrighttecken",
-	ordf:"indikator för feminint ordningstal",
-	laquo:"dubbelt vänstercitattecken",
+	cent:"cent",
+	pound:"pund",
+	curren:"valuta",
+	yen:"yen\nyuan",
+	brvbar:"brutet lodstreck",
+	sect:"stycketecken",
+	uml:"trema\nblanktecken med trema",
+	copy:"copyright",
+	ordf:"feminin ordinal",
+	laquo:"vänster dubbelt vinkelcitat\ndubbla vänsterpekande vinklar",
 	not:"inte-tecken",
-	shy:"mjukt blanksteg",
-	reg:"registrerat varumärke-tecken",
-	macr:"makron",
-	deg:"gradtecken",
-	plusmn:"plus/minus-tecken\nplus/minus-tecken",
-	sup2:"upphöjd tvåa\nkvadrat",
-	sup3:"upphöjd trea\nkubik",
-	acute:"akut accent",
-	micro:"mikrotecken",
-	para:"alinea\nstycketecken",
-	middot:"halvhög punkt",
-	cedil:"cedilj",
-	sup1:"upphöjd etta",
-	ordm:"indikator för maskulint ordningstal",
-	raquo:"dubbelt högercitattecken",
-	frac14:"en fjärdedel",
-	frac12:"en halv",
-	frac34:"tre fjärdedelar",
-	iquest:"omvänt frågetecken",
-	Agrave:"versalt latinskt a med grav accent",
-	Aacute:"versalt latinskt a med akut accent",
-	Acirc:"versalt latinskt a med cirkumflex",
-	Atilde:"versalt latinskt a med tilde",
-	Auml:"versalt latinskt a med trema",
-	Aring:"versalt latinskt a med ring",
-	AElig:"versal latinsk ae-ligatur",
-	Ccedil:"versalt latinskt c med cedilj",
-	Egrave:"versalt latinskt e med grav accent",
-	Eacute:"versalt latinskt e med akut accent",
-	Ecirc:"versalt latinskt e med cirkumflex",
-	Euml:"versalt latinskt e med trema",
-	Igrave:"versalt latinskt i med grav accent",
-	Iacute:"versalt latinskt i med akut accent",
-	Icirc:"versalt latinskt i med cirkumflex",
-	Iuml:"versalt latinskt i med trema",
-	ETH:"versalt latinskt eth",
-	Ntilde:"versalt latinskt n med tilde",
-	Ograve:"versalt latinskt o med grav accent",
-	Oacute:"versalt latinskt o med akut accent",
-	Ocirc:"versalt latinskt o med cirkumflex",
-	Otilde:"versalt latinskt o med tilde",
-	Ouml:"versalt latinskt o med trema",
-	times:"multiplikationstecken",
-	Oslash:"versalt latinskt o med streck",
-	Ugrave:"versalt latinskt u med grav accent",
-	Uacute:"versalt latinskt u med akut accent",
-	Ucirc:"versalt latinskt u med cirkumflex",
-	Uuml:"versalt latinskt u med trema",
-	Yacute:"versalt latinskt y med akut accent",
-	THORN:"versalt latinskt thorn",
-	szlig:"gement latinskt dubbel-s\nß",
-	agrave:"gement latinskt a med grav accent",
-	aacute:"gement latinskt a med akut accent",
-	acirc:"gement latinskt a med cirkumflex",
-	atilde:"gement latinskt a med tilde",
-	auml:"gement latinskt a med trema",
-	aring:"gement latinskt a med ring",
-	aelig:"gemen latinsk ae-ligatur",
-	ccedil:"gement latinskt c med cedilj",
-	egrave:"gement latinskt e med grav accent",
-	eacute:"gement latinskt e med akut accent",
-	ecirc:"gement latinskt e med cirkumflex",
-	euml:"gement latinskt e med trema",
-	igrave:"gement latinskt i med grav accent",
-	iacute:"gement latinskt i med akut accent",
-	icirc:"gement latinskt i med cirkumflex",
-	iuml:"gement latinskt i med trema",
-	eth:"gement latinskt eth",
-	ntilde:"gement latinskt n med tilde",
-	ograve:"gement latinskt o med grav accent",
-	oacute:"gement latinskt o med akut accent",
-	ocirc:"gement latinskt o med cirkumflex",
-	otilde:"gement latinskt o med tilde",
-	ouml:"gement latinskt o med trema",
-	divide:"divisionstecken",
-	oslash:"gement latinskt o med streck",
-	ugrave:"gement latinskt u med grav accent",
-	uacute:"gement latinskt u med akut accent",
-	ucirc:"gement latinskt u med cirkumflex",
-	uuml:"gement latinskt u med trema",
-	yacute:"gement latinskt y med akut accent",
-	thorn:"gement latinskt thorn",
-	yuml:"gement latinskt y med trema",
-
+	shy:"mjukt bindestreck\nmjukt bindestreck",
+	reg:"registrerat varumärke\nregistrerat varumärke",
+	macr:"makron\nblanktecken med makron\növerstruken\nAPL-överstreck",
+	deg:"grader",
+	plusmn:"plus-minus\nplus- och minustecken",
+	sup2:"upphöjd tvåa\nupphöjd siffra 2\nkvadrat",
+	sup3:"upphöjd trea\nupphöjd siffra 3\nkubik",
+	acute:"akut accent\nblanktecken med akut accent",
+	micro:"mikro",
+	para:"pilcrow\nstycketecken",
+	middot:"mellanpunkt\ngeorgianskt komma\ngrekisk mellanpunkt",
+	cedil:"cedilj\nblanktecken med cedilj",
+	sup1:"upphöjd etta\nupphöjd siffra 1",
+	ordm:"maskulin ordinal",
+	raquo:"höger dubbelt vinkelcitat\ndubbla högerpekande vinklar",
+	frac14:"Bråktal, en fjärdedel\nen fjärdedel",
+	frac12:"Bråktal, en halv\nen halv",
+	frac34:"Bråktal, tre fjärdedelar\ntre fjärdedelar",
+	iquest:"omvänt frågetecken\nomvänt frågetecken",
+	Agrave:"Latinsk versal bokstav A med grav accent\nVersalt A med grav accent",
+	Aacute:"Latinsk versal bokstav A med akut accent",
+	Acirc:"Latinsk versal bokstav A med cirkumflex",
+	Atilde:"Latinsk versal bokstav A med tilde",
+	Auml:"Latinsk versal bokstav A med trema",
+	Aring:"Latinsk versal bokstav A med ring ovanför\nVersalt A med ring",
+	AElig:"Latinsk versal bokstav AE\nVersalt AE",
+	Ccedil:"Latinsk versal bokstav C med cedilj",
+	Egrave:"Latinsk versal bokstav E med grav accent",
+	Eacute:"Latinsk versal bokstav E med akut accent",
+	Ecirc:"Latinsk versal bokstav E med cirkumflex",
+	Euml:"Latinsk versal bokstav E med trema",
+	Igrave:"Latinsk versal bokstav I med grav accent",
+	Iacute:"Latinsk versal bokstav I med akut accent",
+	Icirc:"Latinsk versal bokstav I med cirkumflex",
+	Iuml:"Latinsk versal bokstav I med trema",
+	ETH:"Latinsk versal bokstav ETH",
+	Ntilde:"Latinsk versal bokstav N med tilde",
+	Ograve:"Latinsk versal bokstav O med grav accent",
+	Oacute:"Latinsk versal bokstav O med akut accent",
+	Ocirc:"Latinsk versal bokstav O med cirkumflex",
+	Otilde:"Latinsk versal bokstav O med tilde",
+	Ouml:"Latinsk versal bokstav O med trema",
+	times:"multiplikation",
+	Oslash:"Latinsk versal bokstav O med snedstreck\nVersalt O med snedstreck",
+	Ugrave:"Latinsk versal bokstav U med grav accent",
+	Uacute:"Latinsk versal bokstav U med akut accent",
+	Ucirc:"Latinsk versal bokstav U med cirkumflex",
+	Uuml:"Latinsk versal bokstav U med trema",
+	Yacute:"Latinsk versal bokstav Y med akut accent",
+	THORN:"Latinsk versal bokstav THORN",
+	szlig:"Latinsk gemen bokstav skarpt s\nLilla skarpa s",
+	agrave:"Latinsk gemen bokstav a med grav accent\nGement a med grav accent",
+	aacute:"Latinsk gemen bokstav a med akut accent",
+	acirc:"Latinsk gemen bokstav a med cirkumflex",
+	atilde:"Latinsk gemen bokstav a med tilde",
+	auml:"Latinsk gemen bokstav a med trema",
+	aring:"Latinsk gemen bokstav a med ring ovanför\nGement a med ring",
+	aelig:"Latinsk gemen bokstav ae\nGement ae",
+	ccedil:"Latinsk gemen bokstav c med cedilj",
+	egrave:"Latinsk gemen bokstav e med grav accent",
+	eacute:"Latinsk gemen bokstav e med akut accent",
+	ecirc:"Latinsk gemen bokstav e med cirkumflex",
+	euml:"Latinsk gemen bokstav e med trema",
+	igrave:"Latinsk gemen bokstav i med grav accent",
+	iacute:"Latinsk gemen bokstav i med akut accent",
+	icirc:"Latinsk gemen bokstav i med cirkumflex",
+	iuml:"Latinsk gemen bokstav i med trema",
+	eth:"Latinsk gemen bokstav eth",
+	ntilde:"Latinsk gemen bokstav n med tilde",
+	ograve:"Latinsk gemen bokstav o med grav accent",
+	oacute:"Latinsk gemen bokstav o med akut accent",
+	ocirc:"Latinsk gemen bokstav o med cirkumflex",
+	otilde:"Latinsk gemen bokstav o med tilde",
+	ouml:"Latinsk gemen bokstav o med trema",
+	divide:"division",
+	oslash:"Latinsk gemen bokstav o med snedstreck\nGement o med snedstreck",
+	ugrave:"Latinsk gemen bokstav u med grav accent",
+	uacute:"Latinsk gemen bokstav u med akut accent",
+	ucirc:"Latinsk gemen bokstav u med cirkumflex",
+	uuml:"Latinsk gemen bokstav u med trema",
+	yacute:"Latinsk gemen bokstav y med akut accent",
+	thorn:"Latinsk gemen bokstav thorn",
+	yuml:"Latinsk gemen bokstav y med trema",
 // Greek Characters and Symbols
-	fnof:"gement latinskt f med krok\nfunktion\nflorin",
-	Alpha:"versalt grekiskt alfa",
-	Beta:"versalt grekiskt beta",
-	Gamma:"versalt grekiskt gamma",
-	Delta:"versalt grekiskt delta",
-	Epsilon:"versalt grekiskt epsilon",
-	Zeta:"versalt grekiskt zeta",
-	Eta:"versalt grekiskt eta",
-	Theta:"versalt grekiskt theta",
-	Iota:"versalt grekiskt iota",
-	Kappa:"versalt grekiskt kappa",
-	Lambda:"versalt grekiskt lambda",
-	Mu:"versalt grekiskt my",
-	Nu:"versalt grekiskt ny",
-	Xi:"versalt grekiskt xi",
-	Omicron:"versalt grekiskt omikron",
-	Pi:"versalt grekiskt pi",
-	Rho:"versalt grekiskt rho",
-	Sigma:"versalt grekiskt sigma",
-	Tau:"versalt grekiskt tau",
-	Upsilon:"versalt grekiskt ypsilon",
-	Phi:"versalt grekiskt fi",
-	Chi:"versalt grekiskt chi",
-	Psi:"versalt grekiskt psi",
-	Omega:"versalt grekiskt omega",
-	alpha:"gement grekiskt alfa",
-	beta:"gement grekiskt beta",
-	gamma:"gement grekiskt gamma",
-	delta:"gement grekiskt delta",
-	epsilon:"gement grekiskt epsilon",
-	zeta:"gement grekiskt zeta",
-	eta:"gement grekiskt eta",
-	theta:"gement grekiskt theta",
-	iota:"gement grekiskt iota",
-	kappa:"gement grekiskt kappa",
-	lambda:"gement grekiskt lambda",
-	mu:"gement grekiskt my",
-	nu:"gement grekiskt ny",
-	xi:"gement grekiskt xi",
-	omicron:"gement grekiskt omikron",
-	pi:"gement grekiskt pi",
-	rho:"gement grekiskt rho",
-	sigmaf:"gement grekiskt slutligt sigma",
-	sigma:"gement grekiskt sigma",
-	tau:"gement grekiskt tau",
-	upsilon:"gement grekiskt ypsilon",
-	phi:"gement grekiskt fi",
-	chi:"gement grekiskt chi",
-	psi:"gement grekiskt psi",
-	omega:"gement grekiskt omega",
-	thetasym:"gement grekiskt theta",
-	upsih:"grekiskt ypsilon med krok",
-	piv:"grekisk pi-symbol",
-	bull:"punkt\nliten smart cirkel",
-	hellip:"ellips\ntre punkter",
-	prime:"primtecken\nminuter\nfot",
-	Prime:"dubbelt primtecken\nsekunder\ntum",
-	oline:"överstrykning\navståndsöverstrykning",
-	frasl:"bråkstreck",
-	weierp:"versalt skript-P\nexponentuppsättning\nweierstrass-p",
-	image:"versalt I\nimaginärdelssymbol",
-	real:"versalt R\nrealdelssymbol",
-	trade:"varumärkessymbol",
-	alefsym:"alefsymbol",
+	fnof:"Latinsk gement f med hake\nfunktion\nflorin",
+	Alpha:"Grekisk versal bokstav alfa",
+	Beta:"Grekisk versal bokstav beta",
+	Gamma:"Grekisk versal bokstav gamma",
+	Delta:"Grekisk versal bokstav delta",
+	Epsilon:"Grekisk versal bokstav epsilon",
+	Zeta:"Grekisk versal bokstav zeta",
+	Eta:"Grekisk versal bokstav eta",
+	Theta:"Grekisk versal bokstav theta",
+	Iota:"Grekisk versal bokstav iota",
+	Kappa:"Grekisk versal bokstav kappa",
+	Lambda:"Grekisk versal bokstav lambda",
+	Mu:"Grekisk versal bokstav mu",
+	Nu:"Grekisk versal bokstav nu",
+	Xi:"Grekisk versal bokstav xi",
+	Omicron:"Grekisk versal bokstav omikron",
+	Pi:"Grekisk versal bokstav pi",
+	Rho:"Grekisk versal bokstav rho",
+	Sigma:"Grekisk versal bokstav sigma",
+	Tau:"Grekisk versal bokstav tau",
+	Upsilon:"Grekisk versal bokstav upsilon",
+	Phi:"Grekisk versal bokstav phi",
+	Chi:"Grekisk versal bokstav chi",
+	Psi:"Grekisk versal bokstav psi",
+	Omega:"Grekisk versal bokstav omega",
+	alpha:"Grekisk gemen bokstav alfa",
+	beta:"Grekisk gemen bokstav beta",
+	gamma:"Grekisk gemen bokstav gamma",
+	delta:"Grekisk gemen bokstav delta",
+	epsilon:"Grekisk gemen bokstav epsilon",
+	zeta:"Grekisk gemen bokstav zeta",
+	eta:"Grekisk gemen bokstav eta",
+	theta:"Grekisk gemen bokstav theta",
+	iota:"Grekisk gemen bokstav iota",
+	kappa:"Grekisk gemen bokstav kappa",
+	lambda:"Grekisk gemen bokstav lambda",
+	mu:"Grekisk gemen bokstav mu",
+	nu:"Grekisk gemen bokstav nu",
+	xi:"Grekisk gemen bokstav xi",
+	omicron:"Grekisk gemen bokstav omikron",
+	pi:"Grekisk gemen bokstav pi",
+	rho:"Grekisk gemen bokstav rho",
+	sigmaf:"Grekisk gemen bokstav avslutande sigma",
+	sigma:"Grekisk gemen bokstav sigma",
+	tau:"Grekisk gemen bokstav tau",
+	upsilon:"Grekisk gemen bokstav upsilon",
+	phi:"Grekisk gemen bokstav phi",
+	chi:"Grekisk gemen bokstav chi",
+	psi:"Grekisk gemen bokstav psi",
+	omega:"Grekisk gemen bokstav omega",
+	thetasym:"Grekisk gemen bokstav theta-symbol",
+	upsih:"Grekisk upsilon med hake",
+	piv:"Grekisk pi-symbol",
+	bull:"punkt\nsvart liten cirkel",
+	hellip:"horisontell ellips\ntre punkter",
+	prime:"prim\nminuter\nfot",
+	Prime:"dubbel prim\nsekunder\ntum",
+	oline:"överstrykning\nblanktecken med överstrykning",
+	frasl:"bråksnedstreck",
+	weierp:"skrivstil versalt P\nWeierstrass-p",
+	image:"gotisk versalt I\n",
+	real:"gotisk versalt R\n",
+	trade:"varumärke",
+	alefsym:"alef-symbol\nförsta transfinita kardinalvärdet",
 	larr:"vänsterpil",
 	uarr:"uppåtpil",
 	rarr:"högerpil",
 	darr:"nedåtpil",
-	harr:"vänster/höger-pil",
-	crarr:"nedåtpil ned vänstergående hörn\nradbrytning",
-	lArr:"vänsterdubbelpil",
-	uArr:"uppåtdubbelpil",
-	rArr:"högerdubbelpil",
-	dArr:"nedåtdubbelpil",
-	hArr:"vänster/höger-dubbelpil",
+	harr:"dubbelpil",
+	crarr:"nedåtpil med vänsterhörn\nvagnretur",
+	lArr:"dubbel vänsterpil",
+	uArr:"dubbel uppåtpil",
+	rArr:"dubbel högerpil",
+	dArr:"dubbel nedåtpil",
+	hArr:"dubbel dubbelpil",
 	forall:"för alla",
 	part:"partiell differential",
 	exist:"det finns",
-	empty:"tom uppsättning\nnull-uppsättning\ndiameter",
+	empty:"tom mängd\nnull-mängd\ndiameter",
 	nabla:"nabla\nbakåtdifferens",
 	isin:"element av",
 	notin:"inte element av",
-	ni:"innehåller som medlem",
-	prod:"n-unär produkt\nprodukttecken",
-	sum:"n-unär summering",
-	minus:"minustecken",
-	lowast:"asteriskoperator",
-	radic:"kvadratrot",
-	prop:"proportionellt mot",
-	infin:"oändligheten",
+	ni:"innehålls som medlem",
+	prod:"n-ställig produkt\nprodukt",
+	sum:"n-ställig summa",
+	minus:"minus",
+	lowast:"asterisk",
+	radic:"kvadratrot\nrotuttryck",
+	prop:"proportionellt till",
+	infin:"oändlighet",
 	ang:"vinkel",
-	and:"logiskt och",
-	or:"logiskt eller",
-	cap:"skärning",
-	cup:"union","int":"integral",
+	and:"logiskt och\nj",
+	or:"logiskt eller\n",
+	cap:"snitt\n",
+	cup:"union\n","int":"integral",
 	there4:"därför",
-	sim:"tildeoperator\nvarierar med\nliknar",
+	sim:"tilde-operator\nvarierar med\nliknar",
 	cong:"ungefär lika med",
-	asymp:"nästan lika med\nasymptotiskt med",
+	asymp:"nästan lika med\nasymptotiskt till",
 	ne:"inte lika med",
 	equiv:"identiskt med",
 	le:"mindre än eller lika med",
 	ge:"större än eller lika med",
 	sub:"delmängd av",
-	sup:"överordnad mängd till",
+	sup:"supermängd av",
 	nsub:"inte delmängd av",
 	sube:"delmängd av eller lika med",
-	supe:"överordnad mängd till eller lika med",
-	oplus:"plustecken i cirkel\ndirektsumma",
-	otimes:"multiplikationstecken i cirkel\nvektorprodukt",
-	perp:"uppåt\nortogonal mot\nvinkelrät",
+	supe:"supermängd av eller lika med",
+	oplus:"plus i cirkel\ndirektsumma",
+	otimes:"multiplikation i cirkel\nvektorprodukt",
+	perp:"nål uppåt\nortogonalt till\nvinkelrät mot",
 	sdot:"punktoperator",
-	lceil:"vänstertak",
+	lceil:"vänstertak\nAPL upp",
 	rceil:"högertak",
-	lfloor:"vänstergolv",
+	lfloor:"vänstergolv\nAPL ned",
 	rfloor:"högergolv",
-	lang:"vänstervinkelhakparentes",
-	rang:"högervinkelhakparentes",
+	lang:"vänster vinkelparentes",
+	rang:"höger vinkelparentes",
 	loz:"romb",
-	spades:"svart spader",
-	clubs:"svart klöver\ntreklöver",
-	hearts:"svart hjärter",
-	diams:"svart ruter",
-	OElig:"versal latinsk oe-ligatur",
-	oelig:"gemen latinsk oe-ligatur",
-	Scaron:"versalt latinskt s med karon",
-	scaron:"gement latinskt s med karon",
-	Yuml:"versalt latinskt y med trema",
-	circ:"modifieringscirkumflex",
+	spades:"spader",
+	clubs:"klöver\ntreklöver",
+	hearts:"hjärter\n",
+	diams:"ruter",
+	OElig:"Latinsk versal ligatur OE",
+	oelig:"Latinsk gemen ligatur oe",
+	Scaron:"Latinsk versal bokstav S med hake",
+	scaron:"Latinsk gemen bokstav s med hake",
+	Yuml:"Latinsk versal bokstav Y med trema",
+	circ:"cirkumflex accent",
 	tilde:"litet tilde",
-	ensp:"halvfyrkantsblanksteg",
-	emsp:"fyrkantsblanksteg",
-	thinsp:"tunt blanksteg",
-	zwnj:"mjukt hårfint blanksteg",
-	zwj:"hårt hårfint blanksteg",
-	lrm:"vänster-till-höger-märke",
-	rlm:"höger-till-vänster-märke",
-	ndash:"tankstreck",
+	ensp:"kort blanktecken",
+	emsp:"långt blanktecken",
+	thinsp:"tunt blanktecken",
+	zwnj:"zwnj (zero width non-joiner)",
+	zwj:"zwj (zero width joiner)",
+	lrm:"vänster till höger-markering",
+	rlm:"höger till vänster-markering",
+	ndash:"kort tankstreck",
 	mdash:"långt tankstreck",
-	lsquo:"enkelt vänstercitattecken",
-	rsquo:"enkelt högercitattecken",
-	sbquo:"enkelt underkantscitattecken",
-	ldquo:"dubbelt vänstercitattecken",
-	rdquo:"dubbelt högercitattecken",
-	bdquo:"dubbelt underkantscitattecken",
-	dagger:"kors",
-	Dagger:"dubbelkors",
+	lsquo:"vänster enkelt citat",
+	rsquo:"höger enkelt citat",
+	sbquo:"nedre enkelt citat",
+	ldquo:"vänster dubbelt citat",
+	rdquo:"höger dubbelt citat",
+	bdquo:"nedre dubbelt citat",
+	dagger:"enkelt kors",
+	Dagger:"dubbelt kors",
 	permil:"promille",
-	lsaquo:"enkel vänstervinkelparentes",
-	rsaquo:"enkel högervinkelparentes",
-	euro:"eurotecken"
+	lsaquo:"vänster enkelt vinkelcitat",
+	rsaquo:"höger enkelt vinkelcitat",
+	euro:"euro"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/AutoSave.js b/dojox/editor/plugins/nls/th/AutoSave.js
index 436a367..2b0e038 100644
--- a/dojox/editor/plugins/nls/th/AutoSave.js
+++ b/dojox/editor/plugins/nls/th/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "บันทึก",
 	"saveSettingLabelOn": "ตั้งช่วงเวลาบันทึกอัตโนมัติ...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "ถูกบันทึกเมื่อ ${0}",
 	"saveMessageFail": "ล้มเหลวในการบันทึกเมื่อ ${0}"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/Blockquote.js b/dojox/editor/plugins/nls/th/Blockquote.js
index 0081f58..47aee7d 100644
--- a/dojox/editor/plugins/nls/th/Blockquote.js
+++ b/dojox/editor/plugins/nls/th/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "บล็อกคำพูด"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/Breadcrumb.js b/dojox/editor/plugins/nls/th/Breadcrumb.js
index 98300cb..881f91f 100644
--- a/dojox/editor/plugins/nls/th/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/th/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} แอ็คชัน",
 	"selectContents": "เลือกเนื้อหา",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "ย้ายเคอร์เซอร์ไปยังจุดเริ่มต้น",
 	"moveEnd": "ย้ายเคอร์เซอร์ไปยังจุดสิ้นสุด"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/CollapsibleToolbar.js b/dojox/editor/plugins/nls/th/CollapsibleToolbar.js
index c29a1e7..9d9e2f4 100644
--- a/dojox/editor/plugins/nls/th/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/th/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "ยุบรวมแถบเครื่องมือตัวแก้ไข",
 	"expand": "ขยายแถบเครื่องมือตัวแก้ไข"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/FindReplace.js b/dojox/editor/plugins/nls/th/FindReplace.js
index 39ce585..94637f3 100644
--- a/dojox/editor/plugins/nls/th/FindReplace.js
+++ b/dojox/editor/plugins/nls/th/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "ค้นหา:",
 	"findTooltip": "ป้อนข้อความเพื่อหา",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "หาพบ",
 	"eofDialogTextReplace": "ถูกแทนที่"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/InsertAnchor.js b/dojox/editor/plugins/nls/th/InsertAnchor.js
index 5f439de..cba72d2 100644
--- a/dojox/editor/plugins/nls/th/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/th/InsertAnchor.js
@@ -1,13 +1,10 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "แทรกจุดยึด",
 	title: "คุณสมบัติจุดยึด",
 	anchor: "ชื่อ:",
-	text: "รายละเอียด",
-	set: "ตั้งค่า",
+	text: "คำอธิบาย:",
+	set: "เซ็ต",
 	cancel: "ยกเลิก"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/InsertEntity.js b/dojox/editor/plugins/nls/th/InsertEntity.js
index f702bfe..acac750 100644
--- a/dojox/editor/plugins/nls/th/InsertEntity.js
+++ b/dojox/editor/plugins/nls/th/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "แทรกสัญลักษณ์"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/LocalImage.js b/dojox/editor/plugins/nls/th/LocalImage.js
index cb5199d..2204b04 100644
--- a/dojox/editor/plugins/nls/th/LocalImage.js
+++ b/dojox/editor/plugins/nls/th/LocalImage.js
@@ -1,8 +1,7 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "แทรกรูปภาพ",
-	url: "รูปภาพ",
+	url: "Image",
 	browse: "เรียกดู...",
 	text: "รายละเอียด",
 	set: "แทรก",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "ป้อน URL ของรูปภาพ",
 	prePopuTextBrowse: " หรือเรียกดูโลคัลไฟล์"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/PageBreak.js b/dojox/editor/plugins/nls/th/PageBreak.js
index 2aedf25..d7ff692 100644
--- a/dojox/editor/plugins/nls/th/PageBreak.js
+++ b/dojox/editor/plugins/nls/th/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "เส้นกั้นหน้า"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/PasteFromWord.js b/dojox/editor/plugins/nls/th/PasteFromWord.js
index 8dde0e6..307833e 100644
--- a/dojox/editor/plugins/nls/th/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/th/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "วางจาก Word",
-	"paste": "วาง",
-	"cancel": "ยกเลิก",
 	"instructions": "วางเนื้อหาจาก Word ลงในกล่องข้อความข้างล่าง เมื่อคุณพอใจกับเนื้อหาที่แทรกแล้วให้กดปุ่ม วาง เมื่อต้องการยกเลิกการเรียงลำดับข้อความให้กดปุ่ม ยกเลิก"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/Preview.js b/dojox/editor/plugins/nls/th/Preview.js
index a879e19..cc0001b 100644
--- a/dojox/editor/plugins/nls/th/Preview.js
+++ b/dojox/editor/plugins/nls/th/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "แสดงตัวอย่าง"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/SafePaste.js b/dojox/editor/plugins/nls/th/SafePaste.js
index 742bde0..5a33745 100644
--- a/dojox/editor/plugins/nls/th/SafePaste.js
+++ b/dojox/editor/plugins/nls/th/SafePaste.js
@@ -1,5 +1,5 @@
 define(
 ({
-	"instructions": "การแปะโดยตรงถูกปิดใช้งาน. โปรดแปะเนื้อหาในไดอะล็อกนี้โดยใช้คีบอร์ดเบราว์เซอร์พื้นฐานหรือการควบคุมเมนูการแปะ  เมื่อคุณพอใจกับเนื้อหาที่จะแทรก กดปุ่มแปะ ในการที่จะยกเลิกการแทรกเนื้อหา กดปุ่มยกเลิก"
+	"instructions": "การแปะโดยตรงถูกปิดใช้งาน. โปรดแปะเนื้อหาในไดอะล็อกนี้โดยใช้คีย์บอร์ดเบราว์เซอร์พื้นฐานหรือการควบคุมเมนูการแปะ  เมื่อคุณพอใจกับเนื้อหาที่จะแทรก กดปุ่มแปะ ในการที่จะยกเลิกการแทรกเนื้อหา กดปุ่มยกเลิก"
 })
 );
diff --git a/dojox/editor/plugins/nls/th/Save.js b/dojox/editor/plugins/nls/th/Save.js
index 4f22ac6..a354970 100644
--- a/dojox/editor/plugins/nls/th/Save.js
+++ b/dojox/editor/plugins/nls/th/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "บันทึก"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/ShowBlockNodes.js b/dojox/editor/plugins/nls/th/ShowBlockNodes.js
index 1e20d9a..2e05628 100644
--- a/dojox/editor/plugins/nls/th/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/th/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "แสดงอิลิเมนต์บล็อก HTML"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/Smiley.js b/dojox/editor/plugins/nls/th/Smiley.js
index df827d9..d5da053 100644
--- a/dojox/editor/plugins/nls/th/Smiley.js
+++ b/dojox/editor/plugins/nls/th/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "แทรกไอคอนแสดงอารมณ์",
 	emoticonSmile: "ยิ้ม",
@@ -13,15 +12,13 @@ define(
 	emoticonFrown: "หน้าบึ้ง",
 	emoticonShy: "อาย",
 	emoticonGoofy: "โง่",
-	emoticonOops: "oops",
+	emoticonOops: "อุ๊ปส์",
 	emoticonTongue: "แลบลิ้น",
 	emoticonIdea: "ความคิด",
 	emoticonYes: "ใช่",
 	emoticonNo: "ไม่ใช่",
-	emoticonAngel: "โมโห",
+	emoticonAngel: "เทวดา",
 	emoticonCrying: "ร้องไห้",
 	emoticonHappy: "มีความสุข"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/SpellCheck.js b/dojox/editor/plugins/nls/th/SpellCheck.js
index 83cc92f..98cef9c 100644
--- a/dojox/editor/plugins/nls/th/SpellCheck.js
+++ b/dojox/editor/plugins/nls/th/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "ตรวจสอบการสะกดคำแบบแบตช์",
 	unfound: "ไม่พบ",
@@ -10,12 +9,10 @@ define(
 	replace: "แทนที่",
 	replaceWith: "แทนที่ด้วย",
 	replaceAll: "แทนที่ทั้งหมด",
-	cancel: "Cancel",
+	cancel: "ยกเลิก",
 	msg: "ไม่พบคำที่สะกดผิด",
 	iSkip: "ข้ามนี้",
 	iSkipAll: "ข้ามที่เหมือนนี้",
 	iMsg: "ไม่มีการแนะนำการสะกด"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/TableDialog.js b/dojox/editor/plugins/nls/th/TableDialog.js
index 4491e10..5d8c3b4 100644
--- a/dojox/editor/plugins/nls/th/TableDialog.js
+++ b/dojox/editor/plugins/nls/th/TableDialog.js
@@ -1,34 +1,33 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "แทรกตาราง",
-	modifyTableTitle: "ปรับเปลี่ยนไขตาราง",
+	modifyTableTitle: "แก้ไขตาราง",
 	rows: "แถว:",
 	columns: "คอลัมน์:",
-	align: "จัดตำแหน่ง:",
-	cellPadding: "ส่วนเสริมเซลล์:",
-	cellSpacing: "ระยะห่างเซลล์:",
+	align: "จัดแนว:",
+	cellPadding: "ความสูงของเซลล์:",
+	cellSpacing: "ระยะห่างของเซลล์:",
 	tableWidth: "ความกว้างของตาราง:",
 	backgroundColor: "สีพื้นหลัง:",
 	borderColor: "สีเส้นขอบ:",
-	borderThickness: "ความหนาเส้นขอบ",
+	borderThickness: "ความกว้างของขอบ",
 	percent: "เปอร์เซ็นต์",
 	pixels: "พิกเซล",
 	"default": "ดีฟอลต์",
 	left: "ซ้าย",
 	center: "กึ่งกลาง",
 	right: "ขวา",
-	buttonSet: "ตั้งค่า", // translated elsewhere?
+	buttonSet: "เซ็ต", // translated elsewhere?
 	buttonInsert: "แทรก",
 	buttonCancel: "ยกเลิก",
-
 	selectTableLabel: "เลือกตาราง",
 	insertTableRowBeforeLabel: "เพิ่มแถวก่อน",
-	insertTableRowAfterLabel: "เพิ่มแถวหลัง",
+	insertTableRowAfterLabel: "เพิ่มแถวหลังจาก",
 	insertTableColumnBeforeLabel: "เพิ่มคอลัมน์ก่อน",
-	insertTableColumnAfterLabel: "เพิ่มคอลัมน์หลัง",
+	insertTableColumnAfterLabel: "เพิ่มคอลัมน์หลังจาก",
 	deleteTableRowLabel: "ลบแถว",
-	deleteTableColumnLabel: "ลบคอลัมน์"
+	deleteTableColumnLabel: "ลบคอลัมน์",
+	colorTableCellTitle: "เซลล์ตารางสีพื้นหลัง",
+	tableContextMenuTitle: "เมนูบริบทตาราง"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/TextColor.js b/dojox/editor/plugins/nls/th/TextColor.js
index 50de4f2..2a91610 100644
--- a/dojox/editor/plugins/nls/th/TextColor.js
+++ b/dojox/editor/plugins/nls/th/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "เซ็ต",
 	"cancelButtonText": "ยกเลิก"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/th/latinEntities.js b/dojox/editor/plugins/nls/th/latinEntities.js
index b1ea2c6..318b275 100644
--- a/dojox/editor/plugins/nls/th/latinEntities.js
+++ b/dojox/editor/plugins/nls/th/latinEntities.js
@@ -1,50 +1,49 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"เครื่องหมายอัศเจรีย์กลับหัว",
-	cent:"เครื่องหมาย เซ็นต์",
+	cent:"เครื่องหมายเซ็นต์",
 	pound:"เครื่องหมายปอนด์",
 	curren:"เครื่องหมายสกุลเงิน",
-	yen:"เครื่องหมาย เยน\เครื่องหมาย หยวน",
-	brvbar:"แถบแยก\nแถบแยกแนวตั้ง",
+	yen:"เครื่องหมาย เยน\nเครื่องหมาย หยวน",
+	brvbar:" แถบแยก\nแถบแยกแนวตั้ง",
 	sect:"เครื่องหมายแบ่งส่วน",
-	uml:"ไดเอเรซิส\nช่องว่างของไดเอเรซิส",
+	uml:"diaeresis\nspacing diaeresis",
 	copy:"เครื่องหมายลิขสิทธิ์",
 	ordf:"ตังบ่งชี้ลำดับของผู้หญิง",
-	laquo:"เครื่องหมายคำพูดที่ชี้ไปทางซ้าย\nguillemet ที่ชี้ไปทางซ้าย",
-	not:"ลัญญลักษณ์ น็อท",
-	shy:"ซิร์ฟไฮเฟน\nไฮเฟนการตัดสินใจ",
-	reg:"ลัญญลักษณ์การจดทะเบียน\nลัญญลักษณ์เครื่องหมายการค้าจดทะเบียน",
-	macr:"ไมครอน\nช่องว่างของไมครอน\noverline\nAPL overbar",
-	deg:"สัญญลักษณ์องศา",
+	laquo:"เครื่องหมายคำพูดที่ชี้ไปทางซ้าย\nอัญประกาศที่ชี้ไปทางซ้าย   ",
+	not:"ลัญลักษณ์ น็อท",
+	shy:"ซอร์ฟไฮเฟน\nไฮเฟนการตัดสินใจ",
+	reg:"สัญญลักษณ์การจดทะเบียน\nสัญญลักษณ์เครื่องหมายการค้าจดทะเบียน",
+	macr:"มาครอน\nมาครอนการเว้นช่องว่าง\nโอเวอร์ไลน์\nAPL โอเวอร์บาร์",
+	deg:"สัญลักษณ์องศา",
 	plusmn:"เครื่องหมายบวก-ลบ\nเครื่องหมายบวก-หรือ-ลบ",
-	sup2:"ตัวยกสอง\nตัวยกหลักสอง\nยกกำลังสอง",
-	sup3:"ตัวยกสาม\nตัวยกหลักสาม\ncubed",
+	sup2:"ตัวยกสอง\nตัวยกเลขสอง\nสแควร์",
+	sup3:"ตัวยกสาม\nตัวยกเลขสาม\nคิวบ์",
 	acute:"acute accent\nช่องว่างของอคิวท์",
 	micro:"เครื่องหมายไมโคร",
 	para:"เครื่องหมาย pilcrow\nเครื่องหมายย่อหน้า",
-	middot:"จุดกึ่งกลาง\nคอมม่า Georgian\nจุดกึ่งกลางภาษากรีซ",
-	cedil:"ซีดิลลา\nช่องว่างของซีดิลลา",
-	sup1:"ตัวยกหนึ่ง\nตัวยกหลักหนึ่ง",
-	ordm:"ตังบ่งชี้ลำดับของผู้ชาย",
+	middot:"จุดกึ่งกลาง\nคอมม่าGeorgian\nจุดกึ่งกลางภาษากรีก",
+	cedil:"cedilla\ncedilla ช่องว่าง",
+	sup1:" ตัวยกหนึ่ง\nตัวยกหลักหนึ่ง",
+	ordm:"ตัวบ่งชี้ลำดับของผู้ชาย",
 	raquo:"เครื่องหมายคำพูดที่ชี้ไปทางขวา\nguillemet ที่ชี้ไปทางขวา",
-	frac14:"เศษหนึ่งส่วนสี่แบบหยาบๆ\nเศษหนึ่งส่วนสี่",
-	frac12:"เศษหนึ่งส่วนสองแบบหยาบๆ\nเศษหนึ่งส่วนสอง",
-	frac34:"เศษสามส่วนสี่แบบหยาบๆ\nเศษสามส่วนสี่",
-	iquest:"เครื่องหมายคำถามกลับหัว\nเครื่อหมายคำถามกลับหัว",
-	Agrave:"อักษร A ตัวใหญ่ภาษาละติน A ที่มีเครื่องหมายกราฟ\nอักษร A ตัวใหญ่ภาษาละตินที่มีเครื่องหมายกราฟ",
+	frac14:"  เศษหนึ่งส่วนสี่แบบหยาบๆ\nเศษหนึ่งส่วนสี่",
+	frac12:" เศษหนึ่งส่วนสองแบบหยาบๆ\nเศษหนึ่งส่วนสอง",
+	frac34:"    เศษสามส่วนสี่แบบหยาบๆ\nเศษสามส่วนสี่",
+	iquest:" เครื่องหมายคำถามกลับหัว\nเครื่องหมายคำถามกลับหัว",
+	Agrave:" อักษร A ตัวใหญ่ภาษาละตินที่มีเครื่องหมายกราฟอักษร\n A ตัวใหญ่ภาษาละตินที่มีเครื่องหมายกราฟ",
 	Aacute:"อักษรละติน A ตัวใหญ่ พร้อมเครื่องหมายอคิวท์",
-	Acirc:"อักษรละติน A ตัวใหญ่ที่มีเครื่องหมายเซอร์คัมเฟลกซ์ ",
+	Acirc:"อักษรละติน A ตัวใหญ่ที่มีเครื่องหมายเซอร์คัมเฟลกซ์",
 	Atilde:"อักษรละติน A ตัวใหญ่ที่มีเครื่องหมายทิลเดอ",
 	Auml:"อักษรละติน A ตัวใหญ่ที่มีเครื่องหมายไดเอเรซิส",
-	Aring:"อักษรละติน A ตัวใหญ่ที่มีเครื่องหมายวงแหวนด้านบน\nอักษรละติน A ตัวใหญ่ที่มีเครื่องหมายวงแหวน",
-	AElig:"อักษรละติน AE ตัวใหญ่\nอักษรละติน AE ตัวใหญ่ที่ติดกัน",
+	Aring:" อักษรละติน A ตัวใหญ่ที่มีเครื่องหมายวงแหวนด้านบน\nอักษรละติน A ตัวใหญ่ที่มีเครื่องหมายวงแหวน",
+	AElig:"อักษรละติน AE ตัวใหญ่อักษรละติน\nAE ตัวใหญ่ที่ติดกัน",
 	Ccedil:"อักษรละติน C ตัวใหญ่ที่มีเครื่องหมายซีดิลลา",
 	Egrave:"อักษรละติน E ตัวใหญ่ที่มีเครื่องหมายกราฟ",
 	Eacute:"อักษรละติน E ตัวใหญ่ที่มีเครื่องหมายอคิวท์",
@@ -62,20 +61,20 @@ define(
 	Otilde:"อักษรละติน O ตัวใหญ่ที่มีเครื่องหมายทิลเดอ",
 	Ouml:"อักษรละติน O ตัวใหญ่ที่มีเครื่องหมายไดเอเรซิส",
 	times:"เครื่องหมายคูณ",
-	Oslash:"อักษรละติน O ตัวใหญ่ที่มีเครื่องหมายแลช\nกษรละติน O ตัวใหญ่ที่มีเครื่องหมายสแลช",
+	Oslash:" อักษรละติน O ตัวใหญ่ที่มีเครื่องหมายแลชกษรละติน O ตัวใหญ่ที่มีเครื่องหมายสแลช",
 	Ugrave:"อักษรละติน U ตัวใหญ่ที่มีเครื่องหมายกราฟ",
 	Uacute:"อักษรละติน U ตัวใหญ่ที่มีเครื่องหมายอคิวท์",
 	Ucirc:"อักษรละติน U ตัวใหญ่ที่มีเครื่องหมายเซอร์คัมเฟลกซ์",
 	Uuml:"อักษรละติน U ตัวใหญ่ที่มีเครื่องหมายไดเอเรซิส",
 	Yacute:"อักษรละติน Y ตัวใหญ่ที่มีเครื่องหมายอคิวท์",
 	THORN:"อักษรละติน THORN ตัวใหญ่",
-	szlig:"อักษร sharp s ตัวเล็กภาษาละติน\ness-zed",
-	agrave:"อักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายกราฟ\nอักษร a ตัวล็กภาษาละตินที่มีเครื่องหมายกราฟ",
+	szlig:" อักษร sharp s ตัวเล็กภาษาละตินess-zed",
+	agrave:"อักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายกราฟอักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายกราฟ",
 	aacute:"อักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายอคิวท์",
 	acirc:"อักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายเซอร์คัมเฟลกซ์",
 	atilde:"อักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายทิลเดอ",
 	auml:"อักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายไดเอเรซิส",
-	aring:"อักษร a ตัวเล็กภาษาละตินที่มีวงแหวนข้างบน\nอักษร a ตัวล็กภาษาละตินที่มีวงแหวน",
+	aring:"อักษร a ตัวเล็กภาษาละตินที่มีวงแหวนข้างบน\nอักษร a ตัวเล็กภาษาละตินที่มีวงแหวน",
 	aelig:"อักษร ae ตัวเล็กภาษาละติน\nอักษร ae ตัวเล็กภาษาละตินที่ติดกัน",
 	ccedil:"อักษร c ตัวเล็กภาษาละตินที่มีเครื่องหมายซีดิลลา",
 	egrave:"อักษร c ตัวเล็กภาษาละตินที่มีเครื่องหมายกราฟ",
@@ -94,7 +93,7 @@ define(
 	otilde:"อักษร o ตัวเล็กภาษาละตินที่มีเครื่องหมายทิลเดอ",
 	ouml:"อักษร o ตัวเล็กภาษาละตินที่มีเครื่องหมายไดเอเรซิส",
 	divide:"เครื่องหมายหาร",
-	oslash:"อักษรละติน o ตัวเล็กที่มีเครื่องหมายแลช\nอักษรละติน o ตัวเล็กที่มีเครื่องหมายสแลช",
+	oslash:" อักษรละติน o ตัวเล็กที่มีเครื่องหมายแลช\nอักษรละติน o ตัวเล็กที่มีเครื่องหมายสแลช",
 	ugrave:"อักษร u ตัวเล็กภาษาละตินที่มีเครื่องหมายกราฟ",
 	uacute:"อักษร u ตัวเล็กภาษาละตินที่มีเครื่องหมายอคิวท์",
 	ucirc:"อักษร u ตัวเล็กภาษาละตินที่มีเครื่องหมายเซอร์คัมเฟลกซ์",
@@ -102,9 +101,8 @@ define(
 	yacute:"อักษร y ตัวเล็กภาษาละตินที่มีเครื่องหมายอคิวท์",
 	thorn:"อักษร thorn ตัวเล็กภาษาละติน",
 	yuml:"อักษร y ตัวเล็กภาษาละตินที่มีเครื่องหมายไดเอเรซิส",
-
 // Greek Characters and Symbols
-	fnof:"อักษร f ตัวเล็กภาษาละตินที่มีห่วง\nฟังก์ชัน\nflorin",
+	fnof:"   อักษร f ตัวเล็กภาษาละตินที่มีห่วงฟังก์ชันflorin",
 	Alpha:"อักษรอัลฟาตัวใหญ่ภาษากรีซ",
 	Beta:"อักษรเบตาตัวใหญ่ภาษากรีซ",
 	Gamma:"อักษรแกมม่าตัวใหญ่ภาษากรีซ",
@@ -154,26 +152,26 @@ define(
 	chi:"อักษร chi ตัวเล็กภาษากรีซ",
 	psi:"อักษร psi ตัวเล็กภาษากรีซ",
 	omega:"อักษรโอเมกาตัวเล็กภาษากรีซ",
-	thetasym:"อักษรสัญญลักษณ์ทีตาตัวเล็กภาษากรีซ",
-	upsih:"อักษรอิปไซลอนภาษากริซที่มีสัญญลักษณ์ห่วง",
-	piv:"สัญญลักษณ์ pi ภาษากรีซ",
+	thetasym:"อักษรสัญลักษณ์ทีตาตัวเล็กภาษากรีซ",
+	upsih:"อักษรอิปไซลอนภาษากริซที่มีสัญลักษณ์ห่วง",
+	piv:"สัญลักษณ์ pi ภาษากรีซ",
 	bull:"จุดนำ\nวงกลมสีดำเล็กๆ",
-	hellip:"จุดแนวนอน\nจุดนำสามจุด",
-	prime:"เครื่องหมายไพร์ม\nนาที\nฟุต",
-	Prime:"เครื่องหมายดับเบิลไพร์ม\nวินาที\nนิ้ว",
-	oline:"overline\nช่องว่าง overscore",
+	hellip:"  จุดแนวนอน\nจุดนำสามจุด  ",
+	prime:"สูง\nนาที\nฟุต",
+	Prime:"สูงคู่\nวินาที\nนิ้ว",
+	oline:"ข้ามเส้น\nคะแนนเกินช่องว่าง",
 	frasl:"สแลชเศษส่วน",
-	weierp:"สคริปต์ P ตัวใหญ่\npower set\nWeierstrass p",
+	weierp:"สคริปต์ P ตัวใหญ่power set\nWeierstrass p",
 	image:"ตัวอักษร I สีดำตัวใหญ่\nส่วนสมมุติ",
-	real:"ตัวอักษร R สีดำตัวใหญ่\nสัญญลักษณ์ส่วนที่แท้จริง",
-	trade:"สัญญลักษณ์เครื่องหมายการค้า",
-	alefsym:"สัญญลักษณ์ alef\nfirst transfinite cardinal",
+	real:"ตัวอักษร R สีดำตัวใหญ่\nสัญลักษณ์ส่วนที่แท้จริง",
+	trade:"สัญลักษณ์เครื่องหมายการค้า",
+	alefsym:"สัญลักษณ์ alef\nเลขสำหรับจำนวนนับแรก",
 	larr:"ลูกศรชี้ไปทางซ้าย",
 	uarr:"ลูกศรชี้ขึ้นบน",
 	rarr:"ลูกศรชี้ไปทางขวา",
 	darr:"ลูกศรชี้ลง",
 	harr:"ลูกศรซ้ายขวา",
-	crarr:"ลูกศรชี้ลงที่มีมุมไปทางซ้าย\ncarriage return",
+	crarr:"ลูกศรชี้ลงที่มีมุมไปทางซ้าย\nปัดแคร่",
 	lArr:"ลูกศรสองตัวชี้ไปทางซ้าย",
 	uArr:"ลูกศรสองตัวที่ชี้ไปข้างบน",
 	rArr:"ลูกศรสองตัวชี้ไปทางขวา",
@@ -182,27 +180,27 @@ define(
 	forall:"สำหรับทั้งหมด",
 	part:"แตกต่างบางส่วน",
 	exist:"ที่มีอยู่",
-	empty:"เซ็ตว่าง\nเซ็ต null\nเส้นผ่าศูนย์กลาง",
-	nabla:"nabla\nความแตกต่างไปข้างหลัง",
+	empty:"ชุดว่าง\nชุด null\nเส้นผ่าศูนย์กลาง",
+	nabla:"nabla\nความแตกต่างย้อนหลัง",
 	isin:"อิลิเมนต์ของ",
 	notin:"ไม่ใช่อิลิเมนต์ของ",
 	ni:"รวมเป็นสมาชิก",
-	prod:"ผลิตภัณฑ์ n-ary\เครื่องหมายผลิตภัณฑ์",
-	sum:"n-ary sumation",
+	prod:"ผลิตภัณฑ์ n-ary\nสัญลักษณ์ผลิตภัณฑ์",
+	sum:"ผลรวม n-ary",
 	minus:"เครื่องหมายลบ",
 	lowast:"โอเปอเรเตอร์เครื่องหมายดอกจัน",
-	radic:"สแควร์รูท\nเครื่องหมายราก",
+	radic:"รากที่สอง\nเครื่องหมายกรณฑ์",
 	prop:"เป็นสัดส่วนกับ",
 	infin:"อนันต์",
 	ang:"มุม",
-	and:"โลจิคัลและ\nwedge",
-	or:"โลจิคัล หรือ\nvee",
-	cap:"อินเตอร์เซกชัน\ncap",
-	cup:"ยูเนียน\ncup","int":"อินทีกรัล",
+	and:"ตรรกะ และ\nวิธีการ",
+	or:"ตรรกะ\nวี",
+	cap:"สี่แยก\nแค็ป",
+	cup:"สหภาพ\nคัพ","int":"อินทีกรัล",
 	there4:"ดังนั้น",
-	sim:"โอเปอเรเตอร์ดิลเดอ\nแตกต่างกับ\nเหมือนกับ",
+	sim:"ตัวดำเนินการ tilde\nแปรเปลี่ยนกับ\nเหมือนกับ",
 	cong:"ประมาณเท่ากับ",
-	asymp:"เกือบเท่ากับ\nasymptotic to",
+	asymp:"เกือบเท่ากับ\nเกี่ยวกับ",
 	ne:"ไม่เท่ากับ",
 	equiv:"เหมือนกับ",
 	le:"น้อยกว่าหรือเท่ากับ",
@@ -212,21 +210,21 @@ define(
 	nsub:"ไม่ใช่เซ็ตย่อยของ",
 	sube:"เซ็ตย่อยของหรือเท่ากับ",
 	supe:"ซุปเปอร์เซ็ตของหรือเท่ากับ",
-	oplus:"เครื่องหมายวงกลม\nผลรวมโดยตรง",
-	otimes:"วงกลมครั้ง\nผลิตภัณฑ์เวคเตอร์",
-	perp:"up tack\northogonal to\nperpendicular",
-	sdot:"โอเปอเรเตอร์จุด",
-	lceil:"เพดานด้านซ้าย\nAPL upstile",
+	oplus:"บวกวงกลม\nผลรวมโดยตรง",
+	otimes:"เวลาวงกลม\nผลิตภัณฑ์เวคเตอร์",
+	perp:"ตั้งตรง\nไปทางเหนือ\nตั้งฉาก",
+	sdot:"ตัวดำเนินการจุด",
+	lceil:"เพดานซ้าย\nAPL upstile",
 	rceil:"เพดานด้านขวา",
-	lfloor:"พื้นด้านซ้าย\nAPL downstile",
-	rfloor:"พื้นด้านซ้าย",
+	lfloor:"พื้นด้านซ้าย\nดาวน์ไซต์ APL",
+	rfloor:"พื้นด้านขวา",
 	lang:"วงเล็บซ้าย",
 	rang:"วงเล็บขวา",
-	loz:"lozenge",
-	spades:"black spade suit",
-	clubs:"black club suit\nshamrock",
-	hearts:"black heart suit\nvalentine",
-	diams:"black diamond suit",
+	loz:"รูปเพชร",
+	spades:"โพดำ",
+	clubs:"สูทคลับสีดำ\nshamrock",
+	hearts:"สูทหัวใจดำ\nวาเลนไทน์",
+	diams:"ข้าวหลามตัด",
 	OElig:"อักษรละติน OE ตัวใหญ่",
 	oelig:"อักษร oe ตัวเล็กติดกันภาษาละติน",
 	Scaron:"อักษรละติน S ตัวใหญ่ที่มีเครื่องหมายคารอน",
@@ -249,13 +247,11 @@ define(
 	ldquo:"เครื่องหมายคำพูดคู่ด้านซ้าย",
 	rdquo:"เครื่องหมายคำพูดคู่ด้านขวา",
 	bdquo:"เครื่องหมายคำพูด low-9 คู่",
-	dagger:"dagger",
-	Dagger:"dagger คู่",
+	dagger:"แด็กเกอร์",
+	Dagger:"แด็กเกอร์คู่",
 	permil:"เครื่องหมาย per mille",
 	lsaquo:"เครื่องหมายคำพูดเดี่ยวที่ชี้ไปด้านซ้าย",
 	rsaquo:"เครื่องหมายคำพูดเดี่ยวที่ชี้ไปด้านขวา",
 	euro:"เครื่องหมายยูโร"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/AutoSave.js b/dojox/editor/plugins/nls/tr/AutoSave.js
index 7cb0275..07f283e 100644
--- a/dojox/editor/plugins/nls/tr/AutoSave.js
+++ b/dojox/editor/plugins/nls/tr/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "Kaydet",
 	"saveSettingLabelOn": "Otomatik Kaydetme Aralığını Ayarla...",
@@ -13,6 +12,4 @@ define(
 	"saveMessageSuccess": "${0} konumuna kaydedildi",
 	"saveMessageFail": "${0} konumuna kaydedilemedi"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/Blockquote.js b/dojox/editor/plugins/nls/tr/Blockquote.js
index d399017..2d2de19 100644
--- a/dojox/editor/plugins/nls/tr/Blockquote.js
+++ b/dojox/editor/plugins/nls/tr/Blockquote.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "Öbek"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/Breadcrumb.js b/dojox/editor/plugins/nls/tr/Breadcrumb.js
index ff18e96..94af74f 100644
--- a/dojox/editor/plugins/nls/tr/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/tr/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} Eylemleri",
 	"selectContents": "İçindekileri seç",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "İmleci başa taşı",
 	"moveEnd": "İmleci sona taşı"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/CollapsibleToolbar.js b/dojox/editor/plugins/nls/tr/CollapsibleToolbar.js
index 4d75416..33dc320 100644
--- a/dojox/editor/plugins/nls/tr/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/tr/CollapsibleToolbar.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "Düzenleyici Araç Çubuğunu Daralt",
 	"expand": "Düzenleyici Araç Çubuğunu Genişlet"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/FindReplace.js b/dojox/editor/plugins/nls/tr/FindReplace.js
index 8087970..cc25dcb 100644
--- a/dojox/editor/plugins/nls/tr/FindReplace.js
+++ b/dojox/editor/plugins/nls/tr/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "Bul:",
 	"findTooltip": "Bulunacak metni girin",
@@ -21,6 +20,4 @@ define(
 	"eofDialogTextFind": "bulundu",
 	"eofDialogTextReplace": "değiştirildi"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/InsertAnchor.js b/dojox/editor/plugins/nls/tr/InsertAnchor.js
index 9db6349..259dcde 100644
--- a/dojox/editor/plugins/nls/tr/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/tr/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "Tutturucu Ekle",
 	title: "Tutturucu Özellikleri",
@@ -8,6 +7,4 @@ define(
 	set: "Ayarla",
 	cancel: "İptal"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/InsertEntity.js b/dojox/editor/plugins/nls/tr/InsertEntity.js
index 96fab89..780453c 100644
--- a/dojox/editor/plugins/nls/tr/InsertEntity.js
+++ b/dojox/editor/plugins/nls/tr/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "Simge Ekle"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/LocalImage.js b/dojox/editor/plugins/nls/tr/LocalImage.js
index 82817e2..df5031d 100644
--- a/dojox/editor/plugins/nls/tr/LocalImage.js
+++ b/dojox/editor/plugins/nls/tr/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "Resim Ekle",
 	url: "Resim",
@@ -10,6 +9,4 @@ define(
 	prePopuTextUrl: "Bir resim URL'si girin",
 	prePopuTextBrowse: " ya da yerel bir dosyaya göz atın."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/PageBreak.js b/dojox/editor/plugins/nls/tr/PageBreak.js
index db593fa..5f782ee 100644
--- a/dojox/editor/plugins/nls/tr/PageBreak.js
+++ b/dojox/editor/plugins/nls/tr/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "Sayfa Sonu"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/PasteFromWord.js b/dojox/editor/plugins/nls/tr/PasteFromWord.js
index de1463e..c2fdea9 100644
--- a/dojox/editor/plugins/nls/tr/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/tr/PasteFromWord.js
@@ -1,11 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "Word'den Kopyala",
-	"paste": "Yapıştır",
-	"cancel": "İptal",
 	"instructions": "İçeriği Word'den aşağıdaki metin kutusuna yapıştırın. Eklediğiniz içerikten memnunsanız, Yapıştır düğmesini tıklatın. Metin eklemeyi durdurmak için İptal düğmesini tıklatın."
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/Preview.js b/dojox/editor/plugins/nls/tr/Preview.js
index 0fd1c66..b0fb359 100644
--- a/dojox/editor/plugins/nls/tr/Preview.js
+++ b/dojox/editor/plugins/nls/tr/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "Önizleme"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/Save.js b/dojox/editor/plugins/nls/tr/Save.js
index 5e9d22c..cde2a69 100644
--- a/dojox/editor/plugins/nls/tr/Save.js
+++ b/dojox/editor/plugins/nls/tr/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "Kaydet"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/ShowBlockNodes.js b/dojox/editor/plugins/nls/tr/ShowBlockNodes.js
index 61f6eaf..4fe08a0 100644
--- a/dojox/editor/plugins/nls/tr/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/tr/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "HTML Bloğu Öğelerini Göster"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/Smiley.js b/dojox/editor/plugins/nls/tr/Smiley.js
index 6944bd8..4a0e9c0 100644
--- a/dojox/editor/plugins/nls/tr/Smiley.js
+++ b/dojox/editor/plugins/nls/tr/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "İfade Ekle",
 	emoticonSmile: "gülümseme",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "ağlayan ifade",
 	emoticonHappy: "mutlu ifade"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/SpellCheck.js b/dojox/editor/plugins/nls/tr/SpellCheck.js
index 13a61fa..0a6ea4c 100644
--- a/dojox/editor/plugins/nls/tr/SpellCheck.js
+++ b/dojox/editor/plugins/nls/tr/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "Toplu Yazım Denetimi",
 	unfound: "Bulunamadı",
@@ -16,6 +15,4 @@ define(
 	iSkipAll: "Buna benzeyenlerin tümünü atla",
 	iMsg: "Yazım önerisi yok"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/TableDialog.js b/dojox/editor/plugins/nls/tr/TableDialog.js
index cc2b99f..d8726a4 100644
--- a/dojox/editor/plugins/nls/tr/TableDialog.js
+++ b/dojox/editor/plugins/nls/tr/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "Tablo Ekle",
 	modifyTableTitle: "Tabloyu Değiştir",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "Tablo Genişliği",
 	backgroundColor: "Arka Plan Rengi:",
 	borderColor: "Kenarlık Rengi:",
-	borderThickness: "Kenarlık Kalınlığı",
+	borderThickness: "Kenarlık Kalınlığı:",
 	percent: "yüzde",
 	pixels: "piksel",
 	"default": "varsayılan",
@@ -21,14 +20,14 @@ define(
 	buttonSet: "Ayarla", // translated elsewhere?
 	buttonInsert: "Ekle",
 	buttonCancel: "İptal",
-
 	selectTableLabel: "Tablo Seç",
 	insertTableRowBeforeLabel: "Satırı Önüne Ekle",
 	insertTableRowAfterLabel: "Satırı Arkasına Ekle",
 	insertTableColumnBeforeLabel: "Sütunu Önüne Ekle",
 	insertTableColumnAfterLabel: "Sütunu Arkasına Ekle",
 	deleteTableRowLabel: "Satırı Sil",
-	deleteTableColumnLabel: "Sütunu Sil"
+	deleteTableColumnLabel: "Sütunu Sil",
+	colorTableCellTitle: "Arka Plan Rengi Tablo Hücresi",
+	tableContextMenuTitle: "Tablo Bağlam Menüsü"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/TextColor.js b/dojox/editor/plugins/nls/tr/TextColor.js
index 9f6b1c3..48f8d57 100644
--- a/dojox/editor/plugins/nls/tr/TextColor.js
+++ b/dojox/editor/plugins/nls/tr/TextColor.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "Ayarla",
 	"cancelButtonText": "İptal"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/tr/latinEntities.js b/dojox/editor/plugins/nls/tr/latinEntities.js
index f773e61..d08dcbc 100644
--- a/dojox/editor/plugins/nls/tr/latinEntities.js
+++ b/dojox/editor/plugins/nls/tr/latinEntities.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
-		amp:"ampersand",lt:"less-than sign",
-		gt:"greater-than sign",
-		nbsp:"no-break space\nnon-breaking space",
-		quot:"quote",
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
 	*/
 	iexcl:"ters ünlem işareti",
 	cent:"sent işareti",
@@ -44,7 +43,7 @@ define(
 	Atilde:"Tilde imiyle Latince büyük harf A",
 	Auml:"Umlaut imiyle Latince büyük harf A",
 	Aring:"Üstte halka imiyle Latince büyük harf A\nLatince büyük harf A halkalı",
-	AElig:"Latince büyük harf AE\nLatin büyük birleştirmeli yazım AE",
+	AElig:"Latince büyük harf AE\nLatince büyük birleştirmeli yazım AE",
 	Ccedil:"Çengel imiyle Latince büyük harf C",
 	Egrave:"Aksan imiyle Latince büyük harf E",
 	Eacute:"Vurgu imiyle Latince büyük harf E",
@@ -102,7 +101,6 @@ define(
 	yacute:"Vurgu imiyle Latince küçük harf y",
 	thorn:"Latince küçük harf thorn",
 	yuml:"Umlaut imiyle Latince küçük harf y",
-
 // Greek Characters and Symbols
 	fnof:"Kanca imiyle Latince küçük f\nfonksiyon\nflorin",
 	Alpha:"Yunanca büyük harf alpha",
@@ -163,11 +161,11 @@ define(
 	Prime:"üssü iki\nsaniye\ninç",
 	oline:"üstçizgi\naralıklı üstçizgi",
 	frasl:"bölme işaretli kesir",
-	weierp:"el yazısı büyük harf P\nkuvvet kümesi\nWeierstrass p",
+	weierp:"el yazısı büyük P\nkuvvet kümesi\nWeierstrass p",
 	image:"Gotik büyük harf I\nsanal kısım",
 	real:"Gotik büyük harf R\ngerçek kısım işareti",
 	trade:"ticari marka işareti",
-	alefsym:"alef işareti\nbirinci sonsuz sayma sayısı",
+	alefsym:"alef simgesi\nbirinci sonlu sayma sayısı",
 	larr:"sol ok işareti",
 	uarr:"yukarı ok işareti",
 	rarr:"sağ ol işareti",
@@ -187,7 +185,7 @@ define(
 	isin:"elemanıdır",
 	notin:"elemanı değildir",
 	ni:"kapsar",
-	prod:"n-ary çarpım\çarpım işareti",
+	prod:"n-ary çarpım\nçarpım işareti",
 	sum:"n-ary toplamı",
 	minus:"eksi işareti",
 	lowast:"asterisk işleci",
@@ -195,12 +193,12 @@ define(
 	prop:"orantılı",
 	infin:"sonsuzluk",
 	ang:"açı",
-	and:"mantıklı ve\nwedge",
-	or:"mantıklı veya\nvee",
-	cap:"arakesit\ncap",
-	cup:"birleşim\ncup","int":"integral",
+	and:"matıksal ve\nwedge",
+	or:"mantıksal veya\nvee",
+	cap:"kesişim\ncap",
+	cup:"bileşim\ncup","int":"integral",
 	there4:"bu nedenle",
-	sim:"tilde işleci\ndeğişir\nbenzer",
+	sim:"tilde işleci\nile çeşitlenen\nile benzer",
 	cong:"yaklaşık olarak eşit",
 	asymp:"neredeyse eşit\nkavuşmaz",
 	ne:"eşit değil",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"sağ açılı tek tırnak işareti",
 	euro:"euro işareti"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/uk/AutoSave.js b/dojox/editor/plugins/nls/uk/AutoSave.js
new file mode 100644
index 0000000..a28f653
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/AutoSave.js
@@ -0,0 +1,15 @@
+define(
+({
+	"saveLabel": "Зберегти",
+	"saveSettingLabelOn": "Зазначити інтервал автозбереження...",
+	"saveSettingLabelOff": "Вимкнути автозбереження",
+	"saveSettingdialogTitle": "Автозбереження",
+	"saveSettingdialogDescription": "Вкажіть інтервал автозбереження",
+	"saveSettingdialogParamName": "Інтервал автозбереження",
+	"saveSettingdialogParamLabel": "хв",
+	"saveSettingdialogButtonOk": "Задати інтервал",
+	"saveSettingdialogButtonCancel": "Скасувати",
+	"saveMessageSuccess": "Збережено у ${0}",
+	"saveMessageFail": "Не вдалося зберегти у ${0}"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/Blockquote.js b/dojox/editor/plugins/nls/uk/Blockquote.js
new file mode 100644
index 0000000..e6a4ed0
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/Blockquote.js
@@ -0,0 +1,5 @@
+define(
+({
+	"blockquote": "Блок цитат"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/Breadcrumb.js b/dojox/editor/plugins/nls/uk/Breadcrumb.js
new file mode 100644
index 0000000..7406dd1
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/Breadcrumb.js
@@ -0,0 +1,11 @@
+define(
+({
+	"nodeActions": "${nodeName}: дії",
+	"selectContents": "Вибрати вміст",
+	"selectElement": "Вибрати елемент",
+	"deleteElement": "Видалити елемент",
+	"deleteContents": "Видалити вміст",
+	"moveStart": "Перемістити курсор на початок",
+	"moveEnd": "Перемістити курсор у кінець"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/CollapsibleToolbar.js b/dojox/editor/plugins/nls/uk/CollapsibleToolbar.js
new file mode 100644
index 0000000..e82f9a3
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/CollapsibleToolbar.js
@@ -0,0 +1,6 @@
+define(
+({
+	"collapse": "Згорнути панель редагування",
+	"expand": "Розгорнути панель редагування"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/FindReplace.js b/dojox/editor/plugins/nls/uk/FindReplace.js
new file mode 100644
index 0000000..0cebbb6
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/FindReplace.js
@@ -0,0 +1,23 @@
+define(
+({
+	"findLabel": "Знайти:",
+	"findTooltip": "Введіть текст для пошуку",
+	"replaceLabel": "Замінити на",
+	"replaceTooltip": "Введіть текст заміни",
+	"findReplace": "Найти та замінити",
+	"matchCase": "Враховувати регістр",
+	"matchCaseTooltip": "Враховувати регістр",
+	"backwards": "Назад",
+	"backwardsTooltip": "Пошук тексту у зворотному напрямку",
+	"replaceAllButton": "Замінити всі",
+	"replaceAllButtonTooltip": "Замінити весь текст",
+	"findButton": "Знайти",
+	"findButtonTooltip": "Знайти текст",
+	"replaceButton": "Замінити",
+	"replaceButtonTooltip": "Замінити текст",
+	"replaceDialogText": "Замінено ${0} входжень.",
+	"eofDialogText": "Останнє входження ${0}",
+	"eofDialogTextFind": "знайдено",
+	"eofDialogTextReplace": "замінено"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/InsertAnchor.js b/dojox/editor/plugins/nls/uk/InsertAnchor.js
new file mode 100644
index 0000000..be91c93
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/InsertAnchor.js
@@ -0,0 +1,10 @@
+define(
+({
+	insertAnchor: "Вставити мітку",
+	title: "Властивості мітки",
+	anchor: "Ім'я:",
+	text: "Опис:",
+	set: "Встановити",
+	cancel: "Скасувати"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/InsertEntity.js b/dojox/editor/plugins/nls/uk/InsertEntity.js
new file mode 100644
index 0000000..d116d34
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/InsertEntity.js
@@ -0,0 +1,5 @@
+define(
+({
+	insertEntity: "Вставити символ"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/LocalImage.js b/dojox/editor/plugins/nls/uk/LocalImage.js
new file mode 100644
index 0000000..c2c7616
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/LocalImage.js
@@ -0,0 +1,12 @@
+define(
+({
+	insertImageTitle: "Вставити зображення",
+	url: "Зображення",
+	browse: "Огляд...",
+	text: "Опис",
+	set: "Вставити",
+	invalidMessage: "Неправильний тип файлу зображення",
+	prePopuTextUrl: "Введіть URL зображення ",
+	prePopuTextBrowse: " або виберіть локальний файл."
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/PageBreak.js b/dojox/editor/plugins/nls/uk/PageBreak.js
new file mode 100644
index 0000000..43bed3d
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/PageBreak.js
@@ -0,0 +1,5 @@
+define(
+({
+	"pageBreak": "Розрив сторінки"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/PasteFromWord.js b/dojox/editor/plugins/nls/uk/PasteFromWord.js
new file mode 100644
index 0000000..c6d7caf
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/PasteFromWord.js
@@ -0,0 +1,6 @@
+define(
+({
+	"pasteFromWord": "Вставити з Word",
+	"instructions": "Вставка вмісту з Word до текстового поля.  Після вибору вмісту для вставки натисніть кнопку Вставити.  Для скасування вставки тексту натисніть кнопку Скасувати."
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/Preview.js b/dojox/editor/plugins/nls/uk/Preview.js
new file mode 100644
index 0000000..9e7af4a
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/Preview.js
@@ -0,0 +1,5 @@
+define(
+({
+	"preview": "Попередній перегляд"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/SafePaste.js b/dojox/editor/plugins/nls/uk/SafePaste.js
new file mode 100644
index 0000000..b3ab7ea
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/SafePaste.js
@@ -0,0 +1,5 @@
+define(
+({
+	"instructions": "Пряму вставку вимкнено.  Вставте дані в це вікно за допомогою стандартної клавіатури браузера або пунктів меню.  Вибравши вміст для вставки, натисніть кнопку Вставити.  Для скасування вставки вмісту натисніть кнопку Скасувати."
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/Save.js b/dojox/editor/plugins/nls/uk/Save.js
new file mode 100644
index 0000000..a054db0
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/Save.js
@@ -0,0 +1,5 @@
+define(
+({
+	"save": "Зберегти"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/ShowBlockNodes.js b/dojox/editor/plugins/nls/uk/ShowBlockNodes.js
new file mode 100644
index 0000000..6dedda3
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/ShowBlockNodes.js
@@ -0,0 +1,5 @@
+define(
+({
+	"showBlockNodes": "Показати елементи блока HTML"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/Smiley.js b/dojox/editor/plugins/nls/uk/Smiley.js
new file mode 100644
index 0000000..e37aabf
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/Smiley.js
@@ -0,0 +1,24 @@
+define(
+({
+	smiley: "Вставити символ емоції",
+	emoticonSmile: "посмішка",
+	emoticonLaughing: "сміх",
+	emoticonWink: "підморгування",
+	emoticonGrin: "хмурий",
+	emoticonCool: "класний",
+	emoticonAngry: "злий",
+	emoticonHalf: "половина",
+	emoticonEyebrow: "брова",
+	emoticonFrown: "насуплений",
+	emoticonShy: "сором'язливий",
+	emoticonGoofy: "безглуздий",
+	emoticonOops: "ой",
+	emoticonTongue: "язик",
+	emoticonIdea: "ідея",
+	emoticonYes: "так",
+	emoticonNo: "ні",
+	emoticonAngel: "ангел",
+	emoticonCrying: "плач",
+	emoticonHappy: "щастя"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/SpellCheck.js b/dojox/editor/plugins/nls/uk/SpellCheck.js
new file mode 100644
index 0000000..24107f5
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/SpellCheck.js
@@ -0,0 +1,18 @@
+define(
+({
+	widgetLabel: "Перевірка правопису",
+	unfound: "Не знайдено",
+	skip: "Пропустити",
+	skipAll: "Пропустити всі",
+	toDic: "Додати до словника",
+	suggestions: "Варіанти",
+	replace: "Замінити",
+	replaceWith: "Замінити на",
+	replaceAll: "Замінити всі",
+	cancel: "Скасувати",
+	msg: "Помилок не знайдено",
+	iSkip: "Пропустити це",
+	iSkipAll: "Пропустити всі",
+	iMsg: "Немає варіантів"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/TableDialog.js b/dojox/editor/plugins/nls/uk/TableDialog.js
new file mode 100644
index 0000000..b9ece0c
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/TableDialog.js
@@ -0,0 +1,33 @@
+define(
+({
+	insertTableTitle: "Вставити таблицю",
+	modifyTableTitle: "Змінити таблицю",
+	rows: "Рядки:",
+	columns: "Стовпці:",
+	align: "Вирівнювання:",
+	cellPadding: "Відступ всередині комірок:",
+	cellSpacing: "Відстань між комірками:",
+	tableWidth: "Ширина таблиці:",
+	backgroundColor: "Колір фону:",
+	borderColor: "Колір рамки:",
+	borderThickness: "Товщина рамки:",
+	percent: "відсотки",
+	pixels: "пікселі",
+	"default": "за замовчуванням",
+	left: "зліва",
+	center: "у центрі",
+	right: "справа",
+	buttonSet: "Встановити", // translated elsewhere?
+	buttonInsert: "Вставити",
+	buttonCancel: "Скасувати",
+	selectTableLabel: "Виберіть таблицю",
+	insertTableRowBeforeLabel: "Додати рядок вище",
+	insertTableRowAfterLabel: "Додати рядок нижче",
+	insertTableColumnBeforeLabel: "Додати стовпець зліва",
+	insertTableColumnAfterLabel: "Додати стовпець справа",
+	deleteTableRowLabel: "Видалити рядок",
+	deleteTableColumnLabel: "Видалити стовпчик",
+	colorTableCellTitle: "Колір фону - комірка таблиці",
+	tableContextMenuTitle: "Контекстне меню таблиці"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/TextColor.js b/dojox/editor/plugins/nls/uk/TextColor.js
new file mode 100644
index 0000000..43d1758
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/TextColor.js
@@ -0,0 +1,6 @@
+define(
+({
+	"setButtonText": "Встановити",
+	"cancelButtonText": "Скасувати"
+})
+);
diff --git a/dojox/editor/plugins/nls/uk/latinEntities.js b/dojox/editor/plugins/nls/uk/latinEntities.js
new file mode 100644
index 0000000..fe64559
--- /dev/null
+++ b/dojox/editor/plugins/nls/uk/latinEntities.js
@@ -0,0 +1,257 @@
+define(
+({
+	/* These are already handled in the default RTE
+	amp:"ampersand",lt:"less-than sign",
+	gt:"greater-than sign",
+	nbsp:"no-break space\nnon-breaking space",
+	quot:"quote",
+	*/
+	iexcl:"інвертований знак оклику",
+	cent:"символ центу",
+	pound:"символ фунту",
+	curren:"символ грошової одиниці",
+	yen:"символ ієни\nсимвол юаня",
+	brvbar:"переривчаста риса\nвертикальна переривчаста риса",
+	sect:"символ розділу",
+	uml:"трема\nтрема з інтервалом",
+	copy:"символ авторських прав",
+	ordf:"індикатор жіночого роду",
+	laquo:"ліві подвійні кутові лапки\nліві лапки",
+	not:"символ заперечення",
+	shy:"м'яке перенесення\nможливе перенесення",
+	reg:"символ Зареєстрований\nсимвол зареєстрованого товарного знака",
+	macr:"знак довготи\nзнак довготи з інтервалом\верхня риса\nнадкреслення APL",
+	deg:"символ градусів",
+	plusmn:"знак плюс-мінус\nзнак плюсу або мінусу",
+	sup2:"верхній індекс два\nверхній індекс з цифрою два\nзведення у квадрат",
+	sup3:"верхній індекс три\nверхній індекс з цифрою три\nзведення у куб",
+	acute:"знак акут\nакут з інтервалом",
+	micro:"знак мікро",
+	para:"символ абзацу\nсимвол параграфу",
+	middot:"середня точка\nкома у грузинському\nсередня точка у грецькому",
+	cedil:"седиль\nседиль з інтервалом",
+	sup1:"верхній індекс один\nверхній індекс з цифрою один",
+	ordm:"індикатор чоловічого роду",
+	raquo:"Права подвійна кутова лапка\nправа лапка",
+	frac14:"дріб одна четверта\nодна чверть",
+	frac12:"дріб одна друга\nодна друга",
+	frac34:"дріб три чверті\nтри чверті",
+	iquest:"інвертований знак питання\nперевернутий знак питання",
+	Agrave:"латинська прописна буква А з гравісом\nлатинська прописна буква А з гравісом",
+	Aacute:"латинська прописна буква A з акутом",
+	Acirc:"латинська прописна буква A з циркумфлексом",
+	Atilde:"латинська прописна буква A з тильдою",
+	Auml:"латинська прописна буква A з тремою",
+	Aring:"латинська прописна буква A з кружечком угорі\nлатинська прописна буква A з кружечком",
+	AElig:"латинська прописна буква AE\nлатинська прописна лигатура AE",
+	Ccedil:"латинська прописна буква C з седиллю",
+	Egrave:"латинська прописна буква E з гравісом",
+	Eacute:"латинська прописна буква Е з акутом",
+	Ecirc:"латинська прописна буква E з циркумфлексом",
+	Euml:"латинська прописна буква Е з тремою",
+	Igrave:"латинська прописна буква I з грависом",
+	Iacute:"латинська прописна буква І з акутом",
+	Icirc:"латинська прописна буква І з циркумфлексом",
+	Iuml:"латинська прописна буква І з тремою",
+	ETH:"латинська прописна буква ETH",
+	Ntilde:"латинська прописна буква N з тильдою",
+	Ograve:"латинська прописна буква O з грависом",
+	Oacute:"латинська прописна буква O з акутом",
+	Ocirc:"латинська прописна буква O з циркумфлексом",
+	Otilde:"латинська прописна буква O з тильдою",
+	Ouml:"латинська прописна буква O з тремою",
+	times:"знак множення",
+	Oslash:"латинська прописна буква O перекреслена\nлатинська прописна буква O з вертикальною рисою",
+	Ugrave:"латинська прописна буква U з грависом",
+	Uacute:"латинська прописна буква U з акутом",
+	Ucirc:"латинська прописна буква U з циркумфлексом",
+	Uuml:"латинська прописна буква U з тремою",
+	Yacute:"латинська прописна буква Y з акутом",
+	THORN:"латинська прописна буква THORN",
+	szlig:"латинська мала загострена есцет\есцет",
+	agrave:"латинська мала літера a з грависом\nлатинська мала а з грависом",
+	aacute:"латинська мала літера a з акутом",
+	acirc:"латинська мала літера a з циркумфлексом",
+	atilde:"латинська мала літера a з тильдою",
+	auml:"латинська мала літера a з тремою",
+	aring:"латинська мала літера a з кружечком угорі\nлатинська мала літера a з кружечком",
+	aelig:"латинська мала літера ae\nлатинська мала лігатура ae",
+	ccedil:"латинська мала літера c з седиллю",
+	egrave:"латинська мала літера e з грависом",
+	eacute:"латинська мала літера e з акутом",
+	ecirc:"латинська мала літера e з циркумфлексом",
+	euml:"латинська мала літера e з тремою",
+	igrave:"латинська мала літера i з грависом",
+	iacute:"латинська мала літера i з акутом",
+	icirc:"латинська мала літера i з циркумфлексом",
+	iuml:"латинська мала літера i з тремою",
+	eth:"латинська мала літера eth",
+	ntilde:"латинська мала літера n з тильдою",
+	ograve:"латинська мала літера o з грависом",
+	oacute:"латинська мала літера o з акутом",
+	ocirc:"латинська мала літера o з циркумфлексом",
+	otilde:"латинська мала літера o з тильдою",
+	ouml:"латинська мала літера o з тремою",
+	divide:"знак ділення",
+	oslash:"латинська мала літера o перекреслена\nwith stroke o з вертикальною рисою",
+	ugrave:"латинська мала літера u з грависом",
+	uacute:"латинська мала літера u з акутом",
+	ucirc:"латинська мала літера u з циркумфлексом",
+	uuml:"латинська мала літера u з тремою",
+	yacute:"латинська мала літера y з акутом",
+	thorn:"латинська мала літера thorn",
+	yuml:"латинська мала літера y з тремою",
+// Greek Characters and Symbols
+	fnof:"латинська мала літера f з хвостиком\nфункція\nфлорин",
+	Alpha:"грецька прописна літера альфа",
+	Beta:"грецька прописна літера бета",
+	Gamma:"грецька прописна літера гамма",
+	Delta:"грецька прописна літера дельта",
+	Epsilon:"грецька прописна літера епсілон",
+	Zeta:"грецька прописна літера дзета",
+	Eta:"грецька прописна літера ета",
+	Theta:"грецька прописна літера тета",
+	Iota:"грецька прописна літера йота",
+	Kappa:"грецька прописна літера каппа",
+	Lambda:"грецька прописна літера лямбда",
+	Mu:"грецька прописна літера мю",
+	Nu:"грецька прописна літера ню",
+	Xi:"грецька прописна літера ксі",
+	Omicron:"грецька прописна літера омікрон",
+	Pi:"грецька прописна літера пі",
+	Rho:"грецька прописна літера ро",
+	Sigma:"грецька прописна літера сігма",
+	Tau:"грецька прописна літера тау",
+	Upsilon:"грецька прописна літера іпсілон",
+	Phi:"грецька прописна літера фі",
+	Chi:"грецька прописна літера хі",
+	Psi:"грецька прописна літера псі",
+	Omega:"грецька прописна літера омега",
+	alpha:"грецька мала літера альфа",
+	beta:"грецька мала літера бета",
+	gamma:"грецька мала літера гамма",
+	delta:"грецька мала літера дельта",
+	epsilon:"грецька мала літера епсілон",
+	zeta:"грецька мала літера дзета",
+	eta:"грецька мала літера ета",
+	theta:"грецька мала літера тета",
+	iota:"грецька мала літера йота",
+	kappa:"грецька мала літера каппа",
+	lambda:"грецька мала літера лямбда",
+	mu:"грецька мала літера мю",
+	nu:"грецька мала літера ню",
+	xi:"грецька мала літера ксі",
+	omicron:"грецька мала літера омікрон",
+	pi:"грецька мала літера пі",
+	rho:"грецька мала літера ро",
+	sigmaf:"грецька мала літера кінцева сігма",
+	sigma:"грецька мала літера сігма",
+	tau:"грецька мала літера тау",
+	upsilon:"грецька мала літера іпсілон",
+	phi:"грецька мала літера фі",
+	chi:"грецька мала літера хі",
+	psi:"грецька мала літера псі",
+	omega:"грецька мала літера омега",
+	thetasym:"грецька символьна тета",
+	upsih:"грецький іпсілон з хвостиком",
+	piv:"грецький символ пі",
+	bull:"маркер списку\nчорний маленький кружечок",
+	hellip:"багатокрапка\nтри крапки",
+	prime:"штрих\nхвилини\nфути",
+	Prime:"подвійний штрих\nсекунди\nдюйми",
+	oline:"верхня риса\nнадкреслення з інтервалом",
+	frasl:"коса риса",
+	weierp:"рукописна прописна P\nступінна множина\nфункции Вейєрштрасса",
+	image:"чорна прописна I\nуявна частина",
+	real:"чорна прописна R\nдійсна частина",
+	trade:"стивол товарного знака",
+	alefsym:"буква Алеф\nперше трансфінітне кардинальне число",
+	larr:"стрілка вліво",
+	uarr:"стрілка угору",
+	rarr:"стрілка вправо",
+	darr:"стрілка вниз",
+	harr:"стрілка вліво-вправо",
+	crarr:"стрілка вниз з кутом вправо\nповернення каретки",
+	lArr:"подвійна стрілка вліво",
+	uArr:"подвійна стрілка угору",
+	rArr:"подвійна стрілка вправо",
+	dArr:"подвійна стрілка вниз",
+	hArr:"подвійна стрілка вліво-вправо",
+	forall:"для всіх",
+	part:"частковий диференціал",
+	exist:"існує",
+	empty:"порожній набір\nпорожня множина\nдіаметр",
+	nabla:"оператор набла\nрізницеве відношення назад",
+	isin:"є елементом",
+	notin:"не є елементом",
+	ni:"містить як елемент",
+	prod:"n-арний добуток\nзнак добутку",
+	sum:"n-арне підсумовування",
+	minus:"знак мінус",
+	lowast:"оператор зірочка",
+	radic:"квадратний корінь\nзнак кореня",
+	prop:"пропорційно",
+	infin:"нескінченність",
+	ang:"кут",
+	and:"логічне І\nклин угору",
+	or:"логічне АБО\nклин вниз",
+	cap:"перетин\nшапочка",
+	cup:"об'єднання\nчашечка","int":"інтеграл",
+	there4:"отже",
+	sim:"оператор тильда\nзмінюватися з\nподібно до",
+	cong:"приблизно дорівнює",
+	asymp:"майже дорівнює\nасимптотично",
+	ne:"не дорівнює",
+	equiv:"ідентично",
+	le:"менш ніж або дорівнює",
+	ge:"більш ніж або дорівнює",
+	sub:"підмножина",
+	sup:"включає до себе",
+	nsub:"не є підмножиною",
+	sube:"є підмножиною або еквівалентно",
+	supe:"включає до себе або еквівалентно",
+	oplus:"плюс у колі\nпряма сума",
+	otimes:"множення у колі\nвекторний добуток",
+	perp:"перевернений гвіздок\nортогонально\nперпендикулярно",
+	sdot:"оператор крапка",
+	lceil:"ліва дужка округлювання угору\nAPL upstile",
+	rceil:"права дужка округлювання угору",
+	lfloor:"ліва дужка округлювання вниз\nAPL downstile",
+	rfloor:"ліва дужка округлювання вниз",
+	lang:"ліва кутова дужка",
+	rang:"права кутова дужка",
+	loz:"ромб",
+	spades:"піки",
+	clubs:"трефи\nтрилисник",
+	hearts:"чирва\nвалентинка",
+	diams:"бубни",
+	OElig:"латинська прописна лігатура OE",
+	oelig:"латинська мала лігатура oe",
+	Scaron:"латинська прописна літера S з галочкою",
+	scaron:"латинська мала літера s з галочкою",
+	Yuml:"латинська прописна літера Y з тремою",
+	circ:"надрядковий знак циркумфлекс",
+	tilde:"мала тильда",
+	ensp:"пробіл довжини N",
+	emsp:"пробіл довжини М",
+	thinsp:"вузький пробіл",
+	zwnj:"роздільник нульової ширини",
+	zwj:"з'єднувач нульової ширини",
+	lrm:"знак зліва-направо",
+	rlm:"знак справа-наліво",
+	ndash:"коротке тире",
+	mdash:"довге тире",
+	lsquo:"ліва одинарна лапка",
+	rsquo:"права одинарна лапка",
+	sbquo:"одинарна нижня лапка",
+	ldquo:"ліва подвійна лапка",
+	rdquo:"права подвійна лапка",
+	bdquo:"подвійна нижня лапка",
+	dagger:"хрест",
+	Dagger:"подвійний хрест",
+	permil:"знак проміле",
+	lsaquo:"одинарна ліва кутова лапка",
+	rsaquo:"одинарна права кутова лапка",
+	euro:"знак євро"
+})
+);
diff --git a/dojox/editor/plugins/nls/zh-tw/AutoSave.js b/dojox/editor/plugins/nls/zh-tw/AutoSave.js
index e75b06e..52e217e 100644
--- a/dojox/editor/plugins/nls/zh-tw/AutoSave.js
+++ b/dojox/editor/plugins/nls/zh-tw/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "儲存",
 	"saveSettingLabelOn": "設定自動儲存間隔...",
@@ -13,5 +12,4 @@ define(
 	"saveMessageSuccess": "已儲存於 ${0}",
 	"saveMessageFail": "無法儲存於 ${0}"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/Blockquote.js b/dojox/editor/plugins/nls/zh-tw/Blockquote.js
index dbcb9de..82f8598 100644
--- a/dojox/editor/plugins/nls/zh-tw/Blockquote.js
+++ b/dojox/editor/plugins/nls/zh-tw/Blockquote.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "區塊引文"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/Breadcrumb.js b/dojox/editor/plugins/nls/zh-tw/Breadcrumb.js
index 6e06911..a040fe0 100644
--- a/dojox/editor/plugins/nls/zh-tw/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/zh-tw/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} 動作",
 	"selectContents": "選取內容",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "將游標移到開頭",
 	"moveEnd": "將游標移到末尾"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/CollapsibleToolbar.js b/dojox/editor/plugins/nls/zh-tw/CollapsibleToolbar.js
index 935372a..d94a671 100644
--- a/dojox/editor/plugins/nls/zh-tw/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/zh-tw/CollapsibleToolbar.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "收合編輯器工具列",
 	"expand": "展開編輯器工具列"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/FindReplace.js b/dojox/editor/plugins/nls/zh-tw/FindReplace.js
index 414b189..9a8f4c9 100644
--- a/dojox/editor/plugins/nls/zh-tw/FindReplace.js
+++ b/dojox/editor/plugins/nls/zh-tw/FindReplace.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "尋找:",
 	"findTooltip": "輸入要尋找的文字",
@@ -21,5 +20,4 @@ define(
 	"eofDialogTextFind": "找到",
 	"eofDialogTextReplace": "已取代"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/InsertAnchor.js b/dojox/editor/plugins/nls/zh-tw/InsertAnchor.js
index 460b5bb..e41115e 100644
--- a/dojox/editor/plugins/nls/zh-tw/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/zh-tw/InsertAnchor.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "插入錨點",
 	title: "錨點內容",
@@ -8,5 +7,4 @@ define(
 	set: "設定",
 	cancel: "取消"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/InsertEntity.js b/dojox/editor/plugins/nls/zh-tw/InsertEntity.js
index a8872ba..8b59fe0 100644
--- a/dojox/editor/plugins/nls/zh-tw/InsertEntity.js
+++ b/dojox/editor/plugins/nls/zh-tw/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "插入符號"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/LocalImage.js b/dojox/editor/plugins/nls/zh-tw/LocalImage.js
index 4d1da04..fea4133 100644
--- a/dojox/editor/plugins/nls/zh-tw/LocalImage.js
+++ b/dojox/editor/plugins/nls/zh-tw/LocalImage.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "插入影像",
 	url: "影像",
@@ -10,5 +9,4 @@ define(
 	prePopuTextUrl: "輸入影像 URL",
 	prePopuTextBrowse: " 或瀏覽本端檔案。"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/PageBreak.js b/dojox/editor/plugins/nls/zh-tw/PageBreak.js
index b966ada..30a7bbe 100644
--- a/dojox/editor/plugins/nls/zh-tw/PageBreak.js
+++ b/dojox/editor/plugins/nls/zh-tw/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"pageBreak": "分頁"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/PasteFromWord.js b/dojox/editor/plugins/nls/zh-tw/PasteFromWord.js
index 3d10208..3108b72 100644
--- a/dojox/editor/plugins/nls/zh-tw/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/zh-tw/PasteFromWord.js
@@ -1,10 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "從 Word 貼上",
-	"paste": "貼上",
-	"cancel": "取消",
 	"instructions": "將 Word 中的內容貼入下方的文字框。在滿意要插入的內容之後,請按貼上按鈕。若要中斷插入文字,請按取消按鈕。"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/Preview.js b/dojox/editor/plugins/nls/zh-tw/Preview.js
index 1ce6596..82b3e29 100644
--- a/dojox/editor/plugins/nls/zh-tw/Preview.js
+++ b/dojox/editor/plugins/nls/zh-tw/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "預覽"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/SafePaste.js b/dojox/editor/plugins/nls/zh-tw/SafePaste.js
index 4708bc1..c702982 100644
--- a/dojox/editor/plugins/nls/zh-tw/SafePaste.js
+++ b/dojox/editor/plugins/nls/zh-tw/SafePaste.js
@@ -1,5 +1,5 @@
 define(
 ({
-	"instructions": "已停用直接貼上。請使用標準瀏覽器鍵盤或功能表貼上控制,將內容貼上至此對話框中。一旦您滿意要插入的內容,按下貼上按鈕。若要中斷插入內容,按下取消按鈕。"
+	"instructions": "已停用直接貼上。請使用標準瀏覽器鍵盤或功能表貼上控制項,在這個對話框中貼上內容。當您滿意要插入的內容之後,請按貼上按鈕。若要中斷插入內容,請按取消按鈕。"
 })
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/Save.js b/dojox/editor/plugins/nls/zh-tw/Save.js
index a75928d..07f2f89 100644
--- a/dojox/editor/plugins/nls/zh-tw/Save.js
+++ b/dojox/editor/plugins/nls/zh-tw/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "儲存"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/ShowBlockNodes.js b/dojox/editor/plugins/nls/zh-tw/ShowBlockNodes.js
index 0ff24a8..39dd712 100644
--- a/dojox/editor/plugins/nls/zh-tw/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/zh-tw/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "顯示 HTML 區塊元素"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/Smiley.js b/dojox/editor/plugins/nls/zh-tw/Smiley.js
index 5e5bda4..9770eff 100644
--- a/dojox/editor/plugins/nls/zh-tw/Smiley.js
+++ b/dojox/editor/plugins/nls/zh-tw/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "插入表情符號",
 	emoticonSmile: "微笑",
@@ -20,8 +19,6 @@ define(
 	emoticonNo: "不對",
 	emoticonAngel: "守護神",
 	emoticonCrying: "哭泣",
-	emoticonHappy: "歡樂派對"
+	emoticonHappy: "快樂"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/SpellCheck.js b/dojox/editor/plugins/nls/zh-tw/SpellCheck.js
index 8f8dab3..ae181e3 100644
--- a/dojox/editor/plugins/nls/zh-tw/SpellCheck.js
+++ b/dojox/editor/plugins/nls/zh-tw/SpellCheck.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "批次拼字檢查",
 	unfound: "找不到",
@@ -16,5 +15,4 @@ define(
 	iSkipAll: "跳過所有如此項的項目",
 	iMsg: "沒有拼字建議"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/TableDialog.js b/dojox/editor/plugins/nls/zh-tw/TableDialog.js
index c582b14..64412a4 100644
--- a/dojox/editor/plugins/nls/zh-tw/TableDialog.js
+++ b/dojox/editor/plugins/nls/zh-tw/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "插入表格",
 	modifyTableTitle: "修改表格",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "表格寬度:",
 	backgroundColor: "背景顏色:",
 	borderColor: "邊框顏色:",
-	borderThickness: "邊框寬度",
+	borderThickness: "邊框寬度:",
 	percent: "百分比",
 	pixels: "像素",
 	"default": "預設值",
@@ -21,15 +20,14 @@ define(
 	buttonSet: "設定", // translated elsewhere?
 	buttonInsert: "插入",
 	buttonCancel: "取消",
-
 	selectTableLabel: "選取表格",
 	insertTableRowBeforeLabel: "在前面新增一個列",
 	insertTableRowAfterLabel: "在後面新增一個列",
 	insertTableColumnBeforeLabel: "在前面新增一個直欄",
 	insertTableColumnAfterLabel: "在後面新增一個直欄",
 	deleteTableRowLabel: "刪除列",
-	deleteTableColumnLabel: "刪除欄"
+	deleteTableColumnLabel: "刪除欄",
+	colorTableCellTitle: "背景色表資料格",
+	tableContextMenuTitle: "表格快速功能表"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/TextColor.js b/dojox/editor/plugins/nls/zh-tw/TextColor.js
index 041235a..d628407 100644
--- a/dojox/editor/plugins/nls/zh-tw/TextColor.js
+++ b/dojox/editor/plugins/nls/zh-tw/TextColor.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"setButtonText": "設定",
 	"cancelButtonText": "取消"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh-tw/latinEntities.js b/dojox/editor/plugins/nls/zh-tw/latinEntities.js
index 9700299..27391f8 100644
--- a/dojox/editor/plugins/nls/zh-tw/latinEntities.js
+++ b/dojox/editor/plugins/nls/zh-tw/latinEntities.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -102,7 +101,6 @@ define(
 	yacute:"帶揚音符的拉丁文小寫字母 y",
 	thorn:"拉丁文小寫字母 thorn",
 	yuml:"帶分音符的拉丁文小寫字母 y",
-
 // Greek Characters and Symbols
 	fnof:"帶短畫的拉丁文小寫 f\n函數\n弗洛林幣",
 	Alpha:"希臘文大寫字母 Α",
@@ -256,6 +254,4 @@ define(
 	rsaquo:"右尖單角引號",
 	euro:"歐元符號"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/AutoSave.js b/dojox/editor/plugins/nls/zh/AutoSave.js
index 4664acc..9db66fc 100644
--- a/dojox/editor/plugins/nls/zh/AutoSave.js
+++ b/dojox/editor/plugins/nls/zh/AutoSave.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"saveLabel": "保存",
 	"saveSettingLabelOn": "设置自动保存时间间隔...",
@@ -7,11 +6,10 @@ define(
 	"saveSettingdialogTitle": "自动保存",
 	"saveSettingdialogDescription": "指定自动保存时间间隔",
 	"saveSettingdialogParamName": "自动保存时间间隔",
-	"saveSettingdialogParamLabel": "分钟",
+	"saveSettingdialogParamLabel": "最小",
 	"saveSettingdialogButtonOk": "设置时间间隔",
 	"saveSettingdialogButtonCancel": "取消",
 	"saveMessageSuccess": "已保存到 ${0}",
 	"saveMessageFail": "未能保存到 ${0}"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/Blockquote.js b/dojox/editor/plugins/nls/zh/Blockquote.js
index af2721d..b1d28e2 100644
--- a/dojox/editor/plugins/nls/zh/Blockquote.js
+++ b/dojox/editor/plugins/nls/zh/Blockquote.js
@@ -1,7 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"blockquote": "块引用"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/Breadcrumb.js b/dojox/editor/plugins/nls/zh/Breadcrumb.js
index 2033c28..6b21d78 100644
--- a/dojox/editor/plugins/nls/zh/Breadcrumb.js
+++ b/dojox/editor/plugins/nls/zh/Breadcrumb.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"nodeActions": "${nodeName} 操作",
 	"selectContents": "选择内容",
@@ -9,6 +8,4 @@ define(
 	"moveStart": "将光标移至开头",
 	"moveEnd": "将光标移至结尾"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/CollapsibleToolbar.js b/dojox/editor/plugins/nls/zh/CollapsibleToolbar.js
index 12f1985..24d327b 100644
--- a/dojox/editor/plugins/nls/zh/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/nls/zh/CollapsibleToolbar.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"collapse": "折叠编辑器工具栏",
 	"expand": "展开编辑器工具栏"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/FindReplace.js b/dojox/editor/plugins/nls/zh/FindReplace.js
index a4b4b3e..5beaa76 100644
--- a/dojox/editor/plugins/nls/zh/FindReplace.js
+++ b/dojox/editor/plugins/nls/zh/FindReplace.js
@@ -1,14 +1,13 @@
 define(
-//begin v1.x content
 ({
 	"findLabel": "查找:",
 	"findTooltip": "输入要查找的文本",
 	"replaceLabel": "替换为:",
-	"replaceTooltip": "输入要替换成的文本",
+	"replaceTooltip": "输入要替换为的文本",
 	"findReplace": "查找和替换",
-	"matchCase": "匹配大小写",
-	"matchCaseTooltip": "匹配大小写",
-	"backwards": "向后",
+	"matchCase": "大小写匹配",
+	"matchCaseTooltip": "大小写匹配",
+	"backwards": "返回",
 	"backwardsTooltip": "向后搜索文本",
 	"replaceAllButton": "全部替换",
 	"replaceAllButtonTooltip": "替换所有文本",
@@ -16,10 +15,9 @@ define(
 	"findButtonTooltip": "查找文本",
 	"replaceButton": "替换",
 	"replaceButtonTooltip": "替换文本",
-	"replaceDialogText": "已替换 ${0} 个匹配项",
-	"eofDialogText": "最后一个匹配项 ${0}",
-	"eofDialogTextFind": "已找到",
+	"replaceDialogText": "已替换 ${0} 处。",
+	"eofDialogText": "上次出现 ${0}",
+	"eofDialogTextFind": "找到",
 	"eofDialogTextReplace": "已替换"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/InsertAnchor.js b/dojox/editor/plugins/nls/zh/InsertAnchor.js
index 3bf2c10..03c3a6a 100644
--- a/dojox/editor/plugins/nls/zh/InsertAnchor.js
+++ b/dojox/editor/plugins/nls/zh/InsertAnchor.js
@@ -1,12 +1,10 @@
 define(
-//begin v1.x content
 ({
 	insertAnchor: "插入锚点",
 	title: "锚点属性",
 	anchor: "名称:",
-	text: "描述:",
-	set: "设置",
+	text: "说明:",
+	set: "集",
 	cancel: "取消"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/InsertEntity.js b/dojox/editor/plugins/nls/zh/InsertEntity.js
index 17b7d6f..a47d5e4 100644
--- a/dojox/editor/plugins/nls/zh/InsertEntity.js
+++ b/dojox/editor/plugins/nls/zh/InsertEntity.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	insertEntity: "插入符号"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/LocalImage.js b/dojox/editor/plugins/nls/zh/LocalImage.js
index 1370436..471c3a1 100644
--- a/dojox/editor/plugins/nls/zh/LocalImage.js
+++ b/dojox/editor/plugins/nls/zh/LocalImage.js
@@ -1,14 +1,12 @@
 define(
-//begin v1.x content
 ({
 	insertImageTitle: "插入图像",
 	url: "图像",
 	browse: "浏览...",
-	text: "描述",
+	text: "说明",
 	set: "插入",
 	invalidMessage: "无效的图像文件类型",
 	prePopuTextUrl: "输入图像 URL",
 	prePopuTextBrowse: "或浏览本地文件。"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/PageBreak.js b/dojox/editor/plugins/nls/zh/PageBreak.js
index c809089..bf34cf2 100644
--- a/dojox/editor/plugins/nls/zh/PageBreak.js
+++ b/dojox/editor/plugins/nls/zh/PageBreak.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
-	"pageBreak": "换页符"
+	"pageBreak": "分页符"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/PasteFromWord.js b/dojox/editor/plugins/nls/zh/PasteFromWord.js
index 19d4ceb..fce47c1 100644
--- a/dojox/editor/plugins/nls/zh/PasteFromWord.js
+++ b/dojox/editor/plugins/nls/zh/PasteFromWord.js
@@ -1,10 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"pasteFromWord": "从 Word 中粘贴",
-	"paste": "粘贴",
-	"cancel": "取消",
-	"instructions": "将内容从 Word 粘贴到以下文本框。如果对插入的内容满意,请按“粘贴”按钮。要停止插入文本,请按“取消”按钮。"
+	"instructions": "将内容从 Word 粘贴到以下文本框。如果对插入的内容满意,请按“粘贴”按钮。要中止插入文本,请按“取消”按钮。"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/Preview.js b/dojox/editor/plugins/nls/zh/Preview.js
index 01155de..1f8d118 100644
--- a/dojox/editor/plugins/nls/zh/Preview.js
+++ b/dojox/editor/plugins/nls/zh/Preview.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"preview": "预览"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/Save.js b/dojox/editor/plugins/nls/zh/Save.js
index 16e07aa..c199361 100644
--- a/dojox/editor/plugins/nls/zh/Save.js
+++ b/dojox/editor/plugins/nls/zh/Save.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"save": "保存"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/ShowBlockNodes.js b/dojox/editor/plugins/nls/zh/ShowBlockNodes.js
index da43a4d..a209e22 100644
--- a/dojox/editor/plugins/nls/zh/ShowBlockNodes.js
+++ b/dojox/editor/plugins/nls/zh/ShowBlockNodes.js
@@ -1,8 +1,5 @@
 define(
-//begin v1.x content
 ({
 	"showBlockNodes": "显示 HTML 块元素"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/Smiley.js b/dojox/editor/plugins/nls/zh/Smiley.js
index 6278b11..b884842 100644
--- a/dojox/editor/plugins/nls/zh/Smiley.js
+++ b/dojox/editor/plugins/nls/zh/Smiley.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	smiley: "插入表情图标",
 	emoticonSmile: "微笑",
@@ -13,7 +12,7 @@ define(
 	emoticonFrown: "皱眉",
 	emoticonShy: "害羞",
 	emoticonGoofy: "傻了",
-	emoticonOops: "oops",
+	emoticonOops: "惊讶",
 	emoticonTongue: "吐舌",
 	emoticonIdea: "思考",
 	emoticonYes: "点头",
@@ -22,6 +21,4 @@ define(
 	emoticonCrying: "哭泣",
 	emoticonHappy: "高兴"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/SpellCheck.js b/dojox/editor/plugins/nls/zh/SpellCheck.js
index 1fcd97c..6c96c6d 100644
--- a/dojox/editor/plugins/nls/zh/SpellCheck.js
+++ b/dojox/editor/plugins/nls/zh/SpellCheck.js
@@ -1,14 +1,13 @@
 define(
-//begin v1.x content
 ({
 	widgetLabel: "批处理拼写检查",
-	unfound: "未找到",
+	unfound: "找不到",
 	skip: "跳过",
 	skipAll: "全部跳过",
 	toDic: "添加到字典",
 	suggestions: "建议",
 	replace: "替换",
-	replaceWith: "替换为",
+	replaceWith: "替换成",
 	replaceAll: "全部替换",
 	cancel: "取消",
 	msg: "未找到拼写错误",
@@ -16,5 +15,4 @@ define(
 	iSkipAll: "跳过所有与此处相同的地方",
 	iMsg: "没有拼写建议"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/TableDialog.js b/dojox/editor/plugins/nls/zh/TableDialog.js
index a15f0ff..a2193b6 100644
--- a/dojox/editor/plugins/nls/zh/TableDialog.js
+++ b/dojox/editor/plugins/nls/zh/TableDialog.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	insertTableTitle: "插入表",
 	modifyTableTitle: "修改表",
@@ -11,7 +10,7 @@ define(
 	tableWidth: "表宽度:",
 	backgroundColor: "背景色:",
 	borderColor: "边框色:",
-	borderThickness: "边框厚度",
+	borderThickness: "边框厚度:",
 	percent: "百分比",
 	pixels: "像素",
 	"default": "缺省值",
@@ -21,15 +20,14 @@ define(
 	buttonSet: "设置", // translated elsewhere?
 	buttonInsert: "插入",
 	buttonCancel: "取消",
-
 	selectTableLabel: "选择表",
 	insertTableRowBeforeLabel: "在之前添加行",
 	insertTableRowAfterLabel: "在之后添加行",
 	insertTableColumnBeforeLabel: "在之前添加列",
 	insertTableColumnAfterLabel: "在之后添加列",
 	deleteTableRowLabel: "删除行",
-	deleteTableColumnLabel: "删除列"
+	deleteTableColumnLabel: "删除列",
+	colorTableCellTitle: "背景颜色表单元格",
+	tableContextMenuTitle: "表上下文菜单"
 })
-
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/TextColor.js b/dojox/editor/plugins/nls/zh/TextColor.js
index ba86ce9..19ea46e 100644
--- a/dojox/editor/plugins/nls/zh/TextColor.js
+++ b/dojox/editor/plugins/nls/zh/TextColor.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"setButtonText": "设置",
+	"setButtonText": "集",
 	"cancelButtonText": "取消"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/nls/zh/latinEntities.js b/dojox/editor/plugins/nls/zh/latinEntities.js
index 3570a48..6315217 100644
--- a/dojox/editor/plugins/nls/zh/latinEntities.js
+++ b/dojox/editor/plugins/nls/zh/latinEntities.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	/* These are already handled in the default RTE
 		amp:"ampersand",lt:"less-than sign",
@@ -8,16 +7,16 @@ define(
 		quot:"quote",
 	*/
 	iexcl:"反感叹号",
-	cent:"分币符号",
+	cent:"美分符号",
 	pound:"英镑符号",
 	curren:"货币符号",
-	yen:"日元符号/人民币符号",
-	brvbar:"横向虚线\n纵向虚线",
-	sect:"小节符号",
+	yen:"日元符号\n人民币符号",
+	brvbar:"间断条\n断竖线",
+	sect:"节符号",
 	uml:"分音符\n间隔分音符",
 	copy:"版权符号",
 	ordf:"阴性序数指示符",
-	laquo:"左双尖括号\n左双尖括号",
+	laquo:"左指双尖引号\n左指双尖括号",
 	not:"非符号",
 	shy:"软连字符\n自由选定连字符",
 	reg:"注册符号\n注册商标符号",
@@ -27,13 +26,13 @@ define(
 	sup2:"上标 2\n上标数字 2\n平方",
 	sup3:"上标 3\n上标数字 3\n立方",
 	acute:"锐音符\n间隔锐音符",
-	micro:"μ 符号",
+	micro:"微符",
 	para:"段落符号\n段落符号",
 	middot:"中心点\n乔治逗号\n希腊中心点",
 	cedil:"软音符\n间隔软音符",
 	sup1:"上标 1\n上标数字 1",
 	ordm:"阳性序数指示符",
-	raquo:"右双尖括号\n右双尖括号",
+	raquo:"右指双尖引号\n右指双尖括号",
 	frac14:"普通四分之一\n四分之一",
 	frac12:"普通二分之一\n二分之一",
 	frac34:"普通四分之三\n四分之三",
@@ -41,18 +40,18 @@ define(
 	Agrave:"带重音符的拉丁大写字母 A\n带重音符的拉丁大写字母 A",
 	Aacute:"带锐音符的拉丁大写字母 A",
 	Acirc:"带抑扬符的拉丁大写字母 A",
-	Atilde:"带颚化音的拉丁大写字母 A",
+	Atilde:"具有颚化符的拉丁语大写字母 A",
 	Auml:"带分音符的拉丁大写字母 A",
 	Aring:"带上圆圈的拉丁大写字母 A\n带圆圈的拉丁大写字母 A",
 	AElig:"拉丁大写字母 AE\n拉丁大写连字 AE",
 	Ccedil:"带软音符的拉丁大写字母 C",
-	Egrave:"带重音符的拉丁大写字母 E",
+	Egrave:"具有抑音符的拉丁语大写字母 E",
 	Eacute:"带锐音符的拉丁大写字母 E",
 	Ecirc:"带抑扬符的拉丁大写字母 E",
 	Euml:"带分音符的拉丁大写字母 E",
 	Igrave:"带重音符的拉丁大写字母 I",
-	Iacute:"带锐音符的拉丁大写字母 I",
-	Icirc:"带抑扬符的拉丁大写字母 I",
+	Iacute:"具有锐音符的拉丁语大写字母 I",
+	Icirc:"具有音调符号的拉丁语大写字母 I",
 	Iuml:"带分音符的拉丁大写字母 I",
 	ETH:"拉丁大写字母 ETH",
 	Ntilde:"带颚化音的拉丁大写字母 N",
@@ -60,37 +59,37 @@ define(
 	Oacute:"带锐音符的拉丁大写字母 O",
 	Ocirc:"带抑扬符的拉丁大写字母 O",
 	Otilde:"带颚化音的拉丁大写字母 O",
-	Ouml:"带分音符的拉丁大写字母 O",
+	Ouml:"具有分音符号的拉丁语大写字母 O",
 	times:"乘号",
-	Oslash:"带竖线的拉丁大写字母 O\n带斜杠的拉丁大写字母 O",
-	Ugrave:"带重音符的拉丁大写字母 U",
-	Uacute:"带锐音符的拉丁大写字母 U",
+	Oslash:"具有短划线的拉丁语大写字母 O",
+	Ugrave:"具有抑音符的拉丁语大写字母 U",
+	Uacute:"具有锐音符的拉丁语大写字母 U",
 	Ucirc:"带抑扬符的拉丁大写字母 U",
 	Uuml:"带分音符的拉丁大写字母 U",
 	Yacute:"带锐音符的拉丁大写字母 Y",
 	THORN:"拉丁大写字母 THORN",
-	szlig:"拉丁小写字母 sharp s\ness-zed",
+	szlig:"拉丁语小写字母升 s",
 	agrave:"带重音符的拉丁小写字母 a\n带重音符的拉丁小写字母 a",
 	aacute:"带锐音符的拉丁小写字母 a",
 	acirc:"带抑扬符的拉丁小写字母 a",
 	atilde:"带颚化音的拉丁小写字母 a",
 	auml:"带分音符的拉丁小写字母 a",
-	aring:"带上圆圈的拉丁小写字母 a\n带圆圈的拉丁小写字母 a",
+	aring:"具有上圆圈的拉丁语小写字母 a",
 	aelig:"拉丁小写字母 ae\n拉丁小写连字 ae",
 	ccedil:"带软音符的拉丁小写字母 c",
 	egrave:"带重音符的拉丁小写字母 e",
-	eacute:"带锐音符的拉丁小写字母 e",
+	eacute:"具有锐音符的拉丁语小写字母 e",
 	ecirc:"带抑扬符的拉丁小写字母 e",
 	euml:"带分音符的拉丁小写字母 e",
 	igrave:"带重音符的拉丁小写字母 i",
 	iacute:"带锐音符的拉丁小写字母 i",
 	icirc:"带抑扬符的拉丁小写字母 i",
 	iuml:"带分音符的拉丁小写字母 i",
-	eth:"拉丁小写字母 eth",
+	eth:"拉丁语小写字母 eth",
 	ntilde:"带颚化音的拉丁小写字母 n",
 	ograve:"带重音符的拉丁小写字母 o",
 	oacute:"带锐音符的拉丁小写字母 o",
-	ocirc:"带抑扬符的拉丁小写字母 o",
+	ocirc:"具有音调符号的拉丁语小写字母 o",
 	otilde:"带颚化音的拉丁小写字母 o",
 	ouml:"带分音符的拉丁小写字母 o",
 	divide:"除号",
@@ -100,68 +99,67 @@ define(
 	ucirc:"带抑扬符的拉丁小写字母 u",
 	uuml:"带分音符的拉丁小写字母 u",
 	yacute:"带锐音符的拉丁小写字母 y",
-	thorn:"拉丁小写字母 thorn",
-	yuml:"带分音符的拉丁小写字母 y",
-
+	thorn:"拉丁语小写字母 thorn",
+	yuml:"具有分音符号的拉丁语小写字母 y",
 // Greek Characters and Symbols
-	fnof:"带挂钩符号的拉丁小写 f\n分数\nflorin",
+	fnof:"带挂钩符号的拉丁小写 f\n分数\n弗罗林",
 	Alpha:"希腊大写字母 alpha",
 	Beta:"希腊大写字母 beta",
 	Gamma:"希腊大写字母 gamma",
-	Delta:"希腊大写字母 delta",
+	Delta:"希腊语大写字母 delta",
 	Epsilon:"希腊大写字母 epsilon",
 	Zeta:"希腊大写字母 zeta",
 	Eta:"希腊大写字母 eta",
-	Theta:"希腊大写字母 theta",
+	Theta:"希腊语大写字母 theta",
 	Iota:"希腊大写字母 iota",
 	Kappa:"希腊大写字母 kappa",
 	Lambda:"希腊大写字母 lambda",
 	Mu:"希腊大写字母 mu",
-	Nu:"希腊大写字母 nu",
+	Nu:"希腊语大写字母 nu",
 	Xi:"希腊大写字母 xi",
 	Omicron:"希腊大写字母 omicron",
 	Pi:"希腊大写字母 pi",
 	Rho:"希腊大写字母 rho",
-	Sigma:"希腊大写字母 sigma",
+	Sigma:"希腊语大写字母 sigma",
 	Tau:"希腊大写字母 tau",
 	Upsilon:"希腊大写字母 upsilon",
 	Phi:"希腊大写字母 phi",
 	Chi:"希腊大写字母 chi",
-	Psi:"希腊大写字母 psi",
+	Psi:"希腊语大写字母 psi",
 	Omega:"希腊大写字母 omega",
-	alpha:"希腊小写字母 alpha",
+	alpha:"希腊语小写字母 alpha",
 	beta:"希腊小写字母 beta",
 	gamma:"希腊小写字母 gamma",
-	delta:"希腊小写字母 delta",
+	delta:"希腊语小写字母 delta",
 	epsilon:"希腊小写字母 epsilon",
-	zeta:"希腊小写字母 zeta",
-	eta:"希腊小写字母 eta",
+	zeta:"希腊语小写字母 zeta",
+	eta:"希腊语小写字母 eta",
 	theta:"希腊小写字母 theta",
 	iota:"希腊小写字母 iota",
 	kappa:"希腊小写字母 kappa",
-	lambda:"希腊小写字母 lambda",
+	lambda:"希腊语小写字母 lambda",
 	mu:"希腊小写字母 mu",
 	nu:"希腊小写字母 nu",
 	xi:"希腊小写字母 xi",
-	omicron:"希腊小写字母 omicron",
-	pi:"希腊小写字母 pi",
-	rho:"希腊小写字母 rho",
-	sigmaf:"希腊小写字母 final sigma",
-	sigma:"希腊小写字母 sigma",
-	tau:"希腊小写字母 tau",
+	omicron:"希腊语小写字母 omicron",
+	pi:"希腊语小写字母 pi",
+	rho:"希腊语小写字母 rho",
+	sigmaf:"希腊语小写字母 final",
+	sigma:"希腊语小写字母 final",
+	tau:"希腊语小写字母 tau",
 	upsilon:"希腊小写字母 upsilon",
 	phi:"希腊小写字母 phi",
-	chi:"希腊小写字母 chi",
+	chi:"希腊语小写字母 final",
 	psi:"希腊小写字母 psi",
-	omega:"希腊小写字母 omega",
-	thetasym:"希腊小写字母 theta 符号",
+	omega:"希腊语小写字母 final",
+	thetasym:"希腊语小写字母 theta",
 	upsih:"带挂钩符号的希腊字母 upsilon",
 	piv:"希腊 pi 符号",
-	bull:"子弹符号\n黑色小圆圈",
+	bull:"项目符号\n黑色小圆圈",
 	hellip:"水平省略号\n三个点组成的标题",
-	prime:"分钟符号\n分钟\n尺",
-	Prime:"秒符号\n秒\n寸",
-	oline:"顶线\n间隔顶线",
+	prime:"上标符\n分钟\n英尺",
+	Prime:"双上标符\n秒\n英寸",
+	oline:"上划线\n间隔顶线",
 	frasl:"分数斜杠",
 	weierp:"脚本大写 P\n幂集\nWeierstrass p",
 	image:"黑色大写字母 I\n虚部符号",
@@ -172,36 +170,36 @@ define(
 	uarr:"向上箭头",
 	rarr:"向右箭头",
 	darr:"向下箭头",
-	harr:"向左上箭头",
-	crarr:"回车符\n回车符",
+	harr:"左右箭头",
+	crarr:"角朝左的向下箭头\n回车符",
 	lArr:"向左双箭头",
 	uArr:"向上双箭头",
 	rArr:"向右双箭头",
 	dArr:"向下双箭头",
 	hArr:"左右向双箭头",
 	forall:"全部",
-	part:"部分差分",
+	part:"部分差异",
 	exist:"存在",
 	empty:"空集\n空集\n直径",
 	nabla:"劈形算符\n后向差分",
 	isin:"...的元素",
 	notin:"不是...的元素",
-	ni:"作为成员包含",
-	prod:"N 元积\n积符号",
-	sum:"N 元和",
-	minus:"负号",
+	ni:"包含为成员",
+	prod:"N 元乘积\n乘积符号",
+	sum:"n 元求和",
+	minus:"减号",
 	lowast:"星号运算符",
 	radic:"平方根\n根号",
 	prop:"成比例",
-	infin:"无限",
+	infin:"无穷大",
 	ang:"角度",
-	and:"逻辑和\n尖三角形",
+	and:"逻辑与\n楔形",
 	or:"逻辑或\n V 字形",
 	cap:"交集\n盖状",
-	cup:"并集n\n杯状","int":"整数",
+	cup:"并集\n杯状","int":"整数",
 	there4:"因此",
 	sim:"颚化音运算符\n偏离\n相似",
-	cong:"约等于",
+	cong:"近似等于",
 	asymp:"几乎等于\n渐近",
 	ne:"不等于",
 	equiv:"完全相等",
@@ -213,13 +211,13 @@ define(
 	sube:"...的子集或等于",
 	supe:"...的超集或等于",
 	oplus:"带圆圈的加号\n异或",
-	otimes:"带圆圈的乘号\n向量积",
+	otimes:"带圆圈的乘号\n向量乘积",
 	perp:"倒 T\n正交于\n垂直",
-	sdot:"点运算符",
-	lceil:"left ceiling\nAPL upstile",
-	rceil:"right ceiling",
-	lfloor:"left floor\nAPL downstile",
-	rfloor:"right floor",
+	sdot:"点操作符",
+	lceil:"左顶棚\nAPL upstile",
+	rceil:"右顶棚",
+	lfloor:"左地板\nAPL downstile",
+	rfloor:"右地板",
 	lang:"左尖括号",
 	rang:"右尖括号",
 	loz:"菱形",
@@ -234,27 +232,26 @@ define(
 	Yuml:"带分音符的拉丁大写字母 Y",
 	circ:"修饰符字母抑扬符重音符",
 	tilde:"小颚化音符号",
-	ensp:"单倍间距",
+	ensp:"半角空格",
 	emsp:"双倍间距",
 	thinsp:"窄空格",
 	zwnj:"零宽度非连字符",
-	zwj:"零宽度连字符",
+	zwj:"零宽连接符",
 	lrm:"从左向右标记",
 	rlm:"从右向左标记",
 	ndash:"短破折号",
 	mdash:"长破折号",
 	lsquo:"左单引号",
 	rsquo:"右单引号",
-	sbquo:"低单引号",
+	sbquo:"单下 9 引号",
 	ldquo:"左双引号",
 	rdquo:"右双引号",
-	bdquo:"低双引号",
+	bdquo:"双下 9 引号",
 	dagger:"剑号",
 	Dagger:"双剑号",
 	permil:"千分率符号",
-	lsaquo:"左尖括号",
-	rsaquo:"右尖括号",
+	lsaquo:"单左指尖引号",
+	rsaquo:"单右指尖引号",
 	euro:"欧元符号"
 })
-//end v1.x content
 );
diff --git a/dojox/editor/plugins/resources/css/SpellCheck.css b/dojox/editor/plugins/resources/css/SpellCheck.css
index 434b579..bd4fda0 100644
--- a/dojox/editor/plugins/resources/css/SpellCheck.css
+++ b/dojox/editor/plugins/resources/css/SpellCheck.css
@@ -11,11 +11,8 @@
 	background-repeat: no-repeat;
 	background-position: center center;
 	display: inline-block;
-	zoom: 1;
-	*display: inline;
 	width: 16px;
 	height: 16px;
-	margin: 0em 0.5em 0em 0.5em;
 }
 
 .dijitEditorSpellCheckTable .dijitEditorSpellCheckBox {
diff --git a/dojox/editor/plugins/resources/editorPlugins.css b/dojox/editor/plugins/resources/editorPlugins.css
index db2c08a..253545c 100644
--- a/dojox/editor/plugins/resources/editorPlugins.css
+++ b/dojox/editor/plugins/resources/editorPlugins.css
@@ -123,16 +123,13 @@
 }
 
 .dojoxDropDownSelect {
-	background:#FFFFFF url(images/dropBk.png) repeat-x scroll left top;
+	background:#FFFFFF;
 	border: 1px solid;
 	border-top-color:#cccccc;
 	border-right-color:#cccccc;
 	border-left-color:#999999;
 	border-bottom-color:#ffffff;
 }
-.dojoxDropDownSelect.dojoxDropDownSelectHover{
-	background-image:url(images/dropBkOver.png);
-}
 .dojoxDropDownSelect button{
 	line-height:16px;
 	height:16px;
@@ -141,12 +138,6 @@
 	color:#8397b9;
 }
 
-.dijitButtonNode .dijitArrowButtonInner{
-	/* fixing the dijit drop arrows - can't figure why this broke */
-	background:url(../../../../dijit/themes/tundra/images/spriteArrows.png) no-repeat left top;
-	width:7px;
-}
-
 .dojoxEditorUploadNorm{
 	font-family:Arial;
 	font-size:12px;
diff --git a/dojox/editor/plugins/resources/images/checking.gif b/dojox/editor/plugins/resources/images/checking.gif
new file mode 100644
index 0000000..b2778a6
Binary files /dev/null and b/dojox/editor/plugins/resources/images/checking.gif differ
diff --git a/dojox/editor/plugins/resources/insertTable.html b/dojox/editor/plugins/resources/insertTable.html
index da5e9a8..11679fa 100644
--- a/dojox/editor/plugins/resources/insertTable.html
+++ b/dojox/editor/plugins/resources/insertTable.html
@@ -26,13 +26,13 @@
                   <option value="pixels">${pixels}</option>
                 </select></td></tr>	
             <tr><td>
-                <label>${borderThickness}</label></td>
+                <label>${borderThickness}</label>
             </td><td>
                 <span dojoAttachPoint="selectBorder" dojoType="dijit.form.TextBox" value="1"></span>
             </td><td>
                 ${pixels}
             </td></tr><tr><td>
-                <label>${cellPadding}</label></td>
+                <label>${cellPadding}</label>
             </td><td>
                 <span dojoAttachPoint="selectPad" dojoType="dijit.form.TextBox" value="0"></span>
             </td><td class="cellpad"></td></tr><tr><td>
diff --git a/dojox/editor/plugins/resources/modifyTable.html b/dojox/editor/plugins/resources/modifyTable.html
index 35232a7..d96fd2f 100644
--- a/dojox/editor/plugins/resources/modifyTable.html
+++ b/dojox/editor/plugins/resources/modifyTable.html
@@ -35,13 +35,13 @@
                   <option value="pixels">${pixels}</option>
                 </select></td></tr>	
             <tr><td>
-                <label>${borderThickness}</label></td>
+                <label>${borderThickness}</label>
             </td><td>
                 <span dojoAttachPoint="selectBorder" dojoType="dijit.form.TextBox" value="1"></span>
             </td><td>
                 ${pixels}
             </td></tr><tr><td>
-                <label>${cellPadding}</label></td>
+                <label>${cellPadding}</label>
             </td><td>
                 <span dojoAttachPoint="selectPad" dojoType="dijit.form.TextBox" value="0"></span>
             </td><td class="cellpad"></td></tr><tr><td>
diff --git a/dojox/editor/tests/editorAutoSave.html b/dojox/editor/tests/editorAutoSave.html
index 507fd3e..8184762 100644
--- a/dojox/editor/tests/editorAutoSave.html
+++ b/dojox/editor/tests/editorAutoSave.html
@@ -12,7 +12,7 @@
 		@import "../plugins/resources/css/ShowBlockNodes.css";
 	</style>
 	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/editor/tests/editorAutoUrlLink.html b/dojox/editor/tests/editorAutoUrlLink.html
index cdbe2c2..c5ea91d 100644
--- a/dojox/editor/tests/editorAutoUrlLink.html
+++ b/dojox/editor/tests/editorAutoUrlLink.html
@@ -10,7 +10,7 @@
 		@import "../../../dijit/themes/claro/claro.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/editor/tests/editorBlockquote.html b/dojox/editor/tests/editorBlockquote.html
index 00f4155..8160143 100755
--- a/dojox/editor/tests/editorBlockquote.html
+++ b/dojox/editor/tests/editorBlockquote.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/Blockquote.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorBreadcrumb.html b/dojox/editor/tests/editorBreadcrumb.html
index e1c7c65..f91ddf2 100644
--- a/dojox/editor/tests/editorBreadcrumb.html
+++ b/dojox/editor/tests/editorBreadcrumb.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/Breadcrumb.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorCollapsibleToolbar.html b/dojox/editor/tests/editorCollapsibleToolbar.html
index 943cad2..8274027 100755
--- a/dojox/editor/tests/editorCollapsibleToolbar.html
+++ b/dojox/editor/tests/editorCollapsibleToolbar.html
@@ -19,7 +19,7 @@
 		@import "../plugins/resources/css/CollapsibleToolbar.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorFindReplace.html b/dojox/editor/tests/editorFindReplace.html
index a8f9992..1464364 100755
--- a/dojox/editor/tests/editorFindReplace.html
+++ b/dojox/editor/tests/editorFindReplace.html
@@ -12,7 +12,7 @@
 		@import "../plugins/resources/css/ShowBlockNodes.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorInsertAnchor.html b/dojox/editor/tests/editorInsertAnchor.html
index 7a93d8c..c2b5b7c 100755
--- a/dojox/editor/tests/editorInsertAnchor.html
+++ b/dojox/editor/tests/editorInsertAnchor.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/InsertAnchor.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorInsertEntity.html b/dojox/editor/tests/editorInsertEntity.html
index 15b6aaf..8c927e6 100755
--- a/dojox/editor/tests/editorInsertEntity.html
+++ b/dojox/editor/tests/editorInsertEntity.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/InsertEntity.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorLocalImage.html b/dojox/editor/tests/editorLocalImage.html
index 2fa384c..e70495d 100644
--- a/dojox/editor/tests/editorLocalImage.html
+++ b/dojox/editor/tests/editorLocalImage.html
@@ -12,7 +12,7 @@
 		@import "../plugins/resources/css/LocalImage.css";
 	</style>
 	
-	<script type="text/javascript" src="../../../dojo/dojo.js"	djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js"	data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorNormalizeIndentOutdent.html b/dojox/editor/tests/editorNormalizeIndentOutdent.html
index 4fa637d..f3087f9 100755
--- a/dojox/editor/tests/editorNormalizeIndentOutdent.html
+++ b/dojox/editor/tests/editorNormalizeIndentOutdent.html
@@ -10,7 +10,7 @@
 		@import "../../../dijit/themes/tundra/tundra.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorNormalizeStyle.html b/dojox/editor/tests/editorNormalizeStyle.html
index 77e84df..59265b9 100755
--- a/dojox/editor/tests/editorNormalizeStyle.html
+++ b/dojox/editor/tests/editorNormalizeStyle.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/TextColor.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorPageBreak.html b/dojox/editor/tests/editorPageBreak.html
index 1f553fa..d0ffd48 100755
--- a/dojox/editor/tests/editorPageBreak.html
+++ b/dojox/editor/tests/editorPageBreak.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/PageBreak.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorPasteFromWord.html b/dojox/editor/tests/editorPasteFromWord.html
index 08ac086..9ded6c8 100755
--- a/dojox/editor/tests/editorPasteFromWord.html
+++ b/dojox/editor/tests/editorPasteFromWord.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/PasteFromWord.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorPrettyPrint.html b/dojox/editor/tests/editorPrettyPrint.html
index 33dce66..f2c1a93 100755
--- a/dojox/editor/tests/editorPrettyPrint.html
+++ b/dojox/editor/tests/editorPrettyPrint.html
@@ -10,7 +10,7 @@
 		@import "../../../dijit/themes/tundra/tundra.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.layout.AccordionContainer");
diff --git a/dojox/editor/tests/editorPreview.html b/dojox/editor/tests/editorPreview.html
index 991d340..70d309a 100755
--- a/dojox/editor/tests/editorPreview.html
+++ b/dojox/editor/tests/editorPreview.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/Preview.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorResizeTableColumn.html b/dojox/editor/tests/editorResizeTableColumn.html
index 128f230..5950e29 100644
--- a/dojox/editor/tests/editorResizeTableColumn.html
+++ b/dojox/editor/tests/editorResizeTableColumn.html
@@ -6,7 +6,6 @@
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dijit/themes/claro/claro.css";
-			@import "../../../dijit/themes/dijit.css";
 		</style>
 
 		<link href="../plugins/resources/editorPlugins.css" type="text/css" rel="stylesheet" />
diff --git a/dojox/editor/tests/editorSafePaste.html b/dojox/editor/tests/editorSafePaste.html
index 31b6efc..34eb906 100644
--- a/dojox/editor/tests/editorSafePaste.html
+++ b/dojox/editor/tests/editorSafePaste.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/SafePaste.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorSave.html b/dojox/editor/tests/editorSave.html
index 6f3aa6c..31ff14f 100644
--- a/dojox/editor/tests/editorSave.html
+++ b/dojox/editor/tests/editorSave.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/Save.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorShowBlockNodes.html b/dojox/editor/tests/editorShowBlockNodes.html
index 5c441f2..c27ada3 100755
--- a/dojox/editor/tests/editorShowBlockNodes.html
+++ b/dojox/editor/tests/editorShowBlockNodes.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/ShowBlockNodes.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorSmileyPlugin.html b/dojox/editor/tests/editorSmileyPlugin.html
index dd106e0..06420b1 100644
--- a/dojox/editor/tests/editorSmileyPlugin.html
+++ b/dojox/editor/tests/editorSmileyPlugin.html
@@ -10,7 +10,7 @@
 		@import "../../../dijit/themes/tundra/tundra.css";
 		@import "../plugins/resources/css/Smiley.css";
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorSpellCheck.html b/dojox/editor/tests/editorSpellCheck.html
index 3edb42e..5df2201 100644
--- a/dojox/editor/tests/editorSpellCheck.html
+++ b/dojox/editor/tests/editorSpellCheck.html
@@ -13,7 +13,7 @@
 		@import "../plugins/resources/css/SpellCheck.css";
 	</style>
 	
-	<script type="text/javascript" src="../../../dojo/dojo.js"	djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js"	data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/editor/tests/editorStatusBar.html b/dojox/editor/tests/editorStatusBar.html
index ba1fe8e..f02b878 100755
--- a/dojox/editor/tests/editorStatusBar.html
+++ b/dojox/editor/tests/editorStatusBar.html
@@ -12,7 +12,7 @@
 		@import "../plugins/resources/css/StatusBar.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorTablePlugs.html b/dojox/editor/tests/editorTablePlugs.html
index 130b56d..635435a 100644
--- a/dojox/editor/tests/editorTablePlugs.html
+++ b/dojox/editor/tests/editorTablePlugs.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!DOCTYPE html>
 <html xmlns="http://www.w3.org/1999/xhtml">
 	<head>
 	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
@@ -6,16 +6,15 @@
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dijit/themes/claro/claro.css";
-			@import "../../../dijit/themes/dijit.css";
 			@import "../../widget/ColorPicker/ColorPicker.css";
 		</style>
 
 		<link href="../plugins/resources/editorPlugins.css" type="text/css" rel="stylesheet" />
 
 		<script type="text/javascript">
-			var djConfig = {
+			var dojoConfig = {
+				async: true,
 				isDebug: true,
-				parseOnLoad: true,
 				popup:true
 				//forceFirebugLite:true
 			};
@@ -27,20 +26,25 @@
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 		
 		<script>
-			dojo.require("dojo.parser");
-			dojo.require("dijit.Editor");
-			dojo.require("dijit.form.Button");
-			dojo.require("dojox.editor.plugins.TablePlugins");
-			dojo.require("dijit._editor.plugins.ViewSource");
-			dojo.addOnLoad(function(){
-				console.log(dojo.version.toString());
-			});
+			require([
+				"dojo/_base/kernel",
+				"dojo/on",
+				"dojo/parser",
+				"dijit/registry",
+				"dijit/Editor",
+				"dijit/form/Button",
+				"dojox/editor/plugins/TablePlugins",
+				"dijit/_editor/plugins/ViewSource",
+				"dojo/domReady"
+			], function(kernel, on, parser, registry) {
+				console.log(kernel.version.toString());
+				
+				parser.parse();
 
-			dojo.addOnLoad(function(){
-				var editor = dijit.byId("editor");
-				var button = dijit.byId("removeButton");
-				var c = dojo.connect(button, "onClick", function(){
-					dojo.disconnect(c);
+				var editor = registry.byId("editor");
+				var button = registry.byId("removeButton");
+				var c = on(button, "click", function(){
+					c.remove();
 					editor.close();
 					editor.destroy();
 				});
@@ -55,22 +59,24 @@
 	</head>
 	<body class="claro">
 		<div id="main">
-			<div id="editor" dojoType="dijit.Editor" height="200px" plugins="[
+			<div id="editor" data-dojo-type="dijit/Editor"
+				 data-dojo-props="height: '200px', plugins: [
 				'undo', 'redo', 'bold','italic','|',
-				{name: 'dojox.editor.plugins.TablePlugins', command: 'insertTable'},
-				{name: 'dojox.editor.plugins.TablePlugins', command: 'modifyTable'},
-				{name: 'dojox.editor.plugins.TablePlugins', command: 'InsertTableRowBefore'},
-				{name: 'dojox.editor.plugins.TablePlugins', command: 'InsertTableRowAfter'},
-				{name: 'dojox.editor.plugins.TablePlugins', command: 'insertTableColumnBefore'},
-				{name: 'dojox.editor.plugins.TablePlugins', command: 'insertTableColumnAfter'},
-				{name: 'dojox.editor.plugins.TablePlugins', command: 'deleteTableRow'},
-				{name: 'dojox.editor.plugins.TablePlugins', command: 'deleteTableColumn'},
-				{name: 'dojox.editor.plugins.TablePlugins', command: 'colorTableCell'},
-				{name: 'dojox.editor.plugins.TablePlugins', command: 'tableContextMenu'}
+				{name: 'insertTable'},
+				{name: 'modifyTable'},
+				{name: 'insertTableRowBefore'},
+				{name: 'insertTableRowAfter'},
+				{name: 'insertTableColumnBefore'},
+				{name: 'insertTableColumnAfter'},
+				{name: 'deleteTableRow'},
+				{name: 'deleteTableColumn'},
+				{name: 'colorTableCell'},
+				{name: 'tableContextMenu'}
 			]">
 				Dojo Rocks with a fox in socks. Red socks. In a box.
 				<br/><br/>
-			        <table width="200" border="2" cellpadding="2" cellspacing="2" bordercolor="#00FFFF" bgcolor="#FF0000" id="myTable">
+			        <table width="200" border="2" cellpadding="2" cellspacing="2" id="myTable"
+						   style="border-color: #0ff; background-color: #f00">
 					<tr>
 						<td> </td>
 						<td> </td>
@@ -89,6 +95,35 @@
 				</table> 
 			</div>
 		</div>
-		<button id="removeButton" dojoType="dijit.form.Button">Remove Editor</button>
+		<button id="removeButton" data-dojo-type="dijit/form/Button">Remove Editor</button>
+		<hr>
+			<h2>Test Different Color Picker in modifyTable and colorTableCell</h2>
+			<p>This test uses the dojox/widget/ColorPicker picker in modifyTable, which normally uses dijit/ColorPalette, and vice versa for colorTableCell.</p>
+			<div id="editor2" data-dojo-type="dijit/Editor" style="height: 200px"
+				 data-dojo-props="plugins: [ 'undo', 'redo', 'bold','italic','|',
+					{name: 'modifyTable', colorPicker: 'dojox/widget/ColorPicker'},
+					{name: 'colorTableCell', colorPicker: 'dijit/ColorPalette'}]">
+				Dojo Rocks with a fox in socks. Red socks. In a box.
+				<br/><br/>
+			        <table width="200" border="2" cellpadding="2" id="myTable2"
+						   style="border-color: #0ff; background-color: #f00">
+					<tr>
+						<td> </td>
+						<td> </td>
+						<td> </td>
+					</tr>
+					<tr>
+						<td> </td>
+						<td id="myCell2"> </td>
+						<td> </td>
+					</tr>
+					<tr>
+						<td> </td>
+						<td> </td>
+						<td bgcolor="#00FFFF">Text</td>
+					</tr>
+				</table> 
+			</div>
+			
 	</body>
 </html>
diff --git a/dojox/editor/tests/editorTextColor.html b/dojox/editor/tests/editorTextColor.html
index 9b3f215..354b462 100755
--- a/dojox/editor/tests/editorTextColor.html
+++ b/dojox/editor/tests/editorTextColor.html
@@ -11,7 +11,7 @@
 		@import "../plugins/resources/css/TextColor.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorToolbarLineBreak.html b/dojox/editor/tests/editorToolbarLineBreak.html
index df99482..83daf0f 100755
--- a/dojox/editor/tests/editorToolbarLineBreak.html
+++ b/dojox/editor/tests/editorToolbarLineBreak.html
@@ -10,7 +10,7 @@
 		@import "../../../dijit/themes/tundra/tundra.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/editor/tests/editorUploadPlug.html b/dojox/editor/tests/editorUploadPlug.html
index c89b8a9..4232d74 100644
--- a/dojox/editor/tests/editorUploadPlug.html
+++ b/dojox/editor/tests/editorUploadPlug.html
@@ -6,7 +6,6 @@
 <style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/tundra/tundra.css";
-		@import "../../../dijit/themes/dijit.css";
 	</style>
     
     <link href="../../form/resources/FileInput.css" type="text/css" rel="stylesheet" />
diff --git a/dojox/editor/tests/robot/Editor_Smiley.html b/dojox/editor/tests/robot/Editor_Smiley.html
index 93276be..c7acb8c 100644
--- a/dojox/editor/tests/robot/Editor_Smiley.html
+++ b/dojox/editor/tests/robot/Editor_Smiley.html
@@ -10,13 +10,11 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../../../../dijit/tests/helpers.js"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.tests.helpers");	// functions to help test
 
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../editorSmileyPlugin.html');
diff --git a/dojox/editor/tests/testPluginsAll.html b/dojox/editor/tests/testPluginsAll.html
index b28a314..891b288 100644
--- a/dojox/editor/tests/testPluginsAll.html
+++ b/dojox/editor/tests/testPluginsAll.html
@@ -30,7 +30,7 @@
 		#borderContainer { width:100%; height:100%; overflow:hidden;}
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.Editor");
diff --git a/dojox/embed/Flash.js b/dojox/embed/Flash.js
index 3527bb3..a609766 100644
--- a/dojox/embed/Flash.js
+++ b/dojox/embed/Flash.js
@@ -1,16 +1,13 @@
 define(["dojo"], function(dojo) {
 
-	/*******************************************************
-		dojox.embed.Flash
+	// module:
+	//		dojox/embed/Flash
+	// summary:
+	//		Base functionality to insert a flash movie into
+	//		a document on the fly.
+	// example:
+	//	|	var movie=new Flash({ args }, containerNode);
 
-		Base functionality to insert a flash movie into
-		a document on the fly.
-
-		Usage:
-		var movie=new dojox.embed.Flash({ args }, containerNode);
-	 ******************************************************/
-
-	dojo.getObject("embed", true, dojox);
 
 	var fMarkup, fVersion;
 	var minimumVersion = 9; // anything below this will throw an error (may overwrite)
@@ -90,7 +87,8 @@ define(["dojo"], function(dojo) {
 		})();
 
 		//	attach some cleanup for IE, thanks to deconcept :)
-		dojo.addOnUnload(function(){
+		dojo.addOnWindowUnload(function(){
+			console.warn('***************UNLOAD');
 			var dummy = function(){};
 			var objs = dojo.query("object").
 				reverse().
@@ -155,49 +153,39 @@ define(["dojo"], function(dojo) {
 
 
 /*=====
-dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars, expressInstall, redirect){
-	//	path: String
+var __flashArgs = {
+	// path: String
 	//		The URL of the movie to embed.
-	//	id: String?
+	// id: String?
 	//		A unique key that will be used as the id of the created markup.  If you don't
 	//		provide this, a unique key will be generated.
-	//	width: Number?
+	// width: Number?
 	//		The width of the embedded movie; the default value is 320px.
-	//	height: Number?
+	// height: Number?
 	//		The height of the embedded movie; the default value is 240px
-	//	minimumVersion: Number ?
+	// minimumVersion: Number?
 	//		The minimum targeted version of the Flash Player (defaults to 9)
-	//	style: String?
+	// style: String?
 	//		Any CSS style information (i.e. style="background-color:transparent") you want
 	//		to define on the markup.
-	//	params: Object?
+	// params: Object?
 	//		A set of key/value pairs that you want to define in the resultant markup.
-	//	vars: Object?
+	// vars: Object?
 	//		A set of key/value pairs that the Flash movie will interpret as FlashVars.
-	//	expressInstall: Boolean?
+	// expressInstall: Boolean?
 	//		Whether or not to include any kind of expressInstall info. Default is false.
-	//	redirect: String?
+	// redirect: String?
 	//		A url to redirect the browser to if the current Flash version is not supported.
-	this.id=id;
-	this.path=path;
-	this.width=width;
-	this.minimumVersion=minimumVersion;
-	this.height=height;
-	this.style=style;
-	this.params=params;
-	this.vars=vars;
-	this.expressInstall=expressInstall;
-	this.redirect=redirect;
-}
+};
 =====*/
 
 	//	the main entry point
-	dojox.embed.Flash = function(/*dojox.embed.__flashArgs*/ kwArgs, /*DOMNode*/ node){
-		//	summary:
+	var Flash = function(/*__flashArgs*/ kwArgs, /*DOMNode*/ node){
+		// summary:
 		//		Create a wrapper object around a Flash movie; this is the DojoX equivilent
 		//		to SWFObject.
 		//
-		//	description:
+		// description:
 		//		Creates a wrapper object around a Flash movie.  Wrapper object will
 		//		insert the movie reference in node; when the browser first starts
 		//		grabbing the movie, onReady will be fired; when the movie has finished
@@ -209,12 +197,12 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 		//		Flash movie will shoot several methods into the window object before
 		//		EI callbacks can be used properly).
 		//
-		//	kwArgs: dojox.embed.__flashArgs
+		// kwArgs: __flashArgs
 		//		The various arguments that will be used to help define the Flash movie.
-		//	node: DomNode
+		// node: DomNode
 		//		The node where the embed object will be placed
 		//
-		//	example:
+		// example:
 		//		Embed a flash movie in a document using the new operator, and get a reference to it.
 		//	|	var movie = new dojox.embed.Flash({
 		//	|		path: "path/to/my/movie.swf",
@@ -222,7 +210,7 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 		//	|		height: 300
 		//	|	}, myWrapperNode, "testLoaded");
 		//
-		//	example:
+		// example:
 		//		Embed a flash movie in a document without using the new operator.
 		//	|	var movie = dojox.embed.Flash({
 		//	|		path: "path/to/my/movie.swf",
@@ -230,29 +218,29 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 		//	|		height: 300,
 		//	|		style: "position:absolute;top:0;left:0"
 		//	|	}, myWrapperNode, "testLoaded");
-		//
+
 		// File can only be run from a server, due to SWF dependency.
 		if(location.href.toLowerCase().indexOf("file://")>-1){
 			throw new Error("dojox.embed.Flash can't be run directly from a file. To instatiate the required SWF correctly it must be run from a server, like localHost.");
 		}
 
-		//	available: Number
+		// available: Number
 		//		If there is a flash player available, and if so what version.
 		this.available = dojox.embed.Flash.available;
 
-		//	minimumVersion: Number
+		// minimumVersion: Number
 		//		The minimum version of Flash required to run this movie.
 		this.minimumVersion = kwArgs.minimumVersion || minimumVersion;
 
-		//	id: String
+		// id: String
 		//		The id of the DOMNode to be used for this movie.  Can be used with dojo.byId to get a reference.
 		this.id = null;
 
-		//	movie: FlashObject
+		// movie: FlashObject
 		//		A reference to the movie itself.
 		this.movie = null;
 
-		//	domNode: DOMNode
+		// domNode: DOMNode
 		//		A reference to the DOMNode that contains this movie.
 		this.domNode = null;
 		if(node){
@@ -277,14 +265,14 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 		}), 100);
 	};
 
-	dojo.extend(dojox.embed.Flash, {
+	dojo.extend(Flash, {
 		onReady: function(/*HTMLObject*/ movie){
-			//	summary:
+			// summary:
 			//		Stub function for you to attach to when the movie reference is first
 			//		pushed into the document.
 		},
 		onLoad: function(/*HTMLObject*/ movie){
-			//	summary:
+			// summary:
 			//		Stub function for you to attach to when the movie has finished downloading
 			//		and is ready to be manipulated.
 		},
@@ -300,8 +288,8 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 			delete this._pollMax;
 			this.onLoad(this.movie);
 		},
-		init: function(/*dojox.embed.__flashArgs*/ kwArgs, /*DOMNode?*/ node){
-			//	summary
+		init: function(/*__flashArgs*/ kwArgs, /*DOMNode?*/ node){
+			// summary:
 			//		Initialize (i.e. place and load) the movie based on kwArgs.
 			this.destroy();		//	ensure we are clean first.
 			node = dojo.byId(node || this.domNode);
@@ -343,7 +331,7 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 			}
 		},
 		_destroy: function(){
-			//	summary
+			// summary:
 			//		Kill the movie and reset all the properties of this object.
 			try{
 				this.domNode.removeChild(this.movie);
@@ -351,7 +339,7 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 			this.id = this.movie = this.domNode = null;
 		},
 		destroy: function(){
-			//	summary
+			// summary:
 			//		Public interface for destroying all the properties in this object.
 			//		Will also clean all proxied methods.
 			if(!this.movie){ return; }
@@ -379,20 +367,19 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 			}
 		},
 		byId: function (movieName, doc){
-			// 	summary:
+			// summary:
 			//		Gets Flash movie by id.
-			//	description:
+			// description:
 			//		Probably includes methods for outdated
 			//		browsers, but this should catch all cases.
-			// arguments:
-			//		movieName: String
-			//			The name of the SWF
-			//		doc: Object
-			//			The document, if not current window
-			//			(not fully supported)
-			//	example:
-			//	| var movie = dojox.embed.Flash.byId("myId");
-			//
+			// movieName: String
+			//		The name of the SWF
+			// doc: Object
+			//		The document, if not current window
+			//		(not fully supported)
+			// example:
+			//	|	var movie = dojox.embed.Flash.byId("myId");
+
 			doc = doc || document;
 			if(doc.embeds[movieName]){
 				return doc.embeds[movieName];
@@ -411,27 +398,27 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 	});
 
 	//	expose information through the constructor function itself.
-	dojo.mixin(dojox.embed.Flash, {
-		//	summary:
+	dojo.mixin(Flash, {
+		// summary:
 		//		A singleton object used internally to get information
 		//		about the Flash player available in a browser, and
 		//		as the factory for generating and placing markup in a
 		//		document.
 		//
-		//	minSupported: Number
+		// minSupported: Number
 		//		The minimum supported version of the Flash Player, defaults to 8.
-		//	available: Number
+		// available: Number
 		//		Used as both a detection (i.e. if(dojox.embed.Flash.available){ })
 		//		and as a variable holding the major version of the player installed.
-		//	supported: Boolean
+		// supported: Boolean
 		//		Whether or not the Flash Player installed is supported by dojox.embed.
-		//	version: Object
+		// version: Object
 		//		The version of the installed Flash Player; takes the form of
 		//		{ major, minor, rev }.  To get the major version, you'd do this:
 		//		var v=dojox.embed.Flash.version.major;
-		//	initialized: Boolean
+		// initialized: Boolean
 		//		Whether or not the Flash engine is available for use.
-		//	onInitialize: Function
+		// onInitialize: Function
 		//		A stub you can connect to if you are looking to fire code when the
 		//		engine becomes available.  A note: DO NOT use this event to
 		//		place a movie in a document; it will usually fire before DOMContentLoaded
@@ -443,24 +430,24 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 		version: fVersion,
 		initialized: false,
 		onInitialize: function(){
-			dojox.embed.Flash.initialized = true;
+			Flash.initialized = true;
 		},
 		__ie_markup__: function(kwArgs){
 			return fMarkup(kwArgs);
 		},
-		proxy: function(/*dojox.embed.Flash*/ obj, /*Array|String*/ methods){
-			//	summary:
-			//		Create the set of passed methods on the dojox.embed.Flash object
+		proxy: function(/*Flash*/ obj, /*Array|String*/ methods){
+			// summary:
+			//		Create the set of passed methods on the Flash object
 			//		so that you can call that object directly, as opposed to having to
 			//		delve into the internal movie to do this.  Intended to make working
 			//		with Flash movies that use ExternalInterface much easier to use.
 			//
-			//	example:
+			// example:
 			//		Create "setMessage" and "getMessage" methods on foo.
-			//	|	var foo = new dojox.embed.Flash(args, someNode);
+			//	|	var foo = new Flash(args, someNode);
 			//	|	dojo.connect(foo, "onLoad", dojo.hitch(foo, function(){
-			//	|		dojox.embed.Flash.proxy(this, [ "setMessage", "getMessage" ]);
-			//	|		this.setMessage("dojox.embed.Flash.proxy is pretty cool...");
+			//	|		Flash.proxy(this, [ "setMessage", "getMessage" ]);
+			//	|		this.setMessage("Flash.proxy is pretty cool...");
 			//	|		console.log(this.getMessage());
 			//	|	}));
 			dojo.forEach((dojo.isArray(methods) ? methods : [ methods ]), function(item){
@@ -486,7 +473,7 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 		}
 	});
 
-	dojox.embed.Flash.place = function(kwArgs, node){
+	Flash.place = function(kwArgs, node){
 		var o = fMarkup(kwArgs);
 		node = dojo.byId(node);
 		if(!node){
@@ -500,7 +487,9 @@ dojox.embed.__flashArgs = function(path, id, width, height, style, params, vars,
 		}
 		return null;
 	}
-	dojox.embed.Flash.onInitialize();
+	Flash.onInitialize();
+
+	dojo.setObject("dojox.embed.Flash", Flash);
 
-	return dojox.embed.Flash;
+	return Flash;
 });
diff --git a/dojox/embed/Object.js b/dojox/embed/Object.js
index b361f93..9ac61d5 100644
--- a/dojox/embed/Object.js
+++ b/dojox/embed/Object.js
@@ -8,53 +8,56 @@ define([
 ], function (dojo, declare, domGeometry, _Widget, Flash, Quicktime) {
 dojo.experimental("dojox.embed.Object");
 
-return dojo.declare("dojox.embed.Object", _Widget, {
-	//	summary:
+return declare("dojox.embed.Object", _Widget, {
+	// summary:
 	//		A widget you can use to embed either a Flash or Quicktime
 	//		movie.
-	//
-	//	example:
-	//	From markup:
+	// example:
+	//		From markup:
 	//	|	<div dojoType="dojox.embed.Object" src="path/to/movie.swf"></div>
-	//
-	//	example:
-	//	Programmatic:
+	// example:
+	//		Programmatic:
 	//	|	var mov=new dojox.embed.Object({
 	//	|		src: "path/to/movie.swf"
 	//	|	}, node);
-	//
-	//	width: Number?
+
+	// width: Number?
 	//		The width of the movie. If not provided, the width of this.domNode is used.
-	//	height: Number?
+	width: 0,
+
+	// height: Number?
 	//		The height of the movie. If not provided, the height of this.domNode is used.
-	//	src: String
+	height: 0,
+
+	// src: String
 	//		The URL of the movie to embed.
-	//	movie: HTMLEmbed
+	src: "",
+
+	// movie: HTMLEmbed
 	//		The eventual reference to the movie embedded.  If you are looking to script
 	//		control over the movie, you'd access it this way.
-	//	params: Object
+	movie: null,
+
+	// params: Object
 	//		A property bag that is created postCreate.  Any additional attributes you
 	//		define on your domNode will be collected and placed into this, which will
 	//		then be passed to the movie constructor.
-	//	reFlash: RegExp
-	//		Expression used on the src property to determine if this is Flash or Quicktime.
-	//	reQtMovie: RegExp
-	//		Expression used on the src property to determine if this is Flash or Quicktime.
-	//	reQtAudio: RegExp
-	//		Expression used on the src property to determine if this is Flash or Quicktime.
-	
-	width: 0,
-	height: 0,
-	src: "",
-	movie: null,
 	params: null,
 
+	// reFlash: RegExp
+	//		Expression used on the src property to determine if this is Flash or Quicktime.
 	reFlash: /\.swf|\.flv/gi,
+
+	// reQtMovie: RegExp
+	//		Expression used on the src property to determine if this is Flash or Quicktime.
 	reQtMovie: /\.3gp|\.avi|\.m4v|\.mov|\.mp4|\.mpg|\.mpeg|\.qt/gi,
+
+	// reQtAudio: RegExp
+	//		Expression used on the src property to determine if this is Flash or Quicktime.
 	reQtAudio:/\.aiff|\.aif|\.m4a|\.m4b|\.m4p|\.midi|\.mid|\.mp3|\.mpa|\.wav/gi,
 	
 	postCreate: function(){
-		//	summary
+		// summary:
 		//		Constructs the movie and places it in the document.
 		if(!this.width || !this.height){
 			//	get the width and height from the domNode
diff --git a/dojox/embed/Quicktime.js b/dojox/embed/Quicktime.js
index ccf3c29..b3a1c17 100644
--- a/dojox/embed/Quicktime.js
+++ b/dojox/embed/Quicktime.js
@@ -5,14 +5,13 @@ define([
 	"dojo/_base/window",
 	"dojo/dom",
 	"dojo/dom-construct",
-	"dojo/domReady" // fixes doc.readyState in Fx<=3.5
+	"dojo/domReady!" // fixes doc.readyState in Fx<=3.5
 ], function (dojo, lang, has, windowUtil, domUtil, domConstruct) {
-	/*******************************************************
-		dojox.embed.Quicktime
-
-		Base functionality to insert a QuickTime movie
-		into a document on the fly.
-	 ******************************************************/
+	// module:
+	//		dojox/embed/Quicktime
+	// summary:
+	//		Base functionality to insert a QuickTime movie
+	//		into a document on the fly.
 
 	var qtMarkup,
 		qtVersion = { major: 0, minor: 0, rev: 0 },
@@ -110,38 +109,32 @@ define([
 	}
 
 	/*=====
-	dojox.embed.__QTArgs = function(path, id, width, height, params, redirect){
-		//	path: String
+	var __QTArgs = {
+		// path: String
 		//		The URL of the movie to embed.
-		//	id: String?
+		// id: String?
 		//		A unique key that will be used as the id of the created markup.  If you don't
 		//		provide this, a unique key will be generated.
-		//	width: Number?
+		// width: Number?
 		//		The width of the embedded movie; the default value is 320px.
-		//	height: Number?
+		// height: Number?
 		//		The height of the embedded movie; the default value is 240px
-		//	params: Object?
+		// params: Object?
 		//		A set of key/value pairs that you want to define in the resultant markup.
-		//	redirect: String?
+		// redirect: String?
 		//		A url to redirect the browser to if the current QuickTime version is not supported.
-		this.id=id;
-		this.path=path;
-		this.width=width;
-		this.height=height;
-		this.params=params;
-		this.redirect=redirect;
-	}
+	};
 	=====*/
 
-	embed.Quicktime=function(/* dojox.embed.__QTArgs */kwArgs, /* DOMNode */node){
-		//	summary:
+	var Quicktime=function(/* __QTArgs */kwArgs, /* DOMNode */node){
+		// summary:
 		//		Returns a reference to the HTMLObject/HTMLEmbed that is created to
 		//		place the movie in the document.  You can use this either with or
 		//		without the new operator.  Note that with any other DOM manipulation,
 		//		you must wait until the document is finished loading before trying
 		//		to use this.
 		//
-		//	example:
+		// example:
 		//		Embed a QuickTime movie in a document using the new operator, and get a reference to it.
 		//	|	var movie = new dojox.embed.Quicktime({
 		//	|		path: "path/to/my/movie.mov",
@@ -149,7 +142,7 @@ define([
 		//	|		height: 300
 		//	|	}, myWrapperNode);
 		//
-		//	example:
+		// example:
 		//		Embed a movie in a document without using the new operator.
 		//	|	var movie = dojox.embed.Quicktime({
 		//	|		path: "path/to/my/movie.mov",
@@ -157,31 +150,31 @@ define([
 		//	|		height: 300
 		//	|	}, myWrapperNode);
 
-		return embed.Quicktime.place(kwArgs, node);	//	HTMLObject
+		return Quicktime.place(kwArgs, node);	//	HTMLObject
 	};
 
-	dojo.mixin(embed.Quicktime, {
-		//	summary:
+	dojo.mixin(Quicktime, {
+		// summary:
 		//		A singleton object used internally to get information
 		//		about the QuickTime player available in a browser, and
 		//		as the factory for generating and placing markup in a
 		//		document.
 		//
-		//	minSupported: Number
+		// minSupported: Number
 		//		The minimum supported version of the QuickTime Player, defaults to
 		//		6.
-		//	available: Boolean
+		// available: Boolean
 		//		Whether or not QuickTime is available.
-		//	supported: Boolean
+		// supported: Boolean
 		//		Whether or not the QuickTime Player installed is supported by
 		//		dojox.embed.
-		//	version: Object
+		// version: Object
 		//		The version of the installed QuickTime Player; takes the form of
 		//		{ major, minor, rev }.  To get the major version, you'd do this:
 		//		var v=dojox.embed.Quicktime.version.major;
-		//	initialized: Boolean
+		// initialized: Boolean
 		//		Whether or not the QuickTime engine is available for use.
-		//	onInitialize: Function
+		// onInitialize: Function
 		//		A stub you can connect to if you are looking to fire code when the
 		//		engine becomes available.  A note: do NOT use this stub to embed
 		//		a movie in your document; this WILL be fired before DOMContentLoaded
@@ -194,7 +187,7 @@ define([
 		version: qtVersion,
 		initialized: false,
 		onInitialize: function(){
-			embed.Quicktime.initialized = true;
+			Quicktime.initialized = true;
 		},	//	stub function to let you know when this is ready
 
 		place: function(kwArgs, node){
@@ -230,9 +223,9 @@ define([
 				if(qt){
 					try{
 						var v = qt.GetQuickTimeVersion().split(".");
-						embed.Quicktime.version = { major: parseInt(v[0]||0), minor: parseInt(v[1]||0), rev: parseInt(v[2]||0) };
-						if((embed.Quicktime.supported = v[0])){
-							embed.Quicktime.onInitialize();
+						Quicktime.version = { major: parseInt(v[0]||0), minor: parseInt(v[1]||0), rev: parseInt(v[2]||0) };
+						if((Quicktime.supported = v[0])){
+							Quicktime.onInitialize();
 						}
 						c = 0;
 					} catch(e){
@@ -246,27 +239,20 @@ define([
 			}, 20);
 		}
 
-		if(windowUtil.doc.readyState === 'loaded' || windowUtil.doc.readyState === 'complete'){
-			// if onload has already fired, then body is available and we can create a new node
-			domConstruct.create("div", {
-				innerHTML: o.markup,
-				id: id,
-				style: { top:top, left:0, width:widthHeight, height:widthHeight, overflow:"hidden", position:"absolute" }
-			}, windowUtil.body());
-		}else{
-			// body isn't loaded yet, so we need to document.write the QuickTime markup
-			document.write(
-				'<div style="top:'+top+';left:0;width:'+widthHeight+';height:'+widthHeight+';overflow:hidden;position:absolute" id="' + id + '">'
-				+ o.markup
-				+ '</div>');
-		}
+		domConstruct.create("div", {
+			innerHTML: o.markup,
+			id: id,
+			style: { top:top, left:0, width:widthHeight, height:widthHeight, overflow:"hidden", position:"absolute" }
+		}, windowUtil.body());
 		getVer();
 	}else if(has("ie") && installed){
 		// we already know if IE has QuickTime installed, but we need this to seem like a callback.
 		setTimeout(function(){
-			embed.Quicktime.onInitialize();
+			Quicktime.onInitialize();
 		}, 10);
 	}
-	
-	return embed.Quicktime;
+
+	lang.setObject("dojox.embed.Quicktime", Quicktime);
+
+	return Quicktime;
 });
diff --git a/dojox/embed/flashVars.js b/dojox/embed/flashVars.js
index 798b5e9..605d0a4 100644
--- a/dojox/embed/flashVars.js
+++ b/dojox/embed/flashVars.js
@@ -1,10 +1,9 @@
-define(['dojo'],function(dojo){
+define(["dojo"], function(dojo){
 
-dojo.getObject("dojox.embed", true);
 dojo.deprecated("dojox.embed.flashVars", "Will be removed in 2.0", "2.0");
 
-dojox.embed.flashVars = {
-	//	summary
+var flashVars = {
+	// summary:
 	//		Handles flashvar serialization
 	//		Converting complex objects into a simple, clear string that can be appended
 	//		to the swf as a query: myMovie.swf?flashvars=foo.
@@ -12,23 +11,23 @@ dojox.embed.flashVars = {
 	//		Therefore this is something of an "internal" class - unless you know how to
 	//		modify or create SWFs.
 	//
-	//	description:
+	// description:
 	//		JSON could be done, but Deft does not yet have a JSON parser, and quotes are
 	//		very problematic since Flash cannot use eval(); JSON parsing was successful
 	//		when it was fully escaped, but that made it very large anyway. flashvar
 	//		serialization at most is 200% larger than JSON.
 	//
-	//	See:
+	// See:
 	//		Deft/common/flashVars.as
 	//
 	serialize: function(/* String */n, /*Object*/o){
 		// summary:
 		//		Key method. Serializes an object.
-		//	n:String
+		// n: String
 		//		The name for the object, such as: "button"
-		//	o:Object
+		// o: Object
 		//		The object to serialize
-		//
+
 		var esc = function(val){
 			//	have to encode certain characters that indicate an object
 			if(typeof val=="string"){
@@ -56,5 +55,8 @@ dojox.embed.flashVars = {
 		return n+":"+o; // String
 	}
 };
-return dojox.embed.flashVars;
+
+dojo.setObject("dojox.embed.flashVars", flashVars);
+
+return flashVars;
 });
diff --git a/dojox/embed/tests/object.html b/dojox/embed/tests/object.html
index a04e49c..ff3340a 100644
--- a/dojox/embed/tests/object.html
+++ b/dojox/embed/tests/object.html
@@ -11,7 +11,7 @@
 				height: 500px;
 			}
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.embed.Object");
 			dojo.require("dojo.parser");
diff --git a/dojox/embed/tests/quicktime.html b/dojox/embed/tests/quicktime.html
index 8888127..1f7f3b5 100644
--- a/dojox/embed/tests/quicktime.html
+++ b/dojox/embed/tests/quicktime.html
@@ -6,31 +6,29 @@
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
 		<script type="text/javascript">
-			dojo.require("dojox.embed.Quicktime");
-
 			//	what a pain.  We hate having to deal with async loading issues.
-			dojo.addOnLoad(function(){
-				console.log("Getting the Quicktime version...");
-				var r=dojo.byId("results"),
+		require(["dojo/dom", "dojo/_base/connect", "dojox/embed/Quicktime", "dojo/domReady!"], 
+			function(dom, listen, QT){
+				var r=dom.byId("results"),
 					fn=function(){
-						var v=dojox.embed.Quicktime.version || { major: 0, minor: 0, rev: 0 };
+						var v=QT.version || { major: 0, minor: 0, rev: 0 };
 						r.innerHTML = v.major
 							+ '.' + v.minor
 							+ '.' + v.rev;
 					};
-				if(!dojox.embed.Quicktime.available){
+				if(!QT.available){
 					r.innerHTML = "QuickTime plugin not installed";
-				}else if(!dojox.embed.Quicktime.supported){
+				}else if(!QT.supported){
 					r.innerHTML = "QuickTime not supported";
-				}else if(dojox.embed.Quicktime.initialized){
+				}else if(QT.initialized){
 					fn();
 				}else{
 					console.log("dojox.embed.Quicktime not initialized yet... waiting");
-					var h=dojo.connect(dojox.embed.Quicktime, "onInitialize", function(){
+					var h=listen.connect(QT, "onInitialize", function(){
 						fn();
-						dojo.disconnect(h);
+						listen.disconnect(h);
 					});
 				}
 			});
diff --git a/dojox/embed/tests/resources/sample.3gp b/dojox/embed/tests/resources/sample.3gp
new file mode 100644
index 0000000..4a3d8ea
Binary files /dev/null and b/dojox/embed/tests/resources/sample.3gp differ
diff --git a/dojox/encoding/ascii85.js b/dojox/encoding/ascii85.js
index 4594cde..ae53662 100644
--- a/dojox/encoding/ascii85.js
+++ b/dojox/encoding/ascii85.js
@@ -1,9 +1,6 @@
 define(["dojo/_base/lang"], function(lang) {
 
 	var ascii85 = lang.getObject("dojox.encoding.ascii85", true);
-	/*=====
-		ascii85 = dojox.encoding.ascii85;
-	=====*/
 
 	var c = function(input, length, result){
 		var i, j, n, b = [0, 0, 0, 0, 0];
@@ -19,8 +16,10 @@ define(["dojo/_base/lang"], function(lang) {
 	};
 
 	ascii85.encode = function(input){
-		// summary: encodes input data in ascii85 string
-		// input: Array: an array of numbers (0-255) to encode
+		// summary:
+		//		encodes input data in ascii85 string
+		// input: Array
+		//		an array of numbers (0-255) to encode
 		var result = [], reminder = input.length % 4, length = input.length - reminder;
 		c(input, length, result);
 		if(reminder){
@@ -35,8 +34,10 @@ define(["dojo/_base/lang"], function(lang) {
 	};
 
 	ascii85.decode = function(input){
-		// summary: decodes the input string back to array of numbers
-		// input: String: the input string to decode
+		// summary:
+		//		decodes the input string back to array of numbers
+		// input: String
+		//		the input string to decode
 		var n = input.length, r = [], b = [0, 0, 0, 0, 0], i, j, t, x, y, d;
 		for(i = 0; i < n; ++i){
 			if(input.charAt(i) == "z"){
diff --git a/dojox/encoding/base64.js b/dojox/encoding/base64.js
index ddf0e2a..e63dd27 100644
--- a/dojox/encoding/base64.js
+++ b/dojox/encoding/base64.js
@@ -1,16 +1,13 @@
 define(["dojo/_base/lang"], function(lang) {
 	
 	var base64 = lang.getObject("dojox.encoding.base64", true);
-	/*=====
-		base64 = dojox.encoding.base64;
-	=====*/
 
 	var p="=";
 	var tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
 	base64.encode=function(/* byte[] */ba){
-		//	summary
-		//	Encode an array of bytes as a base64-encoded string
+		// summary:
+		//		Encode an array of bytes as a base64-encoded string
 		var s=[], l=ba.length;
 		var rm=l%3;
 		var x=l-rm;
@@ -44,8 +41,8 @@ define(["dojo/_base/lang"], function(lang) {
 	};
 
 	base64.decode=function(/* string */str){
-		//	summary
-		//	Convert a base64-encoded string to an array of bytes
+		// summary:
+		//		Convert a base64-encoded string to an array of bytes
 		var s=str.split(""), out=[];
 		var l=s.length;
 		while(s[--l]==p){ }	//	strip off trailing padding
diff --git a/dojox/encoding/bits.js b/dojox/encoding/bits.js
index e5df2e0..3d49b9a 100644
--- a/dojox/encoding/bits.js
+++ b/dojox/encoding/bits.js
@@ -2,9 +2,6 @@ define([
 	"dojo/_base/lang"	// dojo.extend
 ], function(lang) {
 	var bits = lang.getObject("dojox.encoding.bits", true);
-	/*=====
-		bits = dojox.encoding.bits;
-	=====*/
 
 	bits.OutputStream = function(){
 		this.reset();
diff --git a/dojox/encoding/compression/lzw.js b/dojox/encoding/compression/lzw.js
index 374f6b9..301eee3 100644
--- a/dojox/encoding/compression/lzw.js
+++ b/dojox/encoding/compression/lzw.js
@@ -4,9 +4,6 @@ define([
 ], function(lang, bits) {
 
 	var lzw = lang.getObject("dojox.encoding.compression.lzw", true);
-	/*=====
-		lzw = dojox.encoding.compression.lzw;
-	=====*/
 
 	var _bits = function(x){
 		var w = 1;
diff --git a/dojox/encoding/compression/splay.js b/dojox/encoding/compression/splay.js
index f59140f..8c25aac 100644
--- a/dojox/encoding/compression/splay.js
+++ b/dojox/encoding/compression/splay.js
@@ -3,9 +3,6 @@ define([
 	"../bits"
 ], function(lang, bits) {
 	var compression = lang.getObject("dojox.encoding.compression", true);
-	/*=====
-		compression = dojox.encoding.compression;
-	=====*/
 
 	compression.Splay = function(n){
 		this.up = new Array(2 * n + 1);
diff --git a/dojox/encoding/crypto/Blowfish.js b/dojox/encoding/crypto/Blowfish.js
index 2af5986..216136b 100644
--- a/dojox/encoding/crypto/Blowfish.js
+++ b/dojox/encoding/crypto/Blowfish.js
@@ -4,9 +4,6 @@ define([
 	"../base64",
 	"./_base"
 ], function(lang, arrayUtil, base64, crypto){
-	/*=====
-		crypto = dojox.encoding.crypto;
-	=====*/
 
 /*	Blowfish
  *	Created based on the C# implementation by Marcus Hahn (http://www.hotpixel.net/)
@@ -14,8 +11,8 @@ define([
  *	2005-12-08
  */
 crypto.Blowfish = new function(){
-	//	summary
-	//	Object for doing Blowfish encryption/decryption.
+	// summary:
+	//		Object for doing Blowfish encryption/decryption.
 	var POW2=Math.pow(2,2);
 	var POW3=Math.pow(2,3);
 	var POW4=Math.pow(2,4);
@@ -277,8 +274,8 @@ crypto.Blowfish = new function(){
 //	PUBLIC FUNCTIONS
 ////////////////////////////////////////////////////////////////////////////
 	this.getIV=function(/* dojox.encoding.crypto.outputTypes? */ outputType){
-		//	summary
-		//	returns the initialization vector in the output format specified by outputType
+		// summary:
+		//		returns the initialization vector in the output format specified by outputType
 		var out=outputType||crypto.outputTypes.Base64;
 		switch(out){
 			case crypto.outputTypes.Hex:{
@@ -299,8 +296,8 @@ crypto.Blowfish = new function(){
 	};
 
 	this.setIV=function(/* string */data, /* dojox.encoding.crypto.outputTypes? */inputType){
-		//	summary
-		//	sets the initialization vector to data (as interpreted as inputType)
+		// summary:
+		//		sets the initialization vector to data (as interpreted as inputType)
 		var ip=inputType||crypto.outputTypes.Base64;
 		var ba=null;
 		switch(ip){
@@ -333,8 +330,8 @@ crypto.Blowfish = new function(){
 	};
 
 	this.encrypt = function(/* string */plaintext, /* string */key, /* object? */ao){
-		//	summary
-		//	encrypts plaintext using key; allows user to specify output type and cipher mode via keyword object "ao"
+		// summary:
+		//		encrypts plaintext using key; allows user to specify output type and cipher mode via keyword object "ao"
 		var out=crypto.outputTypes.Base64;
 		var mode=crypto.cipherModes.ECB;
 		if (ao){
@@ -399,8 +396,8 @@ crypto.Blowfish = new function(){
 	};
 
 	this.decrypt = function(/* string */ciphertext, /* string */key, /* object? */ao){
-		//	summary
-		//	decrypts ciphertext using key; allows specification of how ciphertext is encoded via ao.
+		// summary:
+		//		decrypts ciphertext using key; allows specification of how ciphertext is encoded via ao.
 		var ip=crypto.outputTypes.Base64;
 		var mode=crypto.cipherModes.ECB;
 		if (ao){
diff --git a/dojox/encoding/crypto/RSAKey-ext.js b/dojox/encoding/crypto/RSAKey-ext.js
index b029d91..f13220d 100644
--- a/dojox/encoding/crypto/RSAKey-ext.js
+++ b/dojox/encoding/crypto/RSAKey-ext.js
@@ -29,7 +29,7 @@ define([
 	lang.extend(RSAKey, {
 		setPrivate: function(N, E, D){
 			// summary:
-			//	Set the private key fields N, e, d and CRT params from hex strings
+			//		Set the private key fields N, e, d and CRT params from hex strings
 			if(N && E && N.length && E.length){
 				this.n = new BigInteger(N, 16);
 				this.e = parseInt(E, 16);
@@ -40,7 +40,7 @@ define([
 		},
 		setPrivateEx: function(N, E, D, P, Q, DP, DQ, C) {
 			// summary:
-			//	Set the private key fields N, e, d and CRT params from hex strings
+			//		Set the private key fields N, e, d and CRT params from hex strings
 			if(N && E && N.length && E.length){
 				this.n = new BigInteger(N, 16);
 				this.e = parseInt(E, 16);
@@ -56,7 +56,7 @@ define([
 		},
 		generate: function(B, E){
 			// summary:
-			//	Generate a new random private key B bits long, using public expt E
+			//		Generate a new random private key B bits long, using public expt E
 			var rng = this.rngf(), qs = B >> 1;
 			this.e = parseInt(E, 16);
 			var ee = new BigInteger(E, 16);
@@ -95,10 +95,11 @@ define([
 
 		decrypt: function(ctext){
 			// summary:
-			//	Return the PKCS#1 RSA decryption of "ctext".
-			// ctext: String:
-			//	an even-length hex string
-			// returns: a plain string.
+			//		Return the PKCS#1 RSA decryption of "ctext".
+			// ctext: String
+			//		an even-length hex string
+			// returns:
+			//		a plain string.
 			var c = new BigInteger(ctext, 16), m;
 			if(!this.p || !this.q){
 				m = c.modPow(this.d, this.n);
diff --git a/dojox/encoding/crypto/RSAKey.js b/dojox/encoding/crypto/RSAKey.js
index 2bf5459..a31ff76 100644
--- a/dojox/encoding/crypto/RSAKey.js
+++ b/dojox/encoding/crypto/RSAKey.js
@@ -38,10 +38,10 @@ define([
 	return declare("dojox.encoding.crypto.RSAKey", null, {
 		constructor: function(rngf){
 			// summary:
-			//	"empty" RSA key constructor
-			// rndf: Function?:
-			//	function that returns an instance of a random number generator
-			//	(see dojox.math.random for details)
+			//		"empty" RSA key constructor
+			// rndf: Function?
+			//		function that returns an instance of a random number generator
+			//		(see dojox.math.random for details)
 			this.rngf = rngf || defaultRngf;
 			this.e = 0;
 			this.n = this.d = this.p = this.q = this.dmp1 = this.dmq1 = this.coeff = null;
@@ -49,7 +49,7 @@ define([
 
 		setPublic: function(N, E){
 			// summary:
-			//	Set the public key fields N and e from hex strings
+			//		Set the public key fields N and e from hex strings
 			if(N && E && N.length && E.length) {
 				this.n = new BigInteger(N, 16);
 				this.e = parseInt(E, 16);
diff --git a/dojox/encoding/crypto/SimpleAES.js b/dojox/encoding/crypto/SimpleAES.js
index 35ce3e1..5a0f386 100644
--- a/dojox/encoding/crypto/SimpleAES.js
+++ b/dojox/encoding/crypto/SimpleAES.js
@@ -1,11 +1,7 @@
 define(["../base64", "./_base"], 
  function(base64, crypto){
 
-	/*=====
-		crypto = dojox.encoding.crypto;
-	=====*/
-
-	// Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [��5.1.1]
+	// Sbox is pre-computed multiplicative inverse in GF(2^8) used in SubBytes and KeyExpansion [5.1.1]
 	var Sbox =	[0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,
 				 0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,
 				 0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,
@@ -23,7 +19,7 @@ define(["../base64", "./_base"],
 				 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
 				 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16];
 
-	// Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [��5.2]
+	// Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [5.2]
 	var Rcon = [ [0x00, 0x00, 0x00, 0x00],
 				 [0x01, 0x00, 0x00, 0x00],
 				 [0x02, 0x00, 0x00, 0x00],
@@ -46,11 +42,11 @@ define(["../base64", "./_base"],
 	 *
 	 *	 returns byte-array encrypted value (16 bytes)
 	 */
-	function Cipher(input, w) {	   // main Cipher function [��5.1]
+	function Cipher(input, w) {	   // main Cipher function [��5.1]
 	  var Nb = 4;				// block size (in words): no of columns in state (fixed at 4 for AES)
 	  var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys
 
-	  var state = [[],[],[],[]];  // initialise 4xNb byte-array 'state' with input [��3.4]
+	  var state = [[],[],[],[]];  // initialise 4xNb byte-array 'state' with input [3.4]
 	  for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];
 
 	  state = AddRoundKey(state, w, 0, Nb);
@@ -66,13 +62,13 @@ define(["../base64", "./_base"],
 	  state = ShiftRows(state, Nb);
 	  state = AddRoundKey(state, w, Nr, Nb);
 
-	  var output = new Array(4*Nb);	 // convert state to 1-d array before returning [��3.4]
+	  var output = new Array(4*Nb);	 // convert state to 1-d array before returning [3.4]
 	  for (var i=0; i<4*Nb; i++) output[i] = state[i%4][Math.floor(i/4)];
 	  return output;
 	}
 
 
-	function SubBytes(s, Nb) {	  // apply SBox to state S [��5.1.1]
+	function SubBytes(s, Nb) {	  // apply SBox to state S [5.1.1]
 	  for (var r=0; r<4; r++) {
 		for (var c=0; c<Nb; c++) s[r][c] = Sbox[s[r][c]];
 	  }
@@ -80,7 +76,7 @@ define(["../base64", "./_base"],
 	}
 
 
-	function ShiftRows(s, Nb) {	   // shift row r of state S left by r bytes [��5.1.2]
+	function ShiftRows(s, Nb) {	   // shift row r of state S left by r bytes [5.1.2]
 	  var t = new Array(4);
 	  for (var r=1; r<4; r++) {
 		for (var c=0; c<4; c++) t[c] = s[r][(c+r)%Nb];	// shift into temp copy
@@ -90,15 +86,15 @@ define(["../base64", "./_base"],
 	}
 
 
-	function MixColumns(s, Nb) {   // combine bytes of each col of state S [��5.1.3]
+	function MixColumns(s, Nb) {   // combine bytes of each col of state S [5.1.3]
 	  for (var c=0; c<4; c++) {
 		var a = new Array(4);  // 'a' is a copy of the current column from 's'
-		var b = new Array(4);  // 'b' is a�ށ{02} in GF(2^8)
+		var b = new Array(4);  // 'b' is a�ށ{02} in GF(2^8)
 		for (var i=0; i<4; i++) {
 		  a[i] = s[i][c];
 		  b[i] = s[i][c]&0x80 ? s[i][c]<<1 ^ 0x011b : s[i][c]<<1;
 		}
-		// a[n] ^ b[n] is a�ށ{03} in GF(2^8)
+		// a[n] ^ b[n] is a�ށ{03} in GF(2^8)
 		s[0][c] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; // 2*a0 + 3*a1 + a2 + a3
 		s[1][c] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; // a0 * 2*a1 + 3*a2 + a3
 		s[2][c] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; // a0 + a1 + 2*a2 + 3*a3
@@ -108,7 +104,7 @@ define(["../base64", "./_base"],
 	}
 
 
-	function AddRoundKey(state, w, rnd, Nb) {  // xor Round Key into state S [��5.1.4]
+	function AddRoundKey(state, w, rnd, Nb) {  // xor Round Key into state S [5.1.4]
 	  for (var r=0; r<4; r++) {
 		for (var c=0; c<Nb; c++) state[r][c] ^= w[rnd*4+c][r];
 	  }
@@ -116,7 +112,7 @@ define(["../base64", "./_base"],
 	}
 
 
-	function KeyExpansion(key) {  // generate Key Schedule (byte-array Nr+1 x Nb) from Key [��5.2]
+	function KeyExpansion(key) {  // generate Key Schedule (byte-array Nr+1 x Nb) from Key [5.2]
 	  var Nb = 4;			 // block size (in words): no of columns in state (fixed at 4 for AES)
 	  var Nk = key.length/4	 // key length (in words): 4/6/8 for 128/192/256-bit keys
 	  var Nr = Nk + 6;		 // no of rounds: 10/12/14 for 128/192/256-bit keys
@@ -177,7 +173,7 @@ define(["../base64", "./_base"],
 
 	  key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long
 
-	  // initialise counter block (NIST SP800-38A ��B.2): millisecond time-stamp for nonce in 1st 8 bytes,
+	  // initialise counter block (NIST SP800-38A B.2): millisecond time-stamp for nonce in 1st 8 bytes,
 	  // block counter in 2nd 8 bytes
 	  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
 	  var counterBlock = new Array(blockSize);	// block size fixed at 16 bytes / 128 bits (Nb=4) for AES
@@ -301,33 +297,33 @@ define(["../base64", "./_base"],
 
 	crypto.SimpleAES = new (function(){
 		// summary:
-		// 		SimpleAES, ported from dojox.sql, and done without the need for
-		// 		a Google Gears worker pool.
+		//		SimpleAES, ported from dojox.sql, and done without the need for
+		//		a Google Gears worker pool.
 		// description:
 		//		Taken from http://www.movable-type.co.uk/scripts/aes.html by
-		// 		Chris Veness (CLA signed); adapted for Dojo by Brad Neuberg
-		// 		(bkn3 AT columbia.edu) and moved to DojoX crypto by Tom Trenka
-		// 		(ttrenka AT gmail.com).
+		//		Chris Veness (CLA signed); adapted for Dojo by Brad Neuberg
+		//		(bkn3 AT columbia.edu) and moved to DojoX crypto by Tom Trenka
+		//		(ttrenka AT gmail.com).
 		//
-		// 		A few notes:
-		// 		1) This algorithm uses a customized version of CBC mode by creating
-		// 		a nonce, using it as an initialization vector, and storing the
-		// 		IV as the first portion of the encrypted text.  Because of this, it
-		// 		is HIGHLY PROBABLE that it will NOT be usable by other AES implementations.
-		// 		2) All encoding is done in hex format; other encoding formats (such
-		// 		as base 64) are not supported.
-		// 		3) The bit depth of the key is hardcoded at 256, despite the ability
-		// 		of the code to handle all three recommended bit depths.
-		// 		4) The passed key will be padded (as opposed to enforcing a strict
-		// 		length) with null bytes.
+		//		A few notes:
+		//		1) This algorithm uses a customized version of CBC mode by creating
+		//		a nonce, using it as an initialization vector, and storing the
+		//		IV as the first portion of the encrypted text.  Because of this, it
+		//		is HIGHLY PROBABLE that it will NOT be usable by other AES implementations.
+		//		2) All encoding is done in hex format; other encoding formats (such
+		//		as base 64) are not supported.
+		//		3) The bit depth of the key is hardcoded at 256, despite the ability
+		//		of the code to handle all three recommended bit depths.
+		//		4) The passed key will be padded (as opposed to enforcing a strict
+		//		length) with null bytes.
 		this.encrypt = function(/* String */plaintext, /* String */key){
-			//	summary:
+			// summary:
 			//		Encrypt the passed plaintext using the key, with a
 			//		hardcoded bit depth of 256.
 			return AESEncryptCtr(plaintext, key, 256);	//	String
 		};
 		this.decrypt = function(/* String */ciphertext, /* String */key){
-			//	summary:
+			// summary:
 			//		Decrypt the passed ciphertext using the key at a fixed
 			//		bit depth of 256.
 			return AESDecryptCtr(ciphertext, key, 256);	//	String
diff --git a/dojox/encoding/crypto/_base.js b/dojox/encoding/crypto/_base.js
index af557a7..1b2535f 100644
--- a/dojox/encoding/crypto/_base.js
+++ b/dojox/encoding/crypto/_base.js
@@ -1,18 +1,15 @@
 define(["dojo/_base/lang"], function(lang) {
 	
 	var c = lang.getObject("dojox.encoding.crypto", true);
-	/*=====
-		c = dojox.encoding.crypto;
-	=====*/
 
 	c.cipherModes = {
 		// summary:
-		//	Enumeration for various cipher modes.
+		//		Enumeration for various cipher modes.
 		ECB:0, CBC:1, PCBC:2, CFB:3, OFB:4, CTR:5
 	};
 	c.outputTypes = {
 		// summary:
-		//	Enumeration for input and output encodings.
+		//		Enumeration for input and output encodings.
 		Base64:0, Hex:1, String:2, Raw:3
 	};
 	
diff --git a/dojox/encoding/digests/MD5.js b/dojox/encoding/digests/MD5.js
index 30ca232..a3aab46 100644
--- a/dojox/encoding/digests/MD5.js
+++ b/dojox/encoding/digests/MD5.js
@@ -1,8 +1,4 @@
-define(["./_base"], function(dxd) {
-
-	/*=====
-		dxd = dojox.encoding.digests;
-	=====*/
+define(["./_base"], function(base) {
 
 /*	A port of Paul Johnstone's MD5 implementation
  *	http://pajhome.org.uk/crypt/md5/index.html
@@ -18,7 +14,7 @@ define(["./_base"], function(dxd) {
 
 	//	MD5 rounds functions
 	function R(n,c){ return (n<<c)|(n>>>(32-c)); }
-	function C(q,a,b,x,s,t){ return dxd.addWords(R(dxd.addWords(dxd.addWords(a, q), dxd.addWords(x, t)), s), b); }
+	function C(q,a,b,x,s,t){ return base.addWords(R(base.addWords(base.addWords(a, q), base.addWords(x, t)), s), b); }
 	function FF(a,b,c,d,x,s,t){ return C((b&c)|((~b)&d),a,b,x,s,t); }
 	function GG(a,b,c,d,x,s,t){ return C((b&d)|(c&(~d)),a,b,x,s,t); }
 	function HH(a,b,c,d,x,s,t){ return C(b^c^d,a,b,x,s,t); }
@@ -106,16 +102,16 @@ define(["./_base"], function(dxd) {
 			c=II(c,d,a,b,x[i+ 2],15, 718787259);
 			b=II(b,c,d,a,x[i+ 9],21,-343485551);
 
-			a=dxd.addWords(a, olda);
-			b=dxd.addWords(b, oldb);
-			c=dxd.addWords(c, oldc);
-			d=dxd.addWords(d, oldd);
+			a=base.addWords(a, olda);
+			b=base.addWords(b, oldb);
+			c=base.addWords(c, oldc);
+			d=base.addWords(d, oldd);
 		}
 		return [a,b,c,d];
 	}
 
 	function hmac(data, key){
-		var wa=dxd.stringToWord(key);
+		var wa=base.stringToWord(key);
 		if(wa.length>16){
 			wa=core(wa, key.length*chrsz);
 		}
@@ -124,53 +120,53 @@ define(["./_base"], function(dxd) {
 			l[i]=wa[i]^0x36363636;
 			r[i]=wa[i]^0x5c5c5c5c;
 		}
-		var h=core(l.concat(dxd.stringToWord(data)), 512+data.length*chrsz);
+		var h=core(l.concat(base.stringToWord(data)), 512+data.length*chrsz);
 		return core(r.concat(h), 640);
 	}
 
 	//	public function
-	dxd.MD5=function(/* string */data, /* dojox.encoding.digests.outputTypes? */outputType){
-		//	summary
-		//	computes the digest of data, and returns the result according to type outputType
-		var out=outputType || dxd.outputTypes.Base64;
-		var wa=core(dxd.stringToWord(data), data.length*chrsz);
+	var MD5=function(/* string */data, /* dojox.encoding.digests.outputTypes? */outputType){
+		// summary:
+		//		computes the digest of data, and returns the result according to type outputType
+		var out=outputType || base.outputTypes.Base64;
+		var wa=core(base.stringToWord(data), data.length*chrsz);
 		switch(out){
-			case dxd.outputTypes.Raw:{
+			case base.outputTypes.Raw:{
 				return wa;	//	word[]
 			}
-			case dxd.outputTypes.Hex:{
-				return dxd.wordToHex(wa);	//	string
+			case base.outputTypes.Hex:{
+				return base.wordToHex(wa);	//	string
 			}
-			case dxd.outputTypes.String:{
-				return dxd.wordToString(wa);	//	string
+			case base.outputTypes.String:{
+				return base.wordToString(wa);	//	string
 			}
 			default:{
-				return dxd.wordToBase64(wa);	//	string
+				return base.wordToBase64(wa);	//	string
 			}
 		}
 	};
 
 	//	make this private, for later use with a generic HMAC calculator.
-	dxd.MD5._hmac=function(/* string */data, /* string */key, /* dojox.encoding.digests.outputTypes? */outputType){
-		//	summary
-		//	computes the digest of data, and returns the result according to type outputType
-		var out=outputType || dxd.outputTypes.Base64;
+	MD5._hmac=function(/* string */data, /* string */key, /* dojox.encoding.digests.outputTypes? */outputType){
+		// summary:
+		//		computes the digest of data, and returns the result according to type outputType
+		var out=outputType || base.outputTypes.Base64;
 		var wa=hmac(data, key);
 		switch(out){
-			case dxd.outputTypes.Raw:{
+			case base.outputTypes.Raw:{
 				return wa;	//	word[]
 			}
-			case dxd.outputTypes.Hex:{
-				return dxd.wordToHex(wa);	//	string
+			case base.outputTypes.Hex:{
+				return base.wordToHex(wa);	//	string
 			}
-			case dxd.outputTypes.String:{
-				return dxd.wordToString(wa);	//	string
+			case base.outputTypes.String:{
+				return base.wordToString(wa);	//	string
 			}
 			default:{
-				return dxd.wordToBase64(wa);	//	string
+				return base.wordToBase64(wa);	//	string
 			}
 		}
 	};
 
-	return dxd.MD5;
+	return MD5;
 });
diff --git a/dojox/encoding/digests/SHA1.js b/dojox/encoding/digests/SHA1.js
index fa18d8a..483c1c8 100644
--- a/dojox/encoding/digests/SHA1.js
+++ b/dojox/encoding/digests/SHA1.js
@@ -1,9 +1,4 @@
-define(["./_base"], function(dxd) {
-
-	/*=====
-		dxd = dojox.encoding.digests;
-	=====*/
-
+define(["./_base"], function(base){
 /*
  * A port of Paul Johnstone's SHA1 implementation
  *
@@ -37,14 +32,14 @@ define(["./_base"], function(dxd) {
 			for(var j=0;j<80;j++){
 				if(j<16){ w[j]=x[i+j]; }
 				else { w[j]=R(w[j-3]^w[j-8]^w[j-14]^w[j-16],1); }
-				var t = dxd.addWords(dxd.addWords(R(a,5),FT(j,b,c,d)),dxd.addWords(dxd.addWords(e,w[j]),KT(j)));
+				var t = base.addWords(base.addWords(R(a,5),FT(j,b,c,d)),base.addWords(base.addWords(e,w[j]),KT(j)));
 				e=d; d=c; c=R(b,30); b=a; a=t;
 			}
-			a=dxd.addWords(a,olda);
-			b=dxd.addWords(b,oldb);
-			c=dxd.addWords(c,oldc);
-			d=dxd.addWords(d,oldd);
-			e=dxd.addWords(e,olde);
+			a=base.addWords(a,olda);
+			b=base.addWords(b,oldb);
+			c=base.addWords(c,oldc);
+			d=base.addWords(d,oldd);
+			e=base.addWords(e,olde);
 		}
 		return [a, b, c, d, e];
 	}
@@ -89,7 +84,7 @@ define(["./_base"], function(dxd) {
 	}
 
 	function toBase64(/* word[] */wa){
-		//	summary:
+		// summary:
 		//		convert an array of words to base64 encoding, should be more efficient
 		//		than using dojox.encoding.base64
 		var p="=", tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", s=[];
@@ -107,19 +102,19 @@ define(["./_base"], function(dxd) {
 	};
 
 	//	public function
-	dxd.SHA1=function(/* String */data, /* dojox.encoding.digests.outputTypes? */outputType){
-		//	summary:
+	var SHA1=function(/* String */data, /* dojox.encoding.digests.outputTypes? */outputType){
+		// summary:
 		//		Computes the SHA1 digest of the data, and returns the result according to output type.
-		var out=outputType||dxd.outputTypes.Base64;
+		var out=outputType||base.outputTypes.Base64;
 		var wa=core(toWord(data), data.length*chrsz);
 		switch(out){
-			case dxd.outputTypes.Raw:{
+			case base.outputTypes.Raw:{
 				return wa;	//	word[]
 			}
-			case dxd.outputTypes.Hex:{
+			case base.outputTypes.Hex:{
 				return toHex(wa);	//	string
 			}
-			case dxd.outputTypes.String:{
+			case base.outputTypes.String:{
 				return _toString(wa);	//	string
 			}
 			default:{
@@ -129,19 +124,19 @@ define(["./_base"], function(dxd) {
 	}
 
 	//	make this private, for later use with a generic HMAC calculator.
-	dxd.SHA1._hmac=function(/* string */data, /* string */key, /* dojox.encoding.digests.outputTypes? */outputType){
-		//	summary:
+	SHA1._hmac=function(/* string */data, /* string */key, /* dojox.encoding.digests.outputTypes? */outputType){
+		// summary:
 		//		computes the digest of data, and returns the result according to type outputType
-		var out=outputType || dxd.outputTypes.Base64;
+		var out=outputType || base.outputTypes.Base64;
 		var wa=hmac(data, key);
 		switch(out){
-			case dxd.outputTypes.Raw:{
+			case base.outputTypes.Raw:{
 				return wa;	//	word[]
 			}
-			case dxd.outputTypes.Hex:{
+			case base.outputTypes.Hex:{
 				return toHex(wa);	//	string
 			}
-			case dxd.outputTypes.String:{
+			case base.outputTypes.String:{
 				return _toString(wa);	//	string
 			}
 			default:{
@@ -150,5 +145,5 @@ define(["./_base"], function(dxd) {
 		}
 	};
 
-	return dxd.SHA1;
+	return SHA1;
 });
diff --git a/dojox/encoding/digests/SHA224.js b/dojox/encoding/digests/SHA224.js
new file mode 100644
index 0000000..34cfe2c
--- /dev/null
+++ b/dojox/encoding/digests/SHA224.js
@@ -0,0 +1,68 @@
+define(["./_sha-32"], function(sha32){
+	//	The 224-bit implementation of SHA-2
+	var hash = [
+		0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+		0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
+	];
+
+	var SHA224 = function(/* String */data, /* sha32.outputTypes? */outputType){
+		var out = outputType || sha32.outputTypes.Base64;
+		data = sha32.stringToUtf8(data);
+		var wa = sha32.digest(sha32.toWord(data), data.length * 8, hash, 224);
+		switch(out){
+			case sha32.outputTypes.Raw: {
+				return wa;
+			}
+			case sha32.outputTypes.Hex: {
+				return sha32.toHex(wa);
+			}
+			case sha32.outputTypes.String: {
+				return sha32._toString(wa);
+			}
+			default: {
+				return sha32.toBase64(wa);
+			}
+		}
+	};
+
+	SHA224._hmac = function(/* String */data, /* String */key, /* sha32.outputTypes? */outputType){
+		var out = outputType || sha32.outputTypes.Base64;
+		data = sha32.stringToUtf8(data);
+		key = sha32.stringToUtf8(key);
+
+		//	prepare the key
+		var wa = sha32.toWord(key);
+		if(wa.length > 16){
+			wa = sha32.digest(wa, key.length * 8, hash, 224);
+		}
+
+		//	set up the pads
+		var ipad = new Array(16), opad = new Array(16);
+		for(var i=0; i<16; i++){
+			ipad[i] = wa[i] ^ 0x36363636;
+			opad[i] = wa[i] ^ 0x5c5c5c5c;
+		}
+
+		//	make the final digest
+		var r1 = sha32.digest(ipad.concat(sha32.toWord(data)), 512 + data.length * 8, hash, 224);
+		var r2 = sha32.digest(opad.concat(r1), 512 + 160, hash, 224);
+
+		//	return the output.
+		switch(out){
+			case sha32.outputTypes.Raw: {
+				return wa;
+			}
+			case sha32.outputTypes.Hex: {
+				return sha32.toHex(wa);
+			}
+			case sha32.outputTypes.String: {
+				return sha32._toString(wa);
+			}
+			default: {
+				return sha32.toBase64(wa);
+			}
+		}
+	};
+
+	return SHA224;
+});
diff --git a/dojox/encoding/digests/SHA256.js b/dojox/encoding/digests/SHA256.js
new file mode 100644
index 0000000..0622b02
--- /dev/null
+++ b/dojox/encoding/digests/SHA256.js
@@ -0,0 +1,68 @@
+define(["./_sha-32"], function(sha32){
+	//	The 256-bit implementation of SHA-2
+	var hash = [
+		0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+		0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
+	];
+
+	var SHA256 = function(/* String */data, /* sha32.outputTypes? */outputType){
+		var out = outputType || sha32.outputTypes.Base64;
+		data = sha32.stringToUtf8(data);
+		var wa = sha32.digest(sha32.toWord(data), data.length * 8, hash, 256);
+		switch(out){
+			case sha32.outputTypes.Raw: {
+				return wa;
+			}
+			case sha32.outputTypes.Hex: {
+				return sha32.toHex(wa);
+			}
+			case sha32.outputTypes.String: {
+				return sha32._toString(wa);
+			}
+			default: {
+				return sha32.toBase64(wa);
+			}
+		}
+	};
+
+	SHA256._hmac = function(/* String */data, /* String */key, /* sha32.outputTypes? */outputType){
+		var out = outputType || sha32.outputTypes.Base64;
+		data = sha32.stringToUtf8(data);
+		key = sha32.stringToUtf8(key);
+
+		//	prepare the key
+		var wa = sha32.toWord(key);
+		if(wa.length > 16){
+			wa = sha32.digest(wa, key.length * 8, hash, 256);
+		}
+
+		//	set up the pads
+		var ipad = new Array(16), opad = new Array(16);
+		for(var i=0; i<16; i++){
+			ipad[i] = wa[i] ^ 0x36363636;
+			opad[i] = wa[i] ^ 0x5c5c5c5c;
+		}
+
+		//	make the final digest
+		var r1 = sha32.digest(ipad.concat(sha32.toWord(data)), 512 + data.length * 8, hash, 256);
+		var r2 = sha32.digest(opad.concat(r1), 512 + 160, hash, 256);
+
+		//	return the output.
+		switch(out){
+			case sha32.outputTypes.Raw: {
+				return wa;
+			}
+			case sha32.outputTypes.Hex: {
+				return sha32.toHex(wa);
+			}
+			case sha32.outputTypes.String: {
+				return sha32._toString(wa);
+			}
+			default: {
+				return sha32.toBase64(wa);
+			}
+		}
+	};
+
+	return SHA256;
+});
diff --git a/dojox/encoding/digests/SHA384.js b/dojox/encoding/digests/SHA384.js
new file mode 100644
index 0000000..fa50acd
--- /dev/null
+++ b/dojox/encoding/digests/SHA384.js
@@ -0,0 +1,71 @@
+define(["./_sha-64"], function(sha64){
+	//	The 384-bit implementation of SHA-2
+	
+	//	Note that for 64-bit hashes, we're actually doing high-order, low-order, high-order, low-order.
+	//	The 64-bit functions will assemble them into actual 64-bit "words".
+	var hash = [
+		0xcbbb9d5d, 0xc1059ed8, 0x629a292a, 0x367cd507, 0x9159015a, 0x3070dd17, 0x152fecd8, 0xf70e5939,
+		0x67332667, 0xffc00b31, 0x8eb44a87, 0x68581511, 0xdb0c2e0d, 0x64f98fa7, 0x47b5481d, 0xbefa4fa4
+	];
+
+	//	the exported function
+	var SHA384 = function(/* String */data, /* sha64.outputTypes? */outputType){
+		var out = outputType || sha64.outputTypes.Base64;
+		data = sha64.stringToUtf8(data);
+		var wa = sha64.digest(sha64.toWord(data), data.length * 8, hash, 384);
+		switch(out){
+			case sha64.outputTypes.Raw: {
+				return wa;
+			}
+			case sha64.outputTypes.Hex: {
+				return sha64.toHex(wa);
+			}
+			case sha64.outputTypes.String: {
+				return sha64._toString(wa);
+			}
+			default: {
+				return sha64.toBase64(wa);
+			}
+		}
+	};
+	SHA384._hmac = function(/* string */data, /* string */key, /* sha64.outputTypes? */outputType){
+		var out = outputType || sha64.outputTypes.Base64;
+		data = sha64.stringToUtf8(data);
+		key = sha64.stringToUtf8(key);
+
+		//	prepare the key
+		var wa = sha64.toWord(key);
+		if(wa.length > 16){
+			wa = sha64.digest(wa, key.length * 8, hash, 384);
+		}
+
+		//	set up the pads
+		var ipad = new Array(16), opad = new Array(16);
+		for(var i=0; i<16; i++){
+			ipad[i] = wa[i] ^ 0x36363636;
+			opad[i] = wa[i] ^ 0x5c5c5c5c;
+		}
+
+		//	make the final digest
+		var r1 = sha64.digest(ipad.concat(sha64.toWord(data)), 512 + data.length * 8, hash, 384);
+		var r2 = sha64.digest(opad.concat(r1), 512 + 160, hash, 384);
+
+		//	return the output.
+		switch(out){
+			case sha64.outputTypes.Raw: {
+				return wa;
+			}
+			case sha64.outputTypes.Hex: {
+				return sha64.toHex(wa);
+			}
+			case sha64.outputTypes.String: {
+				return sha64._toString(wa);
+			}
+			default: {
+				return sha64.toBase64(wa);
+			}
+		}
+	};
+
+	return SHA384;
+});
diff --git a/dojox/encoding/digests/SHA512.js b/dojox/encoding/digests/SHA512.js
new file mode 100644
index 0000000..7d57b4f
--- /dev/null
+++ b/dojox/encoding/digests/SHA512.js
@@ -0,0 +1,70 @@
+define(["./_sha-64"], function(sha64){
+	//	The 512-bit implementation of SHA-2
+	
+	//	Note that for 64-bit hashes, we're actually doing high-order, low-order, high-order, low-order.
+	//	The 64-bit functions will assemble them into actual 64-bit "words".
+	var hash = [
+		0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,
+		0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179
+	];
+
+	//	the exported function
+	var SHA512 = function(/* String */data, /* sha64.outputTypes? */outputType){
+		var out = outputType || sha64.outputTypes.Base64;
+		data = sha64.stringToUtf8(data);
+		var wa = sha64.digest(sha64.toWord(data), data.length * 8, hash, 512);
+		switch(out){
+			case sha64.outputTypes.Raw: {
+				return wa;
+			}
+			case sha64.outputTypes.Hex: {
+				return sha64.toHex(wa);
+			}
+			case sha64.outputTypes.String: {
+				return sha64._toString(wa);
+			}
+			default: {
+				return sha64.toBase64(wa);
+			}
+		}
+	};
+	SHA512._hmac = function(/* string */data, /* string */key, /* sha64.outputTypes? */outputType){
+		var out = outputType || sha64.outputTypes.Base64;
+		data = sha64.stringToUtf8(data);
+		key = sha64.stringToUtf8(key);
+
+		//	prepare the key
+		var wa = sha64.toWord(key);
+		if(wa.length > 16){
+			wa = sha64.digest(wa, key.length * 8, hash, 512);
+		}
+
+		//	set up the pads
+		var ipad = new Array(16), opad = new Array(16);
+		for(var i=0; i<16; i++){
+			ipad[i] = wa[i] ^ 0x36363636;
+			opad[i] = wa[i] ^ 0x5c5c5c5c;
+		}
+
+		//	make the final digest
+		var r1 = sha64.digest(ipad.concat(sha64.toWord(data)), 512 + data.length * 8, hash, 512);
+		var r2 = sha64.digest(opad.concat(r1), 512 + 160, hash, 512);
+
+		//	return the output.
+		switch(out){
+			case sha64.outputTypes.Raw: {
+				return wa;
+			}
+			case sha64.outputTypes.Hex: {
+				return sha64.toHex(wa);
+			}
+			case sha64.outputTypes.String: {
+				return sha64._toString(wa);
+			}
+			default: {
+				return sha64.toBase64(wa);
+			}
+		}
+	};
+	return SHA512;
+});
diff --git a/dojox/encoding/digests/_base.js b/dojox/encoding/digests/_base.js
index 1850636..564801f 100644
--- a/dojox/encoding/digests/_base.js
+++ b/dojox/encoding/digests/_base.js
@@ -1,20 +1,16 @@
-define(["dojo/_base/lang"], function(lang){
-	var d = lang.getObject("dojox.encoding.digests", true);
-	/*=====
-		d = dojox.encoding.digests;
-	=====*/
+define([], function(){
+	//	These functions are 32-bit word-based.  See _sha-64 for 64-bit word ops.
+	var base = {};
 
-	//TODO: see if it makes sense to meld this into one with the
-	//	crypto base enums
-	d.outputTypes={
-		//	summary:
+	base.outputTypes={
+		// summary:
 		//		Enumeration for input and output encodings.
 		Base64:0, Hex:1, String:2, Raw:3
 	};
 
 	//	word-based addition
-	d.addWords=function(/* word */a, /* word */b){
-		//	summary:
+	base.addWords=function(/* word */a, /* word */b){
+		// summary:
 		//		add a pair of words together with rollover
 		var l=(a&0xFFFF)+(b&0xFFFF);
 		var m=(a>>16)+(b>>16)+(l>>16);
@@ -27,8 +23,8 @@ define(["dojo/_base/lang"], function(lang){
 	var chrsz=8;	//	16 for Unicode
 	var mask=(1<<chrsz)-1;
 
-	d.stringToWord=function(/* string */s){
-		//	summary:
+	base.stringToWord=function(/* string */s){
+		// summary:
 		//		convert a string to a word array
 		var wa=[];
 		for(var i=0, l=s.length*chrsz; i<l; i+=chrsz){
@@ -37,27 +33,28 @@ define(["dojo/_base/lang"], function(lang){
 		return wa;	//	word[]
 	};
 
-	d.wordToString=function(/* word[] */wa){
-		//	summary:
+	base.wordToString=function(/* word[] */wa){
+		// summary:
 		//		convert an array of words to a string
 		var s=[];
 		for(var i=0, l=wa.length*32; i<l; i+=chrsz){
 			s.push(String.fromCharCode((wa[i>>5]>>>(i%32))&mask));
 		}
 		return s.join("");	//	string
-	}
+	};
 
-	d.wordToHex=function(/* word[] */wa){
-		//	summary:
+	base.wordToHex=function(/* word[] */wa){
+		// summary:
 		//		convert an array of words to a hex tab
 		var h="0123456789abcdef", s=[];
 		for(var i=0, l=wa.length*4; i<l; i++){
 			s.push(h.charAt((wa[i>>2]>>((i%4)*8+4))&0xF)+h.charAt((wa[i>>2]>>((i%4)*8))&0xF));
 		}
 		return s.join("");	//	string
-	}
-	d.wordToBase64=function(/* word[] */wa){
-		//	summary:
+	};
+
+	base.wordToBase64=function(/* word[] */wa){
+		// summary:
 		//		convert an array of words to base64 encoding, should be more efficient
 		//		than using dojox.encoding.base64
 		var p="=", tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", s=[];
@@ -74,5 +71,31 @@ define(["dojo/_base/lang"], function(lang){
 		return s.join("");	//	string
 	};
 
-	return d;
+	//	convert to UTF-8
+	base.stringToUtf8 = function(input){
+		var output = "";
+		var i = -1;
+		var x, y;
+
+		while(++i < input.length){
+			x = input.charCodeAt(i);
+			y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+			if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF){
+				x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+				i++;
+			}
+
+			if(x <= 0x7F)
+				output += String.fromCharCode(x);
+			else if(x <= 0x7FF)
+				output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F), 0x80 | (x & 0x3F));
+			else if(x <= 0xFFFF)
+				output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F));
+			else if(x <= 0x1FFFFF)
+				output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07), 0x80 | ((x >>> 12) & 0x3F), 0x80 | ((x >>> 6) & 0x3F), 0x80 | (x & 0x3F));
+		}
+		return output;
+	};
+
+	return base;
 });
diff --git a/dojox/encoding/digests/_sha-32.js b/dojox/encoding/digests/_sha-32.js
new file mode 100644
index 0000000..ff05e45
--- /dev/null
+++ b/dojox/encoding/digests/_sha-32.js
@@ -0,0 +1,138 @@
+define(["./_base"], function(base){
+	//	basic functions for 32-bit word based SHA-2 processing.
+
+	//	create a new object that uses a delegated base.
+	var o = (function(b){
+		var tmp = function(){};
+		tmp.prototype = b;
+		var ret = new tmp();
+		return ret;
+	})(base);
+
+	//	expose the output type conversion functions
+	o.toWord = function(s){
+		var wa = Array(s.length >> 2);
+		for(var i=0; i<wa.length; i++) wa[i] = 0;
+		for(var i=0; i<s.length*8; i+=8)
+			wa[i>>5] |= (s.charCodeAt(i/8)&0xFF)<<(24-i%32);
+		return wa;
+	};
+
+	o.toHex = function(wa){
+		var h="0123456789abcdef", s=[];
+		for(var i=0, l=wa.length*4; i<l; i++){
+			s.push(h.charAt((wa[i>>2]>>((3-i%4)*8+4))&0xF), h.charAt((wa[i>>2]>>((3-i%4)*8))&0xF));
+		}
+		return s.join("");	//	string
+	};
+
+	o.toBase64 = function(wa){
+		var p="=", tab="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", s=[];
+		for(var i=0, l=wa.length*4; i<l; i+=3){
+			var t=(((wa[i>>2]>>8*(3-i%4))&0xFF)<<16)|(((wa[i+1>>2]>>8*(3-(i+1)%4))&0xFF)<<8)|((wa[i+2>>2]>>8*(3-(i+2)%4))&0xFF);
+			for(var j=0; j<4; j++){
+				if(i*8+j*6>wa.length*32){
+					s.push(p);
+				} else {
+					s.push(tab.charAt((t>>6*(3-j))&0x3F));
+				}
+			}
+		}
+		return s.join("");	//	string
+	};
+
+	o._toString = function(wa){
+		var s = "";
+		for(var i=0; i<wa.length*32; i+=8)
+			s += String.fromCharCode((wa[i>>5]>>>(24-i%32))&0xFF);
+		return s;
+	};
+
+	//	the encoding functions
+	function S (X, n) {return ( X >>> n ) | (X << (32 - n));}
+	function R (X, n) {return ( X >>> n );}
+	function Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
+	function Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
+	function Sigma0256(x) {return (S(x, 2) ^ S(x, 13) ^ S(x, 22));}
+	function Sigma1256(x) {return (S(x, 6) ^ S(x, 11) ^ S(x, 25));}
+	function Gamma0256(x) {return (S(x, 7) ^ S(x, 18) ^ R(x, 3));}
+	function Gamma1256(x) {return (S(x, 17) ^ S(x, 19) ^ R(x, 10));}
+	function Sigma0512(x) {return (S(x, 28) ^ S(x, 34) ^ S(x, 39));}
+	function Sigma1512(x) {return (S(x, 14) ^ S(x, 18) ^ S(x, 41));}
+	function Gamma0512(x) {return (S(x, 1)  ^ S(x, 8) ^ R(x, 7));}
+	function Gamma1512(x) {return (S(x, 19) ^ S(x, 61) ^ R(x, 6));}
+
+	//	math alias
+	var add = base.addWords;
+
+	//	constant K array
+	var K = [
+		0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+		0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+		0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+		0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+		0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+		0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+		0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+		0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+	];
+
+	//	the exposed function, used internally by SHA-224 and SHA-256
+	o.digest = function(msg, length, hash, depth){
+		//	clone the hash
+		hash = hash.slice(0);
+
+		var w = new Array(64);
+		var a, b, c, d, e, f, g, h;
+		var i, j, T1, T2;
+
+		//	append padding
+		msg[length >> 5] |= 0x80 << (24 - length % 32);
+		msg[((length + 64 >> 9) << 4) + 15] = length;
+
+		//	do the digest
+		for(i = 0; i < msg.length; i += 16){
+			a = hash[0];
+			b = hash[1];
+			c = hash[2];
+			d = hash[3];
+			e = hash[4];
+			f = hash[5];
+			g = hash[6];
+			h = hash[7];
+
+			for(j = 0; j < 64; j++) {
+				if (j < 16){
+					w[j] = msg[j + i];
+				} else { 
+					w[j] = add(add(add(Gamma1256(w[j - 2]), w[j - 7]), Gamma0256(w[j - 15])), w[j - 16]);
+				}
+
+				T1 = add(add(add(add(h, Sigma1256(e)), Ch(e, f, g)), K[j]), w[j]);
+				T2 = add(Sigma0256(a), Maj(a, b, c));
+				h = g;
+				g = f;
+				f = e;
+				e = add(d, T1);
+				d = c;
+				c = b;
+				b = a;
+				a = add(T1, T2);
+			}
+
+			hash[0] = add(a, hash[0]);
+			hash[1] = add(b, hash[1]);
+			hash[2] = add(c, hash[2]);
+			hash[3] = add(d, hash[3]);
+			hash[4] = add(e, hash[4]);
+			hash[5] = add(f, hash[5]);
+			hash[6] = add(g, hash[6]);
+			hash[7] = add(h, hash[7]);
+		}
+		if(depth == 224){
+			hash.pop();	//	take off the last word
+		}
+		return hash;
+	}
+	return o;
+});
diff --git a/dojox/encoding/digests/_sha-64.js b/dojox/encoding/digests/_sha-64.js
new file mode 100644
index 0000000..a4303a5
--- /dev/null
+++ b/dojox/encoding/digests/_sha-64.js
@@ -0,0 +1,221 @@
+define(["./_sha-32"], function(sha32){
+	//	basic functions for 64-bit word based SHA-2 processing.  Includes
+	//	a constructor for int64.  Relies on the sha32 base for encoding functions,
+	//	but provides its own, making it easier for the user to not worry about 64-bit
+	//	word handling.
+
+	var int64 = function(h, l){ return { h: h, l: l }; };
+
+	//	64-bit math functions
+	function copy(dst, src){
+		dst.h = src.h;
+		dst.l = src.l;
+	}
+
+	//Right-rotates a 64-bit number by shift
+	function rrot(dst, x, shift){
+		dst.l = (x.l >>> shift) | (x.h << (32-shift));
+		dst.h = (x.h >>> shift) | (x.l << (32-shift));
+	}
+
+	//Reverses the dwords of the source and then rotates right by shift.
+	function revrrot(dst, x, shift){
+		dst.l = (x.h >>> shift) | (x.l << (32-shift));
+		dst.h = (x.l >>> shift) | (x.h << (32-shift));
+	}
+
+	//Bitwise-shifts right a 64-bit number by shift
+	function shr(dst, x, shift){
+		dst.l = (x.l >>> shift) | (x.h << (32-shift));
+		dst.h = (x.h >>> shift);
+	}
+
+	//Adds two 64-bit numbers
+	function add(dst, x, y){
+		var w0 = (x.l & 0xffff) + (y.l & 0xffff);
+		var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
+		var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
+		var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
+		dst.l = (w0 & 0xffff) | (w1 << 16);
+		dst.h = (w2 & 0xffff) | (w3 << 16);
+	}
+
+	//Same, except with 4 addends. Works faster than adding them one by one.
+	function add4(dst, a, b, c, d){
+		var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
+		var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
+		var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
+		var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
+		dst.l = (w0 & 0xffff) | (w1 << 16);
+		dst.h = (w2 & 0xffff) | (w3 << 16);
+	}
+
+	//Same, except with 5 addends
+	function add5(dst, a, b, c, d, e){
+		var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff);
+		var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16);
+		var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16);
+		var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
+		dst.l = (w0 & 0xffff) | (w1 << 16);
+		dst.h = (w2 & 0xffff) | (w3 << 16);
+	}
+
+	//	constants
+	var K = [
+		int64(0x428a2f98, 0xd728ae22), int64(0x71374491, 0x23ef65cd), int64(0xb5c0fbcf, 0xec4d3b2f), int64(0xe9b5dba5, 0x8189dbbc), 
+		int64(0x3956c25b, 0xf348b538), int64(0x59f111f1, 0xb605d019), int64(0x923f82a4, 0xaf194f9b), int64(0xab1c5ed5, 0xda6d8118), 
+		int64(0xd807aa98, 0xa3030242), int64(0x12835b01, 0x45706fbe), int64(0x243185be, 0x4ee4b28c), int64(0x550c7dc3, 0xd5ffb4e2), 
+		int64(0x72be5d74, 0xf27b896f), int64(0x80deb1fe, 0x3b1696b1), int64(0x9bdc06a7, 0x25c71235), int64(0xc19bf174, 0xcf692694), 
+		int64(0xe49b69c1, 0x9ef14ad2), int64(0xefbe4786, 0x384f25e3), int64(0x0fc19dc6, 0x8b8cd5b5), int64(0x240ca1cc, 0x77ac9c65), 
+		int64(0x2de92c6f, 0x592b0275), int64(0x4a7484aa, 0x6ea6e483), int64(0x5cb0a9dc, 0xbd41fbd4), int64(0x76f988da, 0x831153b5), 
+		int64(0x983e5152, 0xee66dfab), int64(0xa831c66d, 0x2db43210), int64(0xb00327c8, 0x98fb213f), int64(0xbf597fc7, 0xbeef0ee4), 
+		int64(0xc6e00bf3, 0x3da88fc2), int64(0xd5a79147, 0x930aa725), int64(0x06ca6351, 0xe003826f), int64(0x14292967, 0x0a0e6e70), 
+		int64(0x27b70a85, 0x46d22ffc), int64(0x2e1b2138, 0x5c26c926), int64(0x4d2c6dfc, 0x5ac42aed), int64(0x53380d13, 0x9d95b3df), 
+		int64(0x650a7354, 0x8baf63de), int64(0x766a0abb, 0x3c77b2a8), int64(0x81c2c92e, 0x47edaee6), int64(0x92722c85, 0x1482353b), 
+		int64(0xa2bfe8a1, 0x4cf10364), int64(0xa81a664b, 0xbc423001), int64(0xc24b8b70, 0xd0f89791), int64(0xc76c51a3, 0x0654be30), 
+		int64(0xd192e819, 0xd6ef5218), int64(0xd6990624, 0x5565a910), int64(0xf40e3585, 0x5771202a), int64(0x106aa070, 0x32bbd1b8), 
+		int64(0x19a4c116, 0xb8d2d0c8), int64(0x1e376c08, 0x5141ab53), int64(0x2748774c, 0xdf8eeb99), int64(0x34b0bcb5, 0xe19b48a8), 
+		int64(0x391c0cb3, 0xc5c95a63), int64(0x4ed8aa4a, 0xe3418acb), int64(0x5b9cca4f, 0x7763e373), int64(0x682e6ff3, 0xd6b2b8a3), 
+		int64(0x748f82ee, 0x5defb2fc), int64(0x78a5636f, 0x43172f60), int64(0x84c87814, 0xa1f0ab72), int64(0x8cc70208, 0x1a6439ec), 
+		int64(0x90befffa, 0x23631e28), int64(0xa4506ceb, 0xde82bde9), int64(0xbef9a3f7, 0xb2c67915), int64(0xc67178f2, 0xe372532b), 
+		int64(0xca273ece, 0xea26619c), int64(0xd186b8c7, 0x21c0c207), int64(0xeada7dd6, 0xcde0eb1e), int64(0xf57d4f7f, 0xee6ed178), 
+		int64(0x06f067aa, 0x72176fba), int64(0x0a637dc5, 0xa2c898a6), int64(0x113f9804, 0xbef90dae), int64(0x1b710b35, 0x131c471b), 
+		int64(0x28db77f5, 0x23047d84), int64(0x32caab7b, 0x40c72493), int64(0x3c9ebe0a, 0x15c9bebc), int64(0x431d67c4, 0x9c100d4c), 
+		int64(0x4cc5d4be, 0xcb3e42b6), int64(0x597f299c, 0xfc657e2a), int64(0x5fcb6fab, 0x3ad6faec), int64(0x6c44198c, 0x4a475817)
+	];
+
+	//	our return object
+	var o = {
+		outputTypes: sha32.outputTypes,
+		stringToUtf8: function(s){ return sha32.stringToUtf8(s); },
+		toWord: function(s){ return sha32.toWord(s); },
+		toHex: function(wa){ return sha32.toHex(wa); },
+		toBase64: function(wa){ return sha32.toBase64(wa); },
+		_toString: function(wa){ return sha32._toString(wa); }
+	};
+
+	//	the main function
+	o.digest = function(msg, length, hash, depth){
+		//	prep the hash
+		var HASH = [];
+		for(var i=0, l=hash.length; i<l; i+=2){
+			HASH.push(int64(hash[i], hash[i+1]));
+		}
+
+		//	initialize our variables
+		var T1 = int64(0,0),
+			T2 = int64(0,0),
+			a = int64(0,0),
+			b = int64(0,0),
+			c = int64(0,0),
+			d = int64(0,0),
+			e = int64(0,0),
+			f = int64(0,0),
+			g = int64(0,0),
+			h = int64(0,0),
+			s0 = int64(0,0),
+			s1 = int64(0,0),
+			Ch = int64(0,0),
+			Maj = int64(0,0),
+			r1 = int64(0,0),
+			r2 = int64(0,0),
+			r3 = int64(0,0);
+		var j, i;
+		var w = new Array(80);
+		for(i=0; i<80; i++) w[i] = int64(0, 0);
+
+		// append padding to the source string.
+		msg[length >> 5] |= 0x80 << (24 - (length & 0x1f));
+		msg[((length + 128 >> 10)<< 5) + 31] = length;
+
+		for(i=0; i<msg.length; i+=32){
+			copy(a, HASH[0]);
+			copy(b, HASH[1]);
+			copy(c, HASH[2]);
+			copy(d, HASH[3]);
+			copy(e, HASH[4]);
+			copy(f, HASH[5]);
+			copy(g, HASH[6]);
+			copy(h, HASH[7]);
+
+			for(j=0; j<16; j++){
+				w[j].h = msg[i + 2*j];
+				w[j].l = msg[i + 2*j + 1];
+			}
+
+			for(j=16; j<80; j++){
+				//sigma1
+				rrot(r1, w[j-2], 19);
+				revrrot(r2, w[j-2], 29);
+				shr(r3, w[j-2], 6);
+				s1.l = r1.l ^ r2.l ^ r3.l;
+				s1.h = r1.h ^ r2.h ^ r3.h;
+
+				//sigma0
+				rrot(r1, w[j-15], 1);
+				rrot(r2, w[j-15], 8);
+				shr(r3, w[j-15], 7);
+				s0.l = r1.l ^ r2.l ^ r3.l;
+				s0.h = r1.h ^ r2.h ^ r3.h;
+
+				add4(w[j], s1, w[j-7], s0, w[j-16]);
+			}
+
+			for(j = 0; j < 80; j++){
+				//Ch
+				Ch.l = (e.l & f.l) ^ (~e.l & g.l);
+				Ch.h = (e.h & f.h) ^ (~e.h & g.h);
+
+				//Sigma1
+				rrot(r1, e, 14);
+				rrot(r2, e, 18);
+				revrrot(r3, e, 9);
+				s1.l = r1.l ^ r2.l ^ r3.l;
+				s1.h = r1.h ^ r2.h ^ r3.h;
+
+				//Sigma0
+				rrot(r1, a, 28);
+				revrrot(r2, a, 2);
+				revrrot(r3, a, 7);
+				s0.l = r1.l ^ r2.l ^ r3.l;
+				s0.h = r1.h ^ r2.h ^ r3.h;
+
+				//Maj
+				Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
+				Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
+
+				add5(T1, h, s1, Ch, K[j], w[j]);
+				add(T2, s0, Maj);
+
+				copy(h, g);
+				copy(g, f);
+				copy(f, e);
+				add(e, d, T1);
+				copy(d, c);
+				copy(c, b);
+				copy(b, a);
+				add(a, T1, T2);
+			}
+
+			add(HASH[0], HASH[0], a);
+			add(HASH[1], HASH[1], b);
+			add(HASH[2], HASH[2], c);
+			add(HASH[3], HASH[3], d);
+			add(HASH[4], HASH[4], e);
+			add(HASH[5], HASH[5], f);
+			add(HASH[6], HASH[6], g);
+			add(HASH[7], HASH[7], h);
+		}
+		
+		//	convert the final hash back to 32-bit words
+		var ret = [];
+		if(depth == 384){ HASH.length = 6; }
+		for(var i=0, l=HASH.length; i<l; i++){
+			ret[i*2] = HASH[i].h;
+			ret[i*2+1] = HASH[i].l;
+		}
+		return ret;
+	};
+
+	return o;
+});
diff --git a/dojox/encoding/easy64.js b/dojox/encoding/easy64.js
index d891d75..412e5b4 100644
--- a/dojox/encoding/easy64.js
+++ b/dojox/encoding/easy64.js
@@ -1,9 +1,5 @@
 define(["dojo/_base/lang"], function(lang) {
 	var easy64 = lang.getObject("dojox.encoding.easy64", true);
-	/*=====
-		easy64 = dojox.encoding.easy64;
-	=====*/
-
 	var c = function(input, length, result){
 		for(var i = 0; i < length; i += 3){
 			result.push(
@@ -16,8 +12,10 @@ define(["dojo/_base/lang"], function(lang) {
 	};
 
 	easy64.encode = function(input){
-		// summary: encodes input data in easy64 string
-		// input: Array: an array of numbers (0-255) to encode
+		// summary:
+		//		encodes input data in easy64 string
+		// input: Array
+		//		an array of numbers (0-255) to encode
 		var result = [], reminder = input.length % 3, length = input.length - reminder;
 		c(input, length, result);
 		if(reminder){
@@ -30,8 +28,10 @@ define(["dojo/_base/lang"], function(lang) {
 	};
 
 	easy64.decode = function(input){
-		// summary: decodes the input string back to array of numbers
-		// input: String: the input string to decode
+		// summary:
+		//		decodes the input string back to array of numbers
+		// input: String
+		//		the input string to decode
 		var n = input.length, r = [], b = [0, 0, 0, 0], i, j, d;
 		for(i = 0; i < n; i += 4){
 			for(j = 0; j < 4; ++j){ b[j] = input.charCodeAt(i + j) - 33; }
diff --git a/dojox/encoding/tests/compression/colors2.html b/dojox/encoding/tests/compression/colors2.html
index 24bb9fe..d6758d2 100755
--- a/dojox/encoding/tests/compression/colors2.html
+++ b/dojox/encoding/tests/compression/colors2.html
@@ -8,7 +8,7 @@
 			
 			.pane { margin-top: 2em; }
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.encoding.tests.compression.colors");
 			dojo.require("dojox.encoding.ascii85");
diff --git a/dojox/encoding/tests/compression/colors3.html b/dojox/encoding/tests/compression/colors3.html
index 482c75d..73a0a6d 100755
--- a/dojox/encoding/tests/compression/colors3.html
+++ b/dojox/encoding/tests/compression/colors3.html
@@ -8,7 +8,7 @@
 			
 			.pane { margin-top: 2em; }
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.encoding.tests.compression.colors");
 			dojo.require("dojox.encoding.easy64");
diff --git a/dojox/encoding/tests/compression/test.html b/dojox/encoding/tests/compression/test.html
index 8f07c59..16c3916 100755
--- a/dojox/encoding/tests/compression/test.html
+++ b/dojox/encoding/tests/compression/test.html
@@ -8,7 +8,7 @@
 			
 			.pane { margin-top: 2em; }
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript" src="colors2.js"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.encoding.tests.compression.colors");
diff --git a/dojox/encoding/tests/compression/vq.html b/dojox/encoding/tests/compression/vq.html
index 7805bd4..7f1c786 100755
--- a/dojox/encoding/tests/compression/vq.html
+++ b/dojox/encoding/tests/compression/vq.html
@@ -8,7 +8,7 @@
 			
 			.pane { margin-top: 2em; }
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.encoding.tests.compression.colors");
 			dojo.require("dojox.encoding.compression.splay");
diff --git a/dojox/encoding/tests/digests/SHA224.js b/dojox/encoding/tests/digests/SHA224.js
new file mode 100644
index 0000000..3e6b7a4
--- /dev/null
+++ b/dojox/encoding/tests/digests/SHA224.js
@@ -0,0 +1,18 @@
+define(['doh', '../../digests/_base', '../../digests/SHA224', "../../digests/_sha-32"], function(doh, ded, SHA224, sha32){
+	var message="abc";
+	//	test vector, from http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/SHA224.pdf
+	var wa = [
+		0x23097d22, 0x3405d822, 0x8642a477, 0xbda255b3, 0x2aadbce4, 0xbda0b3f7, 0xe36c9da7
+	];
+	var base64="Iwl9IjQF2CKGQqR3vaJVsyqtvOS9oLP342ydpw==";
+	var hex="23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7";
+
+	doh.register("dojox.encoding.tests.digests.SHA224", [
+		function testBase64Compute(t){
+			t.assertEqual(base64, SHA224(message));
+		},
+		function testHexCompute(t){
+			t.assertEqual(hex, SHA224(message, ded.outputTypes.Hex));
+		}
+	]);
+});
diff --git a/dojox/encoding/tests/digests/SHA256.js b/dojox/encoding/tests/digests/SHA256.js
new file mode 100644
index 0000000..bb67f59
--- /dev/null
+++ b/dojox/encoding/tests/digests/SHA256.js
@@ -0,0 +1,14 @@
+define(['doh', '../../digests/_base', '../../digests/SHA256'], function(doh, ded, SHA256){
+	var message="abc";
+	var hex="ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
+	var base64="ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0=";
+
+	doh.register("dojox.encoding.tests.digests.SHA256", [
+		function testBase64Compute(t){
+			t.assertEqual(base64, SHA256(message));
+		},
+		function testHexCompute(t){
+			t.assertEqual(hex, SHA256(message, ded.outputTypes.Hex));
+		}
+	]);
+});
diff --git a/dojox/encoding/tests/digests/SHA384.js b/dojox/encoding/tests/digests/SHA384.js
new file mode 100644
index 0000000..d62fdfa
--- /dev/null
+++ b/dojox/encoding/tests/digests/SHA384.js
@@ -0,0 +1,36 @@
+define(['doh', '../../digests/_base', '../../digests/SHA384', "../../digests/_sha-64"], 
+		function(doh, ded, SHA384, sha64){
+	var message="abc";
+
+	var vector = [
+		0xcb00753f, 0x45a35e8b, 0xb5a03d69, 0x9ac65007, 
+		0x272c32ab, 0x0eded163, 0x1a8b605a, 0x43ff5bed, 
+		0x8086072b, 0xa1e7cc23, 0x58baeca1, 0x34c825a7
+	];
+
+	var base64="ywB1P0WjXou1oD1pmsZQBycsMqsO3tFjGotgWkP/W+2AhgcroefMI1i67KE0yCWn";
+	var hex="cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7";
+
+	console.log("Vector:", vector.map(function(item){
+		return ((item >> 16) & 0xffff).toString(16) + (item & 0xffff).toString(16);
+	}));
+	console.log(sha64.toHex(vector));
+	console.log(sha64.toBase64(vector));
+	console.log(sha64.toWord(message));
+
+	var test = SHA384(message, ded.outputTypes.Raw);
+	console.log("Message: ", test.map(function(item){
+		return ((item >> 16) & 0xffff).toString(16) + (item & 0xffff).toString(16);
+	}));
+	console.log(sha64.toHex(test));
+	console.log(sha64.toBase64(test));
+
+	doh.register("dojox.encoding.tests.digests.SHA384", [
+		function testBase64Compute(t){
+			t.assertEqual(base64, SHA384(message));
+		},
+		function testHexCompute(t){
+			t.assertEqual(hex, SHA384(message, ded.outputTypes.Hex));
+		}
+	]);
+});
diff --git a/dojox/encoding/tests/digests/SHA512.js b/dojox/encoding/tests/digests/SHA512.js
new file mode 100644
index 0000000..25ca3a6
--- /dev/null
+++ b/dojox/encoding/tests/digests/SHA512.js
@@ -0,0 +1,22 @@
+define(['doh', '../../digests/_base', '../../digests/SHA512'], 
+		function(doh, ded, SHA512){
+	var message="abc";
+	var vector = [
+		0xddaf35a1, 0x93617aba, 0xcc417349, 0xae204131,
+		0x12e6fa4e, 0x89a97ea2, 0x0a9eeee6, 0x4b55d39a, 
+		0x2192992a, 0x274fc1a8, 0x36ba3c23, 0xa3feebbd,
+		0x454d4423, 0x643ce80e, 0x2a9ac94f, 0xa54ca49f
+	];
+
+	var base64="3a81oZNherrMQXNJriBBMRLm+k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9RU1EI2Q86A4qmslPpUyknw==";
+	var hex="ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f";
+
+	doh.register("dojox.encoding.tests.digests.SHA512", [
+		function testBase64Compute(t){
+			t.assertEqual(base64, SHA512(message));
+		},
+		function testHexCompute(t){
+			t.assertEqual(hex, SHA512(message, ded.outputTypes.Hex));
+		}
+	]);
+});
diff --git a/dojox/encoding/tests/digests/_base.js b/dojox/encoding/tests/digests/_base.js
index 652c6db..5549f9d 100644
--- a/dojox/encoding/tests/digests/_base.js
+++ b/dojox/encoding/tests/digests/_base.js
@@ -1 +1 @@
-define(['./MD5', './SHA1'], {});
+define(['./MD5', './SHA1', "./SHA224", "./SHA256", "./SHA384", "./SHA512"], {});
diff --git a/dojox/flash.js b/dojox/flash.js
index 84657ae..0c0b88a 100644
--- a/dojox/flash.js
+++ b/dojox/flash.js
@@ -1,2 +1,9 @@
-dojo.provide("dojox.flash");
-dojo.require("dojox.flash._base");
+define(['./flash/_base'],function(){
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/flash modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
+});
diff --git a/dojox/flash/_base.js b/dojox/flash/_base.js
index ec65c3a..3a61ba8 100644
--- a/dojox/flash/_base.js
+++ b/dojox/flash/_base.js
@@ -4,96 +4,91 @@ dojo.experimental("dojox.flash");
 // for dojo.window.getBox(), needed by dojox.flash.Embed.center()
 dojo.require("dojo.window");
 
-dojox.flash = function(){
+dojox.flash = {
 	// summary:
-	//	Utilities to embed and communicate with the Flash player from Javascript
-	//
+	//		Utilities to embed and communicate with the Flash player from Javascript
 	// description:
-	//	The goal of dojox.flash is to make it easy to extend Flash's capabilities
-	//	into an Ajax/DHTML environment.
+	//		The goal of dojox.flash is to make it easy to extend Flash's capabilities
+	//		into an Ajax/DHTML environment.
 	//
-	//	dojox.flash provides an easy object for interacting with the Flash plugin.
-	//	This object provides methods to determine the current version of the Flash
-	//	plugin (dojox.flash.info); write out the necessary markup to
-	//	dynamically insert a Flash object into the page (dojox.flash.Embed; and
-	//	do dynamic installation and upgrading of the current Flash plugin in
-	//	use (dojox.flash.Install). If you want to call methods on the Flash object
-	//	embedded into the page it is your responsibility to use Flash's ExternalInterface
-	//	API and get a reference to the Flash object yourself.
+	//		dojox.flash provides an easy object for interacting with the Flash plugin.
+	//		This object provides methods to determine the current version of the Flash
+	//		plugin (dojox.flash.info); write out the necessary markup to
+	//		dynamically insert a Flash object into the page (dojox.flash.Embed; and
+	//		do dynamic installation and upgrading of the current Flash plugin in
+	//		use (dojox.flash.Install). If you want to call methods on the Flash object
+	//		embedded into the page it is your responsibility to use Flash's ExternalInterface
+	//		API and get a reference to the Flash object yourself.
 	//
-	//	To use dojox.flash, you must first wait until Flash is finished loading
-	//	and initializing before you attempt communication or interaction.
-	//	To know when Flash is finished use dojo.connect:
+	//		To use dojox.flash, you must first wait until Flash is finished loading
+	//		and initializing before you attempt communication or interaction.
+	//		To know when Flash is finished use dojo.connect:
 	//
-	//|	dojo.connect(dojox.flash, "loaded", myInstance, "myCallback");
+	// |	dojo.connect(dojox.flash, "loaded", myInstance, "myCallback");
 	//
-	//	Then, while the page is still loading provide the file name:
+	//		Then, while the page is still loading provide the file name:
 	//
-	//|	dojox.flash.setSwf(dojo.moduleUrl("dojox", "_storage/storage.swf"));
+	// |	dojox.flash.setSwf(dojo.moduleUrl("dojox", "_storage/storage.swf"));
 	//
-	//	If no SWF files are specified, then Flash is not initialized.
+	//		If no SWF files are specified, then Flash is not initialized.
 	//
-	//	Your Flash must use Flash's ExternalInterface to expose Flash methods and
-	//	to call JavaScript.
+	//		Your Flash must use Flash's ExternalInterface to expose Flash methods and
+	//		to call JavaScript.
 	//
-	//	setSwf can take an optional 'visible' attribute to control whether
-	//	the Flash object is visible or not on the page; the default is visible:
+	//		setSwf can take an optional 'visible' attribute to control whether
+	//		the Flash object is visible or not on the page; the default is visible:
 	//
-	//|	dojox.flash.setSwf(dojo.moduleUrl("dojox", "_storage/storage.swf"),
-	//						false);
+	// |	dojox.flash.setSwf(dojo.moduleUrl("dojox", "_storage/storage.swf"), false);
 	//
-	//	Once finished, you can query Flash version information:
+	//		Once finished, you can query Flash version information:
 	//
-	//|	dojox.flash.info.version
+	// |	dojox.flash.info.version
 	//
-	//	Or can communicate with Flash methods that were exposed:
+	//		Or can communicate with Flash methods that were exposed:
 	//
-	//|	var f = dojox.flash.get();
-	//|	var results = f.sayHello("Some Message");
+	// |	var f = dojox.flash.get();
+	// |	var results = f.sayHello("Some Message");
 	//
-	//	Your Flash files should use DojoExternalInterface.as to register methods;
-	//	this file wraps Flash's normal ExternalInterface but correct various
-	//	serialization bugs that ExternalInterface has.
+	//		Your Flash files should use DojoExternalInterface.as to register methods;
+	//		this file wraps Flash's normal ExternalInterface but correct various
+	//		serialization bugs that ExternalInterface has.
 	//
-	//	Note that dojox.flash is not meant to be a generic Flash embedding
-	//	mechanism; it is as generic as necessary to make Dojo Storage's
-	//	Flash Storage Provider as clean and modular as possible. If you want
-	//	a generic Flash embed mechanism see [SWFObject](http://blog.deconcept.com/swfobject/).
+	// 		Notes:
 	//
-	// 	Notes:
-	//	Note that dojox.flash can currently only work with one Flash object
-	//	on the page; it does not yet support multiple Flash objects on
-	//	the same page.
+	//		- dojox.flash is not meant to be a generic Flash embedding
+	//		mechanism; it is as generic as necessary to make Dojo Storage's
+	//		Flash Storage Provider as clean and modular as possible. If you want
+	//		a generic Flash embed mechanism see [SWFObject](http://blog.deconcept.com/swfobject/).
+	//		- dojox.flash can currently only work with one Flash object
+	//		on the page; it does not yet support multiple Flash objects on
+	//		the same page.
+	//		- Your code can detect whether the Flash player is installing or having
+	//		its version revved in two ways. First, if dojox.flash detects that
+	//		Flash installation needs to occur, it sets dojox.flash.info.installing
+	//		to true. Second, you can detect if installation is necessary with the
+	//		following callback:
 	//
-	//	Your code can detect whether the Flash player is installing or having
-	//	its version revved in two ways. First, if dojox.flash detects that
-	//	Flash installation needs to occur, it sets dojox.flash.info.installing
-	//	to true. Second, you can detect if installation is necessary with the
-	//	following callback:
+	// |	dojo.connect(dojox.flash, "installing", myInstance, "myCallback");
 	//
-	//|	dojo.connect(dojox.flash, "installing", myInstance, "myCallback");
+	//		You can use this callback to delay further actions that might need Flash;
+	//		when installation is finished the full page will be refreshed and the
+	//		user will be placed back on your page with Flash installed.
 	//
-	//	You can use this callback to delay further actions that might need Flash;
-	//	when installation is finished the full page will be refreshed and the
-	//	user will be placed back on your page with Flash installed.
+	//		-------------------
+	//		Todo/Known Issues
+	//		-------------------
 	//
-	//	-------------------
-	//	Todo/Known Issues
-	//	-------------------
+	//		- On Internet Explorer, after doing a basic install, the page is
+	//		not refreshed or does not detect that Flash is now available. The way
+	//		to fix this is to create a custom small Flash file that is pointed to
+	//		during installation; when it is finished loading, it does a callback
+	//		that says that Flash installation is complete on IE, and we can proceed
+	//		to initialize the dojox.flash subsystem.
+	//		- Things aren't super tested for sending complex objects to Flash
+	//		methods, since Dojo Storage only needs strings.
 	//
-	//	* On Internet Explorer, after doing a basic install, the page is
-	//	not refreshed or does not detect that Flash is now available. The way
-	//	to fix this is to create a custom small Flash file that is pointed to
-	//	during installation; when it is finished loading, it does a callback
-	//	that says that Flash installation is complete on IE, and we can proceed
-	//	to initialize the dojox.flash subsystem.
-	//	* Things aren't super tested for sending complex objects to Flash
-	//	methods, since Dojo Storage only needs strings
-	//
-	//	Author- Brad Neuberg, http://codinginparadise.org
-}
+	//		Author- Brad Neuberg, http://codinginparadise.org
 
-dojox.flash = {
 	ready: false,
 	url: null,
 	
@@ -102,13 +97,14 @@ dojox.flash = {
 	_installingListeners: [],
 	
 	setSwf: function(/* String */ url, /* boolean? */ visible){
-		// summary: Sets the SWF files and versions we are using.
+		// summary:
+		//		Sets the SWF files and versions we are using.
 		// url: String
-		//	The URL to this Flash file.
+		//		The URL to this Flash file.
 		// visible: boolean?
-		//	Whether the Flash file is visible or not. If it is not visible we hide
-		//	it off the screen. This defaults to true (i.e. the Flash file is
-		//	visible).
+		//		Whether the Flash file is visible or not. If it is not visible we hide
+		//		it off the screen. This defaults to true (i.e. the Flash file is
+		//		visible).
 		this.url = url;
 		
 		this._visible = true;
@@ -142,13 +138,14 @@ dojox.flash = {
 	},
 	
 	loaded: function(){
-		// summary: Called back when the Flash subsystem is finished loading.
+		// summary:
+		//		Called back when the Flash subsystem is finished loading.
 		// description:
-		//	A callback when the Flash subsystem is finished loading and can be
-		//	worked with. To be notified when Flash is finished loading, add a
-		//  loaded listener:
+		//		A callback when the Flash subsystem is finished loading and can be
+		//		worked with. To be notified when Flash is finished loading, add a
+		//		loaded listener:
 		//
-		//  dojox.flash.addLoadedListener(loadedListener);
+		//		dojox.flash.addLoadedListener(loadedListener);
 	
 		dojox.flash.ready = true;
 		if(dojox.flash._loadedListeners.length){ // FIXME: redundant if? use forEach?
@@ -159,13 +156,14 @@ dojox.flash = {
 	},
 	
 	installing: function(){
-		// summary: Called if Flash is being installed.
+		// summary:
+		//		Called if Flash is being installed.
 		// description:
-		//	A callback to know if Flash is currently being installed or
-		//	having its version revved. To be notified if Flash is installing, connect
-		//	your callback to this method using the following:
+		//		A callback to know if Flash is currently being installed or
+		//		having its version revved. To be notified if Flash is installing, connect
+		//		your callback to this method using the following:
 		//
-		//	dojo.event.connect(dojox.flash, "installing", myInstance, "myCallback");
+		//		dojo.event.connect(dojox.flash, "installing", myInstance, "myCallback");
 		
 		if(dojox.flash._installingListeners.length){ // FIXME: redundant if? use forEach?
 			for(var i = 0; i < dojox.flash._installingListeners.length; i++){
@@ -196,19 +194,20 @@ dojox.flash = {
 
 
 dojox.flash.Info = function(){
-	// summary: A class that helps us determine whether Flash is available.
+	// summary:
+	//		A class that helps us determine whether Flash is available.
 	// description:
-	//	A class that helps us determine whether Flash is available,
-	//	it's major and minor versions, and what Flash version features should
-	//	be used for Flash/JavaScript communication. Parts of this code
-	//	are adapted from the automatic Flash plugin detection code autogenerated
-	//	by the Macromedia Flash 8 authoring environment.
+	//		A class that helps us determine whether Flash is available,
+	//		it's major and minor versions, and what Flash version features should
+	//		be used for Flash/JavaScript communication. Parts of this code
+	//		are adapted from the automatic Flash plugin detection code autogenerated
+	//		by the Macromedia Flash 8 authoring environment.
 	//
-	//	An instance of this class can be accessed on dojox.flash.info after
-	//	the page is finished loading.
+	//		An instance of this class can be accessed on dojox.flash.info after
+	//		the page is finished loading.
 
 	this._detectVersion();
-}
+};
 
 dojox.flash.Info.prototype = {
 	// version: String
@@ -228,7 +227,7 @@ dojox.flash.Info.prototype = {
 	capable: false,
 	
 	// installing: Boolean
-	//	Set if we are in the middle of a Flash installation session.
+	//		Set if we are in the middle of a Flash installation session.
 	installing: false,
 	
 	isVersionOrAbove: function(
@@ -236,18 +235,18 @@ dojox.flash.Info.prototype = {
 							/* int */ reqMinorVer,
 							/* int */ reqVer){ /* Boolean */
 		// summary:
-		//	Asserts that this environment has the given major, minor, and revision
-		//	numbers for the Flash player.
+		//		Asserts that this environment has the given major, minor, and revision
+		//		numbers for the Flash player.
 		// description:
-		//	Asserts that this environment has the given major, minor, and revision
-		//	numbers for the Flash player.
+		//		Asserts that this environment has the given major, minor, and revision
+		//		numbers for the Flash player.
 		//
-		//	Example- To test for Flash Player 7r14:
+		//		Example- To test for Flash Player 7r14:
 		//
-		//	dojox.flash.info.isVersionOrAbove(7, 0, 14)
+		//		dojox.flash.info.isVersionOrAbove(7, 0, 14)
 		// returns:
-		//	Returns true if the player is equal
-		//	or above the given version, false otherwise.
+		//		Returns true if the player is equal
+		//		or above the given version, false otherwise.
 		
 		// make the revision a decimal (i.e. transform revision 14 into
 		// 0.14
@@ -343,30 +342,31 @@ dojox.flash.Info.prototype = {
 };
 
 dojox.flash.Embed = function(visible){
-	// summary: A class that is used to write out the Flash object into the page.
+	// summary:
+	//		A class that is used to write out the Flash object into the page.
 	// description:
-	//	Writes out the necessary tags to embed a Flash file into the page. Note that
-	//	these tags are written out as the page is loaded using document.write, so
-	//	you must call this class before the page has finished loading.
+	//		Writes out the necessary tags to embed a Flash file into the page. Note that
+	//		these tags are written out as the page is loaded using document.write, so
+	//		you must call this class before the page has finished loading.
 	
 	this._visible = visible;
-}
+};
 
 dojox.flash.Embed.prototype = {
 	// width: int
-	//	The width of this Flash applet. The default is the minimal width
-	//	necessary to show the Flash settings dialog. Current value is
-	//  215 pixels.
+	//		The width of this Flash applet. The default is the minimal width
+	//		necessary to show the Flash settings dialog. Current value is
+	//		215 pixels.
 	width: 215,
 	
 	// height: int
-	//	The height of this Flash applet. The default is the minimal height
-	//	necessary to show the Flash settings dialog. Current value is
-	// 138 pixels.
+	//		The height of this Flash applet. The default is the minimal height
+	//		necessary to show the Flash settings dialog. Current value is
+	//		138 pixels.
 	height: 138,
 	
 	// id: String
-	// 	The id of the Flash object. Current value is 'flashObject'.
+	//		The id of the Flash object. Current value is 'flashObject'.
 	id: "flashObject",
 	
 	// Controls whether this is a visible Flash applet or not.
@@ -384,13 +384,14 @@ dojox.flash.Embed.prototype = {
 	},
 	
 	write: function(/* Boolean? */ doExpressInstall){
-		// summary: Writes the Flash into the page.
+		// summary:
+		//		Writes the Flash into the page.
 		// description:
-		//	This must be called before the page
-		//	is finished loading.
+		//		This must be called before the page
+		//		is finished loading.
 		// doExpressInstall: Boolean
-		//	Whether to write out Express Install
-		//	information. Optional value; defaults to false.
+		//		Whether to write out Express Install
+		//		information. Optional value; defaults to false.
 		
 		// figure out the SWF file to get and how to write out the correct HTML
 		// for this Flash version
@@ -500,7 +501,8 @@ dojox.flash.Embed.prototype = {
 	},
 	
 	get: function(){ /* Object */
-		// summary: Gets the Flash object DOM node.
+		// summary:
+		//		Gets the Flash object DOM node.
 
 		if(dojo.isIE || dojo.isWebKit){
 			//TODO: should this really be the else?
@@ -518,9 +520,11 @@ dojox.flash.Embed.prototype = {
 	},
 	
 	setVisible: function(/* Boolean */ visible){
+		// summary:
+		//		Sets the visibility of this Flash object.
+
 		//console.debug("setVisible, visible="+visible);
-		
-		// summary: Sets the visibility of this Flash object.
+
 		var container = dojo.byId(this.id + "Container");
 		if(visible){
 			container.style.position = "absolute"; // IE -- Brad Neuberg
@@ -533,7 +537,8 @@ dojox.flash.Embed.prototype = {
 	},
 	
 	center: function(){
-		// summary: Centers the flash applet on the page.
+		// summary:
+		//		Centers the flash applet on the page.
 		
 		var elementWidth = this.width;
 		var elementHeight = this.height;
@@ -604,7 +609,7 @@ dojox.flash.Communicator.prototype = {
 	// present even in Flash 9.
 	_decodeData: function(data){
 		//console.debug("decodeData, data=", data);
-		// wierdly enough, Flash sometimes returns the result as an
+		// weirdly enough, Flash sometimes returns the result as an
 		// 'object' that is actually an array, rather than as a String;
 		// detect this by looking for a length property; for IE
 		// we also make sure that we aren't dealing with a typeof string
@@ -679,15 +684,16 @@ dojox.flash.Communicator.prototype = {
 // TODO: I did not test the Install code when I refactored Dojo Flash from 0.4 to
 // 1.0, so am not sure if it works. If Flash is not present I now prefer
 // that Gears is installed instead of Flash because GearsStorageProvider is
-// much easier to work with than Flash's hacky ExternalInteface.
+// much easier to work with than Flash's hacky ExternalInterface.
 // -- Brad Neuberg
 dojox.flash.Install = function(){
-	// summary: Helps install Flash plugin if needed.
+	// summary:
+	//		Helps install Flash plugin if needed.
 	// description:
 	//		Figures out the best way to automatically install the Flash plugin
 	//		for this browser and platform. Also determines if installation or
 	//		revving of the current plugin is needed on this platform.
-}
+};
 
 dojox.flash.Install.prototype = {
 	needed: function(){ /* Boolean */
@@ -710,7 +716,8 @@ dojox.flash.Install.prototype = {
 	},
 
 	install: function(){
-		// summary: Performs installation or revving of the Flash plugin.
+		// summary:
+		//		Performs installation or revving of the Flash plugin.
 		var installObj;
 	
 		// indicate that we are installing
@@ -753,7 +760,7 @@ dojox.flash.Install.prototype = {
 						+ "the latest version of the Flash plugin.");
 		}
 	}
-}
+};
 
 // find out if Flash is installed
 dojox.flash.info = new dojox.flash.Info();
diff --git a/dojox/flash/tests/test_flash.html b/dojox/flash/tests/test_flash.html
index f220a37..039aec7 100644
--- a/dojox/flash/tests/test_flash.html
+++ b/dojox/flash/tests/test_flash.html
@@ -1,6 +1,6 @@
 <html>
 	<head>
-		<script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		
 		<script src="test_flash.js"></script>
 	</head>
diff --git a/dojox/form/BusyButton.js b/dojox/form/BusyButton.js
index 356da26..7242ebb 100644
--- a/dojox/form/BusyButton.js
+++ b/dojox/form/BusyButton.js
@@ -9,17 +9,21 @@ define([
 	"dojo/i18n!dijit/nls/loading",
 	"dojo/_base/declare"
 ], function(lang, domAttr, domClass, Button, DropDownButton, ComboButton, i18n, nlsLoading, declare){
-	/*=====
-		Button = dijit.form.Button;
-		DropDownButton = dijit.form.DropDownButton;
-		ComboButton = dijit.form.ComboButton;
-	=====*/
+
 var _BusyButtonMixin = declare("dojox.form._BusyButtonMixin", null, {
 
+	// isBusy: Boolean
 	isBusy: false,
-	busyLabel: "", // text while button is busy
+	
+	// busyLabel: String
+	//		text while button is busy
+	busyLabel: "",
+	
 	timeout: null, // timeout, should be controlled by xhr call
-	useIcon: true, // use a busy icon
+	
+	// useIcon: Boolean
+	//		use a busy icon
+	useIcon: true,
 
 	postMixInProperties: function(){
 		this.inherited(arguments);
@@ -53,7 +57,7 @@ var _BusyButtonMixin = declare("dojox.form._BusyButtonMixin", null, {
 	cancel: function(){
 		// summary:
 		//		if no timeout is set or for other reason the user can put the button back
-		//  	to being idle
+		//		to being idle
 		this.set("disabled", false);
 		this.isBusy = false;
 		this.setLabel(this._label);
@@ -85,7 +89,6 @@ var _BusyButtonMixin = declare("dojox.form._BusyButtonMixin", null, {
 		// this.inherited(arguments); FIXME: throws an Unknown runtime error
 
 		// Begin IE hack
-		// summary: reset the label (text) of the button; takes an HTML string
 		this.label = content;
 		// remove children
 		while(this.containerNode.firstChild){
@@ -127,8 +130,17 @@ var _BusyButtonMixin = declare("dojox.form._BusyButtonMixin", null, {
 	}
 });
 
-var BusyButton = declare("dojox.form.BusyButton", [Button, _BusyButtonMixin], {});
+var BusyButton = declare("dojox.form.BusyButton", [Button, _BusyButtonMixin], {
+	// summary:
+	//		BusyButton is a simple widget which provides implementing more 
+	//		user friendly form submission.
+	// description:
+	//		When a form gets submitted by a user, many times it is recommended to disable
+	//		the submit buttons to prevent double submission. BusyButton provides a simple set
+	//		of features for this purpose
+
+});
 declare("dojox.form.BusyComboButton", [ComboButton, _BusyButtonMixin], {});
 declare("dojox.form.BusyDropDownButton", [DropDownButton, _BusyButtonMixin], {});
 return BusyButton;
-});
\ No newline at end of file
+});
diff --git a/dojox/form/CheckedMultiSelect.js b/dojox/form/CheckedMultiSelect.js
index ae1ea0d..aeab940 100644
--- a/dojox/form/CheckedMultiSelect.js
+++ b/dojox/form/CheckedMultiSelect.js
@@ -7,7 +7,7 @@ define([
 	"dojo/dom-class",
 	"dojo/dom-construct",
 	"dojo/i18n",
-	"dijit/_Widget",
+	"dijit/_WidgetBase",
 	"dijit/_TemplatedMixin",
 	"dijit/_WidgetsInTemplateMixin",
 	"dijit/registry",
@@ -22,21 +22,13 @@ define([
 	"dojo/i18n!dojox/form/nls/CheckedMultiSelect",
 	"dijit/form/CheckBox" // template
 ], function(declare, lang, array, event, domGeometry, domClass, domConstruct, i18n, Widget, TemplatedMixin, WidgetsInTemplateMixin, registry, Menu, MenuItem, Tooltip, FormSelectWidget, ComboButton, CheckedMultiSelectMenuItem, CheckedMultiSelectItem, CheckedMultiSelect, nlsCheckedMultiSelect){
+ 
+// module:
+//		dojox/form/CheckedMultiSelect
+// summary:
+//		Extends the core dojox.form.CheckedMultiSelect to provide a "checkbox" selector
+
 
-	//	module:
-	//		dojox/form/CheckedMultiSelect
-	//	summary:
-	//		Extends the core dojox.form.CheckedMultiSelect to provide a "checkbox" selector
-	//
-
-	/*=====
-		Widget = dijit._Widget;
-		TemplatedMixin = dijit._TemplatedMixin;
-		WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
-		Menu = dijit.Menu;
-		MenuItem = dijit.MenuItem;
-		FormSelectWidget = dijit.form._FormSelectWidget;
-	=====*/
 var formCheckedMultiSelectItem = declare("dojox.form._CheckedMultiSelectItem", [Widget, TemplatedMixin, WidgetsInTemplateMixin], {
 	// summary:
 	//		The individual items for a CheckedMultiSelect
@@ -130,10 +122,9 @@ var formCheckedMultiSelectItem = declare("dojox.form._CheckedMultiSelectItem", [
 var formCheckedMultiSelectMenu = declare("dojox.form._CheckedMultiSelectMenu", Menu, {
 	// summary:
 	//		An internally-used menu for dropdown that allows us a vertical scrollbar
+
 	multiple: false,
 
-	// summary:
-	//		An internally-used menu for dropdown that allows us a vertical scrollbar
 	buildRendering: function(){
 		// summary:
 		//		Stub in our own changes, so that our domNode is not a table
@@ -187,6 +178,7 @@ var formCheckedMultiSelectMenu = declare("dojox.form._CheckedMultiSelectMenu", M
 		//		Handle clicks on an item.
 		// tags:
 		//		private
+		
 		// this can't be done in _onFocus since the _onFocus events occurs asynchronously
 		if(typeof this.isShowingNow == 'undefined'){ // non-popup menu
 			this._markActive();
@@ -223,9 +215,9 @@ var formCheckedMultiSelectMenuItem = declare("dojox.form._CheckedMultiSelectMenu
 	_iconClass: "",
 
 	postMixInProperties: function(){
-	// summary:
-	//		Set the appropriate _subClass value - based on if we are multi-
-	//		or single-select
+		// summary:
+		//		Set the appropriate _subClass value - based on if we are multi-
+		//		or single-select
 		if(this.parent.multiple){
 			this._iconClass = "dojoxCheckedMultiSelectMenuCheckBoxItemIcon";
 			this._type = {type: "checkbox"};
@@ -315,20 +307,6 @@ var formCheckedMultiSelect = declare("dojox.form.CheckedMultiSelect", FormSelect
 	//		See description of `Tooltip.defaultPosition` for details on this parameter.
 	tooltipPosition: [],
 
-	setStore: function(store, selectedValue, fetchArgs){
-		// summary:
-		//		If there is any items selected in the store, the value
-		//		of the widget will be set to the values of these items.
-		this.inherited(arguments);
-		var setSelectedItems = function(items){
-			var value = array.map(items, function(item){ return item.value[0]; });
-			if(value.length){
-				this.set("value", value);
-			}
-		};
-		this.store.fetch({query:{selected: true}, onComplete: setSelectedItems, scope: this});
-	},
-
 	postMixInProperties: function(){
 		this.inherited(arguments);
 		this._nlsResources = i18n.getLocalization("dojox.form", "CheckedMultiSelect", this.lang);
@@ -431,7 +409,7 @@ var formCheckedMultiSelect = declare("dojox.form.CheckedMultiSelect", FormSelect
 		//		notification that an item as been added to this dijit.
 	},
 
-	_addOptionItem: function(/* dojox.form.__SelectOption */ option){
+	_addOptionItem: function(/*dojox.form.__SelectOption*/ option){
 		var item;
 		if(this.dropDown){
 			item = new formCheckedMultiSelectMenuItem({
@@ -462,7 +440,7 @@ var formCheckedMultiSelect = declare("dojox.form.CheckedMultiSelect", FormSelect
 	},
 
 	reset: function(){
-		// summary: Overridden so that the state will be cleared.
+		// Overridden so that the state will be cleared.
 		this.inherited(arguments);
 		Tooltip.hide(this.domNode);
 	},
@@ -473,6 +451,16 @@ var formCheckedMultiSelect = declare("dojox.form.CheckedMultiSelect", FormSelect
 		array.forEach(this._getChildren(), function(item){
 			item._updateBox();
 		});
+		domConstruct.empty(this.containerNode);
+		var self = this;
+		array.forEach(this.value, function(item){
+			var opt = domConstruct.create("option", {
+				"value": item,
+				"label": item,
+				"selected": "selected"
+			});
+			domConstruct.place(opt, self.containerNode);
+		});
 		if(this.dropDown && this.dropDownButton){
 			var i = 0, label = "";
 			array.forEach(this.options, function(option){
@@ -498,7 +486,8 @@ var formCheckedMultiSelect = declare("dojox.form.CheckedMultiSelect", FormSelect
 	},
 
 	invertSelection: function(onChange){
-		// summary: Invert the selection
+		// summary:
+		//		Invert the selection
 		// onChange: Boolean
 		//		If null, onChange is not fired.
 		if(this.multiple){
@@ -528,7 +517,7 @@ var formCheckedMultiSelect = declare("dojox.form.CheckedMultiSelect", FormSelect
 		//		Sets read only (or unsets) all the children as well
 		this.inherited(arguments);
 		if("readOnly" in this.attributeMap){
-			this._attrToDom("readOnly", value);
+			this[this.attributeMap.readOnly].setAttribute("readonly", value);
 		}
 		this.readOnly = value;
 		array.forEach(this._getChildren(), function(node){
@@ -549,4 +538,4 @@ var formCheckedMultiSelect = declare("dojox.form.CheckedMultiSelect", FormSelect
 });
 
 return formCheckedMultiSelect;
-});
\ No newline at end of file
+});
diff --git a/dojox/form/DateTextBox.js b/dojox/form/DateTextBox.js
index b222209..0b99101 100644
--- a/dojox/form/DateTextBox.js
+++ b/dojox/form/DateTextBox.js
@@ -1,195 +1,28 @@
 define([
 	"dojo/_base/kernel",
-	"dojo/_base/lang",
 	"dojo/dom-style",
 	"dojox/widget/Calendar",
-	"dojox/widget/CalendarViews",
 	"dijit/form/_DateTimeTextBox",
-	"dijit/form/TextBox",
 	"dojo/_base/declare"
-], function(kernel, lang, domStyle, Calendar, CalendarViews, _DateTimeTextBox, TextBox, declare){
-kernel.experimental("dojox.form.DateTextBox");
+	], function(kernel, domStyle, Calendar, _DateTimeTextBox, declare){
+	kernel.experimental("dojox/form/DateTextBox");
+	return declare( "dojox.form.DateTextBox", _DateTimeTextBox,
+		{
+			// summary:
+			//		A validating, serializable, range-bound date text box with a popup calendar
 
-	/*=====
-		_DateTimeTextBox = dijit.form._DateTimeTextBox;
-	=====*/
-var DateTextBox = declare( "dojox.form.DateTextBox", _DateTimeTextBox,
-	{
-		// summary:
-		//		A validating, serializable, range-bound date text box with a popup calendar
+			baseClass: "dijitTextBox dijitComboBox dojoxDateTextBox",
 
-		// popupClass: String
-		//  The popup widget to use. In this case, a calendar with Day, Month and Year views.
-		popupClass: "dojox.widget.Calendar",
-		_selector: "date",
+			// popupClass: String
+			//		The popup widget to use. In this case, a calendar with Day, Month and Year views.
+			popupClass: Calendar,
 
-		openDropDown: function(){
-			this.inherited(arguments);
-			domStyle.set(this.dropDown.domNode.parentNode, "position", "absolute");
-		}
-	}
-);
-
-
-declare( "dojox.form.DayTextBox", DateTextBox,
-	{
-		// summary:
-		//		A validating, serializable, range-bound date text box with a popup calendar that contains just months.
-
-		// popupClass: String
-		//  The popup widget to use. In this case, a calendar with just a Month view.
-		popupClass: "dojox.widget.DailyCalendar",
-
-		parse: function(displayVal){
-			return displayVal;
-		},
-
-		format: function(value){
-			return value.getDate ? value.getDate() : value;
-		},
-		validator: function(value){
-			var num = Number(value);
-			var isInt = /(^-?\d\d*$)/.test(String(value));
-			return value == "" || value == null || (isInt && num >= 1 && num <= 31);
-		},
-
-		_setValueAttr: function(value, priorityChange, formattedValue){
-			if(value){
-				if(value.getDate){
-					value = value.getDate();
-				}
-			}
-			TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
-		},
-
-		openDropDown: function(){
-			this.inherited(arguments);
-
-			this.dropDown.onValueSelected = lang.hitch(this, function(value){
-				this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
-				setTimeout(lang.hitch(this, "closeDropDown"), 1); // allow focus time to take
-
-				TextBox.prototype._setValueAttr.call(this, String(value.getDate()), true, String(value.getDate()));
-			});
-		}
-	}
-);
-
-declare( "dojox.form.MonthTextBox", DateTextBox,
-	{
-		// summary:
-		//		A validating, serializable, range-bound date text box with a popup calendar that contains only years
-
-		// popupClass: String
-		//  The popup widget to use. In this case, a calendar with just a Year view.
-		popupClass: "dojox.widget.MonthlyCalendar",
-
-		selector: "date",
-
-		postMixInProperties: function(){
-			this.inherited(arguments);
-			this.constraints.datePattern = "MM";
-		},
-
-		format: function(value){
-			if(!value && value !== 0){
-				return 1;
-			}
-			if(value.getMonth){
-				return value.getMonth() + 1;
-			}
-			return Number(value) + 1;
-		},
-
-		parse: function(value, constraints){
-			return Number(value) - 1;
-		},
-
-		serialize: function(value, constraints){
-			return String(value);
-		},
-
-		validator: function(value){
-			var num = Number(value);
-			var isInt = /(^-?\d\d*$)/.test(String(value));
-			return value == "" || value == null || (isInt && num >= 1 && num <= 12);
-		},
-
-		_setValueAttr: function(value, priorityChange, formattedValue){
-			if(value){
-				if(value.getMonth){
-					value = value.getMonth();
-				}
-			}
-			TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
-		},
-
-		openDropDown: function(){
-			this.inherited(arguments);
-
-			this.dropDown.onValueSelected = lang.hitch(this, function(value){
-				this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
-				setTimeout(lang.hitch(this, "closeDropDown"), 1); // allow focus time to take
-				TextBox.prototype._setValueAttr.call(this, value, true, value);
-			});
-		}
-	}
-);
-
-
-declare( "dojox.form.YearTextBox", DateTextBox,
-	{
-		// summary:
-		//		A validating, serializable, range-bound date text box with a popup calendar that contains only years
-
-		popupClass: "dojox.widget.YearlyCalendar",
-
-		format: function(value){
-			//console.log('Year format ' + value);
-			if(typeof value == "string"){
-				return value;
-			}
-			else if(value.getFullYear){
-				return value.getFullYear();
-			}
-			return value;
-		},
-
-		validator: function(value){
-			return value == "" || value == null || /(^-?\d\d*$)/.test(String(value));
-		},
-
-		_setValueAttr: function(value, priorityChange, formattedValue){
-			if(value){
-				if(value.getFullYear){
-					value = value.getFullYear();
-				}
-			}
-			TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
-		},
-
-		openDropDown: function(){
-			this.inherited(arguments);
-			//console.log('yearly openDropDown and value = ' + this.get('value'));
-
-			this.dropDown.onValueSelected = lang.hitch(this, function(value){
-				this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
-				setTimeout(lang.hitch(this, "closeDropDown"), 1); // allow focus time to take
-				TextBox.prototype._setValueAttr.call(this,value, true, value);
-			});
-		},
-
-		parse: function(/*String*/value, /*dojo.date.locale.__FormatOptions*/constraints){
-			return value || (this._isEmpty(value) ? null : undefined); // Date
-		},
+			_selector: "date",
 
-		filter: function(val){
-			if(val && val.getFullYear){
-				return val.getFullYear().toString();
+			openDropDown: function(){
+				this.inherited(arguments);
+				domStyle.set(this.dropDown.domNode.parentNode, "position", "absolute");
 			}
-			return this.inherited(arguments);
 		}
-	}
-);
-return DateTextBox;
-});
\ No newline at end of file
+	);
+});
diff --git a/dojox/form/DayTextBox.js b/dojox/form/DayTextBox.js
new file mode 100644
index 0000000..1dabad5
--- /dev/null
+++ b/dojox/form/DayTextBox.js
@@ -0,0 +1,52 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojox/widget/DailyCalendar",
+	"dijit/form/TextBox",
+	"./DateTextBox",
+	"dojo/_base/declare"
+	], function(kernel, lang, DailyCalendar, TextBox, DateTextBox, declare){
+		kernel.experimental("dojox/form/DayTextBox");
+	return declare("dojox.form.DayTextBox", DateTextBox,
+		{
+			// summary:
+			//		A validating, serializable, range-bound date text box with a popup calendar that contains just months.
+
+			// popupClass: String
+			//		The popup widget to use. In this case, a calendar with just a Month view.
+			popupClass: DailyCalendar,
+
+			parse: function(displayVal){
+				return displayVal;
+			},
+
+			format: function(value){
+				return value.getDate ? value.getDate() : value;
+			},
+			validator: function(value){
+				var num = Number(value);
+				var isInt = /(^-?\d\d*$)/.test(String(value));
+				return value == "" || value == null || (isInt && num >= 1 && num <= 31);
+			},
+
+			_setValueAttr: function(value, priorityChange, formattedValue){
+				if(value){
+					if(value.getDate){
+						value = value.getDate();
+					}
+				}
+				TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
+			},
+
+			openDropDown: function(){
+				this.inherited(arguments);
+
+				this.dropDown.onValueSelected = lang.hitch(this, function(value){
+					this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
+					setTimeout(lang.hitch(this, "closeDropDown"), 1); // allow focus time to take
+
+					TextBox.prototype._setValueAttr.call(this, String(value.getDate()), true, String(value.getDate()));
+				});
+			}
+		});
+});
diff --git a/dojox/form/DropDownStack.js b/dojox/form/DropDownStack.js
index dabf2e4..34d66aa 100644
--- a/dojox/form/DropDownStack.js
+++ b/dojox/form/DropDownStack.js
@@ -3,12 +3,11 @@ define([
 	"./_SelectStackMixin",
 	"dojo/_base/declare"
 ], function(Select, _SelectStackMixin, declare){
-	/*=====
-		Select = dijit.form.Select;
-		_SelectStackMixin = dojox.form._SelectStackMixin;
-	=====*/
-	return declare("dojox.form.DropDownStack", [ Select, _SelectStackMixin ], {
-	// summary: A dropdown-based select stack.
-
-	});
+/*=====
+return {
+	// summary:
+	//		A dropdown-based select stack.
+};
+=====*/
+	return declare("dojox.form.DropDownStack", [ Select, _SelectStackMixin ]);
 });
\ No newline at end of file
diff --git a/dojox/form/FileInput.js b/dojox/form/FileInput.js
index eabecf7..9a6f7d1 100644
--- a/dojox/form/FileInput.js
+++ b/dojox/form/FileInput.js
@@ -11,33 +11,33 @@ define([
 function(declare, kernel, fx, domAttr, domClass, template, FormWidget, Templated){
 kernel.experimental("dojox.form.FileInput");
 
-	/*=====
-		FormWidget = dijit.form._FormWidget;
-	=====*/
-declare("dojox.form.FileInput", FormWidget,
+return declare("dojox.form.FileInput", FormWidget,
 	{
-	// summary: A styled input type="file"
+	// summary:
+	//		A styled input type="file"
 	//
-	// description: A input type="file" form widget, with a button for uploading to be styled via css,
-	//	a cancel button to clear selection, and FormWidget mixin to provide standard dijit.form.Form
-	//	support (FIXME: maybe not fully implemented)
+	// description:
+	//		A input type="file" form widget, with a button for uploading to be styled via css,
+	//		a cancel button to clear selection, and FormWidget mixin to provide standard dijit.form.Form
+	//		support (FIXME: maybe not fully implemented)
 
 	// label: String
-	//	the title text of the "Browse" button
+	//		the title text of the "Browse" button
 	label: "Browse ...",
 
 	// cancelText: String
-	//	the title of the "Cancel" button
+	//		the title of the "Cancel" button
 	cancelText: "Cancel",
 
 	// name: String
-	//	ugh, this should be pulled from this.domNode
+	//		ugh, this should be pulled from this.domNode
 	name: "uploadFile",
 
 	templateString: template,
 
 	startup: function(){
-		// summary: listen for changes on our real file input
+		// summary:
+		//		listen for changes on our real file input
 		this._listener = this.connect(this.fileInput,"onchange","_matchValue");
 		this._keyListener = this.connect(this.fileInput,"onkeyup","_matchValue");
 	},
@@ -47,7 +47,8 @@ declare("dojox.form.FileInput", FormWidget,
 	postCreate: function(){},
 
 	_matchValue: function(){
-		// summary: set the content of the upper input based on the semi-hidden file input
+		// summary:
+		//		set the content of the upper input based on the semi-hidden file input
 		this.inputNode.value = this.fileInput.value;
 		if(this.inputNode.value){
 			this.cancelNode.style.visibility = "visible";
@@ -55,14 +56,16 @@ declare("dojox.form.FileInput", FormWidget,
 		}
 	},
 
-	setLabel: function(/* String */label,/* String? */cssClass){
-		// summary: method to allow use to change button label
+	setLabel: function(/*String*/ label, /*String?*/ cssClass){
+		// summary:
+		//		method to allow use to change button label
 		this.titleNode.innerHTML = label;
 	},
 
-	reset: function(/* Event */e){
-		// summary: on click of cancel button, since we can't clear the input because of
-		// 	security reasons, we destroy it, and add a new one in it's place.
+	reset: function(/*Event*/ e){
+		// summary:
+		//		on click of cancel button, since we can't clear the input because of
+		//		security reasons, we destroy it, and add a new one in it's place.
 		this.disconnect(this._listener);
 		this.disconnect(this._keyListener);
 		if(this.fileInput){
@@ -73,7 +76,7 @@ declare("dojox.form.FileInput", FormWidget,
 		// should we use cloneNode()? can we?
 		this.fileInput = document.createElement('input');
 		// domAttr.set(this.fileInput,{
-		//	"type":"file", "id":this.id, "name": this.name
+		//		"type":"file", "id":this.id, "name": this.name
 		//});
 		this.fileInput.setAttribute("type","file");
 		this.fileInput.setAttribute("id", this.id);
@@ -88,5 +91,4 @@ declare("dojox.form.FileInput", FormWidget,
 
 });
 
-return dojox.form.FileInput;
 });
diff --git a/dojox/form/FileInputAuto.js b/dojox/form/FileInputAuto.js
index 923de2c..9a07b23 100644
--- a/dojox/form/FileInputAuto.js
+++ b/dojox/form/FileInputAuto.js
@@ -11,47 +11,45 @@ define([
 ], 
 function(declare, lang, fx, win, domStyle, has, template, FileInput, ioIframe){
 
-	/*=====
-		FileInput = dojox.form.FileInput;
-	=====*/
 var FileInputAuto = declare("dojox.form.FileInputAuto", FileInput, 
 	{
-	// summary: An extension on FileInput providing background upload progress
+	// summary:
+	//		An extension on FileInput providing background upload progress
 	//
-	// description: An extended version of FileInput - when the user focuses away from the input
-	//	the selected file is posted via ioIframe to the url. example implementation
-	//	comes with PHP solution for handling upload, and returning required data.
+	// description:
+	//		An extended version of FileInput - when the user focuses away from the input
+	//		the selected file is posted via ioIframe to the url. example implementation
+	//		comes with PHP solution for handling upload, and returning required data.
 	//
-	// notes: the return data from the io.iframe is used to populate the input element with
-	//	data regarding the results. it will be a JSON object, like:
+	//		notes: the return data from the io.iframe is used to populate the input element with
+	//		data regarding the results. it will be a JSON object, like:
 	//
-	//	results = { size: "1024", filename: "file.txt" }
+	//	|	results = { size: "1024", filename: "file.txt" }
 	//
-	//	all the parameters allowed to FileInput apply
+	//		all the parameters allowed to FileInput apply
 
 	// url: String
-	// 	the URL where our background FileUpload will be sent
+	//		the URL where our background FileUpload will be sent
 	url: "",
 
 	// blurDelay: Integer
-	//	time in ms before an un-focused widget will wait before uploading the file to the url="" specified
-	//	default: 2 seconds
+	//		time in ms before an un-focused widget will wait before uploading the file to the url="" specified
+	//		default: 2 seconds
 	blurDelay: 2000,
 
 	// duration: Integer
-	//	The time in ms to use as the generic timing mechanism for the animations
-	//	set to 1 or 0 for "immediate respose"
+	//		The time in ms to use as the generic timing mechanism for the animations
+	//		set to 1 or 0 for "immediate response"
 	duration: 500,
 
 	// uploadMessage: String
-	//
-	//	FIXME: i18n somehow?
+	//		FIXME: i18n somehow?
 	uploadMessage: "Uploading ...",
 	
 	// triggerEvent: String
 	//		Event which triggers the upload. Defaults to onblur, sending the file selected
 	//		'blurDelay' milliseconds after losing focus. Set to "onchange" with a low blurDelay
-	// 		to send files immediately after uploading.
+	//		to send files immediately after uploading.
 	triggerEvent: "onblur",
 	
 	_sent: false,
@@ -60,34 +58,39 @@ var FileInputAuto = declare("dojox.form.FileInputAuto", FileInput,
 	templateString: template,
 	
 	onBeforeSend: function(){
-		// summary: Called immediately before a FileInput sends it's file via io.iframe.send.
+		// summary:
+		//		Called immediately before a FileInput sends it's file via io.iframe.send.
 		//		The return of this function is passed as the `content` member in the io.iframe IOArgs
 		//		object.
 		return {};
 	},
 	
 	startup: function(){
-		// summary: add our extra blur listeners
+		// summary:
+		//		add our extra blur listeners
 		this._blurListener = this.connect(this.fileInput, this.triggerEvent, "_onBlur");
 		this._focusListener = this.connect(this.fileInput, "onfocus", "_onFocus");
 		this.inherited(arguments);
 	},
 
 	_onFocus: function(){
-		// summary: clear the upload timer
+		// summary:
+		//		clear the upload timer
 		if(this._blurTimer){ clearTimeout(this._blurTimer); }
 	},
 
 	_onBlur: function(){
-		// summary: start the upload timer
+		// summary:
+		//		start the upload timer
 		if(this._blurTimer){ clearTimeout(this._blurTimer); }
 		if(!this._sent){
 			this._blurTimer = setTimeout(lang.hitch(this,"_sendFile"),this.blurDelay);
 		}
 	},
 
-	setMessage: function(/*String*/title){
-		// summary: set the text of the progressbar
+	setMessage: function(/*String*/ title){
+		// summary:
+		//		set the text of the progressbar
 		
 		// innerHTML throws errors in IE! so use DOM manipulation instead
 		//this.overlay.innerHTML = title;
@@ -95,8 +98,9 @@ var FileInputAuto = declare("dojox.form.FileInputAuto", FileInput,
 		this.overlay.appendChild(document.createTextNode(title));
 	},
 	
-	_sendFile: function(/* Event */e){
-		// summary: triggers the chain of events needed to upload a file in the background.
+	_sendFile: function(/*Event*/ e){
+		// summary:
+		//		triggers the chain of events needed to upload a file in the background.
 		if(this._sent || this._sending || !this.fileInput.value){ return; }
 
 		this._sending = true;
@@ -135,7 +139,8 @@ var FileInputAuto = declare("dojox.form.FileInputAuto", FileInput,
 	},
 	
 	_handleSend: function(data,ioArgs){
-		// summary: The callback to toggle the progressbar, and fire the user-defined callback
+		// summary:
+		//		The callback to toggle the progressbar, and fire the user-defined callback
 
 		// innerHTML throws errors in IE! so use DOM manipulation instead
 		this.overlay.removeChild(this.overlay.firstChild);
@@ -164,7 +169,8 @@ var FileInputAuto = declare("dojox.form.FileInputAuto", FileInput,
 	},
 
 	reset: function(e){
-		// summary: accomodate our extra focusListeners
+		// summary:
+		//		accommodate our extra focusListeners
 		if(this._blurTimer){ clearTimeout(this._blurTimer); }
 
 		this.disconnect(this._blurListener);
@@ -180,21 +186,26 @@ var FileInputAuto = declare("dojox.form.FileInputAuto", FileInput,
 	},
 
 	onComplete: function(data,ioArgs,widgetRef){
-		// summary: stub function fired when an upload has finished.
-		// data: the raw data found in the first [TEXTAREA] tag of the post url
-		// ioArgs: the Deferred data being passed from the handle: callback
-		// widgetRef: this widget pointer, so you can set this.overlay to a completed/error message easily
+		// summary:
+		//		stub function fired when an upload has finished.
+		// data:
+		//		the raw data found in the first [TEXTAREA] tag of the post url
+		// ioArgs:
+		//		the Deferred data being passed from the handle: callback
+		// widgetRef:
+		//		this widget pointer, so you can set this.overlay to a completed/error message easily
 	}
 });
 
-declare("dojox.form.FileInputBlind", FileInputAuto,
-	{
-	// summary: An extended version of dojox.form.FileInputAuto
-	//	that does not display an input node, but rather only a button
-	// 	and otherwise behaves just like FileInputAuto
+declare("dojox.form.FileInputBlind", FileInputAuto, {
+	// summary:
+	//		An extended version of dojox.form.FileInputAuto
+	//		that does not display an input node, but rather only a button
+	//		and otherwise behaves just like FileInputAuto
 	
 	startup: function(){
-		// summary: hide our fileInput input field
+		// summary:
+		//		hide our fileInput input field
 		this.inherited(arguments);
 		this._off = domStyle.get(this.inputNode,"width");
 		this.inputNode.style.display = "none";
@@ -202,7 +213,8 @@ declare("dojox.form.FileInputBlind", FileInputAuto,
 	},
 	
 	_fixPosition: function(){
-		// summary: in this case, set the button under where the visible button is
+		// summary:
+		//		in this case, set the button under where the visible button is
 		if(has('ie')){
 			domStyle.set(this.fileInput,"width","1px");
 		}else{
@@ -211,7 +223,8 @@ declare("dojox.form.FileInputBlind", FileInputAuto,
 	},
 
 	reset: function(e){
-		// summary: onclick, we need to reposition our newly created input type="file"
+		// summary:
+		//		onclick, we need to reposition our newly created input type="file"
 		this.inherited(arguments);
 		this._fixPosition();
 	}
diff --git a/dojox/form/FileInputBlind.js b/dojox/form/FileInputBlind.js
index fd814cc..69322d1 100644
--- a/dojox/form/FileInputBlind.js
+++ b/dojox/form/FileInputBlind.js
@@ -2,7 +2,7 @@ define([
 	"dojo/_base/lang",
 	"dojox/form/FileInputAuto"
 ], function(lang, FileInputAuto){
-// FIXME: break out code in 2.0. Leave this stub in place until then. Leave FileInputBlind code in Auto.js for
+// TODO: break out code in 2.0. Leave this stub in place until then. Leave FileInputBlind code in Auto.js for
 // backwards compatibility.
 	lang.setObject("dojox.form.FileInputBlind", FileInputAuto);
 	return FileInputAuto;
diff --git a/dojox/form/FilePickerTextBox.js b/dojox/form/FilePickerTextBox.js
index 7c7fec2..703ff25 100644
--- a/dojox/form/FilePickerTextBox.js
+++ b/dojox/form/FilePickerTextBox.js
@@ -14,12 +14,7 @@ define([
 	"dojo/keys" // keys
 ], function(lang, array, event, windowUtils, focus, registry, _TextBoxMixin, ValidationTextBox, _HasDropDown, FilePicker, template, declare, keys){
 
-	/*=====
-		ValidationTextBox = dijit.form.ValidationTextBox;
-		_HasDropDown = dijit._HasDropDown;
-	=====*/
-return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown],
-	{
+	return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown], {
 		// summary:
 		//		A validating text box tied to a file picker popup
 
@@ -37,8 +32,8 @@ return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown
 		valueItem: null,
 
 		// numPanes: number
-		//	The number of panes to display in our box (if we don't have any
-		//	minPaneWidth specified by our constraints)
+		//		The number of panes to display in our box (if we don't have any
+		//		minPaneWidth specified by our constraints)
 		numPanes: 2.25,
 
 		postMixInProperties: function(){
@@ -57,8 +52,9 @@ return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown
 			});
 		},
 
-		_setValueAttr: function(/*string*/value, priorityChange, fromWidget){
-			// summary: sets the value of this widget
+		_setValueAttr: function(/*String*/ value, priorityChange, fromWidget){
+			// summary:
+			//		sets the value of this widget
 			if(!this._searchInProgress){
 				this.inherited(arguments);
 				value = value || "";
@@ -72,8 +68,9 @@ return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown
 			}
 		},
 
-		_onWidgetChange: function(/*item*/item){
-			// summary: called when the path gets changed in the dropdown
+		_onWidgetChange: function(/*item*/ item){
+			// summary:
+			//		called when the path gets changed in the dropdown
 			if(!item && this.focusNode.value){
 				this._hasValidPath = false;
 				this.focusNode.value = "";
@@ -116,7 +113,8 @@ return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown
 		},
 
 		_focusBlur: function(/*Event*/ e){
-			// summary: called when the focus node gets blurred
+			// summary:
+			//		called when the focus node gets blurred
 			if(e.explicitOriginalTarget == this.focusNode && !this._allowBlur){
 				window.setTimeout(lang.hitch(this, function(){
 					if(!this._allowBlur){
@@ -130,7 +128,8 @@ return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown
 		},
 
 		_focusFocus: function(/*Event*/ e){
-			// summary: called when the focus node gets focus
+			// summary:
+			//		called when the focus node gets focus
 			if(this._menuFocus){
 				this.dropDown._updateClass(this._menuFocus, "Item", {"Hover": false});
 			}
@@ -149,14 +148,16 @@ return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown
 		},
 
 		_onBlur: function(){
-			// summary: called when focus is shifted away from this widget
+			// summary:
+			//		called when focus is shifted away from this widget
 			this._allowBlur = true;
 			delete this.dropDown._savedFocus;
 			this.inherited(arguments);
 		},
 
 		_setBlurValue: function(){
-			// summary: sets the value of the widget once focus has left
+			// summary:
+			//		sets the value of the widget once focus has left
 			if(this.dropDown && !this._settingBlurValue){
 				this._settingBlurValue = true;
 				this.set("value", this.focusNode.value);
@@ -166,8 +167,8 @@ return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown
 			}
 		},
 
-		parse: function(/* String */ value, /* Object */ constraints){
-			//	summary:
+		parse: function(/*String*/ value, /*Object*/ constraints){
+			// summary:
 			//		Function to convert a formatted string to a value - we use
 			//		it to verify that it *really* is a valid value
 			if(this._hasValidPath || this._hasSelection){
@@ -193,7 +194,8 @@ return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown
 		},
 
 		_startSearchFromInput: function(){
-			// summary: kicks off a search based off the current text value of the widget
+			// summary:
+			//		kicks off a search based off the current text value of the widget
 			var dd = this.dropDown, fn = this.focusNode;
 			var val = fn.value, oVal = val, topDir = dd.topDir;
 			if(this._hasSelection){
@@ -286,7 +288,8 @@ return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown
 		},
 
 		_onKey: function(/*Event*/ e){
-			// summary: callback when the user presses a key on menu popup node
+			// summary:
+			//		callback when the user presses a key on menu popup node
 			if(this.disabled || this.readOnly){ return; }
 			var c = e.charOrCode;
 			if(c==keys.DOWN_ARROW){
@@ -323,6 +326,5 @@ return declare( "dojox.form.FilePickerTextBox", [ValidationTextBox, _HasDropDown
 				this._searchTimer = window.setTimeout(lang.hitch(this, "_startSearchFromInput"), this.searchDelay + 1);
 			}
 		}
-	}
-);
+	});
 });
\ No newline at end of file
diff --git a/dojox/form/FileUploader.js b/dojox/form/FileUploader.js
index c75e5ad..70e850c 100644
--- a/dojox/form/FileUploader.js
+++ b/dojox/form/FileUploader.js
@@ -7,6 +7,7 @@ define([
 	"dojo/_base/window",
 	"dojo/_base/sniff",
 	"dojo/query",
+	"dojo/dom",
 	"dojo/dom-style",
 	"dojo/dom-geometry",
 	"dojo/dom-attr",
@@ -24,32 +25,25 @@ define([
 	"dojox/embed/Flash",
 	"dojox/embed/flashVars",
 	"dojox/html/styles"
-],function(kernel, declare, lang, array, connect, win, has, query, domStyle, domGeometry, domAttr, domClass, domConstruct, domForm, config, manager, ioIframe, Color, unloadUtils, Widget, TemplatedMixin, Contained, embedFlash, embedFlashVars, htmlStyles){
+],function(kernel, declare, lang, array, connect, win, has, query, dom, domStyle, domGeometry, domAttr, domClass, domConstruct, domForm, config, manager, ioIframe, Color, unloadUtils, Widget, TemplatedMixin, Contained, embedFlash, embedFlashVars, htmlStyles){
 
 kernel.deprecated("dojox.form.FileUploader", "Use dojox.form.Uploader", "2.0");
 
 	//	Usage Notes:
 	//		To center text vertically, use vertical-align:middle;
-	//			which emulates a boxModel button. Using line-height to center text
-	//			can cause height problems in IE6
+	//		which emulates a boxModel button. Using line-height to center text
+	//		can cause height problems in IE6
 
-
-	/*=====
-		Widget = dijit._Widget;
-		TemplatedMixin = dijit._TemplatedMixin;
-		Contained = dijit._Contained;
-	=====*/
-declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
+return declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	// version:
 	//		1.5 (deprecated)
 	// summary:
-	// 		Handles File Uploading to a server (PHP script included for testing)
+	//		Handles File Uploading to a server (PHP script included for testing)
 	//
 	//		FileUploader is now a WIDGET. You do not have to pass a button
 	//		in. Passing a button is still supported until version 1.5 to maintain
-	//		backwards compatibility, but it is not reccomended. Just create your
+	//		backwards compatibility, but it is not recommended. Just create your
 	//		uploader like any other widget.
-	//
 	// description:
 	//		If the correct version of Flash Player is available (> 9.0) , a SWF
 	//		is used. If Flash Player is not installed or is outdated, a typical
@@ -67,30 +61,33 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	//		The HTML button is created in a new way and it is now inline as is the
 	//		FLash button. Styling is much easier and more versatile.
 	//
-	//	Dependencies:
+	//		###Dependencies
+	//
 	//		FileUploader no longer uses FileInput.css. It now uses FileUploader.css
 	//		See requires for JavaScript dependencies.
 	//
-	//	NEW FEATURES -
-	//		There are a ton of features and fixes in this version.
-	//			Disabled: Can be toggled with widget.attr("disable", true|false)
-	//			Submit: A convenience method has been added for if the uploader is in a form.
-	//					Instead of submitting the form, call uploader.submit(theForm), and the
-	//					Uploader will handle all of the form values and post the data.
-	//			Selected List: If passing the ID of a container, the Uploaders will populate it
-	//					with the selected files.
-	//			Deleting Files: You can now delete pending files.
-	//			Progress Built in: showProgress:true will change the button to a progress
-	//					bar on upload.
-	//			Progress Attach: Passing progressWidgetId will tell the Uploader of a progress
-	//					widget. If the Progress widget is initially hidden, it will change to
-	//					visible and then restored after upload.
-	//			A11Y: The Flash button can be accessed with the TAB key. (The HTML cannot due
-	//					to browser limtations)
-	//			Deferred Uploading: (Flash only) throttles the upload to one file at a time
+	//		###NEW FEATURES
+	//
+	//		There are a ton of features and fixes in this version:
+	//
+	//		- Disabled: Can be toggled with widget.set("disabled", true|false)
+	//		- Submit: A convenience method has been added for if the uploader is in a form.
+	//			Instead of submitting the form, call uploader.submit(theForm), and the
+	//			Uploader will handle all of the form values and post the data.
+	//		- Selected List: If passing the ID of a container, the Uploaders will populate it
+	//			with the selected files.
+	//		- Deleting Files: You can now delete pending files.
+	//		- Progress Built in: showProgress:true will change the button to a progress
+	//			bar on upload.
+	//		- Progress Attach: Passing progressWidgetId will tell the Uploader of a progress
+	//			widget. If the Progress widget is initially hidden, it will change to
+	//			visible and then restored after upload.
+	//		- A11Y: The Flash button can be accessed with the TAB key. (The HTML cannot due
+	//			to browser limitations)
+	//		- Deferred Uploading: (Flash only) throttles the upload to one file at a time
 	//
+	//		###CDN USERS
 	//
-	//	CDN USERS -
 	//		FileUpload now works with the CDN but with limitations. The SWF must
 	//		be from the same domain as the HTML page. 'swfPath' has been exposed
 	//		so that you may link to that file (could of course be the same SWF in
@@ -98,24 +95,27 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	//		CDN server. This would require a special XML file that would allow
 	//		access to your server, and the logistics to that is impossible.
 	//
-	//	LIMITATIONS
+	//		###LIMITATIONS
+	//
 	//		- This is not designed to be a part of a form, it contains its own. (See submit())
 	//		- Currently does not in a Dialog box or a Tab where it is not initially visible,
 	//		- The default style inherits font sizes - but a parent container should have a font size
 	//			set somewhere of the results could be inconsistent.
 	//
-	//	OPERA USERS -
+	//		###OPERA USERS
+	//
 	//		It works better than the 1.3 version. fileInputs apperantly can't have opacity
 	//		set to zero. The Flash uploader works but files are auto-uploaded. Must be a
 	//		flashVar problem.
 	//
-	//	Safari Bug note:
-	//	The bug is in the way Safari handles the connection:
+	//		###Safari Bug note:
+	//
+	//		The bug is in the way Safari handles the connection:
 	//		https://bugs.webkit.org/show_bug.cgi?id=5760
 	//		I added this to the virtual host in the Apache conf file, and now it
 	//		works like a charm:
-	//		BrowserMatch Safari nokeepalive
-	//
+	//	|	BrowserMatch Safari nokeepalive
+
 	swfPath: config.uploaderPath || require.toUrl("dojox/form/resources/fileuploader.swf"),
 
 
@@ -125,22 +125,24 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	//		The url targeted for upload. An absolute URL is preferred. Relative URLs are
 	//		changed to absolute.
 	uploadUrl: "",
-	//
-	//	isDebug: Boolean
+
+	// isDebug: Boolean
 	//		If true, outputs traces from the SWF to console. What exactly gets passed
 	//		is very relative, and depends upon what traces have been left in the DEFT SWF.
 	isDebug:false,
-	//
-	//	devMode: Boolean.
+
+	// devMode: Boolean
 	//		Re-implemented. devMode increases the logging, adding style tracing from the SWF.
 	devMode:false,
-	//
-	//	id: String
+
+	/*=====
+	// id: String
 	//		The object id, just like any other widget in Dojo. However, this id
 	//		is also used as a reference for the SWF
-	// id: "",
-	//
-	//	baseClass: String
+	id: "",
+	=====*/
+
+	// baseClass: String
 	//		The name of the class that will style the button in a "normal" state.
 	//		If baseClass is not defined, 'class' will be used.
 	//		NOTE: By default the uploader will be styled like a dijit buttons and
@@ -149,44 +151,44 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	//		overwrite baseClass, you should overwrite the remaing state classes
 	//		that follow) as well.
 	baseClass:"dojoxUploaderNorm",
-	//
-	//	hoverClass: String
+
+	// hoverClass: String
 	//		The name of the class that will style the button in a "hover" state. A specific
 	//		class should be made to do this. Do not rely on a target like button:hover{...}
 	hoverClass:"dojoxUploaderHover",
-	//
-	//	activeClass: String
+
+	// activeClass: String
 	//		The name of the class that will style the button in a "press" state. A specific
 	//		class should be made to do this. Do not rely on a target like button:active{...}
 	activeClass:"dojoxUploaderActive",
-	//
-	//	disabledClass: String
+
+	// disabledClass: String
 	//		The name of the class that will style the button when its disabled.
 	disabledClass:"dojoxUploaderDisabled",
-	//
-	//	force: String
+
+	// force: String
 	//		Use "flash" to always use Flash (and hopefully force the user to download the plugin
 	//		if they don't have it). Use "html" to always use the HTML uploader. An empty string
 	//		(default) will check for the right version of Flash and use HTML if not available.
 	force:"",
-	//
-	//	uploaderType: [readonly] String
+
+	// uploaderType: [readonly] String
 	//		Internal. What type of uploader is being used: "flash" or "html"
 	uploaderType:"",
-	//
-	//	flashObject: [readonly] dojox.embed.Flash
+
+	// flashObject: [readonly] dojox.embed.Flash
 	//		The object that creates the SWF embed object. Mostly Internal.
 	flashObject: null,
-	//
-	//	flashMovie: [readonly] Function
+
+	// flashMovie: [readonly] Function
 	//		The SWF. Mostly Internal.
 	flashMovie: null,
-	//
-	//	insideNode: [readonly] HTMLNode
+
+	// insideNode: [readonly] HTMLNode
 	//		The div that holds the SWF and form/fileInput
 	insideNode: null,
-	//
-	//	deferredUploading: Number (1 - X)
+
+	// deferredUploading: Number (1 - X)
 	//		(Flash only) throttles the upload to a certain amount of files at a time.
 	//		By default, Flash uploads file one at a time to the server, but in parallel.
 	//		Firefox will try to queue all files at once, leading to problems. Set this
@@ -194,88 +196,91 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	//		Generally, 1 should work fine, but you can experiment with queuing more than
 	//		one at a time.
 	//		This is of course ignored if selectMultipleFiles equals false.
-	deferredUploading:1,
-	//
-	//	fileListId: String
+	deferredUploading: 1,
+
+	// fileListId: String
 	//		The id of a dom node to be used as a container for the pending file list.
 	fileListId:"",
-	//
-	//	uploadOnChange: Boolean
-	//		If true, uploads imediately after a file has been selected. If false,
+
+	// uploadOnChange: Boolean
+	//		If true, uploads immediately after a file has been selected. If false,
 	//		waits for upload() to be called.
 	uploadOnChange: false,
-	//
-	//	selectMultipleFiles: Boolean
+
+	// selectMultipleFiles: Boolean
 	//		If true and flash mode, multiple files may be selected from the dialog.
 	//		If html mode, files are not uploaded until upload() is called. The references
 	//		to each file is incremented:uploadedfile0, uploadedfile1, uploadedfile2... etc.
 	selectMultipleFiles: true,
-	//
-	//	htmlFieldName: String
+
+	// htmlFieldName: String
 	//		The name of the field of the fileInput that the server is expecting
 	htmlFieldName:"uploadedfile",
-	//
-	//	flashFieldName: String
+
+	// flashFieldName: String
 	//		The name of the field of the flash uploaded files that the server is expecting
 	flashFieldName:"flashUploadFiles",
-	//
+
 	// fileMask:  Array[ Array[Description, FileTypes], Array[...]...]
-	// 		(an array, or an array of arrays)
+	//		(an array, or an array of arrays)
 	//		Restrict file selection to certain file types
-	// 		Empty array defaults to "All Files"
-	// example:
-	//	fileMask = ["Images", "*.jpg;*.jpeg;*.gif;*.png"]
-	//	or
-	//	fileMask = [
-	//		["Jpeg File", 	"*.jpg;*.jpeg"],
-	//		["GIF File", 	"*.gif"],
-	//		["PNG File", 	"*.png"],
-	//		["All Images", 	"*.jpg;*.jpeg;*.gif;*.png"],
-	//	]
-	//	NOTE: MacType is not supported, as it does not work very well.
-	//			fileMask will work on a Mac, but differently than
-	//			Windows.
-	fileMask: null,
+	//		Empty array defaults to "All Files"
+	//
+	//		example:
 	//
-	//	minFlashVersion: Number
+	//	|	fileMask = ["Images", "*.jpg;*.jpeg;*.gif;*.png"]
+	//		or
+	//	|	fileMask = [
+	//	|		["Jpeg File", 	"*.jpg;*.jpeg"],
+	//	|		["GIF File", 	"*.gif"],
+	//	|		["PNG File", 	"*.png"],
+	//	|		["All Images", 	"*.jpg;*.jpeg;*.gif;*.png"],
+	//	|	]
+	//
+	//		NOTE: MacType is not supported, as it does not work very well.
+	//		fileMask will work on a Mac, but differently than
+	//		Windows.
+	fileMask: null,
+
+	// minFlashVersion: Number
 	//		The minimum of version of Flash player to target. 0 would always install Flash, 100
 	//		would never install it. The Flash Player has supported multiple uploads since
 	//		version 8, so it could go as low as that safely.
 	minFlashVersion:9,
-	//
-	//	tabIndex: Number|String
+
+	// tabIndex: Number|String
 	//		The tab order in the DOM. Only supported by Flash. HTML Uploaders have security
 	//		protection to prevent you from tabbing to the uploader. Stupid.
 	tabIndex:-1,
-	//
-	//	showProgress: Boolean
+
+	// showProgress: Boolean
 	//		If true, the button changes to a progress bar during upload.
 	showProgress:false,
-	//
-	//	progressMessage: String
+
+	// progressMessage: String
 	//		The message shown while the button is changed to a progress bar
 	progressMessage:"Loading",
-	//
-	//	progressBackgroundUrl: String|Uri
+
+	// progressBackgroundUrl: String|Uri
 	//		The background image to use for the button-progress
 	progressBackgroundUrl:require.toUrl("dijit/themes/tundra/images/buttonActive.png"),
-	//
-	//	progressBackgroundColor: String|Number
+
+	// progressBackgroundColor: String|Number
 	//		The background color to use for the button-progress
 	progressBackgroundColor:"#ededed",
-	//
-	//	progressWidgetId:String
+
+	// progressWidgetId:String
 	//		The widget id of a Dijit Progress bar. The Uploader will bind to it and update it
 	//		automatically.
 	progressWidgetId:"",
-	//
+
 	// skipServerCheck: Boolean
-	// 		If true, will not verify that the server was sent the correct format.
+	//		If true, will not verify that the server was sent the correct format.
 	//		This can be safely set to true. The purpose of the server side check
 	//		is mainly to show the dev if they've implemented the different returns
 	//		correctly.
 	skipServerCheck:false,
-	//
+
 	// serverTimeout:Number (milliseconds)
 	//		The amount of time given to the uploaded file
 	//		to wait for a server response. After this amount
@@ -285,7 +290,7 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 
 
 	log: function(){
-		//	summary:
+		// summary:
 		//		Due to the excessive logging necessary to make this code happen,
 		//		It's easier to turn it on and off here in one place.
 		//		Also helpful if there are multiple uploaders on one page.
@@ -356,7 +361,7 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 		//		changed to display:block. Note if the node is in
 		//		a widget that has an onShow event, this is
 		//		overridden.
-		//
+
 		if(!node){ return null; }
 		var hidden = null;
 		var p = node.parentNode;
@@ -449,7 +454,6 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 			this.log("norm:", this.norm)
 			this.log("over:", this.over)
 			this.log("down:", this.down)
-
 		}
 	},
 
@@ -457,7 +461,7 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 		// summary:
 		//		Internal.
 		//		Set up internal dom nodes for button construction.
-		//
+
 		domStyle.set(this.domNode, {
 			width:this.fhtml.nr.w+"px",
 			height:(this.fhtml.nr.h)+"px",
@@ -510,10 +514,10 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 			this.insideNode.innerHTML = this.fhtml.cn;
 		}catch(e){
 			// You have got to be kidding me. IE does us he favor of checking that
-			//	we aren't inserting the improper type of content with innerHTML into
-			//	an inline element. Alert us with an "Unknown Runtime Error". You can't
-			//	MAKE this stuff up.
-			//
+			// we aren't inserting the improper type of content with innerHTML into
+			// an inline element. Alert us with an "Unknown Runtime Error". You can't
+			// MAKE this stuff up.
+
 			if(this.uploaderType == "flash"){
 			this.insideNode = this.insideNode.parentNode.removeChild(this.insideNode);
 				win.body().appendChild(this.insideNode);
@@ -544,50 +548,50 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	// onMouseOut
 
 	onChange: function(dataArray){
-		//	summary:
-		// 		stub to connect
-		// 		Fires when files are selected
-		// 		Event is an array of last files selected
+		// summary:
+		//		stub to connect
+		//		Fires when files are selected
+		//		Event is an array of last files selected
 	},
 
 	onProgress: function(dataArray){
 		// summary:
-		// 		Stub to connect
-		// 		Fires as progress returns from SWF
-		// 		Event is an array of all files uploading
+		//		Stub to connect
+		//		Fires as progress returns from SWF
+		//		Event is an array of all files uploading
 		//		Can be connected to for HTML uploader,
 		//		but will not return anything.
 	},
 
 	onComplete: function(dataArray){
 		// summary:
-		// 		stub to connect
-		// 		Fires when all files have uploaded
-		// 		Event is an array of all files
+		//		stub to connect
+		//		Fires when all files have uploaded
+		//		Event is an array of all files
 	},
 
 	onCancel: function(){
 		// summary:
-		// 		Stub to connect
-		// 		Fires when dialog box has been closed
+		//		Stub to connect
+		//		Fires when dialog box has been closed
 		//		without a file selection
 	},
 
-	onError: function(/* Object or String */evtObject){
+	onError: function(/*Object or String*/ evtObject){
 		// summary:
 		//		Fires on errors
-		//
-		//FIXME: Unsure of a standard form for receiving errors
+
+		// FIXME: Unsure of a standard form for receiving errors
 	},
 
-	onReady: function(/* dojox.form.FileUploader */ uploader){
+	onReady: function(/*dojox.form.FileUploader*/ uploader){
 		// summary:
 		//		Stub - Fired when embedFlash has created the
 		//		Flash object, but it has not necessarilly finished
 		//		downloading, and is ready to be communicated with.
 	},
 
-	onLoad: function(/* dojox.form.FileUploader */ uploader){
+	onLoad: function(/*dojox.form.FileUploader*/ uploader){
 		// summary:
 		//		Stub - SWF has been downloaded 100%.
 	},
@@ -595,21 +599,21 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	/*************************
 	 *	   Public Methods	 *
 	 *************************/
-	submit: function(/* form node ? */form){
+	submit: function(/*form node ?*/ form){
 		// summary:
 		//		If FileUploader is in a form, and other data should be sent
 		//		along with the files, use this instead of form submit.
-		//
+
 		var data = form ? domForm.toObject(form) : null;
 		this.upload(data);
 		return false; // Boolean
 	},
-	upload: function(/*Object ? */data){
+	upload: function(/*Object ? */ data){
 		// summary:
-		// 		When called, begins file upload
-		//	data: Object
+		//		When called, begins file upload
+		// data: Object
 		//		postData to be sent to server
-		//
+
 		if(!this.fileList.length){
 			return false;
 		}
@@ -653,19 +657,19 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 		// prevent form submit
 		return false;
 	},
-	removeFile: function(/*String*/name, /*Boolean*/noListEdit){
+	removeFile: function(/*String*/ name, /*Boolean*/ noListEdit){
 		// summary:
 		//		Removes a file from the pending file list.
 		//		Removes pending data from the Flash movie
 		//		and fileInputes from the HTML uploader.
 		//		If a file container node is bound, the file
 		//		will also be removed.
-		// name:String
+		// name: String
 		//		The name of the file to be removed. Typically the file name,
 		//		such as: picture01.png
-		// noListEdit:Boolean
+		// noListEdit: Boolean
 		//		Internal. If true don't remove files from list.
-		//
+
 		var i;
 		for(i = 0; i < this.fileList.length; i++){
 			if(this.fileList[i].name == name){
@@ -688,7 +692,7 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	},
 
 	destroy: function(){
-		//	summary:
+		// summary:
 		//		Destroys uploader button
 		if(this.uploaderType == "flash" && !this.flashMovie){
 			this._cons.push(connect.connect(this, "onLoad", this, "destroy"));
@@ -712,10 +716,10 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	/*************************
 	 *	   Private Events	 *
 	 *************************/
-	_displayProgress: function(/*Boolean or Number */display){
+	_displayProgress: function(/*Boolean or Number */ display){
 		// summary:
 		//		Shows and updates the built-in progress bar.
-		//
+
 		if(display === true){
 			if(this.uploaderType == "flash"){
 				domStyle.set(this.insideNode,"top", "-2500px");
@@ -776,7 +780,7 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 		//		Internal only. If there is a file list, adds a file to it.
 		//		If you need to use a function such as this, connect to
 		//		onChange and update outside of this widget.
-		//
+
 		if(this.fileListId){
 			var str = '';
 			array.forEach(this.fileList, function(d){
@@ -821,7 +825,7 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	_complete: function(dataArray){
 		// summary:
 		//		Internal. Handles tasks after files have finished uploading
-		//
+
 		dataArray = lang.isArray(dataArray) ? dataArray : [dataArray];
 
 		// Yes. Yes I do have to do three loops here. ugh.
@@ -947,11 +951,11 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 		// summary:
 		//		Internal. You could use this, but you should use upload() or submit();
 		//		which can also handle the post data.
-		//
+
 		// NOTE on deferredUploading:
-		// 		This is not enabled for HTML. Workaround would be to force
+		//		This is not enabled for HTML. Workaround would be to force
 		//		singleFile uploads.
-		//	TODO:
+		// TODO:
 		//		Investigate removing fileInputs and resending form
 		//		multiple times adding each fileInput
 		//
@@ -1086,7 +1090,6 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	_buildForm: function(){
 		// summary:
 		//		Build the form that holds the fileInput
-		//
 
 		if(this._formNode){ return; }
 
@@ -1107,7 +1110,7 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	_buildFileInput: function(){
 		// summary:
 		//		Build the fileInput field
-		//
+
 		if(this._fileInput){
 			this._disconnect();
 			// FIXME:
@@ -1215,9 +1218,8 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 		if(this.uploadUrl){
 			if(this.uploadUrl.toLowerCase().indexOf("http")<0 && this.uploadUrl.indexOf("/")!=0){
 				// Appears to be a relative path. Attempt to
-				//	convert it to absolute, so it will better
-				//target the SWF.
-				//
+				// convert it to absolute, so it will better
+				// target the SWF.
 				var loc = window.location.href.split("/");
 				loc.pop();
 				loc = loc.join("/")+"/";
@@ -1283,14 +1285,14 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 	},
 
 	_connectFlash: function(){
-		// 	summary:
+		// summary:
 		//		Subscribing to published topics coming from the
 		//		Flash uploader.
-		// 	description:
-		//		Sacrificing some readbilty for compactness. this.id
+		//
+		//		Sacrificing some readability for compactness. this.id
 		//		will be on the beginning of the topic, so more than
 		//		one uploader can be on a page and can have unique calls.
-		//
+
 		this._doSub("/filesSelected", "_change");
 		this._doSub("/filesUploaded", "_complete");
 		this._doSub("/filesProgress", "_progress");
@@ -1303,8 +1305,7 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 		this._doSub("/out", "onMouseOut");
 
 		this.connect(this.domNode, "focus", function(){
-			// TODO: some kind of indicator that the Flash button
-			//	is in focus
+			// TODO: some kind of indicator that the Flash button is in focus
 			this.flashMovie.focus();
 			this.flashMovie.doFocus();
 		});
@@ -1375,7 +1376,7 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 
 	getText: function(node){
 		// Get the text of the button. It's possible to use HTML in the Flash Button,
-		//	but the results are not spectacular.
+		// but the results are not spectacular.
 		var cn = lang.trim(node.innerHTML);
 		if(cn.indexOf("<") >- 1){
 			cn = escape(cn);
@@ -1385,7 +1386,7 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 
 	getStyle: function(node){
 		// getting the style of a node. Using very abbreviated characters which the
-		//	Flash movie understands.
+		// Flash movie understands.
 		var o = {};
 		var dim = domGeometry.getContentBox(node);
 		var pad = domGeometry.getPadExtents(node);
@@ -1440,5 +1441,5 @@ declare("dojox.form.FileUploader", [Widget, TemplatedMixin, Contained], {
 		return style;
 	}
 });
-return dojox.form.FileUploader;
+
 });
diff --git a/dojox/form/ListInput.js b/dojox/form/ListInput.js
index a9c8332..8e099c7 100755
--- a/dojox/form/ListInput.js
+++ b/dojox/form/ListInput.js
@@ -21,12 +21,15 @@ define([
 ], function(kernel, lang, array, jsonUtil, fx, win, connect, domClass, domStyle, domConstruct, domGeometry, keys, Widget, TemplatedMixin, FormValueWidget, ValidationTextBox, InlineEditBox, i18nCommon, declare){
 kernel.experimental("dojox.form.ListInput");
 
-	/*=====
-		Widget = dijit._Widget;
-		Templated = dijit._TemplatedMixin;
-		FormValueWidget = dijit.form._FormValueWidget;
-		ValidationTextBox = dijit.form.ValidationTextBox;
-	=====*/
+/*=====
+var __Constraints = {
+	 // locale: String
+	 //		locale used for validation, picks up value from this widget's lang attribute
+	 // _flags_: anything
+	 //		various flags passed to pattern function
+};
+=====*/
+
 var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 	{
 	// summary:
@@ -50,15 +53,15 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 	//		Class which will be used to create the input box. You can implements yours.
 	//		It must be a widget, focusNode or domNode must have "onkeydown" event
 	//		It must have .attr("value") to get value
-	//		It also must impement an (or more) handler for the "onChange" method
+	//		It also must implement an (or more) handler for the "onChange" method
 	inputClass: "dojox.form._ListInputInputBox",
 
-	// inputHandler: String || Array
+	// inputHandler: String|Array
 	//		The widget will connect on all handler to check input value
 	//		You can use comma separated list
 	inputHandler: "onChange",
 
-	// inputProperties: String || Object
+	// inputProperties: String|Object
 	//		Properties used to create input box
 	//		If String, it must be a valid JSON
 	inputProperties: {
@@ -66,7 +69,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 	},
 
 	// submitOnlyValidValue: Boolean
-	//		If true, only valid value will be submited with form
+	//		If true, only valid value will be submitted with form
 	submitOnlyValidValue:true,
 
 	// useOnBlur: Boolean
@@ -75,12 +78,12 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 
 	// readOnlyInput: Boolean
 	//		if false, the list will be editable
-	//		Can only be set when instanciate
+	//		Can only be set when instantiate
 	readOnlyInput: false,
 
 	// maxItems: Int
 	//		Specify max item the list can have
-	//		null = infiny
+	//		null = infinity
 	maxItems: null,
 
 	// showCloseButtonWhenValid: Boolean
@@ -96,12 +99,12 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 	//		Do not specify both regExp and regExpGen
 	regExp: ".*", //"[a-zA-Z.-_]+@[a-zA-Z.-_]+.[a-zA-Z]+",
 
-	// delimiter: String || Array
-	//		delimiter for the string. Every match will be splitted
-	//		The string can contain only one delimiter
+	// delimiter: String|Array
+	//		delimiter for the string. Every match will be splitted.
+	//		The string can contain only one delimiter.
 	delimiter: ",",
 
-	// constraints: ValidationTextBox.__Constraints
+	// constraints: __Constraints
 	//		user-defined object needed to pass parameters to the validator functions
 	constraints: {},
 
@@ -113,8 +116,10 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 
 	templateString: "<div dojoAttachPoint=\"focusNode\" class=\"dijit dijitReset dijitLeft dojoxListInput\"><select dojoAttachpoint=\"_selectNode\" multiple=\"multiple\" class=\"dijitHidden\" ${!nameAttrSetting}></select><ul dojoAttachPoint=\"_listInput\"><li dojoAttachEvent=\"onclick: _onClick\" class=\"dijitInputField dojoxListInputNode dijitHidden\" dojoAttachPoint=\"_inputNode\"></li></ul></div>",
 
+	_setNameAttr: "_selectNode",
+
 	// useAnim: Boolean
-	//		If true, then item will use an anime to show hide itself
+	//		If true, then item will use an animation to show hide itself
 	useAnim: true,
 
 	// duration: Integer
@@ -131,12 +136,12 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 
 	// readOnlyItem: Boolean
 	//		If true, items can be edited
-	//		Can only be set when instanciate
+	//		Can only be set when instantiate
 	readOnlyItem: false,
 
 	// useArrowForEdit: Boolean
 	//		If true, arraow left and right can be used for editing
-	//		Can only be set when instanciate
+	//		Can only be set when instantiate
 	useArrowForEdit: true,
 
 	// _items: Array
@@ -167,7 +172,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		this._createInputBox();
 	},
 
-	_setReadOnlyInputAttr: function(/*Boolean*/value){
+	_setReadOnlyInputAttr: function(/*Boolean*/ value){
 		// summary:
 		//		Change status and if needed, create the inputbox
 		// tags:
@@ -177,7 +182,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		this._createInputBox();
 	},
 
-	_setReadOnlyItemAttr: function(/*Boolean*/value){
+	_setReadOnlyItemAttr: function(/*Boolean*/ value){
 		// summary:
 		//		set read only items
 		// tags:
@@ -224,7 +229,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		this.connect(this._input, "onBlur", "_inputOnBlur");
 	},
 
-	compare: function(/*Array*/val1,/*Array*/val2){
+	compare: function(/*Array*/ val1, /*Array*/ val2){
 		// summary:
 		//		Compare 2 values (as returned by attr('value') for this widget).
 		// tags:
@@ -240,7 +245,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		}
 	},
 
-	add: function(/*String || Array*/values){
+	add: function(/*String|Array*/ values){
 		// summary:
 		//		Create new list element
 		if(this._count>=this.maxItems && this.maxItems !== null){return;}
@@ -335,15 +340,15 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		},this);
 	},
 
-	_placeItem: function(/*domNode*/node){
+	_placeItem: function(/*DomNode*/ node){
 		// summary:
 		//		Place item in the list
 		// tags:
 		//		private
-		domConstruct.place(node,this._inputNode,"before");
+		domConstruct.place(node,this._inputNode, "before");
 	},
 
-	_getCursorPos: function(/*domNode*/node){
+	_getCursorPos: function(/*DomNode*/ node){
 		// summary:
 		//		get current cursor pos
 		// tags:
@@ -362,7 +367,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		}finally{ range=null; }
 	},
 
-	_onItemClose: function(/*dijit._Widget*/ item){
+	_onItemClose: function(/*dijit/_Widget*/ item){
 		// summary:
 		//		Destroy a list element when close button is clicked
 		// tags:
@@ -381,7 +386,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		}
 	},
 
-	_onItemKeyDown:  function(/*dijit._Widget*/ item, /*Event*/ e){
+	_onItemKeyDown:  function(/*dijit/_Widget*/ item, /*Event*/ e){
 		// summary:
 		//		Call when item get a keypress
 		// tags:
@@ -395,7 +400,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		}
 	},
 
-	_editBefore: function(/*widget*/item){
+	_editBefore: function(/*widget*/ item){
 		// summary:
 		//		move trough items
 		// tags:
@@ -405,7 +410,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 			this._currentItem.edit();
 		}
 	},
-	_editAfter: function(/*widget*/item){
+	_editAfter: function(/*widget*/ item){
 		// summary:
 		//		move trough items
 		// tags:
@@ -424,7 +429,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		}
 	},
 
-	_onItemChange: function(/*dijit._Widget*/ item, /*String*/ value){
+	_onItemChange: function(/*dijit/_Widget*/ item, /*String*/ value){
 		// summary:
 		//		Call when item value change
 		// tags:
@@ -439,7 +444,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		this._updateValues();
 	},
 
-	_onItemEdit: function(/*dijit._Widget*/ item){
+	_onItemEdit: function(/*dijit/_Widget*/ item){
 		// summary:
 		//		Call when item is edited
 		// tags:
@@ -447,7 +452,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		domClass.remove(item.domNode,["dijitError", this.baseClass + "Match", this.baseClass + "Mismatch"]);
 	},
 
-	_testItem: function(/*Object*/item,/*String*/value){
+	_testItem: function(/*Object*/ item, /*String*/ value){
 		// summary:
 		//		Change class of item (match, mismatch)
 		// tags:
@@ -475,7 +480,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		return this.value;
 	},
 
-	_setValueAttr: function(/*Array || String*/ newValue){
+	_setValueAttr: function(/*Array|String*/ newValue){
 		// summary:
 		//		Hook so attr('value', value) works.
 		// description:
@@ -487,9 +492,9 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		this.add(this._parseValue(newValue));
 	},
 
-	_parseValue: function(/*String*/newValue){
+	_parseValue: function(/*String*/ newValue){
 		// summary:
-		//		search for delemiters and split if needed
+		//		search for delimiters and split if needed
 		// tags:
 		//		private
 		if(typeof newValue == "string"){
@@ -505,7 +510,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		return newValue;
 	},
 
-	regExpGen: function(/*ValidationTextBox.__Constraints*/constraints){
+	regExpGen: function(/*__Constraints*/ constraints){
 		// summary:
 		//		Overridable function used to generate regExp when dependent on constraints.
 		//		Do not specify both regExp and regExpGen.
@@ -531,7 +536,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		this.inherited(arguments);
 	},
 
-	_onHandler: function(/*String*/value){
+	_onHandler: function(/*String*/ value){
 		// summary:
 		//		When handlers of input are fired, this method check input value and (if needed) modify it
 		// tags:
@@ -542,7 +547,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		}
 	},
 
-	_onClick:  function(/*event*/e){
+	_onClick:  function(/*Event*/ e){
 		// summary:
 		//		give focus to inputbox
 		// tags:
@@ -560,9 +565,9 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		}
 	},
 
-	_inputOnKeyDown: function(/*event*/e){
+	_inputOnKeyDown: function(/*Event*/ e){
 		// summary:
-		//		Used to add keybord interactivity
+		//		Used to add keyboard interactivity
 		// tags:
 		//		private
 		this._currentItem = null;
@@ -605,7 +610,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		return this._getValues(lang.hitch(this,this._mismatchValidator));
 	},
 
-	_getValues: function(/*function*/validator){
+	_getValues: function(/*Function*/ validator){
 		// summary:
 		//		return values with comparator constraint
 		// tags:
@@ -625,14 +630,14 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		return value;
 	},
 
-	_nullValidator: function(/*String*/itemValue){
+	_nullValidator: function(/*String*/ itemValue){
 		// summary:
 		//		return true or false
 		// tags:
 		//		private
 		return true;
 	},
-	_matchValidator: function(/*String*/itemValue){
+	_matchValidator: function(/*String*/ itemValue){
 		// summary:
 		//		return true or false
 		// tags:
@@ -640,7 +645,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		var re = new RegExp(this.regExpGen(this.constraints));
 		return itemValue.match(re);
 	},
-	_mismatchValidator: function(/*String*/itemValue){
+	_mismatchValidator: function(/*String*/ itemValue){
 		// summary:
 		//		return true or false
 		// tags:
@@ -656,7 +661,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		//		private
 		return this._getSomeItem();
 	},
-	_getSomeItem: function(/*dijit._Widget*/ item,/*String*/ position){
+	_getSomeItem: function(/*dijit/_Widget*/ item, /*String*/ position){
 		// summary:
 		//		return the item before the one in params
 		// tags:
@@ -688,7 +693,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		}
 		return lastItem;
 	},
-	_getPreviousItem: function(/*dijit._Widget*/ item){
+	_getPreviousItem: function(/*dijit/_Widget*/ item){
 		// summary:
 		//		return the item before the one in params
 		// tags:
@@ -703,7 +708,7 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 		return this._getSomeItem(item,"after");
 	},
 
-	_destroyItem: function(/*dijit._Widget*/ item, /*Boolean?*/ updateValue){
+	_destroyItem: function(/*dijit/_Widget*/ item, /*Boolean?*/ updateValue){
 		// summary:
 		//		destroy an item
 		// tags:
@@ -759,9 +764,9 @@ var ListInput = declare("dojox.form.ListInput", [FormValueWidget],
 var _ListInputInputItem = declare("dojox.form._ListInputInputItem", [Widget, TemplatedMixin],
 	{
 	// summary:
-	//	Item created by ListInputInput when delimiter is found
+	//		Item created by ListInputInput when delimiter is found
 	// description:
-	//		Simple <li> with close button added to ListInputInput when delimiter is found
+	//		Simple `<li>` with close button added to ListInputInput when delimiter is found
 
 	templateString: "<li class=\"dijit dijitReset dijitLeft dojoxListInputItem\" dojoAttachEvent=\"onclick: onClick\" ><span dojoAttachPoint=\"labelNode\"></span></li>",
 
@@ -829,7 +834,7 @@ var _ListInputInputItem = declare("dojox.form._ListInputInputItem", [Widget, Tem
 		this._createInlineEditBox();
 	},
 
-	_setReadOnlyItemAttr: function(/*Boolean*/value){
+	_setReadOnlyItemAttr: function(/*Boolean*/ value){
 		// summary:
 		//		change the readonly state
 		// tags:
@@ -873,7 +878,7 @@ var _ListInputInputItem = declare("dojox.form._ListInputInputItem", [Widget, Tem
 		}
 	},
 
-	_onCloseEdit: function(/*String*/value){
+	_onCloseEdit: function(/*String*/ value){
 		// summary:
 		//		call when inline editor close himself
 		// tags:
@@ -893,7 +898,7 @@ var _ListInputInputItem = declare("dojox.form._ListInputInputItem", [Widget, Tem
 		this.onEdit();
 	},
 
-	_setDisabledAttr: function(/*Boolean*/value){
+	_setDisabledAttr: function(/*Boolean*/ value){
 		// summary:
 		//		disable inline edit box
 		// tags:
@@ -951,13 +956,13 @@ var _ListInputInputItem = declare("dojox.form._ListInputInputItem", [Widget, Tem
 		//		callback when widget is click
 	},
 
-	onChange: function(/*String*/value){
+	onChange: function(/*String*/ value){
 		// summary:
 		//		callback when widget change its content
 	},
 
 
-	onKeyDown: function(/*String*/value){
+	onKeyDown: function(/*String*/ value){
 		// summary:
 		//		callback when widget get a KeyDown
 	}
@@ -965,7 +970,7 @@ var _ListInputInputItem = declare("dojox.form._ListInputInputItem", [Widget, Tem
 var _ListInputInputBox = declare("dojox.form._ListInputInputBox", [ValidationTextBox],
 	{
 	// summary:
-	//	auto-sized text box
+	//		auto-sized text box
 	// description:
 	//		Auto sized textbox based on dijit.form.TextBox
 
@@ -987,7 +992,7 @@ var _ListInputInputBox = declare("dojox.form._ListInputInputBox", [ValidationTex
 	//		Used to get size of textbox content
 	_sizer:null,
 
-	onChange: function(/*string*/value){
+	onChange: function(/*String*/ value){
 		// summary:
 		//		compute content width
 		this.inherited(arguments);
@@ -1013,4 +1018,4 @@ var _ListInputInputBox = declare("dojox.form._ListInputInputBox", [ValidationTex
 	}
 });
 return ListInput;
-});
\ No newline at end of file
+});
diff --git a/dojox/form/Manager.js b/dojox/form/Manager.js
index f8c92c9..51e5797 100644
--- a/dojox/form/Manager.js
+++ b/dojox/form/Manager.js
@@ -1,6 +1,7 @@
 define([
 	"dijit/_Widget",
-	"dijit/_TemplatedMixin",
+	"dijit/_AttachMixin",
+	"dijit/_WidgetsInTemplateMixin",
 	"./manager/_Mixin",
 	"./manager/_NodeMixin",
 	"./manager/_FormMixin",
@@ -9,46 +10,26 @@ define([
 	"./manager/_DisplayMixin",
 	"./manager/_ClassMixin",
 	"dojo/_base/declare"
-], function(_Widget, _TemplatedMixin, _Mixin, _NodeMixin, _FormMixin, _ValueMixin, _EnableMixin, _DisplayMixin, _ClassMixin, declare){
+], function(_Widget, _AttachMixin, _WidgetsInTemplateMixin, _Mixin, _NodeMixin, _FormMixin, _ValueMixin, _EnableMixin, _DisplayMixin, _ClassMixin, declare){
 
-	/*=====
-		_Widget = dijit._Widget;
-		_Mixin = dojox.form.manager._Mixin;
-		_NodeMixin = dojox.form.manager._NodeMixin;
-		_FormMixin = dojox.form.manager._FormMixin;
-		_ValueMixin = dojox.form.manager._ValueMixin;
-		_EnableMixin = dojox.form.manager._EnableMixin;
-		_DisplayMixin = dojox.form.manager._DisplayMixin;
-		_ClassMixin = dojox.form.manager._ClassMixin;
-	=====*/
-return declare("dojox.form.Manager", [ _Widget, _Mixin, _NodeMixin, _FormMixin, _ValueMixin, _EnableMixin, _DisplayMixin, _ClassMixin ], {
+return declare("dojox.form.Manager", [ _Widget, _WidgetsInTemplateMixin, _AttachMixin, _Mixin, _NodeMixin, _FormMixin, _ValueMixin, _EnableMixin, _DisplayMixin, _ClassMixin ], {
 	// summary:
 	//		The widget to orchestrate dynamic forms.
 	// description:
 	//		This widget hosts dojox.form.manager mixins.
 	//		See _Mixin for more info.
 
+	// Set _AttachMixin.searchContainerNode to true for back-compat for widgets
+	// that have data-dojo-attach-point's and events inside this.containerNode.
+   	// Remove for 2.0.
+	searchContainerNode: true,
+
 	buildRendering: function(){
-		var node = (this.domNode = this.srcNodeRef);
 		if(!this.containerNode){
 			// all widgets with descendants must set containerNode
-				this.containerNode = node;
+			this.containerNode = this.srcNodeRef;
 		}
 		this.inherited(arguments);
-		this._attachPoints = [];
-		this._attachEvents = [];
-		_TemplatedMixin.prototype._attachTemplateNodes.call(this, node, function(n, p){ return n.getAttribute(p); });
-	},
-
-	destroyRendering: function(preserveDom){
-		// ctm: calling _TemplatedMixin
-		if(!this.__ctm){
-			// avoid recursive call from _TemplatedMixin
-			this.__ctm = true;
-			_TemplatedMixin.prototype.destroyRendering.apply(this, arguments);
-			delete this.__ctm;
-			this.inherited(arguments);
-		}
 	}
 });
 });
\ No newline at end of file
diff --git a/dojox/form/MonthTextBox.js b/dojox/form/MonthTextBox.js
new file mode 100644
index 0000000..0654904
--- /dev/null
+++ b/dojox/form/MonthTextBox.js
@@ -0,0 +1,69 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojox/widget/MonthlyCalendar",
+	"dijit/form/TextBox",
+	"./DateTextBox",
+	"dojo/_base/declare"
+	], function(kernel, lang, MonthlyCalendar, TextBox, DateTextBox, declare){
+		kernel.experimental("dojox/form/DateTextBox");
+		return declare( "dojox.form.MonthTextBox", DateTextBox,
+		{
+			// summary:
+			//		A validating, serializable, range-bound date text box with a popup calendar that contains only months
+
+			// popupClass: String
+			//		The popup widget to use. In this case, a calendar with just a Month view.
+			popupClass: MonthlyCalendar,
+
+			selector: "date",
+
+			postMixInProperties: function(){
+				this.inherited(arguments);
+				this.constraints.datePattern = "MM";
+			},
+
+			format: function(value){
+				if(!value && value !== 0){
+					return 1;
+				}
+				if(value.getMonth){
+					return value.getMonth() + 1;
+				}
+				return Number(value) + 1;
+			},
+
+			parse: function(value, constraints){
+				return Number(value) - 1;
+			},
+
+			serialize: function(value, constraints){
+				return String(value);
+			},
+
+			validator: function(value){
+				var num = Number(value);
+				var isInt = /(^-?\d\d*$)/.test(String(value));
+				return value == "" || value == null || (isInt && num >= 1 && num <= 12);
+			},
+
+			_setValueAttr: function(value, priorityChange, formattedValue){
+				if(value){
+					if(value.getMonth){
+						value = value.getMonth();
+					}
+				}
+				TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
+			},
+
+			openDropDown: function(){
+				this.inherited(arguments);
+
+				this.dropDown.onValueSelected = lang.hitch(this, function(value){
+					this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
+					setTimeout(lang.hitch(this, "closeDropDown"), 1); // allow focus time to take
+					TextBox.prototype._setValueAttr.call(this, value, true, value);
+				});
+			}
+		});
+});
\ No newline at end of file
diff --git a/dojox/form/MultiComboBox.js b/dojox/form/MultiComboBox.js
index cf79756..ac7bec2 100644
--- a/dojox/form/MultiComboBox.js
+++ b/dojox/form/MultiComboBox.js
@@ -6,10 +6,6 @@ define([
 ], function(kernel, ValidationTextBox, ComboBoxMixin, declare){
 kernel.experimental("dojox.form.MultiComboBox");
 
-	/*=====
-		ValidationTextBox = dijit.form.ValidationTextBox;
-		ComboBoxMixin = dijit.form.ComboBoxMixin;
-	=====*/
 return declare("dojox.form.MultiComboBox", [ValidationTextBox, ComboBoxMixin],{
 	// summary:
 	//		A ComboBox that accepts multiple inputs on a single line
@@ -28,7 +24,7 @@ return declare("dojox.form.MultiComboBox", [ValidationTextBox, ComboBoxMixin],{
 		this.inherited(arguments);
 	},
 
-	_addPreviousMatches: function(/* String */text){
+	_addPreviousMatches: function(/*String*/ text){
 		if(this._previousMatches){
 			if(!text.match(new RegExp("^"+this._previousMatches))){
 				text = this._previousMatches+text;
@@ -38,7 +34,7 @@ return declare("dojox.form.MultiComboBox", [ValidationTextBox, ComboBoxMixin],{
 		return text; // String
 	},
 
-	_cleanupDelimiters: function(/* String */text){
+	_cleanupDelimiters: function(/*String*/ text){
 		if(this.delimiter){
 			text = text.replace(new RegExp("  +"), " ");
 			text = text.replace(new RegExp("^ *"+this.delimiter+"* *"), "");
@@ -47,12 +43,12 @@ return declare("dojox.form.MultiComboBox", [ValidationTextBox, ComboBoxMixin],{
 		return text;
 	},
 
-	_autoCompleteText: function(/* String */text){
+	_autoCompleteText: function(/*String*/ text){
 		arguments[0] = this._addPreviousMatches(text);
 		this.inherited(arguments);
 	},
 
-	_startSearch: function(/* String */text){
+	_startSearch: function(/*String*/ text){
 		text = this._cleanupDelimiters(text);
 		var re = new RegExp("^.*"+this.delimiter+" *");
 
diff --git a/dojox/form/PasswordValidator.js b/dojox/form/PasswordValidator.js
index 06d2b73..052eb0b 100644
--- a/dojox/form/PasswordValidator.js
+++ b/dojox/form/PasswordValidator.js
@@ -12,15 +12,11 @@ define([
 	"dojo/_base/declare"
 ], function(array, lang, domAttr, i18n, query, keys, FormValueWidget, ValidationTextBox, template, formNlsPasswordValidator, declare){
 
-	/*=====
-		FormValueWidget = dijit.form._FormValueWidget;
-		ValidationTextBox = dijit.form.ValidationTextBox;
-	=====*/
 var _ChildTextBox = declare("dojox.form._ChildTextBox", ValidationTextBox, {
 	// summary:
 	//		A class that is shared between all our children - extends
 	//		ValidationTextBox and provides some shared functionality
-	//
+
 	// containerWidget: widget
 	//		Our parent (the PasswordValidator)
 	containerWidget: null,
@@ -69,7 +65,7 @@ var _OldPWBox = declare("dojox.form._OldPWBox", _ChildTextBox, {
 	//		Whether or not the password is valid
 	_isPWValid: false,
 
-	_setValueAttr: function(/* anything */ newVal, /* boolean? */ priority){
+	_setValueAttr: function(/*anything*/ newVal, /*Boolean?*/ priority){
 		// summary:
 		//		Updates _isPWValid if this isn't our initial update by calling
 		//		our PasswordValidator's pwCheck function
@@ -77,8 +73,8 @@ var _OldPWBox = declare("dojox.form._OldPWBox", _ChildTextBox, {
 			newVal = _OldPWBox.superclass.attr.call(this, "value");
 		}
 		if(priority !== null){
-			//  Priority is passed in as null, explicitly when this is an
-			//	update (not initially set).  We want to check our password now.
+			// Priority is passed in as null, explicitly when this is an
+			// update (not initially set).  We want to check our password now.
 			this._isPWValid = this.containerWidget.pwCheck(newVal);
 		}
 		this.inherited(arguments);
@@ -86,12 +82,12 @@ var _OldPWBox = declare("dojox.form._OldPWBox", _ChildTextBox, {
 		this.containerWidget._childValueAttr(this.containerWidget._inputWidgets[1].get("value"));
 	},
 
-	isValid: function(/* boolean */ isFocused){
+	isValid: function(/*Boolean*/ isFocused){
 		// Take into account the isPWValid setting
 		return this.inherited("isValid", arguments) && this._isPWValid;
 	},
 
-	_update: function(/* event */ e){
+	_update: function(/*Event*/ e){
 		// Only call validate() if we've been blurred or else we get popups
 		// too early.
 		if(this._hasBeenBlurred){ this.validate(true); }
@@ -168,16 +164,18 @@ return declare("dojox.form.PasswordValidator", FormValueWidget, {
 
 	_hasBeenBlurred: false,
 
-	isValid: function(/* boolean */ isFocused){
-		// summary: we are valid if ALL our children are valid
+	isValid: function(/*Boolean*/ isFocused){
+		// summary:
+		//		we are valid if ALL our children are valid
 		return array.every(this._inputWidgets, function(i){
 			if(i && i._setStateClass){ i._setStateClass(); }
 			return (!i || i.isValid());
 		});
 	},
 
-	validate: function(/* boolean */ isFocused){
-		// summary: Validating this widget validates all our children
+	validate: function(/*Boolean*/ isFocused){
+		// summary:
+		//		Validating this widget validates all our children
 		return array.every(array.map(this._inputWidgets, function(i){
 			if(i && i.validate){
 				i._hasBeenBlurred = (i._hasBeenBlurred || this._hasBeenBlurred);
@@ -188,7 +186,8 @@ return declare("dojox.form.PasswordValidator", FormValueWidget, {
 	},
 
 	reset: function(){
-		// summary: Resetting this widget resets all our children
+		// summary:
+		//		Resetting this widget resets all our children
 		this._hasBeenBlurred = false;
 		array.forEach(this._inputWidgets, function(i){
 			if(i && i.reset){ i.reset(); }
@@ -220,7 +219,7 @@ return declare("dojox.form.PasswordValidator", FormValueWidget, {
 		}, this);
 	},
 
-	pwCheck: function(/* string */ password){
+	pwCheck: function(/*String*/ password){
 		// summary:
 		//		Overridable function for validation of the old password box.
 		//
@@ -228,11 +227,11 @@ return declare("dojox.form.PasswordValidator", FormValueWidget, {
 		//		true if it's OK to continue, and false if it is not.
 		//
 		//		IMPORTANT SECURITY NOTE:  Do NOT EVER EVER EVER check this in
-		//									HTML or JavaScript!!!
+		//		HTML or JavaScript!!!
 		//
 		//		You will probably want to override this function to callback
 		//		to a server to verify the password (the callback will need to
-		//		be syncronous) - and it's probably a good idea to validate
+		//		be synchronous) - and it's probably a good idea to validate
 		//		it again on form submission before actually doing
 		//		anything destructive - that's why the "oldName" value
 		//		is available.
@@ -247,9 +246,9 @@ return declare("dojox.form.PasswordValidator", FormValueWidget, {
 	},
 
 	postCreate: function(){
-		//	summary:
+		// summary:
 		//		Sets up the correct widgets.  You *MUST* specify one child
-		//		text box (a simple HTML <input> element) with pwType="new"
+		//		text box (a simple HTML `<input>` element) with pwType="new"
 		//		*and* one child text box with pwType="verify".  You *MAY*
 		//		specify a third child text box with pwType="old" in order to
 		//		prompt the user to enter in their old password before the
@@ -319,4 +318,4 @@ return declare("dojox.form.PasswordValidator", FormValueWidget, {
 		if(!f){ this._inputWidgets[1].focus(); }
 	}
 });
-});
\ No newline at end of file
+});
diff --git a/dojox/form/README b/dojox/form/README
index 462ca5b..7485346 100644
--- a/dojox/form/README
+++ b/dojox/form/README
@@ -21,11 +21,8 @@ Dependencies:
 
 	Depends on dojo core and dijit
 	
-	dojo.form.FileUploader depends on dojox.embed, and uses Flash movies created
-	in the deft project using Flex OSS 3.  You do not need any of the deft code; 
-	compiled movies are included with dojox.form in the resources folder.  
-	If you want to modify the actual movies, you can look in the deft project 
-	(under the package deft.av).
+	dojo/form/Uploader depends on dojox.embed, and uses Flash SWFs created
+	in the deft project using Flex OSS 3.
 -------------------------------------------------------------------------------
 Documentation
 
@@ -53,9 +50,10 @@ Additional Notes (Brief widget list):
 						
 	* FilePickerTextBox - a validating text box that can browser server-side
 						files using a dojox.data.FileStore
-	* FileUploader - Allows for Multi-file uploads and file masking. Uses a SWF
-						file created with Deft. Compatible with Flash Player
-						versions 8-10. Degradeable to a multi-file HTML uploader.
+	* FileUploader - deprecated
+	
+	* Uploader - Allows for Multi-file uploads using HTML5, Flash or an IFrame
+					version 1.9 had changes that may break back-compat.
 	
 	* ListInput - A text-box widget that allows inputting multiple items (similar
 						to the "to" field on many email clients)
diff --git a/dojox/form/RadioStack.js b/dojox/form/RadioStack.js
index 0a71f13..0eefc3a 100644
--- a/dojox/form/RadioStack.js
+++ b/dojox/form/RadioStack.js
@@ -3,11 +3,11 @@ define([
 	"./_SelectStackMixin",
 	"dojo/_base/declare"
 ], function(CheckedMultiSelect, _SelectStackMixin, declare){
-	/*=====
-		CheckedMultiSelect = dojox.form.CheckedMultiSelect;
-		_SelectStackMixin = dojox.form._SelectStackMixin;
-	=====*/
-	return declare("dojox.form.RadioStack", [ CheckedMultiSelect, _SelectStackMixin ], {
-	// summary: A radio-based select stack.
-	});
+/*=====
+return {
+	// summary:
+	//		A radio-based select stack.
+};
+=====*/
+	return declare("dojox.form.RadioStack", [ CheckedMultiSelect, _SelectStackMixin ]);
 });
\ No newline at end of file
diff --git a/dojox/form/RangeSlider.js b/dojox/form/RangeSlider.js
index 6fc2408..784526b 100644
--- a/dojox/form/RangeSlider.js
+++ b/dojox/form/RangeSlider.js
@@ -26,12 +26,7 @@ define([
 		sortForward = function(a, b){ return a - b; }
 	;
 
-	lang.getObject("form", true, dojox);
 
-	/*=====
-		hTemplate = dijit.form.HorizontalSlider;
-		vTemplate = dijit.form.VerticalSlider;
-	=====*/
 	var RangeSliderMixin = declare("dojox.form._RangeSliderMixin", null, {
 
 		value: [0,100],
@@ -55,9 +50,17 @@ define([
 			});
 
 			this._movableMax = new Moveable(this.sliderHandleMax,{ mover: mover });
-			this.focusNodeMax.setAttribute("aria-valuemin", this.minimum);
-			this.focusNodeMax.setAttribute("aria-valuemax", this.maximum);
 
+			//The valuenow of the sliderHandle (min) usually determines the valuemin of sliderHandleMax
+			//and valuenow of sliderHandleMax usually determines the valueMax of sliderHandle
+			//However, in our RangeSlider dragging one handle past the other one causes both to
+			//'snap' together and move so both sliders will have the same min, max values			
+
+			this.sliderHandle.setAttribute("aria-valuemin", this.minimum);
+			this.sliderHandle.setAttribute("aria-valuemax", this.maximum);
+			this.sliderHandleMax.setAttribute("aria-valuemin", this.minimum);
+			this.sliderHandleMax.setAttribute("aria-valuemax", this.maximum);
+			
 			// a dnd for the bar!
 			var barMover = declare(SliderBarMover, {
 				constructor: function(){
@@ -65,7 +68,13 @@ define([
 				}
 			});
 			this._movableBar = new Moveable(this.progressBar,{ mover: barMover });
-		},
+				
+			// Remove these from the progress bar since it isn't a slider
+			this.focusNode.removeAttribute("aria-valuemin");
+			this.focusNode.removeAttribute("aria-valuemax");
+			this.focusNode.removeAttribute("aria-valuenow");
+
+		},		
 
 		destroy: function(){
 			this.inherited(arguments);
@@ -230,11 +239,12 @@ define([
 			// we have to reset this values. don't know the reason for that
 			this._lastValueReported = "";
 			this.valueNode.value = this.value = value = actValue;
-			this.focusNode.setAttribute("aria-valuenow", actValue[0]);
-			this.focusNodeMax.setAttribute("aria-valuenow", actValue[1]);
 
 			this.value.sort(this._isReversed() ? sortReversed : sortForward);
 
+			this.sliderHandle.setAttribute("aria-valuenow", actValue[0]);
+			this.sliderHandleMax.setAttribute("aria-valuenow", actValue[1]);
+			
 			// not calling the _setValueAttr-function of Slider, but the super-super-class (needed for the onchange-event!)
 			FormValueWidget.prototype._setValueAttr.apply(this, arguments);
 			this._printSliderBar(priorityChange, isMaxVal);
@@ -293,8 +303,7 @@ define([
 				widget._isReversed_ = widget._isReversed();
 			}
 
-			var coordEvent = e.touches ? e.touches[0] : e; // if multitouch take first touch for coords
-			var pixelValue = coordEvent[widget._mousePixelCoord] - abspos[widget._startingPixelCoord];
+			var pixelValue = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord];
 			widget._setPixelValue_(widget._isReversed_ ? (abspos[widget._pixelCount]-pixelValue) : pixelValue, abspos[widget._pixelCount], false, true);
 		},
 
@@ -324,14 +333,12 @@ define([
 			if(!bar){
 				bar = widget._bar = domGeometry.position(widget.progressBar, true);
 			}
-			var coordEvent = e.touches ? e.touches[0] : e; // if multitouch take first touch for coords
 
 			if(!mouseOffset){
-				mouseOffset = widget._mouseOffset = coordEvent[widget._mousePixelCoord] - abspos[widget._startingPixelCoord] - bar[widget._startingPixelCoord];
+				mouseOffset = widget._mouseOffset = e[widget._mousePixelCoord] - bar[widget._startingPixelCoord];
 			}
 
-
-			var pixelValueMin = coordEvent[widget._mousePixelCoord] - abspos[widget._startingPixelCoord] - mouseOffset,
+			var pixelValueMin = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord] - mouseOffset,
 				pixelValueMax = pixelValueMin + bar[widget._pixelCount];
 				// we don't narrow the slider when it reaches the bumper!
 				// maybe there is a simpler way
@@ -369,13 +376,13 @@ define([
 
 	declare("dojox.form.HorizontalRangeSlider", [HorizontalSlider, RangeSliderMixin], {
 		// summary:
-		//	A form widget that allows one to select a range with two horizontally draggable images
+		//		A form widget that allows one to select a range with two horizontally draggable images
 		templateString: hTemplate
 	});
 
 	declare("dojox.form.VerticalRangeSlider", [VerticalSlider, RangeSliderMixin], {
 		// summary:
-		//	A form widget that allows one to select a range with two vertically draggable images
+		//		A form widget that allows one to select a range with two vertically draggable images
 		templateString: vTemplate
 	});
 
diff --git a/dojox/form/Rating.js b/dojox/form/Rating.js
index c8e36a3..97df204 100644
--- a/dojox/form/Rating.js
+++ b/dojox/form/Rating.js
@@ -3,102 +3,117 @@ define([
 	"dojo/_base/lang",
 	"dojo/dom-attr",
 	"dojo/dom-class",
+	"dojo/mouse",
+	"dojo/on",
 	"dojo/string",
 	"dojo/query",
 	"dijit/form/_FormWidget"
-], function(declare, lang, domAttr, domClass, string, query, FormWidget){
-
-	/*=====
-		FormWidget = dijit.form._FormWidget;
-	=====*/
-return declare("dojox.form.Rating", FormWidget,{
-	// summary:
-	//		A widget for rating using stars.
-	//
-	// required: Boolean
-	//		TODO: Can be true or false, default is false.
-	// required: false,
-
-	templateString: null,
-
-	// numStars: Integer/Float
-	//		The number of stars to show, default is 3.
-	numStars: 3,
-	// value: Integer/Float
-	//		The current value of the Rating
-	value: 0,
-
-	constructor:function(/*Object*/params){
-		// Build the templateString. The number of stars is given by this.numStars,
-		// which is normally an attribute to the widget node.
-		lang.mixin(this, params);
-
-		// TODO actually "dijitInline" should be applied to the surrounding div, but FF2
-		// screws up when we query() for the star nodes, it orders them randomly, because of the use
-		// of display:--moz-inline-box ... very strange bug
-		// Since using ul and li in combintaion with dijitInline this problem doesnt exist anymore.
-
-		// The focusNode is normally used to store the value, i dont know if that is right here, but seems standard for _FormWidgets
-		var tpl = '<div dojoAttachPoint="domNode" class="dojoxRating dijitInline">' +
-					'<input type="hidden" value="0" dojoAttachPoint="focusNode" /><ul>${stars}</ul>' +
+], function(declare, lang, domAttr, domClass, mouse, on, string, query, FormWidget){
+
+
+	return declare("dojox.form.Rating", FormWidget, {
+		// summary:
+		//		A widget for rating using stars.
+
+		/*=====
+		// required: Boolean
+		//		TODO: Can be true or false, default is false.
+		required: false,
+		=====*/
+
+		templateString: null,
+
+		// numStars: Integer|Float
+		//		The number of stars to show, default is 3.
+		numStars: 3,
+
+		// value: Integer|Float
+		//		The current value of the Rating
+		value: 0,
+
+		buildRendering: function(/*Object*/ params){
+			// summary:
+			//		Build the templateString. The number of stars is given by this.numStars,
+			//		which is normally an attribute to the widget node.
+
+			// The hidden value node is attached as "focusNode" because tabIndex, id, etc. are getting mapped there.
+			var tpl = '<div dojoAttachPoint="domNode" class="dojoxRating dijitInline">' +
+				'<input type="hidden" value="0" dojoAttachPoint="focusNode" /><ul data-dojo-attach-point="list">${stars}</ul>' +
 				'</div>';
-		// The value-attribute is used to "read" the value for processing in the widget class
-		var starTpl = '<li class="dojoxRatingStar dijitInline" dojoAttachEvent="onclick:onStarClick,onmouseover:_onMouse,onmouseout:_onMouse" value="${value}"></li>';
-		var rendered = "";
-		for(var i = 0; i < this.numStars; i++){
-			rendered += string.substitute(starTpl, {value:i+1});
-		}
-		this.templateString = string.substitute(tpl, {stars:rendered});
-	},
+			// The value-attribute is used to "read" the value for processing in the widget class
+			var starTpl = '<li class="dojoxRatingStar dijitInline" value="${value}"></li>';
+			var rendered = "";
+			for(var i = 0; i < this.numStars; i++){
+				rendered += string.substitute(starTpl, {value:i + 1});
+			}
+			this.templateString = string.substitute(tpl, {stars:rendered});
+
+			this.inherited(arguments);
+		},
 
-	postCreate: function(){
-		this.inherited(arguments);
-		this._renderStars(this.value);
-	},
+		postCreate: function(){
+			this.inherited(arguments);
+			this._renderStars(this.value);
+			this.own(
+				// Fire when mouse is moved over one of the stars.
+				on(this.list, on.selector(".dojoxRatingStar", "mouseover"), lang.hitch(this, "_onMouse")),
+				on(this.list, on.selector(".dojoxRatingStar", "click"), lang.hitch(this, "onStarClick")),
+				on(this.list, mouse.leave, lang.hitch(this, function(){
+					// go from hover display back to dormant display
+					this._renderStars(this.value);
+				}))
+			);
+		},
 
-	_onMouse: function(evt){
-		if(this.hovering){
+		_onMouse: function(evt){
+			// summary:
+			//		Called when mouse is moved over one of the stars
 			var hoverValue = +domAttr.get(evt.target, "value");
-			this.onMouseOver(evt, hoverValue);
 			this._renderStars(hoverValue, true);
-		}else{
-			this._renderStars(this.value);
-		}
-	},
-
-	_renderStars: function(value, hover){
-		// summary: Render the stars depending on the value.
-		query(".dojoxRatingStar", this.domNode).forEach(function(star, i){
-			if(i + 1 > value){
-				domClass.remove(star, "dojoxRatingStarHover");
-				domClass.remove(star, "dojoxRatingStarChecked");
-			}else{
-				domClass.remove(star, "dojoxRatingStar" + (hover ? "Checked" : "Hover"));
-				domClass.add(star, "dojoxRatingStar" + (hover ? "Hover" : "Checked"));
-			}
-		});
-	},
-
-	onStarClick:function(/* Event */evt){
-		// summary: Connect on this method to get noticed when a star was clicked.
-		// example: connect(widget, "onStarClick", function(event){ ... })
-		var newVal = +domAttr.get(evt.target, "value");
-		this.setAttribute("value", newVal == this.value ? 0 : newVal);
-		this._renderStars(this.value);
-		this.onChange(this.value); // Do I have to call this by hand?
-	},
-
-	onMouseOver: function(/*evt, value*/){
-		// summary: Connect here, the value is passed to this function as the second parameter!
-	},
-
-	setAttribute: function(/*String*/key, /**/value){
-		// summary: When calling setAttribute("value", 4), set the value and render the stars accordingly.
-		this.set(key, value);
-		if(key=="value"){
+			this.onMouseOver(evt, hoverValue);
+		},
+
+		_renderStars: function(value, hover){
+			// summary:
+			//		Render the stars depending on the value.
+			query(".dojoxRatingStar", this.domNode).forEach(function(star, i){
+				if(i + 1 > value){
+					domClass.remove(star, "dojoxRatingStarHover");
+					domClass.remove(star, "dojoxRatingStarChecked");
+				}else{
+					domClass.remove(star, "dojoxRatingStar" + (hover ? "Checked" : "Hover"));
+					domClass.add(star, "dojoxRatingStar" + (hover ? "Hover" : "Checked"));
+				}
+			});
+		},
+
+		onStarClick: function(/*Event*/ evt){
+			// summary:
+			//		Connect on this method to get noticed when a star was clicked.
+			// example:
+			//	|	connect(widget, "onStarClick", function(event){ ... })
+			var newVal = +domAttr.get(evt.target, "value");
+			this.setAttribute("value", newVal == this.value ? 0 : newVal);
 			this._renderStars(this.value);
-			this.onChange(this.value); // Do I really have to call this by hand? :-(
+			this.onChange(this.value); // Do I have to call this by hand?
+		},
+
+		onMouseOver: function(/*=====evt, value=====*/ ){
+			// summary:
+			//		Connect here, the value is passed to this function as the second parameter!
+		},
+
+		setAttribute: function(/*String*/ key, /*Number*/ value){
+			// summary:
+			//		Deprecated.   Use set("value", ...) instead.
+			this.set(key, value);
+		},
+
+		_setValueAttr: function(val){
+			this.focusNode.value = val;		// reflect the value in our hidden field, for form submission
+			this._set("value", val);
+			this._renderStars(val);
+			this.onChange(val); // Do I really have to call this by hand? :-(
 		}
-	}
-});
+	});
 });
diff --git a/dojox/form/TimeSpinner.js b/dojox/form/TimeSpinner.js
index 72d44b7..ab2c9ce 100644
--- a/dojox/form/TimeSpinner.js
+++ b/dojox/form/TimeSpinner.js
@@ -8,17 +8,17 @@ define([
 	"dojo/date/stamp",
 	"dojo/_base/declare"
 ], function(lang, event, Spinner, keys, dateUtil, dateLocale, dateStamp, declare){
-	/*=====
-		Spinner = dijit.form._Spinner;
-	=====*/
-return declare( "dojox.form.TimeSpinner", Spinner,
+
+return declare("dojox.form.TimeSpinner", Spinner,
 {
-	// summary: Time Spinner
-	// description: This widget is the same as a normal NumberSpinner, but for the time component of a date object instead
+	// summary:
+	//		Time Spinner
+	// description:
+	//		This widget is the same as a normal NumberSpinner, but for the time component of a date object instead
 
 	required: false,
 
-	adjust: function(/* Object */ val, /*Number*/ delta){
+	adjust: function(/*Object*/ val, /*Number*/ delta){
 		return dateUtil.add(val, "minute", delta)
 	},
 
@@ -44,18 +44,17 @@ return declare( "dojox.form.TimeSpinner", Spinner,
 
 	value: "12:00 AM",
 
-       _onKeyPress: function(e){
-                if((e.charOrCode == keys.HOME || e.charOrCode == keys.END) && !(e.ctrlKey || e.altKey || e.metaKey)
-                && typeof this.get('value') != 'undefined' /* gibberish, so HOME and END are default editing keys*/){
-                        var value = this.constraints[(e.charOrCode == keys.HOME ? "min" : "max")];
-                        if(value){
-                                this._setValueAttr(value,true);
-                        }
-                        // eat home or end key whether we change the value or not
-                        event.stop(e);
-                }
-        }
-
-
+   _onKeyDown: function(e){
+	   // TODO: this code is just copied from NumberSpinner
+		if((e.keyCode == keys.HOME || e.keyCode == keys.END) && !(e.ctrlKey || e.altKey || e.metaKey)
+		&& typeof this.get('value') != 'undefined' /* gibberish, so HOME and END are default editing keys*/){
+			var value = this.constraints[(e.keyCode == keys.HOME ? "min" : "max")];
+			if(value){
+				this._setValueAttr(value,true);
+			}
+			// eat home or end key whether we change the value or not
+			event.stop(e);
+		}
+	}
 });
 });
diff --git a/dojox/form/TriStateCheckBox.js b/dojox/form/TriStateCheckBox.js
index 54a88ff..fd3ed05 100644
--- a/dojox/form/TriStateCheckBox.js
+++ b/dojox/form/TriStateCheckBox.js
@@ -1,63 +1,46 @@
 define([
-	"dojo/_base/kernel",
-	"dojo/_base/declare",
-	"dojo/_base/array",
-	"dojo/_base/event",
-	"dojo/query",
-	"dojo/dom-attr",
+	"dojo/_base/kernel", // kernel.deprecated
+	"dojo/_base/declare", // declare
+	"dojo/_base/array", // array.indexOf
+	"dojo/_base/lang", // lang.isArray, lang.isString
+	"dojo/_base/event", // event.stop
+	"dojo/query", // query()
+	"dojo/dom-attr", // domAttr.set
 	"dojo/text!./resources/TriStateCheckBox.html",
-	"dijit/form/ToggleButton"
-], function(kernel, declare, array, event, query, domAttr, template, ToggleButton){
-//	module:
-//		dojox/form/TriStateCheckBox
-//	summary:
-//		Checkbox with three states
-//
-
-	/*=====
-		ToggleButton = dijit.form.ToggleButton;
-	=====*/
-return declare("dojox.form.TriStateCheckBox", ToggleButton,
-	{
-		// summary:
-		//		Checkbox with three states
+	"dijit/form/Button",
+	"dijit/form/_ToggleButtonMixin",
+	"dojo/NodeList-dom" // NodeList.addClass/removeClass
+], function(kernel, declare, array, lang, event, query, domAttr, template, Button, _ToggleButtonMixin){
 
+return declare("dojox.form.TriStateCheckBox", [Button, _ToggleButtonMixin], {
+	// summary:
+	//		Checkbox with three states
+	
 		templateString: template,
 
 		baseClass: "dojoxTriStateCheckBox",
 
 		// type: [private] String
-		//		type attribute on <input> node.
-		//		Overrides `dijit.form.Button.type`.  Users should not change this value.
+		//		type attribute on `<input>` node.
+		//		Overrides `dijit/form/Button.type`.  Users should not change this value.
 		type: "checkbox",
 
-		/*=====
 		// states: Array
 		//		States of TriStateCheckBox.
-		//		The value of This.checked should be one of these three states.
-		states: [false, true, "mixed"],
-		=====*/
+		//		The value of This.checked should be one of these three states:
+		//		[false, true, "mixed"]
+		states: "",
 
-		/*=====
 		// _stateLabels: Object
 		//		These characters are used to replace the image to show
-		//		current state of TriStateCheckBox in high contrast mode.
-		_stateLabels: {
-				"False": '&#63219',
-				"True": '√',
-				"Mixed": '&#8801'
-		},
-		=====*/
+		//		current state of TriStateCheckBox in high contrast mode. This is an associate array of
+		//      states with their corresponding replacing characters. State can either be "False", "True" or "Mixed".
+		 _stateLabels: null,
 
-		/*=====
 		// stateValues: Object
-		//		The values of the TriStateCheckBox in corresponding states.
-		stateValues:	{
-				"False": "off",
-				"True": "on",
-				"Mixed": "mixed"
-		},
-		=====*/
+		//		The values of the TriStateCheckBox in corresponding states. This is an associate array of
+		//      states with their corresponding values. State can either be "False", "True" or "Mixed".
+		stateValue: null,
 
 		// _currentState: Integer
 		//		The current state of the TriStateCheckBox
@@ -74,27 +57,51 @@ return declare("dojox.form.TriStateCheckBox", ToggleButton,
 		//		Similar to disabled except readOnly form values are submitted.
 		readOnly: false,
 
+		// checked: Boolean|String
+		//		Current check state of the check box.
+		checked: "",
+		
+		// aria-pressed for toggle buttons, and aria-checked for checkboxes
+		_aria_attr: "aria-checked",
+
 		constructor: function(){
 			// summary:
 			//		Runs on widget initialization to setup arrays etc.
 			// tags:
 			//		private
-			this.states = [false, true, "mixed"];
+			this.states = [false, "mixed", true];
+			this.checked = false;
 			this._stateLabels = {
-				"False": '&#63219',
+				"False": '□',
 				"True": '√',
-				"Mixed": '&#8801'
+				"Mixed": '■'
 			};
 			this.stateValues = {
-				"False": "off",
+				"False": false,
 				"True": "on",
 				"Mixed": "mixed"
 			};
 		},
-
+		
+		_fillContent: function(/*DomNode*/ source){
+			// Override Button::_fillContent() since it doesn't make sense for CheckBox,
+			// since CheckBox doesn't even have a container
+		},
+		
+		postCreate: function(){
+			domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
+			this.inherited(arguments);
+		},
+		
+		startup: function(){
+			this.set("checked", this.params.checked || this.states[this._currentState]);
+			domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
+			this.inherited(arguments);
+		},
+		
 		// Override behavior from Button, since we don't have an iconNode
 		_setIconClassAttr: null,
-
+		
 		_setCheckedAttr: function(/*String|Boolean*/ checked, /*Boolean?*/ priorityChange){
 			// summary:
 			//		Handler for checked = attribute to constructor, and also calls to
@@ -103,15 +110,18 @@ return declare("dojox.form.TriStateCheckBox", ToggleButton,
 			//		true, false or 'mixed'
 			// description:
 			//		Controls the state of the TriStateCheckBox. Set this.checked,
-			//		this._currentState, value attribute of the <input type=checkbox>
-			//		according to the value of 'checked'.
-			this._set("checked", checked);
-			this._currentState = array.indexOf(this.states, checked);
-			this._stateType = this._getStateType(checked);
-			domAttr.set(this.focusNode || this.domNode, "checked", checked);
-			domAttr.set(this.focusNode, "value", this.stateValues[this._stateType]);
-			(this.focusNode || this.domNode).setAttribute("aria-checked", checked);
-			this._handleOnChange(checked, priorityChange);
+			//		this._currentState, value attribute of the `<input type=checkbox>`
+			//		according to the value of 'checked'.			
+			var stateIndex = array.indexOf(this.states, checked), changed = false;
+			if(stateIndex >= 0){
+				this._currentState = stateIndex;
+				this._stateType = this._getStateType(checked);
+				domAttr.set(this.focusNode, "value", this.stateValues[this._stateType]);
+				domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
+				this.inherited(arguments);
+			}else{
+				console.warn("Invalid state!");
+			}
 		},
 
 		setChecked: function(/*String|Boolean*/ checked){
@@ -121,10 +131,26 @@ return declare("dojox.form.TriStateCheckBox", ToggleButton,
 			this.set('checked', checked);
 		},
 
+		_setStatesAttr: function(/*Array|String*/ states){
+			if(lang.isArray(states)){
+				this._set("states", states);
+			}else if(lang.isString(states)){
+				var map = {
+					"true": true,
+					"false": false,
+					"mixed": "mixed"
+				};
+				states = states.split(/\s*,\s*/);
+				for(var i = 0; i < states.length; i++){
+					states[i] = map[states[i]] !== undefined ? map[states[i]] : false;
+				}
+				this._set("states", states);
+			}
+		},
+		
 		_setReadOnlyAttr: function(/*Boolean*/ value){
 			this._set("readOnly", value);
 			domAttr.set(this.focusNode, "readOnly", value);
-			this.focusNode.setAttribute("aria-readonly", value);
 		},
 
 		_setValueAttr: function(/*String|Boolean*/ newValue, /*Boolean*/ priorityChange){
@@ -132,7 +158,7 @@ return declare("dojox.form.TriStateCheckBox", ToggleButton,
 			//		Handler for value = attribute to constructor, and also calls to
 			//		set('value', val).
 			// description:
-			//		During initialization, just saves as attribute to the <input type=checkbox>.
+			//		During initialization, just saves as attribute to the `<input type=checkbox>`.
 			//
 			//		After initialization,
 			//		when passed a boolean or the string 'mixed', controls the state of the
@@ -165,7 +191,7 @@ return declare("dojox.form.TriStateCheckBox", ToggleButton,
 			// description:
 			//		Change the value of the TriStateCheckBox in 'mixed' and true states.
 			this.stateValues["True"] = newValues[0] ? newValues[0] : this.stateValues["True"];
-			this.stateValues["Mixed"] = newValues[1] ? newValues[1] : this.stateValues["False"];
+			this.stateValues["Mixed"] = newValues[1] ? newValues[1] : this.stateValues["Mixed"];
 		},
 
 		_getValueAttr: function(){
@@ -176,24 +202,15 @@ return declare("dojox.form.TriStateCheckBox", ToggleButton,
 			return this.stateValues[this._stateType];
 		},
 
-		startup: function(){
-			this.set("checked", this.params.checked || this.states[this._currentState]);
-			domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
-			this.inherited(arguments);
-		},
-
-		 _fillContent: function(/*DomNode*/ source){
-			// Override Button::_fillContent() since it doesn't make sense for CheckBox,
-			// since CheckBox doesn't even have a container
-		},
-
 		reset: function(){
 			this._hasBeenBlurred = false;
-			this.stateValues = {
-				"False" : "off",
+			this.set("states", this.params.states || [false, "mixed", true]);
+			this.stateValues = this.params.stateValues || {
+				"False" : false,
 				"True" : "on",
 				"Mixed" : "mixed"
 			};
+			this.set("values", this.params.values || []);
 			this.set('checked', this.params.checked || this.states[0]);
 		},
 
@@ -208,6 +225,7 @@ return declare("dojox.form.TriStateCheckBox", ToggleButton,
 			if(this.id){
 				query("label[for='"+this.id+"']").removeClass("dijitFocusedLabel");
 			}
+			this.mouseFocus = false;
 			this.inherited(arguments);
 		},
 
@@ -219,25 +237,48 @@ return declare("dojox.form.TriStateCheckBox", ToggleButton,
 				event.stop(e);
 				return false;
 			}
+			this.click();
+			return this.onClick(e); // user click actions
+		},
+
+		click: function(){
+			// summary:
+			//		Emulate a click on the check box, but will not trigger the
+			//		onClick method.
 			if(this._currentState >= this.states.length - 1){
 				this._currentState = 0;
 			}else{
-				this._currentState++;
+				if(this._currentState == -1){
+					this.fixState();
+				}else{
+					this._currentState++;
+				}
 			}
+			var oldState = this._currentState;
 			this.set("checked", this.states[this._currentState]);
+			this._currentState = oldState;
 			domAttr.set(this.stateLabelNode, 'innerHTML', this._stateLabels[this._stateType]);
-			return this.onClick(e); // user click actions
 		},
-
+		
+		fixState: function(){
+			// summary:
+			//		Fix _currentState property if it's out of bound.
+			this._currentState = this.states.length - 1;
+		},
+		
 		_getStateType: function(/*String|Boolean*/ state){
-			//	summary:
-			//		Internal function to return the type of a certain state
-			//		false: False
-			//		true: True
-			//		"mixed": Mixed
+			// summary:
+			//		Internal function to return the type of a certain state:
+			//
+			//		- false: False
+			//		- true: True
+			//		- "mixed": Mixed
 			return state ? (state == "mixed" ? "Mixed" : "True") : "False";
+		},
+		
+		_onMouseDown: function(){
+			this.mouseFocus = true;
 		}
-	}
-);
+	});
 
 });
diff --git a/dojox/form/Uploader.js b/dojox/form/Uploader.js
index d458223..68c2856 100644
--- a/dojox/form/Uploader.js
+++ b/dojox/form/Uploader.js
@@ -6,19 +6,22 @@ define([
 	"dojo/_base/connect",
 	"dojo/_base/window",
 	"dojo/dom-style",
+	"dojo/dom-class",
 	"dojo/dom-geometry",
 	"dojo/dom-attr",
 	"dojo/dom-construct",
 	"dojo/dom-form",
 	"dijit",
 	"dijit/form/Button",
-	"dojox/form/uploader/Base",
+	"./uploader/_Base",
+	"./uploader/_HTML5",
+	"./uploader/_IFrame",
+	"./uploader/_Flash",
 	"dojo/i18n!./nls/Uploader",
 	"dojo/text!./resources/Uploader.html"
-],function(kernel, declare, lang, array, connect, win, domStyle, domGeometry, domAttr, domConstruct, domForm, dijit, Button, uploader, res, template){
+],function(kernel, declare, lang, array, connect, win, domStyle, domClass, domGeometry, domAttr, domConstruct,
+		   domForm, dijit, Button, Base, HTML5, IFrame, Flash, res, template){
 
-	kernel.experimental("dojox.form.Uploader");
-	//
 	// TODO:
 	//		i18n
 	//		label via innerHTML
@@ -30,360 +33,374 @@ define([
 	//		Make it so URL can change (current set to Flash on build)
 	//
 
-	/*=====
-		uploader = dojox.form.uploader.Base;
-		WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
-	=====*/
-declare("dojox.form.Uploader", [uploader, Button], {
-	//
-	// Version: 1.6
-	//
-	// summary:
-	//		A widget that creates a stylable file-input button, with optional multi-file selection,
-	//		using only HTML elements. Non-HTML5 browsers have fallback options of Flash or an iframe.
-	//
-	//	description:
-	//		A bare-bones, stylable file-input button, with optional multi-file selection. The list
-	//		of files is not displayed, that is for you to handle by connecting to the onChange
-	//		event, or use the dojox.form.uploader.FileList.
-	//
-	//		Uploader without plugins does not have any ability to upload - it is for use in forms
-	//		where you handle the upload either by a standard POST or with Ajax using an iFrame. This
-	//		class is for convenience of multiple files only. No progress events are available.
-	//
-	//		If the browser supports a file-input with the "multiple" attribute, that will be used.
-	//		If the browser does not support "multiple" (ergo, IE) multiple inputs are used,
-	//		one for each selection.
-	//
-	//
-	//	uploadOnSelect: Boolean
-	//		If true, uploads imediately after a file has been selected. If false,
-	//		waits for upload() to be called.
-	uploadOnSelect:false,
-	//	tabIndex: Number|String
-	//		The tab order in the DOM.
-	tabIndex:0,
-	//	multiple: Boolean
-	//		If true and flash mode, multiple files may be selected from the dialog.
-	multiple:false,
-	//
-	//	label: String
-	//		The text used in the button that when clicked, opens a system Browse Dialog.
-	label:res.label,
-	//
-	// url: String
-	//		The url targeted for upload. An absolute URL is preferred. Relative URLs are
-	//		changed to absolute.
-	url:"",
-	//
-	//	name: String
-	//		The name attribute needs to end with square brackets: [] as this is the standard way
-	//		of handling an attribute "array". This requires a slightly different technique on the
-	//		server.
-	name:"uploadedfile",
-	//
-	//	flashFieldName: String
-	//		If set, this will be the name of the field of the flash uploaded files that the server
-	//		is expecting. If not set, "Flash" is appended to the "name" property.
-	flashFieldName:"",
-	//
-	//	uploadType: String [readonly]
-	//		The type of uploader being used. As an alternative to determining the upload type on the
-	//		server based on the fieldName, this property could be sent to the server to help
-	//		determine what type of parsing should be used.
-	uploadType:"form",
-	//
-	//	showInput: String [const]
-	//		Position to show an input which shows selected filename(s). Possible
-	//		values are "before", "after", which specifies where the input should
-	//		be placed with reference to the containerNode which contains the
-	//		label). By default, this is empty string (no such input will be
-	//		shown). Specify showInput="before" to mimic the look&feel of a
-	//		native file input element.
-	showInput: "",
-
-	_nameIndex:0,
-
-	templateString: template,
-
-	baseClass: 'dijitUploader '+Button.prototype.baseClass,
-
-	postMixInProperties: function(){
-		this._inputs = [];
-		this._cons = [];
-		this.inherited(arguments);
-	},
-	buildRendering: function(){
-		console.warn("buildRendering", this.id)
-		this.inherited(arguments);
-		domStyle.set(this.domNode, {
-			overflow:"hidden",
-			position:"relative"
-		});
-		this._buildDisplay();
-		//change the button node not occupy tabIndex: the real file input
-		//will have tabIndex set
-		domAttr.set(this.titleNode, 'tabIndex', -1);
-	},
-	_buildDisplay: function(){
-		if(this.showInput){
-			this.displayInput = dojo.create('input', {
-				  'class':'dijitUploadDisplayInput',
-				  'tabIndex':-1, 'autocomplete':'off'},
-				this.containerNode, this.showInput);
-			//schedule the attachpoint to be cleaned up on destroy
-			this._attachPoints.push('displayInput');
-			this.connect(this,'onChange', function(files){
-				var i=0,l=files.length, f, r=[];
-				while((f=files[i++])){
-					if(f && f.name){
-						r.push(f.name);
-					}
-				}
-				this.displayInput.value = r.join(', ');
-			});
-			this.connect(this,'reset', function(){
-				this.displayInput.value = '';
-			});
-		}
-	},
-
-	startup: function(){
-		if(this._buildInitialized){
-			return;
-		}
-		this._buildInitialized = true;
-		this._getButtonStyle(this.domNode);
-		this._setButtonStyle();
-		this.inherited(arguments);
-	},
-
-	/*************************
-	 *	   Public Events	 *
-	 *************************/
-
-	onChange: function(/* Array */fileArray){
-		//	summary:
-		// 		stub to connect
-		// 		Fires when files are selected
-		// 		Event is an array of last files selected
-	},
-
-	onBegin: function(/* Array */dataArray){
+	return declare("dojox.form.Uploader", [Base, Button, HTML5, IFrame, Flash], {
 		// summary:
-		// 		Fires when upload begins
-	},
-
-	onProgress: function(/* Object */customEvent){
-		// summary:
-		// 		Stub to connect
-		// 		Fires on upload progress. Event is a normalized object of common properties
-		// 		from HTML5 uploaders and the Flash uploader. Will not fire for IFrame.
-		// customEvent:
-		// 		bytesLoaded: Number
-		// 			Amount of bytes uploaded so far of entire payload (all files)
-		//		bytesTotal: Number
-		//			Amount of bytes of entire payload (all files)
-		//		type: String
-		//			Type of event (progress or load)
-		//		timeStamp: Number
-		//			Timestamp of when event occurred
-	},
-
-	onComplete: function(/* Object */customEvent){
-		// summary:
-		// 		stub to connect
-		// 		Fires when all files have uploaded
-		// 		Event is an array of all files
-		this.reset();
-	},
-
-	onCancel: function(){
-		// summary:
-		// 		Stub to connect
-		// 		Fires when dialog box has been closed
-		//		without a file selection
-	},
-
-	onAbort: function(){
-		// summary:
-		// 		Stub to connect
-		// 		Fires when upload in progress was canceled
-	},
-
-	onError: function(/* Object or String */evtObject){
-		// summary:
-		//		Fires on errors
+		//		A widget that creates a stylable file-input button, with optional multi-file selection,
+		//		using only HTML elements. Non-HTML5 browsers have fallback options of Flash or an iframe.
 		//
-		//FIXME: Unsure of a standard form of error events
-	},
-
-	/*************************
-	 *	   Public Methods	 *
-	 *************************/
-
-	upload: function(/*Object ? */formData){
-		// summary:
-		// 		When called, begins file upload. Only supported with plugins.
-	},
-
-	submit: function(/* form Node ? */form){
-		// summary:
-		//		If Uploader is in a form, and other data should be sent along with the files, use
-		//		this instead of form submit.
-		form = !!form ? form.tagName ? form : this.getForm() : this.getForm();
-		var data = domForm.toObject(form);
-		this.upload(data);
-	},
-
-	reset: function(){
-		// summary
-		// 		Resets entire input, clearing all files.
-		// 		NOTE:
-		// 		Removing individual files is not yet supported, because the HTML5 uploaders can't
-		// 		be edited.
-		// 		TODO:
-		// 		Add this ability by effectively, not uploading them
+		// description:
+		//		A bare-bones, stylable file-input button, with optional multi-file selection. The list
+		//		of files is not displayed, that is for you to handle by connecting to the onChange
+		//		event, or use the dojox.form.uploader.FileList.
 		//
-		delete this._files;
-		this._disconnectButton();
-		array.forEach(this._inputs, domConstruct.destroy, dojo);
-		this._inputs = [];
-		this._nameIndex = 0;
-		this._createInput();
-	},
-
-	getFileList: function(){
-		// summary:
-		// 		Returns a list of selected files.
+		//		Uploader without plugins does not have any ability to upload - it is for use in forms
+		//		where you handle the upload either by a standard POST or with Ajax using an iFrame. This
+		//		class is for convenience of multiple files only. No progress events are available.
+		//
+		//		If the browser supports a file-input with the "multiple" attribute, that will be used.
+		//		If the browser does not support "multiple" (ergo, IE) multiple inputs are used,
+		//		one for each selection.
 		//
-		var fileArray = [];
-		if(this.supports("multiple")){
-			array.forEach(this._files, function(f, i){
-				fileArray.push({
-					index:i,
-					name:f.name,
-					size:f.size,
-					type:f.type
+		//		Version: 1.6
+	
+	
+		// uploadOnSelect: Boolean
+		//		If true, uploads immediately after a file has been selected. If false,
+		//		waits for upload() to be called.
+		uploadOnSelect:false,
+	
+		// tabIndex: Number|String
+		//		The tab order in the DOM.
+		tabIndex:0,
+	
+		// multiple: Boolean
+		//		If true and flash mode, multiple files may be selected from the dialog.
+		multiple:false,
+	
+		// label: String
+		//		The text used in the button that when clicked, opens a system Browse Dialog.
+		label:res.label,
+	
+		// url: String
+		//		The url targeted for upload. An absolute URL is preferred. Relative URLs are
+		//		changed to absolute.
+		url:"",
+	
+		// name: String
+		//		The name attribute needs to end with square brackets: [] as this is the standard way
+		//		of handling an attribute "array". This requires a slightly different technique on the
+		//		server.
+		name:"uploadedfile",
+	
+		// flashFieldName: String
+		//		If set, this will be the name of the field of the flash uploaded files that the server
+		//		is expecting. If not set, "Flash" is appended to the "name" property.
+		flashFieldName:"",
+		
+		//	force: String
+		//		options: form, html5, iframe, flash
+		//		Empty string defaults to html5 if available, and iframe if not.
+		// 		Use "flash" to always use Flash (and hopefully force the user to download the plugin
+		//		if they don't have it).
+		//		Use "iframe" to always use an iframe, and never flash nor html5. Sometimes preferred
+		//		for consistent results.
+		//		Use "form" to not use ajax and post to a page.
+		force:"",
+	
+		// uploadType: String [readonly]
+		//		The type of uploader being used. As an alternative to determining the upload type on the
+		//		server based on the fieldName, this property could be sent to the server to help
+		//		determine what type of parsing should be used.
+		//		This is set based on the force property and what features are available in the browser.
+		uploadType:"",
+	
+		// showInput: String [const]
+		//		Position to show an input which shows selected filename(s). Possible
+		//		values are "before", "after", which specifies where the input should
+		//		be placed with reference to the containerNode which contains the
+		//		label). By default, this is empty string (no such input will be
+		//		shown). Specify showInput="before" to mimic the look&feel of a
+		//		native file input element.
+		showInput: "",
+		
+		//	focusedClass: String
+		//		The class applied to the button when it is focused (via TAB key)
+		focusedClass:"dijitButtonHover",
+	
+		_nameIndex:0,
+	
+		templateString: template,
+	
+		baseClass: 'dijitUploader '+Button.prototype.baseClass,
+	
+		postMixInProperties: function(){
+			this._inputs = [];
+			this._cons = [];
+			this.force = this.force.toLowerCase();
+			if(this.supports("multiple")){
+				this.uploadType = this.force === 'form' ? 'form' : 'html5';
+			}else{
+				this.uploadType = this.force === 'flash' ? 'flash' : 'iframe';
+			}
+			
+			this.inherited(arguments);
+		},
+		buildRendering: function(){
+			this.inherited(arguments);
+			domStyle.set(this.domNode, {
+				overflow:"hidden",
+				position:"relative"
+			});
+			this._buildDisplay();
+			//change the button node not occupy tabIndex: the real file input
+			//will have tabIndex set
+			domAttr.set(this.titleNode, 'tabIndex', -1);
+		},
+		_buildDisplay: function(){
+			if(this.showInput){
+				this.displayInput = domConstruct.create('input', {
+					  'class':'dijitUploadDisplayInput',
+					  'tabIndex':-1, 'autocomplete':'off',
+					  'role':'presentation'},
+					this.containerNode, this.showInput);
+				//schedule the attachpoint to be cleaned up on destroy
+				this._attachPoints.push('displayInput');
+				this.connect(this,'onChange', function(files){
+					var i=0,l=files.length, f, r=[];
+					while((f=files[i++])){
+						if(f && f.name){
+							r.push(f.name);
+						}
+					}
+					this.displayInput.value = r.join(', ');
+				});
+				this.connect(this,'reset', function(){
+					this.displayInput.value = '';
 				});
-			}, this);
-		}else{
-			array.forEach(this._inputs, function(n, i){
-				if(n.value){
+			}
+		},
+	
+		startup: function(){
+			if(this._buildInitialized){
+				return;
+			}
+			this._buildInitialized = true;
+			this._getButtonStyle(this.domNode);
+			this._setButtonStyle();
+			this.inherited(arguments);
+		},
+	
+		/*************************
+		 *	   Public Events	 *
+		 *************************/
+	
+		onChange: function(/*Array*/ fileArray){
+			// summary:
+			//		stub to connect
+			//		Fires when files are selected
+			//		Event is an array of last files selected
+		},
+	
+		onBegin: function(/*Array*/ dataArray){
+			// summary:
+			//		Fires when upload begins
+		},
+	
+		onProgress: function(/*Object*/ customEvent){
+			// summary:
+			//		Stub to connect
+			//		Fires on upload progress. Event is a normalized object of common properties
+			//		from HTML5 uploaders and the Flash uploader. Will not fire for IFrame.
+			// customEvent:
+			//		- bytesLoaded: Number:
+			//			Amount of bytes uploaded so far of entire payload (all files)
+			//		- bytesTotal: Number:
+			//			Amount of bytes of entire payload (all files)
+			//		- type: String:
+			//			Type of event (progress or load)
+			//		- timeStamp: Number:
+			//			Timestamp of when event occurred
+		},
+	
+		onComplete: function(/*Object*/ customEvent){
+			// summary:
+			//		stub to connect
+			//		Fires when all files have uploaded
+			//		Event is an array of all files
+			this.reset();
+		},
+	
+		onCancel: function(){
+			// summary:
+			//		Stub to connect
+			//		Fires when dialog box has been closed
+			//		without a file selection
+		},
+	
+		onAbort: function(){
+			// summary:
+			//		Stub to connect
+			//		Fires when upload in progress was canceled
+		},
+	
+		onError: function(/*Object or String*/ evtObject){
+			// summary:
+			//		Fires on errors
+	
+			// FIXME: Unsure of a standard form of error events
+		},
+	
+		/*************************
+		 *	   Public Methods	 *
+		 *************************/
+	
+		upload: function(/*Object?*/ formData){				
+			// summary:
+			//		When called, begins file upload. Only supported with plugins.
+			formData = formData || {};
+			formData.uploadType = this.uploadType;
+			this.inherited(arguments);
+		},
+	
+		submit: function(/*form Node?*/ form){
+			// summary:
+			//		If Uploader is in a form, and other data should be sent along with the files, use
+			//		this instead of form submit.
+			form = !!form ? form.tagName ? form : this.getForm() : this.getForm();
+			var data = domForm.toObject(form);
+			data.uploadType = this.uploadType;
+			this.upload(data);
+		},
+	
+		reset: function(){
+			// summary:
+			//		Resets entire input, clearing all files.
+			//		NOTE:
+			//		Removing individual files is not yet supported, because the HTML5 uploaders can't
+			//		be edited.
+			//		TODO:
+			//		Add this ability by effectively, not uploading them
+			//
+			delete this._files;
+			this._disconnectButton();
+			array.forEach(this._inputs, domConstruct.destroy, dojo);
+			this._inputs = [];
+			this._nameIndex = 0;
+			this._createInput();
+		},
+	
+		getFileList: function(){
+			// summary:
+			//		Returns a list of selected files.
+	
+			var fileArray = [];
+			if(this.supports("multiple")){
+				array.forEach(this._files, function(f, i){
 					fileArray.push({
 						index:i,
-						name:n.value.substring(n.value.lastIndexOf("\\")+1),
-						size:0,
-						type:n.value.substring(n.value.lastIndexOf(".")+1)
+						name:f.name,
+						size:f.size,
+						type:f.type
 					});
-				}
-			}, this);
-
-		}
-		return fileArray; // Array
-	},
-
-	/*********************************************
-	 *	   Private Property. Get off my lawn.	 *
-	 *********************************************/
-
-	_getValueAttr: function(){
-		// summary:
-		//		Internal. To get disabled use: uploader.get("disabled");
-		return this.getFileList();
-	},
-
-	_setValueAttr: function(disabled){
-		console.error("Uploader value is read only");
-	},
-
-	_setDisabledAttr: function(disabled){
-		// summary:
-		//		Internal. To set disabled use: uploader.set("disabled", true);
-		if(this._disabled == disabled){ return; }
-		this.inherited(arguments);
-		domStyle.set(this.inputNode, "display", disabled ? "none" : "");
-	},
-
-	_getButtonStyle: function(node){
-		this.btnSize = {w:domStyle.get(node,'width'), h:domStyle.get(node,'height')};
-	},
-
-	_setButtonStyle: function(){
-		this.inputNodeFontSize = Math.max(2, Math.max(Math.ceil(this.btnSize.w / 60), Math.ceil(this.btnSize.h / 15)));
-		this._createInput();
-	},
-
-	_createInput: function(){
-		if(this._inputs.length){
+				}, this);
+			}else{
+				array.forEach(this._inputs, function(n, i){
+					if(n.value){
+						fileArray.push({
+							index:i,
+							name:n.value.substring(n.value.lastIndexOf("\\")+1),
+							size:0,
+							type:n.value.substring(n.value.lastIndexOf(".")+1)
+						});
+					}
+				}, this);
+	
+			}
+			return fileArray; // Array
+		},
+	
+		/*********************************************
+		 *	   Private Property. Get off my lawn.	 *
+		 *********************************************/
+	
+		_getValueAttr: function(){
+			// summary:
+			//		Internal. To get disabled use: uploader.get("disabled");
+			return this.getFileList();
+		},
+	
+		_setValueAttr: function(disabled){
+			console.error("Uploader value is read only");
+		},
+	
+		_setDisabledAttr: function(disabled){
+			// summary:
+			//		Internal. To set disabled use: uploader.set("disabled", true);
+			if(this.disabled == disabled || !this.inputNode){ return; }
+			this.inherited(arguments);
+			domStyle.set(this.inputNode, "display", disabled ? "none" : "");
+		},
+	
+		_getButtonStyle: function(node){
+			this.btnSize = {w:domStyle.get(node,'width'), h:domStyle.get(node,'height')};
+		},
+	
+		_setButtonStyle: function(){
+			this.inputNodeFontSize = Math.max(2, Math.max(Math.ceil(this.btnSize.w / 60), Math.ceil(this.btnSize.h / 15)));
+			this._createInput();
+		},
+	
+		_getFileFieldName: function(){
+			var name;
+			if(this.supports("multiple") && this.multiple){
+				name = this.name+"s[]";
+			}else{
+				// <=IE8
+				name = this.name + (this.multiple ? this._nameIndex : "");
+			}
+			return name;
+		},
+	
+		_createInput: function(){
+			if(this._inputs.length){
+				domStyle.set(this.inputNode, {
+					top:"500px"
+				});
+				this._disconnectButton();
+				this._nameIndex++;
+			}
+			var name = this._getFileFieldName();
+			// reset focusNode to the inputNode, so when the button is clicked,
+			// the focus is properly moved to the input element
+			this.focusNode = this.inputNode = domConstruct.create("input", {type:"file", name:name, "aria-labelledby":this.id+"_label"}, this.domNode, "first");
+			if(this.supports("multiple") && this.multiple){
+				domAttr.set(this.inputNode, "multiple", true);
+			}
+			this._inputs.push(this.inputNode);
+	
 			domStyle.set(this.inputNode, {
-				top:"500px"
+				position:"absolute",
+				fontSize:this.inputNodeFontSize+"em",
+				top:"-3px",
+				right:"-3px",
+				opacity:0
 			});
-			this._disconnectButton();
-			this._nameIndex++;
-		}
-
-		var name;
-		if(this.supports("multiple")){
-			// FF3.5+, WebKit
-			name = this.name+"s[]";
-		}else{
-			// <=IE8
-			name = this.name + (this.multiple ? this._nameIndex : "");
-		}
-		// reset focusNode to the inputNode, so when the button is clicked,
-		// the focus is properly moved to the input element
-		this.focusNode = this.inputNode = domConstruct.create("input", {type:"file", name:name}, this.domNode, "first");
-		if(this.supports("multiple") && this.multiple){
-			domAttr.set(this.inputNode, "multiple", true);
-		}
-		this._inputs.push(this.inputNode);
-
-		domStyle.set(this.inputNode, {
-			position:"absolute",
-			fontSize:this.inputNodeFontSize+"em",
-			top:"-3px",
-			right:"-3px",
-			opacity:0
-		});
-		this._connectButton();
-	},
-
-	_connectButton: function(){
-		this._cons.push(connect.connect(this.inputNode, "change", this, function(evt){
-			this._files = this.inputNode.files;
-			this.onChange(this.getFileList(evt));
-			if(!this.supports("multiple") && this.multiple) this._createInput();
-		}));
-
-		if(this.tabIndex > -1){
-			this.inputNode.tabIndex = this.tabIndex;
-
-			this._cons.push(connect.connect(this.inputNode, "focus", this, function(){
-				this.titleNode.style.outline= "1px dashed #ccc";
-			}));
-			this._cons.push(connect.connect(this.inputNode, "blur", this, function(){
-				this.titleNode.style.outline = "";
+			this._connectButton();
+		},
+	
+		_connectButton: function(){
+			this._cons.push(connect.connect(this.inputNode, "change", this, function(evt){
+				this._files = this.inputNode.files;
+				this.onChange(this.getFileList(evt));
+				if(!this.supports("multiple") && this.multiple) this._createInput();
 			}));
+	
+			if(this.tabIndex > -1){
+				this.inputNode.tabIndex = this.tabIndex;
+	
+				this._cons.push(connect.connect(this.inputNode, "focus", this, function(){
+					domClass.add(this.domNode, this.focusedClass);
+				}));
+				this._cons.push(connect.connect(this.inputNode, "blur", this, function(){
+					domClass.remove(this.domNode, this.focusedClass);
+				}));
+			}
+		},
+	
+		_disconnectButton: function(){
+			array.forEach(this._cons, connect.disconnect);
+			this._cons.splice(0,this._cons.length);
 		}
-	},
-
-	_disconnectButton: function(){
-		array.forEach(this._cons, connect.disconnect);
-		this._cons.splice(0,this._cons.length);
-	}
-});
-
-	dojox.form.UploaderOrg = dojox.form.Uploader;
-	var extensions = [dojox.form.UploaderOrg];
-	dojox.form.addUploaderPlugin = function(plug){
-		// summary:
-		// 		Handle Uploader plugins. When the dojox.form.addUploaderPlugin() function is called,
-		// 		the dojox.form.Uploader is recreated using the new plugin (mixin).
-		//
-		extensions.push(plug);
-		declare("dojox.form.Uploader", extensions, {});
-	}
+	});
 
-	return dojox.form.Uploader;
 });
diff --git a/dojox/form/YearTextBox.js b/dojox/form/YearTextBox.js
new file mode 100644
index 0000000..9f0ac07
--- /dev/null
+++ b/dojox/form/YearTextBox.js
@@ -0,0 +1,63 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojox/widget/YearlyCalendar",
+	"dijit/form/TextBox",
+	"./DateTextBox",
+	"dojo/_base/declare"
+	], function(kernel, lang, YearlyCalendar, TextBox, DateTextBox, declare){
+		kernel.experimental("dojox/form/DateTextBox");
+		return declare("dojox.form.YearTextBox", DateTextBox,
+		{
+			// summary:
+			//		A validating, serializable, range-bound date text box with a popup calendar that contains only years
+
+			popupClass: YearlyCalendar,
+
+			format: function(value){
+				//console.log('Year format ' + value);
+				if(typeof value == "string"){
+					return value;
+				}
+				else if(value.getFullYear){
+					return value.getFullYear();
+				}
+				return value;
+			},
+
+			validator: function(value){
+				return value == "" || value == null || /(^-?\d\d*$)/.test(String(value));
+			},
+
+			_setValueAttr: function(value, priorityChange, formattedValue){
+				if(value){
+					if(value.getFullYear){
+						value = value.getFullYear();
+					}
+				}
+				TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
+			},
+
+			openDropDown: function(){
+				this.inherited(arguments);
+				//console.log('yearly openDropDown and value = ' + this.get('value'));
+
+				this.dropDown.onValueSelected = lang.hitch(this, function(value){
+					this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
+					setTimeout(lang.hitch(this, "closeDropDown"), 1); // allow focus time to take
+					TextBox.prototype._setValueAttr.call(this,value, true, value);
+				});
+			},
+
+			parse: function(/*String*/ value, /*dojo.date.locale.__FormatOptions*/ constraints){
+				return value || (this._isEmpty(value) ? null : undefined); // Date
+			},
+
+			filter: function(val){
+				if(val && val.getFullYear){
+					return val.getFullYear().toString();
+				}
+				return this.inherited(arguments);
+			}
+		});
+});
diff --git a/dojox/form/_SelectStackMixin.js b/dojox/form/_SelectStackMixin.js
index 5818a31..3d8e96f 100644
--- a/dojox/form/_SelectStackMixin.js
+++ b/dojox/form/_SelectStackMixin.js
@@ -20,11 +20,11 @@ return declare("dojox.form._SelectStackMixin", null, {
 	//		avoid running into unique ID constraint issues, a stackPrefix mechanism
 	//		is provided.
 
-	// stackId: string
+	// stackId: String
 	//		The id of the stack that this widget is supposed to control
 	stackId: "",
 
-	// stackPrefix: string
+	// stackPrefix: String
 	//		A prefix to remove from our stack pane ids when setting our options.
 	//		This exists so that we won't run into unique ID constraints.  For
 	//		example, if stackPrefix is set to "foo_", and there are three panes
@@ -36,12 +36,14 @@ return declare("dojox.form._SelectStackMixin", null, {
 	stackPrefix: "",
 
 	_paneIdFromOption: function(/*String*/ oVal){
-		// summary: Gets the pane ID given an option value
+		// summary:
+		//		Gets the pane ID given an option value
 		return (this.stackPrefix || "") + oVal; // String
 	},
 
 	_optionValFromPane: function(/*String*/ id){
-		// summary: Gets the option value given a pane ID
+		// summary:
+		//		Gets the option value given a pane ID
 		var sp = this.stackPrefix;
 		if(sp && id.indexOf(sp) === 0){
 			return id.substring(sp.length); // String
@@ -50,8 +52,9 @@ return declare("dojox.form._SelectStackMixin", null, {
 	},
 
 	_togglePane: function(/*dijit._Widget*/ pane, /*Boolean*/ shown){
-		// summary: called when a pane is either shown or hidden (so that
-		//  we can toggle the widgets on it)
+		// summary:
+		//		called when a pane is either shown or hidden (so that
+		//		we can toggle the widgets on it)
 
 		if(pane._shown != undefined && pane._shown == shown){ return; }
 		var widgets = array.filter(pane.getDescendants(), "return item.name;");
@@ -94,7 +97,8 @@ return declare("dojox.form._SelectStackMixin", null, {
 	},
 
 	onAddChild: function(/*dijit._Widget*/ pane, /*Integer?*/ insertIndex){
-		// summary: Called when the stack container adds a new pane
+		// summary:
+		//		Called when the stack container adds a new pane
 		if(!this._panes[pane.id]){
 			this._panes[pane.id] = pane;
 			var v = this._optionValFromPane(pane.id);
@@ -114,7 +118,7 @@ return declare("dojox.form._SelectStackMixin", null, {
 		}
 		this.inherited(arguments);
 	},
-	attr: function(/*String|Object*/name, /*Object?*/value){
+	attr: function(/*String|Object*/ name, /*Object?*/ value){
 		if(name == "value" && arguments.length == 2 && "_savedValue" in this){
 			this._savedValue = value;
 		}
@@ -122,7 +126,8 @@ return declare("dojox.form._SelectStackMixin", null, {
 	},
 
 	onRemoveChild: function(/*dijit._Widget*/ pane){
-		// summary: Called when the stack container removes a pane
+		// summary:
+		//		Called when the stack container removes a pane
 		if(this._panes[pane.id]){
 			delete this._panes[pane.id];
 			this.removeOption(this._optionValFromPane(pane.id));
@@ -130,12 +135,14 @@ return declare("dojox.form._SelectStackMixin", null, {
 	},
 
 	onSelectChild: function(/*dijit._Widget*/ pane){
-		// summary: Called when the stack container selects a new pane
+		// summary:
+		//		Called when the stack container selects a new pane
 		this._setValueAttr(this._optionValFromPane(pane.id));
 	},
 
 	onStartup: function(/*Object*/ info){
-		// summary: Called when the stack container is started up
+		// summary:
+		//		Called when the stack container is started up
 		var selPane = info.selected;
 		this.addOption(array.filter(array.map(info.children, function(c){
 			var v = this._optionValFromPane(c.id);
@@ -206,7 +213,8 @@ return declare("dojox.form._SelectStackMixin", null, {
 	},
 
 	_handleSelfOnChange: function(/*String*/ val){
-		// summary: Called when form select widget's value has changed
+		// summary:
+		//		Called when form select widget's value has changed
 		var pane = this._panes[this._paneIdFromOption(val)];
 		if(pane){
 			var s = manager.byId(this.stackId);
@@ -218,4 +226,4 @@ return declare("dojox.form._SelectStackMixin", null, {
 		}
 	}
 });
-});
\ No newline at end of file
+});
diff --git a/dojox/form/manager/_ClassMixin.js b/dojox/form/manager/_ClassMixin.js
index e1c2236..ff14c6d 100644
--- a/dojox/form/manager/_ClassMixin.js
+++ b/dojox/form/manager/_ClassMixin.js
@@ -21,9 +21,9 @@ define([
 		gatherClassState: function(className, names){
 			// summary:
 			//		Gather the presence of a certain class in all controlled elements.
-			// className: String:
+			// className: String
 			//		The class name to test for.
-			// names: Object?:
+			// names: Object?
 			//		If it is an array, it is a list of names to be processed.
 			//		If it is an object, dictionary keys are names to be processed.
 			//		If it is omitted, all known form elements are to be processed.
@@ -38,9 +38,9 @@ define([
 		addClass: function(className, names){
 			// summary:
 			//		Add a class to nodes according to the supplied set of names
-			// className: String:
+			// className: String
 			//		Class name to add.
-			// names: Object?:
+			// names: Object?
 			//		If it is an array, it is a list of names to be processed.
 			//		If it is an object, dictionary keys are names to be processed.
 			//		If it is omitted, all known form elements are to be processed.
@@ -55,9 +55,9 @@ define([
 		removeClass: function(className, names){
 			// summary:
 			//		Remove a class from nodes according to the supplied set of names
-			// className: String:
+			// className: String
 			//		Class name to remove.
-			// names: Object?:
+			// names: Object?
 			//		If it is an array, it is a list of names to be processed.
 			//		If it is an object, dictionary keys are names to be processed.
 			//		If it is omitted, all known form elements are to be processed.
diff --git a/dojox/form/manager/_DisplayMixin.js b/dojox/form/manager/_DisplayMixin.js
index 748ed6d..2bebb6b 100644
--- a/dojox/form/manager/_DisplayMixin.js
+++ b/dojox/form/manager/_DisplayMixin.js
@@ -17,7 +17,7 @@ return declare("dojox.form.manager._DisplayMixin", null, {
 	gatherDisplayState: function(names){
 		// summary:
 		//		Gather display state of all attached elements and return as a dictionary.
-		// names: Object?:
+		// names: Object?
 		//		If it is an array, it is a list of names to be processed.
 		//		If it is an object, dictionary keys are names to be processed.
 		//		If it is omitted, all known attach point nodes are to be processed.
@@ -32,12 +32,12 @@ return declare("dojox.form.manager._DisplayMixin", null, {
 	show: function(state, defaultState){
 		// summary:
 		//		Show attached nodes according to the supplied state object.
-		// state: Object?:
+		// state: Object?
 		//		Optional. If a name-value dictionary, the value is true
 		//		to show and false to hide. If an array, all names in the
 		//		array will be set to defaultState. If omitted, all form
 		//		elements will be set to defaultState.
-		// defaultState: Boolean?:
+		// defaultState: Boolean?
 		//		The default state (true, if omitted).
 
 		if(arguments.length < 2){
@@ -54,7 +54,7 @@ return declare("dojox.form.manager._DisplayMixin", null, {
 	hide: function(state){
 		// summary:
 		//		Hide attached nodes according to the supplied state object.
-		// state: Object?:
+		// state: Object?
 		//		Optional. If a name-value dictionary, the value is true
 		//		to show and false to hide. If an array, all names in the
 		//		array will be hidden. If omitted, all form elements
diff --git a/dojox/form/manager/_EnableMixin.js b/dojox/form/manager/_EnableMixin.js
index 8308cbf..6775519 100644
--- a/dojox/form/manager/_EnableMixin.js
+++ b/dojox/form/manager/_EnableMixin.js
@@ -21,7 +21,7 @@ define([
 		gatherEnableState: function(names){
 			// summary:
 			//		Gather enable state of all form elements and return as a dictionary.
-			// names: Object?:
+			// names: Object?
 			//		If it is an array, it is a list of names to be processed.
 			//		If it is an object, dictionary keys are names to be processed.
 			//		If it is omitted, all known form elements are to be processed.
@@ -42,12 +42,12 @@ define([
 		enable: function(state, defaultState){
 			// summary:
 			//		Enable form controls according to the supplied state object.
-			// state: Object?:
+			// state: Object?
 			//		Optional. If a name-value dictionary, the value is true
 			//		to enable and false to disable. If an array, all names in the
 			//		array will be set to defaultState. If omitted, all form
 			//		elements will be set to defaultState.
-			// defaultState: Boolean:
+			// defaultState: Boolean
 			//		The default state (true, if omitted).
 
 			if(arguments.length < 2 || defaultState === undefined){
@@ -71,7 +71,7 @@ define([
 			// summary:
 			//		Disable form controls according to the supplied state object
 			//		returning the previous state.
-			// state: Object?:
+			// state: Object?
 			//		Optional. If a name-value dictionary, the value is true
 			//		to enable and false to disable. If an array, all names in the
 			//		array will be disabled. If omitted, disables all.
diff --git a/dojox/form/manager/_FormMixin.js b/dojox/form/manager/_FormMixin.js
index 5b876f8..667387d 100644
--- a/dojox/form/manager/_FormMixin.js
+++ b/dojox/form/manager/_FormMixin.js
@@ -39,7 +39,7 @@ define([
 		// form-specific functionality
 
 		_onReset: function(evt){
-			// NOTE: this function is taken from dijit.formForm, it works only
+			// NOTE: this function is taken from dijit.form.Form, it works only
 			// for form-based managers.
 
 			// create fake event so we can know if preventDefault() is called
@@ -59,7 +59,7 @@ define([
 		},
 
 		onReset: function(){
-			//	summary:
+			// summary:
 			//		Callback when user resets the form. This method is intended
 			//		to be over-ridden. When the `reset` method is called
 			//		programmatically, the return value from `onReset` is used
@@ -91,7 +91,7 @@ define([
 		},
 
 		onSubmit: function(){
-			//	summary:
+			// summary:
 			//		Callback when user submits the form. This method is
 			//		intended to be over-ridden, but by default it checks and
 			//		returns the validity of form elements. When the `submit`
@@ -129,6 +129,11 @@ define([
 			return true;
 		},
 		validate: function(){
+			// summary:
+			//		validate() returns if the form is valid - same as isValid - 
+			//		but provides a few additional (ui-specific) features: it 
+			//		will highlight any sub-widgets that are not valid it will 
+			//		call focus() on the first invalid sub-widget
 			var isValid = true,
 				formWidgets = this.formWidgets,
 				didFocus = false, name;
diff --git a/dojox/form/manager/_Mixin.js b/dojox/form/manager/_Mixin.js
index a75aa7b..6c659c6 100644
--- a/dojox/form/manager/_Mixin.js
+++ b/dojox/form/manager/_Mixin.js
@@ -2,7 +2,7 @@ define([
 	"dojo/_base/window",
 	"dojo/_base/lang",
 	"dojo/_base/array",
-	"dojo/_base/connect",
+	"dojo/on",
 	"dojo/dom-attr",
 	"dojo/dom-class",
 	"dijit/_base/manager",
@@ -11,8 +11,8 @@ define([
 	"dijit/form/Button",
 	"dijit/form/CheckBox",
 	"dojo/_base/declare"
-], function(win, lang, array, connect, domAttr, domClass, manager, Widget, FormWidget, Button, CheckBox, declare){
-	// XXX: This class is loading a bunch of extra widgets just to perform isInstanceOf operations,
+], function(win, lang, array, on, domAttr, domClass, manager, Widget, FormWidget, Button, CheckBox, declare){
+	// TODO: This class is loading a bunch of extra widgets just to perform isInstanceOf operations,
 	// which is wasteful
 
 	var fm = lang.getObject("dojox.form.manager", true),
@@ -20,7 +20,7 @@ define([
 		aa = fm.actionAdapter = function(action){
 			// summary:
 			//		Adapter that automates application of actions to arrays.
-			// action: Function:
+			// action: Function
 			//		Function that takes three parameters: a name, an object
 			//		(usually node or widget), and a value. This action will
 			//		be applied to all elements of array.
@@ -38,7 +38,7 @@ define([
 		ia = fm.inspectorAdapter = function(inspector){
 			// summary:
 			//		Adapter that applies an inspector only to the first item of the array.
-			// inspector: Function:
+			// inspector: Function
 			//		Function that takes three parameters: a name, an object
 			//		(usually node or widget), and a value.
 			return function(name, elem, value){
@@ -61,7 +61,7 @@ define([
 
 		registerWidget = function(widget){
 			var name = widget.get("name");
-			if(name && widget instanceof FormWidget){
+			if(name && widget.isInstanceOf(FormWidget)){
 				if(name in this.formWidgets){
 					var a = this.formWidgets[name].widget;
 					if(lang.isArray(a)){
@@ -81,7 +81,7 @@ define([
 		getObserversFromWidget = function(name){
 			var observers = {};
 			aa(function(_, w){
-				var o = w.get("observer");
+				var o = w.get("data-dojo-observer") || w.get("observer");
 				if(o && typeof o == "string"){
 					array.forEach(o.split(","), function(o){
 						o = lang.trim(o);
@@ -97,34 +97,34 @@ define([
 		connectWidget = function(name, observers){
 			var t = this.formWidgets[name], w = t.widget, c = t.connections;
 			if(c.length){
-				array.forEach(c, connect.disconnect);
+				array.forEach(c, function(item){ item.remove(); });
 				c = t.connections = [];
 			}
 			if(lang.isArray(w)){
 				// radio buttons
 				array.forEach(w, function(w){
 					array.forEach(observers, function(o){
-						c.push(connect.connect(w, "onChange", this, function(evt){
+						c.push(on(w, "change", lang.hitch(this, function(evt){
 							// TODO: for some reason for radio button widgets
 							// w.checked != w.focusNode.checked when value changes.
 							// We test the underlying value to be 100% sure.
 							if(this.watching && domAttr.get(w.focusNode, "checked")){
 								this[o](w.get("value"), name, w, evt);
 							}
-						}));
+						})));
 					}, this);
 				}, this);
 			}else{
 				// the rest
 				// the next line is a crude workaround for Button that fires onClick instead of onChange
 				var eventName = w.isInstanceOf(Button) ?
-						"onClick" : "onChange";
+						"click" : "change";
 				array.forEach(observers, function(o){
-					c.push(connect.connect(w, eventName, this, function(evt){
+					c.push(on(w, eventName, lang.hitch(this, function(evt){
 						if(this.watching){
 							this[o](w.get("value"), name, w, evt);
 						}
-					}));
+					})));
 				}, this);
 			}
 		};
@@ -133,7 +133,7 @@ define([
 		// summary:
 		//		Mixin to orchestrate dynamic forms.
 		// description:
-		//		This mixin provideas a foundation for an enhanced form
+		//		This mixin provides a foundation for an enhanced form
 		//		functionality: unified access to individual form elements,
 		//		unified "onchange" event processing, general event
 		//		processing, I/O orchestration, and common form-related
@@ -161,7 +161,9 @@ define([
 			//		Called when the widget is being destroyed
 
 			for(var name in this.formWidgets){
-				array.forEach(this.formWidgets[name].connections, connect.disconnect);
+				array.forEach(this.formWidgets[name].connections, function(item){
+					item.remove();
+				});
 			}
 			this.formWidgets = {};
 
@@ -173,9 +175,9 @@ define([
 		registerWidget: function(widget){
 			// summary:
 			//		Register a widget with the form manager
-			// widget: String|Node|dijit.form._FormWidget:
+			// widget: String|Node|dijit/form/_FormWidget
 			//		A widget, or its widgetId, or its DOM node
-			// returns: Object:
+			// returns: Object
 			//		Returns self
 			if(typeof widget == "string"){
 				widget = manager.byId(widget);
@@ -193,12 +195,14 @@ define([
 			// summary:
 			//		Removes the widget by name from internal tables unregistering
 			//		connected observers
-			// name: String:
+			// name: String
 			//		Name of the to unregister
-			// returns: Object:
+			// returns: Object
 			//		Returns self
 			if(name in this.formWidgets){
-				array.forEach(this.formWidgets[name].connections, this.disconnect, this);
+				array.forEach(this.formWidgets[name].connections, function(item){
+					item.remove();
+				});
 				delete this.formWidgets[name];
 			}
 			return this;
@@ -207,9 +211,9 @@ define([
 		registerWidgetDescendants: function(widget){
 			// summary:
 			//		Register widget's descendants with the form manager
-			// widget: String|Node|dijit._Widget:
+			// widget: String|Node|dijit._Widget
 			//		A widget, or its widgetId, or its DOM node
-			// returns: Object:
+			// returns: Object
 			//		Returns self
 
 			// convert to widget, if required
@@ -237,9 +241,9 @@ define([
 		unregisterWidgetDescendants: function(widget){
 			// summary:
 			//		Unregister widget's descendants with the form manager
-			// widget: String|Node|dijit._Widget:
+			// widget: String|Node|dijit/_Widget
 			//		A widget, or its widgetId, or its DOM node
-			// returns: Object:
+			// returns: Object
 			//		Returns self
 
 			// convert to widget, if required
@@ -259,7 +263,7 @@ define([
 				),
 				function(name){
 					if(name){
-						this.unregisterNode(name);
+						this.unregisterWidget(name);
 					}
 				},
 				this
@@ -275,11 +279,11 @@ define([
 		formWidgetValue: function(elem, value){
 			// summary:
 			//		Set or get a form widget by name.
-			// elem: String|Object|Array:
+			// elem: String|Object|Array
 			//		Form element's name, widget object, or array or radio widgets.
-			// value: Object?:
+			// value: Object?
 			//		Optional. The value to set.
-			// returns: Object:
+			// returns: Object
 			//		For a getter it returns the value, for a setter it returns
 			//		self. If the elem is not valid, null will be returned.
 
@@ -301,10 +305,10 @@ define([
 				if(isSetter){
 					array.forEach(elem, function(widget){
 						widget.set("checked", false, !this.watching);
-					});
+					}, this);
 					array.forEach(elem, function(widget){
 						widget.set("checked", widget.value === value, !this.watching);
-					});
+					}, this);
 					return this;	// self
 				}
 				// getter
@@ -342,11 +346,11 @@ define([
 		formPointValue: function(elem, value){
 			// summary:
 			//		Set or get a node context by name (using dojoAttachPoint).
-			// elem: String|Object|Array:
+			// elem: String|Object|Array
 			//		A node.
-			// value: Object?:
+			// value: Object?
 			//		Optional. The value to set.
-			// returns: Object:
+			// returns: Object
 			//		For a getter it returns the value, for a setter it returns
 			//		self. If the elem is not valid, null will be returned.
 
@@ -377,15 +381,15 @@ define([
 		inspectFormWidgets: function(inspector, state, defaultValue){
 			// summary:
 			//		Run an inspector function on controlled widgets returning a result object.
-			// inspector: Function:
+			// inspector: Function
 			//		A function to be called on a widget. Takes three arguments: a name, a widget object
 			//		or an array of widget objects, and a supplied value. Runs in the context of
 			//		the form manager. Returns a value that will be collected and returned as a state.
-			// state: Object?:
+			// state: Object?
 			//		Optional. If a name-value dictionary --- only listed names will be processed.
 			//		If an array, all names in the array will be processed with defaultValue.
 			//		If omitted or null, all widgets will be processed with defaultValue.
-			// defaultValue: Object?:
+			// defaultValue: Object?
 			//		Optional. The default state (true, if omitted).
 
 			var name, result = {};
@@ -416,30 +420,30 @@ define([
 		inspectAttachedPoints: function(inspector, state, defaultValue){
 			// summary:
 			//		Run an inspector function on "dojoAttachPoint" nodes returning a result object.
-			// inspector: Function:
+			// inspector: Function
 			//		A function to be called on a node. Takes three arguments: a name, a node or
 			//		an array of nodes, and a supplied value. Runs in the context of the form manager.
 			//		Returns a value that will be collected and returned as a state.
-			// state: Object?:
+			// state: Object?
 			//		Optional. If a name-value dictionary --- only listed names will be processed.
 			//		If an array, all names in the array will be processed with defaultValue.
 			//		If omitted or null, all attached point nodes will be processed with defaultValue.
-			// defaultValue: Object?:
+			// defaultValue: Object?
 			//		Optional. The default state (true, if omitted).
 
-			var name, result = {};
+			var name, elem, result = {};
 
 			if(state){
 				if(lang.isArray(state)){
 					array.forEach(state, function(name){
-						var elem = this[name];
+						elem = this[name];
 						if(elem && elem.tagName && elem.cloneNode){
 							result[name] = inspector.call(this, name, elem, defaultValue);
 						}
 					}, this);
 				}else{
 					for(name in state){
-						var elem = this[name];
+						elem = this[name];
 						if(elem && elem.tagName && elem.cloneNode){
 							result[name] = inspector.call(this, name, elem, state[name]);
 						}
@@ -448,7 +452,7 @@ define([
 			}else{
 				for(name in this){
 					if(!(name in skipNames)){
-						var elem = this[name];
+						elem = this[name];
 						if(elem && elem.tagName && elem.cloneNode){
 							result[name] = inspector.call(this, name, elem, defaultValue);
 						}
@@ -462,16 +466,16 @@ define([
 		inspect: function(inspector, state, defaultValue){
 			// summary:
 			//		Run an inspector function on controlled elements returning a result object.
-			// inspector: Function:
+			// inspector: Function
 			//		A function to be called on a widget, form element, and an attached node.
 			//		Takes three arguments: a name, a node (domNode in the case of widget) or
 			//		an array of such objects, and a supplied value. Runs in the context of
 			//		the form manager. Returns a value that will be collected and returned as a state.
-			// state: Object?:
+			// state: Object?
 			//		Optional. If a name-value dictionary --- only listed names will be processed.
 			//		If an array, all names in the array will be processed with defaultValue.
 			//		If omitted or null, all controlled elements will be processed with defaultValue.
-			// defaultValue: Object?:
+			// defaultValue: Object?
 			//		Optional. The default state (true, if omitted).
 
 			var result = this.inspectFormWidgets(function(name, widget, value){
diff --git a/dojox/form/manager/_NodeMixin.js b/dojox/form/manager/_NodeMixin.js
index 643a562..2e0f53c 100644
--- a/dojox/form/manager/_NodeMixin.js
+++ b/dojox/form/manager/_NodeMixin.js
@@ -1,7 +1,7 @@
 define([
 	"dojo/_base/lang",
 	"dojo/_base/array",
-	"dojo/_base/connect",
+	"dojo/on",
 	"dojo/dom",
 	"dojo/dom-attr",
 	"dojo/query",
@@ -9,7 +9,7 @@ define([
 	"dijit/form/_FormWidget",
 	"dijit/_base/manager",
 	"dojo/_base/declare"
-], function(lang, array, connect, dom, domAttr, query, _Mixin, _FormWidget, manager, declare){
+], function(lang, array, on, dom, domAttr, query, _Mixin, _FormWidget, manager, declare){
 	var fm = lang.getObject("dojox.form.manager", true),
 		aa = fm.actionAdapter,
 		keys = fm._keys,
@@ -17,22 +17,22 @@ define([
 		ce = fm.changeEvent = function(node){
 			// summary:
 			//		Function that returns a valid "onchange" event for a given form node.
-			// node: Node:
+			// node: Node
 			//		Form node.
 
-			var eventName = "onclick";
+			var eventName = "click";
 			switch(node.tagName.toLowerCase()){
 				case "textarea":
-					eventName = "onkeyup";
+					eventName = "keyup";
 					break;
 				case "select":
-					eventName = "onchange";
+					eventName = "change";
 					break;
 				case "input":
 					switch(node.type.toLowerCase()){
 						case "text":
 						case "password":
-							eventName = "onkeyup";
+							eventName = "keyup";
 							break;
 					}
 					break;
@@ -75,7 +75,7 @@ define([
 		getObserversFromNode = function(name){
 			var observers = {};
 			aa(function(_, n){
-				var o = domAttr.get(n, "observer");
+				var o = domAttr.get(n, "data-dojo-observer") || domAttr.get(n, "observer");
 				if(o && typeof o == "string"){
 					array.forEach(o.split(","), function(o){
 						o = lang.trim(o);
@@ -91,18 +91,18 @@ define([
 		connectNode = function(name, observers){
 			var t = this.formNodes[name], c = t.connections;
 			if(c.length){
-				array.forEach(c, connect.disconnect);
+				array.forEach(c, function(item){ item.remove(); });
 				c = t.connections = [];
 			}
 			aa(function(_, n){
 				// the next line is a crude workaround for Button that fires onClick instead of onChange
 				var eventName = ce(n);
 				array.forEach(observers, function(o){
-					c.push(connect.connect(n, eventName, this, function(evt){
+					c.push(on(n, eventName, lang.hitch(this, function(evt){
 						if(this.watching){
 							this[o](this.formNodeValue(name), name, n, evt);
 						}
-					}));
+					})));
 				}, this);
 			}).call(this, null, t.node);
 		};
@@ -111,10 +111,10 @@ define([
 		// summary:
 		//		Mixin to orchestrate dynamic forms (works with DOM nodes).
 		// description:
-		//		This mixin provideas a foundation for an enhanced form
+		//		This mixin provides a foundation for an enhanced form
 		//		functionality: unified access to individual form elements,
-		//		unified "onchange" event processing, and general event
-		//		processing. It complements dojox.form.manager._Mixin
+		//		unified "change" event processing, and general event
+		//		processing. It complements dojox/form/manager/_Mixin
 		//		extending the functionality to DOM nodes.
 
 		destroy: function(){
@@ -122,7 +122,9 @@ define([
 			//		Called when the widget is being destroyed
 
 			for(var name in this.formNodes){
-				array.forEach(this.formNodes[name].connections, connect.disconnect);
+				array.forEach(this.formNodes[name].connections, function(item){
+					item.remove();
+				});
 			}
 			this.formNodes = {};
 
@@ -134,9 +136,9 @@ define([
 		registerNode: function(node){
 			// summary:
 			//		Register a node with the form manager
-			// node: String|Node:
+			// node: String|Node
 			//		A node, or its id
-			// returns: Object:
+			// returns: Object
 			//		Returns self
 			if(typeof node == "string"){
 				node = dom.byId(node);
@@ -152,12 +154,14 @@ define([
 			// summary:
 			//		Removes the node by name from internal tables unregistering
 			//		connected observers
-			// name: String:
+			// name: String
 			//		Name of the to unregister
-			// returns: Object:
+			// returns: Object
 			//		Returns self
 			if(name in this.formNodes){
-				array.forEach(this.formNodes[name].connections, this.disconnect, this);
+				array.forEach(this.formNodes[name].connections, function(item){
+					item.remove();
+				});
 				delete this.formNodes[name];
 			}
 			return this;
@@ -166,9 +170,9 @@ define([
 		registerNodeDescendants: function(node){
 			// summary:
 			//		Register node's descendants (form nodes) with the form manager
-			// node: String|Node:
+			// node: String|Node
 			//		A widget, or its widgetId, or its DOM node
-			// returns: Object:
+			// returns: Object
 			//		Returns self
 
 			if(typeof node == "string"){
@@ -191,9 +195,9 @@ define([
 		unregisterNodeDescendants: function(node){
 			// summary:
 			//		Unregister node's descendants (form nodes) with the form manager
-			// node: String|Node:
+			// node: String|Node
 			//		A widget, or its widgetId, or its DOM node
-			// returns: Object:
+			// returns: Object
 			//		Returns self
 
 			if(typeof node == "string"){
@@ -216,11 +220,11 @@ define([
 		formNodeValue: function(elem, value){
 			// summary:
 			//		Set or get a form element by name.
-			// elem: String|Node|Array:
+			// elem: String|Node|Array
 			//		Form element's name, DOM node, or array or radio nodes.
-			// value: Object?:
+			// value: Object?
 			//		Optional. The value to set.
-			// returns: Object:
+			// returns: Object
 			//		For a getter it returns the value, for a setter it returns
 			//		self. If the elem is not valid, null will be returned.
 
@@ -281,7 +285,7 @@ define([
 							return this;	// self
 						}
 						// getter
-						var result = query("> option", elem).filter(function(opt){
+						result = query("> option", elem).filter(function(opt){
 							return opt.selected;
 						}).map(function(opt){
 							return opt.value;
@@ -329,15 +333,15 @@ define([
 		inspectFormNodes: function(inspector, state, defaultValue){
 			// summary:
 			//		Run an inspector function on controlled form elements returning a result object.
-			// inspector: Function:
+			// inspector: Function
 			//		A function to be called on a form element. Takes three arguments: a name, a node or
 			//		an array of nodes, and a supplied value. Runs in the context of the form manager.
 			//		Returns a value that will be collected and returned as a state.
-			// state: Object?:
+			// state: Object?
 			//		Optional. If a name-value dictionary --- only listed names will be processed.
 			//		If an array, all names in the array will be processed with defaultValue.
 			//		If omitted or null, all form elements will be processed with defaultValue.
-			// defaultValue: Object?:
+			// defaultValue: Object?
 			//		Optional. The default state (true, if omitted).
 
 			var name, result = {};
diff --git a/dojox/form/manager/_ValueMixin.js b/dojox/form/manager/_ValueMixin.js
index 3ce0062..c0e48b8 100644
--- a/dojox/form/manager/_ValueMixin.js
+++ b/dojox/form/manager/_ValueMixin.js
@@ -14,9 +14,9 @@ return declare("dojox.form.manager._ValueMixin", null, {
 	elementValue: function(name, value){
 		// summary:
 		//		Set or get a form widget/element or an attached point node by name.
-		// name: String:
+		// name: String
 		//		The name.
-		// value: Object?:
+		// value: Object?
 		//		Optional. The value to set.
 
 		if(name in this.formWidgets){
@@ -33,7 +33,7 @@ return declare("dojox.form.manager._ValueMixin", null, {
 	gatherFormValues: function(names){
 		// summary:
 		//		Collect form values.
-		// names: Object?:
+		// names: Object?
 		//		If it is an array, it is a list of names of form elements to be collected.
 		//		If it is an object, dictionary keys are names to be collected.
 		//		If it is omitted, all known form elements are to be collected.
@@ -58,7 +58,7 @@ return declare("dojox.form.manager._ValueMixin", null, {
 	setFormValues: function(values){
 		// summary:
 		//		Set values to form elements
-		// values: Object:
+		// values: Object
 		//		A dictionary of key-value pairs.
 		if(values){
 			this.inspectFormWidgets(function(name, widget, value){
diff --git a/dojox/form/nls/CheckedMultiSelect.js b/dojox/form/nls/CheckedMultiSelect.js
index d395164..0ee1a39 100644
--- a/dojox/form/nls/CheckedMultiSelect.js
+++ b/dojox/form/nls/CheckedMultiSelect.js
@@ -8,6 +8,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -25,6 +26,7 @@ define({ root:
 "it": true,
 "hu": true,
 "hr": true,
+"he": true,
 "fr": true,
 "fi": true,
 "es": true,
@@ -32,5 +34,6 @@ define({ root:
 "de": true,
 "da": true,
 "cs": true,
-"ca": true
+"ca": true,
+"bg": true
 });
diff --git a/dojox/form/nls/PasswordValidator.js b/dojox/form/nls/PasswordValidator.js
index 2832e0f..9ad0369 100644
--- a/dojox/form/nls/PasswordValidator.js
+++ b/dojox/form/nls/PasswordValidator.js
@@ -8,6 +8,7 @@ define({ root:
 ,
 "ar": true,
 "az": true,
+"bg": true,
 "ca": true,
 "cs": true,
 "da": true,
@@ -35,6 +36,7 @@ define({ root:
 "sv": true,
 "th": true,
 "tr": true,
+"uk": true,
 "zh": true,
 "zh-tw": true
 });
diff --git a/dojox/form/nls/Uploader.js b/dojox/form/nls/Uploader.js
index 8f1aab7..a18314b 100644
--- a/dojox/form/nls/Uploader.js
+++ b/dojox/form/nls/Uploader.js
@@ -7,6 +7,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -24,6 +25,7 @@ define({ root:
 "it": true,
 "hu": true,
 "hr": true,
+"he": true,
 "fr": true,
 "fi": true,
 "es": true,
@@ -31,5 +33,6 @@ define({ root:
 "de": true,
 "da": true,
 "cs": true,
-"ca": true
+"ca": true,
+"bg": true
 });
diff --git a/dojox/form/nls/ar/CheckedMultiSelect.js b/dojox/form/nls/ar/CheckedMultiSelect.js
new file mode 100644
index 0000000..d48e920
--- /dev/null
+++ b/dojox/form/nls/ar/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "يجب تحديد بند واحد على الأقل. ",
+	multiSelectLabelText: "تم تحديد {num} بند/بنود"
+})
+);
diff --git a/dojox/form/nls/ar/PasswordValidator.js b/dojox/form/nls/ar/PasswordValidator.js
index 092a83f..bf68a02 100644
--- a/dojox/form/nls/ar/PasswordValidator.js
+++ b/dojox/form/nls/ar/PasswordValidator.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "كلمات السرية غير مطابقة.",
-		badPasswordMessage: "كلمة سرية غير صحيحة."
+	badPasswordMessage: "كلمة سرية غير صحيحة."
 })
-//end v1.x content
 );
diff --git a/dojox/form/nls/ar/Uploader.js b/dojox/form/nls/ar/Uploader.js
new file mode 100644
index 0000000..29a491f
--- /dev/null
+++ b/dojox/form/nls/ar/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "تحديد ملفات..."
+})
+);
diff --git a/dojox/form/nls/az/PasswordValidator.js b/dojox/form/nls/az/PasswordValidator.js
index 31a42d3..ae1f5d9 100644
--- a/dojox/form/nls/az/PasswordValidator.js
+++ b/dojox/form/nls/az/PasswordValidator.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 	"badPasswordMessage" : "Səhv şifrə.",
 	"nomatchMessage" : "Şifrələr eyni deyil."
 })
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/bg/CheckedMultiSelect.js b/dojox/form/nls/bg/CheckedMultiSelect.js
new file mode 100644
index 0000000..4b478e8
--- /dev/null
+++ b/dojox/form/nls/bg/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Трябва да бъде избран поне един елемент.",
+	multiSelectLabelText: "избран/и {num} елемент/и"
+})
+);
diff --git a/dojox/form/nls/bg/PasswordValidator.js b/dojox/form/nls/bg/PasswordValidator.js
new file mode 100644
index 0000000..50b2220
--- /dev/null
+++ b/dojox/form/nls/bg/PasswordValidator.js
@@ -0,0 +1,6 @@
+define(
+({
+	nomatchMessage: "Паролите не съвпадат.",
+	badPasswordMessage: "Невалидна парола."
+})
+);
diff --git a/dojox/form/nls/bg/Uploader.js b/dojox/form/nls/bg/Uploader.js
new file mode 100644
index 0000000..d202a45
--- /dev/null
+++ b/dojox/form/nls/bg/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Избери файлове..."
+})
+);
diff --git a/dojox/form/nls/ca/PasswordValidator.js b/dojox/form/nls/ca/PasswordValidator.js
index aa58ea8..fb5fb4f 100644
--- a/dojox/form/nls/ca/PasswordValidator.js
+++ b/dojox/form/nls/ca/PasswordValidator.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Les contrasenyes no coincideixen",
-		badPasswordMessage: "La contrasenya no és correcta"
+	badPasswordMessage: "La contrasenya no és correcta"
 })
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/cs/PasswordValidator.js b/dojox/form/nls/cs/PasswordValidator.js
index d07f32e..a6461c2 100644
--- a/dojox/form/nls/cs/PasswordValidator.js
+++ b/dojox/form/nls/cs/PasswordValidator.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Hesla se neshodují.",
-		badPasswordMessage: "Neplatné heslo."
+	badPasswordMessage: "Neplatné heslo."
 })
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/da/PasswordValidator.js b/dojox/form/nls/da/PasswordValidator.js
index fbe94c7..5b91a38 100644
--- a/dojox/form/nls/da/PasswordValidator.js
+++ b/dojox/form/nls/da/PasswordValidator.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
-        nomatchMessage: "Adgangskoderne stemmer ikke overens.",
-		badPasswordMessage: "Ugyldig adgangskode."
+        nomatchMessage: "Kodeordene stemmer ikke overens.",
+	badPasswordMessage: "Ugyldigt kodeord."
 })
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/de/CheckedMultiSelect.js b/dojox/form/nls/de/CheckedMultiSelect.js
index ce8e895..15670d8 100644
--- a/dojox/form/nls/de/CheckedMultiSelect.js
+++ b/dojox/form/nls/de/CheckedMultiSelect.js
@@ -1,6 +1,6 @@
 define(
 ({
-	invalidMessage: "Es muss mindestens ein Element ausgewählt werden.",
-	multiSelectLabelText: "{num} Element(e) ausgewählt"
+	invalidMessage: "Es muss mindestens ein Eintrag ausgewählt werden.",
+	multiSelectLabelText: "{num} Eintrag/Einträge ausgewählt"
 })
 );
diff --git a/dojox/form/nls/de/PasswordValidator.js b/dojox/form/nls/de/PasswordValidator.js
index eb2bf65..182c6dd 100644
--- a/dojox/form/nls/de/PasswordValidator.js
+++ b/dojox/form/nls/de/PasswordValidator.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Die Kennwörter stimmen nicht überein.",
-		badPasswordMessage: "Ungültiges Kennwort."
+	badPasswordMessage: "Ungültiges Kennwort."
 })
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/el/PasswordValidator.js b/dojox/form/nls/el/PasswordValidator.js
index e89a600..459596d 100644
--- a/dojox/form/nls/el/PasswordValidator.js
+++ b/dojox/form/nls/el/PasswordValidator.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Οι κωδικοί πρόσβασης δεν συμφωνούν.",
-		badPasswordMessage: "Μη έγκυρος κωδικός πρόσβασης."
+	badPasswordMessage: "Μη έγκυρος κωδικός πρόσβασης."
 })
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/es/PasswordValidator.js b/dojox/form/nls/es/PasswordValidator.js
index 1ca3989..4589732 100644
--- a/dojox/form/nls/es/PasswordValidator.js
+++ b/dojox/form/nls/es/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Las contraseñas no coinciden.",
-		badPasswordMessage: "Contraseña no válida."
+	badPasswordMessage: "Contraseña no válida."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/fi/PasswordValidator.js b/dojox/form/nls/fi/PasswordValidator.js
index 28e3e1b..1073b8f 100644
--- a/dojox/form/nls/fi/PasswordValidator.js
+++ b/dojox/form/nls/fi/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Salasanat eivät täsmää.",
-		badPasswordMessage: "Salasana ei kelpaa."
+	badPasswordMessage: "Salasana ei kelpaa."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/fr/PasswordValidator.js b/dojox/form/nls/fr/PasswordValidator.js
index c454136..b23bec5 100644
--- a/dojox/form/nls/fr/PasswordValidator.js
+++ b/dojox/form/nls/fr/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Les mots de passe ne correspondent pas.",
-		badPasswordMessage: "Mot de passe incorrect."
+	badPasswordMessage: "Mot de passe incorrect."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/he/CheckedMultiSelect.js b/dojox/form/nls/he/CheckedMultiSelect.js
new file mode 100644
index 0000000..aa94ed3
--- /dev/null
+++ b/dojox/form/nls/he/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "יש לבחור לפחות פריט אחד.  ",
+	multiSelectLabelText: "{num} פריטים נבחרו "
+})
+);
diff --git a/dojox/form/nls/he/PasswordValidator.js b/dojox/form/nls/he/PasswordValidator.js
index 7f142bd..a3c8586 100644
--- a/dojox/form/nls/he/PasswordValidator.js
+++ b/dojox/form/nls/he/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "הסיסמאות אינן זהות.",
-		badPasswordMessage: "סיסמה לא חוקית."
+	badPasswordMessage: "סיסמה לא חוקית."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/he/Uploader.js b/dojox/form/nls/he/Uploader.js
new file mode 100644
index 0000000..93e5a07
--- /dev/null
+++ b/dojox/form/nls/he/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "בחירת קבצים...‏"
+})
+);
diff --git a/dojox/form/nls/hu/PasswordValidator.js b/dojox/form/nls/hu/PasswordValidator.js
index 3a14fe8..71b895f 100644
--- a/dojox/form/nls/hu/PasswordValidator.js
+++ b/dojox/form/nls/hu/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "A jelszavak nem egyeznek.",
-		badPasswordMessage: "Érvénytelen jelszó."
+	badPasswordMessage: "Érvénytelen jelszó."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/it/PasswordValidator.js b/dojox/form/nls/it/PasswordValidator.js
index 9f16917..25d6615 100644
--- a/dojox/form/nls/it/PasswordValidator.js
+++ b/dojox/form/nls/it/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Le password non corrispondono.",
-		badPasswordMessage: "Password non valida."
+	badPasswordMessage: "Password non valida."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/ja/PasswordValidator.js b/dojox/form/nls/ja/PasswordValidator.js
index 6656b20..0bd0392 100644
--- a/dojox/form/nls/ja/PasswordValidator.js
+++ b/dojox/form/nls/ja/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "パスワードが一致しません。",
-		badPasswordMessage: "無効なパスワードです。"
+	badPasswordMessage: "無効なパスワードです。"
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/kk/PasswordValidator.js b/dojox/form/nls/kk/PasswordValidator.js
index 88eecd5..8c4782e 100644
--- a/dojox/form/nls/kk/PasswordValidator.js
+++ b/dojox/form/nls/kk/PasswordValidator.js
@@ -1,5 +1,6 @@
+define(
 ({
         nomatchMessage: "Құпия сөздер сәйкес емес.",
-		badPasswordMessage: "Құпия сөз дұрыс емес."
+	badPasswordMessage: "Құпия сөз дұрыс емес."
 })
-
+);
diff --git a/dojox/form/nls/ko/PasswordValidator.js b/dojox/form/nls/ko/PasswordValidator.js
index 4c3b48f..73d4147 100644
--- a/dojox/form/nls/ko/PasswordValidator.js
+++ b/dojox/form/nls/ko/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "비밀번호가 일치하지 않습니다.",
-		badPasswordMessage: "올바르지 않은 비밀번호"
+	badPasswordMessage: "올바르지 않은 비밀번호"
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/nb/PasswordValidator.js b/dojox/form/nls/nb/PasswordValidator.js
index 74d430e..0507965 100644
--- a/dojox/form/nls/nb/PasswordValidator.js
+++ b/dojox/form/nls/nb/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Passordene samsvarer ikke.",
-		badPasswordMessage: "Ugyldig passord."
+	badPasswordMessage: "Ugyldig passord."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/nl/CheckedMultiSelect.js b/dojox/form/nls/nl/CheckedMultiSelect.js
index c2130bc..b9ec3d4 100644
--- a/dojox/form/nls/nl/CheckedMultiSelect.js
+++ b/dojox/form/nls/nl/CheckedMultiSelect.js
@@ -1,6 +1,6 @@
 define(
 ({
-	invalidMessage: "Er moet te minste één item worden geselecteerd.",
+	invalidMessage: "Er moet ten minste één item geselecteerd worden.",
 	multiSelectLabelText: "{num} item(s) geselecteerd"
 })
 );
diff --git a/dojox/form/nls/nl/PasswordValidator.js b/dojox/form/nls/nl/PasswordValidator.js
index bce234d..9a68a63 100644
--- a/dojox/form/nls/nl/PasswordValidator.js
+++ b/dojox/form/nls/nl/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Wachtwoorden komen niet overeen.",
-		badPasswordMessage: "Ongeldig wachtwoord."
+	badPasswordMessage: "Ongeldig wachtwoord."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/pl/PasswordValidator.js b/dojox/form/nls/pl/PasswordValidator.js
index b392c66..44d4451 100644
--- a/dojox/form/nls/pl/PasswordValidator.js
+++ b/dojox/form/nls/pl/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Hasła nie są zgodne.",
-		badPasswordMessage: "Niepoprawne hasło."
+	badPasswordMessage: "Niepoprawne hasło."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/pt-pt/CheckedMultiSelect.js b/dojox/form/nls/pt-pt/CheckedMultiSelect.js
new file mode 100644
index 0000000..ca66cbd
--- /dev/null
+++ b/dojox/form/nls/pt-pt/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "É necessário seleccionar pelo menos um artigo.",
+	multiSelectLabelText: "{num} artigo(s) seleccionado(s)"
+})
+);
diff --git a/dojox/form/nls/pt-pt/PasswordValidator.js b/dojox/form/nls/pt-pt/PasswordValidator.js
index a19eda6..7976ded 100644
--- a/dojox/form/nls/pt-pt/PasswordValidator.js
+++ b/dojox/form/nls/pt-pt/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "As palavras-passe não correspondem.",
-		badPasswordMessage: "Palavra-passe não válida."
+	badPasswordMessage: "Palavra-passe não válida."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/pt-pt/Uploader.js b/dojox/form/nls/pt-pt/Uploader.js
new file mode 100644
index 0000000..c747ae1
--- /dev/null
+++ b/dojox/form/nls/pt-pt/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Seleccionar ficheiros..."
+})
+);
diff --git a/dojox/form/nls/pt/PasswordValidator.js b/dojox/form/nls/pt/PasswordValidator.js
index 24c906f..215b9b0 100644
--- a/dojox/form/nls/pt/PasswordValidator.js
+++ b/dojox/form/nls/pt/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "As senhas não correspondem.",
-		badPasswordMessage: "Senha Inválida."
+	badPasswordMessage: "Senha Inválida."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/ro/PasswordValidator.js b/dojox/form/nls/ro/PasswordValidator.js
index 368974a..a553441 100644
--- a/dojox/form/nls/ro/PasswordValidator.js
+++ b/dojox/form/nls/ro/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
-        nomatchMessage: "Parolele nu se potrivesc. ",
-		badPasswordMessage: "Parola nu este validă. "
+        nomatchMessage: "Parolele nu se potrivesc.",
+	badPasswordMessage: "Parolă invalidă."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/ru/CheckedMultiSelect.js b/dojox/form/nls/ru/CheckedMultiSelect.js
index 9f0cd97..2f50e79 100644
--- a/dojox/form/nls/ru/CheckedMultiSelect.js
+++ b/dojox/form/nls/ru/CheckedMultiSelect.js
@@ -1,6 +1,6 @@
 define(
 ({
-	invalidMessage: "Необходимо выбрать, как минимум, один элемент.",
-	multiSelectLabelText: "Выбрано элементов: {num}"
+	invalidMessage: "Выберите хотя бы один элемент.",
+	multiSelectLabelText: "Выбрано: {num}"
 })
 );
diff --git a/dojox/form/nls/ru/PasswordValidator.js b/dojox/form/nls/ru/PasswordValidator.js
index a6b98c2..ba5a852 100644
--- a/dojox/form/nls/ru/PasswordValidator.js
+++ b/dojox/form/nls/ru/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Пароли не совпадают.",
-		badPasswordMessage: "Неправильный пароль."
+	badPasswordMessage: "Неправильный пароль."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/sk/PasswordValidator.js b/dojox/form/nls/sk/PasswordValidator.js
index 785294d..993f52e 100644
--- a/dojox/form/nls/sk/PasswordValidator.js
+++ b/dojox/form/nls/sk/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Heslá sa nezhodujú.",
-		badPasswordMessage: "Neplatné heslo."
+	badPasswordMessage: "Neplatné heslo."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/sl/PasswordValidator.js b/dojox/form/nls/sl/PasswordValidator.js
index 679b4f4..b5d8c55 100644
--- a/dojox/form/nls/sl/PasswordValidator.js
+++ b/dojox/form/nls/sl/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Gesli se ne ujemata.",
-		badPasswordMessage: "Neveljavno geslo."
+	badPasswordMessage: "Neveljavno geslo."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/sl/Uploader.js b/dojox/form/nls/sl/Uploader.js
index 0df9fd7..b7d71a8 100644
--- a/dojox/form/nls/sl/Uploader.js
+++ b/dojox/form/nls/sl/Uploader.js
@@ -1,5 +1,5 @@
 define(
 ({
-	label: "Izberite datoteke ..."
+	label: "Izberi datoteke ..."
 })
 );
diff --git a/dojox/form/nls/sv/PasswordValidator.js b/dojox/form/nls/sv/PasswordValidator.js
index 3983071..88e0507 100644
--- a/dojox/form/nls/sv/PasswordValidator.js
+++ b/dojox/form/nls/sv/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
-        nomatchMessage: "Lösenorden stämmer inte överens.",
-		badPasswordMessage: "Ogiltigt lösenord."
+        nomatchMessage: "Lösenorden överensstämmer inte.",
+	badPasswordMessage: "Ogiltigt lösenord."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/th/PasswordValidator.js b/dojox/form/nls/th/PasswordValidator.js
index 771fca4..3a8358f 100644
--- a/dojox/form/nls/th/PasswordValidator.js
+++ b/dojox/form/nls/th/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "รหัสผ่านไม่ตรงกัน",
-		badPasswordMessage: "รหัสผ่านไม่ถูกต้อง"
+	badPasswordMessage: "รหัสผ่านไม่ถูกต้อง"
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/tr/PasswordValidator.js b/dojox/form/nls/tr/PasswordValidator.js
index e0c73d5..b8424d0 100644
--- a/dojox/form/nls/tr/PasswordValidator.js
+++ b/dojox/form/nls/tr/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "Parolalar eşleşmiyor.",
-		badPasswordMessage: "Geçersiz Parola."
+	badPasswordMessage: "Geçersiz Parola."
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/uk/CheckedMultiSelect.js b/dojox/form/nls/uk/CheckedMultiSelect.js
new file mode 100644
index 0000000..e023c98
--- /dev/null
+++ b/dojox/form/nls/uk/CheckedMultiSelect.js
@@ -0,0 +1,6 @@
+define(
+({
+	invalidMessage: "Виберіть принаймні один елемент.",
+	multiSelectLabelText: "вибрано {num} елементів"
+})
+);
diff --git a/dojox/form/nls/uk/PasswordValidator.js b/dojox/form/nls/uk/PasswordValidator.js
new file mode 100644
index 0000000..43cd535
--- /dev/null
+++ b/dojox/form/nls/uk/PasswordValidator.js
@@ -0,0 +1,6 @@
+define(
+({
+	nomatchMessage: "Паролі не співпадають.",
+	badPasswordMessage: "Неправильний пароль."
+})
+);
diff --git a/dojox/form/nls/uk/Uploader.js b/dojox/form/nls/uk/Uploader.js
new file mode 100644
index 0000000..4ce1feb
--- /dev/null
+++ b/dojox/form/nls/uk/Uploader.js
@@ -0,0 +1,5 @@
+define(
+({
+	label: "Виберіть файли..."
+})
+);
diff --git a/dojox/form/nls/zh-tw/CheckedMultiSelect.js b/dojox/form/nls/zh-tw/CheckedMultiSelect.js
index 3611f7a..bcccc04 100644
--- a/dojox/form/nls/zh-tw/CheckedMultiSelect.js
+++ b/dojox/form/nls/zh-tw/CheckedMultiSelect.js
@@ -1,6 +1,6 @@
 define(
 ({
-	invalidMessage: "至少必須選取一個項目。",
-	multiSelectLabelText: "已選取 {num} 項目"
+	invalidMessage: "必須選取至少一個項目。",
+	multiSelectLabelText: "已選取 {num} 個項目"
 })
 );
diff --git a/dojox/form/nls/zh-tw/PasswordValidator.js b/dojox/form/nls/zh-tw/PasswordValidator.js
index 42e1440..83384c1 100644
--- a/dojox/form/nls/zh-tw/PasswordValidator.js
+++ b/dojox/form/nls/zh-tw/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "密碼不符合。",
-		badPasswordMessage: "無效的密碼。"
+	badPasswordMessage: "無效的密碼。"
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/nls/zh/PasswordValidator.js b/dojox/form/nls/zh/PasswordValidator.js
index e15b442..acc9bcc 100644
--- a/dojox/form/nls/zh/PasswordValidator.js
+++ b/dojox/form/nls/zh/PasswordValidator.js
@@ -1,9 +1,6 @@
 define(
-//begin v1.x content
 ({
         nomatchMessage: "密码不匹配。",
-		badPasswordMessage: "密码无效。"
+	badPasswordMessage: "密码无效。"
 })
-
-//end v1.x content
-);
\ No newline at end of file
+);
diff --git a/dojox/form/resources/CheckedMultiSelect.css b/dojox/form/resources/CheckedMultiSelect.css
index 8037ee1..ba07307 100644
--- a/dojox/form/resources/CheckedMultiSelect.css
+++ b/dojox/form/resources/CheckedMultiSelect.css
@@ -139,7 +139,9 @@
 .claro .dojoxCheckedMultiSelectHover .dojoxCheckedMultiSelectWrapper {
 	border-color: #769dc0;
 	background-color: #e9f4fe;
-	background-image: url('../../../dijit/themes/claro/form/images/textBox_back.png');
+	background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+	background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+	background-image: linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
 	background-repeat: repeat-x;
 	-webkit-transition-duration:.25s;
 }
@@ -224,7 +226,9 @@
 .claro .dojoxCheckedMultiSelectButtonHover {
 	border: 1px solid #769dc0;
 	background-color: #e9f4fe;
-	background-image: url('../../../dijit/themes/claro/form/images/textBox_back.png');
+	background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+	background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+	background-image: linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
 	background-repeat: repeat-x;
 }
 
diff --git a/dojox/form/resources/FileInput.css b/dojox/form/resources/FileInput.css
index a807bc0..4d18582 100644
--- a/dojox/form/resources/FileInput.css
+++ b/dojox/form/resources/FileInput.css
@@ -107,16 +107,19 @@
 	background-color: #fff;
 	background-repeat: repeat-x;
 	background-position: top left;
-	background-image:url("../../../dijit/themes/claro/form/images/textBox_back.png");
+	background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+	background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+	background-image: linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
 	line-height:normal;
 	padding:0.2em 0.3em;
 }
 
 .claro .dijitFileInputButton,
 .claro .dijitFileInputText {
-	background-image: url("../../../dijit/themes/claro/form/images/button_back_full.png");
-	background-position: center top;
-	background-repeat: repeat-x;
+	background-image: -moz-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+	background-image: -webkit-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+	background-image: -o-linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
+	background-image: linear-gradient(rgba(127, 127, 127, 0.2) 0%, rgba(127, 127, 127, 0) 2px);
 	background-color: #cde3f6;
 	border: 1px solid #799ab7;
 	border-radius: 4px;
diff --git a/dojox/form/resources/HorizontalRangeSlider.html b/dojox/form/resources/HorizontalRangeSlider.html
index 6aafba0..fde811d 100644
--- a/dojox/form/resources/HorizontalRangeSlider.html
+++ b/dojox/form/resources/HorizontalRangeSlider.html
@@ -1,4 +1,4 @@
-<table class="dijit dijitReset dijitSlider dijitSliderH dojoxRangeSlider" cellspacing="0" cellpadding="0" border="0" rules="none" dojoAttachEvent="onkeypress:_onKeyPress,onkeyup:_onKeyUp"
+<table class="dijit dijitReset dijitSlider dijitSliderH dojoxRangeSlider" cellspacing="0" cellpadding="0" border="0" rules="none" dojoAttachEvent="onkeypress:_onKeyPress,onkeyup:_onKeyUp" role="presentation"
 	><tr class="dijitReset"
 		><td class="dijitReset" colspan="2"></td
 		><td dojoAttachPoint="topDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationT dijitSliderDecorationH"></td
@@ -14,11 +14,11 @@
 		><td class="dijitReset"
 			><input dojoAttachPoint="valueNode" type="hidden" ${!nameAttrSetting}
 			/><div role="presentation" class="dojoxRangeSliderBarContainer" dojoAttachPoint="sliderBarContainer"
-				><div dojoAttachPoint="sliderHandle" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableH" dojoAttachEvent="onmousedown:_onHandleClick" role="slider" valuemin="${minimum}" valuemax="${maximum}"
+				><div dojoAttachPoint="sliderHandle" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableH" dojoAttachEvent="onmousedown:_onHandleClick" role="slider"
 					><div class="dijitSliderImageHandle dijitSliderImageHandleH"></div
 				></div
 				><div role="presentation" dojoAttachPoint="progressBar,focusNode" class="dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH" dojoAttachEvent="onmousedown:_onBarClick"></div
-				><div dojoAttachPoint="sliderHandleMax,focusNodeMax" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableH" dojoAttachEvent="onmousedown:_onHandleClickMax" role="sliderMax" valuemin="${minimum}" valuemax="${maximum}"
+				><div dojoAttachPoint="sliderHandleMax" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableH" dojoAttachEvent="onmousedown:_onHandleClickMax" role="slider"
 					><div class="dijitSliderImageHandle dijitSliderImageHandleH"></div
 				></div
 				><div role="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH" dojoAttachEvent="onmousedown:_onRemainingBarClick"></div
diff --git a/dojox/form/resources/ListInput.css b/dojox/form/resources/ListInput.css
index 5f4a83b..abceaf9 100755
--- a/dojox/form/resources/ListInput.css
+++ b/dojox/form/resources/ListInput.css
@@ -8,6 +8,7 @@
 	position:relative
 }
 .dojoxListInput ul {
+	list-style-type:none;
 	margin:0;
 	padding:0
 }
@@ -22,7 +23,6 @@
 }
 .dojoxListInputItem {
 	float:left;
-	list-style-type:none;
 	margin:1px 5px 1px 1px;
 	padding:0
 }
diff --git a/dojox/form/resources/TriStateCheckBox.css b/dojox/form/resources/TriStateCheckBox.css
index 237f4bf..001c86a 100644
--- a/dojox/form/resources/TriStateCheckBox.css
+++ b/dojox/form/resources/TriStateCheckBox.css
@@ -15,12 +15,6 @@
  * 4. Disabled state
  * 		.dojoxTriStateCheckBoxDisabled|.dojoxTriStateCheckBoxCheckedDisabled|.dojoxTriStateCheckBoxMixedDisabled - for background image
  */
-.claro .dijitToggleButton .dojoxTriStateCheckBoxIcon {
-  background-image: url('../images/checkmarkNoBorder.png');
-}
-.dj_ie6 .claro .dijitToggleButton .dojoxTriStateCheckBoxIcon {
-  background-image: url('../images/checkmarkNoBorder.gif');
-}
 .claro .dojoxTriStateCheckBox, .claro .dojoxTriStateCheckBoxIcon {
   background-image: url('images/tristatecheckboxStates.png');
   /* checkbox sprite image */
diff --git a/dojox/form/resources/TriStateCheckBox.html b/dojox/form/resources/TriStateCheckBox.html
index 5605128..7e88c17 100644
--- a/dojox/form/resources/TriStateCheckBox.html
+++ b/dojox/form/resources/TriStateCheckBox.html
@@ -1,5 +1,5 @@
 <div class="dijit dijitReset dijitInline" role="presentation"
 	><div class="dojoxTriStateCheckBoxInner" dojoAttachPoint="stateLabelNode"></div
-	><input ${!nameAttrSetting} type="${type}" dojoAttachPoint="focusNode"
+	><input ${!nameAttrSetting} type="${type}" role="${type}" dojoAttachPoint="focusNode"
 	class="dijitReset dojoxTriStateCheckBoxInput" dojoAttachEvent="onclick:_onClick"
-/></div>
\ No newline at end of file
+/></div>
diff --git a/dojox/form/resources/Uploader.html b/dojox/form/resources/Uploader.html
index 449b2a1..dd58020 100644
--- a/dojox/form/resources/Uploader.html
+++ b/dojox/form/resources/Uploader.html
@@ -1,18 +1,17 @@
 <span class="dijit dijitReset dijitInline"
 	><span class="dijitReset dijitInline dijitButtonNode"
-		dojoAttachEvent="ondijitclick:_onClick"
+		data-dojo-attach-event="ondijitclick:_onClick"
 		><span class="dijitReset dijitStretch dijitButtonContents"
-			dojoAttachPoint="titleNode,focusNode"
+			data-dojo-attach-point="titleNode,focusNode"
 			role="button" aria-labelledby="${id}_label"
-			><span class="dijitReset dijitInline dijitIcon" dojoAttachPoint="iconNode"></span
+			><span class="dijitReset dijitInline dijitIcon" data-dojo-attach-point="iconNode"></span
 			><span class="dijitReset dijitToggleButtonIconChar">&#x25CF;</span
 			><span class="dijitReset dijitInline dijitButtonText"
 				id="${id}_label"
-				dojoAttachPoint="containerNode"
+				data-dojo-attach-point="containerNode"
 			></span
 		></span
 	></span
-	><!--no need to have this for Uploader 
-	<input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen" tabIndex="-1"
-		dojoAttachPoint="valueNode"
-/--></span>
+	> 
+	<input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen" tabIndex="-1" data-dojo-attach-point="valueNode" />
+</span>
diff --git a/dojox/form/resources/UploaderFileList.html b/dojox/form/resources/UploaderFileList.html
new file mode 100644
index 0000000..4aa75ed
--- /dev/null
+++ b/dojox/form/resources/UploaderFileList.html
@@ -0,0 +1,17 @@
+<div class="dojoxUploaderFileList">
+	<div data-dojo-attach-point="progressNode" class="dojoxUploaderFileListProgress">
+		<div data-dojo-attach-point="percentBarNode" class="dojoxUploaderFileListProgressBar"></div>
+		<div data-dojo-attach-point="percentTextNode" class="dojoxUploaderFileListPercentText">0%</div>
+	</div>
+	<table class="dojoxUploaderFileListTable">
+		<thead>
+			<tr class="dojoxUploaderFileListHeader">
+				<th class="dojoxUploaderIndex">${headerIndex}</th>
+				<th class="dojoxUploaderIcon">${headerType}</th>
+				<th class="dojoxUploaderFileName">${headerFilename}</th>
+				<th class="dojoxUploaderFileSize" data-dojo-attach-point="sizeHeader">${headerFilesize}</th>
+			</tr>
+		</thead>
+		<tbody class="dojoxUploaderFileListContent" data-dojo-attach-point="listNode"></tbody>
+	</table>
+<div>
\ No newline at end of file
diff --git a/dojox/form/resources/VerticalRangeSlider.html b/dojox/form/resources/VerticalRangeSlider.html
index 55b0d22..39285d8 100644
--- a/dojox/form/resources/VerticalRangeSlider.html
+++ b/dojox/form/resources/VerticalRangeSlider.html
@@ -1,4 +1,5 @@
 <table class="dijitReset dijitSlider dijitSliderV dojoxRangeSlider" cellspacing="0" cellpadding="0" border="0" rules="none"
+	role="presentation"
 	><tr class="dijitReset"
 		><td class="dijitReset"></td
 		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV"
@@ -19,12 +20,12 @@
 			><input dojoAttachPoint="valueNode" type="hidden" ${!nameAttrSetting}
 			/><center role="presentation" style="position:relative;height:100%;" dojoAttachPoint="sliderBarContainer"
 				><div role="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarV dijitSliderRemainingBar dijitSliderRemainingBarV" dojoAttachEvent="onmousedown:_onRemainingBarClick"
-					><div dojoAttachPoint="sliderHandle" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClick" style="vertical-align:top;" role="slider" valuemin="${minimum}" valuemax="${maximum}"
+					><div dojoAttachPoint="sliderHandle" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClick" style="vertical-align:top;" role="slider"
 						><div class="dijitSliderImageHandle dijitSliderImageHandleV"></div
 					></div
 					><div role="presentation" dojoAttachPoint="progressBar,focusNode" tabIndex="${tabIndex}" class="dijitSliderBar dijitSliderBarV dijitSliderProgressBar dijitSliderProgressBarV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onBarClick"
 					></div
-					><div dojoAttachPoint="sliderHandleMax,focusNodeMax" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClickMax" style="vertical-align:top;" role="slider" valuemin="${minimum}" valuemax="${maximum}"
+					><div dojoAttachPoint="sliderHandleMax" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClickMax" style="vertical-align:top;" role="slider"
 						><div class="dijitSliderImageHandle dijitSliderImageHandleV"></div
 					></div
 				></div
diff --git a/dojox/form/resources/_CheckedMultiSelectMenuItem.html b/dojox/form/resources/_CheckedMultiSelectMenuItem.html
index 23a5064..2f15dc4 100644
--- a/dojox/form/resources/_CheckedMultiSelectMenuItem.html
+++ b/dojox/form/resources/_CheckedMultiSelectMenuItem.html
@@ -1,5 +1,5 @@
 <tr class="dijitReset dijitMenuItem" dojoAttachPoint="focusNode" role="menuitemcheckbox" tabIndex="-1"
-	dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick"
+	dojoAttachEvent="ondijitclick:_onClick"
 	><td class="dijitReset dijitMenuItemIconCell" role="presentation"
 		><div src="${_blankGif}" alt="" class="dijitMenuItemIcon ${_iconClass}" dojoAttachPoint="iconNode"
 			><input class="dojoxCheckedMultiSelectCheckBoxInput" dojoAttachPoint="inputNode" type="${_type.type}"
diff --git a/dojox/form/tests/UploadFile.php.disabled b/dojox/form/tests/UploadFile.php.disabled
index 6f981f4..889ee71 100644
--- a/dojox/form/tests/UploadFile.php.disabled
+++ b/dojox/form/tests/UploadFile.php.disabled
@@ -146,14 +146,16 @@ if( isset($_FILES[$fieldName]) || isset($_FILES['uploadedfileFlash'])){
 	//	Multiple files have been passed from HTML
 	//
 	$cnt = 0;
-	trace("HTML multiple POST:");
+	trace("IFrame multiple POST:");
 	trace($postdata, true);
 
 	$_post = $htmldata;
 	$htmldata = array();
+	
+	
 
 	while(isset($_FILES['uploadedfile'.$cnt])){
-	  trace("HTML multiple POST");
+	  trace("IFrame multiple POST");
 		$moved = move_uploaded_file($_FILES['uploadedfile'.$cnt]['tmp_name'],  $upload_path . $_FILES['uploadedfile'.$cnt]['name']);
 		trace("moved:" . $moved ."  ". $_FILES['uploadedfile'.$cnt]['name']);
 		if($moved){
@@ -173,11 +175,16 @@ if( isset($_FILES[$fieldName]) || isset($_FILES['uploadedfileFlash'])){
 			$_post['width'] = $width;
 			$_post['height'] = $height;
 			$_post['type'] = $type;
+			$_post['uploadType'] = $postdata['uploadType'];
 			$_post['size'] = filesize($file);
 			$_post['additionalParams'] = $postdata;
-			trace($_post, true);
+			trace($_post['additionalParams'], true);
 
 			$htmldata[$cnt] = $_post;
+			
+			foreach($postdata as $key => $value){
+				//$htmldata[ $key ] = $value;
+			}
 
 		}elseif(strlen($_FILES['uploadedfile'.$cnt]['name'])){
 		  $htmldata[$cnt] = array("ERROR" => "File could not be moved: ".$_FILES['uploadedfile'.$cnt]['name']);
@@ -286,8 +293,14 @@ if( isset($_FILES[$fieldName]) || isset($_FILES['uploadedfileFlash'])){
 	$htmldata['width'] = $width;
 	$htmldata['height'] = $height;
 	$htmldata['type'] = $type;
+	$htmldata['uploadType'] = $uploadType;
 	$htmldata['size'] = filesize($file);
 	$htmldata['additionalParams'] = $postdata;
+	
+	$data = $json->encode($htmldata);
+	trace($data);
+	print $data;
+	return $data;
 
 
 }elseif(isset($_GET['rmFiles'])){
diff --git a/dojox/form/tests/images/attach.png b/dojox/form/tests/images/attach.png
deleted file mode 100644
index 7fc4811..0000000
Binary files a/dojox/form/tests/images/attach.png and /dev/null differ
diff --git a/dojox/form/tests/images/grad.jpg b/dojox/form/tests/images/grad.jpg
deleted file mode 100644
index 52cf2af..0000000
Binary files a/dojox/form/tests/images/grad.jpg and /dev/null differ
diff --git a/dojox/form/tests/images/grad_down.jpg b/dojox/form/tests/images/grad_down.jpg
deleted file mode 100644
index 7bcec94..0000000
Binary files a/dojox/form/tests/images/grad_down.jpg and /dev/null differ
diff --git a/dojox/form/tests/images/grad_over.jpg b/dojox/form/tests/images/grad_over.jpg
deleted file mode 100644
index 7626ce1..0000000
Binary files a/dojox/form/tests/images/grad_over.jpg and /dev/null differ
diff --git a/dojox/form/tests/images/rndBtnSprite.png b/dojox/form/tests/images/rndBtnSprite.png
deleted file mode 100644
index 432e592..0000000
Binary files a/dojox/form/tests/images/rndBtnSprite.png and /dev/null differ
diff --git a/dojox/form/tests/images/rndBtn_down.png b/dojox/form/tests/images/rndBtn_down.png
deleted file mode 100644
index 1f2f28b..0000000
Binary files a/dojox/form/tests/images/rndBtn_down.png and /dev/null differ
diff --git a/dojox/form/tests/images/rndBtn_norm.png b/dojox/form/tests/images/rndBtn_norm.png
deleted file mode 100644
index 0be88a9..0000000
Binary files a/dojox/form/tests/images/rndBtn_norm.png and /dev/null differ
diff --git a/dojox/form/tests/images/rndBtn_over.png b/dojox/form/tests/images/rndBtn_over.png
deleted file mode 100644
index f6084c1..0000000
Binary files a/dojox/form/tests/images/rndBtn_over.png and /dev/null differ
diff --git a/dojox/form/tests/test_BusyButton.html b/dojox/form/tests/test_BusyButton.html
index 3b7757f..038b77f 100644
--- a/dojox/form/tests/test_BusyButton.html
+++ b/dojox/form/tests/test_BusyButton.html
@@ -18,7 +18,7 @@
 		
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="parseOnLoad: true, isDebug: true"></script>
+			data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.form.BusyButton");
 			dojo.require("dojo.parser");
diff --git a/dojox/form/tests/test_CheckedMultiSelect.html b/dojox/form/tests/test_CheckedMultiSelect.html
index b479532..b5d65c5 100644
--- a/dojox/form/tests/test_CheckedMultiSelect.html
+++ b/dojox/form/tests/test_CheckedMultiSelect.html
@@ -13,232 +13,244 @@
 			.ark { text-decoration: underline; }
 		</style>
 
-	    <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	    <script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
 		
 		<script src="../../../dijit/tests/_testCommon.js"></script>
 
 	    <script type="text/javascript">
-			dojo.require("doh.runner");
-			dojo.require("dojo.parser");
-			dojo.require("dojox.form.CheckedMultiSelect");
-			dojo.require("dijit.form.Button");
-			dojo.require("dijit.form.Form");
-			dojo.require("dojo.data.ItemFileWriteStore");
-		
-			var data = {
-				identifier: "value",
-				label: "label",
-				items: [
-					{value: "AL", label: "Alabama"},
-					{value: "AK", label: "Alaska"},
-					{value: "AZ", label: "Arizona"},
-					{value: "AR", label: "Arkansas"},
-					{value: "CA", label: "California"},
-					{value: "CO", label: "Colorado"},
-					{value: "CT", label: "Connecticut"}
-				]
-			};
-			
-			var readStore = new dojo.data.ItemFileReadStore({data:dojo.clone(data)});
-			var writeStore = new dojo.data.ItemFileWriteStore({data:dojo.clone(data)});
+	    	require(["doh", "dojo/_base/array", "dojo/_base/lang", "dojo/dom-form", "dojo/on", "dojo/parser", "dojo/ready", 
+	    		"dojox/form/CheckedMultiSelect", "dijit/form/Button", "dijit/form/Form", "dojo/data/ItemFileReadStore", 
+	    		"dojo/data/ItemFileWriteStore", "dojo/store/Memory"
+	    	], function(doh, array, lang, domForm, on, parser, ready, CheckedMultiSelect, Button, Form, ItemFileReadStore, 
+	    		ItemFileWriteStore, Memory){
+
+				var data = {
+					identifier: "value",
+					label: "label",
+					items: [
+						{value: "AL", label: "Alabama"},
+						{value: "AK", label: "Alaska"},
+						{value: "AZ", label: "Arizona"},
+						{value: "AR", label: "Arkansas"},
+						{value: "CA", label: "California"},
+						{value: "CO", label: "Colorado"},
+						{value: "CT", label: "Connecticut"}
+					]
+				};
+				
+				readStore = new ItemFileReadStore({data:lang.clone(data)});
+				writeStore = new ItemFileWriteStore({data:lang.clone(data)});
+				objectStore = new Memory({data:lang.clone(data.items), idProperty:"value"});
+				
+				var numOptions = 0;
+				var addNum = 10;
+				var testType;
+				// Uncomment below line to run perf tests - note SLOW to run
+				//testType = "perf";
 			
-			var numOptions = 0;
-			var addNum = 10;
-			var testType;
-			// Uncomment below line to run perf tests - note SLOW to run
-			//testType = "perf";
-		
-			dojo.addOnLoad(function(){
-				doh.register("tests",
-					[
-						function test_setValue(t){
-							t.is(["VA","WA"], form.get("value").ms1);
-							t.is(["TX","GA"], form.get("value").ms2);
-							ms1.set("value", ["TN","CA"]);
-							t.is(["TN","CA"], form.get("value").ms1);
-							ms1.invertSelection();
-							t.is(["VA","WA","FL"], form.get("value").ms1);
-						},
-						function test_addSelected(t){
-							dojo.forEach(ms2.getOptions(ms2.getValue()), function(i){
-								ms2.removeOption(i);
-								ms1.addOption(i);
-							});
-							t.is([], form.get("value").ms2);
-							ms1.invertSelection();
-							t.is(["TN","CA"], form.get("value").ms1);
-						},
-						function delete_selected(t){
-							t.is(["TN","CA"], ms1.getValue());
-							var d = new doh.Deferred();
-							ms1.removeOption("CA");
-							window.setTimeout(function(){
-								try{
-									t.is(["TN"], ms1.getValue());
-									d.callback(true);
-								}catch(e){ d.errback(e); }
-							}, 100);
-							return d;
-						},
-						function test_storeBased(t){
-							t.is([], ms4.get("value"));
-							ms4.set("value", ["CA","AL"]);
-							t.is(["AL","CA"], ms4.get("value"));
-						},
-						function test_changeSelected(t){
-							t.is([], ms5.get("value"));
-							ms5.set("value", ["AL", "AK"]);
-							var d = new doh.Deferred();
-							var cb = function(item){
-								try{
-									writeStore.setValue(item, "label", "North Pole");
+				ready(function(){
+					parser.parse();
+
+					doh.register("tests",
+						[
+							function test_setValue(t){
+								t.is(["VA","WA"], form.get("value").ms1);
+								t.is(["TX","GA"], form.get("value").ms2);
+								ms1.set("value", ["TN","CA"]);
+								t.is(["TN","CA"], form.get("value").ms1);
+								ms1.invertSelection();
+								t.is(["VA","WA","FL"], form.get("value").ms1);
+							},
+							function test_addSelected(t){
+								array.forEach(ms2.getOptions(ms2.get("value")), function(i){
+									ms2.removeOption(i);
+									ms1.addOption(i);
+								});
+								t.is([], form.get("value").ms2);
+								ms1.invertSelection();
+								t.is(["TN","CA"], form.get("value").ms1);
+							},
+							function delete_selected(t){
+								t.is(["TN","CA"], ms1.get("value"));
+								var d = new doh.Deferred();
+								ms1.removeOption("CA");
+								window.setTimeout(function(){
 									try{
-										t.is(["AL","AK"], ms5.get("value"));
-										t.is(writeStore.getValue(item, "label"), 
-												dojo.filter(ms5._getChildren(), function(n){return n.option.value==="AK";})[0].labelNode.innerHTML);
+										t.is(["TN"], ms1.get("value"));
 										d.callback(true);
-									}catch(e){ d.errback(e);}
+									}catch(e){ d.errback(e); }
+								}, 100);
+								return d;
+							},
+							function test_storeBased(t){
+								t.is([], ms4.get("value"));
+								ms4.set("value", ["CA","AL"]);
+								t.is(["AL","CA"], ms4.get("value"));
+								
+								t.is([], ms6.get("value"));
+								ms6.set("value", ["CA","AL"]);
+								t.is(["AL","CA"], ms6.get("value")); 
+							},
+							function test_changeSelected(t){
+								t.is([], ms5.get("value"));
+								ms5.set("value", ["AL", "AK"]);
+								var d = new doh.Deferred();
+								var cb = function(item){
+									try{
+										writeStore.setValue(item, "label", "North Pole");
+										try{
+											t.is(["AL","AK"], ms5.get("value"));
+											t.is(writeStore.getValue(item, "label"), 
+													array.filter(ms5._getChildren(), function(n){return n.option.value==="AK";})[0].labelNode.innerHTML);
+											d.callback(true);
+										}catch(e){ d.errback(e);}
+									}
+									catch(e){
+										d.errback(e);
+									}
 								}
-								catch(e){
-									d.errback(e);
+								writeStore.fetchItemByIdentity({identity: "AK", onItem: cb});
+								return d;
+							},
+							function test_deleteNonSelected(t){
+								t.is(["AL","AK"], ms5.get("value"));
+								var d = new doh.Deferred();
+								var cb = function(item){
+									try{
+										t.is(7, ms5._getChildren().length);
+										writeStore.deleteItem(item);
+										try{
+											t.is(["AL","AK"], ms5.get("value"));
+											t.is(6, ms5._getChildren().length);
+											d.callback(true);
+										}catch(e){ d.errback(e);}
+									}catch (e){
+										d.errback(e);
+									}
 								}
-							}
-							writeStore.fetchItemByIdentity({identity: "AK", onItem: cb});
-							return d;
-						},
-						function test_deleteNonSelected(t){
-							t.is(["AL","AK"], ms5.get("value"));
-							var d = new doh.Deferred();
-							var cb = function(item){
-								try{
-									t.is(7, ms5._getChildren().length);
-									writeStore.deleteItem(item);
+								writeStore.fetchItemByIdentity({identity: "AZ", onItem: cb});
+								return d;
+							},
+							function test_deleteSelected(t){
+								t.is(["AL","AK"], ms5.get("value"));
+								var d = new doh.Deferred();
+								var cb = function(item){
 									try{
-										t.is(["AL","AK"], ms5.get("value"));
 										t.is(6, ms5._getChildren().length);
-										d.callback(true);
-									}catch(e){ d.errback(e);}
-								}catch (e){
-									d.errback(e);
+										writeStore.deleteItem(item);
+										try{
+											t.is(["AL"], ms5.get("value"));
+											t.is(5, ms5._getChildren().length);
+											d.callback(true);
+										}catch(e){ d.errback(e);}
+									}catch (e){
+										d.errback(e);
+									}
 								}
-							}
-							writeStore.fetchItemByIdentity({identity: "AZ", onItem: cb});
-							return d;
-						},
-						function test_deleteSelected(t){
-							t.is(["AL","AK"], ms5.get("value"));
-							var d = new doh.Deferred();
-							var cb = function(item){
+								writeStore.fetchItemByIdentity({identity: "AK", onItem: cb});
+								return d;
+							},
+							function test_newItem(t){
+								t.is(["AL"], ms5.get("value"));
+								t.is(5, ms5._getChildren().length);
+								ms5.set("value", ["AL","NY"]);
+								t.is(["AL"], ms5.get("value"));
+								var d = new doh.Deferred();
+								writeStore.newItem({value: "NY", label: "New York"});
 								try{
 									t.is(6, ms5._getChildren().length);
-									writeStore.deleteItem(item);
-									try{
-										t.is(["AL"], ms5.get("value"));
-										t.is(5, ms5._getChildren().length);
-										d.callback(true);
-									}catch(e){ d.errback(e);}
-								}catch (e){
-									d.errback(e);
-								}
-							}
-							writeStore.fetchItemByIdentity({identity: "AK", onItem: cb});
-							return d;
-						},
-						function test_newItem(t){
-							t.is(["AL"], ms5.get("value"));
-							t.is(5, ms5._getChildren().length);
-							ms5.set("value", ["AL","NY"]);
-							t.is(["AL"], ms5.get("value"));
-							var d = new doh.Deferred();
-							writeStore.newItem({value: "NY", label: "New York"});
-							try{
-								t.is(6, ms5._getChildren().length);
-								ms5.set("value", ["AL","NY"]);
-								t.is(["AL","NY"], ms5.get("value"));
-								d.callback(true);
-							}catch(e){d.errback(e);}
-							return d;
-						},
-						{
-							name: "test_performance_single",
-							testType: testType,
-							trialDuration: 100,
-							trialIterations: 100,
-							trialDelay: 100,
-							runTest: function(t){
-								var opt = {value: "Test", label: "Test Option"};
-								ms3.addOption(opt);
-								ms3.removeOption(opt);
-							}
-						},
-						{
-							name: "test_performance_separate",
-							testType: testType,
-							trialDuration: 100,
-							trialIterations: 100,
-							trialDelay: 100,
-							setUp: function(t){
-								var opts = t.options = [];
-								for(var i = 0; i < addNum; i++){
-									opts.push({value: i + "", label: "Option " + (i + 1)});
-								}
+									ms5.set("value", ["AL","NY"]);
+									t.is(["AL","NY"], ms5.get("value"));
+									d.callback(true);
+								}catch(e){d.errback(e);}
+								return d;
+							},
+							function test_formDegrade(t){
+								var form = domForm.toObject("form");
+								t.is(form.ms1, ["TN"], "form is set properly");
+								t.is(form.ms4, ["AL", "CA"], "form is set properly");
 							},
-							runTest: function(t){
-								dojo.forEach(t.options, function(opt){
+							{
+								name: "test_performance_single",
+								testType: testType,
+								trialDuration: 100,
+								trialIterations: 100,
+								trialDelay: 100,
+								runTest: function(t){
+									var opt = {value: "Test", label: "Test Option"};
 									ms3.addOption(opt);
-								});
-								dojo.forEach(t.options, function(opt){
 									ms3.removeOption(opt);
-								});
-							},
-							tearDown: function(t){
-								delete t.options;
-							}
-						},
-						{
-							name: "test_performance_batch",
-							testType: testType,
-							trialDuration: 100,
-							trialIterations: 100,
-							trialDelay: 100,
-							setUp: function(t){
-								var opts = t.options = [];
-								for(var i = 0; i < addNum; i++){
-									opts.push({value: i + "", label: "Option " + (i + 1)});
 								}
 							},
-							runTest: function(t){
-								ms3.addOption(t.options);
-								ms3.removeOption(t.options);
+							{
+								name: "test_performance_separate",
+								testType: testType,
+								trialDuration: 100,
+								trialIterations: 100,
+								trialDelay: 100,
+								setUp: function(t){
+									var opts = t.options = [];
+									for(var i = 0; i < addNum; i++){
+										opts.push({value: i + "", label: "Option " + (i + 1)});
+									}
+								},
+								runTest: function(t){
+									array.forEach(t.options, function(opt){
+										ms3.addOption(opt);
+									});
+									array.forEach(t.options, function(opt){
+										ms3.removeOption(opt);
+									});
+								},
+								tearDown: function(t){
+									delete t.options;
+								}
 							},
-							tearDown: function(t){
-								delete t.options;
+							{
+								name: "test_performance_batch",
+								testType: testType,
+								trialDuration: 100,
+								trialIterations: 100,
+								trialDelay: 100,
+								setUp: function(t){
+									var opts = t.options = [];
+									for(var i = 0; i < addNum; i++){
+										opts.push({value: i + "", label: "Option " + (i + 1)});
+									}
+								},
+								runTest: function(t){
+									ms3.addOption(t.options);
+									ms3.removeOption(t.options);
+								},
+								tearDown: function(t){
+									delete t.options;
+								}
 							}
-						}
-					]
-				);
-				doh.run();
-				dojo.connect(ms1, "onChange", function(val){
-					console.log("First Select Changed to " + val);
-				});
-				dojo.connect(ss1, "onChange", function(val){
-					console.log("First Radio Select Changed to " + val);
-				});
+						]
+					);
+					doh.run();
+					on(ms1, "change", function(val){
+						console.log("First Select Changed to " + val);
+					});
+					on(ss1, "change", function(val){
+						console.log("First Radio Select Changed to " + val);
+					});
+		    	});
 			});
 		</script>
 	</head>	
 	<body class="claro">
 		<h1 class="testTitle">Test: dojox.form.CheckedMultiSelect</h1>
-		<form dojoType="dijit.form.Form" jsId="form">
+		<form data-dojo-type="dijit/form/Form" id="form" data-dojo-id="form">
 			<h2>Check Boxes</h2>
-			<select jsId="ms1" multiple="true" name="ms1" dojoType="dojox.form.CheckedMultiSelect">
+			<select data-dojo-id="ms1" multiple="true" name="ms1" data-dojo-type="dojox.form.CheckedMultiSelect">
 				<option value="TN">Tennessee</option>
 				<option value="VA" selected="selected">Virginia</option>
 				<option value="WA" selected="selected">Washington</option>
 				<option value="FL">Florida</option>
 				<option value="CA">California</option>
 			</select>
-			<select jsId="ms2" multiple="true" name="ms2" dojoType="dojox.form.CheckedMultiSelect">
+			<select data-dojo-id="ms2" multiple="true" name="ms2" data-dojo-type="dojox.form.CheckedMultiSelect">
 				<option value="UT">Utah</option>
 				<option value="TX" selected="selected">Texas</option>
 				<option value="GA" selected="selected">Georgia</option>
@@ -247,18 +259,18 @@
 				<option value="OR">Oregon</option>
 				<option value="PA">Pennsylvania</option>
 			</select>
-			<select jsId="ms3" multiple="true" name="ms3" dojoType="dojox.form.CheckedMultiSelect">
+			<select data-dojo-id="ms3" multiple="true" name="ms3" data-dojo-type="dojox.form.CheckedMultiSelect">
 			</select>
 		<hr>
 			<h2>Radio Buttons</h2>
-			<select jsId="ss1" name="ss1" dojoType="dojox.form.CheckedMultiSelect">
+			<select data-dojo-id="ss1" name="ss1" data-dojo-type="dojox.form.CheckedMultiSelect">
 				<option value="TN">Tennessee</option>
 				<option value="VA" selected="selected">Virginia</option>
 				<option value="WA">Washington</option>
 				<option value="FL">Florida</option>
 				<option value="CA">California</option>
 			</select>
-			<select jsId="ss2" name="ss2" value="TX" dojoType="dojox.form.CheckedMultiSelect">
+			<select data-dojo-id="ss2" name="ss2" value="TX" data-dojo-type="dojox.form.CheckedMultiSelect">
 				<option value="UT">Utah</option>
 				<option value="TX">Texas</option>
 				<option value="GA">Georgia</option>
@@ -267,22 +279,24 @@
 				<option value="OR">Oregon</option>
 				<option value="PA">Pennsylvania</option>
 			</select>
-			<select jsId="ss3" name="ss3" dojoType="dojox.form.CheckedMultiSelect">
+			<select data-dojo-id="ss3" name="ss3" data-dojo-type="dojox.form.CheckedMultiSelect">
 			</select>
 		<hr>
 			<h4 class="testSubtitle">Store-based</h4>
-			<select jsId="ms4" multiple="true" size="5" name="ms4" store="readStore" dojoType="dojox.form.CheckedMultiSelect">
+			<select data-dojo-id="ms4" multiple="true" size="5" name="ms4" store="readStore" data-dojo-type="dojox.form.CheckedMultiSelect">
+			</select>
+			<select data-dojo-id="ms5" multiple="true" size="5" name="ms5" store="writeStore" data-dojo-type="dojox.form.CheckedMultiSelect">
 			</select>
-			<select jsId="ms5" multiple="true" size="5" name="ms5" store="writeStore" dojoType="dojox.form.CheckedMultiSelect">
+			<select data-dojo-id="ms6" multiple="true" size="5" name="ms6" store="objectStore" labelAttr="label" data-dojo-type="dojox.form.CheckedMultiSelect">
 			</select>
 		<hr>
 			<h4 class="testSubtitle">Validation</h4>
-			<select jsId="rq1" multiple="true" required="true" name="rq1" store="readStore" dojoType="dojox.form.CheckedMultiSelect"
+			<select data-dojo-id="rq1" multiple="true" required="true" name="rq1" store="readStore" data-dojo-type="dojox.form.CheckedMultiSelect"
 				invalidMessage="You need to select at least one"
 			></select>
-			<button dojoType="dijit.form.Button">
+			<button data-dojo-type="dijit.form.Button">
 				Validate
-				<script type='dojo/method' event='onClick'>
+				<script type='dojo/on' data-dojo-event='click'>
 					var isvalid = rq1.isValid();
 					console.warn("isvalid?", isvalid, form, form.validate);
 					try{
@@ -295,48 +309,48 @@
 				</script>
 			</button>
 		<hr>
-			<button dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
+			<button data-dojo-type="dijit.form.Button">
+				<script type="dojo/on" data-dojo-event="click">
 					console.dir(form.get("value"));
 				</script>
 				Get Values
 			</button>
-			<button dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
+			<button data-dojo-type="dijit.form.Button">
+				<script type="dojo/on" data-dojo-event="click">
 					numOptions++;
 					ms3.addOption({value: numOptions + "", label: "Option " + (numOptions)});
 				</script>
 				Add Check Option
 			</button>
-			<button dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
+			<button data-dojo-type="dijit.form.Button">
+				<script type="dojo/on" data-dojo-event="click">
 					numOptions++;
 					ss3.addOption({value: numOptions + "", label: "Option " + (numOptions)});
 				</script>
 				Add Radio Option
 			</button>
-			<button dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
+			<button data-dojo-type="dijit.form.Button">
+				<script type="dojo/on" data-dojo-event="click">
 					ms3.set("disabled", !ms3.disabled);
 					ss3.set("disabled", !ss3.disabled);
 				</script>
 				Toggle Disabled
 			</button>
-			<button dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
+			<button data-dojo-type="dijit.form.Button">
+				<script type="dojo/on" data-dojo-event="click">
 					ms2.set("readOnly", !ms2.readOnly);
 					ss2.set("readOnly", !ss2.readOnly);
 				</script>
 				Toggle Read Only
 			</button>
-			<button dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
+			<button data-dojo-type="dijit.form.Button">
+				<script type="dojo/on" data-dojo-event="click">
 					ms1.invertSelection(true);
 				</script>
 				Invert Selection
 			</button>
-			<button dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
+			<button data-dojo-type="dijit.form.Button">
+				<script type="dojo/on" data-dojo-event="click">
 					console.log(ms1.get("displayedValue"));
 				</script>
 				Get Displayed Value
diff --git a/dojox/form/tests/test_CheckedMultiSelectDropDown.html b/dojox/form/tests/test_CheckedMultiSelectDropDown.html
index 5cef268..6c015ed 100644
--- a/dojox/form/tests/test_CheckedMultiSelectDropDown.html
+++ b/dojox/form/tests/test_CheckedMultiSelectDropDown.html
@@ -12,7 +12,7 @@
 			    text-decoration: underline;
 			}
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true">
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true">
 		</script>
 		<script src="../../../dijit/tests/_testCommon.js">
 		</script>
@@ -76,12 +76,12 @@
 			<option value="opel">Opel</option>
 			<option value="audi">Audi</option>
 		</select>
-		<form dojoType="dijit.form.Form" jsId="form">
+		<form dojoType="dijit.form.Form" data-dojo-id="form">
 			<hr><h2>Multi-select</h2>
 			<table>
 				<tr>
 				<td>
-					<select jsId="ms1" multiple="true" name="ms1" dojoType="dojox.form.CheckedMultiSelect" dropdown="true">
+					<select data-dojo-id="ms1" multiple="true" name="ms1" dojoType="dojox.form.CheckedMultiSelect" dropdown="true">
 						<option value="TN">Tennessee</option>
 						<option value="VA" selected="selected">Virginia</option>
 						<option value="WA" selected="selected">Washington</option>
@@ -91,21 +91,21 @@
 				</td>
 				<td>
 					<button dojoType="dijit.form.Button">
-						<script type="dojo/method" event="onClick">
+						<script type="dojo/method" data-dojo-event="onClick">
 							ms1.invertSelection(true);
 							return false;
 						</script>
 						Invert Selection
 					</button>
 					<button dojoType="dijit.form.Button">
-						<script type="dojo/method" event="onClick">
+						<script type="dojo/method" data-dojo-event="onClick">
 							ms1.set("disabled", !ms1.disabled);
 							return false;
 						</script>
 						Toggle Disabled
 					</button>
 					<button dojoType="dijit.form.Button">
-						<script type="dojo/method" event="onClick">
+						<script type="dojo/method" data-dojo-event="onClick">
 							console.log(ms1.get("displayedValue"));
 							return false;
 						</script>
@@ -114,7 +114,7 @@
 				</td>
 				<tr>
 					<td>
-						<select jsId="ms2" multiple="true" name="ms2" dojoType="dojox.form.CheckedMultiSelect" dropdown="true">
+						<select data-dojo-id="ms2" multiple="true" name="ms2" dojoType="dojox.form.CheckedMultiSelect" dropdown="true">
 							<option value="UT">Utah</option>
 							<option value="TX" selected="selected">Texas</option>
 							<option value="GA" selected="selected">Georgia</option>
@@ -126,7 +126,7 @@
 					</td>
 					<td>
 						<button dojoType="dijit.form.Button">
-							<script type="dojo/method" event="onClick">
+							<script type="dojo/method" data-dojo-event="onClick">
 								ms2.set("readOnly", !ms2.readOnly);
 								return false;
 							</script>
@@ -136,12 +136,12 @@
 				</tr>
 				<tr>
 					<td>
-						<select jsId="ms3" multiple="true" maxHeight="125" name="ms3" dojoType="dojox.form.CheckedMultiSelect" dropdown="true">
+						<select data-dojo-id="ms3" multiple="true" maxHeight="125" name="ms3" dojoType="dojox.form.CheckedMultiSelect" dropdown="true">
 						</select>
 					</td>
 					<td>
 						<button dojoType="dijit.form.Button">
-							<script type="dojo/method" event="onClick">
+							<script type="dojo/method" data-dojo-event="onClick">
 								checkOptions++;
 								ms3.addOption({value: checkOptions + "", label: "Option " + (checkOptions)});
 								return false;
@@ -149,7 +149,7 @@
 							Add Check Option
 						</button>
 						<button dojoType="dijit.form.Button">
-							<script type="dojo/method" event="onClick">
+							<script type="dojo/method" data-dojo-event="onClick">
 								if(checkOptions > 0){
 									checkOptions--;
 									ms3.removeOption(checkOptions);
@@ -162,7 +162,7 @@
 				</tr>
 				<tr>
 					<td>
-						<select value="['AL','AK']" jsId="ms4" multiple="true" maxHeight="125" size="5" name="ms4" store="readStore" dojoType="dojox.form.CheckedMultiSelect" dropdown="true">
+						<select value="['AL','AK']" data-dojo-id="ms4" multiple="true" maxHeight="125" size="5" name="ms4" store="readStore" dojoType="dojox.form.CheckedMultiSelect" dropdown="true">
 						</select>
 					</td>
 					<td>
@@ -171,11 +171,11 @@
 				</tr>
 			</table>
 			<hr><h2>Validation</h2>
-			<select jsId="rq1" multiple="true" required="true" name="rq1" store="readStore" dojoType="dojox.form.CheckedMultiSelect" invalidMessage="You need to select at least one" dropdown="true">
+			<select data-dojo-id="rq1" multiple="true" required="true" name="rq1" store="readStore" dojoType="dojox.form.CheckedMultiSelect" invalidMessage="You need to select at least one" dropdown="true">
 			</select>
 			<button dojoType="dijit.form.Button">
 				Validate
-				<script type='dojo/method' event='onClick'>
+				<script type='dojo/method' data-dojo-event='onClick'>
 					var isvalid = rq1.isValid();
 					console.warn("isvalid?", isvalid, form, form.validate);
 					try{
@@ -189,7 +189,7 @@
 			</button>
 			<hr><h2>Output values in console</h2>
 			<button dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
+				<script type="dojo/method" data-dojo-event="onClick">
 					console.dir(form.get("value"));
 					return false;
 				</script>
diff --git a/dojox/form/tests/test_CheckedMultiSelectNonDropDown.html b/dojox/form/tests/test_CheckedMultiSelectNonDropDown.html
index 646f900..5189bc7 100644
--- a/dojox/form/tests/test_CheckedMultiSelectNonDropDown.html
+++ b/dojox/form/tests/test_CheckedMultiSelectNonDropDown.html
@@ -15,7 +15,7 @@
 				vertical-align: top;
 			}
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true">
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true">
 		</script>
 		<script src="../../../dijit/tests/_testCommon.js">
 		</script>
@@ -81,12 +81,12 @@
 			<option value="opel">Opel</option>
 			<option value="audi">Audi</option>
 		</select>
-		<form dojoType="dijit.form.Form" jsId="form">
+		<form dojoType="dijit.form.Form" data-dojo-id="form">
 			<hr><h2>Multi-select</h2>
 			<table>
 				<tr>
 				<td>
-					<select jsId="ms1" multiple="true" name="ms1" dojoType="dojox.form.CheckedMultiSelect" dropdown="false">
+					<select data-dojo-id="ms1" multiple="true" name="ms1" dojoType="dojox.form.CheckedMultiSelect" dropdown="false">
 						<option value="TN">Tennessee</option>
 						<option value="VA" selected="selected">Virginia</option>
 						<option value="WA" selected="selected">Washington</option>
@@ -96,21 +96,21 @@
 				</td>
 				<td>
 					<button dojoType="dijit.form.Button">
-						<script type="dojo/method" event="onClick">
+						<script type="dojo/method" data-dojo-event="onClick">
 							ms1.invertSelection(true);
 							return false;
 						</script>
 						Invert Selection
 					</button>
 					<button dojoType="dijit.form.Button">
-						<script type="dojo/method" event="onClick">
+						<script type="dojo/method" data-dojo-event="onClick">
 							ms1.set("disabled", !ms1.disabled);
 							return false;
 						</script>
 						Toggle Disabled
 					</button>
 					<button dojoType="dijit.form.Button">
-						<script type="dojo/method" event="onClick">
+						<script type="dojo/method" data-dojo-event="onClick">
 							console.log(ms1.get("displayedValue"));
 							return false;
 						</script>
@@ -119,7 +119,7 @@
 				</td>
 				<tr>
 					<td>
-						<select jsId="ms2" multiple="true" name="ms2" dojoType="dojox.form.CheckedMultiSelect" dropdown="false">
+						<select data-dojo-id="ms2" multiple="true" name="ms2" dojoType="dojox.form.CheckedMultiSelect" dropdown="false">
 							<option value="UT">Utah</option>
 							<option value="TX" selected="selected">Texas</option>
 							<option value="GA" selected="selected">Georgia</option>
@@ -131,7 +131,7 @@
 					</td>
 					<td>
 						<button dojoType="dijit.form.Button">
-							<script type="dojo/method" event="onClick">
+							<script type="dojo/method" data-dojo-event="onClick">
 								ms2.set("readOnly", !ms2.readOnly);
 								return false;
 							</script>
@@ -141,12 +141,12 @@
 				</tr>
 				<tr>
 					<td>
-						<select jsId="ms3" multiple="true" maxHeight="125" name="ms3" dojoType="dojox.form.CheckedMultiSelect" dropdown="false">
+						<select data-dojo-id="ms3" multiple="true" maxHeight="125" name="ms3" dojoType="dojox.form.CheckedMultiSelect" dropdown="false">
 						</select>
 					</td>
 					<td>
 						<button dojoType="dijit.form.Button">
-							<script type="dojo/method" event="onClick">
+							<script type="dojo/method" data-dojo-event="onClick">
 								checkOptions++;
 								ms3.addOption({value: checkOptions + "", label: "Option " + (checkOptions)});
 								return false;
@@ -154,7 +154,7 @@
 							Add Check Option
 						</button>
 						<button dojoType="dijit.form.Button">
-							<script type="dojo/method" event="onClick">
+							<script type="dojo/method" data-dojo-event="onClick">
 								if(checkOptions > 0){
 									checkOptions--;
 									ms3.removeOption(checkOptions);
@@ -167,7 +167,7 @@
 				</tr>
 				<tr>
 					<td>
-						<select jsId="ms4" multiple="true" maxHeight="125" size="5" name="ms4" store="readStore" dojoType="dojox.form.CheckedMultiSelect" dropdown="false">
+						<select data-dojo-id="ms4" multiple="true" maxHeight="125" size="5" name="ms4" store="readStore" dojoType="dojox.form.CheckedMultiSelect" dropdown="false">
 						</select>
 					</td>
 					<td>
@@ -176,11 +176,11 @@
 				</tr>
 			</table>
 			<hr><h2>Validation</h2>
-			<select jsId="rq1" multiple="true" required="true" name="rq1" store="readStore" dojoType="dojox.form.CheckedMultiSelect" invalidMessage="You need to select at least one" dropdown="false">
+			<select data-dojo-id="rq1" multiple="true" required="true" name="rq1" store="readStore" dojoType="dojox.form.CheckedMultiSelect" invalidMessage="You need to select at least one" dropdown="false">
 			</select>
 			<button dojoType="dijit.form.Button">
 				Validate
-				<script type='dojo/method' event='onClick'>
+				<script type='dojo/method' data-dojo-event='onClick'>
 					var isvalid = rq1.isValid();
 					console.warn("isvalid?", isvalid, form, form.validate);
 					try{
@@ -194,7 +194,7 @@
 			</button>
 			<hr><h2>Output values in console</h2>
 			<button dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
+				<script type="dojo/method" data-dojo-event="onClick">
 					console.dir(form.get("value"));
 					return false;
 				</script>
diff --git a/dojox/form/tests/test_DateTextBox.html b/dojox/form/tests/test_DateTextBox.html
index 2187d17..3242cee 100644
--- a/dojox/form/tests/test_DateTextBox.html
+++ b/dojox/form/tests/test_DateTextBox.html
@@ -1,7 +1,7 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE HTML>
 <html>
 	<head>
+	    <meta charset="utf-8">
 		<title>Test DateTextBox Widget</title>
 
 		<!-- required: a default theme file -->
@@ -35,46 +35,40 @@
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true, extraLocale: ['de-de', 'en-us']"></script>
-			
+    	<script type="text/javascript" src="../../../dojo/dojo.js"
+        	data-dojo-config="async:1, parseOnLoad:1, transparentColor: [ 255, 255, 255 ], extraLocale: ['de-de', 'en-us']"></script>
+
+
 		<!-- do not use, only for dynamic themes -->
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dojox.form.DateTextBox");
-			dojo.require("dijit.form.Form");
-			dojo.require("dojo.date.locale");
-			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		</script>
 	</head>
 
 	<body class="tundra">
 		<h1 class="testTitle">Test DateTextBox Widget</h1>
 		<!--	to test form submission, you'll need to create an action handler similar to
 			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
-		<form id="form1" dojoType='dijit.form.Form' action="" name="example" method="">
+		<form id="form1" data-dojo-type='dijit/form/Form' action="" name="example" method="">
 			<div class="dojoTitlePaneLabel">
 				<label for="q1"> Date (local format) </label>
 				<span class="noticeMessage">DateTextBox class, no attributes</span>
 			</div>
 			<div class="testExample">
-				<input id="q1" name="noDOMvalue" type="text" dojoType="dojox.form.DateTextBox"
-				         onChange="dojo.byId('oc1').value=arguments[0]"
+				<input id="q1" name="noDOMvalue" type="text" data-dojo-type="dojox/form/DateTextBox"
+				    onChange="dojo.byId('oc1').value=arguments[0]"
 				>
 				onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off">
 			</div>
 
 			<div class="testExample">
 				Day Only
-				<input id="q1Day" name="q1Day" type="text" dojoType="dojox.form.DayTextBox"
+				<input id="q1Day" name="q1Day" type="text" data-dojo-type="dojox/form/DayTextBox"
 				         onChange="dojo.byId('oc1day').value=arguments[0]"
 				>
 				onChange:<input id="oc1day" size="34" disabled value="not fired yet!" autocomplete="off">
 			</div>
 			<div class="testExample">
 				Month Only
-				<input id="q1Month" name="q1Month" type="text" dojoType="dojox.form.MonthTextBox"
+				<input id="q1Month" name="q1Month" type="text" data-dojo-type="dojox/form/MonthTextBox"
 				         onChange="dojo.byId('oc1month').value=arguments[0]"
 				>
 				onChange:<input id="oc1month" size="34" disabled value="not fired yet!" autocomplete="off">
@@ -82,7 +76,7 @@
 
 			<div class="testExample">
 				Year Only
-				<input id="q1Year" name="q1Year" type="text" dojoType="dojox.form.YearTextBox"
+				<input id="q1Year" name="q1Year" type="text" data-dojo-type="dojox/form/YearTextBox"
 				         onChange="dojo.byId('oc1year').value=arguments[0]"
 				>
 				onChange:<input id="oc1year" size="34" disabled value="not fired yet!" autocomplete="off">
@@ -94,7 +88,7 @@
 			</div>
 			<div class="testExample">
 				<input id="q2" type="text" name="date1" class="medium" value="2005-12-30"
-					dojoType="dojox.form.DateTextBox"
+					data-dojo-type="dojox/form/DateTextBox"
 					constraints="{min:'2004-01-01',max:'2006-12-31',formatLength:'long'}"
 					required="true"
 					trim="true"
@@ -111,7 +105,7 @@
 			</div>
 			<div class="testExample">
 				<input id="q3" type="text" name="date2" class="medium" value="2005-12-30"
-					dojoType="dojox.form.DateTextBox"
+					data-dojo-type="dojox/form/DateTextBox"
 					constraints="{min:'2004-01-01',max:'2006-12-31'}"
 					lang="en-us"
 					required="true"
@@ -132,23 +126,26 @@
 				<span class="noticeMessage">Date, overriding pattern with dd-MM-yyyy</span>
 			</div>
 			<div class="testExample">
-				<input id="q5" name="noDOMvalue" type="text" dojoType="dojox.form.DateTextBox" constraints="{datePattern:'dd-MM-yyyy', strict:true}">
+				<input id="q5" name="noDOMvalue" type="text" data-dojo-type="dojox/form/DateTextBox" data-dojo-props="constraints:{datePattern:'dd-MM-yyyy', strict:true}">
 			</div>
 
 			<script>
-			// See if we can make a widget in script and attach it to the DOM ourselves.
-			dojo.addOnLoad(function(){
-				var props = {
-					name: "date4",
-					value: new Date(2006,10,29),
-					constraints: {min:new Date(2004,0,1),max:new Date(2006,11,31)},
-					lang: "de-de",
-					promptMessage: "dd.mm.yy",
-					rangeMessage: "Enter a date in the year range 2004-2006.",
-					invalidMessage: "Invalid date. Use dd.mm.yy format."
-				};
-				var w = new dojox.form.DateTextBox(props, "q4");
-			});
+			    // See if we can make a widget in script and attach it to the DOM ourselves.
+			    require([
+    				"dojox/form/DateTextBox",
+    				"dojo/domReady!"
+    			], function(DateTextBox){
+    				var props = {
+    					name: "date4",
+    					value: new Date(2006,10,29),
+    					constraints: {min:new Date(2004,0,1),max:new Date(2006,11,31)},
+    					lang: "de-de",
+    					promptMessage: "dd.mm.yy",
+    					rangeMessage: "Enter a date in the year range 2004-2006.",
+    					invalidMessage: "Invalid date. Use dd.mm.yy format."
+    				};
+    				var w = new DateTextBox(props, "q4");
+                });
 			</script>
 
 			<script>
@@ -168,10 +165,10 @@
 				<label for="fromDate"> Date pairs, to/from</label>
 			</div>
 			<div class="testExample">
-				From: <input id="fromDate" type="text" name="fromDate" dojoType="dojox.form.DateTextBox"
+				From: <input id="fromDate" type="text" name="fromDate" data-dojo-type="dojox/form/DateTextBox"
 					required="true"
 					onChange="dijit.byId('toDate').constraints.min = this.getValue();" />
-				To: <input id="toDate" type="text" name="toDate" dojoType="dojox.form.DateTextBox"
+				To: <input id="toDate" type="text" name="toDate" data-dojo-type="dojox/form/DateTextBox"
 					required="true"
 					onChange="dijit.byId('fromDate').constraints.max = this.getValue();" />
 			</div>
@@ -181,7 +178,6 @@
 				<input type="submit" name="submit" />
 				<input type="reset" name="reset" />
 			</div>
-
 		</form>
 	</body>
 </html>
diff --git a/dojox/form/tests/test_FileInput.html b/dojox/form/tests/test_FileInput.html
index ef1890f..7c49dba 100644
--- a/dojox/form/tests/test_FileInput.html
+++ b/dojox/form/tests/test_FileInput.html
@@ -10,7 +10,7 @@
 		@import "../resources/FileInput.css"; 
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.form.FileInput"); 
 		dojo.require("dojox.form.FileInputAuto"); 
diff --git a/dojox/form/tests/test_FilePickerTextBox.html b/dojox/form/tests/test_FilePickerTextBox.html
index 3f2e71d..bb1da2c 100644
--- a/dojox/form/tests/test_FilePickerTextBox.html
+++ b/dojox/form/tests/test_FilePickerTextBox.html
@@ -18,7 +18,7 @@
 	
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true, useCommentedJson: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true, useCommentedJson: true"></script>
 	
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -39,7 +39,7 @@
 	<p>The picker below uses the dojox.data.FileStore and a PHP implementation for the serverside to browse the dojo tree hierarchy in a lazy-load fashion.</p>
 	<p><i><b>This demo must be run from a web-server with PHP support enabled.  Without PHP support, this demo cannot function.</b></i></p>
 	<hr>
-	<div dojoType="dojox.data.FileStore" url="../../data/demos/stores/filestore_dojotree.php" jsId="fileStore" pathAsQueryParam="true"></div>
+	<div dojoType="dojox.data.FileStore" url="../../data/demos/stores/filestore_dojotree.php" data-dojo-id="fileStore" pathAsQueryParam="true"></div>
 	<form dojoType="dijit.form.Form" onSubmit="if(this.validate()){console.dir(this.getValues());}else{console.log('NOT VALID');} return false;">
 		<label>Choose a file:<input required="true" name="fileName" type="text" dojoType="dojox.form.FilePickerTextBox" constraints="{store: fileStore, query:{}}" /></label><br>
 		<button dojoType="dijit.form.Button" type="submit">Submit</button>
diff --git a/dojox/form/tests/test_FileUploader.html b/dojox/form/tests/test_FileUploader.html
index 341a842..bd0832e 100644
--- a/dojox/form/tests/test_FileUploader.html
+++ b/dojox/form/tests/test_FileUploader.html
@@ -55,7 +55,7 @@
 		 }
     </script>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-    	djConfig="isDebug:true, parseOnLoad: true, debugAtAllCosts:false"></script>
+    	data-dojo-config="isDebug:true, parseOnLoad: true, debugAtAllCosts:false"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.form.FileUploader");
 		dojo.require("dijit.form.Button");
diff --git a/dojox/form/tests/test_ListInput.html b/dojox/form/tests/test_ListInput.html
index 41f42c1..c108195 100755
--- a/dojox/form/tests/test_ListInput.html
+++ b/dojox/form/tests/test_ListInput.html
@@ -15,7 +15,7 @@
 		@import "../../../dojox/form/resources/ListInput.css";
 		
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="debugAtAllCost:true,isDebug: true,parseOnLoad:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="debugAtAllCost:true,isDebug: true,parseOnLoad:true"></script>
 	
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
@@ -93,7 +93,7 @@
 	<a dojoType="dijit.form.Button" onclick="getValuesMisMatch();">See unvalidated values in firebug</a>
 	
 	<h1>Demos</h1>
-	<div jsId="tabC" dojoType="dijit.layout.TabContainer" tabStrip="true" style="width: 100%; height:300px;">
+	<div data-dojo-id="tabC" dojoType="dijit.layout.TabContainer" tabStrip="true" style="width: 100%; height:300px;">
 		<div dojoType="dijit.layout.ContentPane" title="Demo 1">
 			<h1>With inputbox and editable items</h1>
 			
@@ -102,7 +102,7 @@
 				This feature can be desactivated
 			</blockquote>
 			
-			<div value="initial item 1" jsId="list_0" name="list" dojoType="dojox.form.ListInput"></div>
+			<div value="initial item 1" data-dojo-id="list_0" name="list" dojoType="dojox.form.ListInput"></div>
 		</div>
 		<div dojoType="dijit.layout.ContentPane" title="Demo 2">
 			<h1>Without inputbox and with editable items</h1>
@@ -112,26 +112,26 @@
 				This feature can be desactivated
 			</blockquote>
 			
-			<div value="initial item 1" jsId="list_1" readOnlyInput="true" dojoType="dojox.form.ListInput"></div>
+			<div value="initial item 1" data-dojo-id="list_1" readOnlyInput="true" dojoType="dojox.form.ListInput"></div>
 		</div>
 		<div dojoType="dijit.layout.ContentPane" title="Demo 3">
 			<h1>Without initial value</h1>
-			<div jsId="list_2" dojoType="dojox.form.ListInput"></div>
+			<div data-dojo-id="list_2" dojoType="dojox.form.ListInput"></div>
 		</div>
 		<div dojoType="dijit.layout.ContentPane" title="Demo 4">
 			<h1>With inputbox and without editable items</h1>
-			<div value="initial item 1" jsId="list_3" readOnlyItem="true"  dojoType="dojox.form.ListInput"></div>
+			<div value="initial item 1" data-dojo-id="list_3" readOnlyItem="true"  dojoType="dojox.form.ListInput"></div>
 		</div>
 		<div dojoType="dijit.layout.ContentPane" title="Demo 5">
 			<h1>Without inputbox and without editable items</h1>
-			<div value="initial item 1" jsId="list_4" readOnlyItem="true" readOnlyInput="true" dojoType="dojox.form.ListInput"></div>
+			<div value="initial item 1" data-dojo-id="list_4" readOnlyItem="true" readOnlyInput="true" dojoType="dojox.form.ListInput"></div>
 		</div>
 		<div dojoType="dijit.layout.ContentPane" title="Demo 6">
 			<h1>With validation</h1>
 			<blockquote>
 				note : enter only digits
 			</blockquote>
-			<div value="1234" jsId="list_5" regExp="[0-9]+" dojoType="dojox.form.ListInput"></div>
+			<div value="1234" data-dojo-id="list_5" regExp="[0-9]+" dojoType="dojox.form.ListInput"></div>
 		</div>
 		<div dojoType="dijit.layout.ContentPane" title="Demo 7">
 			<h1>With custom separator</h1>
@@ -139,7 +139,7 @@
 				note : you can use semi-colon for separate item<br />
 				You also can use an array of separators
 			</blockquote>
-			<div value="initial item 1" jsId="list_6" delimiter=";" dojoType="dojox.form.ListInput"></div>
+			<div value="initial item 1" data-dojo-id="list_6" delimiter=";" dojoType="dojox.form.ListInput"></div>
 		</div>
 		<div dojoType="dijit.layout.ContentPane" title="Demo 8">
 			<h1>With a submit form</h1>
@@ -147,7 +147,7 @@
 				note : after submit, see url
 			</blockquote>
 			<form action="?" method="get">
-				<div value="initial item 1" name="demo8" jsId="list_7" dojoType="dojox.form.ListInput"></div>
+				<div value="initial item 1" name="demo8" data-dojo-id="list_7" dojoType="dojox.form.ListInput"></div>
 				<input type="submit" />
 			</form>
 		</div>
@@ -158,7 +158,7 @@
 				enter only digits
 			</blockquote>
 			<form action="?" method="get">
-				<div name="demo9" jsId="list_8" value="invalid value,1234" regExp="[0-9]+" submitOnlyValidValue="true" dojoType="dojox.form.ListInput"></div>
+				<div name="demo9" data-dojo-id="list_8" value="invalid value,1234" regExp="[0-9]+" submitOnlyValidValue="true" dojoType="dojox.form.ListInput"></div>
 				<input type="submit" />
 			</form>
 		</div>
@@ -167,7 +167,7 @@
 			<blockquote>
 				note : you can only add 3 items
 			</blockquote>
-			<div value="initial item 1" jsId="list_9" maxItems="3" dojoType="dojox.form.ListInput"></div>
+			<div value="initial item 1" data-dojo-id="list_9" maxItems="3" dojoType="dojox.form.ListInput"></div>
 		</div>
 		<div dojoType="dijit.layout.ContentPane" title="Demo 11">
 			<h1>Without close button</h1>
@@ -178,11 +178,11 @@
 				- never<br />
 				- always<br />
 			</blockquote>
-			<div jsId="list_10" showCloseButtonWhenValid="false" showCloseButtonWhenInvalid="false" dojoType="dojox.form.ListInput"></div>
+			<div data-dojo-id="list_10" showCloseButtonWhenValid="false" showCloseButtonWhenInvalid="false" dojoType="dojox.form.ListInput"></div>
 		</div>
 		<div dojoType="dijit.layout.ContentPane" title="Demo 12">
 			<h1>Without anim</h1>
-			<div value="initial item 1" jsId="list_11" useAnim="false" dojoType="dojox.form.ListInput"></div>
+			<div value="initial item 1" data-dojo-id="list_11" useAnim="false" dojoType="dojox.form.ListInput"></div>
 		</div>
 	</div>
 </body>
diff --git a/dojox/form/tests/test_Manager1.html b/dojox/form/tests/test_Manager1.html
index e080fe4..894dbe2 100644
--- a/dojox/form/tests/test_Manager1.html
+++ b/dojox/form/tests/test_Manager1.html
@@ -1,8 +1,9 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
-	<title>dojox.form.Manager (test #1)</title>
-	<style type="text/css">
+	<meta charset="utf-8">
+	<title>dojox/form/Manager (test #1)</title>
+	<style >
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/dijit.css";
 		@import "../../../dijit/themes/tundra/tundra.css";
@@ -17,7 +18,7 @@
 
 		.makeYellow		{ background-color: #ffa; }
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script src="../../../dojo/dojo.js" data-dojo-config="async: 1, isDebug: 1, parseOnLoad: 0"></script>
 	<!--
 	<script type="text/javascript" src="../manager/_Mixin.js"></script>
 	<script type="text/javascript" src="../manager/_FormMixin.js"></script>
@@ -27,7 +28,7 @@
 	<script type="text/javascript" src="../manager/_ClassMixin.js"></script>
 	<script type="text/javascript" src="../Manager.js"></script>
 	-->
-	<script type="text/javascript">
+	<script>
 		dojo.require("dojox.form.Manager");
 
 		dojo.require("dijit.dijit");			// optimize: load dijit layer
@@ -110,7 +111,7 @@
 				<fieldset dojoAttachPoint="part2">
 					<legend>Dijit form widgets</legend>
 					<div>
-						<input type="checkbox" dojoType="dijit.form.CheckBox" id="w01" name="w01" value="w01" observer="showValues">
+						<input type="checkbox" dojoType="dijit.form.CheckBox" id="w01" name="w01" value="w01" data-dojo-observer="showValues">
 						 <label for="w01">w01 input/checkbox dijit.form.CheckBox</label>
 					</div>
 					<div>
@@ -147,16 +148,16 @@
 						<button type="submit" dojoType="dijit.form.Button" name="w11" observer="showValues">w11 typesubmit</button>
 					</div>
 				</fieldset>
-				<script type="dojo/method" event="onSubmit">
+				<script type="dojo/method" data-dojo-event="onSubmit">
 					// do not submit this form
 					return false;
 				</script>
-				<script type="dojo/method" event="logRadio">
+				<script type="dojo/method" data-dojo-event="logRadio">
 					// sample observer: logs radio buttons by name
 					var values = this.gatherFormValues(["e02", "w02"]);
 					console.log("e02: " + values.e02 + ", w02: " + values.w02);
 				</script>
-				<script type="dojo/method" event="showValues" args="value,name">
+				<script type="dojo/method" data-dojo-event="showValues" data-dojo-args="value,name">
 					if(name){
 						// first time this method is called with no parameters
 						// show the name and the value otherwise
diff --git a/dojox/form/tests/test_Manager_amd.html b/dojox/form/tests/test_Manager_amd.html
new file mode 100644
index 0000000..09e7326
--- /dev/null
+++ b/dojox/form/tests/test_Manager_amd.html
@@ -0,0 +1,236 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta charset="utf-8">
+	
+	<title>dojox/form/Manager (test #1)</title>
+	<style>
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/themes/dijit.css";
+		@import "../../../dijit/themes/claro/claro.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+
+		fieldset		{ border: 1px solid; margin: 1em; padding: 1em; }
+		legend 			{ font-weight: bolder; font-size: larger; }
+
+		#result			{ background-color: white; }
+		#result th		{ font-weight: bolder; }
+		#result .hilite	{ background-color: #fd8; }
+
+		.makeYellow		{ background-color: #ffa; }
+	</style>
+	<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: 1, parseOnLoad: 0, async: 1"></script>
+</head>
+<body class="claro">
+	<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'sidebar',gutters:false,liveSplitters:false" style="height: 50em;">
+		<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'left',splitter:true" style="width: 15em;">
+			<table id="result" border="1">
+				<thead>
+					<th>Name</th>
+					<th>Value</th>
+				</thead>
+				<tbody id="table"></tbody>
+			</table>
+			<p id="controls">
+				<input type="checkbox" id="c01" name="c01" value="c01" checked="checked">
+				 <label for="c01">enable the form elements and widgets</label>
+				<br>
+				<input type="checkbox" id="c02" name="c02" value="c02">
+				 <label for="c02">add/remove yellow background</label>
+				<br>
+				<input type="checkbox" id="c03" name="c03" value="c03" checked="checked">
+				 <label for="c03">show form elements</label>
+				<br>
+				<input type="checkbox" id="c04" name="c04" value="c04" checked="checked">
+				 <label for="c04">show form widgets</label>
+			</p>
+		</div>
+		<div data-dojo-type="dijit/layout/ContentPane" id="formContainer" data-dojo-props="region:'center',splitter:true">
+			<form data-dojo-type="dojox/form/Manager" id="form">
+				<fieldset data-dojo-attach-point="part1">
+					<legend>HTML form elements</legend>
+					<div>
+						<input type="checkbox" id="e01" name="e01" value="e01" data-dojo-observer="showValues, logRadio">
+						 <label for="e01">e01 input/checkbox</label>
+					</div>
+					<div>						
+						<input type="radio" id="e021" name="e02" value="e02-1" data-dojo-observer="showValues">
+						 <label for="e021">e02-1 input/radio</label>
+						 
+						<input type="radio" id="e022" name="e02" value="e02-2" checked="checked" data-dojo-observer="showValues">
+						 <label for="e022">e02-2 input/radio</label>
+					</div>
+					<div>
+						<input type="text" id="e03" name="e03" value="e03" data-dojo-observer="showValues">
+						 <label for="e03">e03 input/text</label>
+					</div>
+					<div>
+						<input type="password" id="e04" name="e04" value="e04" data-dojo-observer="showValues">
+						 <label for="e04">e04 input/password</label>
+					</div>
+					<div>
+						<input type="hidden" id="e05" name="e05" value="e05" data-dojo-observer="showValues">
+						 <label for="e05">e05 input/hidden</label>
+					</div>
+					<div>
+						<select id="e06" name="e06" data-dojo-observer="showValues">
+							<option value="e06-1">e06-1 first</option>
+							<option value="e06-2" selected="selected">e06-2 second</option>
+						</select>
+						 <label for="e06">e06 select</label>
+					</div>
+					<div>
+						<label for="e07">e07 textarea</label><br>
+						<textarea id="e07" name="e07" data-dojo-observer="showValues"
+							rows="3" cols="15" style="width: 15em;">e07</textarea>
+					</div>
+					<div>
+						<button name="e08" data-dojo-observer="showValues">e08 button</button> 
+						<input type="button" name="e09" value="e09 input/button" data-dojo-observer="showValues"> 
+						<input type="reset" name="e10" value="e10 input/reset" data-dojo-observer="showValues"> 
+						<input type="submit" name="e11" value="e11 input/submit" data-dojo-observer="showValues">
+					</div>
+				</fieldset>
+				<fieldset dojoAttachPoint="part2">
+					<!-- FIXME: None of these appear to work with data-dojo-observer, or even observer -->
+					<legend>Dijit form widgets</legend>
+					<div>
+						<input type="checkbox" data-dojo-type="dijit/form/CheckBox" id="w01" name="w01" value="w01" data-dojo-observer="showValues">
+						 <label for="w01">w01 input/checkbox dijit/form/CheckBox</label>
+					</div>
+					<div>
+						<input type="radio" data-dojo-type="dijit/form/RadioButton" id="w021" name="w02" value="w02-1" data-dojo-observer="showValues">
+						 <label for="w021">w02-1 input/radio dijit/form/RadioButton</label>
+						 
+						<input type="radio" data-dojo-type="dijit/form/RadioButton" id="w022" name="w02" value="w02-2" checked="checked" data-dojo-bserver="logRadio">
+						 <label for="w022">w02-2 input/radio dijit/form/RadioButton</label>
+					</div>
+					<div>
+						<input type="text" data-dojo-type="dijit/form/TextBox" id="w03" name="w03" value="w03" data-dojo-observer="showValues" intermediateChanges="true">
+						 <label for="w03">w03 input/text dijit/form/TextBox with intermediateChanges="true"</label>
+					</div>
+					<div>
+						<input type="password" data-dojo-type="dijit/form/TextBox" id="w04" name="w04" value="w04" data-dojo-observer="showValues">
+						 <label for="w04">w04 input/password dijit/form/TextBox</label>
+					</div>
+					<div>
+						<select data-dojo-type="dijit/form/Select" id="w06" name="w06" data-dojo-observer="showValues">
+							<option value="w06-1">w06-1 first</option>
+							<option value="w06-2" selected="selected">w06-2 second</option>
+						</select>
+						 <label for="w06">w06 select dijit/form/Select</label>
+					</div>
+					<div>
+						<label for="w07">w07 textarea dijit/form/SimpleTextarea with intermediateChanges="true"</label><br>
+						<textarea data-dojo-type="dijit/form/SimpleTextarea" id="w07" name="w07" data-dojo-observer="showValues"
+							rows="3" cols="15" style="width: 15em;" intermediateChanges="true">w07</textarea>
+					</div>
+					<div>
+						<button data-dojo-type="dijit/form/Button" name="w08" data-dojo-observer="showValues">w08 button</button> 
+						<button type="button" data-dojo-type="dijit/form/Button" name="w09" data-dojo-observer="showValues">w09 type=button</button> 
+						<button type="reset" data-dojo-type="dijit/form/Button" name="w10" data-dojo-observer="showValues">w10 type=reset</button> 
+						<button type="submit" data-dojo-type="dijit/form/Button" name="w11" data-dojo-observer="showValues">w11 type=submit</button>
+					</div>
+				</fieldset>
+				</script>
+				<script type="dojo/method" data-dojo-event="logRadio">
+					// sample observer: logs radio buttons by name
+					var values = this.gatherFormValues(["e02", "w02"]);
+					console.log("e02: " + values.e02 + ", w02: " + values.w02);
+				</script>
+				<script type="dojo/method" data-dojo-event="showValues" data-dojo-args="value,name">
+					if(name){
+						// first time this method is called with no parameters
+						// show the name and the value otherwise
+						console.log("name = ", name, " value = ", value);
+					}
+					require(["dijit/registry", "dojo/query", "dojo/dom-class", "dojo/dom-construct", "dojo/dom"],
+					function(registry, query, domClass, domConstruct, dom){
+						// clear any hilited cells
+						query("tr.hilite", dom.byId("table")).forEach(function(node){
+							domClass.remove(node, "hilite");
+						});
+						// get the node of the table row used to display the value for this input
+						var rowNode = dom.byId("tr" + name);
+						// hilite the node
+						domClass.add(rowNode, "hilite");
+						// update the value displayed
+						query("td.value", rowNode).forEach(function(node){
+							var textNode = document.createTextNode(value.toString());
+							domConstruct.place(textNode, node, "only");
+						});
+					});
+				</script>
+			</form>
+		</div>
+	</div>
+		<script>
+			require([
+				"dijit/registry",
+				"dojo/parser",
+				"dojo/on",
+				"dojo/query",
+				"dojo/dom-construct",
+				"dojo/_base/lang",
+				"dojo/_base/array",
+				"dojo/dom",
+				"dijit/layout/ContentPane",
+				"dijit/layout/BorderContainer",
+				"dojox/form/Manager",
+				"dijit/form/Button",
+				"dijit/form/CheckBox",
+				"dijit/form/RadioButton",
+				"dijit/form/TextBox",
+				"dijit/form/ComboBox",
+				"dijit/form/SimpleTextarea",
+				"dijit/form/Select",
+				"dojo/domReady!"],
+			function(registry, parser, on, query, domConstruct, lang, arrayUtil, dom){
+				// parse the page to render the Dojo elements
+				parser.parse();
+				// get the form widget
+				var form = registry.byId("form");
+				// query for all the inputs whose name begins with e (for element) or w (for widget)
+				var names = [];
+				query("[name^=e], [name^=w]", dom.byId("form")).forEach(function(node){
+					if(arrayUtil.lastIndexOf(names, node.name, names.length - 1) === -1){
+						names.push(node.name);
+					}
+				});
+				// gather the values in the form for all the inputs named in the name array
+				var values = form.gatherFormValues(names),
+					table = dom.byId("table");
+				// sort the name array and create a table to display the names and values
+				names.sort();
+				arrayUtil.forEach(names, function(name){
+					// Note: This is just a quick way to create a table, and is
+					// not the most performant way to create a table using Dojo,
+					// but is sufficient for this example
+					domConstruct.place('<tr id="tr' + name + '"><td>' + name + '</td><td class="value">' + values[name] + '</td>',table);
+					});
+				// attach the event handlers to the control checkboxes
+				query("input[id^=c0]", dom.byId("controls")).on("click", function(evt){
+					switch (evt.target.id){
+						case "c01":
+							form[this.checked ? "enable" : "disable"]();
+							break;
+						case "c02":
+							form[this.checked ? "addClass" : "removeClass"]("makeYellow", ["part1", "part2"]);
+							break;
+						case "c03":
+							form[this.checked ? "show" : "hide"](["part1"]);
+							break;
+						case "c04":
+							form[this.checked ? "show" : "hide"](["part2"]);
+					}
+				});
+				// ensure the submit buttons don't submit, but log
+				form.on("submit", function(evt){
+					evt.preventDefault();
+					evt.stopPropagation();
+					console.log("Submit");
+				});
+			});
+		</script>
+	</body>
+</html>
diff --git a/dojox/form/tests/test_MultiComboBox.html b/dojox/form/tests/test_MultiComboBox.html
index cda0244..e5e0692 100644
--- a/dojox/form/tests/test_MultiComboBox.html
+++ b/dojox/form/tests/test_MultiComboBox.html
@@ -15,7 +15,7 @@
 
 		</style>
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("dojox.form.MultiComboBox");
@@ -32,7 +32,7 @@
 		by the delimiter="" attrbute.
 		</p>
 
-		<div dojoType="dojo.data.ItemFileReadStore" jsId="memberTagStore"
+		<div dojoType="dojo.data.ItemFileReadStore" data-dojo-id="memberTagStore"
 			url="_tags.json"></div>
 		
 		<h3>Default:</h3>		
@@ -53,7 +53,7 @@
 		<h3>From code:</h3>
 		<button dojoType="dijit.form.Button">
 			Make it.
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				var widget = new dojox.form.MultiComboBox({
 					store:memberTagStore,
 					searchAttr:"tag"
diff --git a/dojox/form/tests/test_PasswordValidator.html b/dojox/form/tests/test_PasswordValidator.html
index df2d88c..084a0d6 100644
--- a/dojox/form/tests/test_PasswordValidator.html
+++ b/dojox/form/tests/test_PasswordValidator.html
@@ -2,7 +2,7 @@
 	<head>
 	    <script type="text/javascript" 
 	        src="../../../dojo/dojo.js"
-	        djConfig="isDebug: true, parseOnLoad: true">
+	        data-dojo-config="isDebug: true, parseOnLoad: true">
 	    </script>
 	    <script type="text/javascript">
 			dojo.require("doh.runner");
@@ -105,17 +105,17 @@
 		<h1 class="testTitle">Test: dojox.form.PasswordValidator</h1>
 		<h2>Automated test</h2>
 		<h4 class="testSubtitle">No old password</h4>
-		<form dojoType="dijit.form.Form" jsId="form1" action="" method="GET">
-			<div dojoType="dojox.form.PasswordValidator" jsId="valid1" name="password">
+		<form dojoType="dijit.form.Form" data-dojo-id="form1" action="" method="GET">
+			<div dojoType="dojox.form.PasswordValidator" data-dojo-id="valid1" name="password">
 				<label>Password: <input type="password" id="nv1" pwType="new" /></label><br>
 				<label>Validate: <input type="password" id="vv1" pwType="verify" /></label><br>
 			</div>
 		</form>
 		<hr>
 		<h4 class="testSubtitle">Old password (hard-coded to "oldpw2") - not passed to getValues</h4>
-		<form dojoType="dijit.form.Form" jsId="form2" action="" method="GET">
-			<div dojoType="dojox.form.PasswordValidator" jsId="valid2" name="password">
-				<script type="dojo/method" event="pwCheck" args="password">
+		<form dojoType="dijit.form.Form" data-dojo-id="form2" action="" method="GET">
+			<div dojoType="dojox.form.PasswordValidator" data-dojo-id="valid2" name="password">
+				<script type="dojo/method" data-dojo-event="pwCheck" data-dojo-args="password">
 					/* 
 						NOTE:  Do NOT EVER EVER EVER do this sort of a check!!!
 						
@@ -144,9 +144,9 @@
 		</form>
 		<hr>
 		<h4 class="testSubtitle">Old password (hard-coded to "oldpw3") - passed to getValues</h4>
-		<form dojoType="dijit.form.Form" jsId="form3" action="" method="GET">
-			<div dojoType="dojox.form.PasswordValidator" jsId="valid3" name="password" oldName="oldPassword">
-				<script type="dojo/method" event="pwCheck" args="password">
+		<form dojoType="dijit.form.Form" data-dojo-id="form3" action="" method="GET">
+			<div dojoType="dojox.form.PasswordValidator" data-dojo-id="valid3" name="password" oldName="oldPassword">
+				<script type="dojo/method" data-dojo-event="pwCheck" data-dojo-args="password">
 					console.log("Checking " + password);
 					return password === "oldpw3";
 				</script>
@@ -157,9 +157,9 @@
 		</form>
 		<hr>
 		<h4 class="testSubtitle">In Table, Old password (hard-coded to "oldpw4") - not passed to getValues</h4> 
-		<form dojoType="dijit.form.Form" jsId="form4"> 
-				<div dojoType="dojox.form.PasswordValidator" jsId="valid4" name="password"> 
-						<script type="dojo/method" event="pwCheck" args="password"> 
+		<form dojoType="dijit.form.Form" data-dojo-id="form4">
+				<div dojoType="dojox.form.PasswordValidator" data-dojo-id="valid4" name="password">
+						<script type="dojo/method" data-dojo-event="pwCheck" data-dojo-args="password">
 								return password === "oldpw4"; 
 						</script> 
 						<table> 
@@ -180,9 +180,9 @@
 		</form> 
 		<hr>
 		<h4 class="testSubtitle">In Table, Old password (hard-coded to "oldpw5") - passed to getValues</h4> 
-		<form dojoType="dijit.form.Form" jsId="form5"> 
-				<div dojoType="dojox.form.PasswordValidator" jsId="valid5" name="password" oldName="oldPassword"> 
-						<script type="dojo/method" event="pwCheck" args="password"> 
+		<form dojoType="dijit.form.Form" data-dojo-id="form5">
+				<div dojoType="dojox.form.PasswordValidator" data-dojo-id="valid5" name="password" oldName="oldPassword">
+						<script type="dojo/method" data-dojo-event="pwCheck" data-dojo-args="password">
 								return password === "oldpw5"; 
 						</script> 
 						<table> 
@@ -203,15 +203,15 @@
 		</form> 
 		<hr>
 		<h4 class="testSubtitle">No old password, not required</h4>
-		<form dojoType="dijit.form.Form" jsId="form6">
-			<div dojoType="dojox.form.PasswordValidator" required="false" jsId="valid6" name="password">
+		<form dojoType="dijit.form.Form" data-dojo-id="form6">
+			<div dojoType="dojox.form.PasswordValidator" required="false" data-dojo-id="valid6" name="password">
 				<label>Password: <input type="password" id="nv6" pwType="new" /></label><br>
 				<label>Validate: <input type="password" id="vv6" pwType="verify" /></label><br>
 			</div>
 		</form>
 		<hr>
 		<button dojoType="dijit.form.Button">
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				dojo.forEach([form1, form2, form3, form4, form5, form6], function(i){
 					console.dir(i.get("value"));
 				});
@@ -219,25 +219,25 @@
 			Get Values
 		</button>
 		<button dojoType="dijit.form.Button">
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				valid5.set("disabled", !valid5.disabled);
 			</script>
 			Toggle Disabled
 		</button>
 		<button dojoType="dijit.form.Button">
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				form1.submit();
 			</script>
 			Submit Form 1
 		</button>
 		<button dojoType="dijit.form.Button">
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				form2.submit();
 			</script>
 			Submit Form 2
 		</button>
 		<button dojoType="dijit.form.Button">
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				form3.submit();
 			</script>
 			Submit Form 3
diff --git a/dojox/form/tests/test_RangeSlider.html b/dojox/form/tests/test_RangeSlider.html
index 5d8dfc9..0941a3b 100644
--- a/dojox/form/tests/test_RangeSlider.html
+++ b/dojox/form/tests/test_RangeSlider.html
@@ -1,11 +1,11 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="en">
 <head>
 	<title>Dojox RangeSlider Test</title>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
-		@import "../../../dijit/themes/tundra/tundra.css";
-		@import "../../../dijit/themes/dijit.css";
+		@import "../../../dijit/themes/claro/document.css";
+		@import "../../../dijit/themes/claro/claro.css";
 		@import "../../../dijit/tests/css/dijitTests.css";
 		@import "../resources/RangeSlider.css";
 	</style>
@@ -21,7 +21,7 @@
 
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
 		dojo.require("dojox.form.RangeSlider");
@@ -48,10 +48,11 @@
 	</script>
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 </head>
-<body class="tundra">
+<body class="claro" role="main">
 	<h1 class="testTitle">Dojox RangeSlider test</h1>
 	Just try to drag the slider endpoints and the bar in the middle. You can also use the bumper and the arrows on the left and right to manipulate the range. It's also possible to tab through the slider parts and move the handlers or bar with left/right/up/down-button. 
 	<h2>Horizontal slider</h2>
+	<center>
 	<div 
 		id="hrSlider" 
 		discreteValues="11"
@@ -63,8 +64,9 @@
 		<ol dojoType="dijit.form.HorizontalRuleLabels" container="topDecoration" style="height:1.2em;font-size:75%;color:gray;" count="7" constraints="{pattern:'#.00%'}"></ol>
 		<div dojoType="dijit.form.HorizontalRule" container="topDecoration" count=7 style="height:10px;margin-bottom:-5px;"></div>
 	</div>
-	Horizontal Slider Min Value:<input readonly id="minValue" size="10" value="20.0%"/><br/>
-	Horizontal Slider Max Value:<input readonly id="maxValue" size="10" value="80.0%"/><br/>
+	</center>
+	<label for="minValue">Horizontal Slider Min Value:</label><input readonly id="minValue" size="10" value="20.0%"/><br/>
+	<label for="maxValue">Horizontal Slider Max Value:</label><input readonly id="maxValue" size="10" value="80.0%"/><br/>
 	<button id="disableButton" dojoType="dijit.form.Button" onClick="dijit.byId('hrSlider').set('disabled', true);dijit.byId('disableButton').set('disabled',true);dijit.byId('enableButton').set('disabled',false);">Disable previous slider</button>
 	<button id="enableButton"  dojoType="dijit.form.Button" onClick="dijit.byId('hrSlider').set('disabled', false);dijit.byId('disableButton').set('disabled',false);dijit.byId('enableButton').set('disabled', true);" disabled>Enable previous slider</button>
 	
@@ -89,14 +91,11 @@
 		</ol>
 		<div dojoType="dijit.form.VerticalRule" container="leftDecoration" count=11 style="width:5px;" ruleStyle="border-color:gray;"></div>
 		<div dojoType="dijit.form.VerticalRule" container="rightDecoration" count=11 style="width:5px;" ruleStyle="border-color:gray;"></div>
-		<ol dojoType="dijit.form.VerticalRuleLabels" 
-			container="rightDecoration" 
-			style="width:2em;color:gray;" count="4" numericMargin="100" maximum="10" constraints="{pattern:'#'}"
-		></ol>
+		<ol dojoType="dijit.form.VerticalRuleLabels" data-dojo-props='container:"rightDecoration", style:{width:"2em"}, count:6, numericMargin:1, minimum:0, maximum:100, constraints:{pattern:"#"}'></ol>
 	</div>
 	<p>
-	Vertical Slider Max Value:<input readonly id="vMaxValue" size="10" value="50.0"/><br/>
-	Vertical Slider Min Value:<input readonly id="vMinValue" size="10" value="20.0"/><br/>
+	<label for="vMaxValue">Vertical Slider Max Value:</label><input readonly id="vMaxValue" size="10" value="90.0"/><br/>
+	<label for="vMinValue">Vertical Slider Min Value:</label><input readonly id="vMinValue" size="10" value="10.0"/><br/>
 	</p>
 </body>
 </html>
diff --git a/dojox/form/tests/test_Rating.html b/dojox/form/tests/test_Rating.html
index abe75a2..20bdf81 100644
--- a/dojox/form/tests/test_Rating.html
+++ b/dojox/form/tests/test_Rating.html
@@ -10,7 +10,7 @@
 		@import "../resources/Rating.css"; 
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.form.Rating");
 		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
@@ -59,10 +59,10 @@
 	The attribute "numStars" is set to 10, so we see ten stars.
 	<div id="rating1Box">
 		<span id="rating1" dojoType="dojox.form.Rating" numStars="10">
-			<script type="dojo/event" event="onChange">
+			<script type="dojo/event" data-dojo-event="onChange">
 				dojo.query('#rating1Value')[0].innerHTML = this.value;
 			</script>
-			<script type="dojo/event" event="onMouseOver" args="evt,value">
+			<script type="dojo/event" data-dojo-event="onMouseOver" data-dojo-args="evt,value">
 				dojo.query('#rating1HoverValue')[0].innerHTML = value;
 			</script>
 		</span>
diff --git a/dojox/form/tests/test_SelectStack.html b/dojox/form/tests/test_SelectStack.html
index 211ab5d..65aca7f 100644
--- a/dojox/form/tests/test_SelectStack.html
+++ b/dojox/form/tests/test_SelectStack.html
@@ -2,7 +2,7 @@
 	<head>
 	    <script type="text/javascript" 
 	        src="../../../dojo/dojo.js"
-	        djConfig="isDebug: true, parseOnLoad: true">
+	        data-dojo-config="isDebug: true, parseOnLoad: true">
 	    </script>
 	    <script type="text/javascript">
 			dojo.require("doh.runner");
@@ -78,7 +78,7 @@
 	</head>	
 	<body class="tundra">
 		<h1 class="testTitle">Test: dojox.form.SelectStack</h1>
-		<form dojoType="dijit.form.Form" jsId="form">
+		<form dojoType="dijit.form.Form" data-dojo-id="form">
 			<h4 class="testSubtitle">DropDown-based Select</h4>
 			<select dojoType="dojox.form.DropDownStack" name="dropDown" 
 				stackId="dropDownStack"></select>
@@ -119,7 +119,7 @@
 			<select dojoType="dojox.form.DropDownStack" name="dual" stackId="dualStack" stackPrefix="dual_"></select><br>
 		<hr>
 			<button dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
+				<script type="dojo/method" data-dojo-event="onClick">
 					console.dir(form.get("value"));
 				</script>
 				Get Values
diff --git a/dojox/form/tests/test_TimeSpinner.html b/dojox/form/tests/test_TimeSpinner.html
index 7e8f8e5..1b7f6cd 100644
--- a/dojox/form/tests/test_TimeSpinner.html
+++ b/dojox/form/tests/test_TimeSpinner.html
@@ -10,7 +10,7 @@
 			@import "../../../dijit/themes/claro/claro.css";
 		</style>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
diff --git a/dojox/form/tests/test_TriStateCheckbox.html b/dojox/form/tests/test_TriStateCheckbox.html
index 5cc8880..0e3d8e9 100644
--- a/dojox/form/tests/test_TriStateCheckbox.html
+++ b/dojox/form/tests/test_TriStateCheckbox.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>TriStateCheckBox Widget Demo</title>
@@ -8,128 +8,166 @@
 			@import "../../../dijit/tests/css/dijitTests.css";
 			@import "../resources/TriStateCheckBox.css";
 			label {
-			    margin-right: 0.80em;
+				margin-right: 0.80em;
+				line-height: 25px;
+				vertical-align: middle;
 			}
 		</style>
 		<!-- required: the default dijit theme: -->
 		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true">
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true">
 		</script>
+		<!-- only needed for alternate theme testing: -->
+		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-			dojo.require("dijit.form.Button");
-			dojo.require("dijit.form.Form");
-			dojo.require("dojox.form.TriStateCheckBox");
-			function reportChecked(checked){
-				dojo.byId("oncheckedoutput").innerHTML = checked;
-			}
-			function reportValueChanged(value) {
-				dojo.byId("onvaluechangedoutput").innerHTML = dijit.byId("cb7").get("value");
-			}
-			function reportValueChanged2(value) {
-				dojo.byId("onvaluechangedoutput2").innerHTML = dijit.byId("cb8").get("value");
-			}
-			function defaultSubmitHandler(values){
-				console.debug('actual submitted values: ' + dojo.toJson(values));
-				dojo.byId("submitoutput").innerHTML = dojo.toJson(values);
-			}
-			submittedValues = defaultSubmitHandler;
-			
-			dojo.addOnLoad(function(){
-				var params = {id: "cb6", name: "cb6", checked: true };
-				new dojox.form.TriStateCheckBox(params, "cb6");
+			require(["dojo/_base/kernel", "dojo/parser", "dojo/ready", "dojo/dom", "dojo/json", "dijit/registry", 
+			         "dojox/form/TriStateCheckBox", "dijit/form/Button", "dijit/form/Form"],
+			function(kernel, parser, ready, dom, JSON, registry, TriStateCheckBox){
+				kernel.global["registry"] = registry;
+				reportChecked = function(checked){
+					dom.byId("oncheckedoutput").innerHTML = checked;
+				}
+				reportValueChanged = function(value){
+					dom.byId("onvaluechangedoutput").innerHTML = registry.byId("cb7").get("value");
+				}
+				reportValueChanged2 = function(value){
+					dom.byId("onvaluechangedoutput2").innerHTML = registry.byId("cb8").get("value");
+				}
+				defaultSubmitHandler = function(values){
+					console.debug('actual submitted values: ' + JSON.stringify(values));
+					dom.byId("submitoutput").innerHTML = JSON.stringify(values);
+				}
+				submittedValues = defaultSubmitHandler;
+				
+				ready(function(){
+					parser.parse();
+					var params = {id: "cb6", name: "cb6", checked: true };
+					new TriStateCheckBox(params, "cb6");
+					new TriStateCheckBox({
+						id: "cb11",
+						checked: "mixed"
+					}, "cb11");
+				});
 			});
 		</script>
 	</head>
-	<body class="claro">
+	<body class="claro" role="main">
 		<h1 class="testTitle">Dojox TriStateCheckBoxes Test</h1>
 		<p>
-			Here are some triStateCheckBoxes.  Try clicking, and hovering, tabbing, and using the space bar to select:
+			Here are some TriStateCheckBoxes.  Try clicking, and hovering, tabbing, and using the space bar to select:
 		</p>
 		<!--    to test form submission, you'll need to create an action handler similar to
 		http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
-		<form id="myForm" data-dojo-type="dijit.form.Form" data-dojo-props='action:"../../../dijit/tests/formAction.html", method:"", target:"formSubmitIframe"'>
+		<form id="myForm" data-dojo-type="dijit/form/Form" data-dojo-props='action:"../../../dijit/tests/formAction.html", method:"", target:"formSubmitIframe"'>
 			<input type="checkbox" id="cb0" checked/>
-			<label for="cb0">
+			<label for="cb0" style="vertical-align: top; line-height: 1em;">
 				cb0: Vanilla (non-dojo) checkbox (for comparison purposes)
 			</label>
-			<br>
-			<input id="cb1" data-dojo-id="cb1" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='name:"cb1", value:"foo", onClick:function(){ console.log("clicked cb1") }'/>
+			<br/>
+			<h2>Standard TriStateCheckbox</h2>
+			<input id="cb1" data-dojo-id="cb1" data-dojo-type="dojox/form/TriStateCheckBox" value="foo" name="cb1" data-dojo-props='onClick:function(){ console.log("clicked cb1") }'/>
 			<label for="cb1">
-				cb1: normal TriStateCheckbox, with value=foo, clicking generates console log messages
+				cb1: Standard TriStateCheckbox, with value=foo, clicking generates console log messages
 			</label>
-			<button type=button onclick="alert(dijit.byId('cb1').get('value'));">
+			<button data-dojo-type="dijit/form/Button" onclick="alert(dijit.byId('cb1').get('value'));">
 				get('value')
 			</button>
-			<br>
-			<input id="cb2" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='onChange:reportChecked, name:"cb2", checked:true'/>
+			<br/>
+			<input type="checkbox" id="cb2" data-dojo-type="dojox/form/TriStateCheckBox" name="cb2" data-dojo-props='onChange:reportChecked, checked:true'/>
 			<label for="cb2">
-				cb2: normal TriStateCheckbox, with default value, initially turned on.
+				cb2: Standard TriStateCheckbox, with default value, initially turned on.
 			</label>
 			<span>"onChange" handler displays attribute 'checked': [<span id="oncheckedoutput"></span>]</span>
-			<button type=button onclick="alert(dijit.byId('cb2').get('value'));">
+			<button data-dojo-type="dijit/form/Button" onclick="alert(dijit.byId('cb2').get('value'));">
 				get('value')
 			</button>
-			<br>
-			<input id="cb3" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='name:"cb3", disabled:true'/>
+			<br/>
+			<input type="checkbox" id="cb3" data-dojo-type="dojox/form/TriStateCheckBox" disabled="disabled" name="cb3" />
 			<label for="cb3">
-				cb3: disabled TriStateCheckbox
+				cb3: Disabled TriStateCheckbox
 			</label>
-			<br>
-			<input id="cb4" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='name:"cb4", readOnly:true, checked:true'/>
+			<br/>
+			<input type="checkbox" id="cb4" data-dojo-type="dojox/form/TriStateCheckBox" name="cb4" data-dojo-props='readOnly:true, checked:true'/>
 			<label for="cb4">
-				cb4: readOnly TriStateCheckbox, turned on
+				cb4: ReadOnly TriStateCheckbox, turned on
 			</label>
-			<br>
-			<input id="cb5" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='name:"cb5", value:"", onClick:function(){ console.log("clicked cb5"); }'/>
+			<br/>
+			<input type="checkbox" id="cb5" data-dojo-type="dojox/form/TriStateCheckBox" name="cb5" value="" data-dojo-props='onClick:function(){ console.log("clicked cb5"); }'/>
 			<label for="cb5">
-				cb5: normal TriStateCheckbox, with specified value="", clicking generates console log messages
+				cb5: Standard TriStateCheckbox, with specified value="", clicking generates console log messages
 			</label>
-			<button type=button onclick="alert(dijit.byId('cb5').get('value'));">
+			<button data-dojo-type="dijit/form/Button" onclick="alert(dijit.byId('cb5').get('value'));">
 				get('value')
 			</button>
-			<br>
-			<input id="cb6" type="text"/>
+			<br/>
+			<input type="checkbox" id="cb6" type="text"/>
 			<label for="cb6">
-				cb6: instantiated from script
+				cb6: Instantiated from script
 			</label>
-			<br>
-			<input id="cb7" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='onChange:reportValueChanged, name:"cb7" '/>
+			<br/>
+			<input type="checkbox" id="cb7" data-dojo-type="dojox/form/TriStateCheckBox" name="cb7" data-dojo-props="onChange:reportValueChanged"/>
 			<label for="cb7">
-				cb7: normal TriStateCheckbox.
+				cb7: Standard TriStateCheckbox.
 			</label>
-			<input type="button" onclick='dijit.byId("cb7").set("disabled",true);' value="disable" />
-			<input type="button" onclick='dijit.byId("cb7").set("disabled",false);' value="enable" />
-			<input type="button" onclick='dijit.byId("cb7").set("value", "fish");' value='set value to "fish"' />
-			<input type="button" onclick='dijit.byId("cb7").reset();dijit.byId("cb7").set("checked", true);' value='Reset value+checked' />
+			<button type="button" data-dojo-type="dijit/form/Button">
+				<span>disable</span>
+				<script type="dojo/on" data-dojo-event="click">
+					registry.byId("cb7").set("disabled", true);
+				</script>
+			</button>
+			<button type="button" data-dojo-type="dijit/form/Button">
+				<span>enable</span>
+				<script type="dojo/on" data-dojo-event="click">
+					registry.byId("cb7").set("disabled",false);
+				</script>
+			</button>
+			<button type="button" data-dojo-type="dijit/form/Button">
+				<span>set value to "fish"</span>
+				<script type="dojo/on" data-dojo-event="click">
+					registry.byId("cb7").set("value", "fish");
+				</script>
+			</button>
+			<button type="button" data-dojo-type="dijit/form/Button">
+				<span>Reset value+checked</span>
+				<script type="dojo/on" data-dojo-event="click">
+					registry.byId("cb7").reset();
+					regisrty.byId("cb7").set("checked", true);
+				</script>
+			</button>
 			<span>"onChange" handler displays 'value': [<span id="onvaluechangedoutput"></span>]</span>
-			<br>
-			<input id="cb8" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='onChange:reportValueChanged2, name:"cb8", values:["Done", "Half done"]'/>
+			<br/>
+			<h2>Customized TriStateCheckbox</h2>
+			<input type="checkbox" id="cb8" data-dojo-type="dojox/form/TriStateCheckBox" name="cb8" data-dojo-props='onChange:reportValueChanged2, values:["Done", "Half done"]'/>
 			<label for="cb8">
-				cb8: normal TriStateCheckbox, with specified values=["Done", "Half done"].
+				cb8: TriStateCheckbox with specified values=["Done", "Half done"].
 			</label>
 			<span>"onChange" handler displays 'value': [<span id="onvaluechangedoutput2"></span>]</span>
-			<br>
-			<input id="cb9" data-dojo-id="cb9" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='name:"cb9", states:["mixed", true, false]'/>
+			<br/>
+			<input type="checkbox" id="cb9" data-dojo-id="cb9" data-dojo-type="dojox/form/TriStateCheckBox" name="cb9" data-dojo-props='states:["mixed", true, false]'/>
 			<label for="cb9">
 				cb9: TriStateCheckbox with customized states cycle: ["mixed", true, false]
 			</label>
-			<br>
-			<input id="cb10" data-dojo-id="cb10" data-dojo-type="dojox.form.TriStateCheckBox" data-dojo-props='name:"cb10", states:[true, false]'/>
+			<br/>
+			<input type="checkbox" id="cb10" data-dojo-id="cb10" data-dojo-type="dojox/form/TriStateCheckBox" name="cb10" data-dojo-props="states:[true, false]"/>
 			<label for="cb10">
 				cb10: TriStateCheckbox with customized states cycle: [true, false]
 			</label>
-			<br>
-			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", value:"Submit"'>
+			<br/>
+			<input type="checkbox" id="cb11" name="cb11" />
+			<label for="cb11">
+				cb11: TriStateCheckBox created programatically with a value of "mixed"
+			</label>
+			<br/>
+			<button type="submit" data-dojo-type="dijit/form/Button" value="Submit">
 				Submit
 			</button>
-			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset"'>
+			<button type="reset" data-dojo-type="dijit/form/Button">
 				HTML Reset
 			</button>
 		</form>
-		</div>
-		<span>actual submitted values: <span id="submitoutput"></span></span>
+		<br/>
+		<span>Actual submitted values: <span id="submitoutput"></span></span>
 		<iframe name="formSubmitIframe" src="about:blank" onload="if(this.values)submittedValues(this.values)" style="display:none;"></iframe>
 	</body>
 </html>
diff --git a/dojox/form/tests/test_Uploader.html b/dojox/form/tests/test_Uploader.html
index f621a4d..dcad4ca 100644
--- a/dojox/form/tests/test_Uploader.html
+++ b/dojox/form/tests/test_Uploader.html
@@ -88,53 +88,67 @@
 		}
 	</style>
 	<script>
-		djConfig = {
-			parseOnLoad:true,
+		dojoConfig = {
+			async:1,
 			isDebug:true
 		}
 	</script>
 	<script src="../../../dojo/dojo.js"></script>
 	<script>
-		dojo.require("dojo.parser");
-		dojo.require("dojox.form.Uploader");
-		dojo.require("dojox.form.uploader.FileList");
-		dojo.require("dijit.form.Button");
-		dojo.require("dojox.form.uploader.plugins.Flash");
+		require([
+			'dojo/_base/connect',
+			'dojo/_base/array',
+			'dojo/dom',
+			'dojo/dom-construct',
+			'dijit/registry',
+			'dojo/parser',
+			'dojo/domReady!',
+			'dijit/form/Button',
+			'dojox/form/Uploader',
+			'dojox/form/uploader/FileList'
+		],
+		function(cn, arrayUtil, dom, domConst, registry, parser){
 
-		var handleUpload = function(upl, node){
-			dojo.connect(upl, "onComplete", function(dataArray){
-				dojo.forEach(dojo.isArray(dataArray)?dataArray:[dataArray], function(file){
-					console.log("display:", file)
+			parser.parse();
 
-					var div = dojo.create('div', {className:'thumb'});
-					var span = dojo.create('span', {className:'thumbbk'}, div);
-					var img = dojo.create('img', {src:file.file}, span);
-					node.appendChild(div);
-				});
-			});
-		},
-		handleDnD = function(domnode, uploader){
-			if(uploader.addDropTarget && uploader.uploadType=='html5'){
-				dojo.create('div',{innerHTML:'Drag and Drop files to this fieldset'}, domnode,'last');
-				uploader.addDropTarget(domnode);
-			}
-		}
-
-		dojo.addOnLoad(function(){
-			var uploader=dijit.byId("uploader"), uploader2=dijit.byId("uploader2");
-			dojo.connect(dijit.byId("remBtn"), "onClick", uploader, "reset");
-			dojo.connect(dijit.byId("remBtn2"), "onClick", uploader2, "reset");
-			handleUpload(uploader, dojo.byId('colImages'));
-			handleUpload(uploader2, dojo.byId('colImages'));
+			var
+				uploader=registry.byId("uploader"),
+				uploader2=registry.byId("uploader2"),
+				
+				handleUpload = function(upl, node){
+					cn.connect(upl, "onComplete", function(dataArray){
+						arrayUtil.forEach(dojo.isArray(dataArray)?dataArray:[dataArray], function(file){
+							console.log("display:", file)
+	
+							var div = dojo.create('div', {className:'thumb'});
+							var span = dojo.create('span', {className:'thumbbk'}, div);
+							var img = dojo.create('img', {src:file.file}, span);
+							node.appendChild(div);
+						});
+					});
+				},
+				handleDnD = function(domnode, uploader){
+					if(uploader.addDropTarget && uploader.uploadType=='html5'){
+						domConst.create('div',{innerHTML:'Drag and Drop files to this fieldset'}, domnode,'last');
+						uploader.addDropTarget(domnode);
+					}
+				};
+			
+			cn.connect(registry.byId("remBtn"), "onClick", uploader, "reset");
+			cn.connect(registry.byId("remBtn2"), "onClick", uploader2, "reset");
+			handleUpload(uploader, dom.byId('colImages'));
+			handleUpload(uploader2, dom.byId('colImages'));
 			if(require.has('file-multiple')){
 				handleDnD(uploader.domNode.parentNode, uploader);
 				handleDnD(uploader2.domNode.parentNode, uploader2);
 			}
 		});
+
+
 	</script>
 </head>
 <body class="claro">
-    <h1>Test dojox.form.Uploader</h1>
+    <h1>Test dojox/form/Uploader</h1>
 	<p style="font-size:14px; border:2px solid #ff0000; padding:3px;">
 		<strong>NOTE:</strong> This test does upload,
 		but the server scripts are renamed to <code>tests/UploadFile.php.<strong>disabled</strong></code> and
@@ -142,36 +156,36 @@
 		You should rename these files (removing <code>.disabled</code>) in your local copy to conduct tests.
 	</p>
 	<p class="flash">
-		The Flash plugin will use a SWF to upload in non-HTML5 browsers. All other browsers will use the HTML5 plugin,
+		The Flash feature will use a SWF to upload in non-HTML5 browsers. All other browsers will use the HTML5 plugin,
 		unless <code>force="flash"</code> is used, then Flash will be used in all browsers. <code>force="flash"</code>
 		is provided because Flash has some features that HTML5 does not yet have. But it is still not
 		recommended because of the many problems that Firefox and Webkit have with the Flash plugin.
 	</p>
-	<p class="HTML5">When HTML5 plugin is in use, drag & drop of files to the fieldset is supported.</p>
+	<p class="HTML5">When HTML5 feature is in use, drag & drop of files to the fieldset is supported.</p>
 
-	<table class="pageTable">
+	<table class="pageTable" role="presentation">
 		<tr>
 			<td id="colForm">
 				<form method="post" action="UploadFile.php" id="myForm" enctype="multipart/form-data" >
 					<fieldset>
 						<legend>Block Browse Button Form Post Test</legend>
-						<input class="browseButton" name="uploadedfile" multiple="true" type="file" dojoType="dojox.form.Uploader" label="Select Some Files" isDebug="true" id="uploader" />
-						<input type="text" name="album" value="Summer Vacation" />
-						<input type="text" name="year" value="2011" />
-						<input type="button" id="remBtn" label="Clear" dojoType="dijit.form.Button" />
-						<input type="submit" label="Submit" dojoType="dijit.form.Button" />
-						<div id="files" dojoType="dojox.form.uploader.FileList" uploaderId="uploader"></div>
+						<input class="browseButton" data-dojo-props='name:"uploadedfile", multiple:true, force:"html5", label:"Select Some Files", isDebug:true' type="file" data-dojo-type="dojox/form/Uploader" id="uploader"/>
+						<input type="text" name="album" value="Summer Vacation" aria-label="album" />
++						<input type="text" name="year" value="2011" aria-label="year" />
+						<input type="button" id="remBtn" label="Clear" data-dojo-type="dijit/form/Button" />
+						<input type="submit" label="Submit" data-dojo-type="dijit/form/Button" />
+						<div id="files" data-dojo-type="dojox/form/uploader/FileList" data-dojo-props='uploaderId:"uploader"' ></div>
 					</fieldset>
 				</form>
 				<form method="post" action="UploadFile.php" id="myForm2" enctype="multipart/form-data" >
 					<fieldset>
 						<legend>Inline Browse Button Form Post Test</legend>
-						inline control <div data-dojo-type="dojox.form.Uploader" id="uploader2" data-dojo-props="name:'uploadedfile',showInput:'before',isDebug:true">Browse</div>
-						<input type="text" name="album" value="Summer Vacation" />
-						<input type="text" name="year" value="2011" />
-						<input type="button" id="remBtn2" label="Clear" dojoType="dijit.form.Button" />
-						<input type="submit" label="Submit" dojoType="dijit.form.Button" />
-						<div id="files2" dojoType="dojox.form.uploader.FileList" uploaderId="uploader2"></div>
+						inline control <div data-dojo-type="dojox/form/Uploader" id="uploader2" data-dojo-props="name:'uploadedfile',showInput:'before',isDebug:true">Browse</div>
+						<input type="text" name="album" value="Summer Vacation" aria-label="album" />
++						<input type="text" name="year" value="2011" aria-label="year" />
+						<input type="button" id="remBtn2" label="Clear" data-dojo-type="dijit/form/Button" />
+						<input type="submit" label="Submit" data-dojo-type="dijit/form/Button" />
+						<div id="files2" data-dojo-type="dojox/form/uploader/FileList" data-dojo-props='uploaderId:"uploader2"'></div>
 					</fieldset>
 				</form>
 			</td>
@@ -179,5 +193,6 @@
 			</td>
 		</tr>
 	</table>
+	<a href="./images/attach.png" target='_blank'>Link to test #15285</a>
 </body>
 </html>
diff --git a/dojox/form/tests/test_UploaderAll.html b/dojox/form/tests/test_UploaderAll.html
index beb4f8d..89c2b94 100644
--- a/dojox/form/tests/test_UploaderAll.html
+++ b/dojox/form/tests/test_UploaderAll.html
@@ -161,6 +161,7 @@
 	</script>
 </head>
 <body class="claro">
+<div role="main">
     <h1>Test dojox.form.Uploader Flash</h1>
 	<p style="font-size:14px; border:2px solid #ff0000; padding:3px;">
 		<strong>NOTE:</strong> This test does upload,
@@ -193,15 +194,15 @@
 		<a href="test_UploaderAll.html?iframe">IFrame</a>
 		<a href="test_UploaderAll.html?flash">Flash</a>
 	</p>
-	<table class="pageTable">
+	<table class="pageTable" role="presentation">
 		<tr>
 			<td id="colForm">
 				<form method="post" action="UploadFile.php" id="myForm" enctype="multipart/form-data" >
 					<fieldset>
 						<legend>Form Post Test</legend>
 						<input class="browseButton" name="uploadedfile" multiple="true" type="file" dojoType="dojox.form.Uploader" label="Select Some Files" id="uploader">
-						<input type="text" name="album" value="Summer Vacation" />
-						<input type="text" name="year" value="2011" />
+						<input type="text" name="album" value="Summer Vacation" aria-label="album" />
+						<input type="text" name="year" value="2011" aria-label="year" />
 						<input type="button" id="remBtn" label="Clear" dojoType="dijit.form.Button" />
 						<input type="submit" label="Submit" dojoType="dijit.form.Button" />
 						<div id="files" dojoType="dojox.form.uploader.FileList" uploaderId="uploader"></div>
diff --git a/dojox/form/tests/test_Uploader_programmatic.html b/dojox/form/tests/test_Uploader_programmatic.html
new file mode 100644
index 0000000..9733276
--- /dev/null
+++ b/dojox/form/tests/test_Uploader_programmatic.html
@@ -0,0 +1,211 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 5//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+    <title>Test dojox.form.Uploader Programmatic</title>
+	<link href="../../../dijit/themes/dijit.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/Common.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/form/Common.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/Dialog.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/form/Button.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/layout/TabContainer.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/Dialog.css" rel="stylesheet" />
+
+	<link href="../resources/UploaderFileList.css" rel="stylesheet" />
+	<style>
+		@import "../../../dijit/tests/css/dijitTests.css";
+		html, body{
+			font-family:sans-serif;
+		}
+		.browseButton{
+			width:300px;
+			font-weight:bold;
+			margin:10px 0 2px 0;
+		}
+		.dijitTabPane{
+			padding:20px;
+		}
+		form{
+			width:315px;
+			margin-right:10px;
+		}
+		fieldset{
+			text-align:right;
+		}
+		input[type=text]{
+			width:140px;
+		}
+		.dijitButton{
+			margin-top:15px;
+		}
+		.dojoxUploaderFileList{
+			text-align:left;
+			margin-top:10px;
+		}
+		.pageTable{
+			width:100%;
+		}
+		.pageTable td{
+			vertical-align:top;
+		}
+		#colForm{
+			width:330px;
+		}
+		#colImages{
+			padding-top:7px;
+		}
+		.thumb{
+			border:1px solid #ccc;
+			padding:5px;
+			width:123px;
+			background:#eee;
+			float:left;
+			margin:0 5px 5px 0;
+		}
+		.thumbbk{
+			background:#fff;
+			display:block;
+		}
+		.thumb img{
+			border:1px solid #ccc;
+			width:120px;
+		}
+		.form, .html5, .iframe, .flash{
+			display:none;
+		}
+		.Form .form, .HTML5 .html5, .IFrame .iframe, .Flash .flash{
+			display:block;
+		}
+		#dialog p{
+			width:310px;
+		}
+		.claro .attachButton{
+			width:350px;
+			height:60px;
+			border:0;
+		}
+		.claro .attachButton .dijitButton .dijitButtonNode{
+			background-color:#ffffff;
+			background-image:url(images/attach.png);
+			background-position:left top;
+			background-repeat:no-repeat;
+			height:56px;
+			border:0;
+			-moz-box-shadow:0 0 0;
+			-webkit-box-shadow:0 0 0;
+		}
+		.claro .attachButton .dijitButtonHover .dijitButtonNode{
+			background-position:0px -60px;
+		}
+		code{
+			font-family:monospace;
+			white-space:nowrap;
+		}
+	</style>
+	<script>
+		djConfig = {
+			async:1,
+			isDebug:true
+		}
+	</script>
+	<script src="../../../dojo/dojo.js"></script>
+	
+
+</head>
+<body class="claro">
+    <h1>Test dojox.form.Uploader Programmatic</h1>
+
+	<div id="parent"></div>
+
+	<form method="post" action="UploadFile.php" id="myForm" enctype="multipart/form-data" >
+		<input class="browseButton" name="uploadedfile" multiple="false" type="file" dojoType="dojox.form.Uploader" uploadOnSelect="true" label="Upload via Markup" isDebug="true" id="uploader">
+	</form>
+
+	<form method="post" action="UploadFile.php" id="parent" enctype="multipart/form-data" ></form>
+
+	<form method="post" action="UploadFile.php" id="myForm2" enctype="multipart/form-data" >
+		<fieldset>
+			<legend>Form Post Test</legend>
+			<input class="browseButton" name="uploadedfile" multiple="true" type="file" dojoType="dojox.form.Uploader" label="Select Some Files" isDebug="true" id="uploader2">
+			<input type="submit" label="Submit" dojoType="dijit.form.Button" />
+			<div id="files" dojoType="dojox.form.uploader.FileList" uploaderId="uploader2"></div>
+		</fieldset>
+	</form>
+	<div id="skp"></div>
+	<div id="colImages"></div>
+	<script>
+		require(['dojo', 'dojo/parser', 'dijit/form/Button', 'dijit/Dialog', 'dojox/form/Uploader', 'dojox/form/uploader/FileList', 'dojox/form/uploader/plugins/Flash'],
+				function(dojo, parser, Button, Dialog, Uploader, FileList, uFlash){
+					console.log('ready')
+					//parser.parse();
+
+					makeSKP = function(){
+
+						var div = dojo.create('div',{innerHTML:'<p>This dialog will not upload. Only testing that it parses correctly.</p>'});
+						myUploadDialog = new Dialog({
+							title: "Upload Video",
+							style: "width: 400px;height:300px;",
+							content: div
+						});
+						myUploadDialog.show();
+
+						//
+						// IMPORTANT NOTE!
+						// When using the Uploader programmatically, you cannot use the ref
+						// from the require() - you must use the global. In other words:
+						//
+						// require(['dojox/form/Uploader'], function(Uploader){
+						// 	myUploader = Uploader(...);
+						// })
+						// ... will NOT work!!
+						// You must use:
+						// require(['dojox/form/Uploader'], function(Uploader){
+						//	 myUploader = new dojox.form.Uploader(...);
+						// })
+
+
+						myUploader = new dojox.form.Uploader({
+							label: 'Prog Browse',
+							url:'abc.php',
+							id:"programmatic",
+							multiple: true
+						});
+						div.appendChild(myUploader.domNode);
+						myUploader.startup();
+						var b = new Button({label:"Upload"});
+
+						div.appendChild(b.domNode);
+
+						dojo.connect(b, "onClick", function(){
+							console.log(myUploader.upload)
+							myUploader.upload();
+						});
+					}
+
+					var handleUpload = function(upl, node){
+
+						dojo.connect(upl, "onComplete", function(dataArray){
+
+							dojo.forEach(dataArray, function(file){
+								console.log("display:", file)
+
+								var div = dojo.create('div', {className:'thumb'});
+								var span = dojo.create('span', {className:'thumbbk'}, div);
+								var img = dojo.create('img', {src:file.file}, span);
+								node.appendChild(div);
+							});
+						});
+					}
+					var u = new dojox.form.Uploader({label:"Programmatic Uploader", multiple:true, uploadOnSelect:true, url:"UploadFile.php"});
+					dojo.byId("parentdiv").appendChild(u.domNode);
+					u.startup();
+
+					handleUpload(u, dojo.byId('colImages'));
+					handleUpload(dijit.byId("uploader"), dojo.byId('colImages'));
+					handleUpload(dijit.byId("uploader2"), dojo.byId('colImages'));
+
+					makeSKP();
+
+				});
+	</script>
+</body>
+</html>
diff --git a/dojox/form/uploader/Base.js b/dojox/form/uploader/Base.js
deleted file mode 100644
index 53f81a9..0000000
--- a/dojox/form/uploader/Base.js
+++ /dev/null
@@ -1,125 +0,0 @@
-define([
-	"dojo/dom-form",
-	"dojo/dom-style",
-	"dojo/dom-construct",
-	"dojo/dom-attr",
-	"dojo/has",
-	"dojo/_base/declare",
-	"dojo/_base/event",
-	"dijit/_Widget",
-	"dijit/_TemplatedMixin",
-	"dijit/_WidgetsInTemplateMixin"
-],function(domForm, domStyle, domConstruct, domAttr, has, declare, event, Widget, TemplatedMixin, WidgetsInTemplateMixin){
-
-has.add('FormData', function(){return !!window.FormData;});
-has.add('xhr-sendAsBinary', function(){var xhr=window.XMLHttpRequest && new window.XMLHttpRequest(); return xhr && !!xhr.sendAsBinary;});
-has.add('file-multiple', function(){return !!({'true':1,'false':1}[domAttr.get(document.createElement('input',{type:"file"}), 'multiple')]);});
-
-	/*=====
-		Widget = dijit._Widget;
-		TemplatedMixin = dijit._TemplatedMixin;
-		WidgetsInTemplateMixin = dijit._WidgetsInTemplateMixin;
-	=====*/
-return declare("dojox.form.uploader.Base", [Widget, TemplatedMixin, WidgetsInTemplateMixin], {
-	//
-	// Version: 1.6
-	//
-	// summary:
-	// 		The Base class used for dojox.form.Uploader and dojox.form.uploader.FileList.
-	//
-	// 	description:
-	// 		Should not be used as a standalone. To be mixed in with other classes.
-	//
-
-	getForm: function(){
-		// summary:
-		// 		Finds the parent form of the Uploader, if it exists.
-		//
-		if(!this.form){
-			var n = this.domNode;
-			while(n && n.tagName && n !== document.body){
-				if(n.tagName.toLowerCase() == "form"){
-					this.form = n;
-					break;
-				}
-				n = n.parentNode;
-			}
-		}
-		return this.form // Node;
-	},
-
-	getUrl: function(){
-		// summary:
-		// 		Finds the URL to upload to, whether it be the action in the parent form, this.url or
-		// 		this.uploadUrl
-		//
-		if(this.uploadUrl) this.url = this.uploadUrl;
-		if(this.url) return this.url;
-		if(this.getForm()) this.url = this.form.action;
-		return this.url; // String
-	},
-
-
-	connectForm: function(){
-		// summary:
-		//		Internal. Connects to form if there is one.
-		//
-		this.url = this.getUrl();
-		if(!this._fcon && !!this.getForm()){
-			this._fcon = true;
-			this.connect(this.form, "onsubmit", function(evt){
-				event.stop(evt);
-				this.submit(this.form);
-			});
-		}
-	},
-
-	supports: function(what){
-		//	summary:
-		// 		Does feature testing for uploader capabilities. (No browser sniffing - yay)
-		//
-		switch(what){
-			case "multiple":
-				if(this.force == "flash" || this.force == "iframe") return false;
-				return has("file-multiple");
-			case "FormData":
-				return has(what);
-			case "sendAsBinary":
-				return has("xhr-sendAsBinary");
-		}
-		return false; // Boolean
-	},
-	getMimeType: function(){
-		//	summary:
-		//		Returns the mime type that should be used in an HTML5 upload form. Return result
-		//		may change as the current use is very generic.
-		//
-		return "application/octet-stream"; //image/gif
-	},
-	getFileType: function(/* String */name){
-		// summary:
-		// 		Gets the extension of a file
-		return name.substring(name.lastIndexOf(".")+1).toUpperCase(); // String
-	},
-	convertBytes: function(bytes){
-		// summary:
-		// 		Converts bytes. Returns an object with all conversions. The "value" property is
-		// 		considered the most likely desired result.
-		//
-		var kb = Math.round(bytes/1024*100000)/100000;
-		var mb = Math.round(bytes/1048576*100000)/100000;
-		var gb = Math.round(bytes/1073741824*100000)/100000;
-		var value = bytes;
-		if(kb>1) value = kb.toFixed(1)+" kb";
-		if(mb>1) value = mb.toFixed(1)+" mb";
-		if(gb>1) value = gb.toFixed(1)+" gb";
-		return {
-			kb:kb,
-			mb:mb,
-			gb:gb,
-			bytes:bytes,
-			value: value
-		}; // Object
-	}
-});
-});
diff --git a/dojox/form/uploader/FileList.js b/dojox/form/uploader/FileList.js
index 1b4fcf7..d67e854 100644
--- a/dojox/form/uploader/FileList.js
+++ b/dojox/form/uploader/FileList.js
@@ -6,62 +6,48 @@ define([
 	"dojo/_base/lang",
 	"dojo/_base/array",
 	"dijit/_base/manager",
-	"dojox/form/uploader/Base"
-],function(fx, domStyle, domClass, declare, lang, array, manager, formUploaderBase){
-
-	/*=====
-		formUploaderBase = dojox.form.uploader.Base;
-	=====*/
-return declare("dojox.form.uploader.FileList", [formUploaderBase], {
-	//
-	// Version: 1.6
-	//
+	"dojox/form/uploader/_Base",
+	"dojo/text!../resources/UploaderFileList.html"
+],function(fx, domStyle, domClass, declare, lang, arrayUtil, manager, Base, template){
+
+return declare("dojox.form.uploader.FileList", Base, {
 	// summary:
 	//		A simple widget that provides a list of the files currently selected by
-	//		dojox.form.Uploader
-	//
-	//	description:
+	//		dojox/form/Uploader
+	// description:
 	//		There is a required CSS file: resources/UploaderFileList.css.
 	//		This is a very simple widget, and not beautifully styled. It is here mainly for test
 	//		cases, but could very easily be used, extended, modified, or copied.
-	//
-	//	uploaderId: String
+
+	// uploaderId: String
 	//		The id of the dojox.form.Uploader to connect to.
 	uploaderId:"",
-	//	uploader: dojox.form.Uploader
+
+	// uploader: dojox.form.Uploader
 	//		The dojox.form.Uploader to connect to. Use either this property of unploaderId. This
 	//		property is populated if uploaderId is used.
-	//
 	uploader:null,
-	//	headerIndex: String
-	// 		The label for the index column.
-	//
+
+	// headerIndex: String
+	//		The label for the index column.
 	headerIndex:"#",
-	//	headerType: String
-	// 		The label for the file type column.
-	//
+
+	// headerType: String
+	//		The label for the file type column.
 	headerType:"Type",
-	//	headerFilename: String
-	// 		The label for the file name column.
-	//
+
+	// headerFilename: String
+	//		The label for the file name column.
 	headerFilename:"File Name",
-	//	headerFilesize: String
-	// 		The label for the file size column.
-	//
+
+	// headerFilesize: String
+	//		The label for the file size column.
 	headerFilesize:"Size",
 
 	_upCheckCnt:0,
 	rowAmt:0,
 
-	templateString:	'<div class="dojoxUploaderFileList">' +
-						'<div dojoAttachPoint="progressNode" class="dojoxUploaderFileListProgress"><div dojoAttachPoint="percentBarNode" class="dojoxUploaderFileListProgressBar"></div><div dojoAttachPoint="percentTextNode" class="dojoxUploaderFileListPercentText">0%</div></div>' +
-						'<table class="dojoxUploaderFileListTable">'+
-							'<thead><tr class="dojoxUploaderFileListHeader"><th class="dojoxUploaderIndex">${headerIndex}</th><th class="dojoxUploaderIcon">${headerType}</th><th class="dojoxUploaderFileName">${headerFilename}</th><th class="dojoxUploaderFileSize" dojoAttachPoint="sizeHeader">${headerFilesize}</th></tr></thead>'+
-							'<tbody class="dojoxUploaderFileListContent" dojoAttachPoint="listNode">'+
-							'</tbody>'+
-						'</table>'+
-						'<div>'
-						,
+	templateString:template,
 
 	postCreate: function(){
 		this.setUploader();
@@ -72,7 +58,7 @@ return declare("dojox.form.uploader.FileList", [formUploaderBase], {
 		// summary:
 		//		Clears all rows of items. Happens automatically if Uploader is reset, but you
 		//		could call this directly.
-		//
+
 		for(var i=0;i<this.rowAmt;i++){
 			this.listNode.deleteRow(0);
 		}
@@ -82,7 +68,7 @@ return declare("dojox.form.uploader.FileList", [formUploaderBase], {
 	setUploader: function(){
 		// summary:
 		//		Connects to the Uploader based on the uploader or the uploaderId properties.
-		//
+
 		if(!this.uploaderId && !this.uploader){
 			console.warn("uploaderId not passed to UploaderFileList");
 		}else if(this.uploaderId && !this.uploader){
@@ -114,7 +100,7 @@ return declare("dojox.form.uploader.FileList", [formUploaderBase], {
 		}
 	},
 
-	hideProgress: function(/* Boolean */animate){
+	hideProgress: function(/*Boolean*/ animate){
 		var o = animate ? {
 			ani:true,
 			endDisp:"none",
@@ -127,7 +113,7 @@ return declare("dojox.form.uploader.FileList", [formUploaderBase], {
 		this._hideShowProgress(o);
 	},
 
-	showProgress: function(/* Boolean */animate){
+	showProgress: function(/*Boolean*/ animate){
 		var o = animate ? {
 			ani:true,
 			endDisp:"block",
@@ -140,7 +126,7 @@ return declare("dojox.form.uploader.FileList", [formUploaderBase], {
 		this._hideShowProgress(o);
 	},
 
-	_progress: function(/* Object */ customEvent){
+	_progress: function(/*Object*/ customEvent){
 		this.percentTextNode.innerHTML = customEvent.percent;
 		domStyle.set(this.percentBarNode, "width", customEvent.percent);
 	},
@@ -149,7 +135,7 @@ return declare("dojox.form.uploader.FileList", [formUploaderBase], {
 		var node = this.progressNode;
 		var onEnd = function(){
 			domStyle.set(node, "display", o.endDisp);
-		}
+		};
 		if(o.ani){
 			domStyle.set(node, "display", "block");
 			fx.animateProperty({
@@ -170,7 +156,7 @@ return declare("dojox.form.uploader.FileList", [formUploaderBase], {
 
 	_onUploaderChange: function(fileArray){
 		this.reset();
-		array.forEach(fileArray, function(f, i){
+		arrayUtil.forEach(fileArray, function(f, i){
 			this._addRow(i+1, this.getFileType(f.name), f.name, f.size);
 		}, this)
 	},
diff --git a/dojox/form/uploader/_Base.js b/dojox/form/uploader/_Base.js
new file mode 100644
index 0000000..8773f0e
--- /dev/null
+++ b/dojox/form/uploader/_Base.js
@@ -0,0 +1,116 @@
+define([
+	"dojo/dom-form",
+	"dojo/dom-style",
+	"dojo/dom-construct",
+	"dojo/dom-attr",
+	"dojo/has",
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dijit/_Widget",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin"
+],function(domForm, domStyle, domConstruct, domAttr, has, declare, event, Widget, TemplatedMixin, WidgetsInTemplateMixin){
+
+has.add('FormData', function(){return !!window.FormData;});
+has.add('xhr-sendAsBinary', function(){var xhr=window.XMLHttpRequest && new window.XMLHttpRequest(); return xhr && !!xhr.sendAsBinary;});
+has.add('file-multiple', function(){return !!({'true':1,'false':1}[domAttr.get(document.createElement('input',{type:"file"}), 'multiple')]);});
+
+
+return declare("dojox.form.uploader._Base", [Widget, TemplatedMixin, WidgetsInTemplateMixin], {
+	// summary:
+	//		The Base class used for dojox/form/Uploader and dojox/form/uploader/FileList.
+	//
+	//		Should not be used as a standalone. To be mixed in with other classes.
+	//
+	getForm: function(){
+		// summary:
+		//		Finds the parent form of the Uploader, if it exists.
+
+		if(!this.form){
+			var n = this.domNode;
+			while(n && n.tagName && n !== document.body){
+				if(n.tagName.toLowerCase() == "form"){
+					this.form = n;
+					break;
+				}
+				n = n.parentNode;
+			}
+		}
+		return this.form // Node;
+	},
+
+	getUrl: function(){
+		// summary:
+		//		Finds the URL to upload to, whether it be the action in the parent form, this.url or
+		//		this.uploadUrl
+
+		if(this.uploadUrl) this.url = this.uploadUrl;
+		if(this.url) return this.url;
+		if(this.getForm()) this.url = this.form.action;
+		return this.url; // String
+	},
+
+
+	connectForm: function(){
+		// summary:
+		//		Internal. Connects to form if there is one.
+
+		this.url = this.getUrl();
+		if(!this._fcon && !!this.getForm()){
+			this._fcon = true;
+			this.connect(this.form, "onsubmit", function(evt){
+				console.log('SUBMIT')
+				event.stop(evt);
+				this.submit(this.form);
+			});
+		}
+	},
+
+	supports: function(what){
+		// summary:
+		//		Does feature testing for uploader capabilities. (No browser sniffing - yay)
+
+		switch(what){
+			case "multiple":
+				if(this.force == "flash" || this.force == "iframe") return false;
+				return has("file-multiple");
+			case "FormData":
+				return has(what);
+			case "sendAsBinary":
+				return has("xhr-sendAsBinary");
+		}
+		return false; // Boolean
+	},
+	getMimeType: function(){
+		// summary:
+		//		Returns the mime type that should be used in an HTML5 upload form. Return result
+		//		may change as the current use is very generic.
+		return "application/octet-stream"; //image/gif
+	},
+	getFileType: function(/*String*/ name){
+		// summary:
+		//		Gets the extension of a file
+		return name.substring(name.lastIndexOf(".")+1).toUpperCase(); // String
+	},
+	convertBytes: function(bytes){
+		// summary:
+		//		Converts bytes. Returns an object with all conversions. The "value" property is
+		//		considered the most likely desired result.
+
+		var kb = Math.round(bytes/1024*100000)/100000;
+		var mb = Math.round(bytes/1048576*100000)/100000;
+		var gb = Math.round(bytes/1073741824*100000)/100000;
+		var value = bytes;
+		if(kb>1) value = kb.toFixed(1)+" kb";
+		if(mb>1) value = mb.toFixed(1)+" mb";
+		if(gb>1) value = gb.toFixed(1)+" gb";
+		return {
+			kb:kb,
+			mb:mb,
+			gb:gb,
+			bytes:bytes,
+			value: value
+		}; // Object
+	}
+});
+});
diff --git a/dojox/form/uploader/_Flash.js b/dojox/form/uploader/_Flash.js
new file mode 100644
index 0000000..31c9849
--- /dev/null
+++ b/dojox/form/uploader/_Flash.js
@@ -0,0 +1,306 @@
+define([
+	"dojo/dom-form",
+	"dojo/dom-style",
+	"dojo/dom-construct",
+	"dojo/dom-attr",
+	"dojo/_base/declare",
+	"dojo/_base/config",
+	"dojo/_base/connect",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojox/embed/Flash"
+],function(domForm, domStyle, domConstruct, domAttr, declare, config, connect, lang, arrayUtil, embedFlash){
+
+
+	return declare("dojox.form.uploader._Flash", [], {
+		// summary:
+		//		A mixin for dojox/form/Uploader that utilizes a Flash SWF for handling to upload in IE.
+		//		All other browsers will use the HTML5 plugin, unless force="flash" is used, then Flash
+		//		will be used in all browsers. force="flash"	is provided because Flash has some features
+		//		that HTML5 does not yet have. But it is still not recommended because of the many problems
+		//		that Firefox and Webkit have with the Flash plugin.
+		//
+		// description:
+		//		All properties and methods listed here are specific to the Flash version only.
+		//
+		//
+		// swfPath:String
+		//		Path to SWF. Can be overwritten or provided in djConfig.
+		swfPath:config.uploaderPath || require.toUrl("dojox/form/resources/uploader.swf"),
+
+		// preventCache: Boolean
+		//		If true, then flash request is sent with a value that changes with each request (timestamp)
+		preventCache: true,
+	
+		// skipServerCheck: Boolean
+		//		If true, will not verify that the server was sent the correct format.
+		//		This can be safely set to true. The purpose of the server side check
+		//		is mainly to show the dev if they've implemented the different returns
+		//		correctly.
+		skipServerCheck:true,
+	
+		// serverTimeout:Number (milliseconds)
+		//		The amount of time given to the uploaded file
+		//		to wait for a server response. After this amount
+		//		of time, the onComplete is fired but with a 'server timeout'
+		//		error in the returned item.
+		serverTimeout: 2000,
+	
+		// isDebug: Boolean
+		//		If true, outputs traces from the SWF to console. What exactly gets passed
+		//		is very relative, and depends upon what traces have been left in the DEFT SWF.
+		isDebug:false,
+	
+		// devMode: Boolean.
+		//		Re-implemented. devMode increases the logging, adding style tracing from the SWF.
+		devMode:false,
+	
+		// deferredUploading: Number (1 - X)
+		//		(Flash only) throttles the upload to a certain amount of files at a time.
+		//		By default, Flash uploads file one at a time to the server, but in parallel.
+		//		Firefox will try to queue all files at once, leading to problems. Set this
+		//		to the amount to upload in parallel at a time.
+		//		Generally, 1 should work fine, but you can experiment with queuing more than
+		//		one at a time.
+		//		This is of course ignored if selectMultipleFiles equals false.
+		deferredUploading:0,
+	
+		postMixInProperties: function(){
+			if(this.uploadType === 'flash'){
+				this._files = [];
+				this._fileMap = {};
+				this._createInput = this._createFlashUploader;
+				this.getFileList = this.getFlashFileList;
+				this.reset = this.flashReset;
+				this.upload = this.uploadFlash;
+				this.fieldname = "flashUploadFiles"; ///////////////////// this.name
+			}
+			this.inherited(arguments);
+		},
+	
+		/*************************
+		 *	   Public Events	 *
+		 *************************/
+	
+		onReady: function(/*dojox/form/FileUploader*/ uploader){
+			// summary:
+			//		Stub - Fired when embedFlash has created the
+			//		Flash object, but it has not necessarilly finished
+			//		downloading, and is ready to be communicated with.
+		},
+	
+		onLoad: function(/*dojox/form/FileUploader*/ uploader){
+			// summary:
+			//		Stub - SWF has been downloaded 100%.
+		},
+	
+		onFileChange: function(fileArray){
+			// summary:
+			//		Stub - Flash-specific event. Fires on each selection of files
+			//		and only provides the files selected on that event - not all files
+			//		selected, as with HTML5
+		},
+	
+		onFileProgress: function(fileArray){
+			// summary:
+			//		Stub - Flash-specific event. Fires on progress of upload
+			//		and only provides a file-specific event
+		},
+	
+	
+		/*************************
+		 *	   Public Methods	 *
+		 *************************/
+	
+		getFlashFileList: function(){
+			// summary:
+			//		Returns list of currently selected files
+			return this._files; // Array
+		},
+	
+		flashReset: function(){
+			this.flashMovie.reset();
+			this._files = [];
+			this._fileMap = {};
+		},
+	
+		/*************************
+		 *	   Private Methods	 *
+		 *************************/
+	
+		uploadFlash: function(/*Object ? */ formData){
+			// summary:
+			//		Uploads selected files. Alias "upload()" should be used instead.
+			// tags:
+			//		private
+			this.onBegin(this.getFileList());
+			formData = formData || {};
+			formData.returnType = "F";
+			formData.uploadType = this.uploadType;
+			console.log('flas upload', formData);
+			this.flashMovie.doUpload(formData);
+		},
+	
+		_change: function(fileArray){
+			this._files = this._files.concat(fileArray);
+			arrayUtil.forEach(fileArray, function(f){
+				f.bytesLoaded = 0;
+				f.bytesTotal = f.size;
+				this._fileMap[f.name+"_"+f.size] = f;
+			}, this);
+			this.onChange(this._files);
+			this.onFileChange(fileArray);
+		},
+		_complete: function(fileArray){
+			var o = this._getCustomEvent();
+			o.type = "load";
+			this.onComplete(fileArray);
+		},
+		_progress: function(f){
+			this._fileMap[f.name+"_"+f.bytesTotal].bytesLoaded = f.bytesLoaded;
+			var o = this._getCustomEvent();
+			this.onFileProgress(f);
+			this.onProgress(o);
+		},
+		_error: function(err){
+			this.onError(err);
+		},
+		_onFlashBlur: function(fileArray){
+			//console.log("UploaderFlash._onFlashBlur");
+		},
+	
+		_getCustomEvent: function(){
+			var o = {
+				bytesLoaded:0,
+				bytesTotal:0,
+				type:"progress",
+				timeStamp:new Date().getTime()
+			};
+	
+	
+			for(var nm in this._fileMap){
+				o.bytesTotal += this._fileMap[nm].bytesTotal;
+				o.bytesLoaded += this._fileMap[nm].bytesLoaded;
+			}
+			o.decimal = o.bytesLoaded / o.bytesTotal;
+			o.percent = Math.ceil((o.bytesLoaded / o.bytesTotal)*100)+"%";
+			return o; // Object
+		},
+	
+		_connectFlash: function(){
+			// summary:
+			//		Subscribing to published topics coming from the
+			//		Flash uploader.
+	
+			// Sacrificing some readability for compactness. this.id
+			// will be on the beginning of the topic, so more than
+			// one uploader can be on a page and can have unique calls.
+	
+			this._subs = [];
+			this._cons = [];
+	
+			var doSub = lang.hitch(this, function(s, funcStr){
+				this._subs.push(connect.subscribe(this.id + s, this, funcStr));
+			});
+	
+			doSub("/filesSelected", "_change");
+			doSub("/filesUploaded", "_complete");
+			doSub("/filesProgress", "_progress");
+			doSub("/filesError", "_error");
+			doSub("/filesCanceled", "onCancel");
+			doSub("/stageBlur", "_onFlashBlur");
+	
+			this.connect(this.domNode, "focus", function(){
+				// TODO: some kind of indicator that the Flash button is in focus
+				this.flashMovie.focus();
+				this.flashMovie.doFocus();
+			});
+			if(this.tabIndex>=0){
+				domAttr.set(this.domNode, "tabIndex", this.tabIndex);
+			}
+		},
+		_createFlashUploader: function(){
+			// summary:
+			//		Internal. Creates Flash Uploader
+	
+			var w = this.btnSize.w;
+			var h = this.btnSize.h;
+			if(!w){
+				// FIXME: Commit this
+				setTimeout(dojo.hitch(this, function(){
+					this._getButtonStyle(this.domNode);
+					this._createFlashUploader();
+				}), 200);
+				return;
+			}
+			var url = this.getUrl();
+			if(url){
+				if(url.toLowerCase().indexOf("http")<0 && url.indexOf("/")!=0){
+					// Appears to be a relative path. Attempt to
+					// convert it to absolute, so it will better
+					// target the SWF.
+					var loc = window.location.href.split("/");
+					loc.pop();
+					loc = loc.join("/")+"/";
+					url = loc+url;
+				}
+			}else{
+				console.warn("Warning: no uploadUrl provided.");
+			}
+	
+			this.inputNode = domConstruct.create("div", {className:"dojoxFlashNode"}, this.domNode, "first");
+			domStyle.set(this.inputNode, {
+				position:"absolute",
+				top:"-2px",
+				width:w+"px",
+				height:h+"px",
+				opacity:0
+			});
+	
+	
+	
+			var args = {
+				expressInstall:true,
+				path: (this.swfPath.uri || this.swfPath) + ((this.preventCache)?("?cb_" + (new Date().getTime())):""),
+				width: w,
+				height: h,
+				allowScriptAccess:"always",
+				allowNetworking:"all",
+				vars: {
+					uploadDataFieldName: this.flashFieldName || this.name+"Flash",
+					uploadUrl: url,
+					uploadOnSelect: this.uploadOnSelect,
+					deferredUploading:this.deferredUploading || 0,
+					selectMultipleFiles: this.multiple,
+					id: this.id,
+					isDebug: this.isDebug,
+					noReturnCheck: this.skipServerCheck,
+					serverTimeout:this.serverTimeout
+				},
+				params: {
+					scale:"noscale",
+					//wmode:"transparent",
+					wmode:"opaque",
+					allowScriptAccess:"always",
+					allowNetworking:"all"
+				}
+	
+			};
+	
+			this.flashObject = new embedFlash(args, this.inputNode);
+			this.flashObject.onError = lang.hitch(function(msg){
+				console.error("Flash Error: " + msg);
+			});
+			this.flashObject.onReady = lang.hitch(this, function(){
+				this.onReady(this);
+			});
+			this.flashObject.onLoad = lang.hitch(this, function(mov){
+				this.flashMovie = mov;
+				this.flashReady = true;
+	
+				this.onLoad(this);
+			});
+			this._connectFlash();
+		}
+	});
+});
diff --git a/dojox/form/uploader/_HTML5.js b/dojox/form/uploader/_HTML5.js
new file mode 100644
index 0000000..bfd3903
--- /dev/null
+++ b/dojox/form/uploader/_HTML5.js
@@ -0,0 +1,165 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo"
+],function(declare, lang, arrayUtil, dojo){
+
+	return declare("dojox.form.uploader._HTML5", [], {
+		// summary:
+		//		A mixin for dojox/form/Uploader that adds HTML5 multiple-file upload capabilities and
+		//		progress events.
+		//
+		// description:
+		//		Note that this does not add these capabilities to browsers that don't support them.
+		//		For IE8 or older browsers, _IFrame or _Flash mixins will be used.
+		//
+		
+		// debug message:
+		errMsg:"Error uploading files. Try checking permissions",
+	
+		// Overwrites "form" and could possibly be overwritten again by iframe or flash plugin.
+		uploadType:"html5",
+		
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			if(this.uploadType === "html5"){ }
+		},
+	
+		postCreate: function(){
+			this.connectForm();
+			this.inherited(arguments);
+			if(this.uploadOnSelect){
+				this.connect(this, "onChange", function(data){
+					this.upload(data[0]);
+				});
+			}
+		},
+	
+		_drop: function(e){
+			dojo.stopEvent(e);
+			var dt = e.dataTransfer;
+			this._files = dt.files;
+			this.onChange(this.getFileList());
+		},
+		/*************************
+		 *	   Public Methods	 *
+		 *************************/
+	
+		upload: function(/*Object ? */ formData){
+			// summary:
+			//		See: dojox.form.Uploader.upload
+				
+			this.onBegin(this.getFileList());
+			this.uploadWithFormData(formData);
+		},
+	
+		addDropTarget: function(node, /*Boolean?*/ onlyConnectDrop){
+			// summary:
+			//		Add a dom node which will act as the drop target area so user
+			//		can drop files to this node.
+			// description:
+			//		If onlyConnectDrop is true, dragenter/dragover/dragleave events
+			//		won't be connected to dojo.stopEvent, and they need to be
+			//		canceled by user code to allow DnD files to happen.
+			//		This API is only available in HTML5 plugin (only HTML5 allows
+			//		DnD files).
+			if(!onlyConnectDrop){
+				this.connect(node, 'dragenter', dojo.stopEvent);
+				this.connect(node, 'dragover', dojo.stopEvent);
+				this.connect(node, 'dragleave', dojo.stopEvent);
+			}
+			this.connect(node, 'drop', '_drop');
+		},
+		
+		uploadWithFormData: function(/*Object*/ data){
+			// summary:
+			//		Used with WebKit and Firefox 4+
+			//		Upload files using the much friendlier FormData browser object.
+			// tags:
+			//		private
+	
+			if(!this.getUrl()){
+				console.error("No upload url found.", this); return;
+			}
+			var fd = new FormData(), fieldName=this._getFileFieldName();
+			arrayUtil.forEach(this._files, function(f, i){
+				fd.append(fieldName, f);
+			}, this);
+	
+			if(data){
+				data.uploadType = this.uploadType;
+				for(var nm in data){
+					fd.append(nm, data[nm]);
+				}
+			}
+	
+			var xhr = this.createXhr();
+			xhr.send(fd);
+		},
+	
+		_xhrProgress: function(evt){
+			if(evt.lengthComputable){
+				var o = {
+					bytesLoaded:evt.loaded,
+					bytesTotal:evt.total,
+					type:evt.type,
+					timeStamp:evt.timeStamp
+				};
+				if(evt.type == "load"){
+					// 100%
+					o.percent = "100%";
+					o.decimal = 1;
+				}else{
+					o.decimal = evt.loaded / evt.total;
+					o.percent = Math.ceil((evt.loaded / evt.total)*100)+"%";
+				}
+				this.onProgress(o);
+			}
+		},
+	
+		createXhr: function(){
+			var xhr = new XMLHttpRequest();
+			var timer;
+			xhr.upload.addEventListener("progress", lang.hitch(this, "_xhrProgress"), false);
+			xhr.addEventListener("load", lang.hitch(this, "_xhrProgress"), false);
+			xhr.addEventListener("error", lang.hitch(this, function(evt){
+				this.onError(evt);
+				clearInterval(timer);
+			}), false);
+			xhr.addEventListener("abort", lang.hitch(this, function(evt){
+				this.onAbort(evt);
+				clearInterval(timer);
+			}), false);
+			xhr.onreadystatechange = lang.hitch(this, function(){
+				if(xhr.readyState === 4){
+	//				console.info("COMPLETE")
+					clearInterval(timer);
+					try{
+						this.onComplete(JSON.parse(xhr.responseText.replace(/^\{\}&&/,'')));
+					}catch(e){
+						var msg = "Error parsing server result:";
+						console.error(msg, e);
+						console.error(xhr.responseText);
+						this.onError(msg, e);
+					}
+				}
+			});
+			xhr.open("POST", this.getUrl());
+			xhr.setRequestHeader("Accept","application/json");
+			
+			timer = setInterval(lang.hitch(this, function(){
+				try{
+					if(typeof(xhr.statusText)){} // accessing this error throws an error. Awesomeness.
+				}catch(e){
+					//this.onError("Error uploading file."); // not always an error.
+					clearInterval(timer);
+				}
+			}),250);
+	
+			return xhr;
+		}
+	
+	});
+
+});
diff --git a/dojox/form/uploader/_IFrame.js b/dojox/form/uploader/_IFrame.js
new file mode 100644
index 0000000..d44b954
--- /dev/null
+++ b/dojox/form/uploader/_IFrame.js
@@ -0,0 +1,85 @@
+define([
+	"dojo/query",
+	"dojo/dom-construct",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/dom-form",
+	"dojo/request/iframe"
+],function(query, domConstruct, declare, lang, arrayUtil, domForm, request){
+	
+
+	return declare("dojox.form.uploader._IFrame", [], {
+		// summary:
+		//		A mixin for dojox/form/Uploader that adds Ajax upload capabilities via an iframe.
+		//
+		// description:
+		//		Only supported by IE, due to the specific iFrame hack used.  Progress events are not
+		//		supported.
+		//		
+		//
+	
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			if(this.uploadType === "iframe"){
+				this.uploadType = "iframe";
+				this.upload = this.uploadIFrame;
+			}
+		},
+	
+		uploadIFrame: function(data){
+			// summary:
+			//		Internal. You could use this, but you should use upload() or submit();
+			//		which can also handle the post data.
+	
+			var
+				formObject = {},
+				sendForm,
+				form = this.getForm(),
+				url = this.getUrl(),
+				self = this;
+			data = data || {};
+			data.uploadType = this.uploadType;
+			
+			// create a temp form for which to send data
+			//enctype can't be changed once a form element is created
+			sendForm = domConstruct.place('<form enctype="multipart/form-data" method="post"></form>', this.domNode);
+			arrayUtil.forEach(this._inputs, function(n, i){
+				// don't send blank inputs
+				if(n.value !== ''){
+					sendForm.appendChild(n);
+					formObject[n.name] = n.value;
+				}
+			}, this);
+			
+			
+			// add any extra data as form inputs		
+			if(data){
+				//formObject = domForm.toObject(form);
+				for(nm in data){
+					if(formObject[nm] === undefined){
+						domConstruct.create('input', {name:nm, value:data[nm], type:'hidden'}, sendForm);
+					}
+				}
+			}
+	
+			
+			request.post(url, {
+				form: sendForm,
+				handleAs: "json",
+				content: data
+			}).then(function(result){
+				domConstruct.destroy(sendForm);
+				if(data["ERROR"] || data["error"]){
+					self.onError(result);
+				}else{
+					self.onComplete(result);
+				}
+			}, function(err){
+				console.error('error parsing server result', err);
+				domConstruct.destroy(sendForm); 
+				self.onError(err);
+			});
+		}
+	});
+});
diff --git a/dojox/form/uploader/plugins/Flash.js b/dojox/form/uploader/plugins/Flash.js
index 4b31aff..d0c3c58 100644
--- a/dojox/form/uploader/plugins/Flash.js
+++ b/dojox/form/uploader/plugins/Flash.js
@@ -1,306 +1,4 @@
-define([
-	"dojo/dom-form",
-	"dojo/dom-style",
-	"dojo/dom-construct",
-	"dojo/dom-attr",
-	"dojo/_base/declare",
-	"dojo/_base/config",
-	"dojo/_base/connect",
-	"dojo/_base/lang",
-	"dojo/_base/array",
-	"dojox/form/uploader/plugins/HTML5",
-	"dojox/embed/Flash"
-],function(domForm, domStyle, domConstruct, domAttr, declare, config, connect, lang, array, formUploaderPluginsHTML5, embedFlash){
-
-
-var pluginsFlash = declare("dojox.form.uploader.plugins.Flash", [], {
-	//
-	// Version: 1.6
-	//
-	// summary:
-	//		A plugin for dojox.form.Uploader that utilizes a Flash SWF for handling to upload in IE.
-	//		All other browsers will use the HTML5 plugin, unless force="flash" is used, then Flash
-	//		will be used in all browsers. force="flash"	is provided because Flash has some features
-	//		that HTML5 does not yet have. But it is still not recommended because of the many problems
-	//		that Firefox and Webkit have with the Flash plugin.
-	//
-	//	description:
-	//		Inherits all properties from dojox.form.Uploader and formUploaderPluginsHTML5.
-	//		All properties and methods listed here are specific to the Flash plugin only.
-	//
-	//	swfPath:String
-	//		Path to SWF. Can be overwritten or provided in djConfig.
-	swfPath:config.uploaderPath || require.toUrl("dojox/form/resources/uploader.swf"),
-	//
-	// skipServerCheck: Boolean
-	// 		If true, will not verify that the server was sent the correct format.
-	//		This can be safely set to true. The purpose of the server side check
-	//		is mainly to show the dev if they've implemented the different returns
-	//		correctly.
-	skipServerCheck:true,
-	//
-	// serverTimeout:Number (milliseconds)
-	//		The amount of time given to the uploaded file
-	//		to wait for a server response. After this amount
-	//		of time, the onComplete is fired but with a 'server timeout'
-	//		error in the returned item.
-	serverTimeout: 2000,
-	//
-	//	isDebug: Boolean
-	//		If true, outputs traces from the SWF to console. What exactly gets passed
-	//		is very relative, and depends upon what traces have been left in the DEFT SWF.
-	isDebug:false,
-	//
-	//	devMode: Boolean.
-	//		Re-implemented. devMode increases the logging, adding style tracing from the SWF.
-	devMode:false,
-	//
-	//	deferredUploading: Number (1 - X)
-	//		(Flash only) throttles the upload to a certain amount of files at a time.
-	//		By default, Flash uploads file one at a time to the server, but in parallel.
-	//		Firefox will try to queue all files at once, leading to problems. Set this
-	//		to the amount to upload in parallel at a time.
-	//		Generally, 1 should work fine, but you can experiment with queuing more than
-	//		one at a time.
-	//		This is of course ignored if selectMultipleFiles equals false.
-	deferredUploading:0,
-	//
-	//	force: String
-	//		Use "flash" to always use Flash (and hopefully force the user to download the plugin
-	//		if they don't have it).
-	force:"",
-
-	postMixInProperties: function(){
-		if(!this.supports("multiple")){
-			// Flash will only be used in IE6-8 unless force="flash"
-			this.uploadType = "flash";
-			this._files = [];
-			this._fileMap = {};
-			this._createInput = this._createFlashUploader;
-			this.getFileList = this.getFlashFileList;
-			this.reset = this.flashReset;
-			this.upload = this.uploadFlash;
-			this.fieldname = "flashUploadFiles"; ///////////////////// this.name
-		}
-		this.inherited(arguments);
-	},
-
-	/*************************
-	 *	   Public Events	 *
-	 *************************/
-
-	onReady: function(/* dojox.form.FileUploader */ uploader){
-		// summary:
-		//		Stub - Fired when embedFlash has created the
-		//		Flash object, but it has not necessarilly finished
-		//		downloading, and is ready to be communicated with.
-	},
-
-	onLoad: function(/* dojox.form.FileUploader */ uploader){
-		// summary:
-		//		Stub - SWF has been downloaded 100%.
-	},
-
-	onFileChange: function(fileArray){
-		// summary:
-		// 		Stub - Flash-specific event. Fires on each selection of files
-		// 		and only provides the files selected on that event - not all files
-		// 		selected, as with HTML5
-	},
-
-	onFileProgress: function(fileArray){
-		// summary:
-		// 		Stub - Flash-specific event. Fires on progress of upload
-		// 		and only provides a file-specific event
-	},
-
-
-	/*************************
-	 *	   Public Methods	 *
-	 *************************/
-
-	getFlashFileList: function(){
-		// summary:
-		//		Returns list of currently selected files
-		return this._files; // Array
-	},
-
-	flashReset: function(){
-		this.flashMovie.reset();
-		this._files = [];
-	},
-
-	/*************************
-	 *	   Private Methods	 *
-	 *************************/
-
-	uploadFlash: function(/*Object ? */formData){
-		// summary:
-		// 		Uploads selected files. Alias "upload()" should be used instead.
-		// tags:
-		//		private
-		this.onBegin(this.getFileList());
-		this.flashMovie.doUpload(formData);
-	},
-
-	_change: function(fileArray){
-		this._files = this._files.concat(fileArray);
-		array.forEach(fileArray, function(f){
-			f.bytesLoaded = 0;
-			f.bytesTotal = f.size;
-			this._fileMap[f.name+"_"+f.size] = f;
-		}, this);
-		this.onChange(this._files);
-		this.onFileChange(fileArray);
-	},
-	_complete: function(fileArray){
-		var o = this._getCustomEvent();
-		o.type = "load";
-		this.onComplete(fileArray);
-	},
-	_progress: function(f){
-		this._fileMap[f.name+"_"+f.bytesTotal].bytesLoaded = f.bytesLoaded;
-		var o = this._getCustomEvent();
-		this.onFileProgress(f);
-		this.onProgress(o);
-	},
-	_error: function(err){
-		this.onError(err);
-	},
-	_onFlashBlur: function(fileArray){
-		//console.log("UploaderFlash._onFlashBlur");
-	},
-
-	_getCustomEvent: function(){
-		var o = {
-			bytesLoaded:0,
-			bytesTotal:0,
-			type:"progress",
-			timeStamp:new Date().getTime()
-		};
-
-
-		for(var nm in this._fileMap){
-			o.bytesTotal += this._fileMap[nm].bytesTotal;
-			o.bytesLoaded += this._fileMap[nm].bytesLoaded;
-		}
-		o.decimal = o.bytesLoaded / o.bytesTotal;
-		o.percent = Math.ceil((o.bytesLoaded / o.bytesTotal)*100)+"%";
-		return o; // Object
-	},
-
-	_connectFlash: function(){
-		// 	summary:
-		//		Subscribing to published topics coming from the
-		//		Flash uploader.
-		// 	description:
-		//		Sacrificing some readbilty for compactness. this.id
-		//		will be on the beginning of the topic, so more than
-		//		one uploader can be on a page and can have unique calls.
-		//
-
-		this._subs = [];
-		this._cons = [];
-
-		var doSub = lang.hitch(this, function(s, funcStr){
-			this._subs.push(connect.subscribe(this.id + s, this, funcStr));
-		});
-
-		doSub("/filesSelected", "_change");
-		doSub("/filesUploaded", "_complete");
-		doSub("/filesProgress", "_progress");
-		doSub("/filesError", "_error");
-		doSub("/filesCanceled", "onCancel");
-		doSub("/stageBlur", "_onFlashBlur");
-
-		this.connect(this.domNode, "focus", function(){
-			// TODO: some kind of indicator that the Flash button
-			//	is in focus
-			this.flashMovie.focus();
-			this.flashMovie.doFocus();
-		});
-		if(this.tabIndex>=0){
-			domAttr.set(this.domNode, "tabIndex", this.tabIndex);
-		}
-	},
-	_createFlashUploader: function(){
-		// summary:
-		//		Internal. Creates Flash Uploader
-		//
-		var url = this.getUrl();
-		if(url){
-			if(url.toLowerCase().indexOf("http")<0 && url.indexOf("/")!=0){
-				// Appears to be a relative path. Attempt to
-				//	convert it to absolute, so it will better
-				//target the SWF.
-				//
-				var loc = window.location.href.split("/");
-				loc.pop();
-				loc = loc.join("/")+"/";
-				url = loc+url;
-			}
-		}else{
-			console.warn("Warning: no uploadUrl provided.");
-		}
-
-		this.inputNode = domConstruct.create("div", {className:"dojoxFlashNode"}, this.domNode, "first");
-		domStyle.set(this.inputNode, {
-			position:"absolute",
-			top:"-2px",
-			width:this.btnSize.w+"px",
-			height:this.btnSize.h+"px",
-			opacity:0
-		});
-
-		var w = this.btnSize.w;
-		var h = this.btnSize.h;
-
-		var args = {
-			expressInstall:true,
-			path: (this.swfPath.uri || this.swfPath) + "?cb_" + (new Date().getTime()),
-			width: w,
-			height: h,
-			allowScriptAccess:"always",
-			allowNetworking:"all",
-			vars: {
-				uploadDataFieldName: this.flashFieldName || this.name+"Flash",
-				uploadUrl: url,
-				uploadOnSelect: this.uploadOnSelect,
-				deferredUploading:this.deferredUploading || 0,
-				selectMultipleFiles: this.multiple,
-				id: this.id,
-				isDebug: this.isDebug,
-				noReturnCheck: this.skipServerCheck,
-				serverTimeout:this.serverTimeout
-			},
-			params: {
-				scale:"noscale",
-				wmode:"transparent",
-				wmode:"opaque",
-				allowScriptAccess:"always",
-				allowNetworking:"all"
-			}
-
-		};
-
-		this.flashObject = new embedFlash(args, this.inputNode);
-		this.flashObject.onError = lang.hitch(function(msg){
-			console.error("Flash Error: " + msg);
-		});
-		this.flashObject.onReady = lang.hitch(this, function(){
-			this.onReady(this);
-		});
-		this.flashObject.onLoad = lang.hitch(this, function(mov){
-			this.flashMovie = mov;
-			this.flashReady = true;
-
-			this.onLoad(this);
-		});
-		this._connectFlash();
-	}
-});
-dojox.form.addUploaderPlugin(pluginsFlash);
-
-
-return pluginsFlash;
+define([],function(){
+	console.warn('dojox.form.uploader.plugins.Flash has been removed. You can use Uploader directly and it will contain all necessary functionality.');
+	return {};
 });
diff --git a/dojox/form/uploader/plugins/HTML5.js b/dojox/form/uploader/plugins/HTML5.js
index fb06cbc..6ad6037 100644
--- a/dojox/form/uploader/plugins/HTML5.js
+++ b/dojox/form/uploader/plugins/HTML5.js
@@ -1,240 +1,4 @@
-define([
-	"dojo/_base/declare",
-	"dojo/_base/lang",
-	"dojo/_base/array",
-	"dojo"
-],function(declare, lang, array, dojo){
-
-var pluginsHTML5 = declare("dojox.form.uploader.plugins.HTML5", [], {
-	//
-	// Version: 1.6
-	//
-	// summary:
-	//		A plugin for dojox.form.Uploader that adds HTML5 multiple-file upload capabilities and
-	//		progress events.
-	//
-	//	description:
-	//		Add this plugin to have HTML5 capabilities in the Uploader. Note that it does not add
-	//		these capabilities to browsers that don't support them. For IE or older browsers, add
-	//		additional plugins: IFrame or Flash.
-	//
-	errMsg:"Error uploading files. Try checking permissions",
-
-	// Overwrites "form" and could possibly be overwritten again by iframe or flash plugin.
-	uploadType:"html5",
-
-	postCreate: function(){
-		this.connectForm();
-		this.inherited(arguments);
-		if(this.uploadOnSelect){
-			this.connect(this, "onChange", function(data){
-				this.upload(data[0]);
-			});
-		}
-	},
-
-	_drop: function(e){
-		dojo.stopEvent(e);
-		var dt = e.dataTransfer;
-		this._files = dt.files;
-		this.onChange(this.getFileList());
-	},
-	/*************************
-	 *	   Public Methods	 *
-	 *************************/
-
-	upload: function(/*Object ? */formData){
-		// summary:
-		// 		See: dojox.form.Uploader.upload
-		//
-		this.onBegin(this.getFileList());
-		if(this.supports("FormData")){
-			this.uploadWithFormData(formData);
-		}else if(this.supports("sendAsBinary")){
-			this.sendAsBinary(formData);
-		}
-	},
-
-	addDropTarget: function(node, /*Boolean?*/onlyConnectDrop){
-		// summary:
-		//		Add a dom node which will act as the drop target area so user
-		//		can drop files to this node.
-		// description:
-		//		If onlyConnectDrop is true, dragenter/dragover/dragleave events
-		//		won't be connected to dojo.stopEvent, and they need to be
-		//		canceled by user code to allow DnD files to happen.
-		//		This API is only available in HTML5 plugin (only HTML5 allows
-		//		DnD files).
-		if(!onlyConnectDrop){
-			this.connect(node, 'dragenter', dojo.stopEvent);
-			this.connect(node, 'dragover', dojo.stopEvent);
-			this.connect(node, 'dragleave', dojo.stopEvent);
-		}
-		this.connect(node, 'drop', '_drop');
-	},
-	
-	sendAsBinary: function(/* Object */data){
-		// summary:
-		// 		Used primarily in FF < 4.0. Sends files and form object as binary data, written to
-		// 		still enable use of $_FILES in PHP (or equivalent).
-		// tags:
-		// 		private
-		//
-		if(!this.getUrl()){
-			console.error("No upload url found.", this); return;
-		}
-
-		// The date/number doesn't matter but amount of dashes do. The actual boundary
-		// will have two more dashes than this one which is used in the header.
-		var boundary = "---------------------------" + (new Date).getTime();
-		var xhr = this.createXhr();
-
-		xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
-
-		// finally send the request as binary data
-		// still accessed as $_FILES
-		var msg = this._buildRequestBody(data, boundary);
-		if(!msg){
-			this.onError(this.errMsg);
-		}else{
-			console.log("msg:", msg)
-			console.log("xhr:", xhr)
-
-			xhr.sendAsBinary(msg);
-		}
-	},
-	uploadWithFormData: function(/* Object */data){
-		// summary
-		// 		Used with WebKit and Firefox 4+
-		// 		Upload files using the much friendlier FormData browser object.
-		// tags:
-		// 		private
-		//
-		if(!this.getUrl()){
-			console.error("No upload url found.", this); return;
-		}
-		var fd = new FormData();
-		array.forEach(this._files, function(f, i){
-			fd.append(this.name+"s[]", f);
-		}, this);
-
-		if(data){
-			for(var nm in data){
-				fd.append(nm, data[nm]);
-			}
-		}
-
-		var xhr = this.createXhr();
-		xhr.send(fd);
-	},
-
-	_xhrProgress: function(evt){
-		if(evt.lengthComputable){
-			var o = {
-				bytesLoaded:evt.loaded,
-				bytesTotal:evt.total,
-				type:evt.type,
-				timeStamp:evt.timeStamp
-			};
-			if(evt.type == "load"){
-				// 100%
-				o.percent = "100%",
-				o.decimal = 1;
-			}else{
-				o.decimal = evt.loaded / evt.total;
-				o.percent = Math.ceil((evt.loaded / evt.total)*100)+"%";
-			}
-			this.onProgress(o);
-		}
-	},
-
-	createXhr: function(){
-		var xhr = new XMLHttpRequest();
-		var timer;
-		xhr.upload.addEventListener("progress", lang.hitch(this, "_xhrProgress"), false);
-		xhr.addEventListener("load", lang.hitch(this, "_xhrProgress"), false);
-		xhr.addEventListener("error", lang.hitch(this, function(evt){
-			this.onError(evt);
-			clearInterval(timer);
-		}), false);
-		xhr.addEventListener("abort", lang.hitch(this, function(evt){
-			this.onAbort(evt);
-			clearInterval(timer);
-		}), false);
-		xhr.onreadystatechange = lang.hitch(this, function(){
-			if(xhr.readyState === 4){
-//				console.info("COMPLETE")
-				clearInterval(timer);
-				this.onComplete(JSON.parse(xhr.responseText.replace(/^\{\}&&/,'')));
-			}
-		});
-		xhr.open("POST", this.getUrl());
-
-		timer = setInterval(lang.hitch(this, function(){
-			try{
-				if(typeof(xhr.statusText)){} // accessing this error throws an error. Awesomeness.
-			}catch(e){
-				//this.onError("Error uploading file."); // not always an error.
-				clearInterval(timer);
-			}
-		}),250);
-
-		return xhr;
-	},
-
-	_buildRequestBody : function(data, boundary){
-		var EOL  = "\r\n";
-		var part = "";
-		boundary = "--" + boundary;
-
-		var filesInError = [], files = this._files;
-		array.forEach(files, function(f, i){
-			var fieldName = this.name+"s[]";//+i;
-			var fileName  = f.fileName;
-			var binary;
-
-			try{
-				binary = f.getAsBinary() + EOL;
-				part += boundary + EOL;
-				part += 'Content-Disposition: form-data; ';
-				part += 'name="' + fieldName + '"; ';
-				part += 'filename="'+ fileName + '"' + EOL;
-				part += "Content-Type: " + this.getMimeType() + EOL + EOL;
-				part += binary;
-			}catch(e){
-				filesInError.push({index:i, name:fileName});
-			}
-		}, this);
-
-		if(filesInError.length){
-			if(filesInError.length >= files.length){
-				// all files were bad. Nothing to upload.
-				this.onError({
-					message:this.errMsg,
-					filesInError:filesInError
-				});
-				part = false;
-			}
-		}
-
-		if(!part) return false;
-
-		if(data){
-			for(var nm in data){
-				part += boundary + EOL;
-				part += 'Content-Disposition: form-data; ';
-				part += 'name="' + nm + '"' + EOL + EOL;
-				part += data[nm] + EOL;
-			}
-		}
-
-
-		part += boundary + "--" + EOL;
-		return part;
-	}
-
-});
-dojox.form.addUploaderPlugin(pluginsHTML5);
-
-return pluginsHTML5;
-});
+define([],function(){
+	console.warn('dojox.form.uploader.plugins.HTML5 has been removed. You can use Uploader directly and it will contain all necessary functionality.');
+	return {};
+});
\ No newline at end of file
diff --git a/dojox/form/uploader/plugins/IFrame.js b/dojox/form/uploader/plugins/IFrame.js
index 9937e68..db0ebbd 100644
--- a/dojox/form/uploader/plugins/IFrame.js
+++ b/dojox/form/uploader/plugins/IFrame.js
@@ -1,78 +1,4 @@
-define([
-	"dojo/dom-construct",
-	"dojo/_base/declare",
-	"dojo/_base/lang",
-	"dojo/_base/array",
-	"dojo/io/iframe",
-	"dojox/form/uploader/plugins/HTML5"
-],function(domConstruct, declare, lang, array, ioIframe, formUploaderPluginsHTML5){
-	
-
-var pluginsIFrame = declare("dojox.form.uploader.plugins.IFrame", [], {
-	//
-	// Version: 1.6
-	//
-	// summary:
-	//		A plugin for dojox.form.Uploader that adds Ajax upload capabilities.
-	//
-	//	description:
-	//		Only supported by IE, due to the specifc iFrame hack used. The
-	//		formUploaderPluginsHTML5 plugin should be used along with this to add HTML5
-	//		capabilities to browsers that support them. Progress events are not supported.
-	//		Inherits all properties from dojox.form.Uploader and formUploaderPluginsHTML5.
-	//
-
-	force:"",
-
-	postMixInProperties: function(){
-		this.inherited(arguments);
-		if(!this.supports("multiple") || this.force =="iframe"){
-			this.uploadType = "iframe";
-			this.upload = this.uploadIFrame;
-		}
-	},
-
-	uploadIFrame: function(data){
-		// summary:
-		//		Internal. You could use this, but you should use upload() or submit();
-		//		which can also handle the post data.
-		//
-		var form, destroyAfter = false;
-		if(!this.getForm()){
-			//enctype can't be changed once a form element is created
-			form = domConstruct.place('<form enctype="multipart/form-data" method="post"></form>', this.domNode);
-			array.forEach(this._inputs, function(n, i){
-				if(n.value) form.appendChild(n);
-			}, this);
-			destroyAfter = true;
-		}else{
-			form = this.form;
-		}
-
-		var url = this.getUrl();
-
-		var dfd = ioIframe.send({
-			url: url,
-			form: form,
-			handleAs: "json",
-			content: data,
-			error: lang.hitch(this, function(err){
-				if(destroyAfter){ domConstruct.destroy(form); }
-				this.onError(err);
-			}),
-			load: lang.hitch(this, function(data, ioArgs, widgetRef){
-				if(destroyAfter){ domConstruct.destroy(form); }
-				if(data["ERROR"] || data["error"]){
-					this.onError(data);
-				}else{
-					this.onComplete(data);
-				}
-			})
-		});
-	}
-});
-
-dojox.form.addUploaderPlugin(pluginsIFrame);
-
-return pluginsIFrame;
-});
+define([],function(){
+	console.warn('dojox.form.uploader.plugins.IFrame has been removed. You can use Uploader directly and it will contain all necessary functionality.');
+	return {};
+});
\ No newline at end of file
diff --git a/dojox/fx.js b/dojox/fx.js
index c3e3863..b026aa5 100644
--- a/dojox/fx.js
+++ b/dojox/fx.js
@@ -1,3 +1,10 @@
 define(["./fx/_base"], function(DojoxFx){
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/fx modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
 	return DojoxFx;
 });
diff --git a/dojox/fx/Shadow.js b/dojox/fx/Shadow.js
index 2e5cea7..fa2aba6 100644
--- a/dojox/fx/Shadow.js
+++ b/dojox/fx/Shadow.js
@@ -2,43 +2,46 @@ define(["dojo/_base/kernel", "dojo/_base/query" ,"dojo/_base/lang", "dojo/_base/
 		"dojo/dom-construct", "dojo/dom-class", "dojo/dom-geometry", "dojo/_base/fx", "dojo/fx", "dijit/_Widget",
 		"dojo/NodeList-fx"], 
   function(kernel, query, lang, declare, has, domConstruct, domClass, domGeom, baseFx, coreFx, Widget, NodeListFx){
-kernel.experimental("dojox.fx.Shadow");
-declare("dojox.fx.Shadow", Widget,{
-		// summary: Adds a drop-shadow to a node.
-		//
+
+	kernel.experimental("dojox.fx.Shadow");
+
+	return declare("dojox.fx.Shadow", Widget,{
+		// summary:
+		//		Adds a drop-shadow to a node.
 		// example:
 		// |	// add drop shadows to all nodes with class="hasShadow"
 		// |	dojo.query(".hasShadow").forEach(function(n){
 		// |		var foo = new dojox.fx.Shadow({ node: n });
 		// |		foo.startup();
 		// |	});
-		//
+
 		// shadowPng: String
-		// 	Base location for drop-shadow images
+		//		Base location for drop-shadow images
 		shadowPng: kernel.moduleUrl("dojox.fx", "resources/shadow"),
 	
 		// shadowThickness: Integer
-		// 	How wide (in px) to make the shadow
+		//		How wide (in px) to make the shadow
 		shadowThickness: 7,
 	
 		// shadowOffset: Integer
-		//	How deep to make the shadow appear to be
+		//		How deep to make the shadow appear to be
 		shadowOffset: 3,
 	
 		// opacity: Float
-		//	Overall opacity of the shadow
+		//		Overall opacity of the shadow
 		opacity: 0.75,
 	
 		// animate: Boolean
-		// 	A toggle to disable animated transitions
+		//		A toggle to disable animated transitions
 		animate: false,
 	
 		// node: DomNode
-		// 	The node we will be applying this shadow to
+		//		The node we will be applying this shadow to
 		node: null,
 	
 		startup: function(){
-			// summary: Initializes the shadow.
+			// summary:
+			//		Initializes the shadow.
 	
 			this.inherited(arguments);
 			this.node.style.position = "relative";
@@ -63,7 +66,8 @@ declare("dojox.fx.Shadow", Widget,{
 		},
 	
 		_makePiece: function(name, vertAttach, vertCoord, horzAttach, horzCoord, sizing){
-			// summary: append a shadow pieces to the node, and position it
+			// summary:
+			//		append a shadow pieces to the node, and position it
 			var img;
 			var url = this.shadowPng + name.toUpperCase() + ".png";
 			if(has("ie") < 7){
@@ -86,8 +90,11 @@ declare("dojox.fx.Shadow", Widget,{
 		},
 	
 		setOpacity: function(/* Float */n,/* Object? */animArgs){
-			// summary: set the opacity of the underlay
+			// summary:
+			//		set the opacity of the underlay
+
 			// note: does not work in IE? FIXME.
+
 			if(has("ie")){ return; }
 			if(!animArgs){ animArgs = {}; }
 			if(this.animate){
@@ -103,7 +110,8 @@ declare("dojox.fx.Shadow", Widget,{
 		},
 	
 		setDisabled: function(/* Boolean */disabled){
-			// summary: enable / disable the shadow
+			// summary:
+			//		enable / disable the shadow
 			if(disabled){
 				if(this.disabled){ return; }
 				if(this.animate){ this.nodeList.fadeOut().play();
@@ -118,7 +126,8 @@ declare("dojox.fx.Shadow", Widget,{
 		},
 	
 		resize: function(/* dojox.fx._arg.ShadowResizeArgs */args){
-			// summary: Resizes the shadow based on width and height.
+			// summary:
+			//		Resizes the shadow based on width and height.
 			var x; var y;
 			if(args){ x = args.x; y = args.y;
 			}else{
@@ -142,5 +151,4 @@ declare("dojox.fx.Shadow", Widget,{
 			}
 		}
 	});
-	return dojox.fx.Shadow;
 });
diff --git a/dojox/fx/Timeline.js b/dojox/fx/Timeline.js
index 2956a46..2253cb2 100644
--- a/dojox/fx/Timeline.js
+++ b/dojox/fx/Timeline.js
@@ -2,17 +2,7 @@ define(["dojo/_base/lang","dojo/fx/easing","dojo/_base/fx","dojo/dom","./_base",
 		"dojo/_base/html", "dojo/_base/array","dojo/_base/Color"],
  function(lang, easingUtil, baseFx, dom, dojoxFx, connectUtil, htmlUtil, arrayUtil, Color){
 
-dojoxFx.animateTimeline = function(/* Object */options, /* DomNode|String */node){
-	// options: Object
-	// 		The paramters passed to the timeline animation. Includes:
-	// 			keys: Array
-	// 				An array of objects, with style properties and values.
-	// 			duration:
-	// 				Duration of the animation in milliseconds.
-	// 				Defaults to 1000.
-	// node: DomNode
-	// 		The DomNode or id to be animated.
-	//
+dojoxFx.animateTimeline = function(options, node){
 	// summary:
 	//		An add-on to dojo.fx that provides the ability to create
 	//		a complex property animation based on an array of "keyframes".
@@ -26,34 +16,41 @@ dojoxFx.animateTimeline = function(/* Object */options, /* DomNode|String */node
 	//		keyframe to the third. "width" is transitioned from the first
 	//		to the second to the third.
 	//		Each keyframe can accept the following custom properties:
-	//	step: String
-	//		The start, finish or percentage that this keyframe represents.
-	//		Allowed parameters are:
-	//			0%-100%
-	//			from (same as 0%, used to conform with the Webkit animation spec)
-	//			to (same as 100%, used to conform with the Webkit animation spec)
-	//	ease: String
-	//		The string name of a dojo.fx.easing ease. Defaults to "linear". Use
-	//		the suffix name of the ease, like: "quadIn", not: "dojo.fx.quadIn".
 	//
-	// example:
-	// 		|	var keys = [
-	// 		|	{
-	// 		|		step:"0px",
-	// 		|		ease:"quadInOut",
-	// 		|		width:"50px",
-	// 		|		height:"50px",
-	// 		|	},{
-	// 		|		step:"25%",
-	// 		|		width:"190px"
-	// 		|	},{
-	// 		|		step:"100%",
-	// 		|		width:"10px",
-	// 		|		height:"200px",
-	// 		|	}
-	// 		|	];
-	// 		|	ani = dojox.fx.animateTimeline({keys:keys, duration:2000}, "myDiv").play();
+	//		- step: String:
+	//		  The start, finish or percentage that this keyframe represents.
+	//		  Allowed parameters are:
+	//			- 0%-100%
+	//			- from (same as 0%, used to conform with the Webkit animation spec)
+	//			- to (same as 100%, used to conform with the Webkit animation spec)
+	//		- ease: String:
+	//		  The string name of a dojo.fx.easing ease. Defaults to "linear". Use
+	//		  the suffix name of the ease, like: "quadIn", not: "dojo.fx.quadIn".
+	// options: Object
+	//		The parameters passed to the timeline animation. Includes:
 	//
+	//		- keys: Array: An array of objects, with style properties and values.
+	//		- duration: Duration of the animation in milliseconds.  Defaults to 1000.
+	// node: DomNode|String
+	//		The DomNode or id to be animated.
+	// example:
+	//	|	var keys = [
+	//	|	{
+	//	|		step:"0px",
+	//	|		ease:"quadInOut",
+	//	|		width:"50px",
+	//	|		height:"50px",
+	//	|	},{
+	//	|		step:"25%",
+	//	|		width:"190px"
+	//	|	},{
+	//	|		step:"100%",
+	//	|		width:"10px",
+	//	|		height:"200px",
+	//	|	}
+	//	|	];
+	//	|	ani = dojox.fx.animateTimeline({keys:keys, duration:2000}, "myDiv").play();
+
 	var _curve = new Timeline(options.keys);
 	var ani = baseFx.animateProperty({
 		node:dom.byId(node || options.node),
@@ -80,7 +77,7 @@ dojoxFx.animateTimeline = function(/* Object */options, /* DomNode|String */node
 		_curve.ani = ani;
 	})
 	return ani; // dojo.Animation
-}
+};
 
 var Timeline = function(/* Array */keys){
 	// summary:
@@ -89,7 +86,7 @@ var Timeline = function(/* Array */keys){
 	// tags:
 	//		private
 	this.keys = lang.isArray(keys) ? this.flatten(keys) : keys;
-}
+};
 
 Timeline.prototype.flatten = function(keys){
 	// summary:
@@ -103,7 +100,7 @@ Timeline.prototype.flatten = function(keys){
 			return idx==0 ? 0 : idx / (keys.length - 1)
 		}
 		return parseInt(str, 10) * .01
-	}
+	};
 	var p = {}, o = {};
 	arrayUtil.forEach(keys, function(k, i){
 		var step = getPercent(k.step, i);
@@ -147,7 +144,7 @@ Timeline.prototype.flatten = function(keys){
 	this._properties = p;
 	return o; // Object
 	
-}
+};
 
 Timeline.prototype.getValue = function(/*float*/ p){
 	// summary:
@@ -161,7 +158,7 @@ Timeline.prototype.getValue = function(/*float*/ p){
 		return self._properties[nm].units!="isColor" ?
 			self.keys[nm].values[i] + self._properties[nm].units :
 			self.keys[nm].values[i].toCss();
-	}
+	};
 	
 	for(var nm in this.keys){
 		var k = this.keys[nm];
diff --git a/dojox/fx/_base.js b/dojox/fx/_base.js
index 75c4d2b..1f76b45 100644
--- a/dojox/fx/_base.js
+++ b/dojox/fx/_base.js
@@ -1,56 +1,62 @@
 define(["dojo/_base/array","dojo/_base/lang", "dojo/_base/fx", "dojo/fx", "dojo/dom", "dojo/dom-style",
 	    "dojo/dom-geometry", "dojo/_base/connect", "dojo/_base/html"],
 	function(arrayUtil, lang, baseFx, coreFx, dom, domStyle, domGeom, connectUtil, htmlUtil){
-// summary: Experimental and extended Animations beyond Dojo Core / Base functionality.
-//	Provides advanced Lines, Animations, and convenience aliases.
+
+/*=====
+return {
+	// summary:
+	//		Experimental and extended Animations beyond Dojo Core / Base functionality.
+	//		Provides advanced Lines, Animations, and convenience aliases.
+};
+=====*/
+
 var dojoxFx = lang.getObject("dojox.fx", true);
-/*
-lang.mixin(dojox.fx, {
+
+lang.mixin(dojoxFx, {
 
 	// anim: Function
-	//	Alias of `dojo.anim` - the shorthand `dojo.animateProperty` with auto-play
-	anim: dojo.fx.anim,
+	//		Alias of `dojo.anim` - the shorthand `dojo.animateProperty` with auto-play
+	anim: baseFx.anim,
 
 	// animateProperty: Function
-	//	Alias of `dojo.animateProperty` - animate any CSS property
-	animateProperty: dojox.fx.animateProperty,
+	//		Alias of `dojo.animateProperty` - animate any CSS property
+	animateProperty: baseFx.animateProperty,
 
 	// fadeTo: Function
 	//		Fade an element from an opacity to an opacity.
 	//		Omit `start:` property to detect. `end:` property is required.
 	//		Ultimately an alias to `dojo._fade`
-	fadeTo: dojo._fade,
+	fadeTo: baseFx._fade,
 
 	// fadeIn: Function
-	//	Alias of `dojo.fadeIn` - Fade a node in.
-	fadeIn: dojo.fadeIn,
+	//		Alias of `dojo.fadeIn` - Fade a node in.
+	fadeIn: baseFx.fadeIn,
 	
 	// fadeOut: Function
-	//	Alias of `dojo.fadeOut` - Fades a node out.
-	fadeOut: dojo.fadeOut,
+	//		Alias of `dojo.fadeOut` - Fades a node out.
+	fadeOut: baseFx.fadeOut,
 
 	// combine: Function
-	//	Alias of `dojo.fx.combine` - Run an array of animations in parallel
-	combine: dojo.fx.combine,
+	//		Alias of `dojo.fx.combine` - Run an array of animations in parallel
+	combine: coreFx.combine,
 
 	// chain: Function
-	//	Alias of `dojo.fx.chain` - Run an array of animations in sequence
-	chain: dojo.fx.chain,
+	//		Alias of `dojo.fx.chain` - Run an array of animations in sequence
+	chain: coreFx.chain,
 
 	// slideTo: Function
-	//	Alias of `dojo.fx.slideTo` - Slide a node to a defined top/left coordinate
-	slideTo: dojo.fx.slideTo,
+	//		Alias of `dojo.fx.slideTo` - Slide a node to a defined top/left coordinate
+	slideTo: coreFx.slideTo,
 
 	// wipeIn: Function
-	//	Alias of `dojo.fx.wipeIn` - Wipe a node to visible
-	wipeIn: dojo.fx.wipeIn,
+	//		Alias of `dojo.fx.wipeIn` - Wipe a node to visible
+	wipeIn: coreFx.wipeIn,
 
 	// wipeOut: Function
-	//	Alias of `dojo.fx.wipeOut` - Wipe a node to non-visible
-	wipeOut: dojo.fx.wipeOut
-
+	//		Alias of `dojo.fx.wipeOut` - Wipe a node to non-visible
+	wipeOut: coreFx.wipeOut
 });
-*/
+
 
 dojoxFx.sizeTo = function(/* Object */args){
 	// summary:
@@ -192,12 +198,10 @@ dojoxFx.slideBy = function(/* Object */args){
 dojoxFx.crossFade = function(/* Object */args){
 	// summary:
 	//		Returns an animation cross fading two element simultaneously
-	//
 	// args:
-	//	args.nodes: Array - two element array of domNodes, or id's
-	//
-	//	all other standard animation args mixins apply. args.node ignored.
+	//		- args.nodes: Array - two element array of domNodes, or id's
 	//
+	//		all other standard animation args mixins apply. args.node ignored.
 
 	// simple check for which node is visible, maybe too simple?
 	var node1 = args.nodes[0] = dom.byId(args.nodes[0]),
diff --git a/dojox/fx/_core.js b/dojox/fx/_core.js
index 8224868..8dad558 100644
--- a/dojox/fx/_core.js
+++ b/dojox/fx/_core.js
@@ -1,45 +1,43 @@
 define(["dojo/_base/lang", "dojo/_base/array","./_base"],
 	function(lang, arrayUtil, dojoxFx){
-	/*===== var dojox.fx._Line = line =====*/
+
 	var line = function(start, end){
-		// summary: a custom _Line to accomodate multi-dimensional values
-		//
+		// summary:
+		//		a custom _Line to accommodate multi-dimensional values
 		// description:
-		//	a normal dojo._Line is the curve, and does Line(start,end)
-		//	for propertyAnimation. as we make more complicatied animations, we realize
-		//	some properties can have 2, or 4 values relevant (x,y) or (t,l,r,b) for example
-		//
-		// 	this function provides support for those Lines, and is ported directly from 0.4
-		//	this is a lot of extra code for something so seldom used, so we'll put it here as
-		//	and optional core addition. you can create a new line, and use it during onAnimate
-		//	as you see fit.
+		//		a normal dojo._Line is the curve, and does Line(start,end)
+		//		for propertyAnimation. as we make more complicatied animations, we realize
+		//		some properties can have 2, or 4 values relevant (x,y) or (t,l,r,b) for example
 		//
+		//		this function provides support for those Lines, and is ported directly from 0.4
+		//		this is a lot of extra code for something so seldom used, so we'll put it here as
+		//		and optional core addition. you can create a new line, and use it during onAnimate
+		//		as you see fit.
 		// start: Integer|Array
-		//	An Integer (or an Array of integers) to use as a starting point
+		//		An Integer (or an Array of integers) to use as a starting point
 		// end: Integer|Array
-		//	An Integer (or an Array of integers) to use as an ending point
-		//
-		// example: see dojox.fx.smoothScroll
-		//
+		//		An Integer (or an Array of integers) to use as an ending point
+		// example:
+		//		see dojox.fx.smoothScroll
 		// example:
 		// |	// this is 10 .. 100 and 50 .. 500
 		// |	var curve = new dojox.fx._Line([10,50],[100,500]);
 		// |	// dojo.Animation.onAnimate is called at every step of the animation
 		// |	// to define current values. this _Line returns an array
 		// | 	// at each step. arguments[0] and [1] in this example.
-		//
+
 		this.start = start;
 		this.end = end;
-		
+
 		var isArray = lang.isArray(start),
 			d = (isArray ? [] : end - start);
-		
+
 		if(isArray){
 			// multi-dimensional branch
 			arrayUtil.forEach(this.start, function(s, i){
 				d[i] = this.end[i] - s;
 			}, this);
-			
+
 			this.getValue = function(/*float*/ n){
 				var res = [];
 				arrayUtil.forEach(this.start, function(s, i){
@@ -50,8 +48,10 @@ define(["dojo/_base/lang", "dojo/_base/array","./_base"],
 		}else{
 			// single value branch, document here for both branches:
 			this.getValue = function(/*float*/ n){
-				// summary: Returns the point on the line, or an array of points
-				// n: a floating point number greater than 0 and less than 1
+				// summary:
+				//		Returns the point on the line, or an array of points
+				// n:
+				//		a floating point number greater than 0 and less than 1
 				// returns: Mixed
 				return (d * n) + this.start; // Decimal
 			}
diff --git a/dojox/fx/easing.js b/dojox/fx/easing.js
index 44c665c..d0d0681 100644
--- a/dojox/fx/easing.js
+++ b/dojox/fx/easing.js
@@ -4,7 +4,7 @@ define(["dojo/_base/lang", "dojo/_base/kernel", "dojo/fx/easing"],
 	var fxExt = lang.getObject("dojox.fx",true);
 	fxExt.easing = easing;
 /*=====
-	dojox.fx.easing = {
+	return {
 		// summary:
 		//		An Alias to `dojo.fx.easing`. Moved to Core in Dojo 1.2.
 	};
diff --git a/dojox/fx/ext-dojo/NodeList-style.js b/dojox/fx/ext-dojo/NodeList-style.js
index 29190d9..b8c2964 100644
--- a/dojox/fx/ext-dojo/NodeList-style.js
+++ b/dojox/fx/ext-dojo/NodeList-style.js
@@ -1,24 +1,28 @@
-define(["dojo/_base/lang", "dojo/_base/NodeList","dojo/NodeList-fx", "dojo/fx", "../style"],
-	function(lang, NodeList, NodeListFx, coreFx, styleX){
-// summary:
-//		Core extensions to `dojo.NodeList` providing additional fx to `dojo.NodeList-fx`
-// 		from `dojox.fx.style`
-//
-// description:
-//		A Package to extend dojo base NodeList with fx provided by the `dojox.fx` project.
-//		These are experimental animations, in an experimental
+define(["dojo/_base/lang", "dojo/query", "dojo/NodeList-fx", "dojo/fx", "../style"],
+	function(lang, query, NodeListFx, coreFx, styleX){
 
+/*=====
+return {
+	// summary:
+	//		Core extensions to `dojo.NodeList` providing additional fx to `dojo.NodeList-fx`
+	//		from `dojox.fx.style`
+	// description:
+	//		A Package to extend dojo base NodeList with fx provided by the `dojox.fx` project.
+	//		These are experimental animations, in an experimental
+};
+=====*/
 
-lang.extend( NodeList, {
+var NodeList = query.NodeList;
+
+lang.extend(NodeList, {
 
 	addClassFx: function(cssClass, args){
-		// 	summary:
+		// summary:
 		//		Animate the effects of adding a class to all nodes in this list.
 		//		see `dojox.fx.addClass`
-		//
-		//	tags: FX, NodeList
-		//
-		//	example:
+		// tags:
+		//		FX, NodeList
+		// example:
 		//	|	// fade all elements with class "bar" to to 50% opacity
 		//	|	dojo.query(".bar").addClassFx("bar").play();
 
@@ -31,9 +35,8 @@ lang.extend( NodeList, {
 		// summary:
 		//		Animate the effect of removing a class to all nodes in this list.
 		//		see `dojox.fx.removeClass`
-		//
-		//	tags: FX, NodeList
-		//
+		// tags:
+		//		FX, NodeList
 		// example:
 		//	| dojo.query(".box").removeClassFx("bar").play();
 
@@ -46,9 +49,8 @@ lang.extend( NodeList, {
 		// summary:
 		//		Animate the effect of adding or removing a class to all nodes in this list.
 		//		see `dojox.fx.toggleClass`
-		//
-		//	tags: FX, NodeList
-		//
+		// tags:
+		//		FX, NodeList
 		// example:
 		//	| dojo.query(".box").toggleClass("bar").play();
 
diff --git a/dojox/fx/ext-dojo/NodeList.js b/dojox/fx/ext-dojo/NodeList.js
index ff27eb7..0feba7e 100644
--- a/dojox/fx/ext-dojo/NodeList.js
+++ b/dojox/fx/ext-dojo/NodeList.js
@@ -1,17 +1,23 @@
 define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/fx", "dojox/fx","dojo/NodeList-fx"],
 	function(kernel, lang, baseFx, CoreFx, NodeList){
 kernel.experimental("dojox.fx.ext-dojo.NodeList");
-// summary: Core extensions to dojo.NodeList providing addtional fx to dojo.NodeList-fx
-// description:
-//	A Package to extend dojo base NodeList with fx provided by the dojox.fx project.
-//	These are experimental animations, in an experimental
+
+/*=====
+return {
+	// summary:
+	//		Core extensions to dojo/NodeList providing additional fx to dojo.NodeList-fx
+	// description:
+	//		A Package to extend dojo base NodeList with fx provided by the dojox.fx project.
+	//		These are experimental animations, in an experimental
+};
+=====*/
 
 lang.extend(NodeList, {
 
 	sizeTo: function(args){
-		//	summary:
+		// summary:
 		//		size all elements of this NodeList. Returns an instance of dojo.Animation
-		//	example:
+		// example:
 		//	|	// size all divs with class "blah"
 		//	|	dojo.query("div.blah").sizeTo({
 		//	|		width:50,
@@ -21,29 +27,28 @@ lang.extend(NodeList, {
 	},
 
 	slideBy: function(args){
-		//	summary:
+		// summary:
 		//		slide all elements of this NodeList. Returns an instance of dojo.Animation
-		//
-		//	example:
+		// example:
 		//	|	// slide all tables with class "blah" 10 px
 		//	|	dojo.query("table.blah").slideBy({ top:10, left:10 }).play();
 		return this._anim(CoreFx, "slideBy", args); // dojo.Animation
 	},
 
 	highlight: function(args){
-		//	summary:
+		// summary:
 		//		highlight all elements of the node list.
 		//		Returns an instance of dojo.Animation
-		//	example:
+		// example:
 		//	|	// highlight all links with class "foo"
 		//	|	dojo.query("a.foo").hightlight().play();
 		return this._anim(CoreFx, "highlight", args); // dojo.Animation
 	},
 
 	fadeTo: function(args){
-		// 	summary:
+		// summary:
 		//		fade all elements of the node list to a specified opacity
-		//	example:
+		// example:
 		//	|	// fade all elements with class "bar" to to 50% opacity
 		//	|	dojo.query(".bar").fadeTo({ end: 0.5 }).play();
 		return this._anim(baseFx,"_fade",args);
diff --git a/dojox/fx/ext-dojo/complex.js b/dojox/fx/ext-dojo/complex.js
index b529624..d48a980 100644
--- a/dojox/fx/ext-dojo/complex.js
+++ b/dojox/fx/ext-dojo/complex.js
@@ -2,7 +2,32 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/d
 	"dojo/_base/Color", "dojo/_base/fx", "dojo/fx"], 
 	function(dojo, lang, arrayUtil, declare, connectUtil, Color, baseFx, coreFx){
 	lang.getObject("dojox.fx.ext-dojo.complex", true);
-	
+
+	/*=====
+	return {
+		// summary:
+		//		Extends dojo/_base/fx.animateProperty to animate a "complex property". The primary example is the
+		//		clip style: rect(10px 30px 10px 50px).
+		//		Note this can also be used with (and is actually intended for)
+		//		CSS3 properties, such as transform:
+		//		transform: rotate(10deg) translateX(0px)
+		// description:
+		//		The standard animation doesn't know what to do with something like
+		//		rect(...). This class identifies complex properties by they being a
+		//		string and having parenthesis. If so, that property is made into a
+		//		dojox.fx._Complex object and the getValue() is obtained from
+		//		there.
+		// example:
+		//		|	var ani = dojo.animateProperty({
+		//		|		node:dojo.byId("myDiv"),
+		//		|		duration:600,
+		//		|		properties:{
+		//		|			clip:{start:'rect(0px 50px 50px 0px)', end:'rect(10px 30px 30px 10px)'}
+		//		|		}
+		//		|	}).play();
+	};
+	=====*/
+
 	var da = baseFx.animateProperty;
 	dojo.animateProperty = baseFx.animateProperty = function(options){
 		// summary:
@@ -12,15 +37,13 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/d
 		//		Note this can also be used with (and is actually intended for)
 		//		CSS3 properties, such as transform:
 		//		transform: rotate(10deg) translateX(0px)
-		//
-		//	description:
+		// description:
 		//		The standard animation doesn't know what to do with something like
 		//		rect(...). This class identifies complex properties by they being a
 		//		string and having parenthesis. If so, that property is made into a
 		//		dojox.fx._Complex object and the getValue() is obtained from
 		//		there.
-		//
-		//	example:
+		// example:
 		//		|	var ani = dojo.animateProperty({
 		//		|		node:dojo.byId("myDiv"),
 		//		|		duration:600,
@@ -28,8 +51,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/d
 		//		|			clip:{start:'rect(0px 50px 50px 0px)', end:'rect(10px 30px 30px 10px)'}
 		//		|		}
 		//		|	}).play();
-		//
-		var d = dojo;
+
 		var ani = da(options);
 
 		connectUtil.connect(ani, "beforeBegin", function(){
@@ -44,11 +66,11 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/d
 				for(var p in this._properties){
 					var prop = this._properties[p],
 						start = prop.start;
-					if(start instanceof d.Color){
-						ret[p] = d.blendColors(start, prop.end, r, prop.tempColor).toCss();
+					if(start instanceof dojo.Color){
+						ret[p] = dojo.blendColors(start, prop.end, r, prop.tempColor).toCss();
 					}else if(start instanceof dojox.fx._Complex){
 						ret[p] = start.getValue(r);
-					}else if(!d.isArray(start)){
+					}else if(!dojo.isArray(start)){
 						ret[p] = ((prop.end - start) * r) + start + (p != "opacity" ? prop.units || "px" : 0);
 					}
 				}
@@ -68,15 +90,20 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/d
 
 		});
 		return ani; // dojo.Animation
-	}
+	};
+	/*=====
+	// Hide this override from the doc parser because it obscures the original definition of animateProperty()
+	// TODO: rewrite override as around advice, so we don't need faux-return value above.
+	dojo.animateProperty = baseFx.animateProperty = da;
+	=====*/
 
 	return declare("dojox.fx._Complex", null, {
 		// summary:
 		//		A class that takes a complex property such as
 		//		clip style: rect(10px 30px 10px 50px), and breaks it
-		//		into seperate animatable units. The object has a getValue()
+		//		into separate animatable units. The object has a getValue()
 		//		that will return a string with the modified units.
-		//
+
 		PROP: /\([\w|,|+|\-|#|\.|\s]*\)/g,
 		constructor: function(options){
 			var beg = options.start.match(this.PROP);
@@ -97,8 +124,8 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/d
 
 		getValue: function(/*Float*/r){
 			// summary:
-			// 		Returns a string with teh same integrity as the
-			// 		original star and end, but with the modified units.
+			//		Returns a string with teh same integrity as the
+			//		original star and end, but with the modified units.
 			var str = this.strProp, u;
 			for(var nm in this._properties){
 				var v, o = this._properties[nm];
@@ -119,7 +146,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/d
 			// summary:
 			//		Returns an object that stores the numeric value and
 			//		units of the beggining and ending properties.
-			//
+
 			var b = this.getNumAndUnits(beg);
 			var e = this.getNumAndUnits(end);
 			return {
@@ -133,7 +160,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/d
 			// summary:
 			//		Helper function that splits a stringified set of properties
 			//		into individual units.
-			//
+
 			str = str.substring(1, str.length-1);
 			var s;
 			if(/,/.test(str)){
@@ -150,7 +177,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/d
 			//		Helper function that returns the numeric verion of the string
 			//		property (or dojo.Color object) and the unit in which it was
 			//		defined.
-			//
+
 			if(!prop){ return {}; }
 			if(/#/.test(prop)){
 				return {
diff --git a/dojox/fx/ext-dojo/reverse.js b/dojox/fx/ext-dojo/reverse.js
index 413d59e..b0e8b76 100644
--- a/dojox/fx/ext-dojo/reverse.js
+++ b/dojox/fx/ext-dojo/reverse.js
@@ -1,34 +1,34 @@
 define(["dojo/_base/fx",
 		"dojo/fx",
-		"dojo/_base/lang", 
+		"dojo/_base/lang",
 		"dojo/fx/easing",
 		"dojox/fx"],
 	function(baseFx, coreFx, lang, easingUtil, dojoxFx){ //
-/*===== var dojox.fx.ext-dojo.=====*/
+
 var reverseApi = {
 	// summary:
 	//		A dojo.Animation extension that enables an easy reversal.
-	//	description:
+	// description:
 	//		To use, simply require dojox.fx.ext-dojo.reverse and a reverse()
 	//		method will be added to all dojo.Animations.
 	//		It can be used at any time during the animation. It does not
 	//		need to be called when it ends. It also reverses the easing -
 	//		if dojo.fx.easing.quadIn is used, dojo.fx.easing.quadOut will
 	//		be used when animating backwards.
-	//
+
 	_reversed: false,
 	reverse: function(/*Boolean*/keepPaused, /*Function ? */reverseEase){
 		// summary:
-		// 		The key method added to an animation to enable reversal.
-		// 	keepPaused: Boolean
-		// 		By default, calling reverse() will play the animation if
-		// 		it was paused. Pass in true to keep it paused (will have
-		// 		no effect if reverse is called while animation is playing).
-		// 	reverseEase: Function
-		// 		A function to use for the reverse easing. This allows for
-		// 		the possibility of custom eases that are not in the dojo.fx
-		// 		library.
-		//
+		//		The key method added to an animation to enable reversal.
+		// keepPaused: Boolean
+		//		By default, calling reverse() will play the animation if
+		//		it was paused. Pass in true to keep it paused (will have
+		//		no effect if reverse is called while animation is playing).
+		// reverseEase: Function
+		//		A function to use for the reverse easing. This allows for
+		//		the possibility of custom eases that are not in the dojo.fx
+		//		library.
+
 		var playing = this.status() == "playing";
 		this.pause();
 		this._reversed = !this._reversed;
@@ -42,7 +42,7 @@ var reverseApi = {
 		;
 		this._endTime = curr + sofar;
 		this._startTime = curr - togo;
-		
+
 		if(playing){
 			this.gotoPercent(togo / d)
 		}
@@ -51,7 +51,7 @@ var reverseApi = {
 			p[nm].start = cp[nm].start = p[nm].end;
 			p[nm].end = cp[nm].end = tmp;
 		}
-		
+
 		if(this._reversed){
 			if(!this.rEase){
 				this.fEase = this.easing;
@@ -66,7 +66,7 @@ var reverseApi = {
 							found = nm; break;
 						}
 					}
-					
+
 					if(found){
 						// find ease's opposite
 						if(/InOut/.test(nm) || !/In|Out/i.test(nm)){
@@ -85,7 +85,7 @@ var reverseApi = {
 						this.rEase = this.easing;
 					}
 				}
-				
+
 			}
 			this.easing = this.rEase;
 		}else{
@@ -94,7 +94,7 @@ var reverseApi = {
 		if(!keepPaused && this.status() != "playing"){
 			this.play();
 		}
-		
+
 		return this;
 	}
 };
diff --git a/dojox/fx/flip.js b/dojox/fx/flip.js
index 305df99..56a4b3c 100644
--- a/dojox/fx/flip.js
+++ b/dojox/fx/flip.js
@@ -27,40 +27,45 @@ define([
 	;
 
 	fxExt.flip = function(/*Object*/ args){
-		// summary: Animate a node flipping following a specific direction
-		//
+		// summary:
+		//		Animate a node flipping following a specific direction
 		// description:
 		//		Returns an animation that will flip the
 		//		node around a central axis:
+		//
 		//		if args.dir is "left" or "right" --> y axis
+		//
 		//		if args.dir is "top" or "bottom" --> x axis
 		//
-		//		This effect is obtained using a border distorsion applied to a helper node.
+		//		This effect is obtained using a border distortion applied to a helper node.
 		//
 		//		The user can specify three background colors for the helper node:
-		//		darkColor: the darkest color reached during the animation
-		//		lightColor: the brightest color
-		//		endColor: the final backgroundColor for the node
 		//
-		//		depth: Float
-		//			 0 <= depth <= 1 overrides the computed "depth"
-		//			(0: min distorsion, 1: max distorsion)
+		//		- darkColor: the darkest color reached during the animation
+		//		- lightColor: the brightest color
+		//		- endColor: the final backgroundColor for the node
 		//
-		//		whichAnim: String
-		//			"first"			 : the first half animation
-		//			"last"			 : the second one
-		//			"both" (default) : both
+		//		Other arguments:
 		//
-		//		axis: String
-		//			"center" (default)	  : the node is flipped around his center
-		//			"shortside"			  : the node is flipped around his "short" (in perspective) side
-		//			"longside"			  : the node is flipped around his "long" (in perspective) side
-		//			"cube"				  : the node flips around the central axis of the cube
+		//		- depth: Float
+		//			 - 0 <= depth <= 1 overrides the computed "depth"
+		//			- (0: min distortion, 1: max distortion)
 		//
-		//		shift: Integer
+		//		- whichAnim: String
+		//			- "first"			 : the first half animation
+		//			- "last"			 : the second one
+		//			- "both" (default) : both
+		//
+		//		- axis: String
+		//			- "center" (default)	  : the node is flipped around his center
+		//			- "shortside"			  : the node is flipped around his "short" (in perspective) side
+		//			- "longside"			  : the node is flipped around his "long" (in perspective) side
+		//			- "cube"				  : the node flips around the central axis of the cube
+		//
+		//		- shift: Integer:
 		//			node translation, perpendicular to the rotation axis
 		//
-		//	example:
+		// example:
 		//	|	var anim = dojox.fx.flip({
 		//	|		node: dojo.byId("nodeId"),
 		//	|		dir: "top",
@@ -237,14 +242,13 @@ define([
 	}
 
 	fxExt.flipCube = function(/*Object*/ args){
-		// summary: An extension to `dojox.fx.flip` providing a more 3d-like rotation
-		//
+		// summary:
+		//		An extension to `dojox.fx.flip` providing a more 3d-like rotation
 		// description:
 		//		An extension to `dojox.fx.flip` providing a more 3d-like rotation.
 		//		Behaves the same as `dojox.fx.flip`, using the same attributes and
 		//		other standard `dojo.Animation` properties.
-		//
-		//	example:
+		// example:
 		//		See `dojox.fx.flip`
 		var anims = [],
 			mb = domGeom.getMarginBox(args.node),
@@ -327,14 +331,13 @@ define([
 	};
 	
 	fxExt.flipPage = function(/*Object*/ args){
-		// summary: An extension to `dojox.fx.flip` providing a page flip like animation.
-		//
+		// summary:
+		//		An extension to `dojox.fx.flip` providing a page flip like animation.
 		// description:
 		//		An extension to `dojox.fx.flip` providing a page flip effect.
 		//		Behaves the same as `dojox.fx.flip`, using the same attributes and
 		//		other standard `dojo.Animation` properties.
-		//
-		//	example:
+		// example:
 		//		See `dojox.fx.flip`
 		var n = args.node,
 			coords = htmlUtil.coords(n, true),
@@ -411,19 +414,17 @@ define([
 	
 	
 	fxExt.flipGrid = function(/*Object*/ args){
-		// summary: An extension to `dojox.fx.flip` providing a decomposition in rows * cols flipping elements
-		//
+		// summary:
+		//		An extension to `dojox.fx.flip` providing a decomposition in rows * cols flipping elements
 		// description:
 		//		An extension to `dojox.fx.flip` providing a page flip effect.
 		//		Behaves the same as `dojox.fx.flip`, using the same attributes and
 		//		other standard `dojo.Animation` properties and
 		//
-		//		cols: Integer columns
-		//		rows: Integer rows
-		//
-		//		duration: the single flip duration
-		//
-		//	example:
+		//		- cols: Integer columns
+		//		- rows: Integer rows
+		//		- duration: the single flip duration
+		// example:
 		//		See `dojox.fx.flip`
 		var rows = args.rows || 4,
 			cols = args.cols || 4,
diff --git a/dojox/fx/scroll.js b/dojox/fx/scroll.js
index 4ad1110..2474863 100644
--- a/dojox/fx/scroll.js
+++ b/dojox/fx/scroll.js
@@ -3,12 +3,15 @@ define(["dojo/_base/kernel","dojo/_base/lang", "dojo/_base/fx", "dojox/fx/_base"
 	kernel.experimental("dojox.fx.scroll");
 	var fx = lang.getObject("dojox.fx",true);
 	fxExt.smoothScroll = function(/* Object */args){
-		// summary: Returns an animation that will smooth-scroll to a node
-		// description: This implementation support either horizontal or vertical scroll, as well as
-		// both. In addition, element in iframe can be scrolled to correctly.
-		// offset: {x: int, y: int} this will be added to the target position
-		// duration: Duration of the animation in milliseconds.
-		// win: a node or window object to scroll
+		// summary:
+		//		Returns an animation that will smooth-scroll to a node
+		// description:
+		//		This implementation support either horizontal or vertical scroll, as well as
+		//		both. In addition, element in iframe can be scrolled to correctly.
+		// args:
+		//		- offset: {x: int, y: int} this will be added to the target position
+		//		- duration: Duration of the animation in milliseconds.
+		//		- win: a node or window object to scroll
 	
 		if(!args.target){ args.target = domGeom.position(args.node); }
 	
diff --git a/dojox/fx/split.js b/dojox/fx/split.js
index ef93a1d..0cd514b 100644
--- a/dojox/fx/split.js
+++ b/dojox/fx/split.js
@@ -4,19 +4,18 @@ define(["dojo/_base/lang", "dojo/dom", "dojo/_base/window", "dojo/_base/html", "
 var dojoxFx = lang.getObject("dojox.fx");
 lang.mixin(dojoxFx,{
 	_split: function(/*Object*/ args){
-		// summary: Split a node into rectangular pieces and animate them.
-		//
+		// summary:
+		//		Split a node into rectangular pieces and animate them.
 		// description:
 		//		Returns an animation that will split the node into a grid
 		//		of pieces that move independently.
-		//
-		//	args:
-		//		args.crop: Boolean - If true, pieces will only be visible inside node's boundries
-		//		args.rows: Integer - The number of horizontal pieces (default is 3)
-		//		args.columns: Integer - The number of vertical pieces (default is 3)
-		//		args.pieceAnimation: Function(piece, x, y, coords) - Returns either the dojo.Animation
-		//		or an array of dojo.Animation objects for the piece at location (x, y) in the node's grid;
-		//		coords is the result of dojo.coords(args.node, true);
+		// args:
+		//		- args.crop: Boolean - If true, pieces will only be visible inside node's boundries
+		//		- args.rows: Integer - The number of horizontal pieces (default is 3)
+		//		- args.columns: Integer - The number of vertical pieces (default is 3)
+		//		- args.pieceAnimation: Function(piece, x, y, coords) - Returns either the dojo.Animation
+		//		  or an array of dojo.Animation objects for the piece at location (x, y) in the node's grid;
+		//		  coords is the result of dojo.coords(args.node, true);
 
 		args.rows = args.rows || 3;
 		args.columns = args.columns || 3;
@@ -124,24 +123,23 @@ lang.mixin(dojoxFx,{
 	},
 
 	explode: function(/*Object*/ args){
-		// summary: Explode a node into rectangular pieces
-		//
+		// summary:
+		//		Explode a node into rectangular pieces
 		// description:
 		//		Returns an animation that will split the node into a grid
 		//		of pieces that fly away from the center.
-		//
-		//	args:
-		//		args.rows: Integer - The number of horizontal pieces (default is 3)
-		//		args.columns: Integer - The number of vertical pieces (default is 3)
-		//		args.random: Float - If set, pieces fly to random distances, for random durations,
+		// args:
+		//		- args.rows: Integer - The number of horizontal pieces (default is 3)
+		//		- args.columns: Integer - The number of vertical pieces (default is 3)
+		//		- args.random: Float - If set, pieces fly to random distances, for random durations,
 		//							   and in slightly random directions.  The value defines how much
 		//							   randomness is introduced.
-		//		args.distance: Float - Multiplier for the distance the pieces fly (even when random)
-		//		args.fade: Boolean - If true, pieces fade out while in motion (default is true)
-		//		args.fadeEasing: Function - If args.fade is true, the fade animations use this easing function
-		//		args.unhide: Boolean - If true, the animation is reversed
-		//		args.sync: Boolean - If args.unhide is true, all the pieces converge at the same time
-		//							 (default is true)
+		//		- args.distance: Float - Multiplier for the distance the pieces fly (even when random)
+		//		- args.fade: Boolean - If true, pieces fade out while in motion (default is true)
+		//		- args.fadeEasing: Function - If args.fade is true, the fade animations use this easing function
+		//		- args.unhide: Boolean - If true, the animation is reversed
+		//		- args.sync: Boolean - If args.unhide is true, all the pieces converge at the same time
+		//							   (default is true)
 
 		var node = args.node = dom.byId(args.node);
 		args.rows = args.rows || 3;
@@ -245,22 +243,21 @@ lang.mixin(dojoxFx,{
 	},
 
 	disintegrate: function(/*Object*/ args){
-		// summary: Split a node into rectangular pieces and let them fall
-		//
+		// summary:
+		//		Split a node into rectangular pieces and let them fall
 		// description:
 		//		Returns an animation that will split the node into a grid
 		//		of pieces that drop.
-		//
-		//	args:
-		//		args.rows: Integer - The number of horizontal pieces (default is 5)
-		//		args.columns: Integer - The number of vertical pieces (default is 5)
-		//		args.interval: Float - The number of milliseconds between each piece's animation
-		//		args.distance: Float - The number of the node's heights to drop (default is 1.5)
-		//		args.fade: Boolean - If true, pieces fade out while in motion (default is true)
-		//		args.random: Float - If set, pieces fall in random order. The value defines how much
+		// args:
+		//		- args.rows: Integer - The number of horizontal pieces (default is 5)
+		//		- args.columns: Integer - The number of vertical pieces (default is 5)
+		//		- args.interval: Float - The number of milliseconds between each piece's animation
+		//		- args.distance: Float - The number of the node's heights to drop (default is 1.5)
+		//		- args.fade: Boolean - If true, pieces fade out while in motion (default is true)
+		//		- args.random: Float - If set, pieces fall in random order. The value defines how much
 		//							   randomness is introduced.
-		//		args.reverseOrder: Boolean - If true, pieces animate in reversed order
-		//		args.unhide: Boolean - If true, the peices fall from above and land in place
+		//		- args.reverseOrder: Boolean - If true, pieces animate in reversed order
+		//		- args.unhide: Boolean - If true, the peices fall from above and land in place
 		var node = args.node = dom.byId(args.node);
 
 		args.rows = args.rows || 5;
@@ -340,22 +337,21 @@ lang.mixin(dojoxFx,{
 	},
 
 	shear: function(/*Object*/ args){
-		// summary: Split a node into rectangular pieces and slide them in alternating directions
-		//
+		// summary:
+		//		Split a node into rectangular pieces and slide them in alternating directions
 		// description:
 		//		Returns an animation that will split the node into a grid
 		//		of pieces that slide in alternating directions.
-		//
-		//	args:
-		//		args.rows: Integer - The number of horizontal pieces (default is 6)
-		//		args.columns: Integer - The number of vertical pieces (default is 6)
-		//		args.interval: Float - The number of milliseconds between each piece's animation (default is 0)
-		//		args.distance: Float - The multiple of the node's dimensions to slide (default is 1)
-		//		args.fade: Boolean - If true, pieces fade out while in motion (default is true)
-		//		args.random: Float - If true, pieces have a random delay. The value defines how much
+		// args:
+		//		- args.rows: Integer - The number of horizontal pieces (default is 6)
+		//		- args.columns: Integer - The number of vertical pieces (default is 6)
+		//		- args.interval: Float - The number of milliseconds between each piece's animation (default is 0)
+		//		- args.distance: Float - The multiple of the node's dimensions to slide (default is 1)
+		//		- args.fade: Boolean - If true, pieces fade out while in motion (default is true)
+		//		- args.random: Float - If true, pieces have a random delay. The value defines how much
 		//							   randomness is introduced
-		//		args.reverseOrder: Boolean - If true, pieces animate in reversed order
-		//		args.unhide: Boolean - If true, the animation is reversed
+		//		- args.reverseOrder: Boolean - If true, pieces animate in reversed order
+		//		- args.unhide: Boolean - If true, the animation is reversed
 
 		var node = args.node = dom.byId(args.node);
 
@@ -459,21 +455,20 @@ lang.mixin(dojoxFx,{
 	},
 
 	pinwheel: function(/*Object*/ args){
-		// summary: Split a node into rectangular pieces and wipe them in alternating directions
-		//
+		// summary:
+		//		Split a node into rectangular pieces and wipe them in alternating directions
 		// description:
 		//		Returns an animation that will split the node into a grid
 		//		of pieces that wipe in alternating directions.
-		//
-		//	args:
-		//		args.rows: Integer - The number of horizontal pieces (default is 4)
-		//		args.columns: Integer - The number of vertical pieces (default is 4)
-		//		args.interval: Float - The number of milliseconds between each piece's animation (default is 0)
-		//		args.distance: Float - The percentage of the piece's dimensions the piece should wipe
-		//		args.fade: Boolean - If true, pieces fade out while in motion (default is true)
-		//		args.random: Float - If true, pieces have a random delay. The value defines how much
+		// args:
+		//		- args.rows: Integer - The number of horizontal pieces (default is 4)
+		//		- args.columns: Integer - The number of vertical pieces (default is 4)
+		//		- args.interval: Float - The number of milliseconds between each piece's animation (default is 0)
+		//		- args.distance: Float - The percentage of the piece's dimensions the piece should wipe
+		//		- args.fade: Boolean - If true, pieces fade out while in motion (default is true)
+		//		- args.random: Float - If true, pieces have a random delay. The value defines how much
 		//							   randomness is introduced.
-		//		args.unhide: Boolean - If true, the animation is reversed
+		//		- args.unhide: Boolean - If true, the animation is reversed
 
 		var node = args.node = dom.byId(args.node);
 
@@ -593,20 +588,19 @@ lang.mixin(dojoxFx,{
 	},
 
 	blockFadeOut: function(/*Object*/ args){
-		// summary: Split a node into rectangular pieces and fade them
-		//
+		// summary:
+		//		Split a node into rectangular pieces and fade them
 		// description:
 		//		Returns an animation that will split the node into a grid
 		//		of pieces that fade in or out.
-		//
-		//	args:
-		//		args.rows: Integer - The number of horizontal pieces (default is 5)
-		//		args.columns: Integer - The number of vertical pieces (default is 5)
-		//		args.interval: Float - The number of milliseconds between each piece's animation (default is 0)
-		//		args.random: Float - If true, pieces have a random delay. The value defines how much
+		// args:
+		//		- args.rows: Integer - The number of horizontal pieces (default is 5)
+		//		- args.columns: Integer - The number of vertical pieces (default is 5)
+		//		- args.interval: Float - The number of milliseconds between each piece's animation (default is 0)
+		//		- args.random: Float - If true, pieces have a random delay. The value defines how much
 		//							   randomness is introduced
-		//		args.reverseOrder: Boolean - If true, pieces animate in reversed order
-		//		args.unhide: Boolean - If true, the animation is reversed
+		//		- args.reverseOrder: Boolean - If true, pieces animate in reversed order
+		//		- args.unhide: Boolean - If true, the animation is reversed
 
 		var node = args.node = dom.byId(args.node);
 
diff --git a/dojox/fx/style.js b/dojox/fx/style.js
index ab6edfc..7701037 100644
--- a/dojox/fx/style.js
+++ b/dojox/fx/style.js
@@ -2,22 +2,13 @@ define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base
 		"dojo/_base/connect"],
 	function(dojo,lang,baseFx,coreFx,dojoxFx,arrayUtil,dom,domStyle,domClass,connectUtil){
 	dojo.experimental("dojox.fx.style");
-// summary:
-//		dojox.fx CSS Class Animations:
-//
-// description:
-//		a set of functions to animate properties based on
-//		normalized CSS class definitions.
-//
-//	provides: addClass, removeClass, and toggleClass
-//
 		
 
 	var _getStyleSnapshot = function(/* Object */cache){
 		// summary:
 		//		uses a dojo.getComputedStyle(node) cache reference and
-		// 		iterates through the 'documented/supported animate-able'
-		// 		properties.
+		//		iterates through the 'documented/supported animate-able'
+		//		properties.
 		//
 		// returns:  Array
 		//		an array of raw, calculcated values (no keys), to be normalized/compared
@@ -28,15 +19,15 @@ define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base
 	};
 
 	var _getCalculatedStyleChanges = function(node, cssClass, addClass){
-		// summary: Calculate the difference in style properties between two states
+		// summary:
+		//		Calculate the difference in style properties between two states
 		// description:
-		//	calculate and normalize(?) the differences between two states
-		//	of a node (args.node) by quickly adding or removing a class, and
-		//	iterateing over the results of dojox.fx._getStyleSnapshot()
-		//
+		//		calculate and normalize(?) the differences between two states
+		//		of a node (args.node) by quickly adding or removing a class, and
+		//		iterating over the results of dojox.fx._getStyleSnapshot()
 		// addClass:
-		// 	true to calculate what adding a class would do,
-		// 	false to calculate what removing the class would do
+		//		true to calculate what adding a class would do,
+		//		false to calculate what removing the class would do
 
 		node = dom.byId(node);
 		var	cs = domStyle.getComputedStyle(node);
@@ -58,28 +49,28 @@ define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base
 		return calculated;
 	};
 
-	var styleFx = { // Augment dojox.fx for compat
+	var styleFx = {
+		// summary:
+		//		dojox.fx CSS Class Animations
+		// description:
+		//		a set of functions to animate properties based on
+		//		normalized CSS class definitions.
 
 		addClass: function(node, cssClass, args){
 			// summary:
 			//		Animate the effects of adding a class to a node
-			//
 			// description:
 			//		Creates an animation that will animate
 			//		the properties of a node to the properties
 			//		defined in a standard CSS .class definition.
 			//		(calculating the differences itself)
-			//
 			// node: String|DomNode
 			//		A String ID or DomNode referce to animate
-			//
 			// cssClass: String
 			//		The CSS class name to add to the node
-			//
 			// args: Object?
 			//		Additional optional `dojo.animateProperty` arguments, such as
 			//		duration, easing and so on.
-			//
 			// example:
 			//	|
 			//	|	.bar { line-height: 12px; }
@@ -94,12 +85,13 @@ define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base
 			node = dom.byId(node);
 
 			var pushClass = (function(n){
-				// summary: onEnd we want to add the class to the node
-				//	(as dojo.addClass naturally would) in case our
-				//	class parsing misses anything the browser would
-				// 	otherwise interpret. this may cause some flicker,
-				//	and will only apply the class so children can inherit
-				//	after the animation is done (potentially more flicker)
+				// summary:
+				//		onEnd we want to add the class to the node
+				//		(as dojo.addClass naturally would) in case our
+				//		class parsing misses anything the browser would
+				//		otherwise interpret. this may cause some flicker,
+				//		and will only apply the class so children can inherit
+				//		after the animation is done (potentially more flicker)
 				return function(){
 					domClass.add(n, cssClass);
 					n.style.cssText = _beforeStyle;
@@ -118,16 +110,16 @@ define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base
 		},
 	
 		removeClass: function(node, cssClass, args){
-			// summary: Animate the effects of removing a class from a node
+			// summary:
+			//		Animate the effects of removing a class from a node
 			// description:
-			//	Creates an animation that will animate the properties of a
-			// 	node (args.node) to the properties calculated after removing
-			//	a standard CSS className from a that node.
+			//		Creates an animation that will animate the properties of a
+			//		node (args.node) to the properties calculated after removing
+			//		a standard CSS className from a that node.
 			//
-			//	calls dojo.removeClass(args.cssClass) onEnd of animation
-			//
-			//	standard dojo.Animation object rules apply.
+			//		calls dojo.removeClass(args.cssClass) onEnd of animation
 			//
+			//		standard dojo.Animation object rules apply.
 			// example:
 			// |	// animate the removal of "foo" from a node with id="bar"
 			// |	dojox.fx.removeClass("bar", "foo").play()
@@ -135,13 +127,14 @@ define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base
 			node = dom.byId(node);
 
 			var pullClass = (function(n){
-				// summary: onEnd we want to remove the class from the node
-				//	(as dojo.removeClass naturally would) in case our class
-				//	parsing misses anything the browser would otherwise
-				//	interpret. this may cause some flicker, and will only
-				//	apply the class so children can inherit after the
-				//	animation is done (potentially more flicker)
-				//
+				// summary:
+				//		onEnd we want to remove the class from the node
+				//		(as dojo.removeClass naturally would) in case our class
+				//		parsing misses anything the browser would otherwise
+				//		interpret. this may cause some flicker, and will only
+				//		apply the class so children can inherit after the
+				//		animation is done (potentially more flicker)
+
 				return function(){
 					domClass.remove(n, cssClass);
 					n.style.cssText = _beforeStyle;
@@ -161,13 +154,11 @@ define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base
 		toggleClass: function(node, cssClass, condition, args){
 			// summary:
 			//		Animate the effects of Toggling a class on a Node
-			//
 			// description:
 			//		creates an animation that will animate the effect of
 			//		toggling a class on or off of a node.
 			//		Adds a class to node if not present, or removes if present.
 			//		Pass a boolean condition if you want to explicitly add or remove.
-			//
 			// node: String|DomNode
 			//		The domNode (or string of the id) to toggle
 			// cssClass: String
@@ -176,7 +167,6 @@ define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base
 			//		If passed, true means to add the class, false means to remove.
 			// args: Object?
 			//		Additional `dojo.Animation` args to pass along.
-			//
 			// example:
 			// |	// add the class "sampleClass" to a node id="theNode"
 			// |	dojox.fx.toggleClass("theNode","sampleClass",true).play();
@@ -191,11 +181,12 @@ define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/fx","dojo/fx","./_base
 		},
 	
 		_allowedProperties: [
-			// summary: Our pseudo map of properties we will check for.
+			// summary:
+			//		Our pseudo map of properties we will check for.
 			// description:
-			//	it should be much more intuitive. a way to normalize and
-			//	"predict" intent, or even something more clever ...
-			//	open to suggestions.
+			//		it should be much more intuitive. a way to normalize and
+			//		"predict" intent, or even something more clever ...
+			//		open to suggestions.
 
 			// no-brainers:
 			"width",
diff --git a/dojox/fx/tests/example_Line.html b/dojox/fx/tests/example_Line.html
index 0e2ba25..3b8107f 100644
--- a/dojox/fx/tests/example_Line.html
+++ b/dojox/fx/tests/example_Line.html
@@ -19,7 +19,7 @@
 		}
 	</style>
 	<script type="text/javascript"
-	        djConfig="parseOnLoad: true, isDebug:false"
+	        data-dojo-config="parseOnLoad: true, isDebug:false"
 	        src="../../../dojo/dojo.js"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
diff --git a/dojox/fx/tests/example_backgroundPosition.html b/dojox/fx/tests/example_backgroundPosition.html
index 45dd5c3..7071715 100644
--- a/dojox/fx/tests/example_backgroundPosition.html
+++ b/dojox/fx/tests/example_backgroundPosition.html
@@ -4,7 +4,7 @@
 <head>
 	<title>Animated background position example | The Dojo Toolkit</title>
 		
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/dijit.css";
diff --git a/dojox/fx/tests/example_dojoAnimations.html b/dojox/fx/tests/example_dojoAnimations.html
index c8cf6e1..c5506c5 100644
--- a/dojox/fx/tests/example_dojoAnimations.html
+++ b/dojox/fx/tests/example_dojoAnimations.html
@@ -79,7 +79,7 @@
 	</style>
 	
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad:true, isDebug:true"></script>
+		data-dojo-config="parseOnLoad:true, isDebug:true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
@@ -112,7 +112,7 @@
 	
 	<button dojoType="dijit.form.Button">
 		Fade In/Out
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.fadeOut({ node:"testSlide",
 				onEnd:function(){
 					dojo.fadeIn({ node:"testSlide", delay:300 }).play();	
@@ -123,7 +123,7 @@
 	
 	<button dojoType="dijit.form.Button">
 		animateProperty: height
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.animateProperty({
 				node:"testSlide",
 				properties:{ height:{ end:1 } },
@@ -140,7 +140,7 @@
 	
 	<button dojoType="dijit.form.Button">
 		animateProperty: width
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.animateProperty({
 				node:"testSlide",
 				properties:{ width:1 },
@@ -166,7 +166,7 @@
 	
 	<button dojoType="dijit.form.Button">
 		marginLeft
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.animateProperty({
 				node:"lorem",
 				properties:{
@@ -187,7 +187,7 @@
 	
 	<button dojoType="dijit.form.Button">
 		left / paddingTop
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.animateProperty({
 				node:"lorem",
 				properties:{
@@ -213,7 +213,7 @@
 	
 	<button dojoType="dijit.form.Button">
 		fontSize / width
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.animateProperty({
 				node:"lorem",
 				properties:{
@@ -250,7 +250,7 @@
 
 	<button dojoType="dijit.form.Button">
 		Slide
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			// we're 175px, slide to containerWidth - 195
 			var left = dojo.marginBox("testSlideWrapper").w - 195;
 			// make and play the animation
@@ -268,7 +268,7 @@
 
 	<button dojoType="dijit.form.Button">
 		Combine Slide / Fade
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			var anim1 = dojo.fx.slideTo({
 				top: 10,
 				left: dojo.marginBox("testSlideWrapper").w - 195,
@@ -292,7 +292,7 @@
 	
 	<button dojoType="dijit.form.Button">
 		Chain (4)
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			var anim1 = dojo.fadeOut({ node:"testSlideToo",
 				// so anim1 is over, making this onEnd and anim2 basically
 				// a combine() (depending on the duration: )
@@ -325,7 +325,7 @@
 	
 	<button dojoType="dijit.form.Button">
 		fade .even
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.query(".even","queryUl").fadeOut({
 				onEnd:function(){
 					dojo.query(".even","queryUl").fadeIn({ delay: 300 }).play();	
@@ -336,7 +336,7 @@
 
 	<button dojoType="dijit.form.Button">
 		fade .odd
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.query(".odd","queryUl").fadeOut({
 				onEnd:function(){
 					dojo.query(".odd","queryUl").fadeIn({ delay: 300 }).play();	
@@ -347,7 +347,7 @@
 	
 	<button dojoType="dijit.form.Button">
 		shift .odd
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.query(".odd","queryUl").animateProperty({
 				properties:{
 					marginLeft:34
@@ -367,7 +367,7 @@
 
 	<button dojoType="dijit.form.Button">
 		mmm, easing
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.query(".odd","queryUl").animateProperty({
 				easing:dojo.fx.easing.backOut,
 				properties:{
@@ -390,7 +390,7 @@
 	
 	<button dojoType="dijit.form.Button">
 		Setup FisheyeList
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			this.setAttribute("disabled",true);
 			dojo.query("li","fisheyeList").forEach(function(n){
 				new dojox.widget.FisheyeLite({
diff --git a/dojox/fx/tests/example_easingChart2D.html b/dojox/fx/tests/example_easingChart2D.html
index 45f03cf..272db07 100644
--- a/dojox/fx/tests/example_easingChart2D.html
+++ b/dojox/fx/tests/example_easingChart2D.html
@@ -17,7 +17,7 @@
 	}
 	</style>
 	
-	<script type="text/javascript" djConfig="isDebug:false, parseOnLoad: true"
+	<script type="text/javascript" data-dojo-config="isDebug:false, parseOnLoad: true"
 		src="../../../dojo/dojo.js"></script>
 
 	<script type="text/javascript">
diff --git a/dojox/fx/tests/test_Nodelist-fx.html b/dojox/fx/tests/test_Nodelist-fx.html
index 573860b..0d6eb77 100644
--- a/dojox/fx/tests/test_Nodelist-fx.html
+++ b/dojox/fx/tests/test_Nodelist-fx.html
@@ -4,7 +4,7 @@
 <head>
 	<title>dojo.NodeList-fx and dojox.fx.ext-dojo.Nodelist | fx add-ons to dojo.query()</title>
 		
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:true, isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, isDebug:true"></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/dijit.css";
@@ -198,7 +198,7 @@
 			<label for="g2rb8">.fadeTo (35% opacity)</label><br>
 
 		</p>
-		<script type="dojo/method" event="onSubmit">
+		<script type="dojo/method" data-dojo-event="onSubmit">
 			// it's like cheating, but we don't event want this form to submit. you can type
 			// a query(), use the arrows to select a method, and hit enter. (or should be able to)
 			return false; 
@@ -206,7 +206,7 @@
 
 		<button dojoType="dijit.form.Button" type="submit" id="runnerButton" >
 			Run
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				// our runner / submit button				
 				var str = dojo.byId("customStr").value;
 				var animType;
diff --git a/dojox/fx/tests/test_Shadow.html b/dojox/fx/tests/test_Shadow.html
index b20bbac..a0af14f 100644
--- a/dojox/fx/tests/test_Shadow.html
+++ b/dojox/fx/tests/test_Shadow.html
@@ -4,7 +4,7 @@
 <head>
 	<title>dojox.fx.Shadow - Drop Shadows for DomNodes | The Dojo Toolkit</title>
 		
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/dijit.css";
diff --git a/dojox/fx/tests/test_Timeline.html b/dojox/fx/tests/test_Timeline.html
index 0c55eaf..6012702 100644
--- a/dojox/fx/tests/test_Timeline.html
+++ b/dojox/fx/tests/test_Timeline.html
@@ -49,7 +49,7 @@
 		}
 	</style>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 		<script>
 			dojo.require("dojox.fx.ext-dojo.reverse");
 			dojo.require("dojox.fx.Timeline");
diff --git a/dojox/fx/tests/test_animateClass.html b/dojox/fx/tests/test_animateClass.html
index 025a5c4..f1e5e10 100644
--- a/dojox/fx/tests/test_animateClass.html
+++ b/dojox/fx/tests/test_animateClass.html
@@ -13,7 +13,7 @@
 	</style>
 		
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true" ></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 			
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
@@ -38,21 +38,21 @@
 
 	<button dojoType="dijit.form.Button">
 			spacing test
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				dojo.query("li.baseFont").toggleClassFx("spacedHorizontal").play(5);
 			</script>
 	</button>
 
 	<button dojoType="dijit.form.Button">
 			line-height test
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				dojo.query("li.baseFont").toggleClassFx("spacedVertical").play(5);
 			</script>
 	</button>
 
 	<button dojoType="dijit.form.Button">
 			font-size test
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				dojo.query("li.baseFont").toggleClassFx("fontSizeTest").play(5);
 			</script>
 	</button>
@@ -61,7 +61,7 @@
 
 	<button dojoType="dijit.form.Button" id="addTall">
 		add .tall
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 				var delay = 500;
 				var _anims = [];
 				dojo.query("#colorTest > .testBox").forEach(function(n){
@@ -77,7 +77,7 @@
 	</button>
 	<button dojoType="dijit.form.Button" id="removeTall" disabled="true">
 		remove .tall
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 				var delay = 500;
 				var _anims = [];
 				dojo.query("#colorTest > .testBox").forEach(function(n){
@@ -93,7 +93,7 @@
 	</button>		 
 	<button dojoType="dijit.form.Button" id="addWide">
 		add .wide
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 				var delay = 500;
 				var _anims = [];
 				dojo.query("#colorTest > .testBox").forEach(function(n){
@@ -109,7 +109,7 @@
 	</button>
 	<button dojoType="dijit.form.Button" id="removeWide" disabled="true">
 		remove .wide
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 				var delay = 500;
 				var _anims = [];
 				dojo.query("#colorTest > .testBox").forEach(function(n){
@@ -125,7 +125,7 @@
 	</button>
 	<button dojoType="dijit.form.Button">
 		toggle .tiny
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 				var _anims = [];
 				// until dojox.fx.NodeList-fx is ready:
 				dojo.query("#colorTest > .testBox").forEach(function(node){
@@ -137,13 +137,13 @@
 
 	<button dojoType="dijit.form.Button">
 		query add tall
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.query("#colorTest > .testBox").addClassFx("tall").play();
 		</script>		
 	</button>
 	<button dojoType="dijit.form.Button">
 		query remove tall
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			dojo.query("#colorTest > .testBox").removeClassFx("tall").play();
 		</script>
 	</button>
@@ -166,19 +166,19 @@
 	
 	<button dojoType="dijit.form.Button">
 		.offsetSome
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 				dojox.fx.toggleClass("positionTest","offsetSome").play();		 
 		</script>
 	</button>
 	<button dojoType="dijit.form.Button">
 		.topLeft
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 				dojox.fx.toggleClass("positionTest","topLeft").play();		  
 		</script>
 	</button>
 	<button dojoType="dijit.form.Button">
 		.bottomRight
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 				dojox.fx.toggleClass("positionTest","bottomRight").play();		  
 		</script>
 	</button>
@@ -189,19 +189,19 @@
 			
 	<button dojoType="dijit.form.Button">
 		toggle .green
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 				dojox.fx.toggleClass("positionTest","green").play();
 		</script>
 	</button>
 	<button dojoType="dijit.form.Button">
 		toggle .black
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 				dojox.fx.toggleClass("positionTest","black").play();
 		</script>
 	</button>
 	<button dojoType="dijit.form.Button">
 		toggle .blue
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 				dojox.fx.toggleClass("positionTest","blue").play();
 		</script>
 	</button>
diff --git a/dojox/fx/tests/test_complex.html b/dojox/fx/tests/test_complex.html
index 33b5a45..5ce5dbc 100644
--- a/dojox/fx/tests/test_complex.html
+++ b/dojox/fx/tests/test_complex.html
@@ -33,7 +33,7 @@
 			white-space:nowrap;
 		}
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 		<script>
 			dojo.require("dojox.fx.ext-dojo.complex");
 			
diff --git a/dojox/fx/tests/test_crossFade.html b/dojox/fx/tests/test_crossFade.html
index 330a34a..c812401 100644
--- a/dojox/fx/tests/test_crossFade.html
+++ b/dojox/fx/tests/test_crossFade.html
@@ -4,7 +4,7 @@
 <head>
 	<title>dojox.fx - animation sets to use!</title>
 		
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 	<script type="text/javascript" src="../_base.js"></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/fx/tests/test_easing.html b/dojox/fx/tests/test_easing.html
index b96e94d..7fa9ce7 100644
--- a/dojox/fx/tests/test_easing.html
+++ b/dojox/fx/tests/test_easing.html
@@ -4,7 +4,7 @@
 <head>
 	<title>dojox.fx.easing functions:</title>
 		
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/dijit.css";
diff --git a/dojox/fx/tests/test_flip.html b/dojox/fx/tests/test_flip.html
index f626500..a2e4fa6 100644
--- a/dojox/fx/tests/test_flip.html
+++ b/dojox/fx/tests/test_flip.html
@@ -4,7 +4,7 @@
 <head>
 	<title>dojox.fx.flip | experimental fx add-ons for the Dojo Toolkit</title>
 		
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/tundra/tundra.css";
diff --git a/dojox/fx/tests/test_highlight.html b/dojox/fx/tests/test_highlight.html
index 1d5947e..1bee35b 100644
--- a/dojox/fx/tests/test_highlight.html
+++ b/dojox/fx/tests/test_highlight.html
@@ -3,7 +3,7 @@
 <html>
 <head>
 	<title>dojox.fx.highlight</title>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 	<script type="text/javascript">	
 		dojo.require("dojox.fx");
 		dojo.require("dojox.fx.ext-dojo.NodeList"); 
diff --git a/dojox/fx/tests/test_reverse.html b/dojox/fx/tests/test_reverse.html
index 941e455..df4dcab 100644
--- a/dojox/fx/tests/test_reverse.html
+++ b/dojox/fx/tests/test_reverse.html
@@ -35,7 +35,7 @@
 		
 	</style>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 		<script>
 			dojo.require("dojox.fx.ext-dojo.reverse");
 			dojo.addOnLoad(function(){
diff --git a/dojox/fx/tests/test_scroll.html b/dojox/fx/tests/test_scroll.html
index a04e799..f756d4f 100644
--- a/dojox/fx/tests/test_scroll.html
+++ b/dojox/fx/tests/test_scroll.html
@@ -3,7 +3,7 @@
 <html>
 <head>
 	<title>dojox.fx.scroll</title>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 	<style type="text/css">
 		@import "../../../dijit/themes/tundra.css";
 		@import "../../../dijit/tests/css/dijitTests.css";
diff --git a/dojox/fx/tests/test_sizeTo.html b/dojox/fx/tests/test_sizeTo.html
index 2b7b19a..846015f 100644
--- a/dojox/fx/tests/test_sizeTo.html
+++ b/dojox/fx/tests/test_sizeTo.html
@@ -4,7 +4,7 @@
 <head>
 	<title>dojox.fx.sizeTo | experimental fx add-ons for the Dojo Toolkit</title>
 		
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/dijit.css";
diff --git a/dojox/fx/tests/test_slideBy.html b/dojox/fx/tests/test_slideBy.html
index a1a1960..711e0ed 100644
--- a/dojox/fx/tests/test_slideBy.html
+++ b/dojox/fx/tests/test_slideBy.html
@@ -4,7 +4,7 @@
 <head>
 	<title>dojox.fx - animation sets to use!</title>
 		
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 	<script type="text/javascript" src="../_base.js"></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
diff --git a/dojox/fx/tests/test_split.html b/dojox/fx/tests/test_split.html
index a631478..4f4d974 100644
--- a/dojox/fx/tests/test_split.html
+++ b/dojox/fx/tests/test_split.html
@@ -6,7 +6,7 @@
 
 	<link rel="stylesheet" href="../../../dijit/tests/css/dijitTests.css" />
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:true, isDebug:false"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, isDebug:false"></script>
 		
 	<script type="text/javascript">
 		dojo.require("dojox.fx.split");
diff --git a/dojox/fx/tests/test_text.html b/dojox/fx/tests/test_text.html
index ee161cd..e850321 100644
--- a/dojox/fx/tests/test_text.html
+++ b/dojox/fx/tests/test_text.html
@@ -6,7 +6,7 @@
 	<link rel="stylesheet" href="../../../dijit/tests/css/dijitTests.css" />
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad:true, isDebug:false"></script>
+		data-dojo-config="parseOnLoad:true, isDebug:false"></script>
 		
 	<script type="text/javascript">
 		dojo.require("dojox.fx.text");
diff --git a/dojox/fx/tests/test_wipeTo.html b/dojox/fx/tests/test_wipeTo.html
index 109edb8..7877d2e 100644
--- a/dojox/fx/tests/test_wipeTo.html
+++ b/dojox/fx/tests/test_wipeTo.html
@@ -4,7 +4,7 @@
 <head>
 	<title>dojox.fx.wipeTo | experimental fx add-ons for the Dojo Toolkit</title>
 		
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/themes/dijit.css";
@@ -58,31 +58,31 @@
 
 		<button dojoType="dijit.form.Button">
 			wipeTo width: 400
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				delayAnims({ width: 400 });
 			</script>
 		</button>
 		<button dojoType="dijit.form.Button">
 			wipeTo width: 100
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				delayAnims({ width: 100 });
 			</script>
 		</button>
 		<button dojoType="dijit.form.Button">
 			wipeTo height: 400
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				delayAnims({ height: 400 });
 			</script>
 		</button>
 		<button dojoType="dijit.form.Button">
 			wipeTo height: 25
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				delayAnims({ height: 25 });
 			</script>
 		</button>
 		<button dojoType="dijit.form.Button">
 			wipeTo height: 100
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				delayAnims({ height: 100 });
 			</script>
 		</button>
diff --git a/dojox/fx/text.js b/dojox/fx/text.js
index 2079441..3a94e9e 100644
--- a/dojox/fx/text.js
+++ b/dojox/fx/text.js
@@ -2,25 +2,25 @@ define(["dojo/_base/lang", "./_base", "dojo/_base/fx", "dojo/fx","dojo/fx/easing
 function(lang, dojoxFx, baseFx, coreFx, easingLib, dom, domStyle, htmlLib, connectUtil ){
 var textFx = lang.getObject("dojox.fx.text", true);
 textFx._split = function(/*Object*/ args){
-	// summary: Split a block of text into words or letters
-	//
+	// summary:
+	//		Split a block of text into words or letters
 	// description:
 	//		Returns an animation that will split the node into a grid
 	//		of pieces that move independently.
 	//
-	// NOTE:
+	//		NOTE:
 	//		In some rendering engines, the text will appear to "jump" from its initial position
-	//		when the animation begins.	To work around this bug, enclose the node's text in a <p> or <div>.
-	//
-	//	args:
-	//		args.crop: Boolean - If true, pieces will be positioned relatively rather than absolutely
-	//		args.text: String - Text to place inside the node (otherwise node.innerHTML is used)
-	//		args.words: Boolean - If true, the text will be split into words rather than characters
-	//		args.pieceAnimation: Function(piece, pieceCoords, nodeCoords, number, numPieces)
-	//			- Returns either the dojo.Animation or an array of dojo.Animation objects for the piece;
-	//			pieceCoords is the result of dojo.coords(piece, true);
-	//			nodeCoords is the result of dojo.coords(args.node, true);
-	//			number is the piece's position in the array of pieces, and numPieces is the array.length
+	//		when the animation begins.	To work around this bug, enclose the node's text in a `<p>` or `<div>`.
+	// args:
+	//		- args.crop: Boolean - If true, pieces will be positioned relatively rather than absolutely
+	//		- args.text: String - Text to place inside the node (otherwise node.innerHTML is used)
+	//		- args.words: Boolean - If true, the text will be split into words rather than characters
+	//		- args.pieceAnimation: Function(piece, pieceCoords, nodeCoords, number, numPieces)
+	//			Returns either the dojo.Animation or an array of dojo.Animation objects for the piece.
+	//			The arguments:
+	//			- pieceCoords is the result of dojo.coords(piece, true);
+	//			- nodeCoords is the result of dojo.coords(args.node, true);
+	//			- number is the piece's position in the array of pieces, and numPieces is the array.length
 
 	var node = args.node = dom.byId(args.node),
 		s = node.style,
@@ -115,24 +115,23 @@ textFx._split = function(/*Object*/ args){
 };
 
 textFx.explode = function(/*Object*/ args){
-	// summary: Explode a block of text into words or letters
-	//
+	// summary:
+	//		Explode a block of text into words or letters
 	// description:
 	//		Returns an animation that will split the text into a spans
 	//		of words or characters that fly away from the center.
-	//
-	//	args:
-	//		args.crop: Boolean - If true, pieces will be positioned relatively rather than absolutely
-	//		args.words: Boolean - If true, text will be split into words rather than characters
-	//		args.random: Float - If set, pieces fly to random distances, for random durations,
+	// args:
+	//		- args.crop: Boolean - If true, pieces will be positioned relatively rather than absolutely
+	//		- args.words: Boolean - If true, text will be split into words rather than characters
+	//		- args.random: Float - If set, pieces fly to random distances, for random durations,
 	//							   and in slightly random directions. The value defines how much
 	//							   randomness is introduced.
-	//		args.distance: Float - Multiplier for the distance the pieces fly (even when random)
-	//		args.fade: Boolean - If true, pieces fade out while in motion (default is true)
-	//		args.fadeEasing: Function - If args.fade is true, the fade animations use this easing function
-	//		args.unhide: Boolean - If true, the animation is reversed
-	//		args.sync: Boolean - If args.unhide is true, all the pieces converge at the same time
-	//							 (default is true)
+	//		- args.distance: Float - Multiplier for the distance the pieces fly (even when random)
+	//		- args.fade: Boolean - If true, pieces fade out while in motion (default is true)
+	//		- args.fadeEasing: Function - If args.fade is true, the fade animations use this easing function
+	//		- args.unhide: Boolean - If true, the animation is reversed
+	//		- args.sync: Boolean - If args.unhide is true, all the pieces converge at the same time
+	//							   (default is true)
 
 	var node = args.node = dom.byId(args.node);
 	var s = node.style;
@@ -227,22 +226,21 @@ textFx.converge = function(/*Object*/ args){
 };
 
 textFx.disintegrate = function(/*Object*/ args){
-	// summary: Split a block of text into words or letters and let them fall
-	//
+	// summary:
+	//		Split a block of text into words or letters and let them fall
 	// description:
 	//		Returns an animation that will split the text into spans of words
 	//		or characters that drop.
-	//
-	//	args:
-	//		args.crop: Boolean - If true, pieces will be positioned relatively rather than absolutely
-	//		args.words: Boolean - If true, text will be split into words rather than characters
-	//		args.interval: Float - The number of milliseconds between each piece's animation
-	//		args.distance: Float - The number of the node's heights to drop (default is 1.5)
-	//		args.fade: Boolean - If true, pieces fade out while in motion (default is true)
-	//		args.random: Float - If set, pieces fall in random order. The value defines how much
+	// args:
+	//		- args.crop: Boolean - If true, pieces will be positioned relatively rather than absolutely
+	//		- args.words: Boolean - If true, text will be split into words rather than characters
+	//		- args.interval: Float - The number of milliseconds between each piece's animation
+	//		- args.distance: Float - The number of the node's heights to drop (default is 1.5)
+	//		- args.fade: Boolean - If true, pieces fade out while in motion (default is true)
+	//		- args.random: Float - If set, pieces fall in random order. The value defines how much
 	//							   randomness is introduced
-	//		args.reverseOrder: Boolean - If true, pieces animate in reversed order
-	//		args.unhide: Boolean - If true, the peices fall from above and land in place
+	//		- args.reverseOrder: Boolean - If true, pieces animate in reversed order
+	//		- args.unhide: Boolean - If true, the peices fall from above and land in place
 
 	var node = args.node = dom.byId(args.node);
 	var s = node.style;
@@ -314,19 +312,18 @@ textFx.build = function(/*Object*/ args){
 };
 
 textFx.blockFadeOut = function(/*Object*/ args){
-	// summary: Split a block of text into words or letters and fade them
-	//
+	// summary:
+	//		Split a block of text into words or letters and fade them
 	// description:
 	//		Returns an animation that will split the text into spans of words
 	//		or characters that fade in or out.
-	//
-	//	args:
-	//		args.words: Boolean - If true, text will be split into words rather than characters
-	//		args.interval: Float - The number of milliseconds between each piece's animation (default is 0)
-	//		args.random: Float - If true, pieces have a random delay. The value defines how much
+	// args:
+	//		- args.words: Boolean - If true, text will be split into words rather than characters
+	//		- args.interval: Float - The number of milliseconds between each piece's animation (default is 0)
+	//		- args.random: Float - If true, pieces have a random delay. The value defines how much
 	//							   randomness is introduced
-	//		args.reverseOrder: Boolean - If true, pieces animate in reversed order
-	//		args.unhide: Boolean - If true, the animation is reversed
+	//		- args.reverseOrder: Boolean - If true, pieces animate in reversed order
+	//		- args.unhide: Boolean - If true, the animation is reversed
 
 	var node = args.node = dom.byId(args.node);;
 	var s = node.style;
@@ -371,22 +368,21 @@ textFx.blockFadeIn = function(/*Object*/ args){
 };
 
 textFx.backspace = function(/*Object*/ args){
-	// summary: Split a block of text into words or letters and backspace them in sequence
-	//
+	// summary:
+	//		Split a block of text into words or letters and backspace them in sequence
 	// description:
 	//		Returns an animation that will split the text into spans of words
 	//		or characters that appear as if they were being backspaced (or typed) in real-time.
-	//
-	//	args:
-	//		args.interval: Float - The number of milliseconds between each piece's animation
-	//							   (default is determined by text length and args.duration);
-	//		args.wordDelay: Integer - The number of milliseconds between each word
-	//								  (only effective when args.unhide = true)
-	//		args.fixed: Boolean - If true, only style.opacity changes; otherwise, style.display
-	//							  changes between none and inline, adding realism (default = false)
-	//		args.random: Float - If true, pieces have a random delay. The value defines how much
-	//							   randomness is introduced (only effective when args.unhide = true)
-	//		args.unhide: Boolean - If true, the animation is reversed
+	// args:
+	//		- args.interval: Float - The number of milliseconds between each piece's animation
+	//		  (default is determined by text length and args.duration);
+	//		- args.wordDelay: Integer - The number of milliseconds between each word
+	//		  (only effective when args.unhide = true)
+	//		- args.fixed: Boolean - If true, only style.opacity changes; otherwise, style.display
+	//		  changes between none and inline, adding realism (default = false)
+	//		- args.random: Float - If true, pieces have a random delay. The value defines how much
+	//		  randomness is introduced (only effective when args.unhide = true)
+	//		- args.unhide: Boolean - If true, the animation is reversed
 
 	var node = args.node = dom.byId(args.node);
 	var s = node.style;
@@ -459,4 +455,4 @@ textFx.type = function(/*Object*/ args){
 	return textFx.backspace(args);
 };
 return textFx;
-});
\ No newline at end of file
+});
diff --git a/dojox/gantt/GanttChart.js b/dojox/gantt/GanttChart.js
index cff3fd6..32a451f 100644
--- a/dojox/gantt/GanttChart.js
+++ b/dojox/gantt/GanttChart.js
@@ -1,13 +1,36 @@
-dojo.provide("dojox.gantt.GanttChart");
-
-dojo.require("dijit.Tooltip");
-dojo.require("dojox.gantt.GanttProjectItem");
-dojo.require("dojox.gantt.GanttResourceItem");
-dojo.require("dojox.gantt.TabMenu");
-dojo.require("dojo.date.locale");
-
-(function(){
-	dojo.declare("dojox.gantt.GanttChart", null, {
+// FIXME: documentation
+define([
+    "./GanttProjectItem",
+    "./GanttResourceItem",
+    "./GanttProjectControl",
+    "./GanttTaskControl",
+    "./GanttTaskItem",
+    "./TabMenu",
+    "dijit/Tooltip",
+    "dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+    "dojo/date/locale",
+	"dojo/request",
+	"dojo/request/util",
+	"dojo/on",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dojo/dom-attr",
+	"dojo/dom-geometry",
+	"dojo/keys",
+	"dojo/has",
+	"dojo/_base/window",
+	"dojo/json",
+	"dojo/domReady!"
+], function(GanttProjectItem, GanttResourceItem, GanttProjectControl, 
+		GanttTaskControl, GanttTaskItem, TabMenu,
+		Tooltip, 
+		declare, arrayUtil, lang, locale, request, util, on,
+		dom, domClass, domConstruct, domStyle, domAttr, domGeometry, keys, has, win, JSON){
+	return declare("dojox.gantt.GanttChart", [], {
 		constructor: function(configuration, node){
 			this.resourceChartHeight = configuration.resourceChartHeight !== undefined ? configuration.resourceChartHeight : false;
 			this.withResource = configuration.withResource !== undefined ? configuration.withResource : true;
@@ -19,7 +42,7 @@ dojo.require("dojo.date.locale");
 			this.dataFilePath = configuration.dataFilePath  || "gantt_default.json";
 			this.contentHeight = configuration.height || 400;
 			this.contentWidth = configuration.width || 600;
-			this.content = dojo.byId(node);
+			this.content = dom.byId(node);
 			this.scrollBarWidth = 18;
 			this.panelTimeHeight = 102;
 			this.maxWidthPanelNames = 150;
@@ -55,11 +78,11 @@ dojo.require("dojo.date.locale");
 			this.scale = 1;
 			this.tempDayInPixels = 0;
 			this.resource = null;
-			this.months = dojo.date.locale.getNames("months", "wide");
+			this.months = locale.getNames("months", "wide");
 			this._events = [];
 		},
 		getProject: function(id){
-			return dojo.filter(this.arrProjects, function(proj){
+			return arrayUtil.filter(this.arrProjects, function(proj){
 				return proj.project.id == id;
 			}, this)[0];
 		},
@@ -67,14 +90,12 @@ dojo.require("dojo.date.locale");
 			var widthPred = this.getWidthOnDuration(predTask.duration);
 			var posPred = this.getPosOnDate(predTask.startTime);
 			var posChild = this.getPosOnDate(task.startTime);
-			if((widthPred + posPred) > posChild){
-				return false;
-			}
-			return true;
+			return (widthPred + posPred) <= posChild;
+
 		},
 		correctPosPreviousTask: function(predTask, ctask, ctaskObj){
 			var newDate = new Date(predTask.startTime);
-			newDate.setHours(newDate.getHours() + (predTask.duration / this.hsPerDay * 24))
+			newDate.setHours(newDate.getHours() + (predTask.duration / this.hsPerDay * 24));
 			if(newDate.getHours() > 0){
 				newDate.setHours(0);
 				newDate.setDate(newDate.getDate() + 1);
@@ -83,7 +104,7 @@ dojo.require("dojo.date.locale");
 			if(ctask.parentTask){
 				if(!this.checkPosParentTask(ctask.parentTask, ctask)){
 					var newDate2 = new Date(ctask.parentTask.startTime);
-					newDate2.setHours(newDate2.getHours() + (ctask.parentTask.duration / this.hsPerDay * 24))
+					newDate2.setHours(newDate2.getHours() + (ctask.parentTask.duration / this.hsPerDay * 24));
 					ctask.duration = parseInt((parseInt((newDate2 - ctask.startTime) / (1000 * 60 * 60))) * this.hsPerDay / 24);
 				}
 			}
@@ -197,7 +218,7 @@ dojo.require("dojo.date.locale");
 				}
 				var rowHeight = this.heightTaskItemExtra + this.heightTaskItem;
 				project.nextProject && project.shiftNextProject(project, -rowHeight); //rowHeight: 23
-				this.project = dojo.filter(this.project, function(proj){
+				this.project = arrayUtil.filter(this.project, function(proj){
 					return proj.id != project.project.id;
 				}, this);
 				if((project.previousProject) && (project.nextProject)){
@@ -224,13 +245,13 @@ dojo.require("dojo.date.locale");
 				if(this.project.length == 0){
 					var d = new Date(this.startDate);
 					var t = new Date(d.setDate(d.getDate() + 1));
-					var pi = new dojox.gantt.GanttProjectItem({
+					var pi = new GanttProjectItem({
 						id: 1,
 						name: "New Project",
 						startDate: t
 					});
 					this.project.push(pi);
-					var project = new dojox.gantt.GanttProjectControl(this, pi);
+					var project = new GanttProjectControl(this, pi);
 					project.create();
 					this.arrProjects.push(project);
 					this.contentDataHeight += this.heightTaskItemExtra + this.heightTaskItem;
@@ -246,13 +267,13 @@ dojo.require("dojo.date.locale");
 				return false;
 			}
 			this.checkHeighPanelTasks();
-			var project = new dojox.gantt.GanttProjectItem({
+			var project = new GanttProjectItem({
 				id: id,
 				name: name,
 				startDate: startDate
 			});
 			this.project.push(project);
-			var _project = new dojox.gantt.GanttProjectControl(this, project);
+			var _project = new GanttProjectControl(this, project);
 			for(var i = 0; i < this.arrProjects.length; i++){
 				var curProject = this.arrProjects[i],
 					preProject = this.arrProjects[i-1],
@@ -292,8 +313,8 @@ dojo.require("dojo.date.locale");
 		},
 		openNode: function(parentTask){
 			if(!parentTask.isExpanded){
-				dojo.removeClass(parentTask.cTaskNameItem[2], "ganttImageTreeExpand");
-				dojo.addClass(parentTask.cTaskNameItem[2], "ganttImageTreeCollapse");
+				domClass.remove(parentTask.cTaskNameItem[2], "ganttImageTreeExpand");
+				domClass.add(parentTask.cTaskNameItem[2], "ganttImageTreeCollapse");
 				parentTask.isExpanded = true;
 				parentTask.shiftCurrentTasks(parentTask, parentTask.hideTasksHeight);
 				parentTask.showChildTasks(parentTask, parentTask.isExpanded);
@@ -313,7 +334,7 @@ dojo.require("dojo.date.locale");
 			}
 		},
 		getProjectItemById: function(id){
-			return dojo.filter(this.project, function(proj){
+			return arrayUtil.filter(this.project, function(proj){
 				return proj.id == id;
 			}, this)[0];
 		},
@@ -325,7 +346,9 @@ dojo.require("dojo.date.locale");
 			this.clearEvents();
 		},
 		clearEvents: function(){
-			dojo.forEach(this._events, dojo.disconnect);
+			arrayUtil.forEach(this._events, function(e){
+				e.remove();
+			});
 			this._events = [];
 		},
 		clearData: function(){
@@ -368,7 +391,7 @@ dojo.require("dojo.date.locale");
 			
 			for(var i = 0; i < this.project.length; i++){
 				var proj = this.project[i];
-				var project = new dojox.gantt.GanttProjectControl(this, proj);
+				var project = new GanttProjectControl(this, proj);
 				if(this.arrProjects.length > 0){
 					var previousProject = this.arrProjects[this.arrProjects.length - 1];
 					project.previousProject = previousProject;
@@ -386,44 +409,41 @@ dojo.require("dojo.date.locale");
 		loadJSONData: function(filename){
 			var _this = this;
 			_this.dataFilePath = filename || _this.dataFilePath;
-			dojo.xhrGet({
-				url: _this.dataFilePath,
-				sync: true,
-				load: function(text, ioArgs){
-					_this.loadJSONString(text);
-					_this.buildUIContent();
-					alert("Successfully! Loaded data from: " + _this.dataFilePath);
-				},
-				error: function(err, ioArgs){
-					alert("Failed! Load error: " + _this.dataFilePath);
-				}
+			request.get(_this.dataFilePath, {
+				sync: true
+			}).then(function(response){
+				_this.loadJSONString(response.text);
+				_this.buildUIContent();
+				console.log("Successfully! Loaded data from: " + _this.dataFilePath);
+			}, function(){
+				console.log("Failed! Load error: " + _this.dataFilePath);
 			});
 		},
 		loadJSONString: function(content){
 			//load data
 			if(!content){ return; }
 			this.clearAll();
-			var jsonObj = dojo.fromJson(content);
+			var jsonObj = JSON.parse(content);
 			
 			var items = jsonObj.items;
-			dojo.forEach(items, function(pItem){
+			arrayUtil.forEach(items, function(pItem){
 				var startDate = pItem.startdate.split("-");
-				var project = new dojox.gantt.GanttProjectItem({
+				var project = new GanttProjectItem({
 					id: pItem.id,
 					name: pItem.name,
 					startDate: new Date(startDate[0], (parseInt(startDate[1]) - 1), startDate[2])
 				});
 				var tItems = pItem.tasks;
-				dojo.forEach(tItems, function(tItem){
+				arrayUtil.forEach(tItems, function(tItem){
 					var id = tItem.id,
 						name = tItem.name,
-						starttime = tItem.starttime.split("-");
+						starttime = tItem.starttime.split("-"),
 						duration = tItem.duration,
 						percentage = tItem.percentage,
 						previousTaskId = tItem.previousTaskId,
 						taskOwner = tItem.taskOwner;
 					
-					var task = new dojox.gantt.GanttTaskItem({
+					var task = new GanttTaskItem({
 						id: id,
 						name: name,
 						startTime: new Date(starttime[0], (parseInt(starttime[1]) - 1), starttime[2]),
@@ -442,7 +462,7 @@ dojo.require("dojo.date.locale");
 			 }, this);
 		},
 		buildChildTasksData: function(parentTask, childTaskItems){
-			childTaskItems && dojo.forEach(childTaskItems, function(ctItem){
+			childTaskItems && arrayUtil.forEach(childTaskItems, function(ctItem){
 				var id = ctItem.id,
 					name = ctItem.name,
 					starttime = ctItem.starttime.split("-"),
@@ -451,7 +471,7 @@ dojo.require("dojo.date.locale");
 					previousTaskId = ctItem.previousTaskId,
 					taskOwner = ctItem.taskOwner;
 				
-				var task = new dojox.gantt.GanttTaskItem({
+				var task = new GanttTaskItem({
 					id: id,
 					name: name,
 					startTime: new Date(starttime[0], (parseInt(starttime[1]) - 1), starttime[2]),
@@ -471,7 +491,7 @@ dojo.require("dojo.date.locale");
 		},
 		getJSONData: function(){
 			var jsonObj = {identifier: 'id', items: []};
-			dojo.forEach(this.project, function(proj){
+			arrayUtil.forEach(this.project, function(proj){
 				var project = {
 					id: proj.id,
 					name: proj.name,
@@ -479,7 +499,7 @@ dojo.require("dojo.date.locale");
 					tasks: []
 				};
 				jsonObj.items.push(project);
-				dojo.forEach(proj.parentTasks, function(pTask){
+				arrayUtil.forEach(proj.parentTasks, function(pTask){
 					var task = {
 						id: pTask.id,
 						name: pTask.name,
@@ -497,7 +517,7 @@ dojo.require("dojo.date.locale");
 		},
 		getChildTasksData: function(childTasks){
 			var cTaskObj = [];
-			childTasks && childTasks.length > 0 && dojo.forEach(childTasks, function(childTask){
+			childTasks && childTasks.length > 0 && arrayUtil.forEach(childTasks, function(childTask){
 				var ctask = {
 					id: childTask.id,
 					name: childTask.name,
@@ -514,23 +534,21 @@ dojo.require("dojo.date.locale");
 		},
 		saveJSONData: function(fileName){
 			var _this = this;
-			_this.dataFilePath = (fileName && dojo.trim(fileName).length > 0) ? fileName : this.dataFilePath;
+			_this.dataFilePath = (fileName && lang.trim(fileName).length > 0) ? fileName : this.dataFilePath;
 			try {
-				var td = dojo.xhrPost({
-					url: _this.saveProgramPath,
-					content: {filename: _this.dataFilePath, data: dojo.toJson(_this.getJSONData())},
-					handle: function(res, ioArgs){
-						if((dojo._isDocumentOk(ioArgs.xhr))||
-							(ioArgs.xhr.status == 405)
-						){
-							alert("Successfully! Saved data to " + _this.dataFilePath);
-						}else{
-							alert("Failed! Saved error");
-						}
+				request.post(_this.saveProgramPath, {
+					query: {filename: _this.dataFilePath, data: JSON.stringify(_this.getJSONData())}
+				}).response.then(function(response){
+					if((util.checkStatus(response.options.status))||
+						(response.options.status == 405)
+					){
+						console.log("Successfully! Saved data to " + _this.dataFilePath);
+					}else{
+						console.log("Failed! Saved error");
 					}
 				});
-			} catch (e){
-				alert("exception: " + e.message);
+			} catch(e){
+				console.log("exception: " + e.message);
 			}
 		},
 		sortTaskStartTime: function(a, b){
@@ -540,7 +558,7 @@ dojo.require("dojo.date.locale");
 			return a.startDate < b.startDate ? -1 : (a.startDate > b.startDate ? 1 : 0);
 		},
 		setStartTimeChild: function(parentTask){
-			dojo.forEach(parentTask.cldTasks, function(pcTask){
+			arrayUtil.forEach(parentTask.cldTasks, function(pcTask){
 				if(!pcTask.startTime){
 					pcTask.startTime = parentTask.startTime;
 				}
@@ -550,10 +568,10 @@ dojo.require("dojo.date.locale");
 			}, this);
 		},
 		createPanelTasks: function(){
-			var panelTask = dojo.create("div", {
+			var panelTask = domConstruct.create("div", {
 				className: "ganttTaskPanel"
 			});
-			dojo.style(panelTask, {
+			domStyle.set(panelTask, {
 				height: (this.contentHeight - this.panelTimeHeight - this.scrollBarWidth) + "px"
 			});
 			return panelTask;
@@ -564,9 +582,8 @@ dojo.require("dojo.date.locale");
 			this.pixelsPerHour = this.pixelsPerDay / 24;
 		},
 		createPanelNamesTasksHeader: function(){
-			var _this = this;
-			var panelHeader = dojo.create("div", {className: "ganttPanelHeader"});
-			var tblHeader = dojo.create("table", {
+			var panelHeader = domConstruct.create("div", {className: "ganttPanelHeader"});
+			var tblHeader = domConstruct.create("table", {
 				cellPadding: "0px",
 				border: "0px",
 				cellSpacing: "0px",
@@ -577,117 +594,148 @@ dojo.require("dojo.date.locale");
 			var secondRow = tblHeader.insertRow(tblHeader.rows.length);
 			var thirdRow = tblHeader.insertRow(tblHeader.rows.length);
 			var forthRow = tblHeader.insertRow(tblHeader.rows.length);
-			var zoomIn = dojo.create("td", {
+			var zoomIn = domConstruct.create("td", {
 				align: "center",
 				vAlign: "middle",
 				className: "ganttToolbarZoomIn"
 			}, firstRow);
-			var zoomInFn = dojo.hitch(this, function(){
+			var zoomInFn = lang.hitch(this, function(){
 				if(this.scale * 2 > 5){return;}
 				this.scale = this.scale * 2;
 				this.switchTeleMicroView(this.pixelsPerDay * this.scale);
 			});
-			dojo.disconnect(this.zoomInClickEvent);
-			this.zoomInClickEvent = dojo.connect(zoomIn, "onclick", this, zoomInFn);
+			if(this.zoomInClickEvent){
+				this.zoomInClickEvent.remove();
+			}
+			this.zoomInClickEvent = on(zoomIn, "click", lang.hitch(this, zoomInFn));
 			//a11y support
-			dojo.disconnect(this.zoomInKeyEvent);
-			this.zoomInKeyEvent = dojo.connect(zoomIn, "onkeydown", this, function(e){
-				if(e.keyCode != dojo.keys.ENTER){return;}
+			if(this.zoomInKeyEvent){
+				this.zoomInKeyEvent.remove();
+			}
+			this.zoomInKeyEvent = on(zoomIn, "keydown", lang.hitch(this, function(e){
+				if(e.keyCode != keys.ENTER){return;}
 				zoomInFn();
-			});
-			dojo.attr(zoomIn, "tabIndex", 0);
-			var zoomOut = dojo.create("td", {
+			}));
+
+			domAttr.set(zoomIn, "tabIndex", 0);
+			var zoomOut = domConstruct.create("td", {
 				align: "center",
 				vAlign: "middle",
 				className: "ganttToolbarZoomOut"
 			}, firstRow);
-			var zoomOutFn = dojo.hitch(this, function(){
+			var zoomOutFn = lang.hitch(this, function(){
 				if(this.scale * 0.5 < 0.2){return;}
 				this.scale = this.scale * 0.5;
 				this.switchTeleMicroView(this.pixelsPerDay * this.scale);
 			});
-			dojo.disconnect(this.zoomOutClickEvent);
-			this.zoomOutClickEvent = dojo.connect(zoomOut, "onclick", this, zoomOutFn);
+			if(this.zoomOutClickEvent){
+				this.zoomOutClickEvent.remove();
+			}
+			this.zoomOutClickEvent = on(zoomOut, "click", lang.hitch(this, zoomOutFn));
+
 			//a11y support
-			dojo.disconnect(this.zoomOutKeyEvent);
-			this.zoomOutKeyEvent = dojo.connect(zoomOut, "onkeydown", this, function(e){
-				if(e.keyCode != dojo.keys.ENTER){return;}
+			if(this.zoomOutKeyEvent){
+				this.zoomOutKeyEvent.remove();
+			}
+			this.zoomOutKeyEvent = on(zoomOut, "keydown", lang.hitch(this, function(e){
+				if(e.keyCode != keys.ENTER){return;}
 				zoomOutFn();
-			});
-			dojo.attr(zoomOut, "tabIndex", 0);
-			var micro = dojo.create("td", {
+			}));
+
+			domAttr.set(zoomOut, "tabIndex", 0);
+			var micro = domConstruct.create("td", {
 				align: "center",
 				vAlign: "middle",
 				className: "ganttToolbarMicro"
 			}, secondRow);
-			dojo.disconnect(this.microClickEvent);
-			this.microClickEvent = dojo.connect(micro, "onclick", this, dojo.hitch(this, this.refresh, this.animation?15:1, 0, 2));
+			if(this.microClickEvent){
+				this.microClickEvent.remove();
+			}
+			this.microClickEvent = on(micro, "click", lang.hitch(this, this.refresh, this.animation?15:1, 0, 2));
+
 			//a11y support
-			dojo.disconnect(this.microKeyEvent);
-			this.microKeyEvent = dojo.connect(micro, "onkeydown", this, function(e){
-				if(e.keyCode != dojo.keys.ENTER){return;}
+			if(this.microKeyEvent){
+				this.microKeyEvent.remove();
+			}
+			this.microKeyEvent = on(micro, "keydown", lang.hitch(this, function(e){
+				if(e.keyCode != keys.ENTER){return;}
 				micro.blur();
 				this.refresh(this.animation?15:1, 0, 2);
-			});
-			dojo.attr(micro, "tabIndex", 0);
-			var tele = dojo.create("td", {
+			}));
+
+			domAttr.set(micro, "tabIndex", 0);
+			var tele = domConstruct.create("td", {
 				align: "center",
 				vAlign: "middle",
 				className: "ganttToolbarTele"
 			}, secondRow);
-			dojo.disconnect(this.teleClickEvent);
-			this.teleClickEvent = dojo.connect(tele, "onclick", this, dojo.hitch(this, this.refresh, this.animation?15:1, 0, 0.5));
+			if(this.teleClickEvent){
+				this.teleClickEvent.remove();
+			}
+			this.teleClickEvent = on(tele, "click", lang.hitch(this, this.refresh, this.animation?15:1, 0, 0.5));
 			//a11y support
-			dojo.disconnect(this.teleKeyEvent);
-			this.teleKeyEvent = dojo.connect(tele, "onkeydown", this, function(e){
-				if(e.keyCode != dojo.keys.ENTER){return;}
+			if(this.teleKeyEvent){
+				this.teleKeyEvent.remove();
+			}
+			this.teleKeyEvent = on(tele, "keydown", lang.hitch(this, function(e){
+				if(e.keyCode != keys.ENTER){return;}
 				tele.blur();
 				this.refresh(this.animation?15:1, 0, 0.5);
-			});
-			dojo.attr(tele, "tabIndex", 0);
-			var save = dojo.create("td", {
+			}));
+			domAttr.set(tele, "tabIndex", 0);
+			var save = domConstruct.create("td", {
 				align: "center",
 				vAlign: "middle",
 				className: "ganttToolbarSave"
 			}, thirdRow);
-			dojo.disconnect(this.saveClickEvent);
-			this.saveClickEvent = dojo.connect(save, "onclick", this, dojo.hitch(this, this.saveJSONData, ""));
+			if(this.saveClickEvent){
+				this.saveClickEvent.remove();
+			}
+			this.saveClickEvent = on(save, "click", lang.hitch(this, this.saveJSONData, ""));
 			//a11y support
-			dojo.disconnect(this.saveKeyEvent);
-			this.saveKeyEvent = dojo.connect(save, "onkeydown", this, function(e){
-				if(e.keyCode != dojo.keys.ENTER){return;}
+			if(this.saveKeyEvent){
+				this.saveKeyEvent.remove();
+			}
+			this.saveKeyEvent = on(save, "keydown", lang.hitch(this, function(e){
+				if(e.keyCode != keys.ENTER){return;}
 				this.saveJSONData("");
-			});
-			dojo.attr(save, "tabIndex", 0);
-			var load = dojo.create("td", {
+			}));
+			domAttr.set(save, "tabIndex", 0);
+			var load = domConstruct.create("td", {
 				align: "center",
 				vAlign: "middle",
 				className: "ganttToolbarLoad"
 			}, thirdRow);
-			dojo.disconnect(this.loadClickEvent);
-			this.loadClickEvent = dojo.connect(load, "onclick", this, dojo.hitch(this, this.loadJSONData, ""));
+			if(this.loadClickEvent){
+				this.loadClickEvent.remove();
+			}
+			this.loadClickEvent = on(load, "click", lang.hitch(this, this.loadJSONData, ""));
 			//a11y support
-			dojo.disconnect(this.loadKeyEvent);
-			this.loadKeyEvent = dojo.connect(load, "onkeydown", this, function(e){
-				if(e.keyCode != dojo.keys.ENTER){return;}
+			if(this.loadKeyEvent){
+				this.loadKeyEvent.remove();
+			}
+			this.loadKeyEvent = on(load, "keydown", lang.hitch(this, function(e){
+				if(e.keyCode != keys.ENTER){return;}
 				this.loadJSONData("");
-			});
-			dojo.attr(load, "tabIndex", 0);
+			}));
+
+			domAttr.set(load, "tabIndex", 0);
 			//action popup description
 			var actions = [zoomIn, zoomOut, micro, tele, save, load],
 				titles = ["Enlarge timeline", "Shrink timeline", "Zoom in time zone(microscope view)", "Zoom out time zone(telescope view)",
 							"Save gantt data to json file", "Load gantt data from json file"];
-			dojo.forEach(actions, function(action, i){
+			arrayUtil.forEach(actions, function(action, i){
 				var title = titles[i];
 				var tooltipShow = function(){
-					dojo.addClass(action, "ganttToolbarActionHover");
+					domClass.add(action, "ganttToolbarActionHover");
+					// FIXME: including dijit/Tooltip moves showTooltip and hideTooltip into the dijit namespace
 					dijit.showTooltip(title, action, ["above", "below"]);
 				};
 				action.onmouseover = tooltipShow;
 				//a11y support
 				action.onfocus = tooltipShow;
 				var tooltipHide = function(){
-					dojo.removeClass(action, "ganttToolbarActionHover");
+					domClass.remove(action, "ganttToolbarActionHover");
 					action && dijit.hideTooltip(action);
 				};
 				action.onmouseout = tooltipHide;
@@ -696,19 +744,19 @@ dojo.require("dojo.date.locale");
 			return panelHeader;
 		},
 		createPanelNamesTasks: function(){
-			var panelNameTask = dojo.create("div", {
+			var panelNameTask = domConstruct.create("div", {
 				innerHTML: " ",
 				className: "ganttPanelNames"
 			});
-			dojo.style(panelNameTask, {
+			domStyle.set(panelNameTask, {
 				height: (this.contentHeight - this.panelTimeHeight - this.scrollBarWidth) + "px",
 				width: this.maxWidthPanelNames + "px"
 			});
 			return panelNameTask;
 		},
 		createPanelTime: function(){
-			var panelTime = dojo.create("div", {className: "ganttPanelTime"});
-			var tblTime = dojo.create("table", {
+			var panelTime = domConstruct.create("div", {className: "ganttPanelTime"});
+			var tblTime = domConstruct.create("table", {
 				cellPadding: "0px",
 				border: "0px",
 				cellSpacing: "0px",
@@ -717,7 +765,8 @@ dojo.require("dojo.date.locale");
 			}, panelTime);
 			this.totalDays = this.countDays;
 			//year
-			var newYearRow = tblTime.insertRow(tblTime.rows.length), newYear = oldYear = new Date(this.startDate).getFullYear(), ycount = 0;
+			var newYearRow = tblTime.insertRow(tblTime.rows.length), oldYear, newYear, ycount = 0;
+			newYear = oldYear = new Date(this.startDate).getFullYear();
 			for(var i = 0; i < this.countDays; i++, ycount++){
 				var date = new Date(this.startDate);
 				date.setDate(date.getDate() + i);
@@ -729,9 +778,10 @@ dojo.require("dojo.date.locale");
 				}
 			}
 			this.addYearInPanelTime(newYearRow, ycount, newYear);
-			dojo.style(newYearRow, "display", "none");
+			domStyle.set(newYearRow, "display", "none");
 			//month
-			var newMonthRow = tblTime.insertRow(tblTime.rows.length), newMonth = oldMonth = new Date(this.startDate).getMonth(), mcount = 0, lastYear = 1970;
+			var newMonthRow = tblTime.insertRow(tblTime.rows.length), oldMonth, newMonth, mcount = 0, lastYear = 1970;
+			newMonth = oldMonth = new Date(this.startDate).getMonth();
 			for(var i = 0; i < this.countDays; i++, mcount++){
 				var date = new Date(this.startDate);
 				date.setDate(date.getDate() + i);
@@ -745,11 +795,12 @@ dojo.require("dojo.date.locale");
 			}
 			this.addMonthInPanelTime(newMonthRow, mcount, newMonth, lastYear);
 			//week
-			var newWeekRow = tblTime.insertRow(tblTime.rows.length), newWeek = oldWeek = dojo.date.locale._getWeekOfYear(new Date(this.startDate)), mcount = 0;
+			var newWeekRow = tblTime.insertRow(tblTime.rows.length), oldWeek, newWeek, mcount = 0;
+			newWeek = oldWeek = locale._getWeekOfYear(new Date(this.startDate));
 			for(var i = 0; i < this.countDays; i++, mcount++){
 				var date = new Date(this.startDate);
 				date.setDate(date.getDate() + i);
-				newWeek = dojo.date.locale._getWeekOfYear(date);
+				newWeek = locale._getWeekOfYear(date);
 				if(newWeek != oldWeek){
 					this.addWeekInPanelTime(newWeekRow, mcount, oldWeek);
 					mcount = 0;
@@ -767,11 +818,11 @@ dojo.require("dojo.date.locale");
 			for(var i = 0; i < this.countDays; i++){
 				this.addHourInPanelTime(newHourRow);
 			}
-			dojo.style(newHourRow, "display", "none");
+			domStyle.set(newHourRow, "display", "none");
 			return panelTime;
 		},
-		adjustPanelTime: function(width){
-			var maxEndPos = dojo.map(this.arrProjects, function(project){
+		adjustPanelTime: function(){
+			var maxEndPos = arrayUtil.map(this.arrProjects, function(project){
 				return (parseInt(project.projectItem[0].style.left) + parseInt(project.projectItem[0].firstChild.style.width)
 					+ project.descrProject.offsetWidth + this.panelTimeExpandDelta);
 			}, this).sort(function(a,b){return b-a})[0];
@@ -780,11 +831,12 @@ dojo.require("dojo.date.locale");
 				var prows = this.panelTime.firstChild.firstChild.rows;
 				for(var i = 0; i <= 4; i++){//prows.length
 					this.removeCell(prows[i]);
-				};
+				}
 				var countDays = Math.round((maxEndPos+this.panelTimeExpandDelta) / this.pixelsPerDay);
 				this.totalDays = countDays;
 				//year
-				var newYear = oldYear = new Date(this.startDate).getFullYear(), ycount = 0;
+				var oldYear, newYear, ycount = 0;
+				newYear = oldYear = new Date(this.startDate).getFullYear();
 				for(var i = 0; i < countDays; i++, ycount++){
 					var date = new Date(this.startDate);
 					date.setDate(date.getDate() + i);
@@ -797,7 +849,8 @@ dojo.require("dojo.date.locale");
 				}
 				this.addYearInPanelTime(prows[0], ycount, newYear);
 				//month
-				var newMonth = oldMonth = new Date(this.startDate).getMonth(), mcount = 0, lastYear = 1970;
+				var oldMonth, newMonth, mcount = 0, lastYear = 1970;
+				newMonth = oldMonth = new Date(this.startDate).getMonth();
 				for(var i = 0; i < countDays; i++, mcount++){
 					var date = new Date(this.startDate);
 					date.setDate(date.getDate() + i);
@@ -811,11 +864,12 @@ dojo.require("dojo.date.locale");
 				}
 				this.addMonthInPanelTime(prows[1], mcount, newMonth, lastYear);
 				//week
-				var newWeek = oldWeek = dojo.date.locale._getWeekOfYear(new Date(this.startDate)), mcount = 0;
+				var oldWeek, newWeek, mcount = 0;
+				newWeek = oldWeek = locale._getWeekOfYear(new Date(this.startDate));
 				for(var i = 0; i < countDays; i++, mcount++){
 					var date = new Date(this.startDate);
 					date.setDate(date.getDate() + i);
-					newWeek = dojo.date.locale._getWeekOfYear(date);
+					newWeek = locale._getWeekOfYear(date);
 					if(newWeek != oldWeek){
 						this.addWeekInPanelTime(prows[2], mcount, oldWeek);
 						mcount = 0;
@@ -838,7 +892,7 @@ dojo.require("dojo.date.locale");
 		},
 		addYearInPanelTime: function(row, count, year){
 			var data = "Year   " + year;
-			var newCell = dojo.create("td", {
+			var newCell = domConstruct.create("td", {
 				colSpan: count,
 				align: "center",
 				vAlign: "middle",
@@ -846,11 +900,11 @@ dojo.require("dojo.date.locale");
 				innerHTML: this.pixelsPerDay * count > 20 ? data : "",
 				innerHTMLData: data
 			}, row);
-			dojo.style(newCell, "width", (this.pixelsPerDay * count) + "px");
+			domStyle.set(newCell, "width", (this.pixelsPerDay * count) + "px");
 		},
 		addMonthInPanelTime: function(row, count, month, year){
 			var data = this.months[month] + (year ? " of " + year : "");
-			var newCell = dojo.create("td", {
+			var newCell = domConstruct.create("td", {
 				colSpan: count,
 				align: "center",
 				vAlign: "middle",
@@ -858,11 +912,11 @@ dojo.require("dojo.date.locale");
 				innerHTML: this.pixelsPerDay * count > 30 ? data : "",
 				innerHTMLData: data
 			}, row);
-			dojo.style(newCell, "width", (this.pixelsPerDay * count) + "px");
+			domStyle.set(newCell, "width", (this.pixelsPerDay * count) + "px");
 		},
 		addWeekInPanelTime: function(row, count, week){
 			var data = "Week   " + week;
-			var newCell = dojo.create("td", {
+			var newCell = domConstruct.create("td", {
 				colSpan: count,
 				align: "center",
 				vAlign: "middle",
@@ -870,12 +924,12 @@ dojo.require("dojo.date.locale");
 				innerHTML: this.pixelsPerDay * count > 20 ? data : "",
 				innerHTMLData: data
 			}, row);
-			dojo.style(newCell, "width", (this.pixelsPerDay * count) + "px");
+			domStyle.set(newCell, "width", (this.pixelsPerDay * count) + "px");
 		},
 		addDayInPanelTime: function(row){
 			var date = new Date(this.startDate);
 			date.setDate(date.getDate() + parseInt(row.cells.length));
-			var newCell = dojo.create("td", {
+			var newCell = domConstruct.create("td", {
 				align: "center",
 				vAlign: "middle",
 				className: "ganttDayNumber",
@@ -883,47 +937,47 @@ dojo.require("dojo.date.locale");
 				innerHTMLData: String(date.getDate()),
 				data: row.cells.length
 			}, row);
-			dojo.style(newCell, "width", this.pixelsPerDay + "px");
-			(date.getDay() >= 5) && dojo.addClass(newCell, "ganttDayNumberWeekend");
+			domStyle.set(newCell, "width", this.pixelsPerDay + "px");
+			(date.getDay() >= 5) && domClass.add(newCell, "ganttDayNumberWeekend");
 			this._events.push(
-				dojo.connect(newCell, "onmouseover", this, function(event){
+				on(newCell, "mouseover", lang.hitch(this, function(event){
 					var dayTime = event.target || event.srcElement;
 					var date = new Date(this.startDate.getTime());
-					date.setDate(date.getDate() + parseInt(dojo.attr(dayTime, "data")));
+					date.setDate(date.getDate() + parseInt(domAttr.get(dayTime, "data")));
 					dijit.showTooltip(date.getFullYear() + "." + (date.getMonth() + 1) + "." + date.getDate(), newCell, ["above", "below"]);
-				})
+				}))
 			);
 			this._events.push(
-				dojo.connect(newCell, "onmouseout", this, function(event){
+				on(newCell, "mouseout", lang.hitch(this, function(event){
 					var dayTime = event.target || event.srcElement;
 					dayTime && dijit.hideTooltip(dayTime);
-				})
+				}))
 			);
 		},
 		addHourInPanelTime: function(row){
-			var newCell = dojo.create("td", {
+			var newCell = domConstruct.create("td", {
 				align: "center",
 				vAlign: "middle",
 				className: "ganttHourNumber",
 				data: row.cells.length
 			}, row);
-			dojo.style(newCell, "width", this.pixelsPerDay + "px");
+			domStyle.set(newCell, "width", this.pixelsPerDay + "px");
 			
-			var hourTable = dojo.create("table", {
+			var hourTable = domConstruct.create("table", {
 				cellPadding: "0",
 				cellSpacing: "0"
 			}, newCell);
 			var newRow = hourTable.insertRow(hourTable.rows.length);
 			for(var i = 0; i < this.hsPerDay; i++){
-				var hourTD = dojo.create("td", {
+				var hourTD = domConstruct.create("td", {
 					className: "ganttHourClass"
 				}, newRow);
-				dojo.style(hourTD, "width", (this.pixelsPerDay / this.hsPerDay) + "px");
-				dojo.attr(hourTD, "innerHTMLData", String(9 + i));
+				domStyle.set(hourTD, "width", (this.pixelsPerDay / this.hsPerDay) + "px");
+				domAttr.set(hourTD, "innerHTMLData", String(9 + i));
 				if(this.pixelsPerDay / this.hsPerDay > 5){
-					dojo.attr(hourTD, "innerHTML", String(9 + i));
+					domAttr.set(hourTD, "innerHTML", String(9 + i));
 				}
-				dojo.addClass(hourTD, i <= 3?"ganttHourNumberAM":"ganttHourNumberPM");
+				domClass.add(hourTD, i <= 3?"ganttHourNumberAM":"ganttHourNumberPM");
 			}
 		},
 		incHeightPanelTasks: function(height){
@@ -935,8 +989,8 @@ dojo.require("dojo.date.locale");
 			containerNames.style.height = parseInt(containerNames.style.height) + height + "px";
 		},
 		checkPosition: function(){
-			dojo.forEach(this.arrProjects, function(project){
-				dojo.forEach(project.arrTasks, function(task){
+			arrayUtil.forEach(this.arrProjects, function(project){
+				arrayUtil.forEach(project.arrTasks, function(task){
 					task.checkPosition();
 				}, this);
 			}, this);
@@ -972,22 +1026,22 @@ dojo.require("dojo.date.locale");
 					this.resource.refresh();
 				}
 				this.tempDayInPixels = 0;
-				this.panelNameHeadersCover && dojo.style(this.panelNameHeadersCover, "display", "none");
+				this.panelNameHeadersCover && domStyle.set(this.panelNameHeadersCover, "display", "none");
 				return;
 			}
 			if(this.tempDayInPixels == 0){
 				this.tempDayInPixels = this.pixelsPerDay;
 			}
-			this.panelNameHeadersCover && dojo.style(this.panelNameHeadersCover, "display", "");
+			this.panelNameHeadersCover && domStyle.set(this.panelNameHeadersCover, "display", "");
 			var dip = this.tempDayInPixels + this.tempDayInPixels * (multi - 1) * Math.pow((current / count), 2);
 			this.refreshParams(dip);
-			dojo.forEach(this.arrProjects, function(project){
-				dojo.forEach(project.arrTasks, function(task){
+			arrayUtil.forEach(this.arrProjects, function(project){
+				arrayUtil.forEach(project.arrTasks, function(task){
 					task.refresh();
 				}, this);
 				project.refresh();
 			}, this);
-			setTimeout(dojo.hitch(this, function(){
+			setTimeout(lang.hitch(this, function(){
 				this.refresh(count, ++current, multi);
 			}), 15);
 		},
@@ -995,11 +1049,11 @@ dojo.require("dojo.date.locale");
 			var plChild = this.panelTime.firstChild.firstChild;
 			for(var i = 0; i < 5; i++){//0:Y 1:M 2:W 3:D 4:H
 				if(dip > 40){
-					dojo.style(plChild.rows[i], "display", (i==0||i==1)?"none":"");
+					domStyle.set(plChild.rows[i], "display", (i==0||i==1)?"none":"");
 				}else if(dip < 20){
-					dojo.style(plChild.rows[i], "display", (i==2||i==4)?"none":"");
+					domStyle.set(plChild.rows[i], "display", (i==2||i==4)?"none":"");
 				}else{
-					dojo.style(plChild.rows[i], "display", (i==0||i==4)?"none":"");
+					domStyle.set(plChild.rows[i], "display", (i==0||i==4)?"none":"");
 				}
 			}
 		},
@@ -1008,23 +1062,23 @@ dojo.require("dojo.date.locale");
 			this.panelTime.firstChild.style.width = this.pixelsPerDay * this.totalDays + "px";
 			this.panelTime.firstChild.firstChild.style.width = this.pixelsPerDay * this.totalDays + "px";
 			this.switchTeleMicroView(this.pixelsPerDay);
-			dojo.forEach(this.panelTime.firstChild.firstChild.rows, function(row){
-				dojo.forEach(row.childNodes, function(td){
-					var cs = parseInt(dojo.attr(td, "colSpan") || 1);
-					var idata = dojo.trim(dojo.attr(td, "innerHTMLData")||"");
+			arrayUtil.forEach(this.panelTime.firstChild.firstChild.rows, function(row){
+				arrayUtil.forEach(row.childNodes, function(td){
+					var cs = parseInt(domAttr.get(td, "colSpan") || 1);
+					var idata = lang.trim(domAttr.get(td, "innerHTMLData")||"");
 					if(idata.length > 0){
-						dojo.attr(td, "innerHTML", this.pixelsPerDay * cs < 20 ? "" : idata);
+						domAttr.set(td, "innerHTML", this.pixelsPerDay * cs < 20 ? "" : idata);
 					}else{
-						dojo.forEach(td.firstChild.rows[0].childNodes, function(td){
-							var sdata = dojo.trim(dojo.attr(td, "innerHTMLData")||"");
-							dojo.attr(td, "innerHTML", this.pixelsPerDay / this.hsPerDay > 10 ? sdata : "");
+						arrayUtil.forEach(td.firstChild.rows[0].childNodes, function(td){
+							var sdata = lang.trim(domAttr.get(td, "innerHTMLData")||"");
+							domAttr.set(td, "innerHTML", this.pixelsPerDay / this.hsPerDay > 10 ? sdata : "");
 						}, this);
 					}
 					if(cs == 1){
-						dojo.style(td, "width", (this.pixelsPerDay*cs) + "px");
+						domStyle.set(td, "width", (this.pixelsPerDay*cs) + "px");
 						if(idata.length <= 0){
-							dojo.forEach(td.firstChild.rows[0].childNodes, function(td){
-								dojo.style(td, "width", (this.pixelsPerDay*cs / this.hsPerDay) + "px");
+							arrayUtil.forEach(td.firstChild.rows[0].childNodes, function(td){
+								domStyle.set(td, "width", (this.pixelsPerDay*cs / this.hsPerDay) + "px");
 							}, this);
 						}
 					}
@@ -1033,12 +1087,12 @@ dojo.require("dojo.date.locale");
 		},
 		init: function(){
 			this.startDate = this.getStartDate();
-			dojo.style(this.content, {
+			domStyle.set(this.content, {
 				width: this.contentWidth + "px",
 				height: this.contentHeight + "px"
 			});
 			//create Table
-			this.tableControl = dojo.create("table", {
+			this.tableControl = domConstruct.create("table", {
 				cellPadding: "0",
 				cellSpacing: "0",
 				className: "ganttTabelControl"
@@ -1048,45 +1102,45 @@ dojo.require("dojo.date.locale");
 			this.content.appendChild(this.tableControl);
 			this.countDays = this.getCountDays();
 			//Creation panel of time
-			this.panelTime = dojo.create("div", {className: "ganttPanelTimeContainer"});
-			dojo.style(this.panelTime, "height", this.panelTimeHeight + "px");
+			this.panelTime = domConstruct.create("div", {className: "ganttPanelTimeContainer"});
+			domStyle.set(this.panelTime, "height", this.panelTimeHeight + "px");
 			this.panelTime.appendChild(this.createPanelTime());
 			//Creation panel contentData
-			this.contentData = dojo.create("div", {className: "ganttContentDataContainer"});
-			dojo.style(this.contentData, "height", (this.contentHeight - this.panelTimeHeight) + "px");
+			this.contentData = domConstruct.create("div", {className: "ganttContentDataContainer"});
+			domStyle.set(this.contentData, "height", (this.contentHeight - this.panelTimeHeight) + "px");
 			this.contentData.appendChild(this.createPanelTasks());
 			//Creation panel of names
-			var newCellTblControl = dojo.create("td", {
+			var newCellTblControl = domConstruct.create("td", {
 				vAlign: "top"
 			});
 			//Creation panel of task header
-			this.panelNameHeaders = dojo.create("div", {className: "ganttPanelNameHeaders"}, newCellTblControl);
-			dojo.style(this.panelNameHeaders, {
+			this.panelNameHeaders = domConstruct.create("div", {className: "ganttPanelNameHeaders"}, newCellTblControl);
+			domStyle.set(this.panelNameHeaders, {
 				height: this.panelTimeHeight + "px",
 				width: this.maxWidthPanelNames + "px"
 			});
 			this.panelNameHeaders.appendChild(this.createPanelNamesTasksHeader());
-			this.panelNames = dojo.create("div", {className: "ganttPanelNamesContainer"}, newCellTblControl);
+			this.panelNames = domConstruct.create("div", {className: "ganttPanelNamesContainer"}, newCellTblControl);
 			this.panelNames.appendChild(this.createPanelNamesTasks());
 			newRowTblControl.appendChild(newCellTblControl);
 			//add to control contentData and dataTime
-			newCellTblControl = dojo.create("td", {
+			newCellTblControl = domConstruct.create("td", {
 				vAlign: "top"
 			});
-			var divCell = dojo.create("div", {className: "ganttDivCell"});
+			var divCell = domConstruct.create("div", {className: "ganttDivCell"});
 			divCell.appendChild(this.panelTime);
 			divCell.appendChild(this.contentData);
 			newCellTblControl.appendChild(divCell);
 			newRowTblControl.appendChild(newCellTblControl);
 			//Show panel of names
-			dojo.style(this.panelNames, "height", (this.contentHeight - this.panelTimeHeight - this.scrollBarWidth) + "px");
-			dojo.style(this.panelNames, "width", this.maxWidthPanelNames + "px");
-			dojo.style(this.contentData, "width", (this.contentWidth - this.maxWidthPanelNames) + "px");
-			dojo.style(this.contentData.firstChild, "width", this.pixelsPerDay * this.countDays + "px");
-			dojo.style(this.panelTime, "width", (this.contentWidth - this.maxWidthPanelNames - this.scrollBarWidth) + "px");
-			dojo.style(this.panelTime.firstChild, "width", this.pixelsPerDay * this.countDays + "px");
+			domStyle.set(this.panelNames, "height", (this.contentHeight - this.panelTimeHeight - this.scrollBarWidth) + "px");
+			domStyle.set(this.panelNames, "width", this.maxWidthPanelNames + "px");
+			domStyle.set(this.contentData, "width", (this.contentWidth - this.maxWidthPanelNames) + "px");
+			domStyle.set(this.contentData.firstChild, "width", this.pixelsPerDay * this.countDays + "px");
+			domStyle.set(this.panelTime, "width", (this.contentWidth - this.maxWidthPanelNames - this.scrollBarWidth) + "px");
+			domStyle.set(this.panelTime.firstChild, "width", this.pixelsPerDay * this.countDays + "px");
 			if(this.isShowConMenu){
-				this.tabMenu = new dojox.gantt.TabMenu(this);
+				this.tabMenu = new TabMenu(this);
 			}
 			var _this = this;
 			this.contentData.onscroll = function(){
@@ -1100,7 +1154,7 @@ dojo.require("dojo.date.locale");
 				if(_this.resource){
 					_this.resource.contentData.scrollLeft = this.scrollLeft;
 				}
-			}
+			};
 			this.project.sort(this.sortProjStartDate);
 			for(var i = 0; i < this.project.length; i++){
 				var proj = this.project[i];
@@ -1132,7 +1186,7 @@ dojo.require("dojo.date.locale");
 			for(var i = 0; i < this.project.length; i++){
 				//creation project
 				var proj = this.project[i];
-				var project = new dojox.gantt.GanttProjectControl(this, proj);
+				var project = new GanttProjectControl(this, proj);
 				if(this.arrProjects.length > 0){
 					var previousProject = this.arrProjects[this.arrProjects.length - 1];
 					project.previousProject = previousProject;
@@ -1144,7 +1198,7 @@ dojo.require("dojo.date.locale");
 				this.createTasks(project);
 			}
 			if(this.withResource){
-				this.resource = new dojox.gantt.GanttResourceItem(this);
+				this.resource = new GanttResourceItem(this);
 				this.resource.create();
 			}
 			this.postLoadData();
@@ -1152,17 +1206,17 @@ dojo.require("dojo.date.locale");
 			return this;
 		},
 		postLoadData: function(){
-			dojo.forEach(this.arrProjects, function(project){
-				dojo.forEach(project.arrTasks, function(task){
+			arrayUtil.forEach(this.arrProjects, function(project){
+				arrayUtil.forEach(project.arrTasks, function(task){
 					task.postLoadData();
 				}, this);
 				project.postLoadData();
 			}, this);
 			//toolbar cover div
-			var cpos = dojo.coords(this.panelNameHeaders);
+			var cpos = domGeometry.getMarginBox(this.panelNameHeaders);
 			if(!this.panelNameHeadersCover){
-				this.panelNameHeadersCover = dojo.create("div", {className: "ganttHeaderCover"}, this.panelNameHeaders.parentNode);
-				dojo.style(this.panelNameHeadersCover, {
+				this.panelNameHeadersCover = domConstruct.create("div", {className: "ganttHeaderCover"}, this.panelNameHeaders.parentNode);
+				domStyle.set(this.panelNameHeadersCover, {
 					left: cpos.l+"px",
 					top: cpos.t+"px",
 					height: cpos.h+"px",
@@ -1173,9 +1227,9 @@ dojo.require("dojo.date.locale");
 		},
 		postBindEvents: function(){
 			//highlight row
-			var pos = dojo.position(this.tableControl, true);
-			!dojo.isIE && this._events.push(
-				dojo.connect(this.tableControl, "onmousemove", this, function(event){
+			var pos = domGeometry.position(this.tableControl, true);
+			has("dom-addeventlistener") && this._events.push(
+				on(this.tableControl, "mousemove", lang.hitch(this, function(event){
 					var elem = event.srcElement || event.target;
 					if(elem == this.panelNames.firstChild || elem == this.contentData.firstChild){
 						//23: this.heightTaskItem + this.heightTaskItemExtra
@@ -1183,12 +1237,12 @@ dojo.require("dojo.date.locale");
 						var hlTop = parseInt(event.layerY / rowHeight) * rowHeight + this.panelTimeHeight - this.contentData.scrollTop;
 						if(hlTop != this.oldHLTop && hlTop < (pos.h - 50)){
 							if(this.highLightDiv){
-								dojo.style(this.highLightDiv, "top", (pos.y + hlTop) + "px");
+								domStyle.set(this.highLightDiv, "top", (pos.y + hlTop) + "px");
 							}else{
-								this.highLightDiv = dojo.create("div", {
+								this.highLightDiv = domConstruct.create("div", {
 									className: "ganttRowHighlight"
-								}, dojo.body());
-								dojo.style(this.highLightDiv, {
+								}, win.body());
+								domStyle.set(this.highLightDiv, {
 									top: (pos.y + hlTop) + "px",
 									left: pos.x + "px",
 									width: (pos.w - 20) + "px",
@@ -1198,12 +1252,11 @@ dojo.require("dojo.date.locale");
 						}
 						this.oldHLTop = hlTop;
 					}
-				})
+				}))
 			);
-			//TODO: other event bindings
 		},
 		getStartDate: function(){
-			dojo.forEach(this.project, function(proj){
+			arrayUtil.forEach(this.project, function(proj){
 				if(this.startDate){
 					if(proj.startDate < this.startDate){
 						this.startDate = new Date(proj.startDate);
@@ -1219,12 +1272,12 @@ dojo.require("dojo.date.locale");
 			return parseInt((this.contentWidth - this.maxWidthPanelNames) / (this.pixelsPerHour * 24));
 		},
 		createTasks: function(project){
-			dojo.forEach(project.project.parentTasks, function(pppTask, i){
+			arrayUtil.forEach(project.project.parentTasks, function(pppTask, i){
 				if(i > 0){
 					project.project.parentTasks[i - 1].nextParentTask = pppTask;
 					pppTask.previousParentTask = project.project.parentTasks[i - 1];
 				}
-				var task = new dojox.gantt.GanttTaskControl(pppTask, project, this);
+				var task = new GanttTaskControl(pppTask, project, this);
 				project.arrTasks.push(task);
 				task.create();
 				this.checkHeighPanelTasks();
@@ -1234,12 +1287,12 @@ dojo.require("dojo.date.locale");
 			}, this);
 		},
 		createChildItemControls: function(arrChildTasks, project){
-			arrChildTasks && dojo.forEach(arrChildTasks, function(cTask, i){
+			arrChildTasks && arrayUtil.forEach(arrChildTasks, function(cTask, i){
 				if(i > 0){
 					cTask.previousChildTask = arrChildTasks[i - 1];
 					arrChildTasks[i - 1].nextChildTask = cTask;
 				}
-				var task = new dojox.gantt.GanttTaskControl(cTask, project, this);
+				var task = new GanttTaskControl(cTask, project, this);
 				task.create();
 				this.checkHeighPanelTasks();
 				if(cTask.cldTasks.length > 0){
@@ -1262,4 +1315,4 @@ dojo.require("dojo.date.locale");
 			}
 		}
 	});
-})();
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/dojox/gantt/GanttProjectControl.js b/dojox/gantt/GanttProjectControl.js
new file mode 100644
index 0000000..32d3a22
--- /dev/null
+++ b/dojox/gantt/GanttProjectControl.js
@@ -0,0 +1,886 @@
+define([
+	"./GanttTaskItem",
+	"./GanttTaskControl",
+	"dijit/focus",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/date/locale",
+	"dojo/request",
+	"dojo/on",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dojo/dom-attr",
+	"dojo/dom-geometry",
+	"dojo/keys",
+	"dojo/domReady!"
+], function(GanttTaskItem, GanttTaskControl, focus,
+		declare, arrayUtil, lang, locale, request, on,
+		dom, domClass, domConstruct, domStyle, domAttr, domGeometry, keys){
+	return declare("dojox.gantt.GanttProjectControl", [], {
+		constructor: function(ganttChart, projectItem){
+			this.project = projectItem;
+			this.ganttChart = ganttChart;
+			this.descrProject = null;
+			this.projectItem = null;
+			this.projectNameItem = null;
+			this.posY = 0;
+			this.posX = 0;
+			this.nextProject = null;
+			this.previousProject = null;
+			this.arrTasks = [];
+			this.percentage = 0;
+			this.duration = 0;
+		},
+		checkWidthProjectNameItem: function(){
+			if(this.projectNameItem.offsetWidth + this.projectNameItem.offsetLeft > this.ganttChart.maxWidthTaskNames){
+				var width = this.projectNameItem.offsetWidth + this.projectNameItem.offsetLeft - this.ganttChart.maxWidthTaskNames;
+				var countChar = Math.round(width / (this.projectNameItem.offsetWidth / this.projectNameItem.firstChild.length));
+				var pName = this.project.name.substring(0, this.projectNameItem.firstChild.length - countChar - 3);
+				pName += "...";
+				this.projectNameItem.innerHTML = pName;
+			}
+		},
+		refreshProjectItem: function(projectItem){
+			this.percentage = this.getPercentCompleted();
+			domStyle.set(projectItem, {
+				"left": this.posX + "px",
+				"width": this.duration * this.ganttChart.pixelsPerWorkHour + "px"
+			});
+			var tblProjectItem = projectItem.firstChild;
+			var width = this.duration * this.ganttChart.pixelsPerWorkHour;
+			tblProjectItem.width = ((width == 0) ? 1 : width) + "px";
+			tblProjectItem.style.width = ((width == 0) ? 1 : width) + "px";
+			var rowprojectItem = tblProjectItem.rows[0];
+			if(this.percentage != -1){
+				if(this.percentage != 0){
+					var cellprojectItem = rowprojectItem.firstChild;
+					cellprojectItem.width = this.percentage + "%";
+					var imageProgress = cellprojectItem.firstChild;
+					domStyle.set(imageProgress, {
+						width: (!this.duration ? 1 : (this.percentage * this.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
+						height: this.ganttChart.heightTaskItem + "px"
+					})
+				}
+				if(this.percentage != 100){
+					var cellprojectItem = rowprojectItem.lastChild;
+					cellprojectItem.width = (100 - this.percentage) + "%";
+					var imageProgress = cellprojectItem.firstChild;
+					domStyle.set(imageProgress, {
+						width: (!this.duration ? 1 : ((100 - this.percentage) * this.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
+						height: this.ganttChart.heightTaskItem + "px"
+					})
+				}
+			}else{
+				var cellprojectItem = rowprojectItem.firstChild;
+				cellprojectItem.width = "1px";
+				var imageProgress = cellprojectItem.firstChild;
+				domStyle.set(imageProgress, {
+					width: "1px",
+					height: this.ganttChart.heightTaskItem + "px"
+				})
+			}
+			var divTaskInfo = projectItem.lastChild;
+			var tblTaskInfo = divTaskInfo.firstChild;
+			domStyle.set(tblTaskInfo, {
+				height: this.ganttChart.heightTaskItem + "px",
+				width: (!this.duration ? 1 : (this.duration * this.ganttChart.pixelsPerWorkHour)) + "px"
+			});
+			var rowTaskInfo = tblTaskInfo.rows[0];
+			var cellTaskInfo = rowTaskInfo.firstChild;
+			cellTaskInfo.height = this.ganttChart.heightTaskItem + "px";
+			if(this.project.parentTasks.length == 0){
+				projectItem.style.display = "none";
+			}
+			return projectItem;
+		},
+		refreshDescrProject: function(divDesc){
+			var posX = (this.posX + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
+			domStyle.set(divDesc, {
+				"left": posX + "px"
+			});
+			if(this.project.parentTasks.length == 0){
+				this.descrProject.style.visibility = 'hidden';
+			}
+			return divDesc;
+		},
+		postLoadData: function(){
+			//TODO e.g. project relative info...
+		},
+		refresh: function(){
+			this.posX = (this.project.startDate - this.ganttChart.startDate) / (60 * 60 * 1000) * this.ganttChart.pixelsPerHour;
+			this.refreshProjectItem(this.projectItem[0]);
+			this.refreshDescrProject(this.projectItem[0].nextSibling);
+			return this;
+		},
+		create: function(){
+			var containerTasks = this.ganttChart.contentData.firstChild;
+			this.posX = (this.project.startDate - this.ganttChart.startDate) / (60 * 60 * 1000) * this.ganttChart.pixelsPerHour;
+			if(this.previousProject){
+				if(this.previousProject.arrTasks.length > 0){
+					var lastChildTask = this.ganttChart.getLastChildTask(this.previousProject.arrTasks[this.previousProject.arrTasks.length - 1]);
+					this.posY = parseInt(lastChildTask.cTaskItem[0].style.top) + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+				}else{
+					this.posY = parseInt(this.previousProject.projectItem[0].style.top) + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+				}
+			}else{
+				this.posY = 6;
+			}
+			var containerNames = this.ganttChart.panelNames.firstChild;
+			this.projectNameItem = this.createProjectNameItem();
+			containerNames.appendChild(this.projectNameItem);
+			this.checkWidthProjectNameItem();
+			this.projectItem = [this.createProjectItem(), []];
+			containerTasks.appendChild(this.projectItem[0]);
+			containerTasks.appendChild(this.createDescrProject());
+			this.adjustPanelTime();
+		},
+		getTaskById: function(id){
+			for(var i = 0; i < this.arrTasks.length; i++){
+				var aTask = this.arrTasks[i];
+				var task = this.searchTaskInTree(aTask, id);
+				if(task){
+					return task;
+				}
+			}
+			return null;
+		},
+		searchTaskInTree: function(task, id){
+			if(task.taskItem.id == id){
+				return task;
+			}else{
+				for(var i = 0; i < task.childTask.length; i++){
+					var cTask = task.childTask[i];
+					if(cTask.taskItem.id == id){
+						return cTask;
+					}else{
+						if(cTask.childTask.length > 0){
+							var cTask = this.searchTaskInTree(cTask, id);
+							if(cTask){
+								return cTask;
+							}
+						}
+					}
+				}
+			}
+			return null;
+		},
+		shiftProjectItem: function(){
+			var posItemL = null;
+			var posItemR = null;
+			var posProjectItemL = parseInt(this.projectItem[0].style.left);
+			for(var i = 0; i < this.arrTasks.length; i++){
+				var aTask = this.arrTasks[i];
+				var tmpPosItemL = parseInt(aTask.cTaskItem[0].style.left);
+				var tmpPosItemR = parseInt(aTask.cTaskItem[0].style.left) + parseInt(aTask.cTaskItem[0].firstChild.firstChild.width);
+				if(!posItemL){
+					posItemL = tmpPosItemL;
+				}
+				if(!posItemR){
+					posItemR = tmpPosItemR;
+				}
+				if(posItemL > tmpPosItemL){
+					posItemL = tmpPosItemL;
+				}
+				if(posItemR < tmpPosItemR){
+					posItemR = tmpPosItemR;
+				}
+			}
+			if(posItemL != posProjectItemL){
+				this.project.startDate = new Date(this.ganttChart.startDate);
+				this.project.startDate.setHours(this.project.startDate.getHours() + (posItemL / this.ganttChart.pixelsPerHour));
+			}
+			this.projectItem[0].style.left = posItemL + "px";
+			this.resizeProjectItem(posItemR - posItemL);
+			this.duration = Math.round(parseInt(this.projectItem[0].firstChild.width) / (this.ganttChart.pixelsPerWorkHour));
+			this.shiftDescrProject();
+			this.adjustPanelTime();
+		},
+		adjustPanelTime: function(){
+			var projectItem = this.projectItem[0];
+			var width = parseInt(projectItem.style.left) + parseInt(projectItem.firstChild.style.width) + this.ganttChart.panelTimeExpandDelta;
+			width += this.descrProject.offsetWidth;
+			this.ganttChart.adjustPanelTime(width);
+		},
+		resizeProjectItem: function(width){
+			var percentage = this.percentage,
+				pItem = this.projectItem[0];
+			if(percentage > 0 && percentage < 100){
+				pItem.firstChild.style.width = width + "px";
+				pItem.firstChild.width = width + "px";
+				pItem.style.width = width + "px";
+				var firstRow = pItem.firstChild.rows[0];
+				firstRow.cells[0].firstChild.style.width = Math.round(width * percentage / 100) + "px";
+				firstRow.cells[0].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
+				firstRow.cells[1].firstChild.style.width = Math.round(width * (100 - percentage) / 100) + "px";
+				firstRow.cells[1].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
+				pItem.lastChild.firstChild.width = width + "px";
+			}else if(percentage == 0 || percentage == 100){
+				pItem.firstChild.style.width = width + "px";
+				pItem.firstChild.width = width + "px";
+				pItem.style.width = width + "px";
+				var firstRow = pItem.firstChild.rows[0];
+				firstRow.cells[0].firstChild.style.width = width + "px";
+				firstRow.cells[0].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
+				pItem.lastChild.firstChild.width = width + "px";
+			}
+		},
+		shiftDescrProject: function(){
+			var posX = (parseInt(this.projectItem[0].style.left) + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
+			this.descrProject.style.left = posX + "px";
+			this.descrProject.innerHTML = this.getDescStr();
+		},
+		showDescrProject: function(){
+			var posX = (parseInt(this.projectItem[0].style.left) + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
+			this.descrProject.style.left = posX + "px";
+			this.descrProject.style.visibility = 'visible';
+			this.descrProject.innerHTML = this.getDescStr();
+		},
+		hideDescrProject: function(){
+			this.descrProject.style.visibility = 'hidden';
+		},
+		getDescStr: function(){
+			return this.duration/this.ganttChart.hsPerDay + " days,  " + this.duration + " hours";
+		},
+		createDescrProject: function(){
+			var posX = (this.posX + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
+			var divDesc = domConstruct.create("div", {
+				innerHTML: this.getDescStr(),
+				className: "ganttDescProject"
+			});
+			domStyle.set(divDesc, {
+				left: posX + "px",
+				top: this.posY + "px"
+			});
+			this.descrProject = divDesc;
+			if(this.project.parentTasks.length == 0){
+				this.descrProject.style.visibility = 'hidden';
+			}
+			return divDesc;
+		},
+		createProjectItem: function(){
+			this.percentage = this.getPercentCompleted();
+			this.duration = this.getDuration();
+			var projectItem = domConstruct.create("div", {
+				id: this.project.id,
+				className: "ganttProjectItem"
+			});
+			domStyle.set(projectItem, {
+				left: this.posX + "px",
+				top: this.posY + "px",
+				width: this.duration * this.ganttChart.pixelsPerWorkHour + "px"
+			});
+			var tblProjectItem = domConstruct.create("table", {
+				cellPadding: "0",
+				cellSpacing: "0",
+				className: "ganttTblProjectItem"
+			}, projectItem);
+			var width = this.duration * this.ganttChart.pixelsPerWorkHour;
+			tblProjectItem.width = ((width == 0) ? 1 : width) + "px";
+			tblProjectItem.style.width = ((width == 0) ? 1 : width) + "px";
+		
+			var rowprojectItem = tblProjectItem.insertRow(tblProjectItem.rows.length);
+			if(this.percentage != -1){
+				if(this.percentage != 0){
+					var cellprojectItem = domConstruct.create("td", {
+						width: this.percentage + "%"
+					}, rowprojectItem);
+					cellprojectItem.style.lineHeight = "1px";
+					var imageProgress = domConstruct.create("div", {
+						className: "ganttImageProgressFilled"
+					}, cellprojectItem);
+					domStyle.set(imageProgress, {
+						width: (this.percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+						height: this.ganttChart.heightTaskItem + "px"
+					});
+				}
+				if(this.percentage != 100){
+					var cellprojectItem = domConstruct.create("td", {
+						width: (100 - this.percentage) + "%"
+					}, rowprojectItem);
+					cellprojectItem.style.lineHeight = "1px";
+					var imageProgress = domConstruct.create("div", {
+						className: "ganttImageProgressBg"
+					}, cellprojectItem);
+					domStyle.set(imageProgress, {
+						width: ((100 - this.percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+						height: this.ganttChart.heightTaskItem + "px"
+					});
+				}
+			}else{
+				var cellprojectItem = domConstruct.create("td", {
+					width: "1px"
+				}, rowprojectItem);
+				cellprojectItem.style.lineHeight = "1px";
+				var imageProgress = domConstruct.create("div", {
+					className: "ganttImageProgressBg"
+				}, cellprojectItem);
+				domStyle.set(imageProgress, {
+					width: "1px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+			}
+			var divTaskInfo = domConstruct.create("div", {className: "ganttDivTaskInfo"});
+			var tblTaskInfo = domConstruct.create("table", {
+				cellPadding: "0",
+				cellSpacing: "0",
+				height: this.ganttChart.heightTaskItem + "px",
+				width: ((this.duration * this.ganttChart.pixelsPerWorkHour == 0) ? 1 : this.duration * this.ganttChart.pixelsPerWorkHour) + "px"
+			}, divTaskInfo);
+			var rowTaskInfo = tblTaskInfo.insertRow(0);
+			domConstruct.create("td", {
+				align: "center",
+				vAlign: "top",
+				height: this.ganttChart.heightTaskItem + "px",
+				className: "ganttMoveInfo"
+			}, rowTaskInfo);
+			projectItem.appendChild(divTaskInfo);
+			if(this.project.parentTasks.length == 0){
+				projectItem.style.display = "none";
+			}
+			return projectItem;
+		},
+		createProjectNameItem: function(){
+			var divName = domConstruct.create("div", {
+				className: "ganttProjectNameItem",
+				innerHTML: this.project.name,
+				title: this.project.name
+			});
+			domStyle.set(divName, {
+				left: "5px",
+				top: this.posY + "px"
+			});
+			domAttr.set(divName, "tabIndex", 0);
+			if(this.ganttChart.isShowConMenu){
+				this.ganttChart._events.push(
+					on(divName, "mouseover", lang.hitch(this, function(event){
+						domClass.add(divName, "ganttProjectNameItemHover");
+						clearTimeout(this.ganttChart.menuTimer);
+						this.ganttChart.tabMenu.clear();
+						this.ganttChart.tabMenu.show(event.target, this);
+					}))
+				);
+				this.ganttChart._events.push(
+					on(divName, "keydown", lang.hitch(this, function(event){
+						if(event.keyCode == keys.ENTER){
+							this.ganttChart.tabMenu.clear();
+							this.ganttChart.tabMenu.show(event.target, this);
+						}
+						if(this.ganttChart.tabMenu.isShow && (event.keyCode == keys.LEFT_ARROW || event.keyCode == keys.RIGHT_ARROW)){
+							focus(this.ganttChart.tabMenu.menuPanel.firstChild.rows[0].cells[0]);
+						}
+						if(this.ganttChart.tabMenu.isShow && event.keyCode == keys.ESCAPE){
+							this.ganttChart.tabMenu.hide();
+						}
+					}))
+				);
+				this.ganttChart._events.push(
+					on(divName, "mouseout", lang.hitch(this, function(){
+						domClass.remove(divName, "ganttProjectNameItemHover");
+						clearTimeout(this.ganttChart.menuTimer);
+						this.ganttChart.menuTimer = setTimeout(lang.hitch(this, function(){
+							this.ganttChart.tabMenu.hide();
+						}), 200);
+					}))
+				);
+				this.ganttChart._events.push(
+					on(this.ganttChart.tabMenu.menuPanel, "mouseover", lang.hitch(this, function(){
+						clearTimeout(this.ganttChart.menuTimer);
+					}))
+				);
+				this.ganttChart._events.push(
+					on(this.ganttChart.tabMenu.menuPanel, "keydown", lang.hitch(this, function(){
+						if(this.ganttChart.tabMenu.isShow && event.keyCode == keys.ESCAPE){
+							this.ganttChart.tabMenu.hide();
+						}
+					}))
+				);
+				this.ganttChart._events.push(
+					on(this.ganttChart.tabMenu.menuPanel, "mouseout", lang.hitch(this, function(){
+						clearTimeout(this.ganttChart.menuTimer);
+						this.ganttChart.menuTimer = setTimeout(lang.hitch(this, function(){
+							this.ganttChart.tabMenu.hide();
+						}), 200);
+					}))
+				);
+			}
+			return divName;
+		},
+		getPercentCompleted: function(){
+			var sum = 0;
+			arrayUtil.forEach(this.project.parentTasks, function(ppTask){
+				sum += parseInt(ppTask.percentage);
+			}, this);
+			if(this.project.parentTasks.length != 0){
+				return Math.round(sum / this.project.parentTasks.length);
+			}else{
+				return -1;
+			}
+		},
+		getDuration: function(){
+			var duration = 0, tmpDuration = 0;
+			if(this.project.parentTasks.length > 0){
+				arrayUtil.forEach(this.project.parentTasks, function(ppTask){
+					tmpDuration = ppTask.duration * 24 / this.ganttChart.hsPerDay + (ppTask.startTime - this.ganttChart.startDate) / (60 * 60 * 1000);
+					if(tmpDuration > duration){
+						duration = tmpDuration;
+					}
+				}, this);
+				return ((duration - this.posX) / 24) * this.ganttChart.hsPerDay;
+			}else{
+				return 0;
+			}
+		},
+		deleteTask: function(id){
+			var task = this.getTaskById(id);
+			if(task){
+				this.deleteChildTask(task);
+				this.ganttChart.checkPosition();
+			}
+		},
+		setName: function(name){
+			if(name){
+				this.project.name = name;
+				this.projectNameItem.innerHTML = name;
+				this.projectNameItem.title = name;
+				this.checkWidthProjectNameItem();
+			
+				this.descrProject.innerHTML = this.getDescStr();
+				this.adjustPanelTime();
+			}
+		},
+		setPercentCompleted: function(percentage){
+			percentage = parseInt(percentage);
+			if(isNaN(percentage) || percentage > 100 || percentage < 0){
+				return false;
+			}
+			var prow = this.projectItem[0].firstChild.rows[0],
+				rc0 = prow.cells[0], rc1 = prow.cells[1];
+			if((percentage > 0) && (percentage < 100) && (this.percentage > 0) && (this.percentage < 100)){
+				rc0.width = parseInt(percentage) + "%";
+				rc0.firstChild.style.width = (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px";
+				rc1.width = (100 - parseInt(percentage)) + "%";
+				rc1.firstChild.style.width = ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px";
+			}else if(((percentage == 0) || (percentage == 100)) && (this.percentage > 0) && (this.percentage < 100)){
+				if(percentage == 0){
+					rc0.parentNode.removeChild(rc0);
+					rc1.width = 100 + "%";
+					rc1.firstChild.style.width = this.duration * this.ganttChart.pixelsPerWorkHour + "px";
+				}else if(percentage == 100){
+					rc1.parentNode.removeChild(rc1);
+					rc0.width = 100 + "%";
+					rc0.firstChild.style.width = this.duration * this.ganttChart.pixelsPerWorkHour + "px";
+				}
+			}else if(((percentage == 0) || (percentage == 100)) && ((this.percentage == 0) || (this.percentage == 100))){
+				if((percentage == 0) && (this.percentage == 100)){
+					domClass.remove(rc0.firstChild, "ganttImageProgressFilled");
+					domClass.add(rc0.firstChild, "ganttImageProgressBg");
+				}else if((percentage == 100) && (this.percentage == 0)){
+					domClass.remove(rc0.firstChild, "ganttImageProgressBg");
+					domClass.add(rc0.firstChild, "ganttImageProgressFilled");
+				}
+			}else if(((percentage > 0) || (percentage < 100)) && ((this.percentage == 0) || (this.percentage == 100))){
+				rc0.parentNode.removeChild(rc0);
+				var cellprojectItem = domConstruct.create("td", {
+					width: percentage + "%"
+				}, prow);
+				cellprojectItem.style.lineHeight = "1px";
+				var imageProgress = domConstruct.create("div", {
+					className: "ganttImageProgressFilled"
+				}, cellprojectItem);
+				domStyle.set(imageProgress, {
+					width: (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+				cellprojectItem = domConstruct.create("td", {
+					width: (100 - percentage) + "%"
+				}, prow);
+				cellprojectItem.style.lineHeight = "1px";
+				imageProgress = domConstruct.create("div", {
+					className: "ganttImageProgressBg"
+				}, cellprojectItem);
+				domStyle.set(imageProgress, {
+					width: ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+			}else if(this.percentage == -1){
+				if(percentage == 100){
+					domClass.remove(rc0.firstChild, "ganttImageProgressBg");
+					domClass.add(rc0.firstChild, "ganttImageProgressFilled");
+				}else if(percentage < 100 && percentage > 0){
+					rc0.parentNode.removeChild(rc0);
+					var cellprojectItem = domConstruct.create("td", {
+						width: percentage + "%"
+					}, prow);
+					cellprojectItem.style.lineHeight = "1px";
+					imageProgress = domConstruct.create("div", {
+						className: "ganttImageProgressFilled"
+					}, cellprojectItem);
+					domStyle.set(imageProgress, {
+						width: (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+						height: this.ganttChart.heightTaskItem + "px"
+					});
+					cellprojectItem = domConstruct.create("td", {
+						width: (100 - percentage) + "%"
+					}, prow);
+					cellprojectItem.style.lineHeight = "1px";
+					imageProgress = domConstruct.create("div", {
+						className: "ganttImageProgressBg"
+					}, cellprojectItem);
+					domStyle.set(imageProgress, {
+						width: ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+						height: this.ganttChart.heightTaskItem + "px"
+					});
+				}
+			}
+			this.percentage = percentage;
+			this.descrProject.innerHTML = this.getDescStr();
+			return true;
+		},
+		deleteChildTask: function(task){
+			if(task){
+				var tItem0 = task.cTaskItem[0], tNameItem0 = task.cTaskNameItem[0],
+					tItem1 = task.cTaskItem[1], tNameItem1 = task.cTaskNameItem[1],
+					tNameItem2 = task.cTaskNameItem[2];
+				if(tItem0.style.display == "none"){
+					this.ganttChart.openTree(task.parentTask);
+				}
+				//delete of connecting lines
+				if(task.childPredTask.length > 0){
+					for(var i = 0; i < task.childPredTask.length; i++){
+						var cpTask = task.childPredTask[i];
+						for(var t = 0; t < cpTask.cTaskItem[1].length; t++){
+							cpTask.cTaskItem[1][t].parentNode.removeChild(cpTask.cTaskItem[1][t]);
+						}
+						cpTask.cTaskItem[1] = [];
+						cpTask.predTask = null;
+					}
+				}
+				//delete child task
+				if(task.childTask.length > 0){
+					while(task.childTask.length > 0){
+						this.deleteChildTask(task.childTask[0]);
+					}
+				}
+				//shift tasks
+				var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+				if(tItem0.style.display != "none"){
+					task.shiftCurrentTasks(task, -rowHeight);
+				}
+				//delete object task
+				this.project.deleteTask(task.taskItem.id);
+				//delete div and connecting lines from contentData
+				if(tItem0){
+					tItem0.parentNode.removeChild(tItem0);
+				}
+				task.descrTask.parentNode.removeChild(task.descrTask);
+				if(tItem1.length > 0){
+					for(var j = 0; j < tItem1.length; j++){
+						tItem1[j].parentNode.removeChild(tItem1[j]);
+					}
+				}
+				//delete div and connecting lines from panelName
+				if(tNameItem0){
+					tNameItem0.parentNode.removeChild(tNameItem0);
+				}
+				if(task.cTaskNameItem[1]){
+					for(var j = 0; j < tNameItem1.length; j++){
+						tNameItem1[j].parentNode.removeChild(tNameItem1[j]);
+					}
+				}
+				if(tNameItem2 && tNameItem2.parentNode){
+					tNameItem2.parentNode.removeChild(tNameItem2);
+				}
+				if(task.taskIdentifier){
+					task.taskIdentifier.parentNode.removeChild(task.taskIdentifier);
+					task.taskIdentifier = null;
+				}
+				//delete object task
+				if(task.parentTask){
+					if(task.previousChildTask){
+						if(task.nextChildTask){
+							task.previousChildTask.nextChildTask = task.nextChildTask;
+						}else{
+							task.previousChildTask.nextChildTask = null;
+						}
+					}
+					var parentTask = task.parentTask;
+					for(var i = 0; i < parentTask.childTask.length; i++){
+						if(parentTask.childTask[i].taskItem.id == task.taskItem.id){
+							parentTask.childTask[i] = null;
+							parentTask.childTask.splice(i, 1);
+							break;
+						}
+					}
+					if(parentTask.childTask.length == 0){
+						if(parentTask.cTaskNameItem[2]){
+							parentTask.cTaskNameItem[2].parentNode.removeChild(parentTask.cTaskNameItem[2]);
+							parentTask.cTaskNameItem[2] = null;
+						}
+					}
+				}else{
+					if(task.previousParentTask){
+						if(task.nextParentTask){
+							task.previousParentTask.nextParentTask = task.nextParentTask;
+						}else{
+							task.previousParentTask.nextParentTask = null;
+						}
+					}
+					var project = task.project;
+					for(var i = 0; i < project.arrTasks.length; i++){
+						if(project.arrTasks[i].taskItem.id == task.taskItem.id){
+							project.arrTasks.splice(i, 1);
+						}
+					}
+				}
+				if(task.predTask){
+					var predTask = task.predTask;
+					for(var i = 0; i < predTask.childPredTask.length; i++){
+						if(predTask.childPredTask[i].taskItem.id == task.taskItem.id){
+							predTask.childPredTask[i] = null;
+							predTask.childPredTask.splice(i, 1);
+						}
+					}
+				}
+				if(task.project.arrTasks.length != 0){
+					task.project.shiftProjectItem();
+				}else{
+					task.project.projectItem[0].style.display = "none";
+					this.hideDescrProject();
+				}
+				this.ganttChart.contentDataHeight -= this.ganttChart.heightTaskItemExtra + this.ganttChart.heightTaskItem;
+			}
+		},
+	
+		insertTask: function(id, name, startTime, duration, percentage, previousTaskId, taskOwner, parentTaskId){
+			var task = null;
+			var _task = null;
+			if(this.project.getTaskById(id)){
+				return false;
+			}
+			if((!duration) || (duration < this.ganttChart.minWorkLength)){
+				duration = this.ganttChart.minWorkLength;
+			}
+			if((!name) || (name == "")){
+				name = id;
+			}
+			if((!percentage) || (percentage == "")){
+				percentage = 0;
+			
+			}else{
+				percentage = parseInt(percentage);
+				if(percentage < 0 || percentage > 100){
+					return false;
+				}
+			}
+			var sortRequired = false;
+			if((parentTaskId) && (parentTaskId != "")){
+				var parentTask = this.project.getTaskById(parentTaskId);
+				if(!parentTask){
+					return false;
+				}
+				startTime = startTime || parentTask.startTime;
+				if(startTime < parentTask.startTime){
+					return false;
+				}
+				task = new GanttTaskItem({
+					id: id,
+					name: name,
+					startTime: startTime,
+					duration: duration,
+					percentage: percentage,
+					previousTaskId: previousTaskId,
+					taskOwner: taskOwner
+				});
+				if(!this.ganttChart.checkPosParentTask(parentTask, task)){
+					return false;
+				}
+				task.parentTask = parentTask;
+				var _parentTask = this.getTaskById(parentTask.id);
+				var isHide = false;
+				if(_parentTask.cTaskItem[0].style.display == "none"){
+					isHide = true;
+				}else if(_parentTask.cTaskNameItem[2]){
+					if(!_parentTask.isExpanded){
+						isHide = true;
+					}
+				}
+				if(isHide){
+					if(_parentTask.childTask.length == 0){
+						this.ganttChart.openTree(_parentTask.parentTask);
+					}else{
+						this.ganttChart.openTree(_parentTask);
+					}
+				}
+				if(previousTaskId != ""){
+					var predTask = this.project.getTaskById(previousTaskId);
+					if(!predTask){
+						return false;
+					}
+					if(predTask.parentTask){
+						if(predTask.parentTask.id != task.parentTask.id){
+							return false;
+						}
+					}else{
+						return false;
+					}
+					if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
+						this.ganttChart.correctPosPreviousTask(predTask, task);
+					}
+					task.previousTask = predTask;
+				}
+				var isAdd = false;
+				if(sortRequired) for(var i = 0; i < parentTask.cldTasks.length; i++){
+					if(task.startTime < parentTask.cldTasks[i].startTime){
+						parentTask.cldTasks.splice(i, 0, task);
+						if(i > 0){
+							parentTask.cldTasks[i - 1].nextChildTask = parentTask.cldTasks[i];
+							parentTask.cldTasks[i].previousChildTask = parentTask.cldTasks[i - 1];
+						}
+						if(parentTask.cldTasks[i + 1]){
+							parentTask.cldTasks[i + 1].previousChildTask = parentTask.cldTasks[i];
+							parentTask.cldTasks[i].nextChildTask = parentTask.cldTasks[i + 1];
+						}
+						isAdd = true;
+						break;
+					}
+				}
+				if(!isAdd){
+					if(parentTask.cldTasks.length > 0){
+						parentTask.cldTasks[parentTask.cldTasks.length - 1].nextChildTask = task;
+						task.previousChildTask = parentTask.cldTasks[parentTask.cldTasks.length - 1];
+					}
+					parentTask.cldTasks.push(task);
+				}
+				if(parentTask.cldTasks.length == 1){
+					_parentTask.cTaskNameItem[2] = _parentTask.createTreeImg();
+				}
+				_task = new GanttTaskControl(task, this, this.ganttChart);
+				_task.create();
+				if(task.nextChildTask) _task.nextChildTask = _task.project.getTaskById(task.nextChildTask.id);
+				_task.adjustPanelTime();
+				var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+				_task.shiftCurrentTasks(_task, rowHeight);//23
+			}else{
+				startTime = startTime || this.project.startDate;
+				task = new GanttTaskItem({
+					id: id,
+					name: name,
+					startTime: startTime,
+					duration: duration,
+					percentage: percentage,
+					previousTaskId: previousTaskId,
+					taskOwner: taskOwner
+				});
+				if(task.startTime <= this.ganttChart.startDate){
+					return false;
+				}
+				if(previousTaskId != ""){
+					var predTask = this.project.getTaskById(previousTaskId);
+					if(!predTask){
+						return false;
+					}
+					if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
+						this.ganttChart.correctPosPreviousTask(predTask, task);
+					}
+					if(predTask.parentTask){
+						return false;
+					}
+					task.previousTask = predTask;
+				}
+				var isAdd = false;
+				if(sortRequired){
+					for(var i = 0; i < this.project.parentTasks.length; i++){
+						var ppTask = this.project.parentTasks[i];
+						if(startTime < ppTask.startTime){
+							this.project.parentTasks.splice(i, 0, task);
+							if(i > 0){
+								this.project.parentTasks[i - 1].nextParentTask = task;
+								task.previousParentTask = this.project.parentTasks[i - 1];
+							}
+							if(this.project.parentTasks[i + 1]){
+								this.project.parentTasks[i + 1].previousParentTask = task;
+								task.nextParentTask = this.project.parentTasks[i + 1];
+							}
+							isAdd = true;
+							break;
+						}
+					}
+				}
+				if(!isAdd){
+					if(this.project.parentTasks.length > 0){
+						this.project.parentTasks[this.project.parentTasks.length - 1].nextParentTask = task;
+						task.previousParentTask = this.project.parentTasks[this.project.parentTasks.length - 1];
+					}
+					this.project.parentTasks.push(task);
+				}
+				_task = new GanttTaskControl(task, this, this.ganttChart);
+				_task.create();
+				if(task.nextParentTask) _task.nextParentTask = _task.project.getTaskById(task.nextParentTask.id);
+				_task.adjustPanelTime();
+				this.arrTasks.push(_task);
+				var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+				_task.shiftCurrentTasks(_task, rowHeight);
+				this.projectItem[0].style.display = "inline";
+				this.setPercentCompleted(this.getPercentCompleted());
+				this.shiftProjectItem();
+				this.showDescrProject();
+			}
+			this.ganttChart.checkHeighPanelTasks();
+			this.ganttChart.checkPosition();
+			return _task;
+		},
+		shiftNextProject: function(project, height){
+			if(project.nextProject){
+				project.nextProject.shiftProject(height);
+				this.shiftNextProject(project.nextProject, height);
+			}
+		},
+		shiftProject: function(height){
+			this.posY = this.posY + height;
+			this.projectItem[0].style.top = parseInt(this.projectItem[0].style.top) + height + "px";
+			this.descrProject.style.top = parseInt(this.descrProject.style.top) + height + "px";
+			this.projectNameItem.style.top = parseInt(this.projectNameItem.style.top) + height + "px";
+			if(this.arrTasks.length > 0){
+				this.shiftNextParentTask(this.arrTasks[0], height);
+			}
+		},
+		shiftTask: function(task, height){
+			task.posY = task.posY + height;
+			var tNameItem0 = task.cTaskNameItem[0], tNameItem1 = task.cTaskNameItem[1], tNameItem2 = task.cTaskNameItem[2],
+				tItem1 = task.cTaskItem[1];
+			tNameItem0.style.top = parseInt(tNameItem0.style.top) + height + "px";
+			if(tNameItem2){
+				tNameItem2.style.top = parseInt(tNameItem2.style.top) + height + "px";
+			}
+			if(task.parentTask){
+				tNameItem1[0].style.top = parseInt(tNameItem1[0].style.top) + height + "px";
+				tNameItem1[1].style.top = parseInt(tNameItem1[1].style.top) + height + "px";
+			}
+			task.cTaskItem[0].style.top = parseInt(task.cTaskItem[0].style.top) + height + "px";
+			task.descrTask.style.top = parseInt(task.descrTask.style.top) + height + "px";
+			if(tItem1[0]){
+				tItem1[0].style.top = parseInt(tItem1[0].style.top) + height + "px";
+				tItem1[1].style.top = parseInt(tItem1[1].style.top) + height + "px";
+				tItem1[2].style.top = parseInt(tItem1[2].style.top) + height + "px";
+			}
+		},
+		shiftNextParentTask: function(task, height){
+			this.shiftTask(task, height);
+			this.shiftChildTasks(task, height);
+			if(task.nextParentTask){
+				this.shiftNextParentTask(task.nextParentTask, height);
+			}
+		},
+		shiftChildTasks: function(task, height){
+			arrayUtil.forEach(task.childTask, function(cTask){
+				this.shiftTask(cTask, height);
+				if(cTask.childTask.length > 0){
+					this.shiftChildTasks(cTask, height);
+				}
+			}, this);
+		}
+	});
+});
diff --git a/dojox/gantt/GanttProjectItem.js b/dojox/gantt/GanttProjectItem.js
index 531b613..735fb84 100644
--- a/dojox/gantt/GanttProjectItem.js
+++ b/dojox/gantt/GanttProjectItem.js
@@ -1,968 +1,99 @@
-dojo.provide("dojox.gantt.GanttProjectItem");
-
-dojo.require("dojox.gantt.GanttTaskItem");
-dojo.require("dojo.date.locale");
-dojo.require("dijit.focus");		// dijit.focus()
-
-dojo.declare("dojox.gantt.GanttProjectControl", null, {
-	constructor: function(ganttChart, projectItem){
-		this.project = projectItem;
-		this.ganttChart = ganttChart;
-		this.descrProject = null;
-		this.projectItem = null;
-		this.projectNameItem = null;
-		this.posY = 0;
-		this.posX = 0;
-		this.nextProject = null;
-		this.previousProject = null;
-		this.arrTasks = [];
-		this.percentage = 0;
-		this.duration = 0;
-	},
-	checkWidthProjectNameItem: function(){
-		if(this.projectNameItem.offsetWidth + this.projectNameItem.offsetLeft > this.ganttChart.maxWidthTaskNames){
-			var width = this.projectNameItem.offsetWidth + this.projectNameItem.offsetLeft - this.ganttChart.maxWidthTaskNames;
-			var countChar = Math.round(width / (this.projectNameItem.offsetWidth / this.projectNameItem.firstChild.length));
-			var pName = this.project.name.substring(0, this.projectNameItem.firstChild.length - countChar - 3);
-			pName += "...";
-			this.projectNameItem.innerHTML = pName;
-		}
-	},
-	refreshProjectItem: function(projectItem){
-		this.percentage = this.getPercentCompleted();
-		dojo.style(projectItem, {
-			"left": this.posX + "px",
-			"width": this.duration * this.ganttChart.pixelsPerWorkHour + "px"
-		});
-		var tblProjectItem = projectItem.firstChild;
-		var width = this.duration * this.ganttChart.pixelsPerWorkHour;
-		tblProjectItem.width = ((width == 0) ? 1 : width) + "px";
-		tblProjectItem.style.width = ((width == 0) ? 1 : width) + "px";
-		var rowprojectItem = tblProjectItem.rows[0];
-		if(this.percentage != -1){
-			if(this.percentage != 0){
-				var cellprojectItem = rowprojectItem.firstChild;
-				cellprojectItem.width = this.percentage + "%";
-				var imageProgress = cellprojectItem.firstChild;
-				dojo.style(imageProgress, {
-					width: (!this.duration ? 1 : (this.percentage * this.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
-					height: this.ganttChart.heightTaskItem + "px"
-				})
-			}
-			if(this.percentage != 100){
-				var cellprojectItem = rowprojectItem.lastChild;
-				cellprojectItem.width = (100 - this.percentage) + "%";
-				var imageProgress = cellprojectItem.firstChild;
-				dojo.style(imageProgress, {
-					width: (!this.duration ? 1 : ((100 - this.percentage) * this.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
-					height: this.ganttChart.heightTaskItem + "px"
-				})
-			}
-		}else{
-			var cellprojectItem = rowprojectItem.firstChild;
-			cellprojectItem.width = "1px";
-			var imageProgress = cellprojectItem.firstChild;
-			dojo.style(imageProgress, {
-				width: "1px",
-				height: this.ganttChart.heightTaskItem + "px"
-			})
-		}
-		var divTaskInfo = projectItem.lastChild;
-		var tblTaskInfo = divTaskInfo.firstChild;
-		dojo.style(tblTaskInfo, {
-			height: this.ganttChart.heightTaskItem + "px",
-			width: (!this.duration ? 1 : (this.duration * this.ganttChart.pixelsPerWorkHour)) + "px"
-		});
-		var rowTaskInfo = tblTaskInfo.rows[0];
-		var cellTaskInfo = rowTaskInfo.firstChild;
-		cellTaskInfo.height = this.ganttChart.heightTaskItem + "px";
-		if(this.project.parentTasks.length == 0){
-			projectItem.style.display = "none";
-		}
-		return projectItem;
-	},
-	refreshDescrProject: function(divDesc){
-		var posX = (this.posX + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
-		dojo.style(divDesc, {
-			"left": posX + "px"
-		});
-		if(this.project.parentTasks.length == 0){
-			this.descrProject.style.visibility = 'hidden';
-		}
-		return divDesc;
-	},
-	postLoadData: function(){
-		//TODO e.g. project relative info...
-	},
-	refresh: function(){
-		var containerTasks = this.ganttChart.contentData.firstChild;
-		this.posX = (this.project.startDate - this.ganttChart.startDate) / (60 * 60 * 1000) * this.ganttChart.pixelsPerHour;
-		this.refreshProjectItem(this.projectItem[0]);
-		this.refreshDescrProject(this.projectItem[0].nextSibling);
-		return this;
-	},
-	create: function(){
-		var containerTasks = this.ganttChart.contentData.firstChild;
-		this.posX = (this.project.startDate - this.ganttChart.startDate) / (60 * 60 * 1000) * this.ganttChart.pixelsPerHour;
-		if(this.previousProject){
-			if(this.previousProject.arrTasks.length > 0){
-				var lastChildTask = this.ganttChart.getLastChildTask(this.previousProject.arrTasks[this.previousProject.arrTasks.length - 1]);
-				this.posY = parseInt(lastChildTask.cTaskItem[0].style.top) + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
-			}else{
-				this.posY = parseInt(this.previousProject.projectItem[0].style.top) + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
-			}
-		}else{
-			this.posY = 6;
-		}
-		var containerNames = this.ganttChart.panelNames.firstChild;
-		this.projectNameItem = this.createProjectNameItem();
-		containerNames.appendChild(this.projectNameItem);
-		this.checkWidthProjectNameItem();
-		this.projectItem = [this.createProjectItem(), []];
-		containerTasks.appendChild(this.projectItem[0]);
-		containerTasks.appendChild(this.createDescrProject());
-		this.adjustPanelTime();
-	},
-	getTaskById: function(id){
-		for(var i = 0; i < this.arrTasks.length; i++){
-			var aTask = this.arrTasks[i];
-			var task = this.searchTaskInTree(aTask, id);
-			if(task){
-				return task;
-			}
-		}
-		return null;
-	},
-	searchTaskInTree: function(task, id){
-		if(task.taskItem.id == id){
-			return task;
-		}else{
-			for(var i = 0; i < task.childTask.length; i++){
-				var cTask = task.childTask[i];
-				if(cTask.taskItem.id == id){
-					return cTask;
-				}else{
-					if(cTask.childTask.length > 0){
-						var cTask = this.searchTaskInTree(cTask, id);
-						if(cTask){
-							return cTask;
-						}
-					}
-				}
-			}
-		}
-		return null;
-	},
-	shiftProjectItem: function(){
-		var posItemL = null;
-		var posItemR = null;
-		var posProjectItemL = parseInt(this.projectItem[0].style.left);
-		var posProjectItemR = parseInt(this.projectItem[0].firstChild.style.width) + parseInt(this.projectItem[0].style.left);
-		var widthProjectItem = parseInt(this.projectItem[0].firstChild.style.width);
-		for(var i = 0; i < this.arrTasks.length; i++){
-			var aTask = this.arrTasks[i];
-			var tmpPosItemL = parseInt(aTask.cTaskItem[0].style.left);
-			var tmpPosItemR = parseInt(aTask.cTaskItem[0].style.left) + parseInt(aTask.cTaskItem[0].firstChild.firstChild.width);
-			if(!posItemL){
-				posItemL = tmpPosItemL;
-			}
-			if(!posItemR){
-				posItemR = tmpPosItemR;
-			}
-			if(posItemL > tmpPosItemL){
-				posItemL = tmpPosItemL;
-			}
-			if(posItemR < tmpPosItemR){
-				posItemR = tmpPosItemR;
-			}
-		}
-		if(posItemL != posProjectItemL){
-			this.project.startDate = new Date(this.ganttChart.startDate);
-			this.project.startDate.setHours(this.project.startDate.getHours() + (posItemL / this.ganttChart.pixelsPerHour));
-		}
-		this.projectItem[0].style.left = posItemL + "px";
-		this.resizeProjectItem(posItemR - posItemL);
-		this.duration = Math.round(parseInt(this.projectItem[0].firstChild.width) / (this.ganttChart.pixelsPerWorkHour));
-		this.shiftDescrProject();
-		this.adjustPanelTime();
-	},
-	adjustPanelTime: function(){
-		var projectItem = this.projectItem[0];
-		var width = parseInt(projectItem.style.left) + parseInt(projectItem.firstChild.style.width) + this.ganttChart.panelTimeExpandDelta;
-		width += this.descrProject.offsetWidth;
-		this.ganttChart.adjustPanelTime(width);
-	},
-	resizeProjectItem: function(width){
-		var percentage = this.percentage,
-			pItem = this.projectItem[0];
-		if(percentage > 0 && percentage < 100){
-			pItem.firstChild.style.width = width + "px";
-			pItem.firstChild.width = width + "px";
-			pItem.style.width = width + "px";
-			var firstRow = pItem.firstChild.rows[0];
-			firstRow.cells[0].firstChild.style.width = Math.round(width * percentage / 100) + "px";
-			firstRow.cells[0].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
-			firstRow.cells[1].firstChild.style.width = Math.round(width * (100 - percentage) / 100) + "px";
-			firstRow.cells[1].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
-			pItem.lastChild.firstChild.width = width + "px";
-		}else if(percentage == 0 || percentage == 100){
-			pItem.firstChild.style.width = width + "px";
-			pItem.firstChild.width = width + "px";
-			pItem.style.width = width + "px";
-			var firstRow = pItem.firstChild.rows[0];
-			firstRow.cells[0].firstChild.style.width = width + "px";
-			firstRow.cells[0].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
-			pItem.lastChild.firstChild.width = width + "px";
-		}
-	},
-	shiftDescrProject: function(){
-		var posX = (parseInt(this.projectItem[0].style.left) + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
-		this.descrProject.style.left = posX + "px";
-		this.descrProject.innerHTML = this.getDescStr();
-	},
-	showDescrProject: function(){
-		var posX = (parseInt(this.projectItem[0].style.left) + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
-		this.descrProject.style.left = posX + "px";
-		this.descrProject.style.visibility = 'visible';
-		this.descrProject.innerHTML = this.getDescStr();
-	},
-	hideDescrProject: function(){
-		this.descrProject.style.visibility = 'hidden';
-	},
-	getDescStr: function(){
-		return this.duration/this.ganttChart.hsPerDay + " days,  " + this.duration + " hours";
-	},
-	createDescrProject: function(){
-		var posX = (this.posX + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
-		var divDesc = dojo.create("div", {
-			innerHTML: this.getDescStr(),
-			className: "ganttDescProject"
-		});
-		dojo.style(divDesc, {
-			left: posX + "px",
-			top: this.posY + "px"
-		});
-		this.descrProject = divDesc;
-		if(this.project.parentTasks.length == 0){
-			this.descrProject.style.visibility = 'hidden';
-		}
-		return divDesc;
-	},
-	createProjectItem: function(){
-		this.percentage = this.getPercentCompleted();
-		this.duration = this.getDuration();
-		var projectItem = dojo.create("div", {
-			id: this.project.id,
-			className: "ganttProjectItem"
-		});
-		dojo.style(projectItem, {
-			left: this.posX + "px",
-			top: this.posY + "px",
-			width: this.duration * this.ganttChart.pixelsPerWorkHour + "px"
-		});
-		var tblProjectItem = dojo.create("table", {
-			cellPadding: "0",
-			cellSpacing: "0",
-			className: "ganttTblProjectItem"
-		}, projectItem);
-		var width = this.duration * this.ganttChart.pixelsPerWorkHour;
-		tblProjectItem.width = ((width == 0) ? 1 : width) + "px";
-		tblProjectItem.style.width = ((width == 0) ? 1 : width) + "px";
-		
-		var rowprojectItem = tblProjectItem.insertRow(tblProjectItem.rows.length);
-		if(this.percentage != -1){
-			if(this.percentage != 0){
-				var cellprojectItem = dojo.create("td", {
-					width: this.percentage + "%"
-				}, rowprojectItem);
-				cellprojectItem.style.lineHeight = "1px";
-				var imageProgress = dojo.create("div", {
-					className: "ganttImageProgressFilled"
-				}, cellprojectItem);
-				dojo.style(imageProgress, {
-					width: (this.percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
-					height: this.ganttChart.heightTaskItem + "px"
-				});
-			}
-			if(this.percentage != 100){
-				var cellprojectItem = dojo.create("td", {
-					width: (100 - this.percentage) + "%"
-				}, rowprojectItem);
-				cellprojectItem.style.lineHeight = "1px";
-				var imageProgress = dojo.create("div", {
-					className: "ganttImageProgressBg"
-				}, cellprojectItem);
-				dojo.style(imageProgress, {
-					width: ((100 - this.percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
-					height: this.ganttChart.heightTaskItem + "px"
-				});
-			}
-		}else{
-			var cellprojectItem = dojo.create("td", {
-				width: "1px"
-			}, rowprojectItem);
-			cellprojectItem.style.lineHeight = "1px";
-			var imageProgress = dojo.create("div", {
-				className: "ganttImageProgressBg"
-			}, cellprojectItem);
-			dojo.style(imageProgress, {
-				width: "1px",
-				height: this.ganttChart.heightTaskItem + "px"
-			});
-		}
-		var divTaskInfo = dojo.create("div", {className: "ganttDivTaskInfo"});
-		var tblTaskInfo = dojo.create("table", {
-			cellPadding: "0",
-			cellSpacing: "0",
-			height: this.ganttChart.heightTaskItem + "px",
-			width: ((this.duration * this.ganttChart.pixelsPerWorkHour == 0) ? 1 : this.duration * this.ganttChart.pixelsPerWorkHour) + "px"
-		}, divTaskInfo);
-		var rowTaskInfo = tblTaskInfo.insertRow(0);
-		var cellTaskInfo = dojo.create("td", {
-			align: "center",
-			vAlign: "top",
-			height: this.ganttChart.heightTaskItem + "px",
-			className: "ganttMoveInfo"
-		}, rowTaskInfo);
-		projectItem.appendChild(divTaskInfo);
-		if(this.project.parentTasks.length == 0){
-			projectItem.style.display = "none";
-		}
-		return projectItem;
-	},
-	createProjectNameItem: function(){
-		var divName = dojo.create("div", {
-			className: "ganttProjectNameItem",
-			innerHTML: this.project.name,
-			title: this.project.name
-		});
-		dojo.style(divName, {
-			left: "5px",
-			top: this.posY + "px"
-		});
-		dojo.attr(divName, "tabIndex", 0);
-		if(this.ganttChart.isShowConMenu){
-			this.ganttChart._events.push(
-				dojo.connect(divName, "onmouseover", this, function(event){
-					dojo.addClass(divName, "ganttProjectNameItemHover");
-					clearTimeout(this.ganttChart.menuTimer);
-					this.ganttChart.tabMenu.clear();
-					this.ganttChart.tabMenu.show(event.target, this);
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(divName, "onkeydown", this, function(event){
-					if(event.keyCode == dojo.keys.ENTER){
-						this.ganttChart.tabMenu.clear();
-						this.ganttChart.tabMenu.show(event.target, this);
-					}
-					if(this.ganttChart.tabMenu.isShow && (event.keyCode == dojo.keys.LEFT_ARROW || event.keyCode == dojo.keys.RIGHT_ARROW)){
-						dijit.focus(this.ganttChart.tabMenu.menuPanel.firstChild.rows[0].cells[0]);
-					}
-					if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
-						this.ganttChart.tabMenu.hide();
-					}
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(divName, "onmouseout", this, function(){
-					dojo.removeClass(divName, "ganttProjectNameItemHover");
-					clearTimeout(this.ganttChart.menuTimer);
-					this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
-						this.ganttChart.tabMenu.hide();
-					}), 200);
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseover", this, function(){
-					clearTimeout(this.ganttChart.menuTimer);
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onkeydown", this, function(event){
-					if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
-						this.ganttChart.tabMenu.hide();
-					}
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseout", this, function(){
-					clearTimeout(this.ganttChart.menuTimer);
-					this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
-						this.ganttChart.tabMenu.hide();
-					}), 200);
-				})
-			);
-		}
-		return divName;
-	},
-	getPercentCompleted: function(){
-		var sum = 0, percentage = 0;
-		dojo.forEach(this.project.parentTasks, function(ppTask){
-			sum += parseInt(ppTask.percentage);
-		}, this);
-		if(this.project.parentTasks.length != 0){
-			return percentage = Math.round(sum / this.project.parentTasks.length);
-		}else{
-			return percentage = -1;
-		}
-	},
-	getDuration: function(){
-		var duration = 0, tmpDuration = 0;
-		if(this.project.parentTasks.length > 0){
-			dojo.forEach(this.project.parentTasks, function(ppTask){
-				tmpDuration = ppTask.duration * 24 / this.ganttChart.hsPerDay + (ppTask.startTime - this.ganttChart.startDate) / (60 * 60 * 1000);
-				if(tmpDuration > duration){
-					duration = tmpDuration;
-				}
-			}, this);
-			return ((duration - this.posX) / 24) * this.ganttChart.hsPerDay;
-		}else{
-			return 0;
-		}
-	},
-	deleteTask: function(id){
-		var task = this.getTaskById(id);
-		if(task){
-			this.deleteChildTask(task);
-			this.ganttChart.checkPosition();
-		}
-	},
-	setName: function(name){
-		if(name){
-			this.project.name = name;
-			this.projectNameItem.innerHTML = name;
-			this.projectNameItem.title = name;
-			this.checkWidthProjectNameItem();
-			
-			this.descrProject.innerHTML = this.getDescStr();
-			this.adjustPanelTime();
-		}
-	},
-	setPercentCompleted: function(percentage){
-		percentage = parseInt(percentage);
-		if(isNaN(percentage) || percentage > 100 || percentage < 0){
-			return false;
-		}
-		var prow = this.projectItem[0].firstChild.rows[0],
-			rc0 = prow.cells[0], rc1 = prow.cells[1];
-		if((percentage > 0) && (percentage < 100) && (this.percentage > 0) && (this.percentage < 100)){
-			rc0.width = parseInt(percentage) + "%";
-			rc0.firstChild.style.width = (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px";
-			rc1.width = (100 - parseInt(percentage)) + "%";
-			rc1.firstChild.style.width = ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px";
-		}else if(((percentage == 0) || (percentage == 100)) && (this.percentage > 0) && (this.percentage < 100)){
-			if(percentage == 0){
-				rc0.parentNode.removeChild(rc0);
-				rc1.width = 100 + "%";
-				rc1.firstChild.style.width = this.duration * this.ganttChart.pixelsPerWorkHour + "px";
-			}else if(percentage == 100){
-				rc1.parentNode.removeChild(rc1);
-				rc0.width = 100 + "%";
-				rc0.firstChild.style.width = this.duration * this.ganttChart.pixelsPerWorkHour + "px";
-			}
-		}else if(((percentage == 0) || (percentage == 100)) && ((this.percentage == 0) || (this.percentage == 100))){
-			if((percentage == 0) && (this.percentage == 100)){
-				dojo.removeClass(rc0.firstChild, "ganttImageProgressFilled");
-				dojo.addClass(rc0.firstChild, "ganttImageProgressBg");
-			}else if((percentage == 100) && (this.percentage == 0)){
-				dojo.removeClass(rc0.firstChild, "ganttImageProgressBg");
-				dojo.addClass(rc0.firstChild, "ganttImageProgressFilled");
-			}
-		}else if(((percentage > 0) || (percentage < 100)) && ((this.percentage == 0) || (this.percentage == 100))){
-			rc0.parentNode.removeChild(rc0);
-			var cellprojectItem = dojo.create("td", {
-				width: percentage + "%"
-			}, prow);
-			cellprojectItem.style.lineHeight = "1px";
-			var imageProgress = dojo.create("div", {
-				className: "ganttImageProgressFilled"
-			}, cellprojectItem);
-			dojo.style(imageProgress, {
-				width: (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
-				height: this.ganttChart.heightTaskItem + "px"
-			});
-			cellprojectItem = dojo.create("td", {
-				width: (100 - percentage) + "%"
-			}, prow);
-			cellprojectItem.style.lineHeight = "1px";
-			imageProgress = dojo.create("div", {
-				className: "ganttImageProgressBg"
-			}, cellprojectItem);
-			dojo.style(imageProgress, {
-				width: ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
-				height: this.ganttChart.heightTaskItem + "px"
-			});
-		}else if(this.percentage == -1){
-			if(percentage == 100){
-				dojo.removeClass(rc0.firstChild, "ganttImageProgressBg");
-				dojo.addClass(rc0.firstChild, "ganttImageProgressFilled");
-			}else if(percentage < 100 && percentage > 0){
-				rc0.parentNode.removeChild(rc0);
-				var cellprojectItem = dojo.create("td", {
-					width: percentage + "%"
-				}, prow);
-				cellprojectItem.style.lineHeight = "1px";
-				imageProgress = dojo.create("div", {
-					className: "ganttImageProgressFilled"
-				}, cellprojectItem);
-				dojo.style(imageProgress, {
-					width: (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
-					height: this.ganttChart.heightTaskItem + "px"
-				});
-				cellprojectItem = dojo.create("td", {
-					width: (100 - percentage) + "%"
-				}, prow);
-				cellprojectItem.style.lineHeight = "1px";
-				imageProgress = dojo.create("div", {
-					className: "ganttImageProgressBg"
-				}, cellprojectItem);
-				dojo.style(imageProgress, {
-					width: ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
-					height: this.ganttChart.heightTaskItem + "px"
-				});
-			}
-		}
-		this.percentage = percentage;
-		this.descrProject.innerHTML = this.getDescStr();
-		return true;
-	},
-	deleteChildTask: function(task){
-		if(task){
-			var tItem0 = task.cTaskItem[0], tNameItem0 = task.cTaskNameItem[0],
-				tItem1 = task.cTaskItem[1], tNameItem1 = task.cTaskNameItem[1],
-				tItem2 = task.cTaskItem[2], tNameItem2 = task.cTaskNameItem[2];
-			if(tItem0.style.display == "none"){
-				this.ganttChart.openTree(task.parentTask);
-			}
-			//delete of connecting lines
-			if(task.childPredTask.length > 0){
-				for(var i = 0; i < task.childPredTask.length; i++){
-					var cpTask = task.childPredTask[i];
-					for(var t = 0; t < cpTask.cTaskItem[1].length; t++){
-						cpTask.cTaskItem[1][t].parentNode.removeChild(cpTask.cTaskItem[1][t]);
-					}
-					cpTask.cTaskItem[1] = [];
-					cpTask.predTask = null;
-				}
-			}
-			//delete child task
-			if(task.childTask.length > 0){
-				while(task.childTask.length > 0){
-					this.deleteChildTask(task.childTask[0]);
-				}
-			}
-			//shift tasks
-			var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
-			if(tItem0.style.display != "none"){
-				task.shiftCurrentTasks(task, -rowHeight);
-			}
-			//delete object task
-			this.project.deleteTask(task.taskItem.id);
-			//delete div and connecting lines from contentData
-			if(tItem0){
-				tItem0.parentNode.removeChild(tItem0);
-			}
-			task.descrTask.parentNode.removeChild(task.descrTask);
-			if(tItem1.length > 0){
-				for(var j = 0; j < tItem1.length; j++){
-					tItem1[j].parentNode.removeChild(tItem1[j]);
-				}
-			}
-			//delete div and connecting lines from panelName
-			if(tNameItem0){
-				tNameItem0.parentNode.removeChild(tNameItem0);
-			}
-			if(task.cTaskNameItem[1]){
-				for(var j = 0; j < tNameItem1.length; j++){
-					tNameItem1[j].parentNode.removeChild(tNameItem1[j]);
-				}
-			}
-			if(tNameItem2 && tNameItem2.parentNode){
-				tNameItem2.parentNode.removeChild(tNameItem2);
-			}
-			if(task.taskIdentifier){
-				task.taskIdentifier.parentNode.removeChild(task.taskIdentifier);
-				task.taskIdentifier = null;
-			}
-			//delete object task
-			if(task.parentTask){
-				if(task.previousChildTask){
-					if(task.nextChildTask){
-						task.previousChildTask.nextChildTask = task.nextChildTask;
-					}else{
-						task.previousChildTask.nextChildTask = null;
-					}
-				}
-				var parentTask = task.parentTask;
-				for(var i = 0; i < parentTask.childTask.length; i++){
-					if(parentTask.childTask[i].taskItem.id == task.taskItem.id){
-						parentTask.childTask[i] = null;
-						parentTask.childTask.splice(i, 1);
-						break;
-					}
-				}
-				if(parentTask.childTask.length == 0){
-					if(parentTask.cTaskNameItem[2]){
-						parentTask.cTaskNameItem[2].parentNode.removeChild(parentTask.cTaskNameItem[2]);
-						parentTask.cTaskNameItem[2] = null;
-					}
-				}
-			}else{
-				if(task.previousParentTask){
-					if(task.nextParentTask){
-						task.previousParentTask.nextParentTask = task.nextParentTask;
-					}else{
-						task.previousParentTask.nextParentTask = null;
-					}
-				}
-				var project = task.project;
-				for(var i = 0; i < project.arrTasks.length; i++){
-					if(project.arrTasks[i].taskItem.id == task.taskItem.id){
-						project.arrTasks.splice(i, 1);
-					}
-				}
-			}
-			if(task.predTask){
-				var predTask = task.predTask;
-				for(var i = 0; i < predTask.childPredTask.length; i++){
-					if(predTask.childPredTask[i].taskItem.id == task.taskItem.id){
-						predTask.childPredTask[i] = null;
-						predTask.childPredTask.splice(i, 1);
-					}
+define([
+	"./GanttTaskItem",
+	"dojo/_base/declare",
+	"./GanttProjectControl",
+	"dojo/domReady!"
+], function(GanttTaskItem, declare){
+	return declare("dojox.gantt.GanttProjectItem", [GanttTaskItem], {
+		constructor: function(configuration){
+			//id is required
+			this.id = configuration.id;
+			this.name = configuration.name || this.id;
+			this.startDate = configuration.startDate || new Date();
+			this.parentTasks = [];
+		},
+		getTaskById: function(id){
+			for(var i = 0; i < this.parentTasks.length; i++){
+				var pTask = this.parentTasks[i];
+				var task = this.getTaskByIdInTree(pTask, id);
+				if(task){
+					return task;
 				}
 			}
-			if(task.project.arrTasks.length != 0){
-				task.project.shiftProjectItem();
+			return null;
+		},
+		getTaskByIdInTree: function(parentTask, id){
+			if(parentTask.id == id){
+				return parentTask;
 			}else{
-				task.project.projectItem[0].style.display = "none";
-				this.hideDescrProject();
-			}
-			this.ganttChart.contentDataHeight -= this.ganttChart.heightTaskItemExtra + this.ganttChart.heightTaskItem;
-		}
-	},
-	
-	insertTask: function(id, name, startTime, duration, percentage, previousTaskId, taskOwner, parentTaskId){
-		var task = null;
-		var _task = null;
-		if(this.project.getTaskById(id)){
-			return false;
-		}
-		if((!duration) || (duration < this.ganttChart.minWorkLength)){
-			duration = this.ganttChart.minWorkLength;
-		}
-		if((!name) || (name == "")){
-			name = id;
-		}
-		if((!percentage) || (percentage == "")){
-			percentage = 0;
-			
-		}else{
-			percentage = parseInt(percentage);
-			if(percentage < 0 || percentage > 100){
-				return false;
-			}
-		}
-		var sortRequired = false;
-		if((parentTaskId) && (parentTaskId != "")){
-			var parentTask = this.project.getTaskById(parentTaskId);
-			if(!parentTask){
-				return false;
-			}
-			startTime = startTime || parentTask.startTime;
-			if(startTime < parentTask.startTime){
-				return false;
-			}
-			task = new dojox.gantt.GanttTaskItem({
-				id: id,
-				name: name,
-				startTime: startTime,
-				duration: duration,
-				percentage: percentage,
-				previousTaskId: previousTaskId,
-				taskOwner: taskOwner
-			});
-			if(!this.ganttChart.checkPosParentTask(parentTask, task)){
-				return false;
-			}
-			task.parentTask = parentTask;
-			var _parentTask = this.getTaskById(parentTask.id);
-			var isHide = false;
-			if(_parentTask.cTaskItem[0].style.display == "none"){
-				isHide = true;
-			}else if(_parentTask.cTaskNameItem[2]){
-				if(!_parentTask.isExpanded){
-					isHide = true;
-				}
-			}
-			if(isHide){
-				if(_parentTask.childTask.length == 0){
-					this.ganttChart.openTree(_parentTask.parentTask);
-				}else{
-					this.ganttChart.openTree(_parentTask);
-				}
-			}
-			if(previousTaskId != ""){
-				var predTask = this.project.getTaskById(previousTaskId);
-				if(!predTask){
-					return false;
-				}
-				if(predTask.parentTask){
-					if(predTask.parentTask.id != task.parentTask.id){
-						return false;
-					}
-				}else{
-					return false;
-				}
-				if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
-					this.ganttChart.correctPosPreviousTask(predTask, task);
-				}
-				task.previousTask = predTask;
-			}
-			var isAdd = false;
-			if(sortRequired) for(var i = 0; i < parentTask.cldTasks.length; i++){
-				if(task.startTime < parentTask.cldTasks[i].startTime){
-					parentTask.cldTasks.splice(i, 0, task);
-					if(i > 0){
-						parentTask.cldTasks[i - 1].nextChildTask = parentTask.cldTasks[i];
-						parentTask.cldTasks[i].previousChildTask = parentTask.cldTasks[i - 1];
+				for(var i = 0; i < parentTask.cldTasks.length; i++){
+					var pcTask = parentTask.cldTasks[i];
+					if(pcTask.id == id){
+						return pcTask;
 					}
-					if(parentTask.cldTasks[i + 1]){
-						parentTask.cldTasks[i + 1].previousChildTask = parentTask.cldTasks[i];
-						parentTask.cldTasks[i].nextChildTask = parentTask.cldTasks[i + 1];
-					}
-					isAdd = true;
-					break;
-				}
-			}
-			if(!isAdd){
-				if(parentTask.cldTasks.length > 0){
-					parentTask.cldTasks[parentTask.cldTasks.length - 1].nextChildTask = task;
-					task.previousChildTask = parentTask.cldTasks[parentTask.cldTasks.length - 1];
-				}
-				parentTask.cldTasks.push(task);
-			}
-			if(parentTask.cldTasks.length == 1){
-				var treeImg = _parentTask.createTreeImg();
-				_parentTask.cTaskNameItem[2] = treeImg;
-			}
-			_task = new dojox.gantt.GanttTaskControl(task, this, this.ganttChart);
-			_task.create();
-			if(task.nextChildTask) _task.nextChildTask = _task.project.getTaskById(task.nextChildTask.id);
-			_task.adjustPanelTime();
-			var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
-			_task.shiftCurrentTasks(_task, rowHeight);//23
-		}else{
-			startTime = startTime || this.project.startDate;
-			task = new dojox.gantt.GanttTaskItem({
-				id: id,
-				name: name,
-				startTime: startTime,
-				duration: duration,
-				percentage: percentage,
-				previousTaskId: previousTaskId,
-				taskOwner: taskOwner
-			});
-			if(task.startTime <= this.ganttChart.startDate){
-				return false;
-			}
-			if(previousTaskId != ""){
-				var predTask = this.project.getTaskById(previousTaskId);
-				if(!predTask){
-					return false;
-				}
-				if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
-					this.ganttChart.correctPosPreviousTask(predTask, task);
-				}
-				if(predTask.parentTask){
-					return false;
-				}
-				task.previousTask = predTask;
-			}
-			var isAdd = false;
-			if(sortRequired){
-				for(var i = 0; i < this.project.parentTasks.length; i++){
-					var ppTask = this.project.parentTasks[i];
-					if(startTime < ppTask.startTime){
-						this.project.parentTasks.splice(i, 0, task);
-						if(i > 0){
-							this.project.parentTasks[i - 1].nextParentTask = task;
-							task.previousParentTask = this.project.parentTasks[i - 1];
-						}
-						if(this.project.parentTasks[i + 1]){
-							this.project.parentTasks[i + 1].previousParentTask = task;
-							task.nextParentTask = this.project.parentTasks[i + 1];
-						}
-						isAdd = true;
-						break;
-					}
-				}
-			}
-			if(!isAdd){
-				if(this.project.parentTasks.length > 0){
-					this.project.parentTasks[this.project.parentTasks.length - 1].nextParentTask = task;
-					task.previousParentTask = this.project.parentTasks[this.project.parentTasks.length - 1];
-				}
-				this.project.parentTasks.push(task);
-			}
-			_task = new dojox.gantt.GanttTaskControl(task, this, this.ganttChart);
-			_task.create();
-			if(task.nextParentTask) _task.nextParentTask = _task.project.getTaskById(task.nextParentTask.id);
-			_task.adjustPanelTime();
-			this.arrTasks.push(_task);
-			var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
-			_task.shiftCurrentTasks(_task, rowHeight);
-			this.projectItem[0].style.display = "inline";
-			this.setPercentCompleted(this.getPercentCompleted());
-			this.shiftProjectItem();
-			this.showDescrProject();
-		}
-		this.ganttChart.checkHeighPanelTasks();
-		this.ganttChart.checkPosition();
-		return _task;
-	},
-	shiftNextProject: function(project, height){
-		if(project.nextProject){
-			project.nextProject.shiftProject(height);
-			this.shiftNextProject(project.nextProject, height);
-		}
-	},
-	shiftProject: function(height){
-		this.posY = this.posY + height;
-		this.projectItem[0].style.top = parseInt(this.projectItem[0].style.top) + height + "px";
-		this.descrProject.style.top = parseInt(this.descrProject.style.top) + height + "px";
-		this.projectNameItem.style.top = parseInt(this.projectNameItem.style.top) + height + "px";
-		if(this.arrTasks.length > 0){
-			this.shiftNextParentTask(this.arrTasks[0], height);
-		}
-	},
-	shiftTask: function(task, height){
-		task.posY = task.posY + height;
-		var tNameItem0 = task.cTaskNameItem[0], tNameItem1 = task.cTaskNameItem[1], tNameItem2 = task.cTaskNameItem[2],
-			tItem0 = task.cTaskItem[0], tItem1 = task.cTaskItem[1], tItem2 = task.cTaskItem[2];
-		tNameItem0.style.top = parseInt(tNameItem0.style.top) + height + "px";
-		if(tNameItem2){
-			tNameItem2.style.top = parseInt(tNameItem2.style.top) + height + "px";
-		}
-		if(task.parentTask){
-			tNameItem1[0].style.top = parseInt(tNameItem1[0].style.top) + height + "px";
-			tNameItem1[1].style.top = parseInt(tNameItem1[1].style.top) + height + "px";
-		}
-		task.cTaskItem[0].style.top = parseInt(task.cTaskItem[0].style.top) + height + "px";
-		task.descrTask.style.top = parseInt(task.descrTask.style.top) + height + "px";
-		if(tItem1[0]){
-			tItem1[0].style.top = parseInt(tItem1[0].style.top) + height + "px";
-			tItem1[1].style.top = parseInt(tItem1[1].style.top) + height + "px";
-			tItem1[2].style.top = parseInt(tItem1[2].style.top) + height + "px";
-		}
-	},
-	shiftNextParentTask: function(task, height){
-		this.shiftTask(task, height);
-		this.shiftChildTasks(task, height);
-		if(task.nextParentTask){
-			this.shiftNextParentTask(task.nextParentTask, height);
-		}
-	},
-	shiftChildTasks: function(task, height){
-		dojo.forEach(task.childTask, function(cTask){
-			this.shiftTask(cTask, height);
-			if(cTask.childTask.length > 0){
-				this.shiftChildTasks(cTask, height);
-			}
-		}, this);
-	}
-});
-
-
-dojo.declare("dojox.gantt.GanttProjectItem", null, {
-	constructor: function(configuration){
-		//id is required
-		this.id = configuration.id;
-		this.name = configuration.name || this.id;
-		this.startDate = configuration.startDate || new Date();
-		this.parentTasks = [];
-	},
-	getTaskById: function(id){
-		for(var i = 0; i < this.parentTasks.length; i++){
-			var pTask = this.parentTasks[i];
-			var task = this.getTaskByIdInTree(pTask, id);
-			if(task){
-				return task;
-			}
-		}
-		return null;
-	},
-	getTaskByIdInTree: function(parentTask, id){
-		if(parentTask.id == id){
-			return parentTask;
-		}else{
-			for(var i = 0; i < parentTask.cldTasks.length; i++){
-				var pcTask = parentTask.cldTasks[i];
-				if(pcTask.id == id){
-					return pcTask;
-				}
-				if(pcTask.cldTasks.length > 0){
 					if(pcTask.cldTasks.length > 0){
-						var cTask = this.getTaskByIdInTree(pcTask, id);
-						if(cTask){
-							return cTask;
+						if(pcTask.cldTasks.length > 0){
+							var cTask = this.getTaskByIdInTree(pcTask, id);
+							if(cTask){
+								return cTask;
+							}
 						}
 					}
 				}
 			}
-		}
-		return null;
-	},
-	addTask: function(task){
-		this.parentTasks.push(task);
-		task.setProject(this);
-	},
-	deleteTask: function(id){
-		var task = this.getTaskById(id);
-		if(!task){return;}
-		if(!task.parentTask){
-			for(var i = 0; i < this.parentTasks.length; i++){
-				var pTask = this.parentTasks[i];
-				if(pTask.id == id){
-					if(pTask.nextParentTask){
-						if(pTask.previousParentTask){
-							pTask.previousParentTask.nextParentTask = pTask.nextParentTask;
-							pTask.nextParentTask.previousParentTask = pTask.previousParentTask;
+			return null;
+		},
+		addTask: function(task){
+			this.parentTasks.push(task);
+			task.setProject(this);
+		},
+		deleteTask: function(id){
+			var task = this.getTaskById(id);
+			if(!task){return;}
+			if(!task.parentTask){
+				for(var i = 0; i < this.parentTasks.length; i++){
+					var pTask = this.parentTasks[i];
+					if(pTask.id == id){
+						if(pTask.nextParentTask){
+							if(pTask.previousParentTask){
+								pTask.previousParentTask.nextParentTask = pTask.nextParentTask;
+								pTask.nextParentTask.previousParentTask = pTask.previousParentTask;
+							}else{
+								pTask.nextParentTask.previousParentTask = null;
+							}
 						}else{
-							pTask.nextParentTask.previousParentTask = null;
-						}
-					}else{
-						if(pTask.previousParentTask){
-							pTask.previousParentTask.nextParentTask = null;
+							if(pTask.previousParentTask){
+								pTask.previousParentTask.nextParentTask = null;
+							}
 						}
+						pTask = null;
+						this.parentTasks.splice(i, 1);
+						break;
 					}
-					pTask = null;
-					this.parentTasks.splice(i, 1);
-					break;
 				}
-			}
-		}else{
-			var parentTask = task.parentTask;
-			for(var i = 0; i < parentTask.cldTasks.length; i++){
-				var pcTask = parentTask.cldTasks[i];
-				if(pcTask.id == id){
-					if(pcTask.nextChildTask){
-						if(pcTask.previousChildTask){
-							pcTask.previousChildTask.nextChildTask = pcTask.nextChildTask;
-							pcTask.nextChildTask.previousChildTask = pcTask.previousChildTask;
+			}else{
+				var parentTask = task.parentTask;
+				for(var i = 0; i < parentTask.cldTasks.length; i++){
+					var pcTask = parentTask.cldTasks[i];
+					if(pcTask.id == id){
+						if(pcTask.nextChildTask){
+							if(pcTask.previousChildTask){
+								pcTask.previousChildTask.nextChildTask = pcTask.nextChildTask;
+								pcTask.nextChildTask.previousChildTask = pcTask.previousChildTask;
+							}else{
+								pcTask.nextChildTask.previousChildTask = null;
+							}
 						}else{
-							pcTask.nextChildTask.previousChildTask = null;
-						}
-					}else{
-						if(pcTask.previousChildTask){
-							pcTask.previousChildTask.nextChildTask = null;
+							if(pcTask.previousChildTask){
+								pcTask.previousChildTask.nextChildTask = null;
+							}
 						}
+						pcTask = null;
+						parentTask.cldTasks.splice(i, 1);
+						break;
 					}
-					pcTask = null;
-					parentTask.cldTasks.splice(i, 1);
-					break;
 				}
 			}
 		}
-	}
+	});
 });
diff --git a/dojox/gantt/GanttResourceItem.js b/dojox/gantt/GanttResourceItem.js
index fe10720..718315a 100644
--- a/dojox/gantt/GanttResourceItem.js
+++ b/dojox/gantt/GanttResourceItem.js
@@ -1,457 +1,468 @@
-dojo.provide("dojox.gantt.GanttResourceItem");
-
-dojo.require("dojo.date.locale");
-
-dojo.declare("dojox.gantt.GanttResourceItem", null, {
-	constructor: function(ganttchart){
-		this.ganttChart = ganttchart;
-		this.ownerItem = [];
-		this.ownerNameItem = [];
-		this.ownerTaskNodeMapping = {};
-		this.ownerTaskNodeMapping_time = {};
-		this.resourceInfo = {};
-		this.ownerTimeConsume = {};
-	},
-	clearAll: function(){
-		this.clearData();
-		this.clearItems();
-	},
-	clearData: function(){
-		this.ownerItem = [];
-		this.ownerNameItem = [];
-		this.ownerTaskNodeMapping = {};
-		this.ownerTaskNodeMapping_time = {};
-		this.resourceInfo = {};
-		this.ownerTimeConsume = {};
-	},
-	clearItems: function(){
-		if(this.content.firstChild){
-		    dojo.destroy(this.content.firstChild);
-		}
-	},
-	buildResource: function(){
-		var resourceInfo = {};
-		dojo.forEach(this.ganttChart.arrProjects, function(project){
-			dojo.forEach(project.arrTasks, function(task){
-				task.buildResourceInfo(resourceInfo);
+define([
+    "dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+    "dojo/date/locale",
+	"dojo/request",
+	"dojo/on",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dojo/dom-attr",
+	"dojo/dom-geometry",
+	"dojo/keys",
+	"dojo/domReady!"
+], function(declare, arrayUtil, lang, locale, request, on,
+		dom, domClass, domConstruct, domStyle, domAttr, domGeometry, keys){
+	return declare("dojox.gantt.GanttResourceItem", [], {
+		constructor: function(ganttchart){
+			this.ganttChart = ganttchart;
+			this.ownerItem = [];
+			this.ownerNameItem = [];
+			this.ownerTaskNodeMapping = {};
+			this.ownerTaskNodeMapping_time = {};
+			this.resourceInfo = {};
+			this.ownerTimeConsume = {};
+		},
+		clearAll: function(){
+			this.clearData();
+			this.clearItems();
+		},
+		clearData: function(){
+			this.ownerItem = [];
+			this.ownerNameItem = [];
+			this.ownerTaskNodeMapping = {};
+			this.ownerTaskNodeMapping_time = {};
+			this.resourceInfo = {};
+			this.ownerTimeConsume = {};
+		},
+		clearItems: function(){
+			if(this.content.firstChild){
+			    domConstruct.destroy(this.content.firstChild);
+			}
+		},
+		buildResource: function(){
+			var resourceInfo = {};
+			arrayUtil.forEach(this.ganttChart.arrProjects, function(project){
+				arrayUtil.forEach(project.arrTasks, function(task){
+					task.buildResourceInfo(resourceInfo);
+				}, this);
 			}, this);
-		}, this);
-		return resourceInfo;
-	},
-	buildOwnerTimeConsume: function(){
-		var ownerTimeConsume = {};
-		for(var owner in this.resourceInfo){
-			var tasks = this.resourceInfo[owner];
-			//combine time zone  (startTime - this.startDate) / (60 * 60 * 1000) * this.pixelsPerHour;
-			var timeZoom = {};
-			for(var i = 0; i < tasks.length; i++){
-				var task = tasks[i];
-				var startTime = task.taskItem.startTime.getTime(), dur = task.taskItem.duration * 24 * 60 * 60 * 1000 / this.ganttChart.hsPerDay;
-				timeZoom.min = timeZoom.min ? Math.min(timeZoom.min, startTime) : startTime;
-				timeZoom.max = timeZoom.max ? Math.max(timeZoom.max, (startTime + dur)) : (startTime + dur);
+			return resourceInfo;
+		},
+		buildOwnerTimeConsume: function(){
+			var ownerTimeConsume = {};
+			for(var owner in this.resourceInfo){
+				var tasks = this.resourceInfo[owner];
+				//combine time zone  (startTime - this.startDate) / (60 * 60 * 1000) * this.pixelsPerHour;
+				var timeZoom = {};
+				for(var i = 0; i < tasks.length; i++){
+					var task = tasks[i];
+					var startTime = task.taskItem.startTime.getTime(), dur = task.taskItem.duration * 24 * 60 * 60 * 1000 / this.ganttChart.hsPerDay;
+					timeZoom.min = timeZoom.min ? Math.min(timeZoom.min, startTime) : startTime;
+					timeZoom.max = timeZoom.max ? Math.max(timeZoom.max, (startTime + dur)) : (startTime + dur);
+				}
+				timeZoom.dur = (timeZoom.max - timeZoom.min) * this.ganttChart.hsPerDay / (24 * 60 * 60 * 1000);
+				timeZoom.min = new Date(timeZoom.min);
+				timeZoom.max = new Date(timeZoom.max);
+				ownerTimeConsume[owner] = timeZoom;
 			}
-			timeZoom.dur = (timeZoom.max - timeZoom.min) * this.ganttChart.hsPerDay / (24 * 60 * 60 * 1000);
-			timeZoom.min = new Date(timeZoom.min);
-			timeZoom.max = new Date(timeZoom.max);
-			ownerTimeConsume[owner] = timeZoom;
-		}
-		return ownerTimeConsume;
-	},
-	refresh: function(){
-		this.ownerTimeConsume = this.buildOwnerTimeConsume();
-		//resize outer div
-		this.contentData.firstChild.style.width = Math.max(1200, this.ganttChart.pixelsPerDay * this.ganttChart.totalDays) + "px";
-		for(var owner in this.resourceInfo){
-			this.refreshOwnerEntry(owner);
-		}
-	},
-	reConstruct: function(){
-		this.clearAll();
-		this.resourceInfo = this.buildResource();
-		this.ownerTimeConsume = this.buildOwnerTimeConsume();
-		this.tableControl = dojo.create("table", {
-			cellPadding: "0",
-			cellSpacing: "0",
-			className: "ganttResourceTableControl"
-		});
-		var newRowTblControl = this.tableControl.insertRow(this.tableControl.rows.length);
-		//Add to content Table
-		this.contentHeight = this.content.offsetHeight;
-		this.contentWidth = this.content.offsetWidth;
-		this.content.appendChild(this.tableControl);
-		//Creation panel contentData
-		this.contentData = dojo.create("div", {className: "ganttResourceContentDataContainer"});
-		this.contentData.appendChild(this.createPanelOwners());
-		dojo.style(this.contentData, "height", (this.contentHeight - this.ganttChart.panelTimeHeight) + "px");
-		//Creation panel of names
-		var newCellTblControl = dojo.create("td", {
-			vAlign: "top"
-		});
-		this.panelNames = dojo.create("div", {className: "ganttResourcePanelNames"});
-		this.panelNames.appendChild(this.createPanelNamesOwners());
-		newCellTblControl.appendChild(this.panelNames);
-		newRowTblControl.appendChild(newCellTblControl);
-		//add to control contentData and contentDataTime
-		newCellTblControl = dojo.create("td", {
-			vAlign: "top"
-		});
-		var divCell = dojo.create("div", {className: "ganttResourceDivCell"});
-		divCell.appendChild(this.contentData);
-		newCellTblControl.appendChild(divCell);
-		newRowTblControl.appendChild(newCellTblControl);
-		//Show panel of names
-		dojo.style(this.panelNames, {
-			height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px",
-			width: this.ganttChart.maxWidthPanelNames + "px"
-		});
-		this.contentData.style.width = (this.contentWidth - this.ganttChart.maxWidthPanelNames) + "px";
-		this.contentData.firstChild.style.width = this.ganttChart.pixelsPerDay * (this.ganttChart.panelTime.firstChild.firstChild.rows[3].cells.length) + "px";
-		var _this = this;
-		this.contentData.onscroll = function(){
-			if(_this.panelNames){
-				_this.panelNames.scrollTop = this.scrollTop;
+			return ownerTimeConsume;
+		},
+		refresh: function(){
+			this.ownerTimeConsume = this.buildOwnerTimeConsume();
+			//resize outer div
+			this.contentData.firstChild.style.width = Math.max(1200, this.ganttChart.pixelsPerDay * this.ganttChart.totalDays) + "px";
+			for(var owner in this.resourceInfo){
+				this.refreshOwnerEntry(owner);
 			}
-		}
-		this.contentData.scrollLeft = this.ganttChart.contentData.scrollLeft;
-		for(var owner in this.resourceInfo){
-			this.createOwnerEntry(owner);
-		}
-		this.postAdjustment();
-	},
-	create: function(){
-		var resourceHeader = dojo.create("div", {
-			innerHTML: "Resource Chart:",
-			className: "ganttResourceHeader"
-		}, this.ganttChart.content, "after");
-		dojo.style(resourceHeader, "width", this.ganttChart.contentWidth + "px");
-		var content = dojo.create("div", {className: "ganttResourceContent"}, resourceHeader, "after");
-		dojo.style(content, {
-			width: this.ganttChart.contentWidth + "px",
-			height: (this.ganttChart.resourceChartHeight || (this.ganttChart.contentHeight * 0.8)) + "px"
-		});
-		this.content = content || this.content;
-		//create Table
-		this.reConstruct();
-	},
-	postAdjustment: function(){
-		//contentData height
-		this.contentData.firstChild.style.height = (this.ownerItem.length * 23) + "px";
-		this.panelNames.firstChild.style.height = (this.ownerItem.length * 23) + "px";
-	},
+		},
+		reConstruct: function(){
+			this.clearAll();
+			this.resourceInfo = this.buildResource();
+			this.ownerTimeConsume = this.buildOwnerTimeConsume();
+			this.tableControl = domConstruct.create("table", {
+				cellPadding: "0",
+				cellSpacing: "0",
+				className: "ganttResourceTableControl"
+			});
+			var newRowTblControl = this.tableControl.insertRow(this.tableControl.rows.length);
+			//Add to content Table
+			this.contentHeight = this.content.offsetHeight;
+			this.contentWidth = this.content.offsetWidth;
+			this.content.appendChild(this.tableControl);
+			//Creation panel contentData
+			this.contentData = domConstruct.create("div", {className: "ganttResourceContentDataContainer"});
+			this.contentData.appendChild(this.createPanelOwners());
+			domStyle.set(this.contentData, "height", (this.contentHeight - this.ganttChart.panelTimeHeight) + "px");
+			//Creation panel of names
+			var newCellTblControl = domConstruct.create("td", {
+				vAlign: "top"
+			});
+			this.panelNames = domConstruct.create("div", {className: "ganttResourcePanelNames"});
+			this.panelNames.appendChild(this.createPanelNamesOwners());
+			newCellTblControl.appendChild(this.panelNames);
+			newRowTblControl.appendChild(newCellTblControl);
+			//add to control contentData and contentDataTime
+			newCellTblControl = domConstruct.create("td", {
+				vAlign: "top"
+			});
+			var divCell = domConstruct.create("div", {className: "ganttResourceDivCell"});
+			divCell.appendChild(this.contentData);
+			newCellTblControl.appendChild(divCell);
+			newRowTblControl.appendChild(newCellTblControl);
+			//Show panel of names
+			domStyle.set(this.panelNames, {
+				height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px",
+				width: this.ganttChart.maxWidthPanelNames + "px"
+			});
+			this.contentData.style.width = (this.contentWidth - this.ganttChart.maxWidthPanelNames) + "px";
+			this.contentData.firstChild.style.width = this.ganttChart.pixelsPerDay * (this.ganttChart.panelTime.firstChild.firstChild.rows[3].cells.length) + "px";
+			var _this = this;
+			this.contentData.onscroll = function(){
+				if(_this.panelNames){
+					_this.panelNames.scrollTop = this.scrollTop;
+				}
+			};
+			this.contentData.scrollLeft = this.ganttChart.contentData.scrollLeft;
+			for(var owner in this.resourceInfo){
+				this.createOwnerEntry(owner);
+			}
+			this.postAdjustment();
+		},
+		create: function(){
+			var resourceHeader = domConstruct.create("div", {
+				innerHTML: "Resource Chart:",
+				className: "ganttResourceHeader"
+			}, this.ganttChart.content, "after");
+			domStyle.set(resourceHeader, "width", this.ganttChart.contentWidth + "px");
+			var content = domConstruct.create("div", {className: "ganttResourceContent"}, resourceHeader, "after");
+			domStyle.set(content, {
+				width: this.ganttChart.contentWidth + "px",
+				height: (this.ganttChart.resourceChartHeight || (this.ganttChart.contentHeight * 0.8)) + "px"
+			});
+			this.content = content || this.content;
+			//create Table
+			this.reConstruct();
+		},
+		postAdjustment: function(){
+			//contentData height
+			this.contentData.firstChild.style.height = (this.ownerItem.length * 23) + "px";
+			this.panelNames.firstChild.style.height = (this.ownerItem.length * 23) + "px";
+		},
 	
-	refreshOwnerEntry: function(owner){
-		this.refreshOwnerItem(owner);
-		dojo.forEach(this.resourceInfo[owner], function(task, i){
-			var item = this.ownerTaskNodeMapping[owner].tasks[i][0];
-			this.refreshDetailedTaskEntry(owner, item, task);
-		}, this);
-	},
-	createOwnerEntry: function(owner){
-		var containerOwner = this.contentData.firstChild;
-		var previousOwner = this.ownerItem[this.ownerItem.length - 1];
-		this.ownerTaskNodeMapping[owner] = {};
-		this.ownerTaskNodeMapping[owner][owner] = [];
-		//create nodes
-		var pos = dojo.position(containerOwner);
-		//creation arrTasks
-		var posY = (previousOwner ? parseInt(previousOwner.style.top) : (6 - 23)) + this.ganttChart.heightTaskItem + 11;
-		//creation task item
-		var oItem = this.createOwnerItem(owner, posY);
-		containerOwner.appendChild(oItem);
-		this.ownerItem.push(oItem);
-		this.ownerTaskNodeMapping[owner][owner].push(oItem);
-		if(this.panelNames){
-			var oNameItem = this.createOwnerNameItem(owner, posY);
-			this.panelNames.firstChild.appendChild(oNameItem);
-			this.ownerNameItem.push(oNameItem);
-			this.ownerTaskNodeMapping[owner][owner].push(oNameItem);
-		}
-		var currentOwnerNode = this.ownerItem[this.ownerNameItem.length - 1],
-			currentOwnerNameNode = this.ownerNameItem[this.ownerNameItem.length - 1];
-		//adjust nodes
-		if(this.panelNames){
-			this.checkWidthTaskNameItem(currentOwnerNameNode);
-			var treeImg = this.createTreeImg(currentOwnerNameNode);
-			this.panelNames.firstChild.appendChild(treeImg);
-			this.ownerTaskNodeMapping[owner][owner].push(treeImg);
-		}
-		this.ownerTaskNodeMapping[owner]["taskCount"] = this.resourceInfo[owner].length;
-		this.ownerTaskNodeMapping[owner]["isOpen"] = false;
-		this.ownerTaskNodeMapping[owner]["tasks"] = [];
-		dojo.forEach(this.resourceInfo[owner], function(task){
-			this.ownerTaskNodeMapping[owner]["tasks"].push(this.createDetailedTaskEntry(owner, currentOwnerNameNode, task));
-		}, this);
-		return this;
-	},
-	createOwnerNameItem: function(owner, posY){
-		var ownerName = dojo.create("div", {
-			id: owner,
-			title: owner,
-			innerHTML: owner,
-			className: "ganttOwnerNameItem"
-		});
-		dojo.style(ownerName, "top", posY + "px");
-		return ownerName;
-	},
-	refreshOwnerItem: function(owner){
-		var item = this.ownerTaskNodeMapping[owner][owner][0],
-			start = this.ownerTimeConsume[owner].min, end = this.ownerTimeConsume[owner].max, dur = this.ownerTimeConsume[owner].dur,
-			posX = this.ganttChart.getPosOnDate(start); // should be task start date
-		item.style.left = posX + "px";
-		item.style.width = dur * this.ganttChart.pixelsPerWorkHour + "px";
-		dojo.forEach(this.resourceInfo[owner], function(task, i){
-			var tposX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
-			dojo.style(item.childNodes[i], {
-				left: (tposX - posX) + "px",
-				width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
+		refreshOwnerEntry: function(owner){
+			this.refreshOwnerItem(owner);
+			arrayUtil.forEach(this.resourceInfo[owner], function(task, i){
+				var item = this.ownerTaskNodeMapping[owner].tasks[i][0];
+				this.refreshDetailedTaskEntry(owner, item, task);
+			}, this);
+		},
+		createOwnerEntry: function(owner){
+			var containerOwner = this.contentData.firstChild;
+			var previousOwner = this.ownerItem[this.ownerItem.length - 1];
+			this.ownerTaskNodeMapping[owner] = {};
+			this.ownerTaskNodeMapping[owner][owner] = [];
+			//creation arrTasks
+			var posY = (previousOwner ? parseInt(previousOwner.style.top) : (6 - 23)) + this.ganttChart.heightTaskItem + 11;
+			//creation task item
+			var oItem = this.createOwnerItem(owner, posY);
+			containerOwner.appendChild(oItem);
+			this.ownerItem.push(oItem);
+			this.ownerTaskNodeMapping[owner][owner].push(oItem);
+			if(this.panelNames){
+				var oNameItem = this.createOwnerNameItem(owner, posY);
+				this.panelNames.firstChild.appendChild(oNameItem);
+				this.ownerNameItem.push(oNameItem);
+				this.ownerTaskNodeMapping[owner][owner].push(oNameItem);
+			}
+			var currentOwnerNameNode = this.ownerNameItem[this.ownerNameItem.length - 1];
+			//adjust nodes
+			if(this.panelNames){
+				this.checkWidthTaskNameItem(currentOwnerNameNode);
+				var treeImg = this.createTreeImg(currentOwnerNameNode);
+				this.panelNames.firstChild.appendChild(treeImg);
+				this.ownerTaskNodeMapping[owner][owner].push(treeImg);
+			}
+			this.ownerTaskNodeMapping[owner]["taskCount"] = this.resourceInfo[owner].length;
+			this.ownerTaskNodeMapping[owner]["isOpen"] = false;
+			this.ownerTaskNodeMapping[owner]["tasks"] = [];
+			arrayUtil.forEach(this.resourceInfo[owner], function(task){
+				this.ownerTaskNodeMapping[owner]["tasks"].push(this.createDetailedTaskEntry(owner, currentOwnerNameNode, task));
+			}, this);
+			return this;
+		},
+		createOwnerNameItem: function(owner, posY){
+			var ownerName = domConstruct.create("div", {
+				id: owner,
+				title: owner,
+				innerHTML: owner,
+				className: "ganttOwnerNameItem"
 			});
-		}, this);
-	},
-	createOwnerItem: function(owner, posY){
-		var start = this.ownerTimeConsume[owner].min, end = this.ownerTimeConsume[owner].max, dur = this.ownerTimeConsume[owner].dur;
-		var posX = this.ganttChart.getPosOnDate(start); // should be task start date
-		var ownerControl = dojo.create("div", {
-			id: owner,
-			owner: true,
-			className: "ganttOwnerBar"
-		});
-		dojo.style(ownerControl, {
-			left: posX + "px",
-			top: posY + "px",
-			width: dur * this.ganttChart.pixelsPerWorkHour + "px",
-			height: this.ganttChart.heightTaskItem + "px"
-		});
-		dojo.forEach(this.resourceInfo[owner], function(task){
-			var ownerTaskItem = dojo.create("div", {
+			domStyle.set(ownerName, "top", posY + "px");
+			return ownerName;
+		},
+		refreshOwnerItem: function(owner){
+			var item = this.ownerTaskNodeMapping[owner][owner][0],
+				start = this.ownerTimeConsume[owner].min, dur = this.ownerTimeConsume[owner].dur,
+				posX = this.ganttChart.getPosOnDate(start); // should be task start date
+			item.style.left = posX + "px";
+			item.style.width = dur * this.ganttChart.pixelsPerWorkHour + "px";
+			arrayUtil.forEach(this.resourceInfo[owner], function(task, i){
+				var tposX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
+				domStyle.set(item.childNodes[i], {
+					left: (tposX - posX) + "px",
+					width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
+				});
+			}, this);
+		},
+		createOwnerItem: function(owner, posY){
+			var start = this.ownerTimeConsume[owner].min, dur = this.ownerTimeConsume[owner].dur;
+			var posX = this.ganttChart.getPosOnDate(start); // should be task start date
+			var ownerControl = domConstruct.create("div", {
 				id: owner,
-				className: "ganttOwnerTaskBar"
-			}, ownerControl);
-			var tposX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
-			dojo.style(ownerTaskItem, {
-				left: (tposX - posX) + "px",
-				width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px", // should be task duration
+				owner: true,
+				className: "ganttOwnerBar"
+			});
+			domStyle.set(ownerControl, {
+				left: posX + "px",
+				top: posY + "px",
+				width: dur * this.ganttChart.pixelsPerWorkHour + "px",
 				height: this.ganttChart.heightTaskItem + "px"
 			});
-		}, this);
-		return ownerControl;
-	},
-	refreshDetailedTaskEntry: function(owner, item, task){
-		this.refreshTaskItem(item, task);
-	},
-	createDetailedTaskEntry: function(owner, parentNode, task){
-		var taskItems = [];
-		var containerTasks = this.contentData.firstChild;
-		var posY = parseInt(parentNode.style.top);
-		
-		//creation task item
-		var taskItem = this.createTaskItem(task, posY);
-		taskItem.style.display = "none";
-		containerTasks.appendChild(taskItem);
-		this.ownerItem.push(taskItem);
-		taskItems.push(taskItem);
-		if(this.panelNames){
-			var taskNameItem = this.createTaskNameItem(task.taskItem.name, posY);
-			this.panelNames.firstChild.appendChild(taskNameItem);
-			taskNameItem.style.display = "none";
-			this.ownerNameItem.push(taskNameItem);
-			taskItems.push(taskNameItem);
-		}
-		if(this.panelNames){
-			this.ownerNameItem[this.ownerNameItem.length - 1].style.left = dojo.style(parentNode, "left") + 15 + "px";
-			var arrConnectingLinesNames = this.createConnectingLinesPN(parentNode, this.ownerNameItem[this.ownerNameItem.length - 1]);
-			dojo.forEach(arrConnectingLinesNames, function(lineName){
-				lineName.style.display = "none";
+			arrayUtil.forEach(this.resourceInfo[owner], function(task){
+				var ownerTaskItem = domConstruct.create("div", {
+					id: owner,
+					className: "ganttOwnerTaskBar"
+				}, ownerControl);
+				var tposX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
+				domStyle.set(ownerTaskItem, {
+					left: (tposX - posX) + "px",
+					width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px", // should be task duration
+					height: this.ganttChart.heightTaskItem + "px"
+				});
 			}, this);
-			taskItems.push({
-				"v": arrConnectingLinesNames[0],
-				"h": arrConnectingLinesNames[1]
+			return ownerControl;
+		},
+		refreshDetailedTaskEntry: function(owner, item, task){
+			this.refreshTaskItem(item, task);
+		},
+		createDetailedTaskEntry: function(owner, parentNode, task){
+			var taskItems = [];
+			var containerTasks = this.contentData.firstChild;
+			var posY = parseInt(parentNode.style.top);
+		
+			//creation task item
+			var taskItem = this.createTaskItem(task, posY);
+			taskItem.style.display = "none";
+			containerTasks.appendChild(taskItem);
+			this.ownerItem.push(taskItem);
+			taskItems.push(taskItem);
+			if(this.panelNames){
+				var taskNameItem = this.createTaskNameItem(task.taskItem.name, posY);
+				this.panelNames.firstChild.appendChild(taskNameItem);
+				taskNameItem.style.display = "none";
+				this.ownerNameItem.push(taskNameItem);
+				taskItems.push(taskNameItem);
+			}
+			if(this.panelNames){
+				this.ownerNameItem[this.ownerNameItem.length - 1].style.left = domStyle.get(parentNode, "left") + 15 + "px";
+				var arrConnectingLinesNames = this.createConnectingLinesPN(parentNode, this.ownerNameItem[this.ownerNameItem.length - 1]);
+				arrayUtil.forEach(arrConnectingLinesNames, function(lineName){
+					lineName.style.display = "none";
+				}, this);
+				taskItems.push({
+					"v": arrConnectingLinesNames[0],
+					"h": arrConnectingLinesNames[1]
+				});
+				this.checkWidthTaskNameItem(this.ownerNameItem[this.ownerNameItem.length - 1]);
+			}
+			return taskItems;
+		},
+		createTaskNameItem: function(owner, posY){
+			var taskNameItem = domConstruct.create("div", {
+				id: owner,
+				className: "ganttTaskNameItem",
+				title: owner,
+				innerHTML: owner
 			});
-			this.checkWidthTaskNameItem(this.ownerNameItem[this.ownerNameItem.length - 1]);
-		}
-		return taskItems;
-	},
-	createTaskNameItem: function(owner, posY){
-		var taskNameItem = dojo.create("div", {
-			id: owner,
-			className: "ganttTaskNameItem",
-			title: owner,
-			innerHTML: owner
-		});
-		dojo.style(taskNameItem, "top", posY + "px");
-		return taskNameItem;
-	},
-	refreshTaskItem: function(item, task){
-		var posX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
-		dojo.style(item, {
-			left: posX + "px",
-			width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
-		});
-	},
-	createTaskItem: function(task, posY){
-		var posX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
-		var itemControl = dojo.create("div", {
-			id: task.taskItem.name,
-			className: "ganttTaskBar"
-		});
-		dojo.style(itemControl, {
-			left: posX + "px",
-			top: posY + "px",
-			width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px",
-			height: this.ganttChart.heightTaskItem + "px"
-		});
-		return itemControl;
-	},
-	createConnectingLinesPN: function(parentNode, currentNode){
-		var arrConnectingLinesNames = [];
-		var lineVerticalLeft = dojo.create("div", {
-			innerHTML: " ",
-			className: "ganttResourceLineVerticalLeft"
-		}, this.panelNames.firstChild);
-		lineVerticalLeft.cNode = currentNode;
-		lineVerticalLeft.pNode = parentNode;
-		var LineHorizontalLeft = dojo.create("div", {
-			noShade: true,
-			color: "#000",
-			className: "ganttResourceLineHorizontalLeft"
-		}, this.panelNames.firstChild);
-		LineHorizontalLeft.cNode = currentNode;
-		LineHorizontalLeft.pNode = parentNode;
-		this.panelNames.firstChild.appendChild(LineHorizontalLeft);
-		arrConnectingLinesNames.push(lineVerticalLeft);
-		arrConnectingLinesNames.push(LineHorizontalLeft);
-		return arrConnectingLinesNames;
-	},
-	createTreeImg: function(ownerNameItem){
-		var treeImg = dojo.create("div", {
-			id: ownerNameItem.id,
-			className: "ganttImageTreeExpand"
-		});
-		dojo.attr(treeImg, "tabIndex", 0);
-		var currentItem = this.ownerTaskNodeMapping[ownerNameItem.id];
-		dojo.forEach(["onclick", "onkeydown"], function(e){
-			this.ganttChart._events.push(
-				dojo.connect(treeImg, e, this, function(evt){
-					var reachTarget = false, owner, ownerItem;
-					if(e == "onkeydown" && evt.keyCode != dojo.keys.ENTER){ return; }
-					//TODO: perhaps the following conditional can be collapsed?  Duplicate code.
-					if(currentItem.isOpen){
-						dojo.removeClass(treeImg, "ganttImageTreeCollapse");
-						dojo.addClass(treeImg, "ganttImageTreeExpand");
-						currentItem.isOpen = false;
-						//collapse
-						for(owner in this.ownerTaskNodeMapping){
-							ownerItem = this.ownerTaskNodeMapping[owner];
-							if(reachTarget){
-								dojo.forEach(ownerItem[owner], function(tItem){
-									dojo.style(tItem, "top", dojo.style(tItem, "top") - currentItem.taskCount * 23 + "px");
-								});
-								dojo.forEach(ownerItem.tasks, function(tItems){
-									dojo.forEach(tItems, function(tItem){
-										var item = !tItem.v && !tItem.h ? [tItem] : [tItem.v, tItem.h];
-										dojo.forEach(item, function(t){
-											dojo.style(t, "top", dojo.style(t, "top") - currentItem.taskCount * 23 + "px");
+			domStyle.set(taskNameItem, "top", posY + "px");
+			return taskNameItem;
+		},
+		refreshTaskItem: function(item, task){
+			var posX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
+			domStyle.set(item, {
+				left: posX + "px",
+				width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
+			});
+		},
+		createTaskItem: function(task, posY){
+			var posX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
+			var itemControl = domConstruct.create("div", {
+				id: task.taskItem.name,
+				className: "ganttTaskBar"
+			});
+			domStyle.set(itemControl, {
+				left: posX + "px",
+				top: posY + "px",
+				width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px",
+				height: this.ganttChart.heightTaskItem + "px"
+			});
+			return itemControl;
+		},
+		createConnectingLinesPN: function(parentNode, currentNode){
+			var arrConnectingLinesNames = [];
+			var lineVerticalLeft = domConstruct.create("div", {
+				innerHTML: " ",
+				className: "ganttResourceLineVerticalLeft"
+			}, this.panelNames.firstChild);
+			lineVerticalLeft.cNode = currentNode;
+			lineVerticalLeft.pNode = parentNode;
+			var LineHorizontalLeft = domConstruct.create("div", {
+				noShade: true,
+				color: "#000",
+				className: "ganttResourceLineHorizontalLeft"
+			}, this.panelNames.firstChild);
+			LineHorizontalLeft.cNode = currentNode;
+			LineHorizontalLeft.pNode = parentNode;
+			this.panelNames.firstChild.appendChild(LineHorizontalLeft);
+			arrConnectingLinesNames.push(lineVerticalLeft);
+			arrConnectingLinesNames.push(LineHorizontalLeft);
+			return arrConnectingLinesNames;
+		},
+		createTreeImg: function(ownerNameItem){
+			var treeImg = domConstruct.create("div", {
+				id: ownerNameItem.id,
+				className: "ganttImageTreeExpand"
+			});
+			domAttr.set(treeImg, "tabIndex", 0);
+			var currentItem = this.ownerTaskNodeMapping[ownerNameItem.id];
+			arrayUtil.forEach(["click", "keydown"], function(e){
+				this.ganttChart._events.push(
+					on(treeImg, e, lang.hitch(this, function(evt){
+						var reachTarget = false, owner, ownerItem;
+						if(e == "keydown" && evt.keyCode != keys.ENTER){ return; }
+						//TODO: perhaps the following conditional can be collapsed?  Duplicate code.
+						if(currentItem.isOpen){
+							domClass.remove(treeImg, "ganttImageTreeCollapse");
+							domClass.add(treeImg, "ganttImageTreeExpand");
+							currentItem.isOpen = false;
+							//collapse
+							for(owner in this.ownerTaskNodeMapping){
+								ownerItem = this.ownerTaskNodeMapping[owner];
+								if(reachTarget){
+									arrayUtil.forEach(ownerItem[owner], function(tItem){
+										domStyle.set(tItem, "top", domStyle.get(tItem, "top") - currentItem.taskCount * 23 + "px");
+									});
+									arrayUtil.forEach(ownerItem.tasks, function(tItems){
+										arrayUtil.forEach(tItems, function(tItem){
+											var item = !tItem.v && !tItem.h ? [tItem] : [tItem.v, tItem.h];
+											arrayUtil.forEach(item, function(t){
+												domStyle.set(t, "top", domStyle.get(t, "top") - currentItem.taskCount * 23 + "px");
+											});
 										});
 									});
-								});
-							}else{
-								if(owner == ownerNameItem.id){
-									reachTarget = true;
-									dojo.forEach(ownerItem.tasks, function(tItems, i){
-										dojo.forEach(tItems, function(tItem){
-											this.styleOwnerItem(tItem, ownerItem[owner][0], "none", 0);
+								}else{
+									if(owner == ownerNameItem.id){
+										reachTarget = true;
+										arrayUtil.forEach(ownerItem.tasks, function(tItems){
+											arrayUtil.forEach(tItems, function(tItem){
+												this.styleOwnerItem(tItem, ownerItem[owner][0], "none", 0);
+											}, this);
 										}, this);
-									}, this);
+									}
 								}
 							}
-						}
-					}else{
-						dojo.removeClass(treeImg, "ganttImageTreeExpand");
-						dojo.addClass(treeImg, "ganttImageTreeCollapse");
-						currentItem.isOpen = true;
-						//expand
-						for(owner in this.ownerTaskNodeMapping){
-							ownerItem = this.ownerTaskNodeMapping[owner];
-							if(reachTarget){
-								dojo.forEach(ownerItem[owner], function(tItem){
-									dojo.style(tItem, "top", dojo.style(tItem, "top") + currentItem.taskCount * 23 + "px");
-								});
-								dojo.forEach(ownerItem.tasks, function(tItems){
-									dojo.forEach(tItems, function(tItem){
-										var item = !tItem.v && !tItem.h ? [tItem] : [tItem.v, tItem.h];
-										dojo.forEach(item, function(t){
-											dojo.style(t, "top", dojo.style(t, "top") + currentItem.taskCount * 23 + "px");
+						}else{
+							domClass.remove(treeImg, "ganttImageTreeExpand");
+							domClass.add(treeImg, "ganttImageTreeCollapse");
+							currentItem.isOpen = true;
+							//expand
+							for(owner in this.ownerTaskNodeMapping){
+								ownerItem = this.ownerTaskNodeMapping[owner];
+								if(reachTarget){
+									arrayUtil.forEach(ownerItem[owner], function(tItem){
+										domStyle.set(tItem, "top", domStyle.get(tItem, "top") + currentItem.taskCount * 23 + "px");
+									});
+									arrayUtil.forEach(ownerItem.tasks, function(tItems){
+										arrayUtil.forEach(tItems, function(tItem){
+											var item = !tItem.v && !tItem.h ? [tItem] : [tItem.v, tItem.h];
+											arrayUtil.forEach(item, function(t){
+												domStyle.set(t, "top", domStyle.get(t, "top") + currentItem.taskCount * 23 + "px");
+											});
 										});
 									});
-								});
-							}else{
-								if(owner == ownerNameItem.id){
-									reachTarget = true;
-									dojo.forEach(ownerItem.tasks, function(tItems, i){
-										dojo.forEach(tItems, function(tItem){
-											this.styleOwnerItem(tItem, ownerItem[owner][0], "inline", (i + 1) * 23);
+								}else{
+									if(owner == ownerNameItem.id){
+										reachTarget = true;
+										arrayUtil.forEach(ownerItem.tasks, function(tItems, i){
+											arrayUtil.forEach(tItems, function(tItem){
+												this.styleOwnerItem(tItem, ownerItem[owner][0], "inline", (i + 1) * 23);
+											}, this);
 										}, this);
-									}, this);
+									}
 								}
 							}
 						}
-					}
-				})
-			);
-		}, this);
-		dojo.addClass(treeImg, "ganttResourceTreeImage");
-		dojo.style(treeImg, {
-			left: (dojo.style(ownerNameItem, "left") - 12) + "px",
-			top: (dojo.style(ownerNameItem, "top") + 3) + "px"
-		});
-		return treeImg;
-	},
-	styleOwnerItem: function(tItem, owner, displayType, topOffset){
-		if(tItem.v || tItem.h){
-			dojo.style(tItem.v, {
-				height: Math.max(1, (tItem.v.cNode.offsetTop - tItem.v.pNode.offsetTop)) + "px",
-				top: (tItem.v.pNode.offsetTop + 5) + "px",
-				left: (tItem.v.pNode.offsetLeft - 9) + "px",
-				display: displayType
+					}))
+				);
+			}, this);
+			domClass.add(treeImg, "ganttResourceTreeImage");
+			domStyle.set(treeImg, {
+				left: (domStyle.get(ownerNameItem, "left") - 12) + "px",
+				top: (domStyle.get(ownerNameItem, "top") + 3) + "px"
 			});
-			dojo.style(tItem.h, {
-				width: Math.max(1, (tItem.h.cNode.offsetLeft - tItem.h.pNode.offsetLeft + 4)) + "px",
-				top: (tItem.h.cNode.offsetTop + 5) + "px",
-				left: (tItem.h.pNode.offsetLeft - 9) + "px",
-				display: displayType
+			return treeImg;
+		},
+		styleOwnerItem: function(tItem, owner, displayType, topOffset){
+			if(tItem.v || tItem.h){
+				domStyle.set(tItem.v, {
+					height: Math.max(1, (tItem.v.cNode.offsetTop - tItem.v.pNode.offsetTop)) + "px",
+					top: (tItem.v.pNode.offsetTop + 5) + "px",
+					left: (tItem.v.pNode.offsetLeft - 9) + "px",
+					display: displayType
+				});
+				domStyle.set(tItem.h, {
+					width: Math.max(1, (tItem.h.cNode.offsetLeft - tItem.h.pNode.offsetLeft + 4)) + "px",
+					top: (tItem.h.cNode.offsetTop + 5) + "px",
+					left: (tItem.h.pNode.offsetLeft - 9) + "px",
+					display: displayType
+				});
+			}else{
+				domStyle.set(tItem, {
+					display: displayType,
+					top: parseInt(owner.style.top) + topOffset + "px"
+				});
+			}
+		},
+		checkWidthTaskNameItem: function(taskNameItem){
+			if(taskNameItem && taskNameItem.offsetWidth + taskNameItem.offsetLeft > this.ganttChart.maxWidthPanelNames){
+				var width = taskNameItem.offsetWidth + taskNameItem.offsetLeft - this.ganttChart.maxWidthPanelNames,
+					countChar = Math.round(width / (taskNameItem.offsetWidth / taskNameItem.firstChild.length)),
+					tName = taskNameItem.id.substring(0, taskNameItem.firstChild.length - countChar - 3);
+				taskNameItem.innerHTML = tName + "...";
+			}
+		},
+		createPanelOwners: function(){
+			var panelOwner = domConstruct.create("div", {
+				className: "ganttOwnerPanel"
 			});
-		}else{
-			dojo.style(tItem, {
-				display: displayType,
-				top: parseInt(owner.style.top) + topOffset + "px"
+			domStyle.set(panelOwner, {
+				height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px"
 			});
+			return panelOwner;
+		},
+		createPanelNamesOwners: function(){
+			var panelNameOwner = domConstruct.create("div", {
+				innerHTML: " ",
+				className: "ganttResourcePanelNamesOwners"
+			});
+			domStyle.set(panelNameOwner, {
+				height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px",
+				width: this.ganttChart.maxWidthPanelNames + "px"
+			});
+			return panelNameOwner;
 		}
-	},
-	checkWidthTaskNameItem: function(taskNameItem){
-		if(taskNameItem && taskNameItem.offsetWidth + taskNameItem.offsetLeft > this.ganttChart.maxWidthPanelNames){
-			var width = taskNameItem.offsetWidth + taskNameItem.offsetLeft - this.ganttChart.maxWidthPanelNames,
-				countChar = Math.round(width / (taskNameItem.offsetWidth / taskNameItem.firstChild.length)),
-				tName = taskNameItem.id.substring(0, taskNameItem.firstChild.length - countChar - 3);
-			taskNameItem.innerHTML = tName + "...";
-		}
-	},
-	createPanelOwners: function(){
-		var panelOwner = dojo.create("div", {
-			className: "ganttOwnerPanel"
-		});
-		dojo.style(panelOwner, {
-			height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px"
-		});
-		return panelOwner;
-	},
-	createPanelNamesOwners: function(){
-		var panelNameOwner = dojo.create("div", {
-			innerHTML: " ",
-			className: "ganttResourcePanelNamesOwners"
-		});
-		dojo.style(panelNameOwner, {
-			height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px",
-			width: this.ganttChart.maxWidthPanelNames + "px"
-		});
-		return panelNameOwner;
-	}
-});
+	});
+});
\ No newline at end of file
diff --git a/dojox/gantt/GanttTaskControl.js b/dojox/gantt/GanttTaskControl.js
new file mode 100644
index 0000000..9263ab2
--- /dev/null
+++ b/dojox/gantt/GanttTaskControl.js
@@ -0,0 +1,1334 @@
+define([
+    "dijit/focus",
+    "dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+    "dojo/date/locale",
+	"dojo/request",
+	"dojo/on",	
+	"dojo/dom",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dojo/dom-attr",
+	"dojo/dom-geometry",
+	"dojo/keys",
+	"dojo/domReady!"
+], function(focus, declare, arrayUtil, lang, locale, request, on,
+		dom, domClass, domConstruct, domStyle, domAttr, domGeometry, keys){
+	return declare("dojox.gantt.GanttTaskControl", [], {
+		constructor: function(taskInfo, project, chart){
+			this.ganttChart = chart;
+			this.project = project;
+			this.taskItem = taskInfo;
+			//control variables
+			this.checkMove = false;
+			this.checkResize = false;
+			this.moveChild = false;
+			this.maxPosXMove = -1;
+			this.minPosXMove = -1;
+			this.maxWidthResize = -1;
+			this.minWidthResize = -1;
+			this.posX = 0;
+			this.posY = 0;
+			this.mouseX = 0;
+			this.taskItemWidth = 0;
+			this.isHide = false;
+			this.hideTasksHeight = 0;
+			this.isExpanded = true;
+			this.descrTask = null;
+			this.cTaskItem = null;
+			this.cTaskNameItem = null;
+			this.parentTask = null;
+			this.predTask = null;
+			this.childTask = [];
+			this.childPredTask = [];
+			this.nextChildTask = null;
+			this.previousChildTask = null;
+			this.nextParentTask = null;
+			this.previousParentTask = null;
+		},
+		createConnectingLinesPN: function(){
+			var arrConnectingLinesNames = [];
+			var lineVerticalLeft = domConstruct.create("div", {
+				innerHTML: " ",
+				className: "ganttTaskLineVerticalLeft"
+			}, this.ganttChart.panelNames.firstChild);
+			var cTaskName = this.cTaskNameItem[0], pcTaskName = this.parentTask.cTaskNameItem[0];
+			domStyle.set(lineVerticalLeft, {
+				height: (cTaskName.offsetTop - pcTaskName.offsetTop) + "px",
+				top: (pcTaskName.offsetTop + 5) + "px",
+				left: (pcTaskName.offsetLeft - 9) + "px"
+			});
+			var LineHorizontalLeft = domConstruct.create("div", {
+				noShade: true,
+				color: "#000000",
+				className: "ganttTaskLineHorizontalLeft"
+			}, this.ganttChart.panelNames.firstChild);
+			domStyle.set(LineHorizontalLeft, {
+				left: (pcTaskName.offsetLeft - 9) + "px",
+				top: (cTaskName.offsetTop + 5) + "px",
+				height: "1px",
+				width: (cTaskName.offsetLeft - pcTaskName.offsetLeft + 4) + "px"
+			});
+			arrConnectingLinesNames.push(lineVerticalLeft);
+			arrConnectingLinesNames.push(LineHorizontalLeft);
+			return arrConnectingLinesNames;
+		},
+		createConnectingLinesDS: function(){
+			var contentData = this.ganttChart.contentData.firstChild;
+			var arrLines = [];
+			var arrowImg = domConstruct.create("div", {
+				className: "ganttImageArrow"
+			});
+			//vertical line
+			var lineVerticalRight = document.createElement("div");
+			//horizontal line
+			var lineHorizontal = document.createElement("div");
+			var posXPreviousTask = domStyle.get(this.predTask.cTaskItem[0], "left");
+			var posYPreviousTask = domStyle.get(this.predTask.cTaskItem[0], "top");
+			var posXChildTask = domStyle.get(this.cTaskItem[0], "left");
+			var posYChildTask = this.posY + 2;
+			//width task item
+			var widthPreviousTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
+			if(posYPreviousTask < posYChildTask){
+				domClass.add(lineVerticalRight, "ganttTaskLineVerticalRight");
+				domStyle.set(lineVerticalRight, {
+					height: (posYChildTask - this.ganttChart.heightTaskItem / 2 - posYPreviousTask - 3) + "px",
+					width: "1px",
+					left: (posXPreviousTask + widthPreviousTask - 20) + "px",
+					top: (posYPreviousTask + this.ganttChart.heightTaskItem) + "px"
+				});
+				domClass.add(lineHorizontal, "ganttTaskLineHorizontal");
+				domStyle.set(lineHorizontal, {
+					width: (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
+					left: (posXPreviousTask + widthPreviousTask - 20) + "px",
+					top: (posYChildTask + 2) + "px"
+				});
+				domClass.add(arrowImg, "ganttTaskArrowImg");
+				domStyle.set(arrowImg, {
+					left: (posXChildTask - 7) + "px",
+					top: (posYChildTask - 1) + "px"
+				});
+			}else{
+				domClass.add(lineVerticalRight, "ganttTaskLineVerticalRightPlus");
+				domStyle.set(lineVerticalRight, {
+					height: (posYPreviousTask + 2 - posYChildTask) + "px",
+					width: "1px",
+					left: (posXPreviousTask + widthPreviousTask - 20) + "px",
+					top: (posYChildTask + 2) + "px"
+				});
+				domClass.add(lineHorizontal, "ganttTaskLineHorizontalPlus");
+				domStyle.set(lineHorizontal, {
+					width: (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
+					left: (posXPreviousTask + widthPreviousTask - 20) + "px",
+					top: (posYChildTask + 2) + "px"
+				});
+				domClass.add(arrowImg, "ganttTaskArrowImgPlus");
+				domStyle.set(arrowImg, {
+					left: (posXChildTask - 7) + "px",
+					top: (posYChildTask - 1) + "px"
+				});
+			}
+			contentData.appendChild(lineVerticalRight);
+			contentData.appendChild(lineHorizontal);
+			contentData.appendChild(arrowImg);
+			arrLines.push(lineVerticalRight);
+			arrLines.push(arrowImg);
+			arrLines.push(lineHorizontal);
+			return arrLines;
+		},
+		showChildTasks: function(task, isOpen){
+			if(isOpen){
+				for(var i = 0; i < task.childTask.length; i++){
+					var cTask = task.childTask[i],
+						cTaskItem0 = cTask.cTaskItem[0], cTaskName0 = cTask.cTaskNameItem[0],
+						cTaskItem1 = cTask.cTaskItem[1], cTaskName1 = cTask.cTaskNameItem[1],
+						cTaskName2 = cTask.cTaskNameItem[2];
+					if(cTaskItem0.style.display == "none"){
+						cTaskItem0.style.display = "inline";
+						cTaskName0.style.display = "inline";
+						cTask.showDescTask();
+						task.isHide = false;
+						if(cTaskName2){
+							cTaskName2.style.display = "inline";
+							isOpen = cTask.isExpanded;
+						}
+						for(var k = 0; k < cTaskItem1.length; k++){
+							cTaskItem1[k].style.display = "inline";
+						}
+						for(var k = 0; k < cTaskName1.length; k++){
+							cTaskName1[k].style.display = "inline";
+						}
+						(cTask.taskIdentifier) && (cTask.taskIdentifier.style.display = "inline");
+						this.hideTasksHeight += this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+						if(cTask.childTask.length > 0){
+							this.showChildTasks(cTask, isOpen);
+						}
+					}
+				}
+			}
+		},
+		hideChildTasks: function(task){
+			for(var i = 0; i < task.childTask.length; i++){
+				var cTask = task.childTask[i],
+					cTaskItem0 = cTask.cTaskItem[0], cTaskName0 = cTask.cTaskNameItem[0],
+					cTaskItem1 = cTask.cTaskItem[1], cTaskName1 = cTask.cTaskNameItem[1],
+					cTaskName2 = cTask.cTaskNameItem[2];
+				if(cTaskItem0.style.display != "none"){
+					cTaskItem0.style.display = "none";
+					cTaskName0.style.display = "none";
+					cTask.hideDescTask();
+					task.isHide = true;
+					if(cTaskName2){
+						cTaskName2.style.display = "none";
+					}
+					for(var k = 0; k < cTaskItem1.length; k++){
+						cTaskItem1[k].style.display = "none";
+					}
+					for(var k = 0; k < cTaskName1.length; k++){
+						cTaskName1[k].style.display = "none";
+					}
+					(cTask.taskIdentifier) && (cTask.taskIdentifier.style.display = "none");
+					this.hideTasksHeight += (this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra);
+					if(cTask.childTask.length > 0){
+						this.hideChildTasks(cTask);
+					}
+				}
+			}
+		},
+		shiftCurrentTasks: function(task, height){
+			this.shiftNextTask(this, height);
+			task.project.shiftNextProject(task.project, height);
+		},
+		shiftTask: function(task, height){
+			task.posY = task.posY + height;
+			var taskItem0 = task.cTaskItem[0], taskName0 = task.cTaskNameItem[0],
+				taskItem1 = task.cTaskItem[1], taskName1 = task.cTaskNameItem[1],
+				taskName2 = task.cTaskNameItem[2];
+			taskName0.style.top = parseInt(taskName0.style.top) + height + "px";
+			if(taskName2){
+				taskName2.style.top = parseInt(taskName2.style.top) + height + "px";
+			}
+			if(task.parentTask){
+				if(parseInt(this.cTaskNameItem[0].style.top) > parseInt(task.parentTask.cTaskNameItem[0].style.top) &&
+				(taskName1[0].style.display != "none")){
+					taskName1[0].style.height = parseInt(taskName1[0].style.height) + height + "px";
+				}else{
+					taskName1[0].style.top = parseInt(taskName1[0].style.top) + height + "px";
+				}
+				taskName1[1].style.top = parseInt(taskName1[1].style.top) + height + "px";
+			}
+			taskItem0.style.top = parseInt(taskItem0.style.top) + height + "px";
+			task.descrTask.style.top = parseInt(task.descrTask.style.top) + height + "px";
+			if(task.predTask){
+				if(((parseInt(this.cTaskItem[0].style.top) > parseInt(task.predTask.cTaskItem[0].style.top)) ||
+				(this.cTaskItem[0].id == task.predTask.taskItem.id)) &&
+				taskItem1[0].style.display != "none"){
+					taskItem1[0].style.height = parseInt(taskItem1[0].style.height) + height + "px";
+				}else{
+					taskItem1[0].style.top = parseInt(taskItem1[0].style.top) + height + "px";
+				}
+				taskItem1[1].style.top = parseInt(taskItem1[1].style.top) + height + "px";
+				taskItem1[2].style.top = parseInt(taskItem1[2].style.top) + height + "px";
+			}
+		},
+		shiftNextTask: function(task, height){
+			if(task.nextChildTask){
+				this.shiftTask(task.nextChildTask, height);
+				this.shiftChildTask(task.nextChildTask, height);
+				this.shiftNextTask(task.nextChildTask, height);
+			}else if(task.parentTask){
+				this.shiftNextTask(task.parentTask, height);
+			}else if(task.nextParentTask){
+				this.shiftTask(task.nextParentTask, height);
+				this.shiftChildTask(task.nextParentTask, height);
+				this.shiftNextTask(task.nextParentTask, height);
+			}
+		},
+		shiftChildTask: function(task, height){
+			arrayUtil.forEach(task.childTask, function(cTask){
+				this.shiftTask(cTask, height);
+				if(cTask.childTask.length > 0){
+					this.shiftChildTask(cTask, height);
+				}
+			}, this);
+		},
+		endMove: function(){
+			var cTask0 = this.cTaskItem[0];
+			var width = domStyle.get(cTask0, "left") - this.posX;
+			var startTime = this.getDateOnPosition(domStyle.get(cTask0, "left"));
+			startTime = this.checkPos(startTime);
+			if(this.checkMove){
+				width = this.ganttChart.getPosOnDate(startTime) - this.posX;
+				this.moveCurrentTaskItem(width, this.moveChild);
+				this.project.shiftProjectItem();
+			}
+			this.checkMove = false;
+			this.posX = 0;
+			this.maxPosXMove = -1;
+			this.minPosXMove = -1;
+			cTask0.childNodes[1].firstChild.rows[0].cells[0].innerHTML = "";
+			this.adjustPanelTime();
+			if(this.ganttChart.resource){
+				this.ganttChart.resource.refresh();
+			}
+		},
+		checkPos: function(startTime){
+			var cTask0 = this.cTaskItem[0];
+			var h = startTime.getHours();
+			if(h >= 12){
+				startTime.setDate(startTime.getDate() + 1);
+				startTime.setHours(0);
+				if((parseInt(cTask0.firstChild.firstChild.width) + this.ganttChart.getPosOnDate(startTime) > this.maxPosXMove) && (this.maxPosXMove != -1)){
+					startTime.setDate(startTime.getDate() - 1);
+					startTime.setHours(0);
+				}
+			}else if((h < 12) && (h != 0)){
+				startTime.setHours(0);
+				if((this.ganttChart.getPosOnDate(startTime) < this.minPosXMove)){
+					startTime.setDate(startTime.getDate() + 1);
+				}
+			}
+			cTask0.style.left = this.ganttChart.getPosOnDate(startTime) + "px";
+			return startTime;
+		},
+		getMaxPosPredChildTaskItem: function(){
+			var posPredChildTaskItem = 0;
+			var nextPosPredChildTaskItem = 0;
+			for(var i = 0; i < this.childPredTask.length; i++){
+				nextPosPredChildTaskItem = this.getMaxPosPredChildTaskItemInTree(this.childPredTask[i]);
+				if(nextPosPredChildTaskItem > posPredChildTaskItem){
+					posPredChildTaskItem = nextPosPredChildTaskItem;
+				}
+			}
+			return posPredChildTaskItem;
+		},
+		getMaxPosPredChildTaskItemInTree: function(task){
+			var cTask0 = task.cTaskItem[0];
+			var currentPos = parseInt(cTask0.firstChild.firstChild.width) + domStyle.get(cTask0, "left");
+			var posPredChildTaskItem = 0;
+			var nextPosPredChildTaskItem = 0;
+			arrayUtil.forEach(task.childPredTask, function(cpTask){
+				nextPosPredChildTaskItem = this.getMaxPosPredChildTaskItemInTree(cpTask);
+				if(nextPosPredChildTaskItem > posPredChildTaskItem){
+					posPredChildTaskItem = nextPosPredChildTaskItem;
+				}
+			}, this);
+			return posPredChildTaskItem > currentPos ? posPredChildTaskItem : currentPos;
+		},
+		moveCurrentTaskItem: function(width, moveChild){
+			var taskItem = this.cTaskItem[0];
+			this.taskItem.startTime = new Date(this.ganttChart.startDate);
+			this.taskItem.startTime.setHours(this.taskItem.startTime.getHours() + (parseInt(taskItem.style.left) / this.ganttChart.pixelsPerHour));
+			this.showDescTask();
+			var cTask1 = this.cTaskItem[1];
+			if(cTask1.length > 0){
+				cTask1[2].style.width = parseInt(cTask1[2].style.width) + width + "px";
+				cTask1[1].style.left = parseInt(cTask1[1].style.left) + width + "px";
+			}
+			arrayUtil.forEach(this.childTask, function(cTask){
+				if(!cTask.predTask){
+					this.moveChildTaskItems(cTask, width, moveChild);
+				}
+			}, this);
+			arrayUtil.forEach(this.childPredTask, function(cpTask){
+				this.moveChildTaskItems(cpTask, width, moveChild);
+			}, this);
+		},
+		moveChildTaskItems: function(task, width, moveChild){
+			var taskItem = task.cTaskItem[0];
+			if(moveChild){
+				taskItem.style.left = parseInt(taskItem.style.left) + width + "px";
+				task.adjustPanelTime();
+				task.taskItem.startTime = new Date(this.ganttChart.startDate);
+				task.taskItem.startTime.setHours(task.taskItem.startTime.getHours() + (parseInt(taskItem.style.left) / this.ganttChart.pixelsPerHour));
+				var ctItem = task.cTaskItem[1];
+				arrayUtil.forEach(ctItem, function(item){
+					item.style.left = parseInt(item.style.left) + width + "px";
+				}, this);
+				arrayUtil.forEach(task.childTask, function(cTask){
+					if(!cTask.predTask){
+						this.moveChildTaskItems(cTask, width, moveChild);
+					}
+				}, this);
+				arrayUtil.forEach(task.childPredTask, function(cpTask){
+					this.moveChildTaskItems(cpTask, width, moveChild);
+				}, this);
+			}else{
+				var ctItem = task.cTaskItem[1];
+				if(ctItem.length > 0){
+					var item0 = ctItem[0], item2 = ctItem[2];
+					item2.style.left = parseInt(item2.style.left) + width + "px";
+					item2.style.width = parseInt(item2.style.width) - width + "px";
+					item0.style.left = parseInt(item0.style.left) + width + "px";
+				}
+			}
+			task.moveDescTask();
+		},
+		adjustPanelTime: function(){
+			var taskItem = this.cTaskItem[0];
+			var width = parseInt(taskItem.style.left) + parseInt(taskItem.firstChild.firstChild.width) + this.ganttChart.panelTimeExpandDelta;
+			width += this.descrTask.offsetWidth;
+			this.ganttChart.adjustPanelTime(width);
+		},
+		getDateOnPosition: function(position){
+			var date = new Date(this.ganttChart.startDate);
+			date.setHours(date.getHours() + (position / this.ganttChart.pixelsPerHour));
+			return date;
+		},
+		moveItem: function(event){
+			var pageX = event.screenX;
+			var posTaskItem = (this.posX + (pageX - this.mouseX));
+			var widthTaskItem = parseInt(this.cTaskItem[0].childNodes[0].firstChild.width);
+			var posTaskItemR = posTaskItem + widthTaskItem;
+			if(this.checkMove){
+				if(((this.minPosXMove <= posTaskItem)) &&
+				((posTaskItemR <= this.maxPosXMove) || (this.maxPosXMove == -1))){
+					this.moveTaskItem(posTaskItem);
+				}
+			}
+		},
+		moveTaskItem: function(posX){
+			var cTask = this.cTaskItem[0];
+			cTask.style.left = posX + "px";
+			cTask.childNodes[1].firstChild.rows[0].cells[0].innerHTML = this.getDateOnPosition(posX).getDate() + '.' + (this.getDateOnPosition(posX).getMonth() + 1) + '.' + this.getDateOnPosition(posX).getUTCFullYear();
+		},
+		resizeItem: function(event){
+			if(this.checkResize){
+				var mouseX = event.screenX;
+				var widthTaskItem = this.taskItemWidth + (mouseX - this.mouseX);
+				if(widthTaskItem >= this.taskItemWidth){
+					if((widthTaskItem <= this.maxWidthResize) || (this.maxWidthResize == -1)){
+						this.resizeTaskItem(widthTaskItem);
+					}else if((this.maxWidthResize != -1) && (widthTaskItem > this.maxWidthResize)){
+						this.resizeTaskItem(this.maxWidthResize);
+					}
+				}else if(widthTaskItem <= this.taskItemWidth){
+					if(widthTaskItem >= this.minWidthResize){
+						this.resizeTaskItem(widthTaskItem);
+					}else if(widthTaskItem < this.minWidthResize){
+						this.resizeTaskItem(this.minWidthResize);
+					}
+				}
+			}
+		},
+		resizeTaskItem: function(width){
+			var taskItem = this.cTaskItem[0];
+			var countHours = Math.round(width / this.ganttChart.pixelsPerWorkHour);
+			var trow = taskItem.childNodes[0].firstChild.rows[0],
+				rc0 = trow.cells[0], rc1 = trow.cells[1];
+			rc0 && (rc0.firstChild.style.width = parseInt(rc0.width) * width / 100 + "px");
+			rc1 && (rc1.firstChild.style.width = parseInt(rc1.width) * width / 100 + "px");
+			taskItem.childNodes[0].firstChild.width = width + "px";
+			taskItem.childNodes[1].firstChild.width = width + "px";
+			//resize info
+			this.cTaskItem[0].childNodes[1].firstChild.rows[0].cells[0].innerHTML = countHours;
+			var tcNode2 = taskItem.childNodes[2];
+			tcNode2.childNodes[0].style.width = width + "px";
+			tcNode2.childNodes[1].style.left = width - 10 + "px";
+		},
+		endResizeItem: function(){
+			var taskItem = this.cTaskItem[0];
+			if((this.taskItemWidth != parseInt(taskItem.childNodes[0].firstChild.width))){
+				var posXL = taskItem.offsetLeft;
+				var posXR = taskItem.offsetLeft + parseInt(taskItem.childNodes[0].firstChild.width);
+				this.taskItem.duration = Math.round((posXR - posXL) / this.ganttChart.pixelsPerWorkHour);
+				if(this.childPredTask.length > 0){
+					for(var j = 0; j < this.childPredTask.length; j++){
+						var cpctItem = this.childPredTask[j].cTaskItem[1],
+							item0 = cpctItem[0], item2 = cpctItem[2], tcNode0 = taskItem.childNodes[0];
+						item2.style.width = parseInt(item2.style.width) - (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
+						item2.style.left = parseInt(item2.style.left) + (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
+						item0.style.left = parseInt(item0.style.left) + (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
+					}
+				}
+			}
+			this.cTaskItem[0].childNodes[1].firstChild.rows[0].cells[0].innerHTML = "";
+			this.checkResize = false;
+			this.taskItemWidth = 0;
+			this.mouseX = 0;
+			this.showDescTask();
+			this.project.shiftProjectItem();
+			this.adjustPanelTime();
+			if(this.ganttChart.resource){
+				this.ganttChart.resource.refresh();
+			}
+		},
+		startMove: function(event){
+			this.moveChild = event.ctrlKey;
+			this.mouseX = event.screenX;
+			this.getMoveInfo();
+			this.checkMove = true;
+			this.hideDescTask();
+		},
+		showDescTask: function(){
+			var posX = (parseInt(this.cTaskItem[0].style.left) + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
+			this.descrTask.style.left = posX + "px";
+			this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+			this.descrTask.style.visibility = 'visible';
+		},
+		hideDescTask: function(){
+			domStyle.set(this.descrTask, "visibility", "hidden");
+		},
+		buildResourceInfo: function(resourceInfo){
+			if(this.childTask && this.childTask.length > 0){
+				for(var i = 0; i < this.childTask.length; i++){
+					var cTask = this.childTask[i];
+					cTask.buildResourceInfo(resourceInfo);
+				}
+			}
+			if(lang.trim(this.taskItem.taskOwner).length > 0){
+				var owners = this.taskItem.taskOwner.split(";");
+				for(var i = 0; i < owners.length; i++){
+					var o = owners[i];
+					if(lang.trim(o).length <= 0){
+						continue;
+					}
+					resourceInfo[o] ? (resourceInfo[o].push(this)) : (resourceInfo[o] = [this]);
+				}
+			}
+		},
+		objKeyToStr: function(obj, delm){
+			var returnStr = "";
+			delm = delm || " ";
+			if(obj){
+				for(var key in obj){
+					returnStr += delm + key;
+				}
+			}
+			return returnStr;
+		},
+		getTaskOwner: function(){
+			var tOwner = {};
+			if(lang.trim(this.taskItem.taskOwner).length > 0){
+				var owners = this.taskItem.taskOwner.split(";");
+				for(var i = 0; i < owners.length; i++){
+					var o = owners[i];
+					tOwner[o] = 1;
+				}
+			}
+			arrayUtil.forEach(this.childTask, function(ctask){
+				lang.mixin(tOwner, ctask.getTaskOwner());
+			}, this);
+			return tOwner;
+		},
+		moveDescTask: function(){
+			var posX = (parseInt(this.cTaskItem[0].style.left) + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
+			this.descrTask.style.left = posX + "px";
+		},
+		getMoveInfo: function(){
+			this.posX = parseInt(this.cTaskItem[0].style.left);
+			var widthTaskItem = parseInt(this.cTaskItem[0].childNodes[0].firstChild.width);
+			var posParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].style.left);
+			var posPredTaskItem = !this.predTask ? 0 : parseInt(this.predTask.cTaskItem[0].style.left) + parseInt(this.predTask.cTaskItem[0].childNodes[0].firstChild.width);
+			var widthParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].childNodes[0].firstChild.width);
+		
+			var childPredPosX = 0;
+			var childParentPosX = 0;
+			var childParentPosXR = 0;
+			if(this.childPredTask.length > 0){
+				var posChildTaskItem = null;
+				arrayUtil.forEach(this.childPredTask, function(cpTask){
+					if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem > parseInt(cpTask.cTaskItem[0].style.left)))){
+						posChildTaskItem = parseInt(cpTask.cTaskItem[0].style.left);
+					}
+				}, this);
+				childPredPosX = posChildTaskItem;
+			}
+			if(this.childTask.length > 0){
+				var posChildTaskItemR = null;
+				arrayUtil.forEach(this.childTask, function(cTask){
+					if((!posChildTaskItemR) || ((posChildTaskItemR) && (posChildTaskItemR > (parseInt(cTask.cTaskItem[0].style.left))))){
+						posChildTaskItemR = parseInt(cTask.cTaskItem[0].style.left);
+					}
+				}, this);
+				childParentPosXR = posChildTaskItemR;
+				var posChildTaskItem = null;
+				arrayUtil.forEach(this.childTask, function(cTask){
+					if((!posChildTaskItem) || ((posChildTaskItem)
+					&& (posChildTaskItem < (parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width))))){
+						posChildTaskItem = parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width);
+					}
+				}, this);
+				childParentPosX = posChildTaskItem;
+			}
+			if(!this.moveChild){
+				if(this.childPredTask.length > 0){
+					if(this.maxPosXMove < childPredPosX) this.maxPosXMove = childPredPosX;
+				}
+				if(this.childTask.length > 0){
+					if((this.childPredTask.length > 0) && (this.maxPosXMove - widthTaskItem) > childParentPosXR){
+						this.maxPosXMove = this.maxPosXMove - ((this.maxPosXMove - widthTaskItem) - childParentPosXR);
+					}
+					if(!(this.childPredTask.length > 0)){
+						this.maxPosXMove = childParentPosXR + widthTaskItem;
+					}
+					this.minPosXMove = (childParentPosX - widthTaskItem);
+				}
+				if(posParentTaskItem > 0){
+					if((!(this.childPredTask.length > 0)) && (this.childTask.length > 0)){
+						if(this.maxPosXMove > posParentTaskItem + widthParentTaskItem){
+							this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
+						}
+					}
+					if(this.minPosXMove <= posParentTaskItem){
+						this.minPosXMove = posParentTaskItem;
+					}
+					if((!(this.childTask.length > 0)) && (!(this.childPredTask.length > 0))){
+						this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
+					}else if((!(this.childTask.length > 0)) && (this.childPredTask.length > 0)){
+						if((posParentTaskItem + widthParentTaskItem) > posPredTaskItem){
+							this.maxPosXMove = childPredPosX;
+						}
+					}
+				}
+				if(posPredTaskItem > 0){
+					if(this.minPosXMove <= posPredTaskItem){
+						this.minPosXMove = posPredTaskItem;
+					}
+				}
+				if((posPredTaskItem == 0) && (posParentTaskItem == 0)){
+					if(this.minPosXMove <= this.ganttChart.initialPos){
+						this.minPosXMove = this.ganttChart.initialPos;
+					}
+				}
+			}else{
+				if((posParentTaskItem > 0) && (posPredTaskItem == 0)){
+					this.minPosXMove = posParentTaskItem;
+					this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
+				}else if((posParentTaskItem == 0) && (posPredTaskItem == 0)){
+					this.minPosXMove = this.ganttChart.initialPos;
+					this.maxPosXMove = -1;
+				}else if((posParentTaskItem > 0) && (posPredTaskItem > 0)){
+					this.minPosXMove = posPredTaskItem;
+					this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
+				}else if((posParentTaskItem == 0) && (posPredTaskItem > 0)){
+					this.minPosXMove = posPredTaskItem;
+					this.maxPosXMove = -1;
+				}
+				if((this.parentTask) && (this.childPredTask.length > 0)){
+					var posChildTaskItem = this.getMaxPosPredChildTaskItem(this);
+					var posParentTaskItem = parseInt(this.parentTask.cTaskItem[0].style.left) + parseInt(this.parentTask.cTaskItem[0].firstChild.firstChild.width);
+					this.maxPosXMove = this.posX + widthTaskItem + posParentTaskItem - posChildTaskItem;
+				}
+			}
+		},
+		startResize: function(event){
+			this.mouseX = event.screenX;
+			this.getResizeInfo();
+			this.hideDescTask();
+			this.checkResize = true;
+			this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
+		},
+		getResizeInfo: function(){
+			var cTask = this.cTaskItem[0];
+			var posParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].style.left);
+			var widthParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].childNodes[0].firstChild.width);
+			var posTaskItem = parseInt(cTask.style.left);
+			var childPredPosX = 0;
+			var childParentPosX = 0;
+			if(this.childPredTask.length > 0){
+				var posChildTaskItem = null;
+				arrayUtil.forEach(this.childPredTask, function(cpTask){
+					if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem > parseInt(cpTask.cTaskItem[0].style.left)))){
+						posChildTaskItem = parseInt(cpTask.cTaskItem[0].style.left);
+					}
+				}, this);
+				childPredPosX = posChildTaskItem;
+			}
+			if(this.childTask.length > 0){
+				var posChildTaskItem = null;
+				arrayUtil.forEach(this.childTask, function(cTask){
+					if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem < (parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width))))){
+						posChildTaskItem = parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width);
+					}
+				}, this);
+				childParentPosX = posChildTaskItem;
+			}
+			this.minWidthResize = this.ganttChart.pixelsPerDay;
+			if(this.childTask.length > 0){
+				this.minWidthResize = childParentPosX - posTaskItem;
+			}
+			if((this.childPredTask.length > 0) && (!this.parentTask)){
+				this.maxWidthResize = childPredPosX - posTaskItem;
+			}else if((this.childPredTask.length > 0) && (this.parentTask)){
+				var w1 = posParentTaskItem + widthParentTaskItem - posTaskItem;
+				var w2 = childPredPosX - posTaskItem;
+				this.maxWidthResize = Math.min(w1, w2);
+			}else if((this.childPredTask.length == 0) && (this.parentTask)){
+				this.maxWidthResize = posParentTaskItem + widthParentTaskItem - posTaskItem;
+			}
+		},
+		createTaskItem: function(){
+			this.posX = this.ganttChart.getPosOnDate(this.taskItem.startTime);
+			var itemControl = domConstruct.create("div", {
+				id: this.taskItem.id,
+				className: "ganttTaskItemControl"
+			});
+			domStyle.set(itemControl, {
+				left: this.posX + "px",
+				top: this.posY + "px"
+			});
+			var divTaskItem = domConstruct.create("div", {className: "ganttTaskDivTaskItem"}, itemControl);
+			var tblTaskItem = domConstruct.create("table", {
+				cellPadding: "0",
+				cellSpacing: "0",
+				width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px",
+				className: "ganttTaskTblTaskItem"
+			}, divTaskItem);
+			var rowTblTask = tblTaskItem.insertRow(tblTaskItem.rows.length);
+			if(this.taskItem.percentage != 0){
+				var cellTblTask = domConstruct.create("td", {
+					height: this.ganttChart.heightTaskItem + "px",
+					width: this.taskItem.percentage + "%"
+				}, rowTblTask);
+				cellTblTask.style.lineHeight = "1px";
+				var imageProgress = domConstruct.create("div", {
+					className: "ganttImageTaskProgressFilled"
+				}, cellTblTask);
+				domStyle.set(imageProgress, {
+					width: (this.taskItem.percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+			}
+			if(this.taskItem.percentage != 100){
+				var cellTblTask = domConstruct.create("td", {
+					height: this.ganttChart.heightTaskItem + "px",
+					width: (100 - this.taskItem.percentage) + "%"
+				}, rowTblTask);
+				cellTblTask.style.lineHeight = "1px";
+				var imageProgressFill = domConstruct.create("div", {
+					className: "ganttImageTaskProgressBg"
+				}, cellTblTask);
+				domStyle.set(imageProgressFill, {
+					width: ((100 - this.taskItem.percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+			}
+			if(this.ganttChart.isContentEditable){
+				var divTaskInfo = domConstruct.create("div", {className: "ganttTaskDivTaskInfo"}, itemControl);
+				var tblTaskInfo = domConstruct.create("table", {
+					cellPadding: "0",
+					cellSpacing: "0",
+					height: this.ganttChart.heightTaskItem + "px",
+					width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
+				}, divTaskInfo);
+				var rowTaskInfo = tblTaskInfo.insertRow(0);
+				var cellTaskInfo = domConstruct.create("td", {
+					align: "center",
+					vAlign: "top",
+					height: this.ganttChart.heightTaskItem + "px",
+					className: "ganttMoveInfo"
+				}, rowTaskInfo);
+				var divTaskName = domConstruct.create("div", {className: "ganttTaskDivTaskName"}, itemControl);
+				var divMove = domConstruct.create("div", {}, divTaskName);
+				domConstruct.create("input", {
+					className: "ganttTaskDivMoveInput",
+					type: "text"
+				}, divMove);
+				domStyle.set(divMove, {
+					background: "#000000",
+					opacity: 0
+				});
+				domStyle.set(divMove, {
+					height: this.ganttChart.heightTaskItem + "px",
+					width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
+				});
+				//Creation resize area
+				var divResize = domConstruct.create("div", {className: "ganttTaskDivResize"}, divTaskName);
+				domConstruct.create("input", {
+					className: "ganttTaskDivResizeInput",
+					type: "text"
+				}, divResize);
+				domStyle.set(divResize, {
+					left: (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour - 10) + "px",
+					height: this.ganttChart.heightTaskItem + "px",
+					width: "10px"
+				});
+				this.ganttChart._events.push(
+					on(divMove, "mousedown", lang.hitch(this, function(event){
+						//start move
+						this.moveMoveConn = on(document, "mousemove", lang.hitch(this, function(e){
+							this.checkMove && this.moveItem(e);
+						}));
+						this.moveUpConn = on(document, "mouseup", lang.hitch(this, function(){
+							if(this.checkMove){
+								this.endMove();
+								this.ganttChart.isMoving = false;
+								document.body.releaseCapture && document.body.releaseCapture();
+								this.moveMoveConn.remove();
+								this.moveUpConn.remove();
+							}
+						}));
+						this.startMove(event);
+						this.ganttChart.isMoving = true;
+						document.body.setCapture && document.body.setCapture(false);
+					}))
+				);
+				this.ganttChart._events.push(
+					on(divMove, "mouseover", lang.hitch(this, function(event){
+						event.target && (event.target.style.cursor = "move");
+					}))
+				);
+				this.ganttChart._events.push(
+					on(divMove, "mouseout", lang.hitch(this, function(event){
+						event.target.style.cursor = "";
+					}))
+				);
+				this.ganttChart._events.push(
+					on(divResize, "mousedown", lang.hitch(this, function(event){
+						//start resize
+						this.resizeMoveConn = on(document, "mousemove", lang.hitch(this, function(e){
+							this.checkResize && this.resizeItem(e);
+						}));
+						this.resizeUpConn = on(document, "mouseup", lang.hitch(this, function(){
+							if(this.checkResize){
+								this.endResizeItem();
+								this.ganttChart.isResizing = false;
+								document.body.releaseCapture && document.body.releaseCapture();
+								this.resizeMoveConn.remove();
+								this.resizeUpConn.remove();
+							}
+						}));
+						this.startResize(event);
+						this.ganttChart.isResizing = true;
+						document.body.setCapture && document.body.setCapture(false);
+					}))
+				);
+				this.ganttChart._events.push(
+					on(divResize, "mouseover", lang.hitch(this, function(event){
+						(!this.ganttChart.isMoving) && (!this.ganttChart.isResizing) && event.target && (event.target.style.cursor = "e-resize");
+					}))
+				);
+				this.ganttChart._events.push(
+					on(divResize, "mouseout", lang.hitch(this, function(event){
+						!this.checkResize && event.target && (event.target.style.cursor = "");
+					}))
+				);
+			}
+			return itemControl;
+		},
+		createTaskNameItem: function(){
+			var divName = domConstruct.create("div", {
+				id: this.taskItem.id,
+				className: "ganttTaskTaskNameItem",
+				title: this.taskItem.name + ", id: " + this.taskItem.id + " ",
+				innerHTML: this.taskItem.name
+			});
+			domStyle.set(divName, "top", this.posY + "px");
+			domAttr.set(divName, "tabIndex", 0);
+			if(this.ganttChart.isShowConMenu){
+				this.ganttChart._events.push(
+					on(divName, "mouseover", lang.hitch(this, function(event){
+						domClass.add(divName, "ganttTaskTaskNameItemHover");
+						clearTimeout(this.ganttChart.menuTimer);
+						this.ganttChart.tabMenu.clear();
+						this.ganttChart.tabMenu.show(event.target, this);
+					}))
+				);
+				this.ganttChart._events.push(
+					on(divName, "keydown", lang.hitch(this, function(event){
+						if(event.keyCode == keys.ENTER){
+							this.ganttChart.tabMenu.clear();
+							this.ganttChart.tabMenu.show(event.target, this);
+						}
+						if(this.ganttChart.tabMenu.isShow && (event.keyCode == keys.LEFT_ARROW || event.keyCode == keys.RIGHT_ARROW)){
+							focus(this.ganttChart.tabMenu.menuPanel.firstChild.rows[0].cells[0]);
+						}
+						if(this.ganttChart.tabMenu.isShow && event.keyCode == keys.ESCAPE){
+							this.ganttChart.tabMenu.hide();
+						}
+					}))
+				);
+				this.ganttChart._events.push(
+					on(divName, "mouseout", lang.hitch(this, function(){
+						domClass.remove(divName, "ganttTaskTaskNameItemHover");
+						clearTimeout(this.ganttChart.menuTimer);
+						this.ganttChart.menuTimer = setTimeout(lang.hitch(this, function(){
+							this.ganttChart.tabMenu.hide();
+						}), 200);
+					}))
+				);
+				this.ganttChart._events.push(
+					on(this.ganttChart.tabMenu.menuPanel, "mouseover", lang.hitch(this, function(){
+						clearTimeout(this.ganttChart.menuTimer);
+					}))
+				);
+				this.ganttChart._events.push(
+					on(this.ganttChart.tabMenu.menuPanel, "keydown", lang.hitch(this, function(event){
+						if(this.ganttChart.tabMenu.isShow && event.keyCode == keys.ESCAPE){
+							this.ganttChart.tabMenu.hide();
+						}
+					}))
+				);
+				this.ganttChart._events.push(
+					on(this.ganttChart.tabMenu.menuPanel, "mouseout", lang.hitch(this, function(){
+						clearTimeout(this.ganttChart.menuTimer);
+						this.ganttChart.menuTimer = setTimeout(lang.hitch(this, function(){
+							this.ganttChart.tabMenu.hide();
+						}), 200);
+					}))
+				);
+			}
+			return divName;
+		},
+		createTaskDescItem: function(){
+			var posX = (this.posX + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
+			var divDesc = domConstruct.create("div", {
+				innerHTML: this.objKeyToStr(this.getTaskOwner()),
+				className: "ganttTaskDescTask"
+			});
+			domStyle.set(divDesc, {
+				left: posX + "px",
+				top: this.posY + "px"
+			});
+			return this.descrTask = divDesc;
+		},
+		checkWidthTaskNameItem: function(){
+			if(this.cTaskNameItem[0].offsetWidth + this.cTaskNameItem[0].offsetLeft > this.ganttChart.maxWidthTaskNames){
+				var width = this.cTaskNameItem[0].offsetWidth + this.cTaskNameItem[0].offsetLeft - this.ganttChart.maxWidthTaskNames;
+				var countChar = Math.round(width / (this.cTaskNameItem[0].offsetWidth / this.cTaskNameItem[0].firstChild.length));
+				var tName = this.taskItem.name.substring(0, this.cTaskNameItem[0].firstChild.length - countChar - 3);
+				tName += "...";
+				this.cTaskNameItem[0].innerHTML = tName;
+			}
+		},
+		refreshTaskItem: function(itemControl){
+			this.posX = this.ganttChart.getPosOnDate(this.taskItem.startTime);
+			domStyle.set(itemControl, {
+				"left": this.posX + "px"
+			});
+			var divTaskItem = itemControl.childNodes[0];
+			var tblTaskItem = divTaskItem.firstChild;
+			tblTaskItem.width = (!this.taskItem.duration ? 1 : this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) + "px";
+			var rowTblTask = tblTaskItem.rows[0];
+			if(this.taskItem.percentage != 0){
+				var cellTblTask = rowTblTask.firstChild;
+				cellTblTask.height = this.ganttChart.heightTaskItem + "px";
+				cellTblTask.width = this.taskItem.percentage + "%";
+				cellTblTask.style.lineHeight = "1px";
+				var imageProgress = cellTblTask.firstChild;
+				domStyle.set(imageProgress, {
+					width: (!this.taskItem.duration ? 1 : (this.taskItem.percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+			}
+			if(this.taskItem.percentage != 100){
+				var cellTblTask = rowTblTask.lastChild;
+				cellTblTask.height = this.ganttChart.heightTaskItem + "px";
+				cellTblTask.width = (100 - this.taskItem.percentage) + "%";
+				cellTblTask.style.lineHeight = "1px";
+				var imageProgressFill = cellTblTask.firstChild;
+				domStyle.set(imageProgressFill, {
+					width: (!this.taskItem.duration ? 1 : ((100 - this.taskItem.percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+			}
+			if(this.ganttChart.isContentEditable){
+				var divTaskInfo = itemControl.childNodes[1];
+				var tblTaskInfo = divTaskInfo.firstChild;
+				tblTaskInfo.height = this.ganttChart.heightTaskItem + "px";
+				tblTaskInfo.width = (!this.taskItem.duration ? 1 : (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour)) + "px";
+				var rowTaskInfo = tblTaskInfo.rows[0];
+				var cellTaskInfo = rowTaskInfo.firstChild;
+				cellTaskInfo.height = this.ganttChart.heightTaskItem + "px";
+				var divTaskName = itemControl.childNodes[2];
+				var divMove = divTaskName.firstChild;
+				divMove.style.height = this.ganttChart.heightTaskItem + "px";
+				divMove.style.width = (!this.taskItem.duration ? 1 : (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour)) + "px";
+				//Creation resize area
+				var divResize = divTaskName.lastChild;
+				domStyle.set(divResize, {
+					"left": (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour - 10) + "px"
+				});
+				divResize.style.height = this.ganttChart.heightTaskItem + "px";
+				divResize.style.width = "10px";
+			}
+			return itemControl;
+		},
+		refreshTaskDesc: function(divDesc){
+			var posX = (this.posX + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
+			domStyle.set(divDesc, {
+				"left": posX + "px"
+			});
+			return divDesc;
+		},
+		refreshConnectingLinesDS: function(arrLines){
+			var arrowImg = arrLines[1];
+			var lineVerticalRight = arrLines[0];
+			//horizontal line
+			var lineHorizontal = arrLines[2];
+			var posXPreviousTask = domStyle.get(this.predTask.cTaskItem[0], "left");
+			var posYPreviousTask = domStyle.get(this.predTask.cTaskItem[0], "top");
+			var posXChildTask = domStyle.get(this.cTaskItem[0], "left");
+			var posYChildTask = this.posY + 2;
+			//width task item
+
+			var widthPreviousTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
+			if(posYPreviousTask < posYChildTask){
+				domStyle.set(lineVerticalRight, {
+					"height": (posYChildTask - this.ganttChart.heightTaskItem / 2 - posYPreviousTask - 3) + "px",
+					"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
+				});
+				domStyle.set(lineHorizontal, {
+					"width": (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
+					"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
+				});
+			
+				domStyle.set(arrowImg, {
+					"left": (posXChildTask - 7) + "px"
+				});
+			}else{
+				domStyle.set(lineVerticalRight, {
+					"height": (posYPreviousTask + 2 - posYChildTask) + "px",
+					"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
+				});
+				domStyle.set(lineHorizontal, {
+					"width": (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
+					"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
+				});
+				domStyle.set(arrowImg, {
+					"left": (posXChildTask - 7) + "px"
+				});
+			}
+			return arrLines;
+		},
+		postLoadData: function(){
+			//TODO e.g. task relative info...
+		},
+		refresh: function(){
+			if(this.childTask && this.childTask.length > 0){
+				arrayUtil.forEach(this.childTask, function(cTask){
+					cTask.refresh();
+				}, this);
+			}
+			//creation task item
+			this.refreshTaskItem(this.cTaskItem[0]);
+			this.refreshTaskDesc(this.cTaskItem[0].nextSibling);
+			//Create Connecting Lines
+
+			if(this.taskItem.previousTask && this.predTask){
+				this.refreshConnectingLinesDS(this.cTaskItem[1]);
+			}
+			return this;
+		},
+		create: function(){
+			var containerTasks = this.ganttChart.contentData.firstChild;
+
+			var previousTask = this.taskItem.previousTask;
+			var parentTask = this.taskItem.parentTask;
+			var isCParentTask = (this.taskItem.cldTasks.length > 0);
+			this.cTaskItem = [];
+			this.cTaskNameItem = [];
+			//creation arrTasks
+			if(!parentTask){
+				if(this.taskItem.previousParentTask){
+					this.previousParentTask = this.project.getTaskById(this.taskItem.previousParentTask.id);
+					var lastChildTask = this.ganttChart.getLastChildTask(this.previousParentTask);
+					this.posY = parseInt(lastChildTask.cTaskItem[0].style.top)
+						+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+					this.previousParentTask.nextParentTask = this;
+				}else{
+					this.posY = parseInt(this.project.projectItem[0].style.top)
+						+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+				}
+			}
+			if(parentTask){
+				var task = this.project.getTaskById(this.taskItem.parentTask.id);
+				this.parentTask = task;
+			
+				if(this.taskItem.previousChildTask){
+					this.previousChildTask = this.project.getTaskById(this.taskItem.previousChildTask.id);
+					var lastChildTask = this.ganttChart.getLastChildTask(this.previousChildTask);
+					this.posY = domStyle.get(lastChildTask.cTaskItem[0], "top")
+						+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+					this.previousChildTask.nextChildTask = this;
+				}else{
+					this.posY = domStyle.get(task.cTaskItem[0], "top")
+						+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+				}
+				task.childTask.push(this);
+			}
+			if(previousTask){
+				var task = this.project.getTaskById(previousTask.id);
+				this.predTask = task;
+				task.childPredTask.push(this);
+			}
+			//creation task item
+			this.cTaskItem.push(this.createTaskItem());
+			containerTasks.appendChild(this.cTaskItem[0]);
+			if(this.ganttChart.panelNames){
+				this.cTaskNameItem.push(this.createTaskNameItem());
+				this.ganttChart.panelNames.firstChild.appendChild(this.cTaskNameItem[0]);
+			}
+			containerTasks.appendChild(this.createTaskDescItem());
+			//Create Connecting Lines
+			var arrConnectingLines = [];
+			if(previousTask){
+				arrConnectingLines = this.createConnectingLinesDS();
+			}
+			this.cTaskItem.push(arrConnectingLines);
+			if(this.ganttChart.panelNames){
+				//Create Connecting Lines
+				var arrConnectingLinesNames = [];
+				if(parentTask){
+					this.cTaskNameItem[0].style.left = domStyle.get(this.parentTask.cTaskNameItem[0], "left") + 15 + "px";
+					arrConnectingLinesNames = this.createConnectingLinesPN();
+				}
+				this.checkWidthTaskNameItem();
+				//Identifier
+				this.checkPosition();
+				var treeImg = null;
+				if(isCParentTask){
+					treeImg = this.createTreeImg();
+				}
+				this.cTaskNameItem.push(arrConnectingLinesNames);
+				this.cTaskNameItem.push(treeImg);
+			}
+			this.adjustPanelTime();
+			return this;
+		},
+		checkPosition: function(){
+			//task name position: check Task Identifier
+			if(!this.ganttChart.withTaskId){
+				return;
+			}
+			var pos = domGeometry.getMarginBox(this.cTaskNameItem[0], true);
+			if(this.taskIdentifier){
+				if(this.childTask && this.childTask.length > 0){
+					arrayUtil.forEach(this.childTask, function(cTask){
+						cTask.checkPosition();
+					}, this);
+				}
+				domStyle.set(this.taskIdentifier, {
+					"left": (pos.l + pos.w + 4) + "px",
+					"top": (pos.t - 1) + "px"
+				});
+			}else{
+				this.taskIdentifier = domConstruct.create("div", {
+					id: "TaskId_" + this.taskItem.id,
+					className: "ganttTaskIdentifier",
+					title: this.taskItem.id,
+					innerHTML: this.taskItem.id
+				}, this.cTaskNameItem[0].parentNode);
+				domStyle.set(this.taskIdentifier, {
+					left: (pos.l + pos.w + 4) + "px",
+					top: (pos.t - 1) + "px"
+				});
+			}
+		},
+		createTreeImg: function(){
+			var treeImg = domConstruct.create("div", {
+				id: this.taskItem.id,
+				className: "ganttImageTreeCollapse"
+			});
+			domAttr.set(treeImg, "tabIndex", 0);
+			arrayUtil.forEach(["click", "keydown"], function(e){
+				this.ganttChart._events.push(
+					on(treeImg, e, lang.hitch(this, function(evt){
+						if(e == "keydown" && evt.keyCode != keys.ENTER){ return; }
+						if(this.isExpanded){
+							domClass.remove(treeImg, "ganttImageTreeCollapse");
+							domClass.add(treeImg, "ganttImageTreeExpand");
+							this.isExpanded = false;
+							this.hideChildTasks(this);
+							this.shiftCurrentTasks(this, -this.hideTasksHeight);
+							this.ganttChart.checkPosition();
+						}else{
+							domClass.remove(treeImg, "ganttImageTreeExpand");
+							domClass.add(treeImg, "ganttImageTreeCollapse");
+							this.isExpanded = true;
+							this.shiftCurrentTasks(this, this.hideTasksHeight);
+							this.showChildTasks(this, true);
+							this.hideTasksHeight = 0;
+							this.ganttChart.checkPosition();
+						}
+					}))
+				);
+			}, this);
+			this.ganttChart.panelNames.firstChild.appendChild(treeImg);
+			domClass.add(treeImg, "ganttTaskTreeImage");
+			domStyle.set(treeImg, {
+				left: (domStyle.get(this.cTaskNameItem[0], "left") - 12) + "px",
+				top: (domStyle.get(this.cTaskNameItem[0], "top") + 3) + "px"
+			});
+			return treeImg;
+		},
+		setPreviousTask: function(previousTaskId){
+			if(previousTaskId == ""){
+				this.clearPredTask();
+			}else{
+				var task = this.taskItem;
+				if(task.id == previousTaskId){
+					return false;
+				}
+				var predTaskObj = this.project.getTaskById(previousTaskId);
+				if(!predTaskObj){
+					return false;
+				}
+				var predTask = predTaskObj.taskItem;
+				var a1 = predTask.parentTask == null, a2 = task.parentTask == null;
+				if(a1 && !a2 || !a1 && a2 || !a1 && !a2 && (predTask.parentTask.id != task.parentTask.id)){
+					return false;
+				}
+				//check time
+				var startTime = task.startTime.getTime(),
+					pest = predTask.startTime.getTime(),
+					pdur = predTask.duration * 24 * 60 * 60 * 1000 / predTaskObj.ganttChart.hsPerDay;
+				if((pest+pdur) > startTime){
+					return false;
+				}
+				// remove current connection
+				this.clearPredTask();
+				if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
+					this.ganttChart.correctPosPreviousTask(predTask, task, this);
+				}
+				task.previousTaskId = previousTaskId;
+				task.previousTask = predTask;
+				this.predTask = predTaskObj;
+				predTaskObj.childPredTask.push(this);
+				this.cTaskItem[1] = this.createConnectingLinesDS();
+			}
+			return true;
+		},
+		clearPredTask: function(){
+			if(this.predTask){
+				var ch = this.predTask.childPredTask;
+				for(var i = 0; i < ch.length; i++){
+					if(ch[i] == this){
+						ch.splice(i, 1);
+						break;
+					}
+				}
+				for(var i = 0; i < this.cTaskItem[1].length; i++){
+					this.cTaskItem[1][i].parentNode.removeChild(this.cTaskItem[1][i]);
+				}
+				this.cTaskItem[1] = [];
+				this.taskItem.previousTaskId = null;
+				this.taskItem.previousTask = null;
+				this.predTask = null;
+			}
+		},
+		setStartTime: function(startTime, shiftChild){
+			this.moveChild = shiftChild;
+			this.getMoveInfo();
+			var pos = this.ganttChart.getPosOnDate(startTime);
+			if((parseInt(this.cTaskItem[0].firstChild.firstChild.width) + pos > this.maxPosXMove) && (this.maxPosXMove != -1)){
+				this.maxPosXMove = -1;
+				this.minPosXMove = -1;
+				return false;
+			}
+			if(pos < this.minPosXMove){
+				this.maxPosXMove = -1;
+				this.minPosXMove = -1;
+				return false;
+			}
+			this.cTaskItem[0].style.left = pos;
+			var width = pos - this.posX;
+			this.moveCurrentTaskItem(width, shiftChild);
+			this.project.shiftProjectItem();
+			this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+			this.adjustPanelTime();
+			this.posX = 0;
+			this.maxPosXMove = -1;
+			this.minPosXMove = -1;
+			return true;
+		},
+		setDuration: function(duration){
+			this.getResizeInfo();
+			var width = this.ganttChart.getWidthOnDuration(duration);
+			if((width > this.maxWidthResize) && (this.maxWidthResize != -1)){
+				return false;
+			}else if(width < this.minWidthResize){
+				return false;
+			}else{
+				this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
+				this.resizeTaskItem(width);
+				this.endResizeItem();
+				this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+				return true;
+			}
+		},
+		setTaskOwner: function(owner){
+			owner = (owner == null || owner == undefined) ? "" : owner;
+			this.taskItem.taskOwner = owner;
+			this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+			return true;
+		},
+		setPercentCompleted: function(percentage){
+			percentage = parseInt(percentage);
+			if(isNaN(percentage) || percentage > 100 || percentage < 0){
+				return false;
+			}
+			var trow = this.cTaskItem[0].childNodes[0].firstChild.rows[0],
+				rc0 = trow.cells[0], rc1 = trow.cells[1];
+			if((percentage != 0) && (percentage != 100)){
+				if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
+					rc0.width = percentage + "%";
+					rc1.width = 100 - percentage + "%";
+				}else if((this.taskItem.percentage == 0) || (this.taskItem.percentage == 100)){
+					rc0.parentNode.removeChild(rc0);
+					var cellTblTask = domConstruct.create("td", {
+						height: this.ganttChart.heightTaskItem + "px",
+						width: percentage + "%"
+					}, trow);
+					cellTblTask.style.lineHeight = "1px";
+					var imageProgressFill = domConstruct.create("div", {
+						className: "ganttImageTaskProgressFilled"
+					}, cellTblTask);
+					domStyle.set(imageProgressFill, {
+						width: (percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+						height: this.ganttChart.heightTaskItem + "px"
+					});
+				
+					cellTblTask = domConstruct.create("td", {
+						height: this.ganttChart.heightTaskItem + "px",
+						width: (100 - percentage) + "%"
+					}, trow);
+					cellTblTask.style.lineHeight = "1px";
+					imageProgressFill = domConstruct.create("div", {
+						className: "ganttImageTaskProgressBg"
+					}, cellTblTask);
+					domStyle.set(imageProgressFill, {
+						width: ((100 - percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+						height: this.ganttChart.heightTaskItem + "px"
+					});
+				}
+			}else if(percentage == 0){
+				if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
+					rc0.parentNode.removeChild(rc0);
+					rc1.width = 100 + "%";
+				}else{
+					domClass.remove(rc0.firstChild, "ganttImageTaskProgressFilled");
+					domClass.add(rc0.firstChild, "ganttImageTaskProgressBg");
+				}
+			}else if(percentage == 100){
+				if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
+					rc1.parentNode.removeChild(rc1);
+					rc0.width = 100 + "%";
+				}else{
+					domClass.remove(rc0.firstChild, "ganttImageTaskProgressBg");
+					domClass.add(rc0.firstChild, "ganttImageTaskProgressFilled");
+				}
+			}
+			this.taskItem.percentage = percentage;
+			this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
+			this.resizeTaskItem(this.taskItemWidth);
+			this.endResizeItem();
+			this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+			return true;
+		},
+		setName: function(name){
+			if(name){
+				this.taskItem.name = name;
+				this.cTaskNameItem[0].innerHTML = name;
+				this.cTaskNameItem[0].title = name;
+				this.checkWidthTaskNameItem();
+				this.checkPosition();
+				this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+				this.adjustPanelTime();
+			}
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/gantt/GanttTaskItem.js b/dojox/gantt/GanttTaskItem.js
index 2bdac85..fa27750 100644
--- a/dojox/gantt/GanttTaskItem.js
+++ b/dojox/gantt/GanttTaskItem.js
@@ -1,1358 +1,37 @@
-dojo.provide("dojox.gantt.GanttTaskItem");
-
-dojo.require("dojo.date.locale");
-dojo.require("dijit.focus");		// dijit.focus()
-
-dojo.declare("dojox.gantt.GanttTaskControl", null, {
-	constructor: function(taskInfo, project, chart){
-		this.ganttChart = chart;
-		this.project = project;
-		this.taskItem = taskInfo;
-		//control variables
-		this.checkMove = false;
-		this.checkResize = false;
-		this.moveChild = false;
-		this.maxPosXMove = -1;
-		this.minPosXMove = -1;
-		this.maxWidthResize = -1;
-		this.minWidthResize = -1;
-		this.posX = 0;
-		this.posY = 0;
-		this.mouseX = 0;
-		this.taskItemWidth = 0;
-		this.isHide = false;
-		this.hideTasksHeight = 0;
-		this.isExpanded = true;
-		this.descrTask = null;
-		this.cTaskItem = null;
-		this.cTaskNameItem = null;
-		this.parentTask = null;
-		this.predTask = null;
-		this.childTask = [];
-		this.childPredTask = [];
-		this.nextChildTask = null;
-		this.previousChildTask = null;
-		this.nextParentTask = null;
-		this.previousParentTask = null;
-	},
-	createConnectingLinesPN: function(){
-		var arrConnectingLinesNames = [];
-		var lineVerticalLeft = dojo.create("div", {
-			innerHTML: " ",
-			className: "ganttTaskLineVerticalLeft"
-		}, this.ganttChart.panelNames.firstChild);
-		var cTaskName = this.cTaskNameItem[0], pcTaskName = this.parentTask.cTaskNameItem[0];
-		dojo.style(lineVerticalLeft, {
-			height: (cTaskName.offsetTop - pcTaskName.offsetTop) + "px",
-			top: (pcTaskName.offsetTop + 5) + "px",
-			left: (pcTaskName.offsetLeft - 9) + "px"
-		});
-		var LineHorizontalLeft = dojo.create("div", {
-			noShade: true,
-			color: "#000000",
-			className: "ganttTaskLineHorizontalLeft"
-		}, this.ganttChart.panelNames.firstChild);
-		dojo.style(LineHorizontalLeft, {
-			left: (pcTaskName.offsetLeft - 9) + "px",
-			top: (cTaskName.offsetTop + 5) + "px",
-			height: "1px",
-			width: (cTaskName.offsetLeft - pcTaskName.offsetLeft + 4) + "px"
-		});
-		arrConnectingLinesNames.push(lineVerticalLeft);
-		arrConnectingLinesNames.push(LineHorizontalLeft);
-		return arrConnectingLinesNames;
-	},
-	createConnectingLinesDS: function(){
-		var contentData = this.ganttChart.contentData.firstChild;
-		var arrLines = [];
-		var arrowImg = new Image();
-		var arrowImg = dojo.create("div", {
-			className: "ganttImageArrow"
-		});
-		//vertical line
-		var lineVerticalRight = document.createElement("div");
-		//horizontal line
-		var lineHorizontal = document.createElement("div");
-		var posXPreviousTask = dojo.style(this.predTask.cTaskItem[0], "left");
-		var posYPreviousTask = dojo.style(this.predTask.cTaskItem[0], "top");
-		var posXChildTask = dojo.style(this.cTaskItem[0], "left");
-		var posYChildTask = this.posY + 2;
-		//width task item
-		var widthChildTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
-		var widthPreviousTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
-		if(posYPreviousTask < posYChildTask){
-			dojo.addClass(lineVerticalRight, "ganttTaskLineVerticalRight");
-			dojo.style(lineVerticalRight, {
-				height: (posYChildTask - this.ganttChart.heightTaskItem / 2 - posYPreviousTask - 3) + "px",
-				width: "1px",
-				left: (posXPreviousTask + widthPreviousTask - 20) + "px",
-				top: (posYPreviousTask + this.ganttChart.heightTaskItem) + "px"
-			});
-			dojo.addClass(lineHorizontal, "ganttTaskLineHorizontal");
-			dojo.style(lineHorizontal, {
-				width: (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
-				left: (posXPreviousTask + widthPreviousTask - 20) + "px",
-				top: (posYChildTask + 2) + "px"
-			});
-			dojo.addClass(arrowImg, "ganttTaskArrowImg");
-			dojo.style(arrowImg, {
-				left: (posXChildTask - 7) + "px",
-				top: (posYChildTask - 1) + "px"
-			});
-		}else{
-			dojo.addClass(lineVerticalRight, "ganttTaskLineVerticalRightPlus");
-			dojo.style(lineVerticalRight, {
-				height: (posYPreviousTask + 2 - posYChildTask) + "px",
-				width: "1px",
-				left: (posXPreviousTask + widthPreviousTask - 20) + "px",
-				top: (posYChildTask + 2) + "px"
-			});
-			dojo.addClass(lineHorizontal, "ganttTaskLineHorizontalPlus");
-			dojo.style(lineHorizontal, {
-				width: (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
-				left: (posXPreviousTask + widthPreviousTask - 20) + "px",
-				top: (posYChildTask + 2) + "px"
-			});
-			dojo.addClass(arrowImg, "ganttTaskArrowImgPlus");
-			dojo.style(arrowImg, {
-				left: (posXChildTask - 7) + "px",
-				top: (posYChildTask - 1) + "px"
-			});
-		}
-		contentData.appendChild(lineVerticalRight);
-		contentData.appendChild(lineHorizontal);
-		contentData.appendChild(arrowImg);
-		arrLines.push(lineVerticalRight);
-		arrLines.push(arrowImg);
-		arrLines.push(lineHorizontal);
-		return arrLines;
-	},
-	showChildTasks: function(task, isOpen){
-		if(isOpen){
-			for(var i = 0; i < task.childTask.length; i++){
-				var cTask = task.childTask[i],
-					cTaskItem0 = cTask.cTaskItem[0], cTaskName0 = cTask.cTaskNameItem[0],
-					cTaskItem1 = cTask.cTaskItem[1], cTaskName1 = cTask.cTaskNameItem[1],
-					cTaskItem2 = cTask.cTaskItem[2], cTaskName2 = cTask.cTaskNameItem[2];
-				if(cTaskItem0.style.display == "none"){
-					cTaskItem0.style.display = "inline";
-					cTaskName0.style.display = "inline";
-					cTask.showDescTask();
-					task.isHide = false;
-					if(cTaskName2){
-						cTaskName2.style.display = "inline";
-						isOpen = cTask.isExpanded;
-					}
-					for(var k = 0; k < cTaskItem1.length; k++){
-						cTaskItem1[k].style.display = "inline";
-					}
-					for(var k = 0; k < cTaskName1.length; k++){
-						cTaskName1[k].style.display = "inline";
-					}
-					(cTask.taskIdentifier) && (cTask.taskIdentifier.style.display = "inline");
-					this.hideTasksHeight += this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
-					if(cTask.childTask.length > 0){
-						this.showChildTasks(cTask, isOpen);
-					}
-				}
-			}
-		}
-	},
-	hideChildTasks: function(task){
-		for(var i = 0; i < task.childTask.length; i++){
-			var cTask = task.childTask[i],
-				cTaskItem0 = cTask.cTaskItem[0], cTaskName0 = cTask.cTaskNameItem[0],
-				cTaskItem1 = cTask.cTaskItem[1], cTaskName1 = cTask.cTaskNameItem[1],
-				cTaskItem2 = cTask.cTaskItem[2], cTaskName2 = cTask.cTaskNameItem[2];
-			if(cTaskItem0.style.display != "none"){
-				cTaskItem0.style.display = "none";
-				cTaskName0.style.display = "none";
-				cTask.hideDescTask();
-				task.isHide = true;
-				if(cTaskName2){
-					cTaskName2.style.display = "none";
-				}
-				for(var k = 0; k < cTaskItem1.length; k++){
-					cTaskItem1[k].style.display = "none";
-				}
-				for(var k = 0; k < cTaskName1.length; k++){
-					cTaskName1[k].style.display = "none";
-				}
-				(cTask.taskIdentifier) && (cTask.taskIdentifier.style.display = "none");
-				this.hideTasksHeight += (this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra);
-				if(cTask.childTask.length > 0){
-					this.hideChildTasks(cTask);
-				}
-			}
-		}
-	},
-	shiftCurrentTasks: function(task, height){
-		this.shiftNextTask(this, height);
-		task.project.shiftNextProject(task.project, height);
-	},
-	shiftTask: function(task, height){
-		task.posY = task.posY + height;
-		var taskItem0 = task.cTaskItem[0], taskName0 = task.cTaskNameItem[0],
-			taskItem1 = task.cTaskItem[1], taskName1 = task.cTaskNameItem[1],
-			taskItem2 = task.cTaskItem[2], taskName2 = task.cTaskNameItem[2];
-		taskName0.style.top = parseInt(taskName0.style.top) + height + "px";
-		if(taskName2){
-			taskName2.style.top = parseInt(taskName2.style.top) + height + "px";
-		}
-		if(task.parentTask){
-			if(parseInt(this.cTaskNameItem[0].style.top) > parseInt(task.parentTask.cTaskNameItem[0].style.top) &&
-			(taskName1[0].style.display != "none")){
-				taskName1[0].style.height = parseInt(taskName1[0].style.height) + height + "px";
-			}else{
-				taskName1[0].style.top = parseInt(taskName1[0].style.top) + height + "px";
-			}
-			taskName1[1].style.top = parseInt(taskName1[1].style.top) + height + "px";
-		}
-		taskItem0.style.top = parseInt(taskItem0.style.top) + height + "px";
-		task.descrTask.style.top = parseInt(task.descrTask.style.top) + height + "px";
-		if(task.predTask){
-			if(((parseInt(this.cTaskItem[0].style.top) > parseInt(task.predTask.cTaskItem[0].style.top)) ||
-			(this.cTaskItem[0].id == task.predTask.taskItem.id)) &&
-			taskItem1[0].style.display != "none"){
-				taskItem1[0].style.height = parseInt(taskItem1[0].style.height) + height + "px";
-			}else{
-				taskItem1[0].style.top = parseInt(taskItem1[0].style.top) + height + "px";
-			}
-			taskItem1[1].style.top = parseInt(taskItem1[1].style.top) + height + "px";
-			taskItem1[2].style.top = parseInt(taskItem1[2].style.top) + height + "px";
-		}
-	},
-	shiftNextTask: function(task, height){
-		if(task.nextChildTask){
-			this.shiftTask(task.nextChildTask, height);
-			this.shiftChildTask(task.nextChildTask, height);
-			this.shiftNextTask(task.nextChildTask, height);
-		}else if(task.parentTask){
-			this.shiftNextTask(task.parentTask, height);
-		}else if(task.nextParentTask){
-			this.shiftTask(task.nextParentTask, height);
-			this.shiftChildTask(task.nextParentTask, height);
-			this.shiftNextTask(task.nextParentTask, height);
-		}
-	},
-	shiftChildTask: function(task, height){
-		dojo.forEach(task.childTask, function(cTask){
-			this.shiftTask(cTask, height);
-			if(cTask.childTask.length > 0){
-				this.shiftChildTask(cTask, height);
-			}
-		}, this);
-	},
-	endMove: function(){
-		var cTask0 = this.cTaskItem[0];
-		var width = dojo.style(cTask0, "left") - this.posX;
-		var startTime = this.getDateOnPosition(dojo.style(cTask0, "left"));
-		startTime = this.checkPos(startTime);
-		if(this.checkMove){
-			width = this.ganttChart.getPosOnDate(startTime) - this.posX;
-			this.moveCurrentTaskItem(width, this.moveChild);
-			this.project.shiftProjectItem();
-		}
-		this.checkMove = false;
-		this.posX = 0;
-		this.maxPosXMove = -1;
-		this.minPosXMove = -1;
-		cTask0.childNodes[1].firstChild.rows[0].cells[0].innerHTML = "";
-		this.adjustPanelTime();
-		if(this.ganttChart.resource){
-			this.ganttChart.resource.refresh();
-		}
-	},
-	checkPos: function(startTime){
-		var cTask0 = this.cTaskItem[0];
-		var h = startTime.getHours();
-		if(h >= 12){
-			startTime.setDate(startTime.getDate() + 1);
-			startTime.setHours(0);
-			if((parseInt(cTask0.firstChild.firstChild.width) + this.ganttChart.getPosOnDate(startTime) > this.maxPosXMove) && (this.maxPosXMove != -1)){
-				startTime.setDate(startTime.getDate() - 1);
-				startTime.setHours(0);
-			}
-		}else if((h < 12) && (h != 0)){
-			startTime.setHours(0);
-			if((this.ganttChart.getPosOnDate(startTime) < this.minPosXMove)){
-				startTime.setDate(startTime.getDate() + 1);
-			}
-		}
-		cTask0.style.left = this.ganttChart.getPosOnDate(startTime) + "px";
-		return startTime;
-	},
-	getMaxPosPredChildTaskItem: function(){
-		var posPredChildTaskItem = 0;
-		var nextPosPredChildTaskItem = 0;
-		for(var i = 0; i < this.childPredTask.length; i++){
-			nextPosPredChildTaskItem = this.getMaxPosPredChildTaskItemInTree(this.childPredTask[i]);
-			if(nextPosPredChildTaskItem > posPredChildTaskItem){
-				posPredChildTaskItem = nextPosPredChildTaskItem;
-			}
-		}
-		return posPredChildTaskItem;
-	},
-	getMaxPosPredChildTaskItemInTree: function(task){
-		var cTask0 = task.cTaskItem[0];
-		var currentPos = parseInt(cTask0.firstChild.firstChild.width) + dojo.style(cTask0, "left");
-		var posPredChildTaskItem = 0;
-		var nextPosPredChildTaskItem = 0;
-		dojo.forEach(task.childPredTask, function(cpTask){
-			nextPosPredChildTaskItem = this.getMaxPosPredChildTaskItemInTree(cpTask);
-			if(nextPosPredChildTaskItem > posPredChildTaskItem){
-				posPredChildTaskItem = nextPosPredChildTaskItem;
-			}
-		}, this);
-		return posPredChildTaskItem > currentPos ? posPredChildTaskItem : currentPos;
-	},
-	moveCurrentTaskItem: function(width, moveChild){
-		var taskItem = this.cTaskItem[0];
-		this.taskItem.startTime = new Date(this.ganttChart.startDate);
-		this.taskItem.startTime.setHours(this.taskItem.startTime.getHours() + (parseInt(taskItem.style.left) / this.ganttChart.pixelsPerHour));
-		this.showDescTask();
-		var cTask1 = this.cTaskItem[1];
-		if(cTask1.length > 0){
-			cTask1[2].style.width = parseInt(cTask1[2].style.width) + width + "px";
-			cTask1[1].style.left = parseInt(cTask1[1].style.left) + width + "px";
-		}
-		dojo.forEach(this.childTask, function(cTask){
-			if(!cTask.predTask){
-				this.moveChildTaskItems(cTask, width, moveChild);
-			}
-		}, this);
-		dojo.forEach(this.childPredTask, function(cpTask){
-			this.moveChildTaskItems(cpTask, width, moveChild);
-		}, this);
-	},
-	moveChildTaskItems: function(task, width, moveChild){
-		var taskItem = task.cTaskItem[0];
-		if(moveChild){
-			taskItem.style.left = parseInt(taskItem.style.left) + width + "px";
-			task.adjustPanelTime();
-			task.taskItem.startTime = new Date(this.ganttChart.startDate);
-			task.taskItem.startTime.setHours(task.taskItem.startTime.getHours() + (parseInt(taskItem.style.left) / this.ganttChart.pixelsPerHour));
-			var ctItem = task.cTaskItem[1];
-			dojo.forEach(ctItem, function(item){
-				item.style.left = parseInt(item.style.left) + width + "px";
-			}, this);
-			dojo.forEach(task.childTask, function(cTask){
-				if(!cTask.predTask){
-					this.moveChildTaskItems(cTask, width, moveChild);
-				}
-			}, this);
-			dojo.forEach(task.childPredTask, function(cpTask){
-				this.moveChildTaskItems(cpTask, width, moveChild);
-			}, this);
-		}else{
-			var ctItem = task.cTaskItem[1];
-			if(ctItem.length > 0){
-				var item0 = ctItem[0], item2 = ctItem[2];
-				item2.style.left = parseInt(item2.style.left) + width + "px";
-				item2.style.width = parseInt(item2.style.width) - width + "px";
-				item0.style.left = parseInt(item0.style.left) + width + "px";
-			}
-		}
-		task.moveDescTask();
-	},
-	adjustPanelTime: function(){
-		var taskItem = this.cTaskItem[0];
-		var width = parseInt(taskItem.style.left) + parseInt(taskItem.firstChild.firstChild.width) + this.ganttChart.panelTimeExpandDelta;
-		width += this.descrTask.offsetWidth;
-		this.ganttChart.adjustPanelTime(width);
-	},
-	getDateOnPosition: function(position){
-		var date = new Date(this.ganttChart.startDate);
-		date.setHours(date.getHours() + (position / this.ganttChart.pixelsPerHour));
-		return date;
-	},
-	moveItem: function(event){
-		var pageX = event.screenX;
-		var posTaskItem = (this.posX + (pageX - this.mouseX));
-		var widthTaskItem = parseInt(this.cTaskItem[0].childNodes[0].firstChild.width);
-		var posTaskItemR = posTaskItem + widthTaskItem;
-		if(this.checkMove){
-			if(((this.minPosXMove <= posTaskItem)) &&
-			((posTaskItemR <= this.maxPosXMove) || (this.maxPosXMove == -1))){
-				this.moveTaskItem(posTaskItem);
-			}
-		}
-	},
-	moveTaskItem: function(posX){
-		var cTask = this.cTaskItem[0];
-		cTask.style.left = posX + "px";
-		cTask.childNodes[1].firstChild.rows[0].cells[0].innerHTML = this.getDateOnPosition(posX).getDate() + '.' + (this.getDateOnPosition(posX).getMonth() + 1) + '.' + this.getDateOnPosition(posX).getUTCFullYear();
-	},
-	resizeItem: function(event){
-		if(this.checkResize){
-			var taskItem = this.cTaskItem[0];
-			var mouseX = event.screenX;
-			var width = (mouseX - this.mouseX);
-			var widthTaskItem = this.taskItemWidth + (mouseX - this.mouseX);
-			if(widthTaskItem >= this.taskItemWidth){
-				if((widthTaskItem <= this.maxWidthResize) || (this.maxWidthResize == -1)){
-					this.resizeTaskItem(widthTaskItem);
-				}else if((this.maxWidthResize != -1) && (widthTaskItem > this.maxWidthResize)){
-					this.resizeTaskItem(this.maxWidthResize);
-				}
-			}else if(widthTaskItem <= this.taskItemWidth){
-				if(widthTaskItem >= this.minWidthResize){
-					this.resizeTaskItem(widthTaskItem);
-				}else if(widthTaskItem < this.minWidthResize){
-					this.resizeTaskItem(this.minWidthResize);
-				}
-			}
-		}
-	},
-	resizeTaskItem: function(width){
-		var taskItem = this.cTaskItem[0];
-		var countHours = Math.round(width / this.ganttChart.pixelsPerWorkHour);
-		var trow = taskItem.childNodes[0].firstChild.rows[0],
-			rc0 = trow.cells[0], rc1 = trow.cells[1];
-		rc0 && (rc0.firstChild.style.width = parseInt(rc0.width) * width / 100 + "px");
-		rc1 && (rc1.firstChild.style.width = parseInt(rc1.width) * width / 100 + "px");
-		taskItem.childNodes[0].firstChild.width = width + "px";
-		taskItem.childNodes[1].firstChild.width = width + "px";
-		//resize info
-		this.cTaskItem[0].childNodes[1].firstChild.rows[0].cells[0].innerHTML = countHours;
-		var tcNode2 = taskItem.childNodes[2];
-		tcNode2.childNodes[0].style.width = width + "px";
-		tcNode2.childNodes[1].style.left = width - 10 + "px";
-	},
-	endResizeItem: function(){
-		var taskItem = this.cTaskItem[0];
-		if((this.taskItemWidth != parseInt(taskItem.childNodes[0].firstChild.width))){
-			var posXL = taskItem.offsetLeft;
-			var posXR = taskItem.offsetLeft + parseInt(taskItem.childNodes[0].firstChild.width);
-			var countHours = Math.round((posXR - posXL) / this.ganttChart.pixelsPerWorkHour);
-			this.taskItem.duration = countHours;
-			if(this.childPredTask.length > 0){
-				for(var j = 0; j < this.childPredTask.length; j++){
-					var cpctItem = this.childPredTask[j].cTaskItem[1],
-						item0 = cpctItem[0], item2 = cpctItem[2], tcNode0 = taskItem.childNodes[0];
-					item2.style.width = parseInt(item2.style.width) - (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
-					item2.style.left = parseInt(item2.style.left) + (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
-					item0.style.left = parseInt(item0.style.left) + (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
-				}
-			}
-		}
-		this.cTaskItem[0].childNodes[1].firstChild.rows[0].cells[0].innerHTML = "";
-		this.checkResize = false;
-		this.taskItemWidth = 0;
-		this.mouseX = 0;
-		this.showDescTask();
-		this.project.shiftProjectItem();
-		this.adjustPanelTime();
-		if(this.ganttChart.resource){
-			this.ganttChart.resource.refresh();
-		}
-	},
-	startMove: function(event){
-		this.moveChild = event.ctrlKey;
-		this.mouseX = event.screenX;
-		this.getMoveInfo();
-		this.checkMove = true;
-		this.hideDescTask();
-	},
-	showDescTask: function(){
-		var posX = (parseInt(this.cTaskItem[0].style.left) + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
-		this.descrTask.style.left = posX + "px";
-		this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
-		this.descrTask.style.visibility = 'visible';
-	},
-	hideDescTask: function(){
-		dojo.style(this.descrTask, "visibility", "hidden");
-	},
-	buildResourceInfo: function(resourceInfo){
-		if(this.childTask && this.childTask.length > 0){
-			for(var i = 0; i < this.childTask.length; i++){
-				var cTask = this.childTask[i];
-				cTask.buildResourceInfo(resourceInfo);
-			}
-		}
-		if(dojo.trim(this.taskItem.taskOwner).length > 0){
-			var owners = this.taskItem.taskOwner.split(";");
-			for(var i = 0; i < owners.length; i++){
-				var o = owners[i];
-				if(dojo.trim(o).length <= 0){
-					continue;
-				}
-				resourceInfo[o] ? (resourceInfo[o].push(this)) : (resourceInfo[o] = [this]);
-			}
-		}
-	},
-	objKeyToStr: function(obj, delm){
-		var returnStr = "";
-		delm = delm || " ";
-		if(obj){
-			for(var key in obj){
-				returnStr += delm + key;
-			}
-		}
-		return returnStr;
-	},
-	getTaskOwner: function(){
-		var tOwner = {};
-		if(dojo.trim(this.taskItem.taskOwner).length > 0){
-			var owners = this.taskItem.taskOwner.split(";");
-			for(var i = 0; i < owners.length; i++){
-				var o = owners[i];
-				tOwner[o] = 1;
-			}
-		}
-		dojo.forEach(this.childTask, function(ctask){
-			dojo.mixin(tOwner, ctask.getTaskOwner());
-		}, this);
-		return tOwner;
-	},
-	moveDescTask: function(){
-		var posX = (parseInt(this.cTaskItem[0].style.left) + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
-		this.descrTask.style.left = posX + "px";
-	},
-	getMoveInfo: function(){
-		this.posX = parseInt(this.cTaskItem[0].style.left);
-		var widthTaskItem = parseInt(this.cTaskItem[0].childNodes[0].firstChild.width);
-		var posParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].style.left);
-		var posPredTaskItem = !this.predTask ? 0 : parseInt(this.predTask.cTaskItem[0].style.left) + parseInt(this.predTask.cTaskItem[0].childNodes[0].firstChild.width);
-		var widthParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].childNodes[0].firstChild.width);
-		
-		var childPredPosX = 0;
-		var childParentPosX = 0;
-		var childParentPosXR = 0;
-		if(this.childPredTask.length > 0){
-			var posChildTaskItem = null;
-			dojo.forEach(this.childPredTask, function(cpTask){
-				if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem > parseInt(cpTask.cTaskItem[0].style.left)))){
-					posChildTaskItem = parseInt(cpTask.cTaskItem[0].style.left);
-				}
-			}, this);
-			childPredPosX = posChildTaskItem;
-		}
-		if(this.childTask.length > 0){
-			var posChildTaskItemR = null;
-			dojo.forEach(this.childTask, function(cTask){
-				if((!posChildTaskItemR) || ((posChildTaskItemR) && (posChildTaskItemR > (parseInt(cTask.cTaskItem[0].style.left))))){
-					posChildTaskItemR = parseInt(cTask.cTaskItem[0].style.left);
-				}
-			}, this);
-			childParentPosXR = posChildTaskItemR;
-			var posChildTaskItem = null;
-			dojo.forEach(this.childTask, function(cTask){
-				if((!posChildTaskItem) || ((posChildTaskItem)
-				&& (posChildTaskItem < (parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width))))){
-					posChildTaskItem = parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width);
-				}
-			}, this);
-			childParentPosX = posChildTaskItem;
-		}
-		if(!this.moveChild){
-			if(this.childPredTask.length > 0){
-				if(this.maxPosXMove < childPredPosX) this.maxPosXMove = childPredPosX;
-			}
-			if(this.childTask.length > 0){
-				if((this.childPredTask.length > 0) && (this.maxPosXMove - widthTaskItem) > childParentPosXR){
-					this.maxPosXMove = this.maxPosXMove - ((this.maxPosXMove - widthTaskItem) - childParentPosXR);
-				}
-				if(!(this.childPredTask.length > 0)){
-					this.maxPosXMove = childParentPosXR + widthTaskItem;
-				}
-				this.minPosXMove = (childParentPosX - widthTaskItem);
-			}
-			if(posParentTaskItem > 0){
-				if((!(this.childPredTask.length > 0)) && (this.childTask.length > 0)){
-					if(this.maxPosXMove > posParentTaskItem + widthParentTaskItem){
-						this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
-					}
-				}
-				if(this.minPosXMove <= posParentTaskItem){
-					this.minPosXMove = posParentTaskItem;
-				}
-				if((!(this.childTask.length > 0)) && (!(this.childPredTask.length > 0))){
-					this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
-				}else if((!(this.childTask.length > 0)) && (this.childPredTask.length > 0)){
-					if((posParentTaskItem + widthParentTaskItem) > posPredTaskItem){
-						this.maxPosXMove = childPredPosX;
-					}
-				}
-			}
-			if(posPredTaskItem > 0){
-				if(this.minPosXMove <= posPredTaskItem){
-					this.minPosXMove = posPredTaskItem;
-				}
-			}
-			if((posPredTaskItem == 0) && (posParentTaskItem == 0)){
-				if(this.minPosXMove <= this.ganttChart.initialPos){
-					this.minPosXMove = this.ganttChart.initialPos;
-				}
-			}
-		}else{
-			if((posParentTaskItem > 0) && (posPredTaskItem == 0)){
-				this.minPosXMove = posParentTaskItem;
-				this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
-			}else if((posParentTaskItem == 0) && (posPredTaskItem == 0)){
-				this.minPosXMove = this.ganttChart.initialPos;
-				this.maxPosXMove = -1;
-			}else if((posParentTaskItem > 0) && (posPredTaskItem > 0)){
-				this.minPosXMove = posPredTaskItem;
-				this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
-			}else if((posParentTaskItem == 0) && (posPredTaskItem > 0)){
-				this.minPosXMove = posPredTaskItem;
-				this.maxPosXMove = -1;
-			}
-			if((this.parentTask) && (this.childPredTask.length > 0)){
-				var posChildTaskItem = this.getMaxPosPredChildTaskItem(this);
-				var posParentTaskItem = parseInt(this.parentTask.cTaskItem[0].style.left) + parseInt(this.parentTask.cTaskItem[0].firstChild.firstChild.width);
-				this.maxPosXMove = this.posX + widthTaskItem + posParentTaskItem - posChildTaskItem;
-			}
-		}
-	},
-	startResize: function(event){
-		this.mouseX = event.screenX;
-		this.getResizeInfo();
-		this.hideDescTask();
-		this.checkResize = true;
-		this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
-	},
-	getResizeInfo: function(){
-		var cTask = this.cTaskItem[0];
-		var posParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].style.left);
-		var widthParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].childNodes[0].firstChild.width);
-		var posTaskItem = parseInt(cTask.style.left);
-		var childPredPosX = 0;
-		var childParentPosX = 0;
-		if(this.childPredTask.length > 0){
-			var posChildTaskItem = null;
-			dojo.forEach(this.childPredTask, function(cpTask){
-				if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem > parseInt(cpTask.cTaskItem[0].style.left)))){
-					posChildTaskItem = parseInt(cpTask.cTaskItem[0].style.left);
-				}
-			}, this);
-			childPredPosX = posChildTaskItem;
-		}
-		if(this.childTask.length > 0){
-			var posChildTaskItem = null;
-			dojo.forEach(this.childTask, function(cTask){
-				if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem < (parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width))))){
-					posChildTaskItem = parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width);
-				}
-			}, this);
-			childParentPosX = posChildTaskItem;
-		}
-		this.minWidthResize = this.ganttChart.pixelsPerDay;
-		if(this.childTask.length > 0){
-			this.minWidthResize = childParentPosX - posTaskItem;
-		}
-		if((this.childPredTask.length > 0) && (!this.parentTask)){
-			this.maxWidthResize = childPredPosX - posTaskItem;
-		}else if((this.childPredTask.length > 0) && (this.parentTask)){
-			var w1 = posParentTaskItem + widthParentTaskItem - posTaskItem;
-			var w2 = childPredPosX - posTaskItem;
-			this.maxWidthResize = Math.min(w1, w2);
-		}else if((this.childPredTask.length == 0) && (this.parentTask)){
-			this.maxWidthResize = posParentTaskItem + widthParentTaskItem - posTaskItem;
-		}
-	},
-	createTaskItem: function(){
-		this.posX = this.ganttChart.getPosOnDate(this.taskItem.startTime);
-		var itemControl = dojo.create("div", {
-			id: this.taskItem.id,
-			className: "ganttTaskItemControl"
-		});
-		dojo.style(itemControl, {
-			left: this.posX + "px",
-			top: this.posY + "px"
-		});
-		var divTaskItem = dojo.create("div", {className: "ganttTaskDivTaskItem"}, itemControl);
-		var tblTaskItem = dojo.create("table", {
-			cellPadding: "0",
-			cellSpacing: "0",
-			width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px",
-			className: "ganttTaskTblTaskItem"
-		}, divTaskItem);
-		var rowTblTask = tblTaskItem.insertRow(tblTaskItem.rows.length);
-		if(this.taskItem.percentage != 0){
-			var cellTblTask = dojo.create("td", {
-				height: this.ganttChart.heightTaskItem + "px",
-				width: this.taskItem.percentage + "%"
-			}, rowTblTask);
-			cellTblTask.style.lineHeight = "1px";
-			var imageProgress = dojo.create("div", {
-				className: "ganttImageTaskProgressFilled"
-			}, cellTblTask);
-			dojo.style(imageProgress, {
-				width: (this.taskItem.percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
-				height: this.ganttChart.heightTaskItem + "px"
-			});
-		}
-		if(this.taskItem.percentage != 100){
-			var cellTblTask = dojo.create("td", {
-				height: this.ganttChart.heightTaskItem + "px",
-				width: (100 - this.taskItem.percentage) + "%"
-			}, rowTblTask);
-			cellTblTask.style.lineHeight = "1px";
-			var imageProgressFill = dojo.create("div", {
-				className: "ganttImageTaskProgressBg"
-			}, cellTblTask);
-			dojo.style(imageProgressFill, {
-				width: ((100 - this.taskItem.percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
-				height: this.ganttChart.heightTaskItem + "px"
-			});
-		}
-		if(this.ganttChart.isContentEditable){
-			var divTaskInfo = dojo.create("div", {className: "ganttTaskDivTaskInfo"}, itemControl);
-			var tblTaskInfo = dojo.create("table", {
-				cellPadding: "0",
-				cellSpacing: "0",
-				height: this.ganttChart.heightTaskItem + "px",
-				width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
-			}, divTaskInfo);
-			var rowTaskInfo = tblTaskInfo.insertRow(0);
-			var cellTaskInfo = dojo.create("td", {
-				align: "center",
-				vAlign: "top",
-				height: this.ganttChart.heightTaskItem + "px",
-				className: "ganttMoveInfo"
-			}, rowTaskInfo);
-			var divTaskName = dojo.create("div", {className: "ganttTaskDivTaskName"}, itemControl);
-			var divMove = dojo.create("div", {}, divTaskName);
-			dojo.create("input", {
-				className: "ganttTaskDivMoveInput",
-				type: "text"
-			}, divMove);
-			dojo.isIE && dojo.style(divMove, {
-				background: "#000000",
-				filter: "alpha(opacity=0)"
-			});
-			dojo.style(divMove, {
-				height: this.ganttChart.heightTaskItem + "px",
-				width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
-			});
-			//Creation resize area
-			var divResize = dojo.create("div", {className: "ganttTaskDivResize"}, divTaskName);
-			dojo.create("input", {
-				className: "ganttTaskDivResizeInput",
-				type: "text"
-			}, divResize);
-			dojo.style(divResize, {
-				left: (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour - 10) + "px",
-				height: this.ganttChart.heightTaskItem + "px",
-				width: "10px"
-			});
-			this.ganttChart._events.push(
-				dojo.connect(divMove, "onmousedown", this, function(event){
-					//start move
-					this.moveMoveConn = dojo.connect(document, "onmousemove", this, function(e){
-						this.checkMove && this.moveItem(e);
-					});
-					this.moveUpConn = dojo.connect(document, "onmouseup", this, function(e){
-						if(this.checkMove){
-							this.endMove();
-							this.ganttChart.isMoving = false;
-							document.body.releaseCapture && document.body.releaseCapture();
-							dojo.disconnect(this.moveMoveConn);
-							dojo.disconnect(this.moveUpConn);
-						}
-					});
-					this.startMove(event);
-					this.ganttChart.isMoving = true;
-					document.body.setCapture && document.body.setCapture(false);
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(divMove, "onmouseover", this, function(event){
-					event.target && (event.target.style.cursor = "move");
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(divMove, "onmouseout", this, function(event){
-					event.target.style.cursor = "";
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(divResize, "onmousedown", this, function(event){
-					//start resize
-					this.resizeMoveConn = dojo.connect(document, "onmousemove", this, function(e){
-						this.checkResize && this.resizeItem(e);
-					});
-					this.resizeUpConn = dojo.connect(document, "onmouseup", this, function(e){
-						if(this.checkResize){
-							this.endResizeItem();
-							this.ganttChart.isResizing = false;
-							document.body.releaseCapture && document.body.releaseCapture();
-							dojo.disconnect(this.resizeMoveConn);
-							dojo.disconnect(this.resizeUpConn);
-						}
-					});
-					this.startResize(event);
-					this.ganttChart.isResizing = true;
-					document.body.setCapture && document.body.setCapture(false);
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(divResize, "onmouseover", this, function(event){
-					(!this.ganttChart.isMoving) && (!this.ganttChart.isResizing) && event.target && (event.target.style.cursor = "e-resize");
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(divResize, "onmouseout", this, function(event){
-					!this.checkResize && event.target && (event.target.style.cursor = "");
-				})
-			);
-		}
-		return itemControl;
-	},
-	createTaskNameItem: function(){
-		var divName = dojo.create("div", {
-			id: this.taskItem.id,
-			className: "ganttTaskTaskNameItem",
-			title: this.taskItem.name + ", id: " + this.taskItem.id + " ",
-			innerHTML: this.taskItem.name
-		});
-		dojo.style(divName, "top", this.posY + "px");
-		dojo.attr(divName, "tabIndex", 0);
-		if(this.ganttChart.isShowConMenu){
-			this.ganttChart._events.push(
-				dojo.connect(divName, "onmouseover", this, function(event){
-					dojo.addClass(divName, "ganttTaskTaskNameItemHover");
-					clearTimeout(this.ganttChart.menuTimer);
-					this.ganttChart.tabMenu.clear();
-					this.ganttChart.tabMenu.show(event.target, this);
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(divName, "onkeydown", this, function(event){
-					if(event.keyCode == dojo.keys.ENTER){
-						this.ganttChart.tabMenu.clear();
-						this.ganttChart.tabMenu.show(event.target, this);
-					}
-					if(this.ganttChart.tabMenu.isShow && (event.keyCode == dojo.keys.LEFT_ARROW || event.keyCode == dojo.keys.RIGHT_ARROW)){
-						dijit.focus(this.ganttChart.tabMenu.menuPanel.firstChild.rows[0].cells[0]);
-					}
-					if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
-						this.ganttChart.tabMenu.hide();
-					}
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(divName, "onmouseout", this, function(){
-					dojo.removeClass(divName, "ganttTaskTaskNameItemHover");
-					clearTimeout(this.ganttChart.menuTimer);
-					this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
-						this.ganttChart.tabMenu.hide();
-					}), 200);
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseover", this, function(){
-					clearTimeout(this.ganttChart.menuTimer);
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onkeydown", this, function(event){
-					if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
-						this.ganttChart.tabMenu.hide();
-					}
-				})
-			);
-			this.ganttChart._events.push(
-				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseout", this, function(){
-					clearTimeout(this.ganttChart.menuTimer);
-					this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
-						this.ganttChart.tabMenu.hide();
-					}), 200);
-				})
-			);
-		}
-		return divName;
-	},
-	createTaskDescItem: function(){
-		var posX = (this.posX + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
-		var divDesc = dojo.create("div", {
-			innerHTML: this.objKeyToStr(this.getTaskOwner()),
-			className: "ganttTaskDescTask"
-		});
-		dojo.style(divDesc, {
-			left: posX + "px",
-			top: this.posY + "px"
-		});
-		return this.descrTask = divDesc;
-	},
-	checkWidthTaskNameItem: function(){
-		if(this.cTaskNameItem[0].offsetWidth + this.cTaskNameItem[0].offsetLeft > this.ganttChart.maxWidthTaskNames){
-			var width = this.cTaskNameItem[0].offsetWidth + this.cTaskNameItem[0].offsetLeft - this.ganttChart.maxWidthTaskNames;
-			var countChar = Math.round(width / (this.cTaskNameItem[0].offsetWidth / this.cTaskNameItem[0].firstChild.length));
-			var tName = this.taskItem.name.substring(0, this.cTaskNameItem[0].firstChild.length - countChar - 3);
-			tName += "...";
-			this.cTaskNameItem[0].innerHTML = tName;
-		}
-	},
-	refreshTaskItem: function(itemControl){
-		this.posX = this.ganttChart.getPosOnDate(this.taskItem.startTime);
-		dojo.style(itemControl, {
-			"left": this.posX + "px"
-		});
-		var divTaskItem = itemControl.childNodes[0];
-		var tblTaskItem = divTaskItem.firstChild;
-		tblTaskItem.width = (!this.taskItem.duration ? 1 : this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) + "px";
-		var rowTblTask = tblTaskItem.rows[0];
-		if(this.taskItem.percentage != 0){
-			var cellTblTask = rowTblTask.firstChild;
-			cellTblTask.height = this.ganttChart.heightTaskItem + "px";
-			cellTblTask.width = this.taskItem.percentage + "%";
-			cellTblTask.style.lineHeight = "1px";
-			var imageProgress = cellTblTask.firstChild;
-			dojo.style(imageProgress, {
-				width: (!this.taskItem.duration ? 1 : (this.taskItem.percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
-				height: this.ganttChart.heightTaskItem + "px"
-			});
-		}
-		if(this.taskItem.percentage != 100){
-			var cellTblTask = rowTblTask.lastChild;
-			cellTblTask.height = this.ganttChart.heightTaskItem + "px";
-			cellTblTask.width = (100 - this.taskItem.percentage) + "%";
-			cellTblTask.style.lineHeight = "1px";
-			var imageProgressFill = cellTblTask.firstChild;
-			dojo.style(imageProgressFill, {
-				width: (!this.taskItem.duration ? 1 : ((100 - this.taskItem.percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
-				height: this.ganttChart.heightTaskItem + "px"
-			});
-		}
-		if(this.ganttChart.isContentEditable){
-			var divTaskInfo = itemControl.childNodes[1];
-			var tblTaskInfo = divTaskInfo.firstChild;
-			tblTaskInfo.height = this.ganttChart.heightTaskItem + "px";
-			tblTaskInfo.width = (!this.taskItem.duration ? 1 : (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour)) + "px";
-			var rowTaskInfo = tblTaskInfo.rows[0];
-			var cellTaskInfo = rowTaskInfo.firstChild;
-			cellTaskInfo.height = this.ganttChart.heightTaskItem + "px";
-			var divTaskName = itemControl.childNodes[2];
-			var divMove = divTaskName.firstChild;
-			divMove.style.height = this.ganttChart.heightTaskItem + "px";
-			divMove.style.width = (!this.taskItem.duration ? 1 : (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour)) + "px";
-			//Creation resize area
-			var divResize = divTaskName.lastChild;
-			dojo.style(divResize, {
-				"left": (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour - 10) + "px"
-			});
-			divResize.style.height = this.ganttChart.heightTaskItem + "px";
-			divResize.style.width = "10px";
-		}
-		return itemControl;
-	},
-	refreshTaskDesc: function(divDesc){
-		var posX = (this.posX + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
-		dojo.style(divDesc, {
-			"left": posX + "px"
-		});
-		return divDesc;
-	},
-	refreshConnectingLinesDS: function(arrLines){
-		var arrowImg = arrLines[1];
-		var lineVerticalRight = arrLines[0];
-		//horizontal line
-		var lineHorizontal = arrLines[2];
-		var posXPreviousTask = dojo.style(this.predTask.cTaskItem[0], "left");
-		var posYPreviousTask = dojo.style(this.predTask.cTaskItem[0], "top");
-		var posXChildTask = dojo.style(this.cTaskItem[0], "left");
-		var posYChildTask = this.posY + 2;
-		//width task item
-		var widthChildTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
-		var widthPreviousTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
-		if(posYPreviousTask < posYChildTask){
-			dojo.style(lineVerticalRight, {
-				"height": (posYChildTask - this.ganttChart.heightTaskItem / 2 - posYPreviousTask - 3) + "px",
-				"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
-			});
-			dojo.style(lineHorizontal, {
-				"width": (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
-				"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
-			});
-			
-			dojo.style(arrowImg, {
-				"left": (posXChildTask - 7) + "px"
-			});
-		}else{
-			dojo.style(lineVerticalRight, {
-				"height": (posYPreviousTask + 2 - posYChildTask) + "px",
-				"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
-			});
-			dojo.style(lineHorizontal, {
-				"width": (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
-				"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
-			});
-			dojo.style(arrowImg, {
-				"left": (posXChildTask - 7) + "px"
-			});
-		}
-		return arrLines;
-	},
-	postLoadData: function(){
-		//TODO e.g. task relative info...
-	},
-	refresh: function(){
-		if(this.childTask && this.childTask.length > 0){
-			dojo.forEach(this.childTask, function(cTask){
-				cTask.refresh();
-			}, this);
-		}
-		//creation task item
-		this.refreshTaskItem(this.cTaskItem[0]);
-		this.refreshTaskDesc(this.cTaskItem[0].nextSibling);
-		//Create Connecting Lines
-		var arrConnectingLines = [];
-		if(this.taskItem.previousTask && this.predTask){
-			this.refreshConnectingLinesDS(this.cTaskItem[1]);
-		}
-		return this;
-	},
-	create: function(){
-		var containerTasks = this.ganttChart.contentData.firstChild;
-		var containerNames = this.ganttChart.panelNames.firstChild;
-		var previousTask = this.taskItem.previousTask;
-		var parentTask = this.taskItem.parentTask;
-		var isCParentTask = (this.taskItem.cldTasks.length > 0) ? true : false;
-		this.cTaskItem = [];
-		this.cTaskNameItem = [];
-		//creation arrTasks
-		if(!parentTask){
-			if(this.taskItem.previousParentTask){
-				this.previousParentTask = this.project.getTaskById(this.taskItem.previousParentTask.id);
-				var lastChildTask = this.ganttChart.getLastChildTask(this.previousParentTask);
-				this.posY = parseInt(lastChildTask.cTaskItem[0].style.top)
-					+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
-				this.previousParentTask.nextParentTask = this;
-			}else{
-				this.posY = parseInt(this.project.projectItem[0].style.top)
-					+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
-			}
-		}
-		if(parentTask){
-			var task = this.project.getTaskById(this.taskItem.parentTask.id);
-			this.parentTask = task;
-			
-			if(this.taskItem.previousChildTask){
-				this.previousChildTask = this.project.getTaskById(this.taskItem.previousChildTask.id);
-				var lastChildTask = this.ganttChart.getLastChildTask(this.previousChildTask);
-				this.posY = dojo.style(lastChildTask.cTaskItem[0], "top")
-					+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
-				this.previousChildTask.nextChildTask = this;
-			}else{
-				this.posY = dojo.style(task.cTaskItem[0], "top")
-					+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
-			}
-			task.childTask.push(this);
-		}
-		if(previousTask){
-			var task = this.project.getTaskById(previousTask.id);
-			this.predTask = task;
-			task.childPredTask.push(this);
-		}
-		//creation task item
-		this.cTaskItem.push(this.createTaskItem());
-		containerTasks.appendChild(this.cTaskItem[0]);
-		if(this.ganttChart.panelNames){
-			this.cTaskNameItem.push(this.createTaskNameItem());
-			this.ganttChart.panelNames.firstChild.appendChild(this.cTaskNameItem[0]);
-		}
-		containerTasks.appendChild(this.createTaskDescItem());
-		//Create Connecting Lines
-		var arrConnectingLines = [];
-		if(previousTask){
-			arrConnectingLines = this.createConnectingLinesDS();
-		}
-		this.cTaskItem.push(arrConnectingLines);
-		if(this.ganttChart.panelNames){
-			//Create Connecting Lines
-			var arrConnectingLinesNames = [];
-			if(parentTask){
-				this.cTaskNameItem[0].style.left = dojo.style(this.parentTask.cTaskNameItem[0], "left") + 15 + "px";
-				arrConnectingLinesNames = this.createConnectingLinesPN();
-			}
-			this.checkWidthTaskNameItem();
-			//Identifier
-			this.checkPosition();
-			var treeImg = null;
-			if(isCParentTask){
-				treeImg = this.createTreeImg();
-			}
-			this.cTaskNameItem.push(arrConnectingLinesNames);
-			this.cTaskNameItem.push(treeImg);
-		}
-		this.adjustPanelTime();
-		return this;
-	},
-	checkPosition: function(){
-		//task name position: check Task Identifier
-		if(!this.ganttChart.withTaskId){
-			return;
-		}
-		var pos = dojo.coords(this.cTaskNameItem[0], true);
-		if(this.taskIdentifier){
-			if(this.childTask && this.childTask.length > 0){
-				dojo.forEach(this.childTask, function(cTask){
-					cTask.checkPosition();
-				}, this);
-			}
-			dojo.style(this.taskIdentifier, {
-				"left": (pos.l + pos.w + 4) + "px",
-				"top": (pos.t - 1) + "px"
-			});
-		}else{
-			this.taskIdentifier = dojo.create("div", {
-				id: "TaskId_" + this.taskItem.id,
-				className: "ganttTaskIdentifier",
-				title: this.taskItem.id,
-				innerHTML: this.taskItem.id
-			}, this.cTaskNameItem[0].parentNode);
-			dojo.style(this.taskIdentifier, {
-				left: (pos.l + pos.w + 4) + "px",
-				top: (pos.t - 1) + "px"
-			});
-		}
-	},
-	createTreeImg: function(){
-		var treeImg = dojo.create("div", {
-			id: this.taskItem.id,
-			className: "ganttImageTreeCollapse"
-		});
-		dojo.attr(treeImg, "tabIndex", 0);
-		dojo.forEach(["onclick", "onkeydown"], function(e){
-			this.ganttChart._events.push(
-				dojo.connect(treeImg, e, this, function(evt){
-					if(e == "onkeydown" && evt.keyCode != dojo.keys.ENTER){ return; }
-					if(this.isExpanded){
-						dojo.removeClass(treeImg, "ganttImageTreeCollapse");
-						dojo.addClass(treeImg, "ganttImageTreeExpand");
-						this.isExpanded = false;
-						this.hideChildTasks(this);
-						this.shiftCurrentTasks(this, -this.hideTasksHeight);
-						this.ganttChart.checkPosition();
-					}else{
-						dojo.removeClass(treeImg, "ganttImageTreeExpand");
-						dojo.addClass(treeImg, "ganttImageTreeCollapse");
-						this.isExpanded = true;
-						this.shiftCurrentTasks(this, this.hideTasksHeight);
-						this.showChildTasks(this, true);
-						this.hideTasksHeight = 0;
-						this.ganttChart.checkPosition();
-					}
-				})
-			);
-		}, this);
-		this.ganttChart.panelNames.firstChild.appendChild(treeImg);
-		dojo.addClass(treeImg, "ganttTaskTreeImage");
-		dojo.style(treeImg, {
-			left: (dojo.style(this.cTaskNameItem[0], "left") - 12) + "px",
-			top: (dojo.style(this.cTaskNameItem[0], "top") + 3) + "px"
-		});
-		return treeImg;
-	},
-	setPreviousTask: function(previousTaskId){
-		if(previousTaskId == ""){
-			this.clearPredTask();
-		}else{
-			var task = this.taskItem;
-			if(task.id == previousTaskId){
-				return false;
-			}
-			var predTaskObj = this.project.getTaskById(previousTaskId);
-			if(!predTaskObj){
-				return false;
-			}
-			var predTask = predTaskObj.taskItem;
-			var a1 = predTask.parentTask == null, a2 = task.parentTask == null;
-			if(a1 && !a2 || !a1 && a2 || !a1 && !a2 && (predTask.parentTask.id != task.parentTask.id)){
-				return false;
-			}
-			//check time
-			var startTime = task.startTime.getTime(),
-				pest = predTask.startTime.getTime(),
-				pdur = predTask.duration * 24 * 60 * 60 * 1000 / predTaskObj.ganttChart.hsPerDay;
-			if((pest+pdur) > startTime){
-				return false;
-			}
-			// remove current connection
-			this.clearPredTask();
-			if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
-				this.ganttChart.correctPosPreviousTask(predTask, task, this);
-			}
-			task.previousTaskId = previousTaskId;
-			task.previousTask = predTask;
-			this.predTask = predTaskObj;
-			predTaskObj.childPredTask.push(this);
-			this.cTaskItem[1] = this.createConnectingLinesDS();
-		}
-		return true;
-	},
-	clearPredTask: function(){
-		if(this.predTask){
-			var ch = this.predTask.childPredTask;
-			for(var i = 0; i < ch.length; i++){
-				if(ch[i] == this){
-					ch.splice(i, 1);
-					break;
-				}
-			}
-			for(var i = 0; i < this.cTaskItem[1].length; i++){
-				this.cTaskItem[1][i].parentNode.removeChild(this.cTaskItem[1][i]);
-			}
-			this.cTaskItem[1] = [];
-			this.taskItem.previousTaskId = null;
-			this.taskItem.previousTask = null;
-			this.predTask = null;
-		}
-	},
-	setStartTime: function(startTime, shiftChild){
-		this.moveChild = shiftChild;
-		this.getMoveInfo();
-		var pos = this.ganttChart.getPosOnDate(startTime);
-		if((parseInt(this.cTaskItem[0].firstChild.firstChild.width) + pos > this.maxPosXMove) && (this.maxPosXMove != -1)){
-			this.maxPosXMove = -1;
-			this.minPosXMove = -1;
-			return false;
-		}
-		if(pos < this.minPosXMove){
-			this.maxPosXMove = -1;
-			this.minPosXMove = -1;
-			return false;
-		}
-		this.cTaskItem[0].style.left = pos;
-		var width = pos - this.posX;
-		this.moveCurrentTaskItem(width, shiftChild);
-		this.project.shiftProjectItem();
-		this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
-		this.adjustPanelTime();
-		this.posX = 0;
-		this.maxPosXMove = -1;
-		this.minPosXMove = -1;
-		return true;
-	},
-	setDuration: function(duration){
-		this.getResizeInfo();
-		var width = this.ganttChart.getWidthOnDuration(duration);
-		if((width > this.maxWidthResize) && (this.maxWidthResize != -1)){
-			return false;
-		}else if(width < this.minWidthResize){
-			return false;
-		}else{
-			this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
-			this.resizeTaskItem(width);
-			this.endResizeItem();
-			this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
-			return true;
-		}
-	},
-	setTaskOwner: function(owner){
-		owner = (owner == null || owner == undefined) ? "" : owner;
-		this.taskItem.taskOwner = owner;
-		this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
-		return true;
-	},
-	setPercentCompleted: function(percentage){
-		percentage = parseInt(percentage);
-		if(isNaN(percentage) || percentage > 100 || percentage < 0){
-			return false;
-		}
-		var trow = this.cTaskItem[0].childNodes[0].firstChild.rows[0],
-			rc0 = trow.cells[0], rc1 = trow.cells[1];
-		if((percentage != 0) && (percentage != 100)){
-			if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
-				rc0.width = percentage + "%";
-				rc1.width = 100 - percentage + "%";
-			}else if((this.taskItem.percentage == 0) || (this.taskItem.percentage == 100)){
-				rc0.parentNode.removeChild(rc0);
-				var cellTblTask = dojo.create("td", {
-					height: this.ganttChart.heightTaskItem + "px",
-					width: percentage + "%"
-				}, trow);
-				cellTblTask.style.lineHeight = "1px";
-				var imageProgressFill = dojo.create("div", {
-					className: "ganttImageTaskProgressFilled"
-				}, cellTblTask);
-				dojo.style(imageProgressFill, {
-					width: (percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
-					height: this.ganttChart.heightTaskItem + "px"
-				});
-				
-				cellTblTask = dojo.create("td", {
-					height: this.ganttChart.heightTaskItem + "px",
-					width: (100 - percentage) + "%"
-				}, trow);
-				cellTblTask.style.lineHeight = "1px";
-				imageProgressFill = dojo.create("div", {
-					className: "ganttImageTaskProgressBg"
-				}, cellTblTask);
-				dojo.style(imageProgressFill, {
-					width: ((100 - percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
-					height: this.ganttChart.heightTaskItem + "px"
-				});
-			}
-		}else if(percentage == 0){
-			if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
-				rc0.parentNode.removeChild(rc0);
-				rc1.width = 100 + "%";
-			}else{
-				dojo.removeClass(rc0.firstChild, "ganttImageTaskProgressFilled");
-				dojo.addClass(rc0.firstChild, "ganttImageTaskProgressBg");
-			}
-		}else if(percentage == 100){
-			if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
-				rc1.parentNode.removeChild(rc1);
-				rc0.width = 100 + "%";
-			}else{
-				dojo.removeClass(rc0.firstChild, "ganttImageTaskProgressBg");
-				dojo.addClass(rc0.firstChild, "ganttImageTaskProgressFilled");
-			}
-		}
-		this.taskItem.percentage = percentage;
-		this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
-		this.resizeTaskItem(this.taskItemWidth);
-		this.endResizeItem();
-		this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
-		return true;
-	},
-	setName: function(name){
-		if(name){
-			this.taskItem.name = name;
-			this.cTaskNameItem[0].innerHTML = name;
-			this.cTaskNameItem[0].title = name;
-			this.checkWidthTaskNameItem();
-			this.checkPosition();
-			this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
-			this.adjustPanelTime();
-		}
-	}
-});
-
-dojo.declare("dojox.gantt.GanttTaskItem", null, {
-	constructor: function(configuration){
-		//id is required
-		this.id = configuration.id;
-		this.name = configuration.name || this.id;
-		this.startTime = configuration.startTime || new Date();
-		this.duration = configuration.duration || 8;
-		this.percentage = configuration.percentage || 0;
-		this.previousTaskId = configuration.previousTaskId || "";
-		this.taskOwner = configuration.taskOwner || "";
-		this.cldTasks = [];
-		this.cldPreTasks = [];
-		this.parentTask = null;
-		this.previousTask = null;
-		this.project = null;
-		this.nextChildTask = null;
-		this.previousChildTask = null;
-		this.nextParentTask = null;
-		this.previousParentTask = null;
-	},
-	addChildTask: function(task){
-		this.cldTasks.push(task);
-		task.parentTask = this;
-	},
-	setProject: function(project){
-		this.project = project;
-		for(var j = 0; j < this.cldTasks.length; j++){
-			this.cldTasks[j].setProject(project);
-		}
-	}
+define([
+	"./GanttTaskControl",
+    "dojo/_base/declare",
+	"dojo/domReady!"
+], function(GanttTaskControl, declare){
+	return declare("dojox.gantt.GanttTaskItem", [], {
+		constructor: function(configuration){
+			//id is required
+			this.id = configuration.id;
+			this.name = configuration.name || this.id;
+			this.startTime = configuration.startTime || new Date();
+			this.duration = configuration.duration || 8;
+			this.percentage = configuration.percentage || 0;
+			this.previousTaskId = configuration.previousTaskId || "";
+			this.taskOwner = configuration.taskOwner || "";
+			this.cldTasks = [];
+			this.cldPreTasks = [];
+			this.parentTask = null;
+			this.previousTask = null;
+			this.project = null;
+			this.nextChildTask = null;
+			this.previousChildTask = null;
+			this.nextParentTask = null;
+			this.previousParentTask = null;
+		},
+		addChildTask: function(task){
+			this.cldTasks.push(task);
+			task.parentTask = this;
+		},
+		setProject: function(project){
+			this.project = project;
+			for(var j = 0; j < this.cldTasks.length; j++){
+				this.cldTasks[j].setProject(project);
+			}
+		}
+	});
 });
-
diff --git a/dojox/gantt/README b/dojox/gantt/README
new file mode 100644
index 0000000..2d73528
--- /dev/null
+++ b/dojox/gantt/README
@@ -0,0 +1,45 @@
+-------------------------------------------------------------------------------
+dojox.gantt
+-------------------------------------------------------------------------------
+Version 0.100
+Release date: 12/23/2010
+-------------------------------------------------------------------------------
+Project state:
+alpha
+-------------------------------------------------------------------------------
+Credits
+Tom Trenka (ttrenka at dojotoolkit.org)
+Xiang Zhou (xiangxz at cn.ibm.com) - IBM, CCLA
+Adam Peller (peller at dojotoolkit.org)
+Dylan Schiemann (dylan at dojotoolkit.org)
+Bill Keese (bill at dojotoolkit.org)
+Peter Higgins (dante at dojotoolkit.org)
+
+-------------------------------------------------------------------------------
+Project description
+
+GanttChart(dojox.gantt.GanttChart) is an integrated widget for project and resource management use. It includes a set of features as follows.
+
+        Toolbar - Providing general time line control and save/load button.
+        Project Tree - Listing projects and their tasks.
+        Task Cascade View - A task view with dependency, that can be modified visually.
+        Resource View - A read-only view shows people resource occupation.
+
+
+-------------------------------------------------------------------------------
+Dependencies:
+
+Dojo Core, Dijit.
+-------------------------------------------------------------------------------
+Documentation
+
+[TODO]
+-------------------------------------------------------------------------------
+Installation instructions
+
+Grab the following from the Dojo SVN Repository:
+http://svn.dojotoolkit.org/src/dojox/trunk/gantt/*
+
+Install into the following directory structure:
+/dojox/gantt/
+-------------------------------------------------------------------------------
diff --git a/dojox/gantt/TabMenu.js b/dojox/gantt/TabMenu.js
index ad91843..3ba72e8 100644
--- a/dojox/gantt/TabMenu.js
+++ b/dojox/gantt/TabMenu.js
@@ -1,20 +1,30 @@
-dojo.provide("dojox.gantt.TabMenu");
-
-dojo.require("dijit.dijit");
-dojo.require("dijit.Menu");
-dojo.require("dijit.Dialog");
-dojo.require("dijit.form.NumberSpinner");
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.CheckBox");
-dojo.require("dijit.form.DateTextBox");
-dojo.require("dijit.form.TimeTextBox");
-dojo.require("dojo.date.locale");
-
-dojo.require("dijit.form.Form");
-dojo.require("dojo.parser");
-
-(function(){
-	dojo.declare("dojox.gantt.TabMenu", null, {
+define([
+	"./contextMenuTab",
+	"./GanttTaskControl",
+	"./GanttProjectControl",
+	"dijit/Dialog",
+	"dijit/form/Button",
+	"dijit/form/Form",
+	"dijit/registry",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+    "dojo/date/locale",
+	"dojo/request",
+	"dojo/on",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dojo/dom-attr",
+	"dojo/dom-geometry",
+	"dojo/keys",
+	"dojo/domReady!"
+], function(contextMenuTab, GanttTaskControl, GanttProjectControl,
+		Dialog, Button, Form,
+		registry, declare, arrayUtil, lang, locale, request, on,
+		dom, domClass, domConstruct, domStyle, domAttr, domGeometry, keys){
+	return declare("dojox.gantt.TabMenu", [], {
 		constructor: function(chart){
 			this.ganttChart = chart;
 			this.menuPanel = null;
@@ -103,88 +113,88 @@ dojo.require("dojo.parser");
 			projectTaskAdd.addAction("addTaskAction");
 		},
 		createMenuPanel: function(){
-			this.menuPanel = dojo.create("div", {
+			this.menuPanel = domConstruct.create("div", {
 				innerHTML: "<table></table>",
 				className: "ganttMenuPanel"
 			}, this.ganttChart.content);
-			dojo.addClass(this.menuPanel.firstChild, "ganttContextMenu");
+			domClass.add(this.menuPanel.firstChild, "ganttContextMenu");
 			this.menuPanel.firstChild.cellPadding = 0;
 			this.menuPanel.firstChild.cellSpacing = 0;
 		},
 		createTabPanel: function(){
-			this.tabPanelDlg = dijit.byId(this.tabPanelDlgId) ||
-				new dijit.Dialog({
+			this.tabPanelDlg = registry.byId(this.tabPanelDlgId) ||
+				new Dialog({
 					title: "Settings"
 				});
 			this.tabPanelDlgId = this.tabPanelDlg.id;
 			this.tabPanelDlg.closeButtonNode.style.display = "none";
 			var tabPanel = this.tabPanelDlg.containerNode;
-			this.paneContentArea = dojo.create("div", {className: "dijitDialogPaneContentArea"}, tabPanel);
-			this.paneActionBar = dojo.create("div", {className: "dijitDialogPaneActionBar"}, tabPanel);
+			this.paneContentArea = domConstruct.create("div", {className: "dijitDialogPaneContentArea"}, tabPanel);
+			this.paneActionBar = domConstruct.create("div", {className: "dijitDialogPaneActionBar"}, tabPanel);
 			this.paneContentArea.innerHTML = "<table cellpadding=0 cellspacing=0><tr><th></th></tr><tr><td></td></tr></table>";
 			var headerCell = this.paneContentArea.firstChild.rows[0].cells[0];
 			headerCell.colSpan = 2;
 			headerCell.innerHTML = "Description: ";
-			dojo.addClass(headerCell, "ganttDialogContentHeader");
+			domClass.add(headerCell, "ganttDialogContentHeader");
 			var contentCell = this.paneContentArea.firstChild.rows[1].cells[0];
 			contentCell.innerHTML = "<table></table>";
-			dojo.addClass(contentCell.firstChild, "ganttDialogContentCell");
+			domClass.add(contentCell.firstChild, "ganttDialogContentCell");
 			contentCell.align = "center";
-			this.ok = new dijit.form.Button({label: "OK"});
-			this.cancel = new dijit.form.Button({label: "Cancel"});
+			this.ok = new Button({label: "OK"});
+			this.cancel = new Button({label: "Cancel"});
 			this.paneActionBar.appendChild(this.ok.domNode);
 			this.paneActionBar.appendChild(this.cancel.domNode);
 		},
 		addItemMenuPanel: function(tab){
 			var row = this.menuPanel.firstChild.insertRow(this.menuPanel.firstChild.rows.length);
-			var cell = dojo.create("td", {
+			var cell = domConstruct.create("td", {
 				className: "ganttContextMenuItem",
 				innerHTML: tab.Description
 			});
-			dojo.attr(cell, "tabIndex", 0);
+			domAttr.set(cell, "tabIndex", 0);
 			this.ganttChart._events.push(
-				dojo.connect(cell, "onclick", this, function(){
+				on(cell, "click", lang.hitch(this, function(){
 					try{
 						this.hide();
 						tab.show();
 					}catch(e){
 						console.log("dialog open exception: " + e.message);
 					}
-				})
+				}))
 			);
 			this.ganttChart._events.push(
-				dojo.connect(cell, "onkeydown", this, function(e){
-					if(e.keyCode != dojo.keys.ENTER){return;}
+				on(cell, "keydown", lang.hitch(this, function(event){
+					if(event.keyCode != keys.ENTER){return;}
 					try{
 						this.hide();
 						tab.show();
 					}catch(e){
 						console.log("dialog open exception: " + e.message);
 					}
-				})
+				}))
 			);
 			this.ganttChart._events.push(
-				dojo.connect(cell, "onmouseover", this, function(){
-					dojo.addClass(cell, "ganttContextMenuItemHover");
-				})
+				on(cell, "mouseover", lang.hitch(this, function(){
+					domClass.add(cell, "ganttContextMenuItemHover");
+				}))
 			);
 			this.ganttChart._events.push(
-				dojo.connect(cell, "onmouseout", this, function(){
-					dojo.removeClass(cell, "ganttContextMenuItemHover");
-				})
+				on(cell, "mouseout", lang.hitch(this, function(){
+					domClass.remove(cell, "ganttContextMenuItemHover");
+				}))
 			);
 			row.appendChild(cell);
 		},
 		show: function(elem, object){
-			if(object.constructor == dojox.gantt.GanttTaskControl){
-				dojo.forEach(this.arrTabs, function(tab){
+			if(object.constructor == GanttTaskControl){
+				arrayUtil.forEach(this.arrTabs, function(tab){
 					if(tab.type == "t"){
 						tab.object = object;
 						this.addItemMenuPanel(tab);
 					}
 				}, this);
-			}else if(object.constructor == dojox.gantt.GanttProjectControl){
-				dojo.forEach(this.arrTabs, function(tab){
+			}else if(object.constructor == GanttProjectControl){
+				arrayUtil.forEach(this.arrTabs, function(tab){
 					if(tab.type == "p"){
 						tab.object = object;
 						this.addItemMenuPanel(tab);
@@ -192,20 +202,20 @@ dojo.require("dojo.parser");
 				}, this);
 			}
 			this.isShow = true;
-			dojo.style(this.menuPanel, {
+			domStyle.set(this.menuPanel, {
 				zIndex: 15,
 				visibility: "visible"
 			});
 			//make sure menu box inside gantt's bounding box
-			var menuBox = dojo.position(this.menuPanel, true),
-				bBox = dojo.position(this.ganttChart.content, true),
-				pos = dojo.coords(elem, true);
+			var menuBox = domGeometry.position(this.menuPanel, true),
+				bBox = domGeometry.position(this.ganttChart.content, true),
+				pos = domGeometry.position(elem, true);
 			if((pos.y + menuBox.h) > (bBox.y + bBox.h + 50)){
 				this.menuPanel.style.top = pos.y - menuBox.h + pos.h + "px";
 			}else{
 				this.menuPanel.style.top = pos.y + "px";
 			}
-			if(dojo._isBodyLtr()){
+			if(domGeometry.isBodyLtr()){
 				this.menuPanel.style.left = pos.x + pos.w + 5 + "px";
 			}else{
 				this.menuPanel.style.left = pos.x - menuBox.w - 5 + "px";
@@ -218,356 +228,14 @@ dojo.require("dojo.parser");
 		clear: function(){
 			this.menuPanel.removeChild(this.menuPanel.firstChild);
 			this.menuPanel.innerHTML = "<table></table>";
-			dojo.addClass(this.menuPanel.firstChild, "ganttContextMenu");
+			domClass.add(this.menuPanel.firstChild, "ganttContextMenu");
 			this.menuPanel.firstChild.cellPadding = 0;
 			this.menuPanel.firstChild.cellSpacing = 0;
 		},
 		createTab: function(id, desc, type, showOInfo, menu, withDefaultValue){
-			var tab = new dojox.gantt.contextMenuTab(id, desc, type, showOInfo, menu, withDefaultValue);
+			var tab = new contextMenuTab(id, desc, type, showOInfo, menu, withDefaultValue);
 			this.arrTabs.push(tab);
 			return tab;
 		}
-	});
-	
-	dojo.declare("dojox.gantt.contextMenuTab", null, {
-		constructor: function(id, description, type, showOInfo, tabMenu, withDefaultValue){
-			this.id = id;
-			this.arrItems = [];
-			this.TabItemContainer = null;
-			this.Description = description;
-			this.tabMenu = tabMenu;
-			this.type = type;
-			this.object = null;
-			this.showObjectInfo = showOInfo;
-			this.withDefaultValue = withDefaultValue;
-		},
-		preValueValidation: function(items){
-			for(var i = 0; i < items.length; i++){
-				var item = items[i];
-				//TODO add more validation for Id, Name, .....
-				if(item.required && !item.control.textbox.value){
-					return false;
-				}
-			}
-			return true;
-		},
-		encodeDate: function(date){
-			return date.getFullYear() + "." + (date.getMonth() + 1) + "." + date.getDate();
-		},
-		decodeDate: function(dateStr){
-			var arr = dateStr.split(".");
-			return (arr.length < 3) ? "" : (new Date(arr[0], parseInt(arr[1]) - 1, arr[2]));
-		},
-		renameTaskAction: function(){
-			var name = this.arrItems[0].control.textbox.value;
-			if(dojo.trim(name).length <= 0){
-				return;
-			}
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			this.object.setName(name);
-			this.hide();
-		},
-		deleteAction: function(){
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			this.object.project.deleteTask(this.object.taskItem.id);
-			this.hide();
-			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
-		},
-		durationUpdateAction: function(){
-			var d = this.arrItems[0].control.textbox.value;
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			if(this.object.setDuration(d)){
-				this.hide();
-			}else{
-				alert("Duration out of Range");
-				return;
-			}
-			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.refresh();
-		},
-		cpUpdateAction: function(){
-			var p = this.arrItems[0].control.textbox.value;
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			if(this.object.setPercentCompleted(p)){
-				this.hide();
-			}else{
-				alert("Complete Percentage out of Range");
-				return;
-			}
-		},
-		ownerUpdateAction: function(){
-			var to = this.arrItems[0].control.textbox.value;
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			if(this.object.setTaskOwner(to)){
-				this.hide();
-			}else{
-				alert("Task owner not Valid");
-				return;
-			}
-			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
-		},
-		ptUpdateAction: function(){
-			var p = this.arrItems[0].control.textbox.value;
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			if(this.object.setPreviousTask(p)){
-				this.hide();
-			}else{
-				alert("Please verify the Previous Task (" + p + ")  and adjust its Time Range");
-				return;
-			}
-		},
-		renameProjectAction: function(){
-			var name = this.arrItems[0].control.textbox.value;
-			if(dojo.trim(name).length <= 0){
-				return;
-			}
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			this.object.setName(name);
-			this.hide();
-		},
-		deleteProjectAction: function(){
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			this.object.ganttChart.deleteProject(this.object.project.id);
-			this.hide();
-			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
-		},
-		cpProjectAction: function(){
-			var p = this.arrItems[0].control.textbox.value;
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			if(this.object.setPercentCompleted(p)){
-				this.hide();
-			}else{
-				alert("Percentage not Acceptable");
-				return;
-			}
-		},
-		addTaskAction: function(){
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			var id = this.arrItems[0].control.textbox.value,
-				name = this.arrItems[1].control.textbox.value,
-				startTime = this.decodeDate(this.arrItems[2].control.textbox.value),
-				duration = this.arrItems[3].control.textbox.value,
-				pc = this.arrItems[4].control.textbox.value,
-				owner = this.arrItems[5].control.textbox.value,
-				parentTaskId = this.arrItems[6].control.textbox.value,
-				predTaskId = this.arrItems[7].control.textbox.value;
-			if(dojo.trim(id).length <= 0){
-				return;
-			}
-			if(this.object.insertTask(id, name, startTime, duration, pc, predTaskId, owner, parentTaskId)){
-				this.hide();
-			}else{
-				alert("Please adjust your Customization");
-				return;
-			}
-			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
-		},
-		addSuccessorTaskAction: function(){
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			var pr = this.object.project,
-				id = this.arrItems[0].control.textbox.value,
-				name = this.arrItems[1].control.textbox.value,
-				startTime = this.decodeDate(this.arrItems[2].control.textbox.value),
-				duration = this.arrItems[3].control.textbox.value,
-				pc = this.arrItems[4].control.textbox.value,
-				owner = this.arrItems[5].control.textbox.value;
-			if(dojo.trim(id).length <= 0){
-				return;
-			}
-			var parentTaskId = !this.object.parentTask ? "" : this.object.parentTask.taskItem.id;
-			var predTaskId = this.object.taskItem.id;
-			if(pr.insertTask(id, name, startTime, duration, pc, predTaskId, owner, parentTaskId)){
-				this.hide();
-			}else{
-				alert("Please adjust your Customization");
-				return;
-			}
-			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
-		},
-		addChildTaskAction: function(){
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			var pr = this.object.project,
-				id = this.arrItems[0].control.textbox.value,
-				name = this.arrItems[1].control.textbox.value,
-				startTime = this.decodeDate(this.arrItems[2].control.textbox.value),
-				duration = this.arrItems[3].control.textbox.value,
-				pc = this.arrItems[4].control.textbox.value,
-				owner = this.arrItems[5].control.textbox.value,
-				parentTaskId = this.object.taskItem.id,
-				predTaskId = "";
-			if(dojo.trim(id).length <= 0){
-				return;
-			}
-			if(pr.insertTask(id, name, startTime, duration, pc, predTaskId, owner, parentTaskId)){
-				this.hide();
-			}else{
-				alert("Please adjust your Customization");
-				return;
-			}
-			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
-		},
-		addProjectAction: function(){
-			if(!this.preValueValidation(this.arrItems)){
-				return;
-			}
-			var id = this.arrItems[0].control.textbox.value,
-			namePr = this.arrItems[1].control.textbox.value,
-			startDatePr = this.decodeDate(this.arrItems[2].control.textbox.value);
-			if(dojo.trim(id).length <= 0 || dojo.trim(namePr).length <= 0){
-				return;
-			}
-			if(this.tabMenu.ganttChart.insertProject(id, namePr, startDatePr)){
-				this.hide();
-			}else{
-				alert("Please adjust your Customization");
-				return;
-			}
-			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
-		},
-		
-		addAction: function(handler){
-			this.actionFunc = this[handler];
-		},
-		addItem: function(id, name, key, required){
-			var inputControl;
-			if(key == "startTime" || key == "startDate"){
-				inputControl = new dijit.form.DateTextBox({type:"text", constraints:{datePattern:"yyyy.M.d", strict:true}});
-			}else if(key == "percentage"){
-				inputControl = new dijit.form.NumberSpinner({ constraints:{ max:100, min:0 }});
-			}else if(key == "duration"){
-				inputControl = new dijit.form.NumberSpinner({ constraints:{ min:0 }});
-			}else{
-				inputControl = new dijit.form.TextBox();
-			}
-			this.arrItems.push({
-				id: id,
-				name: name,
-				control: inputControl,
-				tab: this,
-				key: key,
-				required: required
-			});
-		},
-		show: function(){
-			this.tabMenu.tabPanelDlg = this.tabMenu.tabPanelDlg || dijit.byId(this.tabMenu.tabPanelDlgId) ||
-				new dijit.Dialog({
-					title: "Settings"
-				});
-			try{
-				this.tabMenu.tabPanelDlg.show();
-			}catch(e){
-				console.log("dialog show exception: " + e.message);
-				return;
-			}
-			this.tabMenu.tabPanelDlg.titleNode.innerHTML = this.Description;
-			var content = this.tabMenu.paneContentArea.firstChild.rows[1].cells[0].firstChild,
-				action = this.tabMenu.paneActionBar;
-			var cell, cellValue, row = null;
-			
-			if(this.showObjectInfo){
-				if(this.object){
-					if(this.object.constructor == dojox.gantt.GanttTaskControl){
-						this.insertData(content, "Id", this.object.taskItem.id);
-						this.insertData(content, "Name", this.object.taskItem.name);
-						this.insertData(content, "Start Time", this.encodeDate(this.object.taskItem.startTime));
-						this.insertData(content, "Duration (hours)", this.object.taskItem.duration + " hours");
-						this.insertData(content, "Percent Complete (%)", this.object.taskItem.percentage + "%");
-						this.insertData(content, "Task Assignee", this.object.taskItem.taskOwner);
-						this.insertData(content, "Previous Task Id", this.object.taskItem.previousTaskId);
-					}else{
-						this.insertData(content, "Id", this.object.project.id);
-						this.insertData(content, "Name", this.object.project.name);
-						this.insertData(content, "Start date", this.encodeDate(this.object.project.startDate));
-					}
-				}
-			}
-			//separator
-			row = content.insertRow(content.rows.length);
-			cell = row.insertCell(row.cells.length);
-			cell.colSpan = 2;
-			cell.innerHTML = "<hr/>";
-			//input section header
-			row = content.insertRow(content.rows.length);
-			cell = row.insertCell(row.cells.length);
-			cell.colSpan = 2;
-			dojo.addClass(cell, "ganttMenuDialogInputCellHeader");
-			cell.innerHTML = "Customization: " + this.Description;
-			//input details
-			dojo.forEach(this.arrItems, function(item){
-				row = content.insertRow(content.rows.length);
-				cell = row.insertCell(row.cells.length);
-				dojo.addClass(cell, "ganttMenuDialogInputCell");
-				cellValue = row.insertCell(row.cells.length);
-				dojo.addClass(cellValue, "ganttMenuDialogInputCellValue");
-				cell.innerHTML = item.name;
-				cellValue.appendChild(item.control.domNode);
-				//initialize default value
-				if(this.withDefaultValue && this.object){
-					if(this.object.constructor == dojox.gantt.GanttTaskControl){
-						if(item.key == "startTime"){
-							item.control.textbox.value = this.encodeDate(this.object.taskItem.startTime);
-						}else{
-							item.control.textbox.value = item.key ? this.object.taskItem[item.key] : "";
-						}
-					}else{
-						if(item.key == "startDate"){
-							item.control.textbox.value = this.encodeDate(this.object.project.startDate);
-						}else{
-							item.control.textbox.value = item.key ? (this.object.project[item.key] || this.object[item.key] || "") : "";
-						}
-					}
-				}else{
-					//HTML5 placeholder property
-					item.control.textbox.placeholder = item.required ? "---required---" : "---optional---";
-				}
-			}, this);
-			this.tabMenu.ok.onClick = dojo.hitch(this, this.actionFunc);
-			this.tabMenu.cancel.onClick = dojo.hitch(this, this.hide);
-		},
-		hide: function(){
-			try{
-				this.tabMenu.tabPanelDlg.hide();
-			}catch(e){
-				console.log("dialog show exception: " + e.message);
-				this.tabMenu.tabPanelDlg.destroy();
-			}
-			var cell = this.tabMenu.paneContentArea.firstChild.rows[1].cells[0];
-			cell.firstChild.parentNode.removeChild(cell.firstChild);
-			cell.innerHTML = "<table></table>";
-			dojo.addClass(cell.firstChild, "ganttDialogContentCell");
-		},
-		insertData: function(content, name, value){
-			var cell, cellValue, row = null;
-			row = content.insertRow(content.rows.length);
-			cell = row.insertCell(row.cells.length);
-			dojo.addClass(cell, "ganttMenuDialogDescCell");
-			cell.innerHTML = name;
-			cellValue = row.insertCell(row.cells.length);
-			dojo.addClass(cellValue, "ganttMenuDialogDescCellValue");
-			cellValue.innerHTML = value;
-		}
-	});
-})();
+	});	
+});
diff --git a/dojox/gantt/contextMenuTab.js b/dojox/gantt/contextMenuTab.js
new file mode 100644
index 0000000..a938cbf
--- /dev/null
+++ b/dojox/gantt/contextMenuTab.js
@@ -0,0 +1,362 @@
+define([
+	"./GanttTaskControl",
+	"dijit/Menu",
+	"dijit/Dialog",
+	"dijit/form/NumberSpinner",
+	"dijit/form/Button",
+	"dijit/form/CheckBox",
+	"dijit/form/DateTextBox",
+	"dijit/form/TimeTextBox",
+	"dijit/form/TextBox",
+	"dijit/form/Form",
+	"dijit/registry",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/html",
+    "dojo/date/locale",
+	"dojo/request",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dojo/domReady!"
+], function(GanttTaskControl, Menu, Dialog, NumberSpinner, Button, CheckBox, DateTextBox, TimeTextBox, TextBox, Form,
+		registry, declare, arrayUtil, lang, html, locale, request, 
+		dom, domClass){
+	return declare("dojox.gantt.contextMenuTab", [], {
+		constructor: function(id, description, type, showOInfo, tabMenu, withDefaultValue){
+			this.id = id;
+			this.arrItems = [];
+			this.TabItemContainer = null;
+			this.Description = description;
+			this.tabMenu = tabMenu;
+			this.type = type;
+			this.object = null;
+			this.showObjectInfo = showOInfo;
+			this.withDefaultValue = withDefaultValue;
+		},
+		preValueValidation: function(items){
+			for(var i = 0; i < items.length; i++){
+				var item = items[i];
+				//TODO add more validation for Id, Name, .....
+				if(item.required && !item.control.textbox.value){
+					return false;
+				}
+			}
+			return true;
+		},
+		encodeDate: function(date){
+			return date.getFullYear() + "." + (date.getMonth() + 1) + "." + date.getDate();
+		},
+		decodeDate: function(dateStr){
+			var arr = dateStr.split(".");
+			return (arr.length < 3) ? "" : (new Date(arr[0], parseInt(arr[1]) - 1, arr[2]));
+		},
+		renameTaskAction: function(){
+			var name = this.arrItems[0].control.textbox.value;
+			if(lang.trim(name).length <= 0){
+				return;
+			}
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			this.object.setName(name);
+			this.hide();
+		},
+		deleteAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			this.object.project.deleteTask(this.object.taskItem.id);
+			this.hide();
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		durationUpdateAction: function(){
+			var d = this.arrItems[0].control.textbox.value;
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			if(this.object.setDuration(d)){
+				this.hide();
+			}else{
+				alert("Duration out of Range");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.refresh();
+		},
+		cpUpdateAction: function(){
+			var p = this.arrItems[0].control.textbox.value;
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			if(this.object.setPercentCompleted(p)){
+				this.hide();
+			}else{
+				alert("Complete Percentage out of Range");
+			}
+		},
+		ownerUpdateAction: function(){
+			var to = this.arrItems[0].control.textbox.value;
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			if(this.object.setTaskOwner(to)){
+				this.hide();
+			}else{
+				alert("Task owner not Valid");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		ptUpdateAction: function(){
+			var p = this.arrItems[0].control.textbox.value;
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			if(this.object.setPreviousTask(p)){
+				this.hide();
+			}else{
+				alert("Please verify the Previous Task (" + p + ")  and adjust its Time Range");
+			}
+		},
+		renameProjectAction: function(){
+			var name = this.arrItems[0].control.textbox.value;
+			if(lang.trim(name).length <= 0){
+				return;
+			}
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			this.object.setName(name);
+			this.hide();
+		},
+		deleteProjectAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			this.object.ganttChart.deleteProject(this.object.project.id);
+			this.hide();
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		cpProjectAction: function(){
+			var p = this.arrItems[0].control.textbox.value;
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			if(this.object.setPercentCompleted(p)){
+				this.hide();
+			}else{
+				alert("Percentage not Acceptable");
+			}
+		},
+		addTaskAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			var id = this.arrItems[0].control.textbox.value,
+				name = this.arrItems[1].control.textbox.value,
+				startTime = this.decodeDate(this.arrItems[2].control.textbox.value),
+				duration = this.arrItems[3].control.textbox.value,
+				pc = this.arrItems[4].control.textbox.value,
+				owner = this.arrItems[5].control.textbox.value,
+				parentTaskId = this.arrItems[6].control.textbox.value,
+				predTaskId = this.arrItems[7].control.textbox.value;
+			if(lang.trim(id).length <= 0){
+				return;
+			}
+			if(this.object.insertTask(id, name, startTime, duration, pc, predTaskId, owner, parentTaskId)){
+				this.hide();
+			}else{
+				alert("Please adjust your Customization");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		addSuccessorTaskAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			var pr = this.object.project,
+				id = this.arrItems[0].control.textbox.value,
+				name = this.arrItems[1].control.textbox.value,
+				startTime = this.decodeDate(this.arrItems[2].control.textbox.value),
+				duration = this.arrItems[3].control.textbox.value,
+				pc = this.arrItems[4].control.textbox.value,
+				owner = this.arrItems[5].control.textbox.value;
+			if(lang.trim(id).length <= 0){
+				return;
+			}
+			var parentTaskId = !this.object.parentTask ? "" : this.object.parentTask.taskItem.id;
+			var predTaskId = this.object.taskItem.id;
+			if(pr.insertTask(id, name, startTime, duration, pc, predTaskId, owner, parentTaskId)){
+				this.hide();
+			}else{
+				alert("Please adjust your Customization");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		addChildTaskAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			var pr = this.object.project,
+				id = this.arrItems[0].control.textbox.value,
+				name = this.arrItems[1].control.textbox.value,
+				startTime = this.decodeDate(this.arrItems[2].control.textbox.value),
+				duration = this.arrItems[3].control.textbox.value,
+				pc = this.arrItems[4].control.textbox.value,
+				owner = this.arrItems[5].control.textbox.value,
+				parentTaskId = this.object.taskItem.id,
+				predTaskId = "";
+			if(lang.trim(id).length <= 0){
+				return;
+			}
+			if(pr.insertTask(id, name, startTime, duration, pc, predTaskId, owner, parentTaskId)){
+				this.hide();
+			}else{
+				alert("Please adjust your Customization");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		addProjectAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			var id = this.arrItems[0].control.textbox.value,
+			namePr = this.arrItems[1].control.textbox.value,
+			startDatePr = this.decodeDate(this.arrItems[2].control.textbox.value);
+			if(lang.trim(id).length <= 0 || lang.trim(namePr).length <= 0){
+				return;
+			}
+			if(this.tabMenu.ganttChart.insertProject(id, namePr, startDatePr)){
+				this.hide();
+			}else{
+				alert("Please adjust your Customization");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+	
+		addAction: function(handler){
+			this.actionFunc = this[handler];
+		},
+		addItem: function(id, name, key, required){
+			var inputControl;
+			if(key == "startTime" || key == "startDate"){
+				inputControl = new DateTextBox({type:"text", constraints:{datePattern:"yyyy.M.d", strict:true}});
+			}else if(key == "percentage"){
+				inputControl = new NumberSpinner({ constraints:{ max:100, min:0 }});
+			}else if(key == "duration"){
+				inputControl = new NumberSpinner({ constraints:{ min:0 }});
+			}else{
+				inputControl = new TextBox();
+			}
+			this.arrItems.push({
+				id: id,
+				name: name,
+				control: inputControl,
+				tab: this,
+				key: key,
+				required: required
+			});
+		},
+		show: function(){
+			this.tabMenu.tabPanelDlg = this.tabMenu.tabPanelDlg || registry.byId(this.tabMenu.tabPanelDlgId) ||
+				new Dialog({
+					title: "Settings"
+				});
+			try{
+				this.tabMenu.tabPanelDlg.show();
+			}catch(e){
+				console.log("dialog show exception: " + e.message);
+				return;
+			}
+			this.tabMenu.tabPanelDlg.titleNode.innerHTML = this.Description;
+			var content = this.tabMenu.paneContentArea.firstChild.rows[1].cells[0].firstChild;
+			var cell, cellValue, row = null;
+		
+			if(this.showObjectInfo){
+				if(this.object){
+					if(this.object.constructor == GanttTaskControl){
+						this.insertData(content, "Id", this.object.taskItem.id);
+						this.insertData(content, "Name", this.object.taskItem.name);
+						this.insertData(content, "Start Time", this.encodeDate(this.object.taskItem.startTime));
+						this.insertData(content, "Duration (hours)", this.object.taskItem.duration + " hours");
+						this.insertData(content, "Percent Complete (%)", this.object.taskItem.percentage + "%");
+						this.insertData(content, "Task Assignee", this.object.taskItem.taskOwner);
+						this.insertData(content, "Previous Task Id", this.object.taskItem.previousTaskId);
+					}else{
+						this.insertData(content, "Id", this.object.project.id);
+						this.insertData(content, "Name", this.object.project.name);
+						this.insertData(content, "Start date", this.encodeDate(this.object.project.startDate));
+					}
+				}
+			}
+			//separator
+			row = content.insertRow(content.rows.length);
+			cell = row.insertCell(row.cells.length);
+			cell.colSpan = 2;
+			cell.innerHTML = "<hr/>";
+			//input section header
+			row = content.insertRow(content.rows.length);
+			cell = row.insertCell(row.cells.length);
+			cell.colSpan = 2;
+			domClass.add(cell, "ganttMenuDialogInputCellHeader");
+			cell.innerHTML = "Customization: " + this.Description;
+			//input details
+			arrayUtil.forEach(this.arrItems, function(item){
+				row = content.insertRow(content.rows.length);
+				cell = row.insertCell(row.cells.length);
+				domClass.add(cell, "ganttMenuDialogInputCell");
+				cellValue = row.insertCell(row.cells.length);
+				domClass.add(cellValue, "ganttMenuDialogInputCellValue");
+				cell.innerHTML = item.name;
+				cellValue.appendChild(item.control.domNode);
+				//initialize default value
+				if(this.withDefaultValue && this.object){
+					if(this.object.constructor == GanttTaskControl){
+						if(item.key == "startTime"){
+							item.control.textbox.value = this.encodeDate(this.object.taskItem.startTime);
+						}else{
+							item.control.textbox.value = item.key ? this.object.taskItem[item.key] : "";
+						}
+					}else{
+						if(item.key == "startDate"){
+							item.control.textbox.value = this.encodeDate(this.object.project.startDate);
+						}else{
+							item.control.textbox.value = item.key ? (this.object.project[item.key] || this.object[item.key] || "") : "";
+						}
+					}
+				}else{
+					//HTML5 placeholder property
+					item.control.textbox.placeholder = item.required ? "---required---" : "---optional---";
+				}
+			}, this);
+			this.tabMenu.ok.onClick = lang.hitch(this, this.actionFunc);
+			this.tabMenu.cancel.onClick = lang.hitch(this, this.hide);
+		},
+		hide: function(){
+			try{
+				this.tabMenu.tabPanelDlg.hide();
+			}catch(e){
+				console.log("dialog show exception: " + e.message);
+				this.tabMenu.tabPanelDlg.destroy();
+			}
+			var cell = this.tabMenu.paneContentArea.firstChild.rows[1].cells[0];
+			cell.firstChild.parentNode.removeChild(cell.firstChild);
+			cell.innerHTML = "<table></table>";
+			domClass.add(cell.firstChild, "ganttDialogContentCell");
+		},
+		insertData: function(content, name, value){
+			var cellValue,
+				row = content.insertRow(content.rows.length),
+				cell = row.insertCell(row.cells.length);
+			domClass.add(cell, "ganttMenuDialogDescCell");
+			cell.innerHTML = name;
+			cellValue = row.insertCell(row.cells.length);
+			domClass.add(cellValue, "ganttMenuDialogDescCellValue");
+			cellValue.innerHTML = value;
+		}
+	});
+});
diff --git a/dojox/gantt/resources/gantt.css b/dojox/gantt/resources/gantt.css
index 0f17a2a..f8e6560 100644
--- a/dojox/gantt/resources/gantt.css
+++ b/dojox/gantt/resources/gantt.css
@@ -1,26 +1,26 @@
 .ganttToolbarZoomIn {
-	background-image: url("images/zoomIn.png");
+	background-image: url("images/zoomin.png");
 	background-repeat: no-repeat;
 	height: 30px;
 	width: 30px;
 	padding: 2px;
 }
 .ganttToolbarZoomOut {
-	background-image: url("images/zoomOut.png");
+	background-image: url("images/zoomout.png");
 	background-repeat: no-repeat;
 	height: 30px;
 	width: 30px;
 	padding: 2px;
 }
 .ganttToolbarMicro {
-	background-image: url("images/zoomInTime.png");
+	background-image: url("images/zoomintime.png");
 	background-repeat: no-repeat;
 	height: 30px;
 	width: 30px;
 	padding: 2px;
 }
 .ganttToolbarTele {
-	background-image: url("images/zoomOutTime.png");
+	background-image: url("images/zoomouttime.png");
 	background-repeat: no-repeat;
 	height: 30px;
 	width: 30px;
@@ -42,7 +42,7 @@
 }
 .ganttToolbarActionHover{
 	border: 2px solid blue;
-	padding: 0px;
+	padding: 0;
 }
 .ganttToolbar {
 	cursor: pointer;
@@ -125,13 +125,13 @@
 	text-align: center;
 	z-index: 7;
 	position: absolute;
-	left: 0px;
-	top: 0px;
+	left: 0;
+	top: 0;
 }
 .ganttTblTime {
 	background-color: transparent;
 	cursor: pointer;
-	margin-top: 0px;
+	margin-top: 0;
 }
 .ganttHourNumber {
 	font-size: 7px;
@@ -204,8 +204,8 @@
 	font-family: Tahoma, Arial;
 	font-size: 12px;
 	border: 1px solid #b5bcc7;
-	margin: 0px;
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	background-color: #fff;
 	background-repeat: repeat-x;
 	border-collapse: separate;
@@ -213,7 +213,7 @@
 }
 .ganttContextMenuItem {
 	background-image: url("images/menuHighlight.png");
-	background-position:0px -40px;
+	background-position:0 -40px;
 	background-repeat:repeat-x;
 	padding: 3px 10px 4px;
 	height:18px;
@@ -222,7 +222,7 @@
 	border:solid 1px #769dc0;
 	padding: 2px 9px 3px;
 	background-color: #9dcfff;
-	background-position:0px 0px;
+	background-position:0 0;
 	color:#000;
 }
 .ganttMenuDialogDescCell{
@@ -257,7 +257,7 @@
 	font-family: Tahoma, Arial;
 	background: url("images/resourceHeader.png") repeat scroll 0 0 transparent;
 	color: black;
-	padding: 3px 0px 0px 6px;
+	padding: 3px 0 0 6px;
 	height: 25px;
 	font-weight: bold;
 	position:relative;
@@ -318,7 +318,7 @@
 	border-top: solid 1px black;
 	border-bottom: solid 1px black;
 	position:absolute;
-	top:0px;
+	top:0;
 }
 .ganttRowHighlight {
 	background: url("images/rowHighlight.png") repeat scroll 0 0 transparent;
@@ -339,30 +339,30 @@
 	margin: 15px 63px 0;
 }
 .ganttTaskLineVerticalLeft{
-	border-width: 0px 0px 0px 1px; 
+	border-width: 0 0 0 1px;
 	border-style: dotted; 
 	border-color: #86A3BE; 
-	margin: 0px; 
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	z-index:10;
 	position: absolute;
 }
 .ganttTaskLineHorizontalLeft{
 	position: absolute;
-	border-width: 1px 0px 0px 0px;
+	border-width: 1px 0 0 0;
 	font-size: 1px;
 	border-style: dotted; 
 	border-color: #86A3BE;
-	margin: 0px; 
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	z-index:10;
 }
 .ganttTaskLineVerticalRight{
-	border-width: 0px 0px 0px 1px; 
+	border-width: 0 0 0 1px;
 	border-style: solid; 
 	border-color: #4A8F43;
-	margin: 0px; 
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	z-index:6;
 	font-size: 1px;
 	position: absolute;
@@ -371,26 +371,26 @@
 	height:1px;
 	border-color: #4A8F43;
 	border-style: solid;
-	border-width: 1px 0px 0px 0px;
-	margin: 0px; 
-	padding: 0px;
+	border-width: 1px 0 0 0;
+	margin: 0;
+	padding: 0;
 	z-index:6;
 	position: absolute;
 }
 .ganttTaskArrowImg{
 	z-index:6;
-	margin: 0px; 
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	width:7px;
 	height:14px;
 	position: absolute;
 }
 .ganttTaskLineVerticalRightPlus{
-	border-width: 0px 0px 0px 1px; 
+	border-width: 0 0 0 1px;
 	border-style: solid; 
 	border-color: #519145;
-	margin: 0px; 
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	z-index:6;
 	font-size: 1px;
 	position: absolute;
@@ -399,16 +399,16 @@
 	height:1px;
 	border-color: #519145;
 	border-style: solid;
-	border-width: 1px 0px 0px 0px;
-	margin: 0px; 
-	padding: 0px;
+	border-width: 1px 0 0 0;
+	margin: 0;
+	padding: 0;
 	z-index:6;
 	position: absolute;
 }
 .ganttTaskArrowImgPlus{
 	z-index:6;
-	margin: 0px; 
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	width:7px;
 	height:14px;
 	position: absolute;
@@ -420,8 +420,8 @@
 .ganttTaskDivTaskItem{
 	z-index:6;
 	position: absolute;
-	left:0px;
-	top:0px;
+	left:0;
+	top:0;
 }
 .ganttTaskTblTaskItem{
 	border: solid 1px #5FF55F;
@@ -431,14 +431,14 @@
 	font-size:9px;
 	z-index:7;
 	position: absolute;
-	left:0px;
-	top:0px;
+	left:0;
+	top:0;
 }
 .ganttTaskDivTaskName{
 	z-index:7;
 	position: absolute;
-	left:0px;
-	top:0px;
+	left:0;
+	top:0;
 }
 .ganttTaskDivMoveInput{
 	visibility:hidden;
@@ -453,7 +453,7 @@
 .ganttTaskDivResize{
 	z-index:10;
 	position: absolute;
-	top:0px;
+	top:0;
 }
 .ganttTaskTaskNameItem{
 	font-family: Tahoma, Arial;
@@ -487,7 +487,7 @@
 	-khtml-border-radius: 20px;
 	-webkit-border-radius: 20px;
 	border-radius: 20px;
-	padding: 0px 3px;
+	padding: 0 3px;
 	cursor:pointer;
 	white-space:nowrap;
 	height:14px;
@@ -520,11 +520,11 @@
 	position: relative;
 }
 .ganttResourceLineVerticalLeft{
-	border-width: 0px 0px 0px 1px; 
+	border-width: 0 0 0 1px;
 	border-style: dotted; 
 	border-color: #86A3BE; 
-	margin: 0px; 
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	z-index:10;
 	position: absolute;
 }
@@ -532,12 +532,12 @@
 	z-index:10;
 	height:1px;
 	position: absolute;
-	border-width: 1px 0px 0px 0px;
+	border-width: 1px 0 0 0;
 	font-size: 1px;
 	border-style: dotted; 
 	border-color: #86A3BE;
-	margin: 0px; 
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 }
 .ganttResourceTreeImage{
 	cursor: pointer;
diff --git a/dojox/gantt/tests/test_Gantt.html b/dojox/gantt/tests/test_Gantt.html
index 2934cb9..9ad204b 100644
--- a/dojox/gantt/tests/test_Gantt.html
+++ b/dojox/gantt/tests/test_Gantt.html
@@ -1,67 +1,76 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<!DOCTYPE html>
+<html>
 	<head>
 		<title>Gantt Chart</title>
 		<meta http-equiv="content-type" content="text/html; charset=utf-8" />
-		<style type="text/css">
+		<style>
 			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/claro.css";
 			@import "../../../dijit/tests/css/dijitTests.css";
+			@import "../resources/gantt.css";
 		</style>
-		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true">
-		</script>
-		<link type="text/css" rel="stylesheet" href="../resources/gantt.css">
-		<script type="text/javascript" language="JavaScript">
-			dojo.require("dojo.parser"); // scan page for widgets and instantiate them
-			dojo.require("dojox.gantt.GanttChart");
-			
-			dojo.addOnLoad(function(){
-				var projectDev = new dojox.gantt.GanttProjectItem({
+		<script src="../../../dojo/dojo.js"
+        		data-dojo-config="async:true, transparentColor: [ 255, 255, 255 ]"></script>
+
+		<script src="../../../dijit/tests/_testCommon.js"></script>
+
+		<script >
+			require([
+			    "dojo/_base/declare",
+				"dojo/parser",
+				"dojo/query",
+				"dojox/gantt/GanttChart",
+				"dojox/gantt/GanttProjectItem",
+				"dojox/gantt/GanttTaskItem",
+				"dojo/dom",
+				"dojo/domReady!"
+			], function(declare, parser, query, GanttChart, GanttProjectItem, GanttTaskItem, dom){
+			    var projectDev = new GanttProjectItem({
 					id: 1,
 					name: "Development Project",
-					startDate: new Date(2006, 5, 11)
+					startDate: new Date(2012, 5, 11)
 				});
 				
-				var taskRequirement = new dojox.gantt.GanttTaskItem({
+				var taskRequirement = new GanttTaskItem({
 					id: 1,
 					name: "Requirement",
-					startTime: new Date(2006, 5, 11),
+					startTime: new Date(2012, 5, 11),
 					duration: 50,
 					percentage: 50,
 					taskOwner: "Jack"
 				});
-				var taskAnalysis = new dojox.gantt.GanttTaskItem({
+				var taskAnalysis = new GanttTaskItem({
 					id: 2,
 					name: "Analysis",
-					startTime: new Date(2006, 5, 18),
+					startTime: new Date(2012, 5, 18),
 					duration: 40,
 					percentage: 80,
 					previousTaskId: "1",
 					taskOwner: "Michael"
 				});
-				var taskDesign = new dojox.gantt.GanttTaskItem({
+				var taskDesign = new GanttTaskItem({
 					id: 3,
 					name: "Design",
-					startTime: new Date(2006, 5, 18),
+					startTime: new Date(2012, 5, 18),
 					duration: 60,
 					percentage: 80,
 					previousTaskId: "1",
 					taskOwner: "Jason"
 				});
-				var taskDetailDesign = new dojox.gantt.GanttTaskItem({
+				var taskDetailDesign = new GanttTaskItem({
 					id: 4,
 					name: "Detail design",
-					startTime: new Date(2006, 5, 18),
+					startTime: new Date(2012, 5, 18),
 					duration: 30,
 					percentage: 50,
 					previousTaskId: "1",
 					taskOwner: "Michael"
 				});
-				var taskDevelopmentDoc = new dojox.gantt.GanttTaskItem({
+				var taskDevelopmentDoc = new GanttTaskItem({
 					id: 5,
 					name: "Development doc",
-					startTime: new Date(2006, 5, 20),
+					startTime: new Date(2012, 5, 20),
 					duration: 20,
 					percentage: 10,
 					previousTaskId: "1",
@@ -74,46 +83,46 @@
 				projectDev.addTask(taskDetailDesign);
 				projectDev.addTask(taskDevelopmentDoc);
 				
-				var taskSketch = new dojox.gantt.GanttTaskItem({
+				var taskSketch = new GanttTaskItem({
 					id: 6,
 					name: "Sketch",
-					startTime: new Date(2006, 6, 1),
+					startTime: new Date(2012, 6, 1),
 					duration: 20,
 					percentage: 50,
 					previousTaskId: "3",
 					taskOwner: "Rock"
 				});
-				var taskPrototype = new dojox.gantt.GanttTaskItem({
+				var taskPrototype = new GanttTaskItem({
 					id: 7,
 					name: "Prototype",
-					startTime: new Date(2006, 6, 6),
+					startTime: new Date(2012, 6, 6),
 					duration: 60,
 					percentage: 80,
 					previousTaskId: "6",
 					taskOwner: "Rock"
 				});
-				var taskImplementation = new dojox.gantt.GanttTaskItem({
+				var taskImplementation = new GanttTaskItem({
 					id: 8,
 					name: "Implementation",
-					startTime: new Date(2006, 6, 6),
+					startTime: new Date(2012, 6, 6),
 					duration: 30,
 					percentage: 80,
 					previousTaskId: "6",
 					taskOwner: "Jason"
 				});
-				var taskDetailImplement = new dojox.gantt.GanttTaskItem({
+				var taskDetailImplement = new GanttTaskItem({
 					id: 9,
 					name: "Detail Implement",
-					startTime: new Date(2006, 6, 17),
+					startTime: new Date(2012, 6, 17),
 					duration: 120,
 					percentage: 50,
 					previousTaskId: "7",
 					taskOwner: "Jason"
 				});
-				var taskDeliver = new dojox.gantt.GanttTaskItem({
+				var taskDeliver = new GanttTaskItem({
 					id: 10,
 					name: "Deliver",
-					startTime: new Date(2006, 6, 18),
+					startTime: new Date(2012, 6, 18),
 					duration: 100,
 					percentage: 30,
 					previousTaskId: "8",
@@ -127,7 +136,7 @@
 				projectDev.addTask(taskDeliver);
 				
 				// Create Gantt control
-				var ganttChart = new dojox.gantt.GanttChart({
+				var ganttChart = new GanttChart({
 					//readOnly: true,			//optional: gantt chart editable
 					//dataFilePath: "gnt.json",	//optional: json data file path for load and save, default is "gantt_default.json"
 					//withTaskId: false,		//optional: if true, task id will be on the right of task name, default value is !readOnly.
@@ -142,13 +151,12 @@
 				
 				// Initialize and Render
 				ganttChart.init();
-				
 			});
 		</script>
 	</head>
-	<body class="claro">
-		<div class="ganttContent">
-			<div id="gantt">
+	<body class= "claro" >
+		<div class= "ganttContent" >
+			<div id = "gantt" >
 			</div>
 		</div>
 	</body>
diff --git a/dojox/gauges/AnalogArcIndicator.js b/dojox/gauges/AnalogArcIndicator.js
index 5979f15..776738f 100644
--- a/dojox/gauges/AnalogArcIndicator.js
+++ b/dojox/gauges/AnalogArcIndicator.js
@@ -1,9 +1,5 @@
 define(["dojo/_base/declare","dojo/_base/lang","dojo/_base/connect","dojo/_base/fx","./AnalogIndicatorBase"],
-function(declare, lang, connect, fx, AnalogIndicatorBase) { 
-
-/*=====
-	AnalogIndicatorBase = dojox.gauges.AnalogIndicatorBase;
-=====*/
+function(declare, lang, connect, fx, AnalogIndicatorBase) {
 
 return declare("dojox.gauges.AnalogArcIndicator",[AnalogIndicatorBase],{
 	
diff --git a/dojox/gauges/AnalogArrowIndicator.js b/dojox/gauges/AnalogArrowIndicator.js
index 08c186e..0b48e7e 100644
--- a/dojox/gauges/AnalogArrowIndicator.js
+++ b/dojox/gauges/AnalogArrowIndicator.js
@@ -1,15 +1,11 @@
 define(["dojo/_base/declare","./AnalogIndicatorBase"],
-function(declare, AnalogIndicatorBase) { 
-
-/*=====
-	AnalogIndicatorBase = dojox.gauges.AnalogIndicatorBase;
-=====*/
+function(declare, AnalogIndicatorBase) {
 
 return declare("dojox.gauges.AnalogArrowIndicator", [AnalogIndicatorBase],{
 
 	// summary:
 	//		An indicator for the AnalogGauge that draws an arrow. The arrow is drawn on the angle that corresponds
-	// to the value of the indicator.
+	//		to the value of the indicator.
 	
 	_getShapes: function(group){
 		// summary:
diff --git a/dojox/gauges/AnalogCircleIndicator.js b/dojox/gauges/AnalogCircleIndicator.js
index 5e0891f..b72d623 100644
--- a/dojox/gauges/AnalogCircleIndicator.js
+++ b/dojox/gauges/AnalogCircleIndicator.js
@@ -1,9 +1,5 @@
 define(["dojo/_base/declare","./AnalogIndicatorBase"],
-  function(declare, AnalogIndicatorBase) { 
-
-/*=====
-	AnalogIndicatorBase = dojox.gauges.AnalogIndicatorBase;
-=====*/
+  function(declare, AnalogIndicatorBase) {
 
 return declare("dojox.gauges.AnalogCircleIndicator", [AnalogIndicatorBase], {
 	// summary:
@@ -13,7 +9,7 @@ return declare("dojox.gauges.AnalogCircleIndicator", [AnalogIndicatorBase], {
 	
 	
 	_getShapes: function(group){
-		// summary: 
+		// summary:
 		//		Override of dojox.gauges.AnalogLineIndicator._getShapes
 		var color = this.color ? this.color : 'black';
 		var strokeColor = this.strokeColor ? this.strokeColor : color;
diff --git a/dojox/gauges/AnalogGauge.js b/dojox/gauges/AnalogGauge.js
index 64dae44..c2cf362 100644
--- a/dojox/gauges/AnalogGauge.js
+++ b/dojox/gauges/AnalogGauge.js
@@ -3,10 +3,6 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/array","dojo/_base/
 	function(dojo, declare, arr, lang, html, event, 
 			gfx, Gauge, AnalogLineIndicator, domGeometry) {
 
-/*=====
-	Gauge = dojox.gauges._Gauge;
-=====*/
-
 return declare("dojox.gauges.AnalogGauge",Gauge,{
 	// summary:
 	//		a gauge built using the dojox.gfx package.
@@ -36,27 +32,27 @@ return declare("dojox.gauges.AnalogGauge",Gauge,{
 	//	|	</div>
 
 	// startAngle: Number
-	// 		angle (in degrees) for start of gauge (default is -90)
+	//		angle (in degrees) for start of gauge (default is -90)
 	startAngle: -90,
 
 	// endAngle: Number
-	// 		angle (in degrees) for end of gauge (default is 90)
+	//		angle (in degrees) for end of gauge (default is 90)
 	endAngle: 90,
 
 	// cx: Number
-	// 		center of gauge x coordinate (default is gauge width / 2)
+	//		center of gauge x coordinate (default is gauge width / 2)
 	cx: 0,
 
 	// cy: Number
-	// 		center of gauge x coordinate (default is gauge height / 2)
+	//		center of gauge x coordinate (default is gauge height / 2)
 	cy: 0,
 
 	// radius: Number
-	// 		radius of gauge (default is smaller of cx-25 or cy-25)
+	//		radius of gauge (default is smaller of cx-25 or cy-25)
 	radius: 0,
 	
 	// orientation: String
-	// 		The orientation of the gauge. The value can be 'clockwise' or 'cclockwise' (default is 'clockwise')
+	//		The orientation of the gauge. The value can be 'clockwise' or 'cclockwise' (default is 'clockwise')
 	orientation: "clockwise",
 
 	// _defaultIndicator: dojox.gauges._Indicator
@@ -144,7 +140,7 @@ return declare("dojox.gauges.AnalogGauge",Gauge,{
 	_getAngleRange: function(){
 		// summary:
 		//		This is a helper function that returns the angle range
-		//      from startAngle to endAngle according to orientation.
+		//		from startAngle to endAngle according to orientation.
 		var range;
 		var startAngle = this._mod360(this.startAngle);
 		var endAngle = this._mod360(this.endAngle);
@@ -188,14 +184,14 @@ return declare("dojox.gauges.AnalogGauge",Gauge,{
 	},
 	
 	_isScaleCircular: function(){
-		// summary: 
+		// summary:
 		//		internal method to check if the scale is fully circular
 		return (this._mod360(this.startAngle) == this._mod360(this.endAngle));
 	},
 	
 	_mod360:function(v){
 		// summary:
-		//     returns the angle between 0 and 360;
+		//		returns the angle between 0 and 360;
 		while (v>360) v = v - 360;
 		while (v<0) v = v + 360;
 		return v;
@@ -338,15 +334,15 @@ return declare("dojox.gauges.AnalogGauge",Gauge,{
 	_dragIndicator: function(/*Object*/ widget, /*Object*/ e){
 		// summary:
 		//		Handles the dragging of an indicator to the event position, including moving/re-drawing
-		// 		get angle for mouse position
+		//		get angle for mouse position
 		this._dragIndicatorAt(widget, e.pageX, e.pageY);
 		event.stop(e);
 	},
 		
 	_dragIndicatorAt: function(/*Object*/ widget, x,y){
 		// summary:
-		// 		Handles the dragging of an indicator to a specific position, including moving/re-drawing
-		// 		get angle for mouse position
+		//		Handles the dragging of an indicator to a specific position, including moving/re-drawing
+		//		get angle for mouse position
 		var pos = domGeometry.position(widget.gaugeContent, true),
 			xf = x - pos.x,
 			yf = y - pos.y,
diff --git a/dojox/gauges/AnalogIndicatorBase.js b/dojox/gauges/AnalogIndicatorBase.js
index 63c40c8..70adf91 100644
--- a/dojox/gauges/AnalogIndicatorBase.js
+++ b/dojox/gauges/AnalogIndicatorBase.js
@@ -1,17 +1,13 @@
 define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/connect","dojo/_base/fx","dojox/gfx","./_Indicator"],
   function(lang, declare, connect, fx, gfx, Indicator) {
  
-/*=====
-	Indicator = dojox.gauges._indicator;
-=====*/
-
 return declare("dojox.gauges.AnalogIndicatorBase",[Indicator],{
-		//	summary:
+		// summary:
 		//		An abstract base class for indicators that can be used in an AnalogGauge.
 		//
 
 	draw: function(/*dojox.gfx.Group*/ group, /*Boolean?*/ dontAnimate){
-		// summary: 
+		// summary:
 		//		Override of dojox.gauges._Indicator.draw
 		// group: dojox.gfx.Group
 		//		The GFX group when the indicator must be drawn
@@ -73,7 +69,7 @@ return declare("dojox.gauges.AnalogIndicatorBase",[Indicator],{
 	},
 	
 	_layoutLabel:function(group, txt, ox, oy, lrad, angle, labelPlacement){
-		// summary: 
+		// summary:
 		//		Places the label on the side of the tick.
 	
 		var font = this.font ? this.font : gfx.defaultFont;
@@ -174,7 +170,7 @@ return declare("dojox.gauges.AnalogIndicatorBase",[Indicator],{
 	},
 	
 	_move: function(/*Boolean?*/ dontAnimate){
-		// summary: 
+		// summary:
 		// dontAnimate: Boolean
 		//		Indicates if the drawing should not be animated (vs. the default of doing an animation)
 		var v = Math.min(Math.max(this.value, this._gauge.min), this._gauge.max),
diff --git a/dojox/gauges/AnalogLineIndicator.js b/dojox/gauges/AnalogLineIndicator.js
index 6a259bd..8787c9c 100644
--- a/dojox/gauges/AnalogLineIndicator.js
+++ b/dojox/gauges/AnalogLineIndicator.js
@@ -1,14 +1,10 @@
 define(["dojo/_base/declare","./AnalogIndicatorBase"],
   function(declare, AnalogIndicatorBase) {
 
-/*=====
-	AnalogIndicatorBase = dojox.gauges.AnalogIndicatorBase;
-=====*/
-
 return declare("dojox.gauges.AnalogLineIndicator", [AnalogIndicatorBase], {
-	//	summary:
+	// summary:
 	//		An indicator for the AnalogGauge that draws a segment of line that has for length the length of the indicator
-	// 		and that starts at an offset from the center of the gauge. The line is drawn on the angle that corresponds
+	//		and that starts at an offset from the center of the gauge. The line is drawn on the angle that corresponds
 	//		to the value of the indicator.
 
 	_getShapes: function(/*dojox.gfx.Group*/ group){
diff --git a/dojox/gauges/AnalogNeedleIndicator.js b/dojox/gauges/AnalogNeedleIndicator.js
index 68c984b..106dbc6 100644
--- a/dojox/gauges/AnalogNeedleIndicator.js
+++ b/dojox/gauges/AnalogNeedleIndicator.js
@@ -1,14 +1,10 @@
 define(["dojo/_base/declare","./AnalogIndicatorBase"],
   function(declare, AnalogIndicatorBase) { 
 
-/*=====
-	AnalogIndicatorBase = dojox.gauges.AnalogIndicatorBase;
-=====*/
-
 return declare("dojox.gauges.AnalogNeedleIndicator", [AnalogIndicatorBase], {
 	// summary:
 	//		An indicator for the AnalogGauge that draws a needle. The needle is drawn on the angle that corresponds
-	// 		to the value of the indicator.
+	//		to the value of the indicator.
 	
 	_getShapes: function(group){
 		// summary:
diff --git a/dojox/gauges/BarCircleIndicator.js b/dojox/gauges/BarCircleIndicator.js
index 370ba31..38c34e1 100644
--- a/dojox/gauges/BarCircleIndicator.js
+++ b/dojox/gauges/BarCircleIndicator.js
@@ -1,17 +1,13 @@
 define(["dojo/_base/declare","dojox/gfx","./BarLineIndicator"],
-  function(declare, gfx, BarLineIndicator) { 
-
-/*=====
-	BarLineIndicator = dojox.gauges.BarLineIndicator;
-=====*/
+  function(declare, gfx, BarLineIndicator) {
 
 return declare("dojox.gauges.BarCircleIndicator", [BarLineIndicator], {
 	// summary:
 	//		An indicator for the BarGauge that draws a circle at a position that corresponds to the
-	// 		indicator value. This indicator is mainly used to draw round ticks for the scale.
+	//		indicator value. This indicator is mainly used to draw round ticks for the scale.
 	
 	_getShapes: function(group){
-		// summary: 
+		// summary:
 		//		Override of dojox.gauges.BarLineIndicator._getShapes
 		var color = this.color ? this.color : 'black';
 		var strokeColor = this.strokeColor ? this.strokeColor : color;
diff --git a/dojox/gauges/BarGauge.js b/dojox/gauges/BarGauge.js
index d3c3caa..f269d0a 100644
--- a/dojox/gauges/BarGauge.js
+++ b/dojox/gauges/BarGauge.js
@@ -2,10 +2,6 @@ define(["dojo/_base/declare","dojo/_base/lang","dojo/_base/array","dojo/_base/ht
 		"./_Gauge","./BarLineIndicator", "dojo/dom-geometry"],
  function(declare, lang, arr, html, event, gfx, Gauge, BarLineIndicator, domGeometry) {
 
-/*=====
-	Gauge = dojox.gauges._Gauge;
-=====*/
-
 return declare("dojox.gauges.BarGauge", Gauge, {
 	// summary:
 	//		a bar graph built using the dojox.gfx package.
@@ -14,37 +10,37 @@ return declare("dojox.gauges.BarGauge", Gauge, {
 	//		using dojo.gfx (and thus either SVG or VML based on what is supported), this widget
 	//		builds a bar graph component, used to display numerical data in a familiar format.
 	//
-	// usage:
-	//		<script type="text/javascript">
-	//			require(["dojox/gauges/BarGauge"]);
-	//		</script>
-	//		...
-	//		<div 	dojoType="dojox.gauges.BarGauge"
-	//				id="testBarGauge"
-	//				barGaugeHeight="55"
-	//				dataY="25"
-	//				dataHeight="25"
-	//				dataWidth="225">
-	//		</div>
+	// example:
+	// |	<script type="text/javascript">
+	// |		require(["dojox/gauges/BarGauge"]);
+	// |	</script>
+	// |	...
+	// |	<div 	dojoType="dojox.gauges.BarGauge"
+	// |		id="testBarGauge"
+	// |		barGaugeHeight="55"
+	// |		dataY="25"
+	// |		dataHeight="25"
+	// |		dataWidth="225">
+	// |	</div>
 
 	// dataX: Number
-	// x position of data area (default 5)
+	//		x position of data area (default 5)
 	dataX: 5,
 
 	// dataY: Number
-	// y position of data area (default 5)
+	//		y position of data area (default 5)
 	dataY: 5,
 
 	// dataWidth: Number
-	// width of data area (default is bar graph width - 10)
+	//		width of data area (default is bar graph width - 10)
 	dataWidth: 0,
 
 	// dataHeight: Number
-	// height of data area (default is bar graph width - 10)
+	//		height of data area (default is bar graph width - 10)
 	dataHeight: 0,
 
 	// _defaultIndicator: Object
-	// 		override of dojox.gauges._Gauge._defaultIndicator
+	//		override of dojox.gauges._Gauge._defaultIndicator
 	_defaultIndicator: BarLineIndicator,
 
 	startup: function(){
@@ -67,8 +63,8 @@ return declare("dojox.gauges.BarGauge", Gauge, {
 		// summary:
 		//		This is a helper function used to determine the position that represents
 		//		a given value on the bar graph
-		// value:	Number
-		//			A value to be converted to a position for this bar graph.
+		// value: Number
+		//		A value to be converted to a position for this bar graph.
 
 		return this.dataX + Math.floor((value - this.min)/(this.max - this.min)*this.dataWidth);
 	},
@@ -77,8 +73,8 @@ return declare("dojox.gauges.BarGauge", Gauge, {
 		// summary:
 		//		This is a helper function used to determine the value represented by
 		//		a position on the bar graph
-		// pos:		Number
-		//			A position to be converted to a value.
+		// pos:	Number
+		//		A position to be converted to a value.
 		return (pos - this.dataX)*(this.max - this.min)/this.dataWidth + this.min;
 	},
 
@@ -89,7 +85,7 @@ return declare("dojox.gauges.BarGauge", Gauge, {
 		//		Draws a range (colored area on the background of the gauge) 
 		//		based on the given arguments.
 		// group:
-		//      The GFX group where the range must be drawn.
+		//		The GFX group where the range must be drawn.
 		// range:
 		//		A range is either a dojox.gauges.Range or an object
 		//		with similar parameters (low, high, hover, etc.).
@@ -134,8 +130,8 @@ return declare("dojox.gauges.BarGauge", Gauge, {
 	getRangeUnderMouse: function(/*Object*/e){
 		// summary:
 		//		Determines which range the mouse is currently over
-		// e:	Object
-		//			The event object as received by the mouse handling functions below.
+		// e: Object
+		//		The event object as received by the mouse handling functions below.
 		var range = null;
 		var pos = domGeometry.getContentBox(this.gaugeContent);
 		var x = e.clientX - pos.x;
@@ -152,8 +148,8 @@ return declare("dojox.gauges.BarGauge", Gauge, {
 
 	_dragIndicator: function(/*Object*/widget, /*Object*/ e){
 		// summary:
-		// Handles the dragging of an indicator to the event position, including moving/re-drawing
-		// get angle for mouse position
+		//		Handles the dragging of an indicator to the event position, including moving/re-drawing
+		//		get angle for mouse position
 		this._dragIndicatorAt(widget, e.pageX, e.pageY);
 		event.stop(e);
 	},
@@ -162,7 +158,7 @@ return declare("dojox.gauges.BarGauge", Gauge, {
 		
 		// summary:
 		//		Handles the dragging of an indicator, including moving/re-drawing
-		// get new value based on mouse position
+		//		get new value based on mouse position
 		var pos = domGeometry.position(widget.gaugeContent, true);
 		var xl = x - pos.x;
 		var value = widget._getValueForPosition(xl);
diff --git a/dojox/gauges/BarIndicator.js b/dojox/gauges/BarIndicator.js
index d62a447..c24cf57 100644
--- a/dojox/gauges/BarIndicator.js
+++ b/dojox/gauges/BarIndicator.js
@@ -1,9 +1,5 @@
 define(["dojo/_base/declare","dojo/_base/fx","dojo/_base/connect","dojo/_base/lang","./BarLineIndicator"],
-function(declare, fx, connect, lang, BarLineIndicator) { 
-
-/*=====
-	BarLineIndicator = dojox.gauges.BarLineIndicator;
-=====*/
+function(declare, fx, connect, lang, BarLineIndicator) {
 
 return declare("dojox.gauges.BarIndicator",[BarLineIndicator],{
 	
diff --git a/dojox/gauges/BarLineIndicator.js b/dojox/gauges/BarLineIndicator.js
index 43aa6b0..5105e7f 100644
--- a/dojox/gauges/BarLineIndicator.js
+++ b/dojox/gauges/BarLineIndicator.js
@@ -1,9 +1,5 @@
 define(["dojo/_base/declare","dojo/_base/fx","dojo/_base/connect","dojo/_base/lang", "dojox/gfx", "./_Indicator"], 
-  function(declare, fx, connect, lang, gfx, Indicator) { 
-
-/*=====
-	Indicator = dojox.gauges._Indicator;
-=====*/
+  function(declare, fx, connect, lang, gfx, Indicator) {
 
 return declare("dojox.gauges.BarLineIndicator",[Indicator],{
 	
@@ -46,7 +42,7 @@ return declare("dojox.gauges.BarLineIndicator",[Indicator],{
 		return shapes;
 	},
 	draw: function(/*dojox.gfx.Group*/group, /*Boolean?*/ dontAnimate){
-		// summary: 
+		// summary:
 		//		Override of dojox.gauges._Indicator.draw
 		// dontAnimate: Boolean
 		//		Indicates if the drawing should not be animated (vs. the default of doing an animation)
@@ -107,7 +103,7 @@ return declare("dojox.gauges.BarLineIndicator",[Indicator],{
 	},
 	
 	_move: function(/*Boolean?*/ dontAnimate){
-		// summary: 
+		// summary:
 		//		Moves this indicator (since it's already been drawn once)
 		// dontAnimate: Boolean
 		//		Indicates if the drawing should not be animated (vs. the default of doing an animation)
diff --git a/dojox/gauges/GlossyCircularGauge.js b/dojox/gauges/GlossyCircularGauge.js
index dc9fc7d..4d3bac5 100644
--- a/dojox/gauges/GlossyCircularGauge.js
+++ b/dojox/gauges/GlossyCircularGauge.js
@@ -1,10 +1,6 @@
 define(["dojo/_base/declare","dojo/_base/Color","./GlossyCircularGaugeBase"],
   function(declare, Color, GlossyCircularGaugeBase) {
 
-/*=====
-	GlossyCircularGaugeBase = dojox.gauges.GlossyCircularGaugeBase;
-=====*/
-
 return declare("dojox.gauges.GlossyCircularGauge", [GlossyCircularGaugeBase], {
 	// summary:
 	//		Represents a circular gauge with a glossy appearance.
diff --git a/dojox/gauges/GlossyCircularGaugeBase.js b/dojox/gauges/GlossyCircularGaugeBase.js
index ba066de..d3173ae 100644
--- a/dojox/gauges/GlossyCircularGaugeBase.js
+++ b/dojox/gauges/GlossyCircularGaugeBase.js
@@ -1,8 +1,6 @@
 define(["dojo/_base/declare","dojo/_base/lang","dojo/_base/connect","dojox/gfx","./AnalogGauge","./AnalogCircleIndicator","./TextIndicator","./GlossyCircularGaugeNeedle"],
 function(declare, lang, connect, gfx, AnalogGauge, AnalogCircleIndicator, TextIndicator, GlossyCircularGaugeNeedle) {
-/*=====
-	AnalogGauge = dojox.gauges.AnalogGauge;
-=====*/
+
 return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	// summary:
 	//		The base class for GlossyCircularGauge and GlossySemiCircularGauge.
@@ -17,33 +15,33 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	_needle: null,
 	
 	// _textIndicator: dojox.gauges.TextIndicator
-	// 		the text displaying the gauge's value
+	//		the text displaying the gauge's value
 	_textIndicator: null,
 	
 	_textIndicatorAdded: false,
 	
 	// _range: Object
-	// 		the range of this gauge
+	//		the range of this gauge
 	_range: null,
 	
 	// value: Number
-	// 		The value of the gauge.
+	//		The value of the gauge.
 	value: 0,
 	
 	// color: String
-	// 		The main color of the gauge.
+	//		The main color of the gauge.
 	color: 'black',
 	
 	// needleColor: Color
-	// 		The main color of the needle.
+	//		The main color of the needle.
 	needleColor: '#c4c4c4',
 	
 	// textIndicatorFont: String
-	// 		The font of the text indicator
+	//		The font of the text indicator
 	textIndicatorFont: "normal normal normal 20pt serif",
 	
 	// textIndicatorVisible: Boolean
-	// 		Indicates if the text indicator is visible			
+	//		Indicates if the text indicator is visible
 	textIndicatorVisible: true,
 	
 	// textIndicatorColor: Color
@@ -51,47 +49,47 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	textIndicatorColor: '#c4c4c4',
 	
 	// _majorTicksOffset: Number
-	// 		Distance, at design, from gauge's center to major ticks
+	//		Distance, at design, from gauge's center to major ticks
 	_majorTicksOffset: 130,
 	
 	// majorTicksInterval: Number
-	// 		Interval between major ticks
+	//		Interval between major ticks
 	majorTicksInterval: 10,
 	
 	// _majorTicksLength: Number
-	// 		Major tick size, at design
+	//		Major tick size, at design
 	_majorTicksLength: 5,
 	
 	// majorTicksColor: Color
-	// 		Color of major tick marks
+	//		Color of major tick marks
 	majorTicksColor: '#c4c4c4',
 	
 	// majorTicksLabelPlacement: String
-	// 		Placement of major tick labels
+	//		Placement of major tick labels
 	majorTicksLabelPlacement: 'inside',
 	
 	// _minorTicksOffset: Number
-	// 		Distance, at design, from gauge's center to minor ticks
+	//		Distance, at design, from gauge's center to minor ticks
 	_minorTicksOffset: 130,
 	
 	// minorTicksInterval: Number
-	// 		Interval between minor ticks
+	//		Interval between minor ticks
 	minorTicksInterval: 5,
 	
 	// _minorTicksLength: Number
-	// 		Minor tick size, at design
+	//		Minor tick size, at design
 	_minorTicksLength: 3,
 	
 	// minorTicksColor: Color
-	// 		Color of minor tick marks
+	//		Color of minor tick marks
 	minorTicksColor: '#c4c4c4',
 	
 	// noChange: Boolean
-	// 		Indicates if the gauge reacts to touch events
+	//		Indicates if the gauge reacts to touch events
 	noChange: false,
 	
 	// title: String
-	// 		The title displayed in the needle's tooltip
+	//		The title displayed in the needle's tooltip
 	title: "",
 	
 	// font: Object
@@ -99,7 +97,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	font: "normal normal normal 10pt serif",
 	
 	// scalePrecision: Number
-	// 		The precision for the formatting of numbers in the scale (default is 0)
+	//		The precision for the formatting of numbers in the scale (default is 0)
 	scalePrecision: 0,
 	
 	// textIndicatorPrecision: Number
@@ -208,10 +206,10 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	//*******************************************************************************************
 	
 	_setColorAttr: function(color){
-		// summary: 
+		// summary:
 		//		Sets the main color of the gauge
 		// color: String
-		//      The color		
+		//		The color
 		this.color = color ? color : 'black';
 		if (this._gaugeBackground && this._gaugeBackground.parent) 
 			this._gaugeBackground.parent.remove(this._gaugeBackground);
@@ -223,10 +221,10 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setNeedleColorAttr: function(color){
-		// summary: 
+		// summary:
 		//		Sets the main color of the needle
 		// color: String
-		//      The color
+		//		The color
 		this.needleColor = color;
 		if (this._needle){
 			this.removeIndicator(this._needle);
@@ -237,10 +235,10 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setTextIndicatorColorAttr: function(color){
-		// summary: 
+		// summary:
 		//		Sets the color of text indicator display the gauge's value
 		// color: String
-		//      The color		
+		//		The color
 		this.textIndicatorColor = color;
 		if (this._textIndicator){
 			this._textIndicator.color = this.textIndicatorColor;
@@ -249,7 +247,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setTextIndicatorFontAttr: function(font){
-		// summary: 
+		// summary:
 		//		Sets the font of the text indicator
 		// font: String
 		//		An string representing the font such as 'normal normal normal 10pt Helvetica,Arial,sans-serif'	
@@ -264,7 +262,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	setMajorTicksOffset: function(offset){
-		// summary: 
+		// summary:
 		//		Sets the distance from gauge's center to major ticks
 		this._majorTicksOffset = offset;
 		this._setMajorTicksProperty({
@@ -274,13 +272,13 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	getMajorTicksOffset: function(){
-		// summary: 
+		// summary:
 		//		Return the distance from gauge's center to major ticks
 		return this._majorTicksOffset;
 	},
 	
 	_setMajorTicksIntervalAttr: function(interval){
-		// summary: 
+		// summary:
 		//		Sets the interval between major ticks
 		this.majorTicksInterval = interval;
 		this._setMajorTicksProperty({
@@ -289,7 +287,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	setMajorTicksLength: function(length){
-		// summary: 
+		// summary:
 		//		Sets the size of the major ticks.
 		this._majorTicksLength = length;
 		this._setMajorTicksProperty({
@@ -299,13 +297,13 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	getMajorTicksLength: function(){
-		// summary: 
+		// summary:
 		//		Returns the size of the major ticks.
 		return this._majorTicksLength;
 	},
 	
 	_setMajorTicksColorAttr: function(color){
-		// summary: 
+		// summary:
 		//		Sets the color of the major ticks.
 		this.majorTicksColor = color;
 		this._setMajorTicksProperty({
@@ -314,7 +312,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setMajorTicksLabelPlacementAttr: function(placement){
-		// summary: 
+		// summary:
 		//		Sets the placement of labels relatively to major ticks.
 		// placement: String
 		//		'inside' or 'outside'
@@ -332,7 +330,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	setMinorTicksOffset: function(offset){
-		// summary: 
+		// summary:
 		//		Sets the distance from gauge's center to minor ticks
 		this._minorTicksOffset = offset;
 		this._setMinorTicksProperty({
@@ -342,13 +340,13 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	getMinorTicksOffset: function(){
-		// summary: 
+		// summary:
 		//		Returns the distance from gauge's center to minor ticks
 		return this._minorTicksOffset;
 	},
 	
 	_setMinorTicksIntervalAttr: function(interval){
-		// summary: 
+		// summary:
 		//		Sets the interval between minor ticks
 		this.minorTicksInterval = interval;
 		this._setMinorTicksProperty({
@@ -357,7 +355,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	setMinorTicksLength: function(length){
-		// summary: 
+		// summary:
 		//		Sets the size of the minor ticks.
 		this._minorTicksLength = length;
 		this._setMinorTicksProperty({
@@ -367,13 +365,13 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	getMinorTicksLength: function(){
-		// summary: 
+		// summary:
 		//		Return the size of the minor ticks.
 		return this._minorTicksLength;
 	},
 	
 	_setMinorTicksColorAttr: function(color){
-		// summary: 
+		// summary:
 		//		Sets the color of the minor ticks.
 		this.minorTicksColor = color;
 		this._setMinorTicksProperty({
@@ -411,7 +409,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setScalePrecisionAttr: function(value){
-		// summary: 
+		// summary:
 		//		Changes precision of the numbers in the scale of the gauge
 		// value: Number
 		//		The new value
@@ -422,7 +420,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setTextIndicatorPrecisionAttr: function(value){
-		// summary: 
+		// summary:
 		//		Changes precision of the numbers in the text indicator
 		// value: Number
 		//		The new value
@@ -433,7 +431,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setValueAttr: function(value){
-		// summary: 
+		// summary:
 		//		Changes the value of the gauge
 		// value: Number
 		//		The new value for the gauge.			
@@ -451,7 +449,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setNoChangeAttr: function(value){
-		// summary: 
+		// summary:
 		//		Indicates if the value of the gauge can be changed or not
 		// value: boolean
 		//		true indicates that the gauge's value cannot be changed	
@@ -461,7 +459,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setTextIndicatorVisibleAttr: function(value){
-		// summary: 
+		// summary:
 		//		Changes the visibility of the text indicator displaying the gauge's value.
 		// value: boolean
 		//		true to show the indicator, false to hide.
@@ -483,7 +481,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setTitleAttr: function(value){
-		// summary: 
+		// summary:
 		//		Sets the title displayed by the needle's tooltip .
 		// value: String
 		//		the title
@@ -495,7 +493,7 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setOrientationAttr: function(orientation){
-		// summary: 
+		// summary:
 		//		Sets the orientation of the gauge
 		// orientation: String
 		//		Either "clockwise" or "cclockwise"	
@@ -525,11 +523,10 @@ return declare("dojox.gauges.GlossyCircularGaugeBase", [AnalogGauge], {
 	},
 	
 	_setFontAttr: function(font){
-		// summary: 
+		// summary:
 		//		Sets the font of the gauge
 		// font: String
-		//		An string representing the font such as 'normal normal normal 10pt Helvetica,Arial,sans-serif'	
-		//
+		//		An string representing the font such as 'normal normal normal 10pt Helvetica,Arial,sans-serif'
 		
 		this.font = font;
 		this._font = gfx.splitFontString(font);
diff --git a/dojox/gauges/GlossyCircularGaugeNeedle.js b/dojox/gauges/GlossyCircularGaugeNeedle.js
index 8ff67d6..7f9325f 100644
--- a/dojox/gauges/GlossyCircularGaugeNeedle.js
+++ b/dojox/gauges/GlossyCircularGaugeNeedle.js
@@ -1,9 +1,6 @@
 define(["dojo/_base/declare","dojo/_base/Color" ,"./AnalogIndicatorBase"],
   function(declare, Color, AnalogIndicatorBase) {
 
-/*=====
-	AnalogIndicatorBase = dojox.gauges.AnalogIndicatorBase;
-=====*/
 
 return declare("dojox.gauges.GlossyCircularGaugeNeedle", [AnalogIndicatorBase], {
 	// summary:
@@ -19,7 +16,7 @@ return declare("dojox.gauges.GlossyCircularGaugeNeedle", [AnalogIndicatorBase],
 	interactionMode: "gauge",
 	
 	// color: String
-	// The color of the indicator.
+	//		The color of the indicator.
 	color: '#c4c4c4',
 	
 	_getShapes: function(group){
diff --git a/dojox/gauges/GlossyHorizontalGauge.js b/dojox/gauges/GlossyHorizontalGauge.js
index eec7c32..4ec447a 100644
--- a/dojox/gauges/GlossyHorizontalGauge.js
+++ b/dojox/gauges/GlossyHorizontalGauge.js
@@ -1,13 +1,6 @@
 define(["dojo/_base/declare","dojo/_base/connect","dojo/_base/lang","dojo/_base/Color","dojox/gfx","./BarGauge","./BarCircleIndicator","./GlossyHorizontalGaugeMarker"],
   function(declare, connect, lang, Color, gfx, BarGauge, BarCircleIndicator, GlossyHorizontalGaugeMarker) {
 
-
-var NumberUtils
-
-/*=====
-	BarGauge = dojox.gauges.BarGauge;
-=====*/
-
 return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	// summary:
 	//		Represents an horizontal bar gauge with a glossy appearance.
@@ -38,55 +31,55 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	_defaultIndicator: BarCircleIndicator,
 	
 	// color: String
-	// 		The main color of the gauge.
+	//		The main color of the gauge.
 	color: 'black',
 	
 	// needleColor: Color
-	// 		The main color of the needle.
+	//		The main color of the needle.
 	markerColor: 'black',
 	
 	// majorTicksInterval: Number
-	// 		Interval between major ticks
+	//		Interval between major ticks
 	majorTicksInterval: 10,
 	
 	// _majorTicksLength: Number
-	// 		Major tick size, at design
+	//		Major tick size, at design
 	_majorTicksLength: 10,
 	
 	// majorTicksColor: Color
-	// 		Color of major tick marks
+	//		Color of major tick marks
 	majorTicksColor: '#c4c4c4',
 	
 	// minorTicksInterval: Number
-	// 		Interval between minor ticks
+	//		Interval between minor ticks
 	minorTicksInterval: 5,
 	
 	// _minorTicksLength: Number
-	// 		Minor tick size, at design
+	//		Minor tick size, at design
 	_minorTicksLength: 6,
 	
 	// minorTicksColor: Color
-	// 		Color of minor tick marks
+	//		Color of minor tick marks
 	minorTicksColor: '#c4c4c4',
 	
 	// value: Number
-	// 		The value of the gauge.
+	//		The value of the gauge.
 	value: 0,
 	
 	// noChange: Boolean
-	// 		Indicates if the gauge reacts to touch events
+	//		Indicates if the gauge reacts to touch events
 	noChange: false,
 	
 	// title: String
-	// 		The title displayed in the needle's tooltip
+	//		The title displayed in the needle's tooltip
 	title: "",
 	
 	// font: Object
-	// 		The font of the gauge
+	//		The font of the gauge
 	font: "normal normal normal 10pt serif",
 	
 	// scalePrecision: Number
-	// 		The precision for the formatting of numbers in the scale (default is 0)
+	//		The precision for the formatting of numbers in the scale (default is 0)
 	scalePrecision: 0,
 	
 	_font: null,
@@ -167,7 +160,7 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	_layoutGauge: function(){
-		// summary: 
+		// summary:
 		//		Layout the gauge elements depending on the various parameters (size, font, tick length..)
 		
 		if (!this._gaugeStarted) 
@@ -213,7 +206,7 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	_computeDataRectangle: function(){
-		// summary: 
+		// summary:
 		//		Computes the rectangle that defines the data area of the gauge.
 		
 		
@@ -240,13 +233,13 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	_getBorderWidth: function(){
-		// summary: 
+		// summary:
 		//		Computes the width of the border surrounding the gauge
 		return Math.max(this._minBorderWidth, Math.min(this._maxBorderWidth, this._maxBorderWidth * this.height / this._designHeight));
 	},
 	
 	drawBackground: function(group){
-		// summary: 
+		// summary:
 		//		Draws the background of the gauge
 		// group: dojox.gfx.Group
 		//		The GFX group where the background must be drawn
@@ -373,10 +366,10 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	//*******************************************************************************************
 	
 	_setColorAttr: function(color){
-		// summary: 
+		// summary:
 		//		Sets the main color of the gauge
 		// color: String
-		//      The color		
+		//		The color
 		this.color = color ? color : 'black';
 		if (this._gaugeBackground && this._gaugeBackground.parent) 
 			this._gaugeBackground.parent.remove(this._gaugeBackground);
@@ -386,10 +379,10 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	_setMarkerColorAttr: function(color){
-		// summary: 
+		// summary:
 		//		Sets the main color of the marker
 		// color: String
-		//      The color
+		//		The color
 		this.markerColor = color;
 		if (this._needle){
 			this.removeIndicator(this._needle);
@@ -400,7 +393,7 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	_setMajorTicksIntervalAttr: function(interval){
-		// summary: 
+		// summary:
 		//		Sets the interval between major ticks
 		this.majorTicksInterval = interval;
 		this._setMajorTicksProperty({
@@ -409,7 +402,7 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	setMajorTicksLength: function(length){
-		// summary: 
+		// summary:
 		//		Sets the size of the major ticks.
 		this._majorTicksLength = length;
 		this._layoutGauge();
@@ -418,13 +411,13 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	getMajorTicksLength: function(){
-		// summary: 
+		// summary:
 		//		Returns the size of the major ticks.
 		return this._majorTicksLength;
 	},
 	
 	_setMajorTicksColorAttr: function(color){
-		// summary: 
+		// summary:
 		//		Sets the color of the major ticks.
 		this.majorTicksColor = color;
 		this._setMajorTicksProperty({
@@ -441,7 +434,7 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	_setMinorTicksIntervalAttr: function(interval){
-		// summary: 
+		// summary:
 		//		Sets the interval between minor ticks
 		this.minorTicksInterval = interval;
 		this._setMinorTicksProperty({
@@ -450,7 +443,7 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	setMinorTicksLength: function(length){
-		// summary: 
+		// summary:
 		//		Sets the size of the minor ticks.
 		this._minorTicksLength = length;
 		this._layoutGauge();
@@ -458,13 +451,13 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	getMinorTicksLength: function(){
-		// summary: 
+		// summary:
 		//		Gets the size of the minor ticks.
 		return this._minorTicksLength;
 	},
 	
 	_setMinorTicksColorAttr: function(color){
-		// summary: 
+		// summary:
 		//		Sets the color of the minor ticks.
 		this.minorTicksColor = color;
 		this._setMinorTicksProperty({
@@ -501,7 +494,7 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	_setValueAttr: function(value){
-		// summary: 
+		// summary:
 		//		Changes the value of the gauge
 		// value: Number
 		//		The new value for the gauge.			
@@ -519,7 +512,7 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	_setScalePrecisionAttr: function(value){
-		// summary: 
+		// summary:
 		//		Changes precision of the numbers in the scale of the gauge
 		// value: Number
 		//		The new value
@@ -528,7 +521,7 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	_setNoChangeAttr: function(value){
-		// summary: 
+		// summary:
 		//		Indicates if the value of the gauge can be changed or not
 		// value: boolean
 		//		true indicates that the gauge's value cannot be changed	
@@ -538,7 +531,7 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	_setTitleAttr: function(value){
-		// summary: 
+		// summary:
 		//		Sets the title displayed by the needle's tooltip .
 		// value: String
 		//		the title
@@ -550,13 +543,10 @@ return declare("dojox.gauges.GlossyHorizontalGauge", [BarGauge], {
 	},
 	
 	_setFontAttr: function(font){
-		// summary: 
-		//		Sets the font of the gauge
-		// summary: 
+		// summary:
 		//		Sets the font of the gauge
 		// font: String
 		//		An string representing the font such as 'normal normal normal 10pt Helvetica,Arial,sans-serif'	
-		// 
 		
 		this.font = font;
 		this._font = gfx.splitFontString(font);
diff --git a/dojox/gauges/GlossyHorizontalGaugeMarker.js b/dojox/gauges/GlossyHorizontalGaugeMarker.js
index d83b7db..c83b118 100644
--- a/dojox/gauges/GlossyHorizontalGaugeMarker.js
+++ b/dojox/gauges/GlossyHorizontalGaugeMarker.js
@@ -1,10 +1,6 @@
 define(["dojo/_base/declare","dojo/_base/Color","./BarLineIndicator"],
   function(declare, Color, BarLineIndicator) {
 
-/*=====
-	BarLineIndicator = dojox.gauges.BarLineIndicator;
-=====*/
-
 return declare("dojox.gauges.GlossyHorizontalGaugeMarker", [BarLineIndicator], {
 	// summary:
 	//		The marker for the dojox.gauges.GlossyHorizontalGauge.
@@ -14,15 +10,15 @@ return declare("dojox.gauges.GlossyHorizontalGaugeMarker", [BarLineIndicator], {
 	//		Since the needle is created by the gauges class, you do not have to use this class directly.
 	
 	// interactionMode : String
-	// 		The interactionMode can have two values : "indicator" (the default) or "gauge".
+	//		The interactionMode can have two values : "indicator" (the default) or "gauge".
 	//	 	When the value is "indicator", the user must click on the indicator to change the value.
-	// 		When the value is "gauge", the user can click on the gauge to change the indicator value.
-	// 		If a gauge contains several indicators with the indicatorMode property set to "gauge", then
-	// 		only the first indicator will be moved when clicking the gauge.
+	//		When the value is "gauge", the user can click on the gauge to change the indicator value.
+	//		If a gauge contains several indicators with the indicatorMode property set to "gauge", then
+	//		only the first indicator will be moved when clicking the gauge.
 	interactionMode: "gauge",
 	
 	// color: String
-	// 		The color of the indicator.
+	//		The color of the indicator.
 	color: 'black',
 	
 	_getShapes: function(group){
diff --git a/dojox/gauges/GlossySemiCircularGauge.js b/dojox/gauges/GlossySemiCircularGauge.js
index 827c4e4..8d23ecb 100644
--- a/dojox/gauges/GlossySemiCircularGauge.js
+++ b/dojox/gauges/GlossySemiCircularGauge.js
@@ -1,10 +1,6 @@
 define(["dojo/_base/declare","dojo/_base/Color","./GlossyCircularGaugeBase"],
   function(declare, Color, GlossyCircularGaugeBase) {
 
-/*=====
-	GlossyCircularGaugeBase = dojox.gauges.GlossyCircularGaugeBase;
-=====*/
-
 return declare("dojox.gauges.GlossySemiCircularGauge", [GlossyCircularGaugeBase], {
 	// summary:
 	//		Represents a semi circular gauge with a glossy appearance.
@@ -45,7 +41,7 @@ return declare("dojox.gauges.GlossySemiCircularGauge", [GlossyCircularGaugeBase]
 	
 
 	constructor: function(){
-		// summary: 
+		// summary:
 		//		Creates a new GlossySemiCircularGauge
 		this.min = 0;
 		this.max = 100;
@@ -54,7 +50,7 @@ return declare("dojox.gauges.GlossySemiCircularGauge", [GlossyCircularGaugeBase]
 	},
 
 	drawBackground: function(group){
-		// summary: 
+		// summary:
 		//		Draws the background of the gauge
 		// group: dojox.gfx.Group
 		//		The GFX group where the background must be drawn
@@ -149,7 +145,7 @@ return declare("dojox.gauges.GlossySemiCircularGauge", [GlossyCircularGaugeBase]
 	
 	
 	drawForeground: function(group){
-		// summary: 
+		// summary:
 		//		Draws the foreground of the gauge
 		// group: dojox.gfx.Group
 		//		The GFX group where the foreground must be drawn
diff --git a/dojox/gauges/Range.js b/dojox/gauges/Range.js
index 030201f..f30e827 100644
--- a/dojox/gauges/Range.js
+++ b/dojox/gauges/Range.js
@@ -1,17 +1,11 @@
 define(["dojo/_base/declare","dijit/_Widget"], 
   function(declare, Widget) {
-
-/*=====
-	Widget = dijit._Widget;
-=====*/	
 	
 return declare("dojox.gauges.Range", [Widget], {
 	// summary:
 	//		a range to be used in a _Gauge
-	//
 	// description:
 	//		a range widget, which has given properties.  drawn by a _Gauge.
-	//
 	// example:
 	//	|	<script type="text/javascript">
 	//	|		require(["dojox/gauges/AnalogGauge"]);
@@ -43,27 +37,27 @@ return declare("dojox.gauges.Range", [Widget], {
 	//	|	</div>
 	
 	// low: Number
-	// 		the low value of the range
+	//		the low value of the range
 	low: 0,
 	
 	// high: Number
-	// 		the high value of the range
+	//		the high value of the range
 	high: 0,
 	
 	// hover: String
-	// 		the text to put in the tooltip for the gauge
+	//		the text to put in the tooltip for the gauge
 	hover: '',
 	
 	// color: Object
-	// 		the color of the range.  This must be an object of one of two forms:
-	// 		{'color': 'color-name'}
-	// 		OR
-	// 		(for a gradient:)
-	// 		{'type': 'linear', 'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#E0E0E0'}] }
+	//		the color of the range.  This must be an object of one of two forms:
+	//		{'color': 'color-name'}
+	//		OR
+	//		(for a gradient:)
+	//		{'type': 'linear', 'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#E0E0E0'}] }
 	color: null,
 	
 	// size: Number
-	// 		for a circular gauge (such as an AnalogGauge), this dictates the size of the arc
+	//		for a circular gauge (such as an AnalogGauge), this dictates the size of the arc
 	size: 0,
 
 	startup: function(){
diff --git a/dojox/gauges/TextIndicator.js b/dojox/gauges/TextIndicator.js
index 90442b8..9d7fa80 100644
--- a/dojox/gauges/TextIndicator.js
+++ b/dojox/gauges/TextIndicator.js
@@ -1,9 +1,5 @@
 define(["dojo/_base/declare","./_Indicator"],
-  function(declare, Indicator) { 
-
-/*=====
-	Indicator = dojox.gauges._Indicator;
-=====*/
+  function(declare, Indicator) {
 
 return declare("dojox.gauges.TextIndicator", [Indicator], {
 	// summary:
@@ -11,19 +7,19 @@ return declare("dojox.gauges.TextIndicator", [Indicator], {
 	
 	
 	// x: Number
-	// 		The x coordinate of the indicator
+	//		The x coordinate of the indicator
 	x: 0,
 	
 	// y: Number
-	// 		The y coordinate of the indicator
+	//		The y coordinate of the indicator
 	y: 0,
 	
 	// align: String
-	// 		The horizontal alignment of the text, the value can be 'middle' (the default), 'left' or 'right'
+	//		The horizontal alignment of the text, the value can be 'middle' (the default), 'left' or 'right'
 	align: 'middle',
 	
 	// fixedPrecision: Boolean
-	// 		Indicates that the number is displayed in fixed precision or not (precision is defined by the 'precision' property (default is true).
+	//		Indicates that the number is displayed in fixed precision or not (precision is defined by the 'precision' property (default is true).
 	fixedPrecision: true,
 	
 	// precision: Number
@@ -31,7 +27,7 @@ return declare("dojox.gauges.TextIndicator", [Indicator], {
 	precision: 0,
 	
 	draw: function(group, /*Boolean?*/ dontAnimate){
-		// summary: 
+		// summary:
 		//		Override of dojox.gauges._Indicator.draw
 		var v = this.value;
 		
diff --git a/dojox/gauges/_Gauge.js b/dojox/gauges/_Gauge.js
index 4bb8398..997e5fa 100644
--- a/dojox/gauges/_Gauge.js
+++ b/dojox/gauges/_Gauge.js
@@ -1,6 +1,9 @@
-define(["dojo/_base/declare","dojo/_base/lang","dojo/_base/html","dojo/_base/array","dojo/_base/event",
+define(["dojo/_base/kernel", "dojo/_base/declare","dojo/_base/lang","dojo/_base/html","dojo/_base/array","dojo/_base/event",
 		"dojo/_base/connect","dojo/dom-construct", "dijit/_Widget", "dojox/gfx", "./Range", "dojo/fx/easing"], 
-  function(declare, lang, html, arr, event, connect, dom, Widget, gfx, Range) {
+  function(kernel, declare, lang, html, arr, event, connect, dom, Widget, gfx, Range) {
+
+  kernel.deprecated("dojox.gauges", "Use the new extensible dojox.dgauges framework instead", "2.0");
+
 
 	var _tooltipModule =  0;
 	var _numberModule =  0;
@@ -28,50 +31,51 @@ return declare("dojox.gauges._Gauge",[Widget],{
 	height: 0,
 
 	// background: Object
-	// 		The color of the background.  This must be an object of one of two forms:
-	// 		{'color': 'color-name'}
-	// 		OR
-	// 		(for a gradient:)
-	// 		{'type': 'linear', 'x1': 0, 'x2': 0, 'y1': 0, 'y2': 200, 'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#E0E0E0'}] }
+	//		The color of the background.  This must be an object of one of two forms:
+	//		{'color': 'color-name'}
+	//		OR
+	//		(for a gradient:)
+	//		{'type': 'linear', 'x1': 0, 'x2': 0, 'y1': 0, 'y2': 200, 'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#E0E0E0'}] }
 	background: null,
 
 	// image: String
-	// 		Background image for gauge (default is no image)
+	//		Background image for gauge (default is no image)
 	image: null,
 
 	// useRangeStyles: Number
-	// 		Indicates whether to use given css classes (dojoxGaugeRangeXX)
-	// 		to determine the color (and other style attributes?) of the ranges
-	// 		this value should be the number of dojoxGaugeRange classes that are
-	// 		defined, starting at dojoxGaugeRange1 (0 indicates falling to default
-	// 		hardcoded colors)
+	//		Indicates whether to use given css classes (dojoxGaugeRangeXX)
+	//		to determine the color (and other style attributes?) of the ranges
+	//		this value should be the number of dojoxGaugeRange classes that are
+	//		defined, starting at dojoxGaugeRange1 (0 indicates falling to default
+	//		hardcoded colors)
 	useRangeStyles: 0,
 
 	// useTooltip: Boolean
-	// 		Indicates whether tooltips should be displayed for ranges, indicators, etc.
+	//		Indicates whether tooltips should be displayed for ranges, indicators, etc.
 	useTooltip: true,
 	
 	// majorTicks: Object
-	// 		An object representing the tick marks that should be added to the gauge. Major tick marks have a text label
-	// 		indicating the value.  The object can have the following attributes (required are marked with a *):
+	//		An object representing the tick marks that should be added to the gauge. Major tick marks have a text label
+	//		indicating the value.  The object can have the following attributes (required are marked with a *):
+	//
 	//		- offset: the distance from the 'center' of the gauge.  Used differently for Analog vs. Bar
 	//		- width: The width of the mark
 	//		- length: The length of the mark
 	//		- interval: The interval the ticks should be added on
 	//		- color: The color of the mark and text
 	//		- font: an object with any/all of the following parameters:
-	//			{family: "Helvetica", style: "italic", variant: 'small-caps', weight: 'bold', size: "18pt"}
+	// |	{family: "Helvetica", style: "italic", variant: 'small-caps', weight: 'bold', size: "18pt"}
 	majorTicks: null,
 	
 	// minorTicks: Object
-	// 		An object of the same format as majorTicks, indicating where the minor (label-less) marks should be placed
-	// 		The font parameter is ignored if provided since minor tick marks have no text label.
+	//		An object of the same format as majorTicks, indicating where the minor (label-less) marks should be placed
+	//		The font parameter is ignored if provided since minor tick marks have no text label.
 	minorTicks: null,
 
 	// _defaultIndicator: Object
-	// 		Should be overridden by any extending classes and used to indicate what the 'default' indicator is.
-	// 		This object is used as the indicator when creating tick marks or when an anonymous object is passed into 
-	// 		addIndicator.
+	//		Should be overridden by any extending classes and used to indicate what the 'default' indicator is.
+	//		This object is used as the indicator when creating tick marks or when an anonymous object is passed into
+	//		addIndicator.
 	_defaultIndicator: null,
 
 	// defaultColors: Array
@@ -85,22 +89,22 @@ return declare("dojox.gauges._Gauge",[Widget],{
 					[0xDD,0xEE,0xFF,1]],
 	
 	// min: Number
-	// 		The minimum value of the gauge.  Normally not set explicitly, as it will be determined by
-	// 		the ranges that are added.
+	//		The minimum value of the gauge.  Normally not set explicitly, as it will be determined by
+	//		the ranges that are added.
 	min: null,
 	
 	// max: Number
-	// 		The maximum value of the gauge.  Normally not set explicitly, as it will be determined by
-	// 		the ranges that are added.
+	//		The maximum value of the gauge.  Normally not set explicitly, as it will be determined by
+	//		the ranges that are added.
 	max: null,
 	
 	// surface: Object
-	// 		The GFX surface that the shapes are drawn on.  Can be accessed/used by indicators to draw themselves
+	//		The GFX surface that the shapes are drawn on.  Can be accessed/used by indicators to draw themselves
 	surface: null,
 
 	// hideValues: Boolean
-	// 		Indicates whether the text boxes showing the value of the indicator (as text
-	// 		content) should be hidden or shown.  Default is not hidden, aka shown.
+	//		Indicates whether the text boxes showing the value of the indicator (as text
+	//		content) should be hidden or shown.  Default is not hidden, aka shown.
 	hideValues: false,
 
 	// internal data
@@ -175,7 +179,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 	},
 	
 	buildRendering: function(){
-		// summary: 
+		// summary:
 		//		Overrides _Widget.buildRendering
 		var n = this.domNode = this.srcNodeRef ? this.srcNodeRef: dom.create("div");
 		this.gaugeContent = dom.create("div", {
@@ -192,7 +196,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 	},
 
 	_setTicks: function(/*Object*/ oldTicks, /*Object*/ newTicks, /*Boolean*/ major){
-		// summary: 
+		// summary:
 		//		internal method used to clear existing tick marks, then add new ones
 		var i;
 		if (oldTicks && lang.isArray(oldTicks._ticks)){
@@ -234,7 +238,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 	},
 	
 	_isScaleCircular: function(){
-		// summary: 
+		// summary:
 		//		Internal method to check if the scale is fully circular
 		return false;
 	},
@@ -376,10 +380,9 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		//		as the original background argument.
 		// background: Object
 		//		An object in one of the two forms:
-		//			{'color': 'color-name'}
-		//				OR
-		//			(for a gradient:)
-		//			{'type': 'linear', 'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#E0E0E0'}] }
+		// |		{'color': 'color-name'}
+		//		OR (for a gradient:)
+		// |		{'type': 'linear', 'colors': [{offset: 0, color:'#C0C0C0'}, {offset: 1, color: '#E0E0E0'}] }
 		//		If background is null or undefined, this will set the fill to this._backgroundDefault
 		if(!background){ background = this._backgroundDefault; }
 		this.background = background.color || background;
@@ -539,22 +542,22 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		//		This function is used draw text onto the gauge.  The text object
 		//		is also returned by the function so that may be removed later
 		//		by calling removeText
-		// group:   dojox.gfx.Group
-		//          The GFX Group where the text will be added.
-		// txt:		String
-		//			The text to be drawn
-		// x:		Number
-		//			The x coordinate at which to place the text
-		// y:		Number
-		//			The y coordinate at which to place the text
-		// align?:	String
-		//			Indicates how to align the text
-		//			Valid value is 'right', otherwise text is left-aligned
-		// color?:	String
-		//			Indicates the color of the text
-		// font?:	Object
-		//			A font object, generally of the following format:
-		//			{family: "Helvetica", style: "italic", variant: 'small-caps', weight: 'bold', size: "18pt"}
+		// group: dojox/gfx/Group
+		//		The GFX Group where the text will be added.
+		// txt:	String
+		//		The text to be drawn
+		// x: Number
+		//		The x coordinate at which to place the text
+		// y: Number
+		//		The y coordinate at which to place the text
+		// align: String?
+		//		Indicates how to align the text
+		//		Valid value is 'right', otherwise text is left-aligned
+		// color: String?
+		//		Indicates the color of the text
+		// font: Object?
+		//		A font object, generally of the following format:
+		//		{family: "Helvetica", style: "italic", variant: 'small-caps', weight: 'bold', size: "18pt"}
 
 		var t = group.createText({x: x, y: y, text: txt, align: align});
 		t.setFill(color ? color: 'black');
@@ -565,7 +568,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 	removeText:function(/*String*/t){
 		// summary:
 		//		Removes a text element from the gauge.
-		// t:	String
+		// t: String
 		//		The text to remove.
 		if (t.parent)
 	    	t.parent.remove(t);
@@ -574,7 +577,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 	updateTooltip: function(/*String*/txt, /*Event*/ e){
 		// summary:
 		//		Updates the tooltip for the gauge to display the given text.
-		// txt:		String
+		// txt:	String
 		//		The text to put in the tooltip.
 	
 		if (this.useTooltip) {
@@ -596,7 +599,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		// summary:
 		//		This is an internal handler used by the gauge to support 
 		//		hover text
-		// e:	Object
+		// e: Object
 		//		The event object
 		
 		if (this.image && this.image.overlay){
@@ -634,7 +637,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		// summary:
 		//		This is an internal handler used by the gauge to support using
 		//		the mouse to show the tooltips
-		// e:	Object
+		// e: Object
 		//		The event object
 			
 		if (this.useTooltip) {
@@ -657,7 +660,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		// summary:
 		//		This is an internal handler used by the gauge to support using
 		//		the mouse to move indicators
-		// e:	Object
+		// e: Object
 		//		The event object
 		var indicator = this._getInteractiveIndicator();
 		if (indicator){
@@ -669,7 +672,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		// summary:
 		//		This is an internal handler used by the gauge to support using
 		//		the mouse to drag an indicator to modify it's value
-		// e:	Object
+		// e: Object
 		//		The event object
 		
 		if(this._drag){
@@ -682,7 +685,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		// summary:
 		//		This is an internal handler used by the gauge to support using
 		//		the mouse to drag an indicator to modify it's value
-		// e:	Object
+		// e: Object
 		//		The event object
 		this._drag = null;
 		
@@ -698,7 +701,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		//		This is an internal handler used by the gauge to support using
 		//		the mouse to drag an indicator to modify it's value
 		// indicator: _Indicator 
-		//      The indicator object
+		//		The indicator object
 		// e:Object
 		//		The event object
 		
@@ -719,8 +722,8 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		//		This is an internal handler used by the gauge to support using
 		//		the mouse to drag an indicator to modify it's value
 		// indicator: _Indicator 
-		//      The indicator object
-		// e:	Object
+		//		The indicator object
+		// e: Object
 		//		The event object	
 		if (this.useTooltip && !this._drag){
 			
@@ -745,8 +748,8 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		//		This is an internal handler used by the gauge to support using
 		//		the mouse to drag an indicator to modify it's value
 		// indicator: _Indicator 
-		//      The indicator object
-		// e:	Object
+		//		The indicator object
+		// e: Object
 		//		The event object
 		this._hideTooltip();
 		this.gaugeContent.style.cursor = 'pointer';
@@ -784,8 +787,8 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		//		This is an internal handler used by the gauge to support using
 		//		touch events to drag an indicator to modify it's value
 		// indicator: _Indicator 
-		//      The indicator object
-		// e:	Object
+		//		The indicator object
+		// e: Object
 		//		The event object
 		if (!indicator.noChange){
 			this._drag = indicator;
@@ -797,7 +800,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		// summary:
 		//		This is an internal handler used by the gauge to support using
 		//		touch events to drag an indicator to modify it's value
-		// e:	Object
+		// e: Object
 		//		The touch event object
 		this._drag = this._getInteractiveIndicator();
 		this.handleTouchMove(e); //drag indicator to touch position
@@ -807,7 +810,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		// summary:
 		//		This is an internal handler used by the gauge to support using
 		//		touch events to drag an indicator to modify it's value
-		// e:	Object
+		// e: Object
 		//		The touch e object	
 		if (this._drag){
 			this._drag = null;
@@ -819,7 +822,7 @@ return declare("dojox.gauges._Gauge",[Widget],{
 		// summary:
 		//		This is an internal handler used by the gauge to support using
 		//		touch events to drag an indicator to modify it's value
-		// e:	Object
+		// e: Object
 		//		The touch event object
 		
 		if (this._drag && !this._drag.noChange){
diff --git a/dojox/gauges/_Indicator.js b/dojox/gauges/_Indicator.js
index b684ee1..0c652a5 100644
--- a/dojox/gauges/_Indicator.js
+++ b/dojox/gauges/_Indicator.js
@@ -1,10 +1,6 @@
 define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/fx","dojo/_base/html","dojo/_base/connect","dijit/_Widget","dojo/dom-construct", "dojo/dom-class"], 
 function(lang,declare,fx,html,connect,Widget,dom,domClass) {
 
-/*=====
-	Widget = dijit._Widget;
-=====*/
-
 return declare("dojox.gauges._Indicator",[Widget],{
 	// summary:
 	//		An indicator to be used in a gauge
@@ -41,20 +37,20 @@ return declare("dojox.gauges._Indicator",[Widget],{
 	//	|	</div>
 
 	// value: Number
-	// 		The value (on the gauge) that this indicator should be placed at
+	//		The value (on the gauge) that this indicator should be placed at
 	value: 0,
 
 	// type: String
-	// 		The type of indicator to draw.  Varies by gauge type.  Some examples include
-	// "line", "arrow", and "bar"
+	//		The type of indicator to draw.  Varies by gauge type.  Some examples include
+	//		"line", "arrow", and "bar"
 	type: '',
 
 	// color: String
-	// 		The color of the indicator.
+	//		The color of the indicator.
 	color: 'black',
 	
 	// strokeColor: String
-	// 		The color to stroke the outline of the indicator.
+	//		The color to stroke the outline of the indicator.
 	strokeColor: '',
 
 	// label: String
@@ -62,60 +58,60 @@ return declare("dojox.gauges._Indicator",[Widget],{
 	label: '',
 
 	// font: Object
-	// 		The font for the indicator. The font is enerally in a format similar to:
-	// 		{family: "Helvetica", weight: "bold", style: "italic", size: "18pt", rotated: true}
+	//		The font for the indicator. The font is enerally in a format similar to:
+	//		{family: "Helvetica", weight: "bold", style: "italic", size: "18pt", rotated: true}
 	font: {family: "sans-serif", size: "12px"},
 
 	// length: Number
-	// 		The length of the indicator.  In the above example, the radius of the AnalogGauge
-	// 		is 125, but the length of the indicator is 135, meaning it would project beyond
-	// 		the edge of the AnalogGauge
+	//		The length of the indicator.  In the above example, the radius of the AnalogGauge
+	//		is 125, but the length of the indicator is 135, meaning it would project beyond
+	//		the edge of the AnalogGauge
 	length: 0,
 
 	// width: Number
-	// 		The width of the indicator.
+	//		The width of the indicator.
 	width: 0,
 
 	// offset: Number
-	// 		The offset of the indicator
+	//		The offset of the indicator
 	offset: 0,
 
 	// hover: String
-	// 		The string to put in the tooltip when this indicator is hovered over.
+	//		The string to put in the tooltip when this indicator is hovered over.
 	hover: '',
 
 	// front: boolean
-	// 		Keep this indicator at the front
+	//		Keep this indicator at the front
 	front: false,
 
 	// onDragMove: String
-	// 		The function to call when this indicator is moved by dragging.
+	//		The function to call when this indicator is moved by dragging.
 	//		onDragMove: '',
 
 	// easing: String|Object
-	// 		indicates the easing function to be used when animating the of an indicator.
+	//		indicates the easing function to be used when animating the of an indicator.
 	easing: fx._defaultEasing,
 
 	// duration: Number
-	// 		indicates how long an animation of the indicator should take
+	//		indicates how long an animation of the indicator should take
 	duration: 1000,
 
 	// hideValues: Boolean
-	// 		Indicates whether the text boxes showing the value of the indicator (as text
-	// 		content) should be hidden or shown.  Default is not hidden, aka shown.
+	//		Indicates whether the text boxes showing the value of the indicator (as text
+	//		content) should be hidden or shown.  Default is not hidden, aka shown.
 	hideValue: false,
 
 	// noChange: Boolean
-	// 		Indicates whether the indicator's value can be changed.  Useful for
-	// 		a static target indicator.  Default is false (that the value can be changed).
+	//		Indicates whether the indicator's value can be changed.  Useful for
+	//		a static target indicator.  Default is false (that the value can be changed).
 	noChange: false,
 
 	// interactionMode: String
-	// 		The interactionMode can have two values: "indicator" (the default) or "gauge".
-	// 		When the value is "indicator", the user must click on the indicator to change the value.
-	// 		When the value is "gauge", the user can click on the gauge to change the indicator value.
-	// 		If a gauge contains several indicators with the indicatorMode property set to "gauge", then
-	// 		only the first indicator will be moved when clicking the gauge.
+	//		The interactionMode can have two values: "indicator" (the default) or "gauge".
+	//		When the value is "indicator", the user must click on the indicator to change the value.
+	//		When the value is "gauge", the user can click on the gauge to change the indicator value.
+	//		If a gauge contains several indicators with the indicatorMode property set to "gauge", then
+	//		only the first indicator will be moved when clicking the gauge.
 	interactionMode: "indicator",
 	
 	_gauge: null,
@@ -143,7 +139,7 @@ return declare("dojox.gauges._Indicator",[Widget],{
 	},
 		
 	buildRendering: function(){
-		// summary: 
+		// summary:
 		//		Overrides _Widget.buildRendering
 		
 		var n = this.domNode = this.srcNodeRef ? this.srcNodeRef: dom.create("div");
diff --git a/dojox/geo/charting/Feature.js b/dojox/geo/charting/Feature.js
index 8409321..7a0898d 100644
--- a/dojox/geo/charting/Feature.js
+++ b/dojox/geo/charting/Feature.js
@@ -1,198 +1,217 @@
-define(["dojo/_base/lang", "dojo/_base/declare","dojo/_base/array",
-		"dojo/_base/html","dojo/dom","dojo/_base/event", "dojox/gfx/fx", "dojox/color"], 
-  function(lang, declare,arr, html,dom, event, fx,color) {
+define([
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/html",
+	"dojo/dom",
+	"dojo/_base/event",
+	"dojox/gfx/fx",
+	"dojox/color"
+], function(lang, declare,arr, html,dom, event, fx,color){
 
-return declare("dojox.geo.charting.Feature", null, {
-	//	summary: 
-	//		class to encapsulate a map element.
-	//	tags:
-	//		private
+	return declare("dojox.geo.charting.Feature", null, {
+		// summary:
+		//		A class to encapsulate a map element.
+		// tags:
+		//		private
 
-	_isZoomIn: false,
-	isSelected: false,
-	markerText:null,
+		_isZoomIn: false,
+		isSelected: false,
+		markerText:null,
 
 
-	constructor: function(parent, name, shapeData){
-		//	summary: 
-		//		constructs a new Feature.
-		//	tags:
-		//		private
-		this.id = name;
-		this.shape = parent.mapObj.createGroup();
-		this.parent = parent;
-		this.mapObj = parent.mapObj;
-		this._bbox = shapeData.bbox;
-		this._center = shapeData.center;
-		//TODO: fill color would be defined by charting data and legend
-//		this._highlightFill = ["#FFCE52", "#CE6342", "#63A584"][Math.floor(Math.random() * 3)];
-		this._defaultFill = parent.defaultColor;
-		this._highlightFill = parent.highlightColor;
-		this._defaultStroke = {
-			width: this._normalizeStrokeWeight(.5),
-			color: "white"
-		};
-		
-		var shapes = (lang.isArray(shapeData.shape[0])) ? shapeData.shape : [shapeData.shape];
-		arr.forEach(shapes, function(points){
-			this.shape.createPolyline(points).setStroke(this._defaultStroke);
-		}, this);
-		this.unsetValue();
-	},
-	unsetValue:function(){
-		//	summary: 
-		//		clears the numeric value on this Feature object (removes color).
-		
-		this.value = null;
-		this.unsetColor();
-	},
-	unsetColor:function(){
-		this._defaultFill = this.parent.defaultColor;
-		var col = new color.Color(this.parent.defaultColor).toHsl();
-		col.l = 1.2 * col.l;
-		this._highlightFill = color.fromHsl(col);
-		this._setFillWith(this._defaultFill);
-	},
-	setValue:function(value){
-		//	summary: 
-		//		sets a numeric value on this Feature object (used together with series to apply a color).
-		//	value:
-		//		a number
-		this.value = value;
-		if (value == null) {
+		constructor: function(parent, name, shapeData){
+			// summary:
+			//		constructs a new Feature.
+			// tags:
+			//		private
+			this.id = name;
+			this.shape = parent.mapObj.createGroup();
+			this.parent = parent;
+			this.mapObj = parent.mapObj;
+			this._bbox = shapeData.bbox;
+			this._center = shapeData.center;
+			//TODO: fill color would be defined by charting data and legend
+	//		this._highlightFill = ["#FFCE52", "#CE6342", "#63A584"][Math.floor(Math.random() * 3)];
+			this._defaultFill = parent.defaultColor;
+			this._highlightFill = parent.highlightColor;
+			this._defaultStroke = {
+				width: this._normalizeStrokeWeight(.5),
+				color: "white"
+			};
+
+			var shapes = (lang.isArray(shapeData.shape[0])) ? shapeData.shape : [shapeData.shape];
+			arr.forEach(shapes, function(points){
+				this.shape.createPolyline(points).setStroke(this._defaultStroke);
+			}, this);
 			this.unsetValue();
-		} else {
-			if (this.parent.series.length != 0) {
-				for (var i = 0; i < this.parent.series.length; i++) {
-					var range = this.parent.series[i];
-					if ((value >= range.min) && (value < range.max)) {
-						this._setFillWith(range.color);
-						this._defaultFill = range.color;
-						var col = new color.Color(range.color).toHsv();
-						col.v = (col.v + 20);
-						this._highlightFill = color.fromHsv(col);
-						return;
+		},
+		unsetValue:function(){
+			// summary:
+			//		clears the numeric value on this Feature object (removes color).
+
+			this.value = null;
+			this.unsetColor();
+		},
+		unsetColor:function(){
+			// summary:
+			//		clears the colors on this Feature object.
+
+			this._defaultFill = this.parent.defaultColor;
+			var col = new color.Color(this.parent.defaultColor).toHsl();
+			col.l = 1.2 * col.l;
+			this._highlightFill = color.fromHsl(col);
+			this._setFillWith(this._defaultFill);
+		},
+		setValue:function(value){
+			// summary:
+			//		sets a numeric value on this Feature object (used together with series to apply a color).
+			// value: Number
+			//		A numeric value.
+
+			this.value = value;
+			if(value == null){
+				this.unsetValue();
+			}else{
+				if(this.parent.series.length != 0){
+					for(var i = 0; i < this.parent.series.length; i++){
+						var range = this.parent.series[i];
+						if((value >= range.min) && (value < range.max)){
+							this._setFillWith(range.color);
+							this._defaultFill = range.color;
+							var col = new color.Color(range.color).toHsv();
+							col.v = (col.v + 20);
+							this._highlightFill = color.fromHsv(col);
+							return;
+						}
 					}
+					// did not found a range : unset color
+					this.unsetColor();
 				}
-				// did not found a range : unset color
-				this.unsetColor();
 			}
-		}
-	},
-	_setFillWith: function(color){
-		var borders = (lang.isArray(this.shape.children)) ? this.shape.children : [this.shape.children];
-		arr.forEach(borders, lang.hitch(this,function(item){
-			if(this.parent.colorAnimationDuration > 0){
-				var anim1 = fx.animateFill({
-					shape: item,
-					color: {
-						start: item.getFill(),
-						end: color
-					},
-					duration: this.parent.colorAnimationDuration
+		},
+		_setFillWith: function(color){
+			var borders = (lang.isArray(this.shape.children)) ? this.shape.children : [this.shape.children];
+			arr.forEach(borders, lang.hitch(this,function(item){
+				if(this.parent.colorAnimationDuration > 0){
+					var anim1 = fx.animateFill({
+						shape: item,
+						color: {
+							start: item.getFill(),
+							end: color
+						},
+						duration: this.parent.colorAnimationDuration
+					});
+					anim1.play();
+				}else{
+					item.setFill(color);
+				}
+			}));
+		},
+		_setStrokeWith: function(stroke){
+			var borders = (lang.isArray(this.shape.children)) ? this.shape.children : [this.shape.children];
+			arr.forEach(borders, function(item){
+				item.setStroke({
+					color: stroke.color,
+					width: stroke.width,
+					join: "round"
 				});
-				anim1.play();
-			}else{
-				item.setFill(color);
-			}
-		}));
-	},
-	_setStrokeWith: function(stroke){
-		var borders = (lang.isArray(this.shape.children)) ? this.shape.children : [this.shape.children];
-		arr.forEach(borders, function(item){
-			item.setStroke({
-				color: stroke.color,
-				width: stroke.width,
-				join: "round"
 			});
-		});
-	},
-	_normalizeStrokeWeight: function(weight){
-		var matrix = this.shape._getRealMatrix();
-		return (dojox.gfx.renderer != "vml")?weight/(this.shape._getRealMatrix()||{xx:1}).xx:weight;
-	},
-	_onmouseoverHandler: function(evt){
-		this.parent.onFeatureOver(this);
-		this._setFillWith(this._highlightFill);
-		this.mapObj.marker.show(this.id,evt);
-	},
-	_onmouseoutHandler: function(){
-		this._setFillWith(this._defaultFill);
-		this.mapObj.marker.hide();
-		html.style("mapZoomCursor", "display", "none");
-	},
-	_onmousemoveHandler: function(evt){
-		if(this.mapObj.marker._needTooltipRefresh){
-			this.mapObj.marker.show(this.id,evt);
-		}
-		if(this.isSelected){
-			if (this.parent.enableFeatureZoom) {
-				evt = event.fix(evt || window.event);
-				html.style("mapZoomCursor", "left", evt.pageX + 12 + "px");
-				html.style("mapZoomCursor", "top", evt.pageY + "px");
-				html.byId("mapZoomCursor").className = this._isZoomIn ? "mapZoomOut":"mapZoomIn";
-				html.style("mapZoomCursor", "display", "block");
-			}else{
-				html.style("mapZoomCursor", "display", "none");
+		},
+		_normalizeStrokeWeight: function(weight){
+			var matrix = this.shape._getRealMatrix();
+			return (dojox.gfx.renderer != "vml")?weight/(this.shape._getRealMatrix()||{xx:1}).xx:weight;
+		},
+		_onmouseoverHandler: function(evt){
+			this.parent.onFeatureOver(this);
+			this._setFillWith(this._highlightFill);
+			this.mapObj.marker.show(this.id, evt);
+		},
+		_onmouseoutHandler: function(){
+			this._setFillWith(this._defaultFill);
+			this.mapObj.marker.hide();
+			html.style("mapZoomCursor", "display", "none");
+		},
+		_onmousemoveHandler: function(evt){
+			if(this.mapObj.marker._needTooltipRefresh){
+				this.mapObj.marker.show(this.id, evt);
 			}
-		}
-	},
-	_onclickHandler: function(evt){
-		this.parent.onFeatureClick(this);
-		if(!this.isSelected){
-			this.parent.deselectAll();
-			this.select(true);
-			this._onmousemoveHandler(evt);
-		}else if(this.parent.enableFeatureZoom){
-			if(this._isZoomIn){
-				this._zoomOut();
+			if(this.isSelected && evt){
+				if(this.parent.enableFeatureZoom){
+					evt = event.fix(evt || window.event);
+					html.style("mapZoomCursor", "left", evt.pageX + 12 + "px");
+					html.style("mapZoomCursor", "top", evt.pageY + "px");
+					html.byId("mapZoomCursor").className = this._isZoomIn ? "mapZoomOut":"mapZoomIn";
+					html.style("mapZoomCursor", "display", "block");
+				}else{
+					html.style("mapZoomCursor", "display", "none");
+				}
+			}
+		},
+		_onclickHandler: function(evt){
+			this.parent.onFeatureClick(this);
+			if(!this.isSelected){
+				this.parent.deselectAll();
+				this.select(true);
+				this._onmousemoveHandler(evt);
+			}else if(this.parent.enableFeatureZoom){
+				if(this._isZoomIn){
+					this._zoomOut();
+				}else{
+					this._zoomIn();
+				}
+			}
+		},
+
+		select: function(selected){
+			// summary:
+			//		Sets the selected state of this feature to the given value.
+			// selected: Boolean
+			//		A Boolean value indicating the selected state.
+
+			if(selected){
+				this.shape.moveToFront();
+				this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)});
+				this._setFillWith(this._highlightFill);
+				this.isSelected = true;
+				this.parent.selectedFeature = this;
 			}else{
-				this._zoomIn();
+				this._setStrokeWith(this._defaultStroke);
+				this._setFillWith(this._defaultFill);
+				this.isSelected = false;
+				this._isZoomIn = false;
 			}
-		}
-	},
-	
-	select: function(selected) {
-		if(selected){
-			this.shape.moveToFront();
-			this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)});
-			this._setFillWith(this._highlightFill);
-			this.isSelected = true;
-			this.parent.selectedFeature = this;
-		}else{
-			this._setStrokeWith(this._defaultStroke);
-			this._setFillWith(this._defaultFill);
-			this.isSelected = false;
+		},
+
+		_zoomIn: function(){
+			var marker = this.mapObj.marker;
+			marker.hide();
+			this.parent.fitToMapArea(this._bbox, 15,true,lang.hitch(this,function(){
+				this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)});
+				marker._needTooltipRefresh = true;
+				this.parent.onZoomEnd(this);
+			}));
+			this._isZoomIn = true;
+			dom.byId("mapZoomCursor").className = "";
+		},
+		_zoomOut: function(){
+			var marker = this.mapObj.marker;
+			marker.hide();
+			this.parent.fitToMapContents(3,true,lang.hitch(this,function(){
+				this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)});
+				marker._needTooltipRefresh = true;
+				this.parent.onZoomEnd(this);
+			}));
 			this._isZoomIn = false;
+			dom.byId("mapZoomCursor").className = "";
+		},
+
+		init: function(){
+			// summary:
+			//		Initializes this feature.
+
+			this.shape.id = this.id;
+			this.tooltip = null;
 		}
-	},
-	
-	_zoomIn: function(){
-		var marker = this.mapObj.marker;
-		marker.hide();
-		this.parent.fitToMapArea(this._bbox, 15,true,lang.hitch(this,function(){
-			this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)});
-			marker._needTooltipRefresh = true;
-			this.parent.onZoomEnd(this);
-		}));
-		this._isZoomIn = true;
-		dom.byId("mapZoomCursor").className = "";
-	},
-	_zoomOut: function(){
-		var marker = this.mapObj.marker;
-		marker.hide();
-		this.parent.fitToMapContents(3,true,lang.hitch(this,function(){
-			this._setStrokeWith({color:"black",width:this._normalizeStrokeWeight(2)});
-			marker._needTooltipRefresh = true;
-			this.parent.onZoomEnd(this);
-		}));
-		this._isZoomIn = false;
-		dom.byId("mapZoomCursor").className = "";
-	},
-	
-	init: function(){
-		this.shape.id = this.id;
-		this.tooltip = null;
-	}
-});
+	});
 });
\ No newline at end of file
diff --git a/dojox/geo/charting/KeyboardInteractionSupport.js b/dojox/geo/charting/KeyboardInteractionSupport.js
index 7761095..f2819bc 100644
--- a/dojox/geo/charting/KeyboardInteractionSupport.js
+++ b/dojox/geo/charting/KeyboardInteractionSupport.js
@@ -1,144 +1,165 @@
-define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/event","dojo/_base/connect",
-		"dojo/_base/html","dojo/dom","dojox/lang/functional","dojo/keys"],
-  function(lang, declare, event, connect, html, dom, functional, keys) {
+define([
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/connect",
+	"dojo/_base/html",
+	"dojo/dom",
+	"dojox/lang/functional",
+	"dojo/keys"
+], function(lang, declare, event, connect, html, dom, functional, keys){
 
-return declare("dojox.geo.charting.KeyboardInteractionSupport", null, {
-	//	summary: 
-	//		class to handle keyboard interactions on a dojox.geo.charting.Map widget
-	//
-	//		The sections on the leading edge should receive the focus in response to a TAB event. 
-	//		Then use cursor keys to the peer sections. The cursor event should go the adjacent section 
-	//		in that direction. With the focus, the section zooms in upon SPACE. The map should zoom out 
-	//		on ESC. Finally, while it has the focus, the map should lose the focus on TAB.
-	//	tags:
-	//		private
-	_map: null,
-	_zoomEnabled: false,
-	
-	constructor: function(map, options){
-		//	summary: 
-		//		Constructs a new _KeyboardInteractionSupport instance
-		//	map: dojox.geo.charting.Map
-		//		the Map widget this class provides touch navigation for.
-		this._map = map;
-		if(options){
-			this._zoomEnabled = options.enableZoom;
-		}
-	},
-	connect: function(){
-		//	summary: 
-		//		connects this keyboard support class to the Map component
-		var container = dom.byId(this._map.container);
-		//	tab accessing enable
-		html.attr(container, {
-			tabindex: 0,
-			role: "presentation",
-			"aria-label": "map"
-		});
-		// install listeners
-		this._keydownListener = connect.connect(container, "keydown", this, "keydownHandler");
-		this._onFocusListener = connect.connect(container, "focus", this, "onFocus");
-		this._onBlurListener = connect.connect(container, "blur", this, "onBlur");
-	},
-	disconnect: function(){
-		//	summary: 
-		//		disconnects any installed listeners
-		connect.disconnect(this._keydownListener);
-		this._keydownListener = null;
-		connect.disconnect(this._onFocusListener);
-		this._onFocusListener = null;
-		connect.disconnect(this._onBlurListener);
-		this._onBlurListener = null
-	},
-	keydownHandler: function(e){
-		switch(e.keyCode){
-			case keys.LEFT_ARROW:
-				this._directTo(-1,-1,1,-1);
-				break;
-			case keys.RIGHT_ARROW:
-				this._directTo(-1,-1,-1,1);
-				break;
-			case keys.UP_ARROW:
-				this._directTo(1,-1,-1,-1);
-				break;
-			case keys.DOWN_ARROW:
-				this._directTo(-1,1,-1,-1);
-				break;
-			case keys.SPACE:
-				if(this._map.selectedFeature && !this._map.selectedFeature._isZoomIn && this._zoomEnabled){
-					this._map.selectedFeature._zoomIn();
-				}
-				break;
-			case keys.ESCAPE:
-				if(this._map.selectedFeature && this._map.selectedFeature._isZoomIn && this._zoomEnabled){
-					this._map.selectedFeature._zoomOut();
-				}
-				break;
-			default:
-				return;
-		}
-		event.stop(e);
-	},
-	onFocus: function(e){
-		// select the leading region at the map center
-		if(this._map.selectedFeature || this._map.focused){return;}
-		this._map.focused = true;
-		var leadingRegion,
-			needClick = false;
-		if(this._map.lastSelectedFeature){
-			leadingRegion = this._map.lastSelectedFeature;
-		}else{
-			var mapCenter = this._map.getMapCenter(),
-				minDistance = Infinity;
-			// find the region most closing to the map center
-			functional.forIn(this._map.mapObj.features, function(feature){
-				var distance = Math.sqrt(Math.pow(feature._center[0] - mapCenter.x, 2) + Math.pow(feature._center[1] - mapCenter.y, 2));
-				if(distance < minDistance){
-					minDistance = distance;
-					leadingRegion = feature;
-				}
+	return declare("dojox.geo.charting.KeyboardInteractionSupport", null, {
+		// summary:
+		//		class to handle keyboard interactions on a dojox.geo.charting.Map component.
+		//
+		//		The sections on the leading edge should receive the focus in response to a TAB event.
+		//		Then use cursor keys to the peer sections. The cursor event should go the adjacent section
+		//		in that direction. With the focus, the section zooms in upon SPACE. The map should zoom out
+		//		on ESC. Finally, while it has the focus, the map should lose the focus on TAB.
+		// tags:
+		//		private
+		_map: null,
+		_zoomEnabled: false,
+
+		constructor: function(/*dojox/geo/charting/Map*/ map, /*Object?*/ options){
+			// summary:
+			//		Constructs a new _KeyboardInteractionSupport instance
+			// map: dojox/geo/charting/Map
+			//		the Map component this class provides touch navigation for.
+			// options: Object?
+			//		An object defining additional configuration properties. Currently,
+			//		only the enableZoom property of this object is taken into account to enable/disable
+			//		the Map zooming capability.
+			this._map = map;
+			if(options){
+				this._zoomEnabled = options.enableZoom;
+			}
+		},
+		connect: function(){
+			// summary:
+			//		connects this keyboard support class to the Map component
+			var container = dom.byId(this._map.container);
+			//	tab accessing enable
+			html.attr(container, {
+				tabindex: 0,
+				role: "presentation",
+				"aria-label": "map"
 			});
-			needClick = true;
-		}
-		if(leadingRegion){
-			if(needClick) {
-				leadingRegion._onclickHandler(null);
+			// install listeners
+			this._keydownListener = connect.connect(container, "keydown", this, "keydownHandler");
+			this._onFocusListener = connect.connect(container, "focus", this, "onFocus");
+			this._onBlurListener = connect.connect(container, "blur", this, "onBlur");
+		},
+		disconnect: function(){
+			// summary:
+			//		disconnects any installed listeners
+			connect.disconnect(this._keydownListener);
+			this._keydownListener = null;
+			connect.disconnect(this._onFocusListener);
+			this._onFocusListener = null;
+			connect.disconnect(this._onBlurListener);
+			this._onBlurListener = null
+		},
+		keydownHandler: function(/*KeyboardEvent*/e){
+			// summary:
+			//		Handles a keydown event.
+			// e: KeyboardEvent
+			//		An event.
+			switch(e.keyCode){
+				case keys.LEFT_ARROW:
+					this._directTo(-1,-1,1,-1);
+					break;
+				case keys.RIGHT_ARROW:
+					this._directTo(-1,-1,-1,1);
+					break;
+				case keys.UP_ARROW:
+					this._directTo(1,-1,-1,-1);
+					break;
+				case keys.DOWN_ARROW:
+					this._directTo(-1,1,-1,-1);
+					break;
+				case keys.SPACE:
+					if(this._map.selectedFeature && !this._map.selectedFeature._isZoomIn && this._zoomEnabled){
+						this._map.selectedFeature._zoomIn();
+					}
+					break;
+				case keys.ESCAPE:
+					if(this._map.selectedFeature && this._map.selectedFeature._isZoomIn && this._zoomEnabled){
+						this._map.selectedFeature._zoomOut();
+					}
+					break;
+				default:
+					return;
+			}
+			event.stop(e);
+		},
+		onFocus: function(e){
+			// summary:
+			//		Handles the onFocus event.
+			// e: Event
+			//		An event.
+
+			// select the leading region at the map center
+			if(this._map.selectedFeature || this._map.focused){return;}
+			this._map.focused = true;
+			var leadingRegion,
+				needClick = false;
+			if(this._map.lastSelectedFeature){
+				leadingRegion = this._map.lastSelectedFeature;
 			}else{
+				var mapCenter = this._map.getMapCenter(),
+					minDistance = Infinity;
+				// find the region most closing to the map center
+				functional.forIn(this._map.mapObj.features, function(feature){
+					var distance = Math.sqrt(Math.pow(feature._center[0] - mapCenter.x, 2) + Math.pow(feature._center[1] - mapCenter.y, 2));
+					if(distance < minDistance){
+						minDistance = distance;
+						leadingRegion = feature;
+					}
+				});
+				needClick = true;
 			}
-			this._map.mapObj.marker.show(leadingRegion.id);
-		}
-	},
-	onBlur: function(){
-		this._map.lastSelectedFeature = this._map.selectedFeature;
-	},
-	_directTo: function(up,down,left,right){
-		var currentSelected = this._map.selectedFeature,
-		centerX = currentSelected._center[0],
-		centerY = currentSelected._center[1],
-		minMargin = Infinity,
-		nextSelected = null;
-		functional.forIn(this._map.mapObj.features, function(feature){
-			var paddingX = Math.abs(centerX - feature._center[0]),
-			paddingY = Math.abs(centerY - feature._center[1]),
-			paddingSum = paddingX + paddingY;
-			if((up - down) * (centerY - feature._center[1]) > 0){
-				if(paddingX < paddingY && minMargin > paddingSum){
-					minMargin = paddingSum;
-					nextSelected = feature;
+			if(leadingRegion){
+				if(needClick){
+					leadingRegion._onclickHandler(null);
 				}
+				this._map.mapObj.marker.show(leadingRegion.id);
 			}
-			if((left - right) * (centerX - feature._center[0]) > 0){
-				if(paddingX > paddingY && minMargin > paddingSum){
-					minMargin = paddingSum;
-					nextSelected = feature;
+		},
+		onBlur: function(){
+			// summary:
+			//		Handles the onBlur event.
+			this._map.lastSelectedFeature = this._map.selectedFeature;
+		},
+		_directTo: function(up, down, left, right){
+			var currentSelected = this._map.selectedFeature,
+			centerX = currentSelected._center[0],
+			centerY = currentSelected._center[1],
+			minMargin = Infinity,
+			nextSelected = null;
+			functional.forIn(this._map.mapObj.features, function(feature){
+				var paddingX = Math.abs(centerX - feature._center[0]),
+				paddingY = Math.abs(centerY - feature._center[1]),
+				paddingSum = paddingX + paddingY;
+				if((up - down) * (centerY - feature._center[1]) > 0){
+					if(paddingX < paddingY && minMargin > paddingSum){
+						minMargin = paddingSum;
+						nextSelected = feature;
+					}
+				}
+				if((left - right) * (centerX - feature._center[0]) > 0){
+					if(paddingX > paddingY && minMargin > paddingSum){
+						minMargin = paddingSum;
+						nextSelected = feature;
+					}
 				}
+			});
+			if(nextSelected){
+				this._map.mapObj.marker.hide();
+				nextSelected._onclickHandler(null);
+				this._map.mapObj.marker.show(nextSelected.id);
 			}
-		});
-		if(nextSelected){
-			this._map.mapObj.marker.hide();
-			nextSelected._onclickHandler(null);
-			this._map.mapObj.marker.show(nextSelected.id);
 		}
-	}
-});
+	});
 });
\ No newline at end of file
diff --git a/dojox/geo/charting/Map.js b/dojox/geo/charting/Map.js
index 0948022..8bde47a 100644
--- a/dojox/geo/charting/Map.js
+++ b/dojox/geo/charting/Map.js
@@ -1,603 +1,651 @@
-define(["dojo/_base/lang","dojo/_base/array","dojo/_base/declare","dojo/_base/html","dojo/dom",
-		"dojo/dom-geometry","dojo/dom-class", "dojo/_base/xhr","dojo/_base/connect","dojo/_base/window", "dojox/gfx",
-		"dojox/geo/charting/_base","dojox/geo/charting/Feature","dojox/geo/charting/_Marker","dojo/number","dojo/_base/sniff"],
-  function(lang, arr, declare, html, dom, domGeom, domClass, xhr, connect, win, gfx, base, 
-		   Feature, Marker, number, has) {
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/html",
+	"dojo/dom",
+	"dojo/dom-geometry",
+	"dojo/dom-class", 
+	"dojo/_base/xhr",
+	"dojo/_base/connect",
+	"dojo/_base/window", 
+	"dojox/gfx",
+	"./_base",
+	"./Feature",
+	"./_Marker",
+	"dojo/number",
+	"dojo/_base/sniff"
+], function(lang, arr, declare, html, dom, domGeom, domClass, xhr, connect, win, gfx, base, Feature, Marker, number, has){
 
 	return declare("dojox.geo.charting.Map", null, {
-	//	summary:
-	//		Map widget interacted with charting.
-	//	description:
-	//		Support rendering Americas, AsiaPacific, ContinentalEurope, EuropeMiddleEastAfrica,
-	//		USStates, WorldCountries, and WorldCountriesMercator by default.
-	//	example:
-	//	|	var usaMap = new dojox.geo.charting.Map(srcNode, "dojotoolkit/dojox/geo/charting/resources/data/USStates.json");
-	//	|	<div id="map" style="width:600px;height:400px;"></div>
-	
-	//	defaultColor: String
-	//		Default map feature color, e.g: "#B7B7B7"
-	defaultColor:"#B7B7B7",
-	//	highlightColor: String
-	//		Map feature color when mouse over it, e.g: "#"
-	highlightColor:"#D5D5D5",
-	//	series: Array
-	//		stack to data range, e.g: [{name:'label 1', min:20, max:70, color:'#DDDDDD'},{...},...]
-	series:[],
-	dataBindingAttribute:null,
-	dataBindingValueFunction:null,
-	dataStore:null,
-	showTooltips: true,
-	enableFeatureZoom: true,
-	colorAnimationDuration:0,
-	_idAttributes:null,
-	_onSetListener:null,
-	_onNewListener:null,
-	_onDeleteListener:null,
-	constructor: function(/*HTML Node*/container, /*String or Json object*/shapeData){
-		//	container:
-		//		map container html node/id
-		//	shapeData:
-		//		map shape data json object, or url to json file
-		
-		html.style(container, "display", "block");
-		
-		this.container = container;
-		var containerBounds = this._getContainerBounds();
-		// get map container coords
-		this.surface = gfx.createSurface(container, containerBounds.w, containerBounds.h);
-		
-		this._createZoomingCursor();
-		
-		// add transparent background for event capture
-		this.mapBackground = this.surface.createRect({x: 0, y: 0, width: containerBounds.w, height: containerBounds.w}).setFill("rgba(0,0,0,0)");
-		
-		this.mapObj = this.surface.createGroup();
-		this.mapObj.features = {};
-		
-		if (typeof shapeData == "object") {
-			this._init(shapeData);
-		} else {
-	        // load map shape file
-			if (typeof shapeData == "string" && shapeData.length > 0) {
-				xhr.get({
-					url: shapeData,
-					handleAs: "json",
-					sync: true,
-					load: lang.hitch(this, "_init")
-				});
+		// summary:
+		//		Map widget interacted with charting.
+		// description:
+		//		Support rendering Americas, AsiaPacific, ContinentalEurope, EuropeMiddleEastAfrica,
+		//		USStates, WorldCountries, and WorldCountriesMercator by default.
+		// example:
+		//	|	var usaMap = new dojox.geo.charting.Map(srcNode, "dojotoolkit/dojox/geo/charting/resources/data/USStates.json");
+		//	|	<div id="map" style="width:600px;height:400px;"></div>
+	
+		// defaultColor: String
+		//		Default map feature color, e.g: "#B7B7B7"
+		defaultColor:"#B7B7B7",
+		// highlightColor: String
+		//		Map feature color when mouse over it, e.g: "#"
+		highlightColor:"#D5D5D5",
+		// series: Array
+		//		stack to data range, e.g: [{name:'label 1', min:20, max:70, color:'#DDDDDD'},{...},...]
+		series:[],
+		
+		dataBindingAttribute:null,
+		dataBindingValueFunction:null,
+		dataStore:null,
+		showTooltips: true,
+		enableFeatureZoom: true,
+		colorAnimationDuration:0,
+		_idAttributes:null,
+		_onSetListener:null,
+		_onNewListener:null,
+		_onDeleteListener:null,
+		constructor: function(/*Node*/container, /*String|Object*/shapeData){
+			// summary:
+			//		Constructs a new Map instance.
+			// container:
+			//		map container html node/id.
+			// shapeData:
+			//		map shape data json object, or url to json file.
+	
+			html.style(container, "display", "block");
+	
+			this.container = container;
+			var containerBounds = this._getContainerBounds();
+			// get map container coords
+			this.surface = gfx.createSurface(container, containerBounds.w, containerBounds.h);
+	
+			this._createZoomingCursor();
+	
+			// add transparent background for event capture
+			this.mapBackground = this.surface.createRect({x: 0, y: 0, width: containerBounds.w, height: containerBounds.w}).setFill("rgba(0,0,0,0)");
+	
+			this.mapObj = this.surface.createGroup();
+			this.mapObj.features = {};
+	
+			if(typeof shapeData == "object"){
+				this._init(shapeData);
+			}else{
+				// load map shape file
+				if(typeof shapeData == "string" && shapeData.length > 0){
+					xhr.get({
+						url: shapeData,
+						handleAs: "json",
+						sync: true,
+						load: lang.hitch(this, "_init")
+					});
+				}
 			}
-		}
-	},
+		},
 	
-	_getContainerBounds: function() {
-		//	summary: 
-		//		returns the bounds {x:, y:, w: ,h:} of the DOM node container in absolute coordinates 
-		//	tags:
-		//		private
-		
-		var position = domGeom.position(this.container,true);
-		var marginBox = domGeom.getMarginBox(this.container);
-		// use contentBox for correct width and height - surface spans outside border otherwise
-		var contentBox = domGeom.getContentBox(this.container);
-		this._storedContainerBounds = {
-				x: position.x,
-				y: position.y,
-				w: contentBox.w || 100,
-				h: contentBox.h || 100
-			};
-		return this._storedContainerBounds;
-	},
-	
-	resize: function(/**boolean**/ adjustMapCenter/**boolean**/,adjustMapScale,/**boolean**/ animate) {
-		//	summary: 
-		//		resize the underlying GFX surface to accommodate to parent DOM Node size change
-		//	adjustMapCenter: boolean
-		//		keeps the center of the map when resizing the surface
-		//	adjustMapScale: boolean
-		//		adjusts the map scale to keep the visible portion of the map as much as possible 
-		
-		var oldBounds = this._storedContainerBounds; 
-		var newBounds = this._getContainerBounds();
-		
-		if ((oldBounds.w == newBounds.w) && (oldBounds.h == newBounds.h)) {
-			return;
-		}
-		
-		// set surface dimensions, and background
-		this.mapBackground.setShape({width:newBounds.w, height:newBounds.h});
-		this.surface.setDimensions(newBounds.w,newBounds.h);
-		
-		this.mapObj.marker.hide();
-		this.mapObj.marker._needTooltipRefresh = true;
-		
-		if (adjustMapCenter) {
-			
-			var mapScale = this.getMapScale();
-			var newScale = mapScale;
-			
-			if (adjustMapScale) {
-				var bbox = this.mapObj.boundBox;
-				var widthFactor = newBounds.w / oldBounds.w;
-				var heightFactor = newBounds.h / oldBounds.h;
-				newScale = mapScale * Math.sqrt(widthFactor * heightFactor);
+		_getContainerBounds: function(){
+			// summary:
+			//		returns the bounds {x:, y:, w: ,h:} of the DOM node container in absolute coordinates
+			// tags:
+			//		private
+	
+			var position = domGeom.position(this.container,true);
+			var marginBox = domGeom.getMarginBox(this.container);
+			// use contentBox for correct width and height - surface spans outside border otherwise
+			var contentBox = domGeom.getContentBox(this.container);
+			this._storedContainerBounds = {
+					x: position.x,
+					y: position.y,
+					w: contentBox.w || 100,
+					h: contentBox.h || 100
+				};
+			return this._storedContainerBounds;
+		},
+	
+		resize: function(/**boolean**/ adjustMapCenter, /**boolean**/ adjustMapScale, /**boolean**/ animate){
+			// summary:
+			//		resize the underlying GFX surface to accommodate to parent DOM Node size change
+			// adjustMapCenter: boolean
+			//		keeps the center of the map when resizing the surface
+			// adjustMapScale: boolean
+			//		adjusts the map scale to keep the visible portion of the map as much as possible
+	
+			var oldBounds = this._storedContainerBounds;
+			var newBounds = this._getContainerBounds();
+	
+			if((oldBounds.w == newBounds.w) && (oldBounds.h == newBounds.h)){
+				return;
 			}
-			
-			//	current map center
-			var invariantMapPoint = this.screenCoordsToMapCoords(oldBounds.w/2,oldBounds.h/2);
-
-			//	apply new parameters
-			this.setMapCenterAndScale(invariantMapPoint.x,invariantMapPoint.y,newScale,animate);
-		}
-	},
-	
-	_isMobileDevice: function() {
-		//	summary: 
-		//		tests whether the application is running on a mobile device (android or iOS)
-		//	tags:
-		//		private
-		return (has("safari")
-				&& (navigator.userAgent.indexOf("iPhone") > -1 ||
-					navigator.userAgent.indexOf("iPod") > -1 ||
-					navigator.userAgent.indexOf("iPad") > -1
-				)) || (navigator.userAgent.toLowerCase().indexOf("android") > -1);
-	},
-	
-	
-	setMarkerData: function(/*String*/ markerFile){
-		//	summary:
-		//		import markers from outside file, associate with map feature by feature id
-		//		which identified in map shape file, e.g: "NY":"New York"
-		//	markerFile:
-		//		outside marker data url, handled as json style.
-		//		data format: {"NY":"New York",.....}
-		xhr.get({
-			url: markerFile,
-			handleAs: "json",
-			handle: lang.hitch(this, "_appendMarker")
-		});
-	},
-	
-	setDataBindingAttribute: function(/*String*/prop) {
-		//  summary:
-		//		sets the property name of the dataStore items to use as value (see Feature.setValue function)
-		//	prop:
-		//		the property
-		this.dataBindingAttribute = prop;
-		
-		// refresh data
-		if (this.dataStore) {
-			this._queryDataStore();
-		}
-	},
-	
-	setDataBindingValueFunction: function(/* function */valueFunction) {
-		//  summary:
-		//		sets the function that extracts values from dataStore items,to use as Feature values (see Feature.setValue function)
-		//	prop:
-		//		the function
-		this.dataBindingValueFunction = valueFunction;
-		
-		// refresh data
-		if (this.dataStore) {
-			this._queryDataStore();
-		}
-	},
 	
+			// set surface dimensions, and background
+			this.mapBackground.setShape({width:newBounds.w, height:newBounds.h});
+			this.surface.setDimensions(newBounds.w,newBounds.h);
 	
+			this.mapObj.marker.hide();
+			this.mapObj.marker._needTooltipRefresh = true;
 	
-	_queryDataStore: function() {
-		if (!this.dataBindingAttribute || (this.dataBindingAttribute.length == 0))
-			return;
-		
-		var mapInstance = this;
-		this.dataStore.fetch({
-			scope: this,
-			onComplete: function(items){
-				this._idAttributes = mapInstance.dataStore.getIdentityAttributes({});
-				arr.forEach(items, function(item) {
-					var id = mapInstance.dataStore.getValue(item, this._idAttributes[0]);
-					if(mapInstance.mapObj.features[id]){
-						var val = null;
-						var itemVal = mapInstance.dataStore.getValue(item, mapInstance.dataBindingAttribute);
-						if (itemVal) {
-							if (this.dataBindingValueFunction) {
-								val = this.dataBindingValueFunction(itemVal);
-							} else {
-								if (isNaN(val)) {
-									// regular parse
-									val=number.parse(itemVal);
-								} else {
-									val = itemVal;
+			if(adjustMapCenter){
+	
+				var mapScale = this.getMapScale();
+				var newScale = mapScale;
+	
+				if(adjustMapScale){
+					var bbox = this.mapObj.boundBox;
+					var widthFactor = newBounds.w / oldBounds.w;
+					var heightFactor = newBounds.h / oldBounds.h;
+					newScale = mapScale * Math.sqrt(widthFactor * heightFactor);
+				}
+	
+				//	current map center
+				var invariantMapPoint = this.screenCoordsToMapCoords(oldBounds.w/2,oldBounds.h/2);
+	
+				//	apply new parameters
+				this.setMapCenterAndScale(invariantMapPoint.x,invariantMapPoint.y,newScale,animate);
+			}
+		},
+	
+		_isMobileDevice: function(){
+			// summary:
+			//		tests whether the application is running on a mobile device (android or iOS)
+			// tags:
+			//		private
+			return (has("safari")
+					&& (navigator.userAgent.indexOf("iPhone") > -1 ||
+						navigator.userAgent.indexOf("iPod") > -1 ||
+						navigator.userAgent.indexOf("iPad") > -1
+					)) || (navigator.userAgent.toLowerCase().indexOf("android") > -1);
+		},
+	
+	
+		setMarkerData: function(/*String*/ markerFile){
+			// summary:
+			//		import markers from outside file, associate with map feature by feature id
+			//		which identified in map shape file, e.g: "NY":"New York"
+			// markerFile:
+			//		outside marker data url, handled as json style.
+			//		data format: {"NY":"New York",.....}
+			xhr.get({
+				url: markerFile,
+				handleAs: "json",
+				handle: lang.hitch(this, "_appendMarker")
+			});
+		},
+	
+		setDataBindingAttribute: function(/*String*/prop){
+			// summary:
+			//		sets the property name of the dataStore items to use as value (see Feature.setValue function)
+			// prop: String
+			//		the property
+			this.dataBindingAttribute = prop;
+	
+			// refresh data
+			if(this.dataStore){
+				this._queryDataStore();
+			}
+		},
+	
+		setDataBindingValueFunction: function(/* function */valueFunction){
+			// summary:
+			//		sets the function that extracts values from dataStore items,to use as Feature values (see Feature.setValue function)
+			// valueFunction:
+			//		the function
+			this.dataBindingValueFunction = valueFunction;
+	
+			// refresh data
+			if(this.dataStore){
+				this._queryDataStore();
+			}
+		},
+	
+	
+	
+		_queryDataStore: function(){
+			if(!this.dataBindingAttribute || (this.dataBindingAttribute.length == 0)){
+				return;
+			}
+	
+			var mapInstance = this;
+			this.dataStore.fetch({
+				scope: this,
+				onComplete: function(items){
+					this._idAttributes = mapInstance.dataStore.getIdentityAttributes({});
+					arr.forEach(items, function(item){
+						var id = mapInstance.dataStore.getValue(item, this._idAttributes[0]);
+						if(mapInstance.mapObj.features[id]){
+							var val = null;
+							var itemVal = mapInstance.dataStore.getValue(item, mapInstance.dataBindingAttribute);
+							if(itemVal){
+								if(this.dataBindingValueFunction){
+									val = this.dataBindingValueFunction(itemVal);
+								}else{
+									if(isNaN(val)){
+										// regular parse
+										val=number.parse(itemVal);
+									}else{
+										val = itemVal;
+									}
 								}
 							}
+							if(val){
+								mapInstance.mapObj.features[id].setValue(val);
+							}
 						}
-						if (val)
-							mapInstance.mapObj.features[id].setValue(val);
-					}
-				},this);						
+					},this);
+				}
+			});
+		},
+	
+		_onSet:function(item,attribute,oldValue,newValue){
+			// look for matching feature
+			var id = this.dataStore.getValue(item, this._idAttributes[0]);
+			var feature = this.mapObj.features[id];
+			if(feature && (attribute == this.dataBindingAttribute)){
+				if(newValue){
+					feature.setValue(newValue);
+				}else{
+					feature.unsetValue();
+				}
 			}
-		});
-	},
-	
-	_onSet:function(item,attribute,oldValue,newValue){
-		// look for matching feature
-		var id = this.dataStore.getValue(item, this._idAttributes[0]);
-		var feature = this.mapObj.features[id];
-		if (feature && (attribute == this.dataBindingAttribute)) {
-			if (newValue)
+		},
+	
+		_onNew:function(newItem,  parentItem){
+			var id = this.dataStore.getValue(item, this._idAttributes[0]);
+			var feature = this.mapObj.features[id];
+			if(feature && (attribute == this.dataBindingAttribute)){
 				feature.setValue(newValue);
-			else
+			}
+		},
+	
+		_onDelete:function(item){
+			var id = item[this._idAttributes[0]];
+			var feature = this.mapObj.features[id];
+			if(feature){
 				feature.unsetValue();
-		}
-	},
-
-	_onNew:function(newItem,  parentItem){
-		var id = this.dataStore.getValue(item, this._idAttributes[0]);
-		var feature = this.mapObj.features[id];
-		if (feature && (attribute == this.dataBindingAttribute)) {
-			feature.setValue(newValue);
-		}
-	},
+			}
+		},
 	
-	_onDelete:function(item){
-		var id = item[this._idAttributes[0]];
-		var feature = this.mapObj.features[id];
-		if (feature) {
-			feature.unsetValue();
-		}
-	},
-	
-	setDataStore: function(/*ItemFileReadStore*/ dataStore, /*String*/ dataBindingProp){
-		//	summary:
-		//		populate data for each map feature from fetched data store
-		//	dataStore:
-		//		the dataStore to fetch the information from
-		//	dataBindingProp:
-		//		sets the property name of the dataStore items to use as value
-		if (this.dataStore != dataStore) {
-			// disconnect previous listener if any
-			if (this._onSetListener) {
-				connect.disconnect(this._onSetListener);
-				connect.disconnect(this._onNewListener);
-				connect.disconnect(this._onDeleteListener);
+		setDataStore: function(/*dojo/data/ItemFileReadStore*/ dataStore, /*String*/ dataBindingProp){
+			// summary:
+			//		populate data for each map feature from fetched data store
+			// dataStore: dojo/data/ItemFileReadStore
+			//		the dataStore to fetch the information from
+			// dataBindingProp:
+			//		sets the property name of the dataStore items to use as value
+			if(this.dataStore != dataStore){
+				// disconnect previous listener if any
+				if(this._onSetListener){
+					connect.disconnect(this._onSetListener);
+					connect.disconnect(this._onNewListener);
+					connect.disconnect(this._onDeleteListener);
+				}
+	
+				// set new dataStore
+				this.dataStore = dataStore;
+	
+				// install listener on new dataStore
+				if(dataStore){
+					_onSetListener = connect.connect(this.dataStore,"onSet",this,this._onSet);
+					_onNewListener = connect.connect(this.dataStore,"onNew",this,this._onNew);
+					_onDeleteListener = connect.connect(this.dataStore,"onDelete",this,this._onDelete);
+				}
 			}
-			
-			// set new dataStore
-			this.dataStore = dataStore;
-			
-			// install listener on new dataStore
-			if (dataStore) {
-				_onSetListener = connect.connect(this.dataStore,"onSet",this,this._onSet);
-				_onNewListener = connect.connect(this.dataStore,"onNew",this,this._onNew);
-				_onDeleteListener = connect.connect(this.dataStore,"onDelete",this,this._onDelete);
+			if(dataBindingProp){
+				this.setDataBindingAttribute(dataBindingProp);
 			}
-		}
-		if (dataBindingProp)
-			this.setDataBindingAttribute(dataBindingProp);
-
-	},
+		},
 	
+		addSeries: function(/*url|Object[]*/ series){
+			// summary:
+			//		sets ranges of data values (associated with label, color) to style map data values
+			// series:
+			//		Either an url or an array of range objects such as : [{name:'label 1', min:20, max:70, color:'#DDDDDD'},{...},...]
 	
+			if(typeof series == "object"){
+				this._addSeriesImpl(series);
+			}else{
+				// load series file
+				if(typeof series == "string" && series.length > 0){
+					xhr.get({
+						url: series,
+						handleAs: "json",
+						sync: true,
+						load: lang.hitch(this, function(content){
+							this._addSeriesImpl(content.series);
+						})
+					});
+				}
+			}
 	
-	addSeries: function(/*url or Json Object*/ series){
-		//	summary: 
-		//		sets ranges of data values (associated with label, color) to style map data values
-		//	series:
-		//		array of range objects such as : [{name:'label 1', min:20, max:70, color:'#DDDDDD'},{...},...]
-		
-		if (typeof series == "object") {
-			this._addSeriesImpl(series);
-		} else {
-	        // load series file
-			if (typeof series == "string" && series.length > 0) {
-				xhr.get({
-					url: series,
-					handleAs: "json",
-					sync: true,
-					load: lang.hitch(this, function(content){
-						this._addSeriesImpl(content.series);
-					})
-				});
+		},
+	
+		_addSeriesImpl: function(/*Object[]*/series){
+	
+			this.series = series;
+	
+			// refresh color scheme
+			for(var item in this.mapObj.features){
+				var feature = this.mapObj.features[item];
+				feature.setValue(feature.value);
 			}
-		}
-		
-	},
+		},
 	
-	_addSeriesImpl: function(/*Json object*/series) {
-		
-		this.series = series;
-		
-		// refresh color scheme
-		for (var item in this.mapObj.features) {
-			var feature = this.mapObj.features[item];
-			feature.setValue(feature.value);
-		}
-	},
-
 	
-	fitToMapArea: function(/*bbox: {x,y,w,h}*/mapArea,pixelMargin,animate,/* callback function */onAnimationEnd){
-		//	summary: 
-		//		set this component's transformation so that the specified area fits in the component (centered)
-		//	mapArea: 
-		//		the map area that needs to fill the component
-		//	pixelMargin: int
-		//		a margin (in pixels) from the borders of the Map component.
-		//	animate: boolean
-		//		true if the transform change should be animated
-		//	onAnimationEnd: function
-		//		a callback function to be executed when the animation completes (if animate set to true).
-		
-		if(!pixelMargin){
-			pixelMargin = 0;
-		}
-		var width = mapArea.w,
-			height = mapArea.h,
-			containerBounds = this._getContainerBounds(),
-			scale = Math.min((containerBounds.w - 2 * pixelMargin) / width,
-							(containerBounds.h - 2 * pixelMargin) / height);
-		
-		this.setMapCenterAndScale(mapArea.x + mapArea.w / 2,mapArea.y + mapArea.h / 2,scale,animate,onAnimationEnd);
-	},
-	
-	fitToMapContents: function(pixelMargin,animate,/* callback function */onAnimationEnd){
-		//	summary: 
-		//		set this component's transformation so that the whole map data fits in the component (centered)
-		//	pixelMargin: int
-		//		a margin (in pixels) from the borders of the Map component.
-		//	animate: boolean
-		//		true if the transform change should be animated
-		//	onAnimationEnd: function
-		//		a callback function to be executed when the animation completes (if animate set to true).
-		
-		//transform map to fit container
-		var bbox = this.mapObj.boundBox;
-		this.fitToMapArea(bbox,pixelMargin,animate,onAnimationEnd);
-	},
-	
-	setMapCenter: function(centerX,centerY,animate,/* callback function */onAnimationEnd) {
-		//	summary: 
-		//		set this component's transformation so that the map is centered on the specified map coordinates
-		//	centerX: float
-		//		the X coordinate (in map coordinates) of the new center
-		//	centerY: float
-		//		the Y coordinate (in map coordinates) of the new center
-		//	animate: boolean
-		//		true if the transform change should be animated
-		//	onAnimationEnd: function
-		//		a callback function to be executed when the animation completes (if animate set to true).
-		
-		// call setMapCenterAndScale with current map scale 
-		var currentScale = this.getMapScale();
-		this.setMapCenterAndScale(centerX,centerY,currentScale,animate,onAnimationEnd);
-		
-	},
-	
-	_createAnimation: function(onShape,fromTransform,toTransform,/* callback function */onAnimationEnd) {
-		//	summary: 
-		//		creates a transform animation object (between two transforms) used internally
-		//	fromTransform: dojox.gfx.matrix.Matrix2D
-		//		the start transformation (when animation begins)
-		//	toTransform: dojox.gfx.matrix.Matrix2D
-		//		the end transormation (when animation ends)
-		//	onAnimationEnd: function
-		//		callback function to be executed when the animation completes.
-		var fromDx = fromTransform.dx?fromTransform.dx:0;
-		var fromDy = fromTransform.dy?fromTransform.dy:0;
-		var toDx = toTransform.dx?toTransform.dx:0;
-		var toDy = toTransform.dy?toTransform.dy:0;
-		var fromScale = fromTransform.xx?fromTransform.xx:1.0;
-		var toScale = toTransform.xx?toTransform.xx:1.0;
-		
-		var anim = gfx.fx.animateTransform({
-			duration: 1000,
-			shape: onShape,
-			transform: [{
-				name: "translate",
-				start: [fromDx,fromDy],
-				end: [toDx,toDy]
-			},
-			{
-				name: "scale",
-				start: [fromScale],
-				end: [toScale]
+		fitToMapArea: function(mapArea, pixelMargin, animate, onAnimationEnd){
+			// summary:
+			//		set this component's transformation so that the specified area fits in the component (centered)
+			// mapArea: Object
+			//		the map area that needs to fill the component expressed as {x,y,w,h}
+			// pixelMargin: int
+			//		a margin (in pixels) from the borders of the Map component.
+			// animate: boolean
+			//		true if the transform change should be animated
+			// onAnimationEnd: function
+			//		a callback function to be executed when the animation completes (if animate set to true).
+	
+			if(!pixelMargin){
+				pixelMargin = 0;
 			}
-			]
-		});
-
-		//install callback
-		if (onAnimationEnd) {
-			var listener = connect.connect(anim,"onEnd",this,function(event){
-				onAnimationEnd(event);
-				connect.disconnect(listener);
+			var width = mapArea.w,
+				height = mapArea.h,
+				containerBounds = this._getContainerBounds(),
+				scale = Math.min((containerBounds.w - 2 * pixelMargin) / width,
+								(containerBounds.h - 2 * pixelMargin) / height);
+	
+			this.setMapCenterAndScale(mapArea.x + mapArea.w / 2,mapArea.y + mapArea.h / 2,scale,animate,onAnimationEnd);
+		},
+	
+		fitToMapContents: function(pixelMargin,animate,/* callback function */onAnimationEnd){
+			// summary:
+			//		set this component's transformation so that the whole map data fits in the component (centered)
+			// pixelMargin: int
+			//		a margin (in pixels) from the borders of the Map component.
+			// animate: boolean
+			//		true if the transform change should be animated
+			// onAnimationEnd: function
+			//		a callback function to be executed when the animation completes (if animate set to true).
+	
+			//transform map to fit container
+			var bbox = this.mapObj.boundBox;
+			this.fitToMapArea(bbox,pixelMargin,animate,onAnimationEnd);
+		},
+	
+		setMapCenter: function(centerX,centerY,animate,/* callback function */onAnimationEnd){
+			// summary:
+			//		set this component's transformation so that the map is centered on the specified map coordinates
+			// centerX: float
+			//		the X coordinate (in map coordinates) of the new center
+			// centerY: float
+			//		the Y coordinate (in map coordinates) of the new center
+			// animate: boolean
+			//		true if the transform change should be animated
+			// onAnimationEnd: function
+			//		a callback function to be executed when the animation completes (if animate set to true).
+	
+			// call setMapCenterAndScale with current map scale
+			var currentScale = this.getMapScale();
+			this.setMapCenterAndScale(centerX,centerY,currentScale,animate,onAnimationEnd);
+	
+		},
+	
+		_createAnimation: function(onShape,fromTransform,toTransform,/* callback function */onAnimationEnd){
+			// summary:
+			//		creates a transform animation object (between two transforms) used internally
+			// onShape: dojox.gfx.shape.Shape
+			//		The target shape.
+			// fromTransform: dojox.gfx.matrix.Matrix2D
+			//		the start transformation (when animation begins)
+			// toTransform: dojox.gfx.matrix.Matrix2D
+			//		the end transormation (when animation ends)
+			// onAnimationEnd: function
+			//		callback function to be executed when the animation completes.
+			var fromDx = fromTransform.dx?fromTransform.dx:0;
+			var fromDy = fromTransform.dy?fromTransform.dy:0;
+			var toDx = toTransform.dx?toTransform.dx:0;
+			var toDy = toTransform.dy?toTransform.dy:0;
+			var fromScale = fromTransform.xx?fromTransform.xx:1.0;
+			var toScale = toTransform.xx?toTransform.xx:1.0;
+	
+			var anim = gfx.fx.animateTransform({
+				duration: 1000,
+				shape: onShape,
+				transform: [{
+					name: "translate",
+					start: [fromDx,fromDy],
+					end: [toDx,toDy]
+				},
+				{
+					name: "scale",
+					start: [fromScale],
+					end: [toScale]
+				}
+				]
 			});
-		}
-		
-		return anim;
-	},
-
 	
-	setMapCenterAndScale: function(centerX,centerY,scale, animate,/* callback function */onAnimationEnd) {
-		
-		//	summary: 
-		//		set this component's transformation so that the map is centered on the specified map coordinates
-		//		and scaled to the specified scale.
-		//	centerX: float
-		//		the X coordinate (in map coordinates) of the new center
-		//	centerY: float
-		//		the Y coordinate (in map coordinates) of the new center
-		//	scale: float
-		//		the scale of the map
-		//	animate: boolean
-		//		true if the transform change should be animated
-		//	onAnimationEnd: function
-		//		a callback function to be executed when the animation completes (if animate set to true).
-		
-		
-		// compute matrix parameters
-		var bbox = this.mapObj.boundBox;
-		var containerBounds = this._getContainerBounds();
-		var offsetX = containerBounds.w/2 - scale * (centerX - bbox.x);
-		var offsetY = containerBounds.h/2 - scale * (centerY - bbox.y);
-		var newTransform = new gfx.matrix.Matrix2D({xx: scale, yy: scale, dx:offsetX, dy:offsetY});
-		
-		
-		var currentTransform = this.mapObj.getTransform();
-		
-		// can animate only if specified AND curentTransform exists
-		if (!animate || !currentTransform) {
-			this.mapObj.setTransform(newTransform);
-		} else {
-			var anim = this._createAnimation(this.mapObj,currentTransform,newTransform,onAnimationEnd);
-			anim.play();
-		}
-	},
-	
-	getMapCenter: function() {
-		//	summary: 
-		//		returns the map coordinates of the center of this Map component.
-		//	returns: {x:,y:}
-		//		the center in map coordinates
-		var containerBounds = this._getContainerBounds();
-		return this.screenCoordsToMapCoords(containerBounds.w/2,containerBounds.h/2);
-	},
-	
-	setMapScale: function(scale,animate,/* callback function */onAnimationEnd) {
-		//	summary: 
-		//		set this component's transformation so that the map is scaled to the specified scale.
-		//	animate: boolean
-		//		true if the transform change should be animated
-		//	onAnimationEnd: function
-		//		a callback function to be executed when the animation completes (if animate set to true).
-		
-		
-		// default invariant is map center
-		var containerBounds = this._getContainerBounds();
-		var invariantMapPoint = this.screenCoordsToMapCoords(containerBounds.w/2,containerBounds.h/2);
-		this.setMapScaleAt(scale,invariantMapPoint.x,invariantMapPoint.y,animate,onAnimationEnd);
-	},
-	
-	setMapScaleAt: function(scale,fixedMapX,fixedMapY,animate,/* callback function */onAnimationEnd) {
-		//	summary: 
-	    //		set this component's transformation so that the map is scaled to the specified scale, and the specified 
-		//		point (in map coordinates) stays fixed on this Map component
-		//	fixedMapX: float
-		//		the X coordinate (in map coordinates) of the fixed screen point
-		//	fixedMapY: float
-		//		the Y coordinate (in map coordinates) of the fixed screen point
-		//	animate: boolean
-		//		true if the transform change should be animated
-		//	onAnimationEnd: function
-		//		a callback function to be executed when the animation completes (if animate set to true).
-		
-		
-		var invariantMapPoint = null;
-		var invariantScreenPoint = null;
-
-		invariantMapPoint = {x: fixedMapX, y: fixedMapY};
-		invariantScreenPoint = this.mapCoordsToScreenCoords(invariantMapPoint.x,invariantMapPoint.y);
-		
-		// compute matrix parameters
-		var bbox = this.mapObj.boundBox;
-		var offsetX = invariantScreenPoint.x - scale * (invariantMapPoint.x - bbox.x);
-		var offsetY = invariantScreenPoint.y - scale * (invariantMapPoint.y - bbox.y);
-		var newTransform = new gfx.matrix.Matrix2D({xx: scale, yy: scale, dx:offsetX, dy:offsetY});
-
-		var currentTransform = this.mapObj.getTransform();
-
-		// can animate only if specified AND curentTransform exists
-		if (!animate || !currentTransform) {
-			this.mapObj.setTransform(newTransform);
-		} else {
-			var anim = this._createAnimation(this.mapObj,currentTransform,newTransform,onAnimationEnd);
-			anim.play();
-		}
-	},
-	
-	getMapScale: function() {
-		//	summary: 
-		//		returns the scale of this Map component.
-		//	returns: float
-		//		the scale
-		var mat = this.mapObj.getTransform();
-		var scale = mat?mat.xx:1.0;
-		return scale;
-	},
-	
-	mapCoordsToScreenCoords: function(mapX,mapY) {
-		//	summary: 
-		//		converts map coordinates to screen coordinates given the current transform of this Map component
-		//	returns: {x:,y:}
-		//		the screen coordinates correspondig to the specified map coordinates.
-		var matrix = this.mapObj.getTransform();
-		var screenPoint = gfx.matrix.multiplyPoint(matrix, mapX, mapY);
-		return screenPoint;
-	},
-	
-	screenCoordsToMapCoords: function(screenX, screenY) {
-		//	summary: 
-		//		converts screen coordinates to map coordinates given the current transform of this Map component
-		//	returns: {x:,y:}
-		//		the map coordinates corresponding to the specified screen coordinates.
-		var invMatrix = gfx.matrix.invert(this.mapObj.getTransform());
-		var mapPoint = gfx.matrix.multiplyPoint(invMatrix, screenX, screenY);
-		return mapPoint;
-	},
-	deselectAll: function(){
-		//	summary:
-		//		deselect all features of map
-		for(var name in this.mapObj.features){
-			this.mapObj.features[name].select(false);
-		}
-		this.selectedFeature = null;
-		this.focused = false;
-	},
+			//install callback
+			if(onAnimationEnd){
+				var listener = connect.connect(anim,"onEnd",this,function(event){
+					onAnimationEnd(event);
+					connect.disconnect(listener);
+				});
+			}
 	
-	_init: function(shapeData){
-		
-		//	summary: 
-		//		inits this Map component.
-		
-		//transform map to fit container
-		this.mapObj.boundBox = {x: shapeData.layerExtent[0],
-								y: shapeData.layerExtent[1],
-								w: (shapeData.layerExtent[2] - shapeData.layerExtent[0]),
-								h: shapeData.layerExtent[3] - shapeData.layerExtent[1]};
-		this.fitToMapContents(3);
-
-
-		//	if there are "features", then implement them now.
-		arr.forEach(shapeData.featureNames, function(item){
-			var featureShape = shapeData.features[item];
-			featureShape.bbox.x = featureShape.bbox[0];
-			featureShape.bbox.y = featureShape.bbox[1];
-			featureShape.bbox.w = featureShape.bbox[2];
-			featureShape.bbox.h = featureShape.bbox[3];
-			var feature = new Feature(this, item, featureShape);
-			feature.init();
-			this.mapObj.features[item] = feature;
-		}, this);
-		
-
-		//	set up a marker.
-		this.mapObj.marker = new Marker({}, this);
-	},
-	_appendMarker: function(markerData){
-		this.mapObj.marker = new Marker(markerData, this);
-	},
-	_createZoomingCursor: function(){
-		if(!dom.byId("mapZoomCursor")){
-			var mapZoomCursor = win.doc.createElement("div");
-			html.attr(mapZoomCursor,"id","mapZoomCursor");
-			domClass.add(mapZoomCursor,"mapZoomIn");
-			html.style(mapZoomCursor,"display","none");
-			win.body().appendChild(mapZoomCursor);
+			return anim;
+		},
+	
+	
+		setMapCenterAndScale: function(centerX,centerY,scale, animate,/* callback function */onAnimationEnd){
+	
+			// summary:
+			//		set this component's transformation so that the map is centered on the specified map coordinates
+			//		and scaled to the specified scale.
+			// centerX: float
+			//		the X coordinate (in map coordinates) of the new center
+			// centerY: float
+			//		the Y coordinate (in map coordinates) of the new center
+			// scale: float
+			//		the scale of the map
+			// animate: boolean
+			//		true if the transform change should be animated
+			// onAnimationEnd: function
+			//		a callback function to be executed when the animation completes (if animate set to true).
+	
+	
+			// compute matrix parameters
+			var bbox = this.mapObj.boundBox;
+			var containerBounds = this._getContainerBounds();
+			var offsetX = containerBounds.w/2 - scale * (centerX - bbox.x);
+			var offsetY = containerBounds.h/2 - scale * (centerY - bbox.y);
+			var newTransform = new gfx.matrix.Matrix2D({xx: scale, yy: scale, dx:offsetX, dy:offsetY});
+	
+	
+			var currentTransform = this.mapObj.getTransform();
+	
+			// can animate only if specified AND curentTransform exists
+			if(!animate || !currentTransform){
+				this.mapObj.setTransform(newTransform);
+			}else{
+				var anim = this._createAnimation(this.mapObj,currentTransform,newTransform,onAnimationEnd);
+				anim.play();
+			}
+		},
+	
+		getMapCenter: function(){
+			// summary:
+			//		returns the map coordinates of the center of this Map component.
+			// returns: point
+			//		the center in map coordinates
+			var containerBounds = this._getContainerBounds();
+			return this.screenCoordsToMapCoords(containerBounds.w/2,containerBounds.h/2); // point
+		},
+	
+		setMapScale: function(scale,animate,/* callback function */onAnimationEnd){
+			// summary:
+			//		set this component's transformation so that the map is scaled to the specified scale.
+			// scale: Number
+			//		the scale ratio.
+			// animate: boolean
+			//		true if the transform change should be animated
+			// onAnimationEnd: function
+			//		a callback function to be executed when the animation completes (if animate set to true).
+	
+	
+			// default invariant is map center
+			var containerBounds = this._getContainerBounds();
+			var invariantMapPoint = this.screenCoordsToMapCoords(containerBounds.w/2,containerBounds.h/2);
+			this.setMapScaleAt(scale,invariantMapPoint.x,invariantMapPoint.y,animate,onAnimationEnd);
+		},
+	
+		setMapScaleAt: function(scale,fixedMapX,fixedMapY,animate,/* callback function */onAnimationEnd){
+			// summary:
+			//		set this component's transformation so that the map is scaled to the specified scale, and the specified
+			//		point (in map coordinates) stays fixed on this Map component
+			// scale: Number
+			//		the scale ratio.
+			// fixedMapX: float
+			//		the X coordinate (in map coordinates) of the fixed screen point
+			// fixedMapY: float
+			//		the Y coordinate (in map coordinates) of the fixed screen point
+			// animate: boolean
+			//		true if the transform change should be animated
+			// onAnimationEnd: function
+			//		a callback function to be executed when the animation completes (if animate set to true).
+	
+	
+			var invariantMapPoint = null;
+			var invariantScreenPoint = null;
+	
+			invariantMapPoint = {x: fixedMapX, y: fixedMapY};
+			invariantScreenPoint = this.mapCoordsToScreenCoords(invariantMapPoint.x,invariantMapPoint.y);
+	
+			// compute matrix parameters
+			var bbox = this.mapObj.boundBox;
+			var offsetX = invariantScreenPoint.x - scale * (invariantMapPoint.x - bbox.x);
+			var offsetY = invariantScreenPoint.y - scale * (invariantMapPoint.y - bbox.y);
+			var newTransform = new gfx.matrix.Matrix2D({xx: scale, yy: scale, dx:offsetX, dy:offsetY});
+	
+			var currentTransform = this.mapObj.getTransform();
+	
+			// can animate only if specified AND curentTransform exists
+			if(!animate || !currentTransform){
+				this.mapObj.setTransform(newTransform);
+			}else{
+				var anim = this._createAnimation(this.mapObj,currentTransform,newTransform,onAnimationEnd);
+				anim.play();
+			}
+		},
+	
+		getMapScale: function(){
+			// summary:
+			//		returns the scale of this Map component.
+			// returns: float
+			//		the scale
+			var mat = this.mapObj.getTransform();
+			var scale = mat?mat.xx:1.0;
+			return scale; // Number
+		},
+	
+		mapCoordsToScreenCoords: function(mapX,mapY){
+			// summary:
+			//		converts map coordinates to screen coordinates given the current transform of this Map component
+			// mapX: Number
+			//		the x coordinate of the point to convert.
+			// mapY: Number
+			//		the y coordinate of the point to convert.
+			// returns: {x:,y:}
+			//		the screen coordinates correspondig to the specified map coordinates.
+			var matrix = this.mapObj.getTransform();
+			var screenPoint = gfx.matrix.multiplyPoint(matrix, mapX, mapY);
+			return screenPoint; // point
+		},
+	
+		screenCoordsToMapCoords: function(screenX, screenY){
+			// summary:
+			//		converts screen coordinates to map coordinates given the current transform of this Map component
+			// screenX: Number
+			//		the x coordinate of the point to convert.
+			// screenY: Number
+			//		the y coordinate of the point to convert.
+			// returns:
+			//		the map coordinates corresponding to the specified screen coordinates.
+			var invMatrix = gfx.matrix.invert(this.mapObj.getTransform());
+			var mapPoint = gfx.matrix.multiplyPoint(invMatrix, screenX, screenY);
+			return mapPoint; // point
+		},
+		deselectAll: function(){
+			// summary:
+			//		deselect all features of map
+			for(var name in this.mapObj.features){
+				this.mapObj.features[name].select(false);
+			}
+			this.selectedFeature = null;
+			this.focused = false;
+		},
+	
+		_init: function(shapeData){
+			// summary:
+			//		inits this Map component.
+	
+			//transform map to fit container
+			this.mapObj.boundBox = {x: shapeData.layerExtent[0],
+									y: shapeData.layerExtent[1],
+									w: (shapeData.layerExtent[2] - shapeData.layerExtent[0]),
+									h: shapeData.layerExtent[3] - shapeData.layerExtent[1]};
+			this.fitToMapContents(3);
+	
+	
+			//	if there are "features", then implement them now.
+			arr.forEach(shapeData.featureNames, function(item){
+				var featureShape = shapeData.features[item];
+				featureShape.bbox.x = featureShape.bbox[0];
+				featureShape.bbox.y = featureShape.bbox[1];
+				featureShape.bbox.w = featureShape.bbox[2];
+				featureShape.bbox.h = featureShape.bbox[3];
+				var feature = new Feature(this, item, featureShape);
+				feature.init();
+				this.mapObj.features[item] = feature;
+			}, this);
+	
+	
+			//	set up a marker.
+			this.mapObj.marker = new Marker({}, this);
+		},
+		_appendMarker: function(markerData){
+			this.mapObj.marker = new Marker(markerData, this);
+		},
+		_createZoomingCursor: function(){
+			if(!dom.byId("mapZoomCursor")){
+				var mapZoomCursor = win.doc.createElement("div");
+				html.attr(mapZoomCursor,"id","mapZoomCursor");
+				domClass.add(mapZoomCursor,"mapZoomIn");
+				html.style(mapZoomCursor,"display","none");
+				win.body().appendChild(mapZoomCursor);
+			}
+		},
+		onFeatureClick: function(feature){
+			// summary:
+			//		Invoked when the specified feature is clicked.
+			// feature: dojox.geo.charting.Feature
+			//		A Feature.
+			// tags:
+			//		callback
+		},
+		onFeatureOver: function(feature){
+			// summary:
+			//		Invoked when the specified feature is hovered.
+			// feature: dojox.geo.charting.Feature
+			//		A Feature.
+			// tags:
+			//		callback
+		},
+		onZoomEnd:function(feature){
+			// summary:
+			//		Invoked when the specified feature has been zoomed.
+			// feature: dojox.geo.charting.Feature
+			//		A Feature.
+			// tags:
+			//		callback
 		}
-	},
-	onFeatureClick: function(feature){
-	},
-	onFeatureOver: function(feature){
-	},
-	onZoomEnd:function(feature){
-	}
-});
+	});
 });
\ No newline at end of file
diff --git a/dojox/geo/charting/MouseInteractionSupport.js b/dojox/geo/charting/MouseInteractionSupport.js
index fa70fc1..a43a0b7 100644
--- a/dojox/geo/charting/MouseInteractionSupport.js
+++ b/dojox/geo/charting/MouseInteractionSupport.js
@@ -1,334 +1,366 @@
-define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/event",
-		"dojo/_base/connect","dojo/_base/window","dojo/_base/html","dojo/dom","dojo/_base/sniff"],
-  function(lang, declare, event, connect, win, html, dom, has) {
-
-return declare("dojox.geo.charting.MouseInteractionSupport", null, {
-	//	summary: 
-	//		class to handle mouse interactions on a dojox.geo.charting.Map widget
-	//	tags:
-	//		private
-	
-	_map : null,
-	_mapClickLocation : null,
-	_screenClickLocation: null,
-	_mouseDragListener: null,
-	_mouseUpListener: null,
-	_mouseUpClickListener: null,
-	_mouseDownListener: null,
-	_mouseMoveListener: null,
-	_mouseWheelListener: null,
-	_currentFeature: null,
-	_cancelMouseClick: null,
-	_zoomEnabled: false,
-	_panEnabled: false,
-	_onDragStartListener: null,
-	_onSelectStartListener: null,
-
-
-	mouseClickThreshold: 2,
-
-	constructor : function(/* Map */map,/*boolean*/options) {
-		//	summary: 
-		//		Constructs a new _MouseInteractionSupport instance
-		//	map: dojox.geo.charting.Map
-		//		the Map widget this class provides touch navigation for.
-		//	options: object
-		//		to enable panning and mouse wheel zooming
-		this._map = map;
-		this._mapClickLocation = {x: 0,y: 0};
-		this._screenClickLocation = {x: 0,y: 0};
-		this._cancelMouseClick = false;
-		if (options) {
-			this._zoomEnabled = options.enableZoom;
-			this._panEnabled = options.enablePan;
-			if (options.mouseClickThreshold && options.mouseClickThreshold > 0) {
-				this.mouseClickThreshold = options.mouseClickThreshold;
-			}
-		}
-	},
-
-	setEnableZoom: function(enable){
-		//	summary: 
-		//		enables mouse zoom on the map
-		if (enable && !this._mouseWheelListener) {
-			// enable
-			var wheelEventName = !has("mozilla") ? "onmousewheel" : "DOMMouseScroll";
-			this._mouseWheelListener = this._map.surface.connect(wheelEventName, this, this._mouseWheelHandler);
-		} else if (!enable && this._mouseWheelListener) {
-			// disable
-			connect.disconnect(this._mouseWheelListener);
-			this._mouseWheelListener = null;
-		}
-		this._zoomEnabled = enable;
-	},
-
-	setEnablePan: function(enable){
-		//	summary: 
-		//		enables mouse panning on the map
-		this._panEnabled = enable;
-	},
-
-	connect: function() {
-		//	summary: 
-		//		connects this mouse support class to the Map component
-		
-		// install mouse listeners
-		this._mouseMoveListener = this._map.surface.connect("onmousemove", this, this._mouseMoveHandler);
-		this._mouseDownListener = this._map.surface.connect("onmousedown", this, this._mouseDownHandler);
-		
-		if (has("ie")) {
-			_onDragStartListener = connect.connect(win.doc,"ondragstart",this,event.stop);
-			_onSelectStartListener = connect.connect(win.doc,"onselectstart",this,event.stop);			
-		}
-		
-		this.setEnableZoom(this._zoomEnabled);
-		this.setEnablePan(this._panEnabled);
-	},
-
-	disconnect: function() {
-		//	summary: 
-		//		disconnects any installed listeners
-		
-		// store zoomPan state
-		var isZoom = this._zoomEnabled;
-		
-		// disable zoom (disconnects listeners..)
-		this.setEnableZoom(false);
-		
-		// restore value
-		this._zoomEnabled = isZoom;
-		
-		// disconnect remaining listeners
-		if (this._mouseMoveListener) {
-			connect.disconnect(this._mouseMoveListener);
-			this._mouseMoveListener = null;
-			connect.disconnect(this._mouseDownListener);
-			this._mouseDownListener = null;
-		}
-		if (this._onDragStartListener) {
-			connect.disconnect(this._onDragStartListener);
-			this._onDragStartListener = null;
-			connect.disconnect(this._onSelectStartListener);
-			this._onSelectStartListener = null;
-		}
-		
-	},
-
-	_mouseClickHandler: function(mouseEvent) {
-		//	summary: 
-		//		action performed on the map when a mouse click was performed
-		//	mouseEvent: the mouse event
-		//	tags:
+define([
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/connect",
+	"dojo/_base/window",
+	"dojo/_base/html",
+	"dojo/dom",
+	"dojo/_base/sniff"
+], function(lang, declare, event, connect, win, html, dom, has){
+
+	/*=====
+	dojox.geo.charting.__MouseInteractionSupportCtorArgs = {
+		// summary:
+		//		The keyword arguments that can be passed in a MouseInteractionSupport constructor.
+		// enableZoom: Boolean?
+		//		Indicates whether zooming is enabled.
+		// enablePan: Boolean?
+		//		Indicates whether panning is enabled.
+		// mouseClickThreshold: Number?
+		//		The threshold (in pixel) that differentiates a drag from a click.
+	};
+	=====*/
+
+	return declare("dojox.geo.charting.MouseInteractionSupport", null, {
+		// summary:
+		//		class to handle mouse interactions on a dojox.geo.charting.Map widget
+		// tags:
 		//		private
-		
-		var feature = this._getFeatureFromMouseEvent(mouseEvent);
-		
-		if (feature) {
-			// call feature handler
-			feature._onclickHandler(mouseEvent);
-		} else {
-			// unselect all
-			for (var name in this._map.mapObj.features){
-				this._map.mapObj.features[name].select(false);
+
+		_map: null,
+		_mapClickLocation: null,
+		_screenClickLocation: null,
+		_mouseDragListener: null,
+		_mouseUpListener: null,
+		_mouseUpClickListener: null,
+		_mouseDownListener: null,
+		_mouseMoveListener: null,
+		_mouseWheelListener: null,
+		_currentFeature: null,
+		_cancelMouseClick: null,
+		_zoomEnabled: false,
+		_panEnabled: false,
+		_onDragStartListener: null,
+		_onSelectStartListener: null,
+
+
+		mouseClickThreshold: 2,
+
+		constructor : function(map, options){
+			// summary:
+			//		Constructs a new _MouseInteractionSupport instance
+			// map: dojox/geo/charting/Map
+			//		the Map widget this class provides touch navigation for.
+			// options: dojox.geo.charting.__MouseInteractionSupportCtorArgs?
+			//		An object defining additional configuration properties.
+			this._map = map;
+			this._mapClickLocation = {x: 0,y: 0};
+			this._screenClickLocation = {x: 0,y: 0};
+			this._cancelMouseClick = false;
+			if(options){
+				this._zoomEnabled = options.enableZoom;
+				this._panEnabled = options.enablePan;
+				if(options.mouseClickThreshold && options.mouseClickThreshold > 0){
+					this.mouseClickThreshold = options.mouseClickThreshold;
+				}
 			}
-			this._map.onFeatureClick(null);
-		}
-			
-	},
-
-	_mouseDownHandler: function(mouseEvent){
-		//	summary: 
-		//		action performed on the map when a mouse down was performed
-		//	mouseEvent: the mouse event
-		//	tags:
-		//		private
-		
-		
-		event.stop(mouseEvent);
-		
-		this._map.focused = true;
-		// set various status parameters
-		this._cancelMouseClick = false;
-		this._screenClickLocation.x =  mouseEvent.pageX;
-		this._screenClickLocation.y =  mouseEvent.pageY;
-
-		// store map location where mouse down occurred
-		var containerBounds = this._map._getContainerBounds();
-		var offX = mouseEvent.pageX	- containerBounds.x,
-			offY = mouseEvent.pageY - containerBounds.y;
-		var mapPoint = this._map.screenCoordsToMapCoords(offX,offY);
-		this._mapClickLocation.x = mapPoint.x;
-		this._mapClickLocation.y = mapPoint.y;
-
-		// install drag listener if pan is enabled
-		if (!has("ie")) {
-			this._mouseDragListener = connect.connect(win.doc,"onmousemove",this,this._mouseDragHandler);
-			this._mouseUpClickListener = this._map.surface.connect("onmouseup", this, this._mouseUpClickHandler);
-			this._mouseUpListener = connect.connect(win.doc,"onmouseup",this, this._mouseUpHandler);
-		} else {
-			var node = dom.byId(this._map.container);
-			this._mouseDragListener = connect.connect(node,"onmousemove",this,this._mouseDragHandler);
-			this._mouseUpClickListener = this._map.surface.connect("onmouseup", this, this._mouseUpClickHandler);
-			this._mouseUpListener = this._map.surface.connect("onmouseup", this, this._mouseUpHandler);
-			this._map.surface.rawNode.setCapture();
-		}
-	},
+		},
 
-	_mouseUpClickHandler: function(mouseEvent) {
-		
-		if (!this._cancelMouseClick) {
-			// execute mouse click handler
-			this._mouseClickHandler(mouseEvent);
-		}
-		this._cancelMouseClick = false;
-		
-	},
-
-	_mouseUpHandler: function(mouseEvent) {
-		//	summary: 
-		//		action performed on the map when a mouse up was performed
-		//	mouseEvent: the mouse event
-		//	tags:
-		//		private
-		
-		event.stop(mouseEvent);
-		
-		this._map.mapObj.marker._needTooltipRefresh = true;
-		
-		// disconnect listeners
-		if (this._mouseDragListener) {
-			connect.disconnect(this._mouseDragListener);
-			this._mouseDragListener = null;
-		}
-		if (this._mouseUpClickListener) {
-			connect.disconnect(this._mouseUpClickListener);
-			this._mouseUpClickListener = null;
-		}
-		if (this._mouseUpListener) {
-			connect.disconnect(this._mouseUpListener);
-			this._mouseUpListener = null;
-		}
-		
-		if (has("ie")) {
-			this._map.surface.rawNode.releaseCapture();
-		}
-	},
-
-	_getFeatureFromMouseEvent: function(mouseEvent) {
-		//	summary: 
-		//		utility function to return the feature located at this mouse event location
-		//	mouseEvent: the mouse event
-		//	returns: dojox.geo.charting.Feature
-		//		the feature found if any, null otherwise.
-		//	tags:
-		//		private
-		var feature = null;
-		if (mouseEvent.gfxTarget && mouseEvent.gfxTarget.getParent) {
-			feature = this._map.mapObj.features[mouseEvent.gfxTarget.getParent().id];
-		}
-		return feature;
-	},
-
-	_mouseMoveHandler: function(mouseEvent) {
-		//	summary: 
-		//		action performed on the map when a mouse move was performed
-		//	mouseEvent: the mouse event
-		//	tags:
-		//		private
+		setEnableZoom: function(enable){
+			// summary:
+			//		enables mouse zoom on the map
+			// enable: Boolean
+			//		Indicates whether mouse zoom is enabled.
+			if(enable && !this._mouseWheelListener){
+				// enable
+				var wheelEventName = !has("mozilla") ? "onmousewheel" : "DOMMouseScroll";
+				this._mouseWheelListener = this._map.surface.connect(wheelEventName, this, this._mouseWheelHandler);
+			}else if(!enable && this._mouseWheelListener){
+				// disable
+				connect.disconnect(this._mouseWheelListener);
+				this._mouseWheelListener = null;
+			}
+			this._zoomEnabled = enable;
+		},
 
-		
-		// do nothing more if dragging
-		if (this._mouseDragListener && this._panEnabled) {
-			return;
-		}
-		
-		// hover and highlight
-		var feature = this._getFeatureFromMouseEvent(mouseEvent);
-
-		// set/unset highlight
-		if (feature != this._currentFeature) {
-			if (this._currentFeature) {
-				// mouse leaving component
-				this._currentFeature._onmouseoutHandler();
+		setEnablePan: function(enable){
+			// summary:
+			//		enables mouse panning on the map
+			// enable: Boolean
+			//		Indicates whether mouse zoom is enabled.
+			this._panEnabled = enable;
+		},
+
+		connect: function(){
+			// summary:
+			//		connects this mouse support class to the Map component
+
+			// install mouse listeners
+			this._mouseMoveListener = this._map.surface.connect("onmousemove", this, this._mouseMoveHandler);
+			this._mouseDownListener = this._map.surface.connect("onmousedown", this, this._mouseDownHandler);
+
+			if(has("ie")){
+				_onDragStartListener = connect.connect(win.doc,"ondragstart",this,event.stop);
+				_onSelectStartListener = connect.connect(win.doc,"onselectstart",this,event.stop);
 			}
-			this._currentFeature = feature;
-			
-			if (feature)
-				feature._onmouseoverHandler();
-		}
 
-		if (feature)
-			feature._onmousemoveHandler(mouseEvent);
-	},
+			this.setEnableZoom(this._zoomEnabled);
+			this.setEnablePan(this._panEnabled);
+		},
 
-	_mouseDragHandler: function(mouseEvent){
-		//	summary: 
-		//		action performed on the map when a mouse drag was performed
-		//	mouseEvent: the mouse event
-		//	tags:
-		//		private
-		
-		// prevent browser interaction
-		event.stop(mouseEvent);
-		
-		
-		// find out if this the movement discards the "mouse click" gesture
-		var dx = Math.abs(mouseEvent.pageX - this._screenClickLocation.x);
-		var dy = Math.abs(mouseEvent.pageY - this._screenClickLocation.y);
-		if (!this._cancelMouseClick && (dx > this.mouseClickThreshold || dy > this.mouseClickThreshold)) {
-			// cancel mouse click
-			this._cancelMouseClick = true;
-			if (this._panEnabled) {
-				this._map.mapObj.marker.hide();
+		disconnect: function(){
+			// summary:
+			//		disconnects any installed listeners
+
+			// store zoomPan state
+			var isZoom = this._zoomEnabled;
+
+			// disable zoom (disconnects listeners..)
+			this.setEnableZoom(false);
+
+			// restore value
+			this._zoomEnabled = isZoom;
+
+			// disconnect remaining listeners
+			if(this._mouseMoveListener){
+				connect.disconnect(this._mouseMoveListener);
+				this._mouseMoveListener = null;
+				connect.disconnect(this._mouseDownListener);
+				this._mouseDownListener = null;
+			}
+			if(this._onDragStartListener){
+				connect.disconnect(this._onDragStartListener);
+				this._onDragStartListener = null;
+				connect.disconnect(this._onSelectStartListener);
+				this._onSelectStartListener = null;
 			}
+
+		},
+
+		_mouseClickHandler: function(mouseEvent){
+			// summary:
+			//		action performed on the map when a mouse click was performed
+			// mouseEvent: MouseEvent
+			//		the mouse event
+			// tags:
+			//		private
+
+			var feature = this._getFeatureFromMouseEvent(mouseEvent);
+
+			if(feature){
+				// call feature handler
+				feature._onclickHandler(mouseEvent);
+			}else{
+				// unselect all
+				for(var name in this._map.mapObj.features){
+					this._map.mapObj.features[name].select(false);
+				}
+				this._map.onFeatureClick(null);
+			}
+
+		},
+
+		_mouseDownHandler: function(mouseEvent){
+			// summary:
+			//		action performed on the map when a mouse down was performed
+			// mouseEvent: MouseEvent
+			//		the mouse event
+			// tags:
+			//		private
+
+
+			event.stop(mouseEvent);
+
+			this._map.focused = true;
+			// set various status parameters
+			this._cancelMouseClick = false;
+			this._screenClickLocation.x =  mouseEvent.pageX;
+			this._screenClickLocation.y =  mouseEvent.pageY;
+
+			// store map location where mouse down occurred
+			var containerBounds = this._map._getContainerBounds();
+			var offX = mouseEvent.pageX	- containerBounds.x,
+				offY = mouseEvent.pageY - containerBounds.y;
+			var mapPoint = this._map.screenCoordsToMapCoords(offX,offY);
+			this._mapClickLocation.x = mapPoint.x;
+			this._mapClickLocation.y = mapPoint.y;
+
+			// install drag listener if pan is enabled
+			if(!has("ie")){
+				this._mouseDragListener = connect.connect(win.doc,"onmousemove",this,this._mouseDragHandler);
+				this._mouseUpClickListener = this._map.surface.connect("onmouseup", this, this._mouseUpClickHandler);
+				this._mouseUpListener = connect.connect(win.doc,"onmouseup",this, this._mouseUpHandler);
+			}else{
+				var node = dom.byId(this._map.container);
+				this._mouseDragListener = connect.connect(node,"onmousemove",this,this._mouseDragHandler);
+				this._mouseUpClickListener = this._map.surface.connect("onmouseup", this, this._mouseUpClickHandler);
+				this._mouseUpListener = this._map.surface.connect("onmouseup", this, this._mouseUpHandler);
+				this._map.surface.rawNode.setCapture();
+			}
+		},
+
+		_mouseUpClickHandler: function(mouseEvent){
+
+			if(!this._cancelMouseClick){
+				// execute mouse click handler
+				this._mouseClickHandler(mouseEvent);
+			}
+			this._cancelMouseClick = false;
+
+		},
+
+		_mouseUpHandler: function(mouseEvent){
+			// summary:
+			//		action performed on the map when a mouse up was performed
+			// mouseEvent: MouseEvent
+			//		the mouse event
+			// tags:
+			//		private
+
+			event.stop(mouseEvent);
+
+			this._map.mapObj.marker._needTooltipRefresh = true;
+
+			// disconnect listeners
+			if(this._mouseDragListener){
+				connect.disconnect(this._mouseDragListener);
+				this._mouseDragListener = null;
+			}
+			if(this._mouseUpClickListener){
+				connect.disconnect(this._mouseUpClickListener);
+				this._mouseUpClickListener = null;
+			}
+			if(this._mouseUpListener){
+				connect.disconnect(this._mouseUpListener);
+				this._mouseUpListener = null;
+			}
+
+			if(has("ie")){
+				this._map.surface.rawNode.releaseCapture();
+			}
+		},
+
+		_getFeatureFromMouseEvent: function(mouseEvent){
+			// summary:
+			//		utility function to return the feature located at this mouse event location
+			// mouseEvent: MouseEvent
+			//		the mouse event
+			// returns:
+			//		the feature found if any, null otherwise.
+			// tags:
+			//		private
+			var feature = null;
+			if(mouseEvent.gfxTarget && mouseEvent.gfxTarget.getParent){
+				feature = this._map.mapObj.features[mouseEvent.gfxTarget.getParent().id];
+			}
+			return feature; // dojox/geo/charting/Feature
+		},
+
+		_mouseMoveHandler: function(mouseEvent){
+			// summary:
+			//		action performed on the map when a mouse move was performed
+			// mouseEvent: MouseEvent
+			//		the mouse event
+			// tags:
+			//		private
+
+
+			// do nothing more if dragging
+			if(this._mouseDragListener && this._panEnabled){
+				return;
+			}
+
+			// hover and highlight
+			var feature = this._getFeatureFromMouseEvent(mouseEvent);
+
+			// set/unset highlight
+			if(feature != this._currentFeature){
+				if(this._currentFeature){
+					// mouse leaving component
+					this._currentFeature._onmouseoutHandler();
+				}
+				this._currentFeature = feature;
+
+				if(feature){
+					feature._onmouseoverHandler();
+				}
+			}
+
+			if(feature){
+				feature._onmousemoveHandler(mouseEvent);
+			}
+		},
+
+		_mouseDragHandler: function(mouseEvent){
+			// summary:
+			//		action performed on the map when a mouse drag was performed
+			// mouseEvent: MouseEvent
+			//		the mouse event
+			// tags:
+			//		private
+
+			// prevent browser interaction
+			event.stop(mouseEvent);
+
+
+			// find out if this the movement discards the "mouse click" gesture
+			var dx = Math.abs(mouseEvent.pageX - this._screenClickLocation.x);
+			var dy = Math.abs(mouseEvent.pageY - this._screenClickLocation.y);
+			if(!this._cancelMouseClick && (dx > this.mouseClickThreshold || dy > this.mouseClickThreshold)){
+				// cancel mouse click
+				this._cancelMouseClick = true;
+				if(this._panEnabled){
+					this._map.mapObj.marker.hide();
+				}
+			}
+
+			if(!this._panEnabled){
+				return;
+			}
+
+			var cBounds = this._map._getContainerBounds();
+			var offX = mouseEvent.pageX - cBounds.x,
+			offY = mouseEvent.pageY - cBounds.y;
+
+			// compute map offset
+			var mapPoint = this._map.screenCoordsToMapCoords(offX,offY);
+			var mapOffsetX = mapPoint.x - this._mapClickLocation.x;
+			var mapOffsetY = mapPoint.y - this._mapClickLocation.y;
+
+			// adjust map center
+			var currentMapCenter = this._map.getMapCenter();
+			this._map.setMapCenter(currentMapCenter.x - mapOffsetX, currentMapCenter.y - mapOffsetY);
+
+		},
+
+		_mouseWheelHandler: function(mouseEvent){
+			// summary:
+			//		action performed on the map when a mouse wheel up/down was performed
+			// mouseEvent: MouseEvent
+			//		the mouse event
+			// tags:
+			//		private
+
+			// prevent browser interaction
+			event.stop(mouseEvent);
+
+			// hide tooltip
+			this._map.mapObj.marker.hide();
+
+			// event coords within component
+			var containerBounds = this._map._getContainerBounds();
+			var offX = mouseEvent.pageX - containerBounds.x,
+				offY = mouseEvent.pageY - containerBounds.y;
+
+			// current map point before zooming
+			var invariantMapPoint = this._map.screenCoordsToMapCoords(offX,offY);
+
+			// zoom increment power
+			var power  = mouseEvent[(has("mozilla") ? "detail" : "wheelDelta")] / (has("mozilla") ? - 3 : 120) ;
+			var scaleFactor = Math.pow(1.2,power);
+			this._map.setMapScaleAt(this._map.getMapScale()*scaleFactor ,invariantMapPoint.x,invariantMapPoint.y,false);
+			this._map.mapObj.marker._needTooltipRefresh = true;
 		}
-		
-		if (!this._panEnabled)
-			return;
-
-		var cBounds = this._map._getContainerBounds();
-		var offX = mouseEvent.pageX - cBounds.x,
-		offY = mouseEvent.pageY - cBounds.y;
-		
-		// compute map offset
-		var mapPoint = this._map.screenCoordsToMapCoords(offX,offY);
-		var mapOffsetX = mapPoint.x - this._mapClickLocation.x;
-		var mapOffsetY = mapPoint.y - this._mapClickLocation.y;
-
-		// adjust map center
-		var currentMapCenter = this._map.getMapCenter();
-		this._map.setMapCenter(currentMapCenter.x - mapOffsetX, currentMapCenter.y - mapOffsetY);
-		
-	},
-
-	_mouseWheelHandler: function(mouseEvent) {
-		//	summary: 
-		//		action performed on the map when a mouse wheel up/down was performed
-		//	mouseEvent: the mouse event
-		//	tags:
-		//		private
-		
-
-		// prevent browser interaction
-		event.stop(mouseEvent);
-		
-		// hide tooltip
-		this._map.mapObj.marker.hide();
-		
-		// event coords within component
-		var containerBounds = this._map._getContainerBounds();
-		var offX = mouseEvent.pageX - containerBounds.x,
-			offY = mouseEvent.pageY - containerBounds.y;
-		
-		// current map point before zooming
-		var invariantMapPoint = this._map.screenCoordsToMapCoords(offX,offY);
-
-		// zoom increment power
-		var power  = mouseEvent[(has("mozilla") ? "detail" : "wheelDelta")] / (has("mozilla") ? - 3 : 120) ;
-		var scaleFactor = Math.pow(1.2,power);
-		this._map.setMapScaleAt(this._map.getMapScale()*scaleFactor ,invariantMapPoint.x,invariantMapPoint.y,false);
-		this._map.mapObj.marker._needTooltipRefresh = true;
-		
-	}
-});
+	});
 });
diff --git a/dojox/geo/charting/TouchInteractionSupport.js b/dojox/geo/charting/TouchInteractionSupport.js
index e196ab2..c71e436 100644
--- a/dojox/geo/charting/TouchInteractionSupport.js
+++ b/dojox/geo/charting/TouchInteractionSupport.js
@@ -1,312 +1,328 @@
-define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/event", "dojo/_base/connect","dojo/_base/window"],
-  function(lang,declare,event,connect,win) {
+define([
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/connect",
+	"dojo/_base/window"
+], function(lang,declare,event,connect,win){
 
-return declare("dojox.geo.charting.TouchInteractionSupport",null, {
-	//	summary: 
-	//		class to handle touch interactions on a dojox.geo.charting.Map widget
-	//	tags:
-	//		private
-	
-	_map : null,
-	_centerTouchLocation : null,
-	_touchMoveListener: null,
-	_touchEndListener: null,
-	_touchEndTapListener: null,
-	_touchStartListener: null,
-	_initialFingerSpacing: null,
-	_initialScale: null,
-	_tapCount: null,
-	_tapThreshold: null,
-	_lastTap: null,
-	_doubleTapPerformed:false,
-	_oneFingerTouch:false,
-	_tapCancel:false,
-	
-	constructor : function(/* dojox.geo.charting.Map */map,options) {
-		//	summary: 
-		//		Constructs a new _TouchInteractionSupport instance
-		//	map: dojox.geo.charting.Map
-		//		the Map widget this class provides touch navigation for.
-		this._map = map;
-		this._centerTouchLocation = {x: 0,y: 0};		
-				
-		this._tapCount = 0;
-		this._lastTap = {x: 0,y: 0};
-		this._tapThreshold = 100; // square distance in pixels
-	},
+	return declare("dojox.geo.charting.TouchInteractionSupport",null, {
+		// summary:
+		//		A class to handle touch interactions on a dojox/geo/charting/Map component.
+		// tags:
+		//		private
 
-	connect: function() {
-		//	summary: 
-		//		install touch listeners
-		_touchStartListener = this._map.surface.connect("touchstart", this, this._touchStartHandler);
-	},
+		_map: null,
+		_centerTouchLocation: null,
+		_touchMoveListener: null,
+		_touchEndListener: null,
+		_touchEndTapListener: null,
+		_touchStartListener: null,
+		_initialFingerSpacing: null,
+		_initialScale: null,
+		_tapCount: null,
+		_tapThreshold: null,
+		_lastTap: null,
+		_doubleTapPerformed:false,
+		_oneFingerTouch:false,
+		_tapCancel:false,
 
-	disconnect: function() {
-		//	summary: 
-		//		disconnects any installed listeners. Must be called only when disposing of this instance 
-		if (this._touchStartListener) {
-			connect.disconnect(this._touchStartListener);
-			this._touchStartListener = null;
-		}
-	},
+		constructor: function(map){
+			// summary:
+			//		Constructs a new _TouchInteractionSupport instance
+			// map: dojox.geo.charting.Map
+			//		the Map widget this class provides touch navigation for.
+			this._map = map;
+			this._centerTouchLocation = {x: 0,y: 0};
 
-	_getTouchBarycenter: function(touchEvent) {
-		//	summary: 
-		//		returns the midpoint of the two first fingers (or the first finger location if only one)
-		//	touchEvent: a touch event
-		//	returns: dojox.gfx.Point
-		//		the midpoint
-		//	tags:
-		//		private
-		var touches = touchEvent.touches;
-		var firstTouch = touches[0];
-		var secondTouch = null;
-		if (touches.length > 1) {
-			secondTouch = touches[1];
-		} else {
-			secondTouch = touches[0];
-		}
-		var containerBounds = this._map._getContainerBounds();
-		var middleX = (firstTouch.pageX + secondTouch.pageX) / 2.0 - containerBounds.x;
-		var middleY = (firstTouch.pageY + secondTouch.pageY) / 2.0 - containerBounds.y;
-		return {x: middleX,y: middleY};
-	},
+			this._tapCount = 0;
+			this._lastTap = {x: 0,y: 0};
+			this._tapThreshold = 100; // square distance in pixels
+		},
 
-	_getFingerSpacing: function(touchEvent) {
-		//	summary: 
-		//		computes the distance between the first two fingers
-		//	touchEvent: a touch event
-		//	returns: float
-		//		a distance. -1 if less that 2 fingers
-		//	tags:
-		//		private
-		var touches = touchEvent.touches;
-		var spacing = -1;
-		if (touches.length >= 2) {
-			var dx = (touches[1].pageX - touches[0].pageX);
-			var dy = (touches[1].pageY - touches[0].pageY);
-			spacing = Math.sqrt(dx*dx + dy*dy);
-		}
-		return spacing;
-	},
+		connect: function(){
+			// summary:
+			//		install touch listeners
+			this._touchStartListener = this._map.surface.connect("touchstart", this, this._touchStartHandler);
+		},
 
-	_isDoubleTap: function(touchEvent) {
-		//	summary: 
-		//		checks whether the specified touchStart event is a double tap 
-		//		(i.e. follows closely a previous touchStart at approximately the same location)
-		//	touchEvent: a touch event
-		//	returns: boolean
-		//		true if this event is considered a double tap
-		//	tags:
-		//		private
-		var isDoubleTap = false;
-		var touches = touchEvent.touches;
-		if ((this._tapCount > 0) && touches.length == 1) {
-			// test distance from last tap
-			var dx = (touches[0].pageX - this._lastTap.x);
-			var dy = (touches[0].pageY - this._lastTap.y);
-			var distance = dx*dx + dy*dy;
-			if (distance < this._tapThreshold) {
-				isDoubleTap = true;
-			} else {
-				this._tapCount = 0;
+		disconnect: function(){
+			// summary:
+			//		disconnects any installed listeners. Must be called only when disposing of this instance
+			if(this._touchStartListener){
+				connect.disconnect(this._touchStartListener);
+				this._touchStartListener = null;
 			}
-		}
-		this._tapCount++;
-		this._lastTap.x = touches[0].pageX;
-		this._lastTap.y = touches[0].pageY;
-		setTimeout(lang.hitch(this,function() {
-		this._tapCount = 0;}),300);
-		return isDoubleTap;
-	},
+		},
 
-	_doubleTapHandler: function(touchEvent) {
-		//	summary: 
-		//		action performed on the map when a double tap was triggered 
-		//	touchEvent: a touch event
-		//	tags:
-		//		private
-		var feature = this._getFeatureFromTouchEvent(touchEvent);
-		if (feature) {
-			this._map.fitToMapArea(feature._bbox, 15, true);
-		} else {
-			// perform a basic 2x zoom on touch
+		_getTouchBarycenter: function(touchEvent){
+			// summary:
+			//		returns the midpoint of the two first fingers (or the first finger location if only one)
+			// touchEvent: TouchEvent
+			//		a touch event
+			// returns:
+			//		the midpoint
+			// tags:
+			//		private
 			var touches = touchEvent.touches;
+			var firstTouch = touches[0];
+			var secondTouch = null;
+			if(touches.length > 1){
+				secondTouch = touches[1];
+			}else{
+				secondTouch = touches[0];
+			}
 			var containerBounds = this._map._getContainerBounds();
-			var offX = touches[0].pageX - containerBounds.x;
-			var offY = touches[0].pageY - containerBounds.y;
-			// clicked map point before zooming
-			var mapPoint = this._map.screenCoordsToMapCoords(offX,offY);
-			// zoom increment power
-			this._map.setMapCenterAndScale(mapPoint.x, mapPoint.y,this._map.getMapScale()*2,true);
-		}
-	},
+			var middleX = (firstTouch.pageX + secondTouch.pageX) / 2.0 - containerBounds.x;
+			var middleY = (firstTouch.pageY + secondTouch.pageY) / 2.0 - containerBounds.y;
+			return {x: middleX,y: middleY}; // dojox/gfx/Point
+		},
 
-	_getFeatureFromTouchEvent: function(touchEvent) {
-		//	summary: 
-		//		utility function to return the feature located at this touch event location
-		//	touchEvent: a touch event
-		//	returns: dojox.geo.charting.Feature
-		//		the feature found if any, null otherwise.
-		//	tags:
-		//		private
-		var feature = null;
-		if (touchEvent.gfxTarget && touchEvent.gfxTarget.getParent) {
-			feature = this._map.mapObj.features[touchEvent.gfxTarget.getParent().id];
-		}
-		return feature;
-	},
+		_getFingerSpacing: function(touchEvent){
+			// summary:
+			//		computes the distance between the first two fingers
+			// touchEvent: a touch event
+			// returns:
+			//		a distance. -1 if less than 2 fingers
+			// tags:
+			//		private
+			var touches = touchEvent.touches;
+			var spacing = -1;
+			if(touches.length >= 2){
+				var dx = (touches[1].pageX - touches[0].pageX);
+				var dy = (touches[1].pageY - touches[0].pageY);
+				spacing = Math.sqrt(dx*dx + dy*dy);
+			}
+			return spacing;
+		},
 
-	_touchStartHandler: function(touchEvent){
-		//	summary: 
-		//		action performed on the map when a touch start was triggered 
-		//	touchEvent: a touch event
-		//	tags:
-		//		private
-		event.stop(touchEvent);
-		this._oneFingerTouch = (touchEvent.touches.length == 1);
-		this._tapCancel = !this._oneFingerTouch;
-		// test double tap
-		this._doubleTapPerformed = false;
-		if (this._isDoubleTap(touchEvent)) {
-			//console.log("double tap recognized");
-			this._doubleTapHandler(touchEvent);
-			this._doubleTapPerformed = true;
-			return;
-		}
-		// compute map midpoint between fingers		
-		var middlePoint = this._getTouchBarycenter(touchEvent);
-		var mapPoint = this._map.screenCoordsToMapCoords(middlePoint.x,middlePoint.y);
-		this._centerTouchLocation.x = mapPoint.x;
-		this._centerTouchLocation.y = mapPoint.y;
-		// store initial finger spacing to compute zoom later
-		this._initialFingerSpacing = this._getFingerSpacing(touchEvent);
-		// store initial map scale
-		this._initialScale = this._map.getMapScale();
-		// install touch move and up listeners (if not done by other fingers before)
-		if (!this._touchMoveListener) 
-			this._touchMoveListener = connect.connect(win.global,"touchmove",this,this._touchMoveHandler);
-		if (!this._touchEndTapListener) 
-			this._touchEndTapListener = this._map.surface.connect("touchend", this, this._touchEndTapHandler);
-		if (!this._touchEndListener) 
-			this._touchEndListener = connect.connect(win.global,"touchend",this, this._touchEndHandler);
-	},
+		_isDoubleTap: function(touchEvent){
+			// summary:
+			//		checks whether the specified touchStart event is a double tap
+			//		(i.e. follows closely a previous touchStart at approximately the same location)
+			// touchEvent: TouchEvent
+			//		a touch event
+			// returns:
+			//		true if this event is considered a double tap
+			// tags:
+			//		private
+			var isDoubleTap = false;
+			var touches = touchEvent.touches;
+			if((this._tapCount > 0) && touches.length == 1){
+				// test distance from last tap
+				var dx = (touches[0].pageX - this._lastTap.x);
+				var dy = (touches[0].pageY - this._lastTap.y);
+				var distance = dx*dx + dy*dy;
+				if(distance < this._tapThreshold){
+					isDoubleTap = true;
+				}else{
+					this._tapCount = 0;
+				}
+			}
+			this._tapCount++;
+			this._lastTap.x = touches[0].pageX;
+			this._lastTap.y = touches[0].pageY;
+			setTimeout(lang.hitch(this,function(){
+				this._tapCount = 0;}),300);
+			return isDoubleTap;
+		},
 
-	_touchEndTapHandler: function(touchEvent) {
-		//	summary: 
-		//		action performed on the map when a tap was triggered 
-		//	touchEvent: a touch event
-		//	tags:
-		//		private
-		var touches = touchEvent.touches;
-		if (touches.length == 0) {
-			
-			// test potential tap ?
-			if (this._oneFingerTouch && !this._tapCancel) {
-				this._oneFingerTouch = false;
-				setTimeout(lang.hitch(this,function() {
-					// wait to check if double tap
-					// perform test for single tap
-					//console.log("double tap was performed ? " + this._doubleTapPerformed);
-					if (!this._doubleTapPerformed) {
-						// test distance from last tap
-						var dx = (touchEvent.changedTouches[0].pageX - this._lastTap.x);
-						var dy = (touchEvent.changedTouches[0].pageY - this._lastTap.y);
-						var distance = dx*dx + dy*dy;
-						if (distance < this._tapThreshold) {
-							// single tap ok
-							this._singleTapHandler(touchEvent);
-						}
-					}					
-				}),350);
+		_doubleTapHandler: function(touchEvent){
+			// summary:
+			//		action performed on the map when a double tap was triggered
+			// touchEvent: TouchEvent
+			//		a touch event
+			// tags:
+			//		private
+			var feature = this._getFeatureFromTouchEvent(touchEvent);
+			if(feature){
+				this._map.fitToMapArea(feature._bbox, 15, true);
+			}else{
+				// perform a basic 2x zoom on touch
+				var touches = touchEvent.touches;
+				var containerBounds = this._map._getContainerBounds();
+				var offX = touches[0].pageX - containerBounds.x;
+				var offY = touches[0].pageY - containerBounds.y;
+				// clicked map point before zooming
+				var mapPoint = this._map.screenCoordsToMapCoords(offX,offY);
+				// zoom increment power
+				this._map.setMapCenterAndScale(mapPoint.x, mapPoint.y,this._map.getMapScale()*2,true);
 			}
-			this._tapCancel = false;
-			
-		}
-	},
+		},
 
-	_touchEndHandler: function(touchEvent) {
-		//	summary: 
-		//		action performed on the map when a touch end was triggered 
-		//	touchEvent: a touch event
-		//	tags:
-		//		private
-		event.stop(touchEvent);
-		var touches = touchEvent.touches;
-		if (touches.length == 0) {
-			// disconnect listeners only when all fingers are up
-			if (this._touchMoveListener) {
-				connect.disconnect(this._touchMoveListener);
-				this._touchMoveListener = null;
+		_getFeatureFromTouchEvent: function(touchEvent){
+			// summary:
+			//		utility function to return the feature located at this touch event location
+			// touchEvent: TouchEvent
+			//		a touch event
+			// returns:
+			//		the feature found if any, null otherwise.
+			// tags:
+			//		private
+			var feature = null;
+			if(touchEvent.gfxTarget && touchEvent.gfxTarget.getParent){
+				feature = this._map.mapObj.features[touchEvent.gfxTarget.getParent().id];
 			}
-			if (this._touchEndListener) {
-				connect.disconnect(this._touchEndListener);
-				this._touchEndListener = null;
+			return feature;	// dojox/geo/charting/Feature
+		},
+
+		_touchStartHandler: function(touchEvent){
+			// summary:
+			//		action performed on the map when a touch start was triggered
+			// touchEvent: TouchEvent
+			//		a touch event
+			// tags:
+			//		private
+			event.stop(touchEvent);
+			this._oneFingerTouch = (touchEvent.touches.length == 1);
+			this._tapCancel = !this._oneFingerTouch;
+			// test double tap
+			this._doubleTapPerformed = false;
+			if(this._isDoubleTap(touchEvent)){
+				//console.log("double tap recognized");
+				this._doubleTapHandler(touchEvent);
+				this._doubleTapPerformed = true;
+				return;
 			}
-		} else {
-			// recompute touch center
+			// compute map midpoint between fingers
 			var middlePoint = this._getTouchBarycenter(touchEvent);
 			var mapPoint = this._map.screenCoordsToMapCoords(middlePoint.x,middlePoint.y);
 			this._centerTouchLocation.x = mapPoint.x;
 			this._centerTouchLocation.y = mapPoint.y;
-		}
-	},
-	
-	_singleTapHandler: function(touchEvent) {
-		//	summary: 
-		//		action performed on the map when a single tap was triggered 
-		//	touchEvent: a touch event
-		//	tags:
-		//		private
-		var feature = this._getFeatureFromTouchEvent(touchEvent);
-		if (feature) {
-			// call feature handler
-			feature._onclickHandler(touchEvent);
-		} else {
-			// unselect all
-			for (var name in this._map.mapObj.features){
-				this._map.mapObj.features[name].select(false);
+			// store initial finger spacing to compute zoom later
+			this._initialFingerSpacing = this._getFingerSpacing(touchEvent);
+			// store initial map scale
+			this._initialScale = this._map.getMapScale();
+			// install touch move and up listeners (if not done by other fingers before)
+			if(!this._touchMoveListener){
+				this._touchMoveListener = connect.connect(win.global,"touchmove",this,this._touchMoveHandler);
 			}
-			this._map.onFeatureClick(null);
-		}
-	},
+			if(!this._touchEndTapListener){
+				this._touchEndTapListener = this._map.surface.connect("touchend", this, this._touchEndTapHandler);
+			}
+			if(!this._touchEndListener){
+				this._touchEndListener = connect.connect(win.global,"touchend",this, this._touchEndHandler);
+			}
+		},
 
-	_touchMoveHandler: function(touchEvent){
-		//	summary: 
-		//		action performed on the map when a touch move was triggered 
-		//	touchEvent: a touch event
-		//	tags:
-		//		private
+		_touchEndTapHandler: function(touchEvent){
+			// summary:
+			//		action performed on the map when a tap was triggered
+			// touchEvent: TouchEvent
+			//		a touch event
+			// tags:
+			//		private
+			var touches = touchEvent.touches;
+			if(touches.length == 0){
+
+				// test potential tap ?
+				if(this._oneFingerTouch && !this._tapCancel){
+					this._oneFingerTouch = false;
+					setTimeout(lang.hitch(this,function(){
+						// wait to check if double tap
+						// perform test for single tap
+						//console.log("double tap was performed ? " + this._doubleTapPerformed);
+						if(!this._doubleTapPerformed){
+							// test distance from last tap
+							var dx = (touchEvent.changedTouches[0].pageX - this._lastTap.x);
+							var dy = (touchEvent.changedTouches[0].pageY - this._lastTap.y);
+							var distance = dx*dx + dy*dy;
+							if(distance < this._tapThreshold){
+								// single tap ok
+								this._singleTapHandler(touchEvent);
+							}
+						}
+					}), 350);
+				}
+				this._tapCancel = false;
+			}
+		},
 
-		// prevent browser interaction
-		event.stop(touchEvent);
+		_touchEndHandler: function(touchEvent){
+			// summary:
+			//		action performed on the map when a touch end was triggered
+			// touchEvent: TouchEvent
+			//		a touch event
+			// tags:
+			//		private
+			event.stop(touchEvent);
+			var touches = touchEvent.touches;
+			if(touches.length == 0){
+				// disconnect listeners only when all fingers are up
+				if(this._touchMoveListener){
+					connect.disconnect(this._touchMoveListener);
+					this._touchMoveListener = null;
+				}
+				if(this._touchEndListener){
+					connect.disconnect(this._touchEndListener);
+					this._touchEndListener = null;
+				}
+			}else{
+				// recompute touch center
+				var middlePoint = this._getTouchBarycenter(touchEvent);
+				var mapPoint = this._map.screenCoordsToMapCoords(middlePoint.x,middlePoint.y);
+				this._centerTouchLocation.x = mapPoint.x;
+				this._centerTouchLocation.y = mapPoint.y;
+			}
+		},
 
-		// cancel tap if moved too far from first touch location
-		if (!this._tapCancel) {
-			var dx = (touchEvent.touches[0].pageX - this._lastTap.x),
-				dy = (touchEvent.touches[0].pageY - this._lastTap.y);
-			var distance = dx*dx + dy*dy;
-			if (distance > this._tapThreshold) {
-				this._tapCancel = true;
+		_singleTapHandler: function(touchEvent){
+			// summary:
+			//		action performed on the map when a single tap was triggered
+			// touchEvent: TouchEvent
+			//		a touch event
+			// tags:
+			//		private
+			var feature = this._getFeatureFromTouchEvent(touchEvent);
+			if(feature){
+				// call feature handler
+				feature._onclickHandler(touchEvent);
+			}else{
+				// unselect all
+				for(var name in this._map.mapObj.features){
+					this._map.mapObj.features[name].select(false);
+				}
+				this._map.onFeatureClick(null);
 			}
+		},
+
+		_touchMoveHandler: function(touchEvent){
+			// summary:
+			//		action performed on the map when a touch move was triggered
+			// touchEvent: TouchEvent
+			//		a touch event
+			// tags:
+			//		private
+
+			// prevent browser interaction
+			event.stop(touchEvent);
+
+			// cancel tap if moved too far from first touch location
+			if(!this._tapCancel){
+				var dx = (touchEvent.touches[0].pageX - this._lastTap.x),
+					dy = (touchEvent.touches[0].pageY - this._lastTap.y);
+				var distance = dx*dx + dy*dy;
+				if(distance > this._tapThreshold){
+					this._tapCancel = true;
+				}
+			}
+			var middlePoint = this._getTouchBarycenter(touchEvent);
+			// compute map offset
+			var mapPoint = this._map.screenCoordsToMapCoords(middlePoint.x,middlePoint.y),
+				mapOffsetX = mapPoint.x - this._centerTouchLocation.x,
+				mapOffsetY = mapPoint.y - this._centerTouchLocation.y;
+			// compute scale factor
+			var scaleFactor = 1;
+			var touches = touchEvent.touches;
+			if(touches.length >= 2){
+				var fingerSpacing = this._getFingerSpacing(touchEvent);
+				scaleFactor = fingerSpacing / this._initialFingerSpacing;
+				// scale map
+				this._map.setMapScale(this._initialScale*scaleFactor);
+			}
+			// adjust map center on barycentre
+			var currentMapCenter = this._map.getMapCenter();
+			this._map.setMapCenter(currentMapCenter.x - mapOffsetX, currentMapCenter.y - mapOffsetY);
 		}
-		var middlePoint = this._getTouchBarycenter(touchEvent);
-		// compute map offset
-		var mapPoint = this._map.screenCoordsToMapCoords(middlePoint.x,middlePoint.y),
-			mapOffsetX = mapPoint.x - this._centerTouchLocation.x,
-			mapOffsetY = mapPoint.y - this._centerTouchLocation.y;
-		// compute scale factor
-		var scaleFactor = 1;
-		var touches = touchEvent.touches;
-		if (touches.length >= 2) {
-			var fingerSpacing = this._getFingerSpacing(touchEvent);
-			scaleFactor = fingerSpacing / this._initialFingerSpacing;
-			// scale map
-			this._map.setMapScale(this._initialScale*scaleFactor);
-		}
-		// adjust map center on barycentre
-		var currentMapCenter = this._map.getMapCenter();
-		this._map.setMapCenter(currentMapCenter.x - mapOffsetX, currentMapCenter.y - mapOffsetY);
-	}
-});
+	});
 });
diff --git a/dojox/geo/charting/_Marker.js b/dojox/geo/charting/_Marker.js
index f6f2114..12259b9 100644
--- a/dojox/geo/charting/_Marker.js
+++ b/dojox/geo/charting/_Marker.js
@@ -1,65 +1,68 @@
-
-define(["dojo/_base/lang","dojo/_base/array", "dojo/_base/declare","dojo/_base/sniff","./_base"], 
-	function(lang, arr, declare, has) {
-return declare("dojox.geo.charting._Marker", null, {
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/sniff",
+	"./_base"
+], function(lang, arr, declare, has){
+	return declare("dojox.geo.charting._Marker", null, {
+		
+		_needTooltipRefresh: null,
+		_map: null,
+		
+		constructor: function(markerData, map){
+			this._map = map;
+			var mapObj = map.mapObj;
+			this.features = mapObj.features;
+			this.markerData = markerData;
+			_needTooltipRefresh = false;
+		},
 	
-	_needTooltipRefresh: null,
-	_map: null,
+		show: function(featureId, evt){
+			this.currentFeature = this.features[featureId];
+			if(this._map.showTooltips && this.currentFeature){
+				this.markerText = this.currentFeature.markerText || this.markerData[featureId] || featureId;
+				dojox.geo.charting.showTooltip(this.markerText, this.currentFeature.shape, ["before"]);
+			}
+			this._needTooltipRefresh = false;
+		},
 	
-	constructor: function(markerData, map){
-		this._map = map;
-		var mapObj = map.mapObj;
-		this.features = mapObj.features;
-		this.markerData = markerData;
-		_needTooltipRefresh = false;
-	},
-
-	show: function(featureId,evt){
-		this.currentFeature = this.features[featureId];
-		if (this._map.showTooltips && this.currentFeature) {
-			this.markerText = this.currentFeature.markerText || this.markerData[featureId] || featureId;
-			dojox.geo.charting.showTooltip(this.markerText, this.currentFeature.shape, ["before"]);
-		}
-		this._needTooltipRefresh = false;
-	},
-
-	hide: function(){
-		if (this._map.showTooltips && this.currentFeature)
-			dojox.geo.charting.hideTooltip(this.currentFeature.shape);
-		this._needTooltipRefresh = false;
-	},
-
-	_getGroupBoundingBox: function(group){
-		var shapes = group.children;
-		var feature = shapes[0];
-		var bbox = feature.getBoundingBox();
-		this._arround = lang.clone(bbox);
-		arr.forEach(shapes, function(item){
-			var _bbox = item.getBoundingBox();
-			this._arround.x = Math.min(this._arround.x, _bbox.x);
-			this._arround.y = Math.min(this._arround.y, _bbox.y);
-		},this);
-	},
-
-	_toWindowCoords: function(arround, coords, containerSize){
-		var toLeft = (arround.x - this.topLeft[0]) * this.scale;
-		var toTop = (arround.y - this.topLeft[1]) * this.scale
-		if (has("ff") == 3.5) {
-			arround.x = coords.x;
-			arround.y = coords.y;
-		}
-		else if (has("chrome")) {
-			arround.x = containerSize.x + toLeft;
-			arround.y = containerSize.y + toTop;
-		}
-		else {
-			arround.x = coords.x + toLeft;
-			arround.y = coords.y + toTop;
+		hide: function(){
+			if(this._map.showTooltips && this.currentFeature){
+				dojox.geo.charting.hideTooltip(this.currentFeature.shape);
+			}
+			this._needTooltipRefresh = false;
+		},
+	
+		_getGroupBoundingBox: function(group){
+			var shapes = group.children;
+			var feature = shapes[0];
+			var bbox = feature.getBoundingBox();
+			this._arround = lang.clone(bbox);
+			arr.forEach(shapes, function(item){
+				var _bbox = item.getBoundingBox();
+				this._arround.x = Math.min(this._arround.x, _bbox.x);
+				this._arround.y = Math.min(this._arround.y, _bbox.y);
+			},this);
+		},
+	
+		_toWindowCoords: function(arround, coords, containerSize){
+			var toLeft = (arround.x - this.topLeft[0]) * this.scale;
+			var toTop = (arround.y - this.topLeft[1]) * this.scale
+			if(has("ff") == 3.5){
+				arround.x = coords.x;
+				arround.y = coords.y;
+			}else if(has("chrome")){
+				arround.x = containerSize.x + toLeft;
+				arround.y = containerSize.y + toTop;
+			}else{
+				arround.x = coords.x + toLeft;
+				arround.y = coords.y + toTop;
+			}
+			arround.width = (this.currentFeature._bbox[2]) * this.scale;
+			arround.height = (this.currentFeature._bbox[3]) * this.scale;
+			arround.x += arround.width / 6;
+			arround.y += arround.height / 4;
 		}
-		arround.width = (this.currentFeature._bbox[2]) * this.scale;
-		arround.height = (this.currentFeature._bbox[3]) * this.scale;
-		arround.x += arround.width / 6;
-		arround.y += arround.height / 4;
-	}
-});
+	});
 });
diff --git a/dojox/geo/charting/_base.js b/dojox/geo/charting/_base.js
index 7e77a8c..23cc9d1 100644
--- a/dojox/geo/charting/_base.js
+++ b/dojox/geo/charting/_base.js
@@ -1,14 +1,34 @@
-define(["dojo/_base/lang","dojo/_base/array","../../main", "dojo/_base/html","dojo/dom-geometry",
-		"dojox/gfx/matrix","dijit/Tooltip","dojo/_base/NodeList","dojo/NodeList-traverse"],
-  function(lang, arr, dojox, html, domGeom, matrix, Tooltip, NodeList, NodeListTraverse) {
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"../../main",
+	"dojo/_base/html",
+	"dojo/dom-geometry",
+	"dojox/gfx/matrix",
+	"dijit/Tooltip",
+	"dojo/_base/NodeList",
+	"dojo/NodeList-traverse"
+], function(lang, arr, dojox, html, domGeom, matrix, Tooltip, NodeList, NodeListTraverse){
 	var dgc = lang.getObject("geo.charting", true, dojox); 
 
-	dgc.showTooltip = function(/*String*/innerHTML, /*dojox.gfx.shape*/ gfxObject, /*String[]?*/ positions){
+	dgc.showTooltip = function(/*String*/innerHTML, /*dojox/gfx/shape.Shape*/ gfxObject, /*String[]?*/ positions){
+		// summary:
+		//		Show a Tooltip displaying the given HTML message around the given gfx shape.
+		// innerHTML: String
+		//		The message to display as a HTML string.
+		// gfxObject: dojox/gfx/shape.Shape
+		//		The gfx shape around which the tooltip will be placed.
+		// position: String[]?
+		//		The tooltip position.
 		var arroundNode = dgc._normalizeArround(gfxObject);
 		return Tooltip.show(innerHTML, arroundNode, positions);
 	};
 
-	dgc.hideTooltip = function( /*dojox.gfx.shape*/gfxObject){
+	dgc.hideTooltip = function( /*dojox/gfx/shape.Shape*/gfxObject){
+		// summary:
+		//		Hides the tooltip displayed around the given shape.
+		// gfxObject: dojox.gfx.shape.Shape
+		//		A gfx shape.
 		return Tooltip.hide(gfxObject);
 	};
 
@@ -27,9 +47,9 @@ define(["dojo/_base/lang","dojo/_base/array","../../main", "dojo/_base/html","do
 	};
 
 	dgc._getGfxContainer = function(gfxObject){
-		if (gfxObject.surface) {
+		if(gfxObject.surface){
 			return (new NodeList(gfxObject.surface.rawNode)).parents("div")[0];
-		} else {
+		}else{
 			return (new NodeList(gfxObject.rawNode)).parents("div")[0];
 		}
 	};
@@ -51,4 +71,6 @@ define(["dojo/_base/lang","dojo/_base/array","../../main", "dojo/_base/html","do
 		}
 		return bboxObject;
 	};
+	
+	return dgc;
 });
diff --git a/dojox/geo/charting/resources/data/Americas.json b/dojox/geo/charting/resources/data/Americas.json
new file mode 100644
index 0000000..bd9eff6
--- /dev/null
+++ b/dojox/geo/charting/resources/data/Americas.json
@@ -0,0 +1,157 @@
+{
+  "layerExtent":[0.0, 0.0, 6026.97600872762, 8546.173618848681],
+    "layerExtentLL":[-168.144247, 71.837144, 133.34058000000002, 125.54830899999999],
+    "featureNames":["PAN", "PRY", "JAM", "SUR", "GUY", "ECU", "PER", "VEN", "URY", "PRI", "BHS", "BOL", "BLZ", "CHL", "HTI", "SLV", "MEX", "CAN", "ARG", "GTM", "CUB", "COL", "BMU", "USA", "GUF", "DOM", "CRI", "BRA", "NIC", "HND"],
+    "features":{
+      "PAN":{
+        "shape":[[3291, 4420, 3267, 4454, 3277, 4515, 3270, 4518, 3263, 4517, 3256, 4520, 3250, 4530, 3227, 4535, 3220, 4533, 3218, 4511, 3212, 4507, 3209, 4499, 3212, 4496, 3210, 4491, 3209, 4492, 3205, 4491, 3205, 4495, 3201, 4494, 3203, 4496, 3202, 4501, 3200, 4502, 3201, 4510, 3180, 4506, 3181, 4503, 3178, 4503, 3171, 4487, 3167, 4485, 3169, 4479, 3163, 4479, 3152, 4473, 3150, 4476, 3142, 4475, 3143, 4479, 3132, 4478, 3130, 4477, 3139, 4469, 3137, 4468, 3133, 4472, 3129, 4470, 3128,  [...]
+        "center":[3277, 4402],
+        "bbox":[3085.595246937954, 4374.8887242122555, 362.64852135993715, 160.33017119237866]
+      },
+      "PRY":{
+        "shape":[4426, 6479, 4451, 6517, 4466, 6527, 4463, 6559, 4465, 6622, 4432, 6703, 4492, 6732, 4505, 6733, 4521, 6723, 4529, 6737, 4557, 6750, 4558, 6772, 4548, 6816, 4542, 6852, 4542, 6872, 4557, 6891, 4592, 6878, 4601, 6899, 4591, 6910, 4587, 6925, 4546, 7003, 4533, 7038, 4518, 7067, 4492, 7088, 4469, 7096, 4452, 7115, 4439, 7117, 4420, 7109, 4388, 7112, 4380, 7100, 4355, 7093, 4316, 7066, 4292, 7063, 4294, 7044, 4318, 7027, 4329, 7015, 4341, 6985, 4354, 6979, 4371, 6959, 4387, 6 [...]
+        "center":[4411, 6815],
+        "bbox":[4165.505061517585, 6460.070144052053, 435.41773059553634, 657.2190362796891]
+      },
+      "JAM":{
+        "shape":[3311, 3802, 3311, 3795, 3318, 3789, 3336, 3787, 3336, 3783, 3339, 3780, 3400, 3780, 3408, 3788, 3435, 3791, 3447, 3807, 3441, 3811, 3439, 3809, 3437, 3812, 3422, 3814, 3418, 3809, 3406, 3812, 3414, 3809, 3406, 3807, 3401, 3818, 3395, 3818, 3395, 3815, 3391, 3815, 3388, 3824, 3386, 3824, 3386, 3826, 3390, 3825, 3390, 3829, 3375, 3822, 3352, 3825, 3345, 3819, 3346, 3814, 3340, 3815, 3331, 3803, 3320, 3806, 3311, 3802],
+        "center":[3391, 3806],
+        "bbox":[3310.9901408613146, 3779.9261212774727, 136.17160419484844, 49.23023967721292]
+      },
+      "SUR":{
+        "shape":[4890, 4549, 4867, 4608, 4861, 4641, 4870, 4682, 4880, 4703, 4887, 4783, 4871, 4827, 4859, 4824, 4776, 4838, 4790, 4862, 4786, 4871, 4761, 4857, 4743, 4847, 4720, 4798, 4699, 4596, 4703, 4573, 4701, 4543, 4890, 4549],
+        "center":[4787, 4688],
+        "bbox":[4699.17464150158, 4542.632250817333, 190.9758436732718, 328.08963869297986]
+      },
+      "GUY":{
+        "shape":[4698, 4573, 4703, 4573, 4699, 4596, 4720, 4798, 4743, 4847, 4761, 4857, 4641, 4897, 4485, 4615, 4478, 4605, 4450, 4556, 4458, 4534, 4493, 4471, 4513, 4373, 4547, 4389, 4690, 4570, 4698, 4573],
+        "center":[4591, 4631],
+        "bbox":[4450.431229771607, 4372.875137409349, 310.5845777548848, 524.2001287136627]
+      },
+      "ECU":{
+        "shape":[3266, 5235, 3274, 5235, 3284, 5225, 3287, 5231, 3294, 5211, 3294, 5199, 3304, 5182, 3301, 5175, 3282, 5183, 3286, 5171, 3281, 5173, 3268, 5191, 3259, 5188, 3245, 5169, 3231, 5166, 3224, 5157, 3236, 5155, 3240, 5145, 3231, 5117, 3240, 5101, 3227, 5084, 3237, 5073, 3250, 5074, 3252, 5059, 3259, 5054, 3254, 5039, 3277, 5018, 3284, 5001, 3291, 4994, 3280, 4985, 3283, 4978, 3277, 4969, 3278, 4960, 3321, 4941, 3348, 4936, 3348, 4927, 3362, 4928, 3361, 4918, 3419, 4966, 3429, 4 [...]
+        "center":[3397, 5096],
+        "bbox":[3224.2035708291523, 4917.833388407135, 366.0355421613249, 426.08028112672764]
+      },
+      "PER":{
+        "shape":[3823, 6241, 3824, 6257, 3817, 6272, 3806, 6278, 3794, 6274, 3781, 6280, 3757, 6257, 3758, 6244, 3726, 6226, 3732, 6212, 3729, 6200, 3710, 6186, 3693, 6178, 3678, 6151, 3658, 6144, 3636, 6125, 3609, 6110, 3581, 6082, 3568, 6082, 3562, 6069, 3523, 6041, 3524, 6028, 3512, 6022, 3505, 6005, 3491, 5992, 3477, 5970, 3472, 5955, 3464, 5955, 3467, 5945, 3462, 5933, 3469, 5931, 3476, 5918, 3477, 5907, 3462, 5878, 3463, 5864, 3446, 5846, 3446, 5832, 3425, 5818, 3429, 5802, 3424, 5 [...]
+        "center":[3531, 5637],
+        "bbox":[3198.2922744023836, 5015.916040571183, 746.0114673737262, 1264.4396635001003]
+      },
+      "VEN":{
+        "shape":[3768, 4253, 4496, 4366, 4513, 4373, 4493, 4471, 4458, 4534, 4450, 4556, 4478, 4605, 4485, 4615, 4490, 4640, 4428, 4696, 4394, 4706, 4377, 4716, 4273, 4832, 4326, 4853, 4283, 4866, 4275, 4902, 4254, 4907, 4241, 4923, 4210, 4934, 4194, 4949, 4163, 4960, 4136, 4961, 4114, 4927, 4106, 4884, 4093, 4850, 4055, 4803, 4079, 4773, 4076, 4756, 4058, 4731, 4054, 4628, 3963, 4577, 3950, 4594, 3938, 4588, 3726, 4261, 3751, 4215, 3768, 4253],
+        "center":[4167, 4467],
+        "bbox":[3726.1885234749216, 4215.3603520982, 786.7304574171976, 745.4096985677324]
+      },
+      "URY":{
+        "shape":[4145, 7574, 4146, 7560, 4139, 7548, 4141, 7546, 4136, 7524, 4157, 7475, 4172, 7477, 4180, 7467, 4182, 7458, 4176, 7449, 4179, 7429, 4190, 7420, 4190, 7408, 4196, 7398, 4195, 7388, 4199, 7379, 4214, 7373, 4220, 7358, 4234, 7344, 4243, 7327, 4247, 7299, 4266, 7283, 4293, 7294, 4309, 7283, 4318, 7291, 4340, 7351, 4341, 7362, 4336, 7375, 4343, 7385, 4358, 7371, 4366, 7380, 4364, 7409, 4373, 7411, 4379, 7427, 4391, 7439, 4396, 7463, 4412, 7485, 4415, 7503, 4410, 7525, 4425, 7 [...]
+        "center":[4269, 7510],
+        "bbox":[4136.414605177103, 7282.740573959513, 288.97823203003645, 385.92694816759285]
+      },
+      "PRI":{
+        "shape":[3965, 3694, 3970, 3689, 3969, 3684, 3972, 3682, 4029, 3675, 4034, 3678, 4034, 3675, 4036, 3675, 4033, 3675, 4044, 3675, 4041, 3673, 4052, 3674, 4060, 3679, 4064, 3676, 4064, 3684, 4067, 3688, 4057, 3695, 4055, 3705, 4050, 3709, 4043, 3710, 4037, 3715, 3998, 3716, 3993, 3721, 3989, 3719, 3989, 3723, 3985, 3720, 3978, 3723, 3974, 3722, 3973, 3725, 3971, 3721, 3973, 3718, 3973, 3704, 3965, 3694],
+        "center":[4008, 3689],
+        "bbox":[3964.648938933221, 3673.460236057327, 102.66929526974945, 51.97039571816731]
+      },
+      "BHS":{
+        "shape":[[3262, 3241, 3266, 3237, 3284, 3234, 3303, 3249, 3315, 3252, 3316, 3261, 3318, 3264, 3318, 3268, 3312, 3276, 3314, 3298, 3309, 3296, 3308, 3291, 3301, 3291, 3311, 3279, 3307, 3277, 3310, 3273, 3306, 3265, 3309, 3266, 3308, 3262, 3311, 3264, 3308, 3262, 3310, 3253, 3298, 3251, 3296, 3247, 3293, 3248, 3289, 3239, 3284, 3236, 3262, 3241], [3564, 3583, 3567, 3575, 3578, 3563, 3585, 3567, 3595, 3565, 3599, 3552, 3602, 3552, 3598, 3578, 3569, 3588, 3564, 3583], [3206, 3263, 32 [...]
+        "center":[3404, 3414],
+        "bbox":[3206.380670807515, 3234.4524479911097, 395.6347088343741, 353.2412955151108]
+      },
+      "BOL":{
+        "shape":[3897, 5777, 3907, 5771, 3943, 5780, 3955, 5795, 3979, 5786, 3997, 5762, 4015, 5769, 4042, 5745, 4055, 5750, 4089, 5722, 4137, 5718, 4147, 5725, 4161, 5711, 4167, 5719, 4166, 5757, 4151, 5773, 4156, 5812, 4147, 5843, 4156, 5851, 4158, 5866, 4168, 5868, 4168, 5881, 4195, 5908, 4186, 5919, 4233, 5934, 4244, 5929, 4262, 5950, 4276, 5946, 4279, 5963, 4306, 5981, 4329, 5990, 4344, 6020, 4401, 6045, 4419, 6059, 4420, 6073, 4414, 6090, 4420, 6108, 4409, 6152, 4401, 6147, 4410, 6 [...]
+        "center":[4188, 6225],
+        "bbox":[3822.7558117373655, 5711.185330260305, 712.5606866942435, 956.9589459024455]
+      },
+      "BLZ":{
+        "shape":[2695, 3876, 2703, 3877, 2708, 3872, 2722, 3844, 2733, 3845, 2728, 3848, 2724, 3851, 2726, 3855, 2738, 3854, 2742, 3858, 2733, 3889, 2731, 3919, 2735, 3939, 2733, 3957, 2730, 3965, 2723, 3967, 2723, 3972, 2720, 3973, 2717, 3981, 2713, 3982, 2713, 3987, 2709, 3989, 2708, 3993, 2704, 3995, 2702, 3998, 2704, 4003, 2703, 4007, 2696, 4004, 2692, 4009, 2686, 4008, 2677, 3888, 2676, 3883, 2695, 3876],
+        "center":[2716, 3927],
+        "bbox":[2676.4010585560536, 3843.6429993422585, 65.25762155005123, 164.89206396029613]
+      },
+      "CHL":{
+        "shape":[3062, 8049, 3070, 8041, 3079, 8039, 3099, 8027, 3101, 8031, 3108, 8027, 3110, 8030, 3110, 8024, 3118, 8019, 3119, 8013, 3114, 8018, 3106, 8022, 3100, 8018, 3106, 8004, 3114, 8009, 3120, 8007, 3127, 8012, 3127, 8025, 3133, 8018, 3130, 8015, 3133, 8012, 3138, 8016, 3145, 8017, 3140, 8019, 3141, 8023, 3147, 8023, 3139, 8032, 3130, 8031, 3130, 8033, 3140, 8033, 3145, 8029, 3149, 8031, 3144, 8036, 3130, 8038, 3126, 8031, 3125, 8037, 3139, 8042, 3129, 8046, 3123, 8046, 3122, 8 [...]
+        "center":[3494, 7268],
+        "bbox":[3011.530000946609, 6224.028270075911, 908.6423013208423, 2322.1453487727704]
+      },
+      "HTI":{
+        "shape":[3691, 3650, 3699, 3670, 3694, 3681, 3704, 3695, 3699, 3702, 3692, 3704, 3692, 3708, 3703, 3705, 3708, 3715, 3705, 3726, 3697, 3733, 3696, 3740, 3700, 3742, 3701, 3746, 3707, 3753, 3705, 3759, 3695, 3756, 3686, 3754, 3664, 3757, 3661, 3761, 3649, 3761, 3647, 3765, 3602, 3765, 3586, 3772, 3584, 3775, 3587, 3779, 3584, 3781, 3567, 3767, 3550, 3769, 3545, 3765, 3545, 3757, 3549, 3744, 3558, 3741, 3579, 3748, 3630, 3749, 3644, 3746, 3650, 3743, 3652, 3739, 3665, 3736, 3667, 3 [...]
+        "center":[3647, 3708],
+        "bbox":[3544.7177883382833, 3639.6014943016307, 163.6148346646196, 141.37840406936266]
+      },
+      "SLV":{
+        "shape":[2677, 4107, 2696, 4107, 2703, 4114, 2710, 4110, 2715, 4110, 2728, 4124, 2734, 4124, 2740, 4131, 2760, 4127, 2772, 4131, 2778, 4129, 2780, 4132, 2779, 4145, 2785, 4146, 2788, 4149, 2783, 4152, 2783, 4159, 2778, 4161, 2777, 4164, 2771, 4162, 2768, 4164, 2771, 4170, 2766, 4173, 2768, 4178, 2755, 4181, 2746, 4179, 2744, 4175, 2738, 4177, 2732, 4174, 2722, 4177, 2732, 4182, 2715, 4176, 2702, 4166, 2683, 4162, 2666, 4163, 2663, 4159, 2659, 4161, 2655, 4160, 2652, 4154, 2633, 4 [...]
+        "center":[2721, 4146],
+        "bbox":[2628.799656786733, 4106.624427422612, 159.15550897447565, 75.16383937447154]
+      },
+      "MEX":{
+        "shape":[1146, 2922, 1272, 2929, 1267, 2934, 1266, 2942, 1453, 3039, 1605, 3052, 1607, 3024, 1700, 3031, 1705, 3036, 1712, 3051, 1725, 3058, 1734, 3071, 1743, 3076, 1753, 3091, 1765, 3096, 1778, 3108, 1781, 3121, 1788, 3131, 1789, 3150, 1796, 3166, 1800, 3172, 1813, 3179, 1816, 3184, 1826, 3191, 1836, 3193, 1840, 3199, 1849, 3200, 1853, 3206, 1857, 3209, 1860, 3208, 1863, 3212, 1870, 3212, 1879, 3200, 1886, 3197, 1884, 3195, 1885, 3189, 1889, 3186, 1890, 3179, 1897, 3165, 1904, 3 [...]
+        "center":[1881, 3536],
+        "bbox":[1145.8592570121384, 2921.6297125718283, 1664.186074636283, 1175.2713279114178]
+      },
+      "CAN":{
+        "shape":[[855, 880, 857, 879, 1217, 395, 1219, 397, 1244, 414, 1244, 417, 1242, 416, 1244, 420, 1241, 420, 1248, 424, 1252, 434, 1252, 458, 1254, 458, 1256, 449, 1255, 463, 1260, 476, 1263, 476, 1266, 485, 1264, 489, 1268, 487, 1269, 491, 1268, 497, 1277, 494, 1280, 500, 1284, 499, 1291, 520, 1301, 530, 1302, 525, 1295, 514, 1296, 505, 1303, 511, 1308, 511, 1306, 529, 1309, 530, 1305, 538, 1306, 546, 1314, 538, 1312, 513, 1315, 507, 1332, 502, 1350, 503, 1359, 507, 1367, 496, 137 [...]
+        "center":[1699, 1318],
+        "bbox":[851.6447204676282, 395.1921392349853, 2840.3658238438866, 1927.5803579274404]
+      },
+      "ARG":{
+        "shape":[4266, 7283, 4247, 7299, 4243, 7327, 4234, 7344, 4220, 7358, 4214, 7373, 4199, 7379, 4195, 7388, 4196, 7398, 4190, 7408, 4190, 7420, 4179, 7429, 4176, 7449, 4173, 7466, 4165, 7470, 4156, 7467, 4133, 7500, 4133, 7527, 4128, 7529, 4131, 7536, 4126, 7548, 4117, 7546, 4118, 7552, 4114, 7559, 4113, 7567, 4120, 7587, 4132, 7598, 4148, 7624, 4150, 7658, 4128, 7673, 4123, 7697, 4141, 7732, 4128, 7764, 4092, 7791, 4072, 7801, 4081, 7791, 4078, 7790, 4067, 7796, 4066, 7805, 4056, 7 [...]
+        "center":[3844, 7427],
+        "bbox":[3079.8299563904675, 6559.710948837265, 1503.4468237083547, 1932.3131259087704]
+      },
+      "GTM":{
+        "shape":[2703, 4007, 2704, 4013, 2714, 4014, 2719, 4021, 2724, 4015, 2721, 4007, 2723, 4005, 2749, 4019, 2717, 4051, 2694, 4067, 2691, 4073, 2695, 4078, 2694, 4087, 2687, 4094, 2678, 4097, 2676, 4103, 2677, 4107, 2671, 4109, 2666, 4114, 2664, 4130, 2657, 4128, 2636, 4137, 2629, 4149, 2624, 4146, 2604, 4141, 2580, 4145, 2572, 4141, 2563, 4142, 2553, 4133, 2553, 4121, 2546, 4125, 2543, 4130, 2533, 4124, 2522, 4111, 2516, 4108, 2521, 4102, 2513, 4105, 2507, 4097, 2515, 4077, 2522, 4 [...]
+        "center":[2632, 4064],
+        "bbox":[2504.4710892223507, 3888.0297237639816, 244.94164798015254, 261.41670333559523]
+      },
+      "CUB":{
+        "shape":[[2933, 3616, 2931, 3615, 2935, 3608, 2933, 3606, 2926, 3607, 2915, 3614, 2908, 3609, 2908, 3605, 2918, 3606, 2932, 3594, 2933, 3598, 2938, 3598, 2939, 3594, 2942, 3598, 2944, 3595, 2932, 3585, 2931, 3581, 2940, 3577, 2941, 3569, 2947, 3558, 2953, 3559, 2969, 3545, 2997, 3527, 3001, 3529, 3002, 3524, 3030, 3522, 3041, 3513, 3057, 3507, 3091, 3505, 3098, 3510, 3098, 3507, 3112, 3503, 3113, 3507, 3119, 3511, 3120, 3505, 3125, 3504, 3129, 3510, 3134, 3508, 3138, 3502, 3144,  [...]
+        "center":[3254, 3570],
+        "bbox":[2907.6385004372205, 3501.8757926257063, 635.855754253464, 187.8782759748019]
+      },
+      "COL":{
+        "shape":[3453, 4780, 3464, 4760, 3463, 4753, 3458, 4758, 3451, 4751, 3456, 4743, 3449, 4744, 3442, 4750, 3432, 4732, 3451, 4713, 3446, 4684, 3445, 4653, 3433, 4646, 3439, 4640, 3453, 4639, 3443, 4613, 3433, 4604, 3448, 4584, 3439, 4568, 3421, 4552, 3408, 4522, 3413, 4505, 3448, 4457, 3457, 4466, 3486, 4432, 3567, 4282, 3582, 4266, 3782, 4205, 3751, 4215, 3726, 4261, 3938, 4588, 3950, 4594, 3963, 4577, 4054, 4628, 4058, 4731, 4076, 4756, 4079, 4773, 4055, 4803, 4093, 4850, 4106, 4 [...]
+        "center":[3728, 4764],
+        "bbox":[3344.9150233501896, 4205.05442331016, 769.3727798464815, 1101.6262084165537]
+      },
+      "BMU":{
+        "shape":[3868, 2698, 3865, 2707, 3861, 2710, 3868, 2698],
+        "center":[3865, 2704],
+        "bbox":[3861.16609866213, 2698.1162638174333, 7.057062414517986, 11.635735072458829]
+      },
+      "USA":{
+        "shape":[[3252, 2312, 3254, 2301, 3258, 2300, 3259, 2298, 3263, 2299, 3260, 2295, 3262, 2292, 3271, 2284, 3275, 2285, 3275, 2282, 3284, 2282, 3287, 2277, 3309, 2269, 3321, 2253, 3323, 2252, 3320, 2257, 3333, 2261, 3337, 2254, 3342, 2252, 3319, 2276, 3288, 2301, 3259, 2315, 3265, 2308, 3262, 2307, 3259, 2310, 3261, 2312, 3255, 2315, 3252, 2312], [607, 75, 613, 73, 621, 78, 611, 77, 611, 79, 622, 86, 627, 83, 635, 85, 632, 89, 635, 93, 655, 90, 666, 97, 662, 103, 667, 113, 673, 112 [...]
+        "center":[1921, 2511],
+        "bbox":[0.0, 0.0, 3464.0746157088206, 3407.3527144654627]
+      },
+      "GUF":{
+        "shape":[5046, 4686, 4938, 4850, 4871, 4827, 4887, 4783, 4880, 4703, 4870, 4682, 4861, 4641, 4867, 4608, 4890, 4549, 4897, 4550, 4941, 4572, 5017, 4637, 5020, 4651, 5025, 4634, 5038, 4669, 5039, 4682, 5046, 4686],
+        "center":[4940, 4698],
+        "bbox":[4860.925510049343, 4549.367698673053, 184.6115110519204, 300.8002238817644]
+      },
+      "DOM":{
+        "shape":[3696, 3740, 3697, 3733, 3705, 3726, 3708, 3715, 3703, 3705, 3692, 3708, 3692, 3704, 3699, 3702, 3704, 3695, 3694, 3681, 3699, 3670, 3691, 3650, 3691, 3648, 3687, 3642, 3695, 3632, 3702, 3630, 3708, 3637, 3716, 3637, 3722, 3632, 3725, 3627, 3734, 3623, 3754, 3631, 3768, 3627, 3779, 3636, 3786, 3635, 3795, 3630, 3800, 3637, 3805, 3654, 3821, 3656, 3830, 3652, 3832, 3647, 3836, 3646, 3837, 3653, 3842, 3652, 3844, 3655, 3838, 3661, 3823, 3661, 3820, 3667, 3826, 3669, 3861, 3 [...]
+        "center":[3774, 3692],
+        "bbox":[3687.2979121982135, 3623.4116970766, 212.23386684770048, 161.84175961872734]
+      },
+      "CRI":{
+        "shape":[2900, 4315, 2911, 4310, 2909, 4304, 3045, 4312, 3047, 4321, 3048, 4329, 3097, 4382, 3123, 4398, 3123, 4401, 3112, 4395, 3091, 4393, 3087, 4425, 3096, 4466, 3092, 4467, 3086, 4474, 3092, 4479, 3096, 4493, 3094, 4493, 3082, 4474, 3076, 4471, 3078, 4467, 3073, 4457, 3062, 4452, 3066, 4457, 3064, 4464, 3061, 4461, 3051, 4463, 3042, 4453, 3048, 4440, 2976, 4368, 2969, 4376, 2957, 4384, 2954, 4392, 2948, 4389, 2944, 4384, 2900, 4315],
+        "center":[3009, 4364],
+        "bbox":[2899.598206383492, 4304.205674803916, 223.53183671721354, 189.18738706152453]
+      },
+      "BRA":{
+        "shape":[4383, 7621, 4379, 7607, 4386, 7581, 4425, 7552, 4410, 7525, 4415, 7503, 4412, 7485, 4396, 7463, 4391, 7439, 4379, 7427, 4373, 7411, 4364, 7409, 4366, 7380, 4358, 7371, 4343, 7385, 4336, 7375, 4341, 7362, 4340, 7351, 4318, 7291, 4309, 7283, 4293, 7294, 4266, 7283, 4307, 7255, 4316, 7260, 4442, 7168, 4499, 7144, 4554, 7130, 4562, 7110, 4583, 7077, 4580, 7041, 4572, 7023, 4549, 7027, 4546, 7003, 4587, 6925, 4591, 6910, 4601, 6899, 4592, 6878, 4557, 6891, 4542, 6872, 4542, 6 [...]
+        "center":[5033, 5857],
+        "bbox":[3650.74334127771, 4615.301479874872, 2376.23266744991, 3005.997050699276]
+      },
+      "NIC":{
+        "shape":[3049, 4043, 3043, 4048, 3042, 4051, 3038, 4050, 3036, 4053, 3042, 4062, 3040, 4074, 3043, 4075, 3045, 4073, 3047, 4079, 3045, 4091, 3044, 4085, 3041, 4085, 3041, 4088, 3044, 4100, 3041, 4104, 3034, 4105, 3037, 4121, 3033, 4127, 3035, 4135, 3027, 4139, 3031, 4145, 3034, 4143, 3034, 4164, 3038, 4179, 3037, 4185, 3042, 4205, 3039, 4209, 3033, 4210, 3032, 4203, 3035, 4201, 3034, 4190, 3026, 4187, 3026, 4190, 3032, 4196, 3026, 4202, 3026, 4206, 3033, 4213, 3029, 4229, 3025, 4 [...]
+        "center":[2942, 4190],
+        "bbox":[2781.800092351701, 4040.403710101379, 267.4645951975731, 271.9592285729759]
+      },
+      "HND":{
+        "shape":[[2676, 4103, 2678, 4097, 2687, 4094, 2694, 4087, 2695, 4078, 2691, 4073, 2694, 4067, 2717, 4051, 2749, 4019, 2753, 4022, 2760, 4006, 2773, 4004, 2788, 4011, 2794, 4008, 2817, 4010, 2836, 4004, 2850, 4004, 2862, 3996, 2883, 3993, 2873, 3986, 2879, 3985, 2886, 3991, 2904, 3997, 2919, 3994, 2926, 3986, 2938, 3988, 2940, 3992, 2954, 3995, 2956, 3998, 2968, 3999, 2970, 3998, 2962, 3994, 2978, 3991, 2993, 4006, 3010, 4018, 2994, 4013, 2993, 4010, 2989, 4011, 2989, 4007, 2985,  [...]
+        "center":[2836, 4066],
+        "bbox":[2676.1584493127866, 3959.967908946132, 373.10623823648757, 227.7520489745125]
+      }
+    }
+}
diff --git a/dojox/geo/charting/resources/data/AsiaPacific.json b/dojox/geo/charting/resources/data/AsiaPacific.json
new file mode 100644
index 0000000..65a15d8
--- /dev/null
+++ b/dojox/geo/charting/resources/data/AsiaPacific.json
@@ -0,0 +1,117 @@
+{
+  "layerExtent":[0.0, 0.0, 6895.063085693021, 7242.4744292020105],
+    "layerExtentLL":[68.135115, 53.498446, 110.74656599999999, 100.08135899999999],
+    "featureNames":["IND", "AUS", "BGD", "NPL", "BTN", "KOR", "NCL", "SGP", "MYS", "KHM", "VNM", "NZL", "LAO", "THA", "LKA", "PNG", "CHN", "PHL", "JPN", "PRK", "MMR", "IDN"],
+    "features":{
+      "IND":{
+        "shape":[0, 2432, 6, 2419, 37, 2418, 35, 2393, 54, 2404, 70, 2398, 103, 2408, 113, 2395, 158, 2391, 162, 2410, 183, 2401, 169, 2393, 180, 2370, 170, 2343, 152, 2327, 152, 2304, 129, 2304, 120, 2283, 128, 2255, 119, 2235, 98, 2240, 88, 2232, 90, 2205, 140, 2147, 157, 2146, 168, 2171, 238, 2156, 240, 2139, 250, 2135, 265, 2100, 293, 2093, 310, 2075, 333, 2013, 369, 1980, 362, 1964, 391, 1932, 408, 1869, 450, 1841, 400, 1825, 406, 1808, 341, 1779, 346, 1746, 328, 1684, 335, 1667, 36 [...]
+        "center":[650, 2477],
+        "bbox":[0.0, 1553.3806140308764, 1832.7038107439128, 1897.60358345378]
+      },
+      "AUS":{
+        "shape":[[2790, 5598, 2810, 5643, 2815, 5635, 2818, 5660, 2820, 5639, 2828, 5669, 2844, 5672, 2849, 5650, 2824, 5617, 2824, 5598, 2840, 5619, 2837, 5636, 2852, 5636, 2862, 5661, 2869, 5656, 2872, 5621, 2852, 5598, 2849, 5576, 2835, 5566, 2835, 5546, 2818, 5528, 2830, 5479, 2847, 5455, 2846, 5422, 2837, 5410, 2861, 5351, 2867, 5348, 2864, 5402, 2875, 5388, 2883, 5394, 2899, 5352, 2950, 5329, 2994, 5295, 2994, 5286, 3013, 5284, 3035, 5265, 3034, 5276, 3054, 5272, 3068, 5283, 3079,  [...]
+        "center":[4091, 5494],
+        "bbox":[2790.192985745117, 4644.536061495616, 2522.7002631517016, 2331.089758969071]
+      },
+      "BGD":{
+        "shape":[1323, 2545, 1323, 2530, 1307, 2518, 1304, 2478, 1294, 2468, 1304, 2458, 1299, 2452, 1284, 2457, 1288, 2440, 1270, 2420, 1299, 2395, 1291, 2386, 1272, 2386, 1237, 2356, 1251, 2344, 1261, 2352, 1276, 2334, 1305, 2334, 1308, 2316, 1254, 2280, 1272, 2249, 1270, 2236, 1286, 2239, 1292, 2251, 1307, 2245, 1306, 2236, 1322, 2239, 1327, 2261, 1362, 2284, 1366, 2330, 1404, 2342, 1499, 2332, 1520, 2351, 1508, 2375, 1452, 2407, 1447, 2464, 1455, 2470, 1470, 2459, 1469, 2470, 1484, 2 [...]
+        "center":[1364, 2398],
+        "bbox":[1236.5296489149703, 2235.523853651565, 298.0267149250244, 382.9454594951726]
+      },
+      "NPL":{
+        "shape":[1255, 2223, 1254, 2241, 1221, 2249, 1185, 2236, 1169, 2246, 1138, 2247, 1111, 2239, 1092, 2220, 1076, 2227, 1042, 2208, 1032, 2192, 999, 2185, 986, 2193, 947, 2187, 939, 2195, 924, 2186, 904, 2189, 907, 2175, 896, 2168, 871, 2165, 863, 2156, 855, 2163, 842, 2156, 843, 2145, 742, 2096, 758, 2062, 754, 2045, 788, 1999, 800, 1996, 803, 1983, 831, 1978, 835, 1992, 853, 1981, 870, 1996, 904, 2005, 943, 2033, 973, 2072, 1005, 2055, 1008, 2088, 1032, 2091, 1040, 2118, 1059, 209 [...]
+        "center":[1004, 2139],
+        "bbox":[742.3903868065366, 1977.6722619709471, 512.4545482700318, 270.8833664876188]
+      },
+      "BTN":{
+        "shape":[1361, 2233, 1363, 2213, 1351, 2218, 1341, 2208, 1321, 2214, 1317, 2203, 1306, 2205, 1296, 2158, 1297, 2143, 1332, 2139, 1357, 2120, 1372, 2127, 1448, 2109, 1471, 2158, 1470, 2171, 1497, 2183, 1501, 2219, 1480, 2225, 1397, 2219, 1388, 2230, 1361, 2233],
+        "center":[1394, 2175],
+        "bbox":[1295.820878786193, 2108.5205308525606, 204.72868109278807, 124.62073843639746]
+      },
+      "KOR":{
+        "shape":[3613, 1484, 3623, 1469, 3627, 1481, 3626, 1467, 3651, 1470, 3656, 1481, 3668, 1473, 3652, 1464, 3658, 1455, 3646, 1455, 3657, 1442, 3643, 1431, 3638, 1408, 3649, 1408, 3647, 1405, 3668, 1366, 3713, 1354, 3725, 1366, 3746, 1338, 3758, 1361, 3809, 1449, 3819, 1489, 3814, 1547, 3826, 1548, 3819, 1591, 3797, 1626, 3786, 1623, 3791, 1610, 3783, 1621, 3760, 1620, 3755, 1647, 3751, 1633, 3731, 1632, 3733, 1622, 3703, 1635, 3714, 1637, 3707, 1654, 3694, 1637, 3699, 1657, 3689, 1 [...]
+        "center":[3717, 1518],
+        "bbox":[3613.0255503183084, 1338.1417417459159, 213.12973710585356, 338.8805968542488]
+      },
+      "NCL":{
+        "shape":[5969, 5249, 5975, 5242, 5986, 5250, 5992, 5245, 6030, 5278, 6049, 5283, 6069, 5314, 6151, 5367, 6156, 5385, 6149, 5392, 6111, 5376, 6099, 5360, 6093, 5363, 6027, 5320, 5969, 5249],
+        "center":[6061, 5322],
+        "bbox":[5969.452927257854, 5242.018468048895, 186.18452909293956, 149.80535924405467]
+      },
+      "SGP":{
+        "shape":[2214, 3873, 2238, 3873, 2219, 3880, 2211, 3878, 2214, 3873],
+        "center":[2221, 3874],
+        "bbox":[2211.1176216573954, 3872.8025546014555, 26.558480737913214, 6.949743893741015]
+      },
+      "MYS":{
+        "shape":[[2590, 3821, 2600, 3818, 2600, 3832, 2615, 3839, 2642, 3844, 2642, 3835, 2644, 3848, 2652, 3840, 2653, 3848, 2692, 3860, 2684, 3846, 2698, 3847, 2688, 3834, 2697, 3818, 2716, 3814, 2692, 3813, 2695, 3799, 2712, 3803, 2704, 3791, 2708, 3783, 2805, 3757, 2865, 3689, 2862, 3671, 2874, 3672, 2899, 3703, 2911, 3701, 2913, 3663, 2931, 3649, 2925, 3671, 2941, 3691, 2946, 3683, 2937, 3651, 2948, 3654, 2963, 3636, 2948, 3624, 2961, 3609, 2964, 3616, 2978, 3614, 2993, 3595, 2986,  [...]
+        "center":[2870, 3753],
+        "bbox":[1986.9320897990997, 3525.801384867716, 1206.5488540101292, 360.7865920472491]
+      },
+      "KHM":{
+        "shape":[2163, 3242, 2166, 3214, 2156, 3183, 2160, 3168, 2141, 3147, 2133, 3093, 2142, 3094, 2173, 3051, 2194, 3041, 2285, 3034, 2294, 3042, 2300, 3046, 2307, 3084, 2329, 3079, 2345, 3091, 2356, 3073, 2348, 3065, 2350, 3053, 2385, 3034, 2396, 3055, 2431, 3059, 2445, 3087, 2451, 3121, 2439, 3148, 2448, 3178, 2342, 3223, 2336, 3251, 2352, 3261, 2338, 3281, 2323, 3274, 2286, 3295, 2266, 3289, 2250, 3303, 2237, 3292, 2216, 3293, 2201, 3304, 2192, 3295, 2208, 3275, 2202, 3264, 2195, 3 [...]
+        "center":[2262, 3159],
+        "bbox":[2132.7228832788937, 3033.623405007715, 318.2133992516383, 270.03586299056224]
+      },
+      "VNM":{
+        "shape":[2250, 3303, 2266, 3289, 2286, 3295, 2323, 3274, 2338, 3281, 2352, 3261, 2336, 3251, 2342, 3223, 2448, 3178, 2439, 3148, 2451, 3121, 2445, 3087, 2431, 3059, 2441, 3038, 2438, 3014, 2450, 3003, 2447, 2988, 2423, 2991, 2435, 2948, 2405, 2932, 2400, 2919, 2386, 2923, 2382, 2883, 2351, 2854, 2327, 2844, 2320, 2819, 2227, 2732, 2228, 2711, 2245, 2706, 2256, 2718, 2278, 2688, 2264, 2658, 2253, 2658, 2254, 2640, 2233, 2629, 2214, 2635, 2168, 2630, 2153, 2595, 2161, 2564, 2132, 2 [...]
+        "center":[2500, 3080],
+        "bbox":[2107.328468786174, 2469.8740732737388, 457.0309717170135, 952.8558665938081]
+      },
+      "NZL":{
+        "shape":[[6123, 7187, 6153, 7175, 6141, 7175, 6149, 7160, 6136, 7161, 6142, 7143, 6160, 7143, 6153, 7126, 6170, 7102, 6180, 7109, 6176, 7097, 6192, 7082, 6206, 7079, 6202, 7069, 6235, 7026, 6259, 7023, 6310, 6988, 6399, 6908, 6425, 6832, 6446, 6827, 6463, 6803, 6474, 6753, 6508, 6730, 6503, 6746, 6527, 6759, 6524, 6782, 6532, 6792, 6578, 6765, 6586, 6763, 6574, 6771, 6581, 6777, 6572, 6794, 6594, 6785, 6581, 6785, 6591, 6771, 6607, 6771, 6582, 6793, 6612, 6778, 6588, 6805, 6604,  [...]
+        "center":[6573, 6742],
+        "bbox":[6123.400268247372, 6236.987293635293, 771.6628174456491, 1005.4871355667174]
+      },
+      "LAO":{
+        "shape":[2230, 2780, 2222, 2785, 2194, 2774, 2174, 2804, 2151, 2816, 2146, 2805, 2113, 2793, 2056, 2840, 2046, 2833, 2059, 2794, 2052, 2775, 2069, 2736, 2062, 2703, 2017, 2709, 2011, 2692, 2023, 2667, 2005, 2653, 1992, 2661, 1992, 2654, 1982, 2646, 2023, 2600, 2041, 2592, 2053, 2589, 2053, 2610, 2083, 2604, 2086, 2577, 2071, 2552, 2078, 2528, 2107, 2530, 2132, 2562, 2161, 2564, 2153, 2595, 2168, 2630, 2214, 2635, 2233, 2629, 2254, 2640, 2253, 2658, 2264, 2658, 2278, 2688, 2256, 2 [...]
+        "center":[2137, 2682],
+        "bbox":[1982.1338860048786, 2528.2261833230514, 467.3740847231775, 563.0946494553846]
+      },
+      "THA":{
+        "shape":[1822, 2775, 1833, 2779, 1848, 2771, 1845, 2750, 1866, 2691, 1880, 2701, 1918, 2694, 1930, 2671, 1955, 2669, 1954, 2652, 1971, 2656, 1976, 2650, 1982, 2646, 1992, 2654, 1992, 2661, 2005, 2653, 2023, 2667, 2011, 2692, 2017, 2709, 2062, 2703, 2069, 2736, 2052, 2775, 2059, 2794, 2046, 2833, 2056, 2840, 2113, 2793, 2146, 2805, 2151, 2816, 2174, 2804, 2194, 2774, 2222, 2785, 2230, 2780, 2234, 2785, 2278, 2838, 2279, 2897, 2300, 2924, 2320, 2927, 2323, 2948, 2336, 2953, 2325, 2 [...]
+        "center":[2059, 2954],
+        "bbox":[1822.2011784234624, 2646.3881458311816, 513.3899761430221, 955.7310374303006]
+      },
+      "LKA":{
+        "shape":[746, 3365, 780, 3359, 796, 3376, 797, 3393, 814, 3402, 826, 3422, 833, 3455, 847, 3465, 852, 3488, 847, 3552, 821, 3573, 776, 3585, 750, 3577, 728, 3530, 733, 3516, 726, 3459, 748, 3384, 746, 3365],
+        "center":[781, 3460],
+        "bbox":[726.0874402722717, 3358.847500305047, 126.19872289792556, 226.0434745317507]
+      },
+      "PNG":{
+        "shape":[[4539, 4124, 4655, 4170, 4694, 4173, 4736, 4203, 4741, 4196, 4754, 4198, 4755, 4210, 4773, 4214, 4790, 4232, 4805, 4233, 4836, 4260, 4830, 4301, 4871, 4307, 4896, 4323, 4947, 4337, 4960, 4353, 4965, 4375, 4945, 4382, 4907, 4379, 4905, 4395, 4914, 4400, 4920, 4425, 4933, 4426, 4967, 4461, 4982, 4462, 4982, 4493, 5000, 4503, 5002, 4519, 5015, 4529, 5057, 4526, 5045, 4552, 5068, 4562, 5097, 4561, 5098, 4568, 5079, 4572, 5095, 4592, 5108, 4589, 5128, 4601, 5148, 4600, 5135,  [...]
+        "center":[4737, 4341],
+        "bbox":[4517.1726424465205, 4124.491006225601, 728.4015748520624, 506.92523360536234]
+      },
+      "CHN":{
+        "shape":[[1232, 432, 1233, 479, 1250, 491, 1246, 500, 1279, 518, 1289, 540, 1343, 552, 1394, 583, 1436, 669, 1434, 722, 1412, 767, 1426, 795, 1581, 815, 1667, 869, 1708, 874, 1703, 896, 1769, 1009, 1822, 1003, 1959, 1025, 2033, 1015, 2106, 1030, 2127, 1053, 2231, 1089, 2273, 1083, 2275, 1101, 2307, 1106, 2318, 1092, 2451, 1031, 2571, 1030, 2640, 1006, 2686, 951, 2738, 921, 2707, 869, 2740, 803, 2768, 807, 2788, 827, 2847, 831, 2910, 773, 2974, 769, 3006, 747, 3026, 700, 3076, 690 [...]
+        "center":[2087, 1626],
+        "bbox":[327.07055968409804, 0.0, 3834.887464012385, 2809.2690933424037]
+      },
+      "PHL":{
+        "shape":[[3264, 2804, 3260, 2793, 3273, 2791, 3278, 2781, 3280, 2790, 3295, 2783, 3333, 2800, 3341, 2810, 3366, 2790, 3373, 2803, 3359, 2820, 3357, 2846, 3362, 2867, 3374, 2867, 3376, 2905, 3354, 2951, 3356, 2936, 3321, 2959, 3322, 2977, 3310, 2995, 3331, 3034, 3325, 3039, 3328, 3056, 3363, 3090, 3369, 3080, 3362, 3069, 3371, 3072, 3376, 3062, 3393, 3060, 3417, 3083, 3415, 3100, 3429, 3098, 3433, 3084, 3425, 3083, 3426, 3076, 3467, 3093, 3470, 3099, 3447, 3101, 3444, 3108, 3456,  [...]
+        "center":[3436, 3120],
+        "bbox":[3206.1596213214366, 2780.731692988706, 430.3549828939913, 833.968847311563]
+      },
+      "JPN":{
+        "shape":[[3922, 1699, 3930, 1660, 3956, 1663, 4033, 1599, 4034, 1587, 4063, 1574, 4077, 1579, 4052, 1590, 4076, 1590, 4071, 1580, 4080, 1587, 4150, 1572, 4171, 1577, 4190, 1565, 4194, 1573, 4185, 1582, 4192, 1579, 4194, 1590, 4204, 1578, 4209, 1587, 4225, 1584, 4240, 1565, 4241, 1574, 4236, 1549, 4285, 1486, 4289, 1441, 4324, 1429, 4294, 1463, 4306, 1462, 4307, 1488, 4322, 1487, 4328, 1475, 4393, 1440, 4411, 1406, 4443, 1381, 4485, 1268, 4486, 1228, 4473, 1244, 4465, 1236, 4483,  [...]
+        "center":[4445, 1486],
+        "bbox":[3836.932558750513, 774.440002907967, 1000.6024246850106, 1153.5157400187752]
+      },
+      "PRK":{
+        "shape":[3568, 1188, 3615, 1163, 3667, 1088, 3678, 1113, 3721, 1129, 3749, 1127, 3760, 1103, 3739, 1084, 3747, 1070, 3778, 1080, 3816, 1054, 3817, 1040, 3843, 1038, 3858, 990, 3903, 1042, 3891, 1047, 3838, 1104, 3850, 1123, 3843, 1165, 3812, 1177, 3807, 1197, 3774, 1209, 3778, 1218, 3767, 1225, 3739, 1226, 3723, 1247, 3705, 1249, 3709, 1287, 3698, 1280, 3694, 1293, 3731, 1316, 3746, 1338, 3725, 1366, 3713, 1354, 3668, 1366, 3647, 1405, 3635, 1399, 3602, 1406, 3591, 1395, 3586, 14 [...]
+        "center":[3641, 1276],
+        "bbox":[3508.0787352459915, 990.246910404928, 394.51872200758544, 428.97576876293147]
+      },
+      "MMR":{
+        "shape":[1495, 2618, 1492, 2605, 1503, 2592, 1525, 2606, 1513, 2563, 1533, 2532, 1542, 2519, 1548, 2532, 1571, 2513, 1560, 2480, 1583, 2426, 1584, 2395, 1596, 2404, 1630, 2404, 1666, 2330, 1652, 2321, 1694, 2262, 1691, 2243, 1703, 2223, 1728, 2212, 1752, 2186, 1790, 2177, 1816, 2188, 1804, 2164, 1829, 2152, 1825, 2136, 1833, 2125, 1825, 2117, 1827, 2110, 1865, 2124, 1872, 2180, 1891, 2168, 1904, 2206, 1896, 2296, 1881, 2298, 1877, 2314, 1864, 2312, 1857, 2331, 1838, 2341, 1835, 2 [...]
+        "center":[1741, 2564],
+        "bbox":[1492.2717554687163, 2109.8674098101424, 560.4793848238899, 1214.2488246709763]
+      },
+      "IDN":{
+        "shape":[[3923, 4038, 3938, 4022, 3932, 4006, 3951, 3994, 3971, 4001, 4018, 3971, 4062, 4001, 4105, 4002, 4126, 4036, 4111, 4068, 4111, 4100, 4125, 4125, 4131, 4110, 4142, 4107, 4155, 4148, 4175, 4166, 4199, 4166, 4252, 4092, 4265, 4095, 4291, 4081, 4291, 4068, 4309, 4065, 4331, 4045, 4349, 4054, 4354, 4070, 4375, 4066, 4446, 4099, 4456, 4111, 4480, 4106, 4524, 4118, 4539, 4124, 4540, 4349, 4524, 4367, 4517, 4390, 4527, 4401, 4532, 4525, 4512, 4512, 4448, 4460, 4389, 4456, 4399,  [...]
+        "center":[2863, 3978],
+        "bbox":[1664.4703421788538, 3595.7006863209563, 2875.9337926098133, 928.9499549191287]
+      }
+    }
+}
diff --git a/dojox/geo/charting/resources/data/ContinentalEurope.json b/dojox/geo/charting/resources/data/ContinentalEurope.json
new file mode 100644
index 0000000..cba955b
--- /dev/null
+++ b/dojox/geo/charting/resources/data/ContinentalEurope.json
@@ -0,0 +1,217 @@
+{
+  "layerExtent":[0.0, 0.0, 8782.476659627813, 7091.026765715562],
+    "layerExtentLL":[-10.46209716796875, 71.14974975585938, 55.28059387207031, 36.56523513793945],
+    "featureNames":["PRT", "MKD", "YUG", "ROM", "GRC", "FRA", "LUX", "HUN", "BLR", "GBR", "CHE", "LIE", "MDA", "DNK", "NOR", "LVA", "ALB", "DEU", "SWE", "CZE", "AND", "ITA", "FIN", "HRV", "LTU", "GIB", "NLD", "IRL", "CYP", "TUR", "POL", "BGR", "AUT", "MLT", "EST", "SMR", "SVK", "BEL", "SVN", "UKR", "BIH", "ESP"],
+    "features":{
+      "PRT":{
+        "shape":[396, 4666, 416, 4655, 440, 4674, 495, 4669, 474, 4716, 487, 4738, 552, 4732, 576, 4768, 627, 4749, 680, 4767, 703, 4797, 701, 4830, 733, 4866, 586, 4955, 575, 5035, 532, 5161, 484, 5212, 458, 5218, 420, 5198, 443, 5343, 363, 5464, 392, 5502, 336, 5538, 291, 5589, 280, 5673, 255, 5680, 182, 5691, 68, 5619, 11, 5635, 0, 5621, 63, 5553, 136, 5366, 154, 5381, 150, 5333, 84, 5325, 139, 5283, 145, 5248, 117, 5266, 56, 5270, 63, 5246, 124, 5157, 117, 5133, 169, 5124, 271, 4971, [...]
+        "center":[295, 5202],
+        "bbox":[0.0, 4654.741912326274, 732.8668581879103, 1036.414500258673]
+      },
+      "MKD":{
+        "shape":[5129, 5492, 5136, 5524, 5203, 5579, 5219, 5669, 5208, 5693, 5200, 5693, 5182, 5733, 5079, 5725, 5033, 5770, 5001, 5783, 4979, 5770, 4907, 5779, 4902, 5796, 4860, 5778, 4824, 5666, 4841, 5640, 4834, 5582, 4849, 5559, 4914, 5514, 4942, 5543, 4962, 5542, 4994, 5518, 5101, 5488, 5129, 5492],
+        "center":[5020, 5656],
+        "bbox":[4823.5541713750545, 5488.270757088617, 395.5636703875616, 308.1807903040317]
+      },
+      "YUG":{
+        "shape":[5129, 5492, 5101, 5488, 4994, 5518, 4962, 5542, 4942, 5543, 4914, 5514, 4849, 5559, 4834, 5582, 4834, 5558, 4821, 5504, 4792, 5488, 4783, 5440, 4726, 5443, 4721, 5406, 4658, 5481, 4648, 5567, 4626, 5559, 4565, 5461, 4574, 5443, 4559, 5427, 4529, 5444, 4487, 5419, 4423, 5357, 4399, 5362, 4377, 5344, 4392, 5326, 4401, 5324, 4451, 5328, 4517, 5417, 4539, 5397, 4542, 5333, 4588, 5260, 4613, 5264, 4616, 5222, 4685, 5177, 4672, 5126, 4698, 5122, 4710, 5101, 4698, 5066, 4650, 5 [...]
+        "center":[4944, 5223],
+        "bbox":[4377.259621478336, 4669.231116220744, 845.5630580571906, 912.7528487071122]
+      },
+      "ROM":{
+        "shape":[6051, 5182, 5991, 5179, 5977, 5147, 5952, 5134, 5814, 5133, 5723, 5162, 5631, 5233, 5542, 5211, 5526, 5227, 5474, 5226, 5423, 5247, 5287, 5201, 5221, 5209, 5209, 5156, 5230, 5139, 5191, 5125, 5191, 5115, 5152, 5092, 5150, 5067, 5172, 5022, 5146, 5005, 5107, 5061, 5083, 5052, 5073, 5015, 5034, 5022, 4987, 4984, 5020, 4947, 4997, 4921, 5010, 4874, 4909, 4825, 4916, 4765, 4883, 4752, 4860, 4715, 4830, 4680, 4916, 4696, 4926, 4654, 5012, 4610, 4999, 4583, 5032, 4555, 5091, 4 [...]
+        "center":[5548, 4759],
+        "bbox":[4829.98113117481, 4251.517417439844, 1386.503107128071, 995.4050048986155]
+      },
+      "GRC":{
+        "shape":[[5023, 6360, 5192, 6438, 5226, 6481, 5224, 6503, 5268, 6522, 5274, 6547, 5226, 6552, 5162, 6504, 5145, 6507, 5214, 6749, 5137, 6675, 5109, 6704, 5113, 6749, 5087, 6737, 5089, 6701, 5055, 6654, 5046, 6606, 5016, 6609, 5003, 6687, 4972, 6671, 4947, 6585, 4954, 6561, 4975, 6574, 4976, 6526, 4919, 6484, 4909, 6448, 4888, 6446, 4891, 6425, 4914, 6422, 4936, 6376, 4962, 6386, 5023, 6360], [4902, 5796, 4907, 5779, 4979, 5770, 5001, 5783, 5033, 5770, 5079, 5725, 5182, 5733, 5200 [...]
+        "center":[4997, 6076],
+        "bbox":[4727.331184307009, 5628.583433838603, 1070.7649360879159, 1447.1992362133205]
+      },
+      "FRA":{
+        "shape":[[3159, 5161, 3144, 5346, 3109, 5399, 3109, 5432, 3082, 5446, 3061, 5494, 3017, 5450, 3024, 5424, 3005, 5408, 3026, 5380, 3004, 5376, 3014, 5335, 2998, 5304, 3016, 5294, 3013, 5277, 3052, 5227, 3125, 5224, 3140, 5212, 3140, 5185, 3159, 5161], [1950, 5001, 1893, 4909, 1854, 4896, 1836, 4930, 1814, 4936, 1782, 4912, 1679, 4907, 1562, 4777, 1558, 4750, 1527, 4742, 1517, 4710, 1554, 4704, 1602, 4668, 1659, 4488, 1685, 4493, 1693, 4477, 1671, 4471, 1729, 4305, 1754, 4332, 1756 [...]
+        "center":[2391, 4201],
+        "bbox":[1389.1537208525626, 3334.0757472314876, 1818.9218616686878, 2159.8283896845455]
+      },
+      "LUX":{
+        "shape":[2984, 3769, 2966, 3757, 2908, 3741, 2909, 3713, 2923, 3690, 2910, 3649, 2927, 3620, 2953, 3603, 2969, 3625, 2970, 3641, 2978, 3672, 3031, 3700, 3002, 3732, 2984, 3769],
+        "center":[2962, 3696],
+        "bbox":[2907.6713569580397, 3603.467367591528, 123.24150710128379, 165.85538337450043]
+      },
+      "HUN":{
+        "shape":[4296, 4559, 4280, 4505, 4263, 4493, 4241, 4490, 4259, 4449, 4310, 4454, 4313, 4401, 4343, 4371, 4351, 4320, 4410, 4319, 4424, 4265, 4465, 4285, 4572, 4331, 4653, 4318, 4657, 4287, 4673, 4278, 4761, 4279, 4783, 4240, 4855, 4256, 4928, 4188, 4999, 4196, 5033, 4180, 5072, 4227, 5141, 4229, 5188, 4258, 5221, 4279, 5246, 4292, 5208, 4348, 5148, 4358, 5102, 4416, 5091, 4458, 5032, 4555, 4999, 4583, 5012, 4610, 4926, 4654, 4916, 4696, 4830, 4680, 4806, 4677, 4766, 4669, 4706, 4 [...]
+        "center":[4685, 4449],
+        "bbox":[4240.598733661701, 4179.61869450014, 1005.8462491207201, 570.2990284681373]
+      },
+      "BLR":{
+        "shape":[6425, 3423, 6320, 3436, 6271, 3537, 6274, 3583, 6253, 3592, 6187, 3569, 6125, 3599, 6089, 3558, 6057, 3569, 6040, 3606, 6002, 3574, 5977, 3580, 5960, 3562, 5931, 3588, 5899, 3573, 5894, 3597, 5863, 3566, 5818, 3576, 5807, 3539, 5725, 3531, 5644, 3497, 5461, 3509, 5445, 3549, 5425, 3562, 5359, 3555, 5339, 3570, 5363, 3473, 5345, 3448, 5281, 3430, 5288, 3395, 5392, 3332, 5390, 3274, 5338, 3154, 5327, 3100, 5412, 3091, 5453, 3105, 5501, 3076, 5501, 3050, 5530, 3047, 5556, 3 [...]
+        "center":[5896, 3189],
+        "bbox":[5280.61240158958, 2644.1461892591474, 1246.3505057674956, 962.3247039589578]
+      },
+      "GBR":{
+        "shape":[[1387, 2272, 1445, 2244, 1428, 2244, 1434, 2221, 1467, 2227, 1508, 2193, 1526, 2194, 1540, 2189, 1555, 2199, 1637, 2194, 1660, 2204, 1689, 2250, 1701, 2307, 1674, 2333, 1709, 2348, 1707, 2391, 1697, 2400, 1691, 2360, 1680, 2363, 1682, 2414, 1646, 2412, 1603, 2437, 1588, 2413, 1576, 2412, 1544, 2413, 1514, 2326, 1436, 2360, 1408, 2338, 1386, 2293, 1387, 2272], [1757, 1924, 1807, 1925, 1816, 1889, 1837, 1887, 1846, 1872, 1862, 1877, 1850, 1861, 1878, 1831, 1852, 1832, 1843 [...]
+        "center":[2106, 2792],
+        "bbox":[1386.396950473032, 1619.880728410524, 1106.5609306791955, 1704.773969541746]
+      },
+      "CHE":{
+        "shape":[3310, 4301, 3311, 4319, 3307, 4332, 3323, 4332, 3326, 4332, 3361, 4349, 3360, 4364, 3392, 4388, 3430, 4366, 3447, 4372, 3444, 4378, 3423, 4435, 3435, 4445, 3428, 4461, 3407, 4456, 3399, 4435, 3369, 4451, 3378, 4511, 3359, 4515, 3353, 4486, 3312, 4494, 3286, 4482, 3283, 4444, 3258, 4442, 3242, 4496, 3199, 4539, 3209, 4559, 3198, 4575, 3170, 4533, 3182, 4519, 3140, 4491, 3140, 4436, 3127, 4425, 3095, 4443, 3048, 4504, 2982, 4510, 2962, 4525, 2926, 4492, 2893, 4459, 2897, 4 [...]
+        "center":[3132, 4332],
+        "bbox":[2773.2296150390807, 4151.13757166414, 673.2834867511497, 423.6197832599282]
+      },
+      "LIE":{
+        "shape":[3310, 4301, 3323, 4293, 3323, 4332, 3307, 4332, 3311, 4319, 3310, 4301],
+        "center":[3319, 4312],
+        "bbox":[3306.7960818268534, 4293.175176106674, 16.507123954927465, 38.79294440283775]
+      },
+      "MDA":{
+        "shape":[6022, 4835, 6007, 4814, 5991, 4713, 6012, 4609, 6008, 4560, 5981, 4507, 5925, 4471, 5897, 4409, 5854, 4370, 5854, 4334, 5824, 4284, 5797, 4254, 5759, 4252, 5786, 4219, 5889, 4214, 5986, 4263, 6067, 4260, 6123, 4308, 6118, 4398, 6182, 4437, 6189, 4510, 6238, 4530, 6236, 4570, 6250, 4581, 6241, 4617, 6155, 4617, 6140, 4595, 6122, 4598, 6105, 4687, 6037, 4772, 6022, 4835],
+        "center":[6040, 4504],
+        "bbox":[5759.343117433546, 4214.361644561391, 490.214462650496, 620.8730025435534]
+      },
+      "DNK":{
+        "shape":[3436, 2475, 3445, 2446, 3459, 2453, 3470, 2436, 3449, 2423, 3454, 2383, 3509, 2410, 3514, 2430, 3574, 2364, 3587, 2378, 3569, 2418, 3585, 2407, 3599, 2415, 3601, 2434, 3599, 2340, 3693, 2339, 3734, 2359, 3734, 2405, 3708, 2410, 3712, 2422, 3732, 2427, 3739, 2458, 3773, 2457, 3793, 2483, 3776, 2512, 3717, 2513, 3691, 2571, 3664, 2566, 3647, 2582, 3666, 2594, 3618, 2598, 3625, 2624, 3601, 2625, 3603, 2683, 3575, 2716, 3589, 2749, 3570, 2760, 3546, 2765, 3462, 2733, 3470, 2 [...]
+        "center":[3584, 2525],
+        "bbox":[3420.890187915242, 2338.6792348652752, 372.5005178331271, 426.79504676399256]
+      },
+      "NOR":{
+        "shape":[3270, 1332, 3306, 1330, 3295, 1305, 3330, 1310, 3305, 1286, 3308, 1276, 3340, 1305, 3344, 1285, 3381, 1288, 3398, 1251, 3461, 1266, 3480, 1260, 3450, 1254, 3452, 1225, 3523, 1222, 3588, 1239, 3589, 1213, 3533, 1212, 3530, 1200, 3547, 1194, 3532, 1172, 3554, 1165, 3610, 1184, 3647, 1174, 3661, 1149, 3841, 1113, 3865, 1120, 3878, 1159, 3974, 1154, 3985, 1139, 3965, 1131, 3982, 1120, 4039, 1110, 4037, 1098, 4014, 1096, 4011, 1084, 4037, 1078, 4049, 1068, 4031, 1059, 3973, 1 [...]
+        "center":[3749, 1499],
+        "bbox":[3206.1300848898977, 0.0, 2910.608003891943, 2102.507570422189]
+      },
+      "LVA":{
+        "shape":[5029, 2661, 5019, 2614, 5031, 2517, 5079, 2474, 5087, 2427, 5123, 2371, 5234, 2345, 5237, 2376, 5299, 2419, 5307, 2475, 5357, 2494, 5412, 2487, 5410, 2473, 5432, 2454, 5440, 2344, 5438, 2329, 5589, 2297, 5628, 2326, 5650, 2327, 5701, 2381, 5761, 2370, 5816, 2386, 5850, 2409, 5843, 2490, 5856, 2508, 5877, 2504, 5881, 2529, 5903, 2547, 5929, 2612, 5924, 2636, 5924, 2645, 5899, 2644, 5843, 2730, 5781, 2730, 5746, 2756, 5727, 2742, 5701, 2735, 5598, 2647, 5545, 2657, 5528, 2 [...]
+        "center":[5423, 2512],
+        "bbox":[5019.230374572152, 2296.6864929758767, 909.7418921146809, 459.5347027928128]
+      },
+      "ALB":{
+        "shape":[4648, 5567, 4658, 5481, 4721, 5406, 4726, 5443, 4783, 5440, 4792, 5488, 4821, 5504, 4834, 5558, 4834, 5582, 4841, 5640, 4824, 5666, 4860, 5778, 4902, 5796, 4912, 5839, 4870, 5867, 4845, 5935, 4781, 5953, 4794, 5989, 4780, 6032, 4727, 6043, 4735, 6020, 4718, 5965, 4630, 5908, 4623, 5880, 4643, 5895, 4654, 5884, 4634, 5811, 4681, 5762, 4680, 5740, 4659, 5739, 4659, 5720, 4660, 5663, 4686, 5624, 4682, 5583, 4648, 5567],
+        "center":[4753, 5764],
+        "bbox":[4623.431242826121, 5406.314044939459, 288.21254656338806, 636.9616333739486]
+      },
+      "DEU":{
+        "shape":[2953, 3485, 3002, 3443, 3030, 3379, 3027, 3282, 3104, 3280, 3126, 3269, 3111, 3251, 3170, 3232, 3181, 3192, 3135, 3172, 3132, 3151, 3164, 3133, 3192, 3134, 3233, 3029, 3241, 3030, 3245, 3005, 3222, 2986, 3228, 2954, 3243, 2948, 3343, 2953, 3354, 3017, 3379, 2983, 3398, 3003, 3415, 2991, 3398, 2986, 3403, 2965, 3430, 2935, 3458, 2956, 3508, 2959, 3538, 3013, 3589, 3029, 3552, 3013, 3517, 2953, 3465, 2929, 3455, 2906, 3484, 2909, 3479, 2889, 3462, 2883, 3466, 2871, 3489, 2 [...]
+        "center":[3544, 3480],
+        "bbox":[2953.016761917256, 2733.3140050332836, 1259.4756998525709, 1584.1743477288733]
+      },
+      "SWE":{
+        "shape":[3896, 1960, 3923, 1965, 3946, 2006, 3972, 1967, 4006, 1852, 4002, 1821, 4039, 1831, 4072, 1822, 4091, 1787, 4083, 1753, 4110, 1736, 4096, 1678, 4072, 1650, 4070, 1607, 4139, 1604, 4156, 1569, 4144, 1544, 4084, 1492, 4111, 1382, 4087, 1356, 4085, 1276, 4113, 1259, 4097, 1193, 4118, 1151, 4205, 1084, 4265, 1085, 4327, 1102, 4355, 1075, 4358, 1046, 4337, 1011, 4306, 997, 4409, 891, 4431, 788, 4419, 742, 4470, 746, 4528, 722, 4519, 689, 4658, 603, 4613, 537, 4641, 528, 4668, [...]
+        "center":[4534, 1305],
+        "bbox":[3888.131745912067, 306.0048147794044, 1551.5354299424903, 2423.2214513238337]
+      },
+      "CZE":{
+        "shape":[4428, 4125, 4375, 4119, 4336, 4089, 4303, 4105, 4236, 4062, 4144, 4030, 4122, 4075, 4098, 4072, 4085, 4109, 4053, 4091, 4013, 4119, 3964, 4073, 3961, 4051, 3889, 3997, 3853, 3907, 3822, 3891, 3811, 3850, 3823, 3804, 3769, 3774, 3748, 3721, 3780, 3716, 3793, 3745, 4028, 3648, 4099, 3650, 4093, 3631, 4107, 3609, 4135, 3611, 4143, 3649, 4169, 3659, 4212, 3635, 4227, 3660, 4367, 3725, 4348, 3756, 4385, 3820, 4434, 3819, 4424, 3757, 4497, 3803, 4537, 3803, 4523, 3834, 4557, 3 [...]
+        "center":[4244, 3871],
+        "bbox":[3747.6248024833585, 3609.333820252675, 943.12816012453, 515.6231612420029]
+      },
+      "AND":{
+        "shape":[1986, 5011, 1979, 5036, 1978, 5038, 1940, 5035, 1940, 5014, 1950, 5001, 1965, 4993, 1986, 5011],
+        "center":[1959, 5022],
+        "bbox":[1939.993290837291, 4993.367487680855, 45.825468943671694, 44.217785379021734]
+      },
+      "ITA":{
+        "shape":[[2887, 5588, 2934, 5592, 3000, 5562, 3032, 5531, 3043, 5540, 3070, 5522, 3087, 5559, 3109, 5564, 3102, 5603, 3115, 5613, 3119, 5656, 3083, 5747, 3100, 5774, 3044, 5964, 2951, 5915, 2955, 5975, 2925, 6004, 2889, 5994, 2881, 5955, 2872, 5945, 2857, 5961, 2854, 5944, 2913, 5777, 2886, 5778, 2913, 5661, 2908, 5627, 2885, 5625, 2887, 5588], [2895, 4959, 2942, 4899, 2945, 4867, 2895, 4879, 2822, 4831, 2826, 4800, 2869, 4738, 2870, 4707, 2838, 4696, 2839, 4665, 2852, 4641, 2884 [...]
+        "center":[3699, 5336],
+        "bbox":[2821.7097080697677, 4372.265186762417, 1663.615501009117, 2232.6688401062866]
+      },
+      "FIN":{
+        "shape":[5089, 310, 5102, 300, 5136, 313, 5144, 303, 5128, 284, 5152, 266, 5186, 277, 5244, 325, 5258, 372, 5286, 362, 5298, 376, 5347, 382, 5395, 368, 5405, 354, 5523, 393, 5543, 383, 5563, 348, 5584, 350, 5605, 335, 5602, 278, 5624, 228, 5674, 180, 5744, 186, 5778, 158, 5811, 157, 5838, 184, 5919, 208, 5954, 244, 5908, 287, 5915, 314, 5897, 325, 5875, 338, 5911, 349, 5870, 412, 5897, 464, 5966, 480, 6005, 521, 6042, 538, 6037, 563, 5955, 664, 6009, 723, 6067, 862, 6026, 876, 60 [...]
+        "center":[5726, 1213],
+        "bbox":[5081.225920091001, 156.8080055210209, 1184.9355634318117, 1777.2416921524605]
+      },
+      "HRV":{
+        "shape":[4392, 5326, 4297, 5224, 4232, 5188, 4159, 5186, 4150, 5151, 4042, 5030, 4076, 5017, 4109, 5041, 4129, 5038, 4028, 4936, 4037, 4865, 3976, 4778, 3924, 4824, 3923, 4857, 3888, 4881, 3843, 4818, 3843, 4739, 3860, 4728, 3895, 4734, 3932, 4738, 3954, 4736, 3976, 4692, 4010, 4718, 4093, 4744, 4107, 4706, 4155, 4669, 4154, 4650, 4127, 4638, 4145, 4613, 4184, 4580, 4260, 4575, 4284, 4559, 4296, 4559, 4360, 4606, 4423, 4696, 4449, 4693, 4453, 4720, 4490, 4735, 4536, 4727, 4572, 4 [...]
+        "center":[4262, 4690],
+        "bbox":[3842.5325085954673, 4559.400025495054, 859.514165662451, 766.1585288229353]
+      },
+      "LTU":{
+        "shape":[5327, 3100, 5331, 3041, 5282, 3004, 5256, 3000, 5237, 2976, 5251, 2914, 5222, 2854, 5155, 2848, 5095, 2820, 5055, 2817, 5025, 2689, 5029, 2661, 5156, 2601, 5318, 2598, 5430, 2630, 5500, 2596, 5528, 2606, 5545, 2657, 5598, 2647, 5701, 2735, 5727, 2742, 5746, 2756, 5723, 2774, 5711, 2807, 5737, 2808, 5732, 2846, 5634, 2892, 5603, 3002, 5607, 3058, 5588, 3054, 5583, 3029, 5556, 3024, 5530, 3047, 5501, 3050, 5501, 3076, 5453, 3105, 5412, 3091, 5327, 3100],
+        "center":[5389, 2829],
+        "bbox":[5025.067929032761, 2595.85953724431, 721.0016256463132, 509.18959613926745]
+      },
+      "GIB":{
+        "shape":[500, 6018, 499, 6018, 512, 5992, 526, 5998, 526, 6002, 500, 6018],
+        "center":[511, 6009],
+        "bbox":[498.87494372829696, 5992.239333029375, 27.41012013849371, 25.897505756022838]
+      },
+      "NLD":{
+        "shape":[2617, 3302, 2683, 3293, 2708, 3324, 2730, 3318, 2770, 3288, 2763, 3225, 2794, 3261, 2843, 3273, 2844, 3257, 2785, 3244, 2768, 3210, 2796, 3167, 2829, 3152, 2924, 2976, 2909, 3037, 2948, 3050, 2907, 3141, 2959, 3180, 2979, 3172, 2968, 3127, 3022, 3124, 3001, 3096, 3006, 3075, 3037, 3061, 3015, 3060, 3020, 3048, 3000, 3062, 3002, 3033, 2981, 3060, 3006, 2981, 3174, 2972, 3216, 3027, 3233, 3029, 3192, 3134, 3164, 3133, 3132, 3151, 3135, 3172, 3181, 3192, 3170, 3232, 3111, 3 [...]
+        "center":[2972, 3198],
+        "bbox":[2617.298463488684, 2972.0258802796207, 615.5302560472664, 513.3867943758423]
+      },
+      "IRL":{
+        "shape":[1526, 2194, 1508, 2193, 1467, 2227, 1434, 2221, 1428, 2244, 1445, 2244, 1387, 2272, 1386, 2293, 1408, 2338, 1436, 2360, 1514, 2326, 1544, 2413, 1576, 2412, 1584, 2417, 1587, 2437, 1566, 2435, 1555, 2452, 1576, 2522, 1566, 2554, 1539, 2568, 1558, 2580, 1546, 2636, 1495, 2686, 1479, 2731, 1450, 2746, 1460, 2783, 1418, 2782, 1372, 2754, 1336, 2763, 1283, 2746, 1280, 2764, 1250, 2756, 1229, 2779, 1187, 2779, 1191, 2749, 1165, 2748, 1174, 2777, 1148, 2786, 1070, 2775, 1034, 2 [...]
+        "center":[1330, 2520],
+        "bbox":[923.8294699975862, 2128.2663648156276, 663.2337541704218, 658.218441979011]
+      },
+      "CYP":{
+        "shape":[6748, 6998, 6770, 7001, 6804, 6968, 6840, 6974, 6852, 6962, 6845, 6932, 7012, 6911, 7057, 6870, 7128, 6840, 7026, 6917, 7022, 6954, 7048, 6987, 6999, 6991, 6946, 7043, 6886, 7063, 6880, 7085, 6863, 7091, 6847, 7065, 6783, 7062, 6748, 6998],
+        "center":[6933, 6971],
+        "bbox":[6748.170375850311, 6840.275310365706, 379.907421510733, 250.75145534985586]
+      },
+      "TUR":{
+        "shape":[[5680, 5851, 5754, 5788, 5752, 5724, 5798, 5706, 5785, 5647, 5771, 5633, 5759, 5599, 5870, 5554, 5914, 5595, 5980, 5574, 5985, 5584, 5976, 5621, 5997, 5661, 6056, 5696, 6063, 5715, 6081, 5700, 6138, 5722, 6131, 5769, 6114, 5786, 6024, 5763, 5969, 5785, 5940, 5774, 5917, 5784, 5880, 5837, 5818, 5869, 5688, 5981, 5708, 5941, 5699, 5927, 5791, 5883, 5797, 5867, 5700, 5870, 5680, 5851], [6677, 5571, 6815, 5521, 7026, 5513, 7051, 5479, 7078, 5483, 7095, 5540, 7154, 5569, 7213 [...]
+        "center":[7070, 6055],
+        "bbox":[5680.139003117616, 5401.985684257991, 3102.337656510197, 1396.619600449635]
+      },
+      "POL":{
+        "shape":[5256, 3000, 5282, 3004, 5331, 3041, 5327, 3100, 5338, 3154, 5390, 3274, 5392, 3332, 5288, 3395, 5281, 3430, 5345, 3448, 5363, 3473, 5339, 3570, 5339, 3590, 5344, 3623, 5388, 3697, 5409, 3712, 5396, 3731, 5409, 3754, 5402, 3787, 5287, 3875, 5218, 3964, 5218, 4024, 5237, 4065, 5221, 4086, 5121, 4046, 5092, 4015, 5074, 4026, 5058, 4000, 5033, 4011, 5001, 3995, 4941, 4031, 4898, 4006, 4810, 4040, 4765, 3965, 4751, 3958, 4707, 3996, 4692, 3977, 4687, 3959, 4691, 3940, 4665, 3 [...]
+        "center":[4741, 3472],
+        "bbox":[4125.20975228551, 2891.197731325369, 1284.1407784475177, 1194.5171451638166]
+      },
+      "BGR":{
+        "shape":[5771, 5633, 5712, 5629, 5729, 5663, 5720, 5702, 5595, 5724, 5530, 5689, 5510, 5701, 5471, 5653, 5403, 5657, 5395, 5675, 5375, 5669, 5328, 5690, 5208, 5693, 5219, 5669, 5203, 5579, 5136, 5524, 5129, 5492, 5164, 5477, 5168, 5446, 5149, 5436, 5139, 5395, 5223, 5317, 5212, 5289, 5152, 5251, 5135, 5205, 5147, 5143, 5168, 5135, 5191, 5125, 5230, 5139, 5209, 5156, 5221, 5209, 5287, 5201, 5423, 5247, 5474, 5226, 5526, 5227, 5542, 5211, 5631, 5233, 5723, 5162, 5814, 5133, 5952, 5 [...]
+        "center":[5571, 5494],
+        "bbox":[5129.232082632858, 5125.1319587597245, 935.3882194296975, 598.6716356123197]
+      },
+      "AUT":{
+        "shape":[3906, 4522, 3740, 4470, 3746, 4445, 3691, 4421, 3708, 4391, 3630, 4388, 3601, 4373, 3541, 4380, 3515, 4414, 3447, 4372, 3430, 4366, 3392, 4388, 3360, 4364, 3361, 4349, 3326, 4332, 3307, 4332, 3311, 4319, 3310, 4292, 3331, 4243, 3324, 4222, 3393, 4232, 3394, 4269, 3429, 4303, 3467, 4243, 3495, 4269, 3522, 4270, 3524, 4297, 3559, 4288, 3583, 4307, 3641, 4257, 3682, 4270, 3684, 4296, 3707, 4293, 3724, 4240, 3778, 4281, 3794, 4272, 3809, 4305, 3831, 4317, 3844, 4281, 3809, 4 [...]
+        "center":[4039, 4327],
+        "bbox":[3306.7960818268534, 4030.330354614745, 1120.9192080324506, 535.9448476680086]
+      },
+      "MLT":{
+        "shape":[[3736, 6748, 3748, 6760, 3767, 6769, 3764, 6786, 3755, 6779, 3752, 6791, 3731, 6773, 3730, 6756, 3736, 6748], [3739, 6737, 3721, 6749, 3709, 6749, 3707, 6742, 3726, 6734, 3739, 6737]],
+        "center":[3746, 6768],
+        "bbox":[3707.4715195221124, 6734.165836062014, 59.36645800496353, 57.23872478245994]
+      },
+      "EST":{
+        "shape":[5438, 2320, 5462, 2214, 5441, 2218, 5430, 2241, 5406, 2251, 5387, 2224, 5367, 2232, 5338, 2176, 5343, 2154, 5384, 2147, 5379, 2137, 5332, 2135, 5332, 2121, 5356, 2105, 5338, 2103, 5342, 2055, 5416, 2047, 5403, 2030, 5432, 2035, 5450, 2013, 5494, 2016, 5493, 2001, 5574, 2001, 5569, 1982, 5639, 1982, 5756, 2022, 5846, 2025, 5882, 2002, 5901, 2019, 5786, 2125, 5824, 2262, 5851, 2276, 5845, 2307, 5821, 2317, 5813, 2366, 5816, 2386, 5761, 2370, 5701, 2381, 5650, 2327, 5628, 2 [...]
+        "center":[5205, 2223],
+        "bbox":[5331.720299407905, 1981.7815042379805, 569.1402990904235, 404.1030001827992]
+      },
+      "SMR":{
+        "shape":[3651, 5031, 3650, 5044, 3637, 5040, 3651, 5031],
+        "center":[3646, 5038],
+        "bbox":[3637.05981541583, 5030.740291942945, 13.528132310848378, 13.136060398236623]
+      },
+      "SVK":{
+        "shape":[4428, 4125, 4463, 4095, 4498, 4097, 4552, 4056, 4588, 4055, 4648, 3957, 4687, 3959, 4692, 3977, 4707, 3996, 4751, 3958, 4765, 3965, 4810, 4040, 4898, 4006, 4941, 4031, 5001, 3995, 5033, 4011, 5058, 4000, 5074, 4026, 5092, 4015, 5121, 4046, 5221, 4086, 5179, 4092, 5139, 4211, 5141, 4229, 5072, 4227, 5033, 4180, 4999, 4196, 4928, 4188, 4855, 4256, 4783, 4240, 4761, 4279, 4673, 4278, 4657, 4287, 4653, 4318, 4572, 4331, 4465, 4285, 4424, 4265, 4408, 4246, 4413, 4150, 4428, 4125],
+        "center":[4741, 4137],
+        "bbox":[4407.83981523998, 3956.772757012294, 813.2710587450783, 374.41971220439837]
+      },
+      "BEL":{
+        "shape":[2969, 3625, 2953, 3603, 2927, 3620, 2910, 3649, 2923, 3690, 2909, 3713, 2850, 3717, 2796, 3656, 2779, 3631, 2811, 3583, 2712, 3600, 2712, 3560, 2690, 3553, 2706, 3538, 2703, 3510, 2651, 3510, 2623, 3463, 2599, 3455, 2606, 3422, 2534, 3382, 2540, 3342, 2529, 3334, 2559, 3318, 2617, 3302, 2735, 3347, 2758, 3339, 2765, 3313, 2799, 3335, 2837, 3314, 2855, 3337, 2874, 3328, 2888, 3369, 2951, 3401, 2957, 3422, 2916, 3462, 2917, 3476, 2942, 3478, 2953, 3485, 3005, 3497, 2988, 3 [...]
+        "center":[2795, 3484],
+        "bbox":[2528.8666671894866, 3302.470316085842, 482.64382707647155, 414.66110518932646]
+      },
+      "SVN":{
+        "shape":[4241, 4490, 4263, 4493, 4280, 4505, 4296, 4559, 4284, 4559, 4260, 4575, 4184, 4580, 4145, 4613, 4127, 4638, 4154, 4650, 4155, 4669, 4107, 4706, 4093, 4744, 4010, 4718, 3976, 4692, 3954, 4736, 3932, 4738, 3895, 4734, 3901, 4700, 3876, 4666, 3892, 4631, 3852, 4628, 3843, 4597, 3868, 4546, 3896, 4545, 3906, 4522, 4039, 4566, 4112, 4523, 4183, 4546, 4195, 4514, 4223, 4524, 4230, 4491, 4241, 4490],
+        "center":[4080, 4607],
+        "bbox":[3843.3595868900625, 4490.202871474261, 452.52741994551025, 254.29095413254345]
+      },
+      "UKR":{
+        "shape":[7418, 4353, 7388, 4385, 7403, 4352, 7382, 4347, 7326, 4370, 7290, 4421, 7295, 4402, 7240, 4436, 7240, 4464, 7223, 4478, 7212, 4442, 7195, 4447, 7167, 4464, 7163, 4483, 7126, 4475, 7095, 4489, 7044, 4539, 7014, 4496, 7010, 4514, 7036, 4554, 7026, 4567, 6999, 4540, 6978, 4582, 6927, 4616, 6918, 4638, 6916, 4615, 6877, 4614, 6860, 4599, 6849, 4630, 6818, 4610, 6753, 4650, 6713, 4631, 6618, 4660, 6512, 4626, 6540, 4608, 6533, 4579, 6597, 4576, 6586, 4559, 6533, 4539, 6544, 4 [...]
+        "center":[6444, 3959],
+        "bbox":[5139.1720020515395, 3353.778422406775, 2479.6090356365567, 1541.8815363612298]
+      },
+      "BIH":{
+        "shape":[4401, 5324, 4392, 5326, 4410, 5280, 4279, 5141, 4252, 5066, 4193, 5029, 4195, 5000, 4160, 4920, 4170, 4826, 4189, 4816, 4213, 4843, 4245, 4819, 4350, 4789, 4376, 4812, 4431, 4800, 4445, 4836, 4588, 4876, 4615, 4921, 4647, 4919, 4672, 4918, 4699, 4921, 4698, 4945, 4650, 5017, 4698, 5066, 4710, 5101, 4698, 5122, 4672, 5126, 4685, 5177, 4616, 5222, 4613, 5264, 4588, 5260, 4542, 5333, 4539, 5397, 4517, 5417, 4451, 5328, 4401, 5324],
+        "center":[4469, 5084],
+        "bbox":[4160.4317047646655, 4788.749355574284, 549.84387953638, 628.1454411247769]
+      },
+      "ESP":{
+        "shape":[1979, 5036, 2046, 5073, 2086, 5072, 2127, 5105, 2164, 5088, 2185, 5095, 2196, 5113, 2163, 5151, 2171, 5201, 1981, 5292, 1770, 5312, 1746, 5339, 1754, 5365, 1730, 5381, 1711, 5373, 1586, 5463, 1496, 5582, 1501, 5655, 1511, 5685, 1547, 5716, 1547, 5744, 1462, 5752, 1427, 5799, 1408, 5797, 1330, 5903, 1328, 5925, 1347, 5924, 1313, 5937, 1209, 5927, 1149, 5962, 1136, 5990, 1063, 6042, 1037, 5998, 970, 6018, 941, 5991, 853, 5988, 842, 5966, 805, 5952, 691, 5929, 648, 5959, 58 [...]
+        "center":[1070, 5273],
+        "bbox":[279.7614742316311, 4353.690131167325, 1916.3857020823036, 1688.0946359019763]
+      }
+    }
+}
diff --git a/dojox/geo/charting/resources/data/EuropeMiddleEastAfrica.json b/dojox/geo/charting/resources/data/EuropeMiddleEastAfrica.json
new file mode 100644
index 0000000..03da99d
--- /dev/null
+++ b/dojox/geo/charting/resources/data/EuropeMiddleEastAfrica.json
@@ -0,0 +1,562 @@
+{
+  "layerExtent":[0.0, 0.0, 7564.261870579342, 6533.245837506976],
+    "layerExtentLL":[-17.601753, 78.910986, 197.600524, 113.771025],
+    "featureNames":["ROM", "UGA", "DJI", "KGZ", "MOZ", "YEM", "NOR", "COG", "ZAR", "SYR", "RWA", "FIN", "TCD", "UZB", "ARE", "HRV", "MWI", "ARM", "TUN", "AZE", "TUR", "POL", "GEO", "GNQ", "NGA", "TJK", "KEN", "GNB", "PAK", "MDG", "YUG", "EGY", "HUN", "BLR", "LIE", "MDA", "BDI", "ALB", "SAU", "CMR", "TKM", "MLI", "GMB", "OMN", "BFA", "KWT", "JOR", "ZMB", "BEN", "UKR", "BEL", "NAM", "ESH", "CAF", "PRT", "TZA", "ISR", "MKD", "KAZ", "SDN", "SLE", "LSO", "GHA", "DNK", "DEU", "AND", "ITA", "LB [...]
+    "features":{
+      "ROM":{
+        "shape":[1764, 3238, 1705, 3224, 1658, 3248, 1605, 3252, 1554, 3243, 1556, 3225, 1546, 3222, 1546, 3220, 1533, 3192, 1524, 3206, 1492, 3188, 1497, 3159, 1470, 3148, 1472, 3132, 1456, 3120, 1448, 3111, 1471, 3114, 1495, 3090, 1517, 3037, 1555, 3002, 1563, 3000, 1617, 3008, 1630, 3023, 1687, 2995, 1695, 2991, 1712, 3000, 1759, 3076, 1760, 3149, 1761, 3159, 1772, 3165, 1795, 3149, 1809, 3157, 1810, 3162, 1798, 3186, 1779, 3175, 1764, 3238],
+        "center":[1637, 3127],
+        "bbox":[1448.0447083380604, 2990.701022912484, 362.15286811433293, 261.27025144600884]
+      },
+      "UGA":{
+        "shape":[1844, 5148, 1827, 5167, 1817, 5160, 1806, 5165, 1812, 5130, 1824, 5077, 1879, 5032, 1878, 5024, 1853, 5015, 1862, 4977, 1857, 4970, 1869, 4962, 1956, 4965, 1979, 4944, 1985, 4949, 1989, 4964, 1998, 4966, 1994, 4980, 2001, 4996, 2015, 5008, 2020, 5040, 1978, 5101, 1978, 5149, 1863, 5149, 1854, 5145, 1844, 5148],
+        "center":[1916, 5056],
+        "bbox":[1806.1715188952226, 4943.681525485032, 213.92425867635643, 223.74584538746694]
+      },
+      "DJI":{
+        "shape":[2328, 4619, 2342, 4646, 2307, 4667, 2331, 4663, 2335, 4668, 2322, 4683, 2281, 4682, 2278, 4656, 2301, 4629, 2308, 4625, 2314, 4631, 2328, 4619],
+        "center":[2317, 4650],
+        "bbox":[2277.9472130157174, 4619.247910385003, 63.56176506561178, 64.20110939181814]
+      },
+      "KGZ":{
+        "shape":[3332, 3429, 3340, 3420, 3329, 3413, 3334, 3397, 3347, 3405, 3369, 3390, 3386, 3363, 3367, 3355, 3402, 3319, 3388, 3320, 3408, 3296, 3432, 3292, 3487, 3309, 3488, 3292, 3512, 3268, 3586, 3286, 3632, 3279, 3753, 3311, 3754, 3337, 3737, 3331, 3727, 3345, 3721, 3339, 3688, 3355, 3673, 3382, 3622, 3385, 3596, 3417, 3579, 3421, 3572, 3403, 3556, 3415, 3546, 3411, 3514, 3434, 3510, 3455, 3490, 3459, 3483, 3470, 3425, 3474, 3415, 3453, 3387, 3465, 3376, 3453, 3334, 3457, 3332, 3429],
+        "center":[3502, 3379],
+        "bbox":[3329.4066865064874, 3268.338007137479, 424.3910575327818, 205.47890613501977]
+      },
+      "MOZ":{
+        "shape":[1836, 5714, 1830, 5693, 1939, 5654, 1943, 5649, 1967, 5673, 1995, 5675, 1998, 5716, 1986, 5728, 2017, 5761, 2018, 5772, 2027, 5772, 2023, 5751, 2029, 5735, 2046, 5732, 2050, 5722, 2054, 5678, 2028, 5647, 1999, 5632, 1993, 5584, 2004, 5560, 2019, 5557, 2040, 5555, 2052, 5546, 2076, 5560, 2110, 5557, 2127, 5543, 2179, 5541, 2222, 5511, 2228, 5523, 2234, 5529, 2222, 5560, 2222, 5592, 2232, 5608, 2224, 5616, 2233, 5621, 2227, 5663, 2236, 5665, 2232, 5678, 2241, 5681, 2228, 5 [...]
+        "center":[2059, 5797],
+        "bbox":[1829.6925220001026, 5510.788592504243, 411.5445269865695, 664.2816381531075]
+      },
+      "YEM":{
+        "shape":[2313, 4467, 2328, 4457, 2324, 4444, 2333, 4425, 2359, 4433, 2379, 4426, 2444, 4454, 2449, 4479, 2456, 4480, 2549, 4393, 2612, 4380, 2668, 4364, 2708, 4459, 2696, 4462, 2677, 4471, 2676, 4500, 2635, 4520, 2560, 4541, 2537, 4563, 2512, 4563, 2489, 4579, 2427, 4588, 2390, 4615, 2354, 4621, 2337, 4616, 2327, 4591, 2329, 4571, 2308, 4516, 2314, 4518, 2313, 4467],
+        "center":[2468, 4521],
+        "bbox":[2308.035083198681, 4364.326605867121, 400.44893148408664, 256.2922563617458]
+      },
+      "NOR":{
+        "shape":[859, 2076, 878, 2062, 868, 2049, 880, 2058, 896, 2030, 925, 2026, 913, 2013, 960, 2008, 939, 2000, 943, 1977, 964, 1981, 1039, 1929, 1054, 1948, 1087, 1938, 1107, 1913, 1102, 1889, 1066, 1929, 1035, 1912, 1064, 1900, 1057, 1881, 1091, 1842, 1112, 1848, 1122, 1819, 1089, 1807, 1116, 1812, 1139, 1786, 1194, 1621, 1236, 1592, 1268, 1600, 1257, 1581, 1222, 1584, 1240, 1561, 1269, 1572, 1256, 1555, 1275, 1542, 1237, 1548, 1238, 1528, 1279, 1520, 1258, 1506, 1285, 1485, 1304,  [...]
+        "center":[1029, 2109],
+        "bbox":[859.0739363656576, 1169.2132117715387, 1002.2463129907705, 1197.1765326252425]
+      },
+      "COG":{
+        "shape":[1096, 5258, 1116, 5241, 1132, 5247, 1132, 5225, 1118, 5212, 1120, 5194, 1146, 5200, 1153, 5176, 1174, 5198, 1194, 5200, 1199, 5190, 1213, 5203, 1230, 5181, 1232, 5129, 1211, 5118, 1210, 5096, 1227, 5074, 1226, 5062, 1219, 5054, 1187, 5055, 1177, 5036, 1188, 5031, 1186, 5024, 1227, 5027, 1235, 5020, 1243, 5030, 1265, 5029, 1289, 5041, 1286, 5030, 1293, 5024, 1309, 4999, 1311, 4971, 1385, 4968, 1389, 4985, 1359, 5070, 1362, 5099, 1350, 5139, 1320, 5159, 1297, 5193, 1298, 5 [...]
+        "center":[1285, 5124],
+        "bbox":[1096.319007677384, 4967.501813772162, 292.45688307226396, 332.4845145263298]
+      },
+      "ZAR":{
+        "shape":[1143, 5331, 1156, 5328, 1152, 5300, 1171, 5287, 1178, 5284, 1189, 5294, 1223, 5274, 1229, 5290, 1239, 5291, 1256, 5272, 1263, 5276, 1281, 5261, 1298, 5233, 1297, 5193, 1320, 5159, 1350, 5139, 1362, 5099, 1359, 5070, 1389, 4985, 1385, 4968, 1381, 4960, 1382, 4942, 1405, 4918, 1429, 4913, 1460, 4936, 1527, 4947, 1542, 4929, 1596, 4928, 1611, 4919, 1636, 4924, 1651, 4909, 1667, 4916, 1711, 4907, 1720, 4910, 1726, 4919, 1752, 4947, 1781, 4930, 1792, 4943, 1803, 4927, 1816, 4 [...]
+        "center":[1573, 5248],
+        "bbox":[1143.1271499347465, 4906.612701209182, 735.4811731190282, 720.3223393702829]
+      },
+      "SYR":{
+        "shape":[2050, 3692, 2042, 3637, 2048, 3631, 2064, 3634, 2076, 3615, 2077, 3588, 2107, 3602, 2142, 3587, 2176, 3601, 2231, 3580, 2293, 3571, 2298, 3580, 2260, 3607, 2241, 3705, 2159, 3751, 2087, 3800, 2056, 3789, 2038, 3780, 2040, 3773, 2041, 3763, 2043, 3753, 2050, 3750, 2053, 3732, 2074, 3710, 2069, 3693, 2050, 3692],
+        "center":[2154, 3671],
+        "bbox":[2038.0664869993295, 3570.5992797763183, 260.3946548245292, 228.9885484737879]
+      },
+      "RWA":{
+        "shape":[1806, 5165, 1817, 5160, 1827, 5167, 1844, 5148, 1859, 5172, 1861, 5189, 1851, 5203, 1844, 5202, 1823, 5195, 1820, 5212, 1810, 5217, 1798, 5204, 1787, 5210, 1782, 5206, 1793, 5199, 1806, 5165],
+        "center":[1820, 5183],
+        "bbox":[1782.1536974389896, 5147.895817515238, 79.08005517545325, 68.92244099377695]
+      },
+      "FIN":{
+        "shape":[1463, 1402, 1481, 1403, 1487, 1370, 1529, 1440, 1585, 1425, 1630, 1451, 1662, 1413, 1689, 1305, 1743, 1290, 1797, 1357, 1781, 1404, 1774, 1410, 1772, 1502, 1825, 1551, 1790, 1625, 1828, 1739, 1813, 1745, 1807, 1808, 1843, 1882, 1823, 1912, 1888, 1981, 1738, 2178, 1733, 2181, 1662, 2189, 1607, 2222, 1593, 2213, 1559, 2229, 1556, 2189, 1538, 2197, 1493, 2173, 1501, 2099, 1481, 1991, 1503, 1972, 1497, 1957, 1528, 1952, 1525, 1934, 1577, 1888, 1615, 1814, 1650, 1807, 1645, 1 [...]
+        "center":[1702, 1912],
+        "bbox":[1463.1517173325421, 1290.2267153286166, 424.72320394617464, 939.2513382677894]
+      },
+      "TCD":{
+        "shape":[1249, 4204, 1290, 4187, 1594, 4344, 1590, 4494, 1556, 4499, 1548, 4510, 1553, 4515, 1530, 4547, 1536, 4559, 1521, 4574, 1528, 4595, 1511, 4612, 1512, 4618, 1525, 4613, 1534, 4619, 1537, 4657, 1554, 4665, 1554, 4678, 1549, 4689, 1543, 4682, 1514, 4687, 1474, 4740, 1455, 4752, 1400, 4764, 1408, 4775, 1399, 4789, 1350, 4798, 1314, 4816, 1304, 4805, 1277, 4823, 1271, 4816, 1266, 4808, 1252, 4770, 1234, 4764, 1210, 4733, 1219, 4722, 1265, 4721, 1252, 4685, 1244, 4618, 1224, 4 [...]
+        "center":[1383, 4636],
+        "bbox":[1187.9850918927768, 4186.567624778508, 405.85726937632876, 636.1298533782465]
+      },
+      "UZB":{
+        "shape":[2820, 3367, 2817, 3174, 2917, 3141, 3048, 3251, 3164, 3241, 3213, 3289, 3206, 3336, 3227, 3338, 3238, 3375, 3278, 3372, 3279, 3383, 3302, 3388, 3388, 3320, 3402, 3319, 3367, 3355, 3386, 3363, 3369, 3390, 3347, 3405, 3334, 3397, 3329, 3413, 3340, 3420, 3332, 3429, 3328, 3427, 3286, 3460, 3261, 3457, 3253, 3471, 3291, 3491, 3282, 3509, 3291, 3528, 3273, 3558, 3270, 3571, 3251, 3575, 3241, 3567, 3225, 3567, 3226, 3551, 3229, 3529, 3130, 3484, 3072, 3433, 3069, 3406, 3047, 3 [...]
+        "center":[3138, 3385],
+        "bbox":[2817.205169307209, 3141.2163704672744, 585.2558908823235, 434.20004627313756]
+      },
+      "ARE":{
+        "shape":[2830, 4088, 2834, 4091, 2836, 4114, 2811, 4114, 2807, 4122, 2810, 4148, 2822, 4149, 2826, 4163, 2804, 4158, 2791, 4207, 2795, 4221, 2780, 4228, 2668, 4205, 2652, 4162, 2627, 4143, 2635, 4137, 2673, 4163, 2690, 4154, 2746, 4156, 2825, 4071, 2830, 4088],
+        "center":[2741, 4178],
+        "bbox":[2627.4670349517146, 4070.8807713323413, 208.0831035668498, 157.57107184130746]
+      },
+      "HRV":{
+        "shape":[1347, 3283, 1321, 3259, 1285, 3253, 1251, 3217, 1274, 3216, 1245, 3193, 1239, 3165, 1224, 3155, 1208, 3183, 1192, 3148, 1196, 3145, 1205, 3145, 1215, 3145, 1225, 3132, 1257, 3142, 1271, 3121, 1267, 3107, 1302, 3089, 1305, 3089, 1350, 3127, 1399, 3127, 1400, 3133, 1417, 3156, 1408, 3167, 1404, 3176, 1346, 3149, 1279, 3161, 1290, 3213, 1350, 3271, 1347, 3283],
+        "center":[1299, 3124],
+        "bbox":[1192.2171924353331, 3088.6313431920244, 224.827064075796, 193.88421152132014]
+      },
+      "MWI":{
+        "shape":[2019, 5557, 2004, 5560, 1993, 5584, 1999, 5632, 2028, 5647, 2054, 5678, 2050, 5722, 2046, 5732, 2029, 5735, 2023, 5751, 2027, 5772, 2018, 5772, 2017, 5761, 1986, 5728, 1998, 5716, 1995, 5675, 1967, 5673, 1943, 5649, 1941, 5644, 1929, 5636, 1943, 5622, 1943, 5599, 1960, 5589, 1953, 5579, 1954, 5528, 1965, 5528, 1973, 5517, 1944, 5482, 1938, 5472, 1990, 5482, 2004, 5502, 2005, 5540, 2019, 5557],
+        "center":[1977, 5627],
+        "bbox":[1928.9666401711718, 5472.374356591678, 124.55040267337995, 299.5648550487631]
+      },
+      "ARM":{
+        "shape":[2386, 3456, 2382, 3448, 2381, 3441, 2345, 3427, 2349, 3394, 2336, 3376, 2381, 3372, 2390, 3368, 2434, 3424, 2421, 3434, 2455, 3459, 2456, 3495, 2449, 3495, 2444, 3497, 2431, 3463, 2386, 3456],
+        "center":[2405, 3429],
+        "bbox":[2335.752598385609, 3367.920802487782, 120.67586503090115, 129.46574141121027]
+      },
+      "TUN":{
+        "shape":[1014, 3587, 1053, 3568, 1038, 3579, 1058, 3570, 1074, 3598, 1097, 3579, 1101, 3589, 1073, 3623, 1097, 3652, 1099, 3669, 1058, 3712, 1057, 3726, 1084, 3740, 1084, 3750, 1100, 3745, 1098, 3759, 1107, 3763, 1117, 3765, 1118, 3795, 1067, 3832, 1066, 3872, 1058, 3884, 1040, 3891, 1021, 3807, 993, 3789, 993, 3775, 958, 3732, 990, 3690, 993, 3613, 984, 3606, 1005, 3588, 1014, 3587],
+        "center":[1028, 3689],
+        "bbox":[957.8131087657723, 3568.48669367804, 160.31050111974923, 322.48180105551046]
+      },
+      "AZE":{
+        "shape":[[2456, 3495, 2455, 3459, 2421, 3434, 2434, 3424, 2390, 3368, 2398, 3363, 2454, 3375, 2460, 3364, 2443, 3352, 2443, 3340, 2452, 3341, 2489, 3372, 2528, 3342, 2536, 3350, 2567, 3401, 2600, 3419, 2582, 3415, 2566, 3426, 2553, 3481, 2541, 3473, 2538, 3491, 2541, 3512, 2513, 3491, 2525, 3480, 2511, 3455, 2456, 3495], [2386, 3456, 2431, 3463, 2444, 3497, 2433, 3494, 2393, 3469, 2386, 3456]],
+        "center":[2414, 3469],
+        "bbox":[2386.049550152722, 3340.078146740808, 214.34348815915246, 172.08961453333768]
+      },
+      "TUR":{
+        "shape":[[1915, 3343, 2009, 3329, 2032, 3353, 2051, 3351, 2064, 3373, 2075, 3365, 2106, 3384, 2142, 3389, 2183, 3380, 2217, 3387, 2257, 3364, 2260, 3359, 2297, 3364, 2310, 3353, 2327, 3362, 2323, 3372, 2336, 3376, 2349, 3394, 2345, 3427, 2381, 3441, 2382, 3448, 2378, 3457, 2363, 3471, 2376, 3522, 2367, 3539, 2389, 3572, 2377, 3579, 2369, 3569, 2331, 3564, 2311, 3564, 2305, 3576, 2298, 3580, 2293, 3571, 2231, 3580, 2176, 3601, 2142, 3587, 2107, 3602, 2077, 3588, 2076, 3615, 2064,  [...]
+        "center":[2000, 3466],
+        "bbox":[1667.721649216479, 3328.880046144092, 721.7614342942124, 304.9937090214735]
+      },
+      "POL":{
+        "shape":[1550, 2615, 1573, 2628, 1572, 2647, 1575, 2665, 1592, 2721, 1560, 2751, 1584, 2764, 1578, 2794, 1578, 2800, 1598, 2836, 1596, 2858, 1546, 2910, 1552, 2939, 1547, 2945, 1502, 2922, 1434, 2936, 1420, 2916, 1400, 2920, 1399, 2915, 1388, 2892, 1360, 2890, 1354, 2873, 1321, 2863, 1325, 2880, 1312, 2882, 1304, 2855, 1263, 2840, 1258, 2833, 1250, 2823, 1237, 2732, 1222, 2719, 1221, 2662, 1231, 2667, 1236, 2680, 1240, 2643, 1360, 2589, 1377, 2589, 1390, 2620, 1410, 2619, 1401, 2 [...]
+        "center":[1405, 2771],
+        "bbox":[1220.596386181846, 2588.5035662441464, 377.43241739934547, 356.26071529496994]
+      },
+      "GEO":{
+        "shape":[2260, 3359, 2274, 3343, 2262, 3298, 2207, 3256, 2204, 3253, 2277, 3271, 2315, 3267, 2347, 3289, 2350, 3303, 2405, 3293, 2424, 3306, 2419, 3324, 2442, 3333, 2443, 3340, 2443, 3352, 2460, 3364, 2454, 3375, 2398, 3363, 2390, 3368, 2381, 3372, 2336, 3376, 2323, 3372, 2327, 3362, 2310, 3353, 2297, 3364, 2260, 3359],
+        "center":[2335, 3320],
+        "bbox":[2203.5008872847848, 3252.640010363692, 256.8613274642398, 123.30218153008491]
+      },
+      "GNQ":{
+        "shape":[1052, 5016, 1069, 5025, 1106, 5025, 1110, 5068, 1042, 5069, 1033, 5065, 1052, 5016],
+        "center":[1064, 5043],
+        "bbox":[1032.8822540722035, 5016.095500528349, 77.28554901169446, 52.702351929443466]
+      },
+      "NGA":{
+        "shape":[1212, 4602, 1215, 4630, 1229, 4638, 1239, 4658, 1217, 4678, 1208, 4673, 1191, 4699, 1182, 4734, 1165, 4747, 1162, 4772, 1143, 4783, 1128, 4833, 1101, 4858, 1082, 4832, 1065, 4842, 1061, 4833, 1007, 4885, 1008, 4912, 996, 4928, 987, 4922, 982, 4935, 943, 4927, 941, 4940, 931, 4933, 915, 4943, 894, 4937, 874, 4903, 882, 4905, 881, 4896, 868, 4895, 841, 4863, 806, 4861, 819, 4852, 799, 4862, 776, 4862, 773, 4803, 779, 4760, 792, 4754, 806, 4725, 806, 4707, 816, 4701, 807, 4 [...]
+        "center":[963, 4769],
+        "bbox":[772.6793552090106, 4570.24539742332, 466.0294917777495, 373.14368515905153]
+      },
+      "TJK":{
+        "shape":[3525, 3557, 3511, 3565, 3508, 3556, 3482, 3556, 3430, 3593, 3417, 3581, 3424, 3535, 3412, 3533, 3417, 3521, 3385, 3505, 3364, 3530, 3362, 3550, 3338, 3551, 3333, 3570, 3309, 3570, 3287, 3587, 3270, 3571, 3273, 3558, 3291, 3528, 3282, 3509, 3291, 3491, 3253, 3471, 3261, 3457, 3286, 3460, 3328, 3427, 3332, 3429, 3334, 3457, 3376, 3453, 3387, 3465, 3415, 3453, 3425, 3474, 3483, 3470, 3494, 3476, 3508, 3510, 3526, 3505, 3546, 3515, 3547, 3554, 3557, 3559, 3552, 3566, 3531, 3 [...]
+        "center":[3412, 3489],
+        "bbox":[3253.447399355298, 3426.689873449722, 303.37393918648604, 165.9983504365582]
+      },
+      "KEN":{
+        "shape":[2180, 5288, 2119, 5243, 2123, 5224, 1978, 5149, 1978, 5101, 2020, 5040, 2015, 5008, 2001, 4996, 1994, 4980, 1998, 4966, 1989, 4964, 1985, 4949, 1979, 4944, 1989, 4933, 2049, 4933, 2089, 4938, 2138, 4968, 2193, 4978, 2209, 4952, 2235, 4947, 2245, 4955, 2285, 4955, 2247, 5002, 2247, 5143, 2270, 5174, 2259, 5186, 2240, 5186, 2243, 5198, 2216, 5212, 2216, 5238, 2209, 5236, 2203, 5262, 2187, 5289, 2180, 5288],
+        "center":[2143, 5092],
+        "bbox":[1977.9441508407676, 4932.540831183743, 306.6262166851311, 356.62664815341395]
+      },
+      "GNB":{
+        "shape":[28, 4631, 84, 4627, 99, 4619, 168, 4618, 136, 4633, 146, 4648, 142, 4657, 116, 4657, 97, 4682, 95, 4691, 90, 4680, 98, 4670, 85, 4681, 75, 4666, 80, 4664, 75, 4656, 96, 4644, 63, 4652, 60, 4644, 50, 4648, 42, 4640, 48, 4632, 38, 4638, 28, 4631],
+        "center":[103, 4644],
+        "bbox":[27.623186401638723, 4618.3589734699835, 140.8532741761942, 72.17447374106814]
+      },
+      "PAK":{
+        "shape":[3282, 4170, 3264, 4162, 3254, 4123, 3236, 4121, 3234, 4103, 3220, 4088, 3154, 4108, 3136, 4096, 3110, 4107, 3071, 4105, 3063, 4114, 3058, 4107, 3046, 4115, 3045, 4107, 3039, 4106, 3036, 4092, 3052, 4062, 3096, 4050, 3104, 4027, 3084, 4025, 3078, 3981, 3044, 3961, 3025, 3934, 3010, 3908, 3068, 3933, 3132, 3930, 3155, 3920, 3169, 3926, 3218, 3908, 3216, 3868, 3241, 3842, 3255, 3849, 3271, 3843, 3294, 3820, 3325, 3832, 3337, 3820, 3333, 3795, 3342, 3765, 3376, 3747, 3357, 3 [...]
+        "center":[3311, 3923],
+        "bbox":[3010.347660507705, 3580.7545997502552, 621.6886628721459, 589.5333914561202]
+      },
+      "MDG":{
+        "shape":[2342, 5947, 2352, 5945, 2381, 5891, 2360, 5792, 2381, 5756, 2380, 5743, 2422, 5739, 2427, 5728, 2443, 5732, 2448, 5725, 2457, 5736, 2453, 5722, 2474, 5703, 2476, 5717, 2490, 5712, 2481, 5706, 2491, 5687, 2496, 5682, 2499, 5689, 2494, 5700, 2510, 5680, 2519, 5683, 2505, 5673, 2518, 5664, 2512, 5640, 2522, 5641, 2525, 5651, 2547, 5632, 2549, 5597, 2568, 5577, 2566, 5587, 2590, 5615, 2613, 5702, 2600, 5734, 2589, 5711, 2580, 5719, 2589, 5753, 2573, 5784, 2574, 5806, 2508, 6 [...]
+        "center":[2470, 5885],
+        "bbox":[2333.4963674491482, 5577.353558878146, 279.4795799953058, 547.8333551782416]
+      },
+      "YUG":{
+        "shape":[1532, 3314, 1492, 3328, 1479, 3321, 1464, 3333, 1460, 3339, 1460, 3333, 1446, 3304, 1432, 3306, 1430, 3297, 1414, 3337, 1409, 3336, 1390, 3304, 1372, 3304, 1347, 3283, 1349, 3282, 1385, 3298, 1384, 3282, 1423, 3221, 1406, 3200, 1418, 3181, 1410, 3175, 1404, 3176, 1408, 3167, 1417, 3156, 1400, 3133, 1399, 3127, 1410, 3118, 1442, 3110, 1448, 3111, 1456, 3120, 1472, 3132, 1470, 3148, 1497, 3159, 1492, 3188, 1524, 3206, 1533, 3192, 1546, 3220, 1546, 3222, 1540, 3225, 1532, 3 [...]
+        "center":[1484, 3249],
+        "bbox":[1346.5303279115426, 3110.137445573903, 208.29038375687833, 228.45639986115657]
+      },
+      "EGY":{
+        "shape":[1640, 3834, 1708, 3842, 1785, 3867, 1834, 3852, 1841, 3841, 1863, 3843, 1868, 3834, 1897, 3840, 1911, 3866, 1914, 3850, 1930, 3860, 1963, 3858, 1996, 3836, 2000, 3831, 1992, 3860, 2017, 3924, 2010, 3932, 1988, 4002, 1950, 3965, 1950, 3946, 1938, 3939, 1925, 3905, 1914, 3921, 1937, 3968, 1961, 3994, 1960, 4011, 1976, 4031, 2023, 4145, 2047, 4166, 2035, 4165, 2036, 4183, 2039, 4200, 2026, 4214, 2019, 4210, 2005, 4232, 1987, 4235, 1974, 4254, 1888, 4242, 1880, 4234, 1872, 4 [...]
+        "center":[1801, 4042],
+        "bbox":[1622.290332835458, 3830.822705478281, 424.4125311020605, 422.80287407024025]
+      },
+      "HUN":{
+        "shape":[1305, 3089, 1295, 3072, 1289, 3072, 1307, 3060, 1314, 3023, 1330, 3021, 1333, 3006, 1344, 3011, 1395, 3016, 1429, 2993, 1449, 2996, 1468, 2976, 1497, 2973, 1526, 2985, 1539, 2993, 1549, 2999, 1555, 3002, 1517, 3037, 1495, 3090, 1471, 3114, 1448, 3111, 1442, 3110, 1410, 3118, 1399, 3127, 1350, 3127, 1305, 3089],
+        "center":[1406, 3051],
+        "bbox":[1289.044431813633, 2972.672519890462, 266.37127846327485, 154.72296220371982]
+      },
+      "BLR":{
+        "shape":[1891, 2758, 1861, 2760, 1839, 2806, 1802, 2806, 1792, 2793, 1778, 2808, 1755, 2793, 1736, 2803, 1665, 2772, 1583, 2789, 1578, 2794, 1584, 2764, 1560, 2751, 1592, 2721, 1575, 2665, 1572, 2647, 1609, 2649, 1640, 2622, 1655, 2633, 1664, 2579, 1694, 2564, 1691, 2539, 1698, 2533, 1728, 2525, 1754, 2497, 1757, 2500, 1789, 2501, 1799, 2525, 1836, 2512, 1858, 2542, 1847, 2581, 1885, 2649, 1925, 2666, 1911, 2688, 1888, 2683, 1866, 2696, 1891, 2758],
+        "center":[1740, 2677],
+        "bbox":[1560.133903144479, 2496.585156831425, 364.74118293156107, 310.91645508759893]
+      },
+      "LIE":{
+        "shape":[1037, 3053, 1042, 3061, 1037, 3061, 1038, 3058, 1037, 3053],
+        "center":[1039, 3056],
+        "bbox":[1036.7143179413795, 3053.0872929511956, 4.794544531485371, 8.397327484593006]
+      },
+      "MDA":{
+        "shape":[1760, 3149, 1759, 3076, 1712, 3000, 1695, 2991, 1702, 2982, 1778, 2996, 1793, 3009, 1790, 3034, 1807, 3045, 1808, 3065, 1820, 3071, 1820, 3094, 1789, 3088, 1760, 3149],
+        "center":[1768, 3062],
+        "bbox":[1694.5097547591154, 2981.773182077048, 125.94508732978329, 167.2834940697162]
+      },
+      "BDI":{
+        "shape":[1787, 5210, 1798, 5204, 1810, 5217, 1820, 5212, 1823, 5195, 1844, 5202, 1846, 5206, 1845, 5223, 1856, 5228, 1857, 5240, 1829, 5274, 1801, 5285, 1799, 5269, 1792, 5255, 1798, 5224, 1787, 5210],
+        "center":[1823, 5231],
+        "bbox":[1787.3530768462092, 5194.9030555849595, 69.17034721887035, 89.68710008108792]
+      },
+      "ALB":{
+        "shape":[1414, 3337, 1430, 3297, 1432, 3306, 1446, 3304, 1460, 3333, 1460, 3339, 1469, 3386, 1479, 3390, 1467, 3423, 1452, 3428, 1452, 3447, 1440, 3450, 1441, 3444, 1413, 3413, 1420, 3413, 1414, 3396, 1425, 3384, 1423, 3341, 1414, 3337],
+        "center":[1443, 3383],
+        "bbox":[1412.74289805954, 3297.030826881797, 66.4398796053631, 152.9284775565634]
+      },
+      "SAU":{
+        "shape":[2016, 3930, 2056, 3939, 2084, 3907, 2104, 3906, 2130, 3874, 2088, 3837, 2166, 3817, 2177, 3806, 2208, 3813, 2316, 3870, 2321, 3885, 2346, 3886, 2341, 3920, 2389, 3940, 2460, 3941, 2493, 3947, 2506, 3963, 2526, 3958, 2530, 3969, 2545, 4003, 2590, 4044, 2597, 4064, 2588, 4075, 2625, 4138, 2627, 4143, 2652, 4162, 2668, 4205, 2780, 4228, 2795, 4221, 2807, 4245, 2783, 4325, 2668, 4364, 2612, 4380, 2549, 4393, 2456, 4480, 2449, 4479, 2444, 4454, 2379, 4426, 2359, 4433, 2333, 4 [...]
+        "center":[2389, 4165],
+        "bbox":[2001.2196495113064, 3806.040915534255, 806.055521683177, 674.0173843786079]
+      },
+      "CMR":{
+        "shape":[996, 4928, 1008, 4912, 1007, 4885, 1061, 4833, 1065, 4842, 1082, 4832, 1101, 4858, 1128, 4833, 1143, 4783, 1162, 4772, 1165, 4747, 1182, 4734, 1191, 4699, 1208, 4673, 1217, 4678, 1239, 4658, 1229, 4638, 1215, 4630, 1212, 4602, 1224, 4601, 1244, 4618, 1252, 4685, 1265, 4721, 1219, 4722, 1210, 4733, 1234, 4764, 1252, 4770, 1266, 4808, 1271, 4816, 1227, 4872, 1235, 4884, 1226, 4906, 1237, 4910, 1239, 4931, 1254, 4941, 1251, 4962, 1290, 4994, 1287, 5015, 1293, 5024, 1286, 50 [...]
+        "center":[1145, 4909],
+        "bbox":[996.3277411455267, 4601.465083930142, 296.61411121732726, 439.6375552991967]
+      },
+      "TKM":{
+        "shape":[2741, 3566, 2740, 3486, 2723, 3466, 2709, 3466, 2701, 3390, 2704, 3398, 2729, 3392, 2732, 3403, 2758, 3399, 2754, 3389, 2770, 3384, 2733, 3325, 2707, 3328, 2694, 3342, 2701, 3380, 2687, 3348, 2684, 3343, 2704, 3321, 2740, 3311, 2775, 3325, 2794, 3368, 2820, 3367, 2858, 3372, 2854, 3340, 2864, 3327, 2895, 3319, 2896, 3308, 2914, 3312, 2906, 3301, 2922, 3291, 2953, 3318, 2975, 3320, 2977, 3363, 3025, 3374, 3034, 3363, 3047, 3375, 3069, 3406, 3072, 3433, 3130, 3484, 3229, 3 [...]
+        "center":[2897, 3457],
+        "bbox":[2683.6748556203825, 3291.2642052832944, 544.9819750170759, 376.1797530776371]
+      },
+      "MLI":{
+        "shape":[482, 4119, 719, 4286, 718, 4296, 743, 4314, 794, 4333, 791, 4361, 802, 4369, 835, 4360, 835, 4445, 820, 4494, 804, 4512, 720, 4514, 710, 4523, 680, 4525, 643, 4524, 632, 4535, 600, 4540, 579, 4562, 561, 4563, 557, 4581, 544, 4578, 545, 4595, 538, 4595, 537, 4602, 519, 4588, 502, 4598, 508, 4616, 497, 4615, 490, 4644, 464, 4650, 469, 4661, 462, 4681, 459, 4702, 447, 4705, 436, 4717, 434, 4693, 414, 4698, 406, 4716, 389, 4715, 385, 4705, 373, 4715, 366, 4716, 361, 4708, 34 [...]
+        "center":[576, 4427],
+        "bbox":[202.6525712991455, 4118.212821343584, 632.6840770734641, 598.384547120304]
+      },
+      "GMB":{
+        "shape":[58, 4583, 96, 4573, 119, 4579, 120, 4586, 141, 4586, 127, 4598, 91, 4583, 65, 4591, 65, 4599, 25, 4602, 25, 4592, 69, 4588, 39, 4593, 34, 4583, 58, 4583],
+        "center":[76, 4584],
+        "bbox":[25.282438250621222, 4573.347316903808, 116.01881158928757, 28.315418536751167]
+      },
+      "OMN":{
+        "shape":[2668, 4364, 2783, 4325, 2807, 4245, 2795, 4221, 2791, 4207, 2804, 4158, 2826, 4163, 2822, 4149, 2810, 4148, 2807, 4122, 2811, 4114, 2836, 4114, 2838, 4124, 2858, 4157, 2886, 4173, 2919, 4175, 2969, 4230, 2923, 4289, 2916, 4309, 2903, 4298, 2886, 4337, 2892, 4364, 2854, 4373, 2835, 4410, 2800, 4410, 2786, 4443, 2752, 4443, 2718, 4455, 2708, 4459, 2668, 4364],
+        "center":[2847, 4296],
+        "bbox":[2667.9398502903227, 4114.220716985133, 301.3109273403311, 345.1168365365138]
+      },
+      "BFA":{
+        "shape":[678, 4682, 659, 4678, 647, 4688, 642, 4682, 567, 4682, 561, 4698, 567, 4707, 569, 4738, 561, 4746, 554, 4732, 524, 4727, 510, 4730, 503, 4743, 486, 4744, 471, 4715, 457, 4713, 459, 4702, 462, 4681, 469, 4661, 464, 4650, 490, 4644, 497, 4615, 508, 4616, 502, 4598, 519, 4588, 537, 4602, 538, 4595, 545, 4595, 544, 4578, 557, 4581, 561, 4563, 579, 4562, 600, 4540, 632, 4535, 643, 4524, 680, 4525, 681, 4547, 690, 4553, 690, 4567, 710, 4581, 709, 4600, 732, 4621, 748, 4613, 75 [...]
+        "center":[609, 4627],
+        "bbox":[456.6367847456494, 4523.8364096586365, 308.9680836994778, 222.6453249619226]
+      },
+      "KWT":{
+        "shape":[2510, 3901, 2517, 3919, 2501, 3930, 2515, 3934, 2524, 3952, 2526, 3958, 2506, 3963, 2493, 3947, 2460, 3941, 2486, 3900, 2510, 3901],
+        "center":[2504, 3929],
+        "bbox":[2460.144036399838, 3900.3631597764766, 66.25564369659469, 62.90912347907033]
+      },
+      "JOR":{
+        "shape":[2159, 3751, 2177, 3806, 2166, 3817, 2088, 3837, 2130, 3874, 2104, 3906, 2084, 3907, 2056, 3939, 2016, 3930, 2017, 3924, 2030, 3844, 2010, 3841, 2017, 3801, 2039, 3794, 2038, 3780, 2056, 3789, 2087, 3800, 2159, 3751],
+        "center":[2060, 3851],
+        "bbox":[2010.4238495890454, 3750.888785449857, 166.3436058400148, 188.55325808991165]
+      },
+      "ZMB":{
+        "shape":[1576, 5791, 1563, 5784, 1516, 5734, 1517, 5610, 1599, 5612, 1592, 5601, 1597, 5537, 1585, 5530, 1599, 5527, 1611, 5533, 1611, 5550, 1646, 5537, 1647, 5557, 1674, 5567, 1697, 5570, 1716, 5558, 1732, 5579, 1758, 5594, 1763, 5590, 1785, 5625, 1809, 5617, 1810, 5627, 1816, 5624, 1818, 5580, 1804, 5581, 1800, 5591, 1766, 5563, 1778, 5484, 1768, 5464, 1788, 5437, 1854, 5427, 1857, 5437, 1927, 5471, 1938, 5472, 1944, 5482, 1973, 5517, 1965, 5528, 1954, 5528, 1953, 5579, 1960, 5 [...]
+        "center":[1691, 5674],
+        "bbox":[1516.1859305803964, 5427.456232696501, 456.97809185255005, 376.9875508846899]
+      },
+      "BEN":{
+        "shape":[736, 4865, 733, 4758, 720, 4737, 724, 4726, 703, 4711, 703, 4681, 724, 4661, 766, 4652, 762, 4646, 767, 4640, 764, 4634, 780, 4626, 811, 4644, 811, 4650, 807, 4671, 816, 4701, 806, 4707, 806, 4725, 792, 4754, 779, 4760, 773, 4803, 776, 4862, 761, 4865, 736, 4865],
+        "center":[758, 4717],
+        "bbox":[702.5097554541861, 4626.1371392015, 113.63317980548868, 239.23978946159787]
+      },
+      "UKR":{
+        "shape":[[2138, 3054, 2113, 3055, 2082, 3080, 2076, 3071, 2033, 3091, 2027, 3079, 2031, 3095, 2021, 3090, 1997, 3113, 1983, 3102, 1918, 3112, 1891, 3101, 1898, 3089, 1915, 3089, 1898, 3078, 1903, 3064, 1893, 3081, 1882, 3081, 1883, 3070, 1851, 3085, 1847, 3070, 1845, 3104, 1827, 3096, 1834, 3120, 1807, 3129, 1812, 3150, 1809, 3157, 1795, 3149, 1772, 3165, 1761, 3159, 1760, 3149, 1789, 3088, 1820, 3094, 1820, 3071, 1808, 3065, 1807, 3045, 1790, 3034, 1793, 3009, 1778, 2996, 1702,  [...]
+        "center":[1886, 2917],
+        "bbox":[1525.7462358083942, 2743.1330603266765, 684.7371332480532, 462.69215914948563]
+      },
+      "BEL":{
+        "shape":[912, 2885, 900, 2886, 903, 2906, 900, 2913, 885, 2917, 867, 2903, 866, 2882, 840, 2893, 832, 2868, 818, 2871, 773, 2829, 781, 2822, 796, 2814, 831, 2819, 837, 2807, 869, 2804, 894, 2821, 896, 2844, 900, 2845, 915, 2846, 921, 2871, 912, 2885],
+        "center":[856, 2855],
+        "bbox":[773.2926214130065, 2804.4367870612186, 148.17877362465458, 112.8328912927027]
+      },
+      "NAM":{
+        "shape":[1641, 5795, 1636, 5802, 1607, 5806, 1581, 5826, 1572, 5809, 1482, 5821, 1479, 5969, 1439, 5968, 1439, 6084, 1439, 6240, 1408, 6251, 1404, 6261, 1374, 6260, 1343, 6254, 1341, 6232, 1320, 6226, 1301, 6247, 1275, 6228, 1246, 6153, 1243, 6087, 1228, 6060, 1226, 6030, 1228, 6020, 1241, 6023, 1238, 6002, 1187, 5925, 1182, 5901, 1126, 5798, 1124, 5778, 1135, 5772, 1154, 5779, 1178, 5768, 1210, 5785, 1373, 5783, 1399, 5802, 1472, 5811, 1576, 5791, 1608, 5786, 1641, 5795],
+        "center":[1324, 5990],
+        "bbox":[1123.6643932243533, 5767.553267390125, 517.2368970623659, 493.79793676275676]
+      },
+      "ESH":{
+        "shape":[165, 4005, 339, 4005, 339, 4017, 335, 4079, 206, 4080, 205, 4184, 168, 4197, 161, 4219, 171, 4273, 16, 4272, 18, 4253, 65, 4163, 100, 4128, 113, 4071, 138, 4056, 165, 4005],
+        "center":[134, 4134],
+        "bbox":[16.452540989692103, 4005.15426392403, 322.7044548580135, 268.24894629563414]
+      },
+      "CAF":{
+        "shape":[1293, 5024, 1287, 5015, 1290, 4994, 1251, 4962, 1254, 4941, 1239, 4931, 1237, 4910, 1226, 4906, 1235, 4884, 1227, 4872, 1271, 4816, 1277, 4823, 1304, 4805, 1314, 4816, 1350, 4798, 1399, 4789, 1408, 4775, 1400, 4764, 1455, 4752, 1474, 4740, 1514, 4687, 1543, 4682, 1549, 4689, 1559, 4699, 1580, 4730, 1576, 4772, 1602, 4770, 1601, 4790, 1638, 4803, 1652, 4830, 1680, 4849, 1689, 4876, 1716, 4891, 1720, 4910, 1711, 4907, 1667, 4916, 1651, 4909, 1636, 4924, 1611, 4919, 1596, 4 [...]
+        "center":[1479, 4854],
+        "bbox":[1226.372238402814, 4682.064297307367, 493.8500714905756, 341.86758749966884]
+      },
+      "PRT":{
+        "shape":[337, 3336, 360, 3328, 364, 3345, 411, 3336, 431, 3354, 405, 3386, 402, 3452, 387, 3454, 403, 3484, 393, 3568, 388, 3571, 328, 3578, 342, 3515, 337, 3505, 322, 3508, 329, 3487, 311, 3493, 313, 3464, 324, 3458, 344, 3400, 337, 3336],
+        "center":[359, 3464],
+        "bbox":[310.6604075180408, 3328.2997864083063, 120.83560428774126, 249.9566497271594]
+      },
+      "TZA":{
+        "shape":[1846, 5206, 1844, 5202, 1851, 5203, 1861, 5189, 1859, 5172, 1844, 5148, 1854, 5145, 1863, 5149, 1978, 5149, 2123, 5224, 2119, 5243, 2180, 5288, 2179, 5305, 2167, 5341, 2169, 5357, 2196, 5383, 2184, 5404, 2190, 5415, 2182, 5439, 2191, 5454, 2185, 5459, 2198, 5472, 2199, 5504, 2203, 5498, 2205, 5507, 2219, 5507, 2222, 5511, 2179, 5541, 2127, 5543, 2110, 5557, 2076, 5560, 2052, 5546, 2040, 5555, 2019, 5557, 2005, 5540, 2004, 5502, 1990, 5482, 1938, 5472, 1927, 5471, 1857, 5 [...]
+        "center":[2031, 5400],
+        "bbox":[1800.189365489639, 5145.3986544224645, 421.44657503266853, 415.0131619919157]
+      },
+      "ISR":{
+        "shape":[2017, 3924, 1992, 3860, 2000, 3831, 2002, 3819, 2016, 3772, 2019, 3766, 2043, 3753, 2041, 3763, 2040, 3773, 2038, 3780, 2039, 3794, 2017, 3801, 2010, 3841, 2030, 3844, 2017, 3924],
+        "center":[2009, 3812],
+        "bbox":[1992.262072731238, 3752.993797704061, 50.695353178704636, 170.78949534485128]
+      },
+      "MKD":{
+        "shape":[1532, 3314, 1556, 3357, 1553, 3362, 1551, 3362, 1547, 3372, 1522, 3371, 1479, 3390, 1469, 3386, 1460, 3339, 1464, 3333, 1479, 3321, 1492, 3328, 1532, 3314],
+        "center":[1507, 3355],
+        "bbox":[1460.2220651506912, 3314.0773121664547, 95.49679253861223, 75.48626616218371]
+      },
+      "KAZ":{
+        "shape":[2684, 3343, 2679, 3326, 2695, 3297, 2661, 3288, 2649, 3271, 2634, 3273, 2637, 3253, 2593, 3204, 2607, 3193, 2647, 3200, 2622, 3183, 2642, 3157, 2717, 3157, 2695, 3143, 2705, 3069, 2682, 3066, 2673, 3076, 2636, 3057, 2604, 3068, 2581, 3094, 2556, 3094, 2552, 3100, 2521, 3086, 2546, 3078, 2539, 3047, 2512, 3023, 2483, 3023, 2478, 2995, 2455, 2980, 2478, 2940, 2468, 2924, 2490, 2866, 2531, 2901, 2545, 2889, 2533, 2853, 2606, 2807, 2619, 2786, 2641, 2800, 2670, 2789, 2720, 2 [...]
+        "center":[3279, 2961],
+        "bbox":[2454.6529133795393, 2546.7252095332256, 1566.9561292608414, 841.6807755817795]
+      },
+      "SDN":{
+        "shape":[2039, 4200, 2049, 4217, 2089, 4244, 2109, 4378, 2143, 4399, 2154, 4406, 2141, 4426, 2096, 4447, 2075, 4522, 2076, 4546, 2077, 4558, 2073, 4573, 2057, 4614, 2041, 4618, 2022, 4653, 2018, 4687, 2013, 4694, 1998, 4690, 1989, 4700, 1983, 4776, 1976, 4787, 1949, 4785, 1943, 4803, 1968, 4809, 1988, 4837, 2014, 4854, 2021, 4897, 2030, 4906, 2045, 4904, 2045, 4921, 2049, 4933, 1989, 4933, 1979, 4944, 1956, 4965, 1869, 4962, 1857, 4970, 1849, 4967, 1816, 4932, 1803, 4927, 1792, 4 [...]
+        "center":[1814, 4567],
+        "bbox":[1510.5335728993846, 4200.465714721312, 643.0121323321414, 769.7486648510894]
+      },
+      "SLE":{
+        "shape":[160, 4756, 182, 4749, 195, 4725, 240, 4723, 265, 4769, 259, 4773, 262, 4795, 278, 4782, 277, 4785, 277, 4795, 265, 4800, 261, 4817, 234, 4843, 219, 4834, 177, 4816, 200, 4815, 180, 4810, 171, 4789, 164, 4791, 159, 4783, 176, 4779, 163, 4777, 161, 4769, 175, 4768, 160, 4756],
+        "center":[212, 4779],
+        "bbox":[159.02008591898283, 4723.219016811895, 118.51060628974199, 119.82281780882477]
+      },
+      "LSO":{
+        "shape":[1712, 6293, 1752, 6249, 1773, 6248, 1805, 6276, 1785, 6318, 1758, 6321, 1745, 6338, 1718, 6313, 1712, 6293],
+        "center":[1757, 6288],
+        "bbox":[1711.5024270209606, 6248.41163581753, 93.15660381925932, 90.01272696392789]
+      },
+      "GHA":{
+        "shape":[558, 4914, 569, 4915, 570, 4890, 554, 4890, 543, 4847, 558, 4827, 557, 4803, 574, 4789, 572, 4750, 569, 4738, 567, 4707, 561, 4698, 567, 4682, 642, 4682, 647, 4688, 659, 4678, 678, 4682, 676, 4691, 673, 4699, 689, 4713, 680, 4743, 691, 4742, 694, 4764, 686, 4773, 702, 4785, 694, 4793, 694, 4844, 714, 4873, 705, 4878, 701, 4886, 609, 4916, 591, 4929, 558, 4914],
+        "center":[633, 4804],
+        "bbox":[543.4004186681001, 4678.169620124963, 170.1335832347322, 250.40842307121238]
+      },
+      "DNK":{
+        "shape":[984, 2500, 984, 2467, 1005, 2480, 1020, 2453, 1031, 2476, 1026, 2443, 1069, 2442, 1065, 2466, 1093, 2483, 1045, 2531, 1044, 2583, 1038, 2588, 1005, 2585, 1006, 2576, 1006, 2549, 985, 2540, 994, 2516, 984, 2500],
+        "center":[1031, 2508],
+        "bbox":[983.5915907700571, 2442.1073570688723, 109.25085034438985, 145.69287447328043]
+      },
+      "DEU":{
+        "shape":[900, 2845, 915, 2810, 909, 2782, 947, 2758, 931, 2736, 947, 2727, 954, 2692, 956, 2692, 948, 2669, 981, 2662, 988, 2682, 1006, 2652, 1057, 2673, 1016, 2648, 1019, 2623, 1004, 2623, 1021, 2614, 1009, 2596, 1005, 2585, 1038, 2588, 1042, 2591, 1054, 2591, 1053, 2615, 1080, 2624, 1107, 2609, 1090, 2649, 1171, 2620, 1216, 2661, 1221, 2662, 1222, 2719, 1237, 2732, 1250, 2823, 1258, 2833, 1247, 2841, 1228, 2829, 1227, 2841, 1145, 2879, 1131, 2874, 1155, 2895, 1158, 2920, 1180,  [...]
+        "center":[1064, 2813],
+        "bbox":[899.7442310818631, 2584.912531355995, 358.634512947403, 463.69861974727246]
+      },
+      "AND":{
+        "shape":[739, 3301, 739, 3308, 739, 3308, 728, 3305, 730, 3301, 733, 3299, 739, 3301],
+        "center":[733, 3306],
+        "bbox":[728.3847609372136, 3298.5982683395437, 10.855814484402345, 9.730668307314772]
+      },
+      "ITA":{
+        "shape":[[1164, 3529, 1220, 3534, 1266, 3519, 1251, 3557, 1260, 3577, 1253, 3594, 1153, 3547, 1164, 3529], [986, 3393, 1027, 3370, 1044, 3399, 1039, 3474, 1015, 3466, 1012, 3488, 993, 3477, 1000, 3436, 986, 3393], [960, 3241, 968, 3215, 936, 3212, 943, 3187, 932, 3170, 946, 3151, 936, 3128, 956, 3128, 961, 3123, 994, 3094, 1019, 3130, 1029, 3093, 1063, 3106, 1059, 3090, 1074, 3090, 1075, 3068, 1076, 3066, 1095, 3075, 1116, 3060, 1145, 3061, 1156, 3081, 1202, 3089, 1200, 3096, 118 [...]
+        "center":[1174, 3303],
+        "bbox":[931.686746332528, 3060.3922655608867, 448.63992964563727, 533.5242981279944]
+      },
+      "LBN":{
+        "shape":[2050, 3692, 2069, 3693, 2074, 3710, 2053, 3732, 2050, 3750, 2043, 3753, 2019, 3766, 2020, 3761, 2050, 3692],
+        "center":[2045, 3727],
+        "bbox":[2018.6250317253953, 3692.072464028862, 55.48339969623976, 73.54589895018671]
+      },
+      "LBR":{
+        "shape":[234, 4843, 261, 4817, 265, 4800, 277, 4795, 277, 4785, 301, 4783, 307, 4802, 302, 4825, 323, 4830, 345, 4814, 344, 4824, 347, 4846, 339, 4859, 370, 4867, 368, 4879, 385, 4891, 375, 4924, 380, 4942, 375, 4941, 309, 4911, 275, 4871, 234, 4843],
+        "center":[316, 4859],
+        "bbox":[234.11819257235743, 4782.881155876532, 151.3458884106684, 158.64127537395234]
+      },
+      "GIN":{
+        "shape":[97, 4682, 116, 4657, 142, 4657, 146, 4648, 136, 4633, 168, 4618, 174, 4623, 195, 4632, 229, 4621, 235, 4613, 232, 4636, 240, 4642, 252, 4636, 265, 4648, 280, 4636, 295, 4642, 310, 4633, 304, 4628, 309, 4622, 321, 4624, 333, 4644, 329, 4651, 353, 4668, 346, 4677, 361, 4708, 366, 4716, 368, 4767, 377, 4776, 372, 4783, 358, 4779, 355, 4790, 367, 4795, 357, 4817, 345, 4814, 323, 4830, 302, 4825, 307, 4802, 301, 4783, 277, 4785, 278, 4782, 262, 4795, 259, 4773, 265, 4769, 240 [...]
+        "center":[269, 4691],
+        "bbox":[97.44886478236074, 4613.026427809991, 279.57278991726594, 217.1811622445348]
+      },
+      "LBY":{
+        "shape":[1117, 3765, 1151, 3781, 1185, 3778, 1253, 3798, 1280, 3846, 1339, 3857, 1410, 3893, 1423, 3891, 1446, 3863, 1439, 3827, 1447, 3805, 1502, 3774, 1551, 3784, 1568, 3808, 1623, 3815, 1635, 3826, 1640, 3831, 1622, 3894, 1632, 3934, 1633, 4244, 1631, 4324, 1594, 4325, 1594, 4344, 1290, 4187, 1249, 4204, 1216, 4218, 1165, 4188, 1133, 4179, 1114, 4149, 1071, 4138, 1034, 4066, 1053, 4042, 1056, 3995, 1049, 3933, 1034, 3897, 1040, 3891, 1058, 3884, 1066, 3872, 1067, 3832, 1118, 3 [...]
+        "center":[1357, 4029],
+        "bbox":[1033.7528588419068, 3765.157993752304, 605.7924551562776, 579.0150433650751]
+      },
+      "IRQ":{
+        "shape":[2159, 3751, 2241, 3705, 2260, 3607, 2298, 3580, 2305, 3576, 2311, 3564, 2331, 3564, 2369, 3569, 2377, 3579, 2389, 3572, 2410, 3632, 2453, 3639, 2437, 3651, 2441, 3665, 2414, 3704, 2423, 3740, 2441, 3753, 2436, 3768, 2490, 3791, 2506, 3827, 2500, 3855, 2532, 3900, 2526, 3901, 2515, 3899, 2510, 3901, 2486, 3900, 2460, 3941, 2389, 3940, 2341, 3920, 2346, 3886, 2321, 3885, 2316, 3870, 2208, 3813, 2177, 3806, 2159, 3751],
+        "center":[2323, 3757],
+        "bbox":[2159.056666559315, 3563.773697069969, 372.95411313286695, 377.52204480699174]
+      },
+      "ETH":{
+        "shape":[2301, 4629, 2278, 4656, 2281, 4682, 2322, 4683, 2312, 4701, 2339, 4746, 2362, 4763, 2484, 4802, 2516, 4801, 2398, 4923, 2364, 4919, 2330, 4931, 2321, 4944, 2295, 4948, 2285, 4955, 2245, 4955, 2235, 4947, 2209, 4952, 2193, 4978, 2138, 4968, 2089, 4938, 2049, 4933, 2045, 4921, 2045, 4904, 2030, 4906, 2021, 4897, 2014, 4854, 1988, 4837, 1968, 4809, 1943, 4803, 1949, 4785, 1976, 4787, 1983, 4776, 1989, 4700, 1998, 4690, 2013, 4694, 2018, 4687, 2022, 4653, 2041, 4618, 2057, 4 [...]
+        "center":[2187, 4786],
+        "bbox":[1943.3711448700371, 4537.34935241698, 572.3359026552314, 440.4261979508883]
+      },
+      "IRN":{
+        "shape":[2389, 3572, 2367, 3539, 2376, 3522, 2363, 3471, 2378, 3457, 2382, 3448, 2386, 3456, 2393, 3469, 2433, 3494, 2444, 3497, 2449, 3495, 2456, 3495, 2511, 3455, 2525, 3480, 2513, 3491, 2541, 3512, 2546, 3534, 2554, 3554, 2594, 3563, 2616, 3588, 2647, 3600, 2731, 3586, 2721, 3592, 2727, 3595, 2746, 3588, 2741, 3575, 2741, 3566, 2769, 3565, 2799, 3530, 2873, 3521, 2879, 3537, 2907, 3552, 2946, 3557, 2994, 3603, 3019, 3600, 3018, 3630, 3022, 3637, 3017, 3686, 2993, 3717, 3007, 3 [...]
+        "center":[2778, 3791],
+        "bbox":[2362.687511706993, 3448.1186881954786, 740.8459721661443, 665.7786772875265]
+      },
+      "SEN":{
+        "shape":[36, 4480, 45, 4463, 100, 4458, 131, 4465, 142, 4479, 160, 4480, 163, 4500, 180, 4505, 195, 4530, 203, 4532, 203, 4548, 211, 4593, 222, 4591, 235, 4613, 229, 4621, 195, 4632, 174, 4623, 168, 4618, 99, 4619, 84, 4627, 28, 4631, 26, 4626, 73, 4623, 77, 4614, 25, 4621, 26, 4608, 25, 4602, 65, 4599, 65, 4591, 91, 4583, 127, 4598, 141, 4586, 120, 4586, 119, 4579, 96, 4573, 58, 4583, 34, 4583, 38, 4572, 28, 4570, 36, 4559, 25, 4567, 0, 4535, 16, 4527, 36, 4480],
+        "center":[106, 4526],
+        "bbox":[0.0, 4457.881266832332, 234.9383193926334, 174.11893138000323]
+      },
+      "GIB":{
+        "shape":[466, 3625, 466, 3625, 471, 3619, 471, 3620, 466, 3625],
+        "center":[468, 3622],
+        "bbox":[465.99969128330946, 3619.007159911756, 4.744669046927697, 6.179740366193073]
+      },
+      "IRL":{
+        "shape":[397, 2574, 365, 2614, 367, 2620, 388, 2636, 407, 2617, 433, 2637, 435, 2637, 445, 2707, 435, 2759, 384, 2766, 320, 2803, 300, 2804, 312, 2788, 288, 2796, 303, 2781, 279, 2782, 296, 2763, 273, 2762, 303, 2755, 306, 2735, 341, 2728, 294, 2736, 332, 2694, 286, 2680, 306, 2657, 290, 2630, 346, 2629, 362, 2607, 339, 2596, 359, 2566, 381, 2560, 382, 2580, 398, 2555, 407, 2563, 397, 2574],
+        "center":[374, 2695],
+        "bbox":[273.3101675983047, 2555.0834628677076, 172.03823288660618, 249.28877438605923]
+      },
+      "BWA":{
+        "shape":[1636, 5802, 1674, 5845, 1684, 5871, 1717, 5893, 1723, 5908, 1741, 5911, 1748, 5950, 1787, 5957, 1796, 5973, 1801, 5978, 1771, 5993, 1758, 5991, 1720, 6026, 1699, 6063, 1674, 6083, 1652, 6126, 1641, 6130, 1596, 6123, 1575, 6105, 1557, 6105, 1534, 6146, 1524, 6147, 1505, 6173, 1469, 6174, 1473, 6134, 1455, 6094, 1439, 6084, 1439, 5968, 1479, 5969, 1482, 5821, 1572, 5809, 1581, 5826, 1607, 5806, 1636, 5802],
+        "center":[1597, 5970],
+        "bbox":[1439.462969171497, 5801.891613294166, 361.1800308483098, 371.69448819025547]
+      },
+      "GAB":{
+        "shape":[1106, 5025, 1107, 5017, 1184, 5017, 1186, 5024, 1188, 5031, 1177, 5036, 1187, 5055, 1219, 5054, 1226, 5062, 1227, 5074, 1210, 5096, 1211, 5118, 1232, 5129, 1230, 5181, 1213, 5203, 1199, 5190, 1194, 5200, 1174, 5198, 1153, 5176, 1146, 5200, 1120, 5194, 1118, 5212, 1132, 5225, 1132, 5247, 1116, 5241, 1096, 5258, 1092, 5250, 1048, 5207, 1064, 5205, 1042, 5202, 1030, 5183, 1041, 5184, 1029, 5178, 1038, 5171, 1030, 5167, 1033, 5159, 1025, 5165, 1016, 5159, 1005, 5135, 1017, 5 [...]
+        "center":[1115, 5136],
+        "bbox":[1005.1811345363682, 5016.562045020007, 227.11785202063368, 241.10035159498238]
+      },
+      "BGR":{
+        "shape":[1691, 3348, 1677, 3346, 1679, 3364, 1648, 3369, 1618, 3352, 1553, 3362, 1556, 3357, 1532, 3314, 1541, 3310, 1534, 3290, 1555, 3270, 1532, 3243, 1540, 3225, 1546, 3222, 1556, 3225, 1554, 3243, 1605, 3252, 1658, 3248, 1705, 3224, 1764, 3238, 1765, 3244, 1763, 3259, 1741, 3266, 1741, 3294, 1722, 3305, 1741, 3325, 1743, 3334, 1727, 3339, 1716, 3329, 1689, 3339, 1691, 3348],
+        "center":[1642, 3313],
+        "bbox":[1531.8889622391646, 3222.187993200291, 233.42315252062167, 146.8556316715103]
+      },
+      "AUT":{
+        "shape":[1202, 3089, 1156, 3081, 1145, 3061, 1116, 3060, 1095, 3075, 1076, 3066, 1071, 3065, 1062, 3073, 1042, 3061, 1037, 3061, 1038, 3058, 1036, 3051, 1040, 3037, 1037, 3032, 1056, 3031, 1068, 3049, 1076, 3031, 1109, 3044, 1123, 3028, 1141, 3035, 1144, 3020, 1175, 3037, 1171, 2997, 1202, 2973, 1203, 2966, 1218, 2977, 1237, 2972, 1251, 2949, 1331, 2968, 1327, 2975, 1328, 3001, 1333, 3006, 1330, 3021, 1314, 3023, 1307, 3060, 1289, 3072, 1286, 3072, 1275, 3088, 1256, 3084, 1238, 3 [...]
+        "center":[1231, 3033],
+        "bbox":[1036.2412539191687, 2948.527277114319, 296.5373507379659, 148.6611328191384]
+      },
+      "EST":{
+        "shape":[[1516, 2300, 1539, 2289, 1554, 2304, 1538, 2316, 1516, 2300], [1517, 2376, 1510, 2331, 1548, 2321, 1564, 2333, 1525, 2353, 1517, 2376], [1603, 2378, 1611, 2338, 1580, 2345, 1571, 2277, 1645, 2248, 1706, 2264, 1747, 2258, 1753, 2265, 1715, 2305, 1720, 2324, 1735, 2363, 1722, 2396, 1723, 2403, 1686, 2400, 1651, 2369, 1603, 2381, 1603, 2378]],
+        "center":[1528, 2343],
+        "bbox":[1510.2097964443576, 2247.902289971312, 243.13674202471475, 155.22782776440226]
+      },
+      "MRT":{
+        "shape":[339, 4017, 482, 4119, 417, 4118, 452, 4466, 467, 4473, 458, 4506, 313, 4507, 313, 4500, 305, 4500, 304, 4510, 262, 4499, 250, 4516, 228, 4497, 228, 4505, 217, 4504, 213, 4534, 203, 4532, 195, 4530, 180, 4505, 163, 4500, 160, 4480, 142, 4479, 131, 4465, 100, 4458, 45, 4463, 36, 4480, 37, 4460, 55, 4413, 37, 4354, 48, 4317, 15, 4278, 16, 4272, 171, 4273, 161, 4219, 168, 4197, 205, 4184, 206, 4080, 335, 4079, 339, 4017],
+        "center":[259, 4351],
+        "bbox":[15.123417421057209, 4016.9122265173773, 466.84038797556, 516.8163550668178]
+      },
+      "ESP":{
+        "shape":[739, 3308, 793, 3310, 795, 3336, 755, 3368, 706, 3385, 706, 3399, 672, 3431, 659, 3464, 681, 3497, 653, 3517, 646, 3549, 616, 3558, 591, 3592, 582, 3585, 569, 3593, 501, 3593, 471, 3619, 471, 3619, 466, 3625, 466, 3625, 443, 3617, 423, 3579, 398, 3570, 393, 3568, 403, 3484, 387, 3454, 402, 3452, 405, 3386, 431, 3354, 411, 3336, 364, 3345, 360, 3328, 337, 3336, 333, 3330, 342, 3318, 334, 3318, 339, 3299, 327, 3300, 333, 3290, 319, 3279, 334, 3265, 358, 3265, 357, 3250, 37 [...]
+        "center":[540, 3422],
+        "bbox":[319.01823052047337, 3241.0236270146893, 475.9099371549547, 384.1713635057936]
+      },
+      "SWZ":{
+        "shape":[1902, 6192, 1878, 6195, 1852, 6168, 1870, 6129, 1897, 6136, 1902, 6131, 1902, 6192],
+        "center":[1882, 6164],
+        "bbox":[1852.227290113531, 6129.336692077841, 49.713120275315305, 65.53741950568201]
+      },
+      "ZAF":{
+        "shape":[[1712, 6293, 1718, 6313, 1745, 6338, 1758, 6321, 1785, 6318, 1805, 6276, 1773, 6248, 1752, 6249, 1712, 6293], [1301, 6247, 1320, 6226, 1341, 6232, 1343, 6254, 1374, 6260, 1404, 6261, 1408, 6251, 1439, 6240, 1439, 6084, 1455, 6094, 1473, 6134, 1469, 6174, 1505, 6173, 1524, 6147, 1534, 6146, 1557, 6105, 1575, 6105, 1596, 6123, 1641, 6130, 1652, 6126, 1674, 6083, 1699, 6063, 1720, 6026, 1758, 5991, 1771, 5993, 1801, 5978, 1811, 5975, 1831, 5983, 1861, 5981, 1880, 5987, 1901 [...]
+        "center":[1592, 6300],
+        "bbox":[1300.845750360985, 5974.702292209944, 634.2456767736362, 558.5435452970323]
+      },
+      "DZA":{
+        "shape":[587, 3678, 637, 3641, 677, 3635, 700, 3611, 772, 3601, 785, 3588, 845, 3583, 876, 3598, 914, 3576, 939, 3585, 950, 3576, 991, 3588, 1005, 3588, 984, 3606, 993, 3613, 990, 3690, 958, 3732, 993, 3775, 993, 3789, 1021, 3807, 1040, 3891, 1034, 3897, 1049, 3933, 1056, 3995, 1053, 4042, 1034, 4066, 1071, 4138, 1114, 4149, 1133, 4179, 986, 4275, 891, 4343, 835, 4360, 802, 4369, 791, 4361, 794, 4333, 743, 4314, 718, 4296, 719, 4286, 482, 4119, 339, 4017, 339, 4005, 339, 3966, 35 [...]
+        "center":[780, 3983],
+        "bbox":[338.7457705410335, 3575.714550784429, 793.8204499463524, 793.7460025017581]
+      },
+      "GRC":{
+        "shape":[[1671, 3677, 1620, 3680, 1605, 3666, 1575, 3664, 1576, 3652, 1581, 3644, 1605, 3659, 1656, 3659, 1656, 3669, 1679, 3668, 1671, 3677], [1513, 3521, 1553, 3538, 1571, 3556, 1562, 3563, 1543, 3553, 1560, 3608, 1542, 3591, 1531, 3606, 1520, 3577, 1511, 3595, 1504, 3592, 1503, 3559, 1483, 3537, 1513, 3521], [1479, 3390, 1522, 3371, 1547, 3372, 1551, 3362, 1553, 3362, 1618, 3352, 1648, 3369, 1679, 3364, 1677, 3346, 1691, 3348, 1695, 3351, 1698, 3365, 1668, 3400, 1666, 3395, 16 [...]
+        "center":[1505, 3455],
+        "bbox":[1439.8965349574557, 3346.268731474653, 257.8689829899072, 333.6593317802517]
+      },
+      "FRA":{
+        "shape":[[730, 3301, 711, 3283, 659, 3296, 606, 3260, 615, 3256, 633, 3191, 630, 3146, 649, 3172, 646, 3152, 624, 3137, 629, 3102, 600, 3082, 596, 3048, 577, 3051, 583, 3038, 539, 3019, 505, 3020, 494, 3006, 507, 2998, 497, 2992, 515, 2994, 489, 2986, 498, 2972, 550, 2960, 574, 2978, 599, 2967, 619, 2973, 601, 2908, 624, 2907, 626, 2928, 687, 2928, 684, 2912, 737, 2881, 735, 2841, 764, 2832, 773, 2829, 818, 2871, 832, 2868, 840, 2893, 866, 2882, 867, 2903, 885, 2917, 900, 2913, 9 [...]
+        "center":[791, 3075],
+        "bbox":[489.402439140938, 2828.9426480949915, 548.650900006219, 534.296658090756]
+      },
+      "LUX":{
+        "shape":[924, 2924, 918, 2922, 902, 2921, 900, 2913, 903, 2906, 900, 2886, 912, 2885, 913, 2889, 933, 2902, 927, 2913, 924, 2924],
+        "center":[914, 2905],
+        "bbox":[900.2214262917508, 2884.6138446977106, 32.660352142732336, 39.68109043361119]
+      },
+      "GBR":{
+        "shape":[[437, 2460, 463, 2432, 453, 2381, 474, 2376, 464, 2366, 484, 2351, 483, 2324, 491, 2337, 555, 2323, 553, 2348, 505, 2406, 548, 2387, 606, 2407, 574, 2474, 552, 2485, 575, 2492, 531, 2506, 573, 2505, 615, 2537, 627, 2603, 671, 2633, 682, 2668, 650, 2661, 685, 2686, 676, 2714, 717, 2711, 738, 2724, 733, 2769, 693, 2802, 707, 2813, 732, 2808, 713, 2840, 687, 2849, 624, 2841, 583, 2860, 564, 2847, 547, 2853, 536, 2880, 495, 2873, 481, 2893, 458, 2891, 515, 2819, 559, 2820, 5 [...]
+        "center":[616, 2702],
+        "bbox":[365.38220555276104, 2322.9520273023027, 372.8372349481745, 569.5485989362633]
+      },
+      "ZWE":{
+        "shape":[1880, 5987, 1861, 5981, 1831, 5983, 1811, 5975, 1801, 5978, 1796, 5973, 1787, 5957, 1748, 5950, 1741, 5911, 1723, 5908, 1717, 5893, 1684, 5871, 1674, 5845, 1636, 5802, 1641, 5795, 1670, 5802, 1708, 5804, 1734, 5779, 1780, 5755, 1793, 5723, 1812, 5716, 1836, 5714, 1843, 5732, 1875, 5731, 1941, 5760, 1943, 5821, 1926, 5850, 1944, 5884, 1913, 5949, 1880, 5987],
+        "center":[1834, 5854],
+        "bbox":[1635.6213957530047, 5713.840554978694, 308.21713275618754, 273.01052739211445]
+      },
+      "CHE":{
+        "shape":[1037, 3053, 1038, 3058, 1037, 3061, 1042, 3061, 1042, 3061, 1062, 3073, 1071, 3065, 1076, 3066, 1075, 3068, 1074, 3090, 1059, 3090, 1063, 3106, 1029, 3093, 1019, 3130, 994, 3094, 961, 3123, 956, 3128, 945, 3121, 933, 3097, 903, 3112, 902, 3099, 939, 3059, 940, 3038, 967, 3034, 971, 3030, 984, 3032, 1005, 3017, 1030, 3028, 1037, 3032, 1040, 3037, 1036, 3051, 1037, 3053],
+        "center":[991, 3070],
+        "bbox":[901.5818350003973, 3017.287625472859, 174.0149201235962, 112.616003939665]
+      },
+      "AGO":{
+        "shape":[[1313, 5343, 1323, 5383, 1350, 5419, 1412, 5415, 1424, 5394, 1425, 5376, 1457, 5372, 1466, 5375, 1467, 5389, 1505, 5388, 1513, 5435, 1506, 5473, 1530, 5522, 1522, 5523, 1523, 5543, 1537, 5533, 1585, 5530, 1597, 5537, 1592, 5601, 1599, 5612, 1517, 5610, 1516, 5734, 1563, 5784, 1576, 5791, 1472, 5811, 1399, 5802, 1373, 5783, 1210, 5785, 1178, 5768, 1154, 5779, 1135, 5772, 1124, 5778, 1123, 5769, 1126, 5720, 1140, 5693, 1156, 5626, 1177, 5596, 1195, 5586, 1209, 5534, 1171,  [...]
+        "center":[1337, 5570],
+        "bbox":[1122.8569396829403, 5278.748936006733, 475.976520281341, 532.3082335471108]
+      },
+      "LVA":{
+        "shape":[1478, 2504, 1477, 2453, 1504, 2399, 1539, 2388, 1578, 2441, 1602, 2427, 1604, 2387, 1603, 2381, 1651, 2369, 1686, 2400, 1723, 2403, 1733, 2412, 1730, 2441, 1754, 2494, 1754, 2497, 1728, 2525, 1698, 2533, 1693, 2528, 1623, 2477, 1601, 2489, 1517, 2481, 1478, 2504],
+        "center":[1599, 2448],
+        "bbox":[1476.6358197748307, 2368.933178943197, 277.39339745785037, 164.43417950238927]
+      },
+      "SWE":{
+        "shape":[1101, 2286, 1119, 2301, 1129, 2226, 1151, 2222, 1160, 2185, 1141, 2134, 1168, 2113, 1141, 2084, 1136, 1927, 1164, 1889, 1207, 1891, 1216, 1876, 1195, 1840, 1228, 1779, 1225, 1698, 1264, 1681, 1260, 1663, 1308, 1606, 1289, 1569, 1311, 1522, 1341, 1505, 1358, 1519, 1378, 1450, 1439, 1478, 1445, 1401, 1463, 1402, 1579, 1518, 1577, 1672, 1600, 1725, 1582, 1727, 1540, 1719, 1515, 1763, 1488, 1769, 1500, 1791, 1477, 1820, 1496, 1857, 1458, 1910, 1375, 1971, 1361, 2019, 1341, 2 [...]
+        "center":[1287, 1977],
+        "bbox":[1100.6358190839196, 1401.147383125371, 499.1592501202706, 1148.9695314905948]
+      },
+      "CZE":{
+        "shape":[1331, 2968, 1251, 2949, 1237, 2972, 1218, 2977, 1203, 2966, 1201, 2960, 1180, 2947, 1158, 2920, 1155, 2895, 1131, 2874, 1145, 2879, 1227, 2841, 1228, 2829, 1247, 2841, 1258, 2833, 1263, 2840, 1304, 2855, 1312, 2882, 1325, 2880, 1321, 2863, 1354, 2873, 1360, 2890, 1388, 2892, 1399, 2915, 1388, 2915, 1373, 2944, 1331, 2968],
+        "center":[1274, 2901],
+        "bbox":[1131.26203466103, 2828.6770471539303, 267.27712473827114, 148.62963251310202]
+      },
+      "TGO":{
+        "shape":[714, 4873, 694, 4844, 694, 4793, 702, 4785, 686, 4773, 694, 4764, 691, 4742, 680, 4743, 689, 4713, 673, 4699, 676, 4691, 678, 4682, 689, 4687, 703, 4681, 703, 4711, 724, 4726, 720, 4737, 733, 4758, 736, 4865, 714, 4873],
+        "center":[710, 4770],
+        "bbox":[673.1948476988539, 4680.999741882874, 63.07338122243243, 192.1121471739525]
+      },
+      "CIV":{
+        "shape":[380, 4942, 375, 4924, 385, 4891, 368, 4879, 370, 4867, 339, 4859, 347, 4846, 344, 4824, 345, 4814, 357, 4817, 367, 4795, 355, 4790, 358, 4779, 372, 4783, 377, 4776, 368, 4767, 366, 4716, 373, 4715, 385, 4705, 389, 4715, 406, 4716, 414, 4698, 434, 4693, 436, 4717, 447, 4705, 459, 4702, 457, 4713, 471, 4715, 486, 4744, 503, 4743, 510, 4730, 524, 4727, 554, 4732, 561, 4746, 569, 4738, 572, 4750, 574, 4789, 557, 4803, 558, 4827, 543, 4847, 554, 4890, 570, 4890, 569, 4915, 55 [...]
+        "center":[452, 4829],
+        "bbox":[338.998891852654, 4692.680976271764, 234.86163422138083, 248.84145497872032]
+      },
+      "ERI":{
+        "shape":[2328, 4619, 2314, 4631, 2308, 4625, 2301, 4629, 2282, 4598, 2213, 4549, 2180, 4550, 2174, 4543, 2152, 4553, 2131, 4537, 2113, 4560, 2077, 4558, 2076, 4546, 2075, 4522, 2096, 4447, 2141, 4426, 2154, 4406, 2169, 4432, 2199, 4525, 2207, 4512, 2221, 4533, 2255, 4542, 2277, 4573, 2328, 4619],
+        "center":[2194, 4533],
+        "bbox":[2074.5246485800835, 4405.788797621143, 253.80601294473217, 225.06701857148346]
+      },
+      "NER":{
+        "shape":[835, 4360, 891, 4343, 986, 4275, 1133, 4179, 1165, 4188, 1216, 4218, 1249, 4204, 1260, 4240, 1254, 4262, 1286, 4310, 1271, 4357, 1266, 4446, 1200, 4525, 1188, 4547, 1194, 4574, 1178, 4589, 1156, 4601, 1090, 4591, 1060, 4594, 1038, 4611, 1004, 4610, 982, 4594, 938, 4606, 919, 4576, 907, 4580, 880, 4570, 877, 4578, 846, 4576, 829, 4588, 828, 4604, 807, 4624, 811, 4629, 811, 4644, 780, 4626, 764, 4634, 767, 4640, 762, 4646, 749, 4633, 759, 4623, 748, 4613, 732, 4621, 709, 4 [...]
+        "center":[1017, 4439],
+        "bbox":[680.2849124829356, 4178.573518424462, 605.8995755617436, 467.7544132490757]
+      },
+      "MAR":{
+        "shape":[165, 4005, 173, 3995, 228, 3978, 281, 3925, 301, 3887, 292, 3874, 295, 3841, 316, 3790, 341, 3759, 406, 3727, 444, 3641, 466, 3634, 470, 3656, 487, 3667, 546, 3669, 560, 3660, 559, 3672, 576, 3671, 584, 3679, 600, 3688, 606, 3712, 599, 3736, 615, 3779, 632, 3789, 625, 3798, 615, 3809, 556, 3810, 561, 3827, 528, 3836, 522, 3849, 536, 3856, 486, 3878, 478, 3905, 444, 3921, 399, 3925, 357, 3950, 339, 3966, 339, 4005, 165, 4005],
+        "center":[417, 3813],
+        "bbox":[165.1581701427673, 3634.461760878245, 466.9128558927257, 370.86825065487346]
+      },
+      "NLD":{
+        "shape":[796, 2814, 828, 2811, 831, 2781, 857, 2790, 832, 2776, 862, 2695, 861, 2715, 873, 2716, 867, 2747, 884, 2755, 899, 2714, 887, 2708, 883, 2718, 886, 2692, 933, 2678, 949, 2693, 954, 2692, 947, 2727, 931, 2736, 947, 2758, 909, 2782, 915, 2810, 900, 2845, 896, 2844, 894, 2821, 869, 2804, 837, 2807, 831, 2819, 796, 2814],
+        "center":[889, 2760],
+        "bbox":[795.6732015530353, 2678.289766417124, 157.8402015051762, 167.17505039319713]
+      },
+      "LTU":{
+        "shape":[1572, 2647, 1573, 2628, 1550, 2615, 1544, 2608, 1539, 2567, 1488, 2556, 1486, 2551, 1477, 2513, 1478, 2504, 1517, 2481, 1601, 2489, 1623, 2477, 1693, 2528, 1698, 2533, 1691, 2539, 1694, 2564, 1664, 2579, 1655, 2633, 1640, 2622, 1609, 2649, 1572, 2647],
+        "center":[1590, 2558],
+        "bbox":[1477.1917684393848, 2477.0876723246224, 221.26314145156198, 171.44704271675892]
+      },
+      "CYP":{
+        "shape":[1906, 3673, 1995, 3646, 1970, 3660, 1973, 3676, 1934, 3694, 1913, 3688, 1906, 3673],
+        "center":[1948, 3670],
+        "bbox":[1906.0581717058033, 3645.5109665857726, 88.52833959176928, 48.78837973376267]
+      },
+      "SOM":{
+        "shape":[2270, 5174, 2247, 5143, 2247, 5002, 2285, 4955, 2295, 4948, 2321, 4944, 2330, 4931, 2364, 4919, 2398, 4923, 2516, 4801, 2484, 4802, 2362, 4763, 2339, 4746, 2312, 4701, 2322, 4683, 2335, 4668, 2358, 4698, 2399, 4711, 2431, 4690, 2467, 4698, 2497, 4678, 2507, 4684, 2539, 4672, 2558, 4676, 2607, 4661, 2621, 4649, 2642, 4655, 2637, 4702, 2607, 4784, 2568, 4838, 2558, 4873, 2514, 4933, 2516, 4943, 2442, 5019, 2343, 5083, 2270, 5174],
+        "center":[2534, 4755],
+        "bbox":[2246.9891253618957, 4648.817015282079, 395.4717970639231, 524.7219636348473]
+      },
+      "AFG":{
+        "shape":[3022, 3637, 3067, 3667, 3096, 3654, 3096, 3632, 3113, 3635, 3153, 3609, 3162, 3571, 3195, 3558, 3225, 3567, 3241, 3567, 3251, 3575, 3270, 3571, 3287, 3587, 3309, 3570, 3333, 3570, 3338, 3551, 3362, 3550, 3364, 3530, 3385, 3505, 3417, 3521, 3412, 3533, 3424, 3535, 3417, 3581, 3430, 3593, 3482, 3556, 3508, 3556, 3511, 3565, 3525, 3557, 3531, 3559, 3552, 3566, 3547, 3568, 3533, 3572, 3533, 3584, 3462, 3587, 3410, 3620, 3421, 3665, 3401, 3688, 3403, 3717, 3357, 3719, 3376, 3 [...]
+        "center":[3210, 3719],
+        "bbox":[2993.180165850678, 3504.862960797275, 558.5706562161622, 428.05688413116695]
+      },
+      "RUS":{
+        "shape":[[1715, 2305, 1753, 2265, 1748, 2253, 1746, 2237, 1781, 2222, 1832, 2223, 1766, 2186, 1771, 2158, 1746, 2178, 1738, 2178, 1888, 1981, 1823, 1912, 1843, 1882, 1807, 1808, 1813, 1745, 1828, 1739, 1790, 1625, 1825, 1551, 1772, 1502, 1774, 1410, 1781, 1404, 1779, 1415, 1821, 1352, 1848, 1364, 1861, 1324, 1871, 1332, 1900, 1324, 1889, 1306, 1941, 1328, 1933, 1346, 1901, 1329, 1888, 1355, 1937, 1357, 1930, 1376, 1951, 1361, 1954, 1393, 1971, 1375, 2064, 1397, 2242, 1542, 2257,  [...]
+        "center":[4408, 1859],
+        "bbox":[1432.2922900250471, 0.0, 6131.969580554295, 3371.906882197538]
+      },
+      "SVK":{
+        "shape":[1331, 2968, 1373, 2944, 1388, 2915, 1399, 2915, 1400, 2920, 1420, 2916, 1434, 2936, 1502, 2922, 1547, 2945, 1536, 2947, 1526, 2980, 1526, 2985, 1497, 2973, 1468, 2976, 1449, 2996, 1429, 2993, 1395, 3016, 1344, 3011, 1333, 3006, 1328, 3001, 1327, 2975, 1331, 2968],
+        "center":[1416, 2965],
+        "bbox":[1327.248676444256, 2915.3567663266936, 220.02892761648354, 100.83902066972269]
+      },
+      "SVN":{
+        "shape":[1289, 3072, 1295, 3072, 1305, 3089, 1302, 3089, 1267, 3107, 1271, 3121, 1257, 3142, 1225, 3132, 1215, 3145, 1205, 3145, 1206, 3136, 1188, 3111, 1200, 3096, 1202, 3089, 1238, 3097, 1256, 3084, 1275, 3088, 1286, 3072, 1289, 3072],
+        "center":[1250, 3107],
+        "bbox":[1187.7024282859459, 3071.5800381884105, 117.61802231060142, 73.70090455448053]
+      },
+      "BIH":{
+        "shape":[1349, 3282, 1347, 3283, 1350, 3271, 1290, 3213, 1279, 3161, 1346, 3149, 1404, 3176, 1410, 3175, 1418, 3181, 1406, 3200, 1423, 3221, 1384, 3282, 1385, 3298, 1349, 3282],
+        "center":[1361, 3221],
+        "bbox":[1278.9833760751783, 3148.734787773605, 143.95857714242243, 148.83584763130784]
+      }
+    }
+}
diff --git a/dojox/geo/charting/resources/data/NOTICES b/dojox/geo/charting/resources/data/NOTICES
index 5d62e07..1e9fc44 100644
--- a/dojox/geo/charting/resources/data/NOTICES
+++ b/dojox/geo/charting/resources/data/NOTICES
@@ -1,9 +1,13 @@
-Mapping data in this directory was obtained from the United States Geological Survey (USGS) at http://nationalatlas.gov/atlasftp.html.  
-Data and information authored or produced by the USGS are in the public domain:  http://nationalatlas.gov/policies.html.  
-The following notices and information are provided by the USGS:
------------------------------------------------------------------------------------------------------------------------------------------------
 
-	
+USStates.json mapping data was obtained from the United States Geological Survey (USGS) at http://nationalatlas.gov/atlasftp.html.
+Data and information authored or produced by the USGS are in the public domain:  http://nationalatlas.gov/policies.html.
+
+Americas.json, AsianPacific.json, ContinentalEurope.json, EuropeMiddleEastAfrica.json, WorldCountries.json and
+WorldCountriesMercator.json mapping data were obtained from Natural Earth http://www.naturalearthdata.com/downloads/110m-cultural-vectors/110m-admin-0-countries/.
+These data are in the public domain: http://www.naturalearthdata.com/about/terms-of-use/.
+
+The following notices and information are provided by the USGS (first) and then Natural Earth.
+------------------------------------------------------------------------------------------------------------------------
 	Are there legal restrictions on access or use of the data?
 
 		Access_Constraints: None 
@@ -31,7 +35,9 @@ The following notices and information are provided by the USGS:
 	3. What legal disclaimers am I supposed to read?
 
 		Although these data have been processed successfully on a computer system 
-		at the U.S. Geological Survey, no warranty expressed or implied is made by the U.S. Geological Survey regarding the utility of the data on any other system, nor shall the act of distribution constitute any such warranty. No responsibility is assumed by the U.S. Geological Survey in the use of these data. 
+		at the U.S. Geological Survey, no warranty expressed or implied is made by the U.S. Geological Survey regarding
+		the utility of the data on any other system, nor shall the act of distribution constitute any such warranty. No
+		responsibility is assumed by the U.S. Geological Survey in the use of these data.
 
 	4. How can I download or order the data?
 
@@ -58,6 +64,55 @@ The following notices and information are provided by the USGS:
 
 			To order files on CD-ROM, please see <http://nationalatlas.gov/atlasftp.html#q12>. 
 
+------------------------------------------------------------------------------------------------------------------------
+
+------------------------------------------------------------------------------------------------------------------------
+Public Domain. All versions of Natural Earth raster + vector map data found on this website are in the public domain.
+You may use the maps in any manner, including modifying the content and design, electronic dissemination, and offset
+printing. The primary authors, Tom Patterson and Nathaniel Vaughn Kelso, and all other contributors renounce all
+financial claim to the maps and invites you to use them for personal, educational, and commercial purposes.
+
+No permission is needed to use Natural Earth. Crediting the authors is unnecessary.
+
+However, if you wish to cite the map data, simply use one of the following.
+
+Short text: Made with Natural Earth.
+
+Long text: Made with Natural Earth. Free vector and raster map data @ naturalearthdata.com.
+
+All users of Natural Earth are highly encouraged to read about data sources and manipulation in the Data Creation section.
+
+The authors provide Natural Earth as a public service and are not responsible for any problems relating to accuracy,
+content, design, and how it is used. If you find an error or omission, please report it for future updates.
+
+The authors used data from The Washington Post, here is their release:
+
+    Natural Earth is hereby granted a non-exclusive license to use the data being provided by The Washington Post for
+    the sole purpose of creating a world base map.  The Washington Post makes no claims as to the completeness, accuracy
+    or content of the data, and makes no representation of any kind, including, but not limited to, any warranty as to
+    the accuracy or fitness of the data for a particular use (nor shall the act of distribution constitute any such
+    warranty). No responsibility is assumed by The Washington Post for any claims arising out of Natural Earth’s use of
+    the data.
+
+The author’s used river and lake data (for Europe only) from the European Commission, Joint Research Centre, Institute
+for Environment and Sustainability, here is their release:
+
+    Natural Earth is hereby granted a non-exclusive license to use the data being provided by European Commission, Joint
+    Research Centre, Institute for Environment and Sustainability (JRC IES) for the sole purpose of creating a world
+    base map. The EC JRC IES makes no claims as to the completeness, accuracy or content of the data, and makes no
+    representation of any kind, including, but not limited to, any warranty as to the accuracy or fitness of the data
+    for a particular use (nor shall the act of distribution constitute any such warranty). No responsibility is assumed
+    by EC JRC IES for any claims arising out of Natural Earth’s use of the data.
+
+The author’s used road transportation data (for North America only) from XNR Productions, here is their release:
+
+    Natural Earth is hereby granted a non-exclusive license to use the data being provided by XNR Productions for the
+    sole purpose of creating a world base map. XNR makes no claims as to the completeness, accuracy or content of the
+    data, and makes no representation of any kind, including, but not limited to, any warranty as to the accuracy or
+    fitness of the data for a particular use (nor shall the act of distribution constitute any such warranty). No
+    responsibility is assumed by XNR for any claims arising out of Natural Earth’s use of the data.
+
+Happy mapping!
 ---------------------------------------------------------------------------------------------------------------------
 
-This Shapefile data is then reformatted into a simple JSON format
+These Shapefile data have been then reformatted into a simple JSON format
diff --git a/dojox/geo/charting/resources/data/WorldCountries.json b/dojox/geo/charting/resources/data/WorldCountries.json
new file mode 100644
index 0000000..013ce4e
--- /dev/null
+++ b/dojox/geo/charting/resources/data/WorldCountries.json
@@ -0,0 +1,827 @@
+{
+  "layerExtent":[0.0, 0.0, 10329.993903051552, 5461.438355482124],
+    "layerExtentLL":[-168.1442413330078, 84.92936706542969, 348.14300537109375, 138.64053344726562],
+    "featureNames":["JAM", "BTN", "ROM", "DJI", "UGA", "KOR", "KGZ", "MOZ", "NOR", "YEM", "COG", "SYR", "ZAR", "HTI", "PNG", "RWA", "FIN", "JPN", "TCD", "MEX", "UZB", "IDN", "IND", "ARE", "HRV", "ARG", "MWI", "MNG", "ARM", "TUN", "COL", "AZE", "TUR", "POL", "GEO", "GNQ", "NGA", "PAN", "TJK", "GNB", "KEN", "GUY", "PAK", "MDG", "YUG", "VEN", "URY", "EGY", "HUN", "BLR", "LIE", "MDA", "BDI", "ALB", "SAU", "BLZ", "MMR", "TKM", "CMR", "MLI", "OMN", "GMB", "NPL", "GTM", "BFA", "CUB", "USA", "NZ [...]
+    "features":{
+      "JAM":{
+        "shape":[2022, 2216, 2042, 2203, 2074, 2208, 2093, 2219, 2098, 2231, 2075, 2228, 2070, 2235, 2065, 2232, 2063, 2242, 2042, 2235, 2034, 2218, 2022, 2216],
+        "center":[2061, 2222],
+        "bbox":[2022.4989331846493, 2203.0117628213816, 75.12321661889996, 38.75926779587053]
+      },
+      "BTN":{
+        "shape":[7662, 1828, 7661, 1815, 7629, 1810, 7617, 1779, 7616, 1770, 7633, 1767, 7644, 1755, 7653, 1760, 7690, 1748, 7710, 1779, 7711, 1788, 7728, 1795, 7735, 1819, 7680, 1819, 7677, 1826, 7662, 1828],
+        "center":[7672, 1790],
+        "bbox":[7615.727919108827, 1747.926675378431, 119.02364111638235, 80.00542240778759]
+      },
+      "ROM":{
+        "shape":[5554, 1095, 5542, 1094, 5533, 1086, 5505, 1085, 5470, 1103, 5451, 1099, 5428, 1106, 5386, 1099, 5386, 1086, 5378, 1084, 5378, 1082, 5369, 1078, 5372, 1064, 5366, 1061, 5359, 1072, 5333, 1058, 5339, 1051, 5335, 1038, 5313, 1029, 5313, 1018, 5300, 1010, 5292, 1003, 5311, 1006, 5312, 998, 5328, 989, 5324, 984, 5341, 953, 5368, 930, 5374, 928, 5383, 934, 5416, 934, 5428, 943, 5470, 925, 5475, 922, 5489, 928, 5534, 980, 5533, 1008, 5542, 1030, 5543, 1037, 5553, 1042, 5569, 10 [...]
+        "center":[5442, 1015],
+        "bbox":[5292.425488897989, 922.3339587414488, 290.29254037665305, 183.51964493069238]
+      },
+      "DJI":{
+        "shape":[6164, 2483, 6174, 2495, 6177, 2515, 6157, 2526, 6148, 2541, 6169, 2536, 6173, 2542, 6162, 2561, 6125, 2559, 6121, 2528, 6140, 2495, 6147, 2489, 6152, 2497, 6164, 2483],
+        "center":[6156, 2520],
+        "bbox":[6121.028982013296, 2482.539508327221, 56.39151272617528, 78.61103945138348]
+      },
+      "UGA":{
+        "shape":[5741, 3145, 5725, 3169, 5717, 3160, 5707, 3166, 5712, 3122, 5722, 3055, 5733, 3034, 5772, 2997, 5771, 2988, 5748, 2976, 5754, 2954, 5750, 2944, 5756, 2928, 5752, 2919, 5754, 2910, 5763, 2909, 5799, 2914, 5825, 2906, 5841, 2912, 5861, 2886, 5867, 2893, 5871, 2911, 5879, 2914, 5875, 2932, 5883, 2952, 5895, 2967, 5900, 3008, 5862, 3085, 5862, 3146, 5758, 3146, 5750, 3141, 5741, 3145],
+        "center":[5806, 3028],
+        "bbox":[5706.552574861361, 2885.9842703570316, 193.26581663628076, 283.2639138708173]
+      },
+      "KOR":{
+        "shape":[8688, 1380, 8690, 1372, 8695, 1379, 8691, 1371, 8704, 1372, 8710, 1379, 8713, 1374, 8698, 1364, 8700, 1358, 8683, 1343, 8687, 1339, 8686, 1337, 8686, 1317, 8706, 1310, 8715, 1317, 8719, 1302, 8730, 1314, 8780, 1361, 8795, 1383, 8807, 1415, 8813, 1415, 8820, 1439, 8818, 1459, 8811, 1457, 8811, 1450, 8810, 1456, 8798, 1455, 8802, 1470, 8784, 1457, 8772, 1464, 8778, 1465, 8779, 1474, 8768, 1465, 8775, 1476, 8772, 1482, 8764, 1479, 8768, 1472, 8763, 1468, 8748, 1488, 8743, 1 [...]
+        "center":[8750, 1398],
+        "bbox":[8683.478061298752, 1302.3078973597246, 136.94532886695742, 185.35210724158242]
+      },
+      "KGZ":{
+        "shape":[6851, 1245, 6856, 1238, 6845, 1232, 6845, 1219, 6858, 1225, 6872, 1214, 6879, 1192, 6869, 1192, 6863, 1186, 6885, 1162, 6882, 1157, 6870, 1158, 6881, 1139, 6899, 1137, 6928, 1149, 6948, 1149, 6944, 1137, 6958, 1118, 6993, 1129, 7056, 1127, 7065, 1133, 7122, 1138, 7158, 1155, 7163, 1151, 7170, 1171, 7155, 1166, 7151, 1178, 7144, 1173, 7135, 1185, 7122, 1186, 7117, 1207, 7076, 1210, 7072, 1231, 7064, 1235, 7051, 1239, 7040, 1224, 7030, 1234, 7021, 1230, 7001, 1249, 6997, 1 [...]
+        "center":[6978, 1204],
+        "bbox":[6845.294326257989, 1118.2178418806193, 324.9136602000981, 164.13987285190706]
+      },
+      "MOZ":{
+        "shape":[5718, 3847, 5713, 3822, 5813, 3775, 5817, 3768, 5837, 3798, 5862, 3800, 5863, 3849, 5851, 3864, 5876, 3903, 5876, 3915, 5884, 3915, 5883, 3891, 5888, 3872, 5904, 3868, 5908, 3856, 5914, 3804, 5893, 3766, 5880, 3750, 5868, 3749, 5865, 3690, 5875, 3660, 5889, 3657, 5908, 3655, 5919, 3644, 5940, 3661, 5971, 3656, 5987, 3640, 6033, 3637, 6073, 3600, 6078, 3615, 6083, 3622, 6071, 3660, 6074, 3686, 6069, 3700, 6078, 3719, 6070, 3729, 6077, 3735, 6075, 3780, 6070, 3786, 6078, 3 [...]
+        "center":[5912, 3945],
+        "bbox":[5713.470092448802, 3599.912420370947, 369.3593463313109, 767.2026021580468]
+      },
+      "NOR":{
+        "shape":[4812, 463, 4824, 458, 4817, 453, 4826, 457, 4837, 447, 4852, 447, 4848, 441, 4880, 439, 4879, 435, 4866, 436, 4868, 428, 4882, 429, 4932, 412, 4943, 418, 4965, 415, 4965, 409, 4978, 407, 4970, 403, 4973, 399, 4951, 412, 4929, 406, 4948, 402, 4940, 400, 4943, 396, 4965, 384, 4979, 386, 4975, 380, 4985, 376, 4962, 373, 4980, 374, 4995, 367, 5001, 344, 5016, 340, 5010, 331, 5027, 323, 5025, 320, 5051, 312, 5073, 314, 5065, 309, 5042, 310, 5053, 304, 5072, 307, 5063, 302, 50 [...]
+        "center":[4931, 476],
+        "bbox":[4811.717837363835, 216.91906179983272, 626.1576432305746, 364.45567645040416]
+      },
+      "YEM":{
+        "shape":[6140, 2300, 6153, 2287, 6148, 2272, 6155, 2250, 6179, 2259, 6196, 2251, 6256, 2284, 6262, 2314, 6268, 2315, 6343, 2212, 6398, 2198, 6446, 2179, 6491, 2290, 6480, 2294, 6464, 2304, 6465, 2338, 6431, 2363, 6366, 2388, 6347, 2414, 6325, 2414, 6305, 2433, 6250, 2445, 6219, 2477, 6212, 2473, 6187, 2484, 6172, 2479, 6161, 2449, 6162, 2424, 6139, 2357, 6145, 2360, 6140, 2300],
+        "center":[6283, 2364],
+        "bbox":[6139.368528653987, 2179.220981651889, 351.77491197507425, 304.98913315069876]
+      },
+      "COG":{
+        "shape":[5065, 3283, 5083, 3262, 5093, 3275, 5097, 3270, 5097, 3242, 5084, 3225, 5086, 3202, 5110, 3210, 5116, 3180, 5126, 3187, 5135, 3208, 5153, 3210, 5158, 3197, 5171, 3215, 5186, 3186, 5183, 3145, 5188, 3120, 5169, 3107, 5168, 3079, 5183, 3050, 5182, 3035, 5175, 3026, 5147, 3026, 5138, 3003, 5148, 2996, 5146, 2987, 5183, 2991, 5190, 2983, 5197, 2995, 5217, 2993, 5239, 3009, 5236, 2995, 5243, 2987, 5257, 2956, 5258, 2920, 5289, 2913, 5304, 2921, 5325, 2916, 5329, 2939, 5302, 3 [...]
+        "center":[5235, 3114],
+        "bbox":[5064.714410599912, 2912.9910495971008, 264.29828131427166, 423.7884376572588]
+      },
+      "SYR":{
+        "shape":[5837, 1475, 5823, 1425, 5828, 1419, 5841, 1422, 5841, 1411, 5849, 1405, 5847, 1381, 5873, 1393, 5901, 1380, 5918, 1392, 5931, 1392, 5973, 1373, 5994, 1368, 6004, 1374, 6018, 1362, 6024, 1365, 6029, 1374, 6019, 1391, 6001, 1398, 6003, 1465, 5998, 1487, 5935, 1530, 5879, 1577, 5852, 1567, 5836, 1558, 5837, 1551, 5837, 1542, 5837, 1532, 5843, 1529, 5843, 1512, 5859, 1492, 5852, 1476, 5837, 1475],
+        "center":[5921, 1455],
+        "bbox":[5823.470892548572, 1362.4104871115485, 206.01106550823351, 214.18934517021808]
+      },
+      "ZAR":{
+        "shape":[5107, 3376, 5118, 3372, 5115, 3337, 5132, 3321, 5139, 3317, 5148, 3329, 5162, 3312, 5179, 3303, 5184, 3324, 5193, 3325, 5208, 3302, 5215, 3307, 5231, 3288, 5247, 3252, 5247, 3202, 5267, 3159, 5295, 3133, 5305, 3083, 5302, 3046, 5329, 2939, 5325, 2916, 5322, 2906, 5322, 2884, 5330, 2882, 5343, 2854, 5365, 2847, 5388, 2864, 5393, 2877, 5430, 2887, 5438, 2881, 5453, 2890, 5466, 2868, 5516, 2866, 5529, 2855, 5552, 2861, 5562, 2854, 5565, 2842, 5579, 2851, 5619, 2839, 5627, 2 [...]
+        "center":[5495, 3271],
+        "bbox":[5106.5026486860115, 2839.26200866333, 665.3999797626466, 902.7550910880905]
+      },
+      "HTI":{
+        "shape":[2259, 2148, 2259, 2180, 2250, 2188, 2258, 2194, 2247, 2210, 2249, 2211, 2249, 2223, 2244, 2220, 2190, 2217, 2178, 2226, 2171, 2215, 2161, 2215, 2160, 2205, 2170, 2196, 2209, 2209, 2230, 2204, 2232, 2195, 2220, 2177, 2224, 2159, 2215, 2145, 2201, 2149, 2205, 2138, 2227, 2134, 2259, 2148],
+        "center":[2235, 2173],
+        "bbox":[2160.017988940417, 2134.3051121487283, 99.22435197728191, 91.73881897616047]
+      },
+      "PNG":{
+        "shape":[[9561, 3224, 9624, 3259, 9646, 3262, 9668, 3285, 9678, 3281, 9678, 3290, 9705, 3308, 9721, 3329, 9716, 3361, 9778, 3389, 9786, 3418, 9754, 3421, 9758, 3456, 9765, 3457, 9781, 3484, 9789, 3485, 9787, 3509, 9796, 3517, 9795, 3529, 9802, 3536, 9825, 3534, 9816, 3554, 9844, 3561, 9844, 3566, 9833, 3569, 9840, 3584, 9868, 3591, 9851, 3595, 9862, 3605, 9849, 3614, 9833, 3606, 9842, 3600, 9828, 3593, 9784, 3589, 9780, 3579, 9769, 3588, 9731, 3533, 9713, 3481, 9677, 3474, 9671,  [...]
+        "center":[9662, 3392],
+        "bbox":[9535.285988177116, 3223.9698159281193, 414.5075439034463, 390.17661379167066]
+      },
+      "RWA":{
+        "shape":[5707, 3166, 5717, 3160, 5725, 3169, 5741, 3145, 5755, 3175, 5751, 3183, 5756, 3197, 5747, 3214, 5740, 3212, 5738, 3205, 5721, 3204, 5719, 3225, 5710, 3232, 5699, 3215, 5689, 3224, 5685, 3217, 5694, 3210, 5707, 3166],
+        "center":[5719, 3189],
+        "bbox":[5684.585228187231, 3144.5029936855894, 71.58173355636973, 87.27036695463994]
+      },
+      "FIN":{
+        "shape":[[5189, 266, 5201, 266, 5202, 258, 5228, 267, 5234, 274, 5256, 276, 5269, 271, 5300, 277, 5317, 268, 5314, 259, 5327, 244, 5345, 245, 5360, 241, 5400, 255, 5390, 262, 5393, 266, 5389, 268, 5386, 281, 5395, 289, 5434, 302, 5417, 321, 5452, 353, 5443, 354, 5445, 373, 5457, 376, 5460, 389, 5475, 396, 5465, 406, 5516, 429, 5505, 444, 5431, 502, 5427, 503, 5378, 507, 5342, 520, 5332, 516, 5309, 523, 5304, 507, 5292, 510, 5268, 499, 5259, 500, 5252, 485, 5259, 472, 5237, 433, 5 [...]
+        "center":[5382, 406],
+        "bbox":[5189.231016861768, 241.16519493004978, 326.6092313490144, 281.69253276075426]
+      },
+      "JPN":{
+        "shape":[[8901, 1500, 8895, 1478, 8909, 1480, 8933, 1444, 8930, 1437, 8942, 1429, 8950, 1432, 8940, 1438, 8952, 1438, 8947, 1433, 8954, 1437, 8998, 1431, 9004, 1424, 9013, 1439, 9015, 1432, 9027, 1435, 9030, 1425, 9033, 1430, 9024, 1415, 9031, 1381, 9021, 1357, 9036, 1350, 9030, 1369, 9036, 1368, 9043, 1382, 9051, 1382, 9074, 1356, 9073, 1338, 9083, 1325, 9072, 1266, 9061, 1246, 9059, 1254, 9052, 1250, 9056, 1240, 9043, 1224, 9049, 1216, 9041, 1198, 9050, 1200, 9061, 1214, 9061,  [...]
+        "center":[9113, 1381],
+        "bbox":[8868.324610870812, 1031.7647167750729, 310.4750510728263, 604.0231322732711]
+      },
+      "TCD":{
+        "shape":[5186, 1997, 5221, 1978, 5495, 2156, 5499, 2331, 5469, 2338, 5462, 2350, 5467, 2357, 5447, 2395, 5453, 2409, 5440, 2427, 5447, 2453, 5432, 2473, 5433, 2481, 5445, 2475, 5454, 2483, 5457, 2528, 5473, 2538, 5473, 2554, 5469, 2567, 5463, 2559, 5437, 2565, 5428, 2593, 5403, 2631, 5385, 2646, 5336, 2661, 5343, 2675, 5336, 2692, 5302, 2706, 5292, 2703, 5260, 2726, 5251, 2711, 5227, 2734, 5221, 2726, 5217, 2715, 5203, 2668, 5187, 2661, 5165, 2622, 5173, 2608, 5214, 2608, 5202, 2 [...]
+        "center":[5318, 2503],
+        "bbox":[5141.992050909984, 1978.0422847060106, 356.76913637295183, 755.9107394654072]
+      },
+      "MEX":{
+        "shape":[891, 1567, 972, 1559, 965, 1569, 1069, 1620, 1162, 1620, 1169, 1600, 1225, 1601, 1259, 1652, 1261, 1697, 1292, 1724, 1308, 1713, 1321, 1690, 1335, 1684, 1363, 1689, 1379, 1718, 1381, 1756, 1399, 1788, 1395, 1812, 1400, 1841, 1449, 1866, 1459, 1861, 1459, 1863, 1425, 1925, 1444, 1881, 1436, 1891, 1432, 1887, 1429, 1904, 1420, 1909, 1430, 1908, 1418, 1927, 1421, 1934, 1413, 1956, 1423, 1931, 1421, 1942, 1397, 2032, 1409, 2062, 1404, 2074, 1400, 2045, 1398, 2066, 1409, 2109 [...]
+        "center":[1268, 2001],
+        "bbox":[888.4571730961655, 1558.8937987776123, 874.4268423200843, 831.1629248775532]
+      },
+      "UZB":{
+        "shape":[6422, 1195, 6382, 1048, 6455, 1025, 6524, 1063, 6582, 1105, 6672, 1097, 6722, 1134, 6728, 1171, 6745, 1172, 6762, 1202, 6794, 1199, 6798, 1208, 6818, 1212, 6870, 1158, 6882, 1157, 6885, 1162, 6863, 1186, 6869, 1192, 6879, 1192, 6872, 1214, 6858, 1225, 6845, 1219, 6845, 1232, 6856, 1238, 6851, 1245, 6847, 1243, 6821, 1271, 6800, 1268, 6797, 1280, 6832, 1297, 6829, 1312, 6839, 1319, 6840, 1328, 6832, 1354, 6833, 1366, 6818, 1370, 6807, 1362, 6795, 1362, 6792, 1348, 6789, 1 [...]
+        "center":[6684, 1210],
+        "bbox":[6382.2851197963155, 1024.8989709460643, 502.6838763278902, 344.7597465870333]
+      },
+      "IDN":{
+        "shape":[[9221, 3157, 9229, 3144, 9226, 3132, 9236, 3122, 9248, 3128, 9274, 3104, 9298, 3127, 9322, 3129, 9333, 3155, 9324, 3180, 9324, 3205, 9331, 3224, 9341, 3210, 9347, 3242, 9358, 3256, 9371, 3256, 9403, 3199, 9425, 3190, 9425, 3180, 9435, 3178, 9447, 3162, 9457, 3169, 9460, 3182, 9471, 3178, 9516, 3213, 9529, 3210, 9553, 3219, 9561, 3224, 9552, 3398, 9537, 3429, 9541, 3438, 9535, 3533, 9525, 3523, 9494, 3484, 9461, 3480, 9468, 3465, 9464, 3446, 9472, 3440, 9454, 3433, 9462,  [...]
+        "center":[8632, 3110],
+        "bbox":[7959.5589061433575, 2812.7293970097144, 1601.462252002565, 720.2026199861753]
+      },
+      "IND":{
+        "shape":[6960, 1960, 6961, 1951, 6978, 1950, 6975, 1934, 7013, 1943, 7017, 1935, 7040, 1932, 7044, 1945, 7055, 1939, 7047, 1934, 7050, 1918, 7030, 1889, 7028, 1874, 7016, 1875, 7008, 1860, 7010, 1842, 7002, 1829, 6992, 1833, 6985, 1827, 6983, 1810, 7004, 1773, 7012, 1772, 7021, 1788, 7056, 1778, 7064, 1742, 7078, 1738, 7085, 1727, 7089, 1688, 7103, 1668, 7098, 1658, 7108, 1638, 7109, 1600, 7127, 1583, 7099, 1574, 7099, 1564, 7062, 1547, 7043, 1482, 7060, 1489, 7062, 1475, 7076, 1 [...]
+        "center":[7314, 1990],
+        "bbox":[6959.819351624824, 1418.058310503528, 938.7118900368705, 1283.231201945067]
+      },
+      "ARE":{
+        "shape":[6554, 1871, 6558, 1874, 6562, 1899, 6541, 1899, 6539, 1907, 6545, 1936, 6556, 1937, 6561, 1952, 6541, 1947, 6536, 2000, 6542, 2016, 6529, 2025, 6428, 1998, 6409, 1951, 6385, 1930, 6391, 1924, 6395, 1923, 6395, 1933, 6427, 1952, 6441, 1942, 6490, 1944, 6502, 1936, 6507, 1913, 6547, 1852, 6554, 1871],
+        "center":[6488, 1968],
+        "bbox":[6385.057027645435, 1852.4902432755239, 177.3214047272977, 172.08775897681494]
+      },
+      "HRV":{
+        "shape":[5223, 1129, 5201, 1111, 5172, 1107, 5143, 1080, 5161, 1079, 5137, 1062, 5137, 1049, 5121, 1034, 5107, 1055, 5096, 1044, 5093, 1030, 5096, 1027, 5103, 1028, 5111, 1028, 5118, 1018, 5144, 1026, 5154, 1011, 5150, 1001, 5176, 988, 5179, 988, 5216, 1015, 5242, 1019, 5248, 1011, 5255, 1015, 5256, 1019, 5271, 1035, 5265, 1043, 5262, 1049, 5218, 1037, 5214, 1030, 5162, 1039, 5174, 1077, 5225, 1120, 5223, 1129],
+        "center":[5176, 1013],
+        "bbox":[5092.898513711324, 988.1014106160293, 178.2268117161666, 140.9107507770001]
+      },
+      "ARG":{
+        "shape":[2792, 4511, 2787, 4524, 2793, 4541, 2792, 4573, 2786, 4579, 2796, 4623, 2800, 4633, 2791, 4637, 2790, 4661, 2801, 4681, 2799, 4697, 2840, 4724, 2853, 4741, 2847, 4755, 2852, 4769, 2875, 4783, 2880, 4803, 2871, 4826, 2860, 4835, 2862, 4854, 2844, 4867, 2759, 4891, 2714, 4881, 2725, 4901, 2733, 4904, 2725, 4904, 2733, 4909, 2728, 4944, 2743, 4957, 2740, 4967, 2717, 4981, 2681, 4974, 2662, 4961, 2651, 4968, 2666, 5014, 2688, 5022, 2686, 5031, 2702, 5029, 2692, 5023, 2710, 5 [...]
+        "center":[2610, 4612],
+        "bbox":[2384.01135753205, 4129.049500424041, 520.2809312017525, 1274.540455571063]
+      },
+      "MWI":{
+        "shape":[5889, 3657, 5875, 3660, 5865, 3690, 5868, 3749, 5880, 3750, 5893, 3766, 5914, 3804, 5908, 3856, 5904, 3868, 5888, 3872, 5883, 3891, 5884, 3915, 5876, 3915, 5876, 3903, 5851, 3864, 5863, 3849, 5862, 3800, 5837, 3798, 5817, 3768, 5815, 3763, 5805, 3753, 5818, 3736, 5819, 3708, 5835, 3696, 5829, 3684, 5833, 3671, 5828, 3654, 5835, 3634, 5832, 3621, 5842, 3621, 5850, 3607, 5824, 3564, 5820, 3552, 5849, 3566, 5858, 3557, 5866, 3564, 5878, 3589, 5877, 3635, 5889, 3657],
+        "center":[5848, 3742],
+        "bbox":[5804.828177123187, 3552.3979218044497, 109.0063585832786, 363.0737297704918]
+      },
+      "MNG":{
+        "shape":[7302, 880, 7320, 873, 7317, 864, 7335, 855, 7334, 844, 7355, 841, 7358, 831, 7398, 833, 7407, 847, 7439, 842, 7449, 855, 7482, 866, 7497, 860, 7541, 871, 7564, 867, 7572, 864, 7562, 860, 7555, 843, 7525, 818, 7535, 803, 7545, 800, 7546, 785, 7651, 811, 7675, 840, 7716, 855, 7784, 845, 7795, 854, 7804, 849, 7830, 863, 7855, 864, 7860, 876, 7882, 884, 7954, 892, 7965, 885, 8011, 877, 8028, 849, 8047, 851, 8084, 866, 8091, 860, 8105, 862, 8114, 865, 8127, 923, 8123, 928, 81 [...]
+        "center":[7831, 985],
+        "bbox":[7278.978424270293, 785.4262150656663, 1009.9074541780346, 399.9589428196506]
+      },
+      "ARM":{
+        "shape":[6084, 1267, 6079, 1261, 6078, 1255, 6056, 1252, 6046, 1244, 6040, 1232, 6044, 1217, 6031, 1202, 6067, 1199, 6074, 1196, 6096, 1212, 6094, 1224, 6101, 1230, 6118, 1241, 6119, 1248, 6109, 1250, 6141, 1270, 6147, 1300, 6141, 1300, 6138, 1302, 6122, 1273, 6103, 1276, 6095, 1264, 6084, 1267],
+        "center":[6095, 1245],
+        "bbox":[6030.898496009478, 1195.6967656287209, 116.4629657264868, 106.55051639817816]
+      },
+      "TUN":{
+        "shape":[4965, 1379, 4997, 1364, 4985, 1373, 5001, 1365, 5007, 1368, 5009, 1389, 5016, 1390, 5034, 1373, 5037, 1382, 5015, 1412, 5020, 1426, 5037, 1438, 5039, 1454, 5023, 1480, 5006, 1494, 5006, 1507, 5021, 1522, 5028, 1520, 5028, 1529, 5042, 1525, 5041, 1537, 5049, 1541, 5057, 1544, 5059, 1572, 5017, 1608, 5018, 1647, 5010, 1660, 4996, 1667, 4977, 1584, 4953, 1567, 4952, 1553, 4922, 1512, 4948, 1473, 4948, 1403, 4941, 1397, 4958, 1381, 4965, 1379],
+        "center":[4980, 1473],
+        "bbox":[4922.079876750473, 1363.5750753145583, 137.0840163799794, 302.92798153321405]
+      },
+      "COL":{
+        "shape":[2011, 2928, 2017, 2909, 2010, 2907, 2014, 2902, 2005, 2906, 2001, 2893, 2012, 2880, 2011, 2836, 2004, 2830, 2016, 2825, 2007, 2800, 2016, 2786, 2003, 2762, 1997, 2740, 2003, 2719, 2011, 2725, 2024, 2694, 2029, 2701, 2035, 2722, 2040, 2716, 2034, 2686, 2059, 2664, 2064, 2648, 2080, 2646, 2088, 2589, 2114, 2564, 2125, 2571, 2125, 2582, 2135, 2554, 2169, 2556, 2180, 2542, 2202, 2534, 2207, 2512, 2215, 2515, 2225, 2502, 2240, 2507, 2244, 2519, 2232, 2535, 2213, 2540, 2205, 2 [...]
+        "center":[2170, 2934],
+        "bbox":[1947.8901178096671, 2501.862027473862, 427.3229886471522, 797.7027544947373]
+      },
+      "AZE":{
+        "shape":[[6147, 1300, 6141, 1270, 6109, 1250, 6119, 1248, 6118, 1241, 6101, 1230, 6094, 1224, 6096, 1212, 6074, 1196, 6080, 1192, 6097, 1191, 6108, 1199, 6127, 1201, 6130, 1193, 6114, 1183, 6113, 1174, 6120, 1174, 6155, 1199, 6176, 1187, 6181, 1175, 6189, 1181, 6222, 1222, 6239, 1225, 6253, 1237, 6237, 1233, 6226, 1242, 6224, 1289, 6218, 1279, 6214, 1282, 6214, 1297, 6220, 1315, 6193, 1297, 6201, 1287, 6193, 1283, 6196, 1273, 6186, 1266, 6147, 1300], [6084, 1267, 6095, 1264, 6103 [...]
+        "center":[6109, 1279],
+        "bbox":[6073.659941821466, 1173.6436547070828, 179.2280240943037, 141.18913912927792]
+      },
+      "TUR":{
+        "shape":[[5686, 1176, 5713, 1169, 5756, 1171, 5761, 1165, 5782, 1184, 5797, 1182, 5810, 1200, 5818, 1194, 5846, 1208, 5853, 1204, 5859, 1211, 5875, 1213, 5907, 1205, 5936, 1211, 5965, 1192, 5967, 1188, 5997, 1193, 6006, 1184, 6022, 1191, 6020, 1199, 6031, 1202, 6044, 1217, 6040, 1232, 6046, 1244, 6056, 1252, 6078, 1255, 6079, 1261, 6077, 1268, 6067, 1280, 6085, 1323, 6081, 1338, 6089, 1342, 6104, 1367, 6094, 1373, 6090, 1375, 6087, 1364, 6069, 1366, 6054, 1360, 6038, 1359, 6035,  [...]
+        "center":[5769, 1276],
+        "bbox":[5491.8995868794245, 1164.859774440242, 611.9088370157215, 256.87285698285973]
+      },
+      "POL":{
+        "shape":[5333, 702, 5351, 709, 5352, 719, 5356, 728, 5373, 759, 5351, 776, 5370, 784, 5368, 801, 5369, 804, 5387, 825, 5388, 839, 5353, 871, 5360, 889, 5357, 893, 5320, 878, 5269, 887, 5257, 874, 5242, 877, 5240, 874, 5231, 860, 5209, 858, 5201, 854, 5203, 848, 5178, 842, 5182, 853, 5172, 854, 5162, 843, 5164, 837, 5132, 828, 5128, 824, 5121, 818, 5109, 793, 5107, 765, 5095, 758, 5100, 747, 5091, 727, 5099, 730, 5103, 737, 5105, 717, 5145, 709, 5156, 698, 5191, 688, 5203, 688, 52 [...]
+        "center":[5236, 788],
+        "bbox":[5090.850258973163, 688.0474065197322, 296.74968543248906, 204.6554192500862]
+      },
+      "GEO":{
+        "shape":[5967, 1188, 5976, 1176, 5960, 1141, 5939, 1122, 5920, 1121, 5917, 1110, 5910, 1109, 5907, 1106, 5926, 1106, 5968, 1120, 5998, 1117, 6027, 1134, 6032, 1145, 6074, 1137, 6081, 1147, 6091, 1147, 6091, 1161, 6110, 1168, 6113, 1174, 6114, 1183, 6130, 1193, 6127, 1201, 6108, 1199, 6097, 1191, 6080, 1192, 6074, 1196, 6067, 1199, 6031, 1202, 6020, 1199, 6022, 1191, 6006, 1184, 5997, 1193, 5967, 1188],
+        "center":[6022, 1158],
+        "bbox":[5906.722827964623, 1105.5964030501823, 223.33286412908183, 96.51029584398998]
+      },
+      "GNQ":{
+        "shape":[5025, 2978, 5040, 2989, 5074, 2988, 5078, 3043, 5058, 3038, 5016, 3044, 5008, 3040, 5022, 3006, 5025, 2978],
+        "center":[5036, 3012],
+        "bbox":[5007.705114323948, 2977.5098187064327, 69.85486444494927, 66.74810985129443]
+      },
+      "NGA":{
+        "shape":[5165, 2461, 5168, 2496, 5181, 2506, 5190, 2530, 5171, 2554, 5162, 2548, 5148, 2580, 5147, 2605, 5137, 2613, 5140, 2624, 5125, 2640, 5123, 2671, 5106, 2684, 5093, 2747, 5068, 2779, 5051, 2746, 5045, 2757, 5036, 2758, 5032, 2747, 5016, 2778, 5005, 2783, 4984, 2812, 4985, 2845, 4974, 2866, 4966, 2859, 4966, 2875, 4962, 2876, 4932, 2873, 4926, 2865, 4922, 2870, 4924, 2881, 4915, 2872, 4915, 2880, 4901, 2886, 4900, 2879, 4882, 2877, 4874, 2869, 4864, 2835, 4871, 2837, 4870, 2 [...]
+        "center":[4943, 2667],
+        "bbox":[4772.195621277813, 2423.074991679981, 417.3607193649177, 462.5402897475178]
+      },
+      "PAN":{
+        "shape":[[1939, 2661, 1935, 2676, 1910, 2694, 1925, 2730, 1909, 2740, 1892, 2741, 1890, 2710, 1884, 2712, 1883, 2724, 1872, 2720, 1868, 2700, 1847, 2698, 1850, 2691, 1845, 2697, 1830, 2694, 1828, 2708, 1826, 2708, 1821, 2694, 1833, 2664, 1826, 2657, 1827, 2639, 1831, 2633, 1848, 2640, 1846, 2648, 1852, 2650, 1850, 2660, 1855, 2663, 1866, 2662, 1864, 2650, 1874, 2669, 1885, 2670, 1930, 2639, 1925, 2653, 1930, 2655, 1932, 2647, 1939, 2661], [1936, 2650, 1932, 2639, 1945, 2626, 1984 [...]
+        "center":[1934, 2653],
+        "bbox":[1821.2832958915626, 2626.136402705832, 203.00074963274233, 114.90928328028212]
+      },
+      "TJK":{
+        "shape":[7040, 1354, 7042, 1360, 7031, 1360, 7026, 1352, 7005, 1352, 6970, 1385, 6956, 1375, 6952, 1334, 6941, 1333, 6943, 1322, 6912, 1309, 6901, 1330, 6904, 1347, 6885, 1348, 6884, 1365, 6864, 1365, 6850, 1379, 6833, 1366, 6832, 1354, 6840, 1328, 6839, 1319, 6829, 1312, 6832, 1297, 6797, 1280, 6800, 1268, 6821, 1271, 6847, 1243, 6851, 1245, 6859, 1268, 6893, 1265, 6904, 1275, 6925, 1265, 6935, 1271, 6938, 1282, 6971, 1275, 6985, 1279, 6995, 1285, 7014, 1313, 7028, 1309, 7047, 1 [...]
+        "center":[6931, 1295],
+        "bbox":[6796.735364707334, 1243.2455330459952, 270.4696683725015, 141.65913826009228]
+      },
+      "GNB":{
+        "shape":[4105, 2497, 4155, 2492, 4169, 2482, 4231, 2481, 4201, 2500, 4210, 2518, 4206, 2528, 4183, 2529, 4166, 2559, 4163, 2570, 4159, 2558, 4166, 2545, 4161, 2544, 4155, 2558, 4156, 2550, 4150, 2552, 4146, 2540, 4151, 2537, 4147, 2528, 4165, 2519, 4166, 2512, 4136, 2522, 4133, 2512, 4124, 2517, 4117, 2508, 4123, 2499, 4113, 2506, 4105, 2497],
+        "center":[4172, 2512],
+        "bbox":[4104.509502686356, 2481.456492885939, 126.3604915230053, 88.41377318486639]
+      },
+      "KEN":{
+        "shape":[6043, 3321, 5988, 3265, 5992, 3240, 5871, 3147, 5862, 3146, 5862, 3085, 5900, 3008, 5895, 2967, 5883, 2952, 5875, 2932, 5879, 2914, 5871, 2911, 5867, 2893, 5861, 2886, 5870, 2872, 5925, 2872, 5961, 2879, 6006, 2916, 6056, 2929, 6069, 2897, 6093, 2891, 6102, 2900, 6138, 2900, 6104, 2960, 6105, 3138, 6126, 3177, 6116, 3193, 6099, 3193, 6101, 3208, 6096, 3206, 6091, 3220, 6077, 3226, 6076, 3258, 6070, 3256, 6064, 3289, 6049, 3323, 6043, 3321],
+        "center":[6011, 3074],
+        "bbox":[5861.468691740893, 2871.931416102416, 276.22895407602755, 451.21484910835125]
+      },
+      "GUY":{
+        "shape":[2711, 2828, 2713, 2828, 2710, 2841, 2715, 2856, 2693, 2865, 2682, 2903, 2697, 2926, 2695, 2933, 2710, 2937, 2726, 2996, 2736, 3002, 2706, 3004, 2651, 3043, 2622, 3027, 2623, 3014, 2615, 3011, 2617, 2997, 2608, 2974, 2613, 2924, 2624, 2909, 2608, 2882, 2611, 2859, 2591, 2845, 2587, 2838, 2581, 2838, 2566, 2813, 2580, 2793, 2577, 2779, 2609, 2759, 2596, 2756, 2591, 2741, 2603, 2720, 2609, 2724, 2623, 2706, 2622, 2694, 2639, 2706, 2666, 2747, 2658, 2795, 2664, 2771, 2674, 2 [...]
+        "center":[2648, 2859],
+        "bbox":[2565.76560392434, 2694.106227026502, 169.8264754283823, 348.69292054122934]
+      },
+      "PAK":{
+        "shape":[6960, 1960, 6943, 1951, 6928, 1908, 6911, 1906, 6907, 1887, 6892, 1871, 6871, 1885, 6840, 1885, 6838, 1892, 6820, 1879, 6804, 1882, 6800, 1892, 6766, 1889, 6760, 1899, 6754, 1892, 6745, 1900, 6743, 1891, 6738, 1890, 6733, 1875, 6742, 1843, 6779, 1830, 6777, 1822, 6784, 1821, 6781, 1806, 6764, 1804, 6752, 1758, 6719, 1738, 6698, 1710, 6681, 1684, 6734, 1709, 6769, 1702, 6789, 1706, 6806, 1696, 6820, 1701, 6858, 1684, 6849, 1644, 6865, 1618, 6878, 1625, 6891, 1619, 6888, 1 [...]
+        "center":[6941, 1698],
+        "bbox":[6680.701035977257, 1374.3585246001091, 475.3677331950239, 585.7477936675032]
+      },
+      "MDG":{
+        "shape":[6149, 4118, 6158, 4116, 6189, 4054, 6185, 4050, 6191, 4033, 6184, 4013, 6178, 3939, 6200, 3897, 6200, 3881, 6212, 3884, 6225, 3872, 6238, 3877, 6244, 3864, 6257, 3868, 6263, 3859, 6269, 3873, 6266, 3857, 6287, 3834, 6291, 3840, 6287, 3850, 6300, 3844, 6293, 3837, 6303, 3814, 6308, 3808, 6311, 3817, 6305, 3829, 6321, 3806, 6329, 3809, 6329, 3803, 6317, 3798, 6329, 3787, 6325, 3758, 6334, 3759, 6337, 3771, 6346, 3754, 6357, 3748, 6361, 3706, 6380, 3682, 6383, 3688, 6378, 3 [...]
+        "center":[6268, 4047],
+        "bbox":[6137.574572739937, 3681.661823285401, 273.32816955422913, 632.3818959789646]
+      },
+      "YUG":{
+        "shape":[5375, 1153, 5343, 1164, 5332, 1159, 5321, 1168, 5318, 1172, 5318, 1168, 5304, 1146, 5293, 1147, 5291, 1140, 5281, 1155, 5281, 1172, 5276, 1170, 5259, 1146, 5245, 1145, 5221, 1133, 5223, 1129, 5225, 1129, 5235, 1129, 5251, 1145, 5255, 1141, 5253, 1128, 5277, 1097, 5273, 1088, 5280, 1083, 5266, 1068, 5273, 1054, 5267, 1049, 5262, 1049, 5265, 1043, 5271, 1035, 5256, 1019, 5255, 1015, 5263, 1008, 5287, 1003, 5292, 1003, 5300, 1010, 5313, 1018, 5313, 1029, 5335, 1038, 5339, 1 [...]
+        "center":[5331, 1104],
+        "bbox":[5220.675358945868, 1003.0245739236381, 168.5859338182081, 169.4519132045699]
+      },
+      "VEN":{
+        "shape":[2219, 2567, 2220, 2595, 2199, 2627, 2218, 2663, 2230, 2659, 2238, 2645, 2241, 2624, 2226, 2601, 2226, 2580, 2252, 2559, 2270, 2554, 2275, 2545, 2291, 2547, 2288, 2539, 2273, 2541, 2270, 2531, 2281, 2512, 2287, 2515, 2294, 2546, 2328, 2553, 2343, 2596, 2392, 2587, 2408, 2591, 2414, 2602, 2434, 2613, 2461, 2614, 2477, 2596, 2493, 2596, 2473, 2587, 2555, 2583, 2541, 2594, 2522, 2592, 2523, 2603, 2530, 2602, 2528, 2613, 2537, 2621, 2564, 2623, 2583, 2639, 2591, 2648, 2581, 2 [...]
+        "center":[2441, 2755],
+        "bbox":[2162.227224368718, 2512.4524381120937, 461.2541254267321, 549.8107718528659]
+      },
+      "URY":{
+        "shape":[2821, 4698, 2799, 4673, 2794, 4642, 2803, 4639, 2802, 4626, 2796, 4623, 2786, 4579, 2792, 4573, 2793, 4541, 2787, 4524, 2792, 4511, 2810, 4511, 2815, 4502, 2823, 4505, 2852, 4532, 2858, 4546, 2864, 4550, 2868, 4539, 2875, 4542, 2883, 4558, 2933, 4587, 2944, 4609, 2962, 4619, 2951, 4644, 2963, 4665, 2957, 4670, 2951, 4696, 2917, 4719, 2896, 4712, 2874, 4719, 2873, 4711, 2861, 4711, 2847, 4698, 2821, 4698],
+        "center":[2875, 4635],
+        "bbox":[2785.8827233144034, 4501.935682647792, 177.00598390724463, 217.14171720931427]
+      },
+      "EGY":{
+        "shape":[5504, 1610, 5507, 1615, 5527, 1610, 5562, 1618, 5629, 1642, 5670, 1627, 5675, 1617, 5694, 1619, 5697, 1610, 5710, 1618, 5722, 1616, 5729, 1637, 5737, 1642, 5738, 1626, 5752, 1636, 5763, 1629, 5780, 1633, 5793, 1629, 5806, 1612, 5810, 1607, 5813, 1614, 5806, 1635, 5833, 1700, 5828, 1708, 5819, 1749, 5823, 1767, 5816, 1780, 5780, 1741, 5777, 1722, 5767, 1715, 5752, 1680, 5745, 1697, 5768, 1745, 5792, 1772, 5792, 1789, 5808, 1811, 5859, 1932, 5881, 1955, 5871, 1954, 5873, 1 [...]
+        "center":[5657, 1822],
+        "bbox":[5492.999414324112, 1606.9748388287255, 388.1313990322078, 445.83728800269114]
+      },
+      "HUN":{
+        "shape":[5179, 988, 5170, 976, 5165, 976, 5167, 969, 5178, 969, 5182, 944, 5194, 942, 5195, 933, 5204, 936, 5228, 943, 5245, 939, 5248, 932, 5266, 931, 5270, 924, 5285, 926, 5298, 913, 5320, 911, 5330, 919, 5344, 919, 5355, 924, 5362, 928, 5368, 930, 5341, 953, 5324, 984, 5328, 989, 5312, 998, 5311, 1006, 5292, 1003, 5287, 1003, 5263, 1008, 5255, 1015, 5248, 1011, 5242, 1019, 5216, 1015, 5179, 988],
+        "center":[5255, 963],
+        "bbox":[5165.101370188022, 910.613090570134, 203.0034671894573, 108.47030900620905]
+      },
+      "BLR":{
+        "shape":[5602, 780, 5579, 781, 5567, 808, 5552, 803, 5539, 808, 5531, 800, 5521, 809, 5503, 800, 5489, 806, 5472, 802, 5469, 795, 5432, 788, 5393, 790, 5386, 799, 5372, 798, 5368, 801, 5370, 784, 5351, 776, 5373, 759, 5356, 728, 5352, 719, 5380, 720, 5400, 705, 5412, 711, 5414, 683, 5435, 675, 5431, 663, 5435, 660, 5456, 656, 5472, 642, 5475, 644, 5499, 644, 5508, 656, 5534, 650, 5553, 664, 5549, 684, 5587, 714, 5585, 720, 5616, 729, 5609, 741, 5591, 738, 5576, 745, 5602, 780],
+        "center":[5480, 735],
+        "bbox":[5351.293432755901, 642.0689262807927, 265.13317000940515, 166.61128341276367]
+      },
+      "LIE":{
+        "shape":[4967, 964, 4971, 969, 4967, 970, 4968, 967, 4967, 964],
+        "center":[4969, 966],
+        "bbox":[4966.82649774264, 963.8184292591706, 4.010699168529754, 5.694156462936803]
+      },
+      "MDA":{
+        "shape":[5542, 1030, 5533, 1008, 5534, 980, 5489, 928, 5475, 922, 5480, 917, 5540, 926, 5553, 935, 5554, 951, 5568, 959, 5571, 972, 5581, 976, 5583, 992, 5558, 987, 5542, 1030],
+        "center":[5539, 970],
+        "bbox":[5475.10775787825, 916.5148867901967, 108.31324344014956, 113.96032629355113]
+      },
+      "BDI":{
+        "shape":[5689, 3224, 5699, 3215, 5710, 3232, 5719, 3225, 5721, 3204, 5738, 3205, 5740, 3212, 5742, 3218, 5741, 3240, 5751, 3246, 5751, 3261, 5726, 3304, 5713, 3317, 5701, 3317, 5699, 3297, 5693, 3280, 5699, 3241, 5689, 3224],
+        "center":[5721, 3249],
+        "bbox":[5689.243120396438, 3204.041154968294, 62.18340911027917, 113.33430946812177]
+      },
+      "ALB":{
+        "shape":[5281, 1172, 5281, 1155, 5291, 1140, 5293, 1147, 5304, 1146, 5318, 1168, 5318, 1172, 5329, 1210, 5337, 1213, 5340, 1221, 5330, 1240, 5318, 1244, 5319, 1260, 5309, 1262, 5310, 1258, 5285, 1232, 5291, 1232, 5285, 1218, 5293, 1208, 5287, 1201, 5288, 1174, 5281, 1172],
+        "center":[5307, 1208],
+        "bbox":[5280.602044475761, 1140.1447476260098, 59.62277978066595, 122.30313328749094]
+      },
+      "SAU":{
+        "shape":[5833, 1706, 5868, 1715, 5888, 1683, 5906, 1682, 5925, 1650, 5884, 1613, 5949, 1594, 5956, 1583, 5983, 1590, 6083, 1645, 6089, 1660, 6110, 1661, 6110, 1696, 6153, 1716, 6215, 1717, 6243, 1723, 6257, 1740, 6274, 1735, 6278, 1745, 6295, 1781, 6311, 1790, 6307, 1795, 6318, 1810, 6340, 1824, 6349, 1845, 6342, 1857, 6382, 1925, 6385, 1930, 6409, 1951, 6428, 1998, 6529, 2025, 6542, 2016, 6555, 2043, 6543, 2134, 6446, 2179, 6398, 2198, 6343, 2212, 6268, 2315, 6262, 2314, 6256, 2 [...]
+        "center":[6180, 1954],
+        "bbox":[5825.55733126159, 1582.8447776124297, 729.4324789460879, 732.1507726254438]
+      },
+      "BLZ":{
+        "shape":[1665, 2230, 1673, 2228, 1685, 2207, 1691, 2209, 1688, 2211, 1686, 2216, 1694, 2219, 1676, 2292, 1653, 2326, 1652, 2328, 1643, 2329, 1653, 2238, 1654, 2234, 1665, 2230],
+        "center":[1670, 2269],
+        "bbox":[1642.644935544092, 2207.0875451702163, 51.50976754012004, 121.41509102542659]
+      },
+      "MMR":{
+        "shape":[7786, 2088, 7787, 2070, 7801, 2079, 7789, 2049, 7796, 2028, 7799, 2019, 7804, 2028, 7814, 2015, 7804, 1992, 7809, 1956, 7805, 1935, 7830, 1941, 7839, 1892, 7830, 1885, 7844, 1847, 7843, 1822, 7863, 1797, 7882, 1792, 7897, 1799, 7887, 1783, 7899, 1775, 7896, 1758, 7891, 1753, 7891, 1749, 7913, 1758, 7926, 1793, 7934, 1786, 7947, 1811, 7957, 1869, 7949, 1871, 7949, 1881, 7943, 1880, 7942, 1892, 7933, 1899, 7929, 1919, 7942, 1940, 7936, 1953, 7943, 1960, 7954, 1943, 7963, 1 [...]
+        "center":[7912, 2050],
+        "bbox":[7786.0597679656, 1748.7801724280187, 312.6468855510866, 855.6407872930629]
+      },
+      "TKM":{
+        "shape":[6393, 1361, 6377, 1309, 6379, 1292, 6361, 1276, 6350, 1276, 6329, 1214, 6333, 1220, 6353, 1215, 6357, 1224, 6377, 1221, 6372, 1213, 6384, 1209, 6344, 1162, 6323, 1164, 6315, 1175, 6328, 1206, 6311, 1180, 6307, 1176, 6319, 1158, 6347, 1151, 6378, 1162, 6401, 1195, 6422, 1195, 6454, 1199, 6444, 1174, 6450, 1164, 6473, 1157, 6472, 1148, 6487, 1152, 6478, 1143, 6489, 1136, 6520, 1156, 6538, 1158, 6548, 1192, 6590, 1201, 6588, 1192, 6595, 1192, 6632, 1226, 6640, 1249, 6698, 1 [...]
+        "center":[6502, 1268],
+        "bbox":[6307.101472085723, 1135.7120902021504, 487.4651902426158, 316.53087288025176]
+      },
+      "CMR":{
+        "shape":[4974, 2866, 4985, 2845, 4984, 2812, 5005, 2783, 5016, 2778, 5032, 2747, 5036, 2758, 5045, 2757, 5051, 2746, 5068, 2779, 5093, 2747, 5106, 2684, 5123, 2671, 5125, 2640, 5140, 2624, 5137, 2613, 5147, 2605, 5148, 2580, 5162, 2548, 5171, 2554, 5190, 2530, 5181, 2506, 5168, 2496, 5165, 2461, 5175, 2461, 5194, 2481, 5202, 2563, 5214, 2608, 5173, 2608, 5165, 2622, 5187, 2661, 5203, 2668, 5217, 2715, 5221, 2726, 5200, 2760, 5194, 2783, 5182, 2796, 5189, 2811, 5182, 2838, 5191, 2 [...]
+        "center":[5108, 2842],
+        "bbox":[4974.298834472595, 2460.9036575120167, 268.32973064042835, 548.2683569034643]
+      },
+      "MLI":{
+        "shape":[4516, 1904, 4723, 2089, 4723, 2101, 4744, 2121, 4757, 2121, 4761, 2132, 4789, 2143, 4792, 2157, 4786, 2176, 4797, 2185, 4826, 2174, 4826, 2273, 4820, 2280, 4813, 2332, 4799, 2353, 4786, 2348, 4781, 2357, 4724, 2356, 4716, 2366, 4689, 2369, 4656, 2367, 4646, 2381, 4617, 2386, 4598, 2413, 4583, 2415, 4579, 2436, 4567, 2432, 4568, 2453, 4561, 2453, 4561, 2462, 4545, 2445, 4529, 2457, 4535, 2478, 4525, 2477, 4528, 2486, 4519, 2513, 4504, 2511, 4495, 2520, 4500, 2533, 4493, 2 [...]
+        "center":[4597, 2252],
+        "bbox":[4262.720864353886, 1903.316752573141, 563.307143037232, 698.2687821681475]
+      },
+      "OMN":{
+        "shape":[6446, 2179, 6543, 2134, 6555, 2043, 6542, 2016, 6536, 2000, 6541, 1947, 6561, 1952, 6556, 1937, 6545, 1936, 6539, 1907, 6541, 1899, 6562, 1899, 6566, 1910, 6588, 1945, 6615, 1963, 6644, 1965, 6695, 2027, 6662, 2093, 6659, 2116, 6652, 2114, 6650, 2101, 6645, 2103, 6636, 2147, 6644, 2179, 6611, 2190, 6599, 2233, 6567, 2232, 6561, 2244, 6565, 2262, 6559, 2271, 6528, 2271, 6499, 2285, 6491, 2290, 6446, 2179],
+        "center":[6596, 2100],
+        "bbox":[6445.878710540171, 1899.0006276660358, 249.28470167054093, 391.433184380435]
+      },
+      "GMB":{
+        "shape":[4132, 2439, 4167, 2427, 4188, 2434, 4188, 2443, 4207, 2442, 4194, 2456, 4162, 2438, 4156, 2448, 4139, 2449, 4139, 2457, 4103, 2461, 4103, 2449, 4108, 2445, 4115, 2454, 4142, 2445, 4115, 2450, 4111, 2439, 4132, 2439],
+        "center":[4149, 2440],
+        "bbox":[4103.093425336518, 2426.824436921621, 104.08127067063651, 34.31933284724937]
+      },
+      "NPL":{
+        "shape":[7605, 1821, 7607, 1833, 7590, 1838, 7569, 1829, 7546, 1837, 7518, 1819, 7510, 1824, 7482, 1802, 7414, 1800, 7407, 1786, 7388, 1778, 7384, 1783, 7375, 1771, 7316, 1740, 7315, 1708, 7332, 1677, 7332, 1670, 7346, 1666, 7350, 1675, 7357, 1668, 7388, 1683, 7434, 1725, 7448, 1714, 7455, 1735, 7468, 1737, 7476, 1754, 7483, 1740, 7494, 1760, 7509, 1760, 7526, 1771, 7577, 1763, 7592, 1774, 7594, 1786, 7595, 1805, 7605, 1821],
+        "center":[7460, 1767],
+        "bbox":[7314.844461430826, 1666.2088237580385, 292.1034464749582, 171.76321822066848]
+      },
+      "GTM":{
+        "shape":[1652, 2328, 1660, 2339, 1664, 2328, 1677, 2340, 1640, 2373, 1638, 2388, 1626, 2400, 1626, 2403, 1616, 2419, 1600, 2424, 1594, 2433, 1592, 2430, 1558, 2426, 1555, 2410, 1548, 2416, 1535, 2399, 1539, 2394, 1534, 2397, 1531, 2390, 1543, 2368, 1535, 2356, 1561, 2322, 1602, 2322, 1599, 2291, 1578, 2268, 1595, 2266, 1598, 2237, 1653, 2238, 1643, 2329, 1652, 2328],
+        "center":[1606, 2369],
+        "bbox":[1531.4900489859042, 2237.2044298895503, 145.53133415673187, 196.2665980331276]
+      },
+      "BFA":{
+        "shape":[4687, 2560, 4670, 2555, 4659, 2566, 4655, 2559, 4587, 2559, 4582, 2580, 4587, 2590, 4589, 2628, 4581, 2639, 4575, 2621, 4549, 2615, 4536, 2618, 4529, 2634, 4514, 2636, 4514, 2625, 4501, 2600, 4488, 2597, 4491, 2584, 4493, 2558, 4500, 2533, 4495, 2520, 4504, 2511, 4519, 2513, 4528, 2486, 4525, 2477, 4535, 2478, 4529, 2457, 4545, 2445, 4561, 2462, 4561, 2453, 4568, 2453, 4567, 2432, 4579, 2436, 4583, 2415, 4598, 2413, 4617, 2386, 4646, 2381, 4656, 2367, 4689, 2369, 4689, 2 [...]
+        "center":[4625, 2492],
+        "bbox":[4488.127753949635, 2367.2273587790373, 277.3099543799153, 271.7932566734703]
+      },
+      "CUB":{
+        "shape":[[1841, 2053, 1843, 2045, 1831, 2050, 1829, 2043, 1850, 2040, 1846, 2027, 1859, 2012, 1897, 1992, 1932, 1984, 1964, 1986, 1966, 1993, 1978, 1988, 1992, 2001, 2008, 2000, 2018, 2023, 2040, 2021, 2042, 2034, 2051, 2028, 2082, 2065, 2077, 2046, 2107, 2079, 2113, 2073, 2133, 2081, 2136, 2086, 2130, 2102, 2158, 2101, 2180, 2123, 2140, 2137, 2057, 2139, 2059, 2132, 2079, 2116, 2075, 2100, 2046, 2097, 2036, 2087, 2039, 2069, 2033, 2060, 1994, 2056, 1980, 2034, 1977, 2041, 1959,  [...]
+        "center":[2054, 2059],
+        "bbox":[1829.108201060054, 1984.4477961842647, 350.9616716130922, 154.82307510726127]
+      },
+      "USA":{
+        "shape":[[2378, 1224, 2399, 1211, 2426, 1210, 2439, 1202, 2443, 1209, 2451, 1206, 2402, 1224, 2378, 1224], [388, 356, 465, 340, 474, 343, 489, 336, 523, 329, 545, 331, 519, 339, 521, 343, 562, 343, 563, 347, 589, 337, 594, 339, 584, 345, 599, 337, 597, 335, 574, 338, 588, 330, 589, 326, 580, 326, 593, 320, 592, 332, 607, 331, 609, 335, 638, 334, 633, 330, 655, 329, 639, 327, 608, 330, 598, 327, 617, 319, 597, 318, 607, 314, 597, 310, 623, 298, 654, 293, 616, 300, 597, 309, 604, 3 [...]
+        "center":[1633, 1301],
+        "bbox":[0.0, 211.50992636996918, 2652.968037718645, 1692.545909509037]
+      },
+      "NZL":{
+        "shape":[[9705, 5176, 9724, 5171, 9720, 5165, 9730, 5157, 9738, 5157, 9742, 5149, 9784, 5129, 9818, 5105, 9868, 5087, 9932, 5055, 9981, 5014, 10010, 4999, 10026, 4980, 10056, 4964, 10051, 4976, 10059, 4978, 10049, 4994, 10081, 4981, 10068, 4995, 10082, 4991, 10076, 4991, 10086, 4984, 10094, 4984, 10074, 4995, 10093, 4988, 10072, 5001, 10071, 5013, 10005, 5057, 9975, 5073, 9962, 5085, 9974, 5087, 9970, 5093, 9948, 5094, 9958, 5092, 9952, 5089, 9897, 5114, 9877, 5135, 9835, 5165, 9 [...]
+        "center":[10087, 4969],
+        "bbox":[9701.393740572821, 4699.5448918788925, 628.6001624787314, 500.5070673390337]
+      },
+      "GUF":{
+        "shape":[2898, 2908, 2872, 2966, 2867, 2991, 2845, 3003, 2841, 2996, 2811, 3001, 2797, 2986, 2807, 2960, 2815, 2922, 2806, 2913, 2798, 2875, 2819, 2822, 2823, 2823, 2859, 2842, 2886, 2887, 2889, 2877, 2898, 2908],
+        "center":[2842, 2916],
+        "bbox":[2797.197339786994, 2822.0265039832484, 101.29430110887733, 180.69424957758838]
+      },
+      "LAO":{
+        "shape":[8205, 2202, 8185, 2198, 8177, 2219, 8166, 2228, 8142, 2211, 8117, 2245, 8111, 2240, 8113, 2212, 8107, 2198, 8112, 2170, 8104, 2147, 8080, 2151, 8075, 2140, 8078, 2122, 8067, 2112, 8059, 2113, 8053, 2107, 8069, 2075, 8078, 2070, 8084, 2068, 8087, 2082, 8102, 2078, 8100, 2059, 8089, 2042, 8089, 2025, 8105, 2027, 8123, 2049, 8139, 2050, 8139, 2072, 8152, 2096, 8187, 2095, 8200, 2103, 8201, 2116, 8208, 2116, 8219, 2136, 8211, 2158, 8204, 2149, 8195, 2153, 8197, 2168, 8259, 2 [...]
+        "center":[8142, 2133],
+        "bbox":[8053.227835231009, 2025.3959407632171, 295.9104210104424, 403.9148763113333]
+      },
+      "KWT":{
+        "shape":[6252, 1676, 6260, 1695, 6248, 1706, 6261, 1710, 6271, 1729, 6274, 1735, 6257, 1740, 6243, 1723, 6215, 1717, 6232, 1676, 6252, 1676],
+        "center":[6250, 1705],
+        "bbox":[6214.654890796342, 1675.9234902298476, 59.065035810161135, 63.9208951170001]
+      },
+      "JOR":{
+        "shape":[5935, 1530, 5956, 1583, 5949, 1594, 5884, 1613, 5925, 1650, 5906, 1682, 5888, 1683, 5868, 1715, 5833, 1706, 5833, 1700, 5835, 1669, 5830, 1664, 5836, 1620, 5819, 1617, 5820, 1578, 5825, 1571, 5839, 1571, 5836, 1558, 5852, 1567, 5879, 1577, 5935, 1530],
+        "center":[5862, 1627],
+        "bbox":[5819.010046231332, 1529.9853516509918, 137.33988125372252, 185.47481183629907]
+      },
+      "PHL":{
+        "shape":[[8771, 2219, 8767, 2211, 8775, 2203, 8777, 2209, 8785, 2205, 8813, 2224, 8824, 2209, 8830, 2219, 8825, 2231, 8827, 2249, 8833, 2265, 8840, 2265, 8846, 2292, 8839, 2326, 8839, 2315, 8822, 2331, 8825, 2345, 8821, 2358, 8837, 2387, 8838, 2403, 8861, 2428, 8858, 2412, 8874, 2406, 8890, 2423, 8891, 2436, 8898, 2434, 8894, 2418, 8919, 2430, 8921, 2435, 8908, 2442, 8918, 2467, 8934, 2470, 8934, 2492, 8923, 2483, 8927, 2474, 8903, 2471, 8897, 2450, 8872, 2425, 8867, 2425, 8882,  [...]
+        "center":[8904, 2451],
+        "bbox":[8757.75118932903, 2202.5604641655877, 289.41334168898175, 624.8605971678594]
+      },
+      "ZMB":{
+        "shape":[5483, 3938, 5473, 3930, 5433, 3870, 5437, 3722, 5511, 3724, 5504, 3710, 5510, 3692, 5511, 3632, 5501, 3624, 5513, 3620, 5524, 3628, 5524, 3648, 5532, 3650, 5556, 3633, 5555, 3656, 5579, 3669, 5600, 3673, 5618, 3658, 5631, 3684, 5653, 3702, 5658, 3697, 5677, 3740, 5699, 3730, 5699, 3742, 5704, 3739, 5708, 3684, 5695, 3686, 5692, 3698, 5662, 3664, 5675, 3567, 5667, 3542, 5686, 3509, 5746, 3497, 5748, 3509, 5773, 3519, 5779, 3533, 5807, 3542, 5810, 3550, 5820, 3552, 5824, 3 [...]
+        "center":[5591, 3799],
+        "bbox":[5432.561736011266, 3496.5612051906483, 417.0281929071525, 457.0949739651205]
+      },
+      "BEN":{
+        "shape":[4739, 2787, 4734, 2771, 4736, 2654, 4724, 2627, 4729, 2614, 4709, 2595, 4709, 2558, 4728, 2534, 4765, 2522, 4762, 2516, 4766, 2508, 4764, 2500, 4779, 2491, 4796, 2512, 4806, 2512, 4807, 2520, 4803, 2546, 4809, 2553, 4811, 2583, 4802, 2591, 4802, 2613, 4794, 2620, 4789, 2648, 4778, 2656, 4772, 2709, 4777, 2724, 4775, 2783, 4762, 2787, 4739, 2787],
+        "center":[4758, 2603],
+        "bbox":[4708.945024191102, 2490.9381864448064, 102.00702641762382, 296.4861975818594]
+      },
+      "UKR":{
+        "shape":[[5828, 964, 5822, 969, 5824, 964, 5808, 965, 5788, 982, 5781, 976, 5751, 990, 5744, 981, 5749, 992, 5741, 989, 5725, 1005, 5713, 997, 5711, 1003, 5704, 998, 5691, 1005, 5663, 1004, 5640, 997, 5644, 988, 5657, 989, 5643, 981, 5645, 971, 5639, 983, 5630, 983, 5630, 975, 5624, 983, 5607, 986, 5602, 975, 5604, 999, 5589, 993, 5598, 1001, 5597, 1010, 5582, 1020, 5577, 1016, 5583, 1031, 5582, 1036, 5569, 1031, 5553, 1042, 5543, 1037, 5542, 1030, 5558, 987, 5583, 992, 5581, 976 [...]
+        "center":[5615, 875],
+        "bbox":[5343.354528386237, 771.5508310826132, 525.4285363430272, 300.0002056854004]
+      },
+      "NIC":{
+        "shape":[1842, 2372, 1834, 2378, 1837, 2399, 1819, 2442, 1820, 2491, 1815, 2494, 1813, 2477, 1814, 2497, 1807, 2517, 1811, 2527, 1803, 2548, 1804, 2564, 1809, 2567, 1811, 2571, 1795, 2577, 1785, 2564, 1736, 2560, 1735, 2557, 1676, 2467, 1688, 2469, 1689, 2467, 1706, 2466, 1707, 2446, 1721, 2429, 1730, 2430, 1740, 2416, 1748, 2424, 1764, 2403, 1774, 2402, 1777, 2385, 1787, 2375, 1797, 2387, 1817, 2381, 1827, 2370, 1842, 2372],
+        "center":[1767, 2483],
+        "bbox":[1676.2249087237765, 2369.7892777965826, 166.13649401248585, 207.42875496798797]
+      },
+      "BEL":{
+        "shape":[4866, 855, 4857, 856, 4859, 868, 4857, 873, 4845, 875, 4831, 867, 4830, 853, 4811, 860, 4804, 845, 4793, 847, 4780, 833, 4762, 829, 4759, 821, 4764, 817, 4776, 812, 4803, 815, 4807, 808, 4831, 807, 4851, 817, 4846, 828, 4853, 830, 4855, 831, 4867, 832, 4873, 847, 4866, 855],
+        "center":[4822, 837],
+        "bbox":[4758.871630703705, 806.8799895809777, 113.7192582858188, 68.45424032015762]
+      },
+      "NAM":{
+        "shape":[5541, 3943, 5536, 3951, 5510, 3956, 5486, 3978, 5479, 3959, 5417, 3975, 5399, 3972, 5389, 4142, 5355, 4142, 5350, 4269, 5341, 4435, 5314, 4447, 5310, 4457, 5302, 4451, 5284, 4456, 5258, 4450, 5257, 4427, 5240, 4420, 5222, 4442, 5200, 4422, 5187, 4388, 5184, 4347, 5178, 4344, 5178, 4273, 5166, 4244, 5171, 4232, 5166, 4211, 5168, 4200, 5179, 4203, 5177, 4180, 5172, 4179, 5135, 4093, 5131, 4065, 5105, 3996, 5094, 3984, 5084, 3946, 5082, 3922, 5093, 3915, 5110, 3924, 5131, 3 [...]
+        "center":[5253, 4166],
+        "bbox":[5082.459503224306, 3910.298436916151, 458.29594979193917, 546.540635676803]
+      },
+      "PRY":{
+        "shape":[2685, 4016, 2715, 4039, 2720, 4058, 2734, 4095, 2733, 4148, 2772, 4155, 2786, 4144, 2811, 4154, 2831, 4226, 2843, 4234, 2859, 4220, 2869, 4230, 2868, 4247, 2865, 4298, 2867, 4321, 2867, 4339, 2838, 4383, 2809, 4390, 2758, 4378, 2744, 4382, 2740, 4371, 2751, 4347, 2750, 4328, 2760, 4307, 2761, 4283, 2679, 4230, 2668, 4235, 2640, 4223, 2573, 4149, 2574, 4148, 2579, 4145, 2585, 4069, 2593, 4054, 2597, 4026, 2685, 4016],
+        "center":[2741, 4211],
+        "bbox":[2573.0972955792327, 4016.0393056544453, 295.9098682870422, 374.4369398419658]
+      },
+      "SUR":{
+        "shape":[2819, 2822, 2798, 2875, 2806, 2913, 2815, 2922, 2807, 2960, 2797, 2986, 2790, 2984, 2785, 2975, 2764, 2987, 2753, 2980, 2744, 2991, 2749, 3011, 2736, 3002, 2726, 2996, 2710, 2937, 2695, 2933, 2697, 2926, 2682, 2903, 2693, 2865, 2715, 2856, 2710, 2841, 2713, 2828, 2714, 2809, 2755, 2822, 2762, 2807, 2779, 2820, 2781, 2809, 2793, 2809, 2819, 2822],
+        "center":[2755, 2901],
+        "bbox":[2682.2249769487294, 2807.3374420655227, 136.4845417928027, 203.52999956048916]
+      },
+      "CAF":{
+        "shape":[5243, 2987, 5237, 2976, 5240, 2949, 5205, 2909, 5207, 2883, 5193, 2870, 5191, 2843, 5182, 2838, 5189, 2811, 5182, 2796, 5194, 2783, 5200, 2760, 5221, 2726, 5227, 2734, 5251, 2711, 5260, 2726, 5292, 2703, 5302, 2706, 5336, 2692, 5343, 2675, 5336, 2661, 5385, 2646, 5403, 2631, 5428, 2593, 5437, 2565, 5463, 2559, 5469, 2567, 5478, 2580, 5497, 2619, 5492, 2654, 5495, 2671, 5518, 2668, 5518, 2693, 5543, 2699, 5545, 2708, 5551, 2709, 5554, 2727, 5564, 2743, 5577, 2749, 5590, 2 [...]
+        "center":[5409, 2773],
+        "bbox":[5181.779061807174, 2559.4471924418103, 445.6875460216761, 427.9821919067008]
+      },
+      "PRT":{
+        "shape":[4411, 1170, 4430, 1164, 4433, 1177, 4471, 1170, 4487, 1185, 4465, 1210, 4467, 1251, 4461, 1264, 4448, 1265, 4461, 1291, 4453, 1318, 4461, 1323, 4448, 1346, 4451, 1363, 4447, 1366, 4434, 1373, 4409, 1367, 4397, 1372, 4404, 1355, 4406, 1315, 4410, 1317, 4406, 1308, 4394, 1311, 4400, 1293, 4385, 1303, 4385, 1298, 4388, 1274, 4397, 1269, 4415, 1222, 4411, 1170],
+        "center":[4425, 1275],
+        "bbox":[4384.949633313986, 1164.4058042880167, 102.18823908720424, 208.43788971485333]
+      },
+      "AUS":{
+        "shape":[[8438, 4305, 8445, 4351, 8453, 4354, 8460, 4339, 8452, 4317, 8455, 4305, 8460, 4318, 8456, 4330, 8464, 4330, 8464, 4346, 8469, 4343, 8477, 4320, 8464, 4258, 8492, 4209, 8494, 4178, 8516, 4137, 8510, 4173, 8518, 4163, 8522, 4167, 8537, 4138, 8568, 4122, 8599, 4093, 8624, 4078, 8621, 4086, 8645, 4089, 8669, 4071, 8693, 4065, 8705, 4051, 8721, 4056, 8751, 4048, 8786, 4026, 8811, 3983, 8834, 3967, 8836, 3962, 8828, 3962, 8835, 3952, 8830, 3942, 8840, 3920, 8853, 3914, 8852,  [...]
+        "center":[9153, 4235],
+        "bbox":[8381.434621446073, 3624.0785928493515, 1379.1447407585947, 1457.5855414028947]
+      },
+      "ESH":{
+        "shape":[4245, 1783, 4395, 1783, 4394, 1795, 4390, 1862, 4277, 1862, 4274, 1976, 4258, 1976, 4241, 1989, 4234, 2014, 4241, 2075, 4105, 2073, 4108, 2053, 4113, 2031, 4130, 2012, 4129, 2001, 4137, 1995, 4133, 1989, 4154, 1958, 4152, 1952, 4184, 1914, 4197, 1852, 4220, 1837, 4245, 1783],
+        "center":[4213, 1921],
+        "bbox":[4105.406250341965, 1783.1980742815347, 289.3262647234005, 291.9324707033404]
+      },
+      "TZA":{
+        "shape":[5742, 3218, 5740, 3212, 5747, 3214, 5756, 3197, 5751, 3183, 5755, 3175, 5741, 3145, 5750, 3141, 5758, 3146, 5862, 3146, 5871, 3147, 5992, 3240, 5988, 3265, 6043, 3321, 6041, 3343, 6030, 3389, 6032, 3409, 6055, 3442, 6044, 3467, 6048, 3481, 6041, 3512, 6048, 3529, 6042, 3535, 6053, 3553, 6053, 3591, 6057, 3584, 6058, 3595, 6070, 3595, 6073, 3600, 6033, 3637, 5987, 3640, 5971, 3656, 5940, 3661, 5919, 3644, 5908, 3655, 5889, 3657, 5877, 3635, 5878, 3589, 5866, 3564, 5858, 3 [...]
+        "center":[5906, 3462],
+        "bbox":[5699.761630932435, 3141.3387213131614, 373.1579378952338, 519.5916448196717]
+      },
+      "ISR":{
+        "shape":[5833, 1700, 5806, 1635, 5813, 1614, 5810, 1607, 5809, 1595, 5817, 1550, 5818, 1544, 5837, 1532, 5837, 1542, 5837, 1551, 5836, 1558, 5839, 1571, 5825, 1571, 5820, 1578, 5819, 1617, 5836, 1620, 5830, 1664, 5835, 1669, 5833, 1700],
+        "center":[5815, 1589],
+        "bbox":[5805.516501996854, 1531.9814200881708, 33.14028171528207, 167.56906094374722]
+      },
+      "BGD":{
+        "shape":[7684, 2037, 7659, 1984, 7663, 1977, 7652, 1977, 7652, 1965, 7640, 1952, 7652, 1935, 7613, 1909, 7620, 1901, 7626, 1906, 7632, 1894, 7647, 1894, 7646, 1882, 7613, 1859, 7615, 1829, 7628, 1839, 7634, 1830, 7643, 1831, 7648, 1846, 7671, 1861, 7679, 1892, 7701, 1900, 7751, 1893, 7764, 1905, 7761, 1922, 7736, 1943, 7740, 1982, 7746, 1986, 7752, 1978, 7753, 1986, 7761, 1988, 7759, 1966, 7765, 1958, 7759, 1949, 7770, 1950, 7779, 1960, 7777, 1968, 7796, 2028, 7789, 2049, 7801, 2 [...]
+        "center":[7687, 1937],
+        "bbox":[7612.623087532001, 1829.4818420782003, 188.1030116015163, 258.41550799121296]
+      },
+      "MKD":{
+        "shape":[5375, 1153, 5392, 1170, 5397, 1187, 5395, 1191, 5394, 1191, 5391, 1199, 5370, 1198, 5362, 1207, 5337, 1213, 5329, 1210, 5318, 1172, 5321, 1168, 5332, 1159, 5343, 1164, 5375, 1153],
+        "center":[5357, 1185],
+        "bbox":[5318.281521050181, 1153.323515884402, 78.54535748739454, 59.72581663441292]
+      },
+      "KAZ":{
+        "shape":[6307, 1176, 6301, 1163, 6308, 1140, 6279, 1133, 6266, 1120, 6255, 1122, 6253, 1106, 6227, 1078, 6210, 1070, 6219, 1062, 6252, 1067, 6229, 1055, 6240, 1036, 6300, 1036, 6279, 1026, 6282, 996, 6274, 975, 6255, 973, 6250, 979, 6217, 966, 6205, 976, 6194, 974, 6181, 992, 6162, 992, 6160, 996, 6133, 986, 6151, 981, 6140, 960, 6115, 943, 6092, 943, 6084, 925, 6063, 916, 6074, 890, 6064, 880, 6071, 844, 6109, 865, 6117, 858, 6102, 836, 6112, 835, 6124, 827, 6121, 820, 6150, 808 [...]
+        "center":[6697, 903],
+        "bbox":[6063.207665972857, 666.8200643571338, 1202.1888704395833, 545.2966395453805]
+      },
+      "SDN":{
+        "shape":[5878, 1993, 5888, 2012, 5925, 2042, 5953, 2195, 5985, 2220, 5994, 2227, 5984, 2251, 5974, 2251, 5962, 2272, 5946, 2276, 5932, 2365, 5935, 2394, 5936, 2408, 5933, 2427, 5921, 2477, 5907, 2481, 5892, 2524, 5889, 2565, 5885, 2575, 5872, 2569, 5864, 2582, 5861, 2675, 5855, 2689, 5831, 2687, 5826, 2710, 5849, 2717, 5868, 2752, 5878, 2754, 5892, 2773, 5899, 2827, 5907, 2838, 5920, 2836, 5920, 2857, 5925, 2872, 5870, 2872, 5861, 2886, 5841, 2912, 5825, 2906, 5799, 2914, 5763, 2 [...]
+        "center":[5701, 2420],
+        "bbox":[5431.883544399925, 1993.4219975417097, 562.3889197745348, 926.0641392695973]
+      },
+      "SLE":{
+        "shape":[4221, 2651, 4241, 2642, 4253, 2612, 4294, 2610, 4316, 2667, 4310, 2672, 4313, 2700, 4327, 2683, 4326, 2687, 4326, 2699, 4315, 2705, 4311, 2727, 4287, 2759, 4273, 2749, 4277, 2745, 4236, 2725, 4256, 2724, 4238, 2718, 4230, 2692, 4225, 2694, 4220, 2684, 4235, 2679, 4223, 2677, 4222, 2667, 4234, 2665, 4221, 2651],
+        "center":[4267, 2679],
+        "bbox":[4219.888209343912, 2610.208480378272, 106.6630877305679, 149.20823445217047]
+      },
+      "ISL":{
+        "shape":[4075, 349, 4081, 345, 4093, 348, 4088, 340, 4101, 345, 4109, 343, 4102, 342, 4112, 340, 4094, 338, 4112, 339, 4098, 336, 4097, 333, 4107, 334, 4105, 329, 4121, 333, 4121, 337, 4124, 333, 4126, 338, 4130, 335, 4130, 339, 4134, 331, 4119, 328, 4134, 327, 4118, 326, 4120, 322, 4135, 322, 4152, 333, 4161, 333, 4154, 335, 4161, 335, 4160, 340, 4148, 340, 4160, 344, 4155, 349, 4161, 348, 4165, 356, 4170, 345, 4186, 343, 4185, 331, 4193, 329, 4209, 339, 4211, 331, 4227, 326, 42 [...]
+        "center":[4236, 364],
+        "bbox":[4074.66165608179, 315.6993926460826, 292.5579923807245, 89.48186509435828]
+      },
+      "LSO":{
+        "shape":[5571, 4489, 5610, 4444, 5614, 4450, 5628, 4444, 5653, 4471, 5633, 4514, 5609, 4517, 5597, 4535, 5576, 4510, 5571, 4489],
+        "center":[5611, 4484],
+        "bbox":[5571.444959177591, 4443.553536597868, 81.15444223504073, 91.14629949176287]
+      },
+      "GHA":{
+        "shape":[4579, 2849, 4588, 2850, 4590, 2818, 4575, 2818, 4566, 2764, 4579, 2740, 4578, 2710, 4593, 2692, 4587, 2652, 4591, 2643, 4589, 2628, 4587, 2590, 4582, 2580, 4587, 2559, 4655, 2559, 4659, 2566, 4670, 2555, 4687, 2560, 4685, 2570, 4681, 2572, 4683, 2580, 4689, 2581, 4696, 2598, 4695, 2624, 4689, 2635, 4699, 2633, 4701, 2661, 4694, 2673, 4709, 2686, 4701, 2697, 4701, 2761, 4719, 2797, 4711, 2803, 4708, 2814, 4699, 2812, 4652, 2844, 4624, 2851, 4609, 2867, 4579, 2849],
+        "center":[4646, 2710],
+        "bbox":[4565.6282914856765, 2554.6581205457596, 153.36719015757808, 312.27681420489625]
+      },
+      "PRI":{
+        "shape":[2403, 2209, 2409, 2202, 2449, 2205, 2461, 2209, 2461, 2217, 2440, 2231, 2403, 2231, 2403, 2209],
+        "center":[2427, 2216],
+        "bbox":[2402.668720127526, 2201.9242795326195, 58.4361287019542, 29.20489110995277]
+      },
+      "DNK":{
+        "shape":[4910, 644, 4915, 636, 4909, 628, 4925, 634, 4935, 621, 4936, 630, 4944, 632, 4939, 617, 4970, 616, 4968, 627, 4989, 635, 4973, 642, 4966, 657, 4955, 659, 4956, 685, 4953, 688, 4928, 686, 4928, 682, 4927, 668, 4912, 663, 4918, 652, 4910, 644],
+        "center":[4944, 648],
+        "bbox":[4909.028649416544, 616.0540782717756, 79.75464719535012, 71.63129442120226]
+      },
+      "BOL":{
+        "shape":[2292, 3622, 2318, 3621, 2326, 3630, 2339, 3622, 2346, 3605, 2357, 3608, 2393, 3572, 2426, 3570, 2432, 3560, 2439, 3590, 2432, 3602, 2439, 3627, 2438, 3648, 2471, 3686, 2468, 3694, 2520, 3703, 2524, 3713, 2555, 3726, 2567, 3744, 2614, 3761, 2621, 3791, 2621, 3819, 2616, 3817, 2634, 3870, 2697, 3871, 2695, 3891, 2701, 3916, 2725, 3934, 2723, 3945, 2730, 3958, 2722, 4033, 2728, 4046, 2720, 4058, 2715, 4039, 2685, 4016, 2597, 4026, 2593, 4054, 2585, 4069, 2579, 4145, 2574, 4 [...]
+        "center":[2468, 3882],
+        "bbox":[2291.99230779228, 3560.046554268744, 437.9135374662337, 623.8188287102744]
+      },
+      "THA":{
+        "shape":[7982, 2199, 7996, 2195, 7992, 2181, 7996, 2139, 8005, 2146, 8024, 2141, 8028, 2125, 8041, 2123, 8039, 2111, 8050, 2110, 8053, 2107, 8059, 2113, 8067, 2112, 8078, 2122, 8075, 2140, 8080, 2151, 8104, 2147, 8112, 2170, 8107, 2198, 8113, 2212, 8111, 2240, 8117, 2245, 8142, 2211, 8166, 2228, 8177, 2219, 8185, 2198, 8205, 2202, 8208, 2206, 8238, 2244, 8245, 2286, 8260, 2306, 8271, 2308, 8275, 2323, 8282, 2327, 8279, 2341, 8287, 2357, 8287, 2379, 8275, 2395, 8273, 2395, 8269, 2 [...]
+        "center":[8131, 2328],
+        "bbox":[7982.256676790092, 2107.421843558334, 304.59665347668124, 710.2693053495309]
+      },
+      "DEU":{
+        "shape":[4855, 831, 4866, 810, 4861, 794, 4877, 791, 4889, 780, 4889, 773, 4877, 768, 4889, 763, 4892, 743, 4894, 743, 4888, 731, 4913, 727, 4918, 738, 4922, 731, 4930, 731, 4931, 721, 4969, 733, 4938, 719, 4939, 706, 4928, 706, 4941, 701, 4931, 692, 4928, 686, 4953, 688, 4955, 689, 4964, 690, 4964, 702, 4985, 707, 5004, 699, 4993, 720, 5002, 716, 5007, 720, 5015, 711, 5052, 705, 5073, 711, 5076, 723, 5087, 726, 5091, 727, 5100, 747, 5095, 758, 5107, 765, 5109, 793, 5121, 818, 51 [...]
+        "center":[4980, 812],
+        "bbox":[4855.438764937289, 686.2009418827183, 272.7640807796997, 274.5929849337042]
+      },
+      "LKA":{
+        "shape":[7440, 2636, 7459, 2631, 7468, 2644, 7505, 2730, 7504, 2779, 7490, 2795, 7466, 2804, 7451, 2798, 7437, 2762, 7434, 2707, 7440, 2636],
+        "center":[7464, 2708],
+        "bbox":[7433.549181145625, 2630.8513175457665, 71.12205192901456, 173.52509314739837]
+      },
+      "AND":{
+        "shape":[4736, 1144, 4736, 1148, 4736, 1149, 4727, 1146, 4728, 1143, 4731, 1141, 4736, 1144],
+        "center":[4731, 1147],
+        "bbox":[4727.081822101, 1141.351895530791, 8.713232428558513, 7.514827341301498]
+      },
+      "LBN":{
+        "shape":[5837, 1475, 5852, 1476, 5859, 1492, 5843, 1512, 5843, 1529, 5837, 1532, 5818, 1544, 5818, 1539, 5837, 1475],
+        "center":[5836, 1508],
+        "bbox":[5818.105606508412, 1474.9070176017592, 40.598731269822565, 69.08139713759897]
+      },
+      "ITA":{
+        "shape":[[5087, 1329, 5092, 1333, 5102, 1325, 5110, 1334, 5133, 1333, 5170, 1321, 5160, 1354, 5168, 1371, 5164, 1386, 5141, 1380, 5135, 1368, 5118, 1366, 5099, 1351, 5079, 1345, 5079, 1334, 5087, 1329], [4937, 1216, 4970, 1197, 4984, 1221, 4982, 1283, 4962, 1276, 4961, 1294, 4945, 1285, 4949, 1251, 4944, 1252, 4945, 1229, 4937, 1216], [4912, 1097, 4918, 1079, 4908, 1082, 4892, 1076, 4897, 1058, 4887, 1045, 4898, 1032, 4890, 1015, 4906, 1016, 4909, 1012, 4922, 1009, 4935, 992, 495 [...]
+        "center":[5086, 1144],
+        "bbox":[4887.496687570328, 968.770278196411, 371.8489967643545, 417.22325820693777]
+      },
+      "SLV":{
+        "shape":[1626, 2403, 1647, 2407, 1659, 2424, 1680, 2423, 1684, 2439, 1680, 2446, 1677, 2447, 1671, 2449, 1669, 2460, 1644, 2457, 1649, 2461, 1596, 2435, 1594, 2433, 1600, 2424, 1616, 2419, 1626, 2403],
+        "center":[1646, 2434],
+        "bbox":[1594.3826022179019, 2403.2083163464094, 89.28988583355522, 58.10794918342708]
+      },
+      "LBR":{
+        "shape":[4287, 2759, 4311, 2727, 4315, 2705, 4326, 2699, 4326, 2687, 4348, 2684, 4353, 2708, 4348, 2737, 4359, 2734, 4367, 2743, 4387, 2723, 4386, 2736, 4388, 2763, 4381, 2780, 4388, 2779, 4391, 2790, 4410, 2790, 4407, 2804, 4423, 2820, 4413, 2861, 4418, 2883, 4413, 2883, 4354, 2844, 4323, 2795, 4312, 2790, 4308, 2780, 4291, 2770, 4293, 2760, 4287, 2759],
+        "center":[4361, 2780],
+        "bbox":[4286.892195584021, 2684.262131158614, 136.15580955087535, 198.99797283294083]
+      },
+      "CAN":{
+        "shape":[[883, 507, 1247, 251, 1250, 251, 1285, 251, 1281, 253, 1298, 255, 1301, 262, 1306, 259, 1306, 263, 1326, 271, 1345, 268, 1369, 275, 1361, 268, 1377, 267, 1376, 279, 1386, 275, 1382, 266, 1406, 259, 1442, 255, 1464, 248, 1473, 249, 1497, 243, 1499, 246, 1512, 241, 1548, 237, 1548, 242, 1443, 258, 1407, 269, 1408, 273, 1414, 272, 1410, 269, 1430, 270, 1425, 267, 1443, 263, 1431, 266, 1430, 264, 1478, 254, 1469, 258, 1490, 253, 1485, 257, 1493, 256, 1477, 263, 1510, 251, 15 [...]
+        "center":[1751, 553],
+        "bbox":[880.4695830070514, 201.97286835057287, 2206.840477810584, 965.7035845341583]
+      },
+      "PRK":{
+        "shape":[8590, 1226, 8607, 1213, 8613, 1176, 8625, 1189, 8664, 1195, 8663, 1184, 8647, 1174, 8648, 1168, 8666, 1173, 8674, 1153, 8687, 1153, 8681, 1130, 8717, 1154, 8713, 1157, 8702, 1184, 8713, 1193, 8721, 1214, 8709, 1220, 8712, 1230, 8698, 1236, 8703, 1241, 8699, 1244, 8685, 1245, 8675, 1257, 8686, 1276, 8679, 1272, 8680, 1279, 8705, 1291, 8719, 1302, 8715, 1317, 8706, 1310, 8686, 1317, 8686, 1337, 8678, 1334, 8663, 1338, 8655, 1332, 8651, 1345, 8650, 1336, 8645, 1341, 8642, 1 [...]
+        "center":[8649, 1270],
+        "bbox":[8570.744965193502, 1129.8058721948908, 150.1823173234443, 215.29534469286773]
+      },
+      "LBY":{
+        "shape":[5057, 1544, 5087, 1559, 5115, 1556, 5173, 1575, 5199, 1622, 5249, 1633, 5311, 1669, 5322, 1666, 5341, 1638, 5332, 1603, 5338, 1582, 5383, 1552, 5424, 1561, 5433, 1566, 5433, 1578, 5441, 1584, 5482, 1595, 5488, 1591, 5499, 1602, 5503, 1607, 5495, 1626, 5501, 1642, 5493, 1669, 5504, 1710, 5525, 2042, 5527, 2133, 5495, 2134, 5495, 2156, 5221, 1978, 5186, 1997, 5158, 2013, 5112, 1979, 5084, 1969, 5067, 1936, 5029, 1925, 5016, 1906, 5013, 1877, 4995, 1847, 5011, 1822, 5007, 1 [...]
+        "center":[5273, 1808],
+        "bbox":[4991.005544070228, 1543.549552360056, 536.4607802488326, 612.3944045222918]
+      },
+      "GIN":{
+        "shape":[4166, 2559, 4183, 2529, 4206, 2528, 4210, 2518, 4201, 2500, 4231, 2481, 4236, 2487, 4254, 2498, 4285, 2485, 4290, 2475, 4287, 2503, 4294, 2510, 4306, 2503, 4317, 2518, 4331, 2502, 4344, 2511, 4357, 2499, 4352, 2493, 4357, 2486, 4367, 2489, 4377, 2513, 4374, 2521, 4396, 2542, 4389, 2554, 4396, 2561, 4396, 2588, 4403, 2591, 4406, 2602, 4403, 2622, 4411, 2656, 4408, 2665, 4416, 2676, 4411, 2684, 4399, 2679, 4396, 2694, 4407, 2699, 4398, 2727, 4387, 2723, 4367, 2743, 4359, 2 [...]
+        "center":[4320, 2570],
+        "bbox":[4166.07630278407, 2474.9629141460114, 250.0461702740913, 268.38451934741624]
+      },
+      "IRQ":{
+        "shape":[5935, 1530, 5998, 1487, 6003, 1465, 6001, 1398, 6019, 1391, 6029, 1374, 6035, 1370, 6038, 1359, 6054, 1360, 6069, 1366, 6087, 1364, 6090, 1375, 6094, 1373, 6104, 1367, 6114, 1397, 6122, 1400, 6130, 1420, 6166, 1426, 6155, 1438, 6161, 1450, 6143, 1486, 6156, 1520, 6173, 1532, 6170, 1546, 6195, 1554, 6210, 1568, 6219, 1568, 6238, 1604, 6237, 1631, 6243, 1631, 6271, 1675, 6266, 1677, 6256, 1675, 6252, 1676, 6232, 1676, 6215, 1717, 6153, 1716, 6110, 1696, 6110, 1661, 6089, 1 [...]
+        "center":[6074, 1536],
+        "bbox":[5934.878097338688, 1359.4480739306916, 335.6778562872287, 357.90139025708413]
+      },
+      "ETH":{
+        "shape":[6140, 2495, 6121, 2528, 6125, 2559, 6162, 2561, 6154, 2583, 6180, 2639, 6193, 2644, 6202, 2659, 6313, 2708, 6342, 2707, 6240, 2859, 6209, 2855, 6178, 2869, 6170, 2886, 6147, 2891, 6138, 2900, 6102, 2900, 6093, 2891, 6069, 2897, 6056, 2929, 6006, 2916, 5961, 2879, 5925, 2872, 5920, 2857, 5920, 2836, 5907, 2838, 5899, 2827, 5892, 2773, 5878, 2754, 5868, 2752, 5849, 2717, 5826, 2710, 5831, 2687, 5855, 2689, 5861, 2675, 5864, 2582, 5872, 2569, 5885, 2575, 5889, 2565, 5892, 2 [...]
+        "center":[6045, 2689],
+        "bbox":[5826.324879822536, 2383.4393348737217, 515.2422125702042, 545.6017543770445]
+      },
+      "IRN":{
+        "shape":[6104, 1367, 6089, 1342, 6081, 1338, 6085, 1323, 6067, 1280, 6077, 1268, 6079, 1261, 6084, 1267, 6091, 1278, 6128, 1299, 6138, 1302, 6141, 1300, 6147, 1300, 6186, 1266, 6196, 1273, 6193, 1283, 6201, 1287, 6193, 1297, 6220, 1315, 6227, 1334, 6237, 1351, 6271, 1359, 6294, 1381, 6321, 1391, 6337, 1393, 6389, 1379, 6382, 1384, 6387, 1387, 6401, 1381, 6395, 1369, 6393, 1361, 6417, 1360, 6435, 1331, 6462, 1329, 6473, 1320, 6495, 1322, 6503, 1336, 6529, 1349, 6547, 1347, 6561, 1 [...]
+        "center":[6463, 1569],
+        "bbox":[6066.867892445741, 1260.9212588837365, 716.9648814618804, 637.7299554731696]
+      },
+      "SEN":{
+        "shape":[4116, 2315, 4124, 2295, 4173, 2289, 4201, 2297, 4210, 2314, 4226, 2315, 4228, 2339, 4243, 2345, 4256, 2374, 4264, 2377, 4263, 2396, 4268, 2405, 4264, 2432, 4269, 2451, 4279, 2449, 4290, 2475, 4285, 2485, 4254, 2498, 4236, 2487, 4231, 2481, 4169, 2482, 4155, 2492, 4105, 2497, 4103, 2490, 4146, 2487, 4149, 2476, 4102, 2485, 4104, 2469, 4103, 2461, 4139, 2457, 4139, 2449, 4156, 2448, 4162, 2438, 4194, 2456, 4207, 2442, 4188, 2443, 4188, 2434, 4167, 2427, 4132, 2439, 4111, 2 [...]
+        "center":[4177, 2370],
+        "bbox":[4082.2139764936996, 2288.711525933239, 208.22642695421337, 209.38148067857992]
+      },
+      "GIB":{
+        "shape":[4510, 1414, 4510, 1414, 4514, 1408, 4514, 1409, 4510, 1414],
+        "center":[4512, 1411],
+        "bbox":[4510.1747043083815, 1408.3622523861727, 4.038277763155747, 5.547132038636619]
+      },
+      "NCL":{
+        "shape":[10216, 4066, 10229, 4064, 10252, 4090, 10256, 4112, 10288, 4149, 10287, 4161, 10282, 4166, 10265, 4155, 10232, 4116, 10216, 4066],
+        "center":[10250, 4117],
+        "bbox":[10216.313439039344, 4064.0996185780723, 72.01138387901119, 101.77185412615381]
+      },
+      "MYS":{
+        "shape":[[8479, 2987, 8484, 2985, 8485, 2996, 8493, 3002, 8508, 3006, 8508, 2998, 8510, 3008, 8514, 3002, 8514, 3009, 8536, 3018, 8532, 3007, 8539, 3008, 8533, 2998, 8539, 2985, 8549, 2982, 8535, 2981, 8537, 2971, 8546, 2974, 8544, 2958, 8597, 2938, 8628, 2885, 8626, 2871, 8633, 2872, 8648, 2896, 8654, 2894, 8654, 2865, 8664, 2854, 8661, 2871, 8671, 2887, 8667, 2855, 8673, 2858, 8681, 2844, 8672, 2835, 8679, 2823, 8680, 2829, 8688, 2827, 8696, 2812, 8692, 2805, 8701, 2797, 8715,  [...]
+        "center":[8633, 2935],
+        "bbox":[8136.311374251308, 2758.793703438498, 672.4256008349976, 279.85978833062927]
+      },
+      "IRL":{
+        "shape":[4479, 681, 4461, 690, 4465, 693, 4455, 701, 4456, 705, 4471, 713, 4485, 703, 4497, 715, 4504, 713, 4506, 714, 4512, 752, 4499, 775, 4503, 781, 4464, 785, 4455, 793, 4440, 792, 4439, 799, 4415, 806, 4400, 807, 4409, 797, 4390, 802, 4403, 793, 4385, 794, 4398, 783, 4381, 782, 4390, 776, 4403, 778, 4399, 772, 4407, 767, 4433, 763, 4425, 759, 4419, 765, 4398, 768, 4419, 745, 4427, 744, 4393, 737, 4409, 724, 4398, 710, 4440, 709, 4437, 706, 4452, 697, 4435, 692, 4448, 687, 44 [...]
+        "center":[4459, 745],
+        "bbox":[4380.87299884991, 671.0226046056159, 131.00371353197988, 135.81943130192087]
+      },
+      "BWA":{
+        "shape":[5536, 3951, 5568, 4001, 5575, 4031, 5592, 4053, 5603, 4056, 5607, 4074, 5623, 4076, 5621, 4100, 5627, 4121, 5661, 4129, 5668, 4146, 5671, 4152, 5644, 4170, 5633, 4168, 5610, 4199, 5598, 4206, 5577, 4246, 5554, 4268, 5532, 4314, 5522, 4319, 5484, 4312, 5466, 4293, 5450, 4292, 5428, 4336, 5419, 4338, 5415, 4353, 5407, 4352, 5401, 4365, 5391, 4360, 5370, 4366, 5376, 4323, 5363, 4281, 5350, 4269, 5355, 4142, 5389, 4142, 5399, 3972, 5417, 3975, 5479, 3959, 5486, 3978, 5510, 3 [...]
+        "center":[5493, 4143],
+        "bbox":[5349.631808035779, 3950.6679722162626, 321.7557671769064, 414.8806321981938]
+      },
+      "DOM":{
+        "shape":[2247, 2210, 2258, 2194, 2250, 2188, 2259, 2180, 2259, 2148, 2260, 2147, 2265, 2137, 2275, 2142, 2288, 2135, 2320, 2147, 2322, 2164, 2343, 2167, 2328, 2174, 2351, 2178, 2368, 2198, 2357, 2217, 2319, 2205, 2304, 2219, 2292, 2217, 2291, 2208, 2275, 2213, 2262, 2244, 2249, 2238, 2250, 2226, 2249, 2223, 2249, 2211, 2247, 2210],
+        "center":[2298, 2181],
+        "bbox":[2246.7787967384215, 2135.337599459228, 121.21297850229712, 108.9859999380592]
+      },
+      "GRL":{
+        "shape":[[3097, 82, 3114, 80, 3118, 78, 3151, 76, 3217, 67, 3279, 66, 3303, 58, 3296, 56, 3311, 55, 3306, 53, 3292, 52, 3322, 49, 3314, 48, 3311, 50, 3261, 53, 3242, 51, 3242, 47, 3259, 45, 3268, 42, 3292, 40, 3292, 37, 3304, 35, 3316, 36, 3329, 41, 3330, 39, 3322, 38, 3312, 35, 3319, 34, 3347, 36, 3366, 35, 3360, 34, 3360, 32, 3370, 32, 3373, 29, 3364, 29, 3350, 25, 3371, 23, 3438, 30, 3388, 21, 3460, 18, 3476, 20, 3480, 20, 3478, 18, 3501, 18, 3485, 16, 3524, 15, 3541, 19, 3548 [...]
+        "center":[3791, 123],
+        "bbox":[3095.7602803922355, 0.0, 1432.168371630005, 515.8694615082119]
+      },
+      "GAB":{
+        "shape":[5074, 2988, 5075, 2978, 5144, 2979, 5146, 2987, 5148, 2996, 5138, 3003, 5147, 3026, 5175, 3026, 5182, 3035, 5183, 3050, 5168, 3079, 5169, 3107, 5188, 3120, 5183, 3145, 5186, 3186, 5171, 3215, 5158, 3197, 5153, 3210, 5135, 3208, 5126, 3187, 5116, 3180, 5110, 3210, 5086, 3202, 5084, 3225, 5097, 3242, 5097, 3270, 5093, 3275, 5083, 3262, 5065, 3283, 5061, 3274, 5022, 3219, 5029, 3223, 5036, 3216, 5016, 3213, 5005, 3189, 5015, 3190, 5004, 3182, 5013, 3173, 5005, 3168, 5008, 3 [...]
+        "center":[5082, 3130],
+        "bbox":[4982.681713913008, 2978.100323053436, 205.28715906571597, 305.2964243307488]
+      },
+      "BGR":{
+        "shape":[5506, 1180, 5494, 1179, 5497, 1193, 5473, 1197, 5447, 1183, 5395, 1191, 5397, 1187, 5392, 1170, 5375, 1153, 5381, 1150, 5374, 1135, 5389, 1120, 5369, 1099, 5374, 1086, 5378, 1084, 5386, 1086, 5386, 1099, 5428, 1106, 5451, 1099, 5470, 1103, 5505, 1085, 5533, 1086, 5542, 1094, 5554, 1095, 5555, 1100, 5555, 1111, 5538, 1116, 5541, 1138, 5527, 1146, 5544, 1162, 5546, 1169, 5534, 1173, 5524, 1165, 5503, 1173, 5506, 1180],
+        "center":[5463, 1153],
+        "bbox":[5368.750418308241, 1083.620120681092, 186.62622679828473, 112.97242533728786]
+      },
+      "AUT":{
+        "shape":[5098, 989, 5062, 983, 5050, 975, 5052, 969, 5029, 969, 5013, 978, 4998, 973, 4994, 972, 4987, 977, 4971, 969, 4967, 970, 4968, 967, 4966, 962, 4969, 953, 4966, 949, 4981, 949, 4991, 961, 4996, 949, 5023, 957, 5033, 947, 5048, 952, 5049, 942, 5074, 953, 5076, 946, 5068, 943, 5074, 933, 5070, 927, 5093, 911, 5093, 906, 5105, 914, 5112, 908, 5119, 910, 5129, 895, 5191, 907, 5189, 912, 5191, 929, 5195, 933, 5194, 942, 5182, 944, 5178, 969, 5167, 969, 5165, 976, 5163, 977, 51 [...]
+        "center":[5118, 951],
+        "bbox":[4966.274073734857, 895.1012768419246, 229.1265338340918, 98.91703776709039]
+      },
+      "EST":{
+        "shape":[[5284, 553, 5300, 547, 5311, 554, 5301, 559, 5284, 553], [5290, 586, 5292, 578, 5282, 573, 5282, 566, 5286, 569, 5308, 562, 5320, 567, 5294, 575, 5290, 586], [5352, 586, 5354, 569, 5343, 575, 5333, 572, 5325, 563, 5334, 558, 5322, 556, 5321, 543, 5372, 530, 5416, 537, 5445, 535, 5450, 538, 5426, 555, 5431, 563, 5446, 580, 5439, 595, 5441, 598, 5414, 597, 5386, 583, 5353, 588, 5352, 586]],
+        "center":[5296, 571],
+        "bbox":[5281.803849387679, 530.4278273720681, 167.88715326023157, 67.56251323542938]
+      },
+      "HND":{
+        "shape":[1626, 2400, 1638, 2388, 1640, 2373, 1677, 2340, 1679, 2341, 1685, 2330, 1716, 2336, 1755, 2326, 1751, 2321, 1767, 2330, 1781, 2323, 1796, 2334, 1809, 2330, 1824, 2351, 1811, 2340, 1804, 2353, 1812, 2351, 1825, 2363, 1832, 2359, 1829, 2352, 1840, 2370, 1842, 2372, 1827, 2370, 1817, 2381, 1797, 2387, 1787, 2375, 1777, 2385, 1774, 2402, 1764, 2403, 1748, 2424, 1740, 2416, 1730, 2430, 1721, 2429, 1707, 2446, 1706, 2466, 1689, 2467, 1689, 2465, 1687, 2448, 1682, 2445, 1680, 2 [...]
+        "center":[1718, 2380],
+        "bbox":[1626.014041172775, 2320.705367197133, 216.3473615634873, 145.99709574148255]
+      },
+      "MRT":{
+        "shape":[4394, 1795, 4516, 1904, 4459, 1903, 4486, 2299, 4499, 2306, 4491, 2345, 4362, 2347, 4362, 2339, 4355, 2339, 4354, 2350, 4332, 2348, 4317, 2337, 4306, 2358, 4287, 2335, 4286, 2345, 4277, 2343, 4273, 2379, 4264, 2377, 4256, 2374, 4243, 2345, 4228, 2339, 4226, 2315, 4210, 2314, 4201, 2297, 4173, 2289, 4124, 2295, 4116, 2315, 4117, 2292, 4135, 2236, 4133, 2206, 4121, 2167, 4127, 2161, 4122, 2155, 4132, 2125, 4104, 2080, 4105, 2073, 4241, 2075, 4234, 2014, 4241, 1989, 4258, 1 [...]
+        "center":[4317, 2164],
+        "bbox":[4104.006063789865, 1795.4821675970672, 412.3360779074528, 583.6092147137877]
+      },
+      "ESP":{
+        "shape":[4736, 1148, 4768, 1155, 4779, 1150, 4781, 1171, 4749, 1196, 4709, 1210, 4709, 1220, 4682, 1247, 4671, 1274, 4689, 1302, 4666, 1319, 4656, 1344, 4661, 1347, 4635, 1355, 4614, 1385, 4607, 1378, 4596, 1385, 4540, 1385, 4534, 1393, 4522, 1394, 4514, 1408, 4514, 1408, 4510, 1414, 4510, 1414, 4491, 1406, 4488, 1389, 4476, 1373, 4455, 1365, 4451, 1363, 4448, 1346, 4461, 1323, 4453, 1318, 4461, 1291, 4448, 1265, 4461, 1264, 4467, 1251, 4465, 1210, 4487, 1185, 4471, 1170, 4433, 1 [...]
+        "center":[4574, 1239],
+        "bbox":[4398.5478495422685, 1097.6412394005126, 382.4121742600837, 316.2755146696252]
+      },
+      "SWZ":{
+        "shape":[5743, 4385, 5722, 4388, 5702, 4360, 5720, 4318, 5726, 4314, 5744, 4326, 5748, 4321, 5743, 4385],
+        "center":[5728, 4356],
+        "bbox":[5702.29494651405, 4314.235882766303, 45.77203804917917, 73.7078762335932]
+      },
+      "ECU":{
+        "shape":[1907, 3262, 1918, 3258, 1927, 3222, 1914, 3223, 1916, 3214, 1906, 3229, 1886, 3211, 1882, 3205, 1890, 3196, 1885, 3175, 1889, 3163, 1882, 3150, 1895, 3143, 1900, 3128, 1897, 3117, 1917, 3084, 1911, 3077, 1910, 3058, 1957, 3035, 1957, 3028, 1988, 3063, 2003, 3058, 2009, 3079, 2027, 3088, 2032, 3080, 2038, 3086, 2051, 3079, 2063, 3100, 2075, 3116, 2083, 3125, 2084, 3145, 2073, 3148, 2068, 3177, 2051, 3201, 2001, 3236, 1983, 3261, 1975, 3259, 1966, 3314, 1953, 3341, 1935, 3 [...]
+        "center":[1950, 3181],
+        "bbox":[1881.5918672303133, 3027.663087873165, 202.31334596474198, 312.94688769130425]
+      },
+      "ZAF":{
+        "shape":[[5571, 4489, 5576, 4510, 5597, 4535, 5609, 4517, 5633, 4514, 5653, 4471, 5628, 4444, 5614, 4450, 5610, 4444, 5571, 4489], [5222, 4442, 5240, 4420, 5257, 4427, 5258, 4450, 5284, 4456, 5302, 4451, 5310, 4457, 5314, 4447, 5341, 4435, 5350, 4269, 5363, 4281, 5376, 4323, 5370, 4366, 5391, 4360, 5401, 4365, 5407, 4352, 5415, 4353, 5419, 4338, 5428, 4336, 5450, 4292, 5466, 4293, 5484, 4312, 5522, 4319, 5532, 4314, 5554, 4268, 5577, 4246, 5598, 4206, 5610, 4199, 5633, 4168, 5644 [...]
+        "center":[5469, 4496],
+        "bbox":[5221.988399441961, 4148.893191676245, 550.8066930559589, 572.618586273944]
+      },
+      "DZA":{
+        "shape":[4610, 1462, 4638, 1446, 4653, 1428, 4686, 1423, 4705, 1401, 4765, 1392, 4776, 1381, 4825, 1376, 4851, 1390, 4882, 1370, 4903, 1378, 4912, 1370, 4946, 1381, 4958, 1381, 4941, 1397, 4948, 1403, 4948, 1473, 4922, 1512, 4952, 1553, 4953, 1567, 4977, 1584, 4996, 1667, 4991, 1673, 5005, 1709, 5010, 1740, 5006, 1756, 5012, 1773, 5007, 1798, 5011, 1822, 4995, 1847, 5013, 1877, 5016, 1906, 5029, 1925, 5067, 1936, 5084, 1969, 4958, 2076, 4928, 2097, 4875, 2154, 4826, 2174, 4797, 2 [...]
+        "center":[4775, 1761],
+        "bbox":[4394.102502510359, 1369.9210769067863, 689.7373813442273, 815.2476691279007]
+      },
+      "PER":{
+        "shape":[2311, 3941, 2315, 3952, 2313, 3962, 2295, 3972, 2277, 3959, 2276, 3950, 2255, 3941, 2253, 3923, 2229, 3912, 2217, 3895, 2173, 3873, 2153, 3856, 2146, 3857, 2115, 3832, 2114, 3823, 2072, 3776, 2068, 3761, 2073, 3741, 2048, 3690, 2034, 3681, 2032, 3659, 2016, 3640, 1997, 3588, 1990, 3583, 1970, 3512, 1940, 3470, 1942, 3463, 1921, 3422, 1904, 3401, 1893, 3401, 1877, 3388, 1881, 3376, 1890, 3376, 1890, 3368, 1876, 3353, 1881, 3339, 1872, 3322, 1873, 3306, 1903, 3267, 1907, 3 [...]
+        "center":[2076, 3567],
+        "bbox":[1871.7996352414234, 3099.5332318517358, 464.152238452099, 872.4514394767316]
+      },
+      "GRC":{
+        "shape":[[5518, 1461, 5475, 1464, 5475, 1456, 5461, 1451, 5436, 1449, 5436, 1438, 5439, 1431, 5461, 1445, 5504, 1445, 5505, 1453, 5523, 1453, 5518, 1461], [5374, 1322, 5409, 1337, 5425, 1353, 5427, 1358, 5418, 1359, 5401, 1350, 5419, 1398, 5403, 1384, 5400, 1399, 5395, 1397, 5384, 1371, 5379, 1371, 5378, 1387, 5372, 1384, 5365, 1367, 5369, 1355, 5351, 1336, 5358, 1326, 5374, 1322], [5337, 1213, 5362, 1207, 5370, 1198, 5391, 1199, 5394, 1191, 5395, 1191, 5447, 1183, 5473, 1197, 54 [...]
+        "center":[5363, 1266],
+        "bbox":[5309.420535869092, 1178.5207017442406, 213.97415152663143, 285.1809543769209]
+      },
+      "FRA":{
+        "shape":[[4728, 1143, 4713, 1129, 4704, 1129, 4699, 1138, 4671, 1139, 4629, 1112, 4636, 1109, 4643, 1100, 4645, 1064, 4651, 1061, 4646, 1061, 4648, 1028, 4664, 1047, 4661, 1032, 4644, 1022, 4648, 998, 4631, 992, 4617, 966, 4622, 960, 4608, 962, 4613, 954, 4563, 937, 4552, 942, 4543, 932, 4554, 927, 4546, 923, 4560, 924, 4553, 919, 4541, 923, 4542, 914, 4594, 902, 4606, 914, 4626, 907, 4641, 911, 4627, 869, 4645, 869, 4647, 882, 4679, 887, 4693, 882, 4691, 872, 4732, 853, 4730, 82 [...]
+        "center":[4775, 979],
+        "bbox":[4540.948109275762, 821.3659486794832, 435.9258865458278, 370.6015921719679]
+      },
+      "LUX":{
+        "shape":[4876, 880, 4871, 878, 4858, 877, 4857, 873, 4859, 868, 4857, 856, 4866, 855, 4867, 858, 4882, 866, 4877, 873, 4876, 880],
+        "center":[4868, 868],
+        "bbox":[4856.640132276516, 855.0583089504248, 25.422708521956338, 24.687943367650632]
+      },
+      "ZWE":{
+        "shape":[5740, 4162, 5724, 4156, 5698, 4159, 5681, 4149, 5671, 4152, 5668, 4146, 5661, 4129, 5627, 4121, 5621, 4100, 5623, 4076, 5607, 4074, 5603, 4056, 5592, 4053, 5575, 4031, 5568, 4001, 5536, 3951, 5541, 3943, 5566, 3951, 5600, 3954, 5624, 3923, 5666, 3896, 5669, 3873, 5679, 3858, 5697, 3849, 5718, 3847, 5723, 3868, 5752, 3867, 5809, 3902, 5807, 3973, 5803, 3992, 5790, 4006, 5797, 4009, 5794, 4028, 5804, 4046, 5781, 4087, 5772, 4120, 5740, 4162],
+        "center":[5708, 4011],
+        "bbox":[5535.754411696438, 3846.5596641593274, 273.2529991718802, 315.9365109845221]
+      },
+      "GBR":{
+        "shape":[[4511, 625, 4522, 622, 4521, 616, 4530, 611, 4531, 603, 4521, 600, 4527, 599, 4524, 588, 4539, 585, 4533, 581, 4535, 575, 4547, 575, 4547, 563, 4552, 568, 4557, 564, 4601, 564, 4596, 573, 4573, 584, 4578, 591, 4561, 599, 4592, 591, 4634, 596, 4621, 620, 4594, 637, 4604, 634, 4611, 640, 4578, 646, 4610, 646, 4640, 662, 4649, 696, 4667, 699, 4681, 712, 4689, 730, 4666, 726, 4681, 729, 4691, 740, 4694, 746, 4685, 755, 4694, 759, 4700, 752, 4716, 754, 4732, 761, 4728, 787, 4 [...]
+        "center":[4640, 748],
+        "bbox":[4454.554321330179, 562.7796491577859, 277.0039183425861, 297.1407832980069]
+      },
+      "CHE":{
+        "shape":[4967, 964, 4968, 967, 4967, 970, 4971, 969, 4971, 969, 4987, 977, 4994, 972, 4998, 973, 4997, 974, 4998, 989, 4985, 989, 4990, 1000, 4962, 991, 4956, 1017, 4935, 992, 4922, 1009, 4909, 1012, 4906, 1016, 4897, 1011, 4887, 994, 4872, 995, 4874, 1000, 4863, 1005, 4862, 995, 4890, 968, 4891, 954, 4912, 951, 4915, 949, 4925, 950, 4933, 950, 4941, 940, 4961, 947, 4966, 949, 4969, 953, 4966, 962, 4967, 964],
+        "center":[4932, 975],
+        "bbox":[4862.16852929492, 939.8370506373739, 135.54081264822617, 77.05738003532099]
+      },
+      "VNM":{
+        "shape":[8267, 2589, 8275, 2578, 8287, 2582, 8305, 2566, 8314, 2572, 8321, 2557, 8311, 2549, 8312, 2528, 8366, 2494, 8359, 2472, 8363, 2452, 8356, 2426, 8346, 2405, 8349, 2390, 8347, 2353, 8334, 2355, 8336, 2324, 8314, 2302, 8307, 2306, 8300, 2277, 8265, 2248, 8259, 2230, 8197, 2168, 8195, 2153, 8204, 2149, 8211, 2158, 8219, 2136, 8208, 2116, 8201, 2116, 8200, 2103, 8187, 2095, 8152, 2096, 8139, 2072, 8139, 2050, 8123, 2049, 8105, 2027, 8113, 2012, 8136, 2027, 8141, 2011, 8164, 2 [...]
+        "center":[8386, 2421],
+        "bbox":[8105.069236810904, 1985.4909694804903, 324.2861349003897, 694.1511310217913]
+      },
+      "BHS":{
+        "shape":[[2104, 1821, 2118, 1819, 2132, 1835, 2120, 1866, 2115, 1860, 2123, 1853, 2128, 1835, 2117, 1820, 2104, 1821], [2201, 2088, 2212, 2077, 2222, 2080, 2228, 2072, 2221, 2089, 2201, 2088], [2068, 1829, 2075, 1835, 2083, 1824, 2105, 1831, 2075, 1839, 2068, 1829], [2084, 1954, 2094, 1941, 2092, 1962, 2085, 1962, 2084, 1954], [2130, 1886, 2135, 1879, 2150, 1897, 2146, 1922, 2141, 1911, 2146, 1910, 2148, 1897, 2130, 1886], [2159, 1919, 2171, 1945, 2162, 1945, 2168, 1939, 2159, 19 [...]
+        "center":[2151, 1920],
+        "bbox":[2067.7058115577124, 1818.9683060527998, 160.42815098229175, 270.3973537277177]
+      },
+      "AGO":{
+        "shape":[[5259, 3391, 5268, 3442, 5292, 3486, 5348, 3481, 5359, 3455, 5360, 3433, 5386, 3435, 5389, 3428, 5397, 3431, 5398, 3449, 5432, 3447, 5438, 3506, 5431, 3554, 5433, 3567, 5444, 3576, 5451, 3614, 5444, 3615, 5445, 3639, 5457, 3627, 5479, 3631, 5494, 3620, 5501, 3624, 5511, 3632, 5510, 3692, 5504, 3710, 5511, 3724, 5437, 3722, 5433, 3870, 5473, 3930, 5483, 3938, 5390, 3961, 5326, 3951, 5304, 3929, 5159, 3931, 5141, 3912, 5131, 3910, 5110, 3924, 5093, 3915, 5082, 3922, 5082,  [...]
+        "center":[5278, 3673],
+        "bbox":[5081.923683948653, 3310.0090202977717, 429.282899761939, 651.3825228357491]
+      },
+      "LVA":{
+        "shape":[5271, 645, 5267, 621, 5282, 596, 5307, 591, 5328, 613, 5340, 616, 5355, 609, 5353, 590, 5353, 588, 5386, 583, 5414, 597, 5441, 598, 5449, 602, 5450, 616, 5465, 625, 5472, 641, 5472, 642, 5456, 656, 5435, 660, 5430, 658, 5399, 641, 5387, 643, 5375, 633, 5360, 638, 5298, 634, 5271, 645],
+        "center":[5355, 619],
+        "bbox":[5266.560106508288, 582.5124272477984, 205.8048536198894, 77.63700264039437]
+      },
+      "SWE":{
+        "shape":[4987, 546, 5001, 553, 5004, 521, 5020, 520, 5025, 505, 5010, 485, 5026, 483, 5028, 477, 5008, 466, 4998, 411, 5015, 399, 5045, 399, 5050, 395, 5035, 383, 5054, 365, 5049, 341, 5074, 336, 5070, 331, 5099, 316, 5085, 306, 5097, 294, 5116, 290, 5128, 294, 5130, 279, 5137, 277, 5178, 283, 5178, 265, 5189, 266, 5271, 293, 5267, 304, 5276, 307, 5273, 315, 5286, 323, 5280, 333, 5299, 349, 5287, 349, 5259, 347, 5246, 360, 5228, 361, 5237, 368, 5224, 377, 5239, 388, 5217, 405, 51 [...]
+        "center":[5103, 428],
+        "bbox":[4987.015572029185, 265.4011947979404, 312.2017359431138, 403.1216261123048]
+      },
+      "CHL":{
+        "shape":[2404, 5198, 2416, 5179, 2424, 5179, 2422, 5167, 2413, 5174, 2411, 5165, 2427, 5166, 2432, 5173, 2430, 5164, 2443, 5168, 2438, 5177, 2447, 5172, 2440, 5180, 2434, 5176, 2446, 5180, 2443, 5184, 2434, 5180, 2437, 5187, 2429, 5185, 2443, 5194, 2449, 5182, 2455, 5185, 2450, 5177, 2457, 5181, 2456, 5201, 2466, 5173, 2460, 5184, 2455, 5168, 2466, 5157, 2454, 5161, 2453, 5148, 2459, 5146, 2471, 5156, 2473, 5148, 2447, 5143, 2468, 5113, 2466, 5105, 2463, 5112, 2442, 5099, 2451, 5 [...]
+        "center":[2378, 4794],
+        "bbox":[2294.696967627778, 3926.9263834293365, 409.5140564701014, 1534.5119720527878]
+      },
+      "CZE":{
+        "shape":[5191, 907, 5129, 895, 5119, 910, 5112, 908, 5105, 914, 5093, 906, 5091, 902, 5074, 894, 5056, 877, 5052, 862, 5033, 849, 5044, 852, 5089, 830, 5105, 829, 5105, 821, 5120, 829, 5128, 824, 5132, 828, 5164, 837, 5162, 843, 5172, 854, 5182, 853, 5178, 842, 5203, 848, 5201, 854, 5209, 858, 5231, 860, 5240, 874, 5232, 874, 5223, 892, 5191, 907],
+        "center":[5144, 865],
+        "bbox":[5033.18481093142, 821.2078697871904, 207.2457114021454, 92.40669308404063]
+      },
+      "CHN":{
+        "shape":[[7279, 890, 7288, 908, 7327, 933, 7385, 950, 7423, 986, 7432, 1009, 7430, 1029, 7442, 1041, 7522, 1050, 7575, 1074, 7596, 1076, 7598, 1086, 7653, 1138, 7679, 1136, 7751, 1146, 7785, 1142, 7825, 1149, 7840, 1160, 7899, 1177, 7919, 1174, 7924, 1183, 7941, 1185, 7996, 1149, 8055, 1149, 8083, 1137, 8093, 1111, 8111, 1097, 8084, 1074, 8084, 1044, 8113, 1055, 8143, 1057, 8159, 1031, 8190, 1029, 8199, 1020, 8198, 1000, 8219, 995, 8218, 987, 8230, 990, 8238, 981, 8274, 986, 8289 [...]
+        "center":[7939, 1459],
+        "bbox":[6984.5682788075665, 733.6198193010806, 1761.2370839265004, 1489.3938979059308]
+      },
+      "TGO":{
+        "shape":[4719, 2797, 4701, 2761, 4701, 2697, 4709, 2686, 4694, 2673, 4701, 2661, 4699, 2633, 4689, 2635, 4695, 2624, 4696, 2598, 4689, 2581, 4683, 2580, 4681, 2572, 4685, 2570, 4687, 2560, 4697, 2566, 4709, 2558, 4709, 2595, 4729, 2614, 4724, 2627, 4736, 2654, 4734, 2771, 4739, 2787, 4719, 2797],
+        "center":[4716, 2668],
+        "bbox":[4680.729794044019, 2558.137882828665, 58.759197328264236, 238.9979204198371]
+      },
+      "CIV":{
+        "shape":[4418, 2883, 4413, 2861, 4423, 2820, 4407, 2804, 4410, 2790, 4391, 2790, 4388, 2779, 4381, 2780, 4388, 2763, 4386, 2736, 4387, 2723, 4398, 2727, 4407, 2699, 4396, 2694, 4399, 2679, 4411, 2684, 4416, 2676, 4408, 2665, 4411, 2656, 4403, 2622, 4406, 2602, 4413, 2600, 4416, 2589, 4424, 2587, 4428, 2600, 4443, 2601, 4450, 2579, 4456, 2583, 4468, 2573, 4472, 2587, 4466, 2597, 4477, 2598, 4479, 2588, 4491, 2584, 4488, 2597, 4501, 2600, 4514, 2625, 4514, 2636, 4529, 2634, 4536, 2 [...]
+        "center":[4483, 2742],
+        "bbox":[4381.313910911819, 2572.515185718861, 211.89302126126313, 310.74491827269367]
+      },
+      "ERI":{
+        "shape":[6164, 2483, 6152, 2497, 6147, 2489, 6140, 2495, 6121, 2457, 6099, 2443, 6090, 2422, 6057, 2398, 6027, 2399, 6022, 2390, 6003, 2402, 5983, 2383, 5977, 2385, 5968, 2410, 5936, 2408, 5935, 2394, 5932, 2365, 5946, 2276, 5962, 2272, 5974, 2251, 5984, 2251, 5994, 2227, 6010, 2258, 6023, 2297, 6022, 2314, 6033, 2347, 6043, 2358, 6043, 2368, 6046, 2372, 6050, 2354, 6063, 2378, 6068, 2375, 6094, 2389, 6115, 2426, 6135, 2441, 6141, 2459, 6145, 2457, 6158, 2479, 6162, 2474, 6164, 2483],
+        "center":[6039, 2378],
+        "bbox":[5931.650008443746, 2227.460561198128, 232.460998953321, 269.2353909608555]
+      },
+      "NER":{
+        "shape":[4826, 2174, 4875, 2154, 4928, 2097, 4958, 2076, 5084, 1969, 5112, 1979, 5158, 2013, 5186, 1997, 5197, 2038, 5193, 2063, 5223, 2117, 5211, 2170, 5209, 2275, 5152, 2368, 5151, 2382, 5142, 2395, 5147, 2427, 5134, 2445, 5122, 2448, 5114, 2461, 5055, 2448, 5029, 2452, 5009, 2473, 4979, 2471, 4974, 2460, 4969, 2463, 4959, 2452, 4919, 2466, 4902, 2430, 4892, 2435, 4867, 2423, 4865, 2433, 4837, 2430, 4822, 2445, 4821, 2464, 4812, 2484, 4802, 2488, 4806, 2494, 4806, 2512, 4796, 2 [...]
+        "center":[4987, 2266],
+        "bbox":[4688.94356927167, 1969.2241355883932, 533.758948802606, 546.3808525540283]
+      },
+      "MAR":{
+        "shape":[4245, 1783, 4252, 1773, 4300, 1755, 4347, 1701, 4365, 1663, 4358, 1649, 4361, 1617, 4379, 1582, 4380, 1568, 4403, 1538, 4458, 1507, 4479, 1470, 4491, 1428, 4510, 1422, 4513, 1442, 4527, 1452, 4576, 1454, 4588, 1446, 4587, 1457, 4601, 1456, 4608, 1463, 4621, 1471, 4626, 1494, 4620, 1516, 4633, 1557, 4648, 1567, 4633, 1586, 4583, 1587, 4587, 1603, 4560, 1612, 4554, 1625, 4566, 1632, 4539, 1652, 4523, 1654, 4516, 1681, 4486, 1697, 4448, 1700, 4411, 1726, 4396, 1742, 4395, 1 [...]
+        "center":[4466, 1589],
+        "bbox":[4244.755972057574, 1422.2632458867417, 403.1127595077696, 361.1181483223352]
+      },
+      "LTU":{
+        "shape":[5352, 719, 5351, 709, 5333, 702, 5328, 698, 5321, 677, 5282, 672, 5280, 669, 5271, 650, 5271, 645, 5298, 634, 5360, 638, 5375, 633, 5387, 643, 5399, 641, 5430, 658, 5435, 660, 5431, 663, 5435, 675, 5414, 683, 5412, 711, 5400, 705, 5380, 720, 5352, 719],
+        "center":[5357, 672],
+        "bbox":[5271.180828068869, 632.6542043738467, 163.9825309241478, 86.87595850625962]
+      },
+      "NLD":{
+        "shape":[4776, 812, 4800, 811, 4807, 804, 4802, 793, 4822, 799, 4803, 791, 4824, 745, 4824, 756, 4833, 757, 4829, 774, 4842, 778, 4852, 755, 4844, 757, 4843, 752, 4840, 757, 4842, 743, 4877, 736, 4889, 743, 4892, 743, 4889, 763, 4877, 768, 4889, 773, 4889, 780, 4877, 791, 4861, 794, 4866, 810, 4855, 831, 4853, 830, 4846, 828, 4851, 817, 4831, 807, 4807, 808, 4803, 815, 4776, 812],
+        "center":[4845, 781],
+        "bbox":[4775.730949534987, 735.5713013840233, 116.76571996863095, 95.67992105661995]
+      },
+      "KHM":{
+        "shape":[8215, 2543, 8214, 2521, 8207, 2487, 8195, 2471, 8185, 2431, 8191, 2432, 8203, 2400, 8214, 2392, 8263, 2387, 8269, 2393, 8273, 2395, 8280, 2424, 8292, 2420, 8302, 2429, 8306, 2416, 8301, 2401, 8318, 2387, 8326, 2402, 8346, 2405, 8356, 2426, 8363, 2452, 8359, 2472, 8366, 2494, 8312, 2528, 8311, 2549, 8321, 2557, 8314, 2572, 8305, 2566, 8287, 2582, 8275, 2578, 8267, 2589, 8259, 2580, 8240, 2589, 8235, 2582, 8242, 2567, 8238, 2559, 8234, 2555, 8231, 2569, 8220, 2568, 8215, 2543],
+        "center":[8263, 2480],
+        "bbox":[8185.37147168429, 2386.5377180108862, 180.90047298100217, 202.34922692543432]
+      },
+      "CYP":{
+        "shape":[5714, 1457, 5731, 1454, 5732, 1445, 5763, 1444, 5785, 1432, 5766, 1446, 5771, 1460, 5739, 1477, 5721, 1471, 5714, 1457],
+        "center":[5749, 1455],
+        "bbox":[5713.884634998521, 1432.25924856896, 71.04209127720151, 44.708690348867776]
+      },
+      "SOM":{
+        "shape":[6126, 3177, 6105, 3138, 6104, 2960, 6138, 2900, 6147, 2891, 6170, 2886, 6178, 2869, 6209, 2855, 6240, 2859, 6342, 2707, 6313, 2708, 6202, 2659, 6193, 2644, 6180, 2639, 6154, 2583, 6162, 2561, 6173, 2542, 6195, 2579, 6209, 2591, 6232, 2595, 6260, 2570, 6282, 2581, 6293, 2579, 6319, 2555, 6328, 2561, 6356, 2547, 6373, 2552, 6416, 2534, 6428, 2519, 6448, 2526, 6443, 2543, 6446, 2584, 6437, 2602, 6436, 2636, 6423, 2685, 6391, 2754, 6382, 2797, 6348, 2876, 6345, 2872, 6346, 2 [...]
+        "center":[6356, 2650],
+        "bbox":[6104.479061620024, 2518.6511389183215, 343.1893672881315, 658.3382416706527]
+      },
+      "AFG":{
+        "shape":[6640, 1424, 6655, 1439, 6670, 1440, 6676, 1452, 6684, 1452, 6706, 1440, 6708, 1430, 6701, 1420, 6716, 1422, 6743, 1399, 6743, 1366, 6765, 1361, 6767, 1354, 6795, 1362, 6807, 1362, 6818, 1370, 6833, 1366, 6850, 1379, 6864, 1365, 6884, 1365, 6885, 1348, 6904, 1347, 6901, 1330, 6912, 1309, 6943, 1322, 6941, 1333, 6952, 1334, 6956, 1375, 6970, 1385, 7005, 1352, 7026, 1352, 7031, 1360, 7042, 1360, 7040, 1354, 7046, 1355, 7065, 1361, 7053, 1363, 7054, 1377, 7044, 1379, 6995, 1 [...]
+        "center":[6814, 1500],
+        "bbox":[6631.4946510845075, 1308.6023114346542, 433.05915208846, 400.22010462597336]
+      },
+      "RUS":{
+        "shape":[[5426, 555, 5450, 538, 5445, 532, 5442, 526, 5452, 528, 5465, 520, 5501, 520, 5451, 505, 5452, 494, 5437, 502, 5431, 502, 5505, 444, 5516, 429, 5465, 406, 5475, 396, 5460, 389, 5457, 376, 5445, 373, 5443, 354, 5452, 353, 5417, 321, 5434, 302, 5395, 289, 5386, 281, 5389, 268, 5393, 266, 5393, 269, 5399, 268, 5400, 263, 5416, 259, 5414, 254, 5433, 257, 5438, 248, 5445, 250, 5456, 250, 5453, 247, 5463, 248, 5454, 245, 5489, 249, 5485, 253, 5463, 249, 5457, 255, 5465, 252, 5 [...]
+        "center":[7207, 389],
+        "bbox":[5245.141844471403, 69.27853515013177, 4181.174725469643, 1129.6004433313635]
+      },
+      "CRI":{
+        "shape":[1730, 2568, 1737, 2564, 1736, 2560, 1785, 2564, 1795, 2577, 1811, 2571, 1812, 2578, 1814, 2596, 1827, 2619, 1847, 2638, 1848, 2640, 1831, 2633, 1827, 2639, 1826, 2657, 1833, 2664, 1821, 2694, 1826, 2708, 1825, 2708, 1816, 2675, 1811, 2670, 1812, 2683, 1803, 2684, 1799, 2676, 1804, 2664, 1801, 2653, 1767, 2624, 1770, 2612, 1757, 2597, 1751, 2605, 1763, 2616, 1754, 2628, 1735, 2611, 1730, 2596, 1738, 2573, 1730, 2568],
+        "center":[1793, 2616],
+        "bbox":[1729.9827865713048, 2559.9295357285496, 117.53128793739506, 148.02789363227157]
+      },
+      "BRA":{
+        "shape":[[2934, 3090, 2938, 3073, 2941, 3085, 2934, 3090], [2942, 3072, 2951, 3071, 2943, 3084, 2942, 3072], [2963, 4665, 2951, 4644, 2962, 4619, 2944, 4609, 2933, 4587, 2883, 4558, 2875, 4542, 2868, 4539, 2864, 4550, 2858, 4546, 2852, 4532, 2823, 4505, 2815, 4502, 2810, 4511, 2792, 4511, 2806, 4487, 2812, 4488, 2853, 4410, 2903, 4366, 2904, 4332, 2884, 4304, 2873, 4311, 2865, 4298, 2868, 4247, 2869, 4230, 2859, 4220, 2843, 4234, 2831, 4226, 2811, 4154, 2786, 4144, 2772, 4155, 27 [...]
+        "center":[2936, 3596],
+        "bbox":[2134.095445739137, 2844.992230328093, 1349.0682048474341, 1820.1596322502664]
+      },
+      "SVK":{
+        "shape":[5191, 907, 5223, 892, 5232, 874, 5240, 874, 5242, 877, 5257, 874, 5269, 887, 5320, 878, 5357, 893, 5348, 894, 5343, 916, 5344, 919, 5330, 919, 5320, 911, 5298, 913, 5285, 926, 5270, 924, 5266, 931, 5248, 932, 5245, 939, 5228, 943, 5204, 936, 5195, 933, 5191, 929, 5189, 912, 5191, 907],
+        "center":[5257, 906],
+        "bbox":[5189.2044400783025, 874.1361098118816, 167.96600846524507, 68.37464815061162]
+      },
+      "SVN":{
+        "shape":[5165, 976, 5170, 976, 5179, 988, 5176, 988, 5150, 1001, 5154, 1011, 5144, 1026, 5118, 1018, 5111, 1028, 5103, 1028, 5103, 1021, 5099, 1009, 5088, 1004, 5096, 993, 5098, 989, 5126, 994, 5140, 985, 5155, 988, 5163, 977, 5165, 976],
+        "center":[5136, 1001],
+        "bbox":[5087.58744062461, 976.393255082906, 91.25334359015687, 51.39369562619902]
+      },
+      "BIH":{
+        "shape":[5225, 1129, 5223, 1129, 5225, 1120, 5174, 1077, 5162, 1039, 5214, 1030, 5218, 1037, 5262, 1049, 5267, 1049, 5273, 1054, 5266, 1068, 5280, 1083, 5273, 1088, 5277, 1097, 5253, 1128, 5255, 1141, 5251, 1145, 5235, 1129, 5225, 1129],
+        "center":[5231, 1082],
+        "bbox":[5162.210626807983, 1030.2458328729033, 118.00990034118695, 114.31535895724346]
+      }
+    }
+}
diff --git a/dojox/geo/charting/resources/data/WorldCountriesMercator.json b/dojox/geo/charting/resources/data/WorldCountriesMercator.json
new file mode 100644
index 0000000..b172e02
--- /dev/null
+++ b/dojox/geo/charting/resources/data/WorldCountriesMercator.json
@@ -0,0 +1,827 @@
+{
+  "layerExtent":[0.0, 0.0, 8205.292993589293, 5714.379555045271],
+    "layerExtentLL":[-168.1442413330078, 84.92936706542969, 348.14300537109375, 138.64053344726562],
+    "featureNames":["JAM", "BTN", "ROM", "DJI", "UGA", "KOR", "KGZ", "MOZ", "NOR", "YEM", "COG", "SYR", "ZAR", "HTI", "PNG", "RWA", "FIN", "JPN", "TCD", "MEX", "UZB", "IDN", "IND", "ARE", "HRV", "MWI", "ARG", "MNG", "ARM", "TUN", "COL", "AZE", "TUR", "POL", "GEO", "GNQ", "NGA", "PAN", "TJK", "GNB", "KEN", "GUY", "PAK", "MDG", "YUG", "VEN", "URY", "EGY", "HUN", "BLR", "LIE", "MDA", "BDI", "ALB", "SAU", "BLZ", "MMR", "TKM", "CMR", "MLI", "OMN", "GMB", "NPL", "GTM", "BFA", "CUB", "USA", "NZ [...]
+    "features":{
+      "JAM":{
+        "shape":[2113, 3769, 2125, 3763, 2148, 3765, 2162, 3771, 2167, 3778, 2150, 3776, 2148, 3779, 2144, 3778, 2143, 3783, 2128, 3780, 2121, 3771, 2113, 3769],
+        "center":[2140, 3773],
+        "bbox":[2113.0745055025873, 3762.655449917117, 53.570016111194036, 20.433412374480667]
+      },
+      "BTN":{
+        "shape":[6084, 3555, 6085, 3548, 6063, 3544, 6059, 3527, 6060, 3521, 6073, 3519, 6082, 3512, 6088, 3515, 6117, 3508, 6126, 3527, 6125, 3532, 6136, 3536, 6137, 3550, 6098, 3550, 6094, 3554, 6084, 3555],
+        "center":[6097, 3533],
+        "bbox":[6059.3463775842565, 3507.9479889464887, 77.5009108632039, 47.1758114539748]
+      },
+      "ROM":{
+        "shape":[4634, 3057, 4625, 3056, 4619, 3049, 4598, 3048, 4569, 3063, 4555, 3060, 4536, 3065, 4505, 3060, 4506, 3049, 4500, 3047, 4500, 3045, 4494, 3042, 4496, 3031, 4492, 3028, 4486, 3037, 4467, 3026, 4472, 3020, 4470, 3008, 4453, 3001, 4454, 2991, 4445, 2984, 4440, 2978, 4454, 2980, 4455, 2973, 4469, 2965, 4466, 2961, 4482, 2933, 4506, 2911, 4510, 2910, 4517, 2916, 4544, 2915, 4552, 2924, 4587, 2907, 4591, 2904, 4602, 2910, 4631, 2957, 4628, 2982, 4632, 3002, 4632, 3008, 4639, 3 [...]
+        "center":[4556, 2988],
+        "bbox":[4439.635489886346, 2904.3153580221747, 222.97181919599643, 160.86005310162318]
+      },
+      "DJI":{
+        "shape":[4982, 3907, 4988, 3914, 4990, 3923, 4969, 3936, 4983, 3934, 4986, 3937, 4978, 3947, 4952, 3946, 4951, 3930, 4965, 3913, 4969, 3910, 4973, 3914, 4982, 3907],
+        "center":[4975, 3926],
+        "bbox":[4950.593386066556, 3906.9859197417113, 39.13388328611654, 39.527606104424194]
+      },
+      "UGA":{
+        "shape":[4683, 4232, 4673, 4244, 4667, 4240, 4660, 4243, 4664, 4221, 4671, 4189, 4678, 4179, 4705, 4161, 4704, 4156, 4689, 4151, 4693, 4140, 4690, 4135, 4694, 4127, 4691, 4123, 4693, 4119, 4699, 4118, 4724, 4120, 4741, 4116, 4753, 4120, 4766, 4107, 4770, 4110, 4773, 4119, 4778, 4120, 4776, 4129, 4780, 4139, 4789, 4146, 4792, 4166, 4766, 4203, 4766, 4233, 4695, 4233, 4690, 4231, 4683, 4232],
+        "center":[4728, 4176],
+        "bbox":[4660.12852528129, 4106.734556783335, 131.709744033501, 137.75676493109313]
+      },
+      "KOR":{
+        "shape":[6937, 3272, 6940, 3266, 6942, 3271, 6942, 3265, 6951, 3266, 6953, 3271, 6957, 3267, 6949, 3261, 6953, 3256, 6946, 3243, 6950, 3243, 6950, 3242, 6957, 3227, 6974, 3222, 6979, 3227, 6987, 3216, 6991, 3225, 7011, 3258, 7015, 3274, 7013, 3296, 7017, 3296, 7006, 3325, 7002, 3324, 7004, 3319, 6992, 3323, 6990, 3333, 6982, 3324, 6971, 3329, 6975, 3329, 6972, 3336, 6967, 3330, 6969, 3337, 6965, 3341, 6960, 3339, 6965, 3335, 6963, 3332, 6946, 3345, 6946, 3336, 6939, 3332, 6945, 3 [...]
+        "center":[6976, 3284],
+        "bbox":[6936.53488087308, 3216.3176535714138, 80.68118132299242, 128.28477631095302]
+      },
+      "KGZ":{
+        "shape":[5600, 3174, 5605, 3169, 5598, 3164, 5601, 3155, 5609, 3159, 5622, 3150, 5633, 3134, 5624, 3134, 5621, 3129, 5644, 3110, 5643, 3106, 5634, 3107, 5646, 3092, 5661, 3090, 5680, 3100, 5695, 3100, 5696, 3090, 5711, 3075, 5735, 3084, 5784, 3082, 5789, 3087, 5831, 3092, 5854, 3104, 5859, 3101, 5859, 3118, 5849, 3114, 5843, 3123, 5839, 3119, 5829, 3128, 5819, 3129, 5809, 3145, 5778, 3147, 5769, 3164, 5762, 3167, 5752, 3169, 5747, 3158, 5737, 3165, 5731, 3163, 5712, 3177, 5706, 3 [...]
+        "center":[5704, 3143],
+        "bbox":[5597.960293505502, 3075.252195785167, 261.29073303485075, 126.51012568889382]
+      },
+      "MOZ":{
+        "shape":[4679, 4581, 4675, 4568, 4742, 4544, 4744, 4541, 4759, 4556, 4776, 4557, 4779, 4582, 4771, 4590, 4790, 4610, 4790, 4617, 4796, 4617, 4794, 4604, 4797, 4594, 4808, 4592, 4810, 4586, 4812, 4559, 4797, 4539, 4787, 4532, 4779, 4531, 4775, 4501, 4782, 4486, 4791, 4485, 4804, 4483, 4812, 4478, 4826, 4486, 4847, 4484, 4858, 4476, 4889, 4474, 4916, 4456, 4920, 4464, 4923, 4467, 4916, 4486, 4919, 4499, 4916, 4506, 4923, 4516, 4917, 4521, 4923, 4524, 4923, 4547, 4919, 4550, 4925, 4 [...]
+        "center":[4816, 4632],
+        "bbox":[4674.610019463534, 4455.893407859219, 253.38144846216346, 408.98765601915875]
+      },
+      "NOR":{
+        "shape":[4077, 2341, 4088, 2332, 4083, 2324, 4090, 2330, 4100, 2313, 4117, 2310, 4110, 2302, 4139, 2299, 4138, 2292, 4126, 2294, 4129, 2280, 4141, 2283, 4188, 2251, 4197, 2262, 4217, 2256, 4215, 2250, 4230, 2241, 4226, 2226, 4205, 2251, 4186, 2240, 4203, 2232, 4199, 2221, 4220, 2197, 4233, 2201, 4230, 2190, 4239, 2183, 4218, 2175, 4235, 2179, 4249, 2163, 4258, 2116, 4273, 2106, 4268, 2086, 4283, 2061, 4309, 2043, 4329, 2048, 4322, 2036, 4300, 2038, 4312, 2024, 4329, 2031, 4322, 2 [...]
+        "center":[4182, 2361],
+        "bbox":[4077.0155568265604, 1782.8541996841618, 617.067188158961, 737.0825678861565]
+      },
+      "YEM":{
+        "shape":[4972, 3814, 4982, 3807, 4979, 3799, 4984, 3787, 5001, 3792, 5013, 3788, 5053, 3805, 5056, 3821, 5060, 3821, 5117, 3767, 5156, 3760, 5191, 3750, 5216, 3809, 5208, 3810, 5196, 3815, 5195, 3833, 5170, 3846, 5124, 3859, 5110, 3872, 5095, 3872, 5080, 3882, 5042, 3888, 5020, 3904, 5015, 3902, 4998, 3908, 4987, 3905, 4981, 3890, 4982, 3877, 4969, 3843, 4973, 3844, 4972, 3814],
+        "center":[5068, 3847],
+        "bbox":[4969.118075102869, 3750.034935847644, 246.54993279804148, 157.79506506413327]
+      },
+      "COG":{
+        "shape":[4223, 4300, 4235, 4290, 4243, 4296, 4245, 4294, 4245, 4280, 4236, 4272, 4237, 4261, 4254, 4265, 4258, 4250, 4265, 4253, 4271, 4263, 4283, 4264, 4286, 4258, 4295, 4267, 4306, 4253, 4303, 4233, 4307, 4221, 4294, 4214, 4293, 4201, 4304, 4187, 4303, 4179, 4298, 4175, 4279, 4175, 4273, 4164, 4279, 4160, 4279, 4156, 4304, 4158, 4309, 4154, 4313, 4160, 4327, 4159, 4342, 4167, 4340, 4160, 4344, 4156, 4354, 4141, 4355, 4124, 4376, 4120, 4386, 4124, 4401, 4121, 4403, 4132, 4385, 4 [...]
+        "center":[4339, 4218],
+        "bbox":[4223.083573059242, 4119.905011145455, 180.06108685425352, 206.20076741091907]
+      },
+      "SYR":{
+        "shape":[4810, 3336, 4805, 3302, 4809, 3298, 4819, 3300, 4819, 3293, 4826, 3289, 4827, 3272, 4845, 3281, 4867, 3272, 4878, 3280, 4888, 3280, 4922, 3267, 4938, 3263, 4944, 3267, 4956, 3259, 4960, 3261, 4963, 3267, 4953, 3279, 4939, 3284, 4934, 3330, 4928, 3344, 4877, 3372, 4833, 3402, 4814, 3396, 4803, 3390, 4804, 3386, 4805, 3380, 4806, 3374, 4810, 3372, 4812, 3361, 4825, 3347, 4822, 3337, 4810, 3336],
+        "center":[4874, 3323],
+        "bbox":[4802.9025765440365, 3259.230767781386, 160.32085106491013, 143.10343717365868]
+      },
+      "ZAR":{
+        "shape":[4252, 4345, 4260, 4343, 4257, 4326, 4269, 4318, 4274, 4316, 4280, 4322, 4301, 4310, 4304, 4320, 4311, 4320, 4321, 4309, 4325, 4311, 4337, 4302, 4347, 4285, 4347, 4260, 4361, 4239, 4380, 4227, 4387, 4202, 4385, 4185, 4403, 4132, 4401, 4121, 4399, 4117, 4399, 4106, 4404, 4105, 4413, 4091, 4428, 4088, 4443, 4096, 4447, 4102, 4472, 4107, 4478, 4104, 4488, 4109, 4497, 4098, 4531, 4097, 4540, 4092, 4555, 4095, 4562, 4091, 4565, 4085, 4574, 4089, 4601, 4084, 4607, 4086, 4611, 4 [...]
+        "center":[4516, 4294],
+        "bbox":[4251.902590721868, 4083.9118725391213, 452.82408821562603, 443.49104190886237]
+      },
+      "HTI":{
+        "shape":[2272, 3734, 2274, 3750, 2269, 3754, 2275, 3758, 2269, 3766, 2270, 3767, 2271, 3773, 2267, 3772, 2230, 3770, 2222, 3775, 2216, 3769, 2209, 3769, 2208, 3764, 2214, 3759, 2242, 3766, 2256, 3763, 2257, 3758, 2247, 3749, 2248, 3739, 2241, 3732, 2232, 3734, 2233, 3728, 2248, 3726, 2272, 3734],
+        "center":[2257, 3747],
+        "bbox":[2207.811355898826, 3726.036396037922, 67.05636574722712, 48.77994677601737]
+      },
+      "PNG":{
+        "shape":[[7287, 4271, 7331, 4288, 7346, 4289, 7362, 4301, 7369, 4299, 7369, 4303, 7388, 4312, 7399, 4323, 7397, 4338, 7441, 4352, 7448, 4366, 7426, 4367, 7431, 4385, 7436, 4385, 7449, 4398, 7455, 4399, 7455, 4411, 7462, 4415, 7462, 4421, 7467, 4424, 7483, 4423, 7479, 4433, 7498, 4436, 7491, 4440, 7498, 4448, 7517, 4451, 7506, 4454, 7515, 4458, 7507, 4463, 7495, 4459, 7501, 4456, 7490, 4452, 7460, 4450, 7456, 4446, 7449, 4450, 7419, 4423, 7402, 4397, 7377, 4393, 7372, 4387, 7366,  [...]
+        "center":[7362, 4353],
+        "bbox":[7278.803840664321, 4271.102777588017, 275.73988673958047, 191.89883962796375]
+      },
+      "RWA":{
+        "shape":[4660, 4243, 4667, 4240, 4673, 4244, 4683, 4232, 4693, 4247, 4691, 4251, 4694, 4258, 4688, 4266, 4683, 4265, 4681, 4262, 4670, 4261, 4669, 4272, 4663, 4275, 4655, 4267, 4649, 4271, 4645, 4268, 4652, 4264, 4660, 4243],
+        "center":[4669, 4254],
+        "bbox":[4645.341146287997, 4232.46605801844, 48.6883507099983, 42.43444967001324]
+      },
+      "FIN":{
+        "shape":[[4449, 1926, 4460, 1927, 4463, 1907, 4489, 1949, 4510, 1953, 4524, 1941, 4552, 1956, 4571, 1933, 4588, 1867, 4605, 1870, 4621, 1857, 4655, 1898, 4645, 1927, 4640, 1931, 4639, 1987, 4672, 2018, 4650, 2063, 4674, 2134, 4664, 2137, 4661, 2176, 4671, 2182, 4670, 2208, 4683, 2222, 4670, 2240, 4710, 2282, 4618, 2404, 4615, 2406, 4571, 2411, 4538, 2431, 4529, 2426, 4508, 2436, 4506, 2411, 4495, 2416, 4476, 2399, 4468, 2401, 4464, 2377, 4472, 2355, 4460, 2289, 4473, 2277, 4469,  [...]
+        "center":[4596, 2240],
+        "bbox":[4448.936685321843, 1857.3603082270326, 261.495309050546, 578.2821427076294]
+      },
+      "JPN":{
+        "shape":[[7053, 3353, 7057, 3338, 7066, 3339, 7096, 3315, 7096, 3310, 7107, 3306, 7112, 3307, 7103, 3312, 7148, 3307, 7155, 3302, 7157, 3312, 7160, 3307, 7168, 3309, 7174, 3302, 7174, 3306, 7172, 3296, 7191, 3272, 7192, 3255, 7206, 3251, 7194, 3264, 7199, 3263, 7199, 3273, 7205, 3273, 7232, 3255, 7238, 3242, 7251, 3233, 7267, 3190, 7267, 3175, 7262, 3181, 7259, 3178, 7266, 3170, 7263, 3158, 7272, 3152, 7273, 3138, 7279, 3140, 7282, 3150, 7285, 3145, 7291, 3149, 7291, 3137, 7283,  [...]
+        "center":[7251, 3272],
+        "bbox":[7021.2957260992525, 3002.9258671849598, 378.7826821642957, 436.6685376462083]
+      },
+      "TCD":{
+        "shape":[4317, 3651, 4342, 3641, 4529, 3738, 4527, 3830, 4506, 3833, 4501, 3840, 4505, 3843, 4490, 3862, 4494, 3870, 4485, 3879, 4489, 3892, 4478, 3902, 4479, 3906, 4487, 3903, 4493, 3907, 4494, 3930, 4505, 3935, 4505, 3943, 4502, 3950, 4498, 3946, 4480, 3948, 4474, 3962, 4456, 3981, 4444, 3989, 4410, 3996, 4415, 4003, 4410, 4012, 4386, 4019, 4379, 4017, 4357, 4028, 4351, 4021, 4335, 4032, 4331, 4028, 4328, 4023, 4319, 4000, 4308, 3996, 4293, 3977, 4299, 3970, 4327, 3970, 4319, 3 [...]
+        "center":[4400, 3917],
+        "bbox":[4279.520935075297, 3640.591478256288, 249.87986397823897, 391.65511849682343]
+      },
+      "MEX":{
+        "shape":[1202, 3396, 1259, 3391, 1257, 3397, 1345, 3429, 1413, 3430, 1413, 3417, 1454, 3418, 1490, 3450, 1501, 3477, 1529, 3494, 1539, 3487, 1543, 3473, 1551, 3469, 1573, 3472, 1590, 3490, 1599, 3513, 1618, 3531, 1619, 3546, 1628, 3562, 1667, 3577, 1673, 3574, 1674, 3575, 1659, 3611, 1666, 3586, 1662, 3591, 1658, 3590, 1659, 3599, 1654, 3599, 1653, 3602, 1660, 3601, 1655, 3612, 1658, 3616, 1656, 3628, 1659, 3614, 1659, 3620, 1656, 3671, 1668, 3687, 1666, 3693, 1659, 3677, 1661, 3 [...]
+        "center":[1560, 3653],
+        "bbox":[1202.483529052254, 3391.0141380083755, 715.4245047289696, 468.9380354866389]
+      },
+      "UZB":{
+        "shape":[5284, 3136, 5283, 3017, 5344, 2997, 5389, 3030, 5425, 3064, 5496, 3058, 5526, 3088, 5522, 3117, 5535, 3118, 5542, 3141, 5566, 3139, 5567, 3146, 5581, 3149, 5634, 3107, 5643, 3106, 5644, 3110, 5621, 3129, 5624, 3134, 5633, 3134, 5622, 3150, 5609, 3159, 5601, 3155, 5598, 3164, 5605, 3169, 5600, 3174, 5597, 3173, 5571, 3193, 5556, 3192, 5551, 3200, 5574, 3212, 5569, 3224, 5575, 3228, 5574, 3235, 5563, 3254, 5561, 3262, 5550, 3264, 5543, 3259, 5534, 3259, 5534, 3249, 5536, 3 [...]
+        "center":[5480, 3147],
+        "bbox":[5282.605915401533, 2996.985381960224, 361.35524042562247, 267.32988053468534]
+      },
+      "IDN":{
+        "shape":[[7054, 4238, 7060, 4232, 7057, 4226, 7064, 4222, 7072, 4224, 7090, 4213, 7107, 4224, 7123, 4225, 7131, 4238, 7125, 4250, 7125, 4262, 7130, 4271, 7137, 4265, 7142, 4280, 7149, 4287, 7158, 4287, 7179, 4259, 7193, 4255, 7193, 4250, 7208, 4241, 7215, 4244, 7217, 4251, 7225, 4249, 7256, 4266, 7265, 4264, 7281, 4269, 7287, 4271, 7288, 4356, 7279, 4371, 7282, 4376, 7285, 4423, 7277, 4418, 7253, 4398, 7230, 4396, 7234, 4389, 7230, 4380, 7235, 4377, 7222, 4373, 7227, 4362, 7221,  [...]
+        "center":[6653, 4216],
+        "bbox":[6198.900354722582, 4070.926787071948, 1088.6977668876316, 351.65823142081854]
+      },
+      "IND":{
+        "shape":[5569, 3631, 5571, 3625, 5583, 3625, 5582, 3616, 5608, 3621, 5612, 3616, 5629, 3615, 5630, 3622, 5638, 3619, 5633, 3616, 5637, 3607, 5626, 3590, 5626, 3582, 5618, 3582, 5614, 3574, 5617, 3564, 5614, 3556, 5606, 3558, 5602, 3555, 5603, 3544, 5622, 3523, 5628, 3522, 5633, 3531, 5659, 3526, 5669, 3505, 5680, 3502, 5686, 3495, 5695, 3472, 5708, 3459, 5706, 3453, 5717, 3441, 5723, 3417, 5739, 3407, 5720, 3401, 5722, 3394, 5698, 3383, 5696, 3341, 5707, 3345, 5711, 3336, 5722, 3 [...]
+        "center":[5815, 3647],
+        "bbox":[5568.807602569151, 3297.7972371248743, 693.7781921217138, 718.34647481189]
+      },
+      "ARE":{
+        "shape":[5290, 3580, 5293, 3582, 5294, 3596, 5279, 3596, 5276, 3601, 5278, 3617, 5286, 3617, 5288, 3626, 5275, 3623, 5267, 3653, 5269, 3662, 5260, 3666, 5191, 3652, 5181, 3626, 5166, 3614, 5171, 3610, 5173, 3610, 5172, 3616, 5194, 3626, 5204, 3620, 5239, 3622, 5248, 3617, 5253, 3604, 5288, 3569, 5290, 3580],
+        "center":[5236, 3635],
+        "bbox":[5165.787135164099, 3569.364937613166, 128.11349352006164, 97.01407521468445]
+      },
+      "HRV":{
+        "shape":[4377, 3084, 4361, 3070, 4339, 3066, 4319, 3043, 4332, 3043, 4315, 3029, 4311, 3012, 4301, 3006, 4292, 3023, 4283, 3014, 4282, 3001, 4285, 2999, 4290, 2999, 4296, 2999, 4302, 2991, 4322, 2998, 4331, 2985, 4328, 2976, 4350, 2965, 4352, 2965, 4379, 2988, 4399, 2992, 4404, 2985, 4409, 2988, 4410, 2992, 4421, 3006, 4415, 3013, 4412, 3018, 4379, 3007, 4377, 3002, 4336, 3009, 4342, 3041, 4379, 3077, 4377, 3084],
+        "center":[4348, 2986],
+        "bbox":[4282.126566592161, 2964.6095469359557, 138.42243093818252, 119.37150781440505]
+      },
+      "MWI":{
+        "shape":[4791, 4485, 4782, 4486, 4775, 4501, 4779, 4531, 4787, 4532, 4797, 4539, 4812, 4559, 4810, 4586, 4808, 4592, 4797, 4594, 4794, 4604, 4796, 4617, 4790, 4617, 4790, 4610, 4771, 4590, 4779, 4582, 4776, 4557, 4759, 4556, 4744, 4541, 4743, 4538, 4736, 4533, 4745, 4524, 4744, 4510, 4755, 4504, 4750, 4498, 4753, 4492, 4749, 4483, 4754, 4473, 4751, 4467, 4758, 4467, 4763, 4460, 4745, 4438, 4741, 4432, 4762, 4439, 4767, 4435, 4773, 4438, 4782, 4450, 4782, 4474, 4791, 4485],
+        "center":[4765, 4527],
+        "bbox":[4735.731510608965, 4432.2423296937495, 76.68371833892616, 184.43737274759133]
+      },
+      "ARG":{
+        "shape":[2600, 4951, 2595, 4959, 2598, 4969, 2593, 4989, 2587, 4993, 2589, 5021, 2590, 5027, 2584, 5030, 2579, 5045, 2585, 5058, 2581, 5069, 2607, 5087, 2614, 5099, 2608, 5108, 2610, 5117, 2624, 5127, 2625, 5141, 2615, 5157, 2605, 5163, 2604, 5177, 2588, 5186, 2520, 5203, 2488, 5196, 2493, 5211, 2498, 5213, 2492, 5213, 2497, 5217, 2487, 5243, 2495, 5252, 2491, 5260, 2471, 5271, 2445, 5265, 2434, 5255, 2424, 5261, 2426, 5296, 2440, 5303, 2437, 5310, 2450, 5308, 2443, 5303, 2458, 5 [...]
+        "center":[2455, 5014],
+        "bbox":[2227.805075398174, 4730.651197397446, 471.3746866852334, 919.6336597873415]
+      },
+      "MNG":{
+        "shape":[6058, 2864, 6075, 2857, 6076, 2848, 6094, 2839, 6098, 2828, 6116, 2825, 6123, 2815, 6154, 2817, 6156, 2831, 6183, 2826, 6185, 2839, 6208, 2849, 6222, 2844, 6253, 2855, 6273, 2851, 6281, 2847, 6275, 2844, 6276, 2827, 6264, 2801, 6289, 2783, 6296, 2767, 6369, 2794, 6374, 2824, 6401, 2839, 6460, 2829, 6465, 2838, 6474, 2833, 6488, 2847, 6508, 2848, 6505, 2860, 6520, 2868, 6573, 2875, 6626, 2861, 6655, 2833, 6669, 2835, 6690, 2850, 6709, 2846, 6715, 2849, 6689, 2910, 6691, 2 [...]
+        "center":[6433, 2962],
+        "bbox":[6035.193598574085, 2766.8803967214635, 758.9802999176181, 361.6972767033535]
+      },
+      "ARM":{
+        "shape":[5017, 3191, 5015, 3186, 5014, 3181, 4998, 3179, 4992, 3173, 4989, 3164, 4994, 3153, 4986, 3142, 5014, 3139, 5020, 3137, 5034, 3149, 5031, 3158, 5035, 3163, 5047, 3171, 5046, 3176, 5039, 3178, 5059, 3193, 5060, 3215, 5056, 3215, 5053, 3216, 5045, 3195, 5031, 3197, 5026, 3188, 5017, 3191],
+        "center":[5029, 3174],
+        "bbox":[4986.1832611490645, 3136.563601224083, 74.29819791165392, 79.7100142502909]
+      },
+      "TUN":{
+        "shape":[4173, 3271, 4197, 3260, 4187, 3267, 4199, 3261, 4203, 3263, 4205, 3278, 4209, 3278, 4223, 3267, 4226, 3273, 4208, 3294, 4212, 3303, 4224, 3311, 4225, 3322, 4213, 3339, 4199, 3349, 4199, 3357, 4210, 3367, 4215, 3366, 4215, 3372, 4225, 3369, 4224, 3377, 4230, 3380, 4236, 3381, 4237, 3399, 4205, 3422, 4205, 3447, 4199, 3454, 4188, 3459, 4177, 3407, 4159, 3396, 4159, 3387, 4138, 3361, 4158, 3335, 4159, 3287, 4154, 3283, 4167, 3272, 4173, 3271],
+        "center":[4181, 3335],
+        "bbox":[4137.807701758884, 3260.04886012255, 98.70063641006254, 198.5469779036307]
+      },
+      "COL":{
+        "shape":[2141, 4127, 2145, 4118, 2141, 4117, 2143, 4114, 2137, 4117, 2134, 4110, 2141, 4104, 2139, 4082, 2135, 4079, 2143, 4077, 2136, 4065, 2142, 4058, 2132, 4046, 2128, 4035, 2131, 4025, 2136, 4028, 2144, 4013, 2148, 4016, 2153, 4026, 2156, 4023, 2151, 4008, 2167, 3998, 2170, 3990, 2181, 3989, 2183, 3960, 2200, 3948, 2208, 3951, 2209, 3957, 2214, 3943, 2238, 3944, 2245, 3937, 2259, 3933, 2261, 3922, 2267, 3923, 2273, 3917, 2284, 3919, 2287, 3926, 2279, 3933, 2267, 3936, 2262, 3 [...]
+        "center":[2250, 4130],
+        "bbox":[2099.534696157407, 3916.737526459373, 291.2146199734507, 391.1958149066022]
+      },
+      "AZE":{
+        "shape":[[5060, 3215, 5059, 3193, 5039, 3178, 5046, 3176, 5047, 3171, 5035, 3163, 5031, 3158, 5034, 3149, 5020, 3137, 5025, 3133, 5038, 3133, 5045, 3139, 5059, 3141, 5063, 3134, 5052, 3127, 5053, 3119, 5058, 3120, 5081, 3139, 5099, 3130, 5105, 3121, 5110, 3126, 5128, 3157, 5140, 3159, 5149, 3168, 5138, 3165, 5128, 3172, 5120, 3206, 5116, 3199, 5113, 3201, 5111, 3212, 5113, 3225, 5095, 3213, 5103, 3205, 5097, 3202, 5101, 3195, 5094, 3190, 5060, 3215], [5017, 3191, 5026, 3188, 5031 [...]
+        "center":[5034, 3199],
+        "bbox":[5017.150300511297, 3119.421454368878, 131.96777975834448, 105.95280323608358]
+      },
+      "TUR":{
+        "shape":[[4727, 3121, 4749, 3115, 4781, 3117, 4785, 3113, 4799, 3128, 4811, 3126, 4819, 3140, 4826, 3135, 4845, 3146, 4851, 3143, 4854, 3148, 4867, 3150, 4892, 3144, 4913, 3148, 4938, 3134, 4940, 3131, 4962, 3134, 4970, 3128, 4981, 3133, 4979, 3139, 4986, 3142, 4994, 3153, 4989, 3164, 4992, 3173, 4998, 3179, 5014, 3181, 5015, 3186, 5012, 3191, 5003, 3200, 5011, 3231, 5006, 3242, 5011, 3245, 5019, 3262, 5011, 3267, 5008, 3268, 5007, 3260, 4993, 3262, 4983, 3257, 4971, 3257, 4967,  [...]
+        "center":[4779, 3197],
+        "bbox":[4574.887124907251, 3112.5268456618815, 444.3770042619608, 187.77982196859466]
+      },
+      "POL":{
+        "shape":[4503, 2673, 4516, 2681, 4516, 2693, 4518, 2704, 4528, 2738, 4509, 2757, 4523, 2765, 4519, 2783, 4519, 2787, 4532, 2809, 4531, 2823, 4500, 2855, 4503, 2872, 4501, 2876, 4473, 2862, 4431, 2871, 4422, 2858, 4410, 2861, 4409, 2858, 4403, 2844, 4386, 2842, 4380, 2838, 4381, 2832, 4361, 2826, 4364, 2836, 4356, 2837, 4348, 2827, 4351, 2821, 4326, 2811, 4323, 2807, 4318, 2801, 4309, 2775, 4310, 2745, 4300, 2737, 4305, 2724, 4300, 2702, 4306, 2705, 4309, 2713, 4312, 2690, 4346, 2 [...]
+        "center":[4413, 2769],
+        "bbox":[4299.599210896786, 2656.688820784481, 232.3791400937107, 219.34412802193083]
+      },
+      "GEO":{
+        "shape":[4940, 3131, 4948, 3121, 4941, 3093, 4928, 3078, 4913, 3077, 4912, 3069, 4907, 3068, 4905, 3066, 4920, 3065, 4950, 3077, 4974, 3074, 4993, 3088, 4995, 3097, 5029, 3091, 5032, 3098, 5040, 3099, 5038, 3109, 5052, 3115, 5053, 3119, 5052, 3127, 5063, 3134, 5059, 3141, 5045, 3139, 5038, 3133, 5025, 3133, 5020, 3137, 5014, 3139, 4986, 3142, 4979, 3139, 4981, 3133, 4970, 3128, 4962, 3134, 4940, 3131],
+        "center":[4986, 3107],
+        "bbox":[4904.7578783304225, 3064.964853972326, 158.1454643458692, 76.53747162964555]
+      },
+      "GNQ":{
+        "shape":[4196, 4151, 4206, 4157, 4229, 4157, 4232, 4183, 4218, 4181, 4190, 4184, 4184, 4182, 4194, 4165, 4196, 4151],
+        "center":[4203, 4168],
+        "bbox":[4184.026597651729, 4151.31869049849, 47.58348143402418, 32.4480039775417]
+      },
+      "NGA":{
+        "shape":[4294, 3896, 4296, 3914, 4305, 3919, 4311, 3931, 4298, 3943, 4292, 3940, 4282, 3956, 4281, 3968, 4274, 3972, 4276, 3978, 4265, 3986, 4264, 4001, 4252, 4008, 4243, 4039, 4226, 4054, 4214, 4038, 4204, 4044, 4202, 4039, 4190, 4054, 4168, 4071, 4169, 4087, 4162, 4097, 4156, 4093, 4156, 4101, 4153, 4102, 4133, 4100, 4129, 4096, 4126, 4099, 4127, 4104, 4121, 4100, 4121, 4104, 4111, 4107, 4111, 4103, 4098, 4102, 4093, 4099, 4086, 4082, 4091, 4083, 4090, 4077, 4083, 4077, 4066, 4 [...]
+        "center":[4141, 3999],
+        "bbox":[4023.823781390183, 3876.8158534890094, 286.9269660434461, 229.7386539050908]
+      },
+      "PAN":{
+        "shape":[[2085, 3996, 2082, 4004, 2066, 4013, 2078, 4030, 2067, 4035, 2056, 4036, 2053, 4020, 2049, 4021, 2049, 4027, 2041, 4025, 2037, 4015, 2023, 4015, 2025, 4011, 2022, 4014, 2011, 4012, 2010, 4019, 2009, 4019, 2005, 4012, 2012, 3998, 2007, 3994, 2007, 3985, 2009, 3982, 2021, 3986, 2020, 3990, 2027, 3997, 2035, 3997, 2033, 3991, 2041, 4000, 2048, 4000, 2078, 3985, 2075, 3992, 2079, 3989, 2085, 3996], [2082, 3991, 2079, 3985, 2087, 3979, 2114, 3983, 2140, 4000, 2137, 4004, 2143 [...]
+        "center":[2081, 3992],
+        "bbox":[2005.4371391939178, 3978.9220983259556, 138.86651703693792, 56.815748249485296]
+      },
+      "TJK":{
+        "shape":[5718, 3253, 5719, 3257, 5710, 3258, 5708, 3252, 5692, 3252, 5660, 3275, 5652, 3268, 5656, 3239, 5649, 3238, 5652, 3231, 5632, 3221, 5619, 3236, 5618, 3249, 5603, 3249, 5600, 3261, 5585, 3261, 5572, 3271, 5561, 3262, 5563, 3254, 5574, 3235, 5575, 3228, 5569, 3224, 5574, 3212, 5551, 3200, 5556, 3192, 5571, 3193, 5597, 3173, 5600, 3174, 5601, 3191, 5627, 3189, 5633, 3196, 5651, 3189, 5657, 3193, 5657, 3202, 5684, 3197, 5693, 3199, 5700, 3203, 5708, 3224, 5719, 3221, 5731, 3 [...]
+        "center":[5649, 3211],
+        "bbox":[5551.193422361299, 3172.7469320085283, 186.78240141496553, 102.20247231341091]
+      },
+      "GNB":{
+        "shape":[3565, 3914, 3600, 3912, 3609, 3907, 3652, 3906, 3632, 3916, 3638, 3925, 3635, 3930, 3619, 3930, 3608, 3946, 3606, 3951, 3603, 3945, 3608, 3938, 3604, 3938, 3600, 3945, 3601, 3941, 3597, 3942, 3594, 3936, 3598, 3934, 3594, 3930, 3607, 3925, 3607, 3922, 3587, 3927, 3585, 3922, 3579, 3924, 3574, 3920, 3578, 3915, 3571, 3919, 3565, 3914],
+        "center":[3611, 3922],
+        "bbox":[3565.104489911381, 3906.4386193530186, 86.72117570930823, 44.436662990256536]
+      },
+      "KEN":{
+        "shape":[4890, 4319, 4853, 4291, 4855, 4279, 4766, 4233, 4766, 4203, 4792, 4166, 4789, 4146, 4780, 4139, 4776, 4129, 4778, 4120, 4773, 4119, 4770, 4110, 4766, 4107, 4773, 4100, 4810, 4100, 4834, 4103, 4864, 4122, 4899, 4128, 4908, 4112, 4924, 4109, 4930, 4113, 4955, 4114, 4932, 4143, 4932, 4229, 4946, 4248, 4939, 4256, 4927, 4256, 4929, 4263, 4926, 4262, 4922, 4269, 4913, 4272, 4912, 4288, 4908, 4287, 4904, 4303, 4894, 4319, 4890, 4319],
+        "center":[4868, 4198],
+        "bbox":[4765.886174113785, 4099.875404831452, 188.7849703613674, 219.56938659341813]
+      },
+      "GUY":{
+        "shape":[2617, 4078, 2619, 4078, 2620, 4092, 2606, 4097, 2599, 4115, 2609, 4126, 2608, 4130, 2618, 4131, 2629, 4160, 2636, 4163, 2616, 4164, 2578, 4183, 2559, 4175, 2559, 4169, 2554, 4168, 2555, 4161, 2549, 4150, 2552, 4126, 2559, 4118, 2548, 4105, 2550, 4094, 2535, 4087, 2533, 4083, 2528, 4083, 2518, 4071, 2527, 4061, 2525, 4054, 2546, 4045, 2537, 4043, 2533, 4036, 2541, 4025, 2545, 4027, 2555, 4019, 2553, 4013, 2565, 4019, 2585, 4038, 2580, 4062, 2584, 4051, 2591, 4050, 2606, 4 [...]
+        "center":[2575, 4093],
+        "bbox":[2517.726393853509, 4012.596699932666, 118.32867297320308, 170.46119025612325]
+      },
+      "PAK":{
+        "shape":[5569, 3631, 5558, 3626, 5552, 3601, 5540, 3600, 5539, 3589, 5530, 3580, 5514, 3588, 5492, 3588, 5490, 3592, 5479, 3585, 5467, 3586, 5463, 3592, 5439, 3590, 5434, 3596, 5431, 3592, 5423, 3597, 5423, 3592, 5419, 3591, 5417, 3582, 5427, 3564, 5454, 3556, 5454, 3552, 5459, 3551, 5459, 3542, 5447, 3541, 5443, 3514, 5422, 3502, 5411, 3485, 5402, 3469, 5437, 3484, 5463, 3480, 5477, 3483, 5490, 3477, 5499, 3480, 5529, 3469, 5528, 3445, 5543, 3428, 5552, 3433, 5562, 3429, 5561, 3 [...]
+        "center":[5587, 3478],
+        "bbox":[5401.520739680769, 3267.6021347905616, 382.7636837923774, 362.96628316553006]
+      },
+      "MDG":{
+        "shape":[4990, 4725, 4996, 4723, 5014, 4690, 5012, 4688, 5015, 4679, 5008, 4668, 5001, 4629, 5014, 4607, 5014, 4599, 5022, 4600, 5030, 4594, 5039, 4596, 5043, 4590, 5052, 4592, 5056, 4588, 5061, 4595, 5058, 4586, 5071, 4574, 5074, 4578, 5072, 4583, 5081, 4579, 5076, 4576, 5082, 4564, 5085, 4561, 5087, 4566, 5083, 4572, 5093, 4560, 5099, 4562, 5091, 4556, 5099, 4550, 5094, 4535, 5101, 4536, 5103, 4542, 5116, 4530, 5117, 4509, 5129, 4497, 5132, 4500, 5128, 4503, 5135, 4510, 5137, 4 [...]
+        "center":[5069, 4686],
+        "bbox":[4984.7940497369145, 4496.876388382163, 172.07113634419966, 337.292284312899]
+      },
+      "YUG":{
+        "shape":[4492, 3103, 4466, 3112, 4459, 3108, 4449, 3115, 4447, 3119, 4447, 3115, 4438, 3097, 4430, 3098, 4428, 3093, 4420, 3105, 4419, 3118, 4415, 3117, 4404, 3097, 4393, 3097, 4375, 3087, 4377, 3084, 4378, 3084, 4386, 3084, 4397, 3096, 4401, 3093, 4400, 3083, 4421, 3058, 4418, 3050, 4424, 3046, 4414, 3033, 4421, 3022, 4416, 3018, 4412, 3018, 4415, 3013, 4421, 3006, 4410, 2992, 4409, 2988, 4416, 2982, 4436, 2978, 4440, 2978, 4445, 2984, 4454, 2991, 4453, 3001, 4470, 3008, 4472, 3 [...]
+        "center":[4462, 3063],
+        "bbox":[4375.066879643833, 2977.850511213964, 130.3089673278373, 140.6570467805259]
+      },
+      "VEN":{
+        "shape":[2272, 3949, 2275, 3964, 2262, 3979, 2276, 3997, 2283, 3995, 2289, 3988, 2290, 3978, 2278, 3966, 2278, 3956, 2309, 3939, 2321, 3939, 2318, 3935, 2308, 3937, 2306, 3932, 2313, 3922, 2316, 3923, 2323, 3939, 2346, 3943, 2359, 3964, 2392, 3960, 2403, 3961, 2407, 3967, 2421, 3972, 2440, 3973, 2450, 3964, 2461, 3964, 2448, 3959, 2503, 3958, 2494, 3963, 2481, 3962, 2483, 3967, 2487, 3967, 2486, 3972, 2493, 3976, 2511, 3977, 2525, 3985, 2531, 3990, 2524, 3994, 2531, 3994, 2531, 3 [...]
+        "center":[2431, 4043],
+        "bbox":[2237.504042827967, 3922.072037941367, 316.9979730430109, 270.4424348115299]
+      },
+      "URY":{
+        "shape":[2597, 5070, 2585, 5053, 2585, 5033, 2592, 5031, 2593, 5023, 2589, 5021, 2587, 4993, 2593, 4989, 2598, 4969, 2595, 4959, 2600, 4951, 2613, 4951, 2618, 4945, 2623, 4947, 2641, 4964, 2643, 4973, 2648, 4975, 2652, 4968, 2656, 4970, 2660, 4980, 2693, 4998, 2699, 5012, 2710, 5019, 2699, 5034, 2705, 5048, 2700, 5051, 2693, 5068, 2665, 5084, 2650, 5079, 2633, 5084, 2633, 5079, 2624, 5078, 2616, 5070, 2597, 5070],
+        "center":[2645, 5028],
+        "bbox":[2584.6500101447555, 4945.323952517628, 125.36047729020856, 138.45424211164482]
+      },
+      "EGY":{
+        "shape":[4558, 3424, 4560, 3427, 4575, 3424, 4600, 3428, 4647, 3444, 4677, 3434, 4682, 3428, 4695, 3429, 4698, 3423, 4707, 3428, 4716, 3427, 4719, 3441, 4724, 3443, 4726, 3434, 4736, 3440, 4745, 3436, 4757, 3438, 4766, 3435, 4777, 3425, 4780, 3422, 4782, 3426, 4775, 3439, 4790, 3479, 4786, 3484, 4776, 3509, 4778, 3519, 4772, 3527, 4749, 3504, 4748, 3493, 4741, 3488, 4733, 3467, 4727, 3477, 4740, 3506, 4755, 3522, 4755, 3532, 4765, 3545, 4794, 3615, 4808, 3628, 4801, 3627, 4801, 3 [...]
+        "center":[4657, 3552],
+        "bbox":[4546.915787682237, 3421.5650385257436, 261.30412442733905, 260.31300259191676]
+      },
+      "HUN":{
+        "shape":[4352, 2965, 4345, 2954, 4342, 2954, 4344, 2947, 4353, 2947, 4357, 2924, 4367, 2923, 4369, 2914, 4376, 2917, 4394, 2923, 4407, 2920, 4410, 2913, 4425, 2912, 4428, 2905, 4440, 2908, 4452, 2895, 4470, 2893, 4476, 2901, 4488, 2901, 4496, 2906, 4502, 2909, 4506, 2911, 4482, 2933, 4466, 2961, 4469, 2965, 4455, 2973, 4454, 2980, 4440, 2978, 4436, 2978, 4416, 2982, 4409, 2988, 4404, 2985, 4399, 2992, 4379, 2988, 4352, 2965],
+        "center":[4414, 2942],
+        "bbox":[4341.741579012953, 2893.2155344911102, 164.00059929238705, 98.7137234527222]
+      },
+      "BLR":{
+        "shape":[4712, 2761, 4694, 2763, 4680, 2791, 4669, 2786, 4658, 2791, 4652, 2783, 4643, 2792, 4629, 2783, 4617, 2789, 4604, 2785, 4602, 2778, 4573, 2769, 4541, 2771, 4535, 2781, 4523, 2780, 4519, 2783, 4523, 2765, 4509, 2757, 4528, 2738, 4518, 2704, 4516, 2693, 4539, 2694, 4558, 2677, 4567, 2684, 4573, 2651, 4591, 2641, 4589, 2626, 4594, 2623, 4612, 2618, 4628, 2600, 4630, 2602, 4650, 2603, 4656, 2617, 4678, 2610, 4692, 2628, 4685, 2652, 4711, 2688, 4709, 2694, 4733, 2704, 4725, 2 [...]
+        "center":[4620, 2711],
+        "bbox":[4508.647051867414, 2600.096160959874, 224.56534197181736, 191.42630343646942]
+      },
+      "LIE":{
+        "shape":[4186, 2943, 4189, 2948, 4187, 2948, 4187, 2946, 4186, 2943],
+        "center":[4188, 2944],
+        "bbox":[4186.385917528479, 2942.7256826706293, 2.9519286922050014, 5.1700302481581275]
+      },
+      "MDA":{
+        "shape":[4632, 3002, 4628, 2982, 4631, 2957, 4602, 2910, 4591, 2904, 4596, 2899, 4643, 2907, 4652, 2916, 4650, 2931, 4660, 2938, 4661, 2950, 4669, 2954, 4669, 2968, 4649, 2964, 4632, 3002],
+        "center":[4637, 2948],
+        "bbox":[4591.380133274359, 2898.8186413137637, 77.54235537039312, 102.99388773040664]
+      },
+      "BDI":{
+        "shape":[4649, 4271, 4655, 4267, 4663, 4275, 4669, 4272, 4670, 4261, 4681, 4262, 4683, 4265, 4684, 4268, 4684, 4279, 4691, 4282, 4691, 4289, 4674, 4310, 4665, 4316, 4657, 4317, 4656, 4307, 4651, 4298, 4655, 4279, 4649, 4271],
+        "center":[4671, 4283],
+        "bbox":[4648.542271327393, 4261.407670769645, 42.58716877539155, 55.218920631496076]
+      },
+      "ALB":{
+        "shape":[4419, 3118, 4420, 3105, 4428, 3093, 4430, 3098, 4438, 3097, 4447, 3115, 4447, 3119, 4452, 3147, 4459, 3150, 4461, 3156, 4451, 3170, 4442, 3174, 4442, 3185, 4435, 3187, 4436, 3184, 4418, 3164, 4423, 3165, 4419, 3154, 4425, 3146, 4422, 3140, 4424, 3120, 4419, 3118],
+        "center":[4436, 3146],
+        "bbox":[4417.900730572174, 3092.9178243467713, 42.617233245486204, 94.15556868747444]
+      },
+      "SAU":{
+        "shape":[4789, 3483, 4814, 3488, 4831, 3469, 4844, 3468, 4860, 3448, 4833, 3426, 4882, 3413, 4888, 3406, 4907, 3411, 4974, 3446, 4977, 3455, 4992, 3455, 4990, 3477, 5019, 3488, 5063, 3490, 5083, 3493, 5091, 3503, 5104, 3500, 5106, 3506, 5115, 3528, 5125, 3533, 5122, 3536, 5129, 3545, 5143, 3553, 5147, 3565, 5142, 3572, 5164, 3611, 5166, 3614, 5181, 3626, 5191, 3652, 5260, 3666, 5269, 3662, 5276, 3676, 5262, 3726, 5191, 3750, 5156, 3760, 5117, 3767, 5060, 3821, 5056, 3821, 5053, 3 [...]
+        "center":[5019, 3627],
+        "bbox":[4780.21655198948, 3406.307267022362, 496.2756899018432, 414.9818126746618]
+      },
+      "BLZ":{
+        "shape":[1866, 3777, 1871, 3776, 1878, 3765, 1882, 3766, 1880, 3767, 1879, 3769, 1885, 3771, 1879, 3809, 1867, 3827, 1866, 3828, 1860, 3828, 1859, 3781, 1859, 3779, 1866, 3777],
+        "center":[1873, 3797],
+        "bbox":[1858.5796130388244, 3764.811517038298, 26.51643918013974, 63.47019847595993]
+      },
+      "MMR":{
+        "shape":[6135, 3701, 6138, 3691, 6146, 3696, 6141, 3680, 6149, 3668, 6153, 3663, 6155, 3668, 6163, 3661, 6160, 3649, 6168, 3628, 6168, 3617, 6186, 3620, 6199, 3592, 6194, 3588, 6210, 3566, 6214, 3551, 6232, 3537, 6247, 3534, 6256, 3538, 6252, 3529, 6261, 3524, 6263, 3514, 6260, 3511, 6260, 3508, 6275, 3514, 6278, 3535, 6285, 3530, 6290, 3545, 6287, 3579, 6281, 3580, 6279, 3586, 6275, 3585, 6272, 3592, 6265, 3596, 6259, 3608, 6265, 3619, 6258, 3627, 6262, 3631, 6273, 3621, 6278, 3 [...]
+        "center":[6228, 3680],
+        "bbox":[6134.720121327462, 3508.4578675387784, 211.16563940892502, 459.6594148689155]
+      },
+      "TKM":{
+        "shape":[5235, 3258, 5232, 3221, 5235, 3209, 5225, 3197, 5216, 3197, 5211, 3150, 5213, 3155, 5228, 3151, 5230, 3158, 5246, 3156, 5244, 3150, 5253, 3147, 5231, 3110, 5215, 3112, 5207, 3120, 5211, 3144, 5202, 3124, 5200, 3121, 5213, 3107, 5235, 3102, 5257, 3110, 5268, 3136, 5284, 3136, 5308, 3139, 5305, 3120, 5311, 3111, 5330, 3106, 5331, 3099, 5342, 3102, 5337, 3096, 5347, 3089, 5366, 3106, 5380, 3107, 5381, 3134, 5411, 3141, 5411, 3134, 5416, 3134, 5424, 3141, 5437, 3160, 5439, 3 [...]
+        "center":[5332, 3191],
+        "bbox":[5200.393457459113, 3089.3673586337413, 335.53674156707893, 231.60794409146183]
+      },
+      "CMR":{
+        "shape":[4162, 4097, 4169, 4087, 4168, 4071, 4190, 4054, 4202, 4039, 4204, 4044, 4214, 4038, 4226, 4054, 4243, 4039, 4252, 4008, 4264, 4001, 4265, 3986, 4276, 3978, 4274, 3972, 4281, 3968, 4282, 3956, 4292, 3940, 4298, 3943, 4311, 3931, 4305, 3919, 4296, 3914, 4294, 3896, 4302, 3896, 4314, 3906, 4319, 3948, 4327, 3970, 4299, 3970, 4293, 3977, 4308, 3996, 4319, 4000, 4328, 4023, 4331, 4028, 4304, 4063, 4308, 4070, 4303, 4083, 4309, 4086, 4311, 4099, 4320, 4105, 4318, 4118, 4342, 4 [...]
+        "center":[4253, 4085],
+        "bbox":[4161.520536474499, 3896.037318378006, 182.6206424534812, 270.67787090747197]
+      },
+      "MLI":{
+        "shape":[3845, 3599, 3991, 3702, 3990, 3708, 4006, 3719, 4014, 3719, 4017, 3725, 4037, 3731, 4039, 3738, 4035, 3748, 4042, 3753, 4062, 3747, 4062, 3800, 4058, 3803, 4053, 3830, 4043, 3841, 4034, 3838, 4030, 3843, 3991, 3842, 3985, 3848, 3967, 3849, 3944, 3848, 3937, 3855, 3918, 3858, 3904, 3872, 3894, 3873, 3891, 3883, 3883, 3882, 3884, 3892, 3879, 3892, 3879, 3897, 3868, 3888, 3857, 3894, 3861, 3905, 3854, 3904, 3856, 3909, 3850, 3922, 3840, 3921, 3834, 3926, 3837, 3933, 3833, 3 [...]
+        "center":[3903, 3789],
+        "bbox":[3672.867301280128, 3598.506566094853, 389.53356199976497, 368.4158918134058]
+      },
+      "OMN":{
+        "shape":[5191, 3750, 5262, 3726, 5276, 3676, 5269, 3662, 5267, 3653, 5275, 3623, 5288, 3626, 5286, 3617, 5278, 3617, 5276, 3601, 5279, 3596, 5294, 3596, 5296, 3602, 5308, 3622, 5325, 3632, 5345, 3633, 5376, 3668, 5347, 3704, 5343, 3716, 5339, 3715, 5339, 3708, 5335, 3709, 5325, 3733, 5329, 3750, 5305, 3756, 5294, 3778, 5272, 3778, 5267, 3784, 5268, 3794, 5264, 3799, 5243, 3799, 5222, 3806, 5216, 3809, 5191, 3750],
+        "center":[5301, 3708],
+        "bbox":[5190.7057112752, 3596.0486898038143, 185.51228341428123, 212.48294486575287]
+      },
+      "GMB":{
+        "shape":[3584, 3885, 3607, 3879, 3622, 3882, 3622, 3887, 3635, 3887, 3626, 3894, 3604, 3885, 3600, 3889, 3588, 3890, 3588, 3894, 3564, 3896, 3564, 3890, 3567, 3888, 3572, 3893, 3590, 3888, 3572, 3891, 3569, 3885, 3584, 3885],
+        "center":[3595, 3885],
+        "bbox":[3563.663327306629, 3878.7256354352785, 71.4309578676025, 17.433369944043534]
+      },
+      "NPL":{
+        "shape":[6044, 3551, 6044, 3558, 6031, 3561, 6017, 3556, 6000, 3560, 5982, 3550, 5976, 3553, 5959, 3540, 5911, 3539, 5908, 3530, 5896, 3526, 5893, 3529, 5888, 3522, 5850, 3503, 5854, 3484, 5872, 3465, 5873, 3460, 5883, 3458, 5885, 3464, 5892, 3460, 5911, 3469, 5937, 3494, 5949, 3488, 5950, 3500, 5960, 3501, 5962, 3511, 5970, 3503, 5974, 3515, 5985, 3515, 5995, 3521, 6033, 3517, 6042, 3524, 6041, 3531, 6040, 3542, 6044, 3551],
+        "center":[5949, 3520],
+        "bbox":[5849.842752895346, 3458.4148160407526, 193.99205189309305, 102.54413807830588]
+      },
+      "GTM":{
+        "shape":[1866, 3828, 1872, 3834, 1874, 3828, 1884, 3834, 1862, 3851, 1861, 3859, 1854, 3865, 1854, 3867, 1849, 3875, 1838, 3877, 1835, 3882, 1833, 3881, 1809, 3878, 1806, 3870, 1802, 3873, 1791, 3865, 1793, 3862, 1790, 3863, 1788, 3860, 1794, 3849, 1788, 3843, 1802, 3825, 1831, 3825, 1826, 3809, 1809, 3797, 1821, 3796, 1820, 3781, 1859, 3781, 1860, 3828, 1866, 3828],
+        "center":[1838, 3849],
+        "bbox":[1787.6621859614634, 3780.6893947025824, 96.68521860782289, 101.41915524839533]
+      },
+      "BFA":{
+        "shape":[3965, 3946, 3954, 3943, 3946, 3949, 3943, 3946, 3897, 3945, 3893, 3956, 3897, 3961, 3898, 3980, 3893, 3985, 3889, 3976, 3871, 3973, 3862, 3975, 3858, 3983, 3847, 3984, 3847, 3978, 3838, 3966, 3829, 3965, 3831, 3958, 3833, 3945, 3837, 3933, 3834, 3926, 3840, 3921, 3850, 3922, 3856, 3909, 3854, 3904, 3861, 3905, 3857, 3894, 3868, 3888, 3879, 3897, 3879, 3892, 3884, 3892, 3883, 3882, 3891, 3883, 3894, 3873, 3904, 3872, 3918, 3858, 3937, 3855, 3944, 3848, 3967, 3849, 3967, 3 [...]
+        "center":[3923, 3912],
+        "bbox":[3829.2413966890535, 3848.242565232041, 190.22674166577826, 137.07921604806052]
+      },
+      "CUB":{
+        "shape":[[1970, 3682, 1970, 3678, 1962, 3680, 1960, 3676, 1974, 3675, 1970, 3668, 1978, 3660, 2002, 3648, 2025, 3644, 2048, 3645, 2050, 3649, 2059, 3646, 2069, 3653, 2080, 3653, 2090, 3665, 2106, 3664, 2108, 3672, 2114, 3668, 2140, 3689, 2135, 3678, 2159, 3696, 2163, 3693, 2177, 3697, 2180, 3700, 2177, 3709, 2197, 3708, 2214, 3720, 2188, 3728, 2130, 3729, 2130, 3725, 2143, 3716, 2138, 3707, 2118, 3706, 2110, 3701, 2110, 3691, 2105, 3686, 2078, 3684, 2065, 3672, 2064, 3676, 2051,  [...]
+        "center":[2120, 3685],
+        "bbox":[1960.1014003427006, 3644.1595168638105, 254.2874052757868, 84.54144869704987]
+      },
+      "USA":{
+        "shape":[[2218, 3158, 2231, 3148, 2251, 3147, 2259, 3141, 2264, 3147, 2269, 3144, 2237, 3158, 2218, 3158], [0, 2141, 45, 2106, 58, 2112, 60, 2097, 82, 2083, 104, 2082, 92, 2106, 101, 2112, 147, 2121, 156, 2100, 164, 2118, 160, 2096, 144, 2102, 144, 2085, 129, 2074, 132, 2062, 151, 2090, 197, 2094, 185, 2089, 204, 2082, 197, 2078, 148, 2078, 153, 2060, 134, 2058, 136, 2049, 119, 2037, 123, 2011, 144, 1998, 121, 2008, 118, 2037, 133, 2051, 122, 2059, 102, 2054, 81, 2008, 29, 1974,  [...]
+        "center":[1677, 3216],
+        "bbox":[0.0, 1765.2626736896916, 2385.025951427826, 1833.6644244736492]
+      },
+      "NZL":{
+        "shape":[[7887, 5430, 7898, 5426, 7891, 5421, 7894, 5414, 7901, 5414, 7898, 5407, 7918, 5390, 7929, 5369, 7957, 5355, 7991, 5325, 8001, 5296, 8015, 5285, 8019, 5266, 8032, 5257, 8031, 5263, 8040, 5268, 8042, 5281, 8059, 5271, 8057, 5282, 8065, 5278, 8060, 5278, 8064, 5273, 8070, 5273, 8061, 5281, 8072, 5276, 8063, 5286, 8069, 5296, 8031, 5343, 8029, 5353, 8036, 5353, 8040, 5359, 8023, 5360, 8030, 5359, 8024, 5357, 7996, 5377, 7994, 5395, 7980, 5425, 7985, 5421, 7984, 5425, 7975,  [...]
+        "center":[8057, 5262],
+        "bbox":[7886.848432575008, 5070.797806735552, 292.1165540762877, 380.52155183251034]
+      },
+      "GUF":{
+        "shape":[2746, 4118, 2729, 4146, 2725, 4158, 2710, 4164, 2708, 4160, 2688, 4163, 2678, 4156, 2685, 4143, 2689, 4124, 2683, 4120, 2677, 4101, 2691, 4075, 2693, 4076, 2718, 4085, 2737, 4107, 2740, 4103, 2746, 4118],
+        "center":[2707, 4122],
+        "bbox":[2677.1952241875883, 4075.4790136318256, 69.02505923436865, 88.09989366864875]
+      },
+      "LAO":{
+        "shape":[6413, 3762, 6400, 3760, 6392, 3771, 6383, 3776, 6369, 3767, 6347, 3785, 6343, 3782, 6348, 3767, 6346, 3760, 6352, 3745, 6349, 3733, 6332, 3735, 6330, 3729, 6334, 3720, 6323, 3715, 6319, 3712, 6342, 3691, 6346, 3690, 6346, 3698, 6357, 3696, 6358, 3685, 6353, 3676, 6355, 3667, 6367, 3668, 6376, 3680, 6387, 3681, 6384, 3692, 6390, 3705, 6414, 3705, 6422, 3709, 6422, 3716, 6426, 3716, 6431, 3727, 6423, 3739, 6419, 3734, 6412, 3736, 6412, 3744, 6447, 3777, 6450, 3786, 6470, 3 [...]
+        "center":[6378, 3725],
+        "bbox":[6319.1533655034555, 3666.829503505623, 176.10813834087276, 213.16201549793186]
+      },
+      "KWT":{
+        "shape":[5093, 3465, 5098, 3476, 5088, 3483, 5097, 3485, 5102, 3496, 5104, 3500, 5091, 3503, 5083, 3493, 5063, 3490, 5079, 3464, 5093, 3465],
+        "center":[5089, 3482],
+        "bbox":[5062.769005308158, 3464.379966834263, 40.79251046020636, 38.732141511438385]
+      },
+      "JOR":{
+        "shape":[4877, 3372, 4888, 3406, 4882, 3413, 4833, 3426, 4860, 3448, 4844, 3468, 4831, 3469, 4814, 3488, 4789, 3483, 4790, 3479, 4793, 3460, 4790, 3457, 4798, 3430, 4786, 3428, 4790, 3403, 4794, 3399, 4804, 3399, 4803, 3390, 4814, 3396, 4833, 3402, 4877, 3372],
+        "center":[4816, 3434],
+        "bbox":[4785.883439950274, 3372.350930101926, 102.41509375068199, 116.08929339440101]
+      },
+      "PHL":{
+        "shape":[[6804, 3771, 6803, 3767, 6810, 3762, 6833, 3774, 6843, 3766, 6846, 3771, 6840, 3777, 6840, 3787, 6841, 3795, 6846, 3795, 6847, 3810, 6838, 3827, 6839, 3821, 6826, 3830, 6822, 3844, 6830, 3858, 6828, 3867, 6842, 3880, 6842, 3871, 6853, 3868, 6862, 3877, 6862, 3883, 6867, 3882, 6866, 3874, 6881, 3881, 6882, 3883, 6873, 3886, 6878, 3899, 6888, 3901, 6886, 3912, 6880, 3907, 6883, 3903, 6867, 3901, 6864, 3890, 6850, 3878, 6846, 3878, 6854, 3895, 6851, 3898, 6844, 3887, 6830,  [...]
+        "center":[6870, 3891],
+        "bbox":[6782.513965413912, 3762.416627929324, 162.9128000720575, 315.7026469368998]
+      },
+      "ZMB":{
+        "shape":[4518, 4629, 4511, 4624, 4482, 4593, 4482, 4517, 4532, 4518, 4528, 4511, 4531, 4502, 4531, 4472, 4524, 4468, 4532, 4466, 4540, 4470, 4540, 4480, 4546, 4481, 4562, 4472, 4562, 4484, 4579, 4491, 4593, 4492, 4605, 4485, 4615, 4498, 4630, 4507, 4634, 4505, 4647, 4526, 4662, 4522, 4663, 4527, 4666, 4526, 4667, 4498, 4659, 4499, 4657, 4505, 4635, 4488, 4643, 4440, 4637, 4427, 4649, 4411, 4690, 4405, 4691, 4411, 4709, 4416, 4713, 4423, 4732, 4427, 4735, 4431, 4741, 4432, 4745, 4 [...]
+        "center":[4589, 4557],
+        "bbox":[4481.589028782332, 4404.586960521956, 281.35410894730467, 232.10527817774437]
+      },
+      "BEN":{
+        "shape":[4001, 4058, 3998, 4051, 3999, 3993, 3991, 3979, 3994, 3973, 3981, 3963, 3981, 3945, 3994, 3933, 4019, 3927, 4017, 3924, 4020, 3920, 4019, 3916, 4029, 3911, 4041, 3922, 4047, 3922, 4048, 3926, 4045, 3939, 4049, 3942, 4051, 3957, 4044, 3961, 4045, 3972, 4039, 3976, 4035, 3990, 4028, 3994, 4024, 4020, 4027, 4027, 4026, 4056, 4017, 4059, 4001, 4058],
+        "center":[4015, 3967],
+        "bbox":[3980.621476949743, 3911.227524219283, 69.96214408841388, 147.2961339569215]
+      },
+      "UKR":{
+        "shape":[[4864, 2943, 4859, 2948, 4862, 2943, 4849, 2944, 4830, 2960, 4826, 2954, 4800, 2966, 4796, 2958, 4798, 2968, 4793, 2965, 4778, 2980, 4769, 2973, 4767, 2977, 4762, 2974, 4751, 2979, 4729, 2979, 4712, 2972, 4717, 2965, 4727, 2965, 4717, 2958, 4719, 2950, 4713, 2960, 4707, 2960, 4707, 2953, 4702, 2960, 4688, 2963, 4685, 2953, 4684, 2974, 4673, 2969, 4679, 2976, 4677, 2984, 4664, 2993, 4661, 2990, 4663, 3002, 4662, 3007, 4653, 3002, 4639, 3012, 4632, 3008, 4632, 3002, 4649,  [...]
+        "center":[4709, 2859],
+        "bbox":[4487.475154481034, 2751.8916704671847, 421.5818372120966, 284.8723929740363]
+      },
+      "NIC":{
+        "shape":[2001, 3850, 1996, 3854, 1999, 3864, 1990, 3886, 1994, 3911, 1991, 3913, 1988, 3904, 1990, 3914, 1987, 3925, 1990, 3929, 1986, 3945, 1991, 3949, 1993, 3952, 1982, 3955, 1974, 3948, 1941, 3946, 1940, 3944, 1894, 3899, 1902, 3900, 1902, 3899, 1914, 3899, 1914, 3889, 1922, 3880, 1928, 3880, 1934, 3873, 1940, 3877, 1950, 3867, 1956, 3866, 1957, 3857, 1963, 3852, 1971, 3858, 1985, 3855, 1990, 3850, 2001, 3850],
+        "center":[1957, 3907],
+        "bbox":[1893.6032386476159, 3849.558706219956, 107.5624168550537, 104.98880823327272]
+      },
+      "BEL":{
+        "shape":[4110, 2839, 4102, 2840, 4104, 2852, 4102, 2856, 4093, 2859, 4082, 2850, 4081, 2837, 4065, 2844, 4061, 2829, 4052, 2831, 4041, 2817, 4027, 2813, 4024, 2805, 4029, 2801, 4038, 2795, 4060, 2799, 4064, 2791, 4083, 2790, 4099, 2800, 4095, 2812, 4100, 2814, 4102, 2815, 4111, 2815, 4115, 2831, 4110, 2839],
+        "center":[4075, 2821],
+        "bbox":[4024.2013538186347, 2789.6354954546705, 91.23132921343495, 69.46935705474425]
+      },
+      "NAM":{
+        "shape":[4558, 4631, 4555, 4635, 4537, 4638, 4521, 4650, 4516, 4640, 4474, 4648, 4460, 4647, 4459, 4738, 4434, 4738, 4434, 4809, 4434, 4905, 4415, 4912, 4413, 4918, 4407, 4915, 4394, 4917, 4375, 4914, 4374, 4900, 4361, 4896, 4349, 4909, 4333, 4897, 4323, 4877, 4319, 4853, 4315, 4851, 4313, 4811, 4304, 4794, 4307, 4787, 4303, 4776, 4304, 4770, 4312, 4771, 4310, 4759, 4307, 4758, 4279, 4711, 4276, 4696, 4257, 4659, 4248, 4653, 4241, 4633, 4240, 4620, 4247, 4616, 4259, 4621, 4273, 4 [...]
+        "center":[4363, 4751],
+        "bbox":[4239.919702777384, 4613.979325499355, 318.4545648608482, 304.023592750269]
+      },
+      "PRY":{
+        "shape":[2571, 4670, 2590, 4682, 2592, 4692, 2599, 4712, 2594, 4741, 2621, 4745, 2632, 4739, 2649, 4744, 2657, 4784, 2665, 4789, 2677, 4781, 2683, 4787, 2681, 4796, 2675, 4825, 2674, 4838, 2672, 4849, 2647, 4874, 2626, 4879, 2590, 4872, 2580, 4873, 2579, 4867, 2589, 4853, 2602, 4816, 2549, 4786, 2541, 4789, 2522, 4782, 2482, 4742, 2483, 4741, 2486, 4740, 2497, 4698, 2504, 4690, 2508, 4675, 2571, 4670],
+        "center":[2594, 4776],
+        "bbox":[2481.839790920032, 4669.708663951643, 201.25569138441915, 208.8533217319009]
+      },
+      "SUR":{
+        "shape":[2691, 4075, 2677, 4101, 2683, 4120, 2689, 4124, 2685, 4143, 2678, 4156, 2673, 4154, 2669, 4150, 2655, 4156, 2648, 4153, 2642, 4158, 2645, 4168, 2636, 4163, 2629, 4160, 2618, 4131, 2608, 4130, 2609, 4126, 2599, 4115, 2606, 4097, 2620, 4092, 2619, 4078, 2619, 4069, 2647, 4075, 2652, 4068, 2664, 4074, 2665, 4069, 2673, 4069, 2691, 4075],
+        "center":[2648, 4114],
+        "bbox":[2598.713618778766, 4068.2855466250558, 91.81784441600394, 99.25381538187139]
+      },
+      "CAF":{
+        "shape":[4344, 4156, 4340, 4151, 4342, 4138, 4318, 4118, 4320, 4105, 4311, 4099, 4309, 4086, 4303, 4083, 4308, 4070, 4304, 4063, 4331, 4028, 4335, 4032, 4351, 4021, 4357, 4028, 4379, 4017, 4386, 4019, 4410, 4012, 4415, 4003, 4410, 3996, 4444, 3989, 4456, 3981, 4474, 3962, 4480, 3948, 4498, 3946, 4502, 3950, 4508, 3956, 4521, 3975, 4517, 3993, 4519, 4001, 4535, 4000, 4534, 4012, 4551, 4015, 4552, 4020, 4556, 4020, 4558, 4029, 4565, 4037, 4583, 4049, 4588, 4065, 4605, 4074, 4607, 4 [...]
+        "center":[4458, 4052],
+        "bbox":[4303.155287232756, 3945.660975811254, 304.0556421105539, 210.48245674590044]
+      },
+      "AUS":{
+        "shape":[[6625, 4829, 6639, 4856, 6645, 4857, 6647, 4848, 6638, 4836, 6638, 4829, 6644, 4837, 6643, 4843, 6649, 4843, 6652, 4853, 6655, 4851, 6656, 4838, 6636, 4802, 6646, 4775, 6643, 4758, 6652, 4735, 6653, 4755, 6657, 4749, 6660, 4752, 6666, 4736, 6686, 4727, 6702, 4711, 6718, 4703, 6717, 4707, 6734, 4709, 6748, 4699, 6764, 4696, 6771, 4689, 6782, 4691, 6802, 4687, 6823, 4675, 6835, 4652, 6848, 4644, 6849, 4641, 6843, 4641, 6847, 4636, 6842, 4631, 6846, 4619, 6855, 4616, 6853,  [...]
+        "center":[7117, 4789],
+        "bbox":[6625.047704026235, 4467.96818298695, 954.9796844935727, 882.444651306072]
+      },
+      "ESH":{
+        "shape":[3650, 3529, 3757, 3529, 3757, 3536, 3755, 3575, 3675, 3575, 3674, 3639, 3663, 3640, 3652, 3647, 3647, 3661, 3653, 3694, 3558, 3693, 3559, 3682, 3561, 3673, 3574, 3659, 3573, 3653, 3579, 3650, 3576, 3647, 3589, 3629, 3588, 3626, 3609, 3605, 3618, 3569, 3633, 3560, 3650, 3529],
+        "center":[3631, 3608],
+        "bbox":[3558.22687186442, 3528.8982137963267, 198.68406765282953, 165.15657287448175]
+      },
+      "PRT":{
+        "shape":[3755, 3117, 3770, 3112, 3772, 3122, 3801, 3117, 3814, 3128, 3797, 3148, 3800, 3179, 3796, 3188, 3786, 3189, 3796, 3208, 3791, 3228, 3797, 3232, 3787, 3248, 3790, 3260, 3787, 3262, 3778, 3267, 3759, 3263, 3750, 3266, 3755, 3254, 3755, 3226, 3759, 3227, 3756, 3221, 3746, 3223, 3751, 3210, 3740, 3217, 3739, 3214, 3741, 3196, 3748, 3192, 3760, 3157, 3755, 3117],
+        "center":[3769, 3196],
+        "bbox":[3739.3660452096688, 3112.1695654274836, 74.3965558369232, 154.37406712196798]
+      },
+      "TZA":{
+        "shape":[4684, 4268, 4683, 4265, 4688, 4266, 4694, 4258, 4691, 4251, 4693, 4247, 4683, 4232, 4690, 4231, 4695, 4233, 4766, 4233, 4855, 4279, 4853, 4291, 4890, 4319, 4890, 4329, 4882, 4352, 4884, 4361, 4900, 4377, 4893, 4390, 4896, 4397, 4892, 4412, 4897, 4421, 4894, 4424, 4901, 4432, 4902, 4452, 4904, 4448, 4906, 4454, 4914, 4454, 4916, 4456, 4889, 4474, 4858, 4476, 4847, 4484, 4826, 4486, 4812, 4478, 4804, 4483, 4791, 4485, 4782, 4474, 4782, 4450, 4773, 4438, 4767, 4435, 4762, 4 [...]
+        "center":[4799, 4388],
+        "bbox":[4656.445415973089, 4230.9285935038415, 259.47791959071674, 255.51703813287259]
+      },
+      "ISR":{
+        "shape":[4790, 3479, 4775, 3439, 4782, 3426, 4780, 3422, 4780, 3414, 4790, 3385, 4791, 3381, 4806, 3374, 4805, 3380, 4804, 3386, 4803, 3390, 4804, 3399, 4794, 3399, 4790, 3403, 4786, 3428, 4798, 3430, 4790, 3457, 4793, 3460, 4790, 3479],
+        "center":[4785, 3410],
+        "bbox":[4774.701521360906, 3373.6469840011073, 31.212318859447805, 105.15244258062694]
+      },
+      "BGD":{
+        "shape":[6070, 3673, 6059, 3644, 6062, 3640, 6055, 3640, 6057, 3633, 6049, 3626, 6061, 3616, 6037, 3601, 6042, 3597, 6046, 3600, 6052, 3593, 6063, 3593, 6064, 3587, 6044, 3573, 6050, 3556, 6058, 3562, 6063, 3556, 6069, 3557, 6071, 3566, 6085, 3575, 6086, 3592, 6100, 3596, 6136, 3593, 6144, 3600, 6140, 3609, 6119, 3621, 6116, 3643, 6120, 3645, 6125, 3640, 6125, 3645, 6130, 3646, 6132, 3634, 6137, 3629, 6134, 3624, 6142, 3625, 6147, 3630, 6144, 3635, 6149, 3668, 6141, 3680, 6146, 3 [...]
+        "center":[6085, 3618],
+        "bbox":[6036.901556885723, 3556.0256815728944, 112.13941484451607, 144.96574054655684]
+      },
+      "MKD":{
+        "shape":[4492, 3103, 4503, 3116, 4506, 3130, 4504, 3133, 4503, 3133, 4501, 3139, 4485, 3138, 4478, 3145, 4459, 3150, 4452, 3147, 4447, 3119, 4449, 3115, 4459, 3108, 4466, 3112, 4492, 3103],
+        "center":[4476, 3128],
+        "bbox":[4447.13292297698, 3103.4130767908296, 58.79588793672883, 46.47564805536467]
+      },
+      "KAZ":{
+        "shape":[5200, 3121, 5198, 3111, 5207, 3093, 5186, 3087, 5179, 3077, 5170, 3078, 5172, 3066, 5156, 3042, 5145, 3035, 5153, 3029, 5178, 3033, 5162, 3023, 5175, 3007, 5221, 3007, 5207, 2998, 5215, 2971, 5213, 2953, 5199, 2951, 5194, 2957, 5171, 2945, 5159, 2953, 5151, 2952, 5137, 2968, 5122, 2968, 5120, 2972, 5100, 2963, 5116, 2958, 5111, 2939, 5095, 2924, 5077, 2924, 5074, 2907, 5059, 2898, 5074, 2873, 5067, 2864, 5081, 2827, 5106, 2849, 5115, 2842, 5107, 2820, 5153, 2791, 5160, 2 [...]
+        "center":[5567, 2886],
+        "bbox":[5059.388234473865, 2630.9665494024016, 964.7501079702461, 518.2096263303902]
+      },
+      "SDN":{
+        "shape":[4804, 3649, 4810, 3659, 4834, 3676, 4847, 3758, 4868, 3771, 4874, 3776, 4866, 3788, 4859, 3788, 4850, 3799, 4839, 3801, 4825, 3847, 4827, 3862, 4827, 3869, 4824, 3879, 4815, 3904, 4805, 3906, 4793, 3928, 4791, 3949, 4787, 3953, 4778, 3950, 4773, 3957, 4769, 4003, 4765, 4010, 4748, 4009, 4745, 4020, 4760, 4024, 4772, 4041, 4779, 4042, 4788, 4051, 4793, 4078, 4798, 4083, 4807, 4083, 4807, 4093, 4810, 4100, 4773, 4100, 4766, 4107, 4753, 4120, 4741, 4116, 4724, 4120, 4699, 4 [...]
+        "center":[4665, 3875],
+        "bbox":[4478.1089075776745, 3649.148366335325, 395.89238268117697, 473.9220484423872]
+      },
+      "SLE":{
+        "shape":[3647, 3991, 3660, 3987, 3668, 3972, 3696, 3971, 3711, 3999, 3708, 4002, 3710, 4015, 3719, 4007, 3719, 4009, 3718, 4015, 3711, 4018, 3709, 4029, 3692, 4045, 3683, 4039, 3685, 4038, 3657, 4028, 3671, 4028, 3659, 4025, 3653, 4011, 3649, 4012, 3646, 4008, 3656, 4005, 3648, 4004, 3647, 3999, 3656, 3998, 3647, 3991],
+        "center":[3678, 4005],
+        "bbox":[3646.003479851343, 3970.9992900347665, 72.96511919410796, 73.77300919969002]
+      },
+      "ISL":{
+        "shape":[3400, 2126, 3405, 2117, 3419, 2123, 3410, 2107, 3423, 2118, 3431, 2114, 3415, 2103, 3432, 2104, 3416, 2094, 3426, 2094, 3424, 2083, 3450, 2103, 3451, 2088, 3436, 2080, 3450, 2077, 3430, 2074, 3448, 2065, 3477, 2092, 3470, 2095, 3477, 2107, 3466, 2107, 3485, 2142, 3487, 2117, 3502, 2113, 3499, 2086, 3506, 2082, 3523, 2105, 3522, 2086, 3537, 2076, 3557, 2107, 3550, 2078, 3571, 2087, 3577, 2074, 3594, 2073, 3591, 2055, 3604, 2052, 3621, 2074, 3641, 2058, 3626, 2075, 3640, 2 [...]
+        "center":[3551, 2156],
+        "bbox":[3399.938468959589, 2051.7230846774187, 271.1370587124311, 186.55024865821406]
+      },
+      "LSO":{
+        "shape":[4602, 4937, 4627, 4911, 4630, 4914, 4640, 4910, 4659, 4927, 4647, 4953, 4630, 4955, 4623, 4965, 4606, 4950, 4602, 4937],
+        "center":[4630, 4934],
+        "bbox":[4601.8422512848265, 4910.036204187407, 57.35501644920441, 55.41940446524859]
+      },
+      "GHA":{
+        "shape":[3892, 4089, 3898, 4089, 3899, 4074, 3889, 4073, 3883, 4047, 3892, 4035, 3891, 4020, 3901, 4012, 3897, 3992, 3900, 3987, 3898, 3980, 3897, 3961, 3893, 3956, 3897, 3945, 3943, 3946, 3946, 3949, 3954, 3943, 3965, 3946, 3964, 3951, 3963, 3956, 3972, 3965, 3971, 3978, 3967, 3983, 3974, 3982, 3975, 3996, 3971, 4002, 3980, 4009, 3975, 4014, 3975, 4045, 3987, 4063, 3982, 4066, 3980, 4071, 3973, 4071, 3942, 4086, 3923, 4090, 3912, 4097, 3892, 4089],
+        "center":[3938, 4021],
+        "bbox":[3882.660356040404, 3943.263069669189, 104.74856374084266, 154.1725147556631]
+      },
+      "PRI":{
+        "shape":[2377, 3766, 2381, 3762, 2409, 3764, 2418, 3766, 2418, 3770, 2404, 3777, 2379, 3777, 2377, 3766],
+        "center":[2395, 3769],
+        "bbox":[2377.2251741855853, 3762.079884692103, 40.77461998328363, 15.414074989630535]
+      },
+      "DNK":{
+        "shape":[4154, 2602, 4159, 2593, 4154, 2582, 4167, 2590, 4176, 2573, 4177, 2585, 4183, 2587, 4180, 2567, 4206, 2567, 4204, 2581, 4221, 2591, 4191, 2621, 4191, 2653, 4187, 2656, 4167, 2654, 4168, 2649, 4167, 2633, 4155, 2627, 4160, 2612, 4154, 2602],
+        "center":[4183, 2607],
+        "bbox":[4153.679095448544, 2566.555010137012, 67.26402495901948, 89.70073407297332]
+      },
+      "BOL":{
+        "shape":[2322, 4467, 2340, 4466, 2345, 4471, 2354, 4467, 2360, 4458, 2367, 4460, 2394, 4442, 2416, 4441, 2421, 4436, 2425, 4451, 2420, 4457, 2423, 4469, 2421, 4480, 2442, 4499, 2440, 4503, 2475, 4508, 2478, 4513, 2498, 4519, 2506, 4528, 2537, 4537, 2540, 4552, 2539, 4567, 2535, 4566, 2545, 4593, 2589, 4593, 2586, 4604, 2589, 4617, 2604, 4627, 2602, 4632, 2606, 4639, 2595, 4679, 2598, 4686, 2592, 4692, 2590, 4682, 2571, 4670, 2508, 4675, 2504, 4690, 2497, 4698, 2486, 4740, 2483, 4 [...]
+        "center":[2429, 4599],
+        "bbox":[2316.228069492129, 4436.041885893162, 289.5982312626288, 324.75719991725055]
+      },
+      "THA":{
+        "shape":[6259, 3760, 6268, 3759, 6267, 3751, 6275, 3729, 6280, 3732, 6295, 3730, 6299, 3721, 6309, 3720, 6309, 3714, 6317, 3713, 6319, 3712, 6323, 3715, 6334, 3720, 6330, 3729, 6332, 3735, 6349, 3733, 6352, 3745, 6346, 3760, 6348, 3767, 6343, 3782, 6347, 3785, 6369, 3767, 6383, 3776, 6392, 3771, 6400, 3760, 6413, 3762, 6415, 3764, 6431, 3784, 6431, 3806, 6440, 3817, 6447, 3818, 6448, 3826, 6453, 3828, 6449, 3835, 6453, 3843, 6451, 3855, 6441, 3863, 6439, 3863, 6437, 3861, 6434, 3 [...]
+        "center":[6348, 3828],
+        "bbox":[6258.610086103293, 3711.560247826593, 194.34626216399556, 361.79630949128796]
+      },
+      "DEU":{
+        "shape":[4102, 2815, 4112, 2793, 4108, 2776, 4121, 2772, 4131, 2761, 4132, 2753, 4122, 2748, 4131, 2742, 4135, 2721, 4137, 2721, 4132, 2706, 4152, 2702, 4156, 2714, 4167, 2707, 4167, 2696, 4199, 2709, 4173, 2693, 4176, 2678, 4166, 2678, 4177, 2672, 4169, 2661, 4167, 2654, 4187, 2656, 4189, 2658, 4197, 2658, 4197, 2673, 4213, 2679, 4230, 2670, 4219, 2694, 4227, 2690, 4231, 2694, 4238, 2684, 4269, 2676, 4286, 2684, 4287, 2697, 4297, 2701, 4300, 2702, 4305, 2724, 4300, 2737, 4310, 2 [...]
+        "center":[4203, 2795],
+        "bbox":[4102.055608217357, 2654.47781190281, 220.80556297183466, 285.4919962960903]
+      },
+      "LKA":{
+        "shape":[5851, 3984, 5864, 3981, 5870, 3988, 5891, 4030, 5889, 4054, 5879, 4062, 5863, 4067, 5853, 4064, 5844, 4046, 5844, 4019, 5851, 3984],
+        "center":[5864, 4020],
+        "bbox":[5843.671279382772, 3981.2649568467205, 47.773078145078216, 85.56976737465357]
+      },
+      "AND":{
+        "shape":[4003, 3096, 4003, 3100, 4003, 3100, 3997, 3098, 3998, 3096, 3999, 3094, 4003, 3096],
+        "center":[4000, 3098],
+        "bbox":[3996.5522965976493, 3093.882957353292, 6.683740589394802, 5.990874970387267]
+      },
+      "LBN":{
+        "shape":[4810, 3336, 4822, 3337, 4825, 3347, 4812, 3361, 4810, 3372, 4806, 3374, 4791, 3381, 4792, 3378, 4810, 3336],
+        "center":[4807, 3358],
+        "bbox":[4790.932788874814, 3336.1386993162987, 34.16022484086443, 45.28106174275308]
+      },
+      "ITA":{
+        "shape":[[4265, 3236, 4268, 3238, 4276, 3233, 4281, 3239, 4299, 3239, 4327, 3230, 4318, 3253, 4324, 3265, 4320, 3276, 4303, 3272, 4299, 3263, 4287, 3262, 4273, 3251, 4258, 3247, 4258, 3239, 4265, 3236], [4155, 3152, 4181, 3138, 4191, 3156, 4187, 3202, 4173, 3197, 4171, 3210, 4160, 3204, 4164, 3178, 4160, 3179, 4161, 3162, 4155, 3152], [4139, 3058, 4144, 3043, 4137, 3046, 4124, 3041, 4129, 3025, 4122, 3015, 4131, 3003, 4124, 2989, 4137, 2989, 4140, 2986, 4150, 2983, 4160, 2968, 41 [...]
+        "center":[4271, 3096],
+        "bbox":[4121.722125185002, 2947.2230733308274, 276.22048158525104, 328.48260061912333]
+      },
+      "SLV":{
+        "shape":[1854, 3867, 1869, 3868, 1879, 3877, 1893, 3877, 1897, 3885, 1894, 3888, 1893, 3889, 1889, 3890, 1888, 3896, 1871, 3894, 1874, 3896, 1836, 3883, 1835, 3882, 1838, 3877, 1849, 3875, 1854, 3867],
+        "center":[1871, 3882],
+        "bbox":[1834.800946131871, 3866.679178074274, 61.916505829974085, 29.567241869063764]
+      },
+      "LBR":{
+        "shape":[3692, 4045, 3709, 4029, 3711, 4018, 3718, 4015, 3719, 4009, 3733, 4008, 3737, 4019, 3734, 4034, 3741, 4032, 3747, 4037, 3760, 4027, 3760, 4033, 3762, 4046, 3757, 4055, 3761, 4055, 3763, 4060, 3776, 4060, 3775, 4067, 3785, 4074, 3779, 4095, 3782, 4105, 3779, 4105, 3738, 4086, 3717, 4062, 3709, 4060, 3695, 4050, 3696, 4045, 3692, 4045],
+        "center":[3743, 4055],
+        "bbox":[3692.240226523307, 4007.7323030761336, 93.18122579046712, 97.67293304841769]
+      },
+      "CAN":{
+        "shape":[[638, 2411, 639, 1886, 642, 1886, 675, 1885, 747, 1941, 762, 1934, 795, 1951, 775, 1932, 790, 1931, 808, 1962, 794, 1927, 806, 1909, 834, 1898, 844, 1877, 854, 1880, 869, 1864, 875, 1872, 880, 1858, 908, 1846, 916, 1860, 884, 1886, 854, 1893, 822, 1937, 828, 1945, 824, 1936, 845, 1938, 836, 1931, 848, 1920, 836, 1922, 877, 1892, 880, 1920, 894, 1886, 929, 1865, 923, 1879, 937, 1889, 928, 1876, 943, 1850, 960, 1846, 945, 1832, 951, 1821, 981, 1881, 1006, 1905, 1018, 1899, [...]
+        "center":[1431, 2480],
+        "bbox":[637.5712890894472, 1733.2872042495694, 2014.0455285571131, 1381.4546730047703]
+      },
+      "PRK":{
+        "shape":[6919, 3160, 6937, 3150, 6957, 3122, 6961, 3131, 6988, 3136, 6992, 3127, 6984, 3120, 6987, 3115, 6999, 3119, 7014, 3104, 7024, 3103, 7029, 3085, 7046, 3104, 7042, 3106, 7022, 3128, 7026, 3135, 7024, 3151, 7012, 3155, 7010, 3163, 6997, 3167, 6995, 3174, 6984, 3174, 6971, 3183, 6973, 3197, 6969, 3194, 6967, 3199, 6981, 3208, 6987, 3216, 6979, 3227, 6974, 3222, 6957, 3227, 6950, 3242, 6945, 3239, 6933, 3242, 6928, 3238, 6921, 3247, 6923, 3240, 6911, 3242, 6918, 3237, 6903, 3 [...]
+        "center":[6947, 3193],
+        "bbox":[6896.806589137735, 3084.6204540439203, 149.34673724594813, 162.39080041700026]
+      },
+      "LBY":{
+        "shape":[4236, 3381, 4257, 3391, 4278, 3389, 4319, 3401, 4336, 3431, 4372, 3438, 4416, 3460, 4424, 3458, 4438, 3441, 4434, 3419, 4439, 3406, 4473, 3386, 4503, 3393, 4509, 3396, 4508, 3403, 4514, 3407, 4543, 3414, 4548, 3412, 4555, 3418, 4558, 3422, 4551, 3433, 4554, 3444, 4547, 3460, 4553, 3485, 4554, 3676, 4552, 3725, 4530, 3726, 4529, 3738, 4342, 3641, 4317, 3651, 4297, 3660, 4265, 3641, 4245, 3636, 4234, 3617, 4208, 3611, 4199, 3600, 4197, 3584, 4185, 3566, 4197, 3552, 4194, 3 [...]
+        "center":[4384, 3544],
+        "bbox":[4184.562584166332, 3381.136318739763, 372.9768121923207, 356.4903539628431]
+      },
+      "GIN":{
+        "shape":[3608, 3946, 3619, 3930, 3635, 3930, 3638, 3925, 3632, 3916, 3652, 3906, 3655, 3909, 3668, 3915, 3689, 3908, 3693, 3903, 3691, 3918, 3696, 3921, 3703, 3917, 3711, 3925, 3721, 3917, 3730, 3921, 3739, 3915, 3735, 3912, 3739, 3909, 3745, 3910, 3753, 3922, 3751, 3926, 3766, 3937, 3761, 3943, 3766, 3947, 3766, 3960, 3771, 3962, 3773, 3967, 3771, 3977, 3777, 3994, 3775, 3998, 3780, 4004, 3777, 4008, 3769, 4005, 3766, 4012, 3774, 4015, 3768, 4029, 3760, 4027, 3747, 4037, 3741, 4 [...]
+        "center":[3714, 3951],
+        "bbox":[3608.0950677692113, 3903.1554521857233, 172.12855260112747, 133.7150124305631]
+      },
+      "IRQ":{
+        "shape":[4877, 3372, 4928, 3344, 4934, 3330, 4939, 3284, 4953, 3279, 4963, 3267, 4967, 3264, 4971, 3257, 4983, 3257, 4993, 3262, 5007, 3260, 5008, 3268, 5011, 3267, 5019, 3262, 5023, 3284, 5029, 3286, 5032, 3299, 5058, 3303, 5049, 3311, 5051, 3320, 5035, 3344, 5040, 3366, 5051, 3373, 5048, 3383, 5065, 3388, 5074, 3397, 5081, 3397, 5091, 3419, 5087, 3437, 5091, 3437, 5107, 3464, 5103, 3465, 5096, 3464, 5093, 3465, 5079, 3464, 5063, 3490, 5019, 3488, 4990, 3477, 4992, 3455, 4977, 3 [...]
+        "center":[4978, 3376],
+        "bbox":[4877.394235086316, 3257.1472153151867, 229.6220482226645, 232.4342935758209]
+      },
+      "ETH":{
+        "shape":[4965, 3913, 4951, 3930, 4952, 3946, 4978, 3947, 4972, 3958, 4988, 3985, 4997, 3988, 5003, 3995, 5077, 4020, 5097, 4019, 5025, 4094, 5004, 4091, 4983, 4099, 4977, 4107, 4961, 4109, 4955, 4114, 4930, 4113, 4924, 4109, 4908, 4112, 4899, 4128, 4864, 4122, 4834, 4103, 4810, 4100, 4807, 4093, 4807, 4083, 4798, 4083, 4793, 4078, 4788, 4051, 4779, 4042, 4772, 4041, 4760, 4024, 4745, 4020, 4748, 4009, 4765, 4010, 4769, 4003, 4773, 3957, 4778, 3950, 4787, 3953, 4791, 3949, 4793, 3 [...]
+        "center":[4894, 4010],
+        "bbox":[4744.600158774018, 3856.562272165843, 352.3780849301238, 271.16343128677]
+      },
+      "IRN":{
+        "shape":[5019, 3262, 5011, 3245, 5006, 3242, 5011, 3231, 5003, 3200, 5012, 3191, 5015, 3186, 5017, 3191, 5021, 3199, 5046, 3214, 5053, 3216, 5056, 3215, 5060, 3215, 5094, 3190, 5101, 3195, 5097, 3202, 5103, 3205, 5095, 3213, 5113, 3225, 5116, 3239, 5121, 3251, 5145, 3257, 5159, 3272, 5178, 3279, 5189, 3281, 5230, 3271, 5223, 3275, 5227, 3276, 5239, 3272, 5236, 3264, 5235, 3258, 5253, 3258, 5271, 3237, 5292, 3235, 5301, 3229, 5317, 3231, 5321, 3240, 5338, 3250, 5362, 3253, 5391, 3 [...]
+        "center":[5258, 3397],
+        "bbox":[5002.766568787266, 3185.9402589219503, 456.45582856568126, 409.90935962829826]
+      },
+      "SEN":{
+        "shape":[3570, 3821, 3576, 3811, 3609, 3808, 3629, 3812, 3636, 3821, 3646, 3821, 3648, 3834, 3659, 3837, 3668, 3852, 3673, 3853, 3673, 3863, 3677, 3868, 3674, 3881, 3678, 3891, 3685, 3890, 3693, 3903, 3689, 3908, 3668, 3915, 3655, 3909, 3652, 3906, 3609, 3907, 3600, 3912, 3565, 3914, 3564, 3911, 3593, 3909, 3596, 3904, 3563, 3908, 3564, 3900, 3564, 3896, 3588, 3894, 3588, 3890, 3600, 3889, 3604, 3885, 3626, 3894, 3635, 3887, 3622, 3887, 3622, 3882, 3607, 3879, 3584, 3885, 3569, 3 [...]
+        "center":[3613, 3850],
+        "bbox":[3548.097342054373, 3807.6350200724432, 144.64778760314493, 107.20227837878019]
+      },
+      "GIB":{
+        "shape":[3835, 3295, 3835, 3295, 3838, 3291, 3838, 3292, 3835, 3295],
+        "center":[3836, 3293],
+        "bbox":[3835.005980945054, 3291.153624398843, 2.921176126843875, 3.804637518301206]
+      },
+      "NCL":{
+        "shape":[7829, 4697, 7837, 4695, 7859, 4710, 7866, 4722, 7897, 4741, 7899, 4748, 7897, 4751, 7882, 4745, 7850, 4723, 7829, 4697],
+        "center":[7863, 4724],
+        "bbox":[7828.570786234575, 4695.4379750776, 70.48128053936944, 55.41935153484337]
+      },
+      "MYS":{
+        "shape":[[6549, 4156, 6553, 4155, 6553, 4160, 6559, 4163, 6569, 4165, 6569, 4161, 6570, 4166, 6573, 4163, 6573, 4167, 6588, 4171, 6585, 4166, 6590, 4166, 6586, 4161, 6590, 4155, 6597, 4153, 6588, 4153, 6589, 4148, 6595, 4150, 6594, 4142, 6631, 4132, 6653, 4106, 6652, 4100, 6657, 4100, 6666, 4111, 6671, 4111, 6671, 4096, 6678, 4091, 6676, 4099, 6682, 4107, 6681, 4092, 6685, 4093, 6690, 4086, 6685, 4082, 6690, 4076, 6696, 4078, 6702, 4071, 6699, 4067, 6706, 4063, 6717, 4044, 6717,  [...]
+        "center":[6655, 4131],
+        "bbox":[6320.969725284731, 4044.466110073577, 456.74451099507496, 136.5773911477213]
+      },
+      "IRL":{
+        "shape":[3793, 2648, 3773, 2672, 3774, 2676, 3787, 2686, 3798, 2674, 3809, 2688, 3814, 2686, 3816, 2687, 3822, 2730, 3812, 2756, 3816, 2762, 3784, 2766, 3777, 2775, 3765, 2774, 3764, 2782, 3745, 2789, 3733, 2790, 3740, 2780, 3725, 2785, 3735, 2775, 3720, 2776, 3730, 2764, 3716, 2764, 3723, 2757, 3734, 2759, 3730, 2753, 3737, 2747, 3758, 2743, 3751, 2738, 3746, 2745, 3729, 2748, 3746, 2723, 3752, 2722, 3724, 2713, 3737, 2699, 3727, 2682, 3761, 2682, 3759, 2678, 3771, 2668, 3757, 2 [...]
+        "center":[3779, 2722],
+        "bbox":[3716.37006020287, 2636.1125492466463, 105.92124348204561, 153.48314254339175]
+      },
+      "BWA":{
+        "shape":[4555, 4635, 4579, 4662, 4585, 4678, 4605, 4691, 4609, 4701, 4620, 4702, 4619, 4715, 4624, 4726, 4648, 4730, 4654, 4740, 4657, 4743, 4638, 4753, 4630, 4752, 4616, 4769, 4607, 4773, 4594, 4796, 4579, 4808, 4565, 4834, 4558, 4837, 4531, 4833, 4518, 4822, 4507, 4822, 4493, 4847, 4486, 4848, 4484, 4856, 4478, 4856, 4474, 4864, 4467, 4861, 4452, 4864, 4455, 4840, 4444, 4815, 4434, 4809, 4434, 4738, 4459, 4738, 4460, 4647, 4474, 4648, 4516, 4640, 4521, 4650, 4537, 4638, 4555, 4635],
+        "center":[4531, 4739],
+        "bbox":[4434.351870988851, 4635.120893763615, 222.37280580152492, 228.84643253159084]
+      },
+      "DOM":{
+        "shape":[2269, 3766, 2275, 3758, 2269, 3754, 2274, 3750, 2272, 3734, 2272, 3733, 2275, 3727, 2283, 3730, 2291, 3727, 2315, 3733, 2317, 3742, 2330, 3741, 2332, 3745, 2322, 3747, 2339, 3749, 2352, 3760, 2346, 3770, 2318, 3764, 2309, 3771, 2300, 3770, 2300, 3765, 2288, 3768, 2282, 3784, 2272, 3781, 2272, 3775, 2271, 3773, 2270, 3767, 2269, 3766],
+        "center":[2302, 3751],
+        "bbox":[2268.5082393345774, 3726.590630309682, 83.41101403541415, 57.83853569975645]
+      },
+      "GRL":{
+        "shape":[2240, 1153, 2347, 1043, 2413, 1033, 2412, 947, 2431, 920, 2403, 905, 2431, 876, 2419, 864, 2370, 914, 2334, 851, 2378, 771, 2376, 718, 2422, 782, 2395, 695, 2452, 707, 2411, 568, 2429, 529, 2530, 633, 2444, 497, 2523, 457, 2545, 482, 2541, 440, 2571, 450, 2546, 413, 2591, 398, 2654, 632, 2655, 507, 2711, 590, 2713, 555, 2753, 555, 2680, 384, 2715, 385, 2850, 608, 2878, 612, 2889, 582, 2948, 625, 2883, 554, 2777, 336, 2848, 362, 2840, 310, 2893, 304, 2955, 429, 3009, 457, [...]
+        "center":[3028, 1401],
+        "bbox":[2240.1369070382534, 0.0, 1546.6342573728675, 2425.04588969525]
+      },
+      "GAB":{
+        "shape":[4229, 4157, 4230, 4152, 4277, 4152, 4279, 4156, 4279, 4160, 4273, 4164, 4279, 4175, 4298, 4175, 4303, 4179, 4304, 4187, 4293, 4201, 4294, 4214, 4307, 4221, 4303, 4233, 4306, 4253, 4295, 4267, 4286, 4258, 4283, 4264, 4271, 4263, 4265, 4253, 4258, 4250, 4254, 4265, 4237, 4261, 4236, 4272, 4245, 4280, 4245, 4294, 4243, 4296, 4235, 4290, 4223, 4300, 4220, 4295, 4194, 4269, 4199, 4271, 4203, 4267, 4190, 4266, 4182, 4254, 4189, 4254, 4181, 4251, 4187, 4246, 4182, 4244, 4184, 4 [...]
+        "center":[4235, 4225],
+        "bbox":[4166.971441917299, 4151.605937190645, 139.83286744277666, 148.44166040030996]
+      },
+      "BGR":{
+        "shape":[4589, 3124, 4581, 3123, 4582, 3134, 4563, 3137, 4544, 3127, 4504, 3133, 4506, 3130, 4503, 3116, 4492, 3103, 4497, 3101, 4493, 3089, 4505, 3076, 4491, 3059, 4496, 3048, 4500, 3047, 4506, 3049, 4505, 3060, 4536, 3065, 4555, 3060, 4569, 3063, 4598, 3048, 4619, 3049, 4625, 3056, 4634, 3057, 4635, 3060, 4634, 3069, 4620, 3074, 4620, 3091, 4608, 3098, 4620, 3110, 4621, 3116, 4611, 3119, 4605, 3113, 4588, 3119, 4589, 3124],
+        "center":[4559, 3103],
+        "bbox":[4491.25708485555, 3046.838201582335, 143.71494214373251, 90.41677659311244]
+      },
+      "AUT":{
+        "shape":[4288, 2965, 4260, 2960, 4251, 2953, 4253, 2948, 4235, 2947, 4222, 2956, 4210, 2951, 4208, 2950, 4202, 2955, 4190, 2947, 4187, 2948, 4187, 2946, 4186, 2941, 4188, 2933, 4187, 2929, 4198, 2929, 4206, 2940, 4210, 2929, 4231, 2937, 4239, 2927, 4251, 2932, 4252, 2923, 4272, 2933, 4273, 2927, 4267, 2923, 4273, 2914, 4269, 2908, 4288, 2894, 4289, 2889, 4298, 2896, 4304, 2890, 4310, 2893, 4318, 2878, 4367, 2890, 4365, 2895, 4366, 2911, 4369, 2914, 4367, 2923, 4357, 2924, 4353, 2 [...]
+        "center":[4306, 2931],
+        "bbox":[4186.094641509236, 2878.349818498274, 182.57337560172982, 91.52810337850815]
+      },
+      "EST":{
+        "shape":[[4481, 2479, 4496, 2472, 4505, 2482, 4495, 2489, 4481, 2479], [4482, 2526, 4478, 2498, 4481, 2502, 4501, 2492, 4511, 2499, 4487, 2512, 4482, 2526], [4535, 2527, 4540, 2502, 4529, 2511, 4521, 2507, 4515, 2494, 4524, 2487, 4514, 2484, 4516, 2465, 4561, 2447, 4599, 2457, 4624, 2453, 4628, 2458, 4604, 2482, 4607, 2494, 4616, 2518, 4608, 2538, 4609, 2543, 4586, 2541, 4565, 2522, 4535, 2529, 4535, 2527]],
+        "center":[4489, 2505],
+        "bbox":[4477.909571672083, 2446.9859660507886, 149.69544275472072, 95.57135116298241]
+      },
+      "HND":{
+        "shape":[1854, 3865, 1861, 3859, 1862, 3851, 1884, 3834, 1886, 3835, 1889, 3829, 1911, 3832, 1937, 3827, 1934, 3824, 1945, 3829, 1955, 3826, 1966, 3831, 1975, 3829, 1987, 3840, 1977, 3834, 1974, 3841, 1979, 3840, 1989, 3846, 1993, 3844, 1991, 3841, 2000, 3850, 2001, 3850, 1990, 3850, 1985, 3855, 1971, 3858, 1963, 3852, 1957, 3857, 1956, 3866, 1950, 3867, 1940, 3877, 1934, 3873, 1928, 3880, 1922, 3880, 1914, 3889, 1914, 3899, 1902, 3899, 1902, 3898, 1896, 3888, 1894, 3888, 1897, 3 [...]
+        "center":[1916, 3855],
+        "bbox":[1854.0305623032527, 3824.247015990207, 147.13509319941681, 74.7278604750204]
+      },
+      "MRT":{
+        "shape":[3757, 3536, 3845, 3599, 3805, 3599, 3827, 3813, 3836, 3817, 3830, 3837, 3741, 3838, 3741, 3834, 3736, 3834, 3735, 3840, 3720, 3838, 3709, 3833, 3702, 3843, 3689, 3831, 3688, 3837, 3682, 3836, 3679, 3854, 3673, 3853, 3668, 3852, 3659, 3837, 3648, 3834, 3646, 3821, 3636, 3821, 3629, 3812, 3609, 3808, 3576, 3811, 3570, 3821, 3571, 3809, 3582, 3780, 3580, 3764, 3571, 3743, 3575, 3740, 3571, 3737, 3578, 3721, 3557, 3697, 3558, 3693, 3653, 3694, 3647, 3661, 3652, 3647, 3663, 3 [...]
+        "center":[3708, 3742],
+        "bbox":[3557.4086207320406, 3536.137346510093, 287.4261923917102, 318.19570871472615]
+      },
+      "ESP":{
+        "shape":[4003, 3100, 4028, 3104, 4036, 3101, 4038, 3117, 4013, 3137, 3983, 3147, 3982, 3155, 3962, 3176, 3954, 3196, 3967, 3216, 3950, 3229, 3943, 3246, 3946, 3248, 3927, 3254, 3912, 3275, 3907, 3270, 3898, 3275, 3857, 3275, 3852, 3281, 3844, 3282, 3838, 3291, 3838, 3291, 3835, 3295, 3835, 3295, 3821, 3290, 3818, 3277, 3809, 3267, 3793, 3261, 3790, 3260, 3787, 3248, 3797, 3232, 3791, 3228, 3796, 3208, 3786, 3189, 3796, 3188, 3800, 3179, 3797, 3148, 3814, 3128, 3801, 3117, 3772, 3 [...]
+        "center":[3881, 3170],
+        "bbox":[3744.511780401888, 3058.435041617251, 293.01025088482993, 236.5281957579723]
+      },
+      "SWZ":{
+        "shape":[4719, 4875, 4704, 4877, 4688, 4861, 4699, 4837, 4703, 4834, 4716, 4841, 4719, 4838, 4719, 4875],
+        "center":[4707, 4858],
+        "bbox":[4688.484348968921, 4834.279032589687, 30.607483120415964, 42.79497354579871]
+      },
+      "ECU":{
+        "shape":[2070, 4290, 2078, 4288, 2085, 4270, 2076, 4271, 2077, 4266, 2071, 4274, 2057, 4265, 2054, 4262, 2060, 4257, 2056, 4247, 2060, 4241, 2055, 4235, 2063, 4232, 2067, 4224, 2065, 4219, 2079, 4203, 2074, 4190, 2106, 4179, 2106, 4176, 2127, 4193, 2137, 4191, 2141, 4201, 2154, 4205, 2170, 4201, 2178, 4211, 2187, 4219, 2192, 4223, 2192, 4233, 2185, 4234, 2181, 4248, 2170, 4260, 2135, 4277, 2123, 4289, 2117, 4288, 2110, 4315, 2100, 4328, 2089, 4315, 2071, 4311, 2064, 4302, 2072, 4 [...]
+        "center":[2101, 4250],
+        "bbox":[2054.0300034531233, 4175.702752221879, 138.29243386326652, 152.27536001915996]
+      },
+      "ZAF":{
+        "shape":[[4602, 4937, 4606, 4950, 4623, 4965, 4630, 4955, 4647, 4953, 4659, 4927, 4640, 4910, 4630, 4914, 4627, 4911, 4602, 4937], [4349, 4909, 4361, 4896, 4374, 4900, 4375, 4914, 4394, 4917, 4407, 4915, 4413, 4918, 4415, 4912, 4434, 4905, 4434, 4809, 4444, 4815, 4455, 4840, 4452, 4864, 4467, 4861, 4474, 4864, 4478, 4856, 4484, 4856, 4486, 4848, 4493, 4847, 4507, 4822, 4518, 4822, 4531, 4833, 4558, 4837, 4565, 4834, 4579, 4808, 4594, 4796, 4607, 4773, 4616, 4769, 4630, 4752, 4638 [...]
+        "center":[4529, 4942],
+        "bbox":[4349.007468046495, 4741.517756633252, 390.49496341272607, 343.88635417976]
+      },
+      "DZA":{
+        "shape":[3909, 3328, 3930, 3317, 3940, 3305, 3965, 3301, 3979, 3286, 4023, 3280, 4032, 3272, 4068, 3269, 4088, 3278, 4111, 3265, 4126, 3270, 4133, 3264, 4158, 3272, 4167, 3272, 4154, 3283, 4159, 3287, 4158, 3335, 4138, 3361, 4159, 3387, 4159, 3396, 4177, 3407, 4188, 3459, 4185, 3463, 4194, 3484, 4197, 3503, 4194, 3513, 4198, 3523, 4194, 3537, 4197, 3552, 4185, 3566, 4197, 3584, 4199, 3600, 4208, 3611, 4234, 3617, 4245, 3636, 4155, 3695, 4134, 3706, 4097, 3737, 4062, 3747, 4042, 3 [...]
+        "center":[4028, 3515],
+        "bbox":[3756.6577469244726, 3264.4990368614026, 488.7426611137812, 488.69679691776537]
+      },
+      "PER":{
+        "shape":[2316, 4630, 2318, 4636, 2316, 4641, 2302, 4646, 2291, 4639, 2291, 4635, 2278, 4630, 2277, 4621, 2262, 4615, 2254, 4606, 2208, 4586, 2189, 4573, 2189, 4569, 2162, 4545, 2161, 4537, 2165, 4527, 2151, 4501, 2142, 4497, 2142, 4486, 2132, 4476, 2122, 4450, 2117, 4448, 2106, 4412, 2088, 4392, 2076, 4368, 2066, 4358, 2058, 4358, 2047, 4351, 2057, 4342, 2047, 4334, 2051, 4327, 2045, 4319, 2046, 4311, 2068, 4292, 2070, 4290, 2075, 4300, 2072, 4304, 2064, 4302, 2071, 4311, 2089, 4 [...]
+        "center":[2177, 4439],
+        "bbox":[2045.3815987036753, 4210.619322571454, 299.4588481495855, 435.7307566332802]
+      },
+      "GRC":{
+        "shape":[[4577, 3327, 4546, 3329, 4546, 3324, 4536, 3320, 4518, 3319, 4519, 3311, 4521, 3306, 4536, 3316, 4568, 3316, 4568, 3322, 4582, 3321, 4577, 3327], [4480, 3231, 4504, 3241, 4515, 3253, 4516, 3256, 4510, 3257, 4498, 3251, 4508, 3284, 4497, 3274, 4494, 3285, 4490, 3283, 4484, 3265, 4480, 3266, 4478, 3277, 4474, 3274, 4470, 3263, 4474, 3254, 4461, 3240, 4467, 3233, 4480, 3231], [4459, 3150, 4478, 3145, 4485, 3138, 4501, 3139, 4503, 3133, 4504, 3133, 4544, 3127, 4563, 3137, 45 [...]
+        "center":[4474, 3190],
+        "bbox":[4434.61879902175, 3123.2327611182213, 158.76586162399963, 205.42883038299942]
+      },
+      "FRA":{
+        "shape":[[3998, 3096, 3986, 3084, 3979, 3084, 3975, 3091, 3954, 3092, 3921, 3070, 3926, 3067, 3932, 3060, 3933, 3031, 3938, 3028, 3934, 3028, 3936, 3000, 3948, 3016, 3946, 3003, 3932, 2994, 3935, 2973, 3924, 2971, 3917, 2961, 3911, 2945, 3915, 2939, 3904, 2941, 3907, 2934, 3885, 2928, 3880, 2922, 3859, 2922, 3852, 2914, 3860, 2909, 3854, 2905, 3865, 2906, 3849, 2901, 3855, 2893, 3887, 2886, 3901, 2897, 3917, 2890, 3930, 2894, 3918, 2853, 3932, 2853, 3934, 2866, 3960, 2870, 3971,  [...]
+        "center":[4035, 2956],
+        "bbox":[3849.414656122487, 2804.723307427289, 337.79565246536185, 328.95802151769567]
+      },
+      "LUX":{
+        "shape":[4117, 2863, 4113, 2862, 4103, 2861, 4102, 2856, 4104, 2852, 4102, 2840, 4110, 2839, 4110, 2842, 4122, 2850, 4119, 2856, 4117, 2863],
+        "center":[4111, 2852],
+        "bbox":[4102.349411663444, 2838.999132272884, 20.108459384994603, 24.43108708016689]
+      },
+      "ZWE":{
+        "shape":[4705, 4749, 4694, 4745, 4676, 4747, 4663, 4742, 4657, 4743, 4654, 4740, 4648, 4730, 4624, 4726, 4619, 4715, 4620, 4702, 4609, 4701, 4605, 4691, 4585, 4678, 4579, 4662, 4555, 4635, 4558, 4631, 4576, 4635, 4600, 4637, 4615, 4621, 4644, 4606, 4645, 4595, 4652, 4587, 4664, 4582, 4679, 4581, 4683, 4592, 4703, 4591, 4743, 4609, 4741, 4614, 4744, 4633, 4741, 4637, 4744, 4647, 4742, 4657, 4734, 4664, 4739, 4666, 4737, 4676, 4745, 4686, 4731, 4708, 4726, 4726, 4705, 4749],
+        "center":[4677, 4667],
+        "bbox":[4555.123493878856, 4580.909255281847, 189.76439457726428, 168.08820275633207]
+      },
+      "GBR":{
+        "shape":[[3817, 2578, 3833, 2560, 3833, 2550, 3825, 2545, 3830, 2544, 3827, 2529, 3840, 2526, 3834, 2520, 3836, 2512, 3846, 2511, 3846, 2494, 3850, 2502, 3855, 2496, 3890, 2493, 3889, 2508, 3869, 2523, 3873, 2533, 3859, 2545, 3885, 2533, 3919, 2538, 3921, 2545, 3901, 2586, 3888, 2593, 3896, 2590, 3902, 2597, 3875, 2606, 3901, 2605, 3927, 2625, 3934, 2666, 3950, 2670, 3961, 2684, 3968, 2706, 3949, 2701, 3961, 2705, 3970, 2717, 3964, 2734, 3972, 2738, 3977, 2731, 3990, 2732, 4003,  [...]
+        "center":[3927, 2726],
+        "bbox":[3773.0573860569907, 2493.192833509076, 229.54998016797617, 350.6622399881262]
+      },
+      "CHE":{
+        "shape":[4186, 2943, 4187, 2946, 4187, 2948, 4189, 2948, 4190, 2947, 4202, 2955, 4208, 2950, 4210, 2951, 4210, 2952, 4210, 2966, 4200, 2966, 4203, 2975, 4182, 2967, 4176, 2990, 4160, 2968, 4150, 2983, 4140, 2986, 4137, 2989, 4130, 2985, 4123, 2970, 4111, 2971, 4112, 2975, 4104, 2979, 4103, 2971, 4126, 2946, 4127, 2933, 4144, 2931, 4146, 2929, 4154, 2930, 4160, 2930, 4167, 2921, 4182, 2927, 4187, 2929, 4188, 2933, 4186, 2941, 4186, 2943],
+        "center":[4158, 2953],
+        "bbox":[4103.187008858886, 2920.6844033805473, 107.138219356013, 69.3359724339025]
+      },
+      "VNM":{
+        "shape":[6421, 3960, 6427, 3955, 6434, 3957, 6448, 3949, 6454, 3952, 6459, 3944, 6453, 3940, 6455, 3930, 6495, 3913, 6492, 3901, 6497, 3891, 6494, 3878, 6489, 3868, 6493, 3860, 6495, 3841, 6486, 3842, 6490, 3826, 6477, 3815, 6472, 3816, 6470, 3801, 6450, 3786, 6447, 3777, 6412, 3744, 6412, 3736, 6419, 3734, 6423, 3739, 6431, 3727, 6426, 3716, 6422, 3716, 6422, 3709, 6414, 3705, 6390, 3705, 6384, 3692, 6387, 3681, 6376, 3680, 6367, 3668, 6375, 3659, 6388, 3668, 6394, 3659, 6409, 3 [...]
+        "center":[6515, 3876],
+        "bbox":[6366.546403339945, 3644.7400575469037, 173.0110744778949, 360.70788833869756]
+      },
+      "BHS":{
+        "shape":[[2126, 3551, 2135, 3550, 2147, 3559, 2144, 3577, 2139, 3574, 2144, 3569, 2145, 3559, 2135, 3551, 2126, 3551], [2226, 3701, 2243, 3692, 2240, 3702, 2226, 3701], [2101, 3556, 2107, 3559, 2111, 3553, 2128, 3557, 2108, 3561, 2101, 3556], [2129, 3627, 2134, 3620, 2136, 3632, 2131, 3632, 2129, 3627], [2153, 3589, 2155, 3585, 2168, 3595, 2169, 3609, 2164, 3603, 2167, 3603, 2167, 3595, 2153, 3589], [2177, 3607, 2189, 3622, 2183, 3622, 2186, 3619, 2177, 3607], [2212, 3671, 2221,  [...]
+        "center":[2172, 3608],
+        "bbox":[2101.1977694855236, 3549.898616670195, 141.87846880852157, 151.88930218514088]
+      },
+      "AGO":{
+        "shape":[[4356, 4353, 4363, 4377, 4379, 4399, 4417, 4397, 4425, 4384, 4425, 4373, 4443, 4374, 4445, 4371, 4451, 4372, 4451, 4381, 4475, 4380, 4480, 4409, 4475, 4433, 4477, 4440, 4484, 4444, 4490, 4463, 4485, 4463, 4486, 4476, 4494, 4470, 4509, 4472, 4520, 4466, 4524, 4468, 4531, 4472, 4531, 4502, 4528, 4511, 4532, 4518, 4482, 4517, 4482, 4593, 4511, 4624, 4518, 4629, 4454, 4641, 4409, 4635, 4393, 4624, 4293, 4625, 4281, 4615, 4273, 4614, 4259, 4621, 4247, 4616, 4240, 4620, 4239,  [...]
+        "center":[4372, 4492],
+        "bbox":[4239.422580412723, 4313.030248259493, 293.05119916947206, 327.7337677130281]
+      },
+      "LVA":{
+        "shape":[4458, 2604, 4457, 2573, 4474, 2540, 4495, 2533, 4510, 2562, 4520, 2566, 4534, 2557, 4536, 2532, 4535, 2529, 4565, 2522, 4586, 2541, 4609, 2543, 4615, 2548, 4613, 2566, 4625, 2579, 4628, 2598, 4628, 2600, 4612, 2618, 4594, 2623, 4590, 2620, 4566, 2599, 4556, 2601, 4547, 2588, 4534, 2596, 4482, 2590, 4458, 2604],
+        "center":[4533, 2570],
+        "bbox":[4457.238607639531, 2521.502872396299, 170.78672713414016, 101.23935066228387]
+      },
+      "SWE":{
+        "shape":[4226, 2470, 4237, 2479, 4243, 2433, 4257, 2431, 4262, 2409, 4251, 2377, 4265, 2374, 4267, 2364, 4250, 2346, 4248, 2250, 4265, 2226, 4291, 2227, 4297, 2218, 4284, 2196, 4304, 2159, 4303, 2109, 4326, 2098, 4324, 2087, 4353, 2051, 4342, 2029, 4355, 2000, 4374, 1989, 4384, 1998, 4396, 1956, 4434, 1973, 4438, 1926, 4449, 1926, 4520, 1998, 4513, 2025, 4527, 2068, 4519, 2092, 4533, 2125, 4522, 2127, 4496, 2122, 4481, 2149, 4464, 2152, 4472, 2166, 4458, 2183, 4469, 2206, 4446, 2 [...]
+        "center":[4340, 2280],
+        "bbox":[4225.741367490328, 1925.6523872116315, 307.32443867286565, 707.402478393428]
+      },
+      "CHL":{
+        "shape":[2175, 5450, 2191, 5433, 2197, 5433, 2199, 5423, 2190, 5428, 2191, 5421, 2203, 5421, 2205, 5427, 2206, 5420, 2215, 5423, 2208, 5431, 2217, 5427, 2209, 5434, 2206, 5431, 2214, 5434, 2210, 5438, 2204, 5434, 2205, 5440, 2199, 5438, 2208, 5446, 2216, 5435, 2220, 5438, 2218, 5431, 2222, 5435, 2216, 5452, 2232, 5427, 2223, 5437, 2224, 5424, 2236, 5414, 2226, 5417, 2229, 5406, 2234, 5404, 2240, 5413, 2244, 5406, 2226, 5399, 2250, 5376, 2250, 5370, 2246, 5376, 2233, 5364, 2244, 5 [...]
+        "center":[2254, 5135],
+        "bbox":[2175.3492443142513, 4622.668169078296, 208.44914515858773, 1091.7113859669753]
+      },
+      "CZE":{
+        "shape":[4367, 2890, 4318, 2878, 4310, 2893, 4304, 2890, 4298, 2896, 4289, 2889, 4288, 2885, 4275, 2878, 4261, 2861, 4259, 2846, 4245, 2833, 4253, 2836, 4291, 2813, 4304, 2812, 4304, 2805, 4316, 2812, 4323, 2807, 4326, 2811, 4351, 2821, 4348, 2827, 4356, 2837, 4364, 2836, 4361, 2826, 4381, 2832, 4380, 2838, 4386, 2842, 4403, 2844, 4409, 2858, 4402, 2858, 4393, 2876, 4367, 2890],
+        "center":[4332, 2849],
+        "bbox":[4244.597453792947, 2804.5598583363526, 164.55827404047886, 91.50883671105294]
+      },
+      "CHN":{
+        "shape":[[6035, 2873, 6036, 2891, 6057, 2914, 6096, 2930, 6112, 2963, 6112, 2983, 6103, 3000, 6108, 3011, 6167, 3018, 6200, 3039, 6215, 3041, 6214, 3049, 6238, 3092, 6259, 3089, 6310, 3098, 6338, 3094, 6366, 3100, 6374, 3108, 6413, 3122, 6429, 3120, 6430, 3126, 6442, 3129, 6497, 3100, 6542, 3100, 6568, 3091, 6586, 3070, 6605, 3058, 6593, 3039, 6606, 3014, 6624, 3023, 6647, 3024, 6670, 3003, 6695, 3001, 6707, 2992, 6714, 2975, 6733, 2971, 6736, 2964, 6744, 2966, 6755, 2958, 6781,  [...]
+        "center":[6359, 3325],
+        "bbox":[5692.621771004884, 2709.7580094026557, 1451.7140692859775, 1063.4615554155494]
+      },
+      "TGO":{
+        "shape":[3987, 4063, 3975, 4045, 3975, 4014, 3980, 4009, 3971, 4002, 3975, 3996, 3974, 3982, 3967, 3983, 3971, 3978, 3972, 3965, 3963, 3956, 3964, 3951, 3965, 3946, 3972, 3949, 3981, 3945, 3981, 3963, 3994, 3973, 3991, 3979, 3999, 3993, 3998, 4051, 4001, 4058, 3987, 4063],
+        "center":[3985, 4000],
+        "bbox":[3962.572721756216, 3945.00553860495, 38.833299605038064, 118.28041367635706]
+      },
+      "CIV":{
+        "shape":[3782, 4105, 3779, 4095, 3785, 4074, 3775, 4067, 3776, 4060, 3763, 4060, 3761, 4055, 3757, 4055, 3762, 4046, 3760, 4033, 3760, 4027, 3768, 4029, 3774, 4015, 3766, 4012, 3769, 4005, 3777, 4008, 3780, 4004, 3775, 3998, 3777, 3994, 3771, 3977, 3773, 3967, 3778, 3966, 3780, 3960, 3785, 3960, 3788, 3966, 3798, 3966, 3803, 3956, 3807, 3957, 3815, 3952, 3817, 3967, 3823, 3960, 3831, 3958, 3829, 3965, 3838, 3966, 3847, 3978, 3847, 3984, 3858, 3983, 3862, 3975, 3871, 3973, 3889, 3 [...]
+        "center":[3826, 4036],
+        "bbox":[3756.8135740370753, 3952.1974838625733, 144.60061337960315, 153.20775226197793]
+      },
+      "ERI":{
+        "shape":[4982, 3907, 4973, 3914, 4969, 3910, 4965, 3913, 4953, 3894, 4938, 3887, 4933, 3877, 4911, 3864, 4890, 3864, 4887, 3860, 4873, 3866, 4860, 3857, 4856, 3857, 4849, 3870, 4827, 3869, 4827, 3862, 4825, 3847, 4839, 3801, 4850, 3799, 4859, 3788, 4866, 3788, 4874, 3776, 4883, 3792, 4891, 3812, 4890, 3821, 4896, 3838, 4903, 3843, 4902, 3849, 4904, 3851, 4907, 3841, 4915, 3854, 4919, 3852, 4937, 3860, 4950, 3879, 4963, 3886, 4966, 3895, 4977, 3905, 4981, 3903, 4982, 3907],
+        "center":[4899, 3854],
+        "bbox":[4825.349249806749, 3775.56252919978, 156.26442360956662, 138.5701861640082]
+      },
+      "NER":{
+        "shape":[4062, 3747, 4097, 3737, 4134, 3706, 4155, 3695, 4245, 3636, 4265, 3641, 4297, 3660, 4317, 3651, 4324, 3674, 4320, 3687, 4340, 3716, 4331, 3745, 4328, 3801, 4287, 3849, 4280, 3862, 4283, 3879, 4273, 3888, 4265, 3889, 4260, 3896, 4219, 3889, 4201, 3891, 4187, 3902, 4166, 3901, 4163, 3895, 4160, 3897, 4153, 3891, 4125, 3899, 4114, 3880, 4107, 3883, 4090, 3877, 4088, 3882, 4069, 3880, 4058, 3888, 4058, 3898, 4051, 3908, 4045, 3910, 4047, 3913, 4047, 3922, 4041, 3922, 4029, 3 [...]
+        "center":[4174, 3796],
+        "bbox":[3966.9379594871325, 3635.6696916080305, 373.0427837394909, 287.9889616912924]
+      },
+      "MAR":{
+        "shape":[3650, 3529, 3655, 3523, 3688, 3512, 3721, 3480, 3733, 3456, 3728, 3448, 3729, 3428, 3742, 3406, 3742, 3397, 3758, 3377, 3798, 3357, 3813, 3333, 3821, 3304, 3835, 3301, 3838, 3314, 3848, 3321, 3872, 3318, 3884, 3322, 3893, 3317, 3892, 3324, 3903, 3323, 3907, 3328, 3917, 3333, 3921, 3349, 3917, 3363, 3927, 3390, 3937, 3396, 3933, 3401, 3927, 3408, 3890, 3409, 3893, 3419, 3873, 3425, 3870, 3433, 3878, 3437, 3859, 3450, 3848, 3451, 3842, 3467, 3821, 3477, 3793, 3479, 3768, 3 [...]
+        "center":[3805, 3410],
+        "bbox":[3649.782631379591, 3300.6687116013327, 287.4708027987549, 228.3376919430102]
+      },
+      "LTU":{
+        "shape":[4516, 2693, 4516, 2681, 4503, 2673, 4499, 2668, 4496, 2643, 4464, 2637, 4463, 2634, 4458, 2610, 4458, 2604, 4482, 2590, 4534, 2596, 4547, 2588, 4556, 2601, 4566, 2599, 4590, 2620, 4594, 2623, 4589, 2626, 4591, 2641, 4573, 2651, 4567, 2684, 4558, 2677, 4539, 2694, 4516, 2693],
+        "center":[4527, 2638],
+        "bbox":[4457.580908569287, 2588.0917568057184, 136.22820099492765, 105.55730724920659]
+      },
+      "NLD":{
+        "shape":[4038, 2795, 4058, 2793, 4064, 2787, 4060, 2775, 4076, 2781, 4060, 2772, 4079, 2723, 4078, 2735, 4085, 2735, 4082, 2754, 4092, 2759, 4102, 2734, 4095, 2736, 4094, 2730, 4092, 2736, 4093, 2720, 4123, 2712, 4132, 2721, 4135, 2721, 4131, 2742, 4122, 2748, 4132, 2753, 4131, 2761, 4121, 2772, 4108, 2776, 4112, 2793, 4102, 2815, 4100, 2814, 4095, 2812, 4099, 2800, 4083, 2790, 4064, 2791, 4060, 2799, 4038, 2795],
+        "center":[4095, 2762],
+        "bbox":[4037.98072617728, 2711.968806562706, 97.1797010685309, 102.92698369836535]
+      },
+      "KHM":{
+        "shape":[6388, 3937, 6389, 3926, 6376, 3881, 6399, 3861, 6434, 3858, 6437, 3861, 6439, 3863, 6442, 3877, 6450, 3875, 6456, 3880, 6461, 3873, 6458, 3865, 6472, 3858, 6476, 3866, 6489, 3868, 6494, 3878, 6497, 3891, 6492, 3901, 6495, 3913, 6455, 3930, 6453, 3940, 6459, 3944, 6454, 3952, 6448, 3949, 6434, 3957, 6427, 3955, 6421, 3960, 6416, 3956, 6402, 3960, 6399, 3957, 6405, 3949, 6402, 3945, 6400, 3944, 6397, 3950, 6390, 3950, 6388, 3937],
+        "center":[6425, 3906],
+        "bbox":[6376.159411791862, 3858.1499196666978, 120.46113313371188, 102.22327396261335]
+      },
+      "CYP":{
+        "shape":[4722, 3324, 4735, 3322, 4736, 3316, 4759, 3316, 4776, 3307, 4761, 3317, 4763, 3326, 4739, 3338, 4726, 3333, 4722, 3324],
+        "center":[4747, 3323],
+        "bbox":[4721.627145563031, 3307.471538985893, 54.50550809086053, 30.03826954401302]
+      },
+      "SOM":{
+        "shape":[4946, 4248, 4932, 4229, 4932, 4143, 4955, 4114, 4961, 4109, 4977, 4107, 4983, 4099, 5004, 4091, 5025, 4094, 5097, 4019, 5077, 4020, 5003, 3995, 4997, 3988, 4988, 3985, 4972, 3958, 4978, 3947, 4986, 3937, 5000, 3955, 5009, 3961, 5025, 3963, 5045, 3951, 5059, 3957, 5067, 3955, 5086, 3943, 5092, 3947, 5111, 3939, 5123, 3942, 5153, 3933, 5162, 3925, 5175, 3929, 5171, 3938, 5172, 3958, 5165, 3967, 5164, 3984, 5153, 4008, 5129, 4042, 5123, 4063, 5098, 4102, 5096, 4100, 5097, 4 [...]
+        "center":[5108, 3991],
+        "bbox":[4931.5329354698615, 3925.1911473180676, 243.48568578622235, 323.06300020278695]
+      },
+      "AFG":{
+        "shape":[5409, 3302, 5417, 3312, 5428, 3313, 5431, 3321, 5436, 3321, 5454, 3313, 5458, 3306, 5454, 3299, 5465, 3301, 5489, 3285, 5495, 3262, 5512, 3258, 5515, 3253, 5534, 3259, 5543, 3259, 5550, 3264, 5561, 3262, 5572, 3271, 5585, 3261, 5600, 3261, 5603, 3249, 5618, 3249, 5619, 3236, 5632, 3221, 5652, 3231, 5649, 3238, 5656, 3239, 5652, 3268, 5660, 3275, 5692, 3252, 5708, 3252, 5710, 3258, 5719, 3257, 5718, 3253, 5722, 3254, 5735, 3258, 5725, 3260, 5723, 3270, 5716, 3271, 5680, 3 [...]
+        "center":[5524, 3353],
+        "bbox":[5390.950855365526, 3220.8767610839536, 343.9031331181759, 263.54784429935944]
+      },
+      "RUS":{
+        "shape":[[4604, 2482, 4628, 2458, 4625, 2450, 4623, 2440, 4632, 2443, 4645, 2431, 4676, 2432, 4635, 2409, 4639, 2392, 4623, 2404, 4618, 2404, 4710, 2282, 4670, 2240, 4683, 2222, 4670, 2208, 4671, 2182, 4661, 2176, 4664, 2137, 4674, 2134, 4650, 2063, 4672, 2018, 4639, 1987, 4640, 1931, 4645, 1927, 4643, 1934, 4669, 1909, 4669, 1895, 4686, 1903, 4694, 1878, 4700, 1883, 4718, 1878, 4711, 1867, 4743, 1881, 4738, 1892, 4718, 1881, 4710, 1897, 4719, 1889, 4719, 1902, 4740, 1898, 4736,  [...]
+        "center":[6262, 2208],
+        "bbox":[4429.936998830198, 1058.3426030083085, 3775.3559947590957, 2080.6751693784563]
+      },
+      "CRI":{
+        "shape":[1937, 3950, 1941, 3948, 1941, 3946, 1974, 3948, 1982, 3955, 1993, 3952, 1993, 3955, 2006, 3976, 2021, 3985, 2021, 3986, 2009, 3982, 2007, 3985, 2007, 3994, 2012, 3998, 2005, 4012, 2009, 4019, 2008, 4019, 2001, 4003, 1998, 4001, 1998, 4007, 1993, 4007, 1989, 4004, 1992, 3997, 1990, 3992, 1965, 3978, 1967, 3972, 1957, 3965, 1954, 3968, 1962, 3974, 1957, 3980, 1943, 3971, 1938, 3964, 1943, 3952, 1937, 3950],
+        "center":[1982, 3974],
+        "bbox":[1936.8124455436955, 3945.9024178540994, 84.26329941826998, 73.53193766967979]
+      },
+      "BRA":{
+        "shape":[[2771, 4206, 2774, 4198, 2776, 4204, 2771, 4206], [2777, 4197, 2783, 4197, 2778, 4203, 2777, 4197], [2705, 5048, 2699, 5034, 2710, 5019, 2699, 5012, 2693, 4998, 2660, 4980, 2656, 4970, 2652, 4968, 2648, 4975, 2643, 4973, 2641, 4964, 2623, 4947, 2618, 4945, 2613, 4951, 2600, 4951, 2613, 4936, 2618, 4937, 2655, 4890, 2695, 4864, 2699, 4844, 2687, 4828, 2679, 4832, 2675, 4825, 2681, 4796, 2683, 4787, 2677, 4781, 2665, 4789, 2657, 4784, 2649, 4744, 2632, 4739, 2621, 4745, 25 [...]
+        "center":[2765, 4454],
+        "bbox":[2220.6922875613714, 4086.7137832306826, 921.9776298466136, 961.5012132402499]
+      },
+      "SVK":{
+        "shape":[4367, 2890, 4393, 2876, 4402, 2858, 4409, 2858, 4410, 2861, 4422, 2858, 4431, 2871, 4473, 2862, 4501, 2876, 4494, 2877, 4487, 2898, 4488, 2901, 4476, 2901, 4470, 2893, 4452, 2895, 4440, 2908, 4428, 2905, 4425, 2912, 4410, 2913, 4407, 2920, 4394, 2923, 4376, 2917, 4369, 2914, 4366, 2911, 4365, 2895, 4367, 2890],
+        "center":[4420, 2888],
+        "bbox":[4365.263295268367, 2857.9271509960286, 135.46833209936904, 65.23640669840597]
+      },
+      "SVN":{
+        "shape":[4342, 2954, 4345, 2954, 4352, 2965, 4350, 2965, 4328, 2976, 4331, 2985, 4322, 2998, 4302, 2991, 4296, 2999, 4290, 2999, 4291, 2994, 4288, 2983, 4279, 2978, 4287, 2969, 4288, 2965, 4310, 2970, 4321, 2962, 4333, 2964, 4340, 2954, 4342, 2954],
+        "center":[4318, 2976],
+        "bbox":[4279.346899903341, 2954.1113303892125, 72.41554279799584, 45.37660112395133]
+      },
+      "BIH":{
+        "shape":[4378, 3084, 4377, 3084, 4379, 3077, 4342, 3041, 4336, 3009, 4377, 3002, 4379, 3007, 4412, 3018, 4416, 3018, 4421, 3022, 4414, 3033, 4424, 3046, 4418, 3050, 4421, 3058, 4400, 3083, 4401, 3093, 4397, 3096, 4386, 3084, 4378, 3084],
+        "center":[4386, 3046],
+        "bbox":[4335.547133704566, 3001.6142517466806, 88.63304840657929, 94.83074893487901]
+      }
+    }
+}
diff --git a/dojox/geo/charting/resources/data/series.json b/dojox/geo/charting/tests/series.json
similarity index 100%
rename from dojox/geo/charting/resources/data/series.json
rename to dojox/geo/charting/tests/series.json
diff --git a/dojox/geo/charting/tests/test_europemaps.html b/dojox/geo/charting/tests/test_europemaps.html
new file mode 100644
index 0000000..cd99ea0
--- /dev/null
+++ b/dojox/geo/charting/tests/test_europemaps.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<meta name="viewport" content="user-scalable=no, width=device-width" />
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		
+		<title>Simple Maps,support pan and zoom navigation</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../../dijit/themes/tundra/tundra.css";
+			@import "../resources/Map.css";
+			.mapContainer {
+				display: none;
+				width: 680px;
+				height: 600px;
+				border: solid 1px;
+			}
+			
+			.mapVerticalContainer {
+				display: none;
+				width: 405px;
+				height: 500px;
+				border: solid 1px;
+			}
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:true, async: true"
+				src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			require(["dojo/ready", "dojo/on", "dojox/geo/charting/Map",
+					"dojo/has!touch?dojox/geo/charting/TouchInteractionSupport:dojox/geo/charting/MouseInteractionSupport",
+					"dojox/geo/charting/KeyboardInteractionSupport"], function(ready, on, Map, Interaction, Keyboard){
+
+				ready(function(){
+					var map = new Map("Europe", "../resources/data/ContinentalEurope.json");
+					var interaction = new Interaction(map,{enablePan:true,enableZoom:true});
+					interaction.connect();
+					var keyboard = new Keyboard(map, {enableZoom: true});
+        			keyboard.connect();
+					on(window, "resize", function(){map.resize(true,true);});
+				});
+			});
+		</script>
+	</head>
+	<body class="tundra">
+	  <p>Keyboard Tips: Use <b>TAB</b> to focus the map, then use <b>up/down/left/right</b> to go around the map, zoom in by <b>SPACE</b> and zoom out by <b>ESC</b>.</p>
+		<div class="mapContainer" style="display:block;" id="Europe"></div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/geo/charting/tests/test_mapWithCharting.html b/dojox/geo/charting/tests/test_mapWithCharting.html
index c8d015a..f462795 100644
--- a/dojox/geo/charting/tests/test_mapWithCharting.html
+++ b/dojox/geo/charting/tests/test_mapWithCharting.html
@@ -1,3 +1,4 @@
+<!DOCTYPE html>
 <html>
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
@@ -21,7 +22,7 @@
 				border: solid 1px;
 			}
 		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:true,isDebug:true,gfxRenderer:'svg,canvas,vml,silverlight'" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:true,isDebug:true,gfxRenderer:'svg,canvas,vml,silverlight'" src="../../../../dojo/dojo.js"></script>
 		<script type="text/javascript">
 				var isTouchDevice = dojo.isIos || (navigator.userAgent.toLowerCase().indexOf("android") > -1)
 				|| (navigator.userAgent.toLowerCase().indexOf("blackberry") > -1);
diff --git a/dojox/geo/charting/tests/test_mapWithLegend.html b/dojox/geo/charting/tests/test_mapWithLegend.html
index 4dd7da5..6bdc880 100644
--- a/dojox/geo/charting/tests/test_mapWithLegend.html
+++ b/dojox/geo/charting/tests/test_mapWithLegend.html
@@ -1,3 +1,4 @@
+<!DOCTYPE html>
 <html>
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
@@ -8,7 +9,7 @@
 			@import "../../../../dijit/themes/tundra/tundra.css";
 			@import "../resources/Map.css";
 		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:true,gfxRenderer:'svg,canvas,vml,silverlight'" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:true,gfxRenderer:'svg,canvas,vml,silverlight'" src="../../../../dojo/dojo.js"></script>
 		<script type="text/javascript">
 				var isTouchDevice = dojo.isIos || (navigator.userAgent.toLowerCase().indexOf("android") > -1)
 				|| (navigator.userAgent.toLowerCase().indexOf("blackberry") > -1);
diff --git a/dojox/geo/charting/tests/test_maps.html b/dojox/geo/charting/tests/test_maps.html
index dcfeb40..fb6d0f2 100644
--- a/dojox/geo/charting/tests/test_maps.html
+++ b/dojox/geo/charting/tests/test_maps.html
@@ -1,3 +1,4 @@
+<!DOCTYPE html>
 <html>
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
@@ -11,9 +12,8 @@
 			@import "../../../../dijit/themes/tundra/tundra.css";
 			@import "../resources/Map.css";
 			.mapContainer {
-				display: none;
-				width: 100%;
-				height: 100%;
+				width: 680px;
+				height: 600px;
 				border: solid 1px;
 			}
 			
@@ -24,7 +24,7 @@
 				border: solid 1px;
 			}
 		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:true,gfxRenderer:'svg,canvas,vml,silverlight'" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:true,gfxRenderer:'svg,canvas,vml,silverlight'" src="../../../../dojo/dojo.js"></script>
 		<script type="text/javascript">
 				var isTouchDevice = dojo.isIos || (navigator.userAgent.toLowerCase().indexOf("android") > -1)
 				|| (navigator.userAgent.toLowerCase().indexOf("blackberry") > -1);
@@ -54,6 +54,6 @@
 	</head>
 	<body class="tundra">
 	  <p>Keyboard Tips: Use <b>TAB</b> to focus the map, then use <b>up/down/left/right</b> to go around the map, zoom in by <b>SPACE</b> and zoom out by <b>ESC</b>.</p>
-		<div class="mapContainer" style="display:block;" id="USStates"></div>
+		<div class="mapContainer" id="USStates"></div>
 	</body>
 </html>
\ No newline at end of file
diff --git a/dojox/geo/charting/tests/test_widget.html b/dojox/geo/charting/tests/test_widget.html
index b9243c7..8fed4b4 100644
--- a/dojox/geo/charting/tests/test_widget.html
+++ b/dojox/geo/charting/tests/test_widget.html
@@ -1,71 +1,66 @@
+<!DOCTYPE html>
 <html>
-<head>
+	<head>
 
-<link rel="stylesheet" type="text/css" href="../../../../dojo/resources/dojo.css" />
-<link rel="stylesheet" type="text/css" href="../../../../dijit/themes/claro/claro.css" />
-<meta name="viewport" content="user-scalable=no, width=device-width" />
-<meta name="apple-mobile-web-app-capable" content="yes" />
+		<link rel="stylesheet" type="text/css" href="../../../../dojo/resources/dojo.css" />
+		<link rel="stylesheet" type="text/css" href="../../../../dijit/themes/claro/claro.css" />
+		<meta name="viewport" content="user-scalable=no, width=device-width" />
+		<meta name="apple-mobile-web-app-capable" content="yes" />
 
-<script type="text/javascript">
-	var djConfig = {
-		parseOnLoad : true,
-		gfxRenderer: 'svg,vml,silverlight'
-	};
-</script>
+		<script type="text/javascript">
+			var djConfig = {
+				parseOnLoad : true,
+				gfxRenderer : 'svg,vml,silverlight'
+			};
+		</script>
 
-<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
-<script type="text/javascript">
-		var isTouchDevice = dojo.isIos || (navigator.userAgent.toLowerCase().indexOf("android") > -1)
-		|| (navigator.userAgent.toLowerCase().indexOf("blackberry") > -1);
-		var notIsTouchDevice = !isTouchDevice;
-</script>
-<script>
-	dojo.require("dojox.geo.charting.widget.Map");
-	dojo.require("dijit.layout.ContentPane");
-	dojo.require("dijit.layout.BorderContainer");
-	dojo.require("dojo.parser");
-	dojo.require("dojo.data.ItemFileWriteStore");
-	dojo.requireIf(isTouchDevice,"dojox.geo.charting.TouchInteractionSupport");
-	dojo.requireIf(!isTouchDevice,"dojox.geo.charting.MouseInteractionSupport");
-	dojo.require("dojox.geo.charting.KeyboardInteractionSupport");
-	
-	dojo.addOnLoad(function(){
-	
-		dijit.byId("centerMap").startup();
-	
-	});
-	
-	
-	onFeatureOver = function(feature){
-		var map = dijit.byId("centerMap").getInnerMap();
-		if(!feature.markerText && feature.value){
-			feature.markerText = map.mapObj.marker.markerData[feature.id] + ": $" + feature.value.toFixed(3) + "M";
-		}
-	};
-	
-	onFeatureClick = function(feature){
-		console.log("Feature click " + feature)
-	};
-</script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			var isTouchDevice = dojo.isIos || (navigator.userAgent.toLowerCase().indexOf("android") > -1) || (navigator.userAgent.toLowerCase().indexOf("blackberry") > -1);
+			var notIsTouchDevice = !isTouchDevice;
+		</script>
+		<script>
+			dojo.require("dojox.geo.charting.widget.Map");
+			dojo.require("dijit.layout.ContentPane");
+			dojo.require("dijit.layout.BorderContainer");
+			dojo.require("dojo.parser");
+			dojo.require("dojo.data.ItemFileWriteStore");
+			dojo.requireIf(isTouchDevice, "dojox.geo.charting.TouchInteractionSupport");
+			dojo.requireIf(!isTouchDevice, "dojox.geo.charting.MouseInteractionSupport");
+			dojo.require("dojox.geo.charting.KeyboardInteractionSupport");
 
+			dojo.addOnLoad(function() {
 
-</head>
-<body class="claro">
-<div dojoType="dojo.data.ItemFileWriteStore" jsId="dataStore" url="datastore/dataStore.json">
-</div>
-<div dojoType="dijit.layout.BorderContainer" design="headline" style="height: 100%; width: 100%; ">
+				dijit.byId("centerMap").startup();
 
-<div dojoType="dijit.layout.ContentPane" region="center">
-<div id="centerMap" dojoType="dojox.geo.charting.widget.Map" shapeData="../resources/data/USStates.json"
-adjustMapCenterOnResize="true" adjustMapScaleOnResize="true" markerData="../resources/markers/USStates.json"
- dataStore="dataStore" dataBindingAttribute="productA" series="../resources/data/series.json" 
- onFeatureOver="onFeatureOver"  onFeatureClick="onFeatureClick" enableMouseSupport="notIsTouchDevice" enableMousePan="true" enableMouseZoom="true"
- showTooltips="true" enableFeatureZoom="true" enableTouchSupport="isTouchDevice" enableKeyboardSupport="true"
-	style="height: 100%; width: 100%;">
-</div>
-</div>
+			});
 
-</div>
-</body>
+			onFeatureOver = function(feature) {
+				var map = dijit.byId("centerMap").getInnerMap();
+				if (!feature.markerText && feature.value) {
+					feature.markerText = map.mapObj.marker.markerData[feature.id] + ": $" + feature.value.toFixed(3) + "M";
+				}
+			};
+
+			onFeatureClick = function(feature) {
+				console.log("Feature click " + feature)
+			};
+		</script>
+
+	</head>
+	<body class="claro">
+		<div dojoType="dojo.data.ItemFileWriteStore" data-dojo-id="dataStore" url="datastore/dataStore.json"></div>
+		<div dojoType="dijit.layout.BorderContainer" design="headline" style="height: 500px; width: 650px; ">
+
+			<div dojoType="dijit.layout.ContentPane" region="center">
+				<div id="centerMap" dojoType="dojox.geo.charting.widget.Map" shapeData="../resources/data/USStates.json"
+				adjustMapCenterOnResize="true" adjustMapScaleOnResize="true" markerData="../resources/markers/USStates.json"
+				dataStore="dataStore" dataBindingAttribute="product A" series="series.json"
+				onFeatureOver="onFeatureOver"  onFeatureClick="onFeatureClick" enableMouseSupport="notIsTouchDevice" enableMousePan="true" enableMouseZoom="true"
+				showTooltips="true" enableFeatureZoom="true" enableTouchSupport="isTouchDevice" enableKeyboardSupport="true"></div>
+			</div>
+
+		</div>
+	</body>
 </html>
 
diff --git a/dojox/geo/charting/widget/Legend.js b/dojox/geo/charting/widget/Legend.js
index 4422caa..bf74fc2 100644
--- a/dojox/geo/charting/widget/Legend.js
+++ b/dojox/geo/charting/widget/Legend.js
@@ -1,92 +1,93 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/html",
+	"dojo/dom",
+	"dojo/dom-construct",
+	"dojo/dom-class",
+	"dojo/_base/window",
+	"dijit/_Widget"
+], function(dojo, lang, arr, declare, html,dom,domConstruct,domClass, win, Widget){
 
-define(["dojo/_base/kernel", "dojo/_base/lang","dojo/_base/array", "dojo/_base/declare","dojo/_base/html","dojo/dom",
-		 "dojo/dom-construct","dojo/dom-class", "dojo/_base/window", "dijit/_Widget"],
-							function(dojo, lang, arr, declare, html,dom,domConstruct,domClass, win, Widget) {
+	return declare("dojox.geo.charting.widget.Legend",Widget, {
+		// summary:
+		//		A legend widget displaying association between colors and Feature value ranges.
+		//
+		// description:
+		//		This widget basically is a table comprising (icon,string) pairs, describing the color scheme
+		//		used for the map and its associated text descriptions.
+		//
 
-return declare("dojox.geo.charting.widget.Legend",Widget, {
-	// summary:
-	//		A legend widget displaying association between colors and Feature value ranges. 
-	//
-	//	description:
-	//		This widget basically is a table comprising (icon,string) pairs, describing the color scheme
-	//		used for the map and its associated text descriptions.	 
-	// 
-	
-	//	example:
-	// |	var legend = new dojox.geo.charting.widget.Legend({
-	// |		map: map
-	// |	});
-	horizontal:true,
-	legendBody:null,
-	swatchSize:18,
-	map:null,
-	postCreate: function(){
-		//	summary:
-		//		inherited Dijit's postCreate function		
-		//	tags:
-		//		protected
-		if(!this.map){return;}
-		this.series = this.map.series;
-		if (!this.domNode.parentNode) {
-			// compatibility with older version : add to map domNode if not already attached to a parentNode.
-			dom.byId(this.map.container).appendChild(this.domNode);
-		}
-		this.refresh();
-	},
-	buildRendering: function(){ 
-		//	summary:
-		//		Construct the UI for this widget, creates the underlying real dojox.geo.charting.Map object.		
-		//	tags:
-		//		protected
-		this.domNode = domConstruct.create("table",   
-					{role: "group", "class": "dojoxLegendNode"});  
-		this.legendBody = domConstruct.create("tbody", null, this.domNode);  
-		this.inherited(arguments);  
- 	},  
+		// example:
+		// |	var legend = new dojox.geo.charting.widget.Legend({
+		// |		map: map
+		// |	});
+		horizontal:true,
+		legendBody:null,
+		swatchSize:18,
+		map:null,
+		postCreate: function(){
+			if(!this.map){return;}
+			this.series = this.map.series;
+			if(!this.domNode.parentNode){
+				// compatibility with older version : add to map domNode if not already attached to a parentNode.
+				dom.byId(this.map.container).appendChild(this.domNode);
+			}
+			this.refresh();
+		},
+		buildRendering: function(){
+			this.domNode = domConstruct.create("table",
+						{role: "group", "class": "dojoxLegendNode"});
+			this.legendBody = domConstruct.create("tbody", null, this.domNode);
+			this.inherited(arguments);
+		},
 
-	refresh:function(){
-		//	summary:
-		//		Refreshes this legend contents when Map series has changed.		
-		// cleanup
-		while(this.legendBody.lastChild){
-			domConstruct.destroy(this.legendBody.lastChild);
-		}
-		
-		if(this.horizontal){
-			domClass.add(this.domNode,"dojoxLegendHorizontal");
-			this._tr = win.doc.createElement("tr");
-			this.legendBody.appendChild(this._tr);
-		}
-		
-		var s = this.series;
-		if(s.length == 0){return;}
-		
-		arr.forEach(s,function(x){
-			this._addLabel(x.color, x.name);
-		},this);
-	},
-	_addLabel:function(color,label){
-		var icon = win.doc.createElement("td");
-		var text = win.doc.createElement("td");
-		var div = win.doc.createElement("div");
-		domClass.add(icon, "dojoxLegendIcon");
-		domClass.add(text, "dojoxLegendText");
-		div.style.width  = this.swatchSize + "px";
-		div.style.height = this.swatchSize + "px";
-		icon.appendChild(div);
-		
-		if(this.horizontal){
-			this._tr.appendChild(icon);
-			this._tr.appendChild(text);
-		}else{
-			var tr = win.doc.createElement("tr");
-			this.legendBody.appendChild(tr);
-			tr.appendChild(icon);
-			tr.appendChild(text);
+		refresh: function(){
+			// summary:
+			//		Refreshes this legend contents when Map series has changed.
+
+			// cleanup
+			while(this.legendBody.lastChild){
+				domConstruct.destroy(this.legendBody.lastChild);
+			}
+
+			if(this.horizontal){
+				domClass.add(this.domNode,"dojoxLegendHorizontal");
+				this._tr = win.doc.createElement("tr");
+				this.legendBody.appendChild(this._tr);
+			}
+
+			var s = this.series;
+			if(s.length == 0){return;}
+
+			arr.forEach(s,function(x){
+				this._addLabel(x.color, x.name);
+			},this);
+		},
+		_addLabel:function(color,label){
+			var icon = win.doc.createElement("td");
+			var text = win.doc.createElement("td");
+			var div = win.doc.createElement("div");
+			domClass.add(icon, "dojoxLegendIcon");
+			domClass.add(text, "dojoxLegendText");
+			div.style.width  = this.swatchSize + "px";
+			div.style.height = this.swatchSize + "px";
+			icon.appendChild(div);
+
+			if(this.horizontal){
+				this._tr.appendChild(icon);
+				this._tr.appendChild(text);
+			}else{
+				var tr = win.doc.createElement("tr");
+				this.legendBody.appendChild(tr);
+				tr.appendChild(icon);
+				tr.appendChild(text);
+			}
+
+			div.style.background = color;
+			text.innerHTML = String(label);
 		}
-		
-		div.style.background = color;
-		text.innerHTML = String(label);
-	}
-});
+	});
 });
diff --git a/dojox/geo/charting/widget/Map.js b/dojox/geo/charting/widget/Map.js
index c32d6cb..f220cac 100644
--- a/dojox/geo/charting/widget/Map.js
+++ b/dojox/geo/charting/widget/Map.js
@@ -1,181 +1,180 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/html",
+	"dojo/dom-geometry",
+	"dijit/_Widget",
+	"../Map"
+], function(dojo, lang, declare, html,domGeom, Widget, Map){
 
-define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare","dojo/_base/html","dojo/dom-geometry",
-		"dijit/_Widget","dojox/geo/charting/Map"],
-							function(dojo, lang, declare, html,domGeom, Widget, Map) {
-
-return declare("dojox.geo.charting.widget.Map", Widget, {
-	// summary:
-	//		A map viewer widget based on the dojox.geo.charting.Map component
-	//
-	//	description:
-	//		The `dojox.geo.charting.widget.Map` widget combines map display together with charting capabilities. 
-	//		It encapsulates  an `dojox.geo.charting.Map` object on which most operations are delegated.
-	//		Parameters can be passed as argument at construction time to specify map data file (json shape format)
-	//		as well as charting data. 
-	// 
-	//	The parameters are :
-	//	
-	// * `shapeData`: The json object containing map data or the name of the file containing map data.
-	// * `dataStore`: the dataStore to fetch the charting data from
-	// * `dataBindingAttribute`: property name of the dataStore items to use as value for charting
-	// * `markerData`: tooltips to display for map features, handled as json style.
-	// * `adjustMapCenterOnResize`: if true, the center of the map remains the same when resizing the widget   
-	// * `adjustMapScaleOnResize`: if true, the map scale is adjusted to leave the visible portion of the map identical as much as possible 
-	//
-	//	example:
-	//
-	// |	var map = new dojox.geo.charting.widget.Map({
-	// |		shapeData : 'map.json',
-	// |		adjustMapCenterOnresize : true,
-	// |		adjustMapScaleOnresize : true,
-	// |	});
-
-	shapeData : "",
-	dataStore : null,
-	dataBindingAttribute : "",
-	dataBindingValueFunction: null,
-	markerData : "",
-	series : "",
-	adjustMapCenterOnResize: null,
-	adjustMapScaleOnResize: null,
-	animateOnResize: null,
-	onFeatureClick: null,
-	onFeatureOver: null,
-	enableMouseSupport: null,
-	enableTouchSupport: null,
-	enableMouseZoom: null,
-	enableMousePan: null,
-	enableKeyboardSupport: false,
-	showTooltips: false,
-	enableFeatureZoom: null,
-	colorAnimationDuration: 0,
-	mouseClickThreshold: 2,
-	_mouseInteractionSupport:null,
-	_touchInteractionSupport:null,
-	_keyboardInteractionSupport:null,
-	constructor : function(/* Object */options, /* HtmlNode */div){
-		//	summary: 
-		//		Constructs a new Map widget
-		this.map = null;
-	},
-
-	startup : function(){
-		this.inherited(arguments);
-		if (this.map) {
-			this.map.fitToMapContents();
-		}
-		
-	},
-
-	postMixInProperties : function(){
-		this.inherited(arguments);
-	},
-
-	create : function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
-		this.inherited(arguments);
-	},
-	
-	getInnerMap: function() {
-		return this.map;
-	},
-	
-
-	buildRendering : function(){
-		//	summary:
-		//		Construct the UI for this widget, creates the underlying real dojox.geo.charting.Map object.		
-		//	tags:
-		//		protected
-		this.inherited(arguments);
-		if (this.shapeData) {
-			this.map = new Map(this.domNode, this.shapeData);
-			if (this.markerData && (this.markerData.length > 0))
-				this.map.setMarkerData(this.markerData);
-			
-			if (this.dataStore) {
-				if (this.dataBindingValueFunction) {
-					this.map.setDataBindingValueFunction(this.dataBindingValueFunction);
-				}
-				this.map.setDataStore(this.dataStore,this.dataBindingAttribute);
-			}
-			
-			if (this.series && (this.series.length > 0)) {
-				this.map.addSeries(this.series);
-			}
-			
-			if (this.onFeatureClick) {
-				this.map.onFeatureClick = this.onFeatureClick;
-			}
-			if (this.onFeatureOver) {
-				this.map.onFeatureOver = this.onFeatureOver;
+	return declare("dojox.geo.charting.widget.Map", Widget, {
+		// summary:
+		//		A map viewer widget based on the dojox.geo.charting.Map component
+		// description:
+		//		The `dojox.geo.charting.widget.Map` widget combines map display together with charting capabilities.
+		//		It encapsulates  an `dojox.geo.charting.Map` object on which most operations are delegated.
+		//		Parameters can be passed as argument at construction time to specify map data file (json shape format)
+		//		as well as charting data.
+		//
+		//		The parameters are:
+		//
+		//		- `shapeData`: The json object containing map data or the name of the file containing map data.
+		//		- `dataStore`: the dataStore to fetch the charting data from
+		//		- `dataBindingAttribute`: property name of the dataStore items to use as value for charting
+		//		- `markerData`: tooltips to display for map features, handled as json style.
+		//		- `adjustMapCenterOnResize`: if true, the center of the map remains the same when resizing the widget
+		//		- `adjustMapScaleOnResize`: if true, the map scale is adjusted to leave the visible portion of the map identical as much as possible
+		//
+		// example:
+		// |	var map = new dojox.geo.charting.widget.Map({
+		// |		shapeData: 'map.json',
+		// |		adjustMapCenterOnresize: true,
+		// |		adjustMapScaleOnresize: true,
+		// |	});
+
+		shapeData: "",
+		dataStore: null,
+		dataBindingAttribute: "",
+		dataBindingValueFunction: null,
+		markerData: "",
+		series: "",
+		adjustMapCenterOnResize: null,
+		adjustMapScaleOnResize: null,
+		animateOnResize: null,
+		onFeatureClick: null,
+		onFeatureOver: null,
+		enableMouseSupport: null,
+		enableTouchSupport: null,
+		enableMouseZoom: null,
+		enableMousePan: null,
+		enableKeyboardSupport: false,
+		showTooltips: false,
+		enableFeatureZoom: null,
+		colorAnimationDuration: 0,
+		mouseClickThreshold: 2,
+		_mouseInteractionSupport:null,
+		_touchInteractionSupport:null,
+		_keyboardInteractionSupport:null,
+		constructor: function(/* Object */options, /* HtmlNode */div){
+			// summary:
+			//		Constructs a new Map widget
+			this.map = null;
+		},
+
+		startup: function(){
+			this.inherited(arguments);
+			if(this.map){
+				this.map.fitToMapContents();
 			}
-			if (this.enableMouseSupport) {
-				
-				if (!dojox.geo.charting.MouseInteractionSupport) {
-					throw Error("Can't find dojox.geo.charting.MouseInteractionSupport. Didn't you forget to dojo" + ".require() it?");
+
+		},
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+		},
+
+		create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
+			this.inherited(arguments);
+		},
+
+		getInnerMap: function(){
+			return this.map;
+		},
+
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(this.shapeData){
+				this.map = new Map(this.domNode, this.shapeData);
+				if(this.markerData && (this.markerData.length > 0)){
+					this.map.setMarkerData(this.markerData);
 				}
-				var options = {};
-				options.enablePan = this.enableMousePan;
-				options.enableZoom = this.enableMouseZoom;
-				options.mouseClickThreshold = this.mouseClickThreshold;
-				this._mouseInteractionSupport = new dojox.geo.charting.MouseInteractionSupport(this.map,options);
-				this._mouseInteractionSupport.connect();
-			}
-			
-			if (this.enableTouchSupport) {
-				if (!dojox.geo.charting.TouchInteractionSupport) {
-					throw Error("Can't find dojox.geo.charting.TouchInteractionSupport. Didn't you forget to dojo" + ".require() it?");
+
+				if(this.dataStore){
+					if(this.dataBindingValueFunction){
+						this.map.setDataBindingValueFunction(this.dataBindingValueFunction);
+					}
+					this.map.setDataStore(this.dataStore,this.dataBindingAttribute);
 				}
-				this._touchInteractionSupport = new dojox.geo.charting.TouchInteractionSupport(this.map,{});
-				this._touchInteractionSupport.connect(); 
-			}
-			if (this.enableKeyboardSupport) {
-				if (!dojox.geo.charting.KeyboardInteractionSupport) {
-					throw Error("Can't find dojox.geo.charting.KeyboardInteractionSupport. Didn't you forget to dojo" + ".require() it?");
+
+				if(this.series && (this.series.length > 0)){
+					this.map.addSeries(this.series);
+				}
+
+				if(this.onFeatureClick){
+					this.map.onFeatureClick = this.onFeatureClick;
+				}
+				if(this.onFeatureOver){
+					this.map.onFeatureOver = this.onFeatureOver;
+				}
+				if(this.enableMouseSupport){
+					if(!dojox.geo.charting.MouseInteractionSupport){
+						throw Error("Can't find dojox.geo.charting.MouseInteractionSupport. Didn't you forget to dojo" + ".require() it?");
+					}
+					var options = {};
+					options.enablePan = this.enableMousePan;
+					options.enableZoom = this.enableMouseZoom;
+					options.mouseClickThreshold = this.mouseClickThreshold;
+					this._mouseInteractionSupport = new dojox.geo.charting.MouseInteractionSupport(this.map,options);
+					this._mouseInteractionSupport.connect();
+				}
+
+				if(this.enableTouchSupport){
+					if(!dojox.geo.charting.TouchInteractionSupport){
+						throw Error("Can't find dojox.geo.charting.TouchInteractionSupport. Didn't you forget to dojo" + ".require() it?");
+					}
+					this._touchInteractionSupport = new dojox.geo.charting.TouchInteractionSupport(this.map,{});
+					this._touchInteractionSupport.connect();
+				}
+				if(this.enableKeyboardSupport){
+					if(!dojox.geo.charting.KeyboardInteractionSupport){
+						throw Error("Can't find dojox.geo.charting.KeyboardInteractionSupport. Didn't you forget to dojo" + ".require() it?");
+					}
+					this._keyboardInteractionSupport = new dojox.geo.charting.KeyboardInteractionSupport(this.map,{});
+					this._keyboardInteractionSupport.connect();
 				}
-				this._keyboardInteractionSupport = new dojox.geo.charting.KeyboardInteractionSupport(this.map,{});
-				this._keyboardInteractionSupport.connect(); 
+				this.map.showTooltips = this.showTooltips;
+				this.map.enableFeatureZoom = this.enableFeatureZoom;
+				this.map.colorAnimationDuration = this.colorAnimationDuration;
+			}
+		},
+
+		resize : function(/*Object|Number?*/ b, /*Number?*/ height){
+			// summary:
+			//		Resize the widget.
+			// description:
+			//		Resize the domNode and the widget to the dimensions of a box of the following form:
+			//		`{ l: 50, t: 200, w: 300: h: 150 }`
+			// b: Object|Number?
+			//		An hash with optional "l", "t", "w", and "h" properties for "left", "right", "width", and "height"
+			//		respectively; or a number representing the new width.
+			// height: Number?
+			//		A number representing the new height.
+
+			var box;
+			switch(arguments.length){
+				case 0:
+					// case 0, do not resize the div, just the surface
+					break;
+				case 1:
+					// argument, override node box
+					box = lang.mixin({}, b);
+					domGeom.setMarginBox(this.domNode, box);
+					break;
+				case 2:
+					// two argument, width, height
+					box = {
+						w: arguments[0],
+						h: arguments[1]
+					};
+					domGeom.setMarginBox(this.domNode, box);
+					break;
+			}
+
+			if(this.map){
+				this.map.resize(this.adjustMapCenterOnResize,this.adjustMapScaleOnResize,this.animateOnResize);
 			}
-			this.map.showTooltips = this.showTooltips;
-			this.map.enableFeatureZoom = this.enableFeatureZoom;
-			this.map.colorAnimationDuration = this.colorAnimationDuration;
-			
-			
-		}
-	},
-	
-
-	resize : function(b){
-		//	summary:
-		//		Resize the widget.
-		//	description:
-		//		Resize the domNode and the widget to the dimensions of a box of the following form:
-		//			`{ l: 50, t: 200, w: 300: h: 150 }`
-		//	box:
-		//		If passed, denotes the new size of the widget.
-
-		var box;
-		switch (arguments.length) {
-			case 0:
-				// case 0, do not resize the div, just the surface
-				break;
-			case 1:
-				// argument, override node box
-				box = lang.mixin({}, b);
-				domGeom.getMarginBox(this.domNode, box);
-				break;
-			case 2:
-				// two argument, width, height
-				box = {
-					w : arguments[0],
-					h : arguments[1]
-				};
-				domGeom.getMarginBox(this.domNode, box);
-				break;
-		}
-		
-		if (this.map) {
-			this.map.resize(this.adjustMapCenterOnResize,this.adjustMapScaleOnResize,this.animateOnResize);
 		}
-	}
-});
+	});
 });
diff --git a/dojox/geo/openlayers/Collection.js b/dojox/geo/openlayers/Collection.js
index b5636e6..672d026 100644
--- a/dojox/geo/openlayers/Collection.js
+++ b/dojox/geo/openlayers/Collection.js
@@ -1,27 +1,30 @@
-define([ "dojo/_base/kernel", "dojo/_base/declare", "dojox/geo/openlayers/Geometry" ],
-		function(dojo, declare, Geometry) {
-			/*===== 
-			var Geometry = dojox.geo.openlayers.Geometry; 
-			=====*/
-			return declare("dojox.geo.openlayers.Collection", Geometry, {
-				// summary:
-				// A collection of geometries. _coordinates_ holds an array of
-				// geometries.
+define([
+	"dojo/_base/declare",
+	"./Geometry"
+], function(declare, Geometry){
 
-				setGeometries : function(/* Array */g) {
-					// summary:
-					// Sets the geometries
-					// g: Array
-					// The array of geometries.
-					this.coordinates = g;
-				},
+	return declare("dojox.geo.openlayers.Collection", Geometry, {
+		// summary:
+		//		A collection of geometries. 
 
-				// summary:
-				// Retrieves the geometries.
-				// returns: Array
-				// The array of geometries defining this collection.
-				getGeometries : function() {
-					return this.coordinates;
-				}
-			});
-		});
+		// coordinates: Array
+		//		An array of geometries.
+		coordinates:null,
+
+		setGeometries: function(g){
+			// summary:
+			//		Sets the geometries
+			// g: Array
+			//		The array of geometries.
+			this.coordinates = g;
+		},
+
+		getGeometries: function(){
+			// summary:
+			//		Returns the geometries.
+			// returns:
+			//		The array of geometries defining this collection.
+			return this.coordinates; // Array
+		}
+	});
+});
diff --git a/dojox/geo/openlayers/Feature.js b/dojox/geo/openlayers/Feature.js
index 5d0442e..26ea770 100644
--- a/dojox/geo/openlayers/Feature.js
+++ b/dojox/geo/openlayers/Feature.js
@@ -1,69 +1,73 @@
-define(["dojo/_base/kernel", "dojo/_base/declare", "dojox/geo/openlayers/Map"], function(dojo, declare, Map){
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"./_base"
+], function(dojo, declare, openlayers){
 
 	return declare("dojox.geo.openlayers.Feature", null, {
-		//	summary:
+		// summary:
 		//		A Feature encapsulates an item so that it can be added to a Layer.
 		//		This class is not attended to be used as it, but serve as a base class
 		//		for specific features such as GeometryFeature which can display georeferenced 
 		//		geometries and WidgetFeature which can display georeferenced widgets. 
-		constructor : function(){
-			//	summary:
+		constructor: function(){
+			// summary:
 			//		Construct a new Feature
 			this._layer = null;
-			this._coordSys = dojox.geo.openlayers.EPSG4326;
+			this._coordSys = openlayers.EPSG4326;
 		},
 
-		getCoordinateSystem : function(){
-			//	summary:
+		getCoordinateSystem: function(){
+			// summary:
 			//		Returns the coordinate system in which coordinates of this feature are expressed.
-			//	returns: OpenLayers.Projection
+			// returns:
 			//		The coordinate system in which coordinates of this feature are expressed.
-			return this._coordSys;
+			return this._coordSys; // OpenLayers.Projection
 		},
 
-		setCoordinateSystem : function(/* OpenLayers.Projection */cs){
-			//	summary:
+		setCoordinateSystem: function(/* OpenLayers.Projection */cs){
+			// summary:
 			//		Set the coordinate system in which coordinates of this feature are expressed.
-			//	cs: OpenLayers.Projection
+			// cs: OpenLayers.Projection
 			//		The coordinate system in which coordinates of this feature are expressed.
 			this._coordSys = cs;
 		},
 
-		getLayer : function(){
-			//	summary:
+		getLayer: function(){
+			// summary:
 			//		Returns the Layer to which this feature belongs.
-			//	returns: dojox.geo.openlayers.Layer
+			// returns:
 			//		The layer to which this feature belongs.
-			return this._layer;
+			return this._layer; // dojox/geo/openlayers/Layer
 		},
 
-		_setLayer : function(/* dojox.geo.openlayers.Layer */l){
-			//	summary:
+		_setLayer: function(/* dojox/geo/openlayers/Layer */l){
+			// summary:
 			//		Sets the layer to which this Feature belongs
-			//	description:
+			// description:
 			//		Called when the feature is added to the Layer.
-			//	tags:
+			// tags:
 			//		private
 			this._layer = l;
 		},
 
-		render : function(){
-		//	summary:
+		render: function(){
+		// summary:
 		//		subclasses implements drawing specific behavior.
 		},
 
-		remove : function(){
-		//	summary:
+		remove: function(){
+		// summary:
 		//		Subclasses implements specific behavior.
 		//		Called when removed from the layer.
 		},
 
-		_getLocalXY : function(p){
-			//	summary:
+		_getLocalXY: function(p){
+			// summary:
 			//		From projected coordinates to screen coordinates
-			//	p: Object 
+			// p: Object
 			//		Object with x and y fields
-			//	tags:
+			// tags:
 			//		private
 			var x = p.x;
 			var y = p.y;
diff --git a/dojox/geo/openlayers/Geometry.js b/dojox/geo/openlayers/Geometry.js
index ce91409..e8dee76 100644
--- a/dojox/geo/openlayers/Geometry.js
+++ b/dojox/geo/openlayers/Geometry.js
@@ -1,35 +1,33 @@
-define(["dojo/_base/kernel", "dojo/_base/declare"], function(dojo, declare){
+define([
+	"dojo/_base/declare"
+], function(declare){
 
 	return declare("dojox.geo.openlayers.Geometry", null, {
-		//	summary:
+		// summary:
 		//		A Geometry handles description of shapes to be rendered in a GfxLayer
 		//		using a GeometryFeature feature.
-		//		A Geometry can be 
-		//	- A point geometry of type dojox.geo.openlayers.Point. Coordinates are a an 
-		//	Object {x, y}
-		//	- A line string geometry of type dojox.geo.openlayers.LineString. Coordinates are
-		//	an array of {x, y} objects
-		//	- A collection geometry of type dojox.geo.openlayers.Collection. Coordinates are an array of geometries.
+		//		A Geometry can be:
+		//
+		//		- A point geometry of type dojox.geo.openlayers.Point. Coordinates are a an 
+		//		Object {x, y}
+		//		- A line string geometry of type dojox.geo.openlayers.LineString. Coordinates are
+		//		an array of {x, y} objects
+		//		- A collection geometry of type dojox.geo.openlayers.Collection. Coordinates are an array of geometries.
 
-		//	summary:
-		//		The coordinates of the geometry.
-		//		coordinates: {x, y} | Array 
+		// coordinates: Object|Array
+		//		The coordinates of the geometry, Object like {x, y} or Array.
 		coordinates : null,
 
-		//	summary:
+		// shape: [private] dojox/gfx/shape.Shape
 		//		The associated shape when rendered
-		//	shape : dojox.gfx.Shape
-		// 		The shape
-		//	tags:
-		//		internal
-		shape : null,
+		shape: null,
 
-		constructor : function(coords){
-			//	summary:
+		constructor: function(coords){
+			// summary:
 			//		Constructs a new geometry
-			//	coords: {x, y}
-			//		Coordinates of the geometry. {x:<x>, y:<y>} object for a point geometry, array of {x:<x>, y:<y>} 
-			//	objects for line string geometry, array of geometries for collection geometry.
+			// coords: Object
+			//		Coordinates of the geometry. {x:``x``, y:``y``} object for a point geometry, array of {x:``x``, y:``y``}
+			//		objects for line string geometry, array of geometries for collection geometry.
 			this.coordinates = coords;
 		}
 	});
diff --git a/dojox/geo/openlayers/GeometryFeature.js b/dojox/geo/openlayers/GeometryFeature.js
index f0194a6..c282214 100644
--- a/dojox/geo/openlayers/GeometryFeature.js
+++ b/dojox/geo/openlayers/GeometryFeature.js
@@ -1,33 +1,31 @@
-define(["dojo/_base/kernel",
-				"dojo/_base/declare",
-				"dojo/_base/array",
-				"dojo/_base/lang",
-				"dojox/gfx/matrix",
-				"dojox/geo/openlayers/Point",
-				"dojox/geo/openlayers/LineString",
-				"dojox/geo/openlayers/Collection",
-				"dojox/geo/openlayers/Feature"], function(dojo, declare, array, lang, matrix, Point, LineString,
-																									Collection, Feature){
-	/*===== 
-	var Feature = dojox.geo.openlayers.Feature; 
-	=====*/
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojox/gfx/matrix",
+	"./Point",
+	"./LineString",
+	"./Collection",
+	"./Feature"
+], function(declare, array, lang, matrix, Point, LineString, Collection, Feature){
+
 	return declare("dojox.geo.openlayers.GeometryFeature", Feature, {
-		//	summary:
+		// summary:
 		//		A Feature encapsulating a geometry.
-		//	description:
+		// description:
 		//		This Feature renders a geometry such as a Point or LineString geometry. This Feature
 		//		is responsible for reprojecting the geometry before creating a gfx shape to display it.
 		//		By default the shape created is a circle for a Point geometry and a polyline for a 
 		//		LineString geometry. User can change these behavior by overriding the createShape 
 		//		method to create the desired shape.
-		//	example:
+		// example:
 		//	|  var geom = new dojox.geo.openlayers.Point({x:0, y:0});
 		//	|  var gf = new dojox.geo.openlayers.GeometryFeature(geom);
 
-		constructor : function(/* dojox.geo.openlayers.Geometry */geometry){
-			//	summary:
+		constructor: function(geometry){
+			// summary:
 			//		Constructs a GeometryFeature for the specified geometry.
-			//	geometry: OpenLayer.Geometry
+			// geometry: dojox/geo/openlayers/Geometry
 			//		The geometry to render.
 			this._geometry = geometry;
 			this._shapeProperties = {};
@@ -35,10 +33,10 @@ define(["dojo/_base/kernel",
 			this._stroke = null;
 		},
 
-		_createCollection : function(/* dojox.geo.openlayers.Geometry */g){
-			//	summary:
+		_createCollection: function(/* dojox/geo/openlayers/Geometry */g){
+			// summary:
 			//		Create collection shape and add it to the viewport.
-			//	tags:
+			// tags:
 			//		private
 			var layer = this.getLayer();
 			var s = layer.getSurface();
@@ -48,130 +46,138 @@ define(["dojo/_base/kernel",
 			return c;
 		},
 
-		_getCollectionShape : function(/* dojox.geo.openlayers.Geometry */g){
-			//	summary:
+		_getCollectionShape: function(/* dojox/geo/openlayers/Geometry */g){
+			// summary:
 			//		Get the collection shape, create it if necessary
-			//	tags:
+			// tags:
 			//		private
 			var s = g.shape;
-			if (s == null) {
+			if(s == null){
 				s = this._createCollection(g);
 				g.shape = s;
 			}
 			return s;
 		},
 
-		renderCollection : function(/* undefined | dojox.geo.openlayers.Geometry */g){
-			//	summary:
+		renderCollection: function(g){
+			// summary:
 			//		Renders a geometry collection.
-			//	g: undefined | dojox.geo.openlayers.Geometry
+			// g: dojox.geo.openlayers.Geometry?
 			//		The geometry to render.
-			if (g == undefined)
+			if(g == undefined){
 				g = this._geometry;
+			}
 
 			s = this._getCollectionShape(g);
 			var prop = this.getShapeProperties();
 			s.setShape(prop);
 
 			array.forEach(g.coordinates, function(item){
-				if (item instanceof Point)
+				if(item instanceof Point){
 					this.renderPoint(item);
-				else if (item instanceof LineString)
+				}else if(item instanceof LineString){
 					this.renderLineString(item);
-				else if (item instanceof Collection)
+				}else if(item instanceof Collection){
 					this.renderCollection(item);
-				else
+				}else{
 					throw new Error();
+				}
 			}, this);
 			this._applyStyle(g);
 		},
 
-		render : function(/* undefined || dojox.geo.openlayer.Geometry */g){
-			//	summary:
+		render: function(g){
+			// summary:
 			//		Render a geometry. 
 			//		Called by the Layer on which the feature is added. 
-			//	g: undefined || dojox.geo.openlayer.Geometry
+			// g: dojox/geo/openlayer/Geometry?
 			//		The geometry to draw
-			if (g == undefined)
+			if(g == undefined){
 				g = this._geometry;
+			}
 
-			if (g instanceof Point)
+			if(g instanceof Point){
 				this.renderPoint(g);
-			else if (g instanceof LineString)
+			}else if(g instanceof LineString){
 				this.renderLineString(g);
-			else if (g instanceof Collection)
+			}else if(g instanceof Collection){
 				this.renderCollection(g);
-			else
+			}else{
 				throw new Error();
+			}
 		},
 
-		getShapeProperties : function(){
-			//	summary:
+		getShapeProperties: function(){
+			// summary:
 			//		Returns the shape properties. 
-			//	returns: Object
+			// returns: Object
 			//		The shape properties.
 			return this._shapeProperties;
 		},
 
-		setShapeProperties : function(/* Object */s){
-			//	summary:
+		setShapeProperties: function(s){
+			// summary:
 			//		Sets the shape properties. 
-			//	s: Object
+			// s: Object
 			//		The shape properties to set.
 			this._shapeProperties = s;
 			return this;
 		},
 
-		createShape : function(/* Surface */s, /* dojox.geo.openlayers.Geometry */g){
-			//	summary:
+		createShape: function(s, g){
+			// summary:
 			//		Called when the shape rendering the geometry has to be created.
 			//		This default implementation creates a circle for a point geometry, a polyline for
 			//		a LineString geometry and is recursively called when creating a collection.
 			//		User may replace this method to produce a custom shape.
-			//	s: dojox.gfx.Surface
+			// s: dojox/gfx/Surface
 			//		The surface on which the method create the shapes.
-			//	g: dojox.geo.openlayers.Geometry
+			// g: dojox/geo/openlayers/Geometry?
 			//		The reference geometry 
-			//	returns: dojox.gfx.Shape
+			// returns:
 			//		The resulting shape.
-			if (!g)
+			if(!g){
 				g = this._geometry;
+			}
 
 			var shape = null;
-			if (g instanceof Point) {
+			if(g instanceof Point){
 				shape = s.createCircle();
-			} else if (g instanceof LineString) {
+			}else if(g instanceof LineString){
 				shape = s.createPolyline();
-			} else if (g instanceof Collection) {
+			}else if(g instanceof Collection){
 				var grp = s.createGroup();
 				array.forEach(g.coordinates, function(item){
 					var shp = this.createShape(s, item);
 					grp.add(shp);
 				}, this);
 				shape = grp;
-			} else
+			}else{
 				throw new Error();
+			}
 			return shape;
 		},
 
-		getShape : function(){
-			//	summary:
-			//		Retrieves the shape rendering the geometry
-			//	returns: Shape
+		getShape: function(){
+			// summary:
+			//		Returns the shape rendering the geometry
+			// returns:
 			//		The shape used to render the geometry.
 			var g = this._geometry;
-			if (!g)
+			if(!g){
 				return null;
-			if (g.shape)
+			}
+			if(g.shape){
 				return g.shape;
+			}
 			this.render();
-			return g.shape;
+			return g.shape; // dojox.gfx.shape.Shape
 		},
 
-		_createPoint : function(/* dojox.geo.openlayer.Geometry */g){
-			//	summary:
+		_createPoint: function(/* dojox/geo/openlayer/Geometry */g){
+			// summary:
 			//		Create a point shape
-			//	tags:
+			// tags:
 			//		private
 			var layer = this.getLayer();
 			var s = layer.getSurface();
@@ -181,26 +187,27 @@ define(["dojo/_base/kernel",
 			return c;
 		},
 
-		_getPointShape : function(/* dojox.geo.openlayers.Geometry */g){
-			//	summary:
+		_getPointShape: function(/* dojox/geo/openlayers/Geometry */g){
+			// summary:
 			//		get the point geometry shape, create it if necessary
-			//	tags:
+			// tags:
 			//		private
 			var s = g.shape;
-			if (s == null) {
+			if(s == null){
 				s = this._createPoint(g);
 				g.shape = s;
 			}
 			return s;
 		},
 
-		renderPoint : function(/* undefined | dojox.geo.openlayers.Point */g){
-			//	summary:
+		renderPoint: function(g){
+			// summary:
 			//		Renders a point geometry.
-			//	g: undefined | dojox.geo.openlayers.Point
-			//		The geometry to render.
-			if (g == undefined)
+			// g: dojox/geo/openlayers/Point?
+			//		The geometry to render, or the current instance geometry if not specified.
+			if(g == undefined){
 				g = this._geometry;
+			}
 			var layer = this.getLayer();
 			var map = layer.getDojoMap();
 
@@ -216,16 +223,16 @@ define(["dojo/_base/kernel",
 			var cx = a[0];
 			var cy = a[1];
 			var tr = layer.getViewport().getTransform();
-			if (tr)
+			if(tr){
 				s.setTransform(matrix.translate(cx - tr.dx, cy - tr.dy));
-
+			}
 			this._applyStyle(g);
 		},
 
-		_createLineString : function(/* dojox.geo.openlayers.Geometry */g){
-			//	summary:
+		_createLineString: function(/* dojox/geo/openlayers/Geometry */g){
+			// summary:
 			//		Create polyline shape and add it to the viewport.
-			//	tags:
+			// tags:
 			//		private
 			var layer = this.getLayer();
 			var s = layer._surface;
@@ -236,26 +243,27 @@ define(["dojo/_base/kernel",
 			return shape;
 		},
 
-		_getLineStringShape : function(/* dojox.geo.openlayers.Geometry */g){
-			//	summary:
+		_getLineStringShape: function(/* dojox/geo/openlayers/Geometry */g){
+			// summary:
 			//		Get the line string geometry shape, create it if necessary
-			//	tags:
+			// tags:
 			//		private
 			var s = g.shape;
-			if (s == null) {
+			if(s == null){
 				s = this._createLineString(g);
 				g.shape = s;
 			}
 			return s;
 		},
 
-		renderLineString : function(/* undefined | dojox.geo.openlayers.geometry */g){
-			//	summary:
+		renderLineString: function(g){
+			// summary:
 			//		Renders a line string geometry.
-			//	g: undefined | dojox.geo.openlayers.Geometry
+			// g: dojox/geo/openlayers/Geometry?
 			//		The geometry to render.
-			if (g == undefined)
+			if(g == undefined){
 				g = this._geometry;
+			}
 			var layer = this.getLayer();
 			var map = layer.getDojoMap();
 			var lss = this._getLineStringShape(g);
@@ -265,49 +273,50 @@ define(["dojo/_base/kernel",
 			array.forEach(g.coordinates, function(c, i, array){
 				var p = map.transform(c, from);
 				var a = this._getLocalXY(p);
-				if (tr) {
+				if(tr){
 					a[0] -= tr.dx;
 					a[1] -= tr.dy;
 				}
 				points[i] = {
-					x : a[0],
-					y : a[1]
+					x: a[0],
+					y: a[1]
 				};
 			}, this);
 			var prop = lang.mixin({}, this._defaults.lineStringShape);
 			prop = lang.mixin(prop, this.getShapeProperties());
 			prop = lang.mixin(prop, {
-				points : points
+				points: points
 			});
 			lss.setShape(prop);
 			this._applyStyle(g);
 		},
 
-		_applyStyle : function(/* Geometry */g){
-			//	summary:
+		_applyStyle: function(g){
+			// summary:
 			//		Apply the style on the geometry's shape.
-			//	g: dojox.geo.openlayers.Geometry
+			// g: Geometry
 			//		The geometry.
-			//	tags:
+			// tags:
 			//		private
-			if (!g || !g.shape)
+			if(!g || !g.shape){
 				return;
+			}
 
 			var f = this.getFill();
 
 			var fill;
-			if (!f || lang.isString(f) || lang.isArray(f))
+			if(!f || lang.isString(f) || lang.isArray(f)){
 				fill = f;
-			else {
+			}else{
 				fill = lang.mixin({}, this._defaults.fill);
 				fill = lang.mixin(fill, f);
 			}
 
 			var s = this.getStroke();
 			var stroke;
-			if (!s || lang.isString(s) || lang.isArray(s))
+			if(!s || lang.isString(s) || lang.isArray(s)){
 				stroke = s;
-			else {
+			}else{
 				stroke = lang.mixin({}, this._defaults.stroke);
 				stroke = lang.mixin(stroke, s);
 			}
@@ -315,89 +324,92 @@ define(["dojo/_base/kernel",
 			this._applyRecusiveStyle(g, stroke, fill);
 		},
 
-		_applyRecusiveStyle : function(g, stroke, fill){
-			//	summary:
+		_applyRecusiveStyle: function(g, stroke, fill){
+			// summary:
 			//		Apply the style on the geometry's shape recursively.
-			//	g: dojox.geo.openlayers.Geometry
+			// g: dojox.geo.openlayers.Geometry
 			//		The geometry.
-			//	stroke: Object
+			// stroke: Object
 			//		The stroke
-			//	fill:Object
+			// fill:Object
 			//		The fill
-			//	tags:
+			// tags:
 			//		private
 			var shp = g.shape;
 
-			if (shp.setFill)
+			if(shp.setFill){
 				shp.setFill(fill);
+			}
 
-			if (shp.setStroke)
+			if(shp.setStroke){
 				shp.setStroke(stroke);
+			}
 
-			if (g instanceof Collection) {
+			if(g instanceof Collection){
 				array.forEach(g.coordinates, function(i){
 					this._applyRecusiveStyle(i, stroke, fill);
 				}, this);
 			}
 		},
 
-		setStroke : function(/* Object */s){
-			//	summary:
+		setStroke: function(s){
+			// summary:
 			//		Set the stroke style to be applied on the rendered shape.
-			//	s: Object
+			// s: Object
 			//		The stroke style
 			this._stroke = s;
 			return this;
 		},
 
-		getStroke : function(){
-			//	summary:
-			//		Retrieves the stroke style
-			//	returns: Object
+		getStroke: function(){
+			// summary:
+			//		Returns the stroke style
+			// returns:
 			//		The stroke style
 			return this._stroke;
 		},
 
-		setFill : function(/* Object */f){
-			//	summary:
+		setFill: function(f){
+			// summary:
 			//		Set the fill style to be applied on the rendered shape.
-			//	f: Object
+			// f: Object
 			//		The fill style
 			this._fill = f;
 			return this;
 		},
 
-		getFill : function(){
-			//	summary:
-			//		Retrieves the fill style
-			//	returns: Object
+		getFill: function(){
+			// summary:
+			//		Returns the fill style
+			// returns:
 			//		The fill style
 			return this._fill;
 		},
 
-		remove : function(){
-			//	summary:
+		remove: function(){
+			// summary:
 			//		Removes the shape from the Surface. 
 			//		Called when the feature is removed from the layer.
 			var g = this._geometry;
 			var shp = g.shape;
 			g.shape = null;
-			if (shp)
+			if(shp){
 				shp.removeShape();
-			if (g instanceof Collection) {
+			}
+			if(g instanceof Collection){
 				array.forEach(g.coordinates, function(i){
 					this.remove(i);
 				}, this);
 			}
 		},
 
-		_defaults : {
-			fill : null,
-			stroke : null,
-			pointShape : {
-				r : 30
+		_defaults: {
+			fill: null,
+			stroke: null,
+			pointShape: {
+				r: 30
 			},
-			lineStringShape : null
+			lineStringShape: null
 		}
 
 	});
diff --git a/dojox/geo/openlayers/GfxLayer.js b/dojox/geo/openlayers/GfxLayer.js
index 6cb503e..f14222a 100644
--- a/dojox/geo/openlayers/GfxLayer.js
+++ b/dojox/geo/openlayers/GfxLayer.js
@@ -1,126 +1,124 @@
-define(["dojo/_base/kernel",
-				"dojo/_base/declare",
-				"dojo/_base/connect",
-				"dojo/_base/html",
-				"dojox/gfx",
-				"dojox/gfx/_base",
-				"dojox/gfx/shape",
-				"dojox/gfx/path",
-				"dojox/gfx/matrix",
-				"dojox/geo/openlayers/Feature",
-				"dojox/geo/openlayers/Layer"], function(dojo, declare, connect, html, gfx, gbase, shape,
-																								path, matrix, Feature, Layer){
-	/*===== 
-	var Layer = dojox.geo.openlayers.Layer; 
-	=====*/
+define([
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dojo/dom-style",
+	"dojox/gfx",
+	"dojox/gfx/matrix",
+	"./Feature",
+	"./Layer"
+], function(declare, connect, style, gfx, matrix, Feature, Layer){
+
 	return declare("dojox.geo.openlayers.GfxLayer", Layer, {
-		//	summary: 
+		// summary:
 		//		A layer dedicated to render dojox.geo.openlayers.GeometryFeature
-		//	description:
+		// description:
 		//		A layer class for rendering geometries as dojox.gfx.Shape objects.
 		//		This layer class accepts Features which encapsulates graphic objects to be added to the map.
-		//	All objects should be added to this group.
-		//	tags:
+		//		All objects should be added to this group.
+		// tags:
 		//		private
-		_viewport : null,
+		_viewport: null,
 
-		constructor : function(name, options){
-			//	summary:
+		constructor: function(name, options){
+			// summary:
 			//		Constructs a new GFX layer.
-			var s = dojox.gfx.createSurface(this.olLayer.div, 100, 100);
+			var s = gfx.createSurface(this.olLayer.div, 100, 100);
 			this._surface = s;
 			var vp;
-			if (options && options.viewport)
+			if(options && options.viewport){
 				vp = options.viewport;
-			else
+			}else{
 				vp = s.createGroup();
+			}
 			this.setViewport(vp);
-			dojo.connect(this.olLayer, "onMapResize", this, "onMapResize");
+			connect.connect(this.olLayer, "onMapResize", this, "onMapResize");
 			this.olLayer.getDataExtent = this.getDataExtent;
 		},
 
-		getViewport : function(){
-			//	summary:
+		getViewport: function(){
+			// summary:
 			//		Gets the viewport
-			//	tags:
+			// tags:
 			//		internal
 			return this._viewport;
 		},
 
-		setViewport : function(g){
-			//	summary:
+		setViewport: function(g){
+			// summary:
 			//		Sets the viewport
-			//	g: dojox.gfx.Group
-			//	tags:
+			// g: dojox.gfx.Group
+			// tags:
 			//		internal
-			if (this._viewport)
+			if(this._viewport){
 				this._viewport.removeShape();
+			}
 			this._viewport = g;
 			this._surface.add(g);
 		},
 
-		onMapResize : function(){
-			//	summary:
+		onMapResize: function(){
+			// summary:
 			//		Called when map is resized.
-			//	tag:
-			//	protected
+			// tags:
+			//		protected
 			this._surfaceSize();
 		},
 
-		setMap : function(map){
-			//	summary:
+		setMap: function(map){
+			// summary:
 			//		Sets the map for this layer.
-			//	tag:
+			// tags:
 			//		protected
 			this.inherited(arguments);
 			this._surfaceSize();
 		},
 
-		getDataExtent : function(){
-			//	summary:
+		getDataExtent: function(){
+			// summary:
 			//		Get data extent
-			//	tags:
+			// tags:
 			//		private
 			var ret = this._surface.getDimensions();
 			return ret;
 		},
 
-		getSurface : function(){
-			//	summary:
+		getSurface: function(){
+			// summary:
 			//		Get the underlying dojox.gfx.Surface
-			//	returns: dojox.gfx.Surface 
+			// returns:
 			//		The dojox.gfx.Surface this layer uses to draw its GFX rendering.
-			return this._surface;
+			return this._surface; // dojox.gfx.Surface
 		},
 
-		_surfaceSize : function(){
-			//	summary:
+		_surfaceSize: function(){
+			// summary:
 			//		Recomputes the surface size when being resized.
-			//	tags:
+			// tags:
 			//		private
 			var s = this.olLayer.map.getSize();
 			this._surface.setDimensions(s.w, s.h);
 		},
 
-		moveTo : function(event){
+		moveTo: function(event){
 			// summary:
-			//   Called when this layer is moved or zoommed.
-			//	event:
+			//		Called when this layer is moved or zoomed.
+			// event:
 			//		The event
-			var s = dojo.style(this.olLayer.map.layerContainerDiv);
+			var s = style.get(this.olLayer.map.layerContainerDiv);
 			var left = parseInt(s.left);
 			var top = parseInt(s.top);
 
-			if (event.zoomChanged || left || top) {
+			if(event.zoomChanged || left || top){
 				var d = this.olLayer.div;
 
-				dojo.style(d, {
-					left : -left + "px",
-					top : -top + "px"
+				style.set(d, {
+					left: -left + "px",
+					top: -top + "px"
 				});
 
-				if (this._features == null)
+				if(this._features == null){
 					return;
+				}
 				var vp = this.getViewport();
 
 				vp.setTransform(matrix.translate(left, top));
@@ -130,8 +128,8 @@ define(["dojo/_base/kernel",
 			}
 		},
 
-		added : function(){
-			//	summary:
+		added: function(){
+			// summary:
 			//		Called when added to a map.
 			this.inherited(arguments);
 			this._surfaceSize();
diff --git a/dojox/geo/openlayers/GreatCircle.js b/dojox/geo/openlayers/GreatCircle.js
index 6d25bc8..ea90088 100644
--- a/dojox/geo/openlayers/GreatCircle.js
+++ b/dojox/geo/openlayers/GreatCircle.js
@@ -1,26 +1,25 @@
-define(["dojo/_base/lang",
-				"dojox/geo/openlayers/GeometryFeature",
-				"dojox/geo/openlayers/Point",
-				"dojox/geo/openlayers/LineString"], function(lang, GeometryFeature, Point, lineString){
+define([
+	"dojo/_base/lang",
+	"./_base",
+	"./GeometryFeature"
+], function(lang, openlayers, GeometryFeature){
 
-	lang.getObject("geo.openlayers", true, dojox);
+	var gc = openlayers.GreatCircle = {
 
-	dojox.geo.openlayers.GreatCircle = {
-
-		toPointArray : function(p1, p2, increment){
-			//	summary:
+		toPointArray: function(p1, p2, increment){
+			// summary:
 			//		Create a geodetic line as an array of OpenLayers.Point.
-			//	descritpion:
+			// description:
 			//		Create a geodetic line as an array of OpenLayers.Point between the point p1
-			//	and the point p2. Result is a polyline approximation for which a new point is 
-			//	calculated every <em>increment</em> degrees.
-			//	p1: Point
+			//		and the point p2. Result is a polyline approximation for which a new point is 
+			//		calculated every <em>increment</em> degrees.
+			// p1: Point
 			//		The first point of the geodetic line. x and y fields are longitude and
 			//		latitude in decimal degrees.
-			//	p2: Point
+			// p2: Point
 			//		The second point of the geodetic line. x and y fields are longitude and
 			//		latitude in decimal degrees.
-			//	increment: Float
+			// increment: Float
 			//		The value at which a new point is computed. 
 			var startLon = p1.x;
 			var endLon = p2.x;
@@ -33,13 +32,13 @@ define(["dojo/_base/lang",
 			var lat2 = p2.y * d2r;
 			var lon2 = p2.x * d2r;
 
-			if (Math.abs(lon1 - lon2) <= this.TOLERANCE) {
+			if(Math.abs(lon1 - lon2) <= this.TOLERANCE){
 				var l = Math.min(lon1, lon2);
 				lon2 = l + Math.PI;
 			}
 
-			if (Math.abs(lon2 - lon1) == Math.PI) {
-				if (lat1 + lat2 == 0.0) {
+			if(Math.abs(lon2 - lon1) == Math.PI){
+				if(lat1 + lat2 == 0.0){
 					lat2 += Math.PI / 180000000;
 				}
 			}
@@ -51,71 +50,72 @@ define(["dojo/_base/lang",
 			var k = 0;
 			var r2d = this.RAD2DEG;
 
-			while (lon <= elon) {
+			while(lon <= elon){
 				lat = Math.atan((Math.sin(lat1) * Math.cos(lat2) * Math.sin(lon - lon2) - Math.sin(lat2) * Math.cos(lat1)
 																																									* Math.sin(lon - lon1))
 												/ (Math.cos(lat1) * Math.cos(lat2) * Math.sin(lon1 - lon2)));
 				var p = {
-					x : lon * r2d,
-					y : lat * r2d
+					x: lon * r2d,
+					y: lat * r2d
 				};
 				wp[k++] = p;
-				if (lon < elon && (lon + incr) >= elon)
+				if(lon < elon && (lon + incr) >= elon){
 					lon = elon;
-				else
+				}else{
 					lon = lon + incr;
+				}
 			}
 			return wp;
 		},
 
-		toLineString : function(p1, p2, increment){
-			//	summary:
+		toLineString: function(p1, p2, increment){
+			// summary:
 			//		Create a geodetic line as an array of OpenLayers.Geometry.LineString.
-			//	descritpion:
+			// description:
 			//		Create a geodetic line as a OpenLayers.Geometry.LineString between the point p1
 			//		and the point p2. Result is a polyline approximation for which a new point is 
-			// 		calculated every <em>increment</em> degrees.
-			//	p1: Point
+			//		calculated every <em>increment</em> degrees.
+			// p1: Point
 			//		The first point of the geodetic line. x and y fields are longitude and
-			//	latitude in decimal degrees.
-			//	p2: Point
+			//		latitude in decimal degrees.
+			// p2: Point
 			//		The second point of the geodetic line. x and y fields are longitude and
 			//		latitude in decimal degrees.
-			//	increment: Float
+			// increment: Float
 			//		The value at which a new point is computed. 
 			var wp = this.toPointArray(p1, p2, increment);
 			var ls = new OpenLayers.Geometry.LineString(wp);
 			return ls;
 		},
 
-		toGeometryFeature : function(p1, p2, increment){
-			//	summary:
+		toGeometryFeature: function(p1, p2, increment){
+			// summary:
 			//		Create a geodetic line as an array of dojox.geo.openlayers.GeometryFeature.
-			//	description:
-			// 		Create a geodetic line as a dojox.geo.openlayers.GeometryFeature between the point p1
+			// description:
+			//		Create a geodetic line as a dojox.geo.openlayers.GeometryFeature between the point p1
 			//		ant the point p2. Result is a polyline approximation for which a new point is 
 			//		calculated every <em>increment</em> degrees.
-			//	p1: Point
+			// p1: Point
 			//		The first point of the geodetic line. x and y fields are longitude and
 			//		latitude in decimal degrees.
-			//	p2: Point
+			// p2: Point
 			//		The second point of the geodetic line. x and y fields are longitude and
 			//		latitude in decimal degrees.
-			//	increment: Float
+			// increment: Float
 			//		The value at which a new point is computed. 
-			//	returns: GeometryFeature
+			// returns:
 			//		The geodetic line as a GeometryFeature
 
 			var ls = this.toLineString(p1, p2, increment);
-			return new GeometryFeature(ls);
+			return new GeometryFeature(ls); // GeometryFeature
 		},
 
-		DEG2RAD : Math.PI / 180,
+		DEG2RAD: Math.PI / 180,
 
-		RAD2DEG : 180 / Math.PI,
+		RAD2DEG: 180 / Math.PI,
 
-		TOLERANCE : 0.00001
+		TOLERANCE: 0.00001
 	};
-
-	return dojox.geo.openlayers.GreatCircle;
+	
+	return gc;
 });
diff --git a/dojox/geo/openlayers/JsonImport.js b/dojox/geo/openlayers/JsonImport.js
index 35bbbd3..a5c970f 100644
--- a/dojox/geo/openlayers/JsonImport.js
+++ b/dojox/geo/openlayers/JsonImport.js
@@ -1,58 +1,64 @@
-define(["dojo/_base/kernel",
-				"dojo/_base/declare",
-				"dojo/_base/xhr",
-				"dojo/_base/lang",
-				"dojo/_base/array",
-				"dojox/geo/openlayers/LineString",
-				"dojox/geo/openlayers/Collection",
-				"dojo/data/ItemFileReadStore",
-				"dojox/geo/openlayers/GeometryFeature"], function(dojo, declare, xhr, lang, array, LineString, Collection,
-																													ItemFileReadStore, GeometryFeature){
+define([
+	"dojo/_base/declare",
+	"dojo/_base/xhr",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"./LineString",
+	"./Collection",
+	"./GeometryFeature"
+], function(declare, xhr, lang, array, LineString, Collection, GeometryFeature){
+
+	/*=====
+	dojox.geo.openlayers.__JsonImportArgs = {
+		// summary:
+		//		The keyword arguments that can be passed in a JsonImport constructor.
+		// url: String
+		//		The url pointing to the JSON file to load.
+		// nextFeature: function
+		//		The function called each time a feature is read. The function is called with a GeometryFeature as argument.
+		// error: function
+		//		Error callback called if something fails.
+	};
+	=====*/
 
 	return declare("dojox.geo.openlayers.JsonImport", null, {
-		//	summary:
+		// summary:
 		//		Class to load JSON formated ShapeFile as output of the JSon Custom Map Converter.
-		//	description:
+		// description:
 		//		This class loads JSON formated ShapeFile produced by the JSon Custom Map Converter.
 		//		When loading the JSON file, it calls a iterator function each time a feature is read.
 		//		This iterator function is provided as parameter to the constructor.
 		//
-		constructor : function(/* Object */params){
-			//	summary:
+		constructor : function(params){
+			// summary:
 			//		Construct a new JSON importer.
-			//	description:
-			//		Construct a new JSON importer with the specified parameters. These parameters are
-			//		passed through an Object and include:
-			//	<ul>
-			//		<li> url : <em>url</em> </li> The url pointing to the JSON file to load.
-			//		<li> nextFeature : <em>function</em> </li> The function called each time a feature is read.
-			//		The function is called with a GeometryFeature as argument.
-			//		<li> error : <em>function</em> </li> Error function called if something goes wrong.
-			//	</ul>
+			// params: dojox.geo.openlayers.__JsonImportArgs
+			//		The parameters to initialize this JsonImport instance.
 			this._params = params;
 		},
 
-		loadData : function(){
-			//	summary:
+		loadData: function(){
+			// summary:
 			//		Triggers the loading.
 			var p = this._params;
 			xhr.get({
-				url : p.url,
-				handleAs : "json",
-				sync : true,
-				load : lang.hitch(this, this._gotData),
-				error : lang.hitch(this, this._loadError)
+				url: p.url,
+				handleAs: "json",
+				sync: true,
+				load: lang.hitch(this, this._gotData),
+				error: lang.hitch(this, this._loadError)
 			});
 		},
 
-		_gotData : function(/* Object */items){
-			//	summary:
+		_gotData: function(/* Object */items){
+			// summary:
 			//		Called when loading is complete.
-			//	tags:
+			// tags:
 			//		private
 			var nf = this._params.nextFeature;
-			if (!lang.isFunction(nf))
+			if(!lang.isFunction(nf)){
 				return;
+			}
 
 			var extent = items.layerExtent;
 			var ulx = extent[0];
@@ -73,11 +79,11 @@ define(["dojo/_base/kernel",
 
 			var features = items.features;
 
-			for ( var f in features) {
+			for( var f in features){
 				var o = features[f];
 				var s = o["shape"];
 				var gf = null;
-				if (lang.isArray(s[0])) {
+				if(lang.isArray(s[0])){
 
 					var a = new Array();
 					array.forEach(s, function(item){
@@ -88,25 +94,26 @@ define(["dojo/_base/kernel",
 					gf = new GeometryFeature(g);
 					nf.call(this, gf);
 
-				} else {
+				}else{
 					gf = this._makeFeature(s, ulx, uly, lrx, lry, ulxLL, ulyLL, lrxLL, lryLL);
 					nf.call(this, gf);
 				}
 			}
 			var complete = this._params.complete;
-			if (lang.isFunction(complete))
+			if(lang.isFunction(complete)){
 				complete.call(this, complete);
+			}
 		},
 
-		_makeGeometry : function(/* Array */s, /* Float */ulx, /* Float */uly, /* Float */lrx, /* Float */
+		_makeGeometry: function(/* Array */s, /* Float */ulx, /* Float */uly, /* Float */lrx, /* Float */
 		lry, /* Float */ulxLL, /* Float */ulyLL, /* Float */lrxLL, /* Float */lryLL){
-			//	summary:
+			// summary:
 			//		Make a geometry with the specified points.
-			//	tags:
+			// tags:
 			//		private
 			var a = [];
 			var k = 0.0;
-			for ( var i = 0; i < s.length - 1; i += 2) {
+			for( var i = 0; i < s.length - 1; i += 2){
 				var x = s[i];
 				var y = s[i + 1];
 
@@ -117,34 +124,35 @@ define(["dojo/_base/kernel",
 				var py = k * (lryLL - ulyLL) + ulyLL;
 
 				a.push({
-					x : px,
-					y : py
+					x: px,
+					y: py
 				});
 
 			}
 			var ls = new LineString(a);
-			return ls;
+			return ls; // LineString
 		},
 
-		_makeFeature : function(/* Array */s, /* Float */ulx, /* Float */uly, /* Float */lrx, /* Float */
+		_makeFeature: function(/* Array */s, /* Float */ulx, /* Float */uly, /* Float */lrx, /* Float */
 		lry, /* Float */ulxLL, /* Float */ulyLL, /* Float */lrxLL, /* Float */lryLL){
-			//	summary:
+			// summary:
 			//		Make a GeometryFeature with the specified points.
-			//	tags:
+			// tags:
 			//		private
 			var ls = this._makeGeometry(s, ulx, uly, lrx, lry, ulxLL, ulyLL, lrxLL, lryLL);
 			var gf = new GeometryFeature(ls);
 			return gf;
 		},
 
-		_loadError : function(){
-			//	summary:
+		_loadError: function(){
+			// summary:
 			//		Called when an error occurs. Calls the error function is provided in the parameters.
-			//	tags:
+			// tags:
 			//		private
 			var f = this._params.error;
-			if (lang.isFunction(f))
+			if(lang.isFunction(f)){
 				f.apply(this, parameters);
+			}
 		}
 	});
 });
diff --git a/dojox/geo/openlayers/Layer.js b/dojox/geo/openlayers/Layer.js
index f3cdf1f..6ba5ff7 100644
--- a/dojox/geo/openlayers/Layer.js
+++ b/dojox/geo/openlayers/Layer.js
@@ -1,68 +1,76 @@
-define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/sniff"],
-	function(dojo, declare, lang, array, sniff){
+define([
+	"dojo/_base/declare", 
+	"dojo/_base/lang", 
+	"dojo/_base/array", 
+	"dojo/_base/sniff",
+	"./Feature"
+], function(declare, lang, array, sniff, Feature){
 
 		return declare("dojox.geo.openlayers.Layer", null, {
-			//	summary: 
+			// summary:
 			//		Base layer class for dojox.geo.openlayers.Map specific layers extending OpenLayers.Layer class.
 			//		This layer class accepts Features which encapsulates graphic objects to be added to the map.
 			//		This layer class encapsulates an OpenLayers.Layer.
 			//		This class provides Feature management such as add, remove and feature access.
-			constructor : function(name, options){
-				//	summary:
+			constructor: function(name, options){
+				// summary:
 				//		Constructs a new Layer.
-				//	name: String
+				// name: String
 				//		The name of the layer.
-				//	options: Object
+				// options: Object
 				//		Options passed to the underlying OpenLayers.Layer object.
 
 				var ol = options ? options.olLayer : null;
 
-				if (!ol)
+				if(!ol){
 					ol = lang.delegate(new OpenLayers.Layer(name, options));
+				}
 
 				this.olLayer = ol;
 				this._features = null;
 				this.olLayer.events.register("moveend", this, lang.hitch(this, this.moveTo));
 			},
 
-			renderFeature : function(/* Feature */f){
-				//	summary:
+			renderFeature: function(/* Feature */f){
+				// summary:
 				//		Called when rendering a feature is necessary.
-				//	f : Feature
+				// f: Feature
 				//		The feature to draw.
 				f.render();
 			},
 
-			getDojoMap : function(){
+			getDojoMap: function(){
 				return this.dojoMap;
 			},
 
-			addFeature : function(/* Feature | Array */f){
-				//	summary:
+			addFeature: function(f){
+				// summary:
 				//		Add a feature or an array of features to the layer.
-				//	f : Feature or Array
+				// f: Feature|Feature[]
 				//		The Feature or array of features to add.
-				if (lang.isArray(f)) {
+				if(lang.isArray(f)){
 					array.forEach(f, function(item){
 						this.addFeature(item);
 					}, this);
 					return;
 				}
-				if (this._features == null)
+				if(this._features == null){
 					this._features = [];
+				}
 				this._features.push(f);
 				f._setLayer(this);
 			},
 
-			removeFeature : function(/* Feature | Array */f){
-				//	summary :
+			removeFeature: function(f){
+				// summary:
 				//		Removes a feature or an array of features from the layer.
-				//	f : Feature or Array
+				// f: Feature|Feature[]
 				//		The Feature or array of features to remove.
 				var ft = this._features;
-				if (ft == null)
+				if(ft == null){
 					return;
-				if (f instanceof Array) {
+				}
+				if(f instanceof Array){
 					f = f.slice(0);
 					array.forEach(f, function(item){
 						this.removeFeature(item);
@@ -70,93 +78,97 @@ define(["dojo/_base/kernel", "dojo/_base/declare", "dojo/_base/lang", "dojo/_bas
 					return;
 				}
 				var i = array.indexOf(ft, f);
-				if (i != -1)
+				if(i != -1){
 					ft.splice(i, 1);
+				}
 				f._setLayer(null);
 				f.remove();
 			},
 
-			removeFeatureAt : function(index){
-				//	summary:
-				//		Remove the feature at the specified index.
-				//	description:
+			removeFeatureAt: function(index){
+				// summary:
 				//		Remove the feature at the specified index.
-				//	index: Number
+				// index: int
 				//		The index of the feature to remove.
 				var ft = this._features;
 				var f = ft[index];
-				if (!f)
+				if(!f){
 					return;
+				}
 				ft.splice(index, 1);
 				f._setLayer(null);
 				f.remove();
 			},
 
-			getFeatures : function(){
-				//	summary:
-				//		Retrieves the feature hold by this layer.
-				//	returns: Array
+			getFeatures: function(){
+				// summary:
+				//		Returns the feature hold by this layer.
+				// returns:
 				//		The untouched array of features hold by this layer.
-				return this._features;
+				return this._features; // Feature[]
 			},
 
-			getFeatureAt : function(i){
-				//	summary:
+			getFeatureAt: function(i){
+				// summary:
 				//		Returns the i-th feature of this layer.
-				//	i : int
+				// i: Number
 				//		The index of the feature to return.
-				//	returns : ibm_maps.maps.Layer
+				// returns:
 				//		The i-th feature of this layer.
-				if (this._features == null)
+				if(this._features == null){
 					return undefined;
-				return this._features[i];
+				}
+				return this._features[i]; // Feature
 			},
 
-			getFeatureCount : function(){
-				//	summary:
+			getFeatureCount: function(){
+				// summary:
 				//		Returns the number of the features contained by this layer.
-				//	returns: int
+				// returns:
 				//		The number of the features contained by this layer.
-				if (this._features == null)
+				if(this._features == null){
 					return 0;
-				return this._features.length;
+				}
+				return this._features.length; // Number
 			},
 
-			clear : function(){
-				//	summary:
+			clear: function(){
+				// summary:
 				//		Removes all the features from this layer.
 				var fa = this.getFeatures();
 				this.removeFeature(fa);
 			},
 
-			moveTo : function(event){
-				//	summary:
+			moveTo: function(event){
+				// summary:
 				//		Called when the layer is panned or zoomed.
-				//	event: Object
+				// event: MouseEvent
 				//		The event
-				if (event.zoomChanged) {
-					if (this._features == null)
+				if(event.zoomChanged){
+					if(this._features == null){
 						return;
+					}
 					array.forEach(this._features, function(f){
 						this.renderFeature(f);
 					}, this);
 				}
 			},
 
-			redraw : function(){
-				//	summary:
+			redraw: function(){
+				// summary:
 				//		Redraws this layer
-				if (sniff.isIE)
+				if(sniff.isIE){
 					setTimeout(lang.hitch(this, function(){
 						this.olLayer.redraw();
 					}, 0));
-				else
+				}else{
 					this.olLayer.redraw();
+				}
 			},
 
-			added : function(){
-			//	summary:
-			//		Called when the layer is added to the map
+			added: function(){
+				// summary:
+				//		Called when the layer is added to the map
 			}
 
 		});
diff --git a/dojox/geo/openlayers/LineString.js b/dojox/geo/openlayers/LineString.js
index 17cb285..36ec3a9 100644
--- a/dojox/geo/openlayers/LineString.js
+++ b/dojox/geo/openlayers/LineString.js
@@ -1,26 +1,27 @@
-define(["dojo/_base/kernel", "dojo/_base/declare", "dojox/geo/openlayers/Geometry"], function(dojo, declare,
-		/* ===== 
-		var Geometry = dojox.geo.openlayers.Geometry; 
-		=====*/																																															Geometry){
+define([
+	"dojo/_base/declare",
+	"./Geometry"
+], function(declare, Geometry){
+
 	return declare("dojox.geo.openlayers.LineString", Geometry, {
-		//	summary:
+		// summary:
 		//		The `dojox.geo.openlayers.LineString` geometry. This geometry holds an array
 		//		of coordinates.
 
-		setPoints : function(p){
-			//	summary:
+		setPoints: function(p){
+			// summary:
 			//		Sets the points for this geometry.
-			//	p : Array
+			// p: Object[]
 			//		An array of {x, y} objects
 			this.coordinates = p;
 		},
 
-		getPoints : function(){
-			//	summary:
+		getPoints: function(){
+			// summary:
 			//		Gets the points of this geometry.
-			//	returns: Array
+			// returns:
 			//		The points of this geometry.
-			return this.coordinates;
+			return this.coordinates; // Object[]
 		}
 
 	});
diff --git a/dojox/geo/openlayers/Map.js b/dojox/geo/openlayers/Map.js
index a614a76..d64f414 100644
--- a/dojox/geo/openlayers/Map.js
+++ b/dojox/geo/openlayers/Map.js
@@ -1,177 +1,134 @@
-define(["dojo/_base/kernel",
-				"dojo/_base/declare",
-				"dojo/_base/lang",
-				"dojo/_base/array",
-				"dojo/_base/json",
-				"dojo/_base/html",
-				"dojox/main",
-				"dojox/geo/openlayers/TouchInteractionSupport",
-				"dojox/geo/openlayers/Layer",
-				"dojox/geo/openlayers/Patch"], function(dojo, declare, lang, array, json, html, dojox, TouchInteractionSupport,
-																								Layer, Patch){
-
-	dojo.experimental("dojox.geo.openlayers.Map");
-
-	lang.getObject("geo.openlayers", true, dojox);
-
-	dojox.geo.openlayers.BaseLayerType = {
-		//	summary:
-		//		Defines the base layer types to be used at Map construction time or
-		//		with the setBaseLayerType function.
-		//	description:
-		//		This object defines the base layer types to be used at Map construction
-		//		time or with the setBaseLayerType function.
-		//	OSM: String
-		//		The Open Street Map base layer type selector.
-		OSM : "OSM",
-		//	WMS: String
-		//		The Web Map Server base layer type selector.
-		WMS : "WMS",
-		//	GOOGLE: String
-		//		The Google base layer type selector.
-		GOOGLE : "Google",
-		//	VIRTUAL_EARTH: String
-		//		The Virtual Earth base layer type selector.
-		VIRTUAL_EARTH : "VirtualEarth",
-		//	BING: String
-		//		Same as Virtual Earth
-		BING : "VirtualEarth",
-		//	YAHOO: String
-		//		The Yahoo base layer type selector.
-		YAHOO : "Yahoo",
-		//	ARCGIS: String
-		//		The ESRI ARCGis base layer selector.
-		ARCGIS : "ArcGIS"
-	};
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/json",
+	"dojo/dom",
+	"dojo/dom-style",
+	"./_base",
+	"./TouchInteractionSupport",
+	"./Layer",
+	"./Patch"
+], function(kernel, declare, lang, array, json, dom, style, openlayers, TouchInteractionSupport, Layer, Patch){
+
+	kernel.experimental("dojox.geo.openlayers.Map");
 
-	dojox.geo.openlayers.EPSG4326 = new OpenLayers.Projection("EPSG:4326");
-
-	var re = /^\s*(\d{1,3})[D°]\s*(\d{1,2})[M']\s*(\d{1,2}\.?\d*)\s*(S|"|'')\s*([NSEWnsew]{0,1})\s*$/i;
-	dojox.geo.openlayers.parseDMS = function(v, toDecimal){
-		//	summary: 
-		//		Parses the specified string and returns degree minute second or decimal degree.
-		//	description: 
-		//		Parses the specified string and returns degree minute second or decimal degree.
-		//	v: String
-		//		The string to parse
-		//	toDecimal: Boolean
-		//		Specifies if the result should be returned in decimal degrees or in an array
-		//		containg the degrees, minutes, seconds values.
-		//	returns: Float | Array
-		//		the parsed value in decimal degrees or an array containing the degrees, minutes, seconds values.
-
-		var res = re.exec(v);
-		if (res == null || res.length < 5)
-			return parseFloat(v);
-		var d = parseFloat(res[1]);
-		var m = parseFloat(res[2]);
-		var s = parseFloat(res[3]);
-		var nsew = res[5];
-		if (toDecimal) {
-			var lc = nsew.toLowerCase();
-			var dd = d + (m + s / 60.0) / 60.0;
-			if (lc == "w" || lc == "s")
-				dd = -dd;
-			return dd;
-		}
-		return [d, m, s, nsew];
-	};
 
 	Patch.patchGFX();
 
+	/*=====
+	dojox.geo.openlayers.__MapArgs = {
+		// summary:
+		//		The keyword arguments that can be passed in a Map constructor.
+		// baseLayerType: String
+		//		 type of the base layer. Can be any of
+		//
+		//		- `dojox.geo.openlayers.BaseLayerType.OSM`: Open Street Map base layer
+		//		- `dojox.geo.openlayers.BaseLayerType.WMS`: Web Map Service layer
+		//		- `dojox.geo.openlayers.BaseLayerType.GOOGLE`: Google layer
+		//		- `dojox.geo.openlayers.BaseLayerType.VIRTUAL_EARTH`: Virtual Earth layer
+		//		- `dojox.geo.openlayers.BaseLayerType.BING`: Bing layer
+		//		- `dojox.geo.openlayers.BaseLayerType.YAHOO`: Yahoo layer
+		//		- `dojox.geo.openlayers.BaseLayerType.ARCGIS`: ESRI ArgGIS layer
+		// baseLayerName: String
+		//		The name of the base layer.
+		// baseLayerUrl: String
+		//		Some layer may need an url such as Web Map Server.
+		// baseLayerOptions: String
+		//		Additional specific options passed to OpensLayers layer, such as The list of layer to display, for Web Map Server layer.
+	};
+	=====*/
+
 	return declare("dojox.geo.openlayers.Map", null, {
-		//	summary:
+		// summary:
 		//		A map viewer based on the OpenLayers library.
 		//
-		//	description:
+		// description:
 		//		The `dojox.geo.openlayers.Map` object allows to view maps from various map providers. 
 		//		It encapsulates  an `OpenLayers.Map` object on which most operations are delegated.
 		//		GFX layers can be added to display GFX georeferenced shapes as well as Dojo widgets.
 		//		Parameters can be passed as argument at construction time to define the base layer
 		//		type and the base layer parameters such as url or options depending on the type
-		//		specified. These parameters can be any of :
-		//	<br />
-		//	_baseLayerType_: type of the base layer. Can be any of
-		//	
-		//	* `dojox.geo.openlayers.BaseLayerType.OSM`: Open Street Map base layer
-		//	* `dojox.geo.openlayers.BaseLayerType.WMS`: Web Map Service layer
-		//	* `dojox.geo.openlayers.BaseLayerType.GOOGLE`: Google layer
-		//	* `dojox.geo.openlayers.BaseLayerType.VIRTUAL_EARTH`: Virtual Earth layer
-		//	* `dojox.geo.openlayers.BaseLayerType.BING`: Bing layer
-		//	* `dojox.geo.openlayers.BaseLayerType.YAHOO`: Yahoo layer
-		//	* `dojox.geo.openlayers.BaseLayerType.ARCGIS`: ESRI ArgGIS layer
+		//		specified. These parameters can be any of:
 		//
-		//	Note that access to commercial server such as Google, Virtual Earth or Yahoo may need specific licencing.
-		// 
-		//	The parameters value also include :
-		// 
-		//	* `baseLayerName`: The name of the base layer.
-		//	* `baseLayerUrl`: Some layer may need an url such as Web Map Server
-		//	* `baseLayerOptions`: Addtional specific options passed to OpensLayers layer,  
-		//	such as The list of layer to display, for Web Map Server layer.
+		//		_baseLayerType_: type of the base layer. Can be any of:
+		//		
+		//		- `dojox.geo.openlayers.BaseLayerType.OSM`: Open Street Map base layer
+		//		- `dojox.geo.openlayers.BaseLayerType.WMS`: Web Map Service layer
+		//		- `dojox.geo.openlayers.BaseLayerType.GOOGLE`: Google layer
+		//		- `dojox.geo.openlayers.BaseLayerType.VIRTUAL_EARTH`: Virtual Earth layer
+		//		- `dojox.geo.openlayers.BaseLayerType.BING`: Bing layer
+		//		- `dojox.geo.openlayers.BaseLayerType.YAHOO`: Yahoo layer
+		//		- `dojox.geo.openlayers.BaseLayerType.ARCGIS`: ESRI ArgGIS layer
+		//		
+		//		Note that access to commercial server such as Google, Virtual Earth or Yahoo may need specific licencing.
+		//		
+		//		The parameters value also include:
+		//		
+		//		- `baseLayerName`: The name of the base layer.
+		//		- `baseLayerUrl`: Some layer may need an url such as Web Map Server
+		//		- `baseLayerOptions`: Additional specific options passed to OpensLayers layer,
+		//		  such as The list of layer to display, for Web Map Server layer.
 		//
-		//	example:
-		// 
+		// example:
 		//	|	var map = new dojox.geo.openlayers.widget.Map(div, {
-		//	|		baseLayerType : dojox.geo.openlayers.BaseLayerType.OSM,
-		//	|		baseLayerName : 'Open Street Map Layer'
+		//	|		baseLayerType: dojox.geo.openlayers.BaseLayerType.OSM,
+		//	|		baseLayerName: 'Open Street Map Layer'
 		//	|	});
 
-		//	summary:
+		// olMap: OpenLayers.Map
 		//		The underlying OpenLayers.Map object.
 		//		Should be accessed on read mode only.
-		olMap : null,
+		olMap: null,
 
-		_tp : null,
+		_tp: null,
 
-		constructor : function(div, options){
-			//	summary: 
+		constructor: function(div, options){
+			// summary:
 			//		Constructs a new Map object
-			if (!options)
+			if(!options){
 				options = {};
+			}
 
-			div = html.byId(div);
+			div = dom.byId(div);
 
 			this._tp = {
-				x : 0,
-				y : 0
+				x: 0,
+				y: 0
 			};
 
 			var opts = options.openLayersMapOptions;
 
-			if (!opts) {
+			if(!opts){
 				opts = {
-					controls : [new OpenLayers.Control.ScaleLine({
-						maxWidth : 200
+					controls: [new OpenLayers.Control.ScaleLine({
+						maxWidth: 200
 					}), new OpenLayers.Control.Navigation()]
 				};
 			}
-			if (options.accessible) {
+			if(options.accessible){
 				var kbd = new OpenLayers.Control.KeyboardDefaults();
-				if (!opts.controls)
+				if(!opts.controls){
 					opts.controls = [];
+				}
 				opts.controls.push(kbd);
 			}
 			var baseLayerType = options.baseLayerType;
-			if (!baseLayerType)
-				baseLayerType = dojox.geo.openlayers.BaseLayerType.OSM;
-
-			html.style(div, {
-				width : "100%",
-				height : "100%",
-				dir : "ltr"
-			});
-
+			if(!baseLayerType){
+				baseLayerType = openlayers.BaseLayerType.OSM;
+			}
 			var map = new OpenLayers.Map(div, opts);
 			this.olMap = map;
 
 			this._layerDictionary = {
-				olLayers : [],
-				layers : []
+				olLayers: [],
+				layers: []
 			};
 
-			if (options.touchHandler)
+			if(options.touchHandler){
 				this._touchControl = new TouchInteractionSupport(map);
+			}
 
 			var base = this._createBaseLayer(options);
 			this.addLayer(base);
@@ -179,60 +136,68 @@ define(["dojo/_base/kernel",
 			this.initialFit(options);
 		},
 
-		initialFit : function(params){
+		initialFit: function(params){
+			// summary:
+			//		Performs an initial fit to contents.
+			// tags:
+			//		protected
 			var o = params.initialLocation;
-			if (!o)
+			if(!o){
 				o = [-160, 70, 160, -70];
+			}
 			this.fitTo(o);
 		},
 
-		setBaseLayerType : function(
-		/* dojox.geo.openlayers.Map.BaseLayerType */type){
-			//	summary: 
+		setBaseLayerType: function(type){
+			// summary:
 			//		Set the base layer type, replacing the existing base layer
-			//	type: dojox.geo.openlayers.BaseLayerType
+			// type: dojox/geo/openlayers.BaseLayerType
 			//		base layer type
-			//	returns: OpenLayers.Layer
+			// returns:
 			//		The newly created layer.
-			if (type == this.baseLayerType)
-				return null;
+			if(type == this.baseLayerType){
+				return null; // Layer
+			}
 
 			var o = null;
-			if (typeof type == "string") {
+			if(typeof type == "string"){
 				o = {
-					baseLayerName : type,
-					baseLayerType : type
+					baseLayerName: type,
+					baseLayerType: type
 				};
 				this.baseLayerType = type;
-			} else if (typeof type == "object") {
+			}else if(typeof type == "object"){
 				o = type;
 				this.baseLayerType = o.baseLayerType;
 			}
 			var bl = null;
-			if (o != null) {
+			if(o != null){
 				bl = this._createBaseLayer(o);
-				if (bl != null) {
+				if(bl != null){
 					var olm = this.olMap;
 					var ob = olm.getZoom();
 					var oc = olm.getCenter();
 					var recenter = !!oc && !!olm.baseLayer && !!olm.baseLayer.map;
 
-					if (recenter) {
+					if(recenter){
 						var proj = olm.getProjectionObject();
-						if (proj != null)
-							oc = oc.transform(proj, dojox.geo.openlayers.EPSG4326);
+						if(proj != null){
+							oc = oc.transform(proj, openlayers.EPSG4326);
+						}
 					}
 					var old = olm.baseLayer;
-					if (old != null) {
+					if(old != null){
 						var l = this._getLayer(old);
 						this.removeLayer(l);
 					}
-					if (bl != null)
+					if(bl != null){
 						this.addLayer(bl);
-					if (recenter) {
+					}
+					if(recenter){
 						proj = olm.getProjectionObject();
-						if (proj != null)
-							oc = oc.transform(dojox.geo.openlayers.EPSG4326, proj);
+						if(proj != null){
+							oc = oc.transform(openlayers.EPSG4326, proj);
+						}
 						olm.setCenter(oc, ob);
 					}
 				}
@@ -240,50 +205,48 @@ define(["dojo/_base/kernel",
 			return bl;
 		},
 
-		getBaseLayerType : function(){
-			//	summary:
-			//		Retrieves the base layer type.
-			//	returns: dojox.geo.openlayers.BaseLayerType
+		getBaseLayerType: function(){
+			// summary:
+			//		Returns the base layer type.
+			// returns:
 			//		The current base layer type.
-			return this.baseLayerType;
+			return this.baseLayerType; // openlayers.BaseLayerType
 		},
 
-		getScale : function(geodesic){
-			//	summary: 
+		getScale: function(geodesic){
+			// summary:
 			//		Returns the current scale
-			//	geodesic: Boolean
+			// geodesic: Boolean
 			//		Tell if geodesic calculation should be performed. If set to
 			//		true, the scale will be calculated based on the horizontal size of the
 			//		pixel in the center of the map viewport.
-			//	returns: Number
-			//		The current scale.
-			var scale;
+			var scale = null;
 			var om = this.olMap;
-			if (geodesic) {
+			if(geodesic){
 				var units = om.getUnits();
-				if (!units) {
-					return null;
+				if(!units){
+					return null;	// Number
 				}
 				var inches = OpenLayers.INCHES_PER_UNIT;
 				scale = (om.getGeodesicPixelSize().w || 0.000001) * inches["km"] * OpenLayers.DOTS_PER_INCH;
-			} else {
+			}else{
 				scale = om.getScale();
 			}
-			return scale;
+			return scale;	// Number
 		},
 
-		getOLMap : function(){
-			//	summary:
+		getOLMap: function(){
+			// summary:
 			//		gets the underlying OpenLayers map object.
-			//	returns : OpenLayers.Map
+			// returns:
 			//		The underlying OpenLayers map object.
-			return this.olMap;
+			return this.olMap;	// OpenLayers.Map
 		},
 
-		_createBaseLayer : function(params){
-			//	summary:
+		_createBaseLayer: function(params){
+			// summary:
 			//		Creates the base layer.
-			//	tags:
+			// tags:
 			//		private
 			var base = null;
 			var type = params.baseLayerType;
@@ -291,102 +254,111 @@ define(["dojo/_base/kernel",
 			var name = params.baseLayerName;
 			var options = params.baseLayerOptions;
 
-			if (!name)
+			if(!name){
 				name = type;
-			if (!options)
+			}
+			if(!options){
 				options = {};
-			switch (type) {
-				case dojox.geo.openlayers.BaseLayerType.OSM:
+			}
+			switch(type){
+				case openlayers.BaseLayerType.OSM:
 					options.transitionEffect = "resize";
 					//				base = new OpenLayers.Layer.OSM(name, url, options);
 					base = new Layer(name, {
-						olLayer : new OpenLayers.Layer.OSM(name, url, options)
+						olLayer: new OpenLayers.Layer.OSM(name, url, options)
 					});
 				break;
-				case dojox.geo.openlayers.BaseLayerType.WMS:
-					if (!url) {
+				case openlayers.BaseLayerType.WMS:
+					if(!url){
 						url = "http://labs.metacarta.com/wms/vmap0";
-						if (!options.layers)
+						if(!options.layers){
 							options.layers = "basic";
+						}
 					}
 					base = new Layer(name, {
-						olLayer : new OpenLayers.Layer.WMS(name, url, options, {
-							transitionEffect : "resize"
+						olLayer: new OpenLayers.Layer.WMS(name, url, options, {
+							transitionEffect: "resize"
 						})
 					});
 				break;
-				case dojox.geo.openlayers.BaseLayerType.GOOGLE:
+				case openlayers.BaseLayerType.GOOGLE:
 					base = new Layer(name, {
-						olLayer : new OpenLayers.Layer.Google(name, options)
+						olLayer: new OpenLayers.Layer.Google(name, options)
 					});
 				break;
-				case dojox.geo.openlayers.BaseLayerType.VIRTUAL_EARTH:
+				case openlayers.BaseLayerType.VIRTUAL_EARTH:
 					base = new Layer(name, {
-						olLayer : new OpenLayers.Layer.VirtualEarth(name, options)
+						olLayer: new OpenLayers.Layer.VirtualEarth(name, options)
 					});
 				break;
-				case dojox.geo.openlayers.BaseLayerType.YAHOO:
+				case openlayers.BaseLayerType.YAHOO:
 					//				base = new OpenLayers.Layer.Yahoo(name);
 					base = new Layer(name, {
-						olLayer : new OpenLayers.Layer.Yahoo(name, options)
+						olLayer: new OpenLayers.Layer.Yahoo(name, options)
 					});
 				break;
-				case dojox.geo.openlayers.BaseLayerType.ARCGIS:
-					if (!url)
+				case openlayers.BaseLayerType.ARCGIS:
+					if(!url){
 						url = "http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer/export";
+					}
 					base = new Layer(name, {
-						olLayer : new OpenLayers.Layer.ArcGIS93Rest(name, url, options, {})
+						olLayer: new OpenLayers.Layer.ArcGIS93Rest(name, url, options, {})
 					});
 
 				break;
 			}
 
-			if (base == null) {
-				if (type instanceof OpenLayers.Layer)
+			if(base == null){
+				if(type instanceof OpenLayers.Layer){
 					base = type;
-				else {
+				}else{
 					options.transitionEffect = "resize";
 					base = new Layer(name, {
-						olLayer : new OpenLayers.Layer.OSM(name, url, options)
+						olLayer: new OpenLayers.Layer.OSM(name, url, options)
 					});
-					this.baseLayerType = dojox.geo.openlayers.BaseLayerType.OSM;
+					this.baseLayerType = openlayers.BaseLayerType.OSM;
 				}
 			}
 
 			return base;
 		},
 
-		removeLayer : function(/* dojox.geo.openlayers.Layer */layer){
-			//	summary: 
+		removeLayer: function(layer){
+			// summary:
 			//		Remove the specified layer from the map.
-			//	layer: dojox.geo.openlayers.Layer
+			// layer: Layer
 			//		The layer to remove from the map.
 			var om = this.olMap;
 			var i = array.indexOf(this._layerDictionary.layers, layer);
-			if (i > 0)
+			if(i > 0){
 				this._layerDictionary.layers.splice(i, 1);
+			}
 			var oll = layer.olLayer;
 			var j = array.indexOf(this._layerDictionary.olLayers, oll);
-			if (j > 0)
+			if(j > 0){
 				this._layerDictionary.olLayers.splice(i, j);
+			}
 			om.removeLayer(oll, false);
 		},
 
-		layerIndex : function(/* dojox.geo.openlayers.Layer */layer, index){
-			//	summary:
+		layerIndex: function(layer, index){
+			// summary:
 			//		Set or retrieve the layer index.
-			//	description:
+			// description:
 			//		Set or get the layer index, that is the z-order of the layer.
 			//		if the index parameter is provided, the layer index is set to
 			//		this value. If the index parameter is not provided, the index of 
 			//		the layer is returned.
-			//	index: undefined | int
+			// layer: Layer
+			//		the layer to retrieve the index.
+			// index: int?
 			//		index of the layer
-			// 	returns: int
+			// returns:
 			//		the index of the layer.
 			var olm = this.olMap;
-			if (!index)
+			if(!index){
 				return olm.getLayerIndex(layer.olLayer);
+			}
 			//olm.raiseLayer(layer.olLayer, index);
 			olm.setLayerIndex(layer.olLayer, index);
 
@@ -397,13 +369,13 @@ define(["dojo/_base/kernel",
 				return olm.getLayerIndex(l1) - olm.getLayerIndex(l2);
 			});
 
-			return index;
+			return index; // Number
 		},
 
-		addLayer : function(/* dojox.geo.openlayers.Layer */layer){
-			//	summary: 
+		addLayer: function(layer){
+			// summary:
 			//		Add the specified layer to the map.
-			//	layer: dojox.geo.openlayer.Layer
+			// layer: Layer
 			//		The layer to add to the map.
 			layer.dojoMap = this;
 			var om = this.olMap;
@@ -414,28 +386,29 @@ define(["dojo/_base/kernel",
 			layer.added();
 		},
 
-		_getLayer : function(/*OpenLayer.Layer */ol){
-			//	summary:
+		_getLayer: function(/*OpenLayer.Layer */ol){
+			// summary:
 			//		Retrieve the dojox.geo.openlayer.Layer from the OpenLayer.Layer
-			//	tags:
+			// tags:
 			//		private
 			var i = array.indexOf(this._layerDictionary.olLayers, ol);
-			if (i != -1)
+			if(i != -1){
 				return this._layerDictionary.layers[i];
+			}
 			return null;
 		},
 
-		getLayer : function(property, value){
-			//	summary: 
+		getLayer: function(property, value){
+			// summary:
 			//		Returns the layer whose property matches the value.
-			//	property: String
+			// property: String
 			//		The property to check
-			//	value: Object
+			// value: Object
 			//		The value to match
-			//	returns: dojox.geo.openlayer.Layer | Array
+			// returns:
 			//		The layer(s) matching the property's value. Since multiple layers
 			//		match the property's value the return value is an array. 
-			//	example: 
+			// example:
 			//		var layers = map.getLayer("name", "Layer Name");
 			var om = this.olMap;
 			var ols = om.getBy("layers", property, value);
@@ -443,61 +416,63 @@ define(["dojo/_base/kernel",
 			array.forEach(ols, function(ol){
 				ret.push(this._getLayer(ol));
 			}, this);
-			return ret;
+			return ret; // Layer[]
 		},
 
-		getLayerCount : function(){
-			//	summary: 
+		getLayerCount: function(){
+			// summary:
 			//		Returns the count of layers of this map.
-			//	returns: int 
+			// returns:
 			//		The number of layers of this map. 
 			var om = this.olMap;
-			if (om.layers == null)
+			if(om.layers == null){
 				return 0;
-			return om.layers.length;
+			}
+			return om.layers.length; // Number
 		},
 
-		fitTo : function(o){
-			//	summary: 
+		fitTo: function(o){
+			// summary:
 			//		Fits the map on a point,or an area
-			//	description: 
+			// description:
 			//		Fits the map on the point or extent specified as parameter. 
-			//	o: Object
+			// o: Object
 			//		Object with key values fit parameters or a JSON string.
-			//	example:
-			//		Examples of arguments passed to the fitTo function :
+			// example:
+			//		Examples of arguments passed to the fitTo function:
 			//	|	null
 			//		The map is fit on full extent
 			//
 			//	|	{
-			//	|	bounds : [ulx, uly, lrx, lry]
+			//	|		bounds: [ulx, uly, lrx, lry]
 			//	|	}
 			//		The map is fit on the specified bounds expressed as decimal degrees latitude and longitude.
 			//		The bounds are defined with their upper left and lower right corners coordinates.
 			// 
 			//	|	{
-			//	|	position : [longitude, latitude],
-			//	|	extent : degrees
+			//	|		position: [longitude, latitude],
+			//	|		extent: degrees
 			//	|	}
-			//		The map is fit on the specified position showing the extent <extent> around
+			//		The map is fit on the specified position showing the extent `<extent>` around
 			//		the specified center position.
 
 			var map = this.olMap;
-			var from = dojox.geo.openlayers.EPSG4326;
+			var from = openlayers.EPSG4326;
 
-			if (o == null) {
+			if(o == null){
 				var c = this.transformXY(0, 0, from);
 				map.setCenter(new OpenLayers.LonLat(c.x, c.y));
 				return;
 			}
 			var b = null;
-			if (typeof o == "string")
+			if(typeof o == "string"){
 				var j = json.fromJson(o);
-			else
+			}else{
 				j = o;
+			}
 			var ul;
 			var lr;
-			if (j.hasOwnProperty("bounds")) {
+			if(j.hasOwnProperty("bounds")){
 				var a = j.bounds;
 				b = new OpenLayers.Bounds();
 				ul = this.transformXY(a[0], a[1], from);
@@ -507,12 +482,13 @@ define(["dojo/_base/kernel",
 				b.right = lr.x;
 				b.bottom = lr.y;
 			}
-			if (b == null) {
-				if (j.hasOwnProperty("position")) {
+			if(b == null){
+				if(j.hasOwnProperty("position")){
 					var p = j.position;
 					var e = j.hasOwnProperty("extent") ? j.extent : 1;
-					if (typeof e == "string")
+					if(typeof e == "string"){
 						e = parseFloat(e);
+					}
 					b = new OpenLayers.Bounds();
 					ul = this.transformXY(p[0] - e, p[1] + e, from);
 					b.left = ul.x;
@@ -522,17 +498,17 @@ define(["dojo/_base/kernel",
 					b.bottom = lr.y;
 				}
 			}
-			if (b == null) {
-				if (o.length == 4) {
+			if(b == null){
+				if(o.length == 4){
 					b = new OpenLayers.Bounds();
 					// TODO Choose the correct method
-					if (false) {
+					if(false){
 						b.left = o[0];
 						b.top = o[1];
 
 						b.right = o[2];
 						b.bottom = o[3];
-					} else {
+					}else{
 						ul = this.transformXY(o[0], o[1], from);
 						b.left = ul.x;
 						b.top = ul.y;
@@ -542,48 +518,54 @@ define(["dojo/_base/kernel",
 					}
 				}
 			}
-			if (b != null) {
+			if(b != null){
 				map.zoomToExtent(b, true);
 			}
 		},
 
-		transform : function(p, from, to){
-			//	summary:
+		transform: function(p, from, to){
+			// summary:
 			//		Transforms the point passed as argument, expressed in the <em>from</em> 
 			//		coordinate system to the map coordinate system.
-			//	description:
+			// description:
 			//		Transforms the point passed as argument without modifying it. The point is supposed to be expressed
 			//		in the <em>from</em> coordinate system and is transformed to the map coordinate system.
-			//	p : Object {x, y}
+			// p: Object {x, y}
 			//		The point to transform
-			//	from: OpenLayers.Projection
+			// from: OpenLayers.Projection
 			//		The projection in which the point is expressed.
 			return this.transformXY(p.x, p.y, from, to);
 		},
 
-		transformXY : function(x, y, from, to){
-			//	summary
+		transformXY: function(x, y, from, to){
+			// summary:
 			//		Transforms the coordinates passed as argument, expressed in the <em>from</em> 
 			//		coordinate system to the map coordinate system.
-			//	description:
+			// description:
 			//		Transforms the coordinates passed as argument. The coordinate are supposed to be expressed
 			//		in the <em>from</em> coordinate system and are transformed to the map coordinate system.
-			//	x : Number 
+			// x: Number
 			//		The longitude coordinate to transform.
-			//	y : Number
+			// y: Number
 			//		The latitude coordinate to transform.
-			//	from: OpenLayers.Projection
-			//		The projection in which the point is expressed.
+			// from: OpenLayers.Projection?
+			//		The projection in which the point is expressed, or EPSG4326 is not specified.
+			// to: OpenLayers.Projection?
+			//		The projection in which the point is converted to. In not specifed, the map projection is used.
+			// returns:
+			//		The transformed coordinate as an {x,y} Object.
 
 			var tp = this._tp;
 			tp.x = x;
 			tp.y = y;
-			if (!from)
-				from = dojox.geo.openlayers.EPSG4326;
-			if (!to)
+			if(!from){
+				from = openlayers.EPSG4326;
+			}
+			if(!to){
 				to = this.olMap.getProjectionObject();
+			}
 			tp = OpenLayers.Projection.transform(tp, from, to);
-			return tp;
+			return tp; // Object
 		}
 
 	});
diff --git a/dojox/geo/openlayers/Patch.js b/dojox/geo/openlayers/Patch.js
index 5ce22e7..d21349a 100644
--- a/dojox/geo/openlayers/Patch.js
+++ b/dojox/geo/openlayers/Patch.js
@@ -10,55 +10,62 @@ define([
 
 	dgo.Patch = {
 
-		patchMethod : function(/*Object*/type, /*String*/method, /*Function*/execBefore, /*Function*/
+		patchMethod: function(/*Object*/type, /*String*/method, /*Function*/execBefore, /*Function*/
 		execAfter){
-			//	summary:
+			// summary:
 			//		Patches the specified method of the given type so that the 'execBefore' (resp. 'execAfter') function is 
 			//		called before (resp. after) invoking the legacy implementation.
-			//	description:
+			// description:
 			//		The execBefore function is invoked with the following parameter:
 			//		execBefore(method, arguments) where 'method' is the patched method name and 'arguments' the arguments received
 			//		by the legacy implementation.
 			//		The execAfter function is invoked with the following parameter:
 			//		execBefore(method, returnValue, arguments) where 'method' is the patched method name, 'returnValue' the value
 			//		returned by the legacy implementation and 'arguments' the arguments received by the legacy implementation.
-			//	type: Object: the type to patch.
-			//	method: String: the method name.
-			//	execBefore: Function: the function to execute before the legacy implementation. 
-			//	execAfter: Function: the function to execute after the legacy implementation.
-			//	tags:
+			// type: Object
+			//		the type to patch.
+			// method: String
+			//		the method name.
+			// execBefore: Function
+			//		the function to execute before the legacy implementation.
+			// execAfter: Function
+			//		the function to execute after the legacy implementation.
+			// tags:
 			//		private
 			var old = type.prototype[method];
 			type.prototype[method] = function(){
 				var callee = method;
-				if (execBefore)
+				if(execBefore){
 					execBefore.call(this, callee, arguments);
+				}
 				var ret = old.apply(this, arguments);
-				if (execAfter)
+				if(execAfter){
 					ret = execAfter.call(this, callee, ret, arguments) || ret;
+				}
 				return ret;
 			};
 		},
 
-		patchGFX : function(){
+		patchGFX: function(){
 
 			var vmlFixRawNodePath = function(){
-				if (!this.rawNode.path)
+				if(!this.rawNode.path){
 					this.rawNode.path = {};
+				}
 			};
 
-			var vmlFixFillColors = function() {
-				if(this.rawNode.fill && !this.rawNode.fill.colors)
+			var vmlFixFillColors = function(){
+				if(this.rawNode.fill && !this.rawNode.fill.colors){
 					this.rawNode.fill.colors = {};
+				}
 			};
 			
-			if (sniff.isIE <= 8) {
+			if(sniff.isIE <= 8 && gfx.renderer === "vml"){
+				this.patchMethod(gfx.Line, "setShape", vmlFixRawNodePath, null);
+				this.patchMethod(gfx.Polyline, "setShape", vmlFixRawNodePath, null);
+				this.patchMethod(gfx.Path, "setShape", vmlFixRawNodePath, null);
 				
-				dojox.geo.openlayers.Patch.patchMethod(gfx.Line, "setShape", vmlFixRawNodePath, null);
-				dojox.geo.openlayers.Patch.patchMethod(gfx.Polyline, "setShape", vmlFixRawNodePath, null);
-				dojox.geo.openlayers.Patch.patchMethod(gfx.Path, "setShape", vmlFixRawNodePath, null);
-				
-				dojox.geo.openlayers.Patch.patchMethod(shape.Shape, "setFill", vmlFixFillColors, null);
+				this.patchMethod(shape.Shape, "setFill", vmlFixFillColors, null);
 			}
 		}
 	};
diff --git a/dojox/geo/openlayers/Point.js b/dojox/geo/openlayers/Point.js
index 4e4652f..edd9abf 100644
--- a/dojox/geo/openlayers/Point.js
+++ b/dojox/geo/openlayers/Point.js
@@ -1,26 +1,26 @@
-define(["dojo/_base/kernel", "dojo/_base/declare", "dojox/geo/openlayers/Geometry"],
-	function(dojo, declare, Geometry){
-	/*===== 
-	var Geometry = dojox.geo.openlayers.Geometry; 
-	=====*/
+define([
+	"dojo/_base/declare",
+	"./Geometry"
+], function(declare, Geometry){
+
 	return declare("dojox.geo.openlayers.Point", Geometry, {
-		//	summary:
+		// summary:
 		//		A Point geometry handles description of points to be rendered in a GfxLayer
 
-		setPoint : function(p){
-			//	summary:
+		setPoint: function(p){
+			// summary:
 			//		Sets the point for this geometry.
-			//	p : {x, y} Object
-			//		The point geometry.
+			// p: Object
+			//		The point geometry expressed as a {x, y} object.
 			this.coordinates = p;
 		},
 
-		getPoint : function(){
-			//	summary:
+		getPoint: function(){
+			// summary:
 			//		Gets the point defining this geometry.
-			//	returns: {x, y} Object
+			// returns:
 			//		The point defining this geometry.
-			return this.coordinates;
+			return this.coordinates; // Object
 		}
 	});
 });
diff --git a/dojox/geo/openlayers/TouchInteractionSupport.js b/dojox/geo/openlayers/TouchInteractionSupport.js
index f973612..d4e0550 100644
--- a/dojox/geo/openlayers/TouchInteractionSupport.js
+++ b/dojox/geo/openlayers/TouchInteractionSupport.js
@@ -1,31 +1,32 @@
-define(["dojo/_base/kernel",
-				"dojo/_base/declare",
-				"dojo/_base/connect",
-				"dojo/_base/html",
-				"dojo/_base/lang",
-				"dojo/_base/event",
-				"dojo/_base/window"], function(dojo, declare, connect, html, lang, event, window){
+define([
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dojo/_base/html",
+	"dojo/_base/lang",
+	"dojo/_base/event",
+	"dojo/_base/window"
+], function(declare, connect, html, lang, event, win){
 
 	return declare("dojox.geo.openlayers.TouchInteractionSupport", null, {
-		//	summary: 
+		// summary:
 		//		class to handle touch interactions on a OpenLayers.Map widget
-		//	tags:
+		// tags:
 		//		private
 
-		_map : null,
-		_centerTouchLocation : null,
-		_touchMoveListener : null,
-		_touchEndListener : null,
-		_initialFingerSpacing : null,
-		_initialScale : null,
-		_tapCount : null,
-		_tapThreshold : null,
-		_lastTap : null,
-
-		constructor : function(/* OpenLayers.Map */map){
-			//	summary: 
+		_map: null,
+		_centerTouchLocation: null,
+		_touchMoveListener: null,
+		_touchEndListener: null,
+		_initialFingerSpacing: null,
+		_initialScale: null,
+		_tapCount: null,
+		_tapThreshold: null,
+		_lastTap: null,
+
+		constructor: function(map){
+			// summary:
 			//		Constructs a new TouchInteractionSupport instance
-			//	map: OpenLayers.Map
+			// map: OpenLayers.Map
 			//		the Map widget this class provides touch navigation for.
 			this._map = map;
 			this._centerTouchLocation = new OpenLayers.LonLat(0, 0);
@@ -39,28 +40,28 @@ define(["dojo/_base/kernel",
 
 			this._tapCount = 0;
 			this._lastTap = {
-				x : 0,
-				y : 0
+				x: 0,
+				y: 0
 			};
 			this._tapThreshold = 100; // square distance in pixels
 
 		},
 
-		_getTouchBarycenter : function(touchEvent){
-			//	summary: 
+		_getTouchBarycenter: function(touchEvent){
+			// summary:
 			//		returns the midpoint of the two first fingers (or the first finger location if only one)
-			//	touchEvent: Event
+			// touchEvent: TouchEvent
 			//		a touch event
-			//	returns: dojox.gfx.Point
-			//		the midpoint
-			//	tags:
+			// returns:
+			//		the midpoint as an {x,y} object.
+			// tags:
 			//		private
 			var touches = touchEvent.touches;
 			var firstTouch = touches[0];
 			var secondTouch = null;
-			if (touches.length > 1) {
+			if(touches.length > 1){
 				secondTouch = touches[1];
-			} else {
+			}else{
 				secondTouch = touches[0];
 			}
 
@@ -70,24 +71,24 @@ define(["dojo/_base/kernel",
 			var middleY = (firstTouch.pageY + secondTouch.pageY) / 2.0 - marginBox.t;
 
 			return {
-				x : middleX,
-				y : middleY
-			};
+				x: middleX,
+				y: middleY
+			}; // Object
 
 		},
 
-		_getFingerSpacing : function(touchEvent){
-			//	summary: 
+		_getFingerSpacing: function(touchEvent){
+			// summary:
 			//		computes the distance between the first two fingers
-			//	touchEvent: Event
+			// touchEvent: Event
 			//		a touch event
-			//	returns: float
+			// returns: float
 			//		a distance. -1 if less that 2 fingers
-			//	tags:
+			// tags:
 			//		private
 			var touches = touchEvent.touches;
 			var spacing = -1;
-			if (touches.length >= 2) {
+			if(touches.length >= 2){
 				var dx = (touches[1].pageX - touches[0].pageX);
 				var dy = (touches[1].pageY - touches[0].pageY);
 				spacing = Math.sqrt(dx * dx + dy * dy);
@@ -95,26 +96,26 @@ define(["dojo/_base/kernel",
 			return spacing;
 		},
 
-		_isDoubleTap : function(touchEvent){
-			//	summary: 
+		_isDoubleTap: function(touchEvent){
+			// summary:
 			//		checks whether the specified touchStart event is a double tap 
 			//		(i.e. follows closely a previous touchStart at approximately the same location)
-			//	touchEvent: Event
+			// touchEvent: TouchEvent
 			//		a touch event
-			//	returns: boolean
+			// returns: boolean
 			//		true if this event is considered a double tap
-			//	tags:
+			// tags:
 			//		private
 			var isDoubleTap = false;
 			var touches = touchEvent.touches;
-			if ((this._tapCount > 0) && touches.length == 1) {
+			if((this._tapCount > 0) && touches.length == 1){
 				// test distance from last tap
 				var dx = (touches[0].pageX - this._lastTap.x);
 				var dy = (touches[0].pageY - this._lastTap.y);
 				var distance = dx * dx + dy * dy;
-				if (distance < this._tapThreshold) {
+				if(distance < this._tapThreshold){
 					isDoubleTap = true;
-				} else {
+				}else{
 					this._tapCount = 0;
 				}
 			}
@@ -128,13 +129,14 @@ define(["dojo/_base/kernel",
 			return isDoubleTap;
 		},
 
-		_doubleTapHandler : function(touchEvent){
-			//	summary: 
+		_doubleTapHandler: function(touchEvent){
+			// summary:
 			//		action performed on the map when a double tap was triggered 
-			//	touchEvent: Event 
+			// touchEvent: TouchEvent
 			//		a touch event
-			//	tags:
+			// tags:
 			//		private
+
 			// perform a basic 2x zoom on touch
 			var touches = touchEvent.touches;
 			var marginBox = html.marginBox(this._map.div);
@@ -146,17 +148,17 @@ define(["dojo/_base/kernel",
 			this._map.setCenter(new OpenLayers.LonLat(mapPoint.lon, mapPoint.lat), this._map.getZoom() + 1);
 		},
 
-		_touchStartHandler : function(touchEvent){
-			//	summary: 
+		_touchStartHandler: function(touchEvent){
+			// summary:
 			//		action performed on the map when a touch start was triggered 
-			//	touchEvent: Event 
-			// 		a touch event
-			//	tags:
+			// touchEvent: Event
+			//		a touch event
+			// tags:
 			//		private
 			event.stop(touchEvent);
 
 			// test double tap
-			if (this._isDoubleTap(touchEvent)) {
+			if(this._isDoubleTap(touchEvent)){
 				this._doubleTapHandler(touchEvent);
 				return;
 			}
@@ -173,35 +175,36 @@ define(["dojo/_base/kernel",
 			this._initialScale = this._map.getScale();
 
 			// install touch move and up listeners (if not done by other fingers before)
-			if (!this._touchMoveListener)
-				this._touchMoveListener = connect.connect(window.global, "touchmove", this, this._touchMoveHandler);
-			if (!this._touchEndListener)
-				this._touchEndListener = connect.connect(window.global, "touchend", this, this._touchEndHandler);
-
+			if(!this._touchMoveListener){
+				this._touchMoveListener = connect.connect(win.global, "touchmove", this, this._touchMoveHandler);
+			}
+			if(!this._touchEndListener){
+				this._touchEndListener = connect.connect(win.global, "touchend", this, this._touchEndHandler);
+			}
 		},
 
-		_touchEndHandler : function(touchEvent){
-			//	summary: 
+		_touchEndHandler: function(touchEvent){
+			// summary:
 			//		action performed on the map when a touch end was triggered 
-			//	touchEvent: Event 
+			// touchEvent: Event
 			//		a touch event
-			//	tags:
+			// tags:
 			//		private
 			event.stop(touchEvent);
 
 			var touches = touchEvent.touches;
 
-			if (touches.length == 0) {
+			if(touches.length == 0){
 				// disconnect listeners only when all fingers are up
-				if (this._touchMoveListener) {
+				if(this._touchMoveListener){
 					connect.disconnect(this._touchMoveListener);
 					this._touchMoveListener = null;
 				}
-				if (this._touchEndListener) {
+				if(this._touchEndListener){
 					connect.disconnect(this._touchEndListener);
 					this._touchEndListener = null;
 				}
-			} else {
+			}else{
 				// recompute touch center
 				var middlePoint = this._getTouchBarycenter(touchEvent);
 
@@ -209,12 +212,12 @@ define(["dojo/_base/kernel",
 			}
 		},
 
-		_touchMoveHandler : function(touchEvent){
-			//	summary: 
+		_touchMoveHandler: function(touchEvent){
+			// summary:
 			//		action performed on the map when a touch move was triggered 
-			//	touchEvent: Event
+			// touchEvent: Event
 			//		a touch event
-			//	tags:
+			// tags:
 			//		private
 
 			// prevent browser interaction
@@ -230,10 +233,10 @@ define(["dojo/_base/kernel",
 			// compute scale factor
 			var scaleFactor = 1;
 			var touches = touchEvent.touches;
-			if (touches.length >= 2) {
+			if(touches.length >= 2){
 				var fingerSpacing = this._getFingerSpacing(touchEvent);
 				scaleFactor = fingerSpacing / this._initialFingerSpacing;
-				// weird openlayer bug : setting several times the same scale value lead to visual zoom...
+				// weird openlayer bug: setting several times the same scale value lead to visual zoom...
 				this._map.zoomToScale(this._initialScale / scaleFactor);
 			}
 
diff --git a/dojox/geo/openlayers/WidgetFeature.js b/dojox/geo/openlayers/WidgetFeature.js
index 18ade13..285cc0b 100644
--- a/dojox/geo/openlayers/WidgetFeature.js
+++ b/dojox/geo/openlayers/WidgetFeature.js
@@ -1,130 +1,151 @@
-define(
-	["dojo/_base/kernel", "dojo/_base/declare", "dojo/_base/html", "dojo/_base/lang", "dojox/geo/openlayers/Feature"],
-	function(dojo, declare, html, lang, Feature){
-		/*===== 
-		var Feature = dojox.geo.openlayers.Feature; 
-		=====*/
+define([
+	"dojo/_base/declare",
+	"dojo/dom-style",
+	"dojo/_base/lang",
+	"dijit/registry",
+	"./Feature"
+], function(declare, style, lang, registry, Feature){
+	/*=====
+	dojox.geo.openlayers.__WidgetFeatureArgs = {
+		// summary:
+		//		The keyword arguments that can be passed in a WidgetFeature constructor.
+		//		You must define a least one widget retrieval parameter and the geo-localization parameters.
+		// createWidget: Function?
+		//		Function for widget creation. Must return a `dijit._Widget.
+		// dojoType: String?
+		//		The class of a widget to create.
+		// dijitId: String?
+		//		The digitId of an existing widget.
+		// widget: dijit._Widget?
+		//		An already created widget.
+		// width: Number?
+		//		The width of the widget.
+		// height: Number?
+		//		The height of the widget.
+		// longitude: Number
+		//		The longitude, in decimal degrees where to place the widget.
+		// latitude: Number
+		//		The latitude, in decimal degrees where to place the widget.
+	};
+	=====*/
+
 		return declare("dojox.geo.openlayers.WidgetFeature", Feature, {
-			//	summary:
+			// summary:
 			//		Wraps a Dojo widget, provide geolocalisation of the widget and interface
 			//		to Layer class.
-			//	description:
+			// description:
 			//		This class allows to add a widget in a `dojox.geo.openlayers.Layer`.
-			//		Parameters are passed to the constructor. These parameters describe the widget
-			//		and provide geo-localisation of this widget.
-			//		parameters can be: 
-			//	* _createWidget_: Function for widget creation. Must return a `dijit._Widget`.
-			//	* _dojoType_: The class of a widget to create;
-			//	* _dijitId_: The digitId of an existing widget.
-			//	* _widget_: An already created widget.
-			//	* _width_: The width of the widget.
-			//	* _height_: The height of the widget.
-			//	* _longitude_: The longitude, in decimal degrees where to place the widget.
-			//	* _latitude_: The latitude, in decimal degrees where to place the widget.
-			//	You must define a least one widget retrieval parameter and the geo-localization parameters.
-			_widget : null,
-			_bbox : null,
-
-			constructor : function(params){
-				//	summary:
+
+			_widget: null,
+			_bbox: null,
+
+			constructor: function(params){
+				// summary:
 				//		Constructs a new `dojox.geo.openlayers.WidgetFeature`
-				//	params: Object
+				// params: dojox.geo.openlayers.__WidgetFeatureArgs
 				//		The parameters describing the widget.
 				this._params = params;
 			},
 
-			setParameters : function(params){
-				//	summary:
+			setParameters: function(params){
+				// summary:
 				//		Sets the parameters describing the widget.
-				//	params: Object
+				// params: dojox.geo.openlayers.__WidgetFeatureArgs
 				//		The parameters describing the widget.
 				this._params = params;
 			},
 
-			getParameters : function(){
-				//	summary:
-				//		Retreives the parameters describing the widget.
-				//	returns: Object
+			getParameters: function(){
+				// summary:
+				//		Returns the parameters describing the widget.
+				// returns: dojox.geo.openlayers.__WidgetFeatureArgs
 				//		The parameters describing the widget.
 				return this._params;
 			},
 
-			_getWidget : function(){
-				//	summary:
-				//		Creates, if necessary the widget and returns it;
-				//	tags:
+			_getWidget: function(){
+				// summary:
+				//		Creates, if necessary the widget and returns it
+				// tags:
 				//		private
 				var params = this._params;
 
-				if ((this._widget == null) && (params != null)) {
+				if((this._widget == null) && (params != null)){
 					var w = null;
 
-					if (typeof (params.createWidget) == "function") {
+					if(typeof (params.createWidget) == "function"){
 						w = params.createWidget.call(this);
-					} else if (params.dojoType) {
+					}else if(params.dojoType){
 						dojo["require"](params.dojoType);
 						var c = lang.getObject(params.dojoType);
 						w = new c(params);
-					} else if (params.dijitId) {
-						w = dijit.byId(params.dijitId);
-					} else if (params.widget) {
+					}else if(params.dijitId){
+						w = registry.byId(params.dijitId);
+					}else if(params.widget){
 						w = params.widget;
 					}
 
-					if (w != null) {
+					if(w != null){
 						this._widget = w;
-						if (typeof (w.startup) == "function")
+						if(typeof (w.startup) == "function"){
 							w.startup();
+						}
 						var n = w.domNode;
-						if (n != null)
-							html.style(n, {
-								position : "absolute"
+						if(n != null){
+							style.set(n, {
+								position: "absolute"
 							});
+						}
 					}
 					this._widget = w;
 				}
 				return this._widget;
 			},
 
-			_getWidgetWidth : function(){
-				//	summary:
+			_getWidgetWidth: function(){
+				// summary:
 				//		gets the widget width
-				//	tags:
+				// tags:
 				//		private
 				var p = this._params;
-				if (p.width)
+				if(p.width){
 					return p.width;
+				}
 				var w = this._getWidget();
-				if (w)
-					return html.style(w.domNode, "width");
+				if(w){
+					return style.get(w.domNode, "width");
+				}
 				return 10;
 			},
 
-			_getWidgetHeight : function(){
-				//	summary:
+			_getWidgetHeight: function(){
+				// summary:
 				//		gets the widget height
-				//	tags:
+				// tags:
 				//		private
 				var p = this._params;
-				if (p.height)
+				if(p.height){
 					return p.height;
+				}
 				var w = this._getWidget();
-				if (w)
-					return html.style(w.domNode, "height");
+				if(w){
+					return style.get(w.domNode, "height");
+				}
 				return 10;
 			},
 
-			render : function(){
-				//	summary:
+			render: function(){
+				// summary:
 				//		renders the widget.
-				//	descrption:
+				// description:
 				//		Places the widget accordingly to longitude and latitude defined in parameters.
 				//		This function is called when the center of the maps or zoom factor changes.
 				var layer = this.getLayer();
 
 				var widget = this._getWidget();
-				if (widget == null)
+				if(widget == null){
 					return;
+				}
 				var params = this._params;
 				var lon = params.longitude;
 				var lat = params.latitude;
@@ -141,65 +162,70 @@ define(
 				var dom = widget.domNode;
 
 				var pa = layer.olLayer.div;
-				if (dom.parentNode != pa) {
-					if (dom.parentNode)
+				if(dom.parentNode != pa){
+					if(dom.parentNode){
 						dom.parentNode.removeChild(dom);
+					}
 					pa.appendChild(dom);
 				}
 				this._updateWidgetPosition({
-					x : x,
-					y : y,
-					width : width,
-					height : height
+					x: x,
+					y: y,
+					width: width,
+					height: height
 				});
 			},
 
-			_updateWidgetPosition : function(box){
-				//	summary:
+			_updateWidgetPosition: function(box){
+				// summary:
 				//		Places the widget with the computed x and y values
-				//	tags:
+				// tags:
 				//		private
-				//	var box = this._params;
+				
+				// var box = this._params;
 
 				var w = this._widget;
 				var dom = w.domNode;
 
-				html.style(dom, {
-					position : "absolute",
-					left : box.x + "px",
-					top : box.y + "px",
-					width : box.width + "px",
-					height : box.height + "px"
+				style.set(dom, {
+					position: "absolute",
+					left: box.x + "px",
+					top: box.y + "px",
+					width: box.width + "px",
+					height: box.height + "px"
 				});
 
-				if (w.srcNodeRef) {
-					html.style(w.srcNodeRef, {
-						position : "absolute",
-						left : box.x + "px",
-						top : box.y + "px",
-						width : box.width + "px",
-						height : box.height + "px"
+				if(w.srcNodeRef){
+					style.set(w.srcNodeRef, {
+						position: "absolute",
+						left: box.x + "px",
+						top: box.y + "px",
+						width: box.width + "px",
+						height: box.height + "px"
 					});
 				}
 
-				if (lang.isFunction(w.resize))
+				if(lang.isFunction(w.resize)){
 					w.resize({
-						w : box.width,
-						h : box.height
+						w: box.width,
+						h: box.height
 					});
+				}
 			},
 
-			remove : function(){
-				//	summary:
+			remove: function(){
+				// summary:
 				//		removes this feature.
-				//	description:
+				// description:
 				//		Remove this feature by disconnecting the widget from the dom.
-				var w = this.getWidget();
-				if (!w)
+				var w = this._getWidget();
+				if(!w){
 					return;
+				}
 				var dom = w.domNode;
-				if (dom.parentNode)
+				if(dom.parentNode){
 					dom.parentNode.removeChild(dom);
+				}
 			}
 		});
 	});
diff --git a/dojox/geo/openlayers/_base.js b/dojox/geo/openlayers/_base.js
new file mode 100644
index 0000000..4554e58
--- /dev/null
+++ b/dojox/geo/openlayers/_base.js
@@ -0,0 +1,79 @@
+define(["dojo/_base/lang"], function(lang){
+	
+	var openlayers = lang.getObject("dojox.geo.openlayers", true);
+	/*===== openlayers = dojox.geo.openlayers; =====*/
+	
+	openlayers.BaseLayerType = {
+		// summary:
+		//		Defines the base layer types to be used at Map construction time or
+		//		with the setBaseLayerType function.
+		// description:
+		//		This object defines the base layer types to be used at Map construction
+		//		time or with the setBaseLayerType function.
+
+		// OSM: String
+		//		The Open Street Map base layer type selector.
+		OSM: "OSM",
+
+		// WMS: String
+		//		The Web Map Server base layer type selector.
+		WMS: "WMS",
+
+		// GOOGLE: String
+		//		The Google base layer type selector.
+		GOOGLE: "Google",
+
+		// VIRTUAL_EARTH: String
+		//		The Virtual Earth base layer type selector.
+		VIRTUAL_EARTH: "VirtualEarth",
+
+		// BING: String
+		//		Same as Virtual Earth
+		BING: "VirtualEarth",
+
+		// YAHOO: String
+		//		The Yahoo base layer type selector.
+		YAHOO: "Yahoo",
+
+		// ARCGIS: String
+		//		The ESRI ARCGis base layer selector.
+		ARCGIS: "ArcGIS"
+	};
+
+	openlayers.EPSG4326 = new OpenLayers.Projection("EPSG:4326");
+
+	var re = /^\s*(\d{1,3})[D°]\s*(\d{1,2})[M']\s*(\d{1,2}\.?\d*)\s*(S|"|'')\s*([NSEWnsew]{0,1})\s*$/i;
+	openlayers.parseDMS = function(v, toDecimal){
+		// summary:
+		//		Parses the specified string and returns degree minute second or decimal degree.
+		// description:
+		//		Parses the specified string and returns degree minute second or decimal degree.
+		// v: String
+		//		The string to parse
+		// toDecimal: Boolean
+		//		Specifies if the result should be returned in decimal degrees or in an array
+		//		containing the degrees, minutes, seconds values.
+		// returns: Float|Array
+		//		the parsed value in decimal degrees or an array containing the degrees, minutes, seconds values.
+
+		var res = re.exec(v);
+		if(res == null || res.length < 5){
+			return parseFloat(v);
+		}
+		var d = parseFloat(res[1]);
+		var m = parseFloat(res[2]);
+		var s = parseFloat(res[3]);
+		var nsew = res[5];
+		if(toDecimal){
+			var lc = nsew.toLowerCase();
+			var dd = d + (m + s / 60.0) / 60.0;
+			if(lc == "w" || lc == "s"){
+				dd = -dd;
+			}
+			return dd;
+		}
+		return [d, m, s, nsew];
+	};
+	
+	return openlayers;
+});
diff --git a/dojox/geo/openlayers/tests/baseLayers/test_baseLayers.html b/dojox/geo/openlayers/tests/baseLayers/test_baseLayers.html
deleted file mode 100644
index 47fe9c7..0000000
--- a/dojox/geo/openlayers/tests/baseLayers/test_baseLayers.html
+++ /dev/null
@@ -1,223 +0,0 @@
-<html>
-<head>
-<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/dijit.css">
-<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css">
-<title>Dojo Base Layers</title>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-
-<!--  Google API -->
-<script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
-
-<!-- Virtual Earth / Bing -->
-<script src='http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.3'></script>
-
-<!-- Yahoo -->
-<script src="http://api.maps.yahoo.com/ajaxymap?v=3.0&appid=euzuro-openlayers"></script>
-
-<script type="text/javascript" src="http://openlayers.org/api/2.10/OpenLayers.js"></script>
-
-<script type="text/javascript">
-	var djConfig = {
-		parseOnLoad : true
-	};
-</script>
-
-<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
-
-<script type="text/javascript">
-	require([	"dojo/_base/kernel",
-						"dojo/_base/html",
-						"dojo/dom",
-						"dojox/geo/openlayers/Map",
-						"dijit/Menu",
-						"dijit/MenuItem",
-						"dijit/PopupMenuItem",
-						"dojo/parser"], function(dojo, html, dom, Map){
-
-		dojo.ready(function(){
-			var options = {
-				baseLayerName : "TheMap",
-				baseLayerType : dojox.geo.openlayers.BaseLayerType.GOOGLE,
-				touchHandler : true,
-				accessible : true
-			};
-
-			var menu = dom.byId("menu");
-
-			html.style(menu, "visibility", "visible");
-
-			map = new Map("map", options);
-
-			map.fitTo([-160, 70, 160, -70]);
-
-			updateTF(options);
-		})
-
-	});
-
-	var map;
-
-	function setBaseLayer(o){
-		map.setBaseLayerType(o);
-		updateTF(o);
-	}
-
-	function updateTF(o){
-		var ta = dojo.byId("textArea");
-		ta.innerHTML = "Params: " + dojo.toJson(o).replace(/[,]/g, ' ');
-		var bl = map.getOLMap().baseLayer;
-		if (bl && bl.getURL) {
-			var msg = bl.getURL(new OpenLayers.Bounds());
-		}
-
-	}
-</script>
-
-<style type="text/css">
-.olLayerGoogleCopyright {
-	visibility: hidden;
-}
-</style>
-
-</head>
-
-<body class="tundra" >
-
-	<table height="100%" width="100%">
-		<tr>
-			<td height="50" width="100%">
-				<table>
-					<tr>
-						<td>
-							<div id="menu" style="visibility: hidden;">
-								<div dojoType="dijit.Menu">
-									<div dojoType="dijit.PopupMenuItem">
-										<span> Base Layer </span>
-										<div dojoType="dijit.Menu">
-
-											<div dojoType="dijit.MenuItem"
-												onClick="setBaseLayer({
- baseLayerName : 'OpenStreetMap',
- baseLayerType : dojox.geo.openlayers.BaseLayerType.OSM
- })">Open
-												Street Map</div>
-
-											<div dojoType="dijit.PopupMenuItem">
-												<span> Google </span>
-												<div dojoType="dijit.Menu">
-
-													<div dojoType="dijit.MenuItem"
-														onClick="setBaseLayer({
- baseLayerName : 'Google',
- baseLayerType : dojox.geo.openlayers.BaseLayerType.GOOGLE
- })">Google</div>
-
-													<div dojoType="dijit.MenuItem"
-														onClick="setBaseLayer({ 
- baseLayerName : 'GoogleTerrain', 
- baseLayerType : dojox.geo.openlayers.BaseLayerType.GOOGLE, 
- baseLayerOptions : { 
-    type: google.maps.MapTypeId.TERRAIN, 
-    numZoomLevels: 20
- }})">Google
-														Terrain</div>
-
-													<div dojoType="dijit.MenuItem"
-														onClick="setBaseLayer({ 
- baseLayerName : 'GoogleHybrid', 
- baseLayerType : dojox.geo.openlayers.BaseLayerType.GOOGLE, 
- baseLayerOptions : {
-   type: google.maps.MapTypeId.HYBRID, 
-   numZoomLevels: 20
- }})">Google
-														Hybrid</div>
-
-													<div dojoType="dijit.MenuItem"
-														onClick="setBaseLayer({ 
- baseLayerName : 'GoogleSatellite', 
- baseLayerType : dojox.geo.openlayers.BaseLayerType.GOOGLE, 
- baseLayerOptions : {
-    type: google.maps.MapTypeId.SATELLITE, 
-    numZoomLevels: 20}})">Google
-														Satellite</div>
-												</div>
-											</div>
-											<div dojoType="dijit.PopupMenuItem">
-												<span> WMS </span>
-												<div dojoType="dijit.Menu">
-													<div dojoType="dijit.MenuItem"
-														onClick="setBaseLayer({
- baseLayerName : 'WebMapService',
- baseLayerType : dojox.geo.openlayers.BaseLayerType.WMS})">labs.metacarta.com
-													</div>
-												</div>
-											</div>
-											<div dojoType="dijit.MenuItem"
-												onClick="setBaseLayer({
-  baseLayerName : 'VirtualEarth',
-  baseLayerType : dojox.geo.openlayers.BaseLayerType.VIRTUAL_EARTH})">Virtual
-												Earth BING</div>
-											<div dojoType="dijit.MenuItem"
-												onClick="setBaseLayer({
-  baseLayerName : 'Yahoo',
-  baseLayerType : dojox.geo.openlayers.BaseLayerType.YAHOO})">Yahoo
-											</div>
-											<div dojoType="dijit.PopupMenuItem">
-												<span> ArcGIS </span>
-												<div dojoType="dijit.Menu">
-													<div dojoType="dijit.MenuItem"
-														onClick="setBaseLayer({
- baseLayerName : 'ArcGisStreetMap',
- baseLayerType : dojox.geo.openlayers.BaseLayerType.ARCGIS})">Street
-														Map</div>
-													<div dojoType="dijit.MenuItem"
-														onClick="setBaseLayer({
- baseLayerName : 'ArcGisWorldShadedRelief',
- baseLayerType : dojox.geo.openlayers.BaseLayerType.ARCGIS,
- baseLayerUrl : 'http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_ShadedRelief_World_2D/MapServer/export'
- })">World
-														Shaded Relief</div>
-													<div dojoType="dijit.MenuItem"
-														onClick="setBaseLayer({
- baseLayerName : 'ESRIImageryWorld2D',
- baseLayerType : dojox.geo.openlayers.BaseLayerType.ARCGIS,
- baseLayerUrl : 'http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer/export'
- })">ESRI
-														Imagery World 2D</div>
-													<div dojoType="dijit.MenuItem"
-														onClick="setBaseLayer({
- baseLayerName : 'ArcGisNGSTopoUS2D',
- baseLayerType : dojox.geo.openlayers.BaseLayerType.ARCGIS,
- baseLayerUrl : 'http://server.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer/export'
- })">NGS
-														Topo US 2D</div>
-													<div dojoType="dijit.MenuItem"
-														onClick="setBaseLayer({
- baseLayerName : 'ArcGisWorldPhysicalMap',
- baseLayerType : dojox.geo.openlayers.BaseLayerType.ARCGIS,
- baseLayerUrl : 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Physical_Map/MapServer/export'
- })">World
-														Physical Map</div>
-													<div dojoType="dijit.MenuItem"
-														onClick="setBaseLayer(dojox.geo.openlayers.BaseLayerType.ARCGIS)">Arc GIS no
-														args</div>
-												</div>
-											</div>
-										</div>
-									</div>
-								</div>
-							</div></td>
-						<td style="width: 100%; height: 100%;"><textarea id="textArea" rows="1" cols="1"
-								style="width: 100%;"></textarea></td>
-					</tr>
-
-				</table>
-			</td>
-		</tr>
-		<tr>
-			<td>
-				<div id="map" style="background-color: #b5d0d0; width: 100%; height: 100%;"></div>
-			</td>
-		</tr>
-</body>
-</html>
diff --git a/dojox/geo/openlayers/tests/ecr/Ecr.js b/dojox/geo/openlayers/tests/ecr/Ecr.js
deleted file mode 100644
index 0efb102..0000000
--- a/dojox/geo/openlayers/tests/ecr/Ecr.js
+++ /dev/null
@@ -1,209 +0,0 @@
-define(["dojo/_base/kernel",
-				"dojo/_base/declare",
-				"dojo/_base/html",
-				"dojo/_base/array",
-				"dojo/_base/lang",
-				"dojo/dom",
-				"dojox/geo/openlayers/Map",
-				"dojox/geo/openlayers/GfxLayer",
-				"dojo/data/ItemFileReadStore",
-				"dojox/geo/openlayers/tests/ecr/PortRenderer",
-				"dojox/geo/openlayers/tests/ecr/LegsRenderer"], function(dojo, declare, html, arr, lang, dom, Map, GfxLayer,
-																																	ItemFileReadStore, PortRenderer, LegsRenderer){
-
-	return declare("dojox.geo.openlayers.tests.ecr.Ecr", null, {
-		constructor : function(){
-
-			var map = new Map("map");
-
-			map.fitTo([-160, 70, 160, -70]);
-
-			this._map = map;
-
-			layer = new GfxLayer("legs");
-			this._legLayer = layer;
-			map.addLayer(layer);
-
-			layer = new GfxLayer("ports");
-			this._portLayer = layer;
-			map.addLayer(layer);
-
-			this.loadData("data/ecr.json");
-		},
-
-		fitTo : function(where){
-			this._map.fitTo(where);
-		},
-
-		clearLayer : function(layer){
-			var fa = layer.getFeatures();
-			layer.removeFeature(fa);
-		},
-
-		clearEcr : function(event){
-			var layer = this._portLayer;
-			this.clearLayer(layer);
-			layer = this._legLayer;
-			this.clearLayer(layer);
-			this.fillPortChooser(null);
-		},
-
-		setDataSet : function(name){
-			var o = dom.byId(name);
-			var ds = o.value;
-
-			var layer = this._portLayer;
-			this.clearLayer(layer);
-
-			layer = this._legLayer;
-			this.clearLayer(layer);
-
-			this.loadData(ds);
-
-		},
-
-		log : function(o){
-			console.log(o);
-		},
-
-		loadError : function(){
-			this.log(arguments[0]);
-		},
-
-		_portStyle : [{
-			type : "circle",
-			depth : "{radius}",
-			radius : function(ctx){
-				var realValue = ctx.store.getValue(this, "offer");
-				var ret = Math.max(1, Math.log(realValue));
-				return 3 * ret;
-			},
-			stroke : {
-				color : "#4c9a06",
-				width : 1
-			}
-		}, {
-			type : "circle",
-			depth : "{radius}",
-			radius : function(ctx){
-				var realValue = ctx.store.getValue(this, "demand");
-				return 3 * Math.max(1, Math.log(realValue));
-			},
-			stroke : {
-				color : "#bb0000",
-				width : 1
-			}
-		}],
-
-		gotPorts : function(items, request){
-			this.log("got ports " + items.length);
-			var store = request.store;
-			var ctx = {
-				store : store
-			};
-			var renderer = new PortRenderer(this._portStyle, ctx);
-			var layer = this._portLayer;
-
-			arr.forEach(items, function(item, index, array){
-				var f = renderer.render(item);
-				if (f != null)
-					layer.addFeature(f);
-			});
-
-			this.fillPortChooser(items);
-
-			this.portChange('portChooser');
-
-			layer.redraw();
-		},
-
-		_legsStyle : {
-			type : "polyline",
-			stroke : {
-				color : [255, 165, 0]
-			}
-		},
-
-		gotLegs : function(items, request){
-			//      this.log("got legs " + items.length);
-			var ctx = {
-				store : request.store
-			};
-			var renderer = new LegsRenderer(this._legsStyle, ctx);
-			renderer.setGeodetic(true);
-			var layer = this._legLayer;
-			arr.forEach(items, function(item, index, array){
-				var f = renderer.render(item);
-				if (f != null)
-					layer.addFeature(f);
-			});
-			layer.redraw();
-		},
-
-		loadData : function(dataSet){
-			//      this.log("load " + dataSet);
-			var store = new ItemFileReadStore({
-				url : dataSet,
-				urlPreventCache : true
-			});
-
-			store.fetch({
-				query : {
-					type : "legs"
-				},
-				onComplete : lang.hitch(this, this.gotLegs),
-				onError : lang.hitch(this, this.loadError),
-				queryOptions : {
-					deep : true
-				}
-			});
-
-			store.fetch({
-				query : {
-					type : "port"
-				},
-				onComplete : lang.hitch(this, this.gotPorts),
-				onError : lang.hitch(this, this.loadError)
-			});
-
-		},
-
-		regionChange : function(event){
-			this.fitTo(event.currentTarget.value);
-		},
-
-		portChange : function(name){
-			var o = dom.byId(name);
-			this.fitTo(o.value);
-		},
-
-		fillPortChooser : function(items){
-			var ps = dom.byId("portChooser");
-			var opts = ps.options;
-			var ws = '{"position" : [0, 0], "extent" : 70}';
-			if (items == null) {
-				opts.length = 1;
-				opts[0] = new Option("World", ws);
-			} else {
-				opts.length = items.length + 1;
-				opts[0] = new Option("World", ws);
-				var s = '{"position" : [%lo, %la], "extent" : 0.2}';
-				for ( var i = 0; i < items.length; i++) {
-					var item = items[i];
-					var lon = parseFloat(item.longitude);
-					var lat = parseFloat(item.latitude);
-					var os = s.replace("%lo", lon).replace("%la", lat);
-					opts[i + 1] = new Option(item.name, os);
-				}
-			}
-		},
-
-		toggleLayerVisibility : function(name){
-			var cb = dom.byId(name);
-			var a = this._map.getLayer('name', name);
-			arr.forEach(a, function(item, index, array){
-				item.olLayer.setVisibility(cb.checked);
-			});
-		}
-	});
-});
diff --git a/dojox/geo/openlayers/tests/ecr/EcrRenderer.js b/dojox/geo/openlayers/tests/ecr/EcrRenderer.js
deleted file mode 100644
index 841cd37..0000000
--- a/dojox/geo/openlayers/tests/ecr/EcrRenderer.js
+++ /dev/null
@@ -1,163 +0,0 @@
-define(	[	"dojo/_base/kernel",
-					"dojo/_base/declare",
-					"dojo/_base/array",
-					"dojo/_base/lang"], function(dojo, declare, arr, lang){
-
-					return declare("dojox.geo.openlayers.tests.ecr.EcrRenderer", null, {
-
-						constructor : function(opts, context){
-							this._options = opts;
-							this._context = context;
-						},
-
-						render : function(item){
-							var o = this._options;
-							return this._render(o, item);
-						},
-
-						_render : function(o, item){
-							if (o instanceof Array) {
-								var features = [];
-								o.sort(function(i1, i2){
-									var d1 = i1.depth;
-									var d2 = i2.depth;
-									if (d1 != undefined && d2 != undefined) {
-										var id1 = parseInt(d1);
-										var id2 = parseInt(d2);
-										if (id1 == id2)
-											return 0;
-										if (id1 < id2)
-											return -1;
-										return 1;
-									}
-									return 0;
-								});
-								arr.forEach(o, function(oi, index, array){
-
-									var co = lang.clone(oi);
-									this._callFunctions(co, item);
-									this._solveReferences(co, item);
-
-									var f = this._render(co, item);
-
-									if (f != null) {
-										f.setStroke(co.stroke);
-										f.setFill(co.fill);
-										features.push(f);
-									}
-								}, this);
-								return features;
-							}
-
-							var co = lang.clone(o);
-							this._callFunctions(co, item);
-							this._solveReferences(co, item);
-							var gf = this._renderItem(co, item);
-							if (gf != null) {
-								gf.setStroke(co.stroke);
-								gf.setFill(co.fill);
-							}
-							return gf;
-						},
-
-						_renderItem : function(o, item){
-							// subclasses should render
-							return null;
-						},
-
-						_callFunctions : function(o, item){
-							for ( var prop in o) {
-								if (o.hasOwnProperty(prop)) {
-									var v = o[prop];
-									if (typeof v == 'function') {
-										o[prop] = v.call(item, this._context);
-									} else if (typeof v == 'object') {
-										this._callFunctions(v, item);
-									}
-								}
-							}
-						},
-
-						getContext : function(){
-							return this._context;
-						},
-
-						getContextValue : function(name){
-							if (this._context)
-								return this._context[name];
-							return undefined;
-						},
-
-						getValue : function(item, property){
-							var s = this.getContextValue('store');
-							if ((s != undefined) && s.isItem(item)) {
-								return s.getValue(item, property);
-							}
-							if (item.hasOwnProperty(property)) {
-								return item[property];
-							}
-							return undefined;
-						},
-
-						_coords : [0, 0],
-
-						getCoordinates : function(item){
-							var lon = this.getValue(item, "longitude");
-							var lat = this.getValue(item, "latitude");
-							var flon = parseFloat(lon);
-							var flat = parseFloat(lat);
-							var a = this._coords;
-							a[0] = flon;
-							a[1] = flat;
-							return a;
-						},
-
-						_findAttributeValue : function(o, a, item){
-							var v = undefined;
-							if (item != null)
-								v = this.getValue(item, a);
-							if (v != undefined)
-								return v;
-							v = o[a];
-							if (v != undefined)
-								return v;
-
-							for ( var i in o) {
-								var ov = o[i];
-								if (typeof (ov) == 'object') {
-									var vv = this._findAttributeValue(ov, a, null);
-									if (vv != undefined)
-										return vv;
-								}
-							}
-							return undefined;
-						},
-
-						_solveReferences : function(o, item){
-							this.__solveReferences(o, o, item);
-						},
-
-						__solveReferences : function(oo, o, item){
-							for ( var a in o) {
-								var v = o[a];
-								if (typeof (v) == 'object') {
-									this.__solveReferences(oo, v, item);
-								}
-								if (typeof (v) == 'string') {
-									var re = /{(.*)}/;
-									if (v.match(re)) {
-										v = v.replace(re, "$1");
-										var r = this._findAttributeValue(oo, v, item);
-										if (r != undefined) {
-											var ps = parseFloat(r);
-											if (isNaN(ps))
-												o[a] = r;
-											else
-												o[a] = ps;
-										}
-									}
-								}
-							}
-						}
-					});
-				});
diff --git a/dojox/geo/openlayers/tests/ecr/LegsRenderer.js b/dojox/geo/openlayers/tests/ecr/LegsRenderer.js
deleted file mode 100644
index aec3224..0000000
--- a/dojox/geo/openlayers/tests/ecr/LegsRenderer.js
+++ /dev/null
@@ -1,66 +0,0 @@
-define(["dojo/_base/kernel",
-				"dojo/_base/declare",
-				"dojo/_base/array",
-				"dojox/geo/openlayers/tests/ecr/EcrRenderer",
-				"dojox/geo/openlayers/GeometryFeature",
-				"dojox/geo/openlayers/LineString",
-				"dojox/geo/openlayers/Point",
-				"dojox/geo/openlayers/GreatCircle"], function(dojo, declare, arr, EcrRenderer, GeometryFeature, LineString,
-																											Point, GreatCircle){
-
-	return declare("dojox.geo.openlayers.tests.ecr.LegsRenderer", [dojox.geo.openlayers.tests.ecr.EcrRenderer], {
-
-		constructor : function(opts, context){
-			this._geodetic = false;
-			this._greatCircle = null;
-		},
-
-		setGeodetic : function(value){
-			this._geodetic = value;
-		},
-
-		getGeodetic : function(){
-			return this._geodetic;
-		},
-
-		_renderItem : function(o, item){
-			var gf = null;
-			if (o.type == "polyline") {
-				var store = this.getContextValue('store');
-				var stops = store.getValues(item, 'stops');
-				var pts = [];
-				var lastCoords = null;
-				arr.forEach(stops, function(it, index, array){
-					if (store.isItem(it)) {
-						var port = this.getValue(it, "port");
-						var coords = this.getCoordinates(port);
-						if (this.getGeodetic()) {
-							if (lastCoords != null) {
-								var current = {
-									x : coords[0],
-									y : coords[1]
-								};
-								var geodetic = dojox.geo.openlayers.GreatCircle.toPointArray(lastCoords, current, 5);
-								pts = pts.concat(geodetic);
-							}
-						} else {
-							var p = new Point({
-								x : coords[0],
-								y : coords[1]
-							});
-							pts.push(p);
-						}
-						lastCoords = {
-							x : coords[0],
-							y : coords[1]
-						};
-					}
-				}, this);
-
-				var g = new LineString(pts);
-				gf = new GeometryFeature(g);
-			}
-			return gf;
-		}
-	});
-});
diff --git a/dojox/geo/openlayers/tests/ecr/PortRenderer.js b/dojox/geo/openlayers/tests/ecr/PortRenderer.js
deleted file mode 100644
index f0a7ccd..0000000
--- a/dojox/geo/openlayers/tests/ecr/PortRenderer.js
+++ /dev/null
@@ -1,27 +0,0 @@
-define(["dojo/_base/kernel",
-				"dojo/_base/declare",
-				"dojox/geo/openlayers/tests/ecr/EcrRenderer",
-				"dojox/geo/openlayers/GeometryFeature",
-				"dojox/geo/openlayers/Point"], function(dojo, declare, EcrRenderer, GeometryFeature, Point){
-
-	return declare("dojox.geo.openlayers.tests.ecr.PortRenderer", [EcrRenderer], {
-
-		constructor : function(opts, context){},
-
-		_renderItem : function(o, item){
-			var gf = null;
-			if (o.type == "circle") {
-				var coords = this.getCoordinates(item);
-				var g = new Point({
-					x : coords[0],
-					y : coords[1]
-				});
-				gf = new GeometryFeature(g);
-				gf.setShapeProperties({
-					r : o.radius
-				});
-			}
-			return gf;
-		}
-	});
-});
diff --git a/dojox/geo/openlayers/tests/ecr/data/ecr.json b/dojox/geo/openlayers/tests/ecr/data/ecr.json
deleted file mode 100644
index 827818b..0000000
--- a/dojox/geo/openlayers/tests/ecr/data/ecr.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
-	"identifier": "name",
-	"label": "name",
-	"items": [{
-		"type": "port",
-		"name": "Kabul",
-		"longitude": "69.1833333",
-		"latitude": "34.5166667",
-		"offer": "15",
-		"demand": "20"
-	},
-	{
-		"type": "port",
-		"name": "Buenos Aires",
-		"longitude": "-58.4088134",
-		"latitude": "-34.5761256",
-		"offer": "30",
-		"demand": "10"
-	},
-	{
-		"type": "legs",
-		"name": "legs1",
-		"stops": [{
-			"name": "port1",
-			"port": {
-				"_reference": "Kabul"
-				},
-
-			"capacity": "12"
-		},
-		{
-			"name": "port2",
-			"port": {
-				"_reference": "Buenos Aires"
-			},
-
-			"capacity": "20"
-		}]
-	}]
-}
-
diff --git a/dojox/geo/openlayers/tests/ecr/data/ecr2.json b/dojox/geo/openlayers/tests/ecr/data/ecr2.json
deleted file mode 100644
index 839909f..0000000
--- a/dojox/geo/openlayers/tests/ecr/data/ecr2.json
+++ /dev/null
@@ -1,277 +0,0 @@
-{
-	"identifier": "name",
-	"label": "name",
-	"items": [{
-		"type": "port",
-		"name": "Buenos Aires",
-		"longitude": "-58.4088134765625",
-		"latitude": "-34.5761256318848",
-		"offer": "26",
-		"demand": "19"
-	},
-	{
-		"type": "port",
-		"name": "Dhaka",
-		"longitude": "90.4086111",
-		"latitude": "23.7230556",
-		"offer": "1",
-		"demand": "19"
-	},
-	{
-		"type": "port",
-		"name": "Sao Paulo",
-		"longitude": "-46.63611111",
-		"latitude": "-23.5475",
-		"offer": "11",
-		"demand": "20"
-	},
-	{
-		"type": "port",
-		"name": "Rio de Janeiro",
-		"longitude": "-43.2075",
-		"latitude": "-22.90277778",
-		"offer": "15",
-		"demand": "26"
-	},
-	{
-		"type": "port",
-		"name": "Kinshasa",
-		"longitude": "15.315",
-		"latitude": "-4.3297222",
-		"offer": "22",
-		"demand": "26"
-	},
-	{
-		"type": "port",
-		"name": "Zhumadian",
-		"longitude": "114.0294444",
-		"latitude": "32.9794444",
-		"offer": "28",
-		"demand": "13"
-	},
-	{
-		"type": "port",
-		"name": "Taian",
-		"longitude": "117.12",
-		"latitude": "36.1852778",
-		"offer": "25",
-		"demand": "18"
-	},
-	{
-		"type": "port",
-		"name": "Shanghai",
-		"longitude": "121.4580556",
-		"latitude": "31.2222222",
-		"offer": "4",
-		"demand": "19"
-	},
-	{
-		"type": "port",
-		"name": "Nanchong",
-		"longitude": "106.0666667",
-		"latitude": "30.8",
-		"offer": "23",
-		"demand": "11"
-	},
-	{
-		"type": "port",
-		"name": "Beijing",
-		"longitude": "116.397228240967",
-		"latitude": "39.9074977414405",
-		"offer": "28",
-		"demand": "17"
-	},
-	{
-		"type": "port",
-		"name": "Bogota",
-		"longitude": "-74.0833333",
-		"latitude": "4.6",
-		"offer": "12",
-		"demand": "23"
-	},
-	{
-		"type": "port",
-		"name": "Juan Dolio",
-		"longitude": "-69.4166667",
-		"latitude": "18.4166667",
-		"offer": "1",
-		"demand": "28"
-	},
-	{
-		"type": "port",
-		"name": "Cairo",
-		"longitude": "31.25",
-		"latitude": "30.05",
-		"offer": "16",
-		"demand": "23"
-	},
-	{
-		"type": "port",
-		"name": "London",
-		"longitude": "-0.125532746315002",
-		"latitude": "51.5084152563931",
-		"offer": "29",
-		"demand": "6"
-	},
-	{
-		"type": "port",
-		"name": "Hong Kong",
-		"longitude": "114.15007352829",
-		"latitude": "22.2840136009625",
-		"offer": "12",
-		"demand": "27"
-	},
-	{
-		"type": "port",
-		"name": "Jakarta",
-		"longitude": "106.8294444",
-		"latitude": "-6.1744444",
-		"offer": "10",
-		"demand": "14"
-	},
-	{
-		"type": "port",
-		"name": "Delhi",
-		"longitude": "77.2166667",
-		"latitude": "28.6666667",
-		"offer": "7",
-		"demand": "29"
-	},
-	{
-		"type": "port",
-		"name": "Mumbai",
-		"longitude": "72.8479385375977",
-		"latitude": "19.0144100168904",
-		"offer": "23",
-		"demand": "22"
-	},
-	{
-		"type": "port",
-		"name": "Bengaluru",
-		"longitude": "77.6032912731171",
-		"latitude": "12.9762266976805",
-		"offer": "11",
-		"demand": "3"
-	},
-	{
-		"type": "port",
-		"name": "Baghdad",
-		"longitude": "44.3938889",
-		"latitude": "33.3386111",
-		"offer": "20",
-		"demand": "5"
-	},
-	{
-		"type": "port",
-		"name": "Tehran",
-		"longitude": "51.4244444",
-		"latitude": "35.6719444",
-		"offer": "30",
-		"demand": "24"
-	},
-	{
-		"type": "port",
-		"name": "Tokyo",
-		"longitude": "139.691677093506",
-		"latitude": "35.6895265930799",
-		"offer": "22",
-		"demand": "18"
-	},
-	{
-		"type": "port",
-		"name": "Seoul",
-		"longitude": "126.9997222",
-		"latitude": "37.5663889",
-		"offer": "18",
-		"demand": "19"
-	},
-	{
-		"type": "port",
-		"name": "Mexico City",
-		"longitude": "-99.1386111",
-		"latitude": "19.4341667",
-		"offer": "9",
-		"demand": "16"
-	},
-	{
-		"type": "port",
-		"name": "Lagos",
-		"longitude": "3.3958333",
-		"latitude": "6.4530556",
-		"offer": "16",
-		"demand": "10"
-	},
-	{
-		"type": "port",
-		"name": "Lima",
-		"longitude": "-77.05",
-		"latitude": "-12.05",
-		"offer": "10",
-		"demand": "12"
-	},
-	{
-		"type": "port",
-		"name": "Manila",
-		"longitude": "120.9822222",
-		"latitude": "14.6041667",
-		"offer": "23",
-		"demand": "17"
-	},
-	{
-		"type": "port",
-		"name": "Lahore",
-		"longitude": "74.3436111",
-		"latitude": "31.5497222",
-		"offer": "2",
-		"demand": "26"
-	},
-	{
-		"type": "port",
-		"name": "Karachi",
-		"longitude": "67.05",
-		"latitude": "24.8666667",
-		"offer": "29",
-		"demand": "3"
-	},
-	{
-		"type": "port",
-		"name": "Moscow",
-		"longitude": "37.6155556",
-		"latitude": "55.7522222",
-		"offer": "27",
-		"demand": "4"
-	},
-	{
-		"type": "port",
-		"name": "Bangkok",
-		"longitude": "100.5166667",
-		"latitude": "13.75",
-		"offer": "21",
-		"demand": "10"
-	},
-	{
-		"type": "port",
-		"name": "Istanbul",
-		"longitude": "28.9496612548828",
-		"latitude": "41.0138429552247",
-		"offer": "5",
-		"demand": "15"
-	},
-	{
-		"type": "port",
-		"name": "Taipei",
-		"longitude": "121.525",
-		"latitude": "25.0391667",
-		"offer": "22",
-		"demand": "27"
-		},
-	{
-		"type": "port",
-		"name": "New York City",
-		"longitude": "-74.0059729",
-		"latitude": "40.7142691",
-		"offer": "13",
-		"demand": "5"
-	}]
-}
-
diff --git a/dojox/geo/openlayers/tests/ecr/data/ecr3.json b/dojox/geo/openlayers/tests/ecr/data/ecr3.json
deleted file mode 100644
index e909466..0000000
--- a/dojox/geo/openlayers/tests/ecr/data/ecr3.json
+++ /dev/null
@@ -1,3352 +0,0 @@
-{
-    "identifier": "name",
-    "label": "name",
-    "items": [
-        {
-          "type": "port",
-          "name": "Dubai",
-          "longitude": "55.28",
-          "latitude": "25.2522222",
-          "offer": "20",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Kabul",
-          "longitude": "69.1833333",
-          "latitude": "34.5166667",
-          "offer": "5",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Yerevan",
-          "longitude": "44.5136111",
-          "latitude": "40.1811111",
-          "offer": "6",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Luanda",
-          "longitude": "13.2344444",
-          "latitude": "-8.8383333",
-          "offer": "7",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "Buenos Aires",
-          "longitude": "-58.4088134765625",
-          "latitude": "-34.5761256318848",
-          "offer": "15",
-          "demand": "1"
-        },
-        {
-          "type": "port",
-          "name": "Rosario",
-          "longitude": "-60.6663889",
-          "latitude": "-32.9511111",
-          "offer": "26",
-          "demand": "5"
-        },
-        {
-          "type": "port",
-          "name": "Córdoba",
-          "longitude": "-64.1833333",
-          "latitude": "-31.4",
-          "offer": "1",
-          "demand": "24"
-        },
-        {
-          "type": "port",
-          "name": "Wien",
-          "longitude": "16.3720750808716",
-          "latitude": "48.2084877601653",
-          "offer": "28",
-          "demand": "13"
-        },
-        {
-          "type": "port",
-          "name": "Perth",
-          "longitude": "115.8333333",
-          "latitude": "-31.9333333",
-          "offer": "15",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "Adelaide",
-          "longitude": "138.6",
-          "latitude": "-34.9333333",
-          "offer": "27",
-          "demand": "20"
-        },
-        {
-          "type": "port",
-          "name": "Sydney",
-          "longitude": "151.207323074341",
-          "latitude": "-33.8678499639382",
-          "offer": "8",
-          "demand": "13"
-        },
-        {
-          "type": "port",
-          "name": "Melbourne",
-          "longitude": "144.963322877884",
-          "latitude": "-37.8139965641595",
-          "offer": "3",
-          "demand": "21"
-        },
-        {
-          "type": "port",
-          "name": "Baku",
-          "longitude": "49.8822222",
-          "latitude": "40.3952778",
-          "offer": "9",
-          "demand": "6"
-        },
-        {
-          "type": "port",
-          "name": "Dhaka",
-          "longitude": "90.4086111",
-          "latitude": "23.7230556",
-          "offer": "16",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Chittagong",
-          "longitude": "91.8363889",
-          "latitude": "22.3330556",
-          "offer": "30",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Khulna",
-          "longitude": "89.55",
-          "latitude": "22.8",
-          "offer": "9",
-          "demand": "23"
-        },
-        {
-          "type": "port",
-          "name": "Brussels",
-          "longitude": "4.35277462005615",
-          "latitude": "50.8465974826927",
-          "offer": "10",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Ouagadougou",
-          "longitude": "-1.5247222",
-          "latitude": "12.3702778",
-          "offer": "4",
-          "demand": "11"
-        },
-        {
-          "type": "port",
-          "name": "Sofia",
-          "longitude": "23.324146270752",
-          "latitude": "42.6975135281805",
-          "offer": "21",
-          "demand": "17"
-        },
-        {
-          "type": "port",
-          "name": "Santa Cruz de la Sierra",
-          "longitude": "-63.1666667",
-          "latitude": "-17.8",
-          "offer": "7",
-          "demand": "16"
-        },
-        {
-          "type": "port",
-          "name": "Recife",
-          "longitude": "-34.88111111",
-          "latitude": "-8.053888889",
-          "offer": "1",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Fortaleza",
-          "longitude": "-38.54305556",
-          "latitude": "-3.717222222",
-          "offer": "21",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Belém",
-          "longitude": "-48.50444444",
-          "latitude": "-1.455833333",
-          "offer": "14",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "São Paulo",
-          "longitude": "-46.63611111",
-          "latitude": "-23.5475",
-          "offer": "5",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "Salvador",
-          "longitude": "-38.51083333",
-          "latitude": "-12.97111111",
-          "offer": "13",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Rio de Janeiro",
-          "longitude": "-43.2075",
-          "latitude": "-22.90277778",
-          "offer": "7",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "Porto Alegre",
-          "longitude": "-51.23",
-          "latitude": "-30.03305556",
-          "offer": "28",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "Nova Iguaçu",
-          "longitude": "-43.45111111",
-          "latitude": "-22.75916667",
-          "offer": "30",
-          "demand": "21"
-        },
-        {
-          "type": "port",
-          "name": "Guarulhos",
-          "longitude": "-46.53333333",
-          "latitude": "-23.46277778",
-          "offer": "1",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Goiânia",
-          "longitude": "-49.25388889",
-          "latitude": "-16.67861111",
-          "offer": "19",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Curitiba",
-          "longitude": "-49.27305556",
-          "latitude": "-25.42777778",
-          "offer": "17",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "Campinas",
-          "longitude": "-47.06083333",
-          "latitude": "-22.90555556",
-          "offer": "13",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Brasília",
-          "longitude": "-47.92972",
-          "latitude": "-15.77972",
-          "offer": "25",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Belo Horizonte",
-          "longitude": "-43.93777778",
-          "latitude": "-19.92083333",
-          "offer": "16",
-          "demand": "24"
-        },
-        {
-          "type": "port",
-          "name": "Manaus",
-          "longitude": "-60.025",
-          "latitude": "-3.101944444",
-          "offer": "4",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Minsk",
-          "longitude": "27.5666667",
-          "latitude": "53.9",
-          "offer": "26",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Calgary",
-          "longitude": "-114.085285152",
-          "latitude": "51.050112282",
-          "offer": "19",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Montréal",
-          "longitude": "-73.587809",
-          "latitude": "45.5088375",
-          "offer": "7",
-          "demand": "1"
-        },
-        {
-          "type": "port",
-          "name": "Toronto",
-          "longitude": "-79.416304194",
-          "latitude": "43.700113788",
-          "offer": "11",
-          "demand": "24"
-        },
-        {
-          "type": "port",
-          "name": "Vancouver",
-          "longitude": "-123.119340403",
-          "latitude": "49.249657393",
-          "offer": "30",
-          "demand": "15"
-        },
-        {
-          "type": "port",
-          "name": "Lubumbashi",
-          "longitude": "27.4666667",
-          "latitude": "-11.6666667",
-          "offer": "6",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Kinshasa",
-          "longitude": "15.315",
-          "latitude": "-4.3297222",
-          "offer": "12",
-          "demand": "4"
-        },
-        {
-          "type": "port",
-          "name": "Brazzaville",
-          "longitude": "15.2847222",
-          "latitude": "-4.2591667",
-          "offer": "23",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Abidjan",
-          "longitude": "-4.0280556",
-          "latitude": "5.3411111",
-          "offer": "18",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Santiago",
-          "longitude": "-70.5665588378906",
-          "latitude": "-33.4262838490987",
-          "offer": "28",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Yaoundé",
-          "longitude": "11.5166667",
-          "latitude": "3.8666667",
-          "offer": "28",
-          "demand": "28"
-        },
-        {
-          "type": "port",
-          "name": "Douala",
-          "longitude": "9.7",
-          "latitude": "4.0502778",
-          "offer": "21",
-          "demand": "26"
-        },
-        {
-          "type": "port",
-          "name": "Ürümqi",
-          "longitude": "87.5833333",
-          "latitude": "43.8",
-          "offer": "4",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "Zhumadian",
-          "longitude": "114.0294444",
-          "latitude": "32.9794444",
-          "offer": "28",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Zhengzhou",
-          "longitude": "113.6486111",
-          "latitude": "34.7577778",
-          "offer": "6",
-          "demand": "7"
-        },
-        {
-          "type": "port",
-          "name": "Yunfu",
-          "longitude": "112.0333333",
-          "latitude": "22.9333333",
-          "offer": "10",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Xuzhou",
-          "longitude": "117.1916667",
-          "latitude": "34.2669444",
-          "offer": "3",
-          "demand": "11"
-        },
-        {
-          "type": "port",
-          "name": "Xinyang",
-          "longitude": "114.0655556",
-          "latitude": "32.1227778",
-          "offer": "5",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "Xianyang",
-          "longitude": "108.7147222",
-          "latitude": "34.3455556",
-          "offer": "5",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Xian",
-          "longitude": "108.9286111",
-          "latitude": "34.2583333",
-          "offer": "14",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Wuxi",
-          "longitude": "120.2938889",
-          "latitude": "31.5772222",
-          "offer": "17",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Wuhan",
-          "longitude": "114.2666667",
-          "latitude": "30.5833333",
-          "offer": "29",
-          "demand": "21"
-        },
-        {
-          "type": "port",
-          "name": "Tianjin",
-          "longitude": "117.1766667",
-          "latitude": "39.1422222",
-          "offer": "15",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Tangshan",
-          "longitude": "118.1833333",
-          "latitude": "39.6333333",
-          "offer": "1",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Taiyuan",
-          "longitude": "112.5602778",
-          "latitude": "37.8694444",
-          "offer": "1",
-          "demand": "1"
-        },
-        {
-          "type": "port",
-          "name": "Taian",
-          "longitude": "117.12",
-          "latitude": "36.1852778",
-          "offer": "1",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Shiyan",
-          "longitude": "110.7780556",
-          "latitude": "32.6475",
-          "offer": "3",
-          "demand": "6"
-        },
-        {
-          "type": "port",
-          "name": "Shijiazhuang",
-          "longitude": "114.4786111",
-          "latitude": "38.0413889",
-          "offer": "29",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Shenzhen",
-          "longitude": "114.068298339844",
-          "latitude": "22.5455376639819",
-          "offer": "29",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Shantou",
-          "longitude": "116.6783333",
-          "latitude": "23.36",
-          "offer": "2",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Shanghai",
-          "longitude": "121.4580556",
-          "latitude": "31.2222222",
-          "offer": "8",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "Jieyang",
-          "longitude": "116.3655556",
-          "latitude": "23.5297222",
-          "offer": "14",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "Qingdao",
-          "longitude": "120.3719444",
-          "latitude": "36.0986111",
-          "offer": "29",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "Puyang",
-          "longitude": "119.8861111",
-          "latitude": "29.4602778",
-          "offer": "15",
-          "demand": "13"
-        },
-        {
-          "type": "port",
-          "name": "Nanjing",
-          "longitude": "118.7777778",
-          "latitude": "32.0616667",
-          "offer": "6",
-          "demand": "13"
-        },
-        {
-          "type": "port",
-          "name": "Nanchong",
-          "longitude": "106.0666667",
-          "latitude": "30.8",
-          "offer": "10",
-          "demand": "16"
-        },
-        {
-          "type": "port",
-          "name": "Nanchang",
-          "longitude": "115.8833333",
-          "latitude": "28.6833333",
-          "offer": "17",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Luoyang",
-          "longitude": "112.4536111",
-          "latitude": "34.6836111",
-          "offer": "23",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Liuyang",
-          "longitude": "113.6333333",
-          "latitude": "28.15",
-          "offer": "5",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Lanzhou",
-          "longitude": "103.7922222",
-          "latitude": "36.0563889",
-          "offer": "4",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Kunming",
-          "longitude": "102.7183333",
-          "latitude": "25.0388889",
-          "offer": "20",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Kaifeng",
-          "longitude": "114.3483333",
-          "latitude": "34.7911111",
-          "offer": "27",
-          "demand": "5"
-        },
-        {
-          "type": "port",
-          "name": "Jinan",
-          "longitude": "116.9972222",
-          "latitude": "36.6683333",
-          "offer": "8",
-          "demand": "11"
-        },
-        {
-          "type": "port",
-          "name": "Huainan",
-          "longitude": "116.9969444",
-          "latitude": "32.6263889",
-          "offer": "17",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Hefei",
-          "longitude": "117.2808333",
-          "latitude": "31.8638889",
-          "offer": "4",
-          "demand": "24"
-        },
-        {
-          "type": "port",
-          "name": "Hangzhou",
-          "longitude": "120.1688889",
-          "latitude": "30.2552778",
-          "offer": "30",
-          "demand": "23"
-        },
-        {
-          "type": "port",
-          "name": "Handan",
-          "longitude": "114.4677778",
-          "latitude": "36.6005556",
-          "offer": "14",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Guiyang",
-          "longitude": "106.7166667",
-          "latitude": "26.5833333",
-          "offer": "27",
-          "demand": "5"
-        },
-        {
-          "type": "port",
-          "name": "Guangzhou",
-          "longitude": "113.25",
-          "latitude": "23.1166667",
-          "offer": "8",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Fuzhou",
-          "longitude": "119.3061111",
-          "latitude": "26.0613889",
-          "offer": "27",
-          "demand": "26"
-        },
-        {
-          "type": "port",
-          "name": "Dayan",
-          "longitude": "100.220718383789",
-          "latitude": "26.8687934220524",
-          "offer": "2",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Dalian",
-          "longitude": "121.6022222",
-          "latitude": "38.9122222",
-          "offer": "10",
-          "demand": "24"
-        },
-        {
-          "type": "port",
-          "name": "Chongqing",
-          "longitude": "106.5527778",
-          "latitude": "29.5627778",
-          "offer": "21",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Chengdu",
-          "longitude": "104.0666667",
-          "latitude": "30.6666667",
-          "offer": "22",
-          "demand": "16"
-        },
-        {
-          "type": "port",
-          "name": "Changsha",
-          "longitude": "112.9666667",
-          "latitude": "28.2",
-          "offer": "27",
-          "demand": "26"
-        },
-        {
-          "type": "port",
-          "name": "Beijing",
-          "longitude": "116.397228240967",
-          "latitude": "39.9074977414405",
-          "offer": "11",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "Suzhou",
-          "longitude": "120.6180556",
-          "latitude": "31.3113889",
-          "offer": "20",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Shenyang",
-          "longitude": "123.4327778",
-          "latitude": "41.7922222",
-          "offer": "23",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Jilin",
-          "longitude": "126.5602778",
-          "latitude": "43.8508333",
-          "offer": "1",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Harbin",
-          "longitude": "126.65",
-          "latitude": "45.75",
-          "offer": "2",
-          "demand": "25"
-        },
-        {
-          "type": "port",
-          "name": "Fushun",
-          "longitude": "123.9233333",
-          "latitude": "41.8558333",
-          "offer": "7",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Datong",
-          "longitude": "113.2913889",
-          "latitude": "40.0936111",
-          "offer": "1",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Changchun",
-          "longitude": "125.3227778",
-          "latitude": "43.88",
-          "offer": "1",
-          "demand": "11"
-        },
-        {
-          "type": "port",
-          "name": "Baotou",
-          "longitude": "109.8222222",
-          "latitude": "40.6522222",
-          "offer": "12",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Anshan",
-          "longitude": "122.99",
-          "latitude": "41.1236111",
-          "offer": "21",
-          "demand": "4"
-        },
-        {
-          "type": "port",
-          "name": "Medellín",
-          "longitude": "-75.5361111",
-          "latitude": "6.2913889",
-          "offer": "24",
-          "demand": "13"
-        },
-        {
-          "type": "port",
-          "name": "Cali",
-          "longitude": "-76.5225",
-          "latitude": "3.4372222",
-          "offer": "17",
-          "demand": "7"
-        },
-        {
-          "type": "port",
-          "name": "Bogotá",
-          "longitude": "-74.0833333",
-          "latitude": "4.6",
-          "offer": "3",
-          "demand": "23"
-        },
-        {
-          "type": "port",
-          "name": "Barranquilla",
-          "longitude": "-74.7963889",
-          "latitude": "10.9638889",
-          "offer": "16",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Havana",
-          "longitude": "-82.3641667",
-          "latitude": "23.1319444",
-          "offer": "16",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Praha",
-          "longitude": "14.4241322001241",
-          "latitude": "50.0878367932108",
-          "offer": "22",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "München",
-          "longitude": "11.5754914283752",
-          "latitude": "48.1374325498109",
-          "offer": "28",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Hamburg",
-          "longitude": "10.0",
-          "latitude": "53.55",
-          "offer": "8",
-          "demand": "28"
-        },
-        {
-          "type": "port",
-          "name": "Berlin",
-          "longitude": "13.4",
-          "latitude": "52.5166667",
-          "offer": "7",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "Copenhagen",
-          "longitude": "12.5709342956543",
-          "latitude": "55.6776812020993",
-          "offer": "18",
-          "demand": "25"
-        },
-        {
-          "type": "port",
-          "name": "Santo Domingo",
-          "longitude": "-69.9",
-          "latitude": "18.4666667",
-          "offer": "30",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Juan Dolio",
-          "longitude": "-69.4166667",
-          "latitude": "18.4166667",
-          "offer": "17",
-          "demand": "5"
-        },
-        {
-          "type": "port",
-          "name": "Algiers",
-          "longitude": "3.0505556",
-          "latitude": "36.7630556",
-          "offer": "4",
-          "demand": "21"
-        },
-        {
-          "type": "port",
-          "name": "Quito",
-          "longitude": "-78.5",
-          "latitude": "-0.2166667",
-          "offer": "2",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Guayaquil",
-          "longitude": "-79.9",
-          "latitude": "-2.1666667",
-          "offer": "21",
-          "demand": "13"
-        },
-        {
-          "type": "port",
-          "name": "Cairo",
-          "longitude": "31.25",
-          "latitude": "30.05",
-          "offer": "11",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Al JÄ«zah",
-          "longitude": "31.2122222",
-          "latitude": "30.0086111",
-          "offer": "3",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Alexandria",
-          "longitude": "29.9191667",
-          "latitude": "31.1980556",
-          "offer": "30",
-          "demand": "17"
-        },
-        {
-          "type": "port",
-          "name": "Madrid",
-          "longitude": "-3.70256423950195",
-          "latitude": "40.4165020941502",
-          "offer": "29",
-          "demand": "28"
-        },
-        {
-          "type": "port",
-          "name": "Barcelona",
-          "longitude": "2.15898513793945",
-          "latitude": "41.3887868890716",
-          "offer": "23",
-          "demand": "13"
-        },
-        {
-          "type": "port",
-          "name": "Addis Ababa",
-          "longitude": "38.7",
-          "latitude": "9.0333333",
-          "offer": "6",
-          "demand": "23"
-        },
-        {
-          "type": "port",
-          "name": "Paris",
-          "longitude": "2.3488",
-          "latitude": "48.85341",
-          "offer": "22",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "London",
-          "longitude": "-0.125532746315002",
-          "latitude": "51.5084152563931",
-          "offer": "26",
-          "demand": "15"
-        },
-        {
-          "type": "port",
-          "name": "Tbilisi",
-          "longitude": "44.7908333",
-          "latitude": "41.725",
-          "offer": "18",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Kumasi",
-          "longitude": "-1.6166667",
-          "latitude": "6.6833333",
-          "offer": "10",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Accra",
-          "longitude": "-0.2166667",
-          "latitude": "5.55",
-          "offer": "21",
-          "demand": "28"
-        },
-        {
-          "type": "port",
-          "name": "Conakry",
-          "longitude": "-13.7122222",
-          "latitude": "9.5091667",
-          "offer": "7",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Camayenne",
-          "longitude": "-13.6877778",
-          "latitude": "9.535",
-          "offer": "9",
-          "demand": "16"
-        },
-        {
-          "type": "port",
-          "name": "Kowloon",
-          "longitude": "114.1833333",
-          "latitude": "22.3166667",
-          "offer": "2",
-          "demand": "11"
-        },
-        {
-          "type": "port",
-          "name": "Hong Kong",
-          "longitude": "114.15007352829",
-          "latitude": "22.2840136009625",
-          "offer": "25",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "Port-au-Prince",
-          "longitude": "-72.335",
-          "latitude": "18.5391667",
-          "offer": "4",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Budapest",
-          "longitude": "19.0833333",
-          "latitude": "47.5",
-          "offer": "19",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Medan",
-          "longitude": "98.6666667",
-          "latitude": "3.5833333",
-          "offer": "24",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Makassar",
-          "longitude": "119.4386111",
-          "latitude": "-5.1463889",
-          "offer": "28",
-          "demand": "26"
-        },
-        {
-          "type": "port",
-          "name": "Tangerang",
-          "longitude": "106.63",
-          "latitude": "-6.1780556",
-          "offer": "17",
-          "demand": "6"
-        },
-        {
-          "type": "port",
-          "name": "Surabaya",
-          "longitude": "112.7508333",
-          "latitude": "-7.2491667",
-          "offer": "30",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Semarang",
-          "longitude": "110.4166667",
-          "latitude": "-6.9666667",
-          "offer": "12",
-          "demand": "13"
-        },
-        {
-          "type": "port",
-          "name": "Palembang",
-          "longitude": "104.745798110962",
-          "latitude": "-2.91672533277337",
-          "offer": "23",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Jakarta",
-          "longitude": "106.8294444",
-          "latitude": "-6.1744444",
-          "offer": "14",
-          "demand": "20"
-        },
-        {
-          "type": "port",
-          "name": "Depok",
-          "longitude": "106.8186111",
-          "latitude": "-6.4",
-          "offer": "21",
-          "demand": "25"
-        },
-        {
-          "type": "port",
-          "name": "Bekasi",
-          "longitude": "106.9919444",
-          "latitude": "-6.2366667",
-          "offer": "11",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Bandung",
-          "longitude": "107.6205556",
-          "latitude": "-6.9127778",
-          "offer": "10",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Dublin",
-          "longitude": "-6.2488889",
-          "latitude": "53.3330556",
-          "offer": "28",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "Vish�khapatnam",
-          "longitude": "83.3",
-          "latitude": "17.7",
-          "offer": "24",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Benares",
-          "longitude": "83.0",
-          "latitude": "25.3333333",
-          "offer": "5",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Vadodara",
-          "longitude": "73.2",
-          "latitude": "22.3",
-          "offer": "27",
-          "demand": "20"
-        },
-        {
-          "type": "port",
-          "name": "Th�ne",
-          "longitude": "72.9666667",
-          "latitude": "19.2",
-          "offer": "10",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "Teni",
-          "longitude": "77.4833333",
-          "latitude": "10.0",
-          "offer": "21",
-          "demand": "24"
-        },
-        {
-          "type": "port",
-          "name": "SÅ«rat",
-          "longitude": "72.8333333",
-          "latitude": "21.1666667",
-          "offer": "4",
-          "demand": "17"
-        },
-        {
-          "type": "port",
-          "name": "R�jkot",
-          "longitude": "70.7833333",
-          "latitude": "22.3",
-          "offer": "14",
-          "demand": "7"
-        },
-        {
-          "type": "port",
-          "name": "Pune",
-          "longitude": "73.8553547859192",
-          "latitude": "18.5195742288075",
-          "offer": "30",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Pimpri",
-          "longitude": "73.8",
-          "latitude": "18.6166667",
-          "offer": "4",
-          "demand": "16"
-        },
-        {
-          "type": "port",
-          "name": "Patna",
-          "longitude": "85.1166667",
-          "latitude": "25.6",
-          "offer": "9",
-          "demand": "25"
-        },
-        {
-          "type": "port",
-          "name": "N�sik",
-          "longitude": "73.8",
-          "latitude": "19.9833333",
-          "offer": "3",
-          "demand": "5"
-        },
-        {
-          "type": "port",
-          "name": "N�gpur",
-          "longitude": "79.1",
-          "latitude": "21.15",
-          "offer": "14",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Meerut",
-          "longitude": "77.7",
-          "latitude": "28.9833333",
-          "offer": "10",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Chennai",
-          "longitude": "80.2784729003906",
-          "latitude": "13.0878385345075",
-          "offer": "28",
-          "demand": "4"
-        },
-        {
-          "type": "port",
-          "name": "Ludhi�na",
-          "longitude": "75.85",
-          "latitude": "30.9",
-          "offer": "23",
-          "demand": "15"
-        },
-        {
-          "type": "port",
-          "name": "Lucknow",
-          "longitude": "80.9166667",
-          "latitude": "26.85",
-          "offer": "8",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "K�npur",
-          "longitude": "80.35",
-          "latitude": "26.4666667",
-          "offer": "1",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Kaly�n",
-          "longitude": "73.15",
-          "latitude": "19.25",
-          "offer": "5",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Jaipur",
-          "longitude": "75.8166667",
-          "latitude": "26.9166667",
-          "offer": "20",
-          "demand": "25"
-        },
-        {
-          "type": "port",
-          "name": "Jabalpur",
-          "longitude": "79.9500632286072",
-          "latitude": "23.1669748590236",
-          "offer": "27",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Indore",
-          "longitude": "75.8333015441895",
-          "latitude": "22.7179235376322",
-          "offer": "21",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Hyder�b�d",
-          "longitude": "78.4744444",
-          "latitude": "17.3752778",
-          "offer": "23",
-          "demand": "6"
-        },
-        {
-          "type": "port",
-          "name": "H�ora",
-          "longitude": "88.3102778",
-          "latitude": "22.5891667",
-          "offer": "24",
-          "demand": "5"
-        },
-        {
-          "type": "port",
-          "name": "Gorakhpur",
-          "longitude": "75.6833333",
-          "latitude": "29.45",
-          "offer": "8",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Gh�zi�b�d",
-          "longitude": "77.4333333",
-          "latitude": "28.6666667",
-          "offer": "4",
-          "demand": "9"
-        },
-        {
-          "type": "port",
-          "name": "Farīd�b�d",
-          "longitude": "77.3166667",
-          "latitude": "28.4333333",
-          "offer": "16",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Delhi",
-          "longitude": "77.2166667",
-          "latitude": "28.6666667",
-          "offer": "25",
-          "demand": "20"
-        },
-        {
-          "type": "port",
-          "name": "Calcutta",
-          "longitude": "88.3697222",
-          "latitude": "22.5697222",
-          "offer": "12",
-          "demand": "28"
-        },
-        {
-          "type": "port",
-          "name": "Mumbai",
-          "longitude": "72.8479385375977",
-          "latitude": "19.0144100168904",
-          "offer": "9",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Bhop�l",
-          "longitude": "77.4",
-          "latitude": "23.2666667",
-          "offer": "21",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Bengaluru",
-          "longitude": "77.6032912731171",
-          "latitude": "12.9762266976805",
-          "offer": "14",
-          "demand": "15"
-        },
-        {
-          "type": "port",
-          "name": "Aurang�b�d",
-          "longitude": "75.3333333",
-          "latitude": "19.8833333",
-          "offer": "11",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "Amritsar",
-          "longitude": "74.8655556",
-          "latitude": "31.6330556",
-          "offer": "14",
-          "demand": "17"
-        },
-        {
-          "type": "port",
-          "name": "Allah�b�d",
-          "longitude": "81.85",
-          "latitude": "25.45",
-          "offer": "13",
-          "demand": "21"
-        },
-        {
-          "type": "port",
-          "name": "Ahmad�b�d",
-          "longitude": "72.6166667",
-          "latitude": "23.0333333",
-          "offer": "12",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "Ä€gra",
-          "longitude": "78.0166667",
-          "latitude": "27.1833333",
-          "offer": "5",
-          "demand": "5"
-        },
-        {
-          "type": "port",
-          "name": "Baghdad",
-          "longitude": "44.3938889",
-          "latitude": "33.3386111",
-          "offer": "13",
-          "demand": "15"
-        },
-        {
-          "type": "port",
-          "name": "Al Mawşil al Jadīdah",
-          "longitude": "43.0861111",
-          "latitude": "36.3291667",
-          "offer": "5",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "Mosul",
-          "longitude": "43.1188889",
-          "latitude": "36.335",
-          "offer": "17",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Al BaÅŸrah",
-          "longitude": "47.8191667",
-          "latitude": "30.4941667",
-          "offer": "25",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Al Başrah al Qadīmah",
-          "longitude": "47.8175",
-          "latitude": "30.4955556",
-          "offer": "5",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Tehr�n",
-          "longitude": "51.4244444",
-          "latitude": "35.6719444",
-          "offer": "24",
-          "demand": "4"
-        },
-        {
-          "type": "port",
-          "name": "Tabrīz",
-          "longitude": "46.2919444",
-          "latitude": "38.08",
-          "offer": "11",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Shīr�z",
-          "longitude": "52.5383333",
-          "latitude": "29.615",
-          "offer": "15",
-          "demand": "9"
-        },
-        {
-          "type": "port",
-          "name": "Mashhad",
-          "longitude": "59.6119444",
-          "latitude": "36.2958333",
-          "offer": "21",
-          "demand": "20"
-        },
-        {
-          "type": "port",
-          "name": "Karaj",
-          "longitude": "50.9982025623322",
-          "latitude": "35.8287611261052",
-          "offer": "16",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Eşfah�n",
-          "longitude": "51.6713889",
-          "latitude": "32.6597222",
-          "offer": "7",
-          "demand": "26"
-        },
-        {
-          "type": "port",
-          "name": "Roma",
-          "longitude": "12.4833333",
-          "latitude": "41.9",
-          "offer": "23",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "Milano",
-          "longitude": "9.1895055770874",
-          "latitude": "45.4642693810258",
-          "offer": "3",
-          "demand": "13"
-        },
-        {
-          "type": "port",
-          "name": "Amman",
-          "longitude": "35.9333333",
-          "latitude": "31.95",
-          "offer": "29",
-          "demand": "9"
-        },
-        {
-          "type": "port",
-          "name": "Yono",
-          "longitude": "139.6333333",
-          "latitude": "35.8833333",
-          "offer": "9",
-          "demand": "17"
-        },
-        {
-          "type": "port",
-          "name": "Yokohama",
-          "longitude": "139.65",
-          "latitude": "35.45",
-          "offer": "8",
-          "demand": "23"
-        },
-        {
-          "type": "port",
-          "name": "Tokyo",
-          "longitude": "139.691677093506",
-          "latitude": "35.6895265930799",
-          "offer": "19",
-          "demand": "17"
-        },
-        {
-          "type": "port",
-          "name": "Ã…Å’saka",
-          "longitude": "135.502181947231",
-          "latitude": "34.6937398415059",
-          "offer": "21",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Nagoya",
-          "longitude": "136.906409561634",
-          "latitude": "35.1814727966958",
-          "offer": "3",
-          "demand": "17"
-        },
-        {
-          "type": "port",
-          "name": "Kyoto",
-          "longitude": "135.75385093689",
-          "latitude": "35.02106999142",
-          "offer": "20",
-          "demand": "11"
-        },
-        {
-          "type": "port",
-          "name": "K�be",
-          "longitude": "135.1666667",
-          "latitude": "34.6833333",
-          "offer": "20",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Kawasaki",
-          "longitude": "139.7172222",
-          "latitude": "35.5205556",
-          "offer": "23",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "Hiroshima",
-          "longitude": "132.45",
-          "latitude": "34.4",
-          "offer": "28",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "Fukuoka",
-          "longitude": "130.4",
-          "latitude": "33.5833333",
-          "offer": "16",
-          "demand": "7"
-        },
-        {
-          "type": "port",
-          "name": "Sendai",
-          "longitude": "140.8847222",
-          "latitude": "38.2547222",
-          "offer": "17",
-          "demand": "5"
-        },
-        {
-          "type": "port",
-          "name": "Sapporo",
-          "longitude": "141.3538889",
-          "latitude": "43.0547222",
-          "offer": "5",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "Saitama",
-          "longitude": "139.656572341919",
-          "latitude": "35.9080659046769",
-          "offer": "20",
-          "demand": "9"
-        },
-        {
-          "type": "port",
-          "name": "Nairobi",
-          "longitude": "36.8166667",
-          "latitude": "-1.2833333",
-          "offer": "15",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Phnom Penh",
-          "longitude": "104.9166667",
-          "latitude": "11.55",
-          "offer": "6",
-          "demand": "5"
-        },
-        {
-          "type": "port",
-          "name": "Pyongyang",
-          "longitude": "125.7547222",
-          "latitude": "39.0194444",
-          "offer": "14",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "Taej�n",
-          "longitude": "127.4197222",
-          "latitude": "36.3213889",
-          "offer": "26",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "Taegu",
-          "longitude": "128.5911111",
-          "latitude": "35.8702778",
-          "offer": "9",
-          "demand": "13"
-        },
-        {
-          "type": "port",
-          "name": "Suw�n",
-          "longitude": "127.0191667",
-          "latitude": "37.2841667",
-          "offer": "16",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Seoul",
-          "longitude": "126.9997222",
-          "latitude": "37.5663889",
-          "offer": "4",
-          "demand": "15"
-        },
-        {
-          "type": "port",
-          "name": "Pusan",
-          "longitude": "129.0402778",
-          "latitude": "35.1027778",
-          "offer": "15",
-          "demand": "26"
-        },
-        {
-          "type": "port",
-          "name": "Kwangju",
-          "longitude": "126.9155556",
-          "latitude": "35.1547222",
-          "offer": "19",
-          "demand": "4"
-        },
-        {
-          "type": "port",
-          "name": "Inch�n",
-          "longitude": "126.7316667",
-          "latitude": "37.4536111",
-          "offer": "6",
-          "demand": "4"
-        },
-        {
-          "type": "port",
-          "name": "S�ngnam",
-          "longitude": "127.1377778",
-          "latitude": "37.4386111",
-          "offer": "22",
-          "demand": "6"
-        },
-        {
-          "type": "port",
-          "name": "Almaty",
-          "longitude": "76.95",
-          "latitude": "43.25",
-          "offer": "12",
-          "demand": "9"
-        },
-        {
-          "type": "port",
-          "name": "Ras Bayrūt",
-          "longitude": "35.4833333",
-          "latitude": "33.9",
-          "offer": "9",
-          "demand": "25"
-        },
-        {
-          "type": "port",
-          "name": "Beirut",
-          "longitude": "35.5097222",
-          "latitude": "33.8719444",
-          "offer": "29",
-          "demand": "15"
-        },
-        {
-          "type": "port",
-          "name": "Tripoli",
-          "longitude": "13.18",
-          "latitude": "32.8925",
-          "offer": "13",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Rabat",
-          "longitude": "-6.83",
-          "latitude": "34.02",
-          "offer": "18",
-          "demand": "15"
-        },
-        {
-          "type": "port",
-          "name": "Casablanca",
-          "longitude": "-7.61",
-          "latitude": "33.59",
-          "offer": "5",
-          "demand": "5"
-        },
-        {
-          "type": "port",
-          "name": "Antananarivo",
-          "longitude": "47.5166667",
-          "latitude": "-18.9166667",
-          "offer": "6",
-          "demand": "16"
-        },
-        {
-          "type": "port",
-          "name": "Bamako",
-          "longitude": "-8.0",
-          "latitude": "12.65",
-          "offer": "17",
-          "demand": "24"
-        },
-        {
-          "type": "port",
-          "name": "Rangoon",
-          "longitude": "96.1561111",
-          "latitude": "16.8052778",
-          "offer": "2",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "Mandalay",
-          "longitude": "96.0833333",
-          "latitude": "22.0",
-          "offer": "12",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Puebla de Zaragoza",
-          "longitude": "-98.2",
-          "latitude": "19.05",
-          "offer": "20",
-          "demand": "1"
-        },
-        {
-          "type": "port",
-          "name": "Ecatepec",
-          "longitude": "-99.0525",
-          "latitude": "19.6011111",
-          "offer": "15",
-          "demand": "28"
-        },
-        {
-          "type": "port",
-          "name": "Ciudad Nezahualcóyotl",
-          "longitude": "-99.0330556",
-          "latitude": "19.4136111",
-          "offer": "12",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Mexico City",
-          "longitude": "-99.1386111",
-          "latitude": "19.4341667",
-          "offer": "3",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Tijuana",
-          "longitude": "-117.0166667",
-          "latitude": "32.5333333",
-          "offer": "25",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Monterrey",
-          "longitude": "-100.3166667",
-          "latitude": "25.6666667",
-          "offer": "22",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "León",
-          "longitude": "-101.6666667",
-          "latitude": "21.1166667",
-          "offer": "18",
-          "demand": "7"
-        },
-        {
-          "type": "port",
-          "name": "Guadalajara",
-          "longitude": "-103.3333333",
-          "latitude": "20.6666667",
-          "offer": "6",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Ciudad Juárez",
-          "longitude": "-106.4833333",
-          "latitude": "31.7333333",
-          "offer": "18",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Kuala Lumpur",
-          "longitude": "101.7",
-          "latitude": "3.1666667",
-          "offer": "22",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Maputo",
-          "longitude": "32.5891667",
-          "latitude": "-25.9652778",
-          "offer": "25",
-          "demand": "21"
-        },
-        {
-          "type": "port",
-          "name": "Port Harcourt",
-          "longitude": "6.9986111",
-          "latitude": "4.7891667",
-          "offer": "14",
-          "demand": "11"
-        },
-        {
-          "type": "port",
-          "name": "Maiduguri",
-          "longitude": "13.16",
-          "latitude": "11.845",
-          "offer": "2",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Lagos",
-          "longitude": "3.3958333",
-          "latitude": "6.4530556",
-          "offer": "1",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Kano",
-          "longitude": "8.5166667",
-          "latitude": "11.9963889",
-          "offer": "2",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "Kaduna",
-          "longitude": "7.4402778",
-          "latitude": "10.5230556",
-          "offer": "6",
-          "demand": "16"
-        },
-        {
-          "type": "port",
-          "name": "Ibadan",
-          "longitude": "3.8963889",
-          "latitude": "7.3877778",
-          "offer": "22",
-          "demand": "25"
-        },
-        {
-          "type": "port",
-          "name": "Benin-City",
-          "longitude": "5.6333333",
-          "latitude": "6.3333333",
-          "offer": "10",
-          "demand": "7"
-        },
-        {
-          "type": "port",
-          "name": "Kathmandu",
-          "longitude": "85.3166667",
-          "latitude": "27.7166667",
-          "offer": "25",
-          "demand": "4"
-        },
-        {
-          "type": "port",
-          "name": "Lima",
-          "longitude": "-77.05",
-          "latitude": "-12.05",
-          "offer": "11",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Manila",
-          "longitude": "120.9822222",
-          "latitude": "14.6041667",
-          "offer": "17",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Davao",
-          "longitude": "125.6127778",
-          "latitude": "7.0730556",
-          "offer": "12",
-          "demand": "1"
-        },
-        {
-          "type": "port",
-          "name": "R�walpindi",
-          "longitude": "73.0666667",
-          "latitude": "33.6",
-          "offer": "21",
-          "demand": "21"
-        },
-        {
-          "type": "port",
-          "name": "Pesh�war",
-          "longitude": "71.5733333",
-          "latitude": "34.0077778",
-          "offer": "24",
-          "demand": "28"
-        },
-        {
-          "type": "port",
-          "name": "Mult�n",
-          "longitude": "71.4752778",
-          "latitude": "30.1955556",
-          "offer": "25",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "Lahore",
-          "longitude": "74.3436111",
-          "latitude": "31.5497222",
-          "offer": "26",
-          "demand": "4"
-        },
-        {
-          "type": "port",
-          "name": "Kar�chi",
-          "longitude": "67.05",
-          "latitude": "24.8666667",
-          "offer": "12",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Hyder�b�d0",
-          "longitude": "68.3666667",
-          "latitude": "25.3666667",
-          "offer": "15",
-          "demand": "9"
-        },
-        {
-          "type": "port",
-          "name": "Gujr�nw�la",
-          "longitude": "74.1833333",
-          "latitude": "32.15",
-          "offer": "21",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Faisal�b�d",
-          "longitude": "73.0833333",
-          "latitude": "31.4166667",
-          "offer": "1",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "Warsaw",
-          "longitude": "21.0",
-          "latitude": "52.25",
-          "offer": "16",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Asunción",
-          "longitude": "-57.6666667",
-          "latitude": "-25.2666667",
-          "offer": "16",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "BucureÅŸti",
-          "longitude": "26.1",
-          "latitude": "44.4333333",
-          "offer": "25",
-          "demand": "21"
-        },
-        {
-          "type": "port",
-          "name": "Belgrade",
-          "longitude": "20.4680556",
-          "latitude": "44.8186111",
-          "offer": "9",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Volgograd",
-          "longitude": "44.5858333",
-          "latitude": "48.8047222",
-          "offer": "13",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Ufa",
-          "longitude": "56.0375",
-          "latitude": "54.775",
-          "offer": "23",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Saint Petersburg",
-          "longitude": "30.2641667",
-          "latitude": "59.8944444",
-          "offer": "11",
-          "demand": "17"
-        },
-        {
-          "type": "port",
-          "name": "Samara",
-          "longitude": "50.15",
-          "latitude": "53.2",
-          "offer": "10",
-          "demand": "23"
-        },
-        {
-          "type": "port",
-          "name": "Rostov-na-Donu",
-          "longitude": "39.7138889",
-          "latitude": "47.2363889",
-          "offer": "12",
-          "demand": "16"
-        },
-        {
-          "type": "port",
-          "name": "Nizhniy Novgorod",
-          "longitude": "44.002046585083",
-          "latitude": "56.3286733202717",
-          "offer": "29",
-          "demand": "20"
-        },
-        {
-          "type": "port",
-          "name": "Moscow",
-          "longitude": "37.6155556",
-          "latitude": "55.7522222",
-          "offer": "14",
-          "demand": "25"
-        },
-        {
-          "type": "port",
-          "name": "Kazan",
-          "longitude": "49.1333333",
-          "latitude": "55.75",
-          "offer": "17",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Yekaterinburg",
-          "longitude": "60.6125",
-          "latitude": "56.8575",
-          "offer": "17",
-          "demand": "30"
-        },
-        {
-          "type": "port",
-          "name": "Omsk",
-          "longitude": "73.4",
-          "latitude": "55.0",
-          "offer": "24",
-          "demand": "20"
-        },
-        {
-          "type": "port",
-          "name": "Novosibirsk",
-          "longitude": "82.9344444",
-          "latitude": "55.0411111",
-          "offer": "29",
-          "demand": "23"
-        },
-        {
-          "type": "port",
-          "name": "Chelyabinsk",
-          "longitude": "61.4297222",
-          "latitude": "55.1544444",
-          "offer": "2",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Mecca",
-          "longitude": "39.8261111",
-          "latitude": "21.4266667",
-          "offer": "21",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Jiddah",
-          "longitude": "39.2191667",
-          "latitude": "21.5169444",
-          "offer": "21",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Riyadh",
-          "longitude": "46.7727778",
-          "latitude": "24.6408333",
-          "offer": "9",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Medina",
-          "longitude": "39.6141667",
-          "latitude": "24.4686111",
-          "offer": "29",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Omdurman",
-          "longitude": "32.4372222",
-          "latitude": "15.6361111",
-          "offer": "8",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Khartoum",
-          "longitude": "32.5341667",
-          "latitude": "15.5880556",
-          "offer": "12",
-          "demand": "16"
-        },
-        {
-          "type": "port",
-          "name": "Stockholm",
-          "longitude": "18.0649030208588",
-          "latitude": "59.3325765361753",
-          "offer": "14",
-          "demand": "5"
-        },
-        {
-          "type": "port",
-          "name": "Singapore",
-          "longitude": "103.8558333",
-          "latitude": "1.2930556",
-          "offer": "9",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Grand Dakar",
-          "longitude": "-17.4552778",
-          "latitude": "14.7088889",
-          "offer": "18",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "Dakar",
-          "longitude": "-17.4438858032227",
-          "latitude": "14.6951118854684",
-          "offer": "19",
-          "demand": "9"
-        },
-        {
-          "type": "port",
-          "name": "Mogadishu",
-          "longitude": "45.3419172763824",
-          "latitude": "2.03913722186582",
-          "offer": "30",
-          "demand": "28"
-        },
-        {
-          "type": "port",
-          "name": "Aleppo",
-          "longitude": "37.1586111",
-          "latitude": "36.2027778",
-          "offer": "3",
-          "demand": "4"
-        },
-        {
-          "type": "port",
-          "name": "Damascus",
-          "longitude": "36.3",
-          "latitude": "33.5",
-          "offer": "24",
-          "demand": "4"
-        },
-        {
-          "type": "port",
-          "name": "Bangkok",
-          "longitude": "100.5166667",
-          "latitude": "13.75",
-          "offer": "4",
-          "demand": "7"
-        },
-        {
-          "type": "port",
-          "name": "Ä°zmir",
-          "longitude": "27.1502778",
-          "latitude": "38.4072222",
-          "offer": "25",
-          "demand": "24"
-        },
-        {
-          "type": "port",
-          "name": "Gaziantep",
-          "longitude": "37.3825",
-          "latitude": "37.0594444",
-          "offer": "5",
-          "demand": "22"
-        },
-        {
-          "type": "port",
-          "name": "Ankara",
-          "longitude": "32.8644444",
-          "latitude": "39.9272222",
-          "offer": "18",
-          "demand": "23"
-        },
-        {
-          "type": "port",
-          "name": "Adana",
-          "longitude": "35.3288889",
-          "latitude": "37.0016667",
-          "offer": "8",
-          "demand": "17"
-        },
-        {
-          "type": "port",
-          "name": "Ä°stanbul",
-          "longitude": "28.9496612548828",
-          "latitude": "41.0138429552247",
-          "offer": "19",
-          "demand": "16"
-        },
-        {
-          "type": "port",
-          "name": "Bursa",
-          "longitude": "29.0611111",
-          "latitude": "40.1916667",
-          "offer": "20",
-          "demand": "20"
-        },
-        {
-          "type": "port",
-          "name": "Taipei",
-          "longitude": "121.525",
-          "latitude": "25.0391667",
-          "offer": "13",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Tai-chung-shih",
-          "longitude": "120.6866667",
-          "latitude": "24.1483333",
-          "offer": "29",
-          "demand": "11"
-        },
-        {
-          "type": "port",
-          "name": "Kao-hsiung",
-          "longitude": "120.3013889",
-          "latitude": "22.6177778",
-          "offer": "24",
-          "demand": "1"
-        },
-        {
-          "type": "port",
-          "name": "Dar es Salaam",
-          "longitude": "39.2833333",
-          "latitude": "-6.8",
-          "offer": "26",
-          "demand": "23"
-        },
-        {
-          "type": "port",
-          "name": "Odesa",
-          "longitude": "30.7326221466064",
-          "latitude": "46.4774726081453",
-          "offer": "19",
-          "demand": "25"
-        },
-        {
-          "type": "port",
-          "name": "Kiev",
-          "longitude": "30.5166667",
-          "latitude": "50.4333333",
-          "offer": "18",
-          "demand": "12"
-        },
-        {
-          "type": "port",
-          "name": "Kharkiv",
-          "longitude": "36.25",
-          "latitude": "50.0",
-          "offer": "4",
-          "demand": "14"
-        },
-        {
-          "type": "port",
-          "name": "Donetsk",
-          "longitude": "37.8",
-          "latitude": "48.0",
-          "offer": "9",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Dnipropetrovsk",
-          "longitude": "34.9833333",
-          "latitude": "48.45",
-          "offer": "6",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "Kampala",
-          "longitude": "32.5655556",
-          "latitude": "0.3155556",
-          "offer": "27",
-          "demand": "23"
-        },
-        {
-          "type": "port",
-          "name": "Philadelphia",
-          "longitude": "-75.163789",
-          "latitude": "39.952335",
-          "offer": "22",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Dallas",
-          "longitude": "-96.8066667",
-          "latitude": "32.7830556",
-          "offer": "30",
-          "demand": "29"
-        },
-        {
-          "type": "port",
-          "name": "Houston",
-          "longitude": "-95.3632715",
-          "latitude": "29.7632836",
-          "offer": "7",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "San Antonio",
-          "longitude": "-98.4936282",
-          "latitude": "29.4241219",
-          "offer": "26",
-          "demand": "20"
-        },
-        {
-          "type": "port",
-          "name": "Chicago",
-          "longitude": "-87.6500523",
-          "latitude": "41.850033",
-          "offer": "22",
-          "demand": "8"
-        },
-        {
-          "type": "port",
-          "name": "Brooklyn",
-          "longitude": "-73.9495823",
-          "latitude": "40.6501038",
-          "offer": "14",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "New York City",
-          "longitude": "-74.0059729",
-          "latitude": "40.7142691",
-          "offer": "25",
-          "demand": "24"
-        },
-        {
-          "type": "port",
-          "name": "Phoenix",
-          "longitude": "-112.0740373",
-          "latitude": "33.4483771",
-          "offer": "30",
-          "demand": "26"
-        },
-        {
-          "type": "port",
-          "name": "Los Angeles",
-          "longitude": "-118.2436849",
-          "latitude": "34.0522342",
-          "offer": "27",
-          "demand": "10"
-        },
-        {
-          "type": "port",
-          "name": "San Diego",
-          "longitude": "-117.1572551",
-          "latitude": "32.7153292",
-          "offer": "13",
-          "demand": "18"
-        },
-        {
-          "type": "port",
-          "name": "Montevideo",
-          "longitude": "-56.1708333",
-          "latitude": "-34.8580556",
-          "offer": "26",
-          "demand": "3"
-        },
-        {
-          "type": "port",
-          "name": "Tashkent",
-          "longitude": "69.25",
-          "latitude": "41.3166667",
-          "offer": "23",
-          "demand": "1"
-        },
-        {
-          "type": "port",
-          "name": "Valencia",
-          "longitude": "-68.0038889",
-          "latitude": "10.1805556",
-          "offer": "7",
-          "demand": "27"
-        },
-        {
-          "type": "port",
-          "name": "Maracaibo",
-          "longitude": "-71.6405556",
-          "latitude": "10.6316667",
-          "offer": "12",
-          "demand": "1"
-        },
-        {
-          "type": "port",
-          "name": "Caracas",
-          "longitude": "-66.9166667",
-          "latitude": "10.5",
-          "offer": "16",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Thành phố Hồ Chí Minh",
-          "longitude": "106.6666667",
-          "latitude": "10.75",
-          "offer": "30",
-          "demand": "26"
-        },
-        {
-          "type": "port",
-          "name": "Hà Nội",
-          "longitude": "105.85",
-          "latitude": "21.0333333",
-          "offer": "3",
-          "demand": "15"
-        },
-        {
-          "type": "port",
-          "name": "Sanaa",
-          "longitude": "44.2066667",
-          "latitude": "15.3547222",
-          "offer": "9",
-          "demand": "2"
-        },
-        {
-          "type": "port",
-          "name": "Soweto",
-          "longitude": "27.8666667",
-          "latitude": "-26.2666667",
-          "offer": "19",
-          "demand": "25"
-        },
-        {
-          "type": "port",
-          "name": "Pretoria",
-          "longitude": "28.2294444",
-          "latitude": "-25.7069444",
-          "offer": "26",
-          "demand": "6"
-        },
-        {
-          "type": "port",
-          "name": "Johannesburg",
-          "longitude": "28.0833333",
-          "latitude": "-26.2",
-          "offer": "8",
-          "demand": "4"
-        },
-        {
-          "type": "port",
-          "name": "Durban",
-          "longitude": "31.0166667",
-          "latitude": "-29.85",
-          "offer": "19",
-          "demand": "19"
-        },
-        {
-          "type": "port",
-          "name": "Cape Town",
-          "longitude": "18.4166667",
-          "latitude": "-33.9166667",
-          "offer": "5",
-          "demand": "24"
-        },
-        {
-          "type": "port",
-          "name": "Lusaka",
-          "longitude": "28.2833333",
-          "latitude": "-15.4166667",
-          "offer": "18",
-          "demand": "11"
-        },
-        {
-          "type": "port",
-          "name": "Harare",
-          "longitude": "31.0447222",
-          "latitude": "-17.8177778",
-          "offer": "3",
-          "demand": "9"
-        }
-,	{
-		"type": "legs",
-		"name": "leg0",
-		"stops": [
-       {
-        "name": "port00",
-        "port": {
-          "_reference": "Damascus"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "14"
-      },
-       {
-        "name": "port01",
-        "port": {
-          "_reference": "Lima"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "7"
-      },
-       {
-        "name": "port02",
-        "port": {
-          "_reference": "Jaipur"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "1"
-      },
-       {
-        "name": "port03",
-        "port": {
-          "_reference": "Nova Iguaçu"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "7"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg1",
-		"stops": [
-       {
-        "name": "port10",
-        "port": {
-          "_reference": "Taiyuan"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "1"
-      },
-       {
-        "name": "port11",
-        "port": {
-          "_reference": "Melbourne"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "6"
-      },
-       {
-        "name": "port12",
-        "port": {
-          "_reference": "Ä€gra"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "5"
-      },
-       {
-        "name": "port13",
-        "port": {
-          "_reference": "Pusan"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "2"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg2",
-		"stops": [
-       {
-        "name": "port20",
-        "port": {
-          "_reference": "Toronto"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "6"
-      },
-       {
-        "name": "port21",
-        "port": {
-          "_reference": "Dublin"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "0"
-      },
-       {
-        "name": "port22",
-        "port": {
-          "_reference": "Odesa"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "6"
-      },
-       {
-        "name": "port23",
-        "port": {
-          "_reference": "N�sik"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "6"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg3",
-		"stops": [
-       {
-        "name": "port30",
-        "port": {
-          "_reference": "Damascus"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "8"
-      },
-       {
-        "name": "port31",
-        "port": {
-          "_reference": "Odesa"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "2"
-      },
-       {
-        "name": "port32",
-        "port": {
-          "_reference": "Liuyang"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "1"
-      },
-       {
-        "name": "port33",
-        "port": {
-          "_reference": "Aleppo"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "10"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg4",
-		"stops": [
-       {
-        "name": "port40",
-        "port": {
-          "_reference": "Datong"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "6"
-      },
-       {
-        "name": "port41",
-        "port": {
-          "_reference": "Guangzhou"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "14"
-      },
-       {
-        "name": "port42",
-        "port": {
-          "_reference": "Goiânia"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "14"
-      },
-       {
-        "name": "port43",
-        "port": {
-          "_reference": "K�npur"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "7"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg5",
-		"stops": [
-       {
-        "name": "port50",
-        "port": {
-          "_reference": "Taiyuan"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "10"
-      },
-       {
-        "name": "port51",
-        "port": {
-          "_reference": "Medellín"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "8"
-      },
-       {
-        "name": "port52",
-        "port": {
-          "_reference": "Yekaterinburg"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "12"
-      },
-       {
-        "name": "port53",
-        "port": {
-          "_reference": "Taiyuan"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "9"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg6",
-		"stops": [
-       {
-        "name": "port60",
-        "port": {
-          "_reference": "Mecca"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "5"
-      },
-       {
-        "name": "port61",
-        "port": {
-          "_reference": "Ciudad Juárez"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "6"
-      },
-       {
-        "name": "port62",
-        "port": {
-          "_reference": "Bekasi"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "5"
-      },
-       {
-        "name": "port63",
-        "port": {
-          "_reference": "Minsk"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "10"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg7",
-		"stops": [
-       {
-        "name": "port70",
-        "port": {
-          "_reference": "Tianjin"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "0"
-      },
-       {
-        "name": "port71",
-        "port": {
-          "_reference": "Ã…Å’saka"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "9"
-      },
-       {
-        "name": "port72",
-        "port": {
-          "_reference": "Kuala Lumpur"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "8"
-      },
-       {
-        "name": "port73",
-        "port": {
-          "_reference": "Ciudad Nezahualcóyotl"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "2"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg8",
-		"stops": [
-       {
-        "name": "port80",
-        "port": {
-          "_reference": "Ciudad Juárez"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "13"
-      },
-       {
-        "name": "port81",
-        "port": {
-          "_reference": "Fukuoka"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "10"
-      },
-       {
-        "name": "port82",
-        "port": {
-          "_reference": "Donetsk"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "12"
-      },
-       {
-        "name": "port83",
-        "port": {
-          "_reference": "Barranquilla"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "10"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg9",
-		"stops": [
-       {
-        "name": "port90",
-        "port": {
-          "_reference": "Aleppo"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "5"
-      },
-       {
-        "name": "port91",
-        "port": {
-          "_reference": "Jabalpur"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "3"
-      },
-       {
-        "name": "port92",
-        "port": {
-          "_reference": "Donetsk"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "1"
-      },
-       {
-        "name": "port93",
-        "port": {
-          "_reference": "Xinyang"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "8"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg10",
-		"stops": [
-       {
-        "name": "port100",
-        "port": {
-          "_reference": "Luoyang"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "11"
-      },
-       {
-        "name": "port101",
-        "port": {
-          "_reference": "Benares"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "7"
-      },
-       {
-        "name": "port102",
-        "port": {
-          "_reference": "Adana"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "7"
-      },
-       {
-        "name": "port103",
-        "port": {
-          "_reference": "Taegu"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "4"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg11",
-		"stops": [
-       {
-        "name": "port110",
-        "port": {
-          "_reference": "Kinshasa"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "13"
-      },
-       {
-        "name": "port111",
-        "port": {
-          "_reference": "Belém"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "2"
-      },
-       {
-        "name": "port112",
-        "port": {
-          "_reference": "Amman"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "11"
-      },
-       {
-        "name": "port113",
-        "port": {
-          "_reference": "Mexico City"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "2"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg12",
-		"stops": [
-       {
-        "name": "port120",
-        "port": {
-          "_reference": "Chicago"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "13"
-      },
-       {
-        "name": "port121",
-        "port": {
-          "_reference": "Barranquilla"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "6"
-      },
-       {
-        "name": "port122",
-        "port": {
-          "_reference": "Kawasaki"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "10"
-      },
-       {
-        "name": "port123",
-        "port": {
-          "_reference": "Shantou"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "9"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg13",
-		"stops": [
-       {
-        "name": "port130",
-        "port": {
-          "_reference": "Kiev"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "7"
-      },
-       {
-        "name": "port131",
-        "port": {
-          "_reference": "Camayenne"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "5"
-      },
-       {
-        "name": "port132",
-        "port": {
-          "_reference": "Al Başrah al Qadīmah"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "13"
-      },
-       {
-        "name": "port133",
-        "port": {
-          "_reference": "Perth"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "7"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg14",
-		"stops": [
-       {
-        "name": "port140",
-        "port": {
-          "_reference": "Riyadh"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "12"
-      },
-       {
-        "name": "port141",
-        "port": {
-          "_reference": "Casablanca"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "1"
-      },
-       {
-        "name": "port142",
-        "port": {
-          "_reference": "Kano"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "5"
-      },
-       {
-        "name": "port143",
-        "port": {
-          "_reference": "Mashhad"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "3"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg15",
-		"stops": [
-       {
-        "name": "port150",
-        "port": {
-          "_reference": "Al Mawşil al Jadīdah"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "4"
-      },
-       {
-        "name": "port151",
-        "port": {
-          "_reference": "Taegu"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "7"
-      },
-       {
-        "name": "port152",
-        "port": {
-          "_reference": "Bhop�l"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "10"
-      },
-       {
-        "name": "port153",
-        "port": {
-          "_reference": "Campinas"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "14"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg16",
-		"stops": [
-       {
-        "name": "port160",
-        "port": {
-          "_reference": "Kar�chi"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "6"
-      },
-       {
-        "name": "port161",
-        "port": {
-          "_reference": "Milano"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "6"
-      },
-       {
-        "name": "port162",
-        "port": {
-          "_reference": "Lima"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "2"
-      },
-       {
-        "name": "port163",
-        "port": {
-          "_reference": "Calcutta"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "6"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg17",
-		"stops": [
-       {
-        "name": "port170",
-        "port": {
-          "_reference": "Sapporo"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "1"
-      },
-       {
-        "name": "port171",
-        "port": {
-          "_reference": "Sapporo"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "7"
-      },
-       {
-        "name": "port172",
-        "port": {
-          "_reference": "Medellín"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "0"
-      },
-       {
-        "name": "port173",
-        "port": {
-          "_reference": "Amman"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "13"
-      }
-      ]
-	}
-,	{
-		"type": "legs",
-		"name": "leg18",
-		"stops": [
-       {
-        "name": "port180",
-        "port": {
-          "_reference": "Depok"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "12"
-      },
-       {
-        "name": "port181",
-        "port": {
-          "_reference": "Jieyang"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "1"
-      },
-       {
-        "name": "port182",
-        "port": {
-          "_reference": "Faisal�b�d"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "8"
-      },
-       {
-        "name": "port183",
-        "port": {
-          "_reference": "Ã…Å’saka"
-        },
-        "date": "Thu Nov 25 08:20:25 GMT+0100 2010",
-        "capacity": "7"
-      }
-      ]
-	}
-  ]
-}
diff --git a/dojox/geo/openlayers/tests/ecr/data/mapDataFixed.json b/dojox/geo/openlayers/tests/ecr/data/mapDataFixed.json
deleted file mode 100644
index fdc4bbe..0000000
--- a/dojox/geo/openlayers/tests/ecr/data/mapDataFixed.json
+++ /dev/null
@@ -1,41467 +0,0 @@
-{
-   "identifier": "name",
-   "items": [
-      {
-         "demand": 15,
-         "latitude": "+25.2833328",
-         "longitude": "+51.5333328",
-         "name": "QADOH",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+43.5499992",
-         "longitude": "+10.3166666",
-         "name": "ITLIV",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+45.4636889",
-         "longitude": "+9.1881408",
-         "name": "ITMIL",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+44.6470798",
-         "longitude": "+10.92522",
-         "name": "ITMOD",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+62.4666672",
-         "longitude": "+6.1666665",
-         "name": "NOAES",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+40.8333321",
-         "longitude": "+14.2500000",
-         "name": "ITNAP",
-         "offer": 26,
-         "type": "port"
-      },
-      {
-         "demand": 32,
-         "latitude": "+57.6969943",
-         "longitude": "+11.9865",
-         "name": "SEGOT",
-         "offer": 50,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+60.4000015",
-         "longitude": "+5.3166666",
-         "name": "NOBGO",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+56.0499992",
-         "longitude": "+12.6833334",
-         "name": "SEHEL",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 88,
-         "latitude": "+6.9166665",
-         "longitude": "+79.8499985",
-         "name": "LKCMB",
-         "offer": 64,
-         "type": "port"
-      },
-      {
-         "demand": 8,
-         "latitude": "+45.4095683",
-         "longitude": "+11.8765886",
-         "name": "ITPDA",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+41.0000000",
-         "longitude": "+28.9666672",
-         "name": "TRIST",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+38.4166679",
-         "longitude": "+27.1499996",
-         "name": "TRIZM",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 24,
-         "latitude": "+31.8500004",
-         "longitude": "-116.5999985",
-         "name": "MXESE",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+40.6833344",
-         "longitude": "+14.7666664",
-         "name": "ITSAL",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+44.1166649",
-         "longitude": "+9.8333330",
-         "name": "ITSPE",
-         "offer": 44,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+36.7500000",
-         "longitude": "+3.0500000",
-         "name": "DZALG",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+20.67359",
-         "longitude": "-103.343803",
-         "name": "MXGDL",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+25.6333332",
-         "longitude": "+51.9166679",
-         "name": "QAMES",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+36.7166672",
-         "longitude": "+34.6333351",
-         "name": "TRMER",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+45.4333344",
-         "longitude": "+12.3333330",
-         "name": "ITVCE",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+20",
-         "longitude": "+41.45",
-         "name": "SADMN",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+58.1500015",
-         "longitude": "+8.0000000",
-         "name": "NOKRS",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+19.3999996",
-         "longitude": "-99.0500031",
-         "name": "MXMEX",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+47.3690239",
-         "longitude": "+8.5380326",
-         "name": "CHZRH",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+25.6666667",
-         "longitude": "-100.3",
-         "name": "MXMTY",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+39.3166656",
-         "longitude": "+18.0499992",
-         "name": "SESTO",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+34.3333321",
-         "longitude": "+132.4499969",
-         "name": "JPHIJ",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "-34.5833321",
-         "longitude": "-58.6666679",
-         "name": "ARBUE",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+33.5999985",
-         "longitude": "+130.4166718",
-         "name": "JPHKT",
-         "offer": 18,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+34.3852029",
-         "longitude": "+132.4552927",
-         "name": "JPHSA",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 10,
-         "latitude": "+47.5000000",
-         "longitude": "+19.0333328",
-         "name": "HUBUD",
-         "offer": 6,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+34.0666656",
-         "longitude": "+133.0166626",
-         "name": "JPIMB",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+59.9000015",
-         "longitude": "+10.7166662",
-         "name": "NOOSL",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+50.0878114",
-         "longitude": "+14.4204598",
-         "name": "CZPRG",
-         "offer": 6,
-         "type": "port"
-      },
-      {
-         "demand": 29,
-         "latitude": "+21.4666672",
-         "longitude": "+39.1666679",
-         "name": "SAJED",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+37.9500008",
-         "longitude": "+139.0666656",
-         "name": "JPKIJ",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+36.6166649",
-         "longitude": "+136.6000061",
-         "name": "JPKNZ",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+55.7166672",
-         "longitude": "+21.1166668",
-         "name": "LTKLJ",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+33.9000015",
-         "longitude": "+130.9666595",
-         "name": "JPMOJ",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+24.4666672",
-         "longitude": "+54.3666649",
-         "name": "AEAUH",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 98,
-         "latitude": "+35.0499992",
-         "longitude": "+136.8500061",
-         "name": "JPNGO",
-         "offer": 50,
-         "type": "port"
-      },
-      {
-         "demand": 25,
-         "latitude": "+34.6500015",
-         "longitude": "+135.3999939",
-         "name": "JPOSA",
-         "offer": 28,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+25.2666664",
-         "longitude": "+55.2666664",
-         "name": "AEDXB",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 52,
-         "latitude": "+25.1499996",
-         "longitude": "+121.7333298",
-         "name": "TWKEL",
-         "offer": 22,
-         "type": "port"
-      },
-      {
-         "demand": 57,
-         "latitude": "+22.6166668",
-         "longitude": "+120.2500000",
-         "name": "TWKHH",
-         "offer": 94,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+35.0166664",
-         "longitude": "+138.5333405",
-         "name": "JPSMZ",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 162,
-         "latitude": "+51.2166672",
-         "longitude": "+4.4166665",
-         "name": "BEANR",
-         "offer": 150,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+49.2268877",
-         "longitude": "+17.6689027",
-         "name": "CZZLN",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+50.7666664",
-         "longitude": "+3.4333334",
-         "name": "BEAVL",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+34.3499985",
-         "longitude": "+134.0500031",
-         "name": "JPTAK",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+34.0000000",
-         "longitude": "+131.8000031",
-         "name": "JPTKY",
-         "offer": 16,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+19.0499992",
-         "longitude": "-104.3000031",
-         "name": "MXZLO",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+42.6333351",
-         "longitude": "+141.6333313",
-         "name": "JPTMK",
-         "offer": 6,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+36.7500000",
-         "longitude": "+137.2333374",
-         "name": "JPTOY",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 127,
-         "latitude": "+35.6666679",
-         "longitude": "+139.7666626",
-         "name": "JPTYO",
-         "offer": 206,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+36.7999992",
-         "longitude": "+10.1999998",
-         "name": "TNTUN",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 43,
-         "latitude": "+34.6833344",
-         "longitude": "+135.1666718",
-         "name": "JPUKB",
-         "offer": 48,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+24.7666664",
-         "longitude": "+67.3499985",
-         "name": "PKBQM",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 3,
-         "latitude": "-26.8999996",
-         "longitude": "-48.6500015",
-         "name": "BRITJ",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 25,
-         "latitude": "+20.8666668",
-         "longitude": "+106.6666641",
-         "name": "VNHPH",
-         "offer": 34,
-         "type": "port"
-      },
-      {
-         "demand": 77,
-         "latitude": "+25.0000000",
-         "longitude": "+55.0499992",
-         "name": "AEJEA",
-         "offer": 34,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+44.1833344",
-         "longitude": "+28.6499996",
-         "name": "ROCND",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+25.3333340",
-         "longitude": "+56.3499985",
-         "name": "AEKLF",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+34.9500008",
-         "longitude": "+136.6333313",
-         "name": "JPYKK",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 22,
-         "latitude": "+35.4500008",
-         "longitude": "+139.6499939",
-         "name": "JPYOK",
-         "offer": 18,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+44.2527405",
-         "longitude": "-91.5015432",
-         "name": "USADI",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+35.2219971",
-         "longitude": "-101.8312969",
-         "name": "USAMA",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 24,
-         "latitude": "+33.7489954",
-         "longitude": "-84.3879824",
-         "name": "USATL",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 9,
-         "latitude": "+39.2833328",
-         "longitude": "-76.5833359",
-         "name": "USBAL",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 78,
-         "latitude": "+24.2833328",
-         "longitude": "+120.5000000",
-         "name": "TWTXG",
-         "offer": 22,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+36.1666679",
-         "longitude": "-86.7833328",
-         "name": "USBNA",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 43,
-         "latitude": "+42.3833351",
-         "longitude": "-71.0500031",
-         "name": "USBOS",
-         "offer": 10,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+42.8864468",
-         "longitude": "-78.8783689",
-         "name": "USBUF",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 86,
-         "latitude": "+41.850033",
-         "longitude": "-87.6500523",
-         "name": "USCHI",
-         "offer": 106,
-         "type": "port"
-      },
-      {
-         "demand": 25,
-         "latitude": "+32.7833328",
-         "longitude": "-79.9333344",
-         "name": "USCHS",
-         "offer": 70,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+41.5000000",
-         "longitude": "-81.6666641",
-         "name": "USCLE",
-         "offer": 12,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+35.2270869",
-         "longitude": "-80.8431267",
-         "name": "USCLT",
-         "offer": 26,
-         "type": "port"
-      },
-      {
-         "demand": 9,
-         "latitude": "+39.9611755",
-         "longitude": "-82.9987942",
-         "name": "USCMH",
-         "offer": 8,
-         "type": "port"
-      },
-      {
-         "demand": 10,
-         "latitude": "+39.1361111",
-         "longitude": "-84.5030556",
-         "name": "USCVG",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 55,
-         "latitude": "+32.802955",
-         "longitude": "-96.769923",
-         "name": "USDAL",
-         "offer": 86,
-         "type": "port"
-      },
-      {
-         "demand": 14,
-         "latitude": "+39.7391536",
-         "longitude": "-104.9847034",
-         "name": "USDEN",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 8,
-         "latitude": "+42.3166656",
-         "longitude": "-83.0333328",
-         "name": "USDET",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 3,
-         "latitude": "-32.1666679",
-         "longitude": "-52.0833321",
-         "name": "BRRIG",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "-22.9166660",
-         "longitude": "-43.2000008",
-         "name": "BRRIO",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+24.8333340",
-         "longitude": "+67.0000000",
-         "name": "PKKHI",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 9,
-         "latitude": "+31.7587198",
-         "longitude": "-106.4869314",
-         "name": "USELP",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 21,
-         "latitude": "-23.9333324",
-         "longitude": "-46.3333321",
-         "name": "BRSSZ",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 12,
-         "latitude": "+10.7666664",
-         "longitude": "+106.6666641",
-         "name": "VNSGN",
-         "offer": 30,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+52.5166664",
-         "longitude": "+13.3833332",
-         "name": "DEBER",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+52.0230618",
-         "longitude": "+8.5330723",
-         "name": "DEBFE",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 27,
-         "latitude": "+53.0833321",
-         "longitude": "+8.7833338",
-         "name": "DEBRE",
-         "offer": 56,
-         "type": "port"
-      },
-      {
-         "demand": 51,
-         "latitude": "+53.5499992",
-         "longitude": "+8.5833330",
-         "name": "DEBRV",
-         "offer": 18,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+3.8000000",
-         "longitude": "+98.7166672",
-         "name": "IDBLW",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+40.2666664",
-         "longitude": "-76.8833313",
-         "name": "USHAR",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+23.4664962",
-         "longitude": "+116.7558582",
-         "name": "CNCHG",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+30.4997849",
-         "longitude": "+105.5809722",
-         "name": "CNCHS",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 57,
-         "latitude": "+29.7500000",
-         "longitude": "-95.3333359",
-         "name": "USHOU",
-         "offer": 40,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+34.7303688",
-         "longitude": "-86.5861037",
-         "name": "USHSV",
-         "offer": 10,
-         "type": "port"
-      },
-      {
-         "demand": 188,
-         "latitude": "+22.4666672",
-         "longitude": "+113.8833313",
-         "name": "CNCWN",
-         "offer": 18,
-         "type": "port"
-      },
-      {
-         "demand": 86,
-         "latitude": "+34.2333336",
-         "longitude": "-77.9499969",
-         "name": "USILM",
-         "offer": 12,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+39.7683765",
-         "longitude": "-86.1580423",
-         "name": "USIND",
-         "offer": 8,
-         "type": "port"
-      },
-      {
-         "demand": 52,
-         "latitude": "+38.9166679",
-         "longitude": "+121.6833344",
-         "name": "CNDLC",
-         "offer": 54,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+51.2333336",
-         "longitude": "+6.7833333",
-         "name": "DEDUS",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+32.2987573",
-         "longitude": "-90.1848103",
-         "name": "USJAN",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+30.3833332",
-         "longitude": "-81.6333313",
-         "name": "USJAX",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 10,
-         "latitude": "+39.0997265",
-         "longitude": "-94.5785667",
-         "name": "USKCK",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+26.0499992",
-         "longitude": "+119.3000031",
-         "name": "CNFOC",
-         "offer": 32,
-         "type": "port"
-      },
-      {
-         "demand": 8,
-         "latitude": "+50.1166649",
-         "longitude": "+8.6833334",
-         "name": "DEFRA",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+38.7166672",
-         "longitude": "-9.1333332",
-         "name": "PTLIS",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 25,
-         "latitude": "+33.7166672",
-         "longitude": "-118.2666702",
-         "name": "USLAX",
-         "offer": 6,
-         "type": "port"
-      },
-      {
-         "demand": 57,
-         "latitude": "+33.7666664",
-         "longitude": "-118.1833344",
-         "name": "USLGB",
-         "offer": 2100,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+49.2188587",
-         "longitude": "+8.3695841",
-         "name": "DEGER",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+27.5000000",
-         "longitude": "-99.4833298",
-         "name": "USLRD",
-         "offer": 14,
-         "type": "port"
-      },
-      {
-         "demand": 127,
-         "latitude": "+53.5499992",
-         "longitude": "+9.9666662",
-         "name": "DEHAM",
-         "offer": 390,
-         "type": "port"
-      },
-      {
-         "demand": 55,
-         "latitude": "+35.1495343",
-         "longitude": "-90.0489801",
-         "name": "USMEM",
-         "offer": 28,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+25.7833328",
-         "longitude": "-80.1833344",
-         "name": "USMIA",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+60.1698125",
-         "longitude": "+24.9382401",
-         "name": "FIHEL",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 233,
-         "latitude": "+22.4060834",
-         "longitude": "+114.1201536",
-         "name": "CNHKG",
-         "offer": 136,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+30.6833324",
-         "longitude": "-88.0500031",
-         "name": "USMOB",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 14,
-         "latitude": "+44.8833351",
-         "longitude": "-93.1999969",
-         "name": "USMSP",
-         "offer": 8,
-         "type": "port"
-      },
-      {
-         "demand": 9,
-         "latitude": "+29.9647222",
-         "longitude": "-90.0705556",
-         "name": "USMSY",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 19,
-         "latitude": "+23.0833340",
-         "longitude": "+113.4166641",
-         "name": "CNHUA",
-         "offer": 354,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+23.11103",
-         "longitude": "+114.417053",
-         "name": "CNHUI",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+44.8333321",
-         "longitude": "-0.5666667",
-         "name": "FRBOD",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 16,
-         "latitude": "+51.0333328",
-         "longitude": "-114.0666656",
-         "name": "CACAL",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 168,
-         "latitude": "+40.7000008",
-         "longitude": "-74.0000000",
-         "name": "USNYC",
-         "offer": 248,
-         "type": "port"
-      },
-      {
-         "demand": 98,
-         "latitude": "+37.7999992",
-         "longitude": "-122.2833328",
-         "name": "USOAK",
-         "offer": 58,
-         "type": "port"
-      },
-      {
-         "demand": 9,
-         "latitude": "+41.254006",
-         "longitude": "-95.999258",
-         "name": "USOMA",
-         "offer": 6,
-         "type": "port"
-      },
-      {
-         "demand": 12,
-         "latitude": "+36.8499985",
-         "longitude": "-76.3166656",
-         "name": "USORF",
-         "offer": 60,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+5.4166665",
-         "longitude": "+100.3333359",
-         "name": "MYPEN",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 43,
-         "latitude": "+1.4333334",
-         "longitude": "+103.9000015",
-         "name": "MYPGU",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 72,
-         "latitude": "-6.0999999",
-         "longitude": "+106.8666687",
-         "name": "IDJKT",
-         "offer": 198,
-         "type": "port"
-      },
-      {
-         "demand": 53,
-         "latitude": "+3.0000000",
-         "longitude": "+101.4000015",
-         "name": "MYPKG",
-         "offer": 48,
-         "type": "port"
-      },
-      {
-         "demand": 17,
-         "latitude": "+45.5666656",
-         "longitude": "-122.7333298",
-         "name": "USPDX",
-         "offer": 114,
-         "type": "port"
-      },
-      {
-         "demand": 1,
-         "latitude": "+39.9000015",
-         "longitude": "-75.1333313",
-         "name": "USPHL",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+33.4483771",
-         "longitude": "-112.0740373",
-         "name": "USPHX",
-         "offer": 6,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+40.4406248",
-         "longitude": "-79.9958864",
-         "name": "USPIT",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+60.4666672",
-         "longitude": "+26.9500008",
-         "name": "FIKTK",
-         "offer": 30,
-         "type": "port"
-      },
-      {
-         "demand": 16,
-         "latitude": "+43.4333344",
-         "longitude": "+4.9333334",
-         "name": "FRFOS",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+48.1500015",
-         "longitude": "+11.5833330",
-         "name": "DEMUC",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+29.4241219",
-         "longitude": "-98.4936282",
-         "name": "USSAT",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 24,
-         "latitude": "+32.0833321",
-         "longitude": "-81.0833359",
-         "name": "USSAV",
-         "offer": 22,
-         "type": "port"
-      },
-      {
-         "demand": 12,
-         "latitude": "+23.028778",
-         "longitude": "+113.142996",
-         "name": "CNNAH",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 8,
-         "latitude": "+42.91389",
-         "longitude": "-82.60389",
-         "name": "USSDF",
-         "offer": 8,
-         "type": "port"
-      },
-      {
-         "demand": 393,
-         "latitude": "+29.868336",
-         "longitude": "+121.54399",
-         "name": "CNNBO",
-         "offer": 102,
-         "type": "port"
-      },
-      {
-         "demand": 206,
-         "latitude": "+47.6333351",
-         "longitude": "-122.3333359",
-         "name": "USSEA",
-         "offer": 60,
-         "type": "port"
-      },
-      {
-         "demand": 17,
-         "latitude": "+40.7607793",
-         "longitude": "-111.8910474",
-         "name": "USSLC",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 67,
-         "latitude": "+32.0499992",
-         "longitude": "+118.7833328",
-         "name": "CNNKG",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 9,
-         "latitude": "+38.646991",
-         "longitude": "-90.224967",
-         "name": "USSTL",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+32.0000000",
-         "longitude": "+120.8166656",
-         "name": "CNNTG",
-         "offer": 16,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+49.45052",
-         "longitude": "+11.08048",
-         "name": "DENUE",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 80,
-         "latitude": "+47.2500000",
-         "longitude": "-122.4166641",
-         "name": "USTIW",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 12,
-         "latitude": "+11.6000004",
-         "longitude": "+104.9000015",
-         "name": "KHPNH",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 43,
-         "latitude": "+49.4833336",
-         "longitude": "+0.1166667",
-         "name": "FRLEH",
-         "offer": 78,
-         "type": "port"
-      },
-      {
-         "demand": 1158,
-         "latitude": "+31.2500000",
-         "longitude": "+121.5000000",
-         "name": "CNSHA",
-         "offer": 166,
-         "type": "port"
-      },
-      {
-         "demand": 8,
-         "latitude": "+48.7771056",
-         "longitude": "+9.1807688",
-         "name": "DESTR",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+23.0357173",
-         "longitude": "+113.235757",
-         "name": "CNSXC",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 10,
-         "latitude": "+45.5000000",
-         "longitude": "-73.5500031",
-         "name": "CAMTR",
-         "offer": 16,
-         "type": "port"
-      },
-      {
-         "demand": 21,
-         "latitude": "-6.9666667",
-         "longitude": "+110.4833298",
-         "name": "IDSRG",
-         "offer": 6,
-         "type": "port"
-      },
-      {
-         "demand": 8,
-         "latitude": "-7.289166",
-         "longitude": "+112.734398",
-         "name": "IDSUB",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 244,
-         "latitude": "+36.0833321",
-         "longitude": "+120.3000031",
-         "name": "CNTAO",
-         "offer": 148,
-         "type": "port"
-      },
-      {
-         "demand": 43,
-         "latitude": "+32.456584",
-         "longitude": "+119.923046",
-         "name": "CNTAZ",
-         "offer": 6,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+48.8666649",
-         "longitude": "+2.3333333",
-         "name": "FRPAR",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+30.5833340",
-         "longitude": "+114.3166656",
-         "name": "CNWUH",
-         "offer": 8,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+17.9666672",
-         "longitude": "-76.8000031",
-         "name": "JMKIN",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 299,
-         "latitude": "+38.9833336",
-         "longitude": "+117.4833298",
-         "name": "CNXGG",
-         "offer": 114,
-         "type": "port"
-      },
-      {
-         "demand": 1,
-         "latitude": "+50.447234",
-         "longitude": "-104.618013",
-         "name": "CAREG",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 25,
-         "latitude": "+24.4500008",
-         "longitude": "+118.0666656",
-         "name": "CNXMN",
-         "offer": 32,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+48.1117611",
-         "longitude": "-1.6802654",
-         "name": "FRRNS",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+52.129267",
-         "longitude": "-106.670253",
-         "name": "CASAK",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 744,
-         "latitude": "+22.563732",
-         "longitude": "+114.240232",
-         "name": "CNYIT",
-         "offer": 32,
-         "type": "port"
-      },
-      {
-         "demand": 213,
-         "latitude": "+51.9166679",
-         "longitude": "+4.5000000",
-         "name": "NLRTM",
-         "offer": 308,
-         "type": "port"
-      },
-      {
-         "demand": 34,
-         "latitude": "+26.2166672",
-         "longitude": "+111.5999985",
-         "name": "CNYZO",
-         "offer": 6,
-         "type": "port"
-      },
-      {
-         "demand": 10,
-         "latitude": "+31.9666672",
-         "longitude": "+120.4000015",
-         "name": "CNZJG",
-         "offer": 6,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+54.3499985",
-         "longitude": "+18.6499996",
-         "name": "PLGDN",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+54.5166664",
-         "longitude": "+18.5333328",
-         "name": "PLGDY",
-         "offer": 14,
-         "type": "port"
-      },
-      {
-         "demand": 16,
-         "latitude": "+43.6333351",
-         "longitude": "-79.3833313",
-         "name": "CATOR",
-         "offer": 48,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+59.4333344",
-         "longitude": "+24.7333336",
-         "name": "EETLL",
-         "offer": 12,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+51.5499992",
-         "longitude": "+5.0666666",
-         "name": "NLTLB",
-         "offer": 10,
-         "type": "port"
-      },
-      {
-         "demand": 16,
-         "latitude": "+27.2000008",
-         "longitude": "+56.2500000",
-         "name": "IRBND",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 125,
-         "latitude": "+49.2833328",
-         "longitude": "-123.1166687",
-         "name": "CAVAN",
-         "offer": 66,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+37.9333344",
-         "longitude": "+23.6333332",
-         "name": "GRPIR",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+49.895452",
-         "longitude": "-97.138273",
-         "name": "CAWNP",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 9,
-         "latitude": "+53.540941",
-         "longitude": "-113.493698",
-         "name": "CAYEA",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+40.6333351",
-         "longitude": "+22.9500008",
-         "name": "GRSKG",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 25,
-         "latitude": "+41.3499985",
-         "longitude": "+2.1666667",
-         "name": "ESBCN",
-         "offer": 36,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+43.2833328",
-         "longitude": "-2.9166667",
-         "name": "ESBIO",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+10.3000002",
-         "longitude": "+123.9000015",
-         "name": "PHCEB",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+53.3499985",
-         "longitude": "-6.2166667",
-         "name": "IEDUB",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 103,
-         "latitude": "+1.2666667",
-         "longitude": "+103.8333359",
-         "name": "SGSIN",
-         "offer": 98,
-         "type": "port"
-      },
-      {
-         "demand": 9,
-         "latitude": "+53.4166679",
-         "longitude": "+14.5500002",
-         "name": "PLSZZ",
-         "offer": 8,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+18.9666672",
-         "longitude": "+72.8166656",
-         "name": "INBOM",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+22.5666676",
-         "longitude": "+88.3499985",
-         "name": "INCCU",
-         "offer": 36,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+9.9666662",
-         "longitude": "+76.2333298",
-         "name": "INCOK",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+28.635308",
-         "longitude": "+77.22496",
-         "name": "INDEL",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+52.2296756",
-         "longitude": "+21.0122287",
-         "name": "PLWRP",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+28.1000004",
-         "longitude": "-15.4166670",
-         "name": "ESLPA",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+40.4166909",
-         "longitude": "-3.7003454",
-         "name": "ESMAD",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+35.5166664",
-         "longitude": "+35.7666664",
-         "name": "SYLTK",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 92,
-         "latitude": "+14.5833330",
-         "longitude": "+120.9666672",
-         "name": "PHMNL",
-         "offer": 204,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+51.9000015",
-         "longitude": "-8.4666662",
-         "name": "IEORK",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+37.4500008",
-         "longitude": "+126.6166687",
-         "name": "KRINC",
-         "offer": 34,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+23.0333328",
-         "longitude": "+70.2166672",
-         "name": "INIXY",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+36.5999985",
-         "longitude": "+127.3000031",
-         "name": "KRJCW",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 103,
-         "latitude": "+34.9333344",
-         "longitude": "+127.6999969",
-         "name": "KRKAN",
-         "offer": 48,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+36.1166649",
-         "longitude": "+128.3333282",
-         "name": "KRKUM",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+16.7666664",
-         "longitude": "+96.1666641",
-         "name": "MMRGN",
-         "offer": 14,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+56.9666672",
-         "longitude": "+24.1000004",
-         "name": "LVRIX",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+59.8833351",
-         "longitude": "+30.2500000",
-         "name": "RULED",
-         "offer": 46,
-         "type": "port"
-      },
-      {
-         "demand": 10,
-         "latitude": "+13.0833330",
-         "longitude": "+80.2833328",
-         "name": "INMAA",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 19,
-         "latitude": "+56.1500015",
-         "longitude": "+10.2166662",
-         "name": "DKAAR",
-         "offer": 34,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+22.7500000",
-         "longitude": "+69.6999969",
-         "name": "INMUN",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 5,
-         "latitude": "+3.684167",
-         "longitude": "+125.526108",
-         "name": "INNAH",
-         "offer": 8,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+34.8833351",
-         "longitude": "+35.8833351",
-         "name": "SYTTS",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 6,
-         "latitude": "+55.7000008",
-         "longitude": "+12.6166668",
-         "name": "DKCPH",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 6,
-         "latitude": "+39.4500008",
-         "longitude": "-0.3000000",
-         "name": "ESVLC",
-         "offer": 48,
-         "type": "port"
-      },
-      {
-         "demand": 406,
-         "latitude": "+35.1333351",
-         "longitude": "+129.0500031",
-         "name": "KRPUS",
-         "offer": 297,
-         "type": "port"
-      },
-      {
-         "demand": 14,
-         "latitude": "+23.6138199",
-         "longitude": "+58.5922413",
-         "name": "OMMCT",
-         "offer": 8,
-         "type": "port"
-      },
-      {
-         "demand": 14,
-         "latitude": "+8.7833338",
-         "longitude": "+78.1333313",
-         "name": "INTUT",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+13.6999998",
-         "longitude": "+100.5666656",
-         "name": "THBKK",
-         "offer": 50,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+48.2092062",
-         "longitude": "+16.3727778",
-         "name": "ATVIE",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+54.9833336",
-         "longitude": "-5.9166665",
-         "name": "GBBEL",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+52.4829614",
-         "longitude": "-1.893592",
-         "name": "GBBHM",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+29.3500004",
-         "longitude": "+47.9333344",
-         "name": "KWKWI",
-         "offer": 50,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+13.0833330",
-         "longitude": "+100.8833313",
-         "name": "THLCH",
-         "offer": 40,
-         "type": "port"
-      },
-      {
-         "demand": 12,
-         "latitude": "+51.9500008",
-         "longitude": "+1.3166666",
-         "name": "GBFXT",
-         "offer": 206,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+13.7218664",
-         "longitude": "+100.7765055",
-         "name": "THLKG",
-         "offer": 10,
-         "type": "port"
-      },
-      {
-         "demand": 2,
-         "latitude": "+55.8666649",
-         "longitude": "-4.2833333",
-         "name": "GBGLW",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+31.1833324",
-         "longitude": "+29.8666668",
-         "name": "EGALY",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 17,
-         "latitude": "-27.4666672",
-         "longitude": "+153.0166626",
-         "name": "AUBNE",
-         "offer": 6,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+33.6166649",
-         "longitude": "-7.5999999",
-         "name": "MACAS",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+31.4166660",
-         "longitude": "+31.8166676",
-         "name": "EGDAM",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 6,
-         "latitude": "+53.7999992",
-         "longitude": "-1.5833333",
-         "name": "GBLBA",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+53.4166679",
-         "longitude": "-3.0000000",
-         "name": "GBLIV",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 6,
-         "latitude": "+51.3507588",
-         "longitude": "+1.3745662",
-         "name": "GBMAN",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+7.1999998",
-         "longitude": "+100.5999985",
-         "name": "THSGZ",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+34.6833344",
-         "longitude": "+33.0499992",
-         "name": "CYLMS",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 43,
-         "latitude": "-37.8166656",
-         "longitude": "+144.9666595",
-         "name": "AUMEL",
-         "offer": 22,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+51.4333344",
-         "longitude": "+0.7000000",
-         "name": "GBTHP",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 4,
-         "latitude": "+51.4500008",
-         "longitude": "+0.3333333",
-         "name": "GBTIL",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+25.930414",
-         "longitude": "+50.637772",
-         "name": "BHBAH",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 6,
-         "latitude": "+31.2500000",
-         "longitude": "+32.2999992",
-         "name": "EGPSD",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 16,
-         "latitude": "-33.8499985",
-         "longitude": "+151.1999969",
-         "name": "AUSYD",
-         "offer": 32,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+43.5999985",
-         "longitude": "+13.5166664",
-         "name": "ITAOI",
-         "offer": 2,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+47.5499992",
-         "longitude": "+7.5666666",
-         "name": "CHBSL",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+13.9166670",
-         "longitude": "-90.7833328",
-         "name": "GTPRQ",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+45.5499992",
-         "longitude": "+13.7333336",
-         "name": "SIKOP",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+46.0514263",
-         "longitude": "+14.5059655",
-         "name": "SILJU",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "demand": 0,
-         "latitude": "+38.4333344",
-         "longitude": "+15.8999996",
-         "name": "ITGIT",
-         "offer": 0,
-         "type": "port"
-      },
-      {
-         "demand": 14,
-         "latitude": "+44.4166679",
-         "longitude": "+8.9499998",
-         "name": "ITGOA",
-         "offer": 4,
-         "type": "port"
-      },
-      {
-         "demand": 15,
-         "latitude": "+33.8333321",
-         "longitude": "+35.4833336",
-         "name": "LBBEY",
-         "offer": 20,
-         "type": "port"
-      },
-      {
-         "capacity": 200,
-         "name": "32663",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BEANR0",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR1"
-               }
-            },
-            {
-               "date": "2010-12-09",
-               "name": "EGPSD0",
-               "port": {
-                  "_reference": "EGPSD",
-                  "name": "EGPSD1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "32700",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BEANR2",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR3"
-               }
-            },
-            {
-               "date": "2010-12-09",
-               "name": "ITSPE0",
-               "port": {
-                  "_reference": "ITSPE",
-                  "name": "ITSPE1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "33421",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAO0",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO1"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "CNHKG0",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "35311",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EGALY0",
-               "port": {
-                  "_reference": "EGALY",
-                  "name": "EGALY1"
-               }
-            },
-            {
-               "date": "2010-12-09",
-               "name": "TRIST0",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "35430",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EGPSD2",
-               "port": {
-                  "_reference": "EGPSD",
-                  "name": "EGPSD3"
-               }
-            },
-            {
-               "date": "2010-12-09",
-               "name": "ESBCN0",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "35718",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESLPA0",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA1"
-               }
-            },
-            {
-               "date": "2010-12-09",
-               "name": "GBFXT0",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "39230",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITSPE2",
-               "port": {
-                  "_reference": "ITSPE",
-                  "name": "ITSPE3"
-               }
-            },
-            {
-               "date": "2010-12-09",
-               "name": "ESBCN2",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "39539",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPOSA0",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA1"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "JPYOK0",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "40298",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MYPKG0",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG1"
-               }
-            },
-            {
-               "date": "2010-12-09",
-               "name": "PKBQM0",
-               "port": {
-                  "_reference": "PKBQM",
-                  "name": "PKBQM1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "41495",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ROCND0",
-               "port": {
-                  "_reference": "ROCND",
-                  "name": "ROCND1"
-               }
-            },
-            {
-               "date": "2010-12-09",
-               "name": "FRFOS0",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43336",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEDXB0",
-               "port": {
-                  "_reference": "AEDXB",
-                  "name": "AEDXB1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "AEAUH0",
-               "port": {
-                  "_reference": "AEAUH",
-                  "name": "AEAUH1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43337",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEDXB2",
-               "port": {
-                  "_reference": "AEDXB",
-                  "name": "AEDXB3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "AEJEA0",
-               "port": {
-                  "_reference": "AEJEA",
-                  "name": "AEJEA1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43338",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEDXB4",
-               "port": {
-                  "_reference": "AEDXB",
-                  "name": "AEDXB5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "AEKLF0",
-               "port": {
-                  "_reference": "AEKLF",
-                  "name": "AEKLF1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43347",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEJEA2",
-               "port": {
-                  "_reference": "AEJEA",
-                  "name": "AEJEA3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "AEAUH2",
-               "port": {
-                  "_reference": "AEAUH",
-                  "name": "AEAUH3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43348",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEJEA4",
-               "port": {
-                  "_reference": "AEJEA",
-                  "name": "AEJEA5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "AEDXB6",
-               "port": {
-                  "_reference": "AEDXB",
-                  "name": "AEDXB7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43358",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEKLF2",
-               "port": {
-                  "_reference": "AEKLF",
-                  "name": "AEKLF3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "AEAUH4",
-               "port": {
-                  "_reference": "AEAUH",
-                  "name": "AEAUH5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43359",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEKLF4",
-               "port": {
-                  "_reference": "AEKLF",
-                  "name": "AEKLF5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "AEDXB8",
-               "port": {
-                  "_reference": "AEDXB",
-                  "name": "AEDXB9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43362",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEKLF6",
-               "port": {
-                  "_reference": "AEKLF",
-                  "name": "AEKLF7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IRBND0",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43373",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE0",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR4",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43383",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE2",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV0",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43388",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE4",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC0",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43389",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE6",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DENUE0",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43394",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE8",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "EETLL0",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43408",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE10",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR0",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43416",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE12",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLIV0",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43419",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE14",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL0",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43426",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE16",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITGIT0",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43431",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE18",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP0",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43450",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE20",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS0",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43456",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE22",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SIKOP0",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43464",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AUBNE0",
-               "port": {
-                  "_reference": "AUBNE",
-                  "name": "AUBNE1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "AUMEL0",
-               "port": {
-                  "_reference": "AUMEL",
-                  "name": "AUMEL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43468",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AUSYD0",
-               "port": {
-                  "_reference": "AUSYD",
-                  "name": "AUSYD1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "AUBNE2",
-               "port": {
-                  "_reference": "AUBNE",
-                  "name": "AUBNE3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43469",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AUSYD2",
-               "port": {
-                  "_reference": "AUSYD",
-                  "name": "AUSYD3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "AUMEL2",
-               "port": {
-                  "_reference": "AUMEL",
-                  "name": "AUMEL3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43530",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BEANR6",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITSAL0",
-               "port": {
-                  "_reference": "ITSAL",
-                  "name": "ITSAL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43562",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BEAVL0",
-               "port": {
-                  "_reference": "BEAVL",
-                  "name": "BEAVL1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "BEANR8",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43587",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BEAVL2",
-               "port": {
-                  "_reference": "BEAVL",
-                  "name": "BEAVL3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESBIO0",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43622",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BEAVL4",
-               "port": {
-                  "_reference": "BEAVL",
-                  "name": "BEAVL5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITSPE4",
-               "port": {
-                  "_reference": "ITSPE",
-                  "name": "ITSPE5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43654",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BHBAH0",
-               "port": {
-                  "_reference": "BHBAH",
-                  "name": "BHBAH1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "AEJEA6",
-               "port": {
-                  "_reference": "AEJEA",
-                  "name": "AEJEA7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43656",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BHBAH2",
-               "port": {
-                  "_reference": "BHBAH",
-                  "name": "BHBAH3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IRBND2",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43658",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BHBAH4",
-               "port": {
-                  "_reference": "BHBAH",
-                  "name": "BHBAH5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "OMMCT0",
-               "port": {
-                  "_reference": "OMMCT",
-                  "name": "OMMCT1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43668",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BRRIG0",
-               "port": {
-                  "_reference": "BRRIG",
-                  "name": "BRRIG1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "BRITJ0",
-               "port": {
-                  "_reference": "BRITJ",
-                  "name": "BRITJ1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43669",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BRRIG2",
-               "port": {
-                  "_reference": "BRRIG",
-                  "name": "BRRIG3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "BRRIO0",
-               "port": {
-                  "_reference": "BRRIO",
-                  "name": "BRRIO1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43672",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BRRIO2",
-               "port": {
-                  "_reference": "BRRIO",
-                  "name": "BRRIO3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "BRITJ2",
-               "port": {
-                  "_reference": "BRITJ",
-                  "name": "BRITJ3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43676",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BRSSZ0",
-               "port": {
-                  "_reference": "BRSSZ",
-                  "name": "BRSSZ1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "BRITJ4",
-               "port": {
-                  "_reference": "BRITJ",
-                  "name": "BRITJ5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43683",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CACAL0",
-               "port": {
-                  "_reference": "CACAL",
-                  "name": "CACAL1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CAVAN0",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43686",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAMTR0",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CACAL2",
-               "port": {
-                  "_reference": "CACAL",
-                  "name": "CACAL3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43688",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAMTR2",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CASAK0",
-               "port": {
-                  "_reference": "CASAK",
-                  "name": "CASAK1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43690",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAMTR4",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CAVAN2",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43691",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAMTR6",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CAWNP0",
-               "port": {
-                  "_reference": "CAWNP",
-                  "name": "CAWNP1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43692",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAMTR8",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CAYEA0",
-               "port": {
-                  "_reference": "CAYEA",
-                  "name": "CAYEA1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43707",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR0",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CACAL4",
-               "port": {
-                  "_reference": "CACAL",
-                  "name": "CACAL5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43710",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR2",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CASAK2",
-               "port": {
-                  "_reference": "CASAK",
-                  "name": "CASAK3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43711",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR4",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CAVAN4",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43712",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR6",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CAWNP2",
-               "port": {
-                  "_reference": "CAWNP",
-                  "name": "CAWNP3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43713",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR8",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CAYEA2",
-               "port": {
-                  "_reference": "CAYEA",
-                  "name": "CAYEA3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43714",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR10",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MXMEX0",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43721",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR12",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "USSEA0",
-               "port": {
-                  "_reference": "USSEA",
-                  "name": "USSEA1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43731",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAVAN6",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "USCHI0",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43737",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAWNP4",
-               "port": {
-                  "_reference": "CAWNP",
-                  "name": "CAWNP5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CACAL6",
-               "port": {
-                  "_reference": "CACAL",
-                  "name": "CACAL7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43743",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAWNP6",
-               "port": {
-                  "_reference": "CAWNP",
-                  "name": "CAWNP7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CAYEA4",
-               "port": {
-                  "_reference": "CAYEA",
-                  "name": "CAYEA5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43768",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHBSL0",
-               "port": {
-                  "_reference": "CHBSL",
-                  "name": "CHBSL1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR0",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43818",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHBSL2",
-               "port": {
-                  "_reference": "CHBSL",
-                  "name": "CHBSL3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NLRTM0",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43852",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHZRH0",
-               "port": {
-                  "_reference": "CHZRH",
-                  "name": "CHZRH1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV2",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43878",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHZRH2",
-               "port": {
-                  "_reference": "CHZRH",
-                  "name": "CHZRH3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRRNS0",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43900",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHZRH4",
-               "port": {
-                  "_reference": "CHZRH",
-                  "name": "CHZRH5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP2",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43933",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG0",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCHS0",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43934",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG2",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCWN0",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43935",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG4",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNDLC0",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43943",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG6",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNTG0",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43944",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG8",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNSHA0",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43948",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG10",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ0",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43952",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG12",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYZO0",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43968",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHS2",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ2",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "43977",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCWN2",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNDLC2",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44004",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNDLC4",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNBO0",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44005",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNDLC6",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNKG0",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44009",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNDLC8",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAO2",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44012",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNDLC10",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNXGG0",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44015",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNDLC12",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYZO2",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44018",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC0",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCHS4",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44019",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC2",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCWN4",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44024",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC4",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNAH0",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44026",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC6",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNKG2",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44027",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC8",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNTG2",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44028",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC10",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNSHA2",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44031",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC12",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAO4",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44032",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC14",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ4",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44033",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC16",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNWUH0",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44036",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC18",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYIT0",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44037",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC20",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC21"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYZO4",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44039",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG2",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCHS6",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44047",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG4",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNKG4",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44048",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG6",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNTG4",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44052",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG8",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAO6",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44053",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG10",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ6",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44057",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG12",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYIT2",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44060",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA0",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCHS8",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44061",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA2",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCWN6",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44066",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA4",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNAH2",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44067",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA6",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNBO2",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44068",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA8",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNKG6",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44069",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA10",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNTG6",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44070",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA12",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNSHA4",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44073",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA14",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAO8",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44074",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA16",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ8",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44075",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA18",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNXGG2",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44077",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA20",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA21"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYIT4",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44078",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA22",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA23"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYZO6",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44079",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA24",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA25"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNZJG0",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44082",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUI0",
-               "port": {
-                  "_reference": "CNHUI",
-                  "name": "CNHUI1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCWN8",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44098",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUI2",
-               "port": {
-                  "_reference": "CNHUI",
-                  "name": "CNHUI3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYIT6",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44110",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNAH4",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNKG8",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44114",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNAH6",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAO10",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44115",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNAH8",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ10",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44123",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO4",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCHS10",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44131",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO6",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNTG8",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44136",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO8",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ12",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44156",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNKG10",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAO12",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44165",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG10",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCWN10",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44171",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG12",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNAH10",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44174",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG14",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNSHA6",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44179",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG16",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNWUH2",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44180",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG18",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNXGG4",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44182",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG20",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG21"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYIT8",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44184",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG22",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG23"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNZJG2",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44207",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC0",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCHS12",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44208",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC2",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCWN12",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44213",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC4",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNAH12",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44215",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC6",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNKG12",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44216",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC8",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNTG24",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44220",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC10",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ14",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44221",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC12",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNWUH4",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44222",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC14",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNXGG6",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44225",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC16",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYZO8",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44226",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC18",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNZJG4",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44229",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC0"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCWN14",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44237",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC1",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC2"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNKG14",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44238",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC3",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC4"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNTG26",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44239",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC5",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC6"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNSHA8",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44241",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC7",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC8"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAO14",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44242",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC9",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC10"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ16",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44244",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC11",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC12"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNXGG8",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44245",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC13",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC14"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYIT10",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44246",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC15",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC16"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYZO10",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44247",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC17",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC18"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNZJG6",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44278",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAZ18",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNBO10",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44291",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH6",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCHS14",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44292",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH8",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCWN16",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44300",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH10",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNKG16",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44302",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH12",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNSHA10",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44304",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH14",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAO16",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44305",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH16",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ20",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44308",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH18",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYIT12",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44320",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXGG10",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNKG18",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44325",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXGG12",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAO18",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44330",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXGG14",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYZO12",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44333",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN0",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCHS16",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44334",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN2",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCWN18",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44335",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN4",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNDLC14",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44340",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN6",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNBO12",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44341",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN8",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNKG20",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44342",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN10",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNTG28",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44346",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN12",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAO20",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44347",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN14",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ22",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44348",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN16",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNWUH20",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44349",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN18",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNXGG16",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44396",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG8",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCHS18",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44397",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG10",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNCWN20",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44403",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG12",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNBO14",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44404",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG14",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNKG22",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44405",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG16",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNNTG30",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44406",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG18",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNSHA12",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44409",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG20",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG21"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAO22",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44410",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG22",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG23"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNTAZ24",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44411",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG24",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG25"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNWUH22",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44414",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG26",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG27"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYIT14",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44415",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG28",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG29"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "CNYZO14",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44422",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CYLMS0",
-               "port": {
-                  "_reference": "CYLMS",
-                  "name": "CYLMS1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN0",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44425",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CYLMS2",
-               "port": {
-                  "_reference": "CYLMS",
-                  "name": "CYLMS3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRE0",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44426",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CYLMS4",
-               "port": {
-                  "_reference": "CYLMS",
-                  "name": "CYLMS5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV4",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44439",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CYLMS6",
-               "port": {
-                  "_reference": "CYLMS",
-                  "name": "CYLMS7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "EGDAM0",
-               "port": {
-                  "_reference": "EGDAM",
-                  "name": "EGDAM1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44517",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZPRG0",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV6",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44534",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZPRG2",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESLPA2",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44547",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZPRG4",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBFXT2",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44590",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZPRG6",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SIKOP2",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44608",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZZLN2",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV8",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44635",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZZLN4",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB0"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44674",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZZLN6",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PLWRP0",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44675",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZZLN8",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS2",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44684",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZZLN10",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SYTTS0",
-               "port": {
-                  "_reference": "SYTTS",
-                  "name": "SYTTS1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44694",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBER0",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CYLMS8",
-               "port": {
-                  "_reference": "CYLMS",
-                  "name": "CYLMS9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44791",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBFE0",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEDUS0",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44792",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBFE2",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEFRA0",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44871",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE2",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ATVIE24",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44879",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE4",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEBER2",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44881",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE6",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEBRV10",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44882",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE8",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEDUS2",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44883",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE10",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEFRA2",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44886",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE12",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEMUC2",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44887",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE14",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DENUE2",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44888",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE16",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DESTR2",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44949",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE18",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ROCND2",
-               "port": {
-                  "_reference": "ROCND",
-                  "name": "ROCND3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "44961",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE20",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "TRMER0",
-               "port": {
-                  "_reference": "TRMER",
-                  "name": "TRMER1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45021",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRV12",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA0",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45044",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRV14",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SESTO0",
-               "port": {
-                  "_reference": "SESTO",
-                  "name": "SESTO1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45060",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEDUS4",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN12",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45086",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEDUS6",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRFOS2",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45109",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEDUS8",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMIL0",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45139",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEDUS10",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SYTTS2",
-               "port": {
-                  "_reference": "SYTTS",
-                  "name": "SYTTS3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45159",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEFRA4",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEMUC4",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45177",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEFRA6",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRFOS4",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45234",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEFRA8",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "TRMER2",
-               "port": {
-                  "_reference": "TRMER",
-                  "name": "TRMER3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45246",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEGER0",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEBRV16",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45250",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEGER2",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEMUC6",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45301",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEGER4",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MACAS0",
-               "port": {
-                  "_reference": "MACAS",
-                  "name": "MACAS1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45306",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEGER6",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NOKRS0",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45323",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEGER8",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "TRIST2",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45428",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEMUC8",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEBRV18",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45454",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEMUC10",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB1",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB2"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45463",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEMUC12",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL2",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45489",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEMUC14",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NOOSL0",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45501",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEMUC16",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SILJU0",
-               "port": {
-                  "_reference": "SILJU",
-                  "name": "SILJU1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45502",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEMUC18",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SYLTK0",
-               "port": {
-                  "_reference": "SYLTK",
-                  "name": "SYLTK1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45511",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DENUE4",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CHBSL4",
-               "port": {
-                  "_reference": "CHBSL",
-                  "name": "CHBSL5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45519",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DENUE6",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEBRV20",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45521",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DENUE8",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEFRA10",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45572",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DENUE10",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LTKLJ0",
-               "port": {
-                  "_reference": "LTKLJ",
-                  "name": "LTKLJ1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45602",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DESTR4",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CHBSL6",
-               "port": {
-                  "_reference": "CHBSL",
-                  "name": "CHBSL7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45603",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DESTR6",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CHZRH6",
-               "port": {
-                  "_reference": "CHZRH",
-                  "name": "CHZRH7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45604",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DESTR8",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CYLMS10",
-               "port": {
-                  "_reference": "CYLMS",
-                  "name": "CYLMS11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45610",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DESTR10",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEBRV22",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45612",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DESTR12",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DEFRA12",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45631",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DESTR14",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRBOD0",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45644",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DESTR16",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTHP0",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45679",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DESTR18",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SEGOT0",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45690",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR0",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ATVIE26",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45691",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR2",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR10",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45699",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR4",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE4",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45701",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR6",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV24",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45705",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR8",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEHAM0",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45708",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR10",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR20",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45709",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR12",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "DKCPH0",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45715",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR14",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESBCN4",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45718",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR16",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESMAD0",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45719",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR18",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESVLC0",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45725",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR20",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR2",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45728",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR22",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBEL0",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45729",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR24",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBHM0",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45731",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR26",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBGLW0",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45732",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR28",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLBA0",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45736",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR30",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL4",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45739",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR32",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "HUBUD0",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45740",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR34",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IEDUB0",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45744",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR36",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITGOA0",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45748",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR38",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP4",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45749",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR40",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA2",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45767",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR42",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS4",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45773",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR44",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR45"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SIKOP4",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45783",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKCPH2",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEAVL6",
-               "port": {
-                  "_reference": "BEAVL",
-                  "name": "BEAVL7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45830",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKCPH4",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "HUBUD2",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45832",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKCPH6",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IEORK0",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45868",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKCPH8",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "TNTUN0",
-               "port": {
-                  "_reference": "TNTUN",
-                  "name": "TNTUN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45883",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DZALG0",
-               "port": {
-                  "_reference": "DZALG",
-                  "name": "DZALG1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV26",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45890",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DZALG2",
-               "port": {
-                  "_reference": "DZALG",
-                  "name": "DZALG3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR22",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45901",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DZALG4",
-               "port": {
-                  "_reference": "DZALG",
-                  "name": "DZALG5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESVLC2",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45903",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DZALG6",
-               "port": {
-                  "_reference": "DZALG",
-                  "name": "DZALG7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FIKTK0",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45911",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DZALG8",
-               "port": {
-                  "_reference": "DZALG",
-                  "name": "DZALG9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBHM2",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45963",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL2",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ATVIE28",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45964",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL4",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR12",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45969",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL6",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZPRG8",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45970",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL8",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN14",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45971",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL10",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER4",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45972",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL12",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE6",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45974",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL14",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV28",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45975",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL16",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEDUS12",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45976",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL18",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEFRA14",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45977",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL20",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER10",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45979",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL22",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC20",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45989",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL24",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESBIO2",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45991",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL26",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESMAD2",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45992",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL28",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESVLC4",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45995",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL30",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRBOD2",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "45999",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL32",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRRNS2",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46000",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL34",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB3",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB4"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46002",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL36",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBHM4",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46005",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL38",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLBA2",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46007",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL40",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBMAN0",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46009",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL42",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL6",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46012",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL44",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL45"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "HUBUD4",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46019",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL46",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL47"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMIL2",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46021",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL48",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL49"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP6",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46022",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EETLL50",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL51"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA4",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46122",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EGALY2",
-               "port": {
-                  "_reference": "EGALY",
-                  "name": "EGALY3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NLTLB0",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46132",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EGALY4",
-               "port": {
-                  "_reference": "EGALY",
-                  "name": "EGALY5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ROCND4",
-               "port": {
-                  "_reference": "ROCND",
-                  "name": "ROCND5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46156",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EGDAM2",
-               "port": {
-                  "_reference": "EGDAM",
-                  "name": "EGDAM3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV30",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46225",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EGDAM4",
-               "port": {
-                  "_reference": "EGDAM",
-                  "name": "EGDAM5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SEGOT2",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46250",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EGPSD4",
-               "port": {
-                  "_reference": "EGPSD",
-                  "name": "EGPSD5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER12",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46290",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EGPSD6",
-               "port": {
-                  "_reference": "EGPSD",
-                  "name": "EGPSD7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITGOA2",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46359",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBCN6",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRBOD4",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46415",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBCN8",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "TRIST4",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46419",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBIO4",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR14",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46424",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBIO6",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZPRG10",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46444",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBIO8",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ESBCN10",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46447",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBIO10",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ESVLC6",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46494",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBIO12",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PLWRP2",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46516",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESLPA4",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN16",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46532",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESLPA6",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "EGALY6",
-               "port": {
-                  "_reference": "EGALY",
-                  "name": "EGALY7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46555",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESLPA8",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL8",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46579",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESLPA10",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NOBGO0",
-               "port": {
-                  "_reference": "NOBGO",
-                  "name": "NOBGO1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46601",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESMAD4",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR16",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46606",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESMAD6",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZPRG12",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46616",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESMAD8",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC22",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46619",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESMAD10",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKAAR46",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46626",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESMAD12",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ESBCN12",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46629",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESMAD14",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ESVLC8",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46698",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESVLC10",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN18",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46707",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESVLC12",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC24",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46783",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL0",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR18",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46788",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL2",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZPRG14",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46789",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL4",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN20",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46790",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL6",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER6",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46793",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL8",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV32",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46794",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL10",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEDUS14",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46795",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL12",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEFRA16",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46796",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL14",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER14",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46798",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL16",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC26",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46799",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL18",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DENUE12",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46800",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL20",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR24",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46801",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL22",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKAAR48",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR49"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46808",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL24",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESBCN14",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46812",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL26",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESVLC14",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46817",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL28",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR4",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46820",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL30",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBEL2",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46823",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL32",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBGLW2",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46824",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL34",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLBA4",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46831",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL36",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "HUBUD6",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46832",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL38",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IEDUB2",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46838",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL40",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMIL4",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46839",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL42",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMOD0",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46840",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL44",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL45"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP8",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46841",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL46",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL47"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA6",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46859",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL48",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL49"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS6",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46863",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL50",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL51"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SEHEL0",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46867",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL52",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL53"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SYLTK2",
-               "port": {
-                  "_reference": "SYLTK",
-                  "name": "SYLTK3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46874",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK2",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR20",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46879",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK4",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZPRG16",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46880",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK6",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN22",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46881",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK8",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER8",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46882",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK10",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE8",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46884",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK12",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV34",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46885",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK14",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEDUS16",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46886",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK16",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEFRA18",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46887",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK18",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER16",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46889",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK20",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC28",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46890",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK22",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DENUE14",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46891",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK24",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR26",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46896",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK26",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "EGALY8",
-               "port": {
-                  "_reference": "EGALY",
-                  "name": "EGALY9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46900",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK28",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESBIO14",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46905",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK30",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRBOD6",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46908",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK32",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR6",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46909",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK34",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRRNS4",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46910",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK36",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB5",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB6"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46911",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK38",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBEL4",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46914",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK40",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBGLW4",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46915",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK42",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLBA6",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46917",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK44",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK45"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBMAN2",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46919",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK46",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK47"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL10",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46922",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK48",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK49"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "HUBUD8",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46923",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK50",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK51"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IEDUB4",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46929",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK52",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK53"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMIL6",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46931",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK54",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK55"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP10",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46932",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK56",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK57"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA8",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46935",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK58",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK59"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITVCE0",
-               "port": {
-                  "_reference": "ITVCE",
-                  "name": "ITVCE1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46950",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK60",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK61"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS8",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46997",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRBOD8",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "FRFOS6",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "46999",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRBOD10",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "FRPAR8",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47000",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRBOD12",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "FRRNS6",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47001",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRBOD14",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "FRSXB7",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB8"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47018",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRBOD16",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITGOA4",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47041",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRBOD18",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS10",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47088",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRFOS8",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "FRBOD20",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47096",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRFOS10",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBGLW6",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47101",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRFOS12",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL12",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47148",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRLEH0",
-               "port": {
-                  "_reference": "FRLEH",
-                  "name": "FRLEH1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEAVL8",
-               "port": {
-                  "_reference": "BEAVL",
-                  "name": "BEAVL9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47261",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRPAR10",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "EGDAM6",
-               "port": {
-                  "_reference": "EGDAM",
-                  "name": "EGDAM7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47271",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRPAR12",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "FRFOS14",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47317",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRPAR14",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SEGOT4",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47345",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRRNS8",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DENUE16",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47362",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRRNS10",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "FRFOS16",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47364",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRRNS12",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "FRPAR16",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47421",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRSXB9",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB10"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEAVL10",
-               "port": {
-                  "_reference": "BEAVL",
-                  "name": "BEAVL11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47553",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBEL6",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBLIV2",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47600",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBEL8",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "TRMER4",
-               "port": {
-                  "_reference": "TRMER",
-                  "name": "TRMER5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47602",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBHM6",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR22",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47612",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBHM8",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV36",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47638",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBHM10",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRRNS14",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47699",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT4",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN24",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47720",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT6",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESLPA12",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47730",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT8",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB11",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB12"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47842",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBGLW8",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA10",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "47857",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBGLW10",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PLGDY0",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48004",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBLIV4",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBBEL10",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48007",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBLIV6",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBGLW12",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48008",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBLIV8",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBLBA8",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48036",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBLIV10",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NOKRS2",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48078",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBMAN4",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "EETLL52",
-               "port": {
-                  "_reference": "EETLL",
-                  "name": "EETLL53"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48098",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBMAN6",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBGLW14",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48099",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBMAN8",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBLBA10",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48100",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBMAN10",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBLIV12",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48102",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBMAN12",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBTIL14",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48187",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP2",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBBHM12",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48190",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP4",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBLBA12",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48191",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP6",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBLIV14",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48193",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP8",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBTIL16",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48200",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP10",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITGIT2",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48277",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTIL18",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "GBBEL12",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48301",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTIL20",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LBBEY0",
-               "port": {
-                  "_reference": "LBBEY",
-                  "name": "LBBEY1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48340",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRPIR0",
-               "port": {
-                  "_reference": "GRPIR",
-                  "name": "GRPIR1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV38",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48375",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRPIR2",
-               "port": {
-                  "_reference": "GRPIR",
-                  "name": "GRPIR3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTHP12",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48421",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRSKG0",
-               "port": {
-                  "_reference": "GRSKG",
-                  "name": "GRSKG1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR24",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48428",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRSKG2",
-               "port": {
-                  "_reference": "GRSKG",
-                  "name": "GRSKG3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER10",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48431",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRSKG4",
-               "port": {
-                  "_reference": "GRSKG",
-                  "name": "GRSKG5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV40",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48459",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRSKG6",
-               "port": {
-                  "_reference": "GRSKG",
-                  "name": "GRSKG7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBEL14",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48462",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRSKG8",
-               "port": {
-                  "_reference": "GRSKG",
-                  "name": "GRSKG9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBGLW16",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48469",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRSKG10",
-               "port": {
-                  "_reference": "GRSKG",
-                  "name": "GRSKG11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "HUBUD10",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48492",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRSKG12",
-               "port": {
-                  "_reference": "GRSKG",
-                  "name": "GRSKG13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NOOSL2",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48497",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRSKG14",
-               "port": {
-                  "_reference": "GRSKG",
-                  "name": "GRSKG15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS12",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48524",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "HUBUD12",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEDUS18",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48547",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "HUBUD14",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRLEH2",
-               "port": {
-                  "_reference": "FRLEH",
-                  "name": "FRLEH3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48548",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "HUBUD16",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR18",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48604",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW0",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "IDSRG0",
-               "port": {
-                  "_reference": "IDSRG",
-                  "name": "IDSRG1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48609",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW2",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INDEL0",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48614",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW4",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INTUT0",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48616",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW6",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KHPNH0",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48618",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW8",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MMRGN0",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48619",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW10",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPEN0",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48620",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW12",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU0",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48621",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW14",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG2",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48625",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW16",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PKKHI0",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48626",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW18",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN0",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48631",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW20",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNHPH0",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48632",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW22",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN0",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48634",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT0",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "IDSRG2",
-               "port": {
-                  "_reference": "IDSRG",
-                  "name": "IDSRG3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48635",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT2",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "IDSUB0",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48639",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT4",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INDEL2",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48642",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT6",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMUN0",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48643",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT8",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INNAH0",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48644",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT10",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INTUT2",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48646",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT12",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KHPNH2",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48647",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT14",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LKCMB0",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48648",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT16",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MMRGN2",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48649",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT18",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPEN2",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 22,
-         "name": "48650",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT20",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU2",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48651",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT22",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG4",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48655",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT24",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PKKHI2",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48656",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT26",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN2",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48661",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT28",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNHPH2",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48662",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT30",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN2",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48669",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSRG4",
-               "port": {
-                  "_reference": "IDSRG",
-                  "name": "IDSRG5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INDEL4",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48676",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSRG6",
-               "port": {
-                  "_reference": "IDSRG",
-                  "name": "IDSRG7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KHPNH4",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48678",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSRG8",
-               "port": {
-                  "_reference": "IDSRG",
-                  "name": "IDSRG9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MMRGN4",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48680",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSRG10",
-               "port": {
-                  "_reference": "IDSRG",
-                  "name": "IDSRG11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU4",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48681",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSRG12",
-               "port": {
-                  "_reference": "IDSRG",
-                  "name": "IDSRG13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG6",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48691",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSRG14",
-               "port": {
-                  "_reference": "IDSRG",
-                  "name": "IDSRG15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNHPH4",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48692",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSRG16",
-               "port": {
-                  "_reference": "IDSRG",
-                  "name": "IDSRG17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN4",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48694",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB2",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "IDJKT32",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48702",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB4",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMUN2",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48703",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB6",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INNAH2",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48706",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB8",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KHPNH6",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48707",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB10",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LKCMB2",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48708",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB12",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MMRGN6",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48709",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB14",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPEN4",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48710",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB16",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU6",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48711",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB18",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG8",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48715",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB20",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PKKHI4",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48716",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB22",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN4",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48721",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB24",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNHPH6",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48722",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDSUB26",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN6",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48724",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB6",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR26",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48731",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB8",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER12",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48732",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB10",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE10",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48734",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB12",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV42",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48739",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB14",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC30",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48740",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB16",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DENUE18",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48749",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB18",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESBCN16",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48753",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB20",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESVLC16",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48759",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB22",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR20",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48781",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB24",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP12",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48788",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB26",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LVRIX0",
-               "port": {
-                  "_reference": "LVRIX",
-                  "name": "LVRIX1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48800",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB28",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS14",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48808",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB30",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SYLTK4",
-               "port": {
-                  "_reference": "SYLTK",
-                  "name": "SYLTK5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48815",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK2",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR28",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48820",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK4",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZPRG18",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48821",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK6",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN26",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48825",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK8",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV44",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48826",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK10",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEDUS20",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48827",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK12",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEFRA20",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48828",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK14",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER18",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48830",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK16",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC32",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48831",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK18",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DENUE20",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48833",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK20",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKAAR50",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR51"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48840",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK22",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESBCN18",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48844",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK24",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESVLC18",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48850",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK26",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR22",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48852",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK28",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB13",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB14"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48861",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK30",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL22",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48865",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK32",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK33"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "IEDUB32",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48870",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK34",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMIL8",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48871",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK36",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMOD2",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48873",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK38",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA12",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48895",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK40",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SEHEL2",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48902",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK42",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "TRIST6",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48911",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INBOM0",
-               "port": {
-                  "_reference": "INBOM",
-                  "name": "INBOM1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INDEL6",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48914",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INBOM2",
-               "port": {
-                  "_reference": "INBOM",
-                  "name": "INBOM3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INMUN4",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48941",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCCU0",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INDEL8",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48944",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCCU2",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INMUN6",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48945",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCCU4",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INNAH4",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48946",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCCU6",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INTUT4",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48950",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCCU8",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MMRGN8",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48952",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCCU10",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU8",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48958",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCCU12",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN6",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48964",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCCU14",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN8",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48971",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCOK0",
-               "port": {
-                  "_reference": "INCOK",
-                  "name": "INCOK1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INDEL10",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48976",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCOK2",
-               "port": {
-                  "_reference": "INCOK",
-                  "name": "INCOK3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INTUT6",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48982",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCOK4",
-               "port": {
-                  "_reference": "INCOK",
-                  "name": "INCOK5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU10",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48990",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCOK6",
-               "port": {
-                  "_reference": "INCOK",
-                  "name": "INCOK7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "THLCH0",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48993",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCOK8",
-               "port": {
-                  "_reference": "INCOK",
-                  "name": "INCOK9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNHPH8",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "48994",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCOK10",
-               "port": {
-                  "_reference": "INCOK",
-                  "name": "INCOK11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN10",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49008",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INDEL12",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KHPNH8",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49013",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INDEL14",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG10",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49016",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INDEL16",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PKBQM2",
-               "port": {
-                  "_reference": "PKBQM",
-                  "name": "PKBQM3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49032",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INIXY0",
-               "port": {
-                  "_reference": "INIXY",
-                  "name": "INIXY1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INDEL18",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49042",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INIXY2",
-               "port": {
-                  "_reference": "INIXY",
-                  "name": "INIXY3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU12",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49054",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INIXY4",
-               "port": {
-                  "_reference": "INIXY",
-                  "name": "INIXY5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN12",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49062",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA0",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INDEL20",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49064",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA2",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INMUN8",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49065",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA4",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INNAH6",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49066",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA6",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "INTUT8",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49068",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA8",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KHPNH10",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49069",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA10",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LKCMB4",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49070",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA12",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MMRGN10",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49073",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA14",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG12",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49083",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA16",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNHPH10",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49205",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IRBND4",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "AEAUH6",
-               "port": {
-                  "_reference": "AEAUH",
-                  "name": "AEAUH7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49207",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IRBND6",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "AEJEA8",
-               "port": {
-                  "_reference": "AEJEA",
-                  "name": "AEJEA9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49208",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IRBND8",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "AEKLF8",
-               "port": {
-                  "_reference": "AEKLF",
-                  "name": "AEKLF9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49210",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IRBND10",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KWKWI0",
-               "port": {
-                  "_reference": "KWKWI",
-                  "name": "KWKWI1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49211",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IRBND12",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "OMMCT2",
-               "port": {
-                  "_reference": "OMMCT",
-                  "name": "OMMCT3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49215",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IRBND14",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SAJED0",
-               "port": {
-                  "_reference": "SAJED",
-                  "name": "SAJED1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49227",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITAOI0",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV46",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49270",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITAOI2",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITGOA6",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49274",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITAOI4",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITNAP14",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49275",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITAOI6",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITPDA14",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49299",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITAOI8",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SIKOP6",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49397",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGIT4",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "TRMER6",
-               "port": {
-                  "_reference": "TRMER",
-                  "name": "TRMER7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49432",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGOA8",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRFOS18",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49452",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGOA10",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITGIT6",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49469",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGOA12",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NOKRS4",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49634",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITMIL10",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITGIT8",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49638",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITMIL12",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITNAP16",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49639",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITMIL14",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITPDA16",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49725",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITMOD4",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITGIT10",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49729",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITMOD6",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITNAP18",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49790",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITNAP20",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESLPA14",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49916",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITPDA18",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LBBEY2",
-               "port": {
-                  "_reference": "LBBEY",
-                  "name": "LBBEY3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "49945",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITSAL2",
-               "port": {
-                  "_reference": "ITSAL",
-                  "name": "ITSAL3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR30",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50021",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITSAL4",
-               "port": {
-                  "_reference": "ITSAL",
-                  "name": "ITSAL5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS16",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50024",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITSAL6",
-               "port": {
-                  "_reference": "ITSAL",
-                  "name": "ITSAL7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SEGOT6",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50044",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITSPE6",
-               "port": {
-                  "_reference": "ITSPE",
-                  "name": "ITSPE7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE12",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50108",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITSPE8",
-               "port": {
-                  "_reference": "ITSPE",
-                  "name": "ITSPE9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PLGDN0",
-               "port": {
-                  "_reference": "PLGDN",
-                  "name": "PLGDN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50180",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITVCE2",
-               "port": {
-                  "_reference": "ITVCE",
-                  "name": "ITVCE3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITGIT12",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50181",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITVCE4",
-               "port": {
-                  "_reference": "ITVCE",
-                  "name": "ITVCE5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITGOA14",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50183",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITVCE6",
-               "port": {
-                  "_reference": "ITVCE",
-                  "name": "ITVCE7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITMIL16",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50185",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITVCE8",
-               "port": {
-                  "_reference": "ITVCE",
-                  "name": "ITVCE9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "ITNAP22",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50219",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHIJ0",
-               "port": {
-                  "_reference": "JPHIJ",
-                  "name": "JPHIJ1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPHSA0",
-               "port": {
-                  "_reference": "JPHSA",
-                  "name": "JPHSA1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50224",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHIJ2",
-               "port": {
-                  "_reference": "JPHIJ",
-                  "name": "JPHIJ3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPNGO0",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50226",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHIJ4",
-               "port": {
-                  "_reference": "JPHIJ",
-                  "name": "JPHIJ5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ0",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50228",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHIJ6",
-               "port": {
-                  "_reference": "JPHIJ",
-                  "name": "JPHIJ7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPTKY0",
-               "port": {
-                  "_reference": "JPTKY",
-                  "name": "JPTKY1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50232",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHIJ8",
-               "port": {
-                  "_reference": "JPHIJ",
-                  "name": "JPHIJ9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPUKB0",
-               "port": {
-                  "_reference": "JPUKB",
-                  "name": "JPUKB1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50233",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHIJ10",
-               "port": {
-                  "_reference": "JPHIJ",
-                  "name": "JPHIJ11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYKK0",
-               "port": {
-                  "_reference": "JPYKK",
-                  "name": "JPYKK1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50234",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHIJ12",
-               "port": {
-                  "_reference": "JPHIJ",
-                  "name": "JPHIJ13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYOK2",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50241",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT0",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPNGO2",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50243",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT2",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ2",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50247",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT4",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPTOY0",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50250",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT6",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYKK2",
-               "port": {
-                  "_reference": "JPYKK",
-                  "name": "JPYKK3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50251",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT8",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYOK4",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50258",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHSA2",
-               "port": {
-                  "_reference": "JPHSA",
-                  "name": "JPHSA3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPNGO4",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50260",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHSA4",
-               "port": {
-                  "_reference": "JPHSA",
-                  "name": "JPHSA5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ4",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50272",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPIMB0",
-               "port": {
-                  "_reference": "JPIMB",
-                  "name": "JPIMB1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPKIJ0",
-               "port": {
-                  "_reference": "JPKIJ",
-                  "name": "JPKIJ1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50275",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPIMB2",
-               "port": {
-                  "_reference": "JPIMB",
-                  "name": "JPIMB3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPNGO6",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50277",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPIMB4",
-               "port": {
-                  "_reference": "JPIMB",
-                  "name": "JPIMB5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ6",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50292",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPKIJ2",
-               "port": {
-                  "_reference": "JPKIJ",
-                  "name": "JPKIJ3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPNGO8",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50294",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPKIJ4",
-               "port": {
-                  "_reference": "JPKIJ",
-                  "name": "JPKIJ5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ8",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50299",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPKIJ6",
-               "port": {
-                  "_reference": "JPKIJ",
-                  "name": "JPKIJ7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPTYO0",
-               "port": {
-                  "_reference": "JPTYO",
-                  "name": "JPTYO1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50301",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPKIJ8",
-               "port": {
-                  "_reference": "JPKIJ",
-                  "name": "JPKIJ9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYKK4",
-               "port": {
-                  "_reference": "JPYKK",
-                  "name": "JPYKK5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50302",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPKIJ10",
-               "port": {
-                  "_reference": "JPKIJ",
-                  "name": "JPKIJ11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYOK6",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50309",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPKNZ0",
-               "port": {
-                  "_reference": "JPKNZ",
-                  "name": "JPKNZ1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPNGO10",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50311",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPKNZ2",
-               "port": {
-                  "_reference": "JPKNZ",
-                  "name": "JPKNZ3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ10",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50322",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPMOJ0",
-               "port": {
-                  "_reference": "JPMOJ",
-                  "name": "JPMOJ1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPHSA6",
-               "port": {
-                  "_reference": "JPHSA",
-                  "name": "JPHSA7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50328",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPMOJ2",
-               "port": {
-                  "_reference": "JPMOJ",
-                  "name": "JPMOJ3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ12",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50335",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPMOJ4",
-               "port": {
-                  "_reference": "JPMOJ",
-                  "name": "JPMOJ5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYKK6",
-               "port": {
-                  "_reference": "JPYKK",
-                  "name": "JPYKK7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50336",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPMOJ6",
-               "port": {
-                  "_reference": "JPMOJ",
-                  "name": "JPMOJ7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYOK8",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50347",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPNGO12",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPTKY2",
-               "port": {
-                  "_reference": "JPTKY",
-                  "name": "JPTKY3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50356",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPOSA2",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPHSA8",
-               "port": {
-                  "_reference": "JPHSA",
-                  "name": "JPHSA9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50362",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPOSA4",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ14",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50366",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPOSA6",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPTOY2",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50367",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPOSA8",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPTYO2",
-               "port": {
-                  "_reference": "JPTYO",
-                  "name": "JPTYO3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50395",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTAK0",
-               "port": {
-                  "_reference": "JPTAK",
-                  "name": "JPTAK1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPNGO14",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50397",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTAK2",
-               "port": {
-                  "_reference": "JPTAK",
-                  "name": "JPTAK3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ16",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50401",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTAK4",
-               "port": {
-                  "_reference": "JPTAK",
-                  "name": "JPTAK5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPTYO4",
-               "port": {
-                  "_reference": "JPTYO",
-                  "name": "JPTYO5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50403",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTAK6",
-               "port": {
-                  "_reference": "JPTAK",
-                  "name": "JPTAK7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYKK8",
-               "port": {
-                  "_reference": "JPYKK",
-                  "name": "JPYKK9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50408",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTKY4",
-               "port": {
-                  "_reference": "JPTKY",
-                  "name": "JPTKY5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPIMB6",
-               "port": {
-                  "_reference": "JPIMB",
-                  "name": "JPIMB7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50412",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTKY6",
-               "port": {
-                  "_reference": "JPTKY",
-                  "name": "JPTKY7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPNGO16",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50414",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTKY8",
-               "port": {
-                  "_reference": "JPTKY",
-                  "name": "JPTKY9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ18",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50417",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTKY10",
-               "port": {
-                  "_reference": "JPTKY",
-                  "name": "JPTKY11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPTOY4",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50421",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTKY12",
-               "port": {
-                  "_reference": "JPTKY",
-                  "name": "JPTKY13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYOK10",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50424",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK0",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPHSA10",
-               "port": {
-                  "_reference": "JPHSA",
-                  "name": "JPHSA11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50429",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK2",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPNGO18",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50431",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK4",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ20",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50434",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK6",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPTOY6",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50437",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK8",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYKK10",
-               "port": {
-                  "_reference": "JPYKK",
-                  "name": "JPYKK11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50438",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK10",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYOK12",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50441",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTOY8",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPHSA12",
-               "port": {
-                  "_reference": "JPHSA",
-                  "name": "JPHSA13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50446",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTOY10",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPNGO20",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50455",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTOY12",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYOK14",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50458",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTYO6",
-               "port": {
-                  "_reference": "JPTYO",
-                  "name": "JPTYO7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPHSA14",
-               "port": {
-                  "_reference": "JPHSA",
-                  "name": "JPHSA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50471",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTYO8",
-               "port": {
-                  "_reference": "JPTYO",
-                  "name": "JPTYO9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYKK12",
-               "port": {
-                  "_reference": "JPYKK",
-                  "name": "JPYKK13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50480",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPUKB2",
-               "port": {
-                  "_reference": "JPUKB",
-                  "name": "JPUKB3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPNGO22",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50482",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPUKB4",
-               "port": {
-                  "_reference": "JPUKB",
-                  "name": "JPUKB5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPSMZ22",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50487",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPUKB6",
-               "port": {
-                  "_reference": "JPUKB",
-                  "name": "JPUKB7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPTYO10",
-               "port": {
-                  "_reference": "JPTYO",
-                  "name": "JPTYO11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50489",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPUKB8",
-               "port": {
-                  "_reference": "JPUKB",
-                  "name": "JPUKB9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYOK16",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50506",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPYKK14",
-               "port": {
-                  "_reference": "JPYKK",
-                  "name": "JPYKK15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "JPYOK18",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50541",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KHPNH12",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU14",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50547",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KHPNH14",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN8",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50556",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KREIW",
-               "port": {
-                  "_reference": "KREIW",
-                  "name": "KREIW0"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "KRKAN0",
-               "port": {
-                  "_reference": "KRKAN",
-                  "name": "KRKAN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50558",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KREIW1",
-               "port": {
-                  "_reference": "KREIW",
-                  "name": "KREIW2"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "KRPUS0",
-               "port": {
-                  "_reference": "KRPUS",
-                  "name": "KRPUS1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50559",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KRINC0",
-               "port": {
-                  "_reference": "KRINC",
-                  "name": "KRINC1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "KREIW3",
-               "port": {
-                  "_reference": "KREIW",
-                  "name": "KREIW4"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50561",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KRINC2",
-               "port": {
-                  "_reference": "KRINC",
-                  "name": "KRINC3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "KRKAN2",
-               "port": {
-                  "_reference": "KRKAN",
-                  "name": "KRKAN3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50566",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KRJCW0",
-               "port": {
-                  "_reference": "KRJCW",
-                  "name": "KRJCW1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "KRKAN4",
-               "port": {
-                  "_reference": "KRKAN",
-                  "name": "KRKAN5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50577",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KRKUM0",
-               "port": {
-                  "_reference": "KRKUM",
-                  "name": "KRKUM1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "KRKAN6",
-               "port": {
-                  "_reference": "KRKAN",
-                  "name": "KRKAN7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50578",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KRKUM2",
-               "port": {
-                  "_reference": "KRKUM",
-                  "name": "KRKUM3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "KRPUS2",
-               "port": {
-                  "_reference": "KRPUS",
-                  "name": "KRPUS3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50584",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KWKWI2",
-               "port": {
-                  "_reference": "KWKWI",
-                  "name": "KWKWI3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "AEAUH8",
-               "port": {
-                  "_reference": "AEAUH",
-                  "name": "AEAUH9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50586",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KWKWI4",
-               "port": {
-                  "_reference": "KWKWI",
-                  "name": "KWKWI5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "AEJEA10",
-               "port": {
-                  "_reference": "AEJEA",
-                  "name": "AEJEA11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50589",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KWKWI6",
-               "port": {
-                  "_reference": "KWKWI",
-                  "name": "KWKWI7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IRBND16",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50594",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KWKWI8",
-               "port": {
-                  "_reference": "KWKWI",
-                  "name": "KWKWI9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SAJED2",
-               "port": {
-                  "_reference": "SAJED",
-                  "name": "SAJED3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50606",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LBBEY4",
-               "port": {
-                  "_reference": "LBBEY",
-                  "name": "LBBEY5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV48",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV49"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50633",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LBBEY6",
-               "port": {
-                  "_reference": "LBBEY",
-                  "name": "LBBEY7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB15",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB16"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50676",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LBBEY8",
-               "port": {
-                  "_reference": "LBBEY",
-                  "name": "LBBEY9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SEHEL4",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50727",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LTKLJ2",
-               "port": {
-                  "_reference": "LTKLJ",
-                  "name": "LTKLJ3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV50",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV51"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50782",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LTKLJ4",
-               "port": {
-                  "_reference": "LTKLJ",
-                  "name": "LTKLJ5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MACAS2",
-               "port": {
-                  "_reference": "MACAS",
-                  "name": "MACAS3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50852",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LVRIX2",
-               "port": {
-                  "_reference": "LVRIX",
-                  "name": "LVRIX3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBMAN14",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50907",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MACAS4",
-               "port": {
-                  "_reference": "MACAS",
-                  "name": "MACAS5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE14",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "50998",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MMRGN12",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMAA18",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51000",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MMRGN14",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INNAH8",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51001",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MMRGN16",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INTUT10",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51006",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MMRGN18",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU16",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51007",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MMRGN20",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG14",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51011",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MMRGN22",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PKKHI6",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51012",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MMRGN24",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN10",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51020",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXESE0",
-               "port": {
-                  "_reference": "MXESE",
-                  "name": "MXESE1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "MXMEX2",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51023",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXGDL0",
-               "port": {
-                  "_reference": "MXGDL",
-                  "name": "MXGDL1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "MXESE2",
-               "port": {
-                  "_reference": "MXESE",
-                  "name": "MXESE3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51024",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXGDL2",
-               "port": {
-                  "_reference": "MXGDL",
-                  "name": "MXGDL3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "MXMEX4",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51027",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXMEX6",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CATOR14",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51028",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXMEX8",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CAVAN8",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51029",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXMEX10",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "MXESE4",
-               "port": {
-                  "_reference": "MXESE",
-                  "name": "MXESE5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51033",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXMEX12",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "USATL0",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51035",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXMEX14",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "USHOU0",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51040",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXMTY0",
-               "port": {
-                  "_reference": "MXMTY",
-                  "name": "MXMTY1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "MXESE6",
-               "port": {
-                  "_reference": "MXESE",
-                  "name": "MXESE7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51042",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXMTY2",
-               "port": {
-                  "_reference": "MXMTY",
-                  "name": "MXMTY3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "MXMEX16",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51044",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXZLO0",
-               "port": {
-                  "_reference": "MXZLO",
-                  "name": "MXZLO1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "MXESE8",
-               "port": {
-                  "_reference": "MXESE",
-                  "name": "MXESE9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51046",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXZLO2",
-               "port": {
-                  "_reference": "MXZLO",
-                  "name": "MXZLO3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "MXMEX18",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51065",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MYPEN6",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "MYPGU18",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51066",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MYPEN8",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "MYPKG16",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51104",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MYPGU20",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "THLKG0",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51144",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM2",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZPRG20",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51145",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM4",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN28",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51146",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM6",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER14",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51147",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM8",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE16",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51150",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM10",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEDUS22",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51151",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM12",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEFRA22",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51152",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM14",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER20",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51154",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM16",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC34",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51155",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM18",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DENUE22",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51156",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM20",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR28",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51157",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM22",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKAAR52",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR53"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51158",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM24",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKCPH10",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51162",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM26",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "EGDAM8",
-               "port": {
-                  "_reference": "EGDAM",
-                  "name": "EGDAM9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51171",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM28",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRBOD22",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51172",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM30",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRFOS20",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51174",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM32",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR24",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51175",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM34",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRRNS16",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51176",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM36",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB17",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB18"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51178",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM38",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBHM14",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51181",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM40",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLBA14",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51188",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM42",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "HUBUD18",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51196",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM44",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM45"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMOD8",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51197",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM46",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM47"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP24",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51198",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM48",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM49"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA20",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51213",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM50",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM51"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PLSZZ0",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51215",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM52",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM53"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS18",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51219",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM54",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM55"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SEHEL6",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51229",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB2",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ATVIE30",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51237",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB4",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER16",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51243",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB6",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER22",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51247",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB8",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR30",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51248",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB10",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKAAR54",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR55"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51262",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB12",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRBOD24",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51267",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB14",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB19",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB20"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51268",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB16",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBEL16",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51274",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB18",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBMAN16",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51280",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB20",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IEDUB34",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51286",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB22",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMIL18",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51297",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB24",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB25"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "NLRTM56",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM57"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51340",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOAES0",
-               "port": {
-                  "_reference": "NOAES",
-                  "name": "NOAES1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKCPH12",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51359",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOAES2",
-               "port": {
-                  "_reference": "NOAES",
-                  "name": "NOAES3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBEL18",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51400",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOAES4",
-               "port": {
-                  "_reference": "NOAES",
-                  "name": "NOAES5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SEGOT8",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51404",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOAES6",
-               "port": {
-                  "_reference": "NOAES",
-                  "name": "NOAES7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SILJU2",
-               "port": {
-                  "_reference": "SILJU",
-                  "name": "SILJU3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51503",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS6",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR32",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51513",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS8",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV52",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV53"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51515",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS10",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEFRA24",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51520",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS12",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR32",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51522",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS14",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKCPH14",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51535",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS16",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRBOD26",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51545",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS18",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLBA16",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51546",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS20",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLIV16",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51560",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS22",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMOD10",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51561",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS24",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP26",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51579",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS26",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS20",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51594",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL4",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR34",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51602",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL6",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE18",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51604",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL8",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV54",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV55"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51605",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL10",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEDUS24",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51606",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL12",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEFRA26",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51607",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL14",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER24",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51611",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL16",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR34",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51612",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL18",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKAAR56",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR57"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51613",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL20",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKCPH16",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51622",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL22",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESMAD16",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51623",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL24",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESVLC20",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51626",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL26",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRBOD28",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51629",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL28",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR26",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51630",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL30",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRRNS18",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51631",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL32",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB21",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB22"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51633",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL34",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBHM16",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51635",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL36",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBGLW18",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51636",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL38",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLBA18",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51637",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL40",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLIV18",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51638",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL42",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBMAN18",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51640",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL44",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL45"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL24",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51643",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL46",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL47"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "HUBUD20",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51648",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL48",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL49"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITGOA16",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51650",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL50",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL51"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMIL20",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51652",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL52",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL53"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP28",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51653",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL54",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL55"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA22",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51668",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL56",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL57"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PLSZZ2",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51670",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL58",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL59"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS22",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51674",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL60",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL61"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SEHEL8",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51676",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOOSL62",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL63"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SIKOP8",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51686",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "OMMCT4",
-               "port": {
-                  "_reference": "OMMCT",
-                  "name": "OMMCT5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "AEJEA12",
-               "port": {
-                  "_reference": "AEJEA",
-                  "name": "AEJEA13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51689",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "OMMCT6",
-               "port": {
-                  "_reference": "OMMCT",
-                  "name": "OMMCT7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IRBND18",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51694",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "OMMCT8",
-               "port": {
-                  "_reference": "OMMCT",
-                  "name": "OMMCT9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SAJED4",
-               "port": {
-                  "_reference": "SAJED",
-                  "name": "SAJED5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51702",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHCEB0",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INDEL22",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51705",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHCEB2",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMUN10",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51706",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHCEB4",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INNAH10",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51707",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHCEB6",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INTUT12",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51709",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHCEB8",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KHPNH16",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51710",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHCEB10",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LKCMB6",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51712",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHCEB12",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPEN10",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51713",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHCEB14",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU22",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51714",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHCEB16",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG18",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51718",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHCEB18",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN12",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51731",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL0",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INCOK12",
-               "port": {
-                  "_reference": "INCOK",
-                  "name": "INCOK13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51732",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL2",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INDEL24",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51734",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL4",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMAA20",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51735",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL6",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMUN12",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51737",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL8",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INTUT14",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51739",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL10",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KHPNH18",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51740",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL12",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LKCMB8",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51741",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL14",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MMRGN26",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51742",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL16",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPEN12",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51743",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL18",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU24",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51744",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL20",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG20",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51747",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL22",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PKKHI8",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51748",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL24",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN14",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51753",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL26",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNHPH12",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51754",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL28",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN14",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51773",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKBQM4",
-               "port": {
-                  "_reference": "PKBQM",
-                  "name": "PKBQM5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU26",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51778",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKBQM6",
-               "port": {
-                  "_reference": "PKBQM",
-                  "name": "PKBQM7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN16",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51784",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKBQM8",
-               "port": {
-                  "_reference": "PKBQM",
-                  "name": "PKBQM9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN16",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51792",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKKHI10",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INDEL26",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51799",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKKHI12",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KHPNH20",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51800",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKKHI14",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LKCMB10",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51801",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKKHI16",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MMRGN28",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51802",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKKHI18",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPEN14",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51804",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKKHI20",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG22",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51807",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKKHI22",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI23"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "PKBQM10",
-               "port": {
-                  "_reference": "PKBQM",
-                  "name": "PKBQM11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51808",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKKHI24",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN18",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51813",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PKKHI26",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNHPH14",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51822",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDN2",
-               "port": {
-                  "_reference": "PLGDN",
-                  "name": "PLGDN3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN30",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51884",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDN4",
-               "port": {
-                  "_reference": "PLGDN",
-                  "name": "PLGDN5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NLTLB26",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51891",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDN6",
-               "port": {
-                  "_reference": "PLGDN",
-                  "name": "PLGDN7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "PLWRP4",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51907",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY2",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR36",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51908",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY4",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEAVL12",
-               "port": {
-                  "_reference": "BEAVL",
-                  "name": "BEAVL13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51912",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY6",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZPRG22",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51913",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY8",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN32",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51914",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY10",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER18",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51915",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY12",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE20",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51917",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY14",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV56",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV57"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51918",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY16",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEDUS26",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51929",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY18",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "EGALY10",
-               "port": {
-                  "_reference": "EGALY",
-                  "name": "EGALY11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51936",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY20",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESVLC22",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51942",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY22",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR28",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51944",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY24",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB23",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB24"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51945",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY26",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBEL20",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51946",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY28",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBHM18",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51948",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY30",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBGLW20",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51949",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY32",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLBA20",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51950",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY34",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLIV20",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51963",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY36",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMIL22",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51965",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY38",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP30",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51966",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY40",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA24",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51979",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY42",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NOOSL64",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL65"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51981",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY44",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY45"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "PLSZZ4",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51982",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY46",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY47"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "PLWRP6",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "51983",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY48",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY49"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS24",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52003",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ6",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZPRG24",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52009",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ8",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEDUS28",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52010",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ10",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEFRA28",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52014",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ12",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DENUE24",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52015",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ14",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR36",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52027",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ16",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESVLC24",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52033",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ18",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR30",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52038",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ20",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBFXT10",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52051",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ22",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITGIT14",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52055",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ24",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMOD12",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52057",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ26",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA26",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52089",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP8",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR38",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52095",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP10",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN34",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52099",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP12",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV58",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV59"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52101",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP14",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEFRA30",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52104",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP16",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC36",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52121",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP18",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRBOD30",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52145",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP20",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMIL24",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52147",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP22",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP32",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52164",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP24",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP25"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "PLSZZ28",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52167",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP26",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "RULED0",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52180",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PTLIS26",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR40",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52187",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PTLIS28",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER20",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52188",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PTLIS30",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE22",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52193",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PTLIS32",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER26",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52196",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PTLIS34",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DENUE26",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52197",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PTLIS36",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR38",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52229",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PTLIS38",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "HUBUD22",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52230",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PTLIS40",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IEDUB36",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52261",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PTLIS42",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SESTO2",
-               "port": {
-                  "_reference": "SESTO",
-                  "name": "SESTO3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52270",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "QADOH0",
-               "port": {
-                  "_reference": "QADOH",
-                  "name": "QADOH1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "AEAUH10",
-               "port": {
-                  "_reference": "AEAUH",
-                  "name": "AEAUH11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52275",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "QADOH2",
-               "port": {
-                  "_reference": "QADOH",
-                  "name": "QADOH3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IRBND20",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52277",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "QADOH4",
-               "port": {
-                  "_reference": "QADOH",
-                  "name": "QADOH5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "OMMCT10",
-               "port": {
-                  "_reference": "OMMCT",
-                  "name": "OMMCT11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52283",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "QAMES0",
-               "port": {
-                  "_reference": "QAMES",
-                  "name": "QAMES1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "AEJEA14",
-               "port": {
-                  "_reference": "AEJEA",
-                  "name": "AEJEA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52286",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "QAMES2",
-               "port": {
-                  "_reference": "QAMES",
-                  "name": "QAMES3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IRBND22",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52288",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "QAMES4",
-               "port": {
-                  "_reference": "QAMES",
-                  "name": "QAMES5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "OMMCT12",
-               "port": {
-                  "_reference": "OMMCT",
-                  "name": "OMMCT13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52291",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "QAMES6",
-               "port": {
-                  "_reference": "QAMES",
-                  "name": "QAMES7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SAJED6",
-               "port": {
-                  "_reference": "SAJED",
-                  "name": "SAJED7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52324",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ROCND6",
-               "port": {
-                  "_reference": "ROCND",
-                  "name": "ROCND7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FIKTK62",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK63"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52365",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ROCND8",
-               "port": {
-                  "_reference": "ROCND",
-                  "name": "ROCND9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NOOSL66",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL67"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52383",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED2",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ATVIE32",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52384",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED4",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR42",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52389",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED6",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZPRG26",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52390",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED8",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN36",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52391",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED10",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER22",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52392",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED12",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE24",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52394",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED14",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV60",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV61"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52395",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED16",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEDUS30",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52396",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED18",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEFRA32",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52397",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED20",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER28",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52398",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED22",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEHAM2",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52399",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED24",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC38",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52400",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED26",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DENUE28",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52401",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED28",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR40",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52402",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED30",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKAAR58",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR59"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52403",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED32",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DKCPH18",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52409",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED34",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESBCN20",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52412",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED36",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESMAD18",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52413",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED38",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESVLC26",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52416",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED40",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRBOD32",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52417",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED42",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRFOS22",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52419",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED44",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED45"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR32",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52421",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED46",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED47"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRSXB25",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB26"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52422",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED48",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED49"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBEL22",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52425",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED50",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED51"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBGLW22",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52427",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED52",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED53"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLIV22",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52428",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED54",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED55"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBMAN20",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52430",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED56",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED57"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL26",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52433",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED58",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED59"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "HUBUD24",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52434",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED60",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED61"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IEDUB38",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52441",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED62",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED63"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMOD14",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52442",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED64",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED65"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP34",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52443",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED66",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED67"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA28",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52459",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED68",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED69"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PLSZZ30",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52461",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED70",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED71"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PTLIS44",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52464",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED72",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED73"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SEHEL10",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52479",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SADMN0",
-               "port": {
-                  "_reference": "SADMN",
-                  "name": "SADMN1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IRBND24",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52484",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SADMN2",
-               "port": {
-                  "_reference": "SADMN",
-                  "name": "SADMN3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "SAJED8",
-               "port": {
-                  "_reference": "SAJED",
-                  "name": "SAJED9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52490",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SAJED10",
-               "port": {
-                  "_reference": "SAJED",
-                  "name": "SAJED11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "IRBND26",
-               "port": {
-                  "_reference": "IRBND",
-                  "name": "IRBND27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52496",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT10",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ATVIE34",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52497",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT12",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR44",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52503",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT14",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZZLN38",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52504",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT16",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER24",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52505",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT18",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE26",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52507",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT20",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV62",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV63"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52508",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT22",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEDUS32",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52509",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT24",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEFRA34",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52510",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT26",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER30",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52512",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT28",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEMUC40",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52514",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT30",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR42",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52532",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT32",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR34",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52533",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT34",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRRNS20",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52535",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT36",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBEL24",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52536",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT38",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBHM20",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52538",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT40",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBGLW24",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52539",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT42",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBLBA22",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52546",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT44",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT45"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "HUBUD26",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52549",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT46",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT47"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITAOI10",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52553",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT48",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT49"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMIL26",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52554",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT50",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT51"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITMOD16",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52555",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT52",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT53"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP36",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52556",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT54",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT55"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA30",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52558",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT56",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT57"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITSPE10",
-               "port": {
-                  "_reference": "ITSPE",
-                  "name": "ITSPE11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52577",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT58",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT59"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "SEHEL12",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52579",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT60",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT61"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SIKOP10",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52588",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL14",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR46",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52593",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL16",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CZPRG28",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52595",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL18",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBER26",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52598",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL20",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV64",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV65"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52616",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL22",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESMAD20",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52623",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL24",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRPAR36",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52628",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL26",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBFXT12",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52632",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL28",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBMAN22",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52634",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL30",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL28",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52662",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL32",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "PLGDY50",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY51"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52675",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL34",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "TRIST8",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52679",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SESTO4",
-               "port": {
-                  "_reference": "SESTO",
-                  "name": "SESTO5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR48",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR49"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52681",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SESTO6",
-               "port": {
-                  "_reference": "SESTO",
-                  "name": "SESTO7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CHBSL8",
-               "port": {
-                  "_reference": "CHBSL",
-                  "name": "CHBSL9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52717",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SESTO8",
-               "port": {
-                  "_reference": "SESTO",
-                  "name": "SESTO9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBEL26",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52760",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SESTO10",
-               "port": {
-                  "_reference": "SESTO",
-                  "name": "SESTO11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "SEHEL36",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52786",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SGSIN20",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPEN16",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52810",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SIKOP12",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBRV66",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV67"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52813",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SIKOP14",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEGER32",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52817",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SIKOP16",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DESTR44",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52839",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SIKOP18",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBBHM22",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52841",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SIKOP20",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBGLW26",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52844",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SIKOP22",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBMAN24",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52890",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SILJU4",
-               "port": {
-                  "_reference": "SILJU",
-                  "name": "SILJU5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ATVIE36",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52924",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SILJU6",
-               "port": {
-                  "_reference": "SILJU",
-                  "name": "SILJU7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "FRFOS24",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "52946",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SILJU8",
-               "port": {
-                  "_reference": "SILJU",
-                  "name": "SILJU9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITLIV0",
-               "port": {
-                  "_reference": "ITLIV",
-                  "name": "ITLIV1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53098",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SYTTS4",
-               "port": {
-                  "_reference": "SYTTS",
-                  "name": "SYTTS5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ESBCN22",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53170",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK0",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INDEL28",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53172",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK2",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMAA22",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53173",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK4",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMUN14",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53174",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK6",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INNAH12",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53175",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK8",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INTUT16",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53177",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK10",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KHPNH22",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53178",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK12",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LKCMB12",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53180",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK14",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPEN18",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53181",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK16",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU28",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53182",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK18",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG24",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53187",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK20",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN22",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53188",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK22",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK23"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "THLCH2",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53189",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK24",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK25"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "THLKG2",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53190",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK26",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK27"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "THSGZ0",
-               "port": {
-                  "_reference": "THSGZ",
-                  "name": "THSGZ1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53191",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK28",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNHPH16",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53192",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK30",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN18",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53200",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH4",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INDEL30",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53203",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH6",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMUN16",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53204",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH8",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INNAH14",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53205",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH10",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INTUT18",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53208",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH12",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LKCMB14",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53210",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH14",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPEN20",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53211",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH16",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU30",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53212",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH18",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG26",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53217",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH20",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN24",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53219",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH22",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH23"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "THLKG4",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53220",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH24",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH25"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "THSGZ2",
-               "port": {
-                  "_reference": "THSGZ",
-                  "name": "THSGZ3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53222",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH26",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN20",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53230",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG6",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INDEL32",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53232",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG8",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMAA24",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53237",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG10",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "KHPNH24",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53238",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG12",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LKCMB16",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53239",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG14",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MMRGN30",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53240",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG16",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPEN22",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53242",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG18",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG28",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53247",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG20",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN26",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53249",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG22",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG23"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "THLCH28",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53250",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG24",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG25"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "THSGZ4",
-               "port": {
-                  "_reference": "THSGZ",
-                  "name": "THSGZ5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53251",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG26",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNHPH18",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53252",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG28",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "VNSGN22",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53272",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THSGZ6",
-               "port": {
-                  "_reference": "THSGZ",
-                  "name": "THSGZ7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG30",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53277",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THSGZ8",
-               "port": {
-                  "_reference": "THSGZ",
-                  "name": "THSGZ9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN28",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53284",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TNTUN2",
-               "port": {
-                  "_reference": "TNTUN",
-                  "name": "TNTUN3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "BEANR50",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR51"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53292",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TNTUN4",
-               "port": {
-                  "_reference": "TNTUN",
-                  "name": "TNTUN5"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DEBFE28",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53356",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TNTUN6",
-               "port": {
-                  "_reference": "TNTUN",
-                  "name": "TNTUN7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NOOSL68",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL69"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53391",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRIST10",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST11"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "DENUE30",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53416",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRIST12",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST13"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBGLW28",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53433",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRIST14",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST15"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITNAP38",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53434",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRIST16",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST17"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITPDA32",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53445",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRIST18",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST19"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NOBGO2",
-               "port": {
-                  "_reference": "NOBGO",
-                  "name": "NOBGO3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53512",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRIZM0",
-               "port": {
-                  "_reference": "TRIZM",
-                  "name": "TRIZM1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "GBTIL30",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53527",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRIZM2",
-               "port": {
-                  "_reference": "TRIZM",
-                  "name": "TRIZM3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "ITSPE12",
-               "port": {
-                  "_reference": "ITSPE",
-                  "name": "ITSPE13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53554",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRIZM4",
-               "port": {
-                  "_reference": "TRIZM",
-                  "name": "TRIZM5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "TRIST20",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53628",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRMER8",
-               "port": {
-                  "_reference": "TRMER",
-                  "name": "TRMER9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "NOKRS28",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53645",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRMER10",
-               "port": {
-                  "_reference": "TRMER",
-                  "name": "TRMER11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "TRIST22",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53651",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TWKHH0",
-               "port": {
-                  "_reference": "TWKHH",
-                  "name": "TWKHH1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "TWTXG0",
-               "port": {
-                  "_reference": "TWTXG",
-                  "name": "TWTXG1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53652",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TWKHH2",
-               "port": {
-                  "_reference": "TWKHH",
-                  "name": "TWKHH3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "TWTYU",
-               "port": {
-                  "_reference": "TWTYU",
-                  "name": "TWTYU0"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53663",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USADI0",
-               "port": {
-                  "_reference": "USADI",
-                  "name": "USADI1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USDET0",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53668",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USADI2",
-               "port": {
-                  "_reference": "USADI",
-                  "name": "USADI3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSDF0",
-               "port": {
-                  "_reference": "USSDF",
-                  "name": "USSDF1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53674",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USAMA0",
-               "port": {
-                  "_reference": "USAMA",
-                  "name": "USAMA1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMSY0",
-               "port": {
-                  "_reference": "USMSY",
-                  "name": "USMSY1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53687",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USATL2",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USJAX0",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53689",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USATL4",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMEM0",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53690",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USATL6",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMIA0",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53696",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBAL0",
-               "port": {
-                  "_reference": "USBAL",
-                  "name": "USBAL1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USBOS0",
-               "port": {
-                  "_reference": "USBOS",
-                  "name": "USBOS1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53701",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBAL2",
-               "port": {
-                  "_reference": "USBAL",
-                  "name": "USBAL3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USPHL0",
-               "port": {
-                  "_reference": "USPHL",
-                  "name": "USPHL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53702",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBAL4",
-               "port": {
-                  "_reference": "USBAL",
-                  "name": "USBAL5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USPIT0",
-               "port": {
-                  "_reference": "USPIT",
-                  "name": "USPIT1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53707",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBNA0",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USILM0",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53709",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBNA2",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USJAX2",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53710",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBNA4",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMEM2",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53711",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBNA6",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMIA2",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53712",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBNA8",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMOB0",
-               "port": {
-                  "_reference": "USMOB",
-                  "name": "USMOB1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53727",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBUF0",
-               "port": {
-                  "_reference": "USBUF",
-                  "name": "USBUF1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USPIT2",
-               "port": {
-                  "_reference": "USPIT",
-                  "name": "USPIT3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53729",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI2",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI3"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CAVAN10",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53734",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI4",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USCMH0",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53735",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI6",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USCVG0",
-               "port": {
-                  "_reference": "USCVG",
-                  "name": "USCVG1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53736",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI8",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USDET2",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53739",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI10",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USKCK0",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53741",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI12",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMSP0",
-               "port": {
-                  "_reference": "USMSP",
-                  "name": "USMSP1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53742",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI14",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USNYC0",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53743",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI16",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USOMA0",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53745",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI18",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSDF2",
-               "port": {
-                  "_reference": "USSDF",
-                  "name": "USSDF3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53746",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI20",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI21"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSEA2",
-               "port": {
-                  "_reference": "USSEA",
-                  "name": "USSEA3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53747",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI22",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI23"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSTL0",
-               "port": {
-                  "_reference": "USSTL",
-                  "name": "USSTL1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53749",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS0",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USBNA10",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53752",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS2",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USILM2",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53754",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS4",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USJAX4",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53755",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS6",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMEM4",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53756",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS8",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMIA4",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53757",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS10",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMOB2",
-               "port": {
-                  "_reference": "USMOB",
-                  "name": "USMOB3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53762",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE0",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USCVG2",
-               "port": {
-                  "_reference": "USCVG",
-                  "name": "USCVG3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53763",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE2",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USDET4",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53765",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE4",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USKCK2",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53766",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE6",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMSP2",
-               "port": {
-                  "_reference": "USMSP",
-                  "name": "USMSP3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53767",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE8",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USOMA2",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53768",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE10",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSDF4",
-               "port": {
-                  "_reference": "USSDF",
-                  "name": "USSDF5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53769",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE12",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSTL2",
-               "port": {
-                  "_reference": "USSTL",
-                  "name": "USSTL3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53771",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLT0",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USBNA12",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53774",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLT2",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USILM4",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53776",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLT4",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USJAX6",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53777",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLT6",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMEM6",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53778",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLT8",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMIA6",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53779",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLT10",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMOB4",
-               "port": {
-                  "_reference": "USMOB",
-                  "name": "USMOB5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53784",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH2",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USCVG4",
-               "port": {
-                  "_reference": "USCVG",
-                  "name": "USCVG5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53785",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH4",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USDET6",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53787",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH6",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USKCK4",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53788",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH8",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMSP4",
-               "port": {
-                  "_reference": "USMSP",
-                  "name": "USMSP5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53789",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH10",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USOMA4",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53790",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH12",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSDF6",
-               "port": {
-                  "_reference": "USSDF",
-                  "name": "USSDF7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53791",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH14",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSTL4",
-               "port": {
-                  "_reference": "USSTL",
-                  "name": "USSTL5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53800",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCVG6",
-               "port": {
-                  "_reference": "USCVG",
-                  "name": "USCVG7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USOMA6",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53804",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDAL0",
-               "port": {
-                  "_reference": "USDAL",
-                  "name": "USDAL1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USELP0",
-               "port": {
-                  "_reference": "USELP",
-                  "name": "USELP1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53805",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDAL2",
-               "port": {
-                  "_reference": "USDAL",
-                  "name": "USDAL3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USHOU2",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53807",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDAL4",
-               "port": {
-                  "_reference": "USDAL",
-                  "name": "USDAL5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMSY2",
-               "port": {
-                  "_reference": "USMSY",
-                  "name": "USMSY3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53808",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDAL6",
-               "port": {
-                  "_reference": "USDAL",
-                  "name": "USDAL7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSAT0",
-               "port": {
-                  "_reference": "USSAT",
-                  "name": "USSAT1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53815",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDET8",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USCVG8",
-               "port": {
-                  "_reference": "USCVG",
-                  "name": "USCVG9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53817",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDET10",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USKCK6",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53818",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDET12",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMSP6",
-               "port": {
-                  "_reference": "USMSP",
-                  "name": "USMSP7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53819",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDET14",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USOMA8",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53820",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDET16",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSDF8",
-               "port": {
-                  "_reference": "USSDF",
-                  "name": "USSDF9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53821",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDET18",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSTL6",
-               "port": {
-                  "_reference": "USSTL",
-                  "name": "USSTL7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53824",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USELP2",
-               "port": {
-                  "_reference": "USELP",
-                  "name": "USELP3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USHOU4",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53826",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USELP4",
-               "port": {
-                  "_reference": "USELP",
-                  "name": "USELP5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMSY4",
-               "port": {
-                  "_reference": "USMSY",
-                  "name": "USMSY5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53829",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHAR0",
-               "port": {
-                  "_reference": "USHAR",
-                  "name": "USHAR1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USBOS2",
-               "port": {
-                  "_reference": "USBOS",
-                  "name": "USBOS3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53834",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHAR2",
-               "port": {
-                  "_reference": "USHAR",
-                  "name": "USHAR3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USPIT4",
-               "port": {
-                  "_reference": "USPIT",
-                  "name": "USPIT5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53835",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU6",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU7"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CATOR16",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53836",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU8",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU9"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CAVAN12",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53839",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU10",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USATL8",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53840",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU12",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USCHI24",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53846",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU14",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USNYC2",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53847",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU16",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USPDX0",
-               "port": {
-                  "_reference": "USPDX",
-                  "name": "USPDX1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53849",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU18",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU19"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSEA4",
-               "port": {
-                  "_reference": "USSEA",
-                  "name": "USSEA5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53854",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHSV0",
-               "port": {
-                  "_reference": "USHSV",
-                  "name": "USHSV1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USILM6",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53856",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHSV2",
-               "port": {
-                  "_reference": "USHSV",
-                  "name": "USHSV3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USJAX8",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53857",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHSV4",
-               "port": {
-                  "_reference": "USHSV",
-                  "name": "USHSV5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMEM8",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53875",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND0",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USCMH16",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53876",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND2",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USCVG10",
-               "port": {
-                  "_reference": "USCVG",
-                  "name": "USCVG11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53877",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND4",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USDET20",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53878",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND6",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USKCK8",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53879",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND8",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMSP8",
-               "port": {
-                  "_reference": "USMSP",
-                  "name": "USMSP9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53880",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND10",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USOMA10",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53881",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND12",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSDF10",
-               "port": {
-                  "_reference": "USSDF",
-                  "name": "USSDF11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53882",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND14",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSTL8",
-               "port": {
-                  "_reference": "USSTL",
-                  "name": "USSTL9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53889",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USJAN0",
-               "port": {
-                  "_reference": "USJAN",
-                  "name": "USJAN1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USJAX10",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53907",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USKCK10",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USCLE14",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53918",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB0",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB1"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "CAVAN14",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53920",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB2",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USATL10",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53921",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB4",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USCHI26",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53922",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB6",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USHOU20",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53923",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB8",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USLAX0",
-               "port": {
-                  "_reference": "USLAX",
-                  "name": "USLAX1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53925",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB10",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USPDX2",
-               "port": {
-                  "_reference": "USPDX",
-                  "name": "USPDX3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53926",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB12",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSEA6",
-               "port": {
-                  "_reference": "USSEA",
-                  "name": "USSEA7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53930",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLRD0",
-               "port": {
-                  "_reference": "USLRD",
-                  "name": "USLRD1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USHOU22",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53931",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLRD2",
-               "port": {
-                  "_reference": "USLRD",
-                  "name": "USLRD3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMSY6",
-               "port": {
-                  "_reference": "USMSY",
-                  "name": "USMSY7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53932",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLRD4",
-               "port": {
-                  "_reference": "USLRD",
-                  "name": "USLRD5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSAT2",
-               "port": {
-                  "_reference": "USSAT",
-                  "name": "USSAT3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53939",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMEM10",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USILM8",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53941",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMEM12",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USJAX12",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53950",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMIA8",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USILM10",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53964",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMOB6",
-               "port": {
-                  "_reference": "USMOB",
-                  "name": "USMOB7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMEM14",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53965",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMOB8",
-               "port": {
-                  "_reference": "USMOB",
-                  "name": "USMOB9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMIA10",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53974",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMSP10",
-               "port": {
-                  "_reference": "USMSP",
-                  "name": "USMSP11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USKCK12",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53975",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMSP12",
-               "port": {
-                  "_reference": "USMSP",
-                  "name": "USMSP13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USOMA12",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53981",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMSY8",
-               "port": {
-                  "_reference": "USMSY",
-                  "name": "USMSY9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USHOU24",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53987",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC4",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USATL12",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53988",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC6",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USBAL6",
-               "port": {
-                  "_reference": "USBAL",
-                  "name": "USBAL7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53993",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC8",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USHOU26",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53996",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC10",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USPDX4",
-               "port": {
-                  "_reference": "USPDX",
-                  "name": "USPDX5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53997",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC12",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USPHL2",
-               "port": {
-                  "_reference": "USPHL",
-                  "name": "USPHL3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53998",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC14",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC15"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USPIT6",
-               "port": {
-                  "_reference": "USPIT",
-                  "name": "USPIT7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "53999",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC16",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC17"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSEA8",
-               "port": {
-                  "_reference": "USSEA",
-                  "name": "USSEA9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54000",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USOAK0",
-               "port": {
-                  "_reference": "USOAK",
-                  "name": "USOAK1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USDEN0",
-               "port": {
-                  "_reference": "USDEN",
-                  "name": "USDEN1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54001",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USOAK2",
-               "port": {
-                  "_reference": "USOAK",
-                  "name": "USOAK3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USSLC0",
-               "port": {
-                  "_reference": "USSLC",
-                  "name": "USSLC1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54014",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USORF0",
-               "port": {
-                  "_reference": "USORF",
-                  "name": "USORF1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USBOS4",
-               "port": {
-                  "_reference": "USBOS",
-                  "name": "USBOS5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54029",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USPHL4",
-               "port": {
-                  "_reference": "USPHL",
-                  "name": "USPHL5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USBAL8",
-               "port": {
-                  "_reference": "USBAL",
-                  "name": "USBAL9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54030",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USPHL6",
-               "port": {
-                  "_reference": "USPHL",
-                  "name": "USPHL7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USBOS6",
-               "port": {
-                  "_reference": "USBOS",
-                  "name": "USBOS7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54036",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USPHX0",
-               "port": {
-                  "_reference": "USPHX",
-                  "name": "USPHX1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USLGB14",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54038",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USPIT8",
-               "port": {
-                  "_reference": "USPIT",
-                  "name": "USPIT9"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USBOS8",
-               "port": {
-                  "_reference": "USBOS",
-                  "name": "USBOS9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54047",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USSAT4",
-               "port": {
-                  "_reference": "USSAT",
-                  "name": "USSAT5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USHOU28",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54049",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USSAT6",
-               "port": {
-                  "_reference": "USSAT",
-                  "name": "USSAT7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMSY10",
-               "port": {
-                  "_reference": "USMSY",
-                  "name": "USMSY11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54051",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USSAV0",
-               "port": {
-                  "_reference": "USSAV",
-                  "name": "USSAV1"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USBNA14",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54057",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USSAV2",
-               "port": {
-                  "_reference": "USSAV",
-                  "name": "USSAV3"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USJAX14",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54058",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USSAV4",
-               "port": {
-                  "_reference": "USSAV",
-                  "name": "USSAV5"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMEM16",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54059",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USSAV6",
-               "port": {
-                  "_reference": "USSAV",
-                  "name": "USSAV7"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USMIA12",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54078",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USSEA10",
-               "port": {
-                  "_reference": "USSEA",
-                  "name": "USSEA11"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USLGB16",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54081",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USSEA12",
-               "port": {
-                  "_reference": "USSEA",
-                  "name": "USSEA13"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "USTIW0",
-               "port": {
-                  "_reference": "USTIW",
-                  "name": "USTIW1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54100",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH20",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH21"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INCCU16",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54102",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH22",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH23"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INDEL34",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54104",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH24",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH25"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMAA26",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54105",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH26",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMUN18",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54106",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH28",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INNAH16",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54107",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH30",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INTUT20",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54113",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH32",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU32",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54114",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH34",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG32",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54119",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH36",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN30",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54124",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH38",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH39"
-               }
-            },
-            {
-               "date": "2010-12-06",
-               "name": "VNSGN24",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54132",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN26",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN27"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INDEL36",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54134",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN28",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN29"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMAA28",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54135",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN30",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN31"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INMUN20",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54136",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN32",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN33"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INNAH18",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54137",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN34",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN35"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "INTUT22",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54140",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN36",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN37"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "LKCMB18",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54142",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN38",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN39"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPEN24",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54143",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN40",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN41"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPGU34",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54144",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN42",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN43"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "MYPKG34",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54149",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN44",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN45"
-               }
-            },
-            {
-               "date": "2010-12-08",
-               "name": "SGSIN32",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54166",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEDXB10",
-               "port": {
-                  "_reference": "AEDXB",
-                  "name": "AEDXB11"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "AEAUH12",
-               "port": {
-                  "_reference": "AEAUH",
-                  "name": "AEAUH13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54167",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEDXB12",
-               "port": {
-                  "_reference": "AEDXB",
-                  "name": "AEDXB13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "AEJEA16",
-               "port": {
-                  "_reference": "AEJEA",
-                  "name": "AEJEA17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54168",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEDXB14",
-               "port": {
-                  "_reference": "AEDXB",
-                  "name": "AEDXB15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "AEKLF10",
-               "port": {
-                  "_reference": "AEKLF",
-                  "name": "AEKLF11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54188",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEKLF12",
-               "port": {
-                  "_reference": "AEKLF",
-                  "name": "AEKLF13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "AEAUH14",
-               "port": {
-                  "_reference": "AEAUH",
-                  "name": "AEAUH15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54189",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AEKLF14",
-               "port": {
-                  "_reference": "AEKLF",
-                  "name": "AEKLF15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "AEDXB16",
-               "port": {
-                  "_reference": "AEDXB",
-                  "name": "AEDXB17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54201",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ARBUE0",
-               "port": {
-                  "_reference": "ARBUE",
-                  "name": "ARBUE1"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "BRRIO4",
-               "port": {
-                  "_reference": "BRRIO",
-                  "name": "BRRIO5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54215",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE38",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE39"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEFRA36",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54258",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ATVIE40",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE41"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITLIV2",
-               "port": {
-                  "_reference": "ITLIV",
-                  "name": "ITLIV3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54298",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AUSYD4",
-               "port": {
-                  "_reference": "AUSYD",
-                  "name": "AUSYD5"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "AUBNE4",
-               "port": {
-                  "_reference": "AUBNE",
-                  "name": "AUBNE5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54299",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "AUSYD6",
-               "port": {
-                  "_reference": "AUSYD",
-                  "name": "AUSYD7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "AUMEL4",
-               "port": {
-                  "_reference": "AUMEL",
-                  "name": "AUMEL5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54356",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BEANR52",
-               "port": {
-                  "_reference": "BEANR",
-                  "name": "BEANR53"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITMIL28",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54428",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BEAVL14",
-               "port": {
-                  "_reference": "BEAVL",
-                  "name": "BEAVL15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FRSXB27",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB28"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54456",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BEAVL16",
-               "port": {
-                  "_reference": "BEAVL",
-                  "name": "BEAVL17"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "LVRIX4",
-               "port": {
-                  "_reference": "LVRIX",
-                  "name": "LVRIX5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54494",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BRITJ6",
-               "port": {
-                  "_reference": "BRITJ",
-                  "name": "BRITJ7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "BRRIG4",
-               "port": {
-                  "_reference": "BRRIG",
-                  "name": "BRRIG5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54502",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BRRIO6",
-               "port": {
-                  "_reference": "BRRIO",
-                  "name": "BRRIO7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "BRITJ8",
-               "port": {
-                  "_reference": "BRITJ",
-                  "name": "BRITJ9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54503",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BRRIO8",
-               "port": {
-                  "_reference": "BRRIO",
-                  "name": "BRRIO9"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "BRRIG6",
-               "port": {
-                  "_reference": "BRRIG",
-                  "name": "BRRIG7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54506",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BRSSZ2",
-               "port": {
-                  "_reference": "BRSSZ",
-                  "name": "BRSSZ3"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "BRITJ10",
-               "port": {
-                  "_reference": "BRITJ",
-                  "name": "BRITJ11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54507",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "BRSSZ4",
-               "port": {
-                  "_reference": "BRSSZ",
-                  "name": "BRSSZ5"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "BRRIG8",
-               "port": {
-                  "_reference": "BRRIG",
-                  "name": "BRRIG9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54509",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CACAL8",
-               "port": {
-                  "_reference": "CACAL",
-                  "name": "CACAL9"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CAMTR10",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54516",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAMTR12",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CACAL10",
-               "port": {
-                  "_reference": "CACAL",
-                  "name": "CACAL11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54517",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAMTR14",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CAREG0",
-               "port": {
-                  "_reference": "CAREG",
-                  "name": "CAREG1"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54518",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAMTR16",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CASAK4",
-               "port": {
-                  "_reference": "CASAK",
-                  "name": "CASAK5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54520",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAMTR18",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CAVAN16",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54521",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAMTR20",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CAWNP8",
-               "port": {
-                  "_reference": "CAWNP",
-                  "name": "CAWNP9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54522",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAMTR22",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CAYEA6",
-               "port": {
-                  "_reference": "CAYEA",
-                  "name": "CAYEA7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54525",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAREG2",
-               "port": {
-                  "_reference": "CAREG",
-                  "name": "CAREG3"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CASAK6",
-               "port": {
-                  "_reference": "CASAK",
-                  "name": "CASAK7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54537",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR18",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CACAL12",
-               "port": {
-                  "_reference": "CACAL",
-                  "name": "CACAL13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54538",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR20",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CAMTR24",
-               "port": {
-                  "_reference": "CAMTR",
-                  "name": "CAMTR25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54540",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR22",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CASAK8",
-               "port": {
-                  "_reference": "CASAK",
-                  "name": "CASAK9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54541",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR24",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CAVAN18",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54542",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR26",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CAWNP10",
-               "port": {
-                  "_reference": "CAWNP",
-                  "name": "CAWNP11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54543",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CATOR28",
-               "port": {
-                  "_reference": "CATOR",
-                  "name": "CATOR29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CAYEA8",
-               "port": {
-                  "_reference": "CAYEA",
-                  "name": "CAYEA9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54552",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAVAN20",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CACAL14",
-               "port": {
-                  "_reference": "CACAL",
-                  "name": "CACAL15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54555",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAVAN22",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CASAK10",
-               "port": {
-                  "_reference": "CASAK",
-                  "name": "CASAK11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54557",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAVAN24",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CAWNP12",
-               "port": {
-                  "_reference": "CAWNP",
-                  "name": "CAWNP13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54558",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CAVAN26",
-               "port": {
-                  "_reference": "CAVAN",
-                  "name": "CAVAN27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CAYEA10",
-               "port": {
-                  "_reference": "CAYEA",
-                  "name": "CAYEA11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54612",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHBSL10",
-               "port": {
-                  "_reference": "CHBSL",
-                  "name": "CHBSL11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FIKTK64",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK65"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54647",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHBSL12",
-               "port": {
-                  "_reference": "CHBSL",
-                  "name": "CHBSL13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "MACAS6",
-               "port": {
-                  "_reference": "MACAS",
-                  "name": "MACAS7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54654",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHBSL14",
-               "port": {
-                  "_reference": "CHBSL",
-                  "name": "CHBSL15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "PLGDN8",
-               "port": {
-                  "_reference": "PLGDN",
-                  "name": "PLGDN9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54697",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHZRH8",
-               "port": {
-                  "_reference": "CHZRH",
-                  "name": "CHZRH9"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ESBCN24",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54709",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHZRH10",
-               "port": {
-                  "_reference": "CHZRH",
-                  "name": "CHZRH11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FRSXB29",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB30"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54714",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHZRH12",
-               "port": {
-                  "_reference": "CHZRH",
-                  "name": "CHZRH13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBLBA24",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54751",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CHZRH14",
-               "port": {
-                  "_reference": "CHZRH",
-                  "name": "CHZRH15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "RULED74",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED75"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54763",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG14",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCHS20",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54764",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG16",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCWN22",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54770",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG18",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNAH14",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54772",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG20",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG24",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54773",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG22",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNTG32",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54777",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG24",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAO24",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54778",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNCHG26",
-               "port": {
-                  "_reference": "CNCHG",
-                  "name": "CNCHG27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAZ26",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54835",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNDLC16",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG26",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54848",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC22",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCHS22",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54849",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC24",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCWN24",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54850",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC26",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNDLC18",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54854",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC28",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNAH16",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54856",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC30",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG28",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54857",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC32",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNTG34",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54858",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC34",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNSHA14",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54862",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC36",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAZ28",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54863",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC38",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC39"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNWUH24",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54864",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC40",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC41"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXGG18",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54865",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNFOC42",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC43"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXMN20",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54869",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG14",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCHS24",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54870",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG16",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCWN26",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54871",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG18",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNDLC20",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54875",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG20",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNAH18",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54877",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG22",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG30",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54878",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG24",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNTG36",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54879",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG26",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNSHA16",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54882",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG28",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAO26",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54883",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG30",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAZ30",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54884",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG32",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNWUH26",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54885",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHKG34",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXGG20",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54890",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA26",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCHS26",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54891",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA28",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCWN28",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54897",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA30",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNBO16",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54898",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA32",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG32",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54899",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA34",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNTG38",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54900",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA36",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNSHA18",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54904",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA38",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA39"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAZ32",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54905",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA40",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA41"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXGG22",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54907",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA42",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA43"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNYIT16",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54908",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA44",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA45"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNYZO16",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54909",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNHUA46",
-               "port": {
-                  "_reference": "CNHUA",
-                  "name": "CNHUA47"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNZJG30",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54934",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNAH20",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNDLC22",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54936",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNAH22",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNHKG36",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54940",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNAH24",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG34",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54945",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNAH26",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAZ34",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54948",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNAH28",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXMN22",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54953",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO18",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCHS28",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54954",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO20",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCWN30",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54955",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO22",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNDLC24",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54960",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO24",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNAH30",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54961",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO26",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNTG40",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54965",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO28",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAO28",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54966",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO30",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAZ36",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54967",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO32",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNWUH28",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54968",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNBO34",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXGG24",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "54995",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG42",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG43"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCWN32",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55003",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG44",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG45"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG36",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55005",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG46",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG47"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNSXC20",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55008",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG48",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG49"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAZ38",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55010",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG50",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG51"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXGG26",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55013",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG52",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG53"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNYZO18",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55014",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNNTG54",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG55"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNZJG32",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55037",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC22",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCHS30",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55038",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC24",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCWN34",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55039",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC26",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNFOC44",
-               "port": {
-                  "_reference": "CNFOC",
-                  "name": "CNFOC45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55045",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC28",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG38",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55046",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC30",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNTG56",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG57"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55047",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC32",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNSHA20",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55049",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC34",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAO30",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55051",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC36",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNWUH30",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55052",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC38",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC39"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXGG28",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55054",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC40",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC41"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNYIT18",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55055",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNSXC42",
-               "port": {
-                  "_reference": "CNSXC",
-                  "name": "CNSXC43"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNYZO20",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55058",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC19",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC20"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCHS32",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55059",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC21",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC22"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCWN36",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55067",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC23",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC24"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG40",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55068",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC25",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC26"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNTG58",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG59"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55072",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC27",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC28"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAZ40",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55074",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC29",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC30"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXGG30",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55075",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC31",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC32"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNYIT20",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55076",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC33",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC34"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNYZO22",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55077",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAC35",
-               "port": {
-                  "_reference": "CNTAC",
-                  "name": "CNTAC36"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNZJG34",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55082",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAO32",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNHKG38",
-               "port": {
-                  "_reference": "CNHKG",
-                  "name": "CNHKG39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55087",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAO34",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG42",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55098",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNTAO36",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNZJG36",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55122",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH32",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCWN38",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55130",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH34",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG44",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55131",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH36",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNTG60",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG61"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55135",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH38",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH39"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAZ42",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55136",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH40",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH41"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXGG32",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55138",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNWUH42",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH43"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNYIT22",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55144",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXGG34",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNDLC26",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55155",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXGG36",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAO38",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55163",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN24",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCHS34",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55164",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN26",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCWN40",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55173",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN28",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNSHA22",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55177",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN30",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAZ44",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55178",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN32",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNWUH44",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55179",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN34",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXGG38",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55181",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNXMN36",
-               "port": {
-                  "_reference": "CNXMN",
-                  "name": "CNXMN37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNYZO24",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55192",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNYIT24",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG46",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55203",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNYIT26",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNZJG38",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55213",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNYZO26",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG48",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG49"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55223",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNYZO28",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNYIT28",
-               "port": {
-                  "_reference": "CNYIT",
-                  "name": "CNYIT29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55226",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG40",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG41"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCHS36",
-               "port": {
-                  "_reference": "CNCHS",
-                  "name": "CNCHS37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55227",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG42",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG43"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNCWN42",
-               "port": {
-                  "_reference": "CNCWN",
-                  "name": "CNCWN43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55228",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG44",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG45"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNDLC28",
-               "port": {
-                  "_reference": "CNDLC",
-                  "name": "CNDLC29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55232",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG46",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG47"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNAH32",
-               "port": {
-                  "_reference": "CNNAH",
-                  "name": "CNNAH33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55233",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG48",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG49"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNBO36",
-               "port": {
-                  "_reference": "CNNBO",
-                  "name": "CNNBO37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55234",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG50",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG51"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNKG50",
-               "port": {
-                  "_reference": "CNNKG",
-                  "name": "CNNKG51"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55235",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG52",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG53"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNNTG62",
-               "port": {
-                  "_reference": "CNNTG",
-                  "name": "CNNTG63"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55236",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG54",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG55"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNSHA24",
-               "port": {
-                  "_reference": "CNSHA",
-                  "name": "CNSHA25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55239",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG56",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG57"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAO40",
-               "port": {
-                  "_reference": "CNTAO",
-                  "name": "CNTAO41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55240",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG58",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG59"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNTAZ46",
-               "port": {
-                  "_reference": "CNTAZ",
-                  "name": "CNTAZ47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55241",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG60",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG61"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNWUH46",
-               "port": {
-                  "_reference": "CNWUH",
-                  "name": "CNWUH47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55242",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG62",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG63"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNXGG40",
-               "port": {
-                  "_reference": "CNXGG",
-                  "name": "CNXGG41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55245",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CNZJG64",
-               "port": {
-                  "_reference": "CNZJG",
-                  "name": "CNZJG65"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CNYZO30",
-               "port": {
-                  "_reference": "CNYZO",
-                  "name": "CNYZO31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55250",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CYLMS12",
-               "port": {
-                  "_reference": "CYLMS",
-                  "name": "CYLMS13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "CHZRH16",
-               "port": {
-                  "_reference": "CHZRH",
-                  "name": "CHZRH17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55318",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CYLMS14",
-               "port": {
-                  "_reference": "CYLMS",
-                  "name": "CYLMS15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NOOSL70",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL71"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55343",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZPRG30",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "CZZLN40",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55348",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZPRG32",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEDUS34",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55400",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZPRG34",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG35"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "LBBEY10",
-               "port": {
-                  "_reference": "LBBEY",
-                  "name": "LBBEY11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55473",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "CZZLN42",
-               "port": {
-                  "_reference": "CZZLN",
-                  "name": "CZZLN43"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBTHP14",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55570",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBER28",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER29"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "IEORK44",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55571",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBER30",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER31"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITAOI12",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55579",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBER32",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITSAL8",
-               "port": {
-                  "_reference": "ITSAL",
-                  "name": "ITSAL9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55593",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBER34",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER35"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "PLGDY52",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY53"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55627",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBFE30",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DESTR46",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55659",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBFE32",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "HUBUD28",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55660",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBFE34",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE35"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "IEDUB40",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55662",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBFE36",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE37"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITAOI14",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55696",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBFE38",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE39"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SYTTS6",
-               "port": {
-                  "_reference": "SYTTS",
-                  "name": "SYTTS7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55709",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE22",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEBER36",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55710",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE24",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEBFE40",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55711",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE26",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEBRV68",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV69"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55712",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE28",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEDUS36",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55713",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE30",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEFRA38",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55714",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE32",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEGER34",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55716",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE34",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEMUC42",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55717",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE36",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DENUE32",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55718",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE38",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE39"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DESTR48",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR49"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55745",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE40",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE41"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBMAN26",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55755",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE42",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE43"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITGOA18",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55788",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRE44",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE45"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "TNTUN8",
-               "port": {
-                  "_reference": "TNTUN",
-                  "name": "TNTUN9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55836",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEBRV70",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV71"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBMAN28",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55939",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEDUS38",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS39"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITMIL30",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "55983",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEFRA40",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA41"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEBFE42",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56006",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEFRA42",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA43"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FRBOD34",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56046",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEFRA44",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA45"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NOOSL72",
-               "port": {
-                  "_reference": "NOOSL",
-                  "name": "NOOSL73"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56053",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEFRA46",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA47"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "RULED76",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED77"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56061",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEFRA48",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA49"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "TNTUN10",
-               "port": {
-                  "_reference": "TNTUN",
-                  "name": "TNTUN11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56133",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEGER36",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER37"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NLTLB28",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56149",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEGER38",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER39"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SILJU10",
-               "port": {
-                  "_reference": "SILJU",
-                  "name": "SILJU11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56164",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEHAM4",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM5"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEBER38",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56165",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEHAM6",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEBFE44",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56168",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEHAM8",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM9"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEDUS40",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56169",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEHAM10",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM11"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEFRA50",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA51"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56170",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEHAM12",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEGER40",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56171",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEHAM14",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEMUC44",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56172",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEHAM16",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DENUE34",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56173",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEHAM18",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DESTR50",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR51"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56257",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEMUC46",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC47"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEBRE46",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56259",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEMUC48",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC49"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DEDUS42",
-               "port": {
-                  "_reference": "DEDUS",
-                  "name": "DEDUS43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56286",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEMUC50",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC51"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBBHM24",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56308",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DEMUC52",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC53"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITSPE14",
-               "port": {
-                  "_reference": "ITSPE",
-                  "name": "ITSPE15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56376",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DENUE36",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE37"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBBEL28",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56398",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DENUE38",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE39"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITSAL10",
-               "port": {
-                  "_reference": "ITSAL",
-                  "name": "ITSAL11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56500",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DESTR52",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR53"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NOKRS30",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56504",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DESTR54",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR55"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "PLSZZ32",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56539",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR60",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR61"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "DKCPH20",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56554",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKAAR62",
-               "port": {
-                  "_reference": "DKAAR",
-                  "name": "DKAAR63"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FRLEH4",
-               "port": {
-                  "_reference": "FRLEH",
-                  "name": "FRLEH5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56627",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKCPH22",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH23"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEMUC54",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC55"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56637",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKCPH24",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH25"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ESBIO16",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56680",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DKCPH26",
-               "port": {
-                  "_reference": "DKCPH",
-                  "name": "DKCPH27"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NOAES8",
-               "port": {
-                  "_reference": "NOAES",
-                  "name": "NOAES9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56740",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DZALG10",
-               "port": {
-                  "_reference": "DZALG",
-                  "name": "DZALG11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBBEL30",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56763",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DZALG12",
-               "port": {
-                  "_reference": "DZALG",
-                  "name": "DZALG13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITSPE16",
-               "port": {
-                  "_reference": "ITSPE",
-                  "name": "ITSPE17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56780",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "DZALG14",
-               "port": {
-                  "_reference": "DZALG",
-                  "name": "DZALG15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ROCND10",
-               "port": {
-                  "_reference": "ROCND",
-                  "name": "ROCND11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "56984",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EGDAM10",
-               "port": {
-                  "_reference": "EGDAM",
-                  "name": "EGDAM11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEBFE46",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57046",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EGDAM12",
-               "port": {
-                  "_reference": "EGDAM",
-                  "name": "EGDAM13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NOKRS32",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57149",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "EGPSD8",
-               "port": {
-                  "_reference": "EGPSD",
-                  "name": "EGPSD9"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SIKOP24",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57182",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBCN26",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN27"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "EGPSD10",
-               "port": {
-                  "_reference": "EGPSD",
-                  "name": "EGPSD11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57183",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBCN28",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ESBIO18",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57185",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBCN30",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ESMAD22",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57196",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBCN32",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBBHM26",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57274",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBIO20",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ESBCN34",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57316",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESBIO22",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO23"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NLTLB30",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57366",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESLPA16",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ESBIO24",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57368",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESLPA18",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ESVLC28",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57396",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESLPA20",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA21"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITMOD18",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57456",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESMAD24",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ESBCN36",
-               "port": {
-                  "_reference": "ESBCN",
-                  "name": "ESBCN37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57467",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESMAD26",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD27"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FRSXB31",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB32"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57550",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ESVLC30",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ESMAD28",
-               "port": {
-                  "_reference": "ESMAD",
-                  "name": "ESMAD29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57701",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIHEL54",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL55"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "TRIZM6",
-               "port": {
-                  "_reference": "TRIZM",
-                  "name": "TRIZM7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57748",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK66",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK67"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBTHP16",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57761",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FIKTK68",
-               "port": {
-                  "_reference": "FIKTK",
-                  "name": "FIKTK69"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITNAP40",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "57962",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRFOS26",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS27"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "PTLIS46",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58009",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRLEH6",
-               "port": {
-                  "_reference": "FRLEH",
-                  "name": "FRLEH7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "FRBOD36",
-               "port": {
-                  "_reference": "FRBOD",
-                  "name": "FRBOD37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58010",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRLEH8",
-               "port": {
-                  "_reference": "FRLEH",
-                  "name": "FRLEH9"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "FRFOS28",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58011",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRLEH10",
-               "port": {
-                  "_reference": "FRLEH",
-                  "name": "FRLEH11"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "FRPAR38",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58012",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRLEH12",
-               "port": {
-                  "_reference": "FRLEH",
-                  "name": "FRLEH13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "FRRNS22",
-               "port": {
-                  "_reference": "FRRNS",
-                  "name": "FRRNS23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58013",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRLEH14",
-               "port": {
-                  "_reference": "FRLEH",
-                  "name": "FRLEH15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "FRSXB33",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB34"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58094",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRPAR40",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR41"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ESBIO26",
-               "port": {
-                  "_reference": "ESBIO",
-                  "name": "ESBIO27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58313",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "FRSXB35",
-               "port": {
-                  "_reference": "FRSXB",
-                  "name": "FRSXB36"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "LTKLJ6",
-               "port": {
-                  "_reference": "LTKLJ",
-                  "name": "LTKLJ7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58350",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBEL32",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEBRE48",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE49"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58368",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBEL34",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL35"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ESLPA22",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58380",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBEL36",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBFXT14",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58447",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBHM28",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM29"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEMUC56",
-               "port": {
-                  "_reference": "DEMUC",
-                  "name": "DEMUC57"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58452",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBHM30",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM31"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DZALG16",
-               "port": {
-                  "_reference": "DZALG",
-                  "name": "DZALG17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58473",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBHM32",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBLBA26",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58476",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBBHM34",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBTHP18",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58552",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT16",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT17"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ESVLC32",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58561",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT18",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBBEL38",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58562",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT20",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBBHM36",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58563",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT22",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBGLW30",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58564",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT24",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBLBA28",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58565",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT26",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBLIV24",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58566",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT28",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBMAN30",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58568",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT30",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBTIL32",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58572",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBFXT32",
-               "port": {
-                  "_reference": "GBFXT",
-                  "name": "GBFXT33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "IEDUB42",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58693",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBGLW32",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SEGOT62",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT63"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58779",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBLBA30",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA31"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "PLSZZ34",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58809",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBLIV26",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV27"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEGER42",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58916",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBMAN32",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ESVLC34",
-               "port": {
-                  "_reference": "ESVLC",
-                  "name": "ESVLC35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58922",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBMAN34",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN35"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FRPAR42",
-               "port": {
-                  "_reference": "FRPAR",
-                  "name": "FRPAR43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58928",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBMAN36",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBGLW34",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58932",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBMAN38",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN39"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBTIL34",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "58983",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP20",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP21"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "CZPRG36",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59002",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP22",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP23"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "EGPSD12",
-               "port": {
-                  "_reference": "EGPSD",
-                  "name": "EGPSD13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59016",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP24",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBBEL40",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59017",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP26",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBBHM38",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59019",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP28",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBGLW36",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59020",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP30",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBLBA32",
-               "port": {
-                  "_reference": "GBLBA",
-                  "name": "GBLBA33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59021",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP32",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBLIV28",
-               "port": {
-                  "_reference": "GBLIV",
-                  "name": "GBLIV29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59022",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP34",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBMAN40",
-               "port": {
-                  "_reference": "GBMAN",
-                  "name": "GBMAN41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59023",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP36",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "GBTIL36",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59063",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GBTHP38",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP39"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SYTTS8",
-               "port": {
-                  "_reference": "SYTTS",
-                  "name": "SYTTS9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59184",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRPIR4",
-               "port": {
-                  "_reference": "GRPIR",
-                  "name": "GRPIR5"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "EGPSD14",
-               "port": {
-                  "_reference": "EGPSD",
-                  "name": "EGPSD15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59187",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "GRPIR6",
-               "port": {
-                  "_reference": "GRPIR",
-                  "name": "GRPIR7"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ESLPA24",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59417",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "HUBUD30",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD31"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "PLSZZ36",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59451",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW24",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW25"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "MYPKG36",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59455",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDBLW26",
-               "port": {
-                  "_reference": "IDBLW",
-                  "name": "IDBLW27"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "PKKHI28",
-               "port": {
-                  "_reference": "PKKHI",
-                  "name": "PKKHI29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59464",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT34",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "IDSRG18",
-               "port": {
-                  "_reference": "IDSRG",
-                  "name": "IDSRG19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59465",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT36",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "IDSUB28",
-               "port": {
-                  "_reference": "IDSUB",
-                  "name": "IDSUB29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59480",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IDJKT38",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT39"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "MYPGU36",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59636",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEDUB44",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB45"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SIKOP26",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59653",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK46",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK47"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEBFE48",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE49"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59695",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "IEORK48",
-               "port": {
-                  "_reference": "IEORK",
-                  "name": "IEORK49"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "IEDUB46",
-               "port": {
-                  "_reference": "IEDUB",
-                  "name": "IEDUB47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59771",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCCU18",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "INDEL38",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59775",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCCU20",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "INNAH20",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59776",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCCU22",
-               "port": {
-                  "_reference": "INCCU",
-                  "name": "INCCU23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "INTUT24",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59814",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INCOK14",
-               "port": {
-                  "_reference": "INCOK",
-                  "name": "INCOK15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "PHCEB20",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59826",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INDEL40",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL41"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "IDJKT40",
-               "port": {
-                  "_reference": "IDJKT",
-                  "name": "IDJKT41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59892",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA30",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "INDEL42",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59894",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA32",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "INMUN22",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59895",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA34",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "INNAH22",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59896",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMAA36",
-               "port": {
-                  "_reference": "INMAA",
-                  "name": "INMAA37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "INTUT26",
-               "port": {
-                  "_reference": "INTUT",
-                  "name": "INTUT27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "59921",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "INMUN24",
-               "port": {
-                  "_reference": "INMUN",
-                  "name": "INMUN25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "INCOK16",
-               "port": {
-                  "_reference": "INCOK",
-                  "name": "INCOK17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60052",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITAOI16",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI17"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "CZPRG38",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60103",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITAOI18",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITMOD20",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60104",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITAOI20",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITNAP42",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60137",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGIT16",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT17"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ATVIE42",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60142",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGIT18",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT19"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "CYLMS16",
-               "port": {
-                  "_reference": "CYLMS",
-                  "name": "CYLMS17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60190",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGIT20",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITAOI22",
-               "port": {
-                  "_reference": "ITAOI",
-                  "name": "ITAOI23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60205",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGIT22",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT23"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NLTLB32",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60221",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGIT24",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT25"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SILJU12",
-               "port": {
-                  "_reference": "SILJU",
-                  "name": "SILJU13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60228",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGOA20",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA21"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ATVIE44",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60242",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGOA22",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA23"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEGER44",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60285",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGOA24",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITMOD22",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60286",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGOA26",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITNAP44",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60287",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITGOA28",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITPDA34",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60319",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITLIV4",
-               "port": {
-                  "_reference": "ITLIV",
-                  "name": "ITLIV5"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ATVIE46",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60379",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITLIV6",
-               "port": {
-                  "_reference": "ITLIV",
-                  "name": "ITLIV7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITSAL12",
-               "port": {
-                  "_reference": "ITSAL",
-                  "name": "ITSAL13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60399",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITLIV8",
-               "port": {
-                  "_reference": "ITLIV",
-                  "name": "ITLIV9"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SEGOT64",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT65"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60444",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITMIL32",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FRFOS30",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60468",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITMIL34",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITNAP46",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60469",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITMIL36",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITPDA36",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60481",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITMIL38",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL39"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NOKRS34",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60600",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITNAP48",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP49"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEBER40",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60647",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITNAP50",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP51"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITGOA30",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60649",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITNAP52",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP53"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITMIL40",
-               "port": {
-                  "_reference": "ITMIL",
-                  "name": "ITMIL41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60651",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITNAP54",
-               "port": {
-                  "_reference": "ITNAP",
-                  "name": "ITNAP55"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITPDA38",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60688",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITPDA40",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA41"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "CYLMS18",
-               "port": {
-                  "_reference": "CYLMS",
-                  "name": "CYLMS19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60731",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITPDA42",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA43"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GRPIR8",
-               "port": {
-                  "_reference": "GRPIR",
-                  "name": "GRPIR9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60741",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITPDA44",
-               "port": {
-                  "_reference": "ITPDA",
-                  "name": "ITPDA45"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "ITMOD24",
-               "port": {
-                  "_reference": "ITMOD",
-                  "name": "ITMOD25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60784",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITSAL14",
-               "port": {
-                  "_reference": "ITSAL",
-                  "name": "ITSAL15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEBRE50",
-               "port": {
-                  "_reference": "DEBRE",
-                  "name": "DEBRE51"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60876",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITSPE18",
-               "port": {
-                  "_reference": "ITSPE",
-                  "name": "ITSPE19"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEBRV72",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV73"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60879",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITSPE20",
-               "port": {
-                  "_reference": "ITSPE",
-                  "name": "ITSPE21"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEGER46",
-               "port": {
-                  "_reference": "DEGER",
-                  "name": "DEGER47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "60974",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITVCE10",
-               "port": {
-                  "_reference": "ITVCE",
-                  "name": "ITVCE11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DESTR56",
-               "port": {
-                  "_reference": "DESTR",
-                  "name": "DESTR57"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61026",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ITVCE12",
-               "port": {
-                  "_reference": "ITVCE",
-                  "name": "ITVCE13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NOBGO4",
-               "port": {
-                  "_reference": "NOBGO",
-                  "name": "NOBGO5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61049",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHIJ14",
-               "port": {
-                  "_reference": "JPHIJ",
-                  "name": "JPHIJ15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPHSA16",
-               "port": {
-                  "_reference": "JPHSA",
-                  "name": "JPHSA17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61056",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHIJ16",
-               "port": {
-                  "_reference": "JPHIJ",
-                  "name": "JPHIJ17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPSMZ24",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61063",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHIJ18",
-               "port": {
-                  "_reference": "JPHIJ",
-                  "name": "JPHIJ19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPYKK16",
-               "port": {
-                  "_reference": "JPYKK",
-                  "name": "JPYKK17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61066",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT10",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT11"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPHSA18",
-               "port": {
-                  "_reference": "JPHSA",
-                  "name": "JPHSA19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61071",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT12",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPNGO24",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61073",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT14",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPSMZ26",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61077",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT16",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPTOY14",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61079",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT18",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPUKB10",
-               "port": {
-                  "_reference": "JPUKB",
-                  "name": "JPUKB11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61080",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT20",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPYKK18",
-               "port": {
-                  "_reference": "JPYKK",
-                  "name": "JPYKK19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61081",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPHKT22",
-               "port": {
-                  "_reference": "JPHKT",
-                  "name": "JPHKT23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPYOK20",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61140",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPKNZ4",
-               "port": {
-                  "_reference": "JPKNZ",
-                  "name": "JPKNZ5"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPOSA10",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61191",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPOSA12",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPNGO26",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61192",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPOSA14",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPSMZ28",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61196",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPOSA16",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPTOY16",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61198",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPOSA18",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPUKB12",
-               "port": {
-                  "_reference": "JPUKB",
-                  "name": "JPUKB13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61200",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPOSA20",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPYOK22",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61209",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPSMZ30",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPOSA22",
-               "port": {
-                  "_reference": "JPOSA",
-                  "name": "JPOSA23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61242",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTKY14",
-               "port": {
-                  "_reference": "JPTKY",
-                  "name": "JPTKY15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPNGO28",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61247",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTKY16",
-               "port": {
-                  "_reference": "JPTKY",
-                  "name": "JPTKY17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPTOY18",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61251",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTKY18",
-               "port": {
-                  "_reference": "JPTKY",
-                  "name": "JPTKY19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPYOK24",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61254",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK12",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPHSA20",
-               "port": {
-                  "_reference": "JPHSA",
-                  "name": "JPHSA21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61258",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK14",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPMOJ8",
-               "port": {
-                  "_reference": "JPMOJ",
-                  "name": "JPMOJ9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61259",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK16",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPNGO30",
-               "port": {
-                  "_reference": "JPNGO",
-                  "name": "JPNGO31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61261",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK18",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPSMZ32",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61264",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK20",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPTOY20",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61267",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK22",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPYKK20",
-               "port": {
-                  "_reference": "JPYKK",
-                  "name": "JPYKK21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61268",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTMK24",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPYOK26",
-               "port": {
-                  "_reference": "JPYOK",
-                  "name": "JPYOK27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61278",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTOY22",
-               "port": {
-                  "_reference": "JPTOY",
-                  "name": "JPTOY23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPSMZ34",
-               "port": {
-                  "_reference": "JPSMZ",
-                  "name": "JPSMZ35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61298",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "JPTYO12",
-               "port": {
-                  "_reference": "JPTYO",
-                  "name": "JPTYO13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "JPTMK26",
-               "port": {
-                  "_reference": "JPTMK",
-                  "name": "JPTMK27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61386",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KREIW5",
-               "port": {
-                  "_reference": "KREIW",
-                  "name": "KREIW6"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "KRKAN8",
-               "port": {
-                  "_reference": "KRKAN",
-                  "name": "KRKAN9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61389",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KRINC4",
-               "port": {
-                  "_reference": "KRINC",
-                  "name": "KRINC5"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "KREIW7",
-               "port": {
-                  "_reference": "KREIW",
-                  "name": "KREIW8"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61391",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KRINC6",
-               "port": {
-                  "_reference": "KRINC",
-                  "name": "KRINC7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "KRKAN10",
-               "port": {
-                  "_reference": "KRKAN",
-                  "name": "KRKAN11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61409",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KRPUS4",
-               "port": {
-                  "_reference": "KRPUS",
-                  "name": "KRPUS5"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "KREIW9",
-               "port": {
-                  "_reference": "KREIW",
-                  "name": "KREIW10"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61411",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KRPUS6",
-               "port": {
-                  "_reference": "KRPUS",
-                  "name": "KRPUS7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "KRJCW2",
-               "port": {
-                  "_reference": "KRJCW",
-                  "name": "KRJCW3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61412",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KRPUS8",
-               "port": {
-                  "_reference": "KRPUS",
-                  "name": "KRPUS9"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "KRKAN12",
-               "port": {
-                  "_reference": "KRKAN",
-                  "name": "KRKAN13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61423",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "KWKWI10",
-               "port": {
-                  "_reference": "KWKWI",
-                  "name": "KWKWI11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SADMN4",
-               "port": {
-                  "_reference": "SADMN",
-                  "name": "SADMN5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61490",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LBBEY12",
-               "port": {
-                  "_reference": "LBBEY",
-                  "name": "LBBEY13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "LVRIX6",
-               "port": {
-                  "_reference": "LVRIX",
-                  "name": "LVRIX7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61518",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LKCMB20",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB21"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "IDSRG20",
-               "port": {
-                  "_reference": "IDSRG",
-                  "name": "IDSRG21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61530",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LKCMB22",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB23"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "KHPNH26",
-               "port": {
-                  "_reference": "KHPNH",
-                  "name": "KHPNH27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61539",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LKCMB24",
-               "port": {
-                  "_reference": "LKCMB",
-                  "name": "LKCMB25"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SGSIN34",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61559",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LTKLJ8",
-               "port": {
-                  "_reference": "LTKLJ",
-                  "name": "LTKLJ9"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEFRA52",
-               "port": {
-                  "_reference": "DEFRA",
-                  "name": "DEFRA53"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61637",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LVRIX8",
-               "port": {
-                  "_reference": "LVRIX",
-                  "name": "LVRIX9"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ATVIE48",
-               "port": {
-                  "_reference": "ATVIE",
-                  "name": "ATVIE49"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61648",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "LVRIX10",
-               "port": {
-                  "_reference": "LVRIX",
-                  "name": "LVRIX11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEBRV74",
-               "port": {
-                  "_reference": "DEBRV",
-                  "name": "DEBRV75"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61745",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MACAS8",
-               "port": {
-                  "_reference": "MACAS",
-                  "name": "MACAS9"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DENUE40",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61759",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MACAS10",
-               "port": {
-                  "_reference": "MACAS",
-                  "name": "MACAS11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FIHEL56",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL57"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61853",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXGDL4",
-               "port": {
-                  "_reference": "MXGDL",
-                  "name": "MXGDL5"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "MXESE10",
-               "port": {
-                  "_reference": "MXESE",
-                  "name": "MXESE11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61859",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXMEX20",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "MXESE12",
-               "port": {
-                  "_reference": "MXESE",
-                  "name": "MXESE13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61862",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXMEX22",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "MXZLO4",
-               "port": {
-                  "_reference": "MXZLO",
-                  "name": "MXZLO5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61874",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXZLO6",
-               "port": {
-                  "_reference": "MXZLO",
-                  "name": "MXZLO7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "MXESE14",
-               "port": {
-                  "_reference": "MXESE",
-                  "name": "MXESE15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61876",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MXZLO8",
-               "port": {
-                  "_reference": "MXZLO",
-                  "name": "MXZLO9"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "MXMEX24",
-               "port": {
-                  "_reference": "MXMEX",
-                  "name": "MXMEX25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61895",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MYPEN26",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "MYPGU38",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "61896",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "MYPEN28",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "MYPKG38",
-               "port": {
-                  "_reference": "MYPKG",
-                  "name": "MYPKG39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62014",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLRTM58",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM59"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBTHP40",
-               "port": {
-                  "_reference": "GBTHP",
-                  "name": "GBTHP41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62127",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NLTLB34",
-               "port": {
-                  "_reference": "NLTLB",
-                  "name": "NLTLB35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "NLRTM60",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM61"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62190",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOAES10",
-               "port": {
-                  "_reference": "NOAES",
-                  "name": "NOAES11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBBHM40",
-               "port": {
-                  "_reference": "GBBHM",
-                  "name": "GBBHM41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62237",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOAES12",
-               "port": {
-                  "_reference": "NOAES",
-                  "name": "NOAES13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "TNTUN12",
-               "port": {
-                  "_reference": "TNTUN",
-                  "name": "TNTUN13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62341",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS36",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS37"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEBFE50",
-               "port": {
-                  "_reference": "DEBFE",
-                  "name": "DEBFE51"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62347",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS38",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS39"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEHAM20",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62371",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS40",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS41"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBBEL42",
-               "port": {
-                  "_reference": "GBBEL",
-                  "name": "GBBEL43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62380",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "NOKRS42",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS43"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GRPIR10",
-               "port": {
-                  "_reference": "GRPIR",
-                  "name": "GRPIR11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62548",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHCEB22",
-               "port": {
-                  "_reference": "PHCEB",
-                  "name": "PHCEB23"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SGSIN36",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62566",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PHMNL30",
-               "port": {
-                  "_reference": "PHMNL",
-                  "name": "PHMNL31"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "INNAH24",
-               "port": {
-                  "_reference": "INNAH",
-                  "name": "INNAH25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62648",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDN10",
-               "port": {
-                  "_reference": "PLGDN",
-                  "name": "PLGDN11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "CHBSL16",
-               "port": {
-                  "_reference": "CHBSL",
-                  "name": "CHBSL17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62662",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDN12",
-               "port": {
-                  "_reference": "PLGDN",
-                  "name": "PLGDN13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DENUE42",
-               "port": {
-                  "_reference": "DENUE",
-                  "name": "DENUE43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62811",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY54",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY55"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "PLSZZ38",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62812",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLGDY56",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY57"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "PLWRP28",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62852",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ40",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ41"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "EGPSD16",
-               "port": {
-                  "_reference": "EGPSD",
-                  "name": "EGPSD17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62874",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ42",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ43"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBTIL38",
-               "port": {
-                  "_reference": "GBTIL",
-                  "name": "GBTIL39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62877",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ44",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ45"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "HUBUD32",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62902",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ46",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ47"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "PLGDY58",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY59"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62903",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ48",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ49"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "PLWRP30",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62914",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ50",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ51"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "TNTUN14",
-               "port": {
-                  "_reference": "TNTUN",
-                  "name": "TNTUN15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62916",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLSZZ52",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ53"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "TRIZM8",
-               "port": {
-                  "_reference": "TRIZM",
-                  "name": "TRIZM9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62960",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP32",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "GBGLW38",
-               "port": {
-                  "_reference": "GBGLW",
-                  "name": "GBGLW39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62986",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP34",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP35"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NLRTM62",
-               "port": {
-                  "_reference": "NLRTM",
-                  "name": "NLRTM63"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "62994",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PLWRP36",
-               "port": {
-                  "_reference": "PLWRP",
-                  "name": "PLWRP37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "PLSZZ54",
-               "port": {
-                  "_reference": "PLSZZ",
-                  "name": "PLSZZ55"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63063",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "PTLIS48",
-               "port": {
-                  "_reference": "PTLIS",
-                  "name": "PTLIS49"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITGIT26",
-               "port": {
-                  "_reference": "ITGIT",
-                  "name": "ITGIT27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63125",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ROCND12",
-               "port": {
-                  "_reference": "ROCND",
-                  "name": "ROCND13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "CHBSL18",
-               "port": {
-                  "_reference": "CHBSL",
-                  "name": "CHBSL19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63150",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ROCND14",
-               "port": {
-                  "_reference": "ROCND",
-                  "name": "ROCND15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ESLPA26",
-               "port": {
-                  "_reference": "ESLPA",
-                  "name": "ESLPA27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63153",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "ROCND16",
-               "port": {
-                  "_reference": "ROCND",
-                  "name": "ROCND17"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FIHEL58",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL59"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63228",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED78",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED79"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEHAM22",
-               "port": {
-                  "_reference": "DEHAM",
-                  "name": "DEHAM23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63234",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "RULED80",
-               "port": {
-                  "_reference": "RULED",
-                  "name": "RULED81"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DZALG18",
-               "port": {
-                  "_reference": "DZALG",
-                  "name": "DZALG19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63314",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SADMN6",
-               "port": {
-                  "_reference": "SADMN",
-                  "name": "SADMN7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "SAJED12",
-               "port": {
-                  "_reference": "SAJED",
-                  "name": "SAJED13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63321",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SAJED14",
-               "port": {
-                  "_reference": "SAJED",
-                  "name": "SAJED15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "KWKWI12",
-               "port": {
-                  "_reference": "KWKWI",
-                  "name": "KWKWI13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63407",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEGOT66",
-               "port": {
-                  "_reference": "SEGOT",
-                  "name": "SEGOT67"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "SEHEL38",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63491",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SEHEL40",
-               "port": {
-                  "_reference": "SEHEL",
-                  "name": "SEHEL41"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "PLGDN14",
-               "port": {
-                  "_reference": "PLGDN",
-                  "name": "PLGDN15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63514",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SESTO12",
-               "port": {
-                  "_reference": "SESTO",
-                  "name": "SESTO13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "CZPRG40",
-               "port": {
-                  "_reference": "CZPRG",
-                  "name": "CZPRG41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63583",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SESTO14",
-               "port": {
-                  "_reference": "SESTO",
-                  "name": "SESTO15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "PLGDY60",
-               "port": {
-                  "_reference": "PLGDY",
-                  "name": "PLGDY61"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63775",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SILJU14",
-               "port": {
-                  "_reference": "SILJU",
-                  "name": "SILJU15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "ITGOA32",
-               "port": {
-                  "_reference": "ITGOA",
-                  "name": "ITGOA33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63804",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SILJU16",
-               "port": {
-                  "_reference": "SILJU",
-                  "name": "SILJU17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "SIKOP28",
-               "port": {
-                  "_reference": "SIKOP",
-                  "name": "SIKOP29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63910",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SYTTS10",
-               "port": {
-                  "_reference": "SYTTS",
-                  "name": "SYTTS11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "DEBER42",
-               "port": {
-                  "_reference": "DEBER",
-                  "name": "DEBER43"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "63952",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "SYTTS12",
-               "port": {
-                  "_reference": "SYTTS",
-                  "name": "SYTTS13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "HUBUD34",
-               "port": {
-                  "_reference": "HUBUD",
-                  "name": "HUBUD35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64000",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK32",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "INDEL44",
-               "port": {
-                  "_reference": "INDEL",
-                  "name": "INDEL45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64018",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK34",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "THLCH30",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64019",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK36",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "THLKG30",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64020",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THBKK38",
-               "port": {
-                  "_reference": "THBKK",
-                  "name": "THBKK39"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "THSGZ10",
-               "port": {
-                  "_reference": "THSGZ",
-                  "name": "THSGZ11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64039",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH32",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH33"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "MMRGN32",
-               "port": {
-                  "_reference": "MMRGN",
-                  "name": "MMRGN33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64049",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH34",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "THLKG32",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64050",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLCH36",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "THSGZ12",
-               "port": {
-                  "_reference": "THSGZ",
-                  "name": "THSGZ13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64079",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THLKG34",
-               "port": {
-                  "_reference": "THLKG",
-                  "name": "THLKG35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "THLCH38",
-               "port": {
-                  "_reference": "THLCH",
-                  "name": "THLCH39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64101",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THSGZ14",
-               "port": {
-                  "_reference": "THSGZ",
-                  "name": "THSGZ15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "MYPGU40",
-               "port": {
-                  "_reference": "MYPGU",
-                  "name": "MYPGU41"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64105",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "THSGZ16",
-               "port": {
-                  "_reference": "THSGZ",
-                  "name": "THSGZ17"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "PKBQM12",
-               "port": {
-                  "_reference": "PKBQM",
-                  "name": "PKBQM13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64238",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRIST24",
-               "port": {
-                  "_reference": "TRIST",
-                  "name": "TRIST25"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FRFOS32",
-               "port": {
-                  "_reference": "FRFOS",
-                  "name": "FRFOS33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64320",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRIZM10",
-               "port": {
-                  "_reference": "TRIZM",
-                  "name": "TRIZM11"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "EGPSD18",
-               "port": {
-                  "_reference": "EGPSD",
-                  "name": "EGPSD19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64417",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRMER12",
-               "port": {
-                  "_reference": "TRMER",
-                  "name": "TRMER13"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "FIHEL60",
-               "port": {
-                  "_reference": "FIHEL",
-                  "name": "FIHEL61"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64458",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TRMER14",
-               "port": {
-                  "_reference": "TRMER",
-                  "name": "TRMER15"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "NOKRS44",
-               "port": {
-                  "_reference": "NOKRS",
-                  "name": "NOKRS45"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64478",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TWKEL0",
-               "port": {
-                  "_reference": "TWKEL",
-                  "name": "TWKEL1"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "TWTXG2",
-               "port": {
-                  "_reference": "TWTXG",
-                  "name": "TWTXG3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64479",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TWKEL2",
-               "port": {
-                  "_reference": "TWKEL",
-                  "name": "TWKEL3"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "TWTYU1",
-               "port": {
-                  "_reference": "TWTYU",
-                  "name": "TWTYU2"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64481",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TWKHH4",
-               "port": {
-                  "_reference": "TWKHH",
-                  "name": "TWKHH5"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "TWTXG4",
-               "port": {
-                  "_reference": "TWTXG",
-                  "name": "TWTXG5"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64482",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "TWKHH6",
-               "port": {
-                  "_reference": "TWKHH",
-                  "name": "TWKHH7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "TWTYU3",
-               "port": {
-                  "_reference": "TWTYU",
-                  "name": "TWTYU4"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64509",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USATL14",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USBNA16",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64515",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USATL16",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USILM12",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64517",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USATL18",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USJAX16",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64519",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USATL20",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMEM18",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64520",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USATL22",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMIA14",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64521",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USATL24",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMOB10",
-               "port": {
-                  "_reference": "USMOB",
-                  "name": "USMOB11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64533",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBNA18",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USATL26",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64536",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBNA20",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USHSV6",
-               "port": {
-                  "_reference": "USHSV",
-                  "name": "USHSV7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64537",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBNA22",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USILM14",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64539",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBNA24",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USJAX18",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64540",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBNA26",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMEM20",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64551",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USBUF2",
-               "port": {
-                  "_reference": "USBUF",
-                  "name": "USBUF3"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USBAL10",
-               "port": {
-                  "_reference": "USBAL",
-                  "name": "USBAL11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64562",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI28",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USATL28",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64564",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI30",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCMH18",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64565",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI32",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCVG12",
-               "port": {
-                  "_reference": "USCVG",
-                  "name": "USCVG13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64566",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI34",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USDET22",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64569",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI36",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USKCK14",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64571",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI38",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI39"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMSP14",
-               "port": {
-                  "_reference": "USMSP",
-                  "name": "USMSP15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64572",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI40",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI41"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USNYC18",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64573",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI42",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI43"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USOMA14",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64574",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI44",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI45"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USPDX6",
-               "port": {
-                  "_reference": "USPDX",
-                  "name": "USPDX7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64575",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI46",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI47"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSDF12",
-               "port": {
-                  "_reference": "USSDF",
-                  "name": "USSDF13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64577",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHI48",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI49"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSTL10",
-               "port": {
-                  "_reference": "USSTL",
-                  "name": "USSTL11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64579",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS12",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USBNA28",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA29"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64580",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS14",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCLT12",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64582",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS16",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USILM16",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64584",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS18",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USJAX20",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64585",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS20",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMEM22",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64586",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS22",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMIA16",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64587",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS24",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMOB12",
-               "port": {
-                  "_reference": "USMOB",
-                  "name": "USMOB13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64588",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCHS26",
-               "port": {
-                  "_reference": "USCHS",
-                  "name": "USCHS27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSAV8",
-               "port": {
-                  "_reference": "USSAV",
-                  "name": "USSAV9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64591",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE16",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCMH20",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64592",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE18",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCVG14",
-               "port": {
-                  "_reference": "USCVG",
-                  "name": "USCVG15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64593",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE20",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USDET24",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64595",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE22",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USKCK16",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64596",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE24",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMSP16",
-               "port": {
-                  "_reference": "USMSP",
-                  "name": "USMSP17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64597",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE26",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USOMA16",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64598",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE28",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSDF14",
-               "port": {
-                  "_reference": "USSDF",
-                  "name": "USSDF15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64599",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLE30",
-               "port": {
-                  "_reference": "USCLE",
-                  "name": "USCLE31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSTL12",
-               "port": {
-                  "_reference": "USSTL",
-                  "name": "USSTL13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64604",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLT14",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USILM18",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64606",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLT16",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USJAX22",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64607",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLT18",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMEM24",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64608",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCLT20",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMIA18",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64614",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH22",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCVG16",
-               "port": {
-                  "_reference": "USCVG",
-                  "name": "USCVG17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64617",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH24",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USKCK18",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64618",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH26",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMSP18",
-               "port": {
-                  "_reference": "USMSP",
-                  "name": "USMSP19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64619",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH28",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USOMA18",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64620",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH30",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSDF16",
-               "port": {
-                  "_reference": "USSDF",
-                  "name": "USSDF17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64621",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USCMH32",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSTL14",
-               "port": {
-                  "_reference": "USSTL",
-                  "name": "USSTL15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64634",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDAL8",
-               "port": {
-                  "_reference": "USDAL",
-                  "name": "USDAL9"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USELP6",
-               "port": {
-                  "_reference": "USELP",
-                  "name": "USELP7"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64635",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDAL10",
-               "port": {
-                  "_reference": "USDAL",
-                  "name": "USDAL11"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USHOU30",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64637",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDAL12",
-               "port": {
-                  "_reference": "USDAL",
-                  "name": "USDAL13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMSY12",
-               "port": {
-                  "_reference": "USMSY",
-                  "name": "USMSY13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64638",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDAL14",
-               "port": {
-                  "_reference": "USDAL",
-                  "name": "USDAL15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSAT8",
-               "port": {
-                  "_reference": "USSAT",
-                  "name": "USSAT9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64645",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDET26",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCVG18",
-               "port": {
-                  "_reference": "USCVG",
-                  "name": "USCVG19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64647",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDET28",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USKCK20",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64649",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDET30",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USOMA20",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64650",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDET32",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSDF18",
-               "port": {
-                  "_reference": "USSDF",
-                  "name": "USSDF19"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64651",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USDET34",
-               "port": {
-                  "_reference": "USDET",
-                  "name": "USDET35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSTL16",
-               "port": {
-                  "_reference": "USSTL",
-                  "name": "USSTL17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64654",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USELP8",
-               "port": {
-                  "_reference": "USELP",
-                  "name": "USELP9"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USHOU32",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64657",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USELP10",
-               "port": {
-                  "_reference": "USELP",
-                  "name": "USELP11"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSAT10",
-               "port": {
-                  "_reference": "USSAT",
-                  "name": "USSAT11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64669",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU34",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USATL30",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64675",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU36",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMSY14",
-               "port": {
-                  "_reference": "USMSY",
-                  "name": "USMSY15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64676",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU38",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU39"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USNYC20",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64677",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU40",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU41"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USPDX8",
-               "port": {
-                  "_reference": "USPDX",
-                  "name": "USPDX9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64678",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU42",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU43"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSAT12",
-               "port": {
-                  "_reference": "USSAT",
-                  "name": "USSAT13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64679",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHOU44",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU45"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSEA14",
-               "port": {
-                  "_reference": "USSEA",
-                  "name": "USSEA15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64681",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHSV8",
-               "port": {
-                  "_reference": "USHSV",
-                  "name": "USHSV9"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USBNA30",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64684",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHSV10",
-               "port": {
-                  "_reference": "USHSV",
-                  "name": "USHSV11"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USILM20",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64686",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHSV12",
-               "port": {
-                  "_reference": "USHSV",
-                  "name": "USHSV13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USJAX24",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX25"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64687",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHSV14",
-               "port": {
-                  "_reference": "USHSV",
-                  "name": "USHSV15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMEM26",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64688",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHSV16",
-               "port": {
-                  "_reference": "USHSV",
-                  "name": "USHSV17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMIA20",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64689",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHSV18",
-               "port": {
-                  "_reference": "USHSV",
-                  "name": "USHSV19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMOB14",
-               "port": {
-                  "_reference": "USMOB",
-                  "name": "USMOB15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64690",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USHSV20",
-               "port": {
-                  "_reference": "USHSV",
-                  "name": "USHSV21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSAV10",
-               "port": {
-                  "_reference": "USSAV",
-                  "name": "USSAV11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64705",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND16",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCMH34",
-               "port": {
-                  "_reference": "USCMH",
-                  "name": "USCMH35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64706",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND18",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCVG20",
-               "port": {
-                  "_reference": "USCVG",
-                  "name": "USCVG21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64708",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND20",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USKCK22",
-               "port": {
-                  "_reference": "USKCK",
-                  "name": "USKCK23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64709",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND22",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMSP20",
-               "port": {
-                  "_reference": "USMSP",
-                  "name": "USMSP21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64710",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND24",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USOMA22",
-               "port": {
-                  "_reference": "USOMA",
-                  "name": "USOMA23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64711",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USIND26",
-               "port": {
-                  "_reference": "USIND",
-                  "name": "USIND27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSDF20",
-               "port": {
-                  "_reference": "USSDF",
-                  "name": "USSDF21"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64750",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB18",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USATL32",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64751",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB20",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB21"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCHI50",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI51"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64752",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB22",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USHOU46",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64753",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB24",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USLAX2",
-               "port": {
-                  "_reference": "USLAX",
-                  "name": "USLAX3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64754",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB26",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USNYC22",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64755",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB28",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USPDX10",
-               "port": {
-                  "_reference": "USPDX",
-                  "name": "USPDX11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64756",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLGB30",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSEA16",
-               "port": {
-                  "_reference": "USSEA",
-                  "name": "USSEA17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64760",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLRD6",
-               "port": {
-                  "_reference": "USLRD",
-                  "name": "USLRD7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USHOU48",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU49"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64761",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLRD8",
-               "port": {
-                  "_reference": "USLRD",
-                  "name": "USLRD9"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMSY16",
-               "port": {
-                  "_reference": "USMSY",
-                  "name": "USMSY17"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64762",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USLRD10",
-               "port": {
-                  "_reference": "USLRD",
-                  "name": "USLRD11"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSAT14",
-               "port": {
-                  "_reference": "USSAT",
-                  "name": "USSAT15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64767",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMEM28",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCLT22",
-               "port": {
-                  "_reference": "USCLT",
-                  "name": "USCLT23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64769",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMEM30",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USILM22",
-               "port": {
-                  "_reference": "USILM",
-                  "name": "USILM23"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64771",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMEM32",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USJAX26",
-               "port": {
-                  "_reference": "USJAX",
-                  "name": "USJAX27"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64774",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMEM34",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSAV12",
-               "port": {
-                  "_reference": "USSAV",
-                  "name": "USSAV13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64783",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USMIA22",
-               "port": {
-                  "_reference": "USMIA",
-                  "name": "USMIA23"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMEM36",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM37"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64817",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC24",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC25"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USATL34",
-               "port": {
-                  "_reference": "USATL",
-                  "name": "USATL35"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64818",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC26",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC27"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USBAL12",
-               "port": {
-                  "_reference": "USBAL",
-                  "name": "USBAL13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64819",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC28",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC29"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USBOS10",
-               "port": {
-                  "_reference": "USBOS",
-                  "name": "USBOS11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64821",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC30",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC31"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCHI52",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI53"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64823",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC32",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC33"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USHOU50",
-               "port": {
-                  "_reference": "USHOU",
-                  "name": "USHOU51"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64827",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC34",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC35"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USPHL8",
-               "port": {
-                  "_reference": "USPHL",
-                  "name": "USPHL9"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64828",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USNYC36",
-               "port": {
-                  "_reference": "USNYC",
-                  "name": "USNYC37"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USPIT10",
-               "port": {
-                  "_reference": "USPIT",
-                  "name": "USPIT11"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64830",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USOAK4",
-               "port": {
-                  "_reference": "USOAK",
-                  "name": "USOAK5"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USDEN2",
-               "port": {
-                  "_reference": "USDEN",
-                  "name": "USDEN3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64831",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USOAK6",
-               "port": {
-                  "_reference": "USOAK",
-                  "name": "USOAK7"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USSLC2",
-               "port": {
-                  "_reference": "USSLC",
-                  "name": "USSLC3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64843",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USORF2",
-               "port": {
-                  "_reference": "USORF",
-                  "name": "USORF3"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USBAL14",
-               "port": {
-                  "_reference": "USBAL",
-                  "name": "USBAL15"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64849",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USORF4",
-               "port": {
-                  "_reference": "USORF",
-                  "name": "USORF5"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USPIT12",
-               "port": {
-                  "_reference": "USPIT",
-                  "name": "USPIT13"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64854",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USPDX12",
-               "port": {
-                  "_reference": "USPDX",
-                  "name": "USPDX13"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USCHI54",
-               "port": {
-                  "_reference": "USCHI",
-                  "name": "USCHI55"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64866",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USPHX2",
-               "port": {
-                  "_reference": "USPHX",
-                  "name": "USPHX3"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USLGB32",
-               "port": {
-                  "_reference": "USLGB",
-                  "name": "USLGB33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64881",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USSAV14",
-               "port": {
-                  "_reference": "USSAV",
-                  "name": "USSAV15"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USBNA32",
-               "port": {
-                  "_reference": "USBNA",
-                  "name": "USBNA33"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64888",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USSAV16",
-               "port": {
-                  "_reference": "USSAV",
-                  "name": "USSAV17"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USMEM38",
-               "port": {
-                  "_reference": "USMEM",
-                  "name": "USMEM39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64911",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "USSEA18",
-               "port": {
-                  "_reference": "USSEA",
-                  "name": "USSEA19"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "USTIW2",
-               "port": {
-                  "_reference": "USTIW",
-                  "name": "USTIW3"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64949",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH40",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH41"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "SGSIN38",
-               "port": {
-                  "_reference": "SGSIN",
-                  "name": "SGSIN39"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64954",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNHPH42",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH43"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "VNSGN46",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN47"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64972",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN48",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN49"
-               }
-            },
-            {
-               "date": "2010-12-07",
-               "name": "MYPEN30",
-               "port": {
-                  "_reference": "MYPEN",
-                  "name": "MYPEN31"
-               }
-            }
-         ],
-         "type": "legs"
-      },
-      {
-         "capacity": 200,
-         "name": "64984",
-         "stops": [
-            {
-               "date": "2010-12-02",
-               "name": "VNSGN50",
-               "port": {
-                  "_reference": "VNSGN",
-                  "name": "VNSGN51"
-               }
-            },
-            {
-               "date": "2010-12-05",
-               "name": "VNHPH44",
-               "port": {
-                  "_reference": "VNHPH",
-                  "name": "VNHPH45"
-               }
-            }
-         ],
-         "type": "legs"
-      }
-   ],
-   "label": "name"
-}
diff --git a/dojox/geo/openlayers/tests/ecr/test_ecr.html b/dojox/geo/openlayers/tests/ecr/test_ecr.html
deleted file mode 100644
index 548d04c..0000000
--- a/dojox/geo/openlayers/tests/ecr/test_ecr.html
+++ /dev/null
@@ -1,88 +0,0 @@
-<html>
-<head>
-<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/dijit.css">
-<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css">
-<title>Dojo Ecr</title>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-
-<script type="text/javascript" src="http://openlayers.org/api/2.10/OpenLayers.js"></script>
-
-<script type="text/javascript">
-	var djConfig = {
-		parseOnLoad : true
-	};
-</script>
-<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
-
-<script type="text/javascript">
-	var _ecr = null;
-
-	require(["dojo/ready", "dojox/geo/openlayers/tests/ecr/Ecr", "dojo/parser"], function(ready, Ecr){
-
-		ready(function(){
-			_ecr = new Ecr();
-		});
-	})
-</script>
-
-<style type="text/css">
-.menuItem {
-	border-color: grey;
-	border-style: solid;
-	padding: 1;
-	vertcal-align: middle;
-	border-width: 1;
-}
-
-.menuBar {
-	border-color: #deadbeef;
-	border-style: solid;
-	padding: 1;
-	vertcal-align: middle;
-	border-width: 1;
-	background-color: #e0e0e0;
-}
-</style>
-</head>
-<body class="tundra">
-
-	<table class="menuBar">
-
-		<tr valign="top" align="left">
-
-			<td class="menuItem">
-
-				<button onClick="_ecr.setDataSet('dataChooser')">Data Set:</button> <select id="dataChooser"
-				onChange="_ecr.setDataSet('dataChooser')">
-					<option value="data/ecr.json">Two Points and a Line</option>
-					<option value="data/ecr2.json">Some Points</option>
-					<option value="data/ecr3.json">More Points and Lines</option>
-					<option value="data/mapDataFixed.json">Lot of Points and Lines</option>
-			</select>
-			</td>
-
-			<td class="menuItem">
-
-				<button id="clearEcr" onClick="_ecr.clearEcr('clearEcr')">Clear</button>
-			</td>
-
-			<td class="menuItem">
-				<button id="clearEcr" onClick="_ecr.portChange('portChooser')">Go To:</button> <select
-				id="portChooser" onChange="_ecr.portChange('portChooser')" />
-			</td>
-
-			<td class="menuItem">Show<input type="checkbox" id="ports" checked
-				onChange="_ecr.toggleLayerVisibility('ports')"> Ports </input>
-			</td>
-
-			<td class="menuItem">Show<input type="checkbox" id="legs" checked
-				onChange="_ecr.toggleLayerVisibility('legs')">Legs </input>
-			</td>
-
-		</tr>
-	</table>
-
-	<div id="map" style="background-color: #b5d0d0;"></div>
-
-</body>
-</html>
diff --git a/dojox/geo/openlayers/tests/nonWidget/test_nonWidget.html b/dojox/geo/openlayers/tests/nonWidget/test_nonWidget.html
index c52e45a..114870d 100644
--- a/dojox/geo/openlayers/tests/nonWidget/test_nonWidget.html
+++ b/dojox/geo/openlayers/tests/nonWidget/test_nonWidget.html
@@ -1,3 +1,4 @@
+<!DOCTYPE html>
 <html>
 <head profile="http://www.w3.org/2002/12/namespace">
 <link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/dijit.css">
@@ -9,7 +10,7 @@
 <script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
 
 <!-- hosted version -->
-<script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
+<script type="text/javascript" src="http://openlayers.org/api/2/OpenLayers.js"></script>
 
 <script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
 
@@ -36,16 +37,16 @@
 </script>
 
 <style type="text/css">
-.olLayerGoogleCopyright {
-	visibility: hidden;
-}
+	.olLayerGoogleCopyright {
+		visibility: hidden;
+	}
+	body,html {
+		height:100%;
+	}
 </style>
 
 </head>
 <body class="tundra">
-</head>
-
-<div id="map" style="background-color: #b5d0d0; width: 100%; height: 100%;"></div>
-
+	<div id="map" style="background-color: #b5d0d0; height:100%;"></div>
 </body>
 </html>
diff --git a/dojox/geo/openlayers/tests/sun/Cities.js b/dojox/geo/openlayers/tests/sun/Cities.js
deleted file mode 100644
index 5dd82d5..0000000
--- a/dojox/geo/openlayers/tests/sun/Cities.js
+++ /dev/null
@@ -1,310 +0,0 @@
-define(["dojo/_base/kernel",
-				"dojo/_base/declare",
-				"dojo/_base/lang",
-				"dojo/_base/array",
-				"dojo/_base/xhr",
-				"dojox/geo/openlayers/GfxLayer",
-				"dojox/geo/openlayers/Point",
-				"dojox/geo/openlayers/GeometryFeature",
-				"dojox/gfx",
-				"dojox/gfx/move",
-				"dojox/gfx/fx",
-				"dojo/fx"], function(dojo, declare, lang, arr, xhr, GfxLayer, Point, GeometryFeature){
-
-	dojox.gfx.Text.prototype.getBoundingBox = function(){
-		if (dojo.isIE)
-			return this.getShape();
-		return this.rawNode.getBBox();
-	};
-
-	return declare("dojox.geo.openlayers.tests.sun.Cities", null, {
-
-		constructor : function(sunDemo){
-			this.sunDemo = sunDemo;
-			this.pop = dojo.isIE ? 10000000 : 1000000;
-			this.minPop = Math.pow(2, 30);
-			this.maxPop = 0;
-			this.readCSV("c.csv", lang.hitch(this, this.loaded));
-			this._circles = false;
-			this._gradients = false;
-			var layer = new GfxLayer("cities");
-			var map = this.sunDemo.map;
-			map.map.addLayer(layer);
-			this.layer = layer;
-		},
-
-		useGradients : function(u){
-			if(u== undefined)
-				return this._gradients; 
-			this._gradients = u;
-			this.updateCities();
-			return u;
-		},
-
-		useCircles : function(u){
-			if(u == undefined)
-				return this._circles;
-			this._circles = u;
-			this.updateCities(true);
-			return u;
-		},
-
-		loaded : function(res){
-			var layer = this.layer;
-			arr.forEach(res, function(o){
-				var p = {
-					x : parseFloat(o.longitude),
-					y : parseFloat(o.latitude)
-				};
-				var pg = new Point(p);
-				var f = new GeometryFeature(pg);
-				// f.createShape = this.createShape;
-				this.setCreateShape(f, o);
-				var r = o.population;
-				var dp = this.maxPop - this.minPop;
-				if (dp != 0)
-					r = (r - this.minPop + 100) * 20 / dp;
-				else
-					r = 20;
-				if (this._circles)
-					f.setShapeProperties({
-						r : r
-					});
-				else
-					f.setShapeProperties({
-						x : -r / 2,
-						y : -r / 2,
-						width : r,
-						height : r,
-						r : 0
-					});
-				layer.addFeature(f);
-				f.getShape();
-				this.connectTooltip(pg, o.asciiname, r);
-			}, this);
-			layer.redraw();
-			this.updateCities();
-		},
-
-		updateCities : function(redoGeometry){
-			if (!this.layer)
-				return; // ?? throw new Error();
-			var features = this.layer.getFeatures();
-			var gf = this.sunDemo.getTZone();
-			var tz = gf._geometry.coordinates;
-
-			var pointIn = function(p){
-				var sides = tz.length;
-				var j = sides - 1;
-				var oddNodes = false;
-				var x = p.x;
-				var y = p.y;
-				for ( var i = 0; i < sides; i++) {
-					var o = tz[i];
-					var xi = o.x;
-					var yi = o.y;
-
-					o = tz[j];
-					var xj = o.x;
-					var yj = o.y;
-
-					if (yi < y && yj >= y || yj < y && yi >= y) {
-						if (xi + (y - yi) / (yj - yi) * (xj - xi) < x) {
-							oddNodes = !oddNodes;
-						}
-					}
-					j = i;
-					o = tz[j];
-					xj = o.x;
-					yj = o.y;
-				}
-
-				return oddNodes;
-			};
-
-			arr.forEach(features, function(f){
-				var g = f._geometry.coordinates;
-
-				var p = f.getShapeProperties();
-				var r = p.r | p.width;
-				if (redoGeometry) {
-					f.remove();
-					if (this._circles)
-						f.setShapeProperties({
-							r : r
-						});
-					else
-						f.setShapeProperties({
-							x : -r / 2,
-							y : -r / 2,
-							width : r,
-							height : r,
-							r : 0
-						});
-				}
-				if (pointIn(g)) {
-					f.setStroke("black");
-					if (this._gradients)
-						f.setFill({
-							type : "radial",
-							r : r,
-							colors : [{
-								offset : 0,
-								color : [255, 255, 255]
-							}, {
-								offset : 1,
-								color : [0, 0, 0]
-							}]
-						});
-					else
-						f.setFill([0, 0, 0, 0]);
-				} else {
-					f.setStroke([0, 128, 128]);
-					if (this._gradients)
-						f.setFill({
-							type : "radial",
-							r : r,
-							colors : [{
-								offset : 0,
-								color : [255, 255, 255]
-							}, {
-								offset : 1,
-								color : [255, 255, 0]
-							}]
-						});
-					else
-						f.setFill("yellow");
-				}
-			}, this);
-
-			this.layer.redraw();
-		},
-
-		readCSV : function(url, cb){
-			xhr.get({
-				url : url,
-				handleAs : "text",
-				nocache : true,
-				noCache : true,
-				load : lang.hitch(this, function(data){
-
-					var what = ['asciiname', 'longitude', 'latitude', 'population'];
-
-					var res = this.parseCSV(data, what, lang.hitch(this, function(head, line){
-
-						var index = arr.indexOf(head, 'population');
-						var pop = line[index];
-						pop = parseInt(pop);
-						var ok = pop > this.pop;
-						if (ok) {
-							if (pop < this.minPop)
-								this.minPop = pop;
-							if (pop > this.maxPop)
-								this.maxPop = pop;
-						}
-						return ok;
-					}));
-					cb(res);
-				}),
-
-				error : function(e){
-					console.log(e.toString());
-				},
-
-				headers : {
-					content : "text/html; charset=UTF-8"
-				}
-			});
-		},
-
-		parseCSV : function(s, what, condition){
-			var res = [];
-			var nl = "\n";
-			var sep = "\t";
-			var start = 0;
-
-			var eol = s.indexOf(nl, start);
-			var line = s.substring(start, eol);
-
-			var head = line.split(sep);
-			var re = /^\"(.*)\"$/;
-			arr.forEach(head, function(h, index){
-				var r = re.exec(h);
-				if (r && r.length > 1) {
-					head[index] = r[1];
-				}
-			});
-			start = eol + 1;
-
-			var count = 0;
-			while ((eol = s.indexOf(nl, start)) != -1) {
-				line = s.substring(start, eol);
-				var split = line.split(sep);
-				if (condition == undefined || condition(head, split)) {
-					var o = {};
-					arr.forEach(what, function(w, i){
-						index = arr.indexOf(head, w);
-						var splt = split[index];
-						var r = re.exec(splt);
-						if (r && r.length > 1)
-							splt = r[1];
-						o[w] = splt;
-					});
-					res.push(o);
-					count++;
-				}
-				start = eol + 1;
-			}
-			return res;
-		},
-
-		setCreateShape : function(feature, object){
-
-			var createShape = lang.hitch(this, function(/* Surface */surface){
-				var shape;
-				if (this._circles)
-					shape = surface.createCircle();
-				else
-					shape = surface.createRect();
-
-				return shape;
-			});
-
-			feature.createShape = createShape;
-		},
-
-		connectTooltip : function(g, content, size){
-			var map = this.sunDemo.map.map;
-
-			var localXY = function(p){
-				var x = p.x;
-				var y = p.y;
-				var layer = map.olMap.baseLayer;
-				var resolution = map.olMap.getResolution();
-				var extent = layer.getExtent();
-				var rx = (x / resolution + (-extent.left / resolution));
-				var ry = ((extent.top / resolution) - y / resolution);
-				return [rx, ry];
-			};
-
-			g.shape.connect("onmouseover", function(){
-				var p = lang.mixin({}, g.coordinates);
-				p = map.transform(p);
-				var a = localXY(p);
-				var r = {
-					x : a[0],
-					y : a[1],
-					w : size,
-					h : size
-				};
-				var s = g.shape;
-				lang.mixin(s, r);
-				dijit.showTooltip(content, s, ["after"]);
-			});
-
-			g.shape.connect("onmouseout", function(){
-				dijit.hideTooltip(g.shape);
-			});
-		}
-	});
-});
diff --git a/dojox/geo/openlayers/tests/sun/Sun.js b/dojox/geo/openlayers/tests/sun/Sun.js
deleted file mode 100644
index 82aa634..0000000
--- a/dojox/geo/openlayers/tests/sun/Sun.js
+++ /dev/null
@@ -1,226 +0,0 @@
-define(["dojo/_base/kernel", "dojo/_base/declare"], function(dojo, declare){
-	return declare("dojox.geo.openlayers.tests.sun.Sun", null, {
-		_now : false,
-
-		constructor : function(d){
-			if (!d)
-				d = new Date();
-			this._date = d;
-		},
-
-		getDate : function(){
-			var d = this._date;
-			if (d == null) {
-				d = new Date();
-				this._date = d;
-			}
-			return d;
-		},
-
-		setDate : function(d){
-			if (!d)
-				d = new Date();
-			this._date = d;
-		},
-
-		isNow : function(){
-			return this._now;
-		},
-
-		clip : function(p, c){
-			if (p.x < c.x1)
-				p.x = c.x1;
-			if (p.y < c.y2)
-				p.y = c.y2;
-			if (p.x > c.x2)
-				p.x = c.x2;
-			if (p.y > c.y1)
-				p.y = c.y1;
-			return p;
-		},
-
-		twilightZone : function(c){
-			var pts = [];
-
-			clip = function(p, c){
-				if (p.x < c.x1)
-					p.x = c.x1;
-				if (p.y < c.y2)
-					p.y = c.y2;
-				if (p.x > c.x2)
-					p.x = c.x2;
-				if (p.y > c.y1)
-					p.y = c.y1;
-				return p;
-			};
-
-			addPoint = function(p){
-				if (c)
-					p = this.clip(p, c);
-				pts.push(p);
-			};
-
-			sLon = -180;
-			sLat = -90;
-			eLon = 180;
-			eLat = 90;
-			if (c) {
-				if (sLon < c.x1)
-					sLon = c.x1;
-				if (sLat < c.y2)
-					sLat = c.y2;
-				if (eLon > c.x2)
-					eLon = c.x2;
-				if (eLat > c.y1)
-					eLat = c.y1;
-			}
-			var dt = this.getDate();
-			var LT = dt.getUTCHours() + dt.getUTCMinutes() / 60 + dt.getUTCSeconds() / 3600;
-			var tau = 15 * (LT - 12);
-			var o = this.sunDecRa();
-			var dec = o.dec;
-			var incr = 1;
-			var dtr = Math.PI / 180;
-			for ( var i = sLon; i <= eLon; i += incr) {
-				var longitude = i + tau;
-				var tanLat = -Math.cos(longitude * dtr) / Math.tan(dec * dtr);
-				var arctanLat = Math.atan(tanLat) / dtr;
-				addPoint({
-					x : i,
-					y : arctanLat
-				});
-			}
-
-			if (dec < 0) {
-				addPoint({
-					x : 180,
-					y : -85
-				});
-
-				addPoint({
-					x : -180,
-					y : -85
-				});
-
-				addPoint({
-					x : pts[0].x,
-					y : pts[0].y
-				});
-
-			} else {
-				addPoint({
-					x : 180,
-					y : 85
-				});
-
-				addPoint({
-					x : -180,
-					y : 85
-				});
-
-			}
-			return pts;
-		},
-
-		sun : function(){
-			var o = this.sunDecRa();
-			var dec = o.dec;
-			var dt = this.getDate();
-			var LT = dt.getUTCHours() + dt.getUTCMinutes() / 60 + dt.getUTCSeconds() / 3600;
-			var tau = 15 * (LT - 12);
-			var et = 0; // this.et(dt) / 60;
-			var p = {
-				x : -tau + et,
-				y : dec
-			};
-			return p;
-		},
-
-		jd : function(date){
-			var dt;
-			if (date != null)
-				dt = date;
-			else
-				dt = this.getDate();
-			MM = dt.getMonth() + 1;
-			DD = dt.getDate();
-			YY = dt.getFullYear();
-			HR = dt.getUTCHours();
-			MN = dt.getUTCMinutes();
-			SC = 0;
-			with (Math) {
-				HR = HR + (MN / 60) + (SC / 3600);
-				GGG = 1;
-				if (YY <= 1585)
-					GGG = 0;
-				JD = -1 * floor(7 * (floor((MM + 9) / 12) + YY) / 4);
-				S = 1;
-				if ((MM - 9) < 0)
-					S = -1;
-				A = abs(MM - 9);
-				J1 = floor(YY + S * floor(A / 7));
-				J1 = -1 * floor((floor(J1 / 100) + 1) * 3 / 4);
-				JD = JD + floor(275 * MM / 9) + DD + (GGG * J1);
-				JD = JD + 1721027 + 2 * GGG + 367 * YY - 0.5;
-				JD = JD + (HR / 24);
-			}
-			return JD;
-		},
-
-		sunDecRa : function(){
-			var jd = this.jd();
-			var PI2 = 2.0 * Math.PI;
-			var cos_eps = 0.917482;
-			var sin_eps = 0.397778;
-			var M, DL, L, SL, X, Y, Z, R;
-			var T, dec, ra;
-			T = (jd - 2451545.0) / 36525.0; // number of Julian centuries since Jan 1,
-			// 2000, 0 GMT
-			M = PI2 * this.frac(0.993133 + 99.997361 * T);
-			DL = 6893.0 * Math.sin(M) + 72.0 * Math.sin(2.0 * M);
-			L = PI2 * this.frac(0.7859453 + M / PI2 + (6191.2 * T + DL) / 1296000);
-			SL = Math.sin(L);
-			X = Math.cos(L);
-			Y = cos_eps * SL;
-			Z = sin_eps * SL;
-			R = Math.sqrt(1.0 - Z * Z);
-			dec = (360.0 / PI2) * Math.atan(Z / R);
-			ra = (48.0 / PI2) * Math.atan(Y / (X + R));
-			if (ra < 0)
-				ra = ra + 24.0;
-			return {
-				dec : dec,
-				ra : ra
-			};
-		},
-
-		et : function(d){
-			if (!d)
-				d = this.getDate();
-			var year = date.getUTCFullYear();
-			var month = date.getUTCMonth() + 1;
-			var day = date.getUTCDate();
-
-			var N1 = Math.floor((month * 275) / 9);
-			var N2 = Math.floor((month + 9) / 12);
-			var K = 1 + Math.floor((year - 4 * Math.floor(year / 4) + 2) / 3);
-			var j = N1 - N2 * K + day - 30;
-
-			var M = 357 + 0.9856 * j;
-			var C = 1.914 * Math.sin(M) + 0.02 * Math.sin(2 * M);
-			var L = 280 + C + 0.9856 * j;
-			var R = -2.465 * Math.sin(2 * L) + 0.053 * Math.sin(4 * L);
-
-			var ET = (C + R) * 4;
-
-			return ET;
-		},
-
-		frac : function(x){
-			x = x - Math.floor(x);
-			if (x < 0)
-				x = x + 1.0;
-			return x;
-		}
-	});
-});
diff --git a/dojox/geo/openlayers/tests/sun/SunDemo.js b/dojox/geo/openlayers/tests/sun/SunDemo.js
deleted file mode 100644
index 0e3e29d..0000000
--- a/dojox/geo/openlayers/tests/sun/SunDemo.js
+++ /dev/null
@@ -1,298 +0,0 @@
-define(["dojo/_base/kernel",
-				"dojo/_base/declare",
-				"dojo/_base/html",
-				"dojo/_base/lang",
-				"dojo/date",
-				"dojox/geo/openlayers/tests/sun/Sun",
-				"dojox/geo/openlayers/widget/Map",
-				"dojox/timing/_base",
-				"dojox/geo/openlayers/GfxLayer",
-				"dojox/geo/openlayers/GeometryFeature",
-				"dojox/geo/openlayers/LineString",
-				"dojox/geo/openlayers/Point",
-				"dojox/geo/openlayers/JsonImport",
-				"dojox/geo/openlayers/tests/sun/Cities",
-				"dijit/Tooltip"], function(dojo, declare, html, lang, date, Sun, Map, timinig, GfxLayer, GeometryFeature, LineString,
-																		Point, JsonImport, Cities){
-
-	return declare("dojox.geo.openlayers.tests.sun.SunDemo", null, {
-		now : true,
-		map : null,
-		cities : null,
-		layer : null,
-		sun : null,
-
-		constructor : function(div){
-
-			var options = {
-				name : "TheMap",
-				touchHandler : true
-			};
-
-			var map = new Map(options);
-			html.place(map.domNode, div);
-			map.startup();
-			this.map = map;
-
-			map.map.fitTo([-160, 70, 160, -70]);
-
-			var cities = new Cities(this);
-			dojo.connect(this, "updateFeatures", cities, "updateCities");
-			this.cities = cities;
-
-			this.sun = new Sun();
-			var layer = new GfxLayer("sun");
-			this.layer = layer;
-			map.map.addLayer(layer);
-
-			this.updateFeatures();
-
-		},
-
-		showGradients : function(grd){
-			return this.cities.useGradients(grd);
-		},
-
-		showCircles : function(c){
-			return this.cities.useCircles(c);
-		},
-
-		showTooltips : function(tt){
-			var map = this.map.map;
-			var ls = map.getLayer("name", "sun")[0];
-			var lc = map.getLayer("name", "cities")[0];
-			var is = map.layerIndex(ls);
-			var ic = map.layerIndex(lc);
-			var m = Math.min(is, ic);
-			var M = Math.max(is, ic);
-			if (tt) {
-				map.layerIndex(ls, m);
-				map.layerIndex(lc, M);
-			} else {
-				map.layerIndex(ls, M);
-				map.layerIndex(lc, m);
-			}
-		},
-
-		updateFeatures : function(){
-			var l = this.layer;
-			l.removeFeature(l.getFeatures());
-			var f = this.twilightZone({
-				x1 : -180,
-				y1 : 85,
-				x2 : 180,
-				y2 : -85
-			});
-			l.addFeature(f);
-
-			f = this.createStar();
-			l.addFeature(f);
-
-			f = this.createSun();
-			l.addFeature(f);
-
-			l.redraw();
-		},
-
-		getHour : function(d){
-			if (!d)
-				d = this.sun.getDate();
-			return d.getHours() + d.getMinutes() / 60 + d.getSeconds() / 3600;
-		},
-
-		getDay : function(d){
-			if (!d)
-				d = this.sun.getDate();
-			var start = new Date(d.getFullYear(), 0, 1);
-			var oneDay = 1000 * 60 * 60 * 24;
-			var day = Math.floor((d.getTime() - start.getTime()) / oneDay);
-			return day;
-		},
-
-		setDay : function(day){
-			var now = this.sun.getDate();
-			var year = now.getFullYear();
-			var hours = now.getHours();
-			var minutes = now.getMinutes();
-			var seconds = now.getSeconds();
-			var milliSeconds = now.getMilliseconds();
-			var start = new Date(year, 0, 1, hours, minutes, seconds, milliSeconds);
-			start = date.add(start, "day", day);
-			this.setDate(start);
-		},
-
-		setTime : function(t){
-			var d = this.sun.getDate();
-
-			var year = d.getFullYear();
-			var month = d.getMonth();
-			var day = d.getDate();
-			var hours = Math.floor(t);
-			t = 60 * (t - hours);
-			var minutes = Math.floor(t);
-			t = 60 * (t - minutes);
-			var seconds = Math.floor(t);
-			d = new Date(year, month, day, hours, minutes, seconds, 0);
-
-			this.setDate(d);
-		},
-
-		setDate : function(d){
-			this.now = !d;
-			this.sun.setDate(d);
-			this.updateFeatures();
-		},
-
-		advance : function(ms){
-			var d = this.sun.getDate();
-			d = date.add(d, "millisecond", ms);
-			this.setDate(d);
-		},
-
-		getTZone : function(){
-			return this.tZone;
-		},
-
-		twilightZone : function(clip){
-			var tz = this.sun.twilightZone(clip);
-			var g = new LineString(tz);
-			var gf = new GeometryFeature(g);
-			gf.setStroke([248, 236, 56]);
-			gf.setFill([252, 251, 45, 0.3]);
-			this.tZone = gf;
-			return gf;
-		},
-
-		makeStarShape : function(r1, r2, b){
-			var TPI = Math.PI * 2;
-			var di = TPI / b;
-			var s = null;
-			var start = Math.PI;
-			var end = start + TPI;
-			for ( var i = start; i < end; i += di) {
-				var c1 = Math.cos(i);
-				var s1 = Math.sin(i);
-				var i2 = i + di / 2;
-				var c2 = Math.cos(i2);
-				var s2 = Math.sin(i2);
-				if (s == null) {
-					s = "M" + (s1 * r1).toFixed(2) + "," + (c1 * r1).toFixed(2) + " ";
-				} else {
-					s += "L" + (s1 * r1).toFixed(2) + "," + (c1 * r1).toFixed(2) + " ";
-				}
-				s += "L" + (s2 * r2).toFixed(2) + "," + (c2 * r2).toFixed(2) + " ";
-			}
-			s += "z";
-			return s;
-		},
-
-		createStar : function(){
-			var s = this.sun.sun();
-			var geom = new Point(s);
-			var gf = new GeometryFeature(geom);
-
-			gf.createShape = lang.hitch(this, function(/* Surface */s){
-				var r1 = 30;
-				var r2 = 10;
-				var branches = 7;
-				var star = this.makeStarShape(r1, r2, branches);
-				var path = s.createPath();
-				path.setShape({
-					path : star
-				});
-				path.setStroke([0, 100, 0]);
-				path.setFill([0, 100, 0]);
-				//				g.add(path);
-				//				return g;
-				return path;
-			});
-			return gf;
-		},
-
-		makeCrossShape : function(r1, r2, b){
-			var TPI = Math.PI * 2;
-			var di = TPI / b;
-			var s = "";
-			for ( var i = 0; i < TPI; i += di) {
-				var c1 = Math.cos(i);
-				var s1 = Math.sin(i);
-				var i2 = i + Math.PI;
-				var c2 = Math.cos(i2);
-				var s2 = Math.sin(i2);
-				s += "M" + (s1 * r1).toFixed(2) + "," + (c1 * r1).toFixed(2) + " ";
-				s += "L" + (s2 * r1).toFixed(2) + "," + (c2 * r1).toFixed(2) + " ";
-			}
-
-			return s;
-		},
-
-		createSun : function(){
-			var s = this.sun.sun();
-			var g = new Point({
-				x : s.x,
-				y : s.y
-			});
-			var gf = new GeometryFeature(g);
-			var sunRadius = 20;
-			gf.setShapeProperties({
-				r : sunRadius
-			});
-			gf.setStroke("");
-			gf.setFill({
-				type : "radial",
-				r : sunRadius,
-				colors : [{
-					offset : 0,
-					color : [248, 236, 100]
-				}, {
-					offset : 1,
-					color : [255, 127, 0]
-				}]
-			});
-			/*
-						gf.setFill({
-							type : "radial",
-							r : 15,
-							colors : [{
-								offset : 0,
-								color : [248, 236, 100]
-							}, {
-								offset : 1,
-								color : [255, 255, 255, 0.4]
-							}]
-						});
-			*/
-			return gf;
-		},
-
-		_timer : null,
-
-		startTimer : function(checked, time){
-			var t = this._timer;
-			if (!this._timer) {
-				if (!time)
-					time = 1000;
-
-				t = this._timer = new dojox.timing.Timer(time);
-				t.onTick = lang.hitch(this, function(){
-					if (this.now)
-						this.setDate();
-					else
-						this.advance(time);
-				});
-				t.onStart = function(){
-
-				};
-				t.onStop = function(){
-
-				};
-			}
-			if (checked)
-				t.start();
-			else
-				t.stop();
-		}
-
-	});
-
-});
diff --git a/dojox/geo/openlayers/tests/sun/c.csv b/dojox/geo/openlayers/tests/sun/c.csv
deleted file mode 100644
index 7a9a45d..0000000
--- a/dojox/geo/openlayers/tests/sun/c.csv
+++ /dev/null
@@ -1,340 +0,0 @@
-asciiname	latitude	longitude	population
-"Dubai"	25.25222	55.28	1137347
-"Kabul"	34.52813	69.17233	3043532
-"Yerevan"	40.18111	44.51361	1093485
-"Luanda"	-8.83833	13.23444	2776168
-"Buenos Aires"	-34.61315	-58.37723	13076300
-"Rosario"	-32.95111	-60.66639	1173533
-"Cordoba"	-31.4	-64.18333	1428214
-"Vienna"	48.20849	16.37208	1691468
-"Perth"	-31.93333	115.83333	1446704
-"Adelaide"	-34.93333	138.6	1074159
-"Sydney"	-33.86785	151.20732	4394576
-"Melbourne"	-37.814	144.96332	3730206
-"Baku"	40.37767	49.89201	1116513
-"Dhaka"	23.7104	90.40744	10356500
-"Chittagong"	22.33306	91.83639	3920222
-"Khulna"	22.81348	89.56723	1342339
-"Brussels"	50.85045	4.34878	1019022
-"Ouagadougou"	12.36423	-1.53834	1086505
-"Sofia"	42.69751	23.32415	1152556
-"Santa Cruz de la Sierra"	-17.8	-63.16667	1364389
-"Recife"	-8.05389	-34.88111	1478098
-"Fortaleza"	-3.71722	-38.54306	2400000
-"Belem"	-1.45583	-48.50444	1407737
-"Sao Paulo"	-23.5475	-46.63611	10021295
-"Salvador"	-12.97111	-38.51083	2711840
-"Rio de Janeiro"	-22.90278	-43.2075	6023699
-"Porto Alegre"	-30.03306	-51.23	1372741
-"Nova Iguacu"	-22.75917	-43.45111	1002118
-"Guarulhos"	-23.46278	-46.53333	1169577
-"Goiania"	-16.67861	-49.25389	1171195
-"Curitiba"	-25.42778	-49.27306	1718421
-"Campinas"	-22.90556	-47.06083	1031554
-"Brasilia"	-15.77972	-47.92972	2207718
-"Belo Horizonte"	-19.92083	-43.93778	2373224
-"Manaus"	-3.10194	-60.025	1598210
-"Minsk"	53.9	27.56667	1742124
-"Calgary"	51.05011	-114.08529	1019942
-"Montreal"	45.50884	-73.58781	3268513
-"Toronto"	43.70011	-79.4163	4612191
-"Vancouver"	49.24966	-123.11934	1837969
-"Lubumbashi"	-11.66667	27.46667	1373770
-"Kinshasa"	-4.32459	15.32146	7785965
-"Brazzaville"	-4.2669	15.28327	1284609
-"Abidjan"	5.34111	-4.02806	3677115
-"Santiago de Chile"	-33.45722	-70.65685	5278044
-"Yaounde"	3.86667	11.51667	1299369
-"Douala"	4.0469	9.7084	1338082
-"Urumqi"	43.8	87.58333	1508225
-"Zhumadian"	32.97944	114.02944	8263100
-"Zhengzhou"	34.75778	113.64861	2014125
-"Yunfu"	22.93056	112.0373	2612800
-"Tongshan"	34.18045	117.15707	1199193
-"Xinyang"	32.12278	114.06556	1590668
-"Xianyang"	34.33778	108.70261	1034081
-"Xi'an"	34.25833	108.92861	3225812
-"Wuxi"	31.56887	120.28857	1108647
-"Wuhan"	30.58333	114.26667	4184206
-"Tianjin"	39.14222	117.17667	3766207
-"Tangshan"	39.63333	118.18333	1596949
-"Taiyuan"	37.86944	112.56028	2722475
-"Tai'an"	36.18528	117.12	5499000
-"Shiyan"	32.6475	110.77806	3460000
-"Shijiazhuang"	38.04139	114.47861	1992474
-"Shenzhen"	22.54554	114.0683	3000000
-"Shantou"	23.36814	116.71479	1333973
-"Shanghai"	31.22222	121.45806	14608512
-"Jieyang"	23.52886	116.36416	1001985
-"Qingdao"	36.09861	120.37194	1642245
-"Puyang"	29.46028	119.88611	3590000
-"Nanjing"	32.06167	118.77778	3087010
-"Nanchong"	30.79508	106.08474	7150000
-"Nanchang"	28.68333	115.88333	1871351
-"Luoyang"	34.68361	112.45361	1390581
-"Liuyang"	28.15	113.63333	1380000
-"Lanzhou"	36.05639	103.79222	3200000
-"Kunming"	25.03889	102.71833	1023674
-"Kaifeng"	34.79111	114.34833	4800000
-"Jinan"	36.66833	116.99722	2069266
-"Huainan"	32.62639	116.99694	1027655
-"Hefei"	31.86389	117.28083	1388904
-"Hangzhou"	30.25528	120.16889	1878129
-"Handan"	36.60056	114.46778	1358318
-"Guiyang"	26.58333	106.71667	1171633
-"Guangzhou"	23.11667	113.25	3152825
-"Fuzhou"	26.06139	119.30611	1179720
-"Dayan"	26.86879	100.22072	1137600
-"Dalian"	38.91222	121.60222	2035307
-"Chongqing"	29.56278	106.55278	3967028
-"Chengdu"	30.66667	104.06667	3950437
-"Changsha"	28.2	112.96667	2073938
-"Beijing"	39.9075	116.39723	7480601
-"Suzhou"	31.31139	120.61806	1343091
-"Zhongshan"	21.32256	110.58291	2493400
-"Yueyang"	29.33333	113.09194	5000000
-"Shenyang"	41.79222	123.43278	3512192
-"Jilin"	43.85083	126.56028	1881977
-"Harbin"	45.75	126.65	3229883
-"Fushun"	41.85583	123.92333	1400646
-"Datong"	40.09361	113.29139	1052678
-"Changchun"	43.88	125.32278	2537421
-"Baotou"	40.65222	109.82222	1301768
-"Anshan"	41.12361	122.99	1199275
-"Changshu City"	31.64615	120.74221	1047700
-"Medellin"	6.29139	-75.53611	1999979
-"Cali"	3.43722	-76.5225	2392877
-"Bogota"	4.60971	-74.08175	7102602
-"Barranquilla"	10.96389	-74.79639	1380425
-"Havana"	23.13302	-82.38304	2163824
-"Praha"	50.08804	14.42076	1165581
-"Muenchen"	48.13743	11.57549	1260391
-"Hamburg"	53.55	10	1739117
-"Berlin"	52.52437	13.41053	3426354
-"Copenhagen"	55.67594	12.56553	1153615
-"Santo Domingo"	18.50012	-69.98857	2201941
-"Santiago de los Caballeros"	19.45	-70.7	1200000
-"Algiers"	36.7525	3.04197	1977663
-"Quito"	-0.22985	-78.52495	1399814
-"Guayaquil"	-2.16667	-79.9	1952029
-"Cairo"	30.06263	31.24967	7734614
-"Al Jizah"	30.00861	31.21222	2443203
-"Alexandria"	31.19806	29.91917	3811516
-"Madrid"	40.4165	-3.70256	3255944
-"Barcelona"	41.38879	2.15899	1621537
-"Addis Ababa"	9.02497	38.74689	2757729
-"Paris"	48.85341	2.3488	2138551
-"London"	51.50853	-0.12574	7556900
-"Tbilisi"	41.69411	44.83368	1049498
-"Kumasi"	6.68333	-1.61667	1468609
-"Accra"	5.55602	-0.1969	1963264
-"Conakry"	9.53795	-13.67729	1767200
-"Camayenne"	9.535	-13.68778	1871242
-"Kowloon"	22.31667	114.18333	2019533
-"Hong Kong"	22.28552	114.15769	7012738
-"Port-au-Prince"	18.53917	-72.335	1234742
-"Budapest"	47.49801	19.03991	1696128
-"Medan"	3.58333	98.66667	1750971
-"Makassar"	-5.14	119.4221	1321717
-"Tangerang"	-6.17806	106.63	1372124
-"Surabaya"	-7.24917	112.75083	2374658
-"Semarang"	-6.9932	110.4203	1288084
-"Palembang"	-2.91673	104.7458	1441500
-"Jakarta"	-6.21462	106.84513	8540121
-"Depok"	-6.4	106.81861	1198129
-"Bekasi"	-6.2349	106.9896	1520119
-"Bandung"	-6.90389	107.61861	1699719
-"Dublin"	53.34399	-6.26719	1024027
-"Vishakhapatnam"	17.7	83.3	1063178
-"Benares"	25.33333	83	1164404
-"Vadodara"	22.3	73.2	1409476
-"Tuticorin"	8.78333	78.13333	1572273
-"Thane"	19.2	72.96667	1261517
-"Teni"	10	77.48333	1034724
-"Surat"	21.16667	72.83333	2894504
-"Rajkot"	22.3	70.78333	1177362
-"Raigarh Fort"	18.25	73.43333	2207929
-"Pune"	18.51957	73.85535	2935744
-"Pimpri"	18.61667	73.8	1284606
-"Patna"	25.6	85.11667	1599920
-"Nasik"	19.98333	73.8	1289497
-"Nagpur"	21.15	79.1	2228018
-"Meerut"	28.98333	77.7	1223184
-"Chennai"	13.08784	80.27847	4328063
-"Ludhiana"	30.9	75.85	1545368
-"Lucknow"	26.85	80.91667	2472011
-"Kanpur"	26.46667	80.35	2823249
-"Kalyan"	19.25	73.15	1262255
-"Jaipur"	26.91667	75.81667	2711758
-"Jabalpur"	23.16697	79.95006	1030168
-"Indore"	22.71792	75.8333	1837041
-"Hyderabad"	17.37528	78.47444	3597816
-"Haora"	22.58917	88.31028	1027672
-"Gorakhpur"	29.45	75.68333	1324570
-"Ghaziabad"	28.66667	77.43333	1199191
-"Faridabad"	28.43333	77.31667	1220229
-"Dombivli"	19.21667	73.08333	1193000
-"Delhi"	28.66667	77.21667	10927986
-"Calcutta"	22.56972	88.36972	4631392
-"Mumbai"	19.01441	72.84794	12691836
-"Bhopal"	23.26667	77.4	1599914
-"Bengalore"	12.97623	77.60329	5104047
-"Aurangabad"	19.88333	75.33333	1016441
-"Amritsar"	31.63306	74.86556	1092450
-"Allahabad"	25.45	81.85	1073438
-"Ahmadabad"	23.03333	72.61667	3719710
-"Agra"	27.18333	78.01667	1430055
-"Baghdad"	33.34058	44.40088	5672513
-"Al Mawsil al Jadidah"	36.33464	43.09777	2065597
-"Mosul"	36.335	43.11889	1739800
-"Al Basrah"	30.53488	47.78885	2600000
-"Al Basrat al Qadimah"	30.49721	47.81491	2015483
-"Tehran"	35.69439	51.42151	7153309
-"Tabriz"	38.08	46.2919	1424641
-"Shiraz"	29.6036	52.5388	1249942
-"Mashhad"	36.297	59.6062	2307177
-"Karaj"	35.82876	50.9982	1448075
-"Esfahan"	32.65722	51.67761	1547164
-"Roma"	41.89474	12.4839	2563241
-"Milano"	45.46427	9.18951	1306661
-"Amman"	31.95522	35.94503	1275857
-"Yono"	35.88333	139.63333	1077730
-"Yokohama-shi"	35.44778	139.6425	3574443
-"Tokyo"	35.61488	139.5813	8336599
-"Osaka-shi"	34.69374	135.50218	2592413
-"Nagoya-shi"	35.18147	136.90641	2191279
-"Kyoto"	35.02107	135.75385	1459640
-"Kobe-shi"	34.6913	135.183	1528478
-"Kawasaki"	35.52056	139.71722	1306785
-"Hiroshima-shi"	34.39627	132.45937	1143841
-"Fukuoka-shi"	33.60639	130.41806	1392289
-"Sendai-shi"	38.26889	140.87194	1037562
-"Sapporo-shi"	43.06417	141.34694	1883027
-"Saitama"	35.90807	139.65657	1193350
-"Nairobi"	-1.28333	36.81667	2750547
-"Phnom Penh"	11.56245	104.91601	1573544
-"Pyongyang"	39.03385	125.75432	3222000
-"Taejon"	36.32139	127.41972	1475221
-"Taegu"	35.87028	128.59111	2566540
-"Suwon"	37.29111	127.00889	1242724
-"Seoul"	37.56826	126.97783	10349312
-"Pusan"	35.10278	129.04028	3678555
-"Kwangju"	35.15472	126.91556	1416938
-"Goyang"	37.65639	126.835	1073069
-"Inch'on"	37.45361	126.73167	2628000
-"Songnam"	37.43861	127.13778	1031935
-"Almaty"	43.25	76.95	2000900
-"Ra's Bayrut"	33.9	35.48333	1251739
-"Beirut"	33.88894	35.49442	1916100
-"Tripoli"	32.87519	13.18746	1150989
-"Rabat"	34.01325	-6.83255	1655753
-"Casablanca"	33.59278	-7.61916	3144909
-"Antananarivo"	-18.91433	47.53098	1391433
-"Bamako"	12.65	-8	1297281
-"Rangoon"	16.80528	96.15611	4477638
-"Mandalay"	21.97473	96.08359	1208099
-"Gustavo A. Madero"	19.47861	-99.09583	1193161
-"Puebla de Zaragoza"	19.05	-98.2	1590256
-"Iztapalapa"	19.35111	-99.05194	1820888
-"Ecatepec"	19.60111	-99.0525	1806226
-"Ciudad Nezahualcoyotl"	19.41361	-99.03306	1232220
-"Mexico City"	19.42847	-99.12766	12294193
-"Tijuana"	32.53333	-117.01667	1376457
-"Monterrey"	25.66667	-100.31667	1122874
-"Leon"	21.11667	-101.66667	1114626
-"Guadalajara"	20.66667	-103.33333	1640589
-"Ciudad Juarez"	31.73333	-106.48333	1512354
-"Kuala Lumpur"	3.1412	101.68653	1453975
-"Maputo"	-25.96528	32.58917	1191613
-"Port Harcourt"	4.77742	7.0134	1148665
-"Maiduguri"	11.84644	13.16027	1112449
-"Lagos"	6.45306	3.39583	9000000
-"Kano"	11.99435	8.51381	3626068
-"Kaduna"	10.52224	7.43828	1582102
-"Ibadan"	7.38778	3.89639	3565108
-"Benin City"	6.33504	5.62749	1125058
-"Kathmandu"	27.70169	85.3206	1442271
-"Lima"	-12.04318	-77.02824	7737002
-"Manila"	14.6042	120.9822	10444527
-"Davao"	7.07306	125.61278	1212504
-"Rawalpindi"	33.6007	73.0679	1743101
-"Peshawar"	34.00837	71.58018	1218773
-"Multan"	30.19556	71.47528	1437230
-"Lahore"	31.54972	74.34361	6310888
-"Karachi"	24.9056	67.0822	11624219
-"Hyderabad"	25.3823	68.3699	1386330
-"Gujranwala"	32.16167	74.18831	1384471
-"Faisalabad"	31.41667	73.08333	2506595
-"Warsaw"	52.22977	21.01178	1702139
-"Asuncion"	-25.30066	-57.63591	1482200
-"Bucuresti"	44.43225	26.10626	1877155
-"Belgrade"	44.80401	20.46513	1273651
-"Volgograd"	48.80472	44.58583	1011417
-"Ufa"	54.775	56.0375	1033338
-"Saint Petersburg"	59.89444	30.26417	4039745
-"Samara"	53.2	50.15	1134730
-"Rostov-na-Donu"	47.23639	39.71389	1074482
-"Nizhniy Novgorod"	56.32867	44.00205	1284164
-"Moscow"	55.75222	37.61556	10381222
-"Kazan'"	55.7877	49.1248	1104738
-"Yekaterinburg"	56.8575	60.6125	1287573
-"Omsk"	55	73.4	1129281
-"Novosibirsk"	55.04111	82.93444	1419007
-"Chelyabinsk"	55.15444	61.42972	1062919
-"Mecca"	21.42667	39.82611	1323624
-"Jiddah"	21.51694	39.21917	2867446
-"Riyadh"	24.68773	46.72185	4205961
-"Medina"	24.46861	39.61417	1300000
-"Omdurman"	15.63611	32.43722	1200000
-"Khartoum"	15.54665	32.53361	1974647
-"Stockholm"	59.33258	18.0649	1253309
-"Singapore"	1.28967	103.85007	3547809
-"Grand Dakar"	14.70889	-17.45528	2352057
-"Dakar"	14.6937	-17.44406	2476400
-"Mogadishu"	2.03711	45.34375	2587183
-"Aleppo"	36.20278	37.15861	1602264
-"Damascus"	33.5102	36.29128	1569394
-"Bangkok"	13.75	100.51667	5104476
-"Izmir"	38.41273	27.13838	2500603
-"Gaziantep"	37.05944	37.3825	1065975
-"Ankara"	39.91987	32.85427	3517182
-"Adana"	37.00167	35.32889	1248988
-"Istanbul"	41.01384	28.94966	11174257
-"Bursa"	40.19167	29.06111	1412701
-"Taipei"	25.04776	121.53185	7871900
-"Taichung"	24.1469	120.6839	1040725
-"Kaohsiung"	22.61626	120.31333	1519711
-"Dar es Salaam"	-6.82349	39.26951	2698652
-"Odesa"	46.47747	30.73262	1001558
-"Kiev"	50.45466	30.5238	2514227
-"Kharkiv"	50	36.25	1430885
-"Donets'k"	48	37.8	1024700
-"Dnipropetrovsk"	48.45	34.98333	1032822
-"Kampala"	0.31628	32.58219	1353189
-"Philadelphia"	39.95234	-75.16379	1517550
-"Dallas"	32.78306	-96.80667	1211704
-"Houston"	29.76328	-95.36327	2027712
-"San Antonio"	29.42412	-98.49363	1256810
-"Chicago"	41.85003	-87.65005	2841952
-"Brooklyn"	40.6501	-73.94958	2300664
-"Manhattan"	40.78343	-73.96625	1487536
-"New York City"	40.71427	-74.00597	8008278
-"Phoenix"	33.44838	-112.07404	1321045
-"Los Angeles"	34.05223	-118.24368	3694820
-"San Diego"	32.71533	-117.15726	1223400
-"Montevideo"	-34.83346	-56.16735	1270737
-"Tashkent"	41.26465	69.21627	1978028
-"Valencia"	10.16202	-68.00765	1385083
-"Maracay"	10.24694	-67.59583	1754256
-"Maracaibo"	10.63167	-71.64056	2225000
-"Caracas"	10.5	-66.91667	3000000
-"Thanh pho Ho Chi Minh"	10.75	106.66667	3467331
-"Ha Noi"	21.0245	105.84117	1431270
-"Sanaa"	15.35472	44.20667	1937451
-"Soweto"	-26.26667	27.86667	1695047
-"Pretoria"	-25.74486	28.18783	1619438
-"Johannesburg"	-26.20227	28.04363	2026469
-"Durban"	-29.85	31.01667	3120282
-"Cape Town"	-33.91667	18.41667	3433441
-"Lusaka"	-15.40809	28.28636	1267440
-"Harare"	-17.82935	31.05389	1542813
diff --git a/dojox/geo/openlayers/tests/sun/test_sun.html b/dojox/geo/openlayers/tests/sun/test_sun.html
deleted file mode 100644
index 456fcf7..0000000
--- a/dojox/geo/openlayers/tests/sun/test_sun.html
+++ /dev/null
@@ -1,135 +0,0 @@
-<html>
-<head profile="http://www.w3.org/2002/12/namespace">
-<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/dijit.css">
-<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css">
-<title>Dojo Sun</title>
-<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-
-<!-- hosted version -->
-<script type="text/javascript" src="http://openlayers.org/api/2.10/OpenLayers.js"></script>
-
-<style type="text/css">
-.text {
-	font-size: .7em;
-	vertical-align: bottom;
-}
-
-.nobr {
-	white-space: nowrap
-}
-</style>
-
-<script type="text/javascript">
-	var djConfig = {
-		parseOnLoad : true
-	};
-</script>
-
-<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
-
-<script type="text/javascript">
-	var sunDemo;
-
-	require([	"dojo/ready",
-						"dojo/_base/connect",
-						"dojox/geo/openlayers/tests/sun/SunDemo",
-						"dijit/layout/ContentPane",
-						"dijit/form/HorizontalSlider",
-						"dijit/form/HorizontalRuleLabels",
-						"dijit/form/Textarea",
-						"dijit/form/CheckBox",
-						"dijit/Menu",
-						"dijit/MenuItem",
-						"dijit/CheckedMenuItem",
-						"dijit/PopupMenuItem",
-						"dojo/parser"], function(ready, connect, SunDemo){
-
-		ready(function(){
-			sunDemo = new SunDemo('map');
-
-			updateSliders();
-
-			// dojo.on(sunDemo, "updateFeatures", dojo.hitch(this, updateText));
-			dojo.connect(sunDemo, "updateFeatures", this, updateText);
-		});
-
-		function updateSliders(){
-			var dateSlider = dijit.byId("date");
-			dateSlider.set("value", sunDemo.getDay());
-
-			var bissextile = new Date(sunDemo.sun.getDate().getFullYear(), 2, 0).getDate() == 29;
-			dateSlider.set("maximum", (bissextile ? 366 : 365));
-
-			var timeSlider = dijit.byId("time");
-			timeSlider.set("value", sunDemo.getHour());
-		}
-
-		function updateText(){
-			var ta = dijit.byId("textArea");
-			var s = sunDemo.sun.getDate().toString();
-			ta.set('value', s);
-		}
-	});
-</script>
-
-</head>
-<body class="tundra">
-	<table id="theTable" style="width: 100%; height: 100%;">
-		<tr>
-			<td colspan="2" style="width: 100%; height: 100%;">
-				<div id="map" style="background-color: #b5d0d0; height: 100%; width: 100%;">
-					<div dojoType="dijit.Menu" targetNodeIds="map" style="display: none;">
-						<div id="tt" dojoType="dijit.CheckedMenuItem"
-							onClick="sunDemo.showTooltips(dijit.byId('tt').checked)">Tooltips</div>
-						<div id="grd" dojoType="dijit.CheckedMenuItem"
-							onClick="sunDemo.showGradients(dijit.byId('grd').checked)">Gradients</div>
-						<div id="crl" dojoType="dijit.CheckedMenuItem"
-							onClick="sunDemo.showCircles(dijit.byId('crl').checked)">Circles</div>
-					</div>
-				</div>
-			</td>
-		</tr>
-		<tr>
-			<td class="text" width="5%">Day #</td>
-			<td>
-				<div id="date" dojoType="dijit.form.HorizontalSlider"
-					data-dojo-props='onChange:function(val){sunDemo.setDay(val);}' minimum="0" , maximum="365"
-					pageIncrement="1" showButtons="true" intermediateChanges="true" discreteValues="365">
-					<div dojoType="dijit.form.HorizontalRuleLabels" container="topDecoration" class="text"
-						labels="1,50,100,150,200,250,300,365" style="height: 15;"></div>
-				</div>
-			</td>
-		</tr>
-
-		<tr>
-			<td class="text" width="5%">Time</td>
-			<td>
-				<div id="time" dojoType="dijit.form.HorizontalSlider" maximum="24" minimum="0"
-					showButtons="true" intermediateChanges="true"
-					data-dojo-props='onChange:function(val){sunDemo.setTime(val);}'>
-					<div dojoType="dijit.form.HorizontalRuleLabels" container="topDecoration" class="text"
-						labels="0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24" style="height: 15;"></div>
-				</div>
-			</td>
-		</tr>
-
-		<tr>
-			<td colspan="3">
-				<table style="width: 100%;">
-					<tr>
-						<td style="width: 100%;"><textarea class="text" id="textArea"
-								dojoType="dijit.form.Textarea" style="width: 100%;"></textarea>
-						</td>
-						<td>
-							<button class="text" dojoType="dijit.form.Button" onClick='sunDemo.setDate()'>Now</button></td>
-						<td><span class="nobr"> <input type="checkbox" name="auto" id="auto"
-								onclick="sunDemo.startTimer(dijit.byId('auto').checked)" dojoType="dijit.form.CheckBox"> <label
-								for="auto">auto</label> </span>
-						</td>
-					</tr>
-				</table>
-			</td>
-		</tr>
-	</table>
-</body>
-</html>
diff --git a/dojox/geo/openlayers/tests/test_bench.html b/dojox/geo/openlayers/tests/test_bench.html
index 3f80f35..8f4c77c 100644
--- a/dojox/geo/openlayers/tests/test_bench.html
+++ b/dojox/geo/openlayers/tests/test_bench.html
@@ -6,7 +6,7 @@
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 
 <!-- hosted version -->
-<script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
+<script type="text/javascript" src="http://openlayers.org/api/2/OpenLayers.js"></script>
 
 <script type="text/javascript">
 	var djConfig = {
diff --git a/dojox/geo/openlayers/tests/test_gfx.html b/dojox/geo/openlayers/tests/test_gfx.html
index 4f9c318..fedacfd 100644
--- a/dojox/geo/openlayers/tests/test_gfx.html
+++ b/dojox/geo/openlayers/tests/test_gfx.html
@@ -6,7 +6,7 @@
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 
 <!-- hosted version -->
-<script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
+<script type="text/javascript" src="http://openlayers.org/api/2/OpenLayers.js"></script>
 
 <script type="text/javascript">
 	var djConfig = {
diff --git a/dojox/geo/openlayers/tests/test_gfx2.html b/dojox/geo/openlayers/tests/test_gfx2.html
index 0d6853b..8ab960d 100644
--- a/dojox/geo/openlayers/tests/test_gfx2.html
+++ b/dojox/geo/openlayers/tests/test_gfx2.html
@@ -7,7 +7,7 @@
 <meta name="viewport" content="user-scalable=no, width=device-width" />
 
 <!-- hosted version -->
-<script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
+<script type="text/javascript" src="http://openlayers.org/api/2/OpenLayers.js"></script>
 
 <script type="text/javascript">
 	var djConfig = {
diff --git a/dojox/geo/openlayers/tests/test_gfx_amd.html b/dojox/geo/openlayers/tests/test_gfx_amd.html
new file mode 100644
index 0000000..672af2e
--- /dev/null
+++ b/dojox/geo/openlayers/tests/test_gfx_amd.html
@@ -0,0 +1,169 @@
+<html>
+<head profile="http://www.w3.org/2002/12/namespace">
+<link rel="stylesheet" type="text/css" href="../../../../dijit/themes/dijit.css">
+<link rel="stylesheet" type="text/css" href="../../../../dijit/themes/tundra/tundra.css">
+<title>GFX Layer</title>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+
+<!-- hosted version -->
+<script type="text/javascript" src="http://openlayers.org/api/2/OpenLayers.js"></script>
+
+<script type="text/javascript">
+	var dojoConfig = {
+		isDebug : true,
+		parseOnLoad : true,
+		async:true
+	};
+</script>
+
+<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+<script type="text/javascript">
+	require([
+		"dojo/ready",
+		"dojo/_base/array",
+		"dojo/_base/lang",
+		"dijit/registry",
+		"dojox/geo/openlayers/widget/Map",
+		"dojox/geo/openlayers/GfxLayer",
+		"dojox/geo/openlayers/Point",
+		"dojox/geo/openlayers/LineString",
+		"dojox/geo/openlayers/Collection",
+		"dojox/geo/openlayers/GeometryFeature",
+		"dojo/parser"], 
+		function(ready, arr, lang, registry, Map, GfxLayer, Point, LineString, Collection, GeometryFeature){
+
+		ready(function(){
+			var map = registry.byId("map"),
+				layer = new GfxLayer("GfxLayer");
+			map.map.addLayer(layer);
+			var p1 = {
+				x : 7.154126,
+				y : 43.651748
+			};
+			var pg1 = new Point(p1);
+
+			var p2 = {
+				x : 7.1541,
+				y : 43.6517
+			};
+			var pg2 = new Point(p2);
+
+			var grp = new Collection([pg1, pg2]);
+
+			var gf = new GeometryFeature(grp);
+			gf.setStroke("red");
+			gf.setShapeProperties({
+				r : 10
+			});
+			layer.addFeature(gf);
+
+			var cx = 7.154;
+			var cy = 43.651;
+			var ex = 0.001;
+
+			var a1 = [{
+				x : cx - ex,
+				y : cy + ex
+			}, {
+				x : cx + ex,
+				y : cy + ex
+			}, {
+				x : cx + ex,
+				y : cy - ex
+			}, {
+				x : cx - ex,
+				y : cy - ex
+			}, {
+				x : cx - ex,
+				y : cy + ex
+			}];
+
+			ex = 0.00018;
+			var a2 = [{
+				x : cx - ex,
+				y : cy + ex
+			}, {
+				x : cx + ex,
+				y : cy + ex
+			}, {
+				x : cx + ex,
+				y : cy - ex
+			}, {
+				x : cx - ex,
+				y : cy - ex
+			}, {
+				x : cx - ex,
+				y : cy + ex
+			}];
+
+			var f1 = new LineString(a1);
+			var f2 = new LineString(a2);
+
+			grp = new Collection([f1, f2]);
+			gf = new GeometryFeature(grp);
+			gf.setStroke("blue");
+			gf.setFill([0, 0, 0, 0.2]);
+			layer.addFeature(gf);
+			arr.forEach(a2, function(p){
+				var pg = new Point(p);
+				gf = new GeometryFeature(pg);
+				gf.createShape = lang.hitch(this, function(/* Surface */s){
+					var r1 = 30;
+					var r2 = 10;
+					var branches = 9;
+					var star = makeStarShape(r1, r2, branches);
+					var path = s.createPath();
+					path.setShape({
+						path : star
+					});
+					return path;
+				});
+				gf.setStroke("aqua");
+				//      gf.setFill({
+				//        color : [ 255, 100, 0 ]
+				//      });
+				gf.setFill([255, 100, 0]);
+				layer.addFeature(gf);
+			});
+			layer.redraw();
+		});
+
+		function makeStarShape(r1, r2, b){
+			var TPI = Math.PI * 2;
+			var di = TPI / b;
+			var s = null;
+			var start = Math.PI;
+			var end = start + TPI;
+			for ( var i = start; i < end; i += di) {
+				var c1 = Math.cos(i);
+				var s1 = Math.sin(i);
+				var i2 = i + di / 2;
+				var c2 = Math.cos(i2);
+				var s2 = Math.sin(i2);
+				if (s == null) {
+					s = "M" + (s1 * r1).toFixed(2) + "," + (c1 * r1).toFixed(2) + " ";
+				} else {
+					s += "L" + (s1 * r1).toFixed(2) + "," + (c1 * r1).toFixed(2) + " ";
+				}
+				s += "L" + (s2 * r2).toFixed(2) + "," + (c2 * r2).toFixed(2) + " ";
+			}
+			s += "z";
+			return s;
+		}
+
+	});
+</script>
+
+</head>
+<body class="tundra">
+</head>
+
+<div id="map" dojoType="dojox.geo.openlayers.widget.Map" baseLayerType="'OSM'"
+	initialLocation="{
+    position : [7.154126, 43.651748],
+    extent : 0.002 }"
+	style="background-color: #b5d0d0; width: 100%; height: 100%;"></div>
+
+</body>
+</html>
diff --git a/dojox/geo/openlayers/tests/test_widget.html b/dojox/geo/openlayers/tests/test_widget.html
index 2dd3fd8..6e572a7 100644
--- a/dojox/geo/openlayers/tests/test_widget.html
+++ b/dojox/geo/openlayers/tests/test_widget.html
@@ -9,7 +9,7 @@
 <script src="http://maps.google.com/maps/api/js?v=3&sensor=false"></script>
 
 <!-- hosted version -->
-<script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
+<script type="text/javascript" src="http://openlayers.org/api/2/OpenLayers.js"></script>
 
 <script type="text/javascript">
 	var djConfig = {
diff --git a/dojox/geo/openlayers/tests/widgetFeature/test_widgetFeature.html b/dojox/geo/openlayers/tests/widgetFeature/test_widgetFeature.html
index ceafa77..f938a1d 100644
--- a/dojox/geo/openlayers/tests/widgetFeature/test_widgetFeature.html
+++ b/dojox/geo/openlayers/tests/widgetFeature/test_widgetFeature.html
@@ -6,7 +6,7 @@
 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
 
 <!-- hosted version -->
-<script type="text/javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
+<script type="text/javascript" src="http://openlayers.org/api/2/OpenLayers.js"></script>
 
 <script type="text/javascript">
 	var djConfig = {
diff --git a/dojox/geo/openlayers/tests/widgetFeature/test_widgetFeature_amd.html b/dojox/geo/openlayers/tests/widgetFeature/test_widgetFeature_amd.html
new file mode 100644
index 0000000..ee68d6d
--- /dev/null
+++ b/dojox/geo/openlayers/tests/widgetFeature/test_widgetFeature_amd.html
@@ -0,0 +1,328 @@
+<html>
+<head profile="http://www.w3.org/2002/12/namespace">
+<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/dijit.css">
+<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css">
+<title>Dojo Widget Feature</title>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+
+<!-- hosted version -->
+<script type="text/javascript" src="http://openlayers.org/api/2/OpenLayers.js"></script>
+
+<script type="text/javascript">
+	var dojoConfig = {
+		parseOnLoad : true,
+		async:true
+	};
+</script>
+
+<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
+
+<script type="text/javascript">
+	require([
+		"dojo/ready",
+		"dojo/_base/array",
+		"dojo/_base/window",
+		"dojo/sniff",
+		"dojo/dom-construct",
+		"dojox/geo/openlayers/_base",
+		"dojox/geo/openlayers/widget/Map",
+		"dojox/geo/openlayers/Layer",
+		"dojox/geo/openlayers/WidgetFeature",
+		"dojox/charting/widget/Chart",
+		"dojox/charting/themes/PlotKit/blue",
+		"dijit/form/RadioButton",
+		"dojo/parser",
+		"dojox/charting/plot2d/Pie"
+		], 
+		function(ready, arr, win, sniff, domConstruct, openlayers, Map, Layer, WidgetFeature, Chart, blue, RadioButton){
+
+		var map;
+
+		ready(function(){
+			var opts = {
+				baseLayerType : openlayers.OSM
+			};
+
+			map = new Map({}, "map");
+			map.startup();
+
+			var loc = '{"position" : [2.940673, 47.179259], "extent" : "5"}';
+			map.map.fitTo(loc);
+
+			createCharts();
+		});
+
+		function toDeg(r){
+			return r * 180 / Math.PI;
+		}
+
+		var locs = [{
+			name : "Nice",
+			x : 7.262,
+			y : 43.706
+		}, {
+			name : "Aix-en-Provence",
+			x : 5.448,
+			y : 43.528
+		}, {
+			name : "Marseille",
+			x : 5.399,
+			y : 43.297
+		}, {
+			name : "Caen",
+			x : -0.360,
+			y : 49.184
+		}, {
+			name : "Dijon",
+			x : 5.036,
+			y : 47.322
+		}, {
+			name : "Besancon",
+			x : 6.026,
+			y : 47.245
+		}, {
+			name : "Brest",
+			x : -4.490,
+			y : 48.388
+		}, {
+			name : "Nimes",
+			x : 4.361,
+			y : 43.839
+		}, {
+			name : "Toulouse",
+			x : 1.450,
+			y : 43.600
+		}, {
+			name : "Bordeaux",
+			x : -0.575,
+			y : 44.843
+		}, {
+			name : "Montpellier",
+			x : 3.874,
+			y : 43.609
+		}, {
+			name : "Rennes",
+			x : -1.680,
+			y : 48.108
+		}, {
+			name : "Tours",
+			x : 0.684,
+			y : 47.393
+		}, {
+			name : "Grenoble",
+			x : 5.723,
+			y : 45.185
+		}, {
+			name : "Saint-Etienne",
+			x : 4.390,
+			y : 45.441
+		}, {
+			name : "Nantes",
+			x : -1.554,
+			y : 47.219
+		}, {
+			name : "Orleans",
+			x : 1.907,
+			y : 47.904
+		}, {
+			name : "Angers",
+			x : -0.556,
+			y : 47.471
+		}, {
+			name : "Reims",
+			x : 4.031,
+			y : 49.258
+		}, {
+			name : "Nancy",
+			x : 6.174,
+			y : 48.690
+		}, {
+			name : "Metz",
+			x : 6.183,
+			y : 49.109
+		}, {
+			name : "Lille",
+			x : 3.045,
+			y : 50.628
+		}, {
+			name : "Clermont-Ferrand",
+			x : 3.085,
+			y : 45.779
+		}, {
+			name : "Perpignan",
+			x : 2.893,
+			y : 42.698
+		}, {
+			name : "Strasbourg",
+			x : 7.756,
+			y : 48.584
+		}, {
+			name : "Mulhouse",
+			x : 7.333,
+			y : 47.748
+		}, {
+			name : "Lyon",
+			x : 4.835,
+			y : 45.760
+		}, {
+			name : "Villeurbanne",
+			x : 4.882,
+			y : 45.779
+		}, {
+			name : "Le Mans",
+			x : 0.203,
+			y : 47.996
+		}, {
+			name : "Paris",
+			x : 2.346,
+			y : 48.861
+		}, {
+			name : "Le Havre",
+			x : 0.127,
+			y : 49.501
+		}, {
+			name : "Rouen",
+			x : 1.089,
+			y : 49.438
+		}, {
+			name : "Amiens",
+			x : 2.293,
+			y : 49.894
+		}, {
+			name : "Toulon",
+			x : 5.934,
+			y : 43.127
+		}, {
+			name : "Limoges",
+			x : 1.259,
+			y : 45.832
+		}, {
+			name : "Boulogne-Billancourt",
+			x : 2.242,
+			y : 48.840
+		}];
+
+		var locsIE = [{
+			name : "Nice",
+			x : 7.262,
+			y : 43.706
+		}, {
+			name : "Saint-Etienne",
+			x : 4.390,
+			y : 45.441
+		}, {
+			name : "Strasbourg",
+			x : 7.756,
+			y : 48.584
+		}, {
+			name : "Boulogne-Billancourt",
+			x : 2.242,
+			y : 48.840
+		}];
+
+		function createCharts(){
+			var layer = new Layer();
+			map.map.addLayer(layer);
+			var lo;
+			if(sniff.isIE)
+				lo = locsIE;
+			else
+				lo = locs;
+			arr.forEach(lo, function(l){
+				var feature = createChart(l, {});
+				layer.addFeature(feature);
+			});
+			setTimeout(function(){
+				layer.redraw();
+			}, 500);
+		}
+
+		function getCoords(loc){
+			var lng = 0;
+			if(loc.hasOwnProperty('x'))
+				lng = loc.x;
+			if(loc.hasOwnProperty('lng'))
+				lng = openlayers.parseDMS(loc.lng, true);
+
+			var lat = 0;
+			if(loc.hasOwnProperty('y'))
+				lat = loc.y;
+			if(loc.hasOwnProperty('lat'))
+				lat = openlayers.parseDMS(loc.lat, true);
+			return [lng, lat];
+		}
+
+		function createButton(loc){
+			var db = domConstruct.create("div", {}, win.body());
+			var b = new RadioButton({
+				checked : false
+			}, db);
+			var c = getCoords(loc);
+			var f = {
+				longitude : c[0],
+				latitude : c[1],
+				widget : b,
+				width : 15,
+				height : 15
+			};
+			return new WidgetFeature(f);
+		}
+
+		function createChart(loc, params){
+			var feature = null, co = getCoords(loc), descr;
+
+			if(params.dijitId){
+				descr = {
+					longitude : co[0],
+					latitude : co[1],
+					dijitId : params.dijitId,
+					width : 50,
+					height : 50
+				};
+				feature = new WidgetFeature(descr);
+			}else{
+				var chartSize = 50;
+				descr = {
+					// location of the widget
+					longitude : co[0],
+					latitude : co[1],
+					// the function which creates the widget
+					createWidget : function(){
+						var div = domConstruct.create("div", {}, win.body());
+						var chart = new Chart({
+							margins : {
+								l : 0,
+								r : 0,
+								t : 0,
+								b : 0
+							}
+						}, div);
+						var c = chart.chart;
+						c.addPlot("default", {
+							type : "Pie",
+							radius : chartSize / 2,
+							labelOffset : chartSize,
+							fontColor : "black"
+						});
+
+						var ser = [2, 8, 12, 43, 56, 23, 43, 1, 33];
+						c.addSeries("Series", ser);
+						c.setTheme(blue);
+						c.render();
+						c.theme.plotarea.fill = undefined;
+						return chart;
+					},
+					width : chartSize,
+					height : chartSize
+				};
+				feature = new WidgetFeature(descr);
+			}
+			return feature;
+		}
+	});
+</script>
+</head>
+<body class="tundra">
+	<div id="map" style="background-color: #b5d0d0; width: 100%; height: 100%;"></div>
+</body>
+</html>
diff --git a/dojox/geo/openlayers/widget/Map.js b/dojox/geo/openlayers/widget/Map.js
index 8d086e0..e84f9d8 100644
--- a/dojox/geo/openlayers/widget/Map.js
+++ b/dojox/geo/openlayers/widget/Map.js
@@ -1,111 +1,103 @@
-define(["dojo/_base/kernel",
-				"dojo/_base/declare",
-				"dojo/_base/array",
-				"dojo/_base/html",
-				"dojo/query",
-				"dijit/_Widget",
-				"dojox/geo/openlayers/Map",
-				"dojox/geo/openlayers/Layer",
-				"dojox/geo/openlayers/GfxLayer"], function(dojo, declare, array, html, query, Widget, Map, Layer, GfxLayer){
-		/*===== 
-		var Widget = dijit.Widget; 
-		=====*/
+define([
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/dom-geometry",
+	"dojo/query",
+	"dijit/_Widget",
+	"../_base",
+	"../Map",
+	"../Layer",
+	"../GfxLayer"
+], function(lang, declare, array, domgeo, query, Widget, openlayers, Map, Layer, GfxLayer){
+
 	return declare("dojox.geo.openlayers.widget.Map", Widget, {
-		//	summary: 
+		// summary:
 		//		A widget version of the `dojox.geo.openlayers.Map` component.
-		//	description: 
+		// description:
 		//		The `dojox.geo.openlayers.widget.Map` widget is the widget 
 		//		version of the `dojox.geo.openlayers.Map` component. 
-		//		With this widget, user can specify some attributes in the markup suach as
-		// 
-		//	* `baseLayerType`: The type of the base layer. Permitted values are 
-		//	* `initialLocation`: The initial location as for the dojox.geo.openlayers.Map.fitTo method
-		//	* `touchHandler`: Tells if we attach touch handler or not.
-		//	
-		//	example:
-		//	
+		//		With this widget, user can specify some attributes in the markup such as
+		//		
+		//		- `baseLayerType`: The type of the base layer. Permitted values are
+		//		- `initialLocation`: The initial location as for the dojox.geo.openlayers.Map.fitTo method
+		//		- `touchHandler`: Tells if we attach touch handler or not.
+		//
+		// example:
 		//	| <div id="map" dojoType="dojox.geo.openlayers.widget.Map" baseLayerType="Google" initialLocation="{
-		//	|   position : [7.154126, 43.651748],
-		//	|   extent : 0.2 }"
+		//	|   position: [7.154126, 43.651748],
+		//	|   extent: 0.2 }"
 		//	| style="background-color: #b5d0d0; width: 100%; height: 100%;">
 		//
 
-		//	summay:
-		//		Base layer type as defined in `dojox.geo.openlayer.BaseLayerType
-		//	description:
-		//		baseLayerType can be either 
-		//		* `OSM`
-		//		* `WMS`
-		//		* `Google`
-		//		* `VirtualEarth`
-		//		* `Yahoo`
-		//		* `ArcGIS`
-		//	baseLayerType : String
-		//		Base layer type property.
-		baseLayerType : dojox.geo.openlayers.BaseLayerType.OSM,
+		// baseLayerType: String
+		//		Base layer type as defined in `dojox.geo.openlayer.BaseLayerType`. Can be one of:
+		//
+		//		- `OSM`
+		//		- `WMS`
+		//		- `Google`
+		//		- `VirtualEarth`
+		//		- `Yahoo`
+		//		- `ArcGIS`
+		baseLayerType: openlayers.BaseLayerType.OSM,
 
-		//	summary:
-		//		The part of the map shown at startup time.
-		//	description:
-		//		initial location is the string description of the location shown at 
+		// initialLocation: String
+		//		The part of the map shown at startup time. It is the string description of the location shown at
 		//		startup time. Format is the same as for the `dojox.geo.openlayers.widget.Map.fitTo`
 		//		method.
 		//	|	{
-		//	|	bounds : [ulx, uly, lrx, lry]
+		//	|		bounds: [ulx, uly, lrx, lry]
 		//	|	}
 		//		The map is fit on the specified bounds expressed as decimal degrees latitude and longitude.
 		//		The bounds are defined with their upper left and lower right corners coordinates.
-		//	
+		//
 		//	|	{
-		//	|	position : [longitude, latitude],
-		//	|	extent : degrees
+		//	|		position: [longitude, latitude],
+		//	|		extent: degrees
 		//	|	}
-		//	The map is fit on the specified position showing the extent <extent> around
-		//	the specified center position.
-		initialLocation : null,
+		//		The map is fit on the specified position showing the extent `<extent>` around
+		//		the specified center position.
+		initialLocation: null,
 
-		//	summary:
-		//		Tells if the touch handler should be attached to the map or not.
-		//	description:
+		// touchHandler: Boolean
 		//		Tells if the touch handler should be attached to the map or not.
 		//		Touch handler handles touch events so that the widget can be used
 		//		on mobile applications.
-		touchHandler : false,
+		touchHandler: false,
 
-		//	summary:
-		//		The underlying `dojox.geo.openlayers.Map` object.
-		//		This is s readonly member.
+		// map: [readonly] Map
+		//		The underlying `dojox/geo/openlayers/Map` object.
 		map : null,
 
-		startup : function(){
-			//	summary:
+		startup: function(){
+			// summary:
 			//		Processing after the DOM fragment is added to the document
 			this.inherited(arguments);
 			this.map.initialFit({
-				initialLocation : this.initialLocation
+				initialLocation: this.initialLocation
 			});
 		},
 
-		buildRendering : function(){
-			//	summary:
+		buildRendering: function(){
+			// summary:
 			//		Construct the UI for this widget, creates the real dojox.geo.openlayers.Map object.		
-			//	tags:
+			// tags:
 			//		protected
 			this.inherited(arguments);
 			var div = this.domNode;
 			var map = new Map(div, {
-				baseLayerType : this.baseLayerType,
-				touchHandler : this.touchHandler
+				baseLayerType: this.baseLayerType,
+				touchHandler: this.touchHandler
 			});
 			this.map = map;
 
 			this._makeLayers();
 		},
 
-		_makeLayers : function(){
-			//	summary:
+		_makeLayers: function(){
+			// summary:
 			//		Creates layers defined as markup.
-			//	tags:
+			// tags:
 			//		private
 			var n = this.domNode;
 			var layers = /* ?? query. */query("> .layer", n);
@@ -113,45 +105,48 @@ define(["dojo/_base/kernel",
 				var type = l.getAttribute("type");
 				var name = l.getAttribute("name");
 				var cls = "dojox.geo.openlayers." + type;
-				var p = dojo.getObject(cls);
-				if (p) {
+				var p = lang.getObject(cls);
+				if(p){
 					var layer = new p(name, {});
-					if (layer)
+					if(layer){
 						this.map.addLayer(layer);
+					}
 				}
 			}, this);
 		},
 
-		resize : function(b){
-			//	summary:
+		resize : function(b,h){
+			// summary:
 			//		Resize the widget.
-			//	description:
+			// description:
 			//		Resize the domNode and the widget to the dimensions of a box of the following form:
-			//			`{ l: 50, t: 200, w: 300: h: 150 }`
-			//	b: undefined | Box | width, height
+			//		`{ l: 50, t: 200, w: 300: h: 150 }`
+			// b: Object|Number?
 			//		If passed, denotes the new size of the widget.
-			// 		Can be either nothing (widget adapts to the div),
-			// 		a box, or a width and a height.
+			//		Can be either nothing (widget adapts to the div),
+			//		an Object describing a box, or a Number representing the width.
+			// h: Number?
+			//		The new height. Requires that a width has been specified in the first parameter.
 
 			var olm = this.map.getOLMap();
 
 			var box;
-			switch (arguments.length) {
+			switch(arguments.length){
 				case 0:
 					// case 0, do not resize the div, just the surface
 				break;
 				case 1:
 					// argument, override node box
-					box = dojo.mixin({}, b);
-					dojo.marginBox(olm.div, box);
+					box = lang.mixin({}, b);
+					domgeo.setMarginBox(olm.div, box);
 				break;
 				case 2:
 					// two argument, width, height
 					box = {
-						w : arguments[0],
-						h : arguments[1]
+						w: arguments[0],
+						h: arguments[1]
 					};
-					dojo.marginBox(olm.div, box);
+					domgeo.setMarginBox(olm.div, box);
 				break;
 			}
 			olm.updateSize();
diff --git a/dojox/gesture/Base.js b/dojox/gesture/Base.js
index 65aeed0..a65af52 100644
--- a/dojox/gesture/Base.js
+++ b/dojox/gesture/Base.js
@@ -70,7 +70,7 @@ define([
 		//		|		return dojox.gesture.a;
 		//		|	});
 		//
-		//		2. A gesture can be used in the following ways(taking dojox.gestre.tap for example):
+		//		2. A gesture can be used in the following ways(taking dojox.gesture.tap for example):
 		//
 		//		A. Used with dojo.connect()
 		//		|	dojo.connect(node, dojox.gesture.tap, function(e){});
@@ -120,7 +120,7 @@ define([
 		//		Whether the gesture is touch-device only
 		touchOnly : false,
 
-		//	_elements: Array
+		// _elements: Array
 		//		List of elements that wraps target node and gesture data
 		_elements: null,
 
@@ -264,7 +264,11 @@ define([
 				return;
 			}
 			// invoking gesture.press()|move()|release()|cancel()
-			e.preventDefault();
+			// #16900: same condition as in dojo/touch, to avoid breaking the editing of input fields.
+			if((e.target.tagName != "INPUT" || e.target.type == "radio" || e.target.type == "checkbox")
+				&& e.target.tagName != "TEXTAREA"){
+				e.preventDefault(); 
+			}
 			e._locking[this.defaultEvent] = true;
 			this[phase](element.data, e);
 		},
diff --git a/dojox/gesture/swipe.js b/dojox/gesture/swipe.js
index 3b27d08..3acab3b 100644
--- a/dojox/gesture/swipe.js
+++ b/dojox/gesture/swipe.js
@@ -12,24 +12,21 @@ define([
 		// summary:
 		//		This module provides swipe gestures including:
 		//
-		//		1. dojox.gesture.swipe
+		//		####dojox.gesture.swipe
 		//
-		//			A series of 'swipe' will be fired during touchmove, this will mostly
-		//			be used to keep sliding the Dom target based on the swiped distance(dx, dy).
+		//		A series of 'swipe' will be fired during touchmove, this will mostly
+		//		be used to keep sliding the Dom target based on the swiped distance(dx, dy).
 		//
-		//		2. dojox.gesture.swipe.end
+		//		####dojox.gesture.swipe.end
 		//	
-		//			Fired when a swipe is ended so that an bounce animation may be applied
-		//			to the dom target sliding to the final position.
+		//		Fired when a swipe is ended so that an bounce animation may be applied
+		//		to the dom target sliding to the final position.
 		//
 		//		Following information will be included in the fired swipe events:
 		//
 		//		1. type: 'swipe'|'swipe.end'
-		//
 		//		2. time: an integer indicating the delta time(in milliseconds)
-		//
 		//		3. dx: delta distance on X axis, dx less than 0 - moving left, dx larger than 0 - moving right
-		//
 		//		4. dy: delta distance on Y axis, dy less than 0 - moving up, dY larger than 0 - moving down
 		//
 		//		Note - dx and dy can also be used together for a hybrid swipe(both vertically and horizontally)
diff --git a/dojox/gesture/tap.js b/dojox/gesture/tap.js
index a130dd6..10ad030 100644
--- a/dojox/gesture/tap.js
+++ b/dojox/gesture/tap.js
@@ -78,6 +78,7 @@ var clz = declare(/*===== "dojox.gesture.tap", =====*/Base, {
 		//		Overwritten, record initial tap info and register a timeout checker for 'tap.hold'
 		if(e.touches && e.touches.length >= 2){
 			//tap gesture is only for single touch
+			clearTimeout(data.tapTimeOut); 
 			delete data.context;
 			return;
 		}
diff --git a/dojox/gesture/tests/doh/bubble.html b/dojox/gesture/tests/doh/bubble.html
index e7e3d71..99aa2b1 100644
--- a/dojox/gesture/tests/doh/bubble.html
+++ b/dojox/gesture/tests/doh/bubble.html
@@ -21,7 +21,7 @@
 		}
 		
 	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 	<script type="text/javascript">
 		require([
 			"dojo/_base/html",
diff --git a/dojox/gesture/tests/doh/swipe.html b/dojox/gesture/tests/doh/swipe.html
index 07ea44f..252c502 100644
--- a/dojox/gesture/tests/doh/swipe.html
+++ b/dojox/gesture/tests/doh/swipe.html
@@ -21,7 +21,7 @@
 		}
 		
 	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 	<script type="text/javascript">
 		require([
 			"dojo/_base/html",
diff --git a/dojox/gesture/tests/doh/tap.html b/dojox/gesture/tests/doh/tap.html
index eca13f2..0b43124 100644
--- a/dojox/gesture/tests/doh/tap.html
+++ b/dojox/gesture/tests/doh/tap.html
@@ -21,7 +21,7 @@
 		}
 		
 	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 	<script type="text/javascript">
 		require([
 			"dojo/_base/html",
diff --git a/dojox/gesture/tests/test_gesture.html b/dojox/gesture/tests/test_gesture.html
index 6fb3ca4..9dd7178 100644
--- a/dojox/gesture/tests/test_gesture.html
+++ b/dojox/gesture/tests/test_gesture.html
@@ -13,7 +13,7 @@
 			}
 			#inner {
 				width: 250px;
-				height: 80px;
+				height: 140px;
 				border: 1px solid #7FB0DB;
 				background-color: #7FB0DB
 			}
@@ -22,7 +22,7 @@
 				height: 50px;
 			}
 		</style>		
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
 		<script>
 			require([
 				"dojo/_base/kernel",
@@ -85,7 +85,15 @@
 	</head>
 	<body>
 		<div id="outer">
-			outer<div id="inner">inner</div>
+			outer
+			<div id="inner">inner
+				<br/>
+				<input id="input" type="text" placeholder="type here"/>input
+				<br/>
+				<input id="pwd" type="password" name="pwd" placeholder="type here"/>password
+				<br/>
+				<textarea id="textarea" rows="3" cols="20" style="width: 150px; height:30px" placeholder="type here" ></textarea>textarea
+			</div>
 		</div>
 		<div id="log1"></div>
 		<hr/>
diff --git a/dojox/gfx/Moveable.js b/dojox/gfx/Moveable.js
index 2e3689f..6ffdad0 100644
--- a/dojox/gfx/Moveable.js
+++ b/dojox/gfx/Moveable.js
@@ -1,40 +1,62 @@
-define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array","dojo/_base/event","dojo/_base/connect",
-	"dojo/dom-class","dojo/_base/window","./Mover"], 
-  function(lang,declare,arr,event,connect,domClass,win,Mover){
+define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array","dojo/_base/event","dojo/topic","dojo/touch",
+	"dojo/dom-class","dojo/_base/window","./Mover"],
+  function(lang,declare,arr,event,topic,touch,domClass,win,Mover){
+
+	/*=====
+	var __MoveableCtorArgs = declare("dojox.gfx.__MoveableCtorArgs", null, {
+		// summary:
+		//		The arguments used for dojox/gfx/Moveable constructor.
+
+		// delay: Number
+		//		delay move by this number of pixels
+		delay:0,
+
+		// mover: Object
+		//		a constructor of custom Mover
+		mover:Mover
+	});
+	=====*/
+
 	return declare("dojox.gfx.Moveable", null, {
 		constructor: function(shape, params){
-			// summary: an object, which makes a shape moveable
-			// shape: dojox.gfx.Shape: a shape object to be moved
-			// params: Object: an optional object with additional parameters;
-			//	following parameters are recognized:
-			//		delay: Number: delay move by this number of pixels
-			//		mover: Object: a constructor of custom Mover
+			// summary:
+			//		an object, which makes a shape moveable
+			// shape: dojox/gfx.Shape
+			//		a shape object to be moved.
+			// params: __MoveableCtorArgs
+			//		an optional configuration object.
+
 			this.shape = shape;
 			this.delay = (params && params.delay > 0) ? params.delay : 0;
 			this.mover = (params && params.mover) ? params.mover : Mover;
 			this.events = [
-				this.shape.connect("onmousedown", this, "onMouseDown")
+				this.shape.on(touch.press, lang.hitch(this, "onMouseDown"))
 				// cancel text selection and text dragging
 				//, dojo.connect(this.handle, "ondragstart",   dojo, "stopEvent")
 				//, dojo.connect(this.handle, "onselectstart", dojo, "stopEvent")
 			];
 		},
-	
+
 		// methods
 		destroy: function(){
-			// summary: stops watching for possible move, deletes all references, so the object can be garbage-collected
-			arr.forEach(this.events, this.shape.disconnect, this.shape);
+			// summary:
+			//		stops watching for possible move, deletes all references, so the object can be garbage-collected
+			arr.forEach(this.events, function(handle){
+				handle.remove();
+			});
 			this.events = this.shape = null;
 		},
-	
+
 		// mouse event processors
 		onMouseDown: function(e){
-			// summary: event processor for onmousedown, creates a Mover for the shape
-			// e: Event: mouse event
+			// summary:
+			//		event processor for onmousedown, creates a Mover for the shape
+			// e: Event
+			//		mouse event
 			if(this.delay){
 				this.events.push(
-					this.shape.connect("onmousemove", this, "onMouseMove"),
-					this.shape.connect("onmouseup", this, "onMouseUp"));
+					this.shape.on(touch.move, lang.hitch(this, "onMouseMove")),
+					this.shape.on(touch.release, lang.hitch(this, "onMouseUp")));
 				this._lastX = e.clientX;
 				this._lastY = e.clientY;
 			}else{
@@ -43,55 +65,85 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array","dojo/_base/ev
 			event.stop(e);
 		},
 		onMouseMove: function(e){
-			// summary: event processor for onmousemove, used only for delayed drags
-			// e: Event: mouse event
-			if(Math.abs(e.clientX - this._lastX) > this.delay || Math.abs(e.clientY - this._lastY) > this.delay){
+			// summary:
+			//		event processor for onmousemove, used only for delayed drags
+			// e: Event
+			//		mouse event
+			var clientX = e.clientX,
+				clientY = e.clientY;
+
+			if(Math.abs(clientX - this._lastX) > this.delay || Math.abs(clientY - this._lastY) > this.delay){
 				this.onMouseUp(e);
 				new this.mover(this.shape, e, this);
 			}
 			event.stop(e);
 		},
 		onMouseUp: function(e){
-			// summary: event processor for onmouseup, used only for delayed delayed drags
-			// e: Event: mouse event
-			this.shape.disconnect(this.events.pop());
-			this.shape.disconnect(this.events.pop());
+			// summary:
+			//		event processor for onmouseup, used only for delayed delayed drags
+			// e: Event
+			//		mouse event
+			this.events.pop().remove();
 		},
-	
+
 		// local events
-		onMoveStart: function(/* dojox.gfx.Mover */ mover){
-			// summary: called before every move operation
-			connect.publish("/gfx/move/start", [mover]);
+		onMoveStart: function(/* dojox/gfx/Mover */ mover){
+			// summary:
+			//		called before every move operation
+			// mover:
+			//		A Mover instance that fired the event.
+			topic.publish("/gfx/move/start", mover);
 			domClass.add(win.body(), "dojoMove");
 		},
-		onMoveStop: function(/* dojox.gfx.Mover */ mover){
-			// summary: called after every move operation
-			connect.publish("/gfx/move/stop", [mover]);
+		onMoveStop: function(/* dojox/gfx/Mover */ mover){
+			// summary:
+			//		called after every move operation
+			// mover:
+			//		A Mover instance that fired the event.
+			topic.publish("/gfx/move/stop", mover);
 			domClass.remove(win.body(), "dojoMove");
 		},
-		onFirstMove: function(/* dojox.gfx.Mover */ mover){
-			// summary: called during the very first move notification,
-			//	can be used to initialize coordinates, can be overwritten.
-	
+		onFirstMove: function(/* dojox/gfx/Mover */ mover){
+			// summary:
+			//		called during the very first move notification,
+			//		can be used to initialize coordinates, can be overwritten.
+			// mover:
+			//		A Mover instance that fired the event.
+
 			// default implementation does nothing
 		},
-		onMove: function(/* dojox.gfx.Mover */ mover, /* Object */ shift){
-			// summary: called during every move notification,
-			//	should actually move the node, can be overwritten.
+		onMove: function(/* dojox/gfx/Mover */ mover, /* Object */ shift){
+			// summary:
+			//		called during every move notification,
+			//		should actually move the node, can be overwritten.
+			// mover:
+			//		A Mover instance that fired the event.
+			// shift:
+			//		An object as {dx,dy} that represents the shift.
 			this.onMoving(mover, shift);
 			this.shape.applyLeftTransform(shift);
 			this.onMoved(mover, shift);
 		},
-		onMoving: function(/* dojox.gfx.Mover */ mover, /* Object */ shift){
-			// summary: called before every incremental move,
-			//	can be overwritten.
-	
+		onMoving: function(/* dojox/gfx/Mover */ mover, /* Object */ shift){
+			// summary:
+			//		called before every incremental move,
+			//		can be overwritten.
+			// mover:
+			//		A Mover instance that fired the event.
+			// shift:
+			//		An object as {dx,dy} that represents the shift.
+
 			// default implementation does nothing
 		},
-		onMoved: function(/* dojox.gfx.Mover */ mover, /* Object */ shift){
-			// summary: called after every incremental move,
-			//	can be overwritten.
-	
+		onMoved: function(/* dojox/gfx/Mover */ mover, /* Object */ shift){
+			// summary:
+			//		called after every incremental move,
+			//		can be overwritten.
+			// mover:
+			//		A Mover instance that fired the event.
+			// shift:
+			//		An object as {dx,dy} that represents the shift.
+
 			// default implementation does nothing
 		}
 	});
diff --git a/dojox/gfx/Mover.js b/dojox/gfx/Mover.js
index bec60a4..8b0195a 100644
--- a/dojox/gfx/Mover.js
+++ b/dojox/gfx/Mover.js
@@ -1,25 +1,29 @@
-define(["dojo/_base/lang","dojo/_base/array", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/event"], 
-  function(lang,arr,declare,connect,evt){
+define(["dojo/_base/lang","dojo/_base/array", "dojo/_base/declare", "dojo/on", "dojo/touch", "dojo/_base/event"],
+  function(lang, arr, declare, on, touch, event){
 	return declare("dojox.gfx.Mover", null, {
 		constructor: function(shape, e, host){
-			// summary: an object, which makes a shape follow the mouse,
-			//	used as a default mover, and as a base class for custom movers
-			// shape: dojox.gfx.Shape: a shape object to be moved
-			// e: Event: a mouse event, which started the move;
-			//	only clientX and clientY properties are used
-			// host: Object?: object which implements the functionality of the move,
-			//	 and defines proper events (onMoveStart and onMoveStop)
+			// summary:
+			//		an object, which makes a shape follow the mouse,
+			//		used as a default mover, and as a base class for custom movers
+			// shape: dojox/gfx.Shape
+			//		a shape object to be moved
+			// e: Event
+			//		a mouse event, which started the move;
+			//		only clientX and clientY properties are used
+			// host: Object?
+			//		object which implements the functionality of the move,
+			//		 and defines proper events (onMoveStart and onMoveStop)
 			this.shape = shape;
-			this.lastX = e.clientX
+			this.lastX = e.clientX;
 			this.lastY = e.clientY;
 			var h = this.host = host, d = document,
-				firstEvent = connect.connect(d, "onmousemove", this, "onFirstMove");
+				firstEvent = on(d, touch.move, lang.hitch(this, "onFirstMove"));
 			this.events = [
-				connect.connect(d, "onmousemove", this, "onMouseMove"),
-				connect.connect(d, "onmouseup",   this, "destroy"),
+				on(d, touch.move, lang.hitch(this, "onMouseMove")),
+				on(d, touch.release, lang.hitch(this, "destroy")),
 				// cancel text selection and text dragging
-				connect.connect(d, "ondragstart",   evt, "stop"),
-				connect.connect(d, "onselectstart", evt, "stop"),
+				on(d, "dragstart",   lang.hitch(event, "stop")),
+				on(d, "selectstart", lang.hitch(event, "stop")),
 				firstEvent
 			];
 			// notify that the move has started
@@ -29,24 +33,30 @@ define(["dojo/_base/lang","dojo/_base/array", "dojo/_base/declare", "dojo/_base/
 		},
 		// mouse event processors
 		onMouseMove: function(e){
-			// summary: event processor for onmousemove
-			// e: Event: mouse event
+			// summary:
+			//		event processor for onmousemove
+			// e: Event
+			//		mouse event
 			var x = e.clientX;
 			var y = e.clientY;
 			this.host.onMove(this, {dx: x - this.lastX, dy: y - this.lastY});
 			this.lastX = x;
 			this.lastY = y;
-			evt.stop(e);
+			event.stop(e);
 		},
 		// utilities
 		onFirstMove: function(){
-			// summary: it is meant to be called only once
+			// summary:
+			//		it is meant to be called only once
 			this.host.onFirstMove(this);
-			connect.disconnect(this.events.pop());
+			this.events.pop().remove();
 		},
 		destroy: function(){
-			// summary: stops the move, deletes all references, so the object can be garbage-collected
-			arr.forEach(this.events, connect.disconnect);
+			// summary:
+			//		stops the move, deletes all references, so the object can be garbage-collected
+			arr.forEach(this.events, function(handle){
+				handle.remove();
+			});
 			// undo global settings
 			var h = this.host;
 			if(h && h.onMoveStop){
diff --git a/dojox/gfx/VectorText.js b/dojox/gfx/VectorText.js
index 42098b0..bd9bbb6 100644
--- a/dojox/gfx/VectorText.js
+++ b/dojox/gfx/VectorText.js
@@ -1,37 +1,6 @@
 define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/loader" /* dojo._getText */,
 	    "dojo/_base/xhr","./_base", "dojox/xml/DomParser", "dojox/html/metrics","./matrix"],
-  function (lang,declare,arr,loader,xhr,gfx,xmlDomParser,HtmlMetrics,Matrix){
-/*===== 
- 	gfx = dojox.gfx;
- 	dojox.gfx.VectorText = {
-		// summary:
-		//		An implementation of the SVG Font 1.1 spec, using dojox.gfx.
-		//
-		// Basic interface:
-		// var f = new dojox.gfx.Font(url|string);
-		// surface||group.createVectorText(text)
-		//	.setFill(fill)
-		//	.setStroke(stroke)
-		//	.setFont(fontStyleObject);
-		//
-		// The arguments passed to createVectorText are the same as you would
-		// pass to surface||group.createText; the difference is that this
-		// is entirely renderer-agnostic, and the return value is a subclass
-		// of dojox.gfx.Group.
-		//
-		// Note also that the "defaultText" object is slightly different:
-		// { type:"vectortext", x:0, y:0, width:null, height: null,
-		//	text: "", align: "start", decoration: "none" }
-		//
-		// ...as well as the "defaultVectorFont" object:
-		// { type:"vectorfont", size:"10pt" }
-		//
-		// The reason for this should be obvious: most of the style for the font is defined
-		// by the font object itself.
-		//
-		// Note that this will only render IF and WHEN you set the font.
-	};
- =====*/ 
+function (lang,declare,arr,loader,xhr,gfx,xmlDomParser,HtmlMetrics,Matrix){
 	var _getText = function(url){
 		var result;
 		xhr.get({url:url, sync:true, load:function(text){ // Note synchronous!
@@ -39,44 +8,74 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 		}});
 		return result;
 	};
-	 
-	lang.getObject("dojox.gfx.VectorText", true);
-	lang.mixin(gfx, {
-		vectorFontFitting: {
-			NONE: 0,	//	render text according to passed size.
-			FLOW: 1,		//	render text based on the passed width and size
-			FIT: 2			//	render text based on a passed viewbox.
-		},
-		defaultVectorText: {
-			type:"vectortext", x:0, y:0, width: null, height: null,
-			text: "", align: "start", decoration: "none", fitting: 0,	//	vectorFontFitting.NONE
-			leading: 1.5	//	in ems.
-		},
-		defaultVectorFont: {
-			type:"vectorfont", size: "10pt", family: null
-		},
-		_vectorFontCache: {},
-		_svgFontCache: {},
-		getVectorFont: function(/* String */url){
-			if(gfx._vectorFontCache[url]){
-				return gfx._vectorFontCache[url];
-			}
-			return new gfx.VectorFont(url);
-		}
-	});
 
-	return declare("dojox.gfx.VectorFont", null, {  // EARLY RETURN
+	 lang.getObject("dojox.gfx.VectorText", true);
+
+	 lang.mixin(gfx, {
+		  vectorFontFitting: {
+			  NONE: 0,	//		render text according to passed size.
+			  FLOW: 1,		//		render text based on the passed width and size
+			  FIT: 2			//		render text based on a passed viewbox.
+		  },
+		  defaultVectorText: {
+			  type:"vectortext", x:0, y:0, width: null, height: null,
+			  text: "", align: "start", decoration: "none", fitting: 0,	//		vectorFontFitting.NONE
+			  leading: 1.5	//		in ems.
+		  },
+		  defaultVectorFont: {
+			  type:"vectorfont", size: "10pt", family: null
+		  },
+		  _vectorFontCache: {},
+		  _svgFontCache: {},
+		  getVectorFont: function(/* String */url){
+			  if(gfx._vectorFontCache[url]){
+				  return gfx._vectorFontCache[url];
+			  }
+			  return new gfx.VectorFont(url);
+		  }
+	 });
+
+	// TODO: Make up your mind.   Module is called VectorText but it's creating and returning a global called VectorFont
+
+	return declare("dojox.gfx.VectorFont", null, {
+		// summary:
+		//		An implementation of the SVG Font 1.1 spec, using dojox/gfx.
+		//
+		//		Basic interface:
+		//	|	var f = new gfx.Font(url|string);
+		//	|	surface||group.createVectorText(text)
+		//	|	.setFill(fill)
+		//	|	.setStroke(stroke)
+		//	|	.setFont(fontStyleObject);
+		//
+		//		The arguments passed to createVectorText are the same as you would
+		//		pass to surface||group.createText; the difference is that this
+		//		is entirely renderer-agnostic, and the return value is a subclass
+		//		of dojox/gfx.Group.
+		//
+		//		Note also that the "defaultText" object is slightly different:
+		//		{ type:"vectortext", x:0, y:0, width:null, height: null,
+		//		text: "", align: "start", decoration: "none" }
+		//
+		//		...as well as the "defaultVectorFont" object:
+		//		{ type:"vectorfont", size:"10pt" }
+		//
+		//		The reason for this should be obvious: most of the style for the font is defined
+		//		by the font object itself.
+		//
+		//		Note that this will only render IF and WHEN you set the font.
+
 		_entityRe: /&(quot|apos|lt|gt|amp|#x[^;]+|#\d+);/g,
 		_decodeEntitySequence: function(str){
-			//	unescape the unicode sequences
+			//		unescape the unicode sequences
 
-			//	nothing to decode
+			//		nothing to decode
 			if(!str.match(this._entityRe)){ return; }  // undefined
 			var xmlEntityMap = {
 				amp:"&", apos:"'", quot:'"', lt:"<", gt:">"
 			};
 
-			//	we have at least one encoded entity.
+			//		we have at least one encoded entity.
 			var r, tmp="";
 			while((r=this._entityRe.exec(str))!==null){
 				if(r[1].charAt(1)=="x"){
@@ -89,16 +88,16 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 					tmp += xmlEntityMap[r[1]] || "";
 				}
 			}
-			return tmp;	//	String
+			return tmp;	//		String
 		},
 		_parse: function(/* String */svg, /* String */url){
-			//	summary:
+			// summary:
 			//		Take the loaded SVG Font definition file and convert the info
 			//		into things we can use. The SVG Font definition must follow
 			//		the SVG 1.1 Font specification.
 			var doc = gfx._svgFontCache[url]||xmlDomParser.parse(svg);
 
-			//	font information
+			//		font information
 			var f = doc.documentElement.byName("font")[0], face = doc.documentElement.byName("font-face")[0];
 			var unitsPerEm = parseFloat(face.getAttribute("units-per-em")||1000, 10);
 			var advance = {
@@ -120,14 +119,14 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 				}
 			};
 
-			//	face information
+			//		face information
 			var family = face.getAttribute("font-family"),
 				style = face.getAttribute("font-style")||"all",
 				variant = face.getAttribute("font-variant")||"normal",
 				weight = face.getAttribute("font-weight")||"all",
 				stretch = face.getAttribute("font-stretch")||"normal",
 
-				//	additional info, may not be needed
+				//		additional info, may not be needed
 				range = face.getAttribute("unicode-range")||"U+0-10FFFF",
 				panose = face.getAttribute("panose-1") || "0 0 0 0 0 0 0 0 0 0",
 				capHeight = face.getAttribute("cap-height"),
@@ -135,16 +134,16 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 				descent = parseFloat(face.getAttribute("descent")||origin.vert.y, 10),
 				baseline = {};
 
-			//	check for font-face-src/font-face-name
+			//		check for font-face-src/font-face-name
 			var name = family;
 			if(face.byName("font-face-name")[0]){
 				name = face.byName("font-face-name")[0].getAttribute("name");
 			}
 
-			//	see if this is cached already, and if so, forget the rest of the parsing.
+			//		see if this is cached already, and if so, forget the rest of the parsing.
 			if(gfx._vectorFontCache[name]){ return; }
 
-			//	get any provided baseline alignment offsets.
+			//		get any provided baseline alignment offsets.
 			arr.forEach(["alphabetic", "ideographic", "mathematical", "hanging" ], function(attr){
 				var a = face.getAttribute(attr);
 				if(a !== null /* be explicit, might be 0 */){
@@ -153,7 +152,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 			});
 
 		/*
-			//	TODO: decoration hinting.
+			//		TODO: decoration hinting.
 			var decoration = { };
 			arr.forEach(["underline", "strikethrough", "overline"], function(type){
 				if(face.getAttribute(type+"-position")!=null){
@@ -162,13 +161,13 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 			});
 		*/
 
-			//	missing glyph info
+			//		missing glyph info
 			var missing = parseFloat(doc.documentElement.byName("missing-glyph")[0].getAttribute("horiz-adv-x")||advance.x, 10);
 
-			//	glyph information
+			//		glyph information
 			var glyphs = {}, glyphsByName={}, g=doc.documentElement.byName("glyph");
 			arr.forEach(g, function(node){
-				//	we are going to assume the following:
+				//		we are going to assume the following:
 				//		1) we have the unicode attribute
 				//		2) we have the name attribute
 				//		3) we have the horiz-adv-x and d attributes.
@@ -177,7 +176,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 					xAdv = parseFloat(node.getAttribute("horiz-adv-x")||advance.x, 10),
 					path = node.getAttribute("d");
 
-				//	unescape the unicode sequences
+				//		unescape the unicode sequences
 				if(code.match(this._entityRe)){
 					code = this._decodeEntitySequence(code);
 				}
@@ -188,11 +187,11 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 				glyphsByName[name]=o;
 			}, this);
 
-			//	now the fun part: look for kerning pairs.
+			//		now the fun part: look for kerning pairs.
 			var hkern=doc.documentElement.byName("hkern");
 			arr.forEach(hkern, function(node, i){
 				var k = -parseInt(node.getAttribute("k"),10);
-				//	look for either a code or a name
+				//		look for either a code or a name
 				var u1=node.getAttribute("u1"),
 					g1=node.getAttribute("g1"),
 					u2=node.getAttribute("u2"),
@@ -200,15 +199,15 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 					gl;
 
 				if(u1){
-					//	the first of the pair is a sequence of unicode characters.
-					//	TODO: deal with unicode ranges and mulitple characters.
+					//		the first of the pair is a sequence of unicode characters.
+					//		TODO: deal with unicode ranges and mulitple characters.
 					u1 = this._decodeEntitySequence(u1);
 					if(glyphs[u1]){
 						gl = glyphs[u1];
 					}
 				} else {
-					//	we are referring to a name.
-					//	TODO: deal with multiple names
+					//		we are referring to a name.
+					//		TODO: deal with multiple names
 					if(glyphsByName[g1]){
 						gl = glyphsByName[g1];
 					}
@@ -217,7 +216,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 				if(gl){
 					if(!gl.kern){ gl.kern = {}; }
 					if(u2){
-						//	see the notes above.
+						//		see the notes above.
 						u2 = this._decodeEntitySequence(u2);
 						gl.kern[u2] = { x: k };
 					} else {
@@ -228,7 +227,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 				}
 			}, this);
 
-			//	pop the final definition in the font cache.
+			//		pop the final definition in the font cache.
 			lang.mixin(this, {
 				family: family,
 				name: name,
@@ -248,20 +247,20 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 				glyphs: glyphs
 			});
 
-			//	cache the parsed font
+			//		cache the parsed font
 			gfx._vectorFontCache[name] = this;
 			gfx._vectorFontCache[url] = this;
 			if(name!=family && !gfx._vectorFontCache[family]){
 				gfx._vectorFontCache[family] = this;
 			}
 
-			//	cache the doc
+			//		cache the doc
 			if(!gfx._svgFontCache[url]){
 				gfx._svgFontCache[url]=doc;
 			}
 		},
 		_clean: function(){
-			//	summary:
+			// summary:
 			//		Clean off all of the given mixin parameters.
 			var name = this.name, family = this.family;
 			arr.forEach(["family","name","style","variant",
@@ -271,7 +270,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 					try{ delete this[prop]; } catch(e) { }
 			}, this);
 
-			//	try to pull out of the font cache.
+			//		try to pull out of the font cache.
 			if(gfx._vectorFontCache[name]){
 				delete gfx._vectorFontCache[name];
 			}
@@ -282,31 +281,35 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 		},
 
 		constructor: function(/* String|dojo._Url */url){
-			//	summary::
+			// summary:
 			//		Create this font object based on the SVG Font definition at url.
+			// url:
+			//		An url pointing to the SVG Font definition.
 			this._defaultLeading = 1.5;
 			if(url!==undefined){
 				this.load(url);
 			}
 		},
 		load: function(/* String|dojo._Url */url){
-			//	summary::
+			// summary:
 			//		Load the passed SVG and send it to the parser for parsing.
+			// url:
+			//		The svg to parse.
 			this.onLoadBegin(url.toString());
 			this._parse(
 				gfx._svgFontCache[url.toString()]||_getText(url.toString()),
 				url.toString()
 			);
 			this.onLoad(this);
-			return this;	//	dojox.gfx.VectorFont
+			return this;	//		dojox/gfx.VectorFont
 		},
 		initialized: function(){
-			//	summary::
+			// summary:
 			//		Return if we've loaded a font def, and the parsing was successful.
-			return (this.glyphs!==null);	//	Boolean
+			return (this.glyphs!==null);	//		Boolean
 		},
 
-		//	preset round to 3 places.
+		//		preset round to 3 places.
 		_round: function(n){ return Math.round(1000*n)/1000; },
 		_leading: function(unit){ return this.viewbox.height * (unit||this._defaultLeading); },
 		_normalize: function(str){
@@ -324,7 +327,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 				lastGlyph = glyph;
 			});
 
-			//	if the last glyph was a space, pull it off.
+			//		if the last glyph was a space, pull it off.
 			if(lastGlyph && lastGlyph.code == " "){
 				w -= lastGlyph.xAdvance;
 			}
@@ -346,7 +349,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 
 		_trim: function(lines){
 			var fn = function(arr){
-				//	check if the first or last character is a space and if so, remove it.
+				//		check if the first or last character is a space and if so, remove it.
 				if(!arr.length){ return; }
 				if(arr[arr.length-1].code == " "){ arr.splice(arr.length-1, 1); }
 				if(!arr.length){ return; }
@@ -354,7 +357,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 			};
 
 			if(lang.isArray(lines[0])){
-				//	more than one line.
+				//		more than one line.
 				arr.forEach(lines, fn);
 			} else {
 				fn(lines);
@@ -363,7 +366,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 		},
 
 		_split: function(chars, nLines){
-			//	summary:
+			// summary:
 			//		split passed chars into nLines by finding the closest whitespace.
 			var w = this._getWidth(chars),
 				limit = Math.floor(w/nLines),
@@ -392,18 +395,18 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 				c.push(chars[i]);
 			}
 			if(c.length){ lines.push(c); }
-			//	"trim" it
+			//		"trim" it
 			return this._trim(lines);
 		},
 
 		_getSizeFactor: function(size){
-			//	given the size, return a scaling factor based on the height of the
-			//	font as defined in the font definition file.
-			size += "";	//	force the string cast.
+			//		given the size, return a scaling factor based on the height of the
+			//		font as defined in the font definition file.
+			size += "";	//		force the string cast.
 			var metrics = HtmlMetrics.getCachedFontMeasurements(),
 				height=this.viewbox.height,
 				f=metrics["1em"],
-				unit=parseFloat(size, 10);	//	the default.
+				unit=parseFloat(size, 10);	//		the default.
 			if(size.indexOf("em")>-1){
 				return this._round((metrics["1em"]*unit)/height);
 			}
@@ -426,10 +429,10 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 		},
 
 		_getFitFactor: function(lines, w, h, l){
-			//	summary:
+			// summary:
 			//		Find the scaling factor for the given phrase set.
 			if(!h){
-				//	if no height was passed, we assume an array of glyphs instead of lines.
+				//		if no height was passed, we assume an array of glyphs instead of lines.
 				return this._round(w/this._getWidth(lines));
 			} else {
 				var maxw = this._getLongestLine(lines).width,
@@ -438,7 +441,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 			}
 		},
 		_getBestFit: function(chars, w, h, ldng){
-			//	summary:
+			// summary:
 			//		Get the best number of lines to return given w and h.
 			var limit=32,
 				factor=0,
@@ -455,7 +458,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 		},
 
 		_getBestFlow: function(chars, w, scale){
-			//	summary:
+			// summary:
 			//		Based on the given scale, do the best line splitting possible.
 			var lines = [],
 				cw = 0,
@@ -485,41 +488,55 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 			return this._trim(lines);
 		},
 
-		//	public functions
+		//		public functions
 		getWidth: function(/* String */text, /* Float? */scale){
-			//	summary:
+			// summary:
 			//		Get the width of the rendered text without actually rendering it.
+			// text:
+			//		The string to measure.
+			// scale:
+			//		an optional scaling factor.
 			return this._getWidth(arr.map(this._normalize(text).split(""), function(chr){
 				return this.glyphs[chr] || { xAdvance: this.advance.missing.x };
-			}, this)) * (scale || 1);	//	Float
+			}, this)) * (scale || 1);	//		Float
 		},
 		getLineHeight: function(/* Float? */scale){
-			//	summary:
+			// summary:
 			//		return the height of a single line, sans leading, based on scale.
-			return this.viewbox.height * (scale || 1);	//	Float
+			// scale:
+			//		an optional scaling factor.
+			return this.viewbox.height * (scale || 1);	//		Float
 		},
 
-		//	A note:
+		//		A note:
 		//		Many SVG exports do not include information such as x-height, caps-height
 		//		and other coords that may help alignment.  We can calc the baseline and
 		//		we can get a mean line (i.e. center alignment) but that's about all, reliably.
 		getCenterline: function(/* Float? */scale){
-			//	summary:
+			// summary:
 			//		return the y coordinate that is the center of the viewbox.
+			// scale:
+			//		an optional scaling factor.
 			return (scale||1) * (this.viewbox.height/2);
 		},
 		getBaseline: function(/* Float? */scale){
-			//	summary:
+			// summary:
 			//		Find the baseline coord for alignment; adjust for scale if passed.
-			return (scale||1) * (this.viewbox.height+this.descent);	//	Float
+			// scale:
+			//		an optional scaling factor.
+			return (scale||1) * (this.viewbox.height+this.descent);	//		Float
 		},
 
-		draw: function(/* dojox.gfx.Container */group, /* dojox.gfx.__TextArgs */textArgs, /* dojox.gfx.__FontArgs */fontArgs, /* dojox.gfx.__FillArgs */fillArgs, /* dojox.gfx.__StrokeArgs? */strokeArgs){
-			//	summary:
+		draw: function(
+				/* dojox/gfx.Container */group,
+				/* dojox/gfx.Text */ textArgs,
+				/* dojox/gfx.Font */fontArgs,
+				/* dojox/gfx.Fill */fillArgs,
+				/* dojox/gfx.Stroke */strokeArgs){
+			// summary:
 			//		based on the passed parameters, draw the given text using paths
 			//		defined by this font.
-			//
-			//	description:
+			// description:
 			//		The main method of a VectorFont, draw() will take a text fragment
 			//		and render it in a set of groups and paths based on the parameters
 			//		passed.
@@ -535,12 +552,11 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 			//		Resulting GFX structure
 			//		-----------------------
 			//
-			//		The result of this function is a set of gfx objects in the following
-			//		structure:
+			//		The result of this function is a set of gfx objects in the following structure:
 			//
-			//	|	dojox.gfx.Group 			//	the parent group generated by this function
-			//	|	+	dojox.gfx.Group[]		//	a group generated for each line of text
-			//	|		+	dojox.gfx.Path[]	//	each glyph/character in the text
+			//	|	gfx.Group 			//		the parent group generated by this function
+			//	|	+	gfx.Group[]		//		a group generated for each line of text
+			//	|		+	gfx.Path[]	//		each glyph/character in the text
 			//
 			//		Scaling transformations (i.e. making the generated text the correct size)
 			//		are always applied to the parent Group that is generated (i.e. the top
@@ -551,8 +567,8 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 			//		you will need to reapply the scaling transformation as the *last* transform,
 			//		like so:
 			//
-			//	|	textGroup.setTransform(new dojox.gfx.Matrix2D([
-			//	|		dojox.gfx.matrix.translate({ dx: dx, dy: dy }),
+			//	|	textGroup.setTransform(new matrix.Matrix2D([
+			//	|		matrix.translate({ dx: dx, dy: dy }),
 			//	|		textGroup.getTransform()
 			//	|	]));
 			//
@@ -565,11 +581,11 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 			//		In addition to straight text fragments, draw() supports a few advanced
 			//		operations not normally available with vector graphics:
 			//
-			//		* Flow operations (i.e. wrap to a given width)
-			//		* Fitting operations (i.e. find a best fit to a given rectangle)
+			//		- Flow operations (i.e. wrap to a given width)
+			//		- Fitting operations (i.e. find a best fit to a given rectangle)
 			//
 			//		To enable either, pass a `fitting` property along with the textArgs object.
-			//		The possible values are contained in the dojox.gfx.vectorFontFitting enum
+			//		The possible values are contained in the dojox/gfx.vectorFontFitting enum
 			//		(NONE, FLOW, FIT).
 			//
 			//		`Flow fitting`
@@ -597,27 +613,28 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 			//		Always make sure that you are legally allowed to use any fonts that you
 			//		convert to SVG format; we claim no responsibility for any licensing
 			//		infractions that may be caused by the use of this code.
+			// returns: dojox/gfx.Group
 			if(!this.initialized()){
 				throw new Error("dojox.gfx.VectorFont.draw(): we have not been initialized yet.");
 			}
-			//	TODO: BIDI handling.  Deal with layout/alignments based on font parameters.
+			//		TODO: BIDI handling.  Deal with layout/alignments based on font parameters.
 
-			//	start by creating the overall group.  This is the INNER group (the caller
-			//	should be the outer).
+			//		start by creating the overall group.  This is the INNER group (the caller
+			//		should be the outer).
 			var g = group.createGroup();
 
-			//	do the x/y translation on the parent group
-			//	FIXME: this is probably not the best way of doing this.
+			//		do the x/y translation on the parent group
+			//		FIXME: this is probably not the best way of doing this.
 			if(textArgs.x || textArgs.y){
 				group.applyTransform({ dx: textArgs.x||0, dy: textArgs.y||0 });
 			}
 
-			//	go get the glyph array.
+			//		go get the glyph array.
 			var text = arr.map(this._normalize(textArgs.text).split(""), function(chr){
 				return this.glyphs[chr] || { path:null, xAdvance: this.advance.missing.x };
 			}, this);
 
-			//	determine the font style info, ignore decoration.
+			//		determine the font style info, ignore decoration.
 			var size = fontArgs.size,
 				fitting = textArgs.fitting,
 				width = textArgs.width,
@@ -625,16 +642,16 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 				align = textArgs.align,
 				leading = textArgs.leading||this._defaultLeading;
 
-			//	figure out if we have to do fitting at all.
+			//		figure out if we have to do fitting at all.
 			if(fitting){
-				//	more than zero.
+				//		more than zero.
 				if((fitting==gfx.vectorFontFitting.FLOW && !width) || (fitting==gfx.vectorFontFitting.FIT && (!width || !height))){
-					//	reset the fitting if we don't have everything we need.
+					//		reset the fitting if we don't have everything we need.
 					fitting = gfx.vectorFontFitting.NONE;
 				}
 			}
 
-			//	set up the lines array and the scaling factor.
+			//		set up the lines array and the scaling factor.
 			var lines, scale;
 			switch(fitting){
 				case gfx.vectorFontFitting.FIT:
@@ -654,12 +671,12 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 
 			}
 
-			//	make sure lines doesn't have any empty lines.
+			//		make sure lines doesn't have any empty lines.
 			lines = arr.filter(lines, function(item){
 				return item.length>0;
 			});
 
-			//	let's start drawing.
+			//		let's start drawing.
 			var cy = 0,
 				maxw = this._getLongestLine(lines).width;
 
@@ -669,7 +686,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 					linew = this._getWidth(line),
 					lg=g.createGroup();
 
-				//	loop through the glyphs and add them to the line group (lg)
+				//		loop through the glyphs and add them to the line group (lg)
 				for (var j=0; j<line.length; j++){
 					var glyph=line[j];
 					if(glyph.path!==null){
@@ -686,7 +703,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 					}
 				}
 
-				//	transform the line group.
+				//		transform the line group.
 				var dx = 0;
 				if(align=="middle"){ dx = maxw/2 - linew/2; }
 				else if(align=="end"){ dx = maxw - linew; }
@@ -694,44 +711,44 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 				cy += this.viewbox.height * leading;
 			}
 
-			//	scale the group
+			//		scale the group
 			g.setTransform(Matrix.scale(scale));
 
-			//	return the overall group
-			return g;	//	dojox.gfx.Group
+			//		return the overall group
+			return g;	//		dojox/gfx.Group
 		},
 
-		//	events
+		//		events
 		onLoadBegin: function(/* String */url){ },
-		onLoad: function(/* dojox.gfx.VectorFont */font){ }
+		onLoad: function(/* dojox/gfx/VectorText */font){ }
 	});
 
-	//	TODO: dojox.gfx integration
+	//		TODO: dojox/gfx integration
 /*
 
-	//	Inherit from Group but attach Text properties to it.
+	//		Inherit from Group but attach Text properties to it.
 	dojo.declare("dojox.gfx.VectorText", dojox.gfx.Group, {
 		constructor: function(rawNode){
 			dojox.gfx.Group._init.call(this);
 			this.fontStyle = null;
 		},
 
-		//	private methods.
+		//		private methods.
 		_setFont: function(){
-			//	render this using the font code.
+			//		render this using the font code.
 			var f = this.fontStyle;
 			var font = dojox.gfx._vectorFontCache[f.family];
 			if(!font){
 				throw new Error("dojox.gfx.VectorText._setFont: the passed font family '" + f.family + "' was not found.");
 			}
 
-			//	the actual rendering belongs to the font itself.
+			//		the actual rendering belongs to the font itself.
 			font.draw(this, this.shape, this.fontStyle, this.fillStyle, this.strokeStyle);
 		},
 
 		getFont: function(){ return this.fontStyle; },
 
-		//	overridden public methods.
+		//		overridden public methods.
 		setShape: function(newShape){
 			dojox.gfx.Group.setShape.call(this);
 			this.shape = dojox.gfx.makeParameters(this.shape, newShape);
@@ -740,7 +757,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 			return this;
 		},
 
-		//	if we've been drawing, we should have exactly one child, and that
+		//		if we've been drawing, we should have exactly one child, and that
 		//		child will contain the real children.
 		setFill: function(fill){
 			this.fillStyle = fill;
@@ -766,7 +783,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 		},
 
 		setFont: function(newFont){
-			//	this will do the real rendering.
+			//		this will do the real rendering.
 			this.fontStyle = typeof newFont == "string" ? dojox.gfx.splitFontString(newFont)
 				: dojox.gfx.makeParameters(dojox.gfx.defaultFont, newFont);
 			this._setFont();
@@ -778,7 +795,7 @@ define(["dojo/_base/lang","dojo/_base/declare","dojo/_base/array", "dojo/_base/l
 		}
 	});
 
-	//	TODO: figure out how to add this to container objects!
+	//		TODO: figure out how to add this to container objects!
 	dojox.gfx.shape.Creator.createVectorText = function(text){
 		return this.createObject(dojox.gfx.VectorText, text);
 	}
diff --git a/dojox/gfx/_base.js b/dojox/gfx/_base.js
index dc9cfa4..1e46626 100644
--- a/dojox/gfx/_base.js
+++ b/dojox/gfx/_base.js
@@ -1,25 +1,26 @@
-define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sniff", "dojo/_base/window",
-	    "dojo/_base/array","dojo/dom", "dojo/dom-construct","dojo/dom-geometry"], 
-  function(lang, html, Color, has, win, arr, dom, domConstruct, domGeom){
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/Color", "dojo/_base/sniff", "dojo/_base/window",
+	    "dojo/_base/array","dojo/dom", "dojo/dom-construct","dojo/dom-geometry"],
+function(kernel, lang, Color, has, win, arr, dom, domConstruct, domGeom){
 	// module:
 	//		dojox/gfx
 	// summary:
 	//		This module contains common core Graphics API used by different graphics renderers.
+
 	var g = lang.getObject("dojox.gfx", true),
 		b = g._base = {};
-	/*===== g = dojox.gfx; b = dojox.gfx._base; =====*/
 	
 	// candidates for dojox.style (work on VML and SVG nodes)
 	g._hasClass = function(/*DomNode*/node, /*String*/classStr){
-		//	summary:
+		// summary:
 		//		Returns whether or not the specified classes are a portion of the
 		//		class list currently applied to the node.
+		
 		// return (new RegExp('(^|\\s+)'+classStr+'(\\s+|$)')).test(node.className)	// Boolean
 		var cls = node.getAttribute("className");
 		return cls && (" " + cls + " ").indexOf(" " + classStr + " ") >= 0;  // Boolean
 	};
 	g._addClass = function(/*DomNode*/node, /*String*/classStr){
-		//	summary:
+		// summary:
 		//		Adds the specified classes to the end of the class list on the
 		//		passed node.
 		var cls = node.getAttribute("className") || "";
@@ -28,7 +29,8 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 		}
 	};
 	g._removeClass = function(/*DomNode*/node, /*String*/classStr){
-		//	summary: Removes classes from node.
+		// summary:
+		//		Removes classes from node.
 		var cls = node.getAttribute("className");
 		if(cls){
 			node.setAttribute(
@@ -40,9 +42,9 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 
 	// candidate for dojox.html.metrics (dynamic font resize handler is not implemented here)
 
-	//	derived from Morris John's emResized measurer
+	//		derived from Morris John's emResized measurer
 	b._getFontMeasurements = function(){
-		//	summary:
+		// summary:
 		//		Returns an object that has pixel equivilents of standard font
 		//		size values.
 		var heights = {
@@ -53,12 +55,12 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 		var p;
 
 		if(has("ie")){
-			//	we do a font-size fix if and only if one isn't applied already.
-			//	NOTE: If someone set the fontSize on the HTML Element, this will kill it.
+			//		we do a font-size fix if and only if one isn't applied already.
+			// NOTE: If someone set the fontSize on the HTML Element, this will kill it.
 			win.doc.documentElement.style.fontSize="100%";
 		}
 
-		//	set up the measuring node.
+		//		set up the measuring node.
 		var div = domConstruct.create("div", {style: {
 				position: "absolute",
 				left: "0",
@@ -73,7 +75,7 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 				overflow: "hidden"
 			}}, win.body());
 
-		//	do the measurements.
+		//		do the measurements.
 		for(p in heights){
 			div.style.fontSize = p;
 			heights[p] = Math.round(div.offsetHeight * 12/16) * 16/12 / 1000;
@@ -137,314 +139,624 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 		}
 	};
 
+	b._computeTextLocation = function(/*g.defaultTextShape*/textShape, /*Number*/width, /*Number*/height, /*Boolean*/fixHeight) {
+		var loc = {}, align = textShape.align;
+		switch (align) {
+			case 'end':
+				loc.x = textShape.x - width;
+				break;
+			case 'middle':
+				loc.x = textShape.x - width / 2;
+				break;
+			default:
+				loc.x = textShape.x;
+				break;
+		}
+		var c = fixHeight ? 0.75 : 1;
+		loc.y = textShape.y - height*c; // **rough** approximation of the ascent...
+		return loc;
+	};
+	b._computeTextBoundingBox = function(/*shape.Text*/s){
+		// summary:
+		//		Compute the bbox of the given shape.Text instance. Note that this method returns an
+		//		approximation of the bbox, and should be used when the underlying renderer cannot provide precise metrics.
+		if(!g._base._isRendered(s)){
+			return {x:0, y:0, width:0, height:0};
+		}
+		var loc, textShape = s.getShape(),
+			font = s.getFont() || g.defaultFont,
+			w = s.getTextWidth(),
+			h = g.normalizedLength(font.size);
+		loc = b._computeTextLocation(textShape, w, h, true);
+		return {
+			x: loc.x,
+			y: loc.y,
+			width: w,
+			height: h
+		};
+	};
+	b._isRendered = function(/*Shape*/s){
+		var p = s.parent;
+		while(p && p.getParent){
+			p = p.parent;
+		}
+		return p !== null;
+	};
+
 	// candidate for dojo.dom
 
 	var uniqueId = 0;
 	b._getUniqueId = function(){
-		// summary: returns a unique string for use with any DOM element
+		// summary:
+		//		returns a unique string for use with any DOM element
 		var id;
 		do{
-			id = dojo._scopeName + "xUnique" + (++uniqueId);
+			id = kernel._scopeName + "xUnique" + (++uniqueId);
 		}while(dom.byId(id));
 		return id;
 	};
 
-	lang.mixin(g, {
+	// IE10
+
+	b._fixMsTouchAction = function(/*dojox/gfx/shape.Surface*/surface){
+		var r = surface.rawNode;
+		if (typeof r.style.msTouchAction != 'undefined')
+			r.style.msTouchAction = "none";
+	};
+
+	/*=====
+	g.Stroke = {
+		// summary:
+		//		A stroke defines stylistic properties that are used when drawing a path.
+
+		// color: String
+		//		The color of the stroke, default value 'black'.
+		color: "black",
+
+		// style: String
+		//		The style of the stroke, one of 'solid', ... . Default value 'solid'.
+		style: "solid",
+
+		// width: Number
+		//		The width of a stroke, default value 1.
+		width: 1,
+
+		// cap: String
+		//		The endcap style of the path. One of 'butt', 'round', ... . Default value 'butt'.
+		cap: "butt",
+
+		// join: Number
+		//		The join style to use when combining path segments. Default value 4.
+		join: 4
+	};
+	
+	g.Fill = {
+		// summary:
+		//		Defines how to fill a shape. Four types of fills can be used: solid, linear gradient, radial gradient and pattern.
+		//		See dojox/gfx.LinearGradient, dojox/gfx.RadialGradient and dojox/gfx.Pattern respectively for more information about the properties supported by each type.
+		
+		// type: String?
+		//		The type of fill. One of 'linear', 'radial', 'pattern' or undefined. If not specified, a solid fill is assumed.
+		type:"",
+		
+		// color: String|dojo/Color?
+		//		The color of a solid fill type.
+		color:null,
+		
+	};
+	
+	g.LinearGradient = {
+		// summary:
+		//		An object defining the default stylistic properties used for Linear Gradient fills.
+		//		Linear gradients are drawn along a virtual line, which results in appearance of a rotated pattern in a given direction/orientation.
+
+		// type: String
+		//		Specifies this object is a Linear Gradient, value 'linear'
+		type: "linear",
+
+		// x1: Number
+		//		The X coordinate of the start of the virtual line along which the gradient is drawn, default value 0.
+		x1: 0,
+
+		// y1: Number
+		//		The Y coordinate of the start of the virtual line along which the gradient is drawn, default value 0.
+		y1: 0,
+
+		// x2: Number
+		//		The X coordinate of the end of the virtual line along which the gradient is drawn, default value 100.
+		x2: 100,
+
+		// y2: Number
+		//		The Y coordinate of the end of the virtual line along which the gradient is drawn, default value 100.
+		y2: 100,
+
+		// colors: Array
+		//		An array of colors at given offsets (from the start of the line).  The start of the line is
+		//		defined at offest 0 with the end of the line at offset 1.
+		//		Default value, [{ offset: 0, color: 'black'},{offset: 1, color: 'white'}], is a gradient from black to white.
+		colors: []
+	};
+	
+	g.RadialGradient = {
+		// summary:
+		//		Specifies the properties for RadialGradients using in fills patterns.
+
+		// type: String
+		//		Specifies this is a RadialGradient, value 'radial'
+		type: "radial",
+
+		// cx: Number
+		//		The X coordinate of the center of the radial gradient, default value 0.
+		cx: 0,
+
+		// cy: Number
+		//		The Y coordinate of the center of the radial gradient, default value 0.
+		cy: 0,
+
+		// r: Number
+		//		The radius to the end of the radial gradient, default value 100.
+		r: 100,
+
+		// colors: Array
+		//		An array of colors at given offsets (from the center of the radial gradient).
+		//		The center is defined at offest 0 with the outer edge of the gradient at offset 1.
+		//		Default value, [{ offset: 0, color: 'black'},{offset: 1, color: 'white'}], is a gradient from black to white.
+		colors: []
+	};
+	
+	g.Pattern = {
+		// summary:
+		//		An object specifying the default properties for a Pattern using in fill operations.
+
+		// type: String
+		//		Specifies this object is a Pattern, value 'pattern'.
+		type: "pattern",
+
+		// x: Number
+		//		The X coordinate of the position of the pattern, default value is 0.
+		x: 0,
+
+		// y: Number
+		//		The Y coordinate of the position of the pattern, default value is 0.
+		y: 0,
+
+		// width: Number
+		//		The width of the pattern image, default value is 0.
+		width: 0,
+
+		// height: Number
+		//		The height of the pattern image, default value is 0.
+		height: 0,
+
+		// src: String
+		//		A url specifying the image to use for the pattern.
+		src: ""
+	};
+
+	g.Text = {
 		//	summary:
+		//		A keyword argument object defining both the text to be rendered in a VectorText shape,
+		//		and specifying position, alignment, and fitting.
+		//	text: String
+		//		The text to be rendered.
+		//	x: Number?
+		//		The left coordinate for the text's bounding box.
+		//	y: Number?
+		//		The top coordinate for the text's bounding box.
+		//	width: Number?
+		//		The width of the text's bounding box.
+		//	height: Number?
+		//		The height of the text's bounding box.
+		//	align: String?
+		//		The alignment of the text, as defined in SVG. Can be "start", "end" or "middle".
+		//	fitting: Number?
+		//		How the text is to be fitted to the bounding box. Can be 0 (no fitting), 1 (fitting based on
+		//		passed width of the bounding box and the size of the font), or 2 (fit text to the bounding box,
+		//		and ignore any size parameters).
+		//	leading: Number?
+		//		The leading to be used between lines in the text.
+		//	decoration: String?
+		//		Any text decoration to be used.
+	};
+
+	g.Font = {
+		// summary:
+		//		An object specifying the properties for a Font used in text operations.
+	
+		// type: String
+		//		Specifies this object is a Font, value 'font'.
+		type: "font",
+	
+		// style: String
+		//		The font style, one of 'normal', 'bold', default value 'normal'.
+		style: "normal",
+	
+		// variant: String
+		//		The font variant, one of 'normal', ... , default value 'normal'.
+		variant: "normal",
+	
+		// weight: String
+		//		The font weight, one of 'normal', ..., default value 'normal'.
+		weight: "normal",
+	
+		// size: String
+		//		The font size (including units), default value '10pt'.
+		size: "10pt",
+	
+		// family: String
+		//		The font family, one of 'serif', 'sanserif', ..., default value 'serif'.
+		family: "serif"
+	};
+
+	=====*/
+
+	lang.mixin(g, {
+		// summary:
 		//		defines constants, prototypes, and utility functions for the core Graphics API
 
 		// default shapes, which are used to fill in missing parameters
 		defaultPath: {
-			//	summary:
+			// summary:
 			//		Defines the default Path prototype object.
-			type: "path", 
-			//	type: String
+
+			// type: String
 			//		Specifies this object is a Path, default value 'path'.
-			path: ""
-			//	path: String
-			//		The path commands. See W32C SVG 1.0 specification. 
+			type: "path", 
+
+			// path: String
+			//		The path commands. See W32C SVG 1.0 specification.
 			//		Defaults to empty string value.
+			path: ""
 		},
 		defaultPolyline: {
-			//	summary:
+			// summary:
 			//		Defines the default PolyLine prototype.
-			type: "polyline", 
-			//	type: String
+
+			// type: String
 			//		Specifies this object is a PolyLine, default value 'polyline'.
-			points: []
-			//	points: Array
+			type: "polyline",
+
+			// points: Array
 			//		An array of point objects [{x:0,y:0},...] defining the default polyline's line segments. Value is an empty array [].
+			points: []
 		},
 		defaultRect: {
-			//	summary:
+			// summary:
 			//		Defines the default Rect prototype.
+
+			// type: String
+			//		Specifies this default object is a type of Rect. Value is 'rect'
 			type: "rect",
-			//	type: String
-			//		Specifies this default object is a type of Rect. Value is 'rect' 
-			x: 0, 
-			//	x: Number
+
+			// x: Number
 			//		The X coordinate of the default rectangles position, value 0.
-			y: 0, 
-			//	y: Number
+			x: 0,
+
+			// y: Number
 			//		The Y coordinate of the default rectangle's position, value 0.
-			width: 100, 
-			//	width: Number
+			y: 0,
+
+			// width: Number
 			//		The width of the default rectangle, value 100.
-			height: 100, 
-			//	height: Number
+			width: 100,
+
+			// height: Number
 			//		The height of the default rectangle, value 100.
-			r: 0
-			//	r: Number
+			height: 100,
+
+			// r: Number
 			//		The corner radius for the default rectangle, value 0.
+			r: 0
 		},
 		defaultEllipse: {
-			//	summary:
+			// summary:
 			//		Defines the default Ellipse prototype.
-			type: "ellipse", 
-			//	type: String
+
+			// type: String
 			//		Specifies that this object is a type of Ellipse, value is 'ellipse'
-			cx: 0, 
-			//	cx: Number
+			type: "ellipse",
+
+			// cx: Number
 			//		The X coordinate of the center of the ellipse, default value 0.
-			cy: 0, 
-			//	cy: Number
+			cx: 0,
+
+			// cy: Number
 			//		The Y coordinate of the center of the ellipse, default value 0.
-			rx: 200,
-			//	rx: Number
+			cy: 0,
+
+			// rx: Number
 			//		The radius of the ellipse in the X direction, default value 200.
-			ry: 100
-			//	ry: Number
+			rx: 200,
+
+			// ry: Number
 			//		The radius of the ellipse in the Y direction, default value 200.
+			ry: 100
 		},
 		defaultCircle: {
-			//	summary:
+			// summary:
 			//		An object defining the default Circle prototype.
-			type: "circle", 
-			//	type: String
+
+			// type: String
 			//		Specifies this object is a circle, value 'circle'
-			cx: 0, 
-			//	cx: Number
+			type: "circle",
+
+			// cx: Number
 			//		The X coordinate of the center of the circle, default value 0.
-			cy: 0, 
-			//	cy: Number
+			cx: 0,
+			// cy: Number
 			//		The Y coordinate of the center of the circle, default value 0.
-			r: 100
-			//	r: Number
+			cy: 0,
+
+			// r: Number
 			//		The radius, default value 100.
+			r: 100
 		},
 		defaultLine: {
-			//	summary:
-			//		An pbject defining the default Line prototype.
-			type: "line", 
-			//	type: String
+			// summary:
+			//		An object defining the default Line prototype.
+
+			// type: String
 			//		Specifies this is a Line, value 'line'
-			x1: 0, 
-			//	x1: Number
+			type: "line",
+
+			// x1: Number
 			//		The X coordinate of the start of the line, default value 0.
-			y1: 0, 
-			//	y1: Number
+			x1: 0,
+
+			// y1: Number
 			//		The Y coordinate of the start of the line, default value 0.
-			x2: 100,
-			//	x2: Number
+			y1: 0,
+
+			// x2: Number
 			//		The X coordinate of the end of the line, default value 100.
-			y2: 100
-			//	y2: Number
+			x2: 100,
+
+			// y2: Number
 			//		The Y coordinate of the end of the line, default value 100.
+			y2: 100
 		},
 		defaultImage: {
-			//	summary:
+			// summary:
 			//		Defines the default Image prototype.
-			type: "image",
-			//	type: String
+
+			// type: String
 			//		Specifies this object is an image, value 'image'.
-			x: 0, 
-			//	x: Number
+			type: "image",
+
+			// x: Number
 			//		The X coordinate of the image's position, default value 0.
-			y: 0, 
-			//	y: Number
+			x: 0,
+
+			// y: Number
 			//		The Y coordinate of the image's position, default value 0.
-			width: 0,
-			//	width: Number
+			y: 0,
+
+			// width: Number
 			//		The width of the image, default value 0.
-			height: 0,
-			//	height:Number
+			width: 0,
+
+			// height: Number
 			//		The height of the image, default value 0.
-			src: ""
-			//	src: String
+			height: 0,
+
+			// src: String
 			//		The src url of the image, defaults to empty string.
+			src: ""
 		},
 		defaultText: {
-			//	summary:
+			// summary:
 			//		Defines the default Text prototype.
-			type: "text", 
-			//	type: String
+
+			// type: String
 			//		Specifies this is a Text shape, value 'text'.
-			x: 0, 
-			//	x: Number
+			type: "text",
+
+			// x: Number
 			//		The X coordinate of the text position, default value 0.
-			y: 0, 
-			//	y: Number
+			x: 0,
+
+			// y: Number
 			//		The Y coordinate of the text position, default value 0.
-			text: "",
-			//	text: String
+			y: 0,
+
+			// text: String
 			//		The text to be displayed, default value empty string.
-			align: "start",
-			//	align:	String
+			text: "",
+
+			// align:	String
 			//		The horizontal text alignment, one of 'start', 'end', 'center'. Default value 'start'.
-			decoration: "none",
-			//	decoration: String
+			align: "start",
+
+			// decoration: String
 			//		The text decoration , one of 'none', ... . Default value 'none'.
-			rotated: false,
-			//	rotated: Boolean
+			decoration: "none",
+
+			// rotated: Boolean
 			//		Whether the text is rotated, boolean default value false.
-			kerning: true
-			//	kerning: Boolean
+			rotated: false,
+
+			// kerning: Boolean
 			//		Whether kerning is used on the text, boolean default value true.
+			kerning: true
 		},
 		defaultTextPath: {
-			//	summary:
+			// summary:
 			//		Defines the default TextPath prototype.
-			type: "textpath", 
-			//	type: String
+
+			// type: String
 			//		Specifies this is a TextPath, value 'textpath'.
-			text: "", 
-			//	text: String
+			type: "textpath",
+
+			// text: String
 			//		The text to be displayed, default value empty string.
-			align: "start",
-			//	align: String
+			text: "",
+
+			// align: String
 			//		The horizontal text alignment, one of 'start', 'end', 'center'. Default value 'start'.
-			decoration: "none",
-			//	decoration: String
+			align: "start",
+
+			// decoration: String
 			//		The text decoration , one of 'none', ... . Default value 'none'.
-			rotated: false,
-			//	rotated: Boolean
+			decoration: "none",
+
+			// rotated: Boolean
 			//		Whether the text is rotated, boolean default value false.
-			kerning: true
-			//	kerning: Boolean
+			rotated: false,
+
+			// kerning: Boolean
 			//		Whether kerning is used on the text, boolean default value true.
+			kerning: true
 		},
 
 		// default stylistic attributes
 		defaultStroke: {
-			//	summary:
-			//		A stroke defines stylistic properties that are used when drawing a path.  
+			// summary:
+			//		A stroke defines stylistic properties that are used when drawing a path.
 			//		This object defines the default Stroke prototype.
-			type: "stroke", 
-			//	type: String
+			// type: String
 			//		Specifies this object is a type of Stroke, value 'stroke'.
-			color: "black", 
-			//	color: String
+			type: "stroke",
+
+			// color: String
 			//		The color of the stroke, default value 'black'.
-			style: "solid",
-			//	style: String
+			color: "black",
+
+			// style: String
 			//		The style of the stroke, one of 'solid', ... . Default value 'solid'.
-			width: 1,
-			//	width: Number
+			style: "solid",
+
+			// width: Number
 			//		The width of a stroke, default value 1.
-			cap: "butt",
-			//	cap: String
+			width: 1,
+
+			// cap: String
 			//		The endcap style of the path. One of 'butt', 'round', ... . Default value 'butt'.
-			join: 4
-			//	join: Number
+			cap: "butt",
+
+			// join: Number
 			//		The join style to use when combining path segments. Default value 4.
+			join: 4
 		},
 		defaultLinearGradient: {
-			//	summary:
+			// summary:
 			//		An object defining the default stylistic properties used for Linear Gradient fills.
 			//		Linear gradients are drawn along a virtual line, which results in appearance of a rotated pattern in a given direction/orientation.
-			type: "linear", 
-			//	type: String
+
+			// type: String
 			//		Specifies this object is a Linear Gradient, value 'linear'
-			x1: 0, 
-			//	x1: Number
+			type: "linear",
+
+			// x1: Number
 			//		The X coordinate of the start of the virtual line along which the gradient is drawn, default value 0.
-			y1: 0, 
-			//	y1: Number
+			x1: 0,
+
+			// y1: Number
 			//		The Y coordinate of the start of the virtual line along which the gradient is drawn, default value 0.
-			x2: 100,
-			//	x2: Number
+			y1: 0,
+
+			// x2: Number
 			//		The X coordinate of the end of the virtual line along which the gradient is drawn, default value 100.
-			y2: 100,
-			//	y2: Number
+			x2: 100,
+
+			// y2: Number
 			//		The Y coordinate of the end of the virtual line along which the gradient is drawn, default value 100.
+			y2: 100,
+
+			// colors: Array
+			//		An array of colors at given offsets (from the start of the line).  The start of the line is
+			//		defined at offest 0 with the end of the line at offset 1.
+			//		Default value, [{ offset: 0, color: 'black'},{offset: 1, color: 'white'}], is a gradient from black to white.
 			colors: [
 				{ offset: 0, color: "black" }, { offset: 1, color: "white" }
 			]
-			//	colors: Array
-			//		An array of colors at given offsets (from the start of the line).  The start of the line is
-			//		defined at offest 0 with the end of the line at offset 1.
-			//		Default value, [{ offset: 0, color: 'black'},{offset: 1, color: 'white'}], is a gradient from black to white. 
 		},
 		defaultRadialGradient: {
 			// summary:
 			//		An object specifying the default properties for RadialGradients using in fills patterns.
-			type: "radial",
-			//	type: String
+
+			// type: String
 			//		Specifies this is a RadialGradient, value 'radial'
-			cx: 0, 
-			//	cx: Number
+			type: "radial",
+
+			// cx: Number
 			//		The X coordinate of the center of the radial gradient, default value 0.
-			cy: 0, 
-			//	cy: Number
+			cx: 0,
+
+			// cy: Number
 			//		The Y coordinate of the center of the radial gradient, default value 0.
-			r: 100,
-			//	r: Number
+			cy: 0,
+
+			// r: Number
 			//		The radius to the end of the radial gradient, default value 100.
+			r: 100,
+
+			// colors: Array
+			//		An array of colors at given offsets (from the center of the radial gradient).
+			//		The center is defined at offest 0 with the outer edge of the gradient at offset 1.
+			//		Default value, [{ offset: 0, color: 'black'},{offset: 1, color: 'white'}], is a gradient from black to white.
 			colors: [
 				{ offset: 0, color: "black" }, { offset: 1, color: "white" }
 			]
-			//	colors: Array
-			//		An array of colors at given offsets (from the center of the radial gradient).  
-			//		The center is defined at offest 0 with the outer edge of the gradient at offset 1.
-			//		Default value, [{ offset: 0, color: 'black'},{offset: 1, color: 'white'}], is a gradient from black to white. 
 		},
 		defaultPattern: {
 			// summary:
 			//		An object specifying the default properties for a Pattern using in fill operations.
-			type: "pattern", 
+
 			// type: String
 			//		Specifies this object is a Pattern, value 'pattern'.
-			x: 0, 
-			//	x: Number
+			type: "pattern",
+
+			// x: Number
 			//		The X coordinate of the position of the pattern, default value is 0.
-			y: 0, 
-			//	y: Number
+			x: 0,
+
+			// y: Number
 			//		The Y coordinate of the position of the pattern, default value is 0.
-			width: 0, 
-			//	width: Number
+			y: 0,
+
+			// width: Number
 			//		The width of the pattern image, default value is 0.
-			height: 0, 
-			//	height: Number
+			width: 0,
+
+			// height: Number
 			//		The height of the pattern image, default value is 0.
+			height: 0,
+
+			// src: String
+			//		A url specifying the image to use for the pattern.
 			src: ""
-			//	src: String
-			//		A url specifing the image to use for the pattern.
 		},
 		defaultFont: {
 			// summary:
 			//		An object specifying the default properties for a Font used in text operations.
-			type: "font", 
+
 			// type: String
 			//		Specifies this object is a Font, value 'font'.
-			style: "normal", 
-			//	style: String
+			type: "font",
+
+			// style: String
 			//		The font style, one of 'normal', 'bold', default value 'normal'.
-			variant: "normal",
-			//	variant: String
+			style: "normal",
+
+			// variant: String
 			//		The font variant, one of 'normal', ... , default value 'normal'.
-			weight: "normal", 
-			//	weight: String
+			variant: "normal",
+
+			// weight: String
 			//		The font weight, one of 'normal', ..., default value 'normal'.
-			size: "10pt", 
-			//	size: String
+			weight: "normal",
+
+			// size: String
 			//		The font size (including units), default value '10pt'.
-			family: "serif"
-			//	family: String
+			size: "10pt",
+
+			// family: String
 			//		The font family, one of 'serif', 'sanserif', ..., default value 'serif'.
+			family: "serif"
 		},
 
 		getDefault: (function(){
-			//	summary:
+			// summary:
 			//		Returns a function used to access default memoized prototype objects (see them defined above).
 			var typeCtorCache = {};
 			// a memoized delegate()
@@ -459,19 +771,21 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 			}
 		})(),
 
-		normalizeColor: function(/*dojo.Color|Array|string|Object*/ color){
-			//	summary:
+		normalizeColor: function(/*dojo/Color|Array|string|Object*/ color){
+			// summary:
 			//		converts any legal color representation to normalized
-			//		dojo.Color object
-			return (color instanceof Color) ? color : new Color(color); // dojo.Color
+			//		dojo/Color object
+			// color:
+			//		A color representation.
+			return (color instanceof Color) ? color : new Color(color); // dojo/Color
 		},
 		normalizeParameters: function(existed, update){
-			//	summary:
+			// summary:
 			//		updates an existing object with properties from an 'update'
 			//		object
-			//	existed: Object
+			// existed: Object
 			//		the target object to be updated
-			//	update:  Object
+			// update: Object
 			//		the 'update' object, whose properties will be used to update
 			//		the existed object
 			var x;
@@ -486,13 +800,15 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 			return existed;	// Object
 		},
 		makeParameters: function(defaults, update){
-			//	summary:
+			// summary:
 			//		copies the original object, and all copied properties from the
 			//		'update' object
-			//	defaults: Object
+			// defaults: Object
 			//		the object to be cloned before updating
-			//	update:   Object
+			// update: Object
 			//		the object, which properties are to be cloned during updating
+			// returns: Object
+			//      new object with new and default properties
 			var i = null;
 			if(!update){
 				// return dojo.clone(defaults);
@@ -507,11 +823,14 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 			return result; // Object
 		},
 		formatNumber: function(x, addSpace){
-			// summary: converts a number to a string using a fixed notation
+			// summary:
+			//		converts a number to a string using a fixed notation
 			// x: Number
 			//		number to be converted
 			// addSpace: Boolean
 			//		whether to add a space before a positive number
+			// returns: String
+			//      the formatted value
 			var val = x.toString();
 			if(val.indexOf("e") >= 0){
 				val = x.toFixed(4);
@@ -528,8 +847,10 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 		},
 		// font operations
 		makeFontString: function(font){
-			// summary: converts a font object to a CSS font string
-			// font:	Object:	font object (see dojox.gfx.defaultFont)
+			// summary:
+			//		converts a font object to a CSS font string
+			// font: Object
+			//		font object (see dojox/gfx.defaultFont)
 			return font.style + " " + font.variant + " " + font.weight + " " + font.size + " " + font.family; // Object
 		},
 		splitFontString: function(str){
@@ -540,9 +861,11 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 			//		string components should follow the W3C specified order
 			//		(see http://www.w3.org/TR/CSS2/fonts.html#font-shorthand):
 			//		style, variant, weight, size, optional line height (will be
-			//		ignored), and family.
+			//		ignored), and family. Note that the Font.size attribute is limited to numeric CSS length.
 			// str: String
-			//		a CSS font string
+			//		a CSS font string.
+			// returns: Object
+			//      object in dojox/gfx.defaultFont format
 			var font = g.getDefault("Font");
 			var t = str.split(/\s+/);
 			do{
@@ -567,32 +890,44 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 			return font;	// Object
 		},
 		// length operations
-		cm_in_pt: 72 / 2.54, 
-			//	cm_in_pt: Number
-			//		points per centimeter (constant)
+
+		// cm_in_pt: Number
+		//		points per centimeter (constant)
+		cm_in_pt: 72 / 2.54,
+
+		// mm_in_pt: Number
+		//		points per millimeter (constant)
 		mm_in_pt: 7.2 / 2.54,
-			//	mm_in_pt: Number
-			//		points per millimeter (constant)
+
 		px_in_pt: function(){
-			//	summary: returns the current number of pixels per point.
+			// summary:
+			//		returns the current number of pixels per point.
 			return g._base._getCachedFontMeasurements()["12pt"] / 12;	// Number
 		},
+
 		pt2px: function(len){
-			//	summary: converts points to pixels
-			//	len: Number
+			// summary:
+			//		converts points to pixels
+			// len: Number
 			//		a value in points
 			return len * g.px_in_pt();	// Number
 		},
+
 		px2pt: function(len){
-			//	summary: converts pixels to points
-			//	len: Number
+			// summary:
+			//		converts pixels to points
+			// len: Number
 			//		a value in pixels
 			return len / g.px_in_pt();	// Number
 		},
+
 		normalizedLength: function(len) {
-			//	summary: converts any length value to pixels
-			//	len: String
+			// summary:
+			//		converts any length value to pixels
+			// len: String
 			//		a length, e.g., '12pc'
+			// returns: Number
+			//      pixels
 			if(len.length === 0){ return 0; }
 			if(len.length > 2){
 				var px_in_pt = g.px_in_pt();
@@ -609,34 +944,73 @@ define(["dojo/_base/lang", "dojo/_base/html", "dojo/_base/Color", "dojo/_base/sn
 			return parseFloat(len);	// Number
 		},
 
+		// pathVmlRegExp: RegExp
+		//		a constant regular expression used to split a SVG/VML path into primitive components
+		// tags:
+		//		private
 		pathVmlRegExp: /([A-Za-z]+)|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
-			//	pathVmlRegExp: RegExp
-			//		a constant regular expression used to split a SVG/VML path into primitive components
+
+		// pathVmlRegExp: RegExp
+		//		a constant regular expression used to split a SVG/VML path into primitive components
+		// tags:
+		//		private
 		pathSvgRegExp: /([A-Za-z])|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,
-			//	pathVmlRegExp: RegExp
-			//		a constant regular expression used to split a SVG/VML path into primitive components
 
-		equalSources: function(a /*Object*/, b /*Object*/){
-			//	summary: compares event sources, returns true if they are equal
-			//	a: first event source
-			//	b: event source to compare against a
+		equalSources: function(a, b){
+			// summary:
+			//		compares event sources, returns true if they are equal
+			// a: Object
+			//		first event source
+			// b: Object
+			//		event source to compare against a
+			// returns: Boolean
+			//      true, if objects are truthy and the same
 			return a && b && a === b;
 		},
 
-		switchTo: function(renderer/*String|Object*/){
-			//	summary: switch the graphics implementation to the specified renderer.
-			//	renderer: 
+		switchTo: function(/*String|Object*/ renderer){
+			// summary:
+			//		switch the graphics implementation to the specified renderer.
+			// renderer:
 			//		Either the string name of a renderer (eg. 'canvas', 'svg, ...) or the renderer
 			//		object to switch to.
 			var ns = typeof renderer == "string" ? g[renderer] : renderer;
 			if(ns){
+				// If more options are added, update the docblock at the end of shape.js!
 				arr.forEach(["Group", "Rect", "Ellipse", "Circle", "Line",
 						"Polyline", "Image", "Text", "Path", "TextPath",
 						"Surface", "createSurface", "fixTarget"], function(name){
 					g[name] = ns[name];
 				});
+				if(typeof renderer == "string"){
+					g.renderer = renderer;
+				}else{
+					arr.some(["svg","vml","canvas","canvasWithEvents","silverlight"], function(r){
+						return (g.renderer = g[r] && g[r].Surface === g.Surface ? r : null);
+					});
+				}
 			}
 		}
 	});
+	
+	/*=====
+		g.createSurface = function(parentNode, width, height){
+			// summary:
+			//		creates a surface
+			// parentNode: Node
+			//		a parent node
+			// width: String|Number
+			//		width of surface, e.g., "100px" or 100
+			// height: String|Number
+			//		height of surface, e.g., "100px" or 100
+			// returns: dojox/gfx.Surface
+			//     newly created surface
+		};
+		g.fixTarget = function(){
+			// tags:
+			//		private
+		};
+	=====*/
+	
 	return g; // defaults object api
 });
diff --git a/dojox/gfx/_gfxBidiSupport.js b/dojox/gfx/_gfxBidiSupport.js
index 3ac682f..dd9a524 100644
--- a/dojox/gfx/_gfxBidiSupport.js
+++ b/dojox/gfx/_gfxBidiSupport.js
@@ -1,8 +1,14 @@
 define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base/html", "dojo/_base/array",
-		"./utils", "./shape", "dojox/string/BidiEngine"], 
-  function(g, lang, has, dom, html, arr, utils, shapeLib, BidiEngine){
+		"./utils", "./shape", "./path", "dojox/string/BidiEngine"],
+function(g, lang, has, dom, html, arr, utils, shapeLib, pathLib, BidiEngine){
 	lang.getObject("dojox.gfx._gfxBidiSupport", true);
-	/*===== g = dojox.gfx; =====*/
+
+	/*=====
+	// Prevent changes here from masking the definitions in _base.js from the doc parser
+	var origG = g;
+	g = {};
+	=====*/
+
 	switch (g.renderer){
 		case 'vml':
 			g.isVml = true;
@@ -17,6 +23,7 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 			g.isSilverlight = true;
 			break;
 		case 'canvas':
+		case 'canvasWithEvents':
 			g.isCanvas = true;
 			break;
 	}
@@ -29,6 +36,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 		RLE : '\u202B'
 	};
 
+	/*===== g = origG; =====*/
+
 	// the object that performs text transformations.
 	var bidiEngine = new BidiEngine();
 
@@ -36,16 +45,17 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 		// textDir: String
 		//		Will be used as default for Text/TextPath/Group objects that created by this surface
 		//		and textDir wasn't directly specified for them, though the bidi support was loaded.
-		//		Can be setted in two ways:
-		//			1. When the surface is created and textDir value passed to it as fourth 
-		//			parameter.
-		//			2. Using the setTextDir(String) function, when this function is used the value
-		//			of textDir propogates to all of it's children and the children of children (for Groups) etc.
+		//		Can be set in two ways:
+		//
+		//		1. When the surface is created and textDir value passed to it as fourth
+		//		parameter.
+		//		2. Using the setTextDir(String) function, when this function is used the value
+		//		of textDir propagates to all of it's children and the children of children (for Groups) etc.
 		textDir: "",
 
 		setTextDir: function(/*String*/newTextDir){
 			// summary:
-			//		Used for propogation and change of textDir.
+			//		Used for propagation and change of textDir.
 			//		newTextDir will be forced as textDir for all of it's children (Group/Text/TextPath).
 			setTextDir(this, newTextDir);
 		},
@@ -63,7 +73,7 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 
 		setTextDir: function(/*String*/newTextDir){
 			// summary:
-			//		Used for propogation and change of textDir.
+			//		Used for propagation and change of textDir.
 			//		newTextDir will be forced as textDir for all of it's children (Group/Text/TextPath).
 			setTextDir(this, newTextDir);
 		},
@@ -75,123 +85,134 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 	
 	lang.extend(g.Text, {  
 		// summary:
-		//		Overrides some of dojox.gfx.Text properties, and adds some 
+		//		Overrides some of dojox/gfx.Text properties, and adds some
 		//		for bidi support.
 		
 		// textDir: String
 		//		Used for displaying bidi scripts in right layout.
 		//		Defines the base direction of text that displayed, can have 3 values:
-		//			1. "ltr" - base direction is left to right.
-		//			2. "rtl" - base direction is right to left.
-		//			3. "auto" - base direction is contextual (defined by first strong character).
+		//
+		//		1. "ltr" - base direction is left to right.
+		//		2. "rtl" - base direction is right to left.
+		//		3. "auto" - base direction is contextual (defined by first strong character).
 		textDir: "",
 
 		formatText: function (/*String*/ text, /*String*/ textDir){
-			// summary: 
+			// summary:
 			//		Applies the right transform on text, according to renderer.
 			// text:	
 			//		the string for manipulation, by default return value.
 			// textDir:	
 			//		Text direction.
 			//		Can be:
-			//			1. "ltr" - for left to right layout.
-			//			2. "rtl" - for right to left layout
-			//			3. "auto" - for contextual layout: the first strong letter decides the direction.	
-			// discription:
+			//
+			//		1. "ltr" - for left to right layout.
+			//		2. "rtl" - for right to left layout
+			//		3. "auto" - for contextual layout: the first strong letter decides the direction.
+			// description:
 			//		Finds the right transformation that should be applied on the text, according to renderer.
 			//		Was tested in:
-			//			Renderers (browser for testing): 
-			//				canvas (FF, Chrome, Safari), 
-			//				vml (IE), 
-			//				svg (FF, Chrome, Safari, Opera), 
-			//				silverlight (IE, Chrome, Safari, Opera), 
-			//				svgWeb(FF, Chrome, Safari, Opera, IE).
-			//			Browsers [browser version that was tested]: 
-			//				IE [6,7,8], FF [3.6], 
-			//				Chrome (latest for March 2011), 
-			//				Safari [5.0.3], 
-			//				Opera [11.01].
+			//
+			//		Renderers (browser for testing):
+			//
+			//		- canvas (FF, Chrome, Safari),
+			//		- vml (IE),
+			//		- svg (FF, Chrome, Safari, Opera),
+			//		- silverlight (IE, Chrome, Safari, Opera),
+			//		- svgWeb(FF, Chrome, Safari, Opera, IE).
+			//
+			//		Browsers [browser version that was tested]:
+			//
+			//		- IE [6,7,8], FF [3.6],
+			//		- Chrome (latest for March 2011),
+			//		- Safari [5.0.3],
+			//		- Opera [11.01].
 
 			if(textDir && text && text.length > 1){
-			var sourceDir = "ltr", targetDir = textDir;
-
-			if(targetDir == "auto"){
-				//is auto by default
+				var sourceDir = "ltr", targetDir = textDir;
+	
+				if(targetDir == "auto"){
+					//is auto by default
+					if(g.isVml){
+						return text;
+					}
+					targetDir = bidiEngine.checkContextual(text);
+				}
+	
 				if(g.isVml){
+					sourceDir = bidiEngine.checkContextual(text);
+					if(targetDir != sourceDir){
+						if(targetDir == "rtl"){
+							return !bidiEngine.hasBidiChar(text) ? bidiEngine.bidiTransform(text,"IRNNN","ILNNN") : bidi_const.RLM + bidi_const.RLM + text;
+						}else{
+							return bidi_const.LRM + text;
+						}
+					}
 					return text;
 				}
-				targetDir = bidiEngine.checkContextual(text);
-			}
-
-			if(g.isVml){
-				sourceDir = bidiEngine.checkContextual(text);
-				if(targetDir != sourceDir){
+	
+				if(g.isSvgWeb){
 					if(targetDir == "rtl"){
-						return !bidiEngine.hasBidiChar(text) ? bidiEngine.bidiTransform(text,"IRNNN","ILNNN") : bidi_const.RLM + bidi_const.RLM + text;
-					}else{
-						return bidi_const.LRM + text;
+						return bidiEngine.bidiTransform(text,"IRNNN","ILNNN");
 					}
+					return text;
 				}
-				return text;
-			}
-
-			if(g.isSvgWeb){
-				if(targetDir == "rtl"){
-					return bidiEngine.bidiTransform(text,"IRNNN","ILNNN");
+	
+				if(g.isSilverlight){
+					return (targetDir == "rtl") ? bidiEngine.bidiTransform(text,"IRNNN","VLYNN") : bidiEngine.bidiTransform(text,"ILNNN","VLYNN");
 				}
-				return text;
-			}
-
-			if(g.isSilverlight){
-				return (targetDir == "rtl") ? bidiEngine.bidiTransform(text,"IRNNN","VLYNN") : bidiEngine.bidiTransform(text,"ILNNN","VLYNN");
-			}
-
-			if(g.isCanvas){
-				return (targetDir == "rtl") ? bidi_const.RLE + text + bidi_const.PDF : bidi_const.LRE + text + bidi_const.PDF;
-			}
-
-			if(g.isSvg){
-				if(has("ff")){
-					return (targetDir == "rtl") ? bidiEngine.bidiTransform(text,"IRYNN","VLNNN") : bidiEngine.bidiTransform(text,"ILYNN","VLNNN");
+	
+				if(g.isCanvas){
+					return (targetDir == "rtl") ? bidi_const.RLE + text + bidi_const.PDF : bidi_const.LRE + text + bidi_const.PDF;
 				}
-				if(has("chrome") || has("safari") || has("opera")){
-					return bidi_const.LRM + (targetDir == "rtl" ? bidi_const.RLE : bidi_const.LRE) + text + bidi_const.PDF;
+	
+				if(g.isSvg){
+					if(has("ff") < 4){
+						return (targetDir == "rtl") ? bidiEngine.bidiTransform(text,"IRYNN","VLNNN") : bidiEngine.bidiTransform(text,"ILYNN","VLNNN");
+					}else{
+						return bidi_const.LRM + (targetDir == "rtl" ? bidi_const.RLE : bidi_const.LRE) + text + bidi_const.PDF;
+					}					
 				}					
-			}					
-}
+			}
 			return text;
 		},	
 
 		bidiPreprocess: function(newShape){     
 			return newShape;
-		}	
+		}
 	});
 
-	lang.extend(g.TextPath, {          
-			// textDir: String
-			//		Used for displaying bidi scripts in right layout.
-			//		Defines the base direction of text that displayed, can have 3 values:
-			//			1. "ltr" - base direction is left to right.
-			//			2. "rtl" - base direction is right to left.
-			//			3. "auto" - base direction is contextual (defined by first strong character).
+	lang.extend(g.TextPath, {
+		// textDir: String
+		//		Used for displaying bidi scripts in right layout.
+		//		Defines the base direction of text that displayed, can have 3 values:
+		//
+		//		1. "ltr" - base direction is left to right.
+		//		2. "rtl" - base direction is right to left.
+		//		3. "auto" - base direction is contextual (defined by first strong character).
 		textDir: "",
 
 		formatText: function (/*String*/text, /*String*/textDir){
-			// summary: 
+			// summary:
 			//		Applies the right transform on text, according to renderer.
-			// text:	the string for manipulation, by default return value.
-			// textDir:	text direction direction.
+			// text:
+			//		the string for manipulation, by default return value.
+			// textDir:
+			//		text direction direction.
 			//		Can be:
-			//			1. "ltr" - for left to right layout.
-			//			2. "rtl" - for right to left layout
-			//			3. "auto" - for contextual layout: the first strong letter decides the direction.	
-			// discription:
+			//
+			//		1. "ltr" - for left to right layout.
+			//		2. "rtl" - for right to left layout
+			//		3. "auto" - for contextual layout: the first strong letter decides the direction.
+			// description:
 			//		Finds the right transformation that should be applied on the text, according to renderer.
 			//		Was tested in:
-			//			Renderers: 
-			//				canvas (FF, Chrome, Safari), vml (IE), svg (FF, Chrome, Safari, Opera), silverlight (IE8), svgWeb(FF, Chrome, Safari, Opera, IE).
-			//			Browsers: 
-			//				IE [6,7,8], FF [3.6], Chrome (latest for February 2011), Safari [5.0.3], Opera [11.01].
+			//
+			//		Renderers:
+			//		canvas (FF, Chrome, Safari), vml (IE), svg (FF, Chrome, Safari, Opera), silverlight (IE8), svgWeb(FF, Chrome, Safari, Opera, IE).
+			//
+			//		Browsers:
+			//		IE [6,7,8], FF [3.6], Chrome (latest for February 2011), Safari [5.0.3], Opera [11.01].
 
 			if(textDir && text && text.length > 1){
 				var sourceDir = "ltr", targetDir = textDir;
@@ -222,9 +243,9 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 					return text;
 				}
 				//unlike the g.Text that is rendered in logical layout for Bidi scripts.
-				//for g.TextPath in svg always visual -> bidi script is unreadable (except Opera).
+				//for g.TextPath in svg always visual -> bidi script is unreadable (except Opera and FF start from version 4)
 				if(g.isSvg){
-					if(has("opera")){
+					if(has("opera") || has("ff") >= 4){
 						text = bidi_const.LRM + (targetDir == "rtl"? bidi_const.RLE : bidi_const.LRE) + text + bidi_const.PDF;
 					}else{
 						text = (targetDir == "rtl") ? bidiEngine.bidiTransform(text,"IRYNN","VLNNN") : bidiEngine.bidiTransform(text,"ILYNN","VLNNN");
@@ -243,12 +264,13 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 	});	
 		
 	var extendMethod = function(shape, method, before, after){
-		// Some helper function. Used for extending metod of shape.
+		// summary:
+		//		Some helper function. Used for extending methods of shape.
 		// shape: Object
-		//		The shape we overriding it's metod.
+		//		The shape we overriding it's method.
 		// method: String
-		//		The method that is extended, the original metod is called before or after
-		//		functions that passed to extendMethod. 
+		//		The method that is extended, the original method is called before or after
+		//		functions that passed to extendMethod.
 		// before: function
 		//		If defined this function will be executed before the original method.
 		// after: function
@@ -289,7 +311,7 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 
 	};
 
-	// Istead of adding bidiPreprocess to all renders one by one
+	// Instead of adding bidiPreprocess to all renders one by one
 	// use the extendMethod, at first there's a need for bidi transformation 
 	// on text then call to original setShape.
 	extendMethod(g.Text,"setShape", bidiPreprocess, null);
@@ -303,7 +325,7 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 		return obj;
 	};
 
-	// Istead of adding restoreText to all renders one by one
+	// Instead of adding restoreText to all renders one by one
 	// use the extendMethod, at first get the shape by calling the original getShape,
 	// than resrore original text (without the text transformations).
 	extendMethod(g.Text, "getShape", null, restoreText);
@@ -315,7 +337,7 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 			textDir = validateTextDir(args[0]);
 		}
 		group.setTextDir(textDir ? textDir : this.textDir);
-		return group;	// dojox.gfx.Group				
+		return group;	// dojox/gfx.Group
 	};
 
 	// In creation of Group there's a need to update it's textDir,
@@ -327,7 +349,7 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 	extendMethod(g.Group, "createGroup", null, groupTextDir);
 
 	var textDirPreprocess =  function(text){
-		//  inherit from surface / group  if textDir is defined there
+		// inherit from surface / group  if textDir is defined there
 		if(text){
 			var textDir = text.textDir ? validateTextDir(text.textDir) : this.textDir;
 			if(textDir){
@@ -346,7 +368,12 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 	extendMethod(g.Group,"createText", textDirPreprocess, null);
 	extendMethod(g.Group,"createTextPath", textDirPreprocess, null);
 
-	g.createSurface = function(parentNode, width, height, textDir) {        
+	/*=====
+	// don't mask definition of original createSurface() function from doc parser
+	g = {};
+	=====*/
+
+	g.createSurface = function(parentNode, width, height, textDir) {
 		var s = g[g.renderer].createSurface(parentNode, width, height);
 		var tDir = validateTextDir(textDir);
 		
@@ -367,6 +394,7 @@ define(["./_base", "dojo/_base/lang","dojo/_base/sniff", "dojo/dom", "dojo/_base
 		
 		return s;
 	};
+	/*===== g = origG; =====*/
 
 	// some helper functions
 	
diff --git a/dojox/gfx/arc.js b/dojox/gfx/arc.js
index 8b233a5..33a7ed6 100644
--- a/dojox/gfx/arc.js
+++ b/dojox/gfx/arc.js
@@ -1,18 +1,11 @@
 define(["./_base", "dojo/_base/lang", "./matrix"], 
   function(g, lang, m){
-/*===== 
-	g = dojox.gfx;
-	dojox.gfx.arc = {
-		// summary:
-		//		This module contains the core graphics Arc functions.
-	};
-  =====*/
-
 	var twoPI = 2 * Math.PI, pi4 = Math.PI / 4, pi8 = Math.PI / 8,
 		pi48 = pi4 + pi8, curvePI4 = unitArcAsBezier(pi8);
 
 	function unitArcAsBezier(alpha){
-		// summary: return a start point, 1st and 2nd control points, and an end point of
+		// summary:
+		//		return a start point, 1st and 2nd control points, and an end point of
 		//		a an arc, which is reflected on the x axis
 		// alpha: Number
 		//		angle in radians, the arc will be 2 * angle size
@@ -27,23 +20,30 @@ define(["./_base", "dojo/_base/lang", "./matrix"],
 	}
 
 	var arc = g.arc = {
+		// summary:
+		//		This module contains the core graphics Arc functions.
+		
 		unitArcAsBezier: unitArcAsBezier,
 		/*===== 
-			unitArcAsBezier: function(alpha) {
-			// summary: return a start point, 1st and 2nd control points, and an end point of
+		unitArcAsBezier: function(alpha) {
+			// summary:
+			//		return a start point, 1st and 2nd control points, and an end point of
 			//		a an arc, which is reflected on the x axis
 			// alpha: Number
 			//		angle in radians, the arc will be 2 * angle size
-			},
+		},
 		=====*/
+
+		// curvePI4: Object
+		//		an object with properties of an arc around a unit circle from 0 to pi/4
 		curvePI4: curvePI4,
-			// curvePI4: Object
-			//		an object with properties of an arc around a unit circle from 0 to pi/4
+
 		arcAsBezier: function(last, rx, ry, xRotg, large, sweep, x, y){
-			// summary: calculates an arc as a series of Bezier curves
-			//	given the last point and a standard set of SVG arc parameters,
-			//	it returns an array of arrays of parameters to form a series of
-			//	absolute Bezier curves.
+			// summary:
+			//		calculates an arc as a series of Bezier curves
+			//		given the last point and a standard set of SVG arc parameters,
+			//		it returns an array of arrays of parameters to form a series of
+			//		absolute Bezier curves.
 			// last: Object
 			//		a point-like object as a start of the arc
 			// rx: Number
diff --git a/dojox/gfx/bezierutils.js b/dojox/gfx/bezierutils.js
new file mode 100644
index 0000000..7353ca6
--- /dev/null
+++ b/dojox/gfx/bezierutils.js
@@ -0,0 +1,171 @@
+define([
+	"./_base"
+], function(gfx){
+
+	var bu = gfx.bezierutils = {},
+		error = 0.1;
+
+	var tAtLength = bu.tAtLength = function(points, length){
+		// summary:
+		//		Returns the t corresponding to the given length for the specified bezier curve.
+		// points: Number[]
+		//		The bezier points. Should be [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y] for a cubic
+		//		bezier curve or [p1x, p1y, cx, cy, p2x, p2y] for a quadratic bezier curve.
+		// length: Number
+		//		The length.
+		var t = 0,
+			quadratic = points.length == 6,
+			currentLen = 0,
+			splitCount = 0,
+			splitFunc = quadratic ? splitQBezierAtT : splitBezierAtT;
+		var _compute = function(p, error){
+			// control points polygon length
+			var pLen = 0;
+			for(var i = 0; i < p.length-2; i+=2)
+				pLen += distance(p[i],p[i+1],p[i+2],p[i+3]);
+			// chord length
+			var chord = quadratic ?
+				distance(points[0],points[1],points[4],points[5]) :
+				distance(points[0],points[1],points[6],points[7]);
+			// if needs more approx. or if currentLen is greater than the target length,
+			// split the curve one more time
+			if(pLen - chord > error || currentLen + pLen > length + error){
+				++splitCount;
+				var newbezier = splitFunc(p, .5);
+				// check 1st subpath
+				_compute(newbezier[0], error);
+				// the 1st subcurve was the good one, we stop
+				if(Math.abs(currentLen - length) <= error){
+					return;
+				}
+				// need to continue with the 2nde subcurve
+				_compute(newbezier[1], error);
+				return ;
+			}
+			currentLen += pLen;
+			t += 1.0 / (1 << splitCount);
+		};
+		if(length)
+			_compute(points, 0.5);
+		return t;
+	};
+
+	var computeLength = bu.computeLength = function(/*Array*/points){
+		// summary:
+		//		Returns the length of the given bezier curve.
+		// points: Number[]
+		//		The bezier points. Should be [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y] for a cubic
+		//		bezier curve or [p1x, p1y, cx, cy, p2x, p2y] for a quadratic bezier curve.
+
+		var quadratic = points.length == 6, pLen=0;
+		// control points polygon length
+		for(var i = 0; i < points.length-2; i+=2)
+			pLen += distance(points[i],points[i+1],points[i+2],points[i+3]);
+		// chord length
+		var chord = quadratic ?
+			distance(points[0],points[1],points[4],points[5]) :
+			distance(points[0],points[1],points[6],points[7]);
+		// split polygons until the polygon and the chord are "the same"
+		if(pLen-chord>error){
+			var newBeziers = quadratic ? splitQBezierAtT(points,.5) : splitCBezierAtT(points,.5);
+			var length = computeLength(newBeziers[0], quadratic);
+			length += computeLength(newBeziers[1], quadratic);
+			return length;
+		}
+		// pLen is close enough, done.
+		return pLen;
+	};
+
+	var distance = bu.distance = function(x1, y1, x2, y2){
+		// summary:
+		//		Returns the distance between the specified points.
+		return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
+	};
+
+	var splitQBezierAtT = function(points, t){
+		// summary:
+		//		Split a quadratic bezier curve into 2 sub-quadratic beziers at the specified t.
+
+		// de Casteljau
+		var r = 1-t,
+			r2 = r*r,
+			t2 = t*t,
+			p1x = points[0],
+			p1y = points[1],
+			cx = points[2],
+			cy = points[3],
+			p2x = points[4],
+			p2y = points[5],
+
+			ax = r*p1x + t*cx,
+			ay = r*p1y + t*cy,
+			bx = r*cx + t*p2x,
+			by = r*cy + t*p2y,
+			px = r2*p1x + 2*r*t*cx + t2*p2x,
+			py = r2*p1y + 2*r*t*cy + t2*p2y;
+
+		return [
+			[
+				p1x, p1y,
+				ax, ay,
+				px, py
+			],
+			[
+				px, py,
+				bx, by,
+				p2x, p2y
+			]
+		];
+	};
+
+	var splitCBezierAtT = function(points, t){
+		// summary:
+		//		Split a cubic bezier curve into 2 sub-cubic beziers at the specified t.
+
+		// de Casteljau
+		var r = 1-t,
+			r2 = r*r,
+			r3 = r2*r,
+			t2 = t*t,
+			t3 = t2*t,
+			p1x = points[0],
+			p1y = points[1],
+			c1x = points[2],
+			c1y = points[3],
+			c2x = points[4],
+			c2y = points[5],
+			p2x = points[6],
+			p2y = points[7],
+
+			ax = r*p1x + t*c1x,
+			ay = r*p1y + t*c1y,
+			cx = r*c2x + t*p2x,
+			cy = r*c2y + t*p2y,
+			mx = r2*p1x + 2*r*t*c1x + t2*c2x,
+			my = r2*p1y + 2*r*t*c1y + t2*c2y,
+			nx = r2*c1x + 2*r*t*c2x + t2*p2x,
+			ny = r2*c1y + 2*r*t*c2y + t2*p2y,
+			px = r3*p1x + 3*r2*t*c1x + 3*r*t2*c2x+t3*p2x,
+			py = r3*p1y + 3*r2*t*c1y + 3*r*t2*c2y+t3*p2y;
+
+		return [
+			[
+				p1x, p1y,
+				ax, ay,
+				mx, my,
+				px, py
+			],
+			[
+				px, py,
+				nx, ny,
+				cx, cy,
+				p2x, p2y
+			]
+		];
+	};
+
+	var splitBezierAtT = bu.splitBezierAtT = function(points, t){
+		return points.length == 6 ? splitQBezierAtT(points, t) : splitCBezierAtT(points, t);
+	};
+	return bu;
+});
\ No newline at end of file
diff --git a/dojox/gfx/canvas.js b/dojox/gfx/canvas.js
index badc57f..3b30b89 100644
--- a/dojox/gfx/canvas.js
+++ b/dojox/gfx/canvas.js
@@ -1,57 +1,177 @@
-define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/_base/window", "dojo/dom-geometry", 
-		"dojo/dom", "./_base", "./shape", "./path", "./arc", "./matrix", "./decompose"], 
-  function(g, lang, arr, declare, win, domGeom, dom, gfxBase, gs, pathLib, ga, m, decompose ){
-/*===== 
-	dojox.gfx.canvas = {
-	// module:
-	//		dojox/gfx/canvas
-	// summary:
-	//		This the graphics rendering bridge for W3C Canvas compliant browsers.
-	//		Since Canvas is an immediate mode graphics api, with no object graph or
-	//		eventing capabilities, use of this module alone will only add in drawing support.
-	//		The additional module, canvasWithEvents extends this module with additional support
-	//		for handling events on Canvas.  By default, the support for events is now included 
-	//		however, if only drawing capabilities are needed, canvas event module can be disabled
-	//		using the dojoConfig option, canvasEvents:true|false.
-	//		The id of the Canvas renderer is 'canvas'.  This id can be used when switch Dojo's
-	//		graphics context between renderer implementations.  See dojox.gfx._base switchRenderer
-	//		API.
+define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare", "dojo/_base/window", "dojo/dom-geometry",
+		"dojo/dom", "./shape", "./path", "./arc", "./matrix", "./decompose", "./bezierutils"],
+function(g, lang, arr, declare, win, domGeom, dom, gs, pathLib, ga, m, decompose, bezierUtils ){
+	var canvas = g.canvas = {
+		// summary:
+		//		This the graphics rendering bridge for W3C Canvas compliant browsers.
+		//		Since Canvas is an immediate mode graphics api, with no object graph or
+		//		eventing capabilities, use of this module alone will only add in drawing support.
+		//		The additional module, canvasWithEvents extends this module with additional support
+		//		for handling events on Canvas.  By default, the support for events is now included
+		//		however, if only drawing capabilities are needed, canvas event module can be disabled
+		//		using the dojoConfig option, canvasEvents:true|false.
+		//		The id of the Canvas renderer is 'canvas'.  This id can be used when switch Dojo's
+		//		graphics context between renderer implementations.  See dojox/gfx/_base.switchRenderer
+		//		API.
 	};
-	g = dojox.gfx;
-	gs = dojox.gfx.shape;
-	pathLib.Path = dojox.gfx.path.Path;
-	pathLib.TextPath = dojox.gfx.path.TextPath;
-	canvas = dojox.gfx.canvas;
-	canvas.Shape = dojox.gfx.canvas.Shape;
-	gs.Shape = dojox.gfx.shape.Shape;
-	gs.Rect = dojox.gfx.shape.Rect;
-	gs.Ellipse = dojox.gfx.shape.Ellipse;
-	gs.Circle = dojox.gfx.shape.Circle;
-	gs.Line = dojox.gfx.shape.Line;
-	gs.PolyLine = dojox.gfx.shape.PolyLine;
-	gs.Image = dojox.gfx.shape.Image;
-	gs.Text = dojox.gfx.shape.Text;
-	gs.Surface = dojox.gfx.shape.Surface;
-  =====*/
-
-	var canvas = g.canvas = {};
 	var pattrnbuffer = null,
-		mp = m.multiplyPoint, 
-		pi = Math.PI, 
-		twoPI = 2 * pi, 
+		mp = m.multiplyPoint,
+		pi = Math.PI,
+		twoPI = 2 * pi,
 		halfPI = pi /2,
 		extend = lang.extend;
 
-	declare("dojox.gfx.canvas.Shape", gs.Shape, {
+	if(win.global.CanvasRenderingContext2D){
+		var ctx2d = win.doc.createElement("canvas").getContext("2d");
+		var hasNativeDash = typeof ctx2d.setLineDash == "function";
+		var hasFillText = typeof ctx2d.fillText == "function";
+	}
+
+	var dasharray = {
+		solid:				"none",
+		shortdash:			[4, 1],
+		shortdot:			[1, 1],
+		shortdashdot:		[4, 1, 1, 1],
+		shortdashdotdot:	[4, 1, 1, 1, 1, 1],
+		dot:				[1, 3],
+		dash:				[4, 3],
+		longdash:			[8, 3],
+		dashdot:			[4, 3, 1, 3],
+		longdashdot:		[8, 3, 1, 3],
+		longdashdotdot:		[8, 3, 1, 3, 1, 3]
+	};
+
+	function drawDashedArc(/*CanvasRenderingContext2D*/ctx, /*Number[]*/dash,  /*int*/cx,  /*int*/cy,  /*int*/r, /*Number*/sa, /*Number*/ea, /*Boolean*/ccw, /*Boolean?*/apply, prevResidue){
+		var residue, angle, l = dash.length, i= 0;
+		// if there's a previous dash residue from the previous arc, start with it.
+		if(prevResidue){
+			angle = prevResidue.l/r;
+			i = prevResidue.i;
+		}else{
+			angle = dash[0]/r;
+		}
+		while(sa < ea){
+			// if the dash segment length is longer than what remains to stroke, keep it for next arc. (aka residue)
+			if(sa+angle > ea){
+				residue = {l: (sa+angle-ea)*r, i: i};
+				angle = ea-sa;
+			}
+			if(!(i%2)){
+				ctx.beginPath();
+				ctx.arc(cx, cy, r, sa, sa+angle, ccw);
+				if(apply) ctx.stroke();
+			}
+			sa += angle;
+			++i;
+			angle = dash[i%l]/r;
+		}
+		return residue;
+	}
+
+	function splitToDashedBezier(/*Number[]*/points, /*Number[]*/dashArray, /*Number[]*/newPoints, /*Object*/prevResidue){
+		var residue = 0, t = 0, dash, i = 0;
+		if(prevResidue){
+			dash = prevResidue.l;
+			i = prevResidue.i;
+		}else{
+			dash = dashArray[0];
+		}
+		while(t<1){
+			// get the 't' corresponding to the given dash value.
+			t = bezierUtils.tAtLength(points, dash);
+			if(t==1){
+				var rl = bezierUtils.computeLength(points);
+				residue = {l: dash-rl, i: i};
+			}
+			// split bezier at t: left part is the "dash" curve, right part is the remaining bezier points
+			var curves = bezierUtils.splitBezierAtT(points, t);
+			if(!(i%2)){
+				// only keep the "dash" curve
+				newPoints.push(curves[0]);
+			}
+			points = curves[1];
+			++i;
+			dash = dashArray[i%dashArray.length];
+		}
+		return residue;
+	}
+
+	function toDashedCurveTo(/*Array||CanvasRenderingContext2D*/ctx, /*shape.Path*/shape, /*Number[]*/points, /*Object*/prevResidue){
+		// summary:
+		//		Builds a set of bezier (cubic || quadratic)curveTo' canvas instructions that represents a dashed stroke of the specified bezier geometry.
+
+		var pts = [shape.last.x, shape.last.y].concat(points),
+			quadratic = points.length === 4, ctx2d = !(ctx instanceof Array),
+			api = quadratic ? "quadraticCurveTo" : "bezierCurveTo",
+			curves = [];
+		var residue = splitToDashedBezier(pts, shape.canvasDash, curves, prevResidue);
+		for(var c=0; c<curves.length;++c){
+			var curve = curves[c];
+			if(ctx2d){
+				ctx.moveTo(curve[0], curve[1]);
+				ctx[api].apply(ctx, curve.slice(2));
+			}else{
+				ctx.push("moveTo", [curve[0], curve[1]]);
+				ctx.push(api, curve.slice(2));
+			}
+		}
+		return residue;
+	}
+
+	function toDashedLineTo(/*Array||CanvasRenderingContext2D*/ctx, /*shape.Shape*/shape, /*int*/x1, /*int*/y1, /*int*/x2, /*int*/y2, /*Object*/prevResidue){
+		// summary:
+		//		Builds a set of moveTo/lineTo' canvas instructions that represents a dashed stroke of the specified line geometry.
+
+		var residue = 0, r = 0, dal = 0, tlength = bezierUtils.distance(x1, y1, x2, y2), i = 0, dash = shape.canvasDash,
+			prevx = x1, prevy = y1, x, y, ctx2d = !(ctx instanceof Array);
+		if(prevResidue){
+			dal=prevResidue.l;
+			i = prevResidue.i;
+		}else{
+			dal += dash[0];
+		}
+		while(Math.abs(1-r)>0.01){
+			if(dal>tlength){
+				residue = {l:dal-tlength,i:i};
+				dal=tlength;
+			}
+			r = dal/tlength;
+			x = x1 + (x2-x1)*r;
+			y = y1 + (y2-y1)*r;
+			if(!(i++%2)){
+				if(ctx2d){
+					ctx.moveTo(prevx, prevy);
+					ctx.lineTo(x, y);
+				}else{
+					ctx.push("moveTo", [prevx, prevy]);
+					ctx.push("lineTo", [x, y]);
+				}
+			}
+			prevx = x;
+			prevy = y;
+			dal += dash[i%dash.length];
+		}
+		return residue;
+	}
+
+	canvas.Shape = declare("dojox.gfx.canvas.Shape", gs.Shape, {
 		_render: function(/* Object */ ctx){
-			// summary: render the shape
+			// summary:
+			//		render the shape
 			ctx.save();
 			this._renderTransform(ctx);
+			this._renderClip(ctx);
 			this._renderShape(ctx);
 			this._renderFill(ctx, true);
 			this._renderStroke(ctx, true);
 			ctx.restore();
 		},
+		_renderClip: function(ctx){
+			if (this.canvasClip){
+				this.canvasClip.render(ctx);
+				ctx.clip();
+			}
+		},
 		_renderTransform: function(/* Object */ ctx){
 			if("canvasTransform" in this){
 				var t = this.canvasTransform;
@@ -111,32 +231,90 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 				}else{
 					ctx.lineJoin = s.join;
 				}
-				if(apply){ ctx.stroke(); }
+				if(this.canvasDash){
+					if(hasNativeDash){
+						ctx.setLineDash(this.canvasDash);
+						if(apply){ ctx.stroke(); }
+					}else{
+						this._renderDashedStroke(ctx, apply);
+					}
+				}else{
+					if(apply){ ctx.stroke(); }
+				}
 			}else if(!apply){
 				ctx.strokeStyle = "rgba(0,0,0,0.0)";
 			}
 		},
+		_renderDashedStroke: function(ctx, apply){},
 
 		// events are not implemented
 		getEventSource: function(){ return null; },
+		on:				function(){},
 		connect:		function(){},
-		disconnect:		function(){}
+		disconnect:		function(){},
+
+		canvasClip:null,
+		setClip: function(/*Object*/clip){
+			this.inherited(arguments);
+			var clipType = clip ? "width" in clip ? "rect" :
+							"cx" in clip ? "ellipse" :
+							"points" in clip ? "polyline" : "d" in clip ? "path" : null : null;
+			if(clip && !clipType){
+				return this;
+			}
+			this.canvasClip = clip ? makeClip(clipType, clip) : null;
+			if(this.parent){this.parent._makeDirty();}
+			return this;
+		}
 	});
 
-	var modifyMethod = function(shape, method, extra){
-			var old = shape.prototype[method];
-			shape.prototype[method] = extra ?
-				function(){
-					this.surface.makeDirty();
-					old.apply(this, arguments);
-					extra.call(this);
-					return this;
-				} :
-				function(){
-					this.surface.makeDirty();
-					return old.apply(this, arguments);
+	var makeClip = function(clipType, geometry){
+		switch(clipType){
+			case "ellipse":
+				return {
+					canvasEllipse: makeEllipse({shape:geometry}),
+					render: function(ctx){return canvas.Ellipse.prototype._renderShape.call(this, ctx);}
 				};
-		};
+			case "rect":
+				return {
+					shape: lang.delegate(geometry,{r:0}),
+					render: function(ctx){return canvas.Rect.prototype._renderShape.call(this, ctx);}
+				};
+			case "path":
+				return {
+					canvasPath: makeClipPath(geometry),
+					render: function(ctx){this.canvasPath._renderShape(ctx);}
+				};
+			case "polyline":
+				return {
+					canvasPolyline: geometry.points,
+					render: function(ctx){return canvas.Polyline.prototype._renderShape.call(this, ctx);}
+				};
+		}
+		return null;
+	};
+
+	var makeClipPath = function(geo){
+		var p = new dojox.gfx.canvas.Path();
+		p.canvasPath = [];
+		p._setPath(geo.d);
+		return p;
+	};
+
+	var modifyMethod = function(shape, method, extra){
+		var old = shape.prototype[method];
+		shape.prototype[method] = extra ?
+			function(){
+				if(this.parent){this.parent._makeDirty();}
+				old.apply(this, arguments);
+				extra.call(this);
+				return this;
+			} :
+			function(){
+				if(this.parent){this.parent._makeDirty();}
+				return old.apply(this, arguments);
+			};
+	};
 
 	modifyMethod(canvas.Shape, "setTransform",
 		function(){
@@ -186,28 +364,76 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 			}
 		});
 
-	modifyMethod(canvas.Shape, "setStroke");
+	modifyMethod(canvas.Shape, "setStroke",
+		function(){
+			var st = this.strokeStyle;
+			if(st){
+				var da = this.strokeStyle.style.toLowerCase();
+				if(da in dasharray){
+					da = dasharray[da];
+				}
+				if(da instanceof Array){
+					da = da.slice();
+					this.canvasDash = da;
+					var i;
+					for(i = 0; i < da.length; ++i){
+						da[i] *= st.width;
+					}
+					if(st.cap != "butt"){
+						for(i = 0; i < da.length; i += 2){
+							da[i] -= st.width;
+							if(da[i] < 1){ da[i] = 1; }
+						}
+						for(i = 1; i < da.length; i += 2){
+							da[i] += st.width;
+						}
+					}
+				}else{
+					delete this.canvasDash;
+				}
+			}else{
+				delete this.canvasDash;
+			}
+			this._needsDash = !hasNativeDash && !!this.canvasDash;
+		});
+
 	modifyMethod(canvas.Shape, "setShape");
 
-	declare("dojox.gfx.canvas.Group", canvas.Shape, {
-		// summary: a group shape (Canvas), which can be used
-		//	to logically group shapes (e.g, to propagate matricies)
+	canvas.Group = declare("dojox.gfx.canvas.Group", canvas.Shape, {
+		// summary:
+		//		a group shape (Canvas), which can be used
+		//		to logically group shapes (e.g, to propagate matricies)
 		constructor: function(){
 			gs.Container._init.call(this);
 		},
 		_render: function(/* Object */ ctx){
-			// summary: render the group
+			// summary:
+			//		render the group
 			ctx.save();
 			this._renderTransform(ctx);
+			this._renderClip(ctx);
 			for(var i = 0; i < this.children.length; ++i){
 				this.children[i]._render(ctx);
 			}
 			ctx.restore();
+		},
+		destroy: function(){
+			// summary:
+			//		Releases all internal resources owned by this shape. Once this method has been called,
+			//		the instance is considered disposed and should not be used anymore.
+
+			// don't call canvas impl to avoid makeDirty'
+			gs.Container.clear.call(this, true);
+			// avoid this.inherited
+			canvas.Shape.prototype.destroy.apply(this, arguments);
 		}
 	});
 
-	declare("dojox.gfx.canvas.Rect", [canvas.Shape, gs.Rect], {
-		// summary: a rectangle shape (Canvas)
+
+
+	canvas.Rect = declare("dojox.gfx.canvas.Rect", [canvas.Shape, gs.Rect], {
+		// summary:
+		//		a rectangle shape (Canvas)
 		_renderShape: function(/* Object */ ctx){
 			var s = this.shape, r = Math.min(s.r, s.height / 2, s.width / 2),
 				xl = s.x, xr = xl + s.width, yt = s.y, yb = yt + s.height,
@@ -225,7 +451,37 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 				ctx.lineTo(xl2, yb);
 				ctx.lineTo(xl, yt2);
 			}
-	 		ctx.closePath();
+			ctx.closePath();
+		},
+		_renderDashedStroke: function(ctx, apply){
+			var s = this.shape, residue, r = Math.min(s.r, s.height / 2, s.width / 2),
+				xl = s.x, xr = xl + s.width, yt = s.y, yb = yt + s.height,
+				xl2 = xl + r, xr2 = xr - r, yt2 = yt + r, yb2 = yb - r;
+			if(r){
+				ctx.beginPath();
+				residue = toDashedLineTo(ctx, this, xl2, yt, xr2, yt);
+				if(apply) ctx.stroke();
+				residue = drawDashedArc(ctx, this.canvasDash, xr2, yt2, r, -halfPI, 0, false, apply, residue);
+				ctx.beginPath();
+				residue = toDashedLineTo(ctx, this, xr, yt2, xr, yb2, residue);
+				if(apply) ctx.stroke();
+				residue = drawDashedArc(ctx, this.canvasDash, xr2, yb2, r, 0, halfPI, false, apply, residue);
+				ctx.beginPath();
+				residue = toDashedLineTo(ctx, this, xr2, yb, xl2, yb, residue);
+				if(apply) ctx.stroke();
+				residue = drawDashedArc(ctx, this.canvasDash, xl2, yb2, r, halfPI, pi, false, apply, residue);
+				ctx.beginPath();
+				residue = toDashedLineTo(ctx, this, xl, yb2, xl, yt2,residue);
+				if(apply) ctx.stroke();
+				drawDashedArc(ctx, this.canvasDash, xl2, yt2, r, pi, pi + halfPI, false, apply, residue);
+			}else{
+				ctx.beginPath();
+				residue = toDashedLineTo(ctx, this, xl2, yt, xr2, yt);
+				residue = toDashedLineTo(ctx, this, xr2, yt, xr, yb2, residue);
+				residue = toDashedLineTo(ctx, this, xr, yb2, xl2, yb, residue);
+				toDashedLineTo(ctx, this, xl2, yb, xl, yt2, residue);
+				if(apply) ctx.stroke();
+			}
 		}
 	});
 
@@ -239,68 +495,126 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 		}
 	})();
 
-	declare("dojox.gfx.canvas.Ellipse", [canvas.Shape, gs.Ellipse], {
-		// summary: an ellipse shape (Canvas)
+	var makeEllipse = function(shape){
+		// prepare Canvas-specific structures
+		var t, c1, c2, r = [], s = shape.shape,
+			M = m.normalize([m.translate(s.cx, s.cy), m.scale(s.rx, s.ry)]);
+		t = mp(M, bezierCircle[0]);
+		r.push([t.x, t.y]);
+		for(var i = 1; i < bezierCircle.length; i += 3){
+			c1 = mp(M, bezierCircle[i]);
+			c2 = mp(M, bezierCircle[i + 1]);
+			t  = mp(M, bezierCircle[i + 2]);
+			r.push([c1.x, c1.y, c2.x, c2.y, t.x, t.y]);
+		}
+		if(shape._needsDash){
+			var points = [], p1 = r[0];
+			for(i = 1; i < r.length; ++i){
+				var curves = [];
+				splitToDashedBezier(p1.concat(r[i]), shape.canvasDash, curves);
+				p1 = [r[i][4],r[i][5]];
+				points.push(curves);
+			}
+			shape._dashedPoints = points;
+		}
+		return r;
+	};
+
+	canvas.Ellipse = declare("dojox.gfx.canvas.Ellipse", [canvas.Shape, gs.Ellipse], {
+		// summary:
+		//		an ellipse shape (Canvas)
 		setShape: function(){
 			this.inherited(arguments);
-			// prepare Canvas-specific structures
-			var s = this.shape, t, c1, c2, r = [],
-				M = m.normalize([m.translate(s.cx, s.cy), m.scale(s.rx, s.ry)]);
-			t = mp(M, bezierCircle[0]);
-			r.push([t.x, t.y]);
-			for(var i = 1; i < bezierCircle.length; i += 3){
-				c1 = mp(M, bezierCircle[i]);
-				c2 = mp(M, bezierCircle[i + 1]);
-				t  = mp(M, bezierCircle[i + 2]);
-				r.push([c1.x, c1.y, c2.x, c2.y, t.x, t.y]);
-			}
-			this.canvasEllipse = r;
+			this.canvasEllipse = makeEllipse(this);
+			return this;
+		},
+		setStroke: function(){
+			this.inherited(arguments);
+			if(!hasNativeDash){
+				this.canvasEllipse = makeEllipse(this);
+			}
 			return this;
 		},
 		_renderShape: function(/* Object */ ctx){
-			var r = this.canvasEllipse;
+			var r = this.canvasEllipse, i;
 			ctx.beginPath();
 			ctx.moveTo.apply(ctx, r[0]);
-			for(var i = 1; i < r.length; ++i){
+			for(i = 1; i < r.length; ++i){
 				ctx.bezierCurveTo.apply(ctx, r[i]);
 			}
 			ctx.closePath();
+		},
+		_renderDashedStroke: function(ctx, apply){
+			var r = this._dashedPoints;
+			ctx.beginPath();
+			for(var i = 0; i < r.length; ++i){
+				var curves = r[i];
+				for(var j=0;j<curves.length;++j){
+					var curve = curves[j];
+					ctx.moveTo(curve[0], curve[1]);
+					ctx.bezierCurveTo(curve[2],curve[3],curve[4],curve[5],curve[6],curve[7]);
+				}
+			}
+			if(apply) ctx.stroke();
 		}
 	});
 
-	declare("dojox.gfx.canvas.Circle", [canvas.Shape, gs.Circle], {
-		// summary: a circle shape (Canvas)
+	canvas.Circle = declare("dojox.gfx.canvas.Circle", [canvas.Shape, gs.Circle], {
+		// summary:
+		//		a circle shape (Canvas)
 		_renderShape: function(/* Object */ ctx){
 			var s = this.shape;
 			ctx.beginPath();
 			ctx.arc(s.cx, s.cy, s.r, 0, twoPI, 1);
+		},
+		_renderDashedStroke: function(ctx, apply){
+			var s = this.shape;
+			var startAngle = 0, angle, l = this.canvasDash.length; i=0;
+			while(startAngle < twoPI){
+				angle = this.canvasDash[i%l]/s.r;
+				if(!(i%2)){
+					ctx.beginPath();
+					ctx.arc(s.cx, s.cy, s.r, startAngle, startAngle+angle, 0);
+					if(apply) ctx.stroke();
+				}
+				startAngle+=angle;
+				++i;
+			}
 		}
 	});
 
-	declare("dojox.gfx.canvas.Line", [canvas.Shape, gs.Line], {
-		// summary: a line shape (Canvas)
+	canvas.Line = declare("dojox.gfx.canvas.Line", [canvas.Shape, gs.Line], {
+		// summary:
+		//		a line shape (Canvas)
 		_renderShape: function(/* Object */ ctx){
 			var s = this.shape;
 			ctx.beginPath();
 			ctx.moveTo(s.x1, s.y1);
 			ctx.lineTo(s.x2, s.y2);
+		},
+		_renderDashedStroke: function(ctx, apply){
+			var s = this.shape;
+			ctx.beginPath();
+			toDashedLineTo(ctx, this, s.x1, s.y1, s.x2, s.y2);
+			if(apply) ctx.stroke();
 		}
 	});
 
-	declare("dojox.gfx.canvas.Polyline", [canvas.Shape, gs.Polyline], {
-		// summary: a polyline/polygon shape (Canvas)
+	canvas.Polyline = declare("dojox.gfx.canvas.Polyline", [canvas.Shape, gs.Polyline], {
+		// summary:
+		//		a polyline/polygon shape (Canvas)
 		setShape: function(){
 			this.inherited(arguments);
 			var p = this.shape.points, f = p[0], r, c, i;
 			this.bbox = null;
 			// normalize this.shape.points as array of points: [{x,y}, {x,y}, ...]
-			this._normalizePoints();			
-			// after _normalizePoints, if shape.points was [x1,y1,x2,y2,..], shape.points references a new array 
+			this._normalizePoints();
+			// after _normalizePoints, if shape.points was [x1,y1,x2,y2,..], shape.points references a new array
 			// and p references the original points array
 			// prepare Canvas-specific structures, if needed
-			if(p.length){  
+			if(p.length){
 				if(typeof f == "number"){ // already in the canvas format [x1,y1,x2,y2,...]
-					r = p; 
+					r = p;
 				}else{ // convert into canvas-specific format
 					r = [];
 					for(i=0; i < p.length; ++i){
@@ -323,11 +637,20 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 					ctx.lineTo(p[i], p[i + 1]);
 				}
 			}
+		},
+		_renderDashedStroke: function(ctx, apply){
+			var p = this.canvasPolyline, residue = 0;
+			ctx.beginPath();
+			for(var i = 0; i < p.length; i += 2){
+				residue = toDashedLineTo(ctx, this, p[i], p[i + 1], p[i + 2], p[i + 3], residue);
+			}
+			if(apply) ctx.stroke();
 		}
 	});
 
-	declare("dojox.gfx.canvas.Image", [canvas.Shape, gs.Image], {
-		// summary: an image shape (Canvas)
+	canvas.Image = declare("dojox.gfx.canvas.Image", [canvas.Shape, gs.Image], {
+		// summary:
+		//		an image shape (Canvas)
 		setShape: function(){
 			this.inherited(arguments);
 			// prepare Canvas-specific structures
@@ -341,20 +664,21 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 			ctx.drawImage(this.canvasImage, s.x, s.y, s.width, s.height);
 		}
 	});
-	
-	declare("dojox.gfx.canvas.Text", [canvas.Shape, gs.Text], {
+
+	canvas.Text = declare("dojox.gfx.canvas.Text", [canvas.Shape, gs.Text], {
 		_setFont:function(){
-			if (this.fontStyle){
+			if(this.fontStyle){
 				this.canvasFont = g.makeFontString(this.fontStyle);
-			} else {
+			}else{
 				delete this.canvasFont;
 			}
 		},
-		
+
 		getTextWidth: function(){
-			// summary: get the text width in pixels
+			// summary:
+			//		get the text width in pixels
 			var s = this.shape, w = 0, ctx;
-			if(s.text && s.text.length > 0){
+			if(s.text){
 				ctx = this.surface.rawNode.getContext("2d");
 				ctx.save();
 				this._renderTransform(ctx);
@@ -367,13 +691,15 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 			}
 			return w;
 		},
-		
+
 		// override to apply first fill and stroke (
 		// the base implementation is for path-based shape that needs to first define the path then to fill/stroke it.
 		// Here, we need the fillstyle or strokestyle to be set before calling fillText/strokeText.
 		_render: function(/* Object */ctx){
-			// summary: render the shape
-			// ctx : Object: the drawing context.
+			// summary:
+			//		render the shape
+			// ctx: Object
+			//		the drawing context.
 			ctx.save();
 			this._renderTransform(ctx);
 			this._renderFill(ctx, false);
@@ -381,12 +707,14 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 			this._renderShape(ctx);
 			ctx.restore();
 		},
-		
+
 		_renderShape: function(ctx){
-			// summary: a text shape (Canvas)
-			// ctx : Object: the drawing context.
+			// summary:
+			//		a text shape (Canvas)
+			// ctx: Object
+			//		the drawing context.
 			var ta, s = this.shape;
-			if(!s.text || s.text.length == 0){
+			if(!s.text){
 				return;
 			}
 			// text align
@@ -406,22 +734,19 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 		}
 	});
 	modifyMethod(canvas.Text, "setFont");
-	
-	// the next test is from https://github.com/phiggins42/has.js
-	if(win.global.CanvasRenderingContext2D){
-		// need to doublecheck canvas is supported since module can be loaded if building layers (ticket 14288)
-		var ctx2d = win.doc.createElement("canvas").getContext("2d");
-		if(ctx2d && typeof ctx2d.fillText != "function"){
-			canvas.Text.extend({
-				getTextWidth: function(){
-					return 0;
-				},
-				_renderShape: function(){
-				}
-			});
-		}
+
+	if(!hasFillText){
+		canvas.Text.extend({
+			getTextWidth: function(){
+				return 0;
+			},
+			getBoundingBox: function(){
+				return null;
+			},
+			_renderShape: function(){
+			}
+		});
 	}
-	
 
 	var pathRenderers = {
 			M: "_moveToA", m: "_moveToR",
@@ -436,18 +761,33 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 			Z: "_closePath", z: "_closePath"
 		};
 
-	declare("dojox.gfx.canvas.Path", [canvas.Shape, pathLib.Path], {
-		// summary: a path shape (Canvas)
+
+	canvas.Path = declare("dojox.gfx.canvas.Path", [canvas.Shape, pathLib.Path], {
+		// summary:
+		//		a path shape (Canvas)
 		constructor: function(){
 			this.lastControl = {};
 		},
 		setShape: function(){
 			this.canvasPath = [];
+			this._dashedPath= [];
 			return this.inherited(arguments);
 		},
+		setStroke:function(){
+			this.inherited(arguments);
+			if(!hasNativeDash){
+				this.segmented = false;
+				this._confirmSegmented();
+			}
+			return this;
+		},
+		_setPath: function(){
+			this._dashResidue = null;
+			this.inherited(arguments);
+		},
 		_updateWithSegment: function(segment){
 			var last = lang.clone(this.last);
-			this[pathRenderers[segment.action]](this.canvasPath, segment.action, segment.args);
+			this[pathRenderers[segment.action]](this.canvasPath, segment.action, segment.args, this._needsDash ? this._dashedPath : null);
 			this.last = last;
 			this.inherited(arguments);
 		},
@@ -458,69 +798,101 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 				ctx[r[i]].apply(ctx, r[i + 1]);
 			}
 		},
-		_moveToA: function(result, action, args){
+		_renderDashedStroke: hasNativeDash ? function(){} : function(ctx, apply){
+			var r = this._dashedPath;
+			ctx.beginPath();
+			for(var i = 0; i < r.length; i += 2){
+				ctx[r[i]].apply(ctx, r[i + 1]);
+			}
+			if(apply) ctx.stroke();
+		},
+		_moveToA: function(result, action, args, doDash){
 			result.push("moveTo", [args[0], args[1]]);
+			if(doDash) doDash.push("moveTo", [args[0], args[1]]);
 			for(var i = 2; i < args.length; i += 2){
 				result.push("lineTo", [args[i], args[i + 1]]);
+				if(doDash)
+					this._dashResidue = toDashedLineTo(doDash, this, args[i - 2], args[i - 1], args[i], args[i + 1], this._dashResidue);
 			}
 			this.last.x = args[args.length - 2];
 			this.last.y = args[args.length - 1];
 			this.lastControl = {};
 		},
-		_moveToR: function(result, action, args){
+		_moveToR: function(result, action, args, doDash){
+			var pts;
 			if("x" in this.last){
-				result.push("moveTo", [this.last.x += args[0], this.last.y += args[1]]);
+				pts = [this.last.x += args[0], this.last.y += args[1]];
+				result.push("moveTo", pts);
+				if(doDash) doDash.push("moveTo", pts);
 			}else{
-				result.push("moveTo", [this.last.x = args[0], this.last.y = args[1]]);
+				pts = [this.last.x = args[0], this.last.y = args[1]];
+				result.push("moveTo", pts);
+				if(doDash) doDash.push("moveTo", pts);
 			}
 			for(var i = 2; i < args.length; i += 2){
 				result.push("lineTo", [this.last.x += args[i], this.last.y += args[i + 1]]);
+				if(doDash)
+					this._dashResidue = toDashedLineTo(doDash, this, doDash[doDash.length - 1][0], doDash[doDash.length - 1][1], this.last.x, this.last.y, this._dashResidue);
 			}
 			this.lastControl = {};
 		},
-		_lineToA: function(result, action, args){
+		_lineToA: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; i += 2){
+				if(doDash)
+					this._dashResidue = toDashedLineTo(doDash, this, this.last.x, this.last.y, args[i], args[i + 1], this._dashResidue);
 				result.push("lineTo", [args[i], args[i + 1]]);
 			}
 			this.last.x = args[args.length - 2];
 			this.last.y = args[args.length - 1];
 			this.lastControl = {};
 		},
-		_lineToR: function(result, action, args){
+		_lineToR: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; i += 2){
 				result.push("lineTo", [this.last.x += args[i], this.last.y += args[i + 1]]);
+				if(doDash)
+					this._dashResidue = toDashedLineTo(doDash, this, doDash[doDash.length - 1][0], doDash[doDash.length - 1][1], this.last.x, this.last.y, this._dashResidue);
 			}
 			this.lastControl = {};
 		},
-		_hLineToA: function(result, action, args){
+		_hLineToA: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; ++i){
 				result.push("lineTo", [args[i], this.last.y]);
+				if(doDash)
+					this._dashResidue = toDashedLineTo(doDash, this, doDash[doDash.length - 1][0], doDash[doDash.length - 1][1], args[i], this.last.y, this._dashResidue);
 			}
 			this.last.x = args[args.length - 1];
 			this.lastControl = {};
 		},
-		_hLineToR: function(result, action, args){
+		_hLineToR: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; ++i){
 				result.push("lineTo", [this.last.x += args[i], this.last.y]);
+				if(doDash)
+					this._dashResidue = toDashedLineTo(doDash, this, doDash[doDash.length - 1][0], doDash[doDash.length - 1][1], this.last.x, this.last.y, this._dashResidue);
 			}
 			this.lastControl = {};
 		},
-		_vLineToA: function(result, action, args){
+		_vLineToA: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; ++i){
 				result.push("lineTo", [this.last.x, args[i]]);
+				if(doDash)
+					this._dashResidue = toDashedLineTo(doDash, this, doDash[doDash.length - 1][0], doDash[doDash.length - 1][1], this.last.x, args[i], this._dashResidue);
 			}
 			this.last.y = args[args.length - 1];
 			this.lastControl = {};
 		},
-		_vLineToR: function(result, action, args){
+		_vLineToR: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; ++i){
 				result.push("lineTo", [this.last.x, this.last.y += args[i]]);
+				if(doDash)
+					this._dashResidue = toDashedLineTo(doDash, this, doDash[doDash.length - 1][0], doDash[doDash.length - 1][1], this.last.x, this.last.y, this._dashResidue);
 			}
 			this.lastControl = {};
 		},
-		_curveToA: function(result, action, args){
+		_curveToA: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; i += 6){
 				result.push("bezierCurveTo", args.slice(i, i + 6));
+				if(doDash)
+					this._dashResidue = toDashedCurveTo(doDash, this, result[result.length-1], this._dashResidue);
 			}
 			this.last.x = args[args.length - 2];
 			this.last.y = args[args.length - 1];
@@ -528,7 +900,7 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 			this.lastControl.y = args[args.length - 3];
 			this.lastControl.type = "C";
 		},
-		_curveToR: function(result, action, args){
+		_curveToR: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; i += 6){
 				result.push("bezierCurveTo", [
 					this.last.x + args[i],
@@ -538,12 +910,14 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 					this.last.x + args[i + 4],
 					this.last.y + args[i + 5]
 				]);
+				if(doDash)
+					this._dashResidue = toDashedCurveTo(doDash, this, result[result.length-1], this._dashResidue);
 				this.last.x += args[i + 4];
 				this.last.y += args[i + 5];
 			}
 			this.lastControl.type = "C";
 		},
-		_smoothCurveToA: function(result, action, args){
+		_smoothCurveToA: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; i += 4){
 				var valid = this.lastControl.type == "C";
 				result.push("bezierCurveTo", [
@@ -554,6 +928,8 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 					args[i + 2],
 					args[i + 3]
 				]);
+				if(doDash)
+					this._dashResidue = toDashedCurveTo(doDash, this, result[result.length-1], this._dashResidue);
 				this.lastControl.x = args[i];
 				this.lastControl.y = args[i + 1];
 				this.lastControl.type = "C";
@@ -561,7 +937,7 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 			this.last.x = args[args.length - 2];
 			this.last.y = args[args.length - 1];
 		},
-		_smoothCurveToR: function(result, action, args){
+		_smoothCurveToR: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; i += 4){
 				var valid = this.lastControl.type == "C";
 				result.push("bezierCurveTo", [
@@ -572,6 +948,8 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 					this.last.x + args[i + 2],
 					this.last.y + args[i + 3]
 				]);
+				if(doDash)
+					this._dashResidue = toDashedCurveTo(doDash, this, result[result.length-1], this._dashResidue);
 				this.lastControl.x = this.last.x + args[i];
 				this.lastControl.y = this.last.y + args[i + 1];
 				this.lastControl.type = "C";
@@ -579,17 +957,19 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 				this.last.y += args[i + 3];
 			}
 		},
-		_qCurveToA: function(result, action, args){
+		_qCurveToA: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; i += 4){
 				result.push("quadraticCurveTo", args.slice(i, i + 4));
 			}
+			if(doDash)
+				this._dashResidue = toDashedCurveTo(doDash, this, result[result.length - 1], this._dashResidue);
 			this.last.x = args[args.length - 2];
 			this.last.y = args[args.length - 1];
 			this.lastControl.x = args[args.length - 4];
 			this.lastControl.y = args[args.length - 3];
 			this.lastControl.type = "Q";
 		},
-		_qCurveToR: function(result, action, args){
+		_qCurveToR: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; i += 4){
 				result.push("quadraticCurveTo", [
 					this.lastControl.x = this.last.x + args[i],
@@ -597,12 +977,14 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 					this.last.x + args[i + 2],
 					this.last.y + args[i + 3]
 				]);
+				if(doDash)
+					this._dashResidue = toDashedCurveTo(doDash, this, result[result.length - 1], this._dashResidue);
 				this.last.x += args[i + 2];
 				this.last.y += args[i + 3];
 			}
 			this.lastControl.type = "Q";
 		},
-		_qSmoothCurveToA: function(result, action, args){
+		_qSmoothCurveToA: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; i += 2){
 				var valid = this.lastControl.type == "Q";
 				result.push("quadraticCurveTo", [
@@ -611,12 +993,14 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 					args[i],
 					args[i + 1]
 				]);
+				if(doDash)
+					this._dashResidue = toDashedCurveTo(doDash, this, result[result.length - 1], this._dashResidue);
 				this.lastControl.type = "Q";
 			}
 			this.last.x = args[args.length - 2];
 			this.last.y = args[args.length - 1];
 		},
-		_qSmoothCurveToR: function(result, action, args){
+		_qSmoothCurveToR: function(result, action, args, doDash){
 			for(var i = 0; i < args.length; i += 2){
 				var valid = this.lastControl.type == "Q";
 				result.push("quadraticCurveTo", [
@@ -625,12 +1009,14 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 					this.last.x + args[i],
 					this.last.y + args[i + 1]
 				]);
+				if(doDash)
+					this._dashResidue = toDashedCurveTo(doDash, this, result[result.length - 1], this._dashResidue);
 				this.lastControl.type = "Q";
 				this.last.x += args[i];
 				this.last.y += args[i + 1];
 			}
 		},
-		_arcTo: function(result, action, args){
+		_arcTo: function(result, action, args, doDash){
 			var relative = action == "a";
 			for(var i = 0; i < args.length; i += 7){
 				var x1 = args[i + 5], y1 = args[i + 6];
@@ -646,13 +1032,17 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 				arr.forEach(arcs, function(p){
 					result.push("bezierCurveTo", p);
 				});
+				if(doDash)
+					this._dashResidue = toDashedCurveTo(doDash, this, p, this._dashResidue);
 				this.last.x = x1;
 				this.last.y = y1;
 			}
 			this.lastControl = {};
 		},
-		_closePath: function(result, action, args){
+		_closePath: function(result, action, args, doDash){
 			result.push("closePath", []);
+			if(doDash)
+				this._dashResidue = toDashedLineTo(doDash, this, this.last.x, this.last.y, doDash[1][0], doDash[1][1], this._dashResidue);
 			this.lastControl = {};
 		}
 	});
@@ -661,8 +1051,9 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 		function(method){ modifyMethod(canvas.Path, method); }
 	);
 
-	declare("dojox.gfx.canvas.TextPath", [canvas.Shape, pathLib.TextPath], {
-		// summary: a text shape (Canvas)
+	canvas.TextPath = declare("dojox.gfx.canvas.TextPath", [canvas.Shape, pathLib.TextPath], {
+		// summary:
+		//		a text shape (Canvas)
 		_renderShape: function(/* Object */ ctx){
 			var s = this.shape;
 			// nothing for the moment
@@ -675,17 +1066,25 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 		}
 	});
 
-	declare("dojox.gfx.canvas.Surface", gs.Surface, {
-		// summary: a surface object to be used for drawings (Canvas)
+	canvas.Surface = declare("dojox.gfx.canvas.Surface", gs.Surface, {
+		// summary:
+		//		a surface object to be used for drawings (Canvas)
 		constructor: function(){
 			gs.Container._init.call(this);
 			this.pendingImageCount = 0;
 			this.makeDirty();
 		},
+		destroy: function(){
+			gs.Container.clear.call(this, true); // avoid makeDirty() from canvas.Container.clear impl.
+			this.inherited(arguments);
+		},
 		setDimensions: function(width, height){
-			// summary: sets the width and height of the rawNode
-			// width: String: width of surface, e.g., "100px"
-			// height: String: height of surface, e.g., "100px"
+			// summary:
+			//		sets the width and height of the rawNode
+			// width: String
+			//		width of surface, e.g., "100px"
+			// height: String
+			//		height of surface, e.g., "100px"
 			this.width  = g.normalizedLength(width);	// in pixels
 			this.height = g.normalizedLength(height);	// in pixels
 			if(!this.rawNode) return this;
@@ -703,36 +1102,51 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 			return this;	// self
 		},
 		getDimensions: function(){
-			// summary: returns an object with properties "width" and "height"
+			// summary:
+			//		returns an object with properties "width" and "height"
 			return this.rawNode ? {width:  this.rawNode.width, height: this.rawNode.height} : null;	// Object
 		},
-		_render: function(){
-			// summary: render the all shapes
-			if(this.pendingImageCount){ return; }
+		_render: function(force){
+			// summary:
+			//		render the all shapes
+			if(!force && this.pendingImageCount){ return; }
 			var ctx = this.rawNode.getContext("2d");
-			ctx.save();
 			ctx.clearRect(0, 0, this.rawNode.width, this.rawNode.height);
-			for(var i = 0; i < this.children.length; ++i){
-				this.children[i]._render(ctx);
-			}
-			ctx.restore();
+			this.render(ctx);
 			if("pendingRender" in this){
 				clearTimeout(this.pendingRender);
 				delete this.pendingRender;
 			}
 		},
+		render: function(ctx){
+			// summary:
+			//		Renders the gfx scene.
+			// description:
+			//		this method is called to render the gfx scene to the specified context.
+			//		This method should not be invoked directly but should be used instead
+			//		as an extension point on which user can connect to with aspect.before/aspect.after
+			//		to implement pre- or post- image processing jobs on the drawing surface.
+			// ctx: CanvasRenderingContext2D
+			//		The surface Canvas rendering context.
+			ctx.save();
+			for(var i = 0; i < this.children.length; ++i){
+				this.children[i]._render(ctx);
+			}
+			ctx.restore();
+		},
 		makeDirty: function(){
-			// summary: internal method, which is called when we may need to redraw
-			if(!this.pendingImagesCount && !("pendingRender" in this)){
+			// summary:
+			//		internal method, which is called when we may need to redraw
+			if(!this.pendingImagesCount && !("pendingRender" in this) && !this._batch){
 				this.pendingRender = setTimeout(lang.hitch(this, this._render), 0);
 			}
 		},
 		downloadImage: function(img, url){
 			// summary:
 			//		internal method, which starts an image download and renders, when it is ready
-			// img: Image:
+			// img: Image
 			//		the image object
-			// url: String:
+			// url: String
 			//		the url of the image
 			var handler = lang.hitch(this, this.onImageLoad);
 			if(!this.pendingImageCount++ && "pendingRender" in this){
@@ -745,20 +1159,36 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 			img.src = url;
 		},
 		onImageLoad: function(){
-			if(!--this.pendingImageCount){ this._render(); }
+			if(!--this.pendingImageCount){
+				this.onImagesLoaded();
+				this._render();
+			}
+		},
+		onImagesLoaded: function(){
+			// summary:
+			//		An extension point called when all pending images downloads have been completed.
+			// description:
+			//		This method is invoked when all pending images downloads have been completed, just before
+			//		the gfx scene is redrawn. User can connect to this method to get notified when a
+			//		gfx scene containing images is fully resolved.
 		},
 
 		// events are not implemented
 		getEventSource: function(){ return null; },
 		connect:		function(){},
-		disconnect:		function(){}
+		disconnect:		function(){},
+		on:				function(){}
 	});
 
 	canvas.createSurface = function(parentNode, width, height){
-		// summary: creates a surface (Canvas)
-		// parentNode: Node: a parent node
-		// width: String: width of surface, e.g., "100px"
-		// height: String: height of surface, e.g., "100px"
+		// summary:
+		//		creates a surface (Canvas)
+		// parentNode: Node
+		//		a parent node
+		// width: String
+		//		width of surface, e.g., "100px"
+		// height: String
+		//		height of surface, e.g., "100px"
 
 		if(!width && !height){
 			var pos = domGeom.position(parentNode);
@@ -783,46 +1213,76 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 		s.rawNode = c;
 		s._parent = p;
 		s.surface = s;
-		return s;	// dojox.gfx.Surface
+		return s;	// dojox/gfx.Surface
 	};
 
 	// Extenders
 
 	var C = gs.Container, Container = {
+		openBatch: function() {
+			// summary:
+			//		starts a new batch, subsequent new child shapes will be held in
+			//		the batch instead of appending to the container directly.
+			// description:
+			//		Because the canvas renderer has no DOM hierarchy, the canvas implementation differs
+			//		such that it suspends the repaint requests for this container until the current batch is closed by a call to closeBatch().
+			++this._batch;
+			return this;
+		},
+		closeBatch: function() {
+			// summary:
+			//		submits the current batch.
+			// description:
+			//		On canvas, this method flushes the pending redraws queue.
+			this._batch = this._batch > 0 ? --this._batch : 0;
+			this._makeDirty();
+			return this;
+		},
+		_makeDirty: function(){
+			if(!this._batch){
+				this.surface.makeDirty();
+			}
+		},
 		add: function(shape){
-			this.surface.makeDirty();
+			this._makeDirty();
 			return C.add.apply(this, arguments);
 		},
 		remove: function(shape, silently){
-			this.surface.makeDirty();
+			this._makeDirty();
 			return C.remove.apply(this, arguments);
 		},
 		clear: function(){
-			this.surface.makeDirty();
+			this._makeDirty();
 			return C.clear.apply(this, arguments);
 		},
+		getBoundingBox: C.getBoundingBox,
 		_moveChildToFront: function(shape){
-			this.surface.makeDirty();
+			this._makeDirty();
 			return C._moveChildToFront.apply(this, arguments);
 		},
 		_moveChildToBack: function(shape){
-			this.surface.makeDirty();
+			this._makeDirty();
 			return C._moveChildToBack.apply(this, arguments);
 		}
 	};
 
 	var Creator = {
-		// summary: Canvas shape creators
+		// summary:
+		//		Canvas shape creators
 		createObject: function(shapeType, rawShape) {
-			// summary: creates an instance of the passed shapeType class
-			// shapeType: Function: a class constructor to create an instance of
-			// rawShape: Object: properties to be passed in to the classes "setShape" method
-			// overrideSize: Boolean: set the size explicitly, if true
+			// summary:
+			//		creates an instance of the passed shapeType class
+			// shapeType: Function
+			//		a class constructor to create an instance of
+			// rawShape: Object
+			//		properties to be passed in to the classes "setShape" method
+			// overrideSize: Boolean
+			//		set the size explicitly, if true
 			var shape = new shapeType();
 			shape.surface = this.surface;
 			shape.setShape(rawShape);
 			this.add(shape);
-			return shape;	// dojox.gfx.Shape
+			return shape;	// dojox/gfx/shape.Shape
 		}
 	};
 
@@ -833,11 +1293,13 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/declare",
 	extend(canvas.Surface, Container);
 	extend(canvas.Surface, gs.Creator);
 	extend(canvas.Surface, Creator);
-	
-	// no event support -> nothing to fix. 
+
+	// no event support -> nothing to fix.
 	canvas.fixTarget = function(event, gfxElement){
+		// tags:
+		//		private
 		return true;
 	};
-	 
+
 	return canvas;
 });
diff --git a/dojox/gfx/canvasWithEvents.js b/dojox/gfx/canvasWithEvents.js
index 4a6902a..a4c2718 100644
--- a/dojox/gfx/canvasWithEvents.js
+++ b/dojox/gfx/canvasWithEvents.js
@@ -1,71 +1,84 @@
-define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_base/Color", "dojo/dom", 
-		"dojo/dom-geometry", "./_base","./canvas", "./shape", "./matrix"], 
-  function(lang, declare, hub, Color, dom, domGeom, g, canvas, shapeLib, m){
-/*===== 
-	dojox.gfx.canvasWithEvents = {
-	// module:
-	//		dojox/gfx/canvasWithEvents
-	// summary:
-	//		This the graphics rendering bridge for W3C Canvas compliant browsers which extends
-	//		the basic canvas drawing renderer bridge to add additional support for graphics events
-	//		on Shapes.
-	//		Since Canvas is an immediate mode graphics api, with no object graph or
-	//		eventing capabilities, use of the canvas module alone will only add in drawing support.
-	//		This additional module, canvasWithEvents extends this module with additional support
-	//		for handling events on Canvas.  By default, the support for events is now included 
-	//		however, if only drawing capabilities are needed, canvas event module can be disabled
-	//		using the dojoConfig option, canvasEvents:true|false.
-	//		The id of the Canvas renderer is 'canvasWithEvents'.  This id can be used when switch Dojo's
-	//		graphics context between renderer implementations.  See dojox.gfx._base switchRenderer
-	//		API.	
+define(["dojo/_base/lang", "dojo/_base/declare", "dojo/has", "dojo/on", "dojo/aspect", "dojo/touch", "dojo/_base/Color", "dojo/dom",
+		"dojo/dom-geometry", "dojo/_base/window", "./_base","./canvas", "./shape", "./matrix"],
+function(lang, declare, has, on, aspect, touch, Color, dom, domGeom, win, g, canvas, shapeLib, m){
+	function makeFakeEvent(event){
+		// summary:
+		//		Generates a "fake", fully mutable event object by copying the properties from an original host Event
+		//		object to a new standard JavaScript object.
+
+		var fakeEvent = {};
+		for(var k in event){
+			if(typeof event[k] === "function"){
+				// Methods (like preventDefault) must be invoked on the original event object, or they will not work
+				fakeEvent[k] = lang.hitch(event, k);
+			}
+			else{
+				fakeEvent[k] = event[k];
+			}
+		}
+		return fakeEvent;
+	}
+
+	// Browsers that implement the current (January 2013) WebIDL spec allow Event object properties to be mutated
+	// using Object.defineProperty; some older WebKits (Safari 6-) and at least IE10- do not follow the spec. Direct
+	// mutation is, of course, much faster when it can be done.
+    has.add("dom-mutableEvents", function(){
+        var event = document.createEvent("UIEvents");
+        try {
+            if(Object.defineProperty){
+                Object.defineProperty(event, "type", { value: "foo" });
+            }else{
+                event.type = "foo";
+            }
+            return event.type === "foo";
+        }catch(e){
+            return false;
+        }
+    });
+
+	has.add("MSPointer", navigator.msPointerEnabled);
+
+	var canvasWithEvents = g.canvasWithEvents = {
+		// summary:
+		//		This the graphics rendering bridge for W3C Canvas compliant browsers which extends
+		//		the basic canvas drawing renderer bridge to add additional support for graphics events
+		//		on Shapes.
+		//		Since Canvas is an immediate mode graphics api, with no object graph or
+		//		eventing capabilities, use of the canvas module alone will only add in drawing support.
+		//		This additional module, canvasWithEvents extends this module with additional support
+		//		for handling events on Canvas.  By default, the support for events is now included
+		//		however, if only drawing capabilities are needed, canvas event module can be disabled
+		//		using the dojoConfig option, canvasEvents:true|false.
 	};
-	g = dojox.gfx;
-	canvas.Shape = dojox.gfx.canvas.Shape;
-	canvas.Group = dojox.gfx.canvas.Group;
-	canvas.Image = dojox.gfx.canvas.Image;
-	canvas.Text = dojox.gfx.canvas.Text;
-	canvas.Rect = dojox.gfx.canvas.Rect;
-	canvas.Circle = dojox.gfx.canvas.Circle;
-	canvas.Ellipse = dojox.gfx.canvas.Ellipse;
-	canvas.Line = dojox.gfx.canvas.Line;
-	canvas.PolyLine = dojox.gfx.canvas.PolyLine;
-	canvas.TextPath = dojox.gfx.canvas.TextPath;
-	canvas.Path = dojox.gfx.canvas.Path;
-	canvas.Surface = dojox.gfx.canvas.Surface;
-	canvasEvent.Shape = dojox.gfx.canvasWithEvents.Shape;
-	
-  =====*/
-	var canvasEvent = g.canvasWithEvents = {};
-
-	declare("dojox.gfx.canvasWithEvents.Shape", canvas.Shape, {
-		
-		_testInputs: function(/* Object */ctx, /* Array */ pos){
-			if (!this.canvasFill && this.strokeStyle) {
+
+	canvasWithEvents.Shape = declare("dojox.gfx.canvasWithEvents.Shape", canvas.Shape, {
+		_testInputs: function(/* Object */ ctx, /* Array */ pos){
+			if(this.clip || (!this.canvasFill && this.strokeStyle)){
 				// pixel-based until a getStrokedPath-like api is available on the path
 				this._hitTestPixel(ctx, pos);
-			} else {
+			}else{
 				this._renderShape(ctx);
-				var cnt = pos.length, t = this.getTransform();
-				for (var i = 0; i < pos.length; ++i) {
+				var length = pos.length,
+					t = this.getTransform();
+
+				for(var i = 0; i < length; ++i){
 					var input = pos[i];
 					// already hit
-					if (input.target) 
-						continue;
-					var x = input.x, y = input.y;
-					var p = t ? m.multiplyPoint(m.invert(t), x, y) : {
-						x: x,
-						y: y
-					};
+					if(input.target){continue;}
+					var x = input.x,
+						y = input.y,
+						p = t ? m.multiplyPoint(m.invert(t), x, y) : { x: x, y: y };
 					input.target = this._hitTestGeometry(ctx, p.x, p.y);
 				}
 			}
 		},
-		_hitTestPixel: function(/* Object */ctx, /* Array */ pos){
-			for (var i = 0; i < pos.length; ++i) {
+
+		_hitTestPixel: function(/* Object */ ctx, /* Array */ pos){
+			for(var i = 0; i < pos.length; ++i){
 				var input = pos[i];
-				if (input.target) 
-					continue;
-				var x = input.x, y = input.y;
+				if(input.target){continue;}
+				var x = input.x,
+					y = input.y;
 				ctx.clearRect(0,0,1,1);
 				ctx.save();
 				ctx.translate(-x, -y);
@@ -74,10 +87,11 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 				ctx.restore();
 			}
 		},
+
 		_hitTestGeometry: function(ctx, x, y){
 			return ctx.isPointInPath(x, y) ? this : null;
-		},		
-		
+		},
+
 		_renderFill: function(/* Object */ ctx, /* Boolean */ apply){
 			// summary:
 			//		render fill for the shape
@@ -86,93 +100,94 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 			// apply:
 			//		whether ctx.fill() shall be called
 			if(ctx.pickingMode){
-				if("canvasFill" in this && apply){ ctx.fill(); }
+				if("canvasFill" in this && apply){
+					ctx.fill();
+				}
 				return;
 			}
 			this.inherited(arguments);
 		},
-		_renderStroke: function(/* Object */ ctx, /* Boolean */ apply){
+
+		_renderStroke: function(/* Object */ ctx){
 			// summary:
 			//		render stroke for the shape
 			// ctx:
 			//		a canvas context object
 			// apply:
 			//		whether ctx.stroke() shall be called
-			if (this.strokeStyle && ctx.pickingMode) {
+			if(this.strokeStyle && ctx.pickingMode){
 				var c = this.strokeStyle.color;
-				try {
+				try{
 					this.strokeStyle.color = new Color(ctx.strokeStyle);
 					this.inherited(arguments);
-				} finally {
+				}finally{
 					this.strokeStyle.color = c;
 				}
-			} else{
-				this.inherited(arguments);				
+			}else{
+				this.inherited(arguments);
 			}
 		},
-		
+
 		// events
-		
+
 		getEventSource: function(){
-			// summary: returns this gfx shape event source, which is the surface rawnode in the case of canvas.
-			
-			return this.surface.getEventSource();
+			return this.surface.rawNode;
 		},
-		
-		connect: function(name, object, method){
-			// summary: connects a handler to an event on this shape
-			this.surface._setupEvents(name); // setup events on demand
-			// No need to fix callback. The listeners registered by
-			// '_setupEvents()' are always invoked first and they
-			// already 'fix' the event
-			return arguments.length > 2 ? // Object
-					 hub.connect(this, name, object, method) : hub.connect(this, name, object);
+
+		on: function(type, listener){
+			// summary:
+			//		Connects an event to this shape.
+
+			var expectedTarget = this.rawNode;
+
+			// note that event listeners' targets are automatically fixed up in the canvas's addEventListener method
+			return on(this.getEventSource(), type, function(event){
+				if(dom.isDescendant(event.target, expectedTarget)){
+					listener.apply(expectedTarget, arguments);
+				}
+			});
 		},
-		disconnect: function(token){
-			// summary: disconnects an event handler
-			hub.disconnect(token);
+
+		connect: function(name, object, method){
+			// summary:
+			//		Deprecated. Connects a handler to an event on this shape. Use `on` instead.
+
+			if(name.substring(0, 2) == "on"){
+				name = name.substring(2);
+			}
+			return this.on(name, method ? lang.hitch(object, method) : lang.hitch(null, object));
 		},
-		// connect hook
-		oncontextmenu:  function(){},
-		onclick:        function(){},
-		ondblclick:     function(){},
-		onmouseenter:   function(){},
-		onmouseleave:   function(){},
-		onmouseout:     function(){},
-		onmousedown:    function(){},
-		ontouchstart:   function(){},
-		touchstart:     function(){},
-		onmouseup:      function(){},
-		ontouchend:     function(){},
-		touchend:       function(){},
-		onmouseover:    function(){},
-		onmousemove:    function(){},
-		ontouchmove:    function(){},
-		touchmove:      function(){},
-		onkeydown:      function(){},
-		onkeyup:        function(){}
+
+		disconnect: function(handle){
+			// summary:
+			//		Deprecated. Disconnects an event handler. Use `handle.remove` instead.
+
+			handle.remove();
+		}
 	});
-	
-	declare("dojox.gfx.canvasWithEvents.Group", [canvasEvent.Shape, canvas.Group], {
-		_testInputs: function(/*Object*/ctx, /*Array*/ pos){
-			var children = this.children, t = this.getTransform(), i, j;
-			if(children.length == 0){
+
+	canvasWithEvents.Group = declare("dojox.gfx.canvasWithEvents.Group", [canvasWithEvents.Shape, canvas.Group], {
+		_testInputs: function(/*Object*/ ctx, /*Array*/ pos){
+			var children = this.children,
+				t = this.getTransform(),
+				i,
+				j,
+				input;
+
+			if(children.length === 0){
 				return;
 			}
 			var posbk = [];
 			for(i = 0; i < pos.length; ++i){
-				var input = pos[i];
+				input = pos[i];
 				// backup position before transform applied
 				posbk[i] = {
 					x: input.x,
 					y: input.y
 				};
-				if(input.target) continue;
+				if(input.target){continue;}
 				var x = input.x, y = input.y;
-				var p = t ? m.multiplyPoint(m.invert(t), x, y) : {
-					x: x,
-					y: y
-				};
+				var p = t ? m.multiplyPoint(m.invert(t), x, y) : { x: x, y: y };
 				input.x = p.x;
 				input.y = p.y;
 			}
@@ -190,14 +205,34 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 					break;
 				}
 			}
-			for(i = 0; i < pos.length; ++i){
-				pos[i].x = posbk[i].x;
-				pos[i].y = posbk[i].y;
-			}	
-		}	
+			if(this.clip){
+				// filter positive hittests against the group clipping area
+				for(i = 0; i < pos.length; ++i){
+					input = pos[i];
+					input.x = posbk[i].x;
+					input.y = posbk[i].y;
+					if(input.target){
+						ctx.clearRect(0,0,1,1);
+						ctx.save();
+						ctx.translate(-input.x, -input.y);
+						this._render(ctx, true);
+						if(!ctx.getImageData(0, 0, 1, 1).data[0]){
+							input.target = null;
+						}
+						ctx.restore();
+					}
+				}
+			}else{
+				for(i = 0; i < pos.length; ++i){
+					pos[i].x = posbk[i].x;
+					pos[i].y = posbk[i].y;
+				}
+			}
+		}
+
 	});
-	
-	declare("dojox.gfx.canvasWithEvents.Image", [canvasEvent.Shape, canvas.Image], {
+
+	canvasWithEvents.Image = declare("dojox.gfx.canvasWithEvents.Image", [canvasWithEvents.Shape, canvas.Image], {
 		_renderShape: function(/* Object */ ctx){
 			// summary:
 			//		render image
@@ -210,433 +245,417 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/connect", "dojo/_ba
 				this.inherited(arguments);
 			}
 		},
-		
 		_hitTestGeometry: function(ctx, x, y){
 			// TODO: improve hit testing to take into account transparency
 			var s = this.shape;
 			return x >= s.x && x <= s.x + s.width && y >= s.y && y <= s.y + s.height ? this : null;
 		}
 	});
-	
-	declare("dojox.gfx.canvasWithEvents.Text", [canvasEvent.Shape, canvas.Text], {
+
+	canvasWithEvents.Text = declare("dojox.gfx.canvasWithEvents.Text", [canvasWithEvents.Shape, canvas.Text], {
 		_testInputs: function(ctx, pos){
 			return this._hitTestPixel(ctx, pos);
 		}
 	});
 
+	canvasWithEvents.Rect = declare("dojox.gfx.canvasWithEvents.Rect", [canvasWithEvents.Shape, canvas.Rect], {});
+	canvasWithEvents.Circle = declare("dojox.gfx.canvasWithEvents.Circle", [canvasWithEvents.Shape, canvas.Circle], {});
+	canvasWithEvents.Ellipse = declare("dojox.gfx.canvasWithEvents.Ellipse", [canvasWithEvents.Shape, canvas.Ellipse],{});
+	canvasWithEvents.Line = declare("dojox.gfx.canvasWithEvents.Line", [canvasWithEvents.Shape, canvas.Line],{});
+	canvasWithEvents.Polyline = declare("dojox.gfx.canvasWithEvents.Polyline", [canvasWithEvents.Shape, canvas.Polyline],{});
+	canvasWithEvents.Path = declare("dojox.gfx.canvasWithEvents.Path", [canvasWithEvents.Shape, canvas.Path],{});
+	canvasWithEvents.TextPath = declare("dojox.gfx.canvasWithEvents.TextPath", [canvasWithEvents.Shape, canvas.TextPath],{});
 
-	declare("dojox.gfx.canvasWithEvents.Rect", [canvasEvent.Shape, canvas.Rect], {});
-	declare("dojox.gfx.canvasWithEvents.Circle", [canvasEvent.Shape, canvas.Circle], {});
-	declare("dojox.gfx.canvasWithEvents.Ellipse", [canvasEvent.Shape, canvas.Ellipse],{});
-	declare("dojox.gfx.canvasWithEvents.Line", [canvasEvent.Shape, canvas.Line],{});
-	declare("dojox.gfx.canvasWithEvents.Polyline", [canvasEvent.Shape, canvas.Polyline],{});
-	declare("dojox.gfx.canvasWithEvents.Path", [canvasEvent.Shape, canvas.Path],{});
-	declare("dojox.gfx.canvasWithEvents.TextPath", [canvasEvent.Shape, canvas.TextPath],{});
-
-	
-	// a map that redirects shape-specific events to the canvas event handler that deals with these events
-	var _eventsRedirectMap = {
-		onmouseenter : 'onmousemove',
-		onmouseleave : 'onmousemove',
-		onmouseout   : 'onmousemove',
-		onmouseover  : 'onmousemove',
-		touchstart   : 'ontouchstart',
-		touchend     : 'ontouchend',
-		touchmove    : 'ontouchmove'
-	};
-	var _eventsShortNameMap = {
-		ontouchstart   : 'touchstart',
-		ontouchend     : 'touchend',
-		ontouchmove    : 'touchmove'
-	};
-	
-	var uagent = navigator.userAgent.toLowerCase(),
-		isiOS = uagent.search('iphone') > -1 || 
-			    uagent.search('ipad') > -1 || 
-				uagent.search('ipod') > -1;
-	
-	declare("dojox.gfx.canvasWithEvents.Surface", canvas.Surface, {
-		constructor:function(){
-			this._pick = { curr: null, last: null };
-			this._pickOfMouseDown = null;
-			this._pickOfMouseUp = null;
-		},
-		
-		connect: function(/*String*/name, /*Object*/object, /*Function|String*/method){
-			// summary: connects a handler to an event on this surface
-			// name : String
-			//		The event name
-			// object: Object
-			//		The object that method will receive as "this".
-			// method: Function
-			//		A function reference, or name of a function in context.
-			 
-			if (name.indexOf('touch') !== -1) {
-				// in case of surface.connect('touchXXX'...), we must root the handler to the
-				// specific touch event processing (done in fireTouchEvents) so that the event is properly configured.
-				// So, we activate the shape-level event processing calling _setupEvents,
-				// and connect to the _ontouchXXXImpl_ hooks that are called back by invokeHandler() 
-				this._setupEvents(name);
-				name = "_on" + name + "Impl_";
-				return hub.connect(this, name, object, method);
-			} else {
-				this._initMirrorCanvas();
-				return hub.connect(this.getEventSource(), name, null,
-							shapeLib.fixCallback(this, g.fixTarget, object, method));
-			}	
-		},
+	// When events are dispatched using on.emit, certain properties of these events (like target) get overwritten by
+	// the DOM. The only real way to deal with this at the moment, short of never using any standard event properties,
+	// is to store this data out-of-band and fix up the event object passed to the listener by wrapping the listener.
+	// The out-of-band data is stored here.
+	var fixedEventData = null;
 
-		// connection hooks for touch events connect
-		_ontouchstartImpl_: function(){},
-		_ontouchendImpl_:   function(){},
-		_ontouchmoveImpl_:  function(){},
-		
-		_initMirrorCanvas: function(){
-			if (!this.mirrorCanvas) {
-				var p = this._parent, mirror = p.ownerDocument.createElement("canvas");
-				mirror.width = 1;
-				mirror.height = 1;
-				mirror.style.position = 'absolute';
-				mirror.style.left = '-99999px';
-				mirror.style.top = '-99999px';
-				p.appendChild(mirror);
-				this.mirrorCanvas = mirror;
-			}
+	canvasWithEvents.Surface = declare("dojox.gfx.canvasWithEvents.Surface", canvas.Surface, {
+		constructor: function(){
+			this._elementUnderPointer = null;
 		},
 
-		_setupEvents: function(eventName){
-			// summary: 
-			//		setup event listeners if not yet
+		fixTarget: function(listener){
+			// summary:
+			//		Corrects the `target` properties of the event object passed to the actual listener.
+			// listener: Function
+			//		An event listener function.
 
-			// onmouseenter and onmouseleave shape events are handled in the onmousemove surface handler
-			if (eventName in _eventsRedirectMap)
-				eventName = _eventsRedirectMap[eventName];
-			if (this._eventsH && this._eventsH[eventName]) {
-				// the required listener has already been connected
-				return;
-			}
-			// a mirror canvas for shape picking
-			this._initMirrorCanvas();
-			if (!this._eventsH)
-				this._eventsH = {};
-			// register event hooks if not done yet
-			this._eventsH[eventName] = hub.connect(this.getEventSource(), eventName,
-					shapeLib.fixCallback(this, g.fixTarget, this, "_" + eventName));
-			if (eventName === 'onclick' || eventName==='ondblclick') {
-				if(!this._eventsH['onmousedown']){
-					this._eventsH['onmousedown'] = hub.connect(this.getEventSource(),
-							'onmousedown', shapeLib.fixCallback(this, g.fixTarget, this, "_onmousedown"));
+			var surface = this;
+
+			return function(event){
+				var k;
+				if(fixedEventData){
+					if(has("dom-mutableEvents")){
+						Object.defineProperties(event, fixedEventData);
+					}else{
+						event = makeFakeEvent(event);
+						for(k in fixedEventData){
+							event[k] = fixedEventData[k].value;
+						}
+					}
+				}else{
+					// non-synthetic events need to have target correction too, but since there is no out-of-band
+					// data we need to figure out the target ourselves
+					var canvas = surface.getEventSource(),
+						target = canvas._dojoElementFromPoint(
+							// touch events may not be fixed at this point, so clientX/Y may not be set on the
+							// event object
+							(event.changedTouches ? event.changedTouches[0] : event).pageX,
+							(event.changedTouches ? event.changedTouches[0] : event).pageY
+						);
+					if(has("dom-mutableEvents")){
+						Object.defineProperties(event, {
+							target: {
+								value: target,
+								configurable: true,
+								enumerable: true
+							},
+							gfxTarget: {
+								value: target.shape,
+								configurable: true,
+								enumerable: true
+							}
+						});
+					}else{
+						event = makeFakeEvent(event);
+						event.target = target;
+						event.gfxTarget = target.shape;
+					}
 				}
-			 	if(!this._eventsH['onmouseup']){
-					this._eventsH['onmouseup'] = hub.connect(this.getEventSource(),
-							'onmouseup', shapeLib.fixCallback(this, g.fixTarget, this, "_onmouseup"));
+
+				// fixTouchListener in dojo/on undoes target changes by copying everything from changedTouches even
+				// if the value already exists on the event; of course, this canvas implementation currently only
+				// supports one pointer at a time. if we wanted to make sure all the touches arrays' targets were
+				// updated correctly as well, we could support multi-touch and this workaround would not be needed
+				if(has("touch")){
+					// some standard properties like clientX/Y are not provided on the main touch event object,
+					// so copy them over if we need to
+					if(event.changedTouches && event.changedTouches[0]){
+						var changedTouch = event.changedTouches[0];
+						for(k in changedTouch){
+							if(!event[k]){
+								if(has("dom-mutableEvents")){
+									Object.defineProperty(event, k, {
+										value: changedTouch[k],
+										configurable: true,
+										enumerable: true
+									});
+								}else{
+									event[k] = changedTouch[k];
+								}
+							}
+						}
+					}
+					event.corrected = event;
 				}
-			} 			
-		},
-		
-		destroy: function(){
-			// summary: stops the move, deletes all references, so the object can be garbage-collected
-			canvas.Surface.destroy.apply(this);
-			
-			// destroy events and objects
-			for(var i in this._eventsH){
-				hub.disconnect(this._eventsH[i]);
-			}
-			this._eventsH = this.mirrorCanvas = null;
-		},	
-		
-		// events
-		getEventSource: function(){
-			// summary: returns the canvas DOM node for surface-level events
-			return this.rawNode;
+
+				return listener.call(this, event);
+			};
 		},
 
-		// internal handlers used to implement shape-level event notification
-		_invokeHandler: function(base, method, event){
-			// Invokes handler function
-			var handler = base[method];
-			if(handler && handler.after){
-				handler.apply(base, [event]);
-			}else if (method in _eventsShortNameMap){
-				// there may be a synonym event name (touchstart -> ontouchstart)
-				handler = base[_eventsShortNameMap[method]];
-				if(handler && handler.after){
-					handler.apply(base, [event]);
+		_checkPointer: function(event){
+			// summary:
+			//		Emits enter/leave/over/out events in response to the pointer entering/leaving the inner elements
+			//		within the canvas.
+
+			function emit(types, target, relatedTarget){
+				// summary:
+				//		Emits multiple synthetic events defined in `types` with the given target `target`.
+
+				var oldBubbles = event.bubbles;
+
+				for(var i = 0, type; (type = types[i]); ++i){
+					// targets get reset when the event is dispatched so we need to give information to fixTarget to
+					// restore the target on the dispatched event through a back channel
+					fixedEventData = {
+						target: { value: target, configurable: true, enumerable: true},
+						gfxTarget: { value: target.shape, configurable: true, enumerable: true },
+						relatedTarget: { value: relatedTarget, configurable: true, enumerable: true }
+					};
+
+					// bubbles can be set directly, though.
+					Object.defineProperty(event, "bubbles", {
+						value: type.bubbles,
+						configurable: true,
+						enumerable: true
+					});
+
+					on.emit(canvas, type.type, event);
+					fixedEventData = null;
 				}
+
+				Object.defineProperty(event, "bubbles", { value: oldBubbles, configurable: true, enumerable: true });
 			}
-			if(!handler && method.indexOf('touch') !== -1){
-				// special case for surface touch handlers
-				method = "_" + method + "Impl_";
-				handler = base[method];
-				if(handler){
-					handler.apply(base, [event]);
+
+			// Types must be arrays because hash map order is not guaranteed but we must fire in order to match normal
+			// event behaviour
+			var TYPES = {
+					out: [
+						{ type: "mouseout", bubbles: true },
+						{ type: "MSPointerOut", bubbles: true },
+						{ type: "mouseleave", bubbles: false },
+						{ type: "dojotouchout", bubbles: true}
+					],
+					over: [
+						{ type: "mouseover", bubbles: true },
+						{ type: "MSPointerOver", bubbles: true },
+						{ type: "mouseenter", bubbles: false },
+						{ type: "dojotouchover", bubbles: true}
+					]
+				},
+				elementUnderPointer = event.target,
+				oldElementUnderPointer = this._elementUnderPointer,
+				canvas = this.getEventSource();
+
+			if(oldElementUnderPointer !== elementUnderPointer){
+				if(oldElementUnderPointer && oldElementUnderPointer !== canvas){
+					emit(TYPES.out, oldElementUnderPointer, elementUnderPointer);
+				}
+
+				this._elementUnderPointer = elementUnderPointer;
+
+				if(elementUnderPointer && elementUnderPointer !== canvas){
+					emit(TYPES.over, elementUnderPointer, oldElementUnderPointer);
 				}
-			}
-			// Propagates event up in the DOM hierarchy only if event
-			// has not been stopped (event.cancelBubble is true)
-			if (!isEventStopped(event) && base.parent) {
-				this._invokeHandler(base.parent, method, event);
-			}
-		},
-		_oncontextmenu: function(e){
-			// summary: triggers onclick
-			// this._pick.curr = an array of target for touch event, one target instance for mouse events
-			if(this._pick.curr){
-				this._invokeHandler(this._pick.curr, 'oncontextmenu', e);
-			}
-		},
-		_ondblclick: function(e){
-			// summary: triggers onclick
-			// this._pick.curr = an array of target for touch event, one target instance for mouse events
-			if(this._pickOfMouseUp){
-				this._invokeHandler(this._pickOfMouseUp, 'ondblclick', e);
-			}
-		},
-		_onclick: function(e){
-			// summary: triggers onclick
-			// this._pick.curr = an array of target for touch event, one target instance for mouse events
-			if(this._pickOfMouseUp && this._pickOfMouseUp == this._pickOfMouseDown){
-				this._invokeHandler(this._pickOfMouseUp, 'onclick', e);
 			}
 		},
-		_onmousedown: function(e){
-			// summary: triggers onmousedown
-			this._pickOfMouseDown = this._pick.curr;
-			// this._pick.curr = an array of target for touch event, one target instance for mouse events
-			if(this._pick.curr){
-				this._invokeHandler(this._pick.curr, 'onmousedown', e);
-			}
+
+		getEventSource: function(){
+			return this.rawNode;
 		},
-		_ontouchstart: function(e){
-			// summary: triggers ontouchstart			
-			// this._pick.curr = an array of target for touch event, one target instance for mouse events
-			if (this._pick.curr) {
-				this._fireTouchEvent(e);
-			}
-			
+
+		on: function(type, listener){
+			// summary:
+			//		Connects an event to this surface.
+
+			return on(this.getEventSource(), type, listener);
 		},
-		_onmouseup: function(e){
-			// summary: triggers onmouseup
-			// this._pick.curr = an array of target for touch event, one target instance for mouse events
-			this._pickOfMouseUp = this._pick.curr;
-			if(this._pick.curr){
-				this._invokeHandler(this._pick.curr, 'onmouseup', e);
+
+		connect: function(/*String*/ name, /*Object*/ object, /*Function|String*/ method){
+			// summary:
+			//		Deprecated. Connects a handler to an event on this surface. Use `on` instead.
+			// name: String
+			//		The event name
+			// object: Object
+			//		The object that method will receive as "this".
+			// method: Function
+			//		A function reference, or name of a function in context.
+
+			if(name.substring(0, 2) == "on"){
+				name = name.substring(2);
 			}
+			return this.on(name, method ? lang.hitch(object, method) : object);
 		},
-		_ontouchend: function(e){
-			// summary: triggers ontouchend
-			// this._pick.curr = an array of target for touch event, one target instance for mouse events
-			if(this._pick.curr){
-				for(var i = 0; i < this._pick.curr.length; ++i){
-					if(this._pick.curr[i].target){
-						e.gfxTarget = this._pick.curr[i].target;
-						this._invokeHandler(this._pick.curr[i].target, 'ontouchend', e);
-					}
-				}
-			}
+
+		disconnect: function(handle){
+			// summary:
+			//		Deprecated. Disconnects a handler. Use `handle.remove` instead.
+
+			handle.remove();
 		},
-		_onmousemove: function(e){
-			// summary: triggers onmousemove, onmouseenter, onmouseleave
-			// this._pick.curr = an array of target for touch event, one target instance for mouse events
-			if(this._pick.last && this._pick.last != this._pick.curr){
-				this._invokeHandler(this._pick.last, 'onmouseleave', e);
-				this._invokeHandler(this._pick.last, 'onmouseout', e);
-			}
-			if(this._pick.curr){
-				if(this._pick.last == this._pick.curr){
-					this._invokeHandler(this._pick.curr, 'onmousemove', e);
-				}else{
-					this._invokeHandler(this._pick.curr, 'onmouseenter', e);
-					this._invokeHandler(this._pick.curr, 'onmouseover', e);
-				}
+
+		_initMirrorCanvas: function(){
+			// summary:
+			//		Initialises a mirror canvas used for event hit detection.
+
+			this._initMirrorCanvas = function(){};
+
+			var canvas = this.getEventSource(),
+				mirror = this.mirrorCanvas = canvas.ownerDocument.createElement("canvas");
+
+			mirror.width = 1;
+			mirror.height = 1;
+			mirror.style.position = "absolute";
+			mirror.style.left = mirror.style.top = "-99999px";
+			canvas.parentNode.appendChild(mirror);
+
+			var moveEvt = "mousemove";
+			if(has("MSPointer")){
+				moveEvt = "MSPointerMove";
+			}else if(has("touch")){
+				moveEvt = "touchmove";
 			}
+			on(canvas, moveEvt, lang.hitch(this, "_checkPointer"));
 		},
-		_ontouchmove: function(e){
-			// summary: triggers ontouchmove
-			if(this._pick.curr){
-				this._fireTouchEvent(e);
+
+		destroy: function(){
+			if(this.mirrorCanvas){
+				this.mirrorCanvas.parentNode.removeChild(this.mirrorCanvas);
+				this.mirrorCanvas = null;
 			}
-		},
-		
-		_fireTouchEvent: function(e){
-			// this._pick.curr = an array of target for touch event, one target instance for mouse events
-			var toFire = []; // the per-shape events list to fire
-			// for each positive picking:
-			// .group all pickings by target
-			// .collect all touches for the picking target 
-			for(var i = 0; i < this._pick.curr.length; ++i){
-				var pick = this._pick.curr[i];
-				if(pick.target){
-					// touches for this target
-					var gfxtt = pick.target.__gfxtt;
-					if(!gfxtt){
-						gfxtt = [];
-						pick.target.__gfxtt = gfxtt;
-					}
-					// store the touch that yielded to this picking
-					gfxtt.push(pick.t);
-					// if the target has not been added yet, add it
-					if(!pick.target.__inToFire){
-						toFire.push(pick.target);
-						pick.target.__inToFire=true;
-					}
+			this.inherited(arguments);
+		}
+	});
+
+	canvasWithEvents.createSurface = function(parentNode, width, height){
+		// summary:
+		//		creates a surface (Canvas)
+		// parentNode: Node
+		//		a parent node
+		// width: String
+		//		width of surface, e.g., "100px"
+		// height: String
+		//		height of surface, e.g., "100px"
+
+		if(!width && !height){
+			var pos = domGeom.position(parentNode);
+			width  = width  || pos.w;
+			height = height || pos.h;
+		}
+		if(typeof width === "number"){
+			width = width + "px";
+		}
+		if(typeof height === "number"){
+			height = height + "px";
+		}
+
+		var surface = new canvasWithEvents.Surface(),
+			parent = dom.byId(parentNode),
+			canvas = parent.ownerDocument.createElement("canvas");
+
+		canvas.width  = g.normalizedLength(width);	// in pixels
+		canvas.height = g.normalizedLength(height);	// in pixels
+
+		parent.appendChild(canvas);
+		surface.rawNode = canvas;
+		surface._parent = parent;
+		surface.surface = surface;
+
+		g._base._fixMsTouchAction(surface);
+
+		// any event handler added to the canvas needs to have its target fixed.
+		var oldAddEventListener = canvas.addEventListener,
+			oldRemoveEventListener = canvas.removeEventListener,
+			listeners = [];
+
+		var addEventListenerImpl = function(type, listener, useCapture){
+			surface._initMirrorCanvas();
+
+			var actualListener = surface.fixTarget(listener);
+			listeners.push({ original: listener, actual: actualListener });
+			oldAddEventListener.call(this, type, actualListener, useCapture);
+		};
+		var removeEventListenerImpl = function(type, listener, useCapture){
+			for(var i = 0, record; (record = listeners[i]); ++i){
+				if(record.original === listener){
+					oldRemoveEventListener.call(this, type, record.actual, useCapture);
+					listeners.splice(i, 1);
+					break;
 				}
 			}
-			if(toFire.length === 0){
-				// no target, invokes the surface handler
-				this._invokeHandler(this, 'on' + e.type, e);
-			}else{
-				for(i = 0; i < toFire.length; ++i){
-					(function(){
-						var targetTouches = toFire[i].__gfxtt;
-						// fires the original event BUT with our own targetTouches array.
-						// Note for iOS:
-						var evt = lang.delegate(e, {gfxTarget: toFire[i]});
-						if(isiOS){
-							// must use the original preventDefault function or iOS will throw a TypeError
-							evt.preventDefault = function(){e.preventDefault();};
-							evt.stopPropagation = function(){e.stopPropagation();};
-						}
-						// override targetTouches with the filtered one
-						evt.__defineGetter__('targetTouches', function(){return targetTouches;});
-						// clean up
-						delete toFire[i].__gfxtt;
-						delete toFire[i].__inToFire;
-						// fire event
-						this._invokeHandler(toFire[i], 'on' + e.type, evt);
-					}).call(this);
+		};
+		try{
+			Object.defineProperties(canvas, {
+				addEventListener: {
+					value: addEventListenerImpl,
+					enumerable: true,
+					configurable: true
+				},
+				removeEventListener: {
+					value: removeEventListenerImpl
 				}
+			});
+		}catch(e){
+			// Object.defineProperties fails on iOS 4-5. "Not supported on DOM objects").
+			canvas.addEventListener = addEventListenerImpl;
+			canvas.removeEventListener = removeEventListenerImpl;
+		}
+
+
+		canvas._dojoElementFromPoint = function(x, y){
+			// summary:
+			//		Returns the shape under the given (x, y) coordinate.
+			// evt:
+			//		mouse event
+
+			if(!surface.mirrorCanvas){
+				return this;
 			}
-		},
-		_onkeydown: function(){},	// needed?
-		_onkeyup:   function(){},	// needed?
-
-		_whatsUnderEvent: function(evt){
-			// summary:	returns the shape under the mouse event
-			// evt:		mouse event
-			
-			var surface = this, i,
-				pos = domGeom.position(surface.rawNode, true),
-				inputs = [], changedTouches = evt.changedTouches, touches = evt.touches;
-			// collect input events targets
-			if(changedTouches){
-				for(i = 0; i < changedTouches.length; ++i){
-					inputs.push({
-						t: changedTouches[i],
-						x: changedTouches[i].pageX - pos.x,
-						y: changedTouches[i].pageY - pos.y
-					});
-				}
-			}else if(touches){
-				for(i = 0; i < touches.length; ++i){
-					inputs.push({
-						t: touches[i],
-						x: touches[i].pageX - pos.x,
-						y: touches[i].pageY - pos.y
-					});
-				}
-			}else{
-				inputs.push({
-					x : evt.pageX - pos.x,
-					y : evt.pageY - pos.y
-				});
-			} 
-				
+
+			var surfacePosition = domGeom.position(this, true);
+
+			// use canvas-relative positioning
+			x -= surfacePosition.x;
+			y -= surfacePosition.y;
+
 			var mirror = surface.mirrorCanvas,
-				ctx = mirror.getContext('2d'),
+				ctx = mirror.getContext("2d"),
 				children = surface.children;
-			
+
 			ctx.clearRect(0, 0, mirror.width, mirror.height);
 			ctx.save();
 			ctx.strokeStyle = "rgba(127,127,127,1.0)";
 			ctx.fillStyle = "rgba(127,127,127,1.0)";
 			ctx.pickingMode = true;
-			var pick = null;
+
+			// TODO: Make inputs non-array
+			var inputs = [ { x: x, y: y } ];
+
 			// process the inputs to find the target.
-			for(i = children.length-1; i >= 0; i--){
+			for(var i = children.length - 1; i >= 0; i--){
 				children[i]._testInputs(ctx, inputs);
-				// does it need more hit tests ?
-				var allFound = true;
-				for(j = 0; j < inputs.length; ++j){
-					if(inputs[j].target == null){
-						allFound = false;
-						break;
-					}
-				}
-				if(allFound){
+
+				if(inputs[0].target){
 					break;
 				}
 			}
 			ctx.restore();
-			// touch event handlers expect an array of target, mouse handlers one target
-			return (touches || changedTouches) ? inputs : inputs[0].target;
-		}		
-	});
-	
-	canvasEvent.createSurface = function(parentNode, width, height){
-		// summary: creates a surface (Canvas)
-		// parentNode: Node: a parent node
-		// width: String: width of surface, e.g., "100px"
-		// height: String: height of surface, e.g., "100px"
+			return inputs[0] && inputs[0].target ? inputs[0].target.rawNode : this;
+		};
 
-		if(!width && !height){
-			var pos = domGeom.position(parentNode);
-			width  = width  || pos.w;
-			height = height || pos.h;
-		}
-		if(typeof width == "number"){
-			width = width + "px";
-		}
-		if(typeof height == "number"){
-			height = height + "px";
-		}
 
-		var s = new canvasEvent.Surface(),
-			p = dom.byId(parentNode),
-			c = p.ownerDocument.createElement("canvas");
+		return surface; // dojox/gfx.Surface
+	};
 
-		c.width  = g.normalizedLength(width);	// in pixels
-		c.height = g.normalizedLength(height);	// in pixels
+	var Creator = {
+		createObject: function(){
+			// summary:
+			//		Creates a synthetic, partially-interoperable Element object used to uniquely identify the given
+			//		shape within the canvas pseudo-DOM.
 
-		p.appendChild(c);
-		s.rawNode = c;
-		s._parent = p;
-		s.surface = s;
-		return s;	// dojox.gfx.Surface
-	};
+			var shape = this.inherited(arguments),
+				listeners = {};
 
+			shape.rawNode = {
+				shape: shape,
+				ownerDocument: shape.surface.rawNode.ownerDocument,
+				parentNode: shape.parent ? shape.parent.rawNode : null,
+				addEventListener: function(type, listener){
+					var listenersOfType = listeners[type] = (listeners[type] || []);
+					for(var i = 0, record; (record = listenersOfType[i]); ++i){
+						if(record.listener === listener){
+							return;
+						}
+					}
 
-	// Mouse/Touch event
-	var isEventStopped = function(/*Event*/ evt){
-		// summary:
-		//    queries whether an event has been stopped or not
-		// evt: Event
-		//    The event object.
-		if(evt.cancelBubble !== undefined){
-			return evt.cancelBubble;
-		}
-		return false;
-	};
-	
-	canvasEvent.fixTarget = function(event, gfxElement){
-		// summary: 
-		//     Adds the gfxElement to event.gfxTarget if none exists. This new 
-		//     property will carry the GFX element associated with this event.
-		// event: Object 
-		//     The current input event (MouseEvent or TouchEvent)
-		// gfxElement: Object
-		//     The GFX target element (a Surface in this case)
-		if(isEventStopped(event)){
-			return false;
-		}
-		if(!event.gfxTarget){
-			gfxElement._pick.last = gfxElement._pick.curr;
-			gfxElement._pick.curr = gfxElement._whatsUnderEvent(event);
-			if (!lang.isArray(gfxElement._pick.curr))
-				event.gfxTarget = gfxElement._pick.curr;
+					listenersOfType.push({
+						listener: listener,
+						handle: aspect.after(this, "on" + type, shape.surface.fixTarget(listener), true)
+					});
+				},
+				removeEventListener: function(type, listener){
+					var listenersOfType = listeners[type];
+					if(!listenersOfType){
+						return;
+					}
+					for(var i = 0, record; (record = listenersOfType[i]); ++i){
+						if(record.listener === listener){
+							record.handle.remove();
+							listenersOfType.splice(i, 1);
+							return;
+						}
+					}
+				}
+			};
+			return shape;
 		}
-		return true;
 	};
 
-	return canvasEvent;
+	canvasWithEvents.Group.extend(Creator);
+	canvasWithEvents.Surface.extend(Creator);
+
+	return canvasWithEvents;
 });
diff --git a/dojox/gfx/canvasext.js b/dojox/gfx/canvasext.js
new file mode 100644
index 0000000..e81b923
--- /dev/null
+++ b/dojox/gfx/canvasext.js
@@ -0,0 +1,39 @@
+define([
+	"./_base",
+	"./canvas"],
+	function(gfx, canvas){
+
+	/*=====
+	 return {
+	 	// summary:
+	 	//		A module that adds canvas-specific features to the gfx api. You should require this module
+	 	//		when your application specifically targets the HTML5 Canvas renderer.
+	 }
+	 =====*/
+	
+	var ext = gfx.canvasext = {};
+	
+	canvas.Surface.extend({
+		
+		getImageData: function(rect){
+			// summary:
+			//		Returns the canvas pixel buffer.
+			// rect: dojox/gfx.Rectangle
+			//		The canvas area.
+			
+			// flush pending renders queue, if any
+			if("pendingRender" in this){
+				this._render(true); // force render even if there're pendingImages
+			}
+			return this.rawNode.getContext("2d").getImageData(rect.x, rect.y, rect.width, rect.height);				
+		},
+		
+		getContext: function(){
+			// summary:
+			//		Returns the surface CanvasRenderingContext2D.
+			return this.rawNode.getContext("2d");
+		}
+	});		
+
+	return ext;
+});
diff --git a/dojox/gfx/decompose.js b/dojox/gfx/decompose.js
index df03c0d..71e8ca0 100644
--- a/dojox/gfx/decompose.js
+++ b/dojox/gfx/decompose.js
@@ -1,13 +1,14 @@
 define(["./_base", "dojo/_base/lang", "./matrix"], 
   function (g, lang, m){
-	/*===== g = dojox.gfx =====*/
 	function eq(/* Number */ a, /* Number */ b){
-		// summary: compare two FP numbers for equality
+		// summary:
+		//		compare two FP numbers for equality
 		return Math.abs(a - b) <= 1e-6 * (Math.abs(a) + Math.abs(b));	// Boolean
 	}
 
 	function calcFromValues(/* Number */ r1, /* Number */ m1, /* Number */ r2, /* Number */ m2){
-		// summary: uses two close FP ration and their original magnitudes to approximate the result
+		// summary:
+		//		uses two close FP ration and their original magnitudes to approximate the result
 		if(!isFinite(r1)){
 			return r2;	// Number
 		}else if(!isFinite(r2)){
@@ -17,18 +18,20 @@ define(["./_base", "dojo/_base/lang", "./matrix"],
 		return (m1 * r1 + m2 * r2) / (m1 + m2);	// Number
 	}
 
-	function transpose(/* dojox.gfx.matrix.Matrix2D */ matrix){
-		// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object
+	function transpose(matrix){
+		// matrix: dojox/gfx/matrix.Matrix2D
+		//		a 2D matrix-like object
 		var M = new m.Matrix2D(matrix);
-		return lang.mixin(M, {dx: 0, dy: 0, xy: M.yx, yx: M.xy});	// dojox.gfx.matrix.Matrix2D
+		return lang.mixin(M, {dx: 0, dy: 0, xy: M.yx, yx: M.xy});	// dojox/gfx/matrix.Matrix2D
 	}
 
-	function scaleSign(/* dojox.gfx.matrix.Matrix2D */ matrix){
+	function scaleSign(/* dojox/gfx/matrix.Matrix2D */ matrix){
 		return (matrix.xx * matrix.yy < 0 || matrix.xy * matrix.yx > 0) ? -1 : 1;	// Number
 	}
 
-	function eigenvalueDecomposition(/* dojox.gfx.matrix.Matrix2D */ matrix){
-		// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object
+	function eigenvalueDecomposition(matrix){
+		// matrix: dojox/gfx/matrix.Matrix2D
+		//		a 2D matrix-like object
 		var M = m.normalize(matrix),
 			b = -M.xx - M.yy,
 			c = M.xx * M.yy - M.xy * M.yx,
@@ -72,8 +75,9 @@ define(["./_base", "dojo/_base/lang", "./matrix"],
 		};
 	}
 
-	function decomposeSR(/* dojox.gfx.matrix.Matrix2D */ M, /* Object */ result){
-		// summary: decomposes a matrix into [scale, rotate]; no checks are done.
+	function decomposeSR(/* dojox/gfx/matrix.Matrix2D */ M, /* Object */ result){
+		// summary:
+		//		decomposes a matrix into [scale, rotate]; no checks are done.
 		var sign = scaleSign(M),
 			a = result.angle1 = (Math.atan2(M.yx, M.yy) + Math.atan2(-sign * M.xy, sign * M.xx)) / 2,
 			cos = Math.cos(a), sin = Math.sin(a);
@@ -82,8 +86,9 @@ define(["./_base", "dojo/_base/lang", "./matrix"],
 		return result;	// Object
 	}
 
-	function decomposeRS(/* dojox.gfx.matrix.Matrix2D */ M, /* Object */ result){
-		// summary: decomposes a matrix into [rotate, scale]; no checks are done
+	function decomposeRS(/* dojox/gfx/matrix.Matrix2D */ M, /* Object */ result){
+		// summary:
+		//		decomposes a matrix into [rotate, scale]; no checks are done
 		var sign = scaleSign(M),
 			a = result.angle2 = (Math.atan2(sign * M.yx, sign * M.xx) + Math.atan2(-M.xy, M.yy)) / 2,
 			cos = Math.cos(a), sin = Math.sin(a);
@@ -93,12 +98,15 @@ define(["./_base", "dojo/_base/lang", "./matrix"],
 	}
 
 	return g.decompose = function(matrix){
-		// summary: Decompose a 2D matrix into translation, scaling, and rotation components.
-		// description: This function decompose a matrix into four logical components:
-		//	translation, rotation, scaling, and one more rotation using SVD.
-		//	The components should be applied in following order:
+		// summary:
+		//		Decompose a 2D matrix into translation, scaling, and rotation components.
+		// description:
+		//		This function decompose a matrix into four logical components:
+		//		translation, rotation, scaling, and one more rotation using SVD.
+		//		The components should be applied in following order:
 		//	| [translate, rotate(angle2), scale, rotate(angle1)]
-		// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object
+		// matrix: dojox/gfx/matrix.Matrix2D
+		//		a 2D matrix-like object
 		var M = m.normalize(matrix),
 			result = {dx: M.dx, dy: M.dy, sx: 1, sy: 1, angle1: 0, angle2: 0};
 		// detect case: [scale]
diff --git a/dojox/gfx/demos/PI.html b/dojox/gfx/demos/PI.html
index 6e87214..f8d5d87 100644
--- a/dojox/gfx/demos/PI.html
+++ b/dojox/gfx/demos/PI.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
diff --git a/dojox/gfx/demos/beautify.html b/dojox/gfx/demos/beautify.html
index d1f02f5..391bf16 100644
--- a/dojox/gfx/demos/beautify.html
+++ b/dojox/gfx/demos/beautify.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 trimPath = function(o){
diff --git a/dojox/gfx/demos/butterfly.html b/dojox/gfx/demos/butterfly.html
index a54a4c5..dd2f3e4 100644
--- a/dojox/gfx/demos/butterfly.html
+++ b/dojox/gfx/demos/butterfly.html
@@ -7,7 +7,7 @@
 	@import "../../../dijit/themes/tundra/tundra.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
 <script type="text/javascript">
 
 dojo.require("dijit.form.HorizontalSlider");
diff --git a/dojox/gfx/demos/clipping.html b/dojox/gfx/demos/clipping.html
new file mode 100644
index 0000000..b06e0c0
--- /dev/null
+++ b/dojox/gfx/demos/clipping.html
@@ -0,0 +1,880 @@
+<!--[if lt IE 9]>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<![endif]-->
+<![if gte IE 9]>
+<!DOCTYPE HTML>
+<![endif]>
+<html>
+	<head>
+		<title>GFX Clipping Demo</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<script type="text/javascript">
+			//  adapted from Paul Irish's and Erik Moller's work. 
+			(function() {
+			    var lastTime = 0;
+			    var vendors = ['ms', 'moz', 'webkit', 'o'];
+			    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x){
+			        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
+			    }
+			    if(!window.requestAnimationFrame)
+			        window.requestAnimationFrame = function(callback, element){
+			            var currTime = new Date().getTime();
+			            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
+			            var id = window.setTimeout(function() { callback(currTime + timeToCall); }, 
+			              timeToCall);
+			            lastTime = currTime + timeToCall;
+			            return id;
+			        };
+			}());
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async:1"></script>
+		<script type="text/javascript">
+		
+			require(["dojox/gfx","dojo/dom", "dojo/ready"], function(gfx, dom, ready) {
+				var surface, g, m = gfx.matrix, clip,
+					initial_matrix = m.translate(150, 150);
+								
+				
+				var makeShapes = function() {
+					surface = gfx.createSurface(dom.byId("gfx_holder"), 500, 500);
+					surface.createRect({
+						x : 0,
+						y : 0,
+						width : 500,
+						height : 500
+					}).setFill("#eee");
+					g = surface.createGroup().setTransform(initial_matrix);
+					var f, s = {
+						color : "black",
+						width : 1
+					};
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-122.304 84.285C-122.304 84.285 -122.203 86.179 -123.027 86.16C-123.851 86.141 -140.305 38.066 -160.833 40.309C-160.833 40.309 -143.05 32.956 -122.304 84.285z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-118.774 81.262C-118.774 81.262 -119.323 83.078 -120.092 82.779C-120.86 82.481 -119.977 31.675 -140.043 26.801C-140.043 26.801 -120.82 25.937 -118.774 81.262z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-91.284 123.59C-91.284 123.59 -89.648 124.55 -90.118 125.227C-90.589 125.904 -139.763 113.102 -149.218 131.459C-149.218 131.459 -145.539 112.572 -91.284 123.59z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-94.093 133.801C-94.093 133.801 -92.237 134.197 -92.471 134.988C-92.704 135.779 -143.407 139.121 -146.597 159.522C-146.597 159.522 -149.055 140.437 -94.093 133.801z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-98.304 128.276C-98.304 128.276 -96.526 128.939 -96.872 129.687C-97.218 130.435 -147.866 126.346 -153.998 146.064C-153.998 146.064 -153.646 126.825 -98.304 128.276z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-109.009 110.072C-109.009 110.072 -107.701 111.446 -108.34 111.967C-108.979 112.488 -152.722 86.634 -166.869 101.676C-166.869 101.676 -158.128 84.533 -109.009 110.072z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-116.554 114.263C-116.554 114.263 -115.098 115.48 -115.674 116.071C-116.25 116.661 -162.638 95.922 -174.992 112.469C-174.992 112.469 -168.247 94.447 -116.554 114.263z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-119.154 118.335C-119.154 118.335 -117.546 119.343 -118.036 120.006C-118.526 120.669 -167.308 106.446 -177.291 124.522C-177.291 124.522 -173.066 105.749 -119.154 118.335z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-108.42 118.949C-108.42 118.949 -107.298 120.48 -107.999 120.915C-108.7 121.35 -148.769 90.102 -164.727 103.207C-164.727 103.207 -153.862 87.326 -108.42 118.949z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-128.2 90C-128.2 90 -127.6 91.8 -128.4 92C-129.2 92.2 -157.8 50.2 -177.001 57.8C-177.001 57.8 -161.8 46 -128.2 90z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-127.505 96.979C-127.505 96.979 -126.53 98.608 -127.269 98.975C-128.007 99.343 -164.992 64.499 -182.101 76.061C-182.101 76.061 -169.804 61.261 -127.505 96.979z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.172
+					};
+					g.createPath("M-127.62 101.349C-127.62 101.349 -126.498 102.88 -127.199 103.315C-127.9 103.749 -167.969 72.502 -183.927 85.607C-183.927 85.607 -173.062 69.726 -127.62 101.349z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = "#000000";
+					g.createPath("M-129.83 103.065C-129.327 109.113 -128.339 115.682 -126.6 118.801C-126.6 118.801 -130.2 131.201 -121.4 144.401C-121.4 144.401 -121.8 151.601 -120.2 154.801C-120.2 154.801 -116.2 163.201 -111.4 164.001C-107.516 164.648 -98.793 167.717 -88.932 169.121C-88.932 169.121 -71.8 183.201 -75 196.001C-75 196.001 -75.4 212.401 -79 214.001C-79 214.001 -67.4 202.801 -77 219.601L-81.4 238.401C-81.4 238.401 -55.8 216.801 -71.4 235.201L-81.4 261.201C-81.4 261.201 -61.8 242.801 -69 251 [...]
+					f = "#cc7226";
+					s = "#000000";
+					g.createPath("M299.717 80.245C300.345 80.426 302.551 81.55 303.801 83.2C303.801 83.2 310.601 94 305.401 75.6C305.401 75.6 296.201 46.8 305.001 58C305.001 58 311.001 65.2 307.801 51.6C303.936 35.173 301.401 28.8 301.401 28.8C301.401 28.8 313.001 33.6 286.201 -6L295.001 -2.4C295.001 -2.4 275.401 -42 253.801 -47.2L245.801 -53.2C245.801 -53.2 284.201 -91.2 271.401 -128C271.401 -128 264.601 -133.2 255.001 -124C255.001 -124 248.601 -119.2 242.601 -120.8C242.601 -120.8 211.801 -119.6 209.8 [...]
+					f = "#cc7226";
+					s = null;
+					g.createPath("M-115.6 102.6C-140.6 63.2 -126.2 119.601 -126.2 119.601C-117.4 154.001 12.2 116.401 12.2 116.401C12.2 116.401 181.001 86 192.201 82C203.401 78 298.601 84.4 298.601 84.4L293.001 67.6C228.201 21.2 209.001 44.4 195.401 40.4C181.801 36.4 184.201 46 181.001 46.8C177.801 47.6 138.601 22.8 132.201 23.6C125.801 24.4 100.459 0.649 115.401 32.4C131.401 66.4 57 71.6 40.2 60.4C23.4 49.2 47.4 78.8 47.4 78.8C65.8 98.8 31.4 82 31.4 82C-3 69.2 -27 94.8 -30.2 95.6C-33.4 96.4 -38.2 99.6 [...]
+					f = "#e87f3a";
+					g.createPath("M133.51 25.346C127.11 26.146 101.743 2.407 116.71 34.146C133.31 69.346 58.31 73.346 41.51 62.146C24.709 50.946 48.71 80.546 48.71 80.546C67.11 100.546 32.709 83.746 32.709 83.746C-1.691 70.946 -25.691 96.546 -28.891 97.346C-32.091 98.146 -36.891 101.346 -37.691 94.946C-38.491 88.546 -45.87 72.012 -77.691 98.146C-98.927 115.492 -112.418 94.037 -112.418 94.037L-115.618 104.146C-140.618 64.346 -125.546 122.655 -125.546 122.655C-116.745 157.056 13.509 118.146 13.509 118.14 [...]
+					f = "#ea8c4d";
+					g.createPath("M134.819 27.091C128.419 27.891 103.685 3.862 118.019 35.891C134.219 72.092 59.619 75.092 42.819 63.892C26.019 52.692 50.019 82.292 50.019 82.292C68.419 102.292 34.019 85.492 34.019 85.492C-0.381 72.692 -24.382 98.292 -27.582 99.092C-30.782 99.892 -35.582 103.092 -36.382 96.692C-37.182 90.292 -44.43 73.925 -76.382 99.892C-98.855 117.983 -112.036 97.074 -112.036 97.074L-115.636 105.692C-139.436 66.692 -124.891 125.71 -124.891 125.71C-116.091 160.11 14.819 119.892 14.819  [...]
+					f = "#ec9961";
+					g.createPath("M136.128 28.837C129.728 29.637 104.999 5.605 119.328 37.637C136.128 75.193 60.394 76.482 44.128 65.637C27.328 54.437 51.328 84.037 51.328 84.037C69.728 104.037 35.328 87.237 35.328 87.237C0.928 74.437 -23.072 100.037 -26.272 100.837C-29.472 101.637 -34.272 104.837 -35.072 98.437C-35.872 92.037 -42.989 75.839 -75.073 101.637C-98.782 120.474 -111.655 100.11 -111.655 100.11L-115.655 107.237C-137.455 70.437 -124.236 128.765 -124.236 128.765C-115.436 163.165 16.128 121.637  [...]
+					f = "#eea575";
+					g.createPath("M137.438 30.583C131.037 31.383 106.814 7.129 120.637 39.383C137.438 78.583 62.237 78.583 45.437 67.383C28.637 56.183 52.637 85.783 52.637 85.783C71.037 105.783 36.637 88.983 36.637 88.983C2.237 76.183 -21.763 101.783 -24.963 102.583C-28.163 103.383 -32.963 106.583 -33.763 100.183C-34.563 93.783 -41.548 77.752 -73.763 103.383C-98.709 122.965 -111.273 103.146 -111.273 103.146L-115.673 108.783C-135.473 73.982 -123.582 131.819 -123.582 131.819C-114.782 166.22 17.437 123.38 [...]
+					f = "#f1b288";
+					g.createPath("M138.747 32.328C132.347 33.128 106.383 9.677 121.947 41.128C141.147 79.928 63.546 80.328 46.746 69.128C29.946 57.928 53.946 87.528 53.946 87.528C72.346 107.528 37.946 90.728 37.946 90.728C3.546 77.928 -20.454 103.528 -23.654 104.328C-26.854 105.128 -31.654 108.328 -32.454 101.928C-33.254 95.528 -40.108 79.665 -72.454 105.128C-98.636 125.456 -110.891 106.183 -110.891 106.183L-115.691 110.328C-133.691 77.128 -122.927 134.874 -122.927 134.874C-114.127 169.274 18.746 125.1 [...]
+					f = "#f3bf9c";
+					g.createPath("M140.056 34.073C133.655 34.873 107.313 11.613 123.255 42.873C143.656 82.874 64.855 82.074 48.055 70.874C31.255 59.674 55.255 89.274 55.255 89.274C73.655 109.274 39.255 92.474 39.255 92.474C4.855 79.674 -19.145 105.274 -22.345 106.074C-25.545 106.874 -30.345 110.074 -31.145 103.674C-31.945 97.274 -38.668 81.578 -71.145 106.874C-98.564 127.947 -110.509 109.219 -110.509 109.219L-115.709 111.874C-131.709 81.674 -122.273 137.929 -122.273 137.929C-113.473 172.329 20.055 126. [...]
+					f = "#f5ccb0";
+					g.createPath("M141.365 35.819C134.965 36.619 107.523 13.944 124.565 44.619C146.565 84.219 66.164 83.819 49.364 72.619C32.564 61.419 56.564 91.019 56.564 91.019C74.964 111.019 40.564 94.219 40.564 94.219C6.164 81.419 -17.836 107.019 -21.036 107.819C-24.236 108.619 -29.036 111.819 -29.836 105.419C-30.636 99.019 -37.227 83.492 -69.836 108.619C-98.491 130.438 -110.127 112.256 -110.127 112.256L-115.727 113.419C-130.128 85.019 -121.618 140.983 -121.618 140.983C-112.818 175.384 21.364 128. [...]
+					f = "#f8d8c4";
+					g.createPath("M142.674 37.565C136.274 38.365 108.832 15.689 125.874 46.365C147.874 85.965 67.474 85.565 50.674 74.365C33.874 63.165 57.874 92.765 57.874 92.765C76.274 112.765 41.874 95.965 41.874 95.965C7.473 83.165 -16.527 108.765 -19.727 109.565C-22.927 110.365 -27.727 113.565 -28.527 107.165C-29.327 100.765 -35.786 85.405 -68.527 110.365C-98.418 132.929 -109.745 115.293 -109.745 115.293L-115.745 114.965C-129.346 88.564 -120.963 144.038 -120.963 144.038C-112.163 178.438 22.673 130 [...]
+					f = "#fae5d7";
+					g.createPath("M143.983 39.31C137.583 40.11 110.529 17.223 127.183 48.11C149.183 88.91 68.783 87.31 51.983 76.11C35.183 64.91 59.183 94.51 59.183 94.51C77.583 114.51 43.183 97.71 43.183 97.71C8.783 84.91 -15.217 110.51 -18.417 111.31C-21.618 112.11 -26.418 115.31 -27.218 108.91C-28.018 102.51 -34.346 87.318 -67.218 112.11C-98.345 135.42 -109.363 118.329 -109.363 118.329L-115.764 116.51C-128.764 92.51 -120.309 147.093 -120.309 147.093C-111.509 181.493 23.983 132.11 23.983 132.11C23.98 [...]
+					f = "#fcf2eb";
+					g.createPath("M145.292 41.055C138.892 41.855 112.917 18.411 128.492 49.855C149.692 92.656 70.092 89.056 53.292 77.856C36.492 66.656 60.492 96.256 60.492 96.256C78.892 116.256 44.492 99.456 44.492 99.456C10.092 86.656 -13.908 112.256 -17.108 113.056C-20.308 113.856 -25.108 117.056 -25.908 110.656C-26.708 104.256 -32.905 89.232 -65.908 113.856C-98.273 137.911 -108.982 121.365 -108.982 121.365L-115.782 118.056C-128.582 94.856 -119.654 150.147 -119.654 150.147C-110.854 184.547 25.292 13 [...]
+					f = "#ffffff";
+					g.createPath("M-115.8 119.601C-128.6 97.6 -119 153.201 -119 153.201C-110.2 187.601 26.6 135.601 26.6 135.601C26.6 135.601 195.401 105.2 206.601 101.2C217.801 97.2 303.401 102.8 303.401 102.8L298.601 80.4C233.801 34 223.401 63.6 209.801 59.6C196.201 55.6 198.601 65.2 195.401 66C192.201 66.8 153.001 42 146.601 42.8C140.201 43.6 114.981 19.793 129.801 51.6C152.028 99.307 69.041 89.227 54.6 79.6C37.8 68.4 61.8 98 61.8 98C80.2 118.001 45.8 101.2 45.8 101.2C11.4 88.4 -12.6 114.001 -15.8 1 [...]
+					f = "#000000";
+					g.createPath("M-74.2 149.601C-74.2 149.601 -81.4 161.201 -60.6 174.401C-60.6 174.401 -59.2 175.801 -77.2 171.601C-77.2 171.601 -83.4 169.601 -85 159.201C-85 159.201 -89.8 154.801 -94.6 149.201C-99.4 143.601 -74.2 149.601 -74.2 149.601z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M65.8 102C65.8 102 83.498 128.821 82.9 133.601C81.6 144.001 81.4 153.601 84.6 157.601C87.801 161.601 96.601 194.801 96.601 194.801C96.601 194.801 96.201 196.001 108.601 158.001C108.601 158.001 120.201 142.001 100.201 123.601C100.201 123.601 65 94.8 65.8 102z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-54.2 176.401C-54.2 176.401 -43 183.601 -57.4 214.801L-51 212.401C-51 212.401 -51.8 223.601 -55 226.001L-47.8 222.801C-47.8 222.801 -43 230.801 -47 235.601C-47 235.601 -30.2 243.601 -31 250.001C-31 250.001 -24.6 242.001 -28.6 235.601C-32.6 229.201 -39.8 233.201 -39 214.801L-47.8 218.001C-47.8 218.001 -42.2 209.201 -42.2 202.801L-50.2 205.201C-50.2 205.201 -34.731 178.623 -45.4 177.201C-51.4 176.401 -54.2 176.401 -54.2 176.401z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-21.8 193.201C-21.8 193.201 -19 188.801 -21.8 189.601C-24.6 190.401 -55.8 205.201 -61.8 214.801C-61.8 214.801 -27.4 190.401 -21.8 193.201z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-11.4 201.201C-11.4 201.201 -8.6 196.801 -11.4 197.601C-14.2 198.401 -45.4 213.201 -51.4 222.801C-51.4 222.801 -17 198.401 -11.4 201.201z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M1.8 186.001C1.8 186.001 4.6 181.601 1.8 182.401C-1 183.201 -32.2 198.001 -38.2 207.601C-38.2 207.601 -3.8 183.201 1.8 186.001z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-21.4 229.601C-21.4 229.601 -21.4 223.601 -24.2 224.401C-27 225.201 -63 242.801 -69 252.401C-69 252.401 -27 226.801 -21.4 229.601z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-20.2 218.801C-20.2 218.801 -19 214.001 -21.8 214.801C-23.8 214.801 -50.2 226.401 -56.2 236.001C-56.2 236.001 -26.6 214.401 -20.2 218.801z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-34.6 266.401L-44.6 274.001C-44.6 274.001 -34.2 266.401 -30.6 267.601C-30.6 267.601 -37.4 278.801 -38.2 284.001C-38.2 284.001 -27.8 271.201 -22.2 271.601C-22.2 271.601 -14.6 272.001 -14.6 282.801C-14.6 282.801 -9 272.401 -5.8 272.801C-5.8 272.801 -4.6 279.201 -5.8 286.001C-5.8 286.001 -1.8 278.401 2.2 280.001C2.2 280.001 8.6 278.001 7.8 289.601C7.8 289.601 7.8 300.001 7 302.801C7 302.801 12.6 276.401 15 276.001C15 276.001 23 274.801 27.8 283.601C27.8 283.601 23.8 276. [...]
+					f = "#000000";
+					g.createPath("M-29.8 173.601C-29.8 173.601 -15 167.601 25 173.601C25 173.601 32.2 174.001 39 165.201C45.8 156.401 72.6 149.201 79 151.201L88.601 157.601L89.401 158.801C89.401 158.801 101.801 169.201 102.201 176.801C102.601 184.401 87.801 232.401 78.2 248.401C68.6 264.401 59 276.801 39.8 274.401C39.8 274.401 19 270.401 -6.6 274.401C-6.6 274.401 -35.8 272.801 -38.6 264.801C-41.4 256.801 -27.4 241.601 -27.4 241.601C-27.4 241.601 -23 233.201 -24.2 218.801C-25.4 204.401 -25 176.401 -29.8 [...]
+					f = "#e5668c";
+					g.createPath("M-7.8 175.601C0.6 194.001 -29 259.201 -29 259.201C-31 260.801 -16.34 266.846 -6.2 264.401C4.746 261.763 45 266.001 45 266.001C68.6 250.401 81.4 206.001 81.4 206.001C81.4 206.001 91.801 182.001 74.2 178.801C56.6 175.601 -7.8 175.601 -7.8 175.601z").setFill(f).setStroke(s);
+					f = "#b23259";
+					g.createPath("M-9.831 206.497C-6.505 193.707 -4.921 181.906 -7.8 175.601C-7.8 175.601 54.6 182.001 65.8 161.201C70.041 153.326 84.801 184.001 84.4 193.601C84.4 193.601 21.4 208.001 6.6 196.801L-9.831 206.497z").setFill(f).setStroke(s);
+					f = "#a5264c";
+					g.createPath("M-5.4 222.801C-5.4 222.801 -3.4 230.001 -5.8 234.001C-5.8 234.001 -7.4 234.801 -8.6 235.201C-8.6 235.201 -7.4 238.801 -1.4 240.401C-1.4 240.401 0.6 244.801 3 245.201C5.4 245.601 10.2 251.201 14.2 250.001C18.2 248.801 29.4 244.801 29.4 244.801C29.4 244.801 35 241.601 43.8 245.201C43.8 245.201 46.175 244.399 46.6 240.401C47.1 235.701 50.2 232.001 52.2 230.001C54.2 228.001 63.8 215.201 62.6 214.801C61.4 214.401 -5.4 222.801 -5.4 222.801z").setFill(f).setStroke(s);
+					f = "#ff727f";
+					s = "#000000";
+					g.createPath("M-9.8 174.401C-9.8 174.401 -12.6 196.801 -9.4 205.201C-6.2 213.601 -7 215.601 -7.8 219.601C-8.6 223.601 -4.2 233.601 1.4 239.601L13.4 241.201C13.4 241.201 28.6 237.601 37.8 240.401C37.8 240.401 46.794 241.744 50.2 226.801C50.2 226.801 55 220.401 62.2 217.601C69.4 214.801 76.6 173.201 72.6 165.201C68.6 157.201 54.2 152.801 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-8.2 249.201C-8.2 249.201 -9 247.201 -13.4 246.801C-13.4 246.801 -35.8 243.201 -44.2 230.801C-44.2 230.801 -51 225.201 -46.6 236.801C-46.6 236.801 -36.2 257.201 -29.4 260.001C-29.4 260.001 -13 264.001 -8.2 249.201z").setFill(f).setStroke(s);
+					f = "#cc3f4c";
+					s = null;
+					g.createPath("M71.742 185.229C72.401 177.323 74.354 168.709 72.6 165.201C66.154 152.307 49.181 157.695 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401C-9.8 174.401 -11.545 188.364 -10.705 198.376C-10.705 198.376 26.6 186.801 27.4 192.401C27.4 192.401 29 189.201 38.2 189.201C47.4 189.201 70.142 188.029 71.742 185.229z").setFill(f).setStroke(s);
+					s = {
+						color : "#a51926",
+						width : 2
+					};
+					f = null;
+					g.createPath("M28.6 175.201C28.6 175.201 33.4 180.001 29.8 189.601C29.8 189.601 15.4 205.601 17.4 219.601").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-19.4 260.001C-19.4 260.001 -23.8 247.201 -15 254.001C-15 254.001 -10.2 256.001 -11.4 257.601C-12.6 259.201 -18.2 263.201 -19.4 260.001z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-14.36 261.201C-14.36 261.201 -17.88 250.961 -10.84 256.401C-10.84 256.401 -6.419 258.849 -7.96 259.281C-12.52 260.561 -7.96 263.121 -14.36 261.201z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-9.56 261.201C-9.56 261.201 -13.08 250.961 -6.04 256.401C-6.04 256.401 -1.665 258.711 -3.16 259.281C-6.52 260.561 -3.16 263.121 -9.56 261.201z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-2.96 261.401C-2.96 261.401 -6.48 251.161 0.56 256.601C0.56 256.601 4.943 258.933 3.441 259.481C0.48 260.561 3.441 263.321 -2.96 261.401z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M3.52 261.321C3.52 261.321 0 251.081 7.041 256.521C7.041 256.521 10.881 258.121 9.921 259.401C8.961 260.681 9.921 263.241 3.52 261.321z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M10.2 262.001C10.2 262.001 5.4 249.601 14.6 256.001C14.6 256.001 19.4 258.001 18.2 259.601C17 261.201 18.2 264.401 10.2 262.001z").setFill(f).setStroke(s);
+					s = {
+						color : "#a5264c",
+						width : 2
+					};
+					f = null;
+					g.createPath("M-18.2 244.801C-18.2 244.801 -5 242.001 1 245.201C1 245.201 7 246.401 8.2 246.001C9.4 245.601 12.6 245.201 12.6 245.201").setFill(f).setStroke(s);
+					s = {
+						color : "#a5264c",
+						width : 2
+					};
+					g.createPath("M15.8 253.601C15.8 253.601 27.8 240.001 39.8 244.401C46.816 246.974 45.8 243.601 46.6 240.801C47.4 238.001 47.6 233.801 52.6 230.801").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M33 237.601C33 237.601 29 226.801 26.2 239.601C23.4 252.401 20.2 256.001 18.6 258.801C18.6 258.801 18.6 264.001 27 263.601C27 263.601 37.8 263.201 38.2 260.401C38.6 257.601 37 246.001 33 237.601z").setFill(f).setStroke(s);
+					s = {
+						color : "#a5264c",
+						width : 2
+					};
+					f = null;
+					g.createPath("M47 244.801C47 244.801 50.6 242.401 53 243.601").setFill(f).setStroke(s);
+					s = {
+						color : "#a5264c",
+						width : 2
+					};
+					g.createPath("M53.5 228.401C53.5 228.401 56.4 223.501 61.2 222.701").setFill(f).setStroke(s);
+					f = "#b2b2b2";
+					s = null;
+					g.createPath("M-25.8 265.201C-25.8 265.201 -7.8 268.401 -3.4 266.801C-3.4 266.801 5.4 266.801 -3 268.801C-3 268.801 -15.8 268.801 -23.8 267.601C-23.8 267.601 -35.4 262.001 -25.8 265.201z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-11.8 172.001C-11.8 172.001 5.8 172.001 7.8 172.801C7.8 172.801 15 203.601 11.4 211.201C11.4 211.201 10.2 214.001 7.4 208.401C7.4 208.401 -11 175.601 -14.2 173.601C-17.4 171.601 -13 172.001 -11.8 172.001z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-88.9 169.301C-88.9 169.301 -80 171.001 -67.4 173.601C-67.4 173.601 -62.6 196.001 -59.4 200.801C-56.2 205.601 -59.8 205.601 -63.4 202.801C-67 200.001 -81.8 186.001 -83.8 181.601C-85.8 177.201 -88.9 169.301 -88.9 169.301z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-67.039 173.818C-67.039 173.818 -61.239 175.366 -60.23 177.581C-59.222 179.795 -61.432 183.092 -61.432 183.092C-61.432 183.092 -62.432 186.397 -63.634 184.235C-64.836 182.072 -67.708 174.412 -67.039 173.818z").setFill(f).setStroke(s);
+					f = "#000000";
+					s = null;
+					g.createPath("M-67 173.601C-67 173.601 -63.4 178.801 -59.8 178.801C-56.2 178.801 -55.818 178.388 -53 179.001C-48.4 180.001 -48.8 178.001 -42.2 179.201C-39.56 179.681 -37 178.801 -34.2 180.001C-31.4 181.201 -28.2 180.401 -27 178.401C-25.8 176.401 -21 172.201 -21 172.201C-21 172.201 -33.8 174.001 -36.6 174.801C-36.6 174.801 -59 176.001 -67 173.601z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-22.4 173.801C-22.4 173.801 -28.85 177.301 -29.25 179.701C-29.65 182.101 -24 185.801 -24 185.801C-24 185.801 -21.25 190.401 -20.65 188.001C-20.05 185.601 -21.6 174.201 -22.4 173.801z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-59.885 179.265C-59.885 179.265 -52.878 190.453 -52.661 179.242C-52.661 179.242 -52.104 177.984 -53.864 177.962C-59.939 177.886 -58.418 173.784 -59.885 179.265z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-52.707 179.514C-52.707 179.514 -44.786 190.701 -45.422 179.421C-45.422 179.421 -45.415 179.089 -47.168 178.936C-51.915 178.522 -51.57 174.004 -52.707 179.514z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-45.494 179.522C-45.494 179.522 -37.534 190.15 -38.203 180.484C-38.203 180.484 -38.084 179.251 -39.738 178.95C-43.63 178.244 -43.841 174.995 -45.494 179.522z").setFill(f).setStroke(s);
+					f = "#ffffcc";
+					s = {
+						color : "#000000",
+						width : 0.5
+					};
+					g.createPath("M-38.618 179.602C-38.618 179.602 -30.718 191.163 -30.37 181.382C-30.37 181.382 -28.726 180.004 -30.472 179.782C-36.29 179.042 -35.492 174.588 -38.618 179.602z").setFill(f).setStroke(s);
+					f = "#e5e5b2";
+					s = null;
+					g.createPath("M-74.792 183.132L-82.45 181.601C-85.05 176.601 -87.15 170.451 -87.15 170.451C-87.15 170.451 -80.8 171.451 -68.3 174.251C-68.3 174.251 -67.424 177.569 -65.952 183.364L-74.792 183.132z").setFill(f).setStroke(s);
+					f = "#e5e5b2";
+					g.createPath("M-9.724 178.47C-11.39 175.964 -12.707 174.206 -13.357 173.8C-16.37 171.917 -12.227 172.294 -11.098 172.294C-11.098 172.294 5.473 172.294 7.356 173.047C7.356 173.047 7.88 175.289 8.564 178.68C8.564 178.68 -1.524 176.67 -9.724 178.47z").setFill(f).setStroke(s);
+					f = "#cc7226";
+					g.createPath("M43.88 40.321C71.601 44.281 97.121 8.641 98.881 -1.04C100.641 -10.72 90.521 -22.6 90.521 -22.6C91.841 -25.68 87.001 -39.76 81.721 -49C76.441 -58.24 60.54 -57.266 43 -58.24C27.16 -59.12 8.68 -35.8 7.36 -34.04C6.04 -32.28 12.2 6.001 13.52 11.721C14.84 17.441 12.2 43.841 12.2 43.841C46.44 34.741 16.16 36.361 43.88 40.321z").setFill(f).setStroke(s);
+					f = "#ea8e51";
+					g.createPath("M8.088 -33.392C6.792 -31.664 12.84 5.921 14.136 11.537C15.432 17.153 12.84 43.073 12.84 43.073C45.512 34.193 16.728 35.729 43.944 39.617C71.161 43.505 96.217 8.513 97.945 -0.992C99.673 -10.496 89.737 -22.16 89.737 -22.16C91.033 -25.184 86.281 -39.008 81.097 -48.08C75.913 -57.152 60.302 -56.195 43.08 -57.152C27.528 -58.016 9.384 -35.12 8.088 -33.392z").setFill(f).setStroke(s);
+					f = "#efaa7c";
+					g.createPath("M8.816 -32.744C7.544 -31.048 13.48 5.841 14.752 11.353C16.024 16.865 13.48 42.305 13.48 42.305C44.884 33.145 17.296 35.097 44.008 38.913C70.721 42.729 95.313 8.385 97.009 -0.944C98.705 -10.272 88.953 -21.72 88.953 -21.72C90.225 -24.688 85.561 -38.256 80.473 -47.16C75.385 -56.064 60.063 -55.125 43.16 -56.064C27.896 -56.912 10.088 -34.44 8.816 -32.744z").setFill(f).setStroke(s);
+					f = "#f4c6a8";
+					g.createPath("M9.544 -32.096C8.296 -30.432 14.12 5.761 15.368 11.169C16.616 16.577 14.12 41.537 14.12 41.537C43.556 32.497 17.864 34.465 44.072 38.209C70.281 41.953 94.409 8.257 96.073 -0.895C97.737 -10.048 88.169 -21.28 88.169 -21.28C89.417 -24.192 84.841 -37.504 79.849 -46.24C74.857 -54.976 59.824 -54.055 43.24 -54.976C28.264 -55.808 10.792 -33.76 9.544 -32.096z").setFill(f).setStroke(s);
+					f = "#f9e2d3";
+					g.createPath("M10.272 -31.448C9.048 -29.816 14.76 5.681 15.984 10.985C17.208 16.289 14.76 40.769 14.76 40.769C42.628 31.849 18.432 33.833 44.136 37.505C69.841 41.177 93.505 8.129 95.137 -0.848C96.769 -9.824 87.385 -20.84 87.385 -20.84C88.609 -23.696 84.121 -36.752 79.225 -45.32C74.329 -53.888 59.585 -52.985 43.32 -53.888C28.632 -54.704 11.496 -33.08 10.272 -31.448z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					g.createPath("M44.2 36.8C69.4 40.4 92.601 8 94.201 -0.8C95.801 -9.6 86.601 -20.4 86.601 -20.4C87.801 -23.2 83.4 -36 78.6 -44.4C73.8 -52.8 59.346 -51.914 43.4 -52.8C29 -53.6 12.2 -32.4 11 -30.8C9.8 -29.2 15.4 5.6 16.6 10.8C17.8 16 15.4 40 15.4 40C40.9 31.4 19 33.2 44.2 36.8z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M90.601 2.8C90.601 2.8 62.8 10.4 51.2 8.8C51.2 8.8 35.4 2.2 26.6 24C26.6 24 23 31.2 21 33.2C19 35.2 90.601 2.8 90.601 2.8z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M94.401 0.6C94.401 0.6 65.4 12.8 55.4 12.4C55.4 12.4 39 7.8 30.6 22.4C30.6 22.4 22.2 31.6 19 33.2C19 33.2 18.6 34.8 25 30.8L35.4 36C35.4 36 50.2 45.6 59.8 29.6C59.8 29.6 63.8 18.4 63.8 16.4C63.8 14.4 85 8.8 86.601 8.4C88.201 8 94.801 3.8 94.401 0.6z").setFill(f).setStroke(s);
+					f = "#99cc32";
+					g.createPath("M47 36.514C40.128 36.514 31.755 32.649 31.755 26.4C31.755 20.152 40.128 13.887 47 13.887C53.874 13.887 59.446 18.952 59.446 25.2C59.446 31.449 53.874 36.514 47 36.514z").setFill(f).setStroke(s);
+					f = "#659900";
+					g.createPath("M43.377 19.83C38.531 20.552 33.442 22.055 33.514 21.839C35.054 17.22 41.415 13.887 47 13.887C51.296 13.887 55.084 15.865 57.32 18.875C57.32 18.875 52.004 18.545 43.377 19.83z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					g.createPath("M55.4 19.6C55.4 19.6 51 16.4 51 18.6C51 18.6 54.6 23 55.4 19.6z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M45.4 27.726C42.901 27.726 40.875 25.7 40.875 23.2C40.875 20.701 42.901 18.675 45.4 18.675C47.9 18.675 49.926 20.701 49.926 23.2C49.926 25.7 47.9 27.726 45.4 27.726z").setFill(f).setStroke(s);
+					f = "#cc7226";
+					g.createPath("M-58.6 14.4C-58.6 14.4 -61.8 -6.8 -59.4 -11.2C-59.4 -11.2 -48.6 -21.2 -49 -24.8C-49 -24.8 -49.4 -42.8 -50.6 -43.6C-51.8 -44.4 -59.4 -50.4 -65.4 -44C-65.4 -44 -75.8 -26 -75 -19.6L-75 -17.6C-75 -17.6 -82.6 -18 -84.2 -16C-84.2 -16 -85.4 -10.8 -86.6 -10.4C-86.6 -10.4 -89.4 -8 -87.4 -5.2C-87.4 -5.2 -89.4 -2.8 -89 1.2L-81.4 5.2C-81.4 5.2 -79.4 19.6 -68.6 24.8C-63.764 27.129 -60.6 20.4 -58.6 14.4z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					g.createPath("M-59.6 12.56C-59.6 12.56 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.48 -40.36 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.96 -59.6 12.56z").setF [...]
+					f = "#eb955c";
+					g.createPath("M-51.05 -42.61C-52.14 -43.47 -59.63 -49.24 -65.48 -43C-65.48 -43 -75.62 -25.45 -74.84 -19.21L-74.84 -17.26C-74.84 -17.26 -82.25 -17.65 -83.81 -15.7C-83.81 -15.7 -84.98 -10.63 -86.15 -10.24C-86.15 -10.24 -88.88 -7.9 -86.93 -5.17C-86.93 -5.17 -88.88 -2.83 -88.49 1.07L-81.08 4.97C-81.08 4.97 -79.13 19.01 -68.6 24.08C-63.886 26.35 -60.8 19.79 -58.85 13.94C-58.85 13.94 -61.97 -6.73 -59.63 -11.02C-59.63 -11.02 -49.1 -20.77 -49.49 -24.28C-49.49 -24.28 -49.88 -41.83 -51.05 -42 [...]
+					f = "#f2b892";
+					g.createPath("M-51.5 -41.62C-52.48 -42.54 -59.86 -48.08 -65.56 -42C-65.56 -42 -75.44 -24.9 -74.68 -18.82L-74.68 -16.92C-74.68 -16.92 -81.9 -17.3 -83.42 -15.4C-83.42 -15.4 -84.56 -10.46 -85.7 -10.08C-85.7 -10.08 -88.36 -7.8 -86.46 -5.14C-86.46 -5.14 -88.36 -2.86 -87.98 0.94L-80.76 4.74C-80.76 4.74 -78.86 18.42 -68.6 23.36C-64.006 25.572 -61 19.18 -59.1 13.48C-59.1 13.48 -62.14 -6.66 -59.86 -10.84C-59.86 -10.84 -49.6 -20.34 -49.98 -23.76C-49.98 -23.76 -50.36 -40.86 -51.5 -41.62z").set [...]
+					f = "#f8dcc8";
+					g.createPath("M-51.95 -40.63C-52.82 -41.61 -60.09 -46.92 -65.64 -41C-65.64 -41 -75.26 -24.35 -74.52 -18.43L-74.52 -16.58C-74.52 -16.58 -81.55 -16.95 -83.03 -15.1C-83.03 -15.1 -84.14 -10.29 -85.25 -9.92C-85.25 -9.92 -87.84 -7.7 -85.99 -5.11C-85.99 -5.11 -87.84 -2.89 -87.47 0.81L-80.44 4.51C-80.44 4.51 -78.59 17.83 -68.6 22.64C-64.127 24.794 -61.2 18.57 -59.35 13.02C-59.35 13.02 -62.31 -6.59 -60.09 -10.66C-60.09 -10.66 -50.1 -19.91 -50.47 -23.24C-50.47 -23.24 -50.84 -39.89 -51.95 -40. [...]
+					f = "#ffffff";
+					g.createPath("M-59.6 12.46C-59.6 12.46 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.16 -40.68 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.86 -59.6 12.46z").setF [...]
+					f = "#cccccc";
+					g.createPath("M-62.7 6.2C-62.7 6.2 -84.3 -4 -85.2 -4.8C-85.2 -4.8 -76.1 3.4 -75.3 3.4C-74.5 3.4 -62.7 6.2 -62.7 6.2z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-79.8 0C-79.8 0 -61.4 3.6 -61.4 8C-61.4 10.912 -61.643 24.331 -67 22.8C-75.4 20.4 -71.8 6 -79.8 0z").setFill(f).setStroke(s);
+					f = "#99cc32";
+					g.createPath("M-71.4 3.8C-71.4 3.8 -62.422 5.274 -61.4 8C-60.8 9.6 -60.137 17.908 -65.6 19C-70.152 19.911 -72.382 9.69 -71.4 3.8z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M14.595 46.349C14.098 44.607 15.409 44.738 17.2 44.2C19.2 43.6 31.4 39.8 32.2 37.2C33 34.6 46.2 39 46.2 39C48 39.8 52.4 42.4 52.4 42.4C57.2 43.6 63.8 44 63.8 44C66.2 45 69.6 47.8 69.6 47.8C84.2 58 96.601 50.8 96.601 50.8C116.601 44.2 110.601 27 110.601 27C107.601 18 110.801 14.6 110.801 14.6C111.001 10.8 118.201 17.2 118.201 17.2C120.801 21.4 121.601 26.4 121.601 26.4C129.601 37.6 126.201 19.8 126.201 19.8C126.401 18.8 123.601 15.2 123.601 14C123.601 12.8 121.801 9.4 1 [...]
+					f = "#000000";
+					g.createPath("M209.401 -120C209.401 -120 183.801 -112 181.001 -93.2C181.001 -93.2 178.601 -70.4 199.001 -52.8C199.001 -52.8 199.401 -46.4 201.401 -43.2C201.401 -43.2 199.801 -38.4 218.601 -46L245.801 -54.4C245.801 -54.4 252.201 -56.8 257.401 -65.6C262.601 -74.4 277.801 -93.2 274.201 -118.4C274.201 -118.4 275.401 -129.6 269.401 -130C269.401 -130 261.001 -131.6 253.801 -124C253.801 -124 247.001 -120.8 244.601 -121.2L209.401 -120z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M264.022 -120.99C264.022 -120.99 266.122 -129.92 261.282 -125.08C261.282 -125.08 254.242 -119.36 246.761 -119.36C246.761 -119.36 232.241 -117.16 227.841 -103.96C227.841 -103.96 223.881 -77.12 231.801 -71.4C231.801 -71.4 236.641 -63.92 243.681 -70.52C250.722 -77.12 266.222 -107.35 264.022 -120.99z").setFill(f).setStroke(s);
+					f = "#323232";
+					g.createPath("M263.648 -120.632C263.648 -120.632 265.738 -129.376 260.986 -124.624C260.986 -124.624 254.074 -119.008 246.729 -119.008C246.729 -119.008 232.473 -116.848 228.153 -103.888C228.153 -103.888 224.265 -77.536 232.041 -71.92C232.041 -71.92 236.793 -64.576 243.705 -71.056C250.618 -77.536 265.808 -107.24 263.648 -120.632z").setFill(f).setStroke(s);
+					f = "#666666";
+					g.createPath("M263.274 -120.274C263.274 -120.274 265.354 -128.832 260.69 -124.168C260.69 -124.168 253.906 -118.656 246.697 -118.656C246.697 -118.656 232.705 -116.536 228.465 -103.816C228.465 -103.816 224.649 -77.952 232.281 -72.44C232.281 -72.44 236.945 -65.232 243.729 -71.592C250.514 -77.952 265.394 -107.13 263.274 -120.274z").setFill(f).setStroke(s);
+					f = "#999999";
+					g.createPath("M262.9 -119.916C262.9 -119.916 264.97 -128.288 260.394 -123.712C260.394 -123.712 253.738 -118.304 246.665 -118.304C246.665 -118.304 232.937 -116.224 228.777 -103.744C228.777 -103.744 225.033 -78.368 232.521 -72.96C232.521 -72.96 237.097 -65.888 243.753 -72.128C250.41 -78.368 264.98 -107.02 262.9 -119.916z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M262.526 -119.558C262.526 -119.558 264.586 -127.744 260.098 -123.256C260.098 -123.256 253.569 -117.952 246.633 -117.952C246.633 -117.952 233.169 -115.912 229.089 -103.672C229.089 -103.672 225.417 -78.784 232.761 -73.48C232.761 -73.48 237.249 -66.544 243.777 -72.664C250.305 -78.784 264.566 -106.91 262.526 -119.558z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					g.createPath("M262.151 -119.2C262.151 -119.2 264.201 -127.2 259.801 -122.8C259.801 -122.8 253.401 -117.6 246.601 -117.6C246.601 -117.6 233.401 -115.6 229.401 -103.6C229.401 -103.6 225.801 -79.2 233.001 -74C233.001 -74 237.401 -67.2 243.801 -73.2C250.201 -79.2 264.151 -106.8 262.151 -119.2z").setFill(f).setStroke(s);
+					f = "#992600";
+					g.createPath("M50.6 84C50.6 84 30.2 64.8 22.2 64C22.2 64 -12.2 60 -27 78C-27 78 -9.4 57.6 18.2 63.2C18.2 63.2 -3.4 58.8 -15.8 62C-15.8 62 -32.6 62 -42.2 76L-45 80.8C-45 80.8 -41 66 -22.6 60C-22.6 60 0.2 55.2 11 60C11 60 -10.6 53.2 -20.6 55.2C-20.6 55.2 -51 52.8 -63.8 79.2C-63.8 79.2 -59.8 64.8 -45 57.6C-45 57.6 -31.4 48.8 -11 51.6C-11 51.6 3.4 54.8 8.6 57.2C13.8 59.6 12.6 56.8 4.2 52C4.2 52 -1.4 42 -15.4 42.4C-15.4 42.4 -58.2 46 -68.6 58C-68.6 58 -55 46.8 -44.6 44C-44.6 44 -22.2 36  [...]
+					f = "#cccccc";
+					g.createPath("M189 278C189 278 173.5 241.5 161 232C161 232 187 248 190.5 266C190.5 266 190.5 276 189 278z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M236 285.5C236 285.5 209.5 230.5 191 206.5C191 206.5 234.5 244 239.5 270.5L240 276L237 273.5C237 273.5 236.5 282.5 236 285.5z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M292.5 237C292.5 237 230 177.5 228.5 175C228.5 175 289 241 292 248.5C292 248.5 290 239.5 292.5 237z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M104 280.5C104 280.5 123.5 228.5 142.5 251C142.5 251 157.5 261 157 264C157 264 153 257.5 135 258C135 258 116 255 104 280.5z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M294.5 153C294.5 153 249.5 124.5 242 123C230.193 120.639 291.5 152 296.5 162.5C296.5 162.5 298.5 160 294.5 153z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M143.801 259.601C143.801 259.601 164.201 257.601 171.001 250.801L175.401 254.401L193.001 216.001L196.601 221.201C196.601 221.201 211.001 206.401 210.201 198.401C209.401 190.401 223.001 204.401 223.001 204.401C223.001 204.401 222.201 192.801 229.401 199.601C229.401 199.601 227.001 184.001 235.401 192.001C235.401 192.001 224.864 161.844 247.401 187.601C253.001 194.001 248.601 187.201 248.601 187.201C248.601 187.201 222.601 139.201 244.201 153.601C244.201 153.601 246.201  [...]
+					f = "#000000";
+					g.createPath("M109.401 -97.2C109.401 -97.2 97.801 -105.2 93.801 -104.8C89.801 -104.4 121.401 -113.6 162.601 -86C162.601 -86 167.401 -83.2 171.001 -83.6C171.001 -83.6 174.201 -81.2 171.401 -77.6C171.401 -77.6 162.601 -68 173.801 -56.8C173.801 -56.8 192.201 -50 186.601 -58.8C186.601 -58.8 197.401 -54.8 199.801 -50.8C202.201 -46.8 201.001 -50.8 201.001 -50.8C201.001 -50.8 194.601 -58 188.601 -63.2C188.601 -63.2 183.401 -65.2 180.601 -73.6C177.801 -82 175.401 -92 179.801 -95.2C179.801 - [...]
+					f = "#cc7226";
+					g.createPath("M180.801 -106.4C180.801 -106.4 170.601 -113.8 168.601 -113.8C166.601 -113.8 154.201 -124 150.001 -123.6C145.801 -123.2 133.601 -133.2 106.201 -125C106.201 -125 105.601 -127 109.201 -127.8C109.201 -127.8 115.601 -130 116.001 -130.6C116.001 -130.6 136.201 -134.8 143.401 -131.2C143.401 -131.2 152.601 -128.6 158.801 -122.4C158.801 -122.4 170.001 -119.2 173.201 -120.2C173.201 -120.2 182.001 -118 182.401 -116.2C182.401 -116.2 188.201 -113.2 186.401 -110.6C186.401 -110.6 186. [...]
+					f = "#cc7226";
+					g.createPath("M168.33 -108.509C169.137 -107.877 170.156 -107.779 170.761 -106.97C170.995 -106.656 170.706 -106.33 170.391 -106.233C169.348 -105.916 168.292 -106.486 167.15 -105.898C166.748 -105.691 166.106 -105.873 165.553 -106.022C163.921 -106.463 162.092 -106.488 160.401 -105.8C158.416 -106.929 156.056 -106.345 153.975 -107.346C153.917 -107.373 153.695 -107.027 153.621 -107.054C150.575 -108.199 146.832 -107.916 144.401 -110.2C141.973 -110.612 139.616 -111.074 137.188 -111.754C135. [...]
+					f = "#cc7226";
+					g.createPath("M91.696 -122.739C89.178 -124.464 86.81 -125.57 84.368 -127.356C84.187 -127.489 83.827 -127.319 83.625 -127.441C82.618 -128.05 81.73 -128.631 80.748 -129.327C80.209 -129.709 79.388 -129.698 78.88 -129.956C76.336 -131.248 73.707 -131.806 71.2 -133C71.882 -133.638 73.004 -133.394 73.6 -134.2C73.795 -133.92 74.033 -133.636 74.386 -133.827C76.064 -134.731 77.914 -134.884 79.59 -134.794C81.294 -134.702 83.014 -134.397 84.789 -134.125C85.096 -134.078 85.295 -133.555 85.618 -1 [...]
+					f = "#cc7226";
+					g.createPath("M59.198 -115.391C56.044 -116.185 52.994 -116.07 49.978 -117.346C49.911 -117.374 49.688 -117.027 49.624 -117.054C48.258 -117.648 47.34 -118.614 46.264 -119.66C45.351 -120.548 43.693 -120.161 42.419 -120.648C42.095 -120.772 41.892 -121.284 41.591 -121.323C40.372 -121.48 39.445 -122.429 38.4 -123C40.736 -123.795 43.147 -123.764 45.609 -124.148C45.722 -124.166 45.867 -123.845 46 -123.845C46.136 -123.845 46.266 -124.066 46.4 -124.2C46.595 -123.92 46.897 -123.594 47.154 -123 [...]
+					f = "#cc7226";
+					g.createPath("M45.338 -71.179C43.746 -72.398 43.162 -74.429 42.034 -76.221C41.82 -76.561 42.094 -76.875 42.411 -76.964C42.971 -77.123 43.514 -76.645 43.923 -76.443C45.668 -75.581 47.203 -74.339 49.2 -74.2C51.19 -71.966 55.45 -71.581 55.457 -68.2C55.458 -67.341 54.03 -68.259 53.6 -67.4C51.149 -68.403 48.76 -68.3 46.38 -69.767C45.763 -70.148 46.093 -70.601 45.338 -71.179z").setFill(f).setStroke(s);
+					f = "#cc7226";
+					g.createPath("M17.8 -123.756C17.935 -123.755 24.966 -123.522 24.949 -123.408C24.904 -123.099 17.174 -122.05 16.81 -122.22C16.646 -122.296 9.134 -119.866 9 -120C9.268 -120.135 17.534 -123.756 17.8 -123.756z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M33.2 -114C33.2 -114 18.4 -112.2 14 -111C9.6 -109.8 -9 -102.2 -12 -100.2C-12 -100.2 -25.4 -94.8 -42.4 -74.8C-42.4 -74.8 -34.8 -78.2 -32.6 -81C-32.6 -81 -19 -93.6 -19.2 -91C-19.2 -91 -7 -99.6 -7.6 -97.4C-7.6 -97.4 16.8 -108.6 14.8 -105.4C14.8 -105.4 36.4 -110 35.4 -108C35.4 -108 54.2 -103.6 51.4 -103.4C51.4 -103.4 45.6 -102.2 52 -98.6C52 -98.6 48.6 -94.2 43.2 -98.2C37.8 -102.2 40.8 -100 35.8 -99C35.8 -99 33.2 -98.2 28.6 -102.2C28.6 -102.2 23 -106.8 14.2 -103.2C14.2 -103 [...]
+					s = {
+						color : "#4c0000",
+						width : 2
+					};
+					f = null;
+					g.createPath("M51.4 85C51.4 85 36.4 68.2 28 65.6C28 65.6 14.6 58.8 -10 66.6").setFill(f).setStroke(s);
+					s = {
+						color : "#4c0000",
+						width : 2
+					};
+					g.createPath("M24.8 64.2C24.8 64.2 -0.4 56.2 -15.8 60.4C-15.8 60.4 -34.2 62.4 -42.6 76.2").setFill(f).setStroke(s);
+					s = {
+						color : "#4c0000",
+						width : 2
+					};
+					g.createPath("M21.2 63C21.2 63 4.2 55.8 -10.6 53.6C-10.6 53.6 -27.2 51 -43.8 58.2C-43.8 58.2 -56 64.2 -61.4 74.4").setFill(f).setStroke(s);
+					s = {
+						color : "#4c0000",
+						width : 2
+					};
+					g.createPath("M22.2 63.4C22.2 63.4 6.8 52.4 5.8 51C5.8 51 -1.2 40 -14.2 39.6C-14.2 39.6 -35.6 40.4 -52.8 48.4").setFill(f).setStroke(s);
+					f = "#000000";
+					s = null;
+					g.createPath("M20.895 54.407C22.437 55.87 49.4 84.8 49.4 84.8C84.6 121.401 56.6 87.2 56.6 87.2C49 82.4 39.8 63.6 39.8 63.6C38.6 60.8 53.8 70.8 53.8 70.8C57.8 71.6 71.4 90.8 71.4 90.8C64.6 88.4 69.4 95.6 69.4 95.6C72.2 97.6 92.601 113.201 92.601 113.201C96.201 117.201 100.201 118.801 100.201 118.801C114.201 113.601 107.801 126.801 107.801 126.801C110.201 133.601 115.801 122.001 115.801 122.001C127.001 105.2 110.601 107.601 110.601 107.601C80.6 110.401 73.8 94.4 73.8 94.4C71.4 92 80.2 [...]
+					f = "#4c0000";
+					g.createPath("M-3 42.8C-3 42.8 8.6 48.4 11.2 51.2C13.8 54 27.8 65.4 27.8 65.4C27.8 65.4 22.4 63.4 19.8 61.6C17.2 59.8 6.4 51.6 6.4 51.6C6.4 51.6 2.6 45.6 -3 42.8z").setFill(f).setStroke(s);
+					f = "#99cc32";
+					g.createPath("M-61.009 11.603C-60.672 11.455 -61.196 8.743 -61.4 8.2C-62.422 5.474 -71.4 4 -71.4 4C-71.627 5.365 -71.682 6.961 -71.576 8.599C-71.576 8.599 -66.708 14.118 -61.009 11.603z").setFill(f).setStroke(s);
+					f = "#659900";
+					g.createPath("M-61.009 11.403C-61.458 11.561 -61.024 8.669 -61.2 8.2C-62.222 5.474 -71.4 3.9 -71.4 3.9C-71.627 5.265 -71.682 6.861 -71.576 8.499C-71.576 8.499 -67.308 13.618 -61.009 11.403z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-65.4 11.546C-66.025 11.546 -66.531 10.406 -66.531 9C-66.531 7.595 -66.025 6.455 -65.4 6.455C-64.775 6.455 -64.268 7.595 -64.268 9C-64.268 10.406 -64.775 11.546 -65.4 11.546z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-65.4 9z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-111 109.601C-111 109.601 -116.6 119.601 -91.8 113.601C-91.8 113.601 -77.8 112.401 -75.4 110.001C-74.2 110.801 -65.834 113.734 -63 114.401C-56.2 116.001 -47.8 106 -47.8 106C-47.8 106 -43.2 95.5 -40.4 95.5C-37.6 95.5 -40.8 97.1 -40.8 97.1C-40.8 97.1 -47.4 107.201 -47 108.801C-47 108.801 -52.2 128.801 -68.2 129.601C-68.2 129.601 -84.35 130.551 -83 136.401C-83 136.401 -74.2 134.001 -71.8 136.401C-71.8 136.401 -61 136.001 -69 142.401L-75.8 154.001C-75.8 154.001 -75.66 157 [...]
+					f = "#e59999";
+					g.createPath("M-112.2 113.601C-112.2 113.601 -114.2 123.201 -77.4 112.801C-77.4 112.801 -73 112.801 -70.6 113.601C-68.2 114.401 -56.2 117.201 -54.2 116.001C-54.2 116.001 -61.4 129.601 -73 128.001C-73 128.001 -86.2 129.601 -85.8 134.401C-85.8 134.401 -81.8 141.601 -77 144.001C-77 144.001 -74.2 146.401 -74.6 149.601C-75 152.801 -77.8 154.401 -79.8 155.201C-81.8 156.001 -85 152.801 -86.6 152.801C-88.2 152.801 -96.6 146.401 -101 141.601C-105.4 136.801 -113.8 124.801 -113.4 122.001C-113  [...]
+					f = "#b26565";
+					g.createPath("M-109 131.051C-106.4 135.001 -103.2 139.201 -101 141.601C-96.6 146.401 -88.2 152.801 -86.6 152.801C-85 152.801 -81.8 156.001 -79.8 155.201C-77.8 154.401 -75 152.801 -74.6 149.601C-74.2 146.401 -77 144.001 -77 144.001C-80.066 142.468 -82.806 138.976 -84.385 136.653C-84.385 136.653 -84.2 139.201 -89.4 138.401C-94.6 137.601 -99.8 134.801 -101.4 131.601C-103 128.401 -105.4 126.001 -103.8 129.601C-102.2 133.201 -99.8 136.801 -98.2 137.201C-96.6 137.601 -97 138.801 -99.4 138 [...]
+					f = "#992600";
+					g.createPath("M-111.6 110.001C-111.6 110.001 -109.8 96.4 -108.6 92.4C-108.6 92.4 -109.4 85.6 -107 81.4C-104.6 77.2 -102.6 71 -99.6 65.6C-96.6 60.2 -96.4 56.2 -92.4 54.6C-88.4 53 -82.4 44.4 -79.6 43.4C-76.8 42.4 -77 43.2 -77 43.2C-77 43.2 -70.2 28.4 -56.6 32.4C-56.6 32.4 -72.8 29.6 -57 20.2C-57 20.2 -61.8 21.3 -58.5 14.3C-56.299 9.632 -56.8 16.4 -67.8 28.2C-67.8 28.2 -72.8 36.8 -78 39.8C-83.2 42.8 -95.2 49.8 -96.4 53.6C-97.6 57.4 -100.8 63.2 -102.8 64.8C-104.8 66.4 -107.6 70.6 -108 7 [...]
+					f = "#ffffff";
+					g.createPath("M-120.2 114.601C-120.2 114.601 -122.2 113.201 -126.6 119.201C-126.6 119.201 -119.3 152.201 -119.3 153.601C-119.3 153.601 -118.2 151.501 -119.5 144.301C-120.8 137.101 -121.7 124.401 -121.7 124.401L-120.2 114.601z").setFill(f).setStroke(s);
+					f = "#992600";
+					g.createPath("M-98.6 54C-98.6 54 -116.2 57.2 -115.8 86.4L-116.6 111.201C-116.6 111.201 -117.8 85.6 -119 84C-120.2 82.4 -116.2 71.2 -119.4 77.2C-119.4 77.2 -133.4 91.2 -125.4 112.401C-125.4 112.401 -123.9 115.701 -126.9 111.101C-126.9 111.101 -131.5 98.5 -130.4 92.1C-130.4 92.1 -130.2 89.9 -128.3 87.1C-128.3 87.1 -119.7 75.4 -117 73.1C-117 73.1 -115.2 58.7 -99.8 53.5C-99.8 53.5 -94.1 51.2 -98.6 54z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M40.8 -12.2C41.46 -12.554 41.451 -13.524 42.031 -13.697C43.18 -14.041 43.344 -15.108 43.862 -15.892C44.735 -17.211 44.928 -18.744 45.51 -20.235C45.782 -20.935 45.809 -21.89 45.496 -22.55C44.322 -25.031 43.62 -27.48 42.178 -29.906C41.91 -30.356 41.648 -31.15 41.447 -31.748C40.984 -33.132 39.727 -34.123 38.867 -35.443C38.579 -35.884 39.104 -36.809 38.388 -36.893C37.491 -36.998 36.042 -37.578 35.809 -36.552C35.221 -33.965 36.232 -31.442 37.2 -29C36.418 -28.308 36.752 -27. [...]
+					f = "#000000";
+					g.createPath("M31.959 -16.666C32.083 -16.743 31.928 -17.166 32.037 -17.382C32.199 -17.706 32.602 -17.894 32.764 -18.218C32.873 -18.434 32.71 -18.814 32.846 -18.956C35.179 -21.403 35.436 -24.427 34.4 -27.4C35.424 -28.02 35.485 -29.282 35.06 -30.129C34.207 -31.829 34.014 -33.755 33.039 -35.298C32.237 -36.567 30.659 -37.811 29.288 -36.508C28.867 -36.108 28.546 -35.321 28.824 -34.609C28.888 -34.446 29.173 -34.3 29.146 -34.218C29.039 -33.894 28.493 -33.67 28.487 -33.398C28.457 -31.902 27 [...]
+					f = "#000000";
+					g.createPath("M94.771 -26.977C96.16 -25.185 96.45 -22.39 94.401 -21C94.951 -17.691 98.302 -19.67 100.401 -20.2C100.292 -20.588 100.519 -20.932 100.802 -20.937C101.859 -20.952 102.539 -21.984 103.601 -21.8C104.035 -23.357 105.673 -24.059 106.317 -25.439C108.043 -29.134 107.452 -33.407 104.868 -36.653C104.666 -36.907 104.883 -37.424 104.759 -37.786C104.003 -39.997 101.935 -40.312 100.001 -41C98.824 -44.875 98.163 -48.906 96.401 -52.6C94.787 -52.85 94.089 -54.589 92.752 -55.309C91.419  [...]
+					f = "#000000";
+					g.createPath("M57.611 -8.591C56.124 -6.74 52.712 -4.171 55.629 -2.243C55.823 -2.114 56.193 -2.11 56.366 -2.244C58.387 -3.809 60.39 -4.712 62.826 -5.294C62.95 -5.323 63.224 -4.856 63.593 -5.017C65.206 -5.72 67.216 -5.662 68.4 -7C72.167 -6.776 75.732 -7.892 79.123 -9.2C80.284 -9.648 81.554 -10.207 82.755 -10.709C84.131 -11.285 85.335 -12.213 86.447 -13.354C86.58 -13.49 86.934 -13.4 87.201 -13.4C87.161 -14.263 88.123 -14.39 88.37 -15.012C88.462 -15.244 88.312 -15.64 88.445 -15.742C90.5 [...]
+					f = "#000000";
+					g.createPath("M2.2 -58C2.2 -58 -7.038 -60.872 -18.2 -35.2C-18.2 -35.2 -20.6 -30 -23 -28C-25.4 -26 -36.6 -22.4 -38.6 -18.4L-49 -2.4C-49 -2.4 -34.2 -18.4 -31 -20.8C-31 -20.8 -23 -29.2 -26.2 -22.4C-26.2 -22.4 -40.2 -11.6 -39 -2.4C-39 -2.4 -44.6 12 -45.4 14C-45.4 14 -29.4 -18 -27 -19.2C-24.6 -20.4 -23.4 -20.4 -24.6 -16.8C-25.8 -13.2 -26.2 3.2 -29 5.2C-29 5.2 -21 -15.2 -21.8 -18.4C-21.8 -18.4 -18.6 -22 -16.2 -16.8L-17.4 -0.8L-13 11.2C-13 11.2 -15.4 0 -13.8 -15.6C-13.8 -15.6 -15.8 -26 -11 [...]
+					f = "#000000";
+					g.createPath("M-17.8 -41.6C-17.8 -41.6 -30.6 -41.6 -33.8 -36.4L-41 -26.8C-41 -26.8 -23.8 -36.8 -19.8 -38C-15.8 -39.2 -17.8 -41.6 -17.8 -41.6z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-57.8 -35.2C-57.8 -35.2 -59.8 -34 -60.2 -31.2C-60.6 -28.4 -63 -28 -62.2 -25.2C-61.4 -22.4 -59.4 -20 -59.4 -24C-59.4 -28 -57.8 -30 -57 -31.2C-56.2 -32.4 -54.6 -36.8 -57.8 -35.2z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-66.6 26C-66.6 26 -75 22 -78.2 18.4C-81.4 14.8 -80.948 19.966 -85.8 19.6C-91.647 19.159 -90.6 3.2 -90.6 3.2L-94.6 10.8C-94.6 10.8 -95.8 25.2 -87.8 22.8C-83.893 21.628 -82.6 23.2 -84.2 24C-85.8 24.8 -78.6 25.2 -81.4 26.8C-84.2 28.4 -69.8 23.2 -72.2 33.6L-66.6 26z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-79.2 40.4C-79.2 40.4 -94.6 44.8 -98.2 35.2C-98.2 35.2 -103 37.6 -100.8 40.6C-98.6 43.6 -97.4 44 -97.4 44C-97.4 44 -92 45.2 -92.6 46C-93.2 46.8 -95.6 50.2 -95.6 50.2C-95.6 50.2 -85.4 44.2 -79.2 40.4z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					g.createPath("M149.201 118.601C148.774 120.735 147.103 121.536 145.201 122.201C143.284 121.243 140.686 118.137 138.801 120.201C138.327 119.721 137.548 119.661 137.204 118.999C136.739 118.101 137.011 117.055 136.669 116.257C136.124 114.985 135.415 113.619 135.601 112.201C137.407 111.489 138.002 109.583 137.528 107.82C137.459 107.563 137.03 107.366 137.23 107.017C137.416 106.694 137.734 106.467 138.001 106.2C137.866 106.335 137.721 106.568 137.61 106.548C137 106.442 137.124 105.805 13 [...]
+					f = "#ffffff";
+					g.createPath("M139.6 138.201C139.593 136.463 137.992 134.707 139.201 133.001C139.336 133.135 139.467 133.356 139.601 133.356C139.736 133.356 139.867 133.135 140.001 133.001C141.496 135.217 145.148 136.145 145.006 138.991C144.984 139.438 143.897 140.356 144.801 141.001C142.988 142.349 142.933 144.719 142.001 146.601C140.763 146.315 139.551 145.952 138.401 145.401C138.753 143.915 138.636 142.231 139.456 140.911C139.89 140.213 139.603 139.134 139.6 138.201z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-26.6 129.201C-26.6 129.201 -43.458 139.337 -29.4 124.001C-20.6 114.401 -10.6 108.801 -10.6 108.801C-10.6 108.801 -0.2 104.4 3.4 103.2C7 102 22.2 96.8 25.4 96.4C28.6 96 38.2 92 45 96C51.8 100 59.8 104.4 59.8 104.4C59.8 104.4 43.4 96 39.8 98.4C36.2 100.8 29 100.4 23 103.6C23 103.6 8.2 108.001 5 110.001C1.8 112.001 -8.6 123.601 -10.2 122.801C-11.8 122.001 -9.8 121.601 -8.6 118.801C-7.4 116.001 -9.4 114.401 -17.4 120.801C-25.4 127.201 -26.6 129.201 -26.6 129.201z").setFi [...]
+					f = "#000000";
+					g.createPath("M-19.195 123.234C-19.195 123.234 -17.785 110.194 -9.307 111.859C-9.307 111.859 -1.081 107.689 1.641 105.721C1.641 105.721 9.78 104.019 11.09 103.402C29.569 94.702 44.288 99.221 44.835 98.101C45.381 96.982 65.006 104.099 68.615 108.185C69.006 108.628 58.384 102.588 48.686 100.697C40.413 99.083 18.811 100.944 7.905 106.48C4.932 107.989 -4.013 113.773 -6.544 113.662C-9.075 113.55 -19.195 123.234 -19.195 123.234z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-23 148.801C-23 148.801 -38.2 146.401 -21.4 144.801C-21.4 144.801 -3.4 142.801 0.6 137.601C0.6 137.601 14.2 128.401 17 128.001C19.8 127.601 49.8 120.401 50.2 118.001C50.6 115.601 56.2 115.601 57.8 116.401C59.4 117.201 58.6 118.401 55.8 119.201C53 120.001 21.8 136.401 15.4 137.601C9 138.801 -2.6 146.401 -7.4 147.601C-12.2 148.801 -23 148.801 -23 148.801z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-3.48 141.403C-3.48 141.403 -12.062 140.574 -3.461 139.755C-3.461 139.755 5.355 136.331 7.403 133.668C7.403 133.668 14.367 128.957 15.8 128.753C17.234 128.548 31.194 124.861 31.399 123.633C31.604 122.404 65.67 109.823 70.09 113.013C73.001 115.114 63.1 113.437 53.466 117.847C52.111 118.467 18.258 133.054 14.981 133.668C11.704 134.283 5.765 138.174 3.307 138.788C0.85 139.403 -3.48 141.403 -3.48 141.403z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-11.4 143.601C-11.4 143.601 -6.2 143.201 -7.4 144.801C-8.6 146.401 -11 145.601 -11 145.601L-11.4 143.601z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-18.6 145.201C-18.6 145.201 -13.4 144.801 -14.6 146.401C-15.8 148.001 -18.2 147.201 -18.2 147.201L-18.6 145.201z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-29 146.801C-29 146.801 -23.8 146.401 -25 148.001C-26.2 149.601 -28.6 148.801 -28.6 148.801L-29 146.801z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-36.6 147.601C-36.6 147.601 -31.4 147.201 -32.6 148.801C-33.8 150.401 -36.2 149.601 -36.2 149.601L-36.6 147.601z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M1.8 108.001C1.8 108.001 6.2 108.001 5 109.601C3.8 111.201 0.6 110.801 0.6 110.801L1.8 108.001z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-8.2 113.601C-8.2 113.601 -1.694 111.46 -4.2 114.801C-5.4 116.401 -7.8 115.601 -7.8 115.601L-8.2 113.601z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-19.4 118.401C-19.4 118.401 -14.2 118.001 -15.4 119.601C-16.6 121.201 -19 120.401 -19 120.401L-19.4 118.401z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-27 124.401C-27 124.401 -21.8 124.001 -23 125.601C-24.2 127.201 -26.6 126.401 -26.6 126.401L-27 124.401z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-33.8 129.201C-33.8 129.201 -28.6 128.801 -29.8 130.401C-31 132.001 -33.4 131.201 -33.4 131.201L-33.8 129.201z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M5.282 135.598C5.282 135.598 12.203 135.066 10.606 137.195C9.009 139.325 5.814 138.26 5.814 138.26L5.282 135.598z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M15.682 130.798C15.682 130.798 22.603 130.266 21.006 132.395C19.409 134.525 16.214 133.46 16.214 133.46L15.682 130.798z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M26.482 126.398C26.482 126.398 33.403 125.866 31.806 127.995C30.209 130.125 27.014 129.06 27.014 129.06L26.482 126.398z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M36.882 121.598C36.882 121.598 43.803 121.066 42.206 123.195C40.609 125.325 37.414 124.26 37.414 124.26L36.882 121.598z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M9.282 103.598C9.282 103.598 16.203 103.066 14.606 105.195C13.009 107.325 9.014 107.06 9.014 107.06L9.282 103.598z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M19.282 100.398C19.282 100.398 26.203 99.866 24.606 101.995C23.009 104.125 18.614 103.86 18.614 103.86L19.282 100.398z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-3.4 140.401C-3.4 140.401 1.8 140.001 0.6 141.601C-0.6 143.201 -3 142.401 -3 142.401L-3.4 140.401z").setFill(f).setStroke(s);
+					f = "#992600";
+					g.createPath("M-76.6 41.2C-76.6 41.2 -81 50 -81.4 53.2C-81.4 53.2 -80.6 44.4 -79.4 42.4C-78.2 40.4 -76.6 41.2 -76.6 41.2z").setFill(f).setStroke(s);
+					f = "#992600";
+					g.createPath("M-95 55.2C-95 55.2 -98.2 69.6 -97.8 72.4C-97.8 72.4 -99 60.8 -98.6 59.6C-98.2 58.4 -95 55.2 -95 55.2z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-74.2 -19.4L-74.4 -16.2L-76.6 -16C-76.6 -16 -62.4 -3.4 -61.8 4.2C-61.8 4.2 -61 -4 -74.2 -19.4z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-70.216 -18.135C-70.647 -18.551 -70.428 -19.296 -70.836 -19.556C-71.645 -20.072 -69.538 -20.129 -69.766 -20.845C-70.149 -22.051 -69.962 -22.072 -70.084 -23.348C-70.141 -23.946 -69.553 -25.486 -69.168 -25.926C-67.722 -27.578 -69.046 -30.51 -67.406 -32.061C-67.102 -32.35 -66.726 -32.902 -66.441 -33.32C-65.782 -34.283 -64.598 -34.771 -63.648 -35.599C-63.33 -35.875 -63.531 -36.702 -62.962 -36.61C-62.248 -36.495 -61.007 -36.625 -61.052 -35.784C-61.165 -33.664 -62.494 -31.9 [...]
+					f = "#000000";
+					g.createPath("M-73.8 -16.4C-73.8 -16.4 -73.4 -9.6 -71 -8C-68.6 -6.4 -69.8 -7.2 -73 -8.4C-76.2 -9.6 -75 -10.4 -75 -10.4C-75 -10.4 -77.8 -10 -75.4 -8C-73 -6 -69.4 -3.6 -71 -3.6C-72.6 -3.6 -80.2 -7.6 -80.2 -10.4C-80.2 -13.2 -81.2 -17.3 -81.2 -17.3C-81.2 -17.3 -80.1 -18.1 -75.3 -18C-75.3 -18 -73.9 -17.3 -73.8 -16.4z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-74.6 2.2C-74.6 2.2 -83.12 -0.591 -101.6 2.8C-101.6 2.8 -92.569 0.722 -73.8 3C-63.5 4.25 -74.6 2.2 -74.6 2.2z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-72.502 2.129C-72.502 2.129 -80.748 -1.389 -99.453 0.392C-99.453 0.392 -90.275 -0.897 -71.774 2.995C-61.62 5.131 -72.502 2.129 -72.502 2.129z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-70.714 2.222C-70.714 2.222 -78.676 -1.899 -97.461 -1.514C-97.461 -1.514 -88.213 -2.118 -70.052 3.14C-60.086 6.025 -70.714 2.222 -70.714 2.222z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-69.444 2.445C-69.444 2.445 -76.268 -1.862 -93.142 -2.96C-93.142 -2.96 -84.803 -2.79 -68.922 3.319C-60.206 6.672 -69.444 2.445 -69.444 2.445z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M45.84 12.961C45.84 12.961 44.91 13.605 45.124 12.424C45.339 11.243 73.547 -1.927 77.161 -1.677C77.161 -1.677 46.913 11.529 45.84 12.961z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M42.446 13.6C42.446 13.6 41.57 14.315 41.691 13.121C41.812 11.927 68.899 -3.418 72.521 -3.452C72.521 -3.452 43.404 12.089 42.446 13.6z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M39.16 14.975C39.16 14.975 38.332 15.747 38.374 14.547C38.416 13.348 58.233 -2.149 68.045 -4.023C68.045 -4.023 50.015 4.104 39.16 14.975z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M36.284 16.838C36.284 16.838 35.539 17.532 35.577 16.453C35.615 15.373 53.449 1.426 62.28 -0.26C62.28 -0.26 46.054 7.054 36.284 16.838z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					s = null;
+					g.createPath("M4.6 164.801C4.6 164.801 -10.6 162.401 6.2 160.801C6.2 160.801 24.2 158.801 28.2 153.601C28.2 153.601 41.8 144.401 44.6 144.001C47.4 143.601 63.8 140.001 64.2 137.601C64.6 135.201 70.6 132.801 72.2 133.601C73.8 134.401 73.8 143.601 71 144.401C68.2 145.201 49.4 152.401 43 153.601C36.6 154.801 25 162.401 20.2 163.601C15.4 164.801 4.6 164.801 4.6 164.801z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M77.6 127.401C77.6 127.401 74.6 129.001 73.4 131.601C73.4 131.601 67 142.201 52.8 145.401C52.8 145.401 29.8 154.401 22 156.401C22 156.401 8.6 161.401 1.2 160.601C1.2 160.601 -5.8 160.801 0.4 162.401C0.4 162.401 20.6 160.401 24 158.601C24 158.601 39.6 153.401 42.6 150.801C45.6 148.201 63.8 143.201 66 141.201C68.2 139.201 78 130.801 77.6 127.401z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M18.882 158.911C18.882 158.911 24.111 158.685 22.958 160.234C21.805 161.784 19.357 160.91 19.357 160.91L18.882 158.911z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M11.68 160.263C11.68 160.263 16.908 160.037 15.756 161.586C14.603 163.136 12.155 162.263 12.155 162.263L11.68 160.263z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M1.251 161.511C1.251 161.511 6.48 161.284 5.327 162.834C4.174 164.383 1.726 163.51 1.726 163.51L1.251 161.511z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-6.383 162.055C-6.383 162.055 -1.154 161.829 -2.307 163.378C-3.46 164.928 -5.908 164.054 -5.908 164.054L-6.383 162.055z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M35.415 151.513C35.415 151.513 42.375 151.212 40.84 153.274C39.306 155.336 36.047 154.174 36.047 154.174L35.415 151.513z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M45.73 147.088C45.73 147.088 51.689 143.787 51.155 148.849C50.885 151.405 46.362 149.749 46.362 149.749L45.73 147.088z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M54.862 144.274C54.862 144.274 62.021 140.573 60.287 146.035C59.509 148.485 55.493 146.935 55.493 146.935L54.862 144.274z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M64.376 139.449C64.376 139.449 68.735 134.548 69.801 141.21C70.207 143.748 65.008 142.11 65.008 142.11L64.376 139.449z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M26.834 155.997C26.834 155.997 32.062 155.77 30.91 157.32C29.757 158.869 27.308 157.996 27.308 157.996L26.834 155.997z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M62.434 34.603C62.434 34.603 61.708 35.268 61.707 34.197C61.707 33.127 79.191 19.863 88.034 18.479C88.034 18.479 71.935 25.208 62.434 34.603z").setFill(f).setStroke(s);
+					f = "#000000";
+					s = null;
+					g.createPath("M65.4 98.4C65.4 98.4 87.401 120.801 96.601 124.401C96.601 124.401 105.801 135.601 101.801 161.601C101.801 161.601 98.601 169.201 95.401 148.401C95.401 148.401 98.601 123.201 87.401 139.201C87.401 139.201 79 129.301 85.4 129.601C85.4 129.601 88.601 131.601 89.001 130.001C89.401 128.401 81.4 114.801 64.2 100.4C47 86 65.4 98.4 65.4 98.4z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M7 137.201C7 137.201 6.8 135.401 8.6 136.201C10.4 137.001 104.601 143.201 136.201 167.201C136.201 167.201 91.001 144.001 7 137.201z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M17.4 132.801C17.4 132.801 17.2 131.001 19 131.801C20.8 132.601 157.401 131.601 181.001 164.001C181.001 164.001 159.001 138.801 17.4 132.801z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M29 128.801C29 128.801 28.8 127.001 30.6 127.801C32.4 128.601 205.801 115.601 229.401 148.001C229.401 148.001 219.801 122.401 29 128.801z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M39 124.001C39 124.001 38.8 122.201 40.6 123.001C42.4 123.801 164.601 85.2 188.201 117.601C188.201 117.601 174.801 93 39 124.001z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-19 146.801C-19 146.801 -19.2 145.001 -17.4 145.801C-15.6 146.601 2.2 148.801 4.2 187.601C4.2 187.601 -3 145.601 -19 146.801z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-27.8 148.401C-27.8 148.401 -28 146.601 -26.2 147.401C-24.4 148.201 -10.2 143.601 -13 182.401C-13 182.401 -11.8 147.201 -27.8 148.401z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-35.8 148.801C-35.8 148.801 -36 147.001 -34.2 147.801C-32.4 148.601 -17 149.201 -29.4 171.601C-29.4 171.601 -19.8 147.601 -35.8 148.801z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M11.526 104.465C11.526 104.465 11.082 106.464 12.631 105.247C28.699 92.622 61.141 33.72 116.826 28.086C116.826 28.086 78.518 15.976 11.526 104.465z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M22.726 102.665C22.726 102.665 21.363 101.472 23.231 100.847C25.099 100.222 137.541 27.72 176.826 35.686C176.826 35.686 149.719 28.176 22.726 102.665z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M1.885 108.767C1.885 108.767 1.376 110.366 3.087 109.39C12.062 104.27 15.677 47.059 59.254 45.804C59.254 45.804 26.843 31.09 1.885 108.767z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-18.038 119.793C-18.038 119.793 -19.115 121.079 -17.162 120.825C-6.916 119.493 14.489 78.222 58.928 83.301C58.928 83.301 26.962 68.955 -18.038 119.793z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-6.8 113.667C-6.8 113.667 -7.611 115.136 -5.742 114.511C4.057 111.237 17.141 66.625 61.729 63.078C61.729 63.078 27.603 55.135 -6.8 113.667z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-25.078 124.912C-25.078 124.912 -25.951 125.954 -24.369 125.748C-16.07 124.669 1.268 91.24 37.264 95.354C37.264 95.354 11.371 83.734 -25.078 124.912z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-32.677 130.821C-32.677 130.821 -33.682 131.866 -32.091 131.748C-27.923 131.439 2.715 98.36 21.183 113.862C21.183 113.862 9.168 95.139 -32.677 130.821z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M36.855 98.898C36.855 98.898 35.654 97.543 37.586 97.158C39.518 96.774 160.221 39.061 198.184 51.927C198.184 51.927 172.243 41.053 36.855 98.898z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M3.4 163.201C3.4 163.201 3.2 161.401 5 162.201C6.8 163.001 22.2 163.601 9.8 186.001C9.8 186.001 19.4 162.001 3.4 163.201z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M13.8 161.601C13.8 161.601 13.6 159.801 15.4 160.601C17.2 161.401 35 163.601 37 202.401C37 202.401 29.8 160.401 13.8 161.601z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M20.6 160.001C20.6 160.001 20.4 158.201 22.2 159.001C24 159.801 48.6 163.201 72.2 195.601C72.2 195.601 36.6 158.801 20.6 160.001z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M28.225 157.972C28.225 157.972 27.788 156.214 29.678 156.768C31.568 157.322 52.002 155.423 90.099 189.599C90.099 189.599 43.924 154.656 28.225 157.972z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M38.625 153.572C38.625 153.572 38.188 151.814 40.078 152.368C41.968 152.922 76.802 157.423 128.499 192.399C128.499 192.399 54.324 150.256 38.625 153.572z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-1.8 142.001C-1.8 142.001 -2 140.201 -0.2 141.001C1.6 141.801 55 144.401 85.4 171.201C85.4 171.201 50.499 146.426 -1.8 142.001z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M-11.8 146.001C-11.8 146.001 -12 144.201 -10.2 145.001C-8.4 145.801 16.2 149.201 39.8 181.601C39.8 181.601 4.2 144.801 -11.8 146.001z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M49.503 148.962C49.503 148.962 48.938 147.241 50.864 147.655C52.79 148.068 87.86 150.004 141.981 181.098C141.981 181.098 64.317 146.704 49.503 148.962z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M57.903 146.562C57.903 146.562 57.338 144.841 59.264 145.255C61.19 145.668 96.26 147.604 150.381 178.698C150.381 178.698 73.317 143.904 57.903 146.562z").setFill(f).setStroke(s);
+					f = "#ffffff";
+					s = {
+						color : "#000000",
+						width : 0.1
+					};
+					g.createPath("M67.503 141.562C67.503 141.562 66.938 139.841 68.864 140.255C70.79 140.668 113.86 145.004 203.582 179.298C203.582 179.298 82.917 138.904 67.503 141.562z").setFill(f).setStroke(s);
+					f = "#000000";
+					s = null;
+					g.createPath("M-43.8 148.401C-43.8 148.401 -38.6 148.001 -39.8 149.601C-41 151.201 -43.4 150.401 -43.4 150.401L-43.8 148.401z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-13 162.401C-13 162.401 -7.8 162.001 -9 163.601C-10.2 165.201 -12.6 164.401 -12.6 164.401L-13 162.401z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-21.8 162.001C-21.8 162.001 -16.6 161.601 -17.8 163.201C-19 164.801 -21.4 164.001 -21.4 164.001L-21.8 162.001z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-117.169 150.182C-117.169 150.182 -112.124 151.505 -113.782 152.624C-115.439 153.744 -117.446 152.202 -117.446 152.202L-117.169 150.182z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-115.169 140.582C-115.169 140.582 -110.124 141.905 -111.782 143.024C-113.439 144.144 -115.446 142.602 -115.446 142.602L-115.169 140.582z").setFill(f).setStroke(s);
+					f = "#000000";
+					g.createPath("M-122.369 136.182C-122.369 136.182 -117.324 137.505 -118.982 138.624C-120.639 139.744 -122.646 138.202 -122.646 138.202L-122.369 136.182z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-42.6 211.201C-42.6 211.201 -44.2 211.201 -48.2 213.201C-50.2 213.201 -61.4 216.801 -67 226.801C-67 226.801 -54.6 217.201 -42.6 211.201z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M45.116 303.847C45.257 304.105 45.312 304.525 45.604 304.542C46.262 304.582 47.495 304.883 47.37 304.247C46.522 299.941 45.648 295.004 41.515 293.197C40.876 292.918 39.434 293.331 39.36 294.215C39.233 295.739 39.116 297.088 39.425 298.554C39.725 299.975 41.883 299.985 42.8 298.601C43.736 300.273 44.168 302.116 45.116 303.847z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M34.038 308.581C34.786 309.994 34.659 311.853 36.074 312.416C36.814 312.71 38.664 311.735 38.246 310.661C37.444 308.6 37.056 306.361 35.667 304.55C35.467 304.288 35.707 303.755 35.547 303.427C34.953 302.207 33.808 301.472 32.4 301.801C31.285 304.004 32.433 306.133 33.955 307.842C34.091 307.994 33.925 308.37 34.038 308.581z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-5.564 303.391C-5.672 303.014 -5.71 302.551 -5.545 302.23C-5.014 301.197 -4.221 300.075 -4.558 299.053C-4.906 297.997 -6.022 298.179 -6.672 298.748C-7.807 299.742 -7.856 301.568 -8.547 302.927C-8.743 303.313 -8.692 303.886 -9.133 304.277C-9.607 304.698 -10.047 306.222 -9.951 306.793C-9.898 307.106 -10.081 317.014 -9.859 316.751C-9.24 316.018 -6.19 306.284 -6.121 305.392C-6.064 304.661 -5.332 304.196 -5.564 303.391z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-31.202 296.599C-28.568 294.1 -25.778 291.139 -26.22 287.427C-26.336 286.451 -28.111 286.978 -28.298 287.824C-29.1 291.449 -31.139 294.11 -33.707 296.502C-35.903 298.549 -37.765 304.893 -38 305.401C-34.303 300.145 -32.046 297.399 -31.202 296.599z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-44.776 290.635C-44.253 290.265 -44.555 289.774 -44.338 289.442C-43.385 287.984 -42.084 286.738 -42.066 285C-42.063 284.723 -42.441 284.414 -42.776 284.638C-43.053 284.822 -43.395 284.952 -43.503 285.082C-45.533 287.531 -46.933 290.202 -48.376 293.014C-48.559 293.371 -49.703 297.862 -49.39 297.973C-49.151 298.058 -47.431 293.877 -47.221 293.763C-45.958 293.077 -45.946 291.462 -44.776 290.635z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-28.043 310.179C-27.599 309.31 -26.023 308.108 -26.136 307.219C-26.254 306.291 -25.786 304.848 -26.698 305.536C-27.955 306.484 -31.404 307.833 -31.674 313.641C-31.7 314.212 -28.726 311.519 -28.043 310.179z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-13.6 293.001C-13.2 292.333 -12.492 292.806 -12.033 292.543C-11.385 292.171 -10.774 291.613 -10.482 290.964C-9.512 288.815 -7.743 286.995 -7.6 284.601C-9.091 283.196 -9.77 285.236 -10.4 286.201C-11.723 284.554 -12.722 286.428 -14.022 286.947C-14.092 286.975 -14.305 286.628 -14.38 286.655C-15.557 287.095 -16.237 288.176 -17.235 288.957C-17.406 289.091 -17.811 288.911 -17.958 289.047C-18.61 289.65 -19.583 289.975 -19.863 290.657C-20.973 293.364 -24.113 295.459 -26 303.0 [...]
+					f = "#cccccc";
+					g.createPath("M46.2 347.401C46.2 347.401 53.6 327.001 49.2 315.801C49.2 315.801 60.6 337.401 56 348.601C56 348.601 55.6 338.201 51.6 333.201C51.6 333.201 47.6 346.001 46.2 347.401z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M31.4 344.801C31.4 344.801 36.8 336.001 28.8 317.601C28.8 317.601 28 338.001 21.2 349.001C21.2 349.001 35.4 328.801 31.4 344.801z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M21.4 342.801C21.4 342.801 21.2 322.801 21.6 319.801C21.6 319.801 17.8 336.401 7.6 346.001C7.6 346.001 22 334.001 21.4 342.801z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M11.8 310.801C11.8 310.801 17.8 324.401 7.8 342.801C7.8 342.801 14.2 330.601 9.4 323.601C9.4 323.601 12 320.201 11.8 310.801z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-7.4 342.401C-7.4 342.401 -8.4 326.801 -6.6 324.601C-6.6 324.601 -6.4 318.201 -6.8 317.201C-6.8 317.201 -2.8 311.001 -2.6 318.401C-2.6 318.401 -1.2 326.201 1.6 330.801C1.6 330.801 5.2 336.201 5 342.601C5 342.601 -5 312.401 -7.4 342.401z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-11 314.801C-11 314.801 -17.6 325.601 -19.4 344.601C-19.4 344.601 -20.8 338.401 -17 324.001C-17 324.001 -12.8 308.601 -11 314.801z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-32.8 334.601C-32.8 334.601 -27.8 329.201 -26.4 324.201C-26.4 324.201 -22.8 308.401 -29.2 317.001C-29.2 317.001 -29 325.001 -37.2 332.401C-37.2 332.401 -32.4 330.001 -32.8 334.601z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-38.6 329.601C-38.6 329.601 -35.2 312.201 -34.4 311.401C-34.4 311.401 -32.6 308.001 -35.4 311.201C-35.4 311.201 -44.2 330.401 -48.2 337.001C-48.2 337.001 -40.2 327.801 -38.6 329.601z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-44.4 313.001C-44.4 313.001 -32.8 290.601 -54.6 316.401C-54.6 316.401 -43.6 306.601 -44.4 313.001z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M-59.8 298.401C-59.8 298.401 -55 279.601 -52.4 279.801C-52.4 279.801 -44.2 270.801 -50.8 281.401C-50.8 281.401 -56.8 291.001 -56.2 300.801C-56.2 300.801 -56.8 291.201 -59.8 298.401z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M270.5 287C270.5 287 258.5 277 256 273.5C256 273.5 269.5 292 269.5 299C269.5 299 272 291.5 270.5 287z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M276 265C276 265 255 250 251.5 242.5C251.5 242.5 278 272 278 276.5C278 276.5 278.5 267.5 276 265z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M293 111C293 111 281 103 279.5 105C279.5 105 290 111.5 292.5 120C292.5 120 291 111 293 111z").setFill(f).setStroke(s);
+					f = "#cccccc";
+					g.createPath("M301.5 191.5L284 179.5C284 179.5 303 196.5 303.5 200.5L301.5 191.5z").setFill(f).setStroke(s);
+					s = "#000000";
+					f = null;
+					g.createPath("M-89.25 169L-67.25 173.75").setFill(f).setStroke(s);
+					s = "#000000";
+					g.createPath("M-39 331C-39 331 -39.5 327.5 -48.5 338").setFill(f).setStroke(s);
+					s = "#000000";
+					g.createPath("M-33.5 336C-33.5 336 -31.5 329.5 -38 334").setFill(f).setStroke(s);
+					s = "#000000";
+					g.createPath("M20.5 344.5C20.5 344.5 22 333.5 10.5 346.5").setFill(f).setStroke(s);
+				};
+				var vml, sx = 100, sy = 80, startTime;
+				
+				var render = function(timestamp){
+					window.requestAnimationFrame(render);
+                    // do not use timestamp param as it has different type (high resolution timer vs "unix" time).
+                    // Let's stick to Data.getTime for maximum back compat.
+                    timestamp = new Date().getTime();
+            		var elapsed = timestamp - startTime,
+						vx = elapsed/1000*sx,
+						vy = elapsed/1000*sy,
+						clip = g.getClip();
+					var clipr = vml ? clip : {x:clip.cx-clip.rx, y:clip.cy-clip.ry, width:2*clip.rx, height:2*clip.ry};
+					var p = {x:clipr.x, y:clipr.y};
+					p = m.multiplyPoint(initial_matrix, p);
+					if(p.x + vx <= 0 || p.x + vx +clipr.width >= 500){
+						sx = -sx;
+						vx = -vx;
+					}
+					if(p.y + vy <= 0 || p.y + vy + clipr.height >= 500){
+						sy = -sy;
+						vy = -vy;
+					}
+					p.x += vx;
+					p.y += vy;
+					p = m.multiplyPoint(m.invert(initial_matrix), p);
+					if(vml){
+						clip.x = Math.round(p.x); 
+						clip.y = Math.round(p.y);
+					}else{
+						clip.cx = Math.round(p.x)+clip.rx;
+						clip.cy = Math.round(p.y)+clip.ry;
+					}
+					
+					g.setClip(clip);
+					startTime = timestamp ;
+				};
+				
+				ready(function(){
+					makeShapes();
+					vml = /\.vml/.test(surface.declaredClass); 
+					clip =  vml ? {
+						x:100, y:100, width:90, height:65
+					}: {
+						cx:160, cy:140, rx:60, ry:40
+					};
+					g.setClip(clip);
+					startTime = new Date().getTime();
+					window.requestAnimationFrame(render);
+				});
+			});
+		</script>
+	</head>
+	<body>
+		<h1>GFX Clipping Demo</h1>
+		<div id="gfx_holder" style="width: 500px; height: 500px;"></div>
+	</body>
+</html>
diff --git a/dojox/gfx/demos/clockWidget.html b/dojox/gfx/demos/clockWidget.html
index 6912c93..4d3cca7 100644
--- a/dojox/gfx/demos/clockWidget.html
+++ b/dojox/gfx/demos/clockWidget.html
@@ -7,7 +7,7 @@
 	@import "../../../dijit/themes/dijit.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true"></script>
 <script type="text/javascript">
 	dojo.require("dijit._Widget");
 	dojo.require("dijit._Templated");
@@ -307,7 +307,7 @@
 
 <button dojoType="dijit.form.Button">
 	Resize
-	<script type="dojo/method" event="onClick">
+	<script type="dojo/method" data-dojo-event="onClick">
 		dijit.byId("one").resize({ w:250, h:250 });
 	</script>
 </button>
diff --git a/dojox/gfx/demos/filters.html b/dojox/gfx/demos/filters.html
new file mode 100644
index 0000000..a849d91
--- /dev/null
+++ b/dojox/gfx/demos/filters.html
@@ -0,0 +1,221 @@
+<!doctype html>
+<html xmlns="http://www.w3.org/1999/html">
+<head>
+<title>Filter demos</title>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<style type="text/css">
+	@import "../../../dojo/resources/dojo.css";
+	@import "../../../dijit/themes/tundra/tundra.css";
+</style>
+<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="forceGfxRenderer:'svg', parseOnLoad: true"></script>
+<script type="text/javascript">
+
+	require([
+		"dojo/ready", "dojo/_base/array", "dojo/_base/window", "dojo/dom", "dojo/on", "dijit/form/select",
+		"dojo/_base/Color", "dojox/gfx", "dojox/gfx/matrix", "dojox/gfx/svgext", "dojox/gfx/filters"
+	], function(ready, array, win, dom, on, Select, Color, gfx, matrix, svgext, filters){
+
+		var initial_matrix = matrix.translate(80, 15), lion;
+
+		function makeShapes(parentNode, w, h){
+			var surface = gfx.createSurface(dom.byId(parentNode), w, h);
+			surface.createRect({x:0, y:0, width:700, height:700}).setFill("#eee");
+			var g = surface.createGroup().setTransform(initial_matrix);
+			g.createPolyline([69, 18, 82, 8, 99, 3, 118, 5, 135, 12, 149, 21, 156, 13, 165, 9, 177, 13, 183, 28, 180, 50, 164, 91, 155, 107, 154, 114, 151, 121, 141, 127, 139, 136, 155, 206, 157, 251, 126, 342, 133, 357, 128, 376, 83, 376, 75, 368, 67, 350, 61, 350, 53, 369, 4, 369, 2, 361, 5, 354, 12, 342, 16, 321, 4, 257, 4, 244, 7, 218, 9, 179, 26, 127, 43, 93, 32, 77, 30, 70, 24, 67, 16, 49, 17, 35, 18, 23, 30, 12, 40, 7, 53, 7, 62, 12]).setFill("#f2cc99");
+			g.createPolyline([142, 79, 136, 74, 138, 82, 133, 78, 133, 84, 127, 78, 128, 85, 124, 80, 125, 87, 119, 82, 119, 90, 125, 99, 125, 96, 128, 100, 128, 94, 131, 98, 132, 93, 135, 97, 136, 93, 138, 97, 139, 94, 141, 98, 143, 94, 144, 85]).setFill("#e5b27f");
+			g.createPolyline([127, 101, 132, 100, 137, 99, 144, 101, 143, 105, 135, 110]).setFill("#eb8080");
+			g.createPolyline([178, 229, 157, 248, 139, 296, 126, 349, 137, 356, 158, 357, 183, 342, 212, 332, 235, 288, 235, 261, 228, 252, 212, 250, 188, 251]).setFill("#f2cc99");
+			var c = new Color("#9c826b");
+			g.createPolyline([56, 229, 48, 241, 48, 250, 57, 281, 63, 325, 71, 338, 81, 315, 76, 321, 79, 311, 83, 301, 75, 308, 80, 298, 73, 303, 76, 296, 71, 298, 74, 292, 69, 293, 74, 284, 78, 278, 71, 278, 74, 274, 68, 273, 70, 268, 66, 267, 68, 261, 60, 266, 62, 259, 65, 253, 57, 258, 59, 251, 55, 254, 55, 248, 60, 237, 54, 240, 58, 234, 54, 236]).setFill(c);
+			g.createPolyline([74, 363, 79, 368, 81, 368, 85, 362, 89, 363, 92, 370, 96, 373, 101, 372, 108, 361, 110, 371, 113, 373, 116, 371, 120, 358, 122, 363, 123, 371, 126, 371, 129, 367, 132, 357, 135, 361, 130, 376, 127, 377, 94, 378, 84, 376, 76, 371]).setFill(c);
+			g.createPolyline([212, 250, 219, 251, 228, 258, 236, 270, 235, 287, 225, 304, 205, 332, 177, 343, 171, 352, 158, 357, 166, 352, 168, 346, 168, 339, 165, 333, 155, 327, 155, 323, 161, 320, 165, 316, 169, 316, 167, 312, 171, 313, 168, 308, 173, 309, 170, 306, 177, 306, 175, 308, 177, 311, 174, 311, 176, 316, 171, 315, 174, 319, 168, 320, 168, 323, 175, 327, 179, 332, 183, 326, 184, 332, 189, 323, 190, 328, 194, 320, 194, 325, 199, 316, 201, 320, 204, 313, 206, 316, 208, 310, 211, 305, 2 [...]
+			g.createPolyline([151, 205, 151, 238, 149, 252, 141, 268, 128, 282, 121, 301, 130, 300, 126, 313, 118, 324, 116, 337, 120, 346, 133, 352, 133, 340, 137, 333, 145, 329, 156, 327, 153, 319, 153, 291, 157, 271, 170, 259, 178, 277, 193, 250, 174, 216]).setFill(c);
+			g.createPolyline([78, 127, 90, 142, 95, 155, 108, 164, 125, 167, 139, 175, 150, 206, 152, 191, 141, 140, 121, 148, 100, 136]).setFill(c);
+			g.createPolyline([21, 58, 35, 63, 38, 68, 32, 69, 42, 74, 40, 79, 47, 80, 54, 83, 45, 94, 34, 81, 32, 73, 24, 66]).setFill(c);
+			g.createPolyline([71, 34, 67, 34, 66, 27, 59, 24, 54, 17, 48, 17, 39, 22, 30, 26, 28, 31, 31, 39, 38, 46, 29, 45, 36, 54, 41, 61, 41, 70, 50, 69, 54, 71, 55, 58, 67, 52, 76, 43, 76, 39, 68, 44]).setFill(c);
+			g.createPolyline([139, 74, 141, 83, 143, 89, 144, 104, 148, 104, 155, 106, 154, 86, 157, 77, 155, 72, 150, 77, 144, 77]).setFill(c);
+			g.createPolyline([105, 44, 102, 53, 108, 58, 111, 62, 112, 55]).setFill(c);
+			g.createPolyline([141, 48, 141, 54, 144, 58, 139, 62, 137, 66, 136, 59, 137, 52]).setFill(c);
+			g.createPolyline([98, 135, 104, 130, 105, 134, 108, 132, 108, 135, 112, 134, 113, 137, 116, 136, 116, 139, 119, 139, 124, 141, 128, 140, 133, 138, 140, 133, 139, 140, 126, 146, 104, 144]).setFill(c);
+			g.createPolyline([97, 116, 103, 119, 103, 116, 111, 118, 116, 117, 122, 114, 127, 107, 135, 111, 142, 107, 141, 114, 145, 118, 149, 121, 145, 125, 140, 124, 127, 121, 113, 125, 100, 124]).setFill(c);
+			g.createPolyline([147, 33, 152, 35, 157, 34, 153, 31, 160, 31, 156, 28, 161, 28, 159, 24, 163, 25, 163, 21, 165, 22, 170, 23, 167, 17, 172, 21, 174, 18, 175, 23, 176, 22, 177, 28, 177, 33, 174, 37, 176, 39, 174, 44, 171, 49, 168, 53, 164, 57, 159, 68, 156, 70, 154, 60, 150, 51, 146, 43, 144, 35]).setFill(c);
+			g.createPolyline([85, 72, 89, 74, 93, 75, 100, 76, 105, 75, 102, 79, 94, 79, 88, 76]).setFill(c);
+			g.createPolyline([86, 214, 79, 221, 76, 232, 82, 225, 78, 239, 82, 234, 78, 245, 81, 243, 79, 255, 84, 250, 84, 267, 87, 254, 90, 271, 90, 257, 95, 271, 93, 256, 95, 249, 92, 252, 93, 243, 89, 253, 89, 241, 86, 250, 87, 236, 83, 245, 87, 231, 82, 231, 90, 219, 84, 221]).setFill(c);
+			c = new Color("#ffcc7f");
+			g.createPolyline([93, 68, 96, 72, 100, 73, 106, 72, 108, 66, 105, 63, 100, 62]).setFill(c);
+			g.createPolyline([144, 64, 142, 68, 142, 73, 146, 74, 150, 73, 154, 64, 149, 62]).setFill(c);
+			c = new Color("#9c826b");
+			g.createPolyline([57, 91, 42, 111, 52, 105, 41, 117, 53, 112, 46, 120, 53, 116, 50, 124, 57, 119, 55, 127, 61, 122, 60, 130, 67, 126, 66, 134, 71, 129, 72, 136, 77, 130, 76, 137, 80, 133, 82, 138, 86, 135, 96, 135, 94, 129, 86, 124, 83, 117, 77, 123, 79, 117, 73, 120, 75, 112, 68, 116, 71, 111, 65, 114, 69, 107, 63, 110, 68, 102, 61, 107, 66, 98, 61, 103, 63, 97, 57, 99]).setFill(c);
+			g.createPolyline([83, 79, 76, 79, 67, 82, 75, 83, 65, 88, 76, 87, 65, 92, 76, 91, 68, 96, 77, 95, 70, 99, 80, 98, 72, 104, 80, 102, 76, 108, 85, 103, 92, 101, 87, 98, 93, 96, 86, 94, 91, 93, 85, 91, 93, 89, 99, 89, 105, 93, 107, 85, 102, 82, 92, 80]).setFill(c);
+			g.createPolyline([109, 77, 111, 83, 109, 89, 113, 94, 117, 90, 117, 81, 114, 78]).setFill(c);
+			g.createPolyline([122, 128, 127, 126, 134, 127, 136, 129, 134, 130, 130, 128, 124, 129]).setFill(c);
+			g.createPolyline([78, 27, 82, 32, 80, 33, 82, 36, 78, 37, 82, 40, 78, 42, 81, 46, 76, 47, 78, 49, 74, 50, 82, 52, 87, 50, 83, 48, 91, 46, 86, 45, 91, 42, 88, 40, 92, 37, 86, 34, 90, 31, 86, 29, 89, 26]).setFill(c);
+			g.createPolyline([82, 17, 92, 20, 79, 21, 90, 25, 81, 25, 94, 28, 93, 26, 101, 30, 101, 26, 107, 33, 108, 28, 111, 40, 113, 34, 115, 45, 117, 39, 119, 54, 121, 46, 124, 58, 126, 47, 129, 59, 130, 49, 134, 58, 133, 44, 137, 48, 133, 37, 137, 40, 133, 32, 126, 20, 135, 26, 132, 19, 138, 23, 135, 17, 142, 18, 132, 11, 116, 6, 94, 6, 78, 11, 92, 12, 80, 14, 90, 16]).setFill(c);
+			g.createPolyline([142, 234, 132, 227, 124, 223, 115, 220, 110, 225, 118, 224, 127, 229, 135, 236, 122, 234, 115, 237, 113, 242, 121, 238, 139, 243, 121, 245, 111, 254, 95, 254, 102, 244, 104, 235, 110, 229, 100, 231, 104, 224, 113, 216, 122, 215, 132, 217, 141, 224, 145, 230, 149, 240]).setFill(c);
+			g.createPolyline([115, 252, 125, 248, 137, 249, 143, 258, 134, 255, 125, 254]).setFill(c);
+			g.createPolyline([114, 212, 130, 213, 140, 219, 147, 225, 144, 214, 137, 209, 128, 207]).setFill(c);
+			g.createPolyline([102, 263, 108, 258, 117, 257, 131, 258, 116, 260, 109, 265]).setFill(c);
+			g.createPolyline([51, 241, 35, 224, 40, 238, 23, 224, 31, 242, 19, 239, 28, 247, 17, 246, 25, 250, 37, 254, 39, 263, 44, 271, 47, 294, 48, 317, 51, 328, 60, 351, 60, 323, 53, 262, 47, 246]).setFill(c);
+			g.createPolyline([2, 364, 9, 367, 14, 366, 18, 355, 20, 364, 26, 366, 31, 357, 35, 364, 39, 364, 42, 357, 47, 363, 53, 360, 59, 357, 54, 369, 7, 373]).setFill(c);
+			g.createPolyline([7, 349, 19, 345, 25, 339, 18, 341, 23, 333, 28, 326, 23, 326, 27, 320, 23, 316, 25, 311, 20, 298, 15, 277, 12, 264, 9, 249, 10, 223, 3, 248, 5, 261, 15, 307, 17, 326, 11, 343]).setFill(c);
+			g.createPolyline([11, 226, 15, 231, 25, 236, 18, 227]).setFill(c);
+			g.createPolyline([13, 214, 19, 217, 32, 227, 23, 214, 16, 208, 15, 190, 24, 148, 31, 121, 24, 137, 14, 170, 8, 189]).setFill(c);
+			g.createPolyline([202, 254, 195, 258, 199, 260, 193, 263, 197, 263, 190, 268, 196, 268, 191, 273, 188, 282, 200, 272, 194, 272, 201, 266, 197, 265, 204, 262, 200, 258, 204, 256]).setFill(c);
+			c = new Color("#845433");
+			g.createPolyline([151, 213, 165, 212, 179, 225, 189, 246, 187, 262, 179, 275, 176, 263, 177, 247, 171, 233, 163, 230, 165, 251, 157, 264, 146, 298, 145, 321, 133, 326, 143, 285, 154, 260, 153, 240]).setFill(c);
+			g.createPolyline([91, 132, 95, 145, 97, 154, 104, 148, 107, 155, 109, 150, 111, 158, 115, 152, 118, 159, 120, 153, 125, 161, 126, 155, 133, 164, 132, 154, 137, 163, 137, 152, 142, 163, 147, 186, 152, 192, 148, 167, 141, 143, 124, 145, 105, 143]).setFill(c);
+			c = new Color("#9c826b");
+			g.createPolyline([31, 57, 23, 52, 26, 51, 20, 44, 23, 42, 21, 36, 22, 29, 25, 23, 24, 32, 30, 43, 26, 41, 30, 50, 26, 48]).setFill(c);
+			g.createPolyline([147, 21, 149, 28, 155, 21, 161, 16, 167, 14, 175, 15, 173, 11, 161, 9]).setFill(c);
+			g.createPolyline([181, 39, 175, 51, 169, 57, 171, 65, 165, 68, 165, 75, 160, 76, 162, 91, 171, 71, 180, 51]).setFill(c);
+			g.createPolyline([132, 346, 139, 348, 141, 346, 142, 341, 147, 342, 143, 355, 133, 350]).setFill(c);
+			g.createPolyline([146, 355, 151, 352, 155, 348, 157, 343, 160, 349, 151, 356, 147, 357]).setFill(c);
+			g.createPolyline([99, 266, 100, 281, 94, 305, 86, 322, 78, 332, 72, 346, 73, 331, 91, 291]).setFill(c);
+			g.createPolyline([20, 347, 32, 342, 45, 340, 54, 345, 45, 350, 42, 353, 38, 350, 31, 353, 29, 356, 23, 350, 19, 353, 15, 349]).setFill(c);
+			g.createPolyline([78, 344, 86, 344, 92, 349, 88, 358, 84, 352]).setFill(c);
+			g.createPolyline([93, 347, 104, 344, 117, 345, 124, 354, 121, 357, 116, 351, 112, 351, 108, 355, 102, 351]).setFill(c);
+			c = new Color("black");
+			g.createPolyline([105, 12, 111, 18, 113, 24, 113, 29, 119, 34, 116, 23, 112, 16]).setFill(c);
+			g.createPolyline([122, 27, 125, 34, 127, 43, 128, 34, 125, 29]).setFill(c);
+			g.createPolyline([115, 13, 122, 19, 122, 15, 113, 10]).setFill(c);
+			c = new Color("#ffe5b2");
+			g.createPolyline([116, 172, 107, 182, 98, 193, 98, 183, 90, 199, 89, 189, 84, 207, 88, 206, 87, 215, 95, 206, 93, 219, 91, 230, 98, 216, 97, 226, 104, 214, 112, 209, 104, 208, 113, 202, 126, 200, 139, 207, 132, 198, 142, 203, 134, 192, 142, 195, 134, 187, 140, 185, 130, 181, 136, 177, 126, 177, 125, 171, 116, 180]).setFill(c);
+			g.createPolyline([74, 220, 67, 230, 67, 221, 59, 235, 63, 233, 60, 248, 70, 232, 65, 249, 71, 243, 67, 256, 73, 250, 69, 262, 73, 259, 71, 267, 76, 262, 72, 271, 78, 270, 76, 275, 82, 274, 78, 290, 86, 279, 86, 289, 92, 274, 88, 275, 87, 264, 82, 270, 82, 258, 77, 257, 78, 247, 73, 246, 77, 233, 72, 236]).setFill(c);
+			g.createPolyline([133, 230, 147, 242, 148, 250, 145, 254, 138, 247, 129, 246, 142, 245, 138, 241, 128, 237, 137, 238]).setFill(c);
+			g.createPolyline([133, 261, 125, 261, 116, 263, 111, 267, 125, 265]).setFill(c);
+			g.createPolyline([121, 271, 109, 273, 103, 279, 99, 305, 92, 316, 85, 327, 83, 335, 89, 340, 97, 341, 94, 336, 101, 336, 96, 331, 103, 330, 97, 327, 108, 325, 99, 322, 109, 321, 100, 318, 110, 317, 105, 314, 110, 312, 107, 310, 113, 308, 105, 306, 114, 303, 105, 301, 115, 298, 107, 295, 115, 294, 108, 293, 117, 291, 109, 289, 117, 286, 109, 286, 118, 283, 112, 281, 118, 279, 114, 278, 119, 276, 115, 274]).setFill(c);
+			g.createPolyline([79, 364, 74, 359, 74, 353, 76, 347, 80, 351, 83, 356, 82, 360]).setFill(c);
+			g.createPolyline([91, 363, 93, 356, 97, 353, 103, 355, 105, 360, 103, 366, 99, 371, 94, 368]).setFill(c);
+			g.createPolyline([110, 355, 114, 353, 118, 357, 117, 363, 113, 369, 111, 362]).setFill(c);
+			g.createPolyline([126, 354, 123, 358, 124, 367, 126, 369, 129, 361, 129, 357]).setFill(c);
+			g.createPolyline([30, 154, 24, 166, 20, 182, 23, 194, 29, 208, 37, 218, 41, 210, 41, 223, 46, 214, 46, 227, 52, 216, 52, 227, 61, 216, 59, 225, 68, 213, 73, 219, 70, 207, 77, 212, 69, 200, 77, 202, 70, 194, 78, 197, 68, 187, 76, 182, 64, 182, 58, 175, 58, 185, 53, 177, 50, 186, 46, 171, 44, 182, 39, 167, 36, 172, 36, 162, 30, 166]).setFill(c);
+			g.createPolyline([44, 130, 41, 137, 45, 136, 43, 150, 48, 142, 48, 157, 53, 150, 52, 164, 60, 156, 61, 169, 64, 165, 66, 175, 70, 167, 74, 176, 77, 168, 80, 183, 85, 172, 90, 182, 93, 174, 98, 181, 99, 173, 104, 175, 105, 169, 114, 168, 102, 163, 95, 157, 94, 166, 90, 154, 87, 162, 82, 149, 75, 159, 72, 148, 68, 155, 67, 143, 62, 148, 62, 138, 58, 145, 56, 133, 52, 142, 52, 128, 49, 134, 47, 125]).setFill(c);
+			g.createPolyline([13, 216, 19, 219, 36, 231, 22, 223, 16, 222, 22, 227, 12, 224, 13, 220, 16, 220]).setFill(c);
+			g.createPolyline([10, 231, 14, 236, 25, 239, 27, 237, 19, 234]).setFill(c);
+			g.createPolyline([9, 245, 14, 242, 25, 245, 13, 245]).setFill(c);
+			g.createPolyline([33, 255, 26, 253, 18, 254, 25, 256, 18, 258, 27, 260, 18, 263, 27, 265, 19, 267, 29, 270, 21, 272, 29, 276, 21, 278, 30, 281, 22, 283, 31, 287, 24, 288, 32, 292, 23, 293, 34, 298, 26, 299, 37, 303, 32, 305, 39, 309, 33, 309, 39, 314, 34, 314, 40, 318, 34, 317, 40, 321, 34, 321, 41, 326, 33, 326, 40, 330, 33, 332, 39, 333, 33, 337, 42, 337, 54, 341, 49, 337, 52, 335, 47, 330, 50, 330, 45, 325, 49, 325, 45, 321, 48, 321, 45, 316, 46, 306, 45, 286, 43, 274, 36, 261]).se [...]
+			g.createPolyline([7, 358, 9, 351, 14, 351, 17, 359, 11, 364]).setFill(c);
+			g.createPolyline([44, 354, 49, 351, 52, 355, 49, 361]).setFill(c);
+			g.createPolyline([32, 357, 37, 353, 40, 358, 36, 361]).setFill(c);
+			g.createPolyline([139, 334, 145, 330, 154, 330, 158, 334, 154, 341, 152, 348, 145, 350, 149, 340, 147, 336, 141, 339, 139, 345, 136, 342, 136, 339]).setFill(c);
+			g.createPolyline([208, 259, 215, 259, 212, 255, 220, 259, 224, 263, 225, 274, 224, 283, 220, 292, 208, 300, 206, 308, 203, 304, 199, 315, 197, 309, 195, 318, 193, 313, 190, 322, 190, 316, 185, 325, 182, 318, 180, 325, 172, 321, 178, 320, 176, 313, 186, 312, 180, 307, 188, 307, 184, 303, 191, 302, 186, 299, 195, 294, 187, 290, 197, 288, 192, 286, 201, 283, 194, 280, 203, 277, 198, 275, 207, 271, 200, 269, 209, 265, 204, 265, 212, 262]).setFill(c);
+			g.createPolyline([106, 126, 106, 131, 109, 132, 111, 134, 115, 132, 115, 135, 119, 133, 118, 137, 123, 137, 128, 137, 133, 134, 136, 130, 136, 127, 132, 124, 118, 128, 112, 128, 106, 126, 106, 126, 106, 126]).setFill(c);
+			g.createPolyline([107, 114, 101, 110, 98, 102, 105, 97, 111, 98, 119, 102, 121, 108, 118, 112, 113, 115]).setFill(c);
+			g.createPolyline([148, 106, 145, 110, 146, 116, 150, 118, 152, 111, 151, 107]).setFill(c);
+			g.createPolyline([80, 55, 70, 52, 75, 58, 63, 57, 72, 61, 57, 61, 67, 66, 57, 67, 62, 69, 54, 71, 61, 73, 54, 77, 63, 78, 53, 85, 60, 84, 56, 90, 69, 84, 63, 82, 75, 76, 70, 75, 77, 72, 72, 71, 78, 69, 72, 66, 81, 67, 78, 64, 82, 63, 80, 60, 86, 62]).setFill(c);
+			g.createPolyline([87, 56, 91, 52, 96, 50, 102, 56, 98, 56, 92, 60]).setFill(c);
+			g.createPolyline([85, 68, 89, 73, 98, 76, 106, 74, 96, 73, 91, 70]).setFill(c);
+			g.createPolyline([115, 57, 114, 64, 111, 64, 115, 75, 122, 81, 122, 74, 126, 79, 126, 74, 131, 78, 130, 72, 133, 77, 131, 68, 126, 61, 119, 57]).setFill(c);
+			g.createPolyline([145, 48, 143, 53, 147, 59, 151, 59, 150, 55]).setFill(c);
+			g.createPolyline([26, 22, 34, 15, 43, 10, 52, 10, 59, 16, 47, 15, 32, 22]).setFill(c);
+			g.createPolyline([160, 19, 152, 26, 149, 34, 154, 33, 152, 30, 157, 30, 155, 26, 158, 27, 157, 23, 161, 23]).setFill(c);
+			c = new Color("black");
+			g.createPolyline([98, 117, 105, 122, 109, 122, 105, 117, 113, 120, 121, 120, 130, 112, 128, 108, 123, 103, 123, 99, 128, 101, 132, 106, 135, 109, 142, 105, 142, 101, 145, 101, 145, 91, 148, 101, 145, 105, 136, 112, 135, 116, 143, 124, 148, 120, 150, 122, 142, 128, 133, 122, 121, 125, 112, 126, 103, 125, 100, 129, 96, 124]).setFill(c);
+			g.createPolyline([146, 118, 152, 118, 152, 115, 149, 115]).setFill(c);
+			g.createPolyline([148, 112, 154, 111, 154, 109, 149, 109]).setFill(c);
+			g.createPolyline([106, 112, 108, 115, 114, 116, 118, 114]).setFill(c);
+			g.createPolyline([108, 108, 111, 110, 116, 110, 119, 108]).setFill(c);
+			g.createPolyline([106, 104, 109, 105, 117, 106, 115, 104]).setFill(c);
+			g.createPolyline([50, 25, 41, 26, 34, 33, 39, 43, 49, 58, 36, 51, 47, 68, 55, 69, 54, 59, 61, 57, 74, 46, 60, 52, 67, 42, 57, 48, 61, 40, 54, 45, 60, 36, 59, 29, 48, 38, 52, 30, 47, 32]).setFill(c);
+			g.createPolyline([147, 34, 152, 41, 155, 49, 161, 53, 157, 47, 164, 47, 158, 43, 168, 44, 159, 40, 164, 37, 169, 37, 164, 33, 169, 34, 165, 28, 170, 30, 170, 25, 173, 29, 175, 27, 176, 32, 173, 36, 175, 39, 172, 42, 172, 46, 168, 49, 170, 55, 162, 57, 158, 63, 155, 58, 153, 50, 149, 46]).setFill(c);
+			g.createPolyline([155, 71, 159, 80, 157, 93, 157, 102, 155, 108, 150, 101, 149, 93, 154, 101, 152, 91, 151, 83, 155, 79]).setFill(c);
+			g.createPolyline([112, 78, 115, 81, 114, 91, 112, 87, 113, 82]).setFill(c);
+			g.createPolyline([78, 28, 64, 17, 58, 11, 47, 9, 36, 10, 28, 16, 21, 26, 18, 41, 20, 51, 23, 61, 33, 65, 28, 68, 37, 74, 36, 81, 43, 87, 48, 90, 43, 100, 40, 98, 39, 90, 31, 80, 30, 72, 22, 71, 17, 61, 14, 46, 16, 28, 23, 17, 33, 9, 45, 6, 54, 6, 65, 12]).setFill(c);
+			g.createPolyline([67, 18, 76, 9, 87, 5, 101, 2, 118, 3, 135, 8, 149, 20, 149, 26, 144, 19, 132, 12, 121, 9, 105, 7, 89, 8, 76, 14, 70, 20]).setFill(c);
+			g.createPolyline([56, 98, 48, 106, 56, 103, 47, 112, 56, 110, 52, 115, 57, 113, 52, 121, 62, 115, 58, 123, 65, 119, 63, 125, 69, 121, 68, 127, 74, 125, 74, 129, 79, 128, 83, 132, 94, 135, 93, 129, 85, 127, 81, 122, 76, 126, 75, 121, 71, 124, 71, 117, 66, 121, 66, 117, 62, 117, 64, 112, 60, 113, 60, 110, 57, 111, 61, 105, 57, 107, 60, 101, 55, 102]).setFill(c);
+			g.createPolyline([101, 132, 103, 138, 106, 134, 106, 139, 112, 136, 111, 142, 115, 139, 114, 143, 119, 142, 125, 145, 131, 142, 135, 138, 140, 134, 140, 129, 143, 135, 145, 149, 150, 171, 149, 184, 145, 165, 141, 150, 136, 147, 132, 151, 131, 149, 126, 152, 125, 150, 121, 152, 117, 148, 111, 152, 110, 148, 105, 149, 104, 145, 98, 150, 96, 138, 94, 132, 94, 130, 98, 132]).setFill(c);
+			g.createPolyline([41, 94, 32, 110, 23, 132, 12, 163, 6, 190, 7, 217, 5, 236, 3, 247, 9, 230, 12, 211, 12, 185, 18, 160, 26, 134, 35, 110, 43, 99]).setFill(c);
+			g.createPolyline([32, 246, 41, 250, 50, 257, 52, 267, 53, 295, 53, 323, 59, 350, 54, 363, 51, 365, 44, 366, 42, 360, 40, 372, 54, 372, 59, 366, 62, 353, 71, 352, 75, 335, 73, 330, 66, 318, 68, 302, 64, 294, 67, 288, 63, 286, 63, 279, 59, 275, 58, 267, 56, 262, 50, 247, 42, 235, 44, 246, 32, 236, 35, 244]).setFill(c);
+			g.createPolyline([134, 324, 146, 320, 159, 322, 173, 327, 179, 337, 179, 349, 172, 355, 158, 357, 170, 350, 174, 343, 170, 333, 163, 328, 152, 326, 134, 329]).setFill(c);
+			g.createPolyline([173, 339, 183, 334, 184, 338, 191, 329, 194, 332, 199, 323, 202, 325, 206, 318, 209, 320, 213, 309, 221, 303, 228, 296, 232, 289, 234, 279, 233, 269, 230, 262, 225, 256, 219, 253, 208, 252, 198, 252, 210, 249, 223, 250, 232, 257, 237, 265, 238, 277, 238, 291, 232, 305, 221, 323, 218, 335, 212, 342, 200, 349, 178, 348]).setFill(c);
+			g.createPolyline([165, 296, 158, 301, 156, 310, 156, 323, 162, 324, 159, 318, 162, 308, 162, 304]).setFill(c);
+			g.createPolyline([99, 252, 105, 244, 107, 234, 115, 228, 121, 228, 131, 235, 122, 233, 113, 235, 109, 246, 121, 239, 133, 243, 121, 243, 110, 251]).setFill(c);
+			g.createPolyline([117, 252, 124, 247, 134, 249, 136, 253, 126, 252]).setFill(c);
+			g.createPolyline([117, 218, 132, 224, 144, 233, 140, 225, 132, 219, 117, 218, 117, 218, 117, 218]).setFill(c);
+			g.createPolyline([122, 212, 134, 214, 143, 221, 141, 213, 132, 210]).setFill(c);
+			g.createPolyline([69, 352, 70, 363, 76, 373, 86, 378, 97, 379, 108, 379, 120, 377, 128, 378, 132, 373, 135, 361, 133, 358, 132, 366, 127, 375, 121, 374, 121, 362, 119, 367, 117, 374, 110, 376, 110, 362, 107, 357, 106, 371, 104, 375, 97, 376, 90, 375, 90, 368, 86, 362, 83, 364, 86, 369, 85, 373, 78, 370, 73, 362, 71, 351]).setFill(c);
+			g.createPolyline([100, 360, 96, 363, 99, 369, 102, 364]).setFill(c);
+			g.createPolyline([115, 360, 112, 363, 114, 369, 117, 364]).setFill(c);
+			g.createPolyline([127, 362, 125, 364, 126, 369, 128, 365]).setFill(c);
+			g.createPolyline([5, 255, 7, 276, 11, 304, 15, 320, 13, 334, 6, 348, 2, 353, 0, 363, 5, 372, 12, 374, 25, 372, 38, 372, 44, 369, 42, 367, 36, 368, 31, 369, 30, 360, 27, 368, 20, 370, 16, 361, 15, 368, 10, 369, 3, 366, 3, 359, 6, 352, 11, 348, 17, 331, 19, 316, 12, 291, 9, 274]).setFill(c);
+			g.createPolyline([10, 358, 7, 362, 10, 366, 11, 362]).setFill(c);
+			g.createPolyline([25, 357, 22, 360, 24, 366, 27, 360]).setFill(c);
+			g.createPolyline([37, 357, 34, 361, 36, 365, 38, 361]).setFill(c);
+			g.createPolyline([49, 356, 46, 359, 47, 364, 50, 360]).setFill(c);
+			g.createPolyline([130, 101, 132, 102, 135, 101, 139, 102, 143, 103, 142, 101, 137, 100, 133, 100]).setFill(c);
+			g.createPolyline([106, 48, 105, 52, 108, 56, 109, 52]).setFill(c);
+			g.createPolyline([139, 52, 139, 56, 140, 60, 142, 58, 141, 56]).setFill(c);
+			g.createPolyline([25, 349, 29, 351, 30, 355, 33, 350, 37, 348, 42, 351, 45, 347, 49, 345, 44, 343, 36, 345]).setFill(c);
+			g.createPolyline([98, 347, 105, 351, 107, 354, 109, 349, 115, 349, 120, 353, 118, 349, 113, 346, 104, 346]).setFill(c);
+			g.createPolyline([83, 348, 87, 352, 87, 357, 89, 351, 87, 348]).setFill(c);
+			g.createPolyline([155, 107, 163, 107, 170, 107, 186, 108, 175, 109, 155, 109]).setFill(c);
+			g.createPolyline([153, 114, 162, 113, 175, 112, 192, 114, 173, 114, 154, 115]).setFill(c);
+			g.createPolyline([152, 118, 164, 120, 180, 123, 197, 129, 169, 123, 151, 120]).setFill(c);
+			g.createPolyline([68, 109, 87, 106, 107, 106, 106, 108, 88, 108]).setFill(c);
+			g.createPolyline([105, 111, 95, 112, 79, 114, 71, 116, 85, 115, 102, 113]).setFill(c);
+			g.createPolyline([108, 101, 98, 99, 87, 99, 78, 99, 93, 100, 105, 102]).setFill(c);
+			g.createPolyline([85, 63, 91, 63, 97, 60, 104, 60, 108, 62, 111, 69, 112, 75, 110, 74, 108, 71, 103, 73, 106, 69, 105, 65, 103, 64, 103, 67, 102, 70, 99, 70, 97, 66, 94, 67, 97, 72, 88, 67, 84, 66]).setFill(c);
+			g.createPolyline([140, 74, 141, 66, 144, 61, 150, 61, 156, 62, 153, 70, 150, 73, 152, 65, 150, 65, 151, 68, 149, 71, 146, 71, 144, 66, 143, 70, 143, 74]).setFill(c);
+			g.createPolyline([146, 20, 156, 11, 163, 9, 172, 9, 178, 14, 182, 18, 184, 32, 182, 42, 182, 52, 177, 58, 176, 67, 171, 76, 165, 90, 157, 105, 160, 92, 164, 85, 168, 78, 167, 73, 173, 66, 172, 62, 175, 59, 174, 55, 177, 53, 180, 46, 181, 29, 179, 21, 173, 13, 166, 11, 159, 13, 153, 18, 148, 23]).setFill(c);
+			g.createPolyline([150, 187, 148, 211, 150, 233, 153, 247, 148, 267, 135, 283, 125, 299, 136, 292, 131, 313, 122, 328, 122, 345, 129, 352, 133, 359, 133, 367, 137, 359, 148, 356, 140, 350, 131, 347, 129, 340, 132, 332, 140, 328, 137, 322, 140, 304, 154, 265, 157, 244, 155, 223, 161, 220, 175, 229, 186, 247, 185, 260, 176, 275, 178, 287, 185, 277, 188, 261, 196, 253, 189, 236, 174, 213]).setFill(c);
+			g.createPolyline([147, 338, 142, 341, 143, 345, 141, 354, 147, 343]).setFill(c);
+			g.createPolyline([157, 342, 156, 349, 150, 356, 157, 353, 163, 346, 162, 342]).setFill(c);
+			g.createPolyline([99, 265, 96, 284, 92, 299, 73, 339, 73, 333, 87, 300]).setFill(c);
+
+			return g;
+		}
+
+		function buildSelect(){
+			var options = [{label:"none", value:"null", selected:true}];
+
+			array.forEach(["convolutions", "blurs", "colors", "miscs", "shadows", "textures", "reliefs"], function(lib){
+				for(var func in filters[lib]){
+					func = lib + "." + func;
+					options.push({label:func, value:func});
+				}
+			});
+			var select = new Select({
+				name:"filterSelect",
+				options:options
+			}).placeAt("label", "after");
+
+			select.on("change", function(){
+				var f, old = lion.getFilter(), v = this.get("value");
+				if(old){
+					var filterNode = dom.byId(old.id);
+					filterNode.parentNode.removeChild(filterNode);
+				}
+				if(v !== "null"){
+					v = v.split(".");
+					f = filters[v[0]][v[1]];
+				}
+				lion.setFilter(f ? f() : null);
+			});
+		}
+
+		ready(function(){
+			buildSelect();
+			makeShapes("gfx_original", 200, 200).setTransform([matrix.scale(.5,.5)]);
+			lion = makeShapes("gfx_holder", 400, 400);
+		});
+
+	});
+
+</script>
+</head>
+<body class="tundra" style="margin-left:10px">
+<h1>Gfx Filters demo</h1>
+<p>This SVG-only demo illustrates the Gfx built-in, ready-to-use filters available in the dojox/gfx/filters module.</br>
+Note that while any filters can be applied on any shape, the result of the final rendering may vary a lot depending on the
+shape geometry or its appearance properties. For example, the emboss family effects work great on simple geometric shapes
+but less with more complex geometry.
+<br/>Note: IE9 does not support SVG filters (IE10 does).
+</p>
+<p><span id="label" style="margin-right:5px;">Filter to apply:</span></p>
+
+<div id="gfx_holder" style="width: 400px;height: 400px;display:inline-block;"></div>
+<div id="gfx_original" style="width: 200px;height: 200px;display:inline-block;vertical-align:top"></div>
+
+</body>
+</html>
diff --git a/dojox/gfx/demos/lion.html b/dojox/gfx/demos/lion.html
index 0ce33c4..a8ea1ba 100644
--- a/dojox/gfx/demos/lion.html
+++ b/dojox/gfx/demos/lion.html
@@ -7,7 +7,7 @@
 	@import "../../../dijit/themes/tundra/tundra.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
 <!--
 <script type="text/javascript" src="../_base.js"></script>
 <script type="text/javascript" src="../shape.js"></script>
diff --git a/dojox/gfx/demos/roundedPane.html b/dojox/gfx/demos/roundedPane.html
index 4abb775..1c0cb3d 100644
--- a/dojox/gfx/demos/roundedPane.html
+++ b/dojox/gfx/demos/roundedPane.html
@@ -5,7 +5,7 @@
 		<title>rounded skeleton page | The Dojo Toolkit</title>
 			
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-				djConfig="parseOnLoad:true, isDebug:true"></script>
+				data-dojo-config="parseOnLoad:true, isDebug:true"></script>
 
 		<script type="text/javascript">
 		
diff --git a/dojox/gfx/demos/tiger.html b/dojox/gfx/demos/tiger.html
index 2d03fed..3f246c9 100644
--- a/dojox/gfx/demos/tiger.html
+++ b/dojox/gfx/demos/tiger.html
@@ -7,7 +7,7 @@
 	@import "../../../dijit/themes/tundra/tundra.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
 <script type="text/javascript">
 
 dojo.require("dijit.form.HorizontalSlider");
diff --git a/dojox/gfx/demos/tooltip.html b/dojox/gfx/demos/tooltip.html
index 0ccfa11..41820d6 100644
--- a/dojox/gfx/demos/tooltip.html
+++ b/dojox/gfx/demos/tooltip.html
@@ -10,7 +10,7 @@
 			color:#fff;
 		}
 	</style>
-	<script type="text/javascript" djConfig="parseOnLoad:true, isDebug:true" src="../../../dojo/dojo.js"></script>
+	<script type="text/javascript" data-dojo-config="parseOnLoad:true, isDebug:true" src="../../../dojo/dojo.js"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.form.Button");
 	
@@ -188,7 +188,7 @@
 			<div attachId="warn2" id="warn2tt" dojoType="demo.Tooltip"><p style="margin-top:0">Canvas renderer doesn't implement event handling.
 				<button dojoType="dijit.form.Button">
 					Button
-					<script type="dojo/method" event="onClick">
+					<script type="dojo/method" data-dojo-event="onClick">
 						alert(" woo hoo! ");
 						dijit.byId("warn2tt")._hide();
 					</script>
diff --git a/dojox/gfx/filters.js b/dojox/gfx/filters.js
new file mode 100644
index 0000000..ec2d0e6
--- /dev/null
+++ b/dojox/gfx/filters.js
@@ -0,0 +1,742 @@
+define([
+	"dojo/_base/lang",
+	"dojo/_base/array"
+], function(lang, array){
+
+	/*=====
+	return {
+	// summary:
+	//		A module that defines a minimal API to create SVG filter definition objects to be used with the
+	//		dojox/gfx/svgext/Shape.setFilter() API, as well as a set of predefined filters.
+	// description:
+	//		The module defines the following API:
+	//		- filters.createFilter(config, primitives) : Creates a filter object from the specified config and the
+	//		given filter primitives.
+	//		- a set of methods to create the corresponding SVG filter primitives, based on the same
+	//		naming as the specification (e.g. filters.feGaussianBlur() ). A filter primitive method follows the
+	//		following signature (taking feGaussianBlur as an example):
+	//			filters.feGaussianBlur(properties, children?)
+	//			filters.feGaussianBlur(children)
+	//		The "properties" parameter must define the primitive attributes as defined by the specification.
+	//		The "children" array parameter is an array of child filter primitives.
+	//		In addition to this API, the module provides the following predefined filters:
+	//		- filters.convolutions.boxBlur3,
+	//		- filters.convolutions.boxBlur5,
+	//		- filters.convolutions.verticalEdges,
+	//		- filters.convolutions.horizontalEdges,
+	//		- filters.convolutions.allEdges3,
+	//		- filters.convolutions.edgeEnhance,
+	//		- filters.shadows.fastSmallDropShadow,
+	//		- filters.shadows.fastDropShadow,
+	//		- filters.shadows.fastDropShadowLight,
+	//		- filters.shadows.dropShadow,
+	//		- filters.shadows.dropShadowLight,
+	//		- filters.shadows.smallDropShadow,
+	//		- filters.shadows.smallDropShadowLight,
+	//		- filters.blurs.blur1,
+	//		- filters.blurs.blur2,
+	//		- filters.blurs.blur4,
+	//		- filters.blurs.blur8,
+	//		- filters.blurs.glow,
+	//		- filters.colors.negate,
+	//		- filters.colors.sepia,
+	//		- filters.colors.grayscale,
+	//		- filters.colors.showRed,
+	//		- filters.colors.showGreen,
+	//		- filters.colors.showBlue,
+	//		- filters.colors.hueRotate60,
+	//		- filters.colors.hueRotate120,
+	//		- filters.colors.hueRotate180,
+	//		- filters.colors.hueRotate270,
+	//		- filters.miscs.thinEmbossDropShadow,
+	//		- filters.miscs.embossDropShadow,
+	//		- filters.miscs.largeEmbossDropShadow,
+	//		- filters.miscs.thinEmbossDropShadowLight,
+	//		- filters.miscs.embossDropShadowLight,
+	//		- filters.miscs.largeEmbossDropShadowLight,
+	//		- filters.miscs.fuzzy,
+	//		- filters.miscs.veryFuzzy,
+	//		- filters.miscs.melting,
+	//		- filters.miscs.impressionist,
+	//		- filters.miscs.holes,
+	//		- filters.miscs.holesComplement,
+	//		- filters.reliefs.bumpIn,
+	//		- filters.reliefs.bumpOut,
+	//		- filters.reliefs.thinEmboss,
+	//		- filters.reliefs.emboss,
+	//		- filters.reliefs.largeEmboss,
+	//		- filters.textures.paper,
+	//		- filters.textures.swirl,
+	//		- filters.textures.swirl2,
+	//		- filters.textures.gold
+	//		Note: the dojox/gfx/tests/test_filter.html test shows the rendering of all the predefined filters.
+	}
+	=====*/
+
+	var filters = {}, defaultFilterBBox = {x:"0%", y:"0%", width:"100%", height:"100%"}, lib = {};
+
+	//
+	// A minimal facade API to create primitives
+	//
+
+	filters.createFilter = function(/*Object*/args, /*Array*/primitives){
+		// summary:
+		//		Creates a filter with the specified primitives.
+		// description:
+		//		This function creates a new filter object configured with the optional 'args' parameter, and
+		//		adds the filter primitives specified in the 'primitives' array'. The dojox/gfx/filters module
+		//		provides convenient methods to create the corresponding SVG filter primitives, based on the same
+		//		naming as the specification (e.g. filters.feGaussianBlur() ).
+		//		A filter primitive method follows the following signature (taking feGaussianBlur as an example):
+		//			filters.feGaussianBlur(/*Object*/properties, /*Array?*/children)
+		//			filters.feGaussianBlur(/*Array?*/children)
+		//		The "properties" parameter must define the primitive attributes as defined by the specification.
+		//		The optional "children" array parameter is an array of child filter primitives.
+		// args: Object
+		//		The configuration object for the filter.
+		// primitives: Array
+		//		An array of primitives object.
+
+		var filter = lang.mixin({}, defaultFilterBBox, args);
+		if(!filter.primitives){
+			filter.primitives = [];
+		}
+		if(primitives){
+			Array.prototype.push.apply(filter.primitives, primitives);
+		}
+		return filter; /*Object*/
+	};
+
+	var _createFePrimitive = function(tag, args, children){
+		if(args instanceof Array){
+			children = args;
+			args = null;
+		}
+		var fe = lang.mixin({}, args);
+		fe.children = children;
+		fe.tag = tag;
+		return fe;
+	};
+	var _createFeMerge = function(args, children){
+		if(typeof args === "string"){
+			// list of primitives to merge via the 'in' property
+			var toMerge = [];
+			for(var i=0; i<arguments.length; ++i){
+				toMerge.push(filters.feMergeNode({"in":arguments[i]}));
+			}
+			return _createFePrimitive("feMerge", {}, toMerge);
+		}
+		return _createFePrimitive("feMerge", args, children);
+	};
+
+	array.forEach(["feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix", "feDiffuseLighting",
+		"feDisplacementMap", "feFlood", "feGaussianBlur", "feImage", "feMorphology", "feOffset", "feSpecularLighting",
+		"feTile", "feTurbulence", "feDistantLight", "fePointLight", "feSpotLight", "feMergeNode", "feFuncA", "feFuncR",
+		"feFuncG", "feFuncB"], function(fe){
+		filters[fe] = function(args, children){
+			return _createFePrimitive(fe, args, children);
+		};
+	});
+	// special case for feMarge to ease syntax
+	filters.feMerge = _createFeMerge;
+
+
+	var createFilter = filters.createFilter;
+
+	//
+	// Convolution-based filters
+	//
+	lib.convolutions = [
+		createFilter({_gfxName:"boxBlur3"}, [
+			filters.feConvolveMatrix({
+				"in":"SourceGraphic","order":3,"divisor":9,"kernelMatrix":"1,1,1,1,1,1,1,1,1"
+			})
+		]),
+		createFilter({_gfxName:"boxBlur5"}, [
+			filters.feConvolveMatrix({
+				"in":"SourceGraphic","order":5,"divisor":25,"kernelMatrix":"1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"
+			})
+		]),
+		createFilter({_gfxName:"verticalEdges", filterUnits:"objectBoundingBox"}, [
+			filters.feConvolveMatrix({
+				"in":"SourceGraphic","result":"kernel","order":3,"divisor":1,"kernelMatrix":"-1 0 1 -1 0 1 -1 0 1"
+			}),
+			filters.feComponentTransfer({
+				"in":"kernel"
+			}, [
+				filters.feFuncA({"type":"table","tableValues":"1,1"})
+			])
+		]),
+		createFilter({_gfxName:"horizontalEdges", filterUnits:"objectBoundingBox"}, [
+			filters.feConvolveMatrix({
+				"in":"SourceGraphic","result":"kernel","order":3,"divisor":1,"kernelMatrix":"1 1 1 0 0 0 -1 -1 -1"
+			}),
+			filters.feComponentTransfer({
+				"in":"kernel"
+			}, [
+				filters.feFuncA({"type":"table","tableValues":"1,1"})
+			])
+		]),
+		createFilter({_gfxName:"allEdges3", filterUnits:"objectBoundingBox"}, [
+			filters.feConvolveMatrix({
+				"in":"SourceGraphic","result":"kernel","order":3,"divisor":1,"kernelMatrix":"-1 -1 -1 -1 8 -1 -1 -1 -1"
+			}),
+			filters.feComponentTransfer({
+				"in":"kernel"
+			},[
+				filters.feFuncA({"type":"table","tableValues":"1,1"})
+			])
+		]),
+		createFilter({_gfxName: "edgeEnhance", filterUnits:"objectBoundingBox"}, [
+			filters.feConvolveMatrix({
+				"in": "SourceGraphic","result": "kernel","order": 3,"divisor": -1,"kernelMatrix": "0 1 0 1 -5 1 0 1 0"
+			}),
+			filters.feComponentTransfer({
+				"in": "kernel"
+			},[
+				filters.feFuncA({"type":"table","tableValues": "1,1"})
+			])
+		])
+	];
+	array.forEach(lib.convolutions, function(f){
+		lang.mixin(f, defaultFilterBBox);
+	});
+
+	//
+	// Drop Shadow filters
+	//
+	lib.shadows = [
+		createFilter({_gfxName:"fastSmallDropShadow"}, [
+			filters.feColorMatrix({
+				"in":"SourceAlpha","type":"matrix","result":"grey",
+				"values":"0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0,0,0,0.7,0"
+			}),
+			filters.feOffset({"dx":3,"dy":3,"result":"offsetBlur"}),
+			filters.feMerge("offsetBlur", "SourceGraphic")
+		]),
+		createFilter({_gfxName:"fastDropShadow"}, [
+			filters.feColorMatrix({
+				"in":"SourceAlpha","type":"matrix","result":"grey",
+				"values":"0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0,0,0,0.7,0"
+			}),
+			filters.feOffset({"dx":5,"dy":5,"result":"offsetBlur"}),
+			filters.feMerge("offsetBlur", "SourceGraphic")
+		]),
+		createFilter({_gfxName:"fastDropShadowLight"}, [
+			filters.feColorMatrix({
+				"in":"SourceAlpha","type":"matrix","result":"grey",
+				"values":"0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0,0,0,0.4,0"
+			}),
+			filters.feOffset({"dx":5,"dy":5,"result":"offsetBlur"}),
+			filters.feMerge("offsetBlur", "SourceGraphic")
+		]),
+		createFilter({_gfxName:"dropShadow"}, [
+			filters.feGaussianBlur({"in":"SourceAlpha","stdDeviation":4}),
+			filters.feOffset({"dx":5,"dy":5,"result":"offsetBlur"}),
+			filters.feMerge("offsetBlur","SourceGraphic")
+		]),
+		createFilter({_gfxName:"dropShadowLight"}, [
+			filters.feGaussianBlur({"in":"SourceAlpha","stdDeviation":4,"result":"blur"}),
+			filters.feComponentTransfer({
+				"in":"blur","result":"lessblur"
+			},[
+				filters.feFuncA({"type":"linear","slope":0.5})
+			]),
+			filters.feOffset({"in":"lessblur","dx":5,"dy":5,"result":"offsetBlur"}),
+			filters.feMerge("offsetBlur", "SourceGraphic")
+		]),
+		createFilter({_gfxName:"smallDropShadow"}, [
+			filters.feGaussianBlur({"in":"SourceAlpha","stdDeviation":3}),
+			filters.feOffset({"dx":2,"dy":2,"result":"offsetBlur"}),
+			filters.feMerge("offsetBlur", "SourceGraphic")
+		]),
+		createFilter({_gfxName:"smallDropShadowLight"}, [
+			filters.feGaussianBlur({"in":"SourceAlpha","stdDeviation":3,"result":"blur"}),
+			filters.feComponentTransfer({
+				"in":"blur","result":"lessblur"
+			},[
+				filters.feFuncA({"type":"linear","slope":0.5})
+			]),
+			filters.feOffset({"in":"lessblur","dx":2,"dy":2,"result":"offsetBlur"}),
+			filters.feMerge("offsetBlur","SourceGraphic")
+		])
+	];
+	var defaultDropShadowBBox = {
+		x:"-10%",
+		y:"-10%",
+		width:"125%",
+		height:"125%"
+	};
+	array.forEach(lib.shadows, function(f){
+		lang.mixin(f, defaultDropShadowBBox);
+	});
+
+	//
+	// Blur effects
+	//
+	lib.blurs = [
+		createFilter({
+			_gfxName: "blur1",x:"-5%",y:"-5%",width:"110%",height:"110%"
+		},[
+			filters.feGaussianBlur({"in":"SourceGraphic",stdDeviation:1})
+		]),
+		createFilter({
+			_gfxName: "blur2",x:"-15%",y:"-15%",width:"130%",height:"130%"
+		},[
+			filters.feGaussianBlur({"in": "SourceGraphic","stdDeviation": 2})
+		]),
+		createFilter({
+			_gfxName: "blur4",x:"-15%",y:"-15%",width:"130%",height:"130%"
+		},[
+			filters.feGaussianBlur({"in": "SourceGraphic","stdDeviation": 4})
+		]),
+		createFilter({
+			_gfxName: "blur8",x:"-20%",y:"-20%",width:"140%",height:"140%"
+		},[
+			filters.feGaussianBlur({"in": "SourceGraphic","stdDeviation": 8})
+		]),
+		createFilter({
+			_gfxName: "glow",x:"-10%",y:"-10%",width:"120%",height:"120%"
+		},[
+			filters.feGaussianBlur({"in": "SourceGraphic","stdDeviation": 2}),
+			filters.feComponentTransfer([
+				filters.feFuncA({"type":"linear","slope":10})
+			])
+		])
+	];
+
+	//
+	// Colors filters
+	//
+	lib.colors = [
+		createFilter({_gfxName:"negate"}, [
+			filters.feComponentTransfer([
+				filters.feFuncR({"type":"table","tableValues":"1,0"}),
+				filters.feFuncG({"type":"table","tableValues":"1,0"}),
+				filters.feFuncB({"type":"table","tableValues":"1,0"})
+			])
+		]),
+		createFilter({_gfxName:"sepia"}, [
+			filters.feColorMatrix({
+				"result":"grey",
+				"values":"0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0,0,0,1,0"
+			}),
+			filters.feComponentTransfer({
+				"in":"grey"
+			},[
+				filters.feFuncR({"type":"linear","slope":0.5,"intercept":0.5}),
+				filters.feFuncB({"type":"table","tableValues":"0,0"})
+			])
+		]),
+		createFilter({_gfxName:"grayscale"}, [
+			filters.feColorMatrix({
+				"values":"0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0,0,0,1,0"
+			})
+		]),
+		createFilter({_gfxName:"showRed"}, [
+			filters.feComponentTransfer([
+				filters.feFuncG({"type":"table","tableValues":"0,0"}),
+				filters.feFuncB({"type":"table","tableValues":"0,0"})
+			])
+		]),
+		createFilter({_gfxName:"showGreen"}, [
+			filters.feComponentTransfer([
+				filters.feFuncR({"type":"table","tableValues":"0,0"}),
+				filters.feFuncB({"type":"table","tableValues":"0,0"})
+			])
+		]),
+		createFilter({_gfxName:"showBlue"}, [
+			filters.feComponentTransfer([
+				filters.feFuncR({"type":"table","tableValues":"0,0"}),
+				filters.feFuncG({"type":"table","tableValues":"0,0"})
+			])
+		]),
+		createFilter({_gfxName:"hueRotate60"}, [
+			filters.feColorMatrix({"type":"hueRotate","values":60})
+		]),
+		createFilter({_gfxName:"hueRotate120"}, [
+			filters.feColorMatrix({"type":"hueRotate","values":120})
+		]),
+		createFilter({_gfxName:"hueRotate180"}, [
+			filters.feColorMatrix({"type":"hueRotate","values":180})
+		]),
+		createFilter({_gfxName:"hueRotate270"}, [
+			filters.feColorMatrix({"type":"hueRotate","values":270})
+		])
+	];
+	array.forEach(lib.colors, function(f){
+		lang.mixin(f, defaultFilterBBox);
+	});
+
+	lib.miscs = [
+		createFilter({
+			_gfxName:"thinEmbossDropShadow",
+			x:"-5%",y:"-5%",width:"120%",height:"120%"
+		}, [
+			filters.feGaussianBlur({"in":"SourceAlpha","stdDeviation":1,"result":"blur"}),
+			filters.feOffset({"in":"blur",dx:6,dy:6,"result":"offsetBlur"}),
+			filters.feSpecularLighting({
+				"in":"blur","surfaceScale":8,"specularConstant":1,"specularExponent":12,"result":"specOut"
+			}, [
+				filters.fePointLight({x:"-5000",y:"-10000",z:"12000"})
+			]),
+			filters.feComposite({"in":"specOut","in2":"SourceAlpha","operator":"in","result":"specOut"}),
+			filters.feComposite({
+				"in":"SourceGraphic","in2":"specOut","operator":"arithmetic","result":"litPaint",
+				"k1":0,"k2":1,"k3":1,"k4":0}),
+			filters.feMerge("offsetBlur", "litPaint")
+		]),
+		createFilter({
+			_gfxName:"embossDropShadow",
+			x:"-5%",y:"-5%",width:"120%",height:"120%"
+		}, [
+			filters.feGaussianBlur({"in": "SourceAlpha","stdDeviation":"4","result":"blur"}),
+			filters.feOffset({"in":"blur","dx":4,"dy":4,"result":"offsetBlur"}),
+			filters.feSpecularLighting({
+				"in":"blur","surfaceScale":5,"specularConstant":0.75,"specularExponent":20,
+				"lighting-color":"#bbbbbb","result":"specOut"
+			}, [filters.fePointLight({x:-5000,y:-10000,z:20000})]),
+			filters.feComposite({"in":"specOut","in2":"SourceAlpha","operator":"in","result":"specOut"}),
+			filters.feComposite({
+				"in":"SourceGraphic","in2":"specOut","operator":"arithmetic",k1:0,k2:1,k3:1,k4:0,"result":"litPaint"
+			}),
+			filters.feMerge("offsetBlur","litPaint")
+		]),
+		createFilter({
+			_gfxName:"largeEmbossDropShadow",
+			x:"-20%",y:"-20%",width:"140%",height:"140%"
+		}, [
+			filters.feGaussianBlur({"in":"SourceAlpha","stdDeviation":5,"result":"blur"}),
+			filters.feOffset({"in":"blur",dx:6,dy:6,"result":"offsetBlur"}),
+			filters.feSpecularLighting({
+				"in":"blur","surfaceScale":8,"specularConstant":1,"specularExponent":12,"result":"spec"
+			},[
+				filters.fePointLight({x:"-5000",y:"-10000",z:"12000"})
+			]),
+			filters.feComposite({"in":"spec","in2":"SourceGraphic","operator":"in","result":"specOut"}),
+			filters.feComposite({
+				"in":"SourceGraphic","in2":"specOut","operator":"arithmetic","result":"litPaint",
+				"k1":0,"k2":1,"k3":1,"k4":0
+			}),
+			filters.feMerge("offsetBlur", "litPaint")
+		]),
+		createFilter({
+			_gfxName:"thinEmbossDropShadowLight",
+			x:"-5%",y:"-5%",width:"120%",height:"120%"
+		}, [
+			filters.feGaussianBlur({"in":"SourceAlpha","stdDeviation":1,"result":"blur"}),
+			filters.feComponentTransfer({"in":"blur",result:"lessblur"
+			},[
+				filters.feFuncA({type:"linear",slope:"0.5"})
+			]),
+			filters.feOffset({"in":"lessblur","dx":"6","dy":"6","result":"offsetBlur"}),
+			filters.feSpecularLighting({
+				"in":"lessblur","surfaceScale":8,"specularConstant":1,"specularExponent":"12","result":"specOut"
+			},[
+				filters.fePointLight({x:"-5000",y:"-10000",z:"12000"})
+			]),
+			filters.feComposite({"in":"specOut","in2":"SourceAlpha","operator":"in","result":"specOut"}),
+			filters.feComposite({
+				"in":"SourceGraphic","in2":"specOut","result":"litPaint","operator":"arithmetic",
+				"k1":0,"k2":1,"k3":1,"k4":0
+			}),
+			filters.feMerge("offsetBlur", "litPaint")
+		]),
+		createFilter({
+			_gfxName: "embossDropShadowLight",
+			x: "-5%",y: "-5%",width: "120%",height: "120%"
+		}, [
+			filters.feGaussianBlur({"in": "SourceAlpha",stdDeviation:"3",result:"blur"}),
+			filters.feComponentTransfer({
+				"in": "blur",result: "lessblur"
+			},[
+				filters.feFuncA({type: "linear",slope: "0.5"})
+			]),
+			filters.feOffset({"in": "lessblur",dx: "6",dy: "6",result: "offsetBlur"}),
+			filters.feSpecularLighting({
+				"in": "lessblur",surfaceScale: "8",specularConstant: "1",specularExponent: "12",result: "specOut"
+			},[
+				filters.fePointLight({x: "-5000",y: "-10000",z: "12000"})
+			]),
+			filters.feComposite({"in": "specOut",in2: "SourceAlpha",operator: "in",result: "specOut"}),
+			filters.feComposite({
+				"in": "SourceGraphic",in2: "specOut",result: "litPaint",operator: "arithmetic",
+				k1: "0",k2: "1",k3: "1",k4: "0"
+			}),
+			filters.feMerge("offsetBlur", "litPaint")
+		]),
+		createFilter({
+			_gfxName: "largeEmbossDropShadowLight",
+			x: "-20%",y: "-20%",width: "140%",height: "140%"
+		},[
+			filters.feGaussianBlur({"in": "SourceAlpha",stdDeviation: "5",result: "blur"}),
+			filters.feComponentTransfer({"in": "blur",result: "lessblur"
+			},[
+				filters.feFuncA({type: "linear",slope: "0.5"})
+			]),
+			filters.feOffset({"in": "lessblur",dx: "6",dy: "6",result: "offsetBlur"}),
+			filters.feSpecularLighting({
+				"in": "blur",surfaceScale: "8",specularConstant: "1",specularExponent: "12",result: "spec"
+			},[
+				filters.fePointLight({x: "-5000",y: "-10000",z: "12000"})
+			]),
+			filters.feComposite({"in": "spec",in2: "SourceGraphic",operator: "in",result: "specOut"}),
+			filters.feComposite({
+				"in": "SourceGraphic",in2: "specOut",operator: "arithmetic",k1: "0",k2: "1",k3: "1",k4: "0",
+				result: "litPaint"
+			}),
+			filters.feMerge("offsetBlur", "litPaint")
+		]),
+		createFilter({
+			_gfxName:"fuzzy",
+			x:"-10%", y:"-10%", width:"120%", height:"120%"
+		},[
+			filters.feTurbulence({type:"fractalNoise",baseFrequency:"0.1",numOctaves:"1",result:"turb2"}),
+			filters.feDisplacementMap({
+				"in":"SourceGraphic",in2:"turb2",result:"turb2",scale:"20",xChannelSelector:"R",yChannelSelector:"G"
+			})
+		]),
+		createFilter({
+			_gfxName:"veryFuzzy",
+			x:"-20%", y:"-20%", width:"140%", height:"140%"
+		},[
+			filters.feTurbulence({type:"fractalNoise",baseFrequency:"0.1",numOctaves:"1",result:"turb2"}),
+			filters.feDisplacementMap({
+				"in":"SourceGraphic",in2:"turb2",result:"turb2",scale:"35",xChannelSelector:"R",yChannelSelector:"G"
+			})
+		]),
+		createFilter({
+			_gfxName:"melting",
+			x:"-10%", y:"-10%", width:"120%", height:"120%"
+		}, [
+			filters.feTurbulence({type:"fractalNoise",baseFrequency:"0.1",numOctaves:"2",result:"turb"}),
+			filters.feDisplacementMap({
+				result:"bended","in":"SourceGraphic",in2:"turb",scale:"25",xChannelSelector:"R",yChannelSelector:"G"
+			}),
+			filters.feGaussianBlur({"in":"bended",stdDeviation:"1",result:"bb"}),
+			filters.feComponentTransfer({"in": "bb",result: "BendedSource"
+			},[
+				filters.feFuncA({type: "linear",slope: 10,intercept: "-1"})
+			]),
+			filters.feComponentTransfer({
+				"in": "BendedSource",
+				result: "BendedAlpha"
+			}, [
+				filters.feFuncR({ type: "linear", slope: "0", intercept: "0"}),
+				filters.feFuncG({ type: "linear", slope: "0", intercept: "0"}),
+				filters.feFuncB({ type: "linear", slope: "0", intercept: "0"}),
+				filters.feFuncA({ type: "linear", slope: "1", intercept: "0"})
+			]),
+			filters.feGaussianBlur({
+				"in": "BendedAlpha", stdDeviation: "1", result: "blur"
+			}),
+			filters.feSpecularLighting({
+				"in": "blur","lighting-color": "rgb(80%, 80%, 80%)","surfaceScale": "5",
+				specularConstant: "1",specularExponent: "10",result: "specularOut"
+			},[
+				filters.fePointLight({ x: "-5000", y: "-10000", z: "20000"})
+			]),
+			filters.feComposite({
+				"in": "specularOut", in2: "BendedAlpha", operator: "in", result: "specularOut"
+			}),
+			filters.feComposite({
+				"in": "BendedSource",in2: "specularOut",operator: "arithmetic",k1: "0", k2: "1", k3: "1", k4: "0",
+				result: "litPaint"
+			})
+		]),
+		createFilter({
+			_gfxName:"impressionist", x:"0%", y:"0%", width:"100%", height:"100%"
+		},[
+			filters.feMorphology({
+				"in":"SourceGraphic", operator:"dilate", radius:"2"
+			})
+		]),
+		createFilter({
+			_gfxName:"holes", x:"0%", y:"0%", width:"100%", height:"100%"
+		},[
+			filters.feTurbulence({
+				type:"fractalNoise", baseFrequency:"0.1", numOctaves:"1", result:"texture"
+			}),
+			filters.feComponentTransfer({
+				"in":"texture", result:"holes"
+			},[
+				filters.feFuncA({type:"discrete", tableValues:"0,1"})
+			]),
+			filters.feComposite({
+				"in":"SourceGraphic", in2:"holes", operator:"out"
+			})
+		]),
+		createFilter({
+			_gfxName:"holesComplement", x:"0%", y:"0%", width:"100%", height:"100%"
+		},[
+			filters.feTurbulence({
+				type:"fractalNoise", baseFrequency:"0.1", numOctaves:"1", result:"texture"
+			}),
+			filters.feComponentTransfer({
+				"in":"texture", result:"holes"
+			},[
+				filters.feFuncA({ type:"discrete", tableValues:"1,0"})
+			]),
+			filters.feComposite({"in":"SourceGraphic", in2:"holes", operator:"out"})
+		])
+	];
+	
+	lib.reliefs = [
+		createFilter({
+			_gfxName:"bumpIn", x:"0%", y:"0%", width:"100%", height:"100%"
+		},[
+			filters.feColorMatrix({"in":"SourceGraphic", type:"luminanceToAlpha",result:"lumalpha"}),
+			filters.feComponentTransfer({
+				"in":"lumalpha", result:"invertedalpha"
+			},[
+				filters.feFuncA({ type:"table",tableValues:"1,0"})
+			]),
+			filters.feDiffuseLighting({
+				"in":"invertedalpha","lighting-color":"rgb(60%, 60%, 60%)",result:"diffuse",surfaceScale:"5"
+			},[
+				filters.feDistantLight({ azimuth:"135",elevation:"60"})
+			]),
+			filters.feSpecularLighting({
+				"in":"invertedalpha", result:"specular", surfaceScale:"5",specularExponent:"6"
+			},[
+				filters.feDistantLight({ azimuth:"135",elevation:"30"})
+			]),
+			filters.feComposite({ "in":"diffuse",in2:"specular",operator:"arithmetic",k2:"1.0",k3:"1.0"})
+		]),
+		createFilter({
+			_gfxName:"bumpOut", x:"0%", y:"0%", width:"100%", height:"100%"
+		},[
+			filters.feColorMatrix({ "in":"SourceGraphic", type:"luminanceToAlpha", result:"lumalpha"}),
+			filters.feDiffuseLighting({
+				"in":"lumalpha", "lighting-color":"rgb(60%, 60%, 60%)", result:"diffuse", surfaceScale:"5"
+			},[
+				filters.feDistantLight({ azimuth:"135", elevation:"60"})
+			]),
+			filters.feSpecularLighting({
+				"in":"lumalpha", result:"specular", surfaceScale:"5", specularExponent:"6"
+			},[
+				filters.feDistantLight({ azimuth:"135", elevation:"30"})
+			]),
+			filters.feComposite({ "in":"diffuse", in2:"specular", operator:"arithmetic", k2:"1.0", k3:"1.0"})
+		]),
+		createFilter({
+			_gfxName:"thinEmboss", x:"-5%", y:"-5%", width:"110%", height:"110%"
+		},[
+			filters.feGaussianBlur({ "in":"SourceAlpha", stdDeviation:"1", result:"blur"}),
+			filters.feSpecularLighting({
+				"in":"blur", surfaceScale:"8", specularConstant:"1", specularExponent:"12", result:"specOut"
+			},[
+				filters.fePointLight({ x:"-5000", y:"-10000", z:"12000"})
+			]),
+			filters.feComposite({ "in":"specOut", in2:"SourceAlpha", operator:"in",  result:"specOut"}),
+			filters.feComposite({
+				"in":"SourceGraphic", in2:"specOut", operator:"arithmetic", k1:"0", k2:"1", k3:"1", k4:"0"
+			})
+		]),
+		createFilter({
+			_gfxName:"emboss", x:"-5%", y:"-5%", width:"110%", height:"110%"
+		},[
+			filters.feGaussianBlur({ "in":"SourceAlpha", stdDeviation:"3", result:"blur"}),
+			filters.feSpecularLighting({
+				"in":"blur", surfaceScale:"8", specularConstant:"1", specularExponent:"12", result:"specOut"
+			},[
+				filters.fePointLight({ x:"-5000", y:"-10000", z:"12000"})
+			]),
+			filters.feComposite({ "in":"specOut", in2:"SourceAlpha", operator:"in",  result:"specOut"}),
+			filters.feComposite({
+				"in":"SourceGraphic", in2:"specOut", operator:"arithmetic", k1:"0", k2:"1", k3:"1", k4:"0"
+			})
+		]),
+		createFilter({
+			_gfxName:"largeEmboss", x:"-5%", y:"-5%", width:"110%", height:"110%"
+		},[
+			filters.feGaussianBlur({ "in":"SourceAlpha", stdDeviation:"5", result:"blur"}),
+			filters.feSpecularLighting({
+				"in":"blur", surfaceScale:"8", specularConstant:"1", specularExponent:"12", result:"specOut"
+			},[
+				filters.fePointLight({ x:"-5000", y:"-10000", z:"12000"})
+			]),
+			filters.feComposite({ "in":"specOut", in2:"SourceAlpha", operator:"in",  result:"specOut"}),
+			filters.feComposite({
+				"in":"SourceGraphic", in2:"specOut", operator:"arithmetic", k1:"0", k2:"1", k3:"1", k4:"0"
+			})
+		])
+	];
+	
+	lib.textures = [
+		createFilter({
+			_gfxName: "paper", x:"0%", y:"0%", width:"100%", height:"100%"
+		},[
+			filters.feTurbulence({ type:"turbulence", baseFrequency:"0.01", numOctaves:"5",result:"texture"}),
+			filters.feDiffuseLighting({
+				"in":"texture", result:"diffuse", surfaceScale:"-10"
+			},[
+				filters.feDistantLight({ azimuth:"135", elevation:"60"})
+			]),
+			filters.feComposite({ "in":"diffuse", in2:"SourceGraphic", operator:"arithmetic", k1:"1", k2:"0", k3:"0", k4:"0"})
+		]),
+		createFilter({
+			_gfxName:"swirl", x:"0%", y:"0%", width:"100%", height:"100%"
+		},[
+			filters.feTurbulence({ type:"turbulence",baseFrequency:"0.05",numOctaves:"1",result:"texture"}),
+			filters.feDiffuseLighting({
+				"in":"texture",result:"diffuse",surfaceScale:"-10"
+			},[
+				filters.feDistantLight({ azimuth:"135",elevation:"60"})
+			]),
+			filters.feComposite({"in":"diffuse",in2:"SourceGraphic",operator:"arithmetic",k1:"1",k2:"0",k3:"0",k4:"0"})
+		]),
+		createFilter({
+			_gfxName:"swirl2", x:"0%", y:"0%", width:"100%", height:"100%"
+		},[
+			filters.feTurbulence({ type:"turbulence",baseFrequency:"0.15",numOctaves:"1",result:"texture"}),
+			filters.feDiffuseLighting({
+				"in":"texture",result:"diffuse",surfaceScale:"-10"
+			},[
+				filters.feDistantLight({ azimuth:"135",elevation:"60"})
+			]),
+			filters.feComposite({"in":"diffuse",in2:"SourceGraphic",operator:"arithmetic",k1:"1",k2:"0",k3:"0",k4:"0"})
+		]),
+		createFilter({
+			_gfxName:"gold", x:"-5%", y:"-5%", width:"115%", height:"110%"
+		},[
+			filters.feTurbulence({ baseFrequency:"0.2", numOctaves:"1", type:"turbulence", result:"turb"}),
+			filters.feComposite({
+				"in":"SourceGraphic", in2:"turb", operator:"arithmetic", k2:"0.6", k3:"0.4", result:"turb"
+			}),
+			filters.feComposite({ "in":"turb", in2:"SourceGraphic", operator:"in", result:"bump"}),
+			filters.feDiffuseLighting({
+				"in":"turb", surfaceScale:"6.0", "lighting-color":"rgb(60%, 50%, 0%)", diffuseConstant:"1.0", result:"diffuse"
+			},[
+				filters.feDistantLight({ azimuth:"135", elevation:"60"})
+			]),
+			filters.feSpecularLighting({
+				"in":"bump", surfaceScale:"6.0", specularConstant:"1.0", specularExponent:"10.0", result:"specularOut"
+			},[
+				filters.feDistantLight({ azimuth:"135", elevation:"60"})
+			]),
+			filters.feComposite({ "in":"specularOut", in2:"SourceGraphic", operator:"in", result:"specularOut"}),
+			filters.feComposite({ "in":"bump", in2:"diffuse", operator:"arithmetic", k1:"0.7", k2:"0.3", result:"litPaint"}),
+			filters.feComposite({ "in":"litPaint", in2:"specularOut", operator:"arithmetic", k2:"1.0", k3:"0.7", result:"litPaint"})
+		])
+	];
+
+	// exports filters defined in lib as function via the returned object
+	// i.e. var filter = filters.convolution.verticalEdge({x:.., y:..., width:..., height:...})
+	for(var category in lib){
+		if(lib.hasOwnProperty(category)){
+			filters[category] = {};
+			var  cat = lib[category];
+			for(var i=0; i<cat.length;++i){
+				(function(){
+					var f = cat[i];
+					filters[category][f._gfxName] = function(args){
+						return lang.delegate(f, args);
+					};
+				})();
+			}
+		}
+	}
+
+	return filters;
+});
diff --git a/dojox/gfx/fx.js b/dojox/gfx/fx.js
index 7603aa2..d14e7ba 100644
--- a/dojox/gfx/fx.js
+++ b/dojox/gfx/fx.js
@@ -1,7 +1,6 @@
-define(["dojo/_base/lang", "./_base", "./matrix", "dojo/_base/Color", "dojo/_base/array", "dojo/_base/fx", "dojo/_base/connect"], 
-  function(lang, g, m, Color, arr, fx, Hub){
+define(["dojo/_base/lang", "./_base", "./matrix", "dojo/_base/Color", "dojo/_base/array", "dojo/_base/fx", "dojo/_base/connect", "dojo/sniff"], 
+  function(lang, g, m, Color, arr, fx, Hub, has){
 	var fxg = g.fx = {};
-	/*===== g = dojox.gfx; fxg = dojox.gfx.fx; =====*/
 
 	// Generic interpolators. Should they be moved to dojox.fx?
 
@@ -63,6 +62,17 @@ define(["dojo/_base/lang", "./_base", "./matrix", "dojo/_base/Color", "dojo/_bas
 				ret.push(this.original);
 				return;
 			}
+ 			// Adding support for custom matrices
+ 			if(t.name == "matrix"){
+ 				if((t.start instanceof m.Matrix2D) && (t.end instanceof m.Matrix2D)){
+ 					var transfMatrix = new m.Matrix2D();
+ 					for(var p in t.start) {
+ 						transfMatrix[p] = (t.end[p] - t.start[p])*r + t.start[p];
+ 					}
+ 					ret.push(transfMatrix);
+ 				}
+ 				return;
+ 			}
 			if(!(t.name in m)){ return; }
 			var f = m[t.name];
 			if(typeof f != "function"){
@@ -127,9 +137,11 @@ define(["dojo/_base/lang", "./_base", "./matrix", "dojo/_base/Color", "dojo/_bas
 
 	fxg.animateStroke = function(/*Object*/ args){
 		// summary:
-		//	Returns an animation which will change stroke properties over time.
+		//		Returns an animation which will change stroke properties over time.
+		// args:
+		//		an object defining the animation setting.
 		// example:
-		//	|	dojox.gfx.fx.animateStroke{{
+		//	|	fxg.animateStroke{{
 		//	|		shape: shape,
 		//	|		duration: 500,
 		//	|		color: {start: "red", end: "green"},
@@ -176,10 +188,12 @@ define(["dojo/_base/lang", "./_base", "./matrix", "dojo/_base/Color", "dojo/_bas
 
 	fxg.animateFill = function(/*Object*/ args){
 		// summary:
-		//	Returns an animation which will change fill color over time.
-		//	Only solid fill color is supported at the moment
+		//		Returns an animation which will change fill color over time.
+		//		Only solid fill color is supported at the moment
+		// args:
+		//		an object defining the animation setting.
 		// example:
-		//	|	dojox.gfx.fx.animateFill{{
+		//	|	gfx.animateFill{{
 		//	|		shape: shape,
 		//	|		duration: 500,
 		//	|		color: {start: "red", end: "green"}
@@ -199,9 +213,11 @@ define(["dojo/_base/lang", "./_base", "./matrix", "dojo/_base/Color", "dojo/_bas
 
 	fxg.animateFont = function(/*Object*/ args){
 		// summary:
-		//	Returns an animation which will change font properties over time.
+		//		Returns an animation which will change font properties over time.
+		// args:
+		//		an object defining the animation setting.
 		// example:
-		//	|	dojox.gfx.fx.animateFont{{
+		//	|	gfx.animateFont{{
 		//	|		shape: shape,
 		//	|		duration: 500,
 		//	|		variant: {values: ["normal", "small-caps"]},
@@ -241,9 +257,11 @@ define(["dojo/_base/lang", "./_base", "./matrix", "dojo/_base/Color", "dojo/_bas
 
 	fxg.animateTransform = function(/*Object*/ args){
 		// summary:
-		//	Returns an animation which will change transformation over time.
+		//		Returns an animation which will change transformation over time.
+		// args:
+		//		an object defining the animation setting.
 		// example:
-		//	|	dojox.gfx.fx.animateTransform{{
+		//	|	gfx.animateTransform{{
 		//	|		shape: shape,
 		//	|		duration: 500,
 		//	|		transform: [
@@ -258,6 +276,45 @@ define(["dojo/_base/lang", "./_base", "./matrix", "dojo/_base/Color", "dojo/_bas
 			this.curve = new InterpolTransform(args.transform, original);
 		});
 		Hub.connect(anim, "onAnimate", shape, "setTransform");
+		if(g.renderer === "svg" && has("ie") >= 10){
+			// fix http://bugs.dojotoolkit.org/ticket/16879
+			var handlers = [
+					Hub.connect(anim, "onBegin", anim, function(){
+						var parent = shape.getParent();
+						while(parent && parent.getParent){
+							parent = parent.getParent();
+						}
+						if(parent){
+							shape.__svgContainer = parent.rawNode.parentNode;
+						}
+					}),
+					Hub.connect(anim, "onAnimate", anim, function(){
+						try{
+							if(shape.__svgContainer){
+								var ov = shape.__svgContainer.style.visibility;
+								shape.__svgContainer.style.visibility = "visible";
+								var pokeNode = shape.__svgContainer.offsetHeight;
+								shape.__svgContainer.style.visibility = ov;
+							}
+						}catch(e){}
+					}),
+					Hub.connect(anim, "onEnd", anim, function(){
+						arr.forEach(handlers, Hub.disconnect);
+						if(shape.__svgContainer){
+							var ov = shape.__svgContainer.style.visibility;
+							var sn = shape.__svgContainer;
+							shape.__svgContainer.style.visibility = "visible";
+							setTimeout(function(){
+								try{
+									sn.style.visibility = ov;
+									sn = null;
+								}catch(e){}
+							},100);
+						}
+						delete shape.__svgContainer;
+					})
+				];
+		}
 		return anim; // dojo.Animation
 	};
 	
diff --git a/dojox/gfx/gradient.js b/dojox/gfx/gradient.js
index 85d0311..8c52630 100644
--- a/dojox/gfx/gradient.js
+++ b/dojox/gfx/gradient.js
@@ -3,7 +3,6 @@ define(["dojo/_base/lang", "./matrix", "dojo/_base/Color"],
 // Various utilities to deal with a linear gradient (mostly VML-specific)
 	var grad = lang.getObject("dojox.gfx.gradient", true);
 	var C = Color;
-	/*===== grad = dojox.gfx.gradient;  =====*/
 	
 	grad.rescale = function(stops, from, to){
 		// summary:
@@ -12,7 +11,7 @@ define(["dojo/_base/lang", "./matrix", "dojo/_base/Color"],
 		//		if necessary.
 		// stops: Array
 		//		input gradient as a list of colors with offsets
-		//		(see dojox.gfx.defaultLinearGradient and dojox.gfx.defaultRadialGradient)
+		//		(see dojox/gfx.defaultLinearGradient and dojox/gfx.defaultRadialGradient)
 		// from: Number
 		//		the beginning of the window, should be less than "to"
 		// to: Number
@@ -110,17 +109,17 @@ define(["dojo/_base/lang", "./matrix", "dojo/_base/Color"],
 	grad.project = function(matrix, gradient, tl, rb, ttl, trb){
 		// summary:
 		//		Returns a new gradient using the "VML algorithm" and suitable for VML.
-		// matrix: dojox.gfx.Matrix2D|Null:
+		// matrix: dojox/gfx/matrix.Matrix2D|null
 		//		matrix to apply to a shape and its gradient
-		// gradient: Object:
+		// gradient: Object
 		//		a linear gradient object to be transformed
-		// tl: dojox.gfx.Point:
+		// tl: dojox/gfx.Point
 		//		top-left corner of shape's bounding box
-		// rb: dojox.gfx.Point:
+		// rb: dojox/gfx.Point
 		//		right-bottom corner of shape's bounding box
-		// ttl: dojox.gfx.Point:
+		// ttl: dojox/gfx.Point
 		//		top-left corner of shape's transformed bounding box
-		// trb: dojox.gfx.Point:
+		// trb: dojox/gfx.Point
 		//		right-bottom corner of shape's transformed bounding box
 		
 		matrix = matrix || m.identity;
diff --git a/dojox/gfx/gradutils.js b/dojox/gfx/gradutils.js
index 7dd9771..e32bb75 100644
--- a/dojox/gfx/gradutils.js
+++ b/dojox/gfx/gradutils.js
@@ -3,9 +3,7 @@
 define(["./_base", "dojo/_base/lang", "./matrix", "dojo/_base/Color"], 
   function(g, lang, m, Color){
   
-	/*===== g= dojox.gfx =====*/
 	var gradutils = g.gradutils = {};
-	/*===== g= dojox.gfx; gradutils = dojox.gfx.gradutils; =====*/
 
 	function findColor(o, c){
 		if(o <= 0){
@@ -33,9 +31,9 @@ define(["./_base", "dojo/_base/lang", "./matrix", "dojo/_base/Color"],
 	gradutils.getColor = function(fill, pt){
 		// summary:
 		//		sample a color from a gradient using a point
-		// fill: Object:
+		// fill: Object
 		//		fill object
-		// pt: dojox.gfx.Point:
+		// pt: dojox/gfx.Point
 		//		point where to sample a color
 		var o;
 		if(fill){
@@ -55,16 +53,16 @@ define(["./_base", "dojo/_base/lang", "./matrix", "dojo/_base/Color"],
 					o = Math.sqrt(dx * dx + dy * dy) / fill.r;
 					break;
 			}
-			return findColor(o, fill.colors);	// dojo.Color
+			return findColor(o, fill.colors);	// dojo/_base/Color
 		}
 		// simple color
-		return new Color(fill || [0, 0, 0, 0]);	// dojo.Color
+		return new Color(fill || [0, 0, 0, 0]);	// dojo/_base/Color
 	};
 
 	gradutils.reverse = function(fill){
 		// summary:
 		//		reverses a gradient
-		// fill: Object:
+		// fill: Object
 		//		fill object
 		if(fill){
 			switch(fill.type){
diff --git a/dojox/gfx/matrix.js b/dojox/gfx/matrix.js
index 5e0a2d8..24358f7 100644
--- a/dojox/gfx/matrix.js
+++ b/dojox/gfx/matrix.js
@@ -1,7 +1,6 @@
 define(["./_base","dojo/_base/lang"], 
   function(g, lang){
 	var m = g.matrix = {};
-	/*===== g = dojox.gfx; m = dojox.gfx.matrix =====*/
 
 	// candidates for dojox.math:
 	var _degToRadCache = {};
@@ -11,9 +10,10 @@ define(["./_base","dojo/_base/lang"],
 	m._radToDeg = function(radian){ return radian / Math.PI * 180; };
 
 	m.Matrix2D = function(arg){
-		// summary: 
+		// summary:
 		//		a 2D matrix object
-		// description: Normalizes a 2D matrix-like object. If arrays is passed,
+		// description:
+		//		Normalizes a 2D matrix-like object. If arrays is passed,
 		//		all objects of the array are normalized and multiplied sequentially.
 		// arg: Object
 		//		a 2D matrix-like object, a number, or an array of such objects
@@ -46,167 +46,217 @@ define(["./_base","dojo/_base/lang"],
 	lang.extend(m.Matrix2D, {xx: 1, xy: 0, yx: 0, yy: 1, dx: 0, dy: 0});
 
 	lang.mixin(m, {
-		// summary: class constants, and methods of dojox.gfx.matrix
+		// summary:
+		//		class constants, and methods of dojox/gfx/matrix
 
 		// matrix constants
 
-		// identity: dojox.gfx.matrix.Matrix2D
+		// identity: dojox/gfx/matrix.Matrix2D
 		//		an identity matrix constant: identity * (x, y) == (x, y)
 		identity: new m.Matrix2D(),
 
-		// flipX: dojox.gfx.matrix.Matrix2D
+		// flipX: dojox/gfx/matrix.Matrix2D
 		//		a matrix, which reflects points at x = 0 line: flipX * (x, y) == (-x, y)
 		flipX:    new m.Matrix2D({xx: -1}),
 
-		// flipY: dojox.gfx.matrix.Matrix2D
+		// flipY: dojox/gfx/matrix.Matrix2D
 		//		a matrix, which reflects points at y = 0 line: flipY * (x, y) == (x, -y)
 		flipY:    new m.Matrix2D({yy: -1}),
 
-		// flipXY: dojox.gfx.matrix.Matrix2D
+		// flipXY: dojox/gfx/matrix.Matrix2D
 		//		a matrix, which reflects points at the origin of coordinates: flipXY * (x, y) == (-x, -y)
 		flipXY:   new m.Matrix2D({xx: -1, yy: -1}),
 
 		// matrix creators
 
 		translate: function(a, b){
-			// summary: forms a translation matrix
-			// description: The resulting matrix is used to translate (move) points by specified offsets.
-			// a: Number: an x coordinate value
-			// b: Number: a y coordinate value
+			// summary:
+			//		forms a translation matrix
+			// description:
+			//		The resulting matrix is used to translate (move) points by specified offsets.
+			// a: Number|dojox/gfx.Point
+			//		an x coordinate value, or a point-like object, which specifies offsets for both dimensions
+			// b: Number?
+			//		a y coordinate value
+			// returns: dojox/gfx/matrix.Matrix2D
 			if(arguments.length > 1){
-				return new m.Matrix2D({dx: a, dy: b}); // dojox.gfx.matrix.Matrix2D
+				return new m.Matrix2D({dx: a, dy: b}); // dojox/gfx/matrix.Matrix2D
 			}
 			// branch
-			// a: dojox.gfx.Point: a point-like object, which specifies offsets for both dimensions
-			// b: null
-			return new m.Matrix2D({dx: a.x, dy: a.y}); // dojox.gfx.matrix.Matrix2D
+			return new m.Matrix2D({dx: a.x, dy: a.y}); // dojox/gfx/matrix.Matrix2D
 		},
 		scale: function(a, b){
-			// summary: forms a scaling matrix
-			// description: The resulting matrix is used to scale (magnify) points by specified offsets.
-			// a: Number: a scaling factor used for the x coordinate
-			// b: Number: a scaling factor used for the y coordinate
+			// summary:
+			//		forms a scaling matrix
+			// description:
+			//		The resulting matrix is used to scale (magnify) points by specified offsets.
+			// a: Number|dojox/gfx.Point
+			//		a scaling factor used for the x coordinate, or
+			//		a uniform scaling factor used for the both coordinates, or
+			//		a point-like object, which specifies scale factors for both dimensions
+			// b: Number?
+			//		a scaling factor used for the y coordinate
+			// returns: dojox/gfx/matrix.Matrix2D
 			if(arguments.length > 1){
-				return new m.Matrix2D({xx: a, yy: b}); // dojox.gfx.matrix.Matrix2D
+				return new m.Matrix2D({xx: a, yy: b}); // dojox/gfx/matrix.Matrix2D
 			}
 			if(typeof a == "number"){
-				// branch
-				// a: Number: a uniform scaling factor used for the both coordinates
-				// b: null
-				return new m.Matrix2D({xx: a, yy: a}); // dojox.gfx.matrix.Matrix2D
+				return new m.Matrix2D({xx: a, yy: a}); // dojox/gfx/matrix.Matrix2D
 			}
-			// branch
-			// a: dojox.gfx.Point: a point-like object, which specifies scale factors for both dimensions
-			// b: null
-			return new m.Matrix2D({xx: a.x, yy: a.y}); // dojox.gfx.matrix.Matrix2D
+			return new m.Matrix2D({xx: a.x, yy: a.y}); // dojox/gfx/matrix.Matrix2D
 		},
 		rotate: function(angle){
-			// summary: forms a rotating matrix
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified angle.
-			// angle: Number: an angle of rotation in radians (>0 for CW)
+			// angle: Number
+			//		an angle of rotation in radians (>0 for CW)
+			// returns: dojox/gfx/matrix.Matrix2D
 			var c = Math.cos(angle);
 			var s = Math.sin(angle);
-			return new m.Matrix2D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx.matrix.Matrix2D
+			return new m.Matrix2D({xx: c, xy: -s, yx: s, yy: c}); // dojox/gfx/matrix.Matrix2D
 		},
 		rotateg: function(degree){
-			// summary: forms a rotating matrix
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified degree.
-			//		See dojox.gfx.matrix.rotate() for comparison.
-			// degree: Number: an angle of rotation in degrees (>0 for CW)
-			return m.rotate(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+			//		See dojox/gfx/matrix.rotate() for comparison.
+			// degree: Number
+			//		an angle of rotation in degrees (>0 for CW)
+			// returns: dojox/gfx/matrix.Matrix2D
+			return m.rotate(m._degToRad(degree)); // dojox/gfx/matrix.Matrix2D
 		},
 		skewX: function(angle) {
-			// summary: forms an x skewing matrix
-			// description: The resulting matrix is used to skew points in the x dimension
+			// summary:
+			//		forms an x skewing matrix
+			// description:
+			//		The resulting matrix is used to skew points in the x dimension
 			//		around the origin of coordinates (0, 0) by specified angle.
-			// angle: Number: an skewing angle in radians
-			return new m.Matrix2D({xy: Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D
+			// angle: Number
+			//		a skewing angle in radians
+			// returns: dojox/gfx/matrix.Matrix2D
+			return new m.Matrix2D({xy: Math.tan(angle)}); // dojox/gfx/matrix.Matrix2D
 		},
 		skewXg: function(degree){
-			// summary: forms an x skewing matrix
-			// description: The resulting matrix is used to skew points in the x dimension
+			// summary:
+			//		forms an x skewing matrix
+			// description:
+			//		The resulting matrix is used to skew points in the x dimension
 			//		around the origin of coordinates (0, 0) by specified degree.
-			//		See dojox.gfx.matrix.skewX() for comparison.
-			// degree: Number: an skewing angle in degrees
-			return m.skewX(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+			//		See dojox/gfx/matrix.skewX() for comparison.
+			// degree: Number
+			//		a skewing angle in degrees
+			// returns: dojox/gfx/matrix.Matrix2D
+			return m.skewX(m._degToRad(degree)); // dojox/gfx/matrix.Matrix2D
 		},
 		skewY: function(angle){
-			// summary: forms a y skewing matrix
-			// description: The resulting matrix is used to skew points in the y dimension
+			// summary:
+			//		forms a y skewing matrix
+			// description:
+			//		The resulting matrix is used to skew points in the y dimension
 			//		around the origin of coordinates (0, 0) by specified angle.
-			// angle: Number: an skewing angle in radians
-			return new m.Matrix2D({yx: Math.tan(angle)}); // dojox.gfx.matrix.Matrix2D
+			// angle: Number
+			//		a skewing angle in radians
+			// returns: dojox/gfx/matrix.Matrix2D
+			return new m.Matrix2D({yx: Math.tan(angle)}); // dojox/gfx/matrix.Matrix2D
 		},
 		skewYg: function(degree){
-			// summary: forms a y skewing matrix
-			// description: The resulting matrix is used to skew points in the y dimension
+			// summary:
+			//		forms a y skewing matrix
+			// description:
+			//		The resulting matrix is used to skew points in the y dimension
 			//		around the origin of coordinates (0, 0) by specified degree.
-			//		See dojox.gfx.matrix.skewY() for comparison.
-			// degree: Number: an skewing angle in degrees
-			return m.skewY(m._degToRad(degree)); // dojox.gfx.matrix.Matrix2D
+			//		See dojox/gfx/matrix.skewY() for comparison.
+			// degree: Number
+			//		a skewing angle in degrees
+			// returns: dojox/gfx/matrix.Matrix2D
+			return m.skewY(m._degToRad(degree)); // dojox/gfx/matrix.Matrix2D
 		},
 		reflect: function(a, b){
-			// summary: forms a reflection matrix
-			// description: The resulting matrix is used to reflect points around a vector,
+			// summary:
+			//		forms a reflection matrix
+			// description:
+			//		The resulting matrix is used to reflect points around a vector,
 			//		which goes through the origin.
-			// a: dojox.gfx.Point: a point-like object, which specifies a vector of reflection
-			// b: null
+			// a: dojox/gfx.Point|Number
+			//		a point-like object, which specifies a vector of reflection, or an X value
+			// b: Number?
+			//		a Y value
+			// returns: dojox/gfx/matrix.Matrix2D
 			if(arguments.length == 1){
 				b = a.y;
 				a = a.x;
 			}
-			// branch
-			// a: Number: an x coordinate value
-			// b: Number: a y coordinate value
-
 			// make a unit vector
 			var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = 2 * a * b / n2;
-			return new m.Matrix2D({xx: 2 * a2 / n2 - 1, xy: xy, yx: xy, yy: 2 * b2 / n2 - 1}); // dojox.gfx.matrix.Matrix2D
+			return new m.Matrix2D({xx: 2 * a2 / n2 - 1, xy: xy, yx: xy, yy: 2 * b2 / n2 - 1}); // dojox/gfx/matrix.Matrix2D
 		},
 		project: function(a, b){
-			// summary: forms an orthogonal projection matrix
-			// description: The resulting matrix is used to project points orthogonally on a vector,
+			// summary:
+			//		forms an orthogonal projection matrix
+			// description:
+			//		The resulting matrix is used to project points orthogonally on a vector,
 			//		which goes through the origin.
-			// a: dojox.gfx.Point: a point-like object, which specifies a vector of projection
-			// b: null
+			// a: dojox/gfx.Point|Number
+			//		a point-like object, which specifies a vector of projection, or
+			//		an x coordinate value
+			// b: Number?
+			//		a y coordinate value
+			// returns: dojox/gfx/matrix.Matrix2D
 			if(arguments.length == 1){
 				b = a.y;
 				a = a.x;
 			}
-			// branch
-			// a: Number: an x coordinate value
-			// b: Number: a y coordinate value
-
 			// make a unit vector
 			var a2 = a * a, b2 = b * b, n2 = a2 + b2, xy = a * b / n2;
-			return new m.Matrix2D({xx: a2 / n2, xy: xy, yx: xy, yy: b2 / n2}); // dojox.gfx.matrix.Matrix2D
+			return new m.Matrix2D({xx: a2 / n2, xy: xy, yx: xy, yy: b2 / n2}); // dojox/gfx/matrix.Matrix2D
 		},
 
 		// ensure matrix 2D conformance
 		normalize: function(matrix){
-			// summary: converts an object to a matrix, if necessary
-			// description: Converts any 2D matrix-like object or an array of
-			//		such objects to a valid dojox.gfx.matrix.Matrix2D object.
-			// matrix: Object: an object, which is converted to a matrix, if necessary
-			return (matrix instanceof m.Matrix2D) ? matrix : new m.Matrix2D(matrix); // dojox.gfx.matrix.Matrix2D
+			// summary:
+			//		converts an object to a matrix, if necessary
+			// description:
+			//		Converts any 2D matrix-like object or an array of
+			//		such objects to a valid dojox/gfx/matrix.Matrix2D object.
+			// matrix: Object
+			//		an object, which is converted to a matrix, if necessary
+			// returns: dojox/gfx/matrix.Matrix2D
+			return (matrix instanceof m.Matrix2D) ? matrix : new m.Matrix2D(matrix); // dojox/gfx/matrix.Matrix2D
 		},
 
 		// common operations
 
+		isIdentity: function(matrix){
+			// summary:
+			//		returns whether the specified matrix is the identity.
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a 2D matrix object to be tested
+			// returns: Boolean
+			return matrix.xx == 1 && matrix.xy == 0 && matrix.yx == 0 && matrix.yy == 1 && matrix.dx == 0 && matrix.dy == 0; // Boolean
+		},
 		clone: function(matrix){
-			// summary: creates a copy of a 2D matrix
-			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be cloned
+			// summary:
+			//		creates a copy of a 2D matrix
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a 2D matrix-like object to be cloned
+			// returns: dojox/gfx/matrix.Matrix2D
 			var obj = new m.Matrix2D();
 			for(var i in matrix){
 				if(typeof(matrix[i]) == "number" && typeof(obj[i]) == "number" && obj[i] != matrix[i]) obj[i] = matrix[i];
 			}
-			return obj; // dojox.gfx.matrix.Matrix2D
+			return obj; // dojox/gfx/matrix.Matrix2D
 		},
 		invert: function(matrix){
-			// summary: inverts a 2D matrix
-			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object to be inverted
+			// summary:
+			//		inverts a 2D matrix
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a 2D matrix-like object to be inverted
+			// returns: dojox/gfx/matrix.Matrix2D
 			var M = m.normalize(matrix),
 				D = M.xx * M.yy - M.xy * M.yx;
 				M = new m.Matrix2D({
@@ -215,33 +265,72 @@ define(["./_base","dojo/_base/lang"],
 					dx: (M.xy * M.dy - M.yy * M.dx) / D,
 					dy: (M.yx * M.dx - M.xx * M.dy) / D
 				});
-			return M; // dojox.gfx.matrix.Matrix2D
+			return M; // dojox/gfx/matrix.Matrix2D
 		},
 		_multiplyPoint: function(matrix, x, y){
-			// summary: applies a matrix to a point
-			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
-			// x: Number: an x coordinate of a point
-			// y: Number: a y coordinate of a point
-			return {x: matrix.xx * x + matrix.xy * y + matrix.dx, y: matrix.yx * x + matrix.yy * y + matrix.dy}; // dojox.gfx.Point
+			// summary:
+			//		applies a matrix to a point
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a 2D matrix object to be applied
+			// x: Number
+			//		an x coordinate of a point
+			// y: Number
+			//		a y coordinate of a point
+			// returns: dojox/gfx.Point
+			return {x: matrix.xx * x + matrix.xy * y + matrix.dx, y: matrix.yx * x + matrix.yy * y + matrix.dy}; // dojox/gfx.Point
 		},
 		multiplyPoint: function(matrix, /* Number||Point */ a, /* Number? */ b){
-			// summary: applies a matrix to a point
-			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
-			// a: Number: an x coordinate of a point
-			// b: Number?: a y coordinate of a point
+			// summary:
+			//		applies a matrix to a point
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a 2D matrix object to be applied
+			// a: Number|dojox/gfx.Point
+			//		an x coordinate of a point, or a point
+			// b: Number?
+			//		a y coordinate of a point
+			// returns: dojox/gfx.Point
 			var M = m.normalize(matrix);
 			if(typeof a == "number" && typeof b == "number"){
-				return m._multiplyPoint(M, a, b); // dojox.gfx.Point
+				return m._multiplyPoint(M, a, b); // dojox/gfx.Point
 			}
-			// branch
-			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix object to be applied
-			// a: dojox.gfx.Point: a point
-			// b: null
-			return m._multiplyPoint(M, a.x, a.y); // dojox.gfx.Point
+			return m._multiplyPoint(M, a.x, a.y); // dojox/gfx.Point
+		},
+		multiplyRectangle: function(matrix, /*Rectangle*/ rect){
+			// summary:
+			//		Applies a matrix to a rectangle.
+			// description:
+			//		The method applies the transformation on all corners of the
+			//		rectangle and returns the smallest rectangle enclosing the 4 transformed
+			//		points.
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a 2D matrix object to be applied.
+			// rect: Rectangle
+			//		the rectangle to transform.
+			// returns: dojox/gfx.Rectangle
+			var M = m.normalize(matrix);
+			rect = rect || {x:0, y:0, width:0, height:0}; 
+			if(m.isIdentity(M))
+				return {x: rect.x, y: rect.y, width: rect.width, height: rect.height}; // dojo/gfx.Rectangle
+			var p0 = m.multiplyPoint(M, rect.x, rect.y),
+				p1 = m.multiplyPoint(M, rect.x, rect.y + rect.height),
+				p2 = m.multiplyPoint(M, rect.x + rect.width, rect.y),
+				p3 = m.multiplyPoint(M, rect.x + rect.width, rect.y + rect.height),
+				minx = Math.min(p0.x, p1.x, p2.x, p3.x),
+				miny = Math.min(p0.y, p1.y, p2.y, p3.y),
+				maxx = Math.max(p0.x, p1.x, p2.x, p3.x),
+				maxy = Math.max(p0.y, p1.y, p2.y, p3.y);
+			return{ // dojo/gfx.Rectangle
+				x: minx,
+				y: miny,
+				width: maxx - minx,
+				height: maxy - miny
+			};
 		},
 		multiply: function(matrix){
-			// summary: combines matrices by multiplying them sequentially in the given order
-			// matrix: dojox.gfx.matrix.Matrix2D...: a 2D matrix-like object,
+			// summary:
+			//		combines matrices by multiplying them sequentially in the given order
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a 2D matrix-like object,
 			//		all subsequent arguments are matrix-like objects too
 			var M = m.normalize(matrix);
 			// combine matrices
@@ -255,184 +344,149 @@ define(["./_base","dojo/_base/lang"],
 				M.dx = l.xx * r.dx + l.xy * r.dy + l.dx;
 				M.dy = l.yx * r.dx + l.yy * r.dy + l.dy;
 			}
-			return M; // dojox.gfx.matrix.Matrix2D
+			return M; // dojox/gfx/matrix.Matrix2D
 		},
 
 		// high level operations
 
 		_sandwich: function(matrix, x, y){
-			// summary: applies a matrix at a centrtal point
-			// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object, which is applied at a central point
-			// x: Number: an x component of the central point
-			// y: Number: a y component of the central point
-			return m.multiply(m.translate(x, y), matrix, m.translate(-x, -y)); // dojox.gfx.matrix.Matrix2D
+			// summary:
+			//		applies a matrix at a central point
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a 2D matrix-like object, which is applied at a central point
+			// x: Number
+			//		an x component of the central point
+			// y: Number
+			//		a y component of the central point
+			return m.multiply(m.translate(x, y), matrix, m.translate(-x, -y)); // dojox/gfx/matrix.Matrix2D
 		},
 		scaleAt: function(a, b, c, d){
-			// summary: scales a picture using a specified point as a center of scaling
-			// description: Compare with dojox.gfx.matrix.scale().
-			// a: Number: a scaling factor used for the x coordinate
-			// b: Number: a scaling factor used for the y coordinate
-			// c: Number: an x component of a central point
-			// d: Number: a y component of a central point
-
-			// accepts several signatures:
-			//	1) uniform scale factor, Point
-			//	2) uniform scale factor, x, y
-			//	3) x scale, y scale, Point
-			//	4) x scale, y scale, x, y
-
+			// summary:
+			//		scales a picture using a specified point as a center of scaling
+			// description:
+			//		Compare with dojox/gfx/matrix.scale().
+			// a: Number
+			//		a scaling factor used for the x coordinate, or a uniform scaling factor used for both coordinates
+			// b: Number?
+			//		a scaling factor used for the y coordinate
+			// c: Number|Point
+			//		an x component of a central point, or a central point
+			// d: Number
+			//		a y component of a central point
+			// returns: dojox/gfx/matrix.Matrix2D
 			switch(arguments.length){
 				case 4:
 					// a and b are scale factor components, c and d are components of a point
-					return m._sandwich(m.scale(a, b), c, d); // dojox.gfx.matrix.Matrix2D
+					return m._sandwich(m.scale(a, b), c, d); // dojox/gfx/matrix.Matrix2D
 				case 3:
 					if(typeof c == "number"){
-						// branch
-						// a: Number: a uniform scaling factor used for both coordinates
-						// b: Number: an x component of a central point
-						// c: Number: a y component of a central point
-						// d: null
-						return m._sandwich(m.scale(a), b, c); // dojox.gfx.matrix.Matrix2D
+						return m._sandwich(m.scale(a), b, c); // dojox/gfx/matrix.Matrix2D
 					}
-					// branch
-					// a: Number: a scaling factor used for the x coordinate
-					// b: Number: a scaling factor used for the y coordinate
-					// c: dojox.gfx.Point: a central point
-					// d: null
-					return m._sandwich(m.scale(a, b), c.x, c.y); // dojox.gfx.matrix.Matrix2D
+					return m._sandwich(m.scale(a, b), c.x, c.y); // dojox/gfx/matrix.Matrix2D
 			}
-			// branch
-			// a: Number: a uniform scaling factor used for both coordinates
-			// b: dojox.gfx.Point: a central point
-			// c: null
-			// d: null
-			return m._sandwich(m.scale(a), b.x, b.y); // dojox.gfx.matrix.Matrix2D
+			return m._sandwich(m.scale(a), b.x, b.y); // dojox/gfx/matrix.Matrix2D
 		},
 		rotateAt: function(angle, a, b){
-			// summary: rotates a picture using a specified point as a center of rotation
-			// description: Compare with dojox.gfx.matrix.rotate().
-			// angle: Number: an angle of rotation in radians (>0 for CW)
-			// a: Number: an x component of a central point
-			// b: Number: a y component of a central point
-
-			// accepts several signatures:
-			//	1) rotation angle in radians, Point
-			//	2) rotation angle in radians, x, y
-
+			// summary:
+			//		rotates a picture using a specified point as a center of rotation
+			// description:
+			//		Compare with dojox/gfx/matrix.rotate().
+			// angle: Number
+			//		an angle of rotation in radians (>0 for CW)
+			// a: Number|dojox/gfx.Point
+			//		an x component of a central point, or a central point
+			// b: Number?
+			//		a y component of a central point
+			// returns: dojox/gfx/matrix.Matrix2D
 			if(arguments.length > 2){
-				return m._sandwich(m.rotate(angle), a, b); // dojox.gfx.matrix.Matrix2D
+				return m._sandwich(m.rotate(angle), a, b); // dojox/gfx/matrix.Matrix2D
 			}
-
-			// branch
-			// angle: Number: an angle of rotation in radians (>0 for CCW)
-			// a: dojox.gfx.Point: a central point
-			// b: null
-			return m._sandwich(m.rotate(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+			return m._sandwich(m.rotate(angle), a.x, a.y); // dojox/gfx/matrix.Matrix2D
 		},
 		rotategAt: function(degree, a, b){
-			// summary: rotates a picture using a specified point as a center of rotation
-			// description: Compare with dojox.gfx.matrix.rotateg().
-			// degree: Number: an angle of rotation in degrees (>0 for CW)
-			// a: Number: an x component of a central point
-			// b: Number: a y component of a central point
-
-			// accepts several signatures:
-			//	1) rotation angle in degrees, Point
-			//	2) rotation angle in degrees, x, y
-
+			// summary:
+			//		rotates a picture using a specified point as a center of rotation
+			// description:
+			//		Compare with dojox/gfx/matrix.rotateg().
+			// degree: Number
+			//		an angle of rotation in degrees (>0 for CW)
+			// a: Number|dojox/gfx.Point
+			//		an x component of a central point, or a central point
+			// b: Number?
+			//		a y component of a central point
+			// returns: dojox/gfx/matrix.Matrix2D
 			if(arguments.length > 2){
-				return m._sandwich(m.rotateg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+				return m._sandwich(m.rotateg(degree), a, b); // dojox/gfx/matrix.Matrix2D
 			}
-
-			// branch
-			// degree: Number: an angle of rotation in degrees (>0 for CCW)
-			// a: dojox.gfx.Point: a central point
-			// b: null
-			return m._sandwich(m.rotateg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+			return m._sandwich(m.rotateg(degree), a.x, a.y); // dojox/gfx/matrix.Matrix2D
 		},
 		skewXAt: function(angle, a, b){
-			// summary: skews a picture along the x axis using a specified point as a center of skewing
-			// description: Compare with dojox.gfx.matrix.skewX().
-			// angle: Number: an skewing angle in radians
-			// a: Number: an x component of a central point
-			// b: Number: a y component of a central point
-
-			// accepts several signatures:
-			//	1) skew angle in radians, Point
-			//	2) skew angle in radians, x, y
-
+			// summary:
+			//		skews a picture along the x axis using a specified point as a center of skewing
+			// description:
+			//		Compare with dojox/gfx/matrix.skewX().
+			// angle: Number
+			//		a skewing angle in radians
+			// a: Number|dojox/gfx.Point
+			//		an x component of a central point, or a central point
+			// b: Number?
+			//		a y component of a central point
+			// returns: dojox/gfx/matrix.Matrix2D
 			if(arguments.length > 2){
-				return m._sandwich(m.skewX(angle), a, b); // dojox.gfx.matrix.Matrix2D
+				return m._sandwich(m.skewX(angle), a, b); // dojox/gfx/matrix.Matrix2D
 			}
-
-			// branch
-			// angle: Number: an skewing angle in radians
-			// a: dojox.gfx.Point: a central point
-			// b: null
-			return m._sandwich(m.skewX(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+			return m._sandwich(m.skewX(angle), a.x, a.y); // dojox/gfx/matrix.Matrix2D
 		},
 		skewXgAt: function(degree, a, b){
-			// summary: skews a picture along the x axis using a specified point as a center of skewing
-			// description: Compare with dojox.gfx.matrix.skewXg().
-			// degree: Number: an skewing angle in degrees
-			// a: Number: an x component of a central point
-			// b: Number: a y component of a central point
-
-			// accepts several signatures:
-			//	1) skew angle in degrees, Point
-			//	2) skew angle in degrees, x, y
-
+			// summary:
+			//		skews a picture along the x axis using a specified point as a center of skewing
+			// description:
+			//		Compare with dojox/gfx/matrix.skewXg().
+			// degree: Number
+			//		a skewing angle in degrees
+			// a: Number|dojox/gfx.Point
+			//		an x component of a central point, or a central point
+			// b: Number?
+			//		a y component of a central point
+			// returns: dojox/gfx/matrix.Matrix2D
 			if(arguments.length > 2){
-				return m._sandwich(m.skewXg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+				return m._sandwich(m.skewXg(degree), a, b); // dojox/gfx/matrix.Matrix2D
 			}
-
-			// branch
-			// degree: Number: an skewing angle in degrees
-			// a: dojox.gfx.Point: a central point
-			// b: null
-			return m._sandwich(m.skewXg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+			return m._sandwich(m.skewXg(degree), a.x, a.y); // dojox/gfx/matrix.Matrix2D
 		},
 		skewYAt: function(angle, a, b){
-			// summary: skews a picture along the y axis using a specified point as a center of skewing
-			// description: Compare with dojox.gfx.matrix.skewY().
-			// angle: Number: an skewing angle in radians
-			// a: Number: an x component of a central point
-			// b: Number: a y component of a central point
-
-			// accepts several signatures:
-			//	1) skew angle in radians, Point
-			//	2) skew angle in radians, x, y
-
+			// summary:
+			//		skews a picture along the y axis using a specified point as a center of skewing
+			// description:
+			//		Compare with dojox/gfx/matrix.skewY().
+			// angle: Number
+			//		a skewing angle in radians
+			// a: Number|dojox/gfx.Point
+			//		an x component of a central point, or a central point
+			// b: Number?
+			//		a y component of a central point
+			// returns: dojox/gfx/matrix.Matrix2D
 			if(arguments.length > 2){
-				return m._sandwich(m.skewY(angle), a, b); // dojox.gfx.matrix.Matrix2D
+				return m._sandwich(m.skewY(angle), a, b); // dojox/gfx/matrix.Matrix2D
 			}
-
-			// branch
-			// angle: Number: an skewing angle in radians
-			// a: dojox.gfx.Point: a central point
-			// b: null
-			return m._sandwich(m.skewY(angle), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+			return m._sandwich(m.skewY(angle), a.x, a.y); // dojox/gfx/matrix.Matrix2D
 		},
 		skewYgAt: function(/* Number */ degree, /* Number||Point */ a, /* Number? */ b){
-			// summary: skews a picture along the y axis using a specified point as a center of skewing
-			// description: Compare with dojox.gfx.matrix.skewYg().
-			// degree: Number: an skewing angle in degrees
-			// a: Number: an x component of a central point
-			// b: Number?: a y component of a central point
-
-			// accepts several signatures:
-			//	1) skew angle in degrees, Point
-			//	2) skew angle in degrees, x, y
-
+			// summary:
+			//		skews a picture along the y axis using a specified point as a center of skewing
+			// description:
+			//		Compare with dojox/gfx/matrix.skewYg().
+			// degree: Number
+			//		a skewing angle in degrees
+			// a: Number|dojox/gfx.Point
+			//		an x component of a central point, or a central point
+			// b: Number?
+			//		a y component of a central point
+			// returns: dojox/gfx/matrix.Matrix2D
 			if(arguments.length > 2){
-				return m._sandwich(m.skewYg(degree), a, b); // dojox.gfx.matrix.Matrix2D
+				return m._sandwich(m.skewYg(degree), a, b); // dojox/gfx/matrix.Matrix2D
 			}
-
-			// branch
-			// degree: Number: an skewing angle in degrees
-			// a: dojox.gfx.Point: a central point
-			// b: null
-			return m._sandwich(m.skewYg(degree), a.x, a.y); // dojox.gfx.matrix.Matrix2D
+			return m._sandwich(m.skewYg(degree), a.x, a.y); // dojox/gfx/matrix.Matrix2D
 		}
 
 		//TODO: rect-to-rect mapping, scale-to-fit (isotropic and anisotropic versions)
diff --git a/dojox/gfx/path.js b/dojox/gfx/path.js
index 349338d..44f38d6 100644
--- a/dojox/gfx/path.js
+++ b/dojox/gfx/path.js
@@ -1,21 +1,16 @@
-define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"], 
-  function(g, lang, declare, matrix, shapeLib){
-/*===== 
-	dojox.gfx.path = {
-		// summary:
-		//		This module contains the core graphics Path API.
-		//		Path command format follows the W3C SVG 1.0 Path api.
-	};
-	g = dojox.gfx;
-	shape.Shape = dojox.gfx.shape.Shape;
-  =====*/
+define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"],
+	function(g, lang, declare, matrix, shapeLib){
+
+	// module:
+	//		dojox/gfx/path
 
-	var path = g.path = {};
 	var Path = declare("dojox.gfx.path.Path", shapeLib.Shape, {
-		// summary: a generalized path shape
+		// summary:
+		//		a generalized path shape
 
 		constructor: function(rawNode){
-			// summary: a path constructor
+			// summary:
+			//		a path constructor
 			// rawNode: Node
 			//		a DOM node to be used by this path object
 			this.shape = lang.clone(g.defaultPath);
@@ -29,7 +24,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 
 		// mode manipulations
 		setAbsoluteMode: function(mode){
-			// summary: sets an absolute or relative mode for path points
+			// summary:
+			//		sets an absolute or relative mode for path points
 			// mode: Boolean
 			//		true/false or "absolute"/"relative" to specify the mode
 			this._confirmSegmented();
@@ -37,20 +33,23 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			return this; // self
 		},
 		getAbsoluteMode: function(){
-			// summary: returns a current value of the absolute mode
+			// summary:
+			//		returns a current value of the absolute mode
 			this._confirmSegmented();
 			return this.absolute; // Boolean
 		},
 
 		getBoundingBox: function(){
-			// summary: returns the bounding box {x, y, width, height} or null
+			// summary:
+			//		returns the bounding box {x, y, width, height} or null
 			this._confirmSegmented();
-			return (this.bbox && ("l" in this.bbox)) ? {x: this.bbox.l, y: this.bbox.t, width: this.bbox.r - this.bbox.l, height: this.bbox.b - this.bbox.t} : null; // dojox.gfx.Rectangle
+			return (this.bbox && ("l" in this.bbox)) ? {x: this.bbox.l, y: this.bbox.t, width: this.bbox.r - this.bbox.l, height: this.bbox.b - this.bbox.t} : null; // dojox/gfx.Rectangle
 		},
 
 		_getRealBBox: function(){
-			// summary: returns an array of four points or null
-			//	four points represent four corners of the untransformed bounding box
+			// summary:
+			//		returns an array of four points or null
+			//		four points represent four corners of the untransformed bounding box
 			this._confirmSegmented();
 			if(this.tbbox){
 				return this.tbbox;	// Array
@@ -72,7 +71,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 		},
 
 		getLastPosition: function(){
-			// summary: returns the last point in the path, or null
+			// summary:
+			//		returns the last point in the path, or null
 			this._confirmSegmented();
 			return "x" in this.last ? this.last : null; // Object
 		},
@@ -84,7 +84,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 
 		// segment interpretation
 		_updateBBox: function(x, y, m){
-			// summary: updates the bounding box of path with new point
+			// summary:
+			//		updates the bounding box of path with new point
 			// x: Number
 			//		an x coordinate
 			// y: Number
@@ -107,7 +108,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			}
 		},
 		_updateWithSegment: function(segment, matrix){
-			// summary: updates the bounding box of path with new segment
+			// summary:
+			//		updates the bounding box of path with new segment
 			// segment: Object
 			//		a segment
 			var n = segment.args, l = n.length, i;
@@ -217,7 +219,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 		_validSegments: {m: 2, l: 2, h: 1, v: 1, c: 6, s: 4, q: 4, t: 2, a: 7, z: 0},
 
 		_pushSegment: function(action, args){
-			// summary: adds a segment
+			// summary:
+			//		adds a segment
 			// action: String
 			//		valid SVG code for a segment's type
 			// args: Array
@@ -240,11 +243,12 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 		},
 
 		_collectArgs: function(array, args){
-			// summary: converts an array of arguments to plain numeric values
+			// summary:
+			//		converts an array of arguments to plain numeric values
 			// array: Array
 			//		an output argument (array of numbers)
 			// args: Array
-			//		an input argument (can be values of Boolean, Number, dojox.gfx.Point, or an embedded array of them)
+			//		an input argument (can be values of Boolean, Number, dojox/gfx.Point, or an embedded array of them)
 			for(var i = 0; i < args.length; ++i){
 				var t = args[i];
 				if(typeof t == "boolean"){
@@ -261,7 +265,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 
 		// segments
 		moveTo: function(){
-			// summary: forms a move segment
+			// summary:
+			//		forms a move segment
 			this._confirmSegmented();
 			var args = [];
 			this._collectArgs(args, arguments);
@@ -269,7 +274,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			return this; // self
 		},
 		lineTo: function(){
-			// summary: forms a line segment
+			// summary:
+			//		forms a line segment
 			this._confirmSegmented();
 			var args = [];
 			this._collectArgs(args, arguments);
@@ -277,7 +283,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			return this; // self
 		},
 		hLineTo: function(){
-			// summary: forms a horizontal line segment
+			// summary:
+			//		forms a horizontal line segment
 			this._confirmSegmented();
 			var args = [];
 			this._collectArgs(args, arguments);
@@ -285,7 +292,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			return this; // self
 		},
 		vLineTo: function(){
-			// summary: forms a vertical line segment
+			// summary:
+			//		forms a vertical line segment
 			this._confirmSegmented();
 			var args = [];
 			this._collectArgs(args, arguments);
@@ -293,7 +301,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			return this; // self
 		},
 		curveTo: function(){
-			// summary: forms a curve segment
+			// summary:
+			//		forms a curve segment
 			this._confirmSegmented();
 			var args = [];
 			this._collectArgs(args, arguments);
@@ -301,7 +310,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			return this; // self
 		},
 		smoothCurveTo: function(){
-			// summary: forms a smooth curve segment
+			// summary:
+			//		forms a smooth curve segment
 			this._confirmSegmented();
 			var args = [];
 			this._collectArgs(args, arguments);
@@ -309,7 +319,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			return this; // self
 		},
 		qCurveTo: function(){
-			// summary: forms a quadratic curve segment
+			// summary:
+			//		forms a quadratic curve segment
 			this._confirmSegmented();
 			var args = [];
 			this._collectArgs(args, arguments);
@@ -317,7 +328,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			return this; // self
 		},
 		qSmoothCurveTo: function(){
-			// summary: forms a quadratic smooth curve segment
+			// summary:
+			//		forms a quadratic smooth curve segment
 			this._confirmSegmented();
 			var args = [];
 			this._collectArgs(args, arguments);
@@ -325,7 +337,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			return this; // self
 		},
 		arcTo: function(){
-			// summary: forms an elliptic arc segment
+			// summary:
+			//		forms an elliptic arc segment
 			this._confirmSegmented();
 			var args = [];
 			this._collectArgs(args, arguments);
@@ -333,7 +346,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			return this; // self
 		},
 		closePath: function(){
-			// summary: closes a path
+			// summary:
+			//		closes a path
 			this._confirmSegmented();
 			this._pushSegment("Z", []);
 			return this; // self
@@ -354,7 +368,8 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 
 		// setShape
 		_setPath: function(path){
-			// summary: forms a path using an SVG path string
+			// summary:
+			//		forms a path using an SVG path string
 			// path: String
 			//		an SVG path string
 			var p = lang.isArray(path) ? path : path.match(g.pathSvgRegExp);
@@ -382,9 +397,10 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			this._pushSegment(action, args);
 		},
 		setShape: function(newShape){
-			// summary: forms a path using a shape
+			// summary:
+			//		forms a path using a shape
 			// newShape: Object
-			//		an SVG path string or a path object (see dojox.gfx.defaultPath)
+			//		an SVG path string or a path object (see dojox/gfx.defaultPath)
 			this.inherited(arguments, [typeof newShape == "string" ? {path: newShape} : newShape]);
 
 			this.segmented = false;
@@ -400,10 +416,12 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 	});
 
 	var TextPath = declare("dojox.gfx.path.TextPath", Path, {
-		// summary: a generalized TextPath shape
+		// summary:
+		//		a generalized TextPath shape
 
 		constructor: function(rawNode){
-			// summary: a TextPath shape constructor
+			// summary:
+			//		a TextPath shape constructor
 			// rawNode: Node
 			//		a DOM node to be used by this TextPath object
 			if(!("text" in this)){
@@ -414,22 +432,26 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 			}
 		},
 		getText: function(){
-			// summary: returns the current text object or null
+			// summary:
+			//		returns the current text object or null
 			return this.text;	// Object
 		},
 		setText: function(newText){
-			// summary: sets a text to be drawn along the path
+			// summary:
+			//		sets a text to be drawn along the path
 			this.text = g.makeParameters(this.text,
 				typeof newText == "string" ? {text: newText} : newText);
 			this._setText();
 			return this;	// self
 		},
 		getFont: function(){
-			// summary: returns the current font object or null
+			// summary:
+			//		returns the current font object or null
 			return this.fontStyle;	// Object
 		},
 		setFont: function(newFont){
-			// summary: sets a font for text
+			// summary:
+			//		sets a font for text
 			this.fontStyle = typeof newFont == "string" ?
 				g.splitFontString(newFont) :
 				g.makeParameters(g.defaultFont, newFont);
@@ -438,7 +460,16 @@ define(["./_base", "dojo/_base/lang","dojo/_base/declare", "./matrix", "./shape"
 		}
 	});
 
-	return { // our hash of newly defined objects
+	/*=====
+	g.Path = Path;
+	g.TextPath = TextPath;
+	=====*/
+
+	return g.path = {
+		// summary:
+		//		This module contains the core graphics Path API.
+		//		Path command format follows the W3C SVG 1.0 Path api.
+
 		Path: Path,
 		TextPath: TextPath
 	};
diff --git a/dojox/gfx/registry.js b/dojox/gfx/registry.js
new file mode 100644
index 0000000..f1eca2f
--- /dev/null
+++ b/dojox/gfx/registry.js
@@ -0,0 +1,53 @@
+define(["dojo/has","./shape"], function(has, shapeLib){
+
+	has.add("gfxRegistry", 1);
+
+	var registry = {};
+
+	// a set of ids (keys=type)
+	var _ids = {};
+	// a simple set impl to map shape<->id
+	var hash = {};
+
+	registry.register = shapeLib.register = function(/*dojox/gfx/shape.Shape*/s){
+		// summary:
+		//		Register the specified shape into the graphics registry.
+		// s: dojox/gfx/shape.Shape
+		//		The shape to register.
+		// returns: Number
+		//		The unique id associated with this shape.
+
+		// the id pattern : type+number (ex: Rect0,Rect1,etc)
+		var t = s.declaredClass.split('.').pop();
+		var i = t in _ids ? ++_ids[t] : ((_ids[t] = 0));
+		var uid = t+i;
+		hash[uid] = s;
+		return uid;
+	};
+
+	registry.byId = shapeLib.byId = function(/*String*/id){
+		// summary:
+		//		Returns the shape that matches the specified id.
+		// id: String
+		//		The unique identifier for this Shape.
+		// returns: dojox/gfx/shape.Shape
+		return hash[id]; //dojox/gfx/shape.Shape
+	};
+
+	registry.dispose = shapeLib.dispose = function(/*dojox/gfx/shape.Shape*/s, /*Boolean?*/recurse){
+		// summary:
+		//		Removes the specified shape from the registry.
+		// s: dojox/gfx/shape.Shape
+		//		The shape to unregister.
+		if(recurse && s.children){
+			for(var i=0; i< s.children.length; ++i){
+				registry.dispose(s.children[i], true);
+			}
+		}
+		var uid = s.getUID();
+		hash[uid] = null;
+		delete hash[uid];
+	};
+
+	return registry;
+});
diff --git a/dojox/gfx/renderer.js b/dojox/gfx/renderer.js
index a50c4d5..6a833a7 100644
--- a/dojox/gfx/renderer.js
+++ b/dojox/gfx/renderer.js
@@ -1,16 +1,23 @@
 define(["./_base","dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/window", "dojo/_base/config"],
   function(g, lang, has, win, config){
   //>> noBuildResolver
-/*=====
-	dojox.gfx.renderer = {
+	var currentRenderer = null;
+
+	has.add("vml", function(global, document, element){
+		element.innerHTML = "<v:shape adj=\"1\"/>";
+		var supported = ("adj" in element.firstChild);
+		element.innerHTML = "";
+		return supported;
+	});
+
+	return {
 		// summary:
 		//		This module is an AMD loader plugin that loads the appropriate graphics renderer
 		//		implementation based on detected environment and current configuration settings.
-	};
-  =====*/
-	var currentRenderer = null;
-	return {
+		
 		load: function(id, require, load){
+			// tags:
+			//      private
 			if(currentRenderer && id != "force"){
 				load(currentRenderer);
 				return;
@@ -29,7 +36,7 @@ define(["./_base","dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/window", "d
 						}
 						break;
 					case "vml":
-						if(has("ie")){
+						if(has("vml")){
 							renderer = "vml";
 						}
 						break;
diff --git a/dojox/gfx/resources/gfxSvgProxyFrame.html b/dojox/gfx/resources/gfxSvgProxyFrame.html
index cfc7e26..dcef3da 100644
--- a/dojox/gfx/resources/gfxSvgProxyFrame.html
+++ b/dojox/gfx/resources/gfxSvgProxyFrame.html
@@ -1,7 +1,7 @@
 <html>
     <head>
         <script type="text/javascript">
-    		djConfig = {forceGfxRenderer: "svg"};
+    		var dojoConfig = {forceGfxRenderer: "svg"};
     	</script>
         <script type="text/javascript" src="../../../dojo/dojo.js" ></script>
         <script type="text/javascript">
diff --git a/dojox/gfx/shape.js b/dojox/gfx/shape.js
index 36f95a8..50ea9b3 100644
--- a/dojox/gfx/shape.js
+++ b/dojox/gfx/shape.js
@@ -1,168 +1,155 @@
-define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window", "dojo/_base/sniff",
-	"dojo/_base/connect", "dojo/_base/array", "dojo/dom-construct", "dojo/_base/Color", "./matrix"], 
-  function(g, lang, declare, win, has, events, arr, domConstruct, Color, matrixLib){
+define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/kernel", "dojo/_base/sniff",
+	"dojo/on", "dojo/_base/array", "dojo/dom-construct", "dojo/_base/Color", "./matrix" ],
+	function(g, lang, declare, kernel, has, on, arr, domConstruct, Color, matrixLib){
 
-/*===== 
-	dojox.gfx.shape = {
+	var shape = g.shape = {
 		// summary:
 		//		This module contains the core graphics Shape API.
-		//		Different graphics renderer implementation modules (svg, canvas, vml, silverlight, etc.) extend this 
+		//		Different graphics renderer implementation modules (svg, canvas, vml, silverlight, etc.) extend this
 		//		basic api to provide renderer-specific implementations for each shape.
 	};
-  =====*/
 
-	var shape = g.shape = {};
-	// a set of ids (keys=type)
-	var _ids = {};
-	// a simple set impl to map shape<->id
-	var registry = {};
-	
-	shape.register = function(/*dojox.gfx.shape.Shape*/shape){
-		// summary: 
-		//		Register the specified shape into the graphics registry.
-		// shape: dojox.gfx.shape.Shape
-		//		The shape to register.
-		// returns:
-		//		The unique id associated with this shape.
-		// the id pattern : type+number (ex: Rect0,Rect1,etc)
-		var t = shape.declaredClass.split('.').pop();
-		var i = t in _ids ? ++_ids[t] : ((_ids[t] = 0));
-		var uid = t+i;
-		registry[uid] = shape;
-		return uid;
-	};
-	
-	shape.byId = function(/*String*/id){
-		// summary: 
-		//		Returns the shape that matches the specified id.
-		// id: String
-		//		The unique identifier for this Shape.
-		return registry[id]; //dojox.gfx.shape.Shape
-	};
-	
-	shape.dispose = function(/*dojox.gfx.shape.Shape*/shape){
-		// summary: 
-		//		Removes the specified shape from the registry.
-		// shape: dojox.gfx.shape.Shape
-		//		The shape to unregister.
-		delete registry[shape.getUID()];
-	};
-	
-	declare("dojox.gfx.shape.Shape", null, {
-		// summary: a Shape object, which knows how to apply
-		// graphical attributes and transformations
+	shape.Shape = declare("dojox.gfx.shape.Shape", null, {
+		// summary:
+		//		a Shape object, which knows how to apply
+		//		graphical attributes and transformations
 	
 		constructor: function(){
-			//	rawNode: Node
+			// rawNode: Node
 			//		underlying graphics-renderer-specific implementation object (if applicable)
 			this.rawNode = null;
-			//	shape: Object: an abstract shape object
-			//	(see dojox.gfx.defaultPath,
-			//	dojox.gfx.defaultPolyline,
-			//	dojox.gfx.defaultRect,
-			//	dojox.gfx.defaultEllipse,
-			//	dojox.gfx.defaultCircle,
-			//	dojox.gfx.defaultLine,
-			//	or dojox.gfx.defaultImage)
+
+			// shape: Object
+			//		an abstract shape object
+			//		(see dojox/gfx.defaultPath,
+			//		dojox/gfx.defaultPolyline,
+			//		dojox/gfx.defaultRect,
+			//		dojox/gfx.defaultEllipse,
+			//		dojox/gfx.defaultCircle,
+			//		dojox/gfx.defaultLine,
+			//		or dojox/gfx.defaultImage)
 			this.shape = null;
 	
-			//	matrix: dojox.gfx.Matrix2D
+			// matrix: dojox/gfx/matrix.Matrix2D
 			//		a transformation matrix
 			this.matrix = null;
 	
-			//	fillStyle: Object
+			// fillStyle: dojox/gfx.Fill
 			//		a fill object
-			//		(see dojox.gfx.defaultLinearGradient,
-			//		dojox.gfx.defaultRadialGradient,
-			//		dojox.gfx.defaultPattern,
-			//		or dojo.Color)
+			//		(see dojox/gfx.defaultLinearGradient,
+			//		dojox/gfx.defaultRadialGradient,
+			//		dojox/gfx.defaultPattern,
+			//		or dojo/Color)
 			this.fillStyle = null;
 	
-			//	strokeStyle: Object
+			// strokeStyle: dojox/gfx.Stroke
 			//		a stroke object
-			//		(see dojox.gfx.defaultStroke)
+			//		(see dojox/gfx.defaultStroke)
 			this.strokeStyle = null;
 	
-			// bbox: dojox.gfx.Rectangle
+			// bbox: dojox/gfx.Rectangle
 			//		a bounding box of this shape
-			//		(see dojox.gfx.defaultRect)
+			//		(see dojox/gfx.defaultRect)
 			this.bbox = null;
 	
 			// virtual group structure
 	
 			// parent: Object
 			//		a parent or null
-			//		(see dojox.gfx.Surface,
-			//		dojox.gfx.shape.VirtualGroup,
-			//		or dojox.gfx.Group)
+			//		(see dojox/gfx/shape.Surface,
+			//		or dojox/gfx.Group)
 			this.parent = null;
 	
-			// parentMatrix: dojox.gfx.Matrix2D
-			//	a transformation matrix inherited from the parent
+			// parentMatrix: dojox/gfx/matrix.Matrix2D
+			//		a transformation matrix inherited from the parent
 			this.parentMatrix = null;
-			
-			var uid = shape.register(this);
-			this.getUID = function(){
-				return uid;
+
+			if(has("gfxRegistry")){
+				var uid = shape.register(this);
+				this.getUID = function(){
+					return uid;
+				}
+			}
+		},
+		
+		destroy: function(){
+			// summary:
+			//		Releases all internal resources owned by this shape. Once this method has been called,
+			//		the instance is considered destroyed and should not be used anymore.
+			if(has("gfxRegistry")){
+				shape.dispose(this);
+			}
+			if(this.rawNode && "__gfxObject__" in this.rawNode){
+				this.rawNode.__gfxObject__ = null;
 			}
-		},	
+			this.rawNode = null;
+		},
 	
 		// trivial getters
 	
 		getNode: function(){
-			// summary: Different graphics rendering subsystems implement shapes in different ways.  This
-			//	method provides access to the underlying graphics subsystem object.  Clients calling this
-			//	method and using the return value must be careful not to try sharing or using the underlying node
-			//	in a general way across renderer implementation.
-			//	Returns the underlying graphics Node, or null if no underlying graphics node is used by this shape.
+			// summary:
+			//		Different graphics rendering subsystems implement shapes in different ways.  This
+			//		method provides access to the underlying graphics subsystem object.  Clients calling this
+			//		method and using the return value must be careful not to try sharing or using the underlying node
+			//		in a general way across renderer implementation.
+			//		Returns the underlying graphics Node, or null if no underlying graphics node is used by this shape.
 			return this.rawNode; // Node
 		},
 		getShape: function(){
-			// summary: returns the current Shape object or null
-			//	(see dojox.gfx.defaultPath,
-			//	dojox.gfx.defaultPolyline,
-			//	dojox.gfx.defaultRect,
-			//	dojox.gfx.defaultEllipse,
-			//	dojox.gfx.defaultCircle,
-			//	dojox.gfx.defaultLine,
-			//	or dojox.gfx.defaultImage)
+			// summary:
+			//		returns the current Shape object or null
+			//		(see dojox/gfx.defaultPath,
+			//		dojox/gfx.defaultPolyline,
+			//		dojox/gfx.defaultRect,
+			//		dojox/gfx.defaultEllipse,
+			//		dojox/gfx.defaultCircle,
+			//		dojox/gfx.defaultLine,
+			//		or dojox/gfx.defaultImage)
 			return this.shape; // Object
 		},
 		getTransform: function(){
-			// summary: Returns the current transformation matrix applied to this Shape or null
-			return this.matrix;	// dojox.gfx.Matrix2D
+			// summary:
+			//		Returns the current transformation matrix applied to this Shape or null
+			return this.matrix;	// dojox/gfx/matrix.Matrix2D
 		},
 		getFill: function(){
-			// summary: Returns the current fill object or null
-			//	(see dojox.gfx.defaultLinearGradient,
-			//	dojox.gfx.defaultRadialGradient,
-			//	dojox.gfx.defaultPattern,
-			//	or dojo.Color)
+			// summary:
+			//		Returns the current fill object or null
+			//		(see dojox/gfx.defaultLinearGradient,
+			//		dojox/gfx.defaultRadialGradient,
+			//		dojox/gfx.defaultPattern,
+			//		or dojo/Color)
 			return this.fillStyle;	// Object
 		},
 		getStroke: function(){
-			// summary: Returns the current stroke object or null
-			//	(see dojox.gfx.defaultStroke)
+			// summary:
+			//		Returns the current stroke object or null
+			//		(see dojox/gfx.defaultStroke)
 			return this.strokeStyle;	// Object
 		},
 		getParent: function(){
-			// summary: Returns the parent Shape, Group or VirtualGroup or null if this Shape is unparented.
-			//	(see dojox.gfx.Surface,
-			//	dojox.gfx.shape.VirtualGroup,
-			//	or dojox.gfx.Group)
+			// summary:
+			//		Returns the parent Shape, Group or null if this Shape is unparented.
+			//		(see dojox/gfx/shape.Surface,
+			//		or dojox/gfx.Group)
 			return this.parent;	// Object
 		},
 		getBoundingBox: function(){
-			// summary: Returns the bounding box Rectanagle for this shape or null if a BoundingBox cannot be
-			//	calculated for the shape on the current renderer or for shapes with no geometric area (points).
-			//	A bounding box is a rectangular geometric region
-			//	defining the X and Y extent of the shape.
-			//	(see dojox.gfx.defaultRect)
-			return this.bbox;	// dojox.gfx.Rectangle
+			// summary:
+			//		Returns the bounding box Rectangle for this shape or null if a BoundingBox cannot be
+			//		calculated for the shape on the current renderer or for shapes with no geometric area (points).
+			//		A bounding box is a rectangular geometric region
+			//		defining the X and Y extent of the shape.
+			//		(see dojox/gfx.defaultRect)
+			//		Note that this method returns a direct reference to the attribute of this instance. Therefore you should
+			//		not modify its value directly but clone it instead.
+			return this.bbox;	// dojox/gfx.Rectangle
 		},
 		getTransformedBoundingBox: function(){
-			// summary: returns an array of four points or null
-			//	four points represent four corners of the untransformed bounding box
+			// summary:
+			//		returns an array of four points or null
+			//		four points represent four corners of the untransformed bounding box
 			var b = this.getBoundingBox();
 			if(!b){
 				return null;	// null
@@ -177,40 +164,85 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 				];
 		},
 		getEventSource: function(){
-			// summary: returns a Node, which is used as
-			//	a source of events for this shape
+			// summary:
+			//		returns a Node, which is used as
+			//		a source of events for this shape
+			
 			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
 			return this.rawNode;	// Node
 		},
 	
 		// empty settings
+		
+		setClip: function(clip){
+			// summary:
+			//		sets the clipping area of this shape.
+			// description:
+			//		The clipping area defines the shape area that will be effectively visible. Everything that
+			//		would be drawn outside of the clipping area will not be rendered.
+			//		The possible clipping area types are rectangle, ellipse, polyline and path, but all are not
+			//		supported by all the renderers. vml only supports rectangle clipping, while the gfx silverlight renderer does not
+			//		support path clipping.
+			//		The clip parameter defines the clipping area geometry, and should be an object with the following properties:
+			//
+			//		- {x:Number, y:Number, width:Number, height:Number} for rectangular clip
+			//		- {cx:Number, cy:Number, rx:Number, ry:Number} for ellipse clip
+			//		- {points:Array} for polyline clip
+			//		- {d:String} for a path clip.
+			//
+			//		The clip geometry coordinates are expressed in the coordinate system used to draw the shape. In other
+			//		words, the clipping area is defined in the shape parent coordinate system and the shape transform is automatically applied.
+			// example:
+			//		The following example shows how to clip a gfx image with all the possible clip geometry: a rectangle,
+			//		an ellipse, a circle (using the ellipse geometry), a polyline and a path:
+			//
+			//	|	surface.createImage({src:img, width:200,height:200}).setClip({x:10,y:10,width:50,height:50});
+			//	|	surface.createImage({src:img, x:100,y:50,width:200,height:200}).setClip({cx:200,cy:100,rx:20,ry:30});
+			//	|	surface.createImage({src:img, x:0,y:350,width:200,height:200}).setClip({cx:100,cy:425,rx:60,ry:60});
+			//	|	surface.createImage({src:img, x:300,y:0,width:200,height:200}).setClip({points:[350,0,450,50,380,130,300,110]});
+			//	|	surface.createImage({src:img, x:300,y:350,width:200,height:200}).setClip({d:"M 350,350 C314,414 317,557 373,450.0000 z"});
+
+			// clip: Object
+			//		an object that defines the clipping geometry, or null to remove clip.
+			
+			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
+			this.clip = clip;
+		},
+		
+		getClip: function(){
+			return this.clip;
+		},
 	
 		setShape: function(shape){
-			// summary: sets a shape object
-			//	(the default implementation simply ignores it)
+			// summary:
+			//		sets a shape object
+			//		(the default implementation simply ignores it)
 			// shape: Object
-			//	a shape object
-			//	(see dojox.gfx.defaultPath,
-			//	dojox.gfx.defaultPolyline,
-			//	dojox.gfx.defaultRect,
-			//	dojox.gfx.defaultEllipse,
-			//	dojox.gfx.defaultCircle,
-			//	dojox.gfx.defaultLine,
-			//	or dojox.gfx.defaultImage)
+			//		a shape object
+			//		(see dojox/gfx.defaultPath,
+			//		dojox/gfx.defaultPolyline,
+			//		dojox/gfx.defaultRect,
+			//		dojox/gfx.defaultEllipse,
+			//		dojox/gfx.defaultCircle,
+			//		dojox/gfx.defaultLine,
+			//		or dojox/gfx.defaultImage)
+			
 			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
 			this.shape = g.makeParameters(this.shape, shape);
 			this.bbox = null;
 			return this;	// self
 		},
 		setFill: function(fill){
-			// summary: sets a fill object
-			//	(the default implementation simply ignores it)
+			// summary:
+			//		sets a fill object
+			//		(the default implementation simply ignores it)
 			// fill: Object
-			//	a fill object
-			//	(see dojox.gfx.defaultLinearGradient,
-			//	dojox.gfx.defaultRadialGradient,
-			//	dojox.gfx.defaultPattern,
-			//	or dojo.Color)
+			//		a fill object
+			//		(see dojox/gfx.defaultLinearGradient,
+			//		dojox/gfx.defaultRadialGradient,
+			//		dojox/gfx.defaultPattern,
+			//		or dojo/_base/Color)
+			
 			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
 			if(!fill){
 				// don't fill
@@ -239,11 +271,13 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			return this;	// self
 		},
 		setStroke: function(stroke){
-			// summary: sets a stroke object
-			//	(the default implementation simply ignores it)
+			// summary:
+			//		sets a stroke object
+			//		(the default implementation simply ignores it)
 			// stroke: Object
-			//	a stroke object
-			//	(see dojox.gfx.defaultStroke)
+			//		a stroke object
+			//		(see dojox/gfx.defaultStroke)
+			
 			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
 			if(!stroke){
 				// don't stroke
@@ -259,18 +293,22 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			return this;	// self
 		},
 		setTransform: function(matrix){
-			// summary: sets a transformation matrix
-			// matrix: dojox.gfx.Matrix2D
-			//	a matrix or a matrix-like object
-			//	(see an argument of dojox.gfx.Matrix2D
-			//	constructor for a list of acceptable arguments)
+			// summary:
+			//		sets a transformation matrix
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a matrix or a matrix-like object
+			//		(see an argument of dojox/gfx/matrix.Matrix2D
+			//		constructor for a list of acceptable arguments)
+			
 			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
 			this.matrix = matrixLib.clone(matrix ? matrixLib.normalize(matrix) : matrixLib.identity);
 			return this._applyTransform();	// self
 		},
 	
 		_applyTransform: function(){
-			// summary: physically sets a matrix
+			// summary:
+			//		physically sets a matrix
+			
 			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
 			return this;	// self
 		},
@@ -278,7 +316,8 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 		// z-index
 	
 		moveToFront: function(){
-			// summary: moves a shape to front of its parent's list of shapes
+			// summary:
+			//		moves a shape to front of its parent's list of shapes
 			var p = this.getParent();
 			if(p){
 				p._moveChildToFront(this);
@@ -287,7 +326,8 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			return this;	// self
 		},
 		moveToBack: function(){
-			// summary: moves a shape to back of its parent's list of shapes
+			// summary:
+			//		moves a shape to back of its parent's list of shapes
 			var p = this.getParent();
 			if(p){
 				p._moveChildToBack(this);
@@ -296,76 +336,86 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			return this;
 		},
 		_moveToFront: function(){
-			// summary: renderer-specific hook, see dojox.gfx.shape.Shape.moveToFront()
+			// summary:
+			//		renderer-specific hook, see dojox/gfx/shape.Shape.moveToFront()
+			
 			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
 		},
 		_moveToBack: function(){
-			// summary: renderer-specific hook, see dojox.gfx.shape.Shape.moveToFront()
+			// summary:
+			//		renderer-specific hook, see dojox/gfx/shape.Shape.moveToFront()
+			
 			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
 		},
 	
 		// apply left & right transformation
 	
 		applyRightTransform: function(matrix){
-			// summary: multiplies the existing matrix with an argument on right side
-			//	(this.matrix * matrix)
-			// matrix: dojox.gfx.Matrix2D
-			//	a matrix or a matrix-like object
-			//	(see an argument of dojox.gfx.Matrix2D
-			//	constructor for a list of acceptable arguments)
+			// summary:
+			//		multiplies the existing matrix with an argument on right side
+			//		(this.matrix * matrix)
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a matrix or a matrix-like object
+			//		(see an argument of dojox/gfx/matrix.Matrix2D
+			//		constructor for a list of acceptable arguments)
 			return matrix ? this.setTransform([this.matrix, matrix]) : this;	// self
 		},
 		applyLeftTransform: function(matrix){
-			// summary: multiplies the existing matrix with an argument on left side
-			//	(matrix * this.matrix)
-			// matrix: dojox.gfx.Matrix2D
-			//	a matrix or a matrix-like object
-			//	(see an argument of dojox.gfx.Matrix2D
-			//	constructor for a list of acceptable arguments)
+			// summary:
+			//		multiplies the existing matrix with an argument on left side
+			//		(matrix * this.matrix)
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a matrix or a matrix-like object
+			//		(see an argument of dojox/gfx/matrix.Matrix2D
+			//		constructor for a list of acceptable arguments)
 			return matrix ? this.setTransform([matrix, this.matrix]) : this;	// self
 		},
 		applyTransform: function(matrix){
-			// summary: a shortcut for dojox.gfx.Shape.applyRightTransform
-			// matrix: dojox.gfx.Matrix2D
-			//	a matrix or a matrix-like object
-			//	(see an argument of dojox.gfx.Matrix2D
-			//	constructor for a list of acceptable arguments)
+			// summary:
+			//		a shortcut for dojox/gfx/shape.Shape.applyRightTransform
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a matrix or a matrix-like object
+			//		(see an argument of dojox/gfx/matrix.Matrix2D
+			//		constructor for a list of acceptable arguments)
 			return matrix ? this.setTransform([this.matrix, matrix]) : this;	// self
 		},
 	
 		// virtual group methods
 	
 		removeShape: function(silently){
-			// summary: removes the shape from its parent's list of shapes
+			// summary:
+			//		removes the shape from its parent's list of shapes
 			// silently: Boolean
-			// 		if true, do not redraw a picture yet
+			//		if true, do not redraw a picture yet
 			if(this.parent){
 				this.parent.remove(this, silently);
 			}
 			return this;	// self
 		},
 		_setParent: function(parent, matrix){
-			// summary: sets a parent
+			// summary:
+			//		sets a parent
 			// parent: Object
-			//	a parent or null
-			//	(see dojox.gfx.Surface,
-			//	dojox.gfx.shape.VirtualGroup,
-			//	or dojox.gfx.Group)
-			// matrix: dojox.gfx.Matrix2D
-			//	a 2D matrix or a matrix-like object
+			//		a parent or null
+			//		(see dojox/gfx/shape.Surface,
+			//		or dojox/gfx.Group)
+			// matrix: dojox/gfx/matrix.Matrix2D
+			//		a 2D matrix or a matrix-like object
 			this.parent = parent;
 			return this._updateParentMatrix(matrix);	// self
 		},
 		_updateParentMatrix: function(matrix){
-			// summary: updates the parent matrix with new matrix
-			// matrix: dojox.gfx.Matrix2D
-			//	a 2D matrix or a matrix-like object
+			// summary:
+			//		updates the parent matrix with new matrix
+			// matrix: dojox/gfx/Matrix2D
+			//		a 2D matrix or a matrix-like object
 			this.parentMatrix = matrix ? matrixLib.clone(matrix) : null;
 			return this._applyTransform();	// self
 		},
 		_getRealMatrix: function(){
-			// summary: returns the cumulative ('real') transformation matrix
-			//	by combining the shape's matrix with its parent's matrix
+			// summary:
+			//		returns the cumulative ('real') transformation matrix
+			//		by combining the shape's matrix with its parent's matrix
 			var m = this.matrix;
 			var p = this.parent;
 			while(p){
@@ -374,51 +424,67 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 				}
 				p = p.parent;
 			}
-			return m;	// dojox.gfx.Matrix2D
+			return m;	// dojox/gfx/matrix.Matrix2D
 		}
 	});
 	
 	shape._eventsProcessing = {
+		on: function(type, listener){
+			//	summary:
+			//		Connects an event to this shape.
+
+			return on(this.getEventSource(), type, shape.fixCallback(this, g.fixTarget, listener));
+		},
+
 		connect: function(name, object, method){
-			// summary: connects a handler to an event on this shape
+			// summary:
+			//		connects a handler to an event on this shape
+			
 			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
 			// redirect to fixCallback to normalize events and add the gfxTarget to the event. The latter
-			// is done by dojox.gfx.fixTarget which is defined by each renderer
-			return events.connect(this.getEventSource(), name, shape.fixCallback(this, g.fixTarget, object, method));
-			
+			// is done by dojox/gfx.fixTarget which is defined by each renderer
+			if(name.substring(0, 2) == "on"){
+				name = name.substring(2);
+			}
+			return this.on(name, method ? lang.hitch(object, method) : object);
 		},
+
 		disconnect: function(token){
-			// summary: connects a handler by token from an event on this shape
+			// summary:
+			//		connects a handler by token from an event on this shape
+			
 			// COULD BE RE-IMPLEMENTED BY THE RENDERER!
 	
-			events.disconnect(token);
+			return token.remove();
 		}
 	};
 	
 	shape.fixCallback = function(gfxElement, fixFunction, scope, method){
-		//  summary:
-		//      Wraps the callback to allow for tests and event normalization
-		//      before it gets invoked. This is where 'fixTarget' is invoked.
-		//  gfxElement: Object
-		//      The GFX object that triggers the action (ex.: 
-		//      dojox.gfx.Surface and dojox.gfx.Shape). A new event property
-		//      'gfxTarget' is added to the event to reference this object.
-		//      for easy manipulation of GFX objects by the event handlers.
-		//  fixFunction: Function
-		//      The function that implements the logic to set the 'gfxTarget'
-		//      property to the event. It should be 'dojox.gfx.fixTarget' for
-		//      most of the cases
-		//  scope: Object
-		//      Optional. The scope to be used when invoking 'method'. If
-		//      omitted, a global scope is used.
-		//  method: Function|String
-		//      The original callback to be invoked.
+		// summary:
+		//		Wraps the callback to allow for tests and event normalization
+		//		before it gets invoked. This is where 'fixTarget' is invoked.
+		// tags:
+		//      private
+		// gfxElement: Object
+		//		The GFX object that triggers the action (ex.:
+		//		dojox/gfx.Surface and dojox/gfx/shape.Shape). A new event property
+		//		'gfxTarget' is added to the event to reference this object.
+		//		for easy manipulation of GFX objects by the event handlers.
+		// fixFunction: Function
+		//		The function that implements the logic to set the 'gfxTarget'
+		//		property to the event. It should be 'dojox/gfx.fixTarget' for
+		//		most of the cases
+		// scope: Object
+		//		Optional. The scope to be used when invoking 'method'. If
+		//		omitted, a global scope is used.
+		// method: Function|String
+		//		The original callback to be invoked.
 		if(!method){
 			method = scope;
 			scope = null;
 		}
 		if(lang.isString(method)){
-			scope = scope || win.global;
+			scope = scope || kernel.global;
 			if(!scope[method]){ throw(['dojox.gfx.shape.fixCallback: scope["', method, '"] is null (scope="', scope, '")'].join('')); }
 			return function(e){  
 				return fixFunction(e,gfxElement) ? scope[method].apply(scope, arguments || []) : undefined; }; // Function
@@ -432,27 +498,40 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 	lang.extend(shape.Shape, shape._eventsProcessing);
 	
 	shape.Container = {
-		// summary: a container of shapes, which can be used
-		//	as a foundation for renderer-specific groups, or as a way
-		//	to logically group shapes (e.g, to propagate matricies)
+		// summary:
+		//		a container of shapes, which can be used
+		//		as a foundation for renderer-specific groups, or as a way
+		//		to logically group shapes (e.g, to propagate matricies)
 	
 		_init: function() {
-			// children: Array: a list of children
+			// children: Array
+			//		a list of children
 			this.children = [];
+			this._batch = 0;
 		},
 	
 		// group management
 	
 		openBatch: function() {
-			// summary: starts a new batch, subsequent new child shapes will be held in
-			//	the batch instead of appending to the container directly
+			// summary:
+			//		starts a new batch, subsequent new child shapes will be held in
+			//		the batch instead of appending to the container directly.
+			// description:
+			//		Because the canvas renderer has no DOM hierarchy, the canvas implementation differs
+			//		such that it suspends the repaint requests for this container until the current batch is closed by a call to closeBatch().
+			return this;
 		},
 		closeBatch: function() {
-			// summary: submits the current batch, append all pending child shapes to DOM
+			// summary:
+			//		submits the current batch, append all pending child shapes to DOM
+			// description:
+			//		On canvas, this method flushes the pending redraws queue.
+			return this;
 		},
 		add: function(shape){
-			// summary: adds a shape to the list
-			// shape: dojox.gfx.Shape
+			// summary:
+			//		adds a shape to the list
+			// shape: dojox/gfx/shape.Shape
 			//		the shape to add to the list
 			var oldParent = shape.getParent();
 			if(oldParent){
@@ -462,8 +541,9 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			return shape._setParent(this, this._getRealMatrix());	// self
 		},
 		remove: function(shape, silently){
-			// summary: removes a shape from the list
-			//	shape: dojox.gfx.shape.Shape
+			// summary:
+			//		removes a shape from the list
+			// shape: dojox/gfx/shape.Shape
 			//		the shape to remove
 			// silently: Boolean
 			//		if true, do not redraw a picture yet
@@ -481,23 +561,67 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			}
 			return this;	// self
 		},
-		clear: function(){
-			// summary: removes all shapes from a group/surface
+		clear: function(/*Boolean?*/ destroy){
+			// summary:
+			//		removes all shapes from a group/surface.
+			// destroy: Boolean
+			//		Indicates whether the children should be destroyed. Optional.
 			var shape;
 			for(var i = 0; i < this.children.length;++i){
 				shape = this.children[i];
 				shape.parent = null;
 				shape.parentMatrix = null;
+				if(destroy){
+					shape.destroy();
+				}
 			}
 			this.children = [];
 			return this;	// self
 		},
-	
+		getBoundingBox: function(){
+			// summary:
+			//		Returns the bounding box Rectangle for this shape.
+			if(this.children){
+				// if this is a composite shape, then sum up all the children
+				var result = null;
+				arr.forEach(this.children, function(shape){
+					var bb = shape.getBoundingBox();
+					if(bb){
+						var ct = shape.getTransform();
+						if(ct){
+							bb = matrixLib.multiplyRectangle(ct, bb);
+						}
+						if(result){
+							// merge two bbox 
+							result.x = Math.min(result.x, bb.x);
+							result.y = Math.min(result.y, bb.y);
+							result.endX = Math.max(result.endX, bb.x + bb.width);
+							result.endY = Math.max(result.endY, bb.y + bb.height);
+						}else{
+							// first bbox 
+							result = {
+								x: bb.x,
+								y: bb.y,
+								endX: bb.x + bb.width,
+								endY: bb.y + bb.height
+							};
+						}
+					}
+				});
+				if(result){
+					result.width = result.endX - result.x;
+					result.height = result.endY - result.y;
+				}
+				return result; // dojox/gfx.Rectangle
+			}
+			// unknown/empty bounding box, subclass shall override this impl 
+			return null;
+		},
 		// moving child nodes
-	
 		_moveChildToFront: function(shape){
-			// summary: moves a shape to front of the list of shapes
-			//	shape: dojox.gfx.shape.Shape
+			// summary:
+			//		moves a shape to front of the list of shapes
+			// shape: dojox/gfx/shape.Shape
 			//		one of the child shapes to move to the front
 			for(var i = 0; i < this.children.length; ++i){
 				if(this.children[i] == shape){
@@ -509,8 +633,9 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			return this;	// self
 		},
 		_moveChildToBack: function(shape){
-			// summary: moves a shape to back of the list of shapes
-			//	shape: dojox.gfx.shape.Shape
+			// summary:
+			//		moves a shape to back of the list of shapes
+			// shape: dojox/gfx/shape.Shape
 			//		one of the child shapes to move to the front
 			for(var i = 0; i < this.children.length; ++i){
 				if(this.children[i] == shape){
@@ -522,9 +647,10 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			return this;	// self
 		}
 	};
-	
-	declare("dojox.gfx.shape.Surface", null, {
-		// summary: a surface object to be used for drawings
+
+	shape.Surface = declare("dojox.gfx.shape.Surface", null, {
+		// summary:
+		//		a surface object to be used for drawings
 		constructor: function(){
 			// underlying node
 			this.rawNode = null;
@@ -536,11 +662,12 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			this._events = [];
 		},
 		destroy: function(){
-			// summary: destroy all relevant external resources and release all
-			//	external references to make this object garbage-collectible
+			// summary:
+			//		destroy all relevant external resources and release all
+			//		external references to make this object garbage-collectible
 			arr.forEach(this._nodes, domConstruct.destroy);
 			this._nodes = [];
-			arr.forEach(this._events, events.disconnect);
+			arr.forEach(this._events, function(h){ if(h){ h.remove(); } });
 			this._events = [];
 			this.rawNode = null;	// recycle it in _nodes, if it needs to be recycled
 			if(has("ie")){
@@ -553,48 +680,74 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			this._parent = null;
 		},
 		getEventSource: function(){
-			// summary: returns a node, which can be used to attach event listeners
+			// summary:
+			//		returns a node, which can be used to attach event listeners
 			return this.rawNode; // Node
 		},
 		_getRealMatrix: function(){
-			// summary: always returns the identity matrix
-			return null;	// dojox.gfx.Matrix2D
+			// summary:
+			//		always returns the identity matrix
+			return null;	// dojox/gfx/Matrix2D
 		},
+		/*=====
+		 setDimensions: function(width, height){
+			 // summary:
+			 //		sets the width and height of the rawNode
+			 // width: String
+			 //		width of surface, e.g., "100px"
+			 // height: String
+			 //		height of surface, e.g., "100px"
+			 return this;	// self
+		 },
+		 getDimensions: function(){
+			 // summary:
+			 //     gets current width and height in pixels
+			 // returns: Object
+			 //     object with properties "width" and "height"
+		 },
+		 =====*/
 		isLoaded: true,
-		onLoad: function(/*dojox.gfx.Surface*/ surface){
-			// summary: local event, fired once when the surface is created
-			// asynchronously, used only when isLoaded is false, required
-			// only for Silverlight.
+		onLoad: function(/*dojox/gfx/shape.Surface*/ surface){
+			// summary:
+			//		local event, fired once when the surface is created
+			//		asynchronously, used only when isLoaded is false, required
+			//		only for Silverlight.
 		},
 		whenLoaded: function(/*Object|Null*/ context, /*Function|String*/ method){
 			var f = lang.hitch(context, method);
 			if(this.isLoaded){
 				f(this);
 			}else{
-				var h = events.connect(this, "onLoad", function(surface){
-					events.disconnect(h);
+				on.once(this, "load", function(surface){
 					f(surface);
 				});
 			}
 		}
 	});
-	
 	lang.extend(shape.Surface, shape._eventsProcessing);
-	
-	declare("dojox.gfx.Point", null, {
-		// summary: a hypothetical 2D point to be used for drawings - {x, y}
-		// description: This object is defined for documentation purposes.
-		//	You should use the naked object instead: {x: 1, y: 2}.
+
+	/*=====
+	g.Point = declare("dojox/gfx.Point", null, {
+		// summary:
+		//		2D point for drawings - {x, y}
+		// description:
+		//		Do not use this object directly!
+		//		Use the naked object instead: {x: 1, y: 2}.
 	});
-	
-	declare("dojox.gfx.Rectangle", null, {
-		// summary: a hypothetical rectangle - {x, y, width, height}
-		// description: This object is defined for documentation purposes.
-		//	You should use the naked object instead: {x: 1, y: 2, width: 100, height: 200}.
+
+	g.Rectangle = declare("dojox.gfx.Rectangle", null, {
+		// summary:
+		//		rectangle - {x, y, width, height}
+		// description:
+		//		Do not use this object directly!
+		//		Use the naked object instead: {x: 1, y: 2, width: 100, height: 200}.
 	});
-	
-	declare("dojox.gfx.shape.Rect", shape.Shape, {
-		// summary: a generic rectangle
+	 =====*/
+
+
+	shape.Rect = declare("dojox.gfx.shape.Rect", shape.Shape, {
+		// summary:
+		//		a generic rectangle
 		constructor: function(rawNode){
 			// rawNode: Node
 			//		The underlying graphics system object (typically a DOM Node)
@@ -602,13 +755,15 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			this.rawNode = rawNode;
 		},
 		getBoundingBox: function(){
-			// summary: returns the bounding box (its shape in this case)
-			return this.shape;	// dojox.gfx.Rectangle
+			// summary:
+			//		returns the bounding box (its shape in this case)
+			return this.shape;	// dojox/gfx.Rectangle
 		}
 	});
 	
-	declare("dojox.gfx.shape.Ellipse", shape.Shape, {
-		// summary: a generic ellipse
+	shape.Ellipse = declare("dojox.gfx.shape.Ellipse", shape.Shape, {
+		// summary:
+		//		a generic ellipse
 		constructor: function(rawNode){
 			// rawNode: Node
 			//		a DOM Node
@@ -616,19 +771,20 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			this.rawNode = rawNode;
 		},
 		getBoundingBox: function(){
-			// summary: returns the bounding box
+			// summary:
+			//		returns the bounding box
 			if(!this.bbox){
 				var shape = this.shape;
 				this.bbox = {x: shape.cx - shape.rx, y: shape.cy - shape.ry,
 					width: 2 * shape.rx, height: 2 * shape.ry};
 			}
-			return this.bbox;	// dojox.gfx.Rectangle
+			return this.bbox;	// dojox/gfx.Rectangle
 		}
 	});
 	
-	declare("dojox.gfx.shape.Circle", shape.Shape, {
-		// summary: a generic circle
-		//	(this is a helper object, which is defined for convenience)
+	shape.Circle = declare("dojox.gfx.shape.Circle", shape.Shape, {
+		// summary:
+		//		a generic circle
 		constructor: function(rawNode){
 			// rawNode: Node
 			//		a DOM Node
@@ -636,19 +792,20 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			this.rawNode = rawNode;
 		},
 		getBoundingBox: function(){
-			// summary: returns the bounding box
+			// summary:
+			//		returns the bounding box
 			if(!this.bbox){
 				var shape = this.shape;
 				this.bbox = {x: shape.cx - shape.r, y: shape.cy - shape.r,
 					width: 2 * shape.r, height: 2 * shape.r};
 			}
-			return this.bbox;	// dojox.gfx.Rectangle
+			return this.bbox;	// dojox/gfx.Rectangle
 		}
 	});
 	
-	declare("dojox.gfx.shape.Line", shape.Shape, {
-		// summary: a generic line
-		//	(this is a helper object, which is defined for convenience)
+	shape.Line = declare("dojox.gfx.shape.Line", shape.Shape, {
+		// summary:
+		//		a generic line (do not instantiate it directly)
 		constructor: function(rawNode){
 			// rawNode: Node
 			//		a DOM Node
@@ -656,7 +813,8 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			this.rawNode = rawNode;
 		},
 		getBoundingBox: function(){
-			// summary: returns the bounding box
+			// summary:
+			//		returns the bounding box
 			if(!this.bbox){
 				var shape = this.shape;
 				this.bbox = {
@@ -666,13 +824,13 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 					height:	Math.abs(shape.y2 - shape.y1)
 				};
 			}
-			return this.bbox;	// dojox.gfx.Rectangle
+			return this.bbox;	// dojox/gfx.Rectangle
 		}
 	});
 	
-	declare("dojox.gfx.shape.Polyline", shape.Shape, {
-		// summary: a generic polyline/polygon
-		//	(this is a helper object, which is defined for convenience)
+	shape.Polyline = declare("dojox.gfx.shape.Polyline", shape.Shape, {
+		// summary:
+		//		a generic polyline/polygon (do not instantiate it directly)
 		constructor: function(rawNode){
 			// rawNode: Node
 			//		a DOM Node
@@ -680,13 +838,13 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			this.rawNode = rawNode;
 		},
 		setShape: function(points, closed){
-			// summary: sets a polyline/polygon shape object
-			// points: Object
-			//		a polyline/polygon shape object
+			// summary:
+			//		sets a polyline/polygon shape object
+			// points: Object|Array
+			//		a polyline/polygon shape object, or an array of points
 			// closed: Boolean
 			//		close the polyline to make a polygon
 			if(points && points instanceof Array){
-				// points: Array: an array of points
 				this.inherited(arguments, [{points: points}]);
 				if(closed && this.shape.points.length){
 					this.shape.points.push(this.shape.points[0]);
@@ -697,7 +855,8 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			return this;	// self
 		},
 		_normalizePoints: function(){
-			// summary: normalize points to array of {x:number, y:number}
+			// summary:
+			//		normalize points to array of {x:number, y:number}
 			var p = this.shape.points, l = p && p.length;
 			if(l && typeof p[0] == "number"){
 				var points = [];
@@ -708,7 +867,8 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			}
 		},
 		getBoundingBox: function(){
-			// summary: returns the bounding box
+			// summary:
+			//		returns the bounding box
 			if(!this.bbox && this.shape.points.length){
 				var p = this.shape.points;
 				var l = p.length;
@@ -728,13 +888,13 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 					height:	bbox.b - bbox.t
 				};
 			}
-			return this.bbox;	// dojox.gfx.Rectangle
+			return this.bbox;	// dojox/gfx.Rectangle
 		}
 	});
 	
-	declare("dojox.gfx.shape.Image", shape.Shape, {
-		// summary: a generic image
-		//	(this is a helper object, which is defined for convenience)
+	shape.Image = declare("dojox.gfx.shape.Image", shape.Shape, {
+		// summary:
+		//		a generic image (do not instantiate it directly)
 		constructor: function(rawNode){
 			// rawNode: Node
 			//		a DOM Node
@@ -742,21 +902,25 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			this.rawNode = rawNode;
 		},
 		getBoundingBox: function(){
-			// summary: returns the bounding box (its shape in this case)
-			return this.shape;	// dojox.gfx.Rectangle
+			// summary:
+			//		returns the bounding box (its shape in this case)
+			return this.shape;	// dojox/gfx.Rectangle
 		},
 		setStroke: function(){
-			// summary: ignore setting a stroke style
+			// summary:
+			//		ignore setting a stroke style
 			return this;	// self
 		},
 		setFill: function(){
-			// summary: ignore setting a fill style
+			// summary:
+			//		ignore setting a fill style
 			return this;	// self
 		}
 	});
 	
-	declare("dojox.gfx.shape.Text", shape.Shape, {
-		// summary: a generic text
+	shape.Text = declare(shape.Shape, {
+		// summary:
+		//		a generic text (do not instantiate it directly)
 		constructor: function(rawNode){
 			// rawNode: Node
 			//		a DOM Node
@@ -765,32 +929,45 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			this.rawNode = rawNode;
 		},
 		getFont: function(){
-			// summary: returns the current font object or null
+			// summary:
+			//		returns the current font object or null
 			return this.fontStyle;	// Object
 		},
 		setFont: function(newFont){
-			// summary: sets a font for text
+			// summary:
+			//		sets a font for text
 			// newFont: Object
-			//		a font object (see dojox.gfx.defaultFont) or a font string
+			//		a font object (see dojox/gfx.defaultFont) or a font string
 			this.fontStyle = typeof newFont == "string" ? g.splitFontString(newFont) :
 				g.makeParameters(g.defaultFont, newFont);
 			this._setFont();
 			return this;	// self
+		},
+		getBoundingBox: function(){
+			var bbox = null, s = this.getShape();
+			if(s.text){
+				bbox = g._base._computeTextBoundingBox(this);
+			}
+			return bbox;
 		}
 	});
 	
 	shape.Creator = {
-		// summary: shape creators
+		// summary:
+		//		shape creators
 		createShape: function(shape){
-			// summary: creates a shape object based on its type; it is meant to be used
-			//	by group-like objects
+			// summary:
+			//		creates a shape object based on its type; it is meant to be used
+			//		by group-like objects
 			// shape: Object
 			//		a shape descriptor object
+			// returns: dojox/gfx/shape.Shape | Null
+			//      a fully instantiated surface-specific Shape object
 			switch(shape.type){
 				case g.defaultPath.type:		return this.createPath(shape);
 				case g.defaultRect.type:		return this.createRect(shape);
-				case g.defaultCircle.type:	return this.createCircle(shape);
-				case g.defaultEllipse.type:	return this.createEllipse(shape);
+				case g.defaultCircle.type:	    return this.createCircle(shape);
+				case g.defaultEllipse.type:	    return this.createEllipse(shape);
 				case g.defaultLine.type:		return this.createLine(shape);
 				case g.defaultPolyline.type:	return this.createPolyline(shape);
 				case g.defaultImage.type:		return this.createImage(shape);
@@ -800,76 +977,107 @@ define(["./_base", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/window",
 			return null;
 		},
 		createGroup: function(){
-			// summary: creates a group shape
-			return this.createObject(g.Group);	// dojox.gfx.Group
+			// summary:
+			//		creates a group shape
+			return this.createObject(g.Group);	// dojox/gfx/Group
 		},
 		createRect: function(rect){
-			// summary: creates a rectangle shape
+			// summary:
+			//		creates a rectangle shape
 			// rect: Object
-			//		a path object (see dojox.gfx.defaultRect)
-			return this.createObject(g.Rect, rect);	// dojox.gfx.Rect
+			//		a path object (see dojox/gfx.defaultRect)
+			return this.createObject(g.Rect, rect);	// dojox/gfx/shape.Rect
 		},
 		createEllipse: function(ellipse){
-			// summary: creates an ellipse shape
+			// summary:
+			//		creates an ellipse shape
 			// ellipse: Object
-			//		an ellipse object (see dojox.gfx.defaultEllipse)
-			return this.createObject(g.Ellipse, ellipse);	// dojox.gfx.Ellipse
+			//		an ellipse object (see dojox/gfx.defaultEllipse)
+			return this.createObject(g.Ellipse, ellipse);	// dojox/gfx/shape.Ellipse
 		},
 		createCircle: function(circle){
-			// summary: creates a circle shape
+			// summary:
+			//		creates a circle shape
 			// circle: Object
-			//		a circle object (see dojox.gfx.defaultCircle)
-			return this.createObject(g.Circle, circle);	// dojox.gfx.Circle
+			//		a circle object (see dojox/gfx.defaultCircle)
+			return this.createObject(g.Circle, circle);	// dojox/gfx/shape.Circle
 		},
 		createLine: function(line){
-			// summary: creates a line shape
+			// summary:
+			//		creates a line shape
 			// line: Object
-			//		a line object (see dojox.gfx.defaultLine)
-			return this.createObject(g.Line, line);	// dojox.gfx.Line
+			//		a line object (see dojox/gfx.defaultLine)
+			return this.createObject(g.Line, line);	// dojox/gfx/shape.Line
 		},
 		createPolyline: function(points){
-			// summary: creates a polyline/polygon shape
+			// summary:
+			//		creates a polyline/polygon shape
 			// points: Object
-			//		a points object (see dojox.gfx.defaultPolyline)
+			//		a points object (see dojox/gfx.defaultPolyline)
 			//		or an Array of points
-			return this.createObject(g.Polyline, points);	// dojox.gfx.Polyline
+			return this.createObject(g.Polyline, points);	// dojox/gfx/shape.Polyline
 		},
 		createImage: function(image){
-			// summary: creates a image shape
+			// summary:
+			//		creates a image shape
 			// image: Object
-			//		an image object (see dojox.gfx.defaultImage)
-			return this.createObject(g.Image, image);	// dojox.gfx.Image
+			//		an image object (see dojox/gfx.defaultImage)
+			return this.createObject(g.Image, image);	// dojox/gfx/shape.Image
 		},
 		createText: function(text){
-			// summary: creates a text shape
+			// summary:
+			//		creates a text shape
 			// text: Object
-			//		a text object (see dojox.gfx.defaultText)
-			return this.createObject(g.Text, text);	// dojox.gfx.Text
+			//		a text object (see dojox/gfx.defaultText)
+			return this.createObject(g.Text, text);	// dojox/gfx/shape.Text
 		},
 		createPath: function(path){
-			// summary: creates a path shape
+			// summary:
+			//		creates a path shape
 			// path: Object
-			//		a path object (see dojox.gfx.defaultPath)
-			return this.createObject(g.Path, path);	// dojox.gfx.Path
+			//		a path object (see dojox/gfx.defaultPath)
+			return this.createObject(g.Path, path);	// dojox/gfx/shape.Path
 		},
 		createTextPath: function(text){
-			// summary: creates a text shape
+			// summary:
+			//		creates a text shape
 			// text: Object
-			//		a textpath object (see dojox.gfx.defaultTextPath)
-			return this.createObject(g.TextPath, {}).setText(text);	// dojox.gfx.TextPath
+			//		a textpath object (see dojox/gfx.defaultTextPath)
+			return this.createObject(g.TextPath, {}).setText(text);	// dojox/gfx/shape.TextPath
 		},
 		createObject: function(shapeType, rawShape){
-			// summary: creates an instance of the passed shapeType class
-			// SHOULD BE RE-IMPLEMENTED BY THE RENDERER!
+			// summary:
+			//		creates an instance of the passed shapeType class
 			// shapeType: Function
 			//		a class constructor to create an instance of
 			// rawShape: Object 
 			//		properties to be passed in to the classes 'setShape' method
 	
-			return null;	// dojox.gfx.Shape
+			// SHOULD BE RE-IMPLEMENTED BY THE RENDERER!
+			return null;	// dojox/gfx/shape.Shape
 		}
 	};
 	
+	/*=====
+	 lang.extend(shape.Surface, shape.Container);
+	 lang.extend(shape.Surface, shape.Creator);
+
+	 g.Group = declare(shape.Shape, {
+		// summary:
+		//		a group shape, which can be used
+		//		to logically group shapes (e.g, to propagate matricies)
+	});
+	lang.extend(g.Group, shape.Container);
+	lang.extend(g.Group, shape.Creator);
+
+	g.Rect     = shape.Rect;
+	g.Circle   = shape.Circle;
+	g.Ellipse  = shape.Ellipse;
+	g.Line     = shape.Line;
+	g.Polyline = shape.Polyline;
+	g.Text     = shape.Text;
+	g.Surface  = shape.Surface;
+	=====*/
+
 	return shape;
 });
-
diff --git a/dojox/gfx/silverlight.js b/dojox/gfx/silverlight.js
index a7996ef..96a5889 100644
--- a/dojox/gfx/silverlight.js
+++ b/dojox/gfx/silverlight.js
@@ -1,31 +1,12 @@
 define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/Color", 
-		"dojo/_base/array", "dojo/dom-geometry", "dojo/dom", "dojo/_base/sniff", 
-		"./_base", "./shape", "./path"], 
-  function(kernel,lang,declare,color,arr,domGeom,dom,has,g,gs,pathLib){
-/*===== 
-	dojox.gfx.silverlight = {
-	// module:
-	//		dojox/gfx/silverlight
-	// summary:
-	//		This the graphics rendering bridge for the Microsoft Silverlight plugin.
-	//		Silverlight is a faster implementation on IE6-8 than the default 2d graphics, VML
+		"dojo/on", "dojo/_base/array", "dojo/dom-geometry", "dojo/dom", "dojo/_base/sniff",
+		"./_base", "./shape", "./path", "./registry"],
+  function(kernel,lang,declare,color,on,arr,domGeom,dom,has,g,gs,pathLib){
+	var sl = g.silverlight = {
+		// summary:
+		//		This the graphics rendering bridge for the Microsoft Silverlight plugin.
+		//		Silverlight is a faster implementation on IE6-8 than the default 2d graphics, VML
 	};
-	g = dojox.gfx;
-	pathLib.Path = dojox.gfx.path.Path;
-	pathLib.TextPath = dojox.gfx.path.TextPath;
-	sl.Shape = dojox.gfx.canvas.Shape;
-	gs.Shape = dojox.gfx.shape.Shape;
-	gs.Rect = dojox.gfx.shape.Rect;
-	gs.Ellipse = dojox.gfx.shape.Ellipse;
-	gs.Circle = dojox.gfx.shape.Circle;
-	gs.Line = dojox.gfx.shape.Line;
-	gs.PolyLine = dojox.gfx.shape.PolyLine;
-	gs.Image = dojox.gfx.shape.Image;
-	gs.Text = dojox.gfx.shape.Text;
-	gs.Surface = dojox.gfx.shape.Surface;
-  =====*/
-
-	var sl = g.silverlight = {};
 	kernel.experimental("dojox.gfx.silverlight");
 
 	var dasharray = {
@@ -56,24 +37,38 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			courier: "Courier New"
 		};
 
-	function hexColor(/*String|Array|dojo.Color*/ color){
-		// summary: converts a color object to a Silverlight hex color string (#aarrggbb)
+	function hexColor(/*String|Array|dojo/Color*/ color){
+		// summary:
+		//		converts a color object to a Silverlight hex color string (#aarrggbb)
 		var c = g.normalizeColor(color),
 			t = c.toHex(), a = Math.round(c.a * 255);
 		a = (a < 0 ? 0 : a > 255 ? 255 : a).toString(16);
 		return "#" + (a.length < 2 ? "0" + a : a) + t.slice(1);	// String
 	}
 
-	declare("dojox.gfx.silverlight.Shape", gs.Shape, {
-		// summary: Silverlight-specific implementation of dojox.gfx.Shape methods
+	sl.Shape = declare("dojox.gfx.silverlight.Shape", gs.Shape, {
+		// summary:
+		//		Silverlight-specific implementation of dojox/gfx/shape.Shape methods
+
+		destroy: function(){
+			// summary:
+			//		Releases all internal resources owned by this shape. Once this method has been called,
+			//		the instance is considered destroyed and should not be used anymore.
+			if(has("gfxRegistry")){
+				gs.dispose(this);
+			}
+			this.rawNode = null;
+		},
 
 		setFill: function(fill){
-			// summary: sets a fill object (Silverlight)
-			// fill: Object: a fill object
-			//	(see dojox.gfx.defaultLinearGradient,
-			//	dojox.gfx.defaultRadialGradient,
-			//	dojox.gfx.defaultPattern,
-			//	or dojo.Color)
+			// summary:
+			//		sets a fill object (Silverlight)
+			// fill: Object
+			//		a fill object
+			//		(see dojox/gfx.defaultLinearGradient,
+			//		dojox/gfx.defaultRadialGradient,
+			//		dojox/gfx.defaultPattern,
+			//		or dojo/_base/Color)
 
 			var p = this.rawNode.getHost().content, r = this.rawNode, f;
 			if(!fill){
@@ -137,9 +132,11 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		},
 
 		setStroke: function(stroke){
-			// summary: sets a stroke object (Silverlight)
-			// stroke: Object: a stroke object
-			//	(see dojox.gfx.defaultStroke)
+			// summary:
+			//		sets a stroke object (Silverlight)
+			// stroke: Object
+			//		a stroke object
+			//		(see dojox/gfx.defaultStroke)
 
 			var p = this.rawNode.getHost().content, r = this.rawNode;
 			if(!stroke){
@@ -226,26 +223,28 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 
 		setRawNode: function(rawNode){
 			// summary:
-			//	assigns and clears the underlying node that will represent this
-			//	shape. Once set, transforms, gradients, etc, can be applied.
-			//	(no fill & stroke by default)
+			//		assigns and clears the underlying node that will represent this
+			//		shape. Once set, transforms, gradients, etc, can be applied.
+			//		(no fill & stroke by default)
 			rawNode.fill = null;
 			rawNode.stroke = null;
 			this.rawNode = rawNode;
-			this.rawNode.tag = this.getUID();						
+			this.rawNode.tag = this.getUID();
 		},
 
 		// move family
 
 		_moveToFront: function(){
-			// summary: moves a shape to front of its parent's list of shapes (Silverlight)
+			// summary:
+			//		moves a shape to front of its parent's list of shapes (Silverlight)
 			var c = this.parent.rawNode.children, r = this.rawNode;
 			c.remove(r);
 			c.add(r);
 			return this;	// self
 		},
 		_moveToBack: function(){
-			// summary: moves a shape to back of its parent's list of shapes (Silverlight)
+			// summary:
+			//		moves a shape to back of its parent's list of shapes (Silverlight)
 			var c = this.parent.rawNode.children, r = this.rawNode;
 			c.remove(r);
 			c.insert(0, r);
@@ -253,32 +252,103 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		},
 
 		_getAdjustedMatrix: function(){
-			// summary: returns the adjusted ("real") transformation matrix
-			return this.matrix;	// dojox.gfx.Matrix2D
+			// summary:
+			//		returns the adjusted ("real") transformation matrix
+			return this.matrix;	// dojox/gfx/matrix.Matrix2D
+		},
+		
+		setClip: function(clip){
+			// summary:
+			//		sets the clipping area of this shape.
+			// description:
+			//		This method overrides the dojox/gfx/shape.Shape.setClip() method.
+			// clip: Object
+			//		an object that defines the clipping geometry, or null to remove clip.
+			this.inherited(arguments);
+			var r = this.rawNode;
+			if(clip){
+				var clipType = clip ? "width" in clip ? "rect" : 
+								"cx" in clip ? "ellipse" : 
+								"points" in clip ? "polyline" : "d" in clip ? "path" : null : null;
+				if(clip && !clipType){
+					return this;
+				}
+				var bbox = this.getBoundingBox() || {x:0, y:0, width:0, height:0};
+				var clipT = "1,0,0,1,"+(-bbox.x)+","+(-bbox.y);
+				switch(clipType){
+					case "rect":
+						r.clip = r.getHost().content.createFromXaml("<RectangleGeometry/>");
+						r.clip.rect = clip.x+","+clip.y+","+clip.width+","+clip.height;
+						r.clip.transform = clipT;
+						break;
+					case "ellipse":
+						r.clip = r.getHost().content.createFromXaml("<EllipseGeometry/>");
+						r.clip.center = clip.cx+","+clip.cy;
+						r.clip.radiusX = clip.rx;
+						r.clip.radiusY = clip.ry;
+						r.clip.transform = "1,0,0,1,"+(-bbox.x)+","+(-bbox.y);
+						break;
+					case "polyline":
+						if(clip.points.length>2){
+							var line, plinegroup = r.getHost().content.createFromXaml("<PathGeometry/>"),
+								pfigure = r.getHost().content.createFromXaml("<PathFigure/>");
+							pfigure.StartPoint = clip.points[0]+","+clip.points[1];
+							for (var i=2; i<=clip.points.length-2;i=i+2){
+								line = r.getHost().content.createFromXaml("<LineSegment/>");
+								line.Point = clip.points[i]+","+clip.points[i+1];
+								pfigure.segments.add(line);
+							}
+							plinegroup.figures.add(pfigure);
+							plinegroup.transform = "1,0,0,1,"+(-bbox.x)+","+(-bbox.y);
+							r.clip = plinegroup;
+						}
+						break;
+					case "path":
+						// missing JS api
+						break;
+				}
+			}else{
+				r.clip = null;
+			}
+			return this;
 		}
 	});
 
-	declare("dojox.gfx.silverlight.Group", sl.Shape, {
-		// summary: a group shape (Silverlight), which can be used
-		//	to logically group shapes (e.g, to propagate matricies)
+	sl.Group = declare("dojox.gfx.silverlight.Group", sl.Shape, {
+		// summary:
+		//		a group shape (Silverlight), which can be used
+		//		to logically group shapes (e.g, to propagate matricies)
 		constructor: function(){
 			gs.Container._init.call(this);
 		},
 		setRawNode: function(rawNode){
-			// summary: sets a raw Silverlight node to be used by this shape
-			// rawNode: Node: an Silverlight node
+			// summary:
+			//		sets a raw Silverlight node to be used by this shape
+			// rawNode: Node
+			//		a Sliverlight node
 			this.rawNode = rawNode;
-			this.rawNode.tag = this.getUID();						
+			this.rawNode.tag = this.getUID();
 			
+		},
+		destroy: function(){
+			// summary:
+			//		Releases all internal resources owned by this shape. Once this method has been called,
+			//		the instance is considered disposed and should not be used anymore.
+			this.clear(true);
+			// avoid this.inherited
+			sl.Shape.prototype.destroy.apply(this, arguments);
 		}
 	});
 	sl.Group.nodeType = "Canvas";
 
-	declare("dojox.gfx.silverlight.Rect", [sl.Shape, gs.Rect], {
-		// summary: a rectangle shape (Silverlight)
+	sl.Rect = declare("dojox.gfx.silverlight.Rect", [sl.Shape, gs.Rect], {
+		// summary:
+		//		a rectangle shape (Silverlight)
 		setShape: function(newShape){
-			// summary: sets a rectangle shape object (Silverlight)
-			// newShape: Object: a rectangle shape object
+			// summary:
+			//		sets a rectangle shape object (Silverlight)
+			// newShape: Object
+			//		a rectangle shape object
 			this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var r = this.rawNode, n = this.shape;
@@ -288,18 +358,22 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			return this._applyTransform();	// self
 		},
 		_getAdjustedMatrix: function(){
-			// summary: returns the adjusted ("real") transformation matrix
+			// summary:
+			//		returns the adjusted ("real") transformation matrix
 			var matrix = this.matrix, s = this.shape, delta = {dx: s.x, dy: s.y};
-			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox.gfx.Matrix2D
+			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox/gfx/matrix.Matrix2D
 		}
 	});
 	sl.Rect.nodeType = "Rectangle";
 
-	declare("dojox.gfx.silverlight.Ellipse", [sl.Shape, gs.Ellipse], {
-		// summary: an ellipse shape (Silverlight)
+	sl.Ellipse = declare("dojox.gfx.silverlight.Ellipse", [sl.Shape, gs.Ellipse], {
+		// summary:
+		//		an ellipse shape (Silverlight)
 		setShape: function(newShape){
-			// summary: sets an ellipse shape object (Silverlight)
-			// newShape: Object: an ellipse shape object
+			// summary:
+			//		sets an ellipse shape object (Silverlight)
+			// newShape: Object
+			//		an ellipse shape object
 			this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var r = this.rawNode, n = this.shape;
@@ -308,18 +382,22 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			return this._applyTransform();	// self
 		},
 		_getAdjustedMatrix: function(){
-			// summary: returns the adjusted ("real") transformation matrix
+			// summary:
+			//		returns the adjusted ("real") transformation matrix
 			var matrix = this.matrix, s = this.shape, delta = {dx: s.cx - s.rx, dy: s.cy - s.ry};
-			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox.gfx.Matrix2D
+			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox/gfx/matrix.Matrix2D
 		}
 	});
 	sl.Ellipse.nodeType = "Ellipse";
 
-	declare("dojox.gfx.silverlight.Circle", [sl.Shape, gs.Circle], {
-		// summary: a circle shape (Silverlight)
+	sl.Circle = declare("dojox.gfx.silverlight.Circle", [sl.Shape, gs.Circle], {
+		// summary:
+		//		a circle shape (Silverlight)
 		setShape: function(newShape){
-			// summary: sets a circle shape object (Silverlight)
-			// newShape: Object: a circle shape object
+			// summary:
+			//		sets a circle shape object (Silverlight)
+			// newShape: Object
+			//		a circle shape object
 			this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var r = this.rawNode, n = this.shape;
@@ -327,18 +405,22 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			return this._applyTransform();	// self
 		},
 		_getAdjustedMatrix: function(){
-			// summary: returns the adjusted ("real") transformation matrix
+			// summary:
+			//		returns the adjusted ("real") transformation matrix
 			var matrix = this.matrix, s = this.shape, delta = {dx: s.cx - s.r, dy: s.cy - s.r};
-			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox.gfx.Matrix2D
+			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox/gfx/matrix.Matrix2D
 		}
 	});
 	sl.Circle.nodeType = "Ellipse";
 
-	declare("dojox.gfx.silverlight.Line", [sl.Shape, gs.Line], {
-		// summary: a line shape (Silverlight)
+	sl.Line = declare("dojox.gfx.silverlight.Line", [sl.Shape, gs.Line], {
+		// summary:
+		//		a line shape (Silverlight)
 		setShape: function(newShape){
-			// summary: sets a line shape object (Silverlight)
-			// newShape: Object: a line shape object
+			// summary:
+			//		sets a line shape object (Silverlight)
+			// newShape: Object
+			//		a line shape object
 			this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var r = this.rawNode, n = this.shape;
@@ -348,14 +430,15 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 	});
 	sl.Line.nodeType = "Line";
 
-	declare("dojox.gfx.silverlight.Polyline", [sl.Shape, gs.Polyline], {
-		// summary: a polyline/polygon shape (Silverlight)
+	sl.Polyline = declare("dojox.gfx.silverlight.Polyline", [sl.Shape, gs.Polyline], {
+		// summary:
+		//		a polyline/polygon shape (Silverlight)
 		setShape: function(points, closed){
-			// summary: sets a polyline/polygon shape object (Silverlight)
-			// points: Object: a polyline/polygon shape object
+			// summary:
+			//		sets a polyline/polygon shape object (Silverlight)
+			// points: Object|Array
+			//		a polyline/polygon shape object, or an array of points
 			if(points && points instanceof Array){
-				// branch
-				// points: Array: an array of points
 				this.shape = g.makeParameters(this.shape, {points: points});
 				if(closed && this.shape.points.length){
 					this.shape.points.push(this.shape.points[0]);
@@ -375,11 +458,14 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 	});
 	sl.Polyline.nodeType = "Polyline";
 
-	declare("dojox.gfx.silverlight.Image", [sl.Shape, gs.Image], {
-		// summary: an image (Silverlight)
+	sl.Image = declare("dojox.gfx.silverlight.Image", [sl.Shape, gs.Image], {
+		// summary:
+		//		an image (Silverlight)
 		setShape: function(newShape){
-			// summary: sets an image shape object (Silverlight)
-			// newShape: Object: an image shape object
+			// summary:
+			//		sets an image shape object (Silverlight)
+			// newShape: Object
+			//		an image shape object
 			this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var r = this.rawNode, n = this.shape;
@@ -389,30 +475,34 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			return this._applyTransform();	// self
 		},
 		_getAdjustedMatrix: function(){
-			// summary: returns the adjusted ("real") transformation matrix
+			// summary:
+			//		returns the adjusted ("real") transformation matrix
 			var matrix = this.matrix, s = this.shape, delta = {dx: s.x, dy: s.y};
-			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox.gfx.Matrix2D
+			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox/gfx/matrix.Matrix2D
 		},
 		setRawNode: function(rawNode){
 			// summary:
-			//	assigns and clears the underlying node that will represent this
-			//	shape. Once set, transforms, gradients, etc, can be applied.
-			//	(no fill & stroke by default)
+			//		assigns and clears the underlying node that will represent this
+			//		shape. Once set, transforms, gradients, etc, can be applied.
+			//		(no fill & stroke by default)
 			this.rawNode = rawNode;
-			this.rawNode.tag = this.getUID();						
+			this.rawNode.tag = this.getUID();
 		}
 	});
 	sl.Image.nodeType = "Image";
 
-	declare("dojox.gfx.silverlight.Text", [sl.Shape, gs.Text], {
-		// summary: an anchored text (Silverlight)
+	sl.Text = declare("dojox.gfx.silverlight.Text", [sl.Shape, gs.Text], {
+		// summary:
+		//		an anchored text (Silverlight)
 		setShape: function(newShape){
-			// summary: sets a text shape object (Silverlight)
-			// newShape: Object: a text shape object
+			// summary:
+			//		sets a text shape object (Silverlight)
+			// newShape: Object
+			//		a text shape object
 			this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var r = this.rawNode, s = this.shape;
-			r.text = s.text;
+			r.text = "" + s.text; // #14522
 			r.textDecorations = s.decoration === "underline" ? "Underline" : "None";
 			r["Canvas.Left"] = -10000;
 			r["Canvas.Top"]  = -10000;
@@ -447,7 +537,8 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			delete this._delay;
 		},
 		_getAdjustedMatrix: function(){
-			// summary: returns the adjusted ("real") transformation matrix
+			// summary:
+			//		returns the adjusted ("real") transformation matrix
 			var matrix = this.matrix, delta = this._delta, x;
 			if(matrix){
 				x = delta ? [matrix, delta] : matrix;
@@ -457,7 +548,8 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			return new g.Matrix2D(x);
 		},
 		setStroke: function(){
-			// summary: ignore setting a stroke style
+			// summary:
+			//		ignore setting a stroke style
 			return this;	// self
 		},
 		_setFillAttr: function(f){
@@ -465,24 +557,51 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		},
 		setRawNode: function(rawNode){
 			// summary:
-			//	assigns and clears the underlying node that will represent this
-			//	shape. Once set, transforms, gradients, etc, can be applied.
-			//	(no fill & stroke by default)
+			//		assigns and clears the underlying node that will represent this
+			//		shape. Once set, transforms, gradients, etc, can be applied.
+			//		(no fill & stroke by default)
 			this.rawNode = rawNode;
-			this.rawNode.tag = this.getUID();						
+			this.rawNode.tag = this.getUID();
 		},
 		getTextWidth: function(){
-			// summary: get the text width in pixels
+			// summary:
+			//		get the text width in pixels
 			return this.rawNode.actualWidth;
+		},
+		getBoundingBox: function(){
+			var bbox = null, text = this.getShape().text, r = this.rawNode, w = 0, h = 0;
+			if(!g._base._isRendered(this)){
+				return {x:0, y:0, width:0, height:0};
+			}
+			if(text){
+				try{
+					w = r.actualWidth;
+					h = r.actualHeight;
+				}catch(e){
+					// bail out if the node is hidden
+					return null;
+				}
+				var loc = g._base._computeTextLocation(this.getShape(), w, h, true);
+				bbox = {
+					x: loc.x,
+					y: loc.y,
+					width : w,
+					height: h
+				};
+			}
+			return bbox;
 		}
 	});
 	sl.Text.nodeType = "TextBlock";
 
-	declare("dojox.gfx.silverlight.Path", [sl.Shape, pathLib.Path], {
-		// summary: a path shape (Silverlight)
+	sl.Path = declare("dojox.gfx.silverlight.Path", [sl.Shape, pathLib.Path], {
+		// summary:
+		//		a path shape (Silverlight)
 		_updateWithSegment: function(segment){
-			// summary: updates the bounding box of path with new segment
-			// segment: Object: a segment
+			// summary:
+			//		updates the bounding box of path with new segment
+			// segment: Object
+			//		a segment
 			this.inherited(arguments);
 			var p = this.shape.path;
 			if(typeof(p) == "string"){
@@ -490,8 +609,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			}
 		},
 		setShape: function(newShape){
-			// summary: forms a path using a shape (Silverlight)
-			// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
+			// summary:
+			//		forms a path using a shape (Silverlight)
+			// newShape: Object
+			//		an SVG path string or a path object (see dojox/gfx.defaultPath)
 			this.inherited(arguments);
 			var p = this.shape.path;
 			this.rawNode.data = p ? p : null;
@@ -500,15 +621,20 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 	});
 	sl.Path.nodeType = "Path";
 
-	declare("dojox.gfx.silverlight.TextPath", [sl.Shape, pathLib.TextPath], {
-		// summary: a textpath shape (Silverlight)
+	sl.TextPath = declare("dojox.gfx.silverlight.TextPath", [sl.Shape, pathLib.TextPath], {
+		// summary:
+		//		a textpath shape (Silverlight)
 		_updateWithSegment: function(segment){
-			// summary: updates the bounding box of path with new segment
-			// segment: Object: a segment
+			// summary:
+			//		updates the bounding box of path with new segment
+			// segment: Object
+			//		a segment
 		},
 		setShape: function(newShape){
-			// summary: forms a path using a shape (Silverlight)
-			// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
+			// summary:
+			//		forms a path using a shape (Silverlight)
+			// newShape: Object
+			//		an SVG path string or a path object (see dojox/gfx.defaultPath)
 		},
 		_setText: function(){
 		}
@@ -517,20 +643,25 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 
 	var surfaces = {}, nullFunc = new Function;
 
-	declare("dojox.gfx.silverlight.Surface", gs.Surface, {
-		// summary: a surface object to be used for drawings (Silverlight)
+	sl.Surface = declare("dojox.gfx.silverlight.Surface", gs.Surface, {
+		// summary:
+		//		a surface object to be used for drawings (Silverlight)
 		constructor: function(){
 			gs.Container._init.call(this);
 		},
 		destroy: function(){
+			this.clear(true);
 			window[this._onLoadName] = nullFunc;
 			delete surfaces[this._nodeName];
 			this.inherited(arguments);
 		},
 		setDimensions: function(width, height){
-			// summary: sets the width and height of the rawNode
-			// width: String: width of surface, e.g., "100px"
-			// height: String: height of surface, e.g., "100px"
+			// summary:
+			//		sets the width and height of the rawNode
+			// width: String
+			//		width of surface, e.g., "100px"
+			// height: String
+			//		height of surface, e.g., "100px"
 			this.width  = g.normalizedLength(width);	// in pixels
 			this.height = g.normalizedLength(height);	// in pixels
 			var p = this.rawNode && this.rawNode.getHost();
@@ -541,7 +672,8 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			return this;	// self
 		},
 		getDimensions: function(){
-			// summary: returns an object with properties "width" and "height"
+			// summary:
+			//		returns an object with properties "width" and "height"
 			var p = this.rawNode && this.rawNode.getHost();
 			var t = p ? {width: p.content.actualWidth, height: p.content.actualHeight} : null;
 			if(t.width  <= 0){ t.width  = this.width; }
@@ -551,10 +683,14 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 	});
 
 	sl.createSurface = function(parentNode, width, height){
-		// summary: creates a surface (Silverlight)
-		// parentNode: Node: a parent node
-		// width: String: width of surface, e.g., "100px"
-		// height: String: height of surface, e.g., "100px"
+		// summary:
+		//		creates a surface (Silverlight)
+		// parentNode: Node
+		//		a parent node
+		// width: String
+		//		width of surface, e.g., "100px"
+		// height: String
+		//		height of surface, e.g., "100px"
 
 		if(!width && !height){
 			var pos = domGeom.position(parentNode);
@@ -588,7 +724,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		s._onLoadName = onLoadName;
 		window[onLoadName] = function(sender){
 			if(!s.rawNode){
-				s.rawNode = dom.byId(pluginName).content.root;
+				s.rawNode = dom.byId(pluginName, parentNode.ownerDocument).content.root;
 				// register the plugin with its parent node
 				surfaces[s._nodeName] = parentNode;
 				s.onLoad(s);
@@ -617,7 +753,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		}
 		parentNode.innerHTML = obj;
 
-		var pluginNode = dom.byId(pluginName);
+		var pluginNode = dom.byId(pluginName, parentNode.ownerDocument);
 		if(pluginNode.content && pluginNode.content.root){
 			// the plugin was created synchronously
 			s.rawNode = pluginNode.content.root;
@@ -633,7 +769,7 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 		s.width  = g.normalizedLength(width);	// in pixels
 		s.height = g.normalizedLength(height);	// in pixels
 
-		return s;	// dojox.gfx.Surface
+		return s;	// dojox/gfx.Surface
 	};
 
 	// the function below is meant to be global, it is called from
@@ -664,7 +800,8 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 
 	var Font = {
 		_setFont: function(){
-			// summary: sets a font object (Silverlight)
+			// summary:
+			//		sets a font object (Silverlight)
 			var f = this.fontStyle, r = this.rawNode, t = f.family.toLowerCase();
 			r.fontStyle = f.style == "italic" ? "Italic" : "Normal";
 			r.fontWeight = f.weight in fontweight ? fontweight[f.weight] : f.weight;
@@ -680,8 +817,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 
 	var C = gs.Container, Container = {
 		add: function(shape){
-			// summary: adds a shape to a group/surface
-			// shape: dojox.gfx.Shape: a Silverlight shape object
+			// summary:
+			//		adds a shape to a group/surface
+			// shape: dojox/gfx/shape.Shape
+			//		a Silverlight shape object
 			if(this != shape.getParent()){
 				C.add.apply(this, arguments);
 				this.rawNode.children.add(shape.rawNode);
@@ -689,9 +828,12 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			return this;	// self
 		},
 		remove: function(shape, silently){
-			// summary: remove a shape from a group/surface
-			// shape: dojox.gfx.Shape: a Silverlight shape object
-			// silently: Boolean?: if true, regenerate a picture
+			// summary:
+			//		remove a shape from a group/surface
+			// shape: dojox/gfx/shape.Shape
+			//		a Silverlight shape object
+			// silently: Boolean?
+			//		if true, regenerate a picture
 			if(this == shape.getParent()){
 				var parent = shape.rawNode.getParent();
 				if(parent){
@@ -702,26 +844,31 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 			return this;	// self
 		},
 		clear: function(){
-			// summary: removes all shapes from a group/surface
+			// summary:
+			//		removes all shapes from a group/surface
 			this.rawNode.children.clear();
 			return C.clear.apply(this, arguments);
 		},
+		getBoundingBox: C.getBoundingBox,
 		_moveChildToFront: C._moveChildToFront,
 		_moveChildToBack:  C._moveChildToBack
 	};
 
 	var Creator = {
 		createObject: function(shapeType, rawShape){
-			// summary: creates an instance of the passed shapeType class
-			// shapeType: Function: a class constructor to create an instance of
-			// rawShape: Object: properties to be passed in to the classes "setShape" method
+			// summary:
+			//		creates an instance of the passed shapeType class
+			// shapeType: Function
+			//		a class constructor to create an instance of
+			// rawShape: Object
+			//		properties to be passed in to the classes "setShape" method
 			if(!this.rawNode){ return null; }
 			var shape = new shapeType();
 			var node = this.rawNode.getHost().content.createFromXaml("<" + shapeType.nodeType + "/>");
 			shape.setRawNode(node);
 			shape.setShape(rawShape);
 			this.add(shape);
-			return shape;	// dojox.gfx.Shape
+			return shape;	// dojox/gfx/shape.Shape
 		}
 	};
 
@@ -801,32 +948,42 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/declare", "dojo/_bas
 	
 	var eventsProcessing = {
 		connect: function(name, object, method){
-			var token, n = name in eventNames ? eventNames[name] :
-				{name: name, fix: function(){ return {}; }};
-			if(arguments.length > 2){
-				token = this.getEventSource().addEventListener(n.name,
-					function(s, a){ lang.hitch(object, method)(n.fix(s, a)); });
+			return this.on(name, method ? lang.hitch(object, method) : object);
+		},
+
+		on: function(name, listener){
+			if(typeof name === "string"){
+				if(name.indexOf("mouse") === 0){
+					name = "on" + name;
+				}
+				var token, n = name in eventNames ? eventNames[name] :
+					{name: name, fix: function(){ return {}; }};
+				token = this.getEventSource().addEventListener(n.name, function(s, a){ listener(n.fix(s, a)); });
+				return {
+					name: n.name,
+					token: token,
+					remove: lang.hitch(this, function(){
+						this.getEventSource().removeEventListener(n.name, token);
+					})
+				};
 			}else{
-				token = this.getEventSource().addEventListener(n.name,
-					function(s, a){ object(n.fix(s, a)); });
+				// pass this so that it gets back in this.on with the event name
+				return on(this, name, listener);
 			}
-			return {name: n.name, token: token};
 		},
+
 		disconnect: function(token){
-			try{
-				this.getEventSource().removeEventListener(token.name, token.token);
-			}catch(e){
-				// bail out if the node is hidden
-			}
+			return token.remove();
 		}
 	};
 	
 	lang.extend(sl.Shape, eventsProcessing);
 	lang.extend(sl.Surface, eventsProcessing);
 	
-	// patch dojox.gfx
+	// patch dojox/gfx
 	g.equalSources = function(a, b){
-		// summary: compares event sources, returns true if they are equal
+		// summary:
+		//		compares event sources, returns true if they are equal
 		return a && b && a.equals(b);
 	};
 	
diff --git a/dojox/gfx/silverlight_attach.js b/dojox/gfx/silverlight_attach.js
index c5b909e..b5bd7c0 100644
--- a/dojox/gfx/silverlight_attach.js
+++ b/dojox/gfx/silverlight_attach.js
@@ -4,15 +4,19 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./silverlight"],
 	kernel.experimental("dojox.gfx.silverlight_attach");
 	
 	sl.attachNode = function(node){
-		// summary: creates a shape from a Node
-		// node: Node: an Silverlight node
+		// summary:
+		//		creates a shape from a Node
+		// node: Node
+		//		a Silverlight node
 		return null;	// not implemented
 	};
 
 	sl.attachSurface = function(node){
-		// summary: creates a surface from a Node
-		// node: Node: an Silverlight node
-		return null;	// dojox.gfx.Surface
+		// summary:
+		//		creates a surface from a Node
+		// node: Node
+		//		a Silverlight node
+		return null;	// dojox/gfx.Surface
 	};
 	
 	return sl; // return augmented silverlight api
diff --git a/dojox/gfx/svg.js b/dojox/gfx/svg.js
index 7094176..64784bd 100644
--- a/dojox/gfx/svg.js
+++ b/dojox/gfx/svg.js
@@ -1,36 +1,20 @@
-define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare", "dojo/_base/array",
-  "dojo/dom-geometry", "dojo/_base/Color", "./_base", "./shape", "./path"],
-  function(lang, win, dom, declare, arr, domGeom, Color, g, gs, pathLib){
-/*=====
-	dojox.gfx.svg = {
-	// module:
-	//		dojox/gfx/svg
-	// summary:
-	//		This the graphics rendering bridge for browsers compliant with W3C SVG1.0.
-	//		This is the preferred renderer to use for interactive and accessible graphics.
+define(["dojo/_base/lang", "dojo/_base/sniff", "dojo/_base/window", "dojo/dom", "dojo/_base/declare", "dojo/_base/array",
+  "dojo/dom-geometry", "dojo/dom-attr", "dojo/_base/Color", "./_base", "./shape", "./path"],
+function(lang, has, win, dom, declare, arr, domGeom, domAttr, Color, g, gs, pathLib){
+
+	var svg = g.svg = {
+		// summary:
+		//		This the graphics rendering bridge for browsers compliant with W3C SVG1.0.
+		//		This is the preferred renderer to use for interactive and accessible graphics.
 	};
-	pathLib.Path = dojox.gfx.path.Path;
-	pathLib.TextPath = dojox.gfx.path.TextPath;
-	svg.Shape = dojox.gfx.canvas.Shape;
-	gs.Shape = dojox.gfx.shape.Shape;
-	gs.Rect = dojox.gfx.shape.Rect;
-	gs.Ellipse = dojox.gfx.shape.Ellipse;
-	gs.Circle = dojox.gfx.shape.Circle;
-	gs.Line = dojox.gfx.shape.Line;
-	gs.PolyLine = dojox.gfx.shape.PolyLine;
-	gs.Image = dojox.gfx.shape.Image;
-	gs.Text = dojox.gfx.shape.Text;
-	gs.Surface = dojox.gfx.shape.Surface;
-  =====*/
-  var svg = g.svg = {};
 	svg.useSvgWeb = (typeof window.svgweb != "undefined");
 
 	// Need to detect iOS in order to workaround bug when
 	// touching nodes with text
-	var uagent = navigator.userAgent.toLowerCase(),
-		safMobile = uagent.search('iphone') > -1 ||
-					uagent.search('ipad') > -1 ||
-					uagent.search('ipod') > -1;
+	var uagent = navigator.userAgent,
+		safMobile = has("ios"),
+		android = has("android"),
+		textRenderingFix = has("chrome") || (android && android>=4) ? "auto" : "optimizeLegibility";// #16099, #16461
 
 	function _createElementNS(ns, nodeType){
 		// summary:
@@ -43,6 +27,14 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 			return win.doc.createElement(nodeType);
 		}
 	}
+	
+	function _setAttributeNS(node, ns, attr, value){
+		if(node.setAttributeNS){
+			return node.setAttributeNS(ns, attr, value);
+		}else{
+			return node.setAttribute(attr, value);
+		}
+	}
 
 	function _createTextNode(text){
 		if(svg.useSvgWeb){
@@ -66,15 +58,19 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 	};
 
 	svg.getRef = function(name){
-		// summary: returns a DOM Node specified by the name argument or null
-		// name: String: an SVG external reference
+		// summary:
+		//		looks up a node by its external name
+		// name: String
+		//		an SVG external reference
+		// returns:
+		//      returns a DOM Node specified by the name argument or null
 		if(!name || name == "none") return null;
 		if(name.match(/^url\(#.+\)$/)){
 			return dom.byId(name.slice(5, -1));	// Node
 		}
 		// alternative representation of a reference
 		if(name.match(/^#dojoUnique\d+$/)){
-			// we assume here that a reference was generated by dojox.gfx
+			// we assume here that a reference was generated by dojox/gfx
 			return dom.byId(name.slice(1));	// Node
 		}
 		return null;	// Node
@@ -94,16 +90,39 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 		longdashdotdot:		[8, 3, 1, 3, 1, 3]
 	};
 
-	declare("dojox.gfx.svg.Shape", gs.Shape, {
-		// summary: SVG-specific implementation of dojox.gfx.Shape methods
+	var clipCount = 0;
+
+	svg.Shape = declare("dojox.gfx.svg.Shape", gs.Shape, {
+		// summary:
+		//		SVG-specific implementation of dojox/gfx/shape.Shape methods
+
+		destroy: function(){
+			if(this.fillStyle && "type" in this.fillStyle){
+				var fill = this.rawNode.getAttribute("fill"),
+					ref  = svg.getRef(fill);
+				if(ref){
+					ref.parentNode.removeChild(ref);
+				}
+			}
+			if(this.clip){
+				var clipPathProp = this.rawNode.getAttribute("clip-path");
+				if(clipPathProp){
+					var clipNode = dom.byId(clipPathProp.match(/gfx_clip[\d]+/)[0]);
+					if(clipNode){ clipNode.parentNode.removeChild(clipNode); }
+				}
+			}
+			gs.Shape.prototype.destroy.apply(this, arguments);
+		},
 
 		setFill: function(fill){
-			// summary: sets a fill object (SVG)
-			// fill: Object: a fill object
-			//	(see dojox.gfx.defaultLinearGradient,
-			//	dojox.gfx.defaultRadialGradient,
-			//	dojox.gfx.defaultPattern,
-			//	or dojo.Color)
+			// summary:
+			//		sets a fill object (SVG)
+			// fill: Object
+			//		a fill object
+			//		(see dojox/gfx.defaultLinearGradient,
+			//		dojox/gfx.defaultRadialGradient,
+			//		dojox/gfx.defaultPattern,
+			//		or dojo/_base/Color)
 
 			if(!fill){
 				// don't fill
@@ -150,10 +169,10 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 		},
 
 		setStroke: function(stroke){
-			//	summary:
+			// summary:
 			//		sets a stroke object (SVG)
-			//	stroke: Object
-			// 		a stroke object (see dojox.gfx.defaultStroke)
+			// stroke: Object
+			//		a stroke object (see dojox/gfx.defaultStroke)
 
 			var rn = this.rawNode;
 			if(!stroke){
@@ -187,15 +206,16 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 				}
 				if(da instanceof Array){
 					da = lang._toArray(da);
-					for(var i = 0; i < da.length; ++i){
+					var i;
+					for(i = 0; i < da.length; ++i){
 						da[i] *= s.width;
 					}
 					if(s.cap != "butt"){
-						for(var i = 0; i < da.length; i += 2){
+						for(i = 0; i < da.length; i += 2){
 							da[i] -= s.width;
 							if(da[i] < 1){ da[i] = 1; }
 						}
-						for(var i = 1; i < da.length; i += 2){
+						for(i = 1; i < da.length; i += 2){
 							da[i] += s.width;
 						}
 					}
@@ -245,7 +265,7 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 				img.setAttribute("y", 0);
 				img.setAttribute("width",  f.width .toFixed(8));
 				img.setAttribute("height", f.height.toFixed(8));
-				img.setAttributeNS(svg.xmlns.xlink, "xlink:href", f.src);
+				_setAttributeNS(img, svg.xmlns.xlink, "xlink:href", f.src);
 				fill.appendChild(img);
 			}else{
 				fill.setAttribute("gradientUnits", "userSpaceOnUse");
@@ -280,9 +300,9 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 
 		setRawNode: function(rawNode){
 			// summary:
-			//	assigns and clears the underlying node that will represent this
-			//	shape. Once set, transforms, gradients, etc, can be applied.
-			//	(no fill & stroke by default)
+			//		assigns and clears the underlying node that will represent this
+			//		shape. Once set, transforms, gradients, etc, can be applied.
+			//		(no fill & stroke by default)
 			var r = this.rawNode = rawNode;
 			if(this.shape.type!="image"){
 				r.setAttribute("fill", "none");
@@ -296,19 +316,21 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 			r.setAttribute("stroke-miterlimit", 4);
 			// Bind GFX object with SVG node for ease of retrieval - that is to
 			// save code/performance to keep this association elsewhere
-			r.__gfxObject__ = this.getUID();
+			r.__gfxObject__ = this;
 		},
 
 		setShape: function(newShape){
-			// summary: sets a shape object (SVG)
-			// newShape: Object: a shape object
-			//	(see dojox.gfx.defaultPath,
-			//	dojox.gfx.defaultPolyline,
-			//	dojox.gfx.defaultRect,
-			//	dojox.gfx.defaultEllipse,
-			//	dojox.gfx.defaultCircle,
-			//	dojox.gfx.defaultLine,
-			//	or dojox.gfx.defaultImage)
+			// summary:
+			//		sets a shape object (SVG)
+			// newShape: Object
+			//		a shape object
+			//		(see dojox/gfx.defaultPath,
+			//		dojox/gfx.defaultPolyline,
+			//		dojox/gfx.defaultRect,
+			//		dojox/gfx.defaultEllipse,
+			//		dojox/gfx.defaultCircle,
+			//		dojox/gfx.defaultLine,
+			//		or dojox/gfx.defaultImage)
 			this.shape = g.makeParameters(this.shape, newShape);
 			for(var i in this.shape){
 				if(i != "type"){
@@ -322,39 +344,117 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 		// move family
 
 		_moveToFront: function(){
-			// summary: moves a shape to front of its parent's list of shapes (SVG)
+			// summary:
+			//		moves a shape to front of its parent's list of shapes (SVG)
 			this.rawNode.parentNode.appendChild(this.rawNode);
 			return this;	// self
 		},
 		_moveToBack: function(){
-			// summary: moves a shape to back of its parent's list of shapes (SVG)
+			// summary:
+			//		moves a shape to back of its parent's list of shapes (SVG)
 			this.rawNode.parentNode.insertBefore(this.rawNode, this.rawNode.parentNode.firstChild);
 			return this;	// self
+		},
+		setClip: function(clip){
+			// summary:
+			//		sets the clipping area of this shape.
+			// description:
+			//		This method overrides the dojox/gfx/shape.Shape.setClip() method.
+			// clip: Object
+			//		an object that defines the clipping geometry, or null to remove clip.
+			this.inherited(arguments);
+			var clipType = clip ? "width" in clip ? "rect" : 
+							"cx" in clip ? "ellipse" : 
+							"points" in clip ? "polyline" : "d" in clip ? "path" : null : null;
+			if(clip && !clipType){
+				return this;
+			}
+			if(clipType === "polyline"){
+				clip = lang.clone(clip);
+				clip.points = clip.points.join(",");
+			}
+			var clipNode, clipShape,
+				clipPathProp = domAttr.get(this.rawNode, "clip-path");
+			if(clipPathProp){
+				clipNode = dom.byId(clipPathProp.match(/gfx_clip[\d]+/)[0]);
+				if(clipNode){ // may be null if not in the DOM anymore
+					clipNode.removeChild(clipNode.childNodes[0]);
+				}
+			}
+			if(clip){
+				if(clipNode){
+					clipShape = _createElementNS(svg.xmlns.svg, clipType);
+					clipNode.appendChild(clipShape);
+				}else{
+					var idIndex = ++clipCount;
+					var clipId = "gfx_clip" + idIndex;
+					var clipUrl = "url(#" + clipId + ")";
+					this.rawNode.setAttribute("clip-path", clipUrl);
+					clipNode = _createElementNS(svg.xmlns.svg, "clipPath");
+					clipShape = _createElementNS(svg.xmlns.svg, clipType);
+					clipNode.appendChild(clipShape);
+					this.rawNode.parentNode.appendChild(clipNode);
+					domAttr.set(clipNode, "id", clipId);
+				}
+				domAttr.set(clipShape, clip);
+			}else{
+				//remove clip-path
+				this.rawNode.removeAttribute("clip-path");
+				if(clipNode){
+					clipNode.parentNode.removeChild(clipNode);
+				}
+			}
+			return this;
+		},
+		_removeClipNode: function(){
+			var clipNode, clipPathProp = domAttr.get(this.rawNode, "clip-path");
+			if(clipPathProp){
+				clipNode = dom.byId(clipPathProp.match(/gfx_clip[\d]+/)[0]);
+				if(clipNode){
+					clipNode.parentNode.removeChild(clipNode);
+				}
+			}
+			return clipNode;
 		}
 	});
 
-	declare("dojox.gfx.svg.Group", svg.Shape, {
-		// summary: a group shape (SVG), which can be used
-		//	to logically group shapes (e.g, to propagate matricies)
+
+	svg.Group = declare("dojox.gfx.svg.Group", svg.Shape, {
+		// summary:
+		//		a group shape (SVG), which can be used
+		//		to logically group shapes (e.g, to propagate matricies)
 		constructor: function(){
 			gs.Container._init.call(this);
 		},
 		setRawNode: function(rawNode){
-			// summary: sets a raw SVG node to be used by this shape
-			// rawNode: Node: an SVG node
+			// summary:
+			//		sets a raw SVG node to be used by this shape
+			// rawNode: Node
+			//		an SVG node
 			this.rawNode = rawNode;
 			// Bind GFX object with SVG node for ease of retrieval - that is to
 			// save code/performance to keep this association elsewhere
-			this.rawNode.__gfxObject__ = this.getUID();
+			this.rawNode.__gfxObject__ = this;
+		},
+		destroy: function(){
+			// summary:
+			//		Releases all internal resources owned by this shape. Once this method has been called,
+			//		the instance is considered disposed and should not be used anymore.
+			this.clear(true);
+			// avoid this.inherited
+			svg.Shape.prototype.destroy.apply(this, arguments);
 		}
 	});
 	svg.Group.nodeType = "g";
 
-	declare("dojox.gfx.svg.Rect", [svg.Shape, gs.Rect], {
-		// summary: a rectangle shape (SVG)
+	svg.Rect = declare("dojox.gfx.svg.Rect", [svg.Shape, gs.Rect], {
+		// summary:
+		//		a rectangle shape (SVG)
 		setShape: function(newShape){
-			// summary: sets a rectangle shape object (SVG)
-			// newShape: Object: a rectangle shape object
+			// summary:
+			//		sets a rectangle shape object (SVG)
+			// newShape: Object
+			//		a rectangle shape object
 			this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			for(var i in this.shape){
@@ -371,23 +471,24 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 	});
 	svg.Rect.nodeType = "rect";
 
-	declare("dojox.gfx.svg.Ellipse", [svg.Shape, gs.Ellipse], {});
+	svg.Ellipse = declare("dojox.gfx.svg.Ellipse", [svg.Shape, gs.Ellipse], {});
 	svg.Ellipse.nodeType = "ellipse";
 
-	declare("dojox.gfx.svg.Circle", [svg.Shape, gs.Circle], {});
+	svg.Circle = declare("dojox.gfx.svg.Circle", [svg.Shape, gs.Circle], {});
 	svg.Circle.nodeType = "circle";
 
-	declare("dojox.gfx.svg.Line", [svg.Shape, gs.Line], {});
+	svg.Line = declare("dojox.gfx.svg.Line", [svg.Shape, gs.Line], {});
 	svg.Line.nodeType = "line";
 
-	declare("dojox.gfx.svg.Polyline", [svg.Shape, gs.Polyline], {
-		// summary: a polyline/polygon shape (SVG)
+	svg.Polyline = declare("dojox.gfx.svg.Polyline", [svg.Shape, gs.Polyline], {
+		// summary:
+		//		a polyline/polygon shape (SVG)
 		setShape: function(points, closed){
-			// summary: sets a polyline/polygon shape object (SVG)
-			// points: Object: a polyline/polygon shape object
+			// summary:
+			//		sets a polyline/polygon shape object (SVG)
+			// points: Object|Array
+			//		a polyline/polygon shape object, or an array of points
 			if(points && points instanceof Array){
-				// branch
-				// points: Array: an array of points
 				this.shape = g.makeParameters(this.shape, { points: points });
 				if(closed && this.shape.points.length){
 					this.shape.points.push(this.shape.points[0]);
@@ -407,11 +508,14 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 	});
 	svg.Polyline.nodeType = "polyline";
 
-	declare("dojox.gfx.svg.Image", [svg.Shape, gs.Image], {
-		// summary: an image (SVG)
+	svg.Image = declare("dojox.gfx.svg.Image", [svg.Shape, gs.Image], {
+		// summary:
+		//		an image (SVG)
 		setShape: function(newShape){
-			// summary: sets an image shape object (SVG)
-			// newShape: Object: an image shape object
+			// summary:
+			//		sets an image shape object (SVG)
+			// newShape: Object
+			//		an image shape object
 			this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var rawNode = this.rawNode;
@@ -421,20 +525,23 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 				}
 			}
 			rawNode.setAttribute("preserveAspectRatio", "none");
-			rawNode.setAttributeNS(svg.xmlns.xlink, "xlink:href", this.shape.src);
+			_setAttributeNS(rawNode, svg.xmlns.xlink, "xlink:href", this.shape.src);
 			// Bind GFX object with SVG node for ease of retrieval - that is to
 			// save code/performance to keep this association elsewhere
-			rawNode.__gfxObject__ = this.getUID();
+			rawNode.__gfxObject__ = this;
 			return this;	// self
 		}
 	});
 	svg.Image.nodeType = "image";
 
-	declare("dojox.gfx.svg.Text", [svg.Shape, gs.Text], {
-		// summary: an anchored text (SVG)
+	svg.Text = declare("dojox.gfx.svg.Text", [svg.Shape, gs.Text], {
+		// summary:
+		//		an anchored text (SVG)
 		setShape: function(newShape){
-			// summary: sets a text shape object (SVG)
-			// newShape: Object: a text shape object
+			// summary:
+			//		sets a text shape object (SVG)
+			// newShape: Object
+			//		a text shape object
 			this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var r = this.rawNode, s = this.shape;
@@ -444,7 +551,7 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 			r.setAttribute("text-decoration", s.decoration);
 			r.setAttribute("rotate", s.rotated ? 90 : 0);
 			r.setAttribute("kerning", s.kerning ? "auto" : 0);
-			r.setAttribute("text-rendering", "optimizeLegibility");
+			r.setAttribute("text-rendering", textRenderingFix);
 
 			// update the text content
 			if(r.firstChild){
@@ -455,7 +562,8 @@ define(["dojo/_base/lang", "dojo/_base/window", "dojo/dom","dojo/_base/declare",
 			return this;	// self
 		},
 		getTextWidth: function(){
-			// summary: get the text width in pixels
+			// summary:
+			//		get the text width in pixels
 			var rawNode = this.rawNode,
 				oldParent = rawNode.parentNode,
 				_measurementNode = rawNode.cloneNode(true);
@@ -478,23 +586,41 @@ else
 			}
 			oldParent.removeChild(_measurementNode);
 			return _width;
+		},
+		getBoundingBox: function(){
+			var s = this.getShape(), bbox = null;
+			if(s.text){
+				// try/catch the FF native getBBox error.
+				try {
+					bbox = this.rawNode.getBBox();
+				} catch (e) {
+					// under FF when the node is orphan (all other browsers return a 0ed bbox.
+					bbox = {x:0, y:0, width:0, height:0};
+				}
+			}
+			return bbox;
 		}
 	});
 	svg.Text.nodeType = "text";
 
-	declare("dojox.gfx.svg.Path", [svg.Shape, pathLib.Path], {
-		// summary: a path shape (SVG)
+	svg.Path = declare("dojox.gfx.svg.Path", [svg.Shape, pathLib.Path], {
+		// summary:
+		//		a path shape (SVG)
 		_updateWithSegment: function(segment){
-			// summary: updates the bounding box of path with new segment
-			// segment: Object: a segment
+			// summary:
+			//		updates the bounding box of path with new segment
+			// segment: Object
+			//		a segment
 			this.inherited(arguments);
 			if(typeof(this.shape.path) == "string"){
 				this.rawNode.setAttribute("d", this.shape.path);
 			}
 		},
 		setShape: function(newShape){
-			// summary: forms a path using a shape (SVG)
-			// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
+			// summary:
+			//		forms a path using a shape (SVG)
+			// newShape: Object
+			//		an SVG path string or a path object (see dojox/gfx.defaultPath)
 			this.inherited(arguments);
 			if(this.shape.path){
 				this.rawNode.setAttribute("d", this.shape.path);
@@ -506,17 +632,22 @@ else
 	});
 	svg.Path.nodeType = "path";
 
-	declare("dojox.gfx.svg.TextPath", [svg.Shape, pathLib.TextPath], {
-		// summary: a textpath shape (SVG)
+	svg.TextPath = declare("dojox.gfx.svg.TextPath", [svg.Shape, pathLib.TextPath], {
+		// summary:
+		//		a textpath shape (SVG)
 		_updateWithSegment: function(segment){
-			// summary: updates the bounding box of path with new segment
-			// segment: Object: a segment
+			// summary:
+			//		updates the bounding box of path with new segment
+			// segment: Object
+			//		a segment
 			this.inherited(arguments);
 			this._setTextPath();
 		},
 		setShape: function(newShape){
-			// summary: forms a path using a shape (SVG)
-			// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
+			// summary:
+			//		forms a path using a shape (SVG)
+			// newShape: Object
+			//		an SVG path string or a path object (see dojox/gfx.defaultPath)
 			this.inherited(arguments);
 			this._setTextPath();
 			return this;	// self
@@ -540,7 +671,7 @@ else
 					var id = g._base._getUniqueId();
 					path.setAttribute("id", id);
 					defs.appendChild(path);
-					r.firstChild.setAttributeNS(svg.xmlns.xlink, "xlink:href", "#" + id);
+					_setAttributeNS(r.firstChild, svg.xmlns.xlink, "xlink:href", "#" + id);
 				}
 			}
 			if(path){
@@ -583,26 +714,43 @@ else
 	});
 	svg.TextPath.nodeType = "text";
 
-	declare("dojox.gfx.svg.Surface", gs.Surface, {
-		// summary: a surface object to be used for drawings (SVG)
+	// Fix for setDimension bug:
+	// http://bugs.dojotoolkit.org/ticket/16100
+	// (https://code.google.com/p/chromium/issues/detail?id=162628)
+	var hasSvgSetAttributeBug = (function(){ var matches = /WebKit\/(\d*)/.exec(uagent); return matches ? matches[1] : 0})() > 534;
+
+	svg.Surface = declare("dojox.gfx.svg.Surface", gs.Surface, {
+		// summary:
+		//		a surface object to be used for drawings (SVG)
 		constructor: function(){
 			gs.Container._init.call(this);
 		},
 		destroy: function(){
+			// no need to call svg.Container.clear to remove the children raw
+			// nodes since the surface raw node will be removed. So, only dispose at gfx level	
+			gs.Container.clear.call(this, true); 
 			this.defNode = null;	// release the external reference
 			this.inherited(arguments);
 		},
 		setDimensions: function(width, height){
-			// summary: sets the width and height of the rawNode
-			// width: String: width of surface, e.g., "100px"
-			// height: String: height of surface, e.g., "100px"
+			// summary:
+			//		sets the width and height of the rawNode
+			// width: String
+			//		width of surface, e.g., "100px"
+			// height: String
+			//		height of surface, e.g., "100px"
 			if(!this.rawNode){ return this; }
 			this.rawNode.setAttribute("width",  width);
 			this.rawNode.setAttribute("height", height);
+			if(hasSvgSetAttributeBug){
+				this.rawNode.style.width =  width;
+				this.rawNode.style.height =  height;
+			}
 			return this;	// self
 		},
 		getDimensions: function(){
-			// summary: returns an object with properties "width" and "height"
+			// summary:
+			//		returns an object with properties "width" and "height"
 			var t = this.rawNode ? {
 				width:  g.normalizedLength(this.rawNode.getAttribute("width")),
 				height: g.normalizedLength(this.rawNode.getAttribute("height"))} : null;
@@ -611,10 +759,16 @@ else
 	});
 
 	svg.createSurface = function(parentNode, width, height){
-		// summary: creates a surface (SVG)
-		// parentNode: Node: a parent node
-		// width: String: width of surface, e.g., "100px"
-		// height: String: height of surface, e.g., "100px"
+		// summary:
+		//		creates a surface (SVG)
+		// parentNode: Node
+		//		a parent node
+		// width: String|Number
+		//		width of surface, e.g., "100px" or 100
+		// height: String|Number
+		//		height of surface, e.g., "100px" or 100
+		// returns: dojox/gfx/shape.Surface
+		//     newly created surface
 
 		var s = new svg.Surface();
 		s.rawNode = _createElementNS(svg.xmlns.svg, "svg");
@@ -633,14 +787,17 @@ else
 		s._parent = dom.byId(parentNode);
 		s._parent.appendChild(s.rawNode);
 
-		return s;	// dojox.gfx.Surface
+		g._base._fixMsTouchAction(s);
+
+		return s;	// dojox/gfx.Surface
 	};
 
 	// Extenders
 
 	var Font = {
 		_setFont: function(){
-			// summary: sets a font object (SVG)
+			// summary:
+			//		sets a font object (SVG)
 			var f = this.fontStyle;
 			// next line doesn't work in Firefox 2 or Opera 9
 			//this.rawNode.setAttribute("font", dojox.gfx.makeFontString(this.fontStyle));
@@ -654,20 +811,30 @@ else
 
 	var C = gs.Container, Container = {
 		openBatch: function() {
-			// summary: starts a new batch, subsequent new child shapes will be held in
-			//	the batch instead of appending to the container directly
-			this.fragment = _createFragment();
+			// summary:
+			//		starts a new batch, subsequent new child shapes will be held in
+			//		the batch instead of appending to the container directly
+			if(!this._batch){
+				this.fragment = _createFragment();
+			}
+			++this._batch;
+			return this;
 		},
 		closeBatch: function() {
-			// summary: submits the current batch, append all pending child shapes to DOM
-			if (this.fragment) {
+			// summary:
+			//		submits the current batch, append all pending child shapes to DOM
+			this._batch = this._batch > 0 ? --this._batch : 0;
+			if (this.fragment && !this._batch) {
 				this.rawNode.appendChild(this.fragment);
 				delete this.fragment;
 			}
+			return this;
 		},
 		add: function(shape){
-			// summary: adds a shape to a group/surface
-			// shape: dojox.gfx.Shape: an VML shape object
+			// summary:
+			//		adds a shape to a group/surface
+			// shape: dojox/gfx/shape.Shape
+			//		an VML shape object
 			if(this != shape.getParent()){
 				if (this.fragment) {
 					this.fragment.appendChild(shape.rawNode);
@@ -675,13 +842,18 @@ else
 					this.rawNode.appendChild(shape.rawNode);
 				}
 				C.add.apply(this, arguments);
+				// update clipnode with new parent
+				shape.setClip(shape.clip);
 			}
 			return this;	// self
 		},
 		remove: function(shape, silently){
-			// summary: remove a shape from a group/surface
-			// shape: dojox.gfx.Shape: an VML shape object
-			// silently: Boolean?: if true, regenerate a picture
+			// summary:
+			//		remove a shape from a group/surface
+			// shape: dojox/gfx/shape.Shape
+			//		an VML shape object
+			// silently: Boolean?
+			//		if true, regenerate a picture
 			if(this == shape.getParent()){
 				if(this.rawNode == shape.rawNode.parentNode){
 					this.rawNode.removeChild(shape.rawNode);
@@ -689,12 +861,15 @@ else
 				if(this.fragment && this.fragment == shape.rawNode.parentNode){
 					this.fragment.removeChild(shape.rawNode);
 				}
+				// remove clip node from parent 
+				shape._removeClipNode();
 				C.remove.apply(this, arguments);
 			}
 			return this;	// self
 		},
 		clear: function(){
-			// summary: removes all shapes from a group/surface
+			// summary:
+			//		removes all shapes from a group/surface
 			var r = this.rawNode;
 			while(r.lastChild){
 				r.removeChild(r.lastChild);
@@ -708,16 +883,21 @@ else
 			}
 			return C.clear.apply(this, arguments);
 		},
+		getBoundingBox: C.getBoundingBox,
 		_moveChildToFront: C._moveChildToFront,
 		_moveChildToBack:  C._moveChildToBack
 	};
 
 	var Creator = {
-		// summary: SVG shape creators
+		// summary:
+		//		SVG shape creators
 		createObject: function(shapeType, rawShape){
-			// summary: creates an instance of the passed shapeType class
-			// shapeType: Function: a class constructor to create an instance of
-			// rawShape: Object: properties to be passed in to the classes "setShape" method
+			// summary:
+			//		creates an instance of the passed shapeType class
+			// shapeType: Function
+			//		a class constructor to create an instance of
+			// rawShape: Object
+			//		properties to be passed in to the classes "setShape" method
 			if(!this.rawNode){ return null; }
 			var shape = new shapeType(),
 				node = _createElementNS(svg.xmlns.svg, shapeType.nodeType);
@@ -726,7 +906,7 @@ else
 			shape.setShape(rawShape);
 			// rawNode.appendChild() will be done inside this.add(shape) below
 			this.add(shape);
-			return shape;	// dojox.gfx.Shape
+			return shape;	// dojox/gfx/shape.Shape
 		}
 	};
 
@@ -744,18 +924,18 @@ else
 	// Mouse/Touch event
 	svg.fixTarget = function(event, gfxElement) {
 		// summary:
-		//     Adds the gfxElement to event.gfxTarget if none exists. This new
-		//     property will carry the GFX element associated with this event.
+		//		Adds the gfxElement to event.gfxTarget if none exists. This new
+		//		property will carry the GFX element associated with this event.
 		// event: Object
-		//     The current input event (MouseEvent or TouchEvent)
+		//		The current input event (MouseEvent or TouchEvent)
 		// gfxElement: Object
-		//     The GFX target element
+		//		The GFX target element
 		if (!event.gfxTarget) {
 			if (safMobile && event.target.wholeText) {
 				// Workaround iOS bug when touching text nodes
-				event.gfxTarget = gs.byId(event.target.parentElement.__gfxObject__);
+				event.gfxTarget = event.target.parentElement.__gfxObject__;
 			} else {
-				event.gfxTarget = gs.byId(event.target.__gfxObject__);
+				event.gfxTarget = event.target.__gfxObject__;
 			}
 		}
 		return true;
diff --git a/dojox/gfx/svg_attach.js b/dojox/gfx/svg_attach.js
index 7161c9c..02a47fa 100644
--- a/dojox/gfx/svg_attach.js
+++ b/dojox/gfx/svg_attach.js
@@ -4,8 +4,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/C
 	kernel.experimental("dojox.gfx.svg_attach");
 	
 	svg.attachNode = function(node){
-		// summary: creates a shape from a Node
-		// node: Node: an SVG node
+		// summary:
+		//		creates a shape from a Node
+		// node: Node
+		//		an SVG node
 		if(!node){
 			return null;
 		}
@@ -60,25 +62,29 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/C
 			attachStroke(s);
 		}
 		attachTransform(s);
-		return s;	// dojox.gfx.Shape
+		return s;	// dojox/gfx/shape.Shape
 	};
 
 	svg.attachSurface = function(node){
-		// summary: creates a surface from a Node
-		// node: Node: an SVG node
+		// summary:
+		//		creates a surface from a Node
+		// node: Node
+		//		an SVG node
 		var s = new svg.Surface();
 		s.rawNode = node;
 		var def_elems = node.getElementsByTagName("defs");
 		if(def_elems.length == 0){
-			return null;	// dojox.gfx.Surface
+			return null;	// dojox/gfx.Surface
 		}
 		s.defNode = def_elems[0];
-		return s;	// dojox.gfx.Surface
+		return s;	// dojox/gfx.Surface
 	};
 
 	function attachFill(object){
-		// summary: deduces a fill style from a node.
-		// object: dojox.gfx.Shape: an SVG shape
+		// summary:
+		//		deduces a fill style from a node.
+		// object: dojox/gfx/shape.Shape
+		//		an SVG shape
 		var fill = object.rawNode.getAttribute("fill");
 		if(fill == "none"){
 			object.fillStyle = null;
@@ -131,8 +137,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/C
 	}
 
 	function attachStroke(object){
-		// summary: deduces a stroke style from a node.
-		// object: dojox.gfx.Shape: an SVG shape
+		// summary:
+		//		deduces a stroke style from a node.
+		// object: dojox/gfx/shape.Shape
+		//		an SVG shape
 		var rawNode = object.rawNode, stroke = rawNode.getAttribute("stroke");
 		if(stroke == null || stroke == "none"){
 			object.strokeStyle = null;
@@ -154,8 +162,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/C
 	}
 
 	function attachTransform(object){
-		// summary: deduces a transformation matrix from a node.
-		// object: dojox.gfx.Shape: an SVG shape
+		// summary:
+		//		deduces a transformation matrix from a node.
+		// object: dojox/gfx/shape.Shape
+		//		an SVG shape
 		var matrix = object.rawNode.getAttribute("transform");
 		if(matrix.match(/^matrix\(.+\)$/)){
 			var t = matrix.slice(7, -1).split(",");
@@ -170,8 +180,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/C
 	}
 
 	function attachFont(object){
-		// summary: deduces a font style from a Node.
-		// object: dojox.gfx.Shape: an SVG shape
+		// summary:
+		//		deduces a font style from a Node.
+		// object: dojox/gfx/shape.Shape
+		//		an SVG shape
 		var fontStyle = object.fontStyle = lang.clone(g.defaultFont),
 			r = object.rawNode;
 		fontStyle.style = r.getAttribute("font-style");
@@ -182,9 +194,12 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/C
 	}
 
 	function attachShape(object, def){
-		// summary: builds a shape from a node.
-		// object: dojox.gfx.Shape: an SVG shape
-		// def: Object: a default shape template
+		// summary:
+		//		builds a shape from a node.
+		// object: dojox/gfx/shape.Shape
+		//		an SVG shape
+		// def: Object
+		//		a default shape template
 		var shape = object.shape = lang.clone(def), r = object.rawNode;
 		for(var i in shape) {
 			shape[i] = r.getAttribute(i);
@@ -192,15 +207,19 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/C
 	}
 
 	function attachRect(object){
-		// summary: builds a rectangle shape from a node.
-		// object: dojox.gfx.Shape: an SVG shape
+		// summary:
+		//		builds a rectangle shape from a node.
+		// object: dojox/gfx/shape.Shape
+		//		an SVG shape
 		attachShape(object, g.defaultRect);
 		object.shape.r = Math.min(object.rawNode.getAttribute("rx"), object.rawNode.getAttribute("ry"));
 	}
 
 	function attachText(object){
-		// summary: builds a text shape from a node.
-		// object: dojox.gfx.Shape: an SVG shape
+		// summary:
+		//		builds a text shape from a node.
+		// object: dojox/gfx/shape.Shape
+		//		an SVG shape
 		var shape = object.shape = lang.clone(g.defaultText),
 			r = object.rawNode;
 		shape.x = r.getAttribute("x");
@@ -213,8 +232,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array","dojo/_base/C
 	}
 
 	function attachTextPath(object){
-		// summary: builds a textpath shape from a node.
-		// object: dojox.gfx.Shape: an SVG shape
+		// summary:
+		//		builds a textpath shape from a node.
+		// object: dojox/gfx/shape.Shape
+		//		an SVG shape
 		var shape = object.shape = lang.clone(g.defaultTextPath),
 			r = object.rawNode;
 		shape.align = r.getAttribute("text-anchor");
diff --git a/dojox/gfx/svgext.js b/dojox/gfx/svgext.js
new file mode 100644
index 0000000..e8ab801
--- /dev/null
+++ b/dojox/gfx/svgext.js
@@ -0,0 +1,225 @@
+define([
+	"dojo/dom",
+	"dojo/_base/array",
+	"dojo/_base/window",
+	"./_base",
+	"./svg"], 
+	function(dom, array, win, gfx, svg){
+
+	/*=====
+	return {
+		// summary:
+		//		A module that adds svg-specific features to the gfx api. You should require this module
+		//		when your application specifically targets the SVG renderer.
+	}
+	=====*/
+
+	var svgext = gfx.svgext = {};
+	var toIgnore = {
+		primitives:null,
+		tag:null,
+		children:null
+	};
+
+	function buildFilterPrimitivesDOM(primitive, parentNode){
+		var node =  parentNode.ownerDocument.createElementNS(svg.xmlns.svg, primitive.tag);
+		parentNode.appendChild(node);
+		for(var p in primitive){
+			if(!(p in toIgnore)){
+				node.setAttribute(p, primitive[p]);
+			}
+		}
+		if(primitive.children){
+			array.forEach(primitive.children, function(f){buildFilterPrimitivesDOM(f, node);});
+		}
+		return node;
+	}
+
+	/*=====
+	declare("dojox.gfx.svgext.__FilterPrimitiveArgs", null, {
+		// summary:
+		//		Represents an SVG filter primitive.
+		// description:
+		//		In addition to the following properties, a FilterPrimitiveArgs should define the properties specific to
+		//		this primitive, as defined by the SVG spec.
+		// example:
+		//		Define a simple feGaussianBlur primitive:
+		//	|	var blurPrimitive = {
+		//	|		"tag": "feGaussianBlur",
+		//	|		"in": "SourceAlpha",
+		//	|		"stdDeviation":"4",
+		//	|		"result":"blur"
+		//	|	};
+		//
+		// example:
+		//		Define a feSpecularLighting primitive with one fePointLight child
+		//	|	var lighting = {
+		//	|		"tag": "feSpecularLighting",
+		//	|		"in":"blur",
+		//	|		"surfaceScale":5,
+		//	|		"specularConstant":.75,
+		//	|		"specularExponent":20,
+		//	|		"lighting-color":"#bbbbbb",
+		//	|		"result":"specOut"
+		//	|		"children": [
+		//	|			"tag": "fePointLight"
+		//	|			"x":-5000,
+		//	|			"y":-10000,
+		//	|			"z":20000
+		//	|		]
+		//	|	};
+
+		// tag: String?
+		//		The type of the primitive, as specified by the SVG spec (http://www.w3.org/TR/SVG/filters.html)
+		tag: null,
+
+		// children: dojox.gfx.svgext.__FilterPrimitiveArgs[]?
+		//		An array of child primitives, if any.
+		children: null
+	});
+	=====*/
+
+
+	/*=====
+	declare("dojox.gfx.svgext.__FilterArgs", null, {
+		// summary:
+		//		The filter arguments passed to the dojox/gfx/svgext/Shape.setFilter method.
+		// description:
+		//		An object defining the properties of a SVG Filter.
+		// example:
+		//		Define a drop shadow filter:
+		//	|	var filter = {
+		//	|		"id": "fastSmallDropShadow",
+		//	|		"x": "-10%",
+		//	|		"y": "-10%",
+		//	|		"width": "125%",
+		//	|		"height": "125%",
+		//	|		"primitives": [{
+		//	|			"tag": "feColorMatrix",
+		//	|			"in": "SourceAlpha",
+		//	|			"type": "matrix",
+		//	|			"result": "grey",
+		//	|			"values": "0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0,0,0,0.7,0"
+		//	|		},{
+		//	|			"tag": "feOffset",
+		//	|			"dx": 3,
+		//	|			"dy": 3,
+		//	|			"result": "offsetBlur"
+		//	|		},{
+		//	|			"tag": "feMerge",
+		//	|			"children":[{
+		//	|				"tag": "feMergeNode",
+		//	|				"in": "offsetBlur"
+		//	|			},{
+		//	|				"tag": "feMergeNode",
+		//	|				"in": "SourceGraphic"
+		//	|			}]
+		//	|		}]
+		//	|	};
+
+
+		// id: String?
+		//		The filter identifier. If none is provided, a generated id will be used.
+		id: null,
+
+		// filterUnits: String?
+		//		The coordinate system of the filter. Default is "userSpaceOnUse".
+		filterUnits: "userSpaceOnUse",
+
+		// primitives: dojox.gfx.svgext.__FilterPrimitiveArgs[]
+		//		An array of filter primitives that define this filter.
+		primitives: []
+	});
+	=====*/
+
+	svg.Shape.extend({
+		addRenderingOption: function(/*String*/option, /*String*/value){
+			// summary:
+			//		Adds the specified SVG rendering option on this shape.
+			// option: String
+			//		The name of the rendering option to add to this shape, as specified by the
+			//		SVG specification (http://www.w3.org/TR/SVG/painting.html#RenderingProperties)
+			// value: String
+			//		the option value.
+			this.rawNode.setAttribute(option, value);
+			return this; // self
+		},
+
+		setFilter: function(/*dojox.gfx.svgext.__FilterArgs*/filter){
+			// summary:
+			//		Sets the specified SVG Filter on this shape.
+			// filter: dojox.gfx.svgext.__FilterArgs
+			//		An object that defines the filter properties. Note that in order to make the creation of such filter
+			//		easier, the dojox/gfx/filters module defines both a simple API to easily create filter objects and
+			//		also a set of predefined filters like drop shadows, blurs, textures effects (among others).
+			// example:
+			//		Sets a drop shadow filter:
+			//	|	var filter = {
+			//	|		"id": "fastSmallDropShadow",
+			//	|		"x": "-10%",
+			//	|		"y": "-10%",
+			//	|		"width": "125%",
+			//	|		"height": "125%",
+			//	|		"primitives": [{
+			//	|			"tag": "feColorMatrix",
+			//	|			"in": "SourceAlpha",
+			//	|			"type": "matrix",
+			//	|			"result": "grey",
+			//	|			"values": "0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0.2125,0.7154,0.0721,0,0,0,0,0,0.7,0"
+			//	|		},{
+			//	|			"tag": "feOffset",
+			//	|			"dx": 3,
+			//	|			"dy": 3,
+			//	|			"result": "offsetBlur"
+			//	|		},{
+			//	|			"tag": "feMerge",
+			//	|			"in": "offsetBlur",
+			//	|			"in2": "SourceGraphic"
+			//	|		}]
+			//	|	};
+			//	|	var shape = surface.createRect().setFilter(filter);
+			//
+			// example:
+			//		Sets a predefined filter from the dojox/gfx/filters module:
+			//	|	require(["dojox/gfx/filters","dojox/gfx/svgext",...], function(filters, svgext){
+			//	|		...
+			//	|		var filter = filters.textures.paper({"id":"myFilter","x":0,"y":0,"width":100,"height":100});
+			//	|		var shape = surface.createRect().setFilter(filter);
+
+			if(!filter){
+				this.rawNode.removeAttribute("filter");
+				this.filter = null;
+				return this;
+			}
+			this.filter = filter;
+			filter.id = filter.id || gfx._base._getUniqueId();
+			var filterNode = dom.byId(filter.id);
+			if(!filterNode){
+				filterNode = this.rawNode.ownerDocument.createElementNS(svg.xmlns.svg, "filter");
+				filterNode.setAttribute("filterUnits", "userSpaceOnUse");
+				for(var p in filter){
+					if(!(p in toIgnore)){
+						filterNode.setAttribute(p, filter[p]);
+					}
+				}
+				array.forEach(filter.primitives, function(p){
+					buildFilterPrimitivesDOM(p, filterNode);
+				});
+				var surface = this._getParentSurface();
+				if(surface){
+					var defs = surface.defNode;
+					defs.appendChild(filterNode);
+				}
+			}
+			this.rawNode.setAttribute("filter", "url(#"+filter.id+")");
+			return this;
+		},
+
+		getFilter: function(){
+			// summary:
+			//		Gets the shape SVG Filter.
+			return this.filter;
+		}
+	});
+	return svgext;
+});
diff --git a/dojox/gfx/tests/_gfxBidiSupport/canvas/dynamicallyChangeTextCanvas.html b/dojox/gfx/tests/_gfxBidiSupport/canvas/dynamicallyChangeTextCanvas.html
index bfef3ac..caba432 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/canvas/dynamicallyChangeTextCanvas.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/canvas/dynamicallyChangeTextCanvas.html
@@ -6,7 +6,7 @@
 			@import "../../../../../dojo/resources/dojo.css";
 			@import "../../../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, gfxRenderer:'canvas'"></script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, gfxRenderer:'canvas'"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/canvas/inheritFromSurfaceCanvas.html b/dojox/gfx/tests/_gfxBidiSupport/canvas/inheritFromSurfaceCanvas.html
index f9b72f5..ec88eb7 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/canvas/inheritFromSurfaceCanvas.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/canvas/inheritFromSurfaceCanvas.html
@@ -6,7 +6,7 @@
 			@import "../../../../../dijit/tests/css/dijitTests.css";
 		</style>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, gfxRenderer:'canvas'"></script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, gfxRenderer:'canvas'"></script>
 		<script type="text/javascript">
 
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/canvas/test_SurfaceGroupCanvas.html b/dojox/gfx/tests/_gfxBidiSupport/canvas/test_SurfaceGroupCanvas.html
index 652d724..441281a 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/canvas/test_SurfaceGroupCanvas.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/canvas/test_SurfaceGroupCanvas.html
@@ -6,7 +6,7 @@
 			@import "../../../../../dijit/tests/css/dijitTests.css";
 		</style>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, gfxRenderer:'canvas'"></script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, gfxRenderer:'canvas'"></script>
 		<script type="text/javascript">
 
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/canvas/textBidiCanvas.html b/dojox/gfx/tests/_gfxBidiSupport/canvas/textBidiCanvas.html
index a7ceaba..53c22c6 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/canvas/textBidiCanvas.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/canvas/textBidiCanvas.html
@@ -6,7 +6,7 @@
 			@import "../../../../../dojo/resources/dojo.css";
 			@import "../../../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, gfxRenderer:'canvas'"></script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, gfxRenderer:'canvas'"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/dynamicallyChangeText.html b/dojox/gfx/tests/_gfxBidiSupport/dynamicallyChangeText.html
index 5741fac..5e94812 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/dynamicallyChangeText.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/dynamicallyChangeText.html
@@ -6,7 +6,7 @@
 			@import "../../../../dojo/resources/dojo.css";
 			@import "../../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/inheritFromSurface.html b/dojox/gfx/tests/_gfxBidiSupport/inheritFromSurface.html
index e4f0325..9c79215 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/inheritFromSurface.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/inheritFromSurface.html
@@ -6,7 +6,7 @@
 			@import "../../../../dijit/tests/css/dijitTests.css";
 		</style>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/silverlight/dynamicallyChangeTextSilverlight.html b/dojox/gfx/tests/_gfxBidiSupport/silverlight/dynamicallyChangeTextSilverlight.html
index c72635c..541bcca 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/silverlight/dynamicallyChangeTextSilverlight.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/silverlight/dynamicallyChangeTextSilverlight.html
@@ -6,7 +6,7 @@
 			@import "../../../../../dojo/resources/dojo.css";
 			@import "../../../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, gfxRenderer:'silverlight'"></script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, gfxRenderer:'silverlight'"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/silverlight/inheritFromSurfaceSilverlight.html b/dojox/gfx/tests/_gfxBidiSupport/silverlight/inheritFromSurfaceSilverlight.html
index 424bab2..427885a 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/silverlight/inheritFromSurfaceSilverlight.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/silverlight/inheritFromSurfaceSilverlight.html
@@ -6,7 +6,7 @@
 			@import "../../../../../dijit/tests/css/dijitTests.css";
 		</style>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, gfxRenderer:'silverlight'"></script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, gfxRenderer:'silverlight'"></script>
 		<script type="text/javascript">
 
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/silverlight/test_SurfaceGroupSilverlight.html b/dojox/gfx/tests/_gfxBidiSupport/silverlight/test_SurfaceGroupSilverlight.html
index 09062ff..777db4a 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/silverlight/test_SurfaceGroupSilverlight.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/silverlight/test_SurfaceGroupSilverlight.html
@@ -6,7 +6,7 @@
 			@import "../../../../../dijit/tests/css/dijitTests.css";
 		</style>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, gfxRenderer:'silverlight'"></script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, gfxRenderer:'silverlight'"></script>
 		<script type="text/javascript">
 
 			dojo.require("dojox.gfx");
@@ -143,8 +143,8 @@
 					},
 					function changeGroupTextDir(){
 						// add doesn't work for silverlight because of the rawNode call.
-//						g3.add(t5);
-//						g3.add(t2);
+//					g3.add(t5);
+//					g3.add(t2);
 						
 						g2.setTextDir("rtl");
 
@@ -152,10 +152,10 @@
 						// son of g2
 						doh.is("rtl", g3.getTextDir(), "g3.getTextDir"); 
 						
-//						doh.is("rtl", t2.textDir, "t2.getTextDir"); 
+//					doh.is("rtl", t2.textDir, "t2.getTextDir");
 						doh.is("rtl", t3.textDir, "t3.getTextDir"); 
 						
-//						doh.is("rtl", t5.textDir, "t5.getTextDir"); 
+//					doh.is("rtl", t5.textDir, "t5.getTextDir");
 					}
 				]);
 
diff --git a/dojox/gfx/tests/_gfxBidiSupport/silverlight/textBidiSilverlight.html b/dojox/gfx/tests/_gfxBidiSupport/silverlight/textBidiSilverlight.html
index 461f91a..e31ba39 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/silverlight/textBidiSilverlight.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/silverlight/textBidiSilverlight.html
@@ -6,7 +6,7 @@
 			@import "../../../../../dojo/resources/dojo.css";
 			@import "../../../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, gfxRenderer:'silverlight'"></script>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, gfxRenderer:'silverlight'"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/dynamicallyChangeTextSvgWeb.html b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/dynamicallyChangeTextSvgWeb.html
index 5c92bb3..8d1163c 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/dynamicallyChangeTextSvgWeb.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/dynamicallyChangeTextSvgWeb.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="../../svgweb/svgweb/src/svg.js" data-path="../../svgweb/svgweb/src"></script>
-<script src="../../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 
 		<script type="text/javascript">
diff --git a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/inheritFromSurfaceSvgWeb.html b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/inheritFromSurfaceSvgWeb.html
index 90e173e..7c8b719 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/inheritFromSurfaceSvgWeb.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/inheritFromSurfaceSvgWeb.html
@@ -9,7 +9,7 @@
 		<!-- SVGWEB { -->
 		<meta name="svg.render.forceflash" content="true"/>
 		<script src="../../svgweb/svgweb/src/svg.js" data-path="../../svgweb/svgweb/src"></script>
-		<script src="../../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+		<script src="../../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 		<!-- } -->
 		<script type="text/javascript">
 
diff --git a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/test_SurfaceGroupSvgWeb.html b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/test_SurfaceGroupSvgWeb.html
index d2c28e7..7301426 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/test_SurfaceGroupSvgWeb.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/test_SurfaceGroupSvgWeb.html
@@ -9,7 +9,7 @@
 		<!-- SVGWEB { -->
 		<meta name="svg.render.forceflash" content="true"/>
 		<script src="../../svgweb/svgweb/src/svg.js" data-path="../../svgweb/svgweb/src"></script>
-		<script src="../../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+		<script src="../../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 		<!-- } -->
 		<script type="text/javascript">
 
diff --git a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textBidiSvgWeb.html b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textBidiSvgWeb.html
index 0a75a08..310d6b0 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textBidiSvgWeb.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textBidiSvgWeb.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="../../svgweb/svgweb/src/svg.js" data-path="../../svgweb/svgweb/src"></script>
-<script src="../../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">	
 		dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textpathBidiSvgWeb.html b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textpathBidiSvgWeb.html
index 0f9e677..a41334e 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textpathBidiSvgWeb.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/svgWeb/textpathBidiSvgWeb.html
@@ -7,7 +7,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="../../svgweb/svgweb/src/svg.js" data-path="../../svgweb/svgweb/src"></script>
-<script src="../../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/test_SurfaceGroup.html b/dojox/gfx/tests/_gfxBidiSupport/test_SurfaceGroup.html
index ab8785e..ac06d7a 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/test_SurfaceGroup.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/test_SurfaceGroup.html
@@ -6,7 +6,7 @@
 			@import "../../../../dijit/tests/css/dijitTests.css";
 		</style>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/textBidi.html b/dojox/gfx/tests/_gfxBidiSupport/textBidi.html
index f0d2eed..ba9f9f1 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/textBidi.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/textBidi.html
@@ -6,7 +6,7 @@
 			@import "../../../../dojo/resources/dojo.css";
 			@import "../../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/_gfxBidiSupport/textpathBidi.html b/dojox/gfx/tests/_gfxBidiSupport/textpathBidi.html
index 68f0bc3..8e1eef9 100644
--- a/dojox/gfx/tests/_gfxBidiSupport/textpathBidi.html
+++ b/dojox/gfx/tests/_gfxBidiSupport/textpathBidi.html
@@ -6,7 +6,7 @@
 			@import "../../../../dijit/tests/css/dijitTests.css";
 		</style>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 
 			dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/events-canvas.html b/dojox/gfx/tests/events-canvas.html
index 3ec9369..570652d 100644
--- a/dojox/gfx/tests/events-canvas.html
+++ b/dojox/gfx/tests/events-canvas.html
@@ -3,7 +3,7 @@
 	<head>
 		<title>dojox.gfx: Canvas events bug</title>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, gfxRenderer:'canvas'">
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, gfxRenderer:'canvas'">
 		</script>
 		<script type="text/javascript">
 			
diff --git a/dojox/gfx/tests/images/maps.png b/dojox/gfx/tests/images/maps.png
new file mode 100644
index 0000000..03aea0e
Binary files /dev/null and b/dojox/gfx/tests/images/maps.png differ
diff --git a/dojox/gfx/tests/matrix.js b/dojox/gfx/tests/matrix.js
index ac7d2dd..1416ebf 100644
--- a/dojox/gfx/tests/matrix.js
+++ b/dojox/gfx/tests/matrix.js
@@ -219,6 +219,43 @@ dojo.require("dojox.gfx.matrix");
 			var b = m.multiplyPoint(m.project(1, 1), 0, 1);
 			eq(t, b.x, 0.5);
 			eq(t, b.y, 0.5);
+		},
+		function IsIdentityTest(t){
+			var a = new m.Matrix2D();
+			tests.assertTrue(m.isIdentity(a));
+			a.xy=1;
+			tests.assertFalse(m.isIdentity(a));
+		},
+		function MultiplyRectangle(t){
+			var a = new m.Matrix2D(), 
+				r = {x:0,y:0,width:3,height:2},
+				res;
+			// multiply by identity -> same rect
+			res = m.multiplyRectangle(a, r);
+			tests.assertTrue(res.x == r.x && res.y == r.y && res.width == r.width && res.height == r.height);			
+			res = m.multiplyRectangle(m.scale(2,2), r);
+			eq(t, res.x, 0);
+			eq(t, res.y, 0);
+			eq(t, res.width, 6);
+			eq(t, res.height, 4);
+			a = m.rotategAt(-45, 0, 0);
+			var tl = m.multiplyPoint(a, 0, 0), // top left
+				tr = m.multiplyPoint(a, 3, 0), // top right
+				br = m.multiplyPoint(a, 3, 2), // bottom right
+				bl = m.multiplyPoint(a, 0, 2), // bottom left
+				exp = {x : tl.x, y:tr.y, width: br.x, height: bl.y - tr.y}; // expected
+			res = m.multiplyRectangle(a, r);
+			eq(t, res.x, exp.x);
+			eq(t, res.y, exp.y);
+			eq(t, res.width, exp.width);
+			eq(t, res.height, exp.height);
+			// matrices array
+			res = m.multiplyRectangle([m.translate(10,10), m.scale(2,2)], r);
+			eq(t, res.x, 10);
+			eq(t, res.y, 10);
+			eq(t, res.width, 6);
+			eq(t, res.height, 4);
 		}
+		
 	]);
 })();
diff --git a/dojox/gfx/tests/module.js b/dojox/gfx/tests/module.js
index b049f20..f736061 100644
--- a/dojox/gfx/tests/module.js
+++ b/dojox/gfx/tests/module.js
@@ -4,6 +4,12 @@ try{
 	dojo.require("dojox.gfx.tests.matrix");
 	dojo.require("dojox.gfx.tests.decompose");
 	doh.registerUrl("GFX: Utils", dojo.moduleUrl("dojox", "gfx/tests/test_utils.html"), 3600000);
+	doh.registerUrl("GFX: Base", dojo.moduleUrl("dojox", "gfx/tests/test_base.html"), 3600000);
+	doh.registerUrl("GFX: Clean up", dojo.moduleUrl("dojox", "gfx/tests/test_lifecycle.html"), 3600000);
+	doh.registerUrl("GFX: Container bbox", dojo.moduleUrl("dojox", "gfx/tests/test_containerBBox.html"), 3600000);
+	doh.registerUrl("GFX: Text bbox", dojo.moduleUrl("dojox", "gfx/tests/test_textbbox.html"), 3600000);
+	doh.registerUrl("GFX: Batch API", dojo.moduleUrl("dojox", "gfx/tests/test_batch.html"), 3600000);
+	doh.registerUrl("GFX: switchTo", dojo.moduleUrl("dojox", "gfx/tests/test_switchTo.html"), 3600000);
 }catch(e){
 	doh.debug(e);
 }
diff --git a/dojox/gfx/tests/performance/gfx_fill.html b/dojox/gfx/tests/performance/gfx_fill.html
index 7cdf43e..1c0e263 100755
--- a/dojox/gfx/tests/performance/gfx_fill.html
+++ b/dojox/gfx/tests/performance/gfx_fill.html
@@ -6,7 +6,7 @@
 	@import "../../../../dojo/resources/dojo.css";
 	@import "../../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript" src="../../../../util/doh/runner.js"></script>
 <script type="text/javascript">
 	dojo.require("doh.runner");
diff --git a/dojox/gfx/tests/performance/gfx_primitives.html b/dojox/gfx/tests/performance/gfx_primitives.html
index 73a3191..b1bf558 100755
--- a/dojox/gfx/tests/performance/gfx_primitives.html
+++ b/dojox/gfx/tests/performance/gfx_primitives.html
@@ -6,7 +6,7 @@
 	@import "../../../../dojo/resources/dojo.css";
 	@import "../../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript" src="../../../../util/doh/runner.js"></script>
 <script type="text/javascript">
 	dojo.require("doh.runner");
diff --git a/dojox/gfx/tests/performance/gfx_scenes.html b/dojox/gfx/tests/performance/gfx_scenes.html
index 552a3dc..e2d1c77 100755
--- a/dojox/gfx/tests/performance/gfx_scenes.html
+++ b/dojox/gfx/tests/performance/gfx_scenes.html
@@ -6,7 +6,7 @@
 	@import "../../../../dojo/resources/dojo.css";
 	@import "../../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript" src="../../../../util/doh/runner.js"></script>
 <script type="text/javascript">
 	dojo.require("doh.runner");
diff --git a/dojox/gfx/tests/svgweb/README b/dojox/gfx/tests/svgweb/README
index 18224c2..0982a3e 100644
--- a/dojox/gfx/tests/svgweb/README
+++ b/dojox/gfx/tests/svgweb/README
@@ -2,9 +2,8 @@ This folder contains dojox.gfx tests modified to force SVGWeb on all browsers.
 
 NOTICE of 3rd party code included
 =================================
-For ease of testing, the svgweb/ folder contains the latest svgweb trunk
-version (as of 7/4/2010 r1205) released under Apache License Version 2.0:
-http://www.apache.org/licenses/LICENSE-2.0.
+The svgweb/ folder contains a version of svgweb (svgweb-2010-04-09) which has
+been tested against dojox.gfx.
 
 This is a separately licensed library, see COPYING.txt in svgweb/ (note that
 only the binary subset of files from that project are included here).
diff --git a/dojox/gfx/tests/svgweb/sample.html b/dojox/gfx/tests/svgweb/sample.html
index 2d4f493..dcd2f8f 100644
--- a/dojox/gfx/tests/svgweb/sample.html
+++ b/dojox/gfx/tests/svgweb/sample.html
@@ -7,13 +7,13 @@
 		<!-- include svgweb, must before dojo, notice the extra 'data-path' attribute -->
 		<script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
 		<!-- include dojo, notice the config: forceGfxRenderer:'svg' -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="async: true, isDebug: true, forceGfxRenderer: 'svg'"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true, forceGfxRenderer: 'svg'"></script>
 
 		<script type="text/javascript">
-			require(["dojox/gfx", "dojox/gfx/move"], function(){
+			require(["dojo/dom", "dojox/gfx", "dojox/gfx/move"], function(dom){
 			
 			function testSurface() {
-				var node = dojo.byId("surface");
+				var node = dom.byId("surface");
 				var surface = dojox.gfx.createSurface(node, 600, 550);
 				
 				surface.whenLoaded(
diff --git a/dojox/gfx/tests/svgweb/test.roundrect.html b/dojox/gfx/tests/svgweb/test.roundrect.html
index 7bbb809..6b7f5c0 100644
--- a/dojox/gfx/tests/svgweb/test.roundrect.html
+++ b/dojox/gfx/tests/svgweb/test.roundrect.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug: true, forceGfxRenderer: 'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, forceGfxRenderer: 'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_arc.html b/dojox/gfx/tests/svgweb/test_arc.html
index c894aff..f0f445f 100644
--- a/dojox/gfx/tests/svgweb/test_arc.html
+++ b/dojox/gfx/tests/svgweb/test_arc.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_bezier.html b/dojox/gfx/tests/svgweb/test_bezier.html
index 690fe2e..0315d6d 100644
--- a/dojox/gfx/tests/svgweb/test_bezier.html
+++ b/dojox/gfx/tests/svgweb/test_bezier.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_destroy.html b/dojox/gfx/tests/svgweb/test_destroy.html
index 8aaffb4..dabcc0a 100644
--- a/dojox/gfx/tests/svgweb/test_destroy.html
+++ b/dojox/gfx/tests/svgweb/test_destroy.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_fill.html b/dojox/gfx/tests/svgweb/test_fill.html
index 2ad9c3d..edde725 100644
--- a/dojox/gfx/tests/svgweb/test_fill.html
+++ b/dojox/gfx/tests/svgweb/test_fill.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_fx.html b/dojox/gfx/tests/svgweb/test_fx.html
index 82b227a..2d5eace 100644
--- a/dojox/gfx/tests/svgweb/test_fx.html
+++ b/dojox/gfx/tests/svgweb/test_fx.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_fx_shapes.html b/dojox/gfx/tests/svgweb/test_fx_shapes.html
index 34cf4b2..338daaa 100644
--- a/dojox/gfx/tests/svgweb/test_fx_shapes.html
+++ b/dojox/gfx/tests/svgweb/test_fx_shapes.html
@@ -7,7 +7,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
         <script type="text/javascript" charset="utf-8">
             dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_gfx.html b/dojox/gfx/tests/svgweb/test_gfx.html
index 338e3d5..fdb602f 100644
--- a/dojox/gfx/tests/svgweb/test_gfx.html
+++ b/dojox/gfx/tests/svgweb/test_gfx.html
@@ -15,7 +15,7 @@
 	<!-- SVGWEB { -->
 	<meta name="svg.render.forceflash" content="true"/>
 	<script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-	<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+	<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 	<!-- } -->
 
 	<script type="text/javascript">
@@ -477,11 +477,11 @@
 					.setTransform({dx: 40, dy: 30})
 					;
 		//		surface.createRect(rect)
-		//			.setShape({width: 200})
-		//			.setStroke({})
-		//			.setFill(rg)
-		//			.setTransform({dx: 40, dy: 30})
-		//			;
+		//		.setShape({width: 200})
+		//		.setStroke({})
+		//		.setFill(rg)
+		//		.setTransform({dx: 40, dy: 30})
+		//		;
 				});
 				/* } */
 			});
diff --git a/dojox/gfx/tests/svgweb/test_gradient.html b/dojox/gfx/tests/svgweb/test_gradient.html
index bc71e36..b345623 100644
--- a/dojox/gfx/tests/svgweb/test_gradient.html
+++ b/dojox/gfx/tests/svgweb/test_gradient.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_group1.html b/dojox/gfx/tests/svgweb/test_group1.html
index faea4af..cbf94ae 100644
--- a/dojox/gfx/tests/svgweb/test_group1.html
+++ b/dojox/gfx/tests/svgweb/test_group1.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_group2.html b/dojox/gfx/tests/svgweb/test_group2.html
index 24dde60..9bc7fe4 100644
--- a/dojox/gfx/tests/svgweb/test_group2.html
+++ b/dojox/gfx/tests/svgweb/test_group2.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_image1.html b/dojox/gfx/tests/svgweb/test_image1.html
index 7edc570..0c8766d 100644
--- a/dojox/gfx/tests/svgweb/test_image1.html
+++ b/dojox/gfx/tests/svgweb/test_image1.html
@@ -9,10 +9,11 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.matrix");
 
 var image = null, grid_size = 500, grid_step = 50,
 	m = dojox.gfx.matrix;
diff --git a/dojox/gfx/tests/svgweb/test_image2.html b/dojox/gfx/tests/svgweb/test_image2.html
index 6a3a32e..c87612b 100644
--- a/dojox/gfx/tests/svgweb/test_image2.html
+++ b/dojox/gfx/tests/svgweb/test_image2.html
@@ -5,7 +5,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_image3.html b/dojox/gfx/tests/svgweb/test_image3.html
index f0b501b..0e91073 100644
--- a/dojox/gfx/tests/svgweb/test_image3.html
+++ b/dojox/gfx/tests/svgweb/test_image3.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_image4.html b/dojox/gfx/tests/svgweb/test_image4.html
index 12f9deb..8d4e0cb 100644
--- a/dojox/gfx/tests/svgweb/test_image4.html
+++ b/dojox/gfx/tests/svgweb/test_image4.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_image5.html b/dojox/gfx/tests/svgweb/test_image5.html
index 07970fa..f4dd305 100644
--- a/dojox/gfx/tests/svgweb/test_image5.html
+++ b/dojox/gfx/tests/svgweb/test_image5.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_linearGradient.html b/dojox/gfx/tests/svgweb/test_linearGradient.html
index 9a5c5f3..65d35f8 100644
--- a/dojox/gfx/tests/svgweb/test_linearGradient.html
+++ b/dojox/gfx/tests/svgweb/test_linearGradient.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_linestyle.html b/dojox/gfx/tests/svgweb/test_linestyle.html
index fa04db5..5c00f93 100644
--- a/dojox/gfx/tests/svgweb/test_linestyle.html
+++ b/dojox/gfx/tests/svgweb/test_linestyle.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_pattern.html b/dojox/gfx/tests/svgweb/test_pattern.html
index 584ab15..8d53635 100644
--- a/dojox/gfx/tests/svgweb/test_pattern.html
+++ b/dojox/gfx/tests/svgweb/test_pattern.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_poly.html b/dojox/gfx/tests/svgweb/test_poly.html
index e21321a..ecc8bbf 100644
--- a/dojox/gfx/tests/svgweb/test_poly.html
+++ b/dojox/gfx/tests/svgweb/test_poly.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_resize.html b/dojox/gfx/tests/svgweb/test_resize.html
index f151368..ceb80f3 100644
--- a/dojox/gfx/tests/svgweb/test_resize.html
+++ b/dojox/gfx/tests/svgweb/test_resize.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_setPath.html b/dojox/gfx/tests/svgweb/test_setPath.html
index 9ba8bb5..685dda1 100644
--- a/dojox/gfx/tests/svgweb/test_setPath.html
+++ b/dojox/gfx/tests/svgweb/test_setPath.html
@@ -10,7 +10,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_tbbox.html b/dojox/gfx/tests/svgweb/test_tbbox.html
index 8c6e010..5f078b6 100644
--- a/dojox/gfx/tests/svgweb/test_tbbox.html
+++ b/dojox/gfx/tests/svgweb/test_tbbox.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_text.html b/dojox/gfx/tests/svgweb/test_text.html
index 13e1c09..f65e1a8 100644
--- a/dojox/gfx/tests/svgweb/test_text.html
+++ b/dojox/gfx/tests/svgweb/test_text.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_textpath.html b/dojox/gfx/tests/svgweb/test_textpath.html
index 1520959..1631526 100644
--- a/dojox/gfx/tests/svgweb/test_textpath.html
+++ b/dojox/gfx/tests/svgweb/test_textpath.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_transform.html b/dojox/gfx/tests/svgweb/test_transform.html
index 164c2d1..f6272e6 100644
--- a/dojox/gfx/tests/svgweb/test_transform.html
+++ b/dojox/gfx/tests/svgweb/test_transform.html
@@ -9,7 +9,7 @@
 <!-- SVGWEB { -->
 <meta name="svg.render.forceflash" content="true"/>
 <script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 <!-- } -->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
diff --git a/dojox/gfx/tests/svgweb/test_utils.html b/dojox/gfx/tests/svgweb/test_utils.html
index a989e04..545c801 100644
--- a/dojox/gfx/tests/svgweb/test_utils.html
+++ b/dojox/gfx/tests/svgweb/test_utils.html
@@ -10,7 +10,7 @@
 		<!-- SVGWEB { -->
 		<meta name="svg.render.forceflash" content="true"/>
 		<script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-		<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+		<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 		<!-- } -->
 		<script type="text/javascript" src="../../../util/doh/runner.js"></script>
 		<script type="text/javascript">
diff --git a/dojox/gfx/tests/svgweb/test_vectortext_draw.html b/dojox/gfx/tests/svgweb/test_vectortext_draw.html
index 0a63d44..ffddbd9 100644
--- a/dojox/gfx/tests/svgweb/test_vectortext_draw.html
+++ b/dojox/gfx/tests/svgweb/test_vectortext_draw.html
@@ -9,7 +9,7 @@
 		<!-- SVGWEB { -->
 		<meta name="svg.render.forceflash" content="true"/>
 		<script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-		<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+		<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 		<!-- } -->
 		<script type="text/javascript">
 			dojo.require("dojox.gfx");
@@ -21,14 +21,14 @@
 				var url = dojo.moduleUrl("dojox", "gfx/resources/Gillius.svg");
 				var f = new dojox.gfx.VectorFont(url);
 
-				//	draw out the glyphs for testing.
+				//		draw out the glyphs for testing.
 				var surface = dojox.gfx.createSurface("test", 600, 400);
 	/* SVGWEB { */
 	surface.whenLoaded(function() {
 				var rect = surface.createRect({ x: 0, y: 0, width: 600, height: 400 })
 					.setFill(bg);
 
-				//	draw it up.
+				//		draw it up.
 				var txtArgs = {
 					text: "Now is the time for all good men to come to a rest.  Plus, the rain in Spain falls mainly on the plain!",
 					x: 0, y: 0,
diff --git a/dojox/gfx/tests/svgweb/test_vectortext_load.html b/dojox/gfx/tests/svgweb/test_vectortext_load.html
index 4e12d75..a4e9e51 100644
--- a/dojox/gfx/tests/svgweb/test_vectortext_load.html
+++ b/dojox/gfx/tests/svgweb/test_vectortext_load.html
@@ -9,7 +9,7 @@
 		<!-- SVGWEB { -->
 		<meta name="svg.render.forceflash" content="true"/>
 		<script src="svgweb/src/svg.js" data-path="svgweb/src"></script>
-		<script src="../../../../dojo/dojo.js" djConfig="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
+		<script src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true,forceGfxRenderer:'svg'" type="text/javascript"></script>
 		<!-- } -->
 		<script type="text/javascript">
 			dojo.require("dojox.gfx");
@@ -27,7 +27,7 @@
 		}
 	}
 
-				//	draw out the glyphs for testing.
+				//		draw out the glyphs for testing.
 				var surface = dojox.gfx.createSurface("test", 2500, 560);
 	/* SVGWEB { */
 	surface.whenLoaded(function() {
@@ -58,20 +58,20 @@
 				rect.setShape({ x:0, y:0, width:cx*factor, height: (f.viewbox.height*factor)+padding*2 });
 				dojo.byId("test").style.height = Math.round(f.viewbox.height*factor)+padding*2+"px";
 				
-				//	try to find the baseline
+				//		try to find the baseline
 				surface.createLine({ x1: 0, x2: cx*factor, 
 						y1: factor*(f.viewbox.height+f.descent), y2:factor*(f.viewbox.height+f.descent) 
 				}).setStroke({ color: "#a36e2c" });
 
-				//	lets do some measuring lines.
+				//		lets do some measuring lines.
 				var s = "#70657e", axis = surface.createGroup();
-				//	measurement axis
+				//		measurement axis
 				axis.createLine({ x1: 0, x2: cx*factor, y1: factor*f.viewbox.height+padding*2-1, y2: factor*f.viewbox.height+padding*2-1 })
 					.setStroke(s);
 
 				var major=50, minor=10, yMajor=20, yMinor=10, tick=5, steps=Math.floor(cx/minor);
 				for(var i=0; i<steps; i++){
-					//	ticks
+					//		ticks
 					var xpos = i*minor, y2 = padding*2+factor*f.viewbox.height, y1 = (xpos%major==0)?y2-yMajor:y2-yMinor;
 					axis.createLine({ x1: xpos, x2: xpos, y1: y1, y2: y2 }).setStroke(s);
 					if(xpos%major==0){
diff --git a/dojox/gfx/tests/test_arc.html b/dojox/gfx/tests/test_arc.html
index 5bde56a..87e4103 100644
--- a/dojox/gfx/tests/test_arc.html
+++ b/dojox/gfx/tests/test_arc.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 dojo.require("dojox.gfx.shape");
diff --git a/dojox/gfx/tests/test_base.html b/dojox/gfx/tests/test_base.html
new file mode 100644
index 0000000..4bf8faf
--- /dev/null
+++ b/dojox/gfx/tests/test_base.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>GFX Test: Test the functions defined in _base</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
+		<script type="text/javascript" src="../../../util/doh/runner.js"></script>
+		<script type="text/javascript">
+			dojo.require("doh.runner");
+			dojo.require("dojox.gfx");
+			dojo.require("dojox.gfx._base");
+		</script>
+		<script type="text/javascript">
+			dojo.addOnLoad(function(){
+				var drawing, t;
+				doh.register("GFX: _base Tests", [
+					{
+						name: "splitFontString",
+						timeout: 1000,
+						setUp: function(){
+							if(!drawing){
+								var dn = dojo.byId("gfxObject");
+								drawing = dojox.gfx.createSurface(dn, 300, 300);
+								t = drawing.createText({ 
+									 x: 100,
+									 y: 100,
+									 text:"Hello Gfx!"
+								}).setFill("black");
+							}
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							try{
+								var s = "italic small-caps bold 12px arial,sans-serif";
+								var font = dojox.gfx.splitFontString(s);
+								doh.assertEqual("italic", font.style, "Unexpected Values for font style.");
+								doh.assertEqual("small-caps", font.variant, "Unexpected values for font variant.");
+								doh.assertEqual("bold", font.weight, "Unexpected values for font weight.");
+								doh.assertEqual("12px", font.size, "Unexpected values for font size.");
+								doh.assertEqual("arial,sans-serif", font.family, "Unexpected values for font family.");
+								t.setFont(s);
+								s = "italic small-caps bold 12px/30px Georgia";
+								font = dojox.gfx.splitFontString(s);
+								doh.assertEqual("italic", font.style, "Unexpected Values for font style.");
+								doh.assertEqual("small-caps", font.variant, "Unexpected values for font variant.");
+								doh.assertEqual("bold", font.weight, "Unexpected values for font weight.");
+								doh.assertEqual("12px", font.size, "Unexpected values for font size.");
+								doh.assertEqual("Georgia", font.family, "Unexpected values for font family.");
+								t.setFont(s);
+								s = "italic normal normal 150% arial";
+								font = dojox.gfx.splitFontString(s);
+								doh.assertEqual("italic", font.style, "Unexpected Values for font style.");
+								doh.assertEqual("normal", font.variant, "Unexpected values for font variant.");
+								doh.assertEqual("normal", font.weight, "Unexpected values for font weight.");
+								doh.assertEqual("150%", font.size, "Unexpected values for font size.");
+								doh.assertEqual("arial", font.family, "Unexpected values for font family.");
+								t.setFont(s);
+								
+								d.callback(true);
+							}catch(e){
+								d.errback(e);
+							}
+							return d;
+						}
+					},{
+						name: "makeFontString",
+						timeout: 1000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							try{
+								var font = dojox.gfx.makeFontString({
+									style:"italic",
+									variant:"small-caps",
+									weight:"bold",
+									size:"12px",
+									family:"arial,sans-serif"
+								});
+								var expected = "italic small-caps bold 12px arial,sans-serif";
+								doh.assertEqual(expected, font, "Unexpected value for font sting.");
+								
+								d.callback(true);
+							}catch(e){
+								d.errback(e);
+							}
+							return d;
+						}
+					},{
+						name: "_isRendered",
+						timeout: 1000,
+						setUp: function(){
+							if(!drawing){
+								var dn = dojo.byId("gfxObject");
+								drawing = dojox.gfx.createSurface(dn, 300, 300);
+							}
+						},
+						runTest: function(t){
+							var g = drawing.createGroup();
+							var rect = g.createRect();
+							t.assertTrue(dojox.gfx._base._isRendered(rect), "Unexpected value for parented rect.");
+							g.removeShape();
+							t.assertFalse(dojox.gfx._base._isRendered(rect), "Unexpected value for unparented rect.");
+							t.assertFalse(dojox.gfx._base._isRendered(g), "Unexpected value for unparented g.");
+						}
+					}
+				]);
+				doh.run();
+			});
+			</script>
+	</head>
+	<body>
+		<div id="gfxObject" style="width: 500px; height: 500px;font-weight:bold;"></div>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/test_batch.html b/dojox/gfx/tests/test_batch.html
new file mode 100644
index 0000000..d717118
--- /dev/null
+++ b/dojox/gfx/tests/test_batch.html
@@ -0,0 +1,311 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Test Batch</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, packageMap:[{name:'doh',location:'util/doh'}]"></script>
+		<script type="text/javascript">
+			require([
+			"doh/runner",
+			"dojo/ready",
+			"dojo/aspect",
+			"dojox/gfx",
+			"dojox/gfx/shape",
+			"dojox/gfx/svg",
+			"dojox/gfx/canvas"],
+			function(doh, ready, aspect, gfx, gfxshape, svg, canvas){
+				
+				ready(function(){
+					var surface, r,
+						checkSurface = function(){
+							if(!surface){
+								surface = gfx.createSurface(dojo.byId("gfxObject"), 300, 300);
+							}
+						};
+					
+					doh.register("GFX: batching operations [SVG]", [
+						{
+							name: "Surface.openBatch",
+							timeout: 1000,
+							setUp: function(){
+								if(surface){
+									surface.destroy();
+									surface = null;
+								}
+								gfx.switchTo(svg);
+								checkSurface();
+
+							},
+							runTest: function(){
+								var ret = surface.openBatch();
+								doh.assertTrue(ret === surface, "Invalid openBatch return value.");
+								var rect = surface.createRect();
+								var p = rect.rawNode.parentNode;
+								doh.assertTrue(p !== surface.rawNode, "Unexpected DOM parent node.");
+							},
+							tearDown: function(){
+								surface.clear();
+							}
+						},{
+							name: "Surface.closeBatch",
+							timeout: 1000,
+							setUp: function(){
+								if(surface){
+									surface.destroy();
+									surface = null;
+								}
+								gfx.switchTo(svg);
+								checkSurface();
+
+							},
+							runTest: function(){
+								surface.openBatch();
+								var rect = surface.createRect();
+								var ret = surface.closeBatch();
+								doh.assertTrue(ret === surface, "Invalid closeBatch return value.");
+								var p = rect.rawNode.parentNode;
+								doh.assertTrue(p === surface.rawNode, "Unexpected DOM parent node.");
+							},
+							tearDown: function(){
+								surface.clear();
+							}
+						},{
+							name: "nested openBatch",
+							timeout: 1000,
+							setUp: function(){
+								if(surface){
+									surface.destroy();
+									surface = null;
+								}
+								gfx.switchTo(svg);
+								checkSurface();
+							},
+							runTest: function(){
+								surface.openBatch();
+								var rect = surface.createRect().setFill("red");
+								surface.openBatch();
+								var rect2 = surface.createRect({x:200}).setFill("green");
+								doh.assertTrue(rect.rawNode.parentNode === rect2.rawNode.parentNode, "Unexpected parent nodes for rects.");
+								surface.closeBatch();
+								var p = rect2.rawNode.parentNode;
+								doh.assertTrue(p !== surface.rawNode, "Unexpected rect2 DOM parent node in nested batch.");
+								p = rect.rawNode.parentNode;
+								doh.assertTrue(p !== surface.rawNode, "Unexpected rect DOM parent node in nested batch.");
+								surface.closeBatch();
+								p = rect2.rawNode.parentNode;
+								doh.assertTrue(p === surface.rawNode, "Unexpected rect2 DOM parent node in nested batch. Expected: surface.parentNode");
+								p = rect.rawNode.parentNode;
+								doh.assertTrue(p === surface.rawNode, "Unexpected rect DOM parent node in nested batch. Expected: surface.parentNode");
+							},
+							tearDown: function(){
+								surface.clear();
+							}
+						},{
+							name: "Group batching",
+							timeout: 1000,
+							setUp: function(){
+								if(surface){
+									surface.destroy();
+									surface = null;
+								}
+								gfx.switchTo(svg);
+								checkSurface();
+							},
+							runTest: function(){
+								var g = surface.createGroup();
+								g.openBatch();
+								var rect = g.createRect().setFill("red");
+								doh.assertTrue(rect.rawNode.parentNode !== g.rawNode, "Unexpected parent node for rect.");
+								var rect2 = surface.createRect();
+								doh.assertTrue(rect2.rawNode.parentNode === surface.rawNode, "Unexpected parent node for rect2.");
+								g.closeBatch();
+								doh.assertTrue(rect.rawNode.parentNode === g.rawNode, "Unexpected parent node for rect after closeBatch.");
+							},
+							tearDown: function(){
+								surface.clear();
+							}
+						},{
+							name: "Nested Group/Surface batching",
+							timeout: 1000,
+							setUp: function(){
+								if(surface){
+									surface.destroy();
+									surface = null;
+								}
+								gfx.switchTo(svg);
+								checkSurface();
+							},
+							runTest: function(){
+								surface.openBatch();
+								var g = surface.createGroup();
+								doh.assertTrue(g.rawNode.parentNode !== surface.rawNode, "Unexpected parent node for g.");
+								g.openBatch();
+								var rect = g.createRect().setFill("red");
+								doh.assertTrue(rect.rawNode.parentNode !== g.rawNode, "Unexpected parent node for rect.");
+								g.closeBatch();
+								doh.assertTrue(rect.rawNode.parentNode === g.rawNode, "Unexpected parent node for rect after closeBatch.");
+								doh.assertTrue(g.rawNode.parentNode !== surface.rawNode, "Unexpected parent node for g.");
+								surface.closeBatch();
+								doh.assertTrue(g.rawNode.parentNode === surface.rawNode, "Unexpected parent node for g after closeBatch.");
+							},
+							tearDown: function(){
+								surface.clear();
+							}
+						}
+					]);
+					//
+					// Canvas
+					//
+					doh.register("GFX: batching operations [Canvas]", [
+						{
+							name: "Surface.openBatch",
+							timeout: 1000,
+							setUp: function(){
+								if(surface){
+									surface.destroy();
+									surface = null;
+								}
+								gfx.switchTo(canvas);
+								checkSurface();
+							},
+							runTest: function(t){
+								var ret = surface.openBatch();
+								doh.assertTrue(ret === surface, "Invalid openBatch return value.");
+								var called = false;
+								aspect.after(surface,"makeDirty",function(){
+									called = true;
+								});
+								var rect = surface.createRect();
+								doh.assertTrue(!called, "Unexpected surface.render() call.");
+							},
+							tearDown: function(){
+								surface.clear();
+							}
+						},{
+							name: "Surface.closeBatch",
+							timeout: 1000,
+							setUp: function(){
+								if(surface){
+									surface.destroy();
+									surface = null;
+								}
+								gfx.switchTo(canvas);
+								checkSurface();
+							},
+							runTest: function(t){
+								surface.openBatch();
+								var rect = surface.createRect();
+								var called = false;
+								aspect.after(surface,"makeDirty",function(){
+									called = true;
+								});
+								var ret = surface.closeBatch();
+								doh.assertTrue(ret === surface, "Invalid closeBatch return value.");
+								doh.assertTrue(called, "Unexpected surface.render() call.");
+							},
+							tearDown: function(){
+								surface.clear();
+							}
+						},{
+							name: "nested openBatch",
+							timeout: 1000,
+							setUp: function(){
+								if(surface){
+									surface.destroy();
+									surface = null;
+								}
+								gfx.switchTo(canvas);
+								checkSurface();
+							},
+							runTest: function(){
+								surface.openBatch();
+								var rect = surface.createRect().setFill("red");
+								var called = false;
+								aspect.after(surface,"makeDirty",function(){
+									called = true;
+								});
+								surface.openBatch();
+								var rect2 = surface.createRect({x:200}).setFill("green");
+								doh.assertTrue(!called, "Unexpected surface.render() call in nested batch [0].");
+								surface.closeBatch();
+								doh.assertTrue(!called, "Unexpected surface.render() call in nested batch [1].");
+								surface.closeBatch();
+								doh.assertTrue(called, "Surface.render() not called in nested batch.");
+							},
+							tearDown: function(){
+								surface.clear();
+							}
+						},{
+							name: "Group batching",
+							timeout: 1000,
+							setUp: function(){
+								if(surface){
+									surface.destroy();
+									surface = null;
+								}
+								gfx.switchTo(canvas);
+								checkSurface();
+								surface._render(); // flushes pendingRender coming from ctor
+							},
+							runTest: function(){
+								var g = surface.createGroup();
+								var ret = g.openBatch();
+								doh.assertTrue(ret == g, "Unexpected openBatch return value");
+								var called = false;
+								aspect.after(surface,"makeDirty", function(){
+									called = true;
+								});
+								var rect = g.createRect().setFill("red");
+								doh.assertTrue(!called, "Unexpected surface.render called.");
+								g.closeBatch();
+								doh.assertTrue(called, "surface.render not called after group.closeBatch().");
+							},
+							tearDown: function(){
+								surface.clear();
+							}
+						},{
+							name: "Nested Group/Surface batching",
+							timeout: 1000,
+							setUp: function(){
+								if(surface){
+									surface.destroy();
+									surface = null;
+								}
+								gfx.switchTo(canvas);
+								checkSurface();
+								surface._render(); // flushes pendingRender coming from ctor
+							},
+							runTest: function(){
+								surface.openBatch();
+								var g = surface.createGroup();
+								g.openBatch();
+								var called = false;
+								aspect.after(surface,"makeDirty", function(){
+									called = true;
+								});
+								var rect = g.createRect().setFill("red");
+								doh.assertTrue(!called, "Unexpected surface.render called.");
+								g.closeBatch();
+								doh.assertTrue(!surface.pendingRender, "Unexpected surface.render called.");
+								called = false;
+								surface.closeBatch();
+								doh.assertTrue(called, "surface.render not called after group.closeBatch().");
+							},
+							tearDown: function(){
+								surface.clear();
+							}
+						}
+					]);
+				doh.run();
+			});
+		});
+		</script>
+	</head>
+	<body>
+		<div id="gfxObject" style="width: 500px; height: 500px;font-weight:bold;"></div>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/test_bezier.html b/dojox/gfx/tests/test_bezier.html
index a7ccab2..7b72d23 100644
--- a/dojox/gfx/tests/test_bezier.html
+++ b/dojox/gfx/tests/test_bezier.html
@@ -6,7 +6,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 dojo.require("dojox.gfx.shape");
diff --git a/dojox/gfx/tests/test_bubbling.html b/dojox/gfx/tests/test_bubbling.html
index b57d8fa..7d268a0 100644
--- a/dojox/gfx/tests/test_bubbling.html
+++ b/dojox/gfx/tests/test_bubbling.html
@@ -1,61 +1,150 @@
+<!doctype html>
 <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
 <head>
-<title>Testing Bubbling events</title>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<style type="text/css">
-	@import "../../../dojo/resources/dojo.css";
-	@import "../../../dijit/tests/css/dijitTests.css";
-</style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, gfxRenderer:'canvas'"></script>
-<script type="text/javascript">
-dojo.require("dojox.gfx");
-
-createSurface = function(){
-	var surface = dojox.gfx.createSurface("test", 500, 500);
-	surface.whenLoaded(makeShapes);
-};
-
-log = function(msg) {
-	var elt = document.createTextNode(msg);
-	var div = dojo.byId('log');
-	div.insertBefore(elt, div.firstChild);
-	div.insertBefore(document.createElement('br'), elt.nextSibling);
-};
-
-makeShapes = function(surface){
-	var g   = surface.createGroup();
-	var rect = g.createRect().setFill('red');
-	rect.id='rect1';
-	surface.connect('onmousemove', function(e){
-		log('onmousemove received by surface. gfxTarget:'+(e.gfxTarget ? e.gfxTarget.id : 'null'));
-	});
-	if (dojox.gfx.renderer !== 'silverlight')
-		surface.connect('touchstart', function(e){
-			log('touchstart received by surface. gfxTarget:'+(e.gfxTarget ? e.gfxTarget.id : 'null'));
-		});
-	rect.connect('onmousedown', function(e){
-		log('onmousedown received on rect1. gfxTarget:'+e.gfxTarget.id);
-		
-	});
-	if (dojox.gfx.renderer !== 'silverlight')
-		rect.connect('touchstart', function(e){
-			log('touchstart received on rect1. gfxTarget:'+e.gfxTarget.id);
-			
-		});
-	g.connect('onmouseup',function(e){
-		log('onmouseup received on g1. gfxTarget:'+e.gfxTarget.id);
-	});
-	
-};
+	<title>Testing Bubbling events</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+	</style>
+	<script type="text/javascript">
+		var dojoConfig = {
+			isDebug: true,
+			gfxRenderer: 'canvas'
+		}
+	</script>
+	<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+	<script type="text/javascript">
+
+		require([
+			"dojo/_base/array",
+			"dojox/gfx",
+			"dojo/touch",
+			"dojo/dom",
+			"dojo/on",
+			"dojo/sniff",
+			"dojo/ready"
+		], function(array, gfx, touch, dom, on, has, ready){
+
+			var touchMaps = {
+				"press" : touch.press,
+				"release" : touch.release,
+				"move" : touch.move,
+				"over" : touch.over,
+				"out": touch.out
+			}, nativeMaps = has("touch") ? {
+				"press" : "touchstart",
+				"release" : "touchend",
+				"move" : "touchmove"
+			} : {
+				"press" : "mousedown",
+				"release":"mouseup",
+				"move" : "mousemove",
+				"over" : "mouseover",
+				"out" : "mouseout"
+			}, surfaces;
+
+			function log(msg) {
+				var elt = document.createTextNode(msg);
+				var div = dom.byId('log');
+				div.insertBefore(elt, div.firstChild);
+				div.insertBefore(document.createElement('br'), elt.nextSibling);
+			}
+
+			function wireEvents(shape, events, dojoTouch){
+				var maps = dojoTouch ? touchMaps : nativeMaps;
+				array.forEach(events, function(evt){
+					var event = maps[evt];
+					if(!event){ return; }
+					shape.on(maps[evt], function(e){
+						e.preventDefault();
+						var m = dojoTouch ? "touch." + evt : maps[evt];
+						log(m +" received on " + shape.id + ". gfxTarget:" + (e.gfxTarget ? e.gfxTarget.id : "null"));
+					});
+				});
+			}
 
-dojo.addOnLoad(createSurface);
+			function makeShapes(surface, useDojoTouch){
+				var g   = surface.createGroup();
+				g.id = "g";
+				var rect = g.createRect({x:50,y:10,width:180,height:220}).setFill('red');
+				rect.id='rect1';
+				var rect2 = g.createRect({x:10,y:150,width:110,height:175}).setFill('blue');
+				rect2.id='rect2';
+				var rect3 = g.createRect({x:50,y:360,width:50,height:50}).setFill('green');
+				rect3.id='rect3';
+
+				wireEvents(rect, ["press", "release", "move", "over", "out"], useDojoTouch);
+				wireEvents(rect2, ["move", "over", "out"], useDojoTouch);
+				wireEvents(rect3, ["over", "out"], useDojoTouch);
+				wireEvents(rect3, ["over", "out"], useDojoTouch);
+				wireEvents(g, ["press","out"], useDojoTouch);
+				wireEvents(surface, ["press","move"], useDojoTouch);
+			}
+
+			function buildScenes(){
+				surfaces = [];
+				var surface = gfx.createSurface("testDojoTouch", 300, 400);
+				surface.id = "surface";
+				surfaces.push(surface);
+				makeShapes(surface, true);
+				surface = gfx.createSurface("testNative", 300, 400);
+				surface.id = "surface";
+				surfaces.push(surface);
+				makeShapes(surface, false);
+				log("renderer:"+gfx.renderer);
+			}
+
+			var switchRenderer = function(){
+				var select = dom.byId("selectGfx");
+				var r = select.options[select.selectedIndex].value;
+				require(["dojox/gfx/"+r], function(r){
+					for(var i=0; i<surfaces.length; ++i){
+						surfaces[i].destroy();
+					}
+					gfx.switchTo(r);
+					buildScenes();
+				});
+			};
+
+			ready(function(){
+				buildScenes();
+				var select = dom.byId("selectGfx");
+				on(select,"change",function(e){
+					switchRenderer();
+				});
+				array.forEach(select.options, function(opt,i){
+					if (gfx.renderer.indexOf(opt.value) !== -1){
+						select.selectedIndex = i;
+					}
+				});
+			});
+		});
 
-</script>
+	</script>
+	<style>
+	.drawing {
+		width: 300px;
+		height: 400px;
+		display:inline-block;
+		border-color: black;
+		border-width: 2;
+		border-style: solid;
+	}
+	</style>
 </head>
 <body>
-	<h1>Testing fill rule</h1>
-	<div id="test" style="width: 500px; height: 300px;"></div>
-	<div id="log" style="width: 500px; height: 100px;overflow:scroll;"></div>
-	<p>That's all Folks!</p>
+<h1>Test bubbling with canvas.</h1>
+<p>This page shows two canvas-based gfx surfaces: the surface on the left connects its shapes to input events via the dojo/touch API.
+The surface on the right connects its shapes using native input event types (e.g. 'touchstart' or 'mousedown' depending
+on the device).</p>
+GFX Renderer: <select id="selectGfx">
+	<option value="svg">SVG</option>
+	<option value="canvasWithEvents">Canvas</option>
+</select>
+</p>
+<div id="testDojoTouch" class="drawing"></div>
+<div id="testNative" class="drawing"></div>
+<div id="log" style="width: 500px; height: 100px;overflow:scroll;"></div>
 </body>
 </html>
diff --git a/dojox/gfx/tests/test_canvaspolyline.html b/dojox/gfx/tests/test_canvaspolyline.html
index e665801..f98e582 100644
--- a/dojox/gfx/tests/test_canvaspolyline.html
+++ b/dojox/gfx/tests/test_canvaspolyline.html
@@ -1,4 +1,4 @@
-<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<!DOCTYPE html>
 <head>
 <title>Testing polyline points initialization</title>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="gfxRenderer:'canvas', isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="gfxRenderer:'canvas', isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 dojo.require("dojox.gfx.shape");
diff --git a/dojox/gfx/tests/test_clip.html b/dojox/gfx/tests/test_clip.html
new file mode 100644
index 0000000..bfa63e7
--- /dev/null
+++ b/dojox/gfx/tests/test_clip.html
@@ -0,0 +1,138 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Test Clip</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async:true, isDebug:true"></script>
+		<script type="text/javascript">
+			require([
+				"dojo/ready",
+				"dojo/_base/array", 
+				"dojo/dom", 
+				"dojo/on", 
+				"dojox/gfx", 
+				"dojox/gfx/matrix",
+				"dojox/gfx/Moveable"], 
+				function(ready, array, dom, on, gfx, matrix, Moveable) {
+
+				var surface, clipped = [];
+				
+				var drawGrid = function(){
+					var sz = surface.getDimensions();
+					for (var r=0;r<sz.height; r+=50){
+						surface.createLine({y1: r, x1:0, x2:sz.width, y2:r}).setStroke({width:1, color:"#cfcfcf"});
+					}
+					for (var c=0; c<sz.width; c+=50){
+						surface.createLine({y1: 0, x1:c, x2:c, y2:sz.height}).setStroke({width:1, color:"#cfcfcf"});
+					}
+				};
+				var img = "./images/maps.png";
+				
+				var buildScene = function(){
+					clipped = [];
+					var container = dom.byId("gfx_holder");
+					surface = gfx.createSurface(container, 600, 550);
+					surface.whenLoaded(function(){
+						drawGrid();
+						clipped.push(surface.createImage({src:img, width:200,height:200}).setClip({x:10,y:80,width:50,height:50}).setTransform(matrix.translate(200,200)));
+						surface.createRect({width:200,height:200}).setStroke("red").setTransform(matrix.translate(200,200));
+						// clip = ellipse
+						clipped.push(surface.createImage({src:img, x:100,y:50,width:200,height:200}).setClip({cx:200,cy:100,rx:20,ry:30}));
+						surface.createRect({x:100,y:50,width:200,height:200}).setStroke("green");
+						// clip = circle
+						clipped.push(surface.createImage({src:img, x:0,y:350,width:200,height:200}).setClip({cx:100,cy:425,rx:60,ry:60}));
+						surface.createRect({x:0,y:350,width:200,height:200}).setStroke("blue");
+						// clip = path
+						clipped.push(surface.createImage({src:img, x:300,y:350,width:200,height:200}).setClip({d:"M 350,350 C314,414 317,557 373,450.0000 z"}));
+						surface.createRect({x:300,y:350,width:200,height:200}).setStroke("#00FFFF");
+						// clip = polyline
+						clipped.push(surface.createImage({src:img, x:300,y:0,width:200,height:200}).setClip({points:[350,0,450,50,380,130,300,110]}));
+						surface.createRect({x:300,y:0,width:200,height:200}).setStroke("#FF00FF");
+						
+						var g1 = surface.createGroup().setTransform(matrix.translate(50,200)).setClip({x:20, y:20, width:90, height:150});
+						var g = g1.createGroup();
+						g.createRect({width:70, height:100}).setFill("#8B8878");
+						g.createEllipse({cx:50,cy:90,rx:40,ry:20}).setFill("#CDB79E");
+						g.setClip({x:0,y:60,width:80,height:30});
+						g.createRect(g.getBoundingBox()).setStroke("#CDB79E");
+						clipped.push(g);
+						
+						g = g1.createGroup();
+						g.createRect({width:70, height:100}).setFill("#8B8878");
+						g.createEllipse({cx:50,cy:90,rx:40,ry:20}).setFill("#CDB79E");
+						g.setClip({x:0,y:60,width:70,height:50}).setTransform(matrix.translate(50,50));
+						g.createRect(g.getBoundingBox()).setStroke("#CDB79E");
+						clipped.push(g);
+						surface.createRect(g1.getBoundingBox()).setStroke("#8B8878").setTransform(matrix.translate(50,200));
+						
+						clipped.push(surface.createRect({x:50,y:50,width:100, height:100}).setClip({x:50, y:50, width:50, height:50}).setFill("yellow").setTransform(matrix.scaleAt(2,2,50,50)));
+						g = surface.createGroup();
+						var gg = g.createGroup().setTransform(matrix.scaleAt(2,2,50,250)).setClip({x:100, y:300, width:50, height:50});
+						gg.createRect({x:50,y:250,width:100, height:100}).setFill("red");
+						clipped.push(gg);
+						clipped.push(surface.createRect({x:50,y:350,width:50, height:50}).setClip({x:75, y:375, width:25, height:25}).setFill("green"));
+
+
+						array.forEach(clipped, function(s){
+							new Moveable(s);
+						});
+						
+					});
+				};
+				
+				var switchRenderer = function(){
+					var select = dom.byId("selectGfx");
+					var r = select.options[select.selectedIndex].value;
+					if(surface){
+						surface.destroy();
+					}
+					require(["dojox/gfx/"+r], function(r){
+						gfx.switchTo(r);
+						buildScene();
+						dom.byId("noClip").value = clipped[0]._oldClip ? "Set clip" : "Remove clip";
+					});
+				};
+				
+				ready(function() {
+					on(dom.byId("noClip"), "click", function(){
+						array.forEach(clipped,function(s){
+							var c = s.getClip();
+							s.setClip(s._oldClip);
+							s._oldClip = c;
+						});
+						dom.byId("noClip").value = clipped[0]._oldClip ? "Set clip" : "Remove clip";
+					});
+					var select = dom.byId("selectGfx");
+					on(select,"change",function(e){
+						switchRenderer();
+					});
+					array.forEach(select.options, function(opt,i){
+						if (gfx.renderer.indexOf(opt.value) !== -1){
+							select.selectedIndex = i;
+							switchRenderer();
+						}
+					});
+				});
+			});
+
+		</script>
+	</head>
+	<body style="font-family:sans-serif;font-size:10pt">
+		<h1>Test Clip</h1>
+		<p>This page illustrates the gfx clipping api. This api allows to define a clipping area on any gfx Shape types 
+		(including group). The supported clipping geometry are rectangle, ellipse, polyline and path, with the following exceptions:</p>
+			<ul>
+				<li>VML only supports rectangular clipping shape.</li>
+				<li>The gfx Silverlight implementation does not support Path clipping geometry.</li>
+			</ul>
+		<p>You can drag the shapes using the mouse, remove the clip using the button at the bottom, and change the gfx renderer in the combobox.</p>			
+		GFX Renderer: <select id="selectGfx">
+		  <option value="svg">SVG</option>
+		  <option value="canvasWithEvents">Canvas</option>
+		  <option value="silverlight">Silverlight (IE)</option>
+		  <option value="vml">VML (IE <9)</option>
+		</select>
+		<div id="gfx_holder" style="width: 600px; height: 550px; border: solid;background-color: #eeeeee"></div>			
+		<input type="button" value="Remove clip" id="noClip"/>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/test_containerBBox.html b/dojox/gfx/tests/test_containerBBox.html
new file mode 100644
index 0000000..0a8e201
--- /dev/null
+++ b/dojox/gfx/tests/test_containerBBox.html
@@ -0,0 +1,143 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>GFX Test: Test the basic utils functions</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<script type="text/javascript">
+			dojoConfig = {
+				isDebug:true,
+				packages:[{
+					name:'doh',
+					location:'../util/doh'
+				}]
+			}
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojox/gfx",
+				"dojox/gfx/matrix",
+				"dojo/ready"
+			], function(doh, gfx, matrix, ready){
+				ready(function(){
+					var drawing, g;
+					doh.register("Container.getBoundingBox test", [
+						{
+							name: "Default state",
+							timeout: 1000,
+							setUp: function(){
+								if(!drawing){
+									drawing = gfx.createSurface("gfxObject", 300, 300);
+								}
+								drawing.clear();
+								g = drawing.createGroup();
+							},
+							runTest: function(){
+								// surface
+								var bbox = drawing.getBoundingBox();
+								doh.assertTrue(bbox === null, "Unexpected value for empty surface bbox.");
+								// empty group -> null bbox
+								bbox = g.getBoundingBox();
+								doh.assertTrue(bbox === null, "Unexpected value for empty group bbox.");
+							}
+						},						{
+							name: "Group with children",
+							timeout: 1000,
+							setUp: function(){
+								if(!drawing){
+									drawing = gfx.createSurface("gfxObject", 300, 300);
+								}
+								drawing.clear();
+								g = drawing.createGroup();
+							},
+							runTest: function(){
+								// child
+								var r = g.createRect();
+								var bbox = g.getBoundingBox();
+								doh.assertTrue(bbox.x === 0 && bbox.y === 0 && bbox.width === 100 && bbox.height === 100, "Unexpected bbox value.");
+								// children
+								g.createRect({x:200,y:300});
+								bbox = g.getBoundingBox();
+								doh.assertTrue(bbox.x === 0 && bbox.y === 0 && bbox.width === 300 && bbox.height === 400, "Unexpected composite bbox value.");
+								// child with null bbox
+								r = g.createRect();
+								r.getBoundingBox = function(){return null;};
+								var err = false;
+								bbox = null;
+								try{
+									bbox = g.getBoundingBox();
+								}catch(e){
+									err = true;
+								}
+								doh.assertFalse(err, "getBoundingBox fails with null bbox.");
+								doh.assertTrue(bbox.x === 0 && bbox.y === 0 && bbox.width === 300 && bbox.height === 400, "Unexpected composite bbox value with null bbox.");
+								// surface
+								bbox = drawing.getBoundingBox();
+								doh.assertTrue(bbox.x === 0 && bbox.y === 0 && bbox.width === 300 && bbox.height === 400, "Unexpected surface bbox value.");
+								
+							}
+						},{
+							name: "children with transform",
+							timeout: 1000,
+							setUp: function(){
+								if(!drawing){
+									drawing = gfx.createSurface("gfxObject", 300, 300);
+								}
+								drawing.clear();
+								g = drawing.createGroup();
+							},
+							runTest: function(){
+								// child
+								var r = g.createRect();
+								var bbox = g.getBoundingBox();
+								doh.assertTrue(bbox.x === 0 && bbox.y === 0 && bbox.width === 100 && bbox.height === 100, "Unexpected bbox value.");
+								// child with transform
+								r.setTransform(matrix.translate(10,0));
+								bbox = g.getBoundingBox();
+								doh.assertTrue(bbox.x === 10 && bbox.y === 0 && bbox.width === 100 && bbox.height === 100, "Unexpected bbox value with child transform.");
+								// the group has a transform -> getBoundingBox should not be modified
+								g.setTransform(matrix.translate(10,20));
+								bbox = g.getBoundingBox();
+								doh.assertTrue(bbox.x === 10 && bbox.y === 0 && bbox.width === 100 && bbox.height === 100, "Unexpected bbox value with Group transform.");
+								// surface
+								bbox = null;
+								bbox = drawing.getBoundingBox();
+								doh.assertTrue(bbox.x === 20 && bbox.y === 20 && bbox.width === 100 && bbox.height === 100, "Unexpected surface bbox value.");
+							}
+						},{
+							name: "Nested container",
+							timeout: 1000,
+							setUp: function(){
+								if(!drawing){
+									drawing = gfx.createSurface("gfxObject", 300, 300);
+								}
+								drawing.clear();
+								g = drawing.createGroup();
+							},
+							runTest: function(){
+								var r = g.createRect();
+								g.createRect({x:200,y:300});
+								var g2 = g.createGroup();
+								g2.createRect();
+								g2.createRect({x:500});
+								g2.setTransform(matrix.translate(100,200));
+								bbox = g.getBoundingBox();
+								doh.assertTrue(bbox.x === 0 && bbox.y === 0 && bbox.width === 700 && bbox.height === 400, "Unexpected composite bbox value.");
+							}
+						}
+					]);
+					doh.run();
+				});
+			});
+			
+		</script>
+	</head>
+	<body class="tundra">
+		<h1>Test of Group.getBoundingBox</h1>
+		<div id="gfxObject"></div>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/test_dashedstroke.html b/dojox/gfx/tests/test_dashedstroke.html
new file mode 100644
index 0000000..b29d98e
--- /dev/null
+++ b/dojox/gfx/tests/test_dashedstroke.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Test Dashed Stroke</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="gfxRenderer:'canvas',async:true, isDebug:true"></script>
+		<script type="text/javascript">
+			require([
+				"dojo/ready",
+				"dojo/_base/array",
+				"dojo/dom",
+				"dojo/on",
+				"dojox/gfx",
+				"dojox/gfx/matrix",
+				"dojox/gfx/Moveable",
+				"dojox/gfx/svg"],
+				function(ready, array, dom, on, gfx, matrix, Moveable, svg) {
+
+				function makeScene(surface, renderer){
+					surface.createText({x:250,y:50,text:renderer})
+							.setFill("black")
+							.setFont({family:'sans-serif', size:'40pt'})
+					;
+
+					surface.createCircle({cx:130,cy:200,r:70}).setStroke({width:2, style:"dashdot", color:'blue'}).setFill("rgba(162,205,90,.3)");
+					new Moveable(surface.createLine({x1:200,y1:200,x2:400,y2:300}).setStroke({width:2, style:"dashdot", color:'black'}));
+					surface.createRect({x:200,y:200}).setFill("rgba(162,205,90,.3)").setStroke({width:6, style:"longdash", color:'black'});
+					surface.createRect({x:300,y:50,r:10}).setStroke({width:6, style:"dashdot", color:'red'}).setFill("rgba(162,205,90,.3)");
+					new Moveable(surface.createEllipse({cx:300,cy:400, rx:120, ry:80}).setStroke({width:2, style:"dashdot", color:'black'}).setFill("rgba(162,205,90,.3)"));
+
+					// MoveTo + lineTo combine in one M xx,xx,...,xxx [Absolute]
+					surface.createPath()
+							.setStroke({color:'rgb(110,139,61)', width:4, style:'longdash'})
+							.setFill('rgba(162,205,90,.3)')
+							.setShape({path:"M 10.499686,210,100.174931,378.56990,40,290Z"})
+					;
+					// MoveTo + lineTo combine + lineTo  [Relative]
+					surface.createPath()
+							.setStroke({color:'rgb(110,139,61)', width:4, style:'longdash'})
+							.setFill('rgba(162,205,90,.3)')
+							.setShape({path:"m 300.499686,210,130,50,40,90 l 90,-150 Z"})
+					;
+
+					//PI
+					surface.createPath()
+							.setStroke({color:'rgb(110,139,61)', width:4, style:'shortdashdot'})
+							.setFill('rgba(162,205,90,.3)')
+							.setShape({path:"M 10.499686,177.03840 L 31.174931,178.56990 C 52.615925,154.32116 61.039171,82.595924 187.38789,96.634671 C 182.79339,403.95560 48.021426,436.37234 56.444675,499.41907 C 59.507674,535.15406 87.840417,557.10556 118.47041,558.38181 C 215.21014,555.06356 210.87089,424.63084 240.99038,95.868921 L 365.80760,95.868921 C 359.17110,211.75239 341.04836,327.63586 339.00636,441.22208 C 340.53786,516.77606 386.48285,557.10556 446.97708,557.61606 C 546.52456,560.93431 577.9203 [...]
+					;
+
+					surface.createPath()
+							.setStroke({color: "black", style:'longdash', width:3})
+							.setFill('rgba(162,205,90,.3)')
+							.setShape({path:"M400 100 500 100 500 200Q500 250 425 175T400 100z"})
+					;
+					new Moveable(surface.createPolyline({points:[50,50,80,130,160,90,110,270]}).setStroke({width:4, style:"dashdot", color:'black'}));
+				}
+
+				ready(function(){
+					var surface = gfx.createSurface(dom.byId("gfx_holder"), 600, 550);
+					makeScene(surface, "Canvas");
+					gfx.switchTo(svg);
+					surface = gfx.createSurface(dom.byId("svg_holder"), 600, 550);
+					makeScene(surface, "SVG");
+					var hasSetLineDash = typeof document.createElement("canvas").getContext("2d").setLineDash  == "function";
+					dom.byId("holder").innerHTML = "Native dashed stroke: " + hasSetLineDash+"</br>";
+				});
+			});
+
+		</script>
+	</head>
+	<body style="font-family:sans-serif;font-size:12pt">
+		This test illustrates dashed stroke support for canvas renderer. The gfx implementation uses the native implementation if it is provided by the browser, or a custom implementation otherwise.<br/>
+		The left drawing uses the Canvas renderer. The right drawing uses the SVG Renderer for reference purpose.</br>
+		<span id="holder" style="color: red"></span>
+		<div id="gfx_holder" style="width: 600px; height: 550px; border: solid;display:inline-block"></div>
+		<div id="svg_holder" style="width: 600px; height: 550px; border: solid;display:inline-block"></div>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dojox/gfx/tests/test_decompose.html b/dojox/gfx/tests/test_decompose.html
index 5dc92af..935a1f7 100644
--- a/dojox/gfx/tests/test_decompose.html
+++ b/dojox/gfx/tests/test_decompose.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 dojo.require("dojox.gfx.matrix");
diff --git a/dojox/gfx/tests/test_destroy.html b/dojox/gfx/tests/test_destroy.html
index 1d4bf13..57b2503 100644
--- a/dojox/gfx/tests/test_destroy.html
+++ b/dojox/gfx/tests/test_destroy.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--<script type="text/javascript" src="../_base.js"></script>-->
 <!--<script type="text/javascript" src="../shape.js"></script>-->
 <!--<script type="text/javascript" src="../path.js"></script>-->
@@ -15,6 +15,7 @@
 <!--<script type="text/javascript" src="../silverlight.js"></script>-->
 <script type="text/javascript">
 dojo.require("dojox.gfx");
+dojo.require("dojox.gfx.registry");
 
 surface = null;
 
@@ -25,6 +26,7 @@ createSurface = function(){
 
 makeShapes = function(){
 	var path = surface.createPath("");
+	
 	// form concentric circles
 	var center = {x: 250, y: 250};
 	for(var r = 200; r > 0; r -= 30){
@@ -39,14 +41,19 @@ makeShapes = function(){
 
 cleanUp = function(){
 	if(surface){
+		var id = surface.children[0].getUID();
 		surface.destroy();
 		surface = null;
 		var t = dojo.byId("test").innerHTML;
 		if(t){
 			console.error("Garbage detected: " + t);
-		}else{
-			console.log("The parent node was cleaned up properly.");
+			return;
 		}
+		if (dojox.gfx.shape.byId(id)){
+			console.log("Shape not disposed.");
+			return;
+		}
+		console.log("The parent node was cleaned up properly.");
 	}
 	createSurface();
 }
diff --git a/dojox/gfx/tests/test_fill.html b/dojox/gfx/tests/test_fill.html
index 50536fa..9f823a2 100644
--- a/dojox/gfx/tests/test_fill.html
+++ b/dojox/gfx/tests/test_fill.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--<script type="text/javascript" src="../_base.js"></script>-->
 <!--<script type="text/javascript" src="../shape.js"></script>-->
 <!--<script type="text/javascript" src="../path.js"></script>-->
diff --git a/dojox/gfx/tests/test_filter.html b/dojox/gfx/tests/test_filter.html
new file mode 100644
index 0000000..8ef3abf
--- /dev/null
+++ b/dojox/gfx/tests/test_filter.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>Test SVG Filters</title>
+</head>
+<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+	require([
+	"dojo/ready",
+	"dojo/_base/array",
+	"dojox/gfx",
+	"dojox/gfx/matrix",
+	"dojox/gfx/filters",
+	"dojox/gfx/svgext"
+	], function(ready, array, gfx, matrix, filters){
+
+		var surface;
+
+		function makeShape(filter, title){
+			var topg = surface.createGroup();
+			var g = topg.createGroup();
+			g.createPath({path:"M50,90 C0,90 0,30 50,30 L150,30 C200,30 200,90 150,90 z"}).setStroke({color:"#0000D9",width:10});
+			g.createPath({path:"M60,80 C30,80 30,40 60,40 L140,40 C170,40 170,80 140,80 z"}).setFill("#D90000");
+			g.createGroup().createText({x:52, y:76, text:"SVG"}).setFill("white").setFont({family:"verdana", size:45});
+			if(filter){
+				g.setFilter(filter);
+			}
+			topg.createText({x:100, y:140, text: title, align:"middle"}).setFill("black").setFont({family:"verdana", size:20});
+			var tooltip = document.createElementNS("http://www.w3.org/2000/svg", "title");
+			tooltip.appendChild(document.createTextNode(title));
+			topg.rawNode.appendChild(tooltip);
+			return topg;
+		}
+
+		ready(function(){
+			surface = gfx.createSurface("canvas", 800, 900);
+			var count = 0;
+			makeShape(null, "none").setTransform(matrix.scale(.65,.65));
+			array.forEach(["convolutions", "blurs", "colors", "miscs", "shadows", "textures", "reliefs"], function(lib){
+				for(var func in filters[lib]){
+					++count;
+					var f = filters[lib][func];
+					var s = makeShape(f(), func);
+					s.setTransform([matrix.translate((count%6)*132, Math.floor(count/6)*90), matrix.scale(.65,.65)]);
+				}
+			});
+
+			var customFilter = filters.createFilter({
+			        // no id to test id auto assignment
+					x: 0, y:0, width:200, height:120
+				},[
+				filters.feGaussianBlur({
+					"in": "SourceAlpha",
+					"stdDeviation":"4",
+					"result":"blur"
+				}),
+				filters.feOffset({
+					"in":"blur",
+					"dx":4,
+					"dy":4,
+					"result":"offsetBlur"
+				}),
+				filters.feSpecularLighting({
+					"in":"blur",
+					"surfaceScale":5,
+					"specularConstant":.75,
+					"specularExponent":20,
+					"lighting-color":"#bbbbbb",
+					"result":"specOut"
+				}, [filters.fePointLight({
+					x:-5000,
+					y:-10000,
+					z:20000
+				})]),
+				filters.feComposite({
+					"in":"specOut",
+					"in2":"SourceAlpha",
+					"operator":"in",
+					"result":"specOut"
+				}),
+				filters.feComposite({
+					"in":"SourceGraphic",
+					"in2":"specOut",
+					"operator":"arithmetic",
+					k1:0,
+					k2:1,
+					k3:1,
+					k4:0,
+					"result":"litPaint"
+				}),
+				filters.feMerge("offsetBlur","litPaint")
+			]);
+			++count;
+			makeShape(customFilter,"custom").setTransform([matrix.translate((count%6)*132, Math.floor(count/6)*90), matrix.scale(.65,.65)]);
+			++count;
+			makeShape(customFilter,"none").setTransform([matrix.translate((count%6)*132, Math.floor(count/6)*90), matrix.scale(.65,.65)])
+				.children[0].setFilter(null);
+
+		});
+	});
+</script>
+<body>
+<div id="canvas" style="width:800px;height:900px"></div>
+</body>
+</html>
diff --git a/dojox/gfx/tests/test_fx.html b/dojox/gfx/tests/test_fx.html
index 8b7319b..a8286d6 100644
--- a/dojox/gfx/tests/test_fx.html
+++ b/dojox/gfx/tests/test_fx.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--
 <script type="text/javascript" src="../_base.js"></script>
 <script type="text/javascript" src="../shape.js"></script>
@@ -93,6 +93,20 @@ var animateTransform = function(){
 	dojo.connect(anim, "onEnd", function(){ dojo.byId("transform").disabled = ""; });
 	anim.play();
 };
+
+var animateMatrix = function(){
+	var customMatrix = dojox.gfx.matrix.multiply([dojox.gfx.matrix.rotategAt(-90,250,250),dojox.gfx.matrix.translate(100,100),dojox.gfx.matrix.scaleAt(2,250,250)]);
+	var anim = dojox.gfx.fx.animateTransform({
+		duration:	5000,
+		shape: 		text,
+		transform:	[
+			{name: "matrix", start: dojox.gfx.matrix.identity, end: customMatrix}
+		]
+	});
+	dojo.byId("matrix").disabled = "disabled";
+	dojo.connect(anim, "onEnd", function(){ dojo.byId("matrix").disabled = ""; });
+	anim.play();
+};
 </script>
 </head>
 <body>
@@ -104,7 +118,9 @@ var animateTransform = function(){
 	 
 	<button id="font" onclick="animateFont();">Font</button>
 	 
-	<button id="transform" onclick="animateTransform();">Transform</button>
+	<button id="transform" onclick="animateTransform();">Transform (predefined primitives)</button>
+	 
+	<button id="matrix" onclick="animateMatrix();">Transform (raw matrix)</button>
 </p>
 <div id="test" style="width: 500px; height: 500px;"></div>
 <p>That's all Folks!</p>
diff --git a/dojox/gfx/tests/test_fx_shapes.html b/dojox/gfx/tests/test_fx_shapes.html
index 941c026..34c2578 100644
--- a/dojox/gfx/tests/test_fx_shapes.html
+++ b/dojox/gfx/tests/test_fx_shapes.html
@@ -4,7 +4,7 @@
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
         <title>Animate rectangles</title>
         <!--<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/dojo/1.3/dojo/dojo.xd.js"></script>-->
-        <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+        <script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
         <script type="text/javascript" charset="utf-8">
             dojo.require("dojox.gfx");
             dojo.require("dojo.fx");
diff --git a/dojox/gfx/tests/test_gfx.html b/dojox/gfx/tests/test_gfx.html
index 8ffd140..6a58ec2 100644
--- a/dojox/gfx/tests/test_gfx.html
+++ b/dojox/gfx/tests/test_gfx.html
@@ -12,11 +12,11 @@
 	</style>
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="async: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 
-		require(['dojox/gfx','dojo/domReady!'], function(gfx){
+		require(['dojox/gfx', 'dojo/dom', 'dojo/domReady!'], function(gfx, dom){
 
 		var gTestContainer = null;
 		var gTests = {};
@@ -102,7 +102,7 @@
 
 		var runTest = dojo.config.isDebug ? runTest_debug : runTest_nodebug;
 
-			gTestContainer = dojo.byId('testcontainer');
+			gTestContainer = dom.byId('testcontainer');
 			var rect = { x: 0, y: 0, width: 100, height: 100 };
 
 			addTest('rect', function(testName, surface){
@@ -376,11 +376,11 @@
 					.setTransform({dx: 40, dy: 30})
 					;
 		//		surface.createRect(rect)
-		//			.setShape({width: 200})
-		//			.setStroke({})
-		//			.setFill(rg)
-		//			.setTransform({dx: 40, dy: 30})
-		//			;
+		//		.setShape({width: 200})
+		//		.setStroke({})
+		//		.setFill(rg)
+		//		.setTransform({dx: 40, dy: 30})
+		//		;
 			});
 
 			addTest('attach_gradient', function(testName, surface) {
diff --git a/dojox/gfx/tests/test_gfx_amd.html b/dojox/gfx/tests/test_gfx_amd.html
index c29ee6a..cc29683 100644
--- a/dojox/gfx/tests/test_gfx_amd.html
+++ b/dojox/gfx/tests/test_gfx_amd.html
@@ -12,11 +12,11 @@
 	</style>
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="async: true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 
-		require(['dojox/gfx','dojox/gfx/matrix','dojo/domReady!'], function(Gfx, Matrix){
+		require(['dojo/dom', 'dojox/gfx', 'dojox/gfx/matrix','dojo/domReady!'], function(dom, Gfx, Matrix){
 
 		var gTestContainer = null;
 		var gTests = {};
@@ -102,7 +102,7 @@
 
 		var runTest = dojo.config.isDebug ? runTest_debug : runTest_nodebug;
 
-			gTestContainer = dojo.byId('testcontainer');
+			gTestContainer = dom.byId('testcontainer');
 			var rect = { x: 0, y: 0, width: 100, height: 100 };
 
 			addTest('rect', function(testName, surface){
@@ -376,11 +376,11 @@
 					.setTransform({dx: 40, dy: 30})
 					;
 		//		surface.createRect(rect)
-		//			.setShape({width: 200})
-		//			.setStroke({})
-		//			.setFill(rg)
-		//			.setTransform({dx: 40, dy: 30})
-		//			;
+		//		.setShape({width: 200})
+		//		.setStroke({})
+		//		.setFill(rg)
+		//		.setTransform({dx: 40, dy: 30})
+		//		;
 			});
 
 			addTest('attach_gradient', function(testName, surface) {
diff --git a/dojox/gfx/tests/test_gradient.html b/dojox/gfx/tests/test_gradient.html
index 251fc0a..7a7cf81 100644
--- a/dojox/gfx/tests/test_gradient.html
+++ b/dojox/gfx/tests/test_gradient.html
@@ -6,7 +6,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--<script type="text/javascript" src="../vml.js"></script>-->
 <!--<script type="text/javascript" src="../svg.js"></script>-->
 <!--<script type="text/javascript" src="../silverlight.js"></script>-->
diff --git a/dojox/gfx/tests/test_group1.html b/dojox/gfx/tests/test_group1.html
index 0b265e6..5f07126 100644
--- a/dojox/gfx/tests/test_group1.html
+++ b/dojox/gfx/tests/test_group1.html
@@ -6,7 +6,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--<script type="text/javascript" src="../matrix.js"></script>-->
 <!--<script type="text/javascript" src="../util.js"></script>-->
 <!--<script type="text/javascript" src="../shape.js"></script>-->
diff --git a/dojox/gfx/tests/test_group2.html b/dojox/gfx/tests/test_group2.html
index c2fc153..ecbd3f3 100644
--- a/dojox/gfx/tests/test_group2.html
+++ b/dojox/gfx/tests/test_group2.html
@@ -6,7 +6,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 	@import "../../../dijit/themes/tundra/tundra.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 dojo.require("dijit.form.CheckBox");
diff --git a/dojox/gfx/tests/test_image1.html b/dojox/gfx/tests/test_image1.html
index dacd984..91d84e2 100644
--- a/dojox/gfx/tests/test_image1.html
+++ b/dojox/gfx/tests/test_image1.html
@@ -6,7 +6,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
diff --git a/dojox/gfx/tests/test_image2.html b/dojox/gfx/tests/test_image2.html
index e4ff8d5..e765c92 100644
--- a/dojox/gfx/tests/test_image2.html
+++ b/dojox/gfx/tests/test_image2.html
@@ -2,7 +2,7 @@
 <head>
 <title>Testing image</title>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--<script type="text/javascript" src="../vml.js"></script>-->
 <!--<script type="text/javascript" src="../svg.js"></script>-->
 <!--<script type="text/javascript" src="../silverlight.js"></script>-->
diff --git a/dojox/gfx/tests/test_image3.html b/dojox/gfx/tests/test_image3.html
index 23fe299..86c044d 100755
--- a/dojox/gfx/tests/test_image3.html
+++ b/dojox/gfx/tests/test_image3.html
@@ -6,7 +6,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
diff --git a/dojox/gfx/tests/test_image4.html b/dojox/gfx/tests/test_image4.html
index c79f1d5..b55901e 100644
--- a/dojox/gfx/tests/test_image4.html
+++ b/dojox/gfx/tests/test_image4.html
@@ -6,7 +6,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--<script type="text/javascript" src="../vml.js"></script>-->
 <!--<script type="text/javascript" src="../svg.js"></script>-->
 <!--<script type="text/javascript" src="../silverlight.js"></script>-->
diff --git a/dojox/gfx/tests/test_image5.html b/dojox/gfx/tests/test_image5.html
index 91eac54..50ad29f 100644
--- a/dojox/gfx/tests/test_image5.html
+++ b/dojox/gfx/tests/test_image5.html
@@ -1,54 +1,43 @@
-<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
+<!DOCTYPE html>
+<html>
 <head>
+<meta charset="utf-8">
 <title>Testing image 5</title>
-<style type="text/css">
+<style>
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
-<!--<script type="text/javascript" src="../vml.js"></script>-->
-<!--<script type="text/javascript" src="../svg.js"></script>-->
-<!--<script type="text/javascript" src="../silverlight.js"></script>-->
-<script type="text/javascript">
-dojo.require("dojox.gfx");
-dojo.require("dojox.gfx.move");
-dojo.require("dojo.colors");
+<script src="../../../dojo/dojo.js" data-dojo-config="isDebug:1, async: true"></script>
+<script>
+require(["dojox/gfx", "dojox/gfx/matrix", "dojox/gfx/Moveable", "dojo/domReady!"], function(gfx, matrix, Moveable){
+	var surface = gfx.createSurface("test", 800, 600);
+	surface.whenLoaded(function(surface){
+		var gridSize = 800,
+			gridStep = 50;
 
-createSurface = function(){
-	var surface = dojox.gfx.createSurface("test", 800, 600);
-	surface.whenLoaded(makeShapes);
-};
+		for(var i = 0; i <= gridSize; i += gridStep){
+			surface.createLine({ x1: 0, x2: gridSize, y1: i, y2: i }).setStroke("gray");
+			surface.createLine({ y1: 0, y2: gridSize, x1: i, x2: i }).setStroke("gray");
+		}
 
-makeShapes = function(surface){
-    var g = dojox.gfx, m = g.matrix;
-    
-	var grid_size = 800, grid_step = 50;
-	for(var i = 0; i <= grid_size; i += grid_step){
-		surface.createLine({x1: 0, x2: grid_size, y1: i, y2: i}).setStroke("grey");
-		surface.createLine({y1: 0, y2: grid_size, x1: i, x2: i}).setStroke("grey");
-	}
-    
-    var rect1 = surface.createRect({x: 0, y: 0, width: 300, height: 200, r: 5}).setFill("red").setStroke("black");
-    var img1  = surface.createImage({width: 300, height: 200, src: "images/eugene-sm.jpg"}).setTransform({dx: 50, dy: 50});
-    var rect2 = surface.createRect({x: 100, y: 100, width: 300, height: 200, r: 5}).setFill("yellow").setStroke("black");
-    var img2  = surface.createImage({width: 300, height: 200, src: "images/eugene-sm.gif"}).setTransform({dx: 150, dy: 150});
-    var rect3 = surface.createRect({x: 200, y: 200, width: 300, height: 200, r: 5}).setFill("green").setStroke("black");
-    var img3  = surface.createImage({width: 300, height: 200, src: "images/eugene-sm.png"}).setTransform({dx: 250, dy: 250});
-    var rect4 = surface.createRect({x: 300, y: 300, width: 300, height: 200, r: 5}).setFill("blue").setStroke("black");
-    
-	new g.Moveable(rect1);
-	new g.Moveable(rect2);
-	new g.Moveable(rect3);
-	new g.Moveable(rect4);
+		var rect1 = surface.createRect({ x: 0, y: 0, width: 300, height: 200, r: 5 }).setFill("red").setStroke("black");
+		var img1  = surface.createImage({ width: 300, height: 200, src: "images/eugene-sm.jpg"}).setTransform({ dx: 50, dy: 50 });
+		var rect2 = surface.createRect({ x: 100, y: 100, width: 300, height: 200, r: 5 }).setFill("yellow").setStroke("black");
+		var img2  = surface.createImage({ width: 300, height: 200, src: "images/eugene-sm.gif"}).setTransform({ dx: 150, dy: 150 });
+		var rect3 = surface.createRect({ x: 200, y: 200, width: 300, height: 200, r: 5 }).setFill("green").setStroke("black");
+		var img3  = surface.createImage({ width: 300, height: 200, src: "images/eugene-sm.png"}).setTransform({ dx: 250, dy: 250 });
+		var rect4 = surface.createRect({ x: 300, y: 300, width: 300, height: 200, r: 5 }).setFill("blue").setStroke("black");
 
-	new g.Moveable(img1);
-	new g.Moveable(img2);
-	new g.Moveable(img3);
-};
-
-dojo.addOnLoad(createSurface);
+		new Moveable(rect1);
+		new Moveable(rect2);
+		new Moveable(rect3);
+		new Moveable(rect4);
 
+		new Moveable(img1);
+		new Moveable(img2);
+		new Moveable(img3);
+	});
+});
 </script>
 </head>
 <body>
@@ -61,6 +50,5 @@ dojo.addOnLoad(createSurface);
     <img src="images/eugene-sm.gif">
     <img src="images/eugene-sm.png">
 </p>
-<p>That's all Folks!</p>
 </body>
 </html>
diff --git a/dojox/gfx/tests/test_imagedata.html b/dojox/gfx/tests/test_imagedata.html
new file mode 100644
index 0000000..0b6db3b
--- /dev/null
+++ b/dojox/gfx/tests/test_imagedata.html
@@ -0,0 +1,583 @@
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+		<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true,parseOnLoad: true, async:1, gfxRenderer:'canvas'"></script>
+		<script>
+			require([
+				"dojo/_base/array",
+				"dojo/dom",
+				"dojo/on",
+				"dojo/aspect",
+				"dojox/gfx",
+				"dojox/gfx/matrix",
+				"dojo/ready",
+				"dojox/gfx/canvasext"],
+				function(array, dom, on, aspect, gfx, matrix, ready){
+					
+					var initial_matrix = matrix.translate(250, 250), surface;
+					
+					var drawTiger = function(){
+						var g = surface.createGroup().setTransform(initial_matrix);
+						var f, s = {color: "black", width: 1};
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-122.304 84.285C-122.304 84.285 -122.203 86.179 -123.027 86.16C-123.851 86.141 -140.305 38.066 -160.833 40.309C-160.833 40.309 -143.05 32.956 -122.304 84.285z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-118.774 81.262C-118.774 81.262 -119.323 83.078 -120.092 82.779C-120.86 82.481 -119.977 31.675 -140.043 26.801C-140.043 26.801 -120.82 25.937 -118.774 81.262z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-91.284 123.59C-91.284 123.59 -89.648 124.55 -90.118 125.227C-90.589 125.904 -139.763 113.102 -149.218 131.459C-149.218 131.459 -145.539 112.572 -91.284 123.59z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-94.093 133.801C-94.093 133.801 -92.237 134.197 -92.471 134.988C-92.704 135.779 -143.407 139.121 -146.597 159.522C-146.597 159.522 -149.055 140.437 -94.093 133.801z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-98.304 128.276C-98.304 128.276 -96.526 128.939 -96.872 129.687C-97.218 130.435 -147.866 126.346 -153.998 146.064C-153.998 146.064 -153.646 126.825 -98.304 128.276z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-109.009 110.072C-109.009 110.072 -107.701 111.446 -108.34 111.967C-108.979 112.488 -152.722 86.634 -166.869 101.676C-166.869 101.676 -158.128 84.533 -109.009 110.072z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-116.554 114.263C-116.554 114.263 -115.098 115.48 -115.674 116.071C-116.25 116.661 -162.638 95.922 -174.992 112.469C-174.992 112.469 -168.247 94.447 -116.554 114.263z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-119.154 118.335C-119.154 118.335 -117.546 119.343 -118.036 120.006C-118.526 120.669 -167.308 106.446 -177.291 124.522C-177.291 124.522 -173.066 105.749 -119.154 118.335z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-108.42 118.949C-108.42 118.949 -107.298 120.48 -107.999 120.915C-108.7 121.35 -148.769 90.102 -164.727 103.207C-164.727 103.207 -153.862 87.326 -108.42 118.949z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-128.2 90C-128.2 90 -127.6 91.8 -128.4 92C-129.2 92.2 -157.8 50.2 -177.001 57.8C-177.001 57.8 -161.8 46 -128.2 90z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-127.505 96.979C-127.505 96.979 -126.53 98.608 -127.269 98.975C-128.007 99.343 -164.992 64.499 -182.101 76.061C-182.101 76.061 -169.804 61.261 -127.505 96.979z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.172};
+						g.createPath("M-127.62 101.349C-127.62 101.349 -126.498 102.88 -127.199 103.315C-127.9 103.749 -167.969 72.502 -183.927 85.607C-183.927 85.607 -173.062 69.726 -127.62 101.349z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = "#000000";
+						g.createPath("M-129.83 103.065C-129.327 109.113 -128.339 115.682 -126.6 118.801C-126.6 118.801 -130.2 131.201 -121.4 144.401C-121.4 144.401 -121.8 151.601 -120.2 154.801C-120.2 154.801 -116.2 163.201 -111.4 164.001C-107.516 164.648 -98.793 167.717 -88.932 169.121C-88.932 169.121 -71.8 183.201 -75 196.001C-75 196.001 -75.4 212.401 -79 214.001C-79 214.001 -67.4 202.801 -77 219.601L-81.4 238.401C-81.4 238.401 -55.8 216.801 -71.4 235.201L-81.4 261.201C-81.4 261.201 -61.8 242.801 -69 25 [...]
+						f = "#cc7226"; s = "#000000";
+						g.createPath("M299.717 80.245C300.345 80.426 302.551 81.55 303.801 83.2C303.801 83.2 310.601 94 305.401 75.6C305.401 75.6 296.201 46.8 305.001 58C305.001 58 311.001 65.2 307.801 51.6C303.936 35.173 301.401 28.8 301.401 28.8C301.401 28.8 313.001 33.6 286.201 -6L295.001 -2.4C295.001 -2.4 275.401 -42 253.801 -47.2L245.801 -53.2C245.801 -53.2 284.201 -91.2 271.401 -128C271.401 -128 264.601 -133.2 255.001 -124C255.001 -124 248.601 -119.2 242.601 -120.8C242.601 -120.8 211.801 -119.6 209. [...]
+						f = "#cc7226"; s = null;
+						g.createPath("M-115.6 102.6C-140.6 63.2 -126.2 119.601 -126.2 119.601C-117.4 154.001 12.2 116.401 12.2 116.401C12.2 116.401 181.001 86 192.201 82C203.401 78 298.601 84.4 298.601 84.4L293.001 67.6C228.201 21.2 209.001 44.4 195.401 40.4C181.801 36.4 184.201 46 181.001 46.8C177.801 47.6 138.601 22.8 132.201 23.6C125.801 24.4 100.459 0.649 115.401 32.4C131.401 66.4 57 71.6 40.2 60.4C23.4 49.2 47.4 78.8 47.4 78.8C65.8 98.8 31.4 82 31.4 82C-3 69.2 -27 94.8 -30.2 95.6C-33.4 96.4 -38.2 99. [...]
+						f = "#e87f3a";
+						g.createPath("M133.51 25.346C127.11 26.146 101.743 2.407 116.71 34.146C133.31 69.346 58.31 73.346 41.51 62.146C24.709 50.946 48.71 80.546 48.71 80.546C67.11 100.546 32.709 83.746 32.709 83.746C-1.691 70.946 -25.691 96.546 -28.891 97.346C-32.091 98.146 -36.891 101.346 -37.691 94.946C-38.491 88.546 -45.87 72.012 -77.691 98.146C-98.927 115.492 -112.418 94.037 -112.418 94.037L-115.618 104.146C-140.618 64.346 -125.546 122.655 -125.546 122.655C-116.745 157.056 13.509 118.146 13.509 118.1 [...]
+						f = "#ea8c4d";
+						g.createPath("M134.819 27.091C128.419 27.891 103.685 3.862 118.019 35.891C134.219 72.092 59.619 75.092 42.819 63.892C26.019 52.692 50.019 82.292 50.019 82.292C68.419 102.292 34.019 85.492 34.019 85.492C-0.381 72.692 -24.382 98.292 -27.582 99.092C-30.782 99.892 -35.582 103.092 -36.382 96.692C-37.182 90.292 -44.43 73.925 -76.382 99.892C-98.855 117.983 -112.036 97.074 -112.036 97.074L-115.636 105.692C-139.436 66.692 -124.891 125.71 -124.891 125.71C-116.091 160.11 14.819 119.892 14.819 [...]
+						f = "#ec9961";
+						g.createPath("M136.128 28.837C129.728 29.637 104.999 5.605 119.328 37.637C136.128 75.193 60.394 76.482 44.128 65.637C27.328 54.437 51.328 84.037 51.328 84.037C69.728 104.037 35.328 87.237 35.328 87.237C0.928 74.437 -23.072 100.037 -26.272 100.837C-29.472 101.637 -34.272 104.837 -35.072 98.437C-35.872 92.037 -42.989 75.839 -75.073 101.637C-98.782 120.474 -111.655 100.11 -111.655 100.11L-115.655 107.237C-137.455 70.437 -124.236 128.765 -124.236 128.765C-115.436 163.165 16.128 121.637 [...]
+						f = "#eea575";
+						g.createPath("M137.438 30.583C131.037 31.383 106.814 7.129 120.637 39.383C137.438 78.583 62.237 78.583 45.437 67.383C28.637 56.183 52.637 85.783 52.637 85.783C71.037 105.783 36.637 88.983 36.637 88.983C2.237 76.183 -21.763 101.783 -24.963 102.583C-28.163 103.383 -32.963 106.583 -33.763 100.183C-34.563 93.783 -41.548 77.752 -73.763 103.383C-98.709 122.965 -111.273 103.146 -111.273 103.146L-115.673 108.783C-135.473 73.982 -123.582 131.819 -123.582 131.819C-114.782 166.22 17.437 123.3 [...]
+						f = "#f1b288";
+						g.createPath("M138.747 32.328C132.347 33.128 106.383 9.677 121.947 41.128C141.147 79.928 63.546 80.328 46.746 69.128C29.946 57.928 53.946 87.528 53.946 87.528C72.346 107.528 37.946 90.728 37.946 90.728C3.546 77.928 -20.454 103.528 -23.654 104.328C-26.854 105.128 -31.654 108.328 -32.454 101.928C-33.254 95.528 -40.108 79.665 -72.454 105.128C-98.636 125.456 -110.891 106.183 -110.891 106.183L-115.691 110.328C-133.691 77.128 -122.927 134.874 -122.927 134.874C-114.127 169.274 18.746 125. [...]
+						f = "#f3bf9c";
+						g.createPath("M140.056 34.073C133.655 34.873 107.313 11.613 123.255 42.873C143.656 82.874 64.855 82.074 48.055 70.874C31.255 59.674 55.255 89.274 55.255 89.274C73.655 109.274 39.255 92.474 39.255 92.474C4.855 79.674 -19.145 105.274 -22.345 106.074C-25.545 106.874 -30.345 110.074 -31.145 103.674C-31.945 97.274 -38.668 81.578 -71.145 106.874C-98.564 127.947 -110.509 109.219 -110.509 109.219L-115.709 111.874C-131.709 81.674 -122.273 137.929 -122.273 137.929C-113.473 172.329 20.055 126 [...]
+						f = "#f5ccb0";
+						g.createPath("M141.365 35.819C134.965 36.619 107.523 13.944 124.565 44.619C146.565 84.219 66.164 83.819 49.364 72.619C32.564 61.419 56.564 91.019 56.564 91.019C74.964 111.019 40.564 94.219 40.564 94.219C6.164 81.419 -17.836 107.019 -21.036 107.819C-24.236 108.619 -29.036 111.819 -29.836 105.419C-30.636 99.019 -37.227 83.492 -69.836 108.619C-98.491 130.438 -110.127 112.256 -110.127 112.256L-115.727 113.419C-130.128 85.019 -121.618 140.983 -121.618 140.983C-112.818 175.384 21.364 128 [...]
+						f = "#f8d8c4";
+						g.createPath("M142.674 37.565C136.274 38.365 108.832 15.689 125.874 46.365C147.874 85.965 67.474 85.565 50.674 74.365C33.874 63.165 57.874 92.765 57.874 92.765C76.274 112.765 41.874 95.965 41.874 95.965C7.473 83.165 -16.527 108.765 -19.727 109.565C-22.927 110.365 -27.727 113.565 -28.527 107.165C-29.327 100.765 -35.786 85.405 -68.527 110.365C-98.418 132.929 -109.745 115.293 -109.745 115.293L-115.745 114.965C-129.346 88.564 -120.963 144.038 -120.963 144.038C-112.163 178.438 22.673 13 [...]
+						f = "#fae5d7";
+						g.createPath("M143.983 39.31C137.583 40.11 110.529 17.223 127.183 48.11C149.183 88.91 68.783 87.31 51.983 76.11C35.183 64.91 59.183 94.51 59.183 94.51C77.583 114.51 43.183 97.71 43.183 97.71C8.783 84.91 -15.217 110.51 -18.417 111.31C-21.618 112.11 -26.418 115.31 -27.218 108.91C-28.018 102.51 -34.346 87.318 -67.218 112.11C-98.345 135.42 -109.363 118.329 -109.363 118.329L-115.764 116.51C-128.764 92.51 -120.309 147.093 -120.309 147.093C-111.509 181.493 23.983 132.11 23.983 132.11C23.9 [...]
+						f = "#fcf2eb";
+						g.createPath("M145.292 41.055C138.892 41.855 112.917 18.411 128.492 49.855C149.692 92.656 70.092 89.056 53.292 77.856C36.492 66.656 60.492 96.256 60.492 96.256C78.892 116.256 44.492 99.456 44.492 99.456C10.092 86.656 -13.908 112.256 -17.108 113.056C-20.308 113.856 -25.108 117.056 -25.908 110.656C-26.708 104.256 -32.905 89.232 -65.908 113.856C-98.273 137.911 -108.982 121.365 -108.982 121.365L-115.782 118.056C-128.582 94.856 -119.654 150.147 -119.654 150.147C-110.854 184.547 25.292 1 [...]
+						f = "#ffffff";
+						g.createPath("M-115.8 119.601C-128.6 97.6 -119 153.201 -119 153.201C-110.2 187.601 26.6 135.601 26.6 135.601C26.6 135.601 195.401 105.2 206.601 101.2C217.801 97.2 303.401 102.8 303.401 102.8L298.601 80.4C233.801 34 223.401 63.6 209.801 59.6C196.201 55.6 198.601 65.2 195.401 66C192.201 66.8 153.001 42 146.601 42.8C140.201 43.6 114.981 19.793 129.801 51.6C152.028 99.307 69.041 89.227 54.6 79.6C37.8 68.4 61.8 98 61.8 98C80.2 118.001 45.8 101.2 45.8 101.2C11.4 88.4 -12.6 114.001 -15.8  [...]
+						f = "#000000";
+						g.createPath("M-74.2 149.601C-74.2 149.601 -81.4 161.201 -60.6 174.401C-60.6 174.401 -59.2 175.801 -77.2 171.601C-77.2 171.601 -83.4 169.601 -85 159.201C-85 159.201 -89.8 154.801 -94.6 149.201C-99.4 143.601 -74.2 149.601 -74.2 149.601z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M65.8 102C65.8 102 83.498 128.821 82.9 133.601C81.6 144.001 81.4 153.601 84.6 157.601C87.801 161.601 96.601 194.801 96.601 194.801C96.601 194.801 96.201 196.001 108.601 158.001C108.601 158.001 120.201 142.001 100.201 123.601C100.201 123.601 65 94.8 65.8 102z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-54.2 176.401C-54.2 176.401 -43 183.601 -57.4 214.801L-51 212.401C-51 212.401 -51.8 223.601 -55 226.001L-47.8 222.801C-47.8 222.801 -43 230.801 -47 235.601C-47 235.601 -30.2 243.601 -31 250.001C-31 250.001 -24.6 242.001 -28.6 235.601C-32.6 229.201 -39.8 233.201 -39 214.801L-47.8 218.001C-47.8 218.001 -42.2 209.201 -42.2 202.801L-50.2 205.201C-50.2 205.201 -34.731 178.623 -45.4 177.201C-51.4 176.401 -54.2 176.401 -54.2 176.401z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-21.8 193.201C-21.8 193.201 -19 188.801 -21.8 189.601C-24.6 190.401 -55.8 205.201 -61.8 214.801C-61.8 214.801 -27.4 190.401 -21.8 193.201z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-11.4 201.201C-11.4 201.201 -8.6 196.801 -11.4 197.601C-14.2 198.401 -45.4 213.201 -51.4 222.801C-51.4 222.801 -17 198.401 -11.4 201.201z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M1.8 186.001C1.8 186.001 4.6 181.601 1.8 182.401C-1 183.201 -32.2 198.001 -38.2 207.601C-38.2 207.601 -3.8 183.201 1.8 186.001z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-21.4 229.601C-21.4 229.601 -21.4 223.601 -24.2 224.401C-27 225.201 -63 242.801 -69 252.401C-69 252.401 -27 226.801 -21.4 229.601z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-20.2 218.801C-20.2 218.801 -19 214.001 -21.8 214.801C-23.8 214.801 -50.2 226.401 -56.2 236.001C-56.2 236.001 -26.6 214.401 -20.2 218.801z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-34.6 266.401L-44.6 274.001C-44.6 274.001 -34.2 266.401 -30.6 267.601C-30.6 267.601 -37.4 278.801 -38.2 284.001C-38.2 284.001 -27.8 271.201 -22.2 271.601C-22.2 271.601 -14.6 272.001 -14.6 282.801C-14.6 282.801 -9 272.401 -5.8 272.801C-5.8 272.801 -4.6 279.201 -5.8 286.001C-5.8 286.001 -1.8 278.401 2.2 280.001C2.2 280.001 8.6 278.001 7.8 289.601C7.8 289.601 7.8 300.001 7 302.801C7 302.801 12.6 276.401 15 276.001C15 276.001 23 274.801 27.8 283.601C27.8 283.601 23.8 276 [...]
+						f = "#000000";
+						g.createPath("M-29.8 173.601C-29.8 173.601 -15 167.601 25 173.601C25 173.601 32.2 174.001 39 165.201C45.8 156.401 72.6 149.201 79 151.201L88.601 157.601L89.401 158.801C89.401 158.801 101.801 169.201 102.201 176.801C102.601 184.401 87.801 232.401 78.2 248.401C68.6 264.401 59 276.801 39.8 274.401C39.8 274.401 19 270.401 -6.6 274.401C-6.6 274.401 -35.8 272.801 -38.6 264.801C-41.4 256.801 -27.4 241.601 -27.4 241.601C-27.4 241.601 -23 233.201 -24.2 218.801C-25.4 204.401 -25 176.401 -29. [...]
+						f = "#e5668c";
+						g.createPath("M-7.8 175.601C0.6 194.001 -29 259.201 -29 259.201C-31 260.801 -16.34 266.846 -6.2 264.401C4.746 261.763 45 266.001 45 266.001C68.6 250.401 81.4 206.001 81.4 206.001C81.4 206.001 91.801 182.001 74.2 178.801C56.6 175.601 -7.8 175.601 -7.8 175.601z").setFill(f).setStroke(s);
+						f = "#b23259";
+						g.createPath("M-9.831 206.497C-6.505 193.707 -4.921 181.906 -7.8 175.601C-7.8 175.601 54.6 182.001 65.8 161.201C70.041 153.326 84.801 184.001 84.4 193.601C84.4 193.601 21.4 208.001 6.6 196.801L-9.831 206.497z").setFill(f).setStroke(s);
+						f = "#a5264c";
+						g.createPath("M-5.4 222.801C-5.4 222.801 -3.4 230.001 -5.8 234.001C-5.8 234.001 -7.4 234.801 -8.6 235.201C-8.6 235.201 -7.4 238.801 -1.4 240.401C-1.4 240.401 0.6 244.801 3 245.201C5.4 245.601 10.2 251.201 14.2 250.001C18.2 248.801 29.4 244.801 29.4 244.801C29.4 244.801 35 241.601 43.8 245.201C43.8 245.201 46.175 244.399 46.6 240.401C47.1 235.701 50.2 232.001 52.2 230.001C54.2 228.001 63.8 215.201 62.6 214.801C61.4 214.401 -5.4 222.801 -5.4 222.801z").setFill(f).setStroke(s);
+						f = "#ff727f"; s = "#000000";
+						g.createPath("M-9.8 174.401C-9.8 174.401 -12.6 196.801 -9.4 205.201C-6.2 213.601 -7 215.601 -7.8 219.601C-8.6 223.601 -4.2 233.601 1.4 239.601L13.4 241.201C13.4 241.201 28.6 237.601 37.8 240.401C37.8 240.401 46.794 241.744 50.2 226.801C50.2 226.801 55 220.401 62.2 217.601C69.4 214.801 76.6 173.201 72.6 165.201C68.6 157.201 54.2 152.801 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-8.2 249.201C-8.2 249.201 -9 247.201 -13.4 246.801C-13.4 246.801 -35.8 243.201 -44.2 230.801C-44.2 230.801 -51 225.201 -46.6 236.801C-46.6 236.801 -36.2 257.201 -29.4 260.001C-29.4 260.001 -13 264.001 -8.2 249.201z").setFill(f).setStroke(s);
+						f = "#cc3f4c"; s = null;
+						g.createPath("M71.742 185.229C72.401 177.323 74.354 168.709 72.6 165.201C66.154 152.307 49.181 157.695 38.2 168.401C22.2 184.001 20.2 167.201 -9.8 174.401C-9.8 174.401 -11.545 188.364 -10.705 198.376C-10.705 198.376 26.6 186.801 27.4 192.401C27.4 192.401 29 189.201 38.2 189.201C47.4 189.201 70.142 188.029 71.742 185.229z").setFill(f).setStroke(s);
+						s = {color: "#a51926", width: 2}; f = null;
+						g.createPath("M28.6 175.201C28.6 175.201 33.4 180.001 29.8 189.601C29.8 189.601 15.4 205.601 17.4 219.601").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-19.4 260.001C-19.4 260.001 -23.8 247.201 -15 254.001C-15 254.001 -10.2 256.001 -11.4 257.601C-12.6 259.201 -18.2 263.201 -19.4 260.001z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-14.36 261.201C-14.36 261.201 -17.88 250.961 -10.84 256.401C-10.84 256.401 -6.419 258.849 -7.96 259.281C-12.52 260.561 -7.96 263.121 -14.36 261.201z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-9.56 261.201C-9.56 261.201 -13.08 250.961 -6.04 256.401C-6.04 256.401 -1.665 258.711 -3.16 259.281C-6.52 260.561 -3.16 263.121 -9.56 261.201z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-2.96 261.401C-2.96 261.401 -6.48 251.161 0.56 256.601C0.56 256.601 4.943 258.933 3.441 259.481C0.48 260.561 3.441 263.321 -2.96 261.401z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M3.52 261.321C3.52 261.321 0 251.081 7.041 256.521C7.041 256.521 10.881 258.121 9.921 259.401C8.961 260.681 9.921 263.241 3.52 261.321z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M10.2 262.001C10.2 262.001 5.4 249.601 14.6 256.001C14.6 256.001 19.4 258.001 18.2 259.601C17 261.201 18.2 264.401 10.2 262.001z").setFill(f).setStroke(s);
+						s = {color: "#a5264c", width: 2}; f = null;
+						g.createPath("M-18.2 244.801C-18.2 244.801 -5 242.001 1 245.201C1 245.201 7 246.401 8.2 246.001C9.4 245.601 12.6 245.201 12.6 245.201").setFill(f).setStroke(s);
+						s = {color: "#a5264c", width: 2};
+						g.createPath("M15.8 253.601C15.8 253.601 27.8 240.001 39.8 244.401C46.816 246.974 45.8 243.601 46.6 240.801C47.4 238.001 47.6 233.801 52.6 230.801").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M33 237.601C33 237.601 29 226.801 26.2 239.601C23.4 252.401 20.2 256.001 18.6 258.801C18.6 258.801 18.6 264.001 27 263.601C27 263.601 37.8 263.201 38.2 260.401C38.6 257.601 37 246.001 33 237.601z").setFill(f).setStroke(s);
+						s = {color: "#a5264c", width: 2}; f = null;
+						g.createPath("M47 244.801C47 244.801 50.6 242.401 53 243.601").setFill(f).setStroke(s);
+						s = {color: "#a5264c", width: 2};
+						g.createPath("M53.5 228.401C53.5 228.401 56.4 223.501 61.2 222.701").setFill(f).setStroke(s);
+						f = "#b2b2b2"; s = null;
+						g.createPath("M-25.8 265.201C-25.8 265.201 -7.8 268.401 -3.4 266.801C-3.4 266.801 5.4 266.801 -3 268.801C-3 268.801 -15.8 268.801 -23.8 267.601C-23.8 267.601 -35.4 262.001 -25.8 265.201z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-11.8 172.001C-11.8 172.001 5.8 172.001 7.8 172.801C7.8 172.801 15 203.601 11.4 211.201C11.4 211.201 10.2 214.001 7.4 208.401C7.4 208.401 -11 175.601 -14.2 173.601C-17.4 171.601 -13 172.001 -11.8 172.001z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-88.9 169.301C-88.9 169.301 -80 171.001 -67.4 173.601C-67.4 173.601 -62.6 196.001 -59.4 200.801C-56.2 205.601 -59.8 205.601 -63.4 202.801C-67 200.001 -81.8 186.001 -83.8 181.601C-85.8 177.201 -88.9 169.301 -88.9 169.301z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-67.039 173.818C-67.039 173.818 -61.239 175.366 -60.23 177.581C-59.222 179.795 -61.432 183.092 -61.432 183.092C-61.432 183.092 -62.432 186.397 -63.634 184.235C-64.836 182.072 -67.708 174.412 -67.039 173.818z").setFill(f).setStroke(s);
+						f = "#000000"; s = null;
+						g.createPath("M-67 173.601C-67 173.601 -63.4 178.801 -59.8 178.801C-56.2 178.801 -55.818 178.388 -53 179.001C-48.4 180.001 -48.8 178.001 -42.2 179.201C-39.56 179.681 -37 178.801 -34.2 180.001C-31.4 181.201 -28.2 180.401 -27 178.401C-25.8 176.401 -21 172.201 -21 172.201C-21 172.201 -33.8 174.001 -36.6 174.801C-36.6 174.801 -59 176.001 -67 173.601z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-22.4 173.801C-22.4 173.801 -28.85 177.301 -29.25 179.701C-29.65 182.101 -24 185.801 -24 185.801C-24 185.801 -21.25 190.401 -20.65 188.001C-20.05 185.601 -21.6 174.201 -22.4 173.801z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-59.885 179.265C-59.885 179.265 -52.878 190.453 -52.661 179.242C-52.661 179.242 -52.104 177.984 -53.864 177.962C-59.939 177.886 -58.418 173.784 -59.885 179.265z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-52.707 179.514C-52.707 179.514 -44.786 190.701 -45.422 179.421C-45.422 179.421 -45.415 179.089 -47.168 178.936C-51.915 178.522 -51.57 174.004 -52.707 179.514z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-45.494 179.522C-45.494 179.522 -37.534 190.15 -38.203 180.484C-38.203 180.484 -38.084 179.251 -39.738 178.95C-43.63 178.244 -43.841 174.995 -45.494 179.522z").setFill(f).setStroke(s);
+						f = "#ffffcc"; s = {color: "#000000", width: 0.5};
+						g.createPath("M-38.618 179.602C-38.618 179.602 -30.718 191.163 -30.37 181.382C-30.37 181.382 -28.726 180.004 -30.472 179.782C-36.29 179.042 -35.492 174.588 -38.618 179.602z").setFill(f).setStroke(s);
+						f = "#e5e5b2"; s = null;
+						g.createPath("M-74.792 183.132L-82.45 181.601C-85.05 176.601 -87.15 170.451 -87.15 170.451C-87.15 170.451 -80.8 171.451 -68.3 174.251C-68.3 174.251 -67.424 177.569 -65.952 183.364L-74.792 183.132z").setFill(f).setStroke(s);
+						f = "#e5e5b2";
+						g.createPath("M-9.724 178.47C-11.39 175.964 -12.707 174.206 -13.357 173.8C-16.37 171.917 -12.227 172.294 -11.098 172.294C-11.098 172.294 5.473 172.294 7.356 173.047C7.356 173.047 7.88 175.289 8.564 178.68C8.564 178.68 -1.524 176.67 -9.724 178.47z").setFill(f).setStroke(s);
+						f = "#cc7226";
+						g.createPath("M43.88 40.321C71.601 44.281 97.121 8.641 98.881 -1.04C100.641 -10.72 90.521 -22.6 90.521 -22.6C91.841 -25.68 87.001 -39.76 81.721 -49C76.441 -58.24 60.54 -57.266 43 -58.24C27.16 -59.12 8.68 -35.8 7.36 -34.04C6.04 -32.28 12.2 6.001 13.52 11.721C14.84 17.441 12.2 43.841 12.2 43.841C46.44 34.741 16.16 36.361 43.88 40.321z").setFill(f).setStroke(s);
+						f = "#ea8e51";
+						g.createPath("M8.088 -33.392C6.792 -31.664 12.84 5.921 14.136 11.537C15.432 17.153 12.84 43.073 12.84 43.073C45.512 34.193 16.728 35.729 43.944 39.617C71.161 43.505 96.217 8.513 97.945 -0.992C99.673 -10.496 89.737 -22.16 89.737 -22.16C91.033 -25.184 86.281 -39.008 81.097 -48.08C75.913 -57.152 60.302 -56.195 43.08 -57.152C27.528 -58.016 9.384 -35.12 8.088 -33.392z").setFill(f).setStroke(s);
+						f = "#efaa7c";
+						g.createPath("M8.816 -32.744C7.544 -31.048 13.48 5.841 14.752 11.353C16.024 16.865 13.48 42.305 13.48 42.305C44.884 33.145 17.296 35.097 44.008 38.913C70.721 42.729 95.313 8.385 97.009 -0.944C98.705 -10.272 88.953 -21.72 88.953 -21.72C90.225 -24.688 85.561 -38.256 80.473 -47.16C75.385 -56.064 60.063 -55.125 43.16 -56.064C27.896 -56.912 10.088 -34.44 8.816 -32.744z").setFill(f).setStroke(s);
+						f = "#f4c6a8";
+						g.createPath("M9.544 -32.096C8.296 -30.432 14.12 5.761 15.368 11.169C16.616 16.577 14.12 41.537 14.12 41.537C43.556 32.497 17.864 34.465 44.072 38.209C70.281 41.953 94.409 8.257 96.073 -0.895C97.737 -10.048 88.169 -21.28 88.169 -21.28C89.417 -24.192 84.841 -37.504 79.849 -46.24C74.857 -54.976 59.824 -54.055 43.24 -54.976C28.264 -55.808 10.792 -33.76 9.544 -32.096z").setFill(f).setStroke(s);
+						f = "#f9e2d3";
+						g.createPath("M10.272 -31.448C9.048 -29.816 14.76 5.681 15.984 10.985C17.208 16.289 14.76 40.769 14.76 40.769C42.628 31.849 18.432 33.833 44.136 37.505C69.841 41.177 93.505 8.129 95.137 -0.848C96.769 -9.824 87.385 -20.84 87.385 -20.84C88.609 -23.696 84.121 -36.752 79.225 -45.32C74.329 -53.888 59.585 -52.985 43.32 -53.888C28.632 -54.704 11.496 -33.08 10.272 -31.448z").setFill(f).setStroke(s);
+						f = "#ffffff";
+						g.createPath("M44.2 36.8C69.4 40.4 92.601 8 94.201 -0.8C95.801 -9.6 86.601 -20.4 86.601 -20.4C87.801 -23.2 83.4 -36 78.6 -44.4C73.8 -52.8 59.346 -51.914 43.4 -52.8C29 -53.6 12.2 -32.4 11 -30.8C9.8 -29.2 15.4 5.6 16.6 10.8C17.8 16 15.4 40 15.4 40C40.9 31.4 19 33.2 44.2 36.8z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M90.601 2.8C90.601 2.8 62.8 10.4 51.2 8.8C51.2 8.8 35.4 2.2 26.6 24C26.6 24 23 31.2 21 33.2C19 35.2 90.601 2.8 90.601 2.8z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M94.401 0.6C94.401 0.6 65.4 12.8 55.4 12.4C55.4 12.4 39 7.8 30.6 22.4C30.6 22.4 22.2 31.6 19 33.2C19 33.2 18.6 34.8 25 30.8L35.4 36C35.4 36 50.2 45.6 59.8 29.6C59.8 29.6 63.8 18.4 63.8 16.4C63.8 14.4 85 8.8 86.601 8.4C88.201 8 94.801 3.8 94.401 0.6z").setFill(f).setStroke(s);
+						f = "#99cc32";
+						g.createPath("M47 36.514C40.128 36.514 31.755 32.649 31.755 26.4C31.755 20.152 40.128 13.887 47 13.887C53.874 13.887 59.446 18.952 59.446 25.2C59.446 31.449 53.874 36.514 47 36.514z").setFill(f).setStroke(s);
+						f = "#659900";
+						g.createPath("M43.377 19.83C38.531 20.552 33.442 22.055 33.514 21.839C35.054 17.22 41.415 13.887 47 13.887C51.296 13.887 55.084 15.865 57.32 18.875C57.32 18.875 52.004 18.545 43.377 19.83z").setFill(f).setStroke(s);
+						f = "#ffffff";
+						g.createPath("M55.4 19.6C55.4 19.6 51 16.4 51 18.6C51 18.6 54.6 23 55.4 19.6z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M45.4 27.726C42.901 27.726 40.875 25.7 40.875 23.2C40.875 20.701 42.901 18.675 45.4 18.675C47.9 18.675 49.926 20.701 49.926 23.2C49.926 25.7 47.9 27.726 45.4 27.726z").setFill(f).setStroke(s);
+						f = "#cc7226";
+						g.createPath("M-58.6 14.4C-58.6 14.4 -61.8 -6.8 -59.4 -11.2C-59.4 -11.2 -48.6 -21.2 -49 -24.8C-49 -24.8 -49.4 -42.8 -50.6 -43.6C-51.8 -44.4 -59.4 -50.4 -65.4 -44C-65.4 -44 -75.8 -26 -75 -19.6L-75 -17.6C-75 -17.6 -82.6 -18 -84.2 -16C-84.2 -16 -85.4 -10.8 -86.6 -10.4C-86.6 -10.4 -89.4 -8 -87.4 -5.2C-87.4 -5.2 -89.4 -2.8 -89 1.2L-81.4 5.2C-81.4 5.2 -79.4 19.6 -68.6 24.8C-63.764 27.129 -60.6 20.4 -58.6 14.4z").setFill(f).setStroke(s);
+						f = "#ffffff";
+						g.createPath("M-59.6 12.56C-59.6 12.56 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.48 -40.36 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.96 -59.6 12.56z").set [...]
+						f = "#eb955c";
+						g.createPath("M-51.05 -42.61C-52.14 -43.47 -59.63 -49.24 -65.48 -43C-65.48 -43 -75.62 -25.45 -74.84 -19.21L-74.84 -17.26C-74.84 -17.26 -82.25 -17.65 -83.81 -15.7C-83.81 -15.7 -84.98 -10.63 -86.15 -10.24C-86.15 -10.24 -88.88 -7.9 -86.93 -5.17C-86.93 -5.17 -88.88 -2.83 -88.49 1.07L-81.08 4.97C-81.08 4.97 -79.13 19.01 -68.6 24.08C-63.886 26.35 -60.8 19.79 -58.85 13.94C-58.85 13.94 -61.97 -6.73 -59.63 -11.02C-59.63 -11.02 -49.1 -20.77 -49.49 -24.28C-49.49 -24.28 -49.88 -41.83 -51.05 -4 [...]
+						f = "#f2b892";
+						g.createPath("M-51.5 -41.62C-52.48 -42.54 -59.86 -48.08 -65.56 -42C-65.56 -42 -75.44 -24.9 -74.68 -18.82L-74.68 -16.92C-74.68 -16.92 -81.9 -17.3 -83.42 -15.4C-83.42 -15.4 -84.56 -10.46 -85.7 -10.08C-85.7 -10.08 -88.36 -7.8 -86.46 -5.14C-86.46 -5.14 -88.36 -2.86 -87.98 0.94L-80.76 4.74C-80.76 4.74 -78.86 18.42 -68.6 23.36C-64.006 25.572 -61 19.18 -59.1 13.48C-59.1 13.48 -62.14 -6.66 -59.86 -10.84C-59.86 -10.84 -49.6 -20.34 -49.98 -23.76C-49.98 -23.76 -50.36 -40.86 -51.5 -41.62z").se [...]
+						f = "#f8dcc8";
+						g.createPath("M-51.95 -40.63C-52.82 -41.61 -60.09 -46.92 -65.64 -41C-65.64 -41 -75.26 -24.35 -74.52 -18.43L-74.52 -16.58C-74.52 -16.58 -81.55 -16.95 -83.03 -15.1C-83.03 -15.1 -84.14 -10.29 -85.25 -9.92C-85.25 -9.92 -87.84 -7.7 -85.99 -5.11C-85.99 -5.11 -87.84 -2.89 -87.47 0.81L-80.44 4.51C-80.44 4.51 -78.59 17.83 -68.6 22.64C-64.127 24.794 -61.2 18.57 -59.35 13.02C-59.35 13.02 -62.31 -6.59 -60.09 -10.66C-60.09 -10.66 -50.1 -19.91 -50.47 -23.24C-50.47 -23.24 -50.84 -39.89 -51.95 -40 [...]
+						f = "#ffffff";
+						g.createPath("M-59.6 12.46C-59.6 12.46 -62.48 -6.52 -60.32 -10.48C-60.32 -10.48 -50.6 -19.48 -50.96 -22.72C-50.96 -22.72 -51.32 -38.92 -52.4 -39.64C-53.16 -40.68 -60.32 -45.76 -65.72 -40C-65.72 -40 -75.08 -23.8 -74.36 -18.04L-74.36 -16.24C-74.36 -16.24 -81.2 -16.6 -82.64 -14.8C-82.64 -14.8 -83.72 -10.12 -84.8 -9.76C-84.8 -9.76 -87.32 -7.6 -85.52 -5.08C-85.52 -5.08 -87.32 -2.92 -86.96 0.68L-80.12 4.28C-80.12 4.28 -78.32 17.24 -68.6 21.92C-64.248 24.015 -61.4 17.86 -59.6 12.46z").set [...]
+						f = "#cccccc";
+						g.createPath("M-62.7 6.2C-62.7 6.2 -84.3 -4 -85.2 -4.8C-85.2 -4.8 -76.1 3.4 -75.3 3.4C-74.5 3.4 -62.7 6.2 -62.7 6.2z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-79.8 0C-79.8 0 -61.4 3.6 -61.4 8C-61.4 10.912 -61.643 24.331 -67 22.8C-75.4 20.4 -71.8 6 -79.8 0z").setFill(f).setStroke(s);
+						f = "#99cc32";
+						g.createPath("M-71.4 3.8C-71.4 3.8 -62.422 5.274 -61.4 8C-60.8 9.6 -60.137 17.908 -65.6 19C-70.152 19.911 -72.382 9.69 -71.4 3.8z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M14.595 46.349C14.098 44.607 15.409 44.738 17.2 44.2C19.2 43.6 31.4 39.8 32.2 37.2C33 34.6 46.2 39 46.2 39C48 39.8 52.4 42.4 52.4 42.4C57.2 43.6 63.8 44 63.8 44C66.2 45 69.6 47.8 69.6 47.8C84.2 58 96.601 50.8 96.601 50.8C116.601 44.2 110.601 27 110.601 27C107.601 18 110.801 14.6 110.801 14.6C111.001 10.8 118.201 17.2 118.201 17.2C120.801 21.4 121.601 26.4 121.601 26.4C129.601 37.6 126.201 19.8 126.201 19.8C126.401 18.8 123.601 15.2 123.601 14C123.601 12.8 121.801 9.4  [...]
+						f = "#000000";
+						g.createPath("M209.401 -120C209.401 -120 183.801 -112 181.001 -93.2C181.001 -93.2 178.601 -70.4 199.001 -52.8C199.001 -52.8 199.401 -46.4 201.401 -43.2C201.401 -43.2 199.801 -38.4 218.601 -46L245.801 -54.4C245.801 -54.4 252.201 -56.8 257.401 -65.6C262.601 -74.4 277.801 -93.2 274.201 -118.4C274.201 -118.4 275.401 -129.6 269.401 -130C269.401 -130 261.001 -131.6 253.801 -124C253.801 -124 247.001 -120.8 244.601 -121.2L209.401 -120z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M264.022 -120.99C264.022 -120.99 266.122 -129.92 261.282 -125.08C261.282 -125.08 254.242 -119.36 246.761 -119.36C246.761 -119.36 232.241 -117.16 227.841 -103.96C227.841 -103.96 223.881 -77.12 231.801 -71.4C231.801 -71.4 236.641 -63.92 243.681 -70.52C250.722 -77.12 266.222 -107.35 264.022 -120.99z").setFill(f).setStroke(s);
+						f = "#323232";
+						g.createPath("M263.648 -120.632C263.648 -120.632 265.738 -129.376 260.986 -124.624C260.986 -124.624 254.074 -119.008 246.729 -119.008C246.729 -119.008 232.473 -116.848 228.153 -103.888C228.153 -103.888 224.265 -77.536 232.041 -71.92C232.041 -71.92 236.793 -64.576 243.705 -71.056C250.618 -77.536 265.808 -107.24 263.648 -120.632z").setFill(f).setStroke(s);
+						f = "#666666";
+						g.createPath("M263.274 -120.274C263.274 -120.274 265.354 -128.832 260.69 -124.168C260.69 -124.168 253.906 -118.656 246.697 -118.656C246.697 -118.656 232.705 -116.536 228.465 -103.816C228.465 -103.816 224.649 -77.952 232.281 -72.44C232.281 -72.44 236.945 -65.232 243.729 -71.592C250.514 -77.952 265.394 -107.13 263.274 -120.274z").setFill(f).setStroke(s);
+						f = "#999999";
+						g.createPath("M262.9 -119.916C262.9 -119.916 264.97 -128.288 260.394 -123.712C260.394 -123.712 253.738 -118.304 246.665 -118.304C246.665 -118.304 232.937 -116.224 228.777 -103.744C228.777 -103.744 225.033 -78.368 232.521 -72.96C232.521 -72.96 237.097 -65.888 243.753 -72.128C250.41 -78.368 264.98 -107.02 262.9 -119.916z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M262.526 -119.558C262.526 -119.558 264.586 -127.744 260.098 -123.256C260.098 -123.256 253.569 -117.952 246.633 -117.952C246.633 -117.952 233.169 -115.912 229.089 -103.672C229.089 -103.672 225.417 -78.784 232.761 -73.48C232.761 -73.48 237.249 -66.544 243.777 -72.664C250.305 -78.784 264.566 -106.91 262.526 -119.558z").setFill(f).setStroke(s);
+						f = "#ffffff";
+						g.createPath("M262.151 -119.2C262.151 -119.2 264.201 -127.2 259.801 -122.8C259.801 -122.8 253.401 -117.6 246.601 -117.6C246.601 -117.6 233.401 -115.6 229.401 -103.6C229.401 -103.6 225.801 -79.2 233.001 -74C233.001 -74 237.401 -67.2 243.801 -73.2C250.201 -79.2 264.151 -106.8 262.151 -119.2z").setFill(f).setStroke(s);
+						f = "#992600";
+						g.createPath("M50.6 84C50.6 84 30.2 64.8 22.2 64C22.2 64 -12.2 60 -27 78C-27 78 -9.4 57.6 18.2 63.2C18.2 63.2 -3.4 58.8 -15.8 62C-15.8 62 -32.6 62 -42.2 76L-45 80.8C-45 80.8 -41 66 -22.6 60C-22.6 60 0.2 55.2 11 60C11 60 -10.6 53.2 -20.6 55.2C-20.6 55.2 -51 52.8 -63.8 79.2C-63.8 79.2 -59.8 64.8 -45 57.6C-45 57.6 -31.4 48.8 -11 51.6C-11 51.6 3.4 54.8 8.6 57.2C13.8 59.6 12.6 56.8 4.2 52C4.2 52 -1.4 42 -15.4 42.4C-15.4 42.4 -58.2 46 -68.6 58C-68.6 58 -55 46.8 -44.6 44C-44.6 44 -22.2 36 [...]
+						f = "#cccccc";
+						g.createPath("M189 278C189 278 173.5 241.5 161 232C161 232 187 248 190.5 266C190.5 266 190.5 276 189 278z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M236 285.5C236 285.5 209.5 230.5 191 206.5C191 206.5 234.5 244 239.5 270.5L240 276L237 273.5C237 273.5 236.5 282.5 236 285.5z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M292.5 237C292.5 237 230 177.5 228.5 175C228.5 175 289 241 292 248.5C292 248.5 290 239.5 292.5 237z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M104 280.5C104 280.5 123.5 228.5 142.5 251C142.5 251 157.5 261 157 264C157 264 153 257.5 135 258C135 258 116 255 104 280.5z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M294.5 153C294.5 153 249.5 124.5 242 123C230.193 120.639 291.5 152 296.5 162.5C296.5 162.5 298.5 160 294.5 153z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M143.801 259.601C143.801 259.601 164.201 257.601 171.001 250.801L175.401 254.401L193.001 216.001L196.601 221.201C196.601 221.201 211.001 206.401 210.201 198.401C209.401 190.401 223.001 204.401 223.001 204.401C223.001 204.401 222.201 192.801 229.401 199.601C229.401 199.601 227.001 184.001 235.401 192.001C235.401 192.001 224.864 161.844 247.401 187.601C253.001 194.001 248.601 187.201 248.601 187.201C248.601 187.201 222.601 139.201 244.201 153.601C244.201 153.601 246.201 [...]
+						f = "#000000";
+						g.createPath("M109.401 -97.2C109.401 -97.2 97.801 -105.2 93.801 -104.8C89.801 -104.4 121.401 -113.6 162.601 -86C162.601 -86 167.401 -83.2 171.001 -83.6C171.001 -83.6 174.201 -81.2 171.401 -77.6C171.401 -77.6 162.601 -68 173.801 -56.8C173.801 -56.8 192.201 -50 186.601 -58.8C186.601 -58.8 197.401 -54.8 199.801 -50.8C202.201 -46.8 201.001 -50.8 201.001 -50.8C201.001 -50.8 194.601 -58 188.601 -63.2C188.601 -63.2 183.401 -65.2 180.601 -73.6C177.801 -82 175.401 -92 179.801 -95.2C179.801  [...]
+						f = "#cc7226";
+						g.createPath("M180.801 -106.4C180.801 -106.4 170.601 -113.8 168.601 -113.8C166.601 -113.8 154.201 -124 150.001 -123.6C145.801 -123.2 133.601 -133.2 106.201 -125C106.201 -125 105.601 -127 109.201 -127.8C109.201 -127.8 115.601 -130 116.001 -130.6C116.001 -130.6 136.201 -134.8 143.401 -131.2C143.401 -131.2 152.601 -128.6 158.801 -122.4C158.801 -122.4 170.001 -119.2 173.201 -120.2C173.201 -120.2 182.001 -118 182.401 -116.2C182.401 -116.2 188.201 -113.2 186.401 -110.6C186.401 -110.6 186 [...]
+						f = "#cc7226";
+						g.createPath("M168.33 -108.509C169.137 -107.877 170.156 -107.779 170.761 -106.97C170.995 -106.656 170.706 -106.33 170.391 -106.233C169.348 -105.916 168.292 -106.486 167.15 -105.898C166.748 -105.691 166.106 -105.873 165.553 -106.022C163.921 -106.463 162.092 -106.488 160.401 -105.8C158.416 -106.929 156.056 -106.345 153.975 -107.346C153.917 -107.373 153.695 -107.027 153.621 -107.054C150.575 -108.199 146.832 -107.916 144.401 -110.2C141.973 -110.612 139.616 -111.074 137.188 -111.754C135 [...]
+						f = "#cc7226";
+						g.createPath("M91.696 -122.739C89.178 -124.464 86.81 -125.57 84.368 -127.356C84.187 -127.489 83.827 -127.319 83.625 -127.441C82.618 -128.05 81.73 -128.631 80.748 -129.327C80.209 -129.709 79.388 -129.698 78.88 -129.956C76.336 -131.248 73.707 -131.806 71.2 -133C71.882 -133.638 73.004 -133.394 73.6 -134.2C73.795 -133.92 74.033 -133.636 74.386 -133.827C76.064 -134.731 77.914 -134.884 79.59 -134.794C81.294 -134.702 83.014 -134.397 84.789 -134.125C85.096 -134.078 85.295 -133.555 85.618 - [...]
+						f = "#cc7226";
+						g.createPath("M59.198 -115.391C56.044 -116.185 52.994 -116.07 49.978 -117.346C49.911 -117.374 49.688 -117.027 49.624 -117.054C48.258 -117.648 47.34 -118.614 46.264 -119.66C45.351 -120.548 43.693 -120.161 42.419 -120.648C42.095 -120.772 41.892 -121.284 41.591 -121.323C40.372 -121.48 39.445 -122.429 38.4 -123C40.736 -123.795 43.147 -123.764 45.609 -124.148C45.722 -124.166 45.867 -123.845 46 -123.845C46.136 -123.845 46.266 -124.066 46.4 -124.2C46.595 -123.92 46.897 -123.594 47.154 -12 [...]
+						f = "#cc7226";
+						g.createPath("M45.338 -71.179C43.746 -72.398 43.162 -74.429 42.034 -76.221C41.82 -76.561 42.094 -76.875 42.411 -76.964C42.971 -77.123 43.514 -76.645 43.923 -76.443C45.668 -75.581 47.203 -74.339 49.2 -74.2C51.19 -71.966 55.45 -71.581 55.457 -68.2C55.458 -67.341 54.03 -68.259 53.6 -67.4C51.149 -68.403 48.76 -68.3 46.38 -69.767C45.763 -70.148 46.093 -70.601 45.338 -71.179z").setFill(f).setStroke(s);
+						f = "#cc7226";
+						g.createPath("M17.8 -123.756C17.935 -123.755 24.966 -123.522 24.949 -123.408C24.904 -123.099 17.174 -122.05 16.81 -122.22C16.646 -122.296 9.134 -119.866 9 -120C9.268 -120.135 17.534 -123.756 17.8 -123.756z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M33.2 -114C33.2 -114 18.4 -112.2 14 -111C9.6 -109.8 -9 -102.2 -12 -100.2C-12 -100.2 -25.4 -94.8 -42.4 -74.8C-42.4 -74.8 -34.8 -78.2 -32.6 -81C-32.6 -81 -19 -93.6 -19.2 -91C-19.2 -91 -7 -99.6 -7.6 -97.4C-7.6 -97.4 16.8 -108.6 14.8 -105.4C14.8 -105.4 36.4 -110 35.4 -108C35.4 -108 54.2 -103.6 51.4 -103.4C51.4 -103.4 45.6 -102.2 52 -98.6C52 -98.6 48.6 -94.2 43.2 -98.2C37.8 -102.2 40.8 -100 35.8 -99C35.8 -99 33.2 -98.2 28.6 -102.2C28.6 -102.2 23 -106.8 14.2 -103.2C14.2 -10 [...]
+						s = {color: "#4c0000", width: 2}; f = null;
+						g.createPath("M51.4 85C51.4 85 36.4 68.2 28 65.6C28 65.6 14.6 58.8 -10 66.6").setFill(f).setStroke(s);
+						s = {color: "#4c0000", width: 2};
+						g.createPath("M24.8 64.2C24.8 64.2 -0.4 56.2 -15.8 60.4C-15.8 60.4 -34.2 62.4 -42.6 76.2").setFill(f).setStroke(s);
+						s = {color: "#4c0000", width: 2};
+						g.createPath("M21.2 63C21.2 63 4.2 55.8 -10.6 53.6C-10.6 53.6 -27.2 51 -43.8 58.2C-43.8 58.2 -56 64.2 -61.4 74.4").setFill(f).setStroke(s);
+						s = {color: "#4c0000", width: 2};
+						g.createPath("M22.2 63.4C22.2 63.4 6.8 52.4 5.8 51C5.8 51 -1.2 40 -14.2 39.6C-14.2 39.6 -35.6 40.4 -52.8 48.4").setFill(f).setStroke(s);
+						f = "#000000"; s = null;
+						g.createPath("M20.895 54.407C22.437 55.87 49.4 84.8 49.4 84.8C84.6 121.401 56.6 87.2 56.6 87.2C49 82.4 39.8 63.6 39.8 63.6C38.6 60.8 53.8 70.8 53.8 70.8C57.8 71.6 71.4 90.8 71.4 90.8C64.6 88.4 69.4 95.6 69.4 95.6C72.2 97.6 92.601 113.201 92.601 113.201C96.201 117.201 100.201 118.801 100.201 118.801C114.201 113.601 107.801 126.801 107.801 126.801C110.201 133.601 115.801 122.001 115.801 122.001C127.001 105.2 110.601 107.601 110.601 107.601C80.6 110.401 73.8 94.4 73.8 94.4C71.4 92 80. [...]
+						f = "#4c0000";
+						g.createPath("M-3 42.8C-3 42.8 8.6 48.4 11.2 51.2C13.8 54 27.8 65.4 27.8 65.4C27.8 65.4 22.4 63.4 19.8 61.6C17.2 59.8 6.4 51.6 6.4 51.6C6.4 51.6 2.6 45.6 -3 42.8z").setFill(f).setStroke(s);
+						f = "#99cc32";
+						g.createPath("M-61.009 11.603C-60.672 11.455 -61.196 8.743 -61.4 8.2C-62.422 5.474 -71.4 4 -71.4 4C-71.627 5.365 -71.682 6.961 -71.576 8.599C-71.576 8.599 -66.708 14.118 -61.009 11.603z").setFill(f).setStroke(s);
+						f = "#659900";
+						g.createPath("M-61.009 11.403C-61.458 11.561 -61.024 8.669 -61.2 8.2C-62.222 5.474 -71.4 3.9 -71.4 3.9C-71.627 5.265 -71.682 6.861 -71.576 8.499C-71.576 8.499 -67.308 13.618 -61.009 11.403z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-65.4 11.546C-66.025 11.546 -66.531 10.406 -66.531 9C-66.531 7.595 -66.025 6.455 -65.4 6.455C-64.775 6.455 -64.268 7.595 -64.268 9C-64.268 10.406 -64.775 11.546 -65.4 11.546z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-65.4 9z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-111 109.601C-111 109.601 -116.6 119.601 -91.8 113.601C-91.8 113.601 -77.8 112.401 -75.4 110.001C-74.2 110.801 -65.834 113.734 -63 114.401C-56.2 116.001 -47.8 106 -47.8 106C-47.8 106 -43.2 95.5 -40.4 95.5C-37.6 95.5 -40.8 97.1 -40.8 97.1C-40.8 97.1 -47.4 107.201 -47 108.801C-47 108.801 -52.2 128.801 -68.2 129.601C-68.2 129.601 -84.35 130.551 -83 136.401C-83 136.401 -74.2 134.001 -71.8 136.401C-71.8 136.401 -61 136.001 -69 142.401L-75.8 154.001C-75.8 154.001 -75.66 15 [...]
+						f = "#e59999";
+						g.createPath("M-112.2 113.601C-112.2 113.601 -114.2 123.201 -77.4 112.801C-77.4 112.801 -73 112.801 -70.6 113.601C-68.2 114.401 -56.2 117.201 -54.2 116.001C-54.2 116.001 -61.4 129.601 -73 128.001C-73 128.001 -86.2 129.601 -85.8 134.401C-85.8 134.401 -81.8 141.601 -77 144.001C-77 144.001 -74.2 146.401 -74.6 149.601C-75 152.801 -77.8 154.401 -79.8 155.201C-81.8 156.001 -85 152.801 -86.6 152.801C-88.2 152.801 -96.6 146.401 -101 141.601C-105.4 136.801 -113.8 124.801 -113.4 122.001C-113 [...]
+						f = "#b26565";
+						g.createPath("M-109 131.051C-106.4 135.001 -103.2 139.201 -101 141.601C-96.6 146.401 -88.2 152.801 -86.6 152.801C-85 152.801 -81.8 156.001 -79.8 155.201C-77.8 154.401 -75 152.801 -74.6 149.601C-74.2 146.401 -77 144.001 -77 144.001C-80.066 142.468 -82.806 138.976 -84.385 136.653C-84.385 136.653 -84.2 139.201 -89.4 138.401C-94.6 137.601 -99.8 134.801 -101.4 131.601C-103 128.401 -105.4 126.001 -103.8 129.601C-102.2 133.201 -99.8 136.801 -98.2 137.201C-96.6 137.601 -97 138.801 -99.4 13 [...]
+						f = "#992600";
+						g.createPath("M-111.6 110.001C-111.6 110.001 -109.8 96.4 -108.6 92.4C-108.6 92.4 -109.4 85.6 -107 81.4C-104.6 77.2 -102.6 71 -99.6 65.6C-96.6 60.2 -96.4 56.2 -92.4 54.6C-88.4 53 -82.4 44.4 -79.6 43.4C-76.8 42.4 -77 43.2 -77 43.2C-77 43.2 -70.2 28.4 -56.6 32.4C-56.6 32.4 -72.8 29.6 -57 20.2C-57 20.2 -61.8 21.3 -58.5 14.3C-56.299 9.632 -56.8 16.4 -67.8 28.2C-67.8 28.2 -72.8 36.8 -78 39.8C-83.2 42.8 -95.2 49.8 -96.4 53.6C-97.6 57.4 -100.8 63.2 -102.8 64.8C-104.8 66.4 -107.6 70.6 -108  [...]
+						f = "#ffffff";
+						g.createPath("M-120.2 114.601C-120.2 114.601 -122.2 113.201 -126.6 119.201C-126.6 119.201 -119.3 152.201 -119.3 153.601C-119.3 153.601 -118.2 151.501 -119.5 144.301C-120.8 137.101 -121.7 124.401 -121.7 124.401L-120.2 114.601z").setFill(f).setStroke(s);
+						f = "#992600";
+						g.createPath("M-98.6 54C-98.6 54 -116.2 57.2 -115.8 86.4L-116.6 111.201C-116.6 111.201 -117.8 85.6 -119 84C-120.2 82.4 -116.2 71.2 -119.4 77.2C-119.4 77.2 -133.4 91.2 -125.4 112.401C-125.4 112.401 -123.9 115.701 -126.9 111.101C-126.9 111.101 -131.5 98.5 -130.4 92.1C-130.4 92.1 -130.2 89.9 -128.3 87.1C-128.3 87.1 -119.7 75.4 -117 73.1C-117 73.1 -115.2 58.7 -99.8 53.5C-99.8 53.5 -94.1 51.2 -98.6 54z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M40.8 -12.2C41.46 -12.554 41.451 -13.524 42.031 -13.697C43.18 -14.041 43.344 -15.108 43.862 -15.892C44.735 -17.211 44.928 -18.744 45.51 -20.235C45.782 -20.935 45.809 -21.89 45.496 -22.55C44.322 -25.031 43.62 -27.48 42.178 -29.906C41.91 -30.356 41.648 -31.15 41.447 -31.748C40.984 -33.132 39.727 -34.123 38.867 -35.443C38.579 -35.884 39.104 -36.809 38.388 -36.893C37.491 -36.998 36.042 -37.578 35.809 -36.552C35.221 -33.965 36.232 -31.442 37.2 -29C36.418 -28.308 36.752 -27 [...]
+						f = "#000000";
+						g.createPath("M31.959 -16.666C32.083 -16.743 31.928 -17.166 32.037 -17.382C32.199 -17.706 32.602 -17.894 32.764 -18.218C32.873 -18.434 32.71 -18.814 32.846 -18.956C35.179 -21.403 35.436 -24.427 34.4 -27.4C35.424 -28.02 35.485 -29.282 35.06 -30.129C34.207 -31.829 34.014 -33.755 33.039 -35.298C32.237 -36.567 30.659 -37.811 29.288 -36.508C28.867 -36.108 28.546 -35.321 28.824 -34.609C28.888 -34.446 29.173 -34.3 29.146 -34.218C29.039 -33.894 28.493 -33.67 28.487 -33.398C28.457 -31.902 2 [...]
+						f = "#000000";
+						g.createPath("M94.771 -26.977C96.16 -25.185 96.45 -22.39 94.401 -21C94.951 -17.691 98.302 -19.67 100.401 -20.2C100.292 -20.588 100.519 -20.932 100.802 -20.937C101.859 -20.952 102.539 -21.984 103.601 -21.8C104.035 -23.357 105.673 -24.059 106.317 -25.439C108.043 -29.134 107.452 -33.407 104.868 -36.653C104.666 -36.907 104.883 -37.424 104.759 -37.786C104.003 -39.997 101.935 -40.312 100.001 -41C98.824 -44.875 98.163 -48.906 96.401 -52.6C94.787 -52.85 94.089 -54.589 92.752 -55.309C91.419 [...]
+						f = "#000000";
+						g.createPath("M57.611 -8.591C56.124 -6.74 52.712 -4.171 55.629 -2.243C55.823 -2.114 56.193 -2.11 56.366 -2.244C58.387 -3.809 60.39 -4.712 62.826 -5.294C62.95 -5.323 63.224 -4.856 63.593 -5.017C65.206 -5.72 67.216 -5.662 68.4 -7C72.167 -6.776 75.732 -7.892 79.123 -9.2C80.284 -9.648 81.554 -10.207 82.755 -10.709C84.131 -11.285 85.335 -12.213 86.447 -13.354C86.58 -13.49 86.934 -13.4 87.201 -13.4C87.161 -14.263 88.123 -14.39 88.37 -15.012C88.462 -15.244 88.312 -15.64 88.445 -15.742C90. [...]
+						f = "#000000";
+						g.createPath("M2.2 -58C2.2 -58 -7.038 -60.872 -18.2 -35.2C-18.2 -35.2 -20.6 -30 -23 -28C-25.4 -26 -36.6 -22.4 -38.6 -18.4L-49 -2.4C-49 -2.4 -34.2 -18.4 -31 -20.8C-31 -20.8 -23 -29.2 -26.2 -22.4C-26.2 -22.4 -40.2 -11.6 -39 -2.4C-39 -2.4 -44.6 12 -45.4 14C-45.4 14 -29.4 -18 -27 -19.2C-24.6 -20.4 -23.4 -20.4 -24.6 -16.8C-25.8 -13.2 -26.2 3.2 -29 5.2C-29 5.2 -21 -15.2 -21.8 -18.4C-21.8 -18.4 -18.6 -22 -16.2 -16.8L-17.4 -0.8L-13 11.2C-13 11.2 -15.4 0 -13.8 -15.6C-13.8 -15.6 -15.8 -26 -1 [...]
+						f = "#000000";
+						g.createPath("M-17.8 -41.6C-17.8 -41.6 -30.6 -41.6 -33.8 -36.4L-41 -26.8C-41 -26.8 -23.8 -36.8 -19.8 -38C-15.8 -39.2 -17.8 -41.6 -17.8 -41.6z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-57.8 -35.2C-57.8 -35.2 -59.8 -34 -60.2 -31.2C-60.6 -28.4 -63 -28 -62.2 -25.2C-61.4 -22.4 -59.4 -20 -59.4 -24C-59.4 -28 -57.8 -30 -57 -31.2C-56.2 -32.4 -54.6 -36.8 -57.8 -35.2z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-66.6 26C-66.6 26 -75 22 -78.2 18.4C-81.4 14.8 -80.948 19.966 -85.8 19.6C-91.647 19.159 -90.6 3.2 -90.6 3.2L-94.6 10.8C-94.6 10.8 -95.8 25.2 -87.8 22.8C-83.893 21.628 -82.6 23.2 -84.2 24C-85.8 24.8 -78.6 25.2 -81.4 26.8C-84.2 28.4 -69.8 23.2 -72.2 33.6L-66.6 26z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-79.2 40.4C-79.2 40.4 -94.6 44.8 -98.2 35.2C-98.2 35.2 -103 37.6 -100.8 40.6C-98.6 43.6 -97.4 44 -97.4 44C-97.4 44 -92 45.2 -92.6 46C-93.2 46.8 -95.6 50.2 -95.6 50.2C-95.6 50.2 -85.4 44.2 -79.2 40.4z").setFill(f).setStroke(s);
+						f = "#ffffff";
+						g.createPath("M149.201 118.601C148.774 120.735 147.103 121.536 145.201 122.201C143.284 121.243 140.686 118.137 138.801 120.201C138.327 119.721 137.548 119.661 137.204 118.999C136.739 118.101 137.011 117.055 136.669 116.257C136.124 114.985 135.415 113.619 135.601 112.201C137.407 111.489 138.002 109.583 137.528 107.82C137.459 107.563 137.03 107.366 137.23 107.017C137.416 106.694 137.734 106.467 138.001 106.2C137.866 106.335 137.721 106.568 137.61 106.548C137 106.442 137.124 105.805 1 [...]
+						f = "#ffffff";
+						g.createPath("M139.6 138.201C139.593 136.463 137.992 134.707 139.201 133.001C139.336 133.135 139.467 133.356 139.601 133.356C139.736 133.356 139.867 133.135 140.001 133.001C141.496 135.217 145.148 136.145 145.006 138.991C144.984 139.438 143.897 140.356 144.801 141.001C142.988 142.349 142.933 144.719 142.001 146.601C140.763 146.315 139.551 145.952 138.401 145.401C138.753 143.915 138.636 142.231 139.456 140.911C139.89 140.213 139.603 139.134 139.6 138.201z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-26.6 129.201C-26.6 129.201 -43.458 139.337 -29.4 124.001C-20.6 114.401 -10.6 108.801 -10.6 108.801C-10.6 108.801 -0.2 104.4 3.4 103.2C7 102 22.2 96.8 25.4 96.4C28.6 96 38.2 92 45 96C51.8 100 59.8 104.4 59.8 104.4C59.8 104.4 43.4 96 39.8 98.4C36.2 100.8 29 100.4 23 103.6C23 103.6 8.2 108.001 5 110.001C1.8 112.001 -8.6 123.601 -10.2 122.801C-11.8 122.001 -9.8 121.601 -8.6 118.801C-7.4 116.001 -9.4 114.401 -17.4 120.801C-25.4 127.201 -26.6 129.201 -26.6 129.201z").setF [...]
+						f = "#000000";
+						g.createPath("M-19.195 123.234C-19.195 123.234 -17.785 110.194 -9.307 111.859C-9.307 111.859 -1.081 107.689 1.641 105.721C1.641 105.721 9.78 104.019 11.09 103.402C29.569 94.702 44.288 99.221 44.835 98.101C45.381 96.982 65.006 104.099 68.615 108.185C69.006 108.628 58.384 102.588 48.686 100.697C40.413 99.083 18.811 100.944 7.905 106.48C4.932 107.989 -4.013 113.773 -6.544 113.662C-9.075 113.55 -19.195 123.234 -19.195 123.234z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-23 148.801C-23 148.801 -38.2 146.401 -21.4 144.801C-21.4 144.801 -3.4 142.801 0.6 137.601C0.6 137.601 14.2 128.401 17 128.001C19.8 127.601 49.8 120.401 50.2 118.001C50.6 115.601 56.2 115.601 57.8 116.401C59.4 117.201 58.6 118.401 55.8 119.201C53 120.001 21.8 136.401 15.4 137.601C9 138.801 -2.6 146.401 -7.4 147.601C-12.2 148.801 -23 148.801 -23 148.801z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-3.48 141.403C-3.48 141.403 -12.062 140.574 -3.461 139.755C-3.461 139.755 5.355 136.331 7.403 133.668C7.403 133.668 14.367 128.957 15.8 128.753C17.234 128.548 31.194 124.861 31.399 123.633C31.604 122.404 65.67 109.823 70.09 113.013C73.001 115.114 63.1 113.437 53.466 117.847C52.111 118.467 18.258 133.054 14.981 133.668C11.704 134.283 5.765 138.174 3.307 138.788C0.85 139.403 -3.48 141.403 -3.48 141.403z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-11.4 143.601C-11.4 143.601 -6.2 143.201 -7.4 144.801C-8.6 146.401 -11 145.601 -11 145.601L-11.4 143.601z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-18.6 145.201C-18.6 145.201 -13.4 144.801 -14.6 146.401C-15.8 148.001 -18.2 147.201 -18.2 147.201L-18.6 145.201z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-29 146.801C-29 146.801 -23.8 146.401 -25 148.001C-26.2 149.601 -28.6 148.801 -28.6 148.801L-29 146.801z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-36.6 147.601C-36.6 147.601 -31.4 147.201 -32.6 148.801C-33.8 150.401 -36.2 149.601 -36.2 149.601L-36.6 147.601z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M1.8 108.001C1.8 108.001 6.2 108.001 5 109.601C3.8 111.201 0.6 110.801 0.6 110.801L1.8 108.001z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-8.2 113.601C-8.2 113.601 -1.694 111.46 -4.2 114.801C-5.4 116.401 -7.8 115.601 -7.8 115.601L-8.2 113.601z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-19.4 118.401C-19.4 118.401 -14.2 118.001 -15.4 119.601C-16.6 121.201 -19 120.401 -19 120.401L-19.4 118.401z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-27 124.401C-27 124.401 -21.8 124.001 -23 125.601C-24.2 127.201 -26.6 126.401 -26.6 126.401L-27 124.401z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-33.8 129.201C-33.8 129.201 -28.6 128.801 -29.8 130.401C-31 132.001 -33.4 131.201 -33.4 131.201L-33.8 129.201z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M5.282 135.598C5.282 135.598 12.203 135.066 10.606 137.195C9.009 139.325 5.814 138.26 5.814 138.26L5.282 135.598z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M15.682 130.798C15.682 130.798 22.603 130.266 21.006 132.395C19.409 134.525 16.214 133.46 16.214 133.46L15.682 130.798z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M26.482 126.398C26.482 126.398 33.403 125.866 31.806 127.995C30.209 130.125 27.014 129.06 27.014 129.06L26.482 126.398z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M36.882 121.598C36.882 121.598 43.803 121.066 42.206 123.195C40.609 125.325 37.414 124.26 37.414 124.26L36.882 121.598z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M9.282 103.598C9.282 103.598 16.203 103.066 14.606 105.195C13.009 107.325 9.014 107.06 9.014 107.06L9.282 103.598z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M19.282 100.398C19.282 100.398 26.203 99.866 24.606 101.995C23.009 104.125 18.614 103.86 18.614 103.86L19.282 100.398z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-3.4 140.401C-3.4 140.401 1.8 140.001 0.6 141.601C-0.6 143.201 -3 142.401 -3 142.401L-3.4 140.401z").setFill(f).setStroke(s);
+						f = "#992600";
+						g.createPath("M-76.6 41.2C-76.6 41.2 -81 50 -81.4 53.2C-81.4 53.2 -80.6 44.4 -79.4 42.4C-78.2 40.4 -76.6 41.2 -76.6 41.2z").setFill(f).setStroke(s);
+						f = "#992600";
+						g.createPath("M-95 55.2C-95 55.2 -98.2 69.6 -97.8 72.4C-97.8 72.4 -99 60.8 -98.6 59.6C-98.2 58.4 -95 55.2 -95 55.2z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-74.2 -19.4L-74.4 -16.2L-76.6 -16C-76.6 -16 -62.4 -3.4 -61.8 4.2C-61.8 4.2 -61 -4 -74.2 -19.4z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-70.216 -18.135C-70.647 -18.551 -70.428 -19.296 -70.836 -19.556C-71.645 -20.072 -69.538 -20.129 -69.766 -20.845C-70.149 -22.051 -69.962 -22.072 -70.084 -23.348C-70.141 -23.946 -69.553 -25.486 -69.168 -25.926C-67.722 -27.578 -69.046 -30.51 -67.406 -32.061C-67.102 -32.35 -66.726 -32.902 -66.441 -33.32C-65.782 -34.283 -64.598 -34.771 -63.648 -35.599C-63.33 -35.875 -63.531 -36.702 -62.962 -36.61C-62.248 -36.495 -61.007 -36.625 -61.052 -35.784C-61.165 -33.664 -62.494 -31. [...]
+						f = "#000000";
+						g.createPath("M-73.8 -16.4C-73.8 -16.4 -73.4 -9.6 -71 -8C-68.6 -6.4 -69.8 -7.2 -73 -8.4C-76.2 -9.6 -75 -10.4 -75 -10.4C-75 -10.4 -77.8 -10 -75.4 -8C-73 -6 -69.4 -3.6 -71 -3.6C-72.6 -3.6 -80.2 -7.6 -80.2 -10.4C-80.2 -13.2 -81.2 -17.3 -81.2 -17.3C-81.2 -17.3 -80.1 -18.1 -75.3 -18C-75.3 -18 -73.9 -17.3 -73.8 -16.4z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-74.6 2.2C-74.6 2.2 -83.12 -0.591 -101.6 2.8C-101.6 2.8 -92.569 0.722 -73.8 3C-63.5 4.25 -74.6 2.2 -74.6 2.2z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-72.502 2.129C-72.502 2.129 -80.748 -1.389 -99.453 0.392C-99.453 0.392 -90.275 -0.897 -71.774 2.995C-61.62 5.131 -72.502 2.129 -72.502 2.129z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-70.714 2.222C-70.714 2.222 -78.676 -1.899 -97.461 -1.514C-97.461 -1.514 -88.213 -2.118 -70.052 3.14C-60.086 6.025 -70.714 2.222 -70.714 2.222z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-69.444 2.445C-69.444 2.445 -76.268 -1.862 -93.142 -2.96C-93.142 -2.96 -84.803 -2.79 -68.922 3.319C-60.206 6.672 -69.444 2.445 -69.444 2.445z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M45.84 12.961C45.84 12.961 44.91 13.605 45.124 12.424C45.339 11.243 73.547 -1.927 77.161 -1.677C77.161 -1.677 46.913 11.529 45.84 12.961z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M42.446 13.6C42.446 13.6 41.57 14.315 41.691 13.121C41.812 11.927 68.899 -3.418 72.521 -3.452C72.521 -3.452 43.404 12.089 42.446 13.6z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M39.16 14.975C39.16 14.975 38.332 15.747 38.374 14.547C38.416 13.348 58.233 -2.149 68.045 -4.023C68.045 -4.023 50.015 4.104 39.16 14.975z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M36.284 16.838C36.284 16.838 35.539 17.532 35.577 16.453C35.615 15.373 53.449 1.426 62.28 -0.26C62.28 -0.26 46.054 7.054 36.284 16.838z").setFill(f).setStroke(s);
+						f = "#cccccc"; s = null;
+						g.createPath("M4.6 164.801C4.6 164.801 -10.6 162.401 6.2 160.801C6.2 160.801 24.2 158.801 28.2 153.601C28.2 153.601 41.8 144.401 44.6 144.001C47.4 143.601 63.8 140.001 64.2 137.601C64.6 135.201 70.6 132.801 72.2 133.601C73.8 134.401 73.8 143.601 71 144.401C68.2 145.201 49.4 152.401 43 153.601C36.6 154.801 25 162.401 20.2 163.601C15.4 164.801 4.6 164.801 4.6 164.801z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M77.6 127.401C77.6 127.401 74.6 129.001 73.4 131.601C73.4 131.601 67 142.201 52.8 145.401C52.8 145.401 29.8 154.401 22 156.401C22 156.401 8.6 161.401 1.2 160.601C1.2 160.601 -5.8 160.801 0.4 162.401C0.4 162.401 20.6 160.401 24 158.601C24 158.601 39.6 153.401 42.6 150.801C45.6 148.201 63.8 143.201 66 141.201C68.2 139.201 78 130.801 77.6 127.401z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M18.882 158.911C18.882 158.911 24.111 158.685 22.958 160.234C21.805 161.784 19.357 160.91 19.357 160.91L18.882 158.911z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M11.68 160.263C11.68 160.263 16.908 160.037 15.756 161.586C14.603 163.136 12.155 162.263 12.155 162.263L11.68 160.263z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M1.251 161.511C1.251 161.511 6.48 161.284 5.327 162.834C4.174 164.383 1.726 163.51 1.726 163.51L1.251 161.511z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-6.383 162.055C-6.383 162.055 -1.154 161.829 -2.307 163.378C-3.46 164.928 -5.908 164.054 -5.908 164.054L-6.383 162.055z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M35.415 151.513C35.415 151.513 42.375 151.212 40.84 153.274C39.306 155.336 36.047 154.174 36.047 154.174L35.415 151.513z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M45.73 147.088C45.73 147.088 51.689 143.787 51.155 148.849C50.885 151.405 46.362 149.749 46.362 149.749L45.73 147.088z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M54.862 144.274C54.862 144.274 62.021 140.573 60.287 146.035C59.509 148.485 55.493 146.935 55.493 146.935L54.862 144.274z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M64.376 139.449C64.376 139.449 68.735 134.548 69.801 141.21C70.207 143.748 65.008 142.11 65.008 142.11L64.376 139.449z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M26.834 155.997C26.834 155.997 32.062 155.77 30.91 157.32C29.757 158.869 27.308 157.996 27.308 157.996L26.834 155.997z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M62.434 34.603C62.434 34.603 61.708 35.268 61.707 34.197C61.707 33.127 79.191 19.863 88.034 18.479C88.034 18.479 71.935 25.208 62.434 34.603z").setFill(f).setStroke(s);
+						f = "#000000"; s = null;
+						g.createPath("M65.4 98.4C65.4 98.4 87.401 120.801 96.601 124.401C96.601 124.401 105.801 135.601 101.801 161.601C101.801 161.601 98.601 169.201 95.401 148.401C95.401 148.401 98.601 123.201 87.401 139.201C87.401 139.201 79 129.301 85.4 129.601C85.4 129.601 88.601 131.601 89.001 130.001C89.401 128.401 81.4 114.801 64.2 100.4C47 86 65.4 98.4 65.4 98.4z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M7 137.201C7 137.201 6.8 135.401 8.6 136.201C10.4 137.001 104.601 143.201 136.201 167.201C136.201 167.201 91.001 144.001 7 137.201z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M17.4 132.801C17.4 132.801 17.2 131.001 19 131.801C20.8 132.601 157.401 131.601 181.001 164.001C181.001 164.001 159.001 138.801 17.4 132.801z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M29 128.801C29 128.801 28.8 127.001 30.6 127.801C32.4 128.601 205.801 115.601 229.401 148.001C229.401 148.001 219.801 122.401 29 128.801z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M39 124.001C39 124.001 38.8 122.201 40.6 123.001C42.4 123.801 164.601 85.2 188.201 117.601C188.201 117.601 174.801 93 39 124.001z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-19 146.801C-19 146.801 -19.2 145.001 -17.4 145.801C-15.6 146.601 2.2 148.801 4.2 187.601C4.2 187.601 -3 145.601 -19 146.801z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-27.8 148.401C-27.8 148.401 -28 146.601 -26.2 147.401C-24.4 148.201 -10.2 143.601 -13 182.401C-13 182.401 -11.8 147.201 -27.8 148.401z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-35.8 148.801C-35.8 148.801 -36 147.001 -34.2 147.801C-32.4 148.601 -17 149.201 -29.4 171.601C-29.4 171.601 -19.8 147.601 -35.8 148.801z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M11.526 104.465C11.526 104.465 11.082 106.464 12.631 105.247C28.699 92.622 61.141 33.72 116.826 28.086C116.826 28.086 78.518 15.976 11.526 104.465z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M22.726 102.665C22.726 102.665 21.363 101.472 23.231 100.847C25.099 100.222 137.541 27.72 176.826 35.686C176.826 35.686 149.719 28.176 22.726 102.665z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M1.885 108.767C1.885 108.767 1.376 110.366 3.087 109.39C12.062 104.27 15.677 47.059 59.254 45.804C59.254 45.804 26.843 31.09 1.885 108.767z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-18.038 119.793C-18.038 119.793 -19.115 121.079 -17.162 120.825C-6.916 119.493 14.489 78.222 58.928 83.301C58.928 83.301 26.962 68.955 -18.038 119.793z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-6.8 113.667C-6.8 113.667 -7.611 115.136 -5.742 114.511C4.057 111.237 17.141 66.625 61.729 63.078C61.729 63.078 27.603 55.135 -6.8 113.667z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-25.078 124.912C-25.078 124.912 -25.951 125.954 -24.369 125.748C-16.07 124.669 1.268 91.24 37.264 95.354C37.264 95.354 11.371 83.734 -25.078 124.912z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-32.677 130.821C-32.677 130.821 -33.682 131.866 -32.091 131.748C-27.923 131.439 2.715 98.36 21.183 113.862C21.183 113.862 9.168 95.139 -32.677 130.821z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M36.855 98.898C36.855 98.898 35.654 97.543 37.586 97.158C39.518 96.774 160.221 39.061 198.184 51.927C198.184 51.927 172.243 41.053 36.855 98.898z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M3.4 163.201C3.4 163.201 3.2 161.401 5 162.201C6.8 163.001 22.2 163.601 9.8 186.001C9.8 186.001 19.4 162.001 3.4 163.201z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M13.8 161.601C13.8 161.601 13.6 159.801 15.4 160.601C17.2 161.401 35 163.601 37 202.401C37 202.401 29.8 160.401 13.8 161.601z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M20.6 160.001C20.6 160.001 20.4 158.201 22.2 159.001C24 159.801 48.6 163.201 72.2 195.601C72.2 195.601 36.6 158.801 20.6 160.001z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M28.225 157.972C28.225 157.972 27.788 156.214 29.678 156.768C31.568 157.322 52.002 155.423 90.099 189.599C90.099 189.599 43.924 154.656 28.225 157.972z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M38.625 153.572C38.625 153.572 38.188 151.814 40.078 152.368C41.968 152.922 76.802 157.423 128.499 192.399C128.499 192.399 54.324 150.256 38.625 153.572z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-1.8 142.001C-1.8 142.001 -2 140.201 -0.2 141.001C1.6 141.801 55 144.401 85.4 171.201C85.4 171.201 50.499 146.426 -1.8 142.001z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M-11.8 146.001C-11.8 146.001 -12 144.201 -10.2 145.001C-8.4 145.801 16.2 149.201 39.8 181.601C39.8 181.601 4.2 144.801 -11.8 146.001z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M49.503 148.962C49.503 148.962 48.938 147.241 50.864 147.655C52.79 148.068 87.86 150.004 141.981 181.098C141.981 181.098 64.317 146.704 49.503 148.962z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M57.903 146.562C57.903 146.562 57.338 144.841 59.264 145.255C61.19 145.668 96.26 147.604 150.381 178.698C150.381 178.698 73.317 143.904 57.903 146.562z").setFill(f).setStroke(s);
+						f = "#ffffff"; s = {color: "#000000", width: 0.1};
+						g.createPath("M67.503 141.562C67.503 141.562 66.938 139.841 68.864 140.255C70.79 140.668 113.86 145.004 203.582 179.298C203.582 179.298 82.917 138.904 67.503 141.562z").setFill(f).setStroke(s);
+						f = "#000000"; s = null;
+						g.createPath("M-43.8 148.401C-43.8 148.401 -38.6 148.001 -39.8 149.601C-41 151.201 -43.4 150.401 -43.4 150.401L-43.8 148.401z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-13 162.401C-13 162.401 -7.8 162.001 -9 163.601C-10.2 165.201 -12.6 164.401 -12.6 164.401L-13 162.401z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-21.8 162.001C-21.8 162.001 -16.6 161.601 -17.8 163.201C-19 164.801 -21.4 164.001 -21.4 164.001L-21.8 162.001z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-117.169 150.182C-117.169 150.182 -112.124 151.505 -113.782 152.624C-115.439 153.744 -117.446 152.202 -117.446 152.202L-117.169 150.182z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-115.169 140.582C-115.169 140.582 -110.124 141.905 -111.782 143.024C-113.439 144.144 -115.446 142.602 -115.446 142.602L-115.169 140.582z").setFill(f).setStroke(s);
+						f = "#000000";
+						g.createPath("M-122.369 136.182C-122.369 136.182 -117.324 137.505 -118.982 138.624C-120.639 139.744 -122.646 138.202 -122.646 138.202L-122.369 136.182z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-42.6 211.201C-42.6 211.201 -44.2 211.201 -48.2 213.201C-50.2 213.201 -61.4 216.801 -67 226.801C-67 226.801 -54.6 217.201 -42.6 211.201z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M45.116 303.847C45.257 304.105 45.312 304.525 45.604 304.542C46.262 304.582 47.495 304.883 47.37 304.247C46.522 299.941 45.648 295.004 41.515 293.197C40.876 292.918 39.434 293.331 39.36 294.215C39.233 295.739 39.116 297.088 39.425 298.554C39.725 299.975 41.883 299.985 42.8 298.601C43.736 300.273 44.168 302.116 45.116 303.847z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M34.038 308.581C34.786 309.994 34.659 311.853 36.074 312.416C36.814 312.71 38.664 311.735 38.246 310.661C37.444 308.6 37.056 306.361 35.667 304.55C35.467 304.288 35.707 303.755 35.547 303.427C34.953 302.207 33.808 301.472 32.4 301.801C31.285 304.004 32.433 306.133 33.955 307.842C34.091 307.994 33.925 308.37 34.038 308.581z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-5.564 303.391C-5.672 303.014 -5.71 302.551 -5.545 302.23C-5.014 301.197 -4.221 300.075 -4.558 299.053C-4.906 297.997 -6.022 298.179 -6.672 298.748C-7.807 299.742 -7.856 301.568 -8.547 302.927C-8.743 303.313 -8.692 303.886 -9.133 304.277C-9.607 304.698 -10.047 306.222 -9.951 306.793C-9.898 307.106 -10.081 317.014 -9.859 316.751C-9.24 316.018 -6.19 306.284 -6.121 305.392C-6.064 304.661 -5.332 304.196 -5.564 303.391z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-31.202 296.599C-28.568 294.1 -25.778 291.139 -26.22 287.427C-26.336 286.451 -28.111 286.978 -28.298 287.824C-29.1 291.449 -31.139 294.11 -33.707 296.502C-35.903 298.549 -37.765 304.893 -38 305.401C-34.303 300.145 -32.046 297.399 -31.202 296.599z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-44.776 290.635C-44.253 290.265 -44.555 289.774 -44.338 289.442C-43.385 287.984 -42.084 286.738 -42.066 285C-42.063 284.723 -42.441 284.414 -42.776 284.638C-43.053 284.822 -43.395 284.952 -43.503 285.082C-45.533 287.531 -46.933 290.202 -48.376 293.014C-48.559 293.371 -49.703 297.862 -49.39 297.973C-49.151 298.058 -47.431 293.877 -47.221 293.763C-45.958 293.077 -45.946 291.462 -44.776 290.635z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-28.043 310.179C-27.599 309.31 -26.023 308.108 -26.136 307.219C-26.254 306.291 -25.786 304.848 -26.698 305.536C-27.955 306.484 -31.404 307.833 -31.674 313.641C-31.7 314.212 -28.726 311.519 -28.043 310.179z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-13.6 293.001C-13.2 292.333 -12.492 292.806 -12.033 292.543C-11.385 292.171 -10.774 291.613 -10.482 290.964C-9.512 288.815 -7.743 286.995 -7.6 284.601C-9.091 283.196 -9.77 285.236 -10.4 286.201C-11.723 284.554 -12.722 286.428 -14.022 286.947C-14.092 286.975 -14.305 286.628 -14.38 286.655C-15.557 287.095 -16.237 288.176 -17.235 288.957C-17.406 289.091 -17.811 288.911 -17.958 289.047C-18.61 289.65 -19.583 289.975 -19.863 290.657C-20.973 293.364 -24.113 295.459 -26 303. [...]
+						f = "#cccccc";
+						g.createPath("M46.2 347.401C46.2 347.401 53.6 327.001 49.2 315.801C49.2 315.801 60.6 337.401 56 348.601C56 348.601 55.6 338.201 51.6 333.201C51.6 333.201 47.6 346.001 46.2 347.401z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M31.4 344.801C31.4 344.801 36.8 336.001 28.8 317.601C28.8 317.601 28 338.001 21.2 349.001C21.2 349.001 35.4 328.801 31.4 344.801z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M21.4 342.801C21.4 342.801 21.2 322.801 21.6 319.801C21.6 319.801 17.8 336.401 7.6 346.001C7.6 346.001 22 334.001 21.4 342.801z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M11.8 310.801C11.8 310.801 17.8 324.401 7.8 342.801C7.8 342.801 14.2 330.601 9.4 323.601C9.4 323.601 12 320.201 11.8 310.801z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-7.4 342.401C-7.4 342.401 -8.4 326.801 -6.6 324.601C-6.6 324.601 -6.4 318.201 -6.8 317.201C-6.8 317.201 -2.8 311.001 -2.6 318.401C-2.6 318.401 -1.2 326.201 1.6 330.801C1.6 330.801 5.2 336.201 5 342.601C5 342.601 -5 312.401 -7.4 342.401z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-11 314.801C-11 314.801 -17.6 325.601 -19.4 344.601C-19.4 344.601 -20.8 338.401 -17 324.001C-17 324.001 -12.8 308.601 -11 314.801z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-32.8 334.601C-32.8 334.601 -27.8 329.201 -26.4 324.201C-26.4 324.201 -22.8 308.401 -29.2 317.001C-29.2 317.001 -29 325.001 -37.2 332.401C-37.2 332.401 -32.4 330.001 -32.8 334.601z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-38.6 329.601C-38.6 329.601 -35.2 312.201 -34.4 311.401C-34.4 311.401 -32.6 308.001 -35.4 311.201C-35.4 311.201 -44.2 330.401 -48.2 337.001C-48.2 337.001 -40.2 327.801 -38.6 329.601z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-44.4 313.001C-44.4 313.001 -32.8 290.601 -54.6 316.401C-54.6 316.401 -43.6 306.601 -44.4 313.001z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M-59.8 298.401C-59.8 298.401 -55 279.601 -52.4 279.801C-52.4 279.801 -44.2 270.801 -50.8 281.401C-50.8 281.401 -56.8 291.001 -56.2 300.801C-56.2 300.801 -56.8 291.201 -59.8 298.401z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M270.5 287C270.5 287 258.5 277 256 273.5C256 273.5 269.5 292 269.5 299C269.5 299 272 291.5 270.5 287z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M276 265C276 265 255 250 251.5 242.5C251.5 242.5 278 272 278 276.5C278 276.5 278.5 267.5 276 265z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M293 111C293 111 281 103 279.5 105C279.5 105 290 111.5 292.5 120C292.5 120 291 111 293 111z").setFill(f).setStroke(s);
+						f = "#cccccc";
+						g.createPath("M301.5 191.5L284 179.5C284 179.5 303 196.5 303.5 200.5L301.5 191.5z").setFill(f).setStroke(s);
+						s = "#000000"; f = null;
+						g.createPath("M-89.25 169L-67.25 173.75").setFill(f).setStroke(s);
+						s = "#000000";
+						g.createPath("M-39 331C-39 331 -39.5 327.5 -48.5 338").setFill(f).setStroke(s);
+						s = "#000000";
+						g.createPath("M-33.5 336C-33.5 336 -31.5 329.5 -38 334").setFill(f).setStroke(s);
+						s = "#000000";
+						g.createPath("M20.5 344.5C20.5 344.5 22 333.5 10.5 346.5").setFill(f).setStroke(s);
+						
+					};
+					
+					ready(function(){
+						var threshold = 92, width = 700, height = 700;
+						surface = gfx.createSurface("slideTarget", width, height);
+						drawTiger();
+						// button callback for edges detection
+						on(dom.byId("edges"), "click", function(){
+							var input = surface.getImageData({x:0,y:0,width:width,height:height}),
+								context = surface.getContext(),
+								output = context.createImageData(width, height),
+								w = input.width, h = input.height,
+								inputData = input.data,
+								outputData = output.data;
+							// diff edge detection. 
+							for(var y = 1; y < h - 1; ++y){
+								for(var x = 1; x < w - 1; ++x){
+									var i = (y*w + x)*4;
+									// compute diff for each pair of adjacent pixels around pixel i
+									for (var c=0; c<3;++c){ // iterate over color comp.
+										var p1 = inputData[i - w * 4 - 4 + c];
+										var p2 = inputData[i + w * 4 + 4 + c];
+										var max = Math.abs(p2-p1);
+										p1 = inputData[i - w * 4 + 4 + c];
+										p2 = inputData[i + w * 4 - 4 + c];
+										max = Math.max(max, Math.abs(p2-p1));
+										p1 = inputData[i + 4 + c];
+										p2 = inputData[i - 4 + c];
+										max = Math.max(max, Math.abs(p2-p1));
+										p1 = inputData[i - w * 4 + c];
+										p2 = inputData[i + w * 4 + c];
+										max = Math.max(max, Math.abs(p2-p1));
+										if(max<threshold)
+											max = 0;
+										outputData[i + c] = max;
+									}
+									outputData[i + 3] = 255; //alpha
+								}
+							}
+							// put the image data back after manipulation
+							context.putImageData(output, 0, 0);
+						});
+						
+						// wire a pre render callback to draw a text.
+						aspect.before(surface,"render", function(context){
+							context.save();
+							context.fillStyle    = "black"; 
+							context.font         = "italic 30px sans-serif";
+							context.textBaseline = "top";
+							context.fillText("Canvas pixel-based manipulation with dojox.gfx", 0, 0);
+							context.restore();
+						}, true);
+						// wire a post render callback to apply a "negate color" filter.
+						aspect.after(surface,"render", function(context){
+								input = context.getImageData(0,100,width,height);
+								var inputData = input.data;
+								// negate colors
+								for(var i=0, n=inputData.length; i<n; i+=4){
+									 inputData[i  ] = 255 - inputData[i  ]; // red
+									 inputData[i+1] = 255 - inputData[i+1]; // green
+									 inputData[i+2] = 255 - inputData[i+2]; // blue
+								}
+								context.putImageData(input, 0, 100);
+						}, true);
+					});
+				}
+			);
+		</script>
+	</head>
+	<body>
+		This test shows how to use the canvas ImageData api with gfx. Two approaches are illustrated: 
+		<ul>
+			<li>How to use dojo aspect to do some image post-(or pre-) processing on the gfx scene. In this test, 
+				a title is drawn before drawing the gfx scene and a "negate color" filter is applied after. You should see a "blue" tiger.</li>
+			<li>How to use the Surface.getImageData() (specific to the canvas renderer) to do one-shot image data operation. In this
+				test, it applies a edge detection filter.</li>
+		</ul>
+		<div id="slideTarget" ></div>
+		<button id="edges">Detect Edges</button>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/test_lifecycle.html b/dojox/gfx/tests/test_lifecycle.html
new file mode 100644
index 0000000..3435324
--- /dev/null
+++ b/dojox/gfx/tests/test_lifecycle.html
@@ -0,0 +1,176 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Test lifecycle</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, packageMap:[{name:'doh',location:'util/doh'}]"></script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/ready",
+				"dojo/dom",
+				"dojox/gfx",
+				"dojox/gfx/shape",
+				"dojox/gfx/svg",
+				"dojox/gfx/registry"
+			],
+					function(doh, ready, dom, gfx, gfxshape, svg){
+
+					var drawing, r,
+						checkSurface = function(){
+							if(!drawing){
+								var dn = dom.byId("gfxObject");
+								drawing = gfx.createSurface(dn, 300, 300);
+							}
+						};
+					
+					doh.register("GFX: shape lifecycle", [
+						{
+							name: "Shape.destroy",
+							timeout: 1000,
+							setUp: function(){
+								checkSurface();
+								r = drawing.createRect({ 
+									 x: 100,
+									 y: 100
+								}).setFill("black");
+							},
+							runTest: function(){
+								var uid = r.getUID();
+								r.removeShape();
+								r.destroy();
+								doh.assertTrue(!gfxshape.byId(uid), "Unexpected shape.byId return value.");
+							},
+							tearDown: function(){
+								drawing.clear();
+							}
+						},{
+							name: "Group.clear",
+							timeout: 1000,
+							setUp: function(){
+								checkSurface();
+								r = drawing.createGroup();
+								r.createRect({ 
+										 x: 100,
+										 y: 100
+									}).setFill("black");
+							},
+							runTest: function(){
+								var c = r.children[0];
+								r.clear(true);
+								doh.assertTrue(r.children.length == 0, "Unexpected children length on disposed group.");
+								doh.assertTrue(!gfxshape.byId(c.getUID()), "Unexpected shape.byId return value.");
+							}
+						},{
+							name: "Group.destroy",
+							timeout: 1000,
+							setUp: function(){
+								checkSurface();
+								r = drawing.createGroup();
+								r.createRect({ 
+										 x: 100,
+										 y: 100
+									}).setFill("black");
+							},
+							runTest: function(){
+								var uid = r.getUID();
+								var c = r.children[0];
+								r.removeShape();
+								r.destroy();
+								doh.assertTrue(!gfxshape.byId(uid), "Unexpected shape.byId return value.");
+								doh.assertTrue(r.children.length == 0, "Unexpected children length on disposed group.");
+								doh.assertTrue(!gfxshape.byId(r.getUID()), "Unexpected shape.byId return value.");
+								
+								r = drawing.createGroup();
+								var t2 = r.createGroup();
+								c = t2.createRect();
+								r.removeShape();
+								r.destroy();
+								doh.assertTrue(!gfxshape.byId(r.getUID()), "Unexpected shape.byId return value.");
+								doh.assertTrue(r.children.length == 0, "Unexpected children length on disposed group.");
+								doh.assertTrue(!gfxshape.byId(t2.getUID()), "Unexpected shape.byId return value.");
+								doh.assertTrue(t2.children.length == 0, "Unexpected children length on disposed group.");
+								doh.assertTrue(!gfxshape.byId(c.getUID()), "Unexpected shape.byId return value.");
+							}
+						},{
+							name: "SVG-specific : shape clean-up",
+							timeout: 1000,
+							setUp: function(){
+								if(drawing){
+									drawing.destroy();
+									drawing = null;
+								}
+								gfx.switchTo(svg);
+								checkSurface();
+								var grad = {
+									type: "linear",
+									x1: 0, y1: 0,
+									x2: 600, y2: 0,
+									colors: [
+										{ offset: 0.2, color: "red" },
+										{ offset: 0.8, color: "yellow" }
+									]
+								};
+								r = drawing.createRect().setFill(grad).setClip({x:0,y:0,width:300,height:300});
+							},
+							runTest: function(){								
+								var defs = drawing.defNode;
+								doh.assertTrue(defs.childNodes.length == 1, "Unexpected defs children count.");
+								var c = drawing.children[0];
+								c.removeShape();
+								c.destroy();
+								doh.assertTrue(defs.childNodes.length == 0, "Unexpected defs children count. Expected: 0.");
+								doh.assertTrue(drawing.rawNode.childNodes.length == 1 && drawing.rawNode.childNodes[0] == defs, "Unexpected surface children nodes.");
+							}
+						},{
+							name: "SVG-specific : Group clean-up",
+							timeout: 1000,
+							setUp: function(){
+								if(drawing){
+									drawing.destroy();
+									drawing = null;
+								}
+								gfx.switchTo(svg);
+								checkSurface();
+								var grad = {
+									type: "linear",
+									x1: 0, y1: 0,
+									x2: 600, y2: 0,
+									colors: [
+										{ offset: 0.2, color: "red" },
+										{ offset: 0.8, color: "yellow" }
+									]
+								};
+								var sub1 = drawing.createGroup();
+								for(var i=0; i<100; ++i){
+									var r = Math.floor(i/10), offs=4,
+										cc = r%2 == 0 ? -offs : offs,
+										x = (i%10)*60+cc, y = r*60+5, w = 50, h = 50;
+									sub1.createRect({x:x, y:y, width:w, height:h}).setFill(grad).setClip({cx:x+w/2, cy:y+w/2, rx:20, ry:20});
+								}
+							},
+							runTest: function(){								
+								var defs = drawing.defNode;
+								doh.assertTrue(defs.childNodes.length == 100, "Unexpected defs children count.");
+								var g = drawing.children[0];
+								g.clear(true);
+								doh.assertTrue(defs.childNodes.length == 0, "Unexpected defs children count. Expected: 0.");
+								doh.assertTrue(g.rawNode.firstChild == null, "Unexpected group children count. Expected: 0.");
+							}
+						}
+					]);
+
+					ready(function(){
+						doh.run()
+					});
+			});
+		</script>
+	</head>
+	<body>
+		<div id="gfxObject" style="width: 500px; height: 500px;font-weight:bold;"></div>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/test_linearGradient.html b/dojox/gfx/tests/test_linearGradient.html
index bb81eac..ba68fb2 100644
--- a/dojox/gfx/tests/test_linearGradient.html
+++ b/dojox/gfx/tests/test_linearGradient.html
@@ -7,7 +7,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 dojo.require("dojo.colors");
diff --git a/dojox/gfx/tests/test_linestyle.html b/dojox/gfx/tests/test_linestyle.html
index 96adc9d..25678db 100644
--- a/dojox/gfx/tests/test_linestyle.html
+++ b/dojox/gfx/tests/test_linestyle.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--<script type="text/javascript" src="../_base.js"></script>-->
 <!--<script type="text/javascript" src="../shape.js"></script>-->
 <!--<script type="text/javascript" src="../path.js"></script>-->
diff --git a/dojox/gfx/tests/test_loadCanvas.html b/dojox/gfx/tests/test_loadCanvas.html
index ab9f310..2254734 100644
--- a/dojox/gfx/tests/test_loadCanvas.html
+++ b/dojox/gfx/tests/test_loadCanvas.html
@@ -3,7 +3,7 @@
 <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>Testing arc</title>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 	window.onerror = function(){
 		document.writeln("Test has failed: canvas.js cannot be loaded.");
diff --git a/dojox/gfx/tests/test_pattern.html b/dojox/gfx/tests/test_pattern.html
index f5e5e3b..26ad604 100644
--- a/dojox/gfx/tests/test_pattern.html
+++ b/dojox/gfx/tests/test_pattern.html
@@ -7,7 +7,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--<script type="text/javascript" src="../matrix.js"></script>-->
 <!--<script type="text/javascript" src="../vml.js"></script>-->
 <!--<script type="text/javascript" src="../svg.js"></script>-->
diff --git a/dojox/gfx/tests/test_poly.html b/dojox/gfx/tests/test_poly.html
index 8b6d7c4..bbddc4b 100644
--- a/dojox/gfx/tests/test_poly.html
+++ b/dojox/gfx/tests/test_poly.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 dojo.require("dojox.gfx.shape");
diff --git a/dojox/gfx/tests/test_rect_setShape_vml.html b/dojox/gfx/tests/test_rect_setShape_vml.html
index 1ccf201..92198d9 100644
--- a/dojox/gfx/tests/test_rect_setShape_vml.html
+++ b/dojox/gfx/tests/test_rect_setShape_vml.html
@@ -6,7 +6,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--<script type="text/javascript" src="../vml.js"></script>-->
 <!--<script type="text/javascript" src="../svg.js"></script>-->
 <!--<script type="text/javascript" src="../silverlight.js"></script>-->
diff --git a/dojox/gfx/tests/test_refproj.html b/dojox/gfx/tests/test_refproj.html
index c4a682c..13e3ef2 100644
--- a/dojox/gfx/tests/test_refproj.html
+++ b/dojox/gfx/tests/test_refproj.html
@@ -6,7 +6,7 @@
         @import "../../../dojo/resources/dojo.css";
         @import "../../../dijit/themes/tundra/tundra.css";
     </style>
-    <script src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+    <script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
     <script>
         dojo.require("dojox.gfx");
         dojo.require("dojo.colors");
diff --git a/dojox/gfx/tests/test_registry.html b/dojox/gfx/tests/test_registry.html
index 78cf5d6..4fb45d8 100644
--- a/dojox/gfx/tests/test_registry.html
+++ b/dojox/gfx/tests/test_registry.html
@@ -7,12 +7,13 @@
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript" src="../../../util/doh/runner.js"></script>
 		<script type="text/javascript">
 			dojo.require("doh.runner");
 			dojo.require("dojox.gfx");
 			dojo.require("dojox.gfx.shape");
+			dojo.require("dojox.gfx.registry");
 		</script>
 		<script type="text/javascript">
 			dojo.addOnLoad(function(){
@@ -39,7 +40,34 @@
 							obj.getUID =function(){return id;};
 							dojox.gfx.shape.dispose(obj);
 							ret = dojox.gfx.shape.byId(id);
-							t.t(!ret, "Checking dojox.gfx.shape.dispose().");							
+							t.t(!ret, "Checking dojox.gfx.shape.dispose().");
+							// optional recursive dispose
+						}
+					},
+					{
+						name:"recursive dispose",
+						runTest: function(t){
+
+							var obj = {
+								declaredClass: 'module.sub.foo',
+								children:[
+									{ declaredClass: "foo.bar" },
+									{ declaredClass: "bar.foo" }
+								]
+							};
+							var id1 = dojox.gfx.shape.register(obj);
+							obj.getUID =function(){return id1;};
+							var id2 = dojox.gfx.shape.register(obj.children[0]);
+							obj.children[0].getUID =function(){return id2;};
+							var id3 = dojox.gfx.shape.register(obj.children[1]);
+							obj.children[1].getUID =function(){return id3;};
+							dojox.gfx.shape.dispose(obj, true);
+							var ret = dojox.gfx.shape.byId(id1);
+							t.t(!ret, "Shape id1 not disposed (recursive dispose).");
+							ret = dojox.gfx.shape.byId(id2);
+							t.t(!ret, "Child id2 not disposed (recursive dispose).");
+							ret = dojox.gfx.shape.byId(id3);
+							t.t(!ret, "Child id3 not disposed (recursive dispose).");
 						}
 					},
 					{
@@ -63,7 +91,7 @@
 								t.t(o === s, "Checking dojox.gfx.shape.byId()");
 								// rawNode binding
 								var p = s.rawNode.tag ? 'tag' : '__gfxObject__';
-								t.t(s.rawNode[p] == s.getUID(),"Checking rawNode<->gfx binding.");
+								t.t(s.rawNode[p] == s,"Checking rawNode<->gfx binding.");
 								dic[name] = s.getUID();
 							});
 							// successive registration
diff --git a/dojox/gfx/tests/test_renderingOptions.html b/dojox/gfx/tests/test_renderingOptions.html
new file mode 100644
index 0000000..6d64d8e
--- /dev/null
+++ b/dojox/gfx/tests/test_renderingOptions.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML>
+<html lang="en">
+	<head>
+		<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true,parseOnLoad: true, async:1, gfxRenderer:'svg'"></script>
+		<script>
+			require([
+				"dojo/_base/array",
+				"dojox/gfx",
+				"dojox/gfx/matrix",
+				"dojo/ready",
+				"dojox/gfx/svgext"],
+				function(array, gfx, matrix, ready){
+
+				var surface = gfx.createSurface("slideTarget", 700, 500), g, parent = surface;
+				array.forEach(["auto","optimizeSpeed","crispEdges","geometricPrecision"], function(opt,idx){
+					g = parent.createGroup().setTransform(matrix.translate(0, 20*idx));
+					g.createLine({
+						x1 : 10,
+						y1 : 10,
+						x2 : 490,
+						y2 : 100
+					}).setStroke("blue").addRenderingOption("shape-rendering", opt);
+					g.createText({
+						x : 490,
+						y : 100,
+						text :opt
+					}).setFill("black");
+				});
+				parent = surface.createGroup().setTransform(matrix.translate(0, 80));
+				array.forEach(["auto","optimizeSpeed","crispEdges","geometricPrecision"], function(opt,idx){
+					g = parent.createGroup().setTransform(matrix.translate(0, 20*idx));
+					g.createLine({
+						x1 : 10,
+						y1 : 100,
+						x2 : 490,
+						y2 : 100
+					}).setStroke("blue").addRenderingOption("shape-rendering", opt);
+					g.createText({
+						x : 490,
+						y : 100,
+						text :opt
+					}).setFill("black");
+				});
+				parent = surface.createGroup().setTransform(matrix.translate(0, 160));
+				array.forEach(["auto","optimizeSpeed","optimizeLegibility","geometricPrecision"], function(opt,idx){
+					g = parent.createGroup().setTransform(matrix.translate(0, 20*idx));
+					g.createText({
+						x : 50,
+						y : 100,
+						text : "LYoWAT	ff fi fl ffl  ("+ opt +")"
+					}).setFill("black").setFont({size:"23px", family:"Calibri, Constantia"}).addRenderingOption("text-rendering" , opt);
+				});
+			});
+
+		</script>
+	</head>
+	<body>
+		This test demonstrates the various SVG rendering options in action. This test only works on browsers supporting SVG.
+		<div id="slideTarget" ></div>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/test_resize.html b/dojox/gfx/tests/test_resize.html
index 4c02dda..efdc389 100644
--- a/dojox/gfx/tests/test_resize.html
+++ b/dojox/gfx/tests/test_resize.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 dojo.require("dojox.gfx.shape");
diff --git a/dojox/gfx/tests/test_roundrect.html b/dojox/gfx/tests/test_roundrect.html
index 37c9086..1ae134c 100644
--- a/dojox/gfx/tests/test_roundrect.html
+++ b/dojox/gfx/tests/test_roundrect.html
@@ -6,7 +6,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 dojo.require("dojox.gfx.move");
diff --git a/dojox/gfx/tests/test_setPath.html b/dojox/gfx/tests/test_setPath.html
index 7d32f80..a02dcef 100644
--- a/dojox/gfx/tests/test_setPath.html
+++ b/dojox/gfx/tests/test_setPath.html
@@ -7,7 +7,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 	li {font-weight: bold;}
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
@@ -20,42 +20,42 @@ makeShapes = function(surface){
 	// relative path with cubic beziers
 	surface
 		.createPath("m100 100 100 0 0 100c0 50-50 50-100 0s-50-100 0-100z")
-		.setStroke({color: "black"})
+		.setStroke({color: "black", style:'longdash', width:3})
 		.setFill("red")
 		.setTransform({dx: -50, dy: -50})
 		;
 	// absolute path with cubic bezier
 	surface
 		.createPath("M100 100 200 100 200 200C200 250 150 250 100 200S50 100 100 100z")
-		.setStroke({color: "black"})
+        .setStroke({color: "black", style:'longdash', width:3})
 		.setFill("#f80")
 		.setTransform({dx: 100, dy: -50})
 		;
 	// relative path with horizontal and vertical lines, and cubic beziers
 	surface
 		.createPath("m100 100h100v100c0 50-50 50-100 0s-50-100 0-100z")
-		.setStroke({color: "black"})
+        .setStroke({color: "black", style:'longdash', width:3})
 		.setFill("yellow")
 		.setTransform({dx: 250, dy: -50})
 		;
 	// relative path with quadratic beziers
 	surface
 		.createPath("m100 100 100 0 0 100q0 50-75-25t-25-75z")
-		.setStroke({color: "black"})
+        .setStroke({color: "black", style:'longdash', width:3})
 		.setFill("green")
 		.setTransform({dx: -50, dy: 150})
 		;
 	// absolute path with quadratic bezier
 	surface
 		.createPath("M100 100 200 100 200 200Q200 250 125 175T100 100z")
-		.setStroke({color: "black"})
+        .setStroke({color: "black", style:'longdash', width:3})
 		.setFill("blue")
 		.setTransform({dx: 100, dy: 150})
 		;
 	// relative path with horizontal and vertical lines, and quadratic beziers
 	surface
 		.createPath("m100 100h100v100q0 50-75-25t-25-75z")
-		.setStroke({color: "black"})
+        .setStroke({color: "black", style:'longdash', width:3})
 		.setFill("#f0f")
 		.setTransform({dx: 250, dy: 150})
 		;
diff --git a/dojox/gfx/tests/test_surfaceClip.html b/dojox/gfx/tests/test_surfaceClip.html
index 98cedea..31a6c3c 100644
--- a/dojox/gfx/tests/test_surfaceClip.html
+++ b/dojox/gfx/tests/test_surfaceClip.html
@@ -7,7 +7,7 @@
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
-	<script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 	<script>
 		dojo.require("dojox.gfx");
 
diff --git a/dojox/gfx/tests/test_switchTo.html b/dojox/gfx/tests/test_switchTo.html
new file mode 100644
index 0000000..992d024
--- /dev/null
+++ b/dojox/gfx/tests/test_switchTo.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Test switchTo</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async:0, gfxRenderer:'svg,canvas,vml', packageMap:[{name:'doh',location:'util/doh'}]"></script>
+		<script type="text/javascript">
+			require([
+			"doh/runner",
+			"dojo/ready",
+			"dojo/sniff",
+			"dojo/aspect",
+			"dojox/gfx",
+			"dojox/gfx/shape"],
+			function(doh, ready, has, aspect, gfx, gfxshape, svg, canvas){
+				
+				ready(function(){
+					var surface, newRenderer;
+					
+					doh.register("switchTo", [
+						{
+							name: "switchTo(object)",
+							timeout: 1000,
+							setUp: function(){
+							},
+							runTest: function(t){
+								if(gfx.renderer == "vml") return;
+								var r = gfx.renderer == "svg" ? "canvasWithEvents" : "svg";
+								require(["dojox/gfx/" + r], function(){});
+								gfx.switchTo(gfx[r]);
+								t.t(gfx.Surface === gfx[r].Surface, "Unexpected Surface type.");
+								t.t(gfx.renderer === r, "Unexpected renderer.");
+							}
+						},
+						{
+							name: "switchTo(string)",
+							timeout: 1000,
+							setUp: function(){
+							},
+							runTest: function(t){
+								if(gfx.renderer == "vml") return;
+								var r = gfx.renderer == "svg" ? "canvasWithEvents" : "svg";
+								require(["dojox/gfx/" + r], function(){});
+								gfx.switchTo(r);
+								t.t(gfx.Surface === gfx[r].Surface, "Unexpected Surface type.");
+								t.t(gfx.renderer === r, "Unexpected renderer.");
+							}
+						}
+					]);
+				doh.run();
+			});
+		});
+		</script>
+	</head>
+	<body>
+		<div id="gfxObject" style="width: 500px; height: 500px;font-weight:bold;"></div>
+	</body>
+</html>
diff --git a/dojox/gfx/tests/test_tbbox.html b/dojox/gfx/tests/test_tbbox.html
index e50ab57..794af35 100644
--- a/dojox/gfx/tests/test_tbbox.html
+++ b/dojox/gfx/tests/test_tbbox.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 dojo.require("dojox.gfx.shape");
diff --git a/dojox/gfx/tests/test_text.html b/dojox/gfx/tests/test_text.html
index 826cead..821531b 100644
--- a/dojox/gfx/tests/test_text.html
+++ b/dojox/gfx/tests/test_text.html
@@ -1,82 +1,103 @@
-<html>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
 <head>
-<title>Testing text</title>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<style type="text/css">
-	@import "../../../dojo/resources/dojo.css";
-	@import "../../../dijit/tests/css/dijitTests.css";
-</style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
-<!--
-<script type="text/javascript" src="../common.js"></script>
-<script type="text/javascript" src="../shape.js"></script>
--->
-<!--<script type="text/javascript" src="../vml.js"></script>-->
-<!--<script type="text/javascript" src="../svg.js"></script>-->
-<!--<script type="text/javascript" src="../silverlight.js"></script>-->
-<script type="text/javascript">
-dojo.require("dojox.gfx");
+	<title>Testing text</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
+	<script type="text/javascript">
 
-var ROTATION = 30;
+	require(["dojo/ready", "dojo/_base/array", "dojo/dom", "dojo/on", "dojox/gfx","dojox/gfx/matrix"],
+	function(ready, array, dom, on, gfx, matrix){
 
-var surface = null, t1, t2, t3, t4, t5;
+		var ROTATION = 30, surface = null, t1, t2, t3, t4, t5, t6, t7, t8, t9;
 
-var placeAnchor = function(surface, x, y){
-	surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y}).setStroke("blue");
-	surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2}).setStroke("blue");
-};
+		function placeBBox(surface, shape){
+			var bbox = shape.getBoundingBox();
+			var t = shape.getTransform();//shape._getRealMatrix();
+			var tbbox = matrix.multiplyRectangle(t, bbox);
+			var rect = surface.createRect(tbbox).setStroke("red");
+		}
 
-var makeText = function(surface, text, font, fill, stroke){
-	var t = surface.createText(text);
-	if(font)   t.setFont(font);
-	if(fill)   t.setFill(fill);
-	if(stroke) t.setStroke(stroke);
-	placeAnchor(surface, text.x, text.y);
-	return t;
-};
+		function placeAnchor(surface, x, y){
+			surface.createLine({x1: x - 2, y1: y, x2: x + 2, y2: y}).setStroke("blue");
+			surface.createLine({x1: x, y1: y - 2, x2: x, y2: y + 2}).setStroke("blue");
+		}
 
-createSurface = function(){
-	surface = dojox.gfx.createSurface("test", 500, 500);
-	surface.whenLoaded(makeShapes);
-};
+		function makeText(surface, text, font, fill, stroke){
+			var t = surface.createText(text);
+			if(font)   t.setFont(font);
+			if(fill)   t.setFill(fill);
+			if(stroke) t.setStroke(stroke);
+			placeAnchor(surface, text.x, text.y);
+			return t;
+		}
 
-makeShapes = function(){
-	var m = dojox.gfx.matrix;
-	surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
-	t1 = makeText(surface, {x: 250, y: 50, text: "Start", align: "start"}, 
-		{family: "Times", size: "36pt", weight: "bold"}, "black", "red")
-		.setTransform(m.rotategAt(ROTATION, 250, 50));
-	t2 = makeText(surface, {x: 250, y: 100, text: "Middle", align: "middle"}, 
-		{family: "Symbol", size: "24pt"}, "red", "black")
-		.setTransform(m.rotategAt(ROTATION, 250, 100));
-	t3 = makeText(surface, {x: 250, y: 150, text: "End", align: "end"}, 
-		{family: "Helvetica", style: "italic", size: "18pt", rotated: true}, "#FF8000")
-		.setTransform(m.rotategAt(ROTATION, 250, 150));
-	t4 = makeText(surface, {x: 250, y: 200, text: "Define Shuffle Tiff", align: "middle", kerning: true}, 
-		{family: "serif", size: "36pt"}, "black")
-		.setTransform(m.rotategAt(0, 250, 200));
-	t5 = makeText(surface, {x: 250, y: 250, text: "Define Shuffle Tiff", align: "middle", kerning: false}, 
-		{family: "serif", size: "36pt"}, "black")
-		.setTransform(m.rotategAt(0, 250, 250));
-};
+		function makeShapes(){
+			var m = matrix;
+			surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
+			t1 = makeText(surface, {x: 250, y: 50, text: "Start", align: "start"},
+				{family: "Times", size: "36pt", weight: "bold"}, "black", "red")
+				.setTransform(m.rotategAt(ROTATION, 250, 50));
+			t2 = makeText(surface, {x: 250, y: 100, text: "Middle", align: "middle"},
+				{family: "Symbol", size: "24pt"}, "red", "black")
+				.setTransform(m.rotategAt(ROTATION, 250, 100));
+			t3 = makeText(surface, {x: 250, y: 150, text: "End", align: "end"},
+				{family: "Helvetica", style: "italic", size: "18pt", rotated: true}, "#FF8000")
+				.setTransform(m.rotategAt(ROTATION, 250, 150));
+			t4 = makeText(surface, {x: 250, y: 200, text: "Define Shuffle Tiff", align: "middle", kerning: true},
+				{family: "serif", size: "36pt"}, "black")
+				.setTransform(m.rotategAt(0, 250, 200));
+			t5 = makeText(surface, {x: 250, y: 250, text: "Define Shuffle Tiff", align: "middle", kerning: false},
+				{family: "serif", size: "36pt"}, "black")
+				.setTransform(m.rotategAt(0, 250, 250));
+			// test #14522
+			t6 = makeText(surface, {x: 250, y: 290, text: 18, align: "start"},
+				{family: "sans serif", size: "18pt", weight: "bold"}, "black");
+			// test #16099
+			t7 = makeText(surface, {x: 0, y: 0, text: "Middle", align: "middle"},
+				{family: "sans serif", size: "24pt"}, "red", "black")
+				.setTransform(m.translate(250, 340));
+			t8 = makeText(surface, {x: 250, y: 390, text: "Number: \u200E\u202A20\u202C", align: "middle"},
+					{family: "sans serif", size: "24pt"}, "red", "black");
+			// a text with some descents
+			t9 = makeText(surface, {x: 0, y: 0, text: "go, Dojo! go", align: "end"},
+					{family: "serif", size: "36pt"}, "red", "black")
+					.setTransform(m.translate(250, 440));
 
-getSizes = function(){
-	var t = [];
-	dojo.forEach(["t1", "t2", "t3", "t4", "t5"], function(name){
-		var node = eval("(" + name + ")");
-		t.push(node.getShape().text + " = " + node.getTextWidth());
-	});
-	dojo.byId("sizes").innerHTML = t.join("<br/>");
-};
 
-dojo.addOnLoad(createSurface);
+			array.forEach(["t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"], function(name){
+				var node = eval("(" + name + ")");
+				placeBBox(surface, node);
+			});
+		}
+
+		function createSurface(nodeId){
+			surface = gfx.createSurface(nodeId, 500, 500);
+			surface.whenLoaded(makeShapes);
+		}
 
+		function getSizes(){
+			if (!surface.children.length){return;}
+			var t = [];
+			array.forEach(["t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9"], function(name){
+				var node = eval("(" + name + ")");
+				t.push(node.getShape().text + " = " + node.getTextWidth());
+			});
+			dom.byId("sizes").innerHTML = t.join("<br/>");
+		}
+
+		ready(function(){
+			on(dom.byId("getSizes"), "click", getSizes);
+			on(dom.byId("clear"), "click", function(){surface.clear();});
+			createSurface("test");
+		});
+	});
 </script>
 </head>
 <body>
 	<h1>dojox.gfx Text test</h1>
 	<div id="test" style="width: 500px; height: 500px;"></div>
-	<div><button onclick="surface.clear();">Clear</button> <button onclick="getSizes();">Get sizes</button></div>
+	<div><button id="clear">Clear</button> <button id="getSizes">Get sizes</button></div>
 	<p id="sizes"> </p>
 	<p>That's all Folks!</p>
 </body>
diff --git a/dojox/gfx/tests/test_textbbox.html b/dojox/gfx/tests/test_textbbox.html
new file mode 100644
index 0000000..2798ec0
--- /dev/null
+++ b/dojox/gfx/tests/test_textbbox.html
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>Test text bbox</title>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, packageMap:[{name:'doh',location:'util/doh'}]"></script>
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dojo/ready",
+			"dojox/gfx",
+			"dojox/gfx/shape",
+			"dojox/gfx/matrix"],
+				function(doh, ready, gfx, gfxshape, matrix){
+
+					var textShape = { x:20, y:40, text:"Hello !"};
+
+					ready(function(){
+						var surface, r,
+								checkSurface = function(){
+									if(!surface){
+										surface = gfx.createSurface("gfxObject", 300, 300);
+									}
+								};
+
+						doh.register("text.getBoundingBox", [
+							{
+								name: "text.getBoundingBox",
+								timeout: 1000,
+								setUp: function(){
+									if(surface){
+										surface.destroy();
+										surface = null;
+									}
+									checkSurface();
+								},
+								runTest: function(t){
+									var text = surface.createText(textShape).setFill("black");
+									var bbox = text.getBoundingBox();
+									t.assertTrue(bbox !== null, "Unexpected null bbox.");
+									// it's impossible to test for bbox coordinates as it varies depending on the browser...
+								},
+								tearDown: function(){
+									surface.clear();
+								}
+							},{
+								name: "getBoundingBox (empty string)",
+								timeout: 1000,
+								setUp: function(){
+									if(surface){
+										surface.destroy();
+										surface = null;
+									}
+									checkSurface();
+								},
+								runTest: function(t){
+									var text = surface.createText().setFill("black");
+									var bbox = text.getBoundingBox();
+									t.assertTrue(bbox == null, "Unexpected non-null bbox.");
+								},
+								tearDown: function(){
+									surface.clear();
+								}
+							},{
+								name: "getBoundingBox (orphan)",
+								timeout: 1000,
+								setUp: function(){
+									if(surface){
+										surface.destroy();
+										surface = null;
+									}
+									checkSurface();
+								},
+								runTest: function(t){
+									var text = surface.createText(textShape).setFill("black");
+									text.removeShape();
+									var bbox = text.getBoundingBox();
+									t.assertTrue(bbox != null, "Unexpected bbox.");
+									t.assertTrue(bbox.x==0 && bbox.y==0 && bbox.width==0 && bbox.height==0, "Unexpected non empty bbox.");
+									var g = surface.createGroup();
+									text = g.createText(textShape);
+									g.removeShape();
+									bbox = text.getBoundingBox();
+									t.assertTrue(bbox != null, "Unexpected bbox [2].");
+									t.assertTrue(bbox.x==0 && bbox.y==0 && bbox.width==0 && bbox.height==0, "Unexpected non empty bbox.[2]");
+								},
+								tearDown: function(){
+									surface.clear();
+								}
+							}
+
+
+						]);
+						doh.run();
+					});
+				});
+	</script>
+</head>
+<body>
+<div id="gfxObject" style="width: 500px; height: 500px;font-weight:bold;"></div>
+</body>
+</html>
diff --git a/dojox/gfx/tests/test_textpath.html b/dojox/gfx/tests/test_textpath.html
index e9c4e60..4083294 100644
--- a/dojox/gfx/tests/test_textpath.html
+++ b/dojox/gfx/tests/test_textpath.html
@@ -6,7 +6,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--
 <script type="text/javascript" src="../common.js"></script>
 <script type="text/javascript" src="../shape.js"></script>
diff --git a/dojox/gfx/tests/test_transform.html b/dojox/gfx/tests/test_transform.html
index 036e2e0..e699382 100644
--- a/dojox/gfx/tests/test_transform.html
+++ b/dojox/gfx/tests/test_transform.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <!--<script type="text/javascript" src="../vml.js"></script>-->
 <!--<script type="text/javascript" src="../svg.js"></script>-->
 <!--<script type="text/javascript" src="../silverlight.js"></script>-->
diff --git a/dojox/gfx/tests/test_utils.html b/dojox/gfx/tests/test_utils.html
index 5d4dbca..98db02a 100755
--- a/dojox/gfx/tests/test_utils.html
+++ b/dojox/gfx/tests/test_utils.html
@@ -7,7 +7,7 @@
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript" src="../../../util/doh/runner.js"></script>
 		<script type="text/javascript">
 			dojo.require("doh.runner");
@@ -133,6 +133,7 @@
 									doh.assertTrue(low.indexOf("xmlns:xlink=\"http://www.w3.org/1999/xlink\"") !== -1, "Checking the xmlns:xlink attribute.");
 									doh.assertFalse(/\s+href\s*=/g.test(low), "Checking there's no href attributes.");
 									doh.assertTrue(low.indexOf("xlink:href=") !== -1, "Checking the xlink:href attribute.");
+									doh.assertTrue(low.indexOf("<img") === -1, "Checking the <img> cleanup.");
 									doh.assertTrue(svg.indexOf("__gfxObject__") === -1, "Checking __gfxObject__ attribute cleanup.");
 									d.callback(true);
 								}catch(e){
diff --git a/dojox/gfx/tests/test_vectortext_draw.html b/dojox/gfx/tests/test_vectortext_draw.html
index 76e6f92..2835ba5 100644
--- a/dojox/gfx/tests/test_vectortext_draw.html
+++ b/dojox/gfx/tests/test_vectortext_draw.html
@@ -6,7 +6,7 @@
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.gfx");
 			dojo.require("dojox.gfx.fx");
@@ -18,11 +18,11 @@
 				var url = dojo.moduleUrl("dojox", "gfx/resources/Gillius.svg");
 				var f = new dojox.gfx.VectorFont(url);
 
-				//	draw out the glyphs for testing.
+				//		draw out the glyphs for testing.
 				var rect = surface.createRect({ x: 0, y: 0, width: 600, height: 400 })
 					.setFill(bg);
 
-				//	draw it up.
+				//		draw it up.
 				var txtArgs = {
 					text: "Now is the time for all good men to come to a rest.  Plus, the rain in Spain falls mainly on the plain!",
 					x: 0, y: 0,
diff --git a/dojox/gfx/tests/test_vectortext_load.html b/dojox/gfx/tests/test_vectortext_load.html
index 751d51b..f846254 100644
--- a/dojox/gfx/tests/test_vectortext_load.html
+++ b/dojox/gfx/tests/test_vectortext_load.html
@@ -7,7 +7,7 @@
 			@import "../../../dijit/tests/css/dijitTests.css";
 		</style>
 		<script type="text/javascript" src="../../../dojo/dojo.js" 
-			djConfig="isDebug: false"></script>
+			data-dojo-config="isDebug: false"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.gfx");
 			dojo.require("dojox.gfx.VectorText");
@@ -18,7 +18,7 @@
 				var url = dojo.moduleUrl("dojox", "gfx/resources/Gillius.svg");
 				var f = new dojox.gfx.VectorFont(url);
 
-				//	draw out the glyphs for testing.
+				//		draw out the glyphs for testing.
 				var rect = surface.createRect({ x: 0, y: 0, width: 500, height: 560 })
 					.setFill(bg);
 				var g = surface.createGroup(), cx=0, count=0;
@@ -44,20 +44,20 @@
 				rect.setShape({ x:0, y:0, width:cx*factor, height: (f.viewbox.height*factor)+padding*2 });
 				dojo.byId("test").style.height = Math.round(f.viewbox.height*factor)+padding*2+"px";
 				
-				//	try to find the baseline
+				//		try to find the baseline
 				surface.createLine({ x1: 0, x2: cx*factor, 
 						y1: factor*(f.viewbox.height+f.descent), y2:factor*(f.viewbox.height+f.descent) 
 				}).setStroke({ color: "#a36e2c" });
 
-				//	lets do some measuring lines.
+				//		lets do some measuring lines.
 				var s = "#70657e", axis = surface.createGroup();
-				//	measurement axis
+				//		measurement axis
 				axis.createLine({ x1: 0, x2: cx*factor, y1: factor*f.viewbox.height+padding*2-1, y2: factor*f.viewbox.height+padding*2-1 })
 					.setStroke(s);
 
 				var major=50, minor=10, yMajor=20, yMinor=10, tick=5, steps=Math.floor(cx/minor);
 				for(var i=0; i<steps; i++){
-					//	ticks
+					//		ticks
 					var xpos = i*minor, y2 = padding*2+factor*f.viewbox.height, y1 = (xpos%major==0)?y2-yMajor:y2-yMinor;
 					axis.createLine({ x1: xpos, x2: xpos, y1: y1, y2: y2 }).setStroke(s);
 					if(xpos%major==0){
diff --git a/dojox/gfx/utils.js b/dojox/gfx/utils.js
index c916355..cb07fb8 100644
--- a/dojox/gfx/utils.js
+++ b/dojox/gfx/utils.js
@@ -2,21 +2,23 @@ define(["dojo/_base/kernel","dojo/_base/lang","./_base", "dojo/_base/html","dojo
 	"dojo/_base/Deferred", "dojo/_base/sniff", "require","dojo/_base/config"], 
   function(kernel, lang, g, html, arr, win, jsonLib, Deferred, has, require, config){
 	var gu = g.utils = {};
-	/*===== g= dojox.gfx; gu = dojox.gfx.utils; =====*/
 
 	lang.mixin(gu, {
 		forEach: function(
-			/*dojox.gfx.Surface|dojox.gfx.Shape*/ object,
+			/*dojox/gfx/shape.Surface|dojox/gfx/shape.Shape*/ object,
 			/*Function|String|Array*/ f, /*Object?*/ o
 		){
 			// summary:
-			//		Takes a shape or a surface and applies a function "f" to in the context of "o" 
-			//		(or global, if missing). If "shape" was a surface or a group, it applies the same 
+			//		Takes a shape or a surface and applies a function "f" to in the context of "o"
+			//		(or global, if missing). If "shape" was a surface or a group, it applies the same
 			//		function to all children recursively effectively visiting all shapes of the underlying scene graph.
-			// object : The gfx container to iterate.
-			// f : The function to apply.
-			// o : The scope.
-			o = o || win.global;
+			// object:
+			//		The gfx container to iterate.
+			// f:
+			//		The function to apply.
+			// o:
+			//		The scope.
+			o = o || kernel.global;
 			f.call(o, object);
 			if(object instanceof g.Surface || object instanceof g.Group){
 				arr.forEach(object.children, function(shape){
@@ -25,11 +27,12 @@ define(["dojo/_base/kernel","dojo/_base/lang","./_base", "dojo/_base/html","dojo
 			}
 		},
 
-		serialize: function(
-			/* dojox.gfx.Surface|dojox.gfx.Shape */ object
-		){
+		serialize: function(object){
 			// summary:
-			//		Takes a shape or a surface and returns a DOM object, which describes underlying shapes.
+			//		Takes a shape or a surface and returns an object, which describes underlying shapes.
+			// object: dojox/gfx/shape.Surface|dojox/gfx/shape.Shape
+			//		The container to serialize.
+
 			var t = {}, v, isSurface = object instanceof g.Surface;
 			if(isSurface || object instanceof g.Group){
 				t.children = arr.map(object.children, gu.serialize);
@@ -58,21 +61,26 @@ define(["dojo/_base/kernel","dojo/_base/lang","./_base", "dojo/_base/html","dojo
 			return t;	// Object
 		},
 
-		toJson: function(
-			/* dojox.gfx.Surface|dojox.gfx.Shape */ object,
-			/* Boolean? */ prettyPrint
-		){
+		toJson: function(object, prettyPrint){
 			// summary:
 			//		Works just like serialize() but returns a JSON string. If prettyPrint is true, the string is pretty-printed to make it more human-readable.
+			// object: dojox/gfx/shape.Surface|dojox/gfx/shape.Shape
+			//		The container to serialize.
+			// prettyPrint: Boolean?
+			//		Indicates whether the output string should be formatted.
+			// returns: String
+			
 			return jsonLib.toJson(gu.serialize(object), prettyPrint);	// String
 		},
 
-		deserialize: function(
-			/* dojox.gfx.Surface|dojox.gfx.Shape */ parent,
-			/* dojox.gfx.Shape|Array */ object
-		){
+		deserialize: function(parent, object){
 			// summary:
 			//		Takes a surface or a shape and populates it with an object produced by serialize().
+			// parent: dojox/gfx/shape.Surface|dojox/gfx/shape.Shape
+			//		The destination container for the deserialized shapes.
+			// object: dojox/gfx/shape.Shape|Array
+			//		The shapes to deserialize.
+
 			if(object instanceof Array){
 				return arr.map(object, lang.hitch(null, gu.deserialize, parent));	// Array
 			}
@@ -92,18 +100,21 @@ define(["dojo/_base/kernel","dojo/_base/lang","./_base", "dojo/_base/html","dojo
 			if("children" in object){
 				arr.forEach(object.children, lang.hitch(null, gu.deserialize, shape));
 			}
-			return shape;	// dojox.gfx.Shape
+			return shape;	// dojox/gfx/shape.Shape
 		},
 
-		fromJson: function(
-			/* dojox.gfx.Surface|dojox.gfx.Shape */ parent,
-			/* String */ json){
+		fromJson: function(parent, json){
 			// summary:
 			//		Works just like deserialize() but takes a JSON representation of the object.
-			return gu.deserialize(parent, jsonLib.fromJson(json));	// Array || dojox.gfx.Shape
+			// parent: dojox/gfx/shape.Surface|dojox/gfx/shape.Shape
+			//		The destination container for the deserialized shapes.
+			// json: String
+			//		The shapes to deserialize.
+
+			return gu.deserialize(parent, jsonLib.fromJson(json));	// Array|dojox/gfx/shape.Shape
 		},
 
-		toSvg: function(/*GFX object*/surface){
+		toSvg: function(/*dojox/gfx/shape.Surface*/surface){
 			// summary:
 			//		Function to serialize a GFX surface to SVG text.
 			// description:
@@ -291,6 +302,8 @@ define(["dojo/_base/kernel","dojo/_base/lang","./_base", "dojo/_base/html","dojo
 				if(svg.indexOf("xlink:href") === -1){
 					svg = svg.replace(/href\s*=/g, "xlink:href=");
 				}
+				// in IE, <image are serialized as <img>
+				svg = svg.replace(/<img\b([^>]*)>/gi,"<image $1 />");
 				//Do some other cleanup, like stripping out the
 				//dojoGfx attributes and quoting ids.
 				svg = svg.replace(/\bdojoGfx\w*\s*=\s*(['"])\w*\1/g, "");
diff --git a/dojox/gfx/vml.js b/dojox/gfx/vml.js
index 8ba4ed8..c07468b 100644
--- a/dojox/gfx/vml.js
+++ b/dojox/gfx/vml.js
@@ -1,33 +1,23 @@
 define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base/Color", "dojo/_base/sniff",
-		"dojo/_base/config", "dojo/dom", "dojo/dom-geometry", "dojo/_base/window", 
+		"dojo/_base/config", "dojo/dom", "dojo/dom-geometry", "dojo/_base/kernel",
 		"./_base", "./shape", "./path", "./arc", "./gradient", "./matrix"],
-  function(lang, declare, arr, Color, has, config, dom, domGeom, win, g, gs, pathLib, arcLib, gradient, m){
-/*===== 
-	dojox.gfx.vml = {
-	// module:
-	//		dojox/gfx/vml
-	// summary:
-	//		This the default graphics rendering bridge for IE6-7.
-	//		This renderer is very slow.  For best performance on IE6-8, use Silverlight plugin.
-	//		IE9+ defaults to the standard W3C SVG renderer.
+function(lang, declare, arr, Color, has, config, dom, domGeom, kernel, g, gs, pathLib, arcLib, gradient, m){
+	var vml = g.vml = {
+		// summary:
+		//		This the default graphics rendering bridge for IE6-7.
+		//		This renderer is very slow.  For best performance on IE6-8, use Silverlight plugin.
+		//		IE9+ defaults to the standard W3C SVG renderer.
+
+		// TODO: Everything exported from this file should be inside these braces.
+		// For now, I'll just put the declarations needed for documentation.
+
+		// xmlns: String
+		//		a VML's namespace
+
+		// text_alignment: Object
+		//		mapping from SVG alignment to VML alignment
 	};
-	g = dojox.gfx;
-	pathLib.Path = dojox.gfx.path.Path;
-	pathLib.TextPath = dojox.gfx.path.TextPath;
-	vml.Shape = dojox.gfx.canvas.Shape;
-	gs.Shape = dojox.gfx.shape.Shape;
-	gs.Rect = dojox.gfx.shape.Rect;
-	gs.Ellipse = dojox.gfx.shape.Ellipse;
-	gs.Circle = dojox.gfx.shape.Circle;
-	gs.Line = dojox.gfx.shape.Line;
-	gs.PolyLine = dojox.gfx.shape.PolyLine;
-	gs.Image = dojox.gfx.shape.Image;
-	gs.Text = dojox.gfx.shape.Text;
-	gs.Surface = dojox.gfx.shape.Surface;
-  =====*/
-	var vml = g.vml = {};
 
-	// dojox.gfx.vml.xmlns: String: a VML's namespace
 	vml.xmlns = "urn:schemas-microsoft-com:vml";
 
 	document.namespaces.add("v", vml.xmlns);
@@ -41,27 +31,40 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 		s.addRule("v\\:" + vmlElems[i], "behavior:url(#default#VML); display:inline-block");
 	}
 
-	// dojox.gfx.vml.text_alignment: Object: mapping from SVG alignment to VML alignment
 	vml.text_alignment = {start: "left", middle: "center", end: "right"};
 
 	vml._parseFloat = function(str) {
-		// summary: a helper function to parse VML-specific floating-point values
-		// str: String: a representation of a floating-point number
+		// summary:
+		//		a helper function to parse VML-specific floating-point values
+		// str: String
+		//		a representation of a floating-point number
 		return str.match(/^\d+f$/i) ? parseInt(str) / 65536 : parseFloat(str);	// Number
 	};
 
 	vml._bool = {"t": 1, "true": 1};
 
-	declare("dojox.gfx.vml.Shape", gs.Shape, {
-		// summary: VML-specific implementation of dojox.gfx.Shape methods
+	vml._reparentEvents = function(dst, src){
+		for(var name in src){
+			if(name.substr(0, 2).toLowerCase() == "on"){
+				dst[name] = src[name];
+				src[name] = null;
+			}
+		}
+	};
+
+	vml.Shape = declare("dojox.gfx.vml.Shape", gs.Shape, {
+		// summary:
+		//		VML-specific implementation of dojox/gfx/shape.Shape methods
 
 		setFill: function(fill){
-			// summary: sets a fill object (VML)
-			// fill: Object: a fill object
-			//	(see dojox.gfx.defaultLinearGradient,
-			//	dojox.gfx.defaultRadialGradient,
-			//	dojox.gfx.defaultPattern,
-			//	or dojo.Color)
+			// summary:
+			//		sets a fill object (VML)
+			// fill: Object
+			//		a fill object
+			//		(see dojox/gfx.defaultLinearGradient,
+			//		dojox/gfx.defaultRadialGradient,
+			//		dojox/gfx.defaultPattern,
+			//		or dojo/_base/Color)
 
 			if(!fill){
 				// don't fill
@@ -189,9 +192,11 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 		},
 
 		setStroke: function(stroke){
-			// summary: sets a stroke object (VML)
-			// stroke: Object: a stroke object
-			//	(see dojox.gfx.defaultStroke)
+			// summary:
+			//		sets a stroke object (VML)
+			// stroke: Object
+			//		a stroke object
+			//		(see dojox/gfx.defaultStroke)
 
 			if(!stroke){
 				// don't stroke
@@ -268,14 +273,20 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			if(this.fillStyle && this.fillStyle.type == "linear"){
 				this.setFill(this.fillStyle);
 			}
+			if(this.clip){
+				this.setClip(this.clip);
+			}
 			return this;
 		},
 
 		_setDimensions: function(width, height){
-			// summary: sets the width and height of the rawNode,
-			//	if the surface sixe has been changed
-			// width: String: width in pixels
-			// height: String: height in pixels
+			// summary:
+			//		sets the width and height of the rawNode,
+			//		if the surface size has been changed
+			// width: String
+			//		width in pixels
+			// height: String
+			//		height in pixels
 
 			// default implementation does nothing
 			return this; // self
@@ -283,24 +294,26 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 
 		setRawNode: function(rawNode){
 			// summary:
-			//	assigns and clears the underlying node that will represent this
-			//	shape. Once set, transforms, gradients, etc, can be applied.
-			//	(no fill & stroke by default)
+			//		assigns and clears the underlying node that will represent this
+			//		shape. Once set, transforms, gradients, etc, can be applied.
+			//		(no fill & stroke by default)
 			rawNode.stroked = "f";
 			rawNode.filled  = "f";
 			this.rawNode = rawNode;
-			this.rawNode.__gfxObject__ = this.getUID();
+			this.rawNode.__gfxObject__ = this;
 		},
 
 		// move family
 
 		_moveToFront: function(){
-			// summary: moves a shape to front of its parent's list of shapes (VML)
+			// summary:
+			//		moves a shape to front of its parent's list of shapes (VML)
 			this.rawNode.parentNode.appendChild(this.rawNode);
 			return this;
 		},
 		_moveToBack: function(){
-			// summary: moves a shape to back of its parent's list of shapes (VML)
+			// summary:
+			//		moves a shape to back of its parent's list of shapes (VML)
 			var r = this.rawNode, p = r.parentNode, n = p.firstChild;
 			p.insertBefore(r, n);
 			if(n.tagName == "rect"){
@@ -311,32 +324,72 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 		},
 
 		_getRealMatrix: function(){
-			// summary: returns the cumulative ("real") transformation matrix
-			//	by combining the shape's matrix with its parent's matrix
-			return this.parentMatrix ? new m.Matrix2D([this.parentMatrix, this.matrix]) : this.matrix;	// dojox.gfx.Matrix2D
-		}
+			// summary:
+			//		returns the cumulative ("real") transformation matrix
+			//		by combining the shape's matrix with its parent's matrix
+			return this.parentMatrix ? new m.Matrix2D([this.parentMatrix, this.matrix]) : this.matrix;	// dojox/gfx/matrix.Matrix2D
+		},
+		
+		setClip: function(clip){
+			// summary:
+			//		sets the clipping area of this shape.
+			// description:
+			//		This method overrides the dojox/gfx/shape.Shape.setClip() method. Only rectangular geometry is supported.
+			// clip: Object
+			//		an object that defines the clipping geometry, or null to remove clip.
+			this.inherited(arguments);
+			var nodeStyle = this.rawNode.style;
+			if(!clip){
+				// remove clip
+				nodeStyle.position = "absolute";
+			    nodeStyle.clip = "rect(0px "+nodeStyle.width+" "+nodeStyle.height+" 0px)";
+			}else{
+				if("width" in clip){
+					var matrix = this._getRealMatrix(),
+						l = parseFloat(nodeStyle.left),
+						t = parseFloat(nodeStyle.top);
+					if(isNaN(l)) l = 0;
+					if(isNaN(t)) t = 0;
+					// transform the clip with the shape transform to compute the correct w/h (e.g. after a scale)
+					var clipt = m.multiplyRectangle(matrix, clip);
+					var pt = m.multiplyPoint(matrix, {x:l,y:t});
+					// clip property is relative to the elt border box
+					nodeStyle.clip = "rect(" + Math.round(clipt.y-pt.y) + "px " + Math.round(clipt.x-pt.x + clipt.width ) + "px " + 
+											Math.round(clipt.y-pt.y + clipt.height ) + "px " + Math.round(clipt.x -pt.x) + "px)";
+				}
+			}
+			return this;
+ 		}
 	});
 
-	declare("dojox.gfx.vml.Group", vml.Shape, {
-		// summary: a group shape (VML), which can be used
-		//	to logically group shapes (e.g, to propagate matricies)
+	  vml.Group = declare("dojox.gfx.vml.Group", vml.Shape, {
+		// summary:
+		//		a group shape (VML), which can be used
+		//		to logically group shapes (e.g, to propagate matricies)
 		constructor: function(){
 			gs.Container._init.call(this);
 		},
 		// apply transformation
 		_applyTransform: function(){
-			// summary: applies a transformation matrix to a group
+			// summary:
+			//		applies a transformation matrix to a group
 			var matrix = this._getRealMatrix();
 			for(var i = 0; i < this.children.length; ++i){
 				this.children[i]._updateParentMatrix(matrix);
 			}
+			if(this.clip){
+				this.setClip(this.clip);
+			}
 			return this;	// self
 		},
 		_setDimensions: function(width, height){
-			// summary: sets the width and height of the rawNode,
-			//	if the surface sixe has been changed
-			// width: String: width in pixels
-			// height: String: height in pixels
+			// summary:
+			//		sets the width and height of the rawNode,
+			//		if the surface size has been changed
+			// width: String
+			//		width in pixels
+			// height: String
+			//		height in pixels
 			var r = this.rawNode, rs = r.style,
 				bs = this.bgNode.style;
 			rs.width = width;
@@ -348,15 +401,59 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 				this.children[i]._setDimensions(width, height);
 			}
 			return this; // self
+		},
+		setClip: function(clip){
+			// summary:
+			//		sets the clipping area of this shape.
+			// description:
+			//		This method overrides the dojox/gfx/shape.Shape.setClip() method.
+			// clip: Object
+			//		an object that defines the clipping geometry, or null to remove clip.
+
+			this.clip = clip;
+			var nodeStyle = this.rawNode.style;
+			if(!clip){
+				// remove clip
+				nodeStyle.position = "absolute";
+			    nodeStyle.clip = "rect(0px "+nodeStyle.width+" "+nodeStyle.height+" 0px)";
+			}else if("width" in clip){
+				var matrix = this._getRealMatrix();
+				// transform the clip with group transform
+				var clipt = m.multiplyRectangle(matrix, clip);
+				// vml feature :-( ): if the group rawNode bbox x/y are < 0,
+				// need to adjust clip accordingly
+				var bbox = this.getBoundingBox();
+				bbox = bbox ? m.multiplyRectangle(matrix, bbox) : null;
+				var offx = bbox && bbox.x < 0 ? bbox.x : 0,
+					offy = bbox && bbox.y < 0 ? bbox.y : 0;
+				nodeStyle.position = "absolute";
+				nodeStyle.clip = "rect(" + 
+					Math.round(clipt.y - offy) + "px " + 
+					Math.round(clipt.x + clipt.width - offx) + "px " + 
+					Math.round(clipt.y + clipt.height - offy)  + "px " + 
+					Math.round(clipt.x - offx) + "px)";
+			}
+			return this;
+ 		},
+		destroy: function(){
+			// summary:
+			//		Releases all internal resources owned by this shape. Once this method has been called,
+			//		the instance is considered disposed and should not be used anymore.
+			this.clear(true);
+			// avoid this.inherited
+			vml.Shape.prototype.destroy.apply(this, arguments);
 		}
 	});
 	vml.Group.nodeType = "group";
 
-	declare("dojox.gfx.vml.Rect", [vml.Shape, gs.Rect], {
-		// summary: a rectangle shape (VML)
+	  vml.Rect = declare("dojox.gfx.vml.Rect", [vml.Shape, gs.Rect], {
+		// summary:
+		//		a rectangle shape (VML)
 		setShape: function(newShape){
-			// summary: sets a rectangle shape object (VML)
-			// newShape: Object: a rectangle shape object
+			// summary:
+			//		sets a rectangle shape object (VML)
+			// newShape: Object
+			//		a rectangle shape object
 			var shape = this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var r = Math.min(1, (shape.r / Math.min(parseFloat(shape.width), parseFloat(shape.height)))).toFixed(8);
@@ -377,8 +474,9 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 				var node = this.rawNode.ownerDocument.createElement("v:roundrect");
 				node.arcsize = r;
 				node.style.display = "inline-block";
+				vml._reparentEvents(node, this.rawNode);
 				this.rawNode = node;
-				this.rawNode.__gfxObject__ = this.getUID();						
+				this.rawNode.__gfxObject__ = this;
 			}else{
 				this.rawNode.arcsize = r;
 			}
@@ -400,11 +498,14 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	});
 	vml.Rect.nodeType = "roundrect"; // use a roundrect so the stroke join type is respected
 
-	declare("dojox.gfx.vml.Ellipse", [vml.Shape, gs.Ellipse], {
-		// summary: an ellipse shape (VML)
+	vml.Ellipse = declare("dojox.gfx.vml.Ellipse", [vml.Shape, gs.Ellipse], {
+		// summary:
+		//		an ellipse shape (VML)
 		setShape: function(newShape){
-			// summary: sets an ellipse shape object (VML)
-			// newShape: Object: an ellipse shape object
+			// summary:
+			//		sets an ellipse shape object (VML)
+			// newShape: Object
+			//		an ellipse shape object
 			var shape = this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var style = this.rawNode.style;
@@ -417,11 +518,14 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	});
 	vml.Ellipse.nodeType = "oval";
 
-	declare("dojox.gfx.vml.Circle", [vml.Shape, gs.Circle], {
-		// summary: a circle shape (VML)
+	vml.Circle = declare("dojox.gfx.vml.Circle", [vml.Shape, gs.Circle], {
+		// summary:
+		//		a circle shape (VML)
 		setShape: function(newShape){
-			// summary: sets a circle shape object (VML)
-			// newShape: Object: a circle shape object
+			// summary:
+			//		sets a circle shape object (VML)
+			// newShape: Object
+			//		a circle shape object
 			var shape = this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var style = this.rawNode.style;
@@ -434,14 +538,17 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	});
 	vml.Circle.nodeType = "oval";
 
-	declare("dojox.gfx.vml.Line", [vml.Shape, gs.Line], {
-		// summary: a line shape (VML)
+	vml.Line = declare("dojox.gfx.vml.Line", [vml.Shape, gs.Line], {
+		// summary:
+		//		a line shape (VML)
 		constructor: function(rawNode){
 			if(rawNode) rawNode.setAttribute("dojoGfxType", "line");
 		},
 		setShape: function(newShape){
-			// summary: sets a line shape object (VML)
-			// newShape: Object: a line shape object
+			// summary:
+			//		sets a line shape object (VML)
+			// newShape: Object
+			//		a line shape object
 			var shape = this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			this.rawNode.path.v = "m" + shape.x1.toFixed() + " " + shape.y1.toFixed() +
@@ -451,18 +558,20 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	});
 	vml.Line.nodeType = "shape";
 
-	declare("dojox.gfx.vml.Polyline", [vml.Shape, gs.Polyline], {
-		// summary: a polyline/polygon shape (VML)
+	vml.Polyline = declare("dojox.gfx.vml.Polyline", [vml.Shape, gs.Polyline], {
+		// summary:
+		//		a polyline/polygon shape (VML)
 		constructor: function(rawNode){
 			if(rawNode) rawNode.setAttribute("dojoGfxType", "polyline");
 		},
 		setShape: function(points, closed){
-			// summary: sets a polyline/polygon shape object (VML)
-			// points: Object: a polyline/polygon shape object
-			// closed: Boolean?: if true, close the polyline explicitely
+			// summary:
+			//		sets a polyline/polygon shape object (VML)
+			// points: Object|Array
+			//		a polyline/polygon shape object, or an array of points
+			// closed: Boolean?
+			//		if true, close the polyline explicitly
 			if(points && points instanceof Array){
-				// branch
-				// points: Array: an array of points
 				this.shape = g.makeParameters(this.shape, { points: points });
 				if(closed && this.shape.points.length) this.shape.points.push(this.shape.points[0]);
 			}else{
@@ -488,11 +597,14 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	});
 	vml.Polyline.nodeType = "shape";
 
-	declare("dojox.gfx.vml.Image", [vml.Shape, gs.Image], {
-		// summary: an image (VML)
+	vml.Image = declare("dojox.gfx.vml.Image", [vml.Shape, gs.Image], {
+		// summary:
+		//		an image (VML)
 		setShape: function(newShape){
-			// summary: sets an image shape object (VML)
-			// newShape: Object: an image shape object
+			// summary:
+			//		sets an image shape object (VML)
+			// newShape: Object
+			//		an image shape object
 			var shape = this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			this.rawNode.firstChild.src = shape.src;
@@ -540,10 +652,13 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			return this; // self
 		},
 		_setDimensions: function(width, height){
-			// summary: sets the width and height of the rawNode,
-			//	if the surface sixe has been changed
-			// width: String: width in pixels
-			// height: String: height in pixels
+			// summary:
+			//		sets the width and height of the rawNode,
+			//		if the surface size has been changed
+			// width: String
+			//		width in pixels
+			// height: String
+			//		height in pixels
 
 			var r = this.rawNode, f = r.filters["DXImageTransform.Microsoft.Matrix"];
 			if(f){
@@ -557,16 +672,19 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	});
 	vml.Image.nodeType = "rect";
 
-	declare("dojox.gfx.vml.Text", [vml.Shape, gs.Text], {
-		// summary: an anchored text (VML)
+	vml.Text = declare("dojox.gfx.vml.Text", [vml.Shape, gs.Text], {
+		// summary:
+		//		an anchored text (VML)
 		constructor: function(rawNode){
 			if(rawNode){rawNode.setAttribute("dojoGfxType", "text");}
 			this.fontStyle = null;
 		},
 		_alignment: {start: "left", middle: "center", end: "right"},
 		setShape: function(newShape){
-			// summary: sets a text shape object (VML)
-			// newShape: Object: a text shape object
+			// summary:
+			//		sets a text shape object (VML)
+			// newShape: Object
+			//		a text shape object
 			this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			var r = this.rawNode, s = this.shape, x = s.x, y = s.y.toFixed(), path;
@@ -611,7 +729,8 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			return this.setTransform(this.matrix);	// self
 		},
 		_setFont: function(){
-			// summary: sets a font object (VML)
+			// summary:
+			//		sets a font object (VML)
 			var f = this.fontStyle, c = this.rawNode.childNodes;
 			for(var i = 0; i < c.length; ++i){
 				if(c[i].tagName == "textpath"){
@@ -622,9 +741,10 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			this.setTransform(this.matrix);
 		},
 		_getRealMatrix: function(){
-			// summary: returns the cumulative ("real") transformation matrix
-			//	by combining the shape's matrix with its parent's matrix;
-			//	it makes a correction for a font size
+			// summary:
+			//		returns the cumulative ("real") transformation matrix
+			//		by combining the shape's matrix with its parent's matrix;
+			//		it makes a correction for a font size
 			var matrix = this.inherited(arguments);
 			// It appears that text is always aligned vertically at a middle of x-height (???).
 			// It is impossible to obtain these metrics from VML => I try to approximate it with
@@ -633,10 +753,11 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 				matrix = m.multiply(matrix,
 					{dy: -g.normalizedLength(this.fontStyle ? this.fontStyle.size : "10pt") * 0.35});
 			}
-			return matrix;	// dojox.gfx.Matrix2D
+			return matrix;	// dojox/gfx/matrix.Matrix2D
 		},
 		getTextWidth: function(){
-			// summary: get the text width, in px
+			// summary:
+			//		get the text width, in px
 			var rawNode = this.rawNode, _display = rawNode.style.display;
 			rawNode.style.display = "inline";
 			var _width = g.pt2px(parseFloat(rawNode.currentStyle.width));
@@ -646,8 +767,9 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	});
 	vml.Text.nodeType = "shape";
 
-	declare("dojox.gfx.vml.Path", [vml.Shape, pathLib.Path], {
-		// summary: a path shape (VML)
+	vml.Path = declare("dojox.gfx.vml.Path", [vml.Shape, pathLib.Path], {
+		// summary:
+		//		a path shape (VML)
 		constructor: function(rawNode){
 			if(rawNode && !rawNode.getAttribute("dojoGfxType")){
 				rawNode.setAttribute("dojoGfxType", "path");
@@ -656,8 +778,10 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			this.lastControl = {};
 		},
 		_updateWithSegment: function(segment){
-			// summary: updates the bounding box of path with new segment
-			// segment: Object: a segment
+			// summary:
+			//		updates the bounding box of path with new segment
+			// segment: Object
+			//		a segment
 			var last = lang.clone(this.last);
 			this.inherited(arguments);
 			if(arguments.length > 1){ return; } // skip transfomed bbox calculations
@@ -671,8 +795,10 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			}
 		},
 		setShape: function(newShape){
-			// summary: forms a path using a shape (VML)
-			// newShape: Object: an VML path string or a path object (see dojox.gfx.defaultPath)
+			// summary:
+			//		forms a path using a shape (VML)
+			// newShape: Object
+			//		a VML path string or a path object (see dojox/gfx.defaultPath)
 			this.vmlPath = [];
 			this.lastControl.type = "";	// no prior control point
 			this.inherited(arguments);
@@ -900,8 +1026,9 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	});
 	vml.Path.nodeType = "shape";
 
-	declare("dojox.gfx.vml.TextPath", [vml.Path, pathLib.TextPath], {
-		// summary: a textpath shape (VML)
+	vml.TextPath = declare("dojox.gfx.vml.TextPath", [vml.Path, pathLib.TextPath], {
+		// summary:
+		//		a textpath shape (VML)
 		constructor: function(rawNode){
 			if(rawNode){rawNode.setAttribute("dojoGfxType", "textpath");}
 			this.fontStyle = null;
@@ -913,14 +1040,16 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			}
 		},
 		setText: function(newText){
-			// summary: sets a text to be drawn along the path
+			// summary:
+			//		sets a text to be drawn along the path
 			this.text = g.makeParameters(this.text,
 				typeof newText == "string" ? {text: newText} : newText);
 			this._setText();
 			return this;	// self
 		},
 		setFont: function(newFont){
-			// summary: sets a font for text
+			// summary:
+			//		sets a font for text
 			this.fontStyle = typeof newFont == "string" ?
 				g.splitFontString(newFont) :
 				g.makeParameters(g.defaultFont, newFont);
@@ -929,7 +1058,8 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 		},
 
 		_setText: function(){
-			// summary: sets a text shape object (VML)
+			// summary:
+			//		sets a text shape object (VML)
 			this.bbox = null;
 			var r = this.rawNode, s = this.text,
 				// find path and text path
@@ -962,7 +1092,8 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			t.string = s.text;
 		},
 		_setFont: function(){
-			// summary: sets a font object (VML)
+			// summary:
+			//		sets a font object (VML)
 			var f = this.fontStyle, c = this.rawNode.childNodes;
 			for(var i = 0; i < c.length; ++i){
 				if(c[i].tagName == "textpath"){
@@ -974,15 +1105,23 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	});
 	vml.TextPath.nodeType = "shape";
 
-	declare("dojox.gfx.vml.Surface", gs.Surface, {
-		// summary: a surface object to be used for drawings (VML)
+	vml.Surface = declare("dojox.gfx.vml.Surface", gs.Surface, {
+		// summary:
+		//		a surface object to be used for drawings (VML)
 		constructor: function(){
 			gs.Container._init.call(this);
 		},
+		destroy: function(){
+			this.clear(true); 
+			this.inherited(arguments);
+		},
 		setDimensions: function(width, height){
-			// summary: sets the width and height of the rawNode
-			// width: String: width of surface, e.g., "100px"
-			// height: String: height of surface, e.g., "100px"
+			// summary:
+			//		sets the width and height of the rawNode
+			// width: String
+			//		width of surface, e.g., "100px"
+			// height: String
+			//		height of surface, e.g., "100px"
 			this.width  = g.normalizedLength(width);	// in pixels
 			this.height = g.normalizedLength(height);	// in pixels
 			if(!this.rawNode) return this;
@@ -1006,7 +1145,8 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			return this;	// self
 		},
 		getDimensions: function(){
-			// summary: returns an object with properties "width" and "height"
+			// summary:
+			//		returns an object with properties "width" and "height"
 			var t = this.rawNode ? {
 				width:  g.normalizedLength(this.rawNode.style.width),
 				height: g.normalizedLength(this.rawNode.style.height)} : null;
@@ -1017,10 +1157,16 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	});
 
 	vml.createSurface = function(parentNode, width, height){
-		// summary: creates a surface (VML)
-		// parentNode: Node: a parent node
-		// width: String: width of surface, e.g., "100px"
-		// height: String: height of surface, e.g., "100px"
+		// summary:
+		//		creates a surface (VML)
+		// parentNode: Node
+		//		a parent node
+		// width: String|Number
+		//		width of surface, e.g., "100px" or 100
+		// height: String|NUmber
+		//		height of surface, e.g., "100px" or 100
+		// returns:
+		//     newly created surface
 
 		if(!width && !height){
 			var pos = domGeom.position(parentNode);
@@ -1074,14 +1220,14 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 		s.width  = g.normalizedLength(width);	// in pixels
 		s.height = g.normalizedLength(height);	// in pixels
 
-		return s;	// dojox.gfx.Surface
+		return s;	// dojox/gfx/shape.Surface
 	};
 
 	// Extenders
 	
-	// copied from dojox.gfx.utils
+	// copied from dojox/gfx/utils
 	function forEach(object, f, o){
-		o = o || win.global;
+		o = o || kernel.global;
 		f.call(o, object);
 		if(object instanceof g.Surface || object instanceof g.Group){
 			arr.forEach(object.children, function(shape){
@@ -1129,9 +1275,12 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 	var C = gs.Container, Container = {
 		add: config.fixVmlAdd === true ? addPatch9624 : add15,
 		remove: function(shape, silently){
-			// summary: remove a shape from a group/surface
-			// shape: dojox.gfx.Shape: an VML shape object
-			// silently: Boolean?: if true, regenerate a picture
+			// summary:
+			//		remove a shape from a group/surface
+			// shape: dojox/gfx/shape.Shape
+			//		a VML shape object
+			// silently: Boolean?
+			//		if true, regenerate a picture
 			if(this == shape.getParent()){
 				if(this.rawNode == shape.rawNode.parentNode){
 					this.rawNode.removeChild(shape.rawNode);
@@ -1141,7 +1290,8 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			return this;	// self
 		},
 		clear: function(){
-			// summary: removes all shapes from a group/surface
+			// summary:
+			//		removes all shapes from a group/surface
 			var r = this.rawNode;
 			while(r.firstChild != r.lastChild){
 				if(r.firstChild != this.bgNode){
@@ -1153,15 +1303,18 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			}
 			return C.clear.apply(this, arguments);
 		},
+		getBoundingBox: C.getBoundingBox,
 		_moveChildToFront: C._moveChildToFront,
 		_moveChildToBack:  C._moveChildToBack
 	};
 
 	var Creator = {
-		// summary: VML shape creators
+		// summary:
+		//		VML shape creators
 		createGroup: function(){
-			// summary: creates a VML group shape
-			var node = this.createObject(vml.Group, null);	// dojox.gfx.Group
+			// summary:
+			//		creates a VML group shape
+			var node = this.createObject(vml.Group, null);	// dojox/gfx.Group
 			// create a background rectangle, which is required to show all other shapes
 			var r = node.rawNode.ownerDocument.createElement("v:rect");
 			r.style.left = r.style.top = 0;
@@ -1170,11 +1323,13 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			r.filled = r.stroked = "f";
 			node.rawNode.appendChild(r);
 			node.bgNode = r;
-			return node;	// dojox.gfx.Group
+			return node;	// dojox/gfx.Group
 		},
 		createImage: function(image){
-			// summary: creates a VML image shape
-			// image: Object: an image object (see dojox.gfx.defaultImage)
+			// summary:
+			//		creates a VML image shape
+			// image: Object
+			//		an image object (see dojox/gfx.defaultImage)
 			if(!this.rawNode) return null;
 			var shape = new vml.Image(),
 				doc = this.rawNode.ownerDocument,
@@ -1188,11 +1343,13 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			this.rawNode.appendChild(node);
 			shape.setShape(image);
 			this.add(shape);
-			return shape;	// dojox.gfx.Image
+			return shape;	// dojox/gfx/shape.Image
 		},
 		createRect: function(rect){
-			// summary: creates a rectangle shape
-			// rect: Object: a path object (see dojox.gfx.defaultRect)
+			// summary:
+			//		creates a rectangle shape
+			// rect: Object
+			//		a path object (see dojox/gfx.defaultRect)
 			if(!this.rawNode) return null;
 			var shape = new vml.Rect,
 				node = this.rawNode.ownerDocument.createElement("v:roundrect");
@@ -1203,13 +1360,17 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			this.rawNode.appendChild(node);
 			shape.setShape(rect);
 			this.add(shape);
-			return shape;	// dojox.gfx.Rect
+			return shape;	// dojox/gfx.Rect
 		},
 		createObject: function(shapeType, rawShape) {
-			// summary: creates an instance of the passed shapeType class
-			// shapeType: Function: a class constructor to create an instance of
-			// rawShape: Object: properties to be passed in to the classes "setShape" method
-			// overrideSize: Boolean: set the size explicitly, if true
+			// summary:
+			//		creates an instance of the passed shapeType class
+			// shapeType: Function
+			//		a class constructor to create an instance of
+			// rawShape: Object
+			//		properties to be passed in to the classes "setShape" method
+			// overrideSize: Boolean
+			//		set the size explicitly, if true
 			if(!this.rawNode) return null;
 			var shape = new shapeType(),
 				node = this.rawNode.ownerDocument.createElement('v:' + shapeType.nodeType);
@@ -1227,7 +1388,7 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 			}
 			shape.setShape(rawShape);
 			this.add(shape);
-			return shape;	// dojox.gfx.Shape
+			return shape;	// dojox/gfx/shape.Shape
 		},
 		_overrideSize: function(node){
 			var s = this.rawNode.style, w = s.width, h = s.height;
@@ -1247,15 +1408,15 @@ define(["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/_base
 
 	// Mouse/Touch event
 	vml.fixTarget = function(event, gfxElement){
-		// summary: 
-		//     Adds the gfxElement to event.gfxTarget if none exists. This new 
-		//     property will carry the GFX element associated with this event.
+		// summary:
+		//		Adds the gfxElement to event.gfxTarget if none exists. This new
+		//		property will carry the GFX element associated with this event.
 		// event: Object 
-		//     The current input event (MouseEvent or TouchEvent)
+		//		The current input event (MouseEvent or TouchEvent)
 		// gfxElement: Object
-		//     The GFX target element
+		//		The GFX target element
 		if (!event.gfxTarget) {
-			event.gfxTarget = gs.byId(event.target.__gfxObject__);
+			event.gfxTarget = event.target.__gfxObject__;
 		}
 		return true;
 	};
diff --git a/dojox/gfx/vml_attach.js b/dojox/gfx/vml_attach.js
index d385d6c..426a3d2 100644
--- a/dojox/gfx/vml_attach.js
+++ b/dojox/gfx/vml_attach.js
@@ -4,8 +4,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	kernel.experimental("dojox.gfx.vml_attach");
 	
 	vml.attachNode = function(node){
-		// summary: creates a shape from a Node
-		// node: Node: an VML node
+		// summary:
+		//		creates a shape from a Node
+		// node: Node
+		//		a VML node
 		if(!node) return null;
 		var s = null;
 		switch(node.tagName.toLowerCase()){
@@ -70,26 +72,30 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 				attachTransform(s);
 			}
 		}
-		return s;	// dojox.gfx.Shape
+		return s;	// dojox/gfx/shape.Shape
 	};
 
 	vml.attachSurface = function(node){
-		// summary: creates a surface from a Node
-		// node: Node: an VML node
+		// summary:
+		//		creates a surface from a Node
+		// node: Node
+		//		a VML node
 		var s = new vml.Surface();
 		s.clipNode = node;
 		var r = s.rawNode = node.firstChild;
 		var b = r.firstChild;
 		if(!b || b.tagName != "rect"){
-			return null;	// dojox.gfx.Surface
+			return null;	// dojox/gfx.Surface
 		}
 		s.bgNode = r;
-		return s;	// dojox.gfx.Surface
+		return s;	// dojox/gfx.Surface
 	};
 
 	var attachFill = function(object){
-		// summary: deduces a fill style from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		deduces a fill style from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		var fillStyle = null, r = object.rawNode, fo = r.fill, stops, i, t;
 		if(fo.on && fo.type == "gradient"){
 			fillStyle = lang.clone(g.defaultLinearGradient),
@@ -132,8 +138,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachStroke = function(object) {
-		// summary: deduces a stroke style from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		deduces a stroke style from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		var r = object.rawNode;
 		if(!r.stroked){
 			object.strokeStyle = null;
@@ -150,8 +158,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachTransform = function(object) {
-		// summary: deduces a transformation matrix from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		deduces a transformation matrix from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		var s = object.rawNode.skew, sm = s.matrix, so = s.offset;
 		object.matrix = m.normalize({
 			xx: sm.xtox,
@@ -164,15 +174,21 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachGroup = function(object){
-		// summary: reconstructs all group shape parameters from a node (VML).
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		reconstructs all group shape parameters from a node (VML).
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
+		
 		// attach the background
 		object.bgNode = object.rawNode.firstChild;	// TODO: check it first
 	};
 
 	var attachRect = function(object){
-		// summary: builds a rectangle shape from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		builds a rectangle shape from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
+		
 		// a workaround for the VML's arcsize bug: cannot read arcsize of an instantiated node
 		var r = object.rawNode, arcsize = r.outerHTML.match(/arcsize = \"(\d*\.?\d+[%f]?)\"/)[1],
 			style = r.style, width = parseFloat(style.width), height = parseFloat(style.height);
@@ -188,8 +204,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachEllipse = function(object){
-		// summary: builds an ellipse shape from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		builds an ellipse shape from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		var style = object.rawNode.style,
 			rx = parseInt(style.width ) / 2,
 			ry = parseInt(style.height) / 2;
@@ -202,8 +220,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachCircle = function(object){
-		// summary: builds a circle shape from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		builds a circle shape from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		var style = object.rawNode.style, r = parseInt(style.width) / 2;
 		object.shape = g.makeParameters(g.defaultCircle, {
 			cx: parseInt(style.left) + r,
@@ -213,8 +233,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachLine = function(object){
-		// summary: builds a line shape from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		builds a line shape from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		var shape = object.shape = lang.clone(g.defaultLine),
 			p = object.rawNode.path.v.match(g.pathVmlRegExp);
 		do{
@@ -227,8 +249,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachPolyline = function(object){
-		// summary: builds a polyline/polygon shape from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		builds a polyline/polygon shape from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		var shape = object.shape = lang.clone(g.defaultPolyline),
 			p = object.rawNode.path.v.match(g.pathVmlRegExp);
 		do{
@@ -247,15 +271,19 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachImage = function(object){
-		// summary: builds an image shape from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		builds an image shape from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		object.shape = lang.clone(g.defaultImage);
 		object.shape.src = object.rawNode.firstChild.src;
 	};
 
 	var attachImageTransform = function(object) {
-		// summary: deduces a transformation matrix from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		deduces a transformation matrix from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		var mm = object.rawNode.filters["DXImageTransform.Microsoft.Matrix"];
 		object.matrix = m.normalize({
 			xx: mm.M11,
@@ -268,8 +296,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachText = function(object){
-		// summary: builds a text shape from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		builds a text shape from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		var shape = object.shape = lang.clone(g.defaultText),
 			r = object.rawNode, p = r.path.v.match(g.pathVmlRegExp);
 		do{
@@ -303,8 +333,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachFont = function(object){
-		// summary: deduces a font style from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		deduces a font style from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		var fontStyle = object.fontStyle = lang.clone(g.defaultFont),
 			c = object.rawNode.childNodes, i = 0;
 		for(; i < c.length && c[i].tagName == "textpath"; ++i);
@@ -321,8 +353,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachTextTransform = function(object) {
-		// summary: deduces a transformation matrix from a node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		deduces a transformation matrix from a node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		attachTransform(object);
 		var matrix = object.matrix, fs = object.fontStyle;
 		// see comments in _getRealMatrix()
@@ -332,8 +366,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base", "./matrix", "./path",
 	};
 
 	var attachPath = function(object){
-		// summary: builds a path shape from a Node.
-		// object: dojox.gfx.Shape: an VML shape
+		// summary:
+		//		builds a path shape from a Node.
+		// object: dojox/gfx/shape.Shape
+		//		a VML shape
 		var shape = object.shape = lang.clone(g.defaultPath),
 			p = object.rawNode.path.v.match(g.pathVmlRegExp),
 			t = [], skip = false, map = pathLib._pathVmlToSvgMap;
diff --git a/dojox/gfx3d.js b/dojox/gfx3d.js
index a92f812..72dd270 100644
--- a/dojox/gfx3d.js
+++ b/dojox/gfx3d.js
@@ -1,6 +1,14 @@
 // AMD-ID "dojox/gfx3d"
 define(["dojo/_base/kernel","dojox","./gfx3d/matrix","./gfx3d/_base","./gfx3d/object"], function(dojo,dojox) {
-dojo.getObject("gfx3d", true, dojox);
+	dojo.getObject("gfx3d", true, dojox);
 
-return dojox.gfx3d;
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/gfx3d modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
+
+	return dojox.gfx3d;
 });
diff --git a/dojox/gfx3d/_base.js b/dojox/gfx3d/_base.js
index 0979591..98d013e 100644
--- a/dojox/gfx3d/_base.js
+++ b/dojox/gfx3d/_base.js
@@ -1,7 +1,8 @@
 define(["dojo/_base/lang"],function(lang) {
 	var gfx3d = lang.getObject("dojox.gfx3d",true);
 	lang.mixin( gfx3d, {
-		// summary: defines constants, prototypes, and utility functions
+		// summary:
+		//		defines constants, prototypes, and utility functions
 		
 		// default objects, which are used to fill in missing parameters
 		defaultEdges:	  {type: "edges",     style: null, points: []},
diff --git a/dojox/gfx3d/gradient.js b/dojox/gfx3d/gradient.js
index 4f8a192..e0dad43 100644
--- a/dojox/gfx3d/gradient.js
+++ b/dojox/gfx3d/gradient.js
@@ -7,15 +7,24 @@ define(["dojo/_base/lang","./matrix","./vector"],
 	var N = 32;
 
 	gfx3d.gradient = function(model, material, center, radius, from, to, matrix){
-		// summary: calculate a cylindrical gradient
-		// model: dojox.gfx3d.lighting.Model: color model
-		// material: Object: defines visual properties
-		// center: Object: center of the cylinder's bottom
-		// radius: Number: radius of the cylinder
-		// from: Number: from position in radians
-		// to: Number: from position in radians
-		// matrix: dojox.gfx3d.Matrix3D: the cumulative transformation matrix
-		// tolerance: Number: tolerable difference in colors between gradient steps
+		// summary:
+		//		calculate a cylindrical gradient
+		// model: dojox.gfx3d.lighting.Model
+		//		color model
+		// material: Object
+		//		defines visual properties
+		// center: Object
+		//		center of the cylinder's bottom
+		// radius: Number
+		//		radius of the cylinder
+		// from: Number
+		//		from position in radians
+		// to: Number
+		//		from position in radians
+		// matrix: dojox.gfx3d.Matrix3D
+		//		the cumulative transformation matrix
+		// tolerance: Number
+		//		tolerable difference in colors between gradient steps
 
 		var mx = m.normalize(matrix),
 			f = m.multiplyPoint(mx, radius * Math.cos(from) + center.x, radius * Math.sin(from) + center.y, center.z),
diff --git a/dojox/gfx3d/lighting.js b/dojox/gfx3d/lighting.js
index e68350e..7a4f1c0 100644
--- a/dojox/gfx3d/lighting.js
+++ b/dojox/gfx3d/lighting.js
@@ -1,7 +1,7 @@
 define([
 	"dojo/_base/lang",
 	"dojo/_base/Color",	// dojo.Color
-	"dojo/_base/declare",	// dojo.declare
+	"dojo/_base/declare",	// declare
 	"dojox/gfx/_base",
 	"./_base"
 ],function(lang,Color,declare,gfx,gfx3d) {
diff --git a/dojox/gfx3d/matrix.js b/dojox/gfx3d/matrix.js
index 01f16b1..d399366 100644
--- a/dojox/gfx3d/matrix.js
+++ b/dojox/gfx3d/matrix.js
@@ -7,8 +7,10 @@ define(["dojo/_base/lang", "./_base"], function(lang, gfx3d){
 	};
 	
 	gfx3d.matrix.Matrix3D = function(arg){
-		// summary: a 3D matrix object
-		// description: Normalizes a 3D matrix-like object. If arrays is passed,
+		// summary:
+		//		a 3D matrix object
+		// description:
+		//		Normalizes a 3D matrix-like object. If arrays is passed,
 		//		all objects of the array are normalized and multiplied sequentially.
 		// arg: Object
 		//		a 3D matrix-like object, a number, or an array of such objects
@@ -48,7 +50,8 @@ define(["dojo/_base/lang", "./_base"], function(lang, gfx3d){
 	lang.extend(gfx3d.matrix.Matrix3D, {xx: 1, xy: 0, xz: 0, yx: 0, yy: 1, yz: 0, zx: 0, zy: 0, zz: 1, dx: 0, dy: 0, dz: 0});
 	
 	lang.mixin(gfx3d.matrix, {
-		// summary: class constants, and methods of dojox.gfx3d.matrix
+		// summary:
+		//		class constants, and methods of dojox.gfx3d.matrix
 		
 		// matrix constants
 		
@@ -59,172 +62,219 @@ define(["dojo/_base/lang", "./_base"], function(lang, gfx3d){
 		// matrix creators
 		
 		translate: function(a, b, c){
-			// summary: forms a translation matrix
-			// description: The resulting matrix is used to translate (move) points by specified offsets.
-			// a: Number: an x coordinate value
-			// b: Number: a y coordinate value
-			// c: Number: a z coordinate value
+			// summary:
+			//		forms a translation matrix
+			// description:
+			//		The resulting matrix is used to translate (move) points by specified offsets.
+			// a: Number|Object
+			//		an x coordinate value, or a point-like object, which specifies offsets for 3 dimensions
+			// b: Number?
+			//		a y coordinate value
+			// c: Number?
+			//		a z coordinate value
+
 			if(arguments.length > 1){
 				return new gfx3d.matrix.Matrix3D({dx: a, dy: b, dz: c}); // dojox.gfx3d.matrix.Matrix3D
 			}
-			// branch
-			// a: Object: a point-like object, which specifies offsets for 3 dimensions
-			// b: null
+
 			return new gfx3d.matrix.Matrix3D({dx: a.x, dy: a.y, dz: a.z}); // dojox.gfx3d.matrix.Matrix3D
 		},
 		scale: function(a, b, c){
-			// summary: forms a scaling matrix
-			// description: The resulting matrix is used to scale (magnify) points by specified offsets.
-			// a: Number: a scaling factor used for the x coordinate
-			// b: Number: a scaling factor used for the y coordinate
-			// c: Number: a scaling factor used for the z coordinate
+			// summary:
+			//		forms a scaling matrix
+			// description:
+			//		The resulting matrix is used to scale (magnify) points by specified offsets.
+			// a: Number|Object
+			//		a scaling factor used for the x coordinate, or a uniform scaling factor used for the all coordinates,
+			//		or a point-like object, which specifies scale factors for 3 dimensions
+			// b: Number?
+			//		a scaling factor used for the y coordinate
+			// c: Number?
+			//		a scaling factor used for the z coordinate
 			if(arguments.length > 1){
 				return new gfx3d.matrix.Matrix3D({xx: a, yy: b, zz: c}); // dojox.gfx3d.matrix.Matrix3D
 			}
 			if(typeof a == "number"){
-				// branch
-				// a: Number: a uniform scaling factor used for the all coordinates
-				// b: null
 				return new gfx3d.matrix.Matrix3D({xx: a, yy: a, zz: a}); // dojox.gfx3d.matrix.Matrix3D
 			}
-			// branch
-			// a: Object: a point-like object, which specifies scale factors for 3 dimensions
-			// b: null
 			return new gfx3d.matrix.Matrix3D({xx: a.x, yy: a.y, zz: a.z}); // dojox.gfx3d.matrix.Matrix3D
 		},
 		rotateX: function(angle){
-			// summary: forms a rotating matrix (about the x axis)
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the x axis)
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified angle.
-			// angle: Number: an angle of rotation in radians (>0 for CW)
+			// angle: Number
+			//		an angle of rotation in radians (>0 for CW)
 			var c = Math.cos(angle);
 			var s = Math.sin(angle);
 			return new gfx3d.matrix.Matrix3D({yy: c, yz: -s, zy: s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
 		},
 		rotateXg: function(degree){
-			// summary: forms a rotating matrix (about the x axis)
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the x axis)
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified degree.
 			//		See dojox.gfx3d.matrix.rotateX() for comparison.
-			// degree: Number: an angle of rotation in degrees (>0 for CW)
+			// degree: Number
+			//		an angle of rotation in degrees (>0 for CW)
 			return gfx3d.matrix.rotateX(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
 		},
 		rotateY: function(angle){
-			// summary: forms a rotating matrix (about the y axis)
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the y axis)
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified angle.
-			// angle: Number: an angle of rotation in radians (>0 for CW)
+			// angle: Number
+			//		an angle of rotation in radians (>0 for CW)
 			var c = Math.cos(angle);
 			var s = Math.sin(angle);
 			return new gfx3d.matrix.Matrix3D({xx: c, xz: s, zx: -s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
 		},
 		rotateYg: function(degree){
-			// summary: forms a rotating matrix (about the y axis)
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the y axis)
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified degree.
 			//		See dojox.gfx3d.matrix.rotateY() for comparison.
-			// degree: Number: an angle of rotation in degrees (>0 for CW)
+			// degree: Number
+			//		an angle of rotation in degrees (>0 for CW)
 			return gfx3d.matrix.rotateY(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
 		},
 		rotateZ: function(angle){
-			// summary: forms a rotating matrix (about the z axis)
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the z axis)
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified angle.
-			// angle: Number: an angle of rotation in radians (>0 for CW)
+			// angle: Number
+			//		an angle of rotation in radians (>0 for CW)
 			var c = Math.cos(angle);
 			var s = Math.sin(angle);
 			return new gfx3d.matrix.Matrix3D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx3d.matrix.Matrix3D
 		},
 		rotateZg: function(degree){
-			// summary: forms a rotating matrix (about the z axis)
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the z axis)
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified degree.
 			//		See dojox.gfx3d.matrix.rotateZ() for comparison.
-			// degree: Number: an angle of rotation in degrees (>0 for CW)
+			// degree: Number
+			//		an angle of rotation in degrees (>0 for CW)
 			return gfx3d.matrix.rotateZ(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
 		},
 	
 		// camera transformation
 		cameraTranslate: function(a, b, c){
-			// summary: forms a translation matrix
-			// description: The resulting matrix is used to translate (move) points by specified offsets.
-			// a: Number: an x coordinate value
-			// b: Number: a y coordinate value
-			// c: Number: a z coordinate value
+			// summary:
+			//		forms a translation matrix
+			// description:
+			//		The resulting matrix is used to translate (move) points by specified offsets.
+			// a: Number|Object
+			//		an x coordinate value, or a point-like object, which specifies offsets for 3 dimensions
+			// b: Number?
+			//		a y coordinate value
+			// c: Number?
+			//		a z coordinate value
 			if(arguments.length > 1){
 				return new gfx3d.matrix.Matrix3D({dx: -a, dy: -b, dz: -c}); // dojox.gfx3d.matrix.Matrix3D
 			}
-			// branch
-			// a: Object: a point-like object, which specifies offsets for 3 dimensions
-			// b: null
 			return new gfx3d.matrix.Matrix3D({dx: -a.x, dy: -a.y, dz: -a.z}); // dojox.gfx3d.matrix.Matrix3D
 		},
 		cameraRotateX: function(angle){
-			// summary: forms a rotating matrix (about the x axis) in cameraTransform manner
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the x axis) in cameraTransform manner
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified angle.
-			// angle: Number: an angle of rotation in radians (>0 for CW)
+			// angle: Number
+			//		an angle of rotation in radians (>0 for CW)
 			var c = Math.cos(-angle);
 			var s = Math.sin(-angle);
 			return new gfx3d.matrix.Matrix3D({yy: c, yz: -s, zy: s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
 		},
 		cameraRotateXg: function(degree){
-			// summary: forms a rotating matrix (about the x axis)in cameraTransform manner
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the x axis)in cameraTransform manner
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified degree.
 			//		See dojox.gfx3d.matrix.rotateX() for comparison.
-			// degree: Number: an angle of rotation in degrees (>0 for CW)
+			// degree: Number
+			//		an angle of rotation in degrees (>0 for CW)
 			return gfx3d.matrix.rotateX(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
 		},
 		cameraRotateY: function(angle){
-			// summary: forms a rotating matrix (about the y axis) in cameraTransform manner
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the y axis) in cameraTransform manner
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified angle.
-			// angle: Number: an angle of rotation in radians (>0 for CW)
+			// angle: Number
+			//		an angle of rotation in radians (>0 for CW)
 			var c = Math.cos(-angle);
 			var s = Math.sin(-angle);
 			return new gfx3d.matrix.Matrix3D({xx: c, xz: s, zx: -s, zz: c}); // dojox.gfx3d.matrix.Matrix3D
 		},
 		cameraRotateYg: function(degree){
-			// summary: forms a rotating matrix (about the y axis) in cameraTransform manner
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the y axis) in cameraTransform manner
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified degree.
 			//		See dojox.gfx3d.matrix.rotateY() for comparison.
-			// degree: Number: an angle of rotation in degrees (>0 for CW)
+			// degree: Number
+			//		an angle of rotation in degrees (>0 for CW)
 			return gfx3d.matrix.rotateY(dojox.gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
 		},
 		cameraRotateZ: function(angle){
-			// summary: forms a rotating matrix (about the z axis) in cameraTransform manner
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the z axis) in cameraTransform manner
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified angle.
-			// angle: Number: an angle of rotation in radians (>0 for CW)
+			// angle: Number
+			//		an angle of rotation in radians (>0 for CW)
 			var c = Math.cos(-angle);
 			var s = Math.sin(-angle);
 			return new gfx3d.matrix.Matrix3D({xx: c, xy: -s, yx: s, yy: c}); // dojox.gfx3d.matrix.Matrix3D
 		},
 		cameraRotateZg: function(degree){
-			// summary: forms a rotating matrix (about the z axis) in cameraTransform manner
-			// description: The resulting matrix is used to rotate points
+			// summary:
+			//		forms a rotating matrix (about the z axis) in cameraTransform manner
+			// description:
+			//		The resulting matrix is used to rotate points
 			//		around the origin of coordinates (0, 0) by specified degree.
 			//		See dojox.gfx3d.matrix.rotateZ() for comparison.
-			// degree: Number: an angle of rotation in degrees (>0 for CW)
+			// degree: Number
+			//		an angle of rotation in degrees (>0 for CW)
 			return gfx3d.matrix.rotateZ(gfx3d.matrix._degToRad(degree)); // dojox.gfx3d.matrix.Matrix3D
 		},
 	
 		// ensure matrix 3D conformance
 		normalize: function(matrix){
-			// summary: converts an object to a matrix, if necessary
-			// description: Converts any 3D matrix-like object or an array of
+			// summary:
+			//		converts an object to a matrix, if necessary
+			// description:
+			//		Converts any 3D matrix-like object or an array of
 			//		such objects to a valid dojox.gfx3d.matrix.Matrix3D object.
-			// matrix: Object: an object, which is converted to a matrix, if necessary
+			// matrix: Object
+			//		an object, which is converted to a matrix, if necessary
 			return (matrix instanceof gfx3d.matrix.Matrix3D) ? matrix : new gfx3d.matrix.Matrix3D(matrix); // dojox.gfx3d.matrix.Matrix3D
 		},
 		
 		// common operations
 		
 		clone: function(matrix){
-			// summary: creates a copy of a 3D matrix
-			// matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix-like object to be cloned
+			// summary:
+			//		creates a copy of a 3D matrix
+			// matrix: dojox.gfx3d.matrix.Matrix3D
+			//		a 3D matrix-like object to be cloned
 			var obj = new gfx3d.matrix.Matrix3D();
 			for(var i in matrix){
 				if(typeof(matrix[i]) == "number" && typeof(obj[i]) == "number" && obj[i] != matrix[i]) obj[i] = matrix[i];
@@ -232,8 +282,10 @@ define(["dojo/_base/lang", "./_base"], function(lang, gfx3d){
 			return obj; // dojox.gfx3d.matrix.Matrix3D
 		},
 		invert: function(matrix){
-			// summary: inverts a 2D matrix
-			// matrix: dojox.gfx.matrix.Matrix3D: a 2D matrix-like object to be inverted
+			// summary:
+			//		inverts a 2D matrix
+			// matrix: dojox.gfx.matrix.Matrix3D
+			//		a 2D matrix-like object to be inverted
 			var m = gfx3d.matrix.normalize(matrix);
 			var D = m.xx * m.yy * m.zz + m.xy * m.yz * m.zx + m.xz * m.yx * m.zy - m.xx * m.yz * m.zy - m.xy * m.yx * m.zz - m.xz * m.yy * m.zx;
 			var M = new gfx3d.matrix.Matrix3D({
@@ -253,33 +305,40 @@ define(["dojo/_base/lang", "./_base"], function(lang, gfx3d){
 			return M; // dojox.gfx3d.matrix.Matrix3D
 		},
 		_multiplyPoint: function(m, x, y, z){
-			// summary: applies a matrix to a point
-			// matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
-			// x: Number: an x coordinate of a point
-			// y: Number: a y coordinate of a point
-			// z: Number: a z coordinate of a point
+			// summary:
+			//		applies a matrix to a point
+			// matrix: dojox.gfx3d.matrix.Matrix3D
+			//		a 3D matrix object to be applied
+			// x: Number
+			//		an x coordinate of a point
+			// y: Number
+			//		a y coordinate of a point
+			// z: Number
+			//		a z coordinate of a point
 			return {x: m.xx * x + m.xy * y + m.xz * z + m.dx, y: m.yx * x + m.yy * y + m.yz * z + m.dy, z: m.zx * x + m.zy * y + m.zz * z + m.dz}; // Object
 		},
-		multiplyPoint: function(matrix, /* Number||Point */ a, /* Number, optional */ b, /* Number, optional */ c){
-			// summary: applies a matrix to a point
-			// matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
-			// a: Number: an x coordinate of a point
-			// b: Number: a y coordinate of a point
-			// c: Number: a z coordinate of a point
+		multiplyPoint: function(matrix, a,  b, c){
+			// summary:
+			//		applies a matrix to a point
+			// matrix: dojox.gfx3d.matrix.Matrix3D
+			//		a 3D matrix object to be applied
+			// a: Number|Object
+			//		an x coordinate of a point, or an Object specifying the whole point
+			// b: Number?
+			//		a y coordinate of a point
+			// c: Number?
+			//		a z coordinate of a point
 			var m = gfx3d.matrix.normalize(matrix);
 			if(typeof a == "number" && typeof b == "number" && typeof c == "number"){
 				return gfx3d.matrix._multiplyPoint(m, a, b, c); // Object
 			}
-			// branch
-			// matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
-			// a: Object: a point
-			// b: null
-			// c: null
 			return gfx3d.matrix._multiplyPoint(m, a.x, a.y, a.z); // Object
 		},
 		multiply: function(matrix){
-			// summary: combines matrices by multiplying them sequentially in the given order
-			// matrix: dojox.gfx3d.matrix.Matrix3D...: a 3D matrix-like object,
+			// summary:
+			//		combines matrices by multiplying them sequentially in the given order
+			// matrix: dojox.gfx3d.matrix.Matrix3D
+			//		a 3D matrix-like object,
 			//		all subsequent arguments are matrix-like objects too
 			var m = gfx3d.matrix.normalize(matrix);
 			// combine matrices
@@ -304,31 +363,36 @@ define(["dojo/_base/lang", "./_base"], function(lang, gfx3d){
 		},
 	
 		_project: function(m, x, y, z){
-			// summary: applies a matrix to a point
-			// matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
-			// x: Number: an x coordinate of a point
-			// y: Number: a y coordinate of a point
-			// z: Number: a z coordinate of a point
+			// summary:
+			//		applies a matrix to a point
+			// matrix: dojox.gfx3d.matrix.Matrix3D
+			//		a 3D matrix object to be applied
+			// x: Number
+			//		an x coordinate of a point
+			// y: Number
+			//		a y coordinate of a point
+			// z: Number
+			//		a z coordinate of a point
 			return {	// Object
 				x: m.xx * x + m.xy * y + m.xz * z + m.dx,
 				y: m.yx * x + m.yy * y + m.yz * z + m.dy,
 				z: m.zx * x + m.zy * y + m.zz * z + m.dz};
 		},
-		project: function(matrix, /* Number||Point */ a, /* Number, optional */ b, /* Number, optional */ c){
-			// summary: applies a matrix to a point
-			// matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
-			// a: Number: an x coordinate of a point
-			// b: Number: a y coordinate of a point
-			// c: Number: a z coordinate of a point
+		project: function(matrix, a, b, c){
+			// summary:
+			//		applies a matrix to a point
+			// matrix: dojox.gfx3d.matrix.Matrix3D
+			//		a 3D matrix object to be applied
+			// a: Number|Point
+			//		an x coordinate of a point, or an Object specifying the whole point
+			// b: Number?
+			//		a y coordinate of a point
+			// c: Number?
+			//		a z coordinate of a point
 			var m = gfx3d.matrix.normalize(matrix);
 			if(typeof a == "number" && typeof b == "number" && typeof c == "number"){
 				return gfx3d.matrix._project(m, a, b, c); // Object
 			}
-			// branch
-			// matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
-			// a: Object: a point
-			// b: null
-			// c: null
 			return gfx3d.matrix._project(m, a.x, a.y, a.z); // Object
 		}
 	});
diff --git a/dojox/gfx3d/object.js b/dojox/gfx3d/object.js
index 49014e7..9b78299 100644
--- a/dojox/gfx3d/object.js
+++ b/dojox/gfx3d/object.js
@@ -10,6 +10,7 @@ define([
 	"./vector",
 	"./matrix",
 	"./lighting"
+	/*===== , "dojox/gfx/shape" =====*/		// gfx.Surface
 ], function(arrayUtil,declare,lang,gfx,matrixUtil2d,gfx3d,schedulerExtensions,Gradient,VectorUtil,matrixUtil,lightUtil){
 
 var scheduler = schedulerExtensions.scheduler;
@@ -29,103 +30,133 @@ var out = function(o, x){
 
 declare("dojox.gfx3d.Object", null, {
 	constructor: function(){
-		// summary: a Object object, which knows how to map
-		// 3D objects to 2D shapes.
-
-		// object: Object: an abstract Object object
-		// (see dojox.gfx3d.defaultEdges,
-		// dojox.gfx3d.defaultTriangles,
-		// dojox.gfx3d.defaultQuads
-		// dojox.gfx3d.defaultOrbit
-		// dojox.gfx3d.defaultCube
-		// or dojox.gfx3d.defaultCylinder)
+		// summary:
+		//		a Object object, which knows how to map
+		//		3D objects to 2D shapes.
+
+		// object: Object
+		//		an abstract Object object
+		//		(see dojox.gfx3d.defaultEdges,
+		//		dojox.gfx3d.defaultTriangles,
+		//		dojox.gfx3d.defaultQuads
+		//		dojox.gfx3d.defaultOrbit
+		//		dojox.gfx3d.defaultCube
+		//		or dojox.gfx3d.defaultCylinder)
 		this.object = null;
 
-		// matrix: dojox.gfx3d.matrix: world transform
+		// matrix: dojox.gfx3d.matrix
+		//		world transform
 		this.matrix = null;
-		// cache: buffer for intermediate result, used late for draw()
+
+		// cache:
+		//		buffer for intermediate result, used late for draw()
 		this.cache = null;
-		// renderer: a reference for the Viewport
+
+		// renderer:
+		//		a reference for the Viewport
 		this.renderer = null;
-		// parent: a reference for parent, Scene or Viewport object
+
+		// parent:
+		//		a reference for parent, Scene or Viewport object
 		this.parent = null;
 
-		// strokeStyle: Object: a stroke object
+		// strokeStyle: Object
+		//		a stroke object
 		this.strokeStyle = null;
-		// fillStyle: Object: a fill object or texture object
+
+		// fillStyle: Object
+		//		a fill object or texture object
 		this.fillStyle = null;
-		// shape: dojox.gfx.Shape: an underlying 2D shape
+
+		// shape: dojox.gfx.Shape
+		//		an underlying 2D shape
 		this.shape = null;
 	},
 
 	setObject: function(newObject){
-		// summary: sets a Object object
-		// object: Object: an abstract Object object
-		// (see dojox.gfx3d.defaultEdges,
-		// dojox.gfx3d.defaultTriangles,
-		// dojox.gfx3d.defaultQuads
-		// dojox.gfx3d.defaultOrbit
-		// dojox.gfx3d.defaultCube
-		// or dojox.gfx3d.defaultCylinder)
+		// summary:
+		//		sets a Object object
+		// object: Object
+		//		an abstract Object object
+		//		(see dojox.gfx3d.defaultEdges,
+		//		dojox.gfx3d.defaultTriangles,
+		//		dojox.gfx3d.defaultQuads
+		//		dojox.gfx3d.defaultOrbit
+		//		dojox.gfx3d.defaultCube
+		//		or dojox.gfx3d.defaultCylinder)
 		this.object = gfx.makeParameters(this.object, newObject);
 		return this;
 	},
 
 	setTransform: function(matrix){
-		// summary: sets a transformation matrix
-		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx3d.matrix.Matrix
-		//	constructor for a list of acceptable arguments)
+		// summary:
+		//		sets a transformation matrix
+
+		// matrix: dojox.gfx3d.matrix.Matrix
+		//		a matrix or a matrix-like object
+		//		(see an argument of dojox.gfx3d.matrix.Matrix
+		//		constructor for a list of acceptable arguments)
 		this.matrix = matrixUtil.clone(matrix ? matrixUtil.normalize(matrix) : gfx3d.identity, true);
+
 		return this;	// self
 	},
 
 	// apply left & right transformation
 	
 	applyRightTransform: function(matrix){
-		// summary: multiplies the existing matrix with an argument on right side
-		//	(this.matrix * matrix)
-		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx.matrix.Matrix
-		//	constructor for a list of acceptable arguments)
+		// summary:
+		//		multiplies the existing matrix with an argument on right side
+		//		(this.matrix * matrix)
+		// matrix: dojox.gfx3d.matrix.Matrix
+		//		a matrix or a matrix-like object
+		//		(see an argument of dojox.gfx.matrix.Matrix
+		//		constructor for a list of acceptable arguments)
 		return matrix ? this.setTransform([this.matrix, matrix]) : this;	// self
 	},
 	applyLeftTransform: function(matrix){
-		// summary: multiplies the existing matrix with an argument on left side
-		//	(matrix * this.matrix)
-		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx.matrix.Matrix
-		//	constructor for a list of acceptable arguments)
+		// summary:
+		//		multiplies the existing matrix with an argument on left side
+		//		(matrix * this.matrix)
+		// matrix: dojox.gfx3d.matrix.Matrix
+		//		a matrix or a matrix-like object
+		//		(see an argument of dojox.gfx.matrix.Matrix
+		//		constructor for a list of acceptable arguments)
 		return matrix ? this.setTransform([matrix, this.matrix]) : this;	// self
 	},
 
 	applyTransform: function(matrix){
-		// summary: a shortcut for dojox.gfx.Shape.applyRightTransform
-		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx.matrix.Matrix
-		//	constructor for a list of acceptable arguments)
+		// summary:
+		//		a shortcut for dojox.gfx.Shape.applyRightTransform
+		// matrix: dojox.gfx3d.matrix.Matrix
+		//		a matrix or a matrix-like object
+		//		(see an argument of dojox.gfx.matrix.Matrix
+		//		constructor for a list of acceptable arguments)
 		return matrix ? this.setTransform([this.matrix, matrix]) : this;	// self
 	},
 	
 	setFill: function(fill){
-		// summary: sets a fill object
-		// (the default implementation is to delegate to
-		// the underlying 2D shape).
-		// fill: Object: a fill object
-		//	(see dojox.gfx.defaultLinearGradient,
-		//	dojox.gfx.defaultRadialGradient,
-		//	dojox.gfx.defaultPattern,
-		//	dojo.Color
-		//	or dojox.gfx.MODEL)
+		// summary:
+		//		sets a fill object
+		//		(the default implementation is to delegate to
+		//		the underlying 2D shape).
+		// fill: Object
+		//		a fill object
+		//		(see dojox.gfx.defaultLinearGradient,
+		//		dojox.gfx.defaultRadialGradient,
+		//		dojox.gfx.defaultPattern,
+		//		dojo.Color
+		//		or dojox.gfx.MODEL)
 		this.fillStyle = fill;
 		return this;
 	},
 
 	setStroke: function(stroke){
-		// summary: sets a stroke object
-		//	(the default implementation simply ignores it)
-		// stroke: Object: a stroke object
-		//	(see dojox.gfx.defaultStroke)
+		// summary:
+		//		sets a stroke object
+		//		(the default implementation simply ignores it)
+		// stroke: Object
+		//		a stroke object
+		//		(see dojox.gfx.defaultStroke)
 		this.strokeStyle = stroke;
 		return this;
 	},
@@ -172,12 +203,15 @@ declare("dojox.gfx3d.Object", null, {
 });
 
 declare("dojox.gfx3d.Scene", gfx3d.Object, {
-	// summary: the Scene is just a containter.
+	// summary:
+	//		the Scene is just a container.
+	
 	// note: we have the following assumption:
 	// all objects in the Scene are not overlapped with other objects
 	// outside of the scene.
 	constructor: function(){
-		// summary: a containter of other 3D objects
+		// summary:
+		//		a container of other 3D objects
 		this.objects= [];
 		this.todos = [];
 		this.schedule = scheduler.zOrder;
@@ -235,14 +269,14 @@ declare("dojox.gfx3d.Scene", gfx3d.Object, {
 
 declare("dojox.gfx3d.Edges", gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic edge in 3D viewport
+		// summary:
+		//		a generic edge in 3D viewport
 		this.object = lang.clone(gfx3d.defaultEdges);
 	},
 
-	setObject: function(newObject, /* String, optional */ style){
-		// summary: setup the object
-		// newObject: Array of points || Object
-		// style: String, optional
+	setObject: function(/*Points[]|Object*/ newObject, /*String?*/ style){
+		// summary:
+		//		setup the object
 		this.object = gfx.makeParameters(this.object, (newObject instanceof Array) ? { points: newObject, style: style } : newObject);
 		return this;
 	},
@@ -292,7 +326,8 @@ declare("dojox.gfx3d.Edges", gfx3d.Object, {
 
 declare("dojox.gfx3d.Orbit", gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic edge in 3D viewport
+		// summary:
+		//		a generic edge in 3D viewport
 		this.object = lang.clone(gfx3d.defaultOrbit);
 	},
 
@@ -319,8 +354,8 @@ declare("dojox.gfx3d.Orbit", gfx3d.Object, {
 		// http://www.3dsoftware.com/Math/PlaneCurves/EllipseAlgebra/
 		// After we normalize the marks, the equation is:
 		// a x^2 + 2b xy + cy^2 + f = 0: let a = 1
-		//  so the final equation is:
-		//  [ xy, y^2, 1] * [2b, c, f]' = [ -x^2 ]'
+		// so the final equation is:
+		//		[ xy, y^2, 1] * [2b, c, f]' = [ -x^2 ]'
 
 		var A = {
 			xx: marks[0].x * marks[0].y, xy: marks[0].y * marks[0].y, xz: 1,
@@ -374,7 +409,9 @@ declare("dojox.gfx3d.Orbit", gfx3d.Object, {
 declare("dojox.gfx3d.Path3d", gfx3d.Object, {
 	// This object is still very immature !
 	constructor: function(){
-		// summary: a generic line
+		// summary:
+		//		a generic line
+
 		//	(this is a helper object, which is defined for convenience)
 		this.object = lang.clone(gfx3d.defaultPath3d);
 		this.segments = [];
@@ -384,9 +421,12 @@ declare("dojox.gfx3d.Path3d", gfx3d.Object, {
 	},
 
 	_collectArgs: function(array, args){
-		// summary: converts an array of arguments to plain numeric values
-		// array: Array: an output argument (array of numbers)
-		// args: Array: an input argument (can be values of Boolean, Number, dojox.gfx.Point, or an embedded array of them)
+		// summary:
+		//		converts an array of arguments to plain numeric values
+		// array: Array
+		//		an output argument (array of numbers)
+		// args: Array
+		//		an input argument (can be values of Boolean, Number, dojox.gfx.Point, or an embedded array of them)
 		for(var i = 0; i < args.length; ++i){
 			var t = args[i];
 			if(typeof(t) == "boolean"){
@@ -406,9 +446,12 @@ declare("dojox.gfx3d.Path3d", gfx3d.Object, {
 	_validSegments: {m: 3, l: 3,  z: 0},
 
 	_pushSegment: function(action, args){
-		// summary: adds a segment
-		// action: String: valid SVG code for a segment's type
-		// args: Array: a list of parameters for this segment
+		// summary:
+		//		adds a segment
+		// action: String
+		//		valid SVG code for a segment's type
+		// args: Array
+		//		a list of parameters for this segment
 		var group = this._validSegments[action.toLowerCase()], segment;
 		if(typeof(group) == "number"){
 			if(group){
@@ -424,14 +467,16 @@ declare("dojox.gfx3d.Path3d", gfx3d.Object, {
 	},
 
 	moveTo: function(){
-		// summary: formes a move segment
+		// summary:
+		//		forms a move segment
 		var args = [];
 		this._collectArgs(args, arguments);
 		this._pushSegment(this.absolute ? "M" : "m", args);
 		return this; // self
 	},
 	lineTo: function(){
-		// summary: formes a line segment
+		// summary:
+		//		forms a line segment
 		var args = [];
 		this._collectArgs(args, arguments);
 		this._pushSegment(this.absolute ? "L" : "l", args);
@@ -439,7 +484,8 @@ declare("dojox.gfx3d.Path3d", gfx3d.Object, {
 	},
 
 	closePath: function(){
-		// summary: closes a path
+		// summary:
+		//		closes a path
 		this._pushSegment("Z", []);
 		return this; // self
 	},
@@ -449,7 +495,7 @@ declare("dojox.gfx3d.Path3d", gfx3d.Object, {
 		var m = matrixUtil.multiply(camera, this.matrix);
 		// iterate all the segments and convert them to 2D canvas
 		// TODO consider the relative mode
-		var path = ""
+		var path = "";
 		var _validSegments = this._validSegments;
 		arrayUtil.forEach(this.segments, function(item){
 			path += item.action;
@@ -469,15 +515,16 @@ declare("dojox.gfx3d.Path3d", gfx3d.Object, {
 
 declare("dojox.gfx3d.Triangles", gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic triangle
+		// summary:
+		//		a generic triangle
+
 		//	(this is a helper object, which is defined for convenience)
 		this.object = lang.clone(gfx3d.defaultTriangles);
 	},
 
-	setObject: function(newObject, /* String, optional */ style){
-		// summary: setup the object
-		// newObject: Array of points || Object
-		// style: String, optional
+	setObject: function(/*Points[]|Object*/ newObject, /*String?*/ style){
+		// summary:
+		//		setup the object
 		if(newObject instanceof Array){
 			this.object = gfx.makeParameters(this.object, { points: newObject, style: style } );
 		} else {
@@ -540,15 +587,16 @@ declare("dojox.gfx3d.Triangles", gfx3d.Object, {
 
 declare("dojox.gfx3d.Quads", gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic triangle
+		// summary:
+		//		a generic quad
+
 		//	(this is a helper object, which is defined for convenience)
 		this.object = lang.clone(gfx3d.defaultQuads);
 	},
 
-	setObject: function(newObject, /* String, optional */ style){
-		// summary: setup the object
-		// newObject: Array of points || Object
-		// style: String, optional
+	setObject: function(/*Points[]|Object*/ newObject, /*String?*/ style){
+		// summary:
+		//		setup the object
 		this.object = gfx.makeParameters(this.object, (newObject instanceof Array) ? 
 			{ points: newObject, style: style } 
 				: newObject );
@@ -616,14 +664,16 @@ declare("dojox.gfx3d.Quads", gfx3d.Object, {
 
 declare("dojox.gfx3d.Polygon", gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic triangle
+		// summary:
+		//		a generic polygon
+
 		//	(this is a helper object, which is defined for convenience)
 		this.object = lang.clone(gfx3d.defaultPolygon);
 	},
 
-	setObject: function(newObject){
-		// summary: setup the object
-		// newObject: Array of points || Object
+	setObject: function(/*Points[]|Object*/ newObject){
+		// summary:
+		//		setup the object
 		this.object = gfx.makeParameters(this.object, (newObject instanceof Array) ? {path: newObject} : newObject)
 		return this;
 	},
@@ -664,15 +714,17 @@ declare("dojox.gfx3d.Polygon", gfx3d.Object, {
 
 declare("dojox.gfx3d.Cube", gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic triangle
+		// summary:
+		//		a generic cube
+
 		//	(this is a helper object, which is defined for convenience)
 		this.object = lang.clone(gfx3d.defaultCube);
 		this.polygons = [];
 	},
 
-	setObject: function(newObject){
-		// summary: setup the object
-		// newObject: Array of points || Object
+	setObject: function(/*Points[]|Object*/ newObject){
+		// summary:
+		//		setup the object
 		this.object = gfx.makeParameters(this.object, newObject);
 	},
 
@@ -751,8 +803,8 @@ declare("dojox.gfx3d.Cylinder", gfx3d.Object, {
 		// http://www.3dsoftware.com/Math/PlaneCurves/EllipseAlgebra/
 		// After we normalize the marks, the equation is:
 		// a x^2 + 2b xy + cy^2 + f = 0: let a = 1
-		//  so the final equation is:
-		//  [ xy, y^2, 1] * [2b, c, f]' = [ -x^2 ]'
+		// so the final equation is:
+		//		[ xy, y^2, 1] * [2b, c, f]' = [ -x^2 ]'
 
 		var A = {
 			xx: marks[0].x * marks[0].y, xy: marks[0].y * marks[0].y, xz: 1,
@@ -845,16 +897,22 @@ declare("dojox.gfx3d.Cylinder", gfx3d.Object, {
 // the ultimate container of 3D world
 declare("dojox.gfx3d.Viewport", gfx.Group, {
 	constructor: function(){
-		// summary: a viewport/container for 3D objects, which knows
-		// the camera and lightings
+		// summary:
+		//		a viewport/container for 3D objects, which knows
+		//		the camera and lightings
 
-		// matrix: dojox.gfx3d.matrix: world transform
-		// dimension: Object: the dimension of the canvas
+		// matrix: dojox.gfx3d.matrix
+		//		world transform
+
+		// dimension: Object
+		//		the dimension of the canvas
 		this.dimension = null;
 
-		// objects: Array: all 3d Objects
+		// objects: Array
+		//		all 3d Objects
 		this.objects = [];
-		// todos: Array: all 3d Objects that needs to redraw
+		// todos: Array
+		//		all 3d Objects that needs to redraw
 		this.todos = [];
 
 		// FIXME: memory leak?
@@ -865,54 +923,67 @@ declare("dojox.gfx3d.Viewport", gfx.Group, {
 		// deep: boolean, true means the whole viewport needs to re-render, redraw
 		this.deep = false;
 
-		// lights: Array: an array of light objects
+		// lights: Array
+		//		an array of light objects
 		this.lights = [];
 		this.lighting = null;
 	},
 
 	setCameraTransform: function(matrix){
-		// summary: sets a transformation matrix
-		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx.matrix.Matrix
-		//	constructor for a list of acceptable arguments)
+		// summary:
+		//		sets a transformation matrix
+		// matrix: dojox.gfx3d.matrix.Matrix
+		//		a matrix or a matrix-like object
+		//		(see an argument of dojox.gfx.matrix.Matrix
+		//		constructor for a list of acceptable arguments)
 		this.camera = matrixUtil.clone(matrix ? matrixUtil.normalize(matrix) : gfx3d.identity, true);
 		this.invalidate();
 		return this;	// self
 	},
 
 	applyCameraRightTransform: function(matrix){
-		// summary: multiplies the existing matrix with an argument on right side
-		//	(this.matrix * matrix)
-		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx3d.matrix.Matrix
-		//	constructor for a list of acceptable arguments)
+		// summary:
+		//		multiplies the existing matrix with an argument on right side
+		//		(this.matrix * matrix)
+		// matrix: dojox.gfx3d.matrix.Matrix
+		//		a matrix or a matrix-like object
+		//		(see an argument of dojox.gfx3d.matrix.Matrix
+		//		constructor for a list of acceptable arguments)
 		return matrix ? this.setCameraTransform([this.camera, matrix]) : this;	// self
 	},
 
 	applyCameraLeftTransform: function(matrix){
-		// summary: multiplies the existing matrix with an argument on left side
-		//	(matrix * this.matrix)
-		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx3d.matrix.Matrix
-		//	constructor for a list of acceptable arguments)
+		// summary:
+		//		multiplies the existing matrix with an argument on left side
+		//		(matrix * this.matrix)
+		// matrix: dojox.gfx3d.matrix.Matrix
+		//		a matrix or a matrix-like object
+		//		(see an argument of dojox.gfx3d.matrix.Matrix
+		//		constructor for a list of acceptable arguments)
 		return matrix ? this.setCameraTransform([matrix, this.camera]) : this;	// self
 	},
 
 	applyCameraTransform: function(matrix){
-		// summary: a shortcut for dojox.gfx3d.Object.applyRightTransform
-		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx3d.matrix.Matrix
-		//	constructor for a list of acceptable arguments)
+		// summary:
+		//		a shortcut for dojox.gfx3d.Object.applyRightTransform
+		// matrix: dojox.gfx3d.matrix.Matrix
+		//		a matrix or a matrix-like object
+		//		(see an argument of dojox.gfx3d.matrix.Matrix
+		//		constructor for a list of acceptable arguments)
 		return this.applyCameraRightTransform(matrix); // self
 	},
 
-	setLights: function(/* Array || Object */lights, /* Color, optional */ ambient,
-		/* Color, optional */ specular){
-		// summary: set the lights
-		// lights: Array: an array of light object
-		// or lights object
-		// ambient: Color: an ambient object
-		// specular: Color: an specular object
+	setLights: function(/* Array|Object */lights, /* Color? */ ambient,
+		/* Color? */ specular){
+		// summary:
+		//		set the lights
+		// lights: Array
+		//		an array of light object
+		//		or lights object
+		// ambient: Color
+		//		an ambient object
+		// specular: Color
+		//		an specular object
 		this.lights = (lights instanceof Array) ? 
 			{sources: lights, ambient: ambient, specular: specular}
 				: lights;
@@ -925,8 +996,10 @@ declare("dojox.gfx3d.Viewport", gfx.Group, {
 	},
 
 	addLights: function(lights){
-		// summary: add new light/lights to the viewport.
-		// lights: Array || light object: light object(s)
+		// summary:
+		//		add new light/lights to the viewport.
+		// lights: Array|Object
+		//		light object(s)
 		return this.setLights(this.lights.sources.concat(lights));
 	},
 
@@ -956,8 +1029,14 @@ declare("dojox.gfx3d.Viewport", gfx.Group, {
 			// there is no rawNode in canvas GFX implementation
 			if(this.rawNode){
 				var trs = this.rawNode.style;
-				trs.height = h;
-				trs.width = w;
+				if(trs){
+					trs.height = h;
+					trs.width = w;
+				}else{
+					// silverlight
+					this.rawNode.width = w;
+					this.rawNode.height = h;
+				}
 			}
 			this.dimension = {
 				width:  w,
@@ -969,7 +1048,8 @@ declare("dojox.gfx3d.Viewport", gfx.Group, {
 	},
 
 	render: function(){
-		// summary: iterate all children and call their render callback function.
+		// summary:
+		//		iterate all children and call their render callback function.
 		if(!this.todos.length){ return; }
 		// console.debug("Viewport::render");
 		var m = matrixUtil;
@@ -995,61 +1075,65 @@ declare("dojox.gfx3d.Viewport", gfx.Group, {
 gfx3d.Viewport.nodeType = gfx.Group.nodeType;
 
 gfx3d._creators = {
-	// summary: object creators
+	// summary:
+	//		object creators
 	createEdges: function(edges, style){
-		// summary: creates an edge object
-		// line: Object: a edge object (see dojox.gfx3d.defaultPath)
+		// summary:
+		//		creates an edge object
 		return this.create3DObject(gfx3d.Edges, edges, style);	// dojox.gfx3d.Edge
 	},
 	createTriangles: function(tris, style){
-		// summary: creates an edge object
-		// line: Object: a edge object (see dojox.gfx3d.defaultPath)
+		// summary:
+		//		creates an triangle object
 		return this.create3DObject(gfx3d.Triangles, tris, style);	// dojox.gfx3d.Edge
 	},
 	createQuads: function(quads, style){
-		// summary: creates an edge object
-		// line: Object: a edge object (see dojox.gfx3d.defaultPath)
+		// summary:
+		//		creates an quads object
 		return this.create3DObject(gfx3d.Quads, quads, style);	// dojox.gfx3d.Edge
 	},
-	createPolygon: function(points){
-		// summary: creates an triangle object
-		// points: Array of points || Object
+	createPolygon: function(/*Points[]|Object*/ points){
+		// summary:
+		//		creates an polygon object
 		return this.create3DObject(gfx3d.Polygon, points);	// dojox.gfx3d.Polygon
 	},
 
 	createOrbit: function(orbit){
-		// summary: creates an triangle object
-		// points: Array of points || Object
+		// summary:
+		//		creates an Orbit object
 		return this.create3DObject(gfx3d.Orbit, orbit);	// dojox.gfx3d.Cube
 	},
 
 	createCube: function(cube){
-		// summary: creates an triangle object
-		// points: Array of points || Object
+		// summary:
+		//		creates an cube object
 		return this.create3DObject(gfx3d.Cube, cube);	// dojox.gfx3d.Cube
 	},
 
 	createCylinder: function(cylinder){
-		// summary: creates an triangle object
-		// points: Array of points || Object
+		// summary:
+		//		creates an cylinder object
 		return this.create3DObject(gfx3d.Cylinder, cylinder);	// dojox.gfx3d.Cube
 	},
 
 	createPath3d: function(path){
-		// summary: creates an edge object
-		// line: Object: a edge object (see dojox.gfx3d.defaultPath)
+		// summary:
+		//		creates an 3d path object
 		return this.create3DObject(gfx3d.Path3d, path);	// dojox.gfx3d.Edge
 	},
 	createScene: function(){
-		// summary: creates an triangle object
-		// line: Object: a triangle object (see dojox.gfx3d.defaultPath)
+		// summary:
+		//		creates a scene object
 		return this.create3DObject(gfx3d.Scene);	// dojox.gfx3d.Scene
 	},
 
 	create3DObject: function(objectType, rawObject, style){
-		// summary: creates an instance of the passed shapeType class
-		// shapeType: Function: a class constructor to create an instance of
-		// rawShape: Object: properties to be passed in to the classes "setShape" method
+		// summary:
+		//		creates an instance of the passed objectType class
+		// objectType: Function
+		//		a class constructor to create an instance of
+		// rawObject: Object
+		//		properties to be passed in to the classes "setShape" method
 		var obj = new objectType();
 		this.adopt(obj);
 		if(rawObject){ obj.setObject(rawObject, style); }
@@ -1057,8 +1141,8 @@ gfx3d._creators = {
 	},
 	// todo : override the add/remove if necessary
 	adopt: function(obj){
-		// summary: adds a shape to the list
-		// shape: dojox.gfx.Shape: a shape
+		// summary:
+		//		adds a shape to the list
 		obj.renderer = this.renderer; // obj._setParent(this, null); more TODOs HERER?
 		obj.parent = this;
 		this.objects.push(obj);
@@ -1066,8 +1150,10 @@ gfx3d._creators = {
 		return this;
 	},
 	abandon: function(obj, silently){
-		// summary: removes a shape from the list
-		// silently: Boolean?: if true, do not redraw a picture yet
+		// summary:
+		//		removes a shape from the list
+		// silently: Boolean?
+		//		if true, do not redraw a picture yet
 		for(var i = 0; i < this.objects.length; ++i){
 			if(this.objects[i] == obj){
 				this.objects.splice(i, 1);
diff --git a/dojox/gfx3d/scheduler.js b/dojox/gfx3d/scheduler.js
index 06edffc..ea1a663 100644
--- a/dojox/gfx3d/scheduler.js
+++ b/dojox/gfx3d/scheduler.js
@@ -1,7 +1,7 @@
 define([
 	"dojo/_base/lang",
 	"dojo/_base/array",	// dojo.forEach, dojo.every
-	"dojo/_base/declare",	// dojo.declare
+	"dojo/_base/declare",	// declare
 	"./_base",
 	"./vector"
 ], function(lang, arrayUtil, declare, gfx3d, vectorUtil){
@@ -35,18 +35,18 @@ gfx3d.scheduler = {
 
 var BST = declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
 	constructor: function(obj, outline){
-		// summary: build the binary search tree, using binary space partition algorithm.
-		// The idea is for any polygon, for example, (a, b, c), the space is divided by
-		// the plane into two space: plus and minus.
-		//
-		// for any arbitary vertex p, if(p - a) dotProduct n = 0, p is inside the plane,
-		// > 0, p is in the plus space, vice versa for minus space.
-		// n is the normal vector that is perpendicular the plate, defined as:
-		//            n = ( b - a) crossProduct ( c - a )
-		//
-		// in this implementation, n is declared as normal, ,a is declared as orient.
-		//
-		// obj: object: dojox.gfx3d.Object
+		// summary:
+		//		build the binary search tree, using binary space partition algorithm.
+		//		The idea is for any polygon, for example, (a, b, c), the space is divided by
+		//		the plane into two space: plus and minus.
+		//		
+		//		for any arbitrary vertex p, if(p - a) dotProduct n = 0, p is inside the plane,
+		//		> 0, p is in the plus space, vice versa for minus space.
+		//		n is the normal vector that is perpendicular the plate, defined as:
+		// |		n = ( b - a) crossProduct ( c - a )
+		//		
+		//		in this implementation, n is declared as normal, ,a is declared as orient.
+		// obj: dojox.gfx3d.Object
 		this.plus = null;
 		this.minus = null;
 		this.object = obj;
@@ -140,7 +140,7 @@ gfx3d.drawer = {
 			item.draw(viewport.lighting);
 		});
 	}
-	// More aggrasive optimization may re-order the DOM nodes using the order
+	// More aggressive optimization may re-order the DOM nodes using the order
 	// of objects, and only elements of todos call setShape.
 };
 
diff --git a/dojox/gfx3d/tests/test_camerarotate.html b/dojox/gfx3d/tests/test_camerarotate.html
index cc6dee3..cdca5f9 100644
--- a/dojox/gfx3d/tests/test_camerarotate.html
+++ b/dojox/gfx3d/tests/test_camerarotate.html
@@ -7,7 +7,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 	@import "../../../dijit/themes/tundra/tundra.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: false"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: false"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_camerarotate_shaded.html b/dojox/gfx3d/tests/test_camerarotate_shaded.html
index fad5dbe..0f5aae8 100644
--- a/dojox/gfx3d/tests/test_camerarotate_shaded.html
+++ b/dojox/gfx3d/tests/test_camerarotate_shaded.html
@@ -7,7 +7,7 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 		@import "../../../dijit/themes/tundra/tundra.css";
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: false"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: false"></script>
 	<script type="text/javascript">
 
 		dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_cube.html b/dojox/gfx3d/tests/test_cube.html
index f5f1674..cc947f1 100644
--- a/dojox/gfx3d/tests/test_cube.html
+++ b/dojox/gfx3d/tests/test_cube.html
@@ -10,7 +10,7 @@
 The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
 <script type="text/javascript" src="Silverlight.js"></script>
 -->
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 dojo.require("dojox.gfx3d");
 dojo.require("dojox.gfx.utils");
diff --git a/dojox/gfx3d/tests/test_cylinder.html b/dojox/gfx3d/tests/test_cylinder.html
index d6edbb5..e62e9f8 100644
--- a/dojox/gfx3d/tests/test_cylinder.html
+++ b/dojox/gfx3d/tests/test_cylinder.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 
 <script type="text/javascript">
 
diff --git a/dojox/gfx3d/tests/test_drawer.html b/dojox/gfx3d/tests/test_drawer.html
index 3a9af1f..2bfefe5 100644
--- a/dojox/gfx3d/tests/test_drawer.html
+++ b/dojox/gfx3d/tests/test_drawer.html
@@ -7,7 +7,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 	@import "../../../dijit/themes/tundra/tundra.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_edges.html b/dojox/gfx3d/tests/test_edges.html
index 07b78f0..1f33530 100644
--- a/dojox/gfx3d/tests/test_edges.html
+++ b/dojox/gfx3d/tests/test_edges.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_matrix.html b/dojox/gfx3d/tests/test_matrix.html
index 9acf399..db85597 100644
--- a/dojox/gfx3d/tests/test_matrix.html
+++ b/dojox/gfx3d/tests/test_matrix.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_orbit.html b/dojox/gfx3d/tests/test_orbit.html
index cadc043..313890e 100644
--- a/dojox/gfx3d/tests/test_orbit.html
+++ b/dojox/gfx3d/tests/test_orbit.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_overlap.html b/dojox/gfx3d/tests/test_overlap.html
index 19f63d5..e0ca85b 100644
--- a/dojox/gfx3d/tests/test_overlap.html
+++ b/dojox/gfx3d/tests/test_overlap.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_polygon.html b/dojox/gfx3d/tests/test_polygon.html
index ab9f174..9c2fe72 100644
--- a/dojox/gfx3d/tests/test_polygon.html
+++ b/dojox/gfx3d/tests/test_polygon.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_quads.html b/dojox/gfx3d/tests/test_quads.html
index aff3b3b..5fb8a04 100644
--- a/dojox/gfx3d/tests/test_quads.html
+++ b/dojox/gfx3d/tests/test_quads.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_rotate.html b/dojox/gfx3d/tests/test_rotate.html
index 5997275..2b8b12f 100644
--- a/dojox/gfx3d/tests/test_rotate.html
+++ b/dojox/gfx3d/tests/test_rotate.html
@@ -7,7 +7,7 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 	@import "../../../dijit/themes/tundra/tundra.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_scene.html b/dojox/gfx3d/tests/test_scene.html
index 231b289..3ace066 100644
--- a/dojox/gfx3d/tests/test_scene.html
+++ b/dojox/gfx3d/tests/test_scene.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_triangles.html b/dojox/gfx3d/tests/test_triangles.html
index cc4e65b..281da08 100644
--- a/dojox/gfx3d/tests/test_triangles.html
+++ b/dojox/gfx3d/tests/test_triangles.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d");
diff --git a/dojox/gfx3d/tests/test_vector.html b/dojox/gfx3d/tests/test_vector.html
index 371d57e..f8604c4 100644
--- a/dojox/gfx3d/tests/test_vector.html
+++ b/dojox/gfx3d/tests/test_vector.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.gfx3d.vector");
diff --git a/dojox/gfx3d/vector.js b/dojox/gfx3d/vector.js
index 0a5609a..841d54e 100644
--- a/dojox/gfx3d/vector.js
+++ b/dojox/gfx3d/vector.js
@@ -3,14 +3,16 @@ define(["dojo/_base/lang", "dojo/_base/array", "./_base"],function(lang, arrayUt
 gfx3d.vector =  {
 	
 	sum: function(){
-		// summary: sum of the vectors
+		// summary:
+		//		sum of the vectors
 		var v = {x: 0, y: 0, z:0};
 		arrayUtil.forEach(arguments, function(item){ v.x += item.x; v.y += item.y; v.z += item.z; });
 		return v;
 	},
 
 	center: function(){
-		// summary: center of the vectors
+		// summary:
+		//		center of the vectors
 		var l = arguments.length;
 		if(l == 0){
 			return {x: 0, y: 0, z: 0};
@@ -24,75 +26,96 @@ gfx3d.vector =  {
 	},
 
 	_crossProduct: function(x, y, z, u, v, w){
-		// summary: applies a cross product of two vectorss, (x, y, z) and (u, v, w)
-		// x: Number: an x coordinate of a point
-		// y: Number: a y coordinate of a point
-		// z: Number: a z coordinate of a point
-		// u: Number: an x coordinate of a point
-		// v: Number: a y coordinate of a point
-		// w: Number: a z coordinate of a point
+		// summary:
+		//		applies a cross product of two vectors, (x, y, z) and (u, v, w)
+		// x: Number
+		//		x coordinate of first vector
+		// y: Number
+		//		y coordinate of first vector
+		// z: Number
+		//		z coordinate of first vector
+		// u: Number
+		//		x coordinate of second vector
+		// v: Number
+		//		y coordinate of second vector
+		// w: Number
+		//		z coordinate of second vector
 		return {x: y * w - z * v, y: z * u - x * w, z: x * v - y * u}; // Object
 	},
 
 	crossProduct: function(/* Number||Point */ a, /* Number||Point */ b, /* Number, optional */ c, /* Number, optional */ d, /* Number, optional */ e, /* Number, optional */ f){
-		// summary: applies a matrix to a point
-		// matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
-		// a: Number: an x coordinate of a point
-		// b: Number: a y coordinate of a point
-		// c: Number: a z coordinate of a point
-		// d: Number: an x coordinate of a point
-		// e: Number: a y coordinate of a point
-		// f: Number: a z coordinate of a point
+		// summary:
+		//		applies a matrix to a point
+		// matrix: dojox.gfx3d.matrix.Matrix3D
+		//		a 3D matrix object to be applied
+		// a: Number|Point
+		//		x coordinate of first point, or the whole first point
+		// b: Number|Point
+		//		y coordinate of first point, or the whole second point
+		// c: Number
+		//		z coordinate of first point
+		// d: Number
+		//		x coordinate of second point
+		// e: Number
+		//		y coordinate of second point
+		// f: Number
+		//		z coordinate of second point
 		if(arguments.length == 6 && arrayUtil.every(arguments, function(item){ return typeof item == "number"; })){
 			return gfx3d.vector._crossProduct(a, b, c, d, e, f); // Object
 		}
-		// branch
-		// a: Object: a point
-		// b: Object: a point
-		// c: null
-		// d: null
-		// e: null
-		// f: null
+
 		return gfx3d.vector._crossProduct(a.x, a.y, a.z, b.x, b.y, b.z); // Object
 	},
 
 	_dotProduct: function(x, y, z, u, v, w){
-		// summary: applies a cross product of two vectorss, (x, y, z) and (u, v, w)
-		// x: Number: an x coordinate of a point
-		// y: Number: a y coordinate of a point
-		// z: Number: a z coordinate of a point
-		// u: Number: an x coordinate of a point
-		// v: Number: a y coordinate of a point
-		// w: Number: a z coordinate of a point
+		// summary:
+		//		applies a cross product of two vectors, (x, y, z) and (u, v, w)
+		// x: Number
+		//		x coordinate of first point
+		// y: Number
+		//		y coordinate of first point
+		// z: Number
+		//		z coordinate of first point
+		// u: Number
+		//		x coordinate of second point
+		// v: Number
+		//		y coordinate of second point
+		// w: Number
+		//		z coordinate of second point
 		return x * u + y * v + z * w; // Number
 	},
-	dotProduct: function(/* Number||Point */ a, /* Number||Point */ b, /* Number, optional */ c, /* Number, optional */ d, /* Number, optional */ e, /* Number, optional */ f){
-		// summary: applies a matrix to a point
-		// matrix: dojox.gfx3d.matrix.Matrix3D: a 3D matrix object to be applied
-		// a: Number: an x coordinate of a point
-		// b: Number: a y coordinate of a point
-		// c: Number: a z coordinate of a point
-		// d: Number: an x coordinate of a point
-		// e: Number: a y coordinate of a point
-		// f: Number: a z coordinate of a point
+	dotProduct: function(a, b, c, d, e, f){
+		// summary:
+		//		applies a matrix to a point
+		// matrix: dojox.gfx3d.matrix.Matrix3D
+		//		a 3D matrix object to be applied
+		// a: Number|Point
+		//		x coordinate of first point, or the whole first Point
+		// b: Number|Point
+		//		y coordinate of first Point, or the whole second Point
+		// c: Number?
+		//		z coordinate of first point
+		// d: Number?
+		//		x coordinate of second point
+		// e: Number?
+		//		y coordinate of second point
+		// f: Number?
+		//		z coordinate of second point
 		if(arguments.length == 6 && arrayUtil.every(arguments, function(item){ return typeof item == "number"; })){
 			return gfx3d.vector._dotProduct(a, b, c, d, e, f); // Object
 		}
-		// branch
-		// a: Object: a point
-		// b: Object: a point
-		// c: null
-		// d: null
-		// e: null
-		// f: null
 		return gfx3d.vector._dotProduct(a.x, a.y, a.z, b.x, b.y, b.z); // Object
 	},
 
 	normalize: function(/* Point||Array*/ a, /* Point */ b, /* Point */ c){
-		// summary: find the normal of the implicit surface
-		// a: Object: a point
-		// b: Object: a point
-		// c: Object: a point
+		// summary:
+		//		find the normal of the implicit surface
+		// a: Object
+		//		a point
+		// b: Object
+		//		a point
+		// c: Object
+		//		a point
 		var l, m, n;
 		if(a instanceof Array){
 			l = a[0]; m = a[1]; n = a[2];
diff --git a/dojox/grid/BidiSupport.js b/dojox/grid/BidiSupport.js
new file mode 100644
index 0000000..525a0fc
--- /dev/null
+++ b/dojox/grid/BidiSupport.js
@@ -0,0 +1,4 @@
+define(["dojo/_base/kernel", "./bidi/_BidiMixin"],
+function(kernel){
+		kernel.deprecated('dojox.grid.BidiSupport is deprecated,', 'set "has: {\'dojo-bidi\': true }" in data-dojo-config to enable bidi support');
+});
diff --git a/dojox/grid/DataGrid.js b/dojox/grid/DataGrid.js
index f67c6c5..7a1e51e 100644
--- a/dojox/grid/DataGrid.js
+++ b/dojox/grid/DataGrid.js
@@ -7,17 +7,19 @@ define([
 	"dojo/_base/declare",
 	"./_Grid",
 	"./DataSelection",
-	"dojo/_base/html"
+	"dojo/_base/html",
+	"dojo/has",
+	"dojo/has!dojo-bidi?./bidi/_BidiMixin"
 ], function(dojox, array, lang, json, has, declare, _Grid, DataSelection, html){
 
 /*=====
 declare("dojox.grid.__DataCellDef", dojox.grid.__CellDef, {
 	constructor: function(){
-		//	field: String?
+		// field: String?
 		//		The attribute to read from the dojo.data item for the row.
-		//  fields: String[]?
+		// fields: String[]?
 		//		An array of fields to grab the values of and pass as an array to the grid
-		//	get: Function?
+		// get: Function?
 		//		function(rowIndex, item?){} rowIndex is of type Integer, item is of type
 		//		Object.  This function will be called when a cell requests data.  Returns
 		//		the unformatted data for the cell.
@@ -28,9 +30,9 @@ declare("dojox.grid.__DataCellDef", dojox.grid.__CellDef, {
 /*=====
 declare("dojox.grid.__DataViewDef", dojox.grid.__ViewDef, {
 	constructor: function(){
-		//	cells: dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]?
+		// cells: dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]?
 		//		The structure of the cells within this grid.
-		//	defaultCell: dojox.grid.__DataCellDef?
+		// defaultCell: dojox.grid.__DataCellDef?
 		//		A cell definition with default values for all cells in this view.  If
 		//		a property is defined in a cell definition in the "cells" array and
 		//		this property, the cell definition's property will override this
@@ -55,7 +57,7 @@ var DataGrid = declare("dojox.grid.DataGrid", _Grid, {
 
 /*=====
 	// structure: dojox.grid.__DataViewDef|dojox.grid.__DataViewDef[]|dojox.grid.__DataCellDef[]|Array[dojox.grid.__DataCellDef[]]
-	//		View layout defintion.
+	//		View layout definition.
 	structure: '',
 =====*/
 
@@ -77,7 +79,7 @@ var DataGrid = declare("dojox.grid.DataGrid", _Grid, {
 	_isLoaded: false,
 	_isLoading: false,
 	
-	//keepSelection: Boolean
+	// keepSelection: Boolean
 	//		Whether keep selection after sort, filter etc.
 	keepSelection: false,	
 	
@@ -103,7 +105,8 @@ var DataGrid = declare("dojox.grid.DataGrid", _Grid, {
 	},
 
 	get: function(inRowIndex, inItem){
-		// summary: Default data getter.
+		// summary:
+		//		Default data getter.
 		// description:
 		//		Provides data to display in a grid cell. Called in grid cell context.
 		//		So this.cell.index is the column index.
@@ -534,7 +537,8 @@ var DataGrid = declare("dojox.grid.DataGrid", _Grid, {
 	},
 
 	styleRowState: function(inRow){
-		// summary: Perform row styling
+		// summary:
+		//		Perform row styling
 		if(this.store && this.store.getState){
 			var states=this.store.getState(inRow.index), c='';
 			for(var i=0, ss=["inflight", "error", "inserting"], s; s=ss[i]; i++){
@@ -656,4 +660,4 @@ DataGrid.markupFactory = function(props, node, ctor, cellFunc){
 
 return DataGrid;
 
-});
\ No newline at end of file
+});
diff --git a/dojox/grid/EnhancedGrid.js b/dojox/grid/EnhancedGrid.js
index e8984e4..789230f 100644
--- a/dojox/grid/EnhancedGrid.js
+++ b/dojox/grid/EnhancedGrid.js
@@ -7,14 +7,13 @@ define([
 	"dojo/_base/sniff",
 	"dojo/dom",
 	"dojo/dom-geometry",
-	"dojo/i18n",
 	"./DataGrid",
 	"./DataSelection",
 	"./enhanced/_PluginManager",
 	"./enhanced/plugins/_SelectionPreserver",//default loaded plugin
 	"dojo/i18n!./enhanced/nls/EnhancedGrid"
-], function(dojo, dojox, declare, lang, array, has, dom, domGeometry, i18n,
-	DataGrid, DataSelection, _PluginManager, _SelectionPreserver){
+], function(dojo, dojox, declare, lang, array, has, dom, domGeometry,
+	DataGrid, DataSelection, _PluginManager, _SelectionPreserver, nls){
 
 dojo.experimental("dojox.grid.EnhancedGrid");
 
@@ -39,7 +38,9 @@ var EnhancedGrid = declare("dojox.grid.EnhancedGrid", DataGrid, {
 	// |	</script>
 	//
 	//		Step 2. Use EnhancedGrid
+	//
 	//		- Via HTML markup
+	//
 	// |	<div dojoType="dojox.grid.EnhancedGrid" ...
 	// |		plugins="{nestedSorting: true, dnd: true, indirectSelection: true,
 	// |		menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
@@ -48,6 +49,7 @@ var EnhancedGrid = declare("dojox.grid.EnhancedGrid", DataGrid, {
 	// |	</div>
 	//
 	//		- Or via JavaScript
+	//
 	// |	<script type="text/javascript">
 	// |		var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true, dnd: true, indirectSelection: true,
 	// |	               menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",selectedRegionMenu:"selectedRegionMenuId"}},
@@ -60,25 +62,25 @@ var EnhancedGrid = declare("dojox.grid.EnhancedGrid", DataGrid, {
 	//		[Note: Plugin support is still experimental]
 	//
 	//		You can either customize the default plugins or add new ones, more details please see
+	//
 	//		- dojox.grid.enhanced._PluginManager
 	//		- dojox.grid.enhanced._Plugin
 	//		- dojox.grid.enhanced.plugins.*
 
-	//plugins: Object
+	// plugins: Object
 	//		Plugin properties, e.g. {nestedSorting: true, dnd: true, ...}
 	plugins: null,
 
-	//pluginMgr: Object
+	// pluginMgr: Object
 	//		Singleton plugin manager
 	pluginMgr: null,
 
-	//_pluginMgrClass: Object
+	// _pluginMgrClass: Object
 	//		Default plugin manager class
 	_pluginMgrClass: _PluginManager,
 
 	postMixInProperties: function(){
-		//load nls bundle
-		this._nls = i18n.getLocalization("dojox.grid.enhanced", "EnhancedGrid", this.lang);
+		this._nls = nls;
 		this.inherited(arguments);
 	},
 	postCreate: function(){
@@ -193,7 +195,7 @@ var EnhancedGrid = declare("dojox.grid.EnhancedGrid", DataGrid, {
 	},
 	onMouseUp: function(e){	},
 	createView: function(){
-		// summary
+		// summary:
 		//		Overwrite: rewrite getCellX of view.header
 		var view = this.inherited(arguments);
 		if(has('mozilla')){
@@ -259,4 +261,4 @@ EnhancedGrid.registerPlugin = function(clazz, props){
 
 return EnhancedGrid;
 
-});
\ No newline at end of file
+});
diff --git a/dojox/grid/LazyTreeGrid.js b/dojox/grid/LazyTreeGrid.js
index 77f4e98..69b5d9f 100644
--- a/dojox/grid/LazyTreeGrid.js
+++ b/dojox/grid/LazyTreeGrid.js
@@ -259,7 +259,12 @@ var LazyTreeCell = lang.mixin(lang.clone(TreeCell), {
 		if(this.editable && (this.alwaysEditing || (info.rowIndex === rowIndex && info.cell === this))){
 			return this.formatEditing(d, rowIndex);
 		}else{
-			return this._defaultFormat(d, [d, rowIndex, level, this]);
+			var dir = this.textDir || this.grid.textDir;
+			var ret = this._defaultFormat(d, [d, rowIndex, level, this]);
+			if(dir && this._enforceTextDirWithUcc){
+			    ret = this._enforceTextDirWithUcc(dir, ret);
+			}
+			return ret;
 		}
 	}
 });
@@ -342,22 +347,27 @@ var LazyTreeGrid = declare("dojox.grid.LazyTreeGrid", TreeGrid, {
 	//		and dojox.grid.TreeGrid also apply here
 	//
 	//		LazyTreeGrid does not support summary row/items aggregate due to the lazy-loading rationale.
+
 	_layoutClass: _LazyTreeLayout,
 	_size: 0,
-	// treeModel: dijit.tree.ForestStoreModel | dojox.grid.LazyTreeGridStoreModel
+
+	// treeModel: dijit/tree/.ForestStoreModel|dojox/grid/LazyTreeGridStoreModel
 	//		A tree store model object.
 	treeModel: null,
+
 	// defaultState: Object
 	//		Used to restore the state of LazyTreeGrid.
 	//		This object should ONLY be obtained from `LazyTreeGrid.getState()`.
 	defaultState: null,
+
 	// colSpans: Object
-	//		a json object that defines column span of each level rows
-	//		attributes:
-	//			0/1/..: which level need to colspan
-	//			start: start column index of colspan
-	//			end: end column index of colspan
-	//			primary: index of column which content will be displayed (default is value of start).
+	//		A json object that defines column span of each level rows.  Attributes:
+	//
+	//		- 0/1/..: which level need to colspan
+	//		- start: start column index of colspan
+	//		- end: end column index of colspan
+	//		- primary: index of column which content will be displayed (default is value of start).
+	//
 	//		example:
 	//		|	colSpans = {
 	//		|	0:	[
@@ -452,21 +462,21 @@ var LazyTreeGrid = declare("dojox.grid.LazyTreeGrid", TreeGrid, {
 		this.inherited(arguments);
 	},
 	expand: function(itemId){
-		//	summary:
+		// summary:
 		//		Expand the row with the given itemId.
-		//	id: string?
+		// itemId: String?
 		this._fold(itemId, true);
 	},
 	collapse: function(itemId){
-		//	summary:
+		// summary:
 		//		Collapse the row with the given itemId.
-		//	id: string?
+		// itemId: String?
 		this._fold(itemId, false);
 	},
 	refresh: function(keepState){
-		//	summary:
+		// summary:
 		//		Refresh, and persist the expand/collapse state when keepState equals true
-		//	keepState: boolean
+		// keepState: Boolean
 		if(!keepState){
 			this._cleanup();
 		}
@@ -770,7 +780,7 @@ var LazyTreeGrid = declare("dojox.grid.LazyTreeGrid", TreeGrid, {
 			this.inherited(arguments);
 			return;
 		}
-		row.customClasses = (row.odd ? " dojoxGridRowOdd" : "") + (row.selected ? " dojoxGridRowSelected" : "") + (row.over ? " dojoxGridRowOver" : "");
+		row.customClasses += (row.odd ? " dojoxGridRowOdd" : "") + (row.selected ? " dojoxGridRowSelected" : "") + (row.over ? " dojoxGridRowOver" : "");
 		this.focus.styleRow(row);
 		this.edit.styleRow(row);
 	},
diff --git a/dojox/grid/README b/dojox/grid/README
index 91b762c..4f80d3b 100644
--- a/dojox/grid/README
+++ b/dojox/grid/README
@@ -148,4 +148,4 @@ Known issues
 LazyTreeGrid is not compatible with:
  - Most Enhanced Grid features
  - Complicated layouts (e.g. multiple rows in column header)
--------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/dojox/grid/Selection.js b/dojox/grid/Selection.js
index 102da69..864208c 100644
--- a/dojox/grid/Selection.js
+++ b/dojox/grid/Selection.js
@@ -22,6 +22,7 @@ return declare("dojox.grid.Selection", null, {
 	selected: null,
 	updating: 0,
 	selectedIndex: -1,
+	rangeStartIndex: -1,
 
 	setMode: function(mode){
 		if(this.selected.length){
@@ -238,12 +239,14 @@ return declare("dojox.grid.Selection", null, {
 		if(this.mode != 'extended'){
 			this.select(inIndex);
 		}else{
-			var lastSelected = this.selectedIndex;
+			if(!inShiftKey || this.rangeStartIndex < 0){
+				this.rangeStartIndex = inIndex;
+			}
 			if(!inCtrlKey){
 				this.deselectAll(inIndex);
 			}
 			if(inShiftKey){
-				this.selectRange(lastSelected, inIndex);
+				this.selectRange(this.rangeStartIndex, inIndex);
 			}else if(inCtrlKey){
 				this.toggleSelect(inIndex);
 			}else{
diff --git a/dojox/grid/TreeGrid.js b/dojox/grid/TreeGrid.js
index 7103a80..236fa51 100644
--- a/dojox/grid/TreeGrid.js
+++ b/dojox/grid/TreeGrid.js
@@ -18,16 +18,16 @@ define([
 	"./TreeSelection",
 	"./cells/tree",
 	"./_TreeView"
-], function(dojo, dojox, declare, array, lang, event, domAttr, domClass, query, keys, ForestStoreModel, 
+], function(dojo, dojox, declare, array, lang, event, domAttr, domClass, query, keys, ForestStoreModel,
 	DataGrid, _Layout, _FocusManager, _RowManager, _EditManager, TreeSelection, TreeCell){
-		
+
 dojo.experimental("dojox.grid.TreeGrid");
 
 var _TreeAggregator = declare("dojox.grid._TreeAggregator", null, {
 	cells: [],
 	grid: null,
 	childFields: [],
-	
+
 	constructor: function(kwArgs){
 		this.cells = kwArgs.cells || [];
 		this.childFields = kwArgs.childFields || [];
@@ -47,7 +47,7 @@ var _TreeAggregator = declare("dojox.grid._TreeAggregator", null, {
 			delete this.store._cachedAggregates;
 		}
 	},
-	
+
 	cnt: function(cell, level, item){
 		// summary:
 		//		calculates the count of the children of item at the given level
@@ -126,7 +126,7 @@ var _TreeAggregator = declare("dojox.grid._TreeAggregator", null, {
 		}else if(field){
 			return this._cacheValue(typeCache, level, 0);
 		}
-		
+
 		// Calculate it
 		return this._cacheValue(typeCache, level, this[type](cell, level, item));
 	}
@@ -136,12 +136,12 @@ var _TreeLayout = declare("dojox.grid._TreeLayout", _Layout, {
 	// Whether or not we are collapsable - this is calculated when we
 	// set our structure.
 	_isCollapsable: false,
-	
+
 	_getInternalStructure: function(inStructure){
 		//	Create a "Tree View" with 1 row containing references for
 		//		each column (recursively)
 		var g = this.grid;
-		
+
 		var s = inStructure;
 		var cells = s[0].cells[0];
 		var tree = {
@@ -538,22 +538,21 @@ var TreeGrid = declare("dojox.grid.TreeGrid", DataGrid, {
 	//		A grid that supports nesting rows - it provides an expando function
 	//		similar to dijit.Tree.  It also provides mechanisms for aggregating
 	//		the values of subrows
-	//
 	// description:
 	//		TreeGrid currently only works on "simple" structures.  That is,
 	//		single-view structures with a single row in them.
 	//
 	//		The TreeGrid works using the concept of "levels" - level 0 are the
 	//		top-level items.
-	
+
 	// defaultOpen: Boolean
 	//		Whether or not we default to open (all levels).  This defaults to
 	//		false for grids with a treeModel.
 	defaultOpen: true,
 
 	// sortChildItems: Boolean
-	// 		If true, child items will be returned sorted according to the sorting
-	// 		properties of the grid.
+	//		If true, child items will be returned sorted according to the sorting
+	//		properties of the grid.
 	sortChildItems: false,
 
 	// openAtLevels: Array
@@ -562,23 +561,22 @@ var TreeGrid = declare("dojox.grid.TreeGrid", DataGrid, {
 	//		integer (for the # of children to be closed if there are more than
 	//		that)
 	openAtLevels: [],
-	
+
 	// treeModel: dijit.tree.ForestStoreModel
 	//		A dijit.Tree model that will be used instead of using aggregates.
 	//		Setting this value will make the TreeGrid behave like a columnar
 	//		tree.  When setting this value, defaultOpen will default to false,
 	//		and openAtLevels will be ignored.
 	treeModel: null,
-	
+
 	// expandoCell: Integer
 	//		When used in conjunction with a treeModel (see above), this is a 0-based
 	//		index of the cell in which to place the actual expando
 	expandoCell: 0,
-	
-	// private values
+
 	// aggregator: Object
 	//		The aggregator class - it will be populated automatically if we
-	//		are a collapsable grid
+	//		are a collapsible grid
 	aggregator: null,
 
 
@@ -629,6 +627,11 @@ var TreeGrid = declare("dojox.grid.TreeGrid", DataGrid, {
 		this.inherited(arguments);
 	},
 
+	_clearData: function() {
+		this.inherited(arguments);
+		this._by_idty_paths = {};
+	},
+
 	_cleanupExpandoCache: function(index, identity, item){},
 
 	_addItem: function(item, index, noUpdate, dontUpdateRoot){
@@ -700,7 +703,7 @@ var TreeGrid = declare("dojox.grid.TreeGrid", DataGrid, {
 		}
 		return idx;
 	},
-	
+
 	postMixInProperties: function(){
 		if(this.treeModel && !("defaultOpen" in this.params)){
 			// Default open to false for tree models, true for other tree
@@ -731,19 +734,19 @@ var TreeGrid = declare("dojox.grid.TreeGrid", DataGrid, {
 		this._by_idty_paths = {};
 		this.inherited(arguments);
 	},
-	
-    postCreate: function(){
-        this.inherited(arguments);
+
+	postCreate: function(){
+		this.inherited(arguments);
 		if(this.treeModel){
 			this._setModel(this.treeModel);
 		}
-    },
+	},
 
 	setModel: function(treeModel){
 		this._setModel(treeModel);
 		this._refresh(true);
 	},
-	
+
 	_setModel: function(treeModel){
 		if(treeModel && (!ForestStoreModel || !(treeModel instanceof ForestStoreModel))){
 			throw new Error("dojox.grid.TreeGrid: treeModel must be an instance of dijit.tree.ForestStoreModel");
@@ -758,7 +761,7 @@ var TreeGrid = declare("dojox.grid.TreeGrid", DataGrid, {
 		this.inherited(arguments);
 		this.scroller._origDefaultRowHeight = this.scroller.defaultRowHeight;
 	},
-	
+
 	createManagers: function(){
 		// summary:
 		//		create grid managers for various tasks including rows, focus, selection, editing
@@ -780,7 +783,7 @@ var TreeGrid = declare("dojox.grid.TreeGrid", DataGrid, {
 			this.aggregator.store = store;
 		}
 	},
-	
+
 	getDefaultOpenState: function(cellDef, item){
 		// summary:
 		//		Returns the default open state for the given definition and item
@@ -892,7 +895,7 @@ TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
 		}
 		return w;
 	};
-	
+
 	var cellsFromMarkup = function(table){
 		var rows;
 		// Don't support colgroup on our grid - single view, single row only
@@ -909,7 +912,7 @@ TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
 				if(cell.type){
 					cell.type = lang.getObject(cell.type);
 				}
-				
+
 				var subTable = query("> table", th)[0];
 				if(subTable){
 					// If we have a subtable, we are an aggregate and a summary cell
@@ -951,7 +954,7 @@ TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
 		}
 		return [];
 	};
-	
+
 	var rows;
 	if(	!props.structure ){
 		var row = cellsFromMarkup(node);
diff --git a/dojox/grid/_Builder.js b/dojox/grid/_Builder.js
index af55e09..7401f36 100644
--- a/dojox/grid/_Builder.js
+++ b/dojox/grid/_Builder.js
@@ -9,8 +9,9 @@ define([
 	"dojo/dnd/Moveable",
 	"dojox/html/metrics",
 	"./util",
-	"dojo/_base/html"
-], function(dojox, array, lang, win, event, has, connect, Moveable, metrics, util, html){
+	"dojo/_base/html",
+	"dojo/dom-geometry"
+], function(dojox, array, lang, win, event, has, connect, Moveable, metrics, util, html, domGeometry){
 
 	var dg = dojox.grid;
 
@@ -74,7 +75,7 @@ define([
 					inCell.id = this.grid.id + "Hdr" + inCell.index;
 				}
 				// column headers are not editable, mark as aria-readonly=true
-				html = ['<th tabIndex="-1" aria-readonly="true" role="columnheader"', sortInfo, 'id="', inCell.id, '"'];
+				html = ['<th tabIndex="-1" aria-readonly="true" role="columnheader"', sortInfo, ' id="', inCell.id, '"'];
 			}else{
 				// cells inherit grid aria-readonly property; default value for aria-readonly is false(grid is editable)
 				// if grid is editable (had any editable cells), mark non editable cells as aria-readonly=true
@@ -225,6 +226,12 @@ define([
 			if (e.cellNode)
 				this.grid.onMouseDown(e);
 			this.grid.onMouseDownRow(e);
+		},
+
+		_getTextDirStyle: function(textDir, inCell, inRowIndex){
+			// summary:
+			//		 Get BiDi text dir, just a placeholder, defined in dojox/grid/bidi/_BidiMixin
+			return "";
 		}
 	});
 
@@ -255,7 +262,7 @@ define([
 		generateHtml: function(inDataIndex, inRowIndex){
 			var
 				html = this.getTableArray(),
-				v = this.view,
+				v = this.view, dir,
 				cells = v.structure.cells,
 				item = this.grid.getItem(inRowIndex);
 
@@ -269,14 +276,14 @@ define([
 					m = cell.markup; cc = cell.customClasses = []; cs = cell.customStyles = [];
 					// content (format can fill in cc and cs as side-effects)
 					m[5] = cell.format(inRowIndex, item);
-					if(has('ie') < 8 && (m[5] === null || m[5] === '' || /^\s+$/.test(m[5]))){
-						//fix IE 6/7 quirks - border style not effective for empty td
-						m[5] = ' '
-					}
 					// classes
 					m[1] = cc.join(' ');
 					// styles
 					m[3] = cs.join(';');
+					dir = cell.textDir || this.grid.textDir;
+					if(dir){
+					    m[3] += this._getTextDirStyle(dir, cell, inRowIndex);
+					}
 					// in-place concat
 					html.push.apply(html, m);
 				}
@@ -315,7 +322,7 @@ define([
 		},
 
 		generateHtml: function(inGetValue, inValue){
-			var html = this.getTableArray(), cells = this.view.structure.cells;
+			var dir, html = this.getTableArray(), cells = this.view.structure.cells;
 			
 			util.fire(this.view, "onBeforeRow", [-1, cells]);
 			for(var j=0, row; (row=cells[j]); j++){
@@ -349,6 +356,10 @@ define([
 					markup[5] = (inValue != undefined ? inValue : inGetValue(cell));
 					// styles
 					markup[3] = cell.customStyles.join(';');
+					dir = cell.textDir || this.grid.textDir;
+					if(dir){
+					    markup[3] += this._getTextDirStyle(dir, cell, inValue);
+					}
 					// classes
 					markup[1] = cell.customClasses.join(' '); //(cell.customClasses ? ' ' + cell.customClasses : '');
 					html.push(markup.join(''));
@@ -361,28 +372,17 @@ define([
 
 		// event helpers
 		getCellX: function(e){
-			var n, x = e.layerX;
-			if(has('mozilla') || has('ie') >= 9){
-				n = ascendDom(e.target, makeNotTagName("th"));
-				x -= (n && n.offsetLeft) || 0;
-				var t = e.sourceView.getScrollbarWidth();
-				if(!this.grid.isLeftToRight()/*&& e.sourceView.headerNode.scrollLeft < t*/){
-					//fix #11253
-					table = ascendDom(n,makeNotTagName("table"));
-					x -= (table && table.offsetLeft) || 0;
-				}
-				//x -= getProp(ascendDom(e.target, mkNotTagName("td")), "offsetLeft") || 0;
+			var n, x, pos;
+			// Calculate starting x position
+			n = ascendDom(e.target, makeNotTagName("th"));
+			if(n){
+				// We have a proper parent node, use that for position
+				pos = domGeometry.position(n);
+				x = e.clientX - pos.x;
+			}else{
+				// Fall back to layerX
+				x = e.layerX;
 			}
-			n = ascendDom(e.target, function(){
-				if(!n || n == e.cellNode){
-					return false;
-				}
-				// Mozilla 1.8 (FF 1.5) has a bug that makes offsetLeft = -parent border width
-				// when parent has border, overflow: hidden, and is positioned
-				// handle this problem here ... not a general solution!
-				x += (n.offsetLeft < 0 ? 0 : n.offsetLeft);
-				return true;
-			});
 			return x;
 		},
 
@@ -673,7 +673,8 @@ define([
 		map: null,
 
 		mapRows: function(inRows){
-			// summary: Map table topography
+			// summary:
+			//		Map table topography
 
 			//console.log('mapRows');
 			// # of rows
@@ -713,7 +714,8 @@ define([
 		},
 
 		getMapCoords: function(inRow, inCol){
-			// summary: Find node's map coords by it's structure coords
+			// summary:
+			//		Find node's map coords by it's structure coords
 			for(var j=0, row; (row=this.map[j]); j++){
 				for(var i=0, cell; (cell=row[i]); i++){
 					if(cell.c==inCol && cell.r == inRow){
@@ -726,7 +728,8 @@ define([
 		},
 		
 		getNode: function(inTable, inRow, inCol){
-			// summary: Find a node in inNode's table with the given structure coords
+			// summary:
+			//		Find a node in inNode's table with the given structure coords
 			var row = inTable && inTable.rows[inRow];
 			return row && row.cells[inCol];
 		},
@@ -756,4 +759,4 @@ define([
 		_HeaderBuilder: _HeaderBuilder,
 		_ContentBuilder: _ContentBuilder
 	};
-});
\ No newline at end of file
+});
diff --git a/dojox/grid/_EditManager.js b/dojox/grid/_EditManager.js
index 5ae4559..a303637 100644
--- a/dojox/grid/_EditManager.js
+++ b/dojox/grid/_EditManager.js
@@ -14,11 +14,9 @@ return declare("dojox.grid._EditManager", null, {
 		// inGrid: dojox.Grid
 		//		The dojox.Grid this editor should be attached to
 		this.grid = inGrid;
-		if(has('ie')){
-			this.connections = [connect.connect(document.body, "onfocus", lang.hitch(this, "_boomerangFocus"))];
-		}else{
-			this.connections = [connect.connect(this.grid, 'onBlur', this, 'apply')];
-		}
+		this.connections = !has('ie') ? [] : [connect.connect(document.body, "onfocus", lang.hitch(this, "_boomerangFocus"))];
+		this.connections.push(connect.connect(this.grid, 'onBlur', this, 'apply'));
+		this.connections.push(connect.connect(this.grid, 'prerender', this, '_onPreRender'));
 	},
 	
 	info: {},
@@ -253,6 +251,13 @@ return declare("dojox.grid._EditManager", null, {
 		}		
 		w.focused = true;
 		return w.isValid(true);
+	},
+	
+	_onPreRender: function(){
+		if(this.isEditing()){
+			//cache the current editing value before render
+			this.info.value = this.info.cell.getValue();
+		}
 	}
 });
 });
\ No newline at end of file
diff --git a/dojox/grid/_Events.js b/dojox/grid/_Events.js
index 5e61c46..d46a51d 100644
--- a/dojox/grid/_Events.js
+++ b/dojox/grid/_Events.js
@@ -14,34 +14,36 @@ return declare("dojox.grid._Events", null, {
 	//		retain default implementation or override them for custom handling.
 	
 	// cellOverClass: String
-	// 		css class to apply to grid cells over which the cursor is placed.
+	//		css class to apply to grid cells over which the cursor is placed.
 	cellOverClass: "dojoxGridCellOver",
 	
 	onKeyEvent: function(e){
-		// summary: top level handler for Key Events
+		// summary:
+		//		top level handler for Key Events
 		this.dispatchKeyEvent(e);
 	},
 
 	onContentEvent: function(e){
-		// summary: Top level handler for Content events
+		// summary:
+		//		Top level handler for Content events
 		this.dispatchContentEvent(e);
 	},
 
 	onHeaderEvent: function(e){
-		// summary: Top level handler for header events
+		// summary:
+		//		Top level handler for header events
 		this.dispatchHeaderEvent(e);
 	},
 
 	onStyleRow: function(inRow){
 		// summary:
 		//		Perform row styling on a given row. Called whenever row styling is updated.
-		//
 		// inRow: Object
-		// 		Object containing row state information: selected, true if the row is selcted; over:
-		// 		true of the mouse is over the row; odd: true if the row is odd. Use customClasses and
-		// 		customStyles to control row css classes and styles; both properties are strings.
-		//
-		// example: onStyleRow({ selected: true, over:true, odd:false })
+		//		Object containing row state information: selected, true if the row is selcted; over:
+		//		true of the mouse is over the row; odd: true if the row is odd. Use customClasses and
+		//		customStyles to control row css classes and styles; both properties are strings.
+		// example:
+		// |	onStyleRow({ selected: true, over:true, odd:false })
 		var i = inRow;
 		i.customClasses += (i.odd?" dojoxGridRowOdd":"") + (i.selected?" dojoxGridRowSelected":"") + (i.over?" dojoxGridRowOver":"");
 		this.focus.styleRow(inRow);
@@ -50,8 +52,8 @@ return declare("dojox.grid._Events", null, {
 	
 	onKeyDown: function(e){
 		// summary:
-		// 		Grid key event handler. By default enter begins editing and applies edits, escape cancels an edit,
-		// 		tab, shift-tab, and arrow keys move grid cell focus.
+		//		Grid key event handler. By default enter begins editing and applies edits, escape cancels an edit,
+		//		tab, shift-tab, and arrow keys move grid cell focus.
 		if(e.altKey || e.metaKey){
 			return;
 		}
@@ -236,7 +238,7 @@ return declare("dojox.grid._Events", null, {
 		// summary:
 		//		Event fired when mouse is down in a header cell.
 		// e: Event
-		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
 	},
 
 	onCellClick: function(e){
@@ -270,7 +272,6 @@ return declare("dojox.grid._Events", null, {
 			event = e;
 		}
 		this.focus.setFocusCell(event.cell, event.rowIndex);
-		this.onRowClick(event);
 		this.edit.setEditCell(event.cell, event.rowIndex);
 		this.onRowDblClick(e);
 	},
@@ -321,21 +322,21 @@ return declare("dojox.grid._Events", null, {
 		// summary:
 		//		Event fired when mouse moves out of a data row.
 		// e: Event
-		// 		Decorated event object contains reference to grid, cell, and rowIndex
+		//		Decorated event object contains reference to grid, cell, and rowIndex
 	},
 	
 	onRowMouseDown: function(e){
 		// summary:
 		//		Event fired when mouse is down in a row.
 		// e: Event
-		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
 	},
 
 	onRowContextMenu: function(e){
 		// summary:
 		//		Event fired when a row context menu is accessed via mouse right click.
 		// e: Event
-		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
 		event.stop(e);
 	},
 
@@ -344,21 +345,21 @@ return declare("dojox.grid._Events", null, {
 		// summary:
 		//		Event fired when mouse moves over the grid header.
 		// e: Event
-		// 		Decorated event object contains reference to grid, cell, and rowIndex
+		//		Decorated event object contains reference to grid, cell, and rowIndex
 	},
 
 	onHeaderMouseOut: function(e){
 		// summary:
 		//		Event fired when mouse moves out of the grid header.
 		// e: Event
-		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
 	},
 
 	onHeaderCellMouseOver: function(e){
 		// summary:
 		//		Event fired when mouse moves over a header cell.
 		// e: Event
-		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
 		if(e.cellNode){
 			domClass.add(e.cellNode, this.cellOverClass);
 		}
@@ -368,7 +369,7 @@ return declare("dojox.grid._Events", null, {
 		// summary:
 		//		Event fired when mouse moves out of a header cell.
 		// e: Event
-		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
 		if(e.cellNode){
 			domClass.remove(e.cellNode, this.cellOverClass);
 		}
@@ -378,14 +379,14 @@ return declare("dojox.grid._Events", null, {
 		// summary:
 		//		Event fired when mouse is down in a header cell.
 		// e: Event
-		// 		Decorated event object which contains reference to grid, cell, and rowIndex
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
 	},
 
 	onHeaderClick: function(e){
 		// summary:
 		//		Event fired when the grid header is clicked.
 		// e: Event
-		// Decorated event object which contains reference to grid, cell, and rowIndex
+		//		Decorated event object which contains reference to grid, cell, and rowIndex
 	},
 
 	onHeaderCellClick: function(e){
diff --git a/dojox/grid/_FocusManager.js b/dojox/grid/_FocusManager.js
index 38d5998..04122bf 100644
--- a/dojox/grid/_FocusManager.js
+++ b/dojox/grid/_FocusManager.js
@@ -13,8 +13,8 @@ define([
 // focus management
 return declare("dojox.grid._FocusManager", null, {
 	// summary:
-	//	Controls grid cell focus. Owned by grid and used internally for focusing.
-	//	Note: grid cell actually receives keyboard input only when cell is being edited.
+	//		Controls grid cell focus. Owned by grid and used internally for focusing.
+	//		Note: grid cell actually receives keyboard input only when cell is being edited.
 	constructor: function(inGrid){
 		this.grid = inGrid;
 		this.cell = null;
@@ -50,13 +50,13 @@ return declare("dojox.grid._FocusManager", null, {
 	},
 	isFocusCell: function(inCell, inRowIndex){
 		// summary:
-		//	states if the given cell is focused
+		//		states if the given cell is focused
 		// inCell: object
-		//	grid cell object
+		//		grid cell object
 		// inRowIndex: int
-		//	grid row index
+		//		grid row index
 		// returns:
-		//	true of the given grid cell is focused
+		//		true of the given grid cell is focused
 		return (this.cell == inCell) && (this.rowIndex == inRowIndex);
 	},
 	isLastFocusCell: function(){
@@ -76,16 +76,16 @@ return declare("dojox.grid._FocusManager", null, {
 	},
 	isNavHeader: function(){
 		// summary:
-		//	states whether currently navigating among column headers.
+		//		states whether currently navigating among column headers.
 		// returns:
-		//	true if focus is on a column header; false otherwise.
+		//		true if focus is on a column header; false otherwise.
 		return (!!this._colHeadNode);
 	},
 	getHeaderIndex: function(){
 		// summary:
-		//	if one of the column headers currently has focus, return its index.
+		//		if one of the column headers currently has focus, return its index.
 		// returns:
-		//	index of the focused column header, or -1 if none have focus.
+		//		index of the focused column header, or -1 if none have focus.
 		if(this._colHeadNode){
 			return array.indexOf(this._findHeaderCells(), this._colHeadNode);
 		}else{
@@ -99,7 +99,7 @@ return declare("dojox.grid._FocusManager", null, {
 			if(inBork){
 				var sl = this.scrollIntoView();
 				try{
-					if(!this.grid.edit.isEditing()){
+					if(has("webkit") || !this.grid.edit.isEditing()){
 						util.fire(n, "focus");
 						if(sl){ this.cell.view.scrollboxNode.scrollLeft = sl; }
 					}
@@ -128,7 +128,7 @@ return declare("dojox.grid._FocusManager", null, {
 	_delayedHeaderFocus: function(){
 		if(this.isNavHeader()){
 			this.focusHeader();
-			this.grid.domNode.focus();
+			//this.grid.domNode.focus();
 		}
 	},
 	_initColumnHeaders: function(){
@@ -257,10 +257,10 @@ return declare("dojox.grid._FocusManager", null, {
 	colSizeAdjust: function (e, colIdx, delta){ // adjust the column specified by colIdx by the specified delta px
 		var headers = this._findHeaderCells();
 		var view = this.focusView;
-		if (!view) {
-			for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
+		if(!view || !view.header.tableMap.map){
+			for(var i = 0, cView; (cView = this.grid.views.views[i]); i++){
 				// find first view with a tableMap in order to work with empty grid
-				if(cView.header.tableMap.map ){
+				if(cView.header.tableMap.map){
 					view=cView;
 					break;
 				}
@@ -289,20 +289,20 @@ return declare("dojox.grid._FocusManager", null, {
 	},
 	setFocusIndex: function(inRowIndex, inCellIndex){
 		// summary:
-		//	focuses the given grid cell
+		//		focuses the given grid cell
 		// inRowIndex: int
-		//	grid row index
+		//		grid row index
 		// inCellIndex: int
-		//	grid cell index
+		//		grid cell index
 		this.setFocusCell(this.grid.getCell(inCellIndex), inRowIndex);
 	},
 	setFocusCell: function(inCell, inRowIndex){
 		// summary:
-		//	focuses the given grid cell
+		//		focuses the given grid cell
 		// inCell: object
-		//	grid cell object
+		//		grid cell object
 		// inRowIndex: int
-		//	grid row index
+		//		grid row index
 		if(inCell && !this.isFocusCell(inCell, inRowIndex)){
 			this.tabbingOut = false;
 			if (this._colHeadNode){
@@ -376,11 +376,11 @@ return declare("dojox.grid._FocusManager", null, {
 	},
 	move: function(inRowDelta, inColDelta) {
 		// summary:
-		//	focus grid cell or  simulate focus to column header based on position relative to current focus
+		//		focus grid cell or  simulate focus to column header based on position relative to current focus
 		// inRowDelta: int
-		// vertical distance from current focus
+		//		vertical distance from current focus
 		// inColDelta: int
-		// horizontal distance from current focus
+		//		horizontal distance from current focus
 
 		var colDir = inColDelta < 0 ? -1 : 1;
 		// Handle column headers.
@@ -436,7 +436,7 @@ return declare("dojox.grid._FocusManager", null, {
 					}
 					return;
 				}else if((!n || html.style(n, "display") === "none") && inColDelta){
-					if((col + inRowDelta) >= 0 && (col + inRowDelta) <= cc){
+					if((col + inColDelta) >= 0 && (col + inColDelta) <= cc){
 						this.move(inRowDelta, inColDelta > 0 ? ++inColDelta : --inColDelta);
 					}
 					return;
diff --git a/dojox/grid/_Grid.js b/dojox/grid/_Grid.js
index 2d9e0d1..7289b22 100644
--- a/dojox/grid/_Grid.js
+++ b/dojox/grid/_Grid.js
@@ -35,130 +35,106 @@ define([
 		dojo.isCopyKey = dojo.dnd.getCopyKeyState;
 	}
 	/*=====
-	dojox.grid.__CellDef = function(){
-		//	name: String?
+	dojox.grid.__CellDef = {
+		// name: String?
 		//		The text to use in the header of the grid for this cell.
-		//	get: Function?
+		// get: Function?
 		//		function(rowIndex){} rowIndex is of type Integer.  This
 		//		function will be called when a cell	requests data.  Returns the
 		//		unformatted data for the cell.
-		//	value: String?
+		// value: String?
 		//		If "get" is not specified, this is used as the data for the cell.
-		//	defaultValue: String?
+		// defaultValue: String?
 		//		If "get" and "value" aren't specified or if "get" returns an undefined
 		//		value, this is used as the data for the cell.  "formatter" is not run
 		//		on this if "get" returns an undefined value.
-		//	formatter: Function?
+		// formatter: Function?
 		//		function(data, rowIndex){} data is of type anything, rowIndex
 		//		is of type Integer.  This function will be called after the cell
 		//		has its data but before it passes it back to the grid to render.
 		//		Returns the formatted version of the cell's data.
-		//	type: dojox.grid.cells._Base|Function?
+		// type: dojox.grid.cells._Base|Function?
 		//		TODO
-		//	editable: Boolean?
+		// editable: Boolean?
 		//		Whether this cell should be editable or not.
-		//	hidden: Boolean?
+		// hidden: Boolean?
 		//		If true, the cell will not be displayed.
-		//	noresize: Boolean?
+		// noresize: Boolean?
 		//		If true, the cell will not be able to be resized.
-		//	width: Integer|String?
+		// width: Integer|String?
 		//		A CSS size.  If it's an Integer, the width will be in em's.
-		//	colSpan: Integer?
+		// colSpan: Integer?
 		//		How many columns to span this cell.  Will not work in the first
 		//		sub-row of cells.
-		//	rowSpan: Integer?
+		// rowSpan: Integer?
 		//		How many sub-rows to span this cell.
-		//	styles: String?
+		// styles: String?
 		//		A string of styles to apply to both the header cell and main
 		//		grid cells.  Must end in a ';'.
-		//	headerStyles: String?
+		// headerStyles: String?
 		//		A string of styles to apply to just the header cell.  Must end
 		//		in a ';'
-		//	cellStyles: String?
+		// cellStyles: String?
 		//		A string of styles to apply to just the main grid cells.  Must
 		//		end in a ';'
-		//	classes: String?
+		// classes: String?
 		//		A space separated list of classes to apply to both the header
 		//		cell and the main grid cells.
-		//	headerClasses: String?
+		// headerClasses: String?
 		//		A space separated list of classes to apply to just the header
 		//		cell.
-		//	cellClasses: String?
+		// cellClasses: String?
 		//		A space separated list of classes to apply to just the main
 		//		grid cells.
-		//	attrs: String?
+		// attrs: String?
 		//		A space separated string of attribute='value' pairs to add to
 		//		the header cell element and main grid cell elements.
-		this.name = name;
-		this.value = value;
-		this.get = get;
-		this.formatter = formatter;
-		this.type = type;
-		this.editable = editable;
-		this.hidden = hidden;
-		this.width = width;
-		this.colSpan = colSpan;
-		this.rowSpan = rowSpan;
-		this.styles = styles;
-		this.headerStyles = headerStyles;
-		this.cellStyles = cellStyles;
-		this.classes = classes;
-		this.headerClasses = headerClasses;
-		this.cellClasses = cellClasses;
-		this.attrs = attrs;
-	}
+	};
 	=====*/
 
 	/*=====
-	dojox.grid.__ViewDef = function(){
-		//	noscroll: Boolean?
+	dojox.grid.__ViewDef = {
+		// noscroll: Boolean?
 		//		If true, no scrollbars will be rendered without scrollbars.
-		//	width: Integer|String?
+		// width: Integer|String?
 		//		A CSS size.  If it's an Integer, the width will be in em's. If
 		//		"noscroll" is true, this value is ignored.
-		//	cells: dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]?
+		// cells: dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]]?
 		//		The structure of the cells within this grid.
-		//	type: String?
+		// type: String?
 		//		A string containing the constructor of a subclass of
 		//		dojox.grid._View.  If this is not specified, dojox.grid._View
 		//		is used.
-		//	defaultCell: dojox.grid.__CellDef?
+		// defaultCell: dojox.grid.__CellDef?
 		//		A cell definition with default values for all cells in this view.  If
 		//		a property is defined in a cell definition in the "cells" array and
 		//		this property, the cell definition's property will override this
 		//		property's property.
-		//	onBeforeRow: Function?
+		// onBeforeRow: Function?
 		//		function(rowIndex, cells){} rowIndex is of type Integer, cells
 		//		is of type Array[dojox.grid.__CellDef[]].  This function is called
 		//		before each row of data is rendered.  Before the header is
 		//		rendered, rowIndex will be -1.  "cells" is a reference to the
 		//		internal structure of this view's cells so any changes you make to
 		//		it will persist between calls.
-		//	onAfterRow: Function?
+		// onAfterRow: Function?
 		//		function(rowIndex, cells, rowNode){} rowIndex is of type Integer, cells
 		//		is of type Array[dojox.grid.__CellDef[]], rowNode is of type DOMNode.
 		//		This function is called	after each row of data is rendered.  After the
 		//		header is rendered, rowIndex will be -1.  "cells" is a reference to the
 		//		internal structure of this view's cells so any changes you make to
 		//		it will persist between calls.
-		this.noscroll = noscroll;
-		this.width = width;
-		this.cells = cells;
-		this.type = type;
-		this.defaultCell = defaultCell;
-		this.onBeforeRow = onBeforeRow;
-		this.onAfterRow = onAfterRow;
-	}
+	};
 	=====*/
 
 	var _Grid = declare('dojox.grid._Grid',
 		[ _Widget, _TemplatedMixin, _Events ],
 		{
 		// summary:
-		// 		A grid widget with virtual scrolling, cell editing, complex rows,
-		// 		sorting, fixed columns, sizeable columns, etc.
+		//		A grid widget with virtual scrolling, cell editing, complex rows,
+		//		sorting, fixed columns, sizeable columns, etc.
 		//
-		//	description:
+		// description:
 		//		_Grid provides the full set of grid features without any
 		//		direct connection to a data store.
 		//
@@ -168,7 +144,7 @@ define([
 		//		The grid is rendered based on its structure, an object describing
 		//		column and cell layout.
 		//
-		//	example:
+		// example:
 		//		A quick sample:
 		//
 		//		define a get function
@@ -194,7 +170,7 @@ define([
 		templateString: template,
 
 		// classTag: String
-		// 		CSS class applied to the grid's domNode
+		//		CSS class applied to the grid's domNode
 		classTag: 'dojoxGrid',
 
 		// settings
@@ -233,7 +209,7 @@ define([
 		//		If rowHeight is set to a positive number, it will define the height of the rows
 		//		in pixels. This can provide a significant performance advantage, since it
 		//		eliminates the need to measure row sizes during rendering, which is one
-		// 		the primary bottlenecks in the DataGrid's performance.
+		//		the primary bottlenecks in the DataGrid's performance.
 		rowHeight: 0,
 		
 		// autoRender: Boolean
@@ -267,21 +243,21 @@ define([
 		selectionMode: 'extended',
 
 		// rowSelector: Boolean|String
-		// 		If set to true, will add a row selector view to this grid.  If set to a CSS width, will add
-		// 		a row selector of that width to this grid.
+		//		If set to true, will add a row selector view to this grid.  If set to a CSS width, will add
+		//		a row selector of that width to this grid.
 		rowSelector: '',
 
 		// columnReordering: Boolean
-		// 		If set to true, will add drag and drop reordering to views with one row of columns.
+		//		If set to true, will add drag and drop reordering to views with one row of columns.
 		columnReordering: false,
 
 		// headerMenu: dijit.Menu
-		// 		If set to a dijit.Menu, will use this as a context menu for the grid headers.
+		//		If set to a dijit.Menu, will use this as a context menu for the grid headers.
 		headerMenu: null,
 
 		// placeholderLabel: String
-		// 		Label of placeholders to search for in the header menu to replace with column toggling
-		// 		menu items.
+		//		Label of placeholders to search for in the header menu to replace with column toggling
+		//		menu items.
 		placeholderLabel: "GridColumns",
 		
 		// selectable: Boolean
@@ -292,28 +268,28 @@ define([
 		_click: null,
 		
 		// loadingMessage: String
-		//  Message that shows while the grid is loading
+		//		Message that shows while the grid is loading
 		loadingMessage: "<span class='dojoxGridLoading'>${loadingState}</span>",
 
 		// errorMessage: String
-		//  Message that shows when the grid encounters an error loading
+		//		Message that shows when the grid encounters an error loading
 		errorMessage: "<span class='dojoxGridError'>${errorState}</span>",
 
 		// noDataMessage: String
-		//  Message that shows if the grid has no data - wrap it in a
-		//  span with class 'dojoxGridNoData' if you want it to be
-		//  styled similar to the loading and error messages
+		//		Message that shows if the grid has no data - wrap it in a
+		//		span with class 'dojoxGridNoData' if you want it to be
+		//		styled similar to the loading and error messages
 		noDataMessage: "",
 		
 		// escapeHTMLInData: Boolean
 		//		This will escape HTML brackets from the data to prevent HTML from
-		// 		user-inputted data being rendered with may contain JavaScript and result in
-		// 		XSS attacks. This is true by default, and it is recommended that it remain
-		// 		true. Setting this to false will allow data to be displayed in the grid without
-		// 		filtering, and should be only used if it is known that the data won't contain
-		// 		malicious scripts. If HTML is needed in grid cells, it is recommended that
-		// 		you use the formatter function to generate the HTML (the output of
-		// 		formatter functions is not filtered, even with escapeHTMLInData set to true).
+		//		user-inputted data being rendered with may contain JavaScript and result in
+		//		XSS attacks. This is true by default, and it is recommended that it remain
+		//		true. Setting this to false will allow data to be displayed in the grid without
+		//		filtering, and should be only used if it is known that the data won't contain
+		//		malicious scripts. If HTML is needed in grid cells, it is recommended that
+		//		you use the formatter function to generate the HTML (the output of
+		//		formatter functions is not filtered, even with escapeHTMLInData set to true).
 		escapeHTMLInData: true,
 		
 		// formatterScope: Object
@@ -323,13 +299,19 @@ define([
 		formatterScope: null,
 		
 		// editable: boolean
-		// indicates if the grid contains editable cells, default is false
-		// set to true if editable cell encountered during rendering
+		//		indicates if the grid contains editable cells, default is false
+		//		set to true if editable cell encountered during rendering
 		editable: false,
+
+		// summary: String
+		//		Customizable summary descriptions which will be added to grid.domNode
+		summary: '',
+		_setSummaryAttr: 'domNode',
 		
-		// private
+		// sortInfo: [private] Number
 		sortInfo: 0,
-		themeable: true,
+
+		// _placeholders: [private] Array
 		_placeholders: null,
 
 		// _layoutClass: Object
@@ -364,6 +346,9 @@ define([
 			if(!this.isLeftToRight()){
 				html.addClass(this.domNode, this.classTag+"Rtl");
 			}
+			if(this.rowHeight > 0){
+				html.addClass(this.viewsNode, this.classTag + "FixedRowHeight");
+			}
 		},
 		
 		postMixInProperties: function(){
@@ -490,7 +475,8 @@ define([
 		},
 
 		createScroller: function(){
-			// summary: Creates a new virtual scroller
+			// summary:
+			//		Creates a new virtual scroller
 			this.scroller = new _Scroller();
 			this.scroller.grid = this;
 			this.scroller.renderRow = lang.hitch(this, "renderRow");
@@ -498,13 +484,14 @@ define([
 		},
 
 		createLayout: function(){
-			// summary: Creates a new Grid layout
+			// summary:
+			//		Creates a new Grid layout
 			this.layout = new this._layoutClass(this);
 			this.connect(this.layout, "moveColumn", "onMoveColumn");
 		},
 
 		onMoveColumn: function(){
-			this.render();
+			this.update();
 		},
 		
 		onResizeColumn: function(/*int*/ cellIdx){
@@ -564,7 +551,8 @@ define([
 		},
 		
 		getColumnTogglingItems: function(){
-			// Summary: returns an array of dijit.CheckedMenuItem widgets that can be
+			// summary:
+			//		returns an array of dijit.CheckedMenuItem widgets that can be
 			//		added to a menu for toggling columns on and off.
 			var items, checkedItems = [];
 			items = array.map(this.layout.cells, function(cell){
@@ -691,13 +679,6 @@ define([
 			// called.  This saves us an extra call to _resize(), which can
 			// get kind of heavy.
 			
-			// fixes #11101, should ignore resize when in autoheight mode(IE) to avoid a deadlock
-			// e.g when an autoheight editable grid put in dijit.form.Form or other similar containers,
-			// grid switch to editing mode --> grid height change --> From height change
-			// ---> Form call grid.resize() ---> grid height change  --> deaklock
-			if(dojo.isIE && !changeSize && !resultSize && this._autoHeight){
-				return;
-			}
 			this._pendingChangeSize = changeSize;
 			this._pendingResultSize = resultSize;
 			this.sizeChange();
@@ -757,7 +738,7 @@ define([
 				this.height = this.domNode.style.height;
 				delete this.fitTo;
 			}else if(this.fitTo == "parent"){
-				h = this._parentContentBoxHeight = this._parentContentBoxHeight || html._getContentBox(pn).h;
+				h = this._parentContentBoxHeight = (this._parentContentBoxHeight > 0 ? this._parentContentBoxHeight : html._getContentBox(pn).h);
 				this.domNode.style.height = Math.max(0, h) + "px";
 			}
 			
@@ -789,7 +770,10 @@ define([
 		},
 
 		adaptWidth: function() {
-			// private: sets width and position for views and update grid width if necessary
+			// summary:
+			//		sets width and position for views and update grid width if necessary
+			// tags:
+			//		private
 			var doAutoWidth = (!this.initialWidth && this.autoWidth);
 			var w = doAutoWidth ? 0 : this.domNode.clientWidth || (this.domNode.offsetWidth - this._getPadBorder().w),
 				vw = this.views.arrange(1, w);
@@ -800,8 +784,11 @@ define([
 		},
 
 		adaptHeight: function(inHeaderHeight){
-			// private: measures and normalizes header height, then sets view heights, and then updates scroller
-			// content extent
+			// summary:
+			//		measures and normalizes header height, then sets view heights, and then updates scroller
+			//		content extent
+			// tags:
+			//		private
 			var t = inHeaderHeight === undefined ? this._getHeaderHeight() : inHeaderHeight;
 			var h = (this._autoHeight ? -1 : Math.max(this.domNode.clientHeight - t, 0) || 0);
 			this.views.onEach('setSize', [0, h]);
@@ -839,7 +826,7 @@ define([
 		render: function(){
 			// summary:
 			//	Render the grid, headers, and views. Edit and scrolling states are reset. To retain edit and
-			// scrolling states, see Update.
+			//	scrolling states, see Update.
 
 			if(!this.domNode){return;}
 			if(!this._started){return;}
@@ -885,12 +872,18 @@ define([
 		},
 
 		renderRow: function(inRowIndex, inNodes){
-			// summary: private, used internally to render rows
+			// summary:
+			//		used internally to render rows
+			// tags:
+			//		private
 			this.views.renderRow(inRowIndex, inNodes, this._skipRowRenormalize);
 		},
 
 		rowRemoved: function(inRowIndex){
-			// summary: private, used internally to remove rows
+			// summary:
+			//		used internally to remove rows
+			// tags:
+			//		private
 			this.views.rowRemoved(inRowIndex);
 		},
 
@@ -983,10 +976,10 @@ define([
 		},
 
 		updateRowCount: function(inRowCount){
-			//summary:
-			//	Change the number of rows.
+			// summary:
+			//		Change the number of rows.
 			// inRowCount: int
-			//	Number of rows in the grid.
+			//		Number of rows in the grid.
 			if(this.updating){
 				this.invalidated.rowCount = inRowCount;
 			}else{
@@ -1026,7 +1019,7 @@ define([
 			//		Update grid when the height of a row has changed. Row height is handled automatically as rows
 			//		are rendered. Use this function only to update a row's height outside the normal rendering process.
 			// inRowIndex: Integer
-			// 		index of the row that has changed height
+			//		index of the row that has changed height
 
 			this.views.renormalizeRow(inRowIndex);
 			this.scroller.rowHeightChanged(inRowIndex);
@@ -1085,12 +1078,15 @@ define([
 			// summary:
 			//		Scroll the grid to a specific row.
 			// inRowIndex: Integer
-			// 		grid row index
+			//		grid row index
 			this.setScrollTop(this.scroller.findScrollTop(inRowIndex) + 1);
 		},
 
-		// styling (private, used internally to style individual parts of a row)
 		styleRowNode: function(inRowIndex, inRowNode){
+			// summary:
+			//		styling (used internally to style individual parts of a row)
+			// tags:
+			//		private
 			if(inRowNode){
 				this.rows.styleRowNode(inRowIndex, inRowNode);
 			}
@@ -1106,7 +1102,7 @@ define([
 			// summary:
 			//		Retrieves the cell object for a given grid column.
 			// inIndex: Integer
-			// 		Grid column index of cell to retrieve
+			//		Grid column index of cell to retrieve
 			// returns:
 			//		a grid cell
 			return this.layout.cells[inIndex];
@@ -1117,7 +1113,8 @@ define([
 		},
 
 		getCellName: function(inCell){
-			// summary: Returns the cell name of a passed cell
+			// summary:
+			//		Returns the cell name of a passed cell
 			return "Cell " + inCell.index; // String
 		},
 
@@ -1127,7 +1124,7 @@ define([
 			//		Determines if the grid can be sorted
 			// inSortInfo: Integer
 			//		Sort information, 1-based index of column on which to sort, positive for an ascending sort
-			// 		and negative for a descending sort
+			//		and negative for a descending sort
 			// returns: Boolean
 			//		True if grid can be sorted on the given column in the given direction
 		},
@@ -1151,11 +1148,11 @@ define([
 
 		setSortIndex: function(inIndex, inAsc){
 			// summary:
-			// 		Sort the grid on a column in a specified direction
+			//		Sort the grid on a column in a specified direction
 			// inIndex: Integer
-			// 		Column index on which to sort.
+			//		Column index on which to sort.
 			// inAsc: Boolean
-			// 		If true, sort the grid in ascending order, otherwise in descending order
+			//		If true, sort the grid in ascending order, otherwise in descending order
 			var si = inIndex +1;
 			if(inAsc != undefined){
 				si *= (inAsc ? 1 : -1);
@@ -1396,4 +1393,4 @@ define([
 
 	return _Grid;
 
-});
\ No newline at end of file
+});
diff --git a/dojox/grid/_RowSelector.js b/dojox/grid/_RowSelector.js
index 152caa1..2b23afe 100644
--- a/dojox/grid/_RowSelector.js
+++ b/dojox/grid/_RowSelector.js
@@ -30,7 +30,7 @@ return declare('dojox.grid._RowSelector', _View, {
 	},
 	adaptWidth: function(){
 		// Only calculate this here - rather than every call to buildRowContent
-		if(!("contentWidth" in this) && this.contentNode){
+		if(!("contentWidth" in this) && this.contentNode && this.contentNode.offsetWidth > 0){
 			this.contentWidth = this.contentNode.offsetWidth - this.padBorderWidth;
 		}
 	},
diff --git a/dojox/grid/_Scroller.js b/dojox/grid/_Scroller.js
index dbcfcd6..b20397c 100644
--- a/dojox/grid/_Scroller.js
+++ b/dojox/grid/_Scroller.js
@@ -80,7 +80,7 @@ define([
 				case 1: this.rowCount = inRowCount;
 				default: break;
 			}
-			this.defaultPageHeight = this.defaultRowHeight * this.rowsPerPage;
+			this.defaultPageHeight = (this.grid.rowHeight > 0 ? this.grid.rowHeight : this.defaultRowHeight) * this.rowsPerPage;
 			this.pageCount = this._getPageCount(this.rowCount, this.rowsPerPage);
 			this.setKeepInfo(this.keepRows);
 			this.invalidate();
@@ -151,10 +151,9 @@ define([
 		},
 		measurePage: function(inPageIndex){
 			if(this.grid.rowHeight){
-				var height = this.grid.rowHeight + 1;
 				return ((inPageIndex + 1) * this.rowsPerPage > this.rowCount ?
 					this.rowCount - inPageIndex * this.rowsPerPage :
-					this.rowsPerPage) * height;
+					this.rowsPerPage) * this.grid.rowHeight;
 					 
 			}
 			var n = this.getDefaultPageNode(inPageIndex);
diff --git a/dojox/grid/_SelectionPreserver.js b/dojox/grid/_SelectionPreserver.js
index 9e9b655..1b228c8 100644
--- a/dojox/grid/_SelectionPreserver.js
+++ b/dojox/grid/_SelectionPreserver.js
@@ -28,8 +28,8 @@ return declare("dojox.grid._SelectionPreserver", null, {
 		this._connects = [
 			connect.connect(grid, '_setStore', this, 'reset'),
 			connect.connect(grid, '_addItem', this, '_reSelectById'),
-			connect.connect(selection, 'addToSelection', lang.hitch(this, '_selectById', true)),
-			connect.connect(selection, 'deselect', lang.hitch(this, '_selectById', false)),
+			connect.connect(selection, 'onSelected', lang.hitch(this, '_selectById', true)),
+			connect.connect(selection, 'onDeselected', lang.hitch(this, '_selectById', false)),
 			connect.connect(selection, 'deselectAll', this, 'reset')
 		];
 	},
diff --git a/dojox/grid/_View.js b/dojox/grid/_View.js
index b8820d1..fe0806d 100644
--- a/dojox/grid/_View.js
+++ b/dojox/grid/_View.js
@@ -20,7 +20,7 @@ define([
 	"dojo/dnd/Avatar",
 	"dojo/dnd/Manager"
 ], function(dojo, dijit, dojox, declare, array, lang, connect, has, query,
-	win, template, Source, _Widget, _TemplatedMixin, metrics, util, html, _Builder, Avatar){
+	win, template, Source, _Widget, _TemplatedMixin, metrics, util, html, _Builder, Avatar, Manager){
 
 	// a private function
 	var getStyleText = function(inNode, inStyleText){
@@ -39,12 +39,11 @@ define([
 		defaultWidth: "18em",
 
 		// viewWidth: String
-		// 		Width for the view, in valid css unit
+		//		Width for the view, in valid css unit
 		viewWidth: "",
 
 		templateString: template,
-		
-		themeable: false,
+
 		classTag: 'dojoxGrid',
 		marginBottom: 0,
 		rowPad: 2,
@@ -198,7 +197,7 @@ define([
 
 		getColumnsWidth: function(){
 			var h = this.headerContentNode;
-			return h && h.firstChild ? h.firstChild.offsetWidth : 0; // Integer
+			return h && h.firstChild ? (h.firstChild.offsetWidth || html.style(h.firstChild, 'width')) : 0; // Integer
 		},
 
 		setColumnsWidth: function(width){
@@ -377,7 +376,7 @@ define([
 		},
 
 		_onDndDropBefore: function(source, nodes, copy){
-			if(dojo.dnd.manager().target !== this.source){
+			if(Manager.manager().target !== this.source){
 				return;
 			}
 			this.source._targetNode = this.source.targetAnchor;
@@ -392,8 +391,8 @@ define([
 		},
 
 		_onDndDrop: function(source, nodes, copy){
-			if(dojo.dnd.manager().target !== this.source){
-				if(dojo.dnd.manager().source === this.source){
+			if(Manager.manager().target !== this.source){
+				if(Manager.manager().source === this.source){
 					this._removingColumn = true;
 				}
 				return;
@@ -696,8 +695,12 @@ define([
 		// scrolling
 		lastTop: 0,
 		firstScroll:0,
+		_nativeScroll: false,
 
 		doscroll: function(inEvent){
+			if(has('ff') >= 13){
+				this._nativeScroll = true;
+			}
 			//var s = dojo.marginBox(this.headerContentNode.firstChild);
 			var isLtr = this.grid.isLeftToRight();
 			if(this.firstScroll < 2){
@@ -723,12 +726,16 @@ define([
 			if(top !== this.lastTop){
 				this.grid.scrollTo(top);
 			}
+			this._nativeScroll = false;
 		},
 
 		setScrollTop: function(inTop){
 			// 'lastTop' is a semaphore to prevent feedback-loop with doScroll above
 			this.lastTop = inTop;
-			this.scrollboxNode.scrollTop = inTop;
+			if(!this._nativeScroll){
+				//fix #15487
+				this.scrollboxNode.scrollTop = inTop;
+			}
 			return this.scrollboxNode.scrollTop;
 		},
 
@@ -827,23 +834,23 @@ define([
 			a.appendChild(b);
 			this.node = a;
 
-			var m = dojo.dnd.manager();
+			var m = Manager.manager();
 			this.oldOffsetY = m.OFFSET_Y;
 			m.OFFSET_Y = 1;
 		},
 		destroy: function(){
-			dojo.dnd.manager().OFFSET_Y = this.oldOffsetY;
+			Manager.manager().OFFSET_Y = this.oldOffsetY;
 			this.inherited(arguments);
 		}
 	});
 
-	var oldMakeAvatar = dojo.dnd.manager().makeAvatar;
-	dojo.dnd.manager().makeAvatar = function(){
+	var oldMakeAvatar = Manager.manager().makeAvatar;
+	Manager.manager().makeAvatar = function(){
 		var src = this.source;
 		if(src.viewIndex !== undefined && !html.hasClass(win.body(),"dijit_a11y")){
 			return new _GridAvatar(this);
 		}
-		return oldMakeAvatar.call(dojo.dnd.manager());
+		return oldMakeAvatar.call(Manager.manager());
 	};
 
 	return _View;
diff --git a/dojox/grid/_ViewManager.js b/dojox/grid/_ViewManager.js
index 18181e4..bcde9f2 100644
--- a/dojox/grid/_ViewManager.js
+++ b/dojox/grid/_ViewManager.js
@@ -188,13 +188,15 @@ return declare('dojox.grid._ViewManager', null, {
 
 			if(!self.grid.isLeftToRight()){
 				ds.right = l + 'px';
-				// fixed rtl, the scrollbar is on the right side in FF or WebKit
-				if (has('ff') < 4 || has('webkit')){
+				// fixed rtl, the scrollbar is on the right side in FF < 4
+				if(has('ff') < 4){
 					hs.right = l + v.getScrollbarWidth() + 'px';
-					hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px';
 				}else{
 					hs.right = l + 'px';
 				}
+				if(!has('webkit') && hs.width != 'auto'){
+					hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px';					
+				}
 			}else{
 				ds.left = l + 'px';
 				hs.left = l + 'px';
@@ -294,7 +296,8 @@ return declare('dojox.grid._ViewManager', null, {
 	},
 	
 	getFirstScrollingView: function(){
-		// summary: Returns the first grid view with a scroll bar
+		// summary:
+		//		Returns the first grid view with a scroll bar
 		for(var i=0, v; (v=this.views[i]); i++){
 			if(v.hasHScrollbar() || v.hasVScrollbar()){
 				return v;
diff --git a/dojox/grid/bidi/_BidiMixin.js b/dojox/grid/bidi/_BidiMixin.js
new file mode 100644
index 0000000..3233471
--- /dev/null
+++ b/dojox/grid/bidi/_BidiMixin.js
@@ -0,0 +1,177 @@
+define(["../../main", "dojo/_base/lang", "../_Builder", "dijit/_BidiSupport",
+"../_Grid", "../cells/_base", "../cells/dijit"],
+	function(dojox, lang, _Builder, _BidiSupport, _Grid, BaseCell, cellsDijit){
+		// module:
+		//		dojox/grid/bidi/BidiMixin
+		
+		/*=====
+		return {
+			// summary:
+			//		Module that deals with BIDI for Grid
+			// description:
+			//		There's a special need for displaying BIDI text in rtl direction in ltr GUI, or sometimes needed auto support.
+			//		"textDir" attribute should be set on Grid so that this class can be activated and responsible for text direction
+			//		Allowed values:
+			//		1. "ltr"
+			//		2. "rtl"
+			//		3. "auto" - contextual the direction of a text defined by first strong letter.
+			//		By default the same as the page direction.
+	
+			//		Arabic, Hebrew, Urdu, and Farsi (Persian) are written from right to left,
+			//		while numbers and segments of Latin (or Cyrillic or Greek) text are embedded in
+			//		this text from left to right. The dual directionality aspects of such
+			//		bidirectional (bidi) text are posing challenges to the way this text is processed and presented in computer applications.
+			//		The Unicode Bidirectional Algorithm, which is commonly used for preparation of Bidi text for display,
+			//		is not capable to reliably identify the natural base text direction for a given text.
+			//		Only a human reader can unfailingly recognize the natural base text direction for a given text.
+			//		Support for enforcing the base text direction is provided out of the box by most platforms / technologies,
+			//		but very often the default settings do not guarantee proper display of English and Arabic/Hebrew text in the
+			//		same application. See for reference:http://w3-03.ibm.com/globalization/page/publish/4353
+		};
+		=====*/
+
+		lang.extend(_Grid, {
+			/*this.textDir = textDir*/
+			setCellNodeTextDirection: function(inColIndex, inRowIndex, textDir){
+				this.getCell(inColIndex).getNode(inRowIndex).style.direction = textDir || "";
+			},
+			getCellNodeTextDirection: function(inColIndex, inRowIndex){
+				return this.getCell(inColIndex).getNode(inRowIndex).style.direction;
+			},
+			_setTextDirAttr: function(textDir){
+				this.textDir = textDir;
+				this.render();
+			}
+		});
+		
+		lang.extend(_Builder._ContentBuilder, {
+			_getTextDirStyle: function(textDir, inCell, inRowIndex){
+				// summary:
+				//		 Returns input text direction related attributes.
+				// textDir:
+				//		Cell text direction
+				// inCell:
+				//		Cell under processing
+				// inRowIndex:
+				//		Row index
+				var item = this.grid.getItem(inRowIndex), ret = "";
+				if(textDir === "auto"){
+					var name = inCell.get ? inCell.get(inRowIndex, item) : (inCell.value || inCell.defaultValue);
+					if(name){
+						textDir = _BidiSupport.prototype._checkContextual(name);
+					}
+				}
+				ret = " direction:" + textDir + ";";
+				return ret;
+			}
+		});
+
+		lang.extend(_Builder._HeaderBuilder, {
+			_getTextDirStyle: function(textDir, inCell, inValue){
+				// summary:
+				//		 Returns input text direction related attributes.
+				// textDir:
+				//		Cell text direction
+				// inCell:
+				//		Cell under processing
+				// inValue:
+				//		Header cell content
+				if(textDir === "auto"){
+					var name = inValue || inCell.name || inCell.grid.getCellName(inCell);
+					if(name){
+						textDir = _BidiSupport.prototype._checkContextual(name);
+					}
+				}
+				return (' direction:' + textDir + '; ');
+			}
+		});
+
+		lang.extend(BaseCell.Cell, {
+			// text direction UCC constants
+			LRE: '\u202A',
+			RLE: '\u202B',
+			PDF: '\u202C',
+			KEY_HANDLER: "onkeyup=' javascript:(function(){" +
+							"var target; if (event.target) target = event.target; else if (event.srcElement) target = event.srcElement; if(!target) return;"  +			
+							"var regExMatch = /[A-Za-z\u05d0-\u065f\u066a-\u06ef\u06fa-\u07ff\ufb1d-\ufdff\ufe70-\ufefc]/.exec(target.value);" +
+							"target.dir = regExMatch ? ( regExMatch[0] <= \"z\" ? \"ltr\" : \"rtl\" ) : target.dir ? target.dir : \"ltr\"; })();'",
+			_getTextDirMarkup: function(inDatum){
+				// summary:
+				//		Returns input text direction related attributes.
+				// textDir:
+				//		The control text direction
+				// inDatum:
+				//		Control text value.
+				var textDirMarkup = "", textDir = this.textDir || this.grid.textDir;
+				if(textDir){
+					if(textDir === "auto"){
+						textDirMarkup = this.KEY_HANDLER;
+						textDir = _BidiSupport.prototype._checkContextual(inDatum);
+					}
+					textDirMarkup += " dir='" + textDir + "'; ";
+				}
+				return textDirMarkup;
+			},
+			formatEditing: function(inDatum, inRowIndex){
+				this.needFormatNode(inDatum, inRowIndex);
+				return '<input class="dojoxGridInput" ' + this._getTextDirMarkup(inDatum) + ' type="text" value="' + inDatum + '">';
+			},
+			_enforceTextDirWithUcc: function(textDir, text){
+				// summary:
+				//		Wraps by UCC (Unicode control characters) option's text according to textDir
+				// textDir:
+				//		The control text direction
+				// text:
+				//		The text to be wrapped.
+				textDir = (textDir === "auto") ? _BidiSupport.prototype._checkContextual(text) : textDir;
+				return (textDir === "rtl" ? this.RLE : this.LRE) + text + this.PDF;
+			}
+		});
+
+		lang.extend(BaseCell.Select, {
+			_getValueCallOrig: dojox.grid.cells.Select.prototype.getValue,
+			getValue: function(inRowIndex){
+				var ret = this._getValueCallOrig(inRowIndex);
+				if(ret && (this.textDir || this.grid.textDir)){
+					ret = ret.replace(/\u202A|\u202B|\u202C/g, "");
+				}
+				return ret;
+			},
+			formatEditing: function(inDatum, inRowIndex){
+				this.needFormatNode(inDatum, inRowIndex);
+				var h = [ '<select dir = \"' + (this.grid.isLeftToRight() ? 'ltr' : 'rtl') + '\" class="dojoxGridSelect">' ];
+				for(var i = 0, o, v; ((o = this.options[i]) !== undefined) && ((v = this.values[i]) !== undefined); i++){
+					v = v.replace ? v.replace(/&/g, '&').replace(/</g, '<') : v;
+					o = o.replace ? o.replace(/&/g, '&').replace(/</g, '<') : o;
+					if(this.textDir || this.grid.textDir){
+						o = this._enforceTextDirWithUcc(this.textDir || this.grid.textDir, o);
+					}
+					h.push("<option", (inDatum == v ? ' selected' : ''), ' value = "' + v + '"', ">", o, "</option>");
+				}
+				h.push('</select>');
+				return h.join('');
+			}
+		});
+
+		lang.extend(cellsDijit.ComboBox, {
+			getWidgetPropsCallOrig: dojox.grid.cells.ComboBox.prototype.getWidgetProps,
+			getWidgetProps: function(inDatum){
+				var ret = this.getWidgetPropsCallOrig(inDatum);
+				if(this.textDir || this.grid.textDir){
+					ret.textDir = this.textDir || this.grid.textDir;
+				}
+				return ret;
+			}
+		});
+
+		lang.extend(cellsDijit._Widget, {
+			getWidgetPropsCallOrig: dojox.grid.cells._Widget.prototype.getWidgetProps,
+			getWidgetProps: function(inDatum){
+				var ret = this.getWidgetPropsCallOrig(inDatum);
+				if(this.textDir || this.grid.textDir){
+					ret.textDir = this.textDir || this.grid.textDir;
+				}
+				return ret;
+			}
+		});
+});
diff --git a/dojox/grid/cells/_base.js b/dojox/grid/cells/_base.js
index a5e6a31..a80e490 100644
--- a/dojox/grid/cells/_base.js
+++ b/dojox/grid/cells/_base.js
@@ -41,10 +41,10 @@ define([
 
 	var BaseCell = declare("dojox.grid.cells._Base", null, {
 		// summary:
-		//	Respresents a grid cell and contains information about column options and methods
-		//	for retrieving cell related information.
-		//	Each column in a grid layout has a cell object and most events and many methods
-		//	provide access to these objects.
+		//		Represents a grid cell and contains information about column options and methods
+		//		for retrieving cell related information.
+		//		Each column in a grid layout has a cell object and most events and many methods
+		//		provide access to these objects.
 		styles: '',
 		classes: '',
 		editable: false,
@@ -97,34 +97,37 @@ define([
 		// data source
 		format: function(inRowIndex, inItem){
 			// summary:
-			//	provides the html for a given grid cell.
+			//		provides the html for a given grid cell.
 			// inRowIndex: int
-			// grid row index
-			// returns: html for a given grid cell
+			//		grid row index
+			// returns:
+			//		html for a given grid cell
 			var f, i=this.grid.edit.info, d=this.get ? this.get(inRowIndex, inItem) : (this.value || this.defaultValue);
 			d = (d && d.replace && this.grid.escapeHTMLInData) ? d.replace(/&/g, '&').replace(/</g, '<') : d;
 			if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndex && i.cell==this))){
-				return this.formatEditing(d, inRowIndex);
+				return this.formatEditing(i.value ? i.value : d, inRowIndex);
 			}else{
 				return this._defaultFormat(d, [d, inRowIndex, this]);
 			}
 		},
 		formatEditing: function(inDatum, inRowIndex){
 			// summary:
-			//	formats the cell for editing
+			//		formats the cell for editing
 			// inDatum: anything
-			//	cell data to edit
+			//		cell data to edit
 			// inRowIndex: int
-			//	grid row index
-			// returns: string of html to place in grid cell
+			//		grid row index
+			// returns:
+			//		string of html to place in grid cell
 		},
 		// utility
 		getNode: function(inRowIndex){
 			// summary:
-			//	gets the dom node for a given grid cell.
+			//		gets the dom node for a given grid cell.
 			// inRowIndex: int
-			// grid row index
-			// returns: dom node for a given grid cell
+			//		grid row index
+			// returns:
+			//		dom node for a given grid cell
 			return this.view.getCellNode(inRowIndex, this.index);
 		},
 		getHeaderNode: function(){
@@ -143,7 +146,9 @@ define([
 		},
 		// edit support
 		applyEdit: function(inValue, inRowIndex){
-			this.grid.edit.applyCellEdit(inValue, this, inRowIndex);
+			if(this.getNode(inRowIndex)){
+				this.grid.edit.applyCellEdit(inValue, this, inRowIndex);
+			}
 		},
 		cancelEdit: function(inRowIndex){
 			this.grid.doCancelEdit(inRowIndex);
@@ -184,13 +189,13 @@ define([
 		//protected
 		formatNode: function(inNode, inDatum, inRowIndex){
 			// summary:
-			//	format the editing dom node. Use when editor is a widget.
+			//		format the editing dom node. Use when editor is a widget.
 			// inNode: dom node
-			// dom node for the editor
+			//		dom node for the editor
 			// inDatum: anything
-			//	cell data to edit
+			//		cell data to edit
 			// inRowIndex: int
-			//	grid row index
+			//		grid row index
 			if(has('ie')){
 				// IE sux bad
 				whenIdle(this, "focus", inRowIndex, inNode);
@@ -206,20 +211,20 @@ define([
 		//public
 		getValue: function(inRowIndex){
 			// summary:
-			//	returns value entered into editor
+			//		returns value entered into editor
 			// inRowIndex: int
-			// grid row index
+			//		grid row index
 			// returns:
-			//	value of editor
+			//		value of editor
 			return this.getEditNode(inRowIndex)[this._valueProp];
 		},
 		setValue: function(inRowIndex, inValue){
 			// summary:
-			//	set the value of the grid editor
+			//		set the value of the grid editor
 			// inRowIndex: int
-			// grid row index
+			//		grid row index
 			// inValue: anything
-			//	value of editor
+			//		value of editor
 			var n = this.getEditNode(inRowIndex);
 			if(n){
 				n[this._valueProp] = inValue;
@@ -227,52 +232,52 @@ define([
 		},
 		focus: function(inRowIndex, inNode){
 			// summary:
-			//	focus the grid editor
+			//		focus the grid editor
 			// inRowIndex: int
-			// grid row index
+			//		grid row index
 			// inNode: dom node
-			//	editor node
+			//		editor node
 			focusSelectNode(inNode || this.getEditNode(inRowIndex));
 		},
 		save: function(inRowIndex){
 			// summary:
-			//	save editor state
+			//		save editor state
 			// inRowIndex: int
-			// grid row index
+			//		grid row index
 			this.value = this.value || this.getValue(inRowIndex);
 			//console.log("save", this.value, inCell.index, inRowIndex);
 		},
 		restore: function(inRowIndex){
 			// summary:
-			//	restore editor state
+			//		restore editor state
 			// inRowIndex: int
-			// grid row index
+			//		grid row index
 			this.setValue(inRowIndex, this.value);
 			//console.log("restore", this.value, inCell.index, inRowIndex);
 		},
 		//protected
 		_finish: function(inRowIndex){
 			// summary:
-			//	called when editing is completed to clean up editor
+			//		called when editing is completed to clean up editor
 			// inRowIndex: int
-			// grid row index
+			//		grid row index
 			dom.setSelectable(this.grid.domNode, false);
 			this.cancelFormatNode();
 		},
 		//public
 		apply: function(inRowIndex){
 			// summary:
-			//	apply edit from cell editor
+			//		apply edit from cell editor
 			// inRowIndex: int
-			// grid row index
+			//		grid row index
 			this.applyEdit(this.getValue(inRowIndex), inRowIndex);
 			this._finish(inRowIndex);
 		},
 		cancel: function(inRowIndex){
 			// summary:
-			//	cancel cell edit
+			//		cancel cell edit
 			// inRowIndex: int
-			// grid row index
+			//		grid row index
 			this.cancelEdit(inRowIndex);
 			this._finish(inRowIndex);
 		}
@@ -313,9 +318,9 @@ define([
 		getStrAttr("cellClasses", cellDef);
 	};
 
-	var Cell = declare("dojox.grid.cells.Cell", BaseCell, {
-		// summary
-		// grid cell that provides a standard text input box upon editing
+	var Cell = BaseCell.Cell = declare("dojox.grid.cells.Cell", BaseCell, {
+		// summary:
+		//		grid cell that provides a standard text input box upon editing
 		constructor: function(){
 			this.keyFilter = this.keyFilter;
 		},
@@ -355,7 +360,7 @@ define([
 		}
 	};
 
-	var RowIndex = declare("dojox.grid.cells.RowIndex", Cell, {
+	var RowIndex = BaseCell.RowIndex = declare("dojox.grid.cells.RowIndex", Cell, {
 		name: 'Row',
 
 		postscript: function(){
@@ -369,12 +374,12 @@ define([
 		Cell.markupFactory(node, cellDef);
 	};
 
-	var Select = declare("dojox.grid.cells.Select", Cell, {
+	var Select = BaseCell.Select = declare("dojox.grid.cells.Select", Cell, {
 		// summary:
-		// grid cell that provides a standard select for editing
+		//		grid cell that provides a standard select for editing
 
 		// options: Array
-		// 		text of each item
+		//		text of each item
 		options: null,
 
 		// values: Array
@@ -382,7 +387,7 @@ define([
 		values: null,
 
 		// returnIndex: Integer
-		// 		editor returns only the index of the selected option and not the value
+		//		editor returns only the index of the selected option and not the value
 		returnIndex: -1,
 
 		constructor: function(inCell){
@@ -437,9 +442,9 @@ define([
 		}
 	};
 
-	var AlwaysEdit = declare("dojox.grid.cells.AlwaysEdit", Cell, {
+	var AlwaysEdit = BaseCell.AlwaysEdit = declare("dojox.grid.cells.AlwaysEdit", Cell, {
 		// summary:
-		// grid cell that is always in an editable state, regardless of grid editing state
+		//		grid cell that is always in an editable state, regardless of grid editing state
 		alwaysEditing: true,
 		_formatNode: function(inDatum, inRowIndex){
 			this.formatNode(this.getEditNode(inRowIndex), inDatum, inRowIndex);
@@ -454,9 +459,9 @@ define([
 		Cell.markupFactory(node, cell);
 	};
 
-	var Bool = declare("dojox.grid.cells.Bool", AlwaysEdit, {
+	var Bool = BaseCell.Bool = declare("dojox.grid.cells.Bool", AlwaysEdit, {
 		// summary:
-		// grid cell that provides a standard checkbox that is always on for editing
+		//		grid cell that provides a standard checkbox that is always on for editing
 		_valueProp: "checked",
 		formatEditing: function(inDatum, inRowIndex){
 			return '<input class="dojoxGridInput" type="checkbox"' + (inDatum ? ' checked="checked"' : '') + ' style="width: auto" />';
diff --git a/dojox/grid/cells/dijit.js b/dojox/grid/cells/dijit.js
index 94f1636..2839013 100644
--- a/dojox/grid/cells/dijit.js
+++ b/dojox/grid/cells/dijit.js
@@ -10,6 +10,7 @@ define([
 	"dojo/dom",
 	"dojo/dom-attr",
 	"dojo/dom-construct",
+	"dojo/dom-style",
 	"dojo/dom-geometry",
 	"dojo/data/ItemFileReadStore",
 	"dijit/form/DateTextBox",
@@ -21,17 +22,20 @@ define([
 	"dijit/form/NumberTextBox",
 	"dijit/form/CurrencyTextBox",
 	"dijit/form/HorizontalSlider",
+	"dijit/form/_TextBoxMixin",
 	"dijit/Editor",
 	"../util",
 	"./_base"
-], function(dojo, dojox, declare, array, lang, json, connect, has, dom, domAttr, domConstruct,
+], function(dojo, dojox, declare, array, lang, json, connect, has, dom, domAttr, domConstruct, domStyle,
 	domGeometry, ItemFileReadStore, DateTextBox, TimeTextBox, ComboBox, CheckBox, TextBox,
-	NumberSpinner, NumberTextBox, CurrencyTextBox, HorizontalSlider, Editor, util, BaseCell){
+	NumberSpinner, NumberTextBox, CurrencyTextBox, HorizontalSlider, _TextBoxMixin, Editor, util, BaseCell){
 		
 // TODO: shouldn't it be the test file's job to require these modules,
 // if it is using them?  Most of these modules aren't referenced by this file.
-	
-	var _Widget = declare("dojox.grid.cells._Widget", BaseCell, {
+
+	var exports = {};
+
+	var _Widget = exports._Widget = declare("dojox.grid.cells._Widget", BaseCell, {
 		widgetClass: TextBox,
 		constructor: function(inCell){
 			this.widget = null;
@@ -76,6 +80,7 @@ define([
 				this.widgetProps||{},
 				{
 					constraints: lang.mixin({}, this.constraint) || {}, //TODO: really just for ValidationTextBoxes
+					required: (this.constraint || {}).required,
 					value: this._unescapeHTML(inDatum)
 				}
 			);
@@ -103,15 +108,16 @@ define([
 			return undefined;
 		},
 		sizeWidget: function(inNode, inDatum, inRowIndex){
-			var
-				p = this.getNode(inRowIndex),
-				box = dojo.contentBox(p);
-			dojo.marginBox(this.widget.domNode, {w: box.w});
+			var p = this.getNode(inRowIndex);
+			dojo.marginBox(this.widget.domNode, {w: domStyle.get(p, 'width')});
 		},
 		focus: function(inRowIndex, inNode){
 			if(this.widget){
 				setTimeout(lang.hitch(this.widget, function(){
 					util.fire(this, "focus");
+					if(this.focusNode && this.focusNode.tagName === "INPUT"){
+						_TextBoxMixin.selectInputText(this.focusNode);
+					}
 				}), 0);
 			}
 		},
@@ -139,7 +145,7 @@ define([
 		}
 	};
 
-	var ComboBox = declare("dojox.grid.cells.ComboBox", _Widget, {
+	var ComboBox = exports.ComboBox = declare("dojox.grid.cells.ComboBox", _Widget, {
 		widgetClass: ComboBox,
 		getWidgetProps: function(inDatum){
 			var items=[];
@@ -170,7 +176,7 @@ define([
 		}
 	};
 
-	var DateTextBox = declare("dojox.grid.cells.DateTextBox", _Widget, {
+	var DateTextBox = exports.DateTextBox = declare("dojox.grid.cells.DateTextBox", _Widget, {
 		widgetClass: DateTextBox,
 		setValue: function(inRowIndex, inValue){
 			if(this.widget){
@@ -189,7 +195,7 @@ define([
 		_Widget.markupFactory(node, cell);
 	};
 
-	var CheckBox = declare("dojox.grid.cells.CheckBox", _Widget, {
+	var CheckBox = exports.CheckBox = declare("dojox.grid.cells.CheckBox", _Widget, {
 		widgetClass: CheckBox,
 		getValue: function(){
 			return this.widget.checked;
@@ -209,7 +215,7 @@ define([
 		_Widget.markupFactory(node, cell);
 	};
 
-	var Editor = declare("dojox.grid.cells.Editor", _Widget, {
+	var Editor = exports.Editor = declare("dojox.grid.cells.Editor", _Widget, {
 		widgetClass: Editor,
 		getWidgetProps: function(inDatum){
 			return lang.mixin({}, this.widgetProps||{}, {
@@ -219,7 +225,8 @@ define([
 		createWidget: function(inNode, inDatum, inRowIndex){
 			// widget needs its value set after creation
 			var widget = new this.widgetClass(this.getWidgetProps(inDatum), inNode);
-			connect.connect(widget, 'onLoad', lang.hitch(this, 'populateEditor'));
+			// use onLoadDeferred because onLoad may have already fired
+			widget.onLoadDeferred.then(lang.hitch(this, 'populateEditor'));
 			return widget;
 		},
 		formatNode: function(inNode, inDatum, inRowIndex){
@@ -250,6 +257,6 @@ define([
 		}
 	};
 
-	return dojox.grid.cells.dijit;
+	return exports;
 
-});
\ No newline at end of file
+});
diff --git a/dojox/grid/cells/tree.js b/dojox/grid/cells/tree.js
index cc26702..eee7b91 100644
--- a/dojox/grid/cells/tree.js
+++ b/dojox/grid/cells/tree.js
@@ -9,7 +9,12 @@ dojox.grid.cells.TreeCell = {
 	formatAggregate: function(inItem, level, inRowIndexes){
 		var f, g=this.grid, i=g.edit.info,
 			d=g.aggregator ? g.aggregator.getForCell(this, level, inItem, level === this.level ? "cnt" : this.parentCell.aggregate) : (this.value || this.defaultValue);
-		return this._defaultFormat(d, [d, level - this.level, inRowIndexes, this]);
+		var ret = this._defaultFormat(d, [d, level - this.level, inRowIndexes, this]);
+		var dir = this.textDir || this.grid.textDir;
+		if(dir && this._enforceTextDirWithUcc){
+		    ret = this._enforceTextDirWithUcc(dir, ret);
+		}
+		return ret;
 	},
 	formatIndexes: function(inRowIndexes, inItem){
 		var f, g=this.grid, i=g.edit.info,
@@ -17,7 +22,12 @@ dojox.grid.cells.TreeCell = {
 		if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndexes[0] && i.cell==this))){
 			return this.formatEditing(d, inRowIndexes[0], inRowIndexes);
 		}else{
-			return this._defaultFormat(d, [d, inRowIndexes[0], inRowIndexes, this]);
+			var ret = this._defaultFormat(d, [d, inRowIndexes[0], inRowIndexes, this]);
+			var dir = this.textDir || this.grid.textDir;
+			if(dir && this._enforceTextDirWithUcc){
+			    ret = this._enforceTextDirWithUcc(dir, ret);
+			}
+			return ret;
 		}
 	},
 	getOpenState: function(itemId){
diff --git a/dojox/grid/compatGrid.tar.gz b/dojox/grid/compatGrid.tar.gz
index 87c39c8..34321a8 100644
Binary files a/dojox/grid/compatGrid.tar.gz and b/dojox/grid/compatGrid.tar.gz differ
diff --git a/dojox/grid/enhanced/_Events.js b/dojox/grid/enhanced/_Events.js
index b0b31ae..eb487b4 100644
--- a/dojox/grid/enhanced/_Events.js
+++ b/dojox/grid/enhanced/_Events.js
@@ -15,7 +15,7 @@ return declare("dojox.grid.enhanced._Events", null, {
 	//		Methods are copied or replaced for overwriting, this might be refined once
 	//		an overall plugin architecture is set up for DataGrid.
 
-	//_events: Object
+	// _events: Object
 	//		Method map cached from dojox.grid._Events().
 	_events: null,
 
@@ -188,6 +188,7 @@ return declare("dojox.grid.enhanced._Events", null, {
 	onHeaderCellClick: function(e){
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onHeaderCellClick()
+		
 		//move focus to header.
 		this.focus.currentArea("header");
 		//invoke dojox.grid._Events.onHeaderCellClick()
diff --git a/dojox/grid/enhanced/_FocusManager.js b/dojox/grid/enhanced/_FocusManager.js
index bb417d4..b0328f1 100644
--- a/dojox/grid/enhanced/_FocusManager.js
+++ b/dojox/grid/enhanced/_FocusManager.js
@@ -20,58 +20,71 @@ var _FocusArea = declare("dojox.grid.enhanced._FocusArea", null, {
 		// name: string
 		//		Name of this area.
 		name: "",
+
+		onFocus: function(event, step){
+			// summary:
+			//		Called when this area logically gets focus.
+			// event: Event object
+			//		May be unavailable, should check before use.
+			// step: Integer
+			//		The distance in the tab sequence from last focused area to this area.
+			// returns:
+			//		whether this area is successfully focused. If not, the next area will get focus.
+
+ 			return true;
+		},
 		
-		// onFocus: function(event, step)
-		//		Called when this area logically gets focus.
-		//		event: Event object
-		//				May be unavailable, should check before use.
-		//		step: Integer
-		//				The distance in the tab sequence from last focused area to this area.
-		//		returns:
-		//				whether this area is successfully focused. If not, the next area will get focus.
-		onFocus: function(event, step){return true;},
-		
-		// onBlur: function(event, step)
-		//		Called when this area logically loses focus.
-		//		event: Event object
-		//				May be unavailable, should check before use.
-		//		step: Integer
-		//				The distance in the tab sequence from this area to the area to focus.
-		//		returns:
-		//				If Boolean, means whether this area has successfully blurred. If not, the next area to focus is still this one.
-		//				If String, means the next area to focus is given by this returned name.
-		onBlur: function(event, step){return true;},
+		onBlur: function(event, step){
+			// summary:
+			//		Called when this area logically loses focus.
+			// event: Event object
+			//		May be unavailable, should check before use.
+			// step: Integer
+			//		The distance in the tab sequence from this area to the area to focus.
+			// returns:
+			//		If Boolean, means whether this area has successfully blurred. If not, the next area to focus is still this one.
+			//		If String, means the next area to focus is given by this returned name.
+
+			return true;
+		},
 		
-		// onMove: function(rowStep, colStep, event)
-		//		Called when focus is moving around within this area.
-		//		rowStep: Integer
-		//		colStep: Integer
-		//		event: Event object
-		//				May be unavailable, should check before use.
-		onMove: function(rowStep, colStep, event){},
+		onMove: function(rowStep, colStep, event){
+			// summary:
+			//		Called when focus is moving around within this area.
+			// rowStep: Integer
+			// colStep: Integer
+			// event: Event object
+			//		May be unavailable, should check before use.
+		},
 		
-		// onKey: function(event, isBubble)
-		//		Called when some key is pressed when focus is logically in this area.
-		//		event: Event object
-		//		isBubble: Boolean
-		//				Whether is in bubble stage (true) or catch stage (false).
-		//		returns:
-		//				If you do NOT want the event to propagate any further along the area stack, return exactly false.
-		//				So if you return nothing (undefined), this event is still propagating.
-		onKey: function(event, isBubble){return true},
+		onKey: function(event, isBubble){
+			// summary:
+			//		Called when some key is pressed when focus is logically in this area.
+			// event: Event object
+			// isBubble: Boolean
+			//		Whether is in bubble stage (true) or catch stage (false).
+			// returns:
+			//		If you do NOT want the event to propagate any further along the area stack, return exactly false.
+			//		So if you return nothing (undefined), this event is still propagating.
+			return true;
+		},
 		
-		// getRegions: function()
-		//		Define the small regions (dom nodes) in this area.
-		//		returns: Array of dom nodes.
-		getRegions: function(){},
+		getRegions: function(){
+			// summary:
+			//		Define the small regions (dom nodes) in this area.
+			// returns:
+			//		Array of dom nodes.
+		},
 		
-		// onRegionFocus: function(event)
-		//		Connected to the onfocus event of the defined regions (if any)
-		onRegionFocus: function(event){},
+		onRegionFocus: function(event){
+			// summary:
+			//		Connected to the onfocus event of the defined regions (if any)
+		},
 		
-		// onRegionBlur: function(event)
-		//		Connected to the onblur event of the defined regions (if any)
-		onRegionBlur: function(event){},
+		onRegionBlur: function(event){
+			// summary:
+			//		Connected to the onblur event of the defined regions (if any)
+		},
 =====*/
 	constructor: function(area, focusManager){
 		this._fm = focusManager;
@@ -399,7 +412,7 @@ return declare("dojox.grid.enhanced._FocusManager", _FocusManager, {
 		// summary:
 		//		Overwritten
 		//		Check whether currently navigating among column headers.
-		// return:
+		// returns:
 		//		true - focus is on a certain column header | false otherwise
 		return this._areaQueue[this._currentAreaIdx] == "header";
 	},
@@ -461,15 +474,16 @@ return declare("dojox.grid.enhanced._FocusManager", _FocusManager, {
 	_delayedHeaderFocus: function(){
 		// summary:
 		//		Overwritten
-		if(this.isNavHeader()){
+		if(this.isNavHeader() && !has('ie')){
 			this.focusHeader();
 		}
 	},
 	_delayedCellFocus: function(){
 		// summary:
 		//		Overwritten
-		this.currentArea("header", true);
-		this.focusArea(this._currentAreaIdx);
+		
+		//If focus header here, the page will scroll to grid when the grid is created.
+		//this.focusArea("header");
 	},
 	_changeMenuBindNode: function(oldBindNode, newBindNode){
 		var hm = this.grid.headerMenu;
diff --git a/dojox/grid/enhanced/_Plugin.js b/dojox/grid/enhanced/_Plugin.js
index 5510739..de7ed82 100644
--- a/dojox/grid/enhanced/_Plugin.js
+++ b/dojox/grid/enhanced/_Plugin.js
@@ -10,7 +10,6 @@ define([
 return declare("dojox.grid.enhanced._Plugin", null, {
 	// summary:
 	//		Base class for all plugins.
-	//
 	// description:
 	//		Provides common plugin functionality and basic life cycle management.
 	//
@@ -20,7 +19,8 @@ return declare("dojox.grid.enhanced._Plugin", null, {
 	// |												dojox.grid.enhanced.plugins.DnD /*full class name of a plugin*/
 	// |												{"preInit": false, "dependency": ["nestedSorting"]} /*properties*/);
 	//
-	//		[Keywords] of plugin properties(case sensitive)
+	//		[Keywords] of plugin properties (case sensitive):
+	//
 	//		- "preInit": boolean, whether a plugin should be created before EnhancedGrid.postCreate(),
 	//		   false by default(plugins are created after EnhancedGrid.postCreate()).
 	//		- "dependency": array or string, plugin(s) indicated by "dependency" will be created before the current one.
@@ -29,51 +29,54 @@ return declare("dojox.grid.enhanced._Plugin", null, {
 	//
 	// example:
 	//		1. Customize default DnD plugin
-	// |	dojo.declare("mygrid.MyDnD", dojox.grid.enhanced.plugins.DnD, {
+	//
+	// |	declare("mygrid.MyDnD", dojox.grid.enhanced.plugins.DnD, {
 	// |		name:"dnd" //still reuse the plugin name
 	// |		constructor: function(inGrid, option){ ... }
 	// |	});
 	// |	dojox.grid.EnhancedGrid.registerPlugin("dnd", mygrid.MyDnD);
 	//
 	//		2. Add new plugin - PluginA
-	// |	dojo.declare("mygrid.PluginA", dojox.grid.enhanced._Plugin, {
+	//
+	// |	declare("mygrid.PluginA", dojox.grid.enhanced._Plugin, {
 	// |		name: "pA",
 	// |		constructor: function(inGrid, option){ ... }
 	// |	});
 	// |	dojox.grid.EnhancedGrid.registerPlugin("pA",mygrid.PluginA);
 	//
 	//		3. Use plugins
+	//
 	// |	dojo.require("mygrid.MyDnD");
 	// |	dojo.require("mygrid.PluginA");
-	
+	// |
 	// |	<script type="text/javascript">
 	// |		var grid = new dojox.grid.EnhancedGrid(
 	// |		{plugins: {dnd:true, pA:true}, ... }, dojo.byId("gridDiv"));
 	// |		grid.startup();
 	// |	</script>
 
-	//name: String
+	// name: String
 	//		Plugin name, e.g. 'nestedSorting', 'dnd'...
 	name: 'plugin',
 	
-	//grid: Object
+	// grid: Object
 	//		Grid that the plugin belongs to
 	grid: null,
 
-	//option: Object
+	// option: Object
 	//		Plugin properties - leveraged with default and user specified properties.
 	//		e.g. for dnd plugin, it may look like {"class": dojox.grid.enhanced.plugins.DnD, "dependency": ["nestedSorting"], ...}
 	option: {},
 
-	//_connects: Array
+	// _connects: Array
 	//		List of all connections.
 	_connects: [],
 	
-	//_subscribes: Array
+	// _subscribes: Array
 	//		List of all subscribes.
 	_subscribes: [],
 
-	//privates: Object
+	// privates: Object
 	//		Private properties/methods shouldn't be mixin-ed anytime.
 	privates: {},
 	
@@ -168,4 +171,4 @@ return declare("dojox.grid.enhanced._Plugin", null, {
 // |	dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.DnD/*class*/,
 // |		{"dependency": ["nestedSorting"]}/*Optional - properties*/);
 
-});
\ No newline at end of file
+});
diff --git a/dojox/grid/enhanced/_PluginManager.js b/dojox/grid/enhanced/_PluginManager.js
index ab75d38..a328c8f 100644
--- a/dojox/grid/enhanced/_PluginManager.js
+++ b/dojox/grid/enhanced/_PluginManager.js
@@ -12,24 +12,25 @@ define([
 var _PluginManager = declare("dojox.grid.enhanced._PluginManager", null, {
 	// summary:
 	//		Singleton plugin manager
-	//
 	// description:
-	//		Plugin manager is responsible for
+	//		Plugin manager is responsible for:
+	//
 	//		1. Loading required plugins
-	//		2. Handling collaborat	ion and dependencies among plugins
+	//		2. Handling collaboration and dependencies among plugins
+	//
+	//		Some plugin dependencies:
 	//
-	//      Some plugin dependencies:
 	//		- "columnReordering" attribute won't work when either DnD or Indirect Selections plugin is on.
 		
-	//_options: Object
+	// _options: Object
 	//		Normalized plugin options
 	_options: null,
 
-	//_plugins: Array
+	// _plugins: Array
 	//		Plugin list
 	_plugins: null,
 
-	//_connects: Array
+	// _connects: Array
 	//		Connection list
 	_connects: null,
 
@@ -96,8 +97,8 @@ var _PluginManager = declare("dojox.grid.enhanced._PluginManager", null, {
 				this._normalize(p, plugins, registry, loading);
 			}
 		}
-		//"columnReordering" attribute won't work when either DnD or Indirect Selections plugin is used.
-		if(options.dnd || options.indirectSelection){
+		//"columnReordering" attribute won't work when DnD plugin is turned on.
+		if(options.dnd){
 			options.columnReordering = false;
 		}
 		
@@ -158,7 +159,7 @@ var _PluginManager = declare("dojox.grid.enhanced._PluginManager", null, {
 		//		Load required plugin("name")
 		// name: String
 		//		Plugin name
-		// return: Object
+		// returns: Object
 		//		The newly loaded plugin
 		var option = this._options[name];
 		if(!option){ return null; } //return if no plugin option
@@ -191,7 +192,7 @@ var _PluginManager = declare("dojox.grid.enhanced._PluginManager", null, {
 		//		Check if plugin("name") existed
 		// name: String
 		//		Plugin name
-		// return: Boolean
+		// returns: Boolean
 		//		True - existed | False - not existed
 		return !!this.getPlugin(name);
 	},
@@ -200,7 +201,7 @@ var _PluginManager = declare("dojox.grid.enhanced._PluginManager", null, {
 		//		Get plugin("name")
 		// name: String
 		//		Plugin name
-		// return: Object
+		// returns: Object
 		//		Plugin instance
 		var plugins = this._plugins;
 		name = name.toLowerCase();
@@ -214,7 +215,7 @@ var _PluginManager = declare("dojox.grid.enhanced._PluginManager", null, {
 	getPluginClazz: function(clazz){
 		// summary:
 		//		Load target plugin which must be already required (require(..))
-		// clazz: class | String
+		// clazz: Class|String
 		//		Plugin class
 		if(lang.isFunction(clazz)){
 			return clazz;//return if it's already a clazz
@@ -233,7 +234,7 @@ var _PluginManager = declare("dojox.grid.enhanced._PluginManager", null, {
 		//		See if target cell(column) is fixed or not.
 		// cell: Object
 		//		Target cell(column)
-		// return: Boolean
+		// returns: Boolean
 		//		True - fixed| False - not fixed
 
 		//target cell can use Boolean attributes named "isRowSelector" or "fixedPos" to mark it's a fixed cell(column)
@@ -258,7 +259,7 @@ _PluginManager.registerPlugin = function(clazz, props){
 		//		Register plugins - TODO, a better way rather than global registry?
 		// clazz: String
 		//		Full class name, e.g. "dojox.grid.enhanced.plugins.DnD"
-		// props: Object - Optional
+		// props: Object?
 		//		Plugin properties e.g. {"dependency": ["nestedSorting"], ...}
 	if(!clazz){
 		console.warn("Failed to register plugin, class missed!");
@@ -271,4 +272,4 @@ _PluginManager.registerPlugin = function(clazz, props){
 
 return _PluginManager;
 
-});
\ No newline at end of file
+});
diff --git a/dojox/grid/enhanced/nls/EnhancedGrid.js b/dojox/grid/enhanced/nls/EnhancedGrid.js
index 0d36b36..feb0f50 100644
--- a/dojox/grid/enhanced/nls/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/EnhancedGrid.js
@@ -14,6 +14,7 @@ define({ root:
 //end v1.x content
 ,
 "ar": true,
+"bg": true,
 "ca": true,
 "cs": true,
 "da": true,
@@ -42,6 +43,7 @@ define({ root:
 "sv": true,
 "th": true,
 "tr": true,
+"uk": true,
 "zh": true,
 "zh-tw": true
 });
diff --git a/dojox/grid/enhanced/nls/Filter.js b/dojox/grid/enhanced/nls/Filter.js
index bc08970..554b82b 100644
--- a/dojox/grid/enhanced/nls/Filter.js
+++ b/dojox/grid/enhanced/nls/Filter.js
@@ -87,6 +87,7 @@ define({ root:
 //end v1.x content
 ,
 "ar": true,
+"bg": true,
 "ca": true,
 "cs": true,
 "da": true,
@@ -115,6 +116,7 @@ define({ root:
 "sv": true,
 "th": true,
 "tr": true,
+"uk": true,
 "zh": true,
 "zh-tw": true
 });
diff --git a/dojox/grid/enhanced/nls/Pagination.js b/dojox/grid/enhanced/nls/Pagination.js
index 2c693cf..431d94f 100644
--- a/dojox/grid/enhanced/nls/Pagination.js
+++ b/dojox/grid/enhanced/nls/Pagination.js
@@ -22,6 +22,7 @@ define({ root:
 //end v1.x content
 ,
 "ar": true,
+"bg": true,
 "ca": true,
 "cs": true,
 "da": true,
@@ -50,6 +51,7 @@ define({ root:
 "sv": true,
 "th": true,
 "tr": true,
+"uk": true,
 "zh": true,
 "zh-tw": true
 });
diff --git a/dojox/grid/enhanced/nls/ar/EnhancedGrid.js b/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
index ea856ed..97d1be8 100644
--- a/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "فرز منفرد",
 	nestedSort: "فرز متداخل",
-	ascending: "تصاعدي",
-	descending: "تنازلي",
+	ascending: "اضغط للفرز تصاعديا",
+	descending: "اضغط للفرز تنازليا ",
 	sortingState: "${0} - ${1}",
-	unsorted: "عدم فرز هذا العمود",
+	unsorted: "لا تقم بفرز هذا العمود",
 	indirectSelectionRadio: "الصف ${0}، اختيار منفرد، اختيار دائري",
 	indirectSelectionCheckBox: "الصف ${0}، اختيارات متعددة، مربع اختيار",
 	selectAll: "تحديد كل"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/ar/Filter.js b/dojox/grid/enhanced/nls/ar/Filter.js
index d855c76..41fb50f 100644
--- a/dojox/grid/enhanced/nls/ar/Filter.js
+++ b/dojox/grid/enhanced/nls/ar/Filter.js
@@ -1,89 +1,75 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "محو ترشيح البيانات",
-	"filterDefDialogTitle": "ترشيح البيانات",
-	"ruleTitleTemplate": "القاعدة ${0}",
-	
+	"filterDefDialogTitle": "‏ترشيح البيانات‏",
+	"ruleTitleTemplate": "قاعدة ${0}",
 	"conditionEqual": "يساوي",
-	"conditionNotEqual": "لا يساوي",
-	"conditionLess": "أصغر من",
-	"conditionLessEqual": "أصغر من أو يساوي",
-	"conditionLarger": "أكبر من",
+	"conditionNotEqual": "غير مساوي الى",
+	"conditionLess": "‏أقل من‏",
+	"conditionLessEqual": "أقل من أو يساوي",
+	"conditionLarger": "‏أكبر من‏",
 	"conditionLargerEqual": "أكبر من أو يساوي",
-	"conditionContains": "يتضمن",
-	"conditionIs": "هو",
+	"conditionContains": "يحتوي",
+	"conditionIs": "يكون",
 	"conditionStartsWith": "يبدأ بالحروف",
 	"conditionEndWith": "ينتهي بالحروف",
 	"conditionNotContain": "لا يتضمن",
 	"conditionIsNot": "ليس",
-	"conditionNotStartWith": "لا يبدأ بالحروف",
-	"conditionNotEndWith": "لا ينتهي بالحروف",
+	"conditionNotStartWith": "لا يبدأ بـ",
+	"conditionNotEndWith": "لا ينتهي بـ",
 	"conditionBefore": "قبل",
 	"conditionAfter": "بعد",
-	"conditionRange": "المدى",
+	"conditionRange": "مدى",
 	"conditionIsEmpty": "خالي",
-	
 	"all": "كل",
 	"any": "أي",
 	"relationAll": "كل القواعد",
-	"waiRelAll": "مطابقة كل القواعد التالية:",
-	"relationAny": "أية قواعد",
+	"waiRelAll": "مطابقة الكل للقواعد التالية:",
+	"relationAny": "أي قواعد",
 	"waiRelAny": "مطابقة أي من القواعد التالية:",
-	"relationMsgFront": "مطابقة",
+	"relationMsgFront": "مطابقة:",
 	"relationMsgTail": "",
 	"and": "and",
-	"or": "or",
-	
+	"or": "أو",
 	"addRuleButton": "اضافة قاعدة",
 	"waiAddRuleButton": "اضافة قاعدة جديدة",
 	"removeRuleButton": "ازالة قاعدة",
-	"waiRemoveRuleButtonTemplate": "ازالة القاعدة ${0}",
-	
+	"waiRemoveRuleButtonTemplate": "ازالة قاعدة ${0}",
 	"cancelButton": "الغاء",
-	"waiCancelButton": "الغاء مربع الحوار هذا",
+	"waiCancelButton": "الغاء هذا الحوار",
 	"clearButton": "محو",
 	"waiClearButton": "محو ترشيح البيانات",
-	"filterButton": "ترشيح البيانات",
+	"filterButton": "‏ترشيح البيانات‏",
 	"waiFilterButton": "احالة ترشيح البيانات",
-	
 	"columnSelectLabel": "العمود",
 	"waiColumnSelectTemplate": "العمود للقاعدة ${0}",
 	"conditionSelectLabel": "الشرط",
-	"waiConditionSelectTemplate": "الشرط للقاعدة ${0}",
-	"valueBoxLabel": "القيمة",
-	"waiValueBoxTemplate": "أدخل قيمة لترشيح البيانات للقاعدة ${0}",
-	
+	"waiConditionSelectTemplate": "الشرط للعمود ${0}",
+	"valueBoxLabel": "قيمة",
+	"waiValueBoxTemplate": "ادخال قيمة لترشيح بيانات القاعدة ${0}",
 	"rangeTo": "الى",
 	"rangeTemplate": "من ${0} الى ${1}",
-	
 	"statusTipHeaderColumn": "العمود",
-	"statusTipHeaderCondition": "القواعد",
+	"statusTipHeaderCondition": "قواعد",
 	"statusTipTitle": "خط ترشيح البيانات",
-	"statusTipMsg": "اضغط على خط ترشيح البيانات هنا لترشيح البيانات بناءا على القيم التي توجد في ${0}.",
+	"statusTipMsg": "اضغط خط ترشيح البيانات هنا لترشيح بيانات القيم في ${0}.",
 	"anycolumn": "أي عمود",
 	"statusTipTitleNoFilter": "خط ترشيح البيانات",
-	"statusTipTitleHasFilter": "ترشيح البيانات",
-	
-	"defaultItemsName": "بنود",
-	"filterBarMsgHasFilterTemplate": "يتم عرض ${0} من ${1} ${2}.",
-	"filterBarMsgNoFilterTemplate": "لم يتم تطبيق أي ترشيح للبيانات.",
-	
+	"statusTipTitleHasFilter": "‏ترشيح البيانات‏",
+	"statusTipRelAny": "مطابقة أية قواعد.",
+	"statusTipRelAll": "مطابقة كل القواعد.",
+	"defaultItemsName": "البنود",
+	"filterBarMsgHasFilterTemplate": "${0} من ${1} ${2} عرض.",
+	"filterBarMsgNoFilterTemplate": "لم يتم تطبيق ترشيح البيانات",
 	"filterBarDefButton": "تعريف ترشيح البيانات",
 	"waiFilterBarDefButton": "ترشيح بيانات الجدول",
-	"a11yFilterBarDefButton": "ترشيح البيانات...",
+	"a11yFilterBarDefButton": "ترشيح بيانات...",
 	"filterBarClearButton": "محو ترشيح البيانات",
 	"waiFilterBarClearButton": "محو ترشيح البيانات",
 	"closeFilterBarBtn": "اغلاق خط ترشيح البيانات",
-	
-	"clearFilterMsg": "سيؤدي هذا الى ازالة ترشيح البيانات وعرض كل السجلات المتاحة.",
+	"clearFilterMsg": "سيقوم هذا بازالة مرشح البيانات وعرض كل السجلات المتاحة.",
 	"anyColumnOption": "أي عمود",
-	
-	"trueLabel": "متحقق",
-	"falseLabel": "غير متحقق"
+	"trueLabel": "True",
+	"falseLabel": "خطأ"
 })
-//end v1.x content
 );
-
-
-
diff --git a/dojox/grid/enhanced/nls/ar/Pagination.js b/dojox/grid/enhanced/nls/ar/Pagination.js
index dd42fce..750b635 100644
--- a/dojox/grid/enhanced/nls/ar/Pagination.js
+++ b/dojox/grid/enhanced/nls/ar/Pagination.js
@@ -1,23 +1,21 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} من ${1} ${0}",
 	"firstTip": "الصفحة الأولى",
 	"lastTip": "الصفحة الأخيرة",
 	"nextTip": "الصفحة التالية",
 	"prevTip": "الصفحة السابقة",
-	"itemTitle": "بنود",
-	"pageStepLabelTemplate": "الصفحة ${0}",
-	"pageSizeLabelTemplate": "${0} بند/بنود بكل صفحة",
+	"itemTitle": "البنود",
+	"singularItemTitle": "بند",
+	"pageStepLabelTemplate": "صفحة ${0}",
+	"pageSizeLabelTemplate": "${0} بنود لكل صفحة",
 	"allItemsLabelTemplate": "كل البنود",
-	"gotoButtonTitle": "اذهب الى الصفحة المحددة",
-	"dialogTitle": "اذهب الى الصفحة",
-	"dialogIndication": "حدد رقم الصفحة",
+	"gotoButtonTitle": "اذهب الى صفحة خاصة",
+	"dialogTitle": "اذهب الى صفحة",
+	"dialogIndication": "تحديد رقم الصفحة",
 	"pageCountIndication": " (${0} صفحات)",
 	"dialogConfirm": "بدء",
 	"dialogCancel": "الغاء",
-	"all": "كل"
+	"all": "الكل"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/bg/EnhancedGrid.js b/dojox/grid/enhanced/nls/bg/EnhancedGrid.js
new file mode 100644
index 0000000..2d9e6fe
--- /dev/null
+++ b/dojox/grid/enhanced/nls/bg/EnhancedGrid.js
@@ -0,0 +1,13 @@
+define(
+({
+	singleSort: "Единично сортиране",
+	nestedSort: "Вградено сортиране",
+	ascending: "Щракнете, за да сортирате във възходящ ред",
+	descending: "Щракнете, за да сортирате в низходящ ред",
+	sortingState: "${0} - ${1}",
+	unsorted: "Не сортирайте тази колона",
+	indirectSelectionRadio: "Ред ${0}, единичен избор, радио кутия",
+	indirectSelectionCheckBox: "Ред ${0}, множествен избор, поле за отметка",
+	selectAll: "Избери всички"
+})
+);
diff --git a/dojox/grid/enhanced/nls/bg/Filter.js b/dojox/grid/enhanced/nls/bg/Filter.js
new file mode 100644
index 0000000..d7f6d69
--- /dev/null
+++ b/dojox/grid/enhanced/nls/bg/Filter.js
@@ -0,0 +1,75 @@
+define(
+({
+	"clearFilterDialogTitle": "Изчисти филтър",
+	"filterDefDialogTitle": "Филтър",
+	"ruleTitleTemplate": "Правило ${0}",
+	"conditionEqual": "равен",
+	"conditionNotEqual": "не е равен",
+	"conditionLess": "по-малък от",
+	"conditionLessEqual": "по-малък от или равен",
+	"conditionLarger": "по-голям от",
+	"conditionLargerEqual": "по-голям от или равен",
+	"conditionContains": "съдържа",
+	"conditionIs": "е",
+	"conditionStartsWith": "започва с",
+	"conditionEndWith": "завършва с",
+	"conditionNotContain": "не съдържа",
+	"conditionIsNot": "не е",
+	"conditionNotStartWith": "не започва с",
+	"conditionNotEndWith": "не завършва с",
+	"conditionBefore": "преди",
+	"conditionAfter": "след",
+	"conditionRange": "обхват",
+	"conditionIsEmpty": "празен",
+	"all": "всички",
+	"any": "който и да било",
+	"relationAll": "всички правила",
+	"waiRelAll": "Комбинирай всички следни правила:",
+	"relationAny": "които и да било правила",
+	"waiRelAny": "Комбинирай които и да било от следните правила:",
+	"relationMsgFront": "Комбинирай:",
+	"relationMsgTail": "",
+	"and": "и",
+	"or": "или",
+	"addRuleButton": "Добави правило",
+	"waiAddRuleButton": "Добави ново правило",
+	"removeRuleButton": "Премахни правило",
+	"waiRemoveRuleButtonTemplate": "Премахни правило ${0}",
+	"cancelButton": "Отмени",
+	"waiCancelButton": "Отмени този диалог",
+	"clearButton": "Изчисти",
+	"waiClearButton": "Изчисти филтъра",
+	"filterButton": "Филтър",
+	"waiFilterButton": "Подай филтър",
+	"columnSelectLabel": "Колона",
+	"waiColumnSelectTemplate": "Колона за правило ${0}",
+	"conditionSelectLabel": "Условие",
+	"waiConditionSelectTemplate": "Условие за правило ${0}",
+	"valueBoxLabel": "Стойност",
+	"waiValueBoxTemplate": "Въведи стойност за филтриране на правило ${0}",
+	"rangeTo": "до",
+	"rangeTemplate": "от ${0} до ${1}",
+	"statusTipHeaderColumn": "Колона",
+	"statusTipHeaderCondition": "Правила",
+	"statusTipTitle": "Лента с филтри",
+	"statusTipMsg": "Щракнете върху лентата с филтри тук, за да филтрирате стойностите в ${0}.",
+	"anycolumn": "която и да било колона",
+	"statusTipTitleNoFilter": "Лента с филтри",
+	"statusTipTitleHasFilter": "Филтър",
+	"statusTipRelAny": "Комбинирай които и да било правила.",
+	"statusTipRelAll": "Комбинирай всички правила.",
+	"defaultItemsName": "елементи",
+	"filterBarMsgHasFilterTemplate": "Показани ${0} от ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "Не е приложен филтър",
+	"filterBarDefButton": "Определи филтър",
+	"waiFilterBarDefButton": "Филтрирай таблицата",
+	"a11yFilterBarDefButton": "Филтър...",
+	"filterBarClearButton": "Изчисти филтър",
+	"waiFilterBarClearButton": "Изчисти филтъра",
+	"closeFilterBarBtn": "Затвори лентата с филтри",
+	"clearFilterMsg": "Това ще премахне филтъра и ще покаже всички налични записи.",
+	"anyColumnOption": "Която и да било колона",
+	"trueLabel": "Вярно",
+	"falseLabel": "Невярно"
+})
+);
diff --git a/dojox/grid/enhanced/nls/bg/Pagination.js b/dojox/grid/enhanced/nls/bg/Pagination.js
new file mode 100644
index 0000000..82cdfd4
--- /dev/null
+++ b/dojox/grid/enhanced/nls/bg/Pagination.js
@@ -0,0 +1,21 @@
+define(
+({
+	"descTemplate": "${2} - ${3} от ${1} ${0}",
+	"firstTip": "Първа страница",
+	"lastTip": "Последна страница",
+	"nextTip": "Следваща страница",
+	"prevTip": "Предишна страница",
+	"itemTitle": "елементи",
+	"singularItemTitle": "елемент",
+	"pageStepLabelTemplate": "Страница ${0}",
+	"pageSizeLabelTemplate": "${0} елементи на страница",
+	"allItemsLabelTemplate": "Всички елементи",
+	"gotoButtonTitle": "Отиди до конкретна страница",
+	"dialogTitle": "Отиди до страница",
+	"dialogIndication": "Укажи номер на страница",
+	"pageCountIndication": " (${0} страници)",
+	"dialogConfirm": "Отиди",
+	"dialogCancel": "Отмени",
+	"all": "Всички"
+})
+);
diff --git a/dojox/grid/enhanced/nls/ca/EnhancedGrid.js b/dojox/grid/enhanced/nls/ca/EnhancedGrid.js
index 5beb6ce..6e812b8 100644
--- a/dojox/grid/enhanced/nls/ca/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ca/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Ordre únic",
 	nestedSort: "Ordre imbricat",
-	ascending: "Ascendent",
-	descending: "Descendent",
+	ascending: "Feu clic per ordenar de forma ascendent",
+	descending: "Feu clic per ordenar de forma descendent",
 	sortingState: "${0} - ${1}",
 	unsorted: "No ordenis aquesta finestra",
-	indirectSelectionRadio: "Fila ${0}, selecció única, quadre d'opció",
+	indirectSelectionRadio: "Fila ${0}, selecció individual, quadre d'opció",
 	indirectSelectionCheckBox: "Fila ${0}, selecció múltiple, quadre de selecció",
-	selectAll: "Seleccionar-ho tot"
+	selectAll: "Selecciona-ho tot"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/ca/Filter.js b/dojox/grid/enhanced/nls/ca/Filter.js
index a544f9e..90713a9 100644
--- a/dojox/grid/enhanced/nls/ca/Filter.js
+++ b/dojox/grid/enhanced/nls/ca/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Netejar el filtre",
 	"filterDefDialogTitle": "Filtre",
 	"ruleTitleTemplate": "Regla ${0}",
-	
 	"conditionEqual": "igual que",
 	"conditionNotEqual": "no és igual que",
 	"conditionLess": "és menys que",
@@ -22,41 +20,35 @@ define(
 	"conditionBefore": "abans",
 	"conditionAfter": "després",
 	"conditionRange": "interval",
-	"conditionIsEmpty": "és buida",
-	
+	"conditionIsEmpty": "és buit",
 	"all": "tot",
 	"any": "qualsevol",
 	"relationAll": "totes les regles",
 	"waiRelAll": "Fes coincidir totes les regles següents:",
 	"relationAny": "qualsevol regla",
 	"waiRelAny": "Fes coincidir qualsevol de les regles següents:",
-	"relationMsgFront": "Coincidència",
+	"relationMsgFront": "Coincidència:",
 	"relationMsgTail": "",
 	"and": "i",
 	"or": "o",
-	
 	"addRuleButton": "Afegeix regla",
 	"waiAddRuleButton": "Afegeix una regla nova",
 	"removeRuleButton": "Elimina regla",
 	"waiRemoveRuleButtonTemplate": "Elimina la regla ${0}",
-	
 	"cancelButton": "Cancel·la",
 	"waiCancelButton": "Cancel·la aquest diàleg",
 	"clearButton": "Esborra",
 	"waiClearButton": "Neteja el filtre",
 	"filterButton": "Filtre",
 	"waiFilterButton": "Envia el filtre",
-	
 	"columnSelectLabel": "Columna",
 	"waiColumnSelectTemplate": "Columna per a la regla ${0}",
 	"conditionSelectLabel": "Condició",
 	"waiConditionSelectTemplate": "Condició per a la regla ${0}",
 	"valueBoxLabel": "Valor",
 	"waiValueBoxTemplate": "Especifiqueu el valor de filtre per a la regla ${0}",
-	
 	"rangeTo": "a",
 	"rangeTemplate": "de ${0} a ${1}",
-	
 	"statusTipHeaderColumn": "Columna",
 	"statusTipHeaderCondition": "Regles",
 	"statusTipTitle": "Barra de filtre",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "Filtre",
 	"statusTipRelAny": "Coincideix amb qualsevol regla.",
 	"statusTipRelAll": "Coincideix amb totes les regles.",
-	
 	"defaultItemsName": "elements",
 	"filterBarMsgHasFilterTemplate": "Es mostren ${0} de ${1} ${2}.",
 	"filterBarMsgNoFilterTemplate": "No s'ha aplicat cap filtre",
-	
 	"filterBarDefButton": "Defineix filtre",
 	"waiFilterBarDefButton": "Filtra la taula",
 	"a11yFilterBarDefButton": "Filtre...",
 	"filterBarClearButton": "Netejar filtre",
 	"waiFilterBarClearButton": "Neteja el filtre",
 	"closeFilterBarBtn": "Tancar la barra de filtre",
-	
 	"clearFilterMsg": "Això eliminarà el filtre i mostrarà tots els registres disponibles.",
 	"anyColumnOption": "Qualsevol columna",
-	
 	"trueLabel": "Cert",
 	"falseLabel": "Fals"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/ca/Pagination.js b/dojox/grid/enhanced/nls/ca/Pagination.js
index e04c5dc..d12350c 100644
--- a/dojox/grid/enhanced/nls/ca/Pagination.js
+++ b/dojox/grid/enhanced/nls/ca/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} de ${1} ${0}",
 	"firstTip": "Primera pàgina",
@@ -17,7 +16,6 @@ define(
 	"pageCountIndication": " (${0} pàgines)",
 	"dialogConfirm": "Vés-hi",
 	"dialogCancel": "Cancel·la",
-	"all": "tot"
+	"all": "Tots"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/cs/EnhancedGrid.js b/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
index 6a2fcb5..3dda97d 100644
--- a/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
-	singleSort: "Jednotlivé řazení",
+	singleSort: "Jednoduché řazení",
 	nestedSort: "Vnořené řazení",
-	ascending: "Vzestupně",
-	descending: "Sestupně",
+	ascending: "Po klepnutí bude řazeno vzestupně",
+	descending: "Po klepnutí bude řazeno sestupně",
 	sortingState: "${0} - ${1}",
-	unsorted: "Neřadit tento sloupec",
+	unsorted: "Tento sloupec neřadit",
 	indirectSelectionRadio: "Řádek ${0}, jednotlivý výběr, přepínač",
 	indirectSelectionCheckBox: "Řádek ${0}, vícenásobný výběr, zaškrtávací políčko",
 	selectAll: "Vybrat vše"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/cs/Filter.js b/dojox/grid/enhanced/nls/cs/Filter.js
index ae25317..87fe447 100644
--- a/dojox/grid/enhanced/nls/cs/Filter.js
+++ b/dojox/grid/enhanced/nls/cs/Filter.js
@@ -1,88 +1,75 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Vymazat filtr",
 	"filterDefDialogTitle": "Filtr",
 	"ruleTitleTemplate": "Pravidlo ${0}",
-	
 	"conditionEqual": "rovná se",
 	"conditionNotEqual": "nerovná se",
-	"conditionLess": "méně než",
-	"conditionLessEqual": "méně nebo rovno",
-	"conditionLarger": "více než",
-	"conditionLargerEqual": "více nebo rovno",
+	"conditionLess": "je menší než",
+	"conditionLessEqual": "menší nebo rovno",
+	"conditionLarger": "je větší než",
+	"conditionLargerEqual": "větší nebo rovno",
 	"conditionContains": "obsahuje",
 	"conditionIs": "je",
-	"conditionStartsWith": "začíná",
-	"conditionEndWith": "končí",
+	"conditionStartsWith": "začíná na",
+	"conditionEndWith": "končí na",
 	"conditionNotContain": "neobsahuje",
 	"conditionIsNot": "není",
-	"conditionNotStartWith": "nezačíná",
-	"conditionNotEndWith": "nekončí",
+	"conditionNotStartWith": "nezačíná na",
+	"conditionNotEndWith": "nekončí na",
 	"conditionBefore": "před",
 	"conditionAfter": "po",
 	"conditionRange": "rozsah",
 	"conditionIsEmpty": "je prázdné",
-	
 	"all": "vše",
-	"any": "jakékoli",
+	"any": "libovolné",
 	"relationAll": "všechna pravidla",
-	"waiRelAll": "Porovnat všechna tato pravidla:",
-	"relationAny": "jakákoli pravidla",
-	"waiRelAny": "Porovnat jakákoli z těchto pravidel:",
-	"relationMsgFront": "Shoda",
+	"waiRelAll": "Vyhovovat všem následujícím pravidlům:",
+	"relationAny": "libovolné pravidlo",
+	"waiRelAny": "Vyhovovat libovolnému z následujících pravidel:",
+	"relationMsgFront": "Vyhovovat:",
 	"relationMsgTail": "",
 	"and": "a",
 	"or": "nebo",
-	
 	"addRuleButton": "Přidat pravidlo",
 	"waiAddRuleButton": "Přidat nové pravidlo",
 	"removeRuleButton": "Odebrat pravidlo",
 	"waiRemoveRuleButtonTemplate": "Odebrat pravidlo ${0}",
-	
 	"cancelButton": "Storno",
 	"waiCancelButton": "Zrušit toto dialogové okno",
 	"clearButton": "Vymazat",
-	"waiClearButton": "Vymazat filtr",
-	"filterButton": "Filtr",
-	"waiFilterButton": "Odeslat filtr",
-	
+	"waiClearButton": "Vymazat tento filtr",
+	"filterButton": "Filtrovat",
+	"waiFilterButton": "Odeslat tento filtr",
 	"columnSelectLabel": "Sloupec",
-	"waiColumnSelectTemplate": "Sloupec pro pravidlo ${0}",
+	"waiColumnSelectTemplate": "Sloupec pravidla ${0}",
 	"conditionSelectLabel": "Podmínka",
-	"waiConditionSelectTemplate": "Podmínka pro pravidlo ${0}",
+	"waiConditionSelectTemplate": "Podmínka pravidla ${0}",
 	"valueBoxLabel": "Hodnota",
-	"waiValueBoxTemplate": "Zadejte hodnotu do filtru pro pravidlo ${0}",
-	
+	"waiValueBoxTemplate": "Zadat hodnotu filtru pro pravidlo ${0}",
 	"rangeTo": "do",
-	"rangeTemplate": "z ${0} do ${1}",
-	
+	"rangeTemplate": "od ${0} do ${1}",
 	"statusTipHeaderColumn": "Sloupec",
 	"statusTipHeaderCondition": "Pravidla",
-	"statusTipTitle": "Panel filtrování",
-	"statusTipMsg": "Klepněte zde na panel filtrování, abyste filtrovali hodnoty v ${0}.",
-	"anycolumn": "jakýkoli sloupec",
-	"statusTipTitleNoFilter": "Panel filtrování",
+	"statusTipTitle": "Panel filtru",
+	"statusTipMsg": "Klepnutím sem na panel filtru provedete filtrování podle hodnoty pro ${0}.",
+	"anycolumn": "libovolný sloupec",
+	"statusTipTitleNoFilter": "Panel filtru",
 	"statusTipTitleHasFilter": "Filtr",
 	"statusTipRelAny": "Vyhovovat libovolnému pravidlu",
 	"statusTipRelAll": "Vyhovovat všem pravidlům",
-	
 	"defaultItemsName": "položek",
-	"filterBarMsgHasFilterTemplate": "${0} z ${1} ${2} zobrazeno.",
-	"filterBarMsgNoFilterTemplate": "Není použitý žádný filtr",
-	
+	"filterBarMsgHasFilterTemplate": "Zobrazeno ${0} z ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "Není použit žádný filtr",
 	"filterBarDefButton": "Definovat filtr",
 	"waiFilterBarDefButton": "Filtrovat tabulku",
 	"a11yFilterBarDefButton": "Filtrovat...",
 	"filterBarClearButton": "Vymazat filtr",
-	"waiFilterBarClearButton": "Vymazat filtr",
-	"closeFilterBarBtn": "Zavřít panel filtrování",
-	
-	"clearFilterMsg": "Tímto se odebere filtr a zobrazí všechny dostupné záznamy.",
-	"anyColumnOption": "Jakýkoli sloupec",
-	
+	"waiFilterBarClearButton": "Vymazat tento filtr",
+	"closeFilterBarBtn": "Zavřít panel filtru",
+	"clearFilterMsg": "Tato akce odebere filtr a zobrazí se všechny dostupné záznamy.",
+	"anyColumnOption": "Libovolné sloupec",
 	"trueLabel": "Pravda",
 	"falseLabel": "Nepravda"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/cs/Pagination.js b/dojox/grid/enhanced/nls/cs/Pagination.js
index 39f5dc6..e0828b4 100644
--- a/dojox/grid/enhanced/nls/cs/Pagination.js
+++ b/dojox/grid/enhanced/nls/cs/Pagination.js
@@ -1,24 +1,21 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} z ${1} ${0}",
 	"firstTip": "První stránka",
 	"lastTip": "Poslední stránka",
 	"nextTip": "Další stránka",
 	"prevTip": "Předchozí stránka",
-	"itemTitle": "položky",
+	"itemTitle": "položek",
 	"singularItemTitle": "položka",
 	"pageStepLabelTemplate": "Stránka ${0}",
-	"pageSizeLabelTemplate": "${0} položek na stránku",
+	"pageSizeLabelTemplate": "${0} položek na stránce",
 	"allItemsLabelTemplate": "Všechny položky",
-	"gotoButtonTitle": "Přejít na specifickou stránku",
+	"gotoButtonTitle": "Přejít na určitou stránku",
 	"dialogTitle": "Přejít na stránku",
-	"dialogIndication": "Uvést číslo stránky",
-	"pageCountIndication": " (${0} stránky)",
+	"dialogIndication": "Zadat číslo stránky",
+	"pageCountIndication": " (Počet stránek: ${0})",
 	"dialogConfirm": "Přejít",
 	"dialogCancel": "Storno",
-	"all": "vše"
+	"all": "Vše"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/da/EnhancedGrid.js b/dojox/grid/enhanced/nls/da/EnhancedGrid.js
index c55db2a..16aa273 100644
--- a/dojox/grid/enhanced/nls/da/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/da/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
-	singleSort: "Enkelt sortering",
+	singleSort: "Enkel sortering",
 	nestedSort: "Indlejret sortering",
-	ascending: "Stigende",
-	descending: "Faldende",
+	ascending: "Klik for at sortere stigende",
+	descending: "Klik for at sortere faldende",
 	sortingState: "${0} - ${1}",
 	unsorted: "Sortér ikke denne kolonne",
 	indirectSelectionRadio: "Række ${0}, enkelt valg, valgknap",
 	indirectSelectionCheckBox: "Række ${0}, flere valg, afkrydsningsfelt",
 	selectAll: "Markér alle"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/da/Filter.js b/dojox/grid/enhanced/nls/da/Filter.js
index 0f38e3a..1eb9fb6 100644
--- a/dojox/grid/enhanced/nls/da/Filter.js
+++ b/dojox/grid/enhanced/nls/da/Filter.js
@@ -1,12 +1,10 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Ryd filter",
 	"filterDefDialogTitle": "Filter",
 	"ruleTitleTemplate": "Regel ${0}",
-	
-	"conditionEqual": "lig med",
-	"conditionNotEqual": "er forskellig fra",
+	"conditionEqual": "er lig med",
+	"conditionNotEqual": "er ikke lig med",
 	"conditionLess": "er mindre end",
 	"conditionLessEqual": "mindre end eller lig med",
 	"conditionLarger": "er større end",
@@ -21,42 +19,36 @@ define(
 	"conditionNotEndWith": "slutter ikke med",
 	"conditionBefore": "før",
 	"conditionAfter": "efter",
-	"conditionRange": "interval",
+	"conditionRange": "område",
 	"conditionIsEmpty": "er tom",
-	
 	"all": "alle",
-	"any": "vilkårlig",
+	"any": "nogle af",
 	"relationAll": "alle regler",
 	"waiRelAll": "Matcher alle følgende regler:",
 	"relationAny": "vilkårlige regler",
 	"waiRelAny": "Matcher en eller flere af følgende regler:",
-	"relationMsgFront": "Match",
+	"relationMsgFront": "Match:",
 	"relationMsgTail": "",
 	"and": "og",
 	"or": "eller",
-	
 	"addRuleButton": "Tilføj regel",
 	"waiAddRuleButton": "Tilføj en ny regel",
 	"removeRuleButton": "Fjern regel",
 	"waiRemoveRuleButtonTemplate": "Fjern reglen ${0}",
-	
 	"cancelButton": "Annullér",
 	"waiCancelButton": "Annullér denne dialogboks",
 	"clearButton": "Ryd",
-	"waiClearButton": "Ryd filtret",
+	"waiClearButton": "Ryd filteret",
 	"filterButton": "Filter",
-	"waiFilterButton": "Send filtret",
-	
+	"waiFilterButton": "Send filteret",
 	"columnSelectLabel": "Kolonne",
 	"waiColumnSelectTemplate": "Kolonne for reglen ${0}",
 	"conditionSelectLabel": "Betingelse",
 	"waiConditionSelectTemplate": "Betingelse for reglen ${0}",
 	"valueBoxLabel": "Værdi",
-	"waiValueBoxTemplate": "Angiv værdi, der skal filtreres efter for reglen ${0}",
-	
+	"waiValueBoxTemplate": "Angiv værdi for filtrering for regel ${0}",
 	"rangeTo": "til",
 	"rangeTemplate": "fra ${0} til ${1}",
-	
 	"statusTipHeaderColumn": "Kolonne",
 	"statusTipHeaderCondition": "Regler",
 	"statusTipTitle": "Filterlinje",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "Filter",
 	"statusTipRelAny": "Matcher en hvilken som helst regel.",
 	"statusTipRelAll": "Matcher alle regler.",
-	
 	"defaultItemsName": "elementer",
 	"filterBarMsgHasFilterTemplate": "${0} af ${1} ${2} vist.",
 	"filterBarMsgNoFilterTemplate": "Intet filter anvendt",
-	
 	"filterBarDefButton": "Definér filter",
 	"waiFilterBarDefButton": "Filtrér tabellen",
 	"a11yFilterBarDefButton": "Filtrér...",
 	"filterBarClearButton": "Ryd filter",
-	"waiFilterBarClearButton": "Ryd filtret",
+	"waiFilterBarClearButton": "Ryd filteret",
 	"closeFilterBarBtn": "Luk filterlinje",
-	
-	"clearFilterMsg": "Denne funktion fjerner filtret og viser alle tilgængelige records.",
+	"clearFilterMsg": "Denne funktion fjerner filteret og viser alle tilgængelige records.",
 	"anyColumnOption": "Vilkårlig kolonne",
-	
 	"trueLabel": "Sand",
 	"falseLabel": "Falsk"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/da/Pagination.js b/dojox/grid/enhanced/nls/da/Pagination.js
index 357ed4d..50b1674 100644
--- a/dojox/grid/enhanced/nls/da/Pagination.js
+++ b/dojox/grid/enhanced/nls/da/Pagination.js
@@ -1,7 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"descTemplate": "${2} - ${3} af ${1} ${0}",
+	"descTemplate": "${2}-${3} af ${1} ${0}",
 	"firstTip": "Første side",
 	"lastTip": "Sidste side",
 	"nextTip": "Næste side",
@@ -13,11 +12,10 @@ define(
 	"allItemsLabelTemplate": "Alle elementer",
 	"gotoButtonTitle": "Gå til en bestemt side",
 	"dialogTitle": "Gå til side",
-	"dialogIndication": "Angiv sidetallet",
+	"dialogIndication": "Angiv sidenummeret",
 	"pageCountIndication": " (${0} sider)",
-	"dialogConfirm": "Gå",
+	"dialogConfirm": "Udfør",
 	"dialogCancel": "Annullér",
-	"all": "alle"
+	"all": "Alle"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/de/EnhancedGrid.js b/dojox/grid/enhanced/nls/de/EnhancedGrid.js
index 4891395..f83550a 100644
--- a/dojox/grid/enhanced/nls/de/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/de/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
-	singleSort: "Einzelne Sortierung",
+	singleSort: "Einfache Sortierung",
 	nestedSort: "Verschachtelte Sortierung",
-	ascending: "Aufsteigend",
-	descending: "Absteigend",
+	ascending: "Für aufsteigende Sortierung hier klicken",
+	descending: "Für absteigende Sortierung hier klicken",
 	sortingState: "${0} - ${1}",
 	unsorted: "Diese Spalte nicht sortieren",
-	indirectSelectionRadio: "Zeile ${0}, einzelne Auswahl, Optionsfeld",
+	indirectSelectionRadio: "Zeile ${0}, Einzelauswahl, Optionsfeld",
 	indirectSelectionCheckBox: "Zeile ${0}, Mehrfachauswahl, Kontrollkästchen",
 	selectAll: "Alles auswählen"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/de/Filter.js b/dojox/grid/enhanced/nls/de/Filter.js
index 76856b4..76a9e58 100644
--- a/dojox/grid/enhanced/nls/de/Filter.js
+++ b/dojox/grid/enhanced/nls/de/Filter.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Filter löschen",
 	"filterDefDialogTitle": "Filter",
 	"ruleTitleTemplate": "Regel ${0}",
-	
 	"conditionEqual": "gleich",
-	"conditionNotEqual": "ungleich",
-	"conditionLess": "kleiner als",
+	"conditionNotEqual": "ist nicht gleich",
+	"conditionLess": "ist kleiner als",
 	"conditionLessEqual": "kleiner-gleich",
-	"conditionLarger": "größer als",
+	"conditionLarger": "ist größer als",
 	"conditionLargerEqual": "größer-gleich",
 	"conditionContains": "enthält",
 	"conditionIs": "ist",
@@ -19,70 +17,59 @@ define(
 	"conditionIsNot": "ist nicht",
 	"conditionNotStartWith": "beginnt nicht mit",
 	"conditionNotEndWith": "endet nicht mit",
-	"conditionBefore": "vorher",
-	"conditionAfter": "danach",
+	"conditionBefore": "vor",
+	"conditionAfter": "nach",
 	"conditionRange": "Bereich",
 	"conditionIsEmpty": "ist leer",
-	
 	"all": "alle",
-	"any": "beliebige",
-	"relationAll": "alle Regeln",
-	"waiRelAll": "Stimmt mit allen der folgenden Regeln überein:",
-	"relationAny": "beliebige Regeln",
-	"waiRelAny": "Stimmt mit einer beliebigen der folgenden Regeln überein:",
-	"relationMsgFront": "Übereinstimmung",
+	"any": "beliebig",
+	"relationAll": "Alle Regeln",
+	"waiRelAll": "Übereinstimmung mit allen folgenden Regeln:",
+	"relationAny": "Beliebige Regeln",
+	"waiRelAny": "Übereinstimmung mit einer beliebigen der folgenden Regeln:",
+	"relationMsgFront": "Übereinstimmung:",
 	"relationMsgTail": "",
 	"and": "und",
 	"or": "oder",
-	
 	"addRuleButton": "Regel hinzufügen",
 	"waiAddRuleButton": "Neue Regel hinzufügen",
 	"removeRuleButton": "Regel entfernen",
 	"waiRemoveRuleButtonTemplate": "Regel ${0} entfernen",
-	
 	"cancelButton": "Abbrechen",
-	"waiCancelButton": "Diesen Dialog abbrechen",
-	"clearButton": "Löschen",
-	"waiClearButton": "Den Filter löschen",
+	"waiCancelButton": "Dialog abbrechen",
+	"clearButton": "Abwählen",
+	"waiClearButton": "Filter abwählen",
 	"filterButton": "Filter",
-	"waiFilterButton": "Den Filter abschicken",
-	
+	"waiFilterButton": "Filter übergeben",
 	"columnSelectLabel": "Spalte",
 	"waiColumnSelectTemplate": "Spalte für Regel ${0}",
 	"conditionSelectLabel": "Bedingung",
 	"waiConditionSelectTemplate": "Bedingung für Regel ${0}",
 	"valueBoxLabel": "Wert",
-	"waiValueBoxTemplate": "Wert eingeben, um nach Regel ${0} zu filtern",
-	
+	"waiValueBoxTemplate": "Filterwert für Regel ${0} eingeben",
 	"rangeTo": "bis",
 	"rangeTemplate": "von ${0} bis ${1}",
-	
 	"statusTipHeaderColumn": "Spalte",
 	"statusTipHeaderCondition": "Regeln",
 	"statusTipTitle": "Filterleiste",
-	"statusTipMsg": "Klicken Sie auf die Filterleiste hier, um nach Werten in ${0} zu filtern.",
-	"anycolumn": "beliebige Spalte",
+	"statusTipMsg": "Kicken Sie auf die Filterleiste, um nach Werten in ${0} zu filtern.",
+	"anycolumn": "Beliebige Spalte",
 	"statusTipTitleNoFilter": "Filterleiste",
 	"statusTipTitleHasFilter": "Filter",
-	"statusTipRelAny": "Übereinstimmung mit einer oder mehreren beliebigen Regeln.",
-	"statusTipRelAll": "Übereinstimmung mit allen Regeln.",
-	
-	"defaultItemsName": "Elemente",
+	"statusTipRelAny": "Beliebige Regeln abgleichen.",
+	"statusTipRelAll": "Alle Regel abgleichen.",
+	"defaultItemsName": "Einträge",
 	"filterBarMsgHasFilterTemplate": "${0} von ${1} ${2} angezeigt.",
 	"filterBarMsgNoFilterTemplate": "Kein Filter angewendet",
-	
 	"filterBarDefButton": "Filter definieren",
-	"waiFilterBarDefButton": "Die Tabelle filtern",
+	"waiFilterBarDefButton": "Tabelle filtern",
 	"a11yFilterBarDefButton": "Filter...",
 	"filterBarClearButton": "Filter löschen",
-	"waiFilterBarClearButton": "Den Filter löschen",
+	"waiFilterBarClearButton": "Filter abwählen",
 	"closeFilterBarBtn": "Filterleiste schließen",
-	
-	"clearFilterMsg": "Damit wird der Filter gelöscht und es werden alle verfügbaren Sätze angezeigt.",
+	"clearFilterMsg": "Diese Aktion entfernt den Filter und zeigt alle verfügbaren Datensätze an.",
 	"anyColumnOption": "Beliebige Spalte",
-	
 	"trueLabel": "Wahr",
 	"falseLabel": "Falsch"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/de/Pagination.js b/dojox/grid/enhanced/nls/de/Pagination.js
index 741ce0a..a0e58ea 100644
--- a/dojox/grid/enhanced/nls/de/Pagination.js
+++ b/dojox/grid/enhanced/nls/de/Pagination.js
@@ -1,24 +1,21 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} von ${1} ${0}",
 	"firstTip": "Erste Seite",
 	"lastTip": "Letzte Seite",
 	"nextTip": "Nächste Seite",
 	"prevTip": "Vorherige Seite",
-	"itemTitle": "Elemente",
-	"singularItemTitle": "Element",
+	"itemTitle": "Einträge",
+	"singularItemTitle": "Eintrag",
 	"pageStepLabelTemplate": "Seite ${0}",
-	"pageSizeLabelTemplate": "${0} Elemente pro Seite",
-	"allItemsLabelTemplate": "Alle Elemente",
-	"gotoButtonTitle": "Bestimmte Seite aufrufen",
-	"dialogTitle": "Seite aufrufen",
-	"dialogIndication": "Seitenzahl angeben",
+	"pageSizeLabelTemplate": "${0} Einträge pro Seite",
+	"allItemsLabelTemplate": "Alle Einträge",
+	"gotoButtonTitle": "Wechsel zu einer bestimmten Seite",
+	"dialogTitle": "Wechseln zur Seite",
+	"dialogIndication": "Seitennummer angeben",
 	"pageCountIndication": " (${0} Seiten)",
 	"dialogConfirm": "Start",
 	"dialogCancel": "Abbrechen",
-	"all": "alle"
+	"all": "Alle"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/el/EnhancedGrid.js b/dojox/grid/enhanced/nls/el/EnhancedGrid.js
index 83f27bd..b0a7766 100644
--- a/dojox/grid/enhanced/nls/el/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/el/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Απλή ταξινόμηση",
 	nestedSort: "Ένθετη ταξινόμηση",
-	ascending: "Αύξουσα",
-	descending: "Φθίνουσα",
+	ascending: "Πατήστε εδώ για ταξινόμηση σε αύξουσα σειρά",
+	descending: "Πατήστε εδώ για ταξινόμηση σε φθίνουσα σειρά",
 	sortingState: "${0} - ${1}",
 	unsorted: "Χωρίς ταξινόμηση αυτής της στήλης",
-	indirectSelectionRadio: "Γραμμή ${0}, μονή επιλογή, κουμπί επιλογής",
+	indirectSelectionRadio: "Γραμμή ${0}, μία επιλογή, κουμπί επιλογής",
 	indirectSelectionCheckBox: "Γραμμή ${0}, πολλαπλές επιλογές, τετραγωνίδιο επιλογής",
 	selectAll: "Επιλογή όλων"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/el/Filter.js b/dojox/grid/enhanced/nls/el/Filter.js
index 6a7c759..47b2985 100644
--- a/dojox/grid/enhanced/nls/el/Filter.js
+++ b/dojox/grid/enhanced/nls/el/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Εκκαθάριση φίλτρου",
 	"filterDefDialogTitle": "Φίλτρο",
 	"ruleTitleTemplate": "Κανόνας ${0}",
-	
 	"conditionEqual": "ίσο",
 	"conditionNotEqual": "όχι ίσο",
 	"conditionLess": "είναι μικρότερο από",
@@ -23,40 +21,34 @@ define(
 	"conditionAfter": "μετά",
 	"conditionRange": "εύρος",
 	"conditionIsEmpty": "είναι κενό",
-	
 	"all": "όλα",
 	"any": "οποιοδήποτε",
 	"relationAll": "όλοι οι κανόνες",
 	"waiRelAll": "Αντιστοιχία με όλους τους παρακάτω κανόνες:",
 	"relationAny": "οποιοσδήποτε κανόνας",
 	"waiRelAny": "Αντιστοιχία με οποιονδήποτε από τους παρακάτω κανόνες:",
-	"relationMsgFront": "Αντιστοιχία",
+	"relationMsgFront": "Επιστροφή:",
 	"relationMsgTail": "",
 	"and": "και",
 	"or": "ή",
-	
 	"addRuleButton": "Προσθήκη κανόνα",
 	"waiAddRuleButton": "Προσθήκη νέου κανόνα",
 	"removeRuleButton": "Αφαίρεση κανόνα",
 	"waiRemoveRuleButtonTemplate": "Αφαίρεση κανόνα ${0}",
-	
 	"cancelButton": "Ακύρωση",
 	"waiCancelButton": "Ακύρωση αυτού του πλαισίου διαλόγου",
 	"clearButton": "Εκκαθάριση",
 	"waiClearButton": "Εκκαθάριση του φίλτρου",
 	"filterButton": "Φίλτρο",
 	"waiFilterButton": "Υποβολή του φίλτρου",
-	
 	"columnSelectLabel": "Στήλη",
 	"waiColumnSelectTemplate": "Στήλη για τον κανόνα ${0}",
 	"conditionSelectLabel": "Συνθήκη",
 	"waiConditionSelectTemplate": "Συνθήκη για τον κανόνα ${0}",
 	"valueBoxLabel": "Τιμή",
 	"waiValueBoxTemplate": "Καταχωρήστε τιμή φίλτρου για τον κανόνα ${0}",
-	
 	"rangeTo": "έως",
 	"rangeTemplate": "από ${0} έως ${1}",
-	
 	"statusTipHeaderColumn": "Στήλη",
 	"statusTipHeaderCondition": "Κανόνες",
 	"statusTipTitle": "Γραμμή φίλτρου",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "Φίλτρο",
 	"statusTipRelAny": "Αντιστοιχία με οποιουσδήποτε κανόνες.",
 	"statusTipRelAll": "Αντιστοιχία με όλους τους κανόνες.",
-	
 	"defaultItemsName": "στοιχεία",
 	"filterBarMsgHasFilterTemplate": "Εμφανίζονται ${0} από ${1} ${2}.",
 	"filterBarMsgNoFilterTemplate": "Δεν έχει εφαρμοστεί φίλτρο",
-	
 	"filterBarDefButton": "Ορισμός φίλτρου",
 	"waiFilterBarDefButton": "Φιλτράρισμα του πίνακα",
 	"a11yFilterBarDefButton": "Φιλτράρισμα...",
 	"filterBarClearButton": "Εκκαθάριση φίλτρου",
 	"waiFilterBarClearButton": "Εκκαθάριση του φίλτρου",
 	"closeFilterBarBtn": "Κλείσιμο γραμμής φίλτρου",
-	
 	"clearFilterMsg": "Με την επιλογή αυτή θα αφαιρεθεί το φίλτρο και θα εμφανιστούν όλες οι διαθέσιμες εγγραφές.",
 	"anyColumnOption": "Οποιαδήποτε στήλη",
-	
 	"trueLabel": "Αληθές",
 	"falseLabel": "Ψευδές"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/el/Pagination.js b/dojox/grid/enhanced/nls/el/Pagination.js
index 19110ae..391e0a1 100644
--- a/dojox/grid/enhanced/nls/el/Pagination.js
+++ b/dojox/grid/enhanced/nls/el/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} από ${1} ${0}",
 	"firstTip": "Πρώτη σελίδα",
@@ -17,7 +16,6 @@ define(
 	"pageCountIndication": " (${0} σελίδες)",
 	"dialogConfirm": "Μετάβαση",
 	"dialogCancel": "Ακύρωση",
-	"all": "όλα"
+	"all": "Όλα"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/es/EnhancedGrid.js b/dojox/grid/enhanced/nls/es/EnhancedGrid.js
index 30deaf9..3303022 100644
--- a/dojox/grid/enhanced/nls/es/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/es/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Orden único",
 	nestedSort: "Orden anidado",
-	ascending: "Ascendente",
-	descending: "Descendente",
+	ascending: "Pulse para ordenar de forma ascendente",
+	descending: "Pulse para ordenar de forma descendente",
 	sortingState: "${0} - ${1}",
 	unsorted: "No ordenar esta columna",
 	indirectSelectionRadio: "Fila ${0}, selección única, botón de selección",
 	indirectSelectionCheckBox: "Fila ${0}, selección múltiple, recuadro de selección",
 	selectAll: "Seleccionar todo"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/es/Filter.js b/dojox/grid/enhanced/nls/es/Filter.js
index e77895f..3d4e692 100644
--- a/dojox/grid/enhanced/nls/es/Filter.js
+++ b/dojox/grid/enhanced/nls/es/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Borrar filtro",
 	"filterDefDialogTitle": "Filtro",
 	"ruleTitleTemplate": "Regla ${0}",
-	
 	"conditionEqual": "es igual a",
 	"conditionNotEqual": "no es igual a",
 	"conditionLess": "es menor que",
@@ -14,75 +12,64 @@ define(
 	"conditionContains": "contiene",
 	"conditionIs": "es",
 	"conditionStartsWith": "empieza por",
-	"conditionEndWith": "acaba por",
+	"conditionEndWith": "termina por",
 	"conditionNotContain": "no contiene",
 	"conditionIsNot": "no es",
 	"conditionNotStartWith": "no empieza por",
-	"conditionNotEndWith": "no acaba por",
+	"conditionNotEndWith": "no termina por",
 	"conditionBefore": "antes",
 	"conditionAfter": "después",
 	"conditionRange": "rango",
 	"conditionIsEmpty": "está vacío",
-	
 	"all": "todas",
 	"any": "cualquiera",
 	"relationAll": "todas las reglas",
 	"waiRelAll": "Coincidir con todas las reglas siguientes:",
 	"relationAny": "cualquier regla",
 	"waiRelAny": "Coincidir con cualquiera de las reglas siguientes:",
-	"relationMsgFront": "Coincidir",
+	"relationMsgFront": "Coincidir:",
 	"relationMsgTail": "",
 	"and": "y",
 	"or": "o",
-	
 	"addRuleButton": "Añadir regla",
 	"waiAddRuleButton": "Añadir una regla nueva",
 	"removeRuleButton": "Eliminar regla",
 	"waiRemoveRuleButtonTemplate": "Eliminar la regla ${0}",
-	
 	"cancelButton": "Cancelar",
 	"waiCancelButton": "Cancelar este diálogo",
 	"clearButton": "Borrar",
 	"waiClearButton": "Borrar el filtro",
 	"filterButton": "Filtrar",
 	"waiFilterButton": "Enviar el filtro",
-	
 	"columnSelectLabel": "Columna",
 	"waiColumnSelectTemplate": "Columna para la regla ${0}",
 	"conditionSelectLabel": "Condición",
 	"waiConditionSelectTemplate": "Condición para la regla ${0}",
 	"valueBoxLabel": "Valor",
 	"waiValueBoxTemplate": "Escriba el valor que se debe filtrar para la regla ${0}",
-	
 	"rangeTo": "a",
 	"rangeTemplate": "de ${0} a ${1}",
-	
 	"statusTipHeaderColumn": "Columna",
 	"statusTipHeaderCondition": "Reglas",
 	"statusTipTitle": "Barra de filtro",
 	"statusTipMsg": "Pulse aquí en la barra de filtro para filtrar por los valores de ${0}.",
 	"anycolumn": "cualquier columna",
 	"statusTipTitleNoFilter": "Barra de filtro",
-	"statusTipTitleHasFilter": "Filtro",
+	"statusTipTitleHasFilter": "Filtrar",
 	"statusTipRelAny": "Coincidir con cualquier regla.",
 	"statusTipRelAll": "Coincidir con todas las reglas.",
-	
 	"defaultItemsName": "elementos",
-	"filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} mostrados.",
-	"filterBarMsgNoFilterTemplate": "Ningún filtro aplicado",
-	
+	"filterBarMsgHasFilterTemplate": "Se muestran ${0} de ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "No se aplica ningún filtro",
 	"filterBarDefButton": "Definir filtro",
 	"waiFilterBarDefButton": "Filtrar la tabla",
 	"a11yFilterBarDefButton": "Filtrar...",
 	"filterBarClearButton": "Borrar filtro",
 	"waiFilterBarClearButton": "Borrar el filtro",
-	"closeFilterBarBtn": "Cerrar barra de filtro",
-	
-	"clearFilterMsg": "Esto eliminará el filtro y mostrará todos los registros disponibles.",
+	"closeFilterBarBtn": "Cerrar la barra de filtro",
+	"clearFilterMsg": "Eliminará el filtro y mostrará todos los registros disponibles.",
 	"anyColumnOption": "Cualquier columna",
-	
 	"trueLabel": "Verdadero",
 	"falseLabel": "Falso"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/es/Pagination.js b/dojox/grid/enhanced/nls/es/Pagination.js
index a284fa9..d8792ac 100644
--- a/dojox/grid/enhanced/nls/es/Pagination.js
+++ b/dojox/grid/enhanced/nls/es/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} de ${1} ${0}",
 	"firstTip": "Primera página",
@@ -12,13 +11,11 @@ define(
 	"pageSizeLabelTemplate": "${0} elementos por página",
 	"allItemsLabelTemplate": "Todos los elementos",
 	"gotoButtonTitle": "Ir a una página específica",
-	"dialogTitle": "Ir a página",
+	"dialogTitle": "Ir a la página",
 	"dialogIndication": "Especifique el número de página",
 	"pageCountIndication": " (${0} páginas)",
 	"dialogConfirm": "Ir",
 	"dialogCancel": "Cancelar",
-	"all": "todas"
+	"all": "Todo"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/fi/EnhancedGrid.js b/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
index a01e2ba..104517c 100644
--- a/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Yksinkertainen lajittelu",
 	nestedSort: "Sisäkkäinen lajittelu",
-	ascending: "Nouseva",
-	descending: "Laskeva",
+	ascending: "Lajittele nousevaan järjestykseen napsauttamalla",
+	descending: "Lajittele laskevaan järjestykseen napsauttamalla",
 	sortingState: "${0} - ${1}",
 	unsorted: "Älä lajittele tätä saraketta",
-	indirectSelectionRadio: "Rivi ${0}, yksittäisvalinta, ruutu",
-	indirectSelectionCheckBox: "Rivi ${0}, monivalinta, valintaruutu",
+	indirectSelectionRadio: "Rivi ${0}, yksi valinta, valintanappi",
+	indirectSelectionCheckBox: "Rivi ${0}, useita valintoja, valintaruutu",
 	selectAll: "Valitse kaikki"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/fi/Filter.js b/dojox/grid/enhanced/nls/fi/Filter.js
index e3c661b..0570bb8 100644
--- a/dojox/grid/enhanced/nls/fi/Filter.js
+++ b/dojox/grid/enhanced/nls/fi/Filter.js
@@ -1,88 +1,75 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Tyhjennä suodatin",
-	"filterDefDialogTitle": "Suodatin",
+	"filterDefDialogTitle": "Suodata",
 	"ruleTitleTemplate": "Sääntö ${0}",
-	
-	"conditionEqual": "yhtä suuri kuin",
-	"conditionNotEqual": "ei ole yhtä suuri kuin",
+	"conditionEqual": "on yhtä suuri",
+	"conditionNotEqual": "ei ole yhtä suuri",
 	"conditionLess": "on pienempi kuin",
-	"conditionLessEqual": "pienempi tai yhtä suuri kuin",
+	"conditionLessEqual": "pienempi tai yhtä suuri",
 	"conditionLarger": "on suurempi kuin",
-	"conditionLargerEqual": "suurempi tai yhtä suuri kuin",
+	"conditionLargerEqual": "suurempi tai yhtä suuri",
 	"conditionContains": "sisältää",
 	"conditionIs": "on",
-	"conditionStartsWith": "alussa on",
-	"conditionEndWith": "lopussa on",
+	"conditionStartsWith": "alkaa merkillä",
+	"conditionEndWith": "loppuu merkkiin",
 	"conditionNotContain": "ei sisällä",
 	"conditionIsNot": "ei ole",
-	"conditionNotStartWith": "alussa ei ole",
-	"conditionNotEndWith": "lopussa ei ole",
+	"conditionNotStartWith": "ei ala merkillä",
+	"conditionNotEndWith": "ei lopu merkkiin",
 	"conditionBefore": "ennen",
 	"conditionAfter": "jälkeen",
-	"conditionRange": "vaihtelualue",
+	"conditionRange": "sallittu alue",
 	"conditionIsEmpty": "on tyhjä",
-	
 	"all": "kaikki",
 	"any": "mikä tahansa",
 	"relationAll": "kaikki säännöt",
-	"waiRelAll": "Täsmäytä kaikki seuraavat säännöt:",
+	"waiRelAll": "Vastaa kaikkia seuraavia sääntöjä:",
 	"relationAny": "mitkä tahansa säännöt",
-	"waiRelAny": "Täsmäytä mitkä tahansa seuraavista säännöistä:",
-	"relationMsgFront": "Vastine",
+	"waiRelAny": "Vastaa jotakin seuraavista säännöistä:",
+	"relationMsgFront": "Vastine:",
 	"relationMsgTail": "",
 	"and": "ja",
 	"or": "tai",
-	
 	"addRuleButton": "Lisää sääntö",
 	"waiAddRuleButton": "Lisää uusi sääntö",
 	"removeRuleButton": "Poista sääntö",
 	"waiRemoveRuleButtonTemplate": "Poista sääntö ${0}",
-	
 	"cancelButton": "Peruuta",
-	"waiCancelButton": "Peruuta keskustelu",
+	"waiCancelButton": "Peruuta tämä valintaikkuna",
 	"clearButton": "Tyhjennä",
 	"waiClearButton": "Tyhjennä suodatin",
 	"filterButton": "Suodata",
 	"waiFilterButton": "Lähetä suodatin",
-	
 	"columnSelectLabel": "Sarake",
-	"waiColumnSelectTemplate": "Säännön ${0} sarake",
+	"waiColumnSelectTemplate": "Sarake säännölle ${0}",
 	"conditionSelectLabel": "Ehto",
-	"waiConditionSelectTemplate": "Säännön ${0} ehto",
+	"waiConditionSelectTemplate": "Ehto säännölle ${0}",
 	"valueBoxLabel": "Arvo",
-	"waiValueBoxTemplate": "Syötä säännön ${0} suodatettava arvo",
-	
-	"rangeTo": "kohde",
-	"rangeTemplate": "lähde ${0}, kohde ${1}",
-	
+	"waiValueBoxTemplate": "Anna suodatusarvo säännölle ${0}",
+	"rangeTo": "-",
+	"rangeTemplate": "${0} - ${1}",
 	"statusTipHeaderColumn": "Sarake",
 	"statusTipHeaderCondition": "Säännöt",
 	"statusTipTitle": "Suodatinpalkki",
-	"statusTipMsg": "Napsauta suodatinpalkkia kohteen ${0} arvojen suodattamiseksi.",
+	"statusTipMsg": "Napsauta suodatinpalkkia tässä ja suodata arvot kohteessa ${0}.",
 	"anycolumn": "mikä tahansa sarake",
 	"statusTipTitleNoFilter": "Suodatinpalkki",
-	"statusTipTitleHasFilter": "Suodatin",
+	"statusTipTitleHasFilter": "Suodata",
 	"statusTipRelAny": "Vastaa jotakin sääntöä.",
 	"statusTipRelAll": "Vastaa kaikkia sääntöjä.",
-	
-	"defaultItemsName": "nimikkeet",
-	"filterBarMsgHasFilterTemplate": "näkyvissä ${0} / ${1} ${2}.",
-	"filterBarMsgNoFilterTemplate": "Mikään suodatin ei ole käytössä",
-	
+	"defaultItemsName": "kohteet",
+	"filterBarMsgHasFilterTemplate": "${0} / ${1} ${2} näkyy.",
+	"filterBarMsgNoFilterTemplate": "Ei suodatinta käytössä",
 	"filterBarDefButton": "Määritä suodatin",
 	"waiFilterBarDefButton": "Suodata taulukko",
 	"a11yFilterBarDefButton": "Suodata...",
 	"filterBarClearButton": "Tyhjennä suodatin",
 	"waiFilterBarClearButton": "Tyhjennä suodatin",
 	"closeFilterBarBtn": "Sulje suodatinpalkki",
-	
-	"clearFilterMsg": "Tämä toimenpide poistaa suodattimen ja näyttää kaikki saatavilla olevat tallenteet.",
+	"clearFilterMsg": "Poistaa suodattimen ja näyttää kaikki käytettävissä olevat tietueet.",
 	"anyColumnOption": "Mikä tahansa sarake",
-	
 	"trueLabel": "Tosi",
 	"falseLabel": "Epätosi"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/fi/Pagination.js b/dojox/grid/enhanced/nls/fi/Pagination.js
index 66dd638..1ec95dc 100644
--- a/dojox/grid/enhanced/nls/fi/Pagination.js
+++ b/dojox/grid/enhanced/nls/fi/Pagination.js
@@ -1,23 +1,21 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} / ${1} ${0}",
 	"firstTip": "Ensimmäinen sivu",
 	"lastTip": "Viimeinen sivu",
 	"nextTip": "Seuraava sivu",
 	"prevTip": "Edellinen sivu",
-	"itemTitle": "nimikkeet",
+	"itemTitle": "kohteet",
 	"singularItemTitle": "kohde",
 	"pageStepLabelTemplate": "Sivu ${0}",
-	"pageSizeLabelTemplate": "${0} nimikettä sivua kohti",
-	"allItemsLabelTemplate": "Kaikki nimikkeet",
+	"pageSizeLabelTemplate": "${0} kohdetta sivulla",
+	"allItemsLabelTemplate": "Kaikki kohteet",
 	"gotoButtonTitle": "Siirry tietylle sivulle",
 	"dialogTitle": "Siirry sivulle",
-	"dialogIndication": "Kirjoita sivunumero",
+	"dialogIndication": "Määritä sivunumero",
 	"pageCountIndication": " (${0} sivua)",
 	"dialogConfirm": "Siirry",
 	"dialogCancel": "Peruuta",
-	"all": "kaikki"
+	"all": "Kaikki"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/fr/EnhancedGrid.js b/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
index 5709bfc..737135a 100644
--- a/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Tri simple",
 	nestedSort: "Tri imbriqué",
-	ascending: "Croissant",
-	descending: "Décroissant",
+	ascending: "Cliquer pour trier par ordre croissant",
+	descending: "Cliquer pour trier par ordre décroissant",
 	sortingState: "${0} - ${1}",
 	unsorted: "Ne pas trier cette colonne",
 	indirectSelectionRadio: "Ligne ${0}, sélection unique, bouton radio",
 	indirectSelectionCheckBox: "Ligne ${0}, sélection multiple, case à cocher",
-	selectAll: "Tout sélectionner"
+	selectAll: "Sélectionner tout"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/fr/Filter.js b/dojox/grid/enhanced/nls/fr/Filter.js
index 2e2fb9c..527e9fa 100644
--- a/dojox/grid/enhanced/nls/fr/Filter.js
+++ b/dojox/grid/enhanced/nls/fr/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Effacer le filtre",
 	"filterDefDialogTitle": "Filtrer",
 	"ruleTitleTemplate": "Règle ${0}",
-	
 	"conditionEqual": "égal",
 	"conditionNotEqual": "est différent de",
 	"conditionLess": "est inférieur à",
@@ -23,40 +21,34 @@ define(
 	"conditionAfter": "après",
 	"conditionRange": "plage",
 	"conditionIsEmpty": "est vide",
-	
-	"all": "tout",
-	"any": "n'importe quelle",
+	"all": "toutes",
+	"any": "n'importe quelles",
 	"relationAll": "toutes les règles",
 	"waiRelAll": "Satisfaire à toutes les règles suivantes :",
 	"relationAny": "n'importe quelles règles",
-	"waiRelAny": "Satisfaire à une quelconque des règles suivantes :",
-	"relationMsgFront": "Satisfaire",
+	"waiRelAny": "Satisfaire à l'une quelconque des règles suivantes :",
+	"relationMsgFront": "Satisfaire à :",
 	"relationMsgTail": "",
 	"and": "et",
 	"or": "ou",
-	
 	"addRuleButton": "Ajouter une règle",
 	"waiAddRuleButton": "Ajouter une nouvelle règle",
 	"removeRuleButton": "Supprimer la règle",
 	"waiRemoveRuleButtonTemplate": "Supprimer la règle ${0}",
-	
 	"cancelButton": "Annuler",
 	"waiCancelButton": "Annuler cette boîte de dialogue",
 	"clearButton": "Effacer",
 	"waiClearButton": "Effacer le filtre",
 	"filterButton": "Filtrer",
 	"waiFilterButton": "Soumettre le filtre",
-	
 	"columnSelectLabel": "Colonne",
 	"waiColumnSelectTemplate": "Colonne pour la règle ${0}",
 	"conditionSelectLabel": "Condition",
 	"waiConditionSelectTemplate": "Condition pour la règle ${0}",
 	"valueBoxLabel": "Valeur",
 	"waiValueBoxTemplate": "Saisir la valeur à filtrer pour la règle ${0}",
-	
 	"rangeTo": "à",
 	"rangeTemplate": "de ${0} à ${1}",
-	
 	"statusTipHeaderColumn": "Colonne",
 	"statusTipHeaderCondition": "Règles",
 	"statusTipTitle": "Barre de filtre",
@@ -64,25 +56,20 @@ define(
 	"anycolumn": "n'importe quelle colonne",
 	"statusTipTitleNoFilter": "Barre de filtre",
 	"statusTipTitleHasFilter": "Filtrer",
-	"statusTipRelAny": "Répondre à l'une des règles.",
-	"statusTipRelAll": "Réponde à toutes les régles.",
-	
+	"statusTipRelAny": "Satisfaire à l'une quelconque des règles. ",
+	"statusTipRelAll": "Satisfaire à toutes les règles. ",
 	"defaultItemsName": "éléments",
 	"filterBarMsgHasFilterTemplate": "${0} sur ${1} ${2} affichés.",
 	"filterBarMsgNoFilterTemplate": "Aucun filtre appliqué",
-	
 	"filterBarDefButton": "Définir le filtre",
 	"waiFilterBarDefButton": "Filtrer le tableau",
 	"a11yFilterBarDefButton": "Filtrer...",
 	"filterBarClearButton": "Effacer le filtre",
 	"waiFilterBarClearButton": "Effacer le filtre",
 	"closeFilterBarBtn": "Fermer la barre de filtre",
-	
 	"clearFilterMsg": "Cela supprimera le filtre et affichera tous les enregistrements disponibles.",
 	"anyColumnOption": "N'importe quelle colonne",
-	
 	"trueLabel": "Vrai",
 	"falseLabel": "Faux"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/fr/Pagination.js b/dojox/grid/enhanced/nls/fr/Pagination.js
index 8fb15fc..6fe5465 100644
--- a/dojox/grid/enhanced/nls/fr/Pagination.js
+++ b/dojox/grid/enhanced/nls/fr/Pagination.js
@@ -1,7 +1,6 @@
 define(
-//begin v1.x content
 ({
-	"descTemplate": "${2} - ${3} sur ${1} ${0}",
+	"descTemplate": "${2} à ${3} sur ${1} ${0}",
 	"firstTip": "Première page",
 	"lastTip": "Dernière page",
 	"nextTip": "Page suivante",
@@ -11,14 +10,12 @@ define(
 	"pageStepLabelTemplate": "Page ${0}",
 	"pageSizeLabelTemplate": "${0} éléments par page",
 	"allItemsLabelTemplate": "Tous les éléments",
-	"gotoButtonTitle": "Accéder à une page spécifique",
-	"dialogTitle": "Accéder à la page",
+	"gotoButtonTitle": "Aller à une page donnée",
+	"dialogTitle": "Aller à la page",
 	"dialogIndication": "Indiquer le numéro de page",
 	"pageCountIndication": " (${0} pages)",
-	"dialogConfirm": "Accès",
+	"dialogConfirm": "Aller",
 	"dialogCancel": "Annuler",
-	"all": "tout"
+	"all": "Tout"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/he/EnhancedGrid.js b/dojox/grid/enhanced/nls/he/EnhancedGrid.js
index 970a7cf..6641300 100644
--- a/dojox/grid/enhanced/nls/he/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/he/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "מיון יחיד",
 	nestedSort: "מיון מקונן",
-	ascending: "עולה",
-	descending: "יורד",
+	ascending: "לחצו כדי למיין בסדר עולה",
+	descending: "לחצו כדי למיין בסדר יורד",
 	sortingState: "${0} - ${1}",
 	unsorted: "אין למיין עמודה זו",
 	indirectSelectionRadio: "שורה ${0}, בחירה יחידה, תיבת בחירה",
 	indirectSelectionCheckBox: "שורה ${0}, בחירה מרובה, תיבת סימון",
 	selectAll: "בחירת הכל"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/he/Filter.js b/dojox/grid/enhanced/nls/he/Filter.js
index 1724756..473d941 100644
--- a/dojox/grid/enhanced/nls/he/Filter.js
+++ b/dojox/grid/enhanced/nls/he/Filter.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "ניקוי מסנן",
 	"filterDefDialogTitle": "מסנן",
@@ -64,6 +63,8 @@ define(
 	"anycolumn": "כל עמודה",
 	"statusTipTitleNoFilter": "סרגל סינון",
 	"statusTipTitleHasFilter": "מסנן",
+	"statusTipRelAny": "התאמה לכלל כלשהו. ",
+	"statusTipRelAll": "התאמה לכל הכללים. ",
 	
 	"defaultItemsName": "פריטים",
 	"filterBarMsgHasFilterTemplate": "מוצג ${0} מתוך ${1} ${2}.",
@@ -82,8 +83,4 @@ define(
 	"trueLabel": "True",
 	"falseLabel": "False"
 })
-//end v1.x content
 );
-
-
-
diff --git a/dojox/grid/enhanced/nls/he/Pagination.js b/dojox/grid/enhanced/nls/he/Pagination.js
index 5cc0ec2..b974669 100644
--- a/dojox/grid/enhanced/nls/he/Pagination.js
+++ b/dojox/grid/enhanced/nls/he/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} מתוך ${1} ${0}",
 	"firstTip": "עמוד ראשון",
@@ -7,6 +6,7 @@ define(
 	"nextTip": "העמוד הבא",
 	"prevTip": "העמוד הקודם",
 	"itemTitle": "פריטים",
+	"singularItemTitle": "פריט",
 	"pageStepLabelTemplate": "עמוד ${0}",
 	"pageSizeLabelTemplate": "${0} פריטים לעמוד",
 	"allItemsLabelTemplate": "כל הפריטים",
@@ -18,6 +18,4 @@ define(
 	"dialogCancel": "ביטול",
 	"all": "הכל"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/hr/EnhancedGrid.js b/dojox/grid/enhanced/nls/hr/EnhancedGrid.js
index d46c1a5..dddad5a 100644
--- a/dojox/grid/enhanced/nls/hr/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/hr/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Jedan sort",
 	nestedSort: "Ugniježđeni sort",
-	ascending: "Uzlazno",
-	descending: "Silazno",
+	ascending: "Kliknite za uzlazno sortiranje",
+	descending: "Kliknite za silazno sortiranje",
 	sortingState: "${0} - ${1}",
 	unsorted: "Ne sortiraj ovaj stupac",
 	indirectSelectionRadio: "Red ${0}, jedan izbor, radio kućica",
 	indirectSelectionCheckBox: "Red ${0}, više izbora, kontrolna kućica",
 	selectAll: "Izaberi sve"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/hr/Filter.js b/dojox/grid/enhanced/nls/hr/Filter.js
index aeb7b95..dc12d4f 100644
--- a/dojox/grid/enhanced/nls/hr/Filter.js
+++ b/dojox/grid/enhanced/nls/hr/Filter.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Brisanje filtera",
 	"filterDefDialogTitle": "Filter",
@@ -30,7 +29,7 @@ define(
 	"waiRelAll": "Usporedi sva sljedeća pravila:",
 	"relationAny": "bilo koja pravila",
 	"waiRelAny": "Usporedi bilo koje od sljedećih pravila:",
-	"relationMsgFront": "Odgovara",
+	"relationMsgFront": "Usporedi:",
 	"relationMsgTail": "",
 	"and": "i",
 	"or": "ili",
@@ -81,8 +80,7 @@ define(
 	"clearFilterMsg": "Ovo uklanja filter i prikazuje sve raspoložive slogove.",
 	"anyColumnOption": "Bilo koji stupac",
 	
-	"trueLabel": "True",
-	"falseLabel": "False"
+	"trueLabel": "Istinito",
+	"falseLabel": "Lažno"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/hr/Pagination.js b/dojox/grid/enhanced/nls/hr/Pagination.js
index 5248fa1..0365aca 100644
--- a/dojox/grid/enhanced/nls/hr/Pagination.js
+++ b/dojox/grid/enhanced/nls/hr/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} od ${1} ${0}",
 	"firstTip": "Prva stranica",
@@ -17,8 +16,6 @@ define(
 	"pageCountIndication": " (${0} stranica)",
 	"dialogConfirm": "Idi",
 	"dialogCancel": "Opoziv",
-	"all": "svi"
+	"all": "Sve"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/hu/EnhancedGrid.js b/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
index c260371..ebb9188 100644
--- a/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Egyszerű rendezés",
 	nestedSort: "Beágyazott rendezés",
-	ascending: "Növekvő",
-	descending: "Csökkenő",
+	ascending: "Kattintson ide a növekvő rendezéshez",
+	descending: "Kattintson ide a csökkenő rendezéshez",
 	sortingState: "${0} - ${1}",
 	unsorted: "Ne rendezze ezt az oszlopot",
 	indirectSelectionRadio: "${0} sor, egyetlen kijelölés, választógomb",
 	indirectSelectionCheckBox: "${0} sor, több kijelölés, jelölőnégyzet",
 	selectAll: "Összes kijelölése"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/hu/Filter.js b/dojox/grid/enhanced/nls/hu/Filter.js
index 709a238..d83a175 100644
--- a/dojox/grid/enhanced/nls/hu/Filter.js
+++ b/dojox/grid/enhanced/nls/hu/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Szűrő törlése",
 	"filterDefDialogTitle": "Szűrő",
 	"ruleTitleTemplate": "${0} szabály",
-	
 	"conditionEqual": "egyenlő",
 	"conditionNotEqual": "nem egyenlő",
 	"conditionLess": "kisebb mint",
@@ -23,40 +21,34 @@ define(
 	"conditionAfter": "után",
 	"conditionRange": "tartomány",
 	"conditionIsEmpty": "üres",
-	
 	"all": "mind",
 	"any": "bármely",
 	"relationAll": "minden szabály",
 	"waiRelAll": "Megfelel a következő összes szabálynak:",
 	"relationAny": "bármely szabály",
 	"waiRelAny": "Megfelel a következő bármely szabálynak:",
-	"relationMsgFront": "Egyezik",
+	"relationMsgFront": "Egyezés:",
 	"relationMsgTail": "",
 	"and": "és",
 	"or": "vagy",
-	
 	"addRuleButton": "Szabály hozzáadása",
 	"waiAddRuleButton": "Új szabály hozzáadása",
 	"removeRuleButton": "Szabály eltávolítása",
 	"waiRemoveRuleButtonTemplate": "${0} szabály eltávolítása",
-	
 	"cancelButton": "Mégse",
 	"waiCancelButton": "A párbeszédablak bezárása",
 	"clearButton": "Törlés",
 	"waiClearButton": "A szűrő törlése",
 	"filterButton": "Szűrő",
 	"waiFilterButton": "A szűrő elküldése",
-	
 	"columnSelectLabel": "Oszlop",
 	"waiColumnSelectTemplate": "Oszlop a(z) ${0} szabályhoz",
 	"conditionSelectLabel": "Feltétel",
 	"waiConditionSelectTemplate": "Feltétel a(z) ${0} szabályhoz",
 	"valueBoxLabel": "Érték",
 	"waiValueBoxTemplate": "Írja be a szűrni kívánt értéket a(z) ${0} szabályhoz",
-	
 	"rangeTo": "-",
 	"rangeTemplate": "${0} - ${1}",
-	
 	"statusTipHeaderColumn": "Oszlop",
 	"statusTipHeaderCondition": "Szabályok",
 	"statusTipTitle": "Szűrősáv",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "Szűrő",
 	"statusTipRelAny": "Bármely szabálynak megfelel.",
 	"statusTipRelAll": "Minden szabálynak megfelel.",
-	
 	"defaultItemsName": "elemek",
 	"filterBarMsgHasFilterTemplate": "${0} / ${1} ${2} megjelenítve.",
 	"filterBarMsgNoFilterTemplate": "Nincs szűrő alkalmazva.",
-	
 	"filterBarDefButton": "Szűrő meghatározása",
 	"waiFilterBarDefButton": "Táblázat szűrése",
 	"a11yFilterBarDefButton": "Szűrés...",
 	"filterBarClearButton": "Szűrő törlése",
 	"waiFilterBarClearButton": "A szűrő törlése",
 	"closeFilterBarBtn": "Szűrősáv bezárása",
-	
 	"clearFilterMsg": "Eltávolítja a szűrőt és megjeleníti az összes elérhető rekordot.",
 	"anyColumnOption": "Bármely oszlop",
-	
 	"trueLabel": "Igaz",
 	"falseLabel": "Hamis"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/hu/Pagination.js b/dojox/grid/enhanced/nls/hu/Pagination.js
index 1cfb2ed..adc017d 100644
--- a/dojox/grid/enhanced/nls/hu/Pagination.js
+++ b/dojox/grid/enhanced/nls/hu/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} / ${1} ${0}",
 	"firstTip": "Első oldal",
@@ -7,7 +6,7 @@ define(
 	"nextTip": "Következő oldal",
 	"prevTip": "Előző oldal",
 	"itemTitle": "elemek",
-	"singularItemTitle": "elem",
+	"singularItemTitle": "tétel",
 	"pageStepLabelTemplate": "${0}. oldal",
 	"pageSizeLabelTemplate": "${0} elem oldalanként",
 	"allItemsLabelTemplate": "Összes elem",
@@ -17,8 +16,6 @@ define(
 	"pageCountIndication": " (${0} oldal)",
 	"dialogConfirm": "Mehet",
 	"dialogCancel": "Mégse",
-	"all": "mind"
+	"all": "Mind"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/it/EnhancedGrid.js b/dojox/grid/enhanced/nls/it/EnhancedGrid.js
index caf91fb..a3b9f38 100644
--- a/dojox/grid/enhanced/nls/it/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/it/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
-	singleSort: "Ordine singolo",
-	nestedSort: "Ordine nidificato",
-	ascending: "Ascendente",
-	descending: "Decrescente",
+	singleSort: "Ordinamento singolo",
+	nestedSort: "Ordinamento nidificato",
+	ascending: "Fare clic per ordinare in modo crescente",
+	descending: "Fare clic per ordinare in modo decrescente",
 	sortingState: "${0} - ${1}",
 	unsorted: "Non ordinare questa colonna",
-	indirectSelectionRadio: "Riga ${0}, selezione singola, casella di opzione",
-	indirectSelectionCheckBox: "Riga ${0}, selezione multipla, casella di spunta",
+	indirectSelectionRadio: "Riga ${0}, selezione singola, casella ad opzione",
+	indirectSelectionCheckBox: "Riga ${0}, selezione multipla, check box",
 	selectAll: "Seleziona tutto"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/it/Filter.js b/dojox/grid/enhanced/nls/it/Filter.js
index 8d07004..6be13f1 100644
--- a/dojox/grid/enhanced/nls/it/Filter.js
+++ b/dojox/grid/enhanced/nls/it/Filter.js
@@ -1,88 +1,75 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Cancella filtro",
 	"filterDefDialogTitle": "Filtro",
 	"ruleTitleTemplate": "Regola ${0}",
-	
 	"conditionEqual": "uguale a",
-	"conditionNotEqual": "non uguale a",
+	"conditionNotEqual": "diverso da",
 	"conditionLess": "minore di",
-	"conditionLessEqual": "minore di o uguale a",
+	"conditionLessEqual": "minore o uguale",
 	"conditionLarger": "maggiore di",
-	"conditionLargerEqual": "maggiore di o uguale a",
+	"conditionLargerEqual": "maggiore o uguale",
 	"conditionContains": "contiene",
 	"conditionIs": "è",
 	"conditionStartsWith": "inizia con",
-	"conditionEndWith": "finisce con",
+	"conditionEndWith": "termina con",
 	"conditionNotContain": "non contiene",
 	"conditionIsNot": "non è",
 	"conditionNotStartWith": "non inizia con",
-	"conditionNotEndWith": "non finisce con",
+	"conditionNotEndWith": "non termina con",
 	"conditionBefore": "prima",
 	"conditionAfter": "dopo",
 	"conditionRange": "intervallo",
 	"conditionIsEmpty": "è vuoto",
-	
-	"all": "tutte",
+	"all": "tutto",
 	"any": "qualsiasi",
 	"relationAll": "tutte le regole",
-	"waiRelAll": "Confronta con tutte le seguenti regole:",
+	"waiRelAll": "Corrispondenza con tutte le regole seguenti:",
 	"relationAny": "qualsiasi regola",
-	"waiRelAny": "Confronta con qualsiasi delle seguenti regole:",
-	"relationMsgFront": "Confronta",
+	"waiRelAny": "Corrispondenza una qualsiasi delle regole seguenti:",
+	"relationMsgFront": "Corrispondenza:",
 	"relationMsgTail": "",
 	"and": "e",
 	"or": "o",
-	
 	"addRuleButton": "Aggiungi regola",
 	"waiAddRuleButton": "Aggiungi una nuova regola",
 	"removeRuleButton": "Rimuovi regola",
 	"waiRemoveRuleButtonTemplate": "Rimuovi regola ${0}",
-	
 	"cancelButton": "Annulla",
 	"waiCancelButton": "Annulla questa finestra di dialogo",
-	"clearButton": "Cancella",
+	"clearButton": "Elimina",
 	"waiClearButton": "Cancella il filtro",
 	"filterButton": "Filtro",
 	"waiFilterButton": "Inoltra il filtro",
-	
 	"columnSelectLabel": "Colonna",
 	"waiColumnSelectTemplate": "Colonna per la regola ${0}",
 	"conditionSelectLabel": "Condizione",
 	"waiConditionSelectTemplate": "Condizione per la regola ${0}",
 	"valueBoxLabel": "Valore",
 	"waiValueBoxTemplate": "Immettere il valore da filtrare per la regola ${0}",
-	
 	"rangeTo": "a",
 	"rangeTemplate": "da ${0} a ${1}",
-	
 	"statusTipHeaderColumn": "Colonna",
 	"statusTipHeaderCondition": "Regole",
-	"statusTipTitle": "Barra di filtro",
-	"statusTipMsg": "Fare clic sulla barra di filtro qui per filtrare sui valori in ${0}.",
+	"statusTipTitle": "Barra filtro",
+	"statusTipMsg": "Fare clic sulla barra filtro per filtrare in base ai valori in ${0}.",
 	"anycolumn": "qualsiasi colonna",
-	"statusTipTitleNoFilter": "Barra di filtro",
+	"statusTipTitleNoFilter": "Barra filtro",
 	"statusTipTitleHasFilter": "Filtro",
 	"statusTipRelAny": "Corrispondenza con qualsiasi regola.",
 	"statusTipRelAll": "Corrispondenza con tutte le regole.",
-	
 	"defaultItemsName": "elementi",
-	"filterBarMsgHasFilterTemplate": "${0} di ${1} ${2} visualizzati.",
+	"filterBarMsgHasFilterTemplate": "${0} di ${1} ${2} mostrate.",
 	"filterBarMsgNoFilterTemplate": "Nessun filtro applicato",
-	
 	"filterBarDefButton": "Definisci filtro",
 	"waiFilterBarDefButton": "Filtra la tabella",
 	"a11yFilterBarDefButton": "Filtro...",
 	"filterBarClearButton": "Cancella filtro",
 	"waiFilterBarClearButton": "Cancella il filtro",
-	"closeFilterBarBtn": "Chiudi barra di filtro",
-	
-	"clearFilterMsg": "Questo rimuoverà il filtro e visualizzerà tutti i record disponibili.",
+	"closeFilterBarBtn": "Chiudi barra filtro",
+	"clearFilterMsg": "Questa operazione rimuoverà il filtro e visualizzerà tutti i record disponibili.",
 	"anyColumnOption": "Qualsiasi colonna",
-	
 	"trueLabel": "Vero",
 	"falseLabel": "Falso"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/it/Pagination.js b/dojox/grid/enhanced/nls/it/Pagination.js
index 12b642a..7c06afd 100644
--- a/dojox/grid/enhanced/nls/it/Pagination.js
+++ b/dojox/grid/enhanced/nls/it/Pagination.js
@@ -1,24 +1,21 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} di ${1} ${0}",
 	"firstTip": "Prima pagina",
 	"lastTip": "Ultima pagina",
-	"nextTip": "Pagina successiva ",
-	"prevTip": "Pagina precedente ",
-	"itemTitle": "elementi ",
+	"nextTip": "Pagina successiva",
+	"prevTip": "Pagina precedente",
+	"itemTitle": "elementi",
 	"singularItemTitle": "elemento",
 	"pageStepLabelTemplate": "Pagina ${0}",
-	"pageSizeLabelTemplate": "${0} elementi per pagina ",
+	"pageSizeLabelTemplate": "${0} elementi per pagina",
 	"allItemsLabelTemplate": "Tutti gli elementi",
-	"gotoButtonTitle": "Vai a una pagina specifica ",
-	"dialogTitle": "Vai a pagina ",
-	"dialogIndication": "Specificare il numero di pagina",
+	"gotoButtonTitle": "Vai a pagina specifica",
+	"dialogTitle": "Vai a pagina",
+	"dialogIndication": "Specifica numero pagina",
 	"pageCountIndication": " (${0} pagine)",
 	"dialogConfirm": "Vai",
 	"dialogCancel": "Annulla",
-	"all": "tutte"
+	"all": "Tutto"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/ja/EnhancedGrid.js b/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
index 5b20c7d..bc9fbe3 100644
--- a/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "単一ソート",
-	nestedSort: "ネスト・ソート",
-	ascending: "昇順",
-	descending: "降順",
+	nestedSort: "入れ子ソート",
+	ascending: "クリックすると昇順でソート",
+	descending: "クリックすると降順でソート",
 	sortingState: "${0} - ${1}",
 	unsorted: "この列をソートしない",
 	indirectSelectionRadio: "行 ${0}、単一選択、ラジオ・ボックス",
 	indirectSelectionCheckBox: "行 ${0}、複数選択、チェック・ボックス",
-	selectAll: "すべてを選択"
+	selectAll: "すべて選択"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/ja/Filter.js b/dojox/grid/enhanced/nls/ja/Filter.js
index 21f0e58..59316f7 100644
--- a/dojox/grid/enhanced/nls/ja/Filter.js
+++ b/dojox/grid/enhanced/nls/ja/Filter.js
@@ -1,62 +1,54 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "フィルターのクリア",
 	"filterDefDialogTitle": "フィルター",
 	"ruleTitleTemplate": "ルール ${0}",
-	
 	"conditionEqual": "等しい",
 	"conditionNotEqual": "等しくない",
-	"conditionLess": "より小",
-	"conditionLessEqual": "より小または等しい",
-	"conditionLarger": "より大",
-	"conditionLargerEqual": "より大または等しい",
+	"conditionLess": "より小さい",
+	"conditionLessEqual": "以下",
+	"conditionLarger": "より大きい",
+	"conditionLargerEqual": "以上",
 	"conditionContains": "含む",
-	"conditionIs": "該当する",
-	"conditionStartsWith": "先頭",
-	"conditionEndWith": "末尾",
+	"conditionIs": "である",
+	"conditionStartsWith": "始まる",
+	"conditionEndWith": "終わる",
 	"conditionNotContain": "含まない",
-	"conditionIsNot": "該当しない",
-	"conditionNotStartWith": "先頭が異なる",
-	"conditionNotEndWith": "末尾が異なる",
-	"conditionBefore": "より前",
-	"conditionAfter": "より後",
+	"conditionIsNot": "ではない",
+	"conditionNotStartWith": "で始まらない",
+	"conditionNotEndWith": "で終わらない",
+	"conditionBefore": "以前",
+	"conditionAfter": "以後",
 	"conditionRange": "範囲",
 	"conditionIsEmpty": "空である",
-	
 	"all": "すべて",
 	"any": "いずれか",
 	"relationAll": "すべてのルール",
 	"waiRelAll": "次のルールのすべてに一致:",
 	"relationAny": "いずれかのルール",
 	"waiRelAny": "次のルールのいずれかに一致:",
-	"relationMsgFront": "一致",
+	"relationMsgFront": "一致: ",
 	"relationMsgTail": "",
 	"and": "かつ",
-	"or": "または",
-	
+	"or": "または ",
 	"addRuleButton": "ルールの追加",
 	"waiAddRuleButton": "新規ルールの追加",
 	"removeRuleButton": "ルールの削除",
 	"waiRemoveRuleButtonTemplate": "ルール ${0} の削除",
-	
 	"cancelButton": "キャンセル",
-	"waiCancelButton": "このダイアログをキャンセル",
+	"waiCancelButton": "このダイアログのキャンセル",
 	"clearButton": "クリア",
 	"waiClearButton": "フィルターのクリア",
 	"filterButton": "フィルター",
-	"waiFilterButton": "フィルターの実行依頼",
-	
+	"waiFilterButton": "フィルターの送信",
 	"columnSelectLabel": "列",
 	"waiColumnSelectTemplate": "ルール ${0} の列",
 	"conditionSelectLabel": "条件",
 	"waiConditionSelectTemplate": "ルール ${0} の条件",
 	"valueBoxLabel": "値",
-	"waiValueBoxTemplate": "ルール ${0} を検出するフィルター操作のための値を入力",
-	
-	"rangeTo": "範囲",
+	"waiValueBoxTemplate": "ルール ${0} のフィルターの値を入力",
+	"rangeTo": "上限",
 	"rangeTemplate": "${0} から ${1} まで",
-	
 	"statusTipHeaderColumn": "列",
 	"statusTipHeaderCondition": "ルール",
 	"statusTipTitle": "フィルター・バー",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "フィルター",
 	"statusTipRelAny": "いずれかのルールに一致。",
 	"statusTipRelAll": "すべてのルールに一致。",
-	
 	"defaultItemsName": "項目",
-	"filterBarMsgHasFilterTemplate": "${0}/${1} ${2} が表示されました。",
+	"filterBarMsgHasFilterTemplate": "${1} ${2} 中 ${0} が表示されています。",
 	"filterBarMsgNoFilterTemplate": "フィルターが適用されていません",
-	
 	"filterBarDefButton": "フィルターの定義",
-	"waiFilterBarDefButton": "表のフィルタリング",
+	"waiFilterBarDefButton": "表のフィルター",
 	"a11yFilterBarDefButton": "フィルター...",
 	"filterBarClearButton": "フィルターのクリア",
 	"waiFilterBarClearButton": "フィルターのクリア",
 	"closeFilterBarBtn": "フィルター・バーを閉じる",
-	
-	"clearFilterMsg": "これによりフィルターが解除され、使用可能なレコードがすべて表示されます。",
+	"clearFilterMsg": "これによりフィルターが削除され、使用可能なすべてのレコードが表示されます。",
 	"anyColumnOption": "いずれかの列",
-	
-	"trueLabel": "True",
-	"falseLabel": "False"
+	"trueLabel": "真",
+	"falseLabel": "偽"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/ja/Pagination.js b/dojox/grid/enhanced/nls/ja/Pagination.js
index 65a88ef..89c3014 100644
--- a/dojox/grid/enhanced/nls/ja/Pagination.js
+++ b/dojox/grid/enhanced/nls/ja/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3}/${1} ${0}",
 	"firstTip": "最初のページ",
@@ -12,12 +11,11 @@ define(
 	"pageSizeLabelTemplate": "ページ当たり ${0} 項目",
 	"allItemsLabelTemplate": "すべての項目",
 	"gotoButtonTitle": "特定のページに移動",
-	"dialogTitle": "ページの移動",
-	"dialogIndication": "ページ番号を指定してください",
+	"dialogTitle": "ページに移動",
+	"dialogIndication": "ページ番号の指定",
 	"pageCountIndication": " (${0} ページ)",
-	"dialogConfirm": "実行",
+	"dialogConfirm": "移動",
 	"dialogCancel": "キャンセル",
 	"all": "すべて"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/kk/EnhancedGrid.js b/dojox/grid/enhanced/nls/kk/EnhancedGrid.js
index 2fb1569..9accdf3 100644
--- a/dojox/grid/enhanced/nls/kk/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/kk/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Бір рет сұрыптау",
 	nestedSort: "Кірістірілген сұрыптау",
-	ascending: "Артуы бойынша",
-	descending: "Кемуі бойынша",
+	ascending: "Артуы бойынша сұрыптауды басу",
+	descending: "Кемуі бойынша сұрыптауды басу",
 	sortingState: "${0} - ${1}",
 	unsorted: "Бұл бағанды сұрыптамау",
-	indirectSelectionRadio: "${0}-жол, жалғыз элементті таңдау, бір түймешікті таңдау тақтасы",
-	indirectSelectionCheckBox: "${0}-жол, бірнеше элементті таңдау, құсбелгі",
+	indirectSelectionRadio: "${0} қатары, жалғыз таңдау, айырып-қосқыш",
+	indirectSelectionCheckBox: "${0} қатары, бірнеше таңдау, құсбелгі",
 	selectAll: "Барлығын таңдау"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/kk/Filter.js b/dojox/grid/enhanced/nls/kk/Filter.js
index 050e065..39137a5 100644
--- a/dojox/grid/enhanced/nls/kk/Filter.js
+++ b/dojox/grid/enhanced/nls/kk/Filter.js
@@ -1,16 +1,14 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Сүзгіні тазалау",
 	"filterDefDialogTitle": "Сүзгі",
 	"ruleTitleTemplate": "${0} ережесі",
-	
 	"conditionEqual": "тең",
 	"conditionNotEqual": "тең емес",
 	"conditionLess": "аздау",
-	"conditionLessEqual": "аздау немесе тең",
+	"conditionLessEqual": "кем немесе тең",
 	"conditionLarger": "үлкендеу",
-	"conditionLargerEqual": "үлкендеу немесе тең",
+	"conditionLargerEqual": "артық немесе тең",
 	"conditionContains": "құрамында бар",
 	"conditionIs": "–",
 	"conditionStartsWith": "басталады",
@@ -22,41 +20,35 @@ define(
 	"conditionBefore": "алдында",
 	"conditionAfter": "артында",
 	"conditionRange": "ауқым",
-	"conditionIsEmpty": "– бос",
-	
+	"conditionIsEmpty": "бос",
 	"all": "барлығы",
 	"any": "кез келген",
 	"relationAll": "барлық ережелер",
 	"waiRelAll": "Барлық мына ережелерге сәйкес:",
 	"relationAny": "кез келген ереже",
 	"waiRelAny": "Мына ережелерге сәйкес:",
-	"relationMsgFront": "Сәйкес келу",
+	"relationMsgFront": "Сәйкестендіру:",
 	"relationMsgTail": "",
 	"and": "және",
 	"or": "немесе",
-	
 	"addRuleButton": "Ереже қосу",
 	"waiAddRuleButton": "Жаңа ереже қосу",
 	"removeRuleButton": "Ережені алып тастау",
 	"waiRemoveRuleButtonTemplate": "${0} ережесін алып тастау",
-	
 	"cancelButton": "Болдырмау",
 	"waiCancelButton": "Осы тілқатысу терезесін болдырмау",
-	"clearButton": "Тазалау ",
+	"clearButton": "Тазалау",
 	"waiClearButton": "Сүзгіні тазалау",
 	"filterButton": "Сүзгі",
 	"waiFilterButton": "Сүзгіні жіберу",
-	
 	"columnSelectLabel": "Баған",
 	"waiColumnSelectTemplate": "${0} ережесінің бағаны",
 	"conditionSelectLabel": "Шарт",
 	"waiConditionSelectTemplate": "${0} ережесінің шарты",
 	"valueBoxLabel": "Мән",
 	"waiValueBoxTemplate": "${0} ережесін сүзу үшін мәнді енгізу",
-	
 	"rangeTo": "неге",
 	"rangeTemplate": "${0} мәнінен ${1} мәніне",
-	
 	"statusTipHeaderColumn": "Баған",
 	"statusTipHeaderCondition": "Ережелер",
 	"statusTipTitle": "Сүзгі тақтасы",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "Сүзгі",
 	"statusTipRelAny": "Кез келген ережелерді сәйкестендіріңіз.",
 	"statusTipRelAll": "Барлық ережелерді сәйкестендіріңіз.",
-	
 	"defaultItemsName": "элементтер",
 	"filterBarMsgHasFilterTemplate": "${1} ${2} ішінен ${0} көрсетілді.",
 	"filterBarMsgNoFilterTemplate": "Сүзгі қолданылмады",
-	
 	"filterBarDefButton": "Сүзгіні анықтау",
 	"waiFilterBarDefButton": "Кестені сүзу",
 	"a11yFilterBarDefButton": "Сүзгі...",
 	"filterBarClearButton": "Сүзгіні тазалау",
 	"waiFilterBarClearButton": "Сүзгіні тазалау",
 	"closeFilterBarBtn": "Сүзгі тақтасын жабу",
-	
 	"clearFilterMsg": "Бұл сүзгіні жояды және барлық қол жетімді жазбаларды көрсетеді.",
 	"anyColumnOption": "Кез келген баған",
-	
 	"trueLabel": "Шын",
 	"falseLabel": "Жалған"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/kk/Pagination.js b/dojox/grid/enhanced/nls/kk/Pagination.js
index 3c96d49..661f694 100644
--- a/dojox/grid/enhanced/nls/kk/Pagination.js
+++ b/dojox/grid/enhanced/nls/kk/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${1} ${0} элементтің ${2} - ${3} элементі",
 	"firstTip": "Бірінші бет",
@@ -17,7 +16,6 @@ define(
 	"pageCountIndication": " (${0} бет)",
 	"dialogConfirm": "Өту",
 	"dialogCancel": "Болдырмау",
-	"all": "барлығы"
+	"all": "Барлығы"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/ko/EnhancedGrid.js b/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
index 6e97a42..93b7787 100644
--- a/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "단일 정렬",
 	nestedSort: "중첩된 정렬",
-	ascending: "오름차순",
-	descending: "내림차순",
+	ascending: "오름차순으로 정렬하려면 클릭",
+	descending: "내림차순으로 정렬하려면 클릭",
 	sortingState: "${0} - ${1}",
-	unsorted: "이 컬럼은 정렬하지 마십시오",
-	indirectSelectionRadio: "행 ${0}, 단일 선택, 라디오 상자",
+	unsorted: "이 컬럼을 정렬하지 않음",
+	indirectSelectionRadio: "행 ${0}, 단일 선택, 단일 선택 단추",
 	indirectSelectionCheckBox: "행 ${0}, 다중 선택, 선택란",
 	selectAll: "모두 선택"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/ko/Filter.js b/dojox/grid/enhanced/nls/ko/Filter.js
index fc44d89..b66f89c 100644
--- a/dojox/grid/enhanced/nls/ko/Filter.js
+++ b/dojox/grid/enhanced/nls/ko/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "필터 지우기",
 	"filterDefDialogTitle": "필터",
 	"ruleTitleTemplate": "규칙 ${0}",
-	
 	"conditionEqual": "같음",
 	"conditionNotEqual": "같지 않음",
 	"conditionLess": "미만",
@@ -22,41 +20,35 @@ define(
 	"conditionBefore": "이전",
 	"conditionAfter": "이후",
 	"conditionRange": "범위",
-	"conditionIsEmpty": "다음이 비어있음",
-	
+	"conditionIsEmpty": "비어있음",
 	"all": "모두",
 	"any": "임의",
 	"relationAll": "모든 규칙",
 	"waiRelAll": "다음 규칙에 모두 일치:",
 	"relationAny": "임의 규칙",
 	"waiRelAny": "다음 규칙 중에 일치:",
-	"relationMsgFront": "일치",
+	"relationMsgFront": "일치:",
 	"relationMsgTail": "",
 	"and": "및",
 	"or": "또는",
-	
 	"addRuleButton": "규칙 추가",
 	"waiAddRuleButton": "새 규칙 추가",
 	"removeRuleButton": "규칙 제거",
 	"waiRemoveRuleButtonTemplate": "${0} 규칙 제거",
-	
 	"cancelButton": "취소",
 	"waiCancelButton": "이 대화 상자 취소",
 	"clearButton": "지우기",
 	"waiClearButton": "해당 필터 지우기",
 	"filterButton": "필터",
 	"waiFilterButton": "필터 제출",
-	
 	"columnSelectLabel": "컬럼",
 	"waiColumnSelectTemplate": "${0} 규칙에 대한 컬럼",
 	"conditionSelectLabel": "조건",
 	"waiConditionSelectTemplate": "${0} 규칙에 대한 조건",
 	"valueBoxLabel": "값",
 	"waiValueBoxTemplate": "${0} 규칙에 대해 필터링할 값 입력",
-	
 	"rangeTo": "다음에서 종료",
 	"rangeTemplate": "${0}에서 ${1}까지",
-	
 	"statusTipHeaderColumn": "컬럼",
 	"statusTipHeaderCondition": "규칙",
 	"statusTipTitle": "필터 표시줄",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "필터",
 	"statusTipRelAny": "임의 규칙과 일치.",
 	"statusTipRelAll": "모든 규칙과 일치.",
-	
 	"defaultItemsName": "항목",
-	"filterBarMsgHasFilterTemplate": "${0}/${1} ${2} 표시됨",
+	"filterBarMsgHasFilterTemplate": "${1} ${2}의 ${0}이(가) 표시됩니다.",
 	"filterBarMsgNoFilterTemplate": "적용된 필터 없음",
-	
 	"filterBarDefButton": "필터 정의",
 	"waiFilterBarDefButton": "표 필터링",
 	"a11yFilterBarDefButton": "필터...",
 	"filterBarClearButton": "필터 지우기",
 	"waiFilterBarClearButton": "해당 필터 지우기",
 	"closeFilterBarBtn": "필터 표시줄 닫기",
-	
 	"clearFilterMsg": "이로 인해 해당 필터가 제거되며 사용 가능한 모든 레코드가 표시됩니다.",
 	"anyColumnOption": "임의의 컬럼",
-	
 	"trueLabel": "True",
 	"falseLabel": "False"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/ko/Pagination.js b/dojox/grid/enhanced/nls/ko/Pagination.js
index 250f72a..9378829 100644
--- a/dojox/grid/enhanced/nls/ko/Pagination.js
+++ b/dojox/grid/enhanced/nls/ko/Pagination.js
@@ -1,24 +1,21 @@
 define(
-//begin v1.x content
 ({
-	"descTemplate": "${1} ${0} 중 ${2} - ${3}",
-	"firstTip": "첫 번째 페이지",
+	"descTemplate": "${2} - ${3}/${1} ${0}",
+	"firstTip": "첫 페이지",
 	"lastTip": "마지막 페이지",
 	"nextTip": "다음 페이지",
 	"prevTip": "이전 페이지",
 	"itemTitle": "항목",
 	"singularItemTitle": "항목",
-	"pageStepLabelTemplate": "페이지 ${0}",
-	"pageSizeLabelTemplate": "페이지 당 ${0} 항목",
+	"pageStepLabelTemplate": "${0} 페이지",
+	"pageSizeLabelTemplate": "페이지당 ${0}개 항목",
 	"allItemsLabelTemplate": "모든 항목",
 	"gotoButtonTitle": "특정 페이지로 이동",
-	"dialogTitle": "페이지로 이동",
+	"dialogTitle": "페이지 이동",
 	"dialogIndication": "페이지 번호 지정",
-	"pageCountIndication": " (${0} 페이지)",
+	"pageCountIndication": " (${0}페이지)",
 	"dialogConfirm": "이동",
 	"dialogCancel": "취소",
 	"all": "모두"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/nb/EnhancedGrid.js b/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
index b5a7182..cde4061 100644
--- a/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
-	singleSort: "Enkeltsortering",
+	singleSort: "Enkel sortering",
 	nestedSort: "Nestet sortering",
-	ascending: "Stigende",
-	descending: "Synkende",
+	ascending: "Klikk for å sortere stigende",
+	descending: "Klikk for å sortere synkende",
 	sortingState: "${0} - ${1}",
 	unsorted: "Ikke sorter denne kolonnen",
 	indirectSelectionRadio: "Rad ${0}, enkeltvalg, valgknapp",
 	indirectSelectionCheckBox: "Rad ${0}, flervalg, avmerkingsboks",
 	selectAll: "Velg alle"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/nb/Filter.js b/dojox/grid/enhanced/nls/nb/Filter.js
index 912fa72..1ee7711 100644
--- a/dojox/grid/enhanced/nls/nb/Filter.js
+++ b/dojox/grid/enhanced/nls/nb/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Tøm filter",
 	"filterDefDialogTitle": "Filter",
 	"ruleTitleTemplate": "Regel ${0}",
-	
 	"conditionEqual": "er lik",
 	"conditionNotEqual": "er ikke lik",
 	"conditionLess": "er mindre enn",
@@ -13,76 +11,65 @@ define(
 	"conditionLargerEqual": "større enn eller lik",
 	"conditionContains": "inneholder",
 	"conditionIs": "er",
-	"conditionStartsWith": "starter med",
+	"conditionStartsWith": "begynner med",
 	"conditionEndWith": "slutter med",
 	"conditionNotContain": "inneholder ikke",
 	"conditionIsNot": "er ikke",
-	"conditionNotStartWith": "starter ikke med",
+	"conditionNotStartWith": "begynner ikke med",
 	"conditionNotEndWith": "slutter ikke med",
 	"conditionBefore": "før",
 	"conditionAfter": "etter",
 	"conditionRange": "område",
 	"conditionIsEmpty": "er tom",
-	
 	"all": "alle",
 	"any": "minst en",
 	"relationAll": "alle regler",
-	"waiRelAll": "Samsvar med alle disse reglene:",
+	"waiRelAll": "Samsvar med alle følgende regler:",
 	"relationAny": "minst en regel",
-	"waiRelAny": "Samsvar med minst en av disse reglene:",
-	"relationMsgFront": "Samsvar med",
+	"waiRelAny": "Samsvar med minst en av følgende regler:",
+	"relationMsgFront": "Samsvar:",
 	"relationMsgTail": "",
 	"and": "og",
 	"or": "eller",
-	
 	"addRuleButton": "Legg til regel",
 	"waiAddRuleButton": "Legg til en ny regel",
 	"removeRuleButton": "Fjern regel",
 	"waiRemoveRuleButtonTemplate": "Fjern regel ${0}",
-	
 	"cancelButton": "Avbryt",
 	"waiCancelButton": "Avbryt denne dialogboksen",
 	"clearButton": "Tøm",
 	"waiClearButton": "Tøm filteret",
 	"filterButton": "Filtrer",
 	"waiFilterButton": "Send filteret",
-	
 	"columnSelectLabel": "Kolonne",
 	"waiColumnSelectTemplate": "Kolonne for regel ${0}",
 	"conditionSelectLabel": "Betingelse",
 	"waiConditionSelectTemplate": "Betingelse for regel ${0}",
 	"valueBoxLabel": "Verdi",
-	"waiValueBoxTemplate": "Oppgi verdi som skal filtreres for regel ${0}",
-	
+	"waiValueBoxTemplate": "Angi verdi som skal filtreres for regel ${0}",
 	"rangeTo": "til",
 	"rangeTemplate": "fra ${0} til ${1}",
-	
 	"statusTipHeaderColumn": "Kolonne",
 	"statusTipHeaderCondition": "Regler",
 	"statusTipTitle": "Filterlinje",
-	"statusTipMsg": "Klikk på filterlinjen her for å filtrere på verdiene i ${0}.",
+	"statusTipMsg": "Klikk på filterlinjen her for å filtrere på verdier i ${0}.",
 	"anycolumn": "enhver kolonne",
 	"statusTipTitleNoFilter": "Filterlinje",
 	"statusTipTitleHasFilter": "Filter",
 	"statusTipRelAny": "Samsvar med minst en regel.",
 	"statusTipRelAll": "Samsvar med alle regler.",
-	
 	"defaultItemsName": "elementer",
 	"filterBarMsgHasFilterTemplate": "${0} av ${1} ${2} vist.",
-	"filterBarMsgNoFilterTemplate": "Ikke brukt filter",
-	
+	"filterBarMsgNoFilterTemplate": "Det er ikke brukt filter",
 	"filterBarDefButton": "Definer filter",
 	"waiFilterBarDefButton": "Filtrer tabellen",
 	"a11yFilterBarDefButton": "Filtrer...",
 	"filterBarClearButton": "Tøm filter",
 	"waiFilterBarClearButton": "Tøm filteret",
-	"closeFilterBarBtn": "Lukk filterlinjen",
-	
+	"closeFilterBarBtn": "Lukk filterlinje",
 	"clearFilterMsg": "Dette fjerner filteret og viser alle tilgjengelige poster.",
-	"anyColumnOption": "Minst en kolonne",
-	
+	"anyColumnOption": "Enhver kolonne",
 	"trueLabel": "Sann",
 	"falseLabel": "Usann"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/nb/Pagination.js b/dojox/grid/enhanced/nls/nb/Pagination.js
index 74795dd..f316d91 100644
--- a/dojox/grid/enhanced/nls/nb/Pagination.js
+++ b/dojox/grid/enhanced/nls/nb/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} av ${1} ${0}",
 	"firstTip": "Første side",
@@ -13,11 +12,10 @@ define(
 	"allItemsLabelTemplate": "Alle elementer",
 	"gotoButtonTitle": "Gå til en bestemt side",
 	"dialogTitle": "Gå til side",
-	"dialogIndication": "Oppgi sidetallet",
+	"dialogIndication": "Angi sidetall",
 	"pageCountIndication": " (${0} sider)",
-	"dialogConfirm": "Utfør",
+	"dialogConfirm": "OK",
 	"dialogCancel": "Avbryt",
-	"all": "alle"
+	"all": "Alle"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/nl/EnhancedGrid.js b/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
index c048fd2..a03f519 100644
--- a/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Enkelvoudig sorteren",
 	nestedSort: "Genest sorteren",
-	ascending: "Oplopend",
-	descending: "Aflopend",
+	ascending: "Klik hier voor oplopend sorteren",
+	descending: "Klik hier voor aflopend sorteren",
 	sortingState: "${0} - ${1}",
 	unsorted: "Deze kolom niet sorteren",
 	indirectSelectionRadio: "Rij ${0}, enkele selectie, keuzerondje",
 	indirectSelectionCheckBox: "Rij ${0}, meerdere selecties, selectievakje",
 	selectAll: "Alles selecteren"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/nl/Filter.js b/dojox/grid/enhanced/nls/nl/Filter.js
index 6f2f24a..b3173f2 100644
--- a/dojox/grid/enhanced/nls/nl/Filter.js
+++ b/dojox/grid/enhanced/nls/nl/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Filter wissen",
-	"filterDefDialogTitle": "Filteren",
+	"filterDefDialogTitle": "Filter",
 	"ruleTitleTemplate": "Regel ${0}",
-	
 	"conditionEqual": "gelijk aan",
 	"conditionNotEqual": "niet gelijk aan",
 	"conditionLess": "is kleiner dan",
@@ -14,7 +12,7 @@ define(
 	"conditionContains": "bevat",
 	"conditionIs": "is",
 	"conditionStartsWith": "begint met",
-	"conditionEndWith": "eindigt op",
+	"conditionEndWith": "eindigt met",
 	"conditionNotContain": "bevat niet",
 	"conditionIsNot": "is niet",
 	"conditionNotStartWith": "begint niet met",
@@ -23,40 +21,34 @@ define(
 	"conditionAfter": "na",
 	"conditionRange": "bereik",
 	"conditionIsEmpty": "is leeg",
-	
 	"all": "alle",
 	"any": "een of meer",
 	"relationAll": "alle regels",
 	"waiRelAll": "Voldoen aan al deze regels:",
 	"relationAny": "een of meer regels",
 	"waiRelAny": "Voldoen aan een van deze regels:",
-	"relationMsgFront": "Voldoen aan",
+	"relationMsgFront": "Voldoen aan:",
 	"relationMsgTail": "",
 	"and": "en",
 	"or": "of",
-	
 	"addRuleButton": "Regel toevoegen",
 	"waiAddRuleButton": "Een nieuwe regel toevoegen",
 	"removeRuleButton": "Regel verwijderen",
 	"waiRemoveRuleButtonTemplate": "Regel ${0} verwijderen",
-	
 	"cancelButton": "Annuleren",
 	"waiCancelButton": "Dit dialoogvenster annuleren",
 	"clearButton": "Leegmaken",
 	"waiClearButton": "Het filter wissen",
-	"filterButton": "Filteren",
+	"filterButton": "Filter",
 	"waiFilterButton": "Het filter verzenden",
-	
 	"columnSelectLabel": "Kolom",
 	"waiColumnSelectTemplate": "Kolom voor regel ${0}",
 	"conditionSelectLabel": "Voorwaarde",
 	"waiConditionSelectTemplate": "Voorwaarde voor regel ${0}",
 	"valueBoxLabel": "Waarde",
 	"waiValueBoxTemplate": "Geef een filterwaarde op voor regel ${0}",
-	
 	"rangeTo": "tot",
 	"rangeTemplate": "van ${0} tot ${1}",
-	
 	"statusTipHeaderColumn": "Kolom",
 	"statusTipHeaderCondition": "Regels",
 	"statusTipTitle": "Filterbalk",
@@ -64,25 +56,20 @@ define(
 	"anycolumn": "een kolom",
 	"statusTipTitleNoFilter": "Filterbalk",
 	"statusTipTitleHasFilter": "Filter",
-	"statusTipRelAny": "Voldoen aan een van de regels.",
+	"statusTipRelAny": "Voldoen aan een regel.",
 	"statusTipRelAll": "Voldoen aan alle regels.",
-	
 	"defaultItemsName": "items",
 	"filterBarMsgHasFilterTemplate": "${0} van ${1} ${2} afgebeeld.",
 	"filterBarMsgNoFilterTemplate": "Geen filter toegepast",
-	
 	"filterBarDefButton": "Filter definiëren",
 	"waiFilterBarDefButton": "De tabel filteren",
 	"a11yFilterBarDefButton": "Filteren...",
 	"filterBarClearButton": "Filter wissen",
 	"waiFilterBarClearButton": "Het filter wissen",
 	"closeFilterBarBtn": "Filterbalk sluiten",
-	
 	"clearFilterMsg": "Hiermee verwijdert u het filter en worden alle beschikbare records afgebeeld.",
 	"anyColumnOption": "Een kolom",
-	
 	"trueLabel": "Waar",
 	"falseLabel": "Onwaar"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/nl/Pagination.js b/dojox/grid/enhanced/nls/nl/Pagination.js
index 063b9f6..6a28aa7 100644
--- a/dojox/grid/enhanced/nls/nl/Pagination.js
+++ b/dojox/grid/enhanced/nls/nl/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} van ${1} ${0}",
 	"firstTip": "Eerste pagina",
@@ -11,14 +10,12 @@ define(
 	"pageStepLabelTemplate": "Pagina ${0}",
 	"pageSizeLabelTemplate": "${0} items per pagina",
 	"allItemsLabelTemplate": "Alle items",
-	"gotoButtonTitle": "Ga naar bepaalde pagina",
-	"dialogTitle": "Ga naar pagina",
-	"dialogIndication": "Geef het paginanummer op",
+	"gotoButtonTitle": "Naar een specifieke pagina gaan",
+	"dialogTitle": "Naar pagina gaan",
+	"dialogIndication": "Geef het paginanummer op:",
 	"pageCountIndication": " (${0} pagina's)",
 	"dialogConfirm": "Go",
 	"dialogCancel": "Annuleren",
-	"all": "alle"
+	"all": "Alles"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/pl/EnhancedGrid.js b/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
index a391a5f..758eada 100644
--- a/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
-	singleSort: "Pojedyncze sortowanie",
-	nestedSort: "Zagnieżdżone sortowanie",
-	ascending: "Rosnąco",
-	descending: "Malejąco",
+	singleSort: "Sortowanie pojedyncze",
+	nestedSort: "Sortowanie zagnieżdżone",
+	ascending: "Kliknij, aby posortować rosnąco",
+	descending: "Kliknij, aby posortować malejąco",
 	sortingState: "${0} - ${1}",
 	unsorted: "Nie sortuj tej kolumny",
 	indirectSelectionRadio: "Wiersz ${0}, pojedynczy wybór, zestaw przełączników",
 	indirectSelectionCheckBox: "Wiersz ${0}, wybór wielokrotny, pole wyboru",
 	selectAll: "Wybierz wszystko"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/pl/Filter.js b/dojox/grid/enhanced/nls/pl/Filter.js
index 2edfcf2..ddaa6d9 100644
--- a/dojox/grid/enhanced/nls/pl/Filter.js
+++ b/dojox/grid/enhanced/nls/pl/Filter.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Wyczyść filtr",
 	"filterDefDialogTitle": "Filtr",
 	"ruleTitleTemplate": "Reguła ${0}",
-	
 	"conditionEqual": "równe",
-	"conditionNotEqual": "różne od",
-	"conditionLess": "mniejsze od",
+	"conditionNotEqual": "nie jest równe",
+	"conditionLess": "jest mniejsze niż",
 	"conditionLessEqual": "mniejsze lub równe",
-	"conditionLarger": "większe od",
+	"conditionLarger": "jest większe niż",
 	"conditionLargerEqual": "większe lub równe",
 	"conditionContains": "zawiera",
 	"conditionIs": "jest",
@@ -23,66 +21,55 @@ define(
 	"conditionAfter": "po",
 	"conditionRange": "zakres",
 	"conditionIsEmpty": "jest pusty",
-	
 	"all": "wszystkie",
 	"any": "dowolne",
 	"relationAll": "wszystkie reguły",
-	"waiRelAll": "Dopasuj wszystkie poniższe reguły:",
-	"relationAny": "dowolna reguła",
-	"waiRelAny": "Dopasuj dowolną z poniższych reguł:",
-	"relationMsgFront": "Dopasuj",
+	"waiRelAll": "Dopasuj wszystkie następujące reguły:",
+	"relationAny": "dowolne reguły",
+	"waiRelAny": "Dopasuj dowolne z następujących reguł:",
+	"relationMsgFront": "Dopasuj:",
 	"relationMsgTail": "",
-	"and": "i",
+	"and": "oraz",
 	"or": "lub",
-	
 	"addRuleButton": "Dodaj regułę",
 	"waiAddRuleButton": "Dodaj nową regułę",
 	"removeRuleButton": "Usuń regułę",
 	"waiRemoveRuleButtonTemplate": "Usuń regułę ${0}",
-	
 	"cancelButton": "Anuluj",
 	"waiCancelButton": "Anuluj to okno dialogowe",
 	"clearButton": "Wyczyść",
 	"waiClearButton": "Wyczyść filtr",
-	"filterButton": "Filtruj",
-	"waiFilterButton": "Wprowadź ten filtr",
-	
+	"filterButton": "Filtr",
+	"waiFilterButton": "Wyślij filtr",
 	"columnSelectLabel": "Kolumna",
-	"waiColumnSelectTemplate": "Kolumna dla reguły ${0}",
+	"waiColumnSelectTemplate": "Kolumna reguły ${0}",
 	"conditionSelectLabel": "Warunek",
-	"waiConditionSelectTemplate": "Warunek dla reguły ${0}",
+	"waiConditionSelectTemplate": "Warunek reguły ${0}",
 	"valueBoxLabel": "Wartość",
-	"waiValueBoxTemplate": "Wprowadź wartość, aby filtrować dla reguły ${0}",
-	
+	"waiValueBoxTemplate": "Wprowadź wartość filtru dla reguły ${0}",
 	"rangeTo": "do",
 	"rangeTemplate": "od ${0} do ${1}",
-	
 	"statusTipHeaderColumn": "Kolumna",
 	"statusTipHeaderCondition": "Reguły",
 	"statusTipTitle": "Pasek filtru",
-	"statusTipMsg": "Kliknij pasek filtru tutaj, aby filtrować według wartości w ${0}.",
+	"statusTipMsg": "Kliknij pasek filtru w tym miejscu, aby filtrować wartości znajdujące się w ${0}. ",
 	"anycolumn": "dowolna kolumna",
 	"statusTipTitleNoFilter": "Pasek filtru",
 	"statusTipTitleHasFilter": "Filtr",
 	"statusTipRelAny": "Dopasuj do dowolnej z reguł.",
 	"statusTipRelAll": "Dopasuj do wszystkich reguł.",
-	
 	"defaultItemsName": "elementy",
-	"filterBarMsgHasFilterTemplate": "Wyświetlane ${0} z ${1} ${2}.",
-	"filterBarMsgNoFilterTemplate": "Filtr wyłączony",
-	
+	"filterBarMsgHasFilterTemplate": "Liczba wyświetlanych elementów ${2}: ${0} z ${1}. ",
+	"filterBarMsgNoFilterTemplate": "Nie zastosowano żadnego filtru",
 	"filterBarDefButton": "Zdefiniuj filtr",
 	"waiFilterBarDefButton": "Filtruj tabelę",
 	"a11yFilterBarDefButton": "Filtruj...",
 	"filterBarClearButton": "Wyczyść filtr",
 	"waiFilterBarClearButton": "Wyczyść filtr",
 	"closeFilterBarBtn": "Zamknij pasek filtru",
-	
-	"clearFilterMsg": "Filtr zostanie usunięty i wyświetlone będą wszystkie dostępne rekordy.",
+	"clearFilterMsg": "Spowoduje to usunięcie filtru oraz wyświetlenie wszystkich dostępnych rekordów. ",
 	"anyColumnOption": "Dowolna kolumna",
-	
 	"trueLabel": "Prawda",
 	"falseLabel": "Fałsz"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/pl/Pagination.js b/dojox/grid/enhanced/nls/pl/Pagination.js
index 042bdd8..6331200 100644
--- a/dojox/grid/enhanced/nls/pl/Pagination.js
+++ b/dojox/grid/enhanced/nls/pl/Pagination.js
@@ -1,24 +1,21 @@
 define(
-//begin v1.x content
 ({
-	"descTemplate": "${2} - ${3} z ${1} ${0}",
+	"descTemplate": "Od ${2} do ${3} z ${1} ${0}",
 	"firstTip": "Pierwsza strona",
 	"lastTip": "Ostatnia strona",
 	"nextTip": "Następna strona",
 	"prevTip": "Poprzednia strona",
-	"itemTitle": "poz.",
-	"singularItemTitle": "pozycja",
+	"itemTitle": "elementy",
+	"singularItemTitle": "item",
 	"pageStepLabelTemplate": "Strona ${0}",
-	"pageSizeLabelTemplate": "${0} poz. na stronę",
-	"allItemsLabelTemplate": "Wszystkie pozycje",
-	"gotoButtonTitle": "Idź do konkretnej strony",
-	"dialogTitle": "Idź do strony",
-	"dialogIndication": "Podaj numer strony",
-	"pageCountIndication": " (${0} str.)",
-	"dialogConfirm": "Wykonaj",
+	"pageSizeLabelTemplate": "Liczba elementów na stronę: ${0}",
+	"allItemsLabelTemplate": "Wszystkie elementy",
+	"gotoButtonTitle": "Przejdź do konkretnej strony",
+	"dialogTitle": "Przechodzenie do strony",
+	"dialogIndication": "Określ numer strony",
+	"pageCountIndication": " (liczba stron: ${0})",
+	"dialogConfirm": "Przejdź",
 	"dialogCancel": "Anuluj",
-	"all": "wszystkie"
+	"all": "Wszystko"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js b/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js
deleted file mode 100644
index 6232cdd..0000000
--- a/dojox/grid/enhanced/nls/pt-br/EnhancedGrid.js
+++ /dev/null
@@ -1,12 +0,0 @@
-({
-	singleSort: "Classificação Única",
-	nestedSort: "Classificação Aninhada",
-	ascending: "Crescente",
-	descending: "Decrescente",
-	sortingState: "${0} - ${1}",
-	unsorted: "Não classificar esta coluna",
-	indirectSelectionRadio: "Linha ${0}, seleção única, caixa de opção",
-	indirectSelectionCheckBox: "Linha ${0}, seleção múltipla, caixa de seleção",
-	selectAll: "Selecionar todos"
-})
-
diff --git a/dojox/grid/enhanced/nls/pt-br/Filter.js b/dojox/grid/enhanced/nls/pt-br/Filter.js
deleted file mode 100644
index b96eaa8..0000000
--- a/dojox/grid/enhanced/nls/pt-br/Filter.js
+++ /dev/null
@@ -1,85 +0,0 @@
-({
-	"clearFilterDialogTitle": "Limpar Filtro",
-	"filterDefDialogTitle": "Filtrar",
-	"ruleTitleTemplate": "Regra ${0}",
-	
-	"conditionEqual": "igual",
-	"conditionNotEqual": "não é igual",
-	"conditionLess": "é menor que",
-	"conditionLessEqual": "menor que ou igual",
-	"conditionLarger": "é maior que",
-	"conditionLargerEqual": "maior que ou igual",
-	"conditionContains": "contém",
-	"conditionIs": "é",
-	"conditionStartsWith": "começa com",
-	"conditionEndWith": "termina com",
-	"conditionNotContain": "não contém",
-	"conditionIsNot": "não é",
-	"conditionNotStartWith": "não começa com",
-	"conditionNotEndWith": "não termina com",
-	"conditionBefore": "antes",
-	"conditionAfter": "após",
-	"conditionRange": "intervalo",
-	"conditionIsEmpty": "está vazio",
-	
-	"all": "todos",
-	"any": "qualquer",
-	"relationAll": "todas as regras",
-	"waiRelAll": "Corresponder todas as regras a seguir:",
-	"relationAny": "quaisquer regras",
-	"waiRelAny": "Corresponder qualquer uma das regras a seguir:",
-	"relationMsgFront": "Corresponder",
-	"relationMsgTail": "",
-	"and": "e",
-	"or": "ou",
-	
-	"addRuleButton": "Incluir Regra",
-	"waiAddRuleButton": "Incluir uma nova regra",
-	"removeRuleButton": "Remover Regra",
-	"waiRemoveRuleButtonTemplate": "Remover regra ${0}",
-	
-	"cancelButton": "Cancelar",
-	"waiCancelButton": "cancelar este diálogo",
-	"clearButton": "Limpar",
-	"waiClearButton": "Limpar o filtro",
-	"filterButton": "Filtrar",
-	"waiFilterButton": "Submeter o filtro",
-	
-	"columnSelectLabel": "Coluna",
-	"waiColumnSelectTemplate": "Coluna para a regra ${0}",
-	"conditionSelectLabel": "Condição",
-	"waiConditionSelectTemplate": "Condição para a regra ${0}",
-	"valueBoxLabel": "Valor",
-	"waiValueBoxTemplate": "Inserir o valor para filtro para a regra ${0}",
-	
-	"rangeTo": "para",
-	"rangeTemplate": "de ${0} para ${1}",
-	
-	"statusTipHeaderColumn": "Coluna",
-	"statusTipHeaderCondition": "Regras",
-	"statusTipTitle": "Barra de Filtro",
-	"statusTipMsg": "Clique aqui na barra de filtro para filtrar os valores em ${0}.",
-	"anycolumn": "qualquer coluna",
-	"statusTipTitleNoFilter": "Barra de Filtro",
-	"statusTipTitleHasFilter": "Filtrar",
-	
-	"defaultItemsName": "itens",
-	"filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} mostrado.",
-	"filterBarMsgNoFilterTemplate": "Nenhum filtro aplicado",
-	
-	"filterBarDefButton": "Definir filtro",
-	"waiFilterBarDefButton": "Filtrar a tabela",
-	"a11yFilterBarDefButton": "Filtrar...",
-	"filterBarClearButton": "Limpar Filtro",
-	"waiFilterBarClearButton": "Limpar o filtro",
-	"closeFilterBarBtn": "Fechar a barra de filtro",
-	
-	"clearFilterMsg": "Isso removerá o filtro e mostrará todos os registros disponíveis.",
-	"anyColumnOption": "Qualquer Coluna",
-	
-	"trueLabel": "Verdadeiro",
-	"falseLabel": "Falso"
-})
-
-
-
diff --git a/dojox/grid/enhanced/nls/pt-br/Pagination.js b/dojox/grid/enhanced/nls/pt-br/Pagination.js
deleted file mode 100644
index b1cfc6d..0000000
--- a/dojox/grid/enhanced/nls/pt-br/Pagination.js
+++ /dev/null
@@ -1,32 +0,0 @@
-({
-	// ${0}: string
-	//		unit of item, identified by "itemTitle"
-	// ${2}: number
-	//		start item index of current page
-	// ${3}: number
-	//		end item index of current page
-	// ${1}: number
-	//		total number of all items
-	// example:
-	//		the total number is 200, the unit of item is "items"
-	//		rows per page is 20, current page is 1, then the description
-	//		would be looked as below:
-	//	|	1 - 20 of 200 items 
-	"descTemplate": "${2} - ${3} de ${1} ${0}",
-	"firstTip": "Primeira Página",
-	"lastTip": "Última Página",
-	"nextTip": "Próxima Página",
-	"prevTip": "Página Anterior",
-	"itemTitle": "itens",
-	"singularItemTitle": "item",
-	"pageStepLabelTemplate": "Página ${0}",
-	"pageSizeLabelTemplate": "${0} itens por página",
-	"allItemsLabelTemplate": "Todos os itens",
-	"gotoButtonTitle": "Ir para uma página específica",
-	"dialogTitle": "Ir para a página",
-	"dialogIndication": "Especificar o número da página",
-	"pageCountIndication": " (${0} páginas)",
-	"dialogConfirm": "Ir",
-	"dialogCancel": "Cancelar",
-	"all": "todos"
-})
diff --git a/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js b/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js
index 696992d..6364307 100644
--- a/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/pt-pt/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Ordenação única",
 	nestedSort: "Ordenação imbricada",
-	ascending: "Ascendente",
-	descending: "Descendente",
+	ascending: "Faça clique para ordenar Ascendente",
+	descending: "Faça clique para ordenar Descendente",
 	sortingState: "${0} - ${1}",
 	unsorted: "Não ordenar esta coluna",
 	indirectSelectionRadio: "Fila ${0}, selecção única, caixa de opção",
-	indirectSelectionCheckBox: "Fila ${0}, selecção múltipla, quadrado de confirmação",
+	indirectSelectionCheckBox: "Fila ${0}, selecção múltipla, caixa de verificação",
 	selectAll: "Seleccionar tudo"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/pt-pt/Filter.js b/dojox/grid/enhanced/nls/pt-pt/Filter.js
index c8d7fc0..111fcb7 100644
--- a/dojox/grid/enhanced/nls/pt-pt/Filter.js
+++ b/dojox/grid/enhanced/nls/pt-pt/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Limpar filtro",
 	"filterDefDialogTitle": "Filtro",
 	"ruleTitleTemplate": "Regra ${0}",
-	
 	"conditionEqual": "igual",
 	"conditionNotEqual": "não é igual",
 	"conditionLess": "é menor do que",
@@ -23,40 +21,34 @@ define(
 	"conditionAfter": "após",
 	"conditionRange": "intervalo",
 	"conditionIsEmpty": "está vazio",
-	
 	"all": "tudo",
 	"any": "qualquer",
 	"relationAll": "todas as regras",
 	"waiRelAll": "Corresponder a todas as seguintes regras:",
 	"relationAny": "quaisquer regras",
 	"waiRelAny": "Corresponder a qualquer uma das seguintes regras:",
-	"relationMsgFront": "Corresponder",
+	"relationMsgFront": "Corresponder:",
 	"relationMsgTail": "",
 	"and": "and",
 	"or": "or",
-	
 	"addRuleButton": "Adicionar regra",
 	"waiAddRuleButton": "Adicionar uma nova regra",
 	"removeRuleButton": "Remover regra",
 	"waiRemoveRuleButtonTemplate": "Remover regra ${0}",
-	
 	"cancelButton": "Cancelar",
 	"waiCancelButton": "Cancelar esta caixa de diálogo",
 	"clearButton": "Limpar",
 	"waiClearButton": "Limpar o filtro",
 	"filterButton": "Filtro",
 	"waiFilterButton": "Submeter o filtro",
-	
 	"columnSelectLabel": "Coluna",
 	"waiColumnSelectTemplate": "Coluna para a regra ${0}",
 	"conditionSelectLabel": "Condição",
 	"waiConditionSelectTemplate": "Condição para a regra ${0}",
 	"valueBoxLabel": "Valor",
 	"waiValueBoxTemplate": "Introduzir valor para filtrar para a regra ${0}",
-	
 	"rangeTo": "a",
 	"rangeTemplate": "de ${0} a ${1}",
-	
 	"statusTipHeaderColumn": "Coluna",
 	"statusTipHeaderCondition": "Regras",
 	"statusTipTitle": "Barra do filtro",
@@ -64,26 +56,20 @@ define(
 	"anycolumn": "qualquer coluna",
 	"statusTipTitleNoFilter": "Barra do filtro",
 	"statusTipTitleHasFilter": "Filtro",
-	
-	"defaultItemsName": "itens",
+	"statusTipRelAny": "Corresponder quaisquer regras.",
+	"statusTipRelAll": "Corresponder todas as regras.",
+	"defaultItemsName": "artigos",
 	"filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} apresentado(s).",
 	"filterBarMsgNoFilterTemplate": "Nenhum filtro aplicado",
-	
 	"filterBarDefButton": "Definir filtro",
 	"waiFilterBarDefButton": "Filtrar a tabela",
 	"a11yFilterBarDefButton": "Filtrar...",
 	"filterBarClearButton": "Limpar filtro",
 	"waiFilterBarClearButton": "Limpar o filtro",
 	"closeFilterBarBtn": "Fechar barra de filtro",
-	
 	"clearFilterMsg": "Este procedimento irá remover o filtro e apresentar todos os registos disponíveis.",
 	"anyColumnOption": "Qualquer coluna",
-	
 	"trueLabel": "True",
 	"falseLabel": "False"
 })
-//end v1.x content
 );
-
-
-
diff --git a/dojox/grid/enhanced/nls/pt-pt/Pagination.js b/dojox/grid/enhanced/nls/pt-pt/Pagination.js
index cbd7d63..8ef369d 100644
--- a/dojox/grid/enhanced/nls/pt-pt/Pagination.js
+++ b/dojox/grid/enhanced/nls/pt-pt/Pagination.js
@@ -1,23 +1,21 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} de ${1} ${0}",
 	"firstTip": "Primeira página",
 	"lastTip": "Última página",
 	"nextTip": "Página seguinte",
 	"prevTip": "Página anterior",
-	"itemTitle": "itens",
+	"itemTitle": "artigos",
+	"singularItemTitle": "artigo",
 	"pageStepLabelTemplate": "Página ${0}",
-	"pageSizeLabelTemplate": "${0} itens por página",
-	"allItemsLabelTemplate": "Todos os itens",
+	"pageSizeLabelTemplate": "${0} artigos por página",
+	"allItemsLabelTemplate": "Todos os artigos",
 	"gotoButtonTitle": "Avançar para uma página específica",
 	"dialogTitle": "Avançar para a página",
 	"dialogIndication": "Especificar o número de página",
 	"pageCountIndication": " (${0} páginas)",
 	"dialogConfirm": "Ir",
 	"dialogCancel": "Cancelar",
-	"all": "tudo"
+	"all": "Tudo"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/pt/EnhancedGrid.js b/dojox/grid/enhanced/nls/pt/EnhancedGrid.js
index e3863ba..ff21af9 100644
--- a/dojox/grid/enhanced/nls/pt/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/pt/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Classificação Única",
 	nestedSort: "Classificação Aninhada",
-	ascending: "Ascendente",
-	descending: "Descendente",
+	ascending: "Clique para classificar de modo Crescente",
+	descending: "Clique para classificar de modo Decrescente",
 	sortingState: "${0} - ${1}",
 	unsorted: "Não classificar esta coluna",
 	indirectSelectionRadio: "Linha ${0}, seleção única, botão de seleção",
 	indirectSelectionCheckBox: "Linha ${0}, seleção múltipla, caixa de seleção",
 	selectAll: "Selecionar todos"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/pt/Filter.js b/dojox/grid/enhanced/nls/pt/Filter.js
index 5359533..dc2fae2 100644
--- a/dojox/grid/enhanced/nls/pt/Filter.js
+++ b/dojox/grid/enhanced/nls/pt/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Limpar Filtro",
-	"filterDefDialogTitle": "Filtrar",
+	"filterDefDialogTitle": "Filtro",
 	"ruleTitleTemplate": "Regra ${0}",
-	
 	"conditionEqual": "igual",
 	"conditionNotEqual": "não é igual",
 	"conditionLess": "é menor que",
@@ -23,69 +21,55 @@ define(
 	"conditionAfter": "depois",
 	"conditionRange": "intervalo",
 	"conditionIsEmpty": "está vazio",
-	
 	"all": "todos",
-	"any": "qualquer um",
+	"any": "qualquer",
 	"relationAll": "todas as regras",
 	"waiRelAll": "Corresponder a todas as seguintes regras:",
 	"relationAny": "qualquer regra",
 	"waiRelAny": "Corresponder a qualquer uma das seguintes regras:",
-	"relationMsgFront": "Corresponder",
+	"relationMsgFront": "Corresponder:",
 	"relationMsgTail": "",
 	"and": "e",
 	"or": "ou",
-	
 	"addRuleButton": "Incluir Regra",
 	"waiAddRuleButton": "Incluir uma nova regra",
 	"removeRuleButton": "Remover Regra",
 	"waiRemoveRuleButtonTemplate": "Remover regra ${0}",
-	
 	"cancelButton": "Cancelar",
 	"waiCancelButton": "Cancelar este diálogo",
 	"clearButton": "Limpar",
 	"waiClearButton": "Limpar o filtro",
-	"filterButton": "Filtrar",
+	"filterButton": "Filtro",
 	"waiFilterButton": "Enviar o filtro",
-	
 	"columnSelectLabel": "Coluna",
 	"waiColumnSelectTemplate": "Coluna para a regra ${0}",
 	"conditionSelectLabel": "Condição",
 	"waiConditionSelectTemplate": "Condição para a regra ${0}",
 	"valueBoxLabel": "Valor",
 	"waiValueBoxTemplate": "Insira o valor para filtragem da regra ${0}",
-	
-	"rangeTo": "a",
+	"rangeTo": "para",
 	"rangeTemplate": "de ${0} a ${1}",
-	
 	"statusTipHeaderColumn": "Coluna",
 	"statusTipHeaderCondition": "Regras",
 	"statusTipTitle": "Barra de Filtragem",
 	"statusTipMsg": "Clique na barra de filtragem aqui para filtrar os valores de ${0}.",
 	"anycolumn": "qualquer coluna",
 	"statusTipTitleNoFilter": "Barra de Filtragem",
-	"statusTipTitleHasFilter": "Filtrar",
-	"statusTipRelAny": "Quaisquer Regras.",
-	"statusTipRelAll": "Todas as Regras.",
-	
+	"statusTipTitleHasFilter": "Filtro",
+	"statusTipRelAny": "Corresponder a quaisquer regras.",
+	"statusTipRelAll": "Corresponder a todas as regras.",
 	"defaultItemsName": "itens",
 	"filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} mostrados.",
 	"filterBarMsgNoFilterTemplate": "Nenhum filtro aplicado",
-	
 	"filterBarDefButton": "Definir filtro",
 	"waiFilterBarDefButton": "Filtrar a tabela",
 	"a11yFilterBarDefButton": "Filtrar...",
 	"filterBarClearButton": "Limpar filtro",
 	"waiFilterBarClearButton": "Limpar o filtro",
 	"closeFilterBarBtn": "Fechar a barra de filtragem",
-	
 	"clearFilterMsg": "Isso removerá o filtro e mostrará todos os registros disponíveis.",
 	"anyColumnOption": "Qualquer Coluna",
-	
-	"trueLabel": "Verdadeiro",
+	"trueLabel": "True",
 	"falseLabel": "Falso"
 })
-//end v1.x content
 );
-
-
-
diff --git a/dojox/grid/enhanced/nls/pt/Pagination.js b/dojox/grid/enhanced/nls/pt/Pagination.js
index 0b75f31..e8c7f2a 100644
--- a/dojox/grid/enhanced/nls/pt/Pagination.js
+++ b/dojox/grid/enhanced/nls/pt/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} de ${1} ${0}",
 	"firstTip": "Primeira Página",
@@ -17,7 +16,6 @@ define(
 	"pageCountIndication": " (${0} páginas)",
 	"dialogConfirm": "Ir",
 	"dialogCancel": "Cancelar",
-	"all": "todos"
+	"all": "Todos"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/ro/EnhancedGrid.js b/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
index 75e0c8c..b886b2c 100644
--- a/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
-	singleSort: "Sortare singulară",
+	singleSort: "Sortare singură",
 	nestedSort: "Sortare imbricată",
-	ascending: "Crescător",
-	descending: "Descrescător",
+	ascending: "Faceţi clic pentru a sorta Crescător",
+	descending: "Faceţi clic pentru a sorta Descrescător",
 	sortingState: "${0} - ${1}",
-	unsorted: "Nu se sortează această coloană",
+	unsorted: "Această coloană nu se sortează",
 	indirectSelectionRadio: "Rândul ${0}, selecţie singulară, casetă radio",
 	indirectSelectionCheckBox: "Rândul ${0}, selecţie multiplă, casetă de bifare",
 	selectAll: "Selectare tot"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/ro/Filter.js b/dojox/grid/enhanced/nls/ro/Filter.js
index d5bb491..263c304 100644
--- a/dojox/grid/enhanced/nls/ro/Filter.js
+++ b/dojox/grid/enhanced/nls/ro/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Ştergere filtru",
 	"filterDefDialogTitle": "Filtru",
 	"ruleTitleTemplate": "Regulă ${0}",
-	
 	"conditionEqual": "egal",
 	"conditionNotEqual": "nu este egal",
 	"conditionLess": "este mai mic decât",
@@ -23,40 +21,34 @@ define(
 	"conditionAfter": "după",
 	"conditionRange": "interval",
 	"conditionIsEmpty": "este gol",
-	
 	"all": "toate",
 	"any": "oricare",
 	"relationAll": "toate regulile",
-	"waiRelAll": "Răspundeţi tuturor regulilor următoare:",
-	"relationAny": "oricare reguli",
-	"waiRelAny": "Răspundeţi oricărei dintre regulile următoare:",
-	"relationMsgFront": "Răspuns",
+	"waiRelAll": "Potrivire cu toate regulile următoare:",
+	"relationAny": "orice reguli",
+	"waiRelAny": "Potrivire cu oricare dintre regulile următoare:",
+	"relationMsgFront": "Potrivire:",
 	"relationMsgTail": "",
 	"and": "şi",
 	"or": "sau",
-	
 	"addRuleButton": "Adăugare regulă",
 	"waiAddRuleButton": "Adăugare regulă nouă",
 	"removeRuleButton": "Înlăturare regulă",
 	"waiRemoveRuleButtonTemplate": "Înlăturare regulă ${0}",
-	
 	"cancelButton": "Anulare",
 	"waiCancelButton": "Anulaţi acest dialog",
 	"clearButton": "Ştergere",
 	"waiClearButton": "Ştergeţi filtrul",
 	"filterButton": "Filtru",
-	"waiFilterButton": "Lansaţi în execuţie filtrul",
-	
+	"waiFilterButton": "Lansaţi filtrul",
 	"columnSelectLabel": "Coloană",
-	"waiColumnSelectTemplate": "Coloană pentru regulă ${0}",
+	"waiColumnSelectTemplate": "Coloana pentru regula ${0}",
 	"conditionSelectLabel": "Condiţie",
-	"waiConditionSelectTemplate": "Condiţie pentru regula ${0}",
+	"waiConditionSelectTemplate": "Condiţia pentru regula ${0}",
 	"valueBoxLabel": "Valoare",
 	"waiValueBoxTemplate": "Introduceţi valoarea pentru filtrarea pentru regulă ${0}",
-	
 	"rangeTo": "la",
 	"rangeTemplate": "din ${0} la ${1}",
-	
 	"statusTipHeaderColumn": "Coloană",
 	"statusTipHeaderCondition": "Reguli",
 	"statusTipTitle": "Bară de filtru",
@@ -64,25 +56,20 @@ define(
 	"anycolumn": "orice coloană",
 	"statusTipTitleNoFilter": "Bară de filtru",
 	"statusTipTitleHasFilter": "Filtru",
-	"statusTipRelAny": "Potrivire orice regulă.",
-	"statusTipRelAll": "Potrivire toate regulile.",
-	
+	"statusTipRelAny": "Potrivire cu orice regulă.",
+	"statusTipRelAll": "Potrivire cu toate regulile.",
 	"defaultItemsName": "articole",
 	"filterBarMsgHasFilterTemplate": "${0} din ${1} ${2} afişate.",
-	"filterBarMsgNoFilterTemplate": "Niciun filtru nu este aplicat",
-	
+	"filterBarMsgNoFilterTemplate": "Nu este aplicat niciun filtru",
 	"filterBarDefButton": "Definire filtru",
 	"waiFilterBarDefButton": "Filtrare tabelă",
 	"a11yFilterBarDefButton": "Filtru...",
 	"filterBarClearButton": "Ştergere filtru",
 	"waiFilterBarClearButton": "Ştergeţi filtrul",
 	"closeFilterBarBtn": "Închidere bară de filtru",
-	
 	"clearFilterMsg": "Aceasta va înlătura filtrul şi va afişa toate înregistrările disponibile.",
 	"anyColumnOption": "Orice coloană",
-	
 	"trueLabel": "Adevărat",
 	"falseLabel": "Fals"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/ro/Pagination.js b/dojox/grid/enhanced/nls/ro/Pagination.js
index 7829a01..3b1d81c 100644
--- a/dojox/grid/enhanced/nls/ro/Pagination.js
+++ b/dojox/grid/enhanced/nls/ro/Pagination.js
@@ -1,23 +1,21 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} din ${1} ${0}",
 	"firstTip": "Prima pagină",
 	"lastTip": "Ultima pagină",
-	"nextTip": "Următoarea pagină",
-	"prevTip": "Pagina anterioarp",
+	"nextTip": "Pagina următoare",
+	"prevTip": "Pagina anterioară",
 	"itemTitle": "articole",
 	"singularItemTitle": "articol",
 	"pageStepLabelTemplate": "Pagina ${0}",
 	"pageSizeLabelTemplate": "${0} articole pe pagină",
 	"allItemsLabelTemplate": "Toate articolele",
-	"gotoButtonTitle": "Deplasare la o pagină anumită",
-	"dialogTitle": "Deplasare la pagină",
-	"dialogIndication": "Specificaţi numărul de pagină",
+	"gotoButtonTitle": "Salt la o pagină anume",
+	"dialogTitle": "Salt la pagina",
+	"dialogIndication": "Specificaţi numărul paginii",
 	"pageCountIndication": " (${0} pagini)",
-	"dialogConfirm": "Deplasare",
+	"dialogConfirm": "Salt",
 	"dialogCancel": "Anulare",
-	"all": "toate"
+	"all": "Tot"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/ru/EnhancedGrid.js b/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
index 3fb9e01..14c7d5c 100644
--- a/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
-	singleSort: "Простая сортировка",
+	singleSort: "Однократная сортировка",
 	nestedSort: "Вложенная сортировка",
-	ascending: "По возрастанию",
-	descending: "По убыванию",
+	ascending: "Сортировка по возрастанию",
+	descending: "Сортировка по убыванию",
 	sortingState: "${0} - ${1}",
 	unsorted: "Не сортировать этот столбец",
-	indirectSelectionRadio: "Строка ${0}, один выбор, радиокнопка",
-	indirectSelectionCheckBox: "Строка ${0}, несколько выборов, переключатель",
+	indirectSelectionRadio: "Строка ${0}, единственный выбор, радиокнопка",
+	indirectSelectionCheckBox: "Строка ${0}, множественный выбор, флажок",
 	selectAll: "Выбрать все"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/ru/Filter.js b/dojox/grid/enhanced/nls/ru/Filter.js
index dcbbd3a..2381c6c 100644
--- a/dojox/grid/enhanced/nls/ru/Filter.js
+++ b/dojox/grid/enhanced/nls/ru/Filter.js
@@ -1,88 +1,75 @@
 define(
-//begin v1.x content
 ({
-	"clearFilterDialogTitle": "Удалить фильтр",
+	"clearFilterDialogTitle": "Очистить фильтр",
 	"filterDefDialogTitle": "Фильтр",
 	"ruleTitleTemplate": "Правило ${0}",
-	
 	"conditionEqual": "равно",
 	"conditionNotEqual": "не равно",
-	"conditionLess": "меньше, чем",
-	"conditionLessEqual": "меньше или равно",
-	"conditionLarger": "больше, чем",
-	"conditionLargerEqual": "больше или равно",
+	"conditionLess": "меньше чем",
+	"conditionLessEqual": "не меньше чем",
+	"conditionLarger": "больше чем",
+	"conditionLargerEqual": "не больше чем",
 	"conditionContains": "содержит",
-	"conditionIs": "является",
+	"conditionIs": "-",
 	"conditionStartsWith": "начинается с",
-	"conditionEndWith": "заканчивается на",
+	"conditionEndWith": "заканчивается",
 	"conditionNotContain": "не содержит",
-	"conditionIsNot": "не является",
+	"conditionIsNot": "не соответствует",
 	"conditionNotStartWith": "не начинается с",
-	"conditionNotEndWith": "не заканчивается на",
+	"conditionNotEndWith": "не заканчивается",
 	"conditionBefore": "до",
 	"conditionAfter": "после",
 	"conditionRange": "диапазон",
-	"conditionIsEmpty": "пустое",
-	
+	"conditionIsEmpty": "пуст",
 	"all": "все",
 	"any": "любое",
 	"relationAll": "все правила",
-	"waiRelAll": "Соответствие всем следующим правилам:",
-	"relationAny": "любое правило",
-	"waiRelAny": "Соответствие любому из следующих правил:",
-	"relationMsgFront": "Соответствие",
+	"waiRelAll": "Соответствует всем следующим правилам:",
+	"relationAny": "любые правила",
+	"waiRelAny": "Соответствует любому из следующих правил:",
+	"relationMsgFront": "Соответствие:",
 	"relationMsgTail": "",
 	"and": "и",
 	"or": "или",
-	
 	"addRuleButton": "Добавить правило",
 	"waiAddRuleButton": "Добавить новое правило",
 	"removeRuleButton": "Удалить правило",
 	"waiRemoveRuleButtonTemplate": "Удалить правило ${0}",
-	
 	"cancelButton": "Отмена",
 	"waiCancelButton": "Отменить этот диалог",
-	"clearButton": "Удалить",
-	"waiClearButton": "Удалить фильтр",
+	"clearButton": "Очистить",
+	"waiClearButton": "Очистить фильтр",
 	"filterButton": "Фильтр",
-	"waiFilterButton": "Передать фильтр",
-	
+	"waiFilterButton": "Применить фильтр",
 	"columnSelectLabel": "Столбец",
-	"waiColumnSelectTemplate": "Столбец для правила ${0}",
+	"waiColumnSelectTemplate": "Столбец правила ${0}",
 	"conditionSelectLabel": "Условие",
-	"waiConditionSelectTemplate": "Условие для правила ${0}",
+	"waiConditionSelectTemplate": "Условие правила ${0}",
 	"valueBoxLabel": "Значение",
-	"waiValueBoxTemplate": "Задайте значение фильтра для правила ${0}",
-	
-	"rangeTo": "до",
+	"waiValueBoxTemplate": "Введите значение в фильтр правила ${0}",
+	"rangeTo": "к",
 	"rangeTemplate": "от ${0} до ${1}",
-	
 	"statusTipHeaderColumn": "Столбец",
 	"statusTipHeaderCondition": "Правила",
-	"statusTipTitle": "Панель фильтра",
-	"statusTipMsg": "Щелкните по панели фильтра, чтобы применить фильтр к значениям в ${0}.",
+	"statusTipTitle": "Панель фильтров",
+	"statusTipMsg": "Нажмите на панель фильтров для фильтрации по значениям в ${0}.",
 	"anycolumn": "любой столбец",
-	"statusTipTitleNoFilter": "Панель фильтра",
+	"statusTipTitleNoFilter": "Панель фильтров",
 	"statusTipTitleHasFilter": "Фильтр",
-	"statusTipRelAny": "Соответствует любому из правил.",
-	"statusTipRelAll": "Соответствует всем правилам.",
-	
+	"statusTipRelAny": "Соответствие любому из правил.",
+	"statusTipRelAll": "Соответствие всем правилам.",
 	"defaultItemsName": "элементов",
 	"filterBarMsgHasFilterTemplate": "Показано ${0} из ${1} ${2}.",
-	"filterBarMsgNoFilterTemplate": "Фильтр не применен",
-	
-	"filterBarDefButton": "Задать фильтр",
-	"waiFilterBarDefButton": "Применить фильтр к таблице",
-	"a11yFilterBarDefButton": "Фильтр...",
-	"filterBarClearButton": "Удалить фильтр",
-	"waiFilterBarClearButton": "Удалить фильтр",
-	"closeFilterBarBtn": "Закрыть панель фильтра",
-	
-	"clearFilterMsg": "Фильтр будет удален, и будут показаны все записи.",
+	"filterBarMsgNoFilterTemplate": "Фильтры не используются",
+	"filterBarDefButton": "Определить фильтр",
+	"waiFilterBarDefButton": "Фильтровать таблицу",
+	"a11yFilterBarDefButton": "Фильтровать...",
+	"filterBarClearButton": "Очистить фильтр",
+	"waiFilterBarClearButton": "Очистить фильтр",
+	"closeFilterBarBtn": "Закрыть панель фильтров",
+	"clearFilterMsg": "Эта опция удалит фильтр и будут показаны все доступные записи.",
 	"anyColumnOption": "Любой столбец",
-	
-	"trueLabel": "True",
-	"falseLabel": "False"
+	"trueLabel": "Истина",
+	"falseLabel": "Ложь"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/ru/Pagination.js b/dojox/grid/enhanced/nls/ru/Pagination.js
index 8c0655c..e41b829 100644
--- a/dojox/grid/enhanced/nls/ru/Pagination.js
+++ b/dojox/grid/enhanced/nls/ru/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} из ${1} ${0}",
 	"firstTip": "Первая страница",
@@ -11,14 +10,12 @@ define(
 	"pageStepLabelTemplate": "Страница ${0}",
 	"pageSizeLabelTemplate": "${0} элементов на странице",
 	"allItemsLabelTemplate": "Все элементы",
-	"gotoButtonTitle": "Перейти на определенную страницу",
+	"gotoButtonTitle": "Перейти на указанную страницу",
 	"dialogTitle": "Перейти на страницу",
-	"dialogIndication": "Задайте номер страницы",
+	"dialogIndication": "Укажите номер страницы",
 	"pageCountIndication": " (${0} страниц)",
 	"dialogConfirm": "Перейти",
 	"dialogCancel": "Отмена",
-	"all": "все"
+	"all": "Все"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/sk/EnhancedGrid.js b/dojox/grid/enhanced/nls/sk/EnhancedGrid.js
index ce7dd87..a6b1d16 100644
--- a/dojox/grid/enhanced/nls/sk/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/sk/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Jednoduché triedenie",
 	nestedSort: "Vnorené triedenie",
-	ascending: "Vzostupne",
-	descending: "Zostupne",
+	ascending: "Kliknite pre vzostupné triedenie",
+	descending: "Kliknite pre zostupné triedenie",
 	sortingState: "${0} - ${1}",
 	unsorted: "Netriediť tento stĺpec",
 	indirectSelectionRadio: "Riadok ${0}, jednoduchý výber, prepínač",
 	indirectSelectionCheckBox: "Riadok ${0}, viacnásobný výber, začiarkavacie políčko",
 	selectAll: "Vybrať všetko"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/sk/Filter.js b/dojox/grid/enhanced/nls/sk/Filter.js
index 47316a4..c11f236 100644
--- a/dojox/grid/enhanced/nls/sk/Filter.js
+++ b/dojox/grid/enhanced/nls/sk/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Zrušiť filter",
 	"filterDefDialogTitle": "Filter",
 	"ruleTitleTemplate": "Pravidlo ${0}",
-	
 	"conditionEqual": "rovné",
 	"conditionNotEqual": "nerovné",
 	"conditionLess": "menšie ako",
@@ -23,40 +21,34 @@ define(
 	"conditionAfter": "za",
 	"conditionRange": "rozsah",
 	"conditionIsEmpty": "je prázdne",
-	
 	"all": "všetko",
 	"any": "žiadne",
 	"relationAll": "všetky pravidlá",
 	"waiRelAll": "Vyhovovať všetkým týmto pravidlám:",
 	"relationAny": "ľubovoľné pravidlá",
 	"waiRelAny": "Vyhovovať ľubovoľným z týchto pravidiel:",
-	"relationMsgFront": "Vyhovieť",
+	"relationMsgFront": "Zhoda:",
 	"relationMsgTail": "",
 	"and": "a",
 	"or": "alebo",
-	
 	"addRuleButton": "Pridať pravidlo",
 	"waiAddRuleButton": "Pridať nové pravidlo",
 	"removeRuleButton": "Odstrániť pravidlo",
 	"waiRemoveRuleButtonTemplate": "Odstrániť pravidlo ${0}",
-	
 	"cancelButton": "Zrušiť",
 	"waiCancelButton": "Zrušiť toto dialógové okno",
 	"clearButton": "Zrušiť",
 	"waiClearButton": "Zrušiť filter",
-	"filterButton": "Filtrovať",
+	"filterButton": "Filter",
 	"waiFilterButton": "Odoslať filter",
-	
 	"columnSelectLabel": "Stĺpec",
 	"waiColumnSelectTemplate": "Stĺpec pre pravidlo ${0}",
 	"conditionSelectLabel": "Podmienka",
 	"waiConditionSelectTemplate": "Podmienka pre pravidlo ${0}",
 	"valueBoxLabel": "Hodnota",
 	"waiValueBoxTemplate": "Zadajte hodnotu na filtrovanie pre pravidlo ${0}",
-	
 	"rangeTo": "do",
 	"rangeTemplate": "od ${0} do ${1}",
-	
 	"statusTipHeaderColumn": "Stĺpec",
 	"statusTipHeaderCondition": "Pravidlá",
 	"statusTipTitle": "Lišta filtra",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "Filter",
 	"statusTipRelAny": "Zhoda s akýmikoľvek pravidlami.",
 	"statusTipRelAll": "Zhoda so všetkými pravidlami.",
-	
 	"defaultItemsName": "položky",
 	"filterBarMsgHasFilterTemplate": "Zobrazuje sa ${0} z ${1} ${2}.",
 	"filterBarMsgNoFilterTemplate": "Nepoužíva sa žiadny filter",
-	
 	"filterBarDefButton": "Definovať filter",
 	"waiFilterBarDefButton": "Filtrovať tabuľku",
 	"a11yFilterBarDefButton": "Filtrovať...",
 	"filterBarClearButton": "Zrušiť filter",
 	"waiFilterBarClearButton": "Zrušiť filter",
 	"closeFilterBarBtn": "Zatvoriť lištu filtra",
-	
 	"clearFilterMsg": "Toto odstráni filter a zobrazí všetky dostupné záznamy",
 	"anyColumnOption": "Ľubovoľný stĺpec",
-	
 	"trueLabel": "Pravda",
 	"falseLabel": "Nepravda"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/sk/Pagination.js b/dojox/grid/enhanced/nls/sk/Pagination.js
index c8e84b5..8450664 100644
--- a/dojox/grid/enhanced/nls/sk/Pagination.js
+++ b/dojox/grid/enhanced/nls/sk/Pagination.js
@@ -1,12 +1,11 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} z ${1} ${0}",
 	"firstTip": "Prvá strana",
 	"lastTip": "Posledná strana",
 	"nextTip": "Ďalšia strana",
 	"prevTip": "Predošlá strana",
-	"itemTitle": "položiek",
+	"itemTitle": "položky",
 	"singularItemTitle": "položka",
 	"pageStepLabelTemplate": "Strana ${0}",
 	"pageSizeLabelTemplate": "${0} položiek na strane",
@@ -17,7 +16,6 @@ define(
 	"pageCountIndication": " (${0} strán)",
 	"dialogConfirm": "Prejsť",
 	"dialogCancel": "Zrušiť",
-	"all": "všetko"
+	"all": "Všetko"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/sl/EnhancedGrid.js b/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
index a0ded6f..4d309ff 100644
--- a/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Enostavno razvrščanje",
 	nestedSort: "Ugnezdeno razvrščanje",
-	ascending: "Naraščajoče",
-	descending: "Padajoče",
+	ascending: "Kliknite za naraščajoče razvrščanje",
+	descending: "Kliknite za padajoče razvrščanje",
 	sortingState: "${0} - ${1}",
 	unsorted: "Ne razvrščaj tega stolpca",
-	indirectSelectionRadio: "Vrstica ${0}, izbira enega elementa, okence z izbirnim gumbom",
-	indirectSelectionCheckBox: "Vrstica ${0}, izbira več elementov, okence s potrditvenimi polji",
+	indirectSelectionRadio: "Vrstica ${0}, enojni izbor, okence z izbirnim gumbom",
+	indirectSelectionCheckBox: "Vrstica ${0}, večkratni izbor, okence s potrditvenimi polji",
 	selectAll: "Izberi vse"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/sl/Filter.js b/dojox/grid/enhanced/nls/sl/Filter.js
index cbcbffd..242b5f6 100644
--- a/dojox/grid/enhanced/nls/sl/Filter.js
+++ b/dojox/grid/enhanced/nls/sl/Filter.js
@@ -1,62 +1,54 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Počisti filter",
 	"filterDefDialogTitle": "Filter",
 	"ruleTitleTemplate": "Pravilo ${0}",
-	
 	"conditionEqual": "je enako",
 	"conditionNotEqual": "ni enako",
-	"conditionLess": "je manjše kot",
-	"conditionLessEqual": "je manjše kot ali enako",
-	"conditionLarger": "je večje kot",
-	"conditionLargerEqual": "je večje kot ali enako",
+	"conditionLess": "je manjše od",
+	"conditionLessEqual": "je manjše od ali enako",
+	"conditionLarger": "je večje od",
+	"conditionLargerEqual": "je večje od ali enako",
 	"conditionContains": "vsebuje",
 	"conditionIs": "je",
-	"conditionStartsWith": "se začne s",
-	"conditionEndWith": "se konča s",
+	"conditionStartsWith": "začne se z",
+	"conditionEndWith": "konča se z",
 	"conditionNotContain": "ne vsebuje",
 	"conditionIsNot": "ni",
-	"conditionNotStartWith": "se ne začne s",
-	"conditionNotEndWith": "se ne konča s",
+	"conditionNotStartWith": "se ne začne z",
+	"conditionNotEndWith": "se ne konča z",
 	"conditionBefore": "pred",
 	"conditionAfter": "za",
 	"conditionRange": "obseg",
 	"conditionIsEmpty": "je prazno",
-	
 	"all": "vse",
 	"any": "karkoli",
 	"relationAll": "vsa pravila",
 	"waiRelAll": "Ujema se z vsemi od naslednjih pravil:",
 	"relationAny": "katerakoli pravila",
 	"waiRelAny": "Ujema se s katerimkoli od naslednjih pravil:",
-	"relationMsgFront": "Ujemanje",
+	"relationMsgFront": "Ujemanje:",
 	"relationMsgTail": "",
 	"and": "in",
 	"or": "ali",
-	
 	"addRuleButton": "Dodaj pravilo",
 	"waiAddRuleButton": "Dodaj novo pravilo",
 	"removeRuleButton": "Odstrani pravilo",
 	"waiRemoveRuleButtonTemplate": "Odstrani pravilo ${0}",
-	
 	"cancelButton": "Prekliči",
 	"waiCancelButton": "Prekliči to pogovorno okno",
 	"clearButton": "Počisti",
 	"waiClearButton": "Počisti filter",
 	"filterButton": "Filter",
 	"waiFilterButton": "Predloži filter",
-	
 	"columnSelectLabel": "Stolpec",
 	"waiColumnSelectTemplate": "Stolpec za pravilo ${0}",
 	"conditionSelectLabel": "Pogoj",
 	"waiConditionSelectTemplate": "Pogoj za pravilo ${0}",
 	"valueBoxLabel": "Vrednost",
 	"waiValueBoxTemplate": "Vnesite vrednost za filter pravila ${0}",
-	
 	"rangeTo": "do",
 	"rangeTemplate": "od ${0} do ${1}",
-	
 	"statusTipHeaderColumn": "Stolpec",
 	"statusTipHeaderCondition": "Pravila",
 	"statusTipTitle": "Vrstica za filtriranje",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "Filter",
 	"statusTipRelAny": "Ujemanje s katerimkoli pravilom.",
 	"statusTipRelAll": "Ujemanje z vsemi pravili.",
-	
 	"defaultItemsName": "postavke",
 	"filterBarMsgHasFilterTemplate": "Prikazanih je ${0} od ${1} ${2}.",
 	"filterBarMsgNoFilterTemplate": "Uveljavljen ni noben filter.",
-	
 	"filterBarDefButton": "Definiraj filter",
 	"waiFilterBarDefButton": "Filtriraj tabelo",
 	"a11yFilterBarDefButton": "Filtriraj ...",
 	"filterBarClearButton": "Počisti filter",
 	"waiFilterBarClearButton": "Počisti filter",
 	"closeFilterBarBtn": "Zapri vrstico za filtriranje",
-	
 	"clearFilterMsg": "S tem boste odstranili filter in prikazali se bodo vsi razpoložljivi zapisi.",
 	"anyColumnOption": "Katerikoli stolpec",
-	
 	"trueLabel": "True",
 	"falseLabel": "False"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/sl/Pagination.js b/dojox/grid/enhanced/nls/sl/Pagination.js
index e563ff0..fdecb34 100644
--- a/dojox/grid/enhanced/nls/sl/Pagination.js
+++ b/dojox/grid/enhanced/nls/sl/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} od ${1} ${0}",
 	"firstTip": "Prva stran",
@@ -13,12 +12,10 @@ define(
 	"allItemsLabelTemplate": "Vse postavke",
 	"gotoButtonTitle": "Pojdi na specifično stran",
 	"dialogTitle": "Pojdi na stran",
-	"dialogIndication": "Podajte številko strani",
+	"dialogIndication": "Podaj številko strani",
 	"pageCountIndication": " (${0} strani)",
 	"dialogConfirm": "Pojdi",
 	"dialogCancel": "Prekliči",
-	"all": "vse"
+	"all": "Vse"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/sv/EnhancedGrid.js b/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
index 44c3b5f..0ffa676 100644
--- a/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Enkel sortering",
 	nestedSort: "Nästlad sortering",
-	ascending: "Stigande",
-	descending: "Fallande",
+	ascending: "Klicka för att sortera i stigande ordning",
+	descending: "Klicka för att sortera i fallande ordning",
 	sortingState: "${0} - ${1}",
 	unsorted: "Sortera inte den här kolumnen",
 	indirectSelectionRadio: "Rad ${0}, ett enda val, alternativruta",
 	indirectSelectionCheckBox: "Rad ${0}, flera val, kryssruta",
 	selectAll: "Markera alla "
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/sv/Filter.js b/dojox/grid/enhanced/nls/sv/Filter.js
index da971c0..bbd325d 100644
--- a/dojox/grid/enhanced/nls/sv/Filter.js
+++ b/dojox/grid/enhanced/nls/sv/Filter.js
@@ -1,15 +1,13 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Rensa filter",
 	"filterDefDialogTitle": "Filter",
 	"ruleTitleTemplate": "Regel ${0}",
-	
 	"conditionEqual": "lika med",
 	"conditionNotEqual": "inte lika med",
-	"conditionLess": "är mindre än",
-	"conditionLessEqual": "mindre eller lika med",
-	"conditionLarger": "är större än",
+	"conditionLess": "mindre än",
+	"conditionLessEqual": "mindre än eller lika med",
+	"conditionLarger": "större än",
 	"conditionLargerEqual": "större än eller lika med",
 	"conditionContains": "innehåller",
 	"conditionIs": "är",
@@ -23,40 +21,34 @@ define(
 	"conditionAfter": "efter",
 	"conditionRange": "intervall",
 	"conditionIsEmpty": "är tom",
-	
 	"all": "alla",
 	"any": "någon",
 	"relationAll": "alla regler",
 	"waiRelAll": "Matcha alla följande regler:",
 	"relationAny": "någon regel",
 	"waiRelAny": "Matcha någon av följande regler:",
-	"relationMsgFront": "Matcha",
+	"relationMsgFront": "Matcha:",
 	"relationMsgTail": "",
 	"and": "och",
 	"or": "eller",
-	
 	"addRuleButton": "Lägg till regel",
-	"waiAddRuleButton": "Lägg till en ny regel",
+	"waiAddRuleButton": "Lägg till ny regel",
 	"removeRuleButton": "Ta bort regel",
 	"waiRemoveRuleButtonTemplate": "Ta bort regel ${0}",
-	
 	"cancelButton": "Avbryt",
-	"waiCancelButton": "Avbryt dialogen",
+	"waiCancelButton": "Stäng dialogrutan",
 	"clearButton": "Rensa",
 	"waiClearButton": "Rensa filtret",
 	"filterButton": "Filtrera",
 	"waiFilterButton": "Filtrera",
-	
 	"columnSelectLabel": "Kolumn",
 	"waiColumnSelectTemplate": "Kolumn för regel ${0}",
 	"conditionSelectLabel": "Villkor",
 	"waiConditionSelectTemplate": "Villkor för regel ${0}",
 	"valueBoxLabel": "Värde",
 	"waiValueBoxTemplate": "Ange värde för filtrering efter regeln ${0}",
-	
 	"rangeTo": "till",
 	"rangeTemplate": "från ${0} till ${1}",
-	
 	"statusTipHeaderColumn": "Kolumn",
 	"statusTipHeaderCondition": "Regler",
 	"statusTipTitle": "Filterfält",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "Filter",
 	"statusTipRelAny": "Matcha någon regel.",
 	"statusTipRelAll": "Matcha alla regler.",
-	
 	"defaultItemsName": "objekt",
 	"filterBarMsgHasFilterTemplate": "${0} av ${1} ${2} visas.",
 	"filterBarMsgNoFilterTemplate": "Inget filter tillämpat",
-	
 	"filterBarDefButton": "Definiera filter",
 	"waiFilterBarDefButton": "Filtrera tabellen",
 	"a11yFilterBarDefButton": "Filter...",
 	"filterBarClearButton": "Rensa filter",
 	"waiFilterBarClearButton": "Rensa filtret",
 	"closeFilterBarBtn": "Stäng filterfält",
-	
 	"clearFilterMsg": "Tar bort filtret och visar alla tillgängliga poster.",
-	"anyColumnOption": "Alla kolumner",
-	
+	"anyColumnOption": "Någon kolumn",
 	"trueLabel": "Sant",
 	"falseLabel": "Falskt"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/sv/Pagination.js b/dojox/grid/enhanced/nls/sv/Pagination.js
index 628201c..fe06697 100644
--- a/dojox/grid/enhanced/nls/sv/Pagination.js
+++ b/dojox/grid/enhanced/nls/sv/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} av ${1} ${0}",
 	"firstTip": "Första sidan",
@@ -17,7 +16,6 @@ define(
 	"pageCountIndication": " (${0} sidor)",
 	"dialogConfirm": "Gå",
 	"dialogCancel": "Avbryt",
-	"all": "alla"
+	"all": "Alla"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/th/EnhancedGrid.js b/dojox/grid/enhanced/nls/th/EnhancedGrid.js
index 983d781..9305278 100644
--- a/dojox/grid/enhanced/nls/th/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/th/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "เรียงลำดับแบบเดี่ยว",
 	nestedSort: "เรียงลำดับที่ซับซ้อน",
-	ascending: "จากน้อยไปหามาก",
-	descending: "จากมากไปหาน้อย",
+	ascending: "คลิกเพื่อเรียงจากมากไปน้อย",
+	descending: "คลิกเพื่อเรียงจากน้อยไปมาก",
 	sortingState: "${0} - ${1}",
 	unsorted: "ห้ามเรียงลำดับคอลัมน์นี้",
 	indirectSelectionRadio: "แถว ${0}, การเลือกเดียว, กล่องวิทยุ",
 	indirectSelectionCheckBox: "แถว ${0}, การเลือกจำนวนมาก, เช็กบ็อกซ์",
 	selectAll: "เลือกทั้งหมด"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/th/Filter.js b/dojox/grid/enhanced/nls/th/Filter.js
index b6e69e0..935fc71 100644
--- a/dojox/grid/enhanced/nls/th/Filter.js
+++ b/dojox/grid/enhanced/nls/th/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "ลบตัวกรอง",
 	"filterDefDialogTitle": "ตัวกรอง",
 	"ruleTitleTemplate": "กฏ ${0}",
-	
 	"conditionEqual": "เท่ากับ",
 	"conditionNotEqual": "ไม่เท่ากับ",
 	"conditionLess": "น้อยกว่า",
@@ -23,40 +21,34 @@ define(
 	"conditionAfter": "หลัง",
 	"conditionRange": "ช่วง",
 	"conditionIsEmpty": "ว่างอยู่",
-	
 	"all": "ทั้งหมด",
 	"any": "ใด",
 	"relationAll": "กฏทั้งหมด",
 	"waiRelAll": "ตรงกับกฏทั้งหมดต่อไปนี้:",
 	"relationAny": "กฏใดๆ",
 	"waiRelAny": "ตรงกับกฏใดๆต่อไปนี้:",
-	"relationMsgFront": "ตรงกับ",
+	"relationMsgFront": "ตรงกัน:",
 	"relationMsgTail": "",
 	"and": "และ",
 	"or": "หรือ",
-	
 	"addRuleButton": "เพิ่มกฏ",
 	"waiAddRuleButton": "เพิ่มกฏใหม่",
 	"removeRuleButton": "ลบกฏ",
 	"waiRemoveRuleButtonTemplate": "ลบกฏ ${0}",
-	
 	"cancelButton": "ยกเลิก",
 	"waiCancelButton": "ยกเลิกไดอะล็อกนี้",
 	"clearButton": "ลบ",
 	"waiClearButton": "ลบตัวกรอง",
 	"filterButton": "ตัวกรอง",
 	"waiFilterButton": "ส่งตัวกรอง",
-	
 	"columnSelectLabel": "คอลัมน์",
 	"waiColumnSelectTemplate": "คอลัมน์สำหรับกฏ ${0}",
 	"conditionSelectLabel": "เงื่อนไข",
 	"waiConditionSelectTemplate": "เงื่อนไขสำหรับกฏ ${0}",
 	"valueBoxLabel": "ค่า",
 	"waiValueBoxTemplate": "ป้อนค่าให้กับตัวกรองสำหรับกฏ ${0}",
-	
 	"rangeTo": "ถึง",
 	"rangeTemplate": "จาก ${0} ถึง ${1}",
-	
 	"statusTipHeaderColumn": "คอลัมน์",
 	"statusTipHeaderCondition": "กฏ",
 	"statusTipTitle": "แถบตัวกรอง",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "ตัวกรอง",
 	"statusTipRelAny": "ตรงกับกฏใดๆ",
 	"statusTipRelAll": "ตรงกับทุกกฏ",
-	
 	"defaultItemsName": "ไอเท็ม",
 	"filterBarMsgHasFilterTemplate": "${0} ของ ${1} ${2} จะถูกแสดง",
 	"filterBarMsgNoFilterTemplate": "ไม่นำตัวกรองไปใช้",
-	
 	"filterBarDefButton": "กำหนดตัวกรอง",
 	"waiFilterBarDefButton": "กรองตาราง",
 	"a11yFilterBarDefButton": "ตัวกรอง...",
 	"filterBarClearButton": "ลบตัวกรอง",
 	"waiFilterBarClearButton": "ลบตัวกรอง",
 	"closeFilterBarBtn": "ปิดแถบตัวกรอง",
-	
 	"clearFilterMsg": "ซึ่งจะลบตัวกรองออกและแสดงเร็กคอร์ดที่พร้อมใช้งานทั้งหมด",
 	"anyColumnOption": "คอลัมน์ใดๆ",
-	
 	"trueLabel": "จริง",
 	"falseLabel": "เท็จ"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/th/Pagination.js b/dojox/grid/enhanced/nls/th/Pagination.js
index 24f54ff..9a60340 100644
--- a/dojox/grid/enhanced/nls/th/Pagination.js
+++ b/dojox/grid/enhanced/nls/th/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} จาก ${1} ${0}",
 	"firstTip": "หน้าแรก",
@@ -10,7 +9,7 @@ define(
 	"singularItemTitle": "ไอเท็ม",
 	"pageStepLabelTemplate": "หน้า ${0}",
 	"pageSizeLabelTemplate": "${0} ไอเท็มต่อหน้า",
-	"allItemsLabelTemplate": "รายการ ทั้งหมด",
+	"allItemsLabelTemplate": "ไอเท็มทั้งหมด",
 	"gotoButtonTitle": "ไปที่หน้าที่ระบุ",
 	"dialogTitle": "ไปที่หน้า",
 	"dialogIndication": "ระบุหมายเลขหน้า",
@@ -19,5 +18,4 @@ define(
 	"dialogCancel": "ยกเลิก",
 	"all": "ทั้งหมด"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/tr/EnhancedGrid.js b/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
index cc98a9f..d93d762 100644
--- a/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "Tekli Sıralama",
 	nestedSort: "İç İçe Sıralama",
-	ascending: "Artan Düzende",
-	descending: "Azalan Düzende",
+	ascending: "Artan Sırada sıralamak için tıklatın",
+	descending: "Azalan Sırada sıralamak için tıklatın",
 	sortingState: "${0} - ${1}",
 	unsorted: "Bu sütunu sıralama",
 	indirectSelectionRadio: "Satır ${0}, tek seçimli, radyo düğmesi",
 	indirectSelectionCheckBox: "Satır ${0}, çok seçimli, radyo düğmesi",
 	selectAll: "Tümünü seç"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/tr/Filter.js b/dojox/grid/enhanced/nls/tr/Filter.js
index 3a1050d..db285da 100644
--- a/dojox/grid/enhanced/nls/tr/Filter.js
+++ b/dojox/grid/enhanced/nls/tr/Filter.js
@@ -1,10 +1,8 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "Süzgeci Kaldır",
 	"filterDefDialogTitle": "Süzgeç",
 	"ruleTitleTemplate": "Kural ${0}",
-	
 	"conditionEqual": "eşittir",
 	"conditionNotEqual": "eşit değildir",
 	"conditionLess": "küçüktür",
@@ -23,40 +21,34 @@ define(
 	"conditionAfter": "sonra",
 	"conditionRange": "aralık",
 	"conditionIsEmpty": "boş",
-	
 	"all": "tümü",
 	"any": "herhangi biri",
 	"relationAll": "tüm kurallar",
 	"waiRelAll": "Aşağıdaki tüm kurallarla eşleştir",
 	"relationAny": "kuralların herhangi biri",
-	"waiRelAny": "Aşağıdaki kuralların herhangi biri ile eşleştir",
-	"relationMsgFront": "Eşleştir",
+	"waiRelAny": "Aşağıdaki kurallardan herhangi biriyle eşleştir:",
+	"relationMsgFront": "Eşleştir:",
 	"relationMsgTail": "",
 	"and": "ve",
 	"or": "veya",
-	
 	"addRuleButton": "Kural Ekle",
-	"waiAddRuleButton": "Yeni bir kural ekle",
+	"waiAddRuleButton": "Yeni kural ekle",
 	"removeRuleButton": "Kuralı Kaldır",
 	"waiRemoveRuleButtonTemplate": "${0} kuralını kaldır",
-	
 	"cancelButton": "İptal",
 	"waiCancelButton": "Bu iletişim kutusunu iptal et",
 	"clearButton": "Kaldır",
 	"waiClearButton": "Süzgeci kaldır",
 	"filterButton": "Süzgeç",
 	"waiFilterButton": "Süzgeci gönder",
-	
 	"columnSelectLabel": "Sütun",
 	"waiColumnSelectTemplate": "${0} kuralı için sütun",
 	"conditionSelectLabel": "Koşul",
 	"waiConditionSelectTemplate": "${0} kuralı için koşul",
 	"valueBoxLabel": "Değer",
 	"waiValueBoxTemplate": "${0} kuralı için süzülecek değeri girin",
-	
 	"rangeTo": "bitiş",
 	"rangeTemplate": "${0} - ${1}",
-	
 	"statusTipHeaderColumn": "Sütun",
 	"statusTipHeaderCondition": "Kurallar",
 	"statusTipTitle": "Süzgeç Çubuğu",
@@ -66,23 +58,18 @@ define(
 	"statusTipTitleHasFilter": "Süzgeç",
 	"statusTipRelAny": "Herhangi bir kuralı eşleştir.",
 	"statusTipRelAll": "Bütün kuralları eşleştir.",
-	
 	"defaultItemsName": "öğe",
 	"filterBarMsgHasFilterTemplate": "${0} / ${1} ${2} gösteriliyor.",
 	"filterBarMsgNoFilterTemplate": "Süzgeç uygulanmadı",
-	
 	"filterBarDefButton": "Süzgeç tanımla",
 	"waiFilterBarDefButton": "Tabloyu süz",
 	"a11yFilterBarDefButton": "Süz...",
 	"filterBarClearButton": "Süzgeci kaldır",
 	"waiFilterBarClearButton": "Süzgeci kaldır",
 	"closeFilterBarBtn": "Süzgeç çubuğunu kapat",
-	
-	"clearFilterMsg": "Bu seçenek süzgeci kaldırır ve tüm kullanılabilir kayıtları gösterir.",
+	"clearFilterMsg": "Bu işlem süzgeci kaldırır ve tüm kullanılabilir kayıtları gösterir.",
 	"anyColumnOption": "Herhangi Bir Sütun",
-	
 	"trueLabel": "Doğru",
 	"falseLabel": "Yanlış"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/tr/Pagination.js b/dojox/grid/enhanced/nls/tr/Pagination.js
index 1aa949f..16cf5c1 100644
--- a/dojox/grid/enhanced/nls/tr/Pagination.js
+++ b/dojox/grid/enhanced/nls/tr/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} / ${1} ${0}",
 	"firstTip": "İlk Sayfa",
@@ -17,7 +16,6 @@ define(
 	"pageCountIndication": " (${0} sayfa)",
 	"dialogConfirm": "Git",
 	"dialogCancel": "İptal",
-	"all": "tümü"
+	"all": "Tümü"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/uk/EnhancedGrid.js b/dojox/grid/enhanced/nls/uk/EnhancedGrid.js
new file mode 100644
index 0000000..2fe251e
--- /dev/null
+++ b/dojox/grid/enhanced/nls/uk/EnhancedGrid.js
@@ -0,0 +1,13 @@
+define(
+({
+	singleSort: "Однорівневе сортування",
+	nestedSort: "Вкладене сортування",
+	ascending: "Клацніть для сортування за зростанням",
+	descending: "Клацніть для сортування за спаданням",
+	sortingState: "${0} - ${1}",
+	unsorted: "Не сортувати цей стовпець",
+	indirectSelectionRadio: "Рядок ${0}, однорівневе сортування, перемикач",
+	indirectSelectionCheckBox: "Рядок ${0}, багаторівневе сортування, перемикач",
+	selectAll: "Виділити все"
+})
+);
diff --git a/dojox/grid/enhanced/nls/uk/Filter.js b/dojox/grid/enhanced/nls/uk/Filter.js
new file mode 100644
index 0000000..600ffea
--- /dev/null
+++ b/dojox/grid/enhanced/nls/uk/Filter.js
@@ -0,0 +1,75 @@
+define(
+({
+	"clearFilterDialogTitle": "Очистити фільтр",
+	"filterDefDialogTitle": "Фільтр",
+	"ruleTitleTemplate": "Правило ${0}",
+	"conditionEqual": "дорівнює",
+	"conditionNotEqual": "не дорівнює",
+	"conditionLess": "менше за",
+	"conditionLessEqual": "менше або дорівнює",
+	"conditionLarger": "більше за",
+	"conditionLargerEqual": "більше або дорівнює",
+	"conditionContains": "містить",
+	"conditionIs": "дорівнює",
+	"conditionStartsWith": "починається з",
+	"conditionEndWith": "закінчується на",
+	"conditionNotContain": "не містить",
+	"conditionIsNot": "не дорівнює",
+	"conditionNotStartWith": "не починається з",
+	"conditionNotEndWith": "не закінчується на",
+	"conditionBefore": "до",
+	"conditionAfter": "після",
+	"conditionRange": "діапазон",
+	"conditionIsEmpty": "порожній",
+	"all": "всі",
+	"any": "будь-яке",
+	"relationAll": "всі правила",
+	"waiRelAll": "Відповідає всім наступним правилам:",
+	"relationAny": "будь-які правила",
+	"waiRelAny": "Відповідає будь-якому з наступних правил:",
+	"relationMsgFront": "Відповідає:",
+	"relationMsgTail": "",
+	"and": "та",
+	"or": "або",
+	"addRuleButton": "Додати правило",
+	"waiAddRuleButton": "Додати нове правило",
+	"removeRuleButton": "Видалити правило",
+	"waiRemoveRuleButtonTemplate": "Видалити правило ${0}",
+	"cancelButton": "Скасувати",
+	"waiCancelButton": "Скасувати це вікно",
+	"clearButton": "Очистити",
+	"waiClearButton": "Очистити фільтр",
+	"filterButton": "Фільтр",
+	"waiFilterButton": "Застосувати фільтр",
+	"columnSelectLabel": "Стовпчик",
+	"waiColumnSelectTemplate": "Стовпчик для правила ${0}",
+	"conditionSelectLabel": "Умова",
+	"waiConditionSelectTemplate": "Умова правила ${0}",
+	"valueBoxLabel": "Значення",
+	"waiValueBoxTemplate": "Введіть значення до фільтру правила ${0}",
+	"rangeTo": "до",
+	"rangeTemplate": "з ${0} до ${1}",
+	"statusTipHeaderColumn": "Стовпчик",
+	"statusTipHeaderCondition": "Правила",
+	"statusTipTitle": "Панель фільтрів",
+	"statusTipMsg": "Клацніть на панелі фільтрів для фільтрації за значеннями в ${0}.",
+	"anycolumn": "будь-який стовпець",
+	"statusTipTitleNoFilter": "Панель фільтрів",
+	"statusTipTitleHasFilter": "Фільтр",
+	"statusTipRelAny": "Відповідає будь-якому з правил.",
+	"statusTipRelAll": "Відповідає всім правилам.",
+	"defaultItemsName": "елементи",
+	"filterBarMsgHasFilterTemplate": "Показано ${0} з ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "Фільтри не використовуються",
+	"filterBarDefButton": "Визначити фільтр",
+	"waiFilterBarDefButton": "Фільтрувати таблицю",
+	"a11yFilterBarDefButton": "Фільтр...",
+	"filterBarClearButton": "Очистити фільтр",
+	"waiFilterBarClearButton": "Очистити фільтр",
+	"closeFilterBarBtn": "Закрити панель фільтрів",
+	"clearFilterMsg": "Ця опція видаляє фільтр та показує всі доступні записи.",
+	"anyColumnOption": "Будь-який стовпець",
+	"trueLabel": "Істина",
+	"falseLabel": "Неправда"
+})
+);
diff --git a/dojox/grid/enhanced/nls/uk/Pagination.js b/dojox/grid/enhanced/nls/uk/Pagination.js
new file mode 100644
index 0000000..17a81ff
--- /dev/null
+++ b/dojox/grid/enhanced/nls/uk/Pagination.js
@@ -0,0 +1,21 @@
+define(
+({
+	"descTemplate": "${2} - ${3} з ${1} ${0}",
+	"firstTip": "Перша сторінка",
+	"lastTip": "Остання сторінка",
+	"nextTip": "Наступна сторінка",
+	"prevTip": "Попередня сторінка",
+	"itemTitle": "елементи",
+	"singularItemTitle": "елемент",
+	"pageStepLabelTemplate": "Сторінка ${0}",
+	"pageSizeLabelTemplate": "${0} елементів на сторінці",
+	"allItemsLabelTemplate": "Усі елементи",
+	"gotoButtonTitle": "Перейти до вказаної сторінки",
+	"dialogTitle": "Перейти до сторінки",
+	"dialogIndication": "Вкажіть номер сторінки",
+	"pageCountIndication": " (${0} сторінок)",
+	"dialogConfirm": "Перейти",
+	"dialogCancel": "Скасувати",
+	"all": "Всі"
+})
+);
diff --git a/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js b/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
index 0233afd..2cea188 100644
--- a/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
 	singleSort: "單一排序",
 	nestedSort: "巢狀排序",
-	ascending: "遞增",
-	descending: "降冪",
+	ascending: "按一下以遞增排序",
+	descending: "按一下以遞減排序",
 	sortingState: "${0} - ${1}",
-	unsorted: "請勿對此欄執行排序",
+	unsorted: "本欄不進行排序",
 	indirectSelectionRadio: "第 ${0} 行,單一選項,圓鈕框",
 	indirectSelectionCheckBox: "第 ${0} 行,多重選項,勾選框",
 	selectAll: "全選"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/zh-tw/Filter.js b/dojox/grid/enhanced/nls/zh-tw/Filter.js
index 785459e..5926028 100644
--- a/dojox/grid/enhanced/nls/zh-tw/Filter.js
+++ b/dojox/grid/enhanced/nls/zh-tw/Filter.js
@@ -1,88 +1,75 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "清除過濾器",
 	"filterDefDialogTitle": "過濾器",
 	"ruleTitleTemplate": "規則 ${0}",
-	
 	"conditionEqual": "等於",
 	"conditionNotEqual": "不等於",
-	"conditionLess": "是小於",
+	"conditionLess": "為小於",
 	"conditionLessEqual": "小於或等於",
-	"conditionLarger": "是大於",
+	"conditionLarger": "為大於",
 	"conditionLargerEqual": "大於或等於",
-	"conditionContains": "內容",
-	"conditionIs": "是",
+	"conditionContains": "包含",
+	"conditionIs": "為",
 	"conditionStartsWith": "開始於",
 	"conditionEndWith": "結束於",
 	"conditionNotContain": "不包含",
-	"conditionIsNot": "不是",
-	"conditionNotStartWith": "不開始於",
+	"conditionIsNot": "為不是",
+	"conditionNotStartWith": "不起始於",
 	"conditionNotEndWith": "不結束於",
 	"conditionBefore": "之前",
 	"conditionAfter": "之後",
 	"conditionRange": "範圍",
 	"conditionIsEmpty": "為空",
-	
 	"all": "全部",
 	"any": "任何",
 	"relationAll": "所有規則",
-	"waiRelAll": "符合下列所有規則:",
+	"waiRelAll": "符合下列的所有規則:",
 	"relationAny": "任何規則",
-	"waiRelAny": "符合下列任何規則:",
-	"relationMsgFront": "符合",
+	"waiRelAny": "符合下列的任何規則:",
+	"relationMsgFront": "符合:",
 	"relationMsgTail": "",
-	"and": "和",
+	"and": "及",
 	"or": "或",
-	
 	"addRuleButton": "新增規則",
 	"waiAddRuleButton": "新增規則",
 	"removeRuleButton": "移除規則",
 	"waiRemoveRuleButtonTemplate": "移除規則 ${0}",
-	
 	"cancelButton": "取消",
-	"waiCancelButton": "取消此對話",
+	"waiCancelButton": "取消此對話框",
 	"clearButton": "清除",
 	"waiClearButton": "清除過濾器",
 	"filterButton": "過濾器",
 	"waiFilterButton": "提交過濾器",
-	
 	"columnSelectLabel": "直欄",
 	"waiColumnSelectTemplate": "規則 ${0} 的直欄",
 	"conditionSelectLabel": "條件",
 	"waiConditionSelectTemplate": "規則 ${0} 的條件",
 	"valueBoxLabel": "值",
-	"waiValueBoxTemplate": "輸入要針對規則 ${0} 過濾的值",
-	
-	"rangeTo": "至",
-	"rangeTemplate": "從 ${0} 至 ${1}",
-	
+	"waiValueBoxTemplate": "輸入要過濾規則 ${0} 的值",
+	"rangeTo": "到",
+	"rangeTemplate": "從 ${0} 到 ${1}",
 	"statusTipHeaderColumn": "直欄",
 	"statusTipHeaderCondition": "規則",
 	"statusTipTitle": "過濾器列",
-	"statusTipMsg": "按一下這裡的過濾器列以過濾 ${0} 中的值。",
+	"statusTipMsg": "按一下過濾器列以過濾 ${0} 中的值。",
 	"anycolumn": "任何直欄",
 	"statusTipTitleNoFilter": "過濾器列",
 	"statusTipTitleHasFilter": "過濾器",
 	"statusTipRelAny": "符合任何規則。",
 	"statusTipRelAll": "符合所有規則。",
-	
 	"defaultItemsName": "項目",
 	"filterBarMsgHasFilterTemplate": "顯示 ${1} ${2} 之 ${0}。",
-	"filterBarMsgNoFilterTemplate": "未套用過濾器",
-	
+	"filterBarMsgNoFilterTemplate": "未套用任何過濾器",
 	"filterBarDefButton": "定義過濾器",
 	"waiFilterBarDefButton": "過濾表格",
-	"a11yFilterBarDefButton": "過濾器...",
+	"a11yFilterBarDefButton": "過濾...",
 	"filterBarClearButton": "清除過濾器",
 	"waiFilterBarClearButton": "清除過濾器",
 	"closeFilterBarBtn": "關閉過濾器列",
-	
-	"clearFilterMsg": "這將會移除過濾器並顯示所有的可用記錄。",
+	"clearFilterMsg": "這將會移除過濾器並顯示所有可用的記錄。",
 	"anyColumnOption": "任何直欄",
-	
 	"trueLabel": "True",
 	"falseLabel": "False"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/zh-tw/Pagination.js b/dojox/grid/enhanced/nls/zh-tw/Pagination.js
index 0d344d1..6b7adf5 100644
--- a/dojox/grid/enhanced/nls/zh-tw/Pagination.js
+++ b/dojox/grid/enhanced/nls/zh-tw/Pagination.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"descTemplate": "${2} - ${3} / ${1} ${0}",
 	"firstTip": "首頁",
@@ -8,17 +7,15 @@ define(
 	"prevTip": "上一頁",
 	"itemTitle": "項目",
 	"singularItemTitle": "項目",
-	"pageStepLabelTemplate": "第 ${0} 頁",
+	"pageStepLabelTemplate": "頁面 ${0}",
 	"pageSizeLabelTemplate": "每頁 ${0} 個項目",
 	"allItemsLabelTemplate": "所有項目",
-	"gotoButtonTitle": "跳至特定頁面",
+	"gotoButtonTitle": "跳至特定的頁面",
 	"dialogTitle": "跳至頁面",
 	"dialogIndication": "指定頁碼",
-	"pageCountIndication": "(${0} 頁)",
+	"pageCountIndication": " (${0} 個頁面)",
 	"dialogConfirm": "執行",
 	"dialogCancel": "取消",
 	"all": "全部"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/zh/EnhancedGrid.js b/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
index 036aa00..41387db 100644
--- a/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
@@ -1,16 +1,13 @@
 define(
-//begin v1.x content
 ({
-	singleSort: "单层排序",
+	singleSort: "单一排序",
 	nestedSort: "嵌套排序",
-	ascending: "升序",
-	descending: "降序",
+	ascending: "单击以按升序排序",
+	descending: "单击以按降序排序",
 	sortingState: "${0} - ${1}",
-	unsorted: "请勿对此列进行排序",
+	unsorted: "不要对此列排序",
 	indirectSelectionRadio: "第 ${0} 行,单选,单选框",
 	indirectSelectionCheckBox: "第 ${0} 行,多选,复选框",
-	selectAll: "全部选中"
+	selectAll: "全选"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/nls/zh/Filter.js b/dojox/grid/enhanced/nls/zh/Filter.js
index e7a1e19..e57c8f3 100644
--- a/dojox/grid/enhanced/nls/zh/Filter.js
+++ b/dojox/grid/enhanced/nls/zh/Filter.js
@@ -1,88 +1,75 @@
 define(
-//begin v1.x content
 ({
 	"clearFilterDialogTitle": "清除过滤器",
-	"filterDefDialogTitle": "过滤器",
+	"filterDefDialogTitle": "过滤",
 	"ruleTitleTemplate": "规则 ${0}",
-	
 	"conditionEqual": "等于",
 	"conditionNotEqual": "不等于",
 	"conditionLess": "小于",
-	"conditionLessEqual": "小于或等于",
+	"conditionLessEqual": "小于等于",
 	"conditionLarger": "大于",
-	"conditionLargerEqual": "大于或等于",
+	"conditionLargerEqual": "大于等于",
 	"conditionContains": "包含",
 	"conditionIs": "是",
 	"conditionStartsWith": "开始于",
 	"conditionEndWith": "结束于",
 	"conditionNotContain": "不包含",
-	"conditionIsNot": "非",
+	"conditionIsNot": "不是",
 	"conditionNotStartWith": "不是开始于",
 	"conditionNotEndWith": "不是结束于",
-	"conditionBefore": "先于",
-	"conditionAfter": "后于",
+	"conditionBefore": "之前",
+	"conditionAfter": "之后",
 	"conditionRange": "范围",
 	"conditionIsEmpty": "为空",
-	
 	"all": "全部",
-	"any": "任何",
+	"any": "任意",
 	"relationAll": "所有规则",
-	"waiRelAll": "符合以下所有规则:",
-	"relationAny": "任何规则",
-	"waiRelAny": "符合以下任何规则:",
-	"relationMsgFront": "符合",
+	"waiRelAll": "与以下所有规则匹配:",
+	"relationAny": "任意规则",
+	"waiRelAny": "符合以下任意规则:",
+	"relationMsgFront": "匹配:",
 	"relationMsgTail": "",
 	"and": "和",
-	"or": "或",
-	
+	"or": "或 ",
 	"addRuleButton": "添加规则",
-	"waiAddRuleButton": "添加新规则",
+	"waiAddRuleButton": "新增规则",
 	"removeRuleButton": "除去规则",
 	"waiRemoveRuleButtonTemplate": "除去规则 ${0}",
-	
 	"cancelButton": "取消",
-	"waiCancelButton": "取消该对话",
+	"waiCancelButton": "取消此对话框",
 	"clearButton": "清除",
 	"waiClearButton": "清除过滤器",
-	"filterButton": "过滤器",
+	"filterButton": "过滤",
 	"waiFilterButton": "提交过滤器",
-	
 	"columnSelectLabel": "列",
-	"waiColumnSelectTemplate": "规则 ${0} 的列",
+	"waiColumnSelectTemplate": "${0} 规则列",
 	"conditionSelectLabel": "条件",
-	"waiConditionSelectTemplate": "规则 ${0} 的条件",
+	"waiConditionSelectTemplate": "${0} 规则条件",
 	"valueBoxLabel": "值",
-	"waiValueBoxTemplate": "将规则 ${0} 的值输入过滤器",
-	
-	"rangeTo": "到",
+	"waiValueBoxTemplate": "为规则 ${0} 的过滤器输入值",
+	"rangeTo": "至",
 	"rangeTemplate": "从 ${0} 到 ${1}",
-	
 	"statusTipHeaderColumn": "列",
 	"statusTipHeaderCondition": "规则",
 	"statusTipTitle": "过滤器栏",
-	"statusTipMsg": "单击此处的过滤器栏以过滤 ${0} 中的值。",
-	"anycolumn": "任何列",
+	"statusTipMsg": "在此处单击过滤器栏以根据 ${0} 中的值进行过滤。",
+	"anycolumn": "任意列",
 	"statusTipTitleNoFilter": "过滤器栏",
-	"statusTipTitleHasFilter": "过滤器",
+	"statusTipTitleHasFilter": "过滤",
 	"statusTipRelAny": "与任何规则匹配。",
 	"statusTipRelAll": "与所有规则匹配。",
-	
-	"defaultItemsName": "项目",
-	"filterBarMsgHasFilterTemplate": "显示的 ${1} ${2} 的 ${0}。",
-	"filterBarMsgNoFilterTemplate": "未使用过滤器",
-	
+	"defaultItemsName": "项目数",
+	"filterBarMsgHasFilterTemplate": "显示 ${0} 个 ${2}(共 ${1} 个)",
+	"filterBarMsgNoFilterTemplate": "未应用过滤器",
 	"filterBarDefButton": "定义过滤器",
-	"waiFilterBarDefButton": "过滤表",
-	"a11yFilterBarDefButton": "过滤器...",
+	"waiFilterBarDefButton": "过滤表格",
+	"a11yFilterBarDefButton": "过滤...",
 	"filterBarClearButton": "清除过滤器",
 	"waiFilterBarClearButton": "清除过滤器",
 	"closeFilterBarBtn": "关闭过滤器栏",
-	
-	"clearFilterMsg": "该操作将除去过滤器并显示所有现有记录。",
+	"clearFilterMsg": "此操作将除去过滤器并显示所有可用记录。",
 	"anyColumnOption": "任何列",
-	
 	"trueLabel": "True",
 	"falseLabel": "False"
 })
-//end v1.x content
 );
diff --git a/dojox/grid/enhanced/nls/zh/Pagination.js b/dojox/grid/enhanced/nls/zh/Pagination.js
index c1b5452..f92df23 100644
--- a/dojox/grid/enhanced/nls/zh/Pagination.js
+++ b/dojox/grid/enhanced/nls/zh/Pagination.js
@@ -1,24 +1,21 @@
 define(
-//begin v1.x content
 ({
-	"descTemplate": "${1} 个${0}中的  ${2} - ${3}",
-	"firstTip": "第一页",
-	"lastTip": "最后一页",
+	"descTemplate": "第 ${2} - ${3} 个(共 ${1} ${0})",
+	"firstTip": "首页",
+	"lastTip": "末页",
 	"nextTip": "下一页",
 	"prevTip": "上一页",
-	"itemTitle": "项目",
+	"itemTitle": "项目数",
 	"singularItemTitle": "项",
 	"pageStepLabelTemplate": "第 ${0} 页",
-	"pageSizeLabelTemplate": "每页的 ${0} 项目",
-	"allItemsLabelTemplate": "所有项目",
-	"gotoButtonTitle": "转到指定页面",
-	"dialogTitle": "转到页面",
+	"pageSizeLabelTemplate": "每页的 ${0} 项",
+	"allItemsLabelTemplate": "所有项",
+	"gotoButtonTitle": "转至特定页",
+	"dialogTitle": "转至页",
 	"dialogIndication": "指定页数",
-	"pageCountIndication": "(${0} 页)",
-	"dialogConfirm": "确定",
+	"pageCountIndication": "(共 ${0} 页)",
+	"dialogConfirm": "运行",
 	"dialogCancel": "取消",
 	"all": "全部"
 })
-//end v1.x content
 );
-
diff --git a/dojox/grid/enhanced/plugins/CellMerge.js b/dojox/grid/enhanced/plugins/CellMerge.js
index fd359fc..22c1dfd 100644
--- a/dojox/grid/enhanced/plugins/CellMerge.js
+++ b/dojox/grid/enhanced/plugins/CellMerge.js
@@ -10,22 +10,23 @@ define([
 var CellMerge = declare("dojox.grid.enhanced.plugins.CellMerge", _Plugin, {
 	// summary:
 	//		This plugin provides functions to merge(un-merge) adjacent cells within one row.
-	//		Acceptable plugin paramters:
-	//		1. mergedCells: Array
-	//			An array of objects with structure:
-	//			{
-	//				row: function(Integer)|Integer
-	//					If it's a function, it's a predicate to decide which rows are to be merged.
-	//					It takes an integer (the row index), and should return true or false;
-	//				start: Integer
-	//					The column index of the left most cell that shall be merged.
-	//				end: Integer
-	//					The column index of the right most cell that shall be merged.
-	//				major: Integer
-	//					The column index of the cell whose content should be used as the content of the merged cell.
-	//					It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
-	//					If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
-	//			}
+	//		Acceptable plugin parameters:
+	//
+	//		- mergedCells: Array: An array of objects with structure:
+	//
+	// |		{
+	// |			row: function(Integer)|Integer
+	// |				If it's a function, it's a predicate to decide which rows are to be merged.
+	// |				It takes an integer (the row index), and should return true or false;
+	// |			start: Integer
+	// |				The column index of the left most cell that shall be merged.
+	// |			end: Integer
+	// |				The column index of the right most cell that shall be merged.
+	// |			major: Integer
+	// |				The column index of the cell whose content should be used as the content of the merged cell.
+	// |				It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
+	// |				If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
+	// |		}
 	
 	// name: String
 	//		Plugin name
@@ -59,7 +60,7 @@ var CellMerge = declare("dojox.grid.enhanced.plugins.CellMerge", _Plugin, {
 		//		The column index of the cell whose content should be used as the content of the merged cell.
 		//		It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
 		//		If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
-		// return: Object | null
+		// returns: Object|null
 		//		A handler for the merged cells created by a call of this function.
 		//		This handler can be used later to unmerge cells using the function unmergeCells
 		//		If the merge is not valid, returns null;
@@ -72,7 +73,7 @@ var CellMerge = declare("dojox.grid.enhanced.plugins.CellMerge", _Plugin, {
 		if(item){
 			this._updateRows(item);
 		}
-		return item;
+		return item; // Object|null
 	},
 	unmergeCells: function(mergeHandler){
 		// summary:
@@ -92,16 +93,16 @@ var CellMerge = declare("dojox.grid.enhanced.plugins.CellMerge", _Plugin, {
 		//		Get all records of currently merged cells.
 		// tags:
 		//		public
-		// return: Array
+		// returns: Array
 		//		An array of records for merged-cells.
 		//		The record has the following structure:
-		//		{
-		//			"row": 1, //the row index
-		//			"start": 2, //the start column index
-		//			"end": 4, //the end column index
-		//			"major": 3, //the major column index
-		//			"handle": someHandle, //The handler that covers this merge cell record.
-		//		}
+		// |	{
+		// |		"row": 1, //the row index
+		// |		"start": 2, //the start column index
+		// |		"end": 4, //the end column index
+		// |		"major": 3, //the major column index
+		// |		"handle": someHandle, //The handler that covers this merge cell record.
+		// |	}
 		var res = [];
 		for(var i in this._merged){
 			res = res.concat(this._merged[i]);
@@ -113,7 +114,7 @@ var CellMerge = declare("dojox.grid.enhanced.plugins.CellMerge", _Plugin, {
 		//		Get the records of currently merged cells at the given row.
 		// tags:
 		//		public
-		// return: Array
+		// returns: Array
 		//		An array of records for merged-cells. See docs of getMergedCells.
 		return this._merged[rowIndex] || [];
 	},
diff --git a/dojox/grid/enhanced/plugins/Cookie.js b/dojox/grid/enhanced/plugins/Cookie.js
index 0f4a87e..42fe509 100644
--- a/dojox/grid/enhanced/plugins/Cookie.js
+++ b/dojox/grid/enhanced/plugins/Cookie.js
@@ -155,7 +155,7 @@ define([
 	// Persist sorting order
 	var _loadSortOrder = function(sortOrder, grid){
 		try{
-			if(lang.isObject(sortOrder)){
+			if(sortOrder && lang.isObject(sortOrder)){
 				grid.setSortIndex(sortOrder.idx, sortOrder.asc);
 			}
 		}catch(e){
diff --git a/dojox/grid/enhanced/plugins/DnD.js b/dojox/grid/enhanced/plugins/DnD.js
index 12133ee..1650dfe 100644
--- a/dojox/grid/enhanced/plugins/DnD.js
+++ b/dojox/grid/enhanced/plugins/DnD.js
@@ -13,10 +13,10 @@ define([
 	"dojo/dnd/Avatar",
 	"../_Plugin",
 	"../../EnhancedGrid",
+	"dojo/dnd/Manager",
 	"./Selector",
-	"./Rearrange",
-	"dojo/dnd/Manager"
-], function(dojo, declare, connect, array, lang, html, json, win, query, keys, Source, Avatar, _Plugin, EnhancedGrid){
+	"./Rearrange"
+], function(dojo, declare, connect, array, lang, html, json, win, query, keys, Source, Avatar, _Plugin, EnhancedGrid, Manager){
 
 var _devideToArrays = function(a){
 		a.sort(function(v1, v2){
@@ -242,13 +242,15 @@ var DnD = declare("dojox.grid.enhanced.plugins.DnD", _Plugin, {
 	// summary:
 	//		Provide drag and drop for grid columns/rows/cells within grid and out of grid.
 	//		The store of grid must implement dojo.data.api.Write.
+	//
 	//		DnD selected columns:
-	//			Support moving within grid, moving/copying out of grid to a non-grid DnD target.
+	//		Support moving within grid, moving/copying out of grid to a non-grid DnD target.
+	//
 	//		DnD selected rows:
-	//			Support moving within grid, moving/copying out of grid to any DnD target.
-	//		DnD selected cells (in rectangle shape only):
-	//			Support moving/copying within grid, moving/copying out of grid to any DnD target.
+	//		Support moving within grid, moving/copying out of grid to any DnD target.
 	//
+	//		DnD selected cells (in rectangle shape only):
+	//		Support moving/copying within grid, moving/copying out of grid to any DnD target.
 	
 	// name: String,
 	//		plugin name;
@@ -321,10 +323,11 @@ var DnD = declare("dojox.grid.enhanced.plugins.DnD", _Plugin, {
 		//		Combination of any item from type set ("row", "col", "cell")
 		//		and any item from mode set("within", "in", "out") is configurable.
 		//
-		//		"row", "col", "cell" are straitforward, while the other 3 are explained below:
-		//		"within": DnD within grid, that is, column/row reordering and cell moving/copying.
-		//		"in": Whether allowed to accept rows/cells (currently not support columns) from another grid.
-		//		"out": Whether allowed to drag out of grid, to another grid or even to any other DnD target.
+		//		"row", "col", "cell" are straightforward, while the other 3 are explained below:
+		//
+		//		- "within": DnD within grid, that is, column/row reordering and cell moving/copying.
+		//		- "in": Whether allowed to accept rows/cells (currently not support columns) from another grid.
+		//		- "out": Whether allowed to drag out of grid, to another grid or even to any other DnD target.
 		//
 		//		If not provided in the config, will use the default.
 		//		When declared together, Mode set has higher priority than type set.
@@ -647,7 +650,7 @@ var DnD = declare("dojox.grid.enhanced.plugins.DnD", _Plugin, {
 	},
 	_createSource: function(evt){
 		this._elem.createDnDNodes(this._dndRegion);
-		var m = dojo.dnd.manager();
+		var m = Manager.manager();
 		var oldMakeAvatar = m.makeAvatar;
 		m._dndPlugin = this;
 		m.makeAvatar = function(){
diff --git a/dojox/grid/enhanced/plugins/Exporter.js b/dojox/grid/enhanced/plugins/Exporter.js
index 52e932c..e2bd9b1 100644
--- a/dojox/grid/enhanced/plugins/Exporter.js
+++ b/dojox/grid/enhanced/plugins/Exporter.js
@@ -15,9 +15,10 @@ var Exporter = declare("dojox.grid.enhanced.plugins.Exporter", _Plugin, {
 	//		Provide functions to export the grid data into a given format.
 	//
 	//		Acceptable plugin parameters:
+	//
 	//		1. exportFormatter: function(data, cell, rowIndex, item)
-	//				Provide a way to customize how data should look in exported string.
-	//				Note that usually the formatter of grid cell should not be used here (it can return HTML or even widget).
+	//			Provide a way to customize how data should look in exported string.
+	//			Note that usually the formatter of grid cell should not be used here (it can return HTML or even widget).
 	// example:
 	//	|	function onExported(exported_text){
 	//	|		//custom code here...
@@ -65,17 +66,17 @@ var Exporter = declare("dojox.grid.enhanced.plugins.Exporter", _Plugin, {
 		//		then pass the exported text to a given function(onExported).
 		// tags:
 		//		public
-		// type: string
+		// type: String
 		//		A registered export format name
-		// args: object?
+		// args: Object?
 		//		includes:
-		//		{
-		//			fetchArgs: object?
-		//				Any arguments for store.fetch
-		//			writerArgs: object?
-		//				Arguments for the given format writer
-		//		}
-		// onExported: function(string)
+		// |	{
+		// |		fetchArgs: object?
+		// |			Any arguments for store.fetch
+		// |		writerArgs: object?
+		// |			Arguments for the given format writer
+		// |	}
+		// onExported: Function(string)
 		//		Call back function when export result is ready
 		if(lang.isFunction(args)){
 			onExported = args;
@@ -109,7 +110,7 @@ var Exporter = declare("dojox.grid.enhanced.plugins.Exporter", _Plugin, {
 			onExported(this._goThroughGridData(items, writer));
 		}
 	},
-	exportSelected: function(type, writerArgs){
+	exportSelected: function(type, writerArgs, onExported){
 		// summary:
 		//		Only export selected rows.
 		// tags:
@@ -124,7 +125,7 @@ var Exporter = declare("dojox.grid.enhanced.plugins.Exporter", _Plugin, {
 			return "";
 		}
 		var writer = this._getExportWriter(type, writerArgs);
-		return this._goThroughGridData(this.grid.selection.getSelected(), writer);	//String
+		return onExported(this._goThroughGridData(this.grid.selection.getSelected(), writer));	//String
 	},
 	_buildRow: function(/* object */arg_obj,/* ExportWriter */writer){
 		// summary:
diff --git a/dojox/grid/enhanced/plugins/Filter.js b/dojox/grid/enhanced/plugins/Filter.js
index 7a20c9c..e7ff235 100644
--- a/dojox/grid/enhanced/plugins/Filter.js
+++ b/dojox/grid/enhanced/plugins/Filter.js
@@ -1,7 +1,6 @@
 define([
 	"dojo/_base/declare",
 	"dojo/_base/lang",
-	"dojo/i18n",
 	"../_Plugin",
 	"./Dialog",
 	"./filter/FilterLayer",
@@ -11,53 +10,57 @@ define([
 	"./filter/ClearFilterConfirm",
 	"../../EnhancedGrid",
 	"dojo/i18n!../nls/Filter"
-], function(declare, lang, i18n, _Plugin, Dialog, layers, FilterBar, FilterDefDialog, FilterStatusTip, ClearFilterConfirm, EnhancedGrid){
+], function(declare, lang, _Plugin, Dialog, layers, FilterBar, FilterDefDialog, FilterStatusTip, ClearFilterConfirm, EnhancedGrid, nls){
 
 	var Filter = declare("dojox.grid.enhanced.plugins.Filter", _Plugin, {
 		// summary:
 		//		Provide filter functionality for grid.
 		//
 		//		Acceptable plugin parameters:
-		//		1. itemsName: string
+		//
+		//		1. itemsName: string:
 		//			the name shown on the filter bar.
-		//		2. statusTipTimeout: number
+		//		2. statusTipTimeout: number:
 		//			when does the status tip show.
-		//		3. ruleCount: number
+		//		3. ruleCount: number:
 		//			default to 3, should not change to more. The Claro theme limits it.
-		//		4. disabledConditions: object
+		//		4. disabledConditions: object:
 		//			If you don't need all of the conditions provided for a data type,
 		//			you can explicitly declare them here:
 		//			e.g.: disabledConditions: {string: ["contains", "is"], number: ["equalto"], ...}
-		//		5. isServerSide: boolean
+		//		5. isServerSide: boolean:
 		//			Whether to use server side filtering. Default to false.
-		//		6. isStateful: boolean
+		//		6. isStateful: boolean:
 		//			If isServerSide is true, set the server side filter to be stateful or not. default to false.
-		//		7. url: string
+		//		7. url: string:
 		//			If using stateful, this is the url to send commands. default to store.url.
-		//		8. ruleCountToConfirmClearFilter: Integer | null |Infinity
+		//		8. ruleCountToConfirmClearFilter: Integer | null |Infinity:
 		//			If the filter rule count is larger than or equal to this value, then a confirm dialog will show when clearing filter.
 		//			If set to less than 1 or null, then always show the confirm dialog.
 		//			If set to Infinity, then never show the confirm dialog.
 		//			Default value is 2.
 		//
 		//		Acceptable cell parameters defined in layout:
-		//		1. filterable: boolean
+		//
+		//		1. filterable: boolean:
 		//			The column is not filterable only when this is set to false explicitly.
-		//		2. datatype: string
+		//		2. datatype: string:
 		//			The data type of this column. Can be "string", "number", "date", "time", "boolean".
 		//			Default to "string".
-		//		3. autoComplete: boolean
+		//		3. autoComplete: boolean:
 		//			If need auto-complete in the ComboBox for String type, set this to true.
-		//		4. dataTypeArgs: object
+		//		4. dataTypeArgs: object:
 		//			Some arguments helping convert store data to something the filter UI understands.
 		//			Different data type arguments can be provided to different data types.
 		//			For date/time, this is a dojo.date.locale.__FormatOptions, so the DataTimeBox can understand the store data.
 		//			For boolean, this object contains:
-		//				trueLabel: string
-		//					A label to display in the filter definition dialog for true value. Default to "True".
-		//				falseLable: string
-		//					A label to display in the filter definition dialog for false value. Default to "False".
-		//		5. disabledConditions: object
+		//
+		//			- trueLabel: string:
+		//				A label to display in the filter definition dialog for true value. Default to "True".
+		//			- falseLabel: string:
+		//				A label to display in the filter definition dialog for false value. Default to "False".
+		//
+		//		5. disabledConditions: object:
 		//			If you don't need all of the conditions provided by the filter UI on this column, you can explicitly say it out here.
 		//			e.g.: disabledConditions: ["contains", "is"]
 		//			This will disable the "contains" condition for this column, if this column is of string type.
@@ -88,7 +91,7 @@ define([
 			// summary:
 			//		See constructor of dojox.grid.enhanced._Plugin.
 			this.grid = grid;
-			this.nls = i18n.getLocalization("dojox.grid.enhanced", "Filter");
+			this.nls = nls;
 			
 			args = this.args = lang.isObject(args) ? args : {};
 			if(typeof args.ruleCount != 'number' || args.ruleCount < 0){
@@ -132,7 +135,6 @@ define([
 				this.filterDefDialog.destroy();
 				this.filterDefDialog = null;
 				this.grid = null;
-				this.nls = null;
 				this.args = null;
 			}catch(e){
 				console.warn("Filter.destroy() error:",e);
diff --git a/dojox/grid/enhanced/plugins/GridSource.js b/dojox/grid/enhanced/plugins/GridSource.js
index a2e59ff..be63a30 100644
--- a/dojox/grid/enhanced/plugins/GridSource.js
+++ b/dojox/grid/enhanced/plugins/GridSource.js
@@ -96,50 +96,50 @@ return declare("dojox.grid.enhanced.plugins.GridSource", Source, {
 	getCellContent: function(grid, leftTopCell, rightBottomCell){
 		// summary:
 		//		Fill node innerHTML for dnd grid cells.
-		// sample code:
-		//		var cells = grid.layout.cells;
-		//		var store = grid.store;
-		//		var cache = grid._by_idx;
-		//		var res = "Grid Cells from " + grid.id + ":<br/>";
-		//		for(var r = leftTopCell.row; r <= rightBottomCell.row; ++r){
-		//			for(var c = leftTopCell.col; c <= rightBottomCell.col; ++c){
-		//				res += store.getValue(cache[r].item, cells[c].field) + ", ";
-		//			}
-		//			res = res.substring(0, res.length - 2) + ";<br/>";
-		//		}
-		//		return res;
+		// example:
+		//	|	var cells = grid.layout.cells;
+		//	|	var store = grid.store;
+		//	|	var cache = grid._by_idx;
+		//	|	var res = "Grid Cells from " + grid.id + ":<br/>";
+		//	|	for(var r = leftTopCell.row; r <= rightBottomCell.row; ++r){
+		//	|		for(var c = leftTopCell.col; c <= rightBottomCell.col; ++c){
+		//	|			res += store.getValue(cache[r].item, cells[c].field) + ", ";
+		//	|		}
+		//	|		res = res.substring(0, res.length - 2) + ";<br/>";
+		//	|	}
+		//	|	return res;
 	},
 	getRowContent: function(grid, rowIndexes){
 		// summary:
 		//		Fill node innerHTML for dnd grid rows.
-		// sample code:
-		//		var cells = grid.layout.cells;
-		//		var store = grid.store;
-		//		var cache = grid._by_idx;
-		//		var res = "Grid Rows from " + grid.id + ":<br/>";
-		//		for(var i = 0; i < rowIndexes.length; ++i){
-		//			var r = rowIndexes[i];
-		//			res += "Row " + r + ": ";
-		//			for(var j = 0; j < cells.length; ++j){
-		//				if(!cells[j].hidden){
-		//					res += store.getValue(cache[r].item, cells[j].field) + ", ";
-		//				}
-		//			}
-		//			res = res.substring(0, res.length - 2) + ";<br/>";
-		//		}
-		//		return res;
+		// example:
+		//	|	var cells = grid.layout.cells;
+		//	|	var store = grid.store;
+		//	|	var cache = grid._by_idx;
+		//	|	var res = "Grid Rows from " + grid.id + ":<br/>";
+		//	|	for(var i = 0; i < rowIndexes.length; ++i){
+		//	|		var r = rowIndexes[i];
+		//	|		res += "Row " + r + ": ";
+		//	|		for(var j = 0; j < cells.length; ++j){
+		//	|			if(!cells[j].hidden){
+		//	|				res += store.getValue(cache[r].item, cells[j].field) + ", ";
+		//	|			}
+		//	|		}
+		//	|		res = res.substring(0, res.length - 2) + ";<br/>";
+		//	|	}
+		//	|	return res;
 	},
 	getColumnContent: function(grid, colIndexes){
 		// summary:
 		//		Fill node innerHTML for dnd grid columns.
-		// sample code:
-		//		var cells = grid.layout.cells;
-		//		var res = "Grid Columns from " + grid.id + ":";
-		//		for(var i = 0; i < colIndexes.length; ++i){
-		//			var c = colIndexes[i];
-		//			res += (cells[c].name || cells[c].field) + ", ";
-		//		}
-		//		return res.substring(0, res.length - 2);
+		// example:
+		//	|	var cells = grid.layout.cells;
+		//	|	var res = "Grid Columns from " + grid.id + ":";
+		//	|	for(var i = 0; i < colIndexes.length; ++i){
+		//	|		var c = colIndexes[i];
+		//	|		res += (cells[c].name || cells[c].field) + ", ";
+		//	|	}
+		//	|	return res.substring(0, res.length - 2);
 	},
 	onDropGridCells: function(grid, leftTopCell, rightBottomCell){
 		
diff --git a/dojox/grid/enhanced/plugins/IndirectSelection.js b/dojox/grid/enhanced/plugins/IndirectSelection.js
index e9a98db..af71b8b 100644
--- a/dojox/grid/enhanced/plugins/IndirectSelection.js
+++ b/dojox/grid/enhanced/plugins/IndirectSelection.js
@@ -21,40 +21,40 @@ var RowSelector = declare("dojox.grid.cells.RowSelector", gridCells._Widget, {
 	// summary:
 	//		 Common attributes & functions for row selectors(Radio|CheckBox)
 
-	//inputType: String
+	// inputType: String
 	//		Input type - Radio|CheckBox
 	inputType: "",
 	
-	//map: Object
+	// map: Object
 	//		Cache div refs of radio|checkbox to avoid querying each time
 	map: null,
 	
-	//disabledMap: Object
+	// disabledMap: Object
 	//		Cache index of disabled rows
 	disabledMap: null,
 	
-	//isRowSelector: Boolean
+	// isRowSelector: Boolean
 	//		Marker of indirectSelection cell(column)
 	isRowSelector: true,
 
-	//_connects: Array
+	// _connects: Array
 	//		List of all connections.
 	_connects: null,
 	
-	//_subscribes: Array
+	// _subscribes: Array
 	//		List of all subscribes.
 	_subscribes: null,
 
-	//checkedText: String
+	// checkedText: String
 	//		Checked character for high contrast mode
 	checkedText: '✓',
 
-	//unCheckedText: String
+	// unCheckedText: String
 	//		Unchecked character for high contrast mode
 	unCheckedText: 'O',
 
 	constructor: function(){
-		this.map = {}; this.disabledMap = {}, this.disabledCount= 0;
+		this.map = {}; this.disabledMap = {}; this.disabledCount= 0;
 		this._connects = []; this._subscribes = [];
 		this.inA11YMode = html.hasClass(win.body(), "dijit_a11y");
 		
@@ -76,7 +76,7 @@ var RowSelector = declare("dojox.grid.cells.RowSelector", gridCells._Widget, {
 		//		Overwritten, see dojox.grid.cells._Widget
 		var _this = scope;
 		var clazz = _this.baseClass;
-		var checked = _this.getValue(rowIndex);
+		var checked = !!_this.getValue(rowIndex);
 		var disabled = !!_this.disabledMap[rowIndex];//normalize 'undefined'
 		
 		if(checked){
@@ -88,7 +88,7 @@ var RowSelector = declare("dojox.grid.cells.RowSelector", gridCells._Widget, {
 		return ["<div tabindex = -1 ",
 				"id = '" + _this.grid.id + "_rowSelector_" + rowIndex + "' ",
 				"name = '" + _this.grid.id + "_rowSelector' class = '" + clazz + "' ",
-				"role = 'presentation' aria-pressed = '" + checked + "' aria-disabled = '" + disabled +
+				"role = " + _this.inputType + " aria-checked = '" + checked + "' aria-disabled = '" + disabled +
 				"' aria-label = '" + string.substitute(_this.grid._nls["indirectSelection" + _this.inputType], [rowIndex + 1]) + "'>",
 				"<span class = '" + _this.statusTextClass + "'>" + (checked ? _this.checkedText : _this.unCheckedText) + "</span>",
 				"</div>"].join("");
@@ -191,7 +191,7 @@ var RowSelector = declare("dojox.grid.cells.RowSelector", gridCells._Widget, {
 			if(this.disabledMap[index]){
 				html.toggleClass(selector, this.checkedDisabledClass, value);
 			}
-			selector.setAttribute("aria-pressed", value);
+			selector.setAttribute("aria-checked", value);
 			if(this.inA11YMode){
 				selector.firstChild.innerHTML = (value ? this.checkedText : this.unCheckedText);
 			}
@@ -267,7 +267,7 @@ var SingleRowSelector = declare("dojox.grid.cells.SingleRowSelector", RowSelecto
 		//		Event fired on the target row
 		var index = e.rowIndex;
 		if(this.disabledMap[index]){ return; }
-		this._focusEndingCell(index, 0);
+		this._focusEndingCell(index, e.cellIndex);
 		this._nativeSelect(index, !this.grid.selection.selected[index]);
 	}
 });
@@ -275,32 +275,30 @@ var SingleRowSelector = declare("dojox.grid.cells.SingleRowSelector", RowSelecto
 var MultipleRowSelector = declare("dojox.grid.cells.MultipleRowSelector", RowSelector, {
 	// summary:
 	//		Indirect selection cell for multiple or extended mode, using dijit.form.CheckBox
+
+	// inputType: String
 	inputType: "CheckBox",
 	
-	//swipeStartRowIndex: Integer
+	// swipeStartRowIndex: Integer
 	//		Start row index for swipe selection
 	swipeStartRowIndex: -1,
 
-	//swipeMinRowIndex: Integer
+	// swipeMinRowIndex: Integer
 	//		Min row index for swipe selection
 	swipeMinRowIndex: -1,
 	
-	//swipeMinRowIndex: Integer
+	// swipeMinRowIndex: Integer
 	//		Max row index for swipe selection
 	swipeMaxRowIndex: -1,
 	
-	//toSelect: Boolean
+	// toSelect: Boolean
 	//		new state for selection
 	toSelect: false,
 	
-	//lastClickRowIdx: Integer
+	// lastClickRowIdx: Integer
 	//		Row index for last click, used for range selection via Shift + click
 	lastClickRowIdx: -1,
-	
-	//toggleAllTrigerred: Boolean
-	//		Whether toggle all has been triggered or not
-	toggleAllTrigerred: false,
-	
+		
 	unCheckedText: '□',
 
 	constructor: function(){
@@ -330,7 +328,6 @@ var MultipleRowSelector = declare("dojox.grid.cells.MultipleRowSelector", RowSel
 		}else{
 			selection.deselectAll();
 		}
-		this.toggleAllTrigerred = true;
 	},
 	_onMouseDown: function(e){
 		if(e.cell == this){
@@ -341,7 +338,7 @@ var MultipleRowSelector = declare("dojox.grid.cells.MultipleRowSelector", RowSel
 	_onRowMouseOver: function(e){
 		// summary:
 		//		Event fired when mouse moves over a data row(outside of this column).
-		//      - from dojox.grid.enhanced._Events.onRowMouseOver()
+		//		- from dojox.grid.enhanced._Events.onRowMouseOver()
 		// e: Event
 		//		Decorated event object which contains reference to grid, cell, and rowIndex
 		this._updateSelection(e, 0);
@@ -448,7 +445,7 @@ var MultipleRowSelector = declare("dojox.grid.cells.MultipleRowSelector", RowSel
 	inSwipeSelection: function(){
 		// summary:
 		//		Check if during a swipe selection
-		// return: Boolean
+		// returns: Boolean
 		//		Whether in swipe selection
 		return this.swipeStartRowIndex >= 0;
 	},
@@ -465,7 +462,7 @@ var MultipleRowSelector = declare("dojox.grid.cells.MultipleRowSelector", RowSel
 		var rowIndex = e.rowIndex;
 		if(this.disabledMap[rowIndex]){ return; }
 		evt.stop(e);
-		this._focusEndingCell(rowIndex, 0);
+		this._focusEndingCell(rowIndex, e.cellIndex);
 		
 		var delta = rowIndex - this.lastClickRowIdx;
 		var newValue = !this.grid.selection.selected[rowIndex];
@@ -498,7 +495,7 @@ var MultipleRowSelector = declare("dojox.grid.cells.MultipleRowSelector", RowSel
 		var g = this.grid;
 		var selector = headerCellNode.appendChild(html.create("div", {
 			'aria-label': g._nls["selectAll"],
-			"tabindex": -1, "id": g.id + "_rowSelector_-1", "class": this.baseClass, "role": "presentation",
+			"tabindex": -1, "id": g.id + "_rowSelector_-1", "class": this.baseClass, "role": "Checkbox",
 			"innerHTML": "<span class = '" + this.statusTextClass +
 				"'></span><span style='height: 0; width: 0; overflow: hidden; display: block;'>" +
 				g._nls["selectAll"] + "</span>"
@@ -553,15 +550,16 @@ var IndirectSelection = declare("dojox.grid.enhanced.plugins.IndirectSelection",
 	//		For better rendering performance, div(images) are used to simulate radio button|check boxes
 	//
 	// example:
-	//		<div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: true}" ...></div>
-	//		or <div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: {name: 'xxx', width:'30px', styles:'text-align: center;'}}" ...></div>
+	// |	<div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: true}" ...></div>
+	//		or
+	// |	<div dojoType="dojox.grid.EnhancedGrid" plugins="{indirectSelection: {name: 'xxx', width:'30px', styles:'text-align: center;'}}" ...></div>
 
-	//name: String
+	// name: String
 	//		Plugin name
 	name: "indirectSelection",
 	
 	constructor: function(){
-		//Hook layout.setStructure(), so that indirectSelection is always included
+		// Hook layout.setStructure(), so that indirectSelection is always included
 		var layout = this.grid.layout;
 		this.connect(layout, 'setStructure', lang.hitch(layout, this.addRowSelectCell, this.option));
 	},
diff --git a/dojox/grid/enhanced/plugins/Menu.js b/dojox/grid/enhanced/plugins/Menu.js
index 98dd50c..96e4e46 100644
--- a/dojox/grid/enhanced/plugins/Menu.js
+++ b/dojox/grid/enhanced/plugins/Menu.js
@@ -13,16 +13,16 @@ var Menu = declare("dojox.grid.enhanced.plugins.Menu", _Plugin, {
 	// summary:
 	//		 Provides context menu support, including header menu, row menu, cell menu and selected region menu
 	// example:
-	//		<div dojoType="dojox.grid.EnhancedGrid"
-	//			plugins="{menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
-	//							   selectedRegionMenu:"selectedRegionMenuId"}}" ...>
-	//		</div>
+	// |	<div dojoType="dojox.grid.EnhancedGrid"
+	// |		plugins="{menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
+	// |						   selectedRegionMenu:"selectedRegionMenuId"}}" ...>
+	// |	</div>
 	
-	//name: String
+	// name: String
 	//		Plugin name
 	name: "menus",
 
-	//name: [const] Array
+	// types: [const] String[]
 	//		menu types
 	types: ['headerMenu', 'rowMenu', 'cellMenu', 'selectedRegionMenu'],
 	
@@ -41,7 +41,7 @@ var Menu = declare("dojox.grid.enhanced.plugins.Menu", _Plugin, {
 			}
 		}
 	},
-	_initMenu: function(/*String*/menuType, /*String | Widget(dijit.Menu)*/menu){
+	_initMenu: function(/*String*/ menuType, /*String|dijit/Menu*/ menu){
 		var g = this.grid;
 		if(!g[menuType]){//in case already created in _Grid.postCreate()
 			var m = this._getMenuWidget(menu);
@@ -92,7 +92,9 @@ var Menu = declare("dojox.grid.enhanced.plugins.Menu", _Plugin, {
 		// summary:
 		//		Show appropriate context menu
 		//		Fired from dojox.grid.enhanced._Events.onRowContextMenu, 'this' scope - Grid
-		//		TODO: test Shift-F10
+
+		// TODO: test Shift-F10
+
 		var inSelectedRegion = (e.cellNode && html.hasClass(e.cellNode, 'dojoxGridRowSelected') ||
 			e.rowNode && (html.hasClass(e.rowNode, 'dojoxGridRowSelected') || html.hasClass(e.rowNode, 'dojoxGridRowbarSelected')));
 		
diff --git a/dojox/grid/enhanced/plugins/NestedSorting.js b/dojox/grid/enhanced/plugins/NestedSorting.js
index ed0b01e..666df55 100644
--- a/dojox/grid/enhanced/plugins/NestedSorting.js
+++ b/dojox/grid/enhanced/plugins/NestedSorting.js
@@ -19,6 +19,7 @@ var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin
 	//
 	// description:
 	//		A flexible way to control multiple column sorting, including
+	//
 	//		1. Set default sorting order
 	//		2. Disable sorting for certain columns
 	//		3. Set sorting order dynamically with JS API
@@ -66,7 +67,11 @@ var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin
 		}
 		this.connect(this.grid.views, 'render', '_initSort');//including column resize
 		this.initCookieHandler();
-		this.subscribe("dojox/grid/rearrange/move/" + this.grid.id, lang.hitch(this, '_onColumnDnD'));
+		if(this.grid.plugin('rearrange')){
+			this.subscribe("dojox/grid/rearrange/move/" + this.grid.id, lang.hitch(this, '_onColumnDnD'));
+		}else{
+			this.connect(this.grid.layout, 'moveColumn', '_onMoveColumn');
+		}
 	},
 	onStartUp: function(){
 		//overwrite base Grid functions
@@ -75,6 +80,52 @@ var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin
 		this.connect(this.grid, 'onHeaderCellMouseOver', '_onHeaderCellMouseOver');
 		this.connect(this.grid, 'onHeaderCellMouseOut', '_onHeaderCellMouseOut');
 	},
+	_onMoveColumn: function(sourceViewIndex, destViewIndex, cellIndex, targetIndex, before){
+		var cr = this._getCurrentRegion(),
+			idx = cr && this._getRegionHeader(cr).getAttribute('idx'),
+			c = this._headerNodes[idx],
+			sortData = this._sortData,
+			newSortData = {},
+			sortIndex, data;
+		if(cr){
+			this._blurRegion(cr);
+			this._currRegionIdx = array.indexOf(this._getRegions(), c.firstChild);
+		}
+		if(targetIndex < cellIndex){
+			for(sortIndex in sortData){
+				sortIndex = parseInt(sortIndex, 10);
+				data = sortData[sortIndex];
+				if(data){
+					if(sortIndex >= targetIndex && sortIndex < cellIndex){
+						newSortData[sortIndex + 1] = data;
+					}else if(sortIndex == cellIndex){
+						newSortData[targetIndex] = data;
+					}else{
+						newSortData[sortIndex] = data;
+					}
+				}
+			}
+		}else if(targetIndex > cellIndex + 1){
+			if(!before){
+				targetIndex++;
+			}
+			for(sortIndex in sortData){
+				sortIndex = parseInt(sortIndex, 10);
+				data = sortData[sortIndex];
+				if(data){
+					if(sortIndex > cellIndex && sortIndex < targetIndex){
+						newSortData[sortIndex - 1] = data;
+					}else if(sortIndex == cellIndex){
+						newSortData[targetIndex - 1] = data;
+					}else{
+						newSortData[sortIndex] = data;
+					}
+				}
+			}
+		}
+		this._sortData = newSortData;
+		this._initSort(false);
+	},
 	_onColumnDnD: function(type, mapping){
 		// summary:
 		//		Update nested sorting after column moved		
@@ -209,7 +260,7 @@ var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin
 		this._updateHeaderNodeUI(node);
 	},
 	_onHeaderCellClick: function(e){
-		// summary
+		// summary:
 		//		See dojox.grid.enhanced._Events._onHeaderCellClick()
 		this._focusRegion(e.target);
 		if(html.hasClass(e.target, 'dojoxGridSortBtn')){
@@ -219,7 +270,7 @@ var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin
 		}
 	},
 	_onHeaderCellMouseOver: function(e){
-		// summary
+		// summary:
 		//		See dojox.grid._Events._onHeaderCellMouseOver()
 		//		When user mouseover other columns than sorted column in a single sorted grid,
 		//		We need to show 1 in the sorted column
@@ -266,7 +317,7 @@ var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin
 		}
 	},
 	_onHeaderCellMouseOut: function(e){
-		// summary
+		// summary:
 		//		See dojox.grid.enhanced._Events._onHeaderCellMouseOut()
 		var p;
 		for(p in this._sortData){
@@ -340,7 +391,7 @@ var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin
 		}
 	},
 	_prepareNestedSort: function(cellIdx){
-		// summary
+		// summary:
 		//		Prepare the nested sorting, this will order the column on existing sorting result.
 		var i = this._sortData[cellIdx] ? this._sortData[cellIdx].index : null;
 		if(i === 0 || !!i){ return; }
@@ -489,15 +540,21 @@ var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin
 	_focusHeader: function(e){
 		// summary:
 		//		Overwritten, see _FocusManager.focusHeader()
-		//delayed: Boolean
+		// delayed: Boolean
 		//		If called from "this.focus._delayedHeaderFocus()"
 		if(this._currRegionIdx === -1){
 			this._onMove(0, 1, null);
 		}else{
-			this._focusRegion(this._getCurrentRegion());
+			var region = this._getCurrentRegion();
+			this._focusRegion(region);
+			//keep grid body scrolled by header
+			var view = this._getRegionView(region);
+			view.scrollboxNode.scrollLeft = view.headerNode.scrollLeft;
 		}
 		try{
-			evt.stop(e);
+			if(e){
+				evt.stop(e);
+			}
 		}catch(e){}
 		return true;
 	},
@@ -558,7 +615,7 @@ var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin
 		return regions;
 	},
 	_focusRegion: function(region){
-		// summary
+		// summary:
 		//		Focus the given region
 		if(!region){return;}
 		var currRegion = this._getCurrentRegion();
@@ -572,7 +629,10 @@ var NestedSorting = declare("dojox.grid.enhanced.plugins.NestedSorting", _Plugin
 		}else if(html.hasClass(region, 'dojoxGridSortBtn')){
 			html.addClass(region, 'dojoxGridSortBtnFocus');
 		}
-		region.focus();
+		//For invisible nodes, IE will throw error when calling focus().
+		try{
+			region.focus();
+		}catch(e){}
 		this.focus.currentArea('header');
 		this._currRegionIdx = array.indexOf(this._focusRegions, region);
 	},
diff --git a/dojox/grid/enhanced/plugins/Pagination.js b/dojox/grid/enhanced/plugins/Pagination.js
index 1250504..a682596 100644
--- a/dojox/grid/enhanced/plugins/Pagination.js
+++ b/dojox/grid/enhanced/plugins/Pagination.js
@@ -6,10 +6,8 @@ define([
 	"dojo/_base/lang",
 	"dojo/_base/html",
 	"dojo/_base/event",
-	"dojo/_base/window",
 	"dojo/query",
 	"dojo/string",
-	"dojo/i18n",
 	"dojo/keys",
 	"dojo/text!../templates/Pagination.html",
 	"./Dialog",
@@ -24,9 +22,9 @@ define([
 	"dijit/_WidgetsInTemplateMixin",
 	"dojox/html/metrics",
 	"dojo/i18n!../nls/Pagination"
-], function(kernel, declare, array, connect, lang, html, event, win, query, 
-	string, i18n, keys, template, Dialog, layers, _Plugin, EnhancedGrid,
-	Button, NumberTextBox, dijitFocus, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, metrics){
+], function(kernel, declare, array, connect, lang, html, event, query,
+	string, keys, template, Dialog, layers, _Plugin, EnhancedGrid,
+	Button, NumberTextBox, dijitFocus, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, metrics, nls){
 		
 var _GotoPagePane = declare("dojox.grid.enhanced.plugins.pagination._GotoPagePane", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
 	templateString: "<div>" + 
@@ -110,7 +108,7 @@ var _ForcedPageStoreLayer = declare("dojox.grid.enhanced.plugins._ForcedPageStor
 		var _this = this,
 			plugin = _this._plugin,
 			grid = plugin.grid,
-			scope = request.scope || win.global,
+			scope = request.scope || kernel.global,
 			onBegin = request.onBegin;
 		request.start = (plugin._currentPage - 1) * plugin._currentPageSize + request.start;
 		_this.startIdx = request.start;
@@ -149,7 +147,9 @@ var _ForcedPageStoreLayer = declare("dojox.grid.enhanced.plugins._ForcedPageStor
 
 var stopEvent = function(evt){
 	try{
-		event.stop(evt);
+		if(evt){
+			event.stop(evt);
+		}
 	}catch(e){}
 };
 
@@ -354,7 +354,7 @@ var _Paginator = declare("dojox.grid.enhanced.plugins._Paginator", [_Widget, _Te
 		}
 		var padBorder = g._getPadBorder().h;
 		if(!this.plugin.gh){
-			this.plugin.gh = html.contentBox(g.domNode).h + 2 * padBorder;
+			this.plugin.gh = (g.domNode.clientHeight || html.style(g.domNode, 'height')) + 2 * padBorder;
 		}
 		if(resultSize){
 			changeSize = resultSize;
@@ -675,31 +675,40 @@ var Pagination = declare("dojox.grid.enhanced.plugins.Pagination", _Plugin, {
 	//		The typical pagination way to deal with huge dataset
 	//		an alternative for the default virtual scrolling manner.
 	name: "pagination",
+
 	// defaultPageSize: Integer
 	//		Number of rows in a page, 25 by default.
 	defaultPageSize: 25,
+
 	// defaultPage: Integer
 	//		Which page will be displayed initially, 1st page by default.
 	defaultPage: 1,
+
 	// description: boolean
 	//		Whether the description information will be displayed, true by default.
 	description: true,
+
 	// sizeSwitch: boolean
 	//		Whether the page size switch options will be displayed, true by default.
 	sizeSwitch: true,
+
 	// pageStepper: boolean
 	//		Whether the page switch options will be displayed, true by default.
 	pageStepper: true,
+
 	// gotoButton: boolean
 	//		Whether the goto page button will be displayed, false by default.
 	gotoButton: false,
+
 	// pageSizes: Array
 	//		Array of page sizes for switching, e.g. [10, 25, 50, 100, Infinity] by default,
 	//		Infinity or any NaN value will be treated as "all".
 	pageSizes: [10, 25, 50, 100, Infinity],
+
 	// maxPageStep: Integer
 	//		The max number of page sizes to be displayed, 7 by default.
 	maxPageStep: 7,
+
 	// position: string
 	//		The position of the pagination bar - "top"|"bottom", "bottom" by default.
 	position: 'bottom',
@@ -735,9 +744,9 @@ var Pagination = declare("dojox.grid.enhanced.plugins.Pagination", _Plugin, {
 		// summary:
 		//		Shift to the given page, return current page number. If there 
 		//		is no valid page was passed in, just return current page num.
-		//	page: Integer
+		// page: Integer
 		//		The page to go to, starting at 1.
-		//	return:
+		// returns:
 		//		Current page number
 		if(page <= this.getTotalPageNum() && page > 0 && this._currentPage !== page){
 			this._currentPage = page;
@@ -767,13 +776,13 @@ var Pagination = declare("dojox.grid.enhanced.plugins.Pagination", _Plugin, {
 		this.currentPage(this.getTotalPageNum());
 	},
 	currentPageSize: function(size){
-		//	summary:
+		// summary:
 		//		Change the size of current page or return the current page size.
-		//	size: Integer || null
+		// size: Integer|null
 		//		An integer identifying the number of rows per page. If the size
-		//		is an Infinity, all rows will be displayed; if an invalid value pssed
+		//		is an Infinity, all rows will be displayed; if an invalid value passed
 		//		in, the current page size will be returned.
-		//	return
+		// returns:
 		//		Current size of items per page.  
 		if(!isNaN(size)){
 			var g = this.grid,
@@ -825,6 +834,9 @@ var Pagination = declare("dojox.grid.enhanced.plugins.Pagination", _Plugin, {
 		this._multiRemoving = true;
 		this._gridOriginalfuncs[2].apply();
 		this._multiRemoving = false;
+		if(this.grid.store.save){
+			this.grid.store.save();
+		}
 		this.grid.resize();
 		this.grid._refresh();
 	},
@@ -886,7 +898,6 @@ var Pagination = declare("dojox.grid.enhanced.plugins.Pagination", _Plugin, {
 		this.defaultPageSize = this.option.defaultPageSize >= 1 ? parseInt(this.option.defaultPageSize, 10) : this.pageSizes[0];
 		this.option.maxPageStep = this.option.maxPageStep > 0 ? this.option.maxPageStep : this.maxPageStep;
 		this.option.position = lang.isString(this.option.position) ? this.option.position.toLowerCase() : this.position;
-		var nls = i18n.getLocalization("dojox.grid.enhanced", "Pagination");
 		this._nls = [
 			nls.descTemplate,
 			nls.allItemsLabelTemplate,
diff --git a/dojox/grid/enhanced/plugins/Printer.js b/dojox/grid/enhanced/plugins/Printer.js
index 7d1f4ba..58229c0 100644
--- a/dojox/grid/enhanced/plugins/Printer.js
+++ b/dojox/grid/enhanced/plugins/Printer.js
@@ -23,25 +23,28 @@ var Printer = declare("dojox.grid.enhanced.plugins.Printer", _Plugin, {
 	//	|								{table:"border='border'"}		//tagName:"attrbuteList" pairs, optional,
 	//	|																//control the html tags in the generated html
 	//	|	);
-	
-	// __printArgs: {
-	//		title: String
-	//			A title of the printed page can be specified. Optional.
-	//			If given, it's shown in an <h1> tag at the top of the page.
-	//		cssFiles: Array | String
-	//			CSS file paths. Optional.
-	//			Every row and column is given CSS classes, including:
-	//				grid_row_{row-number}, grid_odd_row, grid_even_row, grid_header,
-	//				grid_col_{col-number}, grid_odd_col, grid_even_col
-	//			{row_number} and {col-number} are both integers starting from 1.
-	//			Row classes are for <thead> and <tbody> tags.
-	//			Column classes are for <th> and <td> tags.
-	//			Users can use these classes in the CSS files, but cannot define their own.
-	//		writerArgs: Object (Association Array)
-	//			Arguments for TableWriter.
-	//		fetchArgs: object?
-	//			Any arguments for store.fetch
-	// }
+
+	/*=====
+	__printArgs: {
+		// title: String
+		//		A title of the printed page can be specified. Optional.
+		//		If given, it's shown in an <h1> tag at the top of the page.
+		// cssFiles: Array|String
+		//		CSS file paths. Optional.
+		//		Every row and column is given CSS classes, including:
+		//
+		//		- grid_row_{row-number}, grid_odd_row, grid_even_row, grid_header,
+		//				grid_col_{col-number}, grid_odd_col, grid_even_col
+		//		- {row_number} and {col-number} are both integers starting from 1.
+		//		- Row classes are for <thead> and <tbody> tags.
+		//		- Column classes are for <th> and <td> tags.
+		//		- Users can use these classes in the CSS files, but cannot define their own.
+		// writerArgs: Object
+		//		 Associative Array, arguments for TableWriter.
+		// fetchArgs: object?
+		//		Any arguments for store.fetch
+	},
+	=====*/
 	
 	// name: String
 	//		Plugin name
diff --git a/dojox/grid/enhanced/plugins/Rearrange.js b/dojox/grid/enhanced/plugins/Rearrange.js
index 484671b..4fcf8a7 100644
--- a/dojox/grid/enhanced/plugins/Rearrange.js
+++ b/dojox/grid/enhanced/plugins/Rearrange.js
@@ -48,7 +48,7 @@ var Rearrange = declare("dojox.grid.enhanced.plugins.Rearrange", _Plugin, {
 	moveColumns: function(colsToMove, targetPos){
 		// summary:
 		//		Move a set of columns to a given position.
-		// tag:
+		// tags:
 		//		public
 		// colsToMove: Integer[]
 		//		Array of column indexes.
@@ -113,7 +113,7 @@ var Rearrange = declare("dojox.grid.enhanced.plugins.Rearrange", _Plugin, {
 	moveRows: function(rowsToMove, targetPos){
 		// summary:
 		//		Move a set of rows to a given position
-		// tag:
+		// tags:
 		//		public
 		// rowsToMove: Integer[]
 		//		Array of row indexes.
@@ -362,10 +362,11 @@ var Rearrange = declare("dojox.grid.enhanced.plugins.Rearrange", _Plugin, {
 				rowCnt = g.rowCount,
 				mapping = {},
 				obj = {idx: 0},
-				newRows = [], i,
-				emptyTarget = targetPos < 0;
-				_this = this;
-			var len = rowsToMove.length;
+				newRows = [],
+				i,
+				emptyTarget = targetPos < 0,
+				_this = this,
+				len = rowsToMove.length;
 			if(emptyTarget){
 				targetPos = 0;
 			}else{
@@ -388,8 +389,10 @@ var Rearrange = declare("dojox.grid.enhanced.plugins.Rearrange", _Plugin, {
 						//So try to get attrs from grid.layout.cells[], but this might not be right
 						//since some fields may be missed(e.g ID fields), please use "setIdentifierForNewItem()" 
 						//to add those missed fields
-						attrs = array.map(g.layout.cells, function(cell){
+						attrs = array.filter(array.map(g.layout.cells, function(cell){
 							return cell.field;
+						}), function(field){
+							return field; //non empty
 						});
 					}
 					var rowsToFetch = [];
@@ -465,7 +468,7 @@ var Rearrange = declare("dojox.grid.enhanced.plugins.Rearrange", _Plugin, {
 	_getPageInfo: function(){
 		// summary:
 		//		Find pages that contain visible rows
-		// return: Object
+		// returns: Object
 		//		{topPage: xx, bottomPage: xx, invalidPages: [xx,xx,...]}
 		var scroller = this.grid.scroller,
 			topPage = scroller.page,
diff --git a/dojox/grid/enhanced/plugins/Selector.js b/dojox/grid/enhanced/plugins/Selector.js
index 330cc13..bdb9956 100644
--- a/dojox/grid/enhanced/plugins/Selector.js
+++ b/dojox/grid/enhanced/plugins/Selector.js
@@ -17,11 +17,11 @@ define([
 ], function(dojo, lang, declare, array, event, keys, query, html, win, dijitFocus, _RowSelector, _Plugin, EnhancedGrid){
 
 /*=====
-dojo.declare("__SelectItem", null,{
+declare("__SelectItem", null,{
 	// summary:
 	//		An abstract representation of an item.
 });
-dojo.declare("__SelectCellItem", __SelectItem,{
+declare("__SelectCellItem", __SelectItem,{
 	// summary:
 	//		An abstract representation of a cell.
 	
@@ -33,7 +33,7 @@ dojo.declare("__SelectCellItem", __SelectItem,{
 	//		Column index of this cell
 	col: 0
 });
-dojo.declare("__SelectRowItem", __SelectItem,{
+declare("__SelectRowItem", __SelectItem,{
 	// summary:
 	//		An abstract representation of a row.
 	
@@ -45,7 +45,7 @@ dojo.declare("__SelectRowItem", __SelectItem,{
 	//		An array of column indexes of all the unselected cells in this row.
 	except: []
 });
-dojo.declare("__SelectColItem", __SelectItem,{
+declare("__SelectColItem", __SelectItem,{
 	// summary:
 	//		An abstract representation of a column.
 	
@@ -120,12 +120,13 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	// summary:
 	//		Provides standard extended selection for grid.
 	//		Supports mouse/keyboard selection, multi-selection, and de-selection.
+	//
 	//		Acceptable plugin parameters:
-	//			The whole plugin parameter object is a config object passed to the setupConfig function.
+	//		The whole plugin parameter object is a config object passed to the setupConfig function.
 	//
 	//		Acceptable cell parameters defined in layout:
-	//		1. notselectable: boolean
-	//			Whether this column is (and all the cells in it are) selectable.
+	//
+	//		1. notselectable: Boolean: Whether this column is (and all the cells in it are) selectable.
 	
 	// name: String
 	//		plugin name
@@ -205,12 +206,12 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 		//		Set selection mode for row/col/cell.
 		// config: Object
 		//		An object with the following structure (all properties are optional):
-		//		{
-		//			//Default is "multi", all other values are same as "multi".
-		//			row: false|"disabled"|"single",
-		//			col: false|"disabled"|"single",
-		//			cell: false|"disabled"|"single"
-		//		}
+		// |	{
+		// |		//Default is "multi", all other values are same as "multi".
+		// |		row: false|"disabled"|"single",
+		// |		col: false|"disabled"|"single",
+		// |		cell: false|"disabled"|"single"
+		// |	}
 		if(!config || !lang.isObject(config)){
 			return;
 		}
@@ -234,7 +235,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	isSelected: function(type, rowIndex, colIndex){
 		// summary:
 		//		Check whether a location (a cell, a column or a row) is selected.
-		// tag:
+		// tags:
 		//		public
 		// type: String
 		//		"row" or "col" or "cell"
@@ -243,7 +244,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 		//		If type if "col", this is the column index.
 		// colIndex: Integer?
 		//		Only valid when type is "cell"
-		// return: Boolean
+		// returns: Boolean
 		//		true if selected, false if not. If cell is covered by a selected column, it's selected.
 		return this._isSelected(type, _createItem(type, rowIndex, colIndex));
 	},
@@ -254,7 +255,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	select: function(type, rowIndex, colIndex){
 		// summary:
 		//		Select a location (a cell, a column or a row).
-		// tag:
+		// tags:
 		//		public
 		// type: String
 		//		"row" or "col" or "cell"
@@ -275,14 +276,14 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	selectRange: function(type, start, end, toSelect){
 		// summary:
 		//		Select a continuous range (a block of cells, a set of continuous columns or rows)
-		// tag:
+		// tags:
 		//		public
 		// type: String
 		//		"row" or "col" or "cell"
-		// start: Integer | Object
+		// start: Integer|Object
 		//		If type is "row" or "col", this is the index of the starting row or column.
 		//		If type if "cell", this is the left-top cell of the range.
-		// end: Integer | Object
+		// end: Integer|Object
 		//		If type is "row" or "col", this is the index of the ending row or column.
 		//		If type if "cell", this is the right-bottom cell of the range.
 		this.grid._selectingRange = true;
@@ -296,7 +297,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	clear: function(type){
 		// summary:
 		//		Clear all selections.
-		// tag:
+		// tags:
 		//		public
 		// type: String?
 		//		"row" or "col" or "cell". If omitted, clear all.
@@ -305,11 +306,11 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	isSelecting: function(type){
 		// summary:
 		//		Check whether the user is currently selecting something.
-		// tag:
+		// tags:
 		//		public
 		// type: String
 		//		"row" or "col" or "cell"
-		// return: Boolean
+		// returns: Boolean
 		//		true if is selection, false otherwise.
 		if(typeof type == "undefined"){
 			return this._selecting.col || this._selecting.row || this._selecting.cell;
@@ -320,11 +321,11 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 		// summary:
 		//		Turn on/off this selection functionality if *toEnable* is provided.
 		//		Check whether this selection functionality is enabled if nothing is passed in.
-		// tag:
+		// tags:
 		//		public
 		// toEnable: Boolean?
-		//		To enable or not. Optional.
-		// return: Boolean | undefined
+		//		To enable or not.
+		// returns: Boolean|undefined
 		//		Enabled or not.
 		if(typeof toEnable != "undefined" && !this.isSelecting()){
 			this._enabled = !!toEnable;
@@ -334,13 +335,13 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	getSelected: function(type, includeExceptions){
 		// summary:
 		//		Get an array of selected locations.
-		// tag:
+		// tags:
 		//		public
 		// type: String
 		//		"row" or "col" or "cell"
 		// includeExceptions: Boolean
 		//		Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
-		// return: __SelectItem[]
+		// returns: __SelectItem[]
 		switch(type){
 			case "cell":
 				return array.map(this._selected[type], function(item){ return item; });
@@ -357,13 +358,13 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	getSelectedCount: function(type, includeExceptions){
 		// summary:
 		//		Get the number of selected items.
-		// tag:
+		// tags:
 		//		public
 		// type: String
 		//		"row" or "col" or "cell"
 		// includeExceptions: Boolean
 		//		Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
-		// return: Integer
+		// returns: Integer
 		//		The number of selected items.
 		switch(type){
 			case "cell":
@@ -379,9 +380,9 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	getSelectedType: function(){
 		// summary:
 		//		Get the type of selected items.
-		// tag:
+		// tags:
 		//		public
-		// return: String
+		// returns: String
 		//		"row" or "col" or "cell", or any mix of these (separator is | ).
 		var s = this._selected;
 		return ["",		"cell",		"row",		"row|cell",
@@ -391,9 +392,9 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	getLastSelectedRange: function(type){
 		// summary:
 		//		Get last selected range of the given type.
-		// tag:
+		// tags:
 		//		public
-		// return: Object
+		// returns: Object
 		//		{start: __SelectItem, end: __SelectItem}
 		//		return null if nothing is selected.
 		return this._lastAnchorPoint[type] ? {
@@ -922,7 +923,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 		// summary:
 		//		Clear selection for given type and fire events, but retain the highlight for *reservedItem*,
 		//		thus avoid "flashing".
-		// tag:
+		// tags:
 		//		private
 		// type: String
 		//		"row", "col", or "cell
@@ -958,7 +959,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	_startSelect: function(type, start, extending, isRange, mandatarySelect, toSelect){
 		// summary:
 		//		Start selection, setup start point and current point, fire events.
-		// tag:
+		// tags:
 		//		private
 		// type: String
 		//		"row", "col", or "cell"
@@ -1001,7 +1002,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 			if(type === "row"){
 				this._isUsingRowSelector = true;
 			}
-			this._startPoint[type] = this._lastEndPoint[type];
+			this._startPoint[type] = this._lastAnchorPoint[type];
 			this._highlight(type, this._startPoint[type]);
 			this._isUsingRowSelector = false;
 		}else{
@@ -1018,7 +1019,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	_endSelect: function(type){
 		// summary:
 		//		End selection. Keep records, fire events and cleanup status.
-		// tag:
+		// tags:
 		//		private
 		// type: String
 		//		"row", "col", or "cell"
@@ -1057,6 +1058,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 		// summary:
 		//		Calculate what status should *target* have.
 		//		If *toSelect* is not provided, this is a no op.
+		
 		// This function is time-critical!!
 		if(toSelect !== undefined){
 			var sltd;
@@ -1108,6 +1110,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	_highlightSingle: function(type, toHighlight, target, toSelect, isRefresh){
 		// summary:
 		//		Highlight a single item.
+		
 		// This function is time critical!!
 		var _this = this, toHL, g = _this.grid, cells = g.layout.cells;
 		switch(type){
@@ -1157,6 +1160,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 		//		Highlight from start point to target.
 		// toSelect: Boolean
 		//		Whether we are selecting or deselecting.
+		
 		// This function is time critical!!
 		if(this._selecting[type] && target !== null){
 			var start = this._startPoint[type],
@@ -1223,9 +1227,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 		// summary:
 		//		Blur the current point.
 		var f = this.grid.focus;
-		if(type == "col"){
-			f._blurHeader();
-		}else if(type == "cell"){
+		if(type == "cell"){
 			f._blurContent();
 		}
 	},
@@ -1271,6 +1273,7 @@ var Selector = declare("dojox.grid.enhanced.plugins.Selector", _Plugin, {
 	_forEach: function(type, start, end, func, halfClose){
 		// summary:
 		//		Go through items from *start* point to *end* point.
+		
 		// This function is time critical!!
 		if(!this._isValid(type, start, true) || !this._isValid(type, end, true)){
 			return;
diff --git a/dojox/grid/enhanced/plugins/_RowMapLayer.js b/dojox/grid/enhanced/plugins/_RowMapLayer.js
index 532da67..d8bb192 100644
--- a/dojox/grid/enhanced/plugins/_RowMapLayer.js
+++ b/dojox/grid/enhanced/plugins/_RowMapLayer.js
@@ -1,9 +1,10 @@
 define([
-	"dojo/_base/declare",
 	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/kernel",
 	"dojo/_base/lang",
 	"./_StoreLayer"
-], function(declare, array, lang, layers){
+], function(array, declare, kernel, lang, layers){
 
 var _devideToArrays = function(a){
 	a.sort(function(v1, v2){
@@ -20,7 +21,7 @@ var _devideToArrays = function(a){
 	return arr;
 },
 hitchIfCan = function(scope, func){
-	return func ? lang.hitch(scope || lang.global, func) : function(){};
+	return func ? lang.hitch(scope || kernel.global, func) : function(){};
 };
 
 return declare("dojox.grid.enhanced.plugins._RowMapLayer", layers._StoreLayer, {
diff --git a/dojox/grid/enhanced/plugins/_SelectionPreserver.js b/dojox/grid/enhanced/plugins/_SelectionPreserver.js
index 5e1e272..e9d31cb 100644
--- a/dojox/grid/enhanced/plugins/_SelectionPreserver.js
+++ b/dojox/grid/enhanced/plugins/_SelectionPreserver.js
@@ -75,6 +75,7 @@ return declare("dojox.grid.enhanced.plugins._SelectionPreserver", _SelectionPres
 	_updateMapping: function(trustSelection, isSelect, isForAll, from, to){
 		// summary:
 		//		This function try to keep the selection info updated when range selection is performed.
+		//
 		//		1. Calculate how many unloaded rows are there;
 		//		2. update _selectedById data if grid.selection._selected can be trusted, so loaded but unselected rows can
 		//			be properly recorded.
diff --git a/dojox/grid/enhanced/plugins/_StoreLayer.js b/dojox/grid/enhanced/plugins/_StoreLayer.js
index 05b213f..1f7f1bd 100644
--- a/dojox/grid/enhanced/plugins/_StoreLayer.js
+++ b/dojox/grid/enhanced/plugins/_StoreLayer.js
@@ -4,39 +4,41 @@ define([
 	"dojo/_base/lang",
 	"dojo/_base/xhr"
 ], function(declare, array, lang, xhr){
-// summary:
-//		The dojo.data.api.Read API is powerful, but it's difficult to give the store some special commands before
-//		fetch, so that the store content can be temporarily modified or transformed, and acts as another store. The
-//		parameter *query* or *queryOptions* in keywordArgs for *fetch* is not enough because:
-//		1.	users do not have the opportunity to response to the store actions when these options or queries are applied,
-//			especially when the real store is at server side.
-//		2.	the store implementation must be changed to support any new options in 'query' or 'queryOptions', so it'll be
-//			difficult if this implementation is not able to or very hard to be changed, or some new options are required to
-//			be valid for all stores.
-//		This *StoreLayer* framework is dedicated to provide a uniform way for configuring an existing store, so that
-//		it can be easily extended to have special behaviors or act like a totally different store.
-//		The major approach is to wrap the *fetch* function of store, layer by layer. Every layer treats the incoming
-//		store.fetch as a 'black box', thus maintaining the independence between layers.
-//		*fetch* is the most important data retriever in the Read API, almost all other functions are used for a single
-//		item, and require that this item is already retrieved (by and only by *fetch*). So once we've controlled this
-//		*fetch* function, we've controlled almost the whole store. This fact simplifies our implementation of StoreLayer.
-// example:
-//		//ns is for namespace, i.e.:dojox.grid.enhanced.plugins
-//		ns.wrap(ns.wrap(ns.wrap(store, new ns.FilterLayer()), new ns.UniqueLayer()), new ns.TransformLayer());
-//
-//		//every layer has a name, it should be given in the document of this layer.
-//		//if you don't know it's name, you can get it by: ns.SomeLayer.prototype.name();
-//		store.layer("filter").filterDef(...);
-//		store.layer("unique").setUniqueColumns(...);
-//		store.layer("transform").setScheme(...);
-//
-//		//now use the store as usual...
-//
-//		store.unwrap("transform"); //remove the transform layer but retain the other two.
-//
-//		//now use the store as usual...
-//
-//		store.unwrap(); //remove all the layers, get the original store back.
+	// summary:
+	//		The dojo/data/api/Read API is powerful, but it's difficult to give the store some special commands before
+	//		fetch, so that the store content can be temporarily modified or transformed, and acts as another store. The
+	//		parameter *query* or *queryOptions* in keywordArgs for *fetch* is not enough because:
+	//
+	//		1.	users do not have the opportunity to response to the store actions when these options or queries are applied,
+	//			especially when the real store is at server side.
+	//		2.	the store implementation must be changed to support any new options in 'query' or 'queryOptions', so it'll be
+	//			difficult if this implementation is not able to or very hard to be changed, or some new options are required to
+	//			be valid for all stores.
+	//
+	//		This *StoreLayer* framework is dedicated to provide a uniform way for configuring an existing store, so that
+	//		it can be easily extended to have special behaviors or act like a totally different store.
+	//		The major approach is to wrap the *fetch* function of store, layer by layer. Every layer treats the incoming
+	//		store.fetch as a 'black box', thus maintaining the independence between layers.
+	//		*fetch* is the most important data retriever in the Read API, almost all other functions are used for a single
+	//		item, and require that this item is already retrieved (by and only by *fetch*). So once we've controlled this
+	//		*fetch* function, we've controlled almost the whole store. This fact simplifies our implementation of StoreLayer.
+	// example:
+	//	| //ns is for namespace, i.e.:dojox.grid.enhanced.plugins
+	//	| ns.wrap(ns.wrap(ns.wrap(store, new ns.FilterLayer()), new ns.UniqueLayer()), new ns.TransformLayer());
+	//	| 
+	//	| //every layer has a name, it should be given in the document of this layer.
+	//	| //if you don't know it's name, you can get it by: ns.SomeLayer.prototype.name();
+	//	| store.layer("filter").filterDef(...);
+	//	| store.layer("unique").setUniqueColumns(...);
+	//	| store.layer("transform").setScheme(...);
+	//	| 
+	//	| //now use the store as usual...
+	//	| 
+	//	| store.unwrap("transform"); //remove the transform layer but retain the other two.
+	//	| 
+	//	| //now use the store as usual...
+	//	| 
+	//	| store.unwrap(); //remove all the layers, get the original store back.
 
 	var ns = lang.getObject("grid.enhanced.plugins", true, dojox);
 	
@@ -145,7 +147,7 @@ define([
 		//		The store to be wrapped.
 		// layer: _StoreLayer
 		//		The layer to be used
-		// returns
+		// returns:
 		//		The wrapped store, for nested use only.
 		if(!store._layers){
 			store._layers = [];
@@ -200,12 +202,8 @@ define([
 			this.__enabled = true;
 		},
 		initialize: function(store){
-			// summary:
-			//
 		},
 		uninitialize: function(store){
-			// summary:
-			//
 		},
 		invalidate: function(){
 			
@@ -313,7 +311,7 @@ define([
 			// summary:
 			//		If you only want to modify the user request, instead of sending a separate command
 			//		to server before fetch, just call:
-			//			this.useCommand(false);
+			// |		this.useCommand(false);
 			// tags:
 			//		public
 			// toUse: Boolean?
@@ -342,7 +340,7 @@ define([
 				this.onCommandLoad("", userRequest);
 				this.originFetch(userRequest);
 			}
-			return userRequest;	//dojo.data.api.Request
+			return userRequest;	// dojo/data/api/Request
 		},
 		command: function(/* string */cmdName,/* (string|number|bool|...)? */cmdContent){
 			// summary:
@@ -370,7 +368,7 @@ define([
 			//		callback extension
 			// response: string
 			//		server response
-			// userRequest: [in|out] dojo.data.api.Request
+			// userRequest: [in|out] dojo/data/api/Request
 			//		The request object for *fetch*. You can modify this object according to the *response*
 			//		so as to change the behavior of *fetch*
 			this._onUserCommandLoad(this.__cmds, userRequest, response);
diff --git a/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js b/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js
index 319674e..8594d3e 100644
--- a/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js
+++ b/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js
@@ -9,11 +9,14 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 	//		This is an abstract class for all kinds of writers used in the Exporter plugin.
 	//		It utilizes the strategy pattern to break the export work into several stages,
 	//		and provide interfaces for all of them.
-	//			Implementations might choose some of the functions in this class to override,
+	//
+	//		Implementations might choose some of the functions in this class to override,
 	//		thus providing their own functionalities.
-	//			The Exporter will go through the grid line by line. So in every line, all the Views
+	//
+	//		The Exporter will go through the grid line by line. So in every line, all the Views
 	//		will be reached, and the header line is only handled once.
-	//			An *argObj* object is passed to most functions of this class.
+	//
+	//		An *argObj* object is passed to most functions of this class.
 	//		It carries context arguments that make sense when they are called.
 
 /*=====
@@ -49,20 +52,20 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		//		Reference to the current cell.
 		cell: null,
 		
-		//cellIdx: int
+		// cellIdx: int
 		//		The index of the current cell in the current subrow.
 		//		It's different from cell.index, which is the index in the whole line.
 		cellIdx: -1,
 		
-		//row: item
+		// row: item
 		//		The current row of data (logically), a.k.a.: current item.
 		row: null,
 		
-		//rowIdx: int
+		// rowIdx: int
 		//		The index of the current row (item).
 		rowIdx: -1,
 		
-		// spCols: Array<int>
+		// spCols: int[]
 		//		An array of special column indexes(flat,not regarding structure).
 		//		Special columns are typically attached to grid as a kind of UI facility
 		//		by the grid widget, instead of some real data.
@@ -74,8 +77,9 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		//		If the grid has a _RowSelector view or something else, this view will NOT be
 		//		passed to the user in argObj. So the column index (cell.index) will appear shifted
 		//		(start from 1 instead of 0). This colOffset is provided to remove this shift.
-		// usage:
-		//		var correctColIndex = argObj.cell.index + argObj.colOffset;
+		//
+		//		usage:
+		//		|	var correctColIndex = argObj.cell.index + argObj.colOffset;
 		colOffset: 0
 	},
 =====*/
@@ -101,9 +105,9 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		//		Is there anything we should do now?
 		// tags:
 		//		protected extension
-		// return:
-		//		true: go on hanling the header row and then call afterHeader.
-		//		false: skip the header row, won't call afterHeader.
+		// returns:
+		//		- true: go on handling the header row and then call afterHeader.
+		//		- false: skip the header row, won't call afterHeader.
 		return true;	//Boolean
 	},
 	afterHeader: function(){
@@ -121,9 +125,9 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		//		protected extension
 		// items:
 		//		All the items fetched from the store
-		// return:
-		//		true: go on handling the contents and then call afterContent.
-		//		false: skip all the contents, won't call afterContent.
+		// returns:
+		//		- true: go on handling the contents and then call afterContent.
+		//		- false: skip all the contents, won't call afterContent.
 		return true;	//Boolean
 	},
 	afterContent: function(){
@@ -142,14 +146,14 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		//		protected extension
 		// argObj:
 		//		An object with at least the following context properties available:
-		//		{
-		//			grid,isHeader,
-		//			row,rowIdx,
-		//			spCols
-		//		}
-		// return:
-		//		true: go on handling the current data row and then call afterContentRow.
-		//		false: skip the current data row, won't call afterContentRow.
+		// |	{
+		// |		grid,isHeader,
+		// |		row,rowIdx,
+		// |		spCols
+		// |	}
+		// returns:
+		//		- true: go on handling the current data row and then call afterContentRow.
+		//		- false: skip the current data row, won't call afterContentRow.
 		return true;	//Boolean
 	},
 	afterContentRow: function(/* object */argObj){
@@ -159,11 +163,11 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		//		protected extension
 		// argObj:
 		//		An object with at least the following context properties available:
-		//		{
-		//			grid,isHeader,
-		//			row,rowIdx,
-		//			spCols
-		//		}
+		// |	{
+		// |		grid,isHeader,
+		// |		row,rowIdx,
+		// |		spCols
+		// |	}
 		// returns:
 		//		undefined
 	},
@@ -174,14 +178,14 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		//		protected extension
 		// argObj:
 		//		An object with at least the following context properties available:
-		//		{
-		//			grid,isHeader,
-		//			view,viewIdx,
-		//			spCols(if isHeader==false)
-		//		}
-		// return:
-		//		true: go on handling the current view and then call afterView.
-		//		false: skip the current view, won't call afterView.
+		// |	{
+		// |		grid,isHeader,
+		// |		view,viewIdx,
+		// |		spCols(if isHeader==false)
+		// |	}
+		// returns:
+		//		- true: go on handling the current view and then call afterView.
+		//		- false: skip the current view, won't call afterView.
 		return true;	//Boolean
 	},
 	afterView: function(/* object */argObj){
@@ -191,11 +195,11 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		//		protected extension
 		// argObj:
 		//		An object with at least the following context properties available:
-		//		{
-		//			grid,isHeader,
-		//			view,viewIdx,
-		//			spCols(if isHeader==false)
-		//		}
+		// |	{
+		// |		grid,isHeader,
+		// |		view,viewIdx,
+		// |		spCols(if isHeader==false)
+		// |	}
 		// tags:
 		//		protected extension
 		// returns:
@@ -208,16 +212,16 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		//		protected extension
 		// argObj:
 		//		An object with at least the following context properties available:
-		//		{
-		//			grid,isHeader,
-		//			row,rowIdx,
-		//			view,viewIdx,
-		//			subrow,subrowIdx,
-		//			spCols(if isHeader==false)
-		//		}
-		// return:
-		//		true: go on handling the current subrow and then call afterSubrow.
-		//		false: skip the current subrow, won't call afterSubrow.
+		// |	{
+		// |		grid,isHeader,
+		// |		row,rowIdx,
+		// |		view,viewIdx,
+		// |		subrow,subrowIdx,
+		// |		spCols(if isHeader==false)
+		// |	}
+		// returns:
+		//		- true: go on handling the current subrow and then call afterSubrow.
+		//		- false: skip the current subrow, won't call afterSubrow.
 		return true;	//Boolean
 	},
 	afterSubrow: function(/* object */argObj){
@@ -227,13 +231,13 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		//		protected extension
 		// argObj:
 		//		An object with at least the following context properties available:
-		//		{
-		//			grid,isHeader,
-		//			row,rowIdx,
-		//			view,viewIdx,
-		//			subrow,subrowIdx,
-		//			spCols(if isHeader==false)
-		//		}
+		// |	{
+		// |		grid,isHeader,
+		// |		row,rowIdx,
+		// |		view,viewIdx,
+		// |		subrow,subrowIdx,
+		// |		spCols(if isHeader==false)
+		// |	}
 		// returns:
 		//		undefined
 	},
@@ -244,14 +248,14 @@ return declare("dojox.grid.enhanced.plugins.exporter._ExportWriter", null, {
 		//		protected extension
 		// argObj:
 		//		An object with at least the following context properties available:
-		//		{
-		//			grid,isHeader,
-		//			row,rowIdx,
-		//			view,viewIdx,
-		//			subrow,subrowIdx,
-		//			cell,cellIdx,
-		//			spCols(if isHeader==false)
-		//		}
+		// |	{
+		// |		grid,isHeader,
+		// |		row,rowIdx,
+		// |		view,viewIdx,
+		// |		subrow,subrowIdx,
+		// |		cell,cellIdx,
+		// |		spCols(if isHeader==false)
+		// |	}
 		// returns:
 		//		undefined
 	},
diff --git a/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js b/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
index 0eadec9..dee367c 100644
--- a/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
+++ b/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
@@ -1,16 +1,16 @@
 define([
 	"dojo/_base/declare",
-	"dojo/cache",
 	"dijit/_Widget",
 	"dijit/_TemplatedMixin",
-	"dijit/_WidgetsInTemplateMixin"
-], function(declare, cache, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin){
+	"dijit/_WidgetsInTemplateMixin",
+	"dojo/text!../../templates/ClearFilterConfirmPane.html"
+], function(declare, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, template){
 
 return declare("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm",
 	[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
 	// summary:
 	//		The UI for user to confirm the operation of clearing filter.
-	templateString: cache("dojox.grid", "enhanced/templates/ClearFilterConfirmPane.html"),
+	templateString: template,
 
 	widgetsInTemplate: true,
 
diff --git a/dojox/grid/enhanced/plugins/filter/FilterBar.js b/dojox/grid/enhanced/plugins/filter/FilterBar.js
index 2987321..596b231 100644
--- a/dojox/grid/enhanced/plugins/filter/FilterBar.js
+++ b/dojox/grid/enhanced/plugins/filter/FilterBar.js
@@ -7,7 +7,6 @@ define([
 	"dojo/_base/event",
 	"dojo/_base/html",
 	"dojo/_base/window",
-	"dojo/cache",
 	"dojo/query",
 	"dijit/_Widget",
 	"dijit/_TemplatedMixin",
@@ -15,8 +14,10 @@ define([
 	"dojo/fx",
 	"dojo/_base/fx",
 	"dojo/string",
-	"dijit/focus"
-], function(declare, array, connect, lang, has, event, html, win, cache, query, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, fx, baseFx, string, dijitFocus){
+	"dijit/focus",
+	"dojo/text!../../templates/FilterBar.html"
+], function(declare, array, connect, lang, has, event, html, win, query, _Widget,
+	_TemplatedMixin, _WidgetsInTemplateMixin, fx, baseFx, string, dijitFocus, template){
 
 var _focusClass = "dojoxGridFBarHover",
 	_filteredClass = "dojoxGridFBarFiltered",
@@ -31,7 +32,7 @@ var _focusClass = "dojoxGridFBarHover",
 return declare("dojox.grid.enhanced.plugins.filter.FilterBar", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{
 	// summary:
 	//		The filter bar UI.
-	templateString: cache("dojox.grid","enhanced/templates/FilterBar.html"),
+	templateString: template,
 
 	widgetsInTemplate: true,
 	
@@ -353,7 +354,9 @@ return declare("dojox.grid.enhanced.plugins.filter.FilterBar", [_Widget, _Templa
 	},
 	_showStatusTooltip: function(){
 		this._handle_statusTooltip = null;
-		this.plugin.filterStatusTip.showDialog(this._tippos.x, this._tippos.y, this.getColumnIdx(this._tippos.x));
+		if(this.plugin){
+			this.plugin.filterStatusTip.showDialog(this._tippos.x, this._tippos.y, this.getColumnIdx(this._tippos.x));
+		}
 	},
 	_highlightHeader: function(/* int */colIdx){
 		if(colIdx != this._previousHeaderIdx){
diff --git a/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js b/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
index 35da5f2..e48f094 100644
--- a/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
+++ b/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
@@ -6,7 +6,6 @@ define([
 	"dojo/_base/event",
 	"dojo/_base/html",
 	"dojo/_base/sniff",
-	"dojo/cache",
 	"dojo/keys",
 	"dojo/string",
 	"dojo/window",
@@ -27,14 +26,18 @@ define([
 	"dijit/focus",
 	"dojox/html/metrics",
 	"dijit/a11y",
+	"dojo/text!../../templates/FilterDefPane.html",
+	"dojo/text!../../templates/CriteriaBox.html",
+	"dojo/text!../../templates/FilterBoolValueBox.html",	
 	"dijit/Tooltip",
 	"dijit/form/Select",
 	"dijit/form/RadioButton",
 	"dojox/html/ellipsis",
 	"../../../cells/dijit"
-], function(declare, array, connect, lang, event, html, has, cache, keys, string, win, dateLocale, 
+], function(declare, array, connect, lang, event, html, has, keys, string, win, dateLocale, 
 	FilterBuilder, Dialog, ComboBox, TextBox, NumberTextBox, DateTextBox, TimeTextBox, Button, 
-	AccordionContainer, ContentPane, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, dijitFocus, metrics, dijitA11y){
+	AccordionContainer, ContentPane, _Widget, _TemplatedMixin, _WidgetsInTemplateMixin, dijitFocus,
+	metrics, dijitA11y, defPaneTemplate, criteriaTemplate, boolValueTemplate){
 		
 var _tabIdxes = {
 		// summary:
@@ -93,7 +96,7 @@ var FilterAccordionContainer = declare("dojox.grid.enhanced.plugins.filter.Accor
 		if(parseInt(has('ie'), 10) == 7){
 			//IE7 will fire a lot of "onresize" event during initialization.
 			array.some(this._connects, function(cnnt){
-				if(cnnt[0][1] == "onresize"){
+				if((cnnt[0] || {})[1] == "onresize"){
 					this.disconnect(cnnt);
 					return true;
 				}
@@ -200,7 +203,7 @@ var FilterAccordionContainer = declare("dojox.grid.enhanced.plugins.filter.Accor
 	}
 });
 var FilterDefPane = declare("dojox.grid.enhanced.plugins.filter.FilterDefPane",[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{
-	templateString: cache("dojox.grid","enhanced/templates/FilterDefPane.html"),
+	templateString: defPaneTemplate,
 	widgetsInTemplate: true,
 	dlg: null,
 	postMixInProperties: function(){
@@ -265,7 +268,7 @@ var FilterDefPane = declare("dojox.grid.enhanced.plugins.filter.FilterDefPane",[
 	}
 });
 var CriteriaBox = declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin],{
-	templateString: cache("dojox.grid","enhanced/templates/CriteriaBox.html"),
+	templateString: criteriaTemplate,
 	widgetsInTemplate: true,
 	dlg: null,
 	postMixInProperties: function(){
@@ -293,6 +296,11 @@ var CriteriaBox = declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[_Wid
 		this._showSelectOrLabel(this._condSelect, this._condSelectAlt);
 		
 		this.connect(g.layout, "moveColumn", "onMoveColumn");
+		var _this = this;
+		setTimeout(function(){
+			var type = dlg.getColumnType(dlg.curColIdx);
+			_this._setValueBoxByType(type);
+		}, 0);
 	},
 	_getColumnOptions: function(){
 		var colIdx = this.dlg.curColIdx >= 0 ? String(this.dlg.curColIdx) : "anycolumn";
@@ -467,14 +475,15 @@ var CriteriaBox = declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[_Wid
 		if(obj.column){
 			this._colSelect.set("value", obj.column);
 		}
-		if(obj.condition){
-			this._condSelect.set("value", obj.condition);
-		}
 		if(obj.type){
+			this._setConditionsByType(obj.type);
 			this._setValueBoxByType(obj.type);
 		}else{
 			obj.type = this.dlg.getColumnType(this._colSelect.get("value"));
 		}
+		if(obj.condition){
+			this._condSelect.set("value", obj.condition);
+		}
 		var value = obj.value || "";
 		if(value || (obj.type != "date" && obj.type != "time")){
 			this._curValueBox.set("value", value);
@@ -596,7 +605,7 @@ var CriteriaBox = declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[_Wid
 		this.valueNode.appendChild(this._curValueBox.domNode);
 		
 		//Can not move to setAriaInfo, 'cause the value box is created after the defpane is loaded.
-		this._curValueBox.domNode.setAttribute("aria-label", string.substitute(this.plugin.nls.waiValueBoxTemplate,[this._index]));
+		this._curValueBox.focusNode.setAttribute("aria-label", string.substitute(this.plugin.nls.waiValueBoxTemplate,[this._index]));
 		//Now our cbox is completely ready
 		this.dlg.onRendered(this);
 	},
@@ -611,21 +620,24 @@ var CriteriaBox = declare("dojox.grid.enhanced.plugins.filter.CriteriaBox",[_Wid
 			};
 		if(type == "string"){
 			if(cell && (cell.suggestion || cell.autoComplete)){
-				html.mixin(res, {
+				lang.mixin(res, {
 					store: g.store,
 					searchAttr: cell.field || cell.name,
+					query: g.query || {},
 					fetchProperties: {
 						sort: [{"attribute": cell.field || cell.name}],
-						query: g.query,
-						queryOptions: g.queryOptions
+						queryOptions: lang.mixin({
+							ignoreCase: true,
+							deep: true
+						}, g.queryOptions || {})
 					}
 				});
 			}
 		}else if(type == "boolean"){
-			html.mixin(res, this.dlg.builder.defaultArgs["boolean"]);
+			lang.mixin(res, this.dlg.builder.defaultArgs["boolean"]);
 		}
 		if(cell && cell.dataTypeArgs){
-			html.mixin(res, cell.dataTypeArgs);
+			lang.mixin(res, cell.dataTypeArgs);
 		}
 		return res;
 	},
@@ -676,7 +688,7 @@ var UniqueComboBox = declare("dojox.grid.enhanced.plugins.filter.UniqueComboBox"
 	}
 });
 var BooleanValueBox = declare("dojox.grid.enhanced.plugins.filter.BooleanValueBox", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
-	templateString: cache("dojox.grid","enhanced/templates/FilterBoolValueBox.html"),
+	templateString: boolValueTemplate,
 	widgetsInTemplate: true,
 	constructor: function(args){
 		var nls = args.cbox.plugin.nls;
diff --git a/dojox/grid/enhanced/plugins/filter/FilterLayer.js b/dojox/grid/enhanced/plugins/filter/FilterLayer.js
index bfc8281..797c827 100644
--- a/dojox/grid/enhanced/plugins/filter/FilterLayer.js
+++ b/dojox/grid/enhanced/plugins/filter/FilterLayer.js
@@ -1,15 +1,15 @@
 define([
 	"dojo/_base/declare",
 	"dojo/_base/lang",
-	"dojo/_base/window",
+	"dojo/_base/kernel",
 	"dojo/_base/json",
 	"../_StoreLayer"
-], function(declare, lang, win, json, layers){
+], function(declare, lang, kernel, json, layers){
 
 	var cmdSetFilter = "filter",
 		cmdClearFilter = "clear",
 		hitchIfCan = function(scope, func){
-			return func ? lang.hitch(scope || win.global, func) : function(){};
+			return func ? lang.hitch(scope || kernel.global, func) : function(){};
 		},
 		shallowClone = function(obj){
 			var res = {};
@@ -32,8 +32,8 @@ define([
 			// tags:
 			//		public
 			// filter: (_ConditionExpr|null)?
-			//		null: clear filter definition
-			//		undefined: it's getter
+			//		- null: clear filter definition
+			//		- undefined: it's getter
 			// returns:
 			//		A filter definition if it's getter.
 		},
@@ -127,23 +127,23 @@ define([
 		//		Add a client side filter layer on top of the data store,
 		//		so any filter expression can be applied to the store.
 /*=====
-		//_items: Array,
+		// _items: Array,
 		//		Cached items (may contain holes)
 		_items: [],
 		
-		//_result: Array,
+		// _result: Array,
 		//		Current fetch result
 		_result: [],
-		
-		//_resultStartIdx: Integer,
+
+		// _resultStartIdx: Integer,
 		//		The index in cache of the first result item
 		_resultStartIdx: 0,
 		
-		//_indexMap: Array,
+		// _indexMap: Array,
 		//		A map from the row index of this._items to the row index of the original store.
 		_indexMap: null,
 		
-		//_getter: function(datarow, colArg, rowIndex, store);
+		// _getter: function(datarow, colArg, rowIndex, store);
 		//		A user defined way to get data from store
 		_getter: null,
 		
@@ -220,7 +220,7 @@ define([
 			//		Implement _StoreLayer._fetch
 			// tags:
 			//		private callback
-			// filterRequest: dojo.data.api.Request
+			// filterRequest: dojo/data/api/Request
 			//		The actual request used in store.fetch.
 			//		This function is called recursively to fill the result store items
 			//		until the user specified item count is reached. Only in recursive calls,
diff --git a/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js b/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
index 6d8efb3..05c8712 100644
--- a/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
+++ b/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
@@ -3,7 +3,6 @@ define([
 	"dojo/_base/array",
 	"dojo/_base/lang",
 	"dojo/query",
-	"dojo/cache",
 	"dojo/string",
 	"dojo/date/locale",
 	"dijit/_Widget", 
@@ -12,9 +11,10 @@ define([
 	"dijit/TooltipDialog",
 	"dijit/form/Button",
 	"dijit/_base/popup",
+	"dojo/text!../../templates/FilterStatusPane.html",
 	"dojo/i18n!../../nls/Filter"
-], function(declare, array, lang, query, cache, string, dateLocale, _Widget, 
-	_TemplatedMixin, _WidgetsInTemplateMixin, TooltipDialog, Button, popup){
+], function(declare, array, lang, query, string, dateLocale, _Widget, 
+	_TemplatedMixin, _WidgetsInTemplateMixin, TooltipDialog, Button, popup, template){
 
 	var gridCssCls = "", headerCssCls = "", cellCssCls = "", rowCssCls = "",
 		oddRowCssCls = "dojoxGridFStatusTipOddRow",
@@ -24,7 +24,7 @@ define([
 		_statusFooter = "</tbody></table>";
 
 	var FilterStatusPane = declare("dojox.grid.enhanced.plugins.filter.FilterStatusPane", [_Widget, _TemplatedMixin], {
-		templateString: cache("dojox.grid", "enhanced/templates/FilterStatusPane.html")
+		templateString: template
 	});
 
 	return declare("dojox.grid.enhanced.plugins.filter.FilterStatusTip", null, {
@@ -42,7 +42,7 @@ define([
 			this._rules = [];
 			this.statusPane = new FilterStatusPane();
 			this._dlg = new TooltipDialog({
-				"class": "dojoxGridFStatusTipDialog",
+				"class": "dijitTooltipBelow dojoxGridFStatusTipDialog",
 				content: this.statusPane,
 				autofocus: false
 			});
@@ -141,7 +141,4 @@ define([
 			p.filterDefDialog.showDialog(p.filterBar.getColumnIdx(this._pos.x));
 		}
 	});
-	
-
-	return FilterStatusTip;
 });
diff --git a/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js b/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
index 0fb3b6b..c5b08ac 100644
--- a/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
+++ b/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
@@ -60,9 +60,8 @@ var _DataExpr = declare("dojox.grid.enhanced.plugins.filter._DataExpr", _Conditi
 	//		this _DataExpr is nothing more than a simple wrapper.
 	//		If the data value to be represent is in a store, then _DataExpr is responsible to extract it
 	//		from the store when this condition is applied to a data row.
-	// private fields:
-	//		_value: anything
-	//		_colArg: anything
+	// _value: [private] anything
+	// _colArg: [private] anything
 	_name: "data",
 
 	constructor: function(/* anything */dataValue,/* bool */isColumn, /* object */convertArgs){
@@ -112,13 +111,10 @@ var _DataExpr = declare("dojox.grid.enhanced.plugins.filter._DataExpr", _Conditi
 	},
 
 	_convertData: function(/* anything */dataValue){
-		// summary:
-		//
 		// tags:
 		//		protected extension
 		// dataValue: anything
 		//		This argument should come from a store.
-		// returns:
 		return dataValue;
 	},
 
@@ -139,7 +135,7 @@ var _OperatorExpr = declare("dojox.grid.enhanced.plugins.filter._OperatorExpr",
 	//		An operator expression is a _ConditionExpr that represents an operation.
 	_name: "operator",
 
-	constructor: function(/* Array | operand1,operand2,... */){
+	constructor: function(/* Array|operand1,operand2,... */){
 		// summary:
 		//		The arguments are operands (or an array of operands, if the first argument
 		//		is an Array) of this operator, ordering from left to right.
diff --git a/dojox/grid/enhanced/resources/EnhancedGrid.css b/dojox/grid/enhanced/resources/EnhancedGrid.css
index 7f02773..e592840 100644
--- a/dojox/grid/enhanced/resources/EnhancedGrid.css
+++ b/dojox/grid/enhanced/resources/EnhancedGrid.css
@@ -3,6 +3,5 @@
 @import url("Pagination.css");
 @import url("DnD.css");
 @import url("Sorter.css");
- at import url("../../../widget/Toaster/Toaster.css");
 @import url("../../../html/resources/ellipsis.css");
 
diff --git a/dojox/grid/enhanced/templates/FilterBar.html b/dojox/grid/enhanced/templates/FilterBar.html
index cbcb68d..db60d29 100644
--- a/dojox/grid/enhanced/templates/FilterBar.html
+++ b/dojox/grid/enhanced/templates/FilterBar.html
@@ -1,4 +1,4 @@
-<table class="dojoxGridFBar" border="0" cellspacing="0" dojoAttachEvent="onclick:_onClickFilterBar, onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave, onmousemove:_onMouseMove"
+<table class="dojoxGridFBar" border="0" cellspacing="0" role="presentation" dojoAttachEvent="onclick:_onClickFilterBar, onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave, onmousemove:_onMouseMove"
 	><tr><td class="dojoxGridFBarBtnTD"
 		><span dojoType="dijit.form.Button" class="dojoxGridFBarBtn" dojoAttachPoint="defineFilterButton" label="..." iconClass="dojoxGridFBarDefFilterBtnIcon" showLabel="true" dojoAttachEvent="onClick:_showFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span
 	></td><td class="dojoxGridFBarInfoTD"
diff --git a/dojox/grid/resources/Grid.css b/dojox/grid/resources/Grid.css
index 037d906..383b06d 100644
--- a/dojox/grid/resources/Grid.css
+++ b/dojox/grid/resources/Grid.css
@@ -218,13 +218,21 @@
 
 /* cells */
 
-.dojoxGridCell {
+.dojoxGrid .dojoxGridCell {
 	border: 1px solid;
 	border-color: #EBEADB;
 	border-right-color: #D5CDB5;
 	padding: 3px 3px 3px 3px;
 	text-align: left;
 	overflow: hidden;
+	word-wrap: break-word;
+}
+
+.dojoxGrid .dojoxGridFixedRowHeight .dojoxGridCell {
+	white-space: nowrap;
+	word-break: keep-all;
+	word-wrap: normal;
+	text-overflow: ellipsis;
 }
 
 .dojoxGridCellFocus {
@@ -288,6 +296,11 @@
 }
 
 /* Drag and Drop */
+.dojoxGridRowTable .dojoDndHorizontal th.dojoDndItem {
+	display: table-cell;
+	/* overwrite margin/padding setting from dijit.css */
+	margin: 0;
+}
 .dojoxGridDndAvatar {
 	font-size: 100%;
 }
@@ -412,4 +425,4 @@
 .dojoxGridNoChildren .dojoxGridExpando {
 	visibility: hidden !important;
 	width: 0px !important;
-}
\ No newline at end of file
+}
diff --git a/dojox/grid/resources/Grid_rtl.css b/dojox/grid/resources/Grid_rtl.css
index 77d2dd5..0c82115 100644
--- a/dojox/grid/resources/Grid_rtl.css
+++ b/dojox/grid/resources/Grid_rtl.css
@@ -10,6 +10,10 @@
 	border-left: none;
 }
 
+.dj_ie .dojoxGridRtl .dojoxGridMasterView .dojoxGridRowTable {
+	border-left: #e5dac8 1px solid
+}
+
 .dojoxGridRtl .dojoxGridArrowButtonNode {
 	float:left;
 }
\ No newline at end of file
diff --git a/dojox/grid/resources/claroGrid.css b/dojox/grid/resources/claroGrid.css
index f15ff84..4d58ddf 100644
--- a/dojox/grid/resources/claroGrid.css
+++ b/dojox/grid/resources/claroGrid.css
@@ -1,5 +1,6 @@
 /* Claro styles for DataGrid */
 @import url("Grid.css");
+ at import url("Grid_rtl.css");
 
 .claro .dojoxGrid {
 	margin:0px;
@@ -94,6 +95,11 @@
 .dj_ie .claro .dojoxGridHeader .dojoxGridRowTable {
 	border-collapse:separate;
 }
+.dj_ie6 .claro .dojoxGridHeader .dojoxGridRowTable,
+.dj_ie7 .claro .dojoxGridHeader .dojoxGridRowTable {
+	border-collapse:collapse;
+	border-right: 0px;	
+}
 .claro .dojoxGridHeader .dojoxGridRowTable tr {
 	background: none;
 }
@@ -144,6 +150,10 @@
 .dj_ie .claro .dojoxGridMasterView .dojoxGridRowTable {
 	border-collapse:separate;/*IE, separate is must to show the border of tr and td*/
 }
+.dj_ie6 .claro .dojoxGridMasterView .dojoxGridRowTable,
+.dj_ie7 .claro .dojoxGridMasterView .dojoxGridRowTable {
+	border-collapse: collapse;
+}
 .claro .dojoxGridRowTable tr {
 	background:url("images/row_back.png") #fff repeat-x;
 }
@@ -155,13 +165,16 @@
 }
 
 /* cells */
-.claro .dojoxGridCell {
+.claro .dojoxGrid .dojoxGridCell {
 	outline: none;
 	padding: 3px 5px;
-	word-wrap: break-word;
 	border:1px solid transparent;
 	border-color: transparent #E5DAC8 #E5DAC8 transparent;
 }
+.dj_ie7 .claro .dojoxGridCell,
+.dj_ie7 .claro .dojoxGridHeader .dojoxGridCell {
+	border-left: 0px;
+}
 .dj_ie6 .claro .dojoxGridCell {
 	border-color: #F5F5F5;
 }
@@ -190,7 +203,6 @@
 }
 .dj_ie6 .claro .dojoxGridRowOver .dojoxGridCell,
 .dj_ie7 .claro .dojoxGridRowOver .dojoxGridCell {
-	border-left:1px solid #ABD6FF;
 	border-right:1px solid #ABD6FF;
 }
 .claro .dojoxGridRowActive .dojoxGridCell {
diff --git a/dojox/grid/resources/nihiloGrid.css b/dojox/grid/resources/nihiloGrid.css
index 4fc1bcc..6caf18c 100644
--- a/dojox/grid/resources/nihiloGrid.css
+++ b/dojox/grid/resources/nihiloGrid.css
@@ -1,4 +1,5 @@
 @import url("Grid.css");
+ at import url("Grid_rtl.css");
 
 .nihilo .dojoxGrid {
 	background-color: #e9e9e9;
@@ -235,3 +236,8 @@
 .nihilo .dojoxGridRowOdd .dojoxGridSubRowAlt {
 	background-color: #EDEFF3;
 }
+
+.nihilo .dojoxGridRowTable .dojoDndHorizontal th.dojoDndItem {
+	padding: 3px;
+}
+
diff --git a/dojox/grid/resources/soriaGrid.css b/dojox/grid/resources/soriaGrid.css
index 330ddf3..20f1c26 100644
--- a/dojox/grid/resources/soriaGrid.css
+++ b/dojox/grid/resources/soriaGrid.css
@@ -1,4 +1,5 @@
 @import url("Grid.css");
+ at import url("Grid_rtl.css");
 
 .soria .dojoxGrid {
 	background-color: #e9e9e9;
@@ -243,3 +244,7 @@
 .soria .dojoxGridRowOdd .dojoxGridSubRowAlt {
 	background-color: #EDEFF3;
 }
+
+.soria .dojoxGridRowTable .dojoDndHorizontal th.dojoDndItem {
+	padding: 3px;
+}
diff --git a/dojox/grid/resources/tundraGrid.css b/dojox/grid/resources/tundraGrid.css
index 18ba271..98bde41 100644
--- a/dojox/grid/resources/tundraGrid.css
+++ b/dojox/grid/resources/tundraGrid.css
@@ -1,4 +1,5 @@
 @import url("Grid.css");
+ at import url("Grid_rtl.css");
 
 .tundra .dojoxGrid {
 	background-color: #e9e9e9;
@@ -199,6 +200,9 @@
 
 /* Drag and Drop */
 
+.tundra .dojoxGridRowTable .dojoDndHorizontal th.dojoDndItem {
+	padding: 3px;
+}
 .tundra .dojoxGrid .dojoDndItemBefore {
 	border-left-color: #3559ac;
 }
diff --git a/dojox/grid/tests/bidi/test_edit_dijit.html b/dojox/grid/tests/bidi/test_edit_dijit.html
new file mode 100644
index 0000000..1b3d078
--- /dev/null
+++ b/dojox/grid/tests/bidi/test_edit_dijit.html
@@ -0,0 +1,127 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title>Grid Edit Controls Bidi Test</title>
+	<style type="text/css">
+		@import "../../resources/Grid.css";
+		@import "../../resources/tundraGrid.css";
+		@import "../../../../dojo/resources/dojo.css";
+		@import "../../../../dijit/themes/tundra/tundra.css";
+		@import "../../../../dijit/themes/tundra/tundra_rtl.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+		#controls button {
+			margin-left: 10px;
+		}
+		#grid {
+			width: 450px;
+			height: 150px;
+			border: 1px solid silver;
+		}
+		</style>
+
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true, has: {'dojo-bidi': true}"></script>
+	
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"doh/runner",
+			"dojo/dom",
+			"dojo/query",
+			"dojo/data/ItemFileWriteStore",
+			"dojo/parser",			
+			"dojox/grid/cells/dijit",
+			"dijit/form/ComboBox"
+		], function(ready, registry, runner, dom, query, ItemFileWriteStore){
+			data = {identifier: 'id',label: 'id',items: []};
+			data_list = [
+				{ col1: "First!", col2: "First!", col3: "First!", col4: "First!"},
+				{ col1: "Second!", col2: "Second!", col3: "Second!", col4: "Second!"},
+				{ col1: "Third!", col2: "Third!", col3: "Third!", col4: "Third!"},
+				{ col1: "Forth!", col2: "Forth!", col3: "Forth!", col4: "Forth!"}
+			];
+			for(var i=0; i < 4; i++){
+				data.items.push(dojo.mixin({ id: i }, data_list[i]));
+			}
+			test_store = new ItemFileWriteStore({data: data});	
+			gridLayout = [{
+				defaultCell: { width: 8, editable: true, alwaysEditing: true, type: dojox.grid.cells._Widget, styles: 'text-align: right;'  },
+				rows: [
+					{ name: 'Input!', field: 'col1'},
+					{ name: 'grid.cells.ComboBox!', styles: 'text-align: center;', field: 'col2', 
+						type: dojox.grid.cells.ComboBox,
+						options: ["First!", "Second!", "Third!", "Forth!"], width: 10},
+					{ name: 'grid.cells.Select!', field: 'col3', styles: 'text-align: center;', 
+						type: dojox.grid.cells.Select, options: [ "First!", "Second!", "Third!", "Forth!"]},
+					{ name: 'dijit.form.Combo!', field: 'col4',
+						widgetClass: dijit.form.ComboBox, width: 10}
+				]
+			}];
+		
+			ready(function(){	
+				runner.register("grid.tests.bidi.test_EditControls", [
+					{
+						name: "Grid EditControls, Bidi",						
+						runTest: function(){
+							query("th.dojoxGridCell").forEach(function(node, index, arr){
+								runner.is("rtl", node.style.direction, "header should have 'direction' style corresponding to 'textDir'");							
+							});						
+							var element = registry.byId('dijit_form_TextBox_0');
+							if(element) {					
+								runner.is("rtl", element.get("textDir"), "widget 'textDir' property should coinside with that of grid");
+							}							
+							element = registry.byId('dijit_form_ComboBox_0');
+							if(element) {							
+								runner.is("rtl", element.get("textDir"), "widget 'textDir' property should coinside with that of grid");
+							}
+							element = registry.byId('dijit_form_ComboBox_1');
+							if(element) {
+								runner.is("rtl", element.get("textDir"), "widget 'textDir' property should coinside with that of grid");
+							}								
+						}					
+					}
+				]);					
+
+				runner.register("log", function(){
+					dom.byId('failures').innerHTML = runner._failureCount;
+					dom.byId('errors').innerHTML = runner._errorCount;
+				});
+				setTimeout(function(){runner.run();},2000);				
+			});	
+		},				
+		addRow = function(){		
+			test_store.newItem({
+				id: dijit.registry.byId("grid").rowCount,
+				col1: 'new!',
+				col2: 'new!',
+				col3: 'new!',
+				col4: 'new!'
+			});
+		},
+		toggleAlwaysEditing = function(){
+			var grid = dijit.registry.byId("grid");
+			gridLayout[0].defaultCell.alwaysEditing = !gridLayout[0].defaultCell.alwaysEditing;
+			grid.set('structure', gridLayout);
+		}		
+		);	
+	</script>
+</head>
+<body class="tundra">
+	<h1>Grid Edit Controls Bidi Test</h1>
+    <br />
+	<div id="controls">
+	<button dojoType="dijit.form.Button" onclick="addRow()">Add Row</button>
+	<button dojoType="dijit.form.Button" onclick="toggleAlwaysEditing()">Toggle 'alwaysEditing'</button>	
+	</div>	
+    <br />	
+	<div id="grid" data-dojo-id="grid" data-dojo-type="dojox/grid/DataGrid"
+		data-dojo-props='textDir: "rtl", store:test_store, rowSelector:"20px", structure:gridLayout, escapeHTMLInData:"false" ' ></div>
+	<br />
+	<div id="rowCount"></div>
+
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>		
+</body>
+</html>
diff --git a/dojox/grid/tests/bidi/test_styling.html b/dojox/grid/tests/bidi/test_styling.html
new file mode 100644
index 0000000..dcf07ed
--- /dev/null
+++ b/dojox/grid/tests/bidi/test_styling.html
@@ -0,0 +1,164 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>RTL Grid Bidi Test</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<style type="text/css">
+		@import "../../resources/Grid.css";
+		@import "../../resources/Grid_rtl.css";		
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+		}
+		.heading {
+			font-weight: bold;
+			padding-bottom: 0.25em;
+		}
+				
+		#grid { 
+			border: 1px solid #333;
+			width: 43em;
+			height: 30em;
+		}
+		
+		#grid .dojoxGridRow {
+			border: none;
+		}
+		
+		#grid .dojoxGridRowTable {
+			border-collapse: collapse;
+		}
+		
+		#grid .dojoxGridCell {
+			border: 1px solid #333;
+			padding: 10px;
+		}
+		
+		.selectedRow .dojoxGridCell {
+			background-color: #003366;
+			color: white;
+		}
+		
+		.specialRow .dojoxGridCell {
+			background-color: dimgray;
+		}
+		
+		.selectedRow.specialRow .dojoxGridCell {
+			text-decoration: line-through;
+			/* duplicate selection background-color so has precendence over specialRow background-color */
+			background-color: #003366;
+		}
+		
+		/* in the yellow column, assign specific decoration for special rows that are selected */
+		.selectedRow.specialRow .yellowColumnData {
+			text-decoration: line-through underline;
+		}		
+		.yellowColumn {
+			color: #006666;
+		}		
+		.overRow .dojoxGridCell {
+			text-decoration: underline;
+		}	
+		.greenColumn {
+			color: yellow;
+			background-color: #006666;
+			font-style: italic;
+		}	
+		.yellowColumnData {
+			background-color: yellow;
+			text-decoration: underline;
+		}
+		.redColumnData {
+			color: blue;		
+			background-color: pink;
+			text-decoration: underline;
+		}		
+	</style>
+	
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config = "async: true, parseOnLoad: true, has: {'dojo-bidi': true}"></script>
+	
+	<script type="text/javascript">		
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"doh/runner",
+			"dojo/dom",
+			"dojo/query",
+			"dojo/data/ItemFileWriteStore",
+			"dojox/grid/DataGrid",
+			"dojo/parser",			
+			"dojox/grid/cells/dijit"
+		], function(ready, registry, runner, dom, query, ItemFileWriteStore){		
+			ready(function(){
+				data = {identifier: 'id',label: 'id',items: []};		
+				data_list = [
+					{ col1: "Hello note!", col2: "Hello note!", col3: "Hello note!", col4: 'To problems of corruption by!', col5: 9.12, col6: "Hello note!"},
+					{ col1: "\u05e9\u05dc\u05d5\u05dd note!", col2: "\u05e9\u05dc\u05d5\u05dd note!", col3: "\u05e9\u05dc\u05d5\u05dd note!", col4: 'Which would simply be awkward in!', col5: 12.15, col6: "\u05e9\u05dc\u05d5\u05dd!"}
+				];
+				for(var i=0; i < 60; i++){
+					data.items.push(dojo.mixin({ id: i }, data_list[i%2]));
+				}
+				test_store = new ItemFileWriteStore({data: data});		
+				var structure = [
+					{
+						noscroll: true,
+						cells: [
+							{name: 'Editable LTR!', editable: true, field: 'col1', textDir: 'ltr', width: 6, headerStyles: 'padding-bottom: 2px;', styles: 'border-bottom: 1px dashed #333; border-right: 1px dashed #333; padding: 6px;'},
+							{name: 'Editable RTL!', editable: true, field: 'col2', width: 6, headerStyles: 'padding-bottom: 2px;', styles: 'border-bottom: 1px dashed #333; border-right: 1px dashed #333; padding: 6px;'}
+						]
+					},
+					[
+						{name: 'Editable Auto!', editable: true, field: 'col3', cellClasses: 'redColumnData', textDir: 'auto'},
+						{name: 'Editable inherit!', editable: true, field: 'col4', headerStyles: 'background-image: none; background-color: #003333;', classes: 'greenColumn'},
+						{name: 'Read-only Align center!', field: 'col5', cellClasses: 'yellowColumnData', classes: 'yellowColumn', styles: 'text-align: center;' },
+						{name: 'RTL Select!', cellType: dojox.grid.cells.Select, editable: true, field: 'col6', options: ["Hello note!", "\u05e9\u05dc\u05d5\u05dd note!"]}
+					]
+				];
+				var grid = dijit.registry.byId("grid");
+				grid.setStore(test_store);
+				grid.set('structure', structure);
+
+				runner.register("grid.tests.bidi.test_styling", [
+					{
+						name: "Grid styles, Bidi",					
+						runTest: function(){
+							query(" .dojoxGridCell").forEach(function(node, index, arr){
+								switch(node.getAttribute("idx")){
+									case "0":
+										runner.is("ltr", node.style.direction, "cell node should have 'direction' style corresponding to 'textDir'");
+										break;					
+									case "1":
+									case "3":
+									case "4":
+									case "5":
+										runner.is("rtl", node.style.direction, "cell node should have 'direction' style corresponding to 'textDir'");
+								}
+							});									
+						}
+					}
+				]);
+				runner.register("log", function(){
+					dom.byId('failures').innerHTML = runner._failureCount;
+					dom.byId('errors').innerHTML = runner._errorCount;
+				});
+				runner.run();				
+			});
+		
+		},			
+		toggleGridTextDir = function(){
+			var grid = dijit.registry.byId("grid");
+			grid.set("textDir", (grid.get("textDir") === "rtl") ? "ltr" : "rtl");    
+		} );
+</script>
+</head>
+<body dir="rtl">
+    <input id="btn" type="button" onclick="toggleGridTextDir()" value="Toggle Grid TextDir"><br>	
+    <br />
+	<div class="heading">RTL Grid Bidi Test</div>
+	<div id="grid" data-dojo-id="grid" data-dojo-type="dojox/grid/DataGrid" data-dojo-props='textDir: "rtl" '></div>
+
+		<br>Errors: <span id="errors">?</span>
+		<br>Failures: <span id="failures">?</span>			
+</body>
+</html>
diff --git a/dojox/grid/tests/bidi/test_treegrid_lazyloading.html b/dojox/grid/tests/bidi/test_treegrid_lazyloading.html
new file mode 100644
index 0000000..c84edab
--- /dev/null
+++ b/dojox/grid/tests/bidi/test_treegrid_lazyloading.html
@@ -0,0 +1,134 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+	<head>
+        <title>dojox.grid.TreeGrid Lazy-loading for children items test</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+        <style type="text/css">
+            @import "../../../../dojo/resources/dojo.css";
+            @import "../../../../dijit/themes/claro/claro.css";
+            @import "../../../../dojox/grid/resources/Grid.css";
+	    @import "../../../../dojox/grid/resources/tundraGrid.css";
+            @import "../../../../dojox/grid/resources/claroGrid.css";
+            body {
+				font-size: 0.9em;
+				font-family: Geneva, Arial, Helvetica, sans-serif;
+				padding: 0.5em;
+			}
+			.title {
+				text-align:center;
+				margin:1em;
+			}
+			#grid1 {
+                width: 50em;
+                height: 15em;
+				border: 1px solid #333333;
+            }
+        </style>
+        <script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: {'dojo-bidi': true}, mblAlwaysHideAddressBar: true"></script>
+        <script type="text/javascript">            		
+		require([
+			"dojo/ready",
+			"doh/runner",
+			"dojo/dom",
+			"dojo/query",
+			"dojo/_base/lang",			
+			"dojo/data/ItemFileReadStore",
+			"dojox/grid/LazyTreeGridStoreModel",
+			"dojo/parser",			
+			"dojox/grid/cells/dijit",
+			"dijit/form/ComboBox"
+		], function(ready, runner, dom, query, lang, ItemFileReadStore, LazyTreeGridStoreModel){
+			var continentItems = [
+				{name:'South America!', type:'continent', population:''},
+				{name:'North America!', type:'continent', population:''},
+				{name:'Asia!', type:'continent', population:''},
+				{name:'Oceania!', type:'continent', population:''},
+				{name:'Europe!', type:'continent', population:''}
+			];
+			var continentChildrenList = [];
+			for(var i=0; i < continentItems.length; i++){
+				continentChildrenList.push(lang.mixin({ id: 'continent_' + i }, continentItems[i]));
+			}
+			
+			var countryItems = [
+				{name:'Egypt!', type:'country', population:''},
+				{name: 'Kenya!', type: 'country', population:''},
+				{name:'Sudan!', type:'country', population:''},
+				{name:'China!', type:'country' , population:''},
+		        {name:'India!', type:'country' , population:''}
+			];
+			
+			var countryChildrenList = [];
+			for(var i=0; i < countryItems.length; i++){
+				countryChildrenList.push(lang.mixin({ id: 'country_' + i }, countryItems[i]));
+			}
+			
+			cityItems = [
+				{name:'Nairobi!', type:'city', population:''},
+		        {name:'Mombasa!', type:'city', population:''},
+		        {name:'Khartoum!', type:'city', population:''},
+				{name:'Mexico City!', type:'city', population:'19 million.'},
+		        {name:'Guadalajara!', type:'city', population:'4 million.'}
+			];
+			
+			var cityChildrenList = [];
+			for(var i=0; i < cityItems.length; i++){
+				cityChildrenList.push(lang.mixin({ id: 'city_' + i }, cityItems[i]));
+			}
+
+			var dataItems = {
+				identifier: 'id',
+                label: 'name',
+				items: [
+					{id:'Continent', name:'Continent!', type:'', population: '', children: continentChildrenList},
+					{id:"Country", name:"Country!", type:"", population: '', children: countryChildrenList},
+					{id:"City", name:"City!", type:"", population: '', children: cityChildrenList}
+				]
+			};
+			
+			var readStore = new ItemFileReadStore({data: dataItems});
+			model1 = new LazyTreeGridStoreModel({store: readStore, childrenAttrs: ['children']})			
+			layout = [
+				{name: 'Name!', field: 'name', width: 'auto'},
+				{name: 'Type!', field: 'type', width: 'auto'},
+				{name: 'Population!', field: 'population', width: 'auto'}
+			]
+			
+			ready(function(){				
+				runner.register("grid.tests.bidi.test_LazyLoadTree", [
+					{
+						name: "Lazyload Tree Grid , Bidi",					
+						runTest: function(){
+							query("th.dojoxGridCell").forEach(function(node, index, arr){							
+								runner.is("rtl", node.style.direction, "header should have 'direction' style corresponding to 'textDir'");							
+							});
+
+							query("td.dojoxGridCell").forEach(function(node, index, arr){
+								if(node.lastChild && node.lastChild.tagName && 
+								node.lastChild.tagName.toUpperCase() === "DIV" && node.lastChild.lastChild 
+								&& node.lastChild.lastChild.nodeType === 3 && node.lastChild.lastChild.nodeValue) {								
+									runner.is(String.fromCharCode(8235), node.lastChild.lastChild.nodeValue.charAt(0), "content cell should have direction corresponding to 'textDir'");
+								}
+							});							
+						}
+					}
+				]);
+				runner.register("log", function(){
+					dom.byId('failures').innerHTML = runner._failureCount;
+					dom.byId('errors').innerHTML = runner._errorCount;
+				});
+				runner.run();
+			});				
+		});			
+        </script>
+    </head>
+    <body class="claro">
+        <h1 class="title">Bidi TreeGrid - Lazy-loading</h1>
+		<div id='grid1' data-dojo-id='grid1' data-dojo-type='dojox/grid/LazyTreeGrid'
+				data-dojo-props='textDir: "rtl", structure:layout, treeModel:model1, rowSelector:"true" '></div>
+				
+		<br>Errors: <span id="errors">?</span>
+		<br>Failures: <span id="failures">?</span>					
+    </body>
+</html>
diff --git a/dojox/grid/tests/bidi/test_treegrid_model.html b/dojox/grid/tests/bidi/test_treegrid_model.html
new file mode 100644
index 0000000..50cf905
--- /dev/null
+++ b/dojox/grid/tests/bidi/test_treegrid_model.html
@@ -0,0 +1,101 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+    <head>
+        <title>TreeGrid Model-based test</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+        <style type="text/css">
+            @import "../../../../dojo/resources/dojo.css";
+            @import "../../../../dijit/themes/claro/claro.css";
+            @import "../../../../dojox/grid/resources/Grid.css";
+            @import "../../../../dojox/grid/resources/claroGrid.css";
+            .grid {
+                width: 70em;
+                height: 40em;
+            }
+        </style>
+        <script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: {'dojo-bidi': true}, mblAlwaysHideAddressBar: true"></script>
+
+        <script type="text/javascript">
+		require([
+			"dojo/ready",
+			"doh/runner",
+			"dojo/dom",
+			"dojo/query",
+			"dojo/_base/lang",
+			"dojo/data/ItemFileWriteStore",
+			"dijit/tree/ForestStoreModel",
+			"dojox/grid/TreeGrid",
+			"dojo/parser",			
+			"dojox/grid/cells/dijit"
+		], function(ready, runner, dom, query, lang, ItemFileWriteStore, ForestStoreModel, TreeGrid){
+			ready(function(){		
+				var dataItems = {
+					identifier: 'id',
+					label: 'name',
+					items: [
+						{ id: 'AF', name:'Africa!', type:'continent', population:'900 million!', area: '30,221,532 sq km',
+							timezone: '-1 UTC to +4 UTC',
+							children:[{_reference:'EG'}, {_reference:'KE'}] },
+						{ id: 'EG', name:'Egypt!', type:'country' },
+						{ id: 'KE', name:'Kenya!', type:'country',
+							children:[{_reference:'Nairobi'}, {_reference:'Mombasa'}] },
+						{ id: 'Nairobi', name:'Nairobi!', type:'city' },
+						{ id: 'Mombasa', name:'Mombasa!', type:'city' }
+					]};
+				var dataItems1 = lang.clone(dataItems);
+				
+				var layout = [
+					{ name: "Name!", field: "name", width: "auto" },
+					{ name: "Population!", field: "population", width: "auto" },
+					{ name: "Timezone!", field: "timezone", width: "auto" }
+				];
+				var jsonStore = new ItemFileWriteStore({ data: dataItems1 });
+				var treeModel = new ForestStoreModel({
+					store: jsonStore,
+					query: { type: 'continent' },
+					rootId: 'continentRoot',
+					rootLabel: 'Continents',
+					childrenAttrs: ['children']
+				});
+				var grid2 = new TreeGrid({
+					treeModel: treeModel,
+					structure: layout,
+					defaultOpen: true,
+					textDir: "rtl"
+				}, 'programmatic_grid');
+				grid2.startup();
+				dojo.connect(window, "onresize", grid2, "resize");
+				
+				runner.register("grid.tests.bidi.test_Tree", [
+					{
+						name: "Tree Grid , Bidi",					
+						runTest: function(){
+							query("th.dojoxGridCell").forEach(function(node, index, arr){
+								runner.is("rtl", node.style.direction, "header should have 'direction' style corresponding to 'textDir'");							
+							});
+
+							query("td.dojoxGridCell").forEach(function(node, index, arr){
+								if(node.lastChild && node.lastChild.nodeType === 3) {							
+									runner.is(String.fromCharCode(8235), node.lastChild.nodeValue.charAt(0), "content cell should have direction corresponding to 'textDir'");
+								}
+							});	
+						}
+					}
+				]);
+				runner.register("log", function(){
+					dom.byId('failures').innerHTML = runner._failureCount;
+					dom.byId('errors').innerHTML = runner._errorCount;
+				});
+				runner.run();				
+			});			
+		});
+        </script>
+    </head>
+    <body class="claro">
+		<h1 class="testSubtitle">Bidi TreeGrid Programmatic</h1>
+		<div id="programmatic_grid"></div>
+		<br>
+		<br>Errors: <span id="errors">?</span>
+		<br>Failures: <span id="failures">?</span>			
+    </body>
+</html>
diff --git a/dojox/grid/tests/enhanced/support/test_layout_music.js b/dojox/grid/tests/enhanced/support/test_layout_music.js
index f94427f..2353ba0 100644
--- a/dojox/grid/tests/enhanced/support/test_layout_music.js
+++ b/dojox/grid/tests/enhanced/support/test_layout_music.js
@@ -1,4 +1,3 @@
-dojo.require("dijit.form.DateTextBox");
 var formatDate = function(inDatum){
 	var dtb = new dijit.form.DateTextBox({});
 	var res = dojo.date.locale.parse(inDatum,{
@@ -8,7 +7,7 @@ var formatDate = function(inDatum){
 	dtb.set("value",res);
 	return dtb;
 };
-var layout = [
+this.layout = [
 	[{//--------------------------------------------------------------------------0
 		defaultCell: {editable: true, autoComplete:true, type: dojox.grid.cells._Widget},
 		cells:
diff --git a/dojox/grid/tests/enhanced/support/test_repeat.js b/dojox/grid/tests/enhanced/support/test_repeat.js
index 7327fe8..07cac5c 100644
--- a/dojox/grid/tests/enhanced/support/test_repeat.js
+++ b/dojox/grid/tests/enhanced/support/test_repeat.js
@@ -1,7 +1,7 @@
 (function(){
-var gridIndex = startGridIndex || 0;
-var totalCount = repeatCount || 1000;
-var timeInterval = repeatInterval || 500;
+var gridIndex = 0;
+var totalCount = 1000;
+var timeInterval = 500;
 function createGrid(step){
 	try{
 		var g = dijit.byId("grid");
@@ -53,9 +53,6 @@ function destroy(){
 }
 dojo.addOnLoad(function(){
 	var btns = dojo.byId("ctrlBtns");
-	if(hideCtrlPanel){
-		dojo.style(btns, "display", "none");
-	}
 	btns.appendChild(dojo.create("button",{
 		"innerHTML": "Play",
 		"onclick": start
@@ -85,6 +82,6 @@ dojo.addOnLoad(function(){
 		"innerHTML": "Destroy",
 		"onclick": destroy
 	}));
-	initialShowGrid && gotoGrid();
+	//gotoGrid();
 });
 })();
diff --git a/dojox/grid/tests/enhanced/support/test_write_store_music.js b/dojox/grid/tests/enhanced/support/test_write_store_music.js
index 1357c34..82eeedb 100644
--- a/dojox/grid/tests/enhanced/support/test_write_store_music.js
+++ b/dojox/grid/tests/enhanced/support/test_write_store_music.js
@@ -1,4 +1,3 @@
-dojo.require("dojo.data.ItemFileWriteStore");
 (function(){
 	// some sample data
 	var data = {
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_cellmerge.html b/dojox/grid/tests/enhanced/test_enhanced_grid_cellmerge.html
index 9cd5545..e19d685 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_cellmerge.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_cellmerge.html
@@ -43,15 +43,16 @@
 				border: 1px solid #F1F1F1 !important;
 			}*/
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 		<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
-		<script type="text/javascript" src="support/test_write_store_music.js"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("dijit.form.CheckBox");
+			dojo.require("dojo.data.ItemFileWriteStore");
 			dojo.require("dojox.grid.EnhancedGrid");
 			dojo.require("dojox.grid.enhanced.plugins.CellMerge");
 			
+			
 			var layout = [{
 				cells: [
 					{ field: "id", name:"Identity", datatype:"number", width: 4, editable: false},
@@ -141,6 +142,7 @@
 			}
 			dojo.addOnLoad(updateMergedCells);
 		</script>
+		<script type="text/javascript" src="support/test_write_store_music.js"></script>
 	</head>
 	<body class="claro">
 		<h1 class="title">dojox.grid.EnhancedGrid - Cell Merge</h1>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_cookie.html b/dojox/grid/tests/enhanced/test_enhanced_grid_cookie.html
index 3946742..f6e1364 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_cookie.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_cookie.html
@@ -27,11 +27,11 @@
 			border: 1px solid #F1F1F1 !important;
 		}*/
 	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
-	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
+		dojo.require("dojo.data.ItemFileWriteStore");
 		dojo.require("dojox.grid.EnhancedGrid");
 		dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
 		dojo.require("dojox.grid.enhanced.plugins.DnD");
@@ -70,6 +70,7 @@
 		}
 		
 	</script>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 </head>
 <body class="claro">
 	<h1 class="title">dojox.grid.EnhancedGrid - Cookie</h1>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_dnd.html b/dojox/grid/tests/enhanced/test_enhanced_grid_dnd.html
index cfcb564..481ecf7 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_dnd.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_dnd.html
@@ -52,7 +52,7 @@
 		}*/
 	</style>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_filter.html b/dojox/grid/tests/enhanced/test_enhanced_grid_filter.html
index 5688a02..974a8ce 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_filter.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_filter.html
@@ -20,10 +20,10 @@
 			height: 30em;
 		}
 	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
-	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 	<script type="text/javascript">
+		dojo.require("dojo.data.ItemFileWriteStore");
 		dojo.require("dojox.grid.EnhancedGrid");
 		dojo.require("dojox.grid.enhanced.plugins.Filter");
 		
@@ -96,6 +96,7 @@
 			});
 		});
 	</script>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 </head>
 <body class="claro">
 	<h1 class="title">dojox.grid.EnhancedGrid - Filter</h1>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_indirectSelection.html b/dojox/grid/tests/enhanced/test_enhanced_grid_indirectSelection.html
index a4e909a..6f41db5 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_indirectSelection.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_indirectSelection.html
@@ -20,7 +20,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.grid.EnhancedGrid");
@@ -68,6 +68,7 @@
 					store: test_store,
 					structure: layout,
 					rowSelector: "20px",
+					summary: "A customized grid summary",
 					plugins: {indirectSelection: {headerSelector:true, name: "Selection", width: "60px", styles: "text-align: center;"}}
 				});
 
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_leak_programmatic.html b/dojox/grid/tests/enhanced/test_enhanced_grid_leak_programmatic.html
index e9dbd91..39f6901 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_leak_programmatic.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_leak_programmatic.html
@@ -23,7 +23,7 @@
 	
 		</style>
 		<script type="text/javascript" src="../../../../dojo/dojo.js" 
-			djConfig="isDebug:true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dojox.grid.EnhancedGrid");
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_leak_scroll.html b/dojox/grid/tests/enhanced/test_enhanced_grid_leak_scroll.html
index a8e45df..15ec67c 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_leak_scroll.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_leak_scroll.html
@@ -22,7 +22,7 @@
 	
 		</style>
 		<script type="text/javascript" src="../../../../dojo/dojo.js" 
-			djConfig="isDebug:false, parseOnLoad: true"></script>
+			data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dojox.grid.EnhancedGrid");
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_leak_with_plugin.html b/dojox/grid/tests/enhanced/test_enhanced_grid_leak_with_plugin.html
index 9763ac1..63e5e2a 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_leak_with_plugin.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_leak_with_plugin.html
@@ -48,11 +48,13 @@
 		}*/
 	</style>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.form.CheckBox");
+		dojo.require("dijit.form.DateTextBox");
 		dojo.require("dijit._WidgetsInTemplateMixin");
+		dojo.require("dojo.data.ItemFileWriteStore");
 		dojo.require("dojox.grid.enhanced.plugins.Filter");
 		dojo.require("dojox.grid.enhanced.plugins.exporter.CSVWriter");
 		dojo.require("dojox.grid.enhanced.plugins.Printer");
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_menus.html b/dojox/grid/tests/enhanced/test_enhanced_grid_menus.html
index d5f7453..7fb8974 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_menus.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_menus.html
@@ -18,9 +18,11 @@
 
 	</style>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
 	<script type="text/javascript">
+		dojo.require("dijit.Menu");
+		dojo.require("dijit.MenuItem");
 		dojo.require("dojox.grid.EnhancedGrid");
 		dojo.require("dojox.grid.enhanced.plugins.Menu");
 		dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_nestedsorting.html b/dojox/grid/tests/enhanced/test_enhanced_grid_nestedsorting.html
index 505b902..fac62b2 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_nestedsorting.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_nestedsorting.html
@@ -20,7 +20,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.grid.EnhancedGrid");
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_pagination.html b/dojox/grid/tests/enhanced/test_enhanced_grid_pagination.html
index 21c15e5..2847f60 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_pagination.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_pagination.html
@@ -23,10 +23,10 @@
 			margin: 1em;
 		}
 	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
-	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 	<script type="text/javascript">
+		dojo.require("dojo.data.ItemFileWriteStore");
 		dojo.require("dojox.grid.EnhancedGrid");
 		dojo.require("dojox.grid.enhanced.plugins.Pagination");
 		dojo.require("dojo.parser");
@@ -81,6 +81,7 @@
 			grid.scrollToRow(dijit.byId("row").value - 1);
 		}
 	</script>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 </head>
 <body class="claro">
 	<h1 class="title">dojox.grid.EnhancedGrid - Pagination</h1>
@@ -103,7 +104,7 @@
 		<button data-dojo-type="dijit.form.Button" onclick="scrollToRow()">Go</button>
 	</div>
 	<div id="gridContainer">
-		<div id="grid" dojoType="dojox.grid.EnhancedGrid" store="test_store[0]" structure="layout" plugins="plugins"></div>
+		<div id="grid" dojoType="dojox.grid.EnhancedGrid" store="test_store[0]" structure="layout" plugins="plugins" summary="A customized grid summary"></div>
 	</div><br/>
 	<p><strong>Note:</strong> To see the tundra theme, just append <b style="color:blue;">?theme=tundra</b> to the URL.</p>
 </body>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_plugins.html b/dojox/grid/tests/enhanced/test_enhanced_grid_plugins.html
index 8c8d939..b819623 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_plugins.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_plugins.html
@@ -48,11 +48,13 @@
 		}*/
 	</style>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
 	<script type="text/javascript">
 		dojo.require("dijit._WidgetsInTemplateMixin");
 		dojo.require("dijit.form.CheckBox");
+		dojo.require("dijit.form.DateTextBox");
+		dojo.require("dojo.data.ItemFileWriteStore");
 		dojo.require("dojox.grid.enhanced.plugins.Filter");
 		dojo.require("dojox.grid.enhanced.plugins.exporter.CSVWriter");
 		dojo.require("dojox.grid.enhanced.plugins.Printer");
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_print_export.html b/dojox/grid/tests/enhanced/test_enhanced_grid_print_export.html
index cd28153..a0b03c6 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_print_export.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_print_export.html
@@ -20,11 +20,11 @@
 			height: 50em;
 		}
 	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
-	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
+		dojo.require("dojo.data.ItemFileWriteStore");
 		dojo.require("dojox.grid.EnhancedGrid");
 		dojo.require("dojox.data.CsvStore");
 		dojo.require("dojox.grid.enhanced.plugins.exporter.CSVWriter");
@@ -110,6 +110,7 @@
 			});
 		}
 	</script>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 </head>
 <body class="claro">
 	<h1 class="title">dojox.grid.EnhancedGrid - Print, Export</h1>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_search.html b/dojox/grid/tests/enhanced/test_enhanced_grid_search.html
index 845c7e9..fc01121 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_search.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_search.html
@@ -43,10 +43,10 @@
 			background-color:yellow;
 		}
 	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
-	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 	<script type="text/javascript">
+		dojo.require("dojo.data.ItemFileWriteStore");
 		dojo.require("dojox.grid.EnhancedGrid");
 		dojo.require("dojox.grid.enhanced.plugins.Search");
 		dojo.require("dojo.parser");
@@ -105,6 +105,7 @@
 			dijit.byId("grid").searchRow(getInput(input), dojo.partial(onSearched, "result1"));
 		};
 	</script>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 </head>
 <body class="claro">
 	<h1 class="title" tabindex="0"
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_selector.html b/dojox/grid/tests/enhanced/test_enhanced_grid_selector.html
index ce79467..213e006 100644
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_selector.html
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_selector.html
@@ -31,11 +31,11 @@
 			border: 1px solid #F1F1F1 !important;
 		}*/
 	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
-	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
+		dojo.require("dojo.data.ItemFileWriteStore");
 		dojo.require("dojox.grid.EnhancedGrid");
 		dojo.require("dojox.grid.enhanced.plugins.Selector");
 		dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
@@ -98,6 +98,7 @@
 			dojo.connect(grid, "onEndDeselect", func);
 		});
 	</script>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
 </head>
 <body class="claro">
 	<h1 class="title" tabindex="0"
diff --git a/dojox/grid/tests/robot/7815.html b/dojox/grid/tests/robot/7815.html
index 33c515f..92692f4 100755
--- a/dojox/grid/tests/robot/7815.html
+++ b/dojox/grid/tests/robot/7815.html
@@ -10,7 +10,7 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.robotx");
 
diff --git a/dojox/grid/tests/robot/DataGrid_a11y.html b/dojox/grid/tests/robot/DataGrid_a11y.html
index f037c9e..f77d5fc 100755
--- a/dojox/grid/tests/robot/DataGrid_a11y.html
+++ b/dojox/grid/tests/robot/DataGrid_a11y.html
@@ -10,11 +10,11 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
-		<script type="text/javascript" src="../../../../dijit/tests/helpers.js"></script>
+		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.robotx");
+		dojo.require("dijit.tests.helpers");	// functions to help test
 
 		dojo.addOnLoad(function(){
 
diff --git a/dojox/grid/tests/robot/DataGrid_mouse.html b/dojox/grid/tests/robot/DataGrid_mouse.html
index 8868450..22f0368 100755
--- a/dojox/grid/tests/robot/DataGrid_mouse.html
+++ b/dojox/grid/tests/robot/DataGrid_mouse.html
@@ -10,7 +10,7 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.robotx");
 
diff --git a/dojox/grid/tests/robot/_DataGrid.html b/dojox/grid/tests/robot/_DataGrid.html
index 7693229..64c0ace 100755
--- a/dojox/grid/tests/robot/_DataGrid.html
+++ b/dojox/grid/tests/robot/_DataGrid.html
@@ -17,7 +17,7 @@
 	
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: do NOT use in your code! -->
 	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
@@ -49,7 +49,7 @@
 
 	<h1 dojoType="dojo.dnd.Target" class="testTitle">dojox.grid.DataGrid tests</h1>
 	<input id="initialfocus"></input>
-		<div dojoType="dijit.Menu" jsid="gridMenu" id="gridMenu" style="display: none;">
+		<div dojoType="dijit.Menu" data-dojo-id="gridMenu" id="gridMenu" style="display: none;">
 				<div dojoType="dijit.MenuItem" >Item One</div>
 				<div dojoType="dijit.MenuItem" >Item Two</div>
 				<div dojoType="dijit.MenuItem" >Item Three</div>
diff --git a/dojox/grid/tests/test_backwards_compatibility.html b/dojox/grid/tests/test_backwards_compatibility.html
index ad5a318..96120ac 100644
--- a/dojox/grid/tests/test_backwards_compatibility.html
+++ b/dojox/grid/tests/test_backwards_compatibility.html
@@ -27,7 +27,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -68,12 +68,12 @@
 <body>
 <div class="heading">dojox.grid.Grid Backwards Compatibility Test</div>
 	<div>A new grid</div>
-	<div jsid="grid" id="grid" dojoType="dojox.grid.DataGrid" store="test_store" query="{ id: '*' }" structure="layout" rowSelector="20px"></div>
+	<div data-dojo-id="grid" id="grid" dojoType="dojox.grid.DataGrid" store="test_store" query="{ id: '*' }" structure="layout" rowSelector="20px"></div>
 	<span dojoType="dojo.data.ItemFileReadStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<span dojoType="dojox.grid.data.DojoData" 
-		jsId="dataModel2" 
+		data-dojo-id="dataModel2"
 		rowsPerPage="20"
 		store="jsonStore" 
 		query="{ name : '*' }">
diff --git a/dojox/grid/tests/test_change_structure.html b/dojox/grid/tests/test_change_structure.html
index 984d0ab..29e649f 100644
--- a/dojox/grid/tests/test_change_structure.html
+++ b/dojox/grid/tests/test_change_structure.html
@@ -24,7 +24,7 @@
 			text-align: center;
 		}
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid._Grid");
@@ -108,7 +108,7 @@
 <p>
 	<button onclick="toggleStructure()">Change Structure</button>
 </p>	
-<div id="grid" jsid="grid" dojoType="dojox.grid._Grid" structure="structure" rowSelector="20px" rowCount="100000" elasticView="2"></div>
+<div id="grid" data-dojo-id="grid" dojoType="dojox.grid._Grid" structure="structure" rowSelector="20px" rowCount="100000" elasticView="2"></div>
 
 </body>
 </html>
diff --git a/dojox/grid/tests/test_custom_sort.html b/dojox/grid/tests/test_custom_sort.html
index 59812ba..e8fe3ad 100644
--- a/dojox/grid/tests/test_custom_sort.html
+++ b/dojox/grid/tests/test_custom_sort.html
@@ -22,7 +22,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -64,6 +64,6 @@
 <br />
 <b>Column 1</b>'s data field has a custom sorter that sorts by the status level rather than alphebetically
 <br /><br />
-<div id="grid" jsid="grid" dojoType="dojox.grid.DataGrid" store="test_store" structure="layout"></div>
+<div id="grid" data-dojo-id="grid" dojoType="dojox.grid.DataGrid" store="test_store" structure="layout"></div>
 </body>
 </html>
diff --git a/dojox/grid/tests/test_data_grid.html b/dojox/grid/tests/test_data_grid.html
index ab69db3..7a3a59d 100644
--- a/dojox/grid/tests/test_data_grid.html
+++ b/dojox/grid/tests/test_data_grid.html
@@ -23,7 +23,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -35,10 +35,10 @@
 <body class="tundra">
 	<div class="heading">dojox.grid.DataGrid Basic Test</div>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
-	<table dojoType="dojox.grid.DataGrid" keepSelection=true
-		jsid="grid" id="grid" 
+	<table dojoType="dojox.grid.DataGrid" keepSelection=true summary="A customized grid summary"
+		data-dojo-id="grid" id="grid"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_data_grid_autoheight.html b/dojox/grid/tests/test_data_grid_autoheight.html
index 4c88a9c..db04be6 100644
--- a/dojox/grid/tests/test_data_grid_autoheight.html
+++ b/dojox/grid/tests/test_data_grid_autoheight.html
@@ -19,7 +19,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -30,7 +30,7 @@
 </head>
 <body class="tundra">
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<div class="heading">No autoHeight (takes height of the div)</div>
 	<table dojoType="dojox.grid.DataGrid"
diff --git a/dojox/grid/tests/test_data_grid_autowidth.html b/dojox/grid/tests/test_data_grid_autowidth.html
index 36750c0..97dd527 100644
--- a/dojox/grid/tests/test_data_grid_autowidth.html
+++ b/dojox/grid/tests/test_data_grid_autowidth.html
@@ -23,7 +23,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -41,10 +41,10 @@
 <body class="tundra">
 	<div class="heading">dojox.grid.DataGrid Automatic Width Test</div>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" class="grid" autoWidth="true"
+		data-dojo-id="grid" id="grid" class="grid" autoWidth="true"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -56,7 +56,7 @@
 	</table>
 	<div class="heading">Auto Width with % column widths (and fixed initial grid width)</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid1" id="grid1" class="grid" autoWidth="true" initialWidth="50em"
+		data-dojo-id="grid1" id="grid1" class="grid" autoWidth="true" initialWidth="50em"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -68,7 +68,7 @@
 	</table>
 	<div class="heading">Auto Width with % column widths (and % initial grid width)</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid2" id="grid2" class="grid" autoWidth="true" initialWidth="85%"
+		data-dojo-id="grid2" id="grid2" class="grid" autoWidth="true" initialWidth="85%"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_data_grid_edit.html b/dojox/grid/tests/test_data_grid_edit.html
index bee3ffd..d878a49 100644
--- a/dojox/grid/tests/test_data_grid_edit.html
+++ b/dojox/grid/tests/test_data_grid_edit.html
@@ -22,7 +22,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -34,10 +34,10 @@
 <body class="claro">
 	<div class="heading">dojox.grid.DataGrid Basic Editing Test</div>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" 
+		data-dojo-id="grid" id="grid"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_data_grid_edit_dijit.html b/dojox/grid/tests/test_data_grid_edit_dijit.html
index d24f594..d64ba95 100644
--- a/dojox/grid/tests/test_data_grid_edit_dijit.html
+++ b/dojox/grid/tests/test_data_grid_edit_dijit.html
@@ -25,7 +25,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -38,10 +38,10 @@
 <body class="tundra">
 	<div class="heading">dojox.grid.DataGrid Dijit Editing Test</div>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" 
+		data-dojo-id="grid" id="grid"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_data_grid_edit_large_resultset.html b/dojox/grid/tests/test_data_grid_edit_large_resultset.html
index 5337a35..06f7184 100644
--- a/dojox/grid/tests/test_data_grid_edit_large_resultset.html
+++ b/dojox/grid/tests/test_data_grid_edit_large_resultset.html
@@ -34,7 +34,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -87,12 +87,12 @@
 		<button onclick="grid.singleClickEdit = !grid.singleClickEdit">Toggle singleClickEdit</button> 
 	</div>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		 jsId="jsonStore" url="support/numbers.json">
+		 data-dojo-id="jsonStore" url="support/numbers.json">
 	</span>
-	<div id="grid" jsId="grid" dojoType="dojox.grid.DataGrid" elasticView="2" query="{ id: '*' }"
+	<div id="grid" data-dojo-id="grid" dojoType="dojox.grid.DataGrid" elasticView="2" query="{ id: '*' }"
 		 rowsPerPage="20" store="jsonStore" structure="layoutNumbers" rowSelector="20px">
 	</div>
-	<div id="grid2" jsId="grid2" dojoType="dojox.grid.DataGrid" elasticView="2" query="{ id: '*' }"
+	<div id="grid2" data-dojo-id="grid2" dojoType="dojox.grid.DataGrid" elasticView="2" query="{ id: '*' }"
 		 rowsPerPage="20" store="jsonStore" structure="layoutNumbers" rowSelector="20px">
 	</div>
 </body>
diff --git a/dojox/grid/tests/test_data_grid_empty.html b/dojox/grid/tests/test_data_grid_empty.html
index 97204da..a85be44 100644
--- a/dojox/grid/tests/test_data_grid_empty.html
+++ b/dojox/grid/tests/test_data_grid_empty.html
@@ -13,7 +13,7 @@
 		}
 	</style> 
 	<script type="text/javascript" src="../../../dojo/dojo.js"  
-		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script> 
+		data-dojo-config="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
 	<script type="text/javascript"> 
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid"); 
@@ -44,7 +44,7 @@
 			store="jsonStore" structure="layoutCountries" rowSelector="20px"> 
 		</div> 
 		<button dojoType="dijit.form.Button"> 
-			<script type="dojo/method" event="onClick"> 
+			<script type="dojo/method" data-dojo-event="onClick">
 				numItems++; 
 				dojo.connect(jsonStore, "fetch", function(){
 					console.error("Calling newItem should not trigger a fetch.");
diff --git a/dojox/grid/tests/test_data_grid_hideHdr.html b/dojox/grid/tests/test_data_grid_hideHdr.html
index 8f4c30e..69d139b 100644
--- a/dojox/grid/tests/test_data_grid_hideHdr.html
+++ b/dojox/grid/tests/test_data_grid_hideHdr.html
@@ -24,7 +24,7 @@
 		.dojoxGridHeader { display:none; }
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -37,10 +37,10 @@
 	<div class="heading">dojox.grid.DataGrid Basic Test</div>
 	<p><a href="http://dojotoolkit.org/reference-guide/dojox/grid">grid docs</a> (focusable element before grid)</p>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" 
+		data-dojo-id="grid" id="grid"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_data_grid_large.html b/dojox/grid/tests/test_data_grid_large.html
index c732850..7ee25be 100644
--- a/dojox/grid/tests/test_data_grid_large.html
+++ b/dojox/grid/tests/test_data_grid_large.html
@@ -23,7 +23,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -53,7 +53,7 @@
 <body class="tundra">
 	<div class="heading">dojox.grid.DataGrid Large Data Set Test</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" 
+		data-dojo-id="grid" id="grid"
 		store="test_store" query="{ id: '*' }" rowsPerPage="20" structure="layout" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_data_grid_large_flex_cells.html b/dojox/grid/tests/test_data_grid_large_flex_cells.html
index ea0a20c..ec710ae 100644
--- a/dojox/grid/tests/test_data_grid_large_flex_cells.html
+++ b/dojox/grid/tests/test_data_grid_large_flex_cells.html
@@ -22,7 +22,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: false"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: false"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -81,7 +81,7 @@
 <body class="tundra">
 	<div class="heading">dojox.grid.DataGrid Large Data Set Test with Flex Cells</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" columnReordering="true" 
+		data-dojo-id="grid" id="grid" columnReordering="true"
 		store="test_store" query="{ id: '*' }" rowsPerPage="20" structure="layout">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_data_grid_multiStores.html b/dojox/grid/tests/test_data_grid_multiStores.html
index 55fc65f..573c0d8 100644
--- a/dojox/grid/tests/test_data_grid_multiStores.html
+++ b/dojox/grid/tests/test_data_grid_multiStores.html
@@ -18,7 +18,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -136,7 +136,7 @@
 	<h2>dojo.data.ItemFileReadStore:</h2>
 	<i>Displays a list of countries through ItemFileReadStore format.</i>
 	<span dojoType="dojo.data.ItemFileReadStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<div id="grid" dojoType="dojox.grid.DataGrid" elasticView="2" query="{ name: '*' }" rowsPerPage="20"
 		store="jsonStore" structure="layoutCountries" rowSelector="20px">
@@ -146,7 +146,7 @@
 	<h2>dojox.data.CsvStore:</h2>
 	<i>Displays a list of movies that were stored in CSV format.</i>
 	<span dojoType="dojox.data.CsvStore" 
-		jsId="csvStore" url="support/movies.csv">
+		data-dojo-id="csvStore" url="support/movies.csv">
 	</span>
 	<div id="grid2" dojoType="dojox.grid.DataGrid" elasticView="2" query="{ Title: '*' }" rowsPerPage="5"
 		store="csvStore" structure="layoutMovies" rowSelector="20px">
@@ -155,7 +155,7 @@
 	<h2>dojox.data.XmlStore:</h2>
 	<i>Displays a list of books that were stored in XML format.</i>
 	<span dojoType="dojox.data.XmlStore" 
-		jsId="xmlStore" url="support/books.xml">
+		data-dojo-id="xmlStore" url="support/books.xml">
 	</span>
 	<div id="grid3" dojoType="dojox.grid.DataGrid" elasticView="2" query="{ title: '*' }" rowsPerPage="5"
 		store="xmlStore" structure="layoutBooks" rowSelector="20px">
@@ -165,7 +165,7 @@
 	<h2>dojox.data.FlickrStore:</h2>
 	<i>Displays Flickr imformation on 3DNY (Dojo Developer Days, New York) from the flickr public photo feed, accessed via the FlickrStore dojo.data implementation.</i>
 	<span dojoType="dojox.data.FlickrStore" 
-		jsId="flickrStore">
+		data-dojo-id="flickrStore">
 	</span>
 	<div id="grid4" dojoType="dojox.grid.DataGrid" elasticView="2" query="{ tags: '3dny' }"
 		rowsPerPage="5"
@@ -175,7 +175,7 @@
 	<h2>dojox.data.OpmlStore:</h2>
 	<i>Scans an Opml based document for all items of type 'country'</i> 
 	<span dojoType="dojox.data.OpmlStore" 
-		jsId="opmlStore" url="support/geography.xml">
+		data-dojo-id="opmlStore" url="support/geography.xml">
 	</span>
 	<div id="grid5" dojoType="dojox.grid.DataGrid" elasticView="2" query="{ type: 'country' }"
 		queryOptions="{ deep: true }" rowsPerPage="5"
@@ -226,7 +226,7 @@
 		</tbody>
 	</table>
 	<span dojoType="dojox.data.HtmlStore" 
-		jsId="htmlStore" dataId="tableExample">
+		data-dojo-id="htmlStore" dataId="tableExample">
 	</span>
 	<div id="grid6" dojoType="dojox.grid.DataGrid" elasticView="2" query="{}"
 		store="htmlStore" rowsPerPage="5" structure="layoutHtmlTable" rowSelector="20px">
diff --git a/dojox/grid/tests/test_data_grid_notification.html b/dojox/grid/tests/test_data_grid_notification.html
index 1bf2f1d..c09f1c1 100644
--- a/dojox/grid/tests/test_data_grid_notification.html
+++ b/dojox/grid/tests/test_data_grid_notification.html
@@ -23,7 +23,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -51,10 +51,10 @@
 		}
 	</script>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" 
+		data-dojo-id="grid" id="grid"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_data_grid_page_cache.html b/dojox/grid/tests/test_data_grid_page_cache.html
index c208f6c..da05fd1 100644
--- a/dojox/grid/tests/test_data_grid_page_cache.html
+++ b/dojox/grid/tests/test_data_grid_page_cache.html
@@ -8,7 +8,7 @@
 		@import "../resources/tundraGrid.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djconfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
 		dojo.require("dojo.data.ItemFileWriteStore");
@@ -40,6 +40,6 @@
 <body class="tundra">
 	Scroll trough some pages and then count the number of row nodes. We are instantiating the grid with 10 rows per page, and <b>caching at most 20 rows</b>. So if this policy works, you should never see a number bigger than 20! <br>
 	<button onclick="query()">Get number of row nodes</button>
-	<div jsid="grid1" dojoType="dojox.grid.DataGrid" store="test_store" query="{ id: '*' }" rowsPerPage="10" keepRows="20" structure="layout" style="height: 200px; width: 75%;">
+	<div data-dojo-id="grid1" dojoType="dojox.grid.DataGrid" store="test_store" query="{ id: '*' }" rowsPerPage="10" keepRows="20" structure="layout" style="height: 200px; width: 75%;">
 	</div>
 </body></html>
diff --git a/dojox/grid/tests/test_data_grid_pctWidth.html b/dojox/grid/tests/test_data_grid_pctWidth.html
index 11e24d3..baf7c86 100644
--- a/dojox/grid/tests/test_data_grid_pctWidth.html
+++ b/dojox/grid/tests/test_data_grid_pctWidth.html
@@ -23,7 +23,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -40,10 +40,10 @@
 <body class="tundra">
 	<div class="heading">dojox.grid.DataGrid Percentage Width Test</div>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" 
+		data-dojo-id="grid" id="grid"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_data_grid_processError.html b/dojox/grid/tests/test_data_grid_processError.html
index 0802d37..de2ee91 100644
--- a/dojox/grid/tests/test_data_grid_processError.html
+++ b/dojox/grid/tests/test_data_grid_processError.html
@@ -18,7 +18,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -40,11 +40,11 @@
 	<h2>dojox.data.CsvStore:</h2>.
 	<i>This grid does not load data.  The data store references a non-existent URL on purpose.  It should trigger a failure that we catch and display in an alert</i>
 	<span dojoType="dojox.data.CsvStore" 
-		jsId="csvStore" url="support/NoSuchMovieFile.csv">
+		data-dojo-id="csvStore" url="support/NoSuchMovieFile.csv">
 	</span>
-	<div id="grid" jsid="grid" dojoType="dojox.grid.DataGrid" elasticView="2" query="{ Title: '*' }"
+	<div id="grid" data-dojo-id="grid" dojoType="dojox.grid.DataGrid" elasticView="2" query="{ Title: '*' }"
 		rowsPerPage="5" store="csvStore" structure="layoutMovies" autoRender="false">
-		<script type="dojo/connect" event="onFetchError" args="error">
+		<script type="dojo/connect" data-dojo-event="onFetchError" data-dojo-args="error">
 			alert("Error was encountered when store was queried: " + dojo.toJson(error, true));
 		</script>
 	</div>
diff --git a/dojox/grid/tests/test_data_grid_relWidth.html b/dojox/grid/tests/test_data_grid_relWidth.html
index 8e6dbe0..6dd9071 100644
--- a/dojox/grid/tests/test_data_grid_relWidth.html
+++ b/dojox/grid/tests/test_data_grid_relWidth.html
@@ -23,7 +23,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -45,10 +45,10 @@
 <body class="tundra">
 	<div class="heading">dojox.grid.DataGrid Relative Width Test</div>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" class="grid"
+		data-dojo-id="grid" id="grid" class="grid"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -60,7 +60,7 @@
 	</table>
 	<div class="heading">Relwidth mixed with %</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid1" id="grid1" class="grid"
+		data-dojo-id="grid1" id="grid1" class="grid"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -72,7 +72,7 @@
 	</table>	
 	<div class="heading">Relwidth mixed with static values</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid2" id="grid2" class="grid"
+		data-dojo-id="grid2" id="grid2" class="grid"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -84,7 +84,7 @@
 	</table>	
 	<div class="heading">Relwidth mixed with auto (relwidth not used)</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid3" id="grid3" class="grid"
+		data-dojo-id="grid3" id="grid3" class="grid"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -96,7 +96,7 @@
 	</table>	
 	<div class="heading">Relwidth with colspans</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid4" id="grid4" class="grid"
+		data-dojo-id="grid4" id="grid4" class="grid"
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_data_grid_setStore.html b/dojox/grid/tests/test_data_grid_setStore.html
index b58ef7b..7c8077a 100644
--- a/dojox/grid/tests/test_data_grid_setStore.html
+++ b/dojox/grid/tests/test_data_grid_setStore.html
@@ -28,7 +28,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dojox.grid.DataGrid");
@@ -87,11 +87,11 @@
 		<button onclick="createStore('error');">Error Store</button>
 	</p>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<div class="heading">Grid Test</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" class="grid" autoHeight="15" noDataMessage="Sorry, there is no data available."
+		data-dojo-id="grid" id="grid" class="grid" autoHeight="15" noDataMessage="Sorry, there is no data available."
 		store="jsonStore" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_edit.html b/dojox/grid/tests/test_edit.html
index 537d224..4005ce1 100644
--- a/dojox/grid/tests/test_edit.html
+++ b/dojox/grid/tests/test_edit.html
@@ -35,7 +35,7 @@
 		border: 1px solid silver;
 	}
 </style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.grid.DataGrid");
 		dojo.require("dojo.data.ItemFileWriteStore");
@@ -106,7 +106,7 @@
 </div>
 <br />
 <div id="grid" dojoType="dojox.grid.DataGrid" 
-	jsId="grid"
+	data-dojo-id="grid"
 	rowSelector="20px"
 	store="test_store" structure="gridLayout"></div>
 <br />
diff --git a/dojox/grid/tests/test_edit_canEdit.html b/dojox/grid/tests/test_edit_canEdit.html
index 299e7fd..a974e45 100644
--- a/dojox/grid/tests/test_edit_canEdit.html
+++ b/dojox/grid/tests/test_edit_canEdit.html
@@ -34,7 +34,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -116,7 +116,7 @@
 	</div>
 	<br />
 	<div id="grid" dojoType="dojox.grid.DataGrid" 
-		jsId="grid"
+		data-dojo-id="grid"
 		rowSelector="20px"
 		store="test_store" structure="gridLayout"></div>
 	<br />
diff --git a/dojox/grid/tests/test_edit_dijit.html b/dojox/grid/tests/test_edit_dijit.html
index f9cd047..4c3bd71 100644
--- a/dojox/grid/tests/test_edit_dijit.html
+++ b/dojox/grid/tests/test_edit_dijit.html
@@ -21,7 +21,7 @@
 		}
 		</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
@@ -105,7 +105,7 @@
 		<button onclick="grid.singleClickEdit = !grid.singleClickEdit">Toggle singleClickEdit</button>
 	</div>
 	<br />
-	<div id="grid" jsId="grid" dojoType="dojox.grid.DataGrid" store="test_store" rowSelector="20px" structure="gridLayout" escapeHTMLInData="false"></div>
+	<div id="grid" data-dojo-id="grid" dojoType="dojox.grid.DataGrid" store="test_store" rowSelector="20px" structure="gridLayout" escapeHTMLInData="false"></div>
 	<br />
 	<div id="rowCount"></div>
 </body>
diff --git a/dojox/grid/tests/test_edit_keyNav.html b/dojox/grid/tests/test_edit_keyNav.html
index ce05e0c..65857f6 100644
--- a/dojox/grid/tests/test_edit_keyNav.html
+++ b/dojox/grid/tests/test_edit_keyNav.html
@@ -35,7 +35,7 @@
 		border: 1px solid silver;
 	}
 </style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.grid.DataGrid");
 		dojo.require("dojo.data.ItemFileWriteStore");
@@ -109,7 +109,7 @@ Amount3, and detail field are not editable.  Once in edit mode you can tab and s
 editable fields and remain in edit mode.  Pressing escape leaves edit mode and arrow keys will again move 
 between cells.  </p>
 <div id="grid" dojoType="dojox.grid.DataGrid" 
-	jsId="grid"
+	data-dojo-id="grid"
 	rowSelector="20px"
 	store="test_store" structure="gridLayout"></div>
 <br />
diff --git a/dojox/grid/tests/test_events.html b/dojox/grid/tests/test_events.html
index f416954..02ed5ae 100644
--- a/dojox/grid/tests/test_events.html
+++ b/dojox/grid/tests/test_events.html
@@ -38,7 +38,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid._Grid");
@@ -183,9 +183,9 @@
 </head>
 <body>
 	<h3>dojox.grid.Grid Event Tracking</h3>
-	<div id="eventGrid" jsId="eventGrid" autoWidth="true" autoHeight="true" 
+	<div id="eventGrid" data-dojo-id="eventGrid" autoWidth="true" autoHeight="true"
 		structure="eventLayout" dojoType="dojox.grid._Grid"></div>
-	<div id="grid" jsId="grid" rowCount="100" structure="layout" 
+	<div id="grid" data-dojo-id="grid" rowCount="100" structure="layout"
 		rowSelector="20px" dojoType="dojox.grid._Grid"></div>
 </body>
 </html>
diff --git a/dojox/grid/tests/test_expand.html b/dojox/grid/tests/test_expand.html
index 5a10bcc..fb64c1e 100644
--- a/dojox/grid/tests/test_expand.html
+++ b/dojox/grid/tests/test_expand.html
@@ -29,7 +29,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -102,7 +102,7 @@
 <body>
 	<div class="heading">dojox.grid.Grid Expand Row Example</div>
 
-	<div id="grid" jsid="grid" dojoType="dojox.grid._Grid"
+	<div id="grid" data-dojo-id="grid" dojoType="dojox.grid._Grid"
 		structure="structure" rowCount="100000" autoWidth="true" rowSelector="20px"></div>
 
 </body>
diff --git a/dojox/grid/tests/test_grid.html b/dojox/grid/tests/test_grid.html
index 7fa3216..041a633 100644
--- a/dojox/grid/tests/test_grid.html
+++ b/dojox/grid/tests/test_grid.html
@@ -25,7 +25,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -51,7 +51,7 @@
 </head>
 <body class="tundra">
 	<div class="heading">dojox.grid.Grid Basic Test</div>
-	<div jsId="grid" id="grid" dojoType="dojox.grid.DataGrid" 
+	<div data-dojo-id="grid" id="grid" dojoType="dojox.grid.DataGrid"
 		store="test_store" query="{ id: '*' }" 
 		structure="layout" rowSelector="20px"></div>
 </body>
diff --git a/dojox/grid/tests/test_grid_autorender.html b/dojox/grid/tests/test_grid_autorender.html
index 0709844..fac43cd 100644
--- a/dojox/grid/tests/test_grid_autorender.html
+++ b/dojox/grid/tests/test_grid_autorender.html
@@ -25,7 +25,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.grid.DataGrid");
 		dojo.require("dojo.data.ItemFileWriteStore");
@@ -53,7 +53,7 @@
 </head>
 <body class="tundra">
 	<div class="heading">dojox.grid.Grid autoRender Test</div>
-	<div jsId="grid" id="grid" dojoType="dojox.grid.DataGrid" 
+	<div data-dojo-id="grid" id="grid" dojoType="dojox.grid.DataGrid"
 		store="test_store" query="{ id: '*' }" 
 		structure="layout" rowSelector="20px" autoRender="false"></div>
 	<button onclick="renderGrid()">Render the grid</button>
diff --git a/dojox/grid/tests/test_grid_colspan_resize.html b/dojox/grid/tests/test_grid_colspan_resize.html
index 8cf647d..7c9a94e 100644
--- a/dojox/grid/tests/test_grid_colspan_resize.html
+++ b/dojox/grid/tests/test_grid_colspan_resize.html
@@ -24,7 +24,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="debugAtAllCosts: false, isDebug: false, parseOnLoad: true"></script>
+		data-dojo-config="debugAtAllCosts: false, isDebug: false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojo.data.ItemFileReadStore");
@@ -72,7 +72,7 @@
 </head>
 <body class="tundra">
 	<div dojoType="dojo.data.ItemFileReadStore"
-		jsId="jsonStore" url="support/test_resize_data.json">
+		data-dojo-id="jsonStore" url="support/test_resize_data.json">
 	</div>
 	<div class="heading">No Colspan</div>
 	<div id="grid" dojoType="dojox.grid.DataGrid" 
diff --git a/dojox/grid/tests/test_grid_column_display.html b/dojox/grid/tests/test_grid_column_display.html
index fde0637..a0be2a5 100644
--- a/dojox/grid/tests/test_grid_column_display.html
+++ b/dojox/grid/tests/test_grid_column_display.html
@@ -27,7 +27,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dijit.ColorPalette");
@@ -64,7 +64,7 @@
 <body class="tundra">
 	<div class="heading">dojox.grid.Grid Column Display Toggling Test</div>
 	<div style="margin-top:20px;">Use header menu to change display of columns</div>
-	<div dojoType="dijit.Menu" jsid="gridMenu" id="gridMenu" style="display: none;">
+	<div dojoType="dijit.Menu" data-dojo-id="gridMenu" id="gridMenu" style="display: none;">
 		<div dojoType="dijit.MenuItem" onClick="alert('Hello world');">Enabled Item</div>
 		<div dojoType="dijit.MenuItem" disabled="true">Disabled Item</div>
 		<div dojoType="dijit.MenuSeparator"></div>
@@ -94,7 +94,7 @@
 			<span>Different popup</span>
 			<div dojoType="dijit.ColorPalette"></div>
 		</div>
-		<div dojoType="dijit.PopupMenuItem" jsid="popupItem1">
+		<div dojoType="dijit.PopupMenuItem" data-dojo-id="popupItem1">
 			<span>Show Columns</span>
 			<div dojoType="dijit.Menu" id="submenu4">
 				<div dojoType="dojox.widget.PlaceholderMenuItem" label="GridColumns"></div>
@@ -102,7 +102,7 @@
 		</div>
 	</div>
 
-	<div jsid="grid" id="grid" dojoType="dojox.grid.DataGrid" 
+	<div data-dojo-id="grid" id="grid" dojoType="dojox.grid.DataGrid"
 		columnToggling="true" store="test_store" query="{ id: '*' }" 
 		structure="layout" rowSelector="20px" headerMenu="gridMenu"></div>
 
@@ -110,7 +110,7 @@
 		Destroy third popup item
 	</button>
 	<div class="heading" style="margin-top:50px;">dojox.DataGrid with locked columns</div>
-	<div dojoType="dijit.Menu" jsid="gridMenu2" id="gridMenu2" style="display: none;">
+	<div dojoType="dijit.Menu" data-dojo-id="gridMenu2" id="gridMenu2" style="display: none;">
 		<div dojoType="dijit.MenuItem" onClick="alert('Hello world');">Enabled Item</div>
 		<div dojoType="dijit.MenuItem" disabled="true">Disabled Item</div>
 		<div dojoType="dijit.MenuSeparator"></div>
@@ -140,7 +140,7 @@
 			<span>Different popup</span>
 			<div dojoType="dijit.ColorPalette"></div>
 		</div>
-		<div dojoType="dijit.PopupMenuItem" jsid="popupItemX1">
+		<div dojoType="dijit.PopupMenuItem" data-dojo-id="popupItemX1">
 			<span>Show Columns</span>
 			<div dojoType="dijit.Menu" id="submenuX4">
 				<div dojoType="dojox.widget.PlaceholderMenuItem" label="GridColumns"></div>
@@ -149,7 +149,7 @@
 	</div>
 
 		<span dojoType="dojo.data.ItemFileReadStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	
 
diff --git a/dojox/grid/tests/test_grid_column_reorder.html b/dojox/grid/tests/test_grid_column_reorder.html
index 73fa24a..812b896 100644
--- a/dojox/grid/tests/test_grid_column_reorder.html
+++ b/dojox/grid/tests/test_grid_column_reorder.html
@@ -26,7 +26,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -54,7 +54,7 @@
 <body class="tundra">
 	<div class="heading">dojox.grid.Grid Column Reordering Test</div>
 
-	<div jsid="grid" id="grid" dojoType="dojox.grid.DataGrid" 
+	<div data-dojo-id="grid" id="grid" dojoType="dojox.grid.DataGrid"
 		columnReordering="true" store="test_store" query="{ id: '*' }" 
 		structure="layout" rowSelector="20px"></div>
 </body>
diff --git a/dojox/grid/tests/test_grid_csv_export.html b/dojox/grid/tests/test_grid_csv_export.html
index 8dfaabd..af891f4 100644
--- a/dojox/grid/tests/test_grid_csv_export.html
+++ b/dojox/grid/tests/test_grid_csv_export.html
@@ -25,7 +25,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -85,7 +85,7 @@
 	<button dojoType="dijit.form.Button" onClick="export_all">Export All</button>
 	<button dojoType="dijit.form.Button" onClick="export_selected">Export Selected</button>
 
-	<div jsId="grid" id="grid" dojoType="dojox.grid.DataGrid" 
+	<div data-dojo-id="grid" id="grid" dojoType="dojox.grid.DataGrid"
 		store="test_store" query="{ id: '*' }" 
 		structure="layout" rowSelector="20px"></div>
 
diff --git a/dojox/grid/tests/test_grid_dlg.html b/dojox/grid/tests/test_grid_dlg.html
index c9ea49d..9988ddd 100644
--- a/dojox/grid/tests/test_grid_dlg.html
+++ b/dojox/grid/tests/test_grid_dlg.html
@@ -24,12 +24,12 @@
 		#grid { 
 			border: 1px solid #333;
 			width: 400px;
-			height: 500px;
+			height: 500px !important;
 		}
 	</style>
 
     <script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
     
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
diff --git a/dojox/grid/tests/test_grid_formatters.html b/dojox/grid/tests/test_grid_formatters.html
index 0d4c586..60d1173 100644
--- a/dojox/grid/tests/test_grid_formatters.html
+++ b/dojox/grid/tests/test_grid_formatters.html
@@ -28,7 +28,7 @@
 	</style>
 	<script type="text/javascript" 
 		src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true">
+		data-dojo-config="isDebug: true, parseOnLoad: true">
 	</script>
 	<script type="text/javascript">
 		dojo.require("doh.runner");
@@ -129,9 +129,9 @@
 	</head>	
 	<body class="tundra">
 		<h1 class="testTitle">Test: dojox.tests.grid.Grid Formatters</h1>
-		<div dojoType="dojo.data.ItemFileReadStore" jsId="readStore" url="support/countryStore.json?"></div>
-		<div dojoType="dojox.grid.formatterScopeObj" store="readStore" jsId="myObject"></div>
-		<table dojoType="dojox.grid.DataGrid" jsId="grid" formatterScope="myObject" 
+		<div dojoType="dojo.data.ItemFileReadStore" data-dojo-id="readStore" url="support/countryStore.json?"></div>
+		<div dojoType="dojox.grid.formatterScopeObj" store="readStore" data-dojo-id="myObject"></div>
+		<table dojoType="dojox.grid.DataGrid" data-dojo-id="grid" formatterScope="myObject"
 				style="width: 65em;height: 25em;" store="readStore" queryOptions="{deep:true}" rowsPerPage="100">
 			<thead>
 				<tr>
diff --git a/dojox/grid/tests/test_grid_headerHeight.html b/dojox/grid/tests/test_grid_headerHeight.html
index e4adad9..07ea80b 100644
--- a/dojox/grid/tests/test_grid_headerHeight.html
+++ b/dojox/grid/tests/test_grid_headerHeight.html
@@ -25,7 +25,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -71,10 +71,10 @@
 </head>
 <body>
 	<div class="heading">dojox.grid.Grid Basic Test</div>
-	<div jsid="grid" id="grid" dojoType="dojox.grid.DataGrid" 
+	<div data-dojo-id="grid" id="grid" dojoType="dojox.grid.DataGrid"
 		store="test_store" structure="layout"></div>
 	<br /><br />
-	<div jsid="grid2" id="grid2" dojoType="dojox.grid._Grid" 
+	<div data-dojo-id="grid2" id="grid2" dojoType="dojox.grid._Grid"
 		structure="layout2" rowCount="50" rowSelector="20px"></div>
 </body>
 </html>
diff --git a/dojox/grid/tests/test_grid_hidden_rows.html b/dojox/grid/tests/test_grid_hidden_rows.html
index e52afd5..1fb5107 100644
--- a/dojox/grid/tests/test_grid_hidden_rows.html
+++ b/dojox/grid/tests/test_grid_hidden_rows.html
@@ -4,7 +4,7 @@
 	<title>Grid Bug</title>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 		
 		<!--<script type="text/javascript" src="dojo/dojo/grid.js"></script>--> 
 		
diff --git a/dojox/grid/tests/test_grid_layout.html b/dojox/grid/tests/test_grid_layout.html
index efb0d35..bf65aca 100644
--- a/dojox/grid/tests/test_grid_layout.html
+++ b/dojox/grid/tests/test_grid_layout.html
@@ -32,7 +32,7 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: false"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: false"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
diff --git a/dojox/grid/tests/test_grid_layout_LayoutContainer.html b/dojox/grid/tests/test_grid_layout_LayoutContainer.html
index a27f456..70726e1 100644
--- a/dojox/grid/tests/test_grid_layout_LayoutContainer.html
+++ b/dojox/grid/tests/test_grid_layout_LayoutContainer.html
@@ -31,7 +31,7 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: false"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: false"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
diff --git a/dojox/grid/tests/test_grid_layout_borderContainer.html b/dojox/grid/tests/test_grid_layout_borderContainer.html
index dd43d5e..2af4b07 100644
--- a/dojox/grid/tests/test_grid_layout_borderContainer.html
+++ b/dojox/grid/tests/test_grid_layout_borderContainer.html
@@ -20,7 +20,7 @@
 			}
 		</style>
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: false, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: false, parseOnLoad: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
@@ -64,11 +64,11 @@
 		     <button onclick="grid.singleClickEdit = !grid.singleClickEdit">Toggle singleClickEdit</button>
 		  </div>
 		
-		  <div jsId="grid" class="myGrid" dojoType="dojox.grid.DataGrid" store="test_store" structure="gridLayout"
+		  <div data-dojo-id="grid" class="myGrid" dojoType="dojox.grid.DataGrid" store="test_store" structure="gridLayout"
 		  	region="center">
 		  </div>
 
-		  <div jsId="gridBottom" class="myGrid"	dojoType="dojox.grid.DataGrid" store="test_store" structure="gridLayout"
+		  <div data-dojo-id="gridBottom" class="myGrid"	dojoType="dojox.grid.DataGrid" store="test_store" structure="gridLayout"
 		  	region="bottom" splitter="true" style="height: 100px;">
 		  </div>
 		   
diff --git a/dojox/grid/tests/test_grid_messages.html b/dojox/grid/tests/test_grid_messages.html
index 2041b81..82319bb 100644
--- a/dojox/grid/tests/test_grid_messages.html
+++ b/dojox/grid/tests/test_grid_messages.html
@@ -21,7 +21,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dojox.grid.DataGrid");
@@ -42,17 +42,17 @@
 </head>
 <body class="tundra">
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<span dojoType="dojox.grid.SlowFileWriteStore" 
-		jsId="jsonStore1" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore1" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore2" url="../../../dijit/tests/_data/countries-no.json">
+		data-dojo-id="jsonStore2" url="../../../dijit/tests/_data/countries-no.json">
 	</span>
 	<div class="heading">Grid Messaging Test - Standard</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" class="grid" 
+		data-dojo-id="grid" id="grid" class="grid"
 		store="jsonStore" query="{ name: 'A*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -63,7 +63,7 @@
 	</table><br>
 	<div class="heading">Grid Messaging Test - Loading</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid1" id="grid1" class="grid"
+		data-dojo-id="grid1" id="grid1" class="grid"
 		store="jsonStore1" query="{ name: 'A*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -74,7 +74,7 @@
 	</table><br>
 	<div class="heading">Grid Messaging Test - Empty</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid2" id="grid2" class="grid"
+		data-dojo-id="grid2" id="grid2" class="grid"
 		store="jsonStore" query="{ name: 'nonexist' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -85,7 +85,7 @@
 	</table>
 	<div class="heading">Grid Messaging Test - Error</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid3" id="grid3" class="grid"
+		data-dojo-id="grid3" id="grid3" class="grid"
 		store="jsonStore2" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_grid_messages_autoheight.html b/dojox/grid/tests/test_grid_messages_autoheight.html
index d1b4d12..4588798 100644
--- a/dojox/grid/tests/test_grid_messages_autoheight.html
+++ b/dojox/grid/tests/test_grid_messages_autoheight.html
@@ -22,7 +22,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dojox.grid.DataGrid");
@@ -43,17 +43,17 @@
 </head>
 <body class="tundra">
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<span dojoType="dojox.grid.SlowFileWriteStore" 
-		jsId="jsonStore1" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore1" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore2" url="../../../dijit/tests/_data/countries-no.json">
+		data-dojo-id="jsonStore2" url="../../../dijit/tests/_data/countries-no.json">
 	</span>
 	<div class="heading">Grid Messaging Test - Standard</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid" id="grid" class="grid" autoHeight="true"
+		data-dojo-id="grid" id="grid" class="grid" autoHeight="true"
 		store="jsonStore" query="{ name: 'A*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -64,7 +64,7 @@
 	</table><br>
 	<div class="heading">Grid Messaging Test - Loading</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid1" id="grid1" class="grid" autoHeight="true"
+		data-dojo-id="grid1" id="grid1" class="grid" autoHeight="true"
 		store="jsonStore1" query="{ name: 'A*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -75,7 +75,7 @@
 	</table><br>
 	<div class="heading">Grid Messaging Test - Empty</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid2" id="grid2" class="grid" autoHeight="true"
+		data-dojo-id="grid2" id="grid2" class="grid" autoHeight="true"
 		store="jsonStore" query="{ name: 'nonexist' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
@@ -86,7 +86,7 @@
 	</table>
 	<div class="heading">Grid Messaging Test - Error</div>
 	<table dojoType="dojox.grid.DataGrid"
-		jsid="grid3" id="grid3" class="grid" autoHeight="true"
+		data-dojo-id="grid3" id="grid3" class="grid" autoHeight="true"
 		store="jsonStore2" query="{ name: '*' }" rowsPerPage="20" rowSelector="20px">
 		<thead>
 			<tr>
diff --git a/dojox/grid/tests/test_grid_performance.html b/dojox/grid/tests/test_grid_performance.html
index 35d99ec..d5358bd 100644
--- a/dojox/grid/tests/test_grid_performance.html
+++ b/dojox/grid/tests/test_grid_performance.html
@@ -18,7 +18,7 @@
 			padding-bottom: 0.25em;
 		}
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:false"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:false"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dojox.grid.DataGrid");
diff --git a/dojox/grid/tests/test_grid_programmatic.html b/dojox/grid/tests/test_grid_programmatic.html
index 8490949..9470f30 100644
--- a/dojox/grid/tests/test_grid_programmatic.html
+++ b/dojox/grid/tests/test_grid_programmatic.html
@@ -20,7 +20,7 @@
 			}
 		</style>
 		<script type="text/javascript" src="../../../dojo/dojo.js" 
-			djConfig="isDebug:false, debugAtAllCosts: false, parseOnLoad: true"></script>
+			data-dojo-config="isDebug:false, debugAtAllCosts: false, parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dojox.grid.DataGrid");
diff --git a/dojox/grid/tests/test_grid_programmatic_layout.html b/dojox/grid/tests/test_grid_programmatic_layout.html
index 693f5c2..702e465 100644
--- a/dojox/grid/tests/test_grid_programmatic_layout.html
+++ b/dojox/grid/tests/test_grid_programmatic_layout.html
@@ -21,7 +21,7 @@
 			}
 		</style>
 		<script type="text/javascript" src="../../../dojo/dojo.js" 
-			djConfig="isDebug:false, debugAtAllCosts: false, parseOnLoad: true"></script>
+			data-dojo-config="isDebug:false, debugAtAllCosts: false, parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dijit.layout.TabContainer");
diff --git a/dojox/grid/tests/test_grid_programmatic_leak_test.html b/dojox/grid/tests/test_grid_programmatic_leak_test.html
index 7b4274e..10f6dfe 100644
--- a/dojox/grid/tests/test_grid_programmatic_leak_test.html
+++ b/dojox/grid/tests/test_grid_programmatic_leak_test.html
@@ -21,7 +21,7 @@
 			}
 		</style>
 		<script type="text/javascript" src="../../../dojo/dojo.js" 
-			djConfig="isDebug:false, debugAtAllCosts: false, parseOnLoad: true"></script>
+			data-dojo-config="isDebug:false, debugAtAllCosts: false, parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dojox.grid.DataGrid");
diff --git a/dojox/grid/tests/test_grid_rtl.html b/dojox/grid/tests/test_grid_rtl.html
index 6c218ec..a9a2546 100644
--- a/dojox/grid/tests/test_grid_rtl.html
+++ b/dojox/grid/tests/test_grid_rtl.html
@@ -27,7 +27,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
diff --git a/dojox/grid/tests/test_grid_selectors.html b/dojox/grid/tests/test_grid_selectors.html
index 62bf66e..7420263 100644
--- a/dojox/grid/tests/test_grid_selectors.html
+++ b/dojox/grid/tests/test_grid_selectors.html
@@ -25,7 +25,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -70,15 +70,15 @@
 </head>
 <body class="tundra">
 	<div class="heading">dojox.grid.Grid CheckBox Selector</div>
-	<div jsId="grid_check" id="grid_check" dojoType="dojox.grid.DataGrid" 
+	<div data-dojo-id="grid_check" id="grid_check" dojoType="dojox.grid.DataGrid"
 		store="test_store" query="{ id: '*' }" 
 		structure="layout_check"></div>
 	<div class="heading">dojox.grid.Grid Radio Selector</div>
-	<div jsId="grid_radio" id="grid_radio" dojoType="dojox.grid.DataGrid" 
+	<div data-dojo-id="grid_radio" id="grid_radio" dojoType="dojox.grid.DataGrid"
 		store="test_store" query="{ id: '*' }" 
 		structure="layout_radio"></div>
 	<div class="heading">dojox.grid.Grid CheckBox Selector - no data</div>
-	<div jsId="grid_empty" id="grid_empty" dojoType="dojox.grid.DataGrid" 
+	<div data-dojo-id="grid_empty" id="grid_empty" dojoType="dojox.grid.DataGrid"
 		store="test_store" query="{ id: 'abc' }" 
 		structure="layout_check"></div>
 </body>
diff --git a/dojox/grid/tests/test_grid_simple_structure.html b/dojox/grid/tests/test_grid_simple_structure.html
index 50a33dc..6ad690a 100644
--- a/dojox/grid/tests/test_grid_simple_structure.html
+++ b/dojox/grid/tests/test_grid_simple_structure.html
@@ -26,7 +26,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -45,7 +45,7 @@
 </head>
 <body>
 	<div class="heading">dojox.grid.Grid Basic Test</div>
-	<div jsid="grid" id="grid" dojoType="dojox.grid.DataGrid" 
+	<div data-dojo-id="grid" id="grid" dojoType="dojox.grid.DataGrid"
 		store="test_store" structure="layout"></div>
 </body>
 </html>
diff --git a/dojox/grid/tests/test_grid_simple_structure2.html b/dojox/grid/tests/test_grid_simple_structure2.html
index f266fa8..37a00a0 100644
--- a/dojox/grid/tests/test_grid_simple_structure2.html
+++ b/dojox/grid/tests/test_grid_simple_structure2.html
@@ -25,7 +25,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -49,7 +49,7 @@
 </head>
 <body>
 	<div class="heading">dojox.grid.Grid Basic Test</div>
-	<div jsid="grid" id="grid" dojoType="dojox.grid.DataGrid" 
+	<div data-dojo-id="grid" id="grid" dojoType="dojox.grid.DataGrid"
 		store="test_store" structure="layout"></div>
 </body>
 </html>
diff --git a/dojox/grid/tests/test_grid_tab_container.html b/dojox/grid/tests/test_grid_tab_container.html
index adb4a32..4798e20 100644
--- a/dojox/grid/tests/test_grid_tab_container.html
+++ b/dojox/grid/tests/test_grid_tab_container.html
@@ -6,7 +6,7 @@
 
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
-		@import "../css/dijitTests.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
 
 		body {
 			font-family : sans-serif;
@@ -25,10 +25,10 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
+	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
@@ -102,7 +102,7 @@
 			<br/>
 			
 			
-			<div jsid="grid" id="grid" dojoType="dojox.grid.DataGrid" store="test_store" query="{ id: '*' }" structure="layout" rowSelector="20px"></div>
+			<div data-dojo-id="grid" id="grid" dojoType="dojox.grid.DataGrid" store="test_store" query="{ id: '*' }" structure="layout" rowSelector="20px"></div>
 		</div>
 
 		
diff --git a/dojox/grid/tests/test_grid_themes.html b/dojox/grid/tests/test_grid_themes.html
index 51d631e..485ad58 100644
--- a/dojox/grid/tests/test_grid_themes.html
+++ b/dojox/grid/tests/test_grid_themes.html
@@ -19,7 +19,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -33,7 +33,7 @@
 <body>
 	<h5>dojox.grid.Grid structure from markup (tundra theme)</h5>
 	<span dojoType="dojox.data.CsvStore" 
-		jsId="csvStore" url="support/movies.csv">
+		data-dojo-id="csvStore" url="support/movies.csv">
 	</span>
 
 	<table class="tundra" dojoType="dojox.grid.DataGrid"
@@ -53,7 +53,7 @@
 	</table>
 
 	<span dojoType="dojo.data.ItemFileReadStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<h5>Locked views specified with tables and colgroups (soria theme)</h5>
 
diff --git a/dojox/grid/tests/test_grid_tooltip_menu.html b/dojox/grid/tests/test_grid_tooltip_menu.html
index 2c03da5..a8b1c5d 100644
--- a/dojox/grid/tests/test_grid_tooltip_menu.html
+++ b/dojox/grid/tests/test_grid_tooltip_menu.html
@@ -27,7 +27,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
@@ -160,7 +160,7 @@
 		<input type="button" onclick="toggleMenu(this)" value="Disable Grid Menu">  <br />
 		Note: when the grid menu is disabled, the document's dijit context menu should be shown over the grid.
 	</p>
-	<div id="grid" jsid="grid" dojoType="dojox.grid.DataGrid" 
+	<div id="grid" data-dojo-id="grid" dojoType="dojox.grid.DataGrid"
 		store="test_store" structure="layout"></div>
 </body>
 </html>
diff --git a/dojox/grid/tests/test_keyboard.html b/dojox/grid/tests/test_keyboard.html
index 7e0e6af..dd21fd8 100644
--- a/dojox/grid/tests/test_keyboard.html
+++ b/dojox/grid/tests/test_keyboard.html
@@ -26,7 +26,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -73,9 +73,9 @@
 </head>
 <body class="tundra">
 	<div class="heading" tabindex="0">dojox.grid.Grid Basic Test</div>
-	<div id="grid" jsid="grid" dojoType="dojox.grid.DataGrid" 
+	<div id="grid" data-dojo-id="grid" dojoType="dojox.grid.DataGrid"
 		store="test_store" structure="layout">
-		<script type="dojo/connect" event="onKeyDown" args="e">
+		<script type="dojo/connect" data-dojo-event="onKeyDown" data-dojo-args="e">
 			keyDown(e);
 		</script>
 	</div>
diff --git a/dojox/grid/tests/test_markup.html b/dojox/grid/tests/test_markup.html
index a236cf1..60a6b1b 100644
--- a/dojox/grid/tests/test_markup.html
+++ b/dojox/grid/tests/test_markup.html
@@ -16,7 +16,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, debugAtAllCosts: false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -28,7 +28,7 @@
 <body class="tundra">
 	<h5>dojox.grid.Grid structure from markup</h5>
 	<span dojoType="dojox.data.CsvStore" 
-		jsId="csvStore" url="support/movies.csv">
+		data-dojo-id="csvStore" url="support/movies.csv">
 	</span>
 
 	<table dojoType="dojox.grid.DataGrid"
@@ -49,7 +49,7 @@
 
 
 	<span dojoType="dojo.data.ItemFileReadStore" 
-		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
+		data-dojo-id="jsonStore" url="../../../dijit/tests/_data/countries.json">
 	</span>
 	<h5>Locked views specified with tables and colgroups</h5>
 
diff --git a/dojox/grid/tests/test_mysql_edit.html b/dojox/grid/tests/test_mysql_edit.html
index b5b02d5..58f2b28 100644
--- a/dojox/grid/tests/test_mysql_edit.html
+++ b/dojox/grid/tests/test_mysql_edit.html
@@ -17,7 +17,7 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -137,7 +137,7 @@
 	<button onclick="grid.edit.cancel()">Cancel Edit</button>  
 	<button onclick="grid.render()">Refresh</button>
 	<br><br>
-	<div jsId="grid" class="grid" structure="gridLayout" dojoType="dojox.grid.Grid" 
+	<div data-dojo-id="grid" class="grid" structure="gridLayout" dojoType="dojox.grid.Grid"
 		store="model" singleClickEdit="true" autoWidth="true"></div>
 	<div id="rowCount"></div>
 	<p>Note: This test requires MySql and PHP and works with the database table available in support/testtbl.sql.</p>
diff --git a/dojox/grid/tests/test_selection.html b/dojox/grid/tests/test_selection.html
index 744c43f..4424859 100644
--- a/dojox/grid/tests/test_selection.html
+++ b/dojox/grid/tests/test_selection.html
@@ -25,7 +25,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -51,19 +51,19 @@
 <body class="tundra">
 	<h2>dojox.grid.Grid Selection Models Test</h2>
 	<h3>none</h3>
-	<div jsid="grid1" id="grid1" dojoType="dojox.grid.DataGrid" selectionMode="none"
+	<div data-dojo-id="grid1" id="grid1" dojoType="dojox.grid.DataGrid" selectionMode="none"
 		store="test_store" query="{ id: '*' }" structure="layout">
 	</div>
 	<h3>Single</h3>
-	<div jsid="grid2" id="grid2" dojoType="dojox.grid.DataGrid" selectionMode="single"
+	<div data-dojo-id="grid2" id="grid2" dojoType="dojox.grid.DataGrid" selectionMode="single"
 		store="test_store" query="{ id: '*' }" structure="layout">
 	</div>
 	<h3>Multiple</h3>
-	<div jsid="grid3" id="grid3" dojoType="dojox.grid.DataGrid" selectionMode="multiple"
+	<div data-dojo-id="grid3" id="grid3" dojoType="dojox.grid.DataGrid" selectionMode="multiple"
 		store="test_store" query="{ id: '*' }" structure="layout">
 	</div>
 	<h3>Extended</h3>
-	<div jsid="grid4" id="grid4" dojoType="dojox.grid.DataGrid" selectionMode="extended"
+	<div data-dojo-id="grid4" id="grid4" dojoType="dojox.grid.DataGrid" selectionMode="extended"
 		store="test_store" query="{ id: '*' }" structure="layout">
 	</div>
 </body>
diff --git a/dojox/grid/tests/test_sizing.html b/dojox/grid/tests/test_sizing.html
index aa6cd7a..dc8a8e9 100644
--- a/dojox/grid/tests/test_sizing.html
+++ b/dojox/grid/tests/test_sizing.html
@@ -25,7 +25,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -117,13 +117,13 @@
 	<button onclick="fitHeight()">Fit Data Height</button> 
 	<button onclick="fitBoth()">Fit Data Width & Height</button>
 	<button onclick="sizeDefault()">DefaultSize</button><br><br>
-	<div id="grid" jsid="grid" dojoType="dojox.grid.DataGrid" 
+	<div id="grid" data-dojo-id="grid" dojoType="dojox.grid.DataGrid"
 		autoWidth="true" autoHeight="true" store="test_store" 
 		structure="structure" elasticView="2"></div>
 	
 	<p>Grid fits to a sized container by default:</p>
 	<div id="container">
-		<div id="grid1" jsid="grid1" dojoType="dojox.grid._Grid" 
+		<div id="grid1" data-dojo-id="grid1" dojoType="dojox.grid._Grid"
 			get="get" structure="structure" rowCount="10" elasticView="2"></div>
 	</div>
 
diff --git a/dojox/grid/tests/test_sizing_100rows.html b/dojox/grid/tests/test_sizing_100rows.html
index 641ac5c..030ed3d 100644
--- a/dojox/grid/tests/test_sizing_100rows.html
+++ b/dojox/grid/tests/test_sizing_100rows.html
@@ -29,7 +29,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -121,13 +121,13 @@
 	<button onclick="fitHeight()">Fit Data Height</button> 
 	<button onclick="fitBoth()">Fit Data Width & Height</button>
 	<button onclick="sizeDefault()">DefaultSize</button><br><br>
-	<div id="grid" jsid="grid" dojoType="dojox.grid.DataGrid" 
+	<div id="grid" data-dojo-id="grid" dojoType="dojox.grid.DataGrid"
 		autoWidth="true" autoHeight="true" store="test_store" 
 		structure="structure" rowSelector="20px" elasticView="2"></div>
 	
 	<p>Grid fits to a sized container by default:</p>
 	<div id="container">
-		<div id="grid1" jsid="grid1" dojoType="dojox.grid._Grid" 
+		<div id="grid1" data-dojo-id="grid1" dojoType="dojox.grid._Grid"
 			get="get" structure="structure" rowCount="10" 
 			rowSelector="20px" elasticView="2"></div>
 	</div>
diff --git a/dojox/grid/tests/test_sizing_ResizeHandle.html b/dojox/grid/tests/test_sizing_ResizeHandle.html
index 74052c4..cbd3bbf 100644
--- a/dojox/grid/tests/test_sizing_ResizeHandle.html
+++ b/dojox/grid/tests/test_sizing_ResizeHandle.html
@@ -32,7 +32,7 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dojox.grid.DataGrid");
@@ -82,7 +82,7 @@
 	<p>While this test should work, dojox.layout.ResizeHandle is experimental.</p>
 	
 	<div id="bar" style="position:relative">
-		<div jsId="aGrid" id="grid" dojoType="dojox.grid.DataGrid" 
+		<div data-dojo-id="aGrid" id="grid" dojoType="dojox.grid.DataGrid"
 			store="test_store" rowSelector="20px" 
 			structure="structure" elasticView="2"></div>
 		<div id="hand0"></div>
@@ -90,7 +90,7 @@
 	
 	<p>Grid fits to a sized container by default:</p>
 	<div id="container" style="position:relative">
-		<div jsId="theGrid" id="grid1" dojoType="dojox.grid._Grid" 
+		<div data-dojo-id="theGrid" id="grid1" dojoType="dojox.grid._Grid"
 			get="get" rowSelector="20px" structure="structure" 
 			rowCount="75" elasticView="2"></div>
 		<div id="hand1" dojoType="dojox.layout.ResizeHandle" 
diff --git a/dojox/grid/tests/test_styling.html b/dojox/grid/tests/test_styling.html
index c819a93..09e6d82 100644
--- a/dojox/grid/tests/test_styling.html
+++ b/dojox/grid/tests/test_styling.html
@@ -73,7 +73,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -121,7 +121,7 @@
 </head>
 <body>
 	<div class="heading">dojox.grid.Grid Styling Example</div>
-	<div id="grid" jsid="grid" dojoType="dojox.grid.DataGrid" 
+	<div id="grid" data-dojo-id="grid" dojoType="dojox.grid.DataGrid"
 		onStyleRow="onStyleRow" store="test_store" structure="structure"></div>
 </body>
 </html>
diff --git a/dojox/grid/tests/test_subgrid.html b/dojox/grid/tests/test_subgrid.html
index 08ac3d3..bfee2ed 100644
--- a/dojox/grid/tests/test_subgrid.html
+++ b/dojox/grid/tests/test_subgrid.html
@@ -30,7 +30,7 @@
 	</style>
 	
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:true, debugAtAllCosts: false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:true, debugAtAllCosts: false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.grid.DataGrid");
 		dojo.require("dojo.data.ItemFileWriteStore");
diff --git a/dojox/grid/tests/test_treegrid.html b/dojox/grid/tests/test_treegrid.html
index 0967bb7..7ea9173 100644
--- a/dojox/grid/tests/test_treegrid.html
+++ b/dojox/grid/tests/test_treegrid.html
@@ -13,7 +13,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.grid.TreeGrid");
 		dojo.require("dojo.data.ItemFileWriteStore");
@@ -88,11 +88,11 @@
 <body class="claro">
 	<h1 class="testTitle">Test: dojox.tests.grid.TreeGrid</h1>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
-		jsId="jsonStore" url="support/gamedata.json">
+		data-dojo-id="jsonStore" url="support/gamedata.json">
 	</span>
 
 	<h4 class="testSubtitle">dojox.grid.TreeGrid 1-Level</h4>
-	<table dojoType="dojox.grid.TreeGrid" class="grid"
+	<table dojoType="dojox.grid.TreeGrid" class="grid"  summary="A customized tree grid summary"
 		store="jsonStore" query="{ id: '4' }" queryOptions="{deep: true}" rowsPerPage="20" rowSelector="true">
 		<thead>
 			<tr>
@@ -206,7 +206,7 @@
 
 	<h4 class="testSubtitle">dojox.grid.TreeGrid Large 4-Level - calculated totals and openAtLevels</h4>
 	<table dojoType="dojox.grid.TreeGrid" class="grid" style="height: 45em;width: 100%;"
-		store="jsonStore" rowsPerPage="20" jsId="grid4" rowSelector="true" openAtLevels="false,true,3">
+		store="jsonStore" rowsPerPage="20" data-dojo-id="grid4" rowSelector="true" openAtLevels="false,true,3">
 		<thead>
 			<tr>
 				<th field="label" relWidth="2">Player</th>
diff --git a/dojox/grid/tests/test_treegrid_lazyloading.html b/dojox/grid/tests/test_treegrid_lazyloading.html
index c77121f..c6a94c1 100644
--- a/dojox/grid/tests/test_treegrid_lazyloading.html
+++ b/dojox/grid/tests/test_treegrid_lazyloading.html
@@ -30,7 +30,7 @@
 				border: 1px solid #333333;
             }
         </style>
-        <script type="text/javascript" src="../../../dojo/dojo.js"  djConfig="isDebug:true, parseOnLoad: true"></script>
+        <script type="text/javascript" src="../../../dojo/dojo.js"  data-dojo-config="isDebug:true, parseOnLoad: true"></script>
         <script type="text/javascript">
             dojo.require("dojox.grid.LazyTreeGrid");
 			dojo.require("dojo.data.ItemFileWriteStore");
@@ -150,11 +150,11 @@
     <body class="claro">
         <h1 class="title">Test: dojox.grid.TreeGrid - Lazy-loading for children items</h1>
 		<h2>grid 1</h2>
-		<div id='grid1' jsid='grid1' dojoType='dojox.grid.LazyTreeGrid' 
+		<div id='grid1' data-dojo-id='grid1' dojoType='dojox.grid.LazyTreeGrid' summary="A customized tree grid summary"
 				structure='layout' treeModel='model1' rowSelector='true'></div>
 				
 		<h2>grid 2</h2>
-		<div id='grid2' jsid='grid2' dojoType='dojox.grid.LazyTreeGrid'
+		<div id='grid2' data-dojo-id='grid2' dojoType='dojox.grid.LazyTreeGrid'
 				structure='layout' treeModel='model2' 
 				keepSelection='true' rowSelector='true'></div>
 		
diff --git a/dojox/grid/tests/test_treegrid_loading.html b/dojox/grid/tests/test_treegrid_loading.html
index 8339124..1e6f05b 100644
--- a/dojox/grid/tests/test_treegrid_loading.html
+++ b/dojox/grid/tests/test_treegrid_loading.html
@@ -13,7 +13,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: false"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: false"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.grid.TreeGrid");
 		dojo.require("dojox.data.JsonRestStore");
@@ -116,7 +116,7 @@
 	<h1 class="testTitle">Test: dojox.tests.grid.TreeGrid</h1>
 	<h4 class="testSubtitle">dojox.grid.TreeGrid Large 4-Level - calculated totals and openAtLevels</h4>
 	<table dojoType="dojox.grid.TreeGrid" class="grid" style="height: 45em;width: 100%;"
-		store="store" rowsPerPage="20" jsId="grid" rowSelector="true" openAtLevels="false,true,3">
+		store="store" rowsPerPage="20" data-dojo-id="grid" rowSelector="true" openAtLevels="false,true,3">
 			<thead>
 				<tr>
 					<th field="label" relWidth="2" formatter="seasonSummary">Players</th>
diff --git a/dojox/grid/tests/test_treegrid_model.html b/dojox/grid/tests/test_treegrid_model.html
index 00c994b..58917b3 100644
--- a/dojox/grid/tests/test_treegrid_model.html
+++ b/dojox/grid/tests/test_treegrid_model.html
@@ -13,7 +13,7 @@
                 height: 40em;
             }
         </style>
-        <script type="text/javascript" src="../../../dojo/dojo.js"  djConfig="isDebug:true, parseOnLoad: true"></script>
+        <script type="text/javascript" src="../../../dojo/dojo.js"  data-dojo-config="isDebug:true, parseOnLoad: true"></script>
         <script type="text/javascript">
             dojo.require("dojox.grid.TreeGrid");
             dojo.require("dijit.tree.ForestStoreModel");
@@ -108,24 +108,24 @@
     <body class="claro">
         <h1 class="testTitle">Test: dojox.grid.TreeGrid - Model-based</h1>
         <span dojoType="dojo.data.ItemFileWriteStore"
-              jsId="jsonStore" data="dataItems">
+              data-dojo-id="jsonStore" data="dataItems">
         </span>
 
-        <div dojoType="dijit.tree.ForestStoreModel" jsId="continentModel"
+        <div dojoType="dijit.tree.ForestStoreModel" data-dojo-id="continentModel"
         store="jsonStore" query="{type:'continent'}"
         rootId="continentRoot" rootLabel="Continents" childrenAttrs="children"></div>
 
         <h4 class="testSubtitle">dojox.grid.TreeGrid n-Level</h4>
         <button dojoType="dijit.form.Button">
             Add Belgium
-            <script type="dojo/connect" event="onClick">
+            <script type="dojo/connect" data-dojo-event="onClick">
                 add_item({ id: 'EU_BE', name: 'Belgium', type: 'country' }, "EU");
 				this.set("disabled", true);
             </script>
         </button>
         <button dojoType="dijit.form.Button">
             Delete Italy
-            <script type="dojo/connect" event="onClick">
+            <script type="dojo/connect" data-dojo-event="onClick">
 				jsonStore.fetchItemByIdentity({
 					identity: 'IT',
 					onItem: function(item){
@@ -139,15 +139,15 @@
         </button>
         <button dojoType="dijit.form.Button">
             Add California
-            <script type="dojo/connect" event="onClick">
+            <script type="dojo/connect" data-dojo-event="onClick">
                 add_item({ id: 'US_CA', name: 'California', type: 'state' }, "US");
 				delCal.attr("disabled", false);
 				this.set("disabled", true);
             </script>
         </button>
-        <button dojoType="dijit.form.Button" disabled jsId="delCal">
+        <button dojoType="dijit.form.Button" disabled data-dojo-id="delCal">
             Delete California
-            <script type="dojo/connect" event="onClick">
+            <script type="dojo/connect" data-dojo-event="onClick">
 				jsonStore.fetchItemByIdentity({
 					identity: 'US_CA',
 					onItem: function(item){
@@ -159,9 +159,9 @@
 				this.set("disabled", true);
             </script>
         </button>
-        <button dojoType="dijit.form.Button" jsId="delEU">
+        <button dojoType="dijit.form.Button" data-dojo-id="delEU">
             Delete Europe
-            <script type="dojo/connect" event="onClick">
+            <script type="dojo/connect" data-dojo-event="onClick">
 				jsonStore.fetchItemByIdentity({
 					identity: 'EU',
 					onItem: function(item){
@@ -173,9 +173,9 @@
 				this.set("disabled", true);
             </script>
         </button>
-        <button dojoType="dijit.form.Button" jsId="empty">
+        <button dojoType="dijit.form.Button" data-dojo-id="empty">
             Empty
-            <script type="dojo/connect" event="onClick">
+            <script type="dojo/connect" data-dojo-event="onClick">
 				jsonStore.fetch({
 					query: { id: '*' },
 					queryOptions: { deep: true },
@@ -191,7 +191,7 @@
 				this.set("disabled", true);
             </script>
         </button>
-        <table jsid="grid" dojoType="dojox.grid.TreeGrid" class="grid" treeModel="continentModel">
+        <table data-dojo-id="grid" dojoType="dojox.grid.TreeGrid" class="grid" treeModel="continentModel">
             <thead>
                 <tr>
                     <th field="name" width="auto">Name</th>
diff --git a/dojox/grid/tests/test_treegrid_model_lazy.html b/dojox/grid/tests/test_treegrid_model_lazy.html
index f697140..ccb1aa3 100644
--- a/dojox/grid/tests/test_treegrid_model_lazy.html
+++ b/dojox/grid/tests/test_treegrid_model_lazy.html
@@ -13,7 +13,7 @@
                 height: 40em;
             }
         </style>
-        <script type="text/javascript" src="../../../dojo/dojo.js"  djConfig="isDebug:true, parseOnLoad: false"></script>
+        <script type="text/javascript" src="../../../dojo/dojo.js"  data-dojo-config="isDebug:true, parseOnLoad: false"></script>
         <script type="text/javascript">
             dojo.require("dojox.grid.TreeGrid");
             dojo.require("dijit.tree.ForestStoreModel");
@@ -88,14 +88,14 @@
     <body class="tundra">
         <h1 class="testTitle">Test: dojox.grid.TreeGrid - Model-based lazy loading</h1>
 
-        <div dojoType="dijit.tree.ForestStoreModel" jsId="continentModel"
+        <div dojoType="dijit.tree.ForestStoreModel" data-dojo-id="continentModel"
 			store="jsonStore" query="{type:'continent'}"
 			deferItemLoadingUntilExpand="true"
 			rootId="continentRoot" rootLabel="Continents" childrenAttrs="children">
 		</div>
 
         <h4 class="testSubtitle">dojox.grid.TreeGrid n-Level</h4>
-        <table jsid="grid" dojoType="dojox.grid.TreeGrid" class="grid" treeModel="continentModel">
+        <table data-dojo-id="grid" dojoType="dojox.grid.TreeGrid" class="grid" treeModel="continentModel">
             <thead>
                 <tr>
                     <th field="name" width="auto">Name</th>
diff --git a/dojox/grid/tests/test_treegrid_performance.html b/dojox/grid/tests/test_treegrid_performance.html
index 4bbf327..f3ec419 100644
--- a/dojox/grid/tests/test_treegrid_performance.html
+++ b/dojox/grid/tests/test_treegrid_performance.html
@@ -13,7 +13,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: false"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: false"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.grid.DataGrid");
 		dojo.require("dojox.grid.TreeGrid");
@@ -139,7 +139,7 @@
 	<h1 class="testTitle">
 		Test: dojox.tests.grid.TreeGrid Performance
 		<span dojoType="dojo.data.ItemFileWriteStore" 
-			jsId="jsonStore" url="support/gamedata.json">
+			data-dojo-id="jsonStore" url="support/gamedata.json">
 		</span>
 	</h1>
 
diff --git a/dojox/grid/tests/test_tundra_edit.html b/dojox/grid/tests/test_tundra_edit.html
index 51cf97f..d9260b6 100644
--- a/dojox/grid/tests/test_tundra_edit.html
+++ b/dojox/grid/tests/test_tundra_edit.html
@@ -38,7 +38,7 @@
 			}
 		</style>
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug:false, parseOnLoad: true"></script>
+			data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dijit.dijit");
 			dojo.require("dojox.grid.DataGrid");
@@ -110,7 +110,7 @@
 			<button onclick="grid.singleClickEdit = !grid.singleClickEdit">Toggle singleClickEdit</button>
 		</div>
 		<br />
-		<div jsId="grid" class="myGrid" 
+		<div data-dojo-id="grid" class="myGrid"
 			dojoType="dojox.grid.DataGrid" store="test_store" 
 			structure="gridLayout" rowSelector="20px"></div>
 		<br />
diff --git a/dojox/grid/tests/test_yahoo_images.html b/dojox/grid/tests/test_yahoo_images.html
index 3252ebc..fc09cd6 100644
--- a/dojox/grid/tests/test_yahoo_images.html
+++ b/dojox/grid/tests/test_yahoo_images.html
@@ -18,7 +18,7 @@
 		#info { width: 700px; }
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="debugAtAllCosts: false, isDebug:false, parseOnLoad: true">
+		data-dojo-config="debugAtAllCosts: false, isDebug:false, parseOnLoad: true">
 	</script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
@@ -68,7 +68,7 @@
 	<input id="searchInput" type="text" value="apple">
 	<button onclick="doSearch()" style="clear: both;">Search</button>
 	<div dojoType="dojox.grid.DataGrid" 
-		id="grid" jsId="grid" class="grid" structure="imageLayout" 
+		id="grid" data-dojo-id="grid" class="grid" structure="imageLayout"
 		store="store" elasticView="1" query="{ query: 'apple' }" 
 		rowSelector="20px">
 	</div>
diff --git a/dojox/grid/tests/test_yahoo_search.html b/dojox/grid/tests/test_yahoo_search.html
index 9450dae..2b48531 100644
--- a/dojox/grid/tests/test_yahoo_search.html
+++ b/dojox/grid/tests/test_yahoo_search.html
@@ -19,7 +19,7 @@
 		}
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
-		djConfig="isDebug:false, parseOnLoad: true"></script>
+		data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit");
 		dojo.require("dojox.grid.DataGrid");
@@ -113,7 +113,7 @@
 	<input id="searchInput" type="text" value="apple">  
 	<button onclick="doSearch()">Search</button><br><br>
 	<div dojoType="dojox.grid.DataGrid" 
-		jsId="grid" class="grid" id="grid"
+		data-dojo-id="grid" class="grid" id="grid"
 		autoWidth="true" structure="webLayout" 
 		store="store" elasticView="1" 
 		query="{ query: 'apple' }" 
diff --git a/dojox/grid/util.js b/dojox/grid/util.js
index 1b431bd..0e54959 100644
--- a/dojox/grid/util.js
+++ b/dojox/grid/util.js
@@ -4,9 +4,15 @@ define([
 	"dojo/dom"
 ], function(dojox, lang, dom){
 
-// summary: grid utility library
 	var dgu = lang.getObject("grid.util", true, dojox);
 
+/*=====
+dgu = {
+	// summary:
+	//		grid utility library
+};
+=====*/
+
 	dgu.na = '...';
 	dgu.rowIndexTag = "gridRowIndex";
 	dgu.gridViewTag = "gridView";
@@ -69,6 +75,6 @@ define([
 		inArray[inJ] = cache;
 	};
 
-	return dojox.grid.util;
+	return dgu;
 
 });
\ No newline at end of file
diff --git a/dojox/help/_base.js b/dojox/help/_base.js
index 510aae2..90e89ce 100644
--- a/dojox/help/_base.js
+++ b/dojox/help/_base.js
@@ -11,10 +11,10 @@ dojox.help = {
 	locate: function(/*String*/ searchFor, /*String|Object|String[]|Object[]*/ searchIn, /*Number*/ maxResults){
 		// summary:
 		//		Search for dojo functionality that has something to do with the given string.
-		//  description:
+		// description:
 		//		Search for locally available data; variable names and any cached
 		//		documentation results for matches containing our search parameter
-		// searchFor
+		// searchFor:
 		//		The string to search for.
 		// searchIn:
 		//		The namespaces to search in. Defaults to dojox.help._namespaces
diff --git a/dojox/help/demos/demo_Console.html b/dojox/help/demos/demo_Console.html
index ce33546..0c36d3b 100644
--- a/dojox/help/demos/demo_Console.html
+++ b/dojox/help/demos/demo_Console.html
@@ -1,7 +1,7 @@
 <html>
 	<head>
 		<title>Simple demo of dojox.help.console</title>
-		<script src="../../../dojo/dojo.js" type="text/javascript" djConfig="isDebug: true"></script>
+		<script src="../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.addOnLoad(function(){
 				dojo.query("code").onclick(function(e){
diff --git a/dojox/highlight.js b/dojox/highlight.js
index 5c30eb2..17de276 100644
--- a/dojox/highlight.js
+++ b/dojox/highlight.js
@@ -1,3 +1,10 @@
 define(["./highlight/_base"], function(highlight){
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/highlight modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
 	return highlight;
 });
diff --git a/dojox/highlight/_base.js b/dojox/highlight/_base.js
index 64bef1d..b26c64a 100644
--- a/dojox/highlight/_base.js
+++ b/dojox/highlight/_base.js
@@ -1,22 +1,25 @@
-define(["dojo", "dojox/main"], function(dojo, dojox){
+define([
+	"dojo/_base/lang", 
+	"dojo/_base/array", 
+	"dojo/dom", 
+	"dojo/dom-class"
+], function(lang, array, dom, domClass){
 
-	/*=====
-		dojox.highlight = {
-			//	summary:
-			//		Syntax highlighting with language auto-detection package
-			//
-			//	description:
-			//
-			//		Syntax highlighting with language auto-detection package.
-			//		Released under CLA by the Dojo Toolkit, original BSD release
-			//		available from: http://softwaremaniacs.org/soft/highlight/
-			//
-			//
-		};
-	=====*/
-	var dh = dojo.getObject("dojox.highlight", true),
+
+	var dh = lang.getObject("dojox.highlight", true),
 		C_NUMBER_RE = '\\b(0x[A-Za-z0-9]+|\\d+(\\.\\d+)?)'
 	;
+	/*=====
+	 dh = {
+		 // summary:
+		 //		Syntax highlighting with language auto-detection package
+		 // description:
+		 //		Syntax highlighting with language auto-detection package.
+		 //		Released under CLA by the Dojo Toolkit, original BSD release
+		 //		available from: http://softwaremaniacs.org/soft/highlight/
+	 };
+	 =====*/
+
 	dh.languages = dh.languages || {};
 	// constants
 
@@ -73,14 +76,14 @@ define(["dojo", "dojox/main"], function(dojo, dojox){
 	}
 	
 	function verifyText(block){
-		return dojo.every(block.childNodes, function(node){
+		return array.every(block.childNodes, function(node){
 			return node.nodeType == 3 || String(node.nodeName).toLowerCase() == 'br';
 		});
 	}
 
 	function blockText(block){
 		var result = [];
-		dojo.forEach(block.childNodes, function(node){
+		array.forEach(block.childNodes, function(node){
 			if(node.nodeType == 3){
 				result.push(node.nodeValue);
 			}else if(String(node.nodeName).toLowerCase() == 'br'){
@@ -106,10 +109,10 @@ define(["dojo", "dojox/main"], function(dojo, dojox){
 		}
 	}
 	
-	function buildKeywords(lang){
-		if(lang.defaultMode && lang.modes){
-			buildKeywordGroups(lang.defaultMode);
-			dojo.forEach(lang.modes, buildKeywordGroups);
+	function buildKeywords(language){
+		if(language.defaultMode && language.modes){
+			buildKeywordGroups(language.defaultMode);
+			array.forEach(language.modes, buildKeywordGroups);
 		}
 	}
 	
@@ -146,9 +149,9 @@ define(["dojo", "dojox/main"], function(dojo, dojox){
 		}
 	};
 
-	dojo.extend(Highlighter, {
+	lang.extend(Highlighter, {
 		buildRes: function(){
-			dojo.forEach(this.lang.modes, function(mode){
+			array.forEach(this.lang.modes, function(mode){
 				if(mode.begin){
 					mode.beginRe = this.langRe('^' + mode.begin);
 				}
@@ -201,8 +204,8 @@ define(["dojo", "dojox/main"], function(dojo, dojox){
 			var mode = this.modes[this.modes.length - 1],
 				terminators = {};
 			if(mode.contains){
-				dojo.forEach(this.lang.modes, function(lmode){
-					if(dojo.indexOf(mode.contains, lmode.className) >= 0){
+				array.forEach(this.lang.modes, function(lmode){
+					if(array.indexOf(mode.contains, lmode.className) >= 0){
 						terminators[lmode.begin] = 1;
 					}
 				});
@@ -253,7 +256,7 @@ define(["dojo", "dojox/main"], function(dojo, dojox){
 		
 		buildLexemes: function(mode){
 			var lexemes = {};
-			dojo.forEach(mode.lexems, function(lexeme){
+			array.forEach(mode.lexems, function(lexeme){
 				lexemes[lexeme] = 1;
 			});
 			var t = [];
@@ -360,13 +363,13 @@ define(["dojo", "dojox/main"], function(dojo, dojox){
 			node.innerHTML = text;
 		}
 	}
-	function highlightStringLanguage(lang, str){
-		var highlight = new Highlighter(lang, str);
-		return {result:highlight.result, langName:lang, partialResult:highlight.partialResult};
+	function highlightStringLanguage(language, str){
+		var highlight = new Highlighter(language, str);
+		return {result:highlight.result, langName:language, partialResult:highlight.partialResult};
 	}
 
-	function highlightLanguage(block, lang){
-		var result = highlightStringLanguage(lang, blockText(block));
+	function highlightLanguage(block, language){
+		var result = highlightStringLanguage(language, blockText(block));
 		replaceText(block, block.className, result.result);
 	}
 
@@ -396,32 +399,32 @@ define(["dojo", "dojox/main"], function(dojo, dojox){
 	// the public API
 
 	dojox.highlight.processString = function(/* String */ str, /* String? */lang){
-		// summary: highlight a string of text
-		// returns: Object containing:
-		//         result - string of html with spans to apply formatting
-		//         partialResult - if the formating failed: string of html
-		//                 up to the point of the failure, otherwise: undefined
-		//         langName - the language used to do the formatting
+		// summary:
+		//		highlight a string of text
+		// returns: Object
+		//		Object containing:
+		//
+		//		- result - string of html with spans to apply formatting
+		//		- partialResult - if the formatting failed: string of html
+		//		  up to the point of the failure, otherwise: undefined
+		//		- langName - the language used to do the formatting
 		return lang ? highlightStringLanguage(lang, str) : highlightStringAuto(str);
 	};
 
 	dojox.highlight.init = function(/* String|DomNode */ node){
-		//	summary: Highlight a passed node
-		//
-		//	description:
-		//
+		// summary:
+		//		Highlight a passed node
+		// description:
 		//		Syntax highlight a passed DomNode or String ID of a DomNode
-		//
-		//
-		//	example:
+		// example:
 		//	|	dojox.highlight.init("someId");
 		//
-		node = dojo.byId(node);
-		if(dojo.hasClass(node, "no-highlight")){ return; }
+		node = dom.byId(node);
+		if(domClass.contains(node, "no-highlight")){ return; }
 		if(!verifyText(node)){ return; }
 	
 		var classes = node.className.split(/\s+/),
-			flag = dojo.some(classes, function(className){
+			flag = array.some(classes, function(className){
 				if(className.charAt(0) != "_" && dh.languages[className]){
 					highlightLanguage(node, className);
 					return true;	// stop iterations
@@ -433,31 +436,25 @@ define(["dojo", "dojox/main"], function(dojo, dojox){
 		}
 	};
 
-/*=====
-	dojox.highlight.Code = function(props, node){
-		//	summary: A Class object to allow for dojoType usage with the highlight engine. This is
+	dh.Code = function(props, node){
+		// summary:
+		//		A class object to allow for dojoType usage with the highlight engine. This is
 		//		NOT a Widget in the conventional sense, and does not have any member functions for
 		//		the instance. This is provided as a convenience. You likely should be calling
 		//		`dojox.highlight.init` directly.
-		//
-		//	props: Object?
+		// props: Object?
 		//		Unused. Pass 'null' or {}. Positional usage to allow `dojo.parser` to instantiate
 		//		this class as other Widgets would be.
-		//
-		//	node: String|DomNode
+		// node: String|DomNode
 		//		A String ID or DomNode reference to use as the root node of this instance.
-		//
-		//	example:
+		// example:
 		//	|	<pre><code dojoType="dojox.highlight.Code">for(var i in obj){ ... }</code></pre>
 		//
-		//	example:
+		// example:
 		//	|	var inst = new dojox.highlight.Code({}, "someId");
 		//
-		this.node = dojo.byId(node);
+		dh.init(node);
 	};
-=====*/
-
-	dh.Code = function(props, node){ dh.init(node); };
 
 	return dh;
 
diff --git a/dojox/highlight/languages/cpp.js b/dojox/highlight/languages/cpp.js
index 148feaa..55d57d6 100644
--- a/dojox/highlight/languages/cpp.js
+++ b/dojox/highlight/languages/cpp.js
@@ -1,8 +1,9 @@
-define(["dojo", "dojox/main", "../_base"], function(dojo, dojox){
+define(["../_base"], function(dh){
 	
-	var dh = dojox.highlight, dhc = dh.constants;
+	var dhc = dh.constants;
 	dh.languages.cpp = {
-		// summary: C++ highlight definitions
+		// summary:
+		//		C++ highlight definitions
 		defaultMode: {
 			lexems: [dhc.UNDERSCORE_IDENT_RE],
 			illegal: '</',
diff --git a/dojox/highlight/languages/css.js b/dojox/highlight/languages/css.js
index 4909215..9a6efbe 100644
--- a/dojox/highlight/languages/css.js
+++ b/dojox/highlight/languages/css.js
@@ -1,8 +1,9 @@
-define(["dojox/main", "../_base", "./html"], function(dojox, dh, html){
+define(["../_base", "./html"], function(dh, html){
 	
 	var dhc = dh.constants;
 	return dh.languages.css = {
-		// summary: CSS Language definition file. 
+		// summary:
+		//		CSS Language definition file.
 		defaultMode: {
 			contains: ['id', 'class', 'attr_selector', 'rules', 'comment'],
 			keywords: html.HTML_TAGS,
diff --git a/dojox/highlight/languages/delphi.js b/dojox/highlight/languages/delphi.js
index 4202a49..6bde8c0 100644
--- a/dojox/highlight/languages/delphi.js
+++ b/dojox/highlight/languages/delphi.js
@@ -1,4 +1,4 @@
-define(["dojox/main", "../_base"], function(dojox){
+define(["../_base"], function(dh){
 
 	var DELPHI_KEYWORDS = {
 		'and': 1, 'safecall': 1, 'cdecl': 1, 'then': 1, 'string': 1,
@@ -37,9 +37,10 @@ define(["dojox/main", "../_base"], function(dojox){
 		'class': 1, 'register': 1, 'xorwrite': 1, 'inline': 1
 	};
 
-	var dh = dojox.highlight, dhc = dh.constants;
+	var dhc = dh.constants;
 	dh.languages.delphi = {
-		// summary: Delphi highlight definitions
+		// summary:
+		//		Delphi highlight definitions
 		defaultMode: {
 			lexems: [dhc.IDENT_RE],
 			illegal: '("|\\$[G-Zg-z]|\\/\\*|</)',
diff --git a/dojox/highlight/languages/django.js b/dojox/highlight/languages/django.js
index 227a46c..d3c68d9 100644
--- a/dojox/highlight/languages/django.js
+++ b/dojox/highlight/languages/django.js
@@ -1,6 +1,6 @@
-define(["dojox/main", "../_base", "./xml", "./html"], function(dojox){
+define(["../_base", "./xml", "./html"], function(dh){
 
-	var dh = dojox.highlight, dhc = dh.constants, dhl = dh.languages, x = dhl.xml, h = dhl.html;
+	var dhc = dh.constants, dhl = dh.languages, x = dhl.xml, h = dhl.html;
 	dhl.django = {
 		defaultMode: {
 			contains: ['tag', 'comment', 'doctype', 'template_comment', 'template_tag', 'variable']
diff --git a/dojox/highlight/languages/groovy.js b/dojox/highlight/languages/groovy.js
index 12ccac5..5fc0f4e 100644
--- a/dojox/highlight/languages/groovy.js
+++ b/dojox/highlight/languages/groovy.js
@@ -1,6 +1,6 @@
-define(["dojox/main", "../_base"], function(dojox){
+define(["../_base"], function(dh){
 
-	var dh = dojox.highlight, dhc = dh.constants;
+	var dhc = dh.constants;
 	var GROOVY_KEYWORDS = {
 				'false': 1, 'int': 1, 'float': 1, 'while': 1, 'private': 1,
 				'char': 1, 'catch': 1, 'abstract': 1, 'assert': 1,
@@ -16,7 +16,8 @@ define(["dojox/main", "../_base"], function(dojox){
 				'try': 1, 'this': 1, 'switch': 1, 'continue': 1, 'def': 2
 			}
 	dh.languages.groovy = {
-		// summary: Groovy highlight definitions
+		// summary:
+		//		Groovy highlight definitions
 		defaultMode: {
 			lexems: [dhc.UNDERSCORE_IDENT_RE],
 			illegal: '</',
diff --git a/dojox/highlight/languages/html.js b/dojox/highlight/languages/html.js
index 34a85b9..af08176 100644
--- a/dojox/highlight/languages/html.js
+++ b/dojox/highlight/languages/html.js
@@ -1,4 +1,4 @@
-define(["dojox/main", "../_base", "./xml"], function(dojox){
+define(["../_base", "./xml"], function(dh){
 
 	var HTML_TAGS = {
 		'code': 1, 'kbd': 1, 'font': 1, 'noscript': 1, 'style': 1, 'img': 1,
@@ -31,7 +31,7 @@ define(["dojox/main", "../_base", "./xml"], function(dojox){
 		begin: '[a-zA-Z0-9]+', end: '^'
 	};
 
-	var dh = dojox.highlight, dhc = dh.constants, dhl = dh.languages, x = dhl.xml;
+	var dhc = dh.constants, dhl = dh.languages, x = dhl.xml;
 	dhl.html = {
 		defaultMode: {
 			contains: ['tag', 'comment', 'doctype']
diff --git a/dojox/highlight/languages/java.js b/dojox/highlight/languages/java.js
index 14fe324..2795545 100644
--- a/dojox/highlight/languages/java.js
+++ b/dojox/highlight/languages/java.js
@@ -1,6 +1,6 @@
-define(["dojox/main", "../_base"], function(dojox){
+define(["../_base"], function(dh){
 
-	var dh = dojox.highlight, dhc = dh.constants;
+	var dhc = dh.constants;
 	var javakeywords = {
 				'false': 1, 'int': 1, 'float': 1, 'while': 1, 'private': 1,
 				'char': 1, 'catch': 1, 'abstract': 1, 'assert': 1,
@@ -16,7 +16,8 @@ define(["dojox/main", "../_base"], function(dojox){
 				'try': 1, 'this': 1, 'switch': 1, 'continue': 1
 			}
 	dh.languages.java = {
-		// summary: Java highlight definitions
+		// summary:
+		//		Java highlight definitions
 		defaultMode: {
 			lexems: [dhc.UNDERSCORE_IDENT_RE],
 			illegal: '</',
diff --git a/dojox/highlight/languages/javascript.js b/dojox/highlight/languages/javascript.js
index 9b7b9e1..a7c312a 100644
--- a/dojox/highlight/languages/javascript.js
+++ b/dojox/highlight/languages/javascript.js
@@ -1,6 +1,6 @@
-define(["dojox/main", "../_base"], function(dojox){
+define(["../_base"], function(dh){
 
-	var dh = dojox.highlight, dhc = dh.constants;
+	var dhc = dh.constants;
 	dh.languages.javascript = {
 		defaultMode: {
 			lexems: [dhc.UNDERSCORE_IDENT_RE],
diff --git a/dojox/highlight/languages/pygments/_html.js b/dojox/highlight/languages/pygments/_html.js
index e6c7454..b574082 100644
--- a/dojox/highlight/languages/pygments/_html.js
+++ b/dojox/highlight/languages/pygments/_html.js
@@ -1,6 +1,6 @@
-define(["dojo", "dojox/main", "../../_base"], function(dojo, dojox){
+define(["dojo/_base/lang", "dojox/main", "../../_base"], function(lang, dojox){
 
-	dojo.getObject("highlight.languages.pygments._html", true, dojox);
+	lang.getObject("highlight.languages.pygments._html", true, dojox);
 
 	dojox.highlight.languages.pygments._html.tags = {
 		"code": 1, "kbd": 1, "font": 1, "noscript": 1, "style": 1, "img": 1,
diff --git a/dojox/highlight/languages/pygments/_www.js b/dojox/highlight/languages/pygments/_www.js
index 51b2861..a85d6ad 100644
--- a/dojox/highlight/languages/pygments/_www.js
+++ b/dojox/highlight/languages/pygments/_www.js
@@ -1 +1 @@
-define(["dojox/main", "../../_base", "./xml", "./html", "./css", "./javascript"], function(){ });
\ No newline at end of file
+define(["dojox/main", "../../_base", "./xml", "./html", "./css", "./javascript"], function(){ });
diff --git a/dojox/highlight/languages/pygments/css.js b/dojox/highlight/languages/pygments/css.js
index fcebf4e..47169aa 100644
--- a/dojox/highlight/languages/pygments/css.js
+++ b/dojox/highlight/languages/pygments/css.js
@@ -1,6 +1,6 @@
-define(["dojox/main", "../../_base", "./_html"], function(dojox){
+define(["../../_base", "./_html"], function(dh){
 
-	var dh = dojox.highlight, dhl = dh.languages;
+	var dhl = dh.languages;
 	dhl.css = {
 		defaultMode: {
 			lexems: ["\\b[a-zA-Z0-9]+\\b", "\\b at media\b"],
diff --git a/dojox/highlight/languages/pygments/html.js b/dojox/highlight/languages/pygments/html.js
index 5af4731..928a692 100644
--- a/dojox/highlight/languages/pygments/html.js
+++ b/dojox/highlight/languages/pygments/html.js
@@ -1,6 +1,6 @@
-define(["dojox/main", "../../_base", "./_html"], function(dojox){
+define(["../../_base", "./_html"], function(dh){
 
-	var dh = dojox.highlight, dhl = dh.languages, tags = [],
+	var dhl = dh.languages, tags = [],
 		ht = dhl.pygments._html.tags;
 	
 	for(var key in ht){
diff --git a/dojox/highlight/languages/pygments/javascript.js b/dojox/highlight/languages/pygments/javascript.js
index 57eecdf..9db3f29 100644
--- a/dojox/highlight/languages/pygments/javascript.js
+++ b/dojox/highlight/languages/pygments/javascript.js
@@ -1,6 +1,6 @@
-define(["dojox/main", "../../_base"], function(dojox){
+define(["../../_base"], function(dh){
 
-	var dh = dojox.highlight, dhc = dh.constants;
+	var dhc = dh.constants;
 	dh.languages.javascript = {
 		defaultMode: {
 			lexems: ["\\b[a-zA-Z]+"],
diff --git a/dojox/highlight/languages/pygments/xml.js b/dojox/highlight/languages/pygments/xml.js
index 8591245..00b0859 100644
--- a/dojox/highlight/languages/pygments/xml.js
+++ b/dojox/highlight/languages/pygments/xml.js
@@ -1,6 +1,6 @@
-define(["dojox/main", "../../_base", "../xml"], function(dojox){
+define(["../../_base", "../xml"], function(dh){
 
-	var dxml = dojox.highlight.languages.xml = {
+	var dxml = dh.languages.xml = {
 		defaultMode: {
 			contains: [
 				"name entity",
diff --git a/dojox/highlight/languages/python.js b/dojox/highlight/languages/python.js
index 8452ba8..d68506a 100644
--- a/dojox/highlight/languages/python.js
+++ b/dojox/highlight/languages/python.js
@@ -1,8 +1,9 @@
-define(["dojox/main", "../_base"], function(dojox){
+define(["../_base"], function(dh){
 
-	var dh = dojox.highlight, dhc = dh.constants;
+	var dhc = dh.constants;
 	dh.languages.python = {
-		// summary: Python highlight definitions
+		// summary:
+		//		Python highlight definitions
 		defaultMode: {
 			lexems: [dhc.UNDERSCORE_IDENT_RE],
 			illegal: '(</|->)',
diff --git a/dojox/highlight/languages/sql.js b/dojox/highlight/languages/sql.js
index 98f092f..289502e 100644
--- a/dojox/highlight/languages/sql.js
+++ b/dojox/highlight/languages/sql.js
@@ -1,4 +1,4 @@
-define(["dojox/main", "../_base"], function(dojox){
+define(["../_base"], function(dh){
 
 	var SQL_KEYWORDS = {
 		'all': 1, 'partial': 1, 'global': 1, 'month': 1,
@@ -44,9 +44,10 @@ define(["dojox/main", "../_base"], function(dojox){
 		'having': 1, 'left': 1
 	};
 
-	var dh = dojox.highlight, dhc = dh.constants;
+	var dhc = dh.constants;
 	dh.languages.sql = {
-		// summary: SQL highlight definitions
+		// summary:
+		//		SQL highlight definitions
 		case_insensitive: true,
 			defaultMode: {
 				lexems: [dhc.IDENT_RE],
diff --git a/dojox/highlight/languages/xml.js b/dojox/highlight/languages/xml.js
index 304825f..b88f100 100644
--- a/dojox/highlight/languages/xml.js
+++ b/dojox/highlight/languages/xml.js
@@ -1,4 +1,4 @@
-define(["dojox/main", "../_base"], function(dojox){
+define(["../_base"], function(dh){
 
 	var XML_COMMENT = {
 		className: 'comment',
@@ -16,7 +16,7 @@ define(["dojox/main", "../_base"], function(dojox){
 		begin: '"', end: '"'
 	};
 	
-	var dh = dojox.highlight, dhc = dh.constants;
+	var dhc = dh.constants;
 	dh.languages.xml = {
 		defaultMode: {
 			contains: ['pi', 'comment', 'cdata', 'tag']
diff --git a/dojox/highlight/languages/xquery.js b/dojox/highlight/languages/xquery.js
index 828080d..df012d5 100644
--- a/dojox/highlight/languages/xquery.js
+++ b/dojox/highlight/languages/xquery.js
@@ -1,4 +1,4 @@
-define(["dojox/main", "../_base"], function(dojox){
+define(["../_base"], function(dh){
 
 	// Very simple XQuery language file.  Would be nice
 	// to eventually handle more of the enclosed expressions
@@ -36,7 +36,7 @@ define(["dojox/main", "../_base"], function(dojox){
 		'version': 1, 'where': 1, 'xquery': 1
 	};
 
-	var dh = dojox.highlight, dhc = dh.constants;
+	var dhc = dh.constants;
 	dh.languages.xquery = {
 		case_insensitive: true,
 			defaultMode: {
diff --git a/dojox/highlight/tests/example-xml-resultdata.xml b/dojox/highlight/tests/example-xml-resultdata.xml
index 226183e..5f3aa09 100644
--- a/dojox/highlight/tests/example-xml-resultdata.xml
+++ b/dojox/highlight/tests/example-xml-resultdata.xml
@@ -1 +1 @@
-<a>this is simple</a>
\ No newline at end of file
+<a>this is simple</a>
diff --git a/dojox/highlight/tests/example-xquery-source.xquery b/dojox/highlight/tests/example-xquery-source.xquery
index 351e0a1..43f33af 100644
--- a/dojox/highlight/tests/example-xquery-source.xquery
+++ b/dojox/highlight/tests/example-xquery-source.xquery
@@ -24,4 +24,4 @@ declare function local:equityRows($root) {
 	<th>Currency</th>
 </tr>
 { local:equityRows(/) }
-</table>
\ No newline at end of file
+</table>
diff --git a/dojox/highlight/tests/highlight.js b/dojox/highlight/tests/highlight.js
index f3d42d4..5dcf8e8 100644
--- a/dojox/highlight/tests/highlight.js
+++ b/dojox/highlight/tests/highlight.js
@@ -5,7 +5,8 @@ dojo.require("dojox.highlight.languages._all");
 
 doh.register("dojox.highlight.tests.highlight", [
 	function test_validjavascript(){
-		//summary: Test a valid javascript block is highlighted correctly
+		// summary:
+		//		Test a valid javascript block is highlighted correctly
 		var unformatted = "console.debug('hello'); /*Hi*/";
 		var expected = "console.debug(<span class=\"string\">'hello'</span>); <span class=\"comment\">/*Hi*/</span>";
 		var result = dojox.highlight.processString(unformatted, "javascript");
@@ -14,9 +15,10 @@ doh.register("dojox.highlight.tests.highlight", [
 		doh.assertEqual("javascript", result.langName);
 	},
 	function test_invalidjavascript(){
-		//summary: Test an invalid javascript block with partial result
+		// summary:
+		//		Test an invalid javascript block with partial result
 		var unformatted = "console.debug('hello);\n /*Hi*/";
-		//                               ^_ unmatched quote
+		//			                     ^_ unmatched quote
 		var expected = "console.debug(<span class=\"string\">";
 		var result = dojox.highlight.processString(unformatted, "javascript");
 		doh.assertEqual(unformatted, result.result);
diff --git a/dojox/highlight/tests/test_highlight.html b/dojox/highlight/tests/test_highlight.html
index 328157a..cec1724 100644
--- a/dojox/highlight/tests/test_highlight.html
+++ b/dojox/highlight/tests/test_highlight.html
@@ -35,7 +35,7 @@
 		}
 	</style>
 
-	<script type="text/javascript" djConfig="parseOnLoad: false, isDebug: true" src="../../../dojo/dojo.js"></script>
+	<script type="text/javascript" data-dojo-config="parseOnLoad: false, isDebug: true" src="../../../dojo/dojo.js"></script>
 
 	<script type="text/javascript">
 		// initHighlightOnLoad is deprecated.
diff --git a/dojox/highlight/tests/test_highlightWidget.html b/dojox/highlight/tests/test_highlightWidget.html
index 967b58e..8aa2bea 100644
--- a/dojox/highlight/tests/test_highlightWidget.html
+++ b/dojox/highlight/tests/test_highlightWidget.html
@@ -3,7 +3,7 @@
     <head>
 		<title>Dojo source code color syntax highlighting example</title>
 		<link rel="stylesheet" type="text/css" href="pretty.css" />
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
 		<script type="text/javascript" src="highlightRequires.js"></script>
     </head>
     <body>
@@ -12,13 +12,13 @@
 			<p>View source to see how easy it is to use the Dojo code highlight in your documentation.</p>
 			<p>Mimic the format of SyntaxHighlighter, using dojox.highlight and stylesheets, and our simple Code widget extension.</p>
 			<h3>Java code (including SQL/XML statement definition):</h3>
-			<div lang="java" dojoType="highlight.Code" url="./example-java-source.java" style="height:200px; overflow:auto;"></div>	
+			<div lang="java" dojoType="dojox.highlight.widget.Code" url="./example-java-source.java" style="height:200px; overflow:auto;"></div>	
 			<h3>XQuery code:</h3>
-			<div lang="xquery" dojoType="highlight.Code" url="./example-xquery-source.xquery" style="height:200px; overflow:auto;"></div>
+			<div lang="xquery" dojoType="dojox.highlight.widget.Code" url="./example-xquery-source.xquery" style="height:200px; overflow:auto;"></div>
 			<h3>XML result data:</h3>
-			<div lang="xml" dojoType="highlight.Code" url="./example-xml-resultdata.xml"></div>
+			<div lang="xml" dojoType="dojox.highlight.widget.Code" url="./example-xml-resultdata.xml"></div>
 			<h3>XML doc:</h3>
-			<div lang="xml" dojoType="highlight.Code" url="./example-xml-data.xml" style="height:200px; overflow:auto;"></div>
+			<div lang="xml" dojoType="dojox.highlight.widget.Code" url="./example-xml-data.xml" style="height:200px; overflow:auto;"></div>
 		</div>
     </body>
 </html>
\ No newline at end of file
diff --git a/dojox/highlight/tests/test_pygments.html b/dojox/highlight/tests/test_pygments.html
index 447b894..12a0f98 100644
--- a/dojox/highlight/tests/test_pygments.html
+++ b/dojox/highlight/tests/test_pygments.html
@@ -26,7 +26,7 @@
 	<!-- a sample set of definitions to use as a foundation to color your code -->
 	<link rel="stylesheet" type="text/css" href="../resources/pygments/default.css">
 	
-	<script type="text/javascript" djConfig="parseOnLoad: true, isDebug: true" src="../../../dojo/dojo.js"></script>
+	<script type="text/javascript" data-dojo-config="parseOnLoad: true, isDebug: true" src="../../../dojo/dojo.js"></script>
 	<!--
 	<script type="text/javascript" src="../_base.js"></script>
 	<script type="text/javascript" src="../languages/pygments/xml.js"></script>
diff --git a/dojox/highlight/widget/Code.js b/dojox/highlight/widget/Code.js
index e5a543e..72bbfa9 100644
--- a/dojox/highlight/widget/Code.js
+++ b/dojox/highlight/widget/Code.js
@@ -1,6 +1,18 @@
-define(["dojo", "dijit", "dijit/_Widget", "dijit/_Templated", "dojox/highlight"], function(dojo, dijit){
+define([
+	"dojo/_base/declare", 
+	"dojo/_base/lang", 
+	"dojo/_base/array", 
+	"dojo/query",
+	"dojo/dom-class",
+	"dojo/dom-attr",
+	"dojo/dom-construct",
+	"dojo/request/xhr",
+	"dijit/_Widget", 
+	"dijit/_Templated", 
+	"dojox/highlight"
+], function(declare, lang, array, query, domClass, domAttr, domConstruct, xhr, _Widget, _Templated){
 
-	dojo.declare("dojox.highlight.widget.Code",[dijit._Widget, dijit._Templated],{
+	return declare("dojox.highlight.widget.Code", [_Widget, _Templated],{
 		// summary:
 		//		A simple source code formatting widget that adds line numbering, alternating line colors
 		//		and line range support on top of dojox.highlight module.
@@ -12,7 +24,7 @@ define(["dojo", "dijit", "dijit/_Widget", "dijit/_Templated", "dojox/highlight"]
 		lang:"",
 
 		// Note: If more control over formatting is required, the order list items can be replaced
-		// with a table implementation instead... Excercise is left for those that need it...
+		// with a table implementation instead... exercise is left for those that need it...
 		templateString:
 			'<div class="formatted" style="${style}">'+
 				'<div class="titleBar"></div>'+
@@ -23,13 +35,14 @@ define(["dojo", "dijit", "dijit/_Widget", "dijit/_Templated", "dojox/highlight"]
 		postCreate: function(){
 			this.inherited(arguments);
 			if(this.url){
+				xhr(this.url, {}).then(lang.hitch(this,"_populate"), lang.hitch(this,"_loadError"));
 				// load from a url
-				dojo.xhrGet({
+				/*dojo.xhrGet({
 					url: this.url,
 					// then poopulate:
-					load: dojo.hitch(this,"_populate"),
-					error: dojo.hitch(this,"_loadError")
-				});
+					load: lang.hitch(this,"_populate"),
+					error: lang.hitch(this,"_loadError")
+				});*/
 			}else{
 				// or just populate from our internal content
 				this._populate(this.containerNode.innerHTML);
@@ -43,36 +56,38 @@ define(["dojo", "dijit", "dijit/_Widget", "dijit/_Templated", "dojox/highlight"]
 					data.replace(/\</g,"<") +
 				"</code></pre>";
 			// highlight it
-			dojo.query("pre > code",this.containerNode).forEach(dojox.highlight.init);
+			query("pre > code",this.containerNode).forEach(dojox.highlight.init);
 			// FIXME: in ie7, the innerHTML in a real <pre> isn't split by \n's ?
 			// split the content into lines
 			var lines = this.containerNode.innerHTML.split("\n");
-			dojo.forEach(lines,function(line,i){
+			array.forEach(lines,function(line,i){
 				// setup all the lines of the content as <li>'s
-				var li = dojo.doc.createElement('li');
+				var li = domConstruct.create('li');
 				// add some style sugar:
-				dojo.addClass(li, (i % 2 !== 0 ? "even" : "odd"));
+				domClass.add(li, (i % 2 !== 0 ? "even" : "odd"));
 				line = "<pre><code>" + line + " </code></pre>";
 				line = line.replace(/\t/g,"   ");
 				li.innerHTML = line;
 				this.codeList.appendChild(li);
 			},this);
 			// save our data
-			this._lines = dojo.query("li",this.codeList);
+			this._lines = query("li",this.codeList);
 			this._updateView();
 		},
 	
 		// FIXME: user _setRangeAttr pattern? so you can code.set('range', [1, 100]);
 		setRange: function(/* Array */range){
-			// summary: update the view to a new passed range
-			if(dojo.isArray(range)){
+			// summary:
+			//		update the view to a new passed range
+			if(range instanceof Array){
 				this.range = range;
 				this._updateView();
 			}
 		},
 	
 		_updateView: function(){
-			// summary: set the list to the current range
+			// summary:
+			//		set the list to the current range
 			if(this.range){
 				var r = this.range;
 				this._lines
@@ -86,12 +101,13 @@ define(["dojo", "dijit", "dijit/_Widget", "dijit/_Templated", "dojox/highlight"]
 					.style({ display:"" })
 				;
 				// set the "start" attribute on the OL so numbering works
-				dojo.attr(this.codeList,"start",r[0]);
+				domAttr.set(this.codeList,"start",r[0]);
 			}
 		},
 	
 		_loadError: function(error){
-			// summary: a generic error handler for the url=""
+			// summary:
+			//		a generic error handler for the url=""
 			console.warn("loading: ", this.url, " FAILED", error);
 		}
 
diff --git a/dojox/html.js b/dojox/html.js
index e923302..d2b5108 100644
--- a/dojox/html.js
+++ b/dojox/html.js
@@ -1,3 +1,10 @@
 define(["./html/_base"], function (html) {
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/html modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
 	return html;
 });
\ No newline at end of file
diff --git a/dojox/html/_base.js b/dojox/html/_base.js
index 9de2918..b1924be 100644
--- a/dojox/html/_base.js
+++ b/dojox/html/_base.js
@@ -1,16 +1,20 @@
 define([
+	"dojo/_base/declare",
+	"dojo/Deferred",
+	"dojo/dom-construct",
+	"dojo/html",
 	"dojo/_base/kernel",
 	"dojo/_base/lang",
-	"dojo/_base/xhr",
-	"dojo/_base/window",
+	"dojo/ready",
 	"dojo/_base/sniff",
 	"dojo/_base/url",
-	"dojo/dom-construct",
-	"dojo/html",
-	"dojo/_base/declare"
-], function (dojo, lang, xhrUtil, windowUtil, has, _Url, domConstruct, htmlUtil) {
+	"dojo/_base/xhr",
+	"dojo/when",
+	"dojo/_base/window"
+], function(declare, Deferred, domConstruct, htmlUtil, kernel, lang, ready, has, _Url, xhrUtil, when, windowUtil){
+
 /*
-	Status: dont know where this will all live exactly
+	Status: don't know where this will all live exactly
 	Need to pull in the implementation of the various helper methods
 	Some can be static method, others maybe methods of the ContentSetter (?)
 
@@ -18,7 +22,7 @@ define([
 
 
 */
-	var html = dojo.getObject("dojox.html", true);
+	var html = kernel.getObject("dojox.html", true);
 
 	if(has("ie")){
 		var alphaImageLoader = /(AlphaImageLoader\([^)]*?src=(['"]))(?![a-z]+:|\/)([^\r\n;}]+?)(\2[^)]*\)\s*[;}]?)/g;
@@ -41,26 +45,26 @@ define([
 	var cssPaths = /(?:(?:@import\s*(['"])(?![a-z]+:|\/)([^\r\n;{]+?)\1)|url\(\s*(['"]?)(?![a-z]+:|\/)([^\r\n;]+?)\3\s*\))([a-z, \s]*[;}]?)/g;
 
 	var adjustCssPaths = html._adjustCssPaths = function(cssUrl, cssText){
-		//	summary:
+		// summary:
 		//		adjusts relative paths in cssText to be relative to cssUrl
 		//		a path is considered relative if it doesn't start with '/' and not contains ':'
-		//	description:
+		// description:
 		//		Say we fetch a HTML page from level1/page.html
 		//		It has some inline CSS:
-		//			@import "css/page.css" tv, screen;
-		//			...
-		//			background-image: url(images/aplhaimage.png);
+		//	|		@import "css/page.css" tv, screen;
+		//	|		...
+		//	|		background-image: url(images/aplhaimage.png);
 		//
 		//		as we fetched this HTML and therefore this CSS
 		//		from level1/page.html, these paths needs to be adjusted to:
-		//			@import 'level1/css/page.css' tv, screen;
-		//			...
-		//			background-image: url(level1/images/alphaimage.png);
+		//	|		@import 'level1/css/page.css' tv, screen;
+		//	|		...
+		//	|		background-image: url(level1/images/alphaimage.png);
 		//
 		//		In IE it will also adjust relative paths in AlphaImageLoader()
-		//			filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/alphaimage.png');
+		//	|		filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/alphaimage.png');
 		//		will be adjusted to:
-		//			filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='level1/images/alphaimage.png');
+		//	|		filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='level1/images/alphaimage.png');
 		//
 		//		Please note that any relative paths in AlphaImageLoader in external css files wont work, as
 		//		the paths in AlphaImageLoader is MUST be declared relative to the HTML page,
@@ -113,6 +117,11 @@ define([
 		// if cssUrl is set it will adjust paths accordingly
 		styles.attributes = [];
 
+		cont = cont.replace(/<[!][-][-](.|\s)*?[-][-]>/g,
+			function(comment){
+				return comment.replace(/<(\/?)style\b/ig,"<$1Style").replace(/<(\/?)link\b/ig,"<$1Link").replace(/@import "/ig,"@ import \"");
+			}
+		);
 		return cont.replace(/(?:<style([^>]*)>([\s\S]*?)<\/style>|<link\s+(?=[^>]*rel=['"]?stylesheet)([^>]*?href=(['"])([^>]*?)\4[^>\/]*)\/?>)/gi,
 			function(ignore, styleAttr, cssText, linkAttr, delim, href){
 				// trim attribute
@@ -138,11 +147,11 @@ define([
 	};
 
 	var snarfScripts = html._snarfScripts = function(cont, byRef){
-		// summary
+		// summary:
 		//		strips out script tags from cont
-		// invoke with
-		//	byRef = {errBack:function(){/*add your download error code here*/, downloadRemote: true(default false)}}
-		//	byRef will have {code: 'jscode'} when this scope leaves
+		// byRef:
+		//		byRef = {errBack:function(){/*add your download error code here*/, downloadRemote: true(default false)}}
+		//		byRef will have {code: 'jscode'} when this scope leaves
 		byRef.code = "";
 
 		//Update script tags nested in comments so that the script tag collector doesn't pick
@@ -179,7 +188,7 @@ define([
 		}
 
 		// match <script>, <script type="text/..., but not <script type="dojo(/method)...
-		return cont.replace(/<script\s*(?![^>]*type=['"]?(?:dojo\/|text\/html\b))(?:[^>]*?(?:src=(['"]?)([^>]*?)\1[^>]*)?)*>([\s\S]*?)<\/script>/gi,
+		return cont.replace(/<script\s*(?![^>]*type=['"]?(?:dojo\/|text\/html\b))[^>]*?(?:src=(['"]?)([^>]*?)\1[^>]*)?>([\s\S]*?)<\/script>/gi,
 			function(ignore, delim, src, code){
 				if(src){
 					download(src);
@@ -202,7 +211,7 @@ define([
 		n.text = code; // DOM 1 says this should work
 	};
 
-	html._ContentSetter = dojo.declare(/*===== "dojox.html._ContentSetter", =====*/ htmlUtil._ContentSetter, {
+	html._ContentSetter = declare(/*===== "dojox.html._ContentSetter", =====*/ htmlUtil._ContentSetter, {
 		// adjustPaths: Boolean
 		//		Adjust relative paths in html string content to point to this page
 		//		Only useful if you grab content from a another folder than the current one
@@ -248,7 +257,7 @@ define([
 		},
 
 		onBegin: function() {
-			// summary
+			// summary:
 			//		Called after instantiation, but before set();
 			//		It allows modification of any of the object properties - including the node and content
 			//		provided - before the set operation actually takes place
@@ -288,7 +297,7 @@ define([
 		},
 
 		onEnd: function() {
-			// summary
+			// summary:
 			//		Called after set(), when the new content has been pushed into the node
 			//		It provides an opportunity for post-processing before handing back the node to the caller
 			//		This implementation extends that of dojo.html._ContentSetter
@@ -310,7 +319,22 @@ define([
 				this._renderStyles(styles);
 			}
 
+			// Deferred to signal when this function is complete
+			var d = new Deferred();
+
+			// Setup function to call onEnd() in the superclass, for parsing, and resolve the above Deferred when
+			// parsing is complete.
+			var superClassOnEndMethod = this.getInherited(arguments),
+				args = arguments,
+				callSuperclass = lang.hitch(this, function(){
+					superClassOnEndMethod.apply(this, args);
+
+					// If parser ran (parseContent == true), wait for it to finish, otherwise call d.resolve() immediately
+					when(this.parseDeferred, function(){ d.resolve(); });
+				});
+
 			if(this.executeScripts && code){
+				// Evaluate any <script> blocks in the content
 				if(this.cleanContent){
 					// clean JS from html comments and other crap that browser
 					// parser takes care of in a normal page load
@@ -327,9 +351,21 @@ define([
 				}catch(e){
 					this._onError('Exec', 'Error eval script in '+this.id+', '+e.message, e);
 				}
+
+				// Finally, use ready() to wait for any require() calls from the <script> blocks to complete,
+				// then call onEnd() in the superclass, for parsing, and when that is done resolve the Deferred.
+				// For 2.0, remove the call to ready() (or this whole if() branch?) since the parser can do loading for us.
+				ready(callSuperclass);
+			}else{
+				// There were no <script>'s to execute, so immediately call onEnd() in the superclass, and
+				// when the parser finishes running, resolve the Deferred.
+				callSuperclass();
 			}
-			this.inherited("onEnd", arguments);
+
+			// Return a promise that resolves after the ready() call completes, and after the parser finishes running.
+			return d.promise;
 		},
+
 		tearDown: function() {
 			this.inherited(arguments);
 			delete this._styles;
@@ -345,7 +381,7 @@ define([
 			// XXX: not sure if this is the correct intended behaviour, it was originally
 			// dojo.getObject(this.declaredClass).prototype which will not work with anonymous
 			// modules
-			dojo.mixin(this, html._ContentSetter.prototype);
+			lang.mixin(this, html._ContentSetter.prototype);
 		}
 
 	});
@@ -354,26 +390,26 @@ define([
 		// TODO: add all the other options
 			// summary:
 			//		inserts (replaces) the given content into the given node
-			//	node:
+			// node:
 			//		the parent element that will receive the content
-			//	cont:
+			// cont:
 			//		the content to be set on the parent element.
-			//		This can be an html string, a node reference or a NodeList, dojo.NodeList, Array or other enumerable list of nodes
-			//	params:
+			//		This can be an html string, a node reference or a NodeList, dojo/NodeList, Array or other enumerable list of nodes
+			// params:
 			//		Optional flags/properties to configure the content-setting. See dojo.html._ContentSetter
-			//	example:
+			// example:
 			//		A safe string/node/nodelist content replacement/injection with hooks for extension
 			//		Example Usage:
-			//		dojo.html.set(node, "some string");
-			//		dojo.html.set(node, contentNode, {options});
-			//		dojo.html.set(node, myNode.childNodes, {options});
+			//	|	dojo.html.set(node, "some string");
+			//	|	dojo.html.set(node, contentNode, {options});
+			//	|	dojo.html.set(node, myNode.childNodes, {options});
 
 		if(!params){
 			// simple and fast
 			return htmlUtil._setNodeContent(node, cont, true);
 		}else{
 			// more options but slower
-			var op = new html._ContentSetter(dojo.mixin(
+			var op = new html._ContentSetter(lang.mixin(
 					params,
 					{ content: cont, node: node }
 			));
diff --git a/dojox/html/ellipsis.js b/dojox/html/ellipsis.js
index 363dc01..f77211c 100644
--- a/dojox/html/ellipsis.js
+++ b/dojox/html/ellipsis.js
@@ -1,13 +1,14 @@
 define("dojox/html/ellipsis",["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/Color", "dojo/colors"], function(d){
 	/*=====
-	dojox.html.ellipsis = {
-		// summary: offers cross-browser support for text-overflow: ellipsis
-		//
-		// description: Add "dojoxEllipsis" on any node that you want to ellipsis-ize. In order to function properly,
-		//	the node with the dojoxEllipsis class set on it should be a child of a node with a defined width.
-		//	It should also be a block-level element (i.e. <div>) - it will not work on td elements.
-		//	NOTE: When using the dojoxEllipsis class within tables, the table needs to have the table-layout: fixed style
-	}
+	return {
+		// summary:
+		//		offers cross-browser support for text-overflow: ellipsis
+		// description:
+		//		Add "dojoxEllipsis" on any node that you want to ellipsis-ize. In order to function properly,
+		//		the node with the dojoxEllipsis class set on it should be a child of a node with a defined width.
+		//		It should also be a block-level element (i.e. `<div>`) - it will not work on td elements.
+		//		NOTE: When using the dojoxEllipsis class within tables, the table needs to have the table-layout: fixed style
+	};
 	=====*/
 	
 	if(d.isFF < 7){ //TODO: feature detect text-overflow in computed style?
@@ -49,14 +50,13 @@ define("dojox/html/ellipsis",["dojo/_base/kernel", "dojo/_base/lang", "dojo/_bas
 		var dd = d.doc;
 		var dp = d.place;
 		var iFrame = create("iframe", {className: "dojoxEllipsisIFrame",
-					src: "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'"});
+					src: "javascript:'<html><head><script>if(\"loadFirebugConsole\" in window){window.loadFirebugConsole();}</script></head><body></body></html>'", style: {display: "none"}});
 		var rollRange = function(/* W3C Range */ r, /* int? */ cnt){
-			// Summary:
+			// summary:
 			//		Rolls the given range back one character from the end
-			//
-			//	r: W3C Range
+			// r: W3C Range
 			//		The range to roll back
-			//	cnt: int?
+			// cnt: int?
 			//		An optional number of times to roll back (defaults 1)
 			if(r.collapsed){
 				// Do nothing - we are already collapsed
@@ -95,7 +95,7 @@ define("dojox/html/ellipsis",["dojo/_base/kernel", "dojo/_base/lang", "dojo/_bas
 			}
 		};
 		var createIFrameEllipsis = function(/* Node */ n){
-			// Summary:
+			// summary:
 			//		Given a node, it creates an iframe and and ellipsis div and
 			//		sets up the connections so that they will work correctly.
 			//		This function is used when createXULEllipsis is not able
diff --git a/dojox/html/entities.js b/dojox/html/entities.js
index bd0e6df..f809686 100755
--- a/dojox/html/entities.js
+++ b/dojox/html/entities.js
@@ -142,7 +142,7 @@ define(["dojo/_base/lang"], function(lang) {
 		["\u22C5","sdot"],["\u2308","lceil"],["\u2309","rceil"],["\u230A","lfloor"],
 		["\u230B","rfloor"],["\u2329","lang"],["\u232A","rang"],["\u25CA","loz"],
 		["\u2660","spades"],["\u2663","clubs"],["\u2665","hearts"],["\u2666","diams"],
-		["\u0152","Elig"],["\u0153","oelig"],["\u0160","Scaron"],["\u0161","scaron"],
+		["\u0152","OElig"],["\u0153","oelig"],["\u0160","Scaron"],["\u0161","scaron"],
 		["\u0178","Yuml"],["\u02C6","circ"],["\u02DC","tilde"],["\u2002","ensp"],
 		["\u2003","emsp"],["\u2009","thinsp"],["\u200C","zwnj"],["\u200D","zwj"],
 		["\u200E","lrm"],["\u200F","rlm"],["\u2013","ndash"],["\u2014","mdash"],
diff --git a/dojox/html/ext-dojo/style.js b/dojox/html/ext-dojo/style.js
index df669a4..d39244b 100644
--- a/dojox/html/ext-dojo/style.js
+++ b/dojox/html/ext-dojo/style.js
@@ -4,11 +4,12 @@ define(["dojo/_base/kernel", "dojo/dom-style", "dojo/_base/lang", "dojo/_base/ht
 	kernel.experimental("dojox.html.ext-dojo.style");
 	var st = lang.getObject("dojox.html.ext-dojo.style", true);
 	var HtmlX = lang.getObject("dojox.html");
-	// summary: Extensions to dojo.style adding the css3 "transform" and "transform-origin" properties on IE5.5+
+	// summary:
+	//		Extensions to dojo.style adding the css3 "transform" and "transform-origin" properties on IE5.5+
 	// description:
-	//	A Package to extend the dojo.style function
-	//	Supported transformation functions:
-	//  matrix, translate, translateX, translateY, scale, scaleX, scaleY, rotate, skewX, skewY, skew
+	//		A Package to extend the dojo.style function
+	//		Supported transformation functions:
+	//	 	matrix, translate, translateX, translateY, scale, scaleX, scaleY, rotate, skewX, skewY, skew
 	lang.mixin(HtmlX["ext-dojo"].style, {
 		supportsTransform: true,
 		_toPx: function(measure){
@@ -61,10 +62,10 @@ define(["dojo/_base/kernel", "dojo/dom-style", "dojo/_base/lang", "dojo/_base/ht
 			}
 			if(this.tPropertyName){
 				this.setTransform = function(/*DomNode*/node, /*String*/ transform){
-					return DOMStyle.set(node, this.tPropertyName, transform);
+					return sset(node, this.tPropertyName, transform);
 				};
 				this.getTransform = function(/*DomNode*/node){
-					return DOMStyle.get(node, this.tPropertyName);
+					return sget(node, this.tPropertyName);
 				};
 			}else if(has("ie")){
 				this.setTransform = this._setTransformFilter;
diff --git a/dojox/html/format.js b/dojox/html/format.js
index 3855570..f7ac5a0 100755
--- a/dojox/html/format.js
+++ b/dojox/html/format.js
@@ -22,7 +22,7 @@ define(["dojo/_base/kernel", "./entities", "dojo/_base/array", "dojo/_base/windo
 		//		dojox.html.entities.encode function.
 		// xhtml: boolean
 		//		Optional parameter that declares that the returned HTML should try to be 'xhtml' compatible.
-		//		This means normally unclosed tags are terminated with /> instead of >.  Example: <hr> -> <hr />
+		//		This means normally unclosed tags are terminated with /> instead of >.  Example: `<hr>` -> `<hr />`
 		var content = [];
 		var indentDepth = 0;
 		var closeTags = [];
diff --git a/dojox/html/metrics.js b/dojox/html/metrics.js
index e22b580..fc3deb4 100644
--- a/dojox/html/metrics.js
+++ b/dojox/html/metrics.js
@@ -6,8 +6,8 @@ define(["dojo/_base/kernel","dojo/_base/lang", "dojo/_base/sniff", "dojo/ready",
 
 	//	derived from Morris John's emResized measurer
 	dhm.getFontMeasurements = function(){
-		//	summary
-		//	Returns an object that has pixel equivilents of standard font size values.
+		// summary:
+		//		Returns an object that has pixel equivilents of standard font size values.
 		var heights = {
 			'1em':0, '1ex':0, '100%':0, '12pt':0, '16px':0, 'xx-small':0, 'x-small':0,
 			'small':0, 'medium':0, 'large':0, 'x-large':0, 'xx-large':0
@@ -121,6 +121,7 @@ define(["dojo/_base/kernel","dojo/_base/lang", "dojo/_base/sniff", "dojo/ready",
 		fs.width = "5em";
 		fs.height = "10em";
 		fs.top = "-10000px";
+		fs.display = "none";
 		if(has("ie")){
 			f.onreadystatechange = function(){
 				if(f.contentWindow.document.readyState == "complete"){
@@ -141,7 +142,7 @@ define(["dojo/_base/kernel","dojo/_base/lang", "dojo/_base/sniff", "dojo/ready",
 	dhm.onFontResize = function(){};
 	dhm._fontresize = function(){
 		dhm.onFontResize();
-	}
+	};
 
 	UnloadUtil.addOnUnload(function(){
 		// destroy our font resize iframe if we have one
diff --git a/dojox/html/styles.js b/dojox/html/styles.js
index 791f3a2..5415ed1 100755
--- a/dojox/html/styles.js
+++ b/dojox/html/styles.js
@@ -2,40 +2,39 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/
 	function(lang, ArrayUtil, Window, has) {
 	// summary:
 	//		Methods for creating and manipulating dynamic CSS Styles and Style Sheets
-	//
 	// example:
-	//		| dojox.html.createStyle("#myDiv input", "font-size:24px");
-	//			Creates Style #myDiv input, which can now be applied to myDiv, and
-	//			the inner input will be targeted
-	//		| dojox.html.createStyle(".myStyle", "color:#FF0000");
-	//			Now the class myStyle can be assigned to a node's className
-	var dh = lang.getObject("dojox.html",true);
+	//	|		dojox.html.createStyle("#myDiv input", "font-size:24px");
+	//		Creates Style #myDiv input, which can now be applied to myDiv, and
+	//		the inner input will be targeted
+	//	|		dojox.html.createStyle(".myStyle", "color:#FF0000");
+	//		Now the class myStyle can be assigned to a node's className
+
+	var dh = lang.getObject("dojox.html", true);
 	var dynamicStyleMap = {};
 	var pageStyleSheets = {};
 	var titledSheets = [];
 
-	dh.insertCssRule = function(/*String*/selector, /*String*/declaration, /*String*/styleSheetName){
+	dh.insertCssRule = function(/*String*/selector, /*String*/declaration, /*String?*/styleSheetName){
 		// summary:
-		//	Creates a style and attaches it to a dynamically created stylesheet
-		//	arguments:
-		//		selector:
-		//					A fully qualified class name, as it would appear in
-		//					a CSS dojo.doc. Start classes with periods, target
-		//					nodes with '#'. Large selectors can also be created
-		//					like:
-		//					| "#myDiv.myClass span input"
-		//		declaration:
-		//					A single string that would make up a style block, not
-		//					including the curly braces. Include semi-colons between
-		//					statements. Do not use JavaScript style declarations
-		//					in camel case, use as you would in a CSS dojo.doc:
-		//					| "color:#ffoooo;font-size:12px;margin-left:5px;"
-		//		styleSheetName: ( optional )
-		//					Name of the dynamic style sheet this rule should be
-		//					inserted into. If is not found by that name, it is
-		//					created. If no name is passed, the name "default" is
-		//					used.
-		//
+		//		Creates a style and attaches it to a dynamically created stylesheet
+		// selector:
+		//		A fully qualified class name, as it would appear in
+		//		a CSS dojo.doc. Start classes with periods, target
+		//		nodes with '#'. Large selectors can also be created
+		//		like:
+		// |	 "#myDiv.myClass span input"
+		// declaration:
+		//		A single string that would make up a style block, not
+		//		including the curly braces. Include semi-colons between
+		//		statements. Do not use JavaScript style declarations
+		//		in camel case, use as you would in a CSS dojo.doc:
+		//		| "color:#ffoooo;font-size:12px;margin-left:5px;"
+		// styleSheetName:
+		//		Name of the dynamic style sheet this rule should be
+		//		inserted into. If is not found by that name, it is
+		//		created. If no name is passed, the name "default" is
+		//		used.
+
 		var ss = dh.getDynamicStyleSheet(styleSheetName);
 		var styleText = selector + " {" + declaration + "}";
 		console.log("insertRule:", styleText);
@@ -58,7 +57,7 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/
 		//		The declaration is needed for cases of dupe selectors
 		// description: Only removes DYNAMICALLY created cssRules. If you
 		//		created it with dh.insertCssRule, it can be removed.
-		//
+
 		var ss;
 		var index=-1;
 		var nm;
@@ -93,25 +92,26 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/
 	};
 
 	dh.modifyCssRule = function(selector, declaration, styleSheetName){
-		//Not implemented - it seems to have some merit for changing some complex
-		//selectors. It's not much use for changing simple ones like "span".
-		//For now, simply write a new rule which will cascade over the first.
-		// summary
-		//	Modfies an existing cssRule
+		// summary:
+		//		Not implemented - it seems to have some merit for changing some complex
+		//		selectors. It's not much use for changing simple ones like "span".
+		//		For now, simply write a new rule which will cascade over the first.
+		//
+		//		Modifies an existing cssRule
 	};
 
-	dh.getStyleSheet = function(/*String*/styleSheetName){
+	dh.getStyleSheet = function(/*String?*/styleSheetName){
 		// summary:
 		//		Returns a style sheet based on the argument.
 		//		Searches dynamic style sheets first. If no matches,
 		//		searches document style sheets.
-		//
-		// argument: (optional)
+		// styleSheetName:
 		//		A title or an href to a style sheet. Title can be
 		//		an attribute in a tag, or a dynamic style sheet
 		//		reference. Href can be the name of the file.
 		//		If no argument, the assumed created dynamic style
 		//		sheet is used.
+
 		// try dynamic sheets first
 		if(dynamicStyleMap[styleSheetName || "default"]){
 			return dynamicStyleMap[styleSheetName || "default"];
@@ -130,24 +130,22 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/
 		//qualified name does not have to be passed)
 		var nm;
 		for ( nm in allSheets){
-			if(	allSheets[nm].href && allSheets[nm].href.indexOf(styleSheetName)>-1){
+			if( allSheets[nm].href && allSheets[nm].href.indexOf(styleSheetName)>-1){
 				return allSheets[nm];
 			}
 		}
 		return false; //StyleSheet or false
 	};
 
-	dh.getDynamicStyleSheet = function(/*String*/styleSheetName){
+	dh.getDynamicStyleSheet = function(/*String?*/styleSheetName){
 		// summary:
 		//		Creates and returns a dynamically created style sheet
 		//		used for dynamic styles
-		//
-		//	argument:
-		//			styleSheetName /* optional String */
-		//			The name given the style sheet so that multiple
-		//			style sheets can be created and referenced. If
-		//			no argument is given, the name "default" is used.
-		//
+		// styleSheetName:
+		//		The name given the style sheet so that multiple
+		//		style sheets can be created and referenced. If
+		//		no argument is given, the name "default" is used.
+
 		if(!styleSheetName){ styleSheetName="default"; }
 		if(!dynamicStyleMap[styleSheetName]){
 			if(Window.doc.createStyleSheet){ //IE
@@ -182,11 +180,11 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/
 		}
 	};
 
-	dh.disableStyleSheet = function(styleSheetName){
+	dh.disableStyleSheet = function(/* String */styleSheetName){
 		// summary:
 		//		Disables the dynamic style sheet with the name passed in the
 		//		argument. If no arg is passed, defaults to the default style sheet.
-		//
+
 		var ss = dh.getStyleSheet(styleSheetName);
 		if(ss){
 			if(ss.sheet){
@@ -197,7 +195,7 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/
 		}
 	};
 
-	dh.activeStyleSheet = function(/*?String*/title){
+	dh.activeStyleSheet = function(/*String?*/title){
 		// summary:
 		//		Getter/Setter
 		// description:
@@ -205,7 +203,7 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/
 		//		toggle-able style sheets are disabled.
 		//		If no argument is passed, returns currently enabled
 		//		style sheet.
-		//
+
 		var sheets = dh.getToggledStyleSheets();
 		var i;
 		if(arguments.length === 1){
@@ -224,24 +222,24 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/
 	};
 
 	dh.getPreferredStyleSheet = function(){
-		// summary
-		//	Returns the style sheet that was initially enabled
-		//	on document launch.
-		//TODO
+		// summary:
+		//		Returns the style sheet that was initially enabled
+		//		on document launch.
+		//		TODO, does not work.
 	};
 
+	//	TODO: Sets of style sheets could be grouped according to
+	//			an ID and used in sets, much like different
+	//			groups of radio buttons. It would not however be
+	//			according to W3C spec
+	//
 	dh.getToggledStyleSheets = function(){
 		// summary:
 		//		Searches HTML for style sheets that are "toggle-able" -
 		//		can be enabled and disabled. These would include sheets
 		//		with the title attribute, as well as the REL attribute.
-		//	returns:
+		// returns:
 		//		An array of all toggle-able style sheets
-		//	TODO: Sets of style sheets could be grouped according to
-		//			an ID and used in sets, much like different
-		//			groups of radio buttons. It would not however be
-		//			according to W3C spec
-		//
 		var nm;
 		if(!titledSheets.length){
 			var sObjects = dh.getStyleSheets();
@@ -254,17 +252,14 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "dojo/_base/
 		return titledSheets; //Array
 	};
 
+	//TODO: Does not recursively search for @imports, so it will
+	//		only go one level deep.
 	dh.getStyleSheets = function(){
 		// summary:
 		//		Collects all the style sheets referenced in the HTML page,
-		//		including any incuded via @import.
-		//
-		//	returns:
+		//		including any included via @import.
+		// returns:
 		//		An hash map of all the style sheets.
-		//
-		//TODO: Does not recursively search for @imports, so it will
-		//		only go one level deep.
-		//
 		if(pageStyleSheets.collected) {return pageStyleSheets;}
 		var sheets = Window.doc.styleSheets;
 		ArrayUtil.forEach(sheets, function(n){
diff --git a/dojox/html/tests/entities.js b/dojox/html/tests/entities.js
index 9de34d2..dec6815 100755
--- a/dojox/html/tests/entities.js
+++ b/dojox/html/tests/entities.js
@@ -6,9 +6,9 @@ doh.register("dojox.html.tests.entities",
 		{
 			name: "Encode:  Basic HTML Entities",
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of basic encoding of characters considered HTML entities
-				//	description:
+				// description:
 				//		Simple test of basic encoding of characters considered HTML entities
 				var txt = "This is some \" text \" with & entities inside it that <need to be escaped>";
 				var expected = "This is some " text " with & entities inside it that <need to be escaped>";
@@ -19,9 +19,9 @@ doh.register("dojox.html.tests.entities",
 		{
 			name: "Decode:  Basic HTML Entities",
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of basic encoding of characters considered HTML entities
-				//	description:
+				// description:
 				//		Simple test of basic encoding of characters considered HTML entities
 				var txt = "This is some " text " with & entities inside it that <need to be escaped>";
 				var expected = "This is some \" text \" with & entities inside it that <need to be escaped>";
@@ -32,9 +32,9 @@ doh.register("dojox.html.tests.entities",
 		{
 			name: "Encode:  Basic Latin Entities",
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of basic encoding of characters considered Latin type entities
-				//	description:
+				// description:
 				//		Simple test of basic encoding of characters considered Latin type entities
 				var txt = "";
 				var expected = "";
@@ -51,9 +51,9 @@ doh.register("dojox.html.tests.entities",
 		{
 			name: "Decode:  Basic Latin Entities",
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of basic decoding of characters considered Latin type entities
-				//	description:
+				// description:
 				//		Simple test of basic decoding of characters considered Latin type entities
 					  var txt = "";
 					  var expected = "";
@@ -70,9 +70,9 @@ doh.register("dojox.html.tests.entities",
 		{
 			name: "Encode:  Custom entity map",
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of basic encoding using a custom map instead of the default ones.
-				//	description:
+				// description:
 				//		Simple test of basic encoding using a custom map instead of the default ones.
 				var txt = "This is some \" text with & entities inside it that <need to be escaped>";
 				var expected = "This is some " text with & entities inside it that <need to be escaped>";
@@ -83,9 +83,9 @@ doh.register("dojox.html.tests.entities",
 		{
 			name: "Decode:  Custom entity map",
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of basic decoding using a custom map instead of the default ones.
-				//	description:
+				// description:
 				//		Simple test of basic decoding using a custom map instead of the default ones.
 				var txt = "This is some " text with & entities inside it that <need to be escaped>";
 				var expected = "This is some \" text with & entities inside it that <need to be escaped>";
diff --git a/dojox/html/tests/remote/commentedStyles.html b/dojox/html/tests/remote/commentedStyles.html
new file mode 100755
index 0000000..0fcf878
--- /dev/null
+++ b/dojox/html/tests/remote/commentedStyles.html
@@ -0,0 +1,30 @@
+<html>
+	<head>
+		<style>
+			.myClass {
+				display: none;
+			}
+		</style>
+		<!-- Commented out as a test that the load code for content pane does NOT include it
+			 as script content.
+		<STYLE>
+			.myClass.myClass2 {
+				display: inline;
+			}
+			@import "remoteCss1.css";
+		</STYLE>
+		<link rel="stylesheet" type="text/css" href="remoteCss2.css" />
+		-->
+		<script>
+			//This sets a flag to indicate that the page has loaded and is checked
+			//in the testcase.
+			window.__remotePaneLoaded = true;
+		</script>
+	</head>
+	<body>  
+		<span class="myClass myClass2" id="n1"></span>
+		<span class="myClass myClass3" id="n2"></span>
+		<span class="myClass myClass4" id="n3"></span>
+		Some simple content.
+	</body>
+</html>
diff --git a/dojox/html/tests/remote/remoteCss1.css b/dojox/html/tests/remote/remoteCss1.css
new file mode 100644
index 0000000..37285b8
--- /dev/null
+++ b/dojox/html/tests/remote/remoteCss1.css
@@ -0,0 +1,3 @@
+.myClass.myClass3 {
+	display: "inline";
+}
diff --git a/dojox/html/tests/remote/remoteCss2.css b/dojox/html/tests/remote/remoteCss2.css
new file mode 100644
index 0000000..e56008a
--- /dev/null
+++ b/dojox/html/tests/remote/remoteCss2.css
@@ -0,0 +1,3 @@
+.myClass.myClass4 {
+	display: "inline";
+}
diff --git a/dojox/html/tests/test_ellipsis.html b/dojox/html/tests/test_ellipsis.html
index dfba203..a1b7a38 100644
--- a/dojox/html/tests/test_ellipsis.html
+++ b/dojox/html/tests/test_ellipsis.html
@@ -7,7 +7,7 @@
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: false"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: false"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.html.ellipsis");
 		
diff --git a/dojox/html/tests/test_metrics.html b/dojox/html/tests/test_metrics.html
index ced9ecd..1100898 100644
--- a/dojox/html/tests/test_metrics.html
+++ b/dojox/html/tests/test_metrics.html
@@ -6,7 +6,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, fontSizeWatch: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, fontSizeWatch: true"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.html.metrics");
diff --git a/dojox/html/tests/test_metrics_getTextBox.html b/dojox/html/tests/test_metrics_getTextBox.html
index 91611af..e0af379 100644
--- a/dojox/html/tests/test_metrics_getTextBox.html
+++ b/dojox/html/tests/test_metrics_getTextBox.html
@@ -12,7 +12,7 @@
             .test { font-family: Times, Times New Roman, serif; font-weight: bold; font-size: 12pt; }
             .sample { clear: both; float: left; background-color: #ffd; border: 1px black solid; margin: 0; padding: 0; overflow: hidden; } 
         </style>
-        <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+        <script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
         <script type="text/javascript">
             dojo.require("dojox.html.metrics");
 
diff --git a/dojox/html/tests/test_set.html b/dojox/html/tests/test_set.html
index beb2fb7..f657eaa 100644
--- a/dojox/html/tests/test_set.html
+++ b/dojox/html/tests/test_set.html
@@ -3,20 +3,21 @@
 <html>
 <head>
 	<title>dojox.html.set test</title>
-	<script >
-	function fixPngIE6(){
-		if(this.complete && dojo.isIE < 7){
-			var r = this.runtimeStyle;
-			if(/.png$/i.test(this.src)){
-				r.height = this.height;
-				r.width = this.width;
-				r.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.src+"');";
-				this.src = this.currentStyle.backgroundImage.replace(/url\(\s*['"]?(.+?)['"]?\s*\)/, "$1");
+	<script>
+		var isIE;
+		function fixPngIE6(){
+			if(this.complete && isIE < 7){
+				var r = this.runtimeStyle;
+				if(/.png$/i.test(this.src)){
+					r.height = this.height;
+					r.width = this.width;
+					r.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.src+"');";
+					this.src = this.currentStyle.backgroundImage.replace(/url\(\s*['"]?(.+?)['"]?\s*\)/, "$1");
+				}
+				this.className = this.className.replace('run_png_fix', "");
+				r.behaviour = 'none';
 			}
-			this.className = this.className.replace('run_png_fix', "");
-			r.behaviour = 'none';
 		}
-	}
 	</script>
 	<style type='text/css'>
 		.run_png_fix {
@@ -24,25 +25,35 @@
 			behaviour: expression(fixPngIE6.call(this));
 		}
 	</style>
-	<script src='../../../dojo/dojo.js' djConfig='isDebug:true, parseOnLoad:true'></script>
+	<script src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad:true, async:true"></script>
 	<script>
-		dojo.require('doh.runner');
-		dojo.require('dojo.html');
-		dojo.require('dojox.html/_base');
-		dojo.require('dojox.html');
-		dojo.require('dojo.parser');
-		dojo.require('dojo._base.url');
-
 		// used to test if we fire scrips to document scope
 		function documentCallback(){
 			arguments.callee.reached = true;
 			//console.debug('reached');
-		}
+		};
 		var unTypedVarInDocScope; // a closure test to make sure we can reach this from evaled scripts
 
-		var node1, setter1, setter2;
+		require([
+			"doh/runner",
+			"dojo/dom",
+			"dojo/dom-geometry",
+			"dojo/dom-style",
+			"dojo/_base/lang",
+			"dojo/parser",
+			"dojo/ready",
+			"dojo/sniff",
+			"dojo/_base/url",
+			"dojo/_base/xhr",
+			"dojox/html",		// the module we are testing
+			"dojo/domReady!"
+		], function(doh, dom, domGeom, domStyle, lang, parser, ready, has, _Url, xhr, html){
+
+			// Used by fixPngIE6() above
+			isIE = has("ie");
+	
+			var node1, setter1, setter2;
 
-		dojo.addOnLoad(function(){
 			/* 
 				These tests are largely borrowed from dojox.layout.ContentPane's testsuite
 				They provide coverage for the basic use of the:
@@ -50,456 +61,397 @@
 				
 				We also need to test a couple other scenarios that dojox.html.set allows for: 
 				Reuse of a Setter across different node contexts
-				
-			
 			*/
 
-			node1 = dojo.byId('node1');
-			setter1 = new dojox.html._ContentSetter({
+			node1 = dom.byId('node1');
+			setter1 = new html._ContentSetter({
 				node: node1
 			});
 
-			function ieTrimSpaceBetweenTags(str){
-				return str.replace(/(<[a-z]*[^>]*>)\s*/ig, "$1");
-			}
-
 			doh.register("basicChecks", [
-					{
-						name: 'setContent',
-						runTest: function(t){
-							// test that setContent on a simple node does in fact set it
-							console.log("basicChecks: " + this.name);
-							var msg = "Simple Test";
-							
-							dojox.html.set(node1, msg);
-							t.assertEqual(msg, node1.innerHTML);
-							console.log("/basicChecks: " + this.name);
-						}
+				{
+					name: 'setContent',
+					runTest: function(t){
+						// test that setContent on a simple node does in fact set it
+						console.log("basicChecks: " + this.name);
+						var msg = "Simple Test";
+						
+						html.set(node1, msg);
+						t.assertEqual(msg, node1.innerHTML);
+						console.log("/basicChecks: " + this.name);
 					}
-				]
-			);
-
-			doh.register("pathAdjustments",
-				[
-					{
-						setUp: function() {
-							// setup text fixture for these pathAdjustments tests
-							// we use a _Setter instance rather than dojox.html.set
-							// as the tests include successive sets and depend on prior settings and results
-							setter2 = new dojox.html._ContentSetter({ node: node1 });
-							
-						},
-						name: 'cssPathAdjustments',
-						runTest: function(t){
-							// test that when you setContent, using the adjustPaths and renderStyles options
-							// the paths in the css are corrected for the current document
-							console.log("pathAdjustments: " + this.name);
-
-							// we do this test as one big string to emulate as good as possible, 
-							// but split it later to easily see where we failed
-							var cssText = ".easy{ background-image:url(images/image.png) }\n"
-							+".dontReplaceEasy{ background-image:url(images/images/image.png) }\n"
-							+".hardurl{background-image:url(\t \"../../source/~test/%20t'e(s)t.gif(\"1')?foo=bar11103&bar=baz-foo\"  \t);}body{};\n"
-							+".file{background-image: url(file:///home/nobody/image.png);}\n"
-							+".http{background-image: url(http://dojotoolkit.org/image.png);}\n"
-							+".https{background-image: url(https://dojotoolkit.org/image.png);}\n"
-							+".nonRelative{background-image:url(/toplevelfolder/image.gif);}\n"
-							+'@import "css/main.css";' + "\n at import \t'css/Newbee Url.css'\t;\n"
-							+"@import 'http://dojotoolkit.org/dojo.css';\n"
-							+"  @import 'you/never/thought/' print;\n"
-							+' @import url("it/would/work") tv, screen;'+"\n"
-							+' @import url(/did/you/now.css);'+"\n"
-							+' @import "yes.i.did";';
-							
-							var setParams = {
-								referencePath: "deep/nested/file",
-								adjustPaths: 1,
-								renderStyles: 1
-							};
-							
-							var adjustedCss;
-
-							// hijack internals to snatch the styles before they are inserted to DOM (DOM messes formating)
-							var oldFunc = setter2._renderStyles;
-							console.log("in cssPathAdjustments, returning function");
-
-							setter2._renderStyles = function(styles){
-								adjustedCss = styles.join();
-							};
-							console.log("in cssPathAdjustments, calling set");
-							setter2.set('<style>'+cssText+'</style>', setParams);
-							console.log("in cssPathAdjustments, done calling set");
-							
-							setter2._renderStyles = oldFunc;
-
-							adjustedCss = adjustedCss.split("\n");
-
-							var expectedCss = (".easy{ background-image:url(deep/nested/images/image.png) }\n"
-							+".dontReplaceEasy{ background-image:url(deep/nested/images/images/image.png) }\n"
-							+".hardurl{background-image:url(source/~test/%20t'e(s)t.gif(\"1')?foo=bar11103&bar=baz-foo);}body{};\n"
-							+".file{background-image: url(file:///home/nobody/image.png);}\n"
-							+".http{background-image: url(http://dojotoolkit.org/image.png);}\n"
-							+".https{background-image: url(https://dojotoolkit.org/image.png);}\n"
-							+".nonRelative{background-image:url(/toplevelfolder/image.gif);}\n"
-							+"@import \"deep/nested/css/main.css\";\n at import \"deep/nested/css/Newbee Url.css\"\t;\n"
-							+"@import 'http://dojotoolkit.org/dojo.css';\n"
-							+"  @import \"deep/nested/you/never/thought/\" print;\n"
-							+' @import url(deep/nested/it/would/work) tv, screen;'+"\n"
-							+' @import url(/did/you/now.css);'+"\n"
-							+' @import "deep/nested/yes.i.did";').split("\n");
-
-							// we split and loop to get a faster hint of where it failed
-							for(var i = 0; i < expectedCss.length; i++){
-								t.assertEqual(expectedCss[i], adjustedCss[i]);
-							}
-						},
-						tearDown: function(){
-							delete setter2.adjustPaths; // get back to defaults
-							delete setter2.renderStyles;
-						}
+				}
+			]);
+
+			doh.register("pathAdjustments", [
+				{
+					setUp: function() {
+						// setup text fixture for these pathAdjustments tests
+						// we use a _Setter instance rather than dojox.html.set
+						// as the tests include successive sets and depend on prior settings and results
+						setter2 = new html._ContentSetter({ node: node1 });
+						
 					},
-					{
-						name: 'htmlPathAdjustments',
-						timeout: 1800,
-						runTest: function(t){
-							console.log("pathAdjustments: " + this.name);
-							var d = new t.Deferred();
-							setTimeout(d.getTestCallback(
-								function(){
-									console.log("pathAdjustments: htmlPathAdjustments, in callback");
-									console.log("executeScripts: %s, cleanContent: %s, referencePath: %s, renderStyles: %s", setter2.executeScripts, setter2.cleanContent, setter2.referencePath, setter2.renderStyles);
-									// check that images and styles have been applied
-									var cb = dojo.contentBox(dojo.byId('imgTest'));
-											//dojo.getComputedStyle(dojo.byId('imgTest'));
-									t.assertEqual(188, cb.w);
-									t.assertEqual(125, cb.h);
-
-									// make sure we didn't mess up the other inline styles
-									cb = dojo.contentBox(dojo.byId('inlineStyleTest'));
-									t.assertEqual(188, cb.w);
-									t.assertEqual(125, cb.h);
-
-									// make sure it is the correct image
-									var cs = dojo.getComputedStyle(dojo.byId('inlineStyleTest'));
-									var url = cs.backgroundImage;
-									//remove url(..)
-									url = url.replace(/^\s?url\(['"]?/, "").replace(/['"]?\);?\s?$/, ""); 
-									// compare image url to full path of this document
-									imageUrl = dojo.moduleUrl('dojox', 'html/tests/images/testImage.gif');
-									console.log(new dojo._Url(document.location, imageUrl).toString(), url);
-									t.assertEqual(new dojo._Url(document.location, imageUrl).toString(), url);
-
-									// make sure we loaded the <link rel='stylesheet' correctly
-									var mb = dojo.marginBox(dojo.byId('linkCssTest'));
-									t.assertEqual(112, mb.w); // 100px  + 2px border + 4px margin = 112px
-									t.assertEqual(112, mb.h);
-
-									// make sure we loaded the <style>@import '...'; correctly
-									mb = dojo.marginBox(dojo.byId('importCssTest'));
-									t.assertEqual(110, mb.w); // 100px + 1px border + 4px margin = 110px
-									t.assertEqual(110, mb.h);
-
-									// make sure we didn't render the <link media='print' rel='stylesheet'
-									var mb = dojo.marginBox(dojo.byId('linkMediaTest'));
-									t.assertEqual(212, mb.w); // 100px  + 2px border + 4px margin = 112px
-									t.assertEqual(212, mb.h);
-
-									// make sure we didn't render the <style media='print'>@import '...';
-									mb = dojo.marginBox(dojo.byId('importMediaTest'));
-									t.assertEqual(210, mb.w); // 100px + 1px border + 4px margin = 110px
-									t.assertEqual(210, mb.h);
-									console.log("/pathAdjustments: htmlPathAdjustments, in callback");
-								}
-							), 1500);
-
-							console.log("pathAdjustments: " + this.name + ": requesting content");
-							var remoteUrl = dojo.moduleUrl("dojox", 'html/tests/remote/getResponse.php?mode=htmlPaths'); 
-							
-							dojo.xhrGet({
-								url: remoteUrl, 
-								load: function(data) {
-									console.log("pathAdjustments: htmlPathAdjustments, handling response");
-									setter2.set(data, {
-										adjustPaths: 1, 
-										referencePath: remoteUrl.toString(),
-										renderStyles: 1
-									}); 
-									console.log("/pathAdjustments: htmlPathAdjustments, handling response");
-								}
-							});
-							return d;
-						},
-						tearDown: function(){
-							delete setter2.adjustPaths; // get back to defaults
-							delete setter2.renderStyles;
+					name: 'cssPathAdjustments',
+					runTest: function(t){
+						// test that when you setContent, using the adjustPaths and renderStyles options
+						// the paths in the css are corrected for the current document
+						console.log("pathAdjustments: " + this.name);
+
+						// we do this test as one big string to emulate as good as possible, 
+						// but split it later to easily see where we failed
+						var cssText = ".easy{ background-image:url(images/image.png) }\n"
+						+".dontReplaceEasy{ background-image:url(images/images/image.png) }\n"
+						+".hardurl{background-image:url(\t \"../../source/~test/%20t'e(s)t.gif(\"1')?foo=bar11103&bar=baz-foo\"  \t);}body{};\n"
+						+".file{background-image: url(file:///home/nobody/image.png);}\n"
+						+".http{background-image: url(http://dojotoolkit.org/image.png);}\n"
+						+".https{background-image: url(https://dojotoolkit.org/image.png);}\n"
+						+".nonRelative{background-image:url(/toplevelfolder/image.gif);}\n"
+						+'@import "css/main.css";' + "\n at import \t'css/Newbee Url.css'\t;\n"
+						+"@import 'http://dojotoolkit.org/dojo.css';\n"
+						+"  @import 'you/never/thought/' print;\n"
+						+' @import url("it/would/work") tv, screen;'+"\n"
+						+' @import url(/did/you/now.css);'+"\n"
+						+' @import "yes.i.did";';
+						
+						var setParams = {
+							referencePath: "deep/nested/file",
+							adjustPaths: 1,
+							renderStyles: 1
+						};
+						
+						var adjustedCss;
+
+						// hijack internals to snatch the styles before they are inserted to DOM (DOM messes formating)
+						var oldFunc = setter2._renderStyles;
+						console.log("in cssPathAdjustments, returning function");
+
+						setter2._renderStyles = function(styles){
+							adjustedCss = styles.join();
+						};
+						console.log("in cssPathAdjustments, calling set");
+						setter2.set('<style>'+cssText+'</style>', setParams);
+						console.log("in cssPathAdjustments, done calling set");
+						
+						setter2._renderStyles = oldFunc;
+
+						adjustedCss = adjustedCss.split("\n");
+
+						var expectedCss = (".easy{ background-image:url(deep/nested/images/image.png) }\n"
+						+".dontReplaceEasy{ background-image:url(deep/nested/images/images/image.png) }\n"
+						+".hardurl{background-image:url(source/~test/%20t'e(s)t.gif(\"1')?foo=bar11103&bar=baz-foo);}body{};\n"
+						+".file{background-image: url(file:///home/nobody/image.png);}\n"
+						+".http{background-image: url(http://dojotoolkit.org/image.png);}\n"
+						+".https{background-image: url(https://dojotoolkit.org/image.png);}\n"
+						+".nonRelative{background-image:url(/toplevelfolder/image.gif);}\n"
+						+"@import \"deep/nested/css/main.css\";\n at import \"deep/nested/css/Newbee Url.css\"\t;\n"
+						+"@import 'http://dojotoolkit.org/dojo.css';\n"
+						+"  @import \"deep/nested/you/never/thought/\" print;\n"
+						+' @import url(deep/nested/it/would/work) tv, screen;'+"\n"
+						+' @import url(/did/you/now.css);'+"\n"
+						+' @import "deep/nested/yes.i.did";').split("\n");
+
+						// we split and loop to get a faster hint of where it failed
+						for(var i = 0; i < expectedCss.length; i++){
+							t.assertEqual(expectedCss[i], adjustedCss[i]);
 						}
 					},
-					{
-						name: 'renderStylesOfByDefaultAndOldDeleted',
-						timeout: 1800,
-						runTest: function(t){
-							var d = new t.Deferred();
-							console.log("pathAdjustments: " + this.name);
-
-							setTimeout(d.getTestCallback(
-								function(){
-									// innerHTML'ing <link tags works in some browser (IE, moz), but not all
-									// we can't test if LINK was loaded this way
-
-									// make sure we didn't load the <link rel='stylesheet'
-									//var mb = dojo.marginBox(dojo.byId('linkCssTest'));
-									//t.assertFalse(112 == mb.w);
-									//t.assertFalse(112 == mb.h);
-
-									// make sure we didn't load the <style>@import '...';
-									var mb = dojo.marginBox(dojo.byId('importCssTest'));
-									t.assertFalse(110 == mb.w);
-									t.assertFalse(110 == mb.h);
-								}
-							), 1500);
-
-							var remoteUrl = dojo.moduleUrl("dojox", 'html/tests/remote/getResponse.php?mode=htmlPaths'); 
-							dojo.xhrGet({
-								url: remoteUrl, 
-								load: function(data) {
-									console.log("pathAdjustments: renderStylesOfByDefaultAndOldDeleted, handling response");
-									setter2.set(data, {
-										adjustPaths: 1, 
-										referencePath: remoteUrl.toString()
-									}); 
-									console.log("/pathAdjustments: htmlPathAdjustments, handling response");
-								}
-							});
-							return d;
-						},
-						tearDown: function(){
-							delete setter2.adjustPaths;
-						}
+					tearDown: function(){
+						delete setter2.adjustPaths; // get back to defaults
+						delete setter2.renderStyles;
 					}
-				]
-			);
-
-			doh.register("scriptTests",
-				[
-					{
-						name: 'leaveDojoMethodScriptsAsIs',
-						runTest: function(t){
-							console.log("scriptTests: " + this.name);
-							dojox.html.set(node1, 
-								"<"
-								+"script type='dojo/method'>unTypedVarInDocScope = 'failure';<"
-								+"/script>", 
-								{
-									executeScripts: true
-								}
-							);
-
-							var d = new t.Deferred();
-							// IE req to async this test
-							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('undefined', typeof unTypedVarInDocScope);
-								t.assertFalse(unTypedVarInDocScope == 'failure');
-							}), 40);
-
-							return d;
-						}
-					},
-					{
-						name: 'scripts_evals_in_global_scope',
-						timeout: 1800, // grabing remote js, wait for that
-						runTest: function(t){
-							console.log("scriptTests: " + this.name);
-							var remoteUrl = dojo.moduleUrl("dojox", "html/tests/remote/getResponse.php?mode=remoteJsTrue");
-							dojox.html.set(
-								node1, 
-								"<"
-								+"script>function scriptsInGlobalClicked(){ documentCallback(); }<"
-								+"/script><"+"script src='" + remoteUrl +"'></"
-								+"script>"+"<a href='javascript:scriptsInGlobalClicked()' "
-									+"onfocus='scriptsInGlobalClicked();' id='anchorTag'>test</a>", 
-								{
-									executeScripts: true
-								}
-							);
-
-							var link = dojo.byId('anchorTag');
-							dojo.isFunction(link.click) ? /*others*/ link.click() : /*moz*/ link.focus();
-							var d = new t.Deferred();
-					
-							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('boolean', typeof documentCallback.reached);
-								t.assertTrue(documentCallback.reached);
-								t.assertTrue(unTypedVarInDocScope);
-							}), 40);
-							return d;
-						}
-					},
-					{
-						name:'scriptsEvalsInOrder',
-						timeout: 1800,// grabing remote js, wait for that
-						runTest: function(t){
-							console.log("scriptTests: " + this.name);
-							var remoteUrl = dojo.moduleUrl("dojox", "html/tests/remote/getResponse.php?mode=remoteJsFalse");
-							dojox.html.set(node1, "<"
-								+"script src='"+ remoteUrl +"'><"
-								+"/script><"+"script>unTypedVarInDocScope = 1;<"
-								+"/script>", 
-								{
-									executeScripts: true
-								}); // scripts only test
-
-							// we need to make this async because of IEs strange events loops
-							var d = new t.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('number', typeof unTypedVarInDocScope);
-								t.assertEqual(1, unTypedVarInDocScope);
-							}), 40);
-							return d;
-						}
-					},
-					{
-						name: 'scriptsWithTypeTextJavascript',
-						runTest: function(t){
-							console.log("scriptTests: " + this.name);
-							dojox.html.set(node1, "<"
-								+"script type='text/javascript'> unTypedVarInDocScope = 'text/javascript'; <"
-								+"/script>", {
-									executeScripts: true
-								}
-							);
-
-							var d = new t.Deferred();
-							// IE needs async here
-							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('text/javascript', unTypedVarInDocScope);
-							}), 40);
-							return d;
-						}
+				},
+				{
+					name: 'htmlPathAdjustments',
+					timeout: 1800,
+					runTest: function(t){
+						console.log("pathAdjustments: " + this.name);
+						var d = new t.Deferred();
+						setTimeout(d.getTestCallback(
+							function(){
+								console.log("pathAdjustments: htmlPathAdjustments, in callback");
+								console.log("executeScripts: %s, cleanContent: %s, referencePath: %s, renderStyles: %s", setter2.executeScripts, setter2.cleanContent, setter2.referencePath, setter2.renderStyles);
+								// check that images and styles have been applied
+								var cb = domGeom.getContentBox(dom.byId('imgTest'));
+										//domStyle.getComputedStyle(dom.byId('imgTest'));
+								t.assertEqual(188, cb.w);
+								t.assertEqual(125, cb.h);
+
+								// make sure we didn't mess up the other inline styles
+								cb = domGeom.getContentBox(dom.byId('inlineStyleTest'));
+								t.assertEqual(188, cb.w);
+								t.assertEqual(125, cb.h);
+
+								// make sure it is the correct image
+								var cs = domStyle.getComputedStyle(dom.byId('inlineStyleTest'));
+								var url = cs.backgroundImage;
+								//remove url(..)
+								url = url.replace(/^\s?url\(['"]?/, "").replace(/['"]?\);?\s?$/, ""); 
+								// compare image url to full path of this document
+								imageUrl = require.toUrl("dojox/html/tests/images/testImage.gif");
+								t.assertEqual(new _Url(document.location, imageUrl).toString(), url);
+
+								// make sure we loaded the <link rel='stylesheet' correctly
+								var mb = domGeom.getMarginBox(dom.byId('linkCssTest'));
+								t.assertEqual(112, mb.w); // 100px  + 2px border + 4px margin = 112px
+								t.assertEqual(112, mb.h);
+
+								// make sure we loaded the <style>@import '...'; correctly
+								mb = domGeom.getMarginBox(dom.byId('importCssTest'));
+								t.assertEqual(110, mb.w); // 100px + 1px border + 4px margin = 110px
+								t.assertEqual(110, mb.h);
+
+								// make sure we didn't render the <link media='print' rel='stylesheet'
+								var mb = domGeom.getMarginBox(dom.byId('linkMediaTest'));
+								t.assertEqual(212, mb.w); // 100px  + 2px border + 4px margin = 112px
+								t.assertEqual(212, mb.h);
+
+								// make sure we didn't render the <style media='print'>@import '...';
+								mb = domGeom.getMarginBox(dom.byId('importMediaTest'));
+								t.assertEqual(210, mb.w); // 100px + 1px border + 4px margin = 110px
+								t.assertEqual(210, mb.h);
+								console.log("/pathAdjustments: htmlPathAdjustments, in callback");
+							}
+						), 1500);
+
+						console.log("pathAdjustments: " + this.name + ": requesting content");
+						var remoteUrl = require.toUrl("dojox/html/tests/remote/getResponse.php?mode=htmlPaths"); 
+						
+						xhr.get({
+							url: remoteUrl, 
+							load: function(data) {
+								console.log("pathAdjustments: htmlPathAdjustments, handling response");
+								setter2.set(data, {
+									adjustPaths: 1, 
+									referencePath: remoteUrl.toString(),
+									renderStyles: 1
+								}); 
+								console.log("/pathAdjustments: htmlPathAdjustments, handling response");
+							}
+						});
+						return d;
 					},
-					{
-						name:'scriptsWithHtmlComments',
-						runTest: function(t){
-							dojox.html.set(node1, "<"
-								+"script><!-- unTypedVarInDocScope = 2; --><"
-								+"/script>", {
-									cleanContent: 1,
-									executeScripts: 1 
-								}
-							);
-
-							var d = new t.Deferred();
-							// IE need a async here
-							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('number', typeof unTypedVarInDocScope);
-								t.assertEqual(2, unTypedVarInDocScope);
-							}), 40);
-
-							return d;
-						},
-						tearDown: function(){
-							node1.innerHTML = "";
-						}
+					tearDown: function(){
+						delete setter2.adjustPaths; // get back to defaults
+						delete setter2.renderStyles;
+					}
+				},
+				{
+					name: 'renderStylesOfByDefaultAndOldDeleted',
+					timeout: 1800,
+					runTest: function(t){
+						var d = new t.Deferred();
+						console.log("pathAdjustments: " + this.name);
+
+						setTimeout(d.getTestCallback(
+							function(){
+								// innerHTML'ing <link tags works in some browser (IE, moz), but not all
+								// we can't test if LINK was loaded this way
+
+								// make sure we didn't load the <link rel='stylesheet'
+								//var mb = domGeom.getMarginBox(dom.byId('linkCssTest'));
+								//t.assertFalse(112 == mb.w);
+								//t.assertFalse(112 == mb.h);
+
+								// make sure we didn't load the <style>@import '...';
+								var mb = domGeom.getMarginBox(dom.byId('importCssTest'));
+								t.assertFalse(110 == mb.w);
+								t.assertFalse(110 == mb.h);
+							}
+						), 1500);
+
+						var remoteUrl = require.toUrl("dojox/html/tests/remote/getResponse.php?mode=htmlPaths"); 
+						xhr.get({
+							url: remoteUrl, 
+							load: function(data) {
+								console.log("pathAdjustments: renderStylesOfByDefaultAndOldDeleted, handling response");
+								setter2.set(data, {
+									adjustPaths: 1, 
+									referencePath: remoteUrl.toString()
+								}); 
+								console.log("/pathAdjustments: htmlPathAdjustments, handling response");
+							}
+						});
+						return d;
 					},
-					{
-						name:'scriptsWithCData',
-						runTest: function(t){
-							dojox.html.set(node1, "<"
-								+"script><![CDATA[ unTypedVarInDocScope = 3; ]]><"
-								+"/script>", {
-									cleanContent: 1,
-									executeScripts: 1 
-								}
-							);
-
-							var d = new t.Deferred();
-							// IE need a async here
-							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('number', typeof unTypedVarInDocScope);
-								t.assertEqual(3, unTypedVarInDocScope);
-							}), 40);
-
-							return d;
-						},
-						tearDown: function(){
-							node1.innerHTML = "";
-						}
+					tearDown: function(){
+						delete setter2.adjustPaths;
+					}
+				}
+			]);
+
+			doh.register("scriptTests", [
+				{
+					name: 'leaveDojoMethodScriptsAsIs',
+					runTest: function(t){
+						console.log("scriptTests: " + this.name);
+						html.set(node1,
+							"<"
+							+"script type='dojo/method'>unTypedVarInDocScope = 'failure';<"
+							+"/script>", 
+							{
+								executeScripts: true
+							}
+						);
+
+						var d = new t.Deferred();
+						// IE req to async this test
+						setTimeout(d.getTestCallback(function(){
+							t.assertEqual('undefined', typeof unTypedVarInDocScope);
+							t.assertFalse(unTypedVarInDocScope == 'failure');
+						}), 40);
+
+						return d;
+					}
+				},
+				{
+					name: 'scripts_evals_in_global_scope',
+					timeout: 1800, // grabing remote js, wait for that
+					runTest: function(t){
+						console.log("scriptTests: " + this.name);
+						var remoteUrl = require.toUrl("dojox/html/tests/remote/getResponse.php?mode=remoteJsTrue");
+						html.set(
+							node1, 
+							"<"
+							+"script>function scriptsInGlobalClicked(){ documentCallback(); }<"
+							+"/script><"+"script src='" + remoteUrl +"'></"
+							+"script>"+"<a href='javascript:scriptsInGlobalClicked()' "
+								+"onfocus='scriptsInGlobalClicked();' id='anchorTag'>test</a>", 
+							{
+								executeScripts: true
+							}
+						);
+
+						var link = dom.byId('anchorTag');
+						typeof link.click == "function" ? /*others*/ link.click() : /*moz*/ link.focus();
+						var d = new t.Deferred();
+				
+						setTimeout(d.getTestCallback(function(){
+							t.assertEqual('boolean', typeof documentCallback.reached);
+							t.assertTrue(documentCallback.reached);
+							t.assertTrue(unTypedVarInDocScope);
+						}), 400);
+						return d;
+					}
+				},
+				{
+					name:'scriptsEvalsInOrder',
+					timeout: 1800,// grabing remote js, wait for that
+					runTest: function(t){
+						console.log("scriptTests: " + this.name);
+						var remoteUrl = require.toUrl("dojox/html/tests/remote/getResponse.php?mode=remoteJsFalse");
+						html.set(node1, "<"
+							+"script src='"+ remoteUrl +"'><"
+							+"/script><"+"script>unTypedVarInDocScope = 1;<"
+							+"/script>", 
+							{
+								executeScripts: true
+							}); // scripts only test
+
+						// we need to make this async because of IEs strange events loops
+						var d = new t.Deferred();
+						setTimeout(d.getTestCallback(function(){
+							t.assertEqual('number', typeof unTypedVarInDocScope);
+							t.assertEqual(1, unTypedVarInDocScope);
+						}), 40);
+						return d;
+					}
+				},
+				{
+					name: 'scriptsWithTypeTextJavascript',
+					runTest: function(t){
+						console.log("scriptTests: " + this.name);
+						html.set(node1, "<"
+							+"script type='text/javascript'> unTypedVarInDocScope = 'text/javascript'; <"
+							+"/script>", {
+								executeScripts: true
+							}
+						);
+
+						var d = new t.Deferred();
+						// IE needs async here
+						setTimeout(d.getTestCallback(function(){
+							t.assertEqual('text/javascript', unTypedVarInDocScope);
+						}), 40);
+						return d;
+					}
+				},
+				{
+					name:'scriptsWithHtmlComments',
+					runTest: function(t){
+						html.set(node1, "<"
+							+"script><!-- unTypedVarInDocScope = 2; --><"
+							+"/script>", {
+								cleanContent: 1,
+								executeScripts: 1 
+							}
+						);
+
+						var d = new t.Deferred();
+						// IE need a async here
+						setTimeout(d.getTestCallback(function(){
+							t.assertEqual('number', typeof unTypedVarInDocScope);
+							t.assertEqual(2, unTypedVarInDocScope);
+						}), 40);
+
+						return d;
 					},
-					// FIXME: what /should/ container be in this context? 
-					{
-						name: 'replace_container_',
-						runTest: function(t){
-							unTypedVarInDocScope = 'failure';
-							dojox.html.set(node1, 
-								"<"
-								+"script>function testReplace(){"
-								+	"if(typeof _container_ != 'object'){return 'not replaced 1';}\n"
-								+	"if(_container_ != setter1){ return 'not replaced 2';}\n"
-								+	"if(!_container_ == setter1){ return 'not replaced 3';}\n"
-								+	"var tmp =_container_=dojo;\n"
-								+	"if(tmp != dojo){ return 'replaced when shouldnt 1';}\n"
-								+	"var tmp = _container_  \t \t = dojo;\n"
-								+	"if(tmp != dojo){ return 'replaced when shouldnt 2';}\n"
-								+	"return 'success';\n"
-								+"};\n"
-								+"unTypedVarInDocScope = testReplace();"
-								+"</"+"script>", {
-									executeScripts: 1, 
-									scriptHasHooks: true, 
-									scriptHookReplacement: function() { return "setter1"; }
-							});
-							
-							// let IE inhale here
-							var d = new t.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('success', unTypedVarInDocScope);
-							}), 40);
-							return d;
-						},
-						tearDown: function(){
-							node1.innerHTML = "";
-							unTypedVarInDocScope = "done";
-						}
+					tearDown: function(){
+						node1.innerHTML = "";
+					}
+				},
+				{
+					name:'scriptsWithCData',
+					runTest: function(t){
+						html.set(node1, "<"
+							+"script><![CDATA[ unTypedVarInDocScope = 3; ]]><"
+							+"/script>", {
+								cleanContent: 1,
+								executeScripts: 1 
+							}
+						);
+
+						var d = new t.Deferred();
+						// IE need a async here
+						setTimeout(d.getTestCallback(function(){
+							t.assertEqual('number', typeof unTypedVarInDocScope);
+							t.assertEqual(3, unTypedVarInDocScope);
+						}), 40);
+
+						return d;
 					},
-					
-					"t.assertEqual('done', unTypedVarInDocScope)",
-					
-					{
-						name: 'evalThenParse',
-						runTest: function(t){
-							dojo.global._evalThenParseResult = "";
-							// test the executeScripts / parse sequence
-							// by declaring a class that when instantiated returns true
-							dojox.html.set(node1, 
-								"<"+"script>"
-								+"_evalThenParseResult+='a';\n"
-								+"dojo.provide('dojox.html.tests.TestThinger');"
-								+"dojo.declare('dojox.html.tests.TestThinger', null, {"
-								+"  constructor: function() {"
-								+"	 _evalThenParseResult +='b';"
-								+"  }"
-								+"});"
-								+"</"+"script>\n"
-								+""
-								+"<div dojoType='dojox.html.tests.TestThinger'>\n"
-									+"<"+"script type='dojo/method'>dojo.global._evalThenParseResult +='c';</"+"script>\n"
-								+"</div>\n"
-								, {
-									executeScripts: 1, 
-									scriptHasHooks: false,
-									parseContent: true
-							});
-							
-							t.assertEqual('abc', dojo.global._evalThenParseResult);
-						},
-						tearDown: function(){
-							delete dojo.global._evalThenParseResult;
-						}
+					tearDown: function(){
+						node1.innerHTML = "";
 					}
-				]
-			);
+				},
 
+				{
+					name: 'asyncRequire',
+					runTest: function(t){
+						console.log("scriptTests: " + this.name);
+						html.set(node1,
+							"<"
+							+"script>require(['dojo/tests/resources/AMDWidget']);<"
+							+"/script><div data-dojo-type='dojo/tests/resources/AMDWidget' data-dojo-id='AMDWidgetId'>Hi</div>",
+							{
+								executeScripts: true,
+								parseContent: true
+							}
+						);
 
-			doh.register('regexRegressionAndSpeedtest',[
+						// This ready() callback should fire after the require() above completes, and the
+						// parser instantiates the AMDWidget
+						var d = new t.Deferred();
+						ready(d.getTestCallback(function(){
+							t.t(AMDWidgetId, "AMDWidget was loaded and created");
+						}));
+
+						return d;
+					}
+				}
+			]);
+
+			doh.register('regexRegressionAndSpeedtest', [
 				{
 					name: 'cssPathAdjustments',
 					runTest: function(t){
@@ -549,16 +501,16 @@
 						var adjustedCss;
 
 						// hijack internals to snatch the styles before they are inserted to DOM (DOM messes formating)
-						var oldFunc = dojox.html._ContentSetter.prototype._renderStyles;
-						dojox.html._ContentSetter.prototype._renderStyles = function(styles){
+						var oldFunc = html._ContentSetter.prototype._renderStyles;
+						html._ContentSetter.prototype._renderStyles = function(styles){
 							adjustedCss = styles.join();
 						};
 
 						var start = new Date();
-						dojox.html.set(node1, '<style>'+cssText+'</style>', setParams);
+						html.set(node1, '<style>'+cssText+'</style>', setParams);
 						var end = new Date();
 						
-						dojox.html._ContentSetter.prototype._renderStyles = oldFunc;
+						html._ContentSetter.prototype._renderStyles = oldFunc;
 
 						adjustedCss = adjustedCss.split("\n");
 						console.info('Time used to regex scan css and adjust relative paths within css:'+
@@ -650,31 +602,32 @@
 						var adjustedCss, adjustedHtml;
 
 						// hijack internals to snatch the styles before they are inserted to DOM (DOM messes formating)
-						var oldFunc = dojox.html._ContentSetter.prototype._renderStyles;
-						dojox.html._ContentSetter.prototype._renderStyles = function(styles){
+						var oldFunc = html._ContentSetter.prototype._renderStyles;
+						html._ContentSetter.prototype._renderStyles = function(styles){
 							adjustedCss = styles;
 							this.executeScripts = 0;
 						};
 
-						var oldSetFunc = dojox.html._ContentSetter.prototype.setContent;
-						dojox.html._ContentSetter.prototype.setContent = function(html){
+						var oldSetFunc = html._ContentSetter.prototype.setContent;
+						html._ContentSetter.prototype.setContent = function(html){
 							console.log("replaced setContent is called");
 							adjustedHtml = this.content;
 						};
 
+						// TODO: presumably this hack code doesn't work anymore after the AMD conversion of html._ContentSetter
 						var oldXhr = dojo.xhrGet;
 						dojo.xhrGet = function(){}; // kill script download
 
 						var start = new Date();
 
-						dojox.html.set(node1, htmlText, setParams);
+						html.set(node1, htmlText, setParams);
 
 						console.log("/calling set to clean and adjust paths");
 						var end = new Date();
 
 						// reset back to the way it was
-						dojox.html._ContentSetter.prototype._renderStyles = oldFunc;
-						dojox.html._ContentSetter.prototype.setContent = oldSetFunc;
+						html._ContentSetter.prototype._renderStyles = oldFunc;
+						html._ContentSetter.prototype.setContent = oldSetFunc;
 						dojo.xhrGet = oldXhr;
 
 						console.info('Time used to regex scan html/css and\n adjust relative paths (adjustPaths=true),\n copy scripts (executeScripts=true) and copy css innerText (renderStyles=true) and adjust paths in there \nTime:'+
@@ -700,7 +653,7 @@
 							adjCssBlock = adjustedCss[i].split('\n');
 
 							for(var j = 0; j < exCssBlock.length;j++){
-								t.assertEqual(dojo.trim(exCssBlock[j]), dojo.trim(adjCssBlock[j]));
+								t.assertEqual(lang.trim(exCssBlock[j]), lang.trim(adjCssBlock[j]));
 							}
 							
 						}
@@ -711,7 +664,7 @@
 				{
 					name:'IE_AlphaImageLoader_PathAdjustments',
 					runTest: function(t){
-						if(!dojo.isIE){
+						if(!has("ie")){
 							console.info('aborting test IE_AlphaImageLoader_PathAdjustments, you dont use IE');
 							return;
 						}
@@ -721,7 +674,7 @@
 							referencePath: "deep/"
 						};
 
-						var html = "<div style='width:10px;height:10px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=\"scale\", src=\"images/alpha(1).png\", nextProperty=\"useless\");'><!-- \n"
+						var sourceHtml = "<div style='width:10px;height:10px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=\"scale\", src=\"images/alpha(1).png\", nextProperty=\"useless\");'><!-- \n"
 						+" alpha png in IE 6 --></div>\n"
 						+"<style>\n"
 						+"	.ie_menu_png {"
@@ -748,7 +701,7 @@
 
 
 						for(var i = 0; i < 7; i++){
-							html += html;	
+							sourceHtml += sourceHtml;
 							expectedHtml += expectedHtml;
 							expectedCss += expectedCss;
 						}
@@ -756,13 +709,13 @@
 						var adjustedHtml, adjustedCss;
 
 						// hijack internals to snatch the content
-						var oldRenderStyles = dojox.html._ContentSetter.prototype._renderStyles;
-						var oldSetContent = dojox.html._ContentSetter.prototype.setContent;
-						dojox.html._ContentSetter.prototype._renderStyles = function(styles){ adjustedCss = styles.join(''); };
-						dojox.html._ContentSetter.prototype.setContent = function(cont){ adjustedHtml = this.content; };
+						var oldRenderStyles = html._ContentSetter.prototype._renderStyles;
+						var oldSetContent = html._ContentSetter.prototype.setContent;
+						html._ContentSetter.prototype._renderStyles = function(styles){ adjustedCss = styles.join(''); };
+						html._ContentSetter.prototype.setContent = function(cont){ adjustedHtml = this.content; };
 
 						var start = new Date();
-						dojox.html.set(node1, html, setParams);
+						html.set(node1, sourceHtml, setParams);
 						var end = new Date();
 
 						console.info('Time used to replace AlphaImageLoader(src="...") '
@@ -770,8 +723,8 @@
 									+' characters (roughly '+(Math.round(html.length/1024))+'Kb)');
 
 						// reset hijacked
-						dojox.html._ContentSetter.prototype._renderStyles = oldRenderStyles;
-						dojox.html._ContentSetter.prototype.setContent = oldSetContent;
+						html._ContentSetter.prototype._renderStyles = oldRenderStyles;
+						html._ContentSetter.prototype.setContent = oldSetContent;
 
 
 						// split on newline and run a check on each row to help debugging
@@ -787,8 +740,6 @@
 							t.assertEqual(expectedCss[i], adjustedCss[i]);
 						}
 						
-					},
-					tearDown: function(){
 					}
 				}
 			]);
@@ -800,7 +751,7 @@
 					// not to the cssFile that declares it
 
 					// demo a much better way of "Fixing" alpha png in IE6 than inlining in html
-					var html = "<img src='images/dojoLogo.png' class='run_png_fix'/>";
+					var imgHtml = "<img src='images/dojoLogo.png' class='run_png_fix'/>";
 
 					var showHowHtml = "<pre >\nCode used in IE transparent png example\n"
 								+"code (declared in main page, not through ContentPane)\n"
@@ -815,9 +766,9 @@
 								+"</style>\n\n...\n\nHtml feeded to ContentPane (or your main page):\n"
 								+"<img src='images/dojoLogo.png' class='run_png_fix'/>\n</pre>";
 
-					dojox.html.set(
+					html.set(
 						node1, 
-						html+showHowHtml, {
+						imgHtml + showHowHtml, {
 							executeScripts: 1,
 							renderStyles: 1
 						}
@@ -826,61 +777,60 @@
 			}]);
 
 			doh.register("setterReuse", [
-					{
-						// FIXME: finish this test!
-						name: 'renderStyles',
-						setUp: function() {
-							setter2 = new dojox.html._ContentSetter({
-								renderStyles: true, 
-								cleanContent: true,
-								node: dojo.byId("node2")
-							});
-							setter2.set('<style>#node2 { font-size: 18px }</style>New value');
-						},
-						runTest: function(t){
-							// test the fixture setup ok
-							var node2 = dojo.byId("node2"); 
-							t.assertEqual("New value", node2.innerHTML);
-							t.assertEqual("18px", dojo.style(node2, "fontSize"));
-							
-							// grab the styleNodes in case we need to remove them later - there should be exactly 1
-							// in the reuse scenario, this is what we have to do today
-							var node2_styleNodes = setter2._styleNodes; 
-							setter2._styleNodes = [];
-							t.assertEqual(1, node2_styleNodes.length);
-
-							// now reuse the setter on a different node
-							var node3 = setter2.node = dojo.byId("node3");
-							setter2.set('<style>#node3 { font-size: 24px }</style>Another New value');
-
-							// test the old node is still good, 
-							// and the new node got the correct value, style
-							t.assertEqual("New value", node2.innerHTML);
-							t.assertEqual("18px", dojo.style(node2, "fontSize"));
-
-							t.assertEqual("Another New value", node3.innerHTML);
-							t.assertEqual("24px", dojo.style(node3, "fontSize"));
-
-							// test the old styleNode is still around
-							t.assertEqual(1, node2_styleNodes.length);
-							// test we have just one in the new collection
-							t.assertEqual(1, setter2._styleNodes.length);
-							
-							// I guess you might want to do this...
-							// remove content and associated styles from the current and previous node
-							setter2.set("");
-							t.assertEqual(0, setter2._styleNodes.length);
-							t.assertFalse("24px" == dojo.style(node3, "fontSize"));
-							
-							setter2.node = node2;
-							setter2._styleNodes = node2_styleNodes;
-							setter2.set("");
-							t.assertEqual(0, setter2._styleNodes.length);
-							t.assertFalse("18px" == dojo.style(node2, "fontSize"));
-						}
+				{
+					// FIXME: finish this test!
+					name: 'renderStyles',
+					setUp: function() {
+						setter2 = new html._ContentSetter({
+							renderStyles: true, 
+							cleanContent: true,
+							node: dom.byId("node2")
+						});
+						setter2.set('<style>#node2 { font-size: 18px }</style>New value');
+					},
+					runTest: function(t){
+						// test the fixture setup ok
+						var node2 = dom.byId("node2"); 
+						t.assertEqual("New value", node2.innerHTML);
+						t.assertEqual("18px", domStyle.get(node2, "fontSize"));
+						
+						// grab the styleNodes in case we need to remove them later - there should be exactly 1
+						// in the reuse scenario, this is what we have to do today
+						var node2_styleNodes = setter2._styleNodes; 
+						setter2._styleNodes = [];
+						t.assertEqual(1, node2_styleNodes.length);
+
+						// now reuse the setter on a different node
+						var node3 = setter2.node = dom.byId("node3");
+						setter2.set('<style>#node3 { font-size: 24px }</style>Another New value');
+
+						// test the old node is still good, 
+						// and the new node got the correct value, style
+						t.assertEqual("New value", node2.innerHTML);
+						t.assertEqual("18px", domStyle.get(node2, "fontSize"));
+
+						t.assertEqual("Another New value", node3.innerHTML);
+						t.assertEqual("24px", domStyle.get(node3, "fontSize"));
+
+						// test the old styleNode is still around
+						t.assertEqual(1, node2_styleNodes.length);
+						// test we have just one in the new collection
+						t.assertEqual(1, setter2._styleNodes.length);
+						
+						// I guess you might want to do this...
+						// remove content and associated styles from the current and previous node
+						setter2.set("");
+						t.assertEqual(0, setter2._styleNodes.length);
+						t.assertFalse("24px" == domStyle.get(node3, "fontSize"));
+						
+						setter2.node = node2;
+						setter2._styleNodes = node2_styleNodes;
+						setter2.set("");
+						t.assertEqual(0, setter2._styleNodes.length);
+						t.assertFalse("18px" == domStyle.get(node2, "fontSize"));
 					}
-				]
-			);
+				}
+			]);
 
 			var remoteScriptsSetter;
 			var previousContent;
@@ -888,96 +838,157 @@
 				{
 					name: 'testCommentedScriptTag',
 					setUp: function() {
-						remoteScriptsSetter = new dojox.html._ContentSetter({
+						remoteScriptsSetter = new html._ContentSetter({
 							renderStyles: true, 
 							cleanContent: true,
 							executeScripts: true,
-							node: dojo.byId("node4")
+							node: dom.byId("node4")
 						});
-						previousContent = dojo.byId("node4").innerHTML;
+						previousContent = dom.byId("node4").innerHTML;
 					},
 					tearDown: function(){
-						dojo.byId("node4").innerHTML = previousContent;    
+						dom.byId("node4").innerHTML = previousContent;    
 					},
 					timeout: 10000,
 					runTest: function(t){
 						var deferred = new doh.Deferred(); 
-						var xhrDef = dojo.xhrGet({
+						var xhrDef = xhr.get({
 							url: "remote/commentedScript.html",
 							preventCache: true,
 							handleAs: "text"
 						});
-						xhrDef.addCallback(function(text){
-							remoteScriptsSetter.set(text);
-							var intv = setInterval(function(){
-								if(window.__remotePaneLoaded){
-									clearInterval(intv);
-									window.__remotePaneLoaded = null;
-									try{
-										//Test that entity characters in a src url for a script 
-										//are properly converted to correct form
-										var node = document.getElementById("should_not_be_here"); 
-										doh.assertTrue(node == null);
-										deferred.callback(true);
-									}catch(e){
-										deferred.errback(new Error(e));
+						xhrDef.then(
+							function(text){
+								remoteScriptsSetter.set(text);
+								var intv = setInterval(function(){
+									if(window.__remotePaneLoaded){
+										clearInterval(intv);
+										window.__remotePaneLoaded = null;
+										try{
+											//Test that entity characters in a src url for a script
+											//are properly converted to correct form
+											var node = document.getElementById("should_not_be_here");
+											doh.assertTrue(node == null);
+											deferred.callback(true);
+										}catch(e){
+											deferred.errback(new Error(e));
+										}
 									}
-								}
-							}, 500);
+								}, 500);
+							},
+							function(e){
+								deferred.errback(e);
+							}
+						);
+
+						return deferred;
+					}
+				},
+				{
+					name: 'testCommentedStyleTags',
+					setUp: function() {
+						remoteScriptsSetter = new html._ContentSetter({
+							renderStyles: true, 
+							cleanContent: true,
+							executeScripts: true,
+							node: dom.byId("node4")
 						});
-						xhrDef.addErrback(function(e){
-							deferred.errback(e);
+						previousContent = dom.byId("node4").innerHTML;
+					},
+					tearDown: function(){
+						dom.byId("node4").innerHTML = previousContent;    
+					},
+					timeout: 10000,
+					runTest: function(t){
+						var deferred = new doh.Deferred(); 
+						var xhrDef = xhr.get({
+							url: "remote/commentedStyles.html",
+							preventCache: true,
+							handleAs: "text"
 						});
+						xhrDef.then(
+							function(text){
+								remoteScriptsSetter.set(text);
+								var intv = setInterval(function(){
+									if(window.__remotePaneLoaded){
+										clearInterval(intv);
+										window.__remotePaneLoaded = null;
+										try{
+											var n1 = dojo.byId("n1");
+											var n2 = dojo.byId("n2");
+											var n3 = dojo.byId("n3");
+			
+											doh.assertTrue(domStyle.get(n1, "display") === "none", "No commented out inline styles");
+											doh.assertTrue(domStyle.get(n2, "display") === "none", "No commented out inline links");
+											doh.assertTrue(domStyle.get(n3, "display") === "none", "No commented out inline imports");
+											
+											//Test that entity characters in a src url for a script
+											//are properly converted to correct form
+											var node = document.getElementById("should_not_be_here");
+											doh.assertTrue(node == null);
+											deferred.callback(true);
+										}catch(e){
+											deferred.errback(new Error(e));
+										}
+									}
+								}, 500);
+							},
+							function(e){
+								deferred.errback(e);
+							}
+						);
+
 						return deferred;
 					}
-				},
+				},				
 				{
 					name: 'testEntityChars',
 					setUp: function() {
-						remoteScriptsSetter = new dojox.html._ContentSetter({
+						remoteScriptsSetter = new html._ContentSetter({
 							renderStyles: true, 
 							cleanContent: true,
 							executeScripts: true,
-							node: dojo.byId("node4")
+							node: dom.byId("node4")
 						});
-						previousContent = dojo.byId("node4").innerHTML;
+						previousContent = dom.byId("node4").innerHTML;
 					},
 					tearDown: function(){
-						dojo.byId("node4").innerHTML = previousContent;    
+						dom.byId("node4").innerHTML = previousContent;    
 					},
 					timeout: 10000,
 					runTest: function(t){
 						var deferred = new doh.Deferred(); 
-						var xhrDef = dojo.xhrGet({
+						var xhrDef = xhr.get({
 							url: "remote/commentedScript.html",
 							preventCache: true,
 							handleAs: "text"
 						});
-						xhrDef.addCallback(function(text){
-							remoteScriptsSetter.set(text);
-							var intv = setInterval(function(){
-								if(window.__remotePaneLoaded2){
-									clearInterval(intv);
-									window.__remotePaneLoaded2 = null;
-									try{
-										//Test that entity characters in a src url for a script 
-										//are properly converted to correct form
-										var node = document.getElementById("should_not_be_here2"); 
-										doh.assertTrue(node == null);
-										deferred.callback(true);
-									}catch(e){
-										deferred.errback(new Error(e));
+						xhrDef.then(
+							function(text){
+								remoteScriptsSetter.set(text);
+								var intv = setInterval(function(){
+									if(window.__remotePaneLoaded2){
+										clearInterval(intv);
+										window.__remotePaneLoaded2 = null;
+										try{
+											//Test that entity characters in a src url for a script
+											//are properly converted to correct form
+											var node = document.getElementById("should_not_be_here2");
+											doh.assertTrue(node == null);
+											deferred.callback(true);
+										}catch(e){
+											deferred.errback(new Error(e));
+										}
 									}
-								}
-							}, 500);
-						});
-						xhrDef.addErrback(function(e){
-							deferred.errback(e);
-						});
+								}, 500);
+							},
+							function(e){
+								deferred.errback(e);
+							}
+						);
 						return deferred;
 					}
 				}
-				
 			]);
 
 			doh.run();
@@ -1008,8 +1019,8 @@
 	</style>
 </head>
 <body class='tundra'>
-	<h1>dojox.layout.ContentPane</h1>
-	<h3>As dojox ContentPane is derived from dijit ContentPane, make sure that the dijit test passes before running this test</h3>
+	<h1>dojox/html</h1>
+	<h3>As dojox/html is derived from dojo/html, make sure that the dojo/html test passes before running this test</h3>
 	<h3 class='red'>Test relies on a php page as backend, so you need php installed on your server</h3>
 
 	<div class='box' id='node1'>
diff --git a/dojox/html/tests/test_style-html.html b/dojox/html/tests/test_style-html.html
index c305e8c..2a8f4b9 100644
--- a/dojox/html/tests/test_style-html.html
+++ b/dojox/html/tests/test_style-html.html
@@ -67,7 +67,7 @@
 			margin:auto;
 		}
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: false, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 	dojo.require("dojo.fx");
 	dojo.require("dojox.html.ext-dojo.style");
diff --git a/dojox/html/tests/test_themes.html b/dojox/html/tests/test_themes.html
index 4081a51..d208621 100644
--- a/dojox/html/tests/test_themes.html
+++ b/dojox/html/tests/test_themes.html
@@ -23,7 +23,7 @@ var djConfig = {
 };
 </script>
 
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, fontSizeWatch: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, fontSizeWatch: true"></script>
 
 <script type="text/javascript">
 
diff --git a/dojox/image.js b/dojox/image.js
index d1fe6d0..2b20d52 100644
--- a/dojox/image.js
+++ b/dojox/image.js
@@ -1,8 +1,10 @@
 define(["./image/_base"], function(image){
 	/*=====
-	dojox.image = {
-		// summary: Collection of image-related widgets and controls
-	};
-	=====*/
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/image modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
 	return image;
 });
\ No newline at end of file
diff --git a/dojox/image/Badge.js b/dojox/image/Badge.js
index 21c3b82..e91d805 100644
--- a/dojox/image/Badge.js
+++ b/dojox/image/Badge.js
@@ -1,18 +1,19 @@
-define(["dojo", "dijit", "dojox/main", "dijit/_Widget", "dijit/_TemplatedMixin", "dojo/fx/easing"], function(dojo, dijit, dojox){
+define(["dojo", "dijit", "dojox/main", "dijit/_Widget", "dijit/_TemplatedMixin", "dojo/fx/easing"],
+function(dojo, dijit, dojox, _Widget, _TemplatedMixin){
 
 	dojo.experimental("dojox.image.Badge");
 	dojo.getObject("image", true, dojox);
 	
-	dojo.declare("dojox.image.Badge", [dijit._Widget, dijit._TemplatedMixin], {
-		// summary: A simple grid of Images that loops through thumbnails
-		//
+	return dojo.declare("dojox.image.Badge", [_Widget, _TemplatedMixin], {
+		// summary:
+		//		A simple grid of Images that loops through thumbnails
 
 		baseClass: "dojoxBadge",
 
 		templateString:'<div class="dojoxBadge" dojoAttachPoint="containerNode"></div>',
 
 		// children: String
-		// 		A CSS3 Selector that determines the node to become a child
+		//		A CSS3 Selector that determines the node to become a child
 		children: "div.dojoxBadgeImage",
 
 		// rows: Integer
@@ -53,7 +54,8 @@ define(["dojo", "dijit", "dojox/main", "dijit/_Widget", "dijit/_TemplatedMixin",
 		},
 
 		_init: function(){
-			// summary: Setup and layout the images
+			// summary:
+			//		Setup and layout the images
 
 			var _row = 0,
 				_w = this.cellSize;
@@ -95,7 +97,8 @@ define(["dojo", "dijit", "dojox/main", "dijit/_Widget", "dijit/_TemplatedMixin",
 		},
 
 		_getCell: function(/* DomNode */ n){
-			// summary: Return information about the position for a given node
+			// summary:
+			//		Return information about the position for a given node
 			var _pos = this._nl.indexOf(n);
 			if(_pos >= 0){
 				var _col = _pos % this.cols;
@@ -107,12 +110,14 @@ define(["dojo", "dijit", "dojox/main", "dijit/_Widget", "dijit/_TemplatedMixin",
 		},
 
 		_getImage: function(){
-			// summary: Returns the next image in the list, or the first one if not available
+			// summary:
+			//		Returns the next image in the list, or the first one if not available
 			return "url('')";
 		},
 
 		_enbiggen: function(/* Event|DomNode */ e){
-			// summary: Show the passed node in the picker
+			// summary:
+			//		Show the passed node in the picker
 			var _pos = this._getCell(e.target || e);
 
 			if (_pos){
@@ -155,7 +160,8 @@ define(["dojo", "dijit", "dojox/main", "dijit/_Widget", "dijit/_TemplatedMixin",
 		},
 
 		_loadUnder: function(info, props){
-			// summary: figure out which three images are being covered, and
+			// summary:
+			//		figure out which three images are being covered, and
 			//		determine if they need loaded or not
 
 			var idx = info.io;
@@ -188,7 +194,8 @@ define(["dojo", "dijit", "dojox/main", "dijit/_Widget", "dijit/_TemplatedMixin",
 		},
 
 		_disenbiggen: function(info, props){
-			// summary: Hide the passed node (info.n), passing along properties
+			// summary:
+			//		Hide the passed node (info.n), passing along properties
 			//		received.
 
 			if(props.top >= 0){
@@ -209,7 +216,8 @@ define(["dojo", "dijit", "dojox/main", "dijit/_Widget", "dijit/_TemplatedMixin",
 		},
 
 		_cycle: function(info, props){
-			// summary: Select an un-viewed image from the list, and show it
+			// summary:
+			//		Select an un-viewed image from the list, and show it
 
 			var bc = this.baseClass;
 			dojo.removeClass(info.n, bc + "Top");
@@ -222,7 +230,5 @@ define(["dojo", "dijit", "dojox/main", "dijit/_Widget", "dijit/_TemplatedMixin",
 		}
 
 	});
-
-	return dojox.image.Badge;
-})
+});
 
diff --git a/dojox/image/FlickrBadge.js b/dojox/image/FlickrBadge.js
index 238d8bf..7302c62 100644
--- a/dojox/image/FlickrBadge.js
+++ b/dojox/image/FlickrBadge.js
@@ -5,28 +5,28 @@ define(["dojo", "dojox/main", "dojox/image/Badge", "dojox/data/FlickrRestStore"]
 		children: "a.flickrImage",
 
 		// userid: String
-		// 		If you know your Flickr userid, you can set it to prevent a call to fetch the id
+		//		If you know your Flickr userid, you can set it to prevent a call to fetch the id
 		userid: "",
 
 		// username: String
-		// 		Your Flickr username
+		//		Your Flickr username
 		username: "",
 
 		// setid: String
-		// 		The id of the set to display
+		//		The id of the set to display
 		setid: "",
 
 		// tags: String|Array
-		// 		A comma separated list of tags or an array of tags to grab from Flickr
+		//		A comma separated list of tags or an array of tags to grab from Flickr
 		tags: "",
 
 		// searchText: String
-		// 		Free text search.  Photos who's title, description, or tags contain the text will be displayed
+		//		Free text search.  Photos who's title, description, or tags contain the text will be displayed
 		searchText: "",
 
 		// target: String
-		// 		Where to display the pictures when clicked on.  Valid values are the same as the target attribute
-		// 		of the A tag.
+		//		Where to display the pictures when clicked on.  Valid values are the same as the target attribute
+		//		of the A tag.
 		target: "",
 
 		apikey: "8c6803164dbc395fb7131c9d54843627",
@@ -101,6 +101,5 @@ define(["dojo", "dojox/main", "dojox/image/Badge", "dojox/data/FlickrRestStore"]
 			}
 		}
 	});
-	
 });
 
diff --git a/dojox/image/Gallery.js b/dojox/image/Gallery.js
index 6e1ddf8..4bc3d25 100644
--- a/dojox/image/Gallery.js
+++ b/dojox/image/Gallery.js
@@ -117,10 +117,10 @@ dojo.declare("dojox.image.Gallery",
 		// summary:
 		//		Sets the data store and request objects to read data from.
 		// dataStore:
-		//		An implementation of the dojo.data.api.Read API. This accesses the image
+		//		An implementation of the dojo/data/api/Read API. This accesses the image
 		//		data.
 		// request:
-		//		An implementation of the dojo.data.api.Request API. This specifies the
+		//		An implementation of the dojo/data/api/Request API. This specifies the
 		//		query and paging information to be used by the data store
 		// paramNames:
 		//		An object defining the names of the item attributes to fetch from the
diff --git a/dojox/image/Lightbox.js b/dojox/image/Lightbox.js
index cd6028b..b8d682a 100644
--- a/dojox/image/Lightbox.js
+++ b/dojox/image/Lightbox.js
@@ -3,32 +3,29 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 	dojo.experimental("dojox.image.Lightbox");
 	dojo.getObject("image", true, dojox);
 
-	dojo.declare("dojox.image.Lightbox", dijit._Widget, {
+	var Lightbox = dojo.declare("dojox.image.Lightbox", dijit._Widget, {
 		// summary:
 		//		A dojo-based Lightbox implementation.
-		//
 		// description:
-		//	An Elegant, keyboard accessible, markup and store capable Lightbox widget to show images
-		//	in a modal dialog-esque format. Can show individual images as Modal dialog, or can group
-		//	images with multiple entry points, all using a single "master" Dialog for visualization
+		//		An Elegant, keyboard accessible, markup and store capable Lightbox widget to show images
+		//		in a modal dialog-esque format. Can show individual images as Modal dialog, or can group
+		//		images with multiple entry points, all using a single "master" Dialog for visualization
 		//
-		//	key controls:
-		//		ESC - close
-		//		Down Arrow / Rt Arrow / N - Next Image
-		//		Up Arrow / Lf Arrow / P - Previous Image
+		//		key controls:
 		//
+		//		- ESC - close
+		//		- Down Arrow / Rt Arrow / N - Next Image
+		//		- Up Arrow / Lf Arrow / P - Previous Image
 		// example:
 		// |	<a href="image1.jpg" dojoType="dojox.image.Lightbox">show lightbox</a>
-		//
 		// example:
 		// |	<a href="image2.jpg" dojoType="dojox.image.Lightbox" group="one">show group lightbox</a>
 		// |	<a href="image3.jpg" dojoType="dojox.image.Lightbox" group="one">show group lightbox</a>
-		//
 		// example:
 		// |	not implemented fully yet, though works with basic datastore access. need to manually call
 		// |	widget._attachedDialog.addImage(item,"fromStore") for each item in a store result set.
 		// |	<div dojoType="dojox.image.Lightbox" group="fromStore" store="storeName"></div>
-		//
+
 		// group: String
 		//		Grouping images in a page with similar tags will provide a 'slideshow' like grouping of images
 		group: "",
@@ -49,14 +46,14 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		// modal: Boolean
 		//		If true, this Dialog instance will be truly modal and prevent closing until
 		//		explicitly told to by calling hide() or clicking the (x) - Defaults to false
-		//		to preserve previous behaviors. (aka: enable click-to-click on the underlay)
+		//		to preserve previous behaviors. (aka: enable click-to-close on the underlay)
 		modal: false,
 
 		// _allowPassthru: Boolean
 		//		Privately set this to disable/enable natural link of anchor tags
 		_allowPassthru: false,
 
-		// _attachedDialg: dojox.image._LightboxDialog
+		// _attachedDialog: dojox.image._LightboxDialog
 		//		The pointer to the global lightbox dialog for this widget
 		_attachedDialog: null, // try to share a single underlay per page?
 
@@ -80,7 +77,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		_addSelf: function(){
-			// summary: Add this instance to the master LightBoxDialog
+			// summary:
+			//		Add this instance to the master LightBoxDialog
 			this._attachedDialog.addImage({
 				href: this.href,
 				title: this.title
@@ -88,30 +86,35 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		_handleClick: function(/* Event */e){
-			// summary: Handle the click on the link
+			// summary:
+			//		Handle the click on the link
 			if(!this._allowPassthru){ e.preventDefault(); }
 			else{ return; }
 			this.show();
 		},
 
 		show: function(){
-			// summary: Show the Lightbox with this instance as the starting point
+			// summary:
+			//		Show the Lightbox with this instance as the starting point
 			this._attachedDialog.show(this);
 		},
 
 		hide: function(){
-			// summary: Hide the Lightbox currently showing
+			// summary:
+			//		Hide the Lightbox currently showing
 			this._attachedDialog.hide();
 		},
 
 		// FIXME: switch to .attr, deprecate eventually.
 		disable: function(){
-			// summary: Disables event clobbering and dialog, and follows natural link
+			// summary:
+			//		Disables event clobbering and dialog, and follows natural link
 			this._allowPassthru = true;
 		},
 
 		enable: function(){
-			// summary: Enables the dialog (prevents default link)
+			// summary:
+			//		Enables the dialog (prevents default link)
 			this._allowPassthru = false;
 		},
 
@@ -127,14 +130,12 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 
 	});
 
-	dojo.declare("dojox.image.LightboxDialog",
+	Lightbox.LightboxDialog = dojo.declare("dojox.image.LightboxDialog",
 		dijit.Dialog, {
 		// summary:
 		//		The "dialog" shared	 between any Lightbox instances on the page, publically available
-		//		for programatic manipulation.
-		//
+		//		for programmatic manipulation.
 		// description:
-		//
 		//		A widget that intercepts anchor links (typically around images)
 		//		and displays a modal Dialog. this is the actual Dialog, which you can
 		//		create and populate manually, though should use simple Lightbox's
@@ -142,13 +143,12 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		//
 		//		There should only be one of these on a page, so all dojox.image.Lightbox's will us it
 		//		(the first instance of a Lightbox to be show()'n will create me If i do not exist)
-		//
-		//	example:
+		// example:
 		//	|	// show a single image from a url
 		//	|	var url = "http://dojotoolkit.org/logo.png";
 		//	|	var dialog = new dojox.image.LightboxDialog().startup();
 		//	|	dialog.show({ href: url, title:"My Remote Image"});
-		//
+
 		// title: String
 		//		The current title, read from object passed to show()
 		title: "",
@@ -178,8 +178,12 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		// modal: Boolean
 		//		If true, this Dialog instance will be truly modal and prevent closing until
 		//		explicitly told to by calling hide() or clicking the (x) - Defaults to false
-		//		to preserve previous behaviors. (aka: enable click-to-click on the underlay)
+		//		to preserve previous behaviors. (aka: enable click-to-close on the underlay)
 		modal: false,
+		
+		// imageClass: String
+		//		The classname to apply to the image node in the dialog (for extra styling)
+		imageClass: "dojoxLightboxImage",
 
 	/*=====
 		// _groups: Object
@@ -199,8 +203,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		startup: function(){
-			// summary: Add some extra event handlers, and startup our superclass.
-			//
+			// summary:
+			//		Add some extra event handlers, and startup our superclass.
 			// returns: dijit._Widget
 			//		Perhaps the only `dijit._Widget` that returns itself to allow
 			//		'chaining' or var referencing with .startup()
@@ -217,14 +221,13 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		show: function(/* Object */groupData){
-			// summary: Show the Master Dialog. Starts the chain of events to show
+			// summary:
+			//		Show the Master Dialog. Starts the chain of events to show
 			//		an image in the dialog, including showing the dialog if it is
 			//		not already visible
-			//
 			// groupData: Object
 			//		needs href and title attributes. the values for this image.
-			//
-			//
+
 			var _t = this; // size
 			this._lastGroup = groupData;
 
@@ -247,7 +250,9 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 				// ugly fix for IE being stupid. place the new image relative to the old
 				// image to allow for overriden templates to adjust the location of the
 				// titlebar. DOM will remain "unchanged" between views.
-				var tmpImg = dojo.create("img", null, _t.imgNode, "after");
+				var tmpImg = dojo.create("img", {
+					className: _t.imageClass
+				}, _t.imgNode, "after");
 				dojo.destroy(_t.imgNode);
 				_t.imgNode = tmpImg;
 				_t._makeAnims();
@@ -293,7 +298,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		_ready: function(src){
-			// summary: A function to trigger all 'real' showing of some src
+			// summary:
+			//		A function to trigger all 'real' showing of some src
 
 			var _t = this;
 
@@ -323,7 +329,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		_nextImage: function(){
-			// summary: Load next image in group
+			// summary:
+			//		Load next image in group
 			if(!this.inGroup){ return; }
 			if(this._index + 1 < this.inGroup.length){
 				this._index++;
@@ -334,7 +341,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		_prevImage: function(){
-			// summary: Load previous image in group
+			// summary:
+			//		Load previous image in group
 			if(this.inGroup){
 				if(this._index == 0){
 					this._index = this.inGroup.length - 1;
@@ -346,12 +354,14 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		_loadImage: function(){
-			// summary: Do the prep work before we can show another image
+			// summary:
+			//		Do the prep work before we can show another image
 			this._loadingAnim.play(1);
 		},
 
 		_prepNodes: function(){
-			// summary: A localized hook to accompany _loadImage
+			// summary:
+			//		A localized hook to accompany _loadImage
 			this._imageReady = false;
 			if(this.inGroup && this.inGroup[this._index]){
 				this.show({
@@ -373,7 +383,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		resizeTo: function(/* Object */size, forceTitle){
-			// summary: Resize our dialog container, and fire _showImage
+			// summary:
+			//		Resize our dialog container, and fire _showImage
 
 			var adjustSize = dojo.boxModel == "border-box" ?
 				dojo._getBorderExtents(this.domNode).w : 0,
@@ -403,7 +414,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		_scaleToFit: function(/* Object */size){
-			// summary: resize an image to fit within the bounds of the viewport
+			// summary:
+			//		resize an image to fit within the bounds of the viewport
 			// size: Object
 			//		The 'size' object passed around for this image
 
@@ -435,7 +447,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		_setImageSize: function(size){
-			// summary: Reset the image size to some actual size.
+			// summary:
+			//		Reset the image size to some actual size.
 			var s = this.imgNode;
 			s.height = size.h;
 			s.width = size.w;
@@ -445,7 +458,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		_size: function(){},
 
 		_position: function(/* Event */e){
-			// summary: we want to know the viewport size any time it changes
+			// summary:
+			//		we want to know the viewport size any time it changes
 			this._vp = dojo.window.getBox();
 			this.inherited(arguments);
 
@@ -465,12 +479,14 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		_showImage: function(){
-			// summary: Fade in the image, and fire showNav
+			// summary:
+			//		Fade in the image, and fire showNav
 			this._showImageAnim.play(1);
 		},
 
 		_showNav: function(){
-			// summary: Fade in the footer, and setup our connections.
+			// summary:
+			//		Fade in the footer, and setup our connections.
 			var titleSizeNow = dojo.marginBox(this.titleNode);
 			if(titleSizeNow.h > this._lastTitleSize.h){
 				this.resizeTo(this._wasStyled ? this._lastSize : this._currentSize, titleSizeNow);
@@ -480,7 +496,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		hide: function(){
-			// summary: Hide the Master Lightbox
+			// summary:
+			//		Hide the Master Lightbox
 			dojo.fadeOut({
 				node: this.titleNode,
 				duration: 200,
@@ -498,15 +515,16 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		addImage: function(child, group){
-			// summary: Add an image to this Master Lightbox
-			//
+			// summary:
+			//		Add an image to this Master Lightbox
 			// child: Object
 			//		The image information to add.
-			//		href: String - link to image (required)
-			//		title: String - title to display
 			//
+			//		- href: String - link to image (required)
+			//		- title: String - title to display
 			// group: String?
 			//		attach to group of similar tag or null for individual image instance
+
 			var g = group;
 			if(!child.href){ return; }
 			if(g){
@@ -518,7 +536,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		removeImage: function(/* Widget */child){
-			// summary: Remove an image instance from this LightboxDialog.
+			// summary:
+			//		Remove an image instance from this LightboxDialog.
 			// child: Object
 			//		A reference to the Lightbox child that was added (or an object literal)
 			//		only the .href member is compared for uniqueness. The object may contain
@@ -535,12 +554,14 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		removeGroup: function(group){
-			// summary: Remove all images in a passed group
+			// summary:
+			//		Remove all images in a passed group
 			if(this._groups[group]){ this._groups[group] = []; }
 		},
 
 		_handleKey: function(/* Event */e){
-			// summary: Handle keyboard navigation internally
+			// summary:
+			//		Handle keyboard navigation internally
 			if(!this.open){ return; }
 
 			var dk = dojo.keys;
@@ -565,7 +586,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		_makeAnims: function(){
-			// summary: make and cleanup animation and animation connections
+			// summary:
+			//		make and cleanup animation and animation connections
 
 			dojo.forEach(this._animConnects, dojo.disconnect);
 			this._animConnects = [];
@@ -583,7 +605,8 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 		},
 
 		onClick: function(groupData){
-			// summary: a stub function, called with the currently displayed image as the only argument
+			// summary:
+			//		a stub function, called with the currently displayed image as the only argument
 		},
 
 		_onImageClick: function(e){
@@ -597,9 +620,7 @@ define(["dojo", "dijit", "dojox", "dojo/text!./resources/Lightbox.html", "dijit/
 			}
 		}
 	});
-	
-
-	return dojox.image.Lightbox;
 
+	return Lightbox;
 });
 
diff --git a/dojox/image/LightboxNano.js b/dojox/image/LightboxNano.js
index e1e066e..060403a 100644
--- a/dojox/image/LightboxNano.js
+++ b/dojox/image/LightboxNano.js
@@ -3,7 +3,8 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 	var abs = "absolute",
 		vis = "visibility",
 		getViewport = function(){
-			//	summary: Returns the dimensions and scroll position of the viewable area of a browser window
+			// summary:
+			//		Returns the dimensions and scroll position of the viewable area of a browser window
 			var scrollRoot = (dojo.doc.compatMode == "BackCompat") ? dojo.body() : dojo.doc.documentElement,
 				scroll = dojo._docScroll();
 				return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y };
@@ -11,38 +12,36 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 	;
 
 	return dojo.declare("dojox.image.LightboxNano", null, {
-		//	summary:
+		// summary:
 		//		A simple "nano" version of the lightbox.
-		//
-		//	description:
+		// description:
 		//		Very lightweight lightbox which only displays a larger image.  There is
 		//		no support for a caption or description.  The lightbox can be closed by
 		//		clicking any where or pressing any key.  This widget is intended to be
-		//		used on <a> and <img> tags.  Upon creation, if the domNode is <img> tag,
-		//		then it is wrapped in an <a> tag, then a <div class="enlarge"> is placed
-		//		inside the <a> and can be styled to display an icon that the original
+		//		used on `<a>` and `<img>` tags.  Upon creation, if the domNode is `<img>` tag,
+		//		then it is wrapped in an `<a>` tag, then a `<div class="enlarge">` is placed
+		//		inside the `<a>` and can be styled to display an icon that the original
 		//		can be enlarged.
-		//
-		//	example:
+		// example:
 		//	|	<a dojoType="dojox.image.LightboxNano" href="/path/to/largeimage.jpg"><img src="/path/to/thumbnail.jpg"></a>
-		//
-		//	example:
+		// example:
 		//	|	<img dojoType="dojox.image.LightboxNano" src="/path/to/thumbnail.jpg" href="/path/to/largeimage.jpg">
 
-		//	href: string
+		// href: string
 		//		URL to the large image to show in the lightbox.
 		href: "",
 
-		//	duration: int
+		// duration: int
 		//		The delay in milliseconds of the LightboxNano open and close animation.
 		duration: 500,
 
-		//	preloadDelay: int
+		// preloadDelay: int
 		//		The delay in milliseconds after the LightboxNano is created before preloading the larger image.
 		preloadDelay: 5000,
 
 		constructor: function(/*Object?*/p, /*DomNode?*/n){
-			// summary: Initializes the DOM node and connect onload event
+			// summary:
+			//		Initializes the DOM node and connect onload event
 			var _this = this;
 
 			dojo.mixin(_this, p);
@@ -72,7 +71,8 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 		},
 
 		destroy: function(){
-			// summary: Destroys the LightboxNano and it's DOM node
+			// summary:
+			//		Destroys the LightboxNano and it's DOM node
 			var a = this._connects || [];
 			a.push(this._onClickEvt);
 			dojo.forEach(a, dojo.disconnect);
@@ -80,7 +80,8 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 		},
 
 		_createDiv: function(/*String*/cssClass, /*DomNode*/refNode, /*boolean*/display){
-			// summary: Creates a div for the enlarge icon and loading indicator layers
+			// summary:
+			//		Creates a div for the enlarge icon and loading indicator layers
 			return dojo.create("div", { // DomNode
 				"class": cssClass,
 				style: {
@@ -91,7 +92,8 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 		},
 
 		_load: function(/*Event*/e){
-			// summary: Creates the large image and begins to show it
+			// summary:
+			//		Creates the large image and begins to show it
 			var _this = this;
 
 			e && dojo.stopEvent(e);
@@ -137,7 +139,8 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 		},
 
 		_hideLoading: function(){
-			// summary: Hides the animated loading indicator
+			// summary:
+			//		Hides the animated loading indicator
 			if(this._loadingNode){
 				dojo.style(this._loadingNode, "display", "none");
 			}
@@ -145,7 +148,8 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 		},
 
 		_show: function(){
-			// summary: The image is now loaded, calculate size and display
+			// summary:
+			//		The image is now loaded, calculate size and display
 			var _this = this,
 				vp = getViewport(),
 				w = _this._img.width,
@@ -206,7 +210,8 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 		},
 
 		_sizeBg: function(){
-			// summary: Resize the background to fill the page
+			// summary:
+			//		Resize the background to fill the page
 			var dd = dojo.doc.documentElement;
 			dojo.style(this._bg, {
 				top: 0,
@@ -217,13 +222,15 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 		},
 
 		_key: function(/*Event*/e){
-			// summary: A key was pressed, so hide the lightbox
+			// summary:
+			//		A key was pressed, so hide the lightbox
 			dojo.stopEvent(e);
 			this._hide();
 		},
 
 		_coords: function(/*Object*/s, /*Object*/e){
-			// summary: Returns animation parameters with the start and end coords
+			// summary:
+			//		Returns animation parameters with the start and end coords
 			return { // Object
 				left:	{ start: s.x, end: e.x },
 				top:	{ start: s.y, end: e.y },
@@ -233,7 +240,8 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 		},
 
 		_hide: function(){
-			// summary: Closes the lightbox
+			// summary:
+			//		Closes the lightbox
 			var _this = this;
 			dojo.forEach(_this._connects, dojo.disconnect);
 			_this._connects = [];
@@ -244,7 +252,8 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 		},
 
 		_reset: function(){
-			// summary: Destroys the lightbox
+			// summary:
+			//		Destroys the lightbox
 			dojo.style(this._node, vis, "visible");
 			dojo.destroy(this._img);
 			dojo.destroy(this._bg);
@@ -253,7 +262,8 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 		},
 
 		_anim: function(/*DomNode*/node, /*Object*/args, /*Function*/onEnd){
-			// summary: Creates the lightbox open/close and background fadein/out animations
+			// summary:
+			//		Creates the lightbox open/close and background fadein/out animations
 			return dojo.animateProperty({ // dojo.Animation
 				node: node,
 				duration: this.duration,
@@ -265,16 +275,15 @@ define(["dojo", "dojo/fx"], function(dojo, fx) {
 		show: function(/*Object?*/args){
 			// summary:
 			//		Shows this LightboxNano programatically. Allows passing a new href and
-			//		a programatic origin.
-			//
+			//		a programmatic origin.
 			// args: Object?
 			//		An object with optional members of `href` and `origin`.
 			//		`origin` can be be a String|Id of a DomNode to use when
-			//		animating the openeing of the image (the 'box' effect starts
+			//		animating the opening of the image (the 'box' effect starts
 			//		from this origin point. eg: { origin: e.target })
 			//		If there's no origin, it will use the center of the viewport.
 			//		The `href` member is a string URL for the image to be
-			//		displayed. Omiting either of these members will revert to
+			//		displayed. Omitting either of these members will revert to
 			//		the default href (which could be absent in some cases) and
 			//		the original srcNodeRef for the widget.
 			args = args || {};
diff --git a/dojox/image/Magnifier.js b/dojox/image/Magnifier.js
index ddccafb..6cba3e6 100644
--- a/dojox/image/Magnifier.js
+++ b/dojox/image/Magnifier.js
@@ -6,7 +6,7 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/window", "dojox/
 		//
 		// description:
 		//		An unobtrusive way to add an unstyled overlay
-		// 		above the srcNode image element. The overlay/glass is a
+		//		above the srcNode image element. The overlay/glass is a
 		//		scaled version of the src image (so larger images sized down
 		//		are clearer).
 		//
@@ -14,7 +14,8 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/window", "dojox/
 		//		being sure to create an img node on that surface.
 
 		_createGlass: function(){
-			// summary: create the glassNode, and an img on a dojox.gfx surface
+			// summary:
+			//		create the glassNode, and an img on a dojox.gfx surface
 
 			// images are hard to make into workable templates, so just add outer overlay
 			// and skip using dijit._Templated
@@ -38,7 +39,8 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/window", "dojox/
 		},
 
 		_placeGlass: function(e){
-			// summary: position the overlay centered under the cursor
+			// summary:
+			//		position the overlay centered under the cursor
 			var x = e.pageX - 2,
 				y = e.pageY - 2,
 				xMax = this.offset.x + this.offset.w + 2,
@@ -55,7 +57,8 @@ define(["dojo/_base/declare", "dojo/dom-construct", "dojo/_base/window", "dojox/
 		},
 
 		_setImage: function(e){
-			// summary: set the image's offset in the clipping window relative to the mouse position
+			// summary:
+			//		set the image's offset in the clipping window relative to the mouse position
 
 			var xOff = (e.pageX - this.offset.x) / this.offset.w,
 				yOff = (e.pageY - this.offset.y) / this.offset.h,
diff --git a/dojox/image/MagnifierLite.js b/dojox/image/MagnifierLite.js
index a9fe316..8dfe08f 100644
--- a/dojox/image/MagnifierLite.js
+++ b/dojox/image/MagnifierLite.js
@@ -3,23 +3,24 @@ define(["dojo/_base/kernel", "dojo/_base/declare", "dijit/_Widget", "dojo/dom-co
 	kernel.experimental("dojox.image.MagnifierLite");
 	
 	return declare("dojox.image.MagnifierLite", _Widget, {
-		// summary:	Adds magnification on a portion of an image element
-		//
-		// description: An unobtrusive way to add an unstyled overlay
-		// 		above the srcNode image element. The overlay/glass is a
+		// summary:
+		//		Adds magnification on a portion of an image element
+		// description:
+		//		An unobtrusive way to add an unstyled overlay
+		//		above the srcNode image element. The overlay/glass is a
 		//		scaled version of the src image (so larger images sized down
 		//		are clearer).
 		//
 		//		The logic behind requiring the src image to be large is
 		//		"it's going to be downloaded, anyway" so this method avoids
 		//		having to make thumbnails and 2 http requests among other things.
-		//
+
 		// glassSize: Int
-		// 		the width and height of the bounding box
+		//		the width and height of the bounding box
 		glassSize: 125,
 
 		// scale: Decimal
-		// 		the multiplier of the Mangification.
+		//		the multiplier of the Mangification.
 		scale: 6,
 
 		postCreate: function(){
@@ -40,7 +41,8 @@ define(["dojo/_base/kernel", "dojo/_base/declare", "dijit/_Widget", "dojo/dom-co
 		},
 
 		_createGlass: function(){
-			// summary: make img and glassNode elements as children of the body
+			// summary:
+			//		make img and glassNode elements as children of the body
 
 			var node = this.glassNode = construct.create('div', {
 				style: {
@@ -63,7 +65,8 @@ define(["dojo/_base/kernel", "dojo/_base/declare", "dijit/_Widget", "dojo/dom-co
 		},
 
 		_adjustScale: function(){
-			// summary: update the calculations should this.scale change
+			// summary:
+			//		update the calculations should this.scale change
 
 			this.offset = geometry.position(this.domNode, true);
 			console.dir(this.offset);
@@ -75,7 +78,8 @@ define(["dojo/_base/kernel", "dojo/_base/declare", "dijit/_Widget", "dojo/dom-co
 		},
 
 		_showGlass: function(e){
-			// summary: show the overlay
+			// summary:
+			//		show the overlay
 			this._placeGlass(e);
 			style.set(this.glassNode, {
 				visibility: "visible",
@@ -84,7 +88,8 @@ define(["dojo/_base/kernel", "dojo/_base/declare", "dijit/_Widget", "dojo/dom-co
 		},
 
 		_hideGlass: function(e){
-			// summary: hide the overlay
+			// summary:
+			//		hide the overlay
 			style.set(this.glassNode, {
 				visibility: "hidden",
 				display:"none"
@@ -92,7 +97,8 @@ define(["dojo/_base/kernel", "dojo/_base/declare", "dijit/_Widget", "dojo/dom-co
 		},
 
 		_placeGlass: function(e){
-			// summary: position the overlay centered under the cursor
+			// summary:
+			//		position the overlay centered under the cursor
 
 			this._setImage(e);
 			var sub = Math.floor(this.glassSize / 2);
@@ -103,7 +109,8 @@ define(["dojo/_base/kernel", "dojo/_base/declare", "dijit/_Widget", "dojo/dom-co
 		},
 
 		_setImage: function(e){
-			// summary: set the image's offset in the clipping window relative to the mouse position
+			// summary:
+			//		set the image's offset in the clipping window relative to the mouse position
 
 			var xOff = (e.pageX - this.offset.x) / this.offset.w,
 				yOff = (e.pageY - this.offset.y) / this.offset.h,
diff --git a/dojox/image/SlideShow.js b/dojox/image/SlideShow.js
index 838ce38..3346060 100644
--- a/dojox/image/SlideShow.js
+++ b/dojox/image/SlideShow.js
@@ -52,7 +52,7 @@ dojo.declare("dojox.image.SlideShow",
 	hasNav: true,
 
 	// images: Array
-	// Contains the DOM nodes that individual images are stored in when loaded or loading.
+	//	Contains the DOM nodes that individual images are stored in when loaded or loading.
 	images: [],
 	
 	// pageSize: Number
@@ -69,11 +69,11 @@ dojo.declare("dojox.image.SlideShow",
 	autoStart: false,
 	
 	// fixedHeight: Boolean
-	// If true, the widget does not resize itself to fix the displayed image.
+	//	If true, the widget does not resize itself to fix the displayed image.
 	fixedHeight: false,
 
 	// imageStore: Object
-	//	Implementation of the dojo.data.api.Read API, which provides data on the images
+	//	Implementation of the dojo/data/api/Read API, which provides data on the images
 	//	to be displayed.
 	imageStore: null,
 		
@@ -93,7 +93,7 @@ dojo.declare("dojox.image.SlideShow",
 	titleAttr: "title",
 
 	// slideshowInterval: Number
-	// Time, in seconds, between image transitions during a slideshow.
+	//	Time, in seconds, between image transitions during a slideshow.
 	slideshowInterval: 3,
 	
 	templateString: dojo.cache("dojox.image", "resources/SlideShow.html"),
@@ -107,12 +107,13 @@ dojo.declare("dojox.image.SlideShow",
 	_tmpImage: null,
 	
 	// _request: Object
-	//	Implementation of the dojo.data.api.Request API, which defines the query
+	//	Implementation of the dojo/data/api/Request API, which defines the query
 	//	parameters for accessing the store.
 	_request: null,
 
 	postCreate: function(){
-		// summary: Initilizes the widget, sets up listeners and shows the first image
+		// summary:
+		//		Initializes the widget, sets up listeners and shows the first image
 		this.inherited(arguments);
 		var img = document.createElement("img");
 
@@ -149,10 +150,10 @@ dojo.declare("dojox.image.SlideShow",
 		// summary:
 		//		Sets the data store and request objects to read data from.
 		// dataStore:
-		//		An implementation of the dojo.data.api.Read API. This accesses the image
+		//		An implementation of the dojo/data/api/Read API. This accesses the image
 		//		data.
 		// request:
-		//		An implementation of the dojo.data.api.Request API. This specifies the
+		//		An implementation of the dojo/data/api/Request API. This specifies the
 		//		query and paging information to be used by the data store
 		// paramNames:
 		//		An object defining the names of the item attributes to fetch from the
@@ -658,7 +659,7 @@ dojo.declare("dojox.image.SlideShow",
 	_overElement: function(/*DomNode*/element, /*Event*/e){
 		// summary:
 		//		Returns whether the mouse is over the passed element.
-		//		Element must be display:block (ie, not a <span>)
+		//		Element must be display:block (ie, not a `<span>`)
 		
 		//When the page is unloading, if this method runs it will throw an
 		//exception.
diff --git a/dojox/image/ThumbnailPicker.js b/dojox/image/ThumbnailPicker.js
index fad42fc..68cfa9f 100644
--- a/dojox/image/ThumbnailPicker.js
+++ b/dojox/image/ThumbnailPicker.js
@@ -19,104 +19,110 @@ dojo.require("dijit._Templated");
 dojo.declare("dojox.image.ThumbnailPicker",
 	[dijit._Widget, dijit._Templated],
 	{
-	// summary: A scrolling Thumbnail Picker widget
-	//
+	// summary:
+	//		A scrolling Thumbnail Picker widget
+
 	// imageStore: Object
-	// A data store that implements the dojo.data Read API.
+	//		A data store that implements the dojo.data Read API.
 	imageStore: null,
 
 	// request: Object
-	// A dojo.data Read API Request object.
+	//		A dojo.data Read API Request object.
 	request: null,
 
 	// size: Number
-	// Width or height in pixels, depending if horizontal or vertical.
+	//		Width or height in pixels, depending if horizontal or vertical.
 	size: 500, 
 
 	// thumbHeight: Number
-	// Default height of a thumbnail image
+	//		Default height of a thumbnail image
 	thumbHeight: 75, 
 
 	// thumbWidth: Number
-	// Default width of an image
+	//		Default width of an image
 	thumbWidth: 100, 
 
 	// useLoadNotifier: Boolean
-	// Setting useLoadNotifier to true makes a colored DIV appear under each
-	// thumbnail image, which is used to display the loading status of each
-	// image in the data store.
+	//		Setting useLoadNotifier to true makes a colored DIV appear under each
+	//		thumbnail image, which is used to display the loading status of each
+	//		image in the data store.
 	useLoadNotifier: false,
 
 	// useHyperlink: boolean
-	// Setting useHyperlink to true causes a click on a thumbnail to open a link.
+	//		Setting useHyperlink to true causes a click on a thumbnail to open a link.
 	useHyperlink: false,
 
 	// hyperlinkTarget: String
-	// If hyperlinkTarget is set to "new", clicking on a thumb will open a new window
-	// If it is set to anything else, clicking a thumbnail will open the url in the
-	// current window.
+	//		If hyperlinkTarget is set to "new", clicking on a thumb will open a new window
+	//		If it is set to anything else, clicking a thumbnail will open the url in the
+	//		current window.
 	hyperlinkTarget: "new",
 
 	// isClickable: Boolean
-	// When set to true, the cursor over a thumbnail changes.
+	//		When set to true, the cursor over a thumbnail changes.
 	isClickable: true,
 
 	// isScrollable: Boolean
-	// When true, uses smoothScroll to move between pages
+	//		When true, uses smoothScroll to move between pages
 	isScrollable: true,
 
 	// isHorizontal: Boolean
-	// If true, the thumbnails are displayed horizontally. Otherwise they are displayed
-	// vertically
+	//		If true, the thumbnails are displayed horizontally. Otherwise they are displayed
+	//		vertically
 	isHorizontal: true,
 
-	//autoLoad: Boolean
+	// autoLoad: Boolean
 	autoLoad: true,
 
 	// linkAttr: String
-	// The attribute name for accessing the url from the data store
+	//		The attribute name for accessing the url from the data store
 	linkAttr: "link",
 	
 	// imageThumbAttr: String
-	// The attribute name for accessing the thumbnail image url from the data store
+	//		The attribute name for accessing the thumbnail image url from the data store
 	imageThumbAttr: "imageUrlThumb",
 	
 	// imageLargeAttr: String
-	// The attribute name for accessing the large image url from the data store
+	//		The attribute name for accessing the large image url from the data store
 	imageLargeAttr: "imageUrl",
 	
 	// pageSize: Number
-	//	The number of images to request each time.
+	//		The number of images to request each time.
 	pageSize: 20,
 	
 	// titleAttr: String
-	// The attribute name for accessing the title from the data store
+	//		The attribute name for accessing the title from the data store
 	titleAttr: "title",
 	
 	templateString: dojo.cache("dojox.image", "resources/ThumbnailPicker.html"),
 	
 	// thumbs: Array
-	// Stores the image nodes for the thumbnails.
+	//		Stores the image nodes for the thumbnails.
 	_thumbs: [],
 	
 	// _thumbIndex: Number
-	// The index of the first thumbnail shown
+	//		The index of the first thumbnail shown
 	_thumbIndex: 0,
 	
 	// _maxPhotos: Number
-	// The total number of photos in the image store
+	//		The total number of photos in the image store
 	_maxPhotos: 0,
 	
 	// _loadedImages: Object
-	// Stores the indices of images that have been marked as loaded using the
-	// markImageLoaded function.
+	//		Stores the indices of images that have been marked as loaded using the
+	//		markImageLoaded function.
 	_loadedImages: {},
 
+	baseClass: "ThumbnailPicker",
+
+	cellClass: "Thumbnail",
+
 	postCreate: function(){
 		// summary:
 		//		Initializes styles and listeners
-		this.widgetid = this.id;
+
 		this.inherited(arguments);
+		
 		this.pageSize = Number(this.pageSize);
 
 		this._scrollerSize = this.size - (51 * 2);
@@ -151,14 +157,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 			dojo.addClass(this.thumbsNode, "thumbClickable");
 		}
 		this._totalSize = 0;
-		this.init();
-	},
 
-	init: function(){
-		// summary:
-		//		Creates DOM nodes for thumbnail images and initializes their listeners
-		if(this.isInitialized) {return false;}
-	
 		var classExt = this.isHorizontal ? "Horiz" : "Vert";
 	
 		// FIXME: can we setup a listener around the whole element and determine based on e.target?
@@ -166,26 +165,37 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		dojo.addClass(this.navNext, "next" + classExt);
 		dojo.addClass(this.thumbsNode, "thumb"+classExt);
 		dojo.addClass(this.outerNode, "thumb"+classExt);
-	
+
 		dojo.attr(this.navNextImg, "src", this._blankGif);
 		dojo.attr(this.navPrevImg, "src", this._blankGif);
-		
+
 		this.connect(this.navPrev, "onclick", "_prev");
 		this.connect(this.navNext, "onclick", "_next");
-		this.isInitialized = true;
-		
+
 		if(this.isHorizontal){
-			this._offsetAttr = "offsetLeft";
 			this._sizeAttr = "offsetWidth";
 			this._scrollAttr = "scrollLeft";
 		}else{
-			this._offsetAttr = "offsetTop";
 			this._sizeAttr = "offsetHeight";
 			this._scrollAttr = "scrollTop";
 		}
 	
 		this._updateNavControls();
-		if(this.imageStore && this.request){this._loadNextPage();}
+		
+		this.init();
+	},
+	
+	init: function(){
+		// summary
+		//		Loads first image
+		if(this.isInitialized){
+			return false;
+		}
+		this.isInitialized = true;
+
+		if(this.imageStore && this.request){
+			this._loadNextPage();
+		}
 		return true;
 	},
 
@@ -194,7 +204,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		//		Returns the name of the dojo topic that can be
 		//		subscribed to in order to receive notifications on
 		//		which thumbnail was selected.
-		return (this.widgetId || this.id) + "/select"; // String
+		return this.id + "/select"; // String
 	},
 
 	getShowTopicName: function(){
@@ -202,17 +212,17 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		//		Returns the name of the dojo topic that can be
 		//		subscribed to in order to receive notifications on
 		//		which thumbnail is now visible
-		return (this.widgetId || this.id) + "/show"; // String
+		return this.id + "/show"; // String
 	},
 
 	setDataStore: function(dataStore, request, /*optional*/paramNames){
 		// summary:
 		//		Sets the data store and request objects to read data from.
 		// dataStore:
-		//		An implementation of the dojo.data.api.Read API. This accesses the image
+		//		An implementation of the dojo/data/api/Read API. This accesses the image
 		//		data.
 		// request:
-		//		An implementation of the dojo.data.api.Request API. This specifies the
+		//		An implementation of the dojo/data/api/Request API. This specifies the
 		//		query and paging information to be used by the data store
 		// paramNames:
 		//		An object defining the names of the item attributes to fetch from the
@@ -408,7 +418,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		//		If 'useLoadNotifier' is set to true, then a visual cue is
 		//		given to state whether the image is loaded or not.	Calling this function
 		//		marks an image as loaded.
-		var thumbNotifier = dojo.byId("loadingDiv_"+this.widgetid+"_"+index);
+		var thumbNotifier = dojo.byId("loadingDiv_"+this.id+"_"+index);
 		if(thumbNotifier){this._setThumbClass(thumbNotifier, "thumbLoaded");}
 		this._loadedImages[index] = true;
 	},
@@ -481,7 +491,6 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		
 		//Execute the request for data.
 		this.imageStore.fetch(this.request);
-	
 	},
 
 	_loadImage: function(data, index, callback){
@@ -492,8 +501,10 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		var url = store.getValue(data,this.imageThumbAttr);
 		
 		var imgContainer = dojo.create("div", {
-			id: "img_" + this.widgetid + "_" + index
+			id: "img_" + this.id + "_" + index,
+			"class": this.cellClass
 		});
+		
 		var img = dojo.create("img", {}, imgContainer);
 		img._index = index;
 		img._data = data;
@@ -502,7 +513,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		var loadingDiv;
 		if(this.useLoadNotifier){
 			loadingDiv = dojo.create("div", {
-				id: "loadingDiv_" + this.widgetid+"_" + index
+				id: "loadingDiv_" + this.id+"_" + index
 			}, imgContainer);
 	
 			//If this widget was previously told that the main image for this
@@ -552,6 +563,9 @@ dojo.declare("dojox.image.ThumbnailPicker",
 				title: this.imageStore.getValue(data,this.titleAttr),
 				link: this.imageStore.getValue(data,this.linkAttr)
 			}]);
+			//
+			dojo.query("." + this.cellClass, this.thumbsNode).removeClass(this.cellClass + "Selected");
+			dojo.addClass(evt.target.parentNode, this.cellClass + "Selected");
 			return false;
 		});
 		dojo.addClass(img, "imageGalleryThumb");
@@ -566,7 +580,6 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		// summary:
 		//		Updates the navigation controls to hide/show them when at
 		//		the first or last images.
-		var cells = [];
 		var change = function(node, add){
 			var fn = add ? "addClass" : "removeClass";
 			dojo[fn](node,"enabled");
@@ -577,7 +590,6 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		var size = this.isHorizontal ? "offsetWidth" : "offsetHeight";
 		change(this.navPrev, (this.thumbScroller[pos] > 0));
 		
-		var last = this._thumbs[this._thumbs.length - 1];
 		var addClass = (this.thumbScroller[pos] + this._scrollerSize < this.thumbsNode[size]);
 		change(this.navNext, addClass);
 	}
diff --git a/dojox/image/_base.js b/dojox/image/_base.js
index 8c1c0c7..97b3379 100644
--- a/dojox/image/_base.js
+++ b/dojox/image/_base.js
@@ -5,21 +5,18 @@ define(["dojo", "dojox"], function(dojo, dojox){
 	
 	var cacheNode;
 	dojox.image.preload = function(/* Array */urls){
-		// summary: Preload a list of images in the dom.
-		//
+		// summary:
+		//		Preload a list of images in the dom.
 		// urls: Array
 		//		The list of urls to load. Can be any valid .src attribute.
-		//
-		//	example:
-		//	Load two images into cache:
+		// example:
+		//		Load two images into cache:
 		//	|	dojox.image.preload(["foo.png", "bar.gif"]);
-		//
-		//	example:
-		//	Using djConfig:
+		// example:
+		//		Using djConfig:
 		//	|	var djConfig = {
 		//	|		preloadImages:["bar.png", "baz.png", "http://example.com/icon.gif"]
 		//	|	};
-		//
 		// returns: Array
 		//		An Array of DomNodes that have been cached.
 		
@@ -52,8 +49,8 @@ define(["dojo", "dojox"], function(dojo, dojox){
 	}
 		
 //	dojo.declare("dojox.image.Image", dijit._Widget, {
-//		// summary: an Image widget
-//		//
+//		// summary:
+//		//		an Image widget
 //		// example:
 //		//	| new dojox.Image({ src:"foo.png", id:"bar" });
 //
@@ -62,17 +59,20 @@ define(["dojo", "dojox"], function(dojo, dojox){
 //		title: "",
 //
 //		onLoad: function(e){
-//			// summary: Stub fired when this image is really ready.
+//			// summary:
+//			//		Stub fired when this image is really ready.
 //		},
 //
 //		_onLoad: function(e){
-//			// summary: private function to normalize `onLoad` for this
-//			//	instance.
+//			// summary:
+//			//		private function to normalize `onLoad` for this
+//			//		instance.
 //			this.onLoad(e);
 //		},
 //
 //		_setSrcAttr: function(newSrc){
-//			// summary: Function so widget.attr('src', someUrl) works
+//			// summary:
+//			//		Function so widget.attr('src', someUrl) works
 //
 //			var ts = this.domNode, os = td.src;
 //			if(os !== newSrc){
@@ -83,10 +83,10 @@ define(["dojo", "dojox"], function(dojo, dojox){
 //		/* Sugar Functions: */
 //
 //		crossFade: function(newSrc){
-//			// summary: Set this Image to a new src with crossfading
-//			//
+//			// summary:
+//			//		Set this Image to a new src with crossfading
 //			// example:
-//			//	dijit.byId("bar").crossFade("/images/newImage.png");
+//			// |	dijit.byId("bar").crossFade("/images/newImage.png");
 //			//
 //
 //			d.fadeOut({
diff --git a/dojox/image/resources/Lightbox.html b/dojox/image/resources/Lightbox.html
index aca14ee..7aca817 100644
--- a/dojox/image/resources/Lightbox.html
+++ b/dojox/image/resources/Lightbox.html
@@ -1,7 +1,7 @@
 <div class="dojoxLightbox" dojoAttachPoint="containerNode">
 	<div style="position:relative">
 		<div dojoAttachPoint="imageContainer" class="dojoxLightboxContainer" dojoAttachEvent="onclick: _onImageClick">
-			<img dojoAttachPoint="imgNode" src="${imgUrl}" class="dojoxLightboxImage" alt="${title}">
+			<img dojoAttachPoint="imgNode" src="${imgUrl}" class="${imageClass}" alt="${title}">
 			<div class="dojoxLightboxFooter" dojoAttachPoint="titleNode">
 				<div class="dijitInline LightboxClose" dojoAttachPoint="closeButtonNode"></div>
 				<div class="dijitInline LightboxNext" dojoAttachPoint="nextButtonNode"></div>	
diff --git a/dojox/image/resources/ThumbnailPicker.css b/dojox/image/resources/ThumbnailPicker.css
index 54ace0b..452170c 100644
--- a/dojox/image/resources/ThumbnailPicker.css
+++ b/dojox/image/resources/ThumbnailPicker.css
@@ -63,6 +63,7 @@
 }
 
 .thumbWrapper img {
+    border: solid 2px transparent;
 	height: 75px;
 	max-width: 100px;
 	width: expression(this.width > 100 ? 100: true);/*IE Hack*/
@@ -127,3 +128,10 @@
 	padding-bottom: 2px;
 }
 
+/**
+ *  CssState
+ */
+.Thumbnail:hover img,
+.ThumbnailSelected img {    
+    border-color: #F4D061;
+}
diff --git a/dojox/image/tests/test_Badge.html b/dojox/image/tests/test_Badge.html
index 3c4f4ef..6ccd23f 100644
--- a/dojox/image/tests/test_Badge.html
+++ b/dojox/image/tests/test_Badge.html
@@ -35,7 +35,7 @@
 	</style>
 	
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad:true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -219,7 +219,7 @@
 
 		<!--h3>From dojox.data.FlickrStore:</h3>
 
-		<div dojoType="dojox.data.FlickrStore" jsId="flickrStore" label="title"></div>
+		<div dojoType="dojox.data.FlickrStore" data-dojo-id="flickrStore" label="title"></div>
 		<div id="fromStore" dojoType="dojox.image.Lightbox" store="flickrStore" group="flickrStore"></div>
 
 		<input id="flickrButton" type="button" onclick="dijit.byId('fromStore').show()" value="show flickr lightbox" disabled="disabled" -->
diff --git a/dojox/image/tests/test_FlickrBadge.html b/dojox/image/tests/test_FlickrBadge.html
index 4de7f36..9399105 100644
--- a/dojox/image/tests/test_FlickrBadge.html
+++ b/dojox/image/tests/test_FlickrBadge.html
@@ -34,7 +34,7 @@
 	</style>
 	
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/image/tests/test_Gallery.html b/dojox/image/tests/test_Gallery.html
index 5a6aeb5..0273b79 100644
--- a/dojox/image/tests/test_Gallery.html
+++ b/dojox/image/tests/test_Gallery.html
@@ -13,7 +13,7 @@
 	</style>
 	
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig=" parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config=" parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -61,7 +61,7 @@
 
 	<h2>From ItemFileReadStore:</h2>
 	
-	<div jsId="imageItemStore" dojoType="dojo.data.ItemFileReadStore" url="images.json"></div>
+	<div data-dojo-id="imageItemStore" dojoType="dojo.data.ItemFileReadStore" url="images.json"></div>
 	<div id="gallery2" dojoType="dojox.image.Gallery"></div>
 
 </body>
diff --git a/dojox/image/tests/test_Gallery_GoogleData.html b/dojox/image/tests/test_Gallery_GoogleData.html
index 1ec2c99..2e64388 100644
--- a/dojox/image/tests/test_Gallery_GoogleData.html
+++ b/dojox/image/tests/test_Gallery_GoogleData.html
@@ -13,7 +13,7 @@
 	</style>
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/image/tests/test_Gallery_in_TabContainer.html b/dojox/image/tests/test_Gallery_in_TabContainer.html
index dc4ac52..8835904 100644
--- a/dojox/image/tests/test_Gallery_in_TabContainer.html
+++ b/dojox/image/tests/test_Gallery_in_TabContainer.html
@@ -13,7 +13,7 @@
 	</style>
 	
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -38,10 +38,10 @@
 <body class="tundra">
 	<h1 class="testTitle">dojox.image.Gallery in a TabContainer</h1>
 	
-	<div dojoType="dojox.data.FlickrRestStore" jsId="flickrStore"></div>
+	<div dojoType="dojox.data.FlickrRestStore" data-dojo-id="flickrStore"></div>
 
 	<div dojoType="dijit.layout.TabContainer" style="width:800px;height:1000px;">
-		<script type="dojo/connect" event="startup">
+		<script type="dojo/connect" data-dojo-event="startup">
 			// When the TabContainer has finished constructing, set the data store on each Gallery
 			dojo.forEach(["gallery1", "gallery2", "gallery3"], function(galleryId){
 				var req = {
diff --git a/dojox/image/tests/test_Lightbox.html b/dojox/image/tests/test_Lightbox.html
index a40d755..6522cf3 100644
--- a/dojox/image/tests/test_Lightbox.html
+++ b/dojox/image/tests/test_Lightbox.html
@@ -21,7 +21,7 @@
 	</style>
 	
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -222,12 +222,12 @@
 
 		<h3>From dojox.data.FlickrStore:</h3>
 
-		<div dojoType="dojox.data.FlickrStore" jsId="flickrStore" label="title"></div>
+		<div dojoType="dojox.data.FlickrStore" data-dojo-id="flickrStore" label="title"></div>
 		<div id="fromStore" dojoType="dojox.image.LightboxDialog" store="flickrStore" group="flickrStore"></div>
 
 		<button dojoType="dijit.form.Button" id="flickrButton" disabled="disabled">
 			Show Flickr lightbox
-			<script type="dojo/connect" event="onClick">
+			<script type="dojo/connect" data-dojo-event="onClick">
 				dijit.byId('fromStore').show({ group:"flickrStore" });
 			</script>
 		</button>
diff --git a/dojox/image/tests/test_LightboxNano.html b/dojox/image/tests/test_LightboxNano.html
index c08dd35..11f97e5 100644
--- a/dojox/image/tests/test_LightboxNano.html
+++ b/dojox/image/tests/test_LightboxNano.html
@@ -29,7 +29,7 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug:true, parseOnLoad:true"></script>
+		data-dojo-config="isDebug:true, parseOnLoad:true"></script>
 
 	<script type="text/javascript">
 	dojo.require("dojo.parser");
@@ -93,7 +93,7 @@
 
 	<h2>Declarative example on a <a> tag.</h2>
 
-	<p><a class="pic2" jsId="lightboxNano2" dojoType="dojox.image.LightboxNano" href="images/chris2_lg.jpg"><img src="images/chris2_sm.jpg"></a>
+	<p><a class="pic2" data-dojo-id="lightboxNano2" dojoType="dojox.image.LightboxNano" href="images/chris2_lg.jpg"><img src="images/chris2_sm.jpg"></a>
 	Nullam velit justo, aliquam sit amet, euismod sit amet, fermentum nec, pede. Proin sit amet
 	turpis tincidunt turpis posuere posuere. Donec ante. Donec ipsum. Morbi non lectus. Nullam rhoncus,
 	est in facilisis tincidunt, elit tortor aliquet velit, ut posuere nulla ipsum at tellus. Quisque
diff --git a/dojox/image/tests/test_Magnifier.html b/dojox/image/tests/test_Magnifier.html
index 1eb33a0..b791d41 100644
--- a/dojox/image/tests/test_Magnifier.html
+++ b/dojox/image/tests/test_Magnifier.html
@@ -13,7 +13,7 @@
 		#testImage { border:2px solid #000; }
 		
     </style>
-    <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="async: true, isDebug: true, parseOnLoad:true"></script>
+    <script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true, parseOnLoad:true"></script>
     <script type="text/javascript">
         require(["dojox/image/Magnifier", "dijit/form/Button", "dojo/parser"]);
 	</script>
@@ -54,7 +54,7 @@
 		
 		<button dojoType="dijit.form.Button" id="foob">
 			Make It
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				this.setAttribute("disabled",true);
 				dijit.byId("foobd").setAttribute("disabled",false);
 				new dojox.image.Magnifier({ scale:4.2, glassSize:200 },"foobar");
@@ -63,7 +63,7 @@
 
 		<button dojoType="dijit.form.Button" id="foobd" disabled="disabled">
 			Destroy It
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				this.setAttribute("disabled",true);
 				dijit.byId("foobar").destroy();
 				console.log('layout changed:');
diff --git a/dojox/image/tests/test_MagnifierLite.html b/dojox/image/tests/test_MagnifierLite.html
index 5006eab..8245175 100644
--- a/dojox/image/tests/test_MagnifierLite.html
+++ b/dojox/image/tests/test_MagnifierLite.html
@@ -13,7 +13,7 @@
 		
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="async: true, isDebug: true, parseOnLoad:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, isDebug: true, parseOnLoad:true"></script>
 	<script type="text/javascript">
 		require(["dojox/image/MagnifierLite", "dijit/form/Button", "dojo/parser"]);
 	</script>
@@ -57,7 +57,7 @@
 		
 		<button dojoType="dijit.form.Button" id="foob">
 			Make It
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				this.setAttribute("disabled",true);
 				dijit.byId("foobd").setAttribute("disabled",false);
 				new dojox.image.MagnifierLite({ scale:4.2, glassSize:200 },"foobar");
@@ -66,7 +66,7 @@
 
 		<button dojoType="dijit.form.Button" id="foobd" disabled="disabled">
 			Destroy It
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				dijit.byId("foob").setAttribute("disabled",false);
 				this.setAttribute("disabled",true);
 				dijit.byId("foobar").destroy(true);
diff --git a/dojox/image/tests/test_SlideShow.html b/dojox/image/tests/test_SlideShow.html
index 1a845e6..81ff60c 100644
--- a/dojox/image/tests/test_SlideShow.html
+++ b/dojox/image/tests/test_SlideShow.html
@@ -13,7 +13,7 @@
 	</style>
 	
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: false"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: false"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -54,7 +54,7 @@
 	<h1 class="testTitle">dojox.image.SlideShow</h1>
 
 	<h2>from dojo.data.ItemFileReadStore</h2>
-	<div jsId="imageItemStore" dojoType="dojo.data.ItemFileReadStore" url="images.json"></div>
+	<div data-dojo-id="imageItemStore" dojoType="dojo.data.ItemFileReadStore" url="images.json"></div>
 
 	This SlideShow should display five photos, and loop. It should also
 	open a URL when the image is clicked.  The widget should also resize to
diff --git a/dojox/image/tests/test_SlideShow_GoogleData.html b/dojox/image/tests/test_SlideShow_GoogleData.html
index ab60c52..d49749e 100644
--- a/dojox/image/tests/test_SlideShow_GoogleData.html
+++ b/dojox/image/tests/test_SlideShow_GoogleData.html
@@ -13,7 +13,7 @@
 	</style>
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/image/tests/test_ThumbnailPicker.html b/dojox/image/tests/test_ThumbnailPicker.html
index cacb624..a401aca 100644
--- a/dojox/image/tests/test_ThumbnailPicker.html
+++ b/dojox/image/tests/test_ThumbnailPicker.html
@@ -13,7 +13,7 @@
 	</style>
 	
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: false"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: false"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -150,7 +150,7 @@
 	<button onclick="changeStore()">Change Datastore</button>
     <div id="thumbPicker2" dojoType="dojox.image.ThumbnailPicker" size="400"
 		isClickable="false"></div>
-	<div jsId="imageItemStore" dojoType="dojo.data.ItemFileReadStore" url="images.json"></div>
+	<div data-dojo-id="imageItemStore" dojoType="dojo.data.ItemFileReadStore" url="images.json"></div>
 	
 	<h2>From FlickrRestStore:</h2>
 	This ThumbnailPicker should have 6 thumbnails, with each of them linking
diff --git a/dojox/image/tests/test_ThumbnailPickerLightbox.html b/dojox/image/tests/test_ThumbnailPickerLightbox.html
index 261357a..2851fab 100644
--- a/dojox/image/tests/test_ThumbnailPickerLightbox.html
+++ b/dojox/image/tests/test_ThumbnailPickerLightbox.html
@@ -91,7 +91,7 @@
 	
     <div id="thumbPicker2" dojoType="dojox.image.ThumbnailPicker" size="400"
 		isClickable="false"></div>
-	<div jsId="imageItemStore" dojoType="dojo.data.ItemFileReadStore" url="images.json"></div>
+	<div data-dojo-id="imageItemStore" dojoType="dojo.data.ItemFileReadStore" url="images.json"></div>
 
 </body>
 </html>
diff --git a/dojox/io/OAuth.js b/dojox/io/OAuth.js
index 45694d4..7035639 100644
--- a/dojox/io/OAuth.js
+++ b/dojox/io/OAuth.js
@@ -9,9 +9,9 @@ define([
 dojo.getObject("io.OAuth", true, dojox);
 
 dojox.io.OAuth = new (function(){
-	//	summary:
+	// summary:
 	//		Helper singleton for signing any kind of Ajax request using the OAuth 1.0 protocol.
-	//	description:
+	// description:
 	//		dojox.io.OAuth is a singleton class designed to allow anyone to sign a request,
 	//		based on the OAuth 1.0 specification, made with any of the Dojo Toolkit's Ajax
 	//		methods (such as dojo.xhr[verb], dojo.io.iframe, etc.).
@@ -37,7 +37,7 @@ dojox.io.OAuth = new (function(){
 	};
 
 	var decode = this.decode = function(str){
-		//	summary:
+		// summary:
 		//		Break apart the passed string and decode.
 		//		Some special cases are handled.
 		var a=[], list=str.split("&");
@@ -55,7 +55,7 @@ dojox.io.OAuth = new (function(){
 	};
 
 	function parseUrl(url){
-		//	summary:
+		// summary:
 		//		Create a map out of the passed URL.  Need to pull any
 		//		query string parameters off the URL for the base signature string.
         var keys = [
@@ -113,7 +113,7 @@ dojox.io.OAuth = new (function(){
 	}
 
 	function key(args){
-		//	summary:
+		// summary:
 		//		return the key used to sign a message based on the token object.
 		return encode(args.consumer.secret)
 			+ "&"
@@ -121,7 +121,7 @@ dojox.io.OAuth = new (function(){
 	}
 
 	function addOAuth(/* dojo.__XhrArgs */args, /* dojox.io.__OAuthArgs */oaa){
-		//	summary:
+		// summary:
 		//		Add the OAuth parameters to the query string/content.
 		var o = {
 			oauth_consumer_key: oaa.consumer.key,
@@ -137,7 +137,7 @@ dojox.io.OAuth = new (function(){
 	}
 
 	function convertArgs(args){
-		//	summary:
+		// summary:
 		//		Because of the need to create a base string, we have to do
 		//		some manual args preparation instead of relying on the internal
 		//		Dojo xhr functions.  But we'll let dojo.xhr assemble things
@@ -222,25 +222,21 @@ dojox.io.OAuth = new (function(){
 	}
 	
 	/*=====
-	 	dojox.io.OAuth.__AccessorArgs = function(key, secret){
-			//	key: String
+	 	dojox.io.OAuth.__AccessorArgs = {
+			// key: String
 			//		The key or token issued to either the consumer or by the OAuth service.
-			//	secret: String
+			// secret: String
 			//		The secret (shared secret for consumers, issued secret by OAuth service).
-			this.key = key;
-			this.secret = secret;
 		};
-		dojox.io.OAuth.__OAuthArgs = function(consumer, sig_method, token){
-			//	consumer: dojox.io.OAuth.__AccessorArgs
+		dojox.io.OAuth.__OAuthArgs = {
+			// consumer: dojox.io.OAuth.__AccessorArgs
 			//		The consumer information issued to your OpenAuth application.
-			//	sig_method: String
+			// sig_method: String
 			//		The method used to create the signature.  Should be PLAINTEXT or HMAC-SHA1.
-			//	token: dojox.io.OAuth.__AccessorArgs?
+			// token: dojox.io.OAuth.__AccessorArgs?
 			//		The request token and secret issued by the OAuth service.  If not
 			//		issued yet, this should be null.
-			this.consumer = consumer;
-			this.token = token;
-		}
+		};
 	=====*/
 
 	/*
@@ -252,10 +248,10 @@ dojox.io.OAuth = new (function(){
 	 */
 
 	this.sign = function(/* String*/method, /* dojo.__XhrArgs */args, /* dojox.io.OAuth.__OAuthArgs */oaa){
-		//	summary:
+		// summary:
 		//		Given the OAuth access arguments, sign the kwArgs that you would pass
 		//		to any dojo Ajax method (dojo.xhr*, dojo.io.iframe, dojo.io.script).
-		//	example:
+		// example:
 		//		Sign the kwArgs object for use with dojo.xhrGet:
 		//	|	var oaa = {
 		//	|		consumer: {
diff --git a/dojox/io/httpParse.js b/dojox/io/httpParse.js
index d19f37a..046518a 100644
--- a/dojox/io/httpParse.js
+++ b/dojox/io/httpParse.js
@@ -5,15 +5,15 @@ dojox.io.httpParse = function(/*String*/httpStream, /*String?*/topHeaders,/*Bool
 	// summary:
 	//		Parses an HTTP stream for a message.
 	// httpStream:
-	// 		HTTP stream to parse
+	//		HTTP stream to parse
 	// topHeaders:
 	//		Extra header information to add to each HTTP request (kind of HTTP inheritance)
 	// partial:
 	//		A true value indicates that the stream may not be finished, it may end arbitrarily in mid stream.
 	//		The last XHR object will have a special property _lastIndex that indicates the how far along
-	// 		the httpStream could be successfully parsed into HTTP messages.
-	// return:
-	// 		Returns an array of XHR-like object for reading the headers for each message
+	//		the httpStream could be successfully parsed into HTTP messages.
+	// returns:
+	//		Returns an array of XHR-like object for reading the headers for each message
 	//
 	var xhrs=[];
 	var streamLength = httpStream.length;
diff --git a/dojox/io/proxy/tests/xip.html b/dojox/io/proxy/tests/xip.html
index 1471cdd..99e2718 100644
--- a/dojox/io/proxy/tests/xip.html
+++ b/dojox/io/proxy/tests/xip.html
@@ -10,7 +10,7 @@
 	</style>
 
 	<script type="text/javascript" src="../../../../dojo/dojo.js"
-		djConfig="isDebug:true"></script>
+		data-dojo-config="isDebug:true"></script>
 	<script type="text/javascript">
 		var testXmlGet;
 		require(['dojo/_base/kernel', 'dojox/io/proxy/xip', 'dojo/_base/xhr', 'dojo/_base/html'], function(dojo, xip){
diff --git a/dojox/io/proxy/xip.js b/dojox/io/proxy/xip.js
index acb08a4..34a097e 100644
--- a/dojox/io/proxy/xip.js
+++ b/dojox/io/proxy/xip.js
@@ -2,12 +2,14 @@ define(['dojo/main', 'dojo/io/iframe', 'dojox/data/dom', 'dojo/_base/xhr', 'dojo
 	dojo.getObject("io.proxy.xip", true, dojox);
 
 dojox.io.proxy.xip = {
-	//summary: Object that implements the iframe handling for XMLHttpRequest
-	//IFrame Proxying.
-	//description: Do not use this object directly. See the Dojo Book page
-	//on XMLHttpRequest IFrame Proxying:
-	//http://dojotoolkit.org/book/dojo-book-0-4/part-5-connecting-pieces/i-o/cross-domain-xmlhttprequest-using-iframe-proxy
-	//Usage of XHR IFrame Proxying does not work from local disk in Safari.
+	// summary:
+	//		Object that implements the iframe handling for XMLHttpRequest
+	//		IFrame Proxying.
+	//
+	//		Do not use this object directly. See the Dojo Book page
+	//		on XMLHttpRequest IFrame Proxying:
+	//		http://dojotoolkit.org/book/dojo-book-0-4/part-5-connecting-pieces/i-o/cross-domain-xmlhttprequest-using-iframe-proxy
+	//		Usage of XHR IFrame Proxying does not work from local disk in Safari.
 
 	/*
 	This code is really focused on just sending one complete request to the server, and
@@ -53,8 +55,9 @@ dojox.io.proxy.xip = {
 
 
 	send: function(/*Object*/facade){
-		//summary: starts the xdomain request using the provided facade.
-		//This method first does some init work, then delegates to _realSend.
+		// summary:
+		//		starts the xdomain request using the provided facade.
+		//		This method first does some init work, then delegates to _realSend.
 
 		var url = this.xipClientUrl;
 		//Make sure we are not dealing with javascript urls, just to be safe.
@@ -89,7 +92,8 @@ dojox.io.proxy.xip = {
 	},
 
 	_realSend: function(facade){
-		//summary: starts the actual xdomain request using the provided facade.
+		// summary:
+		//		starts the actual xdomain request using the provided facade.
 		var stateId = "XhrIframeProxy" + (this._stateIdCounter++);
 		facade._stateId = stateId;
 
@@ -297,8 +301,8 @@ dojox.io.proxy.xip = {
 	},
 
 	fragmentReceivedEvent: function(evt){
-		//summary: HTML5 document messaging endpoint. Unpack the event to see
-		//if we want to use it.
+		// summary:
+		//		HTML5 document messaging endpoint. Unpack the event to see if we want to use it.
 		if(evt.uri.split("#")[0] == this.fullXipClientUrl){
 			this.fragmentReceived(evt.data);
 		}
@@ -364,11 +368,12 @@ dojo._xhrObj = dojox.io.proxy.xip.createFacade;
 	not use it.
 */
 dojox.io.proxy.xip.XhrIframeFacade = function(ifpServerUrl){
-	//summary: XMLHttpRequest facade object used by dojox.io.proxy.xip.
-	
-	//description: Do not use this object directly. See the Dojo Book page
-	//on XMLHttpRequest IFrame Proxying:
-	//http://dojotoolkit.org/book/dojo-book-0-4/part-5-connecting-pieces/i-o/cross-domain-xmlhttprequest-using-iframe-proxy
+	// summary:
+	//		XMLHttpRequest facade object used by dojox.io.proxy.xip.
+	//
+	//		Do not use this object directly. See the Dojo Book page
+	//		on XMLHttpRequest IFrame Proxying:
+	//		http://dojotoolkit.org/book/dojo-book-0-4/part-5-connecting-pieces/i-o/cross-domain-xmlhttprequest-using-iframe-proxy
 	this._requestHeaders = {};
 	this._allResponseHeaders = null;
 	this._responseHeaders = {};
diff --git a/dojox/io/scriptFrame.js b/dojox/io/scriptFrame.js
index dd4c05c..4514876 100644
--- a/dojox/io/scriptFrame.js
+++ b/dojox/io/scriptFrame.js
@@ -24,12 +24,14 @@ define(["dojo/main", "dojo/io/script", "dojo/io/iframe"], function(dojo, ioScrip
 		},
 
 		_fixAttachUrl: function(/*String*/url){
-			//summary: fixes the URL so that
+			// summary:
+			//		fixes the URL so that
 		},
 
 		_loaded: function(/*String*/frameId){
-			//summary: callback used when waiting for a frame to load (related to the usage of
-			//the frameId argument to dojo.io.script.get().
+			// summary:
+			//		callback used when waiting for a frame to load (related to the usage of
+			//		the frameId argument to dojo.io.script.get().
 			var waiters = this._getWaiters(frameId);
 			this._loadedIds[frameId] = true;
 			this._waiters[frameId] = null;
@@ -48,10 +50,11 @@ define(["dojo/main", "dojo/io/script", "dojo/io/iframe"], function(dojo, ioScrip
 
 	//Define frame-aware _canAttach method on dojo.io.script
 	ioScript._canAttach = function(/*Object*/ioArgs){
-		//summary: provides an override of dojo.io.script._canAttach to check for
-		//the existence of a the args.frameDoc property. If it is there, and it is a string,
-		//not a document, then create the iframe with an ID of frameDoc, and use that for the calls.
-		//If frameDoc is a document, then dojox.io.scriptFrame should not get involved.
+		// summary:
+		//		provides an override of dojo.io.script._canAttach to check for
+		//		the existence of a the args.frameDoc property. If it is there, and it is a string,
+		//		not a document, then create the iframe with an ID of frameDoc, and use that for the calls.
+		//		If frameDoc is a document, then dojox.io.scriptFrame should not get involved.
 		var fId = ioArgs.args.frameDoc;
 
 		if(fId && dojo.isString(fId)){
diff --git a/dojox/io/tests/scriptFrame.html b/dojox/io/tests/scriptFrame.html
index e55c7b7..e63c487 100644
--- a/dojox/io/tests/scriptFrame.html
+++ b/dojox/io/tests/scriptFrame.html
@@ -7,7 +7,7 @@
 			@import "../../../dojo/resources/dojo.css";
 		</style>
 		<script type="text/javascript" 
-			src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+			src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 			require(['doh/runner', 'dojo/io/script', 'dojox/io/scriptFrame'], function(doh, script, scriptFrame){
 				doh.register("t", 
diff --git a/dojox/io/tests/scriptFrameRepeat.html b/dojox/io/tests/scriptFrameRepeat.html
index 057d544..da57181 100644
--- a/dojox/io/tests/scriptFrameRepeat.html
+++ b/dojox/io/tests/scriptFrameRepeat.html
@@ -7,7 +7,7 @@
 			@import "../../../dojo/resources/dojo.css";
 		</style>
 		<script type="text/javascript" 
-			src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+			src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<script type="text/javascript">
 			require(['dojo/io/script', 'dojox/io/scriptFrame'], function(script, scriptFrame){
 				function repeatCall(){
diff --git a/dojox/io/tests/windowName.html b/dojox/io/tests/windowName.html
index be303bb..5b9d687 100644
--- a/dojox/io/tests/windowName.html
+++ b/dojox/io/tests/windowName.html
@@ -7,7 +7,7 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 	<script type="text/javascript">
 		var test, testPost;
 		require(['dojox/io/windowName'], function(windowName){
diff --git a/dojox/io/tests/xhrMultiPart.html b/dojox/io/tests/xhrMultiPart.html
index 6127c71..84e3b91 100644
--- a/dojox/io/tests/xhrMultiPart.html
+++ b/dojox/io/tests/xhrMultiPart.html
@@ -7,7 +7,7 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 	<script type="text/javascript" src="../xhrMultiPart.js"></script>
 	<script type="text/javascript">
 		var testXhrMulti, testXhrMultiForm, testXhrMultiFormWithFile;
diff --git a/dojox/io/windowName.js b/dojox/io/windowName.js
index 7a302ba..3c6a17b 100644
--- a/dojox/io/windowName.js
+++ b/dojox/io/windowName.js
@@ -6,57 +6,59 @@ dojox.io.windowName = {
 	send: function(/*String*/ method, /*dojo.__IoArgs*/ args){
 		// summary:
 		//		Provides secure cross-domain request capability.
-		// 		Sends a request using an iframe (POST or GET) and reads the response through the
-		// 		frame's window.name.
+		//		Sends a request using an iframe (POST or GET) and reads the response through the
+		//		frame's window.name.
 		//
-		//	method:
+		// method:
 		//		The method to use to send the request, GET or POST
 		//
-		//	args:
+		// args:
 		//		See dojo.xhr
 		//
-		//	args.authElement: DOMNode?
+		//		####args.authElement: DOMNode?
+		//
 		//		By providing an authElement, this indicates that windowName should use the
-		// 		authorized window.name protocol, relying on
+		//		authorized window.name protocol, relying on
 		//		the loaded XD resource to return to the provided return URL on completion
 		//		of authorization/authentication. The provided authElement will be used to place
 		//		the iframe in, so the user can interact with the server resource for authentication
 		//		and/or authorization to access the resource.
 		//
-		//	args.onAuthLoad: Function?
+		//		####args.onAuthLoad: Function?
+		//
 		//		When using authorized access to resources, this function will be called when the
-		// 		authorization page has been loaded. (When authorization is actually completed,
-		// 		the deferred callback function is called with the result). The primary use for this
-		// 		is to make the authElement visible to the user once the resource has loaded
-		// 		(this can be preferable to showing the iframe while the resource is loading
-		// 		since it may not require authorization, it may simply return the resource).
+		//		authorization page has been loaded. (When authorization is actually completed,
+		//		the deferred callback function is called with the result). The primary use for this
+		//		is to make the authElement visible to the user once the resource has loaded
+		//		(this can be preferable to showing the iframe while the resource is loading
+		//		since it may not require authorization, it may simply return the resource).
 		//
-		//	description:
+		// description:
 		//		In order to provide a windowname transport accessible resources/web services, a server
-		// 		should check for the presence of a parameter window.name=true and if a request includes
-		// 		such a parameter, it should respond to the request with an HTML
-		// 		document that sets it's window.name to the string that is to be
-		// 		delivered to the client. For example, if a client makes a window.name request like:
+		//		should check for the presence of a parameter window.name=true and if a request includes
+		//		such a parameter, it should respond to the request with an HTML
+		//		document that sets it's window.name to the string that is to be
+		//		delivered to the client. For example, if a client makes a window.name request like:
 		// 	|	http://othersite.com/greeting?windowname=true
-		// 		And server wants to respond to the client with "Hello", it should return an html page:
-		// |	<html><script type="text/javascript">
-		// |	window.name="Hello";
-		// |	</script></html>
-		// 		One can provide XML or JSON data by simply quoting the data as a string, and parsing the data
-		// 		on the client.
+		//		And server wants to respond to the client with "Hello", it should return an html page:
+		//	|	<html><script type="text/javascript">
+		//	|	window.name="Hello";
+		//	|	</script></html>
+		//		One can provide XML or JSON data by simply quoting the data as a string, and parsing the data
+		//		on the client.
 		//		If you use the authorization window.name protocol, the requester should include an
-		// 		authElement element in the args, and a request will be created like:
+		//		authElement element in the args, and a request will be created like:
 		// 	|	http://othersite.com/greeting?windowname=auth
-		// 		And the server can respond like this:
-		// |	<html><script type="text/javascript">
-		// |	var loc = window.name;
-		// |	authorizationButton.onclick = function(){
-		// |		window.name="Hello";
-		// |		location = loc;
-		// |	};
-		// |	</script></html>
+		//		And the server can respond like this:
+		//	|	<html><script type="text/javascript">
+		//	|	var loc = window.name;
+		//	|	authorizationButton.onclick = function(){
+		//	|		window.name="Hello";
+		//	|		location = loc;
+		//	|	};
+		//	|	</script></html>
 		//		When using windowName from a XD Dojo build, make sure to set the
-		// 		dojo.dojoBlankHtmlUrl property to a local URL.
+		//		dojo.dojoBlankHtmlUrl property to a local URL.
 		args.url += (args.url.match(/\?/) ? '&' : '?') + "windowname=" + (args.authElement ? "auth" : true); // indicate our desire for window.name communication
 		var authElement = args.authElement;
 		var cleanup = function(result){
@@ -68,7 +70,7 @@ dojox.io.windowName = {
 			}catch(e){}
 			(authElement || dojo.body()).removeChild(dfd.ioArgs.outerFrame); // clean up
 			return result;
-		}
+		};
 		var dfd = dojo._ioSetArgs(args,cleanup,cleanup,cleanup);
 		if(args.timeout){
 			setTimeout(function(){
diff --git a/dojox/io/xhrMultiPart.js b/dojox/io/xhrMultiPart.js
index 7797d11..914ce81 100644
--- a/dojox/io/xhrMultiPart.js
+++ b/dojox/io/xhrMultiPart.js
@@ -8,30 +8,24 @@ define([
 	dojo.getObject("io.xhrMultiPart", true, dojox);
 
 	/*=====
-	dojox.io.__xhrContentArgs = function(){
-		//	name: String
+	var __xhrContentArgs = {
+		// name: String
 		//		Name of the form value.
-		//	content: String
+		// content: String
 		//		The contents of the value.
-		//	filename: String?
+		// filename: String?
 		//		An optional filename to pass to the server, as defined by the boundary.
-		//	contentType: String?
+		// contentType: String?
 		//		An optional content-type (MIME) to pass to the server, if value is being
 		//		treated as a file.
-		//	charset: String?
+		// charset: String?
 		//		Optional charset to pass, for the server to interpret the file correctly.
-		//	contentTransferEncoding: String?
+		// contentTransferEncoding: String?
 		//		Optional transfer encoding header value.
-		this.name = name;
-		this.content = content;
-		this.filename = filename;
-		this.contentType = contentType;
-		this.charset = charset;
-		this.contentTransferEncoding = contentTransferEncoding;
-	}
+	};
 	=====*/
-	function _createPart(/* dojox.io.__xhrContentArgs */args, /* String */boundary){
-		//	summary
+	function _createPart(/*__xhrContentArgs */args, /* String */boundary){
+		// summary:
 		//		Assemble an array of boundary parts based on the passed values in args.
 		if(!args["name"] && !args["content"]){
 			throw new Error("Each part of a multi-part request requires 'name' and 'content'.");
@@ -59,7 +53,7 @@ define([
 	}
 
 	function _partsFromNode(/* DOMNode */node, /* String */boundary){
-		//	summary
+		// summary:
 		//		Assemble an array of boundary parts based on the passed FORM node.
 		var o=dojo.formToObject(node), parts=[];
 		for(var p in o){
@@ -75,55 +69,45 @@ define([
 	}
 
 	/*=====
-	dojox.io.__xhrMultiArgs = function(){
-		//	url: String
+	var __xhrMultiArgs = {
+		// url: String
 		//		URL to server endpoint.
-		//	content: Object?
+		// content: Object?
 		//		Contains properties with string values. These
 		//		properties will be serialized using multi-part
 		//		boundaries.
-		//	file: Object?
+		// file: Object?
 		//		Alias for "content".  Provided for backwards compatibility.
-		//	timeout: Integer?
+		// timeout: Integer?
 		//		Milliseconds to wait for the response. If this time
 		//		passes, the then error callbacks are called.
-		//	form: DOMNode?
+		// form: DOMNode?
 		//		DOM node for a form. Used to extract the form values
 		//		and send to the server; each form value will be serialized
 		//		using multi-part boundaries.
-		//	preventCache: Boolean?
+		// preventCache: Boolean?
 		//		Default is false. If true, then a
 		//		"dojo.preventCache" parameter is sent in the request
 		//		with a value that changes with each request
 		//		(timestamp). Useful only with GET-type requests.
-		//	handleAs: String?
+		// handleAs: String?
 		//		Acceptable values depend on the type of IO
 		//		transport (see specific IO calls for more information).
-		//	load: Function?
+		// load: Function?
 		//		function(response, ioArgs){}. response is an Object, ioArgs
 		//		is of type dojo.__IoCallbackArgs. The load function will be
 		//		called on a successful response.
-		//	error: Function?
+		// error: Function?
 		//		function(response, ioArgs){}. response is an Object, ioArgs
 		//		is of type dojo.__IoCallbackArgs. The error function will
 		//		be called in an error case.
-		//	handle: Function?
+		// handle: Function?
 		//		function(response, ioArgs){}. response is an Object, ioArgs
 		//		is of type dojo.__IoCallbackArgs. The handle function will
 		//		be called in either the successful or error case.
-		this.url = url;
-		this.content = content;
-		this.file = file;
-		this.timeout = timeout;
-		this.form = form;
-		this.preventCache = preventCache;
-		this.handleAs = handleAs;
-		this.load = load;
-		this.error = error;
-		this.handle = handle;
-	}
+	};
 	=====*/
-	dojox.io.xhrMultiPart = function(/* dojox.io.__xhrMultiArgs */args){
+	dojox.io.xhrMultiPart = function(/* __xhrMultiArgs */args){
 		if(!args["file"] && !args["content"] && !args["form"]){
 			throw new Error("content, file or form must be provided to dojox.io.xhrMultiPart's arguments");
 		}
diff --git a/dojox/io/xhrPlugins.js b/dojox/io/xhrPlugins.js
index 8b930c3..c59b1fd 100644
--- a/dojox/io/xhrPlugins.js
+++ b/dojox/io/xhrPlugins.js
@@ -7,9 +7,9 @@ define(["dojo/_base/kernel", "dojo/_base/xhr", "dojo/AdapterRegistry"], function
 		return plainXhr = dojox.io.xhrPlugins.plainXhr = plainXhr || dojo._defaultXhr || xhr;
 	}
 	dojox.io.xhrPlugins.register = function(){
-		//	summary:
-		// 		overrides the default xhr handler to implement a registry of
-		// 		xhr handlers
+		// summary:
+		//		overrides the default xhr handler to implement a registry of
+		//		xhr handlers
 		var plainXhr = getPlainXhr();
 		if(!registry){
 			registry = new AdapterRegistry();
@@ -34,16 +34,16 @@ define(["dojo/_base/kernel", "dojo/_base/xhr", "dojo/AdapterRegistry"], function
 		return registry.register.apply(registry, arguments);
 	};
 	dojox.io.xhrPlugins.addProxy = function(proxyUrl){
-		//	summary:
+		// summary:
 		//		adds a server side proxy xhr handler for cross-site URLs
-		//	proxyUrl:
+		// proxyUrl:
 		//		This is URL to send the requests to.
-		//	example:
+		// example:
 		//		Define a proxy:
 		//	|	dojox.io.xhrPlugins.addProxy("/proxy?url=");
-		// 		And then when you call:
+		//		And then when you call:
 		//	|	dojo.xhr("GET",{url:"http://othersite.com/file"});
-		// 		It would result in the request (to your origin server):
+		//		It would result in the request (to your origin server):
 		//	|	GET /proxy?url=http%3A%2F%2Fothersite.com%2Ffile HTTP/1.1
 		var plainXhr = getPlainXhr();
 		dojox.io.xhrPlugins.register(
@@ -62,20 +62,20 @@ define(["dojo/_base/kernel", "dojo/_base/xhr", "dojo/AdapterRegistry"], function
 	};
 	var csXhrSupport;
 	dojox.io.xhrPlugins.addCrossSiteXhr = function(url, httpAdapter){
-		//	summary:
-		// 		Adds W3C Cross site XHR or XDomainRequest handling for the given URL prefix
+		// summary:
+		//		Adds W3C Cross site XHR or XDomainRequest handling for the given URL prefix
 		//
-		// 	url:
+		// url:
 		//		Requests that start with this URL will be considered for using
-		// 		cross-site XHR.
+		//		cross-site XHR.
 		//
-		// 	httpAdapter: This allows for adapting HTTP requests that could not otherwise be
-		// 		sent with XDR, so you can use a convention for headers and PUT/DELETE methods.
+		// httpAdapter: This allows for adapting HTTP requests that could not otherwise be
+		//		sent with XDR, so you can use a convention for headers and PUT/DELETE methods.
 		//
-		//	description:
-		// 		This can be used for servers that support W3C cross-site XHR. In order for
-		// 		a server to allow a client to make cross-site XHR requests,
-		// 		it should respond with the header like:
+		// description:
+		//		This can be used for servers that support W3C cross-site XHR. In order for
+		//		a server to allow a client to make cross-site XHR requests,
+		//		it should respond with the header like:
 		//	|	Access-Control: allow <*>
 		//		see: http://www.w3.org/TR/access-control/
 		var plainXhr = getPlainXhr();
@@ -129,13 +129,13 @@ define(["dojo/_base/kernel", "dojo/_base/xhr", "dojo/AdapterRegistry"], function
 	};
 	dojox.io.xhrPlugins.fullHttpAdapter = function(plainXhr,noRawBody){
 		// summary:
-		// 		Provides a HTTP adaption.
+		//		Provides a HTTP adaption.
 		// description:
-		// 		The following convention is used:
-		// 		method name -> ?http-method=PUT
-		// 		Header -> http-Header-Name=header-value
+		//		The following convention is used:
+		//		method name -> ?http-method=PUT
+		//		Header -> http-Header-Name=header-value
 		//		X-Header -> header_name=header-value
-		//	example:
+		// example:
 		//		dojox.io.xhrPlugins.addXdr("http://somesite.com", dojox.io.xhrPlugins.fullHttpAdapter);
 		return function(method,args,hasBody){
 			var content = {};
diff --git a/dojox/io/xhrScriptPlugin.js b/dojox/io/xhrScriptPlugin.js
index d64b480..f788a46 100644
--- a/dojox/io/xhrScriptPlugin.js
+++ b/dojox/io/xhrScriptPlugin.js
@@ -7,10 +7,11 @@ dojox.io.xhrScriptPlugin = function(/*String*/url, /*String*/callbackParamName,
 	//		dojox.io.script for more information on the transport. Note, that JSONP
 	//		is *not* a secure transport, by loading data from a third-party site using JSONP
 	//		the site has full access to your JavaScript environment.
-	//	url:
+	// url:
 	//		Url prefix of the site which can handle JSONP requests.
-	// 	httpAdapter: This allows for adapting HTTP requests that could not otherwise be
-	// 		sent with JSONP, so you can use a convention for headers and PUT/DELETE methods.
+	// httpAdapter:
+	//		This allows for adapting HTTP requests that could not otherwise be
+	//		sent with JSONP, so you can use a convention for headers and PUT/DELETE methods.
 	xhrPlugins.register(
 		"script",
 		function(method,args){
diff --git a/dojox/io/xhrWindowNamePlugin.js b/dojox/io/xhrWindowNamePlugin.js
index 4ea5d8a..76da4f9 100644
--- a/dojox/io/xhrWindowNamePlugin.js
+++ b/dojox/io/xhrWindowNamePlugin.js
@@ -13,10 +13,11 @@ dojox.io.xhrWindowNamePlugin = function(/*String*/url, /*Function?*/httpAdapter,
 	// summary:
 	//		Adds the windowName transport as an XHR plugin for the given site. See
 	//		dojox.io.windowName for more information on the transport.
-	//	url:
+	// url:
 	//		Url prefix of the site which can handle windowName requests.
-	// 	httpAdapter: This allows for adapting HTTP requests that could not otherwise be
-	// 		sent with window.name, so you can use a convention for headers and PUT/DELETE methods.
+	// httpAdapter:
+	//		This allows for adapting HTTP requests that could not otherwise be
+	//		sent with window.name, so you can use a convention for headers and PUT/DELETE methods.
 	xhrPlugins.register(
 		"windowName",
 		function(method,args){
@@ -36,7 +37,7 @@ dojox.io.xhrWindowNamePlugin = function(/*String*/url, /*Function?*/httpAdapter,
 						// convert the hash to an object to act like response headers
 						return dojo.queryToObject(ioArgs.hash.match(/[^#]*$/)[0])[name];
 					}
-				}
+				};
 				// use the XHR content handlers for handling
 				if(ioArgs.handleAs == 'json'){
 					// use a secure json verifier, using object capability validator for now
diff --git a/dojox/jq.js b/dojox/jq.js
index 4e22bc3..81d3387 100644
--- a/dojox/jq.js
+++ b/dojox/jq.js
@@ -58,8 +58,10 @@ dojo.query differences that cause some tests to fail:
 */
 
 (function(){
-	//Enable io topic publishing
+	//Enable io topic publishing.   But don't mask the original definition of ioPublish from the doc parser.
+	/*===== var ioPublish = dojo.config.ioPublish; =====*/
 	dojo.config.ioPublish = true;
+	/*===== dojo.config.ioPublish = ioPublish; =====*/
 
 	//Support stuff for toDom
 	var selfClosedTags = "|img|meta|hr|br|input|";
@@ -438,11 +440,12 @@ dojo.query differences that cause some tests to fail:
 	}
 	
 	function jqMix(obj, props){
-		//summary: an attempt at a mixin that follows
-		//jquery's .extend rules. Seems odd. Not sure how
-		//to resolve this with dojo.mixin and what the use
-		//cases are for the jquery version.
-		//Copying some code from dojo._mixin.
+		// summary:
+		//		an attempt at a mixin that follows
+		//		jquery's .extend rules. Seems odd. Not sure how
+		//		to resolve this with dojo.mixin and what the use
+		//		cases are for the jquery version.
+		//		Copying some code from dojo._mixin.
 		if(obj == props){
 			return obj;
 		}
@@ -693,8 +696,11 @@ dojo.query differences that cause some tests to fail:
 	}
 
 	function iframeDoc(/*DOMNode*/iframeNode){
-		//summary: Returns the document object associated with the iframe DOM Node argument.
+		// summary:
+		//		Returns the document object associated with the iframe DOM Node argument.
+
 		//Taken from dojo.io.iframe.doc(). Needed for contents() function below.
+
 		var doc = iframeNode.contentDocument || // W3
 			(
 				(
@@ -840,7 +846,9 @@ dojo.query differences that cause some tests to fail:
 	}
 
 	function getDimensions(/*DOMNode*/node, /*String*/type, /*Boolean*/usePadding, /*Boolean*/useBorder, /*Boolean*/useMargin){
-		//summary: sums up the different parts of the width/height based on arguments.
+		// summary:
+		//		sums up the different parts of the width/height based on arguments.
+
 		//If hidden, temporarily show it, do measurements then close.
 		var rehide = false;
 		if((rehide = node.style.display == "none")){
@@ -891,7 +899,9 @@ dojo.query differences that cause some tests to fail:
 	var currentEvtData;
 
 	function getNonNamespacedName(/*String*/evtName){
-		//summary: gets name of the event before the first ".".
+		// summary:
+		//		gets name of the event before the first ".".
+
 		//The $$ stuff is special ids used to create unique names
 		//for bound functions that did not have a unique namespace name.
 		evtName = evtName.split("$$")[0];
@@ -903,7 +913,9 @@ dojo.query differences that cause some tests to fail:
 	}
 
 	function domConnect(/*DOMNode*/node, /*String*/evtName){
-		//summary: handles creating the connection with a real DOM event.
+		// summary:
+		//		handles creating the connection with a real DOM event.
+
 		//This work should only be done one time per evName type.
 		//If the event if an ajax event, use dojo.subscribe instead.
 		if(evtName.indexOf("ajax") == 0){
@@ -963,10 +975,11 @@ dojo.query differences that cause some tests to fail:
 	});
 
 	function makeTriggerData(data, type){
-		//summary: makes sure that the data array is copied
-		//and has an event as the first arg. If this function generates
-		//a fake event (known by the data[0]._isFake property being true)
-		//then the data[0].target needs to be set by the consumer of this function.
+		// summary:
+		//		makes sure that the data array is copied
+		//		and has an event as the first arg. If this function generates
+		//		a fake event (known by the data[0]._isFake property being true)
+		//		then the data[0].target needs to be set by the consumer of this function.
 		
 		data = data || [];
 		data = [].concat(data);
@@ -985,7 +998,8 @@ dojo.query differences that cause some tests to fail:
 	var triggerHandlersCalled = false;
 
 	function triggerHandlers(/*DOMNode*/node, /*Array*/data, /*Function?*/extraFunc){
-		//summary: handles the actual callbacks to the handlers.
+		// summary:
+		//		handles the actual callbacks to the handlers.
 		
 		//Indicate triggerHandlers was called.
 		triggerHandlersCalled = true;
@@ -1204,9 +1218,9 @@ dojo.query differences that cause some tests to fail:
 
 	function copyEventHandlers(/*DOMNode*/ src, /*DOMNode*/ target){
 		// summary:
-		// 		copies the event handlers from onne src *element* node to
-		// 		another target *element* node. Assumes that target had
-		// 		no previous events on it, and is a clone of the src node.
+		//		copies the event handlers from onne src *element* node to
+		//		another target *element* node. Assumes that target had
+		//		no previous events on it, and is a clone of the src node.
 
 		//Get src listeners.
 		var srcNodeId = target.getAttribute(eventAttr);
@@ -1365,7 +1379,7 @@ dojo.query differences that cause some tests to fail:
 
 	f._cloneNode = function(/*DOMNode*/ src){
 		// summary:
-		// 		private utiltity to clone a node. Copies event handlers too.
+		//		private utiltity to clone a node. Copies event handlers too.
 		var target = src.cloneNode(true);
 
 		if(src.nodeType == 1){
@@ -1411,7 +1425,7 @@ dojo.query differences that cause some tests to fail:
 		if(dojo.isString(speed)){
 			if(speed == "slow"){
 				speed = 700;
-			}else if(speed = "fast"){
+			}else if(speed == "fast"){
 				speed = 300;
 			}else{
 				//Everything else is considered normal speed.
diff --git a/dojox/json/query.js b/dojox/json/query.js
index 05b7e7e..fcb1bd4 100644
--- a/dojox/json/query.js
+++ b/dojox/json/query.js
@@ -1,6 +1,6 @@
-define(["dojo/_base/kernel", "dojox", "dojo/_base/array"], function(dojo, dojox){
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojox", "dojo/_base/array"], function(dojo, lang, dojox){
 
-	dojo.getObject("json", true, dojox);
+	lang.getObject("json", true, dojox);
 
 	dojox.json._slice = function(obj,start,end,step){
 		// handles slice operations: [3:6:2]
@@ -12,7 +12,7 @@ define(["dojo/_base/kernel", "dojox", "dojo/_base/array"], function(dojo, dojox)
 	  		results.push(obj[i]);
 	  	}
 		return results;
-	}
+	};
 	dojox.json._find = function e(obj,name){
 		// handles ..name, .*, [*], [val1,val2], [val]
 		// name can be a property to search for, undefined for full recursive, or an array for picking by index
@@ -54,7 +54,7 @@ define(["dojo/_base/kernel", "dojox", "dojo/_base/array"], function(dojo, dojox)
 			walk(obj);
 		}
 		return results;
-	}
+	};
 
 	dojox.json._distinctFilter = function(array, callback){
 		// does the filter with removal of duplicates in O(n)
@@ -83,99 +83,97 @@ define(["dojo/_base/kernel", "dojox", "dojo/_base/array"], function(dojo, dojox)
 			}
 		}
 		return outArr;
-	}
+	};
 	return dojox.json.query = function(/*String*/query,/*Object?*/obj){
 		// summary:
-		// 		Performs a JSONQuery on the provided object and returns the results.
-		// 		If no object is provided (just a query), it returns a "compiled" function that evaluates objects
-		// 		according to the provided query.
+		//		Performs a JSONQuery on the provided object and returns the results.
+		//		If no object is provided (just a query), it returns a "compiled" function that evaluates objects
+		//		according to the provided query.
 		// query:
-		// 		Query string
-		// 	obj:
-		// 		Target of the JSONQuery
-		//
-		//	description:
+		//		Query string
+		// obj:
+		//		Target of the JSONQuery
+		// description:
 		//		JSONQuery provides a comprehensive set of data querying tools including filtering,
 		//		recursive search, sorting, mapping, range selection, and powerful expressions with
 		//		wildcard string comparisons and various operators. JSONQuery generally supersets
-		// 		JSONPath and provides syntax that matches and behaves like JavaScript where
-		// 		possible.
+		//		JSONPath and provides syntax that matches and behaves like JavaScript where
+		//		possible.
 		//
 		//		JSONQuery evaluations begin with the provided object, which can referenced with
-		// 		$. From
-		// 		the starting object, various operators can be successively applied, each operating
-		// 		on the result of the last operation.
+		//		$. From
+		//		the starting object, various operators can be successively applied, each operating
+		//		on the result of the last operation.
 		//
-		// 		Supported Operators:
-		// 		--------------------
-		//		* .property - This will return the provided property of the object, behaving exactly
-		// 		like JavaScript.
-		// 		* [expression] - This returns the property name/index defined by the evaluation of
-		// 		the provided expression, behaving exactly like JavaScript.
-		//		* [?expression] - This will perform a filter operation on an array, returning all the
-		// 		items in an array that match the provided expression. This operator does not
+		//		Supported Operators
+		//		--------------------
+		//
+		//		- .property - This will return the provided property of the object, behaving exactly
+		//		like JavaScript.
+		//		- [expression] - This returns the property name/index defined by the evaluation of
+		//		the provided expression, behaving exactly like JavaScript.
+		//		- [?expression] - This will perform a filter operation on an array, returning all the
+		//		items in an array that match the provided expression. This operator does not
 		//		need to be in brackets, you can simply use ?expression, but since it does not
 		//		have any containment, no operators can be used afterwards when used
-		// 		without brackets.
-		//		* [^?expression] - This will perform a distinct filter operation on an array. This behaves
+		//		without brackets.
+		//		- [^?expression] - This will perform a distinct filter operation on an array. This behaves
 		//		as [?expression] except that it will remove any duplicate values/objects from the
 		//		result set.
-		// 		* [/expression], [\expression], [/expression, /expression] - This performs a sort
-		// 		operation on an array, with sort based on the provide expression. Multiple comma delimited sort
-		// 		expressions can be provided for multiple sort orders (first being highest priority). /
+		//		- [/expression], [\expression], [/expression, /expression] - This performs a sort
+		//		operation on an array, with sort based on the provide expression. Multiple comma delimited sort
+		//		expressions can be provided for multiple sort orders (first being highest priority). /
 		//		indicates ascending order and \ indicates descending order
-		// 		* [=expression] - This performs a map operation on an array, creating a new array
+		//		- [=expression] - This performs a map operation on an array, creating a new array
 		//		with each item being the evaluation of the expression for each item in the source array.
-		//		* [start:end:step] - This performs an array slice/range operation, returning the elements
+		//		- [start:end:step] - This performs an array slice/range operation, returning the elements
 		//		from the optional start index to the optional end index, stepping by the optional step number.
-		// 		* [expr,expr] - This a union operator, returning an array of all the property/index values from
-		// 		the evaluation of the comma delimited expressions.
-		// 		* .* or [*] - This returns the values of all the properties of the current object.
-		// 		* $ - This is the root object, If a JSONQuery expression does not being with a $,
-		// 		it will be auto-inserted at the beginning.
-		// 		* @ - This is the current object in filter, sort, and map expressions. This is generally
-		// 		not necessary, names are auto-converted to property references of the current object
-		// 		in expressions.
-		// 		*	..property - Performs a recursive search for the given property name, returning
-		// 		an array of all values with such a property name in the current object and any subobjects
-		// 		* expr = expr - Performs a comparison (like JS's ==). When comparing to
-		// 		a string, the comparison string may contain wildcards * (matches any number of
-		// 		characters) and ? (matches any single character).
-		// 		* expr ~ expr - Performs a string comparison with case insensitivity.
-		//		* ..[?expression] - This will perform a deep search filter operation on all the objects and
-		// 		subobjects of the current data. Rather than only searching an array, this will search
-		// 		property values, arrays, and their children.
-		//		* $1,$2,$3, etc. - These are references to extra parameters passed to the query
+		//		- [expr,expr] - This a union operator, returning an array of all the property/index values from
+		//		the evaluation of the comma delimited expressions.
+		//		- .* or [*] - This returns the values of all the properties of the current object.
+		//		- $ - This is the root object, If a JSONQuery expression does not being with a $,
+		//		it will be auto-inserted at the beginning.
+		//		- @ - This is the current object in filter, sort, and map expressions. This is generally
+		//		not necessary, names are auto-converted to property references of the current object
+		//		in expressions.
+		//		- ..property - Performs a recursive search for the given property name, returning
+		//		an array of all values with such a property name in the current object and any subobjects
+		//		- expr = expr - Performs a comparison (like JS's ==). When comparing to
+		//		a string, the comparison string may contain wildcards * (matches any number of
+		//		characters) and ? (matches any single character).
+		//		- expr ~ expr - Performs a string comparison with case insensitivity.
+		//		- ..[?expression] - This will perform a deep search filter operation on all the objects and
+		//		subobjects of the current data. Rather than only searching an array, this will search
+		//		property values, arrays, and their children.
+		//		- $1,$2,$3, etc. - These are references to extra parameters passed to the query
 		//		function or the evaluator function.
-		//		* +, -, /, *, &, |, %, (, ), <, >, <=, >=, != - These operators behave just as they do
-		// 		in JavaScript.
-		//
-		//
+		//		- +, -, /, *, &, |, %, (, ), <, >, <=, >=, != - These operators behave just as they do
+		//		in JavaScript.
 		//
 		// 	|	dojox.json.query(queryString,object)
-		// 		and
+		//		and
 		// 	|	dojox.json.query(queryString)(object)
-		// 		always return identical results. The first one immediately evaluates, the second one returns a
-		// 		function that then evaluates the object.
+		//		always return identical results. The first one immediately evaluates, the second one returns a
+		//		function that then evaluates the object.
 		//
-		// 	example:
+		// example:
 		// 	|	dojox.json.query("foo",{foo:"bar"})
-		// 		This will return "bar".
+		//		This will return "bar".
 		//
-		//	example:
+		// example:
 		//	|	evaluator = dojox.json.query("?foo='bar'&rating>3");
 		//		This creates a function that finds all the objects in an array with a property
 		//		foo that is equals to "bar" and with a rating property with a value greater
 		//		than 3.
 		//	|	evaluator([{foo:"bar",rating:4},{foo:"baz",rating:2}])
-		// 		This returns:
+		//		This returns:
 		// 	|	{foo:"bar",rating:4}
 		//
-		//	example:
+		// example:
 		// 	|	evaluator = dojox.json.query("$[?price<15.00][\rating][0:10]");
 		// 	 	This finds objects in array with a price less than 15.00 and sorts then
-		// 		by rating, highest rated first, and returns the first ten items in from this
-		// 		filtered and sorted list.
+		//		by rating, highest rated first, and returns the first ten items in from this
+		//		filtered and sorted list.
 		var depth = 0;
 		var str = [];
 		query = query.replace(/"(\\.|[^"\\])*"|'(\\.|[^'\\])*'|[\[\]]/g,function(t){
diff --git a/dojox/json/ref.js b/dojox/json/ref.js
index 4d87b1f..2a70a0d 100644
--- a/dojox/json/ref.js
+++ b/dojox/json/ref.js
@@ -1,49 +1,55 @@
-define(["dojo/_base/kernel", "dojox", "dojo/date/stamp", "dojo/_base/array", "dojo/_base/json"], function(dojo, dojox){
+define([
+	"dojo/_base/array",
+	"dojo/_base/json",
+	"dojo/_base/kernel", 
+	"dojo/_base/lang",
+	"dojo/date/stamp",
+	"dojox"
+],
+function(array, djson, dojo, lang, stamp, dojox){
 
-dojo.getObject("json", true, dojox);
+lang.getObject("json", true, dojox);
 
 return dojox.json.ref = {
 	// summary:
-	// 		Adds advanced JSON {de}serialization capabilities to the base json library.
-	// 		This enhances the capabilities of dojo.toJson and dojo.fromJson,
-	// 		adding referencing support, date handling, and other extra format handling.
-	// 		On parsing, references are resolved. When references are made to
-	// 		ids/objects that have been loaded yet, the loader function will be set to
-	// 		_loadObject to denote a lazy loading (not loaded yet) object.
+	//		Adds advanced JSON {de}serialization capabilities to the base json library.
+	//		This enhances the capabilities of dojo.toJson and dojo.fromJson,
+	//		adding referencing support, date handling, and other extra format handling.
+	//		On parsing, references are resolved. When references are made to
+	//		ids/objects that have been loaded yet, the loader function will be set to
+	//		_loadObject to denote a lazy loading (not loaded yet) object.
 
 
-	resolveJson: function(/*Object*/ root,/*Object?*/ args){
+	resolveJson: function(/*Object*/ root, /*Object?*/ args){
 		// summary:
-		// 		Indexes and resolves references in the JSON object.
+		//		Indexes and resolves references in the JSON object.
 		// description:
-		// 		A JSON Schema object that can be used to advise the handling of the JSON (defining ids, date properties, urls, etc)
-		//
+		//		A JSON Schema object that can be used to advise the handling of the JSON (defining ids, date properties, urls, etc)
 		// root:
 		//		The root object of the object graph to be processed
 		// args:
 		//		Object with additional arguments:
 		//
-		// The *index* parameter.
-		//		This is the index object (map) to use to store an index of all the objects.
-		// 		If you are using inter-message referencing, you must provide the same object for each call.
-		// The *defaultId* parameter.
-		//		This is the default id to use for the root object (if it doesn't define it's own id)
-		//	The *idPrefix* parameter.
-		//		This the prefix to use for the ids as they enter the index. This allows multiple tables
-		// 		to use ids (that might otherwise collide) that enter the same global index.
-		// 		idPrefix should be in the form "/Service/".  For example,
-		//		if the idPrefix is "/Table/", and object is encountered {id:"4",...}, this would go in the
-		//		index as "/Table/4".
-		//	The *idAttribute* parameter.
-		//		This indicates what property is the identity property. This defaults to "id"
-		//	The *assignAbsoluteIds* parameter.
-		//		This indicates that the resolveJson should assign absolute ids (__id) as the objects are being parsed.
-		//
-		// The *schemas* parameter
-		//		This provides a map of schemas, from which prototypes can be retrieved
-		// The *loader* parameter
-		//		This is a function that is called added to the reference objects that can't be resolved (lazy objects)
-		// return:
+		//		- The *index* parameter:
+		//			This is the index object (map) to use to store an index of all the objects.
+		//			If you are using inter-message referencing, you must provide the same object for each call.
+		//		- The *defaultId* parameter:
+		//			This is the default id to use for the root object (if it doesn't define it's own id)
+		//		- The *idPrefix* parameter:
+		//			This the prefix to use for the ids as they enter the index. This allows multiple tables
+		//			to use ids (that might otherwise collide) that enter the same global index.
+		//			idPrefix should be in the form "/Service/".  For example,
+		//			if the idPrefix is "/Table/", and object is encountered {id:"4",...}, this would go in the
+		//			index as "/Table/4".
+		//		- The *idAttribute* parameter:
+		//			This indicates what property is the identity property. This defaults to "id"
+		//		- The *assignAbsoluteIds* parameter:
+		//			This indicates that the resolveJson should assign absolute ids (__id) as the objects are being parsed.
+		//		- The *schemas* parameter:
+		//			This provides a map of schemas, from which prototypes can be retrieved
+		//		- The *loader* parameter:
+		//			This is a function that is called added to the reference objects that can't be resolved (lazy objects)
+		// returns:
 		//		An object, the result of the processing
 		args = args || {};
 		var idAttribute = args.idAttribute || 'id';
@@ -98,7 +104,7 @@ return dojox.json.ref = {
 					for(i in it){
 						var propertyDefinition = properties[i];
 						if(propertyDefinition && propertyDefinition.format == 'date-time' && typeof it[i] == 'string'){
-							it[i] = dojo.date.stamp.fromISOString(it[i]);
+							it[i] = stamp.fromISOString(it[i]);
 						}
 					}
 				}
@@ -212,14 +218,13 @@ return dojox.json.ref = {
 
 	fromJson: function(/*String*/ str,/*Object?*/ args){
 	// summary:
-	// 		evaluates the passed string-form of a JSON object.
-	//
+	//		evaluates the passed string-form of a JSON object.
 	// str:
 	//		a string literal of a JSON item, for instance:
-	//			'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'
-	// args: See resolveJson
-	//
-	// return:
+	// |	'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'
+	// args:
+	//		See resolveJson
+	// returns:
 	//		An object, the result of the evaluation
 		function ref(target){ // support call styles references as well
 			var refObject = {};
@@ -241,20 +246,17 @@ return dojox.json.ref = {
 		// summary:
 		//		Create a JSON serialization of an object.
 		//		This has support for referencing, including circular references, duplicate references, and out-of-message references
-		// 		id and path-based referencing is supported as well and is based on http://www.json.com/2007/10/19/json-referencing-proposal-and-library/.
-		//
+		//		id and path-based referencing is supported as well and is based on http://www.json.com/2007/10/19/json-referencing-proposal-and-library/.
 		// it:
 		//		an object to be serialized.
-		//
 		// prettyPrint:
 		//		if true, we indent objects and arrays to make the output prettier.
 		//		The variable dojo.toJsonIndentStr is used as the indent string
 		//		-- to use something other than the default (tab),
 		//		change that variable before calling dojo.toJson().
-		//
-		// idPrefix: The prefix that has been used for the absolute ids
-		//
-		// return:
+		// idPrefix:
+		//		The prefix that has been used for the absolute ids
+		// returns:
 		//		a String representing the serialized version of the passed object.
 		var useRefs = this._useRefs;
 		var addProp = this._addProp;
@@ -266,7 +268,7 @@ return dojox.json.ref = {
 			if(typeof it == 'object' && it){
 				var value;
 				if(it instanceof Date){ // properly serialize dates
-					return '"' + dojo.date.stamp.toISOString(it,{zulu:true}) + '"';
+					return '"' + stamp.toISOString(it,{zulu:true}) + '"';
 				}
 				var id = it.__id;
 				if(id){ // we found an identifiable object, we will just serialize a reference to it... unless it is the root
@@ -285,7 +287,7 @@ return dojox.json.ref = {
 						}
 						var refObject = {};
 						refObject[refAttribute] = ref;
-						return serialize(refObject,'#');
+						return djson.toJson(refObject, prettyPrint);
 					}
 					path = id;
 				}else{
@@ -294,12 +296,12 @@ return dojox.json.ref = {
 				}
 				paths[path] = it;// save it here so they can be deleted at the end
 				_indentStr = _indentStr || "";
-				var nextIndent = prettyPrint ? _indentStr + dojo.toJsonIndentStr : "";
+				var nextIndent = prettyPrint ? _indentStr + djson.toJsonIndentStr : "";
 				var newLine = prettyPrint ? "\n" : "";
 				var sep = prettyPrint ? " " : "";
 	
 				if(it instanceof Array){
-					var res = dojo.map(it, function(obj,i){
+					var res = array.map(it, function(obj,i){
 						var val = serialize(obj, addProp(path, i), nextIndent);
 						if(typeof val != "string"){
 							val = "undefined";
@@ -317,7 +319,7 @@ return dojox.json.ref = {
 							keyStr = '"' + i + '"';
 						}else if(typeof i == "string" && (i.charAt(0) != '_' || i.charAt(1) != '_')){
 							// we don't serialize our internal properties __id and __clientId
-							keyStr = dojo._escapeString(i);
+							keyStr = djson._escapeString(i);
 						}else{
 							// skip non-string or number keys
 							continue;
@@ -335,7 +337,7 @@ return dojox.json.ref = {
 				return it.toString();
 			}
 	
-			return dojo.toJson(it); // use the default serializer for primitives
+			return djson.toJson(it); // use the default serializer for primitives
 		}
 		var json = serialize(it,'#','');
 		if(!indexSubObjects){
@@ -348,10 +350,10 @@ return dojox.json.ref = {
 	_addProp: function(id, prop){
 		return id + (id.match(/#/) ? id.length == 1 ? '' : '.' : '#') + prop;
 	},
-	//	refAttribute: String
+	// refAttribute: String
 	//		This indicates what property is the reference property. This acts like the idAttribute
-	// 		except that this is used to indicate the current object is a reference or only partially
-	// 		loaded. This defaults to "$ref".
+	//		except that this is used to indicate the current object is a reference or only partially
+	//		loaded. This defaults to "$ref".
 	refAttribute: "$ref",
 	_useRefs: false,
 	serializeFunctions: false
diff --git a/dojox/json/schema.js b/dojox/json/schema.js
index 10c69b6..a98352b 100644
--- a/dojox/json/schema.js
+++ b/dojox/json/schema.js
@@ -5,48 +5,49 @@ dojo.getObject("json.schema", true, dojox);
 
 dojox.json.schema.validate = function(/*Any*/instance,/*Object*/schema){
 	// summary:
-	//  	To use the validator call this with an instance object and an optional schema object.
-	// 		If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating),
-	// 		that schema will be used to validate and the schema parameter is not necessary (if both exist,
-	// 		both validations will occur).
-	//	instance:
+	//		To use the validator call this with an instance object and an optional schema object.
+	//		If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating),
+	//		that schema will be used to validate and the schema parameter is not necessary (if both exist,
+	//		both validations will occur).
+	// instance:
 	//		The instance value/object to validate
 	// schema:
 	//		The schema to use to validate
 	// description:
-	// 		The validate method will return an object with two properties:
-	// 			valid: A boolean indicating if the instance is valid by the schema
-	// 			errors: An array of validation errors. If there are no errors, then an
-	// 					empty list will be returned. A validation error will have two properties:
-	// 						property: which indicates which property had the error
-	// 						message: which indicates what the error was
+	//		The validate method will return an object with two properties:
 	//
+	//		- valid: A boolean indicating if the instance is valid by the schema
+	//		- errors: An array of validation errors. If there are no errors, then an
+	//		  empty list will be returned. A validation error will have two properties:
+	//		- property: which indicates which property had the error
+	//		- message: which indicates what the error was
+
 	return this._validate(instance,schema,false);
 };
 dojox.json.schema.checkPropertyChange = function(/*Any*/value,/*Object*/schema, /*String*/ property){
 	// summary:
-	// 		The checkPropertyChange method will check to see if an value can legally be in property with the given schema
-	// 		This is slightly different than the validate method in that it will fail if the schema is readonly and it will
-	// 		not check for self-validation, it is assumed that the passed in value is already internally valid.
-	// 		The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for
-	// 		information.
-	//	value:
+	//		The checkPropertyChange method will check to see if an value can legally be in property with the given schema
+	//		This is slightly different than the validate method in that it will fail if the schema is readonly and it will
+	//		not check for self-validation, it is assumed that the passed in value is already internally valid.
+	//		The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for
+	//		information.
+	// value:
 	//		The new instance value/object to check
 	// schema:
 	//		The schema to use to validate
-	// return:
-	// 		see dojox.validate.jsonSchema.validate
-	//
+	// returns:
+	//		see dojox.validate.jsonSchema.validate
+
 	return this._validate(value,schema, property || "property");
 };
 dojox.json.schema.mustBeValid = function(result){
-	//	summary:
+	// summary:
 	//		This checks to ensure that the result is valid and will throw an appropriate error message if it is not
 	// result: the result returned from checkPropertyChange or validate
 	if(!result.valid){
 		throw new TypeError(dojo.map(result.errors,function(error){return "for property " + error.property + ': ' + error.message;}).join(", "));
 	}
-}
+};
 dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolean*/ _changing){
 	
 	var errors = [];
diff --git a/dojox/json/tests/query.js b/dojox/json/tests/query.js
index 7316ca2..db212e0 100644
--- a/dojox/json/tests/query.js
+++ b/dojox/json/tests/query.js
@@ -3,7 +3,7 @@ dojo.require("dojox.json.query");
 
 
 dojox.json.tests.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
 };
diff --git a/dojox/json/tests/ref.js b/dojox/json/tests/ref.js
index 03c6436..bb5614e 100644
--- a/dojox/json/tests/ref.js
+++ b/dojox/json/tests/ref.js
@@ -26,6 +26,17 @@ doh.register("dojox.json.tests.ref", [
 		t.assertEqual(mirrorObj.b.h, mirrorObj.a);
 		t.assertEqual(mirrorObj.array[0], mirrorObj.array[1]);
 	},
+	function toJsonGeneratedIds(t){ 
+		// Make obj reference b twice to ensure that there is at least one $ref 
+		// from obj to b. 
+	 	var b = {__id: 'bId', x: 2}, 
+	 	obj = {a: 1, b1: b, b2: b}; 
+	 	dojox.json.ref.toJson(obj); 
+	 	t.f(obj.hasOwnProperty('__id'), 'obj has __id property.'); 
+	 	t.t(obj.b1 === b, 'obj.b1 !== b'); 
+	 	t.t(obj.b2 === b, 'obj.b2 !== b'); 
+	 	t.is('bId', b.__id, 'b.__id'); 
+	}, 
 	function usingSchemas(t) {
 		var testStr = '{id:"/dog/1",eats:{$ref:"/cat/2"},aTime:"2008-11-07T20:26:17-07:00"}';
 		var schemas = {
diff --git a/dojox/jsonPath.js b/dojox/jsonPath.js
index e18b23d..8956807 100644
--- a/dojox/jsonPath.js
+++ b/dojox/jsonPath.js
@@ -1,2 +1,9 @@
-dojo.provide("dojox.jsonPath");
-dojo.require("dojox.jsonPath.query");
+define(['./jsonPath/query'],function(){
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/jsonPath modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
+});
diff --git a/dojox/jsonPath/query.js b/dojox/jsonPath/query.js
index d9eadff..c893bf1 100644
--- a/dojox/jsonPath/query.js
+++ b/dojox/jsonPath/query.js
@@ -1,26 +1,31 @@
 dojo.provide("dojox.jsonPath.query");
 
-dojox.jsonPath.query = function(/*Object*/obj, /*String*/expr, /*Object*/arg){
-	// summaRy
-	// 	Perform jsonPath query `expr` on javascript object or json string `obj`
-	//	obj - object || json string to perform query on
-	//	expr - jsonPath expression (string) to be evaluated
-	//	arg - {}special arugments.
-	//		resultType: "VALUE"||"BOTH"||"PATH"} (defaults to value)
-	//		evalType: "RESULT"||"ITEM"} (defaults to ?)
+dojox.jsonPath.query = function(/*Object*/ obj, /*String*/ expr, /*Object*/ arg){
+	// summary:
+	//		Perform jsonPath query `expr` on javascript object or json string `obj`
+	// obj:
+	//		object || json string to perform query on
+	// expr:
+	//		jsonPath expression (string) to be evaluated
+	// arg:
+	//		{} special arguments.
+	//
+	//		- resultType: "VALUE"||"BOTH"||"PATH"} (defaults to value)
+	//		- evalType: "RESULT"||"ITEM"} (defaults to ?)
 
 	var re = dojox.jsonPath._regularExpressions;
 	if (!arg){arg={};}
 
 	var strs = [];
 	function _str(i){ return strs[i];}
+	var _strName = _str.name;
 	var acc;
 	if (arg.resultType == "PATH" && arg.evalType == "RESULT") throw Error("RESULT based evaluation not supported with PATH based results");
 	var P = {
 		resultType: arg.resultType || "VALUE",
 		normalize: function(expr){
 			var subx = [];
-			expr = expr.replace(/'([^']|'')*'/g, function(t){return "_str("+(strs.push(eval(t))-1)+")";});
+			expr = expr.replace(/'([^']|'')*'/g, function(t){return _strName + "("+(strs.push(eval(t))-1)+")";});
 			var ll = -1;
 			while(ll!=subx.length){
 				ll=subx.length;//TODO: Do expression syntax checking
@@ -143,9 +148,9 @@ dojox.jsonPath.query = function(/*Object*/obj, /*String*/expr, /*Object*/arg){
 						f(m);
 			}
 		},
-		eval: function(x, _v){
-			try { return $ && _v && eval(x.replace(/@/g,'_v')); }
-			catch(e){ throw new SyntaxError("jsonPath: " + e.message + ": " + x.replace(/@/g, "_v").replace(/\^/g, "_a")); }
+		eval: function(x, v){
+			try { return $ && v && eval(x.replace(/@/g,'v')); }
+			catch(e){ throw new SyntaxError("jsonPath: " + e.message + ": " + x.replace(/@/g, "v").replace(/\^/g, "_a")); }
 		}
 	};
 
diff --git a/dojox/jsonPath/tests/jsonPath.js b/dojox/jsonPath/tests/jsonPath.js
index dfdabdd..d27958a 100644
--- a/dojox/jsonPath/tests/jsonPath.js
+++ b/dojox/jsonPath/tests/jsonPath.js
@@ -3,10 +3,10 @@ dojo.require("dojox.jsonPath");
 
 
 dojox.jsonPath.tests.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
-}
+};
 
 dojox.jsonPath.tests.testData= {
 	store: {
diff --git a/dojox/lang/docs.js b/dojox/lang/docs.js
index 8673581..85ce747 100644
--- a/dojox/lang/docs.js
+++ b/dojox/lang/docs.js
@@ -135,10 +135,9 @@ dojo.provide("dojox.lang.docs");
 	dojox.lang.docs.init = function(/*Boolean*/async){
 		// summary:
 		//		Loads the documentation and applies it to the previously defined classes
-		// 		and any future defined classes
-		//
+		//		and any future defined classes
 		// async:
-		// 		 If true, the documentation will be loaded asynchronously
+		//		 If true, the documentation will be loaded asynchronously
 		function loadFullDocs(){
 			dojo.require = defaultRequire;
 			requiredModules = null;
diff --git a/dojox/lang/functional/array.js b/dojox/lang/functional/array.js
index 4d49b89..2ef9513 100755
--- a/dojox/lang/functional/array.js
+++ b/dojox/lang/functional/array.js
@@ -1,5 +1,5 @@
-define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "./lambda"], 
-	function(dojo, lang, arr, win, df){
+define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "./lambda"],
+	function(kernel, lang, arr, df){
 
 // This module adds high-level functions and related constructs:
 //	- array-processing functions similar to standard JS functions
@@ -16,17 +16,15 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/
 
 	var empty = {};
 
-/*=====
-	var df = dojox.lang.functional;
- =====*/
 	lang.mixin(df, {
 		// JS 1.6 standard array functions, which can take a lambda as a parameter.
 		// Consider using dojo._base.array functions, if you don't need the lambda support.
 		filter: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: creates a new array with all elements that pass the test
-			//	implemented by the provided function.
+			// summary:
+			//		creates a new array with all elements that pass the test
+			//		implemented by the provided function.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var t = [], v, i, n;
 			if(lang.isArray(a)){
 				// array
@@ -52,9 +50,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/
 			return t;	// Array
 		},
 		forEach: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: executes a provided function once per array element.
+			// summary:
+			//		executes a provided function once per array element.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var i, n;
 			if(lang.isArray(a)){
 				// array
@@ -73,10 +72,11 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/
 			return o;	// Object
 		},
 		map: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: creates a new array with the results of calling
-			//	a provided function on every element in this array.
+			// summary:
+			//		creates a new array with the results of calling
+			//		a provided function on every element in this array.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var t, n, i;
 			if(lang.isArray(a)){
 				// array
@@ -98,10 +98,11 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/
 			return t;	// Array
 		},
 		every: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: tests whether all elements in the array pass the test
-			//	implemented by the provided function.
+			// summary:
+			//		tests whether all elements in the array pass the test
+			//		implemented by the provided function.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var i, n;
 			if(lang.isArray(a)){
 				// array
@@ -130,10 +131,11 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/
 			return true;	// Boolean
 		},
 		some: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: tests whether some element in the array passes the test
-			//	implemented by the provided function.
+			// summary:
+			//		tests whether some element in the array passes the test
+			//		implemented by the provided function.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var i, n;
 			if(lang.isArray(a)){
 				// array
diff --git a/dojox/lang/functional/binrec.js b/dojox/lang/functional/binrec.js
index e679c1f..6bf3c1a 100644
--- a/dojox/lang/functional/binrec.js
+++ b/dojox/lang/functional/binrec.js
@@ -6,7 +6,7 @@ dojo.require("dojox.lang.functional.util");
 // This module provides recursion combinators:
 //	- a binary recursion combinator.
 
-// Acknoledgements:
+// Acknowledgements:
 //	- recursion combinators are inspired by Manfred von Thun's article
 //		"Recursion Theory and Joy"
 //		(http://www.latrobe.edu.au/philosophy/phimvt/joy/j05cmp.html)
diff --git a/dojox/lang/functional/curry.js b/dojox/lang/functional/curry.js
index 56aff3b..c2f997c 100755
--- a/dojox/lang/functional/curry.js
+++ b/dojox/lang/functional/curry.js
@@ -6,7 +6,7 @@ dojo.require("dojox.lang.functional.lambda");
 //	- currying and partial functions
 //	- argument pre-processing: mixer and flip
 
-// Acknoledgements:
+// Acknowledgements:
 //	- partial() is based on work by Oliver Steele
 //		(http://osteele.com/sources/javascript/functional/functional.js)
 //		which was published under MIT License
@@ -30,20 +30,23 @@ dojo.require("dojox.lang.functional.lambda");
 	dojo.mixin(df, {
 		// currying and partial functions
 		curry: function(/*Function|String|Array*/ f, /*Number?*/ arity){
-			// summary: curries a function until the arity is satisfied, at
-			//	which point it returns the calculated value.
+			// summary:
+			//		curries a function until the arity is satisfied, at
+			//		which point it returns the calculated value.
 			f = df.lambda(f);
 			arity = typeof arity == "number" ? arity : f.length;
 			return currying({func: f, arity: arity, args: []});	// Function
 		},
 		arg: {},	// marker for missing arguments
 		partial: function(/*Function|String|Array*/ f){
-			// summary: creates a function where some arguments are bound, and
-			//	some arguments (marked as dojox.lang.functional.arg) are will be
-			//	accepted by the final function in the order they are encountered.
-			// description: This method is used to produce partially bound
-			//	functions. If you want to change the order of arguments, use
-			//	dojox.lang.functional.mixer() or dojox.lang.functional.flip().
+			// summary:
+			//		creates a function where some arguments are bound, and
+			//		some arguments (marked as dojox.lang.functional.arg) are will be
+			//		accepted by the final function in the order they are encountered.
+			// description:
+			//		This method is used to produce partially bound
+			//		functions. If you want to change the order of arguments, use
+			//		dojox.lang.functional.mixer() or dojox.lang.functional.flip().
 			var a = arguments, l = a.length, args = new Array(l - 1), p = [], i = 1, t;
 			f = df.lambda(f);
 			for(; i < l; ++i){
@@ -64,9 +67,10 @@ dojo.require("dojox.lang.functional.lambda");
 		},
 		// argument pre-processing
 		mixer: function(/*Function|String|Array*/ f, /*Array*/ mix){
-			// summary: changes the order of arguments using an array of
-			//	numbers mix --- i-th argument comes from mix[i]-th place
-			//	of supplied arguments.
+			// summary:
+			//		changes the order of arguments using an array of
+			//		numbers mix --- i-th argument comes from mix[i]-th place
+			//		of supplied arguments.
 			f = df.lambda(f);
 			return function(){	// Function
 				var t = new Array(mix.length), i = 0, l = mix.length;
@@ -77,8 +81,9 @@ dojo.require("dojox.lang.functional.lambda");
 			};
 		},
 		flip: function(/*Function|String|Array*/ f){
-			// summary: changes the order of arguments by reversing their
-			//	order.
+			// summary:
+			//		changes the order of arguments by reversing their
+			//		order.
 			f = df.lambda(f);
 			return function(){	// Function
 				// reverse arguments
diff --git a/dojox/lang/functional/fold.js b/dojox/lang/functional/fold.js
index 32887ff..36d9278 100755
--- a/dojox/lang/functional/fold.js
+++ b/dojox/lang/functional/fold.js
@@ -1,5 +1,5 @@
-define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "./lambda"],
-	function(lang, arr, win, df){
+define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/kernel", "./lambda"],
+	function(lang, arr, kernel, df){
 
 // This module adds high-level functions and related constructs:
 //	- "fold" family of functions
@@ -19,17 +19,15 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "./lambda"],
 
 	var empty = {};
 
-/*=====
-	var df = dojox.lang.functional;
- =====*/
 	lang.mixin(df, {
 		// classic reduce-class functions
 		foldl: function(/*Array|String|Object*/ a, /*Function*/ f, /*Object*/ z, /*Object?*/ o){
-			// summary: repeatedly applies a binary function to an array from left
-			//	to right using a seed value as a starting point; returns the final
-			//	value.
+			// summary:
+			//		repeatedly applies a binary function to an array from left
+			//		to right using a seed value as a starting point; returns the final
+			//		value.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var i, n;
 			if(lang.isArray(a)){
 				// array
@@ -48,10 +46,11 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "./lambda"],
 			return z;	// Object
 		},
 		foldl1: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: repeatedly applies a binary function to an array from left
-			//	to right; returns the final value.
+			// summary:
+			//		repeatedly applies a binary function to an array from left
+			//		to right; returns the final value.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var z, i, n;
 			if(lang.isArray(a)){
 				// array
@@ -80,39 +79,44 @@ define(["dojo/_base/lang", "dojo/_base/array", "dojo/_base/window", "./lambda"],
 			return z;	// Object
 		},
 		foldr: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
-			// summary: repeatedly applies a binary function to an array from right
-			//	to left using a seed value as a starting point; returns the final
-			//	value.
+			// summary:
+			//		repeatedly applies a binary function to an array from right
+			//		to left using a seed value as a starting point; returns the final
+			//		value.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			for(var i = a.length; i > 0; --i, z = f.call(o, z, a[i], i, a));
 			return z;	// Object
 		},
 		foldr1: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: repeatedly applies a binary function to an array from right
-			//	to left; returns the final value.
+			// summary:
+			//		repeatedly applies a binary function to an array from right
+			//		to left; returns the final value.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var n = a.length, z = a[n - 1], i = n - 1;
 			for(; i > 0; --i, z = f.call(o, z, a[i], i, a));
 			return z;	// Object
 		},
 		// JS 1.8 standard array functions, which can take a lambda as a parameter.
 		reduce: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ z){
-			// summary: apply a function simultaneously against two values of the array
-			//	(from left-to-right) as to reduce it to a single value.
+			// summary:
+			//		apply a function simultaneously against two values of the array
+			//		(from left-to-right) as to reduce it to a single value.
 			return arguments.length < 3 ? df.foldl1(a, f) : df.foldl(a, f, z);	// Object
 		},
 		reduceRight: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ z){
-			// summary: apply a function simultaneously against two values of the array
-			//	(from right-to-left) as to reduce it to a single value.
+			// summary:
+			//		apply a function simultaneously against two values of the array
+			//		(from right-to-left) as to reduce it to a single value.
 			return arguments.length < 3 ? df.foldr1(a, f) : df.foldr(a, f, z);	// Object
 		},
 		// the fold's counterpart: unfold
 		unfold: function(/*Function|String|Array*/ pr, /*Function|String|Array*/ f,
 						/*Function|String|Array*/ g, /*Object*/ z, /*Object?*/ o){
-			// summary: builds an array by unfolding a value
-			o = o || win.global; f = df.lambda(f); g = df.lambda(g); pr = df.lambda(pr);
+			// summary:
+			//		builds an array by unfolding a value
+			o = o || kernel.global; f = df.lambda(f); g = df.lambda(g); pr = df.lambda(pr);
 			var t = [];
 			for(; !pr.call(o, z); t.push(f.call(o, z)), z = g.call(o, z));
 			return t;	// Array
diff --git a/dojox/lang/functional/lambda.js b/dojox/lang/functional/lambda.js
index deeb064..9c50913 100755
--- a/dojox/lang/functional/lambda.js
+++ b/dojox/lang/functional/lambda.js
@@ -1,10 +1,10 @@
-define(["../..", "dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array"], function(dojox, dojo, lang, arr){
+define(["../..", "dojo/_base/lang", "dojo/_base/array"], function(dojox, lang, arr){
 	var df = lang.getObject("lang.functional", true, dojox);
 
 // This module adds high-level functions and related constructs:
 //	- anonymous functions built from the string
 
-// Acknoledgements:
+// Acknowledgements:
 //	- lambda() is based on work by Oliver Steele
 //		(http://osteele.com/sources/javascript/functional/functional.js)
 //		which was published under MIT License
@@ -35,7 +35,7 @@ define(["../..", "dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array"], fu
 			while(sects.length){
 				s = sects.pop();
 				args = sects.pop().split(/\s*,\s*|\s+/m);
-				if(sects.length){ sects.push("(function(" + args + "){return (" + s + ")})"); }
+				if(sects.length){ sects.push("(function(" + args.join(", ") + "){ return (" + s + "); })"); }
 			}
 		}else if(s.match(/\b_\b/)){
 			args = ["_"];
@@ -58,7 +58,7 @@ define(["../..", "dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array"], fu
 					replace(/(?:\b[A-Z]|\.[a-zA-Z_$])[a-zA-Z_$\d]*|[a-zA-Z_$][a-zA-Z_$\d]*:|this|true|false|null|undefined|typeof|instanceof|in|delete|new|void|arguments|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|escape|eval|isFinite|isNaN|parseFloat|parseInt|unescape|dojo|dijit|dojox|window|document|'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"/g, "").
 					match(/([a-z_$][a-z_$\d]*)/gi) || [], t = {};
 				arr.forEach(vars, function(v){
-					if(!(v in t)){
+					if(!t.hasOwnProperty(v)){
 						args.push(v);
 						t[v] = 1;
 					}
@@ -103,8 +103,8 @@ define(["../..", "dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array"], fu
 			//		built from the snippet. It is meant to be evaled in the
 			//		proper context, so local variables can be pulled from the
 			//		environment.
-			s = lambda(s);
-			return "function(" + s.args.join(",") + "){return (" + s.body + ");}";	// String
+			var l = lambda(s);
+			return "function(" + l.args.join(",") + "){return (" + l.body + ");}";	// String
 		},
 		lambda: function(/*Function|String|Array*/ s){
 			// summary:
@@ -117,9 +117,9 @@ define(["../..", "dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array"], fu
 			//		a function object.
 			if(typeof s == "function"){ return s; }
 			if(s instanceof Array){ return compose(s); }
-			if(s in lcache){ return lcache[s]; }
-			s = lambda(s);
-			return lcache[s] = new Function(s.args, "return (" + s.body + ");");	// Function
+			if(lcache.hasOwnProperty(s)){ return lcache[s]; }
+			var l = lambda(s);
+			return lcache[s] = new Function(l.args, "return (" + l.body + ");");	// Function
 		},
 		clearLambdaCache: function(){
 			// summary:
diff --git a/dojox/lang/functional/linrec.js b/dojox/lang/functional/linrec.js
index 410184a..0600f5b 100644
--- a/dojox/lang/functional/linrec.js
+++ b/dojox/lang/functional/linrec.js
@@ -6,7 +6,7 @@ dojo.require("dojox.lang.functional.util");
 // This module provides recursion combinators:
 //	- a linear recursion combinator.
 
-// Acknoledgements:
+// Acknowledgements:
 //	- recursion combinators are inspired by Manfred von Thun's article
 //		"Recursion Theory and Joy"
 //		(http://www.latrobe.edu.au/philosophy/phimvt/joy/j05cmp.html)
diff --git a/dojox/lang/functional/listcomp.js b/dojox/lang/functional/listcomp.js
index 908d739..21f72c4 100755
--- a/dojox/lang/functional/listcomp.js
+++ b/dojox/lang/functional/listcomp.js
@@ -26,24 +26,29 @@ dojo.provide("dojox.lang.functional.listcomp");
 
 	dojo.mixin(dojox.lang.functional, {
 		buildListcomp: function(/*String*/ s){
-			// summary: builds a function from a text snippet, which represents a valid
-			//	JS 1.7 list comprehension, returns a string, which represents the function.
-			// description: This method returns a textual representation of a function
-			//	built from the list comprehension text snippet (conformant to JS 1.7).
-			//	It is meant to be evaled in the proper context, so local variable can be
-			//	pulled from the environment.
+			// summary:
+			//		builds a function from a text snippet, which represents a valid
+			//		JS 1.7 list comprehension, returns a string, which represents the function.
+			// description:
+			//		This method returns a textual representation of a function
+			//		built from the list comprehension text snippet (conformant to JS 1.7).
+			//		It is meant to be evaled in the proper context, so local variable can be
+			//		pulled from the environment.
 			return "function(){" + listcomp(s) + "}";	// String
 		},
 		compileListcomp: function(/*String*/ s){
-			// summary: builds a function from a text snippet, which represents a valid
-			//	JS 1.7 list comprehension, returns a function object.
-			// description: This method returns a function built from the list
-			//	comprehension text snippet (conformant to JS 1.7). It is meant to be
-			//	reused several times.
+			// summary:
+			//		builds a function from a text snippet, which represents a valid
+			//		JS 1.7 list comprehension, returns a function object.
+			// description:
+			//		This method returns a function built from the list
+			//		comprehension text snippet (conformant to JS 1.7). It is meant to be
+			//		reused several times.
 			return new Function([], listcomp(s));	// Function
 		},
 		listcomp: function(/*String*/ s){
-			// summary: executes the list comprehension building an array.
+			// summary:
+			//		executes the list comprehension building an array.
 			return (new Function([], listcomp(s)))();	// Array
 		}
 	});
diff --git a/dojox/lang/functional/multirec.js b/dojox/lang/functional/multirec.js
index e3f2566..2ca44a8 100644
--- a/dojox/lang/functional/multirec.js
+++ b/dojox/lang/functional/multirec.js
@@ -6,7 +6,7 @@ dojo.require("dojox.lang.functional.util");
 // This module provides recursion combinators:
 //	- a multi-way recursion combinator.
 
-// Acknoledgements:
+// Acknowledgements:
 //	- recursion combinators are inspired by Manfred von Thun's article
 //		"Recursion Theory and Joy"
 //		(http://www.latrobe.edu.au/philosophy/phimvt/joy/j05cmp.html)
diff --git a/dojox/lang/functional/numrec.js b/dojox/lang/functional/numrec.js
index a0092ba..18949ad 100644
--- a/dojox/lang/functional/numrec.js
+++ b/dojox/lang/functional/numrec.js
@@ -6,7 +6,7 @@ dojo.require("dojox.lang.functional.util");
 // This module provides recursion combinators:
 //	- a simplified numeric linear recursion combinator.
 
-// Acknoledgements:
+// Acknowledgements:
 //	- recursion combinators are inspired by Manfred von Thun's article
 //		"Recursion Theory and Joy"
 //		(http://www.latrobe.edu.au/philosophy/phimvt/joy/j05cmp.html)
diff --git a/dojox/lang/functional/object.js b/dojox/lang/functional/object.js
index b186b5b..0c1cf25 100755
--- a/dojox/lang/functional/object.js
+++ b/dojox/lang/functional/object.js
@@ -1,4 +1,4 @@
-define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/window", "./lambda"], function(dojo, lang, win, df){
+define(["dojo/_base/kernel", "dojo/_base/lang", "./lambda"], function(kernel, lang, df){
 
 // This module adds high-level functions and related constructs:
 //	- object/dictionary helpers
@@ -10,13 +10,11 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/window", "./lambda"]
 
 	var empty = {};
 
-/*=====
-	var df = dojox.lang.functional;
- =====*/
 	lang.mixin(df, {
 		// object helpers
 		keys: function(/*Object*/ obj){
-			// summary: returns an array of all keys in the object
+			// summary:
+			//		returns an array of all keys in the object
 			var t = [];
 			for(var i in obj){
 				if(!(i in empty)){
@@ -26,7 +24,8 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/window", "./lambda"]
 			return	t; // Array
 		},
 		values: function(/*Object*/ obj){
-			// summary: returns an array of all values in the object
+			// summary:
+			//		returns an array of all values in the object
 			var t = [];
 			for(var i in obj){
 				if(!(i in empty)){
@@ -36,9 +35,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/window", "./lambda"]
 			return	t; // Array
 		},
 		filterIn: function(/*Object*/ obj, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: creates new object with all attributes that pass the test
-			//	implemented by the provided function.
-			o = o || win.global; f = df.lambda(f);
+			// summary:
+			//		creates new object with all attributes that pass the test
+			//		implemented by the provided function.
+			o = o || kernel.global; f = df.lambda(f);
 			var t = {}, v, i;
 			for(i in obj){
 				if(!(i in empty)){
@@ -49,8 +49,9 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/window", "./lambda"]
 			return t;	// Object
 		},
 		forIn: function(/*Object*/ obj, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: iterates over all object attributes.
-			o = o || win.global; f = df.lambda(f);
+			// summary:
+			//		iterates over all object attributes.
+			o = o || kernel.global; f = df.lambda(f);
 			for(var i in obj){
 				if(!(i in empty)){
 					f.call(o, obj[i], i, obj);
@@ -59,9 +60,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/window", "./lambda"]
 			return o;	// Object
 		},
 		mapIn: function(/*Object*/ obj, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: creates new object with the results of calling
-			//	a provided function on every attribute in this object.
-			o = o || win.global; f = df.lambda(f);
+			// summary:
+			//		creates new object with the results of calling
+			//		a provided function on every attribute in this object.
+			o = o || kernel.global; f = df.lambda(f);
 			var t = {}, i;
 			for(i in obj){
 				if(!(i in empty)){
diff --git a/dojox/lang/functional/reversed.js b/dojox/lang/functional/reversed.js
index 6659366..98f8d9b 100755
--- a/dojox/lang/functional/reversed.js
+++ b/dojox/lang/functional/reversed.js
@@ -1,5 +1,5 @@
-define(["dojo/_base/lang", "dojo/_base/window" ,"./lambda"], 
-	function(lang, win, df){
+define(["dojo/_base/lang", "dojo/_base/kernel" ,"./lambda"],
+	function(lang, kernel, df){
 // This module adds high-level functions and related constructs:
 //	- reversed versions of array-processing functions similar to standard JS functions
 
@@ -12,17 +12,15 @@ define(["dojo/_base/lang", "dojo/_base/window" ,"./lambda"],
 //	- operate on dense arrays
 //	- take a string as the array argument
 
-/*=====
-	var df = dojox.lang.functional;
- =====*/
 	lang.mixin(df, {
 		// JS 1.6 standard array functions, which can take a lambda as a parameter.
 		// Consider using dojo._base.array functions, if you don't need the lambda support.
 		filterRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: creates a new array with all elements that pass the test
-			//	implemented by the provided function.
+			// summary:
+			//		creates a new array with all elements that pass the test
+			//		implemented by the provided function.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var t = [], v, i = a.length - 1;
 			for(; i >= 0; --i){
 				v = a[i];
@@ -31,25 +29,28 @@ define(["dojo/_base/lang", "dojo/_base/window" ,"./lambda"],
 			return t;	// Array
 		},
 		forEachRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: executes a provided function once per array element.
+			// summary:
+			//		executes a provided function once per array element.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			for(var i = a.length - 1; i >= 0; f.call(o, a[i], i, a), --i);
 		},
 		mapRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: creates a new array with the results of calling
-			//	a provided function on every element in this array.
+			// summary:
+			//		creates a new array with the results of calling
+			//		a provided function on every element in this array.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var n = a.length, t = new Array(n), i = n - 1, j = 0;
 			for(; i >= 0; t[j++] = f.call(o, a[i], i, a), --i);
 			return t;	// Array
 		},
 		everyRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: tests whether all elements in the array pass the test
-			//	implemented by the provided function.
+			// summary:
+			//		tests whether all elements in the array pass the test
+			//		implemented by the provided function.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			for(var i = a.length - 1; i >= 0; --i){
 				if(!f.call(o, a[i], i, a)){
 					return false;	// Boolean
@@ -58,10 +59,11 @@ define(["dojo/_base/lang", "dojo/_base/window" ,"./lambda"],
 			return true;	// Boolean
 		},
 		someRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: tests whether some element in the array passes the test
-			//	implemented by the provided function.
+			// summary:
+			//		tests whether some element in the array passes the test
+			//		implemented by the provided function.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || win.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			for(var i = a.length - 1; i >= 0; --i){
 				if(f.call(o, a[i], i, a)){
 					return true;	// Boolean
diff --git a/dojox/lang/functional/scan.js b/dojox/lang/functional/scan.js
index 444b46a..109f095 100755
--- a/dojox/lang/functional/scan.js
+++ b/dojox/lang/functional/scan.js
@@ -1,4 +1,4 @@
-define(["dojo/_base/kernel", "dojo/_base/lang", "./lambda"], function(d, darray, df){
+define(["dojo/_base/kernel", "dojo/_base/lang", "./lambda"], function(kernel, lang, df){
 
 // This module adds high-level functions and related constructs:
 //	- "scan" family of functions
@@ -15,16 +15,17 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./lambda"], function(d, darray,
 
 	var empty = {};
 
-	d.mixin(df, {
+	lang.mixin(df, {
 		// classic reduce-class functions
 		scanl: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
-			// summary: repeatedly applies a binary function to an array from left
-			//	to right using a seed value as a starting point; returns an array
-			//	of values produced by foldl() at that point.
+			// summary:
+			//		repeatedly applies a binary function to an array from left
+			//		to right using a seed value as a starting point; returns an array
+			//		of values produced by foldl() at that point.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || d.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var t, n, i;
-			if(d.isArray(a)){
+			if(lang.isArray(a)){
 				// array
 				t = new Array((n = a.length) + 1);
 				t[0] = z;
@@ -45,13 +46,14 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./lambda"], function(d, darray,
 			return t;	// Array
 		},
 		scanl1: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: repeatedly applies a binary function to an array from left
-			//	to right; returns an array of values produced by foldl1() at that
-			//	point.
+			// summary:
+			//		repeatedly applies a binary function to an array from left
+			//		to right; returns an array of values produced by foldl1() at that
+			//		point.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || d.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var t, n, z, first = true;
-			if(d.isArray(a)){
+			if(lang.isArray(a)){
 				// array
 				t = new Array(n = a.length);
 				t[0] = z = a[0];
@@ -78,22 +80,24 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./lambda"], function(d, darray,
 			return t;	// Array
 		},
 		scanr: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
-			// summary: repeatedly applies a binary function to an array from right
-			//	to left using a seed value as a starting point; returns an array
-			//	of values produced by foldr() at that point.
+			// summary:
+			//		repeatedly applies a binary function to an array from right
+			//		to left using a seed value as a starting point; returns an array
+			//		of values produced by foldr() at that point.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || d.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var n = a.length, t = new Array(n + 1), i = n;
 			t[n] = z;
 			for(; i > 0; --i, z = f.call(o, z, a[i], i, a), t[i] = z);
 			return t;	// Array
 		},
 		scanr1: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: repeatedly applies a binary function to an array from right
-			//	to left; returns an array of values produced by foldr1() at that
-			//	point.
+			// summary:
+			//		repeatedly applies a binary function to an array from right
+			//		to left; returns an array of values produced by foldr1() at that
+			//		point.
 			if(typeof a == "string"){ a = a.split(""); }
-			o = o || d.global; f = df.lambda(f);
+			o = o || kernel.global; f = df.lambda(f);
 			var n = a.length, t = new Array(n), z = a[n - 1], i = n - 1;
 			t[i] = z;
 			for(; i > 0; --i, z = f.call(o, z, a[i], i, a), t[i] = z);
diff --git a/dojox/lang/functional/sequence.js b/dojox/lang/functional/sequence.js
index bd1b398..b7bd2a8 100755
--- a/dojox/lang/functional/sequence.js
+++ b/dojox/lang/functional/sequence.js
@@ -1,4 +1,4 @@
-define(["dojo/_base/lang", "./lambda"], function(lang, df){
+define(["dojo/_base/kernel", "dojo/_base/lang", "./lambda"], function(kernel, lang, df){
 
 // This module adds high-level functions and related constructs:
 //	- sequence generators
@@ -9,25 +9,23 @@ define(["dojo/_base/lang", "./lambda"], function(lang, df){
 // Defined methods:
 //	- take any valid lambda argument as the functional argument
 
-/*=====
-	var df = dojox.lang.functional;
- =====*/
-
 	lang.mixin(df, {
 		// sequence generators
 		repeat: function(/*Number*/ n, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
-			// summary: builds an array by repeatedly applying a unary function N times
-			//	with a seed value Z. N should be greater than 0.
-			o = o || dojo.global; f = df.lambda(f);
+			// summary:
+			//		builds an array by repeatedly applying a unary function N times
+			//		with a seed value Z. N should be greater than 0.
+			o = o || kernel.global; f = df.lambda(f);
 			var t = new Array(n), i = 1;
 			t[0] = z;
 			for(; i < n; t[i] = z = f.call(o, z), ++i);
 			return t;	// Array
 		},
 		until: function(/*Function|String|Array*/ pr, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
-			// summary: builds an array by repeatedly applying a unary function with
-			//	a seed value Z until the predicate is satisfied.
-			o = o || dojo.global; f = df.lambda(f); pr = df.lambda(pr);
+			// summary:
+			//		builds an array by repeatedly applying a unary function with
+			//		a seed value Z until the predicate is satisfied.
+			o = o || kernel.global; f = df.lambda(f); pr = df.lambda(pr);
 			var t = [];
 			for(; !pr.call(o, z); t.push(z), z = f.call(o, z));
 			return t;	// Array
diff --git a/dojox/lang/functional/tailrec.js b/dojox/lang/functional/tailrec.js
index c6e7f5d..d52fda0 100644
--- a/dojox/lang/functional/tailrec.js
+++ b/dojox/lang/functional/tailrec.js
@@ -6,7 +6,7 @@ dojo.require("dojox.lang.functional.util");
 // This module provides recursion combinators:
 //	- a tail recursion combinator.
 
-// Acknoledgements:
+// Acknowledgements:
 //	- recursion combinators are inspired by Manfred von Thun's article
 //		"Recursion Theory and Joy"
 //		(http://www.latrobe.edu.au/philosophy/phimvt/joy/j05cmp.html)
diff --git a/dojox/lang/functional/zip.js b/dojox/lang/functional/zip.js
index f4cb818..3556702 100755
--- a/dojox/lang/functional/zip.js
+++ b/dojox/lang/functional/zip.js
@@ -12,12 +12,14 @@ dojo.provide("dojox.lang.functional.zip");
 	dojo.mixin(df, {
 		// combiners
 		zip: function(){
-			// summary: returns an array of arrays, where the i-th array
-			//	contains the i-th element from each of the argument arrays.
-			// description: This is the venerable zip combiner (for example,
-			//	see Python documentation for general details). The returned
-			//	array is truncated to match the length of the shortest input
-			//	array.
+			// summary:
+			//		returns an array of arrays, where the i-th array
+			//		contains the i-th element from each of the argument arrays.
+			// description:
+			//		This is the venerable zip combiner (for example,
+			//		see Python documentation for general details). The returned
+			//		array is truncated to match the length of the shortest input
+			//		array.
 			var n = arguments[0].length, m = arguments.length, i = 1, t = new Array(n), j, p;
 			for(; i < m; n = Math.min(n, arguments[i++].length));
 			for(i = 0; i < n; ++i){
@@ -28,12 +30,14 @@ dojo.provide("dojox.lang.functional.zip");
 			return t;	// Array
 		},
 		unzip: function(/*Array*/ a){
-			// summary: similar to dojox.lang.functional.zip(), but takes
-			//	a single array of arrays as the input.
-			// description: This function is similar to dojox.lang.functional.zip()
-			//	and can be used to unzip objects packed by
-			//	dojox.lang.functional.zip(). It is here mostly to provide
-			//	a short-cut for the different method signature.
+			// summary:
+			//		similar to dojox.lang.functional.zip(), but takes
+			//		a single array of arrays as the input.
+			// description:
+			//		This function is similar to dojox.lang.functional.zip()
+			//		and can be used to unzip objects packed by
+			//		dojox.lang.functional.zip(). It is here mostly to provide
+			//		a short-cut for the different method signature.
 			return df.zip.apply(null, a);	// Array
 		}
 	});
diff --git a/dojox/lang/observable.js b/dojox/lang/observable.js
index 8c4518f..ede9723 100644
--- a/dojox/lang/observable.js
+++ b/dojox/lang/observable.js
@@ -12,15 +12,13 @@ dojo.experimental("dojox.lang.observable");
 // Only properties with primitive values can be wrapped.
 // This has performance implications as well.
 dojox.lang.observable = function(/*Object*/wrapped,/*function*/onRead,/*function*/onWrite,/*function*/onInvoke){
-	// 	summary:
-	// 		Creates a wrapper object, which can be observed. The wrapper object
-	// 		is a proxy to the wrapped object. If you will be making multiple wrapper
-	// 		objects with the same set of listeners, it is recommended that you
-	// 		use makeObservable, as it is more memory efficient.
-	//
-	// 	wrapped:
-	// 		The object to be wrapped and monitored for property access and modification
-	//
+	// summary:
+	//		Creates a wrapper object, which can be observed. The wrapper object
+	//		is a proxy to the wrapped object. If you will be making multiple wrapper
+	//		objects with the same set of listeners, it is recommended that you
+	//		use makeObservable, as it is more memory efficient.
+	// wrapped:
+	//		The object to be wrapped and monitored for property access and modification
 	// onRead:
 	//		See dojox.lang.makeObservable.onRead
 	// onWrite:
@@ -29,45 +27,41 @@ dojox.lang.observable = function(/*Object*/wrapped,/*function*/onRead,/*function
 	//		See dojox.lang.makeObservable.onInvoke
 	
 	return dojox.lang.makeObservable(onRead,onWrite,onInvoke)(wrapped);
-}
+};
 dojox.lang.makeObservable = function(/*function*/onRead,/*function*/onWrite,/*function*/onInvoke,/*Object*/hiddenFunctions){
 		
-	// 	summary:
-	// 		Creates and returns an observable creator function. All the objects that
-	// 		are created with the returned constructor will use the provided onRead and
-	// 		onWrite listeners.
-	// 		The created constructor should be called with a single argument,
-	// 		the object that will be wrapped to be observed. The constructor will
-	// 		return the wrapper object.
-	//
+	// summary:
+	//		Creates and returns an observable creator function. All the objects that
+	//		are created with the returned constructor will use the provided onRead and
+	//		onWrite listeners.
+	//		The created constructor should be called with a single argument,
+	//		the object that will be wrapped to be observed. The constructor will
+	//		return the wrapper object.
 	// onRead:
-	// 		This is called whenever one of the wrapper objects created
-	// 		from the constructor has a property that is accessed. onRead
-	// 		will be called with two arguments, the first being the wrapped object,
-	// 		and the second is the name of property that is being accessed.
-	// 		The value that onRead returns will be used as the value returned
-	// 		by the property access
-	//
+	//		This is called whenever one of the wrapper objects created
+	//		from the constructor has a property that is accessed. onRead
+	//		will be called with two arguments, the first being the wrapped object,
+	//		and the second is the name of property that is being accessed.
+	//		The value that onRead returns will be used as the value returned
+	//		by the property access
 	// onWrite:
-	// 		This is called whenever one of the wrapper objects created
-	// 		from the constructor has a property that is modified. onWrite
-	// 		will be called with three arguments, the first being the wrapped object,
-	// 		the second is the name of property that is being modified, and the
-	// 		third is the value that is being set on the property.
-	//
-	// 	onInvoke:
-	// 		This is called when a method on the object is invoked. The first
-	// 		argument is the wrapper object, the second is the original wrapped object,
-	// 		the third is the method name, and the fourth is the arguments.
+	//		This is called whenever one of the wrapper objects created
+	//		from the constructor has a property that is modified. onWrite
+	//		will be called with three arguments, the first being the wrapped object,
+	//		the second is the name of property that is being modified, and the
+	//		third is the value that is being set on the property.
+	// onInvoke:
+	//		This is called when a method on the object is invoked. The first
+	//		argument is the wrapper object, the second is the original wrapped object,
+	//		the third is the method name, and the fourth is the arguments.
 	//
 	// hiddenFunctions:
-	// 		allows you to define functions that should be delegated
-	// 		but may not be enumerable on the wrapped objects, so they must be
-	// 		explicitly included
-	//
+	//		allows you to define functions that should be delegated
+	//		but may not be enumerable on the wrapped objects, so they must be
+	//		explicitly included
 	// example:
-	// 		The following could be used to create a wrapper that would
-	// 		prevent functions from being accessed on an object:
+	//		The following could be used to create a wrapper that would
+	//		prevent functions from being accessed on an object:
 	// 	|	function onRead(obj,prop){
 	//	|		return typeof obj[prop] == 'function' ? null : obj[prop];
 	//	|	}
@@ -76,7 +70,7 @@ dojox.lang.makeObservable = function(/*function*/onRead,/*function*/onWrite,/*fu
 	//	|	obj = observable(obj);
 	//	|	obj.foo -> 1
 	//	|	obj.bar -> null
-	//
+
 	hiddenFunctions = hiddenFunctions || {};
 	onInvoke = onInvoke || function(scope,obj,method,args){
 		// default implementation for onInvoke, just passes the call through
@@ -249,8 +243,8 @@ if(!{}.__defineGetter__){
 
 dojox.lang.ReadOnlyProxy =
 // summary:
-// 		Provides a read only proxy to another object, this can be
-// 		very useful in object-capability systems
+//		Provides a read only proxy to another object, this can be
+//		very useful in object-capability systems
 // example:
 // 	|	var obj = {foo:"bar"};
 // 	|	var readonlyObj = dojox.lang.ReadOnlyProxy(obj);
diff --git a/dojox/lang/oo/Decorator.js b/dojox/lang/oo/Decorator.js
index 8188fda..d17eef8 100644
--- a/dojox/lang/oo/Decorator.js
+++ b/dojox/lang/oo/Decorator.js
@@ -4,15 +4,15 @@ dojo.provide("dojox.lang.oo.Decorator");
 	var oo = dojox.lang.oo,
 
 	D = oo.Decorator = function(value, decorator){
-		//	summary:
+		// summary:
 		//		The base class for all decorators.
-		//	description:
+		// description:
 		//		This object holds an original function or another decorator
 		//		object, and implements a special mixin algorithm to be used
 		//		by dojox.lang.oo.mixin.
-		//	value: Object:
+		// value: Object
 		//		a payload to be processed by the decorator.
-		//	decorator: Function|Object:
+		// decorator: Function|Object
 		//		a function to handle the custom assignment, or an object with exec()
 		//		method. The signature is:
 		//		decorator(/*String*/ name, /*Function*/ newValue, /*Function*/ oldValue).
@@ -22,12 +22,12 @@ dojo.provide("dojox.lang.oo.Decorator");
 	};
 
 	oo.makeDecorator = function(decorator){
-		//	summary:
+		// summary:
 		//		creates new custom decorator creator
-		//	decorator: Function|Object:
+		// decorator: Function|Object
 		//		a function to handle the custom assignment,
 		//		or an object with exec() method
-		//	returns: Function:
+		// returns: Function
 		//		new decorator constructor
 		return function(value){
 			return new D(value, decorator);
diff --git a/dojox/lang/oo/Filter.js b/dojox/lang/oo/Filter.js
index bea528f..516d573 100644
--- a/dojox/lang/oo/Filter.js
+++ b/dojox/lang/oo/Filter.js
@@ -4,16 +4,16 @@ dojo.provide("dojox.lang.oo.Filter");
 	var oo = dojox.lang.oo,
 
 	F = oo.Filter = function(bag, filter){
-		//	summary:
+		// summary:
 		//		Filter to control mixing in objects by skipping
 		//		properties and renaming them.
-		//	description:
+		// description:
 		//		This object is used as a holder of an original object
-		//		(whose properites are to be copied), and a filter
+		//		(whose properties are to be copied), and a filter
 		//		function used while copying by dojox.lang.oo.mixin.
-		//	bag: Object:
+		// bag: Object
 		//		object to be filtered
-		//	filter: Function|Object:
+		// filter: Function|Object
 		//		a function to handle the name filtering,
 		//		or an object with exec() method
 		this.bag = bag;
@@ -31,13 +31,13 @@ dojo.provide("dojox.lang.oo.Filter");
 	};
 
 	oo.filter = function(bag, map){
-		//	summary:
+		// summary:
 		//		creates a simple filter object
-		//	bag: Object:
+		// bag: Object
 		//		object to be filtered
-		//	map: Object:
+		// map: Object
 		//		the dictionary for renaming/removing while copying
-		//	returns:
+		// returns:
 		//		new dojox.lang.oo.Filter object
 		return new F(bag, new MapFilter(map));
 	};
diff --git a/dojox/lang/oo/aop.js b/dojox/lang/oo/aop.js
index e31c0aa..a0f80fb 100644
--- a/dojox/lang/oo/aop.js
+++ b/dojox/lang/oo/aop.js
@@ -9,30 +9,34 @@ dojo.require("dojox.lang.oo.general");
 
 	// five decorators implementing light-weight AOP weaving
 
+	// reuse existing decorators
+	ooa.before = oog.before;
+	ooa.around = oog.wrap;
+
 	/*=====
 	ooa.before = md(function(name, newValue, oldValue){
-		// summary: creates a "before" advise, by calling new function
-		// before the old one
+		// summary:
+		//		creates a "before" advise, by calling new function
+		//		before the old one
 
 		// dummy body
 	});
 
 	ooa.around = md(function(name, newValue, oldValue){
-		// summary: creates an "around" advise,
-		// the previous value is passed as a first argument and can be null,
-		// arguments are passed as a second argument
+		// summary:
+		//		creates an "around" advise,
+		//		the previous value is passed as a first argument and can be null,
+		//		arguments are passed as a second argument
 
 		// dummy body
 	});
 	=====*/
 
-	// reuse existing decorators
-	ooa.before = oog.before;
-	ooa.around = oog.wrap;
 
 	ooa.afterReturning = md(function(name, newValue, oldValue){
-		// summary: creates an "afterReturning" advise,
-		// the returned value is passed as the only argument
+		// summary:
+		//		creates an "afterReturning" advise,
+		//		the returned value is passed as the only argument
 		return isF(oldValue) ?
 			function(){
 				var ret = oldValue.apply(this, arguments);
@@ -42,8 +46,9 @@ dojo.require("dojox.lang.oo.general");
 	});
 
 	ooa.afterThrowing = md(function(name, newValue, oldValue){
-		// summary: creates an "afterThrowing" advise,
-		// the exception is passed as the only argument
+		// summary:
+		//		creates an "afterThrowing" advise,
+		//		the exception is passed as the only argument
 		return isF(oldValue) ?
 			function(){
 				var ret;
@@ -58,8 +63,9 @@ dojo.require("dojox.lang.oo.general");
 	});
 
 	ooa.after = md(function(name, newValue, oldValue){
-		// summary: creates an "after" advise,
-		// it takes no arguments
+		// summary:
+		//		creates an "after" advise,
+		//		it takes no arguments
 		return isF(oldValue) ?
 			function(){
 				var ret;
diff --git a/dojox/lang/oo/general.js b/dojox/lang/oo/general.js
index cd024ae..e662e35 100644
--- a/dojox/lang/oo/general.js
+++ b/dojox/lang/oo/general.js
@@ -9,17 +9,20 @@ dojo.require("dojox.lang.oo.Decorator");
 	// generally useful decorators
 
 	oog.augment = md(function(name, newValue, oldValue){
-		// summary: add property, if it was not defined before
+		// summary:
+		//		add property, if it was not defined before
 		return typeof oldValue == "undefined" ? newValue : oldValue;
 	});
 
 	oog.override = md(function(name, newValue, oldValue){
-		// summary: override property only if it was already present
+		// summary:
+		//		override property only if it was already present
 		return typeof oldValue != "undefined" ? newValue : oldValue;
 	});
 
 	oog.shuffle = md(function(name, newValue, oldValue){
-		// summary: replaces arguments for an old method
+		// summary:
+		//		replaces arguments for an old method
 		return isF(oldValue) ?
 			function(){
 				return oldValue.apply(this, newValue.apply(this, arguments));
@@ -27,17 +30,19 @@ dojo.require("dojox.lang.oo.Decorator");
 	});
 
 	oog.wrap = md(function(name, newValue, oldValue){
-		// summary: wraps the old values with a supplied function
+		// summary:
+		//		wraps the old values with a supplied function
 		return function(){ return newValue.call(this, oldValue, arguments); };
 	});
 
 	oog.tap = md(function(name, newValue, oldValue){
-		// summary: always returns "this" ignoring the actual return
+		// summary:
+		//		always returns "this" ignoring the actual return
 		return function(){ newValue.apply(this, arguments); return this; };
 	});
 
 	oog.before = md(function(name, newValue, oldValue){
-		//	summary:
+		// summary:
 		//		creates a chain of calls where the new method is called
 		//		before the old method
 		return isF(oldValue) ?
@@ -48,7 +53,7 @@ dojo.require("dojox.lang.oo.Decorator");
 	});
 
 	oog.after = md(function(name, newValue, oldValue){
-		//	summary:
+		// summary:
 		//		creates a chain of calls where the new method is called
 		//		after the old method
 		return isF(oldValue) ?
diff --git a/dojox/lang/oo/mixin.js b/dojox/lang/oo/mixin.js
index 74d4e8a..e556777 100644
--- a/dojox/lang/oo/mixin.js
+++ b/dojox/lang/oo/mixin.js
@@ -14,17 +14,17 @@ dojo.require("dojox.lang.oo.Decorator");
 		extraNames = dojo._extraNames, extraLen = extraNames.length,
 
 		applyDecorator = oo.applyDecorator = function(decorator, name, newValue, oldValue){
-			//	summary:
+			// summary:
 			//		applies a decorator unraveling all embedded decorators
-			//	decorator: Function:
+			// decorator: Function
 			//		top-level decorator to apply
-			//	name: String:
+			// name: String
 			//		name of the property
-			//	newValue: Object:
+			// newValue: Object
 			//		new value of the property
-			//	oldValue: Object:
+			// oldValue: Object
 			//		old value of the property
-			//	returns: Object:
+			// returns: Object
 			//		returns the final value of the property
 			if(newValue instanceof Decorator){
 				var d = newValue.decorator;
@@ -35,31 +35,28 @@ dojo.require("dojox.lang.oo.Decorator");
 		};
 
 	/*=====
-	dojox.lang.oo.__MixinDefaults = function(){
-		//	summary:
+	dojox.lang.oo.__MixinDefaults = {
+		// summary:
 		//		a dict of default parameters for dojox.lang.oo._mixin
-		//	decorator: Function:
+		// decorator: Function
 		//		a decorator function to be used in absence of other decorators
-		//	filter: Function:
+		// filter: Function
 		//		a filter function to be used in absence of other filters
-		//	mixer: Function:
+		// mixer: Function
 		//		a mixer function to be used to mix in new properties
-		this.decorator = decorator;
-		this.filter = filter;
-		this.mixer = mixer;
 	};
 	=====*/
 
 	oo.__mixin = function(target, source, decorator, filter, mixer){
-		//	summary:
+		// summary:
 		//		mixes in two objects processing decorators and filters
-		//	target: Object:
+		// target: Object
 		//		target to receive new/updated properties
-		//	source: Object:
+		// source: Object
 		//		source of properties
-		//	defaults: dojox.lang.oo.__MixinDefaults?:
+		// defaults: dojox.lang.oo.__MixinDefaults?
 		//		default functions for various aspects of mixing
-		//	returns: Object:
+		// returns: Object
 		//		target
 
 		var name, targetName, prop, newValue, oldValue, i;
@@ -105,11 +102,11 @@ dojo.require("dojox.lang.oo.Decorator");
 		// summary:
 		//		mixes in two or more objects processing decorators and filters
 		//		using defaults as a fallback
-		// target: Object:
+		// target: Object
 		//		target to receive new/updated properties
-		// source: Object...:
+		// source: Object...
 		//		source of properties, more than one source is allowed
-		// returns: Object:
+		// returns: Object
 		//		target
 
 		var decorator, filter, i = 1, l = arguments.length;
diff --git a/dojox/lang/oo/rearrange.js b/dojox/lang/oo/rearrange.js
index e7433cb..0a9fe52 100644
--- a/dojox/lang/oo/rearrange.js
+++ b/dojox/lang/oo/rearrange.js
@@ -5,21 +5,21 @@ dojo.provide("dojox.lang.oo.rearrange");
 		opts = Object.prototype.toString, empty = {};
 
 	dojox.lang.oo.rearrange = function(bag, map){
-		//	summary:
+		// summary:
 		//		Process properties in place by removing and renaming them.
-		//	description:
+		// description:
 		//		Properties of an object are to be renamed or removed specified
 		//		by "map" argument. Only own properties of "map" are processed.
-		//	example:
+		// example:
 		//	|	oo.rearrange(bag, {
 		//	|		abc: "def",	// rename "abc" attribute to "def"
 		//	|		ghi: null	// remove/hide "ghi" attribute
 		//	|	});
-		//	bag: Object:
+		// bag: Object
 		//		the object to be processed
-		//	map: Object:
+		// map: Object
 		//		the dictionary for renaming (false value indicates removal of the named property)
-		//	returns: Object:
+		// returns: Object
 		//		the original object
 
 	var name, newName, prop, i, t;
diff --git a/dojox/lang/tests/bench_decl.html b/dojox/lang/tests/bench_decl.html
index c08cf8e..4268db1 100644
--- a/dojox/lang/tests/bench_decl.html
+++ b/dojox/lang/tests/bench_decl.html
@@ -12,7 +12,7 @@
             .stablest { background-color: #ffc; }
             .fastest.stablest { background-color: #cfc; }
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.lang.tests.declare-old");
 
diff --git a/dojox/lang/tests/declare-old.js b/dojox/lang/tests/declare-old.js
index 3d1572f..28c3e7f 100644
--- a/dojox/lang/tests/declare-old.js
+++ b/dojox/lang/tests/declare-old.js
@@ -5,25 +5,25 @@ dojo.provide("dojox.lang.tests.declare-old");
 // this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
 
 dojox.lang.tests.declareOld = function(/*String*/ className, /*Function|Function[]*/ superclass, /*Object*/ props){
-	//	summary:
+	// summary:
 	//		Create a feature-rich constructor from compact notation
 	//
-	//	description:
+	// description:
 	//		Create a feature-rich constructor from compact notation
 	//
-	//	className:
+	// className:
 	//		The name of the constructor (loosely, a "class")
 	//		stored in the "declaredClass" property in the created prototype
-	//	superclass:
+	// superclass:
 	//		May be null, a Function, or an Array of Functions. If an array,
 	//		the first element is used as the prototypical ancestor and
 	//		any following Functions become mixin ancestors.
-	//	props:
+	// props:
 	//		An object whose properties are copied to the
 	//		created prototype.
 	//		Add an instance-initialization function by making it a property
 	//		named "constructor".
-	//	description:
+	// description:
 	//		Create a constructor using a compact notation for inheritance and
 	//		prototype extension.
 	//
@@ -35,7 +35,7 @@ dojox.lang.tests.declareOld = function(/*String*/ className, /*Function|Function
 	//
 	//		"className" is cached in "declaredClass" property of the new class.
 	//
-	//	example:
+	// example:
 	//		Declare a class with no ancestors.
 	//	|	dojo.declare("my.ClassyThing", null, {
 	//	|		aProperty:"string",
@@ -44,7 +44,7 @@ dojox.lang.tests.declareOld = function(/*String*/ className, /*Function|Function
 	//	|		}
 	//	|	});
 	//
-	//	example:
+	// example:
 	//		Declare a class inheriting from my.classed.Foo
 	//	|	dojo.declare("my.classes.Bar", my.classes.Foo, {
 	//	|		// properties to be added to the class prototype
@@ -59,7 +59,7 @@ dojox.lang.tests.declareOld = function(/*String*/ className, /*Function|Function
 	//	|		}
 	//	|	);
 	//
-	//	example:
+	// example:
 	//		Declare a class inherting from two mixins, handling multiple constructor args
 	//	|	dojo.declare("my.ComplexMix", [my.BaseClass, my.MixedClass],{
 	//	|		constructor: function(a, b){
diff --git a/dojox/lang/tests/fun_perf.html b/dojox/lang/tests/fun_perf.html
index 9e1da30..7893950 100644
--- a/dojox/lang/tests/fun_perf.html
+++ b/dojox/lang/tests/fun_perf.html
@@ -4,7 +4,7 @@
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript" src="../functional.js"></script>
 		<script type="text/javascript" src="../functional/sequence.js"></script>
 		<script type="text/javascript" src="../functional/fold.js"></script>
diff --git a/dojox/lang/tests/observable.js b/dojox/lang/tests/observable.js
index 229f1d0..f3ebf42 100644
--- a/dojox/lang/tests/observable.js
+++ b/dojox/lang/tests/observable.js
@@ -91,11 +91,11 @@ dojo.require("dojox.lang.observable");
 					// summary:
 					//	Gets the value of an item's 'property'
 					//
-					//	item: /* object */
-					//	property: /* string */
+					// item: /* object */
+					// property: /* string */
 					//		property to look up value for
 					// lazyCallback: /* function*/
-					// 		not part of the API, but if you are using lazy loading properties, you may provide a callback to resume, in order to have asynchronous loading
+					//		not part of the API, but if you are using lazy loading properties, you may provide a callback to resume, in order to have asynchronous loading
 					var value = item[property];
 					if(value instanceof dojo.Deferred){
 						dojox.rpc._sync = !lazyCallback; // tell the service to operate synchronously (I have some concerns about the "thread" safety with FF3, as I think it does event stacking on sync calls)
diff --git a/dojox/lang/tests/rec_perf.html b/dojox/lang/tests/rec_perf.html
index 3eab63d..edb3722 100644
--- a/dojox/lang/tests/rec_perf.html
+++ b/dojox/lang/tests/rec_perf.html
@@ -4,7 +4,7 @@
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript" src="../functional.js"></script>
 		<script type="text/javascript" src="../functional/linrec.js"></script>
 		<script type="text/javascript" src="../functional/tailrec.js"></script>
diff --git a/dojox/lang/tests/test_aspect.html b/dojox/lang/tests/test_aspect.html
index 912fc76..0cfb800 100644
--- a/dojox/lang/tests/test_aspect.html
+++ b/dojox/lang/tests/test_aspect.html
@@ -4,7 +4,7 @@
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript" src="../aspect.js"></script>
 		<script type="text/javascript" src="../aspect/cflow.js"></script>
 		<script type="text/javascript" src="../aspect/tracer.js"></script>
diff --git a/dojox/lang/tests/test_oo_decl.html b/dojox/lang/tests/test_oo_decl.html
index 0dbdc25..9c69609 100644
--- a/dojox/lang/tests/test_oo_decl.html
+++ b/dojox/lang/tests/test_oo_decl.html
@@ -4,7 +4,7 @@
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 		<!--<script type="text/javascript" src="../oo/declare.js"></script>-->
 		<script type="text/javascript">
 			//dojo.require("dojox.lang.oo.declare");
diff --git a/dojox/lang/tests/test_oo_mixin.html b/dojox/lang/tests/test_oo_mixin.html
index 38a95bf..ce0e599 100644
--- a/dojox/lang/tests/test_oo_mixin.html
+++ b/dojox/lang/tests/test_oo_mixin.html
@@ -4,7 +4,7 @@
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.lang.oo.mixin");
 			dojo.require("dojox.lang.oo.general");
diff --git a/dojox/lang/typed.js b/dojox/lang/typed.js
index bb15851..7541826 100644
--- a/dojox/lang/typed.js
+++ b/dojox/lang/typed.js
@@ -42,9 +42,10 @@
 		}
 	}
 	function validate(instance, schema, property){
-		//	summary:
+		// summary:
 		//		This checks to ensure that the result is valid and will throw an appropriate error message if it is not
-		// result: the result returned from checkPropertyChange or validate
+		// result:
+		//		the result returned from checkPropertyChange or validate
 		if(typeof instance == "function" && schema && !instance.__typedFunction__){
 			instance = validatingFunction(instance, identityFunc(schema));
 		}
diff --git a/dojox/lang/utils.js b/dojox/lang/utils.js
index 56dcf7c..4d801a7 100644
--- a/dojox/lang/utils.js
+++ b/dojox/lang/utils.js
@@ -18,9 +18,12 @@ define(["..", "dojo/_base/lang"],
 	
 	lang.mixin(du, {
 		coerceType: function(target, source){
-			// summary: Coerces one object to the type of another.
-			// target: Object: object, which typeof result is used to coerce "source" object.
-			// source: Object: object, which will be forced to change type.
+			// summary:
+			//		Coerces one object to the type of another.
+			// target: Object
+			//		object, which typeof result is used to coerce "source" object.
+			// source: Object
+			//		object, which will be forced to change type.
 			switch(typeof target){
 				case "number":	return Number(eval("(" + source + ")"));
 				case "string":	return String(source);
@@ -30,10 +33,14 @@ define(["..", "dojo/_base/lang"],
 		},
 		
 		updateWithObject: function(target, source, conv){
-			// summary: Updates an existing object in place with properties from an "source" object.
-			// target: Object: the "target" object to be updated
-			// source: Object: the "source" object, whose properties will be used to source the existed object.
-			// conv: Boolean?: force conversion to the original type
+			// summary:
+			//		Updates an existing object in place with properties from an "source" object.
+			// target: Object
+			//		the "target" object to be updated
+			// source: Object
+			//		the "source" object, whose properties will be used to source the existed object.
+			// conv: Boolean?
+			//		force conversion to the original type
 			if(!source){ return target; }
 			for(var x in target){
 				if(x in source && !(x in empty)){
@@ -49,11 +56,16 @@ define(["..", "dojo/_base/lang"],
 		},
 	
 		updateWithPattern: function(target, source, pattern, conv){
-			// summary: Updates an existing object in place with properties from an "source" object.
-			// target: Object: the "target" object to be updated
-			// source: Object: the "source" object, whose properties will be used to source the existed object.
-			// pattern: Object: object, whose properties will be used to pull values from the "source"
-			// conv: Boolean?: force conversion to the original type
+			// summary:
+			//		Updates an existing object in place with properties from an "source" object.
+			// target: Object
+			//		the "target" object to be updated
+			// source: Object
+			//		the "source" object, whose properties will be used to source the existed object.
+			// pattern: Object
+			//		object, whose properties will be used to pull values from the "source"
+			// conv: Boolean?
+			//		force conversion to the original type
 			if(!source || !pattern){ return target; }
 			for(var x in pattern){
 				if(x in source && !(x in empty)){
@@ -64,9 +76,12 @@ define(["..", "dojo/_base/lang"],
 		},
 		
 		merge: function(object, mixin){
-			// summary: Merge two objects structurally, mixin properties will override object's properties.
-			// object: Object: original object.
-			// mixin: Object: additional object, which properties will override object's properties.
+			// summary:
+			//		Merge two objects structurally, mixin properties will override object's properties.
+			// object: Object
+			//		original object.
+			// mixin: Object
+			//		additional object, which properties will override object's properties.
 			if(mixin){
 				var otype = opts.call(object), mtype = opts.call(mixin), t, i, l, m;
 				switch(mtype){
diff --git a/dojox/layout/ContentPane.js b/dojox/layout/ContentPane.js
index 3bdb1dd..8ca0484 100755
--- a/dojox/layout/ContentPane.js
+++ b/dojox/layout/ContentPane.js
@@ -6,13 +6,12 @@ define([
 	"dojo/_base/declare"
 ], function (lang, xhrUtil, ContentPane, htmlUtil, declare) {
 
-/*===== var ContentPane = dijit.layout.ContentPane =====*/
 return declare("dojox.layout.ContentPane", ContentPane, {
 	// summary:
 	//		An extended version of dijit.layout.ContentPane.
-	//		Supports infile scripts and external ones declared by <script src=''
+	//		Supports infile scripts and external ones declared by `<script src=''...>`
 	//		relative path adjustments (content fetched from a different folder)
-	//		<style> and <link rel='stylesheet' href='..'> tags,
+	//		`<style>` and `<link rel='stylesheet' href='..'>` tags,
 	//		css paths inside cssText is adjusted (if you set adjustPaths = true)
 	//
 	//		NOTE that dojo.require in script in the fetched file isn't recommended
@@ -24,14 +23,12 @@ return declare("dojox.layout.ContentPane", ContentPane, {
 	adjustPaths: false,
 
 	// cleanContent: Boolean
-	//	summary:
-	//		cleans content to make it less likely to generate DOM/JS errors.
-	//	description:
-	//		useful if you send ContentPane a complete page, instead of a html fragment
-	//		scans for
+	//		Cleans content to make it less likely to generate DOM/JS errors.
+	//		Useful if you send ContentPane a complete page, instead of a html fragment
+	//		scans for:
 	//
-	//			* title Node, remove
-	//			* DOCTYPE tag, remove
+	//		- title Node, remove
+	//		- DOCTYPE tag, remove
 	cleanContent: false,
 
 	// renderStyles: Boolean
@@ -44,19 +41,17 @@ return declare("dojox.layout.ContentPane", ContentPane, {
 
 	// scriptHasHooks: Boolean
 	//		replace keyword '_container_' in scripts with 'dijit.byId(this.id)'
-	// NOTE this name might change in the near future
+	//		NOTE this name might change in the near future
 	scriptHasHooks: false,
 
-	constructor: function(){
-		// init per instance properties, initializer doesn't work here because how things is hooked up in dijit._Widget
-		this.ioArgs = {};
-		this.ioMethod = xhrUtil.get;
-	},
+	ioMethod: xhrUtil.get,
+
+	ioArgs: {},
 
-	onExecError: function(e){
+	onExecError: function(/*Event*/ e){
 		// summary:
 		//		event callback, called on script error or on java handler error
-		//		overide and return your own html string if you want a some text
+		//		override and return your own html string if you want a some text
 		//		displayed within the ContentPane
 	},
 
@@ -96,4 +91,4 @@ return declare("dojox.layout.ContentPane", ContentPane, {
 	}
 	// could put back _renderStyles by wrapping/aliasing dojox.html._ContentSetter.prototype._renderStyles
 });
-});
\ No newline at end of file
+});
diff --git a/dojox/layout/Dock.js b/dojox/layout/Dock.js
new file mode 100644
index 0000000..f54c584
--- /dev/null
+++ b/dojox/layout/Dock.js
@@ -0,0 +1,111 @@
+define(["dojo/_base/lang", "dojo/_base/window", "dojo/_base/declare",
+		"dojo/_base/fx", "dojo/on", "dojo/_base/array", "dojo/_base/sniff",
+		"dojo/window", "dojo/dom", "dojo/dom-class", "dojo/dom-geometry", "dojo/dom-construct",
+		"dijit/_TemplatedMixin", "dijit/_WidgetBase", "dijit/BackgroundIframe", "dojo/dnd/Moveable",
+		"./ContentPane", "./ResizeHandle", "dojo/text!./resources/FloatingPane.html", "dojo/domReady!"], function(
+	lang, winUtil, declare, fx, on, arrayUtil, 
+	has, windowLib, dom, domClass, domGeom, domConstruct, _TemplatedMixin, _WidgetBase, BackgroundIframe, 
+	Moveable, ContentPane, ResizeHandle, template){
+
+//TODO: don't want to rely on kernel just to make something as experimental	
+//kernel.experimental("dojox.layout.Dock");
+
+var Dock = declare("dojox.layout.Dock",[_WidgetBase, _TemplatedMixin],{
+	// summary:
+	//		A widget that attaches to a node and keeps track of incoming / outgoing FloatingPanes
+	//		and handles layout
+
+	templateString: '<div class="dojoxDock"><ul dojo-dojo-attach-point="containerNode" class="dojoxDockList"></ul></div>',
+
+	// _docked: [private] Array
+	//		array of panes currently in our dock
+	_docked: [],
+	
+	_inPositioning: false,
+	
+	autoPosition: false,
+	
+	addNode: function(refNode){
+		// summary:
+		//		Insert a dockNode reference into the dock
+		
+		var div = domConstruct.create('li', null, this.containerNode),
+			node = new DockNode({
+				title: refNode.title,
+				paneRef: refNode
+			}, div)
+		;
+		node.startup();
+		return node;
+	},
+
+	startup: function(){
+				
+		if (this.id == "dojoxGlobalFloatingDock" || this.isFixedDock) {
+			// attach window.onScroll, and a position like in presentation/dialog
+			this.own(
+				on(window, "resize", lang.hitch(this, "_positionDock")),
+				on(window, "scroll", lang.hitch(this, "_positionDock"))
+			);
+			if(has("ie")){ // TODO: All versions of IE, or pre-IE9, or some feature to test?
+				this.own(
+					on(this.domNode, "resize", lang.hitch(this, "_positionDock"))
+				);
+			}
+		}
+		this._positionDock(null);
+		this.inherited(arguments);
+
+	},
+	
+	_positionDock: function(/* Event? */e){
+		if(!this._inPositioning){
+			if(this.autoPosition == "south"){
+				// Give some time for scrollbars to appear/disappear
+				setTimeout(lang.hitch(this, function() {
+					this._inPositiononing = true;
+					var viewport = windowLib.getBox();
+					var s = this.domNode.style;
+					s.left = viewport.l + "px";
+					s.width = (viewport.w-2) + "px";
+					s.top = (viewport.h + viewport.t) - this.domNode.offsetHeight + "px";
+					this._inPositioning = false;
+				}), 125);
+			}
+		}
+	}
+
+
+});
+
+var DockNode = declare("dojox.layout._DockNode",[_WidgetBase, _TemplatedMixin],{
+	// summary:
+	//		dojox.layout._DockNode is a private widget used to keep track of
+	//		which pane is docked.
+
+	// title: String
+	//		Shown in dock icon. should read parent iconSrc?
+	title: "",
+
+	// paneRef: Widget
+	//		reference to the FloatingPane we reprasent in any given dock
+	paneRef: null,
+
+	templateString:
+		'<li data-dojo-attach-event="onclick: restore" class="dojoxDockNode">'+
+			'<span data-dojo-attach-point="restoreNode" class="dojoxDockRestoreButton" data-dojo-attach-event="onclick: restore"></span>'+
+			'<span class="dojoxDockTitleNode" data-dojo-attach-point="titleNode">${title}</span>'+
+		'</li>',
+
+	restore: function(){
+		// summary:
+		//		remove this dock item from parent dock, and call show() on reffed floatingpane
+		this.paneRef.show();
+		this.paneRef.bringToTop();
+		this.destroy();
+	}
+});
+
+return Dock;
+});
+
diff --git a/dojox/layout/DragPane.js b/dojox/layout/DragPane.js
index 93405fb..f83d0b8 100644
--- a/dojox/layout/DragPane.js
+++ b/dojox/layout/DragPane.js
@@ -1,14 +1,13 @@
 define(["dojo/_base/declare", "dijit/_Widget", "dojo/_base/html", "dojo/dom-style"],
   function(declare, Widget, htmlUtil, domStyle){
-/*===== var Widget = dijit._Widget; =====*/
 return declare("dojox.layout.DragPane", Widget, {
-	// summary: Makes a pane's content dragable by/within it's surface
-	//
+	// summary:
+	//		Makes a pane's content draggable by/within it's surface
 	// description:
 	//		A small widget which takes a node with overflow:auto and
 	//		allows dragging to position the content. Useful with images,
 	//		or for just adding "something" to a overflow-able div.
-	//
+
 	// invert: Boolean
 	//		Naturally, the behavior is to invert the axis of the drag.
 	//		Setting invert:false will make the pane drag in the same
@@ -21,8 +20,9 @@ return declare("dojox.layout.DragPane", Widget, {
 		this.connect(this.domNode, "onmouseup", "_up");
 	},
 	
-	_down: function(e){
-		// summary: mousedown handler, start the dragging
+	_down: function(/*Event*/ e){
+		// summary:
+		//		mousedown handler, start the dragging
 		var t = this.domNode;
 		e.preventDefault();
 		domStyle.set(t, "cursor", "move");
@@ -35,16 +35,18 @@ return declare("dojox.layout.DragPane", Widget, {
 		}
 	},
 	
-	_up: function(e){
-		// summary: mouseup handler, stop the dragging
+	_up: function(/*Event*/ e){
+		// summary:
+		//		mouseup handler, stop the dragging
 		htmlUtil.setSelectable(this.domNode,true);
 		domStyle.set(this.domNode, "cursor", "pointer");
 		this._mover && this.disconnect(this._mover);
 		delete this._mover;
 	},
 	
-	_move: function(e){
-		// summary: mousemove listener, offset the scroll amount by the delta
+	_move: function(/*Event*/ e){
+		// summary:
+		//		mousemove listener, offset the scroll amount by the delta
 		//		since our last call.
 		
 		var mod = this.invert ? 1 : -1;
@@ -56,4 +58,4 @@ return declare("dojox.layout.DragPane", Widget, {
 	}
 	
 });
-});
\ No newline at end of file
+});
diff --git a/dojox/layout/ExpandoPane.js b/dojox/layout/ExpandoPane.js
index 5777d93..ca2aa4e 100644
--- a/dojox/layout/ExpandoPane.js
+++ b/dojox/layout/ExpandoPane.js
@@ -1,24 +1,29 @@
-define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/declare","dojo/_base/array", 
-	"dojo/_base/connect","dojo/_base/event","dojo/_base/fx","dojo/dom-style",
-	"dojo/dom-class","dojo/dom-geometry","dojo/text!./resources/ExpandoPane.html",
-	"dijit/layout/ContentPane","dijit/_TemplatedMixin","dijit/_Contained","dijit/_Container"], 
-  function(kernel,lang,declare,arrayUtil,connectUtil,eventUtil,baseFx,domStyle,domClass,domGeom,
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/_base/array", 
+	"dojo/_base/connect",
+	"dojo/_base/event",
+	"dojo/_base/fx",
+	"dojo/dom-style",
+	"dojo/dom-class",
+	"dojo/dom-geometry",
+	"dojo/text!./resources/ExpandoPane.html",
+	"dijit/layout/ContentPane",
+	"dijit/_TemplatedMixin",
+	"dijit/_Contained",
+	"dijit/_Container"
+], function(kernel,lang,declare,arrayUtil,connectUtil,eventUtil,baseFx,domStyle,domClass,domGeom,
 		template,ContentPane,TemplatedMixin,Contained,Container) {
-/*=====
-var ContentPane = dijit.layout.ContentPane;
-var TemplatedMixin = dijit._TemplatedMixin;
-var Contained = dijit._Contained;
-var Container = dijit._Container;
-  =====*/
 kernel.experimental("dojox.layout.ExpandoPane"); // just to show it can be done?
 
 return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contained, Container],{
-	// summary: An experimental collapsing-pane for dijit.layout.BorderContainer
-	//
+	// summary:
+	//		An experimental collapsing-pane for dijit.layout.BorderContainer
 	// description:
 	//		Works just like a ContentPane inside of a borderContainer. Will expand/collapse on
 	//		command, and supports having Layout Children as direct descendants
-	//
 
 	//maxHeight: "",
 	//maxWidth: "",
@@ -55,6 +60,11 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 	//		If false, a double-click will cause the preview to popup
 	previewOnDblClick: false,
 
+	// tabIndex: String
+	//		Order fields are traversed when user hits the tab key
+	tabIndex: "0",
+	_setTabIndexAttr: "iconNode",
+
 	baseClass: "dijitExpandoPane",
 
 	postCreate: function(){
@@ -76,6 +86,7 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 				case "trailing" :
 				case "right" :
 					thisClass = rtl ? "Left" : "Right";
+					this._needsPosition = "left";
 					break;
 				case "leading" :
 				case "left" :
@@ -85,6 +96,7 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 					thisClass = "Top";
 					break;
 				case "bottom" :
+					this._needsPosition = "top";
 					thisClass = "Bottom";
 					break;
 			}
@@ -99,6 +111,8 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 		
 		this.connect(this.domNode, "ondblclick", this.previewOnDblClick ? "preview" : "toggle");
 		
+		this.iconNode.setAttribute("aria-controls", this.id);
+		
 		if(this.previewOnDblClick){
 			this.connect(this.getParent(), "_layoutChildren", lang.hitch(this, function(){
 				this._isonlypreview = false;
@@ -134,13 +148,14 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 			this._hideAnim.gotoPercent(99,true);
 		}
 		
+		this.domNode.setAttribute("aria-expanded", this._showing);
 		this._hasSizes = true;
 	},
 	
 	_afterResize: function(e){
 		var tmp = this._currentSize;						// the old size
 		this._currentSize = domGeom.getMarginBox(this.domNode);	// the new size
-		var n = this._currentSize[(this._isHorizontal ? "h" : "w")]
+		var n = this._currentSize[(this._isHorizontal ? "h" : "w")];
 		if(n > this._titleHeight){
 			if(!this._showing){
 				this._showing = !this._showing;
@@ -158,7 +173,8 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 	},
 	
 	_setupAnims: function(){
-		// summary: Create the show and hide animations
+		// summary:
+		//		Create the show and hide animations
 		arrayUtil.forEach(this._animConnects, connectUtil.disconnect);
 		
 		var _common = {
@@ -167,17 +183,35 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 			},
 			isHorizontal = this._isHorizontal,
 			showProps = {},
+			showSize = this._showSize,
+			hideSize = this._closedSize,
 			hideProps = {},
-			dimension = isHorizontal ? "height" : "width"
+			dimension = isHorizontal ? "height" : "width",
+			also = this._needsPosition
 		;
 
 		showProps[dimension] = {
-			end: this._showSize
+			end: showSize
 		};
 		hideProps[dimension] = {
-			end: this._closedSize
+			end: hideSize
 		};
 		
+		if(also){
+			showProps[also] = {
+				end: function(n){
+					var c = parseInt(n.style[also], 10);
+					return c - showSize + hideSize; 
+				}
+			}
+			hideProps[also] = {
+				end: function(n){
+					var c = parseInt(n.style[also], 10);
+					return c + showSize - hideSize;
+				}
+			}
+		}
+		
 		this._showAnim = baseFx.animateProperty(lang.mixin(_common,{
 			easing:this.easeIn,
 			properties: showProps
@@ -194,7 +228,8 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 	},
 	
 	preview: function(){
-		// summary: Expand this pane in preview mode (does not affect surrounding layout)
+		// summary:
+		//		Expand this pane in preview mode (does not affect surrounding layout)
 
 		if(!this._showing){
 			this._isonlypreview = !this._isonlypreview;
@@ -203,7 +238,8 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 	},
 
 	toggle: function(){
-		// summary: Toggle this pane's visibility
+		// summary:
+		//		Toggle this pane's visibility
 		if(this._showing){
 			this._hideWrapper();
 			this._showAnim && this._showAnim.stop();
@@ -213,10 +249,12 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 			this._showAnim.play();
 		}
 		this._showing = !this._showing;
+		this.domNode.setAttribute("aria-expanded", this._showing);
 	},
 	
 	_hideWrapper: function(){
-		// summary: Set the Expando state to "closed"
+		// summary:
+		//		Set the Expando state to "closed"
 		domClass.add(this.domNode, "dojoxExpandoClosed");
 		
 		domStyle.set(this.cwrapper,{
@@ -227,7 +265,8 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 	},
 	
 	_showEnd: function(){
-		// summary: Common animation onEnd code - "unclose"
+		// summary:
+		//		Common animation onEnd code - "unclose"
 		domStyle.set(this.cwrapper, {
 			opacity: 0,
 			visibility:"visible"
@@ -245,7 +284,8 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 	},
 	
 	_hideEnd: function(){
-		// summary: Callback for the hide animation - "close"
+		// summary:
+		//		Callback for the hide animation - "close"
 
 		// every time we hide, reset the "only preview" state
 		if(!this._isonlypreview){
@@ -257,9 +297,9 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 		
 	},
 	
-	resize: function(/* Object? */newSize){
+	resize: function(/*Object?*/newSize){
 		// summary:
-		//		we aren't a layout widget, but need to act like one:
+		//		we aren't a layout widget, but need to act like one.
 		// newSize: Object
 		//		The size object to resize to
 
@@ -278,10 +318,12 @@ return declare("dojox.layout.ExpandoPane", [ContentPane, TemplatedMixin, Contain
 		}
 
 		this._layoutChildren();
+		this._setupAnims();
 	},
 	
-	_trap: function(e){
-		// summary: Trap stray events
+	_trap: function(/*Event*/ e){
+		// summary:
+		//		Trap stray events
 		eventUtil.stop(e);
 	}
 });
diff --git a/dojox/layout/FloatingPane.js b/dojox/layout/FloatingPane.js
index 6959486..5a5e0d2 100644
--- a/dojox/layout/FloatingPane.js
+++ b/dojox/layout/FloatingPane.js
@@ -2,26 +2,20 @@ define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/window","dojo/_base/de
 		"dojo/_base/fx","dojo/_base/connect","dojo/_base/array","dojo/_base/sniff",
 		"dojo/window","dojo/dom","dojo/dom-class","dojo/dom-geometry","dojo/dom-construct",
 		"dijit/_TemplatedMixin","dijit/_Widget","dijit/BackgroundIframe","dojo/dnd/Moveable",
-		"./ContentPane","./ResizeHandle","dojo/text!./resources/FloatingPane.html"], function(
+		"./ContentPane","./ResizeHandle","dojo/text!./resources/FloatingPane.html","./Dock"], function(
 	kernel, lang, winUtil, declare, baseFx, connectUtil, arrayUtil, 
 	has, windowLib, dom, domClass, domGeom, domConstruct, TemplatedMixin, Widget, BackgroundIframe, 
-	Moveable, ContentPane, ResizeHandle, template){
-
-/*=====
-var Widget = dijit._Widget;
-var TemplatedMixin = dijit._TemplatedMixin;
-var ContentPane = dojox.layout.ContentPane;
-=====*/
+	Moveable, ContentPane, ResizeHandle, template,Dock){
+	
 kernel.experimental("dojox.layout.FloatingPane");
 var FloatingPane = declare("dojox.layout.FloatingPane", [ ContentPane, TemplatedMixin ],{
 	// summary:
 	//		A non-modal Floating window.
-	//
 	// description:
 	//		Makes a `dojox.layout.ContentPane` float and draggable by it's title [similar to TitlePane]
 	//		and over-rides onClick to onDblClick for wipeIn/Out of containerNode
 	//		provides minimize(dock) / show() and hide() methods, and resize [almost]
-	//
+
 	// closable: Boolean
 	//		Allow closure of this Node
 	closable: true,
@@ -64,7 +58,7 @@ var FloatingPane = declare("dojox.layout.FloatingPane", [ ContentPane, Templated
 	=====*/
 
 	// contentClass: String
-	// 		The className to give to the inner node which has the content
+	//		The className to give to the inner node which has the content
 	contentClass: "dojoxFloatingPaneContent",
 
 	// animation holders for toggle
@@ -169,13 +163,15 @@ var FloatingPane = declare("dojox.layout.FloatingPane", [ ContentPane, Templated
 	},
 
 	setTitle: function(/* String */ title){
-		// summary: Update the Title bar with a new string
+		// summary:
+		//		Update the Title bar with a new string
 		kernel.deprecated("pane.setTitle", "Use pane.set('title', someTitle)", "2.0");
 		this.set("title", title);
 	},
 		
 	close: function(){
-		// summary: Close and destroy this widget
+		// summary:
+		//		Close and destroy this widget
 		if(!this.closable){ return; }
 		connectUtil.unsubscribe(this._listener);
 		this.hide(lang.hitch(this,function(){
@@ -184,7 +180,8 @@ var FloatingPane = declare("dojox.layout.FloatingPane", [ ContentPane, Templated
 	},
 
 	hide: function(/* Function? */ callback){
-		// summary: Close, but do not destroy this FloatingPane
+		// summary:
+		//		Close, but do not destroy this FloatingPane
 		baseFx.fadeOut({
 			node:this.domNode,
 			duration:this.duration,
@@ -202,7 +199,8 @@ var FloatingPane = declare("dojox.layout.FloatingPane", [ ContentPane, Templated
 	},
 
 	show: function(/* Function? */callback){
-		// summary: Show the FloatingPane
+		// summary:
+		//		Show the FloatingPane
 		var anim = baseFx.fadeIn({node:this.domNode, duration:this.duration,
 			beforeBegin: lang.hitch(this,function(){
 				this.domNode.style.display = "";
@@ -216,17 +214,21 @@ var FloatingPane = declare("dojox.layout.FloatingPane", [ ContentPane, Templated
 				}
 			})
 		}).play();
-		this.resize(domGeom.position(this.domNode));
+		// use w / h from content box dimensions and x / y from position
+		var contentBox = domGeom.getContentBox(this.domNode)
+		this.resize(lang.mixin(domGeom.position(this.domNode), {w: contentBox.w, h: contentBox.h}));
 		this._onShow(); // lazy load trigger
 	},
 
 	minimize: function(){
-		// summary: Hide and dock the FloatingPane
+		// summary:
+		//		Hide and dock the FloatingPane
 		if(!this._isDocked){ this.hide(lang.hitch(this,"_dock")); }
 	},
 
 	maximize: function(){
-		// summary: Make this FloatingPane full-screen (viewport)
+		// summary:
+		//		Make this FloatingPane full-screen (viewport)
 		if(this._maximized){ return; }
 		this._naturalState = domGeom.position(this.domNode);
 		if(this._isDocked){
@@ -254,7 +256,8 @@ var FloatingPane = declare("dojox.layout.FloatingPane", [ ContentPane, Templated
 	},
 	
 	resize: function(/* Object */dim){
-		// summary: Size the FloatingPane and place accordingly
+		// summary:
+		//		Size the FloatingPane and place accordingly
 		dim = dim || this._naturalState;
 		this._currentState = dim;
 
@@ -280,7 +283,8 @@ var FloatingPane = declare("dojox.layout.FloatingPane", [ ContentPane, Templated
 	},
 	
 	bringToTop: function(){
-		// summary: bring this FloatingPane above all other panes
+		// summary:
+		//		bring this FloatingPane above all other panes
 		var windows = arrayUtil.filter(
 			this._allFPs,
 			function(i){
@@ -300,7 +304,8 @@ var FloatingPane = declare("dojox.layout.FloatingPane", [ ContentPane, Templated
 	},
 	
 	destroy: function(){
-		// summary: Destroy this FloatingPane completely
+		// summary:
+		//		Destroy this FloatingPane completely
 		this._allFPs.splice(arrayUtil.indexOf(this._allFPs, this), 1);
 		if(this._resizeHandle){
 			this._resizeHandle.destroy();
@@ -309,94 +314,5 @@ var FloatingPane = declare("dojox.layout.FloatingPane", [ ContentPane, Templated
 	}
 });
 
-var Dock = declare("dojox.layout.Dock",[Widget, TemplatedMixin],{
-	// summary:
-	//		A widget that attaches to a node and keeps track of incoming / outgoing FloatingPanes
-	// 		and handles layout
-
-	templateString: '<div class="dojoxDock"><ul dojoAttachPoint="containerNode" class="dojoxDockList"></ul></div>',
-
-	// private _docked: array of panes currently in our dock
-	_docked: [],
-	
-	_inPositioning: false,
-	
-	autoPosition: false,
-	
-	addNode: function(refNode){
-		// summary: Instert a dockNode refernce into the dock
-		
-		var div = domConstruct.create('li', null, this.containerNode),
-			node = new DockNode({
-				title: refNode.title,
-				paneRef: refNode
-			}, div)
-		;
-		node.startup();
-		return node;
-	},
-
-	startup: function(){
-				
-		if (this.id == "dojoxGlobalFloatingDock" || this.isFixedDock) {
-			// attach window.onScroll, and a position like in presentation/dialog
-			this.connect(window, 'onresize', "_positionDock");
-			this.connect(window, 'onscroll', "_positionDock");
-			if(has("ie")){
-				this.connect(this.domNode, "onresize", "_positionDock");
-			}
-		}
-		this._positionDock(null);
-		this.inherited(arguments);
-
-	},
-	
-	_positionDock: function(/* Event? */e){
-		if(!this._inPositioning){
-			if(this.autoPosition == "south"){
-				// Give some time for scrollbars to appear/disappear
-				setTimeout(lang.hitch(this, function() {
-					this._inPositiononing = true;
-					var viewport = windowLib.getBox();
-					var s = this.domNode.style;
-					s.left = viewport.l + "px";
-					s.width = (viewport.w-2) + "px";
-					s.top = (viewport.h + viewport.t) - this.domNode.offsetHeight + "px";
-					this._inPositioning = false;
-				}), 125);
-			}
-		}
-	}
-
-
-});
-
-var DockNode = declare("dojox.layout._DockNode",[Widget, TemplatedMixin],{
-	// summary:
-	//		dojox.layout._DockNode is a private widget used to keep track of
-	//		which pane is docked.
-	//
-	// title: String
-	// 		Shown in dock icon. should read parent iconSrc?
-	title: "",
-
-	// paneRef: Widget
-	//		reference to the FloatingPane we reprasent in any given dock
-	paneRef: null,
-
-	templateString:
-		'<li dojoAttachEvent="onclick: restore" class="dojoxDockNode">'+
-			'<span dojoAttachPoint="restoreNode" class="dojoxDockRestoreButton" dojoAttachEvent="onclick: restore"></span>'+
-			'<span class="dojoxDockTitleNode" dojoAttachPoint="titleNode">${title}</span>'+
-		'</li>',
-
-	restore: function(){
-		// summary: remove this dock item from parent dock, and call show() on reffed floatingpane
-		this.paneRef.show();
-		this.paneRef.bringToTop();
-		this.destroy();
-	}
-});
-
 return FloatingPane;
 });
\ No newline at end of file
diff --git a/dojox/layout/GridContainer.js b/dojox/layout/GridContainer.js
index fe5c8f0..de381cf 100644
--- a/dojox/layout/GridContainer.js
+++ b/dojox/layout/GridContainer.js
@@ -1,26 +1,31 @@
 define([
 	"dojo/_base/kernel",
+	"dojo/_base/declare", // declare 
 	"dojo/_base/array",
 	"dojo/_base/connect",
-	"dojo/_base/declare",
-	"dojo/_base/html",
+	"dojo/_base/sniff",
+	"dojo/dom-class",
+	"dojo/dom-style",
+	"dojo/dom-geometry",
+	"dojo/dom-construct",
 	"dojo/_base/lang",
 	"dojo/_base/window",
 	"dojo/ready",	// dojo.ready
 	"dojox/layout/GridContainerLite"
-],function(dojo){
-	return dojo.declare(
+],function(dojo, declare, array, connect, has, domClass, domStyle, geom, domConstruct, lang, win, ready, GridContainerLite){
+	return declare(
 		"dojox.layout.GridContainer",
-		dojox.layout.GridContainerLite,
+		GridContainerLite,
 	{
 		// summary:
 		//		A grid containing any kind of objects and acting like web portals.
 		//
 		// description:
 		//		This component inherits of all features of gridContainerLite plus :
-		//			- Resize colums
-		//			- Add / remove columns
-		//			- Fix columns at left or at right.
+		//
+		//		- Resize colums
+		//		- Add / remove columns
+		//		- Fix columns at left or at right.
 		// example:
 		// 	|	<div dojoType="dojox.layout.GridContainer" nbZones="3" isAutoOrganized="true">
 		// 	|		<div dojoType="dijit.layout.ContentPane">Content Pane 1 : Drag Me !</div>
@@ -57,7 +62,7 @@ define([
 		minColWidth: 20,
 
 		// minChildWidth: Integer
-		// 		Minimum children width in pixel (only used for IE6 which doesn't handle min-width css property)
+		//		Minimum children width in pixel (only used for IE6 which doesn't handle min-width css property)
 		minChildWidth: 150,
 
 		// mode: String
@@ -92,7 +97,7 @@ define([
 					//		The CSS property height:100% for the grip
 					//		doesn't work anytime. It's necessary to wait
 					//		the end of loading before to place grips.
-					dojo.ready(dojo.hitch(this, "_placeGrips"));
+					ready(lang.hitch(this, "_placeGrips"));
 				}
 			}
 		},
@@ -107,7 +112,7 @@ define([
 			// targetArea:
 			//		AreaManager Object containing information of targetArea
 			// indexChild:
-			// 		Index where the dropped widget has been placed
+			//		Index where the dropped widget has been placed
 
 			if(this.inherited(arguments)){
 				this._placeGrips();
@@ -136,7 +141,7 @@ define([
 			//		IE6 calls method resize itself.
 			//		If the GridContainer is not visible at this time,
 			//		the method _placeGrips can return a negative value with
-			// 		contentBox method. (see method _placeGrip() with Fix Ie6 for the height)
+			//		contentBox method. (see method _placeGrip() with Fix Ie6 for the height)
 			if(this._isShown() && this.hasResizableColumns){
 				this._placeGrips();
 			}
@@ -152,26 +157,24 @@ define([
 
 			//console.log("dojox.layout.GridContainer ::: _createGrip");
 			var dropZone = this._grid[index],
-				grip = dojo.create("div", { 'class': "gridContainerGrip" }, this.domNode);
+				grip = domConstruct.create("div", { 'class': "gridContainerGrip" }, this.domNode);
 			dropZone.grip = grip;
 			dropZone.gripHandler = [
 				this.connect(grip, "onmouseover", function(e){
 					var gridContainerGripShow = false;
 					for(var i = 0; i < this._grid.length - 1; i++){
-						if(dojo.hasClass(this._grid[i].grip, "gridContainerGripShow")){
+						if(domClass.contains(this._grid[i].grip, "gridContainerGripShow")){
 							gridContainerGripShow = true;
 							break;
 						}
 					}
 					if(!gridContainerGripShow){
-						dojo.removeClass(e.target, "gridContainerGrip");
-						dojo.addClass(e.target, "gridContainerGripShow");
+						domClass.replace(e.target, "gridContainerGripShow", "gridContainerGrip");
 					}
 				})[0],
 				this.connect(grip, "onmouseout", function(e){
 					if(!this._isResized){
-						dojo.removeClass(e.target, "gridContainerGripShow");
-						dojo.addClass(e.target, "gridContainerGrip");
+						domClass.replace(e.target, "gridContainerGrip", "gridContainerGripShow");
 					}
 				})[0],
 				this.connect(grip, "onmousedown", "_resizeColumnOn")[0],
@@ -187,24 +190,24 @@ define([
 
 			//console.log("dojox.layout.GridContainer ::: _placeGrips");
 			var gripWidth, height, left = 0, grip;
-			var scroll = this.domNode.style.overflowY;
+			//var scroll = this.domNode.style.overflowY;
 
-			dojo.forEach(this._grid, function(dropZone){
+			array.forEach(this._grid, function(dropZone){
 				if(dropZone.grip){
 					grip = dropZone.grip;
 					if(!gripWidth){
 						gripWidth = grip.offsetWidth / 2;
 					}
 
-					left += dojo.marginBox(dropZone.node).w;
+					left += geom.getMarginBox(dropZone.node).w;
 
-					dojo.style(grip, "left", (left - gripWidth) + "px");
+					domStyle.set(grip, "left", (left - gripWidth) + "px");
 					//if(dojo.isIE == 6){ do it fot all navigators
 					if(!height){
-						height = dojo.contentBox(this.gridNode).h;
+						height = geom.getContentBox(this.gridNode).h;
 					}
 					if(height > 0){
-						dojo.style(grip, "height", height + "px");
+						domStyle.set(grip, "height", height + "px");
 					}
 					//}
 				}
@@ -236,7 +239,7 @@ define([
 			this._initX = e.pageX;
 			e.preventDefault();
 
-			dojo.body().style.cursor = "ew-resize";
+			win.body().style.cursor = "ew-resize";
 
 			this._isResized = true;
 
@@ -245,7 +248,7 @@ define([
 			var i;
 
 			for(i = 0; i < this._grid.length; i++){
-				tabSize[i] = dojo.contentBox(this._grid[i].node).w;
+				tabSize[i] = geom.getContentBox(this._grid[i].node).w;
 			}
 
 			this._oldTabSize = tabSize;
@@ -266,10 +269,10 @@ define([
 				var width = 0;
 				var childMinWidth = 0;
 
-				dojo.forEach(childNodes, function(child){
+				array.forEach(childNodes, function(child){
 					if(child.nodeType == 1){
-						var objectStyle = dojo.getComputedStyle(child);
-						var minWidth = (dojo.isIE) ? minChild : parseInt(objectStyle.minWidth);
+						var objectStyle = domStyle.getComputedStyle(child);
+						var minWidth = (has("ie")) ? minChild : parseInt(objectStyle.minWidth);
 
 						childMinWidth = minWidth +
 									parseInt(objectStyle.marginLeft) +
@@ -281,12 +284,12 @@ define([
 					}
 				});
 				return width;
-			}
+			};
 			var currentColumnMinWidth = calculateChildMinWidth(this._currentColumn.childNodes, this.minChildWidth);
 
 			var nextColumnMinWidth = calculateChildMinWidth(this._nextColumn.childNodes, this.minChildWidth);
 
-			var minPix = Math.round((dojo.marginBox(this.gridContainerTable).w * this.minColWidth) / 100);
+			var minPix = Math.round((geom.getMarginBox(this.gridContainerTable).w * this.minColWidth) / 100);
 
 			this._currentMinCol = currentColumnMinWidth;
 			this._nextMinCol = nextColumnMinWidth;
@@ -297,8 +300,8 @@ define([
 			if(minPix > this._nextMinCol){
 				this._nextMinCol = minPix;
 			}
-			this._connectResizeColumnMove = dojo.connect(dojo.doc, "onmousemove", this, "_resizeColumnMove");
-			this._connectOnGripMouseUp = dojo.connect(dojo.doc, "onmouseup", this, "_onGripMouseUp");
+			this._connectResizeColumnMove = connect.connect(win.doc, "onmousemove", this, "_resizeColumnMove");
+			this._connectOnGripMouseUp = connect.connect(win.doc, "onmouseup", this, "_onGripMouseUp");
 		},
 
 		_onGripMouseUp: function(){
@@ -308,16 +311,15 @@ define([
 			//		callback
 
 			//console.log(dojox.layout.GridContainer ::: _onGripMouseUp");
-			dojo.body().style.cursor = "default";
+			win.body().style.cursor = "default";
 
-			dojo.disconnect(this._connectResizeColumnMove);
-			dojo.disconnect(this._connectOnGripMouseUp);
+			connect.disconnect(this._connectResizeColumnMove);
+			connect.disconnect(this._connectOnGripMouseUp);
 
 			this._connectOnGripMouseUp = this._connectResizeColumnMove = null;
 
 			if(this._activeGrip){
-				dojo.removeClass(this._activeGrip, "gridContainerGripShow");
-				dojo.addClass(this._activeGrip, "gridContainerGrip");
+				domClass.replace(this._activeGrip, "gridContainerGrip", "gridContainerGripShow");
 			}
 
 			this._isResized = false;
@@ -332,9 +334,9 @@ define([
 			//console.log("dojox.layout.GridContainer ::: _resizeColumnMove");
 			e.preventDefault();
 			if(!this._connectResizeColumnOff){
-				dojo.disconnect(this._connectOnGripMouseUp);
+				connect.disconnect(this._connectOnGripMouseUp);
 				this._connectOnGripMouseUp = null;
-				this._connectResizeColumnOff = dojo.connect(dojo.doc, "onmouseup", this, "_resizeColumnOff");
+				this._connectResizeColumnOff = connect.connect(win.doc, "onmouseup", this, "_resizeColumnOff");
 			}
 
 			var d = e.pageX - this._initX;
@@ -364,10 +366,10 @@ define([
 			//		callback
 
 			//console.log("dojox.layout.GridContainer ::: _resizeColumnOff");
-			dojo.body().style.cursor = "default";
+			win.body().style.cursor = "default";
 
-			dojo.disconnect(this._connectResizeColumnMove);
-			dojo.disconnect(this._connectResizeColumnOff);
+			connect.disconnect(this._connectResizeColumnMove);
+			connect.disconnect(this._connectResizeColumnOff);
 
 			this._connectResizeColumnOff = this._connectResizeColumnMove = null;
 
@@ -386,12 +388,12 @@ define([
 
 			for(i = 0; i < this._grid.length; i++){
 				node = this._grid[i].node;
-				if(dojo.isIE){
-					tabSize[i] = dojo.marginBox(node).w;
-					testSize[i] = dojo.contentBox(node).w;
+				if(has("ie")){
+					tabSize[i] = geom.getMarginBox(node).w;
+					testSize[i] = geom.getContentBox(node).w;
 				}
 				else{
-					tabSize[i] = dojo.contentBox(node).w;
+					tabSize[i] = geom.getContentBox(node).w;
 					testSize = tabSize;
 				}
 			}
@@ -404,7 +406,7 @@ define([
 			}
 
 			if(update){
-				var mul = dojo.isIE ? 100 : 10000;
+				var mul = has("ie") ? 100 : 10000;
 				for(i = 0; i < this._grid.length; i++){
 					this._grid[i].node.style.width = Math.round((100 * mul * tabSize[i]) / tabWidth) / mul + "%";
 				}
@@ -412,8 +414,7 @@ define([
 			}
 
 			if(this._activeGrip){
-				dojo.removeClass(this._activeGrip, "gridContainerGripShow");
-				dojo.addClass(this._activeGrip, "gridContainerGrip");
+				domClass.replace(this._activeGrip, "gridContainerGrip", "gridContainerGripShow");
 			}
 
 			this._isResized = false;
@@ -453,7 +454,7 @@ define([
 							}
 						}
 						if(count.length < delta){
-							dojo.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]);
+							connect.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]);
 						}
 					}
 					else{ // mode = "left"
@@ -476,7 +477,7 @@ define([
 						}
 						if(count.length < delta){
 							//Not enough empty columns
-							dojo.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]);
+							connect.publish("/dojox/layout/gridContainer/noEmptyColumn", [this]);
 						}
 					}
 				}
@@ -514,7 +515,7 @@ define([
 			for(var i = 0; i < nbColumns; i++){
 				// Fix CODEX defect #53025 :
 				//		Apply acceptType attribute on each new column.
-				node = dojo.create("td", {
+				node = domConstruct.create("td", {
 					'class': "gridContainerZone dojoxDndArea" ,
 					'accept': accept,
 					'id': this.id + "_dz" + this.nbZones
@@ -583,15 +584,15 @@ define([
 				grid = this._grid[index];
 
 				if(this.hasResizableColumns && grid.grip){
-					dojo.forEach(grid.gripHandler, function(handler){
-						dojo.disconnect(handler);
+					array.forEach(grid.gripHandler, function(handler){
+						connect.disconnect(handler);
 					});
-					dojo.destroy(this.domNode.removeChild(grid.grip));
+					domConstruct.destroy(this.domNode.removeChild(grid.grip));
 					grid.grip = null;
 				}
 
 				m.unregister(grid.node);
-				dojo.destroy(this.gridNode.removeChild(grid.node));
+				domConstruct.destroy(this.gridNode.removeChild(grid.node));
 				this._grid.splice(index, 1);
 				this.nbZones--;
 				nbDelZones++;
@@ -600,8 +601,8 @@ define([
 			// last grip
 			var lastGrid = this._grid[this.nbZones-1];
 			if(lastGrid.grip){
-				dojo.forEach(lastGrid.gripHandler, dojo.disconnect);
-				dojo.destroy(this.domNode.removeChild(lastGrid.grip));
+				array.forEach(lastGrid.gripHandler, connect.disconnect);
+				domConstruct.destroy(this.domNode.removeChild(lastGrid.grip));
 				lastGrid.grip = null;
 			}
 
@@ -622,7 +623,7 @@ define([
 		},
 
 		destroy: function(){
-			dojo.unsubscribe(this._dropHandler);
+			connect.unsubscribe(this._dropHandler);
 			this.inherited(arguments);
 		}
 	});
diff --git a/dojox/layout/GridContainerLite.js b/dojox/layout/GridContainerLite.js
index e234d20..935a4c2 100644
--- a/dojox/layout/GridContainerLite.js
+++ b/dojox/layout/GridContainerLite.js
@@ -1,26 +1,41 @@
-define(["dojo/_base/kernel",
+define([
+	"dojo/_base/kernel",
 	"dojo/text!./resources/GridContainer.html",
-	"dojo/ready",
-	"dojo/_base/array","dojo/_base/lang",
-	"dojo/_base/declare","dojo/text","dojo/_base/sniff","dojo/_base/html",
-	"dojox/mdnd/AreaManager","dojox/mdnd/DropIndicator",
-	"dojox/mdnd/dropMode/OverDropMode","dojox/mdnd/AutoScroll","dijit/_Templated",
+	"dojo/_base/declare", // declare
+	"dojo/query",
+	"dojo/_base/sniff",
+	"dojo/dom-class",
+	"dojo/dom-style",
+	"dojo/dom-geometry",
+	"dojo/dom-construct",
+	"dojo/dom-attr", // domAttr.get
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/event",
+	"dojo/keys", // keys
+	"dojo/topic", // topic.publish()
+	"dijit/registry",
+	"dijit/focus",
+	"dijit/_base/focus", // dijit.getFocus()
+	"dijit/_WidgetBase",
+	"dijit/_TemplatedMixin",
 	"dijit/layout/_LayoutWidget",
-	"dijit/focus",			// dijit.focus()
-	"dijit/_base/focus"		// dijit.getFocus()
-],function(dojo,template){
+	"dojo/_base/NodeList",
+	"dojox/mdnd/AreaManager", "dojox/mdnd/DropIndicator",
+	"dojox/mdnd/dropMode/OverDropMode","dojox/mdnd/AutoScroll"
+],function(dojo, template, declare, query, has, domClass, domStyle, geom, domConstruct, domAttr, array, lang, events, keys, topic, registry, focus, baseFocus, _WidgetBase, _TemplatedMixin, _LayoutWidget, NodeList){
 
-	var gcl = dojo.declare(
+	var gcl = declare(
 		"dojox.layout.GridContainerLite",
-		[dijit.layout._LayoutWidget, dijit._TemplatedMixin],
+		[_LayoutWidget, _TemplatedMixin],
 	{
 		// summary:
-		// 		The GridContainerLite is a container of child elements that are placed in a kind of grid.
+		//		The GridContainerLite is a container of child elements that are placed in a kind of grid.
 		//
 		// description:
 		//		GridContainerLite displays the child elements by column
 		//		(ie: the children widths are fixed by the column width of the grid but
-		//              the children heights are free).
+		//		the children heights are free).
 		//		Each child is movable by drag and drop inside the GridContainer.
 		//		The position of other children is automatically calculated when a child is moved.
 		//
@@ -55,7 +70,7 @@ define(["dojo/_base/kernel",
 		// 	|		widget.startup();
 		// 	|	});
 
-		//	autoRefresh: Boolean
+		// autoRefresh: Boolean
 		//		Enable the refresh of registered areas on drag start.
 		autoRefresh: true,
 
@@ -64,7 +79,7 @@ define(["dojo/_base/kernel",
 		//		template of gridContainer.
 		templateString: template,
 
-		// dragHandleClass: Array :
+		// dragHandleClass: Array
 		//		CSS class enabling a drag handle on a child.
 		dragHandleClass: "dojoxDragHandle",
 
@@ -116,17 +131,13 @@ define(["dojo/_base/kernel",
 
 			if(this.doLayout){
 				this._border = {
-					'h':(dojo.isIE) ? dojo._getBorderExtents(this.gridContainerTable).h : 0,
-					'w': (dojo.isIE == 6) ? 1 : 0
-				}
-			}
-			else{
-				dojo.style(this.domNode, "overflowY", "hidden");
-				dojo.style(this.gridContainerTable, "height", "auto");
+					h: has("ie") ? geom.getBorderExtents(this.gridContainerTable).h : 0,
+					w: (has("ie") == 6) ? 1 : 0
+				};
+			}else{
+				domStyle.set(this.domNode, "overflowY", "hidden");
+				domStyle.set(this.gridContainerTable, "height", "auto");
 			}
-			// Call postCreate of dijit.layout._LayoutWidget.
-			this.inherited(arguments);
-
 		},
 
 		startup: function(){
@@ -142,7 +153,9 @@ define(["dojo/_base/kernel",
 
 			// Need to call getChildren because getChildren return null
 			// The children are not direct children because of _organizeChildren method
-			dojo.forEach(this.getChildren(), function(child){ child.startup(); });
+			array.forEach(this.getChildren(), function(child){
+			  child.startup();
+			});
 
 			// Need to enable the Drag And Drop only if the GridContainer is visible.
 			if(this._isShown()){
@@ -163,7 +176,7 @@ define(["dojo/_base/kernel",
 			// targetArea:
 			//		AreaManager Object containing information of targetArea
 			// indexChild:
-			// 		Index where the dropped widget has been placed
+			//		Index where the dropped widget has been placed
 			// returns:
 			//		True if resized.
 
@@ -171,9 +184,9 @@ define(["dojo/_base/kernel",
 			if(this._disabled){
 				return false;
 			}
-			if(dijit.getEnclosingWidget(targetArea.node) == this){
-				var widget = dijit.byNode(node);
-				if(widget.resize && dojo.isFunction(widget.resize)){
+			if(registry.getEnclosingWidget(targetArea.node) == this){
+				var widget = registry.byNode(node);
+				if(widget.resize && lang.isFunction(widget.resize)){
 					widget.resize();
 				}
 
@@ -182,9 +195,9 @@ define(["dojo/_base/kernel",
 
 				if(this.doLayout){
 					var domNodeHeight = this._contentBox.h,
-						divHeight = dojo.contentBox(this.gridContainerDiv).h;
+						divHeight = geom.getContentBox(this.gridContainerDiv).h;
 					if(divHeight >= domNodeHeight){
-						dojo.style(this.gridContainerTable, "height",
+						domStyle.set(this.gridContainerTable, "height",
 								(domNodeHeight - this._border.h) + "px");
 					}
 				}
@@ -202,17 +215,17 @@ define(["dojo/_base/kernel",
 			// sourceArea:
 			//		AreaManager Object containing information of sourceArea
 			// indexChild:
-			// 		Index where the dragged widget has been placed
+			//		Index where the dragged widget has been placed
 
 			//console.log("dojox.layout.GridContainerLite ::: resizeChildAfterDragStart");
 			if(this._disabled){
 				return false;
 			}
-			if(dijit.getEnclosingWidget(sourceArea.node) == this){
+			if(registry.getEnclosingWidget(sourceArea.node) == this){
 				this._draggedNode = node;
 				if(this.doLayout){
-					dojo.marginBox(this.gridContainerTable, {
-						'h': dojo.contentBox(this.gridContainerDiv).h - this._border.h
+					geom.setMarginBox(this.gridContainerTable, {
+						h: geom.getContentBox(this.gridContainerDiv).h - this._border.h
 					});
 				}
 				return true;
@@ -224,14 +237,15 @@ define(["dojo/_base/kernel",
 			// summary:
 			//		A specific method which returns children after they were placed in zones.
 			// returns:
-			//		An array containing all children (widgets).
+			//		A NodeList containing all children (widgets).
 			// tags:
 			//		protected
 
-			//console.log("dojox.layout.GridContainerLite ::: _getChildren");
-			var children = [];
-			dojo.forEach(this._grid, function(dropZone){
-				children = children.concat(dojo.query("> [widgetId]", dropZone.node).map(dijit.byNode));
+			var children = new NodeList();
+			array.forEach(this._grid, function(dropZone){
+				query("> [widgetId]", dropZone.node).map(registry.byNode).forEach(function(item){
+				  children.push(item);
+				});
 			});
 			return children;	// Array
 		},
@@ -250,7 +264,7 @@ define(["dojo/_base/kernel",
 			}
 			else{
 				var node = this.domNode;
-				return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !dojo.hasClass(node, "dijitHidden"); // Boolean
+				return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !domClass.contains(node, "dijitHidden"); // Boolean
 			}
 		},
 
@@ -261,15 +275,15 @@ define(["dojo/_base/kernel",
 			//console.log("dojox.layout.GridContainerLite ::: layout");
 			if(this.doLayout){
 				var contentBox = this._contentBox;
-				dojo.marginBox(this.gridContainerTable, {
-					'h': contentBox.h - this._border.h
+				geom.setMarginBox(this.gridContainerTable, {
+					h: contentBox.h - this._border.h
 				});
-				dojo.contentBox(this.domNode, {
-					'w': contentBox.w - this._border.w
+				geom.setContentSize(this.domNode, {
+					w: contentBox.w - this._border.w
 				});
 			}
-			dojo.forEach(this.getChildren(), function(widget){
-				if(widget.resize && dojo.isFunction(widget.resize)){
+			array.forEach(this.getChildren(), function(widget){
+				if(widget.resize && lang.isFunction(widget.resize)){
 					widget.resize();
 				}
 			});
@@ -306,34 +320,17 @@ define(["dojo/_base/kernel",
 			var accept = this.acceptTypes.join(","),
 				i = 0;
 
-			var origWidths = this.colWidths || [];
-			var widths = [];
-			var colWidth;
-			var widthSum = 0;
-
-			// Calculate the widths of each column.
-			for(i = 0; i < this.nbZones; i++){
-				if(widths.length < origWidths.length){
-					widthSum += origWidths[i];
-					widths.push(origWidths[i]);
-				}else{
-					if(!colWidth){
-						colWidth = (100 - widthSum)/(this.nbZones - i);
-					}
-					widths.push(colWidth);
-				}
-			}
+			var widths = this._computeColWidth();
 
-			i = 0;
 			while(i < this.nbZones){
 				// Add the parameter accept in each zone used by AreaManager
 				// (see method dojox.mdnd.AreaManager:registerByNode)
 				this._grid.push({
-					'node': dojo.create("td", {
+					node: domConstruct.create("td", {
 						'class': "gridContainerZone",
-						'accept': accept,
-						'id': this.id + "_dz" + i,
-						'style': {
+						accept: accept,
+						id: this.id + "_dz" + i,
+						style: {
 							'width': widths[i] + "%"
 						}
 					}, this.gridNode)
@@ -344,8 +341,8 @@ define(["dojo/_base/kernel",
 
 		_getZonesAttr: function(){
 			// summary:
-			//   return array of zone (domNode)
-			return dojo.query(".gridContainerZone",  this.containerNode);
+			//		return array of zone (domNode)
+			return query(".gridContainerZone",  this.containerNode);
 		},
 
 		enableDnd: function(){
@@ -354,7 +351,7 @@ define(["dojo/_base/kernel",
 
 			//console.log("dojox.layout.GridContainerLite ::: enableDnd");
 			var m = this._dragManager;
-			dojo.forEach(this._grid, function(dropZone){
+			array.forEach(this._grid, function(dropZone){
 				m.registerByNode(dropZone.node);
 			});
 			m._dropMode.updateAreas(m._areaList);
@@ -367,7 +364,7 @@ define(["dojo/_base/kernel",
 
 			//console.log("dojox.layout.GridContainerLite ::: disableDnd");
 			var m = this._dragManager;
-			dojo.forEach(this._grid, function(dropZone){
+			array.forEach(this._grid, function(dropZone){
 				m.unregister(dropZone.node);
 			});
 			m._dropMode.updateAreas(m._areaList);
@@ -438,20 +435,20 @@ define(["dojo/_base/kernel",
 			//console.log("dojox.layout.GridContainerLite ::: _insertChild", child, column, p);
 			var zone = this._grid[column].node,
 				length = zone.childNodes.length;
-			if(typeof(p) == undefined || p > length){
+			if(typeof p === "undefined" || p > length){
 				p = length;
 			}
 			if(this._disabled){
-				dojo.place(child.domNode, zone, p);
-				dojo.attr(child.domNode, "tabIndex", "0");
+				domConstruct.place(child.domNode, zone, p);
+				domAttr.set(child.domNode, "tabIndex", "0");
 			}
 			else{
 				if(!child.dragRestriction){
 					this._dragManager.addDragItem(zone, child.domNode, p, true);
 				}
 				else{
-					dojo.place(child.domNode, zone, p);
-					dojo.attr(child.domNode, "tabIndex", "0");
+					domConstruct.place(child.domNode, zone, p);
+					domAttr.set(child.domNode, "tabIndex", "0");
 				}
 			}
 			child.set("column", column);
@@ -470,7 +467,7 @@ define(["dojo/_base/kernel",
 
 		addService: function(/*Object*/child, /*Integer?*/column, /*Integer?*/p){
 			//console.log("dojox.layout.GridContainerLite ::: addService");
-			dojo.deprecated("addService is deprecated.", "Please use  instead.", "Future");
+			kernel.deprecated("addService is deprecated.", "Please use  instead.", "Future");
 			this.addChild(child, column, p);
 		},
 
@@ -489,7 +486,7 @@ define(["dojo/_base/kernel",
 			//console.log("dojox.layout.GridContainerLite ::: addChild");
 			child.domNode.id = child.id;
 			dojox.layout.GridContainerLite.superclass.addChild.call(this, child, 0);
-			if(column < 0 || column == undefined){ column = 0; }
+			if(column < 0 || column === undefined){ column = 0; }
 			if(p <= 0){ p = 0; }
 			try{
 				return this._insertChild(child, column, p);
@@ -501,7 +498,7 @@ define(["dojo/_base/kernel",
 		},
 
 		_setColWidthsAttr: function(value){
-			this.colWidths = dojo.isString(value) ? value.split(",") : (dojo.isArray(value) ? value : [value]);
+			this.colWidths = lang.isString(value) ? value.split(",") : (lang.isArray(value) ? value : [value]);
 
 			if(this._started){
 				this._updateColumnsWidth();
@@ -519,6 +516,15 @@ define(["dojo/_base/kernel",
 			//console.log("dojox.layout.GridContainer ::: _updateColumnsWidth");
 			var length = this._grid.length;
 
+			var widths = this._computeColWidth();
+
+			// Set the widths of each node
+			for (var i = 0; i < length; i++){
+				this._grid[i].node.style.width = widths[i] + "%";
+			}
+		},
+
+		_computeColWidth: function(){
 			var origWidths = this.colWidths || [];
 			var widths = [];
 			var colWidth;
@@ -526,7 +532,7 @@ define(["dojo/_base/kernel",
 			var i;
 
 			// Calculate the widths of each column.
-			for(i = 0; i < length; i++){
+			for(i = 0; i < this.nbZones; i++){
 				if(widths.length < origWidths.length){
 					widthSum += origWidths[i] * 1;
 					widths.push(origWidths[i]);
@@ -553,11 +559,7 @@ define(["dojo/_base/kernel",
 					widths[i] *= divisor;
 				}
 			}
-
-			// Set the widths of each node
-			for(i = 0; i < length; i++){
-				this._grid[i].node.style.width = widths[i] + "%";
-			}
+			return widths;
 		},
 
 		_selectFocus: function(/*Event*/event){
@@ -571,10 +573,10 @@ define(["dojo/_base/kernel",
 			//console.log("dojox.layout.GridContainerLite ::: _selectFocus");
 			if(this._disabled){ return; }
 			var key = event.keyCode,
-				k = dojo.keys,
+				k = keys,
 				zone = null,
-				focus = dijit.getFocus(),
-				focusNode = focus.node,
+				cFocus = baseFocus.getFocus(),
+				focusNode = cFocus.node,
 				m = this._dragManager,
 				found,
 				i,
@@ -593,16 +595,16 @@ define(["dojo/_base/kernel",
 							children = area[i].childNodes;
 							for(j = 0; j < children.length; j++){
 								zone = children[j];
-								if(zone != null && zone.style.display != "none"){
-									dijit.focus(zone);
-									dojo.stopEvent(event);
+								if(zone !== null && zone.style.display != "none"){
+									focus.focus(zone);
+									events.stop(event);
 									found = true;
 									break;
 								}
 							}
 							if(found){ break };
 						}
-					break;
+						break;
 					case k.UP_ARROW:
 					case k.LEFT_ARROW:
 						area = this.gridNode.childNodes;
@@ -611,9 +613,9 @@ define(["dojo/_base/kernel",
 							children = area[i].childNodes;
 							for(j = children.length; j >= 0; j--){
 								zone = children[j];
-								if(zone != null && zone.style.display != "none"){
-									dijit.focus(zone);
-									dojo.stopEvent(event);
+								if(zone !== null && zone.style.display != "none"){
+									focus.focus(zone);
+									events.stop(event);
 									found = true;
 									break;
 								}
@@ -622,26 +624,25 @@ define(["dojo/_base/kernel",
 						}
 					break;
 				}
-			}
-			else{
+			}else{
 				if(focusNode.parentNode.parentNode == this.gridNode){
 					var child = (key == k.UP_ARROW || key == k.LEFT_ARROW) ? "lastChild" : "firstChild";
 					var pos = (key == k.UP_ARROW || key == k.LEFT_ARROW) ? "previousSibling" : "nextSibling";
 					switch(key){
 						case k.UP_ARROW:
 						case k.DOWN_ARROW:
-							dojo.stopEvent(event);
+							events.stop(event);
 							found = false;
 							var focusTemp = focusNode;
 							while(!found){
 								children = focusTemp.parentNode.childNodes;
 								var num = 0;
 								for(i = 0; i < children.length; i++){
-									if(children[i].style.display != "none"){ num++ };
+									if(children[i].style.display != "none"){ num++; }
 									if(num > 1){ break; }
 								}
 								if(num == 1){ return; }
-								if(focusTemp[pos] == null){
+								if(focusTemp[pos] === null){
 									zone = focusTemp.parentNode[child];
 								}
 								else{
@@ -667,30 +668,30 @@ define(["dojo/_base/kernel",
 										break;
 									}
 								}
-								if(dojo.isMoz || dojo.isWebKit){ i-- };
+								if(has("mozilla") || has("webkit")){ i--; }
 
-								widget = dijit.byNode(focusNode);
+								widget = registry.byNode(focusNode);
 								if(!widget.dragRestriction){
 									r = m.removeDragItem(parent, focusNode);
 									this.addChild(widget, i, j);
-									dojo.attr(focusNode, "tabIndex", "0");
-									dijit.focus(focusNode);
+									domAttr.set(focusNode, "tabIndex", "0");
+									focus.focus(focusNode);
 								}
 								else{
-									dojo.publish("/dojox/layout/gridContainer/moveRestriction", [this]);
+									topic.publish("/dojox/layout/gridContainer/moveRestriction", this);
 								}
 							}
 							else{
-								dijit.focus(zone);
+								focus.focus(zone);
 							}
 						break;
 						case k.RIGHT_ARROW:
 						case k.LEFT_ARROW:
-							dojo.stopEvent(event);
+							events.stop(event);
 							if(event.shiftKey){
 								var z = 0;
-								if(focusNode.parentNode[pos] == null){
-									if(dojo.isIE && key == k.LEFT_ARROW){
+								if(focusNode.parentNode[pos] === null){
+									if(has("ie") && key == k.LEFT_ARROW){
 										z = this.gridNode.childNodes.length-1;
 									}
 								}
@@ -704,11 +705,11 @@ define(["dojo/_base/kernel",
 										}
 										z++;
 									}
-									if(dojo.isMoz || dojo.isWebKit){ z-- };
+									if(has("mozilla") || has("webkit")){ z--; }
 								}
-								widget = dijit.byNode(focusNode);
+								widget = registry.byNode(focusNode);
 								var _dndType = focusNode.getAttribute("dndtype");
-								if(_dndType == null){
+								if(_dndType === null){
 									//check if it's a dijit object
 									if(widget && widget.dndType){
 										_dndType = widget.dndType.split(/\s*,\s*/);
@@ -734,17 +735,17 @@ define(["dojo/_base/kernel",
 										place = 0;
 									if(k.LEFT_ARROW == key){
 										var t = z;
-										if(dojo.isMoz || dojo.isWebKit){ t = z + 1 };
+										if(has("mozilla") || has("webkit")){ t = z + 1; }
 										place = this.gridNode.childNodes[t].childNodes.length;
 									}
 									// delete of manager :
 									r = m.removeDragItem(parentSource, focusNode);
 									this.addChild(widget, z, place);
-									dojo.attr(r, "tabIndex", "0");
-									dijit.focus(r);
+									domAttr.set(r, "tabIndex", "0");
+									focus.focus(r);
 								}
 								else{
-									dojo.publish("/dojox/layout/gridContainer/moveRestriction", [this]);
+									topic.publish("/dojox/layout/gridContainer/moveRestriction", this);
 								}
 							}
 							else{
@@ -758,7 +759,7 @@ define(["dojo/_base/kernel",
 											node = node.parentNode.childNodes[node.parentNode.childNodes.length-1];
 										}
 										else{
-											node = (dojo.isIE)? node.parentNode.childNodes[0]: node.parentNode.childNodes[1];
+											node = node.parentNode.childNodes[has("ie") ? 0 : 1];
 										}
 									}
 									zone = node[child];
@@ -792,7 +793,7 @@ define(["dojo/_base/kernel",
 										}
 									}
 								}
-								dijit.focus(zone);
+								focus.focus(zone);
 							}
 						break;
 					}
@@ -803,24 +804,30 @@ define(["dojo/_base/kernel",
 		destroy: function(){
 			//console.log("dojox.layout.GridContainerLite ::: destroy");
 			var m = this._dragManager;
-			dojo.forEach(this._grid, function(dropZone){
+			array.forEach(this._grid, function(dropZone){
 				m.unregister(dropZone.node);
 			});
 			this.inherited(arguments);
 		}
 	});
 
-	dojo.extend(dijit._Widget, {
+	gcl.ChildWidgetProperties = {
+		// summary:
+		//		Properties set on children of a GridContainerLite
 
 		// column: String
 		//		Column of the grid to place the widget.
 		//		Defined only if dojo.require("dojox.layout.GridContainerLite") is done.
-		column : "1",
+		column: "1",
 
 		// dragRestriction: Boolean
 		//		If true, the widget can not be draggable.
 		//		Defined only if dojo.require("dojox.layout.GridContainerLite") is done.
-		dragRestriction : false
-	});
+		dragRestriction: false
+	};
+
+	// Add to widget base for benefit of parser.   Remove for 2.0.   Also, hide from doc viewer.
+	lang.extend(_WidgetBase, /*===== {} || =====*/ gcl.ChildWidgetProperties);
+
 	return gcl;
-});
\ No newline at end of file
+});
diff --git a/dojox/layout/RadioGroup.js b/dojox/layout/RadioGroup.js
index cacaed1..e829692 100644
--- a/dojox/layout/RadioGroup.js
+++ b/dojox/layout/RadioGroup.js
@@ -5,33 +5,29 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/l
 
 kernel.experimental("dojox.layout.RadioGroup");
 
-//
-//	dojox.layout.RadioGroup - an experimental (probably poorly named) Layout widget extending StackContainer
-//	that accepts ContentPanes as children, and applies aesthetically pleasing responsive transition animations
-//	attached to :hover of the Buttons created.
-//
-//	FIXME: take the Buttons out of the root template, and allow layoutAlign or similar attrib to use a different
-//	template, or build the template dynamically?
-//
 /*=====
-	var StackContainer = dijit.layout.StackContainer,
-		Templated = dijit._Templated,
-		Contained = dijit._Contained,
-		Widget = dijit._Widget;
+return {
+	// summary:
+	//		dojox.layout.RadioGroup - an experimental (probably poorly named) Layout widget extending StackContainer
+	//		that accepts ContentPanes as children, and applies aesthetically pleasing responsive transition animations
+	//		attached to :hover of the Buttons created.
+
+	// FIXME: take the Buttons out of the root template, and allow layoutAlign or similar attrib to use a different
+	//	template, or build the template dynamically?
+	};
 =====*/
-
 var RadioGroup = declare("dojox.layout.RadioGroup",[StackContainer,Templated],{
-	// summary: A Container that turns its Layout Children into a single Pane and transitions between states
-	//	onHover of the button
-	//
+	// summary:
+	//		A Container that turns its Layout Children into a single Pane and transitions between states
+	//		onHover of the button
 
 	// duration: Integer
-	//	used for Fade and Slide RadioGroup's, the duration to run the transition animation. does not affect anything
-	//	in default RadioGroup
+	//		used for Fade and Slide RadioGroup's, the duration to run the transition animation. does not affect anything
+	//		in default RadioGroup
 	duration: 750,
 
 	// hasButtons: Boolean
-	//	toggles internal button making on or off
+	//		toggles internal button making on or off
 	hasButtons: false,
 
 	// buttonClass: String
@@ -39,7 +35,7 @@ var RadioGroup = declare("dojox.layout.RadioGroup",[StackContainer,Templated],{
 	buttonClass: "dojox.layout._RadioButton",
 	
 	// templateString: String
-	//	the template for our container
+	//		the template for our container
 	templateString: '<div class="dojoxRadioGroup">'
 			+' 	<div dojoAttachPoint="buttonHolder" style="display:none;">'
 			+'		<table class="dojoxRadioButtons"><tbody><tr class="dojoxRadioButtonRow" dojoAttachPoint="buttonNode"></tr></tbody></table>'
@@ -48,7 +44,8 @@ var RadioGroup = declare("dojox.layout.RadioGroup",[StackContainer,Templated],{
 			+'</div>',
 
 	startup: function(){
-		// summary: scan the container for children, and make "tab buttons" for them
+		// summary:
+		//		scan the container for children, and make "tab buttons" for them
 		this.inherited(arguments);
 		this._children = this.getChildren();
 		this._buttons = this._children.length;
@@ -59,7 +56,8 @@ var RadioGroup = declare("dojox.layout.RadioGroup",[StackContainer,Templated],{
 	},
 
 	_setupChild: function(/* dijit._Widget */child){
-		// summary: Creates a hover button for a child node of the RadioGroup
+		// summary:
+		//		Creates a hover button for a child node of the RadioGroup
 		html.style(child.domNode, "position", "absolute");
 		if(this.hasButtons){
 			
@@ -89,7 +87,8 @@ var RadioGroup = declare("dojox.layout.RadioGroup",[StackContainer,Templated],{
 	// FIXME: shouldn't have to rewriting these, need to take styling out of _showChild and _hideChild
 	//		and use classes on the domNode in _transition or something similar (in StackContainer)
 	_transition: function(/*dijit._Widget*/ newWidget, /*dijit._Widget*/ oldWidget){
-		// summary: called when StackContainer receives a selectChild call, used to transition the panes.
+		// summary:
+		//		called when StackContainer receives a selectChild call, used to transition the panes.
 		this._showChild(newWidget);
 		if(oldWidget){
 			this._hideChild(oldWidget);
@@ -103,7 +102,8 @@ var RadioGroup = declare("dojox.layout.RadioGroup",[StackContainer,Templated],{
 	},
 
 	_showChild: function(/*dijit._Widget*/ page){
-		// summary: show the selected child widget
+		// summary:
+		//		show the selected child widget
 		var children = this.getChildren();
 		page.isFirstChild = (page == children[0]);
 		page.isLastChild = (page == children[children.length-1]);
@@ -119,7 +119,8 @@ var RadioGroup = declare("dojox.layout.RadioGroup",[StackContainer,Templated],{
 	},
 
 	_hideChild: function(/*dijit._Widget*/ page){
-		// summary: hide the specified child widget
+		// summary:
+		//		hide the specified child widget
 		page.selected = false;
 		page.domNode.style.display="none";
 		if(page.onHide){
@@ -130,10 +131,12 @@ var RadioGroup = declare("dojox.layout.RadioGroup",[StackContainer,Templated],{
 });
 
 declare("dojox.layout.RadioGroupFade", RadioGroup, {
-	// summary: An extension on a stock RadioGroup, that fades the panes.
+	// summary:
+	//		An extension on a stock RadioGroup, that fades the panes.
 
 	_hideChild: function(page){
-		// summary: hide the specified child widget
+		// summary:
+		//		hide the specified child widget
 		baseFx.fadeOut({
 			node:page.domNode,
 			duration:this.duration,
@@ -142,7 +145,8 @@ declare("dojox.layout.RadioGroupFade", RadioGroup, {
 	},
 
 	_showChild: function(page){
-		// summary: show the specified child widget
+		// summary:
+		//		show the specified child widget
 		this.inherited(arguments);
 		html.style(page.domNode, "opacity", 0);
 		baseFx.fadeIn({
@@ -153,7 +157,8 @@ declare("dojox.layout.RadioGroupFade", RadioGroup, {
 });
 
 declare("dojox.layout.RadioGroupSlide", RadioGroup, {
-	// summary: A Sliding Radio Group
+	// summary:
+	//		A Sliding Radio Group
 	// description:
 	//		An extension on a stock RadioGroup widget, sliding the pane
 	//		into view from being hidden. The entry direction is randomized
@@ -161,7 +166,7 @@ declare("dojox.layout.RadioGroupSlide", RadioGroup, {
 	//
 
 	// easing: Function
-	//	A hook to override the default easing of the pane slides.
+	//		A hook to override the default easing of the pane slides.
 	easing: "dojo.fx.easing.backOut",
 
 	// zTop: Integer
@@ -175,7 +180,8 @@ declare("dojox.layout.RadioGroupSlide", RadioGroup, {
 	},
 	
 	_positionChild: function(page){
-		// summary: set the child out of view immediately after being hidden
+		// summary:
+		//		set the child out of view immediately after being hidden
 
 		// FIXME: is there a real "size" floating around always?
 		if(!this._size){ return; } 
@@ -200,7 +206,8 @@ declare("dojox.layout.RadioGroupSlide", RadioGroup, {
 	},
 
 	_showChild: function(page){
-		// summary: Slide in the selected child widget
+		// summary:
+		//		Slide in the selected child widget
 		
 		var children = this.getChildren();
 		page.isFirstChild = (page == children[0]);
@@ -209,7 +216,7 @@ declare("dojox.layout.RadioGroupSlide", RadioGroup, {
 
 		html.style(page.domNode,{
 			zIndex: this.zTop, display:""
-		})
+		});
 
 		if(this._anim && this._anim.status()=="playing"){
 			this._anim.gotoPercent(100,true);
@@ -233,7 +240,8 @@ declare("dojox.layout.RadioGroupSlide", RadioGroup, {
 	},
 
 	_hideChild: function(page){
-		// summary: reset the position of the hidden pane out of sight
+		// summary:
+		//		reset the position of the hidden pane out of sight
 
 		page.selected = false;
 		page.domNode.style.zIndex = this.zTop - 1;
@@ -246,13 +254,13 @@ declare("dojox.layout.RadioGroupSlide", RadioGroup, {
 });
 
 declare("dojox.layout._RadioButton",[Widget,Templated,Contained],{
-	// summary: The Buttons for a RadioGroup
-	//
-	// description: A private widget used to manipulate the StackContainer (RadioGroup*). Don't create directly.
-	//
+	// summary:
+	//		The Buttons for a RadioGroup
+	// description:
+	//		A private widget used to manipulate the StackContainer (RadioGroup*). Don't create directly.
 	
 	// label: String
-	//	the Text Label of the button
+	//		the Text Label of the button
 	label: "",
 
 	// domNode to tell parent to select
@@ -261,12 +269,14 @@ declare("dojox.layout._RadioButton",[Widget,Templated,Contained],{
 	templateString: '<div dojoAttachPoint="focusNode" class="dojoxRadioButton"><span dojoAttachPoint="titleNode" class="dojoxRadioButtonLabel">${label}</span></div>',
 	
 	startup: function(){
-		// summary: start listening to mouseOver
+		// summary:
+		//		start listening to mouseOver
 		this.connect(this.domNode, "onmouseenter", "_onMouse");
 	},
 	
 	_onMouse: function(/* Event */e){
-		// summary: set the selected child on hover, and set our hover state class
+		// summary:
+		//		set the selected child on hover, and set our hover state class
 		this.getParent().selectChild(this.page);
 		this._clearSelected();
 		domClass.add(this.domNode,"dojoxRadioButtonSelected");
@@ -274,8 +284,9 @@ declare("dojox.layout._RadioButton",[Widget,Templated,Contained],{
 	},
 
 	_clearSelected: function(){
-		// summary: remove hover state class from sibling Buttons. This is easier (and more reliable)
-		//	than setting up an additional connection to onMouseOut
+		// summary:
+		//		remove hover state class from sibling Buttons. This is easier (and more reliable)
+		//		than setting up an additional connection to onMouseOut
 		
 		// FIXME: this relies on the template being [div][span]node[/span][/div]
 		query(".dojoxRadioButtonSelected", this.domNode.parentNode.parentNode)
@@ -293,4 +304,4 @@ lang.extend(Widget,{
 	//		to slideFrom top, left, right, or bottom.
 	slideFrom: "random"
 })
-});
\ No newline at end of file
+});
diff --git a/dojox/layout/ResizeHandle.js b/dojox/layout/ResizeHandle.js
index f678921..1e9e865 100644
--- a/dojox/layout/ResizeHandle.js
+++ b/dojox/layout/ResizeHandle.js
@@ -7,74 +7,71 @@ define(["dojo/_base/kernel","dojo/_base/lang","dojo/_base/connect","dojo/_base/a
 
 kernel.experimental("dojox.layout.ResizeHandle");
 
-/*===== 
-	var Widget = dijit._Widget;
-	var TemplatedMixin = dijit._TemplatedMixin;
-=====*/
 var ResizeHandle = declare("dojox.layout.ResizeHandle",[Widget, TemplatedMixin],
 	{
-	// summary: A dragable handle used to resize an attached node.
+	// summary:
+	//		A draggable handle used to resize an attached node.
 	//
 	// description:
-	//	The handle on the bottom-right corner of FloatingPane or other widgets that allows
-	//	the widget to be resized.
-	//	Typically not used directly.
-	//
+	//		The handle on the bottom-right corner of FloatingPane or other widgets that allows
+	//		the widget to be resized.
+	//		Typically not used directly.
+
 	// targetId: String
-	//	id of the Widget OR DomNode that I will size
+	//		id of the Widget OR DomNode that I will size
 	targetId: "",
 	
 	// targetContainer: DomNode
-	//	over-ride targetId and attch this handle directly to a reference of a DomNode
+	//		over-ride targetId and attch this handle directly to a reference of a DomNode
 	targetContainer: null,
 	
 	// resizeAxis: String
-	//	one of: x|y|xy limit resizing to a single axis, default to xy ...
+	//		one of: x|y|xy limit resizing to a single axis, default to xy ...
 	resizeAxis: "xy",
 	
 	// activeResize: Boolean
-	// 	if true, node will size realtime with mouse movement,
-	//	if false, node will create virtual node, and only resize target on mouseUp
+	//		if true, node will size realtime with mouse movement,
+	//		if false, node will create virtual node, and only resize target on mouseUp
 	activeResize: false,
 	
 	// activeResizeClass: String
-	//	css class applied to virtual resize node.
+	//		css class applied to virtual resize node.
 	activeResizeClass: "dojoxResizeHandleClone",
 	
 	// animateSizing: Boolean
-	//	only applicable if activeResize = false. onMouseup, animate the node to the
-	//	new size
+	//		only applicable if activeResize = false. onMouseup, animate the node to the
+	//		new size
 	animateSizing: true,
 	
 	// animateMethod: String
-	// 	one of "chain" or "combine" ... visual effect only. combine will "scale"
-	// 	node to size, "chain" will alter width, then height
+	//		one of "chain" or "combine" ... visual effect only. combine will "scale"
+	//		node to size, "chain" will alter width, then height
 	animateMethod: "chain",
 
 	// animateDuration: Integer
-	//	time in MS to run sizing animation. if animateMethod="chain", total animation
-	//	playtime is 2*animateDuration
+	//		time in MS to run sizing animation. if animateMethod="chain", total animation
+	//		playtime is 2*animateDuration
 	animateDuration: 225,
 
 	// minHeight: Integer
-	//	smallest height in px resized node can be
+	//		smallest height in px resized node can be
 	minHeight: 100,
 
 	// minWidth: Integer
-	//	smallest width in px resize node can be
+	//		smallest width in px resize node can be
 	minWidth: 100,
 
 	// constrainMax: Boolean
-	//	Toggle if this widget cares about the maxHeight and maxWidth
-	//	parameters.
+	//		Toggle if this widget cares about the maxHeight and maxWidth
+	//		parameters.
 	constrainMax: false,
 
 	// maxHeight: Integer
-	//	Largest height size in px the resize node can become.
+	//		Largest height size in px the resize node can become.
 	maxHeight:0,
 	
 	// maxWidth: Integer
-	//	Largest width size in px the reize node can become.
+	//		Largest width size in px the resize node can become.
 	maxWidth:0,
 
 	// fixedAspect: Boolean
@@ -100,7 +97,8 @@ var ResizeHandle = declare("dojox.layout.ResizeHandle",[Widget, TemplatedMixin],
 	templateString: '<div dojoAttachPoint="resizeHandle" class="dojoxResizeHandle"><div></div></div>',
 
 	postCreate: function(){
-		// summary: setup our one major listener upon creation
+		// summary:
+		//		setup our one major listener upon creation
 		this.connect(this.resizeHandle, "onmousedown", "_beginSizing");
 		if(!this.activeResize){
 			// there shall be only a single resize rubberbox that at the top
@@ -146,7 +144,8 @@ var ResizeHandle = declare("dojox.layout.ResizeHandle",[Widget, TemplatedMixin],
 	},
 
 	_beginSizing: function(/*Event*/ e){
-		// summary: setup movement listeners and calculate initial size
+		// summary:
+		//		setup movement listeners and calculate initial size
 		
 		if(this._isSizing){ return; }
 
@@ -161,6 +160,9 @@ var ResizeHandle = declare("dojox.layout.ResizeHandle",[Widget, TemplatedMixin],
 			var c = domGeometry.position(this.targetDomNode, true);
 			this._resizeHelper.resize({l: c.x, t: c.y, w: c.w, h: c.h});
 			this._resizeHelper.show();
+			if(!this.isLeftToRight()){
+				this._resizeHelper.startPosition = {l: c.x, t: c.y};
+			}
 		}
 
 		this._isSizing = true;
@@ -181,6 +183,10 @@ var ResizeHandle = declare("dojox.layout.ResizeHandle",[Widget, TemplatedMixin],
 				//width/height as well
 				pbw: padborder.w, pbh: padborder.h,
 				mw: margin.w, mh: margin.h};
+		if(!this.isLeftToRight() && dojo.style(this.targetDomNode, "position") == "absolute"){
+			var p = domGeometry.position(this.targetDomNode, true);
+			this.startPosition = {l: p.x, t: p.y};
+		}
 		
 		this._pconnects = [
 			connect.connect(windowBase.doc,"onmousemove",this,"_updateSizing"),
@@ -191,20 +197,21 @@ var ResizeHandle = declare("dojox.layout.ResizeHandle",[Widget, TemplatedMixin],
 	},
 
 	_updateSizing: function(/*Event*/ e){
-		// summary: called when moving the ResizeHandle ... determines
-		//	new size based on settings/position and sets styles.
+		// summary:
+		//		called when moving the ResizeHandle ... determines
+		//		new size based on settings/position and sets styles.
 
 		if(this.activeResize){
 			this._changeSizing(e);
 		}else{
-			var tmp = this._getNewCoords(e, 'border');
+			var tmp = this._getNewCoords(e, 'border', this._resizeHelper.startPosition);
 			if(tmp === false){ return; }
 			this._resizeHelper.resize(tmp);
 		}
 		e.preventDefault();
 	},
 
-	_getNewCoords: function(/* Event */ e, /* String */ box){
+	_getNewCoords: function(/* Event */ e, /* String */ box, /* Object */startPosition){
 		
 		// On IE, if you move the mouse above/to the left of the object being resized,
 		// sometimes clientX/Y aren't set, apparently.  Just ignore the event.
@@ -223,6 +230,16 @@ var ResizeHandle = declare("dojox.layout.ResizeHandle",[Widget, TemplatedMixin],
 			r = this._checkConstraints(newW, newH)
 		;
 		
+		startPosition = (startPosition || this.startPosition);
+		if(startPosition && this._resizeX){
+			// adjust x position for RtoL
+			r.l = startPosition.l + dx;
+			if(r.w != newW){
+				r.l += (newW - r.w);
+			}
+			r.t = startPosition.t;
+		}
+
 		switch(box){
 			case 'margin':
 				r.w += this.startSize.mw;
@@ -239,7 +256,8 @@ var ResizeHandle = declare("dojox.layout.ResizeHandle",[Widget, TemplatedMixin],
 	},
 	
 	_checkConstraints: function(newW, newH){
-		// summary: filter through the various possible constaint possibilities.
+		// summary:
+		//		filter through the various possible constaint possibilities.
 				
 		// minimum size check
 		if(this.minSize){
@@ -277,7 +295,8 @@ var ResizeHandle = declare("dojox.layout.ResizeHandle",[Widget, TemplatedMixin],
 	},
 		
 	_changeSizing: function(/*Event*/ e){
-		// summary: apply sizing information based on information in (e) to attached node
+		// summary:
+		//		apply sizing information based on information in (e) to attached node
 		
 		var isWidget = this.targetWidget && lang.isFunction(this.targetWidget.resize),
 			tmp = this._getNewCoords(e, isWidget && 'margin');
@@ -317,7 +336,8 @@ var ResizeHandle = declare("dojox.layout.ResizeHandle",[Widget, TemplatedMixin],
 	},
 
 	_endSizing: function(/*Event*/ e){
-		// summary: disconnect listenrs and cleanup sizing
+		// summary:
+		//		disconnect listenrs and cleanup sizing
 		arrayUtil.forEach(this._pconnects, connect.disconnect);
 		var pub = lang.partial(connect.publish, this.endTopic, [ this ]);
 		if(!this.activeResize){
@@ -332,29 +352,34 @@ var ResizeHandle = declare("dojox.layout.ResizeHandle",[Widget, TemplatedMixin],
 	},
 	
 	onResize: function(e){
-		// summary: Stub fired when sizing is done. Fired once
-		//	after resize, or often when `intermediateChanges` is
-		//	set to true.
+		// summary:
+		//		Stub fired when sizing is done. Fired once
+		//		after resize, or often when `intermediateChanges` is
+		//		set to true.
 	}
 	
 });
 
 var _ResizeHelper = dojo.declare("dojox.layout._ResizeHelper", Widget, {
-	// summary: A global private resize helper shared between any
+	// summary:
+	//		A global private resize helper shared between any
 	//		`dojox.layout.ResizeHandle` with activeSizing off.
 	
 	show: function(){
-		// summary: show helper to start resizing
+		// summary:
+		//		show helper to start resizing
 		domStyle.set(this.domNode, "display", "");
 	},
 	
 	hide: function(){
-		// summary: hide helper after resizing is complete
+		// summary:
+		//		hide helper after resizing is complete
 		domStyle.set(this.domNode, "display", "none");
 	},
 	
 	resize: function(/* Object */dim){
-		// summary: size the widget and place accordingly
+		// summary:
+		//		size the widget and place accordingly
 		domGeometry.setMarginBox(this.domNode, dim);
 	}
 	
diff --git a/dojox/layout/RotatorContainer.js b/dojox/layout/RotatorContainer.js
index a5c6b19..d0289ee 100755
--- a/dojox/layout/RotatorContainer.js
+++ b/dojox/layout/RotatorContainer.js
@@ -4,27 +4,22 @@ define(["dojo/_base/declare","dojo/_base/html","dojo/_base/connect","dojo/_base/
 ],function(declare,html,connect,lang,array,baseFx,coreFx,manager,
 	StackContainer,StackController,Widget,Templated,Contained){
 
-/*===== 
-	var Widget = dijit._Widget, 
-		Templated = dijit._Templated,
-		Contained = dijit._Contained,
-		StackContainer = dijit.layout.StackContainer,
-		StackController = dijit.layout.StackController;
-=====*/
 var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer, Templated], {
 	// summary:
 	//		Extends a StackContainer to automatically transition between children
 	//		and display navigation in the form of tabs or a pager.
 	//
 	// description:
-	// 		The RotatorContainer cycles through the children with a transition.
+	//		The RotatorContainer cycles through the children with a transition.
 	//
-	// published topics:
-	// 		[widgetId]-update - Notifies pager(s) that a child has changed.
-	//			Parameters:
-	//				/*boolean*/ playing - true if playing, false if paused
-	//				/*int*/ current     - current selected child
-	//				/*int*/ total       - total number of children
+	//		####published topics:
+	//
+	//		[widgetId]-update - Notifies pager(s) that a child has changed.
+	//		Parameters:
+	//
+	//		- /*boolean*/ playing - true if playing, false if paused
+	//		- /*int*/ current     - current selected child
+	//		- /*int*/ total       - total number of children
 	//
 	// example:
 	// |	<div dojoType="dojox.layout.RotatorContainer" id="myRotator" showTabs="true" autoStart="true" transitionDelay="5000">
@@ -89,7 +84,8 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
  	pagerClass: "dojox.layout.RotatorPager",
 
 	postCreate: function(){
-		// summary: Initializes the DOM nodes, tabs, and transition stuff.
+		// summary:
+		//		Initializes the DOM nodes, tabs, and transition stuff.
 		this.inherited(arguments);
 
 		// force this DOM node to a relative position and make sure the children are absolute positioned
@@ -139,7 +135,8 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
 	},
 
 	startup: function(){
-		// summary: Initializes the pagers.
+		// summary:
+		//		Initializes the pagers.
 		if(this._started){ return; }
 
 		// check if the pager is defined within the rotator container
@@ -165,7 +162,8 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
 	},
 
 	destroy: function(){
-		// summary: Unsubscribe to all of our topics
+		// summary:
+		//		Unsubscribe to all of our topics
 		array.forEach(this._subscriptions, connect.unsubscribe);
 		this.inherited(arguments);
 	},
@@ -176,13 +174,15 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
 	},
 
 	_updatePager: function(){
-		// summary: Notify the pager's current and total numbers.
+		// summary:
+		//		Notify the pager's current and total numbers.
 		var c = this.getChildren();
 		connect.publish(this.id+"-update", [this._playing, array.indexOf(c, this.selectedChildWidget)+1, c.length]);
 	},
 
 	_onMouseOver: function(){
-		// summary: Triggered when the mouse is moved over the rotator container.
+		// summary:
+		//		Triggered when the mouse is moved over the rotator container.
 
 		// temporarily suspend the cycling, but don't officially pause it
 		this._resetTimer();
@@ -190,7 +190,8 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
 	},
 
 	_onMouseOut: function(){
-		// summary: Triggered when the mouse is moved off the rotator container.
+		// summary:
+		//		Triggered when the mouse is moved off the rotator container.
 		this._over = false;
 
 		// if we were playing, resume playback in 200ms
@@ -202,13 +203,15 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
 	},
 
 	_resetTimer: function(){
-		// summary: Resets the timer used to start the next transition.
+		// summary:
+		//		Resets the timer used to start the next transition.
 		clearTimeout(this._timer);
 		this._timer = null;
 	},
 
 	_cycle: function(/*boolean or int*/next){
-		// summary: Cycles to the next/previous child.
+		// summary:
+		//		Cycles to the next/previous child.
 
 		// if next is an int, then _cycle() was called via a timer
 		// if next is a boolean, then _cycle() was called via the next/prev buttons, stop playing and reset cycles
@@ -224,8 +227,9 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
 	},
 
 	_manualChange: function(){
-		// summary: This function is only called when a manual change occurs in which
-		//   case we may need to stop playing and we need to reset the cycle counter
+		// summary:
+		//		This function is only called when a manual change occurs in which
+		//		case we may need to stop playing and we need to reset the cycle counter
 		if(this.pauseOnManualChange){
 			this._playing = false;
 		}
@@ -233,7 +237,8 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
 	},
 
 	_play: function(skip){
-		// summary: Schedules the next transition.
+		// summary:
+		//		Schedules the next transition.
 		this._playing = true;
 		this._resetTimer();
 		if(skip !== true && this.cycles>0){
@@ -249,13 +254,15 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
 	},
 
 	_pause: function(){
-		// summary: Clears the transition timer and pauses the rotator.
+		// summary:
+		//		Clears the transition timer and pauses the rotator.
 		this._playing = false;
 		this._resetTimer();
 	},
 
 	_state: function(playing){
-		// summary: Fired when the play/pause pager button is toggled.
+		// summary:
+		//		Fired when the play/pause pager button is toggled.
 		if(playing){
 			// since we were manually changed, disable the cycle counter
 			this.cycles = -1;
@@ -266,7 +273,8 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
 	},
 
 	_transition: function(/*dijit._Widget*/ next, /*dijit._Widget*/ prev){
-		// summary: Dispatches the appropriate transition.
+		// summary:
+		//		Dispatches the appropriate transition.
 		this._resetTimer();
 
 		// check if we have anything to transition
@@ -289,7 +297,8 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
 	},
 
 	_fade: function(/*dijit._Widget*/ next, /*dijit._Widget*/ prev){
-		// summary: Crossfades two children.
+		// summary:
+		//		Crossfades two children.
 		this._styleNode(prev.domNode, 1, 1);
 		this._styleNode(next.domNode, 0, 2);
 
@@ -314,8 +323,9 @@ var RotatorContainer = declare("dojox.layout.RotatorContainer",[StackContainer,
 		anim.play();
 	},
 
-	_styleNode: function(/*DOMnode*/node, /*number*/opacity, /*int*/zIndex){
-		// summary: Helper function to style the children.
+	_styleNode: function(/*DomNode*/node, /*number*/opacity, /*int*/zIndex){
+		// summary:
+		//		Helper function to style the children.
 		html.style(node, "opacity", opacity);
 		html.style(node, "zIndex", zIndex);
 		html.style(node, "position", "absolute");
@@ -328,26 +338,28 @@ declare("dojox.layout.RotatorPager", [Widget, Templated, Contained], {
 	//
 	// description:
 	//		A pager can be defined one of two ways:
-	//			* Externally of the RotatorContainer's template and tell the
-	//			RotatorPager the rotatorId of the RotatorContainer
-	//			* As a direct descendant of the RotatorContainer (i.e. inside the
-	//			RotatorContainer's template)
+	//
+	//		- Externally of the RotatorContainer's template and tell the
+	//		RotatorPager the rotatorId of the RotatorContainer
+	//		- As a direct descendant of the RotatorContainer (i.e. inside the
+	//		RotatorContainer's template)
 	//
 	//		The pager can contain the following components:
-	//			* Previous button
-	//				- Must be a dijit.form.Button
-	//				- dojoAttachPoint must be named "previous"
-	//			* Next button
-	//				- Must be a dijit.form.Button
-	//				- dojoAttachPoint must be named "next"
-	//			* Play/Pause toggle button
-	//				- Must be a dijit.form.ToggleButton
-	//				- dojoAttachPoint must be named "playPause"
-	//				- Use iconClass to specify toggled state
-	//			* Current child #
-	//				- dojoAttachPoint must be named "current"
-	//			* Total # of children
-	//				- dojoAttachPoint must be named "total"
+	//
+	//		- Previous button
+	//			- Must be a dijit.form.Button
+	//			- dojoAttachPoint must be named "previous"
+	//		- Next button
+	//			- Must be a dijit.form.Button
+	//			- dojoAttachPoint must be named "next"
+	//		- Play/Pause toggle button
+	//			- Must be a dijit.form.ToggleButton
+	//			- dojoAttachPoint must be named "playPause"
+	//			- Use iconClass to specify toggled state
+	//		- Current child #
+	//			- dojoAttachPoint must be named "current"
+	//		- Total # of children
+	//			- dojoAttachPoint must be named "total"
 	//
 	//		You can choose to exclude specific controls as well as add elements
 	//		for styling.
@@ -358,13 +370,17 @@ declare("dojox.layout.RotatorPager", [Widget, Templated, Contained], {
 	//		Notifications are received from and sent to the RotatorContainer as
 	//		well as other RotatorPagers.
 	//
-	// published topics:
+	//		####published topics:
+	//
 	//		[widgetId]-cycle - Notify that the next or previous button was pressed.
-	//			Parameters:
-	//				/*boolean*/ next - true if next, false if previous
+	//		Parameters:
+	//
+	//		- /*boolean*/ next - true if next, false if previous
+	//
 	//		[widgetId]-state - Notify that the play/pause button was toggled.
-	//			Parameters:
-	//				/*boolean*/ playing - true if playing, false if paused
+	//		Parameters:
+	//
+	//		- /*boolean*/ playing - true if playing, false if paused
 	//
 	// example:
 	//		A pager with the current/total children and previous/next buttons.
@@ -427,13 +443,14 @@ declare("dojox.layout.RotatorPager", [Widget, Templated, Contained], {
 	},
 
 	destroy: function(){
-		// summary: Unsubscribe to all of our topics
+		// Unsubscribe to all of our topics
 		array.forEach(this._subscriptions, connect.unsubscribe);
 		this.inherited(arguments);
 	},
 
 	_state: function(/*boolean*/playing){
-		// summary: Updates the display of the play/pause button
+		// summary:
+		//		Updates the display of the play/pause button
 		if(this.playPause && this.playPause.checked != playing){
 			this.playPause.set("label", playing ? "Pause" : "Play");
 			this.playPause.set("checked", playing);
@@ -441,7 +458,8 @@ declare("dojox.layout.RotatorPager", [Widget, Templated, Contained], {
 	},
 
 	_update: function(/*boolean*/playing, /*int*/current, /*int*/total){
-		// summary: Updates the pager's play/pause button, current child, and total number of children.
+		// summary:
+		//		Updates the pager's play/pause button, current child, and total number of children.
 		this._state(playing);
 		if(this.current && current){
 			this.current.innerHTML = current;
@@ -452,4 +470,4 @@ declare("dojox.layout.RotatorPager", [Widget, Templated, Contained], {
 	}
 });
 return RotatorContainer;
-});
\ No newline at end of file
+});
diff --git a/dojox/layout/ScrollPane.js b/dojox/layout/ScrollPane.js
index fd437b6..8412969 100644
--- a/dojox/layout/ScrollPane.js
+++ b/dojox/layout/ScrollPane.js
@@ -5,34 +5,29 @@ function(kernel,declare,html,baseFx,Templated,ContentPane,domClass,template){
 
 kernel.experimental("dojox.layout.ScrollPane");
 
-// FIXME: need to adust the _line somehow, it stops scrolling
-	
-/*===== 
-	var ContentPane = dijit.layout.ContentPane,
-		Templated = dijit._Templated;
-=====*/
+// FIXME: need to adjust the _line somehow, it stops scrolling
 
-declare("dojox.layout.ScrollPane",[ContentPane, Templated],{
-	// summary: A pane that "scrolls" its content based on the mouse poisition inside
-	//
+var Scrollpane = declare("dojox.layout.ScrollPane",[ContentPane, Templated],{
+	// summary:
+	//		A pane that "scrolls" its content based on the mouse poisition inside
 	// description:
 	//		A sizable container that takes it's content's natural size and creates
 	//		a scroll effect based on the relative mouse position. It is an interesting
 	//		way to display lists of data, or blocks of content, within a confined
 	//		space.
 	//
-	// 		Horizontal scrolling is supported. Combination scrolling is not.
-	//
+	//		Horizontal scrolling is supported. Combination scrolling is not.
 	// example:
 	// |	<div dojoType="dojox.layout.ScrollPane" style="width:150px height:300px;">
 	// |		<!-- any height content -->
 	// |	</div>
-	//
-	// _line: dojo._Line
-	// 		storage for our top and bottom most scrollpoints
+	
+	// _line: dojo/_base/fx._Line
+	//		storage for our top and bottom most scrollpoints
 	_line: null,
 	
-	// _lo: the height of the visible pane
+	// _lo: 
+	//		the height of the visible pane
 	_lo: null,
 	
 	_offset: 15,
@@ -41,13 +36,15 @@ declare("dojox.layout.ScrollPane",[ContentPane, Templated],{
 	//		either "horizontal" or "vertical" for scroll orientation.
 	orientation: "vertical",
 	
-	// alwaysShow: Boolean
+	// autoHide: Boolean
 	//		whether the scroll helper should hide when mouseleave
 	autoHide: true,
 	templateString: template,
 	
-	resize: function(size){
-		// summary: calculates required sizes. Call this if you add/remove content manually, or reload the content.
+	resize: function(/*Integer?*/ size){
+		// summary:
+		//		calculates required sizes. Call this if you add/remove
+		//		content manually, or reload the content.
 		
 		// if size is passed, it means we need to take care of sizing ourself (this is for IE<8)
 		if(size){
@@ -118,14 +115,16 @@ declare("dojox.layout.ScrollPane",[ContentPane, Templated],{
 	},
 	
 	_set: function(/* Float */n){
+		// summary:
+		//		set the pane's scroll offset, and position the virtual scroll helper
 		if(!this._size){ return; }
-		// summary: set the pane's scroll offset, and position the virtual scroll helper
 		this.wrapper[this._scroll] = Math.floor(this._line.getValue(n));
 		html.style(this.helper, this._edge, Math.floor(this._helpLine.getValue(n)) + "px");
 	},
 	
 	_calc: function(/* Event */e){
-		// summary: calculate the relative offset of the cursor over the node, and call _set
+		// summary:
+		//		calculate the relative offset of the cursor over the node, and call _set
 		if(!this._lo){ this.resize(); }
 		this._set(this._vertical ?
 			((e.pageY - this._lo.y) / this._lo.h) :
@@ -148,4 +147,5 @@ declare("dojox.layout.ScrollPane",[ContentPane, Templated],{
 		}
 	} 
 });
-});
\ No newline at end of file
+return Scrollpane;
+});
diff --git a/dojox/layout/TableContainer.js b/dojox/layout/TableContainer.js
index ef58754..65645ae 100644
--- a/dojox/layout/TableContainer.js
+++ b/dojox/layout/TableContainer.js
@@ -4,7 +4,6 @@ function(kernel, lang, declare, domClass, domConstruct, arrayUtil, domProp, domS
 
 kernel.experimental("dojox.layout.TableContainer");
 
-/*===== var LayoutWidget = dijit.layout._LayoutWidget; =====*/
 var TableContainer = declare("dojox.layout.TableContainer", _LayoutWidget, {
 	// summary:
 	//		A container that lays out its child widgets in a table layout.
@@ -88,8 +87,8 @@ var TableContainer = declare("dojox.layout.TableContainer", _LayoutWidget, {
 				child.startup();
 			}
 		});
-		this.resize();
 		this.layout();
+		this.resize();
 	},
 
 	resize: function(){
@@ -241,8 +240,8 @@ var TableContainer = declare("dojox.layout.TableContainer", _LayoutWidget, {
 	
 	destroyDescendants: function(/*Boolean*/ preserveDom){
 		// summary:
-		//      Destroys all the widgets inside this.containerNode,
-		//      but not this widget itself
+		//		Destroys all the widgets inside this.containerNode,
+		//		but not this widget itself
 		arrayUtil.forEach(this._children, function(child){ child.destroyRecursive(preserveDom); });
 	},
 	
@@ -256,9 +255,10 @@ var TableContainer = declare("dojox.layout.TableContainer", _LayoutWidget, {
 	}
 });
 
-// Extend the default widget with both label and title elements, as
-// well as a "spanLabel" attribute.  If a widget
-lang.extend(_WidgetBase, {
+TableContainer.ChildWidgetProperties = {
+	// summary:
+	//		Properties to be set on children of TableContainer
+
 	// label: String
 	//		The label to display for a given widget
 	label: "",
@@ -277,6 +277,10 @@ lang.extend(_WidgetBase, {
 	// colspan: Number
 	//		The number of columns this widget should span.
 	colspan: 1
-});
+};
+
+// Add to widget base for benefit of parser.   Remove for 2.0.   Also, hide from doc viewer.
+lang.extend(_WidgetBase, /*===== {} || =====*/ TableContainer.ChildWidgetProperties);
+
 return TableContainer;
 });
diff --git a/dojox/layout/ToggleSplitter.js b/dojox/layout/ToggleSplitter.js
index 25c3941..231e068 100644
--- a/dojox/layout/ToggleSplitter.js
+++ b/dojox/layout/ToggleSplitter.js
@@ -2,21 +2,21 @@ define("dojox/layout/ToggleSplitter", ["dojo", "dijit", "dijit/layout/BorderCont
 
 dojo.experimental("dojox.layout.ToggleSplitter");
 
-dojo.declare("dojox.layout.ToggleSplitter", dijit.layout._Splitter, {
+var ToggleSplitter = dojo.declare("dojox.layout.ToggleSplitter", dijit.layout._Splitter, {
 	// summary:
-	//		A draggable and clickable spacer between two items in a dijit.layout.BorderContainer`.
+	//		A draggable and clickable spacer between two items in a `dijit.layout.BorderContainer`.
 	// description:
-	//		This is instantiated by `dijit.layout.BorderContainer. Users should not
+	//		This is instantiated by `dijit.layout.BorderContainer`. Users should not
 	//		create it directly.
 	// tags:
 	//		private
 
-/*=====
-	// container: [const] dijit.layout.BorderContainer
+
+	// container: [const] dijit/layout/BorderContainer
 	//		Pointer to the parent BorderContainer
 	container: null,
 
-	// child: [const] dijit.layout._LayoutWidget
+	// child: [const] dijit/layout/_LayoutWidget
 	//		Pointer to the pane associated with this splitter
 	child: null,
 
@@ -24,7 +24,6 @@ dojo.declare("dojox.layout.ToggleSplitter", dijit.layout._Splitter, {
 	//		Region of pane associated with this splitter.
 	//		"top", "bottom", "left", "right".
 	region: null,
-=====*/
 
 	// state: String
 	//		the initial and current state of the splitter (and its attached pane)
@@ -143,7 +142,7 @@ dojo.declare("dojox.layout.ToggleSplitter", dijit.layout._Splitter, {
 	},
 
 	_handleOnChange: function(preState){
-		// summary
+		// summary:
 		//		Effect the state change with the new value of this.state
 		var paneNode = this.child.domNode,
 			openProps, paneStyle,
@@ -220,7 +219,7 @@ dojo.declare("dojox.layout.ToggleSplitter", dijit.layout._Splitter, {
 	},
 
 	_setStateClass: function(){
-		// Summary:
+		// summary:
 		//		Apply the appropriate classes for the current open state
 		var arrow = "&#9652", region = this.region.toLowerCase(),
 			baseClass = this.baseClass,
@@ -247,7 +246,7 @@ dojo.declare("dojox.layout.ToggleSplitter", dijit.layout._Splitter, {
 		this.a11yText.innerHTML = arrow;
 	},
 
-	_setStateAttr: function(/*Strring*/ state){
+	_setStateAttr: function(/*String*/ state){
 		// summary:
 		//		setter for the state property
 		if(!this._started) {
@@ -292,4 +291,6 @@ dojo.extend(dijit._Widget, {
 	toggleSplitterCollapsedSize: ""
 });
 
-});
\ No newline at end of file
+return ToggleSplitter;
+
+});
diff --git a/dojox/layout/dnd/Avatar.js b/dojox/layout/dnd/Avatar.js
index be57902..d123518 100644
--- a/dojox/layout/dnd/Avatar.js
+++ b/dojox/layout/dnd/Avatar.js
@@ -5,7 +5,7 @@ dojo.require("dojo.dnd.common");
 
 dojo.declare("dojox.layout.dnd.Avatar", dojo.dnd.Avatar, {
 	// summary:
-	//      An Object, which represents the object being moved in a GridContainer
+	//		An Object, which represents the object being moved in a GridContainer
 	constructor: function(manager, opacity){
 		this.opacity = opacity || 0.9;
 	},
@@ -37,7 +37,8 @@ dojo.declare("dojox.layout.dnd.Avatar", dojo.dnd.Avatar, {
 	},
 
 	update: function(){
-		// summary: Updates the avatar to reflect the current DnD state.
+		// summary:
+		//		Updates the avatar to reflect the current DnD state.
 		dojo.toggleClass(this.node, "dojoDndAvatarCanDrop", this.manager.canDropFlag);
 	},
 
diff --git a/dojox/layout/dnd/PlottedDnd.js b/dojox/layout/dnd/PlottedDnd.js
index 97af13b..a99ed0c 100644
--- a/dojox/layout/dnd/PlottedDnd.js
+++ b/dojox/layout/dnd/PlottedDnd.js
@@ -34,7 +34,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	_calculateCoords : function(/*Boolean*/height){
-		// summary: Calculate each position of children
+		// summary:
+		//		Calculate each position of children
 		dojo.forEach(this.node.childNodes, function(child){
 			var c = dojo.coords(child, true);
 			child.coords = {
@@ -50,7 +51,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	_legalMouseDown: function(/*Event*/e){
-		// summary: Checks if user clicked on "approved" items.
+		// summary:
+		//		Checks if user clicked on "approved" items.
 		if(!this.withHandles){ return true; }
 		for(var node = (e.target); node && node != this.node; node = node.parentNode){
 			if(dojo.hasClass(node, this.defaultHandleClass)){
@@ -61,7 +63,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	setDndItemSelectable: function(/*Node*/node, /*Boolean*/isSelectable) {
-		// summary: set an item as selectable
+		// summary:
+		//		set an item as selectable
 		for(var _node = node; _node && node != this.node; _node = _node.parentNode) {
 			if (dojo.hasClass(_node,"dojoDndItem")) {
 				dojo.setSelectable(_node, isSelectable);
@@ -71,7 +74,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	getDraggedWidget: function(/*Node*/node) {
-		// summary: Return one or more widget selected during the drag.
+		// summary:
+		//		Return one or more widget selected during the drag.
 		var _node = node;
 		while (_node && _node.nodeName.toLowerCase()!="body" && !dojo.hasClass(_node,"dojoDndItem")) {
 			_node = _node.parentNode;
@@ -80,13 +84,15 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	isAccepted: function(/*Node*/ node) {
-		// summary: test if this node can be accepted
+		// summary:
+		//		test if this node can be accepted
 		var _dndType = (node) ? node.getAttribute("dndtype") : null;
 		return (_dndType && _dndType in this.accept);
 	},
 	
 	onDndStart:function(/*Object*/source, /*Array*/nodes, /*Object*/copy){
-		// summary: Called to initiate the DnD operation.
+		// summary:
+		//		Called to initiate the DnD operation.
 
 		this.firstIndicator = (source == this);
 		this._calculateCoords(true);
@@ -109,7 +115,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 
 	onDndCancel:function(){
-		// summary: Called to cancel the DnD operation.
+		// summary:
+		//		Called to cancel the DnD operation.
 		var m = dojo.dnd.manager();
 		if(m.source == this && this.hideSource){
 			var nodes = this.getSelectedNodes();
@@ -122,7 +129,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	onDndDrop: function(source,nodes,copy,target) {
-		// summary: Called to finish the DnD operation
+		// summary:
+		//		Called to finish the DnD operation
 		try{
 			if(!this.isAccepted(nodes[0])){
 				this.onDndCancel();
@@ -139,7 +147,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 			
 	onMouseDown: function(/*Event*/e) {
-		// summary: Event processor for onmousedown.
+		// summary:
+		//		Event processor for onmousedown.
 		if(this.current == null){
 			this.selection = {};
 		}else{
@@ -194,7 +203,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 
 	onMouseUp: function(/*Event*/e) {
-		// summary: Event processor for onmouseup.
+		// summary:
+		//		Event processor for onmouseup.
 		dojox.layout.dnd.PlottedDnd.superclass.onMouseUp.call(this,e);
 		this.containerSource = false;
 		if (!dojo.isIE && this.mouseDown){
@@ -206,7 +216,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	onMouseMove: function(e) {
-		// summary: Event processor for onmousemove
+		// summary:
+		//		Event processor for onmousemove
 		var m = dojo.dnd.manager();
 		if(this.isDragging) {
 			var before = false;
@@ -238,7 +249,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	_markTargetAnchor: function(/*Boolean*/before){
-		// summary: Assigns a class to the current target anchor based on "before" status
+		// summary:
+		//		Assigns a class to the current target anchor based on "before" status
 		if(this.current == this.targetAnchor && this.before == before){ return; }
 		this.targetAnchor = this.current;
 		this.targetBox = null;
@@ -246,7 +258,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	_unmarkTargetAnchor: function(){
-		// summary: Removes a class of the current target anchor based on "before" status.
+		// summary:
+		//		Removes a class of the current target anchor based on "before" status.
 		if(!this.targetAnchor){ return; }
 		this.targetAnchor = null;
 		this.targetBox = null;
@@ -254,7 +267,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	setIndicatorPosition: function(/*Event*/e) {
-		// summary: set the position of the drop indicator
+		// summary:
+		//		set the position of the drop indicator
 		var before = false;
 		if(this.current){
 			if (!this.current.coords || this.allowAutoScroll) {
@@ -293,7 +307,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	deleteDashedZone: function() {
-		// summary: hide the dashed zone
+		// summary:
+		//		hide the dashed zone
 		this._drop.style.display = "none";
 			var next = this._drop.nextSibling;
 			while (next != null) {
@@ -304,7 +319,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	insertDashedZone: function(/*Boolean*/before) {
-		// summary: Insert the dashed zone at the right place
+		// summary:
+		//		Insert the dashed zone at the right place
 		if(this.dropObject){
 			if( before == this.dropObject.b &&
 				((this.current && this.dropObject.c == this.current.id) ||
@@ -334,7 +350,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	insertNodes: function(/*Boolean*/addSelected, /*Array*/data, /*Boolean*/before, /*Node*/anchor){
-		// summary: Inserts new data items (see Dojo Container's insertNodes method for details).
+		// summary:
+		//		Inserts new data items (see Dojo Container's insertNodes method for details).
 		if(this.dropObject){
 			dojo.style(this.dropObject.n,"display","none");
 			dojox.layout.dnd.PlottedDnd.superclass.insertNodes.call(this,true,data,true,this.dropObject.n);
@@ -388,8 +405,8 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 
 	_sumAncestorProperties: function(node, prop){
-		//	summary
-		//	Returns the sum of the passed property on all ancestors of node.
+		// summary:
+		//		Returns the sum of the passed property on all ancestors of node.
 		node = dojo.byId(node);
 		if(!node){ return 0; }
 		
@@ -438,7 +455,8 @@ dojox.layout.dnd._setGcDndHandle = function(service,withHandles,handleClasses, f
 };
 
 dojo.declare("dojox.layout.dnd.DropIndicator", null, {
-	// summary: An empty widget to show at the user the drop zone of the widget.
+	// summary:
+	//		An empty widget to show at the user the drop zone of the widget.
 	constructor: function(/*String*/cn, /*String*/tag) {
 		this.tag = tag || "div";
 		this.style = cn || null;
@@ -488,7 +506,8 @@ dojo.extend(dojo.dnd.Manager, {
 	},
 	
 	makeAvatar: function(){
-		//summary: Makes the avatar, it is separate to be overwritten dynamically, if needed.
+		// summary:
+		//		Makes the avatar, it is separate to be overwritten dynamically, if needed.
 		return (this.source.declaredClass == "dojox.layout.dnd.PlottedDnd") ?
 			new dojox.layout.dnd.Avatar(this, this.source.opacity) :
 			new dojo.dnd.Avatar(this)
@@ -512,4 +531,4 @@ if(dojo.isIE){
 	dojo.addOnWindowUnload(function(){
 		dojo.forEach(dojox.layout.dnd.handdleIE, dojo.unsubscribe);
 	});
-}
\ No newline at end of file
+}
diff --git a/dojox/layout/resources/ExpandoPane.css b/dojox/layout/resources/ExpandoPane.css
index 47001a3..9640c63 100644
--- a/dojox/layout/resources/ExpandoPane.css
+++ b/dojox/layout/resources/ExpandoPane.css
@@ -140,7 +140,7 @@
 		border:1px solid #769DC0;
 		border-bottom:none;
         background-color:#cde8ff;
-		background-image: url("../../../dijit/themes/claro/layout/images/accordion.png");
+		background-image: url("../../../dijit/themes/claro/images/standardGradient.png");
         background-position:0px 0px;
         background-repeat:repeat-x;
 		padding: 5px 7px 2px 7px;
@@ -167,7 +167,7 @@
 		background-color: #E6E6E7;
 	}
 	.claro .dojoxExpandoClosed .dojoxExpandoTitle{
-		background-image: url("../../../dijit/themes/claro/layout/images/accordion.png");
+		background-image: url("../../../dijit/themes/claro/images/standardGradient.png");
 		background-position:0 0;
 	}
 	
diff --git a/dojox/layout/resources/ExpandoPane.html b/dojox/layout/resources/ExpandoPane.html
index a2e646f..e52457b 100644
--- a/dojox/layout/resources/ExpandoPane.html
+++ b/dojox/layout/resources/ExpandoPane.html
@@ -1,6 +1,6 @@
 <div class="dojoxExpandoPane">
 	<div dojoAttachPoint="titleWrapper" class="dojoxExpandoTitle">
-		<div class="dojoxExpandoIcon" dojoAttachPoint="iconNode" dojoAttachEvent="onclick:toggle"><span class="a11yNode">X</span></div>			
+		<div class="dojoxExpandoIcon" dojoAttachPoint="iconNode" dojoAttachEvent="ondijitclick:toggle"><span class="a11yNode">X</span></div>
 		<span class="dojoxExpandoTitleNode" dojoAttachPoint="titleNode">${title}</span>
 	</div>
 	<div class="dojoxExpandoWrapper" dojoAttachPoint="cwrapper" dojoAttachEvent="ondblclick:_trap">
diff --git a/dojox/layout/resources/RadioGroup.css b/dojox/layout/resources/RadioGroup.css
index d4d67d2..f56f39b 100644
--- a/dojox/layout/resources/RadioGroup.css
+++ b/dojox/layout/resources/RadioGroup.css
@@ -24,7 +24,11 @@
 	background:#b7b7b7;
 }
 .soria .dojoxRadioButtonSelected {
+/*
+    the following url does not exist; commented out to quiet build errors; tracked at #15696
 	background:#b7cdee url('../../../dijit/themes/soria/images/gradientTopBg.png') repeat-x top center;
+*/
+	background:#b7cdee;
 }
 
 .dojoxRadioButtonLabel {
diff --git a/dojox/layout/resources/icons/gridcontainer_grip.gif b/dojox/layout/resources/icons/gridcontainer_grip.gif
old mode 100644
new mode 100755
diff --git a/dojox/layout/tests/ContentPane.html b/dojox/layout/tests/ContentPane.html
index 63e4091..1871c8a 100644
--- a/dojox/layout/tests/ContentPane.html
+++ b/dojox/layout/tests/ContentPane.html
@@ -24,7 +24,7 @@
 			behaviour: expression(fixPngIE6.call(this));
 		}
 	</style>
-	<script src='../../../dojo/dojo.js' djConfig='isDebug:true, parseOnLoad:true'></script>
+	<script src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 	<script>
 		dojo.require('doh.runner');
 		dojo.require('dojox.layout.ContentPane');
@@ -50,22 +50,30 @@
 
 		var pane1, pane2;
 
-		dojo.addOnLoad(function(){
-
-			pane1 = dijit.byId('parsedPane');
+		dojo.ready(function(){
 
 			function ieTrimSpaceBetweenTags(str){
 				return str.replace(/(<[a-z]*[^>]*>)\s*/ig, "$1");
 			}
 
+			doh.register({
+				name: 'parse',
+				timeout: 5000,
+				runTest: function(t){
+					dojo.parser.parse().then(function(){
+						pane1 = dijit.byId('parsedPane');
+					});
+				}
+			});
+
 			doh.register("basicChecks", [
 					{
 						name: 'setContent',
 						runTest: function(t){
 							console.log("basicChecks: " + this.name);
 							var msg = "Simple Test";
-							pane1.attr('content', msg);
-							t.assertEqual(msg, pane1.domNode.innerHTML);
+							pane1.set('content', msg);
+							t.is(msg, pane1.domNode.innerHTML);
 						}
 					},
 					{
@@ -74,11 +82,11 @@
 						runTest: function(t){
 							console.log("basicChecks: " + this.name);
 							var msg = "simple remote Test"
-							pane1.attr('href', dojo.moduleUrl('dijit', 'tests/layout/getResponse.php?message='+encodeURI(msg)));
+							pane1.set('href', dojo.moduleUrl('dijit', 'tests/layout/getResponse.php?message='+encodeURI(msg)));
 
 							var d = new t.Deferred();
 							setTimeout(d.getTestCallback(function(){
-								t.assertEqual(msg, pane1.domNode.innerHTML)
+								t.is(msg, pane1.domNode.innerHTML)
 							}), 1500);
 							return d;
 						}
@@ -88,11 +96,14 @@
 						runTest: function(t){
 							console.log("basicChecks: " + this.name);
 							var cont = "<div dojoType='dojox.TestWidget'>Test</div>";
-							pane1.attr('content', cont);
-							t.assertFalse(cont.toLowerCase() == pane1.domNode.innerHTML.toLowerCase());
-							t.assertEqual(1, pane1.getChildren().length);
+							pane1.set('content', cont);
+							t.isNot(cont.toLowerCase(),pane1.domNode.innerHTML.toLowerCase());
+							t.is(1, pane1.getChildren().length);
 						}
 					},
+					function startupCalled(){
+						doh.t(select._started, "select widget was created, and startup was called");
+					},
 					{
 						name: 'changeContentTRHead',
 						runTest: function(t){
@@ -100,9 +111,9 @@
 							var trHead = dojo.query('table#tableTest > thead > tr')[0];
 							pane2 = new dojox.layout.ContentPane({} , trHead);
 							var html = "<td><div>This</div>Should<u>Work</u></td>";
-							pane2.attr('content', html);
+							pane2.set('content', html);
 							var res = ieTrimSpaceBetweenTags(pane2.domNode.innerHTML.toLowerCase());
-							t.assertEqual(html.toLowerCase(), res);
+							t.is(html.toLowerCase(), res);
 						},
 						tearDown: function(){
 							pane2.destroy();
@@ -115,9 +126,9 @@
 							var tHead = dojo.query('table#tableTest > thead')[0];
 							pane2 = new dojox.layout.ContentPane({}, tHead);
 							var html = "<tr><td><div>This</div>Should<u>Work</u></td></tr>";
-							pane2.attr('content', html);
+							pane2.set('content', html);
 							var res = ieTrimSpaceBetweenTags(pane2.domNode.innerHTML.toLowerCase());
-							t.assertEqual(html.toLowerCase(), res);
+							t.is(html.toLowerCase(), res);
 						},
 						tearDown: function(){
 							pane2.destroy();
@@ -130,9 +141,9 @@
 							var trBody = dojo.query('table#tableTest > tbody > tr')[0];
 							pane2 = new dojox.layout.ContentPane({}, trBody);
 							var html = "<td><div>This</div>Should<u>Work</u></td>";
-							pane2.attr('content', html);
+							pane2.set('content', html);
 							var res = ieTrimSpaceBetweenTags(pane2.domNode.innerHTML.toLowerCase());
-							t.assertEqual(html.toLowerCase(), res);
+							t.is(html.toLowerCase(), res);
 						},
 						tearDown: function(){
 							pane2.destroy();
@@ -145,9 +156,9 @@
 							var tBody = dojo.query('table#tableTest > tbody')[0];
 							pane2 = new dojox.layout.ContentPane({}, tBody);
 							var html = "<tr><td><div>This</div>Should<u>Work</u></td></tr>";
-							pane2.attr('content', html);
+							pane2.set('content', html);
 							var res = ieTrimSpaceBetweenTags(pane2.domNode.innerHTML.toLowerCase());
-							t.assertEqual(html.toLowerCase(), res);
+							t.is(html.toLowerCase(), res);
 						},
 						tearDown: function(){
 							pane2.destroy();
@@ -160,9 +171,9 @@
 							var table = dojo.query('table#tableTest')[0];
 							pane2 = new dojox.layout.ContentPane({}, table);
 							var html = "<tbody><tr><td><div>This</div>Should<u>Work</u></td></tr></tbody>";
-							pane2.attr('content', html);
+							pane2.set('content', html);
 							var res = ieTrimSpaceBetweenTags(pane2.domNode.innerHTML.toLowerCase());
-							t.assertEqual(html.toLowerCase(), res);
+							t.is(html.toLowerCase(), res);
 						},
 						tearDown: function(){
 							pane2.destroy();
@@ -174,10 +185,10 @@
 						runTest: function(t){
 							console.log("basicChecks: " + this.name);
 							pane1.ioArgs.sync = true;
-							pane1.attr('href', dojo.moduleUrl('dijit', 'tests/layout/getResponse.php?delay=100&message=sync'));
+							pane1.set('href', dojo.moduleUrl('dijit', 'tests/layout/getResponse.php?delay=100&message=sync'));
 
 							// since it was a sync fetch it should be loaded here
-							t.assertEqual('sync', pane1.domNode.innerHTML);
+							t.is('sync', pane1.domNode.innerHTML);
 						},
 						tearDown: function(){
 							pane1.ioArgs = {}; // back to defaults
@@ -190,13 +201,13 @@
 							console.log("basicChecks: " + this.name);
 							// test if we can set a custom header on every request
 							pane1.ioArgs.headers = {'X-TestHeader': 'Testing'};
-							pane1.attr('href', 'remote/getResponse.php?mode=bounceHeaders');
+							pane1.set('href', 'remote/getResponse.php?mode=bounceHeaders');
 
 							var d = new t.Deferred();
 							setTimeout(d.getTestCallback(function(){
 								var cont = pane1.domNode.innerHTML;
-								t.assertTrue(/X-TestHeader/i.test(cont));
-								t.assertTrue(/Testing/i.test(cont));
+								t.t(/X-TestHeader/i.test(cont), "X-TestHeader");
+								t.t(/Testing/i.test(cont), "Testing");
 							}), 1500);
 
 							return d;
@@ -213,11 +224,11 @@
 							// test to post some content on each request
 							pane1.ioMethod = dojo.xhrPost;
 							pane1.ioArgs.content = {test:'it should work'};
-							pane1.attr('href', 'remote/getResponse.php?mode=bounceInput');
+							pane1.set('href', 'remote/getResponse.php?mode=bounceInput');
 
 							var d = new t.Deferred();
 							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('test=it%20should%20work', pane1.domNode.innerHTML);
+								t.is('test=it%20should%20work', pane1.domNode.innerHTML);
 							}), 1500);
 							return d;
 						},
@@ -232,13 +243,13 @@
 						runTest: function(t){
 							console.log("basicChecks: " + this.name);
 							var unLoadCalled, loadCalled;
-							var handle = pane1.attr('content', "test 'var handle = attr('content', '')'");
+							var handle = pane1.set('content', "test 'var handle = set('content', '')'");
 
 							handle.addCallback(function(){
 								loadCalled = true;
 							});
 
-							t.assertTrue(loadCalled);
+							t.t(loadCalled, "loadCalled");
 						}
 					},
 					{
@@ -250,8 +261,8 @@
 							var r_loadCalled;
 							var r_handle, href = dojo.moduleUrl('dijit', 'tests/layout/getResponse.php?delay=100&message=test');
 
-							var handle = pane1.attr('href', href);
-							t.assertTrue(handle);
+							var handle = pane1.set('href', href);
+							t.t(handle, "handle 1");
 							handle.addCallback(function(){
 								console.log("handleFrom_setHref_and_refresh_and_cancelWorking: handle onLoad");
 								loadCalled = 'loadCalled';
@@ -264,12 +275,12 @@
 								console.log("handleFrom_setHref_and_refresh_and_cancelWorking: setting href: " + href);
 								pane1.href = href;
 								handle = pane1.refresh();
-								t.assertTrue(handle);
+								t.t(handle, "handle 2");
 								r_handle = 'refreshHandle ok';
 								handle.addCallback(function(){
 									console.log("handleFrom_setHref_and_refresh_and_cancelWorking: 2ary handle onload");
 									r_loadCalled = 'refresh loadCalled';
-									pane1.attr('content', ''); // trigger unload
+									pane1.set('content', ''); // trigger unload
 								});
 							}, 1500); // wait for page load in case cancel didn't work
 
@@ -277,11 +288,11 @@
 
 							setTimeout(d.getTestCallback(function(){
 								// load from the href (was canceled)
-								t.assertEqual(undefined, loadCalled);
+								t.is(undefined, loadCalled);
 
 								// load from the refresh
-								t.assertEqual('refreshHandle ok', r_handle);
-								t.assertEqual('refresh loadCalled', r_loadCalled);
+								t.is('refreshHandle ok', r_handle);
+								t.is('refresh loadCalled', r_loadCalled);
 							}), 3200);
 
 							return d;
@@ -298,7 +309,7 @@
 							// setup text fixture for these pathAdjustments tests
 							if(!pane1._contentSetter) {
 								// make sure the contentSetter is created, by doing a simple setContent 
-								pane1.attr("content", "");
+								pane1.set("content", "");
 							}
 						},
 						name: 'cssPathAdjustments',
@@ -323,7 +334,7 @@
 							+' @import url(/did/you/now.css);'+"\n"
 							+' @import "yes.i.did";';
 
-							pane1.referencePath = "deep/nested/file";	// hook for testing to trigger path adjustment on an attr('content', ...)
+							pane1.referencePath = "deep/nested/file";	// hook for testing to trigger path adjustment on an set('content', ...)
 							pane1.adjustPaths = true;
 							pane1.renderStyles = true;
 							var adjustedCss;
@@ -335,9 +346,9 @@
 							pane1._contentSetter._renderStyles = function(styles){
 								console.log("in replaced _renderStyles");
 								adjustedCss = styles.join();
-							}
+							};
 							console.log("in cssPathAdjustments, calling set");
-							pane1.attr('content', '<style>'+cssText+'</style>');
+							pane1.set('content', '<style>'+cssText+'</style>');
 							console.log("in cssPathAdjustments, done calling set");
 							pane1._contentSetter._renderStyles = oldFunc;
 
@@ -359,7 +370,7 @@
 
 							// we split and loop to get a faster hint of where it failed
 							for(var i = 0; i < expectedCss.length; i++){
-								t.assertEqual(expectedCss[i], adjustedCss[i]);
+								t.is(expectedCss[i], adjustedCss[i]);
 							}
 						},
 						tearDown: function(){
@@ -382,13 +393,13 @@
 									// check that images and styles have been applied
 									var cb = dojo.contentBox(dojo.byId('imgTest'));
 											//dojo.getComputedStyle(dojo.byId('imgTest'));
-									t.assertEqual(188, cb.w);
-									t.assertEqual(125, cb.h);
+									t.is(188, cb.w);
+									t.is(125, cb.h);
 
 									// make sure we didn't mess up the other inline styles
 									cb = dojo.contentBox(dojo.byId('inlineStyleTest'));
-									t.assertEqual(188, cb.w);
-									t.assertEqual(125, cb.h);
+									t.is(188, cb.w);
+									t.is(125, cb.h);
 
 									// make sure it is the correct image
 									var cs = dojo.getComputedStyle(dojo.byId('inlineStyleTest'));
@@ -397,32 +408,32 @@
 									url = url.replace(/^\s?url\(['"]?/, "").replace(/['"]?\);?\s?$/, ""); 
 									// compare image url to full path of this document
 									imageUrl = dojo.moduleUrl('dojox', 'layout/tests/images/testImage.gif');
-									t.assertEqual(new dojo._Url(document.location, imageUrl).toString(), url);
+									t.is(new dojo._Url(document.location, imageUrl).toString(), url);
 
 									// make sure we loaded the <link rel='stylesheet' correctly
 									var mb = dojo.marginBox(dojo.byId('linkCssTest'));
-									t.assertEqual(112, mb.w); // 100px	+ 2px border + 4px margin = 112px
-									t.assertEqual(112, mb.h);
+									t.is(112, mb.w); // 100px	+ 2px border + 4px margin = 112px
+									t.is(112, mb.h);
 
 									// make sure we loaded the <style>@import '...'; correctly
 									mb = dojo.marginBox(dojo.byId('importCssTest'));
-									t.assertEqual(110, mb.w); // 100px + 1px border + 4px margin = 110px
-									t.assertEqual(110, mb.h);
+									t.is(110, mb.w); // 100px + 1px border + 4px margin = 110px
+									t.is(110, mb.h);
 
 									// make sure we didn't render the <link media='print' rel='stylesheet'
 									var mb = dojo.marginBox(dojo.byId('linkMediaTest'));
-									t.assertEqual(212, mb.w); // 100px	+ 2px border + 4px margin = 112px
-									t.assertEqual(212, mb.h);
+									t.is(212, mb.w); // 100px	+ 2px border + 4px margin = 112px
+									t.is(212, mb.h);
 
 									// make sure we didn't render the <style media='print'>@import '...';
 									mb = dojo.marginBox(dojo.byId('importMediaTest'));
-									t.assertEqual(210, mb.w); // 100px + 1px border + 4px margin = 110px
-									t.assertEqual(210, mb.h);
+									t.is(210, mb.w); // 100px + 1px border + 4px margin = 110px
+									t.is(210, mb.h);
 								}
 							), 1500);
 
 							pane1.adjustPaths=true; pane1.renderStyles=true;
-							pane1.attr('href', 'remote/getResponse.php?mode=htmlPaths');
+							pane1.set('href', 'remote/getResponse.php?mode=htmlPaths');
 							return d;
 						},
 						tearDown: function(){
@@ -444,17 +455,17 @@
 
 									// make sure we didn't load the <link rel='stylesheet'
 									//var mb = dojo.marginBox(dojo.byId('linkCssTest'));
-									//t.assertFalse(112 == mb.w);
-									//t.assertFalse(112 == mb.h);
+									//t.isNot(112, mb.w, "width");
+									//t.isNot(112, mb.h, "height");
 									// make sure we didn't load the <style>@import '...';
 
 									var mb = dojo.marginBox(dojo.byId('importCssTest'));
-									t.assertFalse(110 == mb.w);
-									t.assertFalse(110 == mb.h);
+									t.isNot(110, mb.w, "width 2");
+									t.isNot(110, mb.h, "height 2");
 								}
 							), 1500);
 							pane1.adjustPaths=true;
-							pane1.attr('href', 'remote/getResponse.php?mode=htmlPaths');
+							pane1.set('href', 'remote/getResponse.php?mode=htmlPaths');
 							return d;
 						},
 						tearDown: function(){
@@ -466,20 +477,20 @@
 
 			doh.register("scriptTests",
 				[
-					"t.assertTrue(pane1.executeScripts);",
+					"t.t(pane1.executeScripts, 'executeScripts');",
 					{
 						name: 'leaveDojoMethodScriptsAsIs',
 						runTest: function(t){
 							console.log("scriptTests: " + this.name);
-							pane1.attr('content', "<"
+							pane1.set('content', "<"
 								+"script type='dojo/method'>unTypedVarInDocScope = 'failure';<"
 								+"/script>");
 
 							var d = new t.Deferred();
 							// IE req to async this test
 							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('undefined', typeof unTypedVarInDocScope);
-								t.assertFalse(unTypedVarInDocScope == 'failure');
+								t.is('undefined', typeof unTypedVarInDocScope);
+								t.isNot("failure", unTypedVarInDocScope);
 							}), 40);
 
 							return d;
@@ -490,7 +501,7 @@
 						timeout: 1800, // grabing remote js, wait for that
 						runTest: function(t){
 							console.log("scriptTests: " + this.name);
-							pane1.attr('content', "<"
+							pane1.set('content', "<"
 								+"script>function scriptsInGlobalClicked(){ documentCallback(); }<"
 								+"/script><"+"script src='remote/getResponse.php?mode=remoteJsTrue'></"
 								+"script>"+"<a href='javascript:scriptsInGlobalClicked()' "
@@ -501,9 +512,9 @@
 							var d = new t.Deferred();
 					
 							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('boolean', typeof documentCallback.reached);
-								t.assertTrue(documentCallback.reached);
-								t.assertTrue(unTypedVarInDocScope);
+								t.is('boolean', typeof documentCallback.reached);
+								t.t(documentCallback.reached, "documentCallback.reached");
+								t.t(unTypedVarInDocScope, "unTypedVarInDocScope");
 							}), 40);
 							return d;
 						}
@@ -513,7 +524,7 @@
 						timeout: 1800,// grabing remote js, wait for that
 						runTest: function(t){
 							console.log("scriptTests: " + this.name);
-							pane1.attr('content', "<"
+							pane1.set('content', "<"
 								+"script src='remote/getResponse.php?mode=remoteJsFalse'><"
 								+"/script><"+"script>unTypedVarInDocScope = 1;<"
 								+"/script>"); // scripts only test
@@ -521,8 +532,8 @@
 							// we need to make this async because of IEs strange events loops
 							var d = new t.Deferred();
 							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('number', typeof unTypedVarInDocScope);
-								t.assertEqual(1, unTypedVarInDocScope);
+								t.is('number', typeof unTypedVarInDocScope);
+								t.is(1, unTypedVarInDocScope);
 							}), 40);
 							return d;
 						}
@@ -531,14 +542,14 @@
 						name: 'scriptsWithTypeTextJavascript',
 						runTest: function(t){
 							console.log("scriptTests: " + this.name);
-							pane1.attr('content', "<"
+							pane1.set('content', "<"
 								+"script type='text/javascript'> unTypedVarInDocScope = 'text/javascript'; <"
 								+"/script>");
 
 							var d = new t.Deferred();
 							// IE needs async here
 							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('text/javascript', unTypedVarInDocScope);
+								t.is('text/javascript', unTypedVarInDocScope);
 							}), 40);
 							return d;
 						}
@@ -548,15 +559,15 @@
 						runTest: function(t){
 							console.log("scriptTests: " + this.name);
 							pane1.cleanContent = true;
-							pane1.attr('content', "<"
+							pane1.set('content', "<"
 								+"script><!-- unTypedVarInDocScope = 2; --><"
 								+"/script>");
 
 							var d = new t.Deferred();
 							// IE need a async here
 							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('number', typeof unTypedVarInDocScope);
-								t.assertEqual(2, unTypedVarInDocScope);
+								t.is('number', typeof unTypedVarInDocScope);
+								t.is(2, unTypedVarInDocScope);
 							}), 40);
 
 							return d;
@@ -570,15 +581,15 @@
 						runTest: function(t){
 							console.log("scriptTests: " + this.name);
 							pane1.cleanContent = true;
-							pane1.attr('content', "<"
+							pane1.set('content', "<"
 								+"script><![CDATA[ unTypedVarInDocScope = 3; ]]><"
 								+"/script>");
 
 							var d = new t.Deferred();
 							// IE need a async here
 							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('number', typeof unTypedVarInDocScope);
-								t.assertEqual(3, unTypedVarInDocScope);
+								t.is('number', typeof unTypedVarInDocScope);
+								t.is(3, unTypedVarInDocScope);
 							}), 40);
 
 							return d;
@@ -621,13 +632,13 @@
 											"<", "/script>\n",
 											"</body>\n",
 											"</html>\n"].join("");
-							pane1.attr("content", content);
+							pane1.set("content", content);
 
 							// let IE inhale here
 							var d = new t.Deferred();
 							setTimeout(d.getTestCallback(function(){
-								t.assertEqual("boolean" , typeof shouldBeDefined);
-								t.assertEqual("undefined" , typeof shouldNotBeDefined);
+								t.is("boolean" , typeof shouldBeDefined);
+								t.is("undefined" , typeof shouldNotBeDefined);
 							}), 40);
 							return d;
 						}
@@ -638,7 +649,7 @@
 							console.log("scriptTests: " + this.name);
 							unTypedVarInDocScope = 'failure';
 							pane1.scriptHasHooks = true;
-							pane1.attr('content', "<"
+							pane1.set('content', "<"
 							+"script>function testReplace(){"
 							+	"if(typeof _container_ != 'object'){return 'not replaced 1';}\n"
 							+	"if(_container_ != pane1){ return 'not replaced 2';}\n"
@@ -655,7 +666,7 @@
 							// let IE inhale here
 							var d = new t.Deferred();
 							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('success', unTypedVarInDocScope);
+								t.is('success', unTypedVarInDocScope);
 							}), 40);
 							return d;
 						},
@@ -668,7 +679,7 @@
 						runTest: function(t){
 							console.log("scriptTests: " + this.name);
 							pane1.scriptHasHooks = true;
-							pane1.attr('content', "<"
+							pane1.set('content', "<"
 								+"script>"
 								+"var testConn;"
 								+"_container_.onLoadDeferred.addCallback(function(){"
@@ -689,16 +700,16 @@
 							var d = new t.Deferred();
 							// IE must breathe here
 							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('loaded', unTypedVarInDocScope);
+								t.is('loaded', unTypedVarInDocScope);
 							}), 40);
 							return d;
 						},
 						tearDown: function(){
 							delete pane1.scriptHasHooks; // get back to default
-							pane1.attr('content', '');
+							pane1.set('content', '');
 						}
 					},
-					"t.assertEqual('unloaded', unTypedVarInDocScope)"
+					"t.is('unloaded', unTypedVarInDocScope)"
 					*/
 				]
 			);
@@ -746,7 +757,7 @@
 
 						expectedCss = expectedCss.split("\n");
 
-						pane1.referencePath = "deep/nested/file";	// hook for testing to trigger path adjustment on an attr('content', ...)
+						pane1.referencePath = "deep/nested/file";	// hook for testing to trigger path adjustment on an set('content', ...)
 						pane1.adjustPaths = true;
 						pane1.renderStyles = true;
 						var adjustedCss;
@@ -761,7 +772,7 @@
 						}
 
 						var start = new Date();
-						pane1.attr('content', '<style>'+cssText+'</style>');
+						pane1.set('content', '<style>'+cssText+'</style>');
 						var end = new Date();
 						pane1._contentSetter._renderStyles = oldFunc;
 
@@ -775,7 +786,7 @@
 
 						// we split and loop to get a faster hint of where it failed
 						for(var i = 0; i < expectedCss.length; i++){
-							t.assertEqual(expectedCss[i], adjustedCss[i]);
+							t.is(expectedCss[i], adjustedCss[i]);
 						}
 					},
 					tearDown: function(){
@@ -850,7 +861,7 @@
 						}
 
 
-						pane1.referencePath = "deep/nested/file";	// hook for testing to trigger path adjustment on an attr('content', ...)
+						pane1.referencePath = "deep/nested/file";	// hook for testing to trigger path adjustment on an set('content', ...)
 						pane1.adjustPaths = true;
 						pane1.renderStyles = true;
 						pane1.cleanContent = true;
@@ -876,7 +887,7 @@
 						dojo.xhrGet = function(){}; // kill script download
 
 						var start = new Date();
-						pane1.attr('content', htmlText);
+						pane1.set('content', htmlText);
 						var end = new Date();
 
 						// reset back to the way it was
@@ -896,18 +907,18 @@
 						for(var i = 0; i < expectedHtml.length; i++){
 							//console.debug(expectedHtml[i], i);
 							//console.debug(adjustedHtml[i], i);
-							t.assertEqual(expectedHtml[i], adjustedHtml[i]);
+							t.is(expectedHtml[i], adjustedHtml[i]);
 						}
 
 						var exCssBlock, adjCssBlock;
 						for(var i = 0; i < expectedCss.length; i++){
-							t.assertEqual('string', typeof adjustedCss[i]);
+							t.is('string', typeof adjustedCss[i]);
 
 							exCssBlock = expectedCss[i].split('\n');
 							adjCssBlock = adjustedCss[i].split('\n');
 
 							for(var j = 0; j < exCssBlock.length;j++){
-								t.assertEqual(dojo.trim(exCssBlock[j]), dojo.trim(adjCssBlock[j]));
+								t.is(dojo.trim(exCssBlock[j]), dojo.trim(adjCssBlock[j]));
 							}
 							
 						}
@@ -933,7 +944,7 @@
 						pane1.renderStyles = true;
 
 						pane1.href = "deep/";
-						pane1.referencePath = "deep/";	// hook for testing to trigger path adjustment on an attr('content', ...)
+						pane1.referencePath = "deep/";	// hook for testing to trigger path adjustment on an set('content', ...)
 
 						var html = "<div style='width:10px;height:10px;filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=\"scale\", src=\"images/alpha(1).png\", nextProperty=\"useless\");'><!-- \n"
 						+" alpha png in IE 6 --></div>\n"
@@ -976,10 +987,10 @@
 						pane1._contentSetter._renderStyles = function(styles){ adjustedCss = styles.join(''); };
 						pane1._contentSetter.setContent = function(){
 							adjustedHtml = this.content;
-						}
+						};
 
 						var start = new Date();
-						pane1.attr('content', html);
+						pane1.set('content', html);
 						var end = new Date();
 
 						console.info('Time used to replace AlphaImageLoader(src="...") '
@@ -995,13 +1006,13 @@
 						expectedHtml = expectedHtml.split("\n");
 						adjustedHtml = adjustedHtml.split("\n");
 						for(var i = 0; i < expectedHtml.length; i++){
-							t.assertEqual(expectedHtml[i], adjustedHtml[i]);
+							t.is(expectedHtml[i], adjustedHtml[i]);
 						}
 
 						expectedCss = expectedCss.split("\n");
 						adjustedCss = adjustedCss.split("\n");
 						for(var i = 0; i < expectedCss.length; i++){
-							t.assertEqual(expectedCss[i], adjustedCss[i]);
+							t.is(expectedCss[i], adjustedCss[i]);
 						}
 						
 					},
@@ -1037,7 +1048,7 @@
 
 				pane1.executeScripts = true;
 				pane1.renderStyles = true;
-				pane1.attr('content', html+showHowHtml);
+				pane1.set('content', html+showHowHtml);
 				
 
 				}
@@ -1089,5 +1100,11 @@
 			</tr>
 		<tbody>
 	</table>
+
+	<div data-dojo-type="dojox/layout/ContentPane" data-dojo-id="startupTest">
+		<select data-dojo-type="dijit/form/Select" data-dojo-id="select">
+			<option>hi</option>
+		</select>
+	</div>
 </body>
 </html>
diff --git a/dojox/layout/tests/_bottomPane.html b/dojox/layout/tests/_bottomPane.html
index 8f5090a..f65cb78 100644
--- a/dojox/layout/tests/_bottomPane.html
+++ b/dojox/layout/tests/_bottomPane.html
@@ -2,7 +2,7 @@
 	Bottom Pane Content:
 	<button dojoType="dijit.form.Button">
 		Setup Toggler
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			// only do this once:
 			this.setAttribute('disabled',true);
 			var pane = dijit.getEnclosingWidget(this.domNode.parentNode);
@@ -42,7 +42,7 @@
 
 	<button dojoType="dijit.form.Button">
 		Minimize
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			// simplified version of above:
 			var pane = dijit.getEnclosingWidget(this.domNode.parentNode);
 			pane.domNode.style.height = "1px";
diff --git a/dojox/layout/tests/_floating.html b/dojox/layout/tests/_floating.html
index 5fe8f2d..9ac22ae 100644
--- a/dojox/layout/tests/_floating.html
+++ b/dojox/layout/tests/_floating.html
@@ -4,7 +4,7 @@
 	<br>
 	<button dojoType="dijit.form.Button">
 		Dock To Tab
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			this.setAttribute("disabled",true);
 			var c = dijit.getEnclosingWidget(this.domNode.parentNode);
 			dojo.style(c.focusNode,"display","none");
@@ -21,7 +21,7 @@
 	<br>
 	<button dojoType="dijit.form.Button">
 		Dock To Accordion
-		<script type="dojo/method" event="onClick">
+		<script type="dojo/method" data-dojo-event="onClick">
 			this.setAttribute("disabled",true);
 			var n = dijit.getEnclosingWidget(this.domNode.parentNode);
 			dojo.style(n.focusNode,"display","none");
diff --git a/dojox/layout/tests/test_DragPane.html b/dojox/layout/tests/test_DragPane.html
index 6b9eb6b..1580b0c 100644
--- a/dojox/layout/tests/test_DragPane.html
+++ b/dojox/layout/tests/test_DragPane.html
@@ -13,9 +13,6 @@
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
-	<!-- for debugging: -->
-	<script type="text/javascript" src="../DragPane.js"></script>
-
 	<script type="text/javascript">
 		dojo.require("dojox.layout.DragPane");
 		dojo.require("dojo.parser");
diff --git a/dojox/layout/tests/test_ExpandoPane.html b/dojox/layout/tests/test_ExpandoPane.html
index ff83ec9..7ab7969 100644
--- a/dojox/layout/tests/test_ExpandoPane.html
+++ b/dojox/layout/tests/test_ExpandoPane.html
@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html>
+<html lang="en">
 <head>
 	<title>dojox.layout.ExpandoPane</title>
 
@@ -9,7 +9,7 @@
 	<link rel="stylesheet" href="_expando.css">	
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true, popup:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true, popup:true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -179,7 +179,7 @@
 
 	</script>
 </head>
-<body class="claro">
+<body class="claro" role="main">
 		<div id="bc" style="width:100%; height:100%; padding: 5px;" dojoType="dijit.layout.BorderContainer">
 			<div id="header" dojoType="dijit.layout.ContentPane" region="top" splitter="true">Dojo Expando Pane Test</div>
 			<div dojoType="dojox.layout.ExpandoPane" 
@@ -195,10 +195,10 @@
 					<div dojoType="dijit.layout.ContentPane" title="Search">
 						<div class="searchBar">
 							<p>
-								<span style="float: left;">Search:</span>
+								<label for="searchBox" style="float: left;">Search:</label>
 								<input id="searchBox" name="searchBox" style="float: left;">
 								<span id="runSearchIcon" style="border: none; floast: left; padding: 3px;">
-									<img src="../../presentation/resources/icons/next.png" style="height:12px; width:12px;">
+									<img src="../../presentation/resources/icons/next.png" alt="run search" style="height:12px; width:12px;">
 								</span>
 							</p>
 						</div>
@@ -216,7 +216,7 @@
 						</div>
 					</div>
 					<div dojoType="dijit.layout.ContentPane" title="Tree View">
-						<div dojoType="dojo.data.ItemFileReadStore" jsId="continentStore"
+						<div dojoType="dojo.data.ItemFileReadStore" data-dojo-id="continentStore"
 							url="../../../dijit/tests/_data/countries.json"></div>
 						<div dojoType="dijit.Tree" store="continentStore" query="{type:'continent'}"
 							labelAttr="name" typeAttr="type" label="Toolkit API"></div>
@@ -227,7 +227,7 @@
 				<div dojoType="dijit.layout.ContentPane" title="tab 1">a</div>
 				<div dojoType="dijit.layout.ContentPane" title="tab 2">
 					<button dojoType="dijit.form.Button">Preview left
-						<script type="dojo/method" event="onClick">
+						<script type="dojo/method" data-dojo-event="onClick">
 							dijit.byId("leftPane").preview();
 						</script>
 				</div>
@@ -252,8 +252,8 @@
 				<div dojoType="dijit.layout.AccordionContainer" id="rightAccordion" style="width:275px;" attachParent="true">
 					<div dojoType="dijit.layout.ContentPane" title="Easing Selection">
 						<div class="wrap">
-							<p>This select modifies the left Expando's easing function. An Expando can have an easeIn and an easeOut parameter. This sets both.</p> 
-							<select id="easingSelect" name="easingSelect">
+							<p id="easingSelectLabel">This select modifies the left Expando's easing function. An Expando can have an easeIn and an easeOut parameter. This sets both.</p> 
+							<select id="easingSelect" name="easingSelect" aria-labelledby="easingSelectLabel">
 								<option value="dojo._DefaultEasing">Default</option>
 							</select>
 							<p><label for="durationBox">Duration: </label> <input id="durationBox" name="durationBox" value="1000" /></p>
@@ -269,7 +269,7 @@
 							<p>
 							<button dojoType="dijit.form.Button">
 								Make Floater
-								<script type="dojo/connect" event="onClick">
+								<script type="dojo/connect" data-dojo-event="onClick">
 									var div = dojo.doc.createElement('div');
 									dojo.body().appendChild(div);
 									var fp = new dojox.layout.FloatingPane({
@@ -307,7 +307,7 @@
 					<div dojoType="dijit.layout.ContentPane" title="Search">
 						<button dojoType="dijit.form.Button">
 							Change Title
-							<script type="dojo/method" event="onClick">
+							<script type="dojo/method" data-dojo-event="onClick">
 								dijit.byId("bottomPane").set("title", new Date())
 							</script>
 						</button>
diff --git a/dojox/layout/tests/test_ExpandoPane_code.html b/dojox/layout/tests/test_ExpandoPane_code.html
index 6455bb9..46a99f5 100644
--- a/dojox/layout/tests/test_ExpandoPane_code.html
+++ b/dojox/layout/tests/test_ExpandoPane_code.html
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
         "http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="en">
 <head>
 	<title>dojox.layout.ExpandoPane</title>
 
@@ -10,7 +10,7 @@
 	<link rel="stylesheet" href="_expando.css">	
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -57,17 +57,19 @@
 		#pane0 { background:yellow; }
 	</style>
 </head>
-<body class="tundra">
+<body class="tundra" role="main">
 		<div id="bc" style="width:100%; height:100%;" dojoType="dijit.layout.BorderContainer">
 			<div region="center" style="height:65px; border-bottom:1px solid #666">
-				<button dojoType="dijit.form.Button">
+				<button data-dojo-type="dijit.form.Button" type="button" region="top">
 					Set 3-pane
-					<script type="dojo/method" event="onClick">
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
 						_clearPane();
 						var bc = dijit.byId("bc");
 						
-						var cp = new dijit.layout.ContentPane({
+					//	var cp = new dijit.layout.ContentPane({
+						var cp = new dojox.layout.ExpandoPane({
 							region:"left",
+							duration:125,
 							style:"width:125px; height:100%",
 							splitter:true
 						});
diff --git a/dojox/layout/tests/test_ExpandoPane_more.html b/dojox/layout/tests/test_ExpandoPane_more.html
index c229fd6..aadaa77 100644
--- a/dojox/layout/tests/test_ExpandoPane_more.html
+++ b/dojox/layout/tests/test_ExpandoPane_more.html
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
         "http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="en">
 <head>
 	<title>dojox.layout.ExpandoPane</title>
 
@@ -11,7 +11,7 @@
 	<link rel="stylesheet" href="../../../dijit/tests/css/dijitTests.css">
 	
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -32,7 +32,7 @@
 		dojo.require("dojo.fx.easing");
 	</script>
 </head>
-<body class="tundra">
+<body class="tundra" role="main">
 
 	<h1>Basic ExpandoPane tests</h1>
 
diff --git a/dojox/layout/tests/test_ExpandoPane_prog.html b/dojox/layout/tests/test_ExpandoPane_prog.html
index dfc7228..9025f27 100644
--- a/dojox/layout/tests/test_ExpandoPane_prog.html
+++ b/dojox/layout/tests/test_ExpandoPane_prog.html
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="en">
 <head>
 	<title>dojox.layout.ExpandoPane</title>
 
@@ -13,7 +13,7 @@
 	<link rel="stylesheet" href="../../../dijit/tests/css/dijitTests.css" />
 	
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -97,7 +97,7 @@
 
 	</script>
 </head>
-<body class="tundra">
+<body class="tundra" role="main">
 	<h1 class="testTitle">Programatic ExpandoPane Test</h1>
 	<div id="container0"></div>
 </body>
diff --git a/dojox/layout/tests/test_ExpandoPane_splitters.html b/dojox/layout/tests/test_ExpandoPane_splitters.html
index e9ae23c..c92f03a 100644
--- a/dojox/layout/tests/test_ExpandoPane_splitters.html
+++ b/dojox/layout/tests/test_ExpandoPane_splitters.html
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
         "http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="en">
 <head>
 	<title>dojox.layout.ExpandoPane</title>
 
@@ -11,7 +11,7 @@
 	<link rel="stylesheet" href="../../../dijit/tests/css/dijitTests.css">
 	
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.layout.ContentPane");
@@ -19,7 +19,7 @@
 		dojo.require("dojox.layout.ExpandoPane");
 	</script>
 </head>
-<body class="tundra">
+<body class="tundra" role="main">
 
 	<h1>Testing splitters on ExpandoPanes</h1>
 
diff --git a/dojox/layout/tests/test_FloatingPane.html b/dojox/layout/tests/test_FloatingPane.html
index 9666131..ec5e448 100644
--- a/dojox/layout/tests/test_FloatingPane.html
+++ b/dojox/layout/tests/test_FloatingPane.html
@@ -10,7 +10,7 @@
 	<link rel="stylesheet" href="../resources/ResizeHandle.css">
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/layout/tests/test_GridContainer.html b/dojox/layout/tests/test_GridContainer.html
index e50ecf3..2408921 100644
--- a/dojox/layout/tests/test_GridContainer.html
+++ b/dojox/layout/tests/test_GridContainer.html
@@ -40,7 +40,7 @@
 			
 		</style>
 		
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
diff --git a/dojox/layout/tests/test_GridContainerColWidths.html b/dojox/layout/tests/test_GridContainerColWidths.html
index 546f982..8b9ad7a 100644
--- a/dojox/layout/tests/test_GridContainerColWidths.html
+++ b/dojox/layout/tests/test_GridContainerColWidths.html
@@ -55,7 +55,7 @@
 		<link rel="stylesheet" href="../resources/GridContainer.css">
 		<link rel="stylesheet" href="../resources/DndGridContainer.css">
 		
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
diff --git a/dojox/layout/tests/test_GridContainerLite.html b/dojox/layout/tests/test_GridContainerLite.html
index e51fe36..3eceb28 100644
--- a/dojox/layout/tests/test_GridContainerLite.html
+++ b/dojox/layout/tests/test_GridContainerLite.html
@@ -1,12 +1,11 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!DOCTYPE html>
 <html>
 	<head>
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
 		<title>Demo GridContainer</title>
 
-		<style type="text/css" title="text/css">
+		<style title="text/css">
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dijit/themes/tundra/tundra.css";
 			
@@ -46,47 +45,7 @@
 				margin: 10px !important;
 			}
 		</style>
-		
 		<link rel="stylesheet" href="../resources/GridContainer.css">
-		
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
-		
-		<script type="text/javascript">
-			dojo.require("dojo.parser");
-			dojo.require("dijit.TitlePane");
-			dojo.require("dijit.layout.ContentPane");
-			dojo.require("dojox.layout.GridContainerLite");
-			dojo.require("dijit.Calendar");
-
-			var canDisplayPopup = true;
-			
-			function displayPopup(gridContainer) {
-				//	summary:
-				//		Display a popup when a widget can not be moved (not accepted type)
-
-				if(canDisplayPopup){
-					canDisplayPopup = false;
-					var popup = dojo.doc.createElement("div");
-					dojo.addClass(popup, "gridContainerPopup");
-					popup.innerHTML = "Impossible to move this widget ! ";
-					var attachPopup = dijit.byId("GC1").containerNode.appendChild(popup);
-					setTimeout(dojo.hitch(this, function(){
-						dijit.byId("GC1").containerNode.removeChild(attachPopup);
-						dojo.destroy(attachPopup);
-						canDisplayPopup = true;
-					}), 1500);
-				}
-			};
-
-			dojo.addOnLoad(function(){
-				dojo.subscribe("/dojox/layout/gridContainer/moveRestriction",displayPopup);
-			});
-	
-				
-
-		</script>
-
 	</head>
 
 	<body class="tundra">
@@ -99,24 +58,53 @@
 			</ul>
 		<h2>Grid Container (acceptTypes="ContentPane, Calendar", nbZones="3", isAutoOrganized="true", doLayout="false")</h2>
 			
-			<div id="GC1" dojoType="dojox.layout.GridContainerLite" 
+			<div id="GC1" data-dojo-type="dojox/layout/GridContainerLite" 
 				nbZones="3"
 				hasResizableColumns="false" 
 				doLayout="false" 
 				acceptTypes="ContentPane, Calendar">
-					<div dojoType="dijit.layout.ContentPane" class="cpane" label="Content Pane" dndType="ContentPane" >Content Pane n°1 !</div>
-					<div dojoType="dijit.TitlePane" title="Ergo" dndType="TitlePane" >
+					<div data-dojo-type="dijit/layout/ContentPane" class="cpane" label="Content Pane" dndType="ContentPane" >Content Pane n°1 !</div>
+					<div data-dojo-type="dijit/TitlePane" title="Ergo" dndType="TitlePane" >
 						Non ergo erunt homines deliciis diffluentes audiendi, si quando de amicitia, quam nec usu nec ratione habent cognitam, disputabunt. Nam quis est, pro deorum fidem atque hominum! qui velit, ut neque diligat quemquam nec ipse ab ullo diligatur, circumfluere omnibus copiis atque in omnium rerum abundantia vivere? Haec enim est tyrannorum vita nimirum, in qua nulla fides, nulla caritas, nulla stabilis benevolentiae potest esse fiducia, omnia semper suspecta atque sollicita, nullus locu [...]
 					</div>
-					<div dojoType="dijit.layout.ContentPane" class="cpane" label="Content Pane" dndType="ContentPane">Content Pane n°2 !</div>
-			  		<div dojoType="dijit.layout.ContentPane" title="Intellectum" dndType="ContentPane">
+					<div data-dojo-type="dijit/layout/ContentPane" class="cpane" label="Content Pane" dndType="ContentPane">Content Pane n°2 !</div>
+			  		<div data-dojo-type="dijit/layout/ContentPane" title="Intellectum" dndType="ContentPane">
 			  			Intellectum est enim mihi quidem in multis, et maxime in me ipso, sed paulo ante in omnibus, cum M. Marcellum senatui reique publicae concessisti, commemoratis praesertim offensionibus, te auctoritatem huius ordinis dignitatemque rei publicae tuis vel doloribus vel suspicionibus anteferre. Ille quidem fructum omnis ante actae vitae hodierno die maximum cepit, cum summo consensu senatus, tum iudicio tuo gravissimo et maximo. Ex quo profecto intellegis quanta in dato beneficio sit  [...]
 			  		</div>
 			  		
-					<div dojoType="dijit.layout.ContentPane" class="cpane" label="Content Pane" dndType="ContentPane">Content Pane n°3 !</div>
-					<div dojoType="dijit.layout.ContentPane" class="cpane" label="Content Pane" dndType="ContentPane">Content Pane n°4 !</div>
-					<div dojoType="dijit.Calendar" dndType="Calendar"></div>
+					<div data-dojo-type="dijit/layout/ContentPane" class="cpane" label="Content Pane" dndType="ContentPane">Content Pane n°3 !</div>
+					<div data-dojo-type="dijit/layout/ContentPane" class="cpane" label="Content Pane" dndType="ContentPane">Content Pane n°4 !</div>
+					<div data-dojo-type="dijit/Calendar" dndType="Calendar"></div>
 			</div>
-		
+			<div id="foo"></div>
+    		<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true, async: 1"></script>
+    		<script src="../../../dijit/tests/_testCommon.js"></script>
+
+    		<script>
+    		    require(["dojo/parser", "dojo/topic", "dojo/dom-class", "dojo/dom-construct", "dojo/_base/lang", "dijit/registry", "dojox/layout/GridContainerLite","dijit/TitlePane", "dijit/layout/ContentPane", "dijit/Calendar", "dojo/domReady!"],
+    		    function(parser, topic, domClass, domConstruct, lang, registry, GridContainerLite){
+        			var fooWidget = new GridContainerLite({}, "foo");
+        			var canDisplayPopup = true;
+
+        			function displayPopup(gridContainer) {
+        				//	summary:
+        				//		Display a popup when a widget can not be moved (not accepted type)
+
+        				if(canDisplayPopup){
+        					canDisplayPopup = false;
+        					var popup = document.createElement("div");
+        					domClass(popup, "gridContainerPopup");
+        					popup.innerHTML = "Impossible to move this widget ! ";
+        					var attachPopup = registry.byId("GC1").containerNode.appendChild(popup);
+        					setTimeout(lang.hitch(this, function(){
+        						registry.byId("GC1").containerNode.removeChild(attachPopup);
+        						domConstruct.destroy(attachPopup);
+        						canDisplayPopup = true;
+        					}), 1500);
+        				}
+        			};
+        			topic.subscribe("/dojox/layout/gridContainer/moveRestriction",displayPopup);
+    		    });
+    		</script>
 	</body>
 </html>
diff --git a/dojox/layout/tests/test_GridContainerLite_doLayout.html b/dojox/layout/tests/test_GridContainerLite_doLayout.html
index d6c45a2..30986e4 100644
--- a/dojox/layout/tests/test_GridContainerLite_doLayout.html
+++ b/dojox/layout/tests/test_GridContainerLite_doLayout.html
@@ -34,7 +34,7 @@
 	
 	<link rel="stylesheet" href="../resources/GridContainer.css">
 	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<script type="text/javascript" language="javascript">
 		dojo.require("dojox.layout.GridContainerLite");
diff --git a/dojox/layout/tests/test_GridContainerLite_dragRestriction.html b/dojox/layout/tests/test_GridContainerLite_dragRestriction.html
index ba637df..42d8cf3 100644
--- a/dojox/layout/tests/test_GridContainerLite_dragRestriction.html
+++ b/dojox/layout/tests/test_GridContainerLite_dragRestriction.html
@@ -34,7 +34,7 @@
 	
 	<link rel="stylesheet" href="../resources/GridContainer.css">
 	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<script type="text/javascript" language="javascript">
 		dojo.require("dojox.layout.GridContainerLite");
diff --git a/dojox/layout/tests/test_GridContainer_ResizableCol.html b/dojox/layout/tests/test_GridContainer_ResizableCol.html
index ebbc0c5..15690ef 100644
--- a/dojox/layout/tests/test_GridContainer_ResizableCol.html
+++ b/dojox/layout/tests/test_GridContainer_ResizableCol.html
@@ -37,7 +37,7 @@
 		
 		<link rel="stylesheet" href="../resources/GridContainer.css">
 		
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 		
 		<script type="text/javascript">
diff --git a/dojox/layout/tests/test_GridContainer_TitlePanes.html b/dojox/layout/tests/test_GridContainer_TitlePanes.html
index a4698af..7087c33 100644
--- a/dojox/layout/tests/test_GridContainer_TitlePanes.html
+++ b/dojox/layout/tests/test_GridContainer_TitlePanes.html
@@ -49,7 +49,7 @@
 		<link rel="stylesheet" href="../resources/GridContainer.css">
 		<link rel="stylesheet" href="../resources/DndGridContainer.css">
 		
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
diff --git a/dojox/layout/tests/test_GridContainer_complete_solution.html b/dojox/layout/tests/test_GridContainer_complete_solution.html
index a28b6f8..b7bbb8d 100644
--- a/dojox/layout/tests/test_GridContainer_complete_solution.html
+++ b/dojox/layout/tests/test_GridContainer_complete_solution.html
@@ -16,7 +16,7 @@
 	<link rel="stylesheet" href="../resources/GridContainer.css" type="text/css" />
 	<link rel="stylesheet" href="../../../dijit/tests/css/dijitTests.css" type="text/css"/>
 	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true,  parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true,  parseOnLoad: true"></script>
 	
 	<script type="text/javascript">
 		dojo.require("dojox.layout.GridContainerLite");
@@ -35,7 +35,7 @@
 <body class="tundra">
 	<div style="position:absolute;width:200px;left:5px;top:50px;">
 		<H2>Pure Source Dojo</H2>
-		<div dojoType="dojox.mdnd.PureSource" jsId="c1" class="container" >
+		<div dojoType="dojox.mdnd.PureSource" data-dojo-id="c1" class="container" >
 			<div class="dojoDndItem" dndType="ContentPane"><strong>ContentPane</strong></div>
 			<div class="dojoDndItem" dndType="Portlet"><strong>Portlet</strong></div>
 			<div class="dojoDndItem" dndType="TitlePane"><strong>TitlePane</strong></div>
@@ -43,7 +43,7 @@
 	</div>
 	<div style="position:absolute;width:200px;left:5px;top:220px;">
 		<H2>Source/Target Dojo</H2>
-		<div dojoType="dojo.dnd.Source" accept="rss, TitlePane, News" jsId="c2" class="container">
+		<div dojoType="dojo.dnd.Source" accept="rss, TitlePane, News" data-dojo-id="c2" class="container">
 			<div class="dojoDndItem" dndType="rss">RSS <strong>1</strong></div>
 			<div class="dojoDndItem" dndType="TitlePane"><strong>TitlePane</strong></div>
 			<div class="dojoDndItem" dndType="ContentPane"><strong>ContentPane</strong></div>
@@ -70,7 +70,7 @@
 				style="height:150px;"
 				dndType="Portlet" >
 				<b>Source/Target OAF (drop only rss)</b><br>
-				<div dojoType="dojo.dnd.Source" jsId="cp1" accept="rss">
+				<div dojoType="dojo.dnd.Source" data-dojo-id="cp1" accept="rss">
 					<div class="dojoDndItem" dndType="News">News <strong>1</strong></div>
 					<div class="dojoDndItem" dndType="News">News <strong>2</strong></div>
 					<div class="dojoDndItem" dndType="News">News <strong>3</strong></div>
diff --git a/dojox/layout/tests/test_GridContainer_dragHandle.html b/dojox/layout/tests/test_GridContainer_dragHandle.html
index c67605f..6a2e121 100644
--- a/dojox/layout/tests/test_GridContainer_dragHandle.html
+++ b/dojox/layout/tests/test_GridContainer_dragHandle.html
@@ -40,7 +40,7 @@
 			
 		</style>
 		
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
@@ -81,7 +81,7 @@
 				<div dojoType="dojox.widget.Portlet" title="Portlet with Dialog Settings" id="portlet2">
 				<div dojoType="dojox.widget.PortletDialogSettings" title="Settings in a Dialog">
 					Use Bold Text: <div dojoType="dijit.form.CheckBox">
-						<script type="dojo/connect" event="onClick">
+						<script type="dojo/connect" data-dojo-event="onClick">
 						  dojo.style(dijit.byId('portlet2').containerNode, "fontWeight", this.checked ? "bold" : "normal");
 						</script>
 					</div>
diff --git a/dojox/layout/tests/test_GridContainer_in_BorderContainer.html b/dojox/layout/tests/test_GridContainer_in_BorderContainer.html
index 36b7c84..d0ec817 100644
--- a/dojox/layout/tests/test_GridContainer_in_BorderContainer.html
+++ b/dojox/layout/tests/test_GridContainer_in_BorderContainer.html
@@ -52,7 +52,7 @@
 		<link rel="stylesheet" href="../resources/GridContainer.css">
 		<link rel="stylesheet" href="../resources/ExpandoPane.css">
 		
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
diff --git a/dojox/layout/tests/test_GridContainer_in_BorderContainer_prog.html b/dojox/layout/tests/test_GridContainer_in_BorderContainer_prog.html
index 46c5f58..85f0b2e 100644
--- a/dojox/layout/tests/test_GridContainer_in_BorderContainer_prog.html
+++ b/dojox/layout/tests/test_GridContainer_in_BorderContainer_prog.html
@@ -51,7 +51,7 @@
 		<link rel="stylesheet" href="../resources/GridContainer.css">
 		<link rel="stylesheet" href="../resources/ExpandoPane.css">
 		
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
diff --git a/dojox/layout/tests/test_RadioGroup.html b/dojox/layout/tests/test_RadioGroup.html
index df0d2e0..8bea682 100644
--- a/dojox/layout/tests/test_RadioGroup.html
+++ b/dojox/layout/tests/test_RadioGroup.html
@@ -9,14 +9,11 @@
 	<link rel="stylesheet" href="../resources/RadioGroup.css">	
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
-	<!-- for debugging: -->
-	<script type="text/javascript" src="../RadioGroup.js"></script>
-
 	<script language="JavaScript" type="text/javascript">
 		dojo.require("dojox.layout.RadioGroup");
 		dojo.require("dojo.parser"); 
@@ -79,7 +76,7 @@
 
 	<div>
 		<button dojoType="dijit.form.Button">add children
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				dojo.forEach(["firstGroup","firstFade","firstSlide"], function(id){
 					var w = dijit.byId(id);
 					w.addChild(
@@ -93,7 +90,7 @@
 		</button>
 		
 		<button dojoType="dijit.form.Button">remove one from each
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				dijit.registry.filter(function(w){
 					return w.declaredClass.match(/dojox\.layout\.RadioGroup/);
 				}).forEach(function(w){
diff --git a/dojox/layout/tests/test_ResizeHandle.html b/dojox/layout/tests/test_ResizeHandle.html
index feb228e..44e37f2 100644
--- a/dojox/layout/tests/test_ResizeHandle.html
+++ b/dojox/layout/tests/test_ResizeHandle.html
@@ -98,7 +98,7 @@
 		
 		<button dojoType='dijit.form.Button'>
 			kill handle
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				dijit.byId("hand1").destroy();
 			</script>
 		</button>
@@ -113,7 +113,7 @@
 	>
 		<button dojoType='dijit.form.Button'>
 			kill handle
-			<script type="dojo/method" event="onClick">
+			<script type="dojo/method" data-dojo-event="onClick">
 				dijit.byId("hand2").destroy();
 			</script>
 		</button>
diff --git a/dojox/layout/tests/test_RotatorContainer.html b/dojox/layout/tests/test_RotatorContainer.html
index 39dadc3..d14be0f 100644
--- a/dojox/layout/tests/test_RotatorContainer.html
+++ b/dojox/layout/tests/test_RotatorContainer.html
@@ -23,7 +23,7 @@
 	}
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:true, isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, isDebug:true"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
 		dojo.require("dijit.form.Button");
diff --git a/dojox/layout/tests/test_ScrollPane.html b/dojox/layout/tests/test_ScrollPane.html
index 964258a..49058af 100644
--- a/dojox/layout/tests/test_ScrollPane.html
+++ b/dojox/layout/tests/test_ScrollPane.html
@@ -9,7 +9,7 @@
 	<link rel="stylesheet" href="../resources/ScrollPane.css">	
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/layout/tests/test_ScrollPaneSingle.html b/dojox/layout/tests/test_ScrollPaneSingle.html
index 83ba23f..943a020 100644
--- a/dojox/layout/tests/test_ScrollPaneSingle.html
+++ b/dojox/layout/tests/test_ScrollPaneSingle.html
@@ -10,7 +10,7 @@
 
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: false"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: false"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/layout/tests/test_TableContainer.html b/dojox/layout/tests/test_TableContainer.html
index 7f6d6d4..bf2962a 100644
--- a/dojox/layout/tests/test_TableContainer.html
+++ b/dojox/layout/tests/test_TableContainer.html
@@ -9,7 +9,7 @@
 	<link rel="stylesheet" href="../resources/ScrollPane.css">	
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -271,7 +271,7 @@
 	<div id="colspanTest">
 		<h2>This table tests the use of the 'colspan' attribute with labels enabled</h2>
 		<div dojoType="dojox.layout.TableContainer" cols="3" customClass="greyBlueLNF" labelWidth="-1">
-			<script type="dojo/connect" event="startup">
+			<script type="dojo/connect" data-dojo-event="startup">
 				// Show the actual colspan in each cell
 				dojo.query(".greyBlueLNF-valueCell", this.domNode).forEach(function(cell){
 				  cell.firstChild.innerHTML += " - <i>actual colspan = " + dojo.attr(cell, "colspan") + "</i>";
@@ -291,7 +291,7 @@
 		
 		<h2>This table tests the use of the 'colspan' attribute with labels disabled</h2>
 		<div dojoType="dojox.layout.TableContainer" cols="3" customClass="greyBlueLNF" labelWidth="-1" showLabels="false">
-			<script type="dojo/connect" event="startup">
+			<script type="dojo/connect" data-dojo-event="startup">
 				// Show the actual colspan in each cell
 				dojo.query(".greyBlueLNF-valueCell", this.domNode).forEach(function(cell){
 				  cell.firstChild.innerHTML += " - <i>actual colspan = " + dojo.attr(cell, "colspan") + "</i>";
@@ -322,25 +322,25 @@
 	<div dojoType="dijit.layout.BorderContainer" style="height:100px; border: solid #ccc 1px;">
 		<div dojoType="dijit.layout.ContentPane" region="left" style="width:20%" splitter="true">(left)</div>
 		<div dojoType="dijit.layout.ContentPane" region="center">
-			<div dojoType="dojox.layout.TableContainer" region="center" jsId="tblContainerResize" cols="3" customClass="greyBlueLNF" labelWidth="-1">
+			<div dojoType="dojox.layout.TableContainer" region="center" data-dojo-id="tblContainerResize" cols="3" customClass="greyBlueLNF" labelWidth="-1">
 				<div dojoType="dijit.layout.ContentPane" label="Col 1 Label">
-					<script type="dojo/connect" event="resize">
+					<script type="dojo/connect" data-dojo-event="resize">
 						this.domNode.innerHTML = "<strong>Width: " + dojo.contentBox(this.domNode).w + "</strong>";
 					</script>
 				</div>
 				<div dojoType="dijit.layout.ContentPane" label="Col 2 Label">
-					<script type="dojo/connect" event="resize">
+					<script type="dojo/connect" data-dojo-event="resize">
 						this.domNode.innerHTML = "<strong>Width: " + dojo.contentBox(this.domNode).w + "</strong>";
 					</script>
 				</div>
 				<div dojoType="dijit.layout.BorderContainer" label="Col 1 Label" colspan="2" style="height: 50px">
 					<div dojoType="dijit.layout.ContentPane" region="left" style="width: 50%">
-						<script type="dojo/connect" event="resize">
+						<script type="dojo/connect" data-dojo-event="resize">
 							this.domNode.innerHTML = "<strong>Nested BC region width: " + dojo.contentBox(this.domNode).w + "</strong>";
 						</script>
 					</div>
 					<div dojoType="dijit.layout.ContentPane" region="center" style="width: 50%">
-						<script type="dojo/connect" event="resize">
+						<script type="dojo/connect" data-dojo-event="resize">
 							this.domNode.innerHTML = "<strong>Nested BC region width: " + dojo.contentBox(this.domNode).w + "</strong>";
 							console.log(this.id + " resize");
 						</script>
diff --git a/dojox/layout/tests/test_ToggleSplitter.html b/dojox/layout/tests/test_ToggleSplitter.html
index 829f5f6..3e1b1e9 100644
--- a/dojox/layout/tests/test_ToggleSplitter.html
+++ b/dojox/layout/tests/test_ToggleSplitter.html
@@ -7,7 +7,7 @@
 	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/claro/claro.css">
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/layout/tests/test_TouchStackContainer.html b/dojox/layout/tests/test_TouchStackContainer.html
index 5240fae..d3880c5 100644
--- a/dojox/layout/tests/test_TouchStackContainer.html
+++ b/dojox/layout/tests/test_TouchStackContainer.html
@@ -21,7 +21,7 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: do NOT use in your code! -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/main.js b/dojox/main.js
index 6095f00..5abb84c 100644
--- a/dojox/main.js
+++ b/dojox/main.js
@@ -1,8 +1,14 @@
 define(["dojo/_base/kernel"], function(dojo) {
 	// module:
 	//		dojox/main
-	// summary:
-	//		The dojox package main module; dojox package is somewhat unusual in that the main module currently just provides an empty object.
+
+	/*=====
+	return {
+		// summary:
+		//		The dojox package main module; dojox package is somewhat unusual in that the main module currently just provides an empty object.
+		//		Apps should require modules from the dojox packages directly, rather than loading this module.
+	};
+	=====*/
 
 	return dojo.dojox;
 });
\ No newline at end of file
diff --git a/dojox/math.js b/dojox/math.js
index 1672c8b..0d01a5e 100644
--- a/dojox/math.js
+++ b/dojox/math.js
@@ -1,6 +1,14 @@
 // AMD-ID "dojox/math"
 define(["dojo", "dojox", "dojox/math/_base"], function(dojo, dojox, math) {
-dojo.getObject("math", true, dojox);
+	dojo.getObject("math", true, dojox);
 
-return dojox.math;
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/math modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
+
+	return dojox.math;
 });
diff --git a/dojox/math/BigInteger.js b/dojox/math/BigInteger.js
index 545fd8b..2eeed07 100644
--- a/dojox/math/BigInteger.js
+++ b/dojox/math/BigInteger.js
@@ -133,7 +133,7 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 	  else if(b == 2) k = 1;
 	  else if(b == 32) k = 5;
 	  else if(b == 4) k = 2;
-	  else { this.fromRadix(s,b); return; }
+	  else { this._fromRadix(s,b); return; }
 	  this.t = 0;
 	  this.s = 0;
 	  var i = s.length, mi = false, sh = 0;
@@ -425,9 +425,9 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 
 	// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
 	// justification:
-	//         xy == 1 (mod m)
-	//         xy =  1+km
-	//   xy(2-xy) = (1+km)(1-km)
+	// xy == 1 (mod m)
+	// xy =  1+km
+	// xy(2-xy) = (1+km)(1-km)
 	// x[y(2-xy)] = 1-k^2m^2
 	// x[y(2-xy)] == 1 (mod m^2)
 	// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
diff --git a/dojox/math/_base.js b/dojox/math/_base.js
index bdc9222..e77d119 100644
--- a/dojox/math/_base.js
+++ b/dojox/math/_base.js
@@ -5,30 +5,30 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 	var m = dojox.math;
 	dojo.mixin(dojox.math, {
 		toRadians: function(/* Number */n){
-			//	summary:
+			// summary:
 			//		Convert the passed number to radians.
 			return (n*Math.PI)/180;	// Number
 		},
 		toDegrees: function(/* Number */n){
-			//	summary:
+			// summary:
 			//		Convert the passed number to degrees.
-			return (n*180)/Math.PI;	//	Number
+			return (n*180)/Math.PI;	// Number
 		},
 		degreesToRadians: function(/* Number */n){
-			//	summary:
+			// summary:
 			//		Deprecated.  Use dojox.math.toRadians.
 			return m.toRadians(n);	// Number
 		},
 		radiansToDegrees: function(/* Number */n){
-			//	summary:
+			// summary:
 			//		Deprecated.  Use dojox.math.toDegrees.
-			return m.toDegrees(n);	//	Number
+			return m.toDegrees(n);	// Number
 		},
 
 		_gamma: function(z){
-			//	summary:
+			// summary:
 			//		Compute the gamma function for the passed number.
-			//		Approximately 14 dijits of precision with non-integers.
+			//		Approximately 14 digits of precision with non-integers.
 			var answer = 1; // 0!
 			// gamma(n+1) = n * gamma(n)
 			while (--z >= 1){
@@ -47,8 +47,8 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 			// c[0] = sqrt(2*PI) / exp(a)
 			// var kfact = 1
 			// for (var k=1; k < a; k++){
-			//      c[k] = pow(-k + a, k - 0.5) * exp(-k) / kfact
-			//      kfact *= -k  // (-1)^(k-1) * (k-1)!
+			//		c[k] = pow(-k + a, k - 0.5) * exp(-k) / kfact
+			//		kfact *= -k  // (-1)^(k-1) * (k-1)!
 			// }
 			var c = [ // precomputed from the above algorithm
 					 5.6658056015186327e-6,
@@ -73,14 +73,14 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 		},
 
 		factorial: function(/* Number */n){
-			//	summary:
+			// summary:
 			//		Return the factorial of n
 			return this._gamma(n+1);	// Number
 		},
 
 		permutations: function(/* Number */n, /* Number */k){
-			//	summary:
-			//	TODO
+			// summary:
+			//		TODO
 			if(n==0 || k==0){
 				return 1; 	// Number
 			}
@@ -88,22 +88,22 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 		},
 
 		combinations: function(/* Number */n, /* Number */r){
-			//	summary:
-			//	TODO
+			// summary:
+			//		TODO
 			if(n==0 || r==0){
-				return 1; 	//	Number
+				return 1; 	// Number
 			}
 			return this.factorial(n) / (this.factorial(n-r) * this.factorial(r));	// Number
 		},
 
 		bernstein: function(/* Number */t, /* Number */n, /* Number */ i){
-			//	summary:
-			//	TODO
-			return this.combinations(n, i) * Math.pow(t, i) * Math.pow(1-t, n-i);	//	Number
+			// summary:
+			//		TODO
+			return this.combinations(n, i) * Math.pow(t, i) * Math.pow(1-t, n-i);	// Number
 		},
 
 		gaussian: function(){
-			//	summary:
+			// summary:
 			//		Return a random number based on the Gaussian algo.
 			var k=2;
 			do{
@@ -111,12 +111,12 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 				var j=2*Math.random()-1;
 				k = i*i+j*j;
 			}while(k>=1);
-			return i * Math.sqrt((-2*Math.log(k))/k);	//	Number
+			return i * Math.sqrt((-2*Math.log(k))/k);	// Number
 		},
 
-		//	create a range of numbers
+		// create a range of numbers
 		range: function(/* Number */a, /* Number? */b, /* Number? */step){
-			//	summary:
+			// summary:
 			//		Create a range of numbers based on the parameters.
 			if(arguments.length<2){
 				b=a,a=0;
@@ -139,13 +139,13 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 		},
 
 		distance: function(/* Array */a, /* Array */b){
-			//	summary:
+			// summary:
 			//		Calculate the distance between point A and point B
-			return Math.sqrt(Math.pow(b[0]-a[0],2)+Math.pow(b[1]-a[1],2));	//	Number
+			return Math.sqrt(Math.pow(b[0]-a[0],2)+Math.pow(b[1]-a[1],2));	// Number
 		},
 
 		midpoint: function(/* Array */a, /* Array */b){
-			//	summary:
+			// summary:
 			//		Calculate the midpoint between points A and B.  A and B may be multidimensional.
 			if(a.length!=b.length){
 				console.error("dojox.math.midpoint: Points A and B are not the same dimensionally.", a, b);
@@ -154,7 +154,7 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 			for(var i=0; i<a.length; i++){
 				m[i]=(a[i]+b[i])/2;
 			}
-			return m;	//	Array
+			return m;	// Array
 		}
 	});
 
diff --git a/dojox/math/matrix.js b/dojox/math/matrix.js
index f4beed1..0b0663a 100644
--- a/dojox/math/matrix.js
+++ b/dojox/math/matrix.js
@@ -6,8 +6,8 @@ dojo.mixin(dojox.math.matrix, {
 	iDF:0,
 	ALMOST_ZERO: 1e-10,
 	multiply: function(/* Array */a, /* Array */b){
-		//	summary
-		//	Multiply matrix a by matrix b.
+		// summary:
+		//		Multiply matrix a by matrix b.
 		var ay=a.length, ax=a[0].length, by=b.length, bx=b[0].length;
 		if(ax!=by){
 			console.warn("Can't multiply matricies of sizes " + ax + "," + ay + " and " + bx + "," + by);
@@ -23,11 +23,11 @@ dojo.mixin(dojox.math.matrix, {
 				}
 			}
 		}
-		return c;	//	Array
+		return c;	// Array
 	},
 	product: function(/* Array... */){
-		//	summary
-		//	Return the product of N matrices
+		// summary:
+		//		Return the product of N matrices
 		if (arguments.length==0){
 			console.warn("can't multiply 0 matrices!");
 			return 1;
@@ -36,14 +36,14 @@ dojo.mixin(dojox.math.matrix, {
 		for(var i=1; i<arguments.length; i++){
 			m=this.multiply(m, arguments[i]);
 		}
-		return m;	//	Array
+		return m;	// Array
 	},
 	sum: function(/* Array... */){
-		//	summary
-		//	Return the sum of N matrices
+		// summary:
+		//		Return the sum of N matrices
 		if(arguments.length==0){
 			console.warn("can't sum 0 matrices!");
-			return 0;	//	Number
+			return 0;	// Number
 		}
 		var m=this.copy(arguments[0]);
 		var rows=m.length;
@@ -68,13 +68,13 @@ dojo.mixin(dojox.math.matrix, {
 				}
 			}
 		}
-		return m;	//	Array
+		return m;	// Array
 	},
 	inverse: function(/* Array */a){
-		//	summary
-		//	Return the inversion of the passed matrix
+		// summary:
+		//		Return the inversion of the passed matrix
 		if(a.length==1 && a[0].length==1){
-			return [[1/a[0][0]]];	//	Array
+			return [[1/a[0][0]]];	// Array
 		}
 		var tms=a.length, m=this.create(tms, tms), mm=this.adjoint(a), det=this.determinant(a), dd=0;
 		if(det==0){
@@ -88,11 +88,11 @@ dojo.mixin(dojox.math.matrix, {
 				m[i][j]=dd*mm[i][j];
 			}
 		}
-		return m;	//	Array
+		return m;	// Array
 	},
 	determinant: function(/* Array */a){
-		//	summary
-		//	Calculate the determinant of the passed square matrix.
+		// summary:
+		//		Calculate the determinant of the passed square matrix.
 		if(a.length!=a[0].length){
 			console.warn("Can't calculate the determinant of a non-squre matrix!");
 			return 0;
@@ -101,16 +101,16 @@ dojo.mixin(dojox.math.matrix, {
 		for (var i=0; i<tms; i++){
 			var bii=b[i][i];
 			if (Math.abs(bii)<this.ALMOST_ZERO) {
-				return 0;	//	Number
+				return 0;	// Number
 			}
 			det*=bii;
 		}
 		det*=this.iDF;
-		return det;	//	Number
+		return det;	// Number
 	},
 	upperTriangle: function(/* Array */m){
-		//	Summary
-		//	Find the upper triangle of the passed matrix and return it.
+		// summary:
+		//		Find the upper triangle of the passed matrix and return it.
 		m=this.copy(m);
 		var f1=0, temp=0, tms=m.length, v=1;
 		this.iDF=1;
@@ -149,11 +149,11 @@ dojo.mixin(dojox.math.matrix, {
 				}
 			}
 		}
-		return m;	//	Array
+		return m;	// Array
 	},
 	create: function(/* Number */a, /* Number */b, /* Number? */value){
-		//	summary
-		//	Create a new matrix with rows a and cols b, and pre-populate with value.
+		// summary:
+		//		Create a new matrix with rows a and cols b, and pre-populate with value.
 		value=value||0;
 		var m=[];
 		for (var i=0; i<b; i++){
@@ -162,21 +162,21 @@ dojo.mixin(dojox.math.matrix, {
 				m[i][j]=value;
 			}
 		}
-		return m;	//	Array
+		return m;	// Array
 	},
 	ones: function(/* Number */a, /* Number */b){
-		//	summary
-		//	Create a matrix pre-populated with ones
-		return this.create(a, b, 1);	//	Array
+		// summary:
+		//		Create a matrix pre-populated with ones
+		return this.create(a, b, 1);	// Array
 	},
 	zeros: function(/* Number */a, /* Number */b){
-		//	summary
-		//	Create a matrix pre-populated with zeros
+		// summary:
+		//		Create a matrix pre-populated with zeros
 		return this.create(a, b);	// Array
 	},
 	identity: function(/* Number */size, /* Number? */scale){
-		//	summary
-		//	Create an identity matrix based on the size and scale.
+		// summary:
+		//		Create an identity matrix based on the size and scale.
 		scale=scale||1;
 		var m=[];
 		for(var i=0; i<size; i++){
@@ -185,11 +185,11 @@ dojo.mixin(dojox.math.matrix, {
 				m[i][j]=(i==j?scale:0);
 			}
 		}
-		return m;	//	Array
+		return m;	// Array
 	},
 	adjoint: function(/* Array */a){
-		//	summary
-		//	Find the adjoint of the passed matrix
+		// summary:
+		//		Find the adjoint of the passed matrix
 		var tms=a.length;
 		if(tms<=1){
 			console.warn("Can't find the adjoint of a matrix with a dimension less than 2");
@@ -222,22 +222,22 @@ dojo.mixin(dojox.math.matrix, {
 				m[i][j]=Math.pow(-1, (i+j))*det;
 			}
 		}
-		return this.transpose(m);	//	Array
+		return this.transpose(m);	// Array
 	},
 	transpose: function(/* Array */a){
-		//	summary
-		//	Transpose the passed matrix (i.e. rows to columns)
+		// summary:
+		//		Transpose the passed matrix (i.e. rows to columns)
 		var m=this.create(a.length, a[0].length);
 		for(var i=0; i<a.length; i++){
 			for(var j=0; j<a[i].length; j++){
 				m[j][i]=a[i][j];
 			}
 		}
-		return m;	//	Array
+		return m;	// Array
 	},
 	format: function(/* Array */a, /* Number? */points){
-		//	summary
-		//	Return a string representation of the matrix, rounded to points (if needed)
+		// summary:
+		//		Return a string representation of the matrix, rounded to points (if needed)
 		points=points||5;
 		function format_int(x, dp){
 			var fac=Math.pow(10, dp);
@@ -264,11 +264,11 @@ dojo.mixin(dojox.math.matrix, {
 			}
 			buffer+="|\n";
 		}
-		return buffer;	//	string
+		return buffer;	// string
 	},
 	copy: function(/* Array */a){
-		//	summary
-		//	Create a copy of the passed matrix
+		// summary:
+		//		Create a copy of the passed matrix
 		var ya=a.length, xa=a[0].length, m=this.create(xa, ya);
 		for(var y=0; y<ya; y++){
 			for(var x=0; x<xa; x++){
@@ -278,8 +278,8 @@ dojo.mixin(dojox.math.matrix, {
 		return m;	// Array
 	},
 	scale: function(/* Array */a, /* Number */factor){
-		//	summary
-		//	Create a copy of passed matrix and scale each member by factor.
+		// summary:
+		//		Create a copy of passed matrix and scale each member by factor.
 		a=this.copy(a);
 		var ya=a.length, xa=a[0].length;
 		for(var y=0; y<ya; y++){
diff --git a/dojox/math/random/Secure.js b/dojox/math/random/Secure.js
index 39b5fce..9581cf2 100644
--- a/dojox/math/random/Secure.js
+++ b/dojox/math/random/Secure.js
@@ -9,19 +9,19 @@ define(["dojo"], function(dojo) {
 
 dojo.declare("dojox.math.random.Secure", null, {
 	// summary:
-	//	Super simple implementation of a random number generator,
-	//	which relies on Math.random().
+	//		Super simple implementation of a random number generator,
+	//		which relies on Math.random().
 
 	constructor: function(prng, noEvents){
 		// summary:
-		//	Intializes an instance of a secure random generator.
-		// prng: Function:
-		//	function that returns an instance of PRNG (pseudorandom number generator)
-		//  with two methods: init(array) and next(). It should have a property "size"
-		//	to indicate the required pool size.
-		// noEvents: Boolean?:
-		//	if false or absent, onclick and onkeypress event will be used to add
-		//	"randomness", otherwise events will not be used.
+		//		Initializes an instance of a secure random generator.
+		// prng: Function
+		//		function that returns an instance of PRNG (pseudo random number generator)
+		//		with two methods: init(array) and next(). It should have a property "size"
+		//		to indicate the required pool size.
+		// noEvents: Boolean?
+		//		if false or absent, onclick and onkeypress event will be used to add
+		//		"randomness", otherwise events will not be used.
 		this.prng = prng;
 
 		// Initialize the pool with junk if needed.
@@ -44,7 +44,7 @@ dojo.declare("dojox.math.random.Secure", null, {
 
 	destroy: function(){
 		// summary:
-		//	Disconnects events, if any, preparing the object for GC.
+		//		Disconnects events, if any, preparing the object for GC.
 		if(this.h){
 			dojo.forEach(this.h, dojo.disconnect);
 		}
@@ -52,10 +52,10 @@ dojo.declare("dojox.math.random.Secure", null, {
 
 	nextBytes: function(/* Array */ byteArray){
 		// summary:
-		//	Fills in an array of bytes with random numbers
-		// byteArray: Array:
-		//	array to be filled in with random numbers, only existing
-		//	elements will be filled.
+		//		Fills in an array of bytes with random numbers
+		// byteArray: Array
+		//		array to be filled in with random numbers, only existing
+		//		elements will be filled.
 
 		var state = this.state;
 
@@ -75,13 +75,13 @@ dojo.declare("dojox.math.random.Secure", null, {
 
 	seedTime: function() {
 		// summary:
-		//	Mix in the current time (w/milliseconds) into the pool
+		//		Mix in the current time (w/milliseconds) into the pool
 		this._seed_int(new Date().getTime());
 	},
 
 	_seed_int: function(x) {
 		// summary:
-		//	Mix in a 32-bit integer into the pool
+		//		Mix in a 32-bit integer into the pool
 		var p = this.pool, i = this.pptr;
 		p[i++] ^= x & 255;
 		p[i++] ^= (x >> 8) & 255;
diff --git a/dojox/math/random/Simple.js b/dojox/math/random/Simple.js
index c8324d2..71051ae 100644
--- a/dojox/math/random/Simple.js
+++ b/dojox/math/random/Simple.js
@@ -2,20 +2,20 @@ define(["dojo"], function(dojo) {
 
 	return dojo.declare("dojox.math.random.Simple", null, {
 		// summary:
-		//	Super simple implementation of a random number generator,
-		//	which relies on Math.random().
+		//		Super simple implementation of a random number generator,
+		//		which relies on Math.random().
 	
 		destroy: function(){
 			// summary:
-			//	Prepares the object for GC. (empty in this case)
+			//		Prepares the object for GC. (empty in this case)
 		},
 	
 		nextBytes: function(/* Array */ byteArray){
 			// summary:
-			//	Fills in an array of bytes with random numbers
-			// byteArray: Array:
-			//	array to be filled in with random numbers, only existing
-			//	elements will be filled.
+			//		Fills in an array of bytes with random numbers
+			// byteArray: Array
+			//		array to be filled in with random numbers, only existing
+			//		elements will be filled.
 			for(var i = 0, l = byteArray.length; i < l; ++i){
 				byteArray[i] = Math.floor(256 * Math.random());
 			}
diff --git a/dojox/math/random/prng4.js b/dojox/math/random/prng4.js
index ebb47c1..18ab49a 100644
--- a/dojox/math/random/prng4.js
+++ b/dojox/math/random/prng4.js
@@ -18,9 +18,9 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 	dojo.extend(Arcfour, {
 		init: function(key){
 			// summary:
-			//	Initialize arcfour context
-			// key: Array:
-			//	an array of ints, each from [0..255]
+			//		Initialize arcfour context
+			// key: int[]
+			//		an array of ints, each from [0..255]
 			var i, j, t, S = this.S, len = key.length;
 			for(i = 0; i < 256; ++i){
 				S[i] = i;
diff --git a/dojox/math/round.js b/dojox/math/round.js
index fced6ba..11accc8 100644
--- a/dojox/math/round.js
+++ b/dojox/math/round.js
@@ -5,9 +5,9 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 	dojo.experimental("dojox.math.round");
 
 	dojox.math.round = function(/*Number*/value, /*Number?*/places, /*Number?*/increment){
-		//	summary:
+		// summary:
 		//		Similar to dojo.number.round, but compensates for binary floating point artifacts
-		//	description:
+		// description:
 		//		Rounds to the nearest value with the given number of decimal places, away from zero if equal,
 		//		similar to Number.toFixed().  Rounding can be done by fractional increments also.
 		//		Makes minor adjustments to accommodate for precision errors due to binary floating point representation
@@ -16,32 +16,32 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 		//		floating point values.  The calculations assume 14 significant figures, so the accuracy will
 		//		be limited to a certain number of decimal places preserved will vary with the magnitude of
 		//		the input.  This is not a substitute for decimal arithmetic.
-		//	value:
+		// value:
 		//		The number to round
-		//	places:
+		// places:
 		//		The number of decimal places where rounding takes place.  Defaults to 0 for whole rounding.
 		//		Must be non-negative.
-		//	increment:
+		// increment:
 		//		Rounds next place to nearest value of increment/10.  10 by default.
-		//	example:
-		//		>>> 4.8-(1.1+2.2)
-		//		1.4999999999999996
-		//		>>> Math.round(4.8-(1.1+2.2))
-		//		1
-		//		>>> dojox.math.round(4.8-(1.1+2.2))
-		//		2
-		//		>>> ((4.8-(1.1+2.2))/100)
-		//		0.014999999999999996
-		//		>>> ((4.8-(1.1+2.2))/100).toFixed(2)
-		//		"0.01"
-		//		>>> dojox.math.round((4.8-(1.1+2.2))/100,2)
-		//		0.02
-		//		>>> dojox.math.round(10.71, 0, 2.5)
-		//		10.75
-		//		>>> dojo.number.round(162.295, 2)
-		//		162.29
-		//		>>> dojox.math.round(162.295, 2)
-		//		162.3
+		// example:
+		//	|	>>> 4.8-(1.1+2.2)
+		//	|	1.4999999999999996
+		//	|	>>> Math.round(4.8-(1.1+2.2))
+		//	|	1
+		//	|	>>> dojox.math.round(4.8-(1.1+2.2))
+		//	|	2
+		//	|	>>> ((4.8-(1.1+2.2))/100)
+		//	|	0.014999999999999996
+		//	|	>>> ((4.8-(1.1+2.2))/100).toFixed(2)
+		//	|	"0.01"
+		//	|	>>> dojox.math.round((4.8-(1.1+2.2))/100,2)
+		//	|	0.02
+		//	|	>>> dojox.math.round(10.71, 0, 2.5)
+		//	|	10.75
+		//	|	>>> dojo.number.round(162.295, 2)
+		//	|	162.29
+		//	|	>>> dojox.math.round(162.295, 2)
+		//	|	162.3
 		var wholeFigs = Math.log(Math.abs(value))/Math.log(10);
 		var factor = 10 / (increment || 10);
 		var delta = Math.pow(10, -15 + wholeFigs);
@@ -54,8 +54,13 @@ define(["dojo", "dojox"], function(dojo, dojox) {
 		var round = dojox.math.round;
 		dojox.math.round = function(v, p, m){
 			var d = Math.pow(10, -p || 0), a = Math.abs(v);
-			if(!v || a >= d || a * Math.pow(10, p + 1) < 5){
+			if(!v || a >= d){
 				d = 0;
+			}else{
+				a /= d;
+				if(a < 0.5 || a >= 0.95){
+					d = 0;
+				}
 			}
 			return round(v, p, m) + (v > 0 ? d : -d);
 		}
diff --git a/dojox/math/stats.js b/dojox/math/stats.js
index fec0313..de514b6 100644
--- a/dojox/math/stats.js
+++ b/dojox/math/stats.js
@@ -6,24 +6,24 @@ define(["dojo", "../main"], function(dojo, dojox) {
 	var st = dojox.math.stats;
 	dojo.mixin(st, {
 		sd: function(/* Number[] */a){
-			//	summary:
+			// summary:
 			//		Returns the standard deviation of the passed arguments.
-			return Math.sqrt(st.variance(a));	//	Number
+			return Math.sqrt(st.variance(a));	// Number
 		},
 
 		variance: function(/* Number[] */a){
-			//	summary:
+			// summary:
 			//		Find the variance in the passed array of numbers.
 			var mean=0, squares=0;
 			dojo.forEach(a, function(item){
 				mean+=item;
 				squares+=Math.pow(item,2);
 			});
-			return (squares/a.length)-Math.pow(mean/a.length, 2);	//	Number
+			return (squares/a.length)-Math.pow(mean/a.length, 2);	// Number
 		},
 
-		bestFit: function(/* Object[] || Number[] */a, /* String? */xProp, /* String? */yProp){
-			//	summary:
+		bestFit: function(/* Object[]|Number[] */ a, /* String? */ xProp, /* String? */ yProp){
+			// summary:
 			//		Calculate the slope and intercept in a linear fashion.  An array
 			//		of objects is expected; optionally you can pass in the property
 			//		names for "x" and "y", else x/y is used as the default.  If you
@@ -31,7 +31,7 @@ define(["dojo", "../main"], function(dojo, dojox) {
 			//		where x = the array index.
 			xProp = xProp || "x", yProp = yProp || "y";
 			if(a[0] !== undefined && typeof(a[0]) == "number"){
-				//	this is an array of numbers, so use the index as x.
+				// this is an array of numbers, so use the index as x.
 				a = dojo.map(a, function(item, idx){
 					return { x: idx, y: item };
 				});
@@ -46,15 +46,15 @@ define(["dojo", "../main"], function(dojo, dojox) {
 				sxy += a[i][xProp] * a[i][yProp];
 			}
 
-			//	we use the following because it's more efficient and accurate for determining the slope.
+			// we use the following because it's more efficient and accurate for determining the slope.
 			for(i=0; i<n; i++){
 				t = a[i][xProp] - sx/n;
 				stt += t*t;
 				sts += t*a[i][yProp];
 			}
-			var slope = sts/(stt||1);	//	prevent divide by zero.
+			var slope = sts/(stt||1);	// prevent divide by zero.
 
-			//	get Pearson's R
+			// get Pearson's R
 			var d = Math.sqrt((sxx - Math.pow(sx,2)/n) * (syy - Math.pow(sy,2)/n));
 			if(d === 0){
 				throw new Error("dojox.math.stats.bestFit: the denominator for Pearson's R is 0.");
@@ -66,8 +66,8 @@ define(["dojo", "../main"], function(dojo, dojox) {
 				r = -r;
 			}
 
-			//	to use:  y = slope*x + intercept;
-			return {	//	Object
+			// to use:  y = slope*x + intercept;
+			return {	// Object
 				slope: slope,
 				intercept: (sy - sx*slope)/(n||1),
 				r: r,
@@ -75,44 +75,44 @@ define(["dojo", "../main"], function(dojo, dojox) {
 			};
 		},
 
-		forecast: function(/* Object[] || Number[] */a, /* Number */x, /* String? */xProp, /* String? */yProp){
-			//	summary:
+		forecast: function(/* Object[]|Number[] */a, /* Number */x, /* String? */xProp, /* String? */yProp){
+			// summary:
 			//		Using the bestFit algorithm above, find y for the given x.
 			var fit = st.bestFit(a, xProp, yProp);
-			return (fit.slope * x) + fit.intercept;	//	Number
+			return (fit.slope * x) + fit.intercept;	// Number
 		},
 
 		mean: function(/* Number[] */a){
-			//	summary:
+			// summary:
 			//		Returns the mean value in the passed array.
 			var t=0;
 			dojo.forEach(a, function(v){
 				t += v;
 			});
-			return t / Math.max(a.length, 1);	//	Number
+			return t / Math.max(a.length, 1);	// Number
 		},
 
 		min: function(/* Number[] */a){
-			//	summary:
+			// summary:
 			//		Returns the min value in the passed array.
-			return Math.min.apply(null, a);		//	Number
+			return Math.min.apply(null, a);		// Number
 		},
 
 		max: function(/* Number[] */a){
-			//	summary:
+			// summary:
 			//		Returns the max value in the passed array.
-			return Math.max.apply(null, a);		//	Number
+			return Math.max.apply(null, a);		// Number
 		},
 
 		median: function(/* Number[] */a){
-			//	summary:
+			// summary:
 			//		Returns the value closest to the middle from a sorted version of the passed array.
 			var t = a.slice(0).sort(function(a, b){ return a - b; });
 			return (t[Math.floor(a.length/2)] + t[Math.ceil(a.length/2)])/2; // Number
 		},
 
 		mode: function(/* Number[] */a){
-			//	summary:
+			// summary:
 			//		Returns the mode from the passed array (number that appears the most often).
 			//		This is not the most efficient method, since it requires a double scan, but
 			//		is ensures accuracy.
@@ -121,17 +121,17 @@ define(["dojo", "../main"], function(dojo, dojox) {
 				(o[v]!==undefined)?o[v]++:o[v]=1;
 			});
 
-			//	we did the lookup map because we need the number that appears the most.
+			// we did the lookup map because we need the number that appears the most.
 			for(var p in o){
 				if(m < o[p]){
 					m = o[p], r = p;
 				}
 			}
-			return r;	//	Number
+			return r;	// Number
 		},
 
 		sum: function(/* Number[] */a){
-			//	summary:
+			// summary:
 			//		Return the sum of all the numbers in the passed array.  Does
 			//		not check to make sure values within a are NaN (should simply
 			//		return NaN).
@@ -139,19 +139,19 @@ define(["dojo", "../main"], function(dojo, dojox) {
 			dojo.forEach(a, function(n){
 				sum += n;
 			});
-			return sum;	//	Number
+			return sum;	// Number
 		},
 
 		approxLin: function(a, pos){
-			//	summary:
+			// summary:
 			//		Returns a linearly approximated value from an array using
 			//		a normalized float position value.
-			//	a: Number[]:
+			// a: Number[]
 			//		a sorted numeric array to be used for the approximation.
-			//	pos: Number:
+			// pos: Number
 			//		a position number from 0 to 1. If outside of this range it
 			//		will be clamped.
-			//	returns: Number
+			// returns: Number
 			var p = pos * (a.length - 1), t = Math.ceil(p), f = t - 1;
 			if(f < 0){ return a[0]; }
 			if(t >= a.length){ return a[a.length - 1]; }
@@ -159,17 +159,17 @@ define(["dojo", "../main"], function(dojo, dojox) {
 		},
 
 		summary: function(a, alreadySorted){
-			//	summary:
+			// summary:
 			//		Returns a non-parametric collection of summary statistics:
 			//		the classic five-number summary extended to the Bowley's
 			//		seven-figure summary.
-			//	a: Number[]:
+			// a: Number[]
 			//		a numeric array to be appraised.
-			//	alreadySorted: Boolean?:
+			// alreadySorted: Boolean?
 			//		a Boolean flag to indicated that the array is already sorted.
 			//		This is an optional flag purely to improve the performance.
 			//		If skipped, the array will be assumed unsorted.
-			//	returns: Object
+			// returns: Object
 			if(!alreadySorted){
 				a = a.slice(0);								// copy the array
 				a.sort(function(a, b){ return a - b; });	// sort it properly
diff --git a/dojox/mdnd/AreaManager.js b/dojox/mdnd/AreaManager.js
index b6061f9..64c85ce 100644
--- a/dojox/mdnd/AreaManager.js
+++ b/dojox/mdnd/AreaManager.js
@@ -1,6 +1,20 @@
-define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_base/window",
-	"dojo/_base/array","dojo/query","dojo/_base/html","./Moveable"],function(dojo){
-	var am = dojo.declare(
+define(["dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dojo/_base/window",
+	"dojo/_base/array",
+	"dojo/_base/sniff",
+	"dojo/_base/lang",
+	"dojo/query",
+	"dojo/topic", // topic.publish()
+	"dojo/dom-class",
+	"dojo/dom-geometry",
+	"dojo/dom-construct",
+	"dijit/registry",
+	"dijit/_Widget",
+	"./Moveable"
+],function(dojo, declare, connect, win, array, sniff, lang, query, topic, domClass, geom, domConstruct, registry, _Widget, Moveable){
+	var am = declare(
 		"dojox.mdnd.AreaManager",
 		null,
 	{
@@ -27,10 +41,10 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 	
 			//console.log("dojox.mdnd.AreaManager ::: constructor");
 			this._areaList = [];
-			this.resizeHandler = dojo.connect(dojo.global,"onresize", this, function(){
+			this.resizeHandler = connect.connect(dojo.global,"onresize", this, function(){
 				this._dropMode.updateAreas(this._areaList);
 			});
-	
+			
 			this._oldIndexArea = this._currentIndexArea = this._oldDropIndex = this._currentDropIndex = this._sourceIndexArea = this._sourceDropIndex = -1;
 		},
 	
@@ -63,7 +77,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 					'accept': accept,
 					'initItems': false
 				};
-				dojo.forEach(this._getChildren(area), function(item){
+				array.forEach(this._getChildren(area), function(item){
 					this._setMarginArea(obj, item);
 					obj.items.push(this._addMoveableItem(item));
 				}, this);
@@ -71,7 +85,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 				if(!notInitAreas){
 					this._dropMode.updateAreas(this._areaList);
 				}
-				dojo.publish("/dojox/mdnd/manager/register",[area]);
+				connect.publish("/dojox/mdnd/manager/register",[area]);
 			}
 		},
 	
@@ -81,7 +95,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			//		insert Dnd Areas using the specific sort of dropMode.
 	
 			//console.log("dojox.mdnd.AreaManager ::: registerByClass");
-			dojo.query('.'+this.areaClass).forEach(function(area){
+			query('.'+this.areaClass).forEach(function(area){
 				this.registerByNode(area, true);
 			}, this);
 			this._dropMode.updateAreas(this._areaList);
@@ -98,7 +112,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			//console.log("dojox.mdnd.AreaManager ::: unregister");
 			var index = this._getIndexArea(area);
 			if(index != -1){
-				dojo.forEach(this._areaList[index].items, function(item){
+				array.forEach(this._areaList[index].items, function(item){
 					this._deleteMoveableItem(item);
 				}, this);
 				this._areaList.splice(index,1);
@@ -122,22 +136,22 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			//console.log("dojox.mdnd.AreaManager ::: _addMoveableItem");
 			node.setAttribute("tabIndex", "0");
 			var handle = this._searchDragHandle(node);
-			var moveable = new dojox.mdnd.Moveable({ 'handle': handle, 'skip': true }, node);
+			var moveable = new Moveable({ 'handle': handle, 'skip': true }, node);
 			// add a css style :
-			dojo.addClass(handle || node, "dragHandle");
+			domClass.add(handle || node, "dragHandle");
 			var type = node.getAttribute("dndType");
 			var item = {
 				'item': moveable,
 				'type': type ? type.split(/\s*,\s*/) : ["text"],
-				'handlers': [dojo.connect(moveable, "onDragStart", this, "onDragStart")]
+				'handlers': [connect.connect(moveable, "onDragStart", this, "onDragStart")]
 			}
 			// connect to the uninitialize method of dijit._Widget to delete a moveable before a destruct
-			if(dijit && dijit.byNode){
-				var widget = dijit.byNode(node);
+			if(registry && registry.byNode){
+				var widget = registry.byNode(node);
 				if(widget){
 					item.type = widget.dndType ? widget.dndType.split(/\s*,\s*/) : ["text"];
 					item.handlers.push(
-						dojo.connect(widget, "uninitialize", this, function(){
+						connect.connect(widget, "uninitialize", this, function(){
 							this.removeDragItem(node.parentNode, moveable.node);
 						})
 					);
@@ -156,13 +170,13 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 	
 			//console.log("dojox.mdnd.AreaManager ::: _deleteMoveableItem", objItem);
 			// disconnect the handle
-			dojo.forEach(objItem.handlers, function(handler){
-				dojo.disconnect(handler);
+			array.forEach(objItem.handlers, function(handler){
+				connect.disconnect(handler);
 			});
 			// delete css style :
 			var node = objItem.item.node,
 				handle = this._searchDragHandle(node);
-			dojo.removeClass(handle || node, "dragHandle");
+			domClass.remove(handle || node, "dragHandle");
 			// call destroy of Moveable class
 			objItem.item.destroy();
 		},
@@ -203,13 +217,13 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 				var cssArray = this.dragHandleClass.split(' '),
 					length = cssArray.length,
 					queryCss = "";
-				dojo.forEach(cssArray, function(css, i){
+				array.forEach(cssArray, function(css, i){
 					queryCss += "." + css;
 					if(i != length - 1){
 						queryCss += ", ";
 					}
 				});
-				return dojo.query(queryCss, node)[0]; // DomNode
+				return query(queryCss, node)[0]; // DomNode
 			}
 		},
 	
@@ -294,11 +308,11 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 	
 			//console.log("dojox.mdnd.AreaManager ::: _getChildren");
 			var children = [];
-			dojo.forEach(area.childNodes, function(child){
+			array.forEach(area.childNodes, function(child){
 				// delete \n
 				if(child.nodeType == 1){
-					if(dijit && dijit.byNode){
-						var widget = dijit.byNode(child);
+					if(registry && registry.byNode){
+						var widget = registry.byNode(child);
 						if(widget){
 							if(!widget.dragRestriction){
 								children.push(child);
@@ -329,7 +343,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 	
 			//console.log("dojox.mdnd.AreaManager ::: _setMarginArea");
 			if(area && area.margin === null && node){
-				area.margin = dojo._getMarginExtents(node);
+				area.margin = geom.getMarginExtents(node);
 			}
 		},
 	
@@ -394,20 +408,20 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			}
 	
 			// Create the cover :
-			var _html = (dojo.isWebKit) ? dojo.body() : dojo.body().parentNode;
+			var _html = (sniff("webkit")) ? dojo.body() : dojo.body().parentNode;
 			if(!this._cover){
-				this._cover = dojo.create('div', {
+				this._cover = domConstruct.create('div', {
 					'class': "dndCover"
 				});
-				this._cover2 = dojo.clone(this._cover);
-				dojo.addClass(this._cover2, "dndCover2");
+				this._cover2 = lang.clone(this._cover);
+				domClass.add(this._cover2, "dndCover2");
 			}
 			var h = _html.scrollHeight+"px";
 			this._cover.style.height = this._cover2.style.height = h;
 			dojo.body().appendChild(this._cover);
 			dojo.body().appendChild(this._cover2);
 	
-			this._dragStartHandler = dojo.connect(node.ownerDocument, "ondragstart", dojo, "stopEvent");
+			this._dragStartHandler = connect.connect(node.ownerDocument, "ondragstart", dojo, "stopEvent");
 			// to know the source
 			this._sourceIndexArea = this._lastValidIndexArea = this._currentIndexArea = this._getIndexArea(node.parentNode);
 			// delete the dragItem into the source area
@@ -416,8 +430,8 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			for(var i = 0; i < children.length; i++){
 				if(children[i].item.node == node){
 					this._dragItem = children[i];
-					this._dragItem.handlers.push(dojo.connect(this._dragItem.item, "onDrag", this, "onDrag"));
-					this._dragItem.handlers.push(dojo.connect(this._dragItem.item, "onDragEnd", this, "onDrop"));
+					this._dragItem.handlers.push(connect.connect(this._dragItem.item, "onDrag", this, "onDrag"));
+					this._dragItem.handlers.push(connect.connect(this._dragItem.item, "onDragEnd", this, "onDrop"));
 					children.splice(i,1);
 					this._currentDropIndex = this._sourceDropIndex = i;
 					break;
@@ -428,13 +442,13 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 				nodeRef = sourceArea.items[this._sourceDropIndex].item.node;
 			}
 			// IE7 OPTIMIZATION
-			if(dojo.isIE > 7){
+			if(sniff("ie")> 7){
 				// connect these events on the cover
 				this._eventsIE7 = [
-					dojo.connect(this._cover, "onmouseover", dojo, "stopEvent"),
-					dojo.connect(this._cover, "onmouseout", dojo, "stopEvent"),
-					dojo.connect(this._cover, "onmouseenter", dojo, "stopEvent"),
-					dojo.connect(this._cover, "onmouseleave", dojo, "stopEvent")
+					connect.connect(this._cover, "onmouseover", dojo, "stopEvent"),
+					connect.connect(this._cover, "onmouseout", dojo, "stopEvent"),
+					connect.connect(this._cover, "onmouseenter", dojo, "stopEvent"),
+					connect.connect(this._cover, "onmouseleave", dojo, "stopEvent")
 				];
 			}
 	
@@ -449,10 +463,10 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 	
 			this._dropIndicator.place(sourceArea.node, nodeRef, size);
 			// add a style to place the _dragNode in foreground
-			dojo.addClass(node, "dragNode");
+			domClass.add(node, "dragNode");
 			// A dragged node is always draggable in this source area.
 			this._accept = true;
-			dojo.publish("/dojox/mdnd/drag/start",[node, sourceArea, this._sourceDropIndex]);
+			connect.publish("/dojox/mdnd/drag/start",[node, sourceArea, this._sourceDropIndex]);
 		},
 	
 		onDragEnter: function(/*Object*/coords, /*Object*/size){
@@ -593,7 +607,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			//dropCancel
 			this.onDropCancel();
 			var targetArea = this._areaList[this._currentIndexArea];
-			dojo.removeClass(node, "dragNode");
+			domClass.remove(node, "dragNode");
 			var style = node.style;
 			style.position = "relative";
 			style.left = "0";
@@ -619,19 +633,19 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			targetArea.items = firstListArea.concat(lastListArea);
 	
 			this._setMarginArea(targetArea, node);
-			dojo.forEach(this._areaList, function(obj){
+			array.forEach(this._areaList, function(obj){
 				obj.initItems = false;
 			});
 			// disconnect onDrop handler
-			dojo.disconnect(this._dragItem.handlers.pop());
-			dojo.disconnect(this._dragItem.handlers.pop());
+			connect.disconnect(this._dragItem.handlers.pop());
+			connect.disconnect(this._dragItem.handlers.pop());
 			this._resetAfterDrop();
 			// remove the cover
 			if(this._cover){
 				dojo.body().removeChild(this._cover);
 				dojo.body().removeChild(this._cover2);
 			}
-			dojo.publish("/dojox/mdnd/drop",[node, targetArea, indexChild]);
+			connect.publish("/dojox/mdnd/drop",[node, targetArea, indexChild]);
 		},
 	
 		_resetAfterDrop: function(){
@@ -649,10 +663,10 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			this._sourceDropIndex = -1;
 			this._dropIndicator.remove();
 			if(this._dragStartHandler){
-				dojo.disconnect(this._dragStartHandler);
+				connect.disconnect(this._dragStartHandler);
 			}
-			if(dojo.isIE > 7){
-				dojo.forEach(this._eventsIE7, dojo.disconnect);
+			if(sniff("ie") > 7){
+				array.forEach(this._eventsIE7, connect.disconnect);
 			}
 		},
 	
@@ -667,34 +681,35 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 					throw new Error("Error while destroying AreaManager");
 				}
 			}
-			dojo.disconnect(this.resizeHandler);
+			connect.disconnect(this.resizeHandler);
 			this._dropIndicator.destroy();
 			this._dropMode.destroy();
 			if(dojox.mdnd.autoScroll){
 				dojox.mdnd.autoScroll.destroy();
 			}
 			if(this.refreshListener){
-				dojo.unsubscribe(this.refreshListener);
+				connect.unsubscribe(this.refreshListener);
 			}
 			// destroy the cover
 			if(this._cover){
-				dojo._destroyElement(this._cover);
-				dojo._destroyElement(this._cover2);
+				domConstruct.destroy(this._cover);
+				domConstruct.destroy(this._cover2);
 				delete this._cover;
 				delete this._cover2;
 			}
 		}
 	});
 	
-	if(dijit && dijit._Widget){
+	if(_Widget){
 		//	Add a new property to widget
-		dojo.extend(dijit._Widget, {
+		lang.extend(_Widget, {
 			// dndType: String
 			//		Defines a type of widget.
 			dndType : "text"
 		});
 	}
-	
+
+	// TODO for 2.0 (or earlier): these values should be set on "am", the export of this module, not in dojox.mdnd
 	dojox.mdnd._areaManager = null;
 	dojox.mdnd.areaManager = function(){
 		// summary:
diff --git a/dojox/mdnd/AutoScroll.js b/dojox/mdnd/AutoScroll.js
index 7efd7a0..617c0fc 100644
--- a/dojox/mdnd/AutoScroll.js
+++ b/dojox/mdnd/AutoScroll.js
@@ -1,6 +1,12 @@
-define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/connect",
-	"dojo/_base/window"],function(dojo){
-	var as = dojo.declare(
+define(["dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/connect",
+	"dojo/_base/sniff",
+	"dojo/ready",
+	"dojo/_base/window"
+],function(dojo, declare, lang, connect, sniff, ready){
+	var as = declare(
 		"dojox.mdnd.AutoScroll",
 		null,
 	{
@@ -20,15 +26,15 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/c
 	
 		constructor: function(){
 			//console.log("dojox.mdnd.AutoScroll ::: constructor ");
-			this.resizeHandler = dojo.connect(dojo.global,"onresize", this, function(){
+			this.resizeHandler = connect.connect(dojo.global,"onresize", this, function(){
 				this.getViewport();
 			});
-			dojo.ready(dojo.hitch(this, "init"));
+			ready(lang.hitch(this, "init"));
 		},
 	
 		init: function(){
 			//console.log("dojox.mdnd.AutoScroll ::: init ");
-			this._html = (dojo.isWebKit) ? dojo.body() : dojo.body().parentNode;
+			this._html = (sniff("webkit"))? dojo.body() : dojo.body().parentNode;
 			this.getViewport();
 		},
 	
@@ -114,7 +120,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/c
 				this._html.scrollTop += this.interval;
 				this._node.style.top = (parseInt(this._node.style.top) + this.interval) + "px";
 				this._y += this.interval;
-				this._timer = setTimeout(dojo.hitch(this, "_autoScrollDown"), this.recursiveTimer);
+				this._timer = setTimeout(lang.hitch(this, "_autoScrollDown"), this.recursiveTimer);
 			}
 		},
 	
@@ -132,7 +138,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/c
 				this._html.scrollTop -= this.interval;
 				this._node.style.top = (parseInt(this._node.style.top) - this.interval) + "px";
 				this._y -= this.interval;
-				this._timer = setTimeout(dojo.hitch(this, "_autoScrollUp"),this.recursiveTimer);
+				this._timer = setTimeout(lang.hitch(this, "_autoScrollUp"),this.recursiveTimer);
 			}
 		},
 	
@@ -150,7 +156,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/c
 				this._html.scrollLeft += this.interval;
 				this._node.style.left = (parseInt(this._node.style.left) + this.interval) + "px";
 				this._x += this.interval;
-				this._timer = setTimeout(dojo.hitch(this, "_autoScrollRight"), this.recursiveTimer);
+				this._timer = setTimeout(lang.hitch(this, "_autoScrollRight"), this.recursiveTimer);
 			}
 		},
 	
@@ -168,7 +174,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/c
 				this._html.scrollLeft -= this.interval;
 				this._node.style.left = (parseInt(this._node.style.left) - this.interval) + "px";
 				this._x -= this.interval;
-				this._timer = setTimeout(dojo.hitch(this, "_autoScrollLeft"),this.recursiveTimer);
+				this._timer = setTimeout(lang.hitch(this, "_autoScrollLeft"),this.recursiveTimer);
 			}
 		},
 	
@@ -185,7 +191,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/lang","dojo/_base/c
 	
 		destroy: function(){
 			//console.log("dojox.mdnd.AutoScroll ::: destroy ");
-			dojo.disconnect(this.resizeHandler);
+			connect.disconnect(this.resizeHandler);
 		}
 	});
 	
diff --git a/dojox/mdnd/DropIndicator.js b/dojox/mdnd/DropIndicator.js
index 437f415..94f1c9f 100644
--- a/dojox/mdnd/DropIndicator.js
+++ b/dojox/mdnd/DropIndicator.js
@@ -1,5 +1,10 @@
-define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","./AreaManager"],function(dojo){
-	var di = dojo.declare(
+define(["dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"./AreaManager"
+], function(dojo, declare, domClass, domConstruct){
+	var di = declare(
 		"dojox.mdnd.DropIndicator",
 		null,
 	{
@@ -15,7 +20,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","./AreaManage
 			var dropIndicator = document.createElement("div");
 			var subDropIndicator = document.createElement("div");
 			dropIndicator.appendChild(subDropIndicator);
-			dojo.addClass(dropIndicator, "dropIndicator");
+			domClass.add(dropIndicator, "dropIndicator");
 			this.node = dropIndicator;
 		},
 		
@@ -72,7 +77,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","./AreaManage
 				if(this.node.parentNode){
 					this.node.parentNode.removeChild(this.node);
 				}
-				dojo._destroyElement(this.node);
+				domConstruct.destroy(this.node);
 				delete this.node;
 			}
 		}
diff --git a/dojox/mdnd/LazyManager.js b/dojox/mdnd/LazyManager.js
index aaf2654..791edc3 100644
--- a/dojox/mdnd/LazyManager.js
+++ b/dojox/mdnd/LazyManager.js
@@ -1,12 +1,16 @@
 define([
-	"dojo/_base/kernel",	// dojo.addOnUnload
-	"dojo/_base/lang",	// dojo.hitch
+	"dojo/_base/kernel",	
 	"dojo/_base/declare",
-	"dojo/_base/html",	// dojo.create, dojo.attr, dojo.addClass
+	"dojo/_base/lang",	// dojo.hitch
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-attr",
+	"dojo/dnd/common",
 	"dojo/dnd/Manager",
-	"./PureSource"
-],function(dojo){
-	return dojo.declare(
+	"./PureSource",
+	"dojo/_base/unload"  // dojo.addOnUnload
+],function(dojo, declare, lang, domClass, domConstruct, domAttr, dnd, Manager, PureSource){
+	return declare(
 		"dojox.mdnd.LazyManager",
 		null,
 	{
@@ -17,12 +21,12 @@ define([
 			//console.log("dojox.mdnd.LazyManager ::: constructor");
 			this._registry = {};
 			// initialization of the _fakeSource to enabled DragAndDrop :
-			this._fakeSource = new dojox.mdnd.PureSource(dojo.create("div"), {
+			this._fakeSource = new PureSource(domConstruct.create("div"), {
 				'copyOnly': false
 			});
 			this._fakeSource.startup();
-			dojo.addOnUnload(dojo.hitch(this, "destroy"));
-			this.manager = dojo.dnd.manager();
+			dojo.addOnUnload(lang.hitch(this, "destroy"));
+			this.manager = Manager.manager();
 		},
 		
 		getItem: function(/*DOMNode*/draggedNode){
@@ -44,9 +48,9 @@ define([
 				var m = this.manager,
 					object = this.getItem(draggedNode);
 				if(draggedNode.id == ""){
-					dojo.attr(draggedNode, "id", dojo.dnd.getUniqueId());
+				  domAttr.set(draggedNode, "id", dnd.getUniqueId());
 				}
-				dojo.addClass(draggedNode, "dojoDndItem");
+				domClass.add(draggedNode, "dojoDndItem");
 				this._fakeSource.setItem(draggedNode.id, object);
 				m.startDrag(this._fakeSource, [draggedNode], false);
 				m.onMouseMove(e);
diff --git a/dojox/mdnd/Moveable.js b/dojox/mdnd/Moveable.js
index 2669206..ef5d7dc 100644
--- a/dojox/mdnd/Moveable.js
+++ b/dojox/mdnd/Moveable.js
@@ -1,14 +1,16 @@
 define([
 	"dojo/_base/kernel",
+	"dojo/_base/declare",
 	"dojo/_base/array",
 	"dojo/_base/connect",
-	"dojo/_base/declare",
 	"dojo/_base/event",
-	"dojo/_base/html",
 	"dojo/_base/sniff",
+	"dojo/dom",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
 	"dojo/_base/window"
-],function(dojo){
-	return dojo.declare(
+],function(dojo, declare, array, connect, event, sniff, dom, geom, domStyle){
+	return declare(
 		"dojox.mdnd.Moveable",
 		null,
 	{
@@ -20,7 +22,7 @@ define([
 		handle: null,
 		
 		// skip: Boolean
-		// 		A flag to control a drag action if a form element has been focused.
+		//		A flag to control a drag action if a form element has been focused.
 		//		If true, the drag action is not executed.
 		skip: true,
 	
@@ -31,7 +33,7 @@ define([
 		
 		constructor: function(/*Object*/params, /*DOMNode*/node){
 			// summary:
-			// 		Configure parameters and listen to mousedown events from handle
+			//		Configure parameters and listen to mousedown events from handle
 			//		node.
 			// params:
 			//		Hash of parameters
@@ -39,16 +41,16 @@ define([
 			//		The draggable node
 	
 			//console.log("dojox.mdnd.Moveable ::: constructor");
-			this.node = dojo.byId(node);
+			this.node = dom.byId(node);
 			
 			this.d = this.node.ownerDocument;
 			
 			if(!params){ params = {}; }
-			this.handle = params.handle ? dojo.byId(params.handle) : null;
+			this.handle = params.handle ? dom.byId(params.handle) : null;
 			if(!this.handle){ this.handle = this.node; }
 			this.skip = params.skip;
 			this.events = [
-				dojo.connect(this.handle, "onmousedown", this, "onMouseDown")
+				connect.connect(this.handle, "onmousedown", this, "onMouseDown")
 			];
 			if(dojox.mdnd.autoScroll){
 				this.autoScroll = dojox.mdnd.autoScroll;
@@ -93,12 +95,12 @@ define([
 				this.autoScroll.setAutoScrollNode(this.node);
 				this.autoScroll.setAutoScrollMaxPage();
 			}
-			this.events.push(dojo.connect(this.d, "onmouseup", this, "onMouseUp"));
-			this.events.push(dojo.connect(this.d, "onmousemove", this, "onFirstMove"));
-			this._selectStart = dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent);
+			this.events.push(connect.connect(this.d, "onmouseup", this, "onMouseUp"));
+			this.events.push(connect.connect(this.d, "onmousemove", this, "onFirstMove"));
+			this._selectStart = connect.connect(dojo.body(), "onselectstart", event.stop);
 			this._firstX = e.clientX;
 			this._firstY = e.clientY;
-			dojo.stopEvent(e);
+			event.stop(e);
 		},
 		
 		onFirstMove: function(/*DOMEvent*/e){
@@ -113,15 +115,15 @@ define([
 			//		callback
 	
 			//console.log("dojox.mdnd.Moveable ::: onFirstMove");
-			dojo.stopEvent(e);
+			event.stop(e);
 			var d = (this._firstX - e.clientX) * (this._firstX - e.clientX)
 					+ (this._firstY - e.clientY) * (this._firstY - e.clientY);
 			if(d > this.dragDistance * this.dragDistance){
 				this._isDragging = true;
-				dojo.disconnect(this.events.pop());
-				dojo.style(this.node, "width", dojo.contentBox(this.node).w + "px");
+				connect.disconnect(this.events.pop());
+				domStyle.set(this.node, "width", geom.getContentBox(this.node).w + "px");
 				this.initOffsetDrag(e);
-				this.events.push(dojo.connect(this.d, "onmousemove", this, "onMove"));
+				this.events.push(connect.connect(this.d, "onmousemove", this, "onMove"));
 			}
 		},
 		
@@ -135,7 +137,7 @@ define([
 			//console.log("dojox.mdnd.Moveable ::: initOffsetDrag");
 			this.offsetDrag = { 'l': e.pageX, 't': e.pageY };
 			var s = this.node.style;
-			var position = dojo.position(this.node, true);
+			var position = geom.position(this.node, true);
 			/*if(s.position == "relative" || s.position == ""){
 				s.position = "absolute"; // enforcing the absolute mode
 			}*/
@@ -163,9 +165,9 @@ define([
 			//		callback
 	
 			//console.log("dojox.mdnd.Moveable ::: onMove");
-			dojo.stopEvent(e);
+			event.stop(e);
 			// hack to avoid too many calls to onMove in IE8 causing sometimes slowness
-			if(dojo.isIE == 8 && new Date() - this.date < 20){
+			if(sniff("ie") == 8 && new Date() - this.date < 20){
 				return;
 			}
 			if(this.autoScroll){
@@ -181,7 +183,7 @@ define([
 			
 			// method to catch
 			this.onDrag(this.node, coords, this.size, {'x':e.pageX, 'y':e.pageY});
-			if(dojo.isIE == 8){
+			if(sniff("ie") == 8){
 				this.date = new Date();
 			}
 		},
@@ -194,7 +196,7 @@ define([
 			//		a DOM event
 	
 			if (this._isDragging){
-				dojo.stopEvent(e);
+				event.stop(e);
 				this._isDragging = false;
 				if(this.autoScroll){
 					this.autoScroll.stopAutoScroll();
@@ -203,8 +205,8 @@ define([
 				this.onDragEnd(this.node);
 				this.node.focus();
 			}
-			dojo.disconnect(this.events.pop());
-			dojo.disconnect(this.events.pop());
+			connect.disconnect(this.events.pop());
+			connect.disconnect(this.events.pop());
 		},
 		
 		onDragStart: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size){
@@ -213,7 +215,7 @@ define([
 			//		Notes : border box model
 			// node:
 			//		a DOM node
-			//	coords:
+			// coords:
 			//		absolute position of the main node
 			// size:
 			//		an object encapsulating width an height values
@@ -255,7 +257,7 @@ define([
 			//		Delecte associated events
 	
 			// console.log("dojox.mdnd.Moveable ::: destroy");
-			dojo.forEach(this.events, dojo.disconnect);
+			array.forEach(this.events, connect.disconnect);
 			this.events = this.node = null;
 		}
 	});
diff --git a/dojox/mdnd/PureSource.js b/dojox/mdnd/PureSource.js
index 56feb5a..a13a20a 100644
--- a/dojox/mdnd/PureSource.js
+++ b/dojox/mdnd/PureSource.js
@@ -1,8 +1,16 @@
-define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/connect",
-	"dojo/_base/array","dojo/dnd/Selector","dojo/dnd/Manager"],function(dojo){
-	return dojo.declare(
+define(["dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/connect",
+	"dojo/_base/array",
+	"dojo/dom-class",
+	"dojo/dnd/common",
+	"dojo/dnd/Selector",
+	"dojo/dnd/Manager"
+],function(dojo, declare, lang, connect, array, domClass, dnd, Selector, Manager){
+	return declare(
 		"dojox.mdnd.PureSource",
-		dojo.dnd.Selector,
+		Selector,
 	{
 		// summary:
 		//		A Source Object, which can be used only as a DnD source.
@@ -27,7 +35,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 			//		object which is mixed-in to the 'dojo.dnd.Source' instance.
 	
 			//console.log('dojox.mdnd.PureSource ::: constructor');
-			dojo.mixin(this, dojo.mixin({}, params));
+			lang.mixin(this, lang.mixin({}, params));
 			var type = this.accept;
 			
 			// class-specific variables
@@ -36,14 +44,14 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 	
 			// states
 			this.sourceState = "";
-			dojo.addClass(this.node, "dojoDndSource");
+			domClass.add(this.node, "dojoDndSource");
 			if(this.horizontal){
-				dojo.addClass(this.node, "dojoDndHorizontal");
+				domClass.add(this.node, "dojoDndHorizontal");
 			}
 			// set up events
 			this.topics = [
-				dojo.subscribe("/dnd/cancel", this, "onDndCancel"),
-				dojo.subscribe("/dnd/drop", this, "onDndCancel")
+				connect.subscribe("/dnd/cancel", this, "onDndCancel"),
+				connect.subscribe("/dnd/drop", this, "onDndCancel")
 			];
 		},
 		
@@ -79,7 +87,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 	
 			//console.log('dojox.mdnd.PureSource ::: destroy');
 			dojox.mdnd.PureSource.superclass.destroy.call(this);
-			dojo.forEach(this.topics, dojo.unsubscribe);
+			array.forEach(this.topics, connect.unsubscribe);
 			this.targetAnchor = null;
 		},
 	
@@ -109,11 +117,11 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 				return;
 			}
 			dojox.mdnd.PureSource.superclass.onMouseMove.call(this, e);
-			var m = dojo.dnd.manager();
+			var m = Manager.manager();
 			if(this.mouseDown && !this.isDragging && this.isSource){
 				var nodes = this.getSelectedNodes();
 				if(nodes.length){
-					m.startDrag(this, nodes, this.copyState(dojo.isCopyKey(e)));
+					m.startDrag(this, nodes, this.copyState(connect.isCopyKey(e)));
 					this.isDragging = true;
 				}
 			}
@@ -129,7 +137,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 			//		callback
 	
 			//console.log('dojox.mdnd.PureSource ::: onMouseDown');
-			if(this._legalMouseDown(e) && (!this.skipForm || !dojo.dnd.isFormElement(e))){
+			if(this._legalMouseDown(e) && (!this.skipForm || !dnd.isFormElement(e))){
 				this.mouseDown = true;
 				this.mouseButton = e.button;
 				dojox.mdnd.PureSource.superclass.onMouseDown.call(this, e);
@@ -159,7 +167,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 	
 			//console.log('dojox.mdnd.PureSource ::: onOverEvent');
 			dojox.mdnd.PureSource.superclass.onOverEvent.call(this);
-			dojo.dnd.manager().overSource(this);
+			Manager.manager().overSource(this);
 		},
 		
 		onOutEvent: function(){
@@ -170,7 +178,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 	
 			//console.log('dojox.mdnd.PureSource ::: onOutEvent');
 			dojox.mdnd.PureSource.superclass.onOutEvent.call(this);
-			dojo.dnd.manager().outSource(this);
+			Manager.manager().outSource(this);
 		},
 		
 		_markDndStatus: function(/*Boolean*/copy){
@@ -193,12 +201,12 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 			// returns:
 			//		True if user clicked on "approved" items.
 			// tags:
-			// 		protected
+			//		protected
 	
 			//console.log('dojox.mdnd.PureSource ::: _legalMouseDown');
 			if(!this.withHandles){ return true; }
-			for(var node = e.target; node && !dojo.hasClass(node, "dojoDndItem"); node = node.parentNode){
-				if(dojo.hasClass(node, "dojoDndHandle")){ return true; }
+			for(var node = e.target; node && !domClass.contains(node, "dojoDndItem"); node = node.parentNode){
+				if(domClass.contains(node, "dojoDndHandle")){ return true; }
 			}
 			return false;	// Boolean
 		}
diff --git a/dojox/mdnd/adapter/DndFromDojo.js b/dojox/mdnd/adapter/DndFromDojo.js
index 14dff87..5e7b034 100644
--- a/dojox/mdnd/adapter/DndFromDojo.js
+++ b/dojox/mdnd/adapter/DndFromDojo.js
@@ -1,10 +1,17 @@
-define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_base/array",
-	"dojo/_base/html","dojo/_base/window","dojox/mdnd/AreaManager","dojo/dnd/Manager"],function(dojo){
-	var dfd = dojo.declare(
+define(["dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dojo/_base/array",
+	"dojo/dom-class",
+	"dojo/_base/window",
+	"dojox/mdnd/AreaManager",
+	"dojo/dnd/Manager"
+],function(dojo, declare, connect, array, domClass, win, AreaManager, Manager){
+	var dfd = declare(
 		"dojox.mdnd.adapter.DndFromDojo",
 		null,
 	{
-		// summary
+		// summary:
 		//		Allow communication between Dojo dnd items and DojoX D&D areas
 	
 		// dropIndicatorSize: Object
@@ -41,7 +48,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 	
 		constructor: function(){
 			this._areaManager = dojox.mdnd.areaManager();
-			this._dojoManager = dojo.dnd.manager();
+			this._dojoManager = Manager.manager();
 			this._currentArea = null;
 			this._moveHandler = null;
 			this.subscribeDnd();
@@ -53,10 +60,10 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 	
 			//console.log(("dojox.mdnd.adapter.DndFromDojo ::: subscribeDnd");
 			this._subscribeHandler = [
-				dojo.subscribe("/dnd/start",this,"onDragStart"),
-				dojo.subscribe("/dnd/drop/before", this, "onDrop"),
-				dojo.subscribe("/dnd/cancel",this,"onDropCancel"),
-				dojo.subscribe("/dnd/source/over",this,"onDndSource")
+				connect.subscribe("/dnd/start",this,"onDragStart"),
+				connect.subscribe("/dnd/drop/before", this, "onDrop"),
+				connect.subscribe("/dnd/cancel",this,"onDropCancel"),
+				connect.subscribe("/dnd/source/over",this,"onDndSource")
 			]
 		},
 	
@@ -65,7 +72,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			//		Unsubscribe to some topics of dojo drag and drop.
 	
 			//console.log(("dojox.mdnd.adapter.DndFromDojo ::: unsubscribeDnd");
-			dojo.forEach(this._subscribeHandler, dojo.unsubscribe);
+			array.forEach(this._subscribeHandler, connect.unsubscribe);
 		},
 	
 		_getHoverArea: function(/*Object*/ coords){
@@ -134,10 +141,10 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			// Connect the onMouseMove :
 			// It's usefull to activate the detection of a D&D area and the dropIndicator place only if
 			// the dragNode is out of a the source dojo. The classic behaviour of the dojo source is kept.
-			this._outSourceHandler = dojo.connect(this._dojoManager, "outSource", this, function(){
+			this._outSourceHandler = connect.connect(this._dojoManager, "outSource", this, function(){
 				//dojo.disconnect(this._outSourceHandler);
 				if(this._moveHandler == null){
-					this._moveHandler = dojo.connect(dojo.doc, "mousemove", this, "onMouseMove");
+					this._moveHandler = connect.connect(dojo.doc, "mousemove", this, "onMouseMove");
 				}
 			});
 		},
@@ -162,7 +169,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 				// specific case : a dropIndicator can be hidden (see onDndSource method)
 				if(this._areaManager._dropIndicator.node.style.visibility == "hidden"){
 					this._areaManager._dropIndicator.node.style.visibility = "";
-					dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
+					domClass.add(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
 				}
 				// place the dropIndicator in D&D Area with a default size.
 				this._areaManager.placeDropIndicator(coords, this.dropIndicatorSize);
@@ -184,10 +191,10 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			// if the D&D dojoX Area accepts the drop, change the color of Avatar.
 			if(this._dojoManager.avatar){
 				if(this._areaManager._accept){
-					dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
+					domClass.add(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
 				}
 				else{
-					dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
+					domClass.remove(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
 				}
 			}
 		},
@@ -201,7 +208,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			this._areaManager._accept = false;
 			// change color of avatar
 			if(this._dojoManager.avatar){
-				dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
+				domClass.remove(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
 			}
 			// reset all variables and remove the dropIndicator.
 			if(this._currentArea == null){
@@ -256,7 +263,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 				}
 				if(accept){
 					// disconnect the onMouseMove to disabled the search of a drop zone in the D&D dojoX Area.
-					dojo.disconnect(this._moveHandler);
+					connect.disconnect(this._moveHandler);
 					this._currentArea = this._moveHandler = null;
 					// hidden the visibility of dojoX dropIndicator to prevent an offset when the dropIndicator disappears.
 					// test if drop indicator is visible before applaying hidden style.
@@ -274,7 +281,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 				// Exit of a source/target dojo.
 				// reconnect the onMouseMove to enabled the search of a drop zone in the D&D dojox Area.
 				if(!this._moveHandler)
-					this._moveHandler = dojo.connect(dojo.doc, "mousemove", this, "onMouseMove");
+					this._moveHandler = connect.connect(dojo.doc, "mousemove", this, "onMouseMove");
 	
 				this._resetAvatar();
 			}
@@ -292,10 +299,10 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			//console.log("dojox.mdnd.adapter.DndFromDojo ::: _resetAvatar");
 			if(this._dojoManager.avatar){
 				if(this._areaManager._accept){
-					dojo.addClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
+					domClass.add(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
 				}
 				else{
-					dojo.removeClass(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
+					domClass.remove(this._dojoManager.avatar.node, "dojoDndAvatarCanDrop");
 				}
 			}
 		},
@@ -310,8 +317,8 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			if(this._currentArea == null){
 				// the dragged node is not in the D&D dojox Area => Cancel
 				this._areaManager._resetAfterDrop();
-				dojo.disconnect(this._moveHandler);
-				dojo.disconnect(this._outSourceHandler);
+				connect.disconnect(this._moveHandler);
+				connect.disconnect(this._outSourceHandler);
 				this._currentArea = this._moveHandler = this._outSourceHandler = null;
 			}
 			else{
@@ -323,8 +330,8 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 				}
 				else{
 					this._currentArea = null;
-					dojo.disconnect(this._outSourceHandler);
-					dojo.disconnect(this._moveHandler);
+					connect.disconnect(this._outSourceHandler);
+					connect.disconnect(this._moveHandler);
 					this._moveHandler = this._outSourceHandler = null;
 				}
 			}
@@ -343,12 +350,12 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			//		callback
 	
 			//console.log("dojox.mdnd.adapter.DndFromDojo ::: onDrop", this._currentArea);
-			dojo.disconnect(this._moveHandler);
-			dojo.disconnect(this._outSourceHandler);
+			connect.disconnect(this._moveHandler);
+			connect.disconnect(this._outSourceHandler);
 			this._moveHandler = this._outSourceHandler = null;
 			if(this._currentArea){
 				var dropIndex = this._areaManager._currentDropIndex;
-				dojo.publish("/dnd/drop/after", [source, nodes, copy, this._currentArea, dropIndex]);
+				connect.publish("/dnd/drop/after", [source, nodes, copy, this._currentArea, dropIndex]);
 				this._currentArea = null;
 			}
 			if(this._areaManager._dropIndicator.node.style.visibility == "hidden"){
diff --git a/dojox/mdnd/adapter/DndToDojo.js b/dojox/mdnd/adapter/DndToDojo.js
index c93bf95..7e82b4c 100644
--- a/dojox/mdnd/adapter/DndToDojo.js
+++ b/dojox/mdnd/adapter/DndToDojo.js
@@ -1,6 +1,16 @@
-define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/connect",
-	"dojo/_base/window","dojo/_base/array","dojox/mdnd/PureSource","dojox/mdnd/LazyManager"],function(dojo){
-	var dtd = dojo.declare(
+define(["dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dojo/_base/array",
+	"dojo/dom-class",
+	"dojo/dom-style",
+	"dojo/dom-geometry",
+	"dojo/topic", // topic.publish()
+	"dojo/_base/window",
+	"dojox/mdnd/PureSource",
+	"dojox/mdnd/LazyManager"
+],function(dojo, declare, connect, array, domClass, domStyle, geom, topic, win){
+	var dtd = declare(
 		"dojox.mdnd.adapter.DndToDojo",
 		null,
 	{
@@ -36,24 +46,24 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 		_moveUpHandler: null,
 	
 		// _draggedNode: DOMNode
-		// 		The current dragged node
+		//		The current dragged node
 		_draggedNode: null,
 	
 		constructor: function(){
 			this._dojoList = [];
 			this._currentDojoArea = null;
 			this._dojoxManager = dojox.mdnd.areaManager();
-			this._dragStartHandler = dojo.subscribe("/dojox/mdnd/drag/start", this, function(node, sourceArea, sourceDropIndex){
+			this._dragStartHandler = connect.subscribe("/dojox/mdnd/drag/start", this, function(node, sourceArea, sourceDropIndex){
 				this._draggedNode = node;
-				this._moveHandler = dojo.connect(dojo.doc, "onmousemove", this, "onMouseMove");
+				this._moveHandler = connect.connect(dojo.doc, "onmousemove", this, "onMouseMove");
 			});
-			this._dropHandler = dojo.subscribe("/dojox/mdnd/drop", this, function(node, targetArea, indexChild){
+			this._dropHandler = connect.subscribe("/dojox/mdnd/drop", this, function(node, targetArea, indexChild){
 				if(this._currentDojoArea){
-					dojo.publish("/dojox/mdnd/adapter/dndToDojo/cancel", [this._currentDojoArea.node, this._currentDojoArea.type, this._draggedNode, this.accept]);
+					connect.publish("/dojox/mdnd/adapter/dndToDojo/cancel", [this._currentDojoArea.node, this._currentDojoArea.type, this._draggedNode, this.accept]);
 				}
 				this._draggedNode = null;
 				this._currentDojoArea = null;
-				dojo.disconnect(this._moveHandler);
+				connect.disconnect(this._moveHandler);
 			});
 		},
 	
@@ -90,10 +100,10 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 	
 			//console.log('dojox.mdnd.adapter.DndToDojo ::: _initCoordinates');
 			if(area){
-				var position = dojo.position(area, true),
+				var position = geom.position(area, true),
 					coords = {};
-				coords.x = position.x
-				coords.y = position.y
+				coords.x = position.x;
+				coords.y = position.y;
 				coords.x1 = position.x + position.w;
 				coords.y1 = position.y + position.h;
 				return coords;	// 	Object
@@ -101,18 +111,19 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 			return null;
 		},
 	
-		register: function(/*DOMNode*/area, /*String*/ type,/*Boolean*/ dojoTarget){
+		register: function(/*DOMNode*/area, /*String*/ type, /*Boolean*/ dojoTarget){
 			// summary:
 			//		Register a target dojo.
 			//		The target is represented by an object containing :
-			// 			- the dojo area node
-			// 			- the type reference to identify a group node
-			// 			- the coords of the area to enable refresh position
+			//
+			//		- the dojo area node
+			//		- the type reference to identify a group node
+			//		- the coords of the area to enable refresh position
 			// area:
 			//		The DOM node which has to be registered.
 			// type:
 			//		A String to identify the node.
-			// dojoTarger:
+			// dojoTarget:
 			//		True if the dojo D&D have to be enable when mouse is hover the registered target dojo.
 	
 			//console.log("dojox.mdnd.adapter.DndToDojo ::: registerDojoArea", area, type, dojoTarget);
@@ -155,7 +166,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 			//console.log("dojox.mdnd.adapter.DndToDojo ::: unregisterByType", type);
 			if(type){
 				var tempList = [];
-				dojo.forEach(this._dojoList, function(item, i){
+				array.forEach(this._dojoList, function(item, i){
 					if(item.type != type){
 						tempList.push(item);
 					}
@@ -179,7 +190,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 			//console.log("dojox.mdnd.adapter.DndToDojo ::: refresh");
 			var dojoList = this._dojoList;
 			this.unregister();
-			dojo.forEach(dojoList, function(dojo){
+			array.forEach(dojoList, function(dojo){
 				dojo.coords = this._initCoordinates(dojo.node);
 			}, this);
 			this._dojoList = dojoList;
@@ -194,7 +205,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 			//console.log("dojox.mdnd.adapter.DndToDojo ::: refresh");
 			var dojoList = this._dojoList;
 			this.unregister();
-			dojo.forEach(dojoList, function(dojo){
+			array.forEach(dojoList, function(dojo){
 				if(dojo.type == type){
 					dojo.coords = this._initCoordinates(dojo.node);
 				}
@@ -277,44 +288,44 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 			// specific for drag and drop switch
 			if(this._currentDojoArea.dojo){
 				// disconnect
-				dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
-				dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
+				connect.disconnect(this._dojoxManager._dragItem.handlers.pop());
+				connect.disconnect(this._dojoxManager._dragItem.handlers.pop());
 				//disconnect onmousemove of moveable item
 				//console.info("before",this._dojoxManager._dragItem.item.events.pop());
-				dojo.disconnect(this._dojoxManager._dragItem.item.events.pop());
-				dojo.body().removeChild(this._dojoxManager._cover);
-				dojo.body().removeChild(this._dojoxManager._cover2);
+				connect.disconnect(this._dojoxManager._dragItem.item.events.pop());
+				win.body().removeChild(this._dojoxManager._cover);
+				win.body().removeChild(this._dojoxManager._cover2);
 				var node = this._dojoxManager._dragItem.item.node;
 				// hide dragNode :
 				// disconnect the dojoDndAdapter if it's initialize
 				if(dojox.mdnd.adapter._dndFromDojo){
 					dojox.mdnd.adapter._dndFromDojo.unsubscribeDnd();
 				}
-				dojo.style(node, {
+				domStyle.set(node, {
 					'position': "relative",
 					'top': '0',
 					'left': '0'
 				});
 				// launch the drag and drop Dojo.
 				this._lazyManager.startDrag(e, node);
-				var handle = dojo.connect(this._lazyManager.manager, "overSource", this, function(){
-					dojo.disconnect(handle);
+				var handle = connect.connect(this._lazyManager.manager, "overSource", this, function(){
+					connect.disconnect(handle);
 					if(this._lazyManager.manager.canDropFlag){
 						// remove dropIndicator
 						this._dojoxManager._dropIndicator.node.style.display = "none";
 					}
 				});
 	
-				this.cancelHandler = dojo.subscribe("/dnd/cancel", this, function(){
+				this.cancelHandler = connect.subscribe("/dnd/cancel", this, function(){
 					var moveableItem = this._dojoxManager._dragItem.item;
 					// connect onmousemove of moveable item
 					// need to reconnect the onmousedown of movable class.
 					moveableItem.events = [
-						dojo.connect(moveableItem.handle, "onmousedown", moveableItem, "onMouseDown")
+						connect.connect(moveableItem.handle, "onmousedown", moveableItem, "onMouseDown")
 					];
 					// replace the cover and the dragNode in the cover.
-					dojo.body().appendChild(this._dojoxManager._cover);
-					dojo.body().appendChild(this._dojoxManager._cover2);
+					win.body().appendChild(this._dojoxManager._cover);
+					win.body().appendChild(this._dojoxManager._cover2);
 					this._dojoxManager._cover.appendChild(moveableItem.node);
 	
 					var objectArea = this._dojoxManager._areaList[this._dojoxManager._sourceIndexArea];
@@ -327,19 +338,19 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 					if(this._dojoxManager._dropIndicator.node.style.display == "none"){
 						this._dojoxManager._dropIndicator.node.style.display == "";
 					}
-					this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
-					this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
+					this._dojoxManager._dragItem.handlers.push(connect.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
+					this._dojoxManager._dragItem.handlers.push(connect.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
 					this._draggedNode.style.display = "";
 					this._dojoxManager.onDrop(this._draggedNode);
-					dojo.unsubscribe(this.cancelHandler);
-					dojo.unsubscribe(this.dropHandler);
+					connect.unsubscribe(this.cancelHandler);
+					connect.unsubscribe(this.dropHandler);
 					if(dojox.mdnd.adapter._dndFromDojo){
 						dojox.mdnd.adapter._dndFromDojo.subscribeDnd();
 					}
 				});
-				this.dropHandler = dojo.subscribe("/dnd/drop/before", this, function(params){
-					dojo.unsubscribe(this.cancelHandler);
-					dojo.unsubscribe(this.dropHandler);
+				this.dropHandler = connect.subscribe("/dnd/drop/before", this, function(params){
+					connect.unsubscribe(this.cancelHandler);
+					connect.unsubscribe(this.dropHandler);
 					this.onDrop();
 				});
 			}
@@ -347,17 +358,17 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 				this.accept = this.isAccepted(this._dojoxManager._dragItem.item.node, this._currentDojoArea);
 				if(this.accept){
 					// disconnect
-					dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
-					dojo.disconnect(this._dojoxManager._dragItem.handlers.pop());
+					connect.disconnect(this._dojoxManager._dragItem.handlers.pop());
+					connect.disconnect(this._dojoxManager._dragItem.handlers.pop());
 					// remove dropIndicator
 					this._dojoxManager._dropIndicator.node.style.display = "none";
 					if(!this._moveUpHandler){
-						this._moveUpHandler = dojo.connect(dojo.doc, "onmouseup", this, "onDrop");
+						this._moveUpHandler = connect.connect(dojo.doc, "onmouseup", this, "onDrop");
 					}
 				}
 			}
 			// publish a topic
-			dojo.publish("/dojox/mdnd/adapter/dndToDojo/over",[this._currentDojoArea.node, this._currentDojoArea.type, this._draggedNode, this.accept]);
+			connect.publish("/dojox/mdnd/adapter/dndToDojo/over",[this._currentDojoArea.node, this._currentDojoArea.type, this._draggedNode, this.accept]);
 		},
 	
 		onDragExit: function(/*DOMEvent*/e){
@@ -370,20 +381,20 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 			// set the old height of dropIndicator.
 			if(this._oldDojoArea.dojo){
 				// unsubscribe the topic /dnd/cancel and /dnd/drop/before
-				dojo.unsubscribe(this.cancelHandler);
-				dojo.unsubscribe(this.dropHandler);
+				connect.unsubscribe(this.cancelHandler);
+				connect.unsubscribe(this.dropHandler);
 				// launch Drag and Drop
 				var moveableItem = this._dojoxManager._dragItem.item;
 				// connect onmousemove of moveable item
-				this._dojoxManager._dragItem.item.events.push(dojo.connect(
+				this._dojoxManager._dragItem.item.events.push(connect.connect(
 					moveableItem.node.ownerDocument,
 					"onmousemove",
 					moveableItem,
 					"onMove"
 				));
 				// replace the cover and the dragNode in the cover.
-				dojo.body().appendChild(this._dojoxManager._cover);
-				dojo.body().appendChild(this._dojoxManager._cover2);
+				win.body().appendChild(this._dojoxManager._cover);
+				win.body().appendChild(this._dojoxManager._cover2);
 				this._dojoxManager._cover.appendChild(moveableItem.node);
 				// fix style :
 				var style = moveableItem.node.style;
@@ -401,15 +412,15 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 					this._dojoxManager._dropIndicator.node.style.display = "";
 				}
 				// reconnect the areaManager.
-				this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
-				this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
+				this._dojoxManager._dragItem.handlers.push(connect.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
+				this._dojoxManager._dragItem.handlers.push(connect.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
 				this._dojoxManager._dragItem.item.onMove(e);
 			}
 			else{
 				if(this.accept){
 					// disconnect the mouseUp event.
 					if(this._moveUpHandler){
-						dojo.disconnect(this._moveUpHandler);
+						connect.disconnect(this._moveUpHandler);
 						this._moveUpHandler = null;
 					}
 					// redisplay dropIndicator
@@ -417,13 +428,13 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 						this._dojoxManager._dropIndicator.node.style.display = "";
 					}
 					// reconnect the areaManager.
-					this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
-					this._dojoxManager._dragItem.handlers.push(dojo.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
+					this._dojoxManager._dragItem.handlers.push(connect.connect(this._dojoxManager._dragItem.item, "onDrag", this._dojoxManager, "onDrag"));
+					this._dojoxManager._dragItem.handlers.push(connect.connect(this._dojoxManager._dragItem.item, "onDragEnd", this._dojoxManager, "onDrop"));
 					this._dojoxManager._dragItem.item.onMove(e);
 				}
 			}
 			// publish a topic
-			dojo.publish("/dojox/mdnd/adapter/dndToDojo/out",[this._oldDojoArea.node, this._oldDojoArea.type, this._draggedNode, this.accept]);
+			connect.publish("/dojox/mdnd/adapter/dndToDojo/out",[this._oldDojoArea.node, this._oldDojoArea.type, this._draggedNode, this.accept]);
 		},
 	
 		onDrop: function(/*DOMEvent*/e){
@@ -432,7 +443,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 			// e:
 			//		Event object.
 	
-	//		console.log("dojox.mdnd.adapter.DndToDojo ::: onDrop", this._currentDojoArea);
+			//console.log("dojox.mdnd.adapter.DndToDojo ::: onDrop", this._currentDojoArea);
 			if(this._currentDojoArea.dojo){
 				// reconnect the dojoDndAdapter
 				if(dojox.mdnd.adapter._dndFromDojo){
@@ -444,24 +455,24 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 			}
 			// remove the cover
 			if(this._dojoxManager._cover.parentNode && this._dojoxManager._cover.parentNode.nodeType == 1){
-				dojo.body().removeChild(this._dojoxManager._cover);
-				dojo.body().removeChild(this._dojoxManager._cover2);
+				win.body().removeChild(this._dojoxManager._cover);
+				win.body().removeChild(this._dojoxManager._cover2);
 			}
 			// remove draggedNode of target :
 			if(this._draggedNode.parentNode == this._dojoxManager._cover){
 				this._dojoxManager._cover.removeChild(this._draggedNode);
 			}
-			dojo.disconnect(this._moveHandler);
-			dojo.disconnect(this._moveUpHandler);
+			connect.disconnect(this._moveHandler);
+			connect.disconnect(this._moveUpHandler);
 			this._moveHandler = this._moveUpHandler = null;
-			dojo.publish("/dojox/mdnd/adapter/dndToDojo/drop", [this._draggedNode, this._currentDojoArea.node, this._currentDojoArea.type]);
-			dojo.removeClass(this._draggedNode, "dragNode");
+			connect.publish("/dojox/mdnd/adapter/dndToDojo/drop", [this._draggedNode, this._currentDojoArea.node, this._currentDojoArea.type]);
+			domClass.remove(this._draggedNode, "dragNode");
 			var style = this._draggedNode.style;
 			style.position = "relative";
 			style.left = "0";
 			style.top = "0";
 			style.width = "auto";
-			dojo.forEach(this._dojoxManager._dragItem.handlers, dojo.disconnect);
+			array.forEach(this._dojoxManager._dragItem.handlers, connect.disconnect);
 			this._dojoxManager._deleteMoveableItem(this._dojoxManager._dragItem);
 			this._draggedNode = null;
 			this._currentDojoArea = null;
@@ -473,11 +484,11 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/html","dojo/_base/c
 	dojox.mdnd.adapter._dndToDojo = null;
 	dojox.mdnd.adapter.dndToDojo = function(){
 		// summary:
-		// 		returns the current areaManager, creates one if it is not created yet
+		//		returns the current areaManager, creates one if it is not created yet
 		if(!dojox.mdnd.adapter._dndToDojo){
 			dojox.mdnd.adapter._dndToDojo = new dojox.mdnd.adapter.DndToDojo();
 		}
 		return dojox.mdnd.adapter._dndToDojo;	// Object
 	};
 	return dtd;
-});
\ No newline at end of file
+});
diff --git a/dojox/mdnd/dropMode/DefaultDropMode.js b/dojox/mdnd/dropMode/DefaultDropMode.js
index 673a7b2..b8fdf2d 100644
--- a/dojox/mdnd/dropMode/DefaultDropMode.js
+++ b/dojox/mdnd/dropMode/DefaultDropMode.js
@@ -2,10 +2,10 @@ define([
 	"dojo/_base/kernel",
 	"dojo/_base/declare",
 	"dojo/_base/array",
-	"dojo/_base/html",
+	"dojo/dom-geometry",
 	"dojox/mdnd/AreaManager"
-],function(dojo){
-	var ddm = dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
+],function(dojo, declare, array, geom){
+	var ddm = declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
 		// summary:
 		//		Enabled a type of calcul for Dnd.
 		//		Default class to find the nearest target.
@@ -19,7 +19,7 @@ define([
 		_oldYPoint: null,
 	
 		// _oldBehaviour: String
-		// 		see <getDragPoint>
+		//		see `getDragPoint`
 		_oldBehaviour: "up",
 	
 		addArea: function(/*Array*/areas, /*Object*/object){
@@ -34,7 +34,7 @@ define([
 	
 			//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: addArea");
 			var length =  areas.length;
-			var position = dojo.position(object.node, true);
+			var position = geom.position(object.node, true);
 			object.coords = {'x':position.x, 'y':position.y};
 			if (length == 0) {
 				areas.push(object);
@@ -105,7 +105,7 @@ define([
 			//		protected
 	
 			//console.log("dojox.mdnd.dropMode.DefaultDropMode  ::: _updateArea");
-			var position = dojo.position(area.node, true);
+			var position = geom.position(area.node, true);
 			area.coords.x = position.x;
 			area.coords.y = position.y;
 		},
@@ -117,10 +117,10 @@ define([
 			//		the DnD area
 	
 			//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: initItems");
-			dojo.forEach(area.items, function(obj){
+			array.forEach(area.items, function(obj){
 				//get the vertical middle of the item
 				var node = obj.item.node;
-				var position = dojo.position(node, true);
+				var position = geom.position(node, true);
 				var y = position.y + position.h/2;
 				obj.y = y;
 			});
@@ -133,7 +133,7 @@ define([
 			// area:
 			//		a DnD area object
 			// indexItem:
-			// 		index of a draggable item
+			//		index of a draggable item
 			// size:
 			//		dropIndicator size
 			// added:
@@ -164,10 +164,11 @@ define([
 			//		return coordinates of the draggable item
 			// description:
 			//		return for:
-			// 			- X point : the middle
-			//	  		- Y point : search if the user goes up or goes down with his mouse.
-			//	  		- Up : top of the draggable item
-			//	  		- Down : bottom of the draggable item
+			//
+			//		- X point : the middle
+			//	  	- Y point : search if the user goes up or goes down with his mouse.
+			//	  	- Up : top of the draggable item
+			//	  	- Down : bottom of the draggable item
 			// coords:
 			//		an object encapsulating X and Y position
 			// size:
@@ -176,7 +177,7 @@ define([
 			//		coordinates of mouse
 			// returns:
 			//		an object of coordinates
-			// 		example : {'x':10,'y':10}
+			//		example : {'x':10,'y':10}
 	
 			//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getDragPoint");
 			var y = coords.y;
@@ -200,7 +201,7 @@ define([
 		getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){
 			// summary:
 			//		get the nearest DnD area.
-			//		Coordinates are basically provided by the <getDragPoint> method.
+			//		Coordinates are basically provided by the ``getDragPoint`` method.
 			// areaList:
 			//		a list of DnD areas objects
 			// coords:
@@ -260,7 +261,7 @@ define([
 		_checkInterval: function(/*Array*/areaList, /*Integer*/index, /*Coord*/x){
 			// summary:
 			//		check if the dragNode is in the interval.
-			//		The x coordinate is basically provided by the <getDragPoint> method.
+			//		The x coordinate is basically provided by the ``getDragPoint`` method.
 			// areaList:
 			//		a list of DnD areas objects
 			// index:
@@ -268,7 +269,7 @@ define([
 			// x:
 			//		coordinate x, of the dragNode
 			// returns:
-			//		true if the dragNode is in intervall
+			//		true if the dragNode is in interval
 			// tags:
 			//		protected
 	
@@ -300,7 +301,7 @@ define([
 			// coords:
 			//		coordinates [x,y] of the draggable item
 			// returns:
-			// 		a number
+			//		a number
 			//		or -1 if the area has no children or the drop index represents the last position in to the area
 	
 			//console.log("dojox.mdnd.dropMode.DefaultDropMode ::: getDropIndex");
diff --git a/dojox/mdnd/dropMode/OverDropMode.js b/dojox/mdnd/dropMode/OverDropMode.js
index fabdac6..5fc099a 100644
--- a/dojox/mdnd/dropMode/OverDropMode.js
+++ b/dojox/mdnd/dropMode/OverDropMode.js
@@ -1,6 +1,11 @@
-define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_base/html",
-	"dojo/_base/array","dojox/mdnd/AreaManager"],function(dojo){
-	var odm = dojo.declare(
+define(["dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dojo/_base/array",
+	"dojo/dom-geometry",
+	"dojox/mdnd/AreaManager"
+],function(dojo, declare, connect, array, geom){
+	var odm = declare(
 		"dojox.mdnd.dropMode.OverDropMode",
 		null,
 	{
@@ -22,7 +27,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 		constructor: function(){
 			//console.log("dojox.mdnd.dropMode.OverDropMode ::: constructor");
 			this._dragHandler = [
-				dojo.connect(dojox.mdnd.areaManager(), "onDragEnter", function(coords, size){
+				connect.connect(dojox.mdnd.areaManager(), "onDragEnter", function(coords, size){
 					var m = dojox.mdnd.areaManager();
 					if(m._oldIndexArea == -1){
 						m._oldIndexArea = m._lastValidIndexArea;
@@ -44,7 +49,7 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 	
 			//console.log("dojox.mdnd.dropMode.OverDropMode ::: addArea");
 			var length = areas.length,
-				position = dojo.position(object.node, true);
+				position = geom.position(object.node, true);
 			object.coords = {'x':position.x, 'y':position.y};
 			if(length == 0){
 				areas.push(object);
@@ -85,12 +90,12 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			// summary:
 			//		update the D&D area object (i.e. update coordinates of its DOM node)
 			// area:
-			// 		the D&D area.
+			//		the D&D area.
 			// tags:
 			//		protected
 	
 			//console.log("dojox.mdnd.dropMode.OverDropMode ::: addArea");
-			var position = dojo.position(area.node, true);
+			var position = geom.position(area.node, true);
 			area.coords.x = position.x;
 			area.coords.x2 = position.x + position.w;
 			area.coords.y = position.y;
@@ -103,10 +108,10 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			//		the D&D area.
 	
 			//console.log("dojox.mdnd.dropMode.OverDropMode ::: initItems");
-			dojo.forEach(area.items, function(obj){
+			array.forEach(area.items, function(obj){
 				//get the vertical middle of the item
 				var node = obj.item.node;
-				var position = dojo.position(node, true);
+				var position = geom.position(node, true);
 				var y = position.y + position.h/2;
 				obj.y = y;
 			});
@@ -150,17 +155,18 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 		getDragPoint: function(/*Object*/coords, /*Object*/size, /*Object*/mousePosition){
 			// summary:
 			//		return coordinates of the draggable item.
+			//
 			//		- For X point : the x position of mouse
 			//		- For Y point : the y position of mouse
 			// returns:
 			//		an object of coordinates
-			// 		examples:{'x':10,'y':10}
+			//		examples:{'x':10,'y':10}
 			// coords:
 			//		an object encapsulating X and Y position
 			// size:
-			// 		an object encapsulating width and height values
+			//		an object encapsulating width and height values
 			// mousePosition:
-			// 		coordinates of mouse
+			//		coordinates of mouse
 	
 			//console.log("dojox.mdnd.OverDropMode ::: getDragPoint");
 			return {			// Object
@@ -174,12 +180,12 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 			// summary:
 			//		get the nearest D&D area.
 			// areaList:
-			// 		a list of D&D areas objects
+			//		a list of D&D areas objects
 			// coords:
 			//		coordinates [x,y] of the dragItem (see getDragPoint())
 			// currentIndexArea:
 			//		an index representing the active D&D area
-			//returns:
+			// returns:
 			//		the index of the D&D area
 	
 			//console.log("dojox.mdnd.dropMode.OverDropMode ::: getTargetArea");
@@ -297,10 +303,10 @@ define(["dojo/_base/kernel","dojo/_base/declare","dojo/_base/connect","dojo/_bas
 		},
 	
 		destroy: function(){
-			dojo.forEach(this._dragHandler, dojo.disconnect);
+			array.forEach(this._dragHandler, connect.disconnect);
 		}
 	});
 	
 	dojox.mdnd.areaManager()._dropMode = new dojox.mdnd.dropMode.OverDropMode();
 	return odm;
-});
\ No newline at end of file
+});
diff --git a/dojox/mdnd/dropMode/VerticalDropMode.js b/dojox/mdnd/dropMode/VerticalDropMode.js
index 612c640..7a17593 100644
--- a/dojox/mdnd/dropMode/VerticalDropMode.js
+++ b/dojox/mdnd/dropMode/VerticalDropMode.js
@@ -1,11 +1,11 @@
 define([
 	"dojo/_base/kernel",
 	"dojo/_base/declare",
-	"dojo/_base/html",
 	"dojo/_base/array",
+	"dojo/dom-geometry",
 	"dojox/mdnd/AreaManager"
-],function(dojo){
-	var vdm = dojo.declare(
+],function(dojo, declare, array, geom){
+	var vdm = declare(
 		"dojox.mdnd.dropMode.VerticalDropMode",
 		null,
 	{
@@ -22,7 +22,7 @@ define([
 		_oldYPoint: null,
 	
 		// _oldBehaviour: String
-		// 		see <getDragPoint>
+		//		see `getDragPoint`
 		_oldBehaviour: "up",
 	
 		addArea: function(/*Array*/areas, /*Object*/object){
@@ -37,7 +37,7 @@ define([
 	
 			//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: addArea");
 			var length = areas.length;
-			var position = dojo.position(object.node, true);
+			var position = geom.position(object.node, true);
 			object.coords = {'x':position.x, 'y':position.y};
 			if(length == 0){
 				areas.push(object);
@@ -111,7 +111,7 @@ define([
 			//		protected
 	
 			//console.log("dojox.mdnd.dropMode.VerticalDropMode  ::: _updateArea");
-			var position = dojo.position(area.node, true);
+			var position = geom.position(area.node, true);
 			area.coords.x = position.x;
 			area.coords.y = position.y;
 		},
@@ -123,10 +123,10 @@ define([
 			//		the DnD area
 	
 			//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: initItems");
-			dojo.forEach(area.items, function(obj){
+			array.forEach(area.items, function(obj){
 				//get the vertical middle of the item
 				var node = obj.item.node;
-				var position = dojo.position(node, true);
+				var position = geom.position(node, true);
 				var y = position.y + position.h/2;
 				obj.y = y;
 			});
@@ -139,7 +139,7 @@ define([
 			// area:
 			//		a DnD area object
 			// indexItem:
-			// 		index of a draggable item
+			//		index of a draggable item
 			// size:
 			//		dropIndicator size
 			// added:
@@ -172,10 +172,11 @@ define([
 			//		return coordinates of the draggable item
 			// description:
 			//		return for:
-			// 			- X point : the middle
-			//	  		- Y point : search if the user goes up or goes down with his mouse.
-			//	  		- Up : top of the draggable item
-			//	  		- Down : bottom of the draggable item
+			//
+			//		- X point : the middle
+			//	  	- Y point : search if the user goes up or goes down with his mouse.
+			//	  	- Up : top of the draggable item
+			//	  	- Down : bottom of the draggable item
 			// coords:
 			//		an object encapsulating X and Y position
 			// size:
@@ -184,7 +185,7 @@ define([
 			//		coordinates of mouse
 			// returns:
 			//		an object of coordinates
-			// 		example : {'x':10,'y':10}
+			//		example : {'x':10,'y':10}
 	
 			//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: getDragPoint");
 			var y = coords.y;
@@ -208,7 +209,7 @@ define([
 		getTargetArea: function(/*Array*/areaList, /*Object*/ coords, /*integer*/currentIndexArea ){
 			// summary:
 			//		get the nearest DnD area.
-			//		Coordinates are basically provided by the <getDragPoint> method.
+			//		Coordinates are basically provided by the ``getDragPoint`` method.
 			// areaList:
 			//		a list of DnD areas objects
 			// coords:
@@ -271,7 +272,7 @@ define([
 		_checkInterval: function(/*Array*/areaList, /*Integer*/index, /*Coord*/x){
 			// summary:
 			//		check if the dragNode is in the interval.
-			//		The x coordinate is basically provided by the <getDragPoint> method.
+			//		The x coordinate is basically provided by the ``getDragPoint`` method.
 			// areaList:
 			//		a list of DnD areas objects
 			// index:
@@ -310,7 +311,7 @@ define([
 			// coords:
 			//		coordinates [x,y] of the draggable item
 			// returns:
-			// 		a number
+			//		a number
 			//		or -1 if the area has no children or the drop index represents the last position in to the area
 	
 			//console.log("dojox.mdnd.dropMode.VerticalDropMode ::: getDropIndex");
diff --git a/dojox/mdnd/resources/dnd.css b/dojox/mdnd/resources/dnd.css
index f7f0469..dbed021 100644
--- a/dojox/mdnd/resources/dnd.css
+++ b/dojox/mdnd/resources/dnd.css
@@ -85,7 +85,10 @@
 }
 
 .dj_ie6 .orange .dndCover, .dj_ie7 .orange .dndCover{
+/*
+    the following url does not exist; commented out to quiet build errors; tracked at #15695
 	background-image:url(../../images/oaf/pixel.gif);
+*/
 }
 
 .orange .dndCover2{
diff --git a/dojox/mdnd/tests/functionalTests/test_dnd_acceptance.html b/dojox/mdnd/tests/functionalTests/test_dnd_acceptance.html
index b93a0da..243b357 100644
--- a/dojox/mdnd/tests/functionalTests/test_dnd_acceptance.html
+++ b/dojox/mdnd/tests/functionalTests/test_dnd_acceptance.html
@@ -13,9 +13,10 @@
 		<link rel="stylesheet" type="text/css" href="../resources/test_dnd.css" />
 		
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="parseOnLoad:true, isDebug:false"></script>
+			data-dojo-config="parseOnLoad:true, isDebug:false"></script>
 	
 		<script type="text/javascript">
+			dojo.require("dojo.parser");
 			dojo.require("dojox.mdnd.AreaManager");
 			dojo.require("dojox.mdnd.DropIndicator");
 			dojo.require("dojox.mdnd.dropMode.VerticalDropMode");
diff --git a/dojox/mdnd/tests/functionalTests/test_dnd_autoScroll.html b/dojox/mdnd/tests/functionalTests/test_dnd_autoScroll.html
index 520337b..042390c 100644
--- a/dojox/mdnd/tests/functionalTests/test_dnd_autoScroll.html
+++ b/dojox/mdnd/tests/functionalTests/test_dnd_autoScroll.html
@@ -31,7 +31,7 @@
 		}
 	</style>
 
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	
 	<script type="text/javascript">
 		dojo.require("dojox.mdnd.AutoScroll");
diff --git a/dojox/mdnd/tests/functionalTests/test_dnd_defaultDropMode.html b/dojox/mdnd/tests/functionalTests/test_dnd_defaultDropMode.html
index 9961e9b..ed3f14c 100644
--- a/dojox/mdnd/tests/functionalTests/test_dnd_defaultDropMode.html
+++ b/dojox/mdnd/tests/functionalTests/test_dnd_defaultDropMode.html
@@ -13,7 +13,7 @@
 		<link rel="stylesheet" type="text/css" href="../resources/test_dnd.css" />
 		
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="parseOnLoad:true, isDebug:false"></script>
+			data-dojo-config="parseOnLoad:true, isDebug:false"></script>
 	
 		<script type="text/javascript">
 			dojo.require("dojox.mdnd.AreaManager");
diff --git a/dojox/mdnd/tests/functionalTests/test_dnd_dndFromDojo.html b/dojox/mdnd/tests/functionalTests/test_dnd_dndFromDojo.html
index 1e9b8be..6ff337d 100644
--- a/dojox/mdnd/tests/functionalTests/test_dnd_dndFromDojo.html
+++ b/dojox/mdnd/tests/functionalTests/test_dnd_dndFromDojo.html
@@ -13,7 +13,7 @@
 		<link rel="stylesheet" type="text/css" href="../resources/test_dnd.css" />
 		
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="parseOnLoad:true, isDebug:true"></script>
+			data-dojo-config="parseOnLoad:true, isDebug:true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojox.mdnd.AreaManager");
diff --git a/dojox/mdnd/tests/functionalTests/test_dnd_dndToDojo.html b/dojox/mdnd/tests/functionalTests/test_dnd_dndToDojo.html
index 477dc0e..8183b3c 100644
--- a/dojox/mdnd/tests/functionalTests/test_dnd_dndToDojo.html
+++ b/dojox/mdnd/tests/functionalTests/test_dnd_dndToDojo.html
@@ -13,7 +13,7 @@
 		<link rel="stylesheet" type="text/css" href="../resources/test_dnd.css" />
 		
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="parseOnLoad:true, isDebug:true"></script>
+			data-dojo-config="parseOnLoad:true, isDebug:true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojox.mdnd.AreaManager");
@@ -35,6 +35,7 @@
 				// --------------------------------------------------------------
 				// Rewrite isAccepted method (only for registered dom);
 				adapter.isAccepted = function(draggedNode, target){
+					console.log("isAccepted", target);
 					if(target.type == "domTarget"){
 						var dndType = dojo.attr(draggedNode, "dndType");
 						return (dndType == "type2") ? true : false;
diff --git a/dojox/mdnd/tests/functionalTests/test_dnd_dndToDojo_dndFromDojo.html b/dojox/mdnd/tests/functionalTests/test_dnd_dndToDojo_dndFromDojo.html
index 07d7c09..f394689 100644
--- a/dojox/mdnd/tests/functionalTests/test_dnd_dndToDojo_dndFromDojo.html
+++ b/dojox/mdnd/tests/functionalTests/test_dnd_dndToDojo_dndFromDojo.html
@@ -13,7 +13,7 @@
 		<link rel="stylesheet" type="text/css" href="../resources/test_dnd.css" />
 		
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="parseOnLoad:true, isDebug:true"></script>
+			data-dojo-config="parseOnLoad:true, isDebug:true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dojox.mdnd.AreaManager");
diff --git a/dojox/mdnd/tests/functionalTests/test_dnd_overDropMode.html b/dojox/mdnd/tests/functionalTests/test_dnd_overDropMode.html
index 62163ae..d34c827 100644
--- a/dojox/mdnd/tests/functionalTests/test_dnd_overDropMode.html
+++ b/dojox/mdnd/tests/functionalTests/test_dnd_overDropMode.html
@@ -13,7 +13,7 @@
 		<link rel="stylesheet" type="text/css" href="../resources/test_dnd.css" />
 
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="parseOnLoad:true, isDebug:false"></script>
+			data-dojo-config="parseOnLoad:true, isDebug:false"></script>
 	
 		<script type="text/javascript">
 			dojo.require("dojox.mdnd.AreaManager");
diff --git a/dojox/mdnd/tests/functionalTests/test_dnd_stress.html b/dojox/mdnd/tests/functionalTests/test_dnd_stress.html
index 7258258..e1ec154 100644
--- a/dojox/mdnd/tests/functionalTests/test_dnd_stress.html
+++ b/dojox/mdnd/tests/functionalTests/test_dnd_stress.html
@@ -13,7 +13,7 @@
 		<link rel="stylesheet" type="text/css" href="../resources/test_dnd.css" />
 
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="parseOnLoad:true, isDebug:false"></script>
+			data-dojo-config="parseOnLoad:true, isDebug:false"></script>
 	
 		<script type="text/javascript">
 			dojo.require("dojox.mdnd.AreaManager");
diff --git a/dojox/mdnd/tests/functionalTests/test_dnd_verticalDropMode.html b/dojox/mdnd/tests/functionalTests/test_dnd_verticalDropMode.html
index dba6495..e5f9372 100644
--- a/dojox/mdnd/tests/functionalTests/test_dnd_verticalDropMode.html
+++ b/dojox/mdnd/tests/functionalTests/test_dnd_verticalDropMode.html
@@ -13,7 +13,7 @@
 		<link rel="stylesheet" type="text/css" href="../resources/test_dnd.css" />
 		
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="parseOnLoad:true, isDebug:false"></script>
+			data-dojo-config="parseOnLoad:true, isDebug:false"></script>
 	
 		<script type="text/javascript">
 			dojo.require("dojox.mdnd.AreaManager");
diff --git a/dojox/mdnd/tests/robot/test_dnd_acceptance.html b/dojox/mdnd/tests/robot/test_dnd_acceptance.html
index 1f48b5d..ccdebfb 100644
--- a/dojox/mdnd/tests/robot/test_dnd_acceptance.html
+++ b/dojox/mdnd/tests/robot/test_dnd_acceptance.html
@@ -4,7 +4,7 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true">
+			data-dojo-config="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
diff --git a/dojox/mdnd/tests/robot/test_dnd_defaultDropMode.html b/dojox/mdnd/tests/robot/test_dnd_defaultDropMode.html
index 88460c3..343d219 100644
--- a/dojox/mdnd/tests/robot/test_dnd_defaultDropMode.html
+++ b/dojox/mdnd/tests/robot/test_dnd_defaultDropMode.html
@@ -4,7 +4,7 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true">
+			data-dojo-config="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
diff --git a/dojox/mdnd/tests/robot/test_dnd_dndFromDojo.html b/dojox/mdnd/tests/robot/test_dnd_dndFromDojo.html
index 04179a2..1fc17a9 100644
--- a/dojox/mdnd/tests/robot/test_dnd_dndFromDojo.html
+++ b/dojox/mdnd/tests/robot/test_dnd_dndFromDojo.html
@@ -4,7 +4,7 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true">
+			data-dojo-config="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
diff --git a/dojox/mdnd/tests/robot/test_dnd_dndToDojo.html b/dojox/mdnd/tests/robot/test_dnd_dndToDojo.html
index d52bf95..ebb3e5d 100644
--- a/dojox/mdnd/tests/robot/test_dnd_dndToDojo.html
+++ b/dojox/mdnd/tests/robot/test_dnd_dndToDojo.html
@@ -4,7 +4,7 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true">
+			data-dojo-config="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
diff --git a/dojox/mdnd/tests/robot/test_dnd_overDropMode.html b/dojox/mdnd/tests/robot/test_dnd_overDropMode.html
index ad08492..23a3b45 100644
--- a/dojox/mdnd/tests/robot/test_dnd_overDropMode.html
+++ b/dojox/mdnd/tests/robot/test_dnd_overDropMode.html
@@ -4,13 +4,13 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true">
+			data-dojo-config="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");	
 			
-			dojo.addOnLoad(function(){			
+			dojo.addOnLoad(function(){
 				
 				doh.robot.initRobot('../functionalTests/test_dnd_overDropMode.html');
 				
diff --git a/dojox/mdnd/tests/robot/test_dnd_verticalDropMode.html b/dojox/mdnd/tests/robot/test_dnd_verticalDropMode.html
index 7877e91..1d1ed19 100644
--- a/dojox/mdnd/tests/robot/test_dnd_verticalDropMode.html
+++ b/dojox/mdnd/tests/robot/test_dnd_verticalDropMode.html
@@ -4,7 +4,7 @@
 		
 		<script type="text/javascript" 
 			src="../../../../dojo/dojo.js" 
-			djConfig="isDebug: true">
+			data-dojo-config="isDebug: true">
 		</script>
 		
 		<script type="text/javascript">
diff --git a/dojox/mdnd/tests/unitTests/areaManager/AreaManagerCoverPresence.html b/dojox/mdnd/tests/unitTests/areaManager/AreaManagerCoverPresence.html
index 72a945e..49b080d 100644
--- a/dojox/mdnd/tests/unitTests/areaManager/AreaManagerCoverPresence.html
+++ b/dojox/mdnd/tests/unitTests/areaManager/AreaManagerCoverPresence.html
@@ -35,7 +35,7 @@
 			}
 	
 	</style>
-	<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	
 	
 	<script type="text/javascript">
diff --git a/dojox/mdnd/tests/unitTests/areaManager/AreaManagerManagingDragItems.html b/dojox/mdnd/tests/unitTests/areaManager/AreaManagerManagingDragItems.html
index 132e469..e7868f6 100644
--- a/dojox/mdnd/tests/unitTests/areaManager/AreaManagerManagingDragItems.html
+++ b/dojox/mdnd/tests/unitTests/areaManager/AreaManagerManagingDragItems.html
@@ -4,7 +4,7 @@
 <head>
 
 	<title>AreaManager</title>
-	<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	
 	<link rel="stylesheet" type="text/css" href="../../../../../dojo/resources/dojo.css" />
 	<link rel="stylesheet" type="text/css" href="../../../../../dijit/themes/tundra/tundra.css" />
diff --git a/dojox/mdnd/tests/unitTests/areaManager/AreaManagerRegistering.html b/dojox/mdnd/tests/unitTests/areaManager/AreaManagerRegistering.html
index 8de1242..ff42049 100644
--- a/dojox/mdnd/tests/unitTests/areaManager/AreaManagerRegistering.html
+++ b/dojox/mdnd/tests/unitTests/areaManager/AreaManagerRegistering.html
@@ -4,7 +4,7 @@
 <head>
 
 	<title>AreaManager</title>
-	<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("doh.runner");		
diff --git a/dojox/mdnd/tests/unitTests/dropIndicator/DropIndicatorTest.html b/dojox/mdnd/tests/unitTests/dropIndicator/DropIndicatorTest.html
index 9f5feb7..7af72bf 100644
--- a/dojox/mdnd/tests/unitTests/dropIndicator/DropIndicatorTest.html
+++ b/dojox/mdnd/tests/unitTests/dropIndicator/DropIndicatorTest.html
@@ -5,7 +5,7 @@
 
 	<title>Drop Indicator place test</title>
 	
-	<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	
 	<script type="text/javascript">
 
diff --git a/dojox/mdnd/tests/unitTests/dropMode/DefaultDropModeTest.html b/dojox/mdnd/tests/unitTests/dropMode/DefaultDropModeTest.html
index 551824a..e290d88 100644
--- a/dojox/mdnd/tests/unitTests/dropMode/DefaultDropModeTest.html
+++ b/dojox/mdnd/tests/unitTests/dropMode/DefaultDropModeTest.html
@@ -7,7 +7,7 @@
 	
 	<script type="text/javascript" 
 		src="../../../../../dojo/dojo.js" 
-		djConfig="isDebug: true, parseOnLoad: true">
+		data-dojo-config="isDebug: true, parseOnLoad: true">
 	</script>
 	
 	<script type="text/javascript">
diff --git a/dojox/mdnd/tests/unitTests/dropMode/OverDropModeTest.html b/dojox/mdnd/tests/unitTests/dropMode/OverDropModeTest.html
index 17dbea0..bc9ec74 100644
--- a/dojox/mdnd/tests/unitTests/dropMode/OverDropModeTest.html
+++ b/dojox/mdnd/tests/unitTests/dropMode/OverDropModeTest.html
@@ -7,7 +7,7 @@
 	
 	<script type="text/javascript" 
 		src="../../../../../dojo/dojo.js" 
-		djConfig="isDebug: true, parseOnLoad: true">
+		data-dojo-config="isDebug: true, parseOnLoad: true">
 	</script>
 	
 	<script type="text/javascript">
diff --git a/dojox/mdnd/tests/unitTests/dropMode/VerticalDropModeTest.html b/dojox/mdnd/tests/unitTests/dropMode/VerticalDropModeTest.html
index e1dbf9b..b7c9e24 100644
--- a/dojox/mdnd/tests/unitTests/dropMode/VerticalDropModeTest.html
+++ b/dojox/mdnd/tests/unitTests/dropMode/VerticalDropModeTest.html
@@ -7,7 +7,7 @@
 	
 	<script type="text/javascript" 
 		src="../../../../../dojo/dojo.js" 
-		djConfig="isDebug: true, parseOnLoad: true">
+		data-dojo-config="isDebug: true, parseOnLoad: true">
 	</script>
 	
 	<script type="text/javascript">
diff --git a/dojox/mobile.js b/dojox/mobile.js
index 63cf910..e1fb047 100755
--- a/dojox/mobile.js
+++ b/dojox/mobile.js
@@ -4,5 +4,12 @@ define([
 	"dojox/mobile/_base"
 ], function(dojox, lang, base){
 	lang.getObject("mobile", true, dojox);
+	/*=====
+	return {
+		// summary:
+		//		Deprecated.  Should require dojox/mobile classes directly rather than trying to access them through
+		//		this module.
+	};
+	=====*/
 	return dojox.mobile;
 });
diff --git a/dojox/mobile/Accordion.js b/dojox/mobile/Accordion.js
new file mode 100644
index 0000000..8359089
--- /dev/null
+++ b/dojox/mobile/Accordion.js
@@ -0,0 +1,507 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/sniff",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-attr",
+	"dijit/_Contained",
+	"dijit/_Container",
+	"dijit/_WidgetBase",
+	"./iconUtils",
+	"./lazyLoadUtils",
+	"./_css3",
+	"require",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/Accordion"
+], function(array, declare, lang, has, dom, domClass, domConstruct, domAttr, Contained, Container, WidgetBase, iconUtils, lazyLoadUtils, css3, require, BidiAccordion){
+
+	// module:
+	//		dojox/mobile/Accordion
+
+	// inner class
+	var _AccordionTitle = declare([WidgetBase, Contained], {
+		// summary:
+		//		A widget for the title of the accordion.
+	
+		// label: String
+		//		The title of the accordion.
+		label: "Label",
+		
+		// icon1: String
+		//		A path for the unselected (typically dark) icon. If icon is not
+		//		specified, the iconBase parameter of the parent widget is used.
+		icon1: "",
+
+		// icon2: String
+		//		A path for the selected (typically highlight) icon. If icon is
+		//		not specified, the iconBase parameter of the parent widget or
+		//		icon1 is used.
+		icon2: "",
+
+		// iconPos1: String
+		//		The position of an aggregated unselected (typically dark)
+		//		icon. IconPos1 is a comma-separated list of values like
+		//		top,left,width,height (ex. "0,0,29,29"). If iconPos1 is not
+		//		specified, the iconPos parameter of the parent widget is used.
+		iconPos1: "",
+
+		// iconPos2: String
+		//		The position of an aggregated selected (typically highlight)
+		//		icon. IconPos2 is a comma-separated list of values like
+		//		top,left,width,height (ex. "0,0,29,29"). If iconPos2 is not
+		//		specified, the iconPos parameter of the parent widget or
+		//		iconPos1 is used.
+		iconPos2: "",
+
+		// selected: Boolean
+		//		If true, the widget is in the selected state.
+		selected: false,
+
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblAccordionTitle",
+
+		buildRendering: function(){
+			this.inherited(arguments);
+
+			var a = this.anchorNode = domConstruct.create("a", {
+				className: "mblAccordionTitleAnchor",
+				role: "presentation"
+			}, this.domNode);
+
+			// text box
+			this.textBoxNode = domConstruct.create("div", {className:"mblAccordionTitleTextBox"}, a);
+			this.labelNode = domConstruct.create("span", {
+				className: "mblAccordionTitleLabel",
+				innerHTML: this._cv ? this._cv(this.label) : this.label
+			}, this.textBoxNode);
+			this._isOnLine = this.inheritParams();
+
+			domAttr.set(this.textBoxNode, "role", "tab"); // A11Y
+			domAttr.set(this.textBoxNode, "tabindex", "0");
+		},
+
+		postCreate: function(){
+			this.connect(this.domNode, "onclick", "_onClick");
+			dom.setSelectable(this.domNode, false);
+		},
+
+		inheritParams: function(){
+			var parent = this.getParent();
+			if(parent){
+				if(this.icon1 && parent.iconBase &&
+					parent.iconBase.charAt(parent.iconBase.length - 1) === '/'){
+					this.icon1 = parent.iconBase + this.icon1;
+				}
+				if(!this.icon1){ this.icon1 = parent.iconBase; }
+				if(!this.iconPos1){ this.iconPos1 = parent.iconPos; }
+				if(this.icon2 && parent.iconBase &&
+					parent.iconBase.charAt(parent.iconBase.length - 1) === '/'){
+					this.icon2 = parent.iconBase + this.icon2;
+				}
+				if(!this.icon2){ this.icon2 = parent.iconBase || this.icon1; }
+				if(!this.iconPos2){ this.iconPos2 = parent.iconPos || this.iconPos1; }
+			}
+			return !!parent;
+		},
+
+		_setIcon: function(icon, n){
+			// tags:
+			//		private
+			if(!this.getParent()){ return; } // icon may be invalid because inheritParams is not called yet
+			this._set("icon" + n, icon);
+			if(!this["iconParentNode" + n]){
+				this["iconParentNode" + n] = domConstruct.create("div",
+					{className:"mblAccordionIconParent mblAccordionIconParent" + n}, this.anchorNode, "first");
+			}
+			this["iconNode" + n] = iconUtils.setIcon(icon, this["iconPos" + n],
+				this["iconNode" + n], this.alt, this["iconParentNode" + n]);
+			this["icon" + n] = icon;
+			domClass.toggle(this.domNode, "mblAccordionHasIcon", icon && icon !== "none");
+		},
+
+		_setIcon1Attr: function(icon){
+			// tags:
+			//		private
+			this._setIcon(icon, 1);
+		},
+
+		_setIcon2Attr: function(icon){
+			// tags:
+			//		private
+			this._setIcon(icon, 2);
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			if(!this._isOnLine){
+				this.inheritParams();
+			}
+			if(!this._isOnLine){
+				this.set({ // retry applying the attribute
+					icon1: this.icon1,
+					icon2: this.icon2
+				});
+			}
+			this.inherited(arguments);
+		},
+
+		_onClick: function(e){
+			// summary:
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(this.onClick(e) === false){ return; } // user's click action
+			var p = this.getParent();
+			if(!p.fixedHeight && this.contentWidget.domNode.style.display !== "none"){
+				p.collapse(this.contentWidget, !p.animation);
+			}else{
+				p.expand(this.contentWidget, !p.animation);
+			}
+		},
+
+		onClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User-defined function to handle clicks
+			// tags:
+			//		callback
+		},
+
+		_setSelectedAttr: function(/*Boolean*/selected){
+			// tags:
+			//		private
+			domClass.toggle(this.domNode, "mblAccordionTitleSelected", selected);
+			this._set("selected", selected);
+		}
+	});
+
+	var Accordion = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiAccordion" : "dojox.mobile.Accordion", [WidgetBase, Container, Contained], {
+		// summary:
+		//		A container widget that can display a group of child panes in a stacked format.
+		// description:
+		//		Typically, dojox/mobile/Pane, dojox/mobile/Container, or dojox/mobile/ContentPane are 
+		//		used as child widgets, but Accordion requires no specific child widget. 
+		//		Accordion supports three modes for opening child panes: multiselect, fixed-height,
+		//		and single-select. Accordion can have rounded corners, and it can lazy-load the 
+		//		content modules.
+
+		// iconBase: String
+		//		The default icon path for child widgets.
+		iconBase: "",
+
+		// iconPos: String
+		//		The default icon position for child widgets.
+		iconPos: "",
+
+		// fixedHeight: Boolean
+		//		If true, the entire accordion widget has fixed height regardless
+		//		of the height of each pane; in this mode, there is always an open pane and
+		//		collapsing a pane can only be done by opening a different pane.
+		fixedHeight: false,
+
+		// singleOpen: Boolean
+		//		If true, only one pane is open at a time. The current open pane
+		//		is collapsed, when another pane is opened.
+		singleOpen: false,
+
+		// animation: Boolean
+		//		If true, animation is used when a pane is opened or
+		//		collapsed. The animation works only on webkit browsers.
+		animation: true,
+
+		// roundRect: Boolean
+		//		If true, the widget shows rounded corners.
+		//		Adding the "mblAccordionRoundRect" class to domNode has the same effect.
+		roundRect: false,
+
+		/* internal properties */
+		duration: .3, // [seconds]
+
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblAccordion",
+
+		// _openSpace: [private] Number|String 
+		_openSpace: 1,
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			domAttr.set(this.domNode, "role", "tablist"); // A11Y
+			domAttr.set(this.domNode, "aria-multiselectable", !this.singleOpen); // A11Y
+		},
+		
+		startup: function(){
+			if(this._started){ return; }
+
+			if(domClass.contains(this.domNode, "mblAccordionRoundRect")){
+				this.roundRect = true;
+			}else if(this.roundRect){
+				domClass.add(this.domNode, "mblAccordionRoundRect");
+			}
+
+			if(this.fixedHeight){
+				this.singleOpen = true;
+			}
+			var children = this.getChildren();
+			array.forEach(children, this._setupChild, this);
+			var sel;
+			var posinset = 1;
+			array.forEach(children, function(child){
+				child.startup();
+				child._at.startup();
+				this.collapse(child, true);
+				domAttr.set(child._at.textBoxNode, "aria-setsize", children.length);
+				domAttr.set(child._at.textBoxNode, "aria-posinset", posinset++);
+				if(child.selected){
+					sel = child;
+				}
+			}, this);
+			if(!sel && this.fixedHeight){
+				sel = children[children.length - 1];
+			}
+			if(sel){
+				this.expand(sel, true);
+			}else{
+				this._updateLast();
+			}
+			this.defer(function(){ this.resize(); });
+
+			this._started = true;
+		},
+
+		_setupChild: function(/*Widget*/ child){
+			// tags:
+			//		private
+			if(child.domNode.style.overflow != "hidden"){
+				child.domNode.style.overflow = this.fixedHeight ? "auto" : "hidden";
+			}
+			child._at = new _AccordionTitle({
+				label: child.label,
+				alt: child.alt,
+				icon1: child.icon1,
+				icon2: child.icon2,
+				iconPos1: child.iconPos1,
+				iconPos2: child.iconPos2,
+				contentWidget: child
+			});
+			domConstruct.place(child._at.domNode, child.domNode, "before");
+			domClass.add(child.domNode, "mblAccordionPane");
+			domAttr.set(child._at.textBoxNode, "aria-controls", child.domNode.id); // A11Y
+			domAttr.set(child.domNode, "role", "tabpanel"); // A11Y
+			domAttr.set(child.domNode, "aria-labelledby", child._at.id); // A11Y
+		},
+
+		addChild: function(/*Widget*/ widget, /*int?*/ insertIndex){
+			this.inherited(arguments);
+			if(this._started){
+				this._setupChild(widget);
+				widget._at.startup();
+				if(widget.selected){
+					this.expand(widget, true);
+					this.defer(function(){
+						widget.domNode.style.height = "";
+					});
+				}else{
+					this.collapse(widget);
+				}
+			}
+			this._addChildAriaAttrs();
+		},
+
+		removeChild: function(/*Widget|int*/ widget){
+			if(typeof widget == "number"){
+				widget = this.getChildren()[widget];
+			}
+			if(widget){
+				widget._at.destroy();
+			}
+			this.inherited(arguments);
+			this._addChildAriaAttrs();
+		},
+		
+		_addChildAriaAttrs: function(){
+			var posinset = 1;
+			var children = this.getChildren();
+			array.forEach(children, function(child){
+				domAttr.set(child._at.textBoxNode, "aria-posinset", posinset++);
+				domAttr.set(child._at.textBoxNode, "aria-setsize", children.length);
+			});
+		},
+
+		getChildren: function(){
+			return array.filter(this.inherited(arguments), function(child){
+				return !(child instanceof _AccordionTitle);
+			});
+		},
+
+		getSelectedPanes: function(){
+			return array.filter(this.getChildren(), function(pane){
+				return pane.domNode.style.display != "none";
+			});
+		},
+
+		resize: function(){
+			if(this.fixedHeight){
+				var panes = array.filter(this.getChildren(), function(child){ // active pages
+					return child._at.domNode.style.display != "none";
+				});
+				var openSpace = this.domNode.clientHeight; // height of all panes
+				array.forEach(panes, function(child){
+					openSpace -= child._at.domNode.offsetHeight;
+				});
+				this._openSpace = openSpace > 0 ? openSpace : 0;
+				var sel = this.getSelectedPanes()[0];
+				sel.domNode.style[css3.name("transition")] = "";
+				sel.domNode.style.height = this._openSpace + "px";
+			}
+		},
+
+		_updateLast: function(){
+			// tags:
+			//		private
+			var children = this.getChildren();
+			array.forEach(children, function(c, i){
+				// add "mblAccordionTitleLast" to the last, closed accordion title
+				domClass.toggle(c._at.domNode, "mblAccordionTitleLast",
+					i === children.length - 1 && !domClass.contains(c._at.domNode, "mblAccordionTitleSelected"))
+			}, this);
+		},
+
+		expand: function(/*Widget*/pane, /*boolean*/noAnimation){
+			// summary:
+			//		Expands the given pane to make it visible.
+			// pane:
+			//		A pane widget to expand.
+			// noAnimation:
+			//		If true, the pane expands immediately without animation effect.
+			if(pane.lazy){
+				lazyLoadUtils.instantiateLazyWidgets(pane.containerNode, pane.requires);
+				pane.lazy = false;
+			}
+			var children = this.getChildren();
+			array.forEach(children, function(c, i){
+				c.domNode.style[css3.name("transition")] = noAnimation ? "" : "height "+this.duration+"s linear";
+				if(c === pane){
+					c.domNode.style.display = "";
+					var h;
+					if(this.fixedHeight){
+						h = this._openSpace;
+					}else{
+						h = parseInt(c.height || c.domNode.getAttribute("height")); // ScrollableView may have the height property
+						if(!h){
+							c.domNode.style.height = "";
+							h = c.domNode.offsetHeight;
+							c.domNode.style.height = "0px";
+						}
+					}
+					this.defer(function(){ // necessary for webkitTransition to work
+						c.domNode.style.height = h + "px";
+					});
+					this.select(pane);
+				}else if(this.singleOpen){
+					this.collapse(c, noAnimation);
+				}
+			}, this);
+			this._updateLast();
+			domAttr.set(pane.domNode, "aria-expanded", "true"); // A11Y
+			domAttr.set(pane.domNode, "aria-hidden", "false"); // A11Y
+		},
+
+		collapse: function(/*Widget*/pane, /*boolean*/noAnimation){
+			// summary:
+			//		Collapses the given pane to close it.
+			// pane:
+			//		A pane widget to collapse.
+			// noAnimation:
+			//		If true, the pane collapses immediately without animation effect.
+			if(pane.domNode.style.display === "none"){ return; } // already collapsed
+			pane.domNode.style[css3.name("transition")] = noAnimation ? "" : "height "+this.duration+"s linear";
+			pane.domNode.style.height = "0px";
+			if(!has("css3-animations") || noAnimation){
+				pane.domNode.style.display = "none";
+				this._updateLast();
+			}else{
+				// Adding a webkitTransitionEnd handler to panes may cause conflict
+				// when the panes already have the one. (e.g. ScrollableView)
+				var _this = this;
+				_this.defer(function(){
+					pane.domNode.style.display = "none";
+					_this._updateLast();
+
+					// Need to call parent view's resize() especially when the Accordion is
+					// on a ScrollableView, the ScrollableView is scrolled to
+					// the bottom, and then expand any other pane while in the
+					// non-fixed singleOpen mode.
+					if(!_this.fixedHeight && _this.singleOpen){
+						for(var v = _this.getParent(); v; v = v.getParent()){
+							if(domClass.contains(v.domNode, "mblView")){
+								if(v && v.resize){ v.resize(); }
+								break;
+							}
+						}
+					}
+				}, this.duration*1000);
+			}
+			this.deselect(pane);
+			domAttr.set(pane.domNode, "aria-expanded", "false"); // A11Y
+			domAttr.set(pane.domNode, "aria-hidden", "true"); // A11Y
+		},
+
+		select: function(/*Widget*/pane){
+			// summary:
+			//		Highlights the title bar of the given pane.
+			// pane:
+			//		A pane widget to highlight.
+			pane._at.set("selected", true);
+			domAttr.set(pane._at.textBoxNode, "aria-selected", "true"); // A11Y
+		},
+
+		deselect: function(/*Widget*/pane){
+			// summary:
+			//		Unhighlights the title bar of the given pane.
+			// pane:
+			//		A pane widget to unhighlight.
+			pane._at.set("selected", false);
+			domAttr.set(pane._at.textBoxNode, "aria-selected", "false"); // A11Y
+		}
+	});
+	
+	Accordion.ChildWidgetProperties = {
+		// summary:
+		//		These properties can be specified for the children of a dojox/mobile/Accordion.
+
+		// alt: String
+		//		The alternate text of the Accordion title.
+		alt: "",
+		// label: String
+		//		The label of the Accordion title.
+		label: "",
+		// icon1: String
+		//		The unselected icon of the Accordion title.
+		icon1: "",
+		// icon2: String
+		//		The selected icon of the Accordion title.
+		icon2: "",
+		// iconPos1: String
+		//		The position ("top,left,width,height") of the unselected aggregated icon of the Accordion title.
+		iconPos1: "",
+		// iconPos2: String
+		//		The position ("top,left,width,height") of the selected aggregated icon of the Accordion title.
+		iconPos2: "",
+		// selected: Boolean
+		//		The selected state of the Accordion title.
+		selected: false,
+		// lazy: Boolean
+		//		Specifies that the Accordion child must be lazily loaded.
+		lazy: false
+	};
+
+	// Since any widget can be specified as an Accordion child, mix ChildWidgetProperties
+	// into the base widget class.  (This is a hack, but it's effective.)
+	// This is for the benefit of the parser.   Remove for 2.0.  Also, hide from doc viewer.
+	lang.extend(WidgetBase, /*===== {} || =====*/ Accordion.ChildWidgetProperties);
+
+	return has("dojo-bidi") ? declare("dojox.mobile.Accordion", [Accordion, BidiAccordion]) : Accordion;
+});
diff --git a/dojox/mobile/Audio.js b/dojox/mobile/Audio.js
new file mode 100644
index 0000000..995f124
--- /dev/null
+++ b/dojox/mobile/Audio.js
@@ -0,0 +1,109 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-construct",
+	"dojo/sniff",
+	"dijit/_Contained",
+	"dijit/_WidgetBase"
+], function(declare, domConstruct, has, Contained, WidgetBase){
+	// module:
+	//		dojox/mobile/Audio
+
+	return declare("dojox.mobile.Audio", [WidgetBase, Contained], {
+		// summary:
+		//		A thin wrapper around the HTML5 `<audio>` element.
+		// description:
+		//		dojox/mobile/Audio is a widget which plays audio. If all sources cannot 
+		//		be played (typically, in desktop browsers that do not support `<audio>`), 
+		//		dojox/mobile/Audio automatically replaces `<audio>` with `<embed>`, such 
+		//		that the browser tries to play it with a suitable plug-in.
+		
+		// source: [const] Array
+		//		An array of src and type,
+		//		ex. [{src:"a.mp3", type:"audio/mpeg"}, {src:"a.ogg", type:"audio/ogg"}, ...].
+		//		The src gives the path of the media resource. The type gives the
+		//		type of the media resource.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		source: null,
+
+		// width: [const] String
+		//		The width of the embed element. 
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		width: "200px",
+
+		// height: [const] String
+		//		The height of the embed element.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		height: "15px",
+
+		// _playable: [private] Boolean
+		//		Internal flag.
+		_playable: false,
+		
+		// _tag: [private] String
+		//		The name of the tag ("audio").
+		_tag: "audio",
+
+		constructor: function(){
+			// summary:
+			//		Creates a new instance of the class.
+			this.source = [];
+		},
+
+		buildRendering: function(){
+			this.domNode = this.srcNodeRef || domConstruct.create(this._tag);
+		},
+
+		_getEmbedRegExp: function(){
+			// tags:
+			//		private
+			return has('ff') ? /audio\/mpeg/i :
+				   has('ie') ? /audio\/wav/i :
+				   null;
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this.inherited(arguments);
+			var i;
+		 	if(this.domNode.canPlayType){
+				if(this.source.length > 0){
+					for(i = 0, len = this.source.length; i < len; i++){
+						domConstruct.create("source", {src:this.source[i].src, type:this.source[i].type}, this.domNode);
+						this._playable = this._playable || !!this.domNode.canPlayType(this.source[i].type);
+					}
+				}else{
+					for(i = 0, len = this.domNode.childNodes.length; i < len; i++){
+						var n = this.domNode.childNodes[i];
+						if(n.nodeType === 1 && n.nodeName === "SOURCE"){
+							this.source.push({src:n.src, type:n.type});
+							this._playable = this._playable || !!this.domNode.canPlayType(n.type);
+						}
+					}
+				}
+			}
+			has.add("mobile-embed-audio-video-support", true);	//It should move to staticHasFeatures
+		 	if(has("mobile-embed-audio-video-support")){
+				if(!this._playable){
+					for(i = 0, len = this.source.length, re = this._getEmbedRegExp(); i < len; i++){
+					 	if(this.source[i].type.match(re)){
+							var node = domConstruct.create("embed", {
+								src: this.source[0].src,
+								type: this.source[0].type,
+								width: this.width,
+								height: this.height
+							});
+							this.domNode.parentNode.replaceChild(node, this.domNode);
+							this.domNode = node;
+							this._playable = true;
+							break;
+						}
+					}
+				}
+			}
+		}
+
+	});
+});
diff --git a/dojox/mobile/Badge.js b/dojox/mobile/Badge.js
new file mode 100644
index 0000000..3d7914c
--- /dev/null
+++ b/dojox/mobile/Badge.js
@@ -0,0 +1,75 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"./iconUtils",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/Badge"
+], function(declare, lang, domClass, domConstruct, iconUtils, has, BidiBadge){
+	// module:
+	//		dojox/mobile/Badge
+
+	var Badge = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiBadge" : "dojox.mobile.Badge", null, {
+		// summary:
+		//		A utility class to create and update a badge node.
+		// description:
+		//		Badge is not a widget, but a simple utility class for creating and 
+		//		updating a badge node. A badge consists of a simple DOM button. 
+		//		It is intended to be used from other widgets such as dojox/mobile/IconItem 
+		//		or dojox/mobile/TabBarButton.
+
+		// value: [const] String
+		//		A text to show in a badge.
+		//		Note that changing the value of the property after the badge
+		//		creation has no effect.
+		value: "0",
+
+		// className: [const] String
+		//		A CSS class name of a DOM button.
+		className: "mblDomButtonRedBadge",
+
+		// fontSize: [const] Number
+		//		Font size in pixel. The other style attributes are determined by the DOM
+		//		button itself.
+		//		Note that changing the value of the property after the badge
+		//		creation has no effect.
+		fontSize: 16, // [px]
+
+		constructor: function(/*Object?*/params, /*DomNode?*/node){
+			// summary:
+			//		Creates a new instance of the class.
+			// params:
+			//		Contains properties to be set.
+			// node:
+			//		The DOM node. If none is specified, it is automatically created. 
+			if (params){
+				lang.mixin(this, params);
+			}
+			this.domNode = node ? node : domConstruct.create("div");
+			domClass.add(this.domNode, "mblBadge");
+			if(this.domNode.className.indexOf("mblDomButton") === -1){
+				domClass.add(this.domNode, this.className);
+			}
+			if(this.fontSize !== 16){
+				this.domNode.style.fontSize = this.fontSize + "px";
+			}
+			iconUtils.createDomButton(this.domNode);
+			this.setValue(this.value);
+		},
+
+		getValue: function(){
+			// summary:
+			//		Returns the text shown in the badge.
+			return this.domNode.firstChild.innerHTML || "";
+		},
+
+		setValue: function(/*String*/value){
+			// summary:
+			//		Set a label text to the badge.
+			this.domNode.firstChild.innerHTML = value;
+		}
+	});
+
+	return has("dojo-bidi") ? declare("dojox.mobile.Badge", [Badge, BidiBadge]) : Badge;
+});
diff --git a/dojox/mobile/Button.js b/dojox/mobile/Button.js
index 712b176..7b58b5c 100644
--- a/dojox/mobile/Button.js
+++ b/dojox/mobile/Button.js
@@ -5,51 +5,63 @@ define([
 	"dojo/dom-construct",
 	"dijit/_WidgetBase",
 	"dijit/form/_ButtonMixin",
-	"dijit/form/_FormWidgetMixin"
-],
-	function(array, declare, domClass, domConstruct, WidgetBase, ButtonMixin, FormWidgetMixin){
+	"dijit/form/_FormWidgetMixin",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/Button"
+	],
+	function(array, declare, domClass, domConstruct, WidgetBase, ButtonMixin, FormWidgetMixin, has, BidiButton){
 
-	/*=====
-		WidgetBase = dijit._WidgetBase;
-		FormWidgetMixin = dijit.form._FormWidgetMixin;
-		ButtonMixin = dijit.form._ButtonMixin;
-	=====*/
-	return declare("dojox.mobile.Button", [WidgetBase, FormWidgetMixin, ButtonMixin], {
+	var Button = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiButton" : "dojox.mobile.Button", [WidgetBase, FormWidgetMixin, ButtonMixin], {
 		// summary:
-		//	Non-templated BUTTON widget with a thin API wrapper for click events and setting the label
+		//		Non-templated BUTTON widget with a thin API wrapper for click 
+		//		events and for setting the label.
 		//
-		// description:
-		//              Buttons can display a label, an icon, or both.
-		//              A label should always be specified (through innerHTML) or the label
-		//              attribute.  It can be hidden via showLabel=false.
+		//		Buttons can display a label, an icon, or both.
+		//		A label should always be specified (through innerHTML) or the label
+		//		attribute.  It can be hidden via showLabel=false.
 		// example:
-		// |    <button dojoType="dijit.form.Button" onClick="...">Hello world</button>
+		//	|	<button data-dojo-type="dojox/mobile/Button" onClick="...">Hello world</button>
 
+		// baseClass: String
+		//		The name of the CSS class of this widget.
 		baseClass: "mblButton",
 
-		// Override automatic assigning type --> node, it causes exception on IE.
-		// Instead, type must be specified as this.type when the node is created, as part of the original DOM
+		// _setTypeAttr: [private] Function 
+		//		Overrides the automatic assignment of type to nodes, because it causes
+		//		exception on IE. Instead, the type must be specified as this.type
+		//		when the node is created, as part of the original DOM.
 		_setTypeAttr: null,
 
 		// duration: Number
-		//	duration of selection, milliseconds or -1 for no post-click CSS styling
+		//		The duration of selection, in milliseconds, or -1 for no post-click CSS styling.
 		duration: 1000,
 
+		/*=====
+		// label: String
+		//		The label of the button.
+		label: "",
+		=====*/
+		
 		_onClick: function(e){
+			// tags:
+			//		private
 			var ret = this.inherited(arguments);
 			if(ret && this.duration >= 0){ // if its not a button with a state, then emulate press styles
 				var button = this.focusNode || this.domNode;
 				var newStateClasses = (this.baseClass+' '+this["class"]).split(" ");
 				newStateClasses = array.map(newStateClasses, function(c){ return c+"Selected"; });
 				domClass.add(button, newStateClasses);
-				setTimeout(function(){
+				this.defer(function(){
 					domClass.remove(button, newStateClasses);
 				}, this.duration);
 			}
 			return ret;
 		},
 
-		isFocusable: function(){ return false; },
+		isFocusable: function(){ 
+			// Override of the method of dijit/_WidgetBase.
+			return false; 
+		},
 
 		buildRendering: function(){
 			if(!this.srcNodeRef){
@@ -70,8 +82,11 @@ define([
 		},
 
 		_setLabelAttr: function(/*String*/ content){
+			// tags:
+			//		private
 			this.inherited(arguments, [this._cv ? this._cv(content) : content]);
 		}
 	});
 
+	return has("dojo-bidi") ? declare("dojox.mobile.Button", [Button, BidiButton]) : Button;
 });
diff --git a/dojox/mobile/Carousel.js b/dojox/mobile/Carousel.js
index 90ef6cc..b212012 100644
--- a/dojox/mobile/Carousel.js
+++ b/dojox/mobile/Carousel.js
@@ -1,112 +1,127 @@
 define([
-	"dojo/_base/kernel",
 	"dojo/_base/array",
 	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/_base/event",
 	"dojo/_base/lang",
-	"dojo/_base/sniff",
+	"dojo/sniff",
 	"dojo/dom-class",
 	"dojo/dom-construct",
 	"dojo/dom-style",
+	"dijit/registry",
 	"dijit/_Contained",
 	"dijit/_Container",
 	"dijit/_WidgetBase",
+	"./lazyLoadUtils",
+	"./CarouselItem",
 	"./PageIndicator",
 	"./SwapView",
-	"require"
-], function(kernel, array, connect, declare, event, lang, has, domClass, domConstruct, domStyle, Contained, Container, WidgetBase, PageIndicator, SwapView, require){
-
-/*=====
-	var Contained = dijit._Contained;
-	var Container = dijit._Container;
-	var WidgetBase = dijit._WidgetBase;
-	var PageIndicator = dojox.mobile.PageIndicator;
-	var SwapView = dojox.mobile.SwapView;
-=====*/
+	"require",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/Carousel"
+], function(array, connect, declare, event, lang, has, domClass, domConstruct, domStyle, registry, Contained, Container, WidgetBase, lazyLoadUtils, CarouselItem, PageIndicator, SwapView, require, BidiCarousel){
 
 	// module:
 	//		dojox/mobile/Carousel
-	// summary:
-	//		A carousel widget that manages a list of images
-
-	kernel.experimental("dojox.mobile.Carousel");
 
-	return declare("dojox.mobile.Carousel", [WidgetBase, Container, Contained], {
+	var Carousel = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiCarousel" : "dojox.mobile.Carousel", [WidgetBase, Container, Contained], {
 		// summary:
-		//		A carousel widget that manages a list of images
+		//		A carousel widget that manages a list of images.
 		// description:
 		//		The carousel widget manages a list of images that can be
 		//		displayed horizontally, and allows the user to scroll through
 		//		the list and select a single item.
+		//
+		//		This widget itself has no data store support, but there are two
+		//		subclasses, dojox/mobile/DataCarousel and dojox/mobile/StoreCarousel,
+		//		available for generating the contents from a data store.
+		//		To feed data into a Carousel through a dojo/data, use DataCarousel.
+		//		To feed data into a Carousel through a dojo/store, use StoreCarousel.
+		//
+		//		The Carousel widget loads and instantiates its item contents in
+		//		a lazy manner. For example, if the number of visible items
+		//		(see the property numVisible) is 2, the widget creates 4 items, 2 for the
+		//		initial pane and 2 for the next page, at startup time. If you
+		//		swipe the page to open the second page, the widget creates 2 more
+		//		items for the third page. If the item to create is a dojo widget,
+		//		its module is dynamically loaded automatically before instantiation.
 
 		// numVisible: Number
 		//		The number of visible items.
-		numVisible: 3,
+		numVisible: 2,
+
+		// itemWidth: Number
+		//		The number of visible items (=numVisible) is determined by
+		//		(carousel_width / itemWidth).
+		//		If itemWidth is specified, numVisible is automatically calculated.
+		//		If resize() is called, numVisible is recalculated and the layout
+		//		is changed accordingly.
+		itemWidth: 0,
 
 		// title: String
 		//		A title of the carousel to be displayed on the title bar.
 		title: "",
 
-		// pageIndicator: Boolean
+		// pageIndicator: [const] Boolean
 		//		If true, a page indicator, a series of small dots that indicate
 		//		the current page, is displayed on the title bar.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
 		pageIndicator: true,
 
-		// navButton: Boolean
-		//		If true, navigation buttons are displyaed on the title bar.
+		// navButton: [const] Boolean
+		//		If true, navigation buttons are displyed on the title bar.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
 		navButton: false,
 
-		// height: String
+		// height: [const] String
 		//		Explicitly specified height of the widget (ex. "300px"). If
 		//		"inherit" is specified, the height is inherited from its offset
 		//		parent.
-		height: "300px",
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		height: "",
 
-		// store: Object
-		//		Reference to data provider object used by this widget.
-		store: null,
+		// selectable: Boolean
+		//		If true, an item can be selected by clicking it.
+		selectable: true,
 
-		// query: Object
-		//		A query that can be passed to 'store' to initially filter the
-		//		items.
-		query: null,
-
-		// queryOptions: Object
-		//		An optional parameter for the query.
-		queryOptions: null,
+		/* internal properties */	
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblCarousel",
 
 		buildRendering: function(){
+			this.containerNode = domConstruct.create("div", {className: "mblCarouselPages"});
 			this.inherited(arguments);
-			this.domNode.className = "mblCarousel";
-			var h;
-			if(this.height === "inherit"){
-				if(this.domNode.offsetParent){
-					h = this.domNode.offsetParent.offsetHeight + "px";
+			var i;
+			if(this.srcNodeRef){
+				// reparent
+				for(i = 0, len = this.srcNodeRef.childNodes.length; i < len; i++){
+					this.containerNode.appendChild(this.srcNodeRef.firstChild);
 				}
-			}else if(this.height){
-				h = this.height;
 			}
-			this.domNode.style.height = h;
-			this.headerNode = domConstruct.create("DIV", {className:"mblCarouselHeaderBar"}, this.domNode);
+
+			this.headerNode = domConstruct.create("div", {className: "mblCarouselHeaderBar"}, this.domNode);
 
 			if(this.navButton){
-				this.btnContainerNode = domConstruct.create("DIV", {
+				this.btnContainerNode = domConstruct.create("div", {
 					className: "mblCarouselBtnContainer"
 				}, this.headerNode);
 				domStyle.set(this.btnContainerNode, "float", "right"); // workaround for webkit rendering problem
-				this.prevBtnNode = domConstruct.create("BUTTON", {
+				this.prevBtnNode = domConstruct.create("button", {
 					className: "mblCarouselBtn",
 					title: "Previous",
 					innerHTML: "<"
 				}, this.btnContainerNode);
-				this.nextBtnNode = domConstruct.create("BUTTON", {
+				this.nextBtnNode = domConstruct.create("button", {
 					className: "mblCarouselBtn",
 					title: "Next",
 					innerHTML: ">"
 				}, this.btnContainerNode);
-				this.connect(this.prevBtnNode, "onclick", "onPrevBtnClick");
-				this.connect(this.nextBtnNode, "onclick", "onNextBtnClick");
+				this._prevHandle = this.connect(this.prevBtnNode, "onclick", "onPrevBtnClick");
+				this._nextHandle = this.connect(this.nextBtnNode, "onclick", "onNextBtnClick");
 			}
 
 			if(this.pageIndicator){
@@ -114,209 +129,347 @@ define([
 					this.title = " ";
 				}
 				this.piw = new PageIndicator();
-				domStyle.set(this.piw, "float", "right"); // workaround for webkit rendering problem
 				this.headerNode.appendChild(this.piw.domNode);
 			}
 
-			this.titleNode = domConstruct.create("DIV", {
+			this.titleNode = domConstruct.create("div", {
 				className: "mblCarouselTitle"
 			}, this.headerNode);
 
-			this.containerNode = domConstruct.create("DIV", {className:"mblCarouselPages"}, this.domNode);
-			connect.subscribe("/dojox/mobile/viewChanged", this, "handleViewChanged");
+			this.domNode.appendChild(this.containerNode);
+			this.subscribe("/dojox/mobile/viewChanged", "handleViewChanged");
+			this.connect(this.domNode, "onclick", "_onClick");
+			this.connect(this.domNode, "onkeydown", "_onClick");
+			this._dragstartHandle = this.connect(this.domNode, "ondragstart", event.stop);
+			this.selectedItemIndex = -1;
+			this.items = [];
 		},
 
 		startup: function(){
 			if(this._started){ return; }
+
+			var h;
+			if(this.height === "inherit"){
+				if(this.domNode.offsetParent){
+					h = this.domNode.offsetParent.offsetHeight + "px";
+				}
+			}else if(this.height){
+				h = this.height;
+			}
+			if(h){
+				this.domNode.style.height = h;
+			}
+
 			if(this.store){
+				if(!this.setStore){
+					throw new Error("Use StoreCarousel or DataCarousel instead of Carousel.");
+				}
 				var store = this.store;
 				this.store = null;
 				this.setStore(store, this.query, this.queryOptions);
+			}else{
+				this.resizeItems();
 			}
 			this.inherited(arguments);
+
+			this.currentView = array.filter(this.getChildren(), function(view){
+				return view.isVisible();
+			})[0];
 		},
 
-		setStore: function(store, query, queryOptions){
+		resizeItems: function(){
 			// summary:
-			//		Sets the store to use with this widget.
-			if(store === this.store){ return; }
-			this.store = store;
-			this.query = query;
-			this.queryOptions = queryOptions;
-			this.refresh();
+			//		Resizes the child items of the carousel.
+			var idx = 0, i;
+			var h = this.domNode.offsetHeight - (this.headerNode ? this.headerNode.offsetHeight : 0);
+			var m = has("ie") ? 5 / this.numVisible-1 : 5 / this.numVisible;
+			var node, item;
+			array.forEach(this.getChildren(), function(view){
+				if(!(view instanceof SwapView)){ return; }
+				if(!(view.lazy)){
+					view._instantiated = true;
+				}
+				var ch = view.containerNode.childNodes;
+				for(i = 0, len = ch.length; i < len; i++){
+					node = ch[i];
+					if(node.nodeType !== 1){ continue; }
+					item = this.items[idx] || {};
+					domStyle.set(node, {
+						width: item.width || (90 / this.numVisible + "%"),
+						height: item.height || h + "px",
+						margin: "0 " + (item.margin || m + "%")
+					});
+					domClass.add(node, "mblCarouselSlot");
+					idx++;
+				}
+			}, this);
+
+			if(this.piw){
+				this.piw.refId = this.containerNode.firstChild;
+				this.piw.reset();
+			}
 		},
 
-		refresh: function(){
-			if(!this.store){ return; }
-			this.store.fetch({
-				query: this.query,
-				queryOptions: this.queryOptions,
-				onComplete: lang.hitch(this, "generate"),
-				onError: lang.hitch(this, "onError")
-			});
+		resize: function(){
+			if(!this.itemWidth){ return; }
+			var num = Math.floor(this.domNode.offsetWidth / this.itemWidth);
+			if(num === this.numVisible){ return; }
+			this.selectedItemIndex = this.getIndexByItemWidget(this.selectedItem);
+			this.numVisible = num;
+			if(this.items.length > 0){
+				this.onComplete(this.items);
+				this.select(this.selectedItemIndex);
+			}
+		},
+
+		fillPages: function(){
+			array.forEach(this.getChildren(), function(child, i){
+				var s = "";
+				var j;
+				for(j = 0; j < this.numVisible; j++){
+					var type, props = "", mixins;
+					var idx = i * this.numVisible + j;
+					var item = {};
+					if(idx < this.items.length){
+						item = this.items[idx];
+						type = this.store.getValue(item, "type");
+						if(type){
+							props = this.store.getValue(item, "props");
+							mixins = this.store.getValue(item, "mixins");
+						}else{
+							type = "dojox.mobile.CarouselItem";
+							array.forEach(["alt", "src", "headerText", "footerText"], function(p){
+								var v = this.store.getValue(item, p);
+								if(v !== undefined){
+									if(props){ props += ','; }
+									props += p + ':"' + v + '"';
+								}
+							}, this);
+						}
+					}else{
+						type = "dojox.mobile.CarouselItem";
+						props = 'src:"' + require.toUrl("dojo/resources/blank.gif") + '"' +
+							', className:"mblCarouselItemBlank"';
+					}
+
+					s += '<div data-dojo-type="' + type + '"';
+					if(props){
+						s += ' data-dojo-props=\'' + props + '\'';
+					}
+					if(mixins){
+						s += ' data-dojo-mixins=\'' + mixins + '\'';
+					}
+					s += '></div>';
+				}
+				child.containerNode.innerHTML = s;
+			}, this);
 		},
 
-		generate: function(/*Array*/items, /*Object*/ dataObject){
+		onComplete: function(/*Array*/items){
+			// summary:
+			//		A handler that is called after the fetch completes.
 			array.forEach(this.getChildren(), function(child){
 				if(child instanceof SwapView){
 					child.destroyRecursive();
 				}
 			});
+			this.selectedItem = null;
 			this.items = items;
-			this.swapViews = [];
-			this.images = [];
-			var nPages = Math.ceil(items.length / this.numVisible);
-			var h = this.domNode.offsetHeight - this.headerNode.offsetHeight;
-			for(var i = 0; i < nPages; i++){
-				var w = new SwapView({height:h+"px"});
+			var nPages = Math.ceil(items.length / this.numVisible),
+				i, h = this.domNode.offsetHeight - this.headerNode.offsetHeight,
+				idx = this.selectedItemIndex === -1 ? 0 : this.selectedItemIndex;
+				pg = Math.floor(idx / this.numVisible); // current page
+			for(i = 0; i < nPages; i++){
+				var w = new SwapView({height: h + "px", lazy:true});
 				this.addChild(w);
-				this.swapViews.push(w);
-				w._carouselImages = [];
-				if(i === 0 && this.piw){
-					this.piw.refId = w.id;
-				}
-				for(var j = 0; j < this.numVisible; j++){
-					var idx = i * this.numVisible + j;
-					var item = idx < items.length ? items[idx] :
-						{src:require.toUrl("dojo/resources/blank.gif"), height:"1px"};
-					var disp = w.domNode.style.display;
-					w.domNode.style.display = ""; // need to be visible during the size calculation
-					var box = this.createBox(item, h);
-					w.containerNode.appendChild(box);
-					box.appendChild(this.createHeaderText(item));
-					var img = this.createContent(item, idx);
-					box.appendChild(img);
-					box.appendChild(this.createFooterText(item));
-					this.resizeContent(item, box, img);
-					w.domNode.style.display = disp;
-
-					if(item.height !== "1px"){
-						this.images.push(img);
-						w._carouselImages.push(img);
-					}
+				if(i === pg){
+					w.show();
+					this.currentView = w;
+				}else{
+					w.hide();
 				}
 			}
-			if(this.swapViews[0]){
-				this.loadImages(this.swapViews[0]);
-			}
-			if(this.swapViews[1]){
-				this.loadImages(this.swapViews[1]); // pre-fetch the next view images
-			}
-			this.currentView = this.swapViews[0];
-			if(this.piw){
-				this.piw.reset();
+			this.fillPages();
+			this.resizeItems();
+			var children = this.getChildren();
+			var from = pg - 1 < 0 ? 0 : pg - 1;
+			var to = pg + 1 > nPages - 1 ? nPages - 1 : pg + 1;
+			for(i = from; i <= to; i++){
+				this.instantiateView(children[i]);
 			}
 		},
 
-		createBox: function(item, h){
-			var width = item.width || (90/this.numVisible + "%");
-			var height = item.height || h + "px";
-			var m = has("ie") ? 5/this.numVisible-1 : 5/this.numVisible;
-			var margin = item.margin || (m + "%");
-			var box = domConstruct.create("DIV", {
-				className: "mblCarouselBox"
-			});
-			domStyle.set(box, {
-				margin: "0px " + margin,
-				width: width,
-				height: height
-			});
-			return box;
+		onError: function(/*String*/ /*===== errText =====*/){
+			// summary:
+			//		An error handler.
 		},
 
-		createHeaderText: function(item){
-			this.headerTextNode = domConstruct.create("DIV", {
-				className: "mblCarouselImgHeaderText",
-				innerHTML: item.headerText ? item.headerText : " "
-			});
-			return this.headerTextNode;
+		onUpdate: function(/*Object*/ /*===== item, =====*/ /*Number*/ /*===== insertedInto =====*/){
+			// summary:
+			//		Adds a new item or updates an existing item.
 		},
 
-		createContent: function(item, idx){
-			var props = {
-				alt: item.alt || "",
-				tabIndex: "0", // for keyboard navigation on a desktop browser
-				className: "mblCarouselImg"
-			};
-			var img = domConstruct.create("IMG", props);
-			img._idx = idx;
-			if(item.height !== "1px"){
-				this.connect(img, "onclick", "onClick");
-				this.connect(img, "onkeydown", "onClick");
-				connect.connect(img, "ondragstart", event.stop);
-			}else{
-				img.style.visibility = "hidden";
-			}
-			return img;
+		onDelete: function(/*Object*/ /*===== item, =====*/ /*Number*/ /*===== removedFrom =====*/){
+			// summary:
+			//		Deletes an existing item.
 		},
 
-		createFooterText: function(item){
-			this.footerTextNode = domConstruct.create("DIV", {
-				className: "mblCarouselImgFooterText",
-				innerHTML: item.footerText ? item.footerText : " "
-			});
-			return this.footerTextNode;
+		onSet: function(item, attribute, oldValue, newValue){
+		},
+
+		onNew: function(newItem, parentInfo){
+		},
+
+		onStoreClose: function(request){
+			// summary:
+			//		Called when the store is closed.
 		},
 
-		resizeContent: function(item, box, img){
-			if(item.height !== "1px"){
-				img.style.height = (box.offsetHeight  - this.headerTextNode.offsetHeight - this.footerTextNode.offsetHeight) + "px";
+		getParentView: function(/*DomNode*/node){
+			// summary:
+			//		Returns the parent view of the given DOM node.
+			var w;
+			for(w = registry.getEnclosingWidget(node); w; w = w.getParent()){
+				if(w.getParent() instanceof SwapView){ return w; }
 			}
+			return null;
+		},
+
+		getIndexByItemWidget: function(/*Widget*/w){
+			// summary:
+			//		Returns the index of a given item widget.
+			if(!w){ return -1; }
+			var view = w.getParent();
+			return array.indexOf(this.getChildren(), view) * this.numVisible +
+				array.indexOf(view.getChildren(), w);
 		},
 
-		onError: function(errText){
+		getItemWidgetByIndex: function(/*Number*/index){
+			// summary:
+			//		Returns the index of an item widget at a given index.
+			if(index === -1){ return null; }
+			var view = this.getChildren()[Math.floor(index / this.numVisible)];
+			return view.getChildren()[index % this.numVisible];
 		},
 
-		onPrevBtnClick: function(e){
+		onPrevBtnClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		Called when the "previous" button is clicked.
 			if(this.currentView){
 				this.currentView.goTo(-1);
 			}
 		},
 
-		onNextBtnClick: function(e){
+		onNextBtnClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		Called when the "next" button is clicked.
 			if(this.currentView){
 				this.currentView.goTo(1);
 			}
 		},
 
-		onClick: function(e){
-			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
-			var img = e.currentTarget;
-			for(var i = 0; i < this.images.length; i++){
-				if(this.images[i] === img){
-					domClass.add(img, "mblCarouselImgSelected");
-				}else{
-					domClass.remove(this.images[i], "mblCarouselImgSelected");
+		_onClick: function(e){
+			// summary:
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(this.onClick(e) === false){ return; } // user's click action
+			if(e && e.type === "keydown"){ // keyboard navigation for accessibility
+				if(e.keyCode === 39){ // right arrow
+					this.onNextBtnClick();
+				}else if(e.keyCode === 37){ // left arrow
+					this.onPrevBtnClick();
+				}else if(e.keyCode !== 13){ // !Enter
+					return;
 				}
 			}
-			domStyle.set(img, "opacity", 0.4);
-			setTimeout(function(){
-				domStyle.set(img, "opacity", 1);
-			}, 1000);
-			connect.publish("/dojox/mobile/carouselSelect", [this, img, this.items[img._idx], img._idx]);
+
+			var w;
+			for(w = registry.getEnclosingWidget(e.target); ; w = w.getParent()){
+				if(!w){ return; }
+				if(w.getParent() instanceof SwapView){ break; }
+			}
+			this.select(w);
+			var idx = this.getIndexByItemWidget(w);
+			connect.publish("/dojox/mobile/carouselSelect", [this, w, this.items[idx], idx]);
 		},
 
-		loadImages: function(view){
-			if(!view){ return; }
-			var imgs = view._carouselImages;
-			array.forEach(imgs, function(img){
-				if(!img.src){
-					var item = this.items[img._idx];
-					img.src = item.src;
+		select: function(/*Widget|Number*/itemWidget){
+			// summary:
+			//		Selects the given widget.
+			if(typeof(itemWidget) === "number"){
+				itemWidget = this.getItemWidgetByIndex(itemWidget);
+			}
+			if(this.selectable){
+				if(this.selectedItem){
+					this.selectedItem.set("selected", false);
+					domClass.remove(this.selectedItem.domNode, "mblCarouselSlotSelected");
 				}
-			}, this);
+				if(itemWidget){
+					itemWidget.set("selected", true);
+					domClass.add(itemWidget.domNode, "mblCarouselSlotSelected");
+				}
+				this.selectedItem = itemWidget;
+			}
+		},
+
+		onClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User-defined function to handle clicks.
+			// tags:
+			//		callback
+		},
+
+		instantiateView: function(view){
+			// summary:
+			//		Instantiates the given view.
+			if(view && !view._instantiated){
+				var isHidden = (domStyle.get(view.domNode, "display") === "none");
+				if(isHidden){
+					domStyle.set(view.domNode, {visibility:"hidden", display:""});
+				}
+				lazyLoadUtils.instantiateLazyWidgets(view.containerNode, null, function(root){
+					if(isHidden){
+						domStyle.set(view.domNode, {visibility:"visible", display:"none"});
+					}
+				});
+				view._instantiated = true;
+			}
 		},
 
 		handleViewChanged: function(view){
+			// summary:
+			//		Listens to "/dojox/mobile/viewChanged" events.
 			if(view.getParent() !== this){ return; }
+			if(this.currentView.nextView(this.currentView.domNode) === view){
+				this.instantiateView(view.nextView(view.domNode));
+			}else{
+				this.instantiateView(view.previousView(view.domNode));
+			}
 			this.currentView = view;
-			// lazy-load images in the next view
-			this.loadImages(view.nextView(view.domNode));
 		},
 
 		_setTitleAttr: function(/*String*/title){
-			this.title = title;
+			// tags:
+			//		private
 			this.titleNode.innerHTML = this._cv ? this._cv(title) : title;
+			this._set("title", title);
 		}
 	});
+	
+	Carousel.ChildSwapViewProperties = {
+		// summary:
+		//		This property can be specified for the SwapView children of a dojox/mobile/Carousel.
+
+		// lazy: Boolean
+		//		Specifies that the Carousel child must be lazily loaded.
+		lazy: false
+	};
+
+	// Since any widget can be specified as an Accordion child, mix ChildWidgetProperties
+	// into the base widget class.  (This is a hack, but it's effective.)
+	// This is for the benefit of the parser. Remove for 2.0.  Also, hide from doc viewer.
+	lang.extend(SwapView, /*===== {} || =====*/ Carousel.ChildSwapViewProperties);
+	
+	return has("dojo-bidi") ? declare("dojox.mobile.Carousel", [Carousel, BidiCarousel]) : Carousel;
 });
diff --git a/dojox/mobile/CarouselItem.js b/dojox/mobile/CarouselItem.js
new file mode 100644
index 0000000..dd353ae
--- /dev/null
+++ b/dojox/mobile/CarouselItem.js
@@ -0,0 +1,104 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-construct",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
+	"dijit/_Contained",
+	"dijit/_WidgetBase",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/CarouselItem"
+], function(declare, domConstruct, domGeometry, domStyle, Contained, WidgetBase, has, BidiCarouselItem){
+
+	// module:
+	//		dojox/mobile/CarouselItem
+
+	var CarouselItem = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiCarouselItem" : "dojox.mobile.CarouselItem", [WidgetBase, Contained], {
+		// summary:
+		//		An item of dojox/mobile/Carousel.
+		// description:
+		//		CarouselItem represents an item of dojox/mobile/Carousel. In
+		//		typical use cases, users do not use this widget alone. Instead,
+		//		it is used in conjunction with the Carousel widget.
+
+		// alt: String
+		//		An alt text for the carousel item image.
+		alt: "",
+
+		// src: String
+		//		A path for an image to be displayed as a carousel item.
+		src: "",
+
+		// headerText: String
+		//		A text that is displayed above the carousel item image.
+		headerText: "",
+
+		// footerText: String
+		//		A text that is displayed below the carousel item image.
+		footerText: "",
+
+		/* internal properties */	
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblCarouselItem",
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.domNode.tabIndex = "0";
+			this.headerTextNode = domConstruct.create("div", { className: "mblCarouselItemHeaderText" }, this.domNode);
+			this.imageNode = domConstruct.create("img", { className: "mblCarouselItemImage" }, this.domNode);
+			this.footerTextNode = domConstruct.create("div", { className: "mblCarouselItemFooterText" }, this.domNode);
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this.inherited(arguments);
+			this.resize();
+		},
+
+		resize: function(size){
+			var box = domGeometry.getMarginBox(this.domNode);
+			if(box.h === 0){ return; }
+			var h1 = domGeometry.getMarginBox(this.headerTextNode).h;
+			var h2 = domGeometry.getMarginBox(this.footerTextNode).h;
+			domGeometry.setMarginBox(this.imageNode, {h:box.h - h1 - h2});
+		},
+
+		select: function(){
+			// summary:
+			//		Highlights the item.
+			var img = this.imageNode
+			domStyle.set(img, "opacity", 0.4);
+			this.defer(function(){
+				domStyle.set(img, "opacity", 1);
+			}, 1000);
+		},
+
+		_setAltAttr: function(/*String*/alt){
+			// tags:
+			//		private
+			this._set("alt", alt);
+			this.imageNode.alt = alt;
+		},
+
+		_setSrcAttr: function(/*String*/src){
+			// tags:
+			//		private
+			this._set("src", src);
+			this.imageNode.src = src;
+		},
+
+		_setHeaderTextAttr: function(/*String*/text){
+			this._set("headerText", text);
+			this.headerTextNode.innerHTML = this._cv ? this._cv(text) : text;
+		},
+
+		_setFooterTextAttr: function(/*String*/text){
+			// tags:
+			//		private
+			this._set("footerText", text);
+			this.footerTextNode.innerHTML = this._cv ? this._cv(text) : text;
+		}
+	});
+	return has("dojo-bidi") ? declare("dojox.mobile.CarouselItem", [CarouselItem, BidiCarouselItem]) : CarouselItem;
+});
diff --git a/dojox/mobile/CheckBox.js b/dojox/mobile/CheckBox.js
index 43031a0..04056b8 100644
--- a/dojox/mobile/CheckBox.js
+++ b/dojox/mobile/CheckBox.js
@@ -2,33 +2,48 @@ define([
 	"dojo/_base/declare",
 	"dojo/dom-construct",
 	"dijit/form/_CheckBoxMixin",
-	"./ToggleButton"
+	"./ToggleButton",
+	"./sniff"
 ],
-	function(declare, domConstruct, CheckBoxMixin, ToggleButton){
+	function(declare, domConstruct, CheckBoxMixin, ToggleButton, has){
 
-	/*=====
-		ToggleButton = dojox.mobile.ToggleButton;
-		CheckBoxMixin = dijit.form._CheckBoxMixin;
-	=====*/
 	return declare("dojox.mobile.CheckBox", [ToggleButton, CheckBoxMixin], {
 		// summary:
-		//		A non-templated checkbox widget that can be in two states (checked or not).
+		//		A non-templated checkbox widget that can be in two states 
+		//		(checked or not checked).
 
+		// baseClass: String
+		//		The name of the CSS class of this widget.
 		baseClass: "mblCheckBox",
 
+		// _setTypeAttr: [private] Function 
+		//		Overrides the automatic assignement of type to nodes.
 		_setTypeAttr: function(){}, // cannot be changed: IE complains w/o this
 
 		buildRendering: function(){
-			if(!this.srcNodeRef){
+			if(!this.templateString && !this.srcNodeRef){
 				// The following doesn't work on IE < 8 if the default state is checked.
 				// You have to use "<input checked>" instead but it's not worth the bytes here.
 				this.srcNodeRef = domConstruct.create("input", {type: this.type});
 			}
 			this.inherited(arguments);
-			this.focusNode = this.domNode;
+			if(!this.templateString){
+				// if this widget is templated, let the template set the focusNode via an attach point
+				this.focusNode = this.domNode;
+			}
+
+			if(has("windows-theme")){
+				var rootNode = domConstruct.create("span", {className: "mblCheckableInputContainer"});
+				rootNode.appendChild(this.domNode.cloneNode());
+				this.labelNode = domConstruct.create("span", {className: "mblCheckableInputDecorator"}, rootNode);
+				this.domNode = rootNode;
+				this.focusNode = rootNode.firstChild;
+			}
 		},
 		
 		_getValueAttr: function(){
+			// tags:
+			//		private
 			return (this.checked ? this.value : false);
 		}
 	});
diff --git a/dojox/mobile/ComboBox.js b/dojox/mobile/ComboBox.js
old mode 100644
new mode 100755
index 6ab11c9..e4caa09
--- a/dojox/mobile/ComboBox.js
+++ b/dojox/mobile/ComboBox.js
@@ -5,72 +5,86 @@ define([
 	"dojo/_base/window",
 	"dojo/dom-geometry",
 	"dojo/dom-style",
+	"dojo/dom-attr",
 	"dojo/window",
+	"dojo/touch",
 	"dijit/form/_AutoCompleterMixin",
 	"dijit/popup",
 	"./_ComboBoxMenu",
 	"./TextBox",
 	"./sniff"
-], function(kernel, declare, lang, win, domGeometry, domStyle, windowUtils, AutoCompleterMixin, popup, ComboBoxMenu, TextBox, has){
+], function(kernel, declare, lang, win, domGeometry, domStyle, domAttr, windowUtils, touch, AutoCompleterMixin, popup, ComboBoxMenu, TextBox, has){
 	kernel.experimental("dojox.mobile.ComboBox"); // should be using a more native search-type UI
 
-	/*=====
-		TextBox = dojox.mobile.TextBox;
-		AutoCompleterMixin = dijit.form._AutoCompleterMixin;
-	=====*/
 	return declare("dojox.mobile.ComboBox", [TextBox, AutoCompleterMixin], {
 		// summary:
-		//		A non-templated auto-completing text box widget
-		//
+		//		A non-templated auto-completing text box widget.
 
 		// dropDownClass: [protected extension] String
-		//		Name of the dropdown widget class used to select a date/time.
-		//		Subclasses should specify this.
+		//		Name of the drop-down widget class used to select a date/time.
+		//		Should be specified by subclasses.
 		dropDownClass: "dojox.mobile._ComboBoxMenu",
 
-		// initially disable selection since iphone displays selection handles that makes it hard to pick from the list
+		// initially disable selection since iphone displays selection handles
+		// that makes it hard to pick from the list
+		
+		// selectOnClick: Boolean
+		//		Flag which enables the selection on click.
 		selectOnClick: false,
+		
+		// autoComplete: Boolean
+		//		Flag which enables the auto-completion.
 		autoComplete: false,
 
 		// dropDown: [protected] Widget
-		//		The widget to display as a popup.  This widget *must* be
+		//		The widget to display as a popup. This widget *must* be
 		//		defined before the startup function is called.
 		dropDown: null,
 
-		// maxHeight: [protected] Integer
-		//		The max height for our dropdown.
-		//		Any dropdown taller than this will have scrollbars.
-		//		Set to -1 to limit height to available space in viewport
+		// maxHeight: [protected] int
+		//		The maximum height for the drop-down.
+		//		Any drop-down taller than this value will have scrollbars.
+		//		Set to -1 to limit the height to the available space in the viewport.
 		maxHeight: -1,
 
 		// dropDownPosition: [const] String[]
-		//		This variable controls the position of the drop down.
-		//		It's an array of strings with the following values:
+		//		This variable controls the position of the drop-down.
+		//		It is an array of strings with the following values:
 		//
-		//			* before: places drop down to the left of the target node/widget, or to the right in
-		//			  the case of RTL scripts like Hebrew and Arabic
-		//			* after: places drop down to the right of the target node/widget, or to the left in
-		//			  the case of RTL scripts like Hebrew and Arabic
-		//			* above: drop down goes above target node
-		//			* below: drop down goes below target node
+		//		- before: places drop down to the left of the target node/widget, or to the right in
+		//		  the case of RTL scripts like Hebrew and Arabic
+		//		- after: places drop down to the right of the target node/widget, or to the left in
+		//		  the case of RTL scripts like Hebrew and Arabic
+		//		- above: drop down goes above target node
+		//		- below: drop down goes below target node
 		//
 		//		The list is positions is tried, in order, until a position is found where the drop down fits
 		//		within the viewport.
-		//
 		dropDownPosition: ["below","above"],
 
 		_throttleOpenClose: function(){
-			// prevent open/close in rapid succession
+			// summary:
+			//		Prevents the open/close in rapid succession.
+			// tags:
+			//		private
 			if(this._throttleHandler){
-				clearTimeout(this._throttleHandler);
+				this._throttleHandler.remove();
 			}
-			this._throttleHandler = setTimeout(lang.hitch(this, function(){ this._throttleHandler = null; }), 500);
+			this._throttleHandler = this.defer(function(){ this._throttleHandler = null; }, 500);
 		},
 
 		_onFocus: function(){
+			// summary:
+			//		Shows drop-down if the user is selecting Next/Previous from the virtual keyboard.
+			// tags:
+			//		private
 			this.inherited(arguments);
 			if(!this._opened && !this._throttleHandler){
-				this._startSearchAll(); // show dropdown if user is selecting Next/Previous from virtual keyboard
+				this._startSearchAll(); 
+			}
+
+			if(has("windows-theme")) {
+				this.domNode.blur();
 			}
 		},
 
@@ -80,6 +94,8 @@ define([
 		},
 
 		_setListAttr: function(v){
+			// tags:
+			//		private
 			this._set('list', v); // needed for Firefox 4+ to prevent HTML5 mode
 		},
 
@@ -90,23 +106,34 @@ define([
 			//		protected
 
 			this._throttleOpenClose();
-			if(this.startHandler){
+			if(this.endHandler){
 				this.disconnect(this.startHandler);
-				this.startHandler = null;
-				if(this.moveHandler){ this.disconnect(this.moveHandler); }
-				if(this.endHandler){ this.disconnect(this.endHandler); }
+				this.disconnect(this.endHandler);
+				this.disconnect(this.moveHandler);
+				clearInterval(this.repositionTimer);
+				this.repositionTimer = this.endHandler = null;
 			}
 			this.inherited(arguments);
+			domAttr.remove(this.domNode, "aria-owns");
+			domAttr.set(this.domNode, "aria-expanded", "false");
 			popup.close(this.dropDown);
 			this._opened = false;
+
+			// Remove disable attribute to make input element clickable after context menu closed
+			if(has("windows-theme") && this.domNode.disabled){
+				this.defer(function(){
+					this.domNode.removeAttribute("disabled");
+				}, 300);
+			}
+
 		},
 
 		openDropDown: function(){
 			// summary:
-			//		Opens the dropdown for this widget.   To be called only when this.dropDown
-			//		has been created and is ready to display (ie, it's data is loaded).
+			//		Opens the dropdown for this widget. To be called only when this.dropDown
+			//		has been created and is ready to display (that is, its data is loaded).
 			// returns:
-			//		return value of popup.open()
+			//		Returns the value of popup.open().
 			// tags:
 			//		protected
 
@@ -115,10 +142,19 @@ define([
 				ddNode = dropDown.domNode,
 				aroundNode = this.domNode,
 				self = this;
+				
+			domAttr.set(dropDown.domNode, "role", "listbox");
+			domAttr.set(this.domNode, "aria-expanded", "true");
+			if(dropDown.id){
+				domAttr.set(this.domNode, "aria-owns", dropDown.id);
+			}
 
+			if(has('touch')){
+				win.global.scrollBy(0, domGeometry.position(aroundNode, false).y); // don't call scrollIntoView since it messes up ScrollableView
+			}
 
 			// TODO: isn't maxHeight dependent on the return value from popup.open(),
-			// ie, dependent on how much space is available (BK)
+			// i.e., dependent on how much space is available (BK)
 
 			if(!this._preparedNode){
 				this._preparedNode = true;
@@ -177,7 +213,7 @@ define([
 				parent: this,
 				popup: dropDown,
 				around: aroundNode,
-				orient: this.dropDownPosition,
+				orient: has("windows-theme") ? ["above"] : this.dropDownPosition,
 				onExecute: function(){
 					self.closeDropDown();
 				},
@@ -191,26 +227,96 @@ define([
 			this._opened=true;
 
 			if(wasClosed){
-				if(retVal.aroundCorner.charAt(0) == 'B'){ // is popup below?
-					this.domNode.scrollIntoView(true); // scroll to top
-				}
-				this.startHandler = this.connect(win.doc.documentElement, has('touch') ? "ontouchstart" : "onmousedown",
-					lang.hitch(this, function(){
-						var isMove = false;
-						this.moveHandler = this.connect(win.doc.documentElement, has('touch') ? "ontouchmove" : "onmousemove", function(){ isMove = true; });
-						this.endHandler = this.connect(win.doc.documentElement, has('touch') ? "ontouchend" : "onmouseup", function(){ if(!isMove){ this.closeDropDown(); } });
-					})
+				var	isGesture = false,
+					skipReposition = false,
+					active = false,
+					wrapper = dropDown.domNode.parentNode,
+					aroundNodePos = domGeometry.position(aroundNode, false),
+					popupPos = domGeometry.position(wrapper, false),
+					deltaX = popupPos.x - aroundNodePos.x,
+					deltaY = popupPos.y - aroundNodePos.y,
+					startX = -1, startY = -1;
+
+				// touchstart isn't really needed since touchmove implies touchstart, but
+				// mousedown is needed since mousemove doesn't know if the left button is down or not
+				this.startHandler = this.connect(win.doc.documentElement, touch.press,
+					function(e){
+						skipReposition = true;
+						active = true;
+						isGesture = false;
+						startX = e.clientX;
+						startY = e.clientY;
+					}
+				);
+				this.moveHandler = this.connect(win.doc.documentElement, touch.move,
+					function(e){
+						skipReposition = true;
+						if(e.touches){
+							active = isGesture = true; // touchmove implies touchstart
+						}else if(active && (e.clientX != startX || e.clientY != startY)){
+							isGesture = true;
+						}
+					}
+				);
+				this.clickHandler = this.connect(dropDown.domNode, "onclick",
+					function(){
+						skipReposition = true;
+						active = isGesture = false; // click implies no gesture movement
+					}
 				);
+				this.endHandler = this.connect(win.doc.documentElement, "onmouseup",//touch.release,
+					function(){
+						this.defer(function(){ // allow onclick to go first
+							skipReposition = true;
+							if(!isGesture && active){ // if click without move, then close dropdown
+								this.closeDropDown();
+							}
+							active = false;
+						});
+					}
+				);
+				this.repositionTimer = setInterval(lang.hitch(this, function(){
+					if(skipReposition){ // don't reposition if busy
+						skipReposition = false;
+						return;
+					}
+					var	currentAroundNodePos = domGeometry.position(aroundNode, false),
+						currentPopupPos = domGeometry.position(wrapper, false),
+						currentDeltaX = currentPopupPos.x - currentAroundNodePos.x,
+						currentDeltaY = currentPopupPos.y - currentAroundNodePos.y;
+					// if the popup is no longer placed correctly, relocate it
+					if(Math.abs(currentDeltaX - deltaX) >= 1 || Math.abs(currentDeltaY - deltaY) >= 1){ // Firefox plays with partial pixels
+						domStyle.set(wrapper, { left: parseInt(domStyle.get(wrapper, "left")) + deltaX - currentDeltaX + 'px', top: parseInt(domStyle.get(wrapper, "top")) + deltaY - currentDeltaY + 'px' });
+					}
+				}), 50); // yield a short time to allow for consolidation for better CPU throughput
+			}
+
+			// We need to disable input control in order to prevent opening the soft keyboard in IE
+			if(has("windows-theme")){
+				this.domNode.setAttribute("disabled", true);
 			}
+
 			return retVal;
 		},
 
 		postCreate: function(){
 			this.inherited(arguments);
 			this.connect(this.domNode, "onclick", "_onClick");
+			domAttr.set(this.domNode, "role", "combobox");
+			domAttr.set(this.domNode, "aria-expanded", "false");
+		},
+
+		destroy: function(){
+			if(this.repositionTimer){
+				clearInterval(this.repositionTimer);
+			}
+			this.inherited(arguments);
 		},
 
 		_onClick: function(/*Event*/ e){
+			// tags:
+			//		private
+			
 			// throttle clicks to prevent double click from doing double actions
 			if(!this._throttleHandler){
 				if(this.opened){
diff --git a/dojox/mobile/Container.js b/dojox/mobile/Container.js
new file mode 100644
index 0000000..cdaf443
--- /dev/null
+++ b/dojox/mobile/Container.js
@@ -0,0 +1,21 @@
+define([
+	"dojo/_base/declare",
+	"dijit/_Container",
+	"./Pane"
+], function(declare, Container, Pane){
+
+	// module:
+	//		dojox/mobile/Container
+
+	return declare("dojox.mobile.Container", [Pane, Container], {
+		// summary:
+		//		A simple container-type widget.
+		// description:
+		//		Container is a simple general-purpose container widget.
+		//		It is a widget, but can be regarded as a simple `<div>` element.
+
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblContainer"
+	});
+});
diff --git a/dojox/mobile/ContentPane.js b/dojox/mobile/ContentPane.js
index d9e5f4f..0ad4c31 100644
--- a/dojox/mobile/ContentPane.js
+++ b/dojox/mobile/ContentPane.js
@@ -1,125 +1,22 @@
 define([
-	"dojo/_base/kernel",
-	"dojo/_base/array",
 	"dojo/_base/declare",
-	"dojo/_base/lang",
-	"dojo/_base/window",
-	"dijit/_Contained",
-	"dijit/_WidgetBase",
-	"dojo/_base/xhr",
-	"./ProgressIndicator"
-], function(dojo, array, declare, lang, win, Contained, WidgetBase, xhr, ProgressIndicator){
-
-/*=====
-	var Contained = dijit._Contained;
-	var WidgetBase = dijit._WidgetBase;
-=====*/
+	"./Container",
+	"./_ContentPaneMixin"
+], function(declare, Container, ContentPaneMixin){
 
 	// module:
 	//		dojox/mobile/ContentPane
-	// summary:
-	//		A very simple content pane to embed an HTML fragment.
 
-	return declare("dojox.mobile.ContentPane", [WidgetBase, Contained],{
+	return declare("dojox.mobile.ContentPane", [Container, ContentPaneMixin], {
 		// summary:
 		//		A very simple content pane to embed an HTML fragment.
 		// description:
-		//		This widget embeds an HTML fragment and run the parser. onLoad()
-		//		is called when parsing is done and the content is ready.
-		//		"dojo/_base/xhr" is in the dependency list. Usually this is not
-		//		necessary, but there is a case where dojox.mobile custom build
-		//		does not contain xhr. Note that this widget does not inherit
-		//		from dijit._Container.
-
-		// href: String
-		//		URL of the content to embed.
-		href: "",
-
-		// content: String
-		//		An html fragment to embed.
-		content: "",
-
-		// parseOnLoad: Boolean
-		//		If true, runs the parser when the load completes.
-		parseOnLoad: true,
-
-		// prog: Boolean
-		//		If true, shows progress indicator.
-		prog: true,
-
-		buildRendering: function(){
-			this.inherited(arguments);
-			this.domNode.className = "mblContentPane";
-			if(!this.containerNode){
-				this.containerNode = this.domNode;
-			}
-		},
-
-		startup: function(){
-			if(this._started){ return; }
-			if(this.prog){
-				this._p = ProgressIndicator.getInstance();
-			}
-			var parent = this.getParent && this.getParent();
-			if(!parent || !parent.resize){ // top level widget
-				this.resize();
-			}
-			this.inherited(arguments);
-		},
-	
-		resize: function(){
-			// summary:
-			//		Calls resize() of each child widget.
-			array.forEach(this.getChildren(), function(child){
-				if(child.resize){ child.resize(); }
-			});
-		},
-	
-		loadHandler: function(/*String*/response){
-			// summary:
-			//		A handler called when load completes.
-			this.set("content", response);
-		},
-	
-		errorHandler: function(err){
-			// summary:
-			//		An error handler called when load fails.
-			if(this._p){ this._p.stop(); }
-		},
-	
-		onLoad: function(){
-			// summary:
-			//		Stub method to allow the application to connect to.
-			//		Called when parsing is done and the content is ready.
-		},
-	
-		_setHrefAttr: function(/*String*/href){
-			var p = this._p;
-			if(p){
-				win.body().appendChild(p.domNode);
-				p.start();
-			}
-			this.href = href;
-			xhr.get({
-				url: href,
-				handleAs: "text",
-				load: lang.hitch(this, "loadHandler"),
-				error: lang.hitch(this, "errorHandler")
-			});
-		},
+		//		This widget embeds an HTML fragment and runs the parser. It has
+		//		the ability to load external content using dojo/_base/xhr. onLoad()
+		//		is called when parsing is done and the content is
+		//		ready. Compared with dijit/layout/ContentPane, this widget
+		//		provides only basic fuctionality, but it is much lighter.
 
-		_setContentAttr: function(/*String|DomNode*/data){
-			this.destroyDescendants();
-			if(typeof data === "object"){
-				this.domNode.appendChild(data);
-			}else{
-				this.domNode.innerHTML = data;
-			}
-			if(this.parseOnLoad){
-				dojo.parser.parse(this.domNode);
-			}
-			if(this._p){ this._p.stop(); }
-			this.onLoad();
-		}
+		baseClass: "mblContentPane"
 	});
 });
diff --git a/dojox/mobile/DataCarousel.js b/dojox/mobile/DataCarousel.js
new file mode 100644
index 0000000..3a2b188
--- /dev/null
+++ b/dojox/mobile/DataCarousel.js
@@ -0,0 +1,19 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"./Carousel",
+	"./_DataMixin"
+], function(kernel, declare, Carousel, DataMixin){
+
+	// module:
+	//		dojox/mobile/DataCarousel
+
+	kernel.deprecated("dojox/mobile/DataCarousel", "Use dojox/mobile/StoreCarousel instead", 2.0);
+	return declare("dojox.mobile.DataCarousel", [Carousel, DataMixin], {
+		// summary:
+		//		A dojo/data-enabled Carousel.
+		// description:
+		//		DataCarousel is a subclass of dojox/mobile/Carousel which
+		//		can generate contents according to the given dojo/data store.
+	});
+});
diff --git a/dojox/mobile/DatePicker.js b/dojox/mobile/DatePicker.js
new file mode 100644
index 0000000..27abd31
--- /dev/null
+++ b/dojox/mobile/DatePicker.js
@@ -0,0 +1,22 @@
+define([
+	"dojo/_base/lang",
+	"./_PickerChooser!DatePicker"
+], function(lang, DatePicker){
+
+	// module:
+	//		dojox/mobile/DatePicker
+
+	// TODO: need to list all the properties/methods in the interface provided by
+	// SpinWheelDatePicker / ValuePickerDatePicker
+		
+	/*=====
+	return function(){
+		// summary:
+		//		A wrapper widget around SpinWheelDatePicker or ValuePickerDatePicker.
+		//		It should be used with the automatic theme loader, dojox/mobile/deviceTheme.
+		//		Returns ValuePickerDatePicker when the current theme is "android" or "holodark".
+		//		Returns SpinWheelDatePicker otherwise.
+	};
+	=====*/
+	return lang.setObject("dojox.mobile.DatePicker", DatePicker);
+});
diff --git a/dojox/mobile/EdgeToEdgeCategory.js b/dojox/mobile/EdgeToEdgeCategory.js
index cc9c933..bba9fbd 100644
--- a/dojox/mobile/EdgeToEdgeCategory.js
+++ b/dojox/mobile/EdgeToEdgeCategory.js
@@ -3,14 +3,8 @@ define([
 	"./RoundRectCategory"
 ], function(declare, RoundRectCategory){
 
-/*=====
-	var RoundRectCategory = dojox.mobile.RoundRectCategory;
-=====*/
-
 	// module:
 	//		dojox/mobile/EdgeToEdgeCategory
-	// summary:
-	//		A category header for an edge-to-edge list.
 
 	return declare("dojox.mobile.EdgeToEdgeCategory", RoundRectCategory, {
 		// summary:
@@ -18,6 +12,10 @@ define([
 		buildRendering: function(){
 			this.inherited(arguments);
 			this.domNode.className = "mblEdgeToEdgeCategory";
+
+			if(this.type && this.type == "long"){
+				this.domNode.className += " mblEdgeToEdgeCategoryLong";
+			}
 		}
 	});
 });
diff --git a/dojox/mobile/EdgeToEdgeDataList.js b/dojox/mobile/EdgeToEdgeDataList.js
index 7471eb1..b1cc977 100644
--- a/dojox/mobile/EdgeToEdgeDataList.js
+++ b/dojox/mobile/EdgeToEdgeDataList.js
@@ -1,24 +1,21 @@
 define([
+	"dojo/_base/kernel",
 	"dojo/_base/declare",
 	"./EdgeToEdgeList",
 	"./_DataListMixin"
-], function(declare, EdgeToEdgeList, DataListMixin){
-
-/*=====
-	var EdgeToEdgeList = dojox.mobile.EdgeToEdgeList;
-	var DataListMixin = dojox.mobile._DataListMixin;
-=====*/
+], function(kernel, declare, EdgeToEdgeList, DataListMixin){
 
 	// module:
 	//		dojox/mobile/EdgeToEdgeDataList
-	// summary:
-	//		An enhanced version of EdgeToEdgeList.
 
+	kernel.deprecated("dojox/mobile/EdgeToEdgeDataList", 
+		"Use dojox/mobile/EdgeToEdgeStoreList instead", "2.0");
+	
 	return declare("dojox.mobile.EdgeToEdgeDataList", [EdgeToEdgeList, DataListMixin],{
 		// summary:
-		//		An enhanced version of EdgeToEdgeList.
+		//		A dojo/data-enabled version of EdgeToEdgeList.
 		// description:
-		//		EdgeToEdgeDataList is an enhanced version of EdgeToEdgeList. It
-		//		can generate ListItems according to the given dojo.data store.
+		//		EdgeToEdgeDataList is a subclass of EdgeToEdgeList which
+		//		can generate ListItems according to the given dojo/data store.
 	});
 });
diff --git a/dojox/mobile/EdgeToEdgeList.js b/dojox/mobile/EdgeToEdgeList.js
index d129dea..99b2dd0 100644
--- a/dojox/mobile/EdgeToEdgeList.js
+++ b/dojox/mobile/EdgeToEdgeList.js
@@ -3,22 +3,22 @@ define([
 	"./RoundRectList"
 ], function(declare, RoundRectList){
 
-/*=====
-	var RoundRectList = dojox.mobile.RoundRectList;
-=====*/
-
 	// module:
 	//		dojox/mobile/EdgeToEdgeCategory
-	// summary:
-	//		An edge-to-edge layout list.
 
 	return declare("dojox.mobile.EdgeToEdgeList", RoundRectList, {
 		// summary:
 		//		An edge-to-edge layout list.
 		// description:
 		//		EdgeToEdgeList is an edge-to-edge layout list, which displays
-		//		all items in equally sized rows. Each item must be
-		//		dojox.mobile.ListItem.
+		//		all items in equally-sized rows. Each item must be a
+		//		dojox/mobile/ListItem.
+		
+		// filterBoxClass: String
+		//		The name of the CSS class added to the DOM node inside which is placed the 
+		//		dojox/mobile/SearchBox created when mixing dojox/mobile/FilteredListMixin.
+		//		The default value is "mblFilteredEdgeToEdgeListSearchBox". 
+		filterBoxClass: "mblFilteredEdgeToEdgeListSearchBox",
 
 		buildRendering: function(){
 			this.inherited(arguments);
diff --git a/dojox/mobile/EdgeToEdgeStoreList.js b/dojox/mobile/EdgeToEdgeStoreList.js
new file mode 100644
index 0000000..aeeed02
--- /dev/null
+++ b/dojox/mobile/EdgeToEdgeStoreList.js
@@ -0,0 +1,17 @@
+define([
+	"dojo/_base/declare",
+	"./EdgeToEdgeList",
+	"./_StoreListMixin"
+], function(declare, EdgeToEdgeList, StoreListMixin){
+
+	// module:
+	//		dojox/mobile/EdgeToEdgeStoreList
+
+	return declare("dojox.mobile.EdgeToEdgeStoreList", [EdgeToEdgeList, StoreListMixin],{
+		// summary:
+		//		A dojo/store-enabled version of EdgeToEdgeList.
+		// description:
+		//		EdgeToEdgeStoreList is a subclass of EdgeToEdgeList which
+		//		can generate ListItems according to the given dojo/store store.
+	});
+});
diff --git a/dojox/mobile/ExpandingTextArea.js b/dojox/mobile/ExpandingTextArea.js
index 4a6bf8c..e2fdc18 100644
--- a/dojox/mobile/ExpandingTextArea.js
+++ b/dojox/mobile/ExpandingTextArea.js
@@ -4,23 +4,18 @@ define([
 	"./TextArea"
 ], function(declare, ExpandingTextAreaMixin, TextArea){
 
-	/*=====
-		TextArea = dojox.mobile.TextArea;
-		ExpandingTextAreaMixin = dijit.form._ExpandingTextAreaMixin;
-	=====*/
 	return declare("dojox.mobile.ExpandingTextArea", [TextArea, ExpandingTextAreaMixin], {
 		// summary:
-		//		Non-templated TEXTAREA widget with the capability to adjust it's height according to the amount of data.
-		//
+		//		Non-templated TEXTAREA widget with the capability to adjust its 
+		//		height according to the amount of data.
 		// description:
-		//		A textarea that dynamically expands/contracts (changing it's height) as
+		//		A textarea that dynamically expands/contracts (changing its height) as
 		//		the user types, to display all the text without requiring a vertical scroll bar.
 		//
 		//		Takes all the parameters (name, value, etc.) that a vanilla textarea takes.
-		//		Rows is not supported since this widget adjusts the height.
-		//
+		//		Rows are not supported since this widget adjusts its height.
 		// example:
-		// |	<textarea dojoType="dojox.mobile.ExpandingTextArea">...</textarea>
+		//	|	<textarea dojoType="dojox.mobile.ExpandingTextArea">...</textarea>
 
 		baseClass: "mblTextArea mblExpandingTextArea"
 	});
diff --git a/dojox/mobile/FilteredListMixin.js b/dojox/mobile/FilteredListMixin.js
new file mode 100644
index 0000000..faa3b7b
--- /dev/null
+++ b/dojox/mobile/FilteredListMixin.js
@@ -0,0 +1,422 @@
+define([
+	"require",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/aspect",
+	"dijit/registry",
+	"./SearchBox",
+	"./ScrollableView",
+	"./viewRegistry"
+], function(require, array, declare, lang, dom, domClass, domConstruct,  
+			aspect, registry, SearchBox, ScrollableView, viewRegistry){
+
+	// module:
+	//		dojox/mobile/FilteredListMixin
+
+	return declare("dojox.mobile.FilteredListMixin", null, {
+		// summary:
+		//		Mixin for filtered lists.
+		// description:
+		//		This mixin adds filtering capabilities to all dojox/mobile list widgets:
+		//		dojox/mobile/RoundRectList and any of its subclasses (RoundRectStoreList, 
+		//		RoundRectDataList, EdgeToEdgeList, EdgeToEdgeStoreList, EdgeToEdgeDataList).
+		//		When mixing this class into a list widget, the list items are dynamically 
+		//		filtered depending on the filtering string that the user enters in a 
+		//		dojox/mobile/SearchBox. 
+		//
+		//		This mixin supports the following use-cases:
+		//		1. For user's convenience, by simply mixing this class into a list widget 
+		//		the mixin creates a dojox/mobile/SearchBox and a dojox/mobile/ScrollableView. 
+		//		The list is placed inside the ScrollableView and the SearchBox, which allows
+		//		filtering the list, is placed on top of the ScrollableView.
+		//		2. Alternatively, the user can create (and style) the instance of dojox/mobile/SearchBox, 
+		//		and specify its id using the property filterBoxRef of this mixin. This allows
+		//		placing the SearchBox anywhere in the DOM, while the mixin takes care of 
+		//		the necessary glue to ensure the list is filtered according to the filter criteria
+		//		entered in the SearchBox.
+		//
+		//		The filtering works for lists backed by a store (dojo/store or dojo/data), as well 
+		//		as for lists not backed by a store. When filtering a list backed by a store 
+		//		containing hierarchical data (data items that are children of a parent data item), 
+		//		the store must support recursive search queries such that the filtering can match 
+		//		child items.
+		//
+		//		For configuration purposes, the instance of dojox/mobile/SearchBox can be retrieved
+		//		using the method getFilterBox(). If a dojox/mobile/ScrollableView is created by
+		//		this mixin, it can be retrieved using getScrollableView().
+		//
+		// example:
+		// |	<!-- Markup use-case: -->
+		// |	<!-- SearchBox and ScrollableView created by the mixin. -->
+		// |	<!-- Filtered EdgeToEdgeStoreList created in markup. -->
+		// |	<div data-dojo-type="dojox/mobile/View">
+		// |		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Some heading</h1>
+		// |		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList"
+		// |			data-dojo-mixins="dojox/mobile/FilteredListMixin"
+		// |			data-dojo-props="placeHolder: 'Search', store: myStore"></ul>
+		// |	</div>
+		// example:
+		// |	<!-- Markup use-case: -->
+		// |	<!-- SearchBox and ScrollableView created by the mixin. -->
+		// |	<!-- Filtered RoundRectList created in markup. --> 
+		// |	<div data-dojo-type="dojox/mobile/View">
+		// |		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Some heading</h1>
+		// |		<ul id="list" data-dojo-type="dojox/mobile/RoundRectList"
+		// |			data-dojo-mixins="dojox/mobile/FilteredListMixin"
+		// |			data-dojo-props="placeHolder: 'Search'">
+		// |			<li data-dojo-type="dojox/mobile/ListItem">Item 1</li>
+		// |			<li data-dojo-type="dojox/mobile/ListItem">Item 2</li>
+		// |			...
+		// |		</ul>
+		// |	</div>
+		// example:
+		// |	// Programmatic use-case:
+		// |	// SearchBox and ScrollableView created by the mixin.
+		// |	// Filtered EdgeToEdgeStoreList created programmatically.
+		// |	require(["dojo/_base/declare", "dojo/ready", "dojox/mobile", "dojox/mobile/EdgeToEdgeStoreList", 
+		// |			"dojox/mobile/FilteredListMixin", ...],	function(declare, ready, registry, ...){
+		// |		ready(function(){
+		// |			var listWidget =
+		// |				new declare([EdgeToEdgeStoreList, FilteredListMixin])(
+		// |					{placeHolder: 'Search', store: myStore, "filteredList"});
+		// |			listWidget.startup();
+		// |		});
+		// |	});
+		// |	...
+		// |	<div id="view" data-dojo-type="dojox/mobile/View">
+		// |		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Some heading</h1>
+		// |		<div id="filteredList">
+		// |	</div>
+		// example:
+		// |	<!-- Markup use-case: -->
+		// |	<!-- SearchBox and ScrollableView provided by the user. -->
+		// |	<!-- Filtered EdgeToEdgeDataList created in markup. --> 
+		// |	<div data-dojo-type="dojox/mobile/View">
+		// |		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Some heading</h1>
+		// |		<input id="filterBox" data-dojo-type="dojox/mobile/SearchBox" type="search"
+		// |			class="mblFilteredEdgeToEdgeListSearchBox">		
+		// |		<div data-dojo-type="dojox/mobile/ScrollableView">
+		// |			<ul data-dojo-type="dojox/mobile/EdgeToEdgeDataList" 
+		// |				data-dojo-mixins="dojox/mobile/FilteredListMixin"
+		// |				data-dojo-props="filterBoxRef: 'filterBox', placeHolder: 'Search', store: myStore"></ul>
+		// |		</div>
+		// |	</div>
+		// example:
+		// |	// Programmatic use-case:
+		// |	// SearchBox and ScrollableView provided by the user.
+		// |	// Filtered EdgeToEdgeStoreList created programmatically.
+		// |	require(["dojo/_base/declare", "dojo/ready", "dijit/registry", "dojox/mobile",
+		// |			"dojox/mobile/EdgeToEdgeStoreList", "dojox/mobile/FilteredListMixin",
+		// |			"dojox/mobile/ScrollableView", ...], function(declare, ready, registry, ...){
+		// |		ready(function(){
+		// |			var view = registry.byId("scrollableView");
+		// |			var listWidget =
+		// |				new declare([EdgeToEdgeStoreList, FilteredListMixin])(
+		// |					{id:"list", filterBoxRef: 'filterBox', placeHolder: 'Search', store: myStore});
+		// |			listWidget.placeAt(view.containerNode);
+		// |			listWidget.startup();
+		// |		});
+		// |	});
+		// |	...
+		// |	<div data-dojo-type="dojox/mobile/View">
+		// |		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Some heading</h1>
+		// |		<input id="filterBox" data-dojo-type="dojox/mobile/SearchBox" type="search"
+		// |			class="mblFilteredEdgeToEdgeListSearchBox">		
+		// |		<div id="scrollableView" data-dojo-type="dojox/mobile/ScrollableView">
+		// |	</div>
+
+		// Implementation notes:
+		// - The mixin requires dojox/mobile/ScrollableView statically. It could be required
+		// dynamically, only when needed, that is in the use-case when the mixin creates the 
+		// ScrollableView by itself. But this would create an usability trouble: if the user 
+		// would want to get the instance of ScrollableView in a dojo/ready (say, for configuring
+		// it), he would need to require it upfront, to cope with the case of asynchronous 
+		// loading. Thus, requiring it statically has been preferred, because it avoids this
+		// constraint on user's side and it is not a serious overhead, because in practice 
+		// the filtering is used for long lists, for which a ScrollableView is anyway likely 
+		// to be used. 
+		// - Differently, the loading of the store/data modules is performed dynamically,
+		// in order to avoid their overhead when they are not actually needed.
+		
+		// filterBoxRef: String
+		//		The reference for the search box allowing to enter the filtering criteria.
+		//		Only used at construction time:
+		//		- If unspecified, the mixin creates a dojox/mobile/SearchBox and 
+		//		a dojox/mobile/ScrollableView. The list is placed inside the ScrollableView and the
+		//		SearchBox, wrapped in a DIV, is placed on top of the ScrollableView.
+		//		- If the string is the id of a widget which is an instance of dojox/mobile/SearchBox 
+		//		or a subclass, the mixin uses this SearchBox for filtering the list.
+		//		- If the id is specified but does not reference a dojox/mobile/SearchBox or 
+		//		subclass, an error is thrown. 
+		filterBoxRef: null,
+		
+		// placeHolder: String
+		//		Defines a hint to help users fill out the input field (as defined in HTML 5) of the 
+		//		dojox/mobile/SearchBox. This should only contain plain text	(no HTML markup).
+		//		When the SearchBox is provided by the user (not created by this mixin), its placeHolder
+		//		property takes precedence.
+		placeHolder: "",
+		
+		// filterBoxVisible: Boolean
+		//		A flag which allows to show or hide the dojox/mobile/SearchBox associated with
+		//		the list.
+		filterBoxVisible: true,
+		
+		// _filterBox: [private] dojox/mobile/SearchBox
+		//		The instance of dojox/mobile/SearchBox used by this mixin. 
+		//		Stored for getFilterBox().
+		_filterBox: null,
+		
+		// _createdFilterBox: [private] dojox/mobile/SearchBox
+		//		The instance of dojox/mobile/SearchBox created by this mixin, or null if none
+		//		has been created. Stored for being able to destroy it together with the list widget.
+		_createdFilterBox: null,
+		
+		// _createdScrollableView: [private] dojox/mobile/ScrollableView
+		//		The instance of dojox/mobile/ScrollableView created by this mixin, if any. 
+		//		Stored for getScrollableView() and for being able to destroy it together 
+		//		with the list widget.
+		_createdScrollableView: null,
+		
+		startup: function(){
+			if(this._started){ return; }
+			
+			this.inherited(arguments);
+			
+			if(this.filterBoxRef){
+				// Case #1: search box provided by the user
+				this._filterBox = registry.byId(this.filterBoxRef);
+				
+				if (this._filterBox && this._filterBox.isInstanceOf(SearchBox)){ 
+					// If the list is backed by a dojox/mobile/_StoreListMixin, it
+					// has a labelProperty which is given precedence. 
+					this._filterBox.set("searchAttr", this.labelProperty ? this.labelProperty : "label");
+					if(!this._filterBox.placeHolder){
+						// Give precedence to the placeHolder that may be specified on the provided SearchBox
+						this._filterBox.set("placeHolder", this.placeHolder);
+					}
+					this._filterBox.on("search", lang.hitch(this, "_onFilter"));
+				}else{
+					throw new Error("Cannot find a widget of type dojox/mobile/SearchBox or subclass " +
+						"at the specified filterBoxRef: " + this.filterBoxRef);
+				}
+			}else{ 
+				// Case #2: automatic mode. The mixin creates a SearchBox and a ScrollableView.
+				this._filterBox =
+					new SearchBox({
+						// If the list is backed by a dojox/mobile/_StoreListMixin, it
+						// has a labelProperty which is given precedence. 
+						searchAttr: this.labelProperty ? this.labelProperty : "label",
+						ignoreCase: true,
+						incremental: true,
+						onSearch: lang.hitch(this, "_onFilter"),
+						selectOnClick: true,
+						placeHolder: this.placeHolder
+				});
+				
+				// Store them to be able to destroy them together with the list (see destroy()).
+				this._createdFilterBox = this._filterBox; 
+				this._createdScrollableView = new ScrollableView();
+				
+				var currentDomNode = this.domNode,
+					listParentNode = this.domNode.parentNode;
+				listParentNode.replaceChild(this._createdScrollableView.domNode, this.domNode);
+				// Put the list inside the ScrollableView:
+				domConstruct.place(currentDomNode, this._createdScrollableView.containerNode);
+				
+				var searchBoxParentDiv = domConstruct.create("div");
+				// Put the SearchBox as child of the DIV 
+				domConstruct.place(this._createdFilterBox.domNode, searchBoxParentDiv);
+				// Put the DIV as sibling of the ScrollableView: 
+				domConstruct.place(searchBoxParentDiv, this._createdScrollableView.domNode, "before");
+					
+				if(this.filterBoxClass){
+					// Only adding the class when the mixin creates the SearchBox by itself.
+					domClass.add(searchBoxParentDiv, this.filterBoxClass);
+				}
+					
+				this._createdFilterBox.startup();
+				this._createdScrollableView.startup();
+				this._createdScrollableView.resize();
+			}
+			
+			// Do not use this.getScrollableView() here, because this doesn't cover the
+			// use-case when the scrollable is not created by this mixin.
+			var sv = viewRegistry.getEnclosingScrollable(this.domNode);
+			if(sv){
+				this.connect(sv, "onFlickAnimationEnd", lang.hitch(this, function(){
+					if(!this._filterBox.focusNode.value){ // if search criteria is empty
+						// store the scroll position such that we can reset the 
+						// initial scroll when the user goes back to the unfiltered
+						// list (as done by some native mobile apps). 
+						this._previousUnfilteredScrollPos = sv.getPos();
+					}
+				}));
+			}
+			
+			if(!this.store){
+				this._createStore(this._initStore);
+			}else{
+				this._initStore();
+			}
+		},
+		
+		_setFilterBoxVisibleAttr: function(/* Boolean */ visible){
+			// tags:
+			//		private
+			this._set("filterBoxVisible", visible);
+			if (this._filterBox && this._filterBox.domNode){
+				this._filterBox.domNode.style.display = visible ? "" : "none";
+			}
+		},
+		
+		_setPlaceHolderAttr: function(/* String */ placeHolder){
+			// tags:
+			//		private
+			this._set("placeHolder", placeHolder);
+			if (this._filterBox){ // allow update after construction time
+				this._filterBox.set("placeHolder", placeHolder);
+			}
+		},
+		
+		getFilterBox: function(){
+			// summary:
+			//		Returns the dojox/mobile/SearchBox widget used for entering the filtering criteria.
+			//		If an instance has been referenced at construction time using the property filterBoxRef,
+			//		this instance is returned. Otherwise, returns the instance created by the mixin.
+			//		This function allows the user to get the instance of SearchBox in order to customize
+			//		its parameters. 
+			return this._filterBox;
+		},
+		
+		getScrollableView: function(){
+			// summary:
+			//		Returns the instance of dojox/mobile/ScrollableView created by this mixin,
+			//		or null if none has been created. The mixin creates a ScrollableView if and
+			//		only if the property filterBoxRef is unspecified.
+			//		This function allows the user to get the instance of ScrollableView in order to
+			//		customize its parameters.
+			return this._createdScrollableView;
+		},
+		
+		_initStore: function(){
+			// description:
+			//		Initializes the store.
+			// tags:
+			//		private
+			var store = this.store;
+			if(!store.get || !store.query){ // if old store (dojo/data)
+				// Detect the old dojo/data stores (since the stores don't actually extend a common
+				// base class, there is no direct way to do this check. Hence we rely on the presence 
+				// or absence of these two properties of the new stores which are required for the
+				// list widgets).
+				// TODO: to be removed when removing the support for lists backed by the old dojo/data 
+				// (EdgeToEdgeDataStore, RoundRectDataList).
+				require(["dojo/store/DataStore"], lang.hitch(this, function(DataStore){
+					// wrap the dojo/data store into a dojo/store
+					store = new DataStore({store: store});	
+					this._filterBox.store = store;				
+				}));
+			}else{
+				this._filterBox.store = store;
+			}
+		},
+	
+		_createStore: function(initStoreFunction/* Function */){
+			// summary:
+			//		Creates the store.
+			// description:
+			//		This method is used when the list is not backed by a store. In this case,
+			//		a store is created and filled with items containing the text of the list items.
+			// tags:
+			//		private
+			require(["./_StoreListMixin", "dojo/store/Memory"], lang.hitch(this, function(module, Memory){
+				declare.safeMixin(this, new module());
+					
+				this.append = true; // to avoid that _StoreListMixin.generateList destroys the items
+					
+				// _StoreListMixin.createListItem creates a new item. Instead, we want to reuse the
+				// original item instance, hence:
+				this.createListItem = function(/*Object*/item){
+					return item.listItem;
+				};
+					
+				aspect.before(this, "generateList", function(){
+					// remove all children
+					array.forEach(this.getChildren(), function(child){
+						child.domNode.parentNode.removeChild(child.domNode);
+					});
+				});
+					
+				// Collect the text from the list items
+				var items = [];
+				var text = null;
+				array.forEach(this.getChildren(), function(child){
+					text = child.label ? child.label : (child.domNode.innerText || child.domNode.textContent);
+					items.push({label: text, listItem: child});
+				});
+				var listData = {items: items};
+				// store for the dojox/mobile/EdgeToEdgeStoreList
+				var store = new Memory({idProperty:"label", data: listData});
+				this.store = null;
+				this.query = {};
+				this.setStore(store, this.query, this.queryOptions);
+				lang.hitch(this, initStoreFunction)();
+			}));
+		},
+		
+		_onFilter: function(results, query, options){
+			// summary:
+			//		Internal handler for filtering events.
+			// tags:
+			//		private
+			if(this.onFilter(results, query, options) === false){ return; } // user's filtering action
+			this.setQuery(query);
+			
+			// Do not use this.getScrollableView() because this doesn't cover the
+			// use-case when the scrollable is not created by this mixin.
+			var sv = viewRegistry.getEnclosingScrollable(this.domNode);
+			if(sv){
+				// When the user goes back to the unfiltered list, restore the previous 
+				// scroll position stored for unfiltered list (as done by some native mobile apps).
+				// Otherwise, reset the scroll position, to ensure that the new subset of 
+				// items is visible. 
+				sv.scrollTo(this._filterBox.focusNode.value ?
+					{x:0, y:0} :
+					this._previousUnfilteredScrollPos || {x:0, y:0});
+			}
+		},
+		
+		onFilter: function(/*===== results, query, options =====*/){
+			// summary:
+			//		User-defined function to handle filter actions. If the function returns false,
+			//		the filtering is cancelled.
+			// tags:
+			//		callback
+		},
+		
+		destroy: function(/*Boolean?*/ preserveDom){
+			// summary:
+			//		Destroys the widget. If the list has created dojox/mobile/SearchBox 
+			//		or dojox/mobile/ScrollableView widgets, these widgets are also destroyed.
+			// preserveDom: Boolean
+			//		If true, this method will leave the original DOM structure alone.
+		
+			this.inherited(arguments);
+			
+			// Only destroy widgets created (thus, owned) by this mixin (if any).
+			if(this._createdFilterBox){ 
+				this._createdFilterBox.destroy(preserveDom);
+				this._createdFilterBox = null;
+			}
+			if(this._createdScrollableView){ 
+				this._createdScrollableView.destroy(preserveDom);
+				this._createdScrollableView = null;
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/FixedSplitter.js b/dojox/mobile/FixedSplitter.js
index 88271f1..477f5e7 100644
--- a/dojox/mobile/FixedSplitter.js
+++ b/dojox/mobile/FixedSplitter.js
@@ -7,19 +7,11 @@ define([
 	"dijit/_Contained",
 	"dijit/_Container",
 	"dijit/_WidgetBase",
-	"./FixedSplitterPane"
-], function(array, declare, win, domClass, domGeometry, Contained, Container, WidgetBase, FixedSplitterPane){
-
-/*=====
-	var Contained = dijit._Contained;
-	var Container = dijit._Container;
-	var WidgetBase = dijit._WidgetBase;
-=====*/
+	"dojo/has"
+], function(array, declare, win, domClass, domGeometry, Contained, Container, WidgetBase, has){
 
 	// module:
 	//		dojox/mobile/FixedSplitter
-	// summary:
-	//		A layout container that splits the window horizontally or vertically.
 
 	return declare("dojox.mobile.FixedSplitter", [WidgetBase, Container, Contained], {
 		// summary:
@@ -27,69 +19,100 @@ define([
 		//		vertically.
 		// description:
 		//		FixedSplitter is a very simple container widget that layouts its
-		//		child dom nodes side by side either horizontally or
+		//		child DOM nodes side by side either horizontally or
 		//		vertically. An example usage of this widget would be to realize
 		//		the split view on iPad. There is no visual splitter between the
 		//		children, and there is no function to resize the child panes
 		//		with drag-and-drop. If you need a visual splitter, you can
-		//		specify a border of a child dom node with CSS.
-		//		A child of the widget should be FixedSplitterPane.
+		//		specify a border of a child DOM node with CSS.
+		//
+		//		FixedSplitter has no knowledge of its child widgets.
+		//		dojox/mobile/Container, dojox/mobile/Pane, or dojox/mobile/ContentPane 
+		//		can be used as a child widget of FixedSplitter.
+		//
+		//		- Use dojox/mobile/Container if your content consists of ONLY
+		//		  Dojo widgets.
+		//		- Use dojox/mobile/Pane if your content is an inline HTML
+		//		  fragment (may or may not include Dojo widgets).
+		//		- Use dojox/mobile/ContentPane if your content is an external
+		//		  HTML fragment (may or may not include Dojo widgets).
 		//
 		// example:
-		// |	<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
-		// |		<div dojoType="dojox.mobile.FixedSplitterPane"
-		// |			style="width:200px;border-right:1px solid black;">
-		// |			pane #1 (width=200px)
-		// |		</div>
-		// |		<div dojoType="dojox.mobile.FixedSplitterPane">
-		// |			pane #2
-		// |		</div>
-		// |	</div>
+		//	|	<div data-dojo-type="dojox.mobile.FixedSplitter" orientation="H">
+		//	|		<div data-dojo-type="dojox.mobile.Pane"
+		//	|			style="width:200px;border-right:1px solid black;">
+		//	|			pane #1 (width=200px)
+		//	|		</div>
+		//	|		<div data-dojo-type="dojox.mobile.Pane">
+		//	|			pane #2
+		//	|		</div>
+		//	|	</div>
 
 		// orientation: String
 		//		The direction of split. If "H" is specified, panes are split
 		//		horizontally. If "V" is specified, panes are split vertically.
 		orientation: "H",
 
+		// variablePane: Number
+		//		The index of a pane that fills the remainig space.
+		//		If -1, the last child pane fills the remaining space.
+		variablePane: -1,
 
-		buildRendering: function(){
-			this.domNode = this.containerNode = this.srcNodeRef ? this.srcNodeRef : win.doc.createElement("DIV");
-			domClass.add(this.domNode, "mblFixedSpliter");
-		},
+		// screenSizeAware: Boolean
+		//		If true, dynamically load a screen-size-aware module.
+		screenSizeAware: false,
+
+		// screenSizeAwareClass: String
+		//		A screen-size-aware module to load.
+		screenSizeAwareClass: "dojox/mobile/ScreenSizeAware",
+
+		/* internal properties */
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblFixedSplitter",
 
 		startup: function(){
 			if(this._started){ return; }
-			var children = array.filter(this.domNode.childNodes, function(node){ return node.nodeType == 1; });
-			array.forEach(children, function(node){
-				domClass.add(node, "mblFixedSplitterPane"+this.orientation);
-			}, this);
+			domClass.add(this.domNode, this.baseClass + this.orientation);
+
+			var parent = this.getParent(), f;
+			if(!parent || !parent.resize){ // top level widget
+				var _this = this;
+				f = function(){
+					_this.defer(function(){
+						_this.resize();
+					});
+				};
+			}
+
+			if(this.screenSizeAware){
+				require([this.screenSizeAwareClass], function(module){
+					module.getInstance();
+					f && f();
+				});
+			}else{
+				f && f();
+			}
+
 			this.inherited(arguments);
-	
-			var _this = this;
-			setTimeout(function(){
-				var parent = _this.getParent && _this.getParent();
-				if(!parent || !parent.resize){ // top level widget
-					_this.resize();
-				}
-			}, 0);
-		},
-	
-		resize: function(){
-			this.layout();
 		},
 
-		layout: function(){
-			var sz = this.orientation == "H" ? "w" : "h";
-			var children = array.filter(this.domNode.childNodes, function(node){ return node.nodeType == 1; });
-			var offset = 0;
-			for(var i = 0; i < children.length; i++){
-				domGeometry.setMarginBox(children[i], this.orientation == "H" ? {l:offset} : {t:offset});
-				if(i < children.length - 1){
-					offset += domGeometry.getMarginBox(children[i])[sz];
+		resize: function(){
+			var wh = this.orientation === "H" ? "w" : "h", // width/height
+				tl = this.orientation === "H" ? "l" : "t", // top/left
+				props1 = {}, props2 = {},
+				i, c, h,
+				a = [], offset = 0, total = 0,
+				children = array.filter(this.domNode.childNodes, function(node){ return node.nodeType == 1; }),
+				idx = this.variablePane == -1 ? children.length - 1 : this.variablePane;
+			for(i = 0; i < children.length; i++){
+				if(i != idx){
+					a[i] = domGeometry.getMarginBox(children[i])[wh];
+					total += a[i];
 				}
 			}
-	
-			var h;
+
 			if(this.orientation == "V"){
 				if(this.domNode.parentNode.tagName == "BODY"){
 					if(array.filter(win.body().childNodes, function(node){ return node.nodeType == 1; }).length == 1){
@@ -97,19 +120,51 @@ define([
 					}
 				}
 			}
-			var l = (h || domGeometry.getMarginBox(this.domNode)[sz]) - offset;
-			var props = {};
-			props[sz] = l;
-			domGeometry.setMarginBox(children[children.length - 1], props);
-	
+			var l = (h || domGeometry.getMarginBox(this.domNode)[wh]) - total;
+			props2[wh] = a[idx] = l;
+			c = children[idx];
+			domGeometry.setMarginBox(c, props2);
+			c.style[this.orientation === "H" ? "height" : "width"] = "";
+			// dojox.mobile mirroring support
+			if(has("dojo-bidi") && (this.orientation=="H" && !this.isLeftToRight())){
+				offset = l;
+				for(i = children.length - 1; i >= 0; i--){
+					c = children[i];
+					props1[tl] = l - offset;
+					domGeometry.setMarginBox(c, props1);
+					c.style[this.orientation === "H" ? "top" : "left"] = "";
+					offset -= a[i];
+				}
+			}else{
+				for(i = 0; i < children.length; i++){
+					c = children[i];
+					props1[tl] = offset;
+					domGeometry.setMarginBox(c, props1);
+					c.style[this.orientation === "H" ? "top" : "left"] = "";
+					offset += a[i];
+				}
+			}
+
 			array.forEach(this.getChildren(), function(child){
 				if(child.resize){ child.resize(); }
 			});
 		},
 
-		addChild: function(widget, /*Number?*/insertIndex){
-			domClass.add(widget.domNode, "mblFixedSplitterPane"+this.orientation);
-			this.inherited(arguments);
+		_setOrientationAttr: function(/*String*/orientation){
+			// summary:
+			//		Sets the direction of split.
+			// description:
+			//		The value must be either "H" or "V".
+			//		If "H" is specified, panes are split horizontally.
+			//		If "V" is specified, panes are split vertically.
+			// tags:
+			//		private
+			var s = this.baseClass;
+			domClass.replace(this.domNode, s + orientation, s + this.orientation);
+			this.orientation = orientation;
+			if(this._started){
+				this.resize();
+			}
 		}
 	});
 });
diff --git a/dojox/mobile/FixedSplitterPane.js b/dojox/mobile/FixedSplitterPane.js
index 2490bf0..abca10e 100644
--- a/dojox/mobile/FixedSplitterPane.js
+++ b/dojox/mobile/FixedSplitterPane.js
@@ -1,40 +1,18 @@
 define([
-	"dojo/_base/array",
+	"dojo/_base/kernel",
 	"dojo/_base/declare",
-	"dojo/dom-class",
-	"dijit/_Contained",
-	"dijit/_Container",
-	"dijit/_WidgetBase"
-], function(array, declare, domClass, Contained, Container, WidgetBase){
+	"./Container"
+], function(kernel, declare, Container){
 
-/*=====
-	var Contained = dijit._Contained;
-	var Container = dijit._Container;
-	var WidgetBase = dijit._WidgetBase;
-=====*/
+	kernel.deprecated("dojox/mobile/FixedSplitterPane", "Use dojox/mobile/Container instead", 2.0);
 
 	// module:
 	//		dojox/mobile/FixedSplitterPane
-	// summary:
-	//		A pane widget that is used in a dojox.mobile.FixedSplitter.
 
-	return declare("dojox.mobile.FixedSplitterPane",[WidgetBase, Container, Contained],{
+	return declare("dojox.mobile.FixedSplitterPane", Container, {
 		// summary:
-		//		A pane widget that is used in a dojox.mobile.FixedSplitter.
-		// description:
-		//		FixedSplitterPane is a pane widget that is used in a
-		//		dojox.mobile.FixedSplitter. It is a widget, but can be regarded
-		//		as a simple <div> element.
+		//		Deprecated widget. Use dojox/mobile/Container instead.
 
-		buildRendering: function(){
-			this.inherited(arguments);
-			domClass.add(this.domNode, "mblFixedSplitterPane");
-		},
-
-		resize: function(){
-			array.forEach(this.getChildren(), function(child){
-				if(child.resize){ child.resize(); }
-			});
-		}
+		baseClass: "mblFixedSplitterPane"
 	});
 });
diff --git a/dojox/mobile/FlippableView.js b/dojox/mobile/FlippableView.js
deleted file mode 100644
index 48b8329..0000000
--- a/dojox/mobile/FlippableView.js
+++ /dev/null
@@ -1,8 +0,0 @@
-define([
-	"dojo/_base/kernel",
-	"dojox/mobile/SwapView"
-], function(kernel, SwapView){
-	kernel.deprecated("dojox.mobile.FlippableView is deprecated", "dojox.mobile.FlippableView moved to dojox.mobile.SwapView", 1.7);
-	dojox.mobile.FlippableView = SwapView;
-	return SwapView;
-});
diff --git a/dojox/mobile/FormLayout.js b/dojox/mobile/FormLayout.js
new file mode 100644
index 0000000..fa4e472
--- /dev/null
+++ b/dojox/mobile/FormLayout.js
@@ -0,0 +1,81 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"./Container"
+], function(declare, domClass, Container){
+
+	// module:
+	//		dojox/mobile/FormLayout
+
+	return declare("dojox.mobile.FormLayout", Container, {
+		// summary:
+		//		A responsive container to create mobile forms.
+		// description:
+		//		This container layouts form widgets according to the screen size.
+		//		Each row of a form is made of a <label> and a <fieldset> that contains one or more form widgets.
+		//		By default, if the width of the screen if greater than 500px, the <label> and the <fieldset> are positioned on the same line.
+		//		Otherwise they are stacked vertically. You can force how a <label> and its <fieldset> are positioned using the
+		//		'columns' property.
+		//		Form controls are: "dojox/mobile/Button", "dojox/mobile/CheckBox", "dojox/mobile/ComboBox",
+		//		"dojox/mobile/RadioButton", "dojox/mobile/Slider", "dojox/mobile/TextBox", "dojox/mobile/SearchBox",
+		//		"dojox/mobile/ExpandingTextArea", "dojox/mobile/ToggleButton".
+		// example:
+		// |	<div data-dojo-type="dojox/mobile/FormLayout" data-dojo-props="columns:'two', rightAlign:true">
+		// |		<div>
+		// |			<label>Name:</label>
+		// |			<fieldset>
+		// |				<input data-dojo-type="dojox/mobile/TextBox">
+		// |			</fieldset>
+		// |		</div>
+		// |		<div>
+		// |			<label>Make a choice:</label>
+		// |			<fieldset>
+		// |				<input type="radio" id="rb1" data-dojo-type="dojox/mobile/RadioButton" name="mobileRadio" checked><label for="rb1">Small</label>
+		// |				<input type="radio" id="rb2" data-dojo-type="dojox/mobile/RadioButton" name="mobileRadio" checked><label for="rb2">Medium</label>
+		// |				<input type="radio" id="rb3" data-dojo-type="dojox/mobile/RadioButton" name="mobileRadio" checked><label for="rb3">Large</label>
+		// |			</fieldset>
+		// |		</div>
+		// |	</div>
+
+
+		// columns: [const] "auto" | "single" | "two"
+		//		This property controls how a <label> and its <fieldset> are positioned. The <label> can be on the same line
+		//		than its <fieldset> (two columns) or on top of it (single column).
+		//		If set to "auto", the number of columns depends on the width of the screen: Two columns
+		//		if the width of the screen is larger than 500px, one column otherwise. The width of the screen is determined using CSS
+		//		Media Queries.
+		//		Setting this property to "single" or "two" allows to force the layout used whatever the width of the screen.
+		//		Default value for this property is "auto".
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		columns: "auto",
+
+		// rightAlign: [const] Boolean
+		//		This property controls the horizontal position of control(s) in a <fieldset>. It applies only
+		//		to forms that have two columns (see 'columns' property).
+		//		Default value for this property is false.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		rightAlign: false,
+
+		/* internal properties */
+
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblFormLayout",
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(this.columns == "auto"){
+				domClass.add(this.domNode, "mblFormLayoutAuto");
+			}else if(this.columns == "single"){
+				domClass.add(this.domNode, "mblFormLayoutSingleCol");
+			}else if(this.columns == "two"){
+				domClass.add(this.domNode, "mblFormLayoutTwoCol");
+			}
+			if(this.rightAlign){
+				domClass.add(this.domNode, "mblFormLayoutRightAlign");
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/GridLayout.js b/dojox/mobile/GridLayout.js
new file mode 100644
index 0000000..91506a1
--- /dev/null
+++ b/dojox/mobile/GridLayout.js
@@ -0,0 +1,32 @@
+define([
+	"dojo/_base/declare",
+	"./IconMenu"
+], function(declare, IconMenu){
+	// module:
+	//		dojox/mobile/GridLayout
+
+	return declare("dojox.mobile.GridLayout", IconMenu, {
+		// summary:
+		//		A container widget that places its children in a grid layout.
+
+		// cols: Number
+		//		The number of child items in a row.
+		cols: 0,
+
+		/* internal properties */
+		
+		// childItemClass: String
+		//		The name of the CSS class of grid items.
+		childItemClass: "mblGridItem",
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblGridLayout",
+		
+		// _tags: [private] String
+		_tags: "div",
+		
+		// _createTerminator: [private] Boolean
+		_createTerminator: true
+	});
+});
diff --git a/dojox/mobile/Heading.js b/dojox/mobile/Heading.js
index 52c786a..c39bcd2 100644
--- a/dojox/mobile/Heading.js
+++ b/dojox/mobile/Heading.js
@@ -4,30 +4,28 @@ define([
 	"dojo/_base/declare",
 	"dojo/_base/lang",
 	"dojo/_base/window",
+	"dojo/dom",
 	"dojo/dom-class",
 	"dojo/dom-construct",
 	"dojo/dom-style",
-	"dijit/registry",	// registry.byId
+	"dojo/dom-attr",
+	"dijit/registry",
 	"dijit/_Contained",
 	"dijit/_Container",
 	"dijit/_WidgetBase",
-	"./View"
-], function(array, connect, declare, lang, win, domClass, domConstruct, domStyle, registry, Contained, Container, WidgetBase, View){
-
-	var dm = lang.getObject("dojox.mobile", true);
-
-/*=====
-	var Contained = dijit._Contained;
-	var Container = dijit._Container;
-	var WidgetBase = dijit._WidgetBase;
-=====*/
+	"./ProgressIndicator",
+	"./ToolBarButton",
+	"./View",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/Heading"
+], function(array, connect, declare, lang, win, dom, domClass, domConstruct, domStyle, domAttr, registry, Contained, Container, WidgetBase, ProgressIndicator, ToolBarButton, View, has, BidiHeading){
 
 	// module:
 	//		dojox/mobile/Heading
-	// summary:
-	//		A widget that represents a navigation bar.
 
-	return declare("dojox.mobile.Heading", [WidgetBase, Container, Contained],{
+	var dm = lang.getObject("dojox.mobile", true);
+
+	var Heading = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiHeading" : "dojox.mobile.Heading", [WidgetBase, Container, Contained],{
 		// summary:
 		//		A widget that represents a navigation bar.
 		// description:
@@ -35,15 +33,14 @@ define([
 		//		usually appears at the top of an application. It usually
 		//		displays the title of the current view and can contain a
 		//		navigational control. If you use it with
-		//		dojox.mobile.ScrollableView, it can also be used as a fixed
+		//		dojox/mobile/ScrollableView, it can also be used as a fixed
 		//		header bar or a fixed footer bar. In such cases, specify the
 		//		fixed="top" attribute to be a fixed header bar or the
 		//		fixed="bottom" attribute to be a fixed footer bar. Heading can
 		//		have one or more ToolBarButton widgets as its children.
 
 		// back: String
-		//		A label for the navigational control to return to the previous
-		//		View.
+		//		A label for the navigational control to return to the previous View.
 		back: "",
 
 		// href: String
@@ -51,12 +48,10 @@ define([
 		href: "",
 
 		// moveTo: String
-		//		The id of the transition destination view which resides in the
-		//		current page.
-		//
+		//		The id of the transition destination of the navigation control.
 		//		If the value has a hash sign ('#') before the id (e.g. #view1)
-		//		and the dojo.hash module is loaded by the user application, the
-		//		view transition updates the hash in the browser URL so that the
+		//		and the dojox/mobile/bookmarkable module is loaded by the user application,
+		//		the view transition updates the hash in the browser URL so that the
 		//		user can bookmark the destination view. In this case, the user
 		//		can also use the browser's back/forward button to navigate
 		//		through the views in the browser history.
@@ -70,8 +65,8 @@ define([
 		//		standard transition types, "slide", "fade", "flip", or from the
 		//		extended transition types, "cover", "coverv", "dissolve",
 		//		"reveal", "revealv", "scaleIn", "scaleOut", "slidev",
-		//		"swirl", "zoomIn", "zoomOut". If "none" is specified, transition
-		//		occurs immediately without animation.
+		//		"swirl", "zoomIn", "zoomOut", "cube", and "swap". If "none" is
+		//		specified, transition occurs immediately without animation.
 		transition: "slide",
 
 		// label: String
@@ -83,36 +78,59 @@ define([
 		//		The default icon path for child items.
 		iconBase: "",
 
-		// backProp: Object
-		//		Properties for the back button.
-		backProp: {className: "mblArrowButton"},
-
 		// tag: String
-		//		A name of html tag to create as domNode.
-		tag: "H1",
+		//		A name of HTML tag to create as domNode.
+		tag: "h1",
+
+		// busy: Boolean
+		//		If true, a progress indicator spins on this widget.
+		busy: false,
+
+		// progStyle: String
+		//		A css class name to add to the progress indicator.
+		progStyle: "mblProgWhite",
+
+		/* internal properties */
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.	
+		baseClass: "mblHeading",
 
 		buildRendering: function(){
-			this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement(this.tag);
-			this.domNode.className = "mblHeading";
-			if(!this.label){
-				array.forEach(this.domNode.childNodes, function(n){
-					if(n.nodeType == 3){
-						var v = lang.trim(n.nodeValue);
-						if(v){
-							this.label = v;
-							this.labelNode = domConstruct.create("SPAN", {innerHTML:v}, n, "replace");
+			if(!this.templateString){ // true if this widget is not templated
+				// Create root node if it wasn't created by _TemplatedMixin
+				this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement(this.tag);
+			}
+			this.inherited(arguments);
+			
+			if(!this.templateString){ // true if this widget is not templated
+				if(!this.label){
+					array.forEach(this.domNode.childNodes, function(n){
+						if(n.nodeType == 3){
+							var v = lang.trim(n.nodeValue);
+							if(v){
+								this.label = v;
+								this.labelNode = domConstruct.create("span", {innerHTML:v}, n, "replace");
+							}
 						}
-					}
-				}, this);
+					}, this);
+				}
+				if(!this.labelNode){
+					this.labelNode = domConstruct.create("span", null, this.domNode);
+				}
+				this.labelNode.className = "mblHeadingSpanTitle";
+				this.labelDivNode = domConstruct.create("div", {
+					className: "mblHeadingDivTitle",
+					innerHTML: this.labelNode.innerHTML
+				}, this.domNode);
 			}
-			if(!this.labelNode){
-				this.labelNode = domConstruct.create("SPAN", null, this.domNode);
+
+			if(this.labelDivNode){
+				domAttr.set(this.labelDivNode, "role", "heading"); //a11y
+				domAttr.set(this.labelDivNode, "aria-level", "1");
 			}
-			this.labelNode.className = "mblHeadingSpanTitle";
-			this.labelDivNode = domConstruct.create("DIV", {
-				className: "mblHeadingDivTitle",
-				innerHTML: this.labelNode.innerHTML
-			}, this.domNode);
+
+			dom.setSelectable(this.domNode, false);
 		},
 
 		startup: function(){
@@ -120,17 +138,14 @@ define([
 			var parent = this.getParent && this.getParent();
 			if(!parent || !parent.resize){ // top level widget
 				var _this = this;
-				setTimeout(function(){ // necessary to render correctly
+				_this.defer(function(){ // necessary to render correctly
 					_this.resize();
-				}, 0);
+				});
 			}
 			this.inherited(arguments);
 		},
-	
+
 		resize: function(){
-			if(this._btn){
-				this._btn.style.width = this._body.offsetWidth + this._head.offsetWidth + "px";
-			}
 			if(this.labelNode){
 				// find the rightmost left button (B), and leftmost right button (C)
 				// +-----------------------------+
@@ -140,11 +155,11 @@ define([
 				var children = this.containerNode.childNodes;
 				for(var i = children.length - 1; i >= 0; i--){
 					var c = children[i];
-					if(c.nodeType === 1){
-						if(!rightBtn && domClass.contains(c, "mblToolBarButton") && domStyle.get(c, "float") === "right"){
+					if(c.nodeType === 1 && domStyle.get(c, "display") !== "none"){
+						if(!rightBtn && domStyle.get(c, "float") === "right"){
 							rightBtn = c;
 						}
-						if(!leftBtn && (domClass.contains(c, "mblToolBarButton") && domStyle.get(c, "float") === "left" || c === this._btn)){
+						if(!leftBtn && domStyle.get(c, "float") === "left"){
 							leftBtn = c;
 						}
 					}
@@ -168,99 +183,80 @@ define([
 		},
 
 		_setBackAttr: function(/*String*/back){
-			if (!back){
-				domConstruct.destroy(this._btn);
-				this._btn = null;
-				this.back = "";
+			// tags:
+			//		private
+			this._set("back", back);
+			if(!this.backButton){
+				this.backButton = new ToolBarButton({
+					arrow: "left",
+					label: back,
+					moveTo: this.moveTo,
+					back: !this.moveTo && !this.href, // use browser history unless moveTo or href
+					href: this.href,
+					transition: this.transition,
+					transitionDir: -1,
+					dir: this.isLeftToRight() ? "ltr" : "rtl"
+				});
+				this.backButton.placeAt(this.domNode, "first");
 			}else{
-				if(!this._btn){
-					var btn = domConstruct.create("DIV", this.backProp, this.domNode, "first");
-					var head = domConstruct.create("DIV", {className:"mblArrowButtonHead"}, btn);
-					var body = domConstruct.create("DIV", {className:"mblArrowButtonBody mblArrowButtonText"}, btn);
-
-					this._body = body;
-					this._head = head;
-					this._btn = btn;
-					this.backBtnNode = btn;
-					this.connect(body, "onclick", "onClick");
-				}
-				this.back = back;
-				this._body.innerHTML = this._cv ? this._cv(this.back) : this.back;
+				this.backButton.set("label", back);
 			}
 			this.resize();
 		},
-	
-		_setLabelAttr: function(/*String*/label){
-			this.label = label;
-			this.labelNode.innerHTML = this.labelDivNode.innerHTML = this._cv ? this._cv(label) : label;
+		
+		_setMoveToAttr: function(/*String*/moveTo){
+			// tags:
+			//		private
+			this._set("moveTo", moveTo);
+			if(this.backButton){
+				this.backButton.set("moveTo", moveTo);
+				this.backButton.set("back", !moveTo && !this.href);
+			}
 		},
-	
-		findCurrentView: function(){
-			// summary:
-			//		Search for the view widget that contains this widget.
-			var w = this;
-			while(true){
-				w = w.getParent();
-				if(!w){ return null; }
-				if(w instanceof View){ break; }
+		
+		_setHrefAttr: function(/*String*/href){
+			// tags:
+			//		private
+			this._set("href", href);
+			if(this.backButton){
+				this.backButton.set("href", href);
+				this.backButton.set("back", !this.moveTo && !href);
 			}
-			return w;
 		},
-
-		onClick: function(e){
-			var h1 = this.domNode;
-			domClass.add(h1, "mblArrowButtonSelected");
-			setTimeout(function(){
-				domClass.remove(h1, "mblArrowButtonSelected");
-			}, 1000);
-
-			if(this.back && !this.moveTo && !this.href && history){
-				history.back();	
-				return;
-			}	
-	
-			// keep the clicked position for transition animations
-			var view = this.findCurrentView();
-			if(view){
-				view.clickedPosX = e.clientX;
-				view.clickedPosY = e.clientY;
+		
+		_setTransitionAttr: function(/*String*/transition){
+			// tags:
+			//		private
+			this._set("transition", transition);
+			if(this.backButton){
+				this.backButton.set("transition", transition);
 			}
-			this.goTo(this.moveTo, this.href);
 		},
-	
-		goTo: function(moveTo, href){
-			// summary:
-			//		Given the destination, makes a view transition.
-			var view = this.findCurrentView();
-			if(!view){ return; }
-			if(href){
-				view.performTransition(null, -1, this.transition, this, function(){location.href = href;});
-			}else{
-				if(dm.app && dm.app.STAGE_CONTROLLER_ACTIVE){
-					// If in a full mobile app, then use its mechanisms to move back a scene
-					connect.publish("/dojox/mobile/app/goback");
-				}else{
-					// Basically transition should be performed between two
-					// siblings that share the same parent.
-					// However, when views are nested and transition occurs from
-					// an inner view, search for an ancestor view that is a sibling
-					// of the target view, and use it as a source view.
-					var node = registry.byId(view.convertToId(moveTo));
-					if(node){
-						var parent = node.getParent();
-						while(view){
-							var myParent = view.getParent();
-							if(parent === myParent){
-								break;
-							}
-							view = myParent;
-						}
-					}
-					if(view){
-						view.performTransition(moveTo, -1, this.transition);
-					}
+		
+		_setLabelAttr: function(/*String*/label){
+			// tags:
+			//		private
+			this._set("label", label);
+			this.labelNode.innerHTML = this.labelDivNode.innerHTML = this._cv ? this._cv(label) : label;
+		},
+
+		_setBusyAttr: function(/*Boolean*/busy){
+			// tags:
+			//		private
+			var prog = this._prog;
+			if(busy){
+				if(!prog){
+					prog = this._prog = new ProgressIndicator({size:30, center:false});
+					domClass.add(prog.domNode, this.progStyle);
 				}
+				domConstruct.place(prog.domNode, this.domNode, "first");
+				prog.start();
+			}else if(prog){
+				prog.stop();
 			}
-		}
+			this._set("busy", busy);
+		}	
 	});
+
+	return has("dojo-bidi") ? declare("dojox.mobile.Heading", [Heading, BidiHeading]) : Heading;
 });
diff --git a/dojox/mobile/Icon.js b/dojox/mobile/Icon.js
new file mode 100644
index 0000000..a7e30c6
--- /dev/null
+++ b/dojox/mobile/Icon.js
@@ -0,0 +1,72 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"./iconUtils"
+], function(declare, lang, domClass, domConstruct, iconUtils){
+
+	// module:
+	//		dojox/mobile/Icon
+
+	return declare("dojox.mobile.Icon", null, {
+		// summary:
+		//		A wrapper for image icon, CSS sprite icon, or DOM Button.
+		// description:
+		//		Icon is a simple utility class for creating an image icon, a CSS sprite icon, 
+		//		or a DOM Button. It calls dojox/mobile/iconUtils.createIcon() with the 
+		//		appropriate parameters to create an icon. 
+		//		Note that this module is not a widget, that is it does not inherit 
+		//		from dijit/_WidgetBase.
+		// example:
+		//		Image icon:
+		//	|	<div data-dojo-type="dojox.mobile.Icon"
+		//	|		data-dojo-props='icon:"images/tab-icon-12h.png"'></div>
+		//
+		//		CSS sprite icon:
+		//	|	<div data-dojo-type="dojox.mobile.Icon"
+		//	|		data-dojo-props='icon:"images/tab-icons.png",iconPos:"29,116,29,29"'></div>
+		//
+		//		DOM Button:
+		//	|	<div data-dojo-type="dojox.mobile.Icon"
+		//	|		data-dojo-props='icon:"mblDomButtonBlueCircleArrow"'></div>
+
+		// icon: [const] String
+		//		An icon to display. The value can be either a path for an image
+		//		file or a class name of a DOM button.
+		//		Note that changing the value of the property after the icon
+		//		creation has no effect.
+		icon: "",
+
+		// iconPos: [const] String
+		//		The position of an aggregated icon. IconPos is comma separated
+		//		values like top,left,width,height (ex. "0,0,29,29").
+		//		Note that changing the value of the property after the icon
+		//		creation has no effect.
+		iconPos: "",
+
+		// alt: [const] String
+		//		An alt text for the icon image.
+		//		Note that changing the value of the property after the icon
+		//		creation has no effect.
+		alt: "",
+
+		// tag: String
+		//		The name of the HTML tag to create as this.domNode.
+		tag: "div",
+
+		constructor: function(/*Object?*/args, /*DomNode?*/node){
+			// summary:
+			//		Creates a new instance of the class.
+			// args:
+			//		Contains properties to be set.
+			// node:
+			//		The DOM node. If none is specified, it is automatically created. 
+			if(args){
+				lang.mixin(this, args);
+			}
+			this.domNode = node || domConstruct.create(this.tag);
+			iconUtils.createIcon(this.icon, this.iconPos, null, this.alt, this.domNode);
+		}
+	});
+});
diff --git a/dojox/mobile/IconContainer.js b/dojox/mobile/IconContainer.js
index 3e968a2..ed7e173 100644
--- a/dojox/mobile/IconContainer.js
+++ b/dojox/mobile/IconContainer.js
@@ -1,53 +1,48 @@
 define([
 	"dojo/_base/array",
 	"dojo/_base/declare",
+	"dojo/_base/lang",
 	"dojo/_base/window",
 	"dojo/dom-construct",
-	"dojo/dom-style",
-	"dijit/registry",	// registry.byNode
 	"dijit/_Contained",
 	"dijit/_Container",
 	"dijit/_WidgetBase",
-	"./IconItem",
+	"./IconItem", // to load IconItem for you (no direct references)
 	"./Heading",
 	"./View"
-], function(array, declare, win, domConstruct, domStyle, registry, Contained, Container, WidgetBase, IconItem, Heading, View){
-
-/*=====
-	var Contained = dijit._Contained;
-	var Container = dijit._Container;
-	var WidgetBase = dijit._WidgetBase;
-=====*/
+], function(array, declare, lang, win, domConstruct, Contained, Container, WidgetBase, IconItem, Heading, View){
 
 	// module:
 	//		dojox/mobile/IconContainer
-	// summary:
-	//		A container widget that holds multiple icons.
 
 	return declare("dojox.mobile.IconContainer", [WidgetBase, Container, Contained],{
 		// summary:
-		//		A container widget that holds multiple icons.
+		//		A container widget which can hold multiple icons.
 		// description:
-		//		IconContainer is a container widget that holds multiple icons
-		//		each of which represents application component.
+		//		IconContainer is a container widget which can hold multiple
+		//		icons. Each icon must be a subclass of dojox/mobile/IconItem
+		//		and can be associated with a panel which opens when touching
+		//		the icon.
 
 		// defaultIcon: String
-		//		The default fall-back icon, which is displayed only when the
+		//		The default fallback icon, which is displayed only when the
 		//		specified icon has failed to load.
 		defaultIcon: "",
 
-		// transition: String
+		// transition: [const] String
 		//		A type of animated transition effect. You can choose from the
-		//		standard transition types, "slide", "fade", "flip", or from the
-		//		extended transition types, "cover", "coverv", "dissolve",
+		//		standard transition types: "slide", "fade", "flip", or from the
+		//		extended transition types: "cover", "coverv", "dissolve",
 		//		"reveal", "revealv", "scaleIn", "scaleOut", "slidev",
-		//		"swirl", "zoomIn", "zoomOut". If "none" is specified, transition
-		//		occurs immediately without animation. If "below" is specified,
-		//		the application contents are displayed below the icons.
+		//		"swirl", "zoomIn", "zoomOut", "cube", and "swap". If "none" is
+		//		specified, the transition occurs immediately without animation. If
+		//		"below" is specified, the application contents are displayed
+		//		below the icons. The default value is "below". Note that changing 
+		//		the value of the property after the widget creation has no effect.
 		transition: "below",
 
 		// pressedIconOpacity: Number
-		//		The opacity of the pressed icon image.
+		//		The opacity of the pressed icon image. The default value is 0.4.
 		pressedIconOpacity: 0.4,
 
 		// iconBase: String
@@ -70,115 +65,114 @@ define([
 		//		If true, only one icon content can be opened at a time.
 		single: false,
 
+		// editable: [const] Boolean
+		//		If true, the icons can be removed or reordered. You can enter
+		//		into edit mode by pressing on a child IconItem until it starts shaking.
+		//		The default value is false. Note that changing the value of the property after
+		//		the widget creation has no effect.
+		editable: false,
+
+		// tag: String
+		//		A name of html tag to create as domNode.
+		tag: "ul",
+
+		/* internal properties */	
+		baseClass: "mblIconContainer",
+		editableMixinClass: "dojox/mobile/_EditableIconMixin",
+		iconItemPaneContainerClass: "dojox/mobile/Container",
+		iconItemPaneContainerProps: null,
+		iconItemPaneClass: "dojox/mobile/_IconItemPane",
+		iconItemPaneProps: null,
+
 		buildRendering: function(){
-			this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("UL");
-			this.domNode.className = "mblIconContainer";
-			var t = this._terminator = domConstruct.create("LI");
-			t.className = "mblIconItemTerminator";
-			t.innerHTML = " ";
-			this.domNode.appendChild(t);
+			this.domNode = this.containerNode = this.srcNodeRef || domConstruct.create(this.tag);
+			// _terminator is used to apply the clear:both style to terminate floating icons.
+			this._terminator = domConstruct.create(this.tag === "ul" ? "li" : "div",
+				{className:"mblIconItemTerminator"}, this.domNode);
+			this.inherited(arguments);
 		},
 
-		_setupSubNodes: function(ul){
-			array.forEach(this.getChildren(), function(w){
-				ul.appendChild(w.subNode);
-			});
+		postCreate: function(){
+			if(this.editable && !this.startEdit){ // if editable is true but editableMixinClass is not inherited
+				require([this.editableMixinClass], lang.hitch(this, function(module){
+					declare.safeMixin(this, new module());
+					this.set("editable", this.editable);
+				}));
+			}
 		},
 
 		startup: function(){
 			if(this._started){ return; }
-			if(this.transition === "below"){
-				this._setupSubNodes(this.domNode);
-			}else{
-				var view = this.appView = new View({id:this.id+"_mblApplView"});
-				var _this = this;
-				view.onAfterTransitionIn = function(moveTo, dir, transition, context, method){
-					_this._opening._open_1();
-				};
-				view.domNode.style.visibility = "hidden";
-				var heading = view._heading
-					= new Heading({back: this._cv ? this._cv(this.back) : this.back,
-									label: this._cv ? this._cv(this.label) : this.label,
-									moveTo: this.domNode.parentNode.id,
-									transition: this.transition});
-				view.addChild(heading);
-				var ul = view._ul = win.doc.createElement("UL");
-				ul.className = "mblIconContainer";
-				ul.style.marginTop = "0px";
-				this._setupSubNodes(ul);
-				view.domNode.appendChild(ul);
-
-				var target;
-				for(var w = this.getParent(); w; w = w.getParent()){
-					if(w instanceof View){
-						target = w.domNode.parentNode;
-						break;
+
+			require([this.iconItemPaneContainerClass], lang.hitch(this, function(module){
+				this.paneContainerWidget = new module(this.iconItemPaneContainerProps);
+				if(this.transition === "below"){
+					domConstruct.place(this.paneContainerWidget.domNode, this.domNode, "after");
+				}else{
+					var view = this.appView = new View({id:this.id+"_mblApplView"});
+					var _this = this;
+					view.onAfterTransitionIn = function(moveTo, dir, transition, context, method){
+						_this._opening._open_1();
+					};
+					view.domNode.style.visibility = "hidden";
+					var heading = view._heading
+						= new Heading({back: this._cv ? this._cv(this.back) : this.back,
+										label: this._cv ? this._cv(this.label) : this.label,
+										moveTo: this.domNode.parentNode.id,
+										transition: this.transition == "zoomIn" ? "zoomOut" : this.transition});
+					view.addChild(heading);
+					view.addChild(this.paneContainerWidget);
+
+					var target;
+					for(var w = this.getParent(); w; w = w.getParent()){
+						if(w instanceof View){
+							target = w.domNode.parentNode;
+							break;
+						}
 					}
+					if(!target){ target = win.body(); }
+					target.appendChild(view.domNode);
+
+					view.startup();
 				}
-				if(!target){ target = win.body(); }
-				target.appendChild(view.domNode);
+			}));
 
-				view.startup();
-			}
 			this.inherited(arguments);
 		},
 
 		closeAll: function(){
 			// summary:
 			//		Closes all the icon items.
-			var len = this.domNode.childNodes.length, child, w;
-			for(var i = 0; i < len; i++){
-				var child = this.domNode.childNodes[i];
-				if(child.nodeType !== 1){ continue; }
-				if(child === this._terminator){ break; }
-				var w = registry.byNode(child);
-				w.containerNode.parentNode.style.display = "none";
-				domStyle.set(w.iconNode, "opacity", 1);
-			}
+			array.forEach(this.getChildren(), function(w){
+				w.close(true); // disables closing animation
+			}, this);
 		},
 
 		addChild: function(widget, /*Number?*/insertIndex){
-			var children = this.getChildren();
-			if(typeof insertIndex !== "number" || insertIndex > children.length){
-				insertIndex = children.length;
-			}
-			var idx = insertIndex;
-			var refNode = this.containerNode;
-			if(idx > 0){
-				refNode = children[idx - 1].domNode;
-				idx = "after";
-			}
-			domConstruct.place(widget.domNode, refNode, idx);
-
-			widget.transition = this.transition;
-			if(this.transition === "below"){
-				for(var i = 0, refNode = this._terminator; i < insertIndex; i++){
-					refNode = refNode.nextSibling;
-				}
-				domConstruct.place(widget.subNode, refNode, "after");
-			}else{
-				domConstruct.place(widget.subNode, this.appView._ul, insertIndex);
-			}
-			widget.inheritParams();
-			widget._setIconAttr(widget.icon);
-
-			if(this._started && !widget._started){
-				widget.startup();
+			this.inherited(arguments);
+			// #16597: if removeChild(item) was called to remove the item, it also removes the paneWidget from its container,
+			// But then calling addChild(item) again does not re-add it as it should: it was added the first time through startup
+			// called by addChild, but startup is not called any more the subsequent times.
+			// So we add the pane explicitly if it is orphan.
+			if(this._started && widget.paneWidget && !widget.paneWidget.getParent()){
+				this.paneContainerWidget.addChild(widget.paneWidget, insertIndex);
 			}
+			this.domNode.appendChild(this._terminator); // to ensure that _terminator is always the last node
 		},
 
 		removeChild: function(/*Widget|Number*/widget){
-			if(typeof widget === "number"){
-				widget = this.getChildren()[widget];
-			}
-			if(widget){
-				this.inherited(arguments);
-				if(this.transition === "below"){
-					this.containerNode.removeChild(widget.subNode);
-				}else{
-					this.appView._ul.removeChild(widget.subNode);
-				}
-			}
+			var index = (typeof widget == "number") ? widget : widget.getIndexInParent();
+			this.paneContainerWidget.removeChild(index);
+			this.inherited(arguments);
+		},	
+
+		_setLabelAttr: function(/*String*/text){
+			// tags:
+			//		private
+			if(!this.appView){ return; }
+			this.label = text;
+			var s = this._cv ? this._cv(text) : text;
+			this.appView._heading.set("label", s);
 		}
 	});
 });
diff --git a/dojox/mobile/IconItem.js b/dojox/mobile/IconItem.js
index 1b39dff..3956c9a 100644
--- a/dojox/mobile/IconItem.js
+++ b/dojox/mobile/IconItem.js
@@ -1,30 +1,27 @@
 define([
-	"dojo/_base/kernel",
-	"dojo/_base/array",
 	"dojo/_base/declare",
+	"dojo/_base/event",
 	"dojo/_base/lang",
-	"dojo/_base/sniff",
+	"dojo/sniff",
 	"dojo/_base/window",
-	"dojo/dom-attr",
 	"dojo/dom-class",
 	"dojo/dom-construct",
+	"dojo/dom-geometry",
 	"dojo/dom-style",
-	"dijit/registry",	// registry.byId
-	"./common",
 	"./_ItemBase",
-	"./TransitionEvent"
-], function(dojo, array, declare, lang, has, win, domAttr, domClass, domConstruct, domStyle, registry, common, ItemBase, TransitionEvent){
-
-/*=====
-	var ItemBase = dojox.mobile._ItemBase;
-=====*/
+	"./Badge",
+	"./TransitionEvent",
+	"./iconUtils",
+	"./lazyLoadUtils",
+	"./viewRegistry",
+	"./_css3",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/IconItem"
+], function(declare, event, lang, has, win, domClass, domConstruct, domGeometry, domStyle, ItemBase, Badge, TransitionEvent, iconUtils, lazyLoadUtils, viewRegistry, css3, BidiIconItem){
 
 	// module:
 	//		dojox/mobile/IconItem
-	// summary:
-	//		An icon item widget.
 
-	return declare("dojox.mobile.IconItem", ItemBase, {
+	var IconItem = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiIconItem" : "dojox.mobile.IconItem", ItemBase, {
 		// summary:
 		//		An icon item widget.
 		// description:
@@ -35,113 +32,134 @@ define([
 		//		href or url parameters.
 
 		// lazy: String
-		//		If true, the content of the item, which includes dojo markup, is
-		//		instantiated lazily. That is, only when the icon is opened by
-		//		the user, the required modules are loaded and dojo widgets are
-		//		instantiated.
+		//		If true, the content of the widget, which includes dojo markup,
+		//		is instantiated lazily. That is, only when the widget is opened
+		//		by the user, the required modules are loaded and the content
+		//		widgets are instantiated.
+		//		This option works both in the sync and async loader mode.
 		lazy: false,
 
 		// requires: String
-		//		Comma-separated required module names to be loaded. All the
-		//		modules specified with dojoType and their depending modules are
-		//		automatically loaded by the IconItem. If you need other extra
-		//		modules to be loaded, use this parameter. If lazy is true, the
-		//		specified required modules are loaded when the user opens the
-		//		icon for the first time.
+		//		Comma-separated required module names to be lazily loaded. This
+		//		property is effective only when lazy=true. All the modules
+		//		specified with data-dojo-type and their depending modules are
+		//		automatically loaded by the IconItem when it is opened.
+		//		However, if you need other extra modules to be loaded, use this parameter.
+		//		This option works both in the sync and async loader mode.
 		requires: "",
 
 		// timeout: String
 		//		Duration of highlight in seconds.
 		timeout: 10,
 
-		// closeBtnClass: String
-		//		A class name of a DOM button to be used as a close button.
-		closeBtnClass: "mblDomButtonBlueMinus",
-
-		// closeBtnProp: String
-		//		Properties for the close button.
-		closeBtnProp: null,
-
-
-		templateString: '<div class="mblIconArea" dojoAttachPoint="iconDivNode">'+
-							'<div><img src="${icon}" dojoAttachPoint="iconNode"></div><span dojoAttachPoint="labelNode1"></span>'+
-						'</div>',
-		templateStringSub: '<li class="mblIconItemSub" lazy="${lazy}" style="display:none;" dojoAttachPoint="contentNode">'+
-						'<h2 class="mblIconContentHeading" dojoAttachPoint="closeNode">'+
-							'<div class="${closeBtnClass}" style="position:absolute;left:4px;top:2px;" dojoAttachPoint="closeIconNode"></div><span dojoAttachPoint="labelNode2"></span>'+
-						'</h2>'+
-						'<div class="mblContent" dojoAttachPoint="containerNode"></div>'+
-					'</li>',
-
-		createTemplate: function(s){
-			array.forEach(["lazy","icon","closeBtnClass"], function(v){
-				while(s.indexOf("${"+v+"}") != -1){
-					s = s.replace("${"+v+"}", this[v]);
-				}
-			}, this);
-			var div = win.doc.createElement("DIV");
-			div.innerHTML = s;
-	
-			/*
-			array.forEach(query("[dojoAttachPoint]", domNode), function(node){
-				this[node.getAttribute("dojoAttachPoint")] = node;
-			}, this);
-			*/
-
-			var nodes = div.getElementsByTagName("*");
-			var i, len, s1;
-			len = nodes.length;
-			for(i = 0; i < len; i++){
-				s1 = nodes[i].getAttribute("dojoAttachPoint");
-				if(s1){
-					this[s1] = nodes[i];
-				}
-			}
-			if(this.closeIconNode && this.closeBtnProp){
-				domAttr.set(this.closeIconNode, this.closeBtnProp);
+		// content: String
+		//		An HTML fragment to embed as icon content.
+		content: "",
+
+		// badge: String
+		//		A text to show in a badge (ex. "55").
+		badge: "",
+
+		// badgeClass: String
+		//		A class name of a DOM button for a badge.
+		badgeClass: "mblDomButtonRedBadge",
+
+		// deletable: Boolean
+		//		If true, you can delete this IconItem by clicking on the delete
+		//		icon during edit mode.
+		//		If false, the delete icon is not displayed during edit mode so
+		//		that it cannot be deleted.
+		deletable: true,
+
+		// deleteIcon: String
+		//		A delete icon to display at the top-left corner of the item
+		//		during edit mode. The value can be either a path for an image
+		//		file or a class name of a DOM button.
+		deleteIcon: "",
+
+		// tag: String
+		//		A name of the HTML tag to create as domNode.
+		tag: "li",
+
+		/* internal properties */	
+		// Note these are overrides for similar properties defined in _ItemBase.
+		paramsToInherit: "transition,icon,deleteIcon,badgeClass,deleteIconTitle,deleteIconRole",
+		baseClass: "mblIconItem",
+		_selStartMethod: "touch",
+		_selEndMethod: "none",
+
+		destroy: function(){
+			if(this.badgeObj){
+				delete this.badgeObj;
 			}
-			var domNode = div.removeChild(div.firstChild);
-			div = null;
-			return domNode;
+			this.inherited(arguments);
 		},
 
 		buildRendering: function(){
-			this.inheritParams();
-			var node = this.createTemplate(this.templateString);
-			this.subNode = this.createTemplate(this.templateStringSub);
-			this.subNode._parentNode = this.domNode; // [custom property]
+			this.domNode = this.srcNodeRef || domConstruct.create(this.tag);
 
-			this.domNode = this.srcNodeRef || domConstruct.create("LI");
-			domClass.add(this.domNode, "mblIconItem");
 			if(this.srcNodeRef){
 				// reparent
+				this._tmpNode = domConstruct.create("div");
 				for(var i = 0, len = this.srcNodeRef.childNodes.length; i < len; i++){
-					this.containerNode.appendChild(this.srcNodeRef.firstChild);
+					this._tmpNode.appendChild(this.srcNodeRef.firstChild);
 				}
 			}
-			this.domNode.appendChild(node);
+
+			this.iconDivNode = domConstruct.create("div", {className:"mblIconArea"}, this.domNode);
+			this.iconParentNode = domConstruct.create("div", {className:"mblIconAreaInner"}, this.iconDivNode);
+			this.labelNode = domConstruct.create("span", {className:"mblIconAreaTitle"}, this.iconDivNode);
+
+			this.inherited(arguments);
 		},
 
-		postCreate: function(){
-			common.createDomButton(this.closeIconNode, {
-				top: "-2px",
-				left: "1px"
-			});
-			this.connect(this.iconNode, "onmousedown", "onMouseDownIcon");
-			this.connect(this.iconNode, "onclick", "iconClicked");
-			this.connect(this.closeIconNode, "onclick", "closeIconClicked");
-			this.connect(this.iconNode, "onerror", "onError");
+		startup: function(){
+			if(this._started){ return; }
+
+			var p = this.getParent();
+			require([p.iconItemPaneClass], lang.hitch(this, function(module){
+				var w = this.paneWidget = new module(p.iconItemPaneProps);
+				this.containerNode = w.containerNode;
+				if(this._tmpNode){
+					// reparent
+					for(var i = 0, len = this._tmpNode.childNodes.length; i < len; i++){
+						w.containerNode.appendChild(this._tmpNode.firstChild);
+					}
+					this._tmpNode = null;
+				}
+				p.paneContainerWidget.addChild(w, this.getIndexInParent());
+				w.set("label", this.label);
+				this._clickCloseHandle = this.connect(w.closeIconNode, "onclick", "_closeIconClicked");
+				this._keydownCloseHandle = this.connect(w.closeIconNode, "onkeydown", "_closeIconClicked"); // for desktop browsers
+			}));
+
+			this.inherited(arguments);
+			if(!this._isOnLine){
+				this._isOnLine = true;
+				// retry applying the attribute for which the custom setter delays the actual 
+				// work until _isOnLine is true. 
+				this.set("icon", this._pendingIcon !== undefined ? this._pendingIcon : this.icon);
+				// Not needed anymore (this code executes only once per life cycle):
+				delete this._pendingIcon; 
+			}
+			if(!this.icon && p.defaultIcon){
+				this.set("icon", p.defaultIcon);
+			}
+
+			this._dragstartHandle = this.connect(this.domNode, "ondragstart", event.stop);
+			this.connect(this.domNode, "onkeydown", "_onClick"); // for desktop browsers
 		},
-	
-		highlight: function(){
+
+		highlight: function(/*Number?*/timeout){
 			// summary:
 			//		Shakes the icon 10 seconds.
 			domClass.add(this.iconDivNode, "mblVibrate");
-			if(this.timeout > 0){
+			timeout = (timeout !== undefined) ? timeout : this.timeout;
+			if(timeout > 0){
 				var _this = this;
-				setTimeout(function(){
+				_this.defer(function(){
 					_this.unhighlight();
-				}, this.timeout*1000);
+				}, timeout*1000);
 			}
 		},
 
@@ -151,181 +169,240 @@ define([
 			domClass.remove(this.iconDivNode, "mblVibrate");
 		},
 
-		instantiateWidget: function(e){
-			// summary:
-			//		Instantiates the icon content.
-
-			// avoid use of query
-			/*
-			var list = query('[dojoType]', this.containerNode);
-			for(var i = 0, len = list.length; i < len; i++){
-				dojo["require"](list[i].getAttribute("dojoType"));
-			}
-			*/
-	
-			var nodes = this.containerNode.getElementsByTagName("*");
-			var len = nodes.length;
-			var s;
-			for(var i = 0; i < len; i++){
-				s = nodes[i].getAttribute("dojoType");
-				if(s){
-					dojo["require"](s);
-				}
-			}
-	
-			if(len > 0){
-				dojo.parser.parse(this.containerNode);
-			}
-			this.lazy = false;
-		},
-	
 		isOpen: function(e){
 			// summary:
 			//		Returns true if the icon is open.
-			return this.containerNode.style.display != "none";
+			return this.paneWidget.isOpen();
 		},
-	
-		onMouseDownIcon: function (e){
-			domStyle.set(this.iconNode, "opacity", this.getParent().pressedIconOpacity);
+
+		_onClick: function(e){
+			// summary:
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(this.getParent().isEditing || e && e.type === "keydown" && e.keyCode !== 13){ return; }
+			if(this.onClick(e) === false){ return; } // user's click action
+			this.defaultClickAction(e);
 		},
-	
-		iconClicked: function(e){
-			if(e){
-				this.setTransitionPos(e);
-				setTimeout(lang.hitch(this, function(d){ this.iconClicked(); }), 0);
-				return;
-			}
 
-			if (this.href && this.hrefTarget) {
-				common.openWindow(this.href, this.hrefTarget);
-				dojo.style(this.iconNode, "opacity", 1);
-				return;
-			}
+		onClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User-defined function to handle clicks.
+			// tags:
+			//		callback
+		},
 
-			var transOpts;
-			if(this.moveTo || this.href || this.url || this.scene){
-				transOpts = {moveTo: this.moveTo, href: this.href, url: this.url, scene: this.scene, transitionDir: this.transitionDir, transition: this.transition};
-			}else if(this.transitionOptions){
-				transOpts = this.transitionOptions;
-			}
+		_onNewWindowOpened: function(e){
+			// Override from _ItemBase
+			this.set("selected", false);
+		},
+
+		_prepareForTransition: function(e, transOpts){
+			// Override from _ItemBase
 			if(transOpts){
-				setTimeout(lang.hitch(this, function(d){
-					domStyle.set(this.iconNode, "opacity", 1);
-				}), 1500);
+				this.defer(function(d){
+					this.set("selected", false);
+				}, 1500);
+				return true;
 			}else{
-				return this.open(e);
-			}
-	
-			if(transOpts){
-				return new TransitionEvent(this.domNode,transOpts,e).dispatch();
+				if(this.getParent().transition === "below" && this.isOpen()){
+					this.close();
+				}else{
+					this.open(e);
+				}
+				return false;
 			}
 		},
-	
-		closeIconClicked: function(e){
+
+		_closeIconClicked: function(e){
+			// summary:
+			//		Internal handler for click events.
+			// tags:
+			//		private
 			if(e){
-				setTimeout(lang.hitch(this, function(d){ this.closeIconClicked(); }), 0);
+				if(e.type === "keydown" && e.keyCode !== 13){ return; }
+				if(this.closeIconClicked(e) === false){ return; } // user's click action
+				this.defer(function(d){ this._closeIconClicked(); });
 				return;
 			}
 			this.close();
 		},
-	
+
+		closeIconClicked: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User-defined function to handle clicks for the close icon.
+			// tags:
+			//		callback
+		},
+
 		open: function(e){
 			// summary:
 			//		Opens the icon content, or makes a transition.
 			var parent = this.getParent(); // IconContainer
-			if(this.transition == "below"){
+			if(this.transition === "below"){
 				if(parent.single){
 					parent.closeAll();
-					domStyle.set(this.iconNode, "opacity", this.getParent().pressedIconOpacity);
 				}
 				this._open_1();
 			}else{
 				parent._opening = this;
 				if(parent.single){
-					this.closeNode.style.display = "none";
-					parent.closeAll();
-					var view = registry.byId(parent.id+"_mblApplView");
-					view._heading._setLabelAttr(this.label);
+					this.paneWidget.closeHeaderNode.style.display = "none";
+					if(!this.isOpen()){
+						parent.closeAll();
+					}
+					parent.appView._heading.set("label", this.label);
 				}
-				var transOpts = this.transitionOptions || {transition: this.transition, transitionDir: this.transitionDir, moveTo: parent.id + "_mblApplView"};		
-				new TransitionEvent(this.domNode, transOpts, e).dispatch();
+				this.moveTo = parent.id + "_mblApplView";
+				new TransitionEvent(this.domNode, this.getTransOpts(), e).dispatch();
 			}
 		},
-	
+
 		_open_1: function(){
-			this.contentNode.style.display = "";
+			// summary:
+			//		Opens the icon content for the 'below' transition.
+			// tags:
+			//		private
+			this.paneWidget.show();
 			this.unhighlight();
 			if(this.lazy){
-				if(this.requires){
-					array.forEach(this.requires.split(/,/), function(c){
-						dojo["require"](c);
-					});
-				}
-				this.instantiateWidget();
+				lazyLoadUtils.instantiateLazyWidgets(this.containerNode, this.requires);
+				this.lazy = false;
 			}
-			this.contentNode.scrollIntoView();
+			this.scrollIntoView(this.paneWidget.domNode);
 			this.onOpen();
 		},
-	
-		close: function(){
+
+		scrollIntoView: function(/*DomNode*/node){
+			// summary:
+			//		Scrolls until the given node is in the view.
+			var s = viewRegistry.getEnclosingScrollable(node);
+			if(s){ // this node is placed inside scrollable
+				var dim = s.getDim();
+				if(dim.c.h >= dim.d.h){ // #16306: only if the content is larger than the display area 
+					s.scrollIntoView(node, true);
+				}
+			}else{
+				win.global.scrollBy(0, domGeometry.position(node, false).y);
+			}
+		},
+
+		close: function(/*Boolean?*/noAnimation){
 			// summary:
 			//		Closes the icon content.
-			if(has("webkit")){
-				var t = this.domNode.parentNode.offsetWidth/8;
-				var y = this.iconNode.offsetLeft;
-				var pos = 0;
-				for(var i = 1; i <= 3; i++){
-					if(t*(2*i-1) < y && y <= t*(2*(i+1)-1)){
-						pos = i;
-						break;
-					}
+			if(!this.isOpen()){ return; }
+			this.set("selected", false);
+			if(has("css3-animations") && !noAnimation){
+				var contentNode = this.paneWidget.domNode;
+				if(this.getParent().transition == "below"){
+					domClass.add(contentNode, "mblCloseContent mblShrink");
+					var nodePos = domGeometry.position(contentNode, true);
+					var targetPos = domGeometry.position(this.domNode, true);
+					var origin = (targetPos.x + targetPos.w/2 - nodePos.x) + "px " + (targetPos.y + targetPos.h/2 - nodePos.y) + "px";
+					domStyle.set(contentNode, css3.add({}, { transformOrigin:origin }));
+				}else{
+					domClass.add(contentNode, "mblCloseContent mblShrink0");
 				}
-				domClass.add(this.containerNode.parentNode, "mblCloseContent mblShrink"+pos);
 			}else{
-				this.containerNode.parentNode.style.display = "none";
+				this.paneWidget.hide();
 			}
-			domStyle.set(this.iconNode, "opacity", 1);
 			this.onClose();
 		},
-	
+
 		onOpen: function(){
 			// summary:
-			//		Stub method to allow the application to connect to.
+			//		Stub method to allow the application to connect.
 		},
-	
+
 		onClose: function(){
 			// summary:
-			//		Stub method to allow the application to connect to.
+			//		Stub method to allow the application to connect.
 		},
-	
-		onError: function(){
-			var icon = this.getParent().defaultIcon;
-			if(icon){
-				this.iconNode.src = icon;
+
+		_setLabelAttr: function(/*String*/text){
+			// tags:
+			//		private
+			this.label = text;
+			var s = this._cv ? this._cv(text) : text;
+			this.labelNode.innerHTML = s;
+			if(this.paneWidget){
+				this.paneWidget.set("label", text);
 			}
 		},
-	
-		_setIconAttr: function(icon){
-			if(!this.getParent()){ return; } // icon may be invalid because inheritParams is not called yet
-			this.icon = icon;
-			common.createIcon(icon, this.iconPos, this.iconNode, this.alt);
-			if(this.iconPos){
-				domClass.add(this.iconNode, "mblIconItemSpriteIcon");
-				var arr = this.iconPos.split(/[ ,]/);
-				var p = this.iconNode.parentNode;
-				domStyle.set(p, {
-					width: arr[2] + "px",
-					top: Math.round((p.offsetHeight - arr[3]) / 2) + 1 + "px",
-					margin: "auto"
+
+		_getBadgeAttr: function(){
+			// tags:
+			//		private
+			return this.badgeObj ? this.badgeObj.getValue() : null;
+		},
+
+		_setBadgeAttr: function(/*String*/value){
+			// tags:
+			//		private
+			if(!this.badgeObj){
+				this.badgeObj = new Badge({fontSize:14, className:this.badgeClass});
+				domStyle.set(this.badgeObj.domNode, {
+					position: "absolute",
+					top: "-2px",
+					right: "2px"
 				});
 			}
+			this.badgeObj.setValue(value);
+			if(value){
+				this.iconDivNode.appendChild(this.badgeObj.domNode);
+			}else{
+				this.iconDivNode.removeChild(this.badgeObj.domNode);
+			}
 		},
-	
-		_setLabelAttr: function(/*String*/text){
-			this.label = text;
-			var s = this._cv ? this._cv(text) : text;
-			this.labelNode1.innerHTML = s;
-			this.labelNode2.innerHTML = s;
+
+		_setDeleteIconAttr: function(icon){
+			// tags:
+			//		private
+			if(!this.getParent()){ return; } // icon may be invalid because inheritParams is not called yet
+
+			this._set("deleteIcon", icon);
+			icon = this.deletable ? icon : "";
+			this.deleteIconNode = iconUtils.setIcon(icon, this.deleteIconPos, this.deleteIconNode, 
+					this.deleteIconTitle || this.alt, this.iconDivNode);
+			if(this.deleteIconNode){
+				domClass.add(this.deleteIconNode, "mblIconItemDeleteIcon");
+				if(this.deleteIconRole){
+					this.deleteIconNode.setAttribute("role", this.deleteIconRole);
+				}
+			}
+		},
+
+		_setContentAttr: function(/*String|DomNode*/data){
+			// tags:
+			//		private
+			var root;
+			if(!this.paneWidget){
+				if(!this._tmpNode){
+					this._tmpNode = domConstruct.create("div");
+				}
+				root = this._tmpNode;
+			}else{
+				root = this.paneWidget.containerNode;
+			}
+
+			if(typeof data === "object"){
+				domConstruct.empty(root);
+				root.appendChild(data);
+			}else{
+				root.innerHTML = data;
+			}
+		},
+
+		_setSelectedAttr: function(/*Boolean*/selected){
+			// summary:
+			//		Makes this widget in the selected or unselected state.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			domStyle.set(this.iconNode, "opacity",
+						 selected ? this.getParent().pressedIconOpacity : 1);
 		}
 	});
+
+	return has("dojo-bidi") ? declare("dojox.mobile.IconItem", [IconItem, BidiIconItem]) : IconItem;
 });
diff --git a/dojox/mobile/IconMenu.js b/dojox/mobile/IconMenu.js
new file mode 100644
index 0000000..8d18e67
--- /dev/null
+++ b/dojox/mobile/IconMenu.js
@@ -0,0 +1,126 @@
+define([
+	"dojo/_base/declare",
+	"dojo/sniff",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dojo/dom-attr",
+	"dijit/_Contained",
+	"dijit/_Container",
+	"dijit/_WidgetBase",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/IconMenu",
+	"./IconMenuItem"
+], function(declare, has, domClass, domConstruct, domStyle, domAttr, Contained, Container, WidgetBase, BidiIconMenu){
+	// module:
+	//		dojox/mobile/IconMenu
+
+	var IconMenu = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiIconMenu" : "dojox.mobile.IconMenu", [WidgetBase, Container, Contained], {
+		// summary:
+		//		A pop-up menu.
+		// description:
+		//		The dojox/mobile/IconMenu widget displays a pop-up menu just
+		//		like iPhone's call options menu that is shown while you are on a
+		//		call. Each menu item must be dojox/mobile/IconMenuItem.
+
+		// transition: String
+		//		The default animated transition effect for child items.
+		transition: "slide",
+
+		// iconBase: String
+		//		The default icon path for child items.
+		iconBase: "",
+
+		// iconPos: String
+		//		The default icon position for child items.
+		iconPos: "",
+
+		// cols: Number
+		//		The number of child items in a row.
+		cols: 3,
+
+		// tag: String
+		//		A name of html tag to create as domNode.
+		tag: "ul",
+
+		/* internal properties */
+		selectOne: false,
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblIconMenu",
+		
+		// childItemClass: String
+		//		The name of the CSS class of menu items.
+		childItemClass: "mblIconMenuItem",
+
+		// _createTerminator: [private] Boolean
+		_createTerminator: false,
+
+		buildRendering: function(){
+			this.domNode = this.containerNode = this.srcNodeRef || domConstruct.create(this.tag);
+			domAttr.set(this.domNode, "role", "menu");
+			this.inherited(arguments);
+
+			if(this._createTerminator){
+				var t = this._terminator = domConstruct.create("br");
+				t.className = this.childItemClass + "Terminator";
+				this.domNode.appendChild(t);
+			}
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this.refresh();
+			this.inherited(arguments);
+		},
+
+		refresh: function(){
+			var p = this.getParent();
+			if(p){
+				domClass.remove(p.domNode, "mblSimpleDialogDecoration");
+			}
+			var children = this.getChildren();
+			if(this.cols){
+				var nRows = Math.ceil(children.length / this.cols);
+				var w = Math.floor(100/this.cols);
+				var _w = 100 - w*this.cols;
+				var h = Math.floor(100 / nRows);
+				var _h = 100 - h*nRows;
+				if(has("ie")){
+					_w--;
+					_h--;
+				}
+			}
+			for(var i = 0; i < children.length; i++){
+				var item = children[i];
+				if(this.cols){
+					var first = ((i % this.cols) === 0); // first column
+					var last = (((i + 1) % this.cols) === 0); // last column
+					var rowIdx = Math.floor(i / this.cols);
+					domStyle.set(item.domNode, {
+						width: w + (last ? _w : 0) + "%",
+						height: h + ((rowIdx + 1 === nRows) ? _h : 0) + "%"
+					});
+					domClass.toggle(item.domNode, this.childItemClass + "FirstColumn", first);
+					domClass.toggle(item.domNode, this.childItemClass + "LastColumn", last);
+					domClass.toggle(item.domNode, this.childItemClass + "FirstRow", rowIdx === 0);
+					domClass.toggle(item.domNode, this.childItemClass + "LastRow", rowIdx + 1 === nRows);
+				}
+			};
+		},
+
+		addChild: function(widget, /*Number?*/insertIndex){
+			this.inherited(arguments);
+			this.refresh();
+		},
+
+		hide: function(){
+			var p = this.getParent();
+			if(p && p.hide){
+				p.hide();
+			}
+		}
+	});
+
+	return has("dojo-bidi") ? declare("dojox.mobile.IconMenu", [IconMenu, BidiIconMenu]) : IconMenu;
+});
diff --git a/dojox/mobile/IconMenuItem.js b/dojox/mobile/IconMenuItem.js
new file mode 100644
index 0000000..7204572
--- /dev/null
+++ b/dojox/mobile/IconMenuItem.js
@@ -0,0 +1,122 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-attr",
+	"./iconUtils",
+	"./_ItemBase"
+], function(declare, lang, domClass, domConstruct, domAttr, iconUtils, ItemBase){
+	// module:
+	//		dojox/mobile/IconMenuItem
+
+	return declare("dojox.mobile.IconMenuItem", ItemBase, { 
+		// summary:
+		//		An item of IconMenu.
+		// description:
+		//		IconMenuItem represents a menu item of dojox/mobile/MenuItem. 
+		//		This widget inherits from dojox/mobile/_ItemBase. Its basic usage is 
+		//		similar to other subclasses such as dojox/mobile/ListItem.
+
+		// closeOnAction: Boolean
+		//		If true, the internal handler of click events calls the hide() method 
+		//		of the parent widget, which is typically a dojox/mobile/SimpleDialog.
+		//		The default value is false.
+		closeOnAction: false,
+
+		// tag: String
+		//		The name of the HTML tag to create as domNode.
+		tag: "li",
+
+		/* internal properties */
+		// Note these are overrides for similar properties defined in _ItemBase.
+		baseClass: "mblIconMenuItem",
+		selColor: "mblIconMenuItemSel",
+		_selStartMethod: "touch",
+		_selEndMethod: "touch",
+
+		buildRendering: function(){
+			this.domNode = this.srcNodeRef || domConstruct.create(this.tag);
+			domAttr.set(this.domNode, "role", "menuitemcheckbox");
+			domAttr.set(this.domNode, "aria-checked", "false");
+			this.inherited(arguments);
+			if(this.selected){
+				domClass.add(this.domNode, this.selColor);
+			}
+
+			if(this.srcNodeRef){
+				if(!this.label){
+					this.label = lang.trim(this.srcNodeRef.innerHTML);
+				}
+				this.srcNodeRef.innerHTML = "";
+			}
+
+			var a = this.anchorNode = this.containerNode = domConstruct.create("a", {
+				className: "mblIconMenuItemAnchor",
+				role: "presentation"
+			});
+			var tbl = domConstruct.create("table", {
+				className: "mblIconMenuItemTable",
+				role: "presentation"
+			}, a);
+			var cell = this.iconParentNode = tbl.insertRow(-1).insertCell(-1);
+			this.iconNode = domConstruct.create("div", {
+				className: "mblIconMenuItemIcon"
+			}, cell);
+			this.labelNode = this.refNode = domConstruct.create("div", {
+				className: "mblIconMenuItemLabel"
+			}, cell);
+			this.position = "before";
+			this.domNode.appendChild(a);
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+
+			this.connect(this.domNode, "onkeydown", "_onClick"); // for desktop browsers
+
+			this.inherited(arguments);
+			if(!this._isOnLine){
+				this._isOnLine = true;
+				// retry applying the attribute for which the custom setter delays the actual 
+				// work until _isOnLine is true. 
+				this.set("icon", this._pendingIcon !== undefined ? this._pendingIcon : this.icon);
+				// Not needed anymore (this code executes only once per life cycle):
+				delete this._pendingIcon; 
+			}
+		},
+
+		_onClick: function(e){
+			// summary:
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
+			if(this.onClick(e) === false){ return; } // user's click action
+			if(this.closeOnAction){
+				var p = this.getParent(); // maybe SimpleDialog
+				if(p && p.hide){
+					p.hide();
+				}
+			}
+			this.defaultClickAction(e);
+		},
+
+		onClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User-defined function to handle clicks.
+			// tags:
+			//		callback
+		},
+
+		_setSelectedAttr: function(/*Boolean*/selected){
+			// summary:
+			//		Makes this widget in the selected or unselected state.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			domClass.toggle(this.domNode, this.selColor, selected);
+			domAttr.set(this.domNode, "aria-checked", selected ? "true" : "false");
+		}
+	});
+});
diff --git a/dojox/mobile/ListItem.js b/dojox/mobile/ListItem.js
index d560ec8..9f048ef 100644
--- a/dojox/mobile/ListItem.js
+++ b/dojox/mobile/ListItem.js
@@ -1,32 +1,50 @@
 define([
 	"dojo/_base/array",
-	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/_base/lang",
 	"dojo/dom-class",
 	"dojo/dom-construct",
-	"dojo/has",
-	"./common",
+	"dojo/dom-style",
+	"dojo/dom-attr",
+	"dijit/registry",
+	"dijit/_WidgetBase",
+	"./iconUtils",
 	"./_ItemBase",
-	"./TransitionEvent"
-], function(array, connect, declare, lang, domClass, domConstruct, has, common, ItemBase, TransitionEvent){
-
-/*=====
-	var ItemBase = dojox.mobile._ItemBase;
-=====*/
+	"./ProgressIndicator",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/ListItem"
+], function(array, declare, lang, domClass, domConstruct, domStyle, domAttr, registry, WidgetBase, iconUtils, ItemBase, ProgressIndicator, has,  BidiListItem){
 
 	// module:
 	//		dojox/mobile/ListItem
-	// summary:
-	//		An item of either RoundRectList or EdgeToEdgeList.
 
-	return declare("dojox.mobile.ListItem", ItemBase, {
+	var ListItem = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiListItem" : "dojox.mobile.ListItem", ItemBase, {
 		// summary:
 		//		An item of either RoundRectList or EdgeToEdgeList.
 		// description:
 		//		ListItem represents an item of either RoundRectList or
-		//		EdgeToEdgeList. There are three ways to move to a different
-		//		view, moveTo, href, and url. You can choose only one of them.
+		//		EdgeToEdgeList. There are three ways to move to a different view:
+		//		moveTo, href, and url. You can choose only one of them.
+		//
+		//		A child DOM node (or widget) can have the layout attribute,
+		//		whose value is "left", "right", or "center". Such nodes will be
+		//		aligned as specified.
+		// example:
+		// |	<li data-dojo-type="dojox.mobile.ListItem">
+		// |		<div layout="left">Left Node</div>
+		// |		<div layout="right">Right Node</div>
+		// |		<div layout="center">Center Node</div>
+		// |	</li>
+		//
+		//		Note that even if you specify variableHeight="true" for the list
+		//		and place a tall object inside the layout node as in the example
+		//		below, the layout node does not expand as you may expect,
+		//		because layout node is aligned using float:left, float:right, or
+		//		position:absolute.
+		// example:
+		// |	<li data-dojo-type="dojox.mobile.ListItem" variableHeight="true">
+		// |		<div layout="left"><img src="large-picture.jpg"></div>
+		// |	</li>
 
 		// rightText: String
 		//		A right-aligned text to display on the item.
@@ -44,6 +62,11 @@ define([
 		//		button.
 		rightIcon2: "",
 
+		// deleteIcon: String
+		//		A delete icon to display at the left of the item. The value can
+		//		be either a path for an image file or a class name of a DOM
+		//		button.
+		deleteIcon: "",
 
 		// anchorLabel: Boolean
 		//		If true, the label text becomes a clickable anchor text. When
@@ -56,10 +79,6 @@ define([
 		//		If true, the right hand side arrow is not displayed.
 		noArrow: false,
 
-		// selected: Boolean
-		//		If true, the item is highlighted to indicate it is selected.
-		selected: false,
-
 		// checked: Boolean
 		//		If true, a check mark is displayed at the right of the item.
 		checked: false,
@@ -67,21 +86,22 @@ define([
 		// arrowClass: String
 		//		An icon to display as an arrow. The value can be either a path
 		//		for an image file or a class name of a DOM button.
-		arrowClass: "mblDomButtonArrow",
+		arrowClass: "",
 
 		// checkClass: String
 		//		An icon to display as a check mark. The value can be either a
 		//		path for an image file or a class name of a DOM button.
-		checkClass: "mblDomButtonCheck",
+		checkClass: "",
+
+		// uncheckClass: String
+		//		An icon to display as an uncheck mark. The value can be either a
+		//		path for an image file or a class name of a DOM button.
+		uncheckClass: "",
 
 		// variableHeight: Boolean
-		//		If true, the height of the item varies according to its
-		//		content. In dojo 1.6 or older, the "mblVariableHeight" class was
-		//		used for this purpose. In dojo 1.7, adding the mblVariableHeight
-		//		class still works for backward compatibility.
+		//		If true, the height of the item varies according to its content.
 		variableHeight: false,
 
-
 		// rightIconTitle: String
 		//		An alt text for the right icon.
 		rightIconTitle: "",
@@ -90,111 +110,203 @@ define([
 		//		An alt text for the right icon2.
 		rightIcon2Title: "",
 
-
-		// btnClass: String
-		//		Deprecated. For backward compatibility.
-		btnClass: "",
-
-		// btnClass2: String
-		//		Deprecated. For backward compatibility.
-		btnClass2: "",
+		// header: Boolean
+		//		If true, this item is rendered as a category header.
+		header: false,
 
 		// tag: String
 		//		A name of html tag to create as domNode.
 		tag: "li",
 
-		postMixInProperties: function(){
-			// for backward compatibility
-			if(this.btnClass){
-				this.rightIcon = this.btnClass;
-			}
-			this._setBtnClassAttr = this._setRightIconAttr;
-			this._setBtnClass2Attr = this._setRightIcon2Attr;
-		},
+		// busy: Boolean
+		//		If true, a progress indicator spins.
+		busy: false,
+
+		// progStyle: String
+		//		A css class name to add to the progress indicator.
+		progStyle: "",
+
+		/* internal properties */	
+		// The following properties are overrides of those in _ItemBase.
+		paramsToInherit: "variableHeight,transition,deleteIcon,icon,rightIcon,rightIcon2,uncheckIcon,arrowClass,checkClass,uncheckClass,deleteIconTitle,deleteIconRole",
+		baseClass: "mblListItem",
+
+		_selStartMethod: "touch",
+		_selEndMethod: "timer",
+		_delayedSelection: true,
+
+		_selClass: "mblListItemSelected",
 
 		buildRendering: function(){
-			this.domNode = this.srcNodeRef || domConstruct.create(this.tag);
+			this._templated = !!this.templateString; // true if this widget is templated
+			if(!this._templated){
+				// Create root node if it wasn't created by _TemplatedMixin
+				this.domNode = this.containerNode = this.srcNodeRef || domConstruct.create(this.tag);
+			}
 			this.inherited(arguments);
-			this.domNode.className = "mblListItem" + (this.selected ? " mblItemSelected" : "");
 
-			// label
-			var box = this.box = domConstruct.create("DIV");
-			box.className = "mblListItemTextBox";
-			if(this.anchorLabel){
-				box.style.cursor = "pointer";
+			if(this.selected){
+				domClass.add(this.domNode, this._selClass);
 			}
-			var r = this.srcNodeRef;
-			if(r && !this.label){
-				this.label = "";
-				for(var i = 0, len = r.childNodes.length; i < len; i++){
-					var n = r.firstChild;
-					if(n.nodeType === 3 && lang.trim(n.nodeValue) !== ""){
-						n.nodeValue = this._cv ? this._cv(n.nodeValue) : n.nodeValue;
-						this.labelNode = domConstruct.create("SPAN", {className:"mblListItemLabel"});
-						this.labelNode.appendChild(n);
-						n = this.labelNode;
-					}
-					box.appendChild(n);
-				}
-			}
-			if(!this.labelNode){
-				this.labelNode = domConstruct.create("SPAN", {className:"mblListItemLabel"}, box);
-			}
-			if(this.anchorLabel){
-				box.style.display = "inline"; // to narrow the text region
+			if(this.header){
+				domClass.replace(this.domNode, "mblEdgeToEdgeCategory", this.baseClass);
 			}
 
-			var a = this.anchorNode = domConstruct.create("A");
-			a.className = "mblListItemAnchor";
-			this.domNode.appendChild(a);
-			a.appendChild(box);
+			if(!this._templated){
+				this.labelNode =
+					domConstruct.create("div", {className:"mblListItemLabel"});
+				var ref = this.srcNodeRef;
+				if(ref && ref.childNodes.length === 1 && ref.firstChild.nodeType === 3){
+					// if ref has only one text node, regard it as a label
+					this.labelNode.appendChild(ref.firstChild);
+				}
+				this.domNode.appendChild(this.labelNode);
+			}
+			this._layoutChildren = [];
 		},
 
 		startup: function(){
 			if(this._started){ return; }
-			this.inheritParams();
 			var parent = this.getParent();
-			if(this.moveTo || this.href || this.url || this.clickable || (parent && parent.select)){
-				this._onClickHandle = this.connect(this.anchorNode, "onclick", "onClick");
+			var opts = this.getTransOpts();
+			// When using a template, labelNode may be created via an attach point.
+			// The attach points are not yet set when ListItem.buildRendering() 
+			// executes, hence the need to use them in startup().
+			if((!this._templated || this.labelNode) && this.anchorLabel){
+				this.labelNode.style.display = "inline"; // to narrow the text region
+				this.labelNode.style.cursor = "pointer";
+				this.connect(this.labelNode, "onclick", "_onClick");
+				this.onTouchStart = function(e){
+					return (e.target !== this.labelNode);
+				};
+			}
+			if(opts.moveTo || opts.href || opts.url || this.clickable || (parent && parent.select)){
+				this.connect(this.domNode, "onkeydown", "_onClick"); // for desktop browsers
+			}else{
+				this._handleClick = false;
 			}
-			this.setArrow();
 
+			this.inherited(arguments);
+			
 			if(domClass.contains(this.domNode, "mblVariableHeight")){
 				this.variableHeight = true;
 			}
 			if(this.variableHeight){
 				domClass.add(this.domNode, "mblVariableHeight");
-				setTimeout(lang.hitch(this, "layoutVariableHeight"));
+				this.defer("layoutVariableHeight");
 			}
 
-			this.set("icon", this.icon); // _setIconAttr may be called twice but this is necessary for offline instantiation
-			if(!this.checked && this.checkClass.indexOf(',') !== -1){
-				this.set("checked", this.checked);
+			if(!this._isOnLine){
+				this._isOnLine = true;
+				this.set({ 
+					// retry applying the attributes for which the custom setter delays the actual 
+					// work until _isOnLine is true
+					icon: this._pending_icon !== undefined ? this._pending_icon : this.icon,
+					deleteIcon: this._pending_deleteIcon !== undefined ? this._pending_deleteIcon : this.deleteIcon,
+					rightIcon: this._pending_rightIcon !== undefined ? this._pending_rightIcon : this.rightIcon,
+					rightIcon2: this._pending_rightIcon2 !== undefined ? this._pending_rightIcon2 : this.rightIcon2,
+					uncheckIcon: this._pending_uncheckIcon !== undefined ? this._pending_uncheckIcon : this.uncheckIcon 
+				});
+				// Not needed anymore (this code executes only once per life cycle):
+				delete this._pending_icon;
+				delete this._pending_deleteIcon;
+				delete this._pending_rightIcon;
+				delete this._pending_rightIcon2;
+				delete this._pending_uncheckIcon;
+			}
+			if(parent && parent.select){
+				// retry applying the attributes for which the custom setter delays the actual 
+				// work until _isOnLine is true. 
+				this.set("checked", this._pendingChecked !== undefined ? this._pendingChecked : this.checked);
+				domAttr.set(this.domNode, "role", "option");
+				if(this._pendingChecked || this.checked){
+					domAttr.set(this.domNode, "aria-selected", "true");
+				}
+				// Not needed anymore (this code executes only once per life cycle):
+				delete this._pendingChecked; 
+			}
+			this.setArrow();
+			this.layoutChildren();
+		},
+
+		_updateHandles: function(){
+			// tags:
+			//		private
+			var parent = this.getParent();
+			var opts = this.getTransOpts();
+			if(opts.moveTo || opts.href || opts.url || this.clickable || (parent && parent.select)){
+				if(!this._keydownHandle){
+					this._keydownHandle = this.connect(this.domNode, "onkeydown", "_onClick"); // for desktop browsers
+				}
+				this._handleClick = true;
+			}else{
+				if(this._keydownHandle){
+					this.disconnect(this._keydownHandle);
+					this._keydownHandle = null;
+				}
+				this._handleClick = false;
 			}
 			this.inherited(arguments);
 		},
 
+		layoutChildren: function(){
+			var centerNode;
+			array.forEach(this.domNode.childNodes, function(n){
+				if(n.nodeType !== 1){ return; }
+				var layout = n.getAttribute("layout") || // TODO: Remove the non-HTML5-compliant attribute in 2.0
+					n.getAttribute("data-mobile-layout") || 
+					(registry.byNode(n) || {}).layout;
+				if(layout){ 
+					domClass.add(n, "mblListItemLayout" +
+						layout.charAt(0).toUpperCase() + layout.substring(1));
+					this._layoutChildren.push(n);
+					if(layout === "center"){ centerNode = n; }
+				}
+			}, this);
+			if(centerNode){
+				this.domNode.insertBefore(centerNode, this.domNode.firstChild);
+			}
+		},
+
 		resize: function(){
 			if(this.variableHeight){
 				this.layoutVariableHeight();
 			}
+
+			// labelNode may not exist only when using a template (if not created by an attach point)
+			if(!this._templated || this.labelNode){
+				// If labelNode is empty, shrink it so as not to prevent user clicks.
+				this.labelNode.style.display = this.labelNode.firstChild ? "block" : "inline";
+			}
 		},
 
-		onClick: function(e){
-			var a = e.currentTarget;
-			var li = a.parentNode;
-			if(domClass.contains(li, "mblItemSelected")){ return; } // already selected
-			if(this.anchorLabel){
-				for(var p = e.target; p.tagName !== this.tag.toUpperCase(); p = p.parentNode){
-					if(p.className == "mblListItemTextBox"){
-						domClass.add(p, "mblListItemTextBoxSelected");
-						setTimeout(function(){
-							domClass.remove(p, "mblListItemTextBoxSelected");
-						}, has('android') ? 300 : 1000);
-						this.onAnchorLabelClicked(e);
-						return;
-					}
-				}
+		_onTouchStart: function(e){
+			// tags:
+			//		private
+			if(e.target.getAttribute("preventTouch") || // TODO: Remove the non-HTML5-compliant attribute in 2.0
+				e.target.getAttribute("data-mobile-prevent-touch") ||
+				(registry.getEnclosingWidget(e.target) || {}).preventTouch){
+				return;
+			}
+			this.inherited(arguments);
+		},
+
+		_onClick: function(e){
+			// summary:
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(this.getParent().isEditing || e && e.type === "keydown" && e.keyCode !== 13){ return; }
+			if(this.onClick(e) === false){ return; } // user's click action
+			var n = this.labelNode;
+			// labelNode may not exist only when using a template 
+			if((this._templated || n) && this.anchorLabel && e.currentTarget === n){
+				domClass.add(n, "mblListItemLabelSelected");
+				this.defer(function(){
+					domClass.remove(n, "mblListItemLabelSelected");
+				}, this._duration);
+				this.onAnchorLabelClicked(e);
+				return;
 			}
 			var parent = this.getParent();
 			if(parent.select){
@@ -206,66 +318,50 @@ define([
 					this.set("checked", !this.checked);
 				}
 			}
-			this.select();
-
-			if (this.href && this.hrefTarget) {
-				common.openWindow(this.href, this.hrefTarget);
-				return;
-			}
-			var transOpts;
-			if(this.moveTo || this.href || this.url || this.scene){
-				transOpts = {moveTo: this.moveTo, href: this.href, url: this.url, scene: this.scene, transition: this.transition, transitionDir: this.transitionDir};
-			}else if(this.transitionOptions){
-				transOpts = this.transitionOptions;
-			}	
-
-			if(transOpts){
-				this.setTransitionPos(e);
-				return new TransitionEvent(this.domNode,transOpts,e).dispatch();
-			}
+			this.defaultClickAction(e);
 		},
-	
-		select: function(){
-			// summary:
-			//		Makes this widget in the selected state.
-			var parent = this.getParent();
-			if(parent.stateful){
-				parent.deselectAll();
-			}else{
-				var _this = this;
-				setTimeout(function(){
-					_this.deselect();
-				}, has('android') ? 300 : 1000);
-			}
-			domClass.add(this.domNode, "mblItemSelected");
-		},
-	
-		deselect: function(){
+
+		onClick: function(/*Event*/ /*===== e =====*/){
 			// summary:
-			//		Makes this widget in the deselected state.
-			domClass.remove(this.domNode, "mblItemSelected");
+			//		User-defined function to handle clicks.
+			// tags:
+			//		callback
 		},
-	
+
 		onAnchorLabelClicked: function(e){
 			// summary:
 			//		Stub function to connect to from your application.
 		},
 
 		layoutVariableHeight: function(){
-			var h = this.anchorNode.offsetHeight;
-			if(h === this.anchorNodeHeight){ return; }
-			this.anchorNodeHeight = h;
-			array.forEach([
-					this.rightTextNode,
-					this.rightIcon2Node,
-					this.rightIconNode,
-					this.iconNode
-				], function(n){
-					if(n){
-						var t = Math.round((h - n.offsetHeight) / 2);
+			// summary:
+			//		Lays out the current item with variable height.
+			var h = this.domNode.offsetHeight;
+			if(h === this.domNodeHeight){ return; }
+			this.domNodeHeight = h;
+			array.forEach(this._layoutChildren.concat([
+				this.rightTextNode,
+				this.rightIcon2Node,
+				this.rightIconNode,
+				this.uncheckIconNode,
+				this.iconNode,
+				this.deleteIconNode,
+				this.knobIconNode
+			]), function(n){
+				if(n){
+					var domNode = this.domNode;
+					var f = function(){
+						var t = Math.round((domNode.offsetHeight - n.offsetHeight) / 2) -
+							domStyle.get(domNode, "paddingTop");
 						n.style.marginTop = t + "px";
 					}
-				});
+					if(n.offsetHeight === 0 && n.tagName === "IMG"){
+						n.onload = f;
+					}else{
+						f();
+					}
+				}
+			}, this);
 		},
 
 		setArrow: function(){
@@ -274,9 +370,11 @@ define([
 			if(this.checked){ return; }
 			var c = "";
 			var parent = this.getParent();
-			if(this.moveTo || this.href || this.url || this.clickable){
-				if(!this.noArrow && !(parent && parent.stateful)){
-					c = this.arrowClass;
+			var opts = this.getTransOpts();
+			if(opts.moveTo || opts.href || opts.url || this.clickable){
+				if(!this.noArrow && !(parent && parent.selectOne)){
+					c = this.arrowClass || "mblDomButtonArrow";
+					domAttr.set(this.domNode, "role", "button");
 				}
 			}
 			if(c){
@@ -284,92 +382,197 @@ define([
 			}
 		},
 
-		_setIconAttr: function(icon){
-			if(!this.getParent()){ return; } // icon may be invalid because inheritParams is not called yet
-			this.icon = icon;
-			var a = this.anchorNode;
-			if(!this.iconNode){
-				if(icon){
-					var ref = this.rightIconNode || this.rightIcon2Node || this.rightTextNode || this.box;
-					this.iconNode = domConstruct.create("DIV", {className:"mblListItemIcon"}, ref, "before");
-				}
-			}else{
-				domConstruct.empty(this.iconNode);
+		_findRef: function(/*String*/type){
+			// summary:
+			//		Find an appropriate position to insert a new child node.
+			// tags:
+			//		private
+			var i, node, list = ["deleteIcon", "icon", "rightIcon", "uncheckIcon", "rightIcon2", "rightText"];
+			for(i = array.indexOf(list, type) + 1; i < list.length; i++){
+				node = this[list[i] + "Node"];
+				if(node){ return node; }
 			}
-			if(icon && icon !== "none"){
-				common.createIcon(icon, this.iconPos, null, this.alt, this.iconNode);
-				if(this.iconPos){
-					domClass.add(this.iconNode.firstChild, "mblListItemSpriteIcon");
-				}
-				domClass.remove(a, "mblListItemAnchorNoIcon");
-			}else{
-				domClass.add(a, "mblListItemAnchorNoIcon");
+			for(i = list.length - 1; i >= 0; i--){
+				node = this[list[i] + "Node"];
+				if(node){ return node.nextSibling; }
 			}
+			return this.domNode.firstChild;
 		},
-	
-		_setCheckedAttr: function(/*Boolean*/checked){
-			var parent = this.getParent();
-			if(parent && parent.select === "single" && checked){
-				array.forEach(parent.getChildren(), function(child){
-					child.set("checked", false);
-				});
+		
+		_setIcon: function(/*String*/icon, /*String*/type){
+			// tags:
+			//		private
+			if(!this._isOnLine){
+				// record the value to be able to reapply it (see the code in the startup method)
+				this["_pending_" + type] = icon;
+				return; 
+			} // icon may be invalid because inheritParams is not called yet
+			this._set(type, icon);
+			this[type + "Node"] = iconUtils.setIcon(icon, this[type + "Pos"],
+				this[type + "Node"], this[type + "Title"] || this.alt, this.domNode, this._findRef(type), "before");
+			if(this[type + "Node"]){
+				var cap = type.charAt(0).toUpperCase() + type.substring(1);
+				domClass.add(this[type + "Node"], "mblListItem" + cap);
 			}
-			this._setRightIconAttr(this.checkClass);
-
-			var icons = this.rightIconNode.childNodes;
-			if(icons.length === 1){
-				this.rightIconNode.style.display = checked ? "" : "none";
-			}else{
-				icons[0].style.display = checked ? "" : "none";
-				icons[1].style.display = !checked ? "" : "none";
+			var role = this[type + "Role"];
+			if(role){
+				this[type + "Node"].setAttribute("role", role);
 			}
+		},
 
-			domClass.toggle(this.domNode, "mblListItemChecked", checked);
-			if(parent && this.checked !== checked){
-				parent.onCheckStateChanged(this, checked);
-			}
-			this.checked = checked;
+		_setDeleteIconAttr: function(/*String*/icon){
+			// tags:
+			//		private
+			this._setIcon(icon, "deleteIcon");
 		},
-	
+
+		_setIconAttr: function(icon){
+			// tags:
+			//		private
+			this._setIcon(icon, "icon");
+		},
+
 		_setRightTextAttr: function(/*String*/text){
-			if(!this.rightTextNode){
-				this.rightTextNode = domConstruct.create("DIV", {className:"mblListItemRightText"}, this.box, "before");
+			// tags:
+			//		private
+			if(!this._templated && !this.rightTextNode){
+				// When using a template, let the template create the element.
+				this.rightTextNode = domConstruct.create("div", {className:"mblListItemRightText"}, this.labelNode, "before");
 			}
 			this.rightText = text;
 			this.rightTextNode.innerHTML = this._cv ? this._cv(text) : text;
 		},
-	
+
 		_setRightIconAttr: function(/*String*/icon){
-			if(!this.rightIconNode){
-				var ref = this.rightIcon2Node || this.rightTextNode || this.box;
-				this.rightIconNode = domConstruct.create("DIV", {className:"mblListItemRightIcon"}, ref, "before");
-			}else{
-				domConstruct.empty(this.rightIconNode);
+			// tags:
+			//		private
+			this._setIcon(icon, "rightIcon");
+		},
+
+		_setUncheckIconAttr: function(/*String*/icon){
+			// tags:
+			//		private
+			this._setIcon(icon, "uncheckIcon");
+		},
+
+		_setRightIcon2Attr: function(/*String*/icon){
+			// tags:
+			//		private
+			this._setIcon(icon, "rightIcon2");
+		},
+
+		_setCheckedAttr: function(/*Boolean*/checked){
+			// tags:
+			//		private
+			if(!this._isOnLine){
+				// record the value to be able to reapply it (see the code in the startup method)
+				this._pendingChecked = checked; 
+				return; 
+			} // icon may be invalid because inheritParams is not called yet
+			var parent = this.getParent();
+			if(parent && parent.select === "single" && checked){
+				array.forEach(parent.getChildren(), function(child){
+					child !== this && child.checked && child.set("checked", false) && domAttr.set(child.domNode, "aria-selected", "false");
+				}, this);
 			}
-			this.rightIcon = icon;
-			var arr = (icon || "").split(/,/);
-			if(arr.length === 1){
-				common.createIcon(icon, null, null, this.rightIconTitle, this.rightIconNode);
-			}else{
-				common.createIcon(arr[0], null, null, this.rightIconTitle, this.rightIconNode);
-				common.createIcon(arr[1], null, null, this.rightIconTitle, this.rightIconNode);
+			this._setRightIconAttr(this.checkClass || "mblDomButtonCheck");
+			this._setUncheckIconAttr(this.uncheckClass);
+
+			domClass.toggle(this.domNode, "mblListItemChecked", checked);
+			domClass.toggle(this.domNode, "mblListItemUnchecked", !checked);
+			domClass.toggle(this.domNode, "mblListItemHasUncheck", !!this.uncheckIconNode);
+			this.rightIconNode.style.position = (this.uncheckIconNode && !checked) ? "absolute" : "";
+
+			if(parent && this.checked !== checked){
+				parent.onCheckStateChanged(this, checked);
 			}
+			this._set("checked", checked);
+			domAttr.set(this.domNode, "aria-selected", checked ? "true" : "false");
 		},
-	
-		_setRightIcon2Attr: function(/*String*/icon){
-			if(!this.rightIcon2Node){
-				var ref = this.rightTextNode || this.box;
-				this.rightIcon2Node = domConstruct.create("DIV", {className:"mblListItemRightIcon2"}, ref, "before");
-			}else{
-				domConstruct.empty(this.rightIcon2Node);
+
+		_setBusyAttr: function(/*Boolean*/busy){
+			// tags:
+			//		private
+			var prog = this._prog;
+			if(busy){
+				if(!this._progNode){
+					this._progNode = domConstruct.create("div", {className:"mblListItemIcon"});
+					prog = this._prog = new ProgressIndicator({size:25, center:false, removeOnStop:false});
+					domClass.add(prog.domNode, this.progStyle);
+					this._progNode.appendChild(prog.domNode);
+				}
+				if(this.iconNode){
+					this.domNode.replaceChild(this._progNode, this.iconNode);
+				}else{
+					domConstruct.place(this._progNode, this._findRef("icon"), "before");
+				}
+				prog.start();
+			}else if(this._progNode){
+				if(this.iconNode){
+					this.domNode.replaceChild(this.iconNode, this._progNode);
+				}else{
+					this.domNode.removeChild(this._progNode);
+				}
+				prog.stop();
 			}
-			this.rightIcon2 = icon;
-			common.createIcon(icon, null, null, this.rightIcon2Title, this.rightIcon2Node);
+			this._set("busy", busy);
 		},
-	
-		_setLabelAttr: function(/*String*/text){
-			this.label = text;
-			this.labelNode.innerHTML = this._cv ? this._cv(text) : text;
+
+		_setSelectedAttr: function(/*Boolean*/selected){
+			// summary:
+			//		Makes this widget in the selected or unselected state.
+			// tags:
+			//		private
+			this.inherited(arguments);
+			domClass.toggle(this.domNode, this._selClass, selected);
+		},
+		
+		_setClickableAttr: function(/*Boolean*/clickable){
+			// tags:
+			//		private
+			this._set("clickable", clickable);
+			this._updateHandles();
+		},
+		
+		_setMoveToAttr: function(/*String*/moveTo){
+			// tags:
+			//		private
+			this._set("moveTo", moveTo);
+			this._updateHandles();
+		},
+		
+		_setHrefAttr: function(/*String*/href){
+			// tags:
+			//		private
+			this._set("href", href);
+			this._updateHandles();
+		},
+		
+		_setUrlAttr: function(/*String*/url){
+			// tags:
+			//		private
+			this._set("url", url);
+			this._updateHandles();
 		}
 	});
+	
+	ListItem.ChildWidgetProperties = {
+		// summary:
+		//		These properties can be specified for the children of a dojox/mobile/ListItem.
+
+		// layout: String
+		//		Specifies the position of the ListItem child ("left", "center" or "right").
+		layout: "",
+
+		// preventTouch: Boolean
+		//		Disables touch events on the ListItem child.
+		preventTouch: false
+	};
+	
+	// Since any widget can be specified as a ListItem child, mix ChildWidgetProperties
+	// into the base widget class.  (This is a hack, but it's effective.)
+	// This is for the benefit of the parser.   Remove for 2.0.  Also, hide from doc viewer.
+	lang.extend(WidgetBase, /*===== {} || =====*/ ListItem.ChildWidgetProperties);
+
+	return has("dojo-bidi") ? declare("dojox.mobile.ListItem", [ListItem, BidiListItem]) : ListItem;	
 });
diff --git a/dojox/mobile/LongListMixin.js b/dojox/mobile/LongListMixin.js
new file mode 100644
index 0000000..1aeeeb0
--- /dev/null
+++ b/dojox/mobile/LongListMixin.js
@@ -0,0 +1,304 @@
+define([ "dojo/_base/array",
+         "dojo/_base/lang",
+         "dojo/_base/declare",
+         "dojo/sniff",
+         "dojo/dom-construct",
+         "dojo/dom-geometry",
+         "dijit/registry",
+         "./common",
+         "./viewRegistry" ],
+		function(array, lang, declare, has, domConstruct, domGeometry, registry, dm, viewRegistry){
+
+	// module:
+	//		dojox/mobile/LongListMixin
+	// summary:
+	//		A mixin that enhances performance of long lists contained in scrollable views.
+
+	return declare("dojox.mobile.LongListMixin", null, {
+		// summary:
+		//		This mixin enhances performance of very long lists contained in scrollable views.
+		// description:
+		//		LongListMixin enhances a list contained in a ScrollableView
+		//		so that only a subset of the list items are actually contained in the DOM
+		//		at any given time. 
+		//		The parent must be a ScrollableView or another scrollable component
+		//		that inherits from the dojox.mobile.scrollable mixin, otherwise the mixin has
+		//		no effect. Also, editable lists are not yet supported, so lazy scrolling is
+		//		disabled if the list's 'editable' attribute is true.
+		//		If this mixin is used, list items must be added, removed or reordered exclusively
+		//		using the addChild and removeChild methods of the list. If the DOM is modified
+		//		directly (for example using list.containerNode.appendChild(...)), the list
+		//		will not behave correctly.
+		
+		// pageSize: int
+		//		Items are loaded in the DOM by chunks of this size.
+		pageSize: 20,
+		
+		// maxPages: int
+		//		When this limit is reached, previous pages will be unloaded.
+		maxPages: 5,
+		
+		// unloadPages: int
+		//		Number of pages that will be unloaded when maxPages is reached.
+		unloadPages: 1,
+		
+		startup : function(){
+			if(this._started){ return; }
+			
+			this.inherited(arguments);
+
+			if(!this.editable){
+
+				this._sv = viewRegistry.getEnclosingScrollable(this.domNode);
+
+				if(this._sv){
+
+					// Get all children already added (e.g. through markup) and initialize _items
+					this._items = this.getChildren();
+
+					// remove all existing items from the old container node
+					this._clearItems();
+
+					this.containerNode = domConstruct.create("div", null, this.domNode);
+
+					// listen to scrollTo and slideTo from the parent scrollable object
+
+					this.connect(this._sv, "scrollTo", lang.hitch(this, this._loadItems), true);
+					this.connect(this._sv, "slideTo", lang.hitch(this, this._loadItems), true);
+
+					// The _topDiv and _bottomDiv elements are place holders for the items
+					// that are not actually in the DOM at the top and bottom of the list.
+
+					this._topDiv = domConstruct.create("div", null, this.domNode, "first");
+					this._bottomDiv = domConstruct.create("div", null, this.domNode, "last");
+
+					this._reloadItems();
+				}
+			}
+		},
+		
+		_loadItems : function(toPos){
+			// summary:	Adds and removes items to/from the DOM when the list is scrolled.
+			
+			var sv = this._sv; 			// ScrollableView
+			var h = sv.getDim().d.h;
+			if(h <= 0){ return; } 			// view is hidden
+
+			var cury = -sv.getPos().y; // current y scroll position
+			var posy = toPos ? -toPos.y : cury;
+
+			// get minimum and maximum visible y positions:
+			// we use the largest area including both the current and new position
+			// so that all items will be visible during slideTo animations
+			var visibleYMin = Math.min(cury, posy),
+				visibleYMax = Math.max(cury, posy) + h;
+			
+			// add pages at top and bottom as required to fill the visible area
+			while(this._loadedYMin > visibleYMin && this._addBefore()){ }
+			while(this._loadedYMax < visibleYMax && this._addAfter()){ }
+		},
+		
+		_reloadItems: function(){
+			// summary:	Resets the internal state and reloads items according to the current scroll position.
+
+			// remove all loaded items
+			this._clearItems();
+			
+			// reset internal state
+			this._loadedYMin = this._loadedYMax = 0;
+			this._firstIndex = 0;
+			this._lastIndex = -1;
+			this._topDiv.style.height = "0px";
+			
+			this._loadItems();
+		},
+		
+		_clearItems: function(){
+			// summary: Removes all currently loaded items.
+			var c = this.containerNode;
+			array.forEach(registry.findWidgets(c), function(item){
+				c.removeChild(item.domNode);
+			});
+		},
+		
+		_addBefore: function(){
+			// summary:	Loads pages of items before the currently visible items to fill the visible area.
+			
+			var i, count;
+			
+			var oldBox = domGeometry.getMarginBox(this.containerNode);
+			
+			for(count = 0, i = this._firstIndex-1; count < this.pageSize && i >= 0; count++, i--){
+				var item = this._items[i];
+				domConstruct.place(item.domNode, this.containerNode, "first");
+				if(!item._started){
+					item.startup();
+				}
+				this._firstIndex = i;
+			}
+			
+			var newBox = domGeometry.getMarginBox(this.containerNode);
+
+			this._adjustTopDiv(oldBox, newBox);
+			
+			if(this._lastIndex - this._firstIndex >= this.maxPages*this.pageSize){
+				var toRemove = this.unloadPages*this.pageSize;
+				for(i = 0; i < toRemove; i++){
+					this.containerNode.removeChild(this._items[this._lastIndex - i].domNode);
+				}
+				this._lastIndex -= toRemove;
+				
+				newBox = domGeometry.getMarginBox(this.containerNode);
+			}
+
+			this._adjustBottomDiv(newBox);
+			
+			return count == this.pageSize;
+		},
+		
+		_addAfter: function(){
+			// summary:	Loads pages of items after the currently visible items to fill the visible area.
+			
+			var i, count;
+			
+			var oldBox = null;
+			
+			for(count = 0, i = this._lastIndex+1; count < this.pageSize && i < this._items.length; count++, i++){
+				var item = this._items[i];
+				domConstruct.place(item.domNode, this.containerNode);
+				if(!item._started){
+					item.startup();
+				}
+				this._lastIndex = i;
+			}
+			if(this._lastIndex - this._firstIndex >= this.maxPages*this.pageSize){
+				oldBox = domGeometry.getMarginBox(this.containerNode);
+				var toRemove = this.unloadPages*this.pageSize;
+				for(i = 0; i < toRemove; i++){
+					this.containerNode.removeChild(this._items[this._firstIndex + i].domNode);
+				}
+				this._firstIndex += toRemove;
+			}
+			
+			var newBox = domGeometry.getMarginBox(this.containerNode);
+
+			if(oldBox){
+				this._adjustTopDiv(oldBox, newBox);
+			}
+			this._adjustBottomDiv(newBox);
+
+			return count == this.pageSize;
+		},
+		
+		_adjustTopDiv: function(oldBox, newBox){
+			// summary:	Adjusts the height of the top filler div after items have been added/removed.
+			
+			this._loadedYMin -= newBox.h - oldBox.h;
+			this._topDiv.style.height = this._loadedYMin + "px";
+		},
+		
+		_adjustBottomDiv: function(newBox){
+			// summary:	Adjusts the height of the bottom filler div after items have been added/removed.
+			
+			// the total height is an estimate based on the average height of the already loaded items
+			var h = this._lastIndex > 0 ? (this._loadedYMin + newBox.h) / this._lastIndex : 0;
+			h *= this._items.length - 1 - this._lastIndex;
+			this._bottomDiv.style.height = h + "px";
+			this._loadedYMax = this._loadedYMin + newBox.h;
+		},
+		
+		_childrenChanged : function(){
+			// summary: Called by addChild/removeChild, updates the loaded items.
+			
+			// Whenever an item is added or removed, this may impact the loaded items,
+			// so we have to clear all loaded items and recompute them. We cannot afford 
+			// to do this on every add/remove, so we use a timer to batch these updates.
+			// There would probably be a way to update the loaded items on the fly
+			// in add/removeChild, but at the cost of much more code...
+			if(!this._qs_timer){
+				this._qs_timer = this.defer(function(){
+					delete this._qs_timer;
+					this._reloadItems();
+				});
+			}
+		},
+
+		resize: function(){
+			// summary: Loads/unloads items to fit the new size
+			this.inherited(arguments);
+			if(this._items){
+				this._loadItems();
+			}
+		},
+		
+		// The rest of the methods are overrides of _Container and _WidgetBase.
+		// We must override them because children are not all added to the DOM tree
+		// under the list node, only a subset of them will really be in the DOM,
+		// but we still want the list to look as if all children were there.
+
+		addChild : function(/* dijit._Widget */widget, /* int? */insertIndex){
+			// summary: Overrides dijit._Container
+			if(this._items){
+				if( typeof insertIndex == "number"){
+					this._items.splice(insertIndex, 0, widget);
+				}else{
+					this._items.push(widget);
+				}
+				this._childrenChanged();
+			}else{
+				this.inherited(arguments);
+			}
+		},
+
+		removeChild : function(/* Widget|int */widget){
+			// summary: Overrides dijit._Container
+			if(this._items){
+				this._items.splice(typeof widget == "number" ? widget : this._items.indexOf(widget), 1);
+				this._childrenChanged();
+			}else{
+				this.inherited(arguments);
+			}
+		},
+
+		getChildren : function(){
+			// summary: Overrides dijit._WidgetBase
+			if(this._items){
+				return this._items.slice(0);
+			}else{
+				return this.inherited(arguments);
+			}
+		},
+
+		_getSiblingOfChild : function(/* dijit._Widget */child, /* int */dir){
+			// summary: Overrides dijit._Container
+
+			if(this._items){
+				var index = this._items.indexOf(child);
+				if(index >= 0){
+					index = dir > 0 ? index++ : index--;
+				}
+				return this._items[index];
+			}else{
+				return this.inherited(arguments);
+			}
+		},
+		
+		generateList: function(/*Array*/items){
+			// summary:
+			//		Overrides dojox.mobile._StoreListMixin when the list is a store list.
+			
+			if(this._items && !this.append){
+				// _StoreListMixin calls destroyRecursive to delete existing items, not removeChild,
+				// so we must remove all logical items (i.e. clear _items) before reloading the store.
+				// And since the superclass destroys all children returned by getChildren(), and
+				// this would actually return no children because _items is now empty, we must
+				// destroy all children manually first.
+				array.forEach(this.getChildren(), function(child){
+					child.destroyRecursive();
+				});
+				this._items = [];
+			}
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dojox/mobile/Opener.js b/dojox/mobile/Opener.js
index 6b9adf5..b21dcc7 100644
--- a/dojox/mobile/Opener.js
+++ b/dojox/mobile/Opener.js
@@ -1,5 +1,6 @@
 define([
 	"dojo/_base/declare",
+	"dojo/_base/Deferred",
 	"dojo/_base/lang",
 	"dojo/_base/window",
 	"dojo/dom-class",
@@ -7,51 +8,79 @@ define([
 	"dojo/dom-style",
 	"dojo/dom-geometry",
 	"./Tooltip",
-	"./Overlay"
-], function(declare, lang, win, domClass, domConstruct, domStyle, domGeometry, Tooltip, Overlay){
+	"./Overlay",
+	"./lazyLoadUtils"
+], function(declare, Deferred, lang, win, domClass, domConstruct, domStyle, domGeometry, Tooltip, Overlay, lazyLoadUtils){
 
-	/*=====
-		Tooltip = dojox.mobile.Tooltip;
-		Overlay = dojox.mobile.Overlay;
-	=====*/
 	var isOverlay = domClass.contains(win.doc.documentElement, "dj_phone");
+	
 	var cls = declare("dojox.mobile.Opener", isOverlay ? Overlay : Tooltip, {
 		// summary:
-		//		A non-templated popup widget that will use either Tooltip or Overlay depending on screen size
-		//
+		//		A non-templated popup widget that will use either Tooltip or 
+		//		Overlay depending on screen size.
+
+		// lazy: String
+		//		If true, the content of the widget, which includes dojo markup,
+		//		is instantiated lazily. That is, only when the widget is opened
+		//		by the user, the required modules are loaded and the content
+		//		widgets are instantiated.
+		lazy: false,
+
+		// requires: String
+		//		Comma-separated required module names to be lazily loaded. This
+		//		is effective only when lazy=true. All the modules specified with
+		//		dojoType and their depending modules are automatically loaded
+		//		when the widget is opened. However, if you need other extra
+		//		modules to be loaded, use this parameter.
+		requires: "",
+
 		buildRendering: function(){
 			this.inherited(arguments);
-			this.cover = domConstruct.create('div', { onclick: lang.hitch(this, '_onBlur'), 'class': 'mblOpenerUnderlay', style: { top:'0px', left:'0px', width:'0px', height:'0px', position: isOverlay ? 'absolute' : 'fixed', backgroundColor:'transparent', overflow:'hidden', zIndex:'-1' }}, this.domNode, 'first');
-			this.connect(null, win.global.onorientationchange !== undefined ? "onorientationchange" : "onresize", lang.hitch(this, function(){
-				if(domStyle.get(this.cover, "height") !== '0px'){ // resize cover when shown
-					this._resizeCover();
-				}
-			}));
+			this.cover = domConstruct.create('div', {
+				onclick: lang.hitch(this, '_onBlur'), 'class': 'mblOpenerUnderlay',
+				style: { position: isOverlay ? 'absolute' : 'fixed', backgroundColor:'transparent', overflow:'hidden', zIndex:'-1' }
+			}, this.domNode, 'first');
 		},
 
 		onShow: function(/*DomNode*/node){},
 		onHide: function(/*DomNode*/node, /*Anything*/v){},
 
 		show: function(node, positions){
+			if(this.lazy){
+				this.lazy = false;
+				var _this = this;
+				return Deferred.when(lazyLoadUtils.instantiateLazyWidgets(this.domNode, this.requires), function(){
+					return _this.show(node, positions);
+				});
+			}
 			this.node = node;
 			this.onShow(node);
-			this._resizeCover();
+			domStyle.set(this.cover, { top:'0px', left:'0px', width:'0px', height:'0px' }); // move cover temporarily to calculate domNode vertical position correctly
+			this._resizeCover(domGeometry.position(this.domNode, false)); // must be before this.inherited(arguments) for Tooltip sizing
 			return this.inherited(arguments);
 		},
 
 		hide: function(/*Anything*/ val){
 			this.inherited(arguments);
-			domStyle.set(this.cover, { height:'0px' });
 			this.onHide(this.node, val);
 		},
 		
-		_resizeCover: function(){
+		_reposition: function(){
+			// tags:
+			//		private
+			var popupPos = this.inherited(arguments);
+			this._resizeCover(popupPos);
+			return popupPos;
+		},
+
+		_resizeCover: function(popupPos){
+			// tags:
+			//		private
 			if(isOverlay){
-				domStyle.set(this.cover, { height:'0px' }); // hide cover temporarily to calculate domNode size
-				setTimeout(lang.hitch(this, function(){ // show cover after positioning popup
-					var pos = domGeometry.position(this.domNode, false);
-					domStyle.set(this.cover, { top:-pos.y+'px', left:-pos.x+'px', width:(pos.w+pos.x)+'px', height:(pos.h+pos.y)+'px' });
-				}), 0);
+				if(parseInt(domStyle.get(this.cover, 'top')) != -popupPos.y || parseInt(domStyle.get(this.cover, 'height')) != popupPos.y){
+					var x = Math.max(popupPos.x, 0); // correct onorientationchange values
+					domStyle.set(this.cover, { top:-popupPos.y+'px', left:-x+'px', width:popupPos.w+x+'px', height:popupPos.y+'px' });
+				}
 			}else{
 				domStyle.set(this.cover, { 
 					width:Math.max(win.doc.documentElement.scrollWidth || win.body().scrollWidth || win.doc.documentElement.clientWidth)+'px', 
@@ -59,8 +88,10 @@ define([
 				});
 			}			
 		},
-		
+
 		_onBlur: function(e){
+			// tags:
+			//		private
 			var ret = this.onBlur(e);
 			if(ret !== false){ // only exactly false prevents hide()
 				this.hide(e);
diff --git a/dojox/mobile/Overlay.js b/dojox/mobile/Overlay.js
index 5db7b0d..57445c9 100644
--- a/dojox/mobile/Overlay.js
+++ b/dojox/mobile/Overlay.js
@@ -1,7 +1,7 @@
 define([
 	"dojo/_base/declare",
 	"dojo/_base/lang",
-	"dojo/_base/sniff",
+	"dojo/sniff",
 	"dojo/_base/window",
 	"dojo/dom-class",
 	"dojo/dom-geometry",
@@ -9,19 +9,43 @@ define([
 	"dojo/window",
 	"dijit/_WidgetBase",
 	"dojo/_base/array",
-	"dijit/registry"
-], function(declare, lang, has, win, domClass, domGeometry, domStyle, windowUtils, WidgetBase, array, registry){
+	"dijit/registry",
+	"dojo/touch",
+	"./_css3"
+], function(declare, lang, has, win, domClass, domGeometry, domStyle, windowUtils, WidgetBase, array, registry, touch, css3){
 
-	/*=====
-		WidgetBase = dijit._WidgetBase;
-	=====*/
 	return declare("dojox.mobile.Overlay", WidgetBase, {
 		// summary:
-		//		A non-templated widget that animates up from the bottom, overlaying the current content
-		//
+		//		A non-templated widget that animates up from the bottom, 
+		//		overlaying the current content.
 
+		// baseClass: String
+		//		The name of the CSS class of this widget.
 		baseClass: "mblOverlay mblOverlayHidden",
 
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(!this.containerNode){
+				// set containerNode so that getChildren() works
+				this.containerNode = this.domNode;
+			}
+		},
+
+		_reposition: function(){
+			// summary:
+			//		Position the overlay at the bottom
+			// tags:
+			//		private
+			var popupPos = domGeometry.position(this.domNode);
+			var vp = windowUtils.getBox();
+			if((popupPos.y+popupPos.h) != vp.h // TODO: should be a has() test for position:fixed not scrolling
+				|| (domStyle.get(this.domNode, 'position') != 'absolute' && has('android') < 3)){ // android 2.x supports position:fixed but child transforms don't persist
+				popupPos.y = vp.t + vp.h - popupPos.h;
+				domStyle.set(this.domNode, { position: "absolute", top: popupPos.y + "px", bottom: "auto" });
+			}
+			return popupPos;
+		},
+
 		show: function(/*DomNode?*/aroundNode){
 			// summary:
 			//		Scroll the overlay up into view
@@ -30,61 +54,62 @@ define([
 					w.resize();
 				}
 			});
-			var vp, popupPos;
-			var reposition = lang.hitch(this, function(){
-				domStyle.set(this.domNode, { position: "", top: "auto", bottom: "0px" });
-				popupPos = domGeometry.position(this.domNode);
-				vp = windowUtils.getBox();
-				if((popupPos.y+popupPos.h) != vp.h // TODO: should be a has() test for position:fixed not scrolling
-					|| has('android') < 3){ // android 2.x supports position:fixed but child transforms don't persist
-					popupPos.y = vp.t + vp.h - popupPos.h;
-					domStyle.set(this.domNode, { position: "absolute", top: popupPos.y + "px", bottom: "auto" });
-				}
-			});
-			reposition();
+			var popupPos = this._reposition();
 			if(aroundNode){
 				var aroundPos = domGeometry.position(aroundNode);
 				if(popupPos.y < aroundPos.y){ // if the aroundNode is under the popup, try to scroll it up
 					win.global.scrollBy(0, aroundPos.y + aroundPos.h - popupPos.y);
-					reposition();
+					this._reposition();
 				}
 			}
-			domClass.replace(this.domNode, ["mblCoverv", "mblIn"], ["mblOverlayHidden", "mblRevealv", "mblOut", "mblReverse"]);
 			var _domNode = this.domNode;
-			setTimeout(function(){
+			domClass.replace(_domNode, ["mblCoverv", "mblIn"], ["mblOverlayHidden", "mblRevealv", "mblOut", "mblReverse", "mblTransition"]);
+			this.defer(function(){
+				var handler = this.connect(_domNode, css3.name("transitionEnd"), function(){
+					this.disconnect(handler);
+					domClass.remove(_domNode, ["mblCoverv", "mblIn", "mblTransition"]);
+					this._reposition();
+				});
 				domClass.add(_domNode, "mblTransition");
 			}, 100);
-			var timeoutHandler = null;
-			this._moveHandle = this.connect(win.doc.documentElement, "ontouchmove", function(){
-				if(timeoutHandler){
-					clearTimeout(timeoutHandler);
+			var skipReposition = false;
+
+			this._moveHandle = this.connect(win.doc.documentElement, touch.move,
+				function(){
+					skipReposition = true;
 				}
-				timeoutHandler = setTimeout(function(){
-					reposition();
-					timeoutHandler = null;
-				}, 0);
-			});
+			);
+			this._repositionTimer = setInterval(lang.hitch(this, function(){
+				if(skipReposition){ // don't reposition if busy
+					skipReposition = false;
+					return;
+				}
+				this._reposition();
+			}), 50); // yield a short time to allow for consolidation for better CPU throughput
+			return popupPos;
 		},
 
 		hide: function(){
 			// summary:
 			//		Scroll the overlay down and then make it invisible
+			var _domNode = this.domNode;
 			if(this._moveHandle){
 				this.disconnect(this._moveHandle);
 				this._moveHandle = null;
+				clearInterval(this._repositionTimer);
+				this._repositionTimer = null;
 			}
-			if(has("webkit")){
-				var handler = this.connect(this.domNode, "webkitTransitionEnd", function(){
-					this.disconnect(handler);
-					domClass.replace(this.domNode, ["mblOverlayHidden"], ["mblRevealv", "mblOut", "mblReverse", "mblTransition"]);
-				});
-				domClass.replace(this.domNode, ["mblRevealv", "mblOut", "mblReverse"], ["mblCoverv", "mblIn", "mblTransition"]);
-				var _domNode = this.domNode;
-				setTimeout(function(){
+			if(has("css3-animations")){
+				domClass.replace(_domNode, ["mblRevealv", "mblOut", "mblReverse"], ["mblCoverv", "mblIn", "mblOverlayHidden", "mblTransition"]);
+				this.defer(function(){
+					var handler = this.connect(_domNode, css3.name("transitionEnd"), function(){
+						this.disconnect(handler);
+						domClass.replace(_domNode, ["mblOverlayHidden"], ["mblRevealv", "mblOut", "mblReverse", "mblTransition"]);
+					});
 					domClass.add(_domNode, "mblTransition");
 				}, 100);
 			}else{
-				domClass.replace(this.domNode, ["mblOverlayHidden"], ["mblCoverv", "mblIn", "mblRevealv", "mblOut", "mblReverse"]);
+				domClass.replace(_domNode, ["mblOverlayHidden"], ["mblCoverv", "mblIn", "mblRevealv", "mblOut", "mblReverse"]);
 			}
 		},
 
diff --git a/dojox/mobile/PageIndicator.js b/dojox/mobile/PageIndicator.js
index 44c24d5..0bbc9eb 100644
--- a/dojox/mobile/PageIndicator.js
+++ b/dojox/mobile/PageIndicator.js
@@ -1,24 +1,16 @@
 define([
 	"dojo/_base/connect",
 	"dojo/_base/declare",
-	"dojo/_base/window",
 	"dojo/dom",
 	"dojo/dom-class",
 	"dojo/dom-construct",
-	"dijit/registry",	// registry.byNode
+	"dijit/registry",
 	"dijit/_Contained",
 	"dijit/_WidgetBase"
-], function(connect, declare, win, dom, domClass, domConstruct, registry, Contained, WidgetBase){
-
-/*=====
-	var Contained = dijit._Contained;
-	var WidgetBase = dijit._WidgetBase;
-=====*/
+], function(connect, declare, dom, domClass, domConstruct, registry, Contained, WidgetBase){
 
 	// module:
 	//		dojox/mobile/PageIndicator
-	// summary:
-	//		A current page indicator.
 
 	return declare("dojox.mobile.PageIndicator", [WidgetBase, Contained],{
 		// summary:
@@ -26,8 +18,8 @@ define([
 		// description:
 		//		PageIndicator displays a series of gray and white dots to
 		//		indicate which page is currently being viewed. It can typically
-		//		be used with dojox.mobile.SwapView. It is also internally used
-		//		in dojox.mobile.Carousel.
+		//		be used with dojox/mobile/SwapView. It is also internally used
+		//		in dojox/mobile/Carousel.
 
 		// refId: String
 		//		An ID of a DOM node to be searched. Siblings of the reference
@@ -35,22 +27,25 @@ define([
 		//		will be the reference node.
 		refId: "",
 
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblPageIndicator",
+
 		buildRendering: function(){
-			this.domNode = this.srcNodeRef || win.doc.createElement("DIV");
-			this.domNode.className = "mblPageIndicator";
-			this._tblNode = domConstruct.create("TABLE", {className:"mblPageIndicatorContainer"}, this.domNode);
+			this.inherited(arguments);
+			this._tblNode = domConstruct.create("table", {className:"mblPageIndicatorContainer"}, this.domNode);
 			this._tblNode.insertRow(-1);
-			this.connect(this.domNode, "onclick", "onClick");
-			connect.subscribe("/dojox/mobile/viewChanged", this, function(view){
+			this.connect(this.domNode, "onclick", "_onClick");
+			this.subscribe("/dojox/mobile/viewChanged", function(view){
 				this.reset();
 			});
 		},
 
 		startup: function(){
 			var _this = this;
-			setTimeout(function(){ // to wait until views' visibility is determined
+			_this.defer(function(){ // to wait until views' visibility is determined
 				_this.reset();
-			}, 0);
+			});
 		},
 
 		reset: function(){
@@ -70,7 +65,7 @@ define([
 				domConstruct.empty(r);
 				for(i = 0; i < a.length; i++){
 					c = a[i];
-					dot = domConstruct.create("DIV", {className:"mblPageIndicatorDot"});
+					dot = domConstruct.create("div", {className:"mblPageIndicatorDot"});
 					r.insertCell(-1).appendChild(dot);
 				}
 			}
@@ -89,16 +84,28 @@ define([
 		isView: function(node){
 			// summary:
 			//		Returns true if the given node is a view.
-			return (node && node.nodeType === 1 && domClass.contains(node, "mblView"));
+			return (node && node.nodeType === 1 && domClass.contains(node, "mblView")); // Boolean
 		},
 
-		onClick: function(e){
+		_onClick: function(e){
+			// summary:
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(this.onClick(e) === false){ return; } // user's click action
 			if(e.target !== this.domNode){ return; }
 			if(e.layerX < this._tblNode.offsetLeft){
 				connect.publish("/dojox/mobile/prevPage", [this]);
 			}else if(e.layerX > this._tblNode.offsetLeft + this._tblNode.offsetWidth){
 				connect.publish("/dojox/mobile/nextPage", [this]);
 			}
+		},
+
+		onClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User-defined function to handle clicks.
+			// tags:
+			//		callback
 		}
 	});
 });
diff --git a/dojox/mobile/Pane.js b/dojox/mobile/Pane.js
new file mode 100644
index 0000000..31403c3
--- /dev/null
+++ b/dojox/mobile/Pane.js
@@ -0,0 +1,38 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dijit/_Contained",
+	"dijit/_WidgetBase"
+], function(array, declare, Contained, WidgetBase){
+
+	// module:
+	//		dojox/mobile/Pane
+
+	return declare("dojox.mobile.Pane", [WidgetBase, Contained], {
+		// summary:
+		//		A simple pane widget.
+		// description:
+		//		Pane is a simple general-purpose pane widget.
+		//		It is a widget, but can be regarded as a simple `<div>` element.
+
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblPane",
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(!this.containerNode){
+				// set containerNode so that getChildren() works
+				this.containerNode = this.domNode;
+			}
+		},
+
+		resize: function(){
+			// summary:
+			//		Calls resize() of each child widget.
+			array.forEach(this.getChildren(), function(child){
+				if(child.resize){ child.resize(); }
+			});
+		}
+	});
+});
diff --git a/dojox/mobile/ProgressBar.js b/dojox/mobile/ProgressBar.js
new file mode 100644
index 0000000..9ae06a2
--- /dev/null
+++ b/dojox/mobile/ProgressBar.js
@@ -0,0 +1,79 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dijit/_WidgetBase"
+], function(declare, domClass, domConstruct, WidgetBase){
+
+	// module:
+	//		dojox/mobile/ProgressBar
+
+	return declare("dojox.mobile.ProgressBar", WidgetBase, {
+		// summary:
+		//		A widget that shows the progress of a task.
+		// description:
+		//		The current progress can be specified either using a number (0 to maximum) 
+		//		or percentage (0% to 100%). The setter of the 'value' property can be used to
+		//		update the degree of completion of the task.
+		
+		// value: String
+		//		Number ("0" to maximum) or percentage ("0%" to "100%")
+		//		indicating the degree of completion of the task.
+		value: "0",
+
+		// maximum: Number
+		//		Maximum value.
+		maximum: 100,
+
+		// label: String
+		//		A text to be shown at the center of the progress bar.
+		label: "",
+
+		/* internal properties */	
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblProgressBar",
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.progressNode = domConstruct.create("div", {
+				className: "mblProgressBarProgress"
+			}, this.domNode);
+			this.msgNode = domConstruct.create("div", {
+				className: "mblProgressBarMsg"
+			}, this.domNode);
+		},
+
+		_setValueAttr: function(/*String*/value){
+			// summary:
+			//		Sets the new value to the progress bar.
+			// tags:
+			//		private
+			value += "";
+			this._set("value", value);
+
+			var percent = Math.min(100, (value.indexOf("%") != -1 ?
+				parseFloat(value) : this.maximum ? 100 * value / this.maximum : 0));
+			this.progressNode.style.width = percent + "%";
+			domClass.toggle(this.progressNode, "mblProgressBarNotStarted", !percent);
+			domClass.toggle(this.progressNode, "mblProgressBarComplete", percent == 100);
+			this.onChange(value, this.maximum, percent);
+		},
+
+		_setLabelAttr: function(label){
+			// summary:
+			//		Sets a label text to be shown at the center of the progress bar.
+			// tags:
+			//		private
+			this.msgNode.innerHTML = label;
+		},
+
+		onChange: function(/*Number*/ /*===== percent =====*/){
+			// summary:
+			//		User-defined function called when progress updates.
+			// tags:
+			//		callback
+		}
+	});
+});
diff --git a/dojox/mobile/ProgressIndicator.js b/dojox/mobile/ProgressIndicator.js
index 083ea69..bfe5ce5 100644
--- a/dojox/mobile/ProgressIndicator.js
+++ b/dojox/mobile/ProgressIndicator.js
@@ -1,83 +1,139 @@
 define([
 	"dojo/_base/config",
 	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-class",
 	"dojo/dom-construct",
+	"dojo/dom-geometry",
 	"dojo/dom-style",
-	"dojo/has"
-], function(config, declare, domConstruct, domStyle, has){
+	"dojo/has",
+	"dijit/_Contained",
+	"dijit/_WidgetBase",
+	"./_css3"
+], function(config, declare, lang, domClass, domConstruct, domGeometry, domStyle, has, Contained, WidgetBase, css3){
 
 	// module:
 	//		dojox/mobile/ProgressIndicator
-	// summary:
-	//		A progress indication widget.
 
-	var cls = declare("dojox.mobile.ProgressIndicator", null, {
+	var cls = declare("dojox.mobile.ProgressIndicator", [WidgetBase, Contained], {
 		// summary:
 		//		A progress indication widget.
 		// description:
 		//		ProgressIndicator is a round spinning graphical representation
-		//		that indicates the current task is on-going.
+		//		that indicates the current task is ongoing.
 
 		// interval: Number
 		//		The time interval in milliseconds for updating the spinning
 		//		indicator.
 		interval: 100,
 
-		// colors: Array
-		//		An array of indicator colors.
-		colors: [
-			"#C0C0C0", "#C0C0C0", "#C0C0C0", "#C0C0C0",
-			"#C0C0C0", "#C0C0C0", "#B8B9B8", "#AEAFAE",
-			"#A4A5A4", "#9A9A9A", "#8E8E8E", "#838383"
-		],
+		// size: [const] Number
+		//		The size of the indicator in pixels.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		size: 40,
+
+		// removeOnStop: Boolean
+		//		If true, this widget is removed from the parent node
+		//		when stop() is called.
+		removeOnStop: true,
+
+		// startSpinning: Boolean
+		//		If true, calls start() to run the indicator at startup.
+		startSpinning: false,
+
+		// center: Boolean
+		//		If true, the indicator is displayed as center aligned.
+		center: true,
+
+		// colors: String[]
+		//		An array of indicator colors. 12 colors have to be given.
+		//		If colors are not specified, CSS styles
+		//		(mblProg0Color - mblProg11Color) are used.
+		colors: null,
+
+		/* internal properties */
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.	
+		baseClass: "mblProgressIndicator",
 
 		constructor: function(){
+			// summary:
+			//		Creates a new instance of the class.
+			this.colors = [];
 			this._bars = [];
-			this.domNode = domConstruct.create("DIV");
-			this.domNode.className = "mblProgContainer";
-			if(config["mblAndroidWorkaround"] !== false && has('android') >= 2.2 && has('android') < 3){
-				// workaround to avoid the side effects of the fixes for android screen flicker problem
-				domStyle.set(this.domNode, "webkitTransform", "translate3d(0,0,0)");
+		},
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(this.center){
+				domClass.add(this.domNode, "mblProgressIndicatorCenter");
 			}
-			this.spinnerNode = domConstruct.create("DIV", null, this.domNode);
-			for(var i = 0; i < this.colors.length; i++){
-				var div = domConstruct.create("DIV", {className:"mblProg mblProg"+i}, this.spinnerNode);
+			this.containerNode = domConstruct.create("div", {className:"mblProgContainer"}, this.domNode);
+			this.spinnerNode = domConstruct.create("div", null, this.containerNode);
+			for(var i = 0; i < 12; i++){
+				var div = domConstruct.create("div", {className:"mblProg mblProg"+i}, this.spinnerNode);
 				this._bars.push(div);
 			}
+			this.scale(this.size);
+			if(this.startSpinning){
+				this.start();
+			}
 		},
-	
+
+		scale: function(/*Number*/size){
+			// summary:
+			//		Changes the size of the indicator.
+			// size:
+			//		The size of the indicator in pixels.
+			var scale = size / 40;
+			domStyle.set(this.containerNode, css3.add({}, {
+				transform: "scale(" + scale + ")",
+				transformOrigin: "0 0"
+			}));
+			domGeometry.setMarginBox(this.domNode, {w:size, h:size});
+			domGeometry.setMarginBox(this.containerNode, {w:size / scale, h:size / scale});
+		},
+
 		start: function(){
 			// summary:
-			//		Starts the ProgressIndicator spinning.
+			//		Starts the spinning of the ProgressIndicator.
 			if(this.imageNode){
 				var img = this.imageNode;
-				var l = Math.round((this.domNode.offsetWidth - img.offsetWidth) / 2);
-				var t = Math.round((this.domNode.offsetHeight - img.offsetHeight) / 2);
+				var l = Math.round((this.containerNode.offsetWidth - img.offsetWidth) / 2);
+				var t = Math.round((this.containerNode.offsetHeight - img.offsetHeight) / 2);
 				img.style.margin = t+"px "+l+"px";
 				return;
 			}
 			var cntr = 0;
 			var _this = this;
-			var n = this.colors.length;
+			var n = 12;
 			this.timer = setInterval(function(){
 				cntr--;
 				cntr = cntr < 0 ? n - 1 : cntr;
 				var c = _this.colors;
 				for(var i = 0; i < n; i++){
 					var idx = (cntr + i) % n;
-					_this._bars[i].style.backgroundColor = c[idx];
+					if(c[idx]){
+						_this._bars[i].style.backgroundColor = c[idx];
+					}else{
+						domClass.replace(_this._bars[i],
+										 "mblProg" + idx + "Color",
+										 "mblProg" + (idx === n - 1 ? 0 : idx + 1) + "Color");
+					}
 				}
 			}, this.interval);
 		},
-	
+
 		stop: function(){
 			// summary:
-			//		Stops the ProgressIndicator spinning.
+			//		Stops the spinning of the ProgressIndicator.
 			if(this.timer){
 				clearInterval(this.timer);
 			}
 			this.timer = null;
-			if(this.domNode.parentNode){
+			if(this.removeOnStop && this.domNode && this.domNode.parentNode){
 				this.domNode.parentNode.removeChild(this.domNode);
 			}
 		},
@@ -87,22 +143,29 @@ define([
 			//		Sets an indicator icon image file (typically animated GIF).
 			//		If null is specified, restores the default spinner.
 			if(file){
-				this.imageNode = domConstruct.create("IMG", {src:file}, this.domNode);
+				this.imageNode = domConstruct.create("img", {src:file}, this.containerNode);
 				this.spinnerNode.style.display = "none";
 			}else{
 				if(this.imageNode){
-					this.domNode.removeChild(this.imageNode);
+					this.containerNode.removeChild(this.imageNode);
 					this.imageNode = null;
 				}
 				this.spinnerNode.style.display = "";
 			}
+		},
+
+		destroy: function(){
+			this.inherited(arguments);
+			if(this === cls._instance){
+				cls._instance = null;
+			}
 		}
 	});
 
 	cls._instance = null;
-	cls.getInstance = function(){
+	cls.getInstance = function(props){
 		if(!cls._instance){
-			cls._instance = new cls();
+			cls._instance = new cls(props);
 		}
 		return cls._instance;
 	};
diff --git a/dojox/mobile/README b/dojox/mobile/README
index d9ede45..1e52a28 100755
--- a/dojox/mobile/README
+++ b/dojox/mobile/README
@@ -1,57 +1,42 @@
 -------------------------------------------------------------------------------
-Project Name:  dojox.mobile
+Project Name:  dojox/mobile
 -------------------------------------------------------------------------------
 Version 1.0
 Release date: 03/23/2010
 -------------------------------------------------------------------------------
 Project state:
-dojox.mobile: stable
-dojox.mobile.app: experimental
+dojox/mobile: stable
+dojox/mobile/app: experimental; please use dojox/app instead.
 -------------------------------------------------------------------------------
-[ NO ]	l18n support?
-[ NO ]	a11y support?
+[ YES ]	 l18n support?
+[ YES ]	 a11y support?
 -------------------------------------------------------------------------------
 Credits:
        Jared Jurkiewicz (jared.jurkiewicz at gmail.com)
-       Yoshiroh Kamiyama (Contributor to Jared of base code).
-       Shane O'Sullivan (dojox.mobile.app)
+       Yoshiroh Kamiyama
+       Shane O'Sullivan (dojox/mobile/app)
+       Soyhy Lim
+       Sebastien Brunot
+       Eric Durocher
+       Sergey Grebnov
+       Christophe Jolif
+       Damien Mandrioli
+       Adrian Vasiliu
 
 -------------------------------------------------------------------------------
 Project description
 
-This project tries to solve an area lacking in dojo, namely better 
-support for mobile devices.  This project provides through CSS3 and
-custom styles, interfaces that display and work well on mobile devices 
-such as the Android and iPhone Smart Phones.
+Dojo Mobile provides widgets that can be used to build web-based applications 
+for mobile devices (iOS, Android, BlackBerry, Windows Phone 8). 
 
-The code is deliberately kept as lightweight as possible, using CSS3 animations
-and the like to perform the effects.  There is a compat.js, which will simulate
-most of the effects using dojo.animateProperty and dojox.fx where possible on
-browsers such as FireFox and IE.  It will not load by default, it has to be
-required in separately.
+Dojo Mobile is designed to be as lightweight as possible to achieve a better 
+user experience on mobile devices. 
 -------------------------------------------------------------------------------
 Dependencies:
-        dojo base
-        dijit/_WidgetBase.js
+        dojo
+        dijit
 -------------------------------------------------------------------------------
 Documentation
         Documentation resides at:
         http://dojotoolkit.org/reference-guide/dojox/mobile.html
-
--------------------------------------------------------------------------------
-Installation instructions
-
-Grab the following from the Dojo SVN Repository:
-http://svn.dojotoolkit.org/src/dojox/trunk/mobile/*
-http://svn.dojotoolkit.org/src/dojox/trunk/mobile.js
-
-Install into the following directory structure:
-/dojox/mobile.js
-/dojox/mobile/*
-
-...which should be at the same level as your Dojo checkout.
-
-then dojo.require("dojox.mobile") in your application to load it.
-
 -------------------------------------------------------------------------------
-
diff --git a/dojox/mobile/RadioButton.js b/dojox/mobile/RadioButton.js
index da29f0b..affd654 100644
--- a/dojox/mobile/RadioButton.js
+++ b/dojox/mobile/RadioButton.js
@@ -3,18 +3,19 @@ define([
 	"dijit/form/_RadioButtonMixin",
 	"./CheckBox"
 ], function(declare, RadioButtonMixin, CheckBox){
-	/*=====
-		CheckBox = dojox.mobile.CheckBox;
-		RadioButtonMixin = dijit.form._RadioButtonMixin;
-	=====*/
+
 	return declare("dojox.mobile.RadioButton", [CheckBox, RadioButtonMixin], {
 		// summary:
-		//		A non-templated radiobutton widget that can be in two states (checked or not).
+		//		A non-templated radio button widget that can be in two states (checked or not checked).
 
-		// Override automatic assigning type --> node, it causes exception on IE8.
-		// Instead, type must be specified as this.type when the node is created, as part of the original DOM
+		// _setTypeAttr: [private] Function 
+		//		Overrides the automatic assignment of type to nodes, because it causes
+		//		exception on IE. Instead, the type must be specified as this.type
+		//		when the node is created, as part of the original DOM.
 		_setTypeAttr: null,
 
+		// baseClass: String
+		//		The name of the CSS class of this widget.
 		baseClass: "mblRadioButton"
 	});
 });
diff --git a/dojox/mobile/Rating.js b/dojox/mobile/Rating.js
new file mode 100644
index 0000000..f259a40
--- /dev/null
+++ b/dojox/mobile/Rating.js
@@ -0,0 +1,77 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-construct",
+	"dijit/_WidgetBase",
+	"./iconUtils"
+], function(declare, lang, domConstruct, WidgetBase, iconUtils){
+
+	// module:
+	//		dojox/mobile/Rating
+
+	return declare("dojox.mobile.Rating", WidgetBase, {
+		// summary:
+		//		A widget that displays a rating, usually with stars.
+		// description:
+		//		This widget simply shows the specified number of stars. It is a
+		//		read-only widget, and has no editing capability.
+
+		// image: String
+		//		Path to a star image, which includes three stars, full star,
+		//		empty star, and half star, from left to right.
+		image: "",
+
+		// numStars: Number
+		//		The number of stars to show.
+		numStars: 5,
+
+		// value: Number
+		//		The current value of the Rating.
+		value: 0,
+
+		// alt: String
+		//		An alternate text for the icon image.
+		alt: "",
+
+		/* internal properties */
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblRating",
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.domNode.style.display = "inline-block";
+			var img = this.imgNode = domConstruct.create("img");
+			this.connect(img, "onload",
+				lang.hitch(this, function(){ this.set("value", this.value); }));
+			iconUtils.createIcon(this.image, null, img);
+		},
+
+		_setValueAttr: function(/*Number*/value){
+			// summary:
+			//		Sets the value of the Rating.
+			// tags:
+			//		private
+			this._set("value", value);
+			var h = this.imgNode.height;
+			if(h == 0){ return; } // loading of image has not been completed yet
+			domConstruct.empty(this.domNode);
+			var i, left, w = this.imgNode.width / 3;
+			for(i = 0; i < this.numStars; i++){
+				if(i <= value - 1){
+					left = 0; // full
+				}else if(i >= value){
+					left = w; // empty
+				}else{
+					left = w * 2; // half
+				}
+				var parent = domConstruct.create("div", {
+					style: {"float": "left"}
+				}, this.domNode);
+				iconUtils.createIcon(this.image,
+					"0," + left + "," + w + "," + h, null, this.alt, parent);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/RoundRect.js b/dojox/mobile/RoundRect.js
index ef5b815..846da3a 100644
--- a/dojox/mobile/RoundRect.js
+++ b/dojox/mobile/RoundRect.js
@@ -1,24 +1,13 @@
 define([
-	"dojo/_base/array",
 	"dojo/_base/declare",
-	"dojo/_base/window",
-	"dijit/_Contained",
-	"dijit/_Container",
-	"dijit/_WidgetBase"
-], function(array, declare, win, Contained, Container, WidgetBase){
-
-/*=====
-	var Contained = dijit._Contained;
-	var Container = dijit._Container;
-	var WidgetBase = dijit._WidgetBase;
-=====*/
+	"dojo/dom-class",
+	"./Container"
+], function(declare, domClass, Container){
 
 	// module:
 	//		dojox/mobile/RoundRect
-	// summary:
-	//		A simple round rectangle container.
 
-	return declare("dojox.mobile.RoundRect", [WidgetBase, Container, Contained], {
+	return declare("dojox.mobile.RoundRect", Container, {
 		// summary:
 		//		A simple round rectangle container.
 		// description:
@@ -28,21 +17,24 @@ define([
 		//		if you use RoundRect, you can get a round rectangle even on
 		//		non-CSS3 browsers such as (older) IE.
 
-		// shadow: Boolean
-		//		If true, adds a shadow effect to the container element.
+		// shadow: [const] Boolean
+		//		If true, adds a shadow effect to the container element by adding
+		//		the CSS class "mblShadow" to widget's domNode. The default value
+		//		is false. Note that changing the value of the property after
+		//		the widget creation has no effect.
 		shadow: false,
 
-		buildRendering: function(){
-			this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("DIV");
-			this.domNode.className = this.shadow ? "mblRoundRect mblShadow" : "mblRoundRect";
-		},
+		/* internal properties */	
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblRoundRect",
 
-		resize: function(){
-			// summary:
-			//		Calls resize() of each child widget.
-			array.forEach(this.getChildren(), function(child){
-				if(child.resize){ child.resize(); }
-			});
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(this.shadow){
+				domClass.add(this.domNode, "mblShadow");
+			}
 		}
 	});
 });
diff --git a/dojox/mobile/RoundRectCategory.js b/dojox/mobile/RoundRectCategory.js
index 32f1c75..7334ee0 100644
--- a/dojox/mobile/RoundRectCategory.js
+++ b/dojox/mobile/RoundRectCategory.js
@@ -1,40 +1,53 @@
 define([
 	"dojo/_base/declare",
 	"dojo/_base/window",
+	"dojo/dom-construct",
 	"dijit/_Contained",
-	"dijit/_WidgetBase"
-], function(declare, win, Contained, WidgetBase){
-
-/*=====
-	var Contained = dijit._Contained;
-	var WidgetBase = dijit._WidgetBase;
-=====*/
+	"dijit/_WidgetBase",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/RoundRectCategory"
+], function(declare, win, domConstruct, Contained, WidgetBase, has, BidiRoundRectCategory){
 
 	// module:
 	//		dojox/mobile/RoundRectCategory
-	// summary:
-	//		A category header for a rounded rectangle list.
 
-	return declare("dojox.mobile.RoundRectCategory", [WidgetBase, Contained],{
+	var RoundRectCategory = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiRoundRectCategory" : "dojox.mobile.RoundRectCategory", [WidgetBase, Contained], {
 		// summary:
 		//		A category header for a rounded rectangle list.
 
 		// label: String
-		//		A label text for the widget.
+		//		A label of the category. If the label is not specified,
+		//		innerHTML is used as a label.
 		label: "",
 
+		// tag: String
+		//		A name of html tag to create as domNode.
+		tag: "h2",
+
+		/* internal properties */	
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblRoundRectCategory",
+
 		buildRendering: function(){
-			this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("H2");
-			this.domNode.className = "mblRoundRectCategory";
-			if(!this.label){
-				this.label = this.domNode.innerHTML;
+			var domNode = this.domNode = this.containerNode = this.srcNodeRef || domConstruct.create(this.tag);
+			this.inherited(arguments);
+			if(!this.label && domNode.childNodes.length === 1 && domNode.firstChild.nodeType === 3){
+				// if it has only one text node, regard it as a label
+				this.label = domNode.firstChild.nodeValue;
 			}
 		},
 
 		_setLabelAttr: function(/*String*/label){
+			// summary:
+			//		Sets the category header text.
+			// tags:
+			//		private
 			this.label = label;
 			this.domNode.innerHTML = this._cv ? this._cv(label) : label;
 		}
 	});
 
+	return has("dojo-bidi") ? declare("dojox.mobile.RoundRectCategory", [RoundRectCategory, BidiRoundRectCategory]) : RoundRectCategory;	
 });
diff --git a/dojox/mobile/RoundRectDataList.js b/dojox/mobile/RoundRectDataList.js
index 4c0d3f5..24ae556 100644
--- a/dojox/mobile/RoundRectDataList.js
+++ b/dojox/mobile/RoundRectDataList.js
@@ -1,24 +1,21 @@
 define([
+	"dojo/_base/kernel",
 	"dojo/_base/declare",
 	"./RoundRectList",
 	"./_DataListMixin"
-], function(declare, RoundRectList, DataListMixin){
-
-/*=====
-	var RoundRectList = dojox.mobile.RoundRectList;
-	var DataListMixin = dojox.mobile._DataListMixin;
-=====*/
+], function(kernel, declare, RoundRectList, DataListMixin){
 
 	// module:
 	//		dojox/mobile/RoundRectDataList
-	// summary:
-	//		An enhanced version of RoundRectList.
 
+	kernel.deprecated("dojox/mobile/RoundRectDataList", 
+		"Use dojox/mobile/RoundRectStoreList instead", "2.0");
+		
 	return declare("dojox.mobile.RoundRectDataList", [RoundRectList, DataListMixin], {
 		// summary:
-		//		An enhanced version of RoundRectList.
+		//		A dojo/data-enabled version of RoundRectList.
 		// description:
-		//		RoundRectDataList is an enhanced version of RoundRectList. It
-		//		can generate ListItems according to the given dojo.data store.
+		//		RoundRectDataList is a subclass RoundRectList which
+		//		can generate ListItems according to the given dojo/data store.
 	});
 });
diff --git a/dojox/mobile/RoundRectList.js b/dojox/mobile/RoundRectList.js
index 464027d..039b3e2 100644
--- a/dojox/mobile/RoundRectList.js
+++ b/dojox/mobile/RoundRectList.js
@@ -1,30 +1,25 @@
 define([
 	"dojo/_base/array",
 	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/lang",
 	"dojo/_base/window",
+	"dojo/dom-construct",
+	"dojo/dom-attr",
 	"dijit/_Contained",
 	"dijit/_Container",
 	"dijit/_WidgetBase"
-], function(array, declare, win, Contained, Container, WidgetBase){
-
-/*=====
-	var Contained = dijit._Contained;
-	var Container = dijit._Container;
-	var WidgetBase = dijit._WidgetBase;
-=====*/
+], function(array, declare, event, lang, win, domConstruct, domAttr, Contained, Container, WidgetBase){
 
 	// module:
 	//		dojox/mobile/RoundRectList
-	// summary:
-	//		A rounded rectangle list.
 
 	return declare("dojox.mobile.RoundRectList", [WidgetBase, Container, Contained], {
 		// summary:
 		//		A rounded rectangle list.
 		// description:
 		//		RoundRectList is a rounded rectangle list, which can be used to
-		//		display a group of items. Each item must be
-		//		dojox.mobile.ListItem.
+		//		display a group of items. Each item must be a dojox/mobile/ListItem.
 
 		// transition: String
 		//		The default animated transition effect for child items.
@@ -40,20 +35,78 @@ define([
 
 		// select: String
 		//		Selection mode of the list. The check mark is shown for the
-		//		selected list item(s). The value can be "single", "multiple", or
-		//		"". If "single", there can be only one selected item at a time.
+		//		selected list item(s). The value can be "single", "multiple", or "".
+		//		If "single", there can be only one selected item at a time.
 		//		If "multiple", there can be multiple selected items at a time.
+		//		If "", the check mark is not shown.
 		select: "",
 
-		// stateful: String
+		// stateful: Boolean
 		//		If true, the last selected item remains highlighted.
 		stateful: false,
 
+		// syncWithViews: [const] Boolean
+		//		If true, this widget listens to view transition events to be
+		//		synchronized with view's visibility.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		syncWithViews: false,
+
+		// editable: [const] Boolean
+		//		If true, the list can be reordered.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		editable: false,
+
+		// tag: String
+		//		A name of html tag to create as domNode.
+		tag: "ul",
+
+		/* internal properties */
+		// editableMixinClass: String
+		//		The name of the mixin class.
+		editableMixinClass: "dojox/mobile/_EditableListMixin",
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblRoundRectList",
+		
+		// filterBoxClass: String
+		//		The name of the CSS class added to the DOM node inside which is placed the 
+		//		dojox/mobile/SearchBox created when mixing dojox/mobile/FilteredListMixin.
+		//		The default value is "mblFilteredRoundRectListSearchBox".  
+		filterBoxClass: "mblFilteredRoundRectListSearchBox",
+
 		buildRendering: function(){
-			this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("UL");
-			this.domNode.className = "mblRoundRectList";
+			this.domNode = this.srcNodeRef || domConstruct.create(this.tag);
+			if(this.select){
+				domAttr.set(this.domNode, "role", "listbox");
+				if(this.select === "multiple"){
+					domAttr.set(this.domNode, "aria-multiselectable", "true");
+				}
+			}
+			this.inherited(arguments);
 		},
-	
+
+		postCreate: function(){
+			if(this.editable){
+				require([this.editableMixinClass], lang.hitch(this, function(module){
+					declare.safeMixin(this, new module());
+				}));
+			}
+			this.connect(this.domNode, "onselectstart", event.stop);
+
+			if(this.syncWithViews){ // see also TabBar#postCreate
+				var f = function(view, moveTo, dir, transition, context, method){
+					var child = array.filter(this.getChildren(), function(w){
+						return w.moveTo === "#" + view.id || w.moveTo === view.id; })[0];
+					if(child){ child.set("selected", true); }
+				};
+				this.subscribe("/dojox/mobile/afterTransitionIn", f);
+				this.subscribe("/dojox/mobile/startView", f);
+			}
+		},
+
 		resize: function(){
 			// summary:
 			//		Calls resize() of each child widget.
@@ -62,7 +115,7 @@ define([
 			});
 		},
 
-		onCheckStateChanged: function(/*Widget*/listItem, /*String*/newState){
+		onCheckStateChanged: function(/*Widget*//*===== listItem, =====*/ /*String*//*===== newState =====*/){
 			// summary:
 			//		Stub function to connect to from your application.
 			// description:
@@ -70,30 +123,33 @@ define([
 		},
 
 		_setStatefulAttr: function(stateful){
-			this.stateful = stateful;
+			// tags:
+			//		private
+			this._set("stateful", stateful);
+			this.selectOne = stateful;
 			array.forEach(this.getChildren(), function(child){
 				child.setArrow && child.setArrow();
 			});
 		},
 
-		deselectItem: function(/*ListItem*/item){
+		deselectItem: function(/*dojox/mobile/ListItem*/item){
 			// summary:
 			//		Deselects the given item.
-			item.deselect();
+			item.set("selected", false);
 		},
 
 		deselectAll: function(){
 			// summary:
 			//		Deselects all the items.
 			array.forEach(this.getChildren(), function(child){
-				child.deselect && child.deselect();
+				child.set("selected", false);
 			});
 		},
 
 		selectItem: function(/*ListItem*/item){
 			// summary:
 			//		Selects the given item.
-			item.select();
+			item.set("selected", true);
 		}
 	});
 });
diff --git a/dojox/mobile/RoundRectStoreList.js b/dojox/mobile/RoundRectStoreList.js
new file mode 100644
index 0000000..9c3434f
--- /dev/null
+++ b/dojox/mobile/RoundRectStoreList.js
@@ -0,0 +1,17 @@
+define([
+	"dojo/_base/declare",
+	"./RoundRectList",
+	"./_StoreListMixin"
+], function(declare, RoundRectList, StoreListMixin){
+
+	// module:
+	//		dojox/mobile/RoundRectStoreList
+
+	return declare("dojox.mobile.RoundRectStoreList", [RoundRectList, StoreListMixin], {
+		// summary:
+		//		A dojo/store-enabled version of RoundRectList.
+		// description:
+		//		RoundRectStoreList is a subclass of RoundRectList which
+		//		can generate ListItems according to the given dojo/store store.
+	});
+});
diff --git a/dojox/mobile/ScreenSizeAware.js b/dojox/mobile/ScreenSizeAware.js
new file mode 100644
index 0000000..00f39d5
--- /dev/null
+++ b/dojox/mobile/ScreenSizeAware.js
@@ -0,0 +1,268 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/config",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom",
+	"dijit/registry"
+], function(kernel, array, config, connect, declare, lang, win, dom, registry){
+
+	// module:
+	//		dojox/mobile/ScreenSizeAware
+
+	kernel.experimental("dojox.mobile.ScreenSizeAware"); // should consider support for other UI layout patterns
+
+	var cls = declare("dojox.mobile.ScreenSizeAware", null, {
+		// summary:
+		//		A module to make a screen size aware application.
+		// description:
+		//		This module helps for creating applications that transform their
+		//		UI layout according to the screen size. It assumes that the
+		//		application consists of two horizontally split panes, and the
+		//		left pane has a list widget. If you require this module in such an
+		//		application, in a tablet-sized screen, the application shows a horizontally 
+		//		split view whose left pane is a list widget.
+		//		In a phone-sized screen, the application shows a list widget that fills the screen.
+		//
+		// example:
+		// |	<span data-dojo-type="dojox.mobile.ScreenSizeAware"></span>
+		// |	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		// |	  <div data-dojo-type="dojox.mobile.Container" style="width:300px;">
+		// |	    <div id="leftView" data-dojo-type="dojox.mobile.ScrollableView">
+		// |	      <h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Left Pane</h1>
+		// |	      <ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='stateful:true'>
+		// |	        <li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='label:"View1", moveTo:"view1"'></li>
+		// |	        ....
+		// |	      </ul>
+		// |	    </div>
+		// |	  </div>
+		// |	  <div data-dojo-type="dojox.mobile.Container">
+		// |	    <div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		// |	      <h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"leftView"'>Right Pane</h1>
+		// |	      ....
+		// |	    </div>
+		// |	  </div>
+		// |	</div>
+
+		// splitterId: String
+		//		The id of the FixedSplitter.
+		splitterId: "",
+
+		// leftPaneId: String
+		//		The id of the left pane.
+		leftPaneId: "",
+
+		// rightPaneId: String
+		//		The id of the right pane.
+		rightPaneId: "",
+
+		// leftViewId: String
+		//		The id of the left View.
+		leftViewId: "",
+
+		// leftListId: String
+		//		The id of the list widget in the left view.
+		leftListId: "",
+
+		constructor: function(/*Object?*/options){
+			// summary:
+			//		Creates a new instance of the class.
+			// options:
+			//		Contains properties to be set.
+			if (options){
+				lang.mixin(this, options);
+			}
+			connect.subscribe("/dojox/mobile/screenSize/tablet", this, function(dim){
+				this.transformUI("tablet");
+			});
+			connect.subscribe("/dojox/mobile/screenSize/phone", this, function(dim){
+				this.transformUI("phone");
+			});
+		},
+
+		init: function(){
+			// summary:
+			//		Initializes the application.
+			if(this._initialized){ return; }
+			this._initialized = true;
+
+			// analyze the page structure
+			this.splitter = this.splitterId ? registry.byId(this.splitterId) :
+				array.filter(registry.findWidgets(win.body()),
+					function(c){ return c.declaredClass.indexOf("Splitter") !== -1; })[0];
+			if(!this.splitter){
+				console.error("Splitter not found.");
+				return;
+			}
+
+			this.leftPane = this.leftPaneId ? registry.byId(this.leftPaneId) :
+				this.splitter.getChildren()[0];
+			if(!this.leftPane){
+				console.error("Left pane not found.");
+				return;
+			}
+
+			this.rightPane = this.rightPaneId ? registry.byId(this.rightPaneId) :
+				this.splitter.getChildren()[1];
+			if(!this.rightPane){
+				console.error("Right pane not found.");
+				return;
+			}
+
+			this.leftView = this.leftViewId ? registry.byId(this.leftViewId) :
+				array.filter(registry.findWidgets(this.leftPane.containerNode),
+					function(c){ return c.declaredClass.indexOf("View") !== -1; })[0];
+			if(!this.leftView){
+				console.error("Left view not found.");
+				return;
+			}
+
+			this.leftList = this.leftListId ? registry.byId(this.leftListId) :
+				array.filter(registry.findWidgets(this.leftView.containerNode),
+					function(c){ return c.declaredClass.indexOf("List") !== -1 ||
+								 c.declaredClass.indexOf("IconContainer") !== -1; })[0];
+			if(!this.leftList){
+				console.error("Left list not found.");
+				return;
+			}
+		},
+
+		isPhone: function(){
+			// summary:
+			//		Returns true if the current mode set by transformUI(mode) is "phone".
+			return this._currentMode === "phone"; // Boolean
+		},
+
+		getShowingView: function(){
+			// summary:
+			//		Returns the view currently shown.
+			var firstView =
+				array.filter(this.rightPane.getChildren(), function(c){ return c.declaredClass.indexOf("View") !== -1; })[0];
+			if(!firstView){ return null; }
+			return firstView.getShowingView() ||
+				array.filter(this.rightPane.getChildren(), function(c){ return c.selected; })[0] ||
+				firstView;
+		},
+
+		updateStateful: function(){
+			// summary:
+			//		Updates the stateful property of the list widget in the left-side pane.
+			this.leftList.set("stateful", !this.isPhone());
+		},
+
+		getDestinationId: function(item){
+			// summary:
+			//		Returns the id of the target view of the given item.
+			return item.moveTo;
+		},
+
+		updateBackButton: function(){
+			// summary:
+			//		Updates the back button.
+			array.forEach(this.leftList.getChildren(), function(item){
+				var id = this.getDestinationId(item);
+				var view = registry.byId(id);
+				if(view){
+					var heading = array.filter(view.getChildren(), function(c){ return c.declaredClass.indexOf("Heading") !== -1; })[0];
+					if(heading.backButton){
+						heading.backButton.domNode.style.display = this.isPhone() ? "" : "none";
+					}
+					if(heading.backBtnNode){ // TODO: remove this block later
+						heading.backBtnNode.style.display = this.isPhone() ? "" : "none";
+					}
+				}
+			}, this);
+		},
+
+		updateTransition: function(){
+			// summary:
+			//		Updates the transition property of the items in the left-side widget. 
+			var transition = this.isPhone() ? "slide" : "none";
+			array.forEach(this.leftList.getChildren(), function(item){
+				item.set("transition", transition);
+			});
+		},
+
+		moveList: function(){
+			// summary:
+			//		Places the list widget. If the current mode is "phone", it 
+			//		places the list widget in the right pane, otherwise in the left pane. 
+			var to = this.isPhone() ? this.rightPane: this.leftPane;
+			to.containerNode.appendChild(this.leftView.domNode);
+		},
+
+		showLeftView: function(){
+			// summary:
+			//		Shows the left-side view.
+			this.leftPane.domNode.style.display = this.isPhone() ? "none" : "";
+			this.leftView.show();
+		},
+
+		showRightView: function(){
+			// summary:
+			//		Shows the right-side view.
+			if(this.isPhone()){ return; }
+			var view = this.getShowingView();
+			if(view){
+				view.show();
+			}else{
+				this.leftItemSelected();
+			}
+		},
+
+		updateSelectedItem: function(){
+			// summary:
+			//		Updates the selected item.
+			var id;
+			var view = this.getShowingView();
+			if(view && !this.isPhone()){
+				id = view.id;
+			}
+			if(id){
+				var items = array.filter(this.leftList.getChildren(),
+					function(item){ return this.getDestinationId(item) === id; }, this);
+				if(items && items.length > 0){
+					items[0].set("selected", true);
+				}
+			}else{
+				this.leftList.deselectAll && this.leftList.deselectAll();
+			}
+		},
+
+		leftItemSelected: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		Function called when an item in the left-side list is selected.
+		},
+
+		transformUI: function(/*String*/mode){
+			// summary:
+			//		Applies an UI mode.
+			// mode: 
+			//		If this argument is "phone", sets the UI in phone mode, otherwise 
+			//		in tablet mode.		 
+			this.init();
+			if(mode === this._currentMode){ return; }
+			this._currentMode = mode;
+			this.updateStateful();
+			this.updateBackButton();
+			this.updateTransition();
+			this.moveList();
+			this.showLeftView();
+			this.showRightView();
+			this.updateSelectedItem();
+		}
+	});
+
+	cls._instance = null;
+	cls.getInstance = function(){
+		if(!cls._instance){
+			cls._instance = new cls();
+		}
+		return cls._instance;
+	};
+
+	return cls;
+});
diff --git a/dojox/mobile/ScrollablePane.js b/dojox/mobile/ScrollablePane.js
new file mode 100644
index 0000000..49ea2e4
--- /dev/null
+++ b/dojox/mobile/ScrollablePane.js
@@ -0,0 +1,122 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/sniff",
+	"dojo/_base/window",
+	"dojo/dom",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"./_ScrollableMixin",
+	"./Pane",
+	"./_maskUtils"
+], function(array, declare, has, win, dom, domConstruct, domStyle, ScrollableMixin, Pane, maskUtils){
+
+	// module:
+	//		dojox/mobile/ScrollablePane
+
+	return declare("dojox.mobile.ScrollablePane", [Pane, ScrollableMixin], {
+		// summary:
+		//		A pane that has the touch-scrolling capability.
+
+		// roundCornerMask: Boolean
+		//		If true, creates a rounded corner mask to clip corners of a 
+		//		child widget or DOM node. Works only on WebKit-based browsers.
+		roundCornerMask: false,
+
+		// radius: Number
+		//		Radius of the rounded corner mask.
+		radius: 0,
+
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblScrollablePane",
+
+		buildRendering: function(){
+			var c = this.containerNode = domConstruct.create("div", {
+				className: "mblScrollableViewContainer",
+				style: {
+					width: this.scrollDir === "v" ? "100%" : ""
+				}
+			});
+			this.inherited(arguments);
+
+			if(this.srcNodeRef){
+				// reparent
+				for(var i = 0, len = this.srcNodeRef.childNodes.length; i < len; i++){
+					this.containerNode.appendChild(this.srcNodeRef.firstChild);
+				}
+			}
+
+			if(this.roundCornerMask && (has("webkit")||has("svg"))){
+				var node = this.containerNode;
+				var mask = this.maskNode = domConstruct.create("div", {
+					className: "mblScrollablePaneMask"
+				});
+				mask.appendChild(node);
+				c = mask;
+			}
+
+			this.domNode.appendChild(c);
+			dom.setSelectable(this.containerNode, false);
+		},
+
+		resize: function(){
+			// summary:
+			//		Calls resize() of each child widget.
+			this.inherited(arguments); // scrollable#resize() will be called
+			if(this.roundCornerMask){
+				this.createRoundMask();
+			}
+			array.forEach(this.getChildren(), function(child){
+				if(child.resize){ child.resize(); }
+			});
+		},
+
+		isTopLevel: function(e){
+			// summary:
+			//		Returns true if this is a top-level widget.
+			//		Overrides dojox/mobile/scrollable.
+			var parent = this.getParent && this.getParent();
+			return (!parent || !parent.resize); // top level widget
+		},
+
+		createRoundMask: function(){
+			// summary:
+			//		Creates a rounded corner rectangle mask.
+			// description:
+			//		Creates a rounded corner rectangle mask.
+			//		This function works only on WebKit-based browsers.
+			if(has("webkit")||has("svg")){
+				if(this.domNode.offsetHeight == 0){ return; } // in a hidden view
+				this.maskNode.style.height = this.domNode.offsetHeight + "px";
+				var child = this.getChildren()[0],
+					c = this.containerNode,
+					node = child ? child.domNode :
+						(c.childNodes.length > 0 && (c.childNodes[0].nodeType === 1 ? c.childNodes[0] : c.childNodes[1]));
+
+				var r = this.radius;
+				if(!r){
+					var getRadius = function(n){ return parseInt(domStyle.get(n, "borderTopLeftRadius")); };
+					if(child){
+						r = getRadius(child.domNode);
+						if(!r){
+							var item = child.getChildren()[0];
+							r = item ? getRadius(item.domNode) : 0;
+						}
+					}else{
+						r = getRadius(node);
+					}
+				}
+
+				var pw = this.domNode.offsetWidth, // pane width
+					w = node.offsetWidth,
+					h = this.domNode.offsetHeight,
+					t = domStyle.get(node, "marginTop"),
+					b = domStyle.get(node, "marginBottom"),
+					l = domStyle.get(node, "marginLeft");
+				
+				maskUtils.createRoundMask(this.maskNode, l, t, 0, b, w, h - b - t, r, r);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/ScrollableView.js b/dojox/mobile/ScrollableView.js
index 597291c..83b034b 100644
--- a/dojox/mobile/ScrollableView.js
+++ b/dojox/mobile/ScrollableView.js
@@ -8,39 +8,34 @@ define([
 	"./_ScrollableMixin"
 ], function(array, declare, domClass, domConstruct, registry, View, ScrollableMixin){
 
-	/*=====
-		var View = dojox.mobile.View;
-		var ScrollableMixin = dojox.mobile._ScrollableMixin;
-	=====*/
-
 	// module:
 	//		dojox/mobile/ScrollableView
-	// summary:
-	//		A container that has a touch scrolling capability.
 
 	return declare("dojox.mobile.ScrollableView", [View, ScrollableMixin], {
 		// summary:
 		//		A container that has a touch scrolling capability.
 		// description:
-		//		ScrollableView is a subclass of View (=dojox.mobile.View).
+		//		ScrollableView is a subclass of View (dojox/mobile/View).
 		//		Unlike the base View class, ScrollableView's domNode always stays
 		//		at the top of the screen and its height is "100%" of the screen.
-		//		In this fixed domNode, containerNode scrolls. Browser's default
-		//		scrolling behavior is disabled, and the scrolling machinery is
-		//		re-implemented with JavaScript. Thus the user does not need to use the
-		//		two-finger operation to scroll an inner DIV (containerNode).
+		//		Inside this fixed domNode, the containerNode scrolls. The browser's
+		//		default scrolling behavior is disabled, and the scrolling mechanism is
+		//		reimplemented in JavaScript. Thus the user does not need to use the
+		//		two-finger operation to scroll the inner DIV (containerNode).
 		//		The main purpose of this widget is to realize fixed-positioned header
 		//		and/or footer bars.
 
 		// scrollableParams: Object
-		//		Parameters for dojox.mobile.scrollable.init().
+		//		Parameters for dojox/mobile/scrollable.init().
 		scrollableParams: null,
 
 		// keepScrollPos: Boolean
-		//		Overrides dojox.mobile.View.keepScrollPos.
+		//		Overrides dojox/mobile/View/keepScrollPos.
 		keepScrollPos: false,
 
 		constructor: function(){
+			// summary:
+			//		Creates a new instance of the class.
 			this.scrollableParams = {noResize: true};
 		},
 
@@ -49,15 +44,24 @@ define([
 			domClass.add(this.domNode, "mblScrollableView");
 			this.domNode.style.overflow = "hidden";
 			this.domNode.style.top = "0px";
-			this.containerNode = domConstruct.create("DIV",
+			this.containerNode = domConstruct.create("div",
 				{className:"mblScrollableViewContainer"}, this.domNode);
 			this.containerNode.style.position = "absolute";
 			this.containerNode.style.top = "0px"; // view bar is relative
 			if(this.scrollDir === "v"){
 				this.containerNode.style.width = "100%";
 			}
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			// user can initialize the app footers using a value for fixedFooter (we keep this value for non regression of existing apps)
+			if(this.fixedFooter && !this.isLocalFooter){
+				this._fixedAppFooter = this.fixedFooter;
+				this.fixedFooter = "";
+			}
 			this.reparent();
-			this.findAppBars();
+			this.inherited(arguments);
 		},
 
 		resize: function(){
@@ -67,39 +71,43 @@ define([
 			array.forEach(this.getChildren(), function(child){
 				if(child.resize){ child.resize(); }
 			});
+			this._dim = this.getDim(); // update dimension cache
+			if(this._conn){
+				// if a resize happens during a scroll, update the scrollbar
+				this.resetScrollBar();
+			}
 		},
 
-		isTopLevel: function(e){
+		isTopLevel: function(/*Event*/e){
 			// summary:
 			//		Returns true if this is a top-level widget.
-			//		Overrides dojox.mobile.scrollable.
+			//		Overrides dojox/mobile/scrollable.isTopLevel.
 			var parent = this.getParent && this.getParent();
 			return (!parent || !parent.resize); // top level widget
 		},
 
-		addChild: function(widget, /*Number?*/insertIndex){
+		addFixedBar: function(/*Widget*/widget){
+			// summary:
+			//		Adds a view local fixed bar to this widget.
+			// description:
+			//		This method can be used to programmatically add a view local
+			//		fixed bar to ScrollableView. The bar is appended to this
+			//		widget's domNode. The addChild API cannot be used for this
+			//		purpose, because it adds the given widget to containerNode.
 			var c = widget.domNode;
 			var fixed = this.checkFixedBar(c, true);
-			if(fixed){
-				// Addition of a fixed bar is an exceptional case.
-				// It has to be added to domNode, not containerNode.
-				// In this case, insertIndex is ignored.
-				this.domNode.appendChild(c);
-				if(fixed === "top"){
-					this.fixedHeaderHeight = c.offsetHeight;
-					this.isLocalHeader = true;
-				}else if(fixed === "bottom"){
-					this.fixedFooterHeight = c.offsetHeight;
-					this.isLocalFooter = true;
-					c.style.bottom = "0px";
-				}
-				this.resize();
-				if(this._started && !widget._started){
-					widget.startup();
-				}
-			}else{
-				this.inherited(arguments);
+			if(!fixed){ return; }
+			// Fixed bar has to be added to domNode, not containerNode.
+			this.domNode.appendChild(c);
+			if(fixed === "top"){
+				this.fixedHeaderHeight = c.offsetHeight;
+				this.isLocalHeader = true;
+			}else if(fixed === "bottom"){
+				this.fixedFooterHeight = c.offsetHeight;
+				this.isLocalFooter = true;
+				c.style.bottom = "0px";
 			}
+			this.resize();
 		},
 
 		reparent: function(){
@@ -119,21 +127,44 @@ define([
 		},
 
 		onAfterTransitionIn: function(moveTo, dir, transition, context, method){
+			// summary:
+			//		Overrides View.onAfterTransitionIn to flash the scroll bar
+			//		after performing a view transition.
 			this.flashScrollBar();
 		},
-	
+
 		getChildren: function(){
 			// summary:
-			//		Overrides _WidgetBase#getChildren to add local fixed bars,
+			//		Overrides _WidgetBase.getChildren to add local fixed bars,
 			//		which are not under containerNode, to the children array.
 			var children = this.inherited(arguments);
+			var fixedWidget;
 			if(this.fixedHeader && this.fixedHeader.parentNode === this.domNode){
-				children.push(registry.byNode(this.fixedHeader));
+				fixedWidget = registry.byNode(this.fixedHeader);
+				if(fixedWidget){
+					children.push(fixedWidget);
+				}
 			}
 			if(this.fixedFooter && this.fixedFooter.parentNode === this.domNode){
-				children.push(registry.byNode(this.fixedFooter));
+				fixedWidget = registry.byNode(this.fixedFooter);
+				if(fixedWidget){
+					children.push(fixedWidget);
+				}
 			}
 			return children;
+		},
+
+		_addTransitionPaddingTop: function(/*String|Integer*/ value){
+			// add padding top to the view in order to get alignment during the transition
+			this.domNode.style.paddingTop = value + "px";
+			this.containerNode.style.paddingTop = value + "px";
+		},
+
+		_removeTransitionPaddingTop: function(){
+			// remove padding top from the view after the transition
+			this.domNode.style.paddingTop = "";
+			this.containerNode.style.paddingTop = "";
 		}
+
 	});
 });
diff --git a/dojox/mobile/SearchBox.js b/dojox/mobile/SearchBox.js
new file mode 100644
index 0000000..9497661
--- /dev/null
+++ b/dojox/mobile/SearchBox.js
@@ -0,0 +1,124 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dijit/form/_SearchMixin",
+	"dojox/mobile/TextBox",
+	"dojo/dom-class",
+	"dojo/keys",
+	"dojo/touch",
+	"dojo/on",
+	"./sniff"
+], function(declare, lang, win, SearchMixin, TextBox, domClass, keys, touch, on, has){
+
+	return declare("dojox.mobile.SearchBox", [TextBox, SearchMixin], {
+		// summary:
+		//		A non-templated base class for INPUT type="search".
+
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblTextBox mblSearchBox",
+
+		// type: String
+		//		Corresponds to the type attribute of the HTML `<input>` element.
+		//		The value is "search".
+		type: "search",
+
+		placeHolder: "",
+
+		// incremental: Boolean
+		//		Set true to search on every key or false to only search after 
+		//		pressing ENTER or cancel.
+		incremental: true,
+
+		_setIncrementalAttr: function(val){
+			// summary:
+			//		Custom setter so the INPUT doesn't get the incremental attribute set.
+			// tags:
+			//		private
+			this.incremental = val;
+		},
+
+		_onInput: function(e){
+			// tags:
+			//		private
+			if(e.charOrCode == keys.ENTER){
+				e.charOrCode = 229;
+			}else if(!this.incremental){
+				e.charOrCode = 0; // call _onInput to make sure a pending query is aborted
+			}
+			this.inherited(arguments);
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this.textbox.removeAttribute('incremental'); // only want onsearch to fire for ENTER and cancel
+			if(!this.textbox.hasAttribute('results')){
+				this.textbox.setAttribute('results', '0'); // enables webkit search decoration
+			}
+			if(has("ios") < 5){
+				domClass.add(this.domNode, 'iphone4'); // cannot click cancel button after focus so just remove it
+				this.connect(this.textbox, "onfocus", // if value changes between start of onfocus to end, then it was a cancel
+					function(){
+						if(this.textbox.value !== ''){
+							this.defer(
+								function(){
+									if(this.textbox.value === ''){
+										this._onInput({ charOrCode: keys.ENTER }); // emulate onsearch
+									}
+								}
+							);
+						}
+					}
+				);
+			}
+			this.connect(this.textbox, "onsearch",
+				function(){
+					this._onInput({ charOrCode: keys.ENTER });
+				}
+			);
+			
+			// Clear action for the close button (iOS specific)
+			var _this = this;
+			var touchStartX, touchStartY;
+			var handleRelease;
+			if(has("ios")){
+				this.on(touch.press, function(evt){
+					var rect;
+					touchStartX = evt.touches ? evt.touches[0].pageX : evt.pageX;
+					touchStartY = evt.touches ? evt.touches[0].pageY : evt.pageY;
+					// As the native searchbox on iOS, clear on release, not on start.
+					handleRelease = on(win.doc, touch.release,
+						function(evt){
+							var rect, dx, dy;
+							if(_this.get("value") != ""){
+								dx = evt.pageX - touchStartX;
+								dy = evt.pageY - touchStartY;
+								// Mimic the behavior of native iOS searchbox: 
+								// if location of release event close to the location of start event:
+								if(Math.abs(dx) <= 4 && Math.abs(dy) <= 4){
+									evt.preventDefault();
+									_this.set("value", "");
+									_this._onInput({ charOrCode: keys.ENTER });
+								}
+							}
+							if(handleRelease){ // possibly already cancelled/cleared on touch.press
+								handleRelease.remove();
+								handleRelease = null;
+							}
+						}
+					);
+					rect = _this.domNode.getBoundingClientRect();
+					// if touched in the right-most 20 pixels of the search box 
+					if(rect.right - (evt.touches ? evt.touches[0].pageX : evt.pageX) >= 20){
+						// cancel
+						if(handleRelease){
+							handleRelease.remove();
+							handleRelease = null;
+						} 
+					}
+				});
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/SimpleDialog.js b/dojox/mobile/SimpleDialog.js
new file mode 100644
index 0000000..a05e60c
--- /dev/null
+++ b/dojox/mobile/SimpleDialog.js
@@ -0,0 +1,221 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-attr",
+	"dojo/dom-construct",
+	"dojo/on",
+	"dojo/touch",
+	"dijit/registry",
+	"./Pane",
+	"./iconUtils",
+	"./sniff"
+], function(declare, win, domClass, domAttr, domConstruct, on, touch, registry, Pane, iconUtils, has){
+	// module:
+	//		dojox/mobile/SimpleDialog
+
+	return declare("dojox.mobile.SimpleDialog", Pane, {
+		// summary:
+		//		A dialog box for mobile.
+		// description:
+		//		SimpleDialog is a dialog box for mobile.
+		//		When a SimpleDialog is created, it is initially hidden 
+		//		(display="none"). To show the dialog box, you need to
+		//		get a reference to the widget and to call its show() method.
+		//
+		//		The contents can be arbitrary HTML, text, or widgets. Note,
+		//		however, that the widget is initially hidden. You need to be
+		//		careful when you place in a SimpleDialog elements that cannot 
+		//		be initialized in hidden state.
+		//
+		//		This widget has much less functionalities than dijit/Dialog, 
+		//		but it has the advantage of a much smaller code size.
+
+		// top: String
+		//		The top edge position of the widget. If "auto", the widget is
+		//		placed at the middle of the screen. Otherwise, the value
+		//		(ex. "20px") is used as the top style of widget's domNode.
+		top: "auto",
+
+		// left: String
+		//		The left edge position of the widget. If "auto", the widget is
+		//		placed at the center of the screen. Otherwise, the value
+		//		(ex. "20px") is used as the left style of widget's domNode.
+		left: "auto",
+
+		// modal: Boolean
+		//		If true, a translucent cover is added over the entire page to
+		//		prevent the user from interacting with elements on the page.
+		modal: true,
+
+		// closeButton: [const] Boolean
+		//		If true, a button to close the dialog box is displayed at the
+		//		top-right corner.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		closeButton: false,
+
+		// closeButtonClass: String
+		//		A class name of a DOM button to be used as a close button.
+		closeButtonClass: "mblDomButtonSilverCircleRedCross",
+
+		// tabIndex: String
+		//		Tabindex setting for the item so users can hit the tab key to
+		//		focus on it.
+		tabIndex: "0",
+		
+		// _setTabIndexAttr: [private] String
+		//		Sets tabIndex to domNode.
+		_setTabIndexAttr: "",
+
+		/* internal properties */	
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblSimpleDialog",
+		
+		// _cover: [private] Array
+		//		Array for sharing the cover instances.
+		_cover: [],
+
+		buildRendering: function(){
+			this.containerNode = domConstruct.create("div", {className:"mblSimpleDialogContainer"});
+			if(this.srcNodeRef){
+				// reparent
+				for(var i = 0, len = this.srcNodeRef.childNodes.length; i < len; i++){
+					this.containerNode.appendChild(this.srcNodeRef.removeChild(this.srcNodeRef.firstChild));
+				}
+			}
+			this.inherited(arguments);
+			domAttr.set(this.domNode, "role", "dialog");
+			
+			if(this.containerNode.getElementsByClassName){ //TODO: Do we need to support IE8 a11y?
+	            var titleNode = this.containerNode.getElementsByClassName("mblSimpleDialogTitle")[0];
+	            if (titleNode){
+	            	titleNode.id = titleNode.id || registry.getUniqueId("dojo_mobile_mblSimpleDialogTitle");
+	            	domAttr.set(this.domNode, "aria-labelledby", titleNode.id);
+	            }
+	            var textNode = this.containerNode.getElementsByClassName("mblSimpleDialogText")[0];
+	            if (textNode){
+	                textNode.id = textNode.id || registry.getUniqueId("dojo_mobile_mblSimpleDialogText");
+	                domAttr.set(this.domNode, "aria-describedby", textNode.id);
+	            }
+			}
+			domClass.add(this.domNode, "mblSimpleDialogDecoration");
+			this.domNode.style.display = "none";
+			this.domNode.appendChild(this.containerNode);
+			if(this.closeButton){
+				this.closeButtonNode = domConstruct.create("div", {
+					className: "mblSimpleDialogCloseBtn "+this.closeButtonClass
+				}, this.domNode);
+				iconUtils.createDomButton(this.closeButtonNode);
+				this.connect(this.closeButtonNode, "onclick", "_onCloseButtonClick");
+			}
+			this.connect(this.domNode, "onkeydown", "_onKeyDown"); // for desktop browsers
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this.inherited(arguments);
+			win.body().appendChild(this.domNode);
+		},
+
+		addCover: function(){
+			// summary:
+			//		Adds the transparent DIV cover.
+			if(!this._cover[0]){
+				this._cover[0] = domConstruct.create("div", {
+					className: "mblSimpleDialogCover"
+				}, win.body());
+			}else{
+				this._cover[0].style.display = "";
+			}
+
+			if(has("windows-theme")) {
+				// Hack to prevent interaction with elements placed under cover div.
+				this.own(on(this._cover[0], touch.press, function() {}));
+			}
+		},
+
+		removeCover: function(){
+			// summary:
+			//		Removes the transparent DIV cover.
+			this._cover[0].style.display = "none";
+		},
+
+		_onCloseButtonClick: function(e){
+			// tags:
+			//		private
+			if(this.onCloseButtonClick(e) === false){ return; } // user's click action
+			this.hide();
+		},
+
+		onCloseButtonClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User-defined function to handle clicks.
+			// tags:
+			//		callback
+		},
+
+		_onKeyDown: function(e){
+			// tags:
+			//		private
+			if(e.keyCode == 27){ // ESC
+				this.hide();
+			}
+		},
+
+		refresh: function(){ // TODO: should we call refresh on resize?
+			// summary:
+			//		Refreshes the layout of the dialog.
+			var n = this.domNode;
+			var h;
+			if(this.closeButton){
+				var b = this.closeButtonNode;
+				var s = Math.round(b.offsetHeight / 2);
+				b.style.top = -s + "px";
+				b.style.left = n.offsetWidth - s + "px";
+			}
+			if(this.top === "auto"){
+				h = win.global.innerHeight || win.doc.documentElement.clientHeight;
+				n.style.top = Math.round((h - n.offsetHeight) / 2) + "px";
+			}else{
+				n.style.top = this.top;
+			}
+			if(this.left === "auto"){
+				h = win.global.innerWidth || win.doc.documentElement.clientWidth;
+				n.style.left = Math.round((h - n.offsetWidth) / 2) + "px";
+			}else{
+				n.style.left = this.left;
+			}
+		},
+
+		show: function(){
+			// summary:
+			//		Shows the dialog.
+			if(this.domNode.style.display === ""){ return; }
+			if(this.modal){
+				this.addCover();
+			}
+			this.domNode.style.display = "";
+			this.refresh();
+			var diaglogButton;
+			if(this.domNode.getElementsByClassName){
+				diaglogButton = this.domNode.getElementsByClassName("mblSimpleDialogButton")[0];
+			}
+			var focusNode = diaglogButton || this.closeButtonNode || this.domNode; // Focus preference is: user supplied button, close button, entire dialog
+			/// on Safari iOS the focus is not taken without a timeout
+			this.defer(function(){ focusNode.focus();}, 1000);
+		},
+
+		hide: function(){
+			// summary:
+			//		Hides the dialog.
+			if(this.domNode.style.display === "none"){ return; }
+			this.domNode.style.display = "none";
+			if(this.modal){
+				this.removeCover();
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/Slider.js b/dojox/mobile/Slider.js
index 222ed96..2f58e03 100644
--- a/dojox/mobile/Slider.js
+++ b/dojox/mobile/Slider.js
@@ -4,23 +4,21 @@ define([
 	"dojo/_base/declare",
 	"dojo/_base/lang",
 	"dojo/_base/window",
+	"dojo/sniff",
 	"dojo/dom-class",
 	"dojo/dom-construct",
 	"dojo/dom-geometry",
 	"dojo/dom-style",
+	"dojo/keys",
+	"dojo/touch",
 	"dijit/_WidgetBase",
 	"dijit/form/_FormValueMixin"
 ],
-	function(array, connect, declare, lang, win, domClass, domConstruct, domGeometry, domStyle, WidgetBase, FormValueMixin){
+	function(array, connect, declare, lang, win, has, domClass, domConstruct, domGeometry, domStyle, keys, touch, WidgetBase, FormValueMixin){
 
-	/*=====
-		WidgetBase = dijit._WidgetBase;
-		FormValueMixin = dijit.form._FormValueMixin;
-	=====*/
 	return declare("dojox.mobile.Slider", [WidgetBase, FormValueMixin], {
 		// summary:
 		//		A non-templated Slider widget similar to the HTML5 INPUT type=range.
-		//
 
 		// value: [const] Number
 		//		The current slider value.
@@ -40,6 +38,8 @@ define([
 		//		A value of 0 means continuous (as much as allowed by pixel resolution).
 		step: 1,
 
+		// baseClass: String
+		//		The name of the CSS class of this widget.
 		baseClass: "mblSlider",
 
 		// flip: [const] Boolean
@@ -48,9 +48,10 @@ define([
 
 		// orientation: [const] String
 		//		The slider direction.
-		//		"H": horizontal
-		//		"V": vertical
-		//		"auto": use width/height comparison at instantiation time (default is "H" if width/height are 0)
+		//
+		//		- "H": horizontal
+		//		- "V": vertical
+		//		- "auto": use width/height comparison at instantiation time (default is "H" if width/height are 0)
 		orientation: "auto",
 
 		// halo: Number
@@ -59,18 +60,27 @@ define([
 		halo: "8pt",
 
 		buildRendering: function(){
-			this.focusNode = this.domNode = domConstruct.create("div", {});
-			this.valueNode = domConstruct.create("input", (this.srcNodeRef && this.srcNodeRef.name) ? { type: "hidden", name: this.srcNodeRef.name } : { type: "hidden" }, this.domNode, "last");
-			var relativeParent = domConstruct.create("div", { style: { position:"relative", height:"100%", width:"100%" } }, this.domNode, "last");
-			this.progressBar = domConstruct.create("div", { style:{ position:"absolute" }, "class":"mblSliderProgressBar" }, relativeParent, "last");
-			this.touchBox = domConstruct.create("div", { style:{ position:"absolute" }, "class":"mblSliderTouchBox" }, relativeParent, "last");
-			this.handle = domConstruct.create("div", { style:{ position:"absolute" }, "class":"mblSliderHandle" }, relativeParent, "last");
+			if(!this.templateString){ // true if this widget is not templated
+				this.focusNode = this.domNode = domConstruct.create("div", {});
+				this.valueNode = domConstruct.create("input", (this.srcNodeRef && this.srcNodeRef.name) ? { type: "hidden", name: this.srcNodeRef.name } : { type: "hidden" }, this.domNode, "last");
+				var relativeParent = domConstruct.create("div", { style: { position:"relative", height:"100%", width:"100%" } }, this.domNode, "last");
+				this.progressBar = domConstruct.create("div", { style:{ position:"absolute" }, "class":"mblSliderProgressBar" }, relativeParent, "last");
+				this.touchBox = domConstruct.create("div", { style:{ position:"absolute" }, "class":"mblSliderTouchBox" }, relativeParent, "last");
+				this.handle = domConstruct.create("div", { style:{ position:"absolute" }, "class":"mblSliderHandle" }, relativeParent, "last");
+			}
 			this.inherited(arguments);
+			// prevent browser scrolling on IE10 (evt.preventDefault() is not enough)
+			if(typeof this.domNode.style.msTouchAction != "undefined"){
+				this.domNode.style.msTouchAction = "none";
+			}
 		},
 
 		_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange){
 			// summary:
-			//		Hook so set('value', value) works.
+			//		Hook such that set('value', value) works.
+			// tags:
+			//		private
+			value = Math.max(Math.min(value, this.max), this.min);
 			var fromPercent = (this.value - this.min) * 100 / (this.max - this.min);
 			this.valueNode.value = value;
 			this.inherited(arguments);
@@ -120,9 +130,9 @@ define([
 				e.preventDefault();
 				var isMouse = e.type == "mousedown";
 				var box = domGeometry.position(node, false); // can't use true since the added docScroll and the returned x are body-zoom incompatibile
-				var bodyZoom = domStyle.get(win.body(), "zoom") || 1;
+				var bodyZoom = has("ie") ? 1 : (domStyle.get(win.body(), "zoom") || 1);
 				if(isNaN(bodyZoom)){ bodyZoom = 1; }
-				var nodeZoom = domStyle.get(node, "zoom") || 1;
+				var nodeZoom = has("ie") ? 1 : (domStyle.get(node, "zoom") || 1);
 				if(isNaN(nodeZoom)){ nodeZoom = 1; }
 				var startPixel = box[this._attrs.x] * nodeZoom * bodyZoom + domGeometry.docScroll()[this._attrs.x];
 				var maxPixels = box[this._attrs.w] * nodeZoom * bodyZoom;
@@ -133,29 +143,63 @@ define([
 				array.forEach(actionHandles, connect.disconnect);
 				var root = win.doc.documentElement;
 				var actionHandles = [
-					this.connect(root, isMouse ? "onmousemove" : "ontouchmove", continueDrag),
-					this.connect(root, isMouse ? "onmouseup" : "ontouchend", endDrag)
+					this.connect(root, touch.move, continueDrag),
+					this.connect(root, touch.release, endDrag)
 				];
 			}
 
-			var point, pixelValue, value;
-			var node = this.domNode;
+			function keyPress(/*Event*/ e){
+				if(this.disabled || this.readOnly || e.altKey || e.ctrlKey || e.metaKey){ return; }
+				var	step = this.step,
+					multiplier = 1,
+					newValue;
+				switch(e.keyCode){
+					case keys.HOME:
+						newValue = this.min;
+						break;
+					case keys.END:
+						newValue = this.max;
+						break;
+					case keys.RIGHT_ARROW:
+						multiplier = -1;
+					case keys.LEFT_ARROW:
+						newValue = this.value + multiplier * ((flip && horizontal) ? step : -step);
+						break;
+					case keys.DOWN_ARROW:
+						multiplier = -1;
+					case keys.UP_ARROW:
+						newValue = this.value + multiplier * ((!flip || horizontal) ? step : -step);
+						break;
+					default:
+						return;
+				}
+				e.preventDefault();
+				this._setValueAttr(newValue, false);
+			}
+
+			function keyUp(/*Event*/ e){
+				if(this.disabled || this.readOnly || e.altKey || e.ctrlKey || e.metaKey){ return; }
+				this._setValueAttr(this.value, true);
+			}
+
+			var	point, pixelValue, value,
+				node = this.domNode;
 			if(this.orientation == "auto"){
 				 this.orientation = node.offsetHeight <= node.offsetWidth ? "H" : "V";
 			}
 			// add V or H suffix to baseClass for styling purposes
 			domClass.add(this.domNode, array.map(this.baseClass.split(" "), lang.hitch(this, function(c){ return c+this.orientation; })));
-			var horizontal = this.orientation != "V";
-			var ltr = horizontal ? this.isLeftToRight() : false;
-			var flip = this.flip;
+			var	horizontal = this.orientation != "V",
+				ltr = horizontal ? this.isLeftToRight() : false,
+				flip = !!this.flip;
 			// _reversed is complicated since you can have flipped right-to-left and vertical is upside down by default
-			this._reversed = !(horizontal && ((ltr && !flip) || (!ltr && flip))) || (!horizontal && !flip);
+			this._reversed = !((horizontal && ((ltr && !flip) || (!ltr && flip))) || (!horizontal && flip));
 			this._attrs = horizontal ? { x:'x', w:'w', l:'l', r:'r', pageX:'pageX', clientX:'clientX', handleLeft:"left", left:this._reversed ? "right" : "left", width:"width" } : { x:'y', w:'h', l:'t', r:'b', pageX:'pageY', clientX:'clientY', handleLeft:"top", left:this._reversed ? "bottom" : "top", width:"height" };
 			this.progressBar.style[this._attrs.left] = "0px";
-			this.connect(this.touchBox, "touchstart", beginDrag);
-			this.connect(this.touchBox, "onmousedown", beginDrag); // in case this works
-			this.connect(this.handle, "touchstart", beginDrag);
-			this.connect(this.handle, "onmousedown", beginDrag); // in case this works
+			this.connect(this.touchBox, touch.press, beginDrag);
+			this.connect(this.handle, touch.press, beginDrag);
+			this.connect(this.domNode, "onkeypress", keyPress); // for desktop a11y
+			this.connect(this.domNode, "onkeyup", keyUp); // fire onChange on desktop
 			this.startup();
 			this.set('value', this.value);
 		}
diff --git a/dojox/mobile/SpinWheel.js b/dojox/mobile/SpinWheel.js
index c8b58f6..fbe57e5 100644
--- a/dojox/mobile/SpinWheel.js
+++ b/dojox/mobile/SpinWheel.js
@@ -1,27 +1,15 @@
 define([
-	"dojo/_base/array",
 	"dojo/_base/declare",
-	"dojo/_base/lang",
-	"dojo/dom-class",
+	"dojo/_base/array",
 	"dojo/dom-construct",
-	"dijit/_Contained",
-	"dijit/_Container",
-	"dijit/_WidgetBase",
-	"./SpinWheelSlot"
-], function(array, declare, lang, domClass, domConstruct, Contained, Container, WidgetBase, SpinWheelSlot){
-
-/*=====
-	var Contained = dijit._Contained;
-	var Container = dijit._Container;
-	var WidgetBase = dijit._WidgetBase;
-=====*/
+	"./_PickerBase",
+	"./SpinWheelSlot" // to load SpinWheelSlot for you (no direct references)
+], function(declare, array, domConstruct, PickerBase){
 
 	// module:
 	//		dojox/mobile/SpinWheel
-	// summary:
-	//		A value picker widget that has spin wheels.
 
-	return declare("dojox.mobile.SpinWheel", [WidgetBase, Container, Contained],{
+	return declare("dojox.mobile.SpinWheel", PickerBase, {
 		// summary:
 		//		A value picker widget that has spin wheels.
 		// description:
@@ -29,69 +17,32 @@ define([
 		//		that can be used to pick up some values from the wheel slots by
 		//		spinning them.
 
-		// slotClasses: Array
-		//		An array of slot classes to be this SpinWheel's slots.
-		slotClasses: [],
-
-		// slotProps: Array
-		//		An array of property objects for each slot class specified in
-		//		slotClasses.
-		slotProps: [],
-
 		/* internal properties */	
-		centerPos: 0,
+		baseClass: "mblSpinWheel",
 
 		buildRendering: function(){
 			this.inherited(arguments);
-			domClass.add(this.domNode, "mblSpinWheel");
-			this.centerPos = Math.round(this.domNode.offsetHeight / 2);
-
-			this.slots = [];
-			for(var i = 0; i < this.slotClasses.length; i++){
-				this.slots.push(((typeof this.slotClasses[i] =='string') ? lang.getObject(this.slotClasses[i]) : this.slotClasses[i])(this.slotProps[i]));
-				this.addChild(this.slots[i]);
-			}
-			domConstruct.create("DIV", {className: "mblSpinWheelBar"}, this.domNode);
+			domConstruct.create("div", {className: "mblSpinWheelBar"}, this.domNode);
 		},
 
 		startup: function(){
+			if(this._started){ return; }
+			this.centerPos = Math.round(this.domNode.offsetHeight / 2);
 			this.inherited(arguments);
-			this.reset();
-		},
-
-		getValue: function(){
-			// summary:
-			//		Returns an array of slot values.
-			var a = [];
-			array.forEach(this.getChildren(), function(w){
-				if(w instanceof SpinWheelSlot){
-					a.push(w.getValue());
-				}
-			}, this);
-			return a;
 		},
 
-		setValue: function(/*Array*/a){
-			// summary:
-			//		Sets the slot values.
-			var i = 0;
-			array.forEach(this.getChildren(), function(w){
-				if(w instanceof SpinWheelSlot){
-					w.setValue(a[i]);
-					w.setColor(a[i]);
-					i++;
-				}
-			}, this);
+		resize: function() {
+			this.centerPos = Math.round(this.domNode.offsetHeight / 2);
+			array.forEach(this.getChildren(), function(child){
+				child.resize && child.resize();
+			});
 		},
 
-		reset: function(){
-			// summary:
-			//		Resets the SpinWheel to show the initial values.
-			array.forEach(this.getChildren(), function(w){
-				if(w instanceof SpinWheelSlot){
-					w.setInitialValue();
-				}
-			}, this);
+		addChild: function(/*Widget*/ widget, /*int?*/ insertIndex){
+			this.inherited(arguments);
+			if(this._started){
+				widget.setInitialValue();
+			}
 		}
 	});
 });
diff --git a/dojox/mobile/SpinWheelDatePicker.js b/dojox/mobile/SpinWheelDatePicker.js
index 3a533d0..a8a698b 100644
--- a/dojox/mobile/SpinWheelDatePicker.js
+++ b/dojox/mobile/SpinWheelDatePicker.js
@@ -1,109 +1,54 @@
 define([
+	"dojo/_base/array",
 	"dojo/_base/declare",
 	"dojo/dom-class",
-	"dojo/date",
-	"dojo/date/locale",
+	"./_DatePickerMixin",
 	"./SpinWheel",
 	"./SpinWheelSlot"
-], function(declare, domClass, ddate, datelocale, SpinWheel, SpinWheelSlot){
-
-/*=====
-	var SpinWheel = dojox.mobile.SpinWheel;
-	var SpinWheelSlot = dojox.mobile.SpinWheelSlot;
-=====*/
+], function(array, declare, domClass, DatePickerMixin, SpinWheel, SpinWheelSlot){
 
 	// module:
 	//		dojox/mobile/SpinWheelDatePicker
-	// summary:
-	//		A SpinWheel-based date picker widget.
-
-	//TODO: the api doc parser seems to fail if the 1st arg for declare (=class name) is missing..
-	var SpinWheelYearSlot = declare(/*===== "dojox.mobile.SpinWheelYearSlot", =====*/ SpinWheelSlot, {
-		buildRendering: function(){
-			this.labels = [];
-			if(this.labelFrom !== this.labelTo){
-				var dtA = new Date(this.labelFrom, 0, 1);
-				var i, idx;
-				for(i = this.labelFrom, idx = 0; i <= this.labelTo; i++, idx++){
-					dtA.setFullYear(i);
-					this.labels.push(datelocale.format(dtA, {datePattern:"yyyy", selector:"date"}));
-				}
-			}
-			this.inherited(arguments);
-		}
-	});
-
-	var SpinWheelMonthSlot = declare(/*===== "dojox.mobile.SpinWheelMonthSlot", =====*/ SpinWheelSlot, {
-		buildRendering: function(){
-			this.labels = [];
-			var dtA = new Date(2000, 0, 1);
-			var monthStr;
-			for(var i = 0; i < 12; i++){
-				dtA.setMonth(i);
-				monthStr = datelocale.format(dtA, {datePattern:"MMM", selector:"date"});
-				this.labels.push(monthStr);
-			}
-			this.inherited(arguments);
-		}
-	});
-
-	var SpinWheelDaySlot = declare(/*===== "dojox.mobile.SpinWheelDaySlot", =====*/ SpinWheelSlot, {
-	});
 
-	return declare("dojox.mobile.SpinWheelDatePicker", SpinWheel, {
+	return declare("dojox.mobile.SpinWheelDatePicker", [SpinWheel, DatePickerMixin], {
 		// summary:
 		//		A SpinWheel-based date picker widget.
 		// description:
 		//		SpinWheelDatePicker is a date picker widget. It is a subclass of
-		//		dojox.mobile.SpinWheel. It has the year, month, and day slots.
+		//		dojox/mobile/SpinWheel. It has three slots: year, month, and day.
 
 		slotClasses: [
-			SpinWheelYearSlot,
-			SpinWheelMonthSlot,
-			SpinWheelDaySlot
+			SpinWheelSlot,
+			SpinWheelSlot,
+			SpinWheelSlot
 		],
+
 		slotProps: [
 			{labelFrom:1970, labelTo:2038},
 			{},
-			{labelFrom:1, labelTo:31}
+			{}
 		],
 
 		buildRendering: function(){
+			this.initSlots();
 			this.inherited(arguments);
 			domClass.add(this.domNode, "mblSpinWheelDatePicker");
-			this.connect(this.slots[1], "onFlickAnimationEnd", "onMonthSet");
-			this.connect(this.slots[2], "onFlickAnimationEnd", "onDaySet");
+			this._conn = [
+				this.connect(this.slots[0], "onFlickAnimationEnd", "_onYearSet"),
+				this.connect(this.slots[1], "onFlickAnimationEnd", "_onMonthSet"),
+				this.connect(this.slots[2], "onFlickAnimationEnd", "_onDaySet")
+			];
 		},
 
-		reset: function(){
+		disableValues: function(/*Number*/daysInMonth){
 			// summary:
-			//		Goes to today.
-			var slots = this.slots;
-			var now = new Date();
-			var monthStr = datelocale.format(now, {datePattern:"MMM", selector:"date"});
-			this.setValue([now.getFullYear(), monthStr, now.getDate()]);
-		},
-
-		onMonthSet: function(){
-			// summary:
-			//		A handler called when the month value is changed.
-			var daysInMonth = this.onDaySet();
-			var disableValuesTable = {28:[29,30,31], 29:[30,31], 30:[31], 31:[]};
-			this.slots[2].disableValues(disableValuesTable[daysInMonth]);
-		},
-
-		onDaySet: function(){
-			// summary:
-			//		A handler called when the day value is changed.
-			var y = this.slots[0].getValue();
-			var m = this.slots[1].getValue();
-			var newMonth = datelocale.parse(y+"/"+m, {datePattern:'yyyy/MMM', selector:'date'});
-			var daysInMonth = ddate.getDaysInMonth(newMonth);
-			var d = this.slots[2].getValue();
-			if(daysInMonth < d){
-				this.slots[2].setValue(daysInMonth);
-			}
-			return daysInMonth;
+			//		Disables the end days of the month to match the specified
+			//		number of days of the month.
+			array.forEach(this.slots[2].panelNodes, function(panel){
+				for(var i = 27; i < 31; i++){
+					domClass.toggle(panel.childNodes[i], "mblSpinWheelSlotLabelGray", i >= daysInMonth);
+				}
+			});
 		}
 	});
 });
diff --git a/dojox/mobile/SpinWheelSlot.js b/dojox/mobile/SpinWheelSlot.js
index e31ce9c..028d675 100644
--- a/dojox/mobile/SpinWheelSlot.js
+++ b/dojox/mobile/SpinWheelSlot.js
@@ -1,75 +1,100 @@
 define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
 	"dojo/_base/declare",
 	"dojo/_base/window",
 	"dojo/dom-class",
 	"dojo/dom-construct",
+	"dojo/has", 
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/SpinWheelSlot",
+	"dojo/touch",
+	"dojo/on",
 	"dijit/_Contained",
 	"dijit/_WidgetBase",
-	"./_ScrollableMixin"
-], function(declare, win, domClass, domConstruct, Contained, WidgetBase, ScrollableMixin){
-
-/*=====
-	var Contained = dijit._Contained;
-	var WidgetBase = dijit._WidgetBase;
-	var ScrollableMixin = dojox.mobile._ScrollableMixin;
-=====*/
+	"./scrollable",
+	"./common"
+], function(dojo, array, declare, win, domClass, domConstruct, has, BidiSpinWheelSlot, 
+	touch, on, Contained, WidgetBase, Scrollable){
 
 	// module:
 	//		dojox/mobile/SpinWheelSlot
-	// summary:
-	//		A slot of a SpinWheel.
 
-	return declare("dojox.mobile.SpinWheelSlot", [WidgetBase, Contained, ScrollableMixin], {
+	var SpinWheelSlot = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiSpinWheelSlot" : "dojox.mobile.SpinWheelSlot", [WidgetBase, Contained, Scrollable], {
 		// summary:
 		//		A slot of a SpinWheel.
 		// description:
 		//		SpinWheelSlot is a slot that is placed in the SpinWheel widget.
 
 		// items: Array
-		//		An array of array of key-label paris.
-		//		(e.g. [[0,"Jan"],[1,"Feb"],...] ) If key values for each label
+		//		An array of array of key-label pairs
+		//		(e.g. [[0, "Jan"], [1, "Feb"], ...]). If key values for each label
 		//		are not necessary, labels can be used instead.
 		items: [],
 
 		// labels: Array
-		//		An array of labels to be displayed on the slot.
-		//		(e.g. ["Jan","Feb",...] ) This is a simplified version of the
+		//		An array of labels to be displayed on the slot
+		//		(e.g. ["Jan", "Feb", ...]). This is a simplified version of the
 		//		items property.
 		labels: [],
 
 		// labelFrom: Number
 		//		The start value of display values of the slot. This parameter is
-		//		especially useful when slot has serial values.
+		//		especially useful when the slot has serial values.
 		labelFrom: 0,
 
 		// labelTo: Number
 		//		The end value of display values of the slot.
 		labelTo: 0,
 
+		// zeroPad: Number
+		//		Length of zero padding numbers.
+		//		Ex. zeroPad=2 -> "00", "01", ...
+		//		Ex. zeroPad=3 -> "000", "001", ...
+		zeroPad: 0,
+
 		// value: String
 		//		The initial value of the slot.
 		value: "",
 
+		// step: Number
+		//		The steps between labelFrom and labelTo.
+		step: 1,
+
+		// tabIndex: String
+		//		Tabindex setting for this widget so users can hit the tab key to
+		//		focus on it.
+		tabIndex: "0",
+		_setTabIndexAttr: "", // sets tabIndex to domNode
+
 		/* internal properties */	
+		baseClass: "mblSpinWheelSlot",
+		// maxSpeed: [private] Number
+		//		Maximum speed.
 		maxSpeed: 500,
+		// minItems: [private] int
+		//		Minimum number of items.
 		minItems: 15,
+		// centerPos: [private] Number
+		//		Inherited from parent.
 		centerPos: 0,
+		// scrollbar: [private] Boolean
+		//		False: no scrollbars must be shown.
 		scrollBar: false,
+		// constraint: [private] Boolean
+		//		False: no scroll constraint.
 		constraint: false,
-		allowNestedScrolls: false,
-		androidWorkaroud: false, // disable workaround in SpinWheel
+		// propagatable: [private] Boolean
+		//		False: stop touchstart event propagation.
+		propagatable: false, // stop touchstart event propagation to make spin wheel work inside scrollable
+		// androidWorkaroud: [private] Boolean
+		//		False.
+		androidWorkaroud: false, // disable workaround in SpinWheel TODO:remove this line later
 
 		buildRendering: function(){
 			this.inherited(arguments);
-			domClass.add(this.domNode, "mblSpinWheelSlot");
 
-			var i, j, idx;
-			if(this.labelFrom !== this.labelTo){
-				this.labels = [];
-				for(i = this.labelFrom, idx = 0; i <= this.labelTo; i++, idx++){
-					this.labels[idx] = String(i);
-				}
-			}
+			this.initLabels();
+			var i, j;
 			if(this.labels.length > 0){
 				this.items = [];
 				for(i = 0; i < this.labels.length; i++){
@@ -77,38 +102,131 @@ define([
 				}
 			}
 
-			this.containerNode = domConstruct.create("DIV", {className:"mblSpinWheelSlotContainer"});
+			this.containerNode = domConstruct.create("div", {className:"mblSpinWheelSlotContainer"});
 			this.containerNode.style.height
 				= (win.global.innerHeight||win.doc.documentElement.clientHeight) * 2 + "px"; // must bigger than the screen
 			this.panelNodes = [];
 			for(var k = 0; k < 3; k++){
-				this.panelNodes[k] = domConstruct.create("DIV", {className:"mblSpinWheelSlotPanel"});
+				this.panelNodes[k] = domConstruct.create("div", {className:"mblSpinWheelSlotPanel"});
 				var len = this.items.length;
-				var n = Math.ceil(this.minItems / len);
-				for(j = 0; j < n; j++){
-					for(i = 0; i < len; i++){
-						domConstruct.create("DIV", {
-							className: "mblSpinWheelSlotLabel",
-							name: this.items[i][0],
-							innerHTML: this._cv ? this._cv(this.items[i][1]) : this.items[i][1]
-						}, this.panelNodes[k]);
+				if(len > 0){ // if the slot is not empty
+					var n = Math.ceil(this.minItems / len);
+					for(j = 0; j < n; j++){
+						for(i = 0; i < len; i++){
+							domConstruct.create("div", {
+								className: "mblSpinWheelSlotLabel",
+								name: this.items[i][0],
+								"data-mobile-val": this.items[i][1],
+								innerHTML: this._cv ? this._cv(this.items[i][1]) : this.items[i][1]
+							}, this.panelNodes[k]);
+						}
 					}
 				}
 				this.containerNode.appendChild(this.panelNodes[k]);
 			}
 			this.domNode.appendChild(this.containerNode);
-			this.touchNode = domConstruct.create("DIV", {className:"mblSpinWheelSlotTouch"}, this.domNode);
+			this.touchNode = domConstruct.create("div", {className:"mblSpinWheelSlotTouch"}, this.domNode);
 			this.setSelectable(this.domNode, false);
+
+			if(this.value === "" && this.items.length > 0){
+				this.value = this.items[0][1];
+			}
+			this._initialValue = this.value;
+
+			if(has("windows-theme")){
+				var self = this,
+					containerNode = this.containerNode,
+					threshold = 5;
+
+				this.own(on(self.touchNode, touch.press, function(e){
+					var posY = e.pageY,
+						slots = self.getParent().getChildren();
+
+					for(var i = 0, ln = slots.length; i < ln; i++){
+						var container = slots[i].containerNode;
+
+						if(containerNode !== container){
+							domClass.remove(container, "mblSelectedSlot");
+							container.selected = false;
+						}else{
+							domClass.add(containerNode, "mblSelectedSlot");
+						}
+					}
+
+					var moveHandler = on(self.touchNode, touch.move, function(e){
+						if(Math.abs(e.pageY - posY) < threshold){
+							return;
+						}
+
+						moveHandler.remove();
+						releaseHandler.remove();
+						containerNode.selected = true;
+
+						var item = self.getCenterItem();
+
+						if(item){
+							domClass.remove(item, "mblSelectedSlotItem");
+						}
+					});
+
+					var releaseHandler = on(self.touchNode, touch.release, function(){
+						releaseHandler.remove();
+						moveHandler.remove();
+						containerNode.selected ?
+							domClass.remove(containerNode, "mblSelectedSlot") :
+							domClass.add(containerNode, "mblSelectedSlot");
+
+						containerNode.selected = !containerNode.selected;
+					});
+				}));
+
+				this.on("flickAnimationEnd", function(){
+						var item = self.getCenterItem();
+
+						if(self.previousCenterItem) {
+							domClass.remove(self.previousCenterItem, "mblSelectedSlotItem");
+						}
+
+						domClass.add(item, "mblSelectedSlotItem");
+						self.previousCenterItem = item;
+				});
+			}
 		},
-	
+
 		startup: function(){
+			if(this._started){ return; }
 			this.inherited(arguments);
-			this.centerPos = this.getParent().centerPos;
-			var items = this.panelNodes[1].childNodes;
-			this._itemHeight = items[0].offsetHeight;
-			this.adjust();
+			this.noResize = true;
+			if(this.items.length > 0){ // if the slot is not empty
+				this.init();
+				this.centerPos = this.getParent().centerPos;
+				var items = this.panelNodes[1].childNodes;
+				this._itemHeight = items[0].offsetHeight;
+				this.adjust();
+				this.connect(this.domNode, "onkeydown", "_onKeyDown"); // for desktop browsers
+			}
+			if(has("windows-theme")){
+				this.previousCenterItem = this.getCenterItem();
+				if(this.previousCenterItem){
+					domClass.add(this.previousCenterItem, "mblSelectedSlotItem");
+				}
+			}
 		},
-	
+
+		initLabels: function(){
+			// summary:
+			//		Initializes the slot labels according to the labelFrom/labelTo properties.
+			// tags:
+			//		private
+			if(this.labelFrom !== this.labelTo){
+				var a = this.labels = [],
+					zeros = this.zeroPad && Array(this.zeroPad).join("0");
+				for(var i = this.labelFrom; i <= this.labelTo; i += this.step){
+					a.push(this.zeroPad ? (zeros + i).slice(-this.zeroPad) : i + "");
+				}
+			}
+		},
+
 		adjust: function(){
 			// summary:
 			//		Adjusts the position of slot panels.
@@ -126,17 +244,23 @@ define([
 			this.panelNodes[1].style.top = adjustY + "px";
 			this.panelNodes[2].style.top = h + adjustY + "px";
 		},
-	
+
 		setInitialValue: function(){
 			// summary:
 			//		Sets the initial value using this.value or the first item.
-			if(this.items.length > 0){
-				var val = (this.value !== "") ? this.value : this.items[0][1];
-				this.setValue(val);
+			this.set("value", this._initialValue);
+		},
+
+		_onKeyDown: function(e){
+			if(!e || e.type !== "keydown"){ return; }
+			if(e.keyCode === 40){ // down arrow key
+				this.spin(-1);
+			}else if(e.keyCode === 38){ // up arrow key
+				this.spin(1);
 			}
 		},
-	
-		getCenterPanel: function(){
+
+		_getCenterPanel: function(){
 			// summary:
 			//		Gets a panel that contains the currently selected item.
 			var pos = this.getPos();
@@ -148,44 +272,32 @@ define([
 			}
 			return null;
 		},
-	
-		setColor: function(/*String*/value){
+
+		setColor: function(/*String*/value, /*String?*/color){
 			// summary:
 			//		Sets the color of the specified item as blue.
-			for(var i = 0, len = this.panelNodes.length; i < len; i++){
-				var items = this.panelNodes[i].childNodes;
-				for(var j = 0; j < items.length; j++){
-					if(items[j].innerHTML === String(value)){
-						domClass.add(items[j], "mblSpinWheelSlotLabelBlue");
-					}else{
-						domClass.remove(items[j], "mblSpinWheelSlotLabelBlue");
-					}
-				}
-			}
+			array.forEach(this.panelNodes, function(panel){
+				array.forEach(panel.childNodes, function(node, i){
+					domClass.toggle(node, color || "mblSpinWheelSlotLabelBlue", node.innerHTML === value);
+				}, this);
+			}, this);
 		},
-	
-		disableValues: function(/*Array*/values){
+
+		disableValues: function(/*Number*/n){
 			// summary:
-			//		Makes the specified items grayed out.
-			for(var i = 0, len = this.panelNodes.length; i < len; i++){
-				var items = this.panelNodes[i].childNodes;
-				for(var j = 0; j < items.length; j++){
-					domClass.remove(items[j], "mblSpinWheelSlotLabelGray");
-					for(var k = 0; k < values.length; k++){
-						if(items[j].innerHTML === String(values[k])){
-							domClass.add(items[j], "mblSpinWheelSlotLabelGray");
-							break;
-						}
-					}
+			//		Grays out the items with an index higher or equal to the specified number.
+			array.forEach(this.panelNodes, function(panel){
+				for(var i = 0; i < panel.childNodes.length; i++){
+					domClass.toggle(panel.childNodes[i], "mblSpinWheelSlotLabelGray", i >= n);
 				}
-			}
+			});
 		},
-	
+
 		getCenterItem: function(){
 			// summary:
 			//		Gets the currently selected item.
 			var pos = this.getPos();
-			var centerPanel = this.getCenterPanel();
+			var centerPanel = this._getCenterPanel();
 			if(centerPanel){
 				var top = pos.y + centerPanel.offsetTop;
 				var items = centerPanel.childNodes;
@@ -196,38 +308,75 @@ define([
 				}
 			}
 			return null;
-	
+
 		},
-	
-		getValue: function(){
+
+		_getKeyAttr: function(){
 			// summary:
-			//		Gets the currently selected value.
+			//		Gets the key for the currently selected value.
+			if(!this._started){
+				if(this.items){
+					var v = this.value;
+					for(var i = 0; i < this.items.length; i++){
+						if(this.items[i][1] == this.value){
+							return this.items[i][0];
+						}
+					}
+				}
+				return null;
+			}
 			var item = this.getCenterItem();
-			return (item && item.innerHTML);
+			return (item && item.getAttribute("name"));
 		},
-	
-		getKey: function(){
+
+		_getValueAttr: function(){
 			// summary:
-			//		Gets the key for the currently selected value.
-			return this.getCenterItem().getAttribute("name");
+			//		Gets the currently selected value.
+			if(!this._started){
+				return this.value;
+			}
+			if(this.items.length > 0){ // if the slot is not empty
+				var item = this.getCenterItem();
+				return (item && item.getAttribute("data-mobile-val"));
+			}else{
+				return this._initialValue;
+			}
 		},
-	
-		setValue: function(newValue){
+
+		_setValueAttr: function(value){
+			// summary:
+			//		Sets the value to this slot.
+			if(this.items.length > 0){ // no-op for empty slots
+				this._spinToValue(value, true);
+			}
+		},
+		
+		_spinToValue: function(value, applyValue){
 			// summary:
-			//		Sets the newValue to this slot.
+			//		Spins the slot to the specified value.
+			// tags:
+			//		private
 			var idx0, idx1;
-			var curValue = this.getValue();
+			var curValue = this.get("value");
 			if(!curValue){
-				this._penddingValue = newValue;
+				this._pendingValue = value;
 				return;
 			}
-			this._penddingValue = undefined;
+			if(curValue == value){
+				return; // no change; avoid notification
+			}
+			this._pendingValue = undefined;
+			// to avoid unnecessary notifications, applyValue is false when 
+			// _spinToValue is called by _DatePickerMixin.
+			if(applyValue){
+				this._set("value", value);
+			}
 			var n = this.items.length;
 			for(var i = 0; i < n; i++){
 				if(this.items[i][1] === String(curValue)){
 					idx0 = i;
 				}
-				if(this.items[i][1] === String(newValue)){
+				if(this.items[i][1] === String(value)){
 					idx1 = i;
 				}
 				if(idx0 !== undefined && idx1 !== undefined){
@@ -241,14 +390,40 @@ define([
 			}else{
 				m = (-d < n + d) ? -d : -(n + d);
 			}
+			this.spin(m);
+		},
+		
+		onFlickAnimationStart: function(e){
+			// summary:
+			//		Overrides dojox/mobile/scrollable.onFlickAnimationStart().
+			this._onFlickAnimationStartCalled = true;
+			this.inherited(arguments);
+		},
+
+		onFlickAnimationEnd: function(e){
+			// summary:
+			//		Overrides dojox/mobile/scrollable.onFlickAnimationEnd().
+			this._duringSlideTo = false;
+			this._onFlickAnimationStartCalled = false;
+			this.inherited(arguments);
+		},
+		
+		spin: function(/*Number*/steps){
+			// summary:
+			//		Spins the slot as specified by steps.
+			
+			// do nothing before startup and during slide
+			if(!this._started || this._duringSlideTo){
+				return; 
+			}
 			var to = this.getPos();
-			to.y += m * this._itemHeight;
+			to.y += steps * this._itemHeight;
 			this.slideTo(to, 1);
 		},
-	
+
 		getSpeed: function(){
 			// summary:
-			//		Overrides dojox.mobile.scrollable.getSpeed().
+			//		Overrides dojox/mobile/scrollable.getSpeed().
 			var y = 0, n = this._time.length;
 			var delta = (new Date()).getTime() - this.startTime - this._time[n - 1];
 			if(n >= 2 && delta < 200){
@@ -261,7 +436,7 @@ define([
 
 		calcSpeed: function(/*Number*/d, /*Number*/t){
 			// summary:
-			//		Overrides dojox.mobile.scrollable.calcSpeed().
+			//		Overrides dojox/mobile/scrollable.calcSpeed().
 			var speed = this.inherited(arguments);
 			if(!speed){ return 0; }
 			var v = Math.abs(speed);
@@ -271,26 +446,36 @@ define([
 			}
 			return ret;
 		},
-	
-		adjustDestination: function(to, pos){
+
+		adjustDestination: function(to, pos, dim){
 			// summary:
-			//		Overrides dojox.mobile.scrollable.adjustDestination().
+			//		Overrides dojox/mobile/scrollable.adjustDestination().
 			var h = this._itemHeight;
 			var j = to.y + Math.round(h/2);
-			var a = Math.abs(j);
 			var r = j >= 0 ? j % h : j % h + h;
 			to.y = j - r;
+			return true;
 		},
-	
+
 		resize: function(e){
-			if(this._penddingValue){
-				this.setValue(this._penddingValue);
+			// Correct internal variables & adjust slot panels
+			var items = this.panelNodes[1].childNodes;
+			// TODO investigate - the position is calculated incorrectly for 
+			// windows theme, disable this logic for now.
+			if(items.length > 0 && !has("windows-theme")){ // empty slot?
+				this._itemHeight = items[0].offsetHeight;
+				this.centerPos = this.getParent().centerPos;
+				this.adjust();
+			}
+			if(this._pendingValue){
+				this.set("value", this._pendingValue);
 			}
 		},
 
 		slideTo: function(/*Object*/to, /*Number*/duration, /*String*/easing){
 			// summary:
-			//		Overrides dojox.mobile.scrollable.slideTo().
+			//		Overrides dojox/mobile/scrollable.slideTo().
+			this._duringSlideTo = true; 
 			var pos = this.getPos();
 			var top = pos.y + this.panelNodes[1].offsetTop;
 			var bottom = top + this.panelNodes[1].offsetHeight;
@@ -315,13 +500,25 @@ define([
 					this.panelNodes[2] = t;
 				}
 			}
-			if(!this._initialized){
+			if(this.getParent()._duringStartup){
 				duration = 0; // to reduce flickers at start-up especially on android
-				this._initialized = true;
 			}else if(Math.abs(this._speed.y) < 40){
 				duration = 0.2;
 			}
 			this.inherited(arguments, [to, duration, easing]); // 2nd arg is to avoid excessive optimization by closure compiler
+			if(this.getParent()._duringStartup && !this._onFlickAnimationStartCalled){
+				// during startup, because of duration set to 0, if onFlickAnimationStart() 
+				// has not been called (depends on scrollType value), the call of 
+				// onFlickAnimationEnd is missing, hence:
+				this.onFlickAnimationEnd();
+			}else if(!this._onFlickAnimationStartCalled){
+				// if onFlickAnimationStart() wasn't called, and if slideTo() didn't call
+				// itself onFlickAnimationEnd():
+				this._duringSlideTo = false;
+				// (otherwise, wait for onFlickAnimationEnd which deletes the flag)
+			}
 		}
 	});
+
+	return has("dojo-bidi") ? declare("dojox.mobile.SpinWheelSlot", [SpinWheelSlot, BidiSpinWheelSlot]) : SpinWheelSlot;	
 });
diff --git a/dojox/mobile/SpinWheelTimePicker.js b/dojox/mobile/SpinWheelTimePicker.js
index c94745e..a40f55b 100644
--- a/dojox/mobile/SpinWheelTimePicker.js
+++ b/dojox/mobile/SpinWheelTimePicker.js
@@ -1,57 +1,34 @@
 define([
 	"dojo/_base/declare",
 	"dojo/dom-class",
+	"./_TimePickerMixin",
 	"./SpinWheel",
 	"./SpinWheelSlot"
-], function(declare, domClass, SpinWheel, SpinWheelSlot){
-
-/*=====
-	var SpinWheel = dojox.mobile.SpinWheel;
-=====*/
+], function(declare, domClass, TimePickerMixin, SpinWheel, SpinWheelSlot){
 
 	// module:
 	//		dojox/mobile/SpinWheelTimePicker
-	// summary:
-	//		A SpinWheel-based time picker widget.
 
-	return declare("dojox.mobile.SpinWheelTimePicker", SpinWheel, {
+	return declare("dojox.mobile.SpinWheelTimePicker", [SpinWheel, TimePickerMixin], {
 		// summary:
 		//		A SpinWheel-based time picker widget.
 		// description:
 		//		SpinWheelTimePicker is a time picker widget. It is a subclass of
-		//		dojox.mobile.SpinWheel. It has the hour and minute slots.
+		//		dojox/mobile/SpinWheel. It has two slots: hour and minute.
 
 		slotClasses: [
 			SpinWheelSlot,
 			SpinWheelSlot
 		],
+
 		slotProps: [
-			{labelFrom:0, labelTo:23},
-			{labels:["00","01","02","03","04","05","06","07","08","09",
-					 "10","11","12","13","14","15","16","17","18","19",
-					 "20","21","22","23","24","25","26","27","28","29",
-					 "30","31","32","33","34","35","36","37","38","39",
-					 "40","41","42","43","44","45","46","47","48","49",
-					 "50","51","52","53","54","55","56","57","58","59"]}
+			{labelFrom:0, labelTo:23, style:{width:"50px", textAlign:"right"}},
+			{labelFrom:0, labelTo:59, zeroPad:2, style:{width:"40px", textAlign:"right"}}
 		],
 
 		buildRendering: function(){
 			this.inherited(arguments);
 			domClass.add(this.domNode, "mblSpinWheelTimePicker");
-		},
-
-		reset: function(){
-			// summary:
-			//		Goes to now.
-			var slots = this.slots;
-			var now = new Date();
-			var _h = now.getHours() + "";
-			slots[0].setValue(_h);
-			slots[0].setColor(_h);
-			var m = now.getMinutes();
-			var _m = (m < 10 ? "0" : "") + m;
-			slots[1].setValue(_m);
-			slots[1].setColor(_m);
 		}
 	});
 });
diff --git a/dojox/mobile/StoreCarousel.js b/dojox/mobile/StoreCarousel.js
new file mode 100644
index 0000000..e2b9e15
--- /dev/null
+++ b/dojox/mobile/StoreCarousel.js
@@ -0,0 +1,17 @@
+define([
+	"dojo/_base/declare",
+	"./Carousel",
+	"./_StoreMixin"
+], function(declare, Carousel, StoreMixin){
+
+	// module:
+	//		dojox/mobile/StoreCarousel
+
+	return declare("dojox.mobile.StoreCarousel", [Carousel, StoreMixin], {
+		// summary:
+		//		A dojo/store enabled Carousel.
+		// description:
+		//		StoreCarousel is a subclass of dojox/mobile/Carousel which
+		//		can generate contents according to the given dojo/store store.
+	});
+});
diff --git a/dojox/mobile/SwapView.js b/dojox/mobile/SwapView.js
old mode 100644
new mode 100755
index fce753a..f9d6735
--- a/dojox/mobile/SwapView.js
+++ b/dojox/mobile/SwapView.js
@@ -4,44 +4,55 @@ define([
 	"dojo/_base/declare",
 	"dojo/dom",
 	"dojo/dom-class",
-	"dijit/registry",	// registry.byNode
+	"dijit/registry",
 	"./View",
-	"./_ScrollableMixin"
-], function(array, connect, declare, dom, domClass, registry, View, ScrollableMixin){
-
-/*=====
-	var View = dojox.mobile.View;
-	var ScrollableMixin = dojox.mobile._ScrollableMixin;
-=====*/
+	"./_ScrollableMixin",
+	"./sniff",
+	"./_css3",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/SwapView"
+], function(array, connect, declare, dom, domClass, registry, View, ScrollableMixin, has, css3, BidiSwapView){
 
 	// module:
 	//		dojox/mobile/SwapView
-	// summary:
-	//		A container that can be flipped horizontally.
 
-	return declare("dojox.mobile.SwapView", [View, ScrollableMixin], {
+	var SwapView = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiSwapView" : "dojox.mobile.SwapView", [View, ScrollableMixin], {
 		// summary:
-		//		A container that can be flipped horizontally.
+		//		A container that can be swiped horizontally.
 		// description:
-		//		SwapView is a container widget that represents entire mobile
-		//		device screen, and can be swiped horizontally. (In dojo-1.6, it
-		//		was called 'FlippableView'.) SwapView is a subclass of
-		//		dojox.mobile.View. SwapView allows the user to swipe the screen
-		//		left or right to move between the views. When SwapView is
-		//		swiped, it finds an adjacent SwapView to open it.
+		//		SwapView is a container widget which can be swiped horizontally. 
+		//		SwapView is a subclass of dojox/mobile/View. It allows the user to 
+		//		swipe the screen left or right to move between the views. When 
+		//		SwapView is swiped, it finds an adjacent SwapView to open. When 
+		//		the transition is done, a topic "/dojox/mobile/viewChanged" is 
+		//		published. Note that, to behave properly, the SwapView needs to 
+		//		occupy the entire width of the screen.
 
 		/* internal properties */	
+		// scrollDir: [private] String
+		//		Scroll direction, used by dojox/mobile/scrollable (always "f" for this class).
 		scrollDir: "f",
+		// weight: [private] Number
+		//		Frictional weight used to compute scrolling speed.
 		weight: 1.2,
 
+		// _endOfTransitionTimeoutHandle: [private] Object
+		//		The handle (returned by _WidgetBase.defer) for the timeout set on touchEnd in case
+		//      the end of transition event is not fired by the browser.
+		_endOfTransitionTimeoutHandle: null,
+
 		buildRendering: function(){
 			this.inherited(arguments);
 			domClass.add(this.domNode, "mblSwapView");
 			this.setSelectable(this.domNode, false);
 			this.containerNode = this.domNode;
-			connect.subscribe("/dojox/mobile/nextPage", this, "handleNextPage");
-			connect.subscribe("/dojox/mobile/prevPage", this, "handlePrevPage");
-			this.findAppBars();
+			this.subscribe("/dojox/mobile/nextPage", "handleNextPage");
+			this.subscribe("/dojox/mobile/prevPage", "handlePrevPage");
+			this.noResize = true; // not to call resize() from scrollable#init
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this.inherited(arguments);
 		},
 
 		resize: function(){
@@ -53,9 +64,13 @@ define([
 			});
 		},
 
-		onTouchStart: function(e){
+		onTouchStart: function(/*Event*/e){
 			// summary:
 			//		Internal function to handle touchStart events.
+			if(this._siblingViewsInMotion()){  // Ignore touchstart if the views are already in motion
+				this.propagatable ? e.preventDefault() : event.stop(e);
+				return;
+			}
 			var fromTop = this.domNode.offsetTop;
 			var nextView = this.nextView(this.domNode);
 			if(nextView){
@@ -71,6 +86,22 @@ define([
 				// Temporarily add padding to align with the fromNode while transition
 				prevView.containerNode.style.paddingTop = fromTop + "px";
 			}
+			this._setSiblingViewsInMotion(true);
+			this.inherited(arguments);
+		},
+
+		onTouchEnd: function(/*Event*/e){
+			if(e){
+				if(!this._fingerMovedSinceTouchStart()){ // No transition / animation following touchend in this case
+					this._setSiblingViewsInMotion(false);
+				}else{ // There might be a transition / animation following touchend
+					// As the webkitTransitionEndEvent is not always fired, make sure we call this._setSiblingViewsInMotion(false) even
+					// if the event is not fired (and onFlickAnimationEnd is not called as a result)
+					this._endOfTransitionTimeoutHandle = this.defer(function(){
+						this._setSiblingViewsInMotion(false);
+					}, 1000);
+				}
+			}
 			this.inherited(arguments);
 		},
 
@@ -92,27 +123,29 @@ define([
 			this.goTo(-1);
 		},
 
-		goTo: function(/*Number*/dir){
+		goTo: function(/*Number*/dir, /*String?*/moveTo){
 			// summary:
 			//		Moves to the next or previous view.
-			var w = this.domNode.offsetWidth;
-			var view = (dir == 1) ? this.nextView(this.domNode) : this.previousView(this.domNode);
-			if(!view){ return; }
-			view._beingFlipped = true;
-			view.scrollTo({x:w*dir});
-			view._beingFlipped = false;
-			view.domNode.style.display = "";
-			domClass.add(view.domNode, "mblIn");
-			this.slideTo({x:0}, 0.5, "ease-out", {x:-w*dir});
-		},
-
-		isSwapView: function(node){
+			var view = moveTo ? registry.byId(moveTo) :
+				((dir == 1) ? this.nextView(this.domNode) : this.previousView(this.domNode));
+			if(view && view !== this){
+				this.stopAnimation(); // clean-up animation states
+				view.stopAnimation();
+				this.domNode._isShowing = false; // update isShowing flag
+				view.domNode._isShowing = true;
+				this.performTransition(view.id, dir, "slide", null, function(){
+					connect.publish("/dojox/mobile/viewChanged", [view]);
+				});
+			}
+		},
+
+		isSwapView: function(/*DomNode*/node){
 			// summary:
 			//		Returns true if the given node is a SwapView widget.
 			return (node && node.nodeType === 1 && domClass.contains(node, "mblSwapView"));
 		},
 
-		nextView: function(node){
+		nextView: function(/*DomNode*/node){
 			// summary:
 			//		Returns the next view.
 			for(var n = node.nextSibling; n; n = n.nextSibling){
@@ -121,7 +154,7 @@ define([
 			return null;
 		},
 
-		previousView: function(node){
+		previousView: function(/*DomNode*/node){
 			// summary:
 			//		Returns the previous view.
 			for(var n = node.previousSibling; n; n = n.previousSibling){
@@ -132,18 +165,23 @@ define([
 
 		scrollTo: function(/*Object*/to){
 			// summary:
-			//		Overrides dojox.mobile.scrollable.scrollTo().
+			//		Overrides dojox/mobile/scrollable.scrollTo().
 			if(!this._beingFlipped){
 				var newView, x;
-				if(to.x < 0){
-					newView = this.nextView(this.domNode);
-					x = to.x + this.domNode.offsetWidth;
-				}else{
-					newView = this.previousView(this.domNode);
-					x = to.x - this.domNode.offsetWidth;
+				if(to.x){
+					if(to.x < 0){
+						newView = this.nextView(this.domNode);
+						x = to.x + this.domNode.offsetWidth;
+					}else{
+						newView = this.previousView(this.domNode);
+						x = to.x - this.domNode.offsetWidth;
+					}
 				}
 				if(newView){
-					newView.domNode.style.display = "";
+					if(newView.domNode.style.display === "none"){
+						newView.domNode.style.display = "";
+						newView.resize();
+					}
 					newView._beingFlipped = true;
 					newView.scrollTo({x:x});
 					newView._beingFlipped = false;
@@ -152,9 +190,32 @@ define([
 			this.inherited(arguments);
 		},
 
-		slideTo: function(/*Object*/to, /*Number*/duration, /*String*/easing, fake_pos){
+		findDisp: function(/*DomNode*/node){
+			// summary:
+			//		Overrides dojox/mobile/scrollable.findDisp().
+			// description:
+			//		When this function is called from scrollable.js, there are
+			//		two visible views, one is the current view, the other is the
+			//		next view. This function returns the current view, not the
+			//		next view, which has the mblIn class.
+			if(!domClass.contains(node, "mblSwapView")){
+				return this.inherited(arguments);
+			}
+			if(!node.parentNode){ return null; }
+			var nodes = node.parentNode.childNodes;
+			for(var i = 0; i < nodes.length; i++){
+				var n = nodes[i];
+				if(n.nodeType === 1 && domClass.contains(n, "mblSwapView")
+				    && !domClass.contains(n, "mblIn") && n.style.display !== "none"){
+					return n;
+				}
+			}
+			return node;
+		},
+
+		slideTo: function(/*Object*/to, /*Number*/duration, /*String*/easing, /*Object?*/fake_pos){
 			// summary:
-			//		Overrides dojox.mobile.scrollable.slideTo().
+			//		Overrides dojox/mobile/scrollable.slideTo().
 			if(!this._beingFlipped){
 				var w = this.domNode.offsetWidth;
 				var pos = fake_pos || this.getPos();
@@ -184,45 +245,75 @@ define([
 						}
 					}
 				}
-	
+
 				if(newView){
 					newView._beingFlipped = true;
 					newView.slideTo({x:newX}, duration, easing);
 					newView._beingFlipped = false;
-	
-					if(newX === 0){ // moving to another view
-						dojox.mobile.currentView = newView;
-					}
 					newView.domNode._isShowing = (newView && newX === 0);
 				}
 				this.domNode._isShowing = !(newView && newX === 0);
 			}
 			this.inherited(arguments);
 		},
-	
-		onFlickAnimationEnd: function(e){
+
+		onAnimationEnd: function(/*Event*/e){
 			// summary:
-			//		Overrides dojox.mobile.scrollable.onFlickAnimationEnd().
-			if(e && e.animationName && e.animationName !== "scrollableViewScroll2"){ return; }
-			// Hide all the views other than the currently showing one.
-			// Otherwise, when the orientation is changed, other views
-			// may appear unexpectedly.
-			var children = this.domNode.parentNode.childNodes;
-			for(var i = 0; i < children.length; i++){
-				var c = children[i];
-				if(this.isSwapView(c)){
-					domClass.remove(c, "mblIn");
-					if(!c._isShowing){
-						c.style.display = "none";
-					}
-				}
+			//		Overrides dojox/mobile/View.onAnimationEnd().
+			if(e && e.target && domClass.contains(e.target, "mblScrollableScrollTo2")){ return; }
+			this.inherited(arguments);
+		},
+
+		onFlickAnimationEnd: function(/*Event*/e){
+			if(this._endOfTransitionTimeoutHandle){
+				this._endOfTransitionTimeoutHandle = this._endOfTransitionTimeoutHandle.remove();
 			}
+			// summary:
+			//		Overrides dojox/mobile/scrollable.onFlickAnimationEnd().
+			if(e && e.target && !domClass.contains(e.target, "mblScrollableScrollTo2")){ return; }
 			this.inherited(arguments);
-			if(this.getShowingView() === this){
+
+			if(this.domNode._isShowing){
+				// Hide all the views other than the currently showing one.
+				// Otherwise, when the orientation is changed, other views
+				// may appear unexpectedly.
+				array.forEach(this.domNode.parentNode.childNodes, function(c){
+					if(this.isSwapView(c)){
+						domClass.remove(c, "mblIn");
+						if(!c._isShowing){
+							c.style.display = "none";
+							c.style[css3.name("transform")] = "";
+							c.style.left = "0px"; // top/left mode needs this
+							// reset the temporaty padding on the container node
+							c.style.paddingTop = "";
+						}
+					}
+				}, this);
 				connect.publish("/dojox/mobile/viewChanged", [this]);
 				// Reset the temporary padding
 				this.containerNode.style.paddingTop = "";
+			}else if(!has("css3-animations")){
+				this.containerNode.style.left = "0px"; // compat mode needs this
+			}
+			this._setSiblingViewsInMotion(false);
+		},
+
+		_setSiblingViewsInMotion: function(/*Boolean*/inMotion){
+			var inMotionAttributeValue = inMotion ? "true" : false;
+			var parent = this.domNode.parentNode;
+			if(parent){
+				parent.setAttribute("data-dojox-mobile-swapview-inmotion", inMotionAttributeValue);
+			}
+		},
+
+		_siblingViewsInMotion: function(){
+			var parent = this.domNode.parentNode;
+			if(parent){
+				return parent.getAttribute("data-dojox-mobile-swapview-inmotion") == "true";
+			}else{
+				return false;
 			}
 		}
 	});
+	return has("dojo-bidi") ? declare("dojox.mobile.SwapView", [SwapView, BidiSwapView]) : SwapView;
 });
diff --git a/dojox/mobile/Switch.js b/dojox/mobile/Switch.js
index f4b258e..64e797c 100644
--- a/dojox/mobile/Switch.js
+++ b/dojox/mobile/Switch.js
@@ -5,22 +5,22 @@ define([
 	"dojo/_base/event",
 	"dojo/_base/window",
 	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dojo/dom-attr",
+	"dojo/touch",
 	"dijit/_Contained",
 	"dijit/_WidgetBase",
-	"./sniff"
-], function(array, connect, declare, event, win, domClass, Contained, WidgetBase, has){
-
-/*=====
-	Contained = dijit._Contained;
-	WidgetBase = dijit._WidgetBase;
-=====*/
+	"./sniff", 
+	"./_maskUtils",
+	"./common",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/Switch"
+], function(array, connect, declare, event, win, domClass, domConstruct, domStyle, domAttr, touch, Contained, WidgetBase, has, maskUtils, dm, BidiSwitch){
 
 	// module:
 	//		dojox/mobile/Switch
-	// summary:
-	//		A toggle switch with a sliding knob.
 
-	return declare("dojox.mobile.Switch", [WidgetBase, Contained],{
+	var Switch = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiSwitch" : "dojox.mobile.Switch", [WidgetBase, Contained],{
 		// summary:
 		//		A toggle switch with a sliding knob.
 		// description:
@@ -29,7 +29,7 @@ define([
 		//		handler is called when the switch is manipulated.
 
 		// value: String
-		//		The initial state of the switch. "on" or "off". The default
+		//		The initial state of the switch: "on" or "off". The default
 		//		value is "on".
 		value: "on",
 
@@ -45,36 +45,82 @@ define([
 		//		The right-side label of the switch.
 		rightLabel: "OFF",
 
-		/* internal properties */	
-		_width: 53,
+		// shape: String
+		//		The shape of the switch.
+		//		"mblSwDefaultShape", "mblSwSquareShape", "mblSwRoundShape1",
+		//		"mblSwRoundShape2", "mblSwArcShape1" or "mblSwArcShape2".
+		//		The default value is "mblSwDefaultShape".
+		shape: "mblSwDefaultShape",
+
+		// tabIndex: String
+		//		Tabindex setting for this widget so users can hit the tab key to
+		//		focus on it.
+		tabIndex: "0",
+		_setTabIndexAttr: "", // sets tabIndex to domNode
+
+		/* internal properties */
+		baseClass: "mblSwitch",
+		// role: [private] String
+		//		The accessibility role.
+		role: "", // a11y
 
 		buildRendering: function(){
-			this.domNode = win.doc.createElement("DIV");
-			var c = (this.srcNodeRef && this.srcNodeRef.className) || this.className || this["class"];
-			this._swClass = (c || "").replace(/ .*/,"");
-			this.domNode.className = "mblSwitch";
-			var nameAttr = this.name ? " name=\"" + this.name + "\"" : "";
-			this.domNode.innerHTML =
-				  '<div class="mblSwitchInner">'
-				+	'<div class="mblSwitchBg mblSwitchBgLeft">'
-				+		'<div class="mblSwitchText mblSwitchTextLeft"></div>'
-				+	'</div>'
-				+	'<div class="mblSwitchBg mblSwitchBgRight">'
-				+		'<div class="mblSwitchText mblSwitchTextRight"></div>'
-				+	'</div>'
-				+	'<div class="mblSwitchKnob"></div>'
-				+	'<input type="hidden"'+nameAttr+'></div>'
-				+ '</div>';
-			var n = this.inner = this.domNode.firstChild;
-			this.left = n.childNodes[0];
-			this.right = n.childNodes[1];
-			this.knob = n.childNodes[2];
-			this.input = n.childNodes[3];
+			if(!this.templateString){ // true if this widget is not templated
+				this.domNode = (this.srcNodeRef && this.srcNodeRef.tagName === "SPAN") ?
+					this.srcNodeRef : domConstruct.create("span");
+			}
+			// prevent browser scrolling on IE10 (evt.preventDefault() is not enough)
+			if(typeof this.domNode.style.msTouchAction != "undefined"){
+				this.domNode.style.msTouchAction = "none";
+			}
+			this.inherited(arguments);
+			if(!this.templateString){ // true if this widget is not templated
+				var c = (this.srcNodeRef && this.srcNodeRef.className) || this.className || this["class"];
+				if((c = c.match(/mblSw.*Shape\d*/))){ this.shape = c; }
+				domClass.add(this.domNode, this.shape);
+				var nameAttr = this.name ? " name=\"" + this.name + "\"" : "";
+				this.domNode.innerHTML =
+					  '<div class="mblSwitchInner">'
+					+	'<div class="mblSwitchBg mblSwitchBgLeft">'
+					+		'<div class="mblSwitchText mblSwitchTextLeft"></div>'
+					+	'</div>'
+					+	'<div class="mblSwitchBg mblSwitchBgRight">'
+					+		'<div class="mblSwitchText mblSwitchTextRight"></div>'
+					+	'</div>'
+					+	'<div class="mblSwitchKnob"></div>'
+					+	'<input type="hidden"'+nameAttr+'></div>'
+					+ '</div>';
+				var n = this.inner = this.domNode.firstChild;
+				this.left = n.childNodes[0];
+				this.right = n.childNodes[1];
+				this.knob = n.childNodes[2];
+				this.input = n.childNodes[3];
+			}
+			domAttr.set(this.domNode, "role", "checkbox"); //a11y
+			domAttr.set(this.domNode, "aria-checked", (this.value === "on") ? "true" : "false"); //a11y
+
+			this.switchNode = this.domNode;
+
+			if(has("windows-theme")) {
+				var rootNode = domConstruct.create("div", {className: "mblSwitchContainer"});
+				this.labelNode = domConstruct.create("label", {"class": "mblSwitchLabel", "for": this.id}, rootNode);
+				rootNode.appendChild(this.domNode.cloneNode(true));
+				this.domNode = rootNode;
+				this.focusNode = rootNode.childNodes[1];
+				this.labelNode.innerHTML = (this.value=="off") ? this.rightLabel : this.leftLabel;
+				this.switchNode = this.domNode.childNodes[1];
+				var inner = this.inner = this.domNode.childNodes[1].firstChild;
+				this.left = inner.childNodes[0];
+				this.right = inner.childNodes[1];
+				this.knob = inner.childNodes[2];
+				this.input = inner.childNodes[3];
+			}
 		},
 
 		postCreate: function(){
-			this.connect(this.domNode, "onclick", "onClick");
-			this.connect(this.domNode, has('touch') ? "touchstart" : "onmousedown", "onTouchStart");
+			this.connect(this.switchNode, "onclick", "_onClick");
+			this.connect(this.switchNode, "onkeydown", "_onClick"); // for desktop browsers
+			this._startHandle = this.connect(this.switchNode, touch.press, "onTouchStart");
 			this._initialValue = this.value; // for reset()
 		},
 
@@ -84,75 +130,93 @@ define([
 			this.right.style.display = "";
 			this.inner.style.left = "";
 			if(anim){
-				domClass.add(this.domNode, "mblSwitchAnimation");
+				domClass.add(this.switchNode, "mblSwitchAnimation");
 			}
-			domClass.remove(this.domNode, on ? "mblSwitchOff" : "mblSwitchOn");
-			domClass.add(this.domNode, on ? "mblSwitchOn" : "mblSwitchOff");
-	
+			domClass.remove(this.switchNode, on ? "mblSwitchOff" : "mblSwitchOn");
+			domClass.add(this.switchNode, on ? "mblSwitchOn" : "mblSwitchOff");
+			domAttr.set(this.switchNode, "aria-checked", on ? "true" : "false"); //a11y
+
 			var _this = this;
-			setTimeout(function(){
+			_this.defer(function(){
 				_this.left.style.display = on ? "" : "none";
 				_this.right.style.display = !on ? "" : "none";
-				domClass.remove(_this.domNode, "mblSwitchAnimation");
+				domClass.remove(_this.switchNode, "mblSwitchAnimation");
 			}, anim ? 300 : 0);
 		},
 
-		startup: function(){
-			if(this._swClass.indexOf("Round") != -1){
-				var r = Math.round(this.domNode.offsetHeight / 2);
-				this.createRoundMask(this._swClass, r, this.domNode.offsetWidth);
+		_createMaskImage: function(){
+			if(this._timer){
+				 this._timer.remove();
+				 delete this._timer;
 			}
+			if(this._hasMaskImage){ return; }
+			this._width = this.switchNode.offsetWidth - this.knob.offsetWidth;
+			this._hasMaskImage = true;
+			if(!(has("webkit")||has("svg"))){ return; }
+			var rDef = domStyle.get(this.left, "borderTopLeftRadius");
+			if(rDef == "0px"){ return; }
+			var rDefs = rDef.split(" ");
+			var rx = parseFloat(rDefs[0]), ry = (rDefs.length == 1) ? rx : parseFloat(rDefs[1]);
+			var w = this.switchNode.offsetWidth, h = this.switchNode.offsetHeight;
+			var id = (this.shape+"Mask"+w+h+rx+ry).replace(/\./,"_");
+			
+			maskUtils.createRoundMask(this.switchNode, 0, 0, 0, 0, w, h, rx, ry, 1);
 		},
-	
-		createRoundMask: function(className, r, w){
-			if(!has("webkit") || !className){ return; }
-			if(!this._createdMasks){ this._createdMasks = []; }
-			if(this._createdMasks[className]){ return; }
-			this._createdMasks[className] = 1;
-	
-			var ctx = win.doc.getCSSCanvasContext("2d", className+"Mask", w, 100);
-			ctx.fillStyle = "#000000";
-			ctx.beginPath();
-			ctx.moveTo(r, 0);
-			ctx.arcTo(0, 0, 0, 2*r, r);
-			ctx.arcTo(0, 2*r, r, 2*r, r);
-			ctx.lineTo(w - r, 2*r);
-			ctx.arcTo(w, 2*r, w, r, r);
-			ctx.arcTo(w, 0, w - r, 0, r);
-			ctx.closePath();
-			ctx.fill();
-		},
-	
-		onClick: function(e){
+		
+		_onClick: function(e){
+			// summary:
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
+			if(this.onClick(e) === false){ return; } // user's click action
 			if(this._moved){ return; }
 			this.value = this.input.value = (this.value == "on") ? "off" : "on";
 			this._changeState(this.value, true);
 			this.onStateChanged(this.value);
 		},
-	
-		onTouchStart: function(e){
+
+		onClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User defined function to handle clicks
+			// tags:
+			//		callback
+		},
+
+		onTouchStart: function(/*Event*/e){
 			// summary:
 			//		Internal function to handle touchStart events.
 			this._moved = false;
 			this.innerStartX = this.inner.offsetLeft;
 			if(!this._conn){
-				this._conn = [];
-				this._conn.push(connect.connect(this.inner, has('touch') ? "touchmove" : "onmousemove", this, "onTouchMove"));
-				this._conn.push(connect.connect(this.inner, has('touch') ? "touchend" : "onmouseup", this, "onTouchEnd"));
+				this._conn = [
+					this.connect(this.inner, touch.move, "onTouchMove"),
+					this.connect(win.doc, touch.release, "onTouchEnd")
+				];
+
+				/* While moving the slider knob sometimes IE fires MSPointerCancel event. That prevents firing
+				MSPointerUP event (http://msdn.microsoft.com/ru-ru/library/ie/hh846776%28v=vs.85%29.aspx) so the
+				knob can be stuck in the middle of the switch. As a fix we handle MSPointerCancel event with the
+				same lintener as for MSPointerUp event.
+				*/
+				if(has("windows-theme")){
+					this._conn.push(this.connect(win.doc, "MSPointerCancel", "onTouchEnd"));
+				}
 			}
 			this.touchStartX = e.touches ? e.touches[0].pageX : e.clientX;
 			this.left.style.display = "";
 			this.right.style.display = "";
 			event.stop(e);
+			this._createMaskImage();
 		},
-	
-		onTouchMove: function(e){
+
+		onTouchMove: function(/*Event*/e){
 			// summary:
 			//		Internal function to handle touchMove events.
 			e.preventDefault();
 			var dx;
 			if(e.targetTouches){
-				if(e.targetTouches.length != 1){ return false; }
+				if(e.targetTouches.length != 1){ return; }
 				dx = e.targetTouches[0].clientX - this.touchStartX;
 			}else{
 				dx = e.clientX - this.touchStartX;
@@ -166,35 +230,40 @@ define([
 				this._moved = true;
 			}
 		},
-	
-		onTouchEnd: function(e){
+
+		onTouchEnd: function(/*Event*/e){
 			// summary:
 			//		Internal function to handle touchEnd events.
 			array.forEach(this._conn, connect.disconnect);
 			this._conn = null;
 			if(this.innerStartX == this.inner.offsetLeft){
-				if(has('touch')){
-					var ev = win.doc.createEvent("MouseEvents");
-					ev.initEvent("click", true, true);
-					this.inner.dispatchEvent(ev);
+				// need to send a synthetic click?
+				if(has("touch") && has("clicks-prevented")){
+					dm._sendClick(this.inner, e);
 				}
 				return;
 			}
 			var newState = (this.inner.offsetLeft < -(this._width/2)) ? "off" : "on";
+			newState = this._newState(newState);
 			this._changeState(newState, true);
 			if(newState != this.value){
 				this.value = this.input.value = newState;
 				this.onStateChanged(newState);
 			}
 		},
-	
+		_newState: function(newState){
+			return newState;
+		},
 		onStateChanged: function(/*String*/newState){
 			// summary:
 			//		Stub function to connect to from your application.
 			// description:
 			//		Called when the state has been changed.
+			if (this.labelNode) {
+				this.labelNode.innerHTML = newState=='off' ? this.rightLabel : this.leftLabel;
+			}
 		},
-	
+
 		_setValueAttr: function(/*String*/value){
 			this._changeState(value, false);
 			if(this.value != value){
@@ -202,12 +271,12 @@ define([
 			}
 			this.value = this.input.value = value;
 		},
-	
+
 		_setLeftLabelAttr: function(/*String*/label){
 			this.leftLabel = label;
 			this.left.firstChild.innerHTML = this._cv ? this._cv(label) : label;
 		},
-	
+
 		_setRightLabelAttr: function(/*String*/label){
 			this.rightLabel = label;
 			this.right.firstChild.innerHTML = this._cv ? this._cv(label) : label;
@@ -219,4 +288,6 @@ define([
 			this.set("value", this._initialValue);
 		}
 	});
+
+	return has("dojo-bidi") ? declare("dojox.mobile.Switch", [Switch, BidiSwitch]) : Switch;		
 });
diff --git a/dojox/mobile/TabBar.js b/dojox/mobile/TabBar.js
index 6d719d8..fdd5598 100644
--- a/dojox/mobile/TabBar.js
+++ b/dojox/mobile/TabBar.js
@@ -1,29 +1,24 @@
 define([
 	"dojo/_base/array",
 	"dojo/_base/declare",
+	"dojo/_base/window",
 	"dojo/dom-class",
 	"dojo/dom-construct",
 	"dojo/dom-geometry",
 	"dojo/dom-style",
+	"dojo/dom-attr",
 	"dijit/_Contained",
 	"dijit/_Container",
 	"dijit/_WidgetBase",
-	"./Heading",
-	"./TabBarButton"
-], function(array, declare, domClass, domConstruct, domGeometry, domStyle, Contained, Container, WidgetBase, Heading, TabBarButton){
-
-/*=====
-	var Contained = dijit._Contained;
-	var Container = dijit._Container;
-	var WidgetBase = dijit._WidgetBase;
-=====*/
+	"./TabBarButton",// to load TabBarButton for you (no direct references)
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/TabBar"	
+], function(array, declare, win, domClass, domConstruct, domGeometry, domStyle, domAttr, Contained, Container, WidgetBase, TabBarButton, has, BidiTabBar){
 
 	// module:
 	//		dojox/mobile/TabBar
-	// summary:
-	//		A bar widget that has buttons to control visibility of views.
 
-	return declare("dojox.mobile.TabBar", [WidgetBase, Container, Contained],{
+	var TabBar =  declare(has("dojo-bidi") ? "dojox.mobile.NonBidiTabBar" : "dojox.mobile.TabBar", [WidgetBase, Container, Contained],{
 		// summary:
 		//		A bar widget that has buttons to control visibility of views.
 		// description:
@@ -40,27 +35,65 @@ define([
 		iconPos: "",
 
 		// barType: String
-		//		"tabBar"(default) or "segmentedControl".
+		//		"tabBar", "segmentedControl", "standardTab", "slimTab", "flatTab",
+		//		or "tallTab"
 		barType: "tabBar",
 
-		// inHeading: Boolean
-		//		A flag that indicates whether this widget is in a Heading
-		//		widget.
-		inHeading: false,
+		// closable: Boolean
+		//		If true, user can close (destroy) a child tab by clicking the X on the tab.
+		//		This property is NOT effective for "tabBar" and "tallBar".
+		closable: false,
+
+		// center: Boolean
+		//		If true, place the tabs in the center of the bar.
+		//		This property is NOT effective for "tabBar".
+		center: true,
+
+		// syncWithViews: Boolean
+		//		If true, this widget listens to view transition events to be
+		//		synchronized with view's visibility.
+		syncWithViews: false,
 
 		// tag: String
 		//		A name of html tag to create as domNode.
-		tag: "UL",
+		tag: "ul",
 
-		/* internal properties */	
+		// fill: String
+		//		Define if the TabBar should resize its children so that they evenly fill all the available space in the bar.
+		//
+		//		Allowed values:
+		//
+		//		1. "auto" is the default behavior from version 1.8: bar buttons are resized to evenly fill the entire bar only on small devices (width < 500px) and when barType is "tabBar"
+		//		2. "always": bar buttons are always resized to evenly fill the entire bar
+		//		3. "never": bar buttons are never resized to evenly fill the entire bar
+		fill: "auto",
+
+		/* internal properties */
+		// selectOne: [private] Boolean
+		//		Specifies that only one item can be selected.
+		selectOne: true,
+		baseClass: "mblTabBar",
 		_fixedButtonWidth: 76,
 		_fixedButtonMargin: 17,
 		_largeScreenWidth: 500,
 
 		buildRendering: function(){
-			this._clsName = this.barType == "segmentedControl" ? "mblTabButton" : "mblTabBarButton";
-			this.domNode = this.containerNode = this.srcNodeRef || domConstruct.create(this.tag);
-			this.domNode.className = this.barType == "segmentedControl" ? "mblTabPanelHeader" : "mblTabBar";
+			this.domNode = this.srcNodeRef || domConstruct.create(this.tag);
+			domAttr.set(this.domNode, "role", "tablist");
+			this.reset();
+			this.inherited(arguments);
+		},
+
+		postCreate: function(){
+			if(this.syncWithViews){ // see also RoundRect#postCreate
+				var f = function(view, moveTo, dir, transition, context, method){
+					var child = array.filter(this.getChildren(), function(w){
+						return w.moveTo === "#" + view.id || w.moveTo === view.id; })[0];
+					if(child){ child.set("selected", true); }
+				};
+				this.subscribe("/dojox/mobile/afterTransitionIn", f);
+				this.subscribe("/dojox/mobile/startView", f);
+			}
 		},
 
 		startup: function(){
@@ -69,60 +102,56 @@ define([
 			this.resize();
 		},
 
+		reset: function(){
+			// summary:
+			//		Resets the widget to its initial state.
+			var prev = this._barType;
+			if(typeof this.barType === "object"){
+				this._barType = this.barType["*"];
+				for(var c in this.barType){
+					if(domClass.contains(win.doc.documentElement, c)){
+						this._barType = this.barType[c];
+						break;
+					}
+				}
+			}else{
+				this._barType = this.barType;
+			}
+			var cap = function(s){
+				return s.charAt(0).toUpperCase() + s.substring(1);
+			};
+			if(prev){
+				domClass.remove(this.domNode, this.baseClass + cap(prev));
+			}
+			domClass.add(this.domNode, this.baseClass + cap(this._barType));
+		},
+
 		resize: function(size){
-			var i,w;
+			var i, w;
 			if(size && size.w){
-				domGeometry.setMarginBox(this.domNode, size);
 				w = size.w;
 			}else{
-				// Calculation of the bar width varies according to its "position" value.
-				// When the widget is used as a fixed bar, its position would be "absolute".
-				w = domStyle.get(this.domNode, "position") === "absolute" ?
-					domGeometry.getContentBox(this.domNode).w : domGeometry.getMarginBox(this.domNode).w;
+				w = domGeometry.getMarginBox(this.domNode).w;
 			}
 			var bw = this._fixedButtonWidth;
 			var bm = this._fixedButtonMargin;
-	
-			var children = this.containerNode.childNodes;
-			var arr = [];
-			for(i = 0; i < children.length; i++){
-				var c = children[i];
-				if(c.nodeType != 1){ continue; }
-				if(domClass.contains(c, this._clsName)){
-					arr.push(c);
-				}
-			}
-	
-			var margin;
-			if(this.barType == "segmentedControl"){
-				margin = w;
-				var totalW = 0; // total width of all the buttons
-				for(i = 0; i < arr.length; i++){
-					margin -= domGeometry.getMarginBox(arr[i]).w;
-					totalW += arr[i].offsetWidth;
-				}
-				margin = Math.floor(margin/2);
-				var parent = this.getParent();
-				var inHeading = this.inHeading || parent instanceof Heading;
-				this.containerNode.style.padding = (inHeading ? 0 : 3) + "px 0px 0px " + (inHeading ? 0 : margin) + "px";
-				if(inHeading){
-					domStyle.set(this.domNode, {
-						background: "none",
-						border: "none",
-						width: totalW + 2 + "px"
-					});
-				}
-				domClass.add(this.domNode, "mblTabBar" + (inHeading ? "Head" : "Top"));
-			}else{
+			var arr = array.map(this.getChildren(), function(w){ return w.domNode; });
+
+			domClass.toggle(this.domNode, "mblTabBarNoIcons",
+							!array.some(this.getChildren(), function(w){ return w.iconNode1; }));
+			domClass.toggle(this.domNode, "mblTabBarNoText",
+							!array.some(this.getChildren(), function(w){ return w.label; }));
+
+			var margin = 0;
+			if(this._barType == "tabBar"){
+				this.containerNode.style.paddingLeft = "";
 				margin = Math.floor((w - (bw + bm * 2) * arr.length) / 2);
-				if(w < this._largeScreenWidth || margin < 0){
-					// If # of buttons is 4, for example, assign "25%" to each button.
-					// More precisely, 1%(left margin) + 98%(bar width) + 1%(right margin)
+				if(this.fill == "always" || (this.fill == "auto" && (w < this._largeScreenWidth || margin < 0))){
+					domClass.add(this.domNode, "mblTabBarFill");
 					for(i = 0; i < arr.length; i++){
-						arr[i].style.width = Math.round(98/arr.length) + "%";
-						arr[i].style.margin = "0px";
+						arr[i].style.width = (100/arr.length) + "%";
+						arr[i].style.margin = "0";
 					}
-					this.containerNode.style.padding = "0px 0px 0px 1%";
 				}else{
 					// Fixed width buttons. Mainly for larger screen such as iPad.
 					for(i = 0; i < arr.length; i++){
@@ -130,24 +159,60 @@ define([
 						arr[i].style.margin = "0 " + bm + "px";
 					}
 					if(arr.length > 0){
-						arr[0].style.marginLeft = margin + bm + "px";
+						if(has("dojo-bidi") && !this.isLeftToRight()){
+							arr[0].style.marginLeft = "0px";
+							arr[0].style.marginRight = margin + bm + "px";
+						}else{
+							arr[0].style.marginLeft = margin + bm + "px";
+						}
 					}
 					this.containerNode.style.padding = "0px";
 				}
-			}
-
-			if(!array.some(this.getChildren(), function(child){ return child.iconNode1; })){
-				domClass.add(this.domNode, "mblTabBarNoIcons");
 			}else{
-				domClass.remove(this.domNode, "mblTabBarNoIcons");
+				for(i = 0; i < arr.length; i++){
+					arr[i].style.width = arr[i].style.margin = "";
+				}
+				var parent = this.getParent();
+				if(this.fill == "always"){
+					domClass.add(this.domNode, "mblTabBarFill");
+					for(i = 0; i < arr.length; i++){
+						arr[i].style.width = (100/arr.length) + "%";
+						if(this._barType != "segmentedControl" && this._barType != "standardTab") {
+							arr[i].style.margin = "0";
+						}
+					}
+				}else{
+					if(this.center && (!parent || !domClass.contains(parent.domNode, "mblHeading"))){
+						margin = w;
+						for(i = 0; i < arr.length; i++){
+							margin -= domGeometry.getMarginBox(arr[i]).w;
+						}
+						margin = Math.floor(margin/2);
+					}
+					if(has("dojo-bidi") && !this.isLeftToRight()){
+						this.containerNode.style.paddingLeft = "0px";
+						this.containerNode.style.paddingRight = margin ? margin + "px" : "";
+					}else{
+						this.containerNode.style.paddingLeft = margin ? margin + "px" : "";
+					}
+				}
 			}
-
-			if(!array.some(this.getChildren(), function(child){ return child.label; })){
-				domClass.add(this.domNode, "mblTabBarNoText");
-			}else{
-				domClass.remove(this.domNode, "mblTabBarNoText");
+			if(size && size.w){
+				domGeometry.setMarginBox(this.domNode, size);
 			}
+		},
+		getSelectedTab: function(){
+			// summary:
+			//		Returns the first selected child.
+			return array.filter(this.getChildren(), function(w){ return w.selected; })[0];
+		},
+
+		onCloseButtonClick: function(/*TabBarButton*/tab){
+			// summary:
+			//		Called whenever the close button [X] of a child tab is clicked.
+			return true;
 		}
 	});
-
+	
+	return has("dojo-bidi")?declare("dojox.mobile.TabBar", [TabBar, BidiTabBar]):TabBar;	
 });
diff --git a/dojox/mobile/TabBarButton.js b/dojox/mobile/TabBarButton.js
index aef79fe..8660086 100644
--- a/dojox/mobile/TabBarButton.js
+++ b/dojox/mobile/TabBarButton.js
@@ -1,29 +1,30 @@
 define([
+	"dojo/_base/connect",
 	"dojo/_base/declare",
+	"dojo/_base/event",
 	"dojo/_base/lang",
-	"dojo/_base/window",
+	"dojo/dom",
 	"dojo/dom-class",
 	"dojo/dom-construct",
-	"dijit/registry",	// registry.byNode
-	"./common",
-	"./_ItemBase"
-], function(declare, lang, win, domClass, domConstruct, registry, common, ItemBase){
-
-/*=====
-	var ItemBase = dojox.mobile._ItemBase;
-=====*/
+	"dojo/dom-style",
+	"dojo/dom-attr",
+	"./View",
+	"./iconUtils",
+	"./_ItemBase",
+	"./Badge",
+	"./sniff",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/TabBarButton"
+], function(connect, declare, event, lang, dom, domClass, domConstruct, domStyle, domAttr, View, iconUtils, ItemBase, Badge, has, BidiTabBarButton){
 
 	// module:
 	//		dojox/mobile/TabBarButton
-	// summary:
-	//		A button widget that is placed in the TabBar widget.
 
-	return declare("dojox.mobile.TabBarButton", ItemBase,{
+	var TabBarButton = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiTabBarButton" : "dojox.mobile.TabBarButton", ItemBase,{
 		// summary:
 		//		A button widget that is placed in the TabBar widget.
 		// description:
 		//		TabBarButton is a button that is placed in the TabBar widget. It
-		//		is a subclass of dojox.mobile._ItemBase just like ListItem or
+		//		is a subclass of dojox/mobile/_ItemBase just like ListItem or
 		//		IconItem. So, unlike Button, it has similar capability as
 		//		ListItem or IconItem, such as icon support, transition, etc.
 
@@ -40,21 +41,21 @@ define([
 
 		// iconPos1: String
 		//		The position of an aggregated unselected (typically dark)
-		//		icon. IconPos1 is comma separated values like
+		//		icon. IconPos1 is a comma-separated list of values like
 		//		top,left,width,height (ex. "0,0,29,29"). If iconPos1 is not
 		//		specified, the iconPos parameter of the parent widget is used.
 		iconPos1: "",
 
 		// iconPos2: String
 		//		The position of an aggregated selected (typically highlight)
-		//		icon. IconPos2 is comma separated values like
+		//		icon. IconPos2 is a comma-separated list of values like
 		//		top,left,width,height (ex. "0,0,29,29"). If iconPos2 is not
 		//		specified, the iconPos parameter of the parent widget or
 		//		iconPos1 is used.
 		iconPos2: "",
 
 		// selected: Boolean
-		//		If true, the button is in the selected status.
+		//		If true, the button is in the selected state.
 		selected: false,
 
 		// transition: String
@@ -63,15 +64,35 @@ define([
 
 		// tag: String
 		//		A name of html tag to create as domNode.
-		tag: "LI",
+		tag: "li",
+
+		// badge: String
+		//		A string to show on a badge. (ex. "12")
+		badge: "",
 
 		/* internal properties */	
-		selectOne: true,
+		baseClass: "mblTabBarButton",
+		// closeIcon: [private] String
+		//		CSS class for the close icon.
+		closeIcon: "mblDomButtonWhiteCross",
+
+		_selStartMethod: "touch",
+		_selEndMethod: "touch",
+		
+		// _moveTo: String
+		//		id of destination view
+		_moveTo: "",
+
+		destroy: function(){
+			if(this.badgeObj){
+				delete this.badgeObj;
+			}
+			this.inherited(arguments);
+		},
 
-	
 		inheritParams: function(){
 			// summary:
-			//		Overrides dojox.mobile._ItemBase.inheritParams().
+			//		Overrides dojox/mobile/_ItemBase.inheritParams().
 			if(this.icon && !this.icon1){ this.icon1 = this.icon; }
 			var parent = this.getParent();
 			if(parent){
@@ -88,144 +109,194 @@ define([
 				}
 				if(!this.icon2){ this.icon2 = parent.iconBase || this.icon1; }
 				if(!this.iconPos2){ this.iconPos2 = parent.iconPos || this.iconPos1; }
-			}
-		},
-	
-		buildRendering: function(){
-			var a = this.anchorNode = domConstruct.create("A", {className:"mblTabBarButtonAnchor"});
-			this.connect(a, "onclick", "onClick");
-	
-			this.box = domConstruct.create("DIV", {className:"mblTabBarButtonTextBox"}, a);
-			var box = this.box;
-			var label = "";
-			var r = this.srcNodeRef;
-			if(r){
-				for(var i = 0, len = r.childNodes.length; i < len; i++){
-					var n = r.firstChild;
-					if(n.nodeType === 3){
-						label += lang.trim(n.nodeValue);
+
+				if(parent.closable){
+					if(!this.icon1){
+						this.icon1 = this.closeIcon;
 					}
-					box.appendChild(n);
+					if(!this.icon2){
+						this.icon2 = this.closeIcon;
+					}
+					domClass.add(this.domNode, "mblTabBarButtonClosable");
 				}
 			}
-			if(!this.label){
-				this.label = label;
-			}
-	
+		},
+
+		buildRendering: function(){
 			this.domNode = this.srcNodeRef || domConstruct.create(this.tag);
-			this.containerNode = this.domNode;
-			this.domNode.appendChild(a);
-			if(this.domNode.className.indexOf("mblDomButton") != -1){
-				// deprecated. TODO: remove this code in 1.8
-				var domBtn = domConstruct.create("DIV", null, a);
-				common.createDomButton(this.domNode, null, domBtn);
-				domClass.add(this.domNode, "mblTabButtonDomButton");
-				domClass.add(domBtn, "mblTabButtonDomButtonClass");
+			if(this.srcNodeRef){
+				if(!this.label){
+					this.label = lang.trim(this.srcNodeRef.innerHTML);
+				}
+				this.srcNodeRef.innerHTML = "";
 			}
-			if((this.icon1 || this.icon).indexOf("mblDomButton") != -1){
-				domClass.add(this.domNode, "mblTabButtonDomButton");
+
+			this.labelNode = this.box = domConstruct.create("div", {className:"mblTabBarButtonLabel"}, this.domNode);
+			
+			domAttr.set(this.domNode, "role", "tab");
+			domAttr.set(this.domNode, "aria-selected", "false");
+			this._moveTo = this._getMoveToId();
+			if(this._moveTo){
+				var tabPanelNode = dom.byId(this._moveTo);
+				if(tabPanelNode){
+					domAttr.set(this.domNode, "aria-controls", this._moveTo);
+					domAttr.set(tabPanelNode, "role", "tabpanel");
+					domAttr.set(tabPanelNode, "aria-labelledby", this.id);
+				}
 			}
+			
+			this.inherited(arguments);
 		},
-	
+
 		startup: function(){
 			if(this._started){ return; }
-			this.inheritParams();
+
+			this._dragstartHandle = this.connect(this.domNode, "ondragstart", event.stop);
+			this.connect(this.domNode, "onkeydown", "_onClick"); // for desktop browsers
 			var parent = this.getParent();
-	
-			var _clsName = parent ? parent._clsName : "mblTabBarButton";
-			domClass.add(this.domNode, _clsName + (this.selected ? " mblTabButtonSelected" : ""));
-	
-			if(parent && parent.barType == "segmentedControl"){
-				// proper className may not be set when created dynamically
-				domClass.remove(this.domNode, "mblTabBarButton");
-				domClass.add(this.domNode, parent._clsName);
-				this.box.className = "";
+			if(parent && parent.closable){
+				this._clickCloseHandler = this.connect(this.iconDivNode, "onclick", "_onCloseButtonClick");
+				this._keydownCloseHandler = this.connect(this.iconDivNode, "onkeydown", "_onCloseButtonClick"); // for desktop browsers
+				this.iconDivNode.tabIndex = "0";
 			}
-			this.set({icon1:this.icon1, icon2:this.icon2});
+
 			this.inherited(arguments);
+			if(!this._isOnLine){
+				this._isOnLine = true;
+				// retry applying the attribute for which the custom setter delays the actual 
+				// work until _isOnLine is true. 
+				this.set({
+					icon: this._pendingIcon !== undefined ? this._pendingIcon : this.icon,
+					icon1:this.icon1,
+					icon2:this.icon2});
+				// Not needed anymore (this code executes only once per life cycle):
+				delete this._pendingIcon; 
+			}
+			dom.setSelectable(this.domNode, false);
 		},
-	
-		select: function(){
+
+		onClose: function(e){
 			// summary:
-			//		Makes this widget in the selected state.
-			if(arguments[0]){ // deselect
-				this.selected = false;
-				domClass.remove(this.domNode, "mblTabButtonSelected");
-			}else{ // select
-				this.selected = true;
-				domClass.add(this.domNode, "mblTabButtonSelected");
-				for(var i = 0, c = this.domNode.parentNode.childNodes; i < c.length; i++){
-					if(c[i].nodeType != 1){ continue; }
-					var w = registry.byNode(c[i]); // sibling widget
-					if(w && w != this){
-						w.deselect();
-					}
-				}
-			}
-			if(this.iconNode1){
-				this.iconNode1.style.visibility = this.selected ? "hidden" : "";
-			}
-			if(this.iconNode2){
-				this.iconNode2.style.visibility = this.selected ? "" : "hidden";
+			//		Called when the parent is a dojox/mobile/TabBar whose closable property is true, and the user clicked the close button.
+			connect.publish("/dojox/mobile/tabClose", [this]);
+			return this.getParent().onCloseButtonClick(this);
+		},
+
+		_onCloseButtonClick: function(e){
+			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
+			if(this.onCloseButtonClick(e) === false){ return; } // user's click action
+			if(this.onClose()){
+				this.destroy();
 			}
 		},
-		
-		deselect: function(){
+
+		onCloseButtonClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User defined function to handle clicks
+			//		when the parent is a dojox/mobile/TabBar whose closable property is true.
+			// tags:
+			//		callback
+		},
+
+		_onClick: function(e){
 			// summary:
-			//		Makes this widget in the deselected state.
-			this.select(true);
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
+			if(this.onClick(e) === false){ return; } // user's click action
+			this.defaultClickAction(e);
 		},
-	
-		onClick: function(e){
-			this.defaultClickAction();
+
+		onClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User defined function to handle clicks
+			// tags:
+			//		callback
 		},
-	
-		_setIcon: function(icon, pos, num, sel){
-			var i = "icon" + num, n = "iconNode" + num, p = "iconPos" + num;
-			if(icon){ this[i] = icon; }
-			if(pos){
-				if(this[p] === pos){ return; }
-				this[p] = pos;
+
+		_setIcon: function(icon, n){
+			if(!this.getParent()){ return; } // icon may be invalid because inheritParams is not called yet
+			this._set("icon" + n, icon);
+			if(!this.iconDivNode){
+				this.iconDivNode = domConstruct.create("div", {className:"mblTabBarButtonIconArea"}, this.domNode, "first");
+				// mblTabBarButtonDiv -> mblTabBarButtonIconArea
 			}
-			if(icon && icon !== "none"){
-				if(!this.iconDivNode){
-					this.iconDivNode = domConstruct.create("DIV", {className:"mblTabBarButtonDiv"}, this.anchorNode, "first");
-				}
-				if(!this[n]){
-					this[n] = domConstruct.create("div", {className:"mblTabBarButtonIcon"}, this.iconDivNode);
+			if(!this["iconParentNode" + n]){
+				this["iconParentNode" + n] = domConstruct.create("div", {className:"mblTabBarButtonIconParent mblTabBarButtonIconParent" + n}, this.iconDivNode);
+				// mblTabBarButtonIcon -> mblTabBarButtonIconParent
+			}
+			this["iconNode" + n] = iconUtils.setIcon(icon, this["iconPos" + n],
+				this["iconNode" + n], this.alt, this["iconParentNode" + n]);
+			this["icon" + n] = icon;
+			domClass.toggle(this.domNode, "mblTabBarButtonHasIcon", icon && icon !== "none");
+		},
+		
+		_getMoveToId: function(){
+			// summary:
+			//		Return the id of the destination view.
+			//		If there is no id, return an empty string.
+			if(this.moveTo){
+				if(this.moveTo === "#"){ return ""; }
+				var toId = "";
+				if(typeof(this.moveTo) === "object" && this.moveTo.moveTo){
+					toId = this.moveTo.moveTo;
 				}else{
-					domConstruct.empty(this[n]);
+					toId = this.moveTo;
 				}
-				common.createIcon(icon, this[p], null, this.alt, this[n]);
-				if(this[p]){
-					domClass.add(this[n].firstChild, "mblTabBarButtonSpriteIcon");
+				if(toId){
+					toId = View.prototype.convertToId(toId);
 				}
-				domClass.remove(this.iconDivNode, "mblTabBarButtonNoIcon");
-				this[n].style.visibility = sel ? "hidden" : "";
-			}else if(this.iconDivNode){
-				domClass.add(this.iconDivNode, "mblTabBarButtonNoIcon");
+				return toId;
 			}
 		},
-	
+
 		_setIcon1Attr: function(icon){
-			this._setIcon(icon, null, 1, this.selected);
+			this._setIcon(icon, 1);
 		},
-	
+
 		_setIcon2Attr: function(icon){
-			this._setIcon(icon, null, 2, !this.selected);
+			this._setIcon(icon, 2);
 		},
-	
-		_setIconPos1Attr: function(pos){
-			this._setIcon(null, pos, 1, this.selected);
+
+		_getBadgeAttr: function(){
+			return this.badgeObj && this.badgeObj.domNode.parentNode &&
+				this.badgeObj.domNode.parentNode.nodeType == 1 ? this.badgeObj.getValue() : null;
 		},
-	
-		_setIconPos2Attr: function(pos){
-			this._setIcon(null, pos, 2, !this.selected);
+
+		_setBadgeAttr: function(/*String*/value){
+			if(!this.badgeObj){
+				this.badgeObj = new Badge({fontSize:11});
+				domStyle.set(this.badgeObj.domNode, {
+					position: "absolute",
+					top: "0px",
+					right: "0px"
+				});
+			}
+			this.badgeObj.setValue(value);
+			if(value){
+				this.domNode.appendChild(this.badgeObj.domNode);
+			}else{
+				if(this.domNode === this.badgeObj.domNode.parentNode){
+					this.domNode.removeChild(this.badgeObj.domNode);
+				}
+			}
 		},
 
-		_setLabelAttr: function(/*String*/text){
-			this.label = text;
-			this.box.innerHTML = this._cv ? this._cv(text) : text;
+		_setSelectedAttr: function(/*Boolean*/selected){
+			// summary:
+			//		Makes this widget in the selected or unselected state.
+			this.inherited(arguments);
+			domClass.toggle(this.domNode, "mblTabBarButtonSelected", selected);
+			domAttr.set(this.domNode, "aria-selected", selected ? "true" : "false");
+			if(this._moveTo){
+				var tabPanelNode = dom.byId(this._moveTo);
+				if(tabPanelNode){
+					domAttr.set(tabPanelNode, "aria-hidden", selected ? "false" : "true");
+				}
+			}
 		}
 	});
+
+	return has("dojo-bidi")?declare("dojox.mobile.TabBarButton", [TabBarButton, BidiTabBarButton]):TabBarButton;
 });
diff --git a/dojox/mobile/TextArea.js b/dojox/mobile/TextArea.js
index c24d398..4b84c8f 100644
--- a/dojox/mobile/TextArea.js
+++ b/dojox/mobile/TextArea.js
@@ -4,17 +4,12 @@ define([
 	"./TextBox"
 ], function(declare, domConstruct, TextBox){
 
-	/*=====
-		TextBox = dojox.mobile.TextBox;
-	=====*/
 	return declare("dojox.mobile.TextArea",TextBox, {
 		// summary:
 		//		Non-templated TEXTAREA widget.
-		//
 		// description:
 		//		A textarea widget that wraps an HTML TEXTAREA element.
 		//		Takes all the parameters (name, value, etc.) that a vanilla textarea takes.
-		//
 		// example:
 		// |	<textarea dojoType="dojox.mobile.TextArea">...</textarea>
 
diff --git a/dojox/mobile/TextBox.js b/dojox/mobile/TextBox.js
index 0fa1c13..fd6a983 100644
--- a/dojox/mobile/TextBox.js
+++ b/dojox/mobile/TextBox.js
@@ -3,15 +3,12 @@ define([
 	"dojo/dom-construct",
 	"dijit/_WidgetBase",
 	"dijit/form/_FormValueMixin",
-	"dijit/form/_TextBoxMixin"
-], function(declare, domConstruct, WidgetBase, FormValueMixin, TextBoxMixin){
+	"dijit/form/_TextBoxMixin",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/TextBox"
+], function(declare, domConstruct, WidgetBase, FormValueMixin, TextBoxMixin, has, BidiTextBox){
 
-	/*=====
-		WidgetBase = dijit._WidgetBase;
-		FormValueMixin = dijit.form._FormValueMixin;
-		TextBoxMixin = dijit.form._TextBoxMixin;
-	=====*/
-	return declare("dojox.mobile.TextBox",[WidgetBase, FormValueMixin, TextBoxMixin],{
+	var TextBox = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiTextBox" : "dojox.mobile.TextBox", [WidgetBase, FormValueMixin, TextBoxMixin],{
 		// summary:
 		//		A non-templated base class for textbox form inputs
 
@@ -22,7 +19,11 @@ define([
 		_setTypeAttr: null,
 
 		// Map widget attributes to DOMNode attributes.
-		_setPlaceHolderAttr: "textbox",
+		_setPlaceHolderAttr: function(/*String*/value){
+			value = this._cv ? this._cv(value) : value;
+			this._set("placeHolder", value);
+			this.textbox.setAttribute("placeholder", value);
+		},
 
 		buildRendering: function(){
 			if(!this.srcNodeRef){
@@ -34,8 +35,14 @@ define([
 
 		postCreate: function(){
 			this.inherited(arguments);
-			this.connect(this.textbox, "onfocus", "_onFocus");
+			this.connect(this.textbox, "onmouseup", function(){ this._mouseIsDown = false; });
+			this.connect(this.textbox, "onmousedown", function(){ this._mouseIsDown = true; });
+			this.connect(this.textbox, "onfocus", function(e){
+				this._onFocus(this._mouseIsDown ? "mouse" : e);
+				this._mouseIsDown = false;
+			});
 			this.connect(this.textbox, "onblur", "_onBlur");
 		}
 	});
+	return has("dojo-bidi") ? declare("dojox.mobile.TextBox", [TextBox, BidiTextBox]) : TextBox;	
 });
diff --git a/dojox/mobile/TimePicker.js b/dojox/mobile/TimePicker.js
new file mode 100644
index 0000000..c4bf18a
--- /dev/null
+++ b/dojox/mobile/TimePicker.js
@@ -0,0 +1,21 @@
+define([
+	"dojo/_base/lang",
+	"./_PickerChooser!TimePicker"
+], function(lang, TimePicker){
+
+	/*=====
+	return function(){
+		// module:
+		//		dojox/mobile/TimePicker
+		// summary:
+		//		A wrapper widget around SpinWheelTimePicker or ValuePickerTimePicker.
+		//		Returns ValuePickerTimePicker when the current theme is "android" or "holodark".
+		//		Returns SpinWheelTimePicker otherwise.
+
+		 // TODO: need to list all the properties/methods in the interface provided by
+		 // SpinWheelTimePicker / ValuePickerTimePicker
+	 };
+	=====*/
+
+	return lang.setObject("dojox.mobile.TimePicker", TimePicker);
+});
diff --git a/dojox/mobile/ToggleButton.js b/dojox/mobile/ToggleButton.js
index f6073ca..aa8cace 100644
--- a/dojox/mobile/ToggleButton.js
+++ b/dojox/mobile/ToggleButton.js
@@ -5,10 +5,6 @@ define([
 	"./Button"
 ], function(declare, domClass, ToggleButtonMixin, Button){
 
-	/*=====
-		Button = dojox.mobile.Button;
-		ToggleButtonMixin = dijit.form._ToggleButtonMixin;
-	=====*/
 	return declare("dojox.mobile.ToggleButton", [Button, ToggleButtonMixin], {
 		// summary:
 		//		A non-templated button widget that can be in two states (checked or not).
diff --git a/dojox/mobile/ToolBarButton.js b/dojox/mobile/ToolBarButton.js
index 904b88b..fd2914c 100644
--- a/dojox/mobile/ToolBarButton.js
+++ b/dojox/mobile/ToolBarButton.js
@@ -1,107 +1,178 @@
 define([
 	"dojo/_base/declare",
+	"dojo/_base/lang",
 	"dojo/_base/window",
 	"dojo/dom-class",
 	"dojo/dom-construct",
 	"dojo/dom-style",
-	"./common",
-	"./_ItemBase"
-], function(declare, win, domClass, domConstruct, domStyle, common, ItemBase){
-/*=====
-	var ItemBase = dojox.mobile._ItemBase;
-=====*/
+	"dojo/dom-attr",
+	"./sniff",
+	"./_ItemBase",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/ToolBarButton"
+], function(declare, lang, win, domClass, domConstruct, domStyle, domAttr, has, ItemBase, BidiToolBarButton){
 
 	// module:
 	//		dojox/mobile/ToolBarButton
-	// summary:
-	//		A button widget that is placed in the Heading widget.
 
-	return declare("dojox.mobile.ToolBarButton", ItemBase, {
+	var ToolBarButton = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiToolBarButton" : "dojox.mobile.ToolBarButton", ItemBase, {
 		// summary:
-		//		A button widget that is placed in the Heading widget.
+		//		A button widget which is placed in the Heading widget.
 		// description:
-		//		ToolBarButton is a button that is placed in the Heading
-		//		widget. It is a subclass of dojox.mobile._ItemBase just like
-		//		ListItem or IconItem. So, unlike Button, it has basically the
-		//		same capability as ListItem or IconItem, such as icon support,
-		//		transition, etc.
+		//		ToolBarButton is a button which is typically placed in the
+		//		Heading widget. It is a subclass of dojox/mobile/_ItemBase just
+		//		like ListItem or IconItem. So, unlike Button, it has basically
+		//		the same capability as ListItem or IconItem, such as icon
+		//		support, transition, etc.
 
 		// selected: Boolean
-		//		If true, the button is in the selected status.
+		//		If true, the button is in the selected state.
 		selected: false,
 
-		// btnClass: String
-		//		Deprecated.
-		btnClass: "",
+		// arrow: [const] String
+		//		Specifies "right" or "left" to be an arrow button.
+		//		Note that changing the value of the property after the widget 
+		//		creation has no effect.
+		arrow: "",
 
-		/* internal properties */	
-		_defaultColor: "mblColorDefault",
-		_selColor: "mblColorDefaultSel",
+		// light: [const] Boolean
+		//		If true, this widget produces only a single `<span>` node when it
+		//		has only an icon or only a label, and has no arrow. In that
+		//		case, you cannot have both icon and label, or arrow even if you
+		//		try to set them.
+		//		Note that changing the value of the property after the widget 
+		//		creation has no effect.
+		light: true,
+
+		// defaultColor: String
+		//		CSS class for the default color.
+		//		Note: If this button has an arrow (typically back buttons on iOS),
+		//		the class selector used for it is the value of defaultColor + "45".
+		//		For example, by default the arrow selector is "mblColorDefault45".
+		defaultColor: "mblColorDefault",
+
+		// selColor: String
+		//		CSS class for the selected color.
+		//		Note: If this button has an arrow (typically back buttons on iOS),
+		//		the class selector used for it is the value of selColor + "45".
+		//		For example, by default the selected arrow selector is "mblColorDefaultSel45".
+		selColor: "mblColorDefaultSel",
+
+		/* internal properties */
+		baseClass: "mblToolBarButton",
+
+		_selStartMethod: "touch",
+		_selEndMethod: "touch",
 
 		buildRendering: function(){
-			this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("div");
-			this.inheritParams();
-			domClass.add(this.domNode, "mblToolBarButton mblArrowButtonText");
-			var color;
-			if(this.selected){
-				color = this._selColor;
-			}else if(this.domNode.className.indexOf("mblColor") == -1){
-				color = this._defaultColor;
+			if(!this.label && this.srcNodeRef){
+				this.label = this.srcNodeRef.innerHTML;
 			}
-			domClass.add(this.domNode, color);
-	
-			if(!this.label){
-				this.label = this.domNode.innerHTML;
+			this.label = lang.trim(this.label);
+			this.domNode = (this.srcNodeRef && this.srcNodeRef.tagName === "SPAN") ?
+				this.srcNodeRef : domConstruct.create("span");
+			domAttr.set(this.domNode, "role", "button");
+			this.inherited(arguments);
+
+			if(this.light && !this.arrow && (!this.icon || !this.label)){
+				this.labelNode = this.tableNode = this.bodyNode = this.iconParentNode = this.domNode;
+				domClass.add(this.domNode, this.defaultColor + " mblToolBarButtonBody" +
+							 (this.icon ? " mblToolBarButtonLightIcon" : " mblToolBarButtonLightText"));
+				return;
 			}
 
-			if(this.icon && this.icon != "none"){
-				this.iconNode = domConstruct.create("div", {className:"mblToolBarButtonIcon"}, this.domNode);
-				common.createIcon(this.icon, this.iconPos, null, this.alt, this.iconNode);
-				if(this.iconPos){
-					domClass.add(this.iconNode.firstChild, "mblToolBarButtonSpriteIcon");
-				}
-			}else{
-				if(common.createDomButton(this.domNode)){
-					domClass.add(this.domNode, "mblToolBarButtonDomButton");
-				}else{
-					domClass.add(this.domNode, "mblToolBarButtonText");
-				}
+			this.domNode.innerHTML = "";
+			if(this.arrow === "left" || this.arrow === "right"){
+				this.arrowNode = domConstruct.create("span", {
+					className: "mblToolBarButtonArrow mblToolBarButton" +
+					(this.arrow === "left" ? "Left" : "Right") + "Arrow " +
+					(has("ie") < 10 ? "" : (this.defaultColor + " " + this.defaultColor + "45"))
+				}, this.domNode);
+				domClass.add(this.domNode, "mblToolBarButtonHas" +
+					(this.arrow === "left" ? "Left" : "Right") + "Arrow");
 			}
-			this.connect(this.domNode, "onclick", "onClick");
+			this.bodyNode = domConstruct.create("span", {className:"mblToolBarButtonBody"}, this.domNode);
+			this.tableNode = domConstruct.create("table", {cellPadding:"0",cellSpacing:"0",border:"0"}, this.bodyNode);
+			if(!this.label && this.arrow){
+				// The class mblToolBarButtonText is needed for arrow shape too.
+				// If the button has a label, the class is set by _setLabelAttr. If no label, do it here.
+				this.tableNode.className = "mblToolBarButtonText";
+			}
+
+			var row = this.tableNode.insertRow(-1);
+			this.iconParentNode = row.insertCell(-1);
+			this.labelNode = row.insertCell(-1);
+			this.iconParentNode.className = "mblToolBarButtonIcon";
+			this.labelNode.className = "mblToolBarButtonLabel";
+
+			if(this.icon && this.icon !== "none" && this.label){
+				domClass.add(this.domNode, "mblToolBarButtonHasIcon");
+				domClass.add(this.bodyNode, "mblToolBarButtonLabeledIcon");
+			}
+
+			domClass.add(this.bodyNode, this.defaultColor);
 		},
-	
-		select: function(){
+
+		startup: function(){
+			if(this._started){ return; }
+
+			this.connect(this.domNode, "onkeydown", "_onClick"); // for desktop browsers
+
+			this.inherited(arguments);
+			if(!this._isOnLine){
+				this._isOnLine = true;
+				// retry applying the attribute for which the custom setter delays the actual 
+				// work until _isOnLine is true. 
+				this.set("icon", this._pendingIcon !== undefined ? this._pendingIcon : this.icon);
+				// Not needed anymore (this code executes only once per life cycle):
+				delete this._pendingIcon; 
+			}
+		},
+
+		_onClick: function(e){
 			// summary:
-			//		Makes this widget in the selected state.
-			domClass.toggle(this.domNode, this._selColor, !arguments[0]);
-			this.selected = !arguments[0];
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
+			if(this.onClick(e) === false){ return; } // user's click action
+			this.defaultClickAction(e);
 		},
-		
-		deselect: function(){
+
+		onClick: function(/*Event*/ /*===== e =====*/){
 			// summary:
-			//		Makes this widget in the deselected state.
-			this.select(true);
+			//		User defined function to handle clicks
+			// tags:
+			//		callback
 		},
-	
-		onClick: function(e){
-			this.setTransitionPos(e);
-			this.defaultClickAction();
+
+		_setLabelAttr: function(/*String*/text){
+			// summary:
+			//		Sets the button label text.
+			this.inherited(arguments);
+			domClass.toggle(this.tableNode, "mblToolBarButtonText", text || this.arrow); // also needed if only arrow
 		},
-	
-		_setBtnClassAttr: function(/*String*/btnClass){
-			var node = this.domNode;
-			if(node.className.match(/(mblDomButton\w+)/)){
-				domClass.remove(node, RegExp.$1);
+
+		_setSelectedAttr: function(/*Boolean*/selected){
+			// summary:
+			//		Makes this widget in the selected or unselected state.
+			var replace = function(node, a, b){
+				domClass.replace(node, a + " " + a + "45", b + " " + b + "45");
 			}
-			domClass.add(node, btnClass);
-			if(common.createDomButton(this.domNode)){
-				domClass.add(this.domNode, "mblToolBarButtonDomButton");
+			this.inherited(arguments);
+			if(selected){
+				domClass.replace(this.bodyNode, this.selColor, this.defaultColor);
+				if(!(has("ie") < 10) && this.arrowNode){
+					replace(this.arrowNode, this.selColor, this.defaultColor);
+				}
+			}else{
+				domClass.replace(this.bodyNode, this.defaultColor, this.selColor);
+				if(!(has("ie") < 10) && this.arrowNode){
+					replace(this.arrowNode, this.defaultColor, this.selColor);
+				}
 			}
-		},
-
-		_setLabelAttr: function(/*String*/text){
-			this.label = text;
-			this.domNode.innerHTML = this._cv ? this._cv(text) : text;
+			domClass.toggle(this.domNode, "mblToolBarButtonSelected", selected);
+			domClass.toggle(this.bodyNode, "mblToolBarButtonBodySelected", selected);
 		}
 	});
+	return has("dojo-bidi") ? declare("dojox.mobile.ToolBarButton", [ToolBarButton, BidiToolBarButton]) : ToolBarButton;
 });
diff --git a/dojox/mobile/Tooltip.js b/dojox/mobile/Tooltip.js
index ed1a460..a58710b 100644
--- a/dojox/mobile/Tooltip.js
+++ b/dojox/mobile/Tooltip.js
@@ -8,16 +8,14 @@ define([
 	"dojo/dom-geometry",
 	"dojo/dom-style",
 	"dijit/place",
-	"dijit/_WidgetBase"
-], function(array, registry, declare, lang, domClass, domConstruct, domGeometry, domStyle, place, WidgetBase){
+	"dijit/_WidgetBase",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/Tooltip"
+], function(array, registry, declare, lang, domClass, domConstruct, domGeometry, domStyle, place, WidgetBase, has, BidiTooltip){
 
-	/*=====
-		WidgetBase = dijit._WidgetBase;
-	=====*/
-	return declare("dojox.mobile.Tooltip", WidgetBase, {
+	var Tooltip = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiTooltip" : "dojox.mobile.Tooltip", WidgetBase, {
 		// summary:
 		//		A non-templated popup bubble widget
-		//
 
 		baseClass: "mblTooltip mblTooltipHidden",
 
@@ -27,17 +25,23 @@ define([
 			this.anchor = domConstruct.create("div", {"class":"mblTooltipAnchor"}, this.domNode, "first");
 			this.arrow = domConstruct.create("div", {"class":"mblTooltipArrow"}, this.anchor);
 			this.innerArrow = domConstruct.create("div", {"class":"mblTooltipInnerArrow"}, this.anchor);
+			if(!this.containerNode){
+				// set containerNode so that getChildren() works
+				this.containerNode = this.domNode;
+			}
 		},
 
-		show: function(/*DomNode*/ aroundNode, positions){
+		show: function(/*DomNode*/ aroundNode, /*Array*/positions){
 			// summary:
 			//		Pop up the tooltip and point to aroundNode using the best position
 			// positions:
 			//		Ordered list of positions to try matching up.
-			//			* before: places drop down before the aroundNode
-			//			* after: places drop down after the aroundNode
-			//			* above-centered: drop down goes above aroundNode
-			//			* below-centered: drop down goes below aroundNode
+			//
+			//		- before-centered: places drop down before the aroundNode
+			//		- after-centered: places drop down after the aroundNode
+			//		- above-centered: drop down goes above aroundNode
+			//		- below-centered: drop down goes below aroundNode
+
 			var domNode = this.domNode;
 			var connectorClasses = {
 				"MRM": "mblTooltipAfter",
@@ -56,14 +60,21 @@ define([
 			domClass.remove(domNode, ["mblTooltipAfter","mblTooltipBefore","mblTooltipBelow","mblTooltipAbove"]);
 			array.forEach(registry.findWidgets(domNode), function(widget){
 				if(widget.height == "auto" && typeof widget.resize == "function"){
-					if(!widget.fixedFooterHeight){
-						widget.fixedFooterHeight = domGeometry.getPadBorderExtents(domNode).b;
+					if(!widget._parentPadBorderExtentsBottom){
+						widget._parentPadBorderExtentsBottom = domGeometry.getPadBorderExtents(domNode).b;
 					}
 					widget.resize();
 				}
 			});
-			var best = place.around(domNode, aroundNode, positions || ['below-centered', 'above-centered', 'after', 'before'], this.isLeftToRight());
-			var connectorClass = connectorClasses[best.corner + best.aroundCorner.charAt(0)] || '';
+			// Convert before/after to before-centered/after-centered for compatibility
+			// TODO remove this 1.7->1.8 compatibility code in 2.0
+			if(positions){
+				positions = array.map(positions, function(pos){
+					return {after: "after-centered", before: "before-centered"}[pos] || pos;
+				});
+			}
+			var best = place.around(domNode, aroundNode, positions || ["below-centered", "above-centered", "after-centered", "before-centered"], this.isLeftToRight());
+			var connectorClass = connectorClasses[best.corner + best.aroundCorner.charAt(0)] || "";
 			domClass.add(domNode, connectorClass);
 			var pos = domGeometry.position(aroundNode, true);
 			domStyle.set(this.anchor, (connectorClass == "mblTooltipAbove" || connectorClass == "mblTooltipBelow")
@@ -96,4 +107,6 @@ define([
 			this.inherited(arguments);
 		}
 	});
+	
+	return has("dojo-bidi") ? declare("dojox.mobile.Tooltip", [Tooltip, BidiTooltip]) : Tooltip;		
 });
diff --git a/dojox/mobile/TransitionEvent.js b/dojox/mobile/TransitionEvent.js
index c21ed26..fcf6bbe 100644
--- a/dojox/mobile/TransitionEvent.js
+++ b/dojox/mobile/TransitionEvent.js
@@ -1,35 +1,28 @@
-define([
-	"dojo/_base/declare",
-	"dojo/_base/Deferred",
-	"dojo/_base/lang",
-	"dojo/on",
-	"./transition"
-], function(declare, Deferred, lang, on, transitDeferred){
+define(["dojo/_base/declare", "dojo/on"], function(declare, on){
 
 	return declare("dojox.mobile.TransitionEvent", null, {
-		constructor: function(target, transitionOptions, triggerEvent){
-			this.transitionOptions=transitionOptions;	
+		// summary:
+		//		A class used to trigger view transitions.
+		
+		constructor: function(/*DomNode*/target, /*Object*/transitionOptions, /*Event?*/triggerEvent){
+			// summary:
+			//		Creates a transition event.
+			// target:
+			//		The DOM node that initiates the transition (for example a ListItem).
+			// transitionOptions:
+			//		Contains the transition options.
+			// triggerEvent:
+			//		The event that triggered the transition (for example a touch event on a ListItem).
+			this.transitionOptions = transitionOptions;
 			this.target = target;
-			this.triggerEvent=triggerEvent||null;	
+			this.triggerEvent = triggerEvent||null;
 		},
 
 		dispatch: function(){
+			// summary:
+			//		Dispatches this transition event. Emits a "startTransition" event on the target.
 			var opts = {bubbles:true, cancelable:true, detail: this.transitionOptions, triggerEvent: this.triggerEvent};	
-			//console.log("Target: ", this.target, " opts: ", opts);
-
 			var evt = on.emit(this.target,"startTransition", opts);
-			//console.log('evt: ', evt);
-			if(evt){
-				Deferred.when(transitDeferred, lang.hitch(this, function(transition){
-					Deferred.when(transition.call(this, evt), lang.hitch(this, function(results){
-						this.endTransition(results);
-					})); 
-				}));
-			}
-		},
-
-		endTransition: function(results){
-			on.emit(this.target, "endTransition" , {detail: results.transitionOptions});
 		}
 	});
 });
diff --git a/dojox/mobile/TreeView.js b/dojox/mobile/TreeView.js
new file mode 100644
index 0000000..7b465f9
--- /dev/null
+++ b/dojox/mobile/TreeView.js
@@ -0,0 +1,120 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-construct",
+	"dijit/registry",
+	"./Heading",
+	"./ListItem",
+	"./ProgressIndicator",
+	"./RoundRectList",
+	"./ScrollableView",
+	"./viewRegistry",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/TreeView"
+], function(kernel, array, declare, lang, win, domConstruct, registry, Heading, ListItem, ProgressIndicator, RoundRectList, ScrollableView, viewRegistry, has, BidiTreeView){
+
+	// module:
+	//		dojox/mobile/TreeView
+
+	kernel.experimental("dojox.mobile.TreeView");
+
+	var TreeView = declare(has("dojo-bidi") ? "dojox.mobile.NonBidiTreeView" : "dojox.mobile.TreeView", ScrollableView, {
+		// summary:
+		//		A scrollable view with tree-style navigation.
+		// description:
+		//		This widget can be connected to a dojox/data/FileStore as a
+		//		quick directory browser. You may use it when implementing the
+		//		Master-Detail pattern.
+
+		postCreate: function(){
+			this._load();
+			this.inherited(arguments);
+		},
+		
+		_customizeListItem: function(listItemArgs){
+		},
+
+		_load: function(){
+			this.model.getRoot(
+				lang.hitch(this, function(item){
+					var scope = this;
+					var list = new RoundRectList();
+					var node = {};
+					var listItemArgs = {
+						label: scope.model.rootLabel,
+						moveTo: '#',
+						onClick: function(){ scope.handleClick(this); },
+						item: item
+					};
+					this._customizeListItem(listItemArgs);
+					var listitem = new ListItem(listItemArgs);
+					list.addChild(listitem);
+					this.addChild(list);
+				})
+			)
+		},
+
+		handleClick: function(li){
+			// summary:
+			//		Called when the user clicks a tree item.
+			// li: dojox/mobile/ListItem
+			//		The item that the user clicked.
+			var newViewId = "view_";
+			if(li.item[this.model.newItemIdAttr]){
+				newViewId += li.item[this.model.newItemIdAttr];
+			}else{
+				newViewId += "rootView";
+			}
+			newViewId = newViewId.replace('/', '_');
+			if(registry.byId(newViewId)){  // view already exists, just transition to it
+				registry.byNode(li.domNode).transitionTo(newViewId);
+				return;
+			}
+
+			var prog = ProgressIndicator.getInstance();
+			win.body().appendChild(prog.domNode);
+			prog.start();
+
+			this.model.getChildren(li.item,
+				lang.hitch(this, function(items){
+					var scope = this;
+					var list = new RoundRectList();
+					array.forEach(items, function(item, i){
+						var listItemArgs = {
+							item: item,
+							label: item[scope.model.store.label],
+							transition: "slide"
+						};
+						scope._customizeListItem(listItemArgs);
+						if(scope.model.mayHaveChildren(item)){
+							listItemArgs.moveTo = '#';
+							listItemArgs.onClick = function(){ scope.handleClick(this); };
+						}
+						var listitem = new ListItem(listItemArgs);
+						list.addChild(listitem);
+					});
+
+					var heading = new Heading({
+						label: "Dynamic View",
+						back: "Back",
+						moveTo: viewRegistry.getEnclosingView(li.domNode).id
+					});
+
+					var newView = ScrollableView({
+						id: newViewId
+					}, domConstruct.create("div", null, win.body()));
+					newView.addChild(heading);
+					newView.addChild(list);
+					newView.startup();
+					prog.stop();
+					registry.byNode(li.domNode).transitionTo(newView.id);
+				})
+			)
+		}
+	});
+	
+	return has("dojo-bidi") ? declare("dojox.mobile.TreeView", [TreeView, BidiTreeView]) : TreeView;		
+});
diff --git a/dojox/mobile/ValuePicker.js b/dojox/mobile/ValuePicker.js
new file mode 100644
index 0000000..9af55c6
--- /dev/null
+++ b/dojox/mobile/ValuePicker.js
@@ -0,0 +1,31 @@
+define([
+	"dojo/_base/declare",
+	"./_PickerBase",
+	"./ValuePickerSlot" // to load ValuePickerSlot for you (no direct references)
+], function(declare, PickerBase){
+
+	// module:
+	//		dojox/mobile/ValuePicker
+
+	return declare("dojox.mobile.ValuePicker", PickerBase, {
+		// summary:
+		//		A value picker that has a stepper.
+		// description:
+		//		ValuePicker is a widget for selecting values. The values
+		//		can be selected by using the Plus or Minus buttons, or by
+		//		entering the value directly into the input field.
+		//		This type of value picker is typically seen on Android devices.
+
+		/* internal properties */	
+		baseClass: "mblValuePicker",
+
+		onValueChanged: function(/*dojox/mobile/ValuePickerSlot*/slot){
+			// summary:
+			//		Callback when the slot value is changed.
+			// slot:
+			//		The slot widget whose value has been changed.
+			// tags:
+			//		callback
+		}
+	});
+});
diff --git a/dojox/mobile/ValuePickerDatePicker.js b/dojox/mobile/ValuePickerDatePicker.js
new file mode 100644
index 0000000..8efcd1c
--- /dev/null
+++ b/dojox/mobile/ValuePickerDatePicker.js
@@ -0,0 +1,130 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"dojo/dom-attr",
+	"./_DatePickerMixin",
+	"./ValuePicker",
+	"./ValuePickerSlot"
+], function(declare, domClass, domAttr, DatePickerMixin, ValuePicker, ValuePickerSlot){
+
+	// module:
+	//		dojox/mobile/ValuePickerDatePicker
+
+	return declare("dojox.mobile.ValuePickerDatePicker", [ValuePicker, DatePickerMixin], {
+		// summary:
+		//		A ValuePicker-based date picker widget.
+		// description:
+		//		ValuePickerDatePicker is a date picker widget. It is a subclass of
+		//		dojox/mobile/ValuePicker. It has 3 slots: day, month and year.
+		
+		// readOnly: [const] Boolean
+		//		If true, slot input fields are read-only. Only the plus and
+		//		minus buttons can be used to change the values.
+		//		Note that changing the value of the property after the widget 
+		//		creation has no effect.
+		readOnly: false,
+		
+		// yearPlusBtnLabel: String
+		//		(Accessibility) Label for year plus button
+		yearPlusBtnLabel: "",
+		
+		// yearPlusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for the year plus button
+		yearPlusBtnLabelRef: "",
+		
+		// yearPlusBtnLabel: String
+		//		(Accessibility) Label for year minus button
+		yearMinusBtnLabel: "",
+		
+		// yearPlusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for the year minus button
+		yearMinusBtnLabelRef: "",
+
+		// monthPlusBtnLabel: String
+		//		(Accessibility) Label for month plus button
+		monthPlusBtnLabel: "",
+		
+		// monthPlusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for the month plus button
+		monthPlusBtnLabelRef: "",
+		
+		// monthMinusBtnLabel: String
+		//		(Accessibility) Label for month minus button
+		monthMinusBtnLabel: "",
+		
+		// monthMinusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for the month minus button
+		monthMinusBtnLabelRef: "",
+
+		// dayPlusBtnLabel: String
+		//		(Accessibility) Label for day plus button
+		dayPlusBtnLabel: "",
+		
+		// dayPlusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for the day plus button
+		dayPlusBtnLabelRef: "",
+		
+		// dayMinusBtnLabel: String
+		//		(Accessibility) Label for day minus button
+		dayMinusBtnLabel: "",
+		
+		// dayMinusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for the day minus button
+		dayMinusBtnLabelRef: "",
+
+		slotClasses: [
+			ValuePickerSlot,
+			ValuePickerSlot,
+			ValuePickerSlot
+		],
+
+		slotProps: [
+			{labelFrom:1970, labelTo:2038, style:{width:"87px"}},
+			{style:{width:"72px"}},
+			{style:{width:"72px"}}
+		],
+
+		buildRendering: function(){
+			var p = this.slotProps;
+			p[0].readOnly = p[1].readOnly = p[2].readOnly = this.readOnly;
+			this._setBtnLabels(p);
+			this.initSlots();
+			this.inherited(arguments);
+			domClass.add(this.domNode, "mblValuePickerDatePicker");
+			this._conn = [
+				this.connect(this.slots[0], "_spinToValue", "_onYearSet"),
+				this.connect(this.slots[1], "_spinToValue", "_onMonthSet"),
+				this.connect(this.slots[2], "_spinToValue", "_onDaySet")
+			];
+		},
+
+		disableValues: function(/*Number*/daysInMonth){
+			// summary:
+			//		Disables the end days of the month to match the specified
+			//		number of days of the month.
+			var items = this.slots[2].items;
+			if(this._tail){
+				this.slots[2].items = items = items.concat(this._tail);
+			}
+			this._tail = items.slice(daysInMonth);
+			items.splice(daysInMonth);
+		},
+		
+		_setBtnLabels: function(slotProps){
+		    //summary:
+		    // Set a11y labels on the plus/minus buttons
+			slotProps[0].plusBtnLabel = this.yearPlusBtnLabel;
+			slotProps[0].plusBtnLabelRef = this.yearPlusBtnLabelRef;
+			slotProps[0].minusBtnLabel = this.yearMinusBtnLabel;
+			slotProps[0].minusBtnLabelRef = this.yearMinusBtnLabelRef;
+			slotProps[1].plusBtnLabel = this.monthPlusBtnLabel; 
+			slotProps[1].plusBtnLabelRef = this.monthPlusBtnLabelRef;
+			slotProps[1].minusBtnLabel = this.monthMinusBtnLabel;
+			slotProps[1].minusBtnLabelRef = this.monthMinusBtnLabelRef;
+			slotProps[2].plusBtnLabel = this.dayPlusBtnLabel;
+			slotProps[2].plusBtnLabelRef = this.dayPlusBtnLabelRef;
+			slotProps[2].minusBtnLabel = this.dayMinusBtnLabel;
+			slotProps[2].minusBtnLabelRef = this.dayMinusBtnLabelRef;
+		}
+	});
+});
diff --git a/dojox/mobile/ValuePickerSlot.js b/dojox/mobile/ValuePickerSlot.js
new file mode 100644
index 0000000..2f46997
--- /dev/null
+++ b/dojox/mobile/ValuePickerSlot.js
@@ -0,0 +1,389 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-attr",
+	"dojo/touch",
+	"dijit/_WidgetBase",
+	"./iconUtils",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/ValuePickerSlot"
+], function(array, declare, event, lang, win, domClass, domConstruct, domAttr, touch, WidgetBase, iconUtils, has, BidiValuePickerSlot){
+
+	// module:
+	//		dojox/mobile/ValuePickerSlot
+
+	var ValuePickerSlot = declare(has("dojo-bidi") ?  "dojox.mobile.NonBidiValuePickerSlot" : "dojox.mobile.ValuePickerSlot", WidgetBase, {
+		// summary:
+		//		A widget representing one slot of a ValuePicker widget.
+		
+		// items: Array
+		//		An array of array of key-label pairs
+		//		(e.g. [[0, "Jan"], [1,"Feb"], ...]). If key values for each label
+		//		are not necessary, labels can be used instead.
+		items: [],
+
+		// labels: String[]
+		//		An array of labels to be displayed on the value picker
+		//		(e.g. ["Jan","Feb",...]). This is a simplified version of the
+		//		items property.
+		labels: [],
+
+		// labelFrom: Number
+		//		The start value of display values of the value picker. This
+		//		parameter is especially useful when value picker has serial
+		//		values.
+		labelFrom: 0,
+
+		// labelTo: Number
+		//		The end value of display values of the value picker.
+		labelTo: 0,
+
+		// zeroPad: Number
+		//		Length of zero padding numbers.
+		//		Ex. zeroPad=2 -> "00", "01", ...
+		//		Ex. zeroPad=3 -> "000", "001", ...
+		zeroPad: 0,
+
+		// value: String
+		//		The initial value of the value picker.
+		value: "",
+
+		// step: Number
+		//		The steps between labelFrom and labelTo.
+		step: 1,
+
+		// readOnly: [const] Boolean
+		//		A flag used to indicate if the input field is readonly or not.
+		//		Note that changing the value of the property after the widget 
+		//		creation has no effect.
+		readOnly: false,
+
+		// tabIndex: String
+		//		Tabindex setting for this widget so users can hit the tab key to
+		//		focus on it.
+		tabIndex: "0",
+
+		// key: Object
+		//		The key of the currently selected value in the items array. This is a read-only property.
+		//		Warning: Do not use this property directly, make sure to call the get() method.
+		/*=====
+		key: null,
+		=====*/
+		
+		// plusBtnLabel: String
+		//		(Accessibility) Text label for plus button
+		plusBtnLabel: "",
+		
+		// plusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for plus button
+		plusBtnLabelRef: "",
+		
+		// minusBtnLabel: String
+		//		(Accessibility) Text label for minus button
+		minusBtnLabel: "",
+		
+		// minusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for minus button
+		minusBtnLabelRef: "",
+
+		/* internal properties */	
+		baseClass: "mblValuePickerSlot",
+
+		buildRendering: function(){
+			this.inherited(arguments);
+
+			this.initLabels();
+			if(this.labels.length > 0){
+				this.items = [];
+				for(var i = 0; i < this.labels.length; i++){
+					this.items.push([i, this.labels[i]]);
+				}
+			}
+
+			this.plusBtnNode = domConstruct.create("div", {
+				className: "mblValuePickerSlotPlusButton mblValuePickerSlotButton",
+				title: "+"
+			}, this.domNode);
+			
+			this.plusIconNode = domConstruct.create("div", {
+				className: "mblValuePickerSlotIcon"
+			}, this.plusBtnNode);
+			iconUtils.createIcon("mblDomButtonGrayPlus", null, this.plusIconNode);
+
+			this.inputAreaNode = domConstruct.create("div", {
+				className: "mblValuePickerSlotInputArea"
+			}, this.domNode);
+			this.inputNode = domConstruct.create("input", {
+				className: "mblValuePickerSlotInput",
+				readonly: this.readOnly
+			}, this.inputAreaNode);
+			
+			this.minusBtnNode = domConstruct.create("div", {
+				className: "mblValuePickerSlotMinusButton mblValuePickerSlotButton",
+				title: "-"
+			}, this.domNode);
+			this.minusIconNode = domConstruct.create("div", {
+				className: "mblValuePickerSlotIcon"
+			}, this.minusBtnNode);
+			iconUtils.createIcon("mblDomButtonGrayMinus", null, this.minusIconNode);
+			
+			domAttr.set(this.plusBtnNode, "role", "button"); //a11y
+			this._setPlusBtnLabelAttr(this.plusBtnLabel)
+			this._setPlusBtnLabelRefAttr(this.plusBtnLabelRef);
+			
+			domAttr.set(this.inputNode, "role", "textbox");
+			var registry = require("dijit/registry");
+			var inputAreaNodeId =  registry.getUniqueId("dojo_mobile__mblValuePickerSlotInput");
+			domAttr.set(this.inputNode, "id", inputAreaNodeId);
+			domAttr.set(this.plusBtnNode, "aria-controls", inputAreaNodeId);
+			
+			domAttr.set(this.minusBtnNode, "role", "button");
+			domAttr.set(this.minusBtnNode, "aria-controls", inputAreaNodeId);
+			this._setMinusBtnLabelAttr(this.minusBtnLabel);
+			this._setMinusBtnLabelRefAttr(this.minusBtnLabelRef);
+
+			if(this.value === "" && this.items.length > 0){
+				this.value = this.items[0][1];
+			}
+			this._initialValue = this.value;
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this._handlers = [
+				this.connect(this.plusBtnNode, touch.press, "_onTouchStart"),
+				this.connect(this.minusBtnNode, touch.press, "_onTouchStart"),
+				this.connect(this.plusBtnNode, "onkeydown", "_onClick"), // for desktop browsers
+				this.connect(this.minusBtnNode, "onkeydown", "_onClick"), // for desktop browsers
+				this.connect(this.inputNode, "onchange", lang.hitch(this, function(e){
+					this._onChange(e);
+				}))
+			];
+			this.inherited(arguments);
+			this._set(this.plusBtnLabel);
+		},
+
+		initLabels: function(){
+			// summary:
+			//		Initializes the labels of this slot according to the labelFrom and labelTo properties.
+			// tags:
+			//		private
+			if(this.labelFrom !== this.labelTo){
+				var a = this.labels = [],
+					zeros = this.zeroPad && Array(this.zeroPad).join("0");
+				for(var i = this.labelFrom; i <= this.labelTo; i += this.step){
+					a.push(this.zeroPad ? (zeros + i).slice(-this.zeroPad) : i + "");
+				}
+			}
+		},
+
+		spin: function(/*Number*/steps){
+			// summary:
+			//		Spins the slot as specified by steps.
+
+			// find the position of the current value
+			var pos = -1,
+				v = this.get("value"),
+				len = this.items.length;
+			for(var i = 0; i < len; i++){
+				if(this.items[i][1] === v){
+					pos = i;
+					break;
+				}
+			}
+			if(v == -1){ return; }
+			pos += steps;
+			if(pos < 0){ // shift to positive
+				pos += (Math.abs(Math.ceil(pos / len)) + 1) * len;
+			}
+			var newItem = this.items[pos % len];
+			this.set("value", newItem[1]);
+		},
+
+		setInitialValue: function(){
+			// summary:
+			//		Sets the initial value using this.value or the first item.
+			this.set("value", this._initialValue);
+		},
+
+		_onClick: function(e){
+			// summary:
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
+			if(this.onClick(e) === false){ return; } // user's click action
+			var node = e.currentTarget;
+			if(node === this.plusBtnNode || node === this.minusBtnNode){
+				this._btn = node;
+			}
+			this.spin(this._btn === this.plusBtnNode ? 1 : -1);
+		},
+
+		onClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User defined function to handle clicks
+			// tags:
+			//		callback
+		},
+
+		_onChange: function(e){
+			// summary:
+			//		Internal handler for the input field's value change events
+			// tags:
+			//		callback
+			if(this.onChange(e) === false){ return; } // user's click action
+			var v = this.get("value"), // text in the input field
+				a = this.validate(v);
+			this.set("value", a.length ? a[0][1] : this.value);
+		},
+
+		onChange: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User defined function to handle value changes
+			// tags:
+			//		callback
+		},
+
+		validate: function(value){
+			return array.filter(this.items, function(a){
+				return (a[1] + "").toLowerCase() == (value + "").toLowerCase();
+			});
+		},
+
+		_onTouchStart: function(e){
+			this._conn = [
+				this.connect(win.body(), touch.move, "_onTouchMove"),
+				this.connect(win.body(), touch.release, "_onTouchEnd")
+			];
+			this.touchStartX = e.touches ? e.touches[0].pageX : e.clientX;
+			this.touchStartY = e.touches ? e.touches[0].pageY : e.clientY;
+			domClass.add(e.currentTarget, "mblValuePickerSlotButtonSelected");
+			this._btn = e.currentTarget;
+			if(this._timer){
+				this._timer.remove(); // fail safe
+				this._timer = null;
+			}
+			if(this._interval){
+				clearInterval(this._interval); // fail safe
+				this._interval = null;
+			}
+			this._timer = this.defer(function(){
+				this._interval = setInterval(lang.hitch(this, function(){
+					this.spin(this._btn === this.plusBtnNode ? 1 : -1);
+				}), 60);
+				this._timer = null;
+			}, 1000);
+			event.stop(e);
+		},
+
+		_onTouchMove: function(e){
+			var x = e.touches ? e.touches[0].pageX : e.clientX;
+			var y = e.touches ? e.touches[0].pageY : e.clientY;
+			if(Math.abs(x - this.touchStartX) >= 4 ||
+			   Math.abs(y - this.touchStartY) >= 4){ // dojox/mobile/scrollable.threshold
+			   	if(this._timer){
+					this._timer.remove(); // fail safe
+					this._timer = null;
+				}
+				if(this._interval){
+					clearInterval(this._interval); // fail safe
+					this._interval = null;
+				}
+				array.forEach(this._conn, this.disconnect, this);
+				domClass.remove(this._btn, "mblValuePickerSlotButtonSelected");
+			}
+		},
+
+		_onTouchEnd: function(e){
+			if(this._timer){
+				this._timer.remove();
+				this._timer = null;
+			}
+			array.forEach(this._conn, this.disconnect, this);
+			domClass.remove(this._btn, "mblValuePickerSlotButtonSelected");
+			if(this._interval){
+				clearInterval(this._interval);
+				this._interval = null;
+			}else{
+				this._onClick(e);
+			}
+		},
+
+		_getKeyAttr: function(){
+			var val = this.get("value");
+			var item = array.filter(this.items, function(item){
+				return item[1] === val;
+			})[0];
+			return item ? item[0] : null;
+		},
+
+		_getValueAttr: function(){
+			// summary:
+			//		Gets the currently selected value.
+			return this.inputNode.value;
+		},
+
+		_setValueAttr: function(value){
+			// summary:
+			//		Sets a new value to this slot.
+			this._spinToValue(value, true);
+		},
+		
+		_spinToValue: function(value, applyValue){
+			// summary:
+			//		Sets a new value to this slot.
+			// tags:
+			//		private
+			if(this.get("value") == value){
+				return; // no change; avoid notification
+			}
+			this.inputNode.value = value;
+			// to avoid unnecessary notifications, applyValue is undefined when 
+			// _spinToValue is called by _DatePickerMixin.
+			if(applyValue){
+				this._set("value", value);
+			}
+			var parent = this.getParent();
+			if(parent && parent.onValueChanged){
+				parent.onValueChanged(this);
+			}
+		},
+
+		_setTabIndexAttr: function(/*String*/ tabIndex){
+			this.plusBtnNode.setAttribute("tabIndex", tabIndex);
+			this.minusBtnNode.setAttribute("tabIndex", tabIndex);
+		},
+		
+		_setAria: function(node, attr, value){
+			if(value){
+				domAttr.set(node, attr, value);
+			}else{
+				domAttr.remove(node, attr);
+			}
+		},
+		
+		_setPlusBtnLabelAttr: function(/*String*/ plusBtnLabel){
+			this._setAria(this.plusBtnNode, "aria-label", plusBtnLabel);
+		},
+		
+		_setPlusBtnLabelRefAttr: function(/*String*/ plusBtnLabelRef){
+			this._setAria(this.plusBtnNode, "aria-labelledby", plusBtnLabelRef);
+		},
+		
+		_setMinusBtnLabelAttr: function(/*String*/ minusBtnLabel){
+			this._setAria(this.minusBtnNode, "aria-label", minusBtnLabel);
+		},
+		
+		_setMinusBtnLabelRefAttr: function(/*String*/ minusBtnLabelRef){
+			this._setAria(this.minusBtnNode, "aria-labelledby", minusBtnLabelRef);
+		}
+	});
+	
+	return has("dojo-bidi") ? declare("dojox.mobile.ValuePickerSlot", [ValuePickerSlot, BidiValuePickerSlot]) : ValuePickerSlot;
+});
diff --git a/dojox/mobile/ValuePickerTimePicker.js b/dojox/mobile/ValuePickerTimePicker.js
new file mode 100644
index 0000000..c08537f
--- /dev/null
+++ b/dojox/mobile/ValuePickerTimePicker.js
@@ -0,0 +1,218 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"./_TimePickerMixin",
+	"./ToolBarButton",
+	"./ValuePicker",
+	"./ValuePickerSlot"
+], function(declare, domClass, TimePickerMixin, ToolBarButton, ValuePicker, ValuePickerSlot){
+
+	// module:
+	//		dojox/mobile/ValuePickerTimePicker
+
+	return declare("dojox.mobile.ValuePickerTimePicker", [ValuePicker, TimePickerMixin], {
+		// summary:
+		//		A ValuePicker-based time picker widget.
+		// description:
+		//		ValuePickerTimePicker is a time picker widget. It is a subclass of
+		//		dojox.mobile.ValuePicker. It has two slots: hour and minute.
+
+		// readOnly: [const] Boolean
+		//		If true, slot input fields are read-only. Only the plus and
+		//		minus buttons can be used to change the values.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		readOnly: false,
+
+		// is24h: Boolean
+		//		If true, the time is displayed in 24h format.
+		//		Otherwise, displayed in AM/PM mode.
+		is24h: false,
+
+		/*=====
+		// values: Array
+		//		The time value, as an array in 24h format: [hour24, minute] (ex. ["22","06"]).
+		//		Warning: Do not use this property directly, make sure to call set() or get() methods.
+		values: null,
+
+		// values12: Array
+		//		The time value, as an array in 12h format: [hour12, minute, ampm] (ex. ["10","06","PM"]).
+		//		Warning: Do not use this property directly, make sure to call set() or get() methods.
+		values12: null,
+		=====*/
+		
+		// hourPlusBtnLabel: String
+		//		(Accessibility) Label for hour plus button
+		hourPlusBtnLabel: "",
+		
+		// hourPlusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for the hour plus button
+		hourPlusBtnLabelRef: "",
+		
+		// minutePlusBtnLabel: String
+		//		(Accessibility) Label for minute plus button
+		minutePlusBtnLabel: "",
+		
+		// minutePlusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for the minute plus button
+		minutePlusBtnLabelRef: "",
+		
+		// hourMinusBtnLabel: String
+		//		(Accessibility) Label for hour minus button
+		hourMinusBtnLabel: "",
+		
+		// hourMinusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for the hour minus button
+		hourMinusBtnLabelRef: "",
+		
+		// minuteMinusBtnLabel: String
+		//		(Accessibility) Label for minute minus button
+		minuteMinusBtnLabel: "",
+		
+		// minuteMinusBtnLabelRef: String
+		//		(Accessibility) Reference to a node id containing text label for the minute minus button
+		minuteMinusBtnLabelRef: "",
+
+		slotClasses: [
+			ValuePickerSlot,
+			ValuePickerSlot
+		],
+
+		slotProps: [
+			{labelFrom:0, labelTo:23, style:{width:"72px"}},
+			{labelFrom:0, labelTo:59, zeroPad:2, style:{width:"72px"}}
+		],
+
+		buildRendering: function(){
+			var p = this.slotProps;
+			p[0].readOnly = p[1].readOnly = this.readOnly;
+			this._setBtnLabels(p);
+			this.inherited(arguments);
+			var items = this.slots[0].items;
+			this._zero = items.slice(0, 1);
+			this._pm = items.slice(13);
+
+			domClass.add(this.domNode, "mblValuePickerTimePicker");
+			domClass.add(this.slots[0].domNode, "mblValuePickerTimePickerHourSlot");
+			domClass.add(this.slots[1].domNode, "mblValuePickerTimePickerMinuteSlot");
+
+			this.ampmButton = new ToolBarButton();
+			this.addChild(this.ampmButton);
+			this._conn = [
+				this.connect(this.ampmButton, "onClick", "onBtnClick")
+			];
+			this.set("is24h", this.is24h);
+		},
+
+		to12h: function(a){
+			// summary:
+			//		Converts a 24h time to a 12h time.
+			// a: Array
+			//		[hour24, minute] (ex. ["22","06"])
+			// returns: Array
+			//		[hour12, minute, ampm] (ex. ["10","06","PM"])
+			// tags:
+			//		private
+			var h = a[0] - 0;
+			var ampm = h < 12 ? "AM" : "PM";
+			if(h == 0){
+				h = 12;
+			}else if(h > 12){
+				h = h - 12;
+			}
+			return [h + "", a[1], ampm]; // [hour12, minute, ampm]
+		},
+
+		to24h: function(a){
+			// summary:
+			//		Converts a 12h time to a 24h time.
+			// a: Array
+			//		[hour12, minute, ampm] (ex. ["10","06","PM"])
+			// returns: Array
+			//		[hour24, minute] (ex. ["22","06"])
+			// tags:
+			//		private
+			var h = a[0] - 0;
+			if(a[2] == "AM"){
+				h = h == 12 ? 0 : h; // 12AM is 0h
+			}else{
+				h = h == 12 ? h : h + 12; // 12PM is 12h
+			}
+			return [h + "", a[1]]; // [hour24, minute]
+		},
+
+		onBtnClick: function(){
+			// summary:
+			//		The handler for the AM/PM button.
+			var ampm = this.ampmButton.get("label") == "AM" ? "PM" : "AM";
+			var v = this.get("values12");
+			v[2] = ampm;
+			this.set("values12", v);
+			if(this.onValueChanged){
+				this.onValueChanged(this.slots[0]);
+			}
+		},
+
+		_setIs24hAttr: function(/*Boolean*/is24h){
+			// summary:
+			//		Changes the time display mode, 24h or 12h.
+			var items = this.slots[0].items;
+			if(is24h && items.length != 24){ // 24h: 0 - 23
+				this.slots[0].items = this._zero.concat(items).concat(this._pm);
+			}else if(!is24h && items.length != 12){ // 12h: 1 - 12
+				items.splice(0, 1);
+				items.splice(12);
+			}
+			var v = this.get("values");
+			this._set("is24h", is24h);
+			this.ampmButton.domNode.style.display = is24h ? "none" : "";
+			this.set("values", v);
+		},
+
+		_getValuesAttr: function(){
+			// summary:
+			//		Returns an array of hour and minute in 24h format.
+			var v = this.inherited(arguments); // [hour, minute]
+			return this.is24h ? v : this.to24h([v[0], v[1], this.ampmButton.get("label")]);
+		},
+
+		_setValuesAttr: function(/*Array*/values){
+			// summary:
+			//		Sets an array of hour and minute in 24h format.
+			// values:
+			//		[hour24, minute] (ex. ["22","06"])
+			if(this.is24h){
+				this.inherited(arguments);
+			}else{
+				values = this.to12h(values);
+				this.ampmButton.set("label", values[2]);
+				this.inherited(arguments);
+			}
+		},
+
+		_getValues12Attr: function(){
+			// summary:
+			//		Returns an array of hour and minute in 12h format.
+			return this.to12h(this._getValuesAttr());
+		},
+
+		_setValues12Attr: function(/*Array*/values){
+			// summary:
+			//		Sets an array of hour and minute in 12h format.
+			// values:
+			//		[hour12, minute, ampm] (ex. ["10","06","PM"])
+			this.set("values", this.to24h(values));
+		},
+		
+		_setBtnLabels: function(slotProps){
+		    slotProps[0].plusBtnLabel = this.hourPlusBtnLabel; 
+			slotProps[0].plusBtnLabelRef = this.hourPlusBtnLabelRef;
+			slotProps[0].minusBtnLabel = this.hourMinusBtnLabel;
+			slotProps[0].minusBtnLabelRef = this.hourMinusBtnLabelRef;
+			slotProps[1].plusBtnLabel = this.minutePlusBtnLabel;
+			slotProps[1].plusBtnLabelRef = this.minutePlusBtnLabelRef;
+			slotProps[1].minusBtnLabel = this.minuteMinusBtnLabel;
+			slotProps[1].minusBtnLabelRef = this.minuteMinusBtnLabelRef;
+		}
+	});
+});
diff --git a/dojox/mobile/Video.js b/dojox/mobile/Video.js
new file mode 100644
index 0000000..0275457
--- /dev/null
+++ b/dojox/mobile/Video.js
@@ -0,0 +1,41 @@
+define([
+	"dojo/_base/declare",
+	"dojo/sniff",
+	"./Audio"
+], function(declare, has, Audio){
+	// module:
+	//		dojox/mobile/Video
+
+	return declare("dojox.mobile.Video", Audio, {
+		// summary:
+		//		A thin wrapper around the HTML5 `<video>` element.
+		// description:
+		//		dojox/mobile/Video is a widget which plays video. If all sources cannot 
+		//		be played (typically, in desktop browsers that do not support `<video>`), 
+		//		dojox/mobile/Video automatically replaces `<video>` with `<embed>`, such 
+		//		that the browser tries to play it with a suitable plug-in.
+		
+		// width: [const] String
+		//		The width of the embed element.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		width: "200px",
+
+		// height: [const] String
+		//		The height of the embed element.
+		//		Note that changing the value of the property after the widget
+		//		creation has no effect.
+		height: "150px",
+
+		// _tag: [private] String
+		//		The name of the tag ("video").
+		_tag: "video",
+
+		_getEmbedRegExp: function(){
+			return has("ff") ? /video\/mp4/i :
+				   has("ie") >= 9 ? /video\/webm/i :
+				   //has("safari") ? /video\/webm/i : //Google is gooing to provide webm plugin for safari
+				   null;
+		}
+	});
+});
diff --git a/dojox/mobile/View.js b/dojox/mobile/View.js
index 65b2e60..a1d1927 100644
--- a/dojox/mobile/View.js
+++ b/dojox/mobile/View.js
@@ -1,37 +1,30 @@
 define([
-	"dojo/_base/kernel", // to test dojo.hash
 	"dojo/_base/array",
 	"dojo/_base/config",
 	"dojo/_base/connect",
 	"dojo/_base/declare",
 	"dojo/_base/lang",
-	"dojo/_base/sniff",
+	"dojo/sniff",
 	"dojo/_base/window",
 	"dojo/_base/Deferred",
 	"dojo/dom",
 	"dojo/dom-class",
+	"dojo/dom-construct",
 	"dojo/dom-geometry",
 	"dojo/dom-style",
-//	"dojo/hash", // optionally prereq'ed
-	"dijit/registry",	// registry.byNode
+	"dijit/registry",
 	"dijit/_Contained",
 	"dijit/_Container",
 	"dijit/_WidgetBase",
 	"./ViewController", // to load ViewController for you (no direct references)
-	"./transition"
-], function(dojo, array, config, connect, declare, lang, has, win, Deferred, dom, domClass, domGeometry, domStyle, registry, Contained, Container, WidgetBase, ViewController, transitDeferred){
-
-/*=====
-	var Contained = dijit._Contained;
-	var Container = dijit._Container;
-	var WidgetBase = dijit._WidgetBase;
-	var ViewController = dojox.mobile.ViewController;
-=====*/
+	"./common",
+	"./transition",
+	"./viewRegistry",
+	"./_css3"
+], function(array, config, connect, declare, lang, has, win, Deferred, dom, domClass, domConstruct, domGeometry, domStyle, registry, Contained, Container, WidgetBase, ViewController, common, transitDeferred, viewRegistry, css3){
 
 	// module:
 	//		dojox/mobile/View
-	// summary:
-	//		A widget that represents a view that occupies the full screen
 
 	var dm = lang.getObject("dojox.mobile", true);
 
@@ -39,81 +32,125 @@ define([
 		// summary:
 		//		A widget that represents a view that occupies the full screen
 		// description:
-		//		View acts as a container for any HTML and/or widgets. An entire
-		//		HTML page can have multiple View widgets and the user can
-		//		navigate through the views back and forth without page
-		//		transitions.
-	
+		//		View is a container widget for any HTML element and/or Dojo widgets.
+		//		As a Dojo widget container it can itself contain View widgets
+		//		forming a set of nested views. A Dojo Mobile application is usually
+		//		made of multiple View widgets and the user can navigate through
+		//		the views back and forth with animated transition effects.
+		//		
+		//		When using several sibling views (direct children of the same
+		//		element), you can use the 'selected' attribute to define whether
+		//		the view should be displayed when the application is launched.
+		//		If no view has selected=true, the first sibling view is displayed
+		//		at startup time.
+
 		// selected: Boolean
 		//		If true, the view is displayed at startup time.
 		selected: false,
 
 		// keepScrollPos: Boolean
-		//		If true, the scroll position is kept between views.
+		//		If true, the scroll position is kept when transition occurs between views.
 		keepScrollPos: true,
-	
-		constructor: function(params, node){
+
+		// tag: String
+		//		The name of the HTML tag to create as domNode. The default value is "div".
+		tag: "div",
+
+		/* internal properties */
+		baseClass: "mblView",
+
+		constructor: function(/*Object*/params, /*DomNode?*/node){
+			// summary:
+			//		Creates a new instance of the class.
+			// params:
+			//		Contains the parameters.
+			// node:
+			//		The DOM node. If none is specified, it is automatically created. 
 			if(node){
 				dom.byId(node).style.visibility = "hidden";
 			}
-			this._aw = has('android') >= 2.2 && has('android') < 3; // flag for android animation workaround
 		},
-	
+
+		destroy: function(){
+			viewRegistry.remove(this.id);
+			this.inherited(arguments);
+		},
+
 		buildRendering: function(){
-			this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("DIV");
-			this.domNode.className = "mblView";
-			this.connect(this.domNode, "webkitAnimationEnd", "onAnimationEnd");
-			this.connect(this.domNode, "webkitAnimationStart", "onAnimationStart");
+			if(!this.templateString){
+				// Create root node if it wasn't created by _TemplatedMixin
+				this.domNode = this.containerNode = this.srcNodeRef || domConstruct.create(this.tag);
+			}
+
+			this._animEndHandle = this.connect(this.domNode, css3.name("animationEnd"), "onAnimationEnd");
+			this._animStartHandle = this.connect(this.domNode, css3.name("animationStart"), "onAnimationStart");
 			if(!config['mblCSS3Transition']){
-			    this.connect(this.domNode, "webkitTransitionEnd", "onAnimationEnd");
+				this._transEndHandle = this.connect(this.domNode, css3.name("transitionEnd"), "onAnimationEnd");
 			}
-			var id = location.href.match(/#(\w+)([^\w=]|$)/) ? RegExp.$1 : null;
-	
-			this._visible = this.selected && !id || this.id == id;
-	
-			if(this.selected){
-				dm._defaultView = this;
+			if(has('mblAndroid3Workaround')){
+				// workaround for the screen flicker issue on Android 3.x/4.0
+				// applying "-webkit-transform-style:preserve-3d" to domNode can avoid
+				// transition animation flicker
+				domStyle.set(this.domNode, css3.name("transformStyle"), "preserve-3d");
 			}
+
+			viewRegistry.add(this);
+			this.inherited(arguments);
 		},
 
 		startup: function(){
 			if(this._started){ return; }
-			var siblings = [];
-			var children = this.domNode.parentNode.childNodes;
-			var visible = false;
-			// check if a visible view exists
-			for(var i = 0; i < children.length; i++){
-				var c = children[i];
-				if(c.nodeType === 1 && domClass.contains(c, "mblView")){
-					siblings.push(c);
-					visible = visible || registry.byNode(c)._visible;
-				}
+
+			// Determine which view among the siblings should be visible.
+			// Priority:
+			//	 1. fragment id in the url (ex. #view1,view2)
+			//	 2. this.selected
+			//	 3. the first view
+			if(this._visible === undefined){
+				var views = this.getSiblingViews();
+				var ids = location.hash && location.hash.substring(1).split(/,/);
+				var fragView, selectedView, firstView;
+				array.forEach(views, function(v, i){
+					if(array.indexOf(ids, v.id) !== -1){ fragView = v; }
+					if(i == 0){ firstView = v; }
+					if(v.selected){ selectedView = v; }
+					v._visible = false;
+				}, this);
+				(fragView || selectedView || firstView)._visible = true;
 			}
-			var _visible = this._visible;
-			// if no visible view exists, make the first view visible
-			if(siblings.length === 1 || (!visible && siblings[0] === this.domNode)){
-				_visible = true;
+			if(this._visible){
+				// The 2nd arg is not to hide its sibling views so that they can be
+				// correctly initialized.
+				this.show(true, true);
+
+				// Defer firing events to let user connect to events just after creation
+				// TODO: revisit this for 2.0
+				this.defer(function(){
+					this.onStartView();
+					connect.publish("/dojox/mobile/startView", [this]);
+				});
 			}
-			var _this = this;
-			setTimeout(function(){ // necessary to render the view correctly
-				if(!_visible){
-					_this.domNode.style.display = "none";
-				}else{
-					dm.currentView = _this; //TODO:1.8 reconsider this. currentView may not have a currently showing view when views are nested.
-					_this.onStartView();
-					connect.publish("/dojox/mobile/startView", [_this]);
-				}
-				if(_this.domNode.style.visibility != "visible"){ // this check is to avoid screen flickers
-					_this.domNode.style.visibility = "visible";
-				}
-				var parent = _this.getParent && _this.getParent();
-				if(!parent || !parent.resize){ // top level widget
-					_this.resize();
-				}
-			}, has("ie") ? 100 : 0); // give IE a little time to complete drawing
+
+			if(this.domNode.style.visibility != "visible"){ // this check is to avoid screen flickers
+				this.domNode.style.visibility = "visible";
+			}
+
+			// Need to call inherited first - so that child widgets get started
+			// up correctly
 			this.inherited(arguments);
+
+			var parent = this.getParent();
+			if(!parent || !parent.resize){ // top level widget
+				this.resize();
+			}
+
+			if(!this._visible){
+				// hide() should be called last so that child widgets can be
+				// initialized while they are visible.
+				this.hide();
+			}
 		},
-	
+
 		resize: function(){
 			// summary:
 			//		Calls resize() of each child widget.
@@ -128,53 +165,50 @@ define([
 			// description:
 			//		Called only when this view is shown at startup time.
 		},
-	
+
 		onBeforeTransitionIn: function(moveTo, dir, transition, context, method){
 			// summary:
 			//		Stub function to connect to from your application.
 			// description:
 			//		Called before the arriving transition occurs.
 		},
-	
+
 		onAfterTransitionIn: function(moveTo, dir, transition, context, method){
 			// summary:
 			//		Stub function to connect to from your application.
 			// description:
 			//		Called after the arriving transition occurs.
 		},
-	
+
 		onBeforeTransitionOut: function(moveTo, dir, transition, context, method){
 			// summary:
 			//		Stub function to connect to from your application.
 			// description:
 			//		Called before the leaving transition occurs.
 		},
-	
+
 		onAfterTransitionOut: function(moveTo, dir, transition, context, method){
 			// summary:
 			//		Stub function to connect to from your application.
 			// description:
 			//		Called after the leaving transition occurs.
 		},
-	
-		_saveState: function(moveTo, dir, transition, context, method){
-			this._context = context;
-			this._method = method;
-			if(transition == "none"){
-				transition = null;
-			}
-			this._moveTo = moveTo;
-			this._dir = dir;
-			this._transition = transition;
-			this._arguments = lang._toArray(arguments);
-			this._args = [];
-			if(context || method){
-				for(var i = 5; i < arguments.length; i++){
-					this._args.push(arguments[i]);
+
+		_clearClasses: function(/*DomNode*/node){
+			// summary:
+			//		Clean up the domNode classes that were added while making a transition.
+			// description:
+			//		Remove all the "mbl" prefixed classes except mbl*View.
+			if(!node){ return; }
+			var classes = [];
+			array.forEach(lang.trim(node.className||"").split(/\s+/), function(c){
+				if(c.match(/^mbl\w*View$/) || c.indexOf("mbl") === -1){
+					classes.push(c);
 				}
-			}
+			}, this);
+			node.className = classes.join(' ');
 		},
-		
+
 		_fixViewState: function(/*DomNode*/toNode){
 			// summary:
 			//		Sanity check for view transition states.
@@ -186,31 +220,42 @@ define([
 			for(var i = 0; i < nodes.length; i++){
 				var n = nodes[i];
 				if(n.nodeType === 1 && domClass.contains(n, "mblView")){
-					n.className = "mblView"; //TODO: Should remove classes one by one. This would clear user defined classes or even mblScrollableView.
+					this._clearClasses(n);
 				}
 			}
-			toNode.className = "mblView"; // just in case toNode is a sibling of an ancestor.
+			this._clearClasses(toNode); // just in case toNode is a sibling of an ancestor.
+			
+			// #16337
+			// Uninitialization may fail to clear _inProgress when multiple
+			// performTransition calls occur in a short duration of time.
+			var toWidget = registry.byNode(toNode);
+			if(toWidget){
+				toWidget._inProgress = false;
+			}
 		},
-	
+
 		convertToId: function(moveTo){
 			if(typeof(moveTo) == "string"){
 				// removes a leading hash mark (#) and params if exists
 				// ex. "#bar&myParam=0003" -> "bar"
-				moveTo.match(/^#?([^&?]+)/);
-				return RegExp.$1;
+				return moveTo.replace(/^#?([^&?]+).*/, "$1");
 			}
 			return moveTo;
 		},
-	
-		performTransition: function(/*String*/moveTo, /*Number*/dir, /*String*/transition,
-									/*Object|null*/context, /*String|Function*/method /*optional args*/){
+
+		_isBookmarkable: function(detail){
+			return detail.moveTo && (config['mblForceBookmarkable'] || detail.moveTo.charAt(0) === '#') && !detail.hashchange;
+		},
+
+		performTransition: function(/*String*/moveTo, /*Number*/transitionDir, /*String*/transition,
+									/*Object|null*/context, /*String|Function*/method /*...*/){
 			// summary:
 			//		Function to perform the various types of view transitions, such as fade, slide, and flip.
 			// moveTo: String
 			//		The id of the transition destination view which resides in
 			//		the current page.
 			//		If the value has a hash sign ('#') before the id
-			//		(e.g. #view1) and the dojo.hash module is loaded by the user
+			//		(e.g. #view1) and the dojo/hash module is loaded by the user
 			//		application, the view transition updates the hash in the
 			//		browser URL so that the user can bookmark the destination
 			//		view. In this case, the user can also use the browser's
@@ -218,22 +263,22 @@ define([
 			//		browser history.
 			//		If null, transitions to a blank view.
 			//		If '#', returns immediately without transition.
-			// dir: Number
+			// transitionDir: Number
 			//		The transition direction. If 1, transition forward. If -1, transition backward.
-			//		For example, the slide transition slides the view from right to left when dir == 1,
-			//		and from left to right when dir == -1.
+			//		For example, the slide transition slides the view from right to left when transitionDir == 1,
+			//		and from left to right when transitionDir == -1.
 			// transition: String
 			//		A type of animated transition effect. You can choose from
 			//		the standard transition types, "slide", "fade", "flip", or
 			//		from the extended transition types, "cover", "coverv",
-			//		"dissolve", "reveal", "revealv", "scaleIn",
-			//		"scaleOut", "slidev", "swirl", "zoomIn", "zoomOut". If
-			//		"none" is specified, transition occurs immediately without
-			//		animation.
+			//		"dissolve", "reveal", "revealv", "scaleIn", "scaleOut",
+			//		"slidev", "swirl", "zoomIn", "zoomOut", "cube", and
+			//		"swap". If "none" is specified, transition occurs
+			//		immediately without animation.
 			// context: Object
 			//		The object that the callback function will receive as "this".
 			// method: String|Function
-			//		A callback function that is called when the transition has been finished.
+			//		A callback function that is called when the transition has finished.
 			//		A function reference, or name of a function in context.
 			// tags:
 			//		public
@@ -245,130 +290,142 @@ define([
 			// example:
 			//		Transition forward to a blank view, and then open another page.
 			//	|	performTransition(null, 1, "slide", null, function(){location.href = href;});
-			if(moveTo === "#"){ return; }
-			if(dojo.hash){
-				if(typeof(moveTo) == "string" && moveTo.charAt(0) == '#' && !dm._params){
-					dm._params = [];
-					for(var i = 0; i < arguments.length; i++){
-						dm._params.push(arguments[i]);
-					}
-					dojo.hash(moveTo);
-					return;
+
+			if(this._inProgress){ return; } // transition is in progress
+			this._inProgress = true;
+			
+			// normalize the arg
+			var detail, optArgs;
+			if(moveTo && typeof(moveTo) === "object"){
+				detail = moveTo;
+				optArgs = transitionDir; // array
+			}else{
+				detail = {
+					moveTo: moveTo,
+					transitionDir: transitionDir,
+					transition: transition,
+					context: context,
+					method: method
+				};
+				optArgs = [];
+				for(var i = 5; i < arguments.length; i++){
+					optArgs.push(arguments[i]);
 				}
 			}
-			this._saveState.apply(this, arguments);
+
+			// save the parameters
+			this._detail = detail;
+			this._optArgs = optArgs;
+			this._arguments = [
+				detail.moveTo,
+				detail.transitionDir,
+				detail.transition,
+				detail.context,
+				detail.method
+			];
+
+			if(detail.moveTo === "#"){ return; }
 			var toNode;
-			if(moveTo){
-				toNode = this.convertToId(moveTo);
+			if(detail.moveTo){
+				toNode = this.convertToId(detail.moveTo);
 			}else{
 				if(!this._dummyNode){
-					this._dummyNode = win.doc.createElement("DIV");
+					this._dummyNode = win.doc.createElement("div");
 					win.body().appendChild(this._dummyNode);
 				}
 				toNode = this._dummyNode;
 			}
+
+			if(this.addTransitionInfo && typeof(detail.moveTo) == "string" && this._isBookmarkable(detail)){
+				this.addTransitionInfo(this.id, detail.moveTo, {transitionDir:detail.transitionDir, transition:detail.transition});
+			}
+
 			var fromNode = this.domNode;
 			var fromTop = fromNode.offsetTop;
 			toNode = this.toNode = dom.byId(toNode);
-			if(!toNode){ console.log("dojox.mobile.View#performTransition: destination view not found: "+moveTo); return; }
-			toNode.style.visibility = this._aw ? "visible" : "hidden";
+			if(!toNode){ console.log("dojox/mobile/View.performTransition: destination view not found: "+detail.moveTo); return; }
+			toNode.style.visibility = "hidden";
 			toNode.style.display = "";
 			this._fixViewState(toNode);
 			var toWidget = registry.byNode(toNode);
 			if(toWidget){
 				// Now that the target view became visible, it's time to run resize()
 				if(config["mblAlwaysResizeOnTransition"] || !toWidget._resized){
-					dm.resizeAll(null, toWidget);
+					common.resizeAll(null, toWidget);
 					toWidget._resized = true;
 				}
-	
-				if(transition && transition != "none"){
+
+				if(detail.transition && detail.transition != "none"){
 					// Temporarily add padding to align with the fromNode while transition
-					toWidget.containerNode.style.paddingTop = fromTop + "px";
+					toWidget._addTransitionPaddingTop(fromTop);
 				}
 
+				toWidget.load && toWidget.load(); // for ContentView
+
 				toWidget.movedFrom = fromNode.id;
 			}
-	
-			this.onBeforeTransitionOut.apply(this, arguments);
-			connect.publish("/dojox/mobile/beforeTransitionOut", [this].concat(lang._toArray(arguments)));
+			if(has('mblAndroidWorkaround') && !config['mblCSS3Transition']
+					&& detail.transition && detail.transition != "none"){
+				// workaround for the screen flicker issue on Android 2.2/2.3
+				// apply "-webkit-transform-style:preserve-3d" to both toNode and fromNode
+				// to make them 3d-transition-ready state just before transition animation
+				domStyle.set(toNode, css3.name("transformStyle"), "preserve-3d");
+				domStyle.set(fromNode, css3.name("transformStyle"), "preserve-3d");
+				// show toNode offscreen to avoid flicker when switching "display" and "visibility" styles
+				domClass.add(toNode, "mblAndroidWorkaround");
+			}
+
+			this.onBeforeTransitionOut.apply(this, this._arguments);
+			connect.publish("/dojox/mobile/beforeTransitionOut", [this].concat(lang._toArray(this._arguments)));
 			if(toWidget){
 				// perform view transition keeping the scroll position
 				if(this.keepScrollPos && !this.getParent()){
 					var scrollTop = win.body().scrollTop || win.doc.documentElement.scrollTop || win.global.pageYOffset || 0;
 					fromNode._scrollTop = scrollTop;
-					var toTop = (dir == 1) ? 0 : (toNode._scrollTop || 0);
+					var toTop = (detail.transitionDir == 1) ? 0 : (toNode._scrollTop || 0);
 					toNode.style.top = "0px";
 					if(scrollTop > 1 || toTop !== 0){
 						fromNode.style.top = toTop - scrollTop + "px";
 						if(config["mblHideAddressBar"] !== false){
-							setTimeout(function(){ // iPhone needs setTimeout
+							this.defer(function(){ // iPhone needs setTimeout (via defer)
 								win.global.scrollTo(0, (toTop || 1));
-							}, 0);
+							});
 						}
 					}
 				}else{
 					toNode.style.top = "0px";
 				}
-				toWidget.onBeforeTransitionIn.apply(toWidget, arguments);
-				connect.publish("/dojox/mobile/beforeTransitionIn", [toWidget].concat(lang._toArray(arguments)));
-			}
-			if(!this._aw){
-				toNode.style.display = "none";
-				toNode.style.visibility = "visible";
-			}
-			
-			if(dm._iw && dm.scrollable){ // Workaround for iPhone flicker issue (only when scrollable.js is loaded)
-				var ss = dm.getScreenSize();
-				// Show cover behind the view.
-				// cover's z-index is set to -10000, lower than z-index value specified in transition css.
-				win.body().appendChild(dm._iwBgCover);
-				domStyle.set(dm._iwBgCover, {
-					position: "absolute",
-					top: "0px",
-					left: "0px",
-					height: (ss.h + 1) + "px", // "+1" means the height of scrollTo(0,1)
-					width: ss.w + "px",
-					backgroundColor: domStyle.get(win.body(), "background-color"),
-					zIndex: -10000,
-					display: ""
-				});
-				// Show toNode behind the cover.
-				domStyle.set(toNode, {
-					position: "absolute",
-					zIndex: -10001,
-					visibility: "visible",
-					display: ""
-				});
-				// setTimeout seems to be necessary to avoid flicker.
-				// Also the duration of setTimeout should be long enough to avoid flicker.
-				// 0 is not effective. 50 sometimes causes flicker.
-				setTimeout(lang.hitch(this, function(){
-					this._doTransition(fromNode, toNode, transition, dir);
-				}), 80);
-			}else{
-				this._doTransition(fromNode, toNode, transition, dir);
+				toWidget.onBeforeTransitionIn.apply(toWidget, this._arguments);
+				connect.publish("/dojox/mobile/beforeTransitionIn", [toWidget].concat(lang._toArray(this._arguments)));
 			}
+			toNode.style.display = "none";
+			toNode.style.visibility = "visible";
+
+			common.fromView = this;
+			common.toView = toWidget;
+
+			this._doTransition(fromNode, toNode, detail.transition, detail.transitionDir);
+		},
+
+		_addTransitionPaddingTop: function(/*String|Integer*/ value){
+			// add padding top to the view in order to get alignment during the transition
+			this.containerNode.style.paddingTop = value + "px";
 		},
+
+		_removeTransitionPaddingTop: function(){
+			// remove padding top from the view after the transition
+			this.containerNode.style.paddingTop = "";
+		},
+
 		_toCls: function(s){
 			// convert from transition name to corresponding class name
 			// ex. "slide" -> "mblSlide"
 			return "mbl"+s.charAt(0).toUpperCase() + s.substring(1);
 		},
-	
-		_doTransition: function(fromNode, toNode, transition, dir){
-			var rev = (dir == -1) ? " mblReverse" : "";
-			if(dm._iw && dm.scrollable){ // Workaround for iPhone flicker issue (only when scrollable.js is loaded)
-				// Show toNode after flicker ends
-				domStyle.set(toNode, {
-					position: "",
-					zIndex: ""
-				});
-				// Remove cover
-				win.body().removeChild(dm._iwBgCover);
-			}else if(!this._aw){
-				toNode.style.display = "";
-			}
+
+		_doTransition: function(fromNode, toNode, transition, transitionDir){
+			var rev = (transitionDir == -1) ? " mblReverse" : "";
+			toNode.style.display = "";
 			if(!transition || transition == "none"){
 				this.domNode.style.display = "none";
 				this.invokeCallback();
@@ -379,19 +436,44 @@ define([
 					//need to set the toNode to absolute position
 					var toPosition = domStyle.get(toNode, "position");
 					domStyle.set(toNode, "position", "absolute");
-					Deferred.when(transit(fromNode, toNode, {transition: transition, reverse: (dir===-1)?true:false}),lang.hitch(this,function(){
+					Deferred.when(transit(fromNode, toNode, {transition: transition, reverse: (transitionDir===-1)?true:false}),lang.hitch(this,function(){
 						domStyle.set(toNode, "position", toPosition);
+						// Reset the temporary padding on toNode
+						toNode.style.paddingTop = "";
 						this.invokeCallback();
 					}));
 				}));
 			}else{
+				if(transition.indexOf("cube") != -1){
+					if(has('ipad')){
+						domStyle.set(toNode.parentNode, {webkitPerspective:1600});
+					}else if(has("ios")){
+						domStyle.set(toNode.parentNode, {webkitPerspective:800});
+					}
+				}
 				var s = this._toCls(transition);
-				domClass.add(fromNode, s + " mblOut" + rev);
-				domClass.add(toNode, s + " mblIn" + rev);
-				setTimeout(function(){
-					domClass.add(fromNode, "mblTransition");
-					domClass.add(toNode, "mblTransition");
-				}, 100);
+				if(has('mblAndroidWorkaround')){
+					// workaround for the screen flicker issue on Android 2.2
+					// applying transition css classes just after setting toNode.style.display = ""
+					// causes flicker, so wait for a while using setTimeout (via defer)
+					var _this = this;
+					_this.defer(function(){
+						domClass.add(fromNode, s + " mblOut" + rev);
+						domClass.add(toNode, s + " mblIn" + rev);
+						domClass.remove(toNode, "mblAndroidWorkaround"); // remove offscreen style
+						_this.defer(function(){
+							domClass.add(fromNode, "mblTransition");
+							domClass.add(toNode, "mblTransition");
+						}, 30); // 30 = 100 - 70, to make total delay equal to 100ms
+					}, 70); // 70ms is experiential value
+				}else{
+					domClass.add(fromNode, s + " mblOut" + rev);
+					domClass.add(toNode, s + " mblIn" + rev);
+					this.defer(function(){
+						domClass.add(fromNode, "mblTransition");
+						domClass.add(toNode, "mblTransition");
+					}, 100);
+				}
 				// set transform origin
 				var fromOrigin = "50% 50%";
 				var toOrigin = "50% 50%";
@@ -417,17 +499,19 @@ define([
 					fromOrigin = posX + "px " + posY + "px";
 					toOrigin = posX + "px " + posY + "px";
 				}
-				domStyle.set(fromNode, {webkitTransformOrigin:fromOrigin});
-				domStyle.set(toNode, {webkitTransformOrigin:toOrigin});
+				domStyle.set(fromNode, css3.add({}, {transformOrigin:fromOrigin}));
+				domStyle.set(toNode, css3.add({}, {transformOrigin:toOrigin}));
 			}
-			dm.currentView = registry.byNode(toNode);
 		},
-	
+
 		onAnimationStart: function(e){
+			// summary:
+			//		A handler that is called when transition animation starts.
 		},
 
-
 		onAnimationEnd: function(e){
+			// summary:
+			//		A handler that is called after transition animation ends.
 			var name = e.animationName || e.target.className;
 			if(name.indexOf("Out") === -1 &&
 				name.indexOf("In") === -1 &&
@@ -436,29 +520,40 @@ define([
 			if(domClass.contains(this.domNode, "mblOut")){
 				isOut = true;
 				this.domNode.style.display = "none";
-				domClass.remove(this.domNode, [this._toCls(this._transition), "mblIn", "mblOut", "mblReverse"]);
+				domClass.remove(this.domNode, [this._toCls(this._detail.transition), "mblIn", "mblOut", "mblReverse"]);
 			}else{
 				// Reset the temporary padding
-				this.containerNode.style.paddingTop = "";
+				this._removeTransitionPaddingTop();
 			}
-			domStyle.set(this.domNode, {webkitTransformOrigin:""});
+			domStyle.set(this.domNode, css3.add({}, {transformOrigin:""}));
 			if(name.indexOf("Shrink") !== -1){
 				var li = e.target;
 				li.style.display = "none";
 				domClass.remove(li, "mblCloseContent");
+
+				// If target is placed inside scrollable, need to call onTouchEnd
+				// to adjust scroll position
+				var p = viewRegistry.getEnclosingScrollable(this.domNode);
+				p && p.onTouchEnd();
 			}
 			if(isOut){
 				this.invokeCallback();
 			}
-			// this.domNode may be destroyed as a result of invoking the callback,
-			// so check for that before accessing it.
-			this.domNode && (this.domNode.className = "mblView");
+			this._clearClasses(this.domNode);
 
 			// clear the clicked position
 			this.clickedPosX = this.clickedPosY = undefined;
+
+			if(name.indexOf("Cube") !== -1 &&
+				name.indexOf("In") !== -1 && has("ios")){
+				this.domNode.parentNode.style[css3.name("perspective")] = "";
+			}
 		},
 
 		invokeCallback: function(){
+			// summary:
+			//		A function to be called after performing a transition to
+			//		call a specified callback.
 			this.onAfterTransitionOut.apply(this, this._arguments);
 			connect.publish("/dojox/mobile/afterTransitionOut", [this].concat(this._arguments));
 			var toWidget = registry.byNode(this.toNode);
@@ -466,47 +561,119 @@ define([
 				toWidget.onAfterTransitionIn.apply(toWidget, this._arguments);
 				connect.publish("/dojox/mobile/afterTransitionIn", [toWidget].concat(this._arguments));
 				toWidget.movedFrom = undefined;
+				if(this.setFragIds && this._isBookmarkable(this._detail)){
+					this.setFragIds(toWidget); // setFragIds is defined in bookmarkable.js
+				}
+			}
+			if(has('mblAndroidWorkaround')){
+				// workaround for the screen flicker issue on Android 2.2/2.3
+				// remove "-webkit-transform-style" style after transition finished
+				// to avoid side effects such as input field auto-scrolling issue
+				// use setTimeout (via defer) to avoid flicker in case of ScrollableView
+				this.defer(function(){
+					if(toWidget){ domStyle.set(this.toNode, css3.name("transformStyle"), ""); }
+					domStyle.set(this.domNode, css3.name("transformStyle"), "");
+				});
 			}
 
-			var c = this._context, m = this._method;
-			if(!c && !m){ return; }
-			if(!m){
-				m = c;
-				c = null;
+			var c = this._detail.context, m = this._detail.method;
+			if(c || m){
+				if(!m){
+					m = c;
+					c = null;
+				}
+				c = c || win.global;
+				if(typeof(m) == "string"){
+					c[m].apply(c, this._optArgs);
+				}else if(typeof(m) == "function"){
+					m.apply(c, this._optArgs);
+				}
 			}
-			c = c || win.global;
-			if(typeof(m) == "string"){
-				c[m].apply(c, this._args);
+			this._detail = this._optArgs = this._arguments = undefined;
+			this._inProgress = false;
+		},
+
+		isVisible: function(/*Boolean?*/checkAncestors){
+			// summary:
+			//		Return true if this view is visible
+			// checkAncestors:
+			//		If true, in addition to its own visibility, also checks the
+			//		ancestors visibility to see if the view is actually being
+			//		shown or not.
+			var visible = function(node){
+				return domStyle.get(node, "display") !== "none";
+			};
+			if(checkAncestors){
+				for(var n = this.domNode; n.tagName !== "BODY"; n = n.parentNode){
+					if(!visible(n)){ return false; }
+				}
+				return true;
 			}else{
-				m.apply(c, this._args);
+				return visible(this.domNode);
 			}
 		},
-	
+
 		getShowingView: function(){
 			// summary:
 			//		Find the currently showing view from my sibling views.
 			// description:
-			//		Note that dojox.mobile.currentView is the last shown view.
-			//		If the page consists of a splitter, there are multiple showing views.
+			//		Note that depending on the ancestor views' visibility,
+			//		the found view may not be actually shown.
 			var nodes = this.domNode.parentNode.childNodes;
 			for(var i = 0; i < nodes.length; i++){
 				var n = nodes[i];
-				if(n.nodeType === 1 && domClass.contains(n, "mblView") && domStyle.get(n, "display") !== "none"){
+				if(n.nodeType === 1 && domClass.contains(n, "mblView") && n.style.display !== "none"){
 					return registry.byNode(n);
 				}
 			}
 			return null;
 		},
-	
-		show: function(){
+
+		getSiblingViews: function(){
+			// summary:
+			//		Returns an array of the sibling views.
+			if(!this.domNode.parentNode){ return [this]; }
+			return array.map(array.filter(this.domNode.parentNode.childNodes,
+				function(n){ return n.nodeType === 1 && domClass.contains(n, "mblView"); }),
+				function(n){ return registry.byNode(n); });
+		},
+
+		show: function(/*Boolean?*/noEvent, /*Boolean?*/doNotHideOthers){
 			// summary:
 			//		Shows this view without a transition animation.
-			var view = this.getShowingView();
-			if(view){
-				view.domNode.style.display = "none"; // from-style
+			var out = this.getShowingView();
+			if(!noEvent){
+				if(out){
+					out.onBeforeTransitionOut(out.id);
+					connect.publish("/dojox/mobile/beforeTransitionOut", [out, out.id]);
+				}
+				this.onBeforeTransitionIn(this.id);
+				connect.publish("/dojox/mobile/beforeTransitionIn", [this, this.id]);
+			}
+
+			if(doNotHideOthers){
+				this.domNode.style.display = "";
+			}else{
+				array.forEach(this.getSiblingViews(), function(v){
+					v.domNode.style.display = (v === this) ? "" : "none";
+				}, this);
+			}
+			this.load && this.load(); // for ContentView
+
+			if(!noEvent){
+				if(out){
+					out.onAfterTransitionOut(out.id);
+					connect.publish("/dojox/mobile/afterTransitionOut", [out, out.id]);
+				}
+				this.onAfterTransitionIn(this.id);
+				connect.publish("/dojox/mobile/afterTransitionIn", [this, this.id]);
 			}
-			this.domNode.style.display = ""; // to-style
-			dm.currentView = this;
+		},
+
+		hide: function(){
+			// summary:
+			//		Hides this view without a transition animation.
+			this.domNode.style.display = "none";
 		}
 	});
 });
diff --git a/dojox/mobile/ViewController.js b/dojox/mobile/ViewController.js
index 8266cfe..dcef712 100644
--- a/dojox/mobile/ViewController.js
+++ b/dojox/mobile/ViewController.js
@@ -5,259 +5,249 @@ define([
 	"dojo/_base/declare",
 	"dojo/_base/lang",
 	"dojo/_base/window",
+	"dojo/_base/Deferred",
 	"dojo/dom",
 	"dojo/dom-class",
 	"dojo/dom-construct",
-//	"dojo/hash", // optionally prereq'ed
 	"dojo/on",
 	"dojo/ready",
-	"dijit/registry",	// registry.byId
+	"dijit/registry",
 	"./ProgressIndicator",
-	"./TransitionEvent"
-], function(dojo, array, connect, declare, lang, win, dom, domClass, domConstruct, on, ready, registry, ProgressIndicator, TransitionEvent){
+	"./TransitionEvent",
+	"./viewRegistry"
+], function(dojo, array, connect, declare, lang, win, Deferred, dom, domClass, domConstruct, on, ready, registry, ProgressIndicator, TransitionEvent, viewRegistry){
 
 	// module:
 	//		dojox/mobile/ViewController
-	// summary:
-	//		A singleton class that controlls view transition.
-
-	var dm = lang.getObject("dojox.mobile", true);
 
 	var Controller = declare("dojox.mobile.ViewController", null, {
 		// summary:
-		//		A singleton class that controlls view transition.
+		//		A singleton class that controls view transition.
 		// description:
 		//		This class listens to the "startTransition" events and performs
 		//		view transitions. If the transition destination is an external
-		//		view specified with the url parameter, retrieves the view
-		//		content and parses it to create a new target view.
+		//		view specified with the url parameter, the view content is
+		//		retrieved and parsed to create a new target view.
+
+		// dataHandlerClass: Object
+		//		The data handler class used to load external views,
+		//		by default "dojox/mobile/dh/DataHandler"
+		//		(see the Data Handlers page in the reference documentation).
+		dataHandlerClass: "dojox/mobile/dh/DataHandler",
+		// dataSourceClass: Object
+		//		The data source class used to load external views,
+		//		by default "dojox/mobile/dh/UrlDataSource"
+		//		(see the Data Handlers page in the reference documentation).
+		dataSourceClass: "dojox/mobile/dh/UrlDataSource",
+		// fileTypeMapClass: Object
+		//		The file type map class used to load external views,
+		//		by default "dojox/mobile/dh/SuffixFileTypeMap"
+		//		(see the Data Handlers page in the reference documentation).
+		fileTypeMapClass: "dojox/mobile/dh/SuffixFileTypeMap",
 
 		constructor: function(){
-			this.viewMap={};
-			this.currentView=null;
-			this.defaultView=null;
+			// summary:
+			//		Creates a new instance of the class.
+			// tags:
+			//		private
+			this.viewMap = {};
 			ready(lang.hitch(this, function(){
 				on(win.body(), "startTransition", lang.hitch(this, "onStartTransition"));
 			}));
 		},
 
-		findCurrentView: function(moveTo,src){
+		findTransitionViews: function(/*String*/moveTo){
 			// summary:
-			//		Searches for the currently showing view.
-			if(moveTo){
-				var w = registry.byId(moveTo);
-				if(w && w.getShowingView){ return w.getShowingView(); }
-			}
-			if(dm.currentView){
-				return dm.currentView; //TODO:1.8 may not return an expected result especially when views are nested
-			}
-			//TODO:1.8 probably never reaches here
-			w = src;
-			while(true){
-				w = w.getParent();
-				if(!w){ return null; }
-				if(domClass.contains(w.domNode, "mblView")){ break; }
+			//		Parses the moveTo argument and determines a starting view and a destination view.
+			// returns: Array
+			//		An array containing the currently showing view, the destination view
+			//		and the transition parameters, or an empty array if the moveTo argument
+			//		could not be parsed. 
+			if(!moveTo){ return []; }
+			// removes a leading hash mark (#) and params if exists
+			// ex. "#bar&myParam=0003" -> "bar"
+			moveTo.match(/^#?([^&?]+)(.*)/);
+			var params = RegExp.$2;
+			var view = registry.byId(RegExp.$1);
+			if(!view){ return []; }
+			for(var v = view.getParent(); v; v = v.getParent()){ // search for the topmost invisible parent node
+				if(v.isVisible && !v.isVisible()){
+					var sv = view.getShowingView();
+					if(sv && sv.id !== view.id){
+						view.show();
+					}
+					view = v;
+				}
 			}
-			return w;
+			return [view.getShowingView(), view, params]; // fromView, toView, params
 		},
 
-		onStartTransition: function(evt){
+		openExternalView: function(/*Object*/ transOpts, /*DomNode*/ target){
 			// summary:
-			//		A handler that performs view transition.
+			//		Loads an external view and performs a transition to it.
+			// returns: dojo/_base/Deferred
+			//		Deferred object that resolves when the external view is
+			//		ready and a transition starts. Note that it resolves before
+			//		the transition is complete.
+			// description:
+			//		This method loads external view content through the
+			//		dojox/mobile data handlers, creates a new View instance with
+			//		the loaded content, and performs a view transition to the
+			//		new view. The external view content can be specified with
+			//		the url property of transOpts. The new view is created under
+			//		a DOM node specified by target.
+			//
+			// example:
+			//		This example loads view1.html, creates a new view under
+			//		`<body>`, and performs a transition to the new view with the
+			//		slide animation.
+			//		
+			//	|	var vc = ViewController.getInstance();
+			//	|	vc.openExternalView({
+			//	|	    url: "view1.html", 
+			//	|	    transition: "slide"
+			//	|	}, win.body());
+			//
+			//
+			// example:
+			//		If you want to perform a view transition without animation,
+			//		you can give transition:"none" to transOpts.
+			//
+			//	|	var vc = ViewController.getInstance();
+			//	|	vc.openExternalView({
+			//	|	    url: "view1.html", 
+			//	|	    transition: "none"
+			//	|	}, win.body());
+			//
+			// example:
+			//		If you want to dynamically create an external view, but do
+			//		not want to perform a view transition to it, you can give noTransition:true to transOpts.
+			//		This may be useful when you want to preload external views before the user starts using them.
+			//
+			//	|	var vc = ViewController.getInstance();
+			//	|	vc.openExternalView({
+			//	|	    url: "view1.html", 
+			//	|	    noTransition: true
+			//	|	}, win.body());
+			//
+			// example:
+			//		To do something when the external view is ready:
+			//
+			//	|	var vc = ViewController.getInstance();
+			//	|	Deferred.when(vc.openExternalView({...}, win.body()), function(){
+			//	|	    doSomething();
+			//	|	});
 
-			evt.preventDefault();
-			if(!evt.detail || (evt.detail && !evt.detail.moveTo && !evt.detail.href && !evt.detail.url && !evt.detail.scene)){ return; }
-			var w = this.findCurrentView(evt.detail.moveTo, (evt.target && evt.target.id)?registry.byId(evt.target.id):registry.byId(evt.target)); // the current view widget
-			if(!w || (evt.detail && evt.detail.moveTo && w === registry.byId(evt.detail.moveTo))){ return; }
-			if(evt.detail.href){
-				var t = registry.byId(evt.target.id).hrefTarget;
-				if(t){
-					dm.openWindow(evt.detail.href, t);
-				}else{
-					w.performTransition(null, evt.detail.transitionDir, evt.detail.transition, evt.target, function(){location.href = evt.detail.href;});
-				}
-				return;
-			} else if(evt.detail.scene){
-				connect.publish("/dojox/mobile/app/pushScene", [evt.detail.scene]);
-				return;
-			}
-			var moveTo = evt.detail.moveTo;
-			if(evt.detail.url){
-				var id;
-				if(dm._viewMap && dm._viewMap[evt.detail.url]){
-					// external view has already been loaded
-					id = dm._viewMap[evt.detail.url];
+			var d = new Deferred();
+			var id = this.viewMap[transOpts.url];
+			if(id){
+				transOpts.moveTo = id;
+				if(transOpts.noTransition){
+					registry.byId(id).hide();
 				}else{
-					// get the specified external view and append it to the <body>
-					var text = this._text;
-					if(!text){
-						if(registry.byId(evt.target.id).sync){
-							// We do not add explicit dependency on dojo/_base/xhr to this module
-							// to be able to create a build that does not contain dojo/_base/xhr.
-							// User applications that do sync loading here need to explicitly
-							// require dojo/_base/xhr up front.
-							dojo.xhrGet({url:evt.detail.url, sync:true, load:function(result){
-								text = lang.trim(result);
-							}});
-						}else{
-							var s = "dojo/_base/xhr"; // assign to a variable so as not to be picked up by the build tool
-							require([s], lang.hitch(this, function(xhr){
-								var prog = ProgressIndicator.getInstance();
-								win.body().appendChild(prog.domNode);
-								prog.start();
-								var obj = xhr.get({
-									url: evt.detail.url,
-									handleAs: "text"
-								});
-								obj.addCallback(lang.hitch(this, function(response, ioArgs){
-									prog.stop();
-									if(response){
-										this._text = response;
-										new TransitionEvent(evt.target, {
-												transition: evt.detail.transition,
-											 	transitionDir: evt.detail.transitionDir,
-											 	moveTo: moveTo,
-											 	href: evt.detail.href,
-											 	url: evt.detail.url,
-											 	scene: evt.detail.scene},
-											 		evt.detail)
-											 			.dispatch();
-									}
-								}));
-								obj.addErrback(function(error){
-									prog.stop();
-									console.log("Failed to load "+evt.detail.url+"\n"+(error.description||error));
-								});
-							}));
-							return;
-						}
-					}
-					this._text = null;
-					id = this._parse(text, registry.byId(evt.target.id).urlTarget);
-					if(!dm._viewMap){
-						dm._viewMap = [];
-					}
-					dm._viewMap[evt.detail.url] = id;
+					new TransitionEvent(win.body(), transOpts).dispatch();
 				}
-				moveTo = id;
-				w = this.findCurrentView(moveTo,registry.byId(evt.target.id)) || w; // the current view widget
+				d.resolve(true);
+				return d;
 			}
-			w.performTransition(moveTo, evt.detail.transitionDir, evt.detail.transition, null, null);
-		},
 
-		_parse: function(text, id){
-			// summary:
-			//		Parses the given view content.
-			// description:
-			//		If the content is html fragment, constructs dom tree with it
-			//		and runs the parser. If the content is json data, passes it
-			//		to _instantiate().
-			var container, view, i, j, len;
-			var currentView	 = this.findCurrentView();
-			var target = registry.byId(id) && registry.byId(id).containerNode
-						|| dom.byId(id)
-						|| currentView && currentView.domNode.parentNode
-						|| win.body();
 			// if a fixed bottom bar exists, a new view should be placed before it.
 			var refNode = null;
-			for(j = target.childNodes.length - 1; j >= 0; j--){
-				var c = target.childNodes[j];
+			for(var i = target.childNodes.length - 1; i >= 0; i--){
+				var c = target.childNodes[i];
 				if(c.nodeType === 1){
-					if(c.getAttribute("fixed") === "bottom"){
+					var fixed = c.getAttribute("fixed") // TODO: Remove the non-HTML5-compliant attribute in 2.0
+						|| c.getAttribute("data-mobile-fixed")
+						|| (registry.byNode(c) && registry.byNode(c).fixed);
+					if(fixed === "bottom"){
 						refNode = c;
-					}
-					break;
-				}
-			}
-			if(text.charAt(0) === "<"){ // html markup
-				container = domConstruct.create("DIV", {innerHTML: text});
-				for(i = 0; i < container.childNodes.length; i++){
-					var n = container.childNodes[i];
-					if(n.nodeType === 1){
-						view = n; // expecting <div dojoType="dojox.mobile.View">
 						break;
 					}
 				}
-				if(!view){
-					console.log("dojox.mobile.ViewController#_parse: invalid view content");
-					return;
-				}
-				view.style.visibility = "hidden";
-				target.insertBefore(container, refNode);
-				var ws = dojo.parser.parse(container);
-				array.forEach(ws, function(w){
-					if(w && !w._started && w.startup){
-						w.startup();
-					}
-				});
-
-				// allows multiple root nodes in the fragment,
-				// but transition will be performed to the 1st view.
-				for(i = 0, len = container.childNodes.length; i < len; i++){
-					target.insertBefore(container.firstChild, refNode); // reparent
-				}
-				target.removeChild(container);
-
-				registry.byNode(view)._visible = true;
-			}else if(text.charAt(0) === "{"){ // json
-				container = domConstruct.create("DIV");
-				target.insertBefore(container, refNode);
-				this._ws = [];
-				view = this._instantiate(eval('('+text+')'), container);
-				for(i = 0; i < this._ws.length; i++){
-					var w = this._ws[i];
-					w.startup && !w._started && (!w.getParent || !w.getParent()) && w.startup();
-				}
-				this._ws = null;
 			}
-			view.style.display = "none";
-			view.style.visibility = "visible";
-			return dojo.hash ? "#" + view.id : view.id;
-		},
 
-		_instantiate: function(/*Object*/obj, /*DomNode*/node, /*Widget*/parent){
-			// summary:
-			//		Given the evaluated json data, does the same thing as what
-			//		the parser does.
-			var widget;
-			for(var key in obj){
-				if(key.charAt(0) == "@"){ continue; }
-				var cls = lang.getObject(key);
-				if(!cls){ continue; }
-				var params = {};
-				var proto = cls.prototype;
-				var objs = lang.isArray(obj[key]) ? obj[key] : [obj[key]];
-				for(var i = 0; i < objs.length; i++){
-					for(var prop in objs[i]){
-						if(prop.charAt(0) == "@"){
-							var val = objs[i][prop];
-							prop = prop.substring(1);
-							if(typeof proto[prop] == "string"){
-								params[prop] = val;
-							}else if(typeof proto[prop] == "number"){
-								params[prop] = val - 0;
-							}else if(typeof proto[prop] == "boolean"){
-							params[prop] = (val != "false");
-							}else if(typeof proto[prop] == "object"){
-								params[prop] = eval("(" + val + ")");
-							}
+			var dh = transOpts.dataHandlerClass || this.dataHandlerClass;
+			var ds = transOpts.dataSourceClass || this.dataSourceClass;
+			var ft = transOpts.fileTypeMapClass || this.fileTypeMapClass;
+			require([dh, ds, ft], lang.hitch(this, function(DataHandler, DataSource, FileTypeMap){
+				var handler = new DataHandler(new DataSource(transOpts.data || transOpts.url), target, refNode);
+				var contentType = transOpts.contentType || FileTypeMap.getContentType(transOpts.url) || "html";
+				handler.processData(contentType, lang.hitch(this, function(id){
+					if(id){
+						this.viewMap[transOpts.url] = transOpts.moveTo = id;
+						if(transOpts.noTransition){
+							registry.byId(id).hide();
+						}else{
+							new TransitionEvent(win.body(), transOpts).dispatch();
 						}
+						d.resolve(true);
+					}else{
+						d.reject("Failed to load "+transOpts.url);
 					}
-					widget = new cls(params, node);
-					if(node){ // to call View's startup()
-						widget._visible = true;
-						this._ws.push(widget);
+				}));
+			}));
+			return d;
+		},
+
+		onStartTransition: function(evt){
+			// summary:
+			//		A handler that performs view transition.
+			evt.preventDefault();
+			if(!evt.detail){ return; }
+			var detail = evt.detail;
+			if(!detail.moveTo && !detail.href && !detail.url && !detail.scene){ return; }
+
+			if(detail.url && !detail.moveTo){
+				var urlTarget = detail.urlTarget;
+				var w = registry.byId(urlTarget);
+				var target = w && w.containerNode || dom.byId(urlTarget);
+				if(!target){
+					w = viewRegistry.getEnclosingView(evt.target);
+					target = w && w.domNode.parentNode || win.body();
+				}
+				this.openExternalView(detail, target);
+				return;
+			}else if(detail.href){
+				if(detail.hrefTarget && detail.hrefTarget != "_self"){
+					win.global.open(detail.href, detail.hrefTarget);
+				}else{
+					var view; // find top level visible view
+					for(var v = viewRegistry.getEnclosingView(evt.target); v; v = viewRegistry.getParentView(v)){
+						view = v;
 					}
-					if(parent && parent.addChild){
-						parent.addChild(widget);
+					if(view){
+						view.performTransition(null, detail.transitionDir, detail.transition, evt.target, function(){location.href = detail.href;});
 					}
-					this._instantiate(objs[i], null, widget);
 				}
+				return;
+			}else if(detail.scene){
+				connect.publish("/dojox/mobile/app/pushScene", [detail.scene]);
+				return;
+			}
+
+			var arr = this.findTransitionViews(detail.moveTo),
+				fromView = arr[0],
+				toView = arr[1],
+				params = arr[2];
+			if(!location.hash && !detail.hashchange){
+				viewRegistry.initialView = fromView;
+			}
+			if(detail.moveTo && toView){
+				detail.moveTo = (detail.moveTo.charAt(0) === '#' ? '#' + toView.id : toView.id) + params;
+			}
+			if(!fromView || (detail.moveTo && fromView === registry.byId(detail.moveTo.replace(/^#?([^&?]+).*/, "$1")))){ return; }
+			var src = registry.getEnclosingWidget(evt.target);
+			if(src && src.callback){
+				detail.context = src;
+				detail.method = src.callback;
 			}
-			return widget && widget.domNode;
+			fromView.performTransition(detail);
 		}
 	});
-	new Controller(); // singleton
+	Controller._instance = new Controller(); // singleton
+	Controller.getInstance = function(){
+		return Controller._instance;
+	};
 	return Controller;
 });
 
diff --git a/dojox/mobile/_ComboBoxMenu.js b/dojox/mobile/_ComboBoxMenu.js
index eaf7f69..da8c4e2 100644
--- a/dojox/mobile/_ComboBoxMenu.js
+++ b/dojox/mobile/_ComboBoxMenu.js
@@ -5,26 +5,31 @@ define([
 	"dojo/dom-construct",
 	"dijit/form/_ComboBoxMenuMixin",
 	"dijit/_WidgetBase",
-	"dojox/mobile/_ListTouchMixin",
-	"./scrollable"
+	"./_ListTouchMixin",
+	"./scrollable",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/_ComboBoxMenu"
 ],
-	function(dojo, declare, domClass, domConstruct, ComboBoxMenuMixin, WidgetBase, ListTouchMixin, Scrollable){
+	function(dojo, declare, domClass, domConstruct, ComboBoxMenuMixin, WidgetBase, ListTouchMixin, Scrollable, has, BidiComboBoxMenu){
+	// module:
+	//		dojox/mobile/_ComboBoxMenu
 
-	/*=====
-		ComboBoxMenuMixin = dijit.form._ComboBoxMenuMixin;
-		WidgetBase = dijit._WidgetBase;
-		ListTouchMixin = dojox.mobile._ListTouchMixin;
-	=====*/
-	return declare("dojox.mobile._ComboBoxMenu", [WidgetBase, ListTouchMixin, ComboBoxMenuMixin], {
+	var _ComboBoxMenu = declare(has("dojo-bidi") ? "dojox.mobile._NonBidiComboBoxMenu" : "dojox.mobile._ComboBoxMenu", [WidgetBase, ListTouchMixin, ComboBoxMenuMixin], {
 		// summary:
-		//		Focus-less menu for internal use in `dijit.form.ComboBox`
+		//		Focus-less menu for internal use in dojox/mobile/ComboBox.
 		//		Abstract methods that must be defined externally:
-		//			onChange: item was explicitly chosen (mousedown somewhere on the menu and mouseup somewhere on the menu)
-		//			onPage: next(1) or previous(-1) button pressed
+		//
+		//		- onChange: item was explicitly chosen (mousedown somewhere on the menu and mouseup somewhere on the menu);
+		//		- onPage: next(1) or previous(-1) button pressed.
 		// tags:
 		//		private
 
+		// baseClass: String
+		//		The name of the CSS class of this widget.
 		baseClass: "mblComboBoxMenu",
+		
+		// bgIframe: [private] Boolean
+		//		Flag to prevent the creation of a background iframe, when appropriate. For internal usage. 
 		bgIframe: true, // so it's not created for IE and FF
 
 		buildRendering: function(){
@@ -36,6 +41,7 @@ define([
 		},
 
 		_createMenuItem: function(){
+			// override of the method from dijit/form/_ComboBoxMenu.
 			return domConstruct.create("div", {
 				"class": "mblReset mblComboBoxMenuItem" +(this.isLeftToRight() ? "" : " mblComboBoxMenuItemRtl"),
 				role: "option"
@@ -44,17 +50,19 @@ define([
 
 		onSelect: function(/*DomNode*/ node){
 			// summary:
-			//		Add selected CSS
+			//		Add selected CSS.
 			domClass.add(node, "mblComboBoxMenuItemSelected");
 		},
 
 		onDeselect: function(/*DomNode*/ node){
 			// summary:
-			//		Remove selected CSS
+			//		Remove selected CSS.
 			domClass.remove(node, "mblComboBoxMenuItemSelected");
 		},
 
 		onOpen: function(){
+			// summary:
+			//		Called when the menu opens.
 			this.scrollable.init({
 				domNode: this.domNode,
 				containerNode: this.containerNode
@@ -63,6 +71,8 @@ define([
 		},
 
 		onClose: function(){
+			// summary:
+			//		Called when the menu closes.
 			this.scrollable.cleanup();
 		},
 
@@ -73,9 +83,9 @@ define([
 
 		postCreate: function(){
 			this.inherited(arguments);
-			this.scrollable = new Scrollable(dojo, dojox);
+			this.scrollable = new Scrollable();
 			this.scrollable.resize = function(){}; // resize changes the height rudely
-			this.scrollable.androidWorkaroud = false; // disable Android workaround
 		}
 	});
+	return has("dojo-bidi") ? declare("dojox.mobile._ComboBoxMenu", [_ComboBoxMenu, BidiComboBoxMenu]) : _ComboBoxMenu;
 });
diff --git a/dojox/mobile/_ContentPaneMixin.js b/dojox/mobile/_ContentPaneMixin.js
new file mode 100644
index 0000000..316ef08
--- /dev/null
+++ b/dojox/mobile/_ContentPaneMixin.js
@@ -0,0 +1,130 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/Deferred",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/_base/xhr",
+	"./_ExecScriptMixin",
+	"./ProgressIndicator",
+	"./lazyLoadUtils"
+], function(declare, Deferred, lang, win, xhr, ExecScriptMixin, ProgressIndicator, lazyLoadUtils){
+
+	// module:
+	//		dojox/mobile/_ContentPaneMixin
+
+	return declare("dojox.mobile._ContentPaneMixin", ExecScriptMixin, {
+		// summary:
+		//		Mixin for a very simple content pane to embed an HTML fragment.
+		// description:
+		//		By mixing this class into a widget, the widget can have the ability
+		//		to embed an external HTML fragment and to run the parser.
+
+		// href: String
+		//		URL of the content to embed.
+		href: "",
+
+		// lazy: String
+		//		If true, external content specified with the href property is
+		//		not loaded at startup time. It can be loaded by calling load().
+		lazy: false,
+
+		// content: String
+		//		An HTML fragment to embed.
+		content: "",
+
+		// parseOnLoad: Boolean
+		//		If true, runs the parser when the load completes.
+		parseOnLoad: true,
+
+		// prog: Boolean
+		//		If true, shows progress indicator while loading an HTML fragment
+		//		specified by href.
+		prog: true,
+
+		// executeScripts: Boolean
+		//		If true, executes scripts that is found in the content.
+		executeScripts: true,
+
+		constructor: function(){
+			// summary:
+			//		Creates a new instance of the class.
+			// tags:
+			//		private
+			if(this.prog){
+				this._p = ProgressIndicator.getInstance();
+			}
+		},
+
+		loadHandler: function(/*String*/response){
+			// summary:
+			//		A handler called when load completes.
+			this.set("content", response);
+		},
+
+		errorHandler: function(err){
+			// summary:
+			//		An error handler called when load fails.
+			if(this._p){ this._p.stop(); }
+		},
+
+		load: function(){
+			// summary:
+			//		Loads external content specified with href.
+			this.lazy = false;
+			this.set("href", this.href);
+		},
+
+		onLoad: function(){
+			// summary:
+			//		Stub method to allow the application to connect to the
+			//		loading of external content (see load()).
+			//		Called when parsing is done and the content is ready.
+			return true;
+		},
+
+		_setHrefAttr: function(/*String*/href){
+			// tags:
+			//		private
+			if(this.lazy || !href || href === this._loaded){
+				this.lazy = false;
+				return null;
+			}
+			var p = this._p;
+			if(p){
+				win.body().appendChild(p.domNode);
+				p.start();
+			}
+			this._set("href", href);
+			this._loaded = href;
+			return xhr.get({
+				url: href,
+				handleAs: "text",
+				load: lang.hitch(this, "loadHandler"),
+				error: lang.hitch(this, "errorHandler")
+			});
+		},
+
+		_setContentAttr: function(/*String|DomNode*/data){
+			// tags:
+			//		private			
+			this.destroyDescendants();
+			if(typeof data === "object"){
+				this.containerNode.appendChild(data);
+			}else{
+				if(this.executeScripts){
+					data = this.execScript(data);
+				}
+				this.containerNode.innerHTML = data;
+			}
+			if(this.parseOnLoad){
+				var _this = this;
+				return Deferred.when(lazyLoadUtils.instantiateLazyWidgets(_this.containerNode), function(){
+					if(_this._p){ _this._p.stop(); }
+					return _this.onLoad();
+				});
+			}
+			if(this._p){ this._p.stop(); }
+			return this.onLoad();
+		}
+	});
+});
diff --git a/dojox/mobile/_DataListMixin.js b/dojox/mobile/_DataListMixin.js
index 4b3fb52..c0cd6bc 100644
--- a/dojox/mobile/_DataListMixin.js
+++ b/dojox/mobile/_DataListMixin.js
@@ -1,39 +1,38 @@
 define([
 	"dojo/_base/array",
-	"dojo/_base/connect",
 	"dojo/_base/declare",
-	"dojo/_base/lang",
-	"dijit/registry",	// registry.byId
-	"./ListItem"
-], function(array, connect, declare, lang, registry, ListItem){
+	"dijit/registry",
+	"./_DataMixin",
+	"./ListItem",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/_StoreListMixin"
+], function(array, declare, registry, DataMixin, ListItem, has, BidiDataListMixin){
 
 	// module:
 	//		dojox/mobile/_DataListMixin
-	// summary:
-	//		Mixin for widgets to generate the list items corresponding to the
-	//		data provider object.
 
-	return declare("dojox.mobile._DataListMixin", null,{
+	var _DataListMixin = declare(has("dojo-bidi") ? "dojox.mobile._NonBidiDataListMixin" : "dojox.mobile._DataListMixin", DataMixin, {
 		// summary:
 		//		Mixin for widgets to generate the list items corresponding to
 		//		the data provider object.
 		// description:
 		//		By mixing this class into the widgets, the list item nodes are
 		//		generated as the child nodes of the widget and automatically
-		//		re-generated whenever the corresponding data items are modified.
+		//		regenerated whenever the corresponding data items are modified.
 
-		// store: Object
-		//		Reference to data provider object
-		store: null,
+		// append: Boolean
+		//		If true, refresh() does not clear the existing items.
+		append: false,
 
-		// query: Object
-		//		A query that can be passed to 'store' to initially filter the
-		//		items.
-		query: null,
+		// itemMap: Object
+		//		An optional parameter mapping field names from the store to ItemList name.
+		// example:
+		//	|	itemMap:{text:'label', profile_image_url:'icon' }
+		itemMap: null,
 
-		// queryOptions: Object
-		//		An optional parameter for the query.
-		queryOptions: null,
+		// itemRenderer: ListItem class or subclass
+		//		The class used to create list items. Default is dojox/mobile/ListItem.
+		itemRenderer: ListItem,
 
 		buildRendering: function(){
 			this.inherited(arguments);
@@ -43,36 +42,6 @@ define([
 			this.setStore(store, this.query, this.queryOptions);
 		},
 
-		setStore: function(store, query, queryOptions){
-			// summary:
-			//		Sets the store to use with this widget.
-			if(store === this.store){ return; }
-			this.store = store;
-			this.query = query;
-			this.queryOptions = queryOptions;
-			if(store && store.getFeatures()["dojo.data.api.Notification"]){
-				array.forEach(this._conn || [], connect.disconnect);
-				this._conn = [
-					connect.connect(store, "onSet", this, "onSet"),
-					connect.connect(store, "onNew", this, "onNew"),
-					connect.connect(store, "onDelete", this, "onDelete")
-				];
-			}
-			this.refresh();
-		},
-
-		refresh: function(){
-			// summary:
-			//		Fetches the data and generates the list items.
-			if(!this.store){ return; }
-			this.store.fetch({
-				query: this.query,
-				queryOptions: this.queryOptions,
-				onComplete: lang.hitch(this, "onComplete"),
-				onError: lang.hitch(this, "onError")
-			});
-		},
-
 		createListItem: function(/*Object*/item){
 			// summary:
 			//		Creates a list item widget.
@@ -83,20 +52,27 @@ define([
 				if(name === labelAttr){
 					attr["label"] = this.store.getLabel(item);
 				}else{
-					attr[name] = this.store.getValue(item, name);
+					attr[(this.itemMap && this.itemMap[name]) || name] = this.store.getValue(item, name);
 				}
 			}, this);
-			var w = new ListItem(attr);
+			// TODO this code should be like for textDir in the bidi mixin createListItem method
+			// however for that dynamic set/get of the dir property must be supported first
+			// that is why for now as a workaround we keep the code here
+			if(has("dojo-bidi") && typeof attr["dir"] == "undefined"){
+				attr["dir"] = this.isLeftToRight() ? "ltr" : "rtl";
+			}
+			var w = new this.itemRenderer(attr);
 			item._widgetId = w.id;
 			return w;
 		},
-
 		generateList: function(/*Array*/items, /*Object*/dataObject){
 			// summary:
 			//		Given the data, generates a list of items.
-			array.forEach(this.getChildren(), function(child){
-				child.destroyRecursive();
-			});
+			if(!this.append){
+				array.forEach(this.getChildren(), function(child){
+					child.destroyRecursive();
+				});
+			}
 			array.forEach(items, function(item, index){
 				this.addChild(this.createListItem(item));
 			}, this);
@@ -114,20 +90,29 @@ define([
 		},
 
 		onSet: function(/*Object*/item, /*String*/attribute, /*Object|Array*/oldValue, /*Object|Array*/newValue){
-			//	summary:
-			//		See dojo.data.api.Notification.onSet()
+			// summary:
+			//		See dojo/data/api/Notification.onSet().
 		},
 
 		onNew: function(/*Object*/newItem, /*Object?*/parentInfo){
-			//	summary:
-			//		See dojo.data.api.Notification.onNew()
+			// summary:
+			//		See dojo/data/api/Notification.onNew().
 			this.addChild(this.createListItem(newItem));
 		},
 
 		onDelete: function(/*Object*/deletedItem){
-			//	summary:
-			//		See dojo.data.api.Notification.onDelete()
+			// summary:
+			//		See dojo/data/api/Notification.onDelete().
 			registry.byId(deletedItem._widgetId).destroyRecursive();
+		},
+
+		onStoreClose: function(/*Object?*/request){
+			// summary:
+			//		Refresh list on close.
+			if(this.store.clearOnClose){
+				this.refresh();
+			}
 		}
 	});
+	return has("dojo-bidi") ? declare("dojox.mobile._DataListMixin", [_DataListMixin, BidiDataListMixin]) : _DataListMixin;	
 });
diff --git a/dojox/mobile/_DataMixin.js b/dojox/mobile/_DataMixin.js
new file mode 100644
index 0000000..a6dc18a
--- /dev/null
+++ b/dojox/mobile/_DataMixin.js
@@ -0,0 +1,125 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/Deferred"
+], function(kernel, array, declare, lang, Deferred){
+
+	// module:
+	//		dojox/mobile/_DataMixin
+
+	kernel.deprecated("dojox/mobile/_DataMixin", "Use dojox/mobile/_StoreMixin instead", "2.0");
+
+	return declare("dojox.mobile._DataMixin", null, {
+		// summary:
+		//		Mixin for widgets to enable dojo/data data store.
+		// description:
+		//		By mixing this class into a widget, it can get data through a
+		//		dojo/data data store. The widget must implement
+		//		onComplete(/*Array*/items) to handle the retrieved data.
+
+		// store: Object
+		//		Reference to data provider object used by this widget.
+		store: null,
+
+		// query: Object
+		//		A query that can be passed to 'store' to initially filter the items.
+		query: null,
+
+		// queryOptions: Object
+		//		An optional parameter for the query.
+		queryOptions: null,
+
+		setStore: function(/*dojo/data/store*/store, /*dojo/data/api/Request|Object*/query, /*Object?*/queryOptions){
+			// summary:
+			//		Sets the store to use with this widget.
+			if(store === this.store){ return null; }
+			this.store = store;
+			this._setQuery(query, queryOptions);
+			if(store && store.getFeatures()["dojo.data.api.Notification"]){
+				array.forEach(this._conn || [], this.disconnect, this);
+				this._conn = [
+					this.connect(store, "onSet", "onSet"),
+					this.connect(store, "onNew", "onNew"),
+					this.connect(store, "onDelete", "onDelete"),
+					this.connect(store, "close", "onStoreClose")
+				];
+			}
+			return this.refresh();
+		},
+
+		setQuery: function(/*dojo/data/api/Request|Object*/query, /*Object?*/queryOptions){
+			// summary:
+			//		Sets a query.
+			this._setQuery(query, queryOptions);
+			return this.refresh();
+		},
+
+		_setQuery: function(query, queryOptions){
+			// tags:
+			//		private
+			this.query = query;
+			this.queryOptions = queryOptions || this.queryOptions;
+		},
+
+		refresh: function(){
+			// summary:
+			//		Fetches the data and generates the list items.
+			if(!this.store){ return null; }
+			var d = new Deferred();
+			var onComplete = lang.hitch(this, function(items, request){
+				this.onComplete(items, request);
+				d.resolve();
+			});
+			var onError = lang.hitch(this, function(errorData, request){
+				this.onError(errorData, request);
+				d.resolve();
+			});
+			var q = this.query;
+			this.store.fetch({
+				query: q,
+				queryOptions: this.queryOptions,
+				onComplete: onComplete,
+				onError: onError,
+				start: q && q.start,
+				count: q && q.count
+			});
+			return d;
+		}
+
+/*
+		// Subclass MUST implement the following methods.
+
+		onComplete: function(items, request){
+			// summary:
+			//		An handler that is called after the fetch completes.
+		},
+
+		onError: function(errorData, request){
+			// summary:
+			//		An error handler.
+		},
+
+		onSet: function(item, attribute, oldValue, newValue){
+			// summary:
+			//		See dojo/data/api/Notification.onSet()
+		},
+
+		onNew: function(newItem, parentInfo){
+			// summary:
+			//		See dojo/data/api/Notification.onNew()
+		},
+
+		onDelete: function(deletedItem){
+			// summary:
+			//		See dojo/data/api/Notification.onDelete()
+		},
+
+		onStoreClose: function(request){
+			// summary:
+			//		Refresh list on close.
+		}
+*/
+	});
+});
diff --git a/dojox/mobile/_DatePickerMixin.js b/dojox/mobile/_DatePickerMixin.js
new file mode 100644
index 0000000..4e5b45d
--- /dev/null
+++ b/dojox/mobile/_DatePickerMixin.js
@@ -0,0 +1,275 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/date",
+	"dojo/date/locale",
+	"dojo/date/stamp"
+], function(array, declare, lang, ddate, datelocale, datestamp){
+
+	// module:
+	//		dojox/mobile/_DatePickerMixin
+
+	var slotMixin = {
+		format: function(/*Date*/d){
+			return datelocale.format(d, {datePattern:this.pattern, selector:"date"});
+		}
+	};
+
+	var yearSlotMixin = lang.mixin({
+		initLabels: function(){
+			this.labels = [];
+			if(this.labelFrom !== this.labelTo){
+				var d = new Date(this.labelFrom, 0, 1);
+				var i, idx;
+				for(i = this.labelFrom, idx = 0; i <= this.labelTo; i++, idx++){
+					d.setFullYear(i);
+					this.labels.push(this.format(d));
+				}
+			}
+		}
+	}, slotMixin);
+
+	var monthSlotMixin = lang.mixin({
+		initLabels: function(){
+			this.labels = [];
+			// On certain BlackBerry devices, we need to init to 16 not 1 to avoid some devices bugs (see #15677)
+			var d = new Date(2000, 0, 16);
+			for(var i = 0; i < 12; i++){
+				d.setMonth(i);
+				this.labels.push(this.format(d));
+			}
+		}
+	}, slotMixin);
+
+	var daySlotMixin = lang.mixin({
+		initLabels: function(){
+			this.labels = [];
+			var d = new Date(2000, 0, 1);
+			for(var i = 1; i <= 31; i++){
+				d.setDate(i);
+				this.labels.push(this.format(d));
+			}
+		}
+	}, slotMixin);
+
+	return declare("dojox.mobile._DatePickerMixin", null, {
+		// summary:
+		//		A mixin for date picker widget.
+
+		// yearPattern: String
+		//		A pattern to be used to format year.
+		yearPattern: "yyyy",
+
+		// monthPattern: String
+		//		A pattern to be used to format month.
+		monthPattern: "MMM",
+
+		// dayPattern: String
+		//		A pattern to be used to format day.
+		dayPattern: "d",
+		
+		/*=====
+		// value: String
+		//		A string representing the date value.
+		//		The setter of this property first converts the value argument by calling 
+		//		the fromISOString method of the dojo/date/stamp module, then sets the 
+		//		values of the picker according to the resulting	Date object. 
+		//		If the string cannot be parsed by fromISOString, the method does nothing.
+		//		Example: set("value", "2012-1-20"); // January 20, 2012
+		//		The getter returns the string formatted as described in the dojo/date/stamp 
+		//		module.
+		value: "",
+		=====*/
+		
+		initSlots: function(){
+			// summary:
+			//		Initializes the slots.
+			var c = this.slotClasses, p = this.slotProps;
+			c[0] = declare(c[0], yearSlotMixin);
+			c[1] = declare(c[1], monthSlotMixin);
+			c[2] = declare(c[2], daySlotMixin);
+			p[0].pattern = this.yearPattern;
+			p[1].pattern = this.monthPattern;
+			p[2].pattern = this.dayPattern;
+			this.reorderSlots();
+		},
+
+		reorderSlots: function(){
+			// summary:
+			//		Reorders the slots.			
+			if(this.slotOrder.length){ return; }
+			var a = datelocale._parseInfo().bundle["dateFormat-short"].toLowerCase().split(/[^ymd]+/, 3);
+			this.slotOrder = array.map(a, function(pat){
+				return {y:0, m:1, d:2}[pat.charAt(0)];
+			});
+		},
+
+		reset: function(){
+			// summary:
+			//		Goes to today.
+			var now = new Date();
+			var v = array.map(this.slots, function(w){ return w.format(now); });
+			this.set("colors", v);
+			this._disableEndDaysOfMonth();
+			if(this.value){
+				this.set("value", this.value);
+				this.value = null;
+			}else if(this.values){
+				this.set("values", this.values);
+				this.values = null;
+			}else{
+				this.set("values", v);
+			}
+		},
+
+		_onYearSet: function(){
+			// summary:
+			//		An internal handler called when the year value is changed.
+			// tags:
+			//		private
+			var slot = this.slots[0];
+			var newValue = slot.get("value");
+			if(!(slot._previousValue && newValue == slot._previousValue)){ // do nothing if the value is unchanged
+				this._disableEndDaysOfMonth();
+				slot._previousValue = newValue;
+				slot._set("value", newValue);
+				this.onYearSet();
+			}
+		},
+		
+		onYearSet: function(){
+			// summary:
+			//		A handler called when the year value is changed.
+		},
+
+		_onMonthSet: function(){
+			// summary:
+			//		An internal handler called when the month value is changed.
+			// tags:
+			//		private
+			var slot = this.slots[1];
+			var newValue = slot.get("value");
+			if(!(slot._previousValue && newValue == slot._previousValue)){ // do nothing if the value is unchanged
+				this._disableEndDaysOfMonth();
+				slot._previousValue = newValue;
+				slot._set("value", newValue); // notify watches
+				this.onMonthSet();
+			}
+		},
+
+		onMonthSet: function(){
+			// summary:
+			//		A handler called when the month value is changed.
+		},
+
+		_onDaySet: function(){
+			// summary:
+			//		An internal handler called when the day value is changed.
+			// tags:
+			//		private
+			var slot = this.slots[2];
+			var newValue = slot.get("value");
+			if(!(slot._previousValue && newValue == slot._previousValue)){ // do nothing if the value is unchanged
+				if(!this._disableEndDaysOfMonth()){
+					// If _disableEndDaysOfMonth has changed the day value,
+					// skip notifications till next call of _onDaySet, to
+					// avoid the extra notification for the (invalid)
+					// intermediate value of the day.
+					slot._previousValue = newValue;
+					slot._set("value", newValue); // notify watches
+					this.onDaySet();
+				}
+			}
+		},
+
+		onDaySet: function(){
+			// summary:
+			//		A handler called when the day value is changed.
+		},
+
+		_disableEndDaysOfMonth: function(){
+			// summary:
+			//		Disables the end days of the month to match the specified
+			//		number of days of the month. Returns true if the day value is changed.
+			// tags:
+			//		private
+			var pat = this.slots[0].pattern + "/" + this.slots[1].pattern,
+				v = this.get("values"),
+				date = datelocale.parse(v[0] + "/" + v[1], {datePattern:pat, selector:"date"}),
+				daysInMonth = ddate.getDaysInMonth(date);
+			var changedDay = false;
+			if(daysInMonth < v[2]){
+				// day value is invalid for this month, change it
+				changedDay = true;
+				this.slots[2]._spinToValue(daysInMonth, false/*applyValue*/);
+			}
+			this.disableValues(daysInMonth);
+			return changedDay;
+		},
+
+		_getDateAttr: function(){
+			// summary:
+			//		Returns a Date object for the current values.
+			// tags:
+			//		private
+			var v = this.get("values"), // [year, month, day]
+				s = this.slots,
+				pat = s[0].pattern + "/" + s[1].pattern + "/" + s[2].pattern;
+				return datelocale.parse(v[0] + "/" + v[1] + "/" + v[2], {datePattern:pat, selector:"date"});
+		},
+
+		_setValuesAttr: function(/*Array*/values){
+			// summary:
+			//		Sets the current date as an array of values.
+			// description:
+			//		This method takes an array that consists of three values,
+			//		year, month, and day. If the values are integer, they are
+			//		formatted to locale-specific strings before setting them to
+			//		the slots. Month starts from 1 to 12 (Ex. 1 - Jan, 2 - Feb, etc.)
+			//		If the values are NOT integer, they are directly
+			//		passed to the setter of the slots without formatting.
+			//
+			// example:
+			//	|	set("values", [2012, 1, 20]); // January 20, 2012
+			// tags:
+			//		private
+			array.forEach(this.getSlots(), function(w, i){
+				var v = values[i];
+				if(typeof v == "number"){
+					var arr = [1970, 1, 1];
+					arr.splice(i, 1, v - 0);
+					v = w.format(new Date(arr[0], arr[1] - 1, arr[2]));
+				}
+				w.set("value", v);
+			});
+		},
+		
+		_setValueAttr: function(/*String*/value){
+			// summary:
+			//		Sets the current date as an String formatted according to a subset of the ISO-8601 standard.
+			// description:
+			//		This method first converts the value argument by calling the fromISOString method of
+			//		the dojo/date/stamp module, then sets the values of the picker according to the resulting
+			//		Date object. If the string cannot be parsed by fromISOString, the method does nothing.
+			// value:
+			//		A string formatted as described in the dojo/date/stamp module.
+			// example:
+			//	|	set("value", "2012-1-20"); // January 20, 2012
+			// tags:
+			//		private			
+			var date = datestamp.fromISOString(value);
+			this.set("values", array.map(this.slots, function(w){ return w.format(date); }));
+		},
+		
+		_getValueAttr: function(){
+			// summary:
+			//		Gets the current date as a String formatted according to a subset of the ISO-8601 standard.
+			// returns: String
+			//		A string formatted as described in the dojo/date/stamp module.
+			// tags:
+			//		private			
+			return datestamp.toISOString(this.get("date"), { selector: "date" });
+		}		
+	});
+});
diff --git a/dojox/mobile/_EditableIconMixin.js b/dojox/mobile/_EditableIconMixin.js
new file mode 100644
index 0000000..eea7de0
--- /dev/null
+++ b/dojox/mobile/_EditableIconMixin.js
@@ -0,0 +1,417 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
+	"dojo/touch",
+	"dijit/registry",
+	"./IconItem",
+	"./sniff",
+	"./viewRegistry",
+	"./_css3"
+], function(array, connect, declare, event, lang, win, domGeometry, domStyle, touch, registry, IconItem, has, viewRegistry, css3){
+
+	// module:
+	//		dojox/mobile/_EditableIconMixin
+
+	return declare("dojox.mobile._EditableIconMixin", null, {
+		// summary:
+		//		A mixin for IconContainer to make it editable.
+
+		deleteIconForEdit: "mblDomButtonBlackCircleCross",
+		threshold: 4, // drag threshold value in pixels
+
+		destroy: function(){
+			// summary:
+			//		Destroys the container.
+			if(this._blankItem){
+				this._blankItem.destroy();
+			}
+			this.inherited(arguments);
+		},
+
+		startEdit: function(){
+			// summary:
+			//		Starts the editing.
+			if(!this.editable || this.isEditing){ return; }
+
+			this.isEditing = true;
+			if(!this._handles){
+				this._handles = [
+					this.connect(this.domNode, css3.name("transitionStart"), "_onTransitionStart"),
+					this.connect(this.domNode, css3.name("transitionEnd"), "_onTransitionEnd")
+				];
+			}
+
+			var count = 0;
+			array.forEach(this.getChildren(), function(w){
+				this.defer(function(){
+					w.set("deleteIcon", this.deleteIconForEdit);
+					if(w.deleteIconNode){
+						w._deleteHandle = this.connect(w.deleteIconNode, "onclick", "_deleteIconClicked");
+					}
+					w.highlight(0);
+				}, 15*count++);
+			}, this);
+
+			connect.publish("/dojox/mobile/startEdit", [this]); // pubsub
+			this.onStartEdit(); // callback
+		},
+
+		endEdit: function(){
+			// summary:
+			//		Ends the editing.
+			if(!this.isEditing){ return; }
+
+			array.forEach(this.getChildren(), function(w){
+				w.unhighlight();
+				if(w._deleteHandle){
+					this.disconnect(w._deleteHandle);
+					w._deleteHandle = null;
+				}
+				w.set("deleteIcon", "");
+			}, this);
+
+			this._movingItem = null;
+			if(this._handles){
+				array.forEach(this._handles, this.disconnect, this);
+				this._handles = null;
+			}
+
+			connect.publish("/dojox/mobile/endEdit", [this]); // pubsub
+			this.onEndEdit(); // callback
+			this.isEditing = false;
+		},
+
+		scaleItem: function(/*Widget*/widget, /*Number*/ratio){
+			// summary:
+			//		Scales an item according to the specified ratio.
+			domStyle.set(widget.domNode, css3.add({}, {
+				transition: has("android") ? "" : css3.name("transform", true) + " .1s ease-in-out",
+				transform: ratio == 1 ? "" : "scale(" + ratio + ")"
+			}));			
+		},
+
+		_onTransitionStart: function(e){
+			// tags:
+			//		private
+			event.stop(e);
+		},
+
+		_onTransitionEnd: function(e){
+			// tags:
+			//		private
+			event.stop(e);
+			var w = registry.getEnclosingWidget(e.target);
+			w._moving = false;
+			domStyle.set(w.domNode, css3.name("transition"), "");
+		},
+
+		_onTouchStart: function(e){
+			// tags:
+			//		private
+			if(!this._blankItem){
+				this._blankItem = new IconItem();
+				this._blankItem.domNode.style.visibility = "hidden";
+				this._blankItem._onClick = function(){};
+			}
+			var item = this._movingItem = registry.getEnclosingWidget(e.target);
+			var iconPressed = false;
+			var n;
+			for(n = e.target; n !== item.domNode; n = n.parentNode){
+				if(n === item.iconNode){
+					iconPressed = true;
+					break;
+				}
+			}
+			if(!iconPressed){ return; }
+
+			if(!this._conn){
+				this._conn = [
+					this.connect(this.domNode, touch.move, "_onTouchMove"),
+					this.connect(win.doc, touch.release, "_onTouchEnd")
+				];
+			}
+			this._touchStartPosX = e.touches ? e.touches[0].pageX : e.pageX;
+			this._touchStartPosY = e.touches ? e.touches[0].pageY : e.pageY;
+			if(this.isEditing){
+				this._onDragStart(e);
+			}else{
+				// set timer to detect long press
+				this._pressTimer = this.defer(function(){
+					this.startEdit();
+					this._onDragStart(e);
+				}, 1000);
+			}
+		},
+
+		_onDragStart: function(e){
+			// tags:
+			//		private
+			this._dragging = true;
+
+			var movingItem = this._movingItem;
+			if(movingItem.get("selected")){
+				movingItem.set("selected", false);
+			}
+			this.scaleItem(movingItem, 1.1);
+
+			var x = e.touches ? e.touches[0].pageX : e.pageX;
+			var y = e.touches ? e.touches[0].pageY : e.pageY;
+			
+			var enclosingScrollable = viewRegistry.getEnclosingScrollable(movingItem.domNode);
+			var dx = 0;
+			var dy = 0;
+			if(enclosingScrollable){ // this node is placed inside a scrollable
+				var pos = enclosingScrollable.getPos();
+				dx = pos.x;
+				dy = pos.y;
+				event.stop(e);
+			}
+			
+			var startPos = this._startPos = domGeometry.position(movingItem.domNode, true);
+			this._offsetPos = {
+				x: startPos.x - x - dx,
+				y: startPos.y - y - dy
+			};
+
+			this._startIndex = this.getIndexOfChild(movingItem);
+			this.addChild(this._blankItem, this._startIndex);
+			this.moveChild(movingItem, this.getChildren().length);
+			domStyle.set(movingItem.domNode, {
+				position: "absolute",
+				top: (startPos.y - dy) + "px",
+				left: (startPos.x - dx) + "px",
+				zIndex: 100
+			});
+		},
+
+		_onTouchMove: function(e){
+			// tags:
+			//		private
+			var x = e.touches ? e.touches[0].pageX : e.pageX;
+			var y = e.touches ? e.touches[0].pageY : e.pageY;
+			if(this._dragging){
+				domStyle.set(this._movingItem.domNode, {
+					top: (this._offsetPos.y + y) + "px",
+					left: (this._offsetPos.x + x) + "px"
+				});
+				this._detectOverlap({x: x, y: y});
+				event.stop(e);
+			}else{
+				var dx = Math.abs(this._touchStartPosX - x);
+				var dy = Math.abs(this._touchStartPosY - y);
+				if (dx > this.threshold || dy > this.threshold) {
+					this._clearPressTimer();					
+				}
+			}
+		},
+
+		_onTouchEnd: function(e){
+			// tags:
+			//		private
+			this._clearPressTimer();
+			if(this._conn){
+				array.forEach(this._conn, this.disconnect, this);
+				this._conn = null;				
+			}
+
+			if(this._dragging){
+				this._dragging = false;
+
+				var movingItem = this._movingItem;
+				this.scaleItem(movingItem, 1.0);
+				domStyle.set(movingItem.domNode, {
+					position: "",
+					top: "",
+					left: "",
+					zIndex: ""
+				});
+				var startIndex = this._startIndex;
+				var endIndex = this.getIndexOfChild(this._blankItem);
+				this.moveChild(movingItem, endIndex);
+				this.removeChild(this._blankItem);
+				connect.publish("/dojox/mobile/moveIconItem", [this, movingItem, startIndex, endIndex]); // pubsub
+				this.onMoveItem(movingItem, startIndex, endIndex); // callback
+			}
+		},
+
+		_clearPressTimer: function(){
+			// tags:
+			//		private
+			if(this._pressTimer){
+				this._pressTimer.remove();
+				this._pressTimer = null;
+			}
+		},
+
+		_detectOverlap: function(/*Object*/point){
+			// tags:
+			//		private
+			var children = this.getChildren(),
+				blankItem = this._blankItem,
+				blankPos = domGeometry.position(blankItem.domNode, true),
+				blankIndex = this.getIndexOfChild(blankItem),
+				dir = 1,
+				i, w, pos;
+			if(this._contains(point, blankPos)){
+				return;
+			}else if(point.y < blankPos.y || (point.y <= blankPos.y + blankPos.h && point.x < blankPos.x)){
+				dir = -1;
+			}
+			for(i = blankIndex + dir; i>=0 && i<children.length-1; i += dir){
+				w = children[i];
+				if(w._moving){ continue; }
+				pos = domGeometry.position(w.domNode, true);
+				if(this._contains(point, pos)){
+					this.defer(function(){
+						this.moveChildWithAnimation(blankItem, dir == 1 ? i+1 : i);
+					});
+					break;
+				}else if((dir == 1 && pos.y > point.y) || (dir == -1 && pos.y + pos.h < point.y)){
+					break;
+				}
+			}
+		},
+
+		_contains: function(point, pos){
+			// tags:
+			//		private
+			return pos.x < point.x && point.x < pos.x + pos.w && pos.y < point.y && point.y < pos.y + pos.h;
+		},
+
+		_animate: function(/*int*/from, /*int*/to){
+			// tags:
+			//		private
+			if(from == to) { return; }
+			var dir = from < to ? 1 : -1;
+			var children = this.getChildren();
+			var posArray = [];
+			var i;
+			for(i=from; i!=to; i+=dir){
+				posArray.push({
+					t: (children[i+dir].domNode.offsetTop - children[i].domNode.offsetTop) + "px",
+					l: (children[i+dir].domNode.offsetLeft - children[i].domNode.offsetLeft) + "px"
+				});
+			}
+			for(i=from, j=0; i!=to; i+=dir, j++){
+				var w = children[i];
+				w._moving = true;
+				domStyle.set(w.domNode, {
+					top: posArray[j].t,
+					left: posArray[j].l
+				});
+				this.defer(lang.hitch(w, function(){
+					domStyle.set(this.domNode, css3.add({
+						top: "0px",
+						left: "0px"
+					}, {
+						transition: "top .3s ease-in-out, left .3s ease-in-out"
+					}));
+				}), j*10);
+			}
+		},
+
+		removeChildWithAnimation: function(/*Widget|Number*/widget){
+			// summary:
+			//		Removes the given child with animation.
+			var index = (typeof widget === "number") ? widget : this.getIndexOfChild(widget);
+			this.removeChild(widget);
+
+			// Show remove animation
+			if(this._blankItem){
+				// #16868 - no _blankItem if calling deleteItem() programmatically, that is
+				// without _onTouchStart() being called.
+				this.addChild(this._blankItem);
+			}
+			this._animate(index, this.getChildren().length - 1);
+			if(this._blankItem){
+				this.removeChild(this._blankItem);
+			}
+		},
+
+		moveChild: function(/*Widget|Number*/widget, /*Number?*/insertIndex){
+			// summary:
+			//		Moves a child without animation.
+			this.addChild(widget, insertIndex);
+			this.paneContainerWidget.addChild(widget.paneWidget, insertIndex);
+		},
+
+		moveChildWithAnimation: function(/*Widget|Number*/widget, /*Number?*/insertIndex){
+			// summary:
+			//		Moves a child with animation.	
+			var index = this.getIndexOfChild(this._blankItem);
+			this.moveChild(widget, insertIndex);
+
+			// Show move animation
+			this._animate(index, insertIndex);
+		},
+
+		_deleteIconClicked: function(e){
+			// summary:
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(this.deleteIconClicked(e) === false){ return; } // user's click action
+			var item = registry.getEnclosingWidget(e.target);
+			this.deleteItem(item);
+		},
+
+		deleteIconClicked: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User-defined function to handle clicks for the delete icon.
+			// tags:
+			//		callback
+		},
+
+		deleteItem: function(/*Widget*/item){
+			// summary:
+			//		Deletes the given item.
+			if(item._deleteHandle){
+				this.disconnect(item._deleteHandle);
+			}
+			this.removeChildWithAnimation(item);
+
+			connect.publish("/dojox/mobile/deleteIconItem", [this, item]); // pubsub
+			this.onDeleteItem(item); // callback
+
+			item.destroy();
+		},
+
+		onDeleteItem: function(/*Widget*/item){
+			// summary:
+			//		Stub function to connect to from your application.
+		},
+
+		onMoveItem: function(/*Widget*/item, /*int*/from, /*int*/to){
+			// summary:
+			//		Stub function to connect to from your application.
+		},
+
+		onStartEdit: function(){
+			// summary:
+			//		Stub function to connect to from your application.
+		},
+
+		onEndEdit: function(){
+			// summary:
+			//		Stub function to connect to from your application.
+		},
+
+		_setEditableAttr: function(/*Boolean*/editable){
+			// tags:
+			//		private
+			this._set("editable", editable);
+			if(editable && !this._touchStartHandle){ // Allow users to start editing by long press on IconItems
+				this._touchStartHandle = this.connect(this.domNode, touch.press, "_onTouchStart");
+			}else if(!editable && this._touchStartHandle){
+				this.disconnect(this._touchStartHandle);
+				this._touchStartHandle = null;
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/_EditableListMixin.js b/dojox/mobile/_EditableListMixin.js
new file mode 100755
index 0000000..cb0a873
--- /dev/null
+++ b/dojox/mobile/_EditableListMixin.js
@@ -0,0 +1,263 @@
+// TODO: auto scroll?
+
+define([
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/declare",
+	"dojo/_base/event",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
+	"dojo/touch",
+	"dojo/dom-attr",
+	"dijit/registry",
+	"./ListItem"
+], function(array, connect, declare, event, win, domClass, domGeometry, domStyle, touch, domAttr, registry, ListItem){
+
+	// module:
+	//		dojox/mobile/EditableRoundRectList
+
+	return declare("dojox.mobile._EditableListMixin", null, {
+		// summary:
+		//		A rounded rectangle list.
+		// description:
+		//		EditableRoundRectList is a rounded rectangle list, which can be used to
+		//		display a group of items. Each item must be	a dojox/mobile/ListItem.
+
+		rightIconForEdit: "mblDomButtonGrayKnob",
+		deleteIconForEdit: "mblDomButtonRedCircleMinus",
+
+		// isEditing: Boolean
+		//		A read-only flag that indicates whether the widget is in the editing mode.
+		isEditing: false,
+
+		destroy: function(){
+			// summary:
+			//		Destroys the widget.
+			if(this._blankItem){
+				this._blankItem.destroy();
+			}
+			this.inherited(arguments);
+		},
+
+		_setupMoveItem: function(/*DomNode*/node){
+			// tags:
+			//		private
+			domStyle.set(node, {
+				width: domGeometry.getContentBox(node).w + "px",
+				top: node.offsetTop + "px"
+			});
+			domClass.add(node, "mblListItemFloat");
+		},
+
+		_resetMoveItem: function(/*DomNode*/node){
+			// tags:
+			//		private
+			this.defer(function(){ // iPhone needs setTimeout (via defer)
+				domClass.remove(node, "mblListItemFloat");
+				domStyle.set(node, {
+					width: "",
+					top: ""
+				});
+			});
+		},
+
+		_onClick: function(e){
+			// summary:
+			//		Internal handler for click events.
+			// tags:
+			//		private
+			if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
+			if(this.onClick(e) === false){ return; } // user's click action
+			var item = registry.getEnclosingWidget(e.target);
+			for(var n = e.target; n !== item.domNode; n = n.parentNode){
+				if(n === item.deleteIconNode){
+					connect.publish("/dojox/mobile/deleteListItem", [item]);
+					this.onDeleteItem(item); //callback
+					break;
+				}
+			}
+		},
+
+		onClick: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User-defined function to handle clicks.
+			// tags:
+			//		callback
+		},
+
+		_onTouchStart: function(e){
+			// tags:
+			//		private
+			if(this.getChildren().length <= 1){ return; }
+			if(!this._blankItem){
+				this._blankItem = new ListItem();
+			}
+			var item = this._movingItem = registry.getEnclosingWidget(e.target);
+			this._startIndex = this.getIndexOfChild(item);
+			var rightIconPressed = false;
+			for(var n = e.target; n !== item.domNode; n = n.parentNode){
+				if(n === item.rightIconNode){
+					rightIconPressed = true;
+					domAttr.set(item.rightIconNode, "aria-grabbed", "true");
+					domAttr.set(this.domNode, "aria-dropeffect", "move");
+					break;
+				}
+			}
+			if(!rightIconPressed){ return; }
+			var ref = item.getNextSibling();
+			ref = ref ? ref.domNode : null;
+			this.containerNode.insertBefore(this._blankItem.domNode, ref);
+			this._setupMoveItem(item.domNode);
+			this.containerNode.appendChild(item.domNode);
+
+			if(!this._conn){
+				this._conn = [
+					this.connect(this.domNode, touch.move, "_onTouchMove"),
+					this.connect(win.doc, touch.release, "_onTouchEnd")
+				];
+			}
+			this._pos = [];
+			array.forEach(this.getChildren(), function(c, index){
+				this._pos.push(domGeometry.position(c.domNode, true).y);
+			}, this);
+			this.touchStartY = e.touches ? e.touches[0].pageY : e.pageY;
+			this._startTop = domGeometry.getMarginBox(item.domNode).t;
+			event.stop(e);
+		},
+
+		_onTouchMove: function(e){
+			// tags:
+			//		private
+			var y = e.touches ? e.touches[0].pageY : e.pageY;
+			var index = this._pos.length - 1;
+			for(var i = 1; i < this._pos.length; i++){
+				if(y < this._pos[i]){
+					index = i - 1;
+					break;
+				}
+			}
+			var item = this.getChildren()[index];
+			var blank = this._blankItem;
+			if(item !== blank){
+				var p = item.domNode.parentNode;
+				if(item.getIndexInParent() < blank.getIndexInParent()){
+					p.insertBefore(blank.domNode, item.domNode);
+				}else{
+					p.insertBefore(item.domNode, blank.domNode);
+				}
+			}
+			this._movingItem.domNode.style.top = this._startTop + (y - this.touchStartY) + "px";
+		},
+
+		_onTouchEnd: function(e){
+			// tags:
+			//		private
+			var startIndex = this._startIndex;
+			var endIndex = this.getIndexOfChild(this._blankItem);
+						
+			var ref = this._blankItem.getNextSibling();
+			ref = ref ? ref.domNode : null;
+			if(ref === null){ 
+				//If the item is droped at the end of the list the endIndex is wrong
+				endIndex--; 
+			} 
+			this.containerNode.insertBefore(this._movingItem.domNode, ref);
+			this.containerNode.removeChild(this._blankItem.domNode);
+			this._resetMoveItem(this._movingItem.domNode);
+
+			array.forEach(this._conn, connect.disconnect);
+			this._conn = null;
+			
+			this.onMoveItem(this._movingItem, startIndex, endIndex); //callback
+			
+			domAttr.set(this._movingItem.rightIconNode, "aria-grabbed", "false");
+			domAttr.remove(this.domNode, "aria-dropeffect");
+		},
+
+		startEdit: function(){
+			// summary:
+			//		Starts the editing.
+			this.isEditing = true;
+			domClass.add(this.domNode, "mblEditableRoundRectList");
+			array.forEach(this.getChildren(), function(child){
+				if(!child.deleteIconNode){
+					child.set("rightIcon", this.rightIconForEdit);
+					if(child.rightIconNode){
+						domAttr.set(child.rightIconNode, "role", "button");
+						domAttr.set(child.rightIconNode, "aria-grabbed", "false");
+					}
+					child.set("deleteIcon", this.deleteIconForEdit);
+					child.deleteIconNode.tabIndex = child.tabIndex;
+					if(child.deleteIconNode){
+						domAttr.set(child.deleteIconNode, "role", "button");
+					}
+				}
+				child.rightIconNode.style.display = "";
+				child.deleteIconNode.style.display = "";
+				if(typeof child.rightIconNode.style.msTouchAction != "undefined"){
+					child.rightIconNode.style.msTouchAction = "none";
+				}
+			}, this);
+			if(!this._handles){
+				this._handles = [
+					this.connect(this.domNode, touch.press, "_onTouchStart"),
+					this.connect(this.domNode, "onclick", "_onClick"),
+					this.connect(this.domNode, "onkeydown", "_onClick") // for desktop browsers
+				];
+			}
+			
+			this.onStartEdit(); // callback
+		},
+
+		endEdit: function(){
+			// summary:
+			//		Ends the editing.
+			domClass.remove(this.domNode, "mblEditableRoundRectList");
+			array.forEach(this.getChildren(), function(child){
+				child.rightIconNode.style.display = "none";
+				child.deleteIconNode.style.display = "none";
+				if(typeof child.rightIconNode.style.msTouchAction != "undefined"){
+					child.rightIconNode.style.msTouchAction = "auto";
+				}
+			});
+			if(this._handles){
+				array.forEach(this._handles, this.disconnect, this);
+				this._handles = null;
+			}
+			this.isEditing = false;
+			
+			this.onEndEdit(); // callback
+		},
+		
+		
+		onDeleteItem: function(/*Widget*/item){
+			// summary:
+			//		Stub function to connect to from your application.
+			// description:
+			//		This function is called when a user clicks the delete
+			//		button.
+			//		You have to provide that function or subscribe to /dojox/mobile/deleteListItem, 
+			//		otherwise the delete button will have no-effect.
+			
+		},
+		
+		onMoveItem: function(/*Widget*/item, /*int*/from, /*int*/to){
+			// summary:
+			//		Stub function to connect to from your application.
+		},
+
+		onStartEdit: function(){
+			// summary:
+			//		Stub function to connect to from your application.
+		},
+
+		onEndEdit: function(){
+			// summary:
+			//		Stub function to connect to from your application.
+		}
+
+
+	});
+});
diff --git a/dojox/mobile/_ExecScriptMixin.js b/dojox/mobile/_ExecScriptMixin.js
new file mode 100644
index 0000000..7c7a524
--- /dev/null
+++ b/dojox/mobile/_ExecScriptMixin.js
@@ -0,0 +1,40 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/window",
+	"dojo/dom-construct"
+], function(kernel, declare, win, domConstruct){
+	// module:
+	//		dojox/mobile/_ExecScriptMixin
+
+	return declare("dojox.mobile._ExecScriptMixin", null, {
+		// summary:
+		//		Mixin for providing script execution capability to content handlers.
+		// description:
+		//		This module defines the execScript method, which is called
+		//		from an HTML content handler.
+
+		execScript: function(/*String*/ html){
+			// summary:
+			//		Finds script tags and executes the script.
+			// html: String
+			//		The HTML input.
+			// returns: String
+			//		The given HTML text from which <script> blocks are removed.
+			var s = html.replace(/\f/g, " ").replace(/<\/script>/g, "\f");
+			s = s.replace(/<script [^>]*src=['"]([^'"]+)['"][^>]*>([^\f]*)\f/ig, function(ignore, path){
+				domConstruct.create("script", {
+					type: "text/javascript",
+					src: path}, win.doc.getElementsByTagName("head")[0]);
+				return "";
+			});
+
+			s = s.replace(/<script>([^\f]*)\f/ig, function(ignore, code){
+				kernel.eval(code);
+				return "";
+			});
+
+			return s;
+		}
+	});
+});
diff --git a/dojox/mobile/_IconItemPane.js b/dojox/mobile/_IconItemPane.js
new file mode 100644
index 0000000..4b32cc4
--- /dev/null
+++ b/dojox/mobile/_IconItemPane.js
@@ -0,0 +1,99 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-construct",
+	"./Pane",
+	"./iconUtils",
+	"./sniff"
+], function(declare, domConstruct, Pane, iconUtils, has){
+
+	// module:
+	//		dojox/mobile/_IconItemPane
+
+	return declare("dojox.mobile._IconItemPane", Pane, {
+		// summary:
+		//		An internal widget used for IconContainer.
+
+		// iconPos: String
+		//		The default icon position for child items.
+		iconPos: "",
+		
+		// closeIconRole: String
+		//		The HTML role of the close icon. Example: "button".
+		closeIconRole: "",
+		
+		// closeIconTitle: String
+		//		The title of the close icon.
+		closeIconTitle: "",
+		
+		// label: String
+		//		The label of the item.
+		label: "",
+		
+		// closeIcon: String
+		//		CSS class for the close icon.
+		closeIcon: "mblDomButtonBlueMinus",
+		
+		// baseClass: String
+		//		The name of the CSS class of this widget.
+		baseClass: "mblIconItemPane",
+
+		// tabIndex: String
+		//		Tab index for the close button, such that users can hit the tab
+		//		key to focus on it.
+		tabIndex: "0",
+		
+		// _setTabIndexAttr: [private] String
+		//		Sets tabIndex to closeIconNode.
+		_setTabIndexAttr: "closeIconNode", 
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.hide();
+			this.closeHeaderNode = domConstruct.create("h2", {className:"mblIconItemPaneHeading"}, this.domNode);
+			this.closeIconNode = domConstruct.create("div", {
+				className: "mblIconItemPaneIcon",
+				role: this.closeIconRole,
+				title: this.closeIconTitle
+			}, this.closeHeaderNode);
+			this.labelNode = domConstruct.create("span", {className:"mblIconItemPaneTitle"}, this.closeHeaderNode);
+			this.containerNode = domConstruct.create("div", {className:"mblContent"}, this.domNode);
+		},
+
+		show: function(){
+			// summary:
+			//		Shows the widget.
+			this.domNode.style.display = "";
+		},
+
+		hide: function(){
+			// summary:
+			//		Hides the widget.
+			this.domNode.style.display = "none";
+		},
+
+		isOpen: function(e){
+			// summary:
+			//		Tests whether the widget is open.
+			return this.domNode.style.display !== "none";
+		},
+
+		_setLabelAttr: function(/*String*/text){
+			// tags:
+			//		private
+			this._set("label", text);
+			this.labelNode.innerHTML = this._cv ? this._cv(text) : text;
+		},
+
+		_setCloseIconAttr: function(icon){
+			// tags:
+			//		private
+			this._set("closeIcon", icon);
+			this.closeIconNode = iconUtils.setIcon(icon, this.iconPos, this.closeIconNode, null, this.closeHeaderNode);
+
+			if(has("windows-theme") && this.closeIconTitle !== ""){
+				this.closeButtonNode = domConstruct.create("span", {className:"mblButton mblCloseButton", innerHTML:this.closeIconTitle,
+					style: {display: "none"}}, this.closeIconNode);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/_ItemBase.js b/dojox/mobile/_ItemBase.js
index 2427010..b1773da 100644
--- a/dojox/mobile/_ItemBase.js
+++ b/dojox/mobile/_ItemBase.js
@@ -1,31 +1,26 @@
 define([
-	"dojo/_base/kernel",
-	"dojo/_base/config",
+	"dojo/_base/array",
 	"dojo/_base/declare",
-	"dijit/registry",	// registry.getEnclosingWidget
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/touch",
+	"dijit/registry",
 	"dijit/_Contained",
 	"dijit/_Container",
 	"dijit/_WidgetBase",
 	"./TransitionEvent",
-	"./View"
-], function(kernel, config, declare, registry, Contained, Container, WidgetBase, TransitionEvent, View){
-
-/*=====
-	var Contained = dijit._Contained;
-	var Container = dijit._Container;
-	var WidgetBase = dijit._WidgetBase;
-	var TransitionEvent = dojox.mobile.TransitionEvent;
-	var View = dojox.mobile.View;
-=====*/
+	"./iconUtils",
+	"./sniff",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/_ItemBase"
+], function(array, declare, lang, win, domClass, touch, registry, Contained, Container, WidgetBase, TransitionEvent, iconUtils, has, BidiItemBase){
 
 	// module:
 	//		dojox/mobile/_ItemBase
-	// summary:
-	//		A base class for item classes (e.g. ListItem, IconItem, etc.)
 
-	return declare("dojox.mobile._ItemBase", [WidgetBase, Container, Contained],{
+	var _ItemBase = declare(has("dojo-bidi") ? "dojox.mobile._NonBidiItemBase" : "dojox.mobile._ItemBase", [WidgetBase, Container, Contained], {
 		// summary:
-		//		A base class for item classes (e.g. ListItem, IconItem, etc.)
+		//		A base class for item classes (e.g. ListItem, IconItem, etc.).
 		// description:
 		//		_ItemBase is a base class for widgets that have capability to
 		//		make a view transition when clicked.
@@ -44,7 +39,7 @@ define([
 		iconPos: "", // top,left,width,height (ex. "0,0,29,29")
 
 		// alt: String
-		//		An alt text for the icon image.
+		//		An alternate text for the icon image.
 		alt: "",
 
 		// href: String
@@ -62,7 +57,7 @@ define([
 		//		current page.
 		//
 		//		If the value has a hash sign ('#') before the id (e.g. #view1)
-		//		and the dojo.hash module is loaded by the user application, the
+		//		and the dojo/hash module is loaded by the user application, the
 		//		view transition updates the hash in the browser URL so that the
 		//		user can bookmark the destination view. In this case, the user
 		//		can also use the browser's back/forward button to navigate
@@ -73,7 +68,7 @@ define([
 		moveTo: "",
 
 		// scene: String
-		//		The name of a scene. Used from dojox.mobile.app.
+		//		The name of a scene. Used from dojox/mobile/app.
 		scene: "",
 
 		// clickable: Boolean
@@ -95,13 +90,17 @@ define([
 		//		a sibling of the current view.
 		urlTarget: "",
 
+		// back: Boolean
+		//		If true, history.back() is called when clicked.
+		back: false,
+
 		// transition: String
 		//		A type of animated transition effect. You can choose from the
 		//		standard transition types, "slide", "fade", "flip", or from the
 		//		extended transition types, "cover", "coverv", "dissolve",
 		//		"reveal", "revealv", "scaleIn", "scaleOut", "slidev",
-		//		"swirl", "zoomIn", "zoomOut". If "none" is specified, transition
-		//		occurs immediately without animation.
+		//		"swirl", "zoomIn", "zoomOut", "cube", and "swap". If "none" is
+		//		specified, transition occurs immediately without animation.
 		transition: "",
 
 		// transitionDir: Number
@@ -121,14 +120,6 @@ define([
 		//		context.
 		callback: null,
 
-		// sync: Boolean
-		//		If true, XHR for the view content specified with the url
-		//		parameter is performed synchronously. If false, it is done
-		//		asynchronously and the progress indicator is displayed while
-		//		loading the content. This parameter is effective only when the
-		//		url parameter is used.
-		sync: true,
-
 		// label: String
 		//		A label of the item. If the label is not specified, innerHTML is
 		//		used as a label.
@@ -138,86 +129,277 @@ define([
 		//		If true, the item acts like a toggle button.
 		toggle: false,
 
+		// selected: Boolean
+		//		If true, the item is highlighted to indicate it is selected.
+		selected: false,
+
+		// tabIndex: String
+		//		Tabindex setting for the item so users can hit the tab key to
+		//		focus on it.
+		tabIndex: "0",
+		
+		// _setTabIndexAttr: [private] String
+		//		Sets tabIndex to domNode.
+		_setTabIndexAttr: "",
+
+		/* internal properties */	
+
+		// paramsToInherit: String
+		//		Comma separated parameters to inherit from the parent.
+		paramsToInherit: "transition,icon",
+
+		// _selStartMethod: String
+		//		Specifies how the item enters the selected state.
+		//
+		//		- "touch": Use touch events to enter the selected state.
+		//		- "none": Do not change the selected state.
+		_selStartMethod: "none", // touch or none
+
+		// _selEndMethod: String
+		//		Specifies how the item leaves the selected state.
+		//
+		//		- "touch": Use touch events to leave the selected state.
+		//		- "timer": Use setTimeout to leave the selected state.
+		//		- "none": Do not change the selected state.
+		_selEndMethod: "none", // touch, timer, or none
+
+		// _delayedSelection: Boolean
+		//		If true, selection is delayed 100ms and canceled if dragged in
+		//		order to avoid selection when flick operation is performed.
+		_delayedSelection: false,
+
 		// _duration: Number
 		//		Duration of selection, milliseconds.
 		_duration: 800,
 
-	
+		// _handleClick: Boolean
+		//		If true, this widget listens to touch events.
+		_handleClick: true,
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			this._isOnLine = this.inheritParams();
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			if(!this._isOnLine){
+				this.inheritParams();
+			}
+			this._updateHandles();
+			this.inherited(arguments);
+		},
+
 		inheritParams: function(){
+			// summary:
+			//		Copies from the parent the values of parameters specified 
+			//		by the property paramsToInherit.
 			var parent = this.getParent();
 			if(parent){
-				if(!this.transition){ this.transition = parent.transition; }
-				if(this.icon && parent.iconBase &&
-					parent.iconBase.charAt(parent.iconBase.length - 1) === '/'){
-					this.icon = parent.iconBase + this.icon;
+				array.forEach(this.paramsToInherit.split(/,/), function(p){
+					if(p.match(/icon/i)){
+						var base = p + "Base", pos = p + "Pos";
+						if(this[p] && parent[base] &&
+							parent[base].charAt(parent[base].length - 1) === '/'){
+							this[p] = parent[base] + this[p];
+						}
+						if(!this[p]){ this[p] = parent[base]; }
+						if(!this[pos]){ this[pos] = parent[pos]; }
+					}
+					if(!this[p]){ this[p] = parent[p]; }
+				}, this);
+			}
+			return !!parent;
+		},
+
+		_updateHandles: function(){
+			// tags:
+			//		private
+			if(this._handleClick && this._selStartMethod === "touch"){
+				if(!this._onTouchStartHandle){
+					this._onTouchStartHandle = this.connect(this.domNode, touch.press, "_onTouchStart");
+				}
+			}else{
+				if(this._onTouchStartHandle){
+					this.disconnect(this._onTouchStartHandle);
+					this._onTouchStartHandle = null;
 				}
-				if(!this.icon){ this.icon = parent.iconBase; }
-				if(!this.iconPos){ this.iconPos = parent.iconPos; }
 			}
 		},
-	
-		select: function(){
+		
+		getTransOpts: function(){
 			// summary:
-			//		Makes this widget in the selected state.
-			// description:
-			//		Subclass must implement.
+			//		Copies from the parent and returns the values of parameters  
+			//		specified by the property paramsToInherit.
+			var opts = this.transitionOptions || {};
+			array.forEach(["moveTo", "href", "hrefTarget", "url", "target",
+				"urlTarget", "scene", "transition", "transitionDir"], function(p){
+				opts[p] = opts[p] || this[p];
+			}, this);
+			return opts; // Object
 		},
-	
-		deselect: function(){
+
+		userClickAction: function(/*Event*/ /*===== e =====*/){
 			// summary:
-			//		Makes this widget in the deselected state.
-			// description:
-			//		Subclass must implement.
+			//		User-defined click action.
+		},
+
+		defaultClickAction: function(/*Event*/e){
+			// summary:
+			//		The default action of this item.
+			this.handleSelection(e);
+			if(this.userClickAction(e) === false){ return; } // user's click action
+			this.makeTransition(e);
 		},
-	
-		defaultClickAction: function(e){
+
+		handleSelection: function(/*Event*/e){
+			// summary:
+			//		Handles this items selection state.
+
+			// Before transitioning, we want the visual effect of selecting the item.
+			// To ensure this effect happens even if _delayedSelection is true:
+			if(this._delayedSelection){
+				this.set("selected", true);
+			} // the item will be deselected after transition.
+
+			if(this._onTouchEndHandle){
+				this.disconnect(this._onTouchEndHandle);
+				this._onTouchEndHandle = null;
+			}
+
+			var p = this.getParent();
 			if(this.toggle){
-				if(this.selected){
-					this.deselect();
-				}else{
-					this.select();
-				}
-			}else if(!this.selected){
-				this.select();
-				if(!this.selectOne){
-					var _this = this;
-					setTimeout(function(){
-						_this.deselect();
+				this.set("selected", !this._currentSel);
+			}else if(p && p.selectOne){
+				this.set("selected", true);
+			}else{
+				if(this._selEndMethod === "touch"){
+					this.set("selected", false);
+				}else if(this._selEndMethod === "timer"){
+					this.defer(function(){
+						this.set("selected", false);
 					}, this._duration);
 				}
-				var transOpts;
-				if(this.moveTo || this.href || this.url || this.scene){
-					transOpts = {moveTo: this.moveTo, href: this.href, url: this.url, scene: this.scene, transition: this.transition, transitionDir: this.transitionDir};
-				}else if(this.transitionOptions){
-					transOpts = this.transitionOptions;
-				}	
-				if(transOpts){
-					return new TransitionEvent(this.domNode,transOpts,e).dispatch();
+			}
+		},
+
+		makeTransition: function(/*Event*/e){
+			// summary:
+			//		Makes a transition.
+			if(this.back && history){
+				history.back();	
+				return;
+			}	
+			if (this.href && this.hrefTarget && this.hrefTarget != "_self") {
+				win.global.open(this.href, this.hrefTarget || "_blank");
+				this._onNewWindowOpened(e);
+				return;
+			}
+			var opts = this.getTransOpts();
+			var doTransition = 
+				!!(opts.moveTo || opts.href || opts.url || opts.target || opts.scene);
+			if(this._prepareForTransition(e, doTransition ? opts : null) === false){ return; }
+			if(doTransition){
+				this.setTransitionPos(e);
+				new TransitionEvent(this.domNode, opts, e).dispatch();
+			}
+		},
+
+		_onNewWindowOpened: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		Subclasses may want to implement it.
+		},
+
+		_prepareForTransition: function(/*Event*/e, /*Object*/transOpts){
+			// summary:
+			//		Subclasses may want to implement it.
+		},
+
+		_onTouchStart: function(e){
+			// tags:
+			//		private
+			if(this.getParent().isEditing || this.onTouchStart(e) === false){ return; } // user's touchStart action
+			if(!this._onTouchEndHandle && this._selStartMethod === "touch"){
+				// Connect to the entire window. Otherwise, fail to receive
+				// events if operation is performed outside this widget.
+				// Expose both connect handlers in case the user has interest.
+				this._onTouchMoveHandle = this.connect(win.body(), touch.move, "_onTouchMove");
+				this._onTouchEndHandle = this.connect(win.body(), touch.release, "_onTouchEnd");
+			}
+			this.touchStartX = e.touches ? e.touches[0].pageX : e.clientX;
+			this.touchStartY = e.touches ? e.touches[0].pageY : e.clientY;
+			this._currentSel = this.selected;
+
+			if(this._delayedSelection){
+				// so as not to make selection when the user flicks on ScrollableView
+				this._selTimer = this.defer(function(){
+					this.set("selected", true);
+				}, 100);
+			}else{
+				this.set("selected", true);
+			}
+		},
+
+		onTouchStart: function(/*Event*/ /*===== e =====*/){
+			// summary:
+			//		User-defined function to handle touchStart events.
+			// tags:
+			//		callback
+		},
+
+		_onTouchMove: function(e){
+			// tags:
+			//		private
+			var x = e.touches ? e.touches[0].pageX : e.clientX;
+			var y = e.touches ? e.touches[0].pageY : e.clientY;
+			if(Math.abs(x - this.touchStartX) >= 4 ||
+			   Math.abs(y - this.touchStartY) >= 4){ // dojox/mobile/scrollable.threshold
+				this.cancel();
+				var p = this.getParent();
+				if(p && p.selectOne){
+					this._prevSel && this._prevSel.set("selected", true);
+				}else{
+					this.set("selected", false);
 				}
 			}
 		},
-	
-		getParent: function(){
+
+		_disconnect: function(){
+			// tags:
+			//		private
+			this.disconnect(this._onTouchMoveHandle);
+			this.disconnect(this._onTouchEndHandle);
+			this._onTouchMoveHandle = this._onTouchEndHandle = null;
+		},
+
+		cancel: function(){
 			// summary:
-			//		Gets the parent widget.
-			// description:
-			//		Almost equivalent to _Contained#getParent, but this method
-			//		does not cause a script error even if this widget has no
-			//		parent yet.
-			var ref = this.srcNodeRef || this.domNode;
-			return ref && ref.parentNode ? registry.getEnclosingWidget(ref.parentNode) : null;
+			//		Cancels an ongoing selection (if any).
+			if(this._selTimer){
+				this._selTimer.remove(); 
+				this._selTimer = null;
+			}
+			this._disconnect();
+		},
+
+		_onTouchEnd: function(e){
+			// tags:
+			//		private
+			if(!this._selTimer && this._delayedSelection){ return; }
+			this.cancel();
+			this._onClick(e);
 		},
 
 		setTransitionPos: function(e){
 			// summary:
 			//		Stores the clicked position for later use.
 			// description:
-			//		Some of the transition animations (e.g. ScaleIn) needs the
+			//		Some of the transition animations (e.g. ScaleIn) need the
 			//		clicked position.
 			var w = this;
 			while(true){
 				w = w.getParent();
-				if(!w || w instanceof View){ break; }
+				if(!w || domClass.contains(w.domNode, "mblView")){ break; }
 			}
 			if(w){
 				w.clickedPosX = e.clientX;
@@ -225,24 +407,60 @@ define([
 			}
 		},
 
-		transitionTo: function(moveTo, href, url, scene){
+		transitionTo: function(/*String|Object*/moveTo, /*String*/href, /*String*/url, /*String*/scene){
 			// summary:
 			//		Performs a view transition.
 			// description:
 			//		Given a transition destination, this method performs a view
 			//		transition. This method is typically called when this item
 			//		is clicked.
-			if(config.isDebug){
-				var alreadyCalledHash = arguments.callee._ach || (arguments.callee._ach = {}),
-					caller = (arguments.callee.caller || "unknown caller").toString();
-				if(!alreadyCalledHash[caller]){
-					kernel.deprecated(this.declaredClass + "::transitionTo() is deprecated." +
-					caller, "", "2.0");
-					alreadyCalledHash[caller] = true;
+			var opts = (moveTo && typeof(moveTo) === "object") ? moveTo :
+				{moveTo: moveTo, href: href, url: url, scene: scene,
+				 transition: this.transition, transitionDir: this.transitionDir};
+			new TransitionEvent(this.domNode, opts).dispatch();
+		},
+
+		_setIconAttr: function(icon){
+			// tags:
+			//		private
+			if(!this._isOnLine){
+				// record the value to be able to reapply it (see the code in the startup method)
+				this._pendingIcon = icon;  
+				return; 
+			} // icon may be invalid because inheritParams is not called yet
+			this._set("icon", icon);
+			this.iconNode = iconUtils.setIcon(icon, this.iconPos, this.iconNode, this.alt, this.iconParentNode, this.refNode, this.position);
+		},
+
+		_setLabelAttr: function(/*String*/text){
+			// tags:
+			//		private
+			this._set("label", text);
+			this.labelNode.innerHTML = this._cv ? this._cv(text) : text;
+		},
+
+		_setSelectedAttr: function(/*Boolean*/selected){
+			// summary:
+			//		Makes this widget in the selected or unselected state.
+			// description:
+			//		Subclass should override.
+			// tags:
+			//		private
+			if(selected){
+				var p = this.getParent();
+				if(p && p.selectOne){
+					// deselect the currently selected item
+					var arr = array.filter(p.getChildren(), function(w){
+						return w.selected;
+					});
+					array.forEach(arr, function(c){
+						this._prevSel = c;
+						c.set("selected", false);
+					}, this);
 				}
 			}
-			new TransitionEvent(this.domNode, {moveTo: moveTo, href: href, url: url, scene: scene,
-						transition: this.transition, transitionDir: this.transitionDir}).dispatch();
+			this._set("selected", selected);
 		}
 	});
+	return has("dojo-bidi") ? declare("dojox.mobile._ItemBase", [_ItemBase, BidiItemBase]) : _ItemBase;
 });
diff --git a/dojox/mobile/_ListTouchMixin.js b/dojox/mobile/_ListTouchMixin.js
index 265f44c..1a9657f 100644
--- a/dojox/mobile/_ListTouchMixin.js
+++ b/dojox/mobile/_ListTouchMixin.js
@@ -1,32 +1,48 @@
 define([
 	"dojo/_base/declare",
-	"dojo/_base/event",
+	"dojo/touch",
+	"./sniff",
 	"dijit/form/_ListBase"
-], function(declare, event, ListBase){
+], function(declare, touch, has, ListBase){
 
-	/*=====
-		ListBase = dijit.form._ListBase;
-	=====*/
 	return declare( "dojox.mobile._ListTouchMixin", ListBase, {
 		// summary:
-		//		Focus-less menu to handle touch events consistently
-		//		Abstract methods that must be defined externally:
-		//			onClick: item was chosen (mousedown somewhere on the menu and mouseup somewhere on the menu)
-		// tags:
-		//		private
-	
+		//		Focus-less menu to handle touch events consistently.
+		// description:
+		//		Focus-less menu to handle touch events consistently. Abstract
+		//		method that must be defined externally:
+		//
+		//		- onClick: item was chosen (mousedown somewhere on the menu and mouseup somewhere on the menu).
+
 		postCreate: function(){
 			this.inherited(arguments);
-			this.connect(this.domNode, "onclick", "_onClick");
-		},
-	
-		_onClick: function(/*Event*/ evt){
-			event.stop(evt);
-			var target = this._getTarget(evt);
-			if(target){
-				this._setSelectedAttr(target);
-				this.onClick(target);
+
+			// For some reason in IE click event is fired immediately after user scrolled combobox control and released
+			// his/her finger. As a fix we replace click with tap event that is fired correctly.
+			if(!(has("ie") >= 10 && typeof(MSGesture) !== "undefined")){ 
+				this._listConnect("click", "_onClick");
+			}else{
+				this._listConnect(touch.press, "_onPress");
+
+				var self = this,
+					tapGesture = new MSGesture(),
+					target;
+
+				this._onPress = function(e){
+					tapGesture.target = self.domNode;
+					tapGesture.addPointer(e.pointerId);
+					target = e.target;
+				}
+
+				this.on("MSGestureTap", function(e){
+					self._onClick(e, target);
+				});
 			}
+		},
+
+		_onClick: function(/*Event*/ evt, /*DomNode*/ target){
+			this._setSelectedAttr(target);
+			this.onClick(target);
 		}
 	});
 });
diff --git a/dojox/mobile/_PickerBase.js b/dojox/mobile/_PickerBase.js
new file mode 100644
index 0000000..0eecc37
--- /dev/null
+++ b/dojox/mobile/_PickerBase.js
@@ -0,0 +1,116 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dijit/_Contained",
+	"dijit/_Container",
+	"dijit/_WidgetBase"
+], function(array, declare, Contained, Container, WidgetBase){
+
+	// module:
+	//		dojox/mobile/_PickerBase
+
+	return declare("dojox.mobile._PickerBase", [WidgetBase, Container, Contained], {
+		// summary:
+		//		A base class for picker classes (e.g. SpinWheel, ValuePicker).
+
+		/*=====
+		// values: Array
+		//		An array of slot values.
+		//		Warning: Do not use this property directly, make sure to call set() or get() methods.
+		values: "",
+		=====*/
+		
+		/*=====
+		// colors: Array
+		//		An array of slot colors.
+		//		Warning: Do not use this property directly, make sure to call set() or get() methods.
+		colors: "",
+		=====*/
+		
+		/* internal properties */
+
+		// slotClasses: [protected] Array
+		//		An array of slot classes. This property is intended to be used
+		//		when you create a subclass of this widget that has specific slots.
+		slotClasses: [],
+
+		// slotProps: [protected] Array
+		//		An array of property objects for each slot class specified in
+		//		slotClasses. This property is intended to be used when you
+		//		create a subclass of this widget that has specific slots.
+		slotProps: [],
+
+		// slotOrder: [protected] Array
+		//		An array of index of slotClasses and slotProps.
+		//		If there are three slots and slotOrder=[2,1,0], the slots are
+		//		displayed in reversed order. This property is intended to be used
+		//		when you create a subclass of this widget that has specific slots.
+		slotOrder: [],
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.slots = [];
+			for(var i = 0; i < this.slotClasses.length; i++){
+				var idx = this.slotOrder.length ? this.slotOrder[i] : i;
+				var slot = new this.slotClasses[idx](this.slotProps[idx]);
+				this.addChild(slot);
+				this.slots[idx] = slot;
+			}
+		},
+
+		startup: function(){
+			if(this._started){ return; }
+			this._duringStartup = true;
+			this.inherited(arguments);
+			this.reset();
+			delete this._duringStartup;
+		},
+
+		getSlots: function(){
+			// summary:
+			//		Returns an array of child slot widgets.
+			return this.slots.length ? this.slots :
+				array.filter(this.getChildren(), function(c){
+					return c.declaredClass.indexOf("Slot") !== -1;
+				});
+		},
+
+		_getValuesAttr: function(){
+			// summary:
+			//		Returns an array of slot values.
+			// tags:
+			//		private
+			return array.map(this.getSlots(), function(w){
+				return w.get("value");
+			});
+		},
+
+		_setValuesAttr: function(/*Array*/a){
+			// summary:
+			//		Sets the slot values.
+			// tags:
+			//		private
+			array.forEach(this.getSlots(), function(w, i){
+				w.set("value", a[i]);
+			});
+		},
+
+		_setColorsAttr: function(/*Array*/a){
+			// summary:
+			//		Sets the slot colors.
+			// tags:
+			//		private
+			array.forEach(this.getSlots(), function(w, i){
+				w.setColor && w.setColor(a[i]);
+			});
+		},
+
+		reset: function(){
+			// summary:
+			//		Resets the picker to show the initial values.
+			array.forEach(this.getSlots(), function(w){
+				w.setInitialValue();
+			});
+		}
+	});
+});
diff --git a/dojox/mobile/_PickerChooser.js b/dojox/mobile/_PickerChooser.js
new file mode 100644
index 0000000..a8be642
--- /dev/null
+++ b/dojox/mobile/_PickerChooser.js
@@ -0,0 +1,22 @@
+define([
+	"dojo/_base/lang",
+	"dojo/_base/window"
+], function(lang, win){
+
+	// module:
+	//		dojox/mobile/_PickerChooser
+
+	return{
+		// summary:
+		//		This widget chooses a picker class according to the current theme.
+		//		Imports ValuePicker-based date/time picker when the current theme is "android".
+		//		Imports SpinWheel-based date/time picker otherwise.
+
+		load: function (id, parentRequire, loaded){
+			// summary:
+			//		Imports a picker class according to the current theme.
+			var dm = win.global._no_dojo_dm || lang.getObject("dojox.mobile", true);
+			parentRequire([(dm.currentTheme === "android" || dm.currentTheme === "holodark" ? "./ValuePicker" : "./SpinWheel") + id], loaded);
+		}
+	};
+});
diff --git a/dojox/mobile/_ScrollableMixin.js b/dojox/mobile/_ScrollableMixin.js
index f402616..c8106a7 100644
--- a/dojox/mobile/_ScrollableMixin.js
+++ b/dojox/mobile/_ScrollableMixin.js
@@ -1,5 +1,6 @@
 define([
 	"dojo/_base/kernel",
+	"dojo/_base/config",
 	"dojo/_base/declare",
 	"dojo/_base/lang",
 	"dojo/_base/window",
@@ -7,20 +8,14 @@ define([
 	"dojo/dom-class",
 	"dijit/registry",	// registry.byNode
 	"./scrollable"
-], function(dojo, declare, lang, win, dom, domClass, registry, Scrollable){
+], function(dojo, config, declare, lang, win, dom, domClass, registry, Scrollable){
 	// module:
 	//		dojox/mobile/_ScrollableMixin
-	// summary:
-	//		Mixin for widgets to have a touch scrolling capability.
 
-	var cls = declare("dojox.mobile._ScrollableMixin", null, {
+	var cls = declare("dojox.mobile._ScrollableMixin", Scrollable, {
 		// summary:
 		//		Mixin for widgets to have a touch scrolling capability.
-		// description:
-		//		Actual implementation is in scrollable.js.
-		//		scrollable.js is not a dojo class, but just a collection
-		//		of functions. This module makes scrollable.js a dojo class.
-
+	
 		// fixedHeader: String
 		//		Id of the fixed header.
 		fixedHeader: "",
@@ -29,15 +24,25 @@ define([
 		//		Id of the fixed footer.
 		fixedFooter: "",
 
+		_fixedAppFooter: "",
+
 		// scrollableParams: Object
-		//		Parameters for dojox.mobile.scrollable.init().
+		//		Parameters for dojox/mobile/scrollable.init().
 		scrollableParams: null,
 
 		// allowNestedScrolls: Boolean
-		//		e.g. Allow ScrollableView in a SwapView.
+		//		Flag to allow scrolling in nested containers, e.g. to allow ScrollableView in a SwapView.
 		allowNestedScrolls: true,
 
+		// appBars: Boolean
+		//		Enables the search for application-specific bars (header or footer).
+		appBars: true, 
+
 		constructor: function(){
+			// summary:
+			//		Creates a new instance of the class.
+			// tags:
+			//		private
 			this.scrollableParams = {};
 		},
 
@@ -48,8 +53,11 @@ define([
 
 		startup: function(){
 			if(this._started){ return; }
-			var node;
-			var params = this.scrollableParams;
+			if(this._fixedAppFooter){
+				this._fixedAppFooter = dom.byId(this._fixedAppFooter);
+			}
+			this.findAppBars();
+			var node, params = this.scrollableParams;
 			if(this.fixedHeader){
 				node = dom.byId(this.fixedHeader);
 				if(node.parentNode == this.domNode){ // local footer
@@ -65,23 +73,33 @@ define([
 				}
 				params.fixedFooterHeight = node.offsetHeight;
 			}
+			this.scrollType = this.scrollType || config["mblScrollableScrollType"] || 0;
 			this.init(params);
 			if(this.allowNestedScrolls){
 				for(var p = this.getParent(); p; p = p.getParent()){
 					if(p && p.scrollableParams){
-						this.isNested = true;
 						this.dirLock = true;
 						p.dirLock = true;
 						break;
 					}
 				}
 			}
+			// subscribe to afterResizeAll to scroll the focused input field into view
+			// so as not to break layout on orientation changes while keyboard is shown (#14991)
+			this._resizeHandle = this.subscribe("/dojox/mobile/afterResizeAll", function(){
+				if(this.domNode.style.display === 'none'){ return; }
+				var elem = win.doc.activeElement;
+				if(this.isFormElement(elem) && dom.isDescendant(elem, this.containerNode)){
+					this.scrollIntoView(elem);
+				}
+			});
 			this.inherited(arguments);
 		},
 
 		findAppBars: function(){
 			// summary:
 			//		Search for application-specific header or footer.
+			if(!this.appBars){ return; }
 			var i, len, c;
 			for(i = 0, len = win.body().childNodes.length; i < len; i++){
 				c = win.body().childNodes[i];
@@ -100,7 +118,8 @@ define([
 			// summary:
 			//		Checks if the given node is a fixed bar or not.
 			if(node.nodeType === 1){
-				var fixed = node.getAttribute("fixed")
+				var fixed = node.getAttribute("fixed") // TODO: Remove the non-HTML5-compliant attribute in 2.0
+					|| node.getAttribute("data-mobile-fixed")
 					|| (registry.byNode(node) && registry.byNode(node).fixed);
 				if(fixed === "top"){
 					domClass.add(node, "mblFixedHeaderBar");
@@ -111,13 +130,16 @@ define([
 					return fixed;
 				}else if(fixed === "bottom"){
 					domClass.add(node, "mblFixedBottomBar");
-					this.fixedFooter = node;
+					if(local){
+						this.fixedFooter = node;
+					}else{
+						this._fixedAppFooter = node;
+					}
 					return fixed;
 				}
 			}
 			return null;
 		}
 	});
-	lang.extend(cls, new Scrollable(dojo, dojox));
 	return cls;
 });
diff --git a/dojox/mobile/_StoreListMixin.js b/dojox/mobile/_StoreListMixin.js
new file mode 100644
index 0000000..87125c7
--- /dev/null
+++ b/dojox/mobile/_StoreListMixin.js
@@ -0,0 +1,124 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"./_StoreMixin",
+	"./ListItem",
+	"dojo/has",
+	"dojo/has!dojo-bidi?dojox/mobile/bidi/_StoreListMixin"
+], function(array, declare, StoreMixin, ListItem, has, BidiStoreListMixin){
+
+	// module:
+	//		dojox/mobile/_StoreListMixin
+
+	var _StoreListMixin = declare(has("dojo-bidi") ? "dojox.mobile._NonBidiStoreListMixin" : "dojox.mobile._StoreListMixin", StoreMixin, {
+		// summary:
+		//		Mixin for widgets to generate the list items corresponding to
+		//		the dojo/store data provider object.
+		// description:
+		//		Mixin for widgets to generate the list items corresponding to
+		//		the dojo/store data provider object.
+		//		By mixing this class into the widgets, the list item nodes are
+		//		generated as the child nodes of the widget and automatically
+		//		regenerated whenever the corresponding data items are modified.
+
+		// append: Boolean
+		//		If true, refresh() does not clear the existing items.
+		append: false,
+
+		// itemMap: Object
+		//		An optional parameter mapping field names from the store to ItemList names.
+		//		Example: itemMap:{text:'label', profile_image_url:'icon'}
+		itemMap: null,
+
+		// itemRenderer: ListItem class or subclass
+		//		The class used to create list items. Default is dojox/mobile/ListItem.
+		itemRenderer: ListItem,
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			if(!this.store){ return; }
+			var store = this.store;
+			this.store = null;
+			this.setStore(store, this.query, this.queryOptions);
+		},
+
+		createListItem: function(/*Object*/item){
+			// summary:
+			//		Creates a list item widget.
+			return new this.itemRenderer(this._createItemProperties(item));
+		},
+		
+		_createItemProperties: function(/*Object*/item){
+			// summary:
+			//		Creates list item properties.
+			var props = {};
+			if(!item["label"]){
+				props["label"] = item[this.labelProperty];
+			}
+			// TODO this code should be like for textDir in the bidi mixin createListItem method
+			// however for that dynamic set/get of the dir property must be supported first
+			// that is why for now as a workaround we keep the code here
+			if(has("dojo-bidi") && typeof props["dir"] == "undefined"){
+				props["dir"] = this.isLeftToRight() ? "ltr" : "rtl";
+			}
+			for(var name in item){
+				props[(this.itemMap && this.itemMap[name]) || name] = item[name];
+			}
+			return props;
+		},
+		
+		_setDirAttr: function(props){
+			// summary:
+			//		Set the 'dir' attribute to support Mirroring.
+			//		To be implemented by the bidi/_StoreLisMixin.js
+			return props;
+		},
+		generateList: function(/*Array*/items){
+			// summary:
+			//		Given the data, generates a list of items.
+			if(!this.append){
+				array.forEach(this.getChildren(), function(child){
+					child.destroyRecursive();
+				});
+			}
+			array.forEach(items, function(item, index){
+				this.addChild(this.createListItem(item));
+				if(item[this.childrenProperty]){
+					array.forEach(item[this.childrenProperty], function(child, index){
+						this.addChild(this.createListItem(child));
+					}, this);
+				}
+			}, this);
+		},
+
+		onComplete: function(/*Array*/items){
+			// summary:
+			//		A handler that is called after the fetch completes.
+			this.generateList(items);
+		},
+
+		onError: function(/*Object*/ /*===== errorData =====*/){
+			// summary:
+			//		An error handler.
+		},
+
+		onAdd: function(/*Object*/item, /*Number*/insertedInto){
+			// summary:
+			//		Calls createListItem and adds the new list item when a new data item has been added to the store.
+			this.addChild(this.createListItem(item), insertedInto);
+		},
+
+		onUpdate: function(/*Object*/item, /*Number*/insertedInto){
+			// summary:
+			//		Updates an existing list item when a data item has been modified.
+			this.getChildren()[insertedInto].set(this._createItemProperties(item));
+		},
+
+		onDelete: function(/*Object*/item, /*Number*/removedFrom){
+			// summary:
+			//		Deletes an existing item.
+			this.getChildren()[removedFrom].destroyRecursive();
+		}
+	});
+	return has("dojo-bidi") ? declare("dojox.mobile._StoreListMixin", [_StoreListMixin, BidiStoreListMixin]) : _StoreListMixin;	
+});
diff --git a/dojox/mobile/_StoreMixin.js b/dojox/mobile/_StoreMixin.js
new file mode 100644
index 0000000..c653b47
--- /dev/null
+++ b/dojox/mobile/_StoreMixin.js
@@ -0,0 +1,150 @@
+define([
+	"dojo/_base/Deferred",
+	"dojo/_base/declare"
+], function(Deferred, declare){
+
+	// module:
+	//		dojox/mobile/_StoreMixin
+
+	return declare("dojox.mobile._StoreMixin", null, {
+		// summary:
+		//		Mixin for widgets to enable dojo/store data store.
+		// description:
+		//		By mixing this class into a widget, it can get data through a
+		//		dojo/store data store. The widget must implement the following
+		//		methods to handle the retrieved data:
+		//
+		//		- onComplete(/*Array*/items), onError(/*Object*/errorData),
+		//		- onUpdate(/*Object*/item, /*Number*/insertedInto), and
+		//		- onDelete(/*Object*/item, /*Number*/removedFrom).
+	
+		// store: Object
+		//		Reference to data provider object used by this widget.
+		store: null,
+
+		// query: Object
+		//		A query that can be passed to 'store' to initially filter the items.
+		query: null,
+
+		// queryOptions: Object
+		//		An optional parameter for the query.
+		queryOptions: null,
+
+		// labelProperty: String
+		//		A property name (a property in the dojo/store item) that specifies that item's label.
+		labelProperty: "label",
+
+		// childrenProperty: String
+		//		A property name (a property in the dojo/store item) that specifies that item's children.
+		childrenProperty: "children",
+
+		setStore: function(/*dojo/store/api/Store*/store, /*String*/query, /*Object*/queryOptions){
+			// summary:
+			//		Sets the store to use with this widget.
+			if(store === this.store){ return null; }
+			if(store){
+				store.getValue = function(item, property){
+					return item[property];
+				};
+			}
+			this.store = store;
+			this._setQuery(query, queryOptions);
+			return this.refresh();
+		},
+
+		setQuery: function(/*String*/query, /*Object*/queryOptions){
+			this._setQuery(query, queryOptions);
+			return this.refresh();
+		},
+
+		_setQuery: function(/*String*/query, /*Object*/queryOptions){
+			// tags:
+			//		private
+			this.query = query;
+			this.queryOptions = queryOptions || this.queryOptions;
+		},
+
+		refresh: function(){
+			// summary:
+			//		Fetches the data and generates the list items.
+			if(!this.store){ return null; }
+			var _this = this;
+			var promise = this.store.query(this.query, this.queryOptions);
+			if(this._observe_h){
+				this._observe_h.remove();
+			}
+			Deferred.when(promise, function(results){
+				if(results.items){
+					results = results.items; // looks like dojo/data style items array
+				}
+				if(promise.observe){
+					_this._observe_h = promise.observe(function(object, previousIndex, newIndex){
+						if(previousIndex != -1){
+							if(newIndex != previousIndex){
+								// item removed or moved
+								_this.onDelete(object, previousIndex);
+								// TODO: support move, i.e. newIndex != -1?
+							}else{
+								// item modified
+								// if onAdd is not defined, we are "bug compatible" with 1.8 and we do nothing.
+								// TODO remove test in 2.0
+								if(_this.onAdd){
+									_this.onUpdate(object, newIndex);
+								}
+							}
+						}else if(newIndex != -1){
+							// item added
+							if(_this.onAdd){
+								 // new widget with onAdd method defined
+								_this.onAdd(object, newIndex);
+							}else{
+								// TODO remove in 2.0
+								// compatibility with 1.8: onAdd did not exist, add was handled by onUpdate
+								_this.onUpdate(object, newIndex);
+							}
+						}												
+					}, true); // we want to be notified of updates
+				}
+				_this.onComplete(results);
+			}, function(error){
+				_this.onError(error);
+			});
+			return promise;
+		}
+
+/*=====
+		// Subclass MUST implement the following methods.
+
+		, onComplete: function(items){
+			// summary:
+			//		A handler that is called after the fetch completes.
+		},
+
+		onError: function(errorData){
+			// summary:
+			//		An error handler.
+		},
+
+		onUpdate: function(item, insertedInto){
+			// summary:
+			//		Called when an existing data item has been modified in the store.
+			//		Note: for compatibility with previous versions where only onUpdate was present,
+			//		if onAdd is not defined, onUpdate will be called instead.
+		},
+
+		onDelete: function(item, removedFrom){
+			// summary:
+			//		Called when a data item has been removed from the store.
+		},
+		
+		// Subclass should implement the following methods.
+
+		onAdd: function(item, insertedInto){
+			// summary:
+			//		Called when a new data item has been added to the store.
+			//		Note: for compatibility with previous versions where this function did not exist,
+			//		if onAdd is not defined, onUpdate will be called instead.
+		}
+=====*/
+	});
+});
diff --git a/dojox/mobile/_TimePickerMixin.js b/dojox/mobile/_TimePickerMixin.js
new file mode 100644
index 0000000..3a6b109
--- /dev/null
+++ b/dojox/mobile/_TimePickerMixin.js
@@ -0,0 +1,48 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-class",
+	"dojo/date/locale"
+], function(declare, domClass, datelocale){
+
+	// module:
+	//		dojox/mobile/_TimePickerMixin
+
+	return declare("dojox.mobile._TimePickerMixin", null, {
+		// summary:
+		//		A mixin for time picker widget.
+
+		/*=====
+		// date: Date
+		//		A Date object corresponding to the current values of the picker.
+		date: null,
+		=====*/
+		
+		reset: function(){
+			// summary:
+			//		Goes to now. Resets the hour and minutes to the current time.
+			var now = new Date(),
+				h = now.getHours() + "",
+				m = now.getMinutes();
+			m = (m < 10 ? "0" : "") + m;
+			this.set("colors", [h, m]);
+			if(this.values){
+				this.set("values", this.values);
+				this.values = null;
+			}else if(this.values12){
+				this.set("values12", this.values12);
+				this.values12 = null;
+			}else{
+				this.set("values", [h, m]);
+			}
+		},
+
+		_getDateAttr: function(){
+			// summary:
+			//		Returns a Date object for the current values.
+			// tags:
+			//		private
+			var v = this.get("values"); // [hour24, minute]
+			return datelocale.parse(v[0] + ":" + v[1], {timePattern:"H:m", selector:"time"});
+		}
+	});
+});
diff --git a/dojox/mobile/_base.js b/dojox/mobile/_base.js
index 317050a..1a7f149 100644
--- a/dojox/mobile/_base.js
+++ b/dojox/mobile/_base.js
@@ -8,14 +8,23 @@ define([
 	"./RoundRectList",
 	"./EdgeToEdgeList",
 	"./ListItem",
+	"./Container",
+	"./Pane",
 	"./Switch",
 	"./ToolBarButton",
 	"./ProgressIndicator"
 ], function(common, View, Heading, RoundRect, RoundRectCategory, EdgeToEdgeCategory, RoundRectList, EdgeToEdgeList, ListItem, Switch, ToolBarButton, ProgressIndicator){
 	// module:
 	//		dojox/mobile/_base
-	// summary:
-	//		Includes the basic dojox.mobile modules
 
+	/*=====
+	return {
+		// summary:
+		//		Includes the basic dojox/mobile modules: common, View, Heading, 
+		//		RoundRect, RoundRectCategory, EdgeToEdgeCategory, RoundRectList,
+		//		EdgeToEdgeList, ListItem, Container, Pane, Switch, ToolBarButton, 
+		//		and ProgressIndicator.
+	};
+	=====*/
 	return common;
 });
diff --git a/dojox/mobile/_compat.js b/dojox/mobile/_compat.js
index ecbe21a..fadef0f 100644
--- a/dojox/mobile/_compat.js
+++ b/dojox/mobile/_compat.js
@@ -4,11 +4,13 @@ define([
 	"dojo/_base/connect",	// connect.connect
 	"dojo/_base/fx",	// fx.fadeOut, fx.fadeIn
 	"dojo/_base/lang",	// lang.extend, lang.isArray
-	"dojo/_base/sniff",		// has("webkit"), has("ie")
+	"dojo/sniff",		// has("webkit"), has("ie")
 	"dojo/_base/window",	// win.doc, win.body
 	"dojo/dom-class",
 	"dojo/dom-construct",
+	"dojo/dom-geometry",
 	"dojo/dom-style",
+	"dojo/dom-attr",
 	"dojo/fx",
 	"dojo/fx/easing",
 	"dojo/ready",
@@ -18,58 +20,65 @@ define([
 	"dojox/fx/flip",
 	"./EdgeToEdgeList",
 	"./IconContainer",
+	"./ProgressIndicator",
 	"./RoundRect",
 	"./RoundRectList",
 	"./ScrollableView",
 	"./Switch",
 	"./View",
+	"./Heading",
 	"require"
-], function(array, config, connect, bfx, lang, has, win, domClass, domConstruct, domStyle, fx, easing, ready, uacss, registry, xfx, flip, EdgeToEdgeList, IconContainer, RoundRect, RoundRectList, ScrollableView, Switch, View, require){
-
-/*=====
-	var EdgeToEdgeList = dojox.mobile.EdgeToEdgeList;
-	var IconContainer = dojox.mobile.IconContainer;
-	var RoundRect = dojox.mobile.RoundRect;
-	var RoundRectList = dojox.mobile.RoundRectList;
-	var ScrollableView = dojox.mobile.ScrollableView;
-	var Switch = dojox.mobile.Switch;
-	var View = dojox.mobile.View;
-=====*/
+], function(array, config, connect, bfx, lang, has, win, domClass, domConstruct, domGeometry, domStyle, domAttr, fx, easing, ready, uacss, registry, xfx, flip, EdgeToEdgeList, IconContainer, ProgressIndicator, RoundRect, RoundRectList, ScrollableView, Switch, View, Heading, require){
 
 	// module:
 	//		dojox/mobile/compat
+
+/*=====
+return {
 	// summary:
-	//		CSS3 compatibility module
+	//		CSS3 compatibility module.
 	// description:
-	//		This module provides support for some of the CSS3 features to dojox.mobile
-	//		for non-CSS3 browsers, such as IE or Firefox.
-	//		If you load this module, it directly replaces some of the methods of
-	//		dojox.mobile instead of subclassing. This way, html pages remains the same
-	//		regardless of whether this compatibility module is used or not.
-	//		Recommended usage is as follows. the code below loads dojox.mobile.compat
-	//		only when isWebKit is true.
+	//		This module provides to dojox/mobile support for some of the CSS3 features 
+	//		in non-CSS3 browsers, such as IE or Firefox.
+	//		If you require this module, when running in a non-CSS3 browser it directly 
+	//		replaces some of the methods of	dojox/mobile classes, without any subclassing. 
+	//		This way, HTML pages remain the same regardless of whether this compatibility 
+	//		module is used or not.
 	//
-	//		dojo.require("dojox.mobile");
-	//		dojo.requireIf(!has("webkit"), "dojox.mobile.compat");
+	//		Example of usage: 
+	//		|	require([
+	//		|		"dojox/mobile",
+	//		|		"dojox/mobile/compat",
+	//		|		...
+	//		|	], function(...){
+	//		|		...
+	//		|	});
 	//
-	//		This module also loads compatibility CSS files, which has -compat.css
-	//		suffix. You can use either the <link> tag or @import to load theme
+	//		This module also loads compatibility CSS files, which have a -compat.css
+	//		suffix. You can use either the `<link>` tag or `@import` to load theme
 	//		CSS files. Then, this module searches for the loaded CSS files and loads
-	//		compatibility CSS files. For example, if you load iphone.css in a page,
-	//		this module automatically loads iphone-compat.css.
-	//		If you explicitly load iphone-compat.css with <link> or @import,
-	//		this module will not load the already loaded file.
+	//		compatibility CSS files. For example, if you load dojox/mobile/themes/iphone/iphone.css
+	//		in a page, this module automatically loads dojox/mobile/themes/iphone/iphone-compat.css.
+	//		If you explicitly load iphone-compat.css with `<link>` or `@import`,
+	//		this module will not load again the already loaded file.
+	//
+	//		Note that, by default, compatibility CSS files are only loaded for CSS files located
+	//		in a directory containing a "mobile/themes" path. For that, a matching is done using 
+	//		the default pattern	"/\/mobile\/themes\/.*\.css$/". If a custom theme is not located 
+	//		in a directory containing this path, the data-dojo-config needs to specify a custom 
+	//		pattern using the "mblLoadCompatPattern" configuration parameter, for instance:
+	//		|	data-dojo-config="mblLoadCompatPattern: /\/mycustomtheme\/.*\.css$/"
+};
+=====*/
 
 	var dm = lang.getObject("dojox.mobile", true);
-	/*=====
-	dm = dojox.mobile
-	=====*/
 
-	if(!has("webkit")){
+	if(!(has("webkit") || has("ie") >= 10)){
 		lang.extend(View, {
 			_doTransition: function(fromNode, toNode, transition, dir){
 				var anim;
 				this.wakeUp(toNode);
+				var s1, s2;
 				if(!transition || transition == "none"){
 					toNode.style.display = "";
 					fromNode.style.display = "none";
@@ -77,13 +86,13 @@ define([
 					this.invokeCallback();
 				}else if(transition == "slide" || transition == "cover" || transition == "reveal"){
 					var w = fromNode.offsetWidth;
-					var s1 = fx.slideTo({
+					s1 = fx.slideTo({
 						node: fromNode,
 						duration: 400,
 						left: -w*dir,
 						top: domStyle.get(fromNode, "top")
 					});
-					var s2 = fx.slideTo({
+					s2 = fx.slideTo({
 						node: toNode,
 						duration: 400,
 						left: 0,
@@ -94,6 +103,7 @@ define([
 					toNode.style.display = "";
 					anim = fx.combine([s1,s2]);
 					connect.connect(anim, "onEnd", this, function(){
+						if(!this._inProgress){ return; } // transition has been aborted
 						fromNode.style.display = "none";
 						fromNode.style.left = "0px";
 						toNode.style.position = "relative";
@@ -107,13 +117,13 @@ define([
 					anim.play();
 				}else if(transition == "slidev" || transition == "coverv" || transition == "reavealv"){
 					var h = fromNode.offsetHeight;
-					var s1 = fx.slideTo({
+					s1 = fx.slideTo({
 						node: fromNode,
 						duration: 400,
 						left: 0,
 						top: -h*dir
 					});
-					var s2 = fx.slideTo({
+					s2 = fx.slideTo({
 						node: toNode,
 						duration: 400,
 						left: 0,
@@ -125,6 +135,7 @@ define([
 					toNode.style.display = "";
 					anim = fx.combine([s1,s2]);
 					connect.connect(anim, "onEnd", this, function(){
+						if(!this._inProgress){ return; } // transition has been aborted
 						fromNode.style.display = "none";
 						toNode.style.position = "relative";
 						this.invokeCallback();
@@ -140,6 +151,7 @@ define([
 					toNode.style.position = "absolute";
 					toNode.style.left = "0px";
 					connect.connect(anim, "onEnd", this, function(){
+						if(!this._inProgress){ return; } // transition has been aborted
 						fromNode.style.display = "none";
 						toNode.style.position = "relative";
 						toNode.style.display = "";
@@ -163,6 +175,7 @@ define([
 					toNode.style.display = "";
 					domStyle.set(toNode, "opacity", 0);
 					connect.connect(anim, "onEnd", this, function(){
+						if(!this._inProgress){ return; } // transition has been aborted
 						fromNode.style.display = "none";
 						toNode.style.position = "relative";
 						domStyle.set(fromNode, "opacity", 1);
@@ -170,9 +183,8 @@ define([
 					});
 					anim.play();
 				}
-				dm.currentView = registry.byNode(toNode);
 			},
-		
+
 			wakeUp: function(/*DomNode*/node){
 				// summary:
 				//		Function to force IE to redraw a node since its layout
@@ -197,7 +209,7 @@ define([
 			}
 		});	
 
-	
+
 		lang.extend(Switch, {
 			_changeState: function(/*String*/state, /*Boolean*/anim){
 				// summary:
@@ -209,25 +221,26 @@ define([
 				// tags:
 				//		private
 				var on = (state === "on");
-		
+
 				var pos;
 				if(!on){
-					pos = -this.inner.firstChild.firstChild.offsetWidth;
+					pos = this.isLeftToRight() ? -domStyle.get(this.right,"left") : 0;
 				}else{
-					pos = 0;
+					pos = this.isLeftToRight() ? 0 : -domStyle.get(this.right,"left");
 				}
-		
+
 				this.left.style.display = "";
 				this.right.style.display = "";
-		
+
 				var _this = this;
 				var f = function(){
 					domClass.remove(_this.domNode, on ? "mblSwitchOff" : "mblSwitchOn");
 					domClass.add(_this.domNode, on ? "mblSwitchOn" : "mblSwitchOff");
 					_this.left.style.display = on ? "" : "none";
 					_this.right.style.display = !on ? "" : "none";
+					domAttr.set(_this.domNode, "aria-checked", on ? "true" : "false"); //a11y
 				};
-		
+
 				if(anim){
 					var a = fx.slideTo({
 						node: this.inner,
@@ -237,7 +250,7 @@ define([
 					});
 					a.play();
 				}else{
-					if(on || pos){
+					if((this.isLeftToRight() ? on : !on) || pos){
 						this.inner.style.left = pos + "px";
 					}
 					f();
@@ -245,7 +258,27 @@ define([
 			}
 		});	
 
-	
+
+		lang.extend(ProgressIndicator, {
+			scale: function(/*Number*/size){
+				if(has("ie")){
+					var dim = {w:size, h:size};
+					domGeometry.setMarginBox(this.domNode, dim);
+					domGeometry.setMarginBox(this.containerNode, dim);
+				}else if(has("ff")){
+					var scale = size / 40;
+					domStyle.set(this.containerNode, {
+						MozTransform: "scale(" + scale + ")",
+						MozTransformOrigin: "0 0"
+					});
+
+					domGeometry.setMarginBox(this.domNode, {w:size, h:size});
+					domGeometry.setMarginBox(this.containerNode, {w:size / scale, h:size / scale});
+				}
+			}
+		});	
+
+
 		if(has("ie")){
 			lang.extend(RoundRect, {
 				buildRendering: function(){
@@ -261,6 +294,7 @@ define([
 
 
 			RoundRectList._addChild = RoundRectList.prototype.addChild;
+			RoundRectList._postCreate = RoundRectList.prototype.postCreate;
 			lang.extend(RoundRectList, {
 				buildRendering: function(){
 					// summary:
@@ -270,12 +304,16 @@ define([
 					//		protected
 					dm.createRoundRect(this, true);
 					this.domNode.className = "mblRoundRectList";
+					if(has("ie") && has("dojo-bidi") && !this.isLeftToRight()){
+						this.domNode.className = "mblRoundRectList mblRoundRectListRtl"
+					}
 				},
-			
+
 				postCreate: function(){
+					RoundRectList._postCreate.apply(this, arguments);
 					this.redrawBorders();
 				},
-		
+
 				addChild: function(widget, /*Number?*/insertIndex){
 					RoundRectList._addChild.apply(this, arguments);
 					this.redrawBorders();
@@ -283,14 +321,14 @@ define([
 						dm.applyPngFilter(widget.domNode);
 					}
 				},
-			
+
 				redrawBorders: function(){
 					// summary:
 					//		Function to adjust the creation of RoundRectLists on IE.
 					//		Removed undesired styles.
 					// tags:
 					//		public
-			
+
 					// Remove a border of the last ListItem.
 					// This is for browsers that do not support the last-child CSS pseudo-class.
 
@@ -309,7 +347,7 @@ define([
 
 			lang.extend(EdgeToEdgeList, {
 				buildRendering: function(){
-				this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("UL");
+				this.domNode = this.containerNode = this.srcNodeRef || win.doc.createElement("ul");
 					this.domNode.className = "mblEdgeToEdgeList";
 				}
 			});
@@ -334,11 +372,11 @@ define([
 					// tags:
 					//		public
 					var i, len;
-					_this.domNode = win.doc.createElement("DIV");
+					_this.domNode = win.doc.createElement("div");
 					_this.domNode.style.padding = "0px";
 					_this.domNode.style.backgroundColor = "transparent";
 					_this.domNode.style.border = "none"; // borderStyle = "none"; doesn't work on IE9
-					_this.containerNode = win.doc.createElement(isList?"UL":"DIV");
+					_this.containerNode = win.doc.createElement(isList?"ul":"div");
 					_this.containerNode.className = "mblRoundRectContainer";
 					if(_this.srcNodeRef){
 						_this.srcNodeRef.parentNode.replaceChild(_this.domNode, _this.srcNodeRef);
@@ -348,13 +386,13 @@ define([
 						_this.srcNodeRef = null;
 					}
 					_this.domNode.appendChild(_this.containerNode);
-		
+
 					for(i = 0; i <= 5; i++){
-						var top = domConstruct.create("DIV");
+						var top = domConstruct.create("div");
 						top.className = "mblRoundCorner mblRoundCorner"+i+"T";
 						_this.domNode.insertBefore(top, _this.containerNode);
-		
-						var bottom = domConstruct.create("DIV");
+
+						var bottom = domConstruct.create("div");
 						bottom.className = "mblRoundCorner mblRoundCorner"+i+"B";
 						_this.domNode.appendChild(bottom);
 					}
@@ -367,7 +405,7 @@ define([
 					// On IE, margin-top of the first child does not seem to be effective,
 					// probably because padding-top is specified for containerNode
 					// to make room for a fixed header. This dummy node is a workaround for that.
-					var dummy = domConstruct.create("DIV", {className:"mblDummyForIE", innerHTML:" "}, this.containerNode, "first");
+					var dummy = domConstruct.create("div", {className:"mblDummyForIE", innerHTML:" "}, this.containerNode, "first");
 					domStyle.set(dummy, {
 						position: "relative",
 						marginBottom: "-2px",
@@ -375,6 +413,20 @@ define([
 					});
 				}
 			});
+
+			// #13846: on IE<10, setSelectable(false) sets unselectable="on" on all children,
+			// which makes INPUT elements uneditable.
+			Heading._buildRendering = Heading.prototype.buildRendering;
+			lang.extend(Heading, {
+				buildRendering: function(){
+					Heading._buildRendering.apply(this);
+					var nodes = this.domNode.getElementsByTagName("INPUT"),
+						i = nodes.length;
+					while(i--){
+						nodes[i].removeAttribute("unselectable");
+					}
+				}
+			});
 		} // if	(has("ie"))
 
 
@@ -430,7 +482,7 @@ define([
 
 		dm.loadCssFile = function(/*String*/file){
 			// summary:
-			//		Overrides dojox.mobile.loadCssFile() defined in
+			//		Overrides dojox/mobile.loadCssFile() defined in
 			//		deviceTheme.js.
 			if(!dm.loadedCssFiles){ dm.loadedCssFiles = []; }
 			if(win.doc.createStyleSheet){
@@ -443,7 +495,7 @@ define([
 					};
 				}(file), 0);
 			}else{
-				dm.loadedCssFiles.push(domConstruct.create("LINK", {
+				dm.loadedCssFiles.push(domConstruct.create("link", {
 					href: file,
 					type: "text/css",
 					rel: "stylesheet"
@@ -491,7 +543,7 @@ define([
 					}
 				}
 			}
-		
+
 			// find <link>
 			var elems = win.doc.getElementsByTagName("link");
 			for(i = 0, len = elems.length; i < len; i++){
@@ -513,18 +565,51 @@ define([
 				setTimeout(function(){ // IE needs setTimeout
 					dm.loadCompatCssFiles(true);
 				}, 0);
+				return;
 			}
 			dm._loadedCss = undefined;
 			var paths = dm.getCssPaths();
+			// dojox.mobile mirroring support
+			if(has("dojo-bidi")){
+				paths = dm.loadRtlCssFiles(paths);
+			}
 			for(var i = 0; i < paths.length; i++){
 				var href = paths[i];
-				if((href.match(dm.loadCompatPattern) || location.href.indexOf("mobile/tests/") !== -1) && href.indexOf("-compat.css") === -1){
+				// Load the -compat.css only for css files that belong to a theme. For that, by default
+				// we match on directories containing "mobile/themes". If a custom theme is located
+				// outside a "mobile/themes" directory, the dojoConfig needs to specify a custom 
+				// pattern using the "mblLoadCompatPattern" configuration parameter, for instance:
+				// data-dojo-config="mblLoadCompatPattern: /\/mycustom\/.*\.css$/"
+				// Additionally, compat css files are loaded for css in the mobile/tests directory.
+				if((href.match(config.mblLoadCompatPattern || dm.loadCompatPattern) || 
+					location.href.indexOf("mobile/tests/") !== -1) && href.indexOf("-compat.css") === -1){
 					var compatCss = href.substring(0, href.length-4)+"-compat.css";
 					dm.loadCss(compatCss);
 				}
 			}
 		};
-	
+		if(has("dojo-bidi")){
+			dm.loadRtlCssFiles = function(/*Array*/paths){
+				// summary:
+				//		Function to load the corresponding *_rtl.css file for every *.css file.
+				//		Enable mobile mirroring support
+				// paths: Array
+				//		Array of css files within the page.
+				for(var i = 0; i < paths.length; i++){
+					var href = paths[i];
+					if(href.indexOf("_rtl") == -1){
+						var rtlCssList = "android.css blackberry.css custom.css iphone.css holodark.css base.css Carousel.css ComboBox.css IconContainer.css IconMenu.css ListItem.css RoundRectCategory.css SpinWheel.css Switch.css TabBar.css ToggleButton.css ToolBarButton.css";
+						var cssName = href.substr(href.lastIndexOf('/') + 1);
+						if(rtlCssList.indexOf(cssName) != -1){
+							var rtlPath = href.replace(".css", "_rtl.css");
+							paths.push(rtlPath);
+							dm.loadCss(rtlPath);
+						}
+					}
+				}
+				return paths;
+			};
+		}
 		dm.hideAddressBar = function(/*Event?*/evt, /*Boolean?*/doResize){
 			if(doResize !== false){ dm.resizeAll(); }
 		};
diff --git a/dojox/mobile/_css3.js b/dojox/mobile/_css3.js
new file mode 100755
index 0000000..aceee3a
--- /dev/null
+++ b/dojox/mobile/_css3.js
@@ -0,0 +1,129 @@
+define([
+	"dojo/_base/window",
+	"dojo/_base/array",
+	"dojo/has"
+], function(win, arr, has){
+	
+	// caches for capitalized names and hypen names
+	var cnames = [], hnames = [];
+	
+	// element style used for feature testing
+	var style = win.doc.createElement("div").style;
+	
+	// We just test webkit prefix for now since our themes only have standard and webkit
+	// (see dojox/mobile/themes/common/css3.less)
+	// More prefixes can be added if/when we add them to css3.less.
+	var prefixes = ["webkit"];
+	
+	// Does the browser support CSS3 animations?
+	has.add("css3-animations", function(global, document, element){
+		var style = element.style;
+		return (style["animation"] !== undefined && style["transition"] !== undefined) ||
+			arr.some(prefixes, function(p){
+				return style[p+"Animation"] !== undefined && style[p+"Transition"] !== undefined;
+			});
+	});
+	
+	var css3 = {
+		// summary:
+		//		This module provide some cross-browser support for CSS3 properties.
+	
+		name: function(/*String*/p, /*Boolean?*/hyphen){
+			// summary:
+			//		Returns the name of a CSS3 property with the correct prefix depending on the browser.
+			// p:
+			//		The (non-prefixed) property name. The property name is assumed to be consistent with
+			//		the hyphen argument, for example "transition-property" if hyphen is true, or "transitionProperty"
+			//		if hyphen is false. If the browser supports the non-prefixed property, the property name will be
+			//		returned unchanged.
+			// hyphen:
+			//		Optional, true if hyphen notation should be used (for example "transition-property" or "-webkit-transition-property"),
+			//		false for camel-case notation (for example "transitionProperty" or "webkitTransitionProperty").
+			
+			var n = (hyphen?hnames:cnames)[p];
+			if(!n){
+				
+				if(/End|Start/.test(p)){
+					// event names: no good way to feature-detect, so we
+					// assume they have the same prefix as the corresponding style property
+					var idx = p.length - (p.match(/End/) ? 3 : 5);
+					var s = p.substr(0, idx);
+					var pp = this.name(s);
+					if(pp == s){
+						// no prefix, standard event names are all lowercase
+						n = p.toLowerCase();
+					}else{
+						// prefix, e.g. webkitTransitionEnd (camel case)
+						n = pp + p.substr(idx);
+					}
+				}else if(p == "keyframes"){
+					// special case for keyframes, we also rely on consistency between 'animation' and 'keyframes'
+					var pk = this.name("animation", hyphen);
+					if(pk == "animation"){
+						n = p;
+					}else if(hyphen){
+						n = pk.replace(/animation/, "keyframes");
+					}else{
+						n = pk.replace(/Animation/, "Keyframes");
+					}
+				}else{
+					// convert name to camel-case for feature test
+					var cn = hyphen ? p.replace(/-(.)/g, function(match, p1){
+    					return p1.toUpperCase();
+					}) : p;
+					
+					if(style[cn] !== undefined){
+						// standard non-prefixed property is supported
+						n = p;
+					}else{
+						// try prefixed versions
+						cn = cn.charAt(0).toUpperCase() + cn.slice(1);
+						arr.some(prefixes, function(prefix){
+							if(style[prefix+cn] !== undefined){
+								if(hyphen){
+									n = "-" + prefix + "-" + p;
+								}else{
+									n = prefix + cn;
+								}
+							}
+						});
+					}
+				}
+				
+				if(!n){
+					// The property is not supported, just return it unchanged, it will be ignored.
+					n = p;
+				}
+
+				(hyphen?hnames:cnames)[p] = n;
+			}
+			return n;
+		},
+		
+		add: function(/*Object*/styles, /*Object*/css3Styles){
+			// summary:
+			//		Prefixes all property names in "css3Styles" and adds the prefixed properties in "styles".
+			//		Used as a convenience when an object is passed to domStyle.set to set multiple styles.
+			// example:
+			//		domStyle.set(bar, css3.add({
+			//			opacity: 0.6,
+			//			position: "absolute",
+			//			backgroundColor: "#606060"
+			//		}, {
+			//			borderRadius: "2px",
+			//			transformOrigin: "0 0"
+			//		}));
+			// returns:
+			//		The "styles" argument where the CSS3 styles have been added.
+			
+			for(var p in css3Styles){
+				if(css3Styles.hasOwnProperty(p)){
+					styles[css3.name(p)] = css3Styles[p];
+				}
+			}
+			return styles;
+		}
+	}
+	
+	return css3;
+});
diff --git a/dojox/mobile/_maskUtils.js b/dojox/mobile/_maskUtils.js
new file mode 100755
index 0000000..8939c6b
--- /dev/null
+++ b/dojox/mobile/_maskUtils.js
@@ -0,0 +1,116 @@
+define([
+	"dojo/_base/window",
+	"dojo/dom-style",
+	"./sniff"
+], function(win, domStyle, has){
+	
+	var cache = {};
+	
+	return {
+		// summary:
+		//		Utility methods to clip rounded corners of various elements (Switch, ScrollablePane, scrollbars in scrollable widgets).
+		//		Uses -webkit-mask-image on webkit, or SVG on other browsers.
+		
+		createRoundMask: function(/*DomNode*/node, x, y, r, b, w, h, rx, ry, e){
+			// summary:
+			//		Creates and sets a mask for the specified node.
+			
+			var tw = x + w + r;
+			var th = y + h + b;
+			
+			if(has("webkit")){			// use -webkit-mask-image
+				var id = ("DojoMobileMask" + x + y + w + h + rx + ry).replace(/\./g, "_");
+				if (!cache[id]) {
+					cache[id] = 1;
+					var ctx = win.doc.getCSSCanvasContext("2d", id, tw, th);
+					ctx.beginPath();
+					if (rx == ry) {
+						// round arc
+						if(rx == 2 && w == 5){
+							// optimized case for vertical scrollbar
+							ctx.fillStyle = "rgba(0,0,0,0.5)";
+							ctx.fillRect(1, 0, 3, 2);
+							ctx.fillRect(0, 1, 5, 1);
+							ctx.fillRect(0, h - 2, 5, 1);
+							ctx.fillRect(1, h - 1, 3, 2);
+							ctx.fillStyle = "rgb(0,0,0)";
+							ctx.fillRect(0, 2, 5, h - 4);
+						}else if(rx == 2 && h == 5){
+							// optimized case for horizontal scrollbar
+							ctx.fillStyle = "rgba(0,0,0,0.5)";
+							ctx.fillRect(0, 1, 2, 3);
+							ctx.fillRect(1, 0, 1, 5);
+							ctx.fillRect(w - 2, 0, 1, 5);
+							ctx.fillRect(w - 1, 1, 2, 3);
+							ctx.fillStyle = "rgb(0,0,0)";
+							ctx.fillRect(2, 0, w - 4, 5);
+						}else{
+							// general case
+							ctx.fillStyle = "#000000";
+							ctx.moveTo(x+rx, y);
+							ctx.arcTo(x, y, x, y+rx, rx);
+							ctx.lineTo(x, y+h - rx);
+							ctx.arcTo(x, y+h, x+rx, y+h, rx);
+							ctx.lineTo(x+w - rx, y+h);
+							ctx.arcTo(x+w, y+h, x+w, y+rx, rx);
+							ctx.lineTo(x+w, y+rx);
+							ctx.arcTo(x+w, y, x+w - rx, y, rx);
+						}
+					} else {
+						// elliptical arc
+						var pi = Math.PI;
+						ctx.scale(1, ry / rx);
+						ctx.moveTo(x+rx, y);
+						ctx.arc(x+rx, y+rx, rx, 1.5 * pi, 0.5 * pi, true);
+						ctx.lineTo(x+w - rx, y+2 * rx);
+						ctx.arc(x+w - rx, y+rx, rx, 0.5 * pi, 1.5 * pi, true);
+					}
+					ctx.closePath();
+					ctx.fill();
+				}
+				node.style.webkitMaskImage = "-webkit-canvas(" + id + ")";
+			}else if(has("svg")){		// add an SVG image to clip the corners.
+				if(node._svgMask){
+					node.removeChild(node._svgMask);
+				}
+				var bg = null;
+				for(var p = node.parentNode; p; p = p.parentNode){
+					bg = domStyle.getComputedStyle(p).backgroundColor;
+					if(bg && bg != "transparent" && !bg.match(/rgba\(.*,\s*0\s*\)/)){
+						break;
+					}
+				}
+				var svgNS = "http://www.w3.org/2000/svg";
+				var svg = win.doc.createElementNS(svgNS, "svg");
+				svg.setAttribute("width", tw);
+				svg.setAttribute("height", th);
+				svg.style.position = "absolute";
+				svg.style.pointerEvents = "none";
+				svg.style.opacity = "1";
+				svg.style.zIndex = "2147483647"; // max int
+				var path = win.doc.createElementNS(svgNS, "path");
+				e = e || 0;
+				rx += e;
+				ry += e;
+				// TODO: optimized cases for scrollbars as in webkit case?
+				var d = " M" + (x + rx - e) + "," + (y - e) + " a" + rx + "," + ry + " 0 0,0 " + (-rx) + "," + ry + " v" + (-ry) + " h" + rx + " Z" +
+						" M" + (x - e) + "," + (y + h - ry + e) + " a" + rx + "," + ry + " 0 0,0 " + rx + "," + ry + " h" + (-rx) + " v" + (-ry) + " z" +
+						" M" + (x + w - rx + e) + "," + (y + h + e) + " a" + rx + "," + ry + " 0 0,0 " + rx + "," + (-ry) + " v" + ry + " h" + (-rx) + " z" +
+						" M" + (x + w + e) + "," + (y + ry - e) + " a" + rx + "," + ry + " 0 0,0 " + (-rx) + "," + (-ry) + " h" + rx + " v" + ry + " z";
+				if(y > 0){
+					d += " M0,0 h" + tw + " v" + y + " h" + (-tw) + " z";
+				}
+				if(b > 0){
+					d += " M0," + (y + h) + " h" + tw + " v" + b + " h" + (-tw) + " z";
+				}
+				path.setAttribute("d", d);
+				path.setAttribute("fill", bg);
+				path.setAttribute("stroke", bg);
+				path.style.opacity = "1";
+				svg.appendChild(path); 
+				node._svgMask = svg;
+				node.appendChild(svg);
+			}
+		}
+	};
+});
diff --git a/dojox/mobile/app.js b/dojox/mobile/app.js
index 174ad28..32ec11e 100755
--- a/dojox/mobile/app.js
+++ b/dojox/mobile/app.js
@@ -1,5 +1,14 @@
 define([
 	"./app/_base"
 ], function(appBase){
+	
+	/*=====
+	return {
+		// summary:
+		//		Loads dojox/mobile/app/_base. 
+		// tags:
+		//		private
+	};
+	=====*/
 	return appBase;
 });
diff --git a/dojox/mobile/app/AlertDialog.js b/dojox/mobile/app/AlertDialog.js
index 1fe5a0f..58ef153 100644
--- a/dojox/mobile/app/AlertDialog.js
+++ b/dojox/mobile/app/AlertDialog.js
@@ -101,7 +101,7 @@ dojo.declare("dojox.mobile.app.AlertDialog", dijit._WidgetBase, {
 
 			// Find the widget that was tapped.
 			while(!dijit.byNode(node)){
-				node - node.parentNode;
+				node = node.parentNode;
 			}
 		}
 
diff --git a/dojox/mobile/app/List.js b/dojox/mobile/app/List.js
index 26b9008..4a9fd80 100644
--- a/dojox/mobile/app/List.js
+++ b/dojox/mobile/app/List.js
@@ -16,7 +16,7 @@ dojo.require("dijit._WidgetBase");
 		//		can be provided for when the list is empty.
 
 		// items: Array
-		//    The array of data items that will be rendered.
+		//		The array of data items that will be rendered.
 		items: null,
 
 		// itemTemplate: String
@@ -29,14 +29,14 @@ dojo.require("dijit._WidgetBase");
 		//		are no data items. This is optional.
 		emptyTemplate: "",
 
-		//  dividerTemplate: String
-		//    The URL to the HTML file containing the markup for the dividers
-		//    between groups of list items
+		// dividerTemplate: String
+		//		The URL to the HTML file containing the markup for the dividers
+		//		between groups of list items
 		dividerTemplate: "",
 
 		// dividerFunction: Function
-		//    Function to create divider elements. This should return a divider
-		//    value for each item in the list
+		//		Function to create divider elements. This should return a divider
+		//		value for each item in the list
 		dividerFunction: null,
 
 		// labelDelete: String
@@ -48,7 +48,6 @@ dojo.require("dijit._WidgetBase");
 		labelCancel: "Cancel",
 
 		// controller: Object
-		//
 		controller: null,
 
 		// autoDelete: Boolean
@@ -69,7 +68,7 @@ dojo.require("dijit._WidgetBase");
 		_templateLoadCount: 0,
 
 		// _mouseDownPos: Object
-		//    The coordinates of where a mouseDown event was detected
+		//		The coordinates of where a mouseDown event was detected
 		_mouseDownPos: null,
 
 		baseClass: "list",
@@ -245,7 +244,7 @@ dojo.require("dijit._WidgetBase");
 
 		preDelete: function(currentLeftPos){
 			// summary:
-			//    Slides the row offscreen before it is deleted
+			//		Slides the row offscreen before it is deleted
 
 			// TODO: do this with CSS3!
 			var self = this;
@@ -374,7 +373,7 @@ dojo.require("dijit._WidgetBase");
 
 		onDelete: function(data, index, array){
 			// summary:
-			//    Called when a row is deleted
+			//		Called when a row is deleted
 			// data:
 			//		The data related to the row being deleted
 			// index:
@@ -432,8 +431,8 @@ dojo.require("dijit._WidgetBase");
 
 		_setDataInfo: function(rowNode, event){
 			// summary:
-			//    Attaches the data item and index for each row to any event
-			//    that occurs on that row.
+			//		Attaches the data item and index for each row to any event
+			//		that occurs on that row.
 			event.item = rowNode._data;
 			event.index = rowNode._idx;
 		},
@@ -614,13 +613,13 @@ dojo.require("dijit._WidgetBase");
 
 		_setFormattersAttr: function(formatters){
 			// summary:
-			//    Sets the data items, and causes a rerender of the list
+			//		Sets the data items, and causes a rerender of the list
 			this.formatters = formatters;
 		},
 
 		_setItemsAttr: function(items){
 			// summary:
-			//    Sets the data items, and causes a rerender of the list
+			//		Sets the data items, and causes a rerender of the list
 
 			this.items = items || [];
 
diff --git a/dojox/mobile/app/ListSelector.js b/dojox/mobile/app/ListSelector.js
index 9f55455..db3ed9e 100644
--- a/dojox/mobile/app/ListSelector.js
+++ b/dojox/mobile/app/ListSelector.js
@@ -7,17 +7,17 @@ dojo.require("dojo.fx");
 dojo.declare("dojox.mobile.app.ListSelector", dojox.mobile.app._Widget, {
 
 	// data: Array
-	//    The array of items to display.  Each element in the array
-	//    should have both a label and value attribute, e.g.
-	//    [{label: "Open", value: 1} , {label: "Delete", value: 2}]
+	//		The array of items to display.  Each element in the array
+	//		should have both a label and value attribute, e.g.
+	//		[{label: "Open", value: 1} , {label: "Delete", value: 2}]
 	data: null,
 
 	// controller: Object
-	//    The current SceneController widget.
+	//		The current SceneController widget.
 	controller: null,
 
 	// onChoose: Function
-	//    The callback function for when an item is selected
+	//		The callback function for when an item is selected
 	onChoose: null,
 
 	destroyOnHide: false,
@@ -183,7 +183,7 @@ dojo.declare("dojox.mobile.app.ListSelector", dojox.mobile.app._Widget, {
 
 	render: function(){
 		// summary:
-		//    Renders
+		//		Renders
 	
 		dojo.empty(this.domNode);
 		dojo.style(this.domNode, "opacity", 0);
diff --git a/dojox/mobile/app/SceneAssistant.js b/dojox/mobile/app/SceneAssistant.js
index 22a6e11..e0da1ef 100644
--- a/dojox/mobile/app/SceneAssistant.js
+++ b/dojox/mobile/app/SceneAssistant.js
@@ -3,7 +3,7 @@ dojo.experimental("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("dojox.mobile.app.SceneAssistant", null, {
 	// summary:
-	//    The base class for all scene assistants.
+	//		The base class for all scene assistants.
 
 	constructor: function(){
 
@@ -11,25 +11,25 @@ dojo.declare("dojox.mobile.app.SceneAssistant", null, {
 
 	setup: function(){
 		// summary:
-		//    Called to set up the widget.  The UI is not visible at this time
+		//		Called to set up the widget.  The UI is not visible at this time
 
 	},
 
 	activate: function(params){
 		// summary:
-		//    Called each time the scene becomes visible.  This can be as a result
-		//    of a new scene being created, or a subsequent scene being destroyed
-		//    and control transferring back to this scene assistant.
+		//		Called each time the scene becomes visible.  This can be as a result
+		//		of a new scene being created, or a subsequent scene being destroyed
+		//		and control transferring back to this scene assistant.
 		// params:
-		//    Optional paramters, only passed when a subsequent scene pops itself
-		//    off the stack and passes back data.
+		//		Optional parameters, only passed when a subsequent scene pops itself
+		//		off the stack and passes back data.
 	},
 
 	deactivate: function(){
 		// summary:
-		//    Called each time the scene becomes invisible.  This can be as a result
-		//    of it being popped off the stack and destroyed,
-		//    or another scene being created and pushed on top of it on the stack
+		//		Called each time the scene becomes invisible.  This can be as a result
+		//		of it being popped off the stack and destroyed,
+		//		or another scene being created and pushed on top of it on the stack
 	},
 
 	destroy: function(){
diff --git a/dojox/mobile/app/SceneController.js b/dojox/mobile/app/SceneController.js
index e7fb829..6e3b67d 100644
--- a/dojox/mobile/app/SceneController.js
+++ b/dojox/mobile/app/SceneController.js
@@ -16,8 +16,8 @@ dojo.require("dojox.mobile._base");
 
 		init: function(sceneName, params){
 			// summary:
-			//    Initializes the scene by loading the HTML template and code, if it has
-			//    not already been loaded
+			//		Initializes the scene by loading the HTML template and code, if it has
+			//		not already been loaded
 
 			this.sceneName = sceneName;
 			this.params = params;
@@ -41,8 +41,8 @@ dojo.require("dojox.mobile._base");
 
 		_setContents: function(templateHtml){
 			// summary:
-			//    Sets the content of the View, and invokes either the loading or
-			//    initialization of the scene assistant.
+			//		Sets the content of the View, and invokes either the loading or
+			//		initialization of the scene assistant.
 			templates[this.sceneName] = templateHtml;
 
 			this.domNode.innerHTML = "<div>" + templateHtml + "</div>";
@@ -90,9 +90,9 @@ dojo.require("dojox.mobile._base");
 
 		_initAssistant: function(){
 			// summary:
-			//    Initializes the scene assistant. At this point, the View is
-			//    populated with the HTML template, and the scene assistant type
-			//    is declared.
+			//		Initializes the scene assistant. At this point, the View is
+			//		populated with the HTML template, and the scene assistant type
+			//		is declared.
 
 			console.log("Instantiating the scene assistant " + this.sceneAssistantName);
 
@@ -115,8 +115,8 @@ dojo.require("dojox.mobile._base");
 
 		query: function(selector, node){
 			// summary:
-			//    Queries for DOM nodes within either the node passed in as an argument
-			//    or within this view.
+			//		Queries for DOM nodes within either the node passed in as an argument
+			//		or within this view.
 
 			return dojo.query(selector, node || this.domNode)
 		},
diff --git a/dojox/mobile/app/StageController.js b/dojox/mobile/app/StageController.js
index 554090d..73e60bf 100644
--- a/dojox/mobile/app/StageController.js
+++ b/dojox/mobile/app/StageController.js
@@ -6,7 +6,7 @@ dojo.require("dojox.mobile.app.SceneController");
 dojo.declare("dojox.mobile.app.StageController", null,{
 
 	// scenes: Array
-	//    The list of scenes currently in existance in the app.
+	//		The list of scenes currently in existence in the app.
 	scenes: null,
 
 	effect: "fade",
diff --git a/dojox/mobile/app/_FormWidget.js b/dojox/mobile/app/_FormWidget.js
index 09ea3cd..55a0046 100644
--- a/dojox/mobile/app/_FormWidget.js
+++ b/dojox/mobile/app/_FormWidget.js
@@ -8,8 +8,8 @@ dojo.require("dijit.focus");	// dijit.focus()
 
 dojo.declare("dojox.mobile.app._FormWidget", dijit._WidgetBase, {
 	// summary:
-	//		Base class for widgets corresponding to native HTML elements such as <checkbox> or <button>,
-	//		which can be children of a <form> node or a `dojox.mobile.app.Form` widget.
+	//		Base class for widgets corresponding to native HTML elements such as `<checkbox>` or `<button>`,
+	//		which can be children of a `<form>` node or a `dojox.mobile.app.Form` widget.
 	//
 	// description:
 	//		Represents a single HTML element.
@@ -23,15 +23,15 @@ dojo.declare("dojox.mobile.app._FormWidget", dijit._WidgetBase, {
 	name: "",
 
 	// alt: String
-	//		Corresponds to the native HTML <input> element's attribute.
+	//		Corresponds to the native HTML `<input>` element's attribute.
 	alt: "",
 
 	// value: String
-	//		Corresponds to the native HTML <input> element's attribute.
+	//		Corresponds to the native HTML `<input>` element's attribute.
 	value: "",
 
 	// type: String
-	//		Corresponds to the native HTML <input> element's attribute.
+	//		Corresponds to the native HTML `<input>` element's attribute.
 	type: "text",
 
 	// disabled: Boolean
@@ -216,9 +216,10 @@ dojo.declare("dojox.mobile.app._FormWidget", dijit._WidgetBase, {
 dojo.declare("dojox.mobile.app._FormValueWidget", dojox.mobile.app._FormWidget,
 {
 	// summary:
-	//		Base class for widgets corresponding to native HTML elements such as <input> or <select> that have user changeable values.
+	//		Base class for widgets corresponding to native HTML elements such as `<input>` or `<select>`
+	//		that have user changeable values.
 	// description:
-	//		Each _FormValueWidget represents a single input value, and has a (possibly hidden) <input> element,
+	//		Each _FormValueWidget represents a single input value, and has a (possibly hidden) `<input>` element,
 	//		to which it serializes it's input value, so that form submission (either normal submission or via FormBind?)
 	//		works as expected.
 
diff --git a/dojox/mobile/app/_base.js b/dojox/mobile/app/_base.js
index 1fd3d97..8344b96 100755
--- a/dojox/mobile/app/_base.js
+++ b/dojox/mobile/app/_base.js
@@ -131,7 +131,7 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 	dojo.mixin(dojox.mobile.app, {
 		init: function(node){
 			// summary:
-			//    Initializes the mobile app. Creates the
+			//		Initializes the mobile app. Creates the
 
 			rootNode = node || dojo.body();
 			dojox.mobile.app.STAGE_CONTROLLER_ACTIVE = true;
diff --git a/dojox/mobile/app/_event.js b/dojox/mobile/app/_event.js
index 330a0ae..d04c5d7 100644
--- a/dojox/mobile/app/_event.js
+++ b/dojox/mobile/app/_event.js
@@ -8,13 +8,12 @@ dojo.mixin(dojox.mobile.app, {
 		// summary:
 		//		Listens for a flick event on a DOM node.  If the mouse/touch
 		//		moves more than 15 pixels in any given direction it is a flick.
-		//		The synthetic event fired specifies the direction as
-		//		<ul>
-		//			<li><b>'ltr'</b> Left To Right</li>
-		//			<li><b>'rtl'</b> Right To Left</li>
-		//			<li><b>'ttb'</b> Top To Bottom</li>
-		//			<li><b>'btt'</b> Bottom To Top</li>
-		//		</ul>
+		//		The synthetic event fired specifies the direction as:
+		//
+		//		- ltr - Left to Right
+		//		- rtl - Right to Left
+		//		- ttb - Top To Bottom
+		//		- btt - Bottom To top
 		// target: Node
 		//		The DOM node to connect to
 
diff --git a/dojox/mobile/bidi/Accordion.js b/dojox/mobile/bidi/Accordion.js
new file mode 100644
index 0000000..d106e9f
--- /dev/null
+++ b/dojox/mobile/bidi/Accordion.js
@@ -0,0 +1,23 @@
+define([
+	"dojo/_base/declare",
+	"./common"
+], function(declare, common){
+
+	// module:
+	//		dojox/mobile/bidi/Accordion
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile Accordion widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction support for Label.
+		//		This class should not be used directly.
+		//		Mobile Accordion widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_setupChild: function(child){
+			if(this.textDir){
+				child.label = common.enforceTextDirWithUcc(child.label, this.textDir); 
+			}
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/Badge.js b/dojox/mobile/bidi/Badge.js
new file mode 100644
index 0000000..eed110a
--- /dev/null
+++ b/dojox/mobile/bidi/Badge.js
@@ -0,0 +1,32 @@
+define(["dojo/_base/declare", "./common"], function(declare, common){
+
+	// module:
+	//		dojox/mobile/bidi/Badge
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for Badge, using Unicode Control Characters to control text direction.
+		// description:
+		//		Added textDir attribute, similar to mobile widgets based on dijit._WidgetBase.
+		//		Extension to value setting attributes, with text direction support.
+		//		This class should not be used directly.
+		//		Mobile Badge widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		
+		// textDir: String
+		//		Mobile widgets, derived from dijit._WidgetBase has this attribute for text direction support (bidi support).
+		//		The text direction can be different than the GUI direction.
+		//		Values: "ltr", "rtl", "auto"(the direction of a text defined by first strong letter).
+		textDir: "", 
+
+		setValue: function(/*String*/value){
+			this.domNode.firstChild.innerHTML = common.enforceTextDirWithUcc(value, this.textDir);
+		},
+
+		setTextDir: function(/*String*/textDir){
+			if (this.textDir !== textDir){
+				this.textDir = textDir;
+				this.domNode.firstChild.innerHTML = common.enforceTextDirWithUcc(common.removeUCCFromText(this.domNode.firstChild.innerHTML), this.textDir);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/Button.js b/dojox/mobile/bidi/Button.js
new file mode 100644
index 0000000..4c02aa5
--- /dev/null
+++ b/dojox/mobile/bidi/Button.js
@@ -0,0 +1,25 @@
+define(["dojo/_base/declare", "./common"], function(declare, common){
+
+	// module:
+	//		mobile/bidi/Button
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile Button widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction support for Label.
+		//		This class should not be used directly.
+		//		Mobile Button widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_setLabelAttr: function(/*String*/ content){
+			this.inherited(arguments, [this._cv ? this._cv(content) : content]);
+			this.focusNode.innerHTML = common.enforceTextDirWithUcc(this.focusNode.innerHTML, this.textDir); 
+		},
+
+		_setTextDirAttr: function(/*String*/ textDir){
+			if(!this._created || this.textDir !== textDir){
+				this._set("textDir", textDir);
+				this.focusNode.innerHTML = common.enforceTextDirWithUcc(common.removeUCCFromText(this.focusNode.innerHTML), this.textDir);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/Carousel.js b/dojox/mobile/bidi/Carousel.js
new file mode 100644
index 0000000..7866301
--- /dev/null
+++ b/dojox/mobile/bidi/Carousel.js
@@ -0,0 +1,53 @@
+define([
+	"dojo/_base/declare",
+	"./common",
+	"dojo/dom-style"
+], function(declare,common, domStyle){
+
+	// module:
+	//		dojox/mobile/bidi/Carousel
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile Carousel widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction support for Title.
+		//		This class should not be used directly.
+		//		Mobile Carousel widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		
+		buildRendering: function(){
+			this.inherited(arguments);
+			// dojox.mobile mirroring support
+		 	if(!this.isLeftToRight()){
+				if(this.navButton){
+					domStyle.set(this.btnContainerNode, "float", "left"); // workaround for webkit rendering problem
+					this.disconnect(this._prevHandle);
+					this.disconnect(this._nextHandle);
+					this._prevHandle = this.connect(this.prevBtnNode, "onclick", "onNextBtnClick");
+					this._nextHandle = this.connect(this.nextBtnNode, "onclick", "onPrevBtnClick");
+				}
+				
+				if(this.pageIndicator){
+					domStyle.set(this.piw, "float", "left"); // workaround for webkit rendering problem
+				}
+			} 
+		},
+		_setTitleAttr: function(title){
+			this.titleNode.innerHTML = this._cv ? this._cv(title) : title;
+			this._set("title", title);
+			if(this.textDir){
+				this.titleNode.innerHTML = common.enforceTextDirWithUcc(this.titleNode.innerHTML, this.textDir);
+				this.titleNode.style.textAlign = (this.dir.toLowerCase() === "rtl") ? "right" : "left";
+			}
+		},
+		_setTextDirAttr: function(textDir){
+			if(textDir && this.textDir !== textDir){
+				this.textDir = textDir;
+				this.titleNode.innerHTML = common.removeUCCFromText(this.titleNode.innerHTML);
+				this.titleNode.innerHTML = common.enforceTextDirWithUcc(this.titleNode.innerHTML, this.textDir);
+				if(this.items.length > 0)
+					this.onComplete(this.items);
+				} 
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/CarouselItem.js b/dojox/mobile/bidi/CarouselItem.js
new file mode 100644
index 0000000..7840d88
--- /dev/null
+++ b/dojox/mobile/bidi/CarouselItem.js
@@ -0,0 +1,36 @@
+define([
+	"dojo/_base/declare",
+	"./common"
+], function(declare, common){
+
+	// module:
+	//		dojox/mobile/bidi/CarouselItem
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile CarouselItem widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction support for Header and Footer.
+		//		This class should not be used directly.
+		//		Mobile CarouselItem widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_setHeaderTextAttr: function(text){
+			this._set("headerText", text);
+			this.headerTextNode.innerHTML = this._cv ? this._cv(text) : text;
+			var p = this.getParent() ? this.getParent().getParent() : null;
+			this.textDir = this.textDir ? this.textDir : p ? p.get("textDir") : ""; //take textDir from Carousel
+			if(this.textDir){
+				this.headerTextNode.innerHTML = common.enforceTextDirWithUcc(this.headerTextNode.innerHTML, this.textDir);
+			}
+		},
+
+		_setFooterTextAttr: function(text){
+			this._set("footerText", text);
+			this.footerTextNode.innerHTML = this._cv ? this._cv(text) : text;
+			var p = this.getParent() ? this.getParent().getParent() : null;
+			this.textDir = this.textDir ? this.textDir : p ? p.get("textDir") : ""; //take textDir from Carousel
+			if(this.textDir){
+				this.footerTextNode.innerHTML = _BidiSupport.enforceTextDirWithUcc(this.footerTextNode.innerHTML, this.textDir);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/Heading.js b/dojox/mobile/bidi/Heading.js
new file mode 100644
index 0000000..acf07c9
--- /dev/null
+++ b/dojox/mobile/bidi/Heading.js
@@ -0,0 +1,38 @@
+define([
+	"dojo/_base/declare",
+	"./common"
+], function(declare, common){
+
+	// module:
+	//		dojox/mobile/bidi/Heading
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile Heading widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction support for Label and Back.
+		//		This class should not be used directly.
+		//		Mobile Heading widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_setLabelAttr: function(label){
+			this.inherited(arguments);
+			if(this.getTextDir(label) === "rtl"){ this.domNode.style.direction = "rtl"; } //for text-overflow: ellipsis;
+			this.labelDivNode.innerHTML = common.enforceTextDirWithUcc(this.labelDivNode.innerHTML, this.textDir);
+		},
+
+		_setBackAttr: function(back){
+			this.inherited(arguments);
+			this.backButton.labelNode.innerHTML = common.enforceTextDirWithUcc(this.backButton.labelNode.innerHTML, this.textDir);
+			this.labelNode.innerHTML = this.labelDivNode.innerHTML;
+		}, 
+
+		_setTextDirAttr: function( textDir){
+			if(!this._created || this.textDir != textDir){
+				this._set("textDir", textDir);
+				if(this.getTextDir(this.labelDivNode.innerHTML) === "rtl"){ this.domNode.style.direction = "rtl"; }//for text-overflow: ellipsis;
+				this.labelDivNode.innerHTML = common.enforceTextDirWithUcc(common.removeUCCFromText(this.labelDivNode.innerHTML), this.textDir);
+				common.setTextDirForButtons(this);
+			}
+		}
+	});
+});
+
diff --git a/dojox/mobile/bidi/IconItem.js b/dojox/mobile/bidi/IconItem.js
new file mode 100644
index 0000000..ee10a08
--- /dev/null
+++ b/dojox/mobile/bidi/IconItem.js
@@ -0,0 +1,42 @@
+define([
+	"dojo/_base/declare",
+	"./common"
+], function(declare, common){
+
+	// module:
+	//		dojox/mobile/bidi/IconItem
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile IconItem widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction for Label.
+		//		This class should not be used directly.
+		//		Mobile IconItem widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_applyAttributes: function(){
+			if(!this.textDir && this.getParent() && this.getParent().get("textDir")){
+				this.textDir = this.getParent().get("textDir");
+			}
+			this.inherited(arguments);
+		},
+
+		_setLabelAttr: function(text){
+			if(this.textDir){
+				text = common.enforceTextDirWithUcc(text, this.textDir);
+			}
+			this.inherited(arguments);
+		},
+
+		_setTextDirAttr: function(textDir){
+			if(textDir && this.textDir !== textDir){
+				this.textDir = textDir;
+				this.labelNode.innerHTML = common.removeUCCFromText(this.labelNode.innerHTML);
+				this.labelNode.innerHTML = common.enforceTextDirWithUcc(this.labelNode.innerHTML, this.textDir);
+				if(this.paneWidget){
+					this.paneWidget.labelNode.innerHTML = common.removeUCCFromText(this.paneWidget.labelNode.innerHTML);
+					this.paneWidget.labelNode.innerHTML = common.enforceTextDirWithUcc(this.paneWidget.labelNode.innerHTML, this.textDir);		            		            
+				}
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/IconMenu.js b/dojox/mobile/bidi/IconMenu.js
new file mode 100644
index 0000000..97ded2c
--- /dev/null
+++ b/dojox/mobile/bidi/IconMenu.js
@@ -0,0 +1,23 @@
+define([
+	"dojo/_base/declare",
+	"./common"
+], function(declare, common){
+
+	// module:
+	//		dojox/mobile/bidi/IconMenu
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile IconMenu widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction, textDir is set to MenuItems.
+		//		This class should not be used directly.
+		//		Mobile IconMenu widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_setTextDirAttr: function(/*String*/ textDir){
+			if(!this._created || this.textDir !== textDir){
+				this._set("textDir", textDir);
+				common.setTextDirForButtons(this);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/ListItem.js b/dojox/mobile/bidi/ListItem.js
new file mode 100644
index 0000000..dccd79f
--- /dev/null
+++ b/dojox/mobile/bidi/ListItem.js
@@ -0,0 +1,98 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/dom-construct",
+	"./common",
+	"dojo/_base/window"
+], function(declare, array, domConstruct, common, win){
+
+	// module:
+	//		dojox/mobile/ListItem
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile ListItem widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction support for Label and RightText.
+		//		Text direction is also applied to ListItem's embedded nodes, containing text.
+		//		Complicated embedded nodes (like tables) are not supported.
+		//		This class should not be used directly.
+		//		Mobile ListItem widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_applyAttributes: function(){
+			if(!this.textDir && this.getParent() && this.getParent().get("textDir")){
+				this.textDir = this.getParent().get("textDir");
+			}
+			this.inherited( arguments);
+			if(this.textDir){
+			    this._applyTextDirToTextElements();
+			}    
+		},
+
+		_setRightTextAttr: function(text){
+			if(!this.templateString && !this.rightTextNode){
+				// When using a template, let the template create the element.
+				this.rightTextNode = domConstruct.create("div", {className:"mblListItemRightText"}, this.labelNode, "before");
+			}
+			if(this.rightTextNode){ // when using a template it may not contain a rightTextNode 
+				this.rightText = text;
+				this.rightTextNode.innerHTML = this._cv ? this._cv(text) : text;
+				if(this.textDir){
+					this.rightTextNode.innerHTML = common.enforceTextDirWithUcc(this.rightTextNode.innerHTML, this.textDir);
+				}
+			}
+		},
+
+		_setLabelAttr: function(/*String*/text){
+			this.inherited("_setLabelAttr",arguments);
+			this.labelNode.innerHTML = common.enforceTextDirWithUcc(this.labelNode.innerHTML, this.textDir);
+		},
+
+		_applyTextDirToTextElements: function(){
+			// summary:
+			//		Wrap child text nodes in directional UCC marks
+			if(this.labelNode.innerHTML){
+				this.labelNode.innerHTML = common.removeUCCFromText(this.labelNode.innerHTML);
+				this.labelNode.innerHTML = common.enforceTextDirWithUcc(this.labelNode.innerHTML, this.textDir);
+				this.labelNode.style.cssText = "text-align: start";
+				return;
+			}
+			var nEncount = 0;
+			array.forEach(this.domNode.childNodes, function(node){
+				if(nEncount === 0){
+					/* Replace content of directional text node, if found */
+					if(node.nodeType === 3 && (node.nodeValue === common.MARK.RLE || node.nodeValue === common.MARK.LRE)){
+						node.nodeValue = (node.nodeValue === common.MARK.RLE) ? common.MARK.LRE : common.MARK.RLE;
+						nEncount = 2;
+						return;      
+					}
+					var currentNode = (node.nodeType === 1 && node.childNodes.length === 1) ? node.firstChild : node;
+					if(currentNode.nodeType === 3 && currentNode.nodeValue){
+						/* Insert directional text node */
+						if(currentNode.nodeValue.search(/[.\S]/) != -1){
+							nEncount = 1;
+							textNode = win.doc.createTextNode((this.getTextDir(currentNode.nodeValue).toLowerCase() === 'rtl') ? common.MARK.RLE : common.MARK.LRE);    
+							domConstruct.place(textNode, node, "before");
+						}
+					}
+				}
+				/* Insert PDF text node, prevent further processing */
+				else if(nEncount === 1 && node.nodeName.toLowerCase() === "div"){
+						nEncount = 2;
+						textNode = win.doc.createTextNode(common.MARK.PDF);
+						domConstruct.place(textNode, node, "before");
+				}
+			}, this);
+		},
+
+		_setTextDirAttr: function(textDir){
+			if(textDir && this.textDir !== textDir){
+				this.textDir = textDir;
+				this._applyTextDirToTextElements();
+				if(this.rightTextNode){
+				    this.rightTextNode.innerHTML = common.removeUCCFromText(this.rightTextNode.innerHTML);
+				    this.rightTextNode.innerHTML = common.enforceTextDirWithUcc(this.rightTextNode.innerHTML, this.textDir);
+				}
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/RoundRectCategory.js b/dojox/mobile/bidi/RoundRectCategory.js
new file mode 100644
index 0000000..40bec95
--- /dev/null
+++ b/dojox/mobile/bidi/RoundRectCategory.js
@@ -0,0 +1,30 @@
+define([
+	"dojo/_base/declare",
+	"./common"
+], function(declare, common){
+
+	// module:
+	//		dojox/mobile/bidi/RoundRectCategory
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile RoundRectCategory widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction support for Label.
+		//		This class should not be used directly.
+		//		Mobile RoundRectCategory widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_setLabelAttr: function(text){
+			if(this.textDir){
+				text = common.enforceTextDirWithUcc(text, this.textDir);
+			}
+			this.inherited(arguments);
+		},
+		_setTextDirAttr: function(textDir){
+			if(textDir && this.textDir !== textDir){
+				this.textDir = textDir;
+				this.label = common.removeUCCFromText(this.label);
+				this.set('label', this.label);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/SpinWheelSlot.js b/dojox/mobile/bidi/SpinWheelSlot.js
new file mode 100644
index 0000000..ec12635
--- /dev/null
+++ b/dojox/mobile/bidi/SpinWheelSlot.js
@@ -0,0 +1,42 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/window",
+	"dojo/_base/array",
+	"dojo/dom-construct",
+	"./common"      
+], function(declare, win, array, domConstruct, common){
+
+	// module:
+	//		dojox/mobile/bidi/SpinWheelSlot
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile SpinWheelSlot widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		This class should not be used directly.
+		//		Mobile SpinWheelSlot widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		postCreate: function(){
+			this.inherited(arguments);
+			if(!this.textDir && this.getParent() && this.getParent().get("textDir")){
+				this.set("textDir", this.getParent().get("textDir"));
+			}
+		},
+
+		_setTextDirAttr: function(textDir){
+			if(textDir && (!this._created || this.textDir !== textDir)){
+				this.textDir = textDir;
+				this._setTextDirToNodes(this.textDir);
+			}
+		},
+
+		_setTextDirToNodes: function(textDir){
+			array.forEach(this.panelNodes, function(panel){
+				array.forEach(panel.childNodes, function(node, i){
+					node.innerHTML = common.removeUCCFromText(node.innerHTML);     
+					node.innerHTML = common.enforceTextDirWithUcc(node.innerHTML, this.textDir);      
+					node.style.textAlign = (this.dir.toLowerCase() === "rtl") ? "right" : "left";      
+				}, this);
+			}, this);
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/SwapView.js b/dojox/mobile/bidi/SwapView.js
new file mode 100644
index 0000000..1fe2d51
--- /dev/null
+++ b/dojox/mobile/bidi/SwapView.js
@@ -0,0 +1,38 @@
+define([
+	"dojo/_base/declare"
+], function(declare){
+
+	// module:
+	//		dojox/mobile/bidi/SwapView
+
+	return declare(null, {
+		
+		// callParentFunction: Boolean
+		//		Boolean value indicate whether to call the parent version of the function or the child one.
+		//		Used to support mirroring.
+		_callParentFunction: false,
+		
+		nextView: function(/*DomNode*/node){
+			//dojox.mobile mirroring support
+			if(this.isLeftToRight() || this._callParentFunction){
+				this._callParentFunction = false;
+				return this.inherited(arguments);
+			}else{
+				this._callParentFunction = true;
+				return this.previousView(node);
+			}
+		},
+		previousView: function(/*DomNode*/node){
+			//dojox.mobile mirroring support
+			if(this.isLeftToRight() || this._callParentFunction){
+				this._callParentFunction = false;
+				return this.inherited(arguments);
+			}else{
+				this._callParentFunction = true;
+				return this.nextView(node);
+			}
+		}
+		
+		
+	});
+});
diff --git a/dojox/mobile/bidi/Switch.js b/dojox/mobile/bidi/Switch.js
new file mode 100644
index 0000000..093c9fb
--- /dev/null
+++ b/dojox/mobile/bidi/Switch.js
@@ -0,0 +1,59 @@
+define([
+	"dojo/_base/declare",
+	"./common",
+	"dojo/dom-class"	
+], function(declare, common, domClass){
+
+	// module:
+	//		dojox/mobile/bidi/Switch
+
+	return declare(null, {
+		// summary:
+		//		Bidi support for mobile Switch widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction support for LeftLabel and RightLabel.
+		//		This class should not be used directly.
+		//		Mobile Switch widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		postCreate: function(){
+			this.inherited(arguments);
+			if(!this.textDir && this.getParent() && this.getParent().get("textDir")){
+				this.set("textDir", this.getParent().get("textDir"));
+			}
+		},
+		buildRendering: function(){
+			this.inherited(arguments);
+			// dojox.mobile mirroring support
+			if(!this.isLeftToRight()){
+				domClass.add(this.left, "mblSwitchBgLeftRtl");
+				domClass.add(this.left.firstChild, "mblSwitchTextLeftRtl");
+				domClass.add(this.right, "mblSwitchBgRightRtl");
+				domClass.add(this.right.firstChild, "mblSwitchTextRightRtl");				
+			}
+		},
+		_newState: function(newState){
+			if(this.isLeftToRight()){
+				return this.inherited(arguments);
+			}
+			return (this.inner.offsetLeft < -(this._width/2)) ? "on" : "off";
+		},
+		_setLeftLabelAttr: function(label){
+			this.inherited(arguments);
+			this.left.firstChild.innerHTML = common.enforceTextDirWithUcc(this.left.firstChild.innerHTML, this.textDir);
+		},
+
+		_setRightLabelAttr: function(label){
+			this.inherited(arguments);
+			this.right.firstChild.innerHTML = common.enforceTextDirWithUcc(this.right.firstChild.innerHTML, this.textDir);
+		},
+
+		_setTextDirAttr: function(textDir){
+			if(textDir && (!this._created || this.textDir !== textDir)){
+				this.textDir = textDir;
+				this.left.firstChild.innerHTML = common.removeUCCFromText(this.left.firstChild.innerHTML);
+				this.left.firstChild.innerHTML = common.enforceTextDirWithUcc(this.left.firstChild.innerHTML, this.textDir);
+				this.right.firstChild.innerHTML = common.removeUCCFromText(this.right.firstChild.innerHTML);
+				this.right.firstChild.innerHTML = common.enforceTextDirWithUcc(this.right.firstChild.innerHTML, this.textDir);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/TabBar.js b/dojox/mobile/bidi/TabBar.js
new file mode 100644
index 0000000..febe574
--- /dev/null
+++ b/dojox/mobile/bidi/TabBar.js
@@ -0,0 +1,23 @@
+define([
+	"dojo/_base/declare",
+	"./common"
+], function(declare, common){
+
+	// module:
+	//		mobile/bidi/TabBar
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile TabBar widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Attribute textDir is set to TabBar and to TabBarButtons.
+		//		This class should not be used directly.
+		//		Mobile TabBar widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_setTextDirAttr: function(/*String*/ textDir){
+			if(!this._created || this.textDir !== textDir){
+				this._set("textDir", textDir);
+				common.setTextDirForButtons(this);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/TabBarButton.js b/dojox/mobile/bidi/TabBarButton.js
new file mode 100644
index 0000000..c9be36d
--- /dev/null
+++ b/dojox/mobile/bidi/TabBarButton.js
@@ -0,0 +1,29 @@
+define([
+	"dojo/_base/declare",
+	"./common",
+	"dojo/dom-class"
+], function(declare, common, domClass){
+
+	// module:
+	//		mobile/bidi/TabBarButton
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile TabBarButton widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		This class should not be used directly.
+		//		Mobile TabBarButton widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_setBadgeAttr: function(/*String*/ text){
+			this.inherited(arguments);
+			this.badgeObj.setTextDir(this.textDir);
+		},
+		_setIcon: function(icon, n){
+			this.inherited(arguments);
+			// dojox.mobile mirroring support
+			if(this.iconDivNode && !this.isLeftToRight()){
+				domClass.remove(this.iconDivNode, "mblTabBarButtonIconArea");	
+				domClass.add(this.iconDivNode, "mblTabBarButtonIconAreaRtl");	
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/TextBox.js b/dojox/mobile/bidi/TextBox.js
new file mode 100644
index 0000000..11af4cb
--- /dev/null
+++ b/dojox/mobile/bidi/TextBox.js
@@ -0,0 +1,48 @@
+define([
+	"dojo/_base/declare",
+	"dijit/_BidiSupport"  //load implementation for textDir from dijit (for editable widgets), (no direct references)
+], function(declare){
+
+	// module:
+	//		dojox/mobile/bidi/TextBox
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile TextBox widget.
+		// description:
+		//		Implementation for text direction using HTML "dir" attribute (used for editable widgets).
+		//		This class should not be used directly.
+		//		Mobile TextBox widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_setTextDirAttr: function(/*String*/ textDir){
+			if(!this._created || this.textDir != textDir){
+				this._set("textDir", textDir);
+				if(this.value){
+					this.applyTextDir(this.focusNode || this.textbox);
+				}
+				else{
+					this.applyTextDir(this.focusNode || this.textbox, this.textbox.getAttribute("placeholder"));
+				}
+			}
+		},
+
+		_setDirAttr: function(/*String*/ dir){
+			if(!(this.textDir && this.textbox)){
+				this.dir = dir;
+			}
+		},
+
+		_onBlur: function(e){
+			this.inherited(arguments);
+			if(!this.textbox.value){
+				this.applyTextDir(this.textbox, this.textbox.getAttribute("placeholder"));
+			}
+		},
+
+		_onInput: function(e){
+			this.inherited(arguments);
+			if(!this.textbox.value){
+				this.applyTextDir(this.textbox, this.textbox.getAttribute("placeholder"));
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/ToolBarButton.js b/dojox/mobile/bidi/ToolBarButton.js
new file mode 100644
index 0000000..aaddca9
--- /dev/null
+++ b/dojox/mobile/bidi/ToolBarButton.js
@@ -0,0 +1,35 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-class"
+], function(declare, lang, domClass){
+
+	// module:
+	//		dojox/mobile/ToolBarButton
+
+	return declare(null, {
+		buildRendering: function(){
+			this.inherited(arguments);
+			//dojox.mobile mirroring support
+			if(!this.isLeftToRight() && this.arrow){
+				var cRemove1 = (this.arrow === "left" ? "mblToolBarButtonLeftArrow" : "mblToolBarButtonRightArrow");
+				var cRemove2 = (this.arrow === "left" ? "mblToolBarButtonHasLeftArrow" : "mblToolBarButtonHasRightArrow");
+				var cAdd1 = (this.arrow === "left" ? "mblToolBarButtonRightArrow" : "mblToolBarButtonLeftArrow");
+				var cAdd2 = (this.arrow === "left" ? "mblToolBarButtonHasRightArrow" : "mblToolBarButtonHasLeftArrow");
+				domClass.remove(this.arrowNode, cRemove1);
+				domClass.add(this.arrowNode, cAdd1);
+				domClass.remove(this.domNode, cRemove2);
+				domClass.add(this.domNode, cAdd2);
+			}
+		},
+		_setLabelAttr: function(/*String*/text){
+			// summary:
+			//		Sets the button label text.
+			this.inherited(arguments);
+			// dojox.mobile mirroring support
+			if(!this.isLeftToRight()){
+				domClass.toggle(this.tableNode, "mblToolBarButtonTextRtl", text || this.arrow);
+			}
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/Tooltip.js b/dojox/mobile/bidi/Tooltip.js
new file mode 100644
index 0000000..cb1f4f8
--- /dev/null
+++ b/dojox/mobile/bidi/Tooltip.js
@@ -0,0 +1,54 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"./common"   
+], function(array, declare, common){
+
+	// module:
+	//		dojox/mobile/bidi/Tooltip
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile Tooltip widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction support for Tooltip's text containing embedded nodes.
+		//		Complicated embedded nodes (like tables) are not supported.
+		//		This class should not be used directly.
+		//		Mobile Tooltip widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		postCreate: function(){
+			this.inherited(arguments);
+			if(this.textDir){
+				this._applyTextDirToTextElements();
+		    }		    
+		},
+		buildRendering: function(){
+		    this.inherited(arguments);
+			//dojox.mobile mirroring support
+			if(!this.isLeftToRight()){
+				this.arrow.style.left = "0px";
+			}
+		},
+
+		_setTextDirAttr: function(textDir){
+			if(textDir && this.textDir !== textDir){
+				this.textDir = textDir;
+				this._applyTextDirToTextElements();
+			}
+		},
+
+		_applyTextDirToTextElements: function(){
+			// summary:
+			//		Wrap relevant child text nodes in directional UCC marks
+			array.forEach(this.domNode.childNodes, function(node){
+				var currentNode = (node.nodeType === 1 && node.childNodes.length === 1) ? node.firstChild : node;
+				if(currentNode.nodeType === 3 && currentNode.nodeValue){
+					if(currentNode.nodeValue.search(/[.\S]/) != -1){
+						currentNode.nodeValue = common.removeUCCFromText(currentNode.nodeValue);
+						currentNode.nodeValue = common.enforceTextDirWithUcc(currentNode.nodeValue, this.textDir);
+					}
+				}
+			}, this);
+		}
+	});
+});
+
diff --git a/dojox/mobile/bidi/TreeView.js b/dojox/mobile/bidi/TreeView.js
new file mode 100644
index 0000000..b47fc36
--- /dev/null
+++ b/dojox/mobile/bidi/TreeView.js
@@ -0,0 +1,20 @@
+define([
+	"dojo/_base/declare"
+], function(declare){
+
+	// module:
+	//		dojox/mobile/bidi/TreeView
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile TreeView widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Text direction attribute of the Tree is set to ListItem.
+		//		This class should not be used directly.
+		//		Mobile TreeView widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_customizeListItem: function(listItemArgs){
+			listItemArgs.textDir = this.textDir;
+		}
+
+	});
+});
diff --git a/dojox/mobile/bidi/ValuePickerSlot.js b/dojox/mobile/bidi/ValuePickerSlot.js
new file mode 100644
index 0000000..bb94951
--- /dev/null
+++ b/dojox/mobile/bidi/ValuePickerSlot.js
@@ -0,0 +1,43 @@
+define([
+	"dojo/_base/declare",
+	"./common"   
+], function(declare, common){
+
+	// module:
+	//		dojox/mobile/bidi/ValuePickerSlot
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile ValuePickerSlot widget, using Unicode Chontrol Characters to control text direction.
+		// description:
+		//		Implementation for text direction support for Value.
+		//		This class should not be used directly.
+		//		Mobile ValuePickerSlot widget loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		postCreate: function(){
+			if(!this.textDir && this.getParent() && this.getParent().get("textDir")){
+				this.textDir = this.getParent().get("textDir");
+			}
+		},
+
+		_getValueAttr: function(){
+			return common.removeUCCFromText(this.inputNode.value);
+		},
+
+		_setValueAttr: function(value){
+			this.inherited(arguments);
+			this._applyTextDirToValueNode();
+		},
+
+		_setTextDirAttr: function(textDir){
+			if(textDir && this.textDir !== textDir){
+				this.textDir = textDir;
+				this._applyTextDirToValueNode();
+			}
+		},
+
+		_applyTextDirToValueNode: function(){
+			this.inputNode.value = common.removeUCCFromText(this.inputNode.value);
+			this.inputNode.value = common.enforceTextDirWithUcc(this.inputNode.value, this.textDir);
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/_ComboBoxMenu.js b/dojox/mobile/bidi/_ComboBoxMenu.js
new file mode 100644
index 0000000..94200df
--- /dev/null
+++ b/dojox/mobile/bidi/_ComboBoxMenu.js
@@ -0,0 +1,27 @@
+define([
+	"dojo/_base/declare",
+	"dojo/dom-construct",
+	"dojo/dom-class",
+	"dojo/dom-style"
+],
+	function(declare, domConstruct, domClass, domStyle){
+	// module:
+	//		dojox/mobile/bidi/_ComboBoxMenu
+
+	return declare(null, {
+
+		buildRendering: function(){
+			this.inherited(arguments);
+			// dojox.mobile mirroring support
+			if(!this.isLeftToRight()){
+				this.containerNode.style.left = "auto";
+				domStyle.set(this.containerNode, { position:"absolute", top:0, right:0 });
+				domClass.remove(this.previousButton, "mblComboBoxMenuItem");
+				domClass.add(this.previousButton, "mblComboBoxMenuItemRtl");
+				domClass.remove(this.nextButton, "mblComboBoxMenuItem");
+				domClass.add(this.nextButton, "mblComboBoxMenuItemRtl");
+			}
+		}
+		
+	});
+});
diff --git a/dojox/mobile/bidi/_ItemBase.js b/dojox/mobile/bidi/_ItemBase.js
new file mode 100644
index 0000000..6de5010
--- /dev/null
+++ b/dojox/mobile/bidi/_ItemBase.js
@@ -0,0 +1,40 @@
+define([
+	"dojo/_base/declare",
+	"./common"
+], function(declare, common){
+
+	// module:
+	//		dojox/mobile/bidi/_ItemBase
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile _ItemBase widget, using Unicode Control Characters to control text direction.
+		// description:
+		//		Implementation for text direction support for Label.
+		//		This class should not be used directly.
+		//		Mobile _ItemBase loads this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		_setLabelAttr: function(/*String*/ text){
+			this._set("label", text);
+			this.labelNode.innerHTML = this._cv ? this._cv(text) : text;
+			if (!this.textDir){
+				var p = this.getParent();
+				this.textDir = p && p.get("textDir") ? p.get("textDir") : "";
+			}
+			this.labelNode.innerHTML = common.enforceTextDirWithUcc(this.labelNode.innerHTML, this.textDir);
+		},
+		_setTextDirAttr: function(/*String*/ textDir){
+			if(!this._created || this.textDir !== textDir){
+				this._set("textDir", textDir);
+				this.labelNode.innerHTML = common.enforceTextDirWithUcc(common.removeUCCFromText(this.labelNode.innerHTML), this.textDir);
+				if(this.badgeObj && this.badgeObj.setTextDir){ this.badgeObj.setTextDir(textDir); }
+			}
+		},
+		getTransOpts: function(){
+			var opts = this.inherited(arguments);
+			if(!this.isLeftToRight()){
+				opts.transitionDir = opts.transitionDir * -1; 
+			}
+			return opts;
+		}		
+	});
+});
diff --git a/dojox/mobile/bidi/_StoreListMixin.js b/dojox/mobile/bidi/_StoreListMixin.js
new file mode 100644
index 0000000..5519a7f
--- /dev/null
+++ b/dojox/mobile/bidi/_StoreListMixin.js
@@ -0,0 +1,21 @@
+define([
+	"dojo/_base/declare"
+], function(declare){
+
+	// module:
+	//		dojox/mobile/bidi/_StoreListMixin
+
+	return declare(null, {
+		// summary:
+		//		Support for control over text direction for mobile _StoreListMixin and _DataListMixin.
+		// description:
+		//		Property textDir is set to created ListItem.
+		//		This class should not be used directly.
+		//		Mobile _StoreListMixin and _DataListMixin load this module when user sets "has: {'dojo-bidi': true }" in data-dojo-config.
+		createListItem: function(item){
+			var w = this.inherited(arguments);
+			w.set("textDir", this.textDir);
+			return w;
+		}
+	});
+});
diff --git a/dojox/mobile/bidi/common.js b/dojox/mobile/bidi/common.js
new file mode 100644
index 0000000..3e522ed
--- /dev/null
+++ b/dojox/mobile/bidi/common.js
@@ -0,0 +1,61 @@
+define(["dojo/_base/array", "dijit/_BidiSupport"], function(array, _BidiSupport){
+
+		// module:
+		//		bidi/common
+		// summary:
+		//		Module contains functions to support text direction, that can be set independent to GUI direction.
+		// description:
+		//		Unicode control characters (UCC) used to control text direction.
+
+		common = {};
+		common.enforceTextDirWithUcc = function(text, textDir){
+			// summary:
+			//		Wraps by UCC (Unicode control characters) displayed text according to textDir.
+			// text:
+			//		The text to be wrapped.
+			// textDir:
+			//		Text direction.
+			// description:
+			//		There's a dir problem with some HTML elements. For some Android browsers Hebrew text is displayed right to left also 
+			//		when dir is set to LTR.
+			//		Therefore the only solution is to use UCC to display the text in correct orientation.
+			if(textDir){
+				textDir = (textDir === "auto") ? _BidiSupport.prototype._checkContextual(text) : textDir;
+				return ((textDir === "rtl") ? common.MARK.RLE : common.MARK.LRE) + text + common.MARK.PDF;
+			}
+			return text;
+		};
+
+		common.removeUCCFromText = function(text){
+			// summary:
+			//		Removes UCC from input string.
+			// text:
+			//		The text to be stripped from UCC.
+			if (!text){
+				return text;
+			}
+			return text.replace(/\u202A|\u202B|\u202C/g,"");
+		};
+
+		common.setTextDirForButtons = function(widget){
+			// summary:
+			//		Sets textDir property to children.
+			// widget:
+			//		parent widget
+			var children = widget.getChildren();
+			if (children && widget.textDir){
+				array.forEach(children, function(ch){
+					ch.set("textDir", widget.textDir);
+				}, widget); 
+			}
+		};
+
+		// UCC - constants that will be used by bidi support.
+		common.MARK = {
+			LRE : '\u202A',
+			RLE : '\u202B',
+			PDF : '\u202C'
+		};
+
+		return common;
+});
diff --git a/dojox/mobile/bookmarkable.js b/dojox/mobile/bookmarkable.js
new file mode 100644
index 0000000..997419e
--- /dev/null
+++ b/dojox/mobile/bookmarkable.js
@@ -0,0 +1,154 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/hash",
+	"dijit/registry",
+	"./TransitionEvent",
+	"./View",
+	"./viewRegistry"
+], function(array, connect, lang, win, hash, registry, TransitionEvent, View, viewRegistry){
+
+	// module:
+	//		dojox/mobile/bookmarkable
+
+	var b = {
+		// summary:
+		//		Utilities to make the view transitions bookmarkable.
+
+		// settingHash: [private] Boolean
+		//		Whether the browser URL needs to be updated to include the hash.
+		settingHash: false,
+		
+		// transitionInfo: Array
+		//		An array containing information about the transition.
+		transitionInfo: [],
+
+		getTransitionInfo: function(/*String*/ fromViewId, /*String*/ toViewId){
+			// summary:
+			//		Returns an array containing the transition information.
+			return this.transitionInfo[fromViewId.replace(/^#/, "") + ":" + toViewId.replace(/^#/, "")]; // Array
+		},
+
+		addTransitionInfo: function(/*String*/ fromViewId, /*String*/ toViewId, /*Object*/args){
+			// summary:
+			//		Adds transition information.
+			this.transitionInfo[fromViewId.replace(/^#/, "") + ":" + toViewId.replace(/^#/, "")] = args;
+		},
+
+		findTransitionViews: function(/*String*/moveTo){
+			// summary:
+			//		Searches for a starting view and a destination view.
+			if(!moveTo){ return []; }
+			var view = registry.byId(moveTo.replace(/^#/, ""));
+			if(!view){ return []; }
+			for(var v = view.getParent(); v; v = v.getParent()){ // search for the topmost invisible parent node
+				if(v.isVisible && !v.isVisible()){
+					view = v;
+				}
+			}
+			// fromView, toView
+			return [view.getShowingView(), view]; // Array 
+		},
+
+		onHashChange: function(value){
+			// summary:
+			//		Called on "/dojo/hashchange" events.
+			if(this.settingHash){
+				this.settingHash = false;
+				return;
+			}
+			var params = this.handleFragIds(value);
+			params.hashchange = true;
+			new TransitionEvent(win.body(), params).dispatch();
+		},
+
+		handleFragIds: function(/*String*/fragIds){
+			// summary:
+			//		Analyzes the given hash (fragment id).
+			// description:
+			//		Given a comma-separated list of view IDs, this method
+			//		searches for a transition destination, and makes all the
+			//		views in the hash visible.
+
+			var arr, moveTo;
+			if(!fragIds){
+				moveTo = viewRegistry.initialView.id;
+				arr = this.findTransitionViews(moveTo);
+			}else{
+				var ids = fragIds.replace(/^#/, "").split(/,/);
+				for(var i = 0; i < ids.length; i++){
+					// Search for a transition destination view.
+
+					var view = registry.byId(ids[i]);
+
+					// Skip a visible view. Visible view can't be a destination candidate.
+					if(view.isVisible()){ continue; }
+
+					// Check if all the ancestors are in the fragIds.
+					// If not, obviously the view was NOT visible before the previous transition.
+					// That means the previous transition can't happen from that view,
+					// which means the view can't be a destination.
+					var success = true;
+					for(var v = viewRegistry.getParentView(view); v; v = viewRegistry.getParentView(v)){
+						if(array.indexOf(ids, v.id) === -1){
+							success = false;
+							break;
+						}
+					}
+					if(!success){
+						// Simply make the view visible without transition.
+						array.forEach(view.getSiblingViews(), function(v){
+							v.domNode.style.display = (v === view) ? "" : "none";
+						});
+						continue;
+					}
+
+					arr = this.findTransitionViews(ids[i]);
+					if(arr.length === 2){
+						moveTo = ids[i];
+						// The destination found. But continue the loop to make
+						// the other views in the fragIds visible.
+					}
+				}
+			}
+
+			var args = this.getTransitionInfo(arr[0].id, arr[1].id);
+			var dir = 1;
+			if(!args){
+				args = this.getTransitionInfo(arr[1].id, arr[0].id);
+				dir = -1;
+			}
+
+			return {
+				moveTo: "#" + moveTo,
+				transitionDir: args ? args.transitionDir * dir : 1,
+				transition: args ? args.transition : "none"
+			};
+		},
+
+		setFragIds: function(/*Widget*/toView){
+			// summary:
+			//		Updates the hash (fragment id) in the browser URL.
+			// description:
+			//		The hash value consists of one or more visible view ids
+			//		separated with commas.
+
+			var arr = array.filter(viewRegistry.getViews(), function(v){ return v.isVisible(); });
+			this.settingHash = true;
+			hash(array.map(arr, function(v){ return v.id; }).join(","));
+		}
+	};
+
+	connect.subscribe("/dojo/hashchange", null, function(){ b.onHashChange.apply(b, arguments); });
+
+	lang.extend(View, {
+		getTransitionInfo: function(){ b.getTransitionInfo.apply(b, arguments); },
+		addTransitionInfo: function(){ b.addTransitionInfo.apply(b, arguments); },
+		handleFragIds: function(){ b.handleFragIds.apply(b, arguments); },
+		setFragIds: function(){ b.setFragIds.apply(b, arguments); }
+	});
+
+	return b;
+});
diff --git a/dojox/mobile/build/build.bat b/dojox/mobile/build/build.bat
index adf5820..7b3bd75 100755
--- a/dojox/mobile/build/build.bat
+++ b/dojox/mobile/build/build.bat
@@ -4,10 +4,9 @@ rem Build script for dojox.mobile
 
 if "%1"=="separate" goto ok
 if "%1"=="single" goto ok
-echo Usage: build separate^|single [webkit]
+echo Usage: build separate^|single
 echo   separate  Create mobile.js that includes only dojox.mobile
 echo   single    Create a single dojo.js layer that includes dojox.mobile
-echo   webkit    Enable webkitMobile=true option (Loses PC browser support)
 goto end
 :ok
 
@@ -15,19 +14,14 @@ rem set optimize=shrinksafe
 set optimize=closure
 set profile=mobile
 set dir=release-mobile-separate
-set webkit=
 rem set standalone=standaloneScrollable=true
 if "%~1"=="single" set profile=mobile-all
 if "%~1"=="single" set dir=release-mobile-single
 shift
-if not "%~1"=="webkit" goto skip1
-set webkit=webkitMobile=true
-shift
-:skip1
 
 cd ..\..\..\util\buildscripts
 
-call build profile=%profile% action=release optimize=%optimize% layerOptimize=%optimize% cssOptimize=comments releaseDir=../../%dir%/ %webkit% %standalone% %~1 %~2 %~3 %~4 %~5 %~6 %~7 %~8 %~9
+call build profile=%profile% action=release optimize=%optimize% layerOptimize=%optimize% cssOptimize=comments releaseDir=../../%dir%/ %standalone% %~1 %~2 %~3 %~4 %~5 %~6 %~7 %~8 %~9
 
 cd ..\..\dojox\mobile\build
 
diff --git a/dojox/mobile/build/build.sh b/dojox/mobile/build/build.sh
index 6ecb656..eecc105 100755
--- a/dojox/mobile/build/build.sh
+++ b/dojox/mobile/build/build.sh
@@ -3,10 +3,9 @@
 # Build script for dojox.mobile
 
 if [ $# -eq 0 ]; then
-  echo 'Usage: build separate|single [webkit]'
+  echo 'Usage: build separate|single'
   echo '  separate  Create mobile.js that includes only dojox.mobile'
   echo '  single    Create a single dojo.js layer that includes dojox.mobile'
-  echo '  webkit    Enable webkitMobile=true option (Loses PC browser support)'
   exit 1
 fi
 
@@ -14,7 +13,6 @@ fi
 optimize=closure
 profile=mobile
 dir=release-mobile-separate
-webkit=
 #standalone=standaloneScrollable=true
 if [ "$1" == "single" ]; then
   profile=mobile-all
@@ -23,13 +21,9 @@ if [ "$1" == "single" ]; then
   dir=release-mobile-single
 fi
 shift 1
-if [ "$1" == "webkit" ]; then
-  webkit=webkitMobile=true
-  shift 1
-fi
 
 cd ../../../util/buildscripts
 
-./build.sh profile=$profile action=release optimize=$optimize layerOptimize=$optimize cssOptimize=comments releaseDir=../../$dir/ $webkit $standalone $*
+./build.sh profile=$profile action=release optimize=$optimize layerOptimize=$optimize cssOptimize=comments releaseDir=../../$dir/ $standalone $*
 
 cd ../../dojox/mobile/build
diff --git a/dojox/mobile/common.js b/dojox/mobile/common.js
index f97a9d2..24a4d74 100644
--- a/dojox/mobile/common.js
+++ b/dojox/mobile/common.js
@@ -1,34 +1,48 @@
 define([
-	"dojo/_base/kernel", // to test dojo.hash
 	"dojo/_base/array",
 	"dojo/_base/config",
 	"dojo/_base/connect",
 	"dojo/_base/lang",
 	"dojo/_base/window",
+	"dojo/_base/kernel",
 	"dojo/dom-class",
 	"dojo/dom-construct",
-	"dojo/dom-style",
-//	"dojo/hash", // optionally prereq'ed
 	"dojo/ready",
-	"dijit/registry",	// registry.toArray
+	"dojo/touch",
+	"dijit/registry",
 	"./sniff",
-	"./uacss"
-], function(dojo, array, config, connect, lang, win, domClass, domConstruct, domStyle, ready, registry, has, uacss){
-
-	var dm = lang.getObject("dojox.mobile", true);
-/*=====
-	var dm = dojox.mobile;
-=====*/
+	"./uacss" // (no direct references)
+], function(array, config, connect, lang, win, kernel, domClass, domConstruct, ready, touch, registry, has){
 
 	// module:
 	//		dojox/mobile/common
-	// summary:
-	//		A common module for dojox.mobile.
-	// description:
-	//		This module includes common utility functions that are used by
-	//		dojox.mobile widgets. Also, it provides functions that are commonly
-	//		necessary for mobile web applications, such as the hide address bar
-	//		function.
+
+	var dm = lang.getObject("dojox.mobile", true);
+
+	// tell dojo/touch to generate synthetic clicks immediately
+	// and regardless of preventDefault() calls on touch events
+	win.doc.dojoClick = true;
+	/// ... but let user disable this by removing dojoClick from the document
+	if(has("touch")){
+		// Do we need to send synthetic clicks when preventDefault() is called on touch events?
+		// This is normally true on anything except Android 4.1+ and IE10, but users reported
+		// exceptions like Galaxy Note 2. So let's use a has("clicks-prevented") flag, and let
+		// applications override it through data-dojo-config="has:{'clicks-prevented':true}" if needed.
+		has.add("clicks-prevented", !(has("android") >= 4.1 || has("ie") >= 10));
+		if(has("clicks-prevented")){
+			dm._sendClick = function(target, e){
+				// dojo/touch will send a click if dojoClick is set, so don't do it again.
+				for(var node = target; node; node = node.parentNode){
+					if(node.dojoClick){
+						return;
+					}
+				}
+				var ev = win.doc.createEvent("MouseEvents"); 
+				ev.initMouseEvent("click", true, true, win.global, 1, e.screenX, e.screenY, e.clientX, e.clientY); 
+				target.dispatchEvent(ev);
+			};
+		}
+	}
 
 	dm.getScreenSize = function(){
 		// summary:
@@ -41,7 +55,7 @@ define([
 
 	dm.updateOrient = function(){
 		// summary:
-		//		Updates the orientation specific css classes, 'dj_portrait' and
+		//		Updates the orientation specific CSS classes, 'dj_portrait' and
 		//		'dj_landscape'.
 		var dim = dm.getScreenSize();
 		domClass.replace(win.doc.documentElement,
@@ -55,12 +69,16 @@ define([
 		// summary:
 		//		Detects the screen size and determines if the screen is like
 		//		phone or like tablet. If the result is changed,
-		//		it sets either of the following css class to <html>
-		//			- 'dj_phone'
-		//			- 'dj_tablet'
-		//		and it publishes either of the following events.
-		//			- '/dojox/mobile/screenSize/phone'
-		//			- '/dojox/mobile/screenSize/tablet'
+		//		it sets either of the following css class to `<html>`:
+		//
+		//		- 'dj_phone'
+		//		- 'dj_tablet'
+		//
+		//		and it publishes either of the following events:
+		//
+		//		- '/dojox/mobile/screenSize/phone'
+		//		- '/dojox/mobile/screenSize/tablet'
+
 		var dim = dm.getScreenSize();
 		var sz = Math.min(dim.w, dim.h);
 		var from, to;
@@ -79,99 +97,92 @@ define([
 	};
 	dm.detectScreenSize();
 
-	dm.setupIcon = function(/*DomNode*/iconNode, /*String*/iconPos){
-		// summary:
-		//		Sets up CSS sprite for a foreground image.
-		if(iconNode && iconPos){
-			var arr = array.map(iconPos.split(/[ ,]/),function(item){return item-0});
-			var t = arr[0]; // top
-			var r = arr[1] + arr[2]; // right
-			var b = arr[0] + arr[3]; // bottom
-			var l = arr[1]; // left
-			domStyle.set(iconNode, {
-				clip: "rect("+t+"px "+r+"px "+b+"px "+l+"px)",
-				top: (iconNode.parentNode ? domStyle.get(iconNode, "top") : 0) - t + "px",
-				left: -l + "px"
-			});
-		}
-	};
-
-	// dojox.mobile.hideAddressBarWait: Number
+	// dojox/mobile.hideAddressBarWait: Number
 	//		The time in milliseconds to wait before the fail-safe hiding address
 	//		bar runs. The value must be larger than 800.
 	dm.hideAddressBarWait = typeof(config["mblHideAddressBarWait"]) === "number" ?
 		config["mblHideAddressBarWait"] : 1500;
 
-	dm.hide_1 = function(force){
+	dm.hide_1 = function(){
 		// summary:
 		//		Internal function to hide the address bar.
+		// tags:
+		//		private
 		scrollTo(0, 1);
-		var h = dm.getScreenSize().h + "px";
-		if(has('android')){
-			if(force){
-				win.body().style.minHeight = h;
-			}
-			dm.resizeAll();
-		}else{
-			if(force || dm._h === h && h !== win.body().style.minHeight){
-				win.body().style.minHeight = h;
+		dm._hidingTimer = (dm._hidingTimer == 0) ? 200 : dm._hidingTimer * 2;
+		setTimeout(function(){ // wait for a while for "scrollTo" to finish
+			if(dm.isAddressBarHidden() || dm._hidingTimer > dm.hideAddressBarWait){
+				// Succeeded to hide address bar, or failed but timed out 
 				dm.resizeAll();
+				dm._hiding = false;
+			}else{
+				// Failed to hide address bar, so retry after a while
+				setTimeout(dm.hide_1, dm._hidingTimer);
 			}
-		}
-		dm._h = h;
+		}, 50); //50ms is an experiential value
 	};
 
-	dm.hide_fs = function(){
-		// summary:
-		//		Internal function to hide the address bar for fail-safe.
-		// description:
-		//		Resets the height of the body, performs hiding the address
-		//		bar, and calls resizeAll().
-		//		This is for fail-safe, in case of failure to complete the
-		//		address bar hiding in time.
-		var t = win.body().style.minHeight;
-		win.body().style.minHeight = (dm.getScreenSize().h * 2) + "px"; // to ensure enough height for scrollTo to work
-		scrollTo(0, 1);
-		setTimeout(function(){
-			dm.hide_1(1);
-			dm._hiding = false;
-		}, 1000);
-	};
 	dm.hideAddressBar = function(/*Event?*/evt){
 		// summary:
 		//		Hides the address bar.
 		// description:
-		//		Tries hiding of the address bar a couple of times to do it as
-		//		quick as possible while ensuring resize is done after the hiding
+		//		Tries to hide the address bar a couple of times. The purpose is to do 
+		//		it as quick as possible while ensuring the resize is done after the hiding
 		//		finishes.
 		if(dm.disableHideAddressBar || dm._hiding){ return; }
 		dm._hiding = true;
-		dm._h = 0;
-		win.body().style.minHeight = (dm.getScreenSize().h * 2) + "px"; // to ensure enough height for scrollTo to work
-		setTimeout(dm.hide_1, 0);
-		setTimeout(dm.hide_1, 200);
-		setTimeout(dm.hide_1, 800);
-		setTimeout(dm.hide_fs, dm.hideAddressBarWait);
+		dm._hidingTimer = has("ios") ? 200 : 0; // Need to wait longer in case of iPhone
+		var minH = screen.availHeight;
+		if(has('android')){
+			minH = outerHeight / devicePixelRatio;
+			// On some Android devices such as Galaxy SII, minH might be 0 at this time.
+			// In that case, retry again after a while. (200ms is an experiential value)
+			if(minH == 0){
+				dm._hiding = false;
+				setTimeout(function(){ dm.hideAddressBar(); }, 200);
+			}
+			// On some Android devices such as HTC EVO, "outerHeight/devicePixelRatio"
+			// is too short to hide address bar, so make it high enough
+			if(minH <= innerHeight){ minH = outerHeight; }
+			// On Android 2.2/2.3, hiding address bar fails when "overflow:hidden" style is
+			// applied to html/body element, so force "overflow:visible" style
+			if(has('android') < 3){
+				win.doc.documentElement.style.overflow = win.body().style.overflow = "visible";
+			}
+		}
+		if(win.body().offsetHeight < minH){ // to ensure enough height for scrollTo to work
+			win.body().style.minHeight = minH + "px";
+			dm._resetMinHeight = true;
+		}
+		setTimeout(dm.hide_1, dm._hidingTimer);
+	};
+
+	dm.isAddressBarHidden = function(){
+		return pageYOffset === 1;
 	};
 
 	dm.resizeAll = function(/*Event?*/evt, /*Widget?*/root){
 		// summary:
-		//		Call the resize() method of all the top level resizable widgets.
+		//		Calls the resize() method of all the top level resizable widgets.
 		// description:
-		//		Find all widgets that do not have a parent or the parent does not
-		//		have the resize() method, and call resize() for them.
-		//		If a widget has a parent that has resize(), call of the widget's
+		//		Finds all widgets that do not have a parent or the parent does not
+		//		have the resize() method, and calls resize() for them.
+		//		If a widget has a parent that has resize(), calling widget's
 		//		resize() is its parent's responsibility.
 		// evt:
 		//		Native event object
 		// root:
-		//		If specified, search the specified widget recursively for top level
+		//		If specified, searches the specified widget recursively for top-level
 		//		resizable widgets.
 		//		root.resize() is always called regardless of whether root is a
 		//		top level widget or not.
-		//		If omitted, search the entire page.
+		//		If omitted, searches the entire page.
 		if(dm.disableResizeAll){ return; }
-		connect.publish("/dojox/mobile/resizeAll", [evt, root]);
+		connect.publish("/dojox/mobile/resizeAll", [evt, root]); // back compat
+		connect.publish("/dojox/mobile/beforeResizeAll", [evt, root]);
+		if(dm._resetMinHeight){
+			win.body().style.minHeight = dm.getScreenSize().h + "px";
+		} 
 		dm.updateOrient();
 		dm.detectScreenSize();
 		var isTopLevel = function(w){
@@ -191,226 +202,116 @@ define([
 			array.forEach(array.filter(registry.toArray(), isTopLevel),
 					function(w){ w.resize(); });
 		}
+		connect.publish("/dojox/mobile/afterResizeAll", [evt, root]);
 	};
 
 	dm.openWindow = function(url, target){
 		// summary:
-		//		Opens a new browser window with the given url.
+		//		Opens a new browser window with the given URL.
 		win.global.open(url, target || "_blank");
 	};
 
-	dm.createDomButton = function(/*DomNode*/refNode, /*Object?*/style, /*DomNode?*/toNode){
+	dm._detectWindowsTheme = function(){
 		// summary:
-		//		Creates a DOM button.
-		// description:
-		//		DOM button is a simple graphical object that consists of one or
-		//		more nested DIV elements with some CSS styling. It can be used
-		//		in place of an icon image on ListItem, IconItem, and so on.
-		//		The kind of DOM button to create is given as a class name of
-		//		refNode. The number of DIVs to create is searched from the style
-		//		sheets in the page. However, if the class name has a suffix that
-		//		starts with an underscore, like mblDomButtonGoldStar_5, then the
-		//		suffixed number is used instead. A class name for DOM button
-		//		must starts with 'mblDomButton'.
-		// refNode:
-		//		A node that has a DOM button class name.
-		// style:
-		//		A hash object to set styles to the node.
-		// toNode:
-		//		A root node to create a DOM button. If omitted, refNode is used.
+		//		Detects if the "windows" theme is used,
+		//		if it is used, set has("windows-theme") and
+		//		add the .windows_theme class on the document.
+		
+		// Avoid unwanted (un)zoom on some WP8 devices (at least Nokia Lumia 920) 
+		if(navigator.userAgent.match(/IEMobile\/10\.0/)){
+			domConstruct.create("style", 
+				{innerHTML: "@-ms-viewport {width: auto !important}"}, win.doc.head);
+		}
 
-		if(!dm._domButtons){
-			if(has("webkit")){
-				var findDomButtons = function(sheet, dic){
-					// summary:
-					//		Searches the style sheets for DOM buttons.
-					// description:
-					//		Returns a key-value pair object whose keys are DOM
-					//		button class names and values are the number of DOM
-					//		elements they need.
-					var i, j;
-					if(!sheet){
-						var dic = {};
-						var ss = dojo.doc.styleSheets;
-						for (i = 0; i < ss.length; i++){
-							ss[i] && findDomButtons(ss[i], dic);
-						}
-						return dic;
-					}
-					var rules = sheet.cssRules || [];
-					for (i = 0; i < rules.length; i++){
-						var rule = rules[i];
-						if(rule.href && rule.styleSheet){
-							findDomButtons(rule.styleSheet, dic);
-						}else if(rule.selectorText){
-							var sels = rule.selectorText.split(/,/);
-							for (j = 0; j < sels.length; j++){
-								var sel = sels[j];
-								var n = sel.split(/>/).length - 1;
-								if(sel.match(/(mblDomButton\w+)/)){
-									var cls = RegExp.$1;
-									if(!dic[cls] || n > dic[cls]){
-										dic[cls] = n;
-									}
-								}
-							}
-						}
-					}
-				}
-				dm._domButtons = findDomButtons();
-			}else{
-				dm._domButtons = {};
+		var setWindowsTheme = function(){
+			domClass.add(win.doc.documentElement, "windows_theme");
+			kernel.experimental("Dojo Mobile Windows theme", "Behavior and appearance of the Windows theme are experimental.");
+		};
+
+		// First see if the "windows-theme" feature has already been set explicitly
+		// in that case skip aut-detect
+		var windows = has("windows-theme");
+		if(windows !== undefined){
+			if(windows){
+				setWindowsTheme();
 			}
+			return;
 		}
 
-		var s = refNode.className;
-		var node = toNode || refNode;
-		if(s.match(/(mblDomButton\w+)/) && s.indexOf("/") === -1){
-			var btnClass = RegExp.$1;
-			var nDiv = 4;
-			if(s.match(/(mblDomButton\w+_(\d+))/)){
-				nDiv = RegExp.$2 - 0;
-			}else if(dm._domButtons[btnClass] !== undefined){
-				nDiv = dm._domButtons[btnClass];
-			}
-			var props = null;
-			if(has("bb") && config["mblBBBoxShadowWorkaround"] !== false){
-				// Removes box-shadow because BlackBerry incorrectly renders it.
-				props = {style:"-webkit-box-shadow:none"};
-			}
-			for(var i = 0, p = node; i < nDiv; i++){
-				p = p.firstChild || domConstruct.create("DIV", props, p);
+		// check css
+		var i, j;
+
+		var check = function(href){
+			// TODO: find a better regexp to match?
+			if(href && href.indexOf("/windows/") !== -1){
+				has.add("windows-theme", true);
+				setWindowsTheme();
+				return true;
 			}
-			if(toNode){
-				setTimeout(function(){
-					domClass.remove(refNode, btnClass);
-				}, 0);
-				domClass.add(toNode, btnClass);
+			return false;
+		};
+
+		// collect @import
+		var s = win.doc.styleSheets;
+		for(i = 0; i < s.length; i++){
+			if(s[i].href){ continue; }
+			var r = s[i].cssRules || s[i].imports;
+			if(!r){ continue; }
+			for(j = 0; j < r.length; j++){
+				if(check(r[j].href)){
+					return;
+				}
 			}
-		}else if(s.indexOf(".") !== -1){ // file name
-			domConstruct.create("IMG", {src:s}, node);
-		}else{
-			return null;
-		}
-		domClass.add(node, "mblDomButton");
-		if(config["mblAndroidWorkaround"] !== false && has('android') >= 2.2){
-			// Android workaround for the issue that domButtons' -webkit-transform styles sometimes invalidated
-			// by applying -webkit-transform:translated3d(x,y,z) style programmatically to non-ancestor elements,
-			// which results in breaking domButtons.
-			domStyle.set(node, "webkitTransform", "translate3d(0,0,0)");
 		}
-		!!style && domStyle.set(node, style);
-		return node;
-	};
-	
-	dm.createIcon = function(/*String*/icon, /*String*/iconPos, /*DomNode*/node, /*String?*/title, /*DomNode?*/parent){
-		// summary:
-		//		Creates or updates an icon node
-		// description:
-		//		If node exists, updates the existing node. Otherwise, creates a new one.
-		// icon:
-		//		Path for an image, or DOM button class name.
-		if(icon && icon.indexOf("mblDomButton") === 0){
-			// DOM button
-			if(node && node.className.match(/(mblDomButton\w+)/)){
-				domClass.remove(node, RegExp.$1);
-			}else{
-				node = domConstruct.create("DIV");
-			}
-			node.title = title;
-			domClass.add(node, icon);
-			dm.createDomButton(node);
-		}else if(icon && icon !== "none"){
-			// Image
-			if(!node || node.nodeName !== "IMG"){
-				node = domConstruct.create("IMG", {
-					alt: title
-				});
-			}
-			node.src = (icon || "").replace("${theme}", dm.currentTheme);
-			dm.setupIcon(node, iconPos);
-			if(parent && iconPos){
-				var arr = iconPos.split(/[ ,]/);
-				domStyle.set(parent, {
-					width: arr[2] + "px",
-					height: arr[3] + "px"
-				});
+
+		// collect <link>
+		var elems = win.doc.getElementsByTagName("link");
+		for(i = 0; i < elems.length; i++){
+			if(check(elems[i].href)){
+				return;
 			}
 		}
-		if(parent){
-			parent.appendChild(node);
-		}
-		return node;
 	};
 
-	// flag for iphone flicker workaround
-	dm._iw = config["mblIosWorkaround"] !== false && has('iphone');
-	if(dm._iw){
-		dm._iwBgCover = domConstruct.create("div"); // Cover to hide flicker in the background
+	if(config["mblApplyPageStyles"] !== false){
+		domClass.add(win.doc.documentElement, "mobile");
 	}
-	
-	if(config.parseOnLoad){
-		ready(90, function(){
-			// avoid use of query
-			/*
-			var list = query('[lazy=true] [dojoType]', null);
-			list.forEach(function(node, index, nodeList){
-				node.setAttribute("__dojoType", node.getAttribute("dojoType"));
-				node.removeAttribute("dojoType");
-			});
-			*/
-		
-			var nodes = win.body().getElementsByTagName("*");
-			var i, len, s;
-			len = nodes.length;
-			for(i = 0; i < len; i++){
-				s = nodes[i].getAttribute("dojoType");
-				if(s){
-					if(nodes[i].parentNode.getAttribute("lazy") == "true"){
-						nodes[i].setAttribute("__dojoType", s);
-						nodes[i].removeAttribute("dojoType");
-					}
-				}
-			}
-		});
+	if(has('chrome')){
+		// dojox/mobile does not load uacss (only _compat does), but we need dj_chrome.
+		domClass.add(win.doc.documentElement, "dj_chrome");
 	}
+
+	if(win.global._no_dojo_dm){
+		// deviceTheme seems to be loaded from a script tag (= non-dojo usage)
+		var _dm = win.global._no_dojo_dm;
+		for(var i in _dm){
+			dm[i] = _dm[i];
+		}
+		dm.deviceTheme.setDm(dm);
+	}
+
+	// flag for Android transition animation flicker workaround
+	has.add('mblAndroidWorkaround', 
+			config["mblAndroidWorkaround"] !== false && has('android') < 3, undefined, true);
+	has.add('mblAndroid3Workaround', 
+			config["mblAndroid3Workaround"] !== false && has('android') >= 3, undefined, true);
+
+	dm._detectWindowsTheme();
 	
 	ready(function(){
 		dm.detectScreenSize(true);
-		if(config["mblApplyPageStyles"] !== false){
-			domClass.add(win.doc.documentElement, "mobile");
+		domClass.add(win.body(), "mblBackground");
+		if(config["mblAndroidWorkaroundButtonStyle"] !== false && has('android')){
+			// workaround for the form button disappearing issue on Android 2.2-4.0
+			domConstruct.create("style", {innerHTML:"BUTTON,INPUT[type='button'],INPUT[type='submit'],INPUT[type='reset'],INPUT[type='file']::-webkit-file-upload-button{-webkit-appearance:none;} audio::-webkit-media-controls-play-button,video::-webkit-media-controls-play-button{-webkit-appearance:media-play-button;} video::-webkit-media-controls-fullscreen-button{-webkit-appearance:media-fullscreen-button;}"}, win.doc.head, "first");
 		}
-		if(has('chrome')){
-			// dojox.mobile does not load uacss (only _compat does), but we need dj_chrome.
-			domClass.add(win.doc.documentElement, "dj_chrome");
+		if(has('mblAndroidWorkaround')){
+			// add a css class to show view offscreen for android flicker workaround
+			domConstruct.create("style", {innerHTML:".mblView.mblAndroidWorkaround{position:absolute;top:-9999px !important;left:-9999px !important;}"}, win.doc.head, "last");
 		}
 
-		if(config["mblAndroidWorkaround"] !== false && has('android') >= 2.2){ // workaround for android screen flicker problem
-			if(config["mblAndroidWorkaroundButtonStyle"] !== false){
-				// workaround to avoid buttons disappear due to the side-effect of the webkitTransform workaroud below
-				domConstruct.create("style", {innerHTML:"BUTTON,INPUT[type='button'],INPUT[type='submit'],INPUT[type='reset'],INPUT[type='file']::-webkit-file-upload-button{-webkit-appearance:none;}"}, win.doc.head, "first");
-			}
-			if(has('android') < 3){ // for Android 2.2.x and 2.3.x
-				domStyle.set(win.doc.documentElement, "webkitTransform", "translate3d(0,0,0)");
-				// workaround for auto-scroll issue when focusing input fields
-				connect.connect(null, "onfocus", null, function(e){
-					domStyle.set(win.doc.documentElement, "webkitTransform", "");
-				});
-				connect.connect(null, "onblur", null, function(e){
-					domStyle.set(win.doc.documentElement, "webkitTransform", "translate3d(0,0,0)");
-				});
-			}else{ // for Android 3.x
-				if(config["mblAndroid3Workaround"] !== false){
-					domStyle.set(win.doc.documentElement, {
-						webkitBackfaceVisibility: "hidden",
-						webkitPerspective: 8000
-					});
-				}
-			}
-		}
-	
-		//	You can disable hiding the address bar with the following djConfig.
-		//	var djConfig = { mblHideAddressBar: false };
+		//	You can disable hiding the address bar with the following dojoConfig.
+		//	var dojoConfig = { mblHideAddressBar: false };
 		var f = dm.resizeAll;
 		if(config["mblHideAddressBar"] !== false &&
 			navigator.appVersion.indexOf("Mobile") != -1 ||
@@ -420,77 +321,72 @@ define([
 				f = dm.hideAddressBar;
 			}
 		}
-		connect.connect(null, (win.global.onorientationchange !== undefined && !has('android'))
-			? "onorientationchange" : "onresize", null, f);
-	
-		// avoid use of query
-		/*
-		var list = query('[__dojoType]', null);
-		list.forEach(function(node, index, nodeList){
-			node.setAttribute("dojoType", node.getAttribute("__dojoType"));
-			node.removeAttribute("__dojoType");
-		});
-		*/
-	
-		var nodes = win.body().getElementsByTagName("*");
-		var i, len = nodes.length, s;
-		for(i = 0; i < len; i++){
-			s = nodes[i].getAttribute("__dojoType");
-			if(s){
-				nodes[i].setAttribute("dojoType", s);
-				nodes[i].removeAttribute("__dojoType");
-			}
-		}
-	
-		if(dojo.hash){
-			// find widgets under root recursively
-			var findWidgets = function(root){
-				if(!root){ return []; }
-				var arr = registry.findWidgets(root);
-				var widgets = arr;
-				for(var i = 0; i < widgets.length; i++){
-					arr = arr.concat(findWidgets(widgets[i].containerNode));
+
+		var ios6 = has("ios") >= 6; // Full-screen support for iOS6 or later 
+		if((has('android') || ios6) && win.global.onorientationchange !== undefined){
+			var _f = f;
+			var curSize, curClientWidth, curClientHeight;
+			if(ios6){
+				curClientWidth = win.doc.documentElement.clientWidth;
+				curClientHeight = win.doc.documentElement.clientHeight;
+			}else{ // Android
+				// Call resize for the first resize event after orientationchange
+				// because the size information may not yet be up to date when the 
+				// event orientationchange occurs.
+				f = function(evt){
+					var _conn = connect.connect(null, "onresize", null, function(e){
+						connect.disconnect(_conn);
+						_f(e);
+					});
 				}
-				return arr;
+				curSize = dm.getScreenSize();
 			};
-			connect.subscribe("/dojo/hashchange", null, function(value){
-				var view = dm.currentView;
-				if(!view){ return; }
-				var params = dm._params;
-				if(!params){ // browser back/forward button was pressed
-					var moveTo = value ? value : dm._defaultView.id;
-					var widgets = findWidgets(view.domNode);
-					var dir = 1, transition = "slide";
-					for(i = 0; i < widgets.length; i++){
-						var w = widgets[i];
-						if("#"+moveTo == w.moveTo){
-							// found a widget that has the given moveTo
-							transition = w.transition;
-							dir = (w instanceof dm.Heading) ? -1 : 1;
-							break;
-						}
+			// Android: Watch for resize events when the virtual keyboard is shown/hidden.
+			// The heuristic to detect this is that the screen width does not change
+			// and the height changes by more than 100 pixels.
+			//
+			// iOS >= 6: Watch for resize events when entering or existing the new iOS6 
+			// full-screen mode. The heuristic to detect this is that clientWidth does not
+			// change while the clientHeight does change.
+			connect.connect(null, "onresize", null, function(e){
+				if(ios6){
+					var newClientWidth = win.doc.documentElement.clientWidth,
+						newClientHeight = win.doc.documentElement.clientHeight;
+					if(newClientWidth == curClientWidth && newClientHeight != curClientHeight){
+						// full-screen mode has been entered/exited (iOS6)
+						_f(e);
+					}
+					curClientWidth = newClientWidth;
+					curClientHeight = newClientHeight;
+				}else{ // Android
+					var newSize = dm.getScreenSize();
+					if(newSize.w == curSize.w && Math.abs(newSize.h - curSize.h) >= 100){
+						// keyboard has been shown/hidden (Android)
+						_f(e);
 					}
-					params = [ moveTo, dir, transition ];
+					curSize = newSize;
 				}
-				view.performTransition.apply(view, params);
-				dm._params = null;
 			});
 		}
-	
+		
+		connect.connect(null, win.global.onorientationchange !== undefined
+			? "onorientationchange" : "onresize", null, f);
 		win.body().style.visibility = "visible";
 	});
 
-	// To search _parentNode first.  TODO:1.8 reconsider this redefinition.
-	registry.getEnclosingWidget = function(node){
-		while(node){
-			var id = node.getAttribute && node.getAttribute("widgetId");
-			if(id){
-				return registry.byId(id);
-			}
-			node = node._parentNode || node.parentNode;
-		}
-		return null;
-	};
+	// TODO: return functions declared above in this hash, rather than
+	// dojox.mobile.
 
+	/*=====
+	return {
+		// summary:
+		//		A common module for dojox/mobile.
+		// description:
+		//		This module includes common utility functions that are used by
+		//		dojox/mobile widgets. Also, it provides functions that are commonly
+		//		necessary for mobile web applications, such as the hide address bar
+		//		function.
+	};
+	=====*/
 	return dm;
 });
diff --git a/dojox/mobile/compat.js b/dojox/mobile/compat.js
index 6d3ca38..fa1bec4 100644
--- a/dojox/mobile/compat.js
+++ b/dojox/mobile/compat.js
@@ -1,11 +1,57 @@
 define([
 	"dojo/_base/lang",
-	"dojo/_base/sniff"
+	"dojo/sniff"
 ], function(lang, has){
+	// module:
+	//		dojox/mobile/compat
+
 	var dm = lang.getObject("dojox.mobile", true);
-	if(!has("webkit")){
+	// TODO: Use feature detection instead, but this would require a major rewrite of _compat
+	// to detect each feature and plug the corresponding compat code if needed.
+	// Currently the compat code is a workaround for too many different things to be able to
+	// decide based on feature detection. So for now we just disable _compat on the mobile browsers
+	// that are known to support enough CSS3: all webkit-based browsers and IE10 (Windows [Phone] 8).
+	if(!(has("webkit") || has("ie") >= 10)){
 		var s = "dojox/mobile/_compat"; // assign to a variable so as not to be picked up by the build tool
 		require([s]);
 	}
+	
+	/*=====
+	return {
+		// summary:
+		//		CSS3 compatibility module.
+		// description:
+		//		This module provides to dojox/mobile support for some of the CSS3 features 
+		//		in non-CSS3 browsers, such as IE or Firefox.
+		//		If you require this module, when running in a non-CSS3 browser it directly 
+		//		replaces some of the methods of	dojox/mobile classes, without any subclassing. 
+		//		This way, HTML pages remain the same regardless of whether this compatibility 
+		//		module is used or not.
+		//
+		//		Example of usage: 
+		//		|	require([
+		//		|		"dojox/mobile",
+		//		|		"dojox/mobile/compat",
+		//		|		...
+		//		|	], function(...){
+		//		|		...
+		//		|	});
+		//
+		//		This module also loads compatibility CSS files, which have a -compat.css
+		//		suffix. You can use either the `<link>` tag or `@import` to load theme
+		//		CSS files. Then, this module searches for the loaded CSS files and loads
+		//		compatibility CSS files. For example, if you load dojox/mobile/themes/iphone/iphone.css
+		//		in a page, this module automatically loads dojox/mobile/themes/iphone/iphone-compat.css.
+		//		If you explicitly load iphone-compat.css with `<link>` or `@import`,
+		//		this module will not load again the already loaded file.
+		//
+		//		Note that, by default, compatibility CSS files are only loaded for CSS files located
+		//		in a directory containing a "mobile/themes" path. For that, a matching is done using 
+		//		the default pattern	"/\/mobile\/themes\/.*\.css$/". If a custom theme is not located 
+		//		in a directory containing this path, the data-dojo-config needs to specify a custom 
+		//		pattern using the "mblLoadCompatPattern" configuration parameter, for instance:
+		// |	data-dojo-config="mblLoadCompatPattern: /\/mycustomtheme\/.*\.css$/"
+	};
+	=====*/
 	return dm;
 });
diff --git a/dojox/mobile/deviceTheme.js b/dojox/mobile/deviceTheme.js
index 75d7258..ec7cd10 100644
--- a/dojox/mobile/deviceTheme.js
+++ b/dojox/mobile/deviceTheme.js
@@ -1,188 +1,292 @@
-define([
-	"dojo/_base/array",
+(typeof define === "undefined" ? function(deps, def) { def(); } : define)([
 	"dojo/_base/config",
 	"dojo/_base/lang",
 	"dojo/_base/window",
-	"dojo/dom-class",
-	"dojo/dom-construct",
 	"require"
-], function(array, config, lang, win, domClass, domConstruct, require){
-
-	var dm = lang.getObject("dojox.mobile", true);
-/*=====
-	var dm = dojox.mobile
-=====*/
+], function(config, lang, win, require){
 
 	// module:
 	//		dojox/mobile/deviceTheme
-	// summary:
-	//		Automatic Theme Loader
-	// description:
-	//		Detects the User Agent of the browser and loads appropriate theme files.
-	//		Simply dojo.require this module to enable the automatic theme loading.
-	//		For simulations, the user agent may be overridden by setting djConfig.mblUserAgent.
-	//
-	//		By default, an all-in-one theme file (e.g. themes/iphone/iphone.css) is
-	//		loaded. The all-in-one theme files contain style sheets for all the
-	//		dojox.mobile widgets regardless of whether they are used in your
-	//		application or not.
-	//		If you want to choose what theme files to load, you can specify them
-	//		via djConfig as shown in the following example:
-	//
-	//	|	djConfig="parseOnLoad:true, mblThemeFiles:['base','Button']"
-	//
-	//		Or you may want to use dojox.mobile.themeFiles as follows to get the
-	//		same result. Note that the assignment has to be done before loading
-	//		deviceTheme.js.
-	//
-	//	|	dojo.require("dojox.mobile");
-	//	|	dojox.mobile.themeFiles = ['base','Button'];
-	//	|	dojo.require("dojox.mobile.deviceTheme");
-	//
-	//		In the case of this example, if iphone is detected, for example, the
-	//		following files will be loaded:
-	//
-	//	|	dojox/mobile/themes/iphone/base.css
-	//	|	dojox/mobile/themes/iphone/Button.css
-	//
-	//		If you want to load style sheets for your own custom widgets, you can
-	//		specify a package name along with a theme file name in an array.
-	//
-	//	|	['base',['com.acme','MyWidget']]
-	//
-	//		In this case, the following files will be loaded.
-	//
-	//	|	dojox/mobile/themes/iphone/base.css
-	//	|	com/acme/themes/iphone/MyWidget.css
-	//
-	//		If you specify '@theme' as a theme file name, it will be replaced with
-	//		the theme folder name (e.g. 'iphone'). For example,
-	//
-	//	|	['@theme',['com.acme','MyWidget']]
-	//
-	//		will load the following files.
-	//
-	//	|	dojox/mobile/themes/iphone/iphone.css
-	//	|	com/acme/themes/iphone/MyWidget.css
-	//
-	//		Note that the load of the theme files is performed asynchronously by
-	//		the browser, and thus you cannot assume the load has been completed
-	//		when your appliation is initialized. For example, if some widget in
-	//		your application uses node dimensions that cannot be determined
-	//		without CSS styles being applied to them to calculate its layout at
-	//		initialization, the layout calculation may fail.
-	//		Possible workaround for this problem is to use dojo.require to load
-	//		deviceTheme.js and place it in a separate <script> block immediately
-	//		below a script tag that loads dojo.js as below. This may (or may
-	//		not) solve the problem.
-	//
-	//	|	<script src="dojo.js"></script>
-	//	|	<script>
-	//	|		dojo.require("dojox.mobile.deviceTheme");
-	//	|	</script>
-	//	|	<script>
-	//	|		dojo.require("dojox.mobile");
-	//	|		....
-	//
-	//		A better solution would be to not use deviceTheme and use <link>
-	//		or @import instead to load the theme files.
-
-
-	dm.loadCssFile = function(/*String*/file){
-		// summary:
-		//		Loads the given CSS file programmatically.
-		dm.loadedCssFiles.push(domConstruct.create("LINK", {
-			href: file,
-			type: "text/css",
-			rel: "stylesheet"
-		}, win.doc.getElementsByTagName('head')[0]));
-	};
 
-	dm.themeMap = dm.themeMap || [
-		// summary:
-		//		A map of user-agents to theme files.
-		// description:
-		//		The first array element is a regexp pattern that matches the
-		//		userAgent string.
-		//
-		//		The second array element is a theme folder name.
-		//
-		//		The third array element is an array of css file paths to load.
-		//
-		//		The matching is performed in the array order, and stops after the
-		//		first match.
-		[
-			"Android",
-			"android",
-			[]
-		],
-		[
-			"BlackBerry",
-			"blackberry",
-			[]
-		],
-		[
-			"iPad",
-			"iphone",
-			[require.toUrl("dojox/mobile/themes/iphone/ipad.css")]
-		],
-		[
-			"Custom",
-			"custom",
-			[]
-		],
-		[
-			".*",
-			"iphone",
-			[]
-		]
-	];
+	var dm = lang && lang.getObject("dojox.mobile", true) || {};
 
-	dm.loadDeviceTheme = function(/*String?*/userAgent){
+	var DeviceTheme = function(){
 		// summary:
-		//		Loads a device-specific theme according to the user-agent
-		//		string.
+		//		Automatic theme loader.
 		// description:
-		//		This function is automatically called when this module is
-		//		evaluated.
-		var t = config["mblThemeFiles"] || dm.themeFiles || ["@theme"];
-		if(!lang.isArray(t)){ console.log("loadDeviceTheme: array is expected but found: "+t); }
-		var i, j;
-		var m = dm.themeMap;
-		var ua = userAgent || config["mblUserAgent"] || (location.search.match(/theme=(\w+)/) ? RegExp.$1 : navigator.userAgent);
-		for(i = 0; i < m.length; i++){
-			if(ua.match(new RegExp(m[i][0]))){
-				var theme = m[i][1];
-				domClass.replace(win.doc.documentElement, theme + "_theme", dm.currentTheme ? dm.currentTheme + "_theme" : "");
-				dm.currentTheme = theme;
-				var files = [].concat(m[i][2]);
-				for(j = t.length - 1; j >= 0; j--){
-					var pkg = lang.isArray(t[j]) ? (t[j][0]||"").replace(/\./g, '/') : "dojox/mobile";
-					var name = lang.isArray(t[j]) ? t[j][1] : t[j];
-					var f = "themes/" + theme + "/" +
-						(name === "@theme" ? theme : name) + ".css";
-					files.unshift(require.toUrl(pkg+"/"+f));
-				}
-				//remove old css files
-				array.forEach(dm.loadedCssFiles, function(n){
-					n.parentNode.removeChild(n);
-				});
-				dm.loadedCssFiles = [];
-				for(j = 0; j < files.length; j++){
-					dm.loadCssFile(files[j].toString());
-				}
-				if(userAgent && dm.loadCompatCssFiles){ // we will assume compat is loaded and ready..
-					dm.loadCompatCssFiles();
+		//		This module detects the user agent of the browser and loads the
+		//		appropriate theme files. It can be enabled by simply including 
+		//		the dojox/mobile/deviceTheme script in your application as follows:
+		//
+		//	|	<script src="dojox/mobile/deviceTheme.js"></script>
+		//	|	<script src="dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+		//
+		//		Using the script tag as above is the recommended way to load the 
+		//		deviceTheme. Trying to load it using the AMD loader can lead to styles 
+		//		being applied too late, because the loading of the theme files would 
+		//		be performed asynchronously by the browser, so you could not assume 
+		//		that the loading has been completed when your widgets are initialized.
+		//		However, loading deviceTheme using the script tag has the drawback that 
+		//		deviceTheme.js cannot be included in a build.
+		//
+		//		You can also pass an additional query parameter string:
+		//		theme={theme id} to force a specific theme through the browser
+		//		URL input. The available theme ids are Android, Holodark (theme introduced in Android 3.0), 
+		//		BlackBerry, Custom, iPhone, and iPad. The theme names are case-sensitive. If the given
+		//		id does not match, the iPhone theme is used.
+		//
+		//	|	http://your.server.com/yourapp.html // automatic detection
+		//	|	http://your.server.com/yourapp.html?theme=Android // forces Android theme
+		//	|	http://your.server.com/yourapp.html?theme=Holodark // forces Holodark theme
+		//	|	http://your.server.com/yourapp.html?theme=BlackBerry // forces Blackberry theme
+		//	|	http://your.server.com/yourapp.html?theme=Custom // forces Custom theme
+		//	|	http://your.server.com/yourapp.html?theme=iPhone // forces iPhone theme
+		//	|	http://your.server.com/yourapp.html?theme=iPad // forces iPad theme
+		//
+		//		To simulate a particular device from the application code, the user agent
+		//		can be forced by setting dojoConfig.mblUserAgent as follows:
+		//
+		//	|	<script src="dojox/mobile/deviceTheme.js" data-dojo-config="mblUserAgent: 'Holodark'"></script>
+		//	|	<script src="dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+		//
+		//		By default, an all-in-one theme file (e.g. themes/iphone/iphone.css) is
+		//		loaded. The all-in-one theme files contain style sheets for all the
+		//		dojox/mobile widgets regardless of whether they are used in your
+		//		application or not.
+		//
+		//		If you want to choose what theme files to load, you can specify them
+		//		via dojoConfig or data-dojo-config as shown in the following example:
+		//
+		//	|	<script src="dojox/mobile/deviceTheme.js"
+		//	|		data-dojo-config="mblThemeFiles:['base','Button']"></script>
+		//	|	<script src="dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+		//
+		//		In the case of this example, if iphone is detected, for example, the
+		//		following files will be loaded:
+		//
+		//	|	dojox/mobile/themes/iphone/base.css
+		//	|	dojox/mobile/themes/iphone/Button.css
+		//
+		//		If you want to load style sheets for your own custom widgets, you can
+		//		specify a package name along with a theme file name in an array.
+		//
+		//	|	['base',['com.acme','MyWidget']]
+		//
+		//		In this case, the following files will be loaded.
+		//
+		//	|	dojox/mobile/themes/iphone/base.css
+		//	|	com/acme/themes/iphone/MyWidget.css
+		//
+		//		If you specify '@theme' as a theme file name, it will be replaced with
+		//		the theme folder name (e.g. 'iphone'). For example,
+		//
+		//	|	['@theme',['com.acme','MyWidget']]
+		//
+		//		will load the following files:
+		//
+		//	|	dojox/mobile/themes/iphone/iphone.css
+		//	|	com/acme/themes/iphone/MyWidget.css
+		
+		if(!win){
+			win = window;
+			win.doc = document;
+			win._no_dojo_dm = dm;
+		}
+		config = config || win.mblConfig || {};
+		var scripts = win.doc.getElementsByTagName("script");
+		for(var i = 0; i < scripts.length; i++){
+			var n = scripts[i];
+			var src = n.getAttribute("src") || "";
+			if(src.match(/\/deviceTheme\.js/i)){
+				config.baseUrl = src.replace("deviceTheme\.js", "../../dojo/");
+				var conf = (n.getAttribute("data-dojo-config") || n.getAttribute("djConfig"));
+				if(conf){
+					var obj = eval("({ " + conf + " })");
+					for(var key in obj){
+						config[key] = obj[key];
+					}
 				}
 				break;
+			}else if(src.match(/\/dojo\.js/i)){
+				config.baseUrl = src.replace("dojo\.js", "");
+				break;
 			}
 		}
+
+		this.loadCssFile = function(/*String*/file){
+			// summary:
+			//		Loads the given CSS file programmatically.
+			var link = win.doc.createElement("link");
+			link.href = file;
+			link.type = "text/css";
+			link.rel = "stylesheet";
+			var head = win.doc.getElementsByTagName('head')[0];
+			head.insertBefore(link, head.firstChild);
+			dm.loadedCssFiles.push(link);
+		};
+
+		this.toUrl = function(/*String*/path){
+			// summary:
+			//		A wrapper for require.toUrl to support non-dojo usage.
+			return require ? require.toUrl(path) : config.baseUrl + "../" + path;
+		};
+
+		this.setDm = function(/*Object*/_dm){
+			// summary:
+			//		Replaces the dojox/mobile object.
+			// description:
+			//		When this module is loaded from a script tag, dm is a plain
+			//		local object defined at the begining of this module.
+			//		common.js will replace the local dm object with the
+			//		real dojox/mobile object through this method.
+			dm = _dm;
+		};
+
+		this.themeMap = config.themeMap || [
+			// summary:
+			//		A map of user-agents to theme files.
+			// description:
+			//		The first array element is a regexp pattern that matches the
+			//		userAgent string.
+			//
+			//		The second array element is a theme folder name.
+			//
+			//		The third array element is an array of css file paths to load.
+			//
+			//		The matching is performed in the array order, and stops after the
+			//		first match.
+			[
+				"Holodark",
+				"holodark",
+				[]
+			],
+			[
+				"Android 3",
+				"holodark",
+				[]
+			],
+			[
+				"Android 4",
+				"holodark",
+				[]
+			],
+			[
+				"Android",
+				"android",
+				[]
+			],
+			[
+				"BlackBerry",
+				"blackberry",
+				[]
+			],
+			[
+				"BB10",
+				"blackberry",
+				[]
+			],
+			[
+				"iPhone",
+				"iphone",
+				[]
+			],
+			[
+				"iPad",
+				"iphone",
+				[this.toUrl("dojox/mobile/themes/iphone/ipad.css")]
+			],
+			[
+				"MSIE 10",
+				"windows",
+				[]
+			],
+			[
+				"WindowsPhone",
+				"windows",
+				[]
+			],
+			[
+				"Custom",
+				"custom",
+				[]
+			],
+			[
+				".*",
+				"iphone",
+				[]
+			]
+		];
+
+		dm.loadedCssFiles = [];
+		this.loadDeviceTheme = function(/*String?*/userAgent){
+			// summary:
+			//		Loads a device-specific theme according to the user-agent
+			//		string.
+			// description:
+			//		This function is automatically called when this module is
+			//		evaluated.
+			var t = config.mblThemeFiles || dm.themeFiles || ["@theme"];
+			var i, j;
+			var m = this.themeMap;
+			var ua = userAgent || config.mblUserAgent || (location.search.match(/theme=(\w+)/) ? RegExp.$1 : navigator.userAgent);
+			for(i = 0; i < m.length; i++){
+				if(ua.match(new RegExp(m[i][0]))){
+					var theme = m[i][1];
+					if(theme == "windows" && config.mblDisableWindowsTheme){
+						continue;
+					}
+					var cls = win.doc.documentElement.className;
+					cls = cls.replace(new RegExp(" *" + dm.currentTheme + "_theme"), "") + " " + theme + "_theme";
+					win.doc.documentElement.className = cls;
+					dm.currentTheme = theme;
+					var files = [].concat(m[i][2]);
+					for(j = 0; j < t.length; j++){ 
+						var isArray = (t[j] instanceof Array || typeof t[j] == "array");
+						var path;
+						if(!isArray && t[j].indexOf('/') !== -1){
+							path = t[j];
+						}else{
+							var pkg = isArray ? (t[j][0]||"").replace(/\./g, '/') : "dojox/mobile";
+							var name = (isArray ? t[j][1] : t[j]).replace(/\./g, '/');
+							var f = "themes/" + theme + "/" +
+								(name === "@theme" ? theme : name) + ".css";
+							path = pkg + "/" + f;
+						}
+						files.unshift(this.toUrl(path));
+					}
+					//remove old css files
+					for(var k = 0; k < dm.loadedCssFiles.length; k++){
+						var n = dm.loadedCssFiles[k];
+						n.parentNode.removeChild(n);
+					}
+					dm.loadedCssFiles = [];
+					for(j = 0; j < files.length; j++){
+						// dojox.mobile mirroring support
+						var cssFilePath = files[j].toString();
+						if(config["dojo-bidi"] == true && cssFilePath.indexOf("_rtl") == -1){
+							var rtlCssList = "android.css blackberry.css custom.css iphone.css holodark.css base.css Carousel.css ComboBox.css IconContainer.css IconMenu.css ListItem.css RoundRectCategory.css SpinWheel.css Switch.css TabBar.css ToggleButton.css ToolBarButton.css";
+							var cssName = cssFilePath.substr(cssFilePath.lastIndexOf('/') + 1);
+							if(rtlCssList.indexOf(cssName) != -1){
+								this.loadCssFile(cssFilePath.replace(".css","_rtl.css"));
+							}
+						}
+						this.loadCssFile(files[j].toString());
+					}
+
+					if(userAgent && dm.loadCompatCssFiles){
+						dm.loadCompatCssFiles();
+					}
+					break;
+				}
+			}
+		};
 	};
-	
-	if(dm.configDeviceTheme){
-		dm.configDeviceTheme();
-	}
-	dm.loadDeviceTheme();
 
-	return dm;
+	// Singleton.  (TODO: can we replace DeviceTheme class and singleton w/a simple hash of functions?)
+	var deviceTheme = new DeviceTheme();
+
+	deviceTheme.loadDeviceTheme();
+	window.deviceTheme = dm.deviceTheme = deviceTheme;
+
+	return deviceTheme;
 });
diff --git a/dojox/mobile/dh/ContentTypeMap.js b/dojox/mobile/dh/ContentTypeMap.js
new file mode 100644
index 0000000..45a76f7
--- /dev/null
+++ b/dojox/mobile/dh/ContentTypeMap.js
@@ -0,0 +1,33 @@
+define([
+	"dojo/_base/lang"
+], function(lang){
+
+	// module:
+	//		dojox/mobile/dh/ContentTypeMap
+
+	var o = {
+		// summary:
+		//		A component that provides a map for determining the content handler
+		//		class from a content-type.
+	};
+	lang.setObject("dojox.mobile.dh.ContentTypeMap", o);
+
+	o.map = {
+		"html": "dojox/mobile/dh/HtmlContentHandler",
+		"json": "dojox/mobile/dh/JsonContentHandler"
+	};
+
+	o.add = function(/*String*/ contentType, /*String*/ handlerClass){
+		// summary:
+		//		Adds a handler class for the given content type.
+		this.map[contentType] = handlerClass;
+	};
+
+	o.getHandlerClass = function(/*String*/ contentType){
+		// summary:
+		//		Returns the handler class for the given content type.
+		return this.map[contentType];
+	};
+
+	return o;
+});
diff --git a/dojox/mobile/dh/DataHandler.js b/dojox/mobile/dh/DataHandler.js
new file mode 100644
index 0000000..a32a385
--- /dev/null
+++ b/dojox/mobile/dh/DataHandler.js
@@ -0,0 +1,57 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/Deferred",
+	"./ContentTypeMap"
+], function(declare, lang, Deferred, ContentTypeMap){
+
+	// module:
+	//		dojox/mobile/dh/DataHandler
+
+	return declare("dojox.mobile.dh.DataHandler", null, {
+		// summary:
+		//		A component that provides an interface between data and handlers.
+		// description:
+		//		This module fetches data through DataSource and calls a
+		//		ContentHandler to parse the content data and create a new view.
+
+		// ds: Object
+		//		A DataSource instance.
+		ds: null,
+
+		// target: DomNode
+		//		A DOM node under which a new view is created.
+		target: null,
+
+		// refNode: DomNode
+		//		An optional reference DOM node before which a new view is created.
+		refNode: null,
+
+		constructor: function(/*DataSource*/ ds, /*DomNode*/ target, /*DomNode?*/ refNode){
+			// summary:
+			//		Creates a new instance of the class.
+			this.ds = ds;
+			this.target = target;
+			this.refNode = refNode;
+		},
+
+		processData: function(/*String*/ contentType, /*Function*/ callback){
+			// summary:
+			//		Fetches data through DataSource and passes it to a content
+			//		handler.
+			// contentType:
+			//		The type of the content. (ex. "html")
+			//		It is used to determine what content handler to use.
+			// callback:
+			//		A function to be called after creating a new view.
+			var ch = ContentTypeMap.getHandlerClass(contentType);
+			require([ch], lang.hitch(this, function(ContentHandler){
+				Deferred.when(this.ds.getData(), lang.hitch(this, function(){
+					Deferred.when(new ContentHandler().parse(this.ds.text, this.target, this.refNode), function(id){
+						callback(id);
+					});
+				}))
+			}));
+		}
+	});
+});
diff --git a/dojox/mobile/dh/HtmlContentHandler.js b/dojox/mobile/dh/HtmlContentHandler.js
new file mode 100644
index 0000000..a56ab9b
--- /dev/null
+++ b/dojox/mobile/dh/HtmlContentHandler.js
@@ -0,0 +1,61 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/Deferred",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dijit/registry",
+	"../lazyLoadUtils"
+], function(dojo, array, declare, Deferred, domClass, domConstruct, registry, lazyLoadUtils){
+
+	// module:
+	//		dojox/mobile/dh/HtmlContentHandler
+
+	return declare("dojox.mobile.dh.HtmlContentHandler", null, {
+		// summary:
+		//		A HTML content handler.
+		// description:
+		//		This module is a content handler that creates a view from HTML
+		//		data. If widgets used in the HTML data are not available, they
+		//		are loaded automatically before instantiation.
+
+		parse: function(/*String*/ content, /*DomNode*/ target, /*DomNode?*/ refNode){
+			// summary:
+			//		Parses the given data and creates a new view at the given position.
+			// content:
+			//		Content data for a new view.
+			// target:
+			//		A DOM node under which a new view is created.
+			// refNode:
+			//		An optional reference DOM node before which a new view is created.
+			if(this.execScript){
+				content = this.execScript(content);
+			}
+			var container = domConstruct.create("div", {
+				innerHTML: content,
+				style: {visibility: "hidden"}
+			});
+			target.insertBefore(container, refNode);
+
+			return Deferred.when(lazyLoadUtils.instantiateLazyWidgets(container), function(){
+				// allows multiple root nodes in the fragment,
+				// but transition will be performed to the 1st view.
+				var view;
+				for(i = 0, len = container.childNodes.length; i < len; i++){
+					var n = container.firstChild;
+					if(!view && n.nodeType === 1){
+						view = registry.byNode(n);
+					}
+					target.insertBefore(container.firstChild, refNode); // reparent
+				}
+				target.removeChild(container);
+				if(!view || !domClass.contains(view.domNode, "mblView")){
+					console.log("HtmlContentHandler.parse: invalid view content");
+					return null;
+				}
+				return view.id;
+			});
+		}
+	});
+});
diff --git a/dojox/mobile/dh/HtmlScriptContentHandler.js b/dojox/mobile/dh/HtmlScriptContentHandler.js
new file mode 100644
index 0000000..631934f
--- /dev/null
+++ b/dojox/mobile/dh/HtmlScriptContentHandler.js
@@ -0,0 +1,14 @@
+define([
+	"dojo/_base/declare",
+	"./HtmlContentHandler",
+	"../_ExecScriptMixin"
+], function(declare, HtmlContentHandler, _ExecScriptMixin){
+
+	// module:
+	//		dojox/mobile/dh/HtmlScriptContentHandler
+
+	return declare("dojox.mobile.dh.HtmlScriptContentHandler", [HtmlContentHandler, _ExecScriptMixin], {
+		// summary:
+		//		An HTML content handler that has script execution capability.
+	});
+});
diff --git a/dojox/mobile/dh/JsonContentHandler.js b/dojox/mobile/dh/JsonContentHandler.js
new file mode 100644
index 0000000..7336198
--- /dev/null
+++ b/dojox/mobile/dh/JsonContentHandler.js
@@ -0,0 +1,239 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/Deferred",
+	"dojo/json",
+	"dojo/dom-construct"
+], function(dojo, array, declare, lang, Deferred, json, domConstruct){
+
+	// module:
+	//		dojox/mobile/dh/JsonContentHandler
+
+	return declare("dojox.mobile.dh.JsonContentHandler", null, {
+		// summary:
+		//		A JSON content handler.
+		// description:
+		//		This module is a content handler that creates a view from JSON
+		//		data. If widgets used in the JSON data are not available, they
+		//		are loaded automatically before instantiation.
+		//
+		//		There are two formats as shown in the examples below. You can
+		//		choose either of them. The v1.7 format can be more compact, but
+		//		if you want multiple widgets at the same level, they must be in
+		//		an array. So, you can have, for example, two consecutive
+		//		RoundRectLists, but you cannot have, for example,
+		//		RoundRectCategory, RoundRectList, RoundRectCategory, and
+		//		RoundRectList, because they are keys in one JS object, which
+		//		causes conflict. The v1.8 format has no such limitation.
+		//
+		// example:
+		// 	|	// v1.7 format
+		//	|	{
+		//	|	  "dojox.mobile.View": {
+		//	|	    "@id": "view1",
+		//	|	    "dojox.mobile.Heading": {
+		//	|	      "@back": "Home",
+		//	|	      "@moveTo": "home",
+		//	|	      "@label": "view1.json"
+		//	|	    },
+		//	|	    "dojox.mobile.EdgeToEdgeList": {
+		//	|	      "dojox.mobile.ListItem": [{
+		//	|	        "@label": "Jack Coleman"
+		//	|	      }, {
+		//	|	        "@label": "James Evans"
+		//	|	      }, {
+		//	|	        "@label": "Jason Griffin"
+		//	|	      }]
+		//	|	    }
+		//	|	  }
+		//	|	}
+		//	|	
+		// example:
+		//	|	// v1.8 format
+		//	|	{
+		//	|	  "class": "dojox.mobile.View",
+		//	|	  "@id": "view1",
+		//	|	  "children": [
+		//	|	
+		//	|	    {
+		//	|	      "class": "dojox.mobile.Heading",
+		//	|	      "@back": "Home",
+		//	|	      "@moveTo": "home",
+		//	|	      "@label": "view1.json"
+		//	|	    },
+		//	|	
+		//	|	    {
+		//	|	      "class": "dojox.mobile.EdgeToEdgeList",
+		//	|	      "children": [
+		//	|	        {
+		//	|	          "class": "dojox.mobile.ListItem",
+		//	|	          "@label": "Jack Coleman"
+		//	|	        },
+		//	|	        {
+		//	|	          "class": "dojox.mobile.ListItem",
+		//	|	          "@label": "James Evans"
+		//	|	        },
+		//	|	        {
+		//	|	          "class": "dojox.mobile.ListItem",
+		//	|	          "@label": "Jason Griffin"
+		//	|	        }
+		//	|	      ]
+		//	|	    }
+		//	|	
+		//	|	  ]
+		//	|	}
+		//	|	
+		// example:
+		//	|	// SpinWheel in v1.8 format
+		//	|	{
+		//	|	  "class": "dojox.mobile.View",
+		//	|	  "@id": "view1",
+		//	|	  "children": [
+		//	|	    {
+		//	|	      "class": "dojox.mobile.SpinWheel",
+		//	|	      "@id": "spin1",
+		//	|	      "@style": {"margin":"10px auto","width":"304px"},
+		//	|	      "children": [
+		//	|	        {
+		//	|	          "class": "dojox.mobile.SpinWheelSlot",
+		//	|	          "@labels": "A,B,C,D,E",
+		//	|	          "@style": {"textAlign":"center","width":"300px"}
+		//	|	        }
+		//	|	      ]
+		//	|	    }
+		//	|	  ]
+		//	|	}
+
+		parse: function(/*Object*/ content, /*DomNode*/ target, /*DomNode?*/ refNode){
+			// summary:
+			//		Parses the given data and creates a new view at the given position.
+			// content:
+			//		Content data for a new view.
+			// target:
+			//		A DOM node under which a new view is created.
+			// refNode:
+			//		An optional reference DOM node before which a new view is created.
+			var view, container = domConstruct.create("DIV");
+			target.insertBefore(container, refNode);
+			this._ws = [];
+			this._req = [];
+			var root = json.parse(content);
+			return Deferred.when(this._loadPrereqs(root), lang.hitch(this, function(){
+				view = this._instantiate(root, container);
+				view.style.visibility = "hidden";
+				array.forEach(this._ws, function(w){
+					if(!w._started && w.startup){
+						w.startup();
+					}
+				});
+				this._ws = null;
+				return view.id;
+			}));
+		},
+
+		_loadPrereqs: function(root){
+			// tags:
+			//		private
+			var d = new Deferred();
+			var req = this._collectRequires(root);
+			if(req.length === 0){ return true; }
+
+			if(dojo.require){
+				array.forEach(req, function(c){
+					dojo["require"](c);
+				});
+				return true;
+			}else{
+				req = array.map(req, function(s){ return s.replace(/\./g, "/"); });
+				require(req, function(){
+					d.resolve(true);
+				});
+			}
+			return d;
+		},
+
+		_collectRequires: function(obj){
+			// tags:
+			//		private
+			var className = obj["class"];
+			for(var key in obj){
+				if(key.charAt(0) == "@" || key === "children"){ continue; }
+				var cls = className || key.replace(/:.*/, "");
+				this._req.push(cls);
+				if(!cls){ continue; }
+				var objs = className ? [obj] :
+						(lang.isArray(obj[key]) ? obj[key] : [obj[key]]);
+				for(var i = 0; i < objs.length; i++){
+					// process child widgets
+					if(!className){
+						this._collectRequires(objs[i]);
+					}else if(objs[i].children){
+						for(var j = 0; j < objs[i].children.length; j++){
+							this._collectRequires(objs[i].children[j]);
+						}
+					}
+				}
+			}
+			return this._req;
+		},
+
+		_instantiate: function(/*Object*/obj, /*DomNode*/node, /*Widget*/parent){
+			// summary:
+			//		Given the evaluated json data, does the same thing as what
+			//		the parser does.
+			// tags:
+			//		private
+			var widget;
+			var className = obj["class"];
+			for(var key in obj){
+				if(key.charAt(0) == "@" || key === "children"){ continue; }
+				var cls = lang.getObject(className || key.replace(/:.*/, ""));
+				if(!cls){ continue; }
+				var proto = cls.prototype,
+					objs = className ? [obj] :
+						(lang.isArray(obj[key]) ? obj[key] : [obj[key]]);
+				for(var i = 0; i < objs.length; i++){
+					var params = {};
+					for(var prop in objs[i]){
+						if(prop.charAt(0) == "@"){
+							var v = objs[i][prop];
+							prop = prop.substring(1);
+							var t = typeof proto[prop];
+							if(lang.isArray(proto[prop])){
+								params[prop] = v.split(/\s*,\s*/);
+							}else if(t === "string"){
+								params[prop] = v;
+							}else if(t === "number"){
+								params[prop] = v - 0;
+							}else if(t === "boolean"){
+								params[prop] = (v !== "false");
+							}else if(t === "object"){
+								params[prop] = json.parse(v);
+							}else if(t === "function"){
+								params[prop] = lang.getObject(v, false) || new Function(v);
+							}
+						}
+					}
+					widget = new cls(params, node);
+					if(node){ // to call View's startup()
+						this._ws.push(widget);
+					}
+					if(parent){
+						widget.placeAt(parent.containerNode || parent.domNode);
+					}
+					// process child widgets
+					if(!className){
+						this._instantiate(objs[i], null, widget);
+					}else if(objs[i].children){
+						for(var j = 0; j < objs[i].children.length; j++){
+							this._instantiate(objs[i].children[j], null, widget);
+						}
+					}
+				}
+			}
+			return widget && widget.domNode;
+		}
+	});
+});
diff --git a/dojox/mobile/dh/PatternFileTypeMap.js b/dojox/mobile/dh/PatternFileTypeMap.js
new file mode 100644
index 0000000..dfb96fd
--- /dev/null
+++ b/dojox/mobile/dh/PatternFileTypeMap.js
@@ -0,0 +1,38 @@
+define([
+	"dojo/_base/lang"
+], function(lang){
+
+	// module:
+	//		dojox/mobile/dh/PatternFileTypeMap
+
+	var o = {
+		// summary:
+		//		A component that provides a map for determining content-type from
+		//		the pattern of the URL.
+	};
+	lang.setObject("dojox.mobile.dh.PatternFileTypeMap", o);
+
+	o.map = {
+		".*\.html": "html",
+		".*\.json": "json"
+	};
+
+	o.add = function(/*String*/ key, /*String*/ contentType){
+		// summary:
+		//		Adds a handler class for the given content type.		
+		this.map[key] = contentType;
+	};
+
+	o.getContentType = function(/*String*/ fileName){
+		// summary:
+		//		Returns the handler class for the given content type.		
+		for(var key in this.map){
+			if((new RegExp(key)).test(fileName)){
+				return this.map[key];
+			}
+		}
+		return null;
+	};
+
+	return o;
+});
diff --git a/dojox/mobile/dh/StringDataSource.js b/dojox/mobile/dh/StringDataSource.js
new file mode 100644
index 0000000..9038712
--- /dev/null
+++ b/dojox/mobile/dh/StringDataSource.js
@@ -0,0 +1,26 @@
+define([
+	"dojo/_base/declare"
+], function(declare){
+
+	// module:
+	//		dojox/mobile/dh/StringDataSource
+
+	return declare("dojox.mobile.dh.StringDataSource", null, {
+		// summary:
+		//		A component that simply returns the given text.
+
+		text: "",
+
+		constructor: function(/*String*/ text){
+			// summary:
+			//		Creates a new instance of the class.
+			this.text = text;
+		},
+
+		getData: function(){
+			// summary:
+			//		Returns the given text.			
+			return this.text;
+		}
+	});
+});
diff --git a/dojox/mobile/dh/SuffixFileTypeMap.js b/dojox/mobile/dh/SuffixFileTypeMap.js
new file mode 100644
index 0000000..9b20f9e
--- /dev/null
+++ b/dojox/mobile/dh/SuffixFileTypeMap.js
@@ -0,0 +1,34 @@
+define([
+	"dojo/_base/lang"
+], function(lang){
+
+	// module:
+	//		dojox/mobile/dh/SuffixFileTypeMap
+
+	var o = {
+		// summary:
+		//		A component that provides a map for determining content-type from
+		//		the suffix of the URL.
+	};
+	lang.setObject("dojox.mobile.dh.SuffixFileTypeMap", o);
+
+	o.map = {
+		"html": "html",
+		"json": "json"
+	};
+
+	o.add = function(/*String*/ key, /*String*/ contentType){
+		// summary:
+		//		Adds a handler class for the given content type.
+		this.map[key] = contentType;
+	};
+
+	o.getContentType = function(/*String*/ fileName){
+		// summary:
+		//		Returns the handler class for the given content type.		
+		var fileType = (fileName || "").replace(/.*\./, "");
+		return this.map[fileType];
+	};
+
+	return o;
+});
diff --git a/dojox/mobile/dh/UrlDataSource.js b/dojox/mobile/dh/UrlDataSource.js
new file mode 100644
index 0000000..8321d40
--- /dev/null
+++ b/dojox/mobile/dh/UrlDataSource.js
@@ -0,0 +1,40 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/xhr"
+], function(declare, lang, xhr){
+
+	// module:
+	//		dojox/mobile/dh/UrlDataSource
+
+	return declare("dojox.mobile.dh.UrlDataSource", null, {
+		// summary:
+		//		A component that accesses the given URL and fetches the data as text.
+
+		text: "",
+
+		_url: "",
+
+		constructor: function(/*String*/ url){
+			// summary:
+			//		Creates a new instance of the class.
+			this._url = url;
+		},
+
+		getData: function(){
+			// summary:
+			//		Returns a Deferred that accesses the given URL and fetches the data as text.
+			var obj = xhr.get({
+				url: this._url,
+				handleAs: "text"
+			});
+			obj.addCallback(lang.hitch(this, function(response, ioArgs){
+				this.text = response;
+			}));
+			obj.addErrback(function(error){
+				console.log("Failed to load "+this._url+"\n"+(error.description||error));
+			});
+			return obj; // Deferred
+		}
+	});
+});
diff --git a/dojox/mobile/i18n.js b/dojox/mobile/i18n.js
index ae7ca52..2791960 100644
--- a/dojox/mobile/i18n.js
+++ b/dojox/mobile/i18n.js
@@ -4,38 +4,46 @@ define([
 	"dijit/_WidgetBase"
 ], function(lang, di18n, WidgetBase){
 
-/*=====
-	var WidgetBase = dijit._WidgetBase;
-=====*/
-
 	// module:
 	//		dojox/mobile/i18n
-	// summary:
-	//		An internationalization utility for dojox.mobile-based user
-	//		applications.
 
-	var i18n = lang.getObject("dojox.mobile.i18n", true);
-/*=====
-	var i18n = dojox.mobile.i18n;
-=====*/
+	var i18n = {
+		// summary:
+		//		An internationalization utility for applications based on dojox/mobile.
+	};
+	lang.setObject("dojox.mobile.i18n", i18n);
 
 	i18n.load = function(/*String*/packageName, /*String*/bundleName, /*String?*/locale){
 		// summary:
-		//		Loads an nls resouce bundle and returns an array of localized
+		//		Loads an nls resource bundle and returns an array of localized
 		//		resources.
 		return i18n.registerBundle(di18n.getLocalization(packageName, bundleName, locale));
 	};
 
 	i18n.registerBundle = function(/*Array*/bundle){
 		// summary:
-		//		Accumulates the given localized resouces in an array and returns
+		//		Accumulates the given localized resources in an array and returns
 		//		it.
 		if(!i18n.bundle){ i18n.bundle = []; }
 		return lang.mixin(i18n.bundle, bundle);
 	};
 
+	i18n.I18NProperties = {
+		// summary:
+		//		These properties can be specified for any widget once the dojox/mobile/i18n module is loaded.
+
+		// mblNoConv: Boolean
+		//		Disables localization by dojox/mobile/i18n for the widget on which the property is set.
+		mblNoConv: false
+	};
+
+	// Since any widget can have properties localized by dojox/mobile/i18n, mix I18NProperties
+	// into the base widget class.  (This is a hack, but it's effective.)
+	// This is for the benefit of the parser.   Remove for 2.0.  Also, hide from doc viewer.
+	lang.extend(WidgetBase, /*===== {} || =====*/ i18n.I18NProperties);
+
+	// Mixin the _cv method which is called by property setters.
 	lang.extend(WidgetBase, {
-		mblNoConv: false,
 		_cv: function(s){
 			if(this.mblNoConv || !i18n.bundle){ return s; }
 			return i18n.bundle[lang.trim(s)] || s;
diff --git a/dojox/mobile/iconUtils.js b/dojox/mobile/iconUtils.js
new file mode 100644
index 0000000..b997daf
--- /dev/null
+++ b/dojox/mobile/iconUtils.js
@@ -0,0 +1,240 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/config",
+	"dojo/_base/connect",
+	"dojo/_base/event",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"./sniff"
+], function(array, config, connect, event, lang, win, domClass, domConstruct, domStyle, has){
+
+	var dm = lang.getObject("dojox.mobile", true);
+
+	// module:
+	//		dojox/mobile/iconUtils
+
+	var IconUtils = function(){
+		// summary:
+		//		Utilities to create an icon (image, CSS sprite image, or DOM Button).
+
+		this.setupSpriteIcon = function(/*DomNode*/iconNode, /*String*/iconPos){
+			// summary:
+			//		Sets up CSS sprite for a foreground image.
+			if(iconNode && iconPos){
+				var arr = array.map(iconPos.split(/[ ,]/),function(item){return item-0});
+				var t = arr[0]; // top
+				var r = arr[1] + arr[2]; // right
+				var b = arr[0] + arr[3]; // bottom
+				var l = arr[1]; // left
+				domStyle.set(iconNode, {
+					position: "absolute",
+					clip: "rect("+t+"px "+r+"px "+b+"px "+l+"px)",
+					top: (iconNode.parentNode ? domStyle.get(iconNode, "top") : 0) - t + "px",
+					left: -l + "px"
+				});
+				domClass.add(iconNode, "mblSpriteIcon");
+			}
+		};
+
+		this.createDomButton = function(/*DomNode*/refNode, /*Object?*/style, /*DomNode?*/toNode){
+			// summary:
+			//		Creates a DOM button.
+			// description:
+			//		DOM button is a simple graphical object that consists of one or
+			//		more nested DIV elements with some CSS styling. It can be used
+			//		in place of an icon image on ListItem, IconItem, and so on.
+			//		The kind of DOM button to create is given as a class name of
+			//		refNode. The number of DIVs to create is searched from the style
+			//		sheets in the page. However, if the class name has a suffix that
+			//		starts with an underscore, like mblDomButtonGoldStar_5, then the
+			//		suffixed number is used instead. A class name for DOM button
+			//		must starts with 'mblDomButton'.
+			// refNode:
+			//		A node that has a DOM button class name.
+			// style:
+			//		A hash object to set styles to the node.
+			// toNode:
+			//		A root node to create a DOM button. If omitted, refNode is used.
+
+			if(!this._domButtons){
+				if(has("webkit")){
+					var findDomButtons = function(sheet, dic){
+						// summary:
+						//		Searches the style sheets for DOM buttons.
+						// description:
+						//		Returns a key-value pair object whose keys are DOM
+						//		button class names and values are the number of DOM
+						//		elements they need.
+						var i, j;
+						if(!sheet){
+							var _dic = {};
+							var ss = win.doc.styleSheets;
+							for (i = 0; i < ss.length; i++){
+								ss[i] && findDomButtons(ss[i], _dic);
+							}
+							return _dic;
+						}
+						var rules = sheet.cssRules || [];
+						for (i = 0; i < rules.length; i++){
+							var rule = rules[i];
+							if(rule.href && rule.styleSheet){
+								findDomButtons(rule.styleSheet, dic);
+							}else if(rule.selectorText){
+								var sels = rule.selectorText.split(/,/);
+								for (j = 0; j < sels.length; j++){
+									var sel = sels[j];
+									var n = sel.split(/>/).length - 1;
+									if(sel.match(/(mblDomButton\w+)/)){
+										var cls = RegExp.$1;
+										if(!dic[cls] || n > dic[cls]){
+											dic[cls] = n;
+										}
+									}
+								}
+							}
+						}
+						return dic;
+					}
+					this._domButtons = findDomButtons();
+				}else{
+					this._domButtons = {};
+				}
+			}
+
+			var s = refNode.className;
+			var node = toNode || refNode;
+			if(s.match(/(mblDomButton\w+)/) && s.indexOf("/") === -1){
+				var btnClass = RegExp.$1;
+				var nDiv = 4;
+				if(s.match(/(mblDomButton\w+_(\d+))/)){
+					nDiv = RegExp.$2 - 0;
+				}else if(this._domButtons[btnClass] !== undefined){
+					nDiv = this._domButtons[btnClass];
+				}
+				var props = null;
+				if(has("bb") && config["mblBBBoxShadowWorkaround"] !== false){
+					// Removes box-shadow because BlackBerry incorrectly renders it.
+					props = {style:"-webkit-box-shadow:none"};
+				}
+				for(var i = 0, p = node; i < nDiv; i++){
+					p = p.firstChild || domConstruct.create("div", props, p);
+				}
+				if(toNode){
+					setTimeout(function(){
+						domClass.remove(refNode, btnClass);
+					}, 0);
+					domClass.add(toNode, btnClass);
+				}
+			}else if(s.indexOf(".") !== -1){ // file name
+				domConstruct.create("img", {src:s}, node);
+			}else{
+				return null;
+			}
+			domClass.add(node, "mblDomButton");
+			!!style && domStyle.set(node, style);
+			return node;
+		};
+
+		this.createIcon = function(/*String*/icon, /*String?*/iconPos, /*DomNode?*/node, /*String?*/title, /*DomNode?*/parent, /*DomNode?*/refNode, /*String?*/pos){
+			// summary:
+			//		Creates or updates an icon node
+			// description:
+			//		If node exists, updates the existing node. Otherwise, creates a new one.
+			// icon:
+			//		Path for an image, or DOM button class name.
+			title = title || "";
+			if(icon && icon.indexOf("mblDomButton") === 0){
+				// DOM button
+				if(!node){
+					node = domConstruct.create("div", null, refNode || parent, pos);
+				}else{
+					if(node.className.match(/(mblDomButton\w+)/)){
+						domClass.remove(node, RegExp.$1);
+					}
+				}
+				node.title = title;
+				domClass.add(node, icon);
+				this.createDomButton(node);
+			}else if(icon && icon !== "none"){
+				// Image
+				if(!node || node.nodeName !== "IMG"){
+					node = domConstruct.create("img", {
+						alt: title
+					}, refNode || parent, pos);
+				}
+				node.src = (icon || "").replace("${theme}", dm.currentTheme);
+				this.setupSpriteIcon(node, iconPos);
+				if(iconPos && parent){
+					var arr = iconPos.split(/[ ,]/);
+					domStyle.set(parent, {
+						position: "relative",
+						width: arr[2] + "px",
+						height: arr[3] + "px"
+					});
+					domClass.add(parent, "mblSpriteIconParent");
+				}
+				connect.connect(node, "ondragstart", event, "stop");
+			}
+			return node;
+		};
+
+		this.iconWrapper = false;
+		this.setIcon = function(/*String*/icon, /*String*/iconPos, /*DomNode*/iconNode, /*String?*/alt, /*DomNode*/parent, /*DomNode?*/refNode, /*String?*/pos){
+			// summary:
+			//		A setter function to set an icon.
+			// description:
+			//		This function is intended to be used by icon setters (e.g. _setIconAttr)
+			// icon:
+			//		An icon path or a DOM button class name.
+			// iconPos:
+			//		The position of an aggregated icon. IconPos is comma separated
+			//		values like top,left,width,height (ex. "0,0,29,29").
+			// iconNode:
+			//		An icon node.
+			// alt:
+			//		An alt text for the icon image.
+			// parent:
+			//		Parent node of the icon.
+			// refNode:
+			//		A node reference to place the icon.
+			// pos:
+			//		The position of the icon relative to refNode.
+			if(!parent || !icon && !iconNode){ return null; }
+			if(icon && icon !== "none"){ // create or update an icon
+				if(!this.iconWrapper && icon.indexOf("mblDomButton") !== 0 && !iconPos){ // image
+					if(iconNode && iconNode.tagName === "DIV"){
+						domConstruct.destroy(iconNode);
+						iconNode = null;
+					}
+					iconNode = this.createIcon(icon, null, iconNode, alt, parent, refNode, pos);
+					domClass.add(iconNode, "mblImageIcon");
+				}else{ // sprite or DOM button
+					if(iconNode && iconNode.tagName === "IMG"){
+						domConstruct.destroy(iconNode);
+						iconNode = null;
+					}
+					iconNode && domConstruct.empty(iconNode);
+					if(!iconNode){
+						iconNode = domConstruct.create("div", null, refNode || parent, pos);
+					}
+					this.createIcon(icon, iconPos, null, null, iconNode);
+					if(alt){
+						iconNode.title = alt;
+					}
+				}
+				domClass.remove(parent, "mblNoIcon");
+				return iconNode;
+			}else{ // clear the icon
+				domConstruct.destroy(iconNode);
+				domClass.add(parent, "mblNoIcon");
+				return null;
+			}
+		};
+	};
+
+	// Return singleton.  (TODO: can we replace IconUtils class and singleton w/a simple hash of functions?)
+	return new IconUtils();
+});
diff --git a/dojox/mobile/lazyLoadUtils.js b/dojox/mobile/lazyLoadUtils.js
new file mode 100644
index 0000000..6b085c4
--- /dev/null
+++ b/dojox/mobile/lazyLoadUtils.js
@@ -0,0 +1,96 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/config",
+	"dojo/_base/window",
+	"dojo/_base/Deferred",
+	"dojo/ready"
+], function(dojo, array, config, win, Deferred, ready){
+
+	// module:
+	//		dojox/mobile/lazyLoadUtils
+
+	var LazyLoadUtils = function(){
+		// summary:
+		//		Utilities to lazy-loading of Dojo widgets.
+
+		this._lazyNodes = [];
+		var _this = this;
+		if(config.parseOnLoad){
+			ready(90, function(){
+				var lazyNodes = array.filter(win.body().getElementsByTagName("*"), // avoid use of dojo.query
+					function(n){ return n.getAttribute("lazy") === "true" || (n.getAttribute("data-dojo-props")||"").match(/lazy\s*:\s*true/); });
+				var i, j, nodes, s, n;
+				for(i = 0; i < lazyNodes.length; i++){
+					array.forEach(["dojoType", "data-dojo-type"], function(a){
+						nodes = array.filter(lazyNodes[i].getElementsByTagName("*"),
+											function(n){ return n.getAttribute(a); });
+						for(j = 0; j < nodes.length; j++){
+							n = nodes[j];
+							n.setAttribute("__" + a, n.getAttribute(a));
+							n.removeAttribute(a);
+							_this._lazyNodes.push(n);
+						}
+					});
+				}
+			});
+		}
+
+		ready(function(){
+			for(var i = 0; i < _this._lazyNodes.length; i++){ /* 1.8 */
+				var n = _this._lazyNodes[i];
+				array.forEach(["dojoType", "data-dojo-type"], function(a){
+					if(n.getAttribute("__" + a)){
+						n.setAttribute(a, n.getAttribute("__" + a));
+						n.removeAttribute("__" + a);
+					}
+				});
+			}
+			delete _this._lazyNodes;
+
+		});
+
+		this.instantiateLazyWidgets = function(root, requires, callback){
+			// summary:
+			//		Instantiates dojo widgets under the root node.
+			// description:
+			//		Finds DOM nodes that have the dojoType or data-dojo-type attributes,
+			//		requires the found Dojo modules, and runs the parser.
+			var d = new Deferred();
+			var req = requires ? requires.split(/,/) : [];
+			var nodes = root.getElementsByTagName("*"); // avoid use of dojo.query
+			var len = nodes.length;
+			for(var i = 0; i < len; i++){
+				var s = nodes[i].getAttribute("dojoType") || nodes[i].getAttribute("data-dojo-type");
+				if(s){
+					req.push(s);
+					var m = nodes[i].getAttribute("data-dojo-mixins"),
+						mixins = m ? m.split(/, */) : [];
+					req = req.concat(mixins);
+				}
+			}
+			if(req.length === 0){ return true; }
+
+			if(dojo.require){
+				array.forEach(req, function(c){
+					dojo["require"](c);
+				});
+				dojo.parser.parse(root);
+				if(callback){ callback(root); }
+				return true;
+			}else{
+				req = array.map(req, function(s){ return s.replace(/\./g, "/"); });
+				require(req, function(){
+					dojo.parser.parse(root);
+					if(callback){ callback(root); }
+					d.resolve(true);
+				});
+			}
+			return d;
+		}	
+	};
+
+	// Return singleton.  (TODO: can we replace LazyLoadUtils class and singleton w/a simple hash of functions?)
+	return new LazyLoadUtils();
+});
+
diff --git a/dojox/mobile/migrationAssist.js b/dojox/mobile/migrationAssist.js
new file mode 100644
index 0000000..873ad31
--- /dev/null
+++ b/dojox/mobile/migrationAssist.js
@@ -0,0 +1,429 @@
+/*
+
+About migrationAssist
+=====================
+
+The migrationAssist is a Dojo module that helps you migrate your
+dojox/mobile 1.6/1.7 applications to 1.8. To enable migrationAssist,
+all you need to do is require this module as shown in the examples below.
+
+	<script language="JavaScript" type="text/javascript">
+		dojo.require("dojox.mobile.migrationAssist");
+		dojo.require("dojox.mobile"); // This is a mobile app.
+		....
+	</script>
+
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"dojox/mobile/migrationAssist",
+			"dojox/mobile", // This is a mobile app.
+			....
+		]);
+	</script>
+
+If your application uses deprecated or no longer available functions,
+this module detects them and displays messages in the browser console.
+
+Also, it tries to dynamically fix them as much as possible so that
+the target application can work somehow.
+
+Note, however, that the purpose of migrationAssist is not to
+run the older applications as they are, but to assist migration.
+
+
+Changes from 1.6/1.7 to 1.8
+===========================
+
+Carousel
+--------
+ - Carousel has no backward compatibility, since it was experimental in 1.7.
+   There are two subclasses that support data stores.
+   Use DataCarousel if you want to use carousel with dojo/data.
+   Use StoreCarousel if you want to use carousel with dojo/store.
+
+FixedSplitter
+-------------
+ - FixedSplitter.css is no longer in the themes/common folder.
+   It is in the device theme folder. (e.g. themes/iphone/FixedSplitter.css)
+
+FlippableView
+-------------
+ - FlippableView was deprecated in 1.7, and removed in 1.8. Use SwapView instead.
+
+ListItem
+--------
+ - The sync property is no longer supported. It always behaves asynchronously.
+ - The btnClass property is no longer supported. Use rightIcon instead.
+ - The btnClass2 property is no longer supported. Use rightIcon2 instead.
+
+SpinWheel
+---------
+ - SpinWheel.css is no longer in the themes/common folder.
+   It is in the device theme folder. (e.g. themes/iphone/SpinWheel.css)
+ - getValue() is no longer supported. Use get("values") instead.
+ - setValue() is no longer supported. Use set("values", newValue) instead.
+
+SpinWheelSlot
+-------------
+ - getValue() is no longer supported. Use get("value") instead.
+ - getKey() is no longer supported. Use get("key") instead.
+ - setValue() is no longer supported. Use set("value", newValue) instead.
+
+Switch
+------
+ - When you place it in a ListItem, class="mblItemSwitch" is no longer necessary.
+
+TabBar
+------
+- In 1.7 or older, barType="segmentedControl" produced different UIs according to the
+  current theme. In the iphone theme, it was a segmented control, but in other themes,
+  it was tabs with or without icons. In 1.8, however, barType="segmentedControl"
+  always produces a segmented control UI regardless of the current theme.
+  If you still need the old behavior,
+      barType:{"iphone_theme":"segmentedControl","*":"tallTab"}
+  should produce a segmented control for the iphone theme, and a tall tab bar for
+  the other themes. You need to use deviceTheme.js to specify barType that way.
+  Also, if you want to hide the tab icons on the segmented control in the iphone theme,
+  you could apply a css like this:
+      <style>
+      .iphone_theme .mblTabBarSegmentedControl .mblTabBarButtonIconArea {
+          display: none;
+      }
+      </style>
+  See test_ScrollableView-demo.html for an example usage.
+
+TabBarButton
+-------------
+ - Specifying a DOM Button with the class attribute like class="mblDomButtonWhitePlus"
+   is no longer supported. Use icon="mblDomButtonWhitePlus" instead.
+ - select() and deselect() are no longer supported. Use set("selected", boolean) instead.
+
+ToolBarButton
+-------------
+ - Specifying the button color style with the class attribute like class="mblColorBlue"
+   is no longer supported. Use defaultColor="mblColorBlue" instead.
+ - Specifying a DOM Button with the class attribute like class="mblDomButtonWhitePlus"
+   is no longer supported. Use icon="mblDomButtonWhitePlus" instead.
+ - select() and deselect() are no longer supported. Use set("selected", boolean) instead.
+
+dojox/mobile/parser
+-------------------
+ - dojox/mobile/parser no longer accepts array-type attribute like
+     labels="['A','B','C','D','E']"
+   Instead, you should specify like labels="A,B,C,D,E", which is the format dojo/parser
+   accepts.
+
+bookmarkable
+------------
+ - To enable the bookmarkable feature, require dojox/mobile/bookmarkable
+   instead of dojo/hash
+
+*/
+
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/window",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"dojo/ready",
+	"dijit/_Container",
+	"dijit/_WidgetBase",
+	"./_ItemBase",
+	"./common", 
+	"./FixedSplitterPane",
+	"./Heading",
+	"./iconUtils",
+	"./ListItem",
+	"./RoundRect",
+	"./SpinWheel",
+	"./SpinWheelSlot",
+	"./SwapView",
+	"./TabBarButton",
+	"./ToolBarButton",
+	"./View"
+], function(declare, lang, win, domClass, domConstruct, domStyle, ready, Container, WidgetBase, _ItemBase, mobile, FixedSplitterPane, Heading, iconUtils, ListItem, RoundRect, SpinWheel, SpinWheelSlot, SwapView, TabBarButton, ToolBarButton, View){
+
+	// module:
+	//		dojox/mobile/migrationAssist
+
+	var currentTheme;
+
+	var MigrationAssist = function(){
+		// summary:
+		//		Dojo Mobile 1.6/1.7 to 1.8 migration assistance.
+
+		var get = function(w, key){
+			return w[key] || w.srcNodeRef && w.srcNodeRef.getAttribute(key);
+		};
+
+		this.dispatch = function(/*String*/cls, /*Widget*/ w){
+			var base = cls.replace(/.*\./, "");
+			this["check" + base] && this["check" + base](w);
+		};
+
+		this.checkCarousel = function(/*Widget*/ w){
+			console.log('[MIG:error] Carousel has no backward compatibility, since it was experimental in 1.7. The new Carousel supports dojo/store instead of dojo/data.');
+		};
+
+		this.checkFixedSplitter = function(/*Widget*/ w){
+			// FixedSplitter.css has been moved from the themes/common folder
+			// to the device theme folder such as themes/android.
+			if(!this._fixedSplitter_css_checked){
+				this._fixedSplitter_css_checked = true;
+				var dummy = domConstruct.create("div", {
+					className: "mblFixedSplitter"
+				}, win.body());
+				if(domStyle.get(dummy, "height") == 0){
+					domConstruct.create("link", {
+						href: "../themes/android/FixedSplitter.css",
+						type: "text/css",
+						rel: "stylesheet"
+					}, win.doc.getElementsByTagName('head')[0]);
+					console.log('[MIG:fixed] FixedSplitter.css does not seem to be loaded. Loaded it for you just now. It is in the device theme folder.');
+				}
+				win.body().removeChild(dummy);
+				setTimeout(function(){
+					w.resize();
+				}, 1000);
+			}
+		};
+
+		this.checkFixedSplitterPane = function(/*Widget*/ w){
+			console.log('[MIG:fixed] FixedSplitterPane: Deprecated. Use dojox/mobile/Container instead.');
+		};
+		this.checkFixedSplitter = function(/*Widget*/ w){
+			// FixedSplitter.css has been moved from the themes/common folder
+			// to the device theme folder such as themes/android.
+			if(!this._fixedSplitter_css_checked){
+				this._fixedSplitter_css_checked = true;
+				var dummy = domConstruct.create("div", {
+					className: "mblFixedSplitter"
+				}, win.body());
+				if(domStyle.get(dummy, "height") == 0){
+					domConstruct.create("link", {
+						href: "../themes/android/FixedSplitter.css",
+						type: "text/css",
+						rel: "stylesheet"
+					}, win.doc.getElementsByTagName('head')[0]);
+					console.log('[MIG:fixed] FixedSplitter.css does not seem to be loaded. Loaded it for you just now. It is in the device theme folder.');
+				}
+				win.body().removeChild(dummy);
+				setTimeout(function(){
+					w.resize();
+				}, 1000);
+			}
+		};
+
+		this.checkListItem = function(/*Widget*/ w){
+			if(w.sync !== undefined || w.srcNodeRef && w.srcNodeRef.getAttribute("sync")){
+				console.log('[MIG:fixed] ListItem: The sync property is no longer supported. (async always)');
+			}
+			if(w.btnClass !== undefined || w.srcNodeRef && w.srcNodeRef.getAttribute("btnClass")){
+				console.log('[MIG:fixed] ListItem: The btnClass property is no longer supported. Use rightIcon instead.');
+				w.rightIcon = w.btnClass || w.srcNodeRef && w.srcNodeRef.getAttribute("btnClass");
+			}
+			if(w.btnClass2 !== undefined || w.srcNodeRef && w.srcNodeRef.getAttribute("btnClass2")){
+				console.log('[MIG:fixed] ListItem: The btnClass2 property is no longer supported. Use rightIcon2 instead.');
+				w.rightIcon2 = w.btnClass2 || w.srcNodeRef && w.srcNodeRef.getAttribute("btnClass2");
+			}
+		};
+
+		this.checkSpinWheelSlot = function(/*Widget*/ w){
+			if(w.labels && w.labels[0] && w.labels[0].charAt(0) === '['){
+				for(var i = 0; i < w.labels.length; i++){
+					w.labels[i] = w.labels[i].replace(/^\[*[\'\"]*/, '');
+					w.labels[i] = w.labels[i].replace(/[\'\"]*\]*$/, '');
+				}
+				console.log('[MIG:fixed] SpinWheelSlot: dojox/mobile/parser no longer accepts array-type attribute like labels="[\'A\',\'B\',\'C\',\'D\',\'E\']". Specify as labels="A,B,C,D,E" instead.' );
+			}
+		};
+
+		this.checkSwapView = function(/*Widget*/ w){
+			var n = w.srcNodeRef;
+			if(n){
+				var type = n.getAttribute("dojoType") || n.getAttribute("data-dojo-type");
+				if(type === "dojox.mobile.FlippableView"){
+					console.log('[MIG:fixed] FlippableView: FlippableView is no longer supported. Use SwapView instead.');
+				}
+			}
+		};
+
+		this.checkSwitch = function(/*Widget*/ w){
+			if(w["class"] === "mblItemSwitch"){
+				console.log('[MIG:fixed] Switch: class="mblItemSwitch" is no longer necessary.');
+			}
+		};
+
+		this.checkTabBar = function(/*Widget*/ w){
+			if(get(w, "barType") === "segmentedControl"){
+				console.log('[MIG:warning] TabBar: segmentedControl in 1.8 produces the same UI regardless of the current theme. See the inline doc in migrationAssist.js for details.');
+				domConstruct.create("style", {
+					innerHTML: ".iphone_theme .mblTabBarSegmentedControl .mblTabBarButtonIconArea { display: none; }"
+				}, win.doc.getElementsByTagName('head')[0]);
+			}
+		};
+
+		this.checkTabBarButton = function(/*Widget*/ w){
+			if((w["class"] || "").indexOf("mblDomButton") === 0){
+				console.log('[MIG:fixed] TabBarButton: Use icon="' + w["class"] + '" instead of class="' + w["class"] + '".');
+				w.icon = w["class"];
+				w["class"] = "";
+				if(w.srcNodeRef){
+					w.srcNodeRef.className = "";
+				}
+			}
+		};
+
+		this.checkToolBarButton = function(/*Widget*/ w){
+			if((w["class"] || "").indexOf("mblColor") === 0){
+				console.log('[MIG:fixed] ToolBarButton: Use defaultColor="' + w["class"] + '" instead of class="' + w["class"] + '".');
+				w.defaultColor = w["class"];
+				w["class"] = "";
+				if(w.srcNodeRef){
+					w.srcNodeRef.className = "";
+				}
+			}
+
+			if((w["class"] || "").indexOf("mblDomButton") === 0){
+				console.log('[MIG:fixed] ToolBarButton: Use icon="' + w["class"] + '" instead of class="' + w["class"] + '".');
+				w.icon = w["class"];
+				w["class"] = "";
+				if(w.srcNodeRef){
+					w.srcNodeRef.className = "";
+				}
+			}
+		};
+	};
+
+	dojox.mobile.FlippableView = SwapView;
+
+	var migrationAssist = new MigrationAssist();
+
+	// Hide from the API doc tool, we want to get the documentation for the normal WidgetBase.postMixInProperties()
+	WidgetBase.prototype.postMixInProperties = /*===== WidgetBase.prototype.postMixInProperties || =====*/ function(){
+		migrationAssist.dispatch(this.declaredClass, this);
+		dojo.forEach([FixedSplitterPane, Heading, RoundRect, SpinWheel, TabBarButton, ToolBarButton, View], function(module){
+			if(this.declaredClass !== module.prototype.declaredClass && this instanceof module){
+				migrationAssist.dispatch(module.prototype.declaredClass, this);
+			}
+		}, this);
+
+	};
+
+
+	extendSelectFunction = function(obj) {
+		lang.extend(obj, {
+			select: function(){
+				console.log('[MIG:fixed] ' + this.declaredClass + '(id='+this.id+'): Use set("selected", boolean) instead of select/deselect.');
+				obj.prototype.set.apply(this, ["selected", !arguments[0]]);
+			},
+			deselect: function(){
+				this.select(true);
+			}
+		});
+	};
+
+	extendSelectFunction(ToolBarButton);
+	extendSelectFunction(TabBarButton);
+
+	lang.extend(ListItem, {
+		set: function(key, value){
+			if(key === "btnClass"){
+				console.log('[MIG:fixed] ' + this.declaredClass + '(id='+this.id+'): Use set("rightIcon",x) instead of set("btnClass",x).');
+				key = "rightIcon";
+			}else if(key === "btnClass2"){
+				console.log('[MIG:fixed] ' + this.declaredClass + '(id='+this.id+'): Use set("rightIcon2",x) instead of set("btnClass2",x).');
+				key = "rightIcon2";
+			}
+			WidgetBase.prototype.set.apply(this, [key, value]);
+		}
+	});
+
+	lang.extend(SpinWheel, {
+		getValue: function(){
+			console.log('[MIG:fixed] SpinWheel: getValue() is no longer supported. Use get("values") instead.');
+			return this.get("values");
+		},
+		setValue: function(newValue){
+			console.log('[MIG:fixed] SpinWheel: setValue() is no longer supported. Use set("values",x) instead.');
+			return this.set("values", newValue);
+		}
+	});
+
+	lang.extend(SpinWheelSlot, {
+		getValue: function(){
+			console.log('[MIG:fixed] SpinWheelSlot: getValue() is no longer supported. Use get("value") instead.');
+			return this.get("value");
+		},
+		getKey: function(){
+			console.log('[MIG:fixed] SpinWheelSlot: getKey() is no longer supported. Use get("key") instead.');
+			return this.get("key");
+		},
+		setValue: function(newValue){
+			console.log('[MIG:fixed] SpinWheelSlot: setValue() is no longer supported. Use set("value",x) instead.');
+			return this.set("value", newValue);
+		}
+	});
+
+	lang.mixin(mobile, {
+		createDomButton: function(){
+			console.log('[MIG:fixed] dojox.mobile(id='+arguments[0].id+'): createDomButton was moved to iconUtils.');
+			return iconUtils.createDomButton.apply(this, arguments);
+		}
+	});
+
+	// check css
+	var cssFiles = [], i, j;
+
+	// collect @import
+	var s = win.doc.styleSheets;
+	for(i = 0; i < s.length; i++){
+		if(s[i].href){ continue; }
+		var r = s[i].cssRules || s[i].imports;
+		if(!r){ continue; }
+		for(j = 0; j < r.length; j++){
+			if(r[j].href){
+				cssFiles.push(r[j].href);
+			}
+		}
+	}
+
+	// collect <link>
+	var elems = win.doc.getElementsByTagName("link");
+	for(i = 0; i < elems.length; i++){
+		cssFiles.push(elems[i].href);
+	}
+
+	for(i = 0; i < cssFiles.length; i++){
+		if(cssFiles[i].indexOf("/iphone/") !== -1){
+			currentTheme = "iphone";
+		}else if(cssFiles[i].indexOf("/android/") !== -1){
+			currentTheme = "android";
+		}else if(cssFiles[i].indexOf("/blackberry/") !== -1){
+			currentTheme = "blackberry";
+		}else if(cssFiles[i].indexOf("/custom/") !== -1){
+			currentTheme = "custom";
+		}
+		domClass.add(win.doc.documentElement, currentTheme + "_theme");
+
+		if(cssFiles[i].match(/themes\/common\/(FixedSplitter.css)|themes\/common\/(SpinWheel.css)/)){
+			console.log('[MIG:error] ' + (RegExp.$1 || RegExp.$2) + ' is no longer in the themes/common folder. It is in the device theme folder.');
+		}
+	}
+
+	ready(function(){
+		if(dojo.hash){
+			console.log('[MIG:fixed] dojo/hash detected. If you would like to enable the bookmarkable feature, require dojox/mobile/bookmarkable instead of dojo/hash');
+			if(dojo.require){
+				dojo["require"]("dojox.mobile.bookmarkable");
+			}else{
+				require(["dojox/mobile/bookmarkable"]);
+			}
+		}
+	});
+
+	// Return singleton.  (TODO: can we replace LazyLoadUtils class and singleton w/a simple hash of functions?)
+	return migrationAssist;
+});
diff --git a/dojox/mobile/mobile-all.js b/dojox/mobile/mobile-all.js
index 24684bf..2748b16 100644
--- a/dojox/mobile/mobile-all.js
+++ b/dojox/mobile/mobile-all.js
@@ -1,47 +1,88 @@
 define([
 	"./_base",
-	"./compat",
+	"./_EditableIconMixin",
+	"./_EditableListMixin",
+	"./_ExecScriptMixin",
+	"./_IconItemPane",
+	"./Accordion",
+	"./Audio",
+	"./Badge",
 	"./Button",
 	"./Carousel",
+	"./CarouselItem",
 	"./CheckBox",
 	"./ComboBox",
+	"./compat",
 	"./ContentPane",
+	"./DataCarousel",
+	"./DatePicker",
 	"./EdgeToEdgeDataList",
+	"./EdgeToEdgeStoreList",
 	"./ExpandingTextArea",
 	"./FixedSplitter",
 	"./FixedSplitterPane",
-	"./FlippableView",
+	"./GridLayout",
+	"./Icon",
 	"./IconContainer",
 	"./IconItem",
+	"./IconMenu",
+	"./IconMenuItem",
 	"./Opener",
 	"./Overlay",
 	"./PageIndicator",
+	"./ProgressBar",
 	"./RadioButton",
+	"./Rating",
 	"./RoundRectDataList",
+	"./RoundRectStoreList",
+	"./ScreenSizeAware",
+	"./ScrollablePane",
 	"./ScrollableView",
+	"./SearchBox",
 	"./Slider",
 	"./SpinWheel",
 	"./SpinWheelDatePicker",
 	"./SpinWheelSlot",
 	"./SpinWheelTimePicker",
+	"./StoreCarousel",
 	"./SwapView",
-	"./Switch",
 	"./TabBar",
 	"./TabBarButton",
 	"./TextArea",
 	"./TextBox",
+	"./TimePicker",
 	"./ToggleButton",
 	"./Tooltip",
 	"./transition",
 	"./TransitionEvent",
-	"./ViewController"
+	"./TreeView",
+	"./ValuePicker",
+	"./ValuePickerDatePicker",
+	"./ValuePickerSlot",
+	"./ValuePickerTimePicker",
+	"./Video",
+	"./ViewController",
+	"./dh/ContentTypeMap",
+	"./dh/DataHandler",
+	"./dh/HtmlContentHandler",
+	"./dh/HtmlScriptContentHandler",
+	"./dh/JsonContentHandler",
+	"./dh/PatternFileTypeMap",
+	"./dh/StringDataSource",
+	"./dh/SuffixFileTypeMap",
+	"./dh/UrlDataSource"
 ], function(common){
 	// module:
 	//		dojox/mobile/mobile-all
-	// summary:
-	//		A rollup that includes every mobile module. You probably don't need this.
 
-	console.warn("mobile-all may include much more code than your application actually requires. We strongly recommend that you investigate a custom build.");
+	console.warn("dojox/mobile/mobile-all may include much more code than your application actually requires. We strongly recommend that you use a custom build.");
 
+	/*=====
+	return {
+		// summary:
+		//		A roll-up that includes every mobile module. You probably don't need
+		//		this. Demo purposes only.
+	};
+	=====*/
 	return common;
 });
diff --git a/dojox/mobile/pageTurningUtils.js b/dojox/mobile/pageTurningUtils.js
new file mode 100644
index 0000000..8b79692
--- /dev/null
+++ b/dojox/mobile/pageTurningUtils.js
@@ -0,0 +1,600 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/event",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/dom-style",
+	"./_css3"
+], function(kernel, array, connect, event, domClass, domConstruct, domStyle, css3){
+	// module:
+	//		dojox/mobile/pageTurningUtils
+	
+	kernel.experimental("dojox.mobile.pageTurningUtils");
+
+	return function(){
+		// summary:
+		//		Utilities to provide page turning effects just like turning a real book.
+		// example:
+		// |	require([
+		// |		"dojo/ready",
+		// |		"dojox/mobile/pageTurningUtils"
+		// |	], function(ready, pageTurningUtils){
+		// |		var utils = new pageTurningUtils();
+		// |		ready(function(){
+		// |			utils.init(300, 400); // Specify width and height by pixels
+		// |			utils.initCatalog(document.getElementById("catalog"));
+		// |		});
+		// |	);
+		// |	<div id="catalog">
+		// |		<div id="page1">
+		// |			<div id="front1"><img src="img1.png"></div>
+		// |			<div id="back1"><img src="img2.png"></div>
+		// |		</div>
+		// |		<div id="page2">
+		// |			<div id="front2"><img src="img3.png"></div>
+		// |			<div id="back2"><img src="img4.png"></div>
+		// |		</div>
+		// |		<div id="page3">
+		// |			<div id="front3"><img src="img5.png"></div>
+		// |			<div id="back3"></div>
+		// |		</div>
+		// |	</div>
+
+		this.w = 0;
+		this.h = 0;
+		this.turnfrom = "top";
+		this.page = 1;
+		this.dogear = 1.0;
+		this.duration = 2;
+		this.alwaysDogeared = false;
+
+		/* Internal properties */
+		this._styleParams = {};
+		this._catalogNode = null;
+		this._currentPageNode = null;
+		this._transitionEndHandle = null;
+
+		this.init = function(/*int*/w, /*int*/h, /*String?*/turnfrom, 
+							/*int?*/page, /*Number?*/dogear, /*Number?*/duration,
+							/*Boolean?*/alwaysDogeared){
+			// summary:
+			//		Sets property values necessary for calculating the style parameters
+			//		for page positioning and page turning effects.
+			// w: int
+			//		The width of each page by pixels. You cannot specify it by percentage.
+			// h: int
+			//		The height of each page by pixels. You cannot specify it by percentage.
+			// turnfrom: String?
+			//		Specifies from which side/corner the page turning starts. 
+			//		You can choose from "top", "bottom" or "left". Defaults to "top".
+			//		If "top", each page is turned from top-right corner of the page.
+			//		If "bottom", each page is turned from bottom-right corner of the page.
+			//		And if "left", each page is turned from top-left corner of the page.
+			//		The page is shown as dog-eared except the case of "bottom".
+			// page: int?
+			//		The number of pages shown in the screen at a time.
+			//		This parameter should be either of 1 or 2. Defaults to 1.
+			//		If 1, the only one side of two facing pages are shown. 
+			//		If 2, the two facing pages are shown at a time.
+			// dogear: Number?
+			//		The ratio of actual dog-ear width to the maximum dog-ear width which is
+			//		11 percent of the page width (= 0.11 * w).
+			//		This parameter should be a float number between 0 and 1. Defaults to 1.
+			//		The actual dog-ear width is calculated by the following formula:
+			// |		0.11 * w * dogear.
+			//		This parameter is ignored if "bottom" is specified to turnfrom parameter.
+			// duration: Number?
+			//		The duration of page turning animations by seconds. (ex. 1.5, 3, etc)
+			//		Defaults to 2.
+			// alwaysDogeared: Boolean?
+			//		Specifies whether all pages are always dog-eared or not.
+			//		If true, all pages are always dog-eared.
+			//		If false, only the current page is dog-eared while the others are not.
+			//		This parameter is ignored if "bottom" is specified to turnfrom parameter.
+			
+			// Set property values
+			this.w = w;
+			this.h = h;
+			this.turnfrom = turnfrom ? turnfrom : this.turnfrom;
+			this.page = page ? page : this.page;
+			this.dogear = typeof dogear !== 'undefined' ? dogear : this.dogear;
+			this.duration = typeof duration !== 'undefined' ? duration : this.duration;
+			this.alwaysDogeared = typeof alwaysDogeared !== 'undefined' ? alwaysDogeared : this.alwaysDogeared
+			
+			if(this.turnfrom === "bottom"){ // dog-ear is not supported if using "bottom"
+				this.alwaysDogeared = true;
+			}
+			// Calculate style parameters for page positioning and page turning effects
+			this._calcStyleParams();
+		};
+
+		this._calcStyleParams = function(){
+			// tags:
+			//		private
+			var tan58 = Math.tan(58 * Math.PI/180),
+				cos32 = Math.cos(32 * Math.PI/180),
+				sin32 = Math.sin(32 * Math.PI/180),
+				tan32 = Math.tan(32 * Math.PI/180),
+				w = this.w,
+				h = this.h,
+				page = this.page,
+				turnfrom = this.turnfrom,
+				params = this._styleParams;
+			
+			// Calculate each div size and position based on the page turning algorithm
+			//	 fw: frontWidth, fh: frontHeight, dw: dogear, cx: posX, cy: posY,
+			//	 dx: dogearX, dy: dogearY, fy:actualPagePos
+			var Q = fold = w * tan58,
+				fw = Q * sin32 + Q * cos32 * tan58,
+				fh = fold + w + w/tan58,
+				dw = w * 0.11 * this.dogear,
+				pw = w - dw,
+				base = pw * cos32,
+				cx, cy, dx, dy, fy; // These params depend on the types of "turnfrom" parameter
+			
+			switch(this.turnfrom){ // TODO Should separate each case as a plugin?
+			case "top":
+				cx = fw - base;
+				cy = base * tan58;
+				dx = fw - dw;
+				dy = cy + pw/tan58 - 7;
+				fy = cy/cos32;
+				
+				params.init = {
+					page: css3.add({
+						top: -fy + "px",
+						left: (-fw + (page === 2 ? w : 0)) + "px",
+						width: fw + "px",
+						height: fh + "px"
+					}, {
+						transformOrigin: "100% 0%"
+					}),
+					front: css3.add({
+						width: w + "px",
+						height: h + "px"
+					}, {
+						boxShadow: "0 0"
+					}),
+					back: css3.add({
+						width: w + "px",
+						height: h + "px"
+					}, {
+						boxShadow: "0 0"
+					}),
+					shadow: {
+						display: "",
+						left: fw + "px",
+						height: h * 1.5 + "px"
+					}
+				};
+				params.turnForward = {
+					page: css3.add({}, {
+						transform: "rotate(0deg)"
+					}),
+					front: css3.add({}, {
+						transform: "translate("+ fw + "px," + fy +"px) rotate(0deg)",
+						transformOrigin: "-110px -18px"
+					}),
+					back: css3.add({}, {
+						transform: "translate("+ (fw - w) + "px," + fy +"px) rotate(0deg)",
+						transformOrigin: "0px 0px"
+					})
+				};
+				params.turnBackward = {
+					page: css3.add({}, {
+						transform: "rotate(-32deg)"
+					}),
+					front: css3.add({}, {
+						transform: "translate("+ cx + "px," + cy +"px) rotate(32deg)",
+						transformOrigin: "0px 0px"
+					}),
+					back: css3.add({}, {
+						transform: "translate("+ dx + "px," + dy +"px) rotate(-32deg)",
+						transformOrigin: "0px 0px"
+					})
+				};
+				break;
+				
+			case "bottom":
+				cx = fw - (h * sin32 + w * cos32) - 2;
+				cy = fh - (h + w/tan32) * cos32;
+				dx = fw;
+				dy = fh - w/sin32 - h;
+				fy = fh - w/tan32 - h;
+				
+				params.init = {
+					page: css3.add({
+						top: (-fy + 50) + "px",
+						left: (-fw + (page === 2 ? w : 0)) + "px",
+						width: fw + "px",
+						height: fh + "px"
+					}, {
+						transformOrigin: "100% 100%"
+					}),
+					front: css3.add({
+						width: w + "px",
+						height: h + "px"
+					}, {
+						boxShadow: "0 0"
+					}),
+					back: css3.add({
+						width: w + "px",
+						height: h + "px"
+					}, {
+						boxShadow: "0 0"
+					}),
+					shadow: {
+						display: "none"
+					}
+				};
+				params.turnForward = {
+					page: css3.add({}, {
+						transform: "rotate(0deg)"
+					}),
+					front: css3.add({}, {
+						transform: "translate("+ fw + "px," + fy +"px) rotate(0deg)",
+						transformOrigin: "-220px 35px"
+					}),
+					back: css3.add({}, {
+						transform: "translate("+ (w * 2) + "px," + fy +"px) rotate(0deg)",
+						transformOrigin: "0px 0px"
+					})
+				};
+				params.turnBackward = {
+					page: css3.add({}, {
+						transform: "rotate(32deg)"
+					}),
+					front: css3.add({}, {
+						transform: "translate("+ cx + "px," + cy +"px) rotate(-32deg)",
+						transformOrigin: "0px 0px"
+					}),
+					back: css3.add({}, {
+						transform: "translate("+ dx + "px," + dy +"px) rotate(0deg)",
+						transformOrigin: "0px 0px"
+					})
+				};
+				break;
+				
+			case "left":
+				cx = -w;
+				cy = pw/tan32 - 2;
+				dx = -pw;
+				dy = fy = pw/sin32 + dw * sin32;
+				
+				params.init = {
+					page: css3.add({
+						top: -cy + "px",
+						left: w + "px",
+						width: fw + "px",
+						height: fh + "px"
+					}, {
+						transformOrigin: "0% 0%"
+					}),
+					front: css3.add({
+						width: w + "px",
+						height: h + "px"
+					}, {
+						boxShadow: "0 0"
+					}),
+					back: css3.add({
+						width: w + "px",
+						height: h + "px"
+					}, {
+						boxShadow: "0 0"
+					}),
+					shadow: {
+						display: "",
+						left: "-4px",
+						height: ((page === 2 ? h * 1.5 : h) + 50) + "px"
+					}
+				};
+				params.turnForward = {
+					page: css3.add({}, {
+						transform: "rotate(0deg)"
+					}),
+					front: css3.add({}, {
+						transform: "translate("+ cx + "px," + cy +"px) rotate(0deg)",
+						transformOrigin: "160px 68px"
+					}),
+					back: css3.add({}, {
+						transform: "translate(0px," + cy +"px) rotate(0deg)",
+						transformOrigin: "0px 0px"
+					})
+				};
+				params.turnBackward = {
+					page: css3.add({}, {
+						transform: "rotate(32deg)"
+					}),
+					front: css3.add({}, {
+						transform: "translate("+ (-dw) + "px," + dy +"px) rotate(-32deg)",
+						transformOrigin: "0px 0px"
+					}),
+					back: css3.add({}, {
+						transform: "translate("+ dx + "px," + dy +"px) rotate(32deg)",
+						transformOrigin: "top right"
+					})
+				};
+				break;
+			}
+			
+			params.init.catalog = { // catalogNode
+				width: (page === 2 ? w * 2 : w) + "px",
+				height: ((page === 2 ? h * 1.5 : h) + (turnfrom == "top" ? 0 : 50)) + "px"
+			};
+		};
+
+		this.getChildren = function(/*DomNode*/node){
+			return array.filter(node.childNodes, function(n){ return n.nodeType === 1; });
+		};
+
+		this.getPages = function(){
+			// summary:
+			//		Get the array of all page nodes.
+			return this._catalogNode ? this.getChildren(this._catalogNode) : null;
+		};
+
+		this.getCurrentPage = function(){
+			// summary:
+			//		Get the current page node.
+			return this._currentPageNode;
+		};
+
+		this.getIndexOfPage = function(/*DomNode*/pageNode, /*DomNode[]?*/pages){
+			if(!pages){
+				pages = this.getPages();
+			}
+			for(var i=0; i<pages.length; i++){
+				if(pageNode === pages[i]){ return i; }
+			}
+			return -1;
+		};
+
+		this.getNextPage = function(/*DomNode*/pageNode){
+			for(var n = pageNode.nextSibling; n; n = n.nextSibling){
+				if(n.nodeType === 1){ return n; }
+			}
+			return null;
+		};
+
+		this.getPreviousPage = function(/*DomNode*/pageNode){
+			for(var n = pageNode.previousSibling; n; n = n.previousSibling){
+				if(n.nodeType === 1){ return n; }
+			}
+			return null;
+		};
+
+		this.isPageTurned = function(/*DomNode*/pageNode){
+			return pageNode.style[css3.name("transform")] == "rotate(0deg)";
+		};
+
+		this._onPageTurned = function(e){
+			event.stop(e);
+			if(domClass.contains(e.target, "mblPageTurningPage")){
+				this.onPageTurned(e.target);
+			}
+		};
+
+		this.onPageTurned = function(/*DomNode*/ /*===== pageNode =====*/){
+			// summary:
+			//		Stub function to which your application connects 
+			//		to handle the event when each page is tured 
+			// description:
+			//		Called just after each page is turned.
+		};
+
+		this.initCatalog = function(/*DomNode*/catalogNode){
+			// summary:
+			//		Initializes the specified catalog/book.
+			// description:
+			//		Apply style class and other various styles to the specified catalog node
+			//		for initialization.
+			//		This function must be called every time when property values
+			//		are changed by calling this.init(...) function.
+			// catalogNode: DOMNode
+			//		The catalog node to be initialized.
+			
+			if(this._catalogNode != catalogNode){
+				if(this._transitionEndHandle){
+					connect.disconnect(this._transitionEndHandle);
+				}
+				this._transitionEndHandle = connect.connect(catalogNode, css3.name("transitionEnd"), this, "_onPageTurned")
+				this._catalogNode = catalogNode;
+			}
+			
+			// Initialize catalog node
+			domClass.add(catalogNode, "mblPageTurningCatalog");
+			domStyle.set(catalogNode, this._styleParams.init.catalog);
+			
+			// Initialize child pages
+			var pages = this.getPages();
+			array.forEach(pages, function(pageNode){
+				this.initPage(pageNode);
+			}, this);
+			
+			this.resetCatalog();
+		};
+
+		this._getBaseZIndex = function(){
+			// Check z-index of catalogNode
+			return this._catalogNode.style.zIndex || 0;
+		};
+
+		this.resetCatalog = function(){
+			// summary:
+			//		Resets the catalog by adjust the state of child pages.
+			// description:
+			//		Adjust z-index and dog-ear show/hide state of each child page.
+			//		This function must be called when you add a new page 
+			//		or remove some page after initialization.
+			
+			// Adjust z-index and dog-ear of child pages
+			var pages = this.getPages(),
+				len = pages.length,
+				base = this._getBaseZIndex();
+			for(var i = len - 1; i>=0; i--){
+				var pageNode = pages[i];
+				this.showDogear(pageNode);
+				if(this.isPageTurned(pageNode)){
+					pageNode.style.zIndex = base + len + 1;
+				}else{
+					pageNode.style.zIndex = base + len - i;
+					!this.alwaysDogeared && this.hideDogear(pageNode);
+					this._currentPageNode = pageNode;
+				}
+			}
+			if(!this.alwaysDogeared && this._currentPageNode != pages[len - 1]){
+				this.showDogear(this._currentPageNode);
+			}
+		};
+
+		this.initPage = function(/*DomNode*/pageNode, /*int?*/dir){
+			// summary:
+			//		Initializes the specified page.
+			// description:
+			//		Apply style class and other various styles to the specified page node
+			//		for initialization.
+			//		This function must be called when you add a new page after initialization.
+			// pageNode: DOMNode
+			//		The page node to be initialized.
+			// dir: int?
+			//		Specified whether the page is turned or not at initialization.
+			//		This parameter should be either of 1 or -1.
+			//		If 1, the page is turned at initialization. If -1, it is not turned.
+			
+			// Create shadow node if not exist
+			var childNodes = this.getChildren(pageNode);
+			while(childNodes.length < 3){
+				pageNode.appendChild(domConstruct.create("div", null));
+				childNodes = this.getChildren(pageNode);
+			}
+			
+			// Check if it is the first time to initialize this page node or not
+			var isFirst = !domClass.contains(pageNode, "mblPageTurningPage");
+			
+			// Apply style class
+			domClass.add(pageNode, "mblPageTurningPage");
+			domClass.add(childNodes[0], "mblPageTurningFront"); // frontNode
+			domClass.add(childNodes[1], "mblPageTurningBack"); // backNode
+			domClass.add(childNodes[2], "mblPageTurningShadow"); // shadowNode
+			
+			// Apply styles
+			var p = this._styleParams.init;
+			domStyle.set(pageNode, p.page);
+			domStyle.set(childNodes[0], p.front); // frontNode
+			domStyle.set(childNodes[1], p.back); // backNode
+			p.shadow && domStyle.set(childNodes[2], p.shadow); // shadowNode
+			
+			if(!dir){
+				// Determine whether to turn this page or not
+				if(isFirst && this._currentPageNode){
+					var pages = this.getPages();
+					dir = this.getIndexOfPage(pageNode) < this.getIndexOfPage(this._currentPageNode) ? 1 : -1;
+				}else{
+					dir = this.isPageTurned(pageNode) ? 1 : -1;
+				}
+			}
+			this._turnPage(pageNode, dir, 0);
+		};
+
+		this.turnToNext = function(/*Number?*/duration){
+			// summary:
+			//		Turns a page forward.
+			// description:
+			//		The current page is turned forward if it is not the last page of the book.
+			// duration: Number?
+			//		The duration of page turning animations by seconds. (ex. 1.5, 3, etc)
+			//		If this parameter is omitted, this.duration property value is used.
+			var nextPage = this.getNextPage(this._currentPageNode);
+			if(nextPage){
+				this._turnPage(this._currentPageNode, 1, duration);
+				this._currentPageNode = nextPage;
+			}
+		};
+
+		this.turnToPrev = function(/*Number?*/duration){
+			// summary:
+			//		Turns a page backward.
+			// description:
+			//		The current page is turned backward if it is not the first page of the book.
+			// duration: Number?
+			//		The duration of page turning animations by seconds. (ex. 1.5, 3, etc)
+			//		If this parameter is omitted, this.duration property value is used.
+			var prevPage = this.getPreviousPage(this._currentPageNode);
+			if(prevPage){
+				this._turnPage(prevPage, -1, duration);
+				this._currentPageNode = prevPage;
+			}
+		};
+
+		this.goTo = function(/*int*/index){
+			// summary:
+			//		Jumps to the specified page without page turning animations.
+			// index: int
+			//		The index of the page you want to jump to.
+			var pages = this.getPages();
+			if(this._currentPageNode === pages[index] || pages.length <= index) { return; }
+			
+			var goBackward = index < this.getIndexOfPage(this._currentPageNode, pages);
+			while(this._currentPageNode !== pages[index]) {
+				goBackward ? this.turnToPrev(0) : this.turnToNext(0);
+			}
+		};
+
+		this._turnPage = function(/*DomNode*/pageNode, /*int*/dir, /*Number?*/duration){
+			// tags:
+			//		private
+			var childNodes = this.getChildren(pageNode),
+				d = ((typeof duration !== 'undefined') ? duration : this.duration) + "s",
+				p = (dir === 1) ? this._styleParams.turnForward : this._styleParams.turnBackward;
+			
+			// Apply styles for page turning animations
+			p.page[css3.name("transitionDuration")] = d;
+			domStyle.set(pageNode, p.page);
+			
+			p.front[css3.name("transitionDuration")] = d;
+			domStyle.set(childNodes[0], p.front); // frontNode
+			
+			p.back[css3.name("transitionDuration")] = d;
+			domStyle.set(childNodes[1], p.back); // backNode
+			
+			// Adjust z-index and dog-ear
+			var pages = this.getPages(),
+				nextPage = this.getNextPage(pageNode),
+				len = pages.length,
+				base = this._getBaseZIndex();
+			if(dir === 1){
+				pageNode.style.zIndex = base + len + 1;
+				if(!this.alwaysDogeared && nextPage && this.getNextPage(nextPage)){
+					this.showDogear(nextPage);
+				}
+			}else{
+				if(nextPage){
+					nextPage.style.zIndex = base + len - this.getIndexOfPage(nextPage, pages);
+					!this.alwaysDogeared && this.hideDogear(nextPage);
+				}
+			}
+		};
+
+		this.showDogear = function(/*DomNode*/pageNode){
+			// summary:
+			//		Shows the dog-ear.
+			var childNodes = this.getChildren(pageNode);;
+			domStyle.set(pageNode, "overflow", "");
+			childNodes[1] && domStyle.set(childNodes[1], "display", ""); // backNode
+			childNodes[2] && domStyle.set(childNodes[2], "display", this.turnfrom === "bottom" ? "none" : ""); // shadowNode
+		};
+
+		this.hideDogear = function(/*DomNode*/pageNode){
+			// summary:
+			//		Hides the dog-ear.
+			if(this.turnfrom === "bottom"){ return; }
+			
+			var childNodes = this.getChildren(pageNode);
+			domStyle.set(pageNode, "overflow", "visible");
+			childNodes[1] && domStyle.set(childNodes[1], "display", "none"); // backNode
+			childNodes[2] && domStyle.set(childNodes[2], "display", "none"); // shadowNode
+		};
+	};
+});
diff --git a/dojox/mobile/parser.js b/dojox/mobile/parser.js
index 7128f4d..e626055 100644
--- a/dojox/mobile/parser.js
+++ b/dojox/mobile/parser.js
@@ -1,52 +1,64 @@
 define([
 	"dojo/_base/kernel",
+	"dojo/_base/array",
 	"dojo/_base/config",
 	"dojo/_base/lang",
 	"dojo/_base/window",
 	"dojo/ready"
-], function(dojo, config, lang, win, ready){
+], function(dojo, array, config, lang, win, ready){
 
 	// module:
 	//		dojox/mobile/parser
-	// summary:
-	//		A lightweight parser.
 
 	var dm = lang.getObject("dojox.mobile", true);
 
-	var parser = new function(){
+	var Parser = function(){
 		// summary:
 		//		A lightweight parser.
 		// description:
-		//		dojox.mobile.parser is an extremely small subset of
-		//		dojo.parser. It has no extended features over dojo.parser, so
-		//		there is no reason you have to use dojox.mobile.parser instead
-		//		of dojo.parser. However, if dojox.mobile.parser's capability is
-		//		enough for your application, use of it could reduce the total
-		//		code size.
+		//		dojox/mobile/parser is an extremely small subset of dojo/parser.
+		//		It has no additional features over dojo/parser, so there is no
+		//		benefit in terms of features by using dojox/mobile/parser instead 
+		//		of dojo/parser.	However, if dojox/mobile/parser's capabilities are
+		//		enough for your	application, using it could reduce the total code size.
 
-		this.instantiate = function(/* Array */nodes, /* Object? */mixin, /* Object? */args){
+		var _ctorMap = {};
+		var getCtor = function(type, mixins){
+			if(typeof(mixins) === "string"){
+				var t = type + ":" + mixins.replace(/ /g, "");
+				return _ctorMap[t] ||
+					(_ctorMap[t] = getCtor(type).createSubclass(array.map(mixins.split(/, */), getCtor)));
+			}
+			return _ctorMap[type] || (_ctorMap[type] = lang.getObject(type) || require(type));
+		};
+		var _eval = function(js){ return eval(js); };
+
+		this.instantiate = function(/* DomNode[] */nodes, /* Object? */mixin, /* Object? */options){
 			// summary:
 			//		Function for instantiating a list of widget nodes.
 			// nodes:
-			//		The list of DOMNodes to walk and instantiate widgets on.
+			//		The list of DomNodes to walk and instantiate widgets on.
 			mixin = mixin || {};
-			args = args || {};
+			options = options || {};
 			var i, ws = [];
 			if(nodes){
 				for(i = 0; i < nodes.length; i++){
-					var n = nodes[i];
-					var cls = lang.getObject(n.getAttribute("dojoType") || n.getAttribute("data-dojo-type"));
-					var proto = cls.prototype;
-					var params = {}, prop, v, t;
-					lang.mixin(params, eval('({'+(n.getAttribute("data-dojo-props")||"")+'})'));
-					lang.mixin(params, args.defaults);
+					var n = nodes[i],
+						type = n._type,
+						ctor = getCtor(type, n.getAttribute("data-dojo-mixins")),
+						proto = ctor.prototype,
+						params = {}, prop, v, t;
+					lang.mixin(params, _eval.call(options.propsThis, '({'+(n.getAttribute("data-dojo-props")||"")+'})'));
+					lang.mixin(params, options.defaults);
 					lang.mixin(params, mixin);
 					for(prop in proto){
 						v = n.getAttributeNode(prop);
 						v = v && v.nodeValue;
 						t = typeof proto[prop];
 						if(!v && (t !== "boolean" || v !== "")){ continue; }
-						if(t === "string"){
+						if(lang.isArray(proto[prop])){
+							params[prop] = v.split(/\s*,\s*/);
+						}else if(t === "string"){
 							params[prop] = v;
 						}else if(t === "number"){
 							params[prop] = v - 0;
@@ -54,15 +66,18 @@ define([
 							params[prop] = (v !== "false");
 						}else if(t === "object"){
 							params[prop] = eval("(" + v + ")");
+						}else if(t === "function"){
+							params[prop] = lang.getObject(v, false) || new Function(v);
+							n.removeAttribute(prop);
 						}
 					}
 					params["class"] = n.className;
-					params.style = n.style && n.style.cssText;
+					if(!params.style){ params.style = n.style.cssText; }
 					v = n.getAttribute("data-dojo-attach-point");
 					if(v){ params.dojoAttachPoint = v; }
 					v = n.getAttribute("data-dojo-attach-event");
 					if(v){ params.dojoAttachEvent = v; }
-					var instance = new cls(params, n);
+					var instance = new ctor(params, n);
 					ws.push(instance);
 					var jsId = n.getAttribute("jsId") || n.getAttribute("data-dojo-id");
 					if(jsId){
@@ -71,13 +86,13 @@ define([
 				}
 				for(i = 0; i < ws.length; i++){
 					var w = ws[i];
-					!args.noStart && w.startup && !w._started && w.startup();
+					!options.noStart && w.startup && !w._started && w.startup();
 				}
 			}
 			return ws;
 		};
 
-		this.parse = function(rootNode, args){
+		this.parse = function(/* DomNode */ rootNode, /* Object? */ options){
 			// summary:
 			//		Function to handle parsing for widgets in the current document.
 			//		It is not as powerful as the full parser, but it will handle basic
@@ -86,28 +101,57 @@ define([
 			//		The root node in the document to parse from
 			if(!rootNode){
 				rootNode = win.body();
-			}else if(!args && rootNode.rootNode){
+			}else if(!options && rootNode.rootNode){
 				// Case where 'rootNode' is really a params object.
-				args = rootNode;
+				options = rootNode;
 				rootNode = rootNode.rootNode;
 			}
 
 			var nodes = rootNode.getElementsByTagName("*");
-			var i, list = [];
+			var i, j, list = [];
 			for(i = 0; i < nodes.length; i++){
-				var n = nodes[i];
-				if(n.getAttribute("dojoType") || n.getAttribute("data-dojo-type")){
+				var n = nodes[i],
+					type = (n._type = n.getAttribute("dojoType") || n.getAttribute("data-dojo-type"));
+				if(type){
+					if(n._skip){
+						n._skip = "";
+						continue;
+					}
+					if(getCtor(type).prototype.stopParser && !(options && options.template)){
+						var arr = n.getElementsByTagName("*");
+						for(j = 0; j < arr.length; j++){
+							arr[j]._skip = "1";
+						}
+					}
 					list.push(n);
 				}
 			}
-			var mixin = args && args.template ? {template: true} : null;
-			return this.instantiate(list, mixin, args);
+			var mixin = options && options.template ? {template: true} : null;
+			return this.instantiate(list, mixin, options);
 		};
-	}();
+	};
+
+	// Singleton.   (TODO: replace parser class and singleton w/a simple hash of functions)
+	var parser = new Parser();
+
 	if(config.parseOnLoad){
-		ready(100, parser, "parse");
+		ready(100, function(){
+			// Now that all the modules are loaded, check if the app loaded dojo/parser too.
+			// If it did, let dojo/parser handle the parseOnLoad flag instead of me.
+			try{
+				if(!require("dojo/parser")){
+					// IE6 takes this path when dojo/parser unavailable, rather than catch() block below,
+					// due to http://support.microsoft.com/kb/944397
+					parser.parse();
+				}
+			}catch(e){
+				// Other browsers (and later versions of IE) take this path when dojo/parser unavailable
+				parser.parse();
+			}
+		});
 	}
 	dm.parser = parser; // for backward compatibility
-	dojo.parser = parser; // in case user application calls dojo.parser
+	dojo.parser = dojo.parser || parser; // in case user application calls dojo.parser
+
 	return parser;
 });
diff --git a/dojox/mobile/scrollable.js b/dojox/mobile/scrollable.js
old mode 100644
new mode 100755
index cd1d0de..d90a00f
--- a/dojox/mobile/scrollable.js
+++ b/dojox/mobile/scrollable.js
@@ -1,133 +1,3 @@
-//>>includeStart("standaloneScrollable", kwArgs.standaloneScrollable);
-
-// The code block surrounded by the includeStart/End pragma is to simulate
-// several dojo APIs that are used in this module for non-dojo applications.
-// For dojo applications, this code block is removed by the build tool.
-
-if(typeof define === "undefined"){ // assumes dojo.js is not loaded
-	dojo = {doc:document, global:window};
-	dojox = {mobile:{}};
-
-	dojo.has = function(name){
-		var ua = navigator.userAgent;
-		if(name === "webkit"){
-			return ua.indexOf("WebKit") != -1;
-		}
-		if(name === "android"){
-			return parseFloat(ua.split("Android ")[1]) || undefined;
-		}
-		if(name === "iphone"){
-			return ua.match(/(iPhone|iPod|iPad)/);
-		}
-		if(name === "ie"){
-			return parseFloat(ua.split("MSIE ")[1]) || undefined;
-		}
-		if(name === "touch"){
-			return (typeof dojo.doc.documentElement.ontouchstart != "undefined" &&
-				navigator.appVersion.indexOf("Mobile") != -1) || !!dojo.has("android");
-		}
-	};
-
-	dojo.stopEvent = function(evt){
-		if(evt.preventDefault){
-			evt.preventDefault();
-			evt.stopPropagation();
-		}else{
-			evt.cancelBubble = true;
-		}
-		return false;
-	};
-
-	dojo.setStyle = function(node, style, value){
-		if(typeof style === "string"){
-			var obj = {};
-			obj[style] = value;
-			style = obj;
-		}
-		for(var s in style){
-			if(style.hasOwnProperty(s)){
-				node.style[s] = style[s];
-				if(s === "opacity" && typeof(node.style.filter) !== "undefined"){
-					node.style.filter = " progid:DXImageTransform.Microsoft.alpha(opacity="+ (style[s]*100) +")";
-				}
-			}
-		}
-	};
-
-	dojo.create = function(tag, attrs, refNode){
-		return refNode.appendChild(dojo.doc.createElement(tag));
-	};
-
-	dojo.hasClass = function(node, s){
-		return (node.className.indexOf(s) != -1);
-	};
-	dojo.addClass = function(node, s){
-		if(!dojo.hasClass(node, s)){
-			node.className += " " + s;
-		}
-	};
-	dojo.removeClass = function(node, s){
-		node.className = node.className.replace(" " + s, "");
-	};
-
-	dojo.connect = function(node, eventName, scope, method){
-		var handler = function(e){
-			e = e || dojo.global.event;
-			if(!e.target){
-				e.target = e.srcElement;
-				e.pageX = e.offsetX;
-				e.pageY = e.offsetY;
-			}
-			scope[method](e);
-		};
-		if(node.addEventListener){
-			node.addEventListener(eventName.replace(/^on/,""), handler, false);
-		}else{
-			node.attachEvent(eventName, handler);
-		}
-		return {node:node, eventName:eventName, handler:handler};
-	};
-	dojo.disconnect = function(handle){
-		if(handle.node.removeEventListener){
-			handle.node.removeEventListener(handle.eventName.replace(/^on/,""), handle.handler, false);
-		}else{
-			handle.node.detachEvent(handle.eventName, handle.handler);
-		}
-	};
-
-	define = function(module, deps, def){
-		var _def = (arguments.length === 2) ? arguments[1] : arguments[2];
-		_def(
-			dojo, // dojo
-			{ // connect
-				connect: dojo.connect,
-				disconnect: dojo.disconnect
-			},
-			{ // event
-				stop: dojo.stopEvent
-			},
-			{ // lang
-				getObject: function(){}
-			},
-			dojo, // win
-			{ // domClass
-				contains: dojo.hasClass,
-				add: dojo.addClass,
-				remove: dojo.removeClass
-			},
-			{ // domConstruct
-				create: dojo.create
-			},
-			{ // domStyle
-				set: dojo.setStyle
-			},
-			dojo.has // has
-		);
-	};
-}
-//>>includeEnd("standaloneScrollable");
-
-
 define([
 	"dojo/_base/kernel",
 	"dojo/_base/connect",
@@ -137,1112 +7,1455 @@ define([
 	"dojo/dom-class",
 	"dojo/dom-construct",
 	"dojo/dom-style",
-	"./sniff"
-], function(dojo, connect, event, lang, win, domClass, domConstruct, domStyle, has){
+	"dojo/dom-geometry",
+	"dojo/touch",
+	"./sniff",
+	"./_css3",
+	"./_maskUtils"
+], function(dojo, connect, event, lang, win, domClass, domConstruct, domStyle,
+			domGeom, touch, has, css3, maskUtils){
 
-	var dm = lang.getObject("dojox.mobile", true);
+	// module:
+	//		dojox/mobile/scrollable
 
-/*=====
-// summary:
-//		Utility for enabling touch scrolling capability.
-// description:
-//		Mobile WebKit browsers do not allow scrolling inner DIVs. (You need
-//		the two-finger operation to scroll them.)
-//		That means you cannot have fixed-positioned header/footer bars.
-//		To solve this issue, this module disables the browsers default scrolling
-//		behavior, and re-builds its own scrolling machinery by handling touch
-//		events. In this module, this.domNode has height "100%" and is fixed to
-//		the window, and this.containerNode scrolls. If you place a bar outside
-//		of this.containerNode, then it will be fixed-positioned while
-//		this.containerNode is scrollable.
-//
-//		This module has the following features:
-//		- Scrolls inner DIVs vertically, horizontally, or both.
-//		- Vertical and horizontal scroll bars.
-//		- Flashes the scroll bars when a view is shown.
-//		- Simulates the flick operation using animation.
-//		- Respects header/footer bars if any.
-//
-//		dojox.mobile.scrollable is a simple function object, which holds
-//		several properties and functions in it. But if you transform it to a
-//		dojo class, it can be used as a mix-in class for any custom dojo
-//		widgets. dojox.mobile._ScrollableMixin is such a class.
-//
-//		Also, it can be used even for non-dojo applications. In such cases,
-//		several dojo APIs used in this module, such as dojo.connect,
-//		dojo.create, etc., are re-defined so that the code works without dojo.
-//		When in dojo, of course those re-defined functions are not necessary.
-//		So, they are surrounded by the includeStart and includeEnd directives
-//		so that they can be excluded from the build.
-//
-//		If you use this module for non-dojo application, you need to explicitly
-//		assign your outer fixed node and inner scrollable node to this.domNode
-//		and this.containerNode respectively.
-//
-//		Non-dojo application should capture the onorientationchange or
-//		the onresize event and call resize() in the event handler.
-//
-// example:
-//		Use this module from a non-dojo applicatoin:
-//		| function onLoad(){
-//		| 	var scrollable = new dojox.mobile.scrollable(dojo, dojox);
-//		| 	scrollable.init({
-//		| 		domNode: "outer", // id or node
-//		| 		containerNode: "inner" // id or node
-//		| 	});
-//		| }
-//		| <body onload="onLoad()">
-//		| 	<h1 id="hd1" style="position:relative;width:100%;z-index:1;">
-//		| 		Fixed Header
-//		| 	</h1>
-//		| 	<div id="outer" style="position:relative;height:100%;overflow:hidden;">
-//		| 		<div id="inner" style="position:absolute;width:100%;">
-//		| 			... content ...
-//		| 		</div>
-//		| 	</div>
-//		| </body>
-=====*/
-
-var scrollable = function(/*Object?*/dojo, /*Object?*/dojox){
-	this.fixedHeaderHeight = 0; // height of a fixed header
-	this.fixedFooterHeight = 0; // height of a fixed footer
-	this.isLocalFooter = false; // footer is view-local (as opposed to application-wide)
-	this.scrollBar = true; // show scroll bar or not
-	this.scrollDir = "v"; // v: vertical, h: horizontal, vh: both, f: flip
-	this.weight = 0.6; // frictional drag
-	this.fadeScrollBar = true;
-	this.disableFlashScrollBar = false;
-	this.threshold = 4; // drag threshold value in pixels
-	this.constraint = true; // bounce back to the content area
-	this.touchNode = null; // a node that will have touch event handlers
-	this.isNested = false; // this scrollable's parent is also a scrollable
-	this.dirLock = false; // disable the move handler if scroll starts in the unexpected direction
-	this.height = ""; // explicitly specified height of this widget (ex. "300px")
-	this.androidWorkaroud = true; // workaround input field jumping issue
-
-//>>includeStart("standaloneScrollable", kwArgs.standaloneScrollable);
-	if(!dojo){ // namespace objects are not passed
-		dojo = window.dojo;
-		dojox = window.dojox;
-	}
-//>>includeEnd("standaloneScrollable");
-
-	this.init = function(/*Object?*/params){
-		if(params){
-			for(var p in params){
-				if(params.hasOwnProperty(p)){
-					this[p] = ((p == "domNode" || p == "containerNode") && typeof params[p] == "string") ?
-						win.doc.getElementById(params[p]) : params[p]; // mix-in params
-				}
-			}
-		}
-		this.touchNode = this.touchNode || this.containerNode;
-		this._v = (this.scrollDir.indexOf("v") != -1); // vertical scrolling
-		this._h = (this.scrollDir.indexOf("h") != -1); // horizontal scrolling
-		this._f = (this.scrollDir == "f"); // flipping views
-
-		this._ch = []; // connect handlers
-		this._ch.push(connect.connect(this.touchNode,
-			has('touch') ? "touchstart" : "onmousedown", this, "onTouchStart"));
-		if(has("webkit")){
-			this._ch.push(connect.connect(this.domNode, "webkitAnimationEnd", this, "onFlickAnimationEnd"));
-			this._ch.push(connect.connect(this.domNode, "webkitAnimationStart", this, "onFlickAnimationStart"));
-
-			this._aw = this.androidWorkaroud &&
-				has("android") >= 2.2 && has("android") < 3;
-			if(this._aw){
-				this._ch.push(connect.connect(win.global, "onresize", this, "onScreenSizeChanged"));
-				this._ch.push(connect.connect(win.global, "onfocus", this, function(e){
-					if(this.containerNode.style.webkitTransform){
-						this.stopAnimation();
-						this.toTopLeft();
-					}
-				}));
-				this._sz = this.getScreenSize();
-			}
+	// TODO: rename to Scrollable.js (capital S) for 2.0
 
-			// Creation of keyframes takes a little time. If they are created
-			// in a lazy manner, a slight delay is noticeable when you start
-			// scrolling for the first time. This is to create keyframes up front.
-			for(var i = 0; i < 3; i++){
-				this.setKeyframes(null, null, i);
-			}
-		}
-		// Workaround for iPhone flicker issue
-		if(has('iphone')){
-			domStyle.set(this.containerNode, "webkitTransform", "translate3d(0,0,0)");
-		}
-		
-		this._speed = {x:0, y:0};
-		this._appFooterHeight = 0;
-		if(this.isTopLevel() && !this.noResize){
-			this.resize();
-		}
-		var _this = this;
-		setTimeout(function(){
-			_this.flashScrollBar();
-		}, 600);
-	};
+	// TODO: shouldn't be referencing this dojox/mobile variable, would be better to require the mobile.js module
+	var dm = lang.getObject("dojox.mobile", true);
 
-	this.isTopLevel = function(){
-		// subclass may want to override
-		return true;
+	// feature detection
+	has.add("translate3d", function(){
+		if(has("css3-animations")){
+			var elem = win.doc.createElement("div");
+			elem.style[css3.name("transform")] = "translate3d(0px,1px,0px)";
+			win.doc.documentElement.appendChild(elem);
+			var v = win.doc.defaultView.getComputedStyle(elem, '')[css3.name("transform", true)];
+			var hasTranslate3d = v && v.indexOf("matrix") === 0;
+			win.doc.documentElement.removeChild(elem);
+			return hasTranslate3d;
+		}
+	});
+
+	var Scrollable = function(){
+		// summary:
+		//		Mixin for enabling touch scrolling capability.
+		// description:
+		//		Mixin for enabling touch scrolling capability.
+		//		Mobile WebKit browsers do not allow scrolling inner DIVs. (For instance,
+		//		on iOS you need the two-finger operation to scroll them.)
+		//		That means you cannot have fixed-positioned header/footer bars.
+		//		To solve this issue, this module disables the browsers default scrolling
+		//		behavior, and rebuilds its own scrolling machinery by handling touch
+		//		events. In this module, this.domNode has height "100%" and is fixed to
+		//		the window, and this.containerNode scrolls. If you place a bar outside
+		//		of this.containerNode, then it will be fixed-positioned while
+		//		this.containerNode is scrollable.
+		//
+		//		This module has the following features:
+		//
+		//		- Scrolls inner DIVs vertically, horizontally, or both.
+		//		- Vertical and horizontal scroll bars.
+		//		- Flashes the scroll bars when a view is shown.
+		//		- Simulates the flick operation using animation.
+		//		- Respects header/footer bars if any.
 	};
 
-	this.cleanup = function(){
-		if(this._ch){
-			for(var i = 0; i < this._ch.length; i++){
-				connect.disconnect(this._ch[i]);
-			}
-			this._ch = null;
-		}
-	};
+	lang.extend(Scrollable, {
+		// fixedHeaderHeight: Number
+		//		height of a fixed header
+		fixedHeaderHeight: 0,
 
-	this.findDisp = function(/*DomNode*/node){
-		// summary:
-		//		Finds the currently displayed view node from my sibling nodes.
-		if(!node.parentNode){ return null; }
-		var nodes = node.parentNode.childNodes;
-		for(var i = 0; i < nodes.length; i++){
-			var n = nodes[i];
-			if(n.nodeType === 1 && domClass.contains(n, "mblView") && n.style.display !== "none"){
-				return n;
-			}
-		}
-		return node;
-	};
+		// fixedFooterHeight: Number
+		//		height of a fixed footer
+		fixedFooterHeight: 0,
 
-	this.getScreenSize = function(){
-		// summary:
-		//		Returns the dimensions of the browser window.
-		return {
-			h: win.global.innerHeight||win.doc.documentElement.clientHeight||win.doc.documentElement.offsetHeight,
-			w: win.global.innerWidth||win.doc.documentElement.clientWidth||win.doc.documentElement.offsetWidth
-		};
-	};
+		// isLocalFooter: Boolean
+		//		footer is view-local (as opposed to application-wide)
+		isLocalFooter: false,
 
-	this.isKeyboardShown = function(e){
-		// summary:
-		//		Internal function for android workaround.
-		// description:
-		//		Returns true if a virtual keyboard is shown.
-		//		Indirectly detects whether a virtual keyboard is shown or not by
-		//		examining the screen size.
-		// TODO: need more reliable detection logic
-		if(!this._sz){ return false; }
-		var sz = this.getScreenSize();
-		return (sz.w * sz.h) / (this._sz.w * this._sz.h) < 0.8;
-	};
+		// scrollBar: Boolean
+		//		show scroll bar or not
+		scrollBar: true,
 
-	this.disableScroll = function(/*Boolean*/v){
-		// summary:
-		//		Internal function for android workaround.
-		// description:
-		//		Disables the touch scrolling and enables the browser's default
-		//		scrolling.
-		if(this.disableTouchScroll === v || this.domNode.style.display === "none"){ return; }
-		this.disableTouchScroll = v;
-		this.scrollBar = !v;
-		dm.disableHideAddressBar = dm.disableResizeAll = v;
-		var of = v ? "visible" : "hidden";
-		domStyle.set(this.domNode, "overflow", of);
-		domStyle.set(win.doc.documentElement, "overflow", of);
-		domStyle.set(win.body(), "overflow", of);
-		var c = this.containerNode;
-		if(v){
-			if(!c.style.webkitTransform){
-				// stop animation when soft keyborad is shown before animation ends.
-				// TODO: there might be a better way to wait for animation ending.
-				this.stopAnimation();
-				this.toTopLeft();
-			}
-			var mt = parseInt(c.style.marginTop) || 0;
-			var h = c.offsetHeight + mt + this.fixedFooterHeight - this._appFooterHeight;
-			domStyle.set(this.domNode, "height", h + "px");
-			
-			this._cPos = { // store containerNode's position
-				x: parseInt(c.style.left) || 0,
-				y: parseInt(c.style.top) || 0
-			};
-			domStyle.set(c, {
-				top: "0px",
-				left: "0px"
-			});
-			
-			var a = win.doc.activeElement; // focused input field
-			if(a){ // scrolling to show focused input field
-				var at = 0; // top position of focused input field
-				for(var n = a; n.tagName != "BODY"; n = n.offsetParent){
-					at += n.offsetTop;
-				}
-				var st = at + a.clientHeight + 10 - this.getScreenSize().h; // top postion of browser scroll bar
-				if(st > 0){
-					win.body().scrollTop = st;
-				}
-			}	
-		}else{
-			if(this._cPos){ // restore containerNode's position
-				domStyle.set(c, {
-					top: this._cPos.y + "px",
-					left: this._cPos.x + "px"
-				});
-				this._cPos = null;
-			}
-			var tags = this.domNode.getElementsByTagName("*");
-			for(var i = 0; i < tags.length; i++){
-				tags[i].blur && tags[i].blur();
-			}
-			// Call dojox.mobile.resizeAll if exists.
-			dm.resizeAll && dm.resizeAll();
-		}
-	};
+		// scrollDir: String
+		//		v: vertical, h: horizontal, vh: both, f: flip
+		scrollDir: "v",
 
-	this.onScreenSizeChanged = function(e){
-		// summary:
-		//		Internal function for android workaround.
-		var sz = this.getScreenSize();
-		if(sz.w * sz.h > this._sz.w * this._sz.h){
-			this._sz = sz; // update the screen size
-		}
-		this.disableScroll(this.isKeyboardShown());
-	};
+		// weight: Number
+		//		frictional drag
+		weight: 0.6,
 
-	this.toTransform = function(e){
-		// summary:
-		//		Internal function for android workaround.
-		var c = this.containerNode;
-		if(c.offsetTop === 0 && c.offsetLeft === 0 || !c._webkitTransform){ return; }
-		domStyle.set(c, {
-			webkitTransform: c._webkitTransform,
-			top: "0px",
-			left: "0px"
-		});
-		c._webkitTransform = null;
-	};
+		// fadeScrollBar: Boolean
+		fadeScrollBar: true,
 
-	this.toTopLeft = function(){
-		// summary:
-		//		Internal function for android workaround.
-		var c = this.containerNode;
-		if(!c.style.webkitTransform){ return; } // already converted to top/left
-		c._webkitTransform = c.style.webkitTransform;
-		var pos = this.getPos();
-		domStyle.set(c, {
-			webkitTransform: "",
-			top: pos.y + "px",
-			left: pos.x + "px"
-		});
-	};
-	
-	this.resize = function(e){
-		// summary:
-		//		Adjusts the height of the widget.
-		// description:
-		//		If the height property is 'inherit', the height is inherited
-		//		from its offset parent. If 'auto', the content height, which
-		//		could be smaller than the entire screen height, is used. If an
-		//		explicit height value (ex. "300px"), it is used as the new
-		//		height. If nothing is specified as the height property, from the
-		//		current top position of the widget to the bottom of the screen
-		//		will be the new height.
-
-		// moved from init() to support dynamically added fixed bars
-		this._appFooterHeight = (this.fixedFooterHeight && !this.isLocalFooter) ?
-			this.fixedFooterHeight : 0;
-		if(this.isLocalHeader){
-			this.containerNode.style.marginTop = this.fixedHeaderHeight + "px";
-		}
+		// disableFlashScrollBar: Boolean
+		disableFlashScrollBar: false,
 
-		// Get the top position. Same as dojo.position(node, true).y
-		var top = 0;
-		for(var n = this.domNode; n && n.tagName != "BODY"; n = n.offsetParent){
-			n = this.findDisp(n); // find the first displayed view node
-			if(!n){ break; }
-			top += n.offsetTop;
-		}
+		// threshold: Number
+		//		drag threshold value in pixels
+		threshold: 4,
+
+		// constraint: Boolean
+		//		bounce back to the content area
+		constraint: true,
+
+		// touchNode: DOMNode
+		//		a node that will have touch event handlers
+		touchNode: null,
+
+		// propagatable: Boolean
+		//		let touchstart event propagate up
+		propagatable: true,
+
+		// dirLock: Boolean
+		//		disable the move handler if scroll starts in the unexpected direction
+		dirLock: false,
 
-		// adjust the height of this view
-		var	h,
-			screenHeight = this.getScreenSize().h,
-			dh = screenHeight - top - this._appFooterHeight; // default height
-		if(this.height === "inherit"){
-			if(this.domNode.offsetParent){
-				h = this.domNode.offsetParent.offsetHeight + "px";
-			}
-		}else if(this.height === "auto"){
-			var parent = this.domNode.offsetParent;
-			if(parent){
-				this.domNode.style.height = "0px";
-				var	parentRect = parent.getBoundingClientRect(),
-					scrollableRect = this.domNode.getBoundingClientRect(),
-					contentBottom = parentRect.bottom - this._appFooterHeight;
-				if(scrollableRect.bottom >= contentBottom){ // use entire screen
-					dh = screenHeight - (scrollableRect.top - parentRect.top) - this._appFooterHeight;
-				}else{ // stretch to fill predefined area
-					dh = contentBottom - scrollableRect.bottom;
+		// height: String
+		//		explicitly specified height of this widget (ex. "300px")
+		height: "",
+
+		// scrollType: Number
+		//		- 1: use -webkit-transform:translate3d(x,y,z) style, use -webkit-animation for slide anim
+		//		- 2: use top/left style,
+		//		- 3: use -webkit-transform:translate3d(x,y,z) style, use -webkit-transition for slide anim
+		//		- 0: use default value (2 in case of Android < 3, 3 if iOS6, otherwise 1)
+		scrollType: 0,
+		
+		// for Tooltip.js
+		_parentPadBorderExtentsBottom: 0,
+		
+		init: function(/*Object?*/params){
+			// summary:
+			//		Initialize according to the given params.
+			// description:
+			//		Mixes in the given params into this instance. At least domNode
+			//		and containerNode have to be given.
+			//		Starts listening to the touchstart events.
+			//		Calls resize(), if this widget is a top level widget.
+			if(params){
+				for(var p in params){
+					if(params.hasOwnProperty(p)){
+						this[p] = ((p == "domNode" || p == "containerNode") && typeof params[p] == "string") ?
+							win.doc.getElementById(params[p]) : params[p]; // mix-in params
+					}
+				}
+			}
+			// prevent browser scrolling on IE10 (evt.preventDefault() is not enough)
+			if(typeof this.domNode.style.msTouchAction != "undefined"){
+				this.domNode.style.msTouchAction = "none";
+			}
+			this.touchNode = this.touchNode || this.containerNode;
+			this._v = (this.scrollDir.indexOf("v") != -1); // vertical scrolling
+			this._h = (this.scrollDir.indexOf("h") != -1); // horizontal scrolling
+			this._f = (this.scrollDir == "f"); // flipping views
+
+			this._ch = []; // connect handlers
+			this._ch.push(connect.connect(this.touchNode, touch.press, this, "onTouchStart"));
+			if(has("css3-animations")){
+				// flag for whether to use -webkit-transform:translate3d(x,y,z) or top/left style.
+				// top/left style works fine as a workaround for input fields auto-scrolling issue,
+				// so use top/left in case of Android by default.
+				this._useTopLeft = this.scrollType ? this.scrollType === 2 : has('android') < 3;
+				// Flag for using webkit transition on transform, instead of animation + keyframes.
+				// (keyframes create a slight delay before the slide animation...)
+				if(!this._useTopLeft){
+					this._useTransformTransition = this.scrollType ? this.scrollType === 3 : has("ios") >= 6;
+				}
+				if(!this._useTopLeft){
+					if(this._useTransformTransition){
+						this._ch.push(connect.connect(this.domNode, css3.name("transitionEnd"), this, "onFlickAnimationEnd"));
+						this._ch.push(connect.connect(this.domNode, css3.name("transitionStart"), this, "onFlickAnimationStart"));
+					}else{
+						this._ch.push(connect.connect(this.domNode, css3.name("animationEnd"), this, "onFlickAnimationEnd"));
+						this._ch.push(connect.connect(this.domNode, css3.name("animationStart"), this, "onFlickAnimationStart"));
+	
+						// Creation of keyframes takes a little time. If they are created
+						// in a lazy manner, a slight delay is noticeable when you start
+						// scrolling for the first time. This is to create keyframes up front.
+						for(var i = 0; i < 3; i++){
+							this.setKeyframes(null, null, i);
+						}
+					}
+					if(has("translate3d")){ // workaround for flicker issue on iPhone and Android 3.x/4.0
+						domStyle.set(this.containerNode, css3.name("transform"), "translate3d(0,0,0)");
+					}
+				}else{
+					this._ch.push(connect.connect(this.domNode, css3.name("transitionEnd"), this, "onFlickAnimationEnd"));
+					this._ch.push(connect.connect(this.domNode, css3.name("transitionStart"), this, "onFlickAnimationStart"));
 				}
 			}
-			// content could be smaller than entire screen height
-			var contentHeight = Math.max(this.domNode.scrollHeight, this.containerNode.scrollHeight);
-			h = (contentHeight ? Math.min(contentHeight, dh) : dh) + "px";
-		}else if(this.height){
-			h = this.height;
-		}
-		if(!h){
-			h = dh + "px";
-		}
-		if(h.charAt(0) !== "-" && // to ensure that h is not negative (e.g. "-10px")
-			h !== "default"){
-			this.domNode.style.height = h;
-		}
 
-		// to ensure that the view is within a scrolling area when resized.
-		this.onTouchEnd();
-	};
+			this._speed = {x:0, y:0};
+			this._appFooterHeight = 0;
+			if(this.isTopLevel() && !this.noResize){
+				this.resize();
+			}
+			var _this = this;
+			setTimeout(function(){ 
+				// Why not using widget.defer() instead of setTimeout()? Because this module
+				// is not always mixed into a widget (ex. dojox/mobile/_ComboBoxMenu), and adding 
+				// a check to call either defer or setTimeout has been considered overkill.
+				_this.flashScrollBar();
+			}, 600);
+			
+			// #16363: while navigating among input field using TAB (desktop keyboard) or 
+			// NEXT (mobile soft keyboard), domNode.scrollTop gets modified (this holds even 
+			// if the text widget has selectOnFocus at false, that is even if dijit's _FormWidgetMixin._onFocus 
+			// does not trigger a global scrollIntoView). This messes up ScrollableView's own 
+			// scrolling machinery. To avoid this misbehavior:
+			if(win.global.addEventListener){ // all supported browsers but IE8
+				// (for IE8, using attachEvent is not a solution, because it only works in bubbling phase)
+				this._onScroll = function(e){
+					if(!_this.domNode || _this.domNode.style.display === 'none'){ return; }
+					var scrollTop = _this.domNode.scrollTop;
+					var scrollLeft = _this.domNode.scrollLeft; 
+					var pos;
+					if(scrollTop > 0 || scrollLeft > 0){ 
+						pos = _this.getPos(); 
+						// Reset to zero while compensating using our own scroll: 
+						_this.domNode.scrollLeft = 0; 
+						_this.domNode.scrollTop = 0; 
+						_this.scrollTo({x: pos.x - scrollLeft, y: pos.y - scrollTop}); // no animation 
+					}
+				};
+				win.global.addEventListener("scroll", this._onScroll, true);
+			}
+			// #17062: Ensure auto-scroll when navigating focusable fields
+			if(!this.disableTouchScroll && this.domNode.addEventListener){
+				this._onFocusScroll = function(e){
+					if(!_this.domNode || _this.domNode.style.display === 'none'){ return; }
+					var node = win.doc.activeElement;
+					var nodeRect, scrollableRect;
+					if(node){
+						nodeRect = node.getBoundingClientRect();
+						scrollableRect = _this.domNode.getBoundingClientRect();
+						if(nodeRect.height < _this.getDim().d.h){
+							// do not call scrollIntoView for elements with a height
+							// larger than the height of scrollable's content display
+							// area (it would be ergonomically harmful).
+							
+							if(nodeRect.top < (scrollableRect.top + _this.fixedHeaderHeight)){
+								// scrolling towards top (to bring into the visible area an element
+								// located above it).
+								_this.scrollIntoView(node, true);
+							}else if((nodeRect.top + nodeRect.height) > 
+								(scrollableRect.top + scrollableRect.height - _this.fixedFooterHeight)){
+								// scrolling towards bottom (to bring into the visible area an element
+								// located below it).
+								_this.scrollIntoView(node, false);
+							} // else do nothing (the focused node is already visible)
+						}
+					}
+				};
+				this.domNode.addEventListener("focus", this._onFocusScroll, true);
+			}
+		},
+
+		isTopLevel: function(){
+			// summary:
+			//		Returns true if this is a top-level widget.
+			// description:
+			//		Subclass may want to override.
+			return true;
+		},
+
+		cleanup: function(){
+			// summary:
+			//		Uninitialize the module.
+			if(this._ch){
+				for(var i = 0; i < this._ch.length; i++){
+					connect.disconnect(this._ch[i]);
+				}
+				this._ch = null;
+			}
+			if(this._onScroll && win.global.removeEventListener){ // all supported browsers but IE8
+				win.global.removeEventListener("scroll", this._onScroll, true);
+				this._onScroll = null;
+			}
+			
+			if(this._onFocusScroll && this.domNode.removeEventListener){
+				this.domNode.removeEventListener("focus", this._onFocusScroll, true);
+				this._onFocusScroll = null;
+			} 
+		},
+
+		findDisp: function(/*DomNode*/node){
+			// summary:
+			//		Finds the currently displayed view node from my sibling nodes.
+			if(!node.parentNode){ return null; }
+
+			// the given node is the first candidate
+			if(node.nodeType === 1 && domClass.contains(node, "mblSwapView") && node.style.display !== "none"){
+				return node;
+			}
 
-	this.onFlickAnimationStart = function(e){
-		event.stop(e);
-	};
+			var nodes = node.parentNode.childNodes;
+			for(var i = 0; i < nodes.length; i++){
+				var n = nodes[i];
+				if(n.nodeType === 1 && domClass.contains(n, "mblView") && n.style.display !== "none"){
+					return n;
+				}
+			}
+			return node;
+		},
+
+		getScreenSize: function(){
+			// summary:
+			//		Returns the dimensions of the browser window.
+			return {
+				h: win.global.innerHeight||win.doc.documentElement.clientHeight||win.doc.documentElement.offsetHeight,
+				w: win.global.innerWidth||win.doc.documentElement.clientWidth||win.doc.documentElement.offsetWidth
+			};
+		},
+
+		resize: function(e){
+			// summary:
+			//		Adjusts the height of the widget.
+			// description:
+			//		If the height property is 'inherit', the height is inherited
+			//		from its offset parent. If 'auto', the content height, which
+			//		could be smaller than the entire screen height, is used. If an
+			//		explicit height value (ex. "300px"), it is used as the new
+			//		height. If nothing is specified as the height property, from the
+			//		current top position of the widget to the bottom of the screen
+			//		will be the new height.
+
+			// moved from init() to support dynamically added fixed bars
+			this._appFooterHeight = (this._fixedAppFooter) ? this._fixedAppFooter.offsetHeight : 0;
+			if(this.isLocalHeader){
+				this.containerNode.style.marginTop = this.fixedHeaderHeight + "px";
+			}
 
-	this.onFlickAnimationEnd = function(e){
-		var an = e && e.animationName;
-		if(an && an.indexOf("scrollableViewScroll2") === -1){
-			if(an.indexOf("scrollableViewScroll0") !== -1){ // scrollBarV
-				domClass.remove(this._scrollBarNodeV, "mblScrollableScrollTo0");
-			}else if(an.indexOf("scrollableViewScroll1") !== -1){ // scrollBarH
-				domClass.remove(this._scrollBarNodeH, "mblScrollableScrollTo1");
-			}else{ // fade or others
-				if(this._scrollBarNodeV){ this._scrollBarNodeV.className = ""; }
-				if(this._scrollBarNodeH){ this._scrollBarNodeH.className = ""; }
+			// Get the top position. Same as dojo.position(node, true).y
+			var top = 0;
+			for(var n = this.domNode; n && n.tagName != "BODY"; n = n.offsetParent){
+				n = this.findDisp(n); // find the first displayed view node
+				if(!n){ break; }
+				top += n.offsetTop + domGeom.getBorderExtents(n).h;
 			}
-			return;
-		}
-		if(e && e.srcElement){
-			event.stop(e);
-		}
-		this.stopAnimation();
-		if(this._bounce){
-			var _this = this;
-			var bounce = _this._bounce;
-			setTimeout(function(){
-				_this.slideTo(bounce, 0.3, "ease-out");
-			}, 0);
-			_this._bounce = undefined;
-		}else{
-			this.hideScrollBar();
-			this.removeCover();
-			if(this._aw){ this.toTopLeft(); } // android workaround
-		}
-	};
 
-	this.isFormElement = function(node){
-		if(node && node.nodeType !== 1){ node = node.parentNode; }
-		if(!node || node.nodeType !== 1){ return false; }
-		var t = node.tagName;
-		return (t === "SELECT" || t === "INPUT" || t === "TEXTAREA" || t === "BUTTON");
-	};
+			// adjust the height of this view
+			var	h,
+				screenHeight = this.getScreenSize().h,
+				dh = screenHeight - top - this._appFooterHeight; // default height
+			if(this.height === "inherit"){
+				if(this.domNode.offsetParent){
+					h = domGeom.getContentBox(this.domNode.offsetParent).h - domGeom.getBorderExtents(this.domNode).h + "px";
+				}
+			}else if(this.height === "auto"){
+				var parent = this.domNode.offsetParent;
+				if(parent){
+					this.domNode.style.height = "0px";
+					var	parentRect = parent.getBoundingClientRect(),
+						scrollableRect = this.domNode.getBoundingClientRect(),
+						contentBottom = parentRect.bottom - this._appFooterHeight - this._parentPadBorderExtentsBottom;
+					if(scrollableRect.bottom >= contentBottom){ // use entire screen
+						dh = screenHeight - (scrollableRect.top - parentRect.top) - this._appFooterHeight - this._parentPadBorderExtentsBottom;
+					}else{ // stretch to fill predefined area
+						dh = contentBottom - scrollableRect.bottom;
+					}
+				}
+				// content could be smaller than entire screen height
+				var contentHeight = Math.max(this.domNode.scrollHeight, this.containerNode.scrollHeight);
+				h = (contentHeight ? Math.min(contentHeight, dh) : dh) + "px";
+			}else if(this.height){
+				h = this.height;
+			}
+			if(!h){
+				h = dh + "px";
+			}
+			if(h.charAt(0) !== "-" && // to ensure that h is not negative (e.g. "-10px")
+				h !== "default"){
+				this.domNode.style.height = h;
+			}
 
-	this.onTouchStart = function(e){
-		if(this.disableTouchScroll){ return; }
-		if(this._conn && (new Date()).getTime() - this.startTime < 500){
-			return; // ignore successive onTouchStart calls
-		}
-		if(!this._conn){
-			this._conn = [];
-			this._conn.push(connect.connect(win.doc, has('touch') ? "touchmove" : "onmousemove", this, "onTouchMove"));
-			this._conn.push(connect.connect(win.doc, has('touch') ? "touchend" : "onmouseup", this, "onTouchEnd"));
-		}
+			if(!this._conn){
+				// to ensure that the view is within a scrolling area when resized.
+				this.onTouchEnd();
+			}
+		},
 
-		this._aborted = false;
-		if(domClass.contains(this.containerNode, "mblScrollableScrollTo2")){
-			this.abort();
-		}else{ // reset scrollbar class especially for reseting fade-out animation
-			if(this._scrollBarNodeV){ this._scrollBarNodeV.className = ""; }
-			if(this._scrollBarNodeH){ this._scrollBarNodeH.className = ""; }
-		}
-		if(this._aw){ this.toTransform(e); } // android workaround
-		this.touchStartX = e.touches ? e.touches[0].pageX : e.clientX;
-		this.touchStartY = e.touches ? e.touches[0].pageY : e.clientY;
-		this.startTime = (new Date()).getTime();
-		this.startPos = this.getPos();
-		this._dim = this.getDim();
-		this._time = [0];
-		this._posX = [this.touchStartX];
-		this._posY = [this.touchStartY];
-		this._locked = false;
-
-		if(!this.isFormElement(e.target) && !this.isNested){
+		onFlickAnimationStart: function(e){
 			event.stop(e);
-		}
-	};
+		},
 
-	this.onTouchMove = function(e){
-		if(this._locked){ return; }
-		var x = e.touches ? e.touches[0].pageX : e.clientX;
-		var y = e.touches ? e.touches[0].pageY : e.clientY;
-		var dx = x - this.touchStartX;
-		var dy = y - this.touchStartY;
-		var to = {x:this.startPos.x + dx, y:this.startPos.y + dy};
-		var dim = this._dim;
-
-		dx = Math.abs(dx);
-		dy = Math.abs(dy);
-		if(this._time.length == 1){ // the first TouchMove after TouchStart
-			if(this.dirLock){
-				if(this._v && !this._h && dx >= this.threshold && dx >= dy ||
-					(this._h || this._f) && !this._v && dy >= this.threshold && dy >= dx){
-					this._locked = true;
+		onFlickAnimationEnd: function(e){
+			if(has("ios")){
+				this._keepInputCaretInActiveElement();
+			}
+			if(e){
+				var an = e.animationName;
+				if(an && an.indexOf("scrollableViewScroll2") === -1){
+					if(an.indexOf("scrollableViewScroll0") !== -1){ // scrollBarV
+						if(this._scrollBarNodeV){ domClass.remove(this._scrollBarNodeV, "mblScrollableScrollTo0"); }
+					}else if(an.indexOf("scrollableViewScroll1") !== -1){ // scrollBarH
+						if(this._scrollBarNodeH){ domClass.remove(this._scrollBarNodeH, "mblScrollableScrollTo1"); }
+					}else{ // fade or others
+						if(this._scrollBarNodeV){ this._scrollBarNodeV.className = ""; }
+						if(this._scrollBarNodeH){ this._scrollBarNodeH.className = ""; }
+					}
 					return;
 				}
+				if(this._useTransformTransition || this._useTopLeft){
+					var n = e.target;
+					if(n === this._scrollBarV || n === this._scrollBarH){
+						var cls = "mblScrollableScrollTo" + (n === this._scrollBarV ? "0" : "1");
+						if(domClass.contains(n, cls)){
+							domClass.remove(n, cls);
+						}else{
+							n.className = "";
+						}
+						return;
+					}
+				}
+				if(e.srcElement){
+					event.stop(e);
+				}
 			}
-			if(this._v && Math.abs(dy) < this.threshold ||
-				(this._h || this._f) && Math.abs(dx) < this.threshold){
-				return;
+			this.stopAnimation();
+			if(this._bounce){
+				var _this = this;
+				var bounce = _this._bounce;
+				setTimeout(function(){
+					_this.slideTo(bounce, 0.3, "ease-out");
+				}, 0);
+				_this._bounce = undefined;
+			}else{
+				this.hideScrollBar();
+				this.removeCover();
+			}
+		},
+
+		isFormElement: function(/*DOMNode*/node){
+			// summary:
+			//		Returns true if the given node is a form control.
+			if(node && node.nodeType !== 1){ node = node.parentNode; }
+			if(!node || node.nodeType !== 1){ return false; }
+			var t = node.tagName;
+			return (t === "SELECT" || t === "INPUT" || t === "TEXTAREA" || t === "BUTTON");
+		},
+
+		onTouchStart: function(e){
+			// summary:
+			//		User-defined function to handle touchStart events.
+			if(this.disableTouchScroll){ return; }
+			if(this._conn && (new Date()).getTime() - this.startTime < 500){
+				return; // ignore successive onTouchStart calls
+			}
+			if(!this._conn){
+				this._conn = [];
+				this._conn.push(connect.connect(win.doc, touch.move, this, "onTouchMove"));
+				this._conn.push(connect.connect(win.doc, touch.release, this, "onTouchEnd"));
 			}
-			this.addCover();
-			this.showScrollBar();
-		}
 
-		var weight = this.weight;
-		if(this._v && this.constraint){
-			if(to.y > 0){ // content is below the screen area
-				to.y = Math.round(to.y * weight);
-			}else if(to.y < -dim.o.h){ // content is above the screen area
-				if(dim.c.h < dim.d.h){ // content is shorter than display
-					to.y = Math.round(to.y * weight);
+			this._aborted = false;
+			if(domClass.contains(this.containerNode, "mblScrollableScrollTo2")){
+				this.abort();
+			}else{ // reset scrollbar class especially for reseting fade-out animation
+				if(this._scrollBarNodeV){ this._scrollBarNodeV.className = ""; }
+				if(this._scrollBarNodeH){ this._scrollBarNodeH.className = ""; }
+			}
+			this.touchStartX = e.touches ? e.touches[0].pageX : e.clientX;
+			this.touchStartY = e.touches ? e.touches[0].pageY : e.clientY;
+			this.startTime = (new Date()).getTime();
+			this.startPos = this.getPos();
+			this._dim = this.getDim();
+			this._time = [0];
+			this._posX = [this.touchStartX];
+			this._posY = [this.touchStartY];
+			this._locked = false;
+
+			if(!this.isFormElement(e.target)){
+				this.propagatable ? e.preventDefault() : event.stop(e);
+			}
+		},
+
+		onTouchMove: function(e){
+			// summary:
+			//		User-defined function to handle touchMove events.
+			if(this._locked){ return; }
+			var x = e.touches ? e.touches[0].pageX : e.clientX;
+			var y = e.touches ? e.touches[0].pageY : e.clientY;
+			var dx = x - this.touchStartX;
+			var dy = y - this.touchStartY;
+			var to = {x:this.startPos.x + dx, y:this.startPos.y + dy};
+			var dim = this._dim;
+
+			dx = Math.abs(dx);
+			dy = Math.abs(dy);
+			if(this._time.length == 1){ // the first TouchMove after TouchStart
+				if(this.dirLock){
+					if(this._v && !this._h && dx >= this.threshold && dx >= dy ||
+						(this._h || this._f) && !this._v && dy >= this.threshold && dy >= dx){
+						this._locked = true;
+						return;
+					}
+				}
+				if(this._v && this._h){ // scrollDir="hv"
+					if(dy < this.threshold &&
+					   dx < this.threshold){
+						return;
+					}
 				}else{
-					to.y = -dim.o.h - Math.round((-dim.o.h - to.y) * weight);
+					if(this._v && dy < this.threshold ||
+					   (this._h || this._f) && dx < this.threshold){
+						return;
+					}
 				}
+				this.addCover();
+				this.showScrollBar();
 			}
-		}
-		if((this._h || this._f) && this.constraint){
-			if(to.x > 0){
-				to.x = Math.round(to.x * weight);
-			}else if(to.x < -dim.o.w){
-				if(dim.c.w < dim.d.w){
+
+			var weight = this.weight;
+			if(this._v && this.constraint){
+				if(to.y > 0){ // content is below the screen area
+					to.y = Math.round(to.y * weight);
+				}else if(to.y < -dim.o.h){ // content is above the screen area
+					if(dim.c.h < dim.d.h){ // content is shorter than display
+						to.y = Math.round(to.y * weight);
+					}else{
+						to.y = -dim.o.h - Math.round((-dim.o.h - to.y) * weight);
+					}
+				}
+			}
+			if((this._h || this._f) && this.constraint){
+				if(to.x > 0){
 					to.x = Math.round(to.x * weight);
-				}else{
-					to.x = -dim.o.w - Math.round((-dim.o.w - to.x) * weight);
+				}else if(to.x < -dim.o.w){
+					if(dim.c.w < dim.d.w){
+						to.x = Math.round(to.x * weight);
+					}else{
+						to.x = -dim.o.w - Math.round((-dim.o.w - to.x) * weight);
+					}
 				}
 			}
-		}
-		this.scrollTo(to);
-
-		var max = 10;
-		var n = this._time.length; // # of samples
-		if(n >= 2){
-			// Check the direction of the finger move.
-			// If the direction has been changed, discard the old data.
-			var d0, d1;
-			if(this._v && !this._h){
-				d0 = this._posY[n - 1] - this._posY[n - 2];
-				d1 = y - this._posY[n - 1];
-			}else if(!this._v && this._h){
-				d0 = this._posX[n - 1] - this._posX[n - 2];
-				d1 = x - this._posX[n - 1];
-			}
-			if(d0 * d1 < 0){ // direction changed
-				// leave only the latest data
-				this._time = [this._time[n - 1]];
-				this._posX = [this._posX[n - 1]];
-				this._posY = [this._posY[n - 1]];
-				n = 1;
+			this.scrollTo(to);
+
+			var max = 10;
+			var n = this._time.length; // # of samples
+			if(n >= 2){
+				// Check the direction of the finger move.
+				// If the direction has been changed, discard the old data.
+				var d0, d1;
+				if(this._v && !this._h){
+					d0 = this._posY[n - 1] - this._posY[n - 2];
+					d1 = y - this._posY[n - 1];
+				}else if(!this._v && this._h){
+					d0 = this._posX[n - 1] - this._posX[n - 2];
+					d1 = x - this._posX[n - 1];
+				}
+				if(d0 * d1 < 0){ // direction changed
+					// leave only the latest data
+					this._time = [this._time[n - 1]];
+					this._posX = [this._posX[n - 1]];
+					this._posY = [this._posY[n - 1]];
+					n = 1;
+				}
 			}
-		}
-		if(n == max){
-			this._time.shift();
-			this._posX.shift();
-			this._posY.shift();
-		}
-		this._time.push((new Date()).getTime() - this.startTime);
-		this._posX.push(x);
-		this._posY.push(y);
-	};
+			if(n == max){
+				this._time.shift();
+				this._posX.shift();
+				this._posY.shift();
+			}
+			this._time.push((new Date()).getTime() - this.startTime);
+			this._posX.push(x);
+			this._posY.push(y);
+		},
+
+		_keepInputCaretInActiveElement: function(){
+			var activeElement = win.doc.activeElement;
+			var initialValue;
+			if(activeElement && (activeElement.tagName == "INPUT" || activeElement.tagName == "TEXTAREA")){
+				initialValue = activeElement.value;
+				if(activeElement.type == "number" || activeElement.type == "week"){
+					if(initialValue){
+						activeElement.value = activeElement.value + 1;
+					}else{
+						activeElement.value = (activeElement.type == "week") ? "2013-W10" : 1;
+					}
+					activeElement.value = initialValue;
+				}else{
+					activeElement.value = activeElement.value + " ";
+					activeElement.value = initialValue;
+				}
+			}
+		},
 
-	this.onTouchEnd = function(e){
-		if(this._locked){ return; }
-		var speed = this._speed = {x:0, y:0};
-		var dim = this._dim;
-		var pos = this.getPos();
-		var to = {}; // destination
-		if(e){
-			if(!this._conn){ return; } // if we get onTouchEnd without onTouchStart, ignore it.
-			for(var i = 0; i < this._conn.length; i++){
-				connect.disconnect(this._conn[i]);
-			}
-			this._conn = null;
-	
+		_fingerMovedSinceTouchStart: function(){
+			// summary:
+			//		Return true if the "finger" has moved since the touchStart, false otherwise.
 			var n = this._time.length; // # of samples
-			var clicked = false;
-			if(!this._aborted){
-				if(n <= 1){
-					clicked = true;
-				}else if(n == 2 && Math.abs(this._posY[1] - this._posY[0]) < 4
-					&& has('touch')){ // for desktop browsers, posY could be the same, since we're using clientY, see onTouchMove()
+			if(n <= 1 || (n == 2 && Math.abs(this._posY[1] - this._posY[0]) < 4 && has('touch'))){
+				return false;
+			}else{
+				return true;
+			}
+		},
+
+		onTouchEnd: function(/*Event*/e){
+			// summary:
+			//		User-defined function to handle touchEnd events.
+			if(this._locked){ return; }
+			var speed = this._speed = {x:0, y:0};
+			var dim = this._dim;
+			var pos = this.getPos();
+			var to = {}; // destination
+			if(e){
+				if(!this._conn){ return; } // if we get onTouchEnd without onTouchStart, ignore it.
+				for(var i = 0; i < this._conn.length; i++){
+					connect.disconnect(this._conn[i]);
+				}
+				this._conn = null;
+
+				var clicked = false;
+				if(!this._aborted && !this._fingerMovedSinceTouchStart()){
 					clicked = true;
 				}
-			}
-			var isFormElem = this.isFormElement(e.target);
-			if(clicked && !isFormElem){ // clicked, not dragged or flicked
-				this.hideScrollBar();
-				this.removeCover();
-				if(has('touch')){
-					var elem = e.target;
-					if(elem.nodeType != 1){
-						elem = elem.parentNode;
+				if(clicked){ // clicked, not dragged or flicked
+					this.hideScrollBar();
+					this.removeCover();
+					// need to send a synthetic click?
+					if(has("touch") && has("clicks-prevented") && !this.isFormElement(e.target)){
+						var elem = e.target;
+						if(elem.nodeType != 1){
+							elem = elem.parentNode;
+						}
+						setTimeout(function(){
+							dm._sendClick(elem, e);
+						});
 					}
-					var ev = win.doc.createEvent("MouseEvents");
-					ev.initMouseEvent("click", true, true, win.global, 1, e.screenX, e.screenY, e.clientX, e.clientY);
-					setTimeout(function(){
-						elem.dispatchEvent(ev);
-					}, 0);
+					return;
 				}
-				return;
-			}else if(this._aw && clicked && isFormElem){ // clicked input fields
-				this.hideScrollBar();
-				this.toTopLeft();
-				return;
+				speed = this._speed = this.getSpeed();
+			}else{
+				if(pos.x == 0 && pos.y == 0){ return; } // initializing
+				dim = this.getDim();
 			}
-			speed = this._speed = this.getSpeed();
-		}else{
-			if(pos.x == 0 && pos.y == 0){ return; } // initializing
-			dim = this.getDim();
-		}
 
-		if(this._v){
-			to.y = pos.y + speed.y;
-		}
-		if(this._h || this._f){
-			to.x = pos.x + speed.x;
-		}
+			if(this._v){
+				to.y = pos.y + speed.y;
+			}
+			if(this._h || this._f){
+				to.x = pos.x + speed.x;
+			}
 
-		this.adjustDestination(to, pos);
-
-		if(this.scrollDir == "v" && dim.c.h < dim.d.h){ // content is shorter than display
-			this.slideTo({y:0}, 0.3, "ease-out"); // go back to the top
-			return;
-		}else if(this.scrollDir == "h" && dim.c.w < dim.d.w){ // content is narrower than display
-			this.slideTo({x:0}, 0.3, "ease-out"); // go back to the left
-			return;
-		}else if(this._v && this._h && dim.c.h < dim.d.h && dim.c.w < dim.d.w){
-			this.slideTo({x:0, y:0}, 0.3, "ease-out"); // go back to the top-left
-			return;
-		}
+			if(this.adjustDestination(to, pos, dim) === false){ return; }
+			if(this.constraint){
+				if(this.scrollDir == "v" && dim.c.h < dim.d.h){ // content is shorter than display
+					this.slideTo({y:0}, 0.3, "ease-out"); // go back to the top
+					return;
+				}else if(this.scrollDir == "h" && dim.c.w < dim.d.w){ // content is narrower than display
+					this.slideTo({x:0}, 0.3, "ease-out"); // go back to the left
+					return;
+				}else if(this._v && this._h && dim.c.h < dim.d.h && dim.c.w < dim.d.w){
+					this.slideTo({x:0, y:0}, 0.3, "ease-out"); // go back to the top-left
+					return;
+				}
+			}
 
-		var duration, easing = "ease-out";
-		var bounce = {};
-		if(this._v && this.constraint){
-			if(to.y > 0){ // going down. bounce back to the top.
-				if(pos.y > 0){ // started from below the screen area. return quickly.
-					duration = 0.3;
-					to.y = 0;
+			var duration, easing = "ease-out";
+			var bounce = {};
+			if(this._v && this.constraint){
+				if(to.y > 0){ // going down. bounce back to the top.
+					if(pos.y > 0){ // started from below the screen area. return quickly.
+						duration = 0.3;
+						to.y = 0;
+					}else{
+						to.y = Math.min(to.y, 20);
+						easing = "linear";
+						bounce.y = 0;
+					}
+				}else if(-speed.y > dim.o.h - (-pos.y)){ // going up. bounce back to the bottom.
+					if(pos.y < -dim.o.h){ // started from above the screen top. return quickly.
+						duration = 0.3;
+						to.y = dim.c.h <= dim.d.h ? 0 : -dim.o.h; // if shorter, move to 0
+					}else{
+						to.y = Math.max(to.y, -dim.o.h - 20);
+						easing = "linear";
+						bounce.y = -dim.o.h;
+					}
+				}
+			}
+			if((this._h || this._f) && this.constraint){
+				if(to.x > 0){ // going right. bounce back to the left.
+					if(pos.x > 0){ // started from right of the screen area. return quickly.
+						duration = 0.3;
+						to.x = 0;
+					}else{
+						to.x = Math.min(to.x, 20);
+						easing = "linear";
+						bounce.x = 0;
+					}
+				}else if(-speed.x > dim.o.w - (-pos.x)){ // going left. bounce back to the right.
+					if(pos.x < -dim.o.w){ // started from left of the screen top. return quickly.
+						duration = 0.3;
+						to.x = dim.c.w <= dim.d.w ? 0 : -dim.o.w; // if narrower, move to 0
+					}else{
+						to.x = Math.max(to.x, -dim.o.w - 20);
+						easing = "linear";
+						bounce.x = -dim.o.w;
+					}
+				}
+			}
+			this._bounce = (bounce.x !== undefined || bounce.y !== undefined) ? bounce : undefined;
+
+			if(duration === undefined){
+				var distance, velocity;
+				if(this._v && this._h){
+					velocity = Math.sqrt(speed.x*speed.x + speed.y*speed.y);
+					distance = Math.sqrt(Math.pow(to.y - pos.y, 2) + Math.pow(to.x - pos.x, 2));
+				}else if(this._v){
+					velocity = speed.y;
+					distance = to.y - pos.y;
+				}else if(this._h){
+					velocity = speed.x;
+					distance = to.x - pos.x;
+				}
+				if(distance === 0 && !e){ return; } // #13154
+				duration = velocity !== 0 ? Math.abs(distance / velocity) : 0.01; // time = distance / velocity
+			}
+			this.slideTo(to, duration, easing);
+		},
+
+		adjustDestination: function(/*Object*/to, /*Object*/pos, /*Object*/dim){
+			// summary:
+			//		A stub function to be overridden by subclasses.
+			// description:
+			//		This function is called from onTouchEnd(). The purpose is to give its
+			//		subclasses a chance to adjust the destination position. If this
+			//		function returns false, onTouchEnd() returns immediately without
+			//		performing scroll.
+			// to:
+			//		The destination position. An object with x and y.
+			// pos:
+			//		The current position. An object with x and y.
+			// dim:
+			//		Dimension information returned by getDim().			
+
+			// subclass may want to implement
+			return true; // Boolean
+		},
+
+		abort: function(){
+			// summary:
+			//		Aborts scrolling.
+			// description:
+			//		This function stops the scrolling animation that is currently
+			//		running. It is called when the user touches the screen while
+			//		scrolling.
+			this._aborted = true;
+			this.scrollTo(this.getPos());
+			this.stopAnimation();
+		},
+		_forceRendering: function(elt){
+			// tags:
+			//		private
+			//		There are issues with Android > 3: No acceleration and no way to stop the scrolling.
+			//		This workaround improves the scrolling behaviour.
+			if(has("android") >= 4.1){
+				var tmp = elt.style.display;
+				elt.style.display = "none";
+				elt.offsetHeight; // Accessing offsetHeight forces the rendering
+				elt.style.display = tmp;
+			}
+		},
+		stopAnimation: function(){
+			// summary:
+			//		Stops the currently running animation.
+
+			this._forceRendering(this.containerNode);
+			domClass.remove(this.containerNode, "mblScrollableScrollTo2");
+			if(this._scrollBarV){
+				this._scrollBarV.className = "";
+				this._forceRendering(this._scrollBarV);
+			}
+			if(this._scrollBarH){
+				this._scrollBarH.className = "";
+				this._forceRendering(this._scrollBarH);
+			}
+			if(this._useTransformTransition || this._useTopLeft){
+				this.containerNode.style[css3.name("transition")] = "";
+				if(this._scrollBarV) { this._scrollBarV.style[css3.name("transition")] = ""; }
+				if(this._scrollBarH) { this._scrollBarH.style[css3.name("transition")] = ""; }
+			}
+		},
+
+		scrollIntoView: function(/*DOMNode*/node, /*Boolean?*/alignWithTop, /*Number?*/duration){
+			// summary:
+			//		Scrolls the pane until the searching node is in the view.
+			// node:
+			//		A DOM node to be searched for view.
+			// alignWithTop:
+			//		If true, aligns the node at the top of the pane.
+			//		If false, aligns the node at the bottom of the pane.
+			// duration:
+			//		Duration of scrolling in seconds. (ex. 0.3)
+			//		If not specified, scrolls without animation.
+			// description:
+			//		Just like the scrollIntoView method of DOM elements, this
+			//		function causes the given node to scroll into view, aligning it
+			//		either at the top or bottom of the pane.
+
+			if(!this._v){ return; } // cannot scroll vertically
+
+			var c = this.containerNode,
+				h = this.getDim().d.h, // the height of ScrollableView's content display area
+				top = 0;
+
+			// Get the top position of node relative to containerNode
+			for(var n = node; n !== c; n = n.offsetParent){
+				if(!n || n.tagName === "BODY"){ return; } // exit if node is not a child of scrollableView
+				top += n.offsetTop;
+			}
+			// Calculate scroll destination position
+			var y = alignWithTop ? Math.max(h - c.offsetHeight, -top) : Math.min(0, h - top - node.offsetHeight);
+
+			// Scroll to destination position
+			(duration && typeof duration === "number") ? 
+				this.slideTo({y: y}, duration, "ease-out") : this.scrollTo({y: y});
+		},
+
+		getSpeed: function(){
+			// summary:
+			//		Returns an object that indicates the scrolling speed.
+			// description:
+			//		From the position and elapsed time information, calculates the
+			//		scrolling speed, and returns an object with x and y.
+			var x = 0, y = 0, n = this._time.length;
+			// if the user holds the mouse or finger more than 0.5 sec, do not move.
+			if(n >= 2 && (new Date()).getTime() - this.startTime - this._time[n - 1] < 500){
+				var dy = this._posY[n - (n > 3 ? 2 : 1)] - this._posY[(n - 6) >= 0 ? n - 6 : 0];
+				var dx = this._posX[n - (n > 3 ? 2 : 1)] - this._posX[(n - 6) >= 0 ? n - 6 : 0];
+				var dt = this._time[n - (n > 3 ? 2 : 1)] - this._time[(n - 6) >= 0 ? n - 6 : 0];
+				y = this.calcSpeed(dy, dt);
+				x = this.calcSpeed(dx, dt);
+			}
+			return {x:x, y:y};
+		},
+
+		calcSpeed: function(/*Number*/distance, /*Number*/time){
+			// summary:
+			//		Calculate the speed given the distance and time.
+			return Math.round(distance / time * 100) * 4;
+		},
+
+		scrollTo: function(/*Object*/to, /*Boolean?*/doNotMoveScrollBar, /*DomNode?*/node){
+			// summary:
+			//		Scrolls to the given position immediately without animation.
+			// to:
+			//		The destination position. An object with x and y.
+			//		ex. {x:0, y:-5}
+			// doNotMoveScrollBar:
+			//		If true, the scroll bar will not be updated. If not specified,
+			//		it will be updated.
+			// node:
+			//		A DOM node to scroll. If not specified, defaults to
+			//		this.containerNode.
+
+			// scroll events
+			var scrollEvent, beforeTopHeight, afterBottomHeight;
+			var doScroll = true;
+			if(!this._aborted && this._conn){ // No scroll event if the call to scrollTo comes from abort or onTouchEnd
+				if(!this._dim){
+					this._dim = this.getDim();
+				}
+				beforeTopHeight = (to.y > 0)?to.y:0;
+				afterBottomHeight = (this._dim.o.h + to.y < 0)?-1 * (this._dim.o.h + to.y):0;
+				scrollEvent = {bubbles: false,
+						cancelable: false,
+						x: to.x,
+						y: to.y,
+						beforeTop: beforeTopHeight > 0,
+						beforeTopHeight: beforeTopHeight,
+						afterBottom: afterBottomHeight > 0,
+						afterBottomHeight: afterBottomHeight};
+				// before scroll event
+				doScroll = this.onBeforeScroll(scrollEvent);
+			}
+			
+			if(doScroll){
+				var s = (node || this.containerNode).style;
+				if(has("css3-animations")){
+					if(!this._useTopLeft){
+						if(this._useTransformTransition){
+							s[css3.name("transition")] = "";	
+						}
+						s[css3.name("transform")] = this.makeTranslateStr(to);
+					}else{
+						s[css3.name("transition")] = "";
+						if(this._v){
+							s.top = to.y + "px";
+						}
+						if(this._h || this._f){
+							s.left = to.x + "px";
+						}
+					}
 				}else{
-					to.y = Math.min(to.y, 20);
-					easing = "linear";
-					bounce.y = 0;
+					if(this._v){
+						s.top = to.y + "px";
+					}
+					if(this._h || this._f){
+						s.left = to.x + "px";
+					}
+				}
+				if(has("ios")){
+					this._keepInputCaretInActiveElement();
+				}
+				if(!doNotMoveScrollBar){
+					this.scrollScrollBarTo(this.calcScrollBarPos(to));
 				}
-			}else if(-speed.y > dim.o.h - (-pos.y)){ // going up. bounce back to the bottom.
-				if(pos.y < -dim.o.h){ // started from above the screen top. return quickly.
-					duration = 0.3;
-					to.y = dim.c.h <= dim.d.h ? 0 : -dim.o.h; // if shorter, move to 0
+				if(scrollEvent){
+					// After scroll event
+					this.onAfterScroll(scrollEvent);
+				}
+			}
+		},
+
+		onBeforeScroll: function(/*Event*/e){
+			// e: Event
+			//		the scroll event, that contains the following attributes:
+			//		x (x coordinate of the scroll destination),
+			//		y (y coordinate of the scroll destination),
+			//		beforeTop (a boolean that is true if the scroll detination is before the top of the scrollable),
+			//		beforeTopHeight (the number of pixels before the top of the scrollable for the scroll destination),
+			//		afterBottom (a boolean that is true if the scroll destination is after the bottom of the scrollable),
+			//		afterBottomHeight (the number of pixels after the bottom of the scrollable for the scroll destination)
+			// summary:
+			//		called before a scroll is initiated. If this method returns false,
+			//		the scroll is canceled.
+			// tags:
+			//		callback
+			return true;
+		},
+
+		onAfterScroll: function(/*Event*/e){
+			// e: Event
+			//		the scroll event, that contains the following attributes:
+			//		x (x coordinate of the scroll destination),
+			//		y (y coordinate of the scroll destination),
+			//		beforeTop (a boolean that is true if the scroll detination is before the top of the scrollable),
+			//		beforeTopHeight (the number of pixels before the top of the scrollable for the scroll destination),
+			//		afterBottom (a boolean that is true if the scroll destination is after the bottom of the scrollable),
+			//		afterBottomHeight (the number of pixels after the bottom of the scrollable for the scroll destination)
+			// summary:
+			//		called after a scroll has been performed.
+			// tags:
+			//		callback
+		},
+		
+		slideTo: function(/*Object*/to, /*Number*/duration, /*String*/easing){
+			// summary:
+			//		Scrolls to the given position with the slide animation.
+			// to:
+			//		The scroll destination position. An object with x and/or y.
+			//		ex. {x:0, y:-5}, {y:-29}, etc.
+			// duration:
+			//		Duration of scrolling in seconds. (ex. 0.3)
+			// easing:
+			//		The name of easing effect which webkit supports.
+			//		"ease", "linear", "ease-in", "ease-out", etc.
+
+			this._runSlideAnimation(this.getPos(), to, duration, easing, this.containerNode, 2);
+			this.slideScrollBarTo(to, duration, easing);
+		},
+
+		makeTranslateStr: function(/*Object*/to){
+			// summary:
+			//		Constructs a string value that is passed to the -webkit-transform property.
+			// to:
+			//		The destination position. An object with x and/or y.
+			// description:
+			//		Return value example: "translate3d(0px,-8px,0px)"
+
+			var y = this._v && typeof to.y == "number" ? to.y+"px" : "0px";
+			var x = (this._h||this._f) && typeof to.x == "number" ? to.x+"px" : "0px";
+			return has("translate3d") ?
+					"translate3d("+x+","+y+",0px)" : "translate("+x+","+y+")";
+		},
+
+		getPos: function(){
+			// summary:
+			//		Gets the top position in the midst of animation.
+			if(has("css3-animations")){
+				var s = win.doc.defaultView.getComputedStyle(this.containerNode, '');
+				if(!this._useTopLeft){
+					var m = s[css3.name("transform")];
+					if(m && m.indexOf("matrix") === 0){
+						var arr = m.split(/[,\s\)]+/);
+						// IE10 returns a matrix3d
+						var i = m.indexOf("matrix3d") === 0 ? 12 : 4;
+						return {y:arr[i+1] - 0, x:arr[i] - 0};
+					}
+					return {x:0, y:0};
 				}else{
-					to.y = Math.max(to.y, -dim.o.h - 20);
-					easing = "linear";
-					bounce.y = -dim.o.h;
+					return {x:parseInt(s.left) || 0, y:parseInt(s.top) || 0};
 				}
+			}else{
+				// this.containerNode.offsetTop does not work here,
+				// because it adds the height of the top margin.
+				var y = parseInt(this.containerNode.style.top) || 0;
+				return {y:y, x:this.containerNode.offsetLeft};
 			}
-		}
-		if((this._h || this._f) && this.constraint){
-			if(to.x > 0){ // going right. bounce back to the left.
-				if(pos.x > 0){ // started from right of the screen area. return quickly.
-					duration = 0.3;
-					to.x = 0;
+		},
+
+		getDim: function(){
+			// summary:
+			//		Returns various internal dimensional information needed for calculation.
+
+			var d = {};
+			// content width/height
+			d.c = {h:this.containerNode.offsetHeight, w:this.containerNode.offsetWidth};
+
+			// view width/height
+			d.v = {h:this.domNode.offsetHeight + this._appFooterHeight, w:this.domNode.offsetWidth};
+
+			// display width/height
+			d.d = {h:d.v.h - this.fixedHeaderHeight - this.fixedFooterHeight - this._appFooterHeight, w:d.v.w};
+
+			// overflowed width/height
+			d.o = {h:d.c.h - d.v.h + this.fixedHeaderHeight + this.fixedFooterHeight + this._appFooterHeight, w:d.c.w - d.v.w};
+			return d;
+		},
+
+		showScrollBar: function(){
+			// summary:
+			//		Shows the scroll bar.
+			// description:
+			//		This function creates the scroll bar instance if it does not
+			//		exist yet, and calls resetScrollBar() to reset its length and
+			//		position.
+
+			if(!this.scrollBar){ return; }
+
+			var dim = this._dim;
+			if(this.scrollDir == "v" && dim.c.h <= dim.d.h){ return; }
+			if(this.scrollDir == "h" && dim.c.w <= dim.d.w){ return; }
+			if(this._v && this._h && dim.c.h <= dim.d.h && dim.c.w <= dim.d.w){ return; }
+
+			var createBar = function(self, dir){
+				var bar = self["_scrollBarNode" + dir];
+				if(!bar){
+					var wrapper = domConstruct.create("div", null, self.domNode);
+					var props = { position: "absolute", overflow: "hidden" };
+					if(dir == "V"){
+						props.right = "2px";
+						props.width = "5px";
+					}else{
+						props.bottom = (self.isLocalFooter ? self.fixedFooterHeight : 0) + 2 + "px";
+						props.height = "5px";
+					}
+					domStyle.set(wrapper, props);
+					wrapper.className = "mblScrollBarWrapper";
+					self["_scrollBarWrapper"+dir] = wrapper;
+
+					bar = domConstruct.create("div", null, wrapper);
+					domStyle.set(bar, css3.add({
+						opacity: 0.6,
+						position: "absolute",
+						backgroundColor: "#606060",
+						fontSize: "1px",
+						MozBorderRadius: "2px",
+						zIndex: 2147483647 // max of signed 32-bit integer
+					}, {
+						borderRadius: "2px",
+						transformOrigin: "0 0"
+					}));
+					domStyle.set(bar, dir == "V" ? {width: "5px"} : {height: "5px"});
+					self["_scrollBarNode" + dir] = bar;
+				}
+				return bar;
+			};
+			if(this._v && !this._scrollBarV){
+				this._scrollBarV = createBar(this, "V");
+			}
+			if(this._h && !this._scrollBarH){
+				this._scrollBarH = createBar(this, "H");
+			}
+			this.resetScrollBar();
+		},
+
+		hideScrollBar: function(){
+			// summary:
+			//		Hides the scroll bar.
+			// description:
+			//		If the fadeScrollBar property is true, hides the scroll bar with
+			//		the fade animation.
+
+			if(this.fadeScrollBar && has("css3-animations")){
+				if(!dm._fadeRule){
+					var node = domConstruct.create("style", null, win.doc.getElementsByTagName("head")[0]);
+					node.textContent =
+						".mblScrollableFadeScrollBar{"+
+						"  " + css3.name("animation-duration", true) + ": 1s;"+
+						"  " + css3.name("animation-name", true) + ": scrollableViewFadeScrollBar;}"+
+						"@" + css3.name("keyframes", true) + " scrollableViewFadeScrollBar{"+
+						"  from { opacity: 0.6; }"+
+						"  to { opacity: 0; }}";
+					dm._fadeRule = node.sheet.cssRules[1];
+				}
+			}
+			if(!this.scrollBar){ return; }
+			var f = function(bar, self){
+				domStyle.set(bar, css3.add({
+					opacity: 0
+				}, {
+					animationDuration: ""
+				}));
+				// do not use fade animation in case of using top/left on Android
+				// since it causes screen flicker during adress bar's fading out
+				if(!(self._useTopLeft && has('android'))){
+					bar.className = "mblScrollableFadeScrollBar";
+				}
+			};
+			if(this._scrollBarV){
+				f(this._scrollBarV, this);
+				this._scrollBarV = null;
+			}
+			if(this._scrollBarH){
+				f(this._scrollBarH, this);
+				this._scrollBarH = null;
+			}
+		},
+
+		calcScrollBarPos: function(/*Object*/to){
+			// summary:
+			//		Calculates the scroll bar position.
+			// description:
+			//		Given the scroll destination position, calculates the top and/or
+			//		the left of the scroll bar(s). Returns an object with x and y.
+			// to:
+			//		The scroll destination position. An object with x and y.
+			//		ex. {x:0, y:-5}			
+
+			var pos = {};
+			var dim = this._dim;
+			var f = function(wrapperH, barH, t, d, c){
+				var y = Math.round((d - barH - 8) / (d - c) * t);
+				if(y < -barH + 5){
+					y = -barH + 5;
+				}
+				if(y > wrapperH - 5){
+					y = wrapperH - 5;
+				}
+				return y;
+			};
+			if(typeof to.y == "number" && this._scrollBarV){
+				pos.y = f(this._scrollBarWrapperV.offsetHeight, this._scrollBarV.offsetHeight, to.y, dim.d.h, dim.c.h);
+			}
+			if(typeof to.x == "number" && this._scrollBarH){
+				pos.x = f(this._scrollBarWrapperH.offsetWidth, this._scrollBarH.offsetWidth, to.x, dim.d.w, dim.c.w);
+			}
+			return pos;
+		},
+
+		scrollScrollBarTo: function(/*Object*/to){
+			// summary:
+			//		Moves the scroll bar(s) to the given position without animation.
+			// to:
+			//		The destination position. An object with x and/or y.
+			//		ex. {x:2, y:5}, {y:20}, etc.
+
+			if(!this.scrollBar){ return; }
+			if(this._v && this._scrollBarV && typeof to.y == "number"){
+				if(has("css3-animations")){
+					if(!this._useTopLeft){
+						if(this._useTransformTransition){
+							this._scrollBarV.style[css3.name("transition")] = "";
+						}
+						this._scrollBarV.style[css3.name("transform")] = this.makeTranslateStr({y:to.y});
+					}else{
+						domStyle.set(this._scrollBarV, css3.add({
+							top: to.y + "px"
+						}, {
+							transition: ""
+						}));
+					}
 				}else{
-					to.x = Math.min(to.x, 20);
-					easing = "linear";
-					bounce.x = 0;
+					this._scrollBarV.style.top = to.y + "px";
 				}
-			}else if(-speed.x > dim.o.w - (-pos.x)){ // going left. bounce back to the right.
-				if(pos.x < -dim.o.w){ // started from left of the screen top. return quickly.
-					duration = 0.3;
-					to.x = dim.c.w <= dim.d.w ? 0 : -dim.o.w; // if narrower, move to 0
+			}
+			if(this._h && this._scrollBarH && typeof to.x == "number"){
+				if(has("css3-animations")){
+					if(!this._useTopLeft){
+						if(this._useTransformTransition){
+							this._scrollBarH.style[css3.name("transition")] = "";
+						}
+						this._scrollBarH.style[css3.name("transform")] = this.makeTranslateStr({x:to.x});
+					}else{
+						domStyle.set(this._scrollBarH, css3.add({
+							left: to.x + "px"
+						}, {
+							transition: ""
+						}));
+					}
 				}else{
-					to.x = Math.max(to.x, -dim.o.w - 20);
-					easing = "linear";
-					bounce.x = -dim.o.w;
+					this._scrollBarH.style.left = to.x + "px";
 				}
 			}
-		}
-		this._bounce = (bounce.x !== undefined || bounce.y !== undefined) ? bounce : undefined;
-
-		if(duration === undefined){
-			var distance, velocity;
-			if(this._v && this._h){
-				velocity = Math.sqrt(speed.x+speed.x + speed.y*speed.y);
-				distance = Math.sqrt(Math.pow(to.y - pos.y, 2) + Math.pow(to.x - pos.x, 2));
-			}else if(this._v){
-				velocity = speed.y;
-				distance = to.y - pos.y;
-			}else if(this._h){
-				velocity = speed.x;
-				distance = to.x - pos.x;
-			}
-			if(distance === 0 && !e){ return; } // #13154
-			duration = velocity !== 0 ? Math.abs(distance / velocity) : 0.01; // time = distance / velocity
-		}
-		this.slideTo(to, duration, easing);
-	};
-
-	this.adjustDestination = function(to, pos){
-		// subclass may want to implement
-	};
-
-	this.abort = function(){
-		this.scrollTo(this.getPos());
-		this.stopAnimation();
-		this._aborted = true;
-	};
-
-	this.stopAnimation = function(){
-		// stop the currently running animation
-		domClass.remove(this.containerNode, "mblScrollableScrollTo2");
-		if(has("android")){
-			domStyle.set(this.containerNode, "webkitAnimationDuration", "0s"); // workaround for android screen flicker problem
-		}
-		if(this._scrollBarV){
-			this._scrollBarV.className = "";
-		}
-		if(this._scrollBarH){
-			this._scrollBarH.className = "";
-		}
-	};
-
-	this.getSpeed = function(){
-		var x = 0, y = 0, n = this._time.length;
-		// if the user holds the mouse or finger more than 0.5 sec, do not move.
-		if(n >= 2 && (new Date()).getTime() - this.startTime - this._time[n - 1] < 500){
-			var dy = this._posY[n - (n > 3 ? 2 : 1)] - this._posY[(n - 6) >= 0 ? n - 6 : 0];
-			var dx = this._posX[n - (n > 3 ? 2 : 1)] - this._posX[(n - 6) >= 0 ? n - 6 : 0];
-			var dt = this._time[n - (n > 3 ? 2 : 1)] - this._time[(n - 6) >= 0 ? n - 6 : 0];
-			y = this.calcSpeed(dy, dt);
-			x = this.calcSpeed(dx, dt);
-		}
-		return {x:x, y:y};
-	};
-
-	this.calcSpeed = function(/*Number*/d, /*Number*/t){
-		return Math.round(d / t * 100) * 4;
-	};
-
-	this.scrollTo = function(/*Object*/to, /*Boolean?*/doNotMoveScrollBar, /*DomNode?*/node){ // to: {x, y}
-		// summary:
-		//		Scrolls to the given position.
-		var s = (node || this.containerNode).style;
-		if(has("webkit")){
-			s.webkitTransform = this.makeTranslateStr(to);
-		}else{
-			if(this._v){
-				s.top = to.y + "px";
+		},
+
+		slideScrollBarTo: function(/*Object*/to, /*Number*/duration, /*String*/easing){
+			// summary:
+			//		Moves the scroll bar(s) to the given position with the slide animation.
+			// to:
+			//		The destination position. An object with x and y.
+			//		ex. {x:0, y:-5}
+			// duration:
+			//		Duration of the animation in seconds. (ex. 0.3)
+			// easing:
+			//		The name of easing effect which webkit supports.
+			//		"ease", "linear", "ease-in", "ease-out", etc.
+
+			if(!this.scrollBar){ return; }
+			var fromPos = this.calcScrollBarPos(this.getPos());
+			var toPos = this.calcScrollBarPos(to);
+			if(this._v && this._scrollBarV){
+				this._runSlideAnimation({y:fromPos.y}, {y:toPos.y}, duration, easing, this._scrollBarV, 0);
 			}
-			if(this._h || this._f){
-				s.left = to.x + "px";
+			if(this._h && this._scrollBarH){
+				this._runSlideAnimation({x:fromPos.x}, {x:toPos.x}, duration, easing, this._scrollBarH, 1);
 			}
-		}
-		if(!doNotMoveScrollBar){
-			this.scrollScrollBarTo(this.calcScrollBarPos(to));
-		}
-	};
-
-	this.slideTo = function(/*Object*/to, /*Number*/duration, /*String*/easing){
-		// summary:
-		//		Scrolls to the given position with slide animation.
-		this._runSlideAnimation(this.getPos(), to, duration, easing, this.containerNode, 2);
-		this.slideScrollBarTo(to, duration, easing);
-	};
-
-	this.makeTranslateStr = function(to){
-		var y = this._v && typeof to.y == "number" ? to.y+"px" : "0px";
-		var x = (this._h||this._f) && typeof to.x == "number" ? to.x+"px" : "0px";
-		return dm.hasTranslate3d ?
-				"translate3d("+x+","+y+",0px)" : "translate("+x+","+y+")";
-	};
+		},
 
-	this.getPos = function(){
-		// summary:
-		//		Get the top position in the midst of animation
-		if(has("webkit")){
-			var m = win.doc.defaultView.getComputedStyle(this.containerNode, '')["-webkit-transform"];
-			if(m && m.indexOf("matrix") === 0){
-				var arr = m.split(/[,\s\)]+/);
-				return {y:arr[5] - 0, x:arr[4] - 0};
-			}
-			return {x:0, y:0};
-		}else{
-			// this.containerNode.offsetTop does not work here,
-			// because it adds the height of the top margin.
-			var y = parseInt(this.containerNode.style.top) || 0;
-			return {y:y, x:this.containerNode.offsetLeft};
-		}
-	};
-
-	this.getDim = function(){
-		var d = {};
-		// content width/height
-		d.c = {h:this.containerNode.offsetHeight, w:this.containerNode.offsetWidth};
-
-		// view width/height
-		d.v = {h:this.domNode.offsetHeight + this._appFooterHeight, w:this.domNode.offsetWidth};
-
-		// display width/height
-		d.d = {h:d.v.h - this.fixedHeaderHeight - this.fixedFooterHeight, w:d.v.w};
-
-		// overflowed width/height
-		d.o = {h:d.c.h - d.v.h + this.fixedHeaderHeight + this.fixedFooterHeight, w:d.c.w - d.v.w};
-		return d;
-	};
-
-	this.showScrollBar = function(){
-		if(!this.scrollBar){ return; }
-
-		var dim = this._dim;
-		if(this.scrollDir == "v" && dim.c.h <= dim.d.h){ return; }
-		if(this.scrollDir == "h" && dim.c.w <= dim.d.w){ return; }
-		if(this._v && this._h && dim.c.h <= dim.d.h && dim.c.w <= dim.d.w){ return; }
-
-		var createBar = function(self, dir){
-			var bar = self["_scrollBarNode" + dir];
-			if(!bar){
-				var wrapper = domConstruct.create("div", null, self.domNode);
-				var props = { position: "absolute", overflow: "hidden" };
-				if(dir == "V"){
-					props.right = "2px";
-					props.width = "5px";
+		_runSlideAnimation: function(/*Object*/from, /*Object*/to, /*Number*/duration, /*String*/easing, /*DomNode*/node, /*Number*/idx){
+			// tags:
+			//		private
+			
+			// idx: 0:scrollbarV, 1:scrollbarH, 2:content
+			if(has("css3-animations")){
+				if(!this._useTopLeft){
+					if(this._useTransformTransition){
+						// for iOS6 (maybe others?): use -webkit-transform + -webkit-transition
+						if(to.x === undefined){ to.x = from.x; }
+						if(to.y === undefined){ to.y = from.y; }
+						 // make sure we actually change the transform, otherwise no webkitTransitionEnd is fired.
+						if(to.x !== from.x || to.y !== from.y){
+							domStyle.set(node, css3.add({}, {
+								transitionProperty: css3.name("transform"),
+								transitionDuration: duration + "s",
+								transitionTimingFunction: easing
+							}));
+							var t = this.makeTranslateStr(to);
+							setTimeout(function(){ // setTimeout is needed to prevent webkitTransitionEnd not fired
+								domStyle.set(node, css3.add({}, {
+									transform: t
+								}));
+							}, 0);
+							domClass.add(node, "mblScrollableScrollTo"+idx);
+						} else {
+							// transform not changed, just hide the scrollbar
+							this.hideScrollBar();
+							this.removeCover();
+						}
+					}else{
+						// use -webkit-transform + -webkit-animation
+						this.setKeyframes(from, to, idx);
+						domStyle.set(node, css3.add({}, {
+							animationDuration: duration + "s",
+							animationTimingFunction: easing
+						}));
+						domClass.add(node, "mblScrollableScrollTo"+idx);
+						if(idx == 2){
+							this.scrollTo(to, true, node);
+						}else{
+							this.scrollScrollBarTo(to);
+						}
+					}
 				}else{
-					props.bottom = (self.isLocalFooter ? self.fixedFooterHeight : 0) + 2 + "px";
-					props.height = "5px";
+					domStyle.set(node, css3.add({}, {
+						transitionProperty: "top, left",
+						transitionDuration: duration + "s",
+						transitionTimingFunction: easing
+					}));
+					setTimeout(function(){ // setTimeout is needed to prevent webkitTransitionEnd not fired
+						domStyle.set(node, {
+							top: (to.y || 0) + "px",
+							left: (to.x || 0) + "px"
+						});
+					}, 0);
+					domClass.add(node, "mblScrollableScrollTo"+idx);
+				}
+			}else if(dojo.fx && dojo.fx.easing && duration){
+				// If you want to support non-webkit browsers,
+				// your application needs to load necessary modules as follows:
+				//
+				// | dojo.require("dojo.fx");
+				// | dojo.require("dojo.fx.easing");
+				//
+				// This module itself does not make dependency on them.
+				// TODO: for 2.0 the dojo global is going away.   Use require("dojo/fx") and require("dojo/fx/easing") instead.
+				var s = dojo.fx.slideTo({
+					node: node,
+					duration: duration*1000,
+					left: to.x,
+					top: to.y,
+					easing: (easing == "ease-out") ? dojo.fx.easing.quadOut : dojo.fx.easing.linear
+				}).play();
+				if(idx == 2){
+					connect.connect(s, "onEnd", this, "onFlickAnimationEnd");
 				}
-				domStyle.set(wrapper, props);
-				wrapper.className = "mblScrollBarWrapper";
-				self["_scrollBarWrapper"+dir] = wrapper;
-
-				bar = domConstruct.create("div", null, wrapper);
-				domStyle.set(bar, {
-					opacity: 0.6,
-					position: "absolute",
-					backgroundColor: "#606060",
-					fontSize: "1px",
-					webkitBorderRadius: "2px",
-					MozBorderRadius: "2px",
-					webkitTransformOrigin: "0 0",
-					zIndex: 2147483647 // max of signed 32-bit integer
-				});
-				domStyle.set(bar, dir == "V" ? {width: "5px"} : {height: "5px"});
-				self["_scrollBarNode" + dir] = bar;
-			}
-			return bar;
-		};
-		if(this._v && !this._scrollBarV){
-			this._scrollBarV = createBar(this, "V");
-		}
-		if(this._h && !this._scrollBarH){
-			this._scrollBarH = createBar(this, "H");
-		}
-		this.resetScrollBar();
-	};
-
-	this.hideScrollBar = function(){
-		var fadeRule;
-		if(this.fadeScrollBar && has("webkit")){
-			if(!dm._fadeRule){
-				var node = domConstruct.create("style", null, win.doc.getElementsByTagName("head")[0]);
-				node.textContent =
-					".mblScrollableFadeScrollBar{"+
-					"  -webkit-animation-duration: 1s;"+
-					"  -webkit-animation-name: scrollableViewFadeScrollBar;}"+
-					"@-webkit-keyframes scrollableViewFadeScrollBar{"+
-					"  from { opacity: 0.6; }"+
-					"  to { opacity: 0; }}";
-				dm._fadeRule = node.sheet.cssRules[1];
-			}
-			fadeRule = dm._fadeRule;
-		}
-		if(!this.scrollBar){ return; }
-		var f = function(bar, self){
-			domStyle.set(bar, {
-				opacity: 0,
-				webkitAnimationDuration: ""
-			});
-			if(self._aw){ // android workaround
-				bar.style.webkitTransform = "";
 			}else{
-				bar.className = "mblScrollableFadeScrollBar";
+				// directly jump to the destination without animation
+				if(idx == 2){
+					this.scrollTo(to, false, node);
+					this.onFlickAnimationEnd();
+				}else{
+					this.scrollScrollBarTo(to);
+				}
 			}
-		};
-		if(this._scrollBarV){
-			f(this._scrollBarV, this);
-			this._scrollBarV = null;
-		}
-		if(this._scrollBarH){
-			f(this._scrollBarH, this);
-			this._scrollBarH = null;
-		}
-	};
-
-	this.calcScrollBarPos = function(/*Object*/to){ // to: {x, y}
-		var pos = {};
-		var dim = this._dim;
-		var f = function(wrapperH, barH, t, d, c){
-			var y = Math.round((d - barH - 8) / (d - c) * t);
-			if(y < -barH + 5){
-				y = -barH + 5;
-			}
-			if(y > wrapperH - 5){
-				y = wrapperH - 5;
-			}
-			return y;
-		};
-		if(typeof to.y == "number" && this._scrollBarV){
-			pos.y = f(this._scrollBarWrapperV.offsetHeight, this._scrollBarV.offsetHeight, to.y, dim.d.h, dim.c.h);
-		}
-		if(typeof to.x == "number" && this._scrollBarH){
-			pos.x = f(this._scrollBarWrapperH.offsetWidth, this._scrollBarH.offsetWidth, to.x, dim.d.w, dim.c.w);
-		}
-		return pos;
-	};
-
-	this.scrollScrollBarTo = function(/*Object*/to){ // to: {x, y}
-		if(!this.scrollBar){ return; }
-		if(this._v && this._scrollBarV && typeof to.y == "number"){
-			if(has("webkit")){
-				this._scrollBarV.style.webkitTransform = this.makeTranslateStr({y:to.y});
-			}else{
-				this._scrollBarV.style.top = to.y + "px";
+		},
+
+		resetScrollBar: function(){
+			// summary:
+			//		Resets the scroll bar length, position, etc.
+			var f = function(wrapper, bar, d, c, hd, v){
+				if(!bar){ return; }
+				var props = {};
+				props[v ? "top" : "left"] = hd + 4 + "px"; // +4 is for top or left margin
+				var t = (d - 8) <= 0 ? 1 : d - 8;
+				props[v ? "height" : "width"] = t + "px";
+				domStyle.set(wrapper, props);
+				var l = Math.round(d * d / c); // scroll bar length
+				l = Math.min(Math.max(l - 8, 5), t); // -8 is for margin for both ends
+				bar.style[v ? "height" : "width"] = l + "px";
+				domStyle.set(bar, {"opacity": 0.6});
+			};
+			var dim = this.getDim();
+			f(this._scrollBarWrapperV, this._scrollBarV, dim.d.h, dim.c.h, this.fixedHeaderHeight, true);
+			f(this._scrollBarWrapperH, this._scrollBarH, dim.d.w, dim.c.w, 0);
+			this.createMask();
+		},
+
+		createMask: function(){
+			// summary:
+			//		Creates a mask for a scroll bar edge.
+			// description:
+			//		This function creates a mask that hides corners of one scroll
+			//		bar edge to make it round edge. The other side of the edge is
+			//		always visible and round shaped with the border-radius style.
+			if(!(has("webkit")||has("svg"))){ return; }
+			//var ctx;
+			if(this._scrollBarWrapperV){
+				var h = this._scrollBarWrapperV.offsetHeight;
+				maskUtils.createRoundMask(this._scrollBarWrapperV, 0, 0, 0, 0, 5, h, 2, 2, 0.5);
 			}
-		}
-		if(this._h && this._scrollBarH && typeof to.x == "number"){
-			if(has("webkit")){
-				this._scrollBarH.style.webkitTransform = this.makeTranslateStr({x:to.x});
-			}else{
-				this._scrollBarH.style.left = to.x + "px";
+			if(this._scrollBarWrapperH){
+				var w = this._scrollBarWrapperH.offsetWidth;
+				maskUtils.createRoundMask(this._scrollBarWrapperH, 0, 0, 0, 0, w, 5, 2, 2, 0.5);
 			}
-		}
-	};
-
-	this.slideScrollBarTo = function(/*Object*/to, /*Number*/duration, /*String*/easing){
-		if(!this.scrollBar){ return; }
-		var fromPos = this.calcScrollBarPos(this.getPos());
-		var toPos = this.calcScrollBarPos(to);
-		if(this._v && this._scrollBarV){
-			this._runSlideAnimation({y:fromPos.y}, {y:toPos.y}, duration, easing, this._scrollBarV, 0);
-		}
-		if(this._h && this._scrollBarH){
-			this._runSlideAnimation({x:fromPos.x}, {x:toPos.x}, duration, easing, this._scrollBarH, 1);
-		}
-	};
-
-	this._runSlideAnimation = function(/*Object*/from, /*Object*/to, /*Number*/duration, /*String*/easing, node, idx){
-		// idx: 0:scrollbarV, 1:scrollbarH, 2:content
-		if(has("webkit")){
-			this.setKeyframes(from, to, idx);
-			domStyle.set(node, {
-				webkitAnimationDuration: duration + "s",
-				webkitAnimationTimingFunction: easing
-			});
-			domClass.add(node, "mblScrollableScrollTo"+idx);
-			if(idx == 2){
-				this.scrollTo(to, true, node);
-			}else{
-				this.scrollScrollBarTo(to);
-			}
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		}else if(dojo.fx && dojo.fx.easing && duration){
-			// If you want to support non-webkit browsers,
-			// your application needs to load necessary modules as follows:
-			//
-			// | dojo.require("dojo.fx");
-			// | dojo.require("dojo.fx.easing");
-			//
-			// This module itself does not make dependency on them.
-			var s = dojo.fx.slideTo({
-				node: node,
-				duration: duration*1000,
-				left: to.x,
-				top: to.y,
-				easing: (easing == "ease-out") ? dojo.fx.easing.quadOut : dojo.fx.easing.linear
-			}).play();
-			if(idx == 2){
-				connect.connect(s, "onEnd", this, "onFlickAnimationEnd");
-			}
-		}else{
-			// directly jump to the destination without animation
-			if(idx == 2){
-				this.scrollTo(to, false, node);
-				this.onFlickAnimationEnd();
-			}else{
-				this.scrollScrollBarTo(to);
+		},
+
+		flashScrollBar: function(){
+			// summary:
+			//		Shows the scroll bar instantly.
+			// description:
+			//		This function shows the scroll bar, and then hides it 300ms
+			//		later. This is used to show the scroll bar to the user for a
+			//		short period of time when a hidden view is revealed.
+			if(this.disableFlashScrollBar || !this.domNode){ return; }
+			this._dim = this.getDim();
+			if(this._dim.d.h <= 0){ return; } // dom is not ready
+			this.showScrollBar();
+			var _this = this;
+			setTimeout(function(){
+				_this.hideScrollBar();
+			}, 300);
+		},
+
+		addCover: function(){
+			// summary:
+			//		Adds the transparent DIV cover.
+			// description:
+			//		The cover is to prevent DOM events from affecting the child
+			//		widgets such as a list widget. Without the cover, for example,
+			//		child widgets may receive a click event and respond to it
+			//		unexpectedly when the user flicks the screen to scroll.
+			//		Note that only the desktop browsers need the cover.
+
+			if(!has('touch') && !this.noCover){
+				if(!dm._cover){
+					dm._cover = domConstruct.create("div", null, win.doc.body);
+					dm._cover.className = "mblScrollableCover";
+					domStyle.set(dm._cover, {
+						backgroundColor: "#ffff00",
+						opacity: 0,
+						position: "absolute",
+						top: "0px",
+						left: "0px",
+						width: "100%",
+						height: "100%",
+						zIndex: 2147483647 // max of signed 32-bit integer
+					});
+					this._ch.push(connect.connect(dm._cover, touch.press, this, "onTouchEnd"));
+				}else{
+					dm._cover.style.display = "";
+				}
+				this.setSelectable(dm._cover, false);
+				this.setSelectable(this.domNode, false);
 			}
-//>>excludeEnd("webkitMobile");
-		}
-	};
-
-	this.resetScrollBar = function(){
-		//	summary:
-		//		Resets the scroll bar length, position, etc.
-		var f = function(wrapper, bar, d, c, hd, v){
-			if(!bar){ return; }
-			var props = {};
-			props[v ? "top" : "left"] = hd + 4 + "px"; // +4 is for top or left margin
-			var t = (d - 8) <= 0 ? 1 : d - 8;
-			props[v ? "height" : "width"] = t + "px";
-			domStyle.set(wrapper, props);
-			var l = Math.round(d * d / c); // scroll bar length
-			l = Math.min(Math.max(l - 8, 5), t); // -8 is for margin for both ends
-			bar.style[v ? "height" : "width"] = l + "px";
-			domStyle.set(bar, {"opacity": 0.6});
-		};
-		var dim = this.getDim();
-		f(this._scrollBarWrapperV, this._scrollBarV, dim.d.h, dim.c.h, this.fixedHeaderHeight, true);
-		f(this._scrollBarWrapperH, this._scrollBarH, dim.d.w, dim.c.w, 0);
-		this.createMask();
-	};
-
-	this.createMask = function(){
-		//	summary:
-		//		Creates a mask for a scroll bar edge.
-		// description:
-		//		This function creates a mask that hides corners of one scroll
-		//		bar edge to make it round edge. The other side of the edge is
-		//		always visible and round shaped with the border-radius style.
-		if(!has("webkit")){ return; }
-		var ctx;
-		if(this._scrollBarWrapperV){
-			var h = this._scrollBarWrapperV.offsetHeight;
-			ctx = win.doc.getCSSCanvasContext("2d", "scrollBarMaskV", 5, h);
-			ctx.fillStyle = "rgba(0,0,0,0.5)";
-			ctx.fillRect(1, 0, 3, 2);
-			ctx.fillRect(0, 1, 5, 1);
-			ctx.fillRect(0, h - 2, 5, 1);
-			ctx.fillRect(1, h - 1, 3, 2);
-			ctx.fillStyle = "rgb(0,0,0)";
-			ctx.fillRect(0, 2, 5, h - 4);
-			this._scrollBarWrapperV.style.webkitMaskImage = "-webkit-canvas(scrollBarMaskV)";
-		}
-		if(this._scrollBarWrapperH){
-			var w = this._scrollBarWrapperH.offsetWidth;
-			ctx = win.doc.getCSSCanvasContext("2d", "scrollBarMaskH", w, 5);
-			ctx.fillStyle = "rgba(0,0,0,0.5)";
-			ctx.fillRect(0, 1, 2, 3);
-			ctx.fillRect(1, 0, 1, 5);
-			ctx.fillRect(w - 2, 0, 1, 5);
-			ctx.fillRect(w - 1, 1, 2, 3);
-			ctx.fillStyle = "rgb(0,0,0)";
-			ctx.fillRect(2, 0, w - 4, 5);
-			this._scrollBarWrapperH.style.webkitMaskImage = "-webkit-canvas(scrollBarMaskH)";
-		}
-	};
+		},
 
-	this.flashScrollBar = function(){
-		if(this.disableFlashScrollBar || !this.domNode){ return; }
-		this._dim = this.getDim();
-		if(this._dim.d.h <= 0){ return; } // dom is not ready
-		this.showScrollBar();
-		var _this = this;
-		setTimeout(function(){
-			_this.hideScrollBar();
-		}, 300);
-	};
+		removeCover: function(){
+			// summary:
+			//		Removes the transparent DIV cover.
 
-	this.addCover = function(){
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		if(!has('touch') && !this.noCover){
-			if(!this._cover){
-				this._cover = domConstruct.create("div", null, win.doc.body);
-				domStyle.set(this._cover, {
-					backgroundColor: "#ffff00",
-					opacity: 0,
-					position: "absolute",
-					top: "0px",
-					left: "0px",
-					width: "100%",
-					height: "100%",
-					zIndex: 2147483647 // max of signed 32-bit integer
-				});
-				this._ch.push(connect.connect(this._cover,
-					has('touch') ? "touchstart" : "onmousedown", this, "onTouchEnd"));
-			}else{
-				this._cover.style.display = "";
+			if(!has('touch') && dm._cover){
+				dm._cover.style.display = "none";
+				this.setSelectable(dm._cover, true);
+				this.setSelectable(this.domNode, true);
 			}
-			this.setSelectable(this._cover, false);
-			this.setSelectable(this.domNode, false);
-		}
-//>>excludeEnd("webkitMobile");
-	};
+		},
 
-	this.removeCover = function(){
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		if(!has('touch') && this._cover){
-			this._cover.style.display = "none";
-			this.setSelectable(this._cover, true);
-			this.setSelectable(this.domNode, true);
-		}
-//>>excludeEnd("webkitMobile");
-	};
+		setKeyframes: function(/*Object*/from, /*Object*/to, /*Number*/idx){
+			// summary:
+			//		Programmatically sets key frames for the scroll animation.
 
-	this.setKeyframes = function(/*Object*/from, /*Object*/to, /*Number*/idx){
-		if(!dm._rule){
-			dm._rule = [];
-		}
-		// idx: 0:scrollbarV, 1:scrollbarH, 2:content
-		if(!dm._rule[idx]){
-			var node = domConstruct.create("style", null, win.doc.getElementsByTagName("head")[0]);
-			node.textContent =
-				".mblScrollableScrollTo"+idx+"{-webkit-animation-name: scrollableViewScroll"+idx+";}"+
-				"@-webkit-keyframes scrollableViewScroll"+idx+"{}";
-			dm._rule[idx] = node.sheet.cssRules[1];
-		}
-		var rule = dm._rule[idx];
-		if(rule){
-			if(from){
-				rule.deleteRule("from");
-				rule.insertRule("from { -webkit-transform: "+this.makeTranslateStr(from)+"; }");
-			}
-			if(to){
-				if(to.x === undefined){ to.x = from.x; }
-				if(to.y === undefined){ to.y = from.y; }
-				rule.deleteRule("to");
-				rule.insertRule("to { -webkit-transform: "+this.makeTranslateStr(to)+"; }");
+			if(!dm._rule){
+				dm._rule = [];
 			}
-		}
-	};
-
-	this.setSelectable = function(node, selectable){
-		// dojo.setSelectable has dependency on dojo.query. Re-define our own.
-		node.style.KhtmlUserSelect = selectable ? "auto" : "none";
-		node.style.MozUserSelect = selectable ? "" : "none";
-		node.onselectstart = selectable ? null : function(){return false;};
-		if(has("ie")){
-			node.unselectable = selectable ? "" : "on";
-			var nodes = node.getElementsByTagName("*");
-			for(var i = 0; i < nodes.length; i++){
-				nodes[i].unselectable = selectable ? "" : "on";
+			// idx: 0:scrollbarV, 1:scrollbarH, 2:content
+			if(!dm._rule[idx]){
+				var node = domConstruct.create("style", null, win.doc.getElementsByTagName("head")[0]);
+				node.textContent =
+					".mblScrollableScrollTo"+idx+"{" + css3.name("animation-name", true) + ": scrollableViewScroll"+idx+";}"+
+					"@" + css3.name("keyframes", true) + " scrollableViewScroll"+idx+"{}";
+				dm._rule[idx] = node.sheet.cssRules[1];
+			}
+			var rule = dm._rule[idx];
+			if(rule){
+				if(from){
+					rule.deleteRule(has("webkit")?"from":0);
+					(rule.insertRule||rule.appendRule).call(rule, "from { " + css3.name("transform", true) + ": "+this.makeTranslateStr(from)+"; }");
+				}
+				if(to){
+					if(to.x === undefined){ to.x = from.x; }
+					if(to.y === undefined){ to.y = from.y; }
+					rule.deleteRule(has("webkit")?"to":1);
+					(rule.insertRule||rule.appendRule).call(rule, "to { " + css3.name("transform", true) + ": "+this.makeTranslateStr(to)+"; }");
+				}
+			}
+		},
+
+		setSelectable: function(/*DomNode*/node, /*Boolean*/selectable){
+			// summary:
+			//		Sets the given node as selectable or unselectable.
+			 
+			// dojo.setSelectable has dependency on dojo.query. Redefine our own.
+			node.style.KhtmlUserSelect = selectable ? "auto" : "none";
+			node.style.MozUserSelect = selectable ? "" : "none";
+			node.onselectstart = selectable ? null : function(){return false;};
+			if(has("ie")){
+				node.unselectable = selectable ? "" : "on";
+				var nodes = node.getElementsByTagName("*");
+				for(var i = 0; i < nodes.length; i++){
+					nodes[i].unselectable = selectable ? "" : "on";
+				}
 			}
 		}
-	};
+	});
 
-	// feature detection
-	if(has("webkit")){
-		var elem = win.doc.createElement("div");
-		elem.style.webkitTransform = "translate3d(0px,1px,0px)";
-		win.doc.documentElement.appendChild(elem);
-		var v = win.doc.defaultView.getComputedStyle(elem, '')["-webkit-transform"];
-		dm.hasTranslate3d = v && v.indexOf("matrix") === 0;
-		win.doc.documentElement.removeChild(elem);
-	}
-};
-
-//>>includeStart("standaloneScrollable", kwArgs.standaloneScrollable);
-	if(!dm){ dm = dojox.mobile; }
-//>>includeEnd("standaloneScrollable");
-dm.scrollable = scrollable; // for backward compatibility
-return scrollable;
+	lang.setObject("dojox.mobile.scrollable", Scrollable);
+
+	return Scrollable;
 });
diff --git a/dojox/mobile/sniff.js b/dojox/mobile/sniff.js
index 9fa269d..fddf640 100644
--- a/dojox/mobile/sniff.js
+++ b/dojox/mobile/sniff.js
@@ -1,31 +1,21 @@
 define([
-	"dojo/_base/window",
-	"dojo/_base/sniff"
-], function(win, has){
+	"dojo/_base/kernel",
+	"dojo/sniff"
+], function(kernel, has){
 
-	var ua = navigator.userAgent;
-
-	// BlackBerry (OS 6 or later only)
-	has.add('bb', ua.indexOf("BlackBerry") >= 0 && parseFloat(ua.split("Version/")[1]) || undefined, undefined, true);
-
-	// Android
-	has.add('android', parseFloat(ua.split("Android ")[1]) || undefined, undefined, true);
-
-	// iPhone, iPod, or iPad
-	// If iPod or iPad is detected, in addition to has('ipod') or has('ipad'),
-	// has('iphone') will also have iOS version number.
-	if(ua.match(/(iPhone|iPod|iPad)/)){
-		var p = RegExp.$1.replace(/P/, 'p');
-		var v = ua.match(/OS ([\d_]+)/) ? RegExp.$1 : "1";
-		var os = parseFloat(v.replace(/_/, '.').replace(/_/g, ''));
-		has.add(p, os, undefined, true);
-		has.add('iphone', os, undefined, true);
-	}
-
-	if(has("webkit")){
-		has.add('touch', (typeof win.doc.documentElement.ontouchstart != "undefined" &&
-			navigator.appVersion.indexOf("Mobile") != -1) || !!has('android'), undefined, true);
-	}
+	kernel.deprecated("dojox/mobile/sniff", "Use dojo/sniff instead", "2.0");
+	
+	// TODO: remove this in 2.0
+	has.add("iphone", has("ios"));
 
+	/*=====
+	return {
+		// summary:
+		//		Deprecated: use dojo/sniff instead.
+		//		On iOS, dojox/mobile/sniff sets "iphone" to the same value as "ios"
+		//		for compatibility with earlier versions, but this should be considered deprecated.
+		//		In future versions, "iphone" will be set only when running on an iPhone (not iPad on iPod).
+	};
+	=====*/
 	return has;
 });
diff --git a/dojox/mobile/tests/audio/sample.mp3 b/dojox/mobile/tests/audio/sample.mp3
new file mode 100644
index 0000000..3d530d3
Binary files /dev/null and b/dojox/mobile/tests/audio/sample.mp3 differ
diff --git a/dojox/mobile/tests/audio/sample.ogg b/dojox/mobile/tests/audio/sample.ogg
new file mode 100644
index 0000000..a01ea23
Binary files /dev/null and b/dojox/mobile/tests/audio/sample.ogg differ
diff --git a/dojox/mobile/tests/audio/sample.wav b/dojox/mobile/tests/audio/sample.wav
new file mode 100644
index 0000000..3b09782
Binary files /dev/null and b/dojox/mobile/tests/audio/sample.wav differ
diff --git a/dojox/mobile/tests/auto.html b/dojox/mobile/tests/auto.html
new file mode 100644
index 0000000..609d8a8
--- /dev/null
+++ b/dojox/mobile/tests/auto.html
@@ -0,0 +1,99 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<title>dojox.mobile auto run</title>
+	<script src="index.js"></script>
+	<script>
+	var tests, win, c, data, map = {}, theme = "";
+	function sort(keys){
+		var data = [];
+		for(var i = 0; i < keys.length; i++){
+			var key = keys[i];
+			var items = [];
+			items.label = key.label;
+			for(var j = 0; j < tests.length; j++){
+				var item = tests[j];
+				var url = item.url;
+				var label = item.label || item.url;
+				var tags = item.tags ? item.tags.split(/,/) : [];
+				for(var k = 0; k < tags.length; k++){
+					if(tags[k] === key.tag){
+						items.push(item);
+					}
+				}
+			}
+			data.push(items);
+			map[key.label] = items;
+		}
+		return data;
+	}
+	function init(){
+		c = document.getElementById("container");
+		var data = sort(categories);
+		for(var i = 0; i < data.length; i++){
+			var cat = data[i];
+			var inp = document.createElement("input");
+			inp.type = "checkbox";
+			inp.name = cat.label;
+			c.appendChild(inp);
+			c.appendChild(document.createTextNode(cat.label));
+			c.appendChild(document.createElement("br"));
+		}
+	}
+	function checkAll(v){
+		for(var i = 0; i < c.childNodes.length; i++){
+			var inp = c.childNodes[i];
+			if(inp.tagName !== "INPUT"){ continue; }
+			inp.checked = v;
+		}
+	}
+	function run(idx){
+		win.location.href = tests[idx++] + (theme ? "?theme=" + theme : "");
+		setTimeout(function(){
+			if(idx < tests.length){
+				run(idx);
+			}else{
+				win.close();
+			}
+		}, document.forms[0].interval.value - 0);
+	}
+	function start1(){
+		tests = [];
+		for(var i = 0; i < c.childNodes.length; i++){
+			var inp = c.childNodes[i];
+			if(inp.tagName !== "INPUT" || !inp.checked){ continue; }
+			var label = inp.name;
+			console.log(label);
+			var items = map[label];
+			for(var j = 0; j < items.length; j++){
+				tests.push(items[j].url);
+			}
+		}
+		win = window.open("about:blank", "_blank");
+		run(0);
+	}
+	function onThemeChange(){
+		theme = document.getElementById("sel1").value;
+	}
+	</script>
+	</head>
+	<body onload="init()">
+		<form>
+			<select id="sel1" onchange="onThemeChange()">
+				<option value=""></option>
+				<option value="iPhone">iPhone</option>
+				<option value="Android">Android</option>
+				<option value="BlackBerry">BlackBerry</option>
+				<option value="Custom">Custom</option>
+			</select>
+			<input id="btn" type="button" onclick="start1()" value=" START "><br>
+			<hr>
+			Interval: <input name="interval" value="5000"> [ms]<br>
+			<div id="container"></div>
+			<hr>
+			<input id="btn" type="button" onclick="checkAll(true)" value=" Check All ">
+			<input id="btn" type="button" onclick="checkAll(false)" value=" Uncheck All "><br>
+		</form>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_Accordion.html b/dojox/mobile/tests/bidi/Bidi_Accordion.html
new file mode 100644
index 0000000..cad0b3b
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_Accordion.html
@@ -0,0 +1,279 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - Accordion</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Accordion']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/_base/manager",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",			
+			"dojox/mobile/Accordion",
+			"dojox/mobile/ContentPane",
+			"dojox/mobile/ScrollableView"
+]);
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url('../images/red-button-bg.png');
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+<!---	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:{"iphone_theme":"segmentedControl","*":"tallTab"}, fixed:"top"'>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true, moveTo:"view1"'> LTR</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view2"'> RTL</li>
+	</ul>--->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">Accordion widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+				
+		<div data-dojo-type="dojox.mobile.Accordion" id="1" data-dojo-props='textDir: "ltr",singleOpen:true, roundRect:true' style="height:200px;">
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Hello World!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"../data/fragment1.html"'>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום עולם!",icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"'>
+					<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"../images/tab-icon-11h.png"'>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u1space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u2space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							Wi-Fi!
+						</li>
+					</ul>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Hello עולם!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"' class="myPane">
+					<div style="padding:10px">
+						<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+						<div style="border-top: 1px dashed gray;margin: 20px"></div>
+						<img alt="" src="../images/dojo-logo1.png" style="float:left;margin-right:5px">
+						<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+						<p>Dojo's powerful, lightweight core makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.</p>
+					</div>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום World!"'>
+				</div>
+				</div>
+		</div>				
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		<div data-dojo-type="dojox.mobile.Accordion" data-dojo-props='textDir: "rtl",singleOpen:true, roundRect:true' style="height:400px;">
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Hello World!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"../data/fragment1.html"'>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום עולם!",icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"'>
+					<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"../images/tab-icon-11h.png"'>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u1space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u2space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							Wi-Fi!
+						</li>
+					</ul>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Hello עולם!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"' class="myPane">
+					<div style="padding:10px">
+						<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+						<div style="border-top: 1px dashed gray;margin: 20px"></div>
+						<img alt="" src="../images/dojo-logo1.png" style="float:left;margin-right:5px">
+						<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+						<p>Dojo's powerful, lightweight core makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.</p>
+					</div>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום World!"'>
+				</div>
+				</div>
+		</div>
+					
+		
+	</div>
+		
+		
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+	
+		<div data-dojo-type="dojox.mobile.Accordion" data-dojo-props='textDir: "auto",singleOpen:true, roundRect:true' style="height:400px;">
+				<div data-dojo-type="dojox.mobile.ContentPane" id="cp" data-dojo-props='label:"Hello World!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"../data/fragment1.html"'>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום עולם!",icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"'>
+					<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"../images/tab-icon-11h.png"'>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u1space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u2space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							Wi-Fi!
+						</li>
+					</ul>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Hello עולם!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"' class="myPane">
+					<div style="padding:10px">
+						<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+						<div style="border-top: 1px dashed gray;margin: 20px"></div>
+						<img alt="" src="../images/dojo-logo1.png" style="float:left;margin-right:5px">
+						<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+						<p>Dojo's powerful, lightweight core makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.</p>
+					</div>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום World!"'>
+				</div>
+				</div>
+		</div>
+	</div>	
+	 
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		<div data-dojo-type="dojox.mobile.Accordion" dir="rtl" data-dojo-props='textDir: "ltr",singleOpen:true, roundRect:true' style="height:400px;">
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Hello World!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"../data/fragment1.html"'>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום עולם!",icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"'>
+					<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"../images/tab-icon-11h.png"'>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u1space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u2space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							Wi-Fi!
+						</li>
+					</ul>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Hello עולם!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"' class="myPane">
+					<div style="padding:10px">
+						<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+						<div style="border-top: 1px dashed gray;margin: 20px"></div>
+						<img alt="" src="../images/dojo-logo1.png" style="float:left;margin-right:5px">
+						<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+						<p>Dojo's powerful, lightweight core makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.</p>
+					</div>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום World!"'>
+				</div>
+				</div>
+		</div>
+		
+		
+	</div>
+	<div id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+		<div data-dojo-type="dojox.mobile.Accordion" dir="rtl" data-dojo-props='textDir: "rtl",singleOpen:true, roundRect:true' style="height:400px;">
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Hello World!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"../data/fragment1.html"'>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום עולם!",icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"'>
+					<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"../images/tab-icon-11h.png"'>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u1space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u2space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							Wi-Fi!
+						</li>
+					</ul>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Hello עולם!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"' class="myPane">
+					<div style="padding:10px">
+						<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+						<div style="border-top: 1px dashed gray;margin: 20px"></div>
+						<img alt="" src="../images/dojo-logo1.png" style="float:left;margin-right:5px">
+						<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+						<p>Dojo's powerful, lightweight core makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.</p>
+					</div>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום World!"'>
+				</div>
+				</div>
+		</div>
+		
+		</div>	
+		
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		<div data-dojo-type="dojox.mobile.Accordion" dir="rtl" data-dojo-props='textDir: "auto",singleOpen:true, roundRect:true' style="height:400px;">
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Hello World!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"../data/fragment1.html"'>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום עולם!",icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"'>
+					<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"../images/tab-icon-11h.png"'>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u1space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u2space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							Wi-Fi!
+						</li>
+					</ul>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Hello עולם!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"' class="myPane">
+					<div style="padding:10px">
+						<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+						<div style="border-top: 1px dashed gray;margin: 20px"></div>
+						<img alt="" src="../images/dojo-logo1.png" style="float:left;margin-right:5px">
+						<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+						<p>Dojo's powerful, lightweight core makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.</p>
+					</div>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"שלום World!"'>
+				</div>
+				</div>
+		</div>
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_Button.html b/dojox/mobile/tests/bidi/Bidi_Button.html
new file mode 100644
index 0000000..a3b77ac
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_Button.html
@@ -0,0 +1,179 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - Button</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/Button",
+			"dojox/mobile/Heading",
+			//"dojo/parser",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"						
+		], function(connect, ready, array, dom, registry, Button, Heading){
+			ready(function(){
+				//create list programmaticaly
+				var view = registry.byId("view2");
+				var heading = new Heading({label:"Created programmatically"});
+				view.addChild(heading);
+				var button = new Button({label:"\u05e9\u05dc\u05d5\u05dd end",  textDir:"rtl"});
+				view.addChild(button);
+				//change textDir, text
+				var btnLtr = registry.byId("btn5");				
+				btnLtr.connect(btnLtr, "onClick", function(){
+					array.forEach(["btn11", "btn12", "btn13", "btn14"], function (btnId){
+						registry.byId(btnId).set("textDir", "ltr");
+					});							
+				});
+				var btnRtl = registry.byId("btn6");
+				btnLtr.connect(btnRtl, "onClick", function(){
+					array.forEach(["btn11", "btn12", "btn13", "btn14"], function (btnId){
+						registry.byId(btnId).set("textDir", "rtl");
+					});							
+				});	
+				var btnAuto = registry.byId("btn7");
+				btnAuto.connect(btnAuto, "onClick", function(){
+					array.forEach(["btn11", "btn12", "btn13", "btn14"], function (btnId){
+						registry.byId(btnId).set("textDir", "auto");
+					});							
+				});						
+				var btnLbl = registry.byId("btnLbl");
+				btnLbl.connect(btnLbl, "onClick", function(){
+					registry.byId("btn31").set("label", "\u05e9\u05dc\u05d5\u05dd for test!");
+				});
+		});
+	
+	});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url('../images/red-button-bg.png');
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	 <h2 data-dojo-type="dojox.mobile.Heading">Button widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir LTR</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btn11" class="mblBlueButton"  data-dojo-props='textDir:"ltr"'>Hello World!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn12" class="mblRedButton" data-dojo-props='textDir:"ltr"'>שלום עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn13"  data-dojo-props='textDir:"ltr"' >Hello עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn14"  data-dojo-props='textDir:"ltr"' >שלום World!</button>
+		<hr>
+		<br>
+		<b>++++++++++++++++++++++++++++++++++++++++++++++++</b>
+		<br>
+		<button data-dojo-type="dojox.mobile.Button" id="btn5" class="mblRedButton" data-dojo-props='label:"Set textDir ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn6" class="mblRedButton" data-dojo-props='label:"Set textDir rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn7" class="mblRedButton" data-dojo-props='label:"Set textDir auto"'></button>
+
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir RTL</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btn21" class="mblBlueButton"  data-dojo-props='textDir:"rtl"'>Hello World!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn22" class="mblRedButton" data-dojo-props='textDir:"rtl"'>שלום עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn23"  data-dojo-props='textDir:"rtl"' >Hello עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn24"  data-dojo-props='textDir:"rtl"' >שלום World!</button>
+		<hr>
+	</div>	
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir AUTO</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btn31" class="mblBlueButton"  data-dojo-props='textDir:"auto"'>Hello World!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn32" class="mblRedButton" data-dojo-props='textDir:"auto"'>שלום עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn33"  data-dojo-props='textDir:"auto"' >Hello עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn34"  data-dojo-props='textDir:"auto"' >שלום World!</button>
+		<hr>		
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text Button</button>
+	</div>	
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir LTR</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btn41" class="mblBlueButton"  data-dojo-props='textDir:"ltr"'>Hello World!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn42" class="mblRedButton" data-dojo-props='textDir:"ltr"'>שלום עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn43"  data-dojo-props='textDir:"ltr"' >Hello עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn44"  data-dojo-props='textDir:"ltr"' >שלום World!</button>
+		<hr>
+	</div>
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDirRTR</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btn51" class="mblBlueButton"  data-dojo-props='textDir:"rtl"'>Hello World!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn52" class="mblRedButton" data-dojo-props='textDir:"rtl"'>שלום עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn53"  data-dojo-props='textDir:"rtl"' >Hello עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn54"  data-dojo-props='textDir:"rtl"' >שלום World!</button>
+		<hr>
+	</div>	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir AUTO</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btn61" class="mblBlueButton"  data-dojo-props='textDir:"auto"'>Hello World!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn62" class="mblRedButton" data-dojo-props='textDir:"auto"'>שלום עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn63"  data-dojo-props='textDir:"auto"' >Hello עולם!</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn64"  data-dojo-props='textDir:"auto"' >שלום World!</button>
+		<hr>		
+	</div>	
+</div>
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_ComboBox.html b/dojox/mobile/tests/bidi/Bidi_ComboBox.html
new file mode 100644
index 0000000..6f56bf0
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_ComboBox.html
@@ -0,0 +1,165 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bidi Mobile test - ComboBox</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ComboBox']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: { 'dojo-bidi': true }"></script>
+
+
+	
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dijit/_base/manager",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/ComboBox",
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView"
+		], function(connect, ready, array, dom, registry){
+
+			ready(function(){
+		
+				//change textDir, text
+				var btnLtr = registry.byId("btn1");				
+				btnLtr.connect(btnLtr, "onClick", function(){
+					registry.byId("LtrCombo1").set("textDir", "ltr");
+					
+				});
+				var btnRtl = registry.byId("btn2");
+				btnLtr.connect(btnRtl, "onClick", function(){
+					registry.byId("LtrCombo1").set("textDir", "rtl");
+									
+				});	
+				var btnAuto = registry.byId("btn3");
+				btnAuto.connect(btnAuto, "onClick", function(){
+					registry.byId("LtrCombo1").set("textDir", "auto");
+									
+				});
+				
+				// change label for icon container				
+				var btnLbl = registry.byId("btnLbl");
+				btnLbl.connect(btnLbl, "onClick", function(){
+				var c = registry.byId("AutoCombo1");
+				var l = c.get("label");
+				c.set("label", "new");
+				var n =  c.get("label");
+				
+					registry.byId("AutoCombo1").set("value","\u05e9\u05dc\u05d5\u05dd END!");
+					
+				});						
+			});
+			
+		});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	
+	</style>
+	
+	
+</head>
+<body style="visibility:hidden;">
+
+		<datalist id="values">
+		<select data-dojo-type="dijit.form.DataList" data-dojo-props='id:"values"' >
+				<option selected>שלו&#1501!</option>
+				<option >Hello!</option>
+				<option >My name is אמיר!  </option>
+				<option >שמי הוא Amir!</option>
+		</select>
+		</datalist>
+
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">ComboBox widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		<br>
+		<input id="LtrCombo1" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello!", list:"values", textDir:"ltr"'>
+		<br>
+		<br>
+		<button data-dojo-type="dojox.mobile.Button" id="btn1" class="mblRedButton" data-dojo-props='label:"Set textDir of ComboBox to ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn2" class="mblRedButton" data-dojo-props='label:"Set textDir of ComboBox to rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn3" class="mblRedButton" data-dojo-props='label:"Set textDir of ComboBox to auto"'></button>
+			
+	
+
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		
+			<input id="RTLCombo1" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello!", list:"values", textDir:"rtl"'>
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		
+		<input id="AutoCombo1" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello!", list:"values", textDir:"auto"'>
+		<br>
+		<br>
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text Button for ComboBoxes</button>
+	</div>	
+	 
+	 
+	<div id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		
+		
+		<input id="LtrCombo2" dir="rtl" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello!", list:"values", textDir:"ltr"'>
+		
+	</div>
+	
+	<div id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+			
+		 <input id="RtlCombo2" dir="rtl" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello!", list:"values", textDir:"rtl"'>
+		
+	</div>	
+	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		
+		 <input id="AutoCombo2" dir="rtl" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello!", list:"values", textDir:"auto"'>
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_Dialog.html b/dojox/mobile/tests/bidi/Bidi_Dialog.html
new file mode 100644
index 0000000..9f00cf3
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_Dialog.html
@@ -0,0 +1,426 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - Dialog</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SimpleDialog','TextBox','Button','ComboBox']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/ComboBox",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/Heading",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/TextArea",
+			"dojox/mobile/EdgeToEdgeDataList",
+			"dojox/mobile/Button"
+		], function(registry){
+			show1 = function(){
+				registry.byId("dlg1").show();
+			}
+			show2 = function(){
+				registry.byId("dlg2").show();
+			}
+			show3 = function(){
+				registry.byId("dlg3").show();
+			}
+			show4 = function(){
+				registry.byId("dlg4").show();
+			}
+			show5 = function(){
+				registry.byId("dlg5").show();
+			}
+			show6 = function(){
+				registry.byId("dlg6").show();
+			}
+		});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url('../images/red-button-bg.png');
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+	
+	<style>
+	#dlg1 {
+		top: 25%;
+		left: 25%;
+		width: 700px;
+		height: 550px;
+	}
+	#dlg1 TABLE {
+		margin: 20px;
+	}
+	#dlg1 INPUT, #dlg1 TEXTAREA {
+		background-color: #000000;
+		color: #ffffff;
+		width: 90%;
+		font-size: 17px;
+		margin: 4px;
+	}
+	#dlg1 TEXTAREA {
+		height: 160px;
+	}
+	.dlgTitle {
+		font-family: Helvetica;
+		font-size: 17px;
+		margin: 14px 14px;
+	}
+	</style>
+	
+	<style>
+	#dlg2 {
+		top: 25%;
+		left: 25%;
+		width: 700px;
+		height: 550px;
+	}
+	#dlg2 TABLE {
+		margin: 20px;
+	}
+	#dlg2 INPUT, #dlg2 TEXTAREA {
+		background-color: #000000;
+		color: #ffffff;
+		width: 90%;
+		font-size: 17px;
+		margin: 4px;
+	}
+	#dlg2 TEXTAREA {
+		height: 160px;
+	}
+	.dlgTitle {
+		font-family: Helvetica;
+		font-size: 17px;
+		margin: 14px 14px;
+	}
+	</style>
+	
+	<style>
+	#dlg3 {
+		top: 25%;
+		left: 25%;
+		width: 700px;
+		height: 550px;
+	}
+	#dlg3 TABLE {
+		margin: 20px;
+	}
+	#dlg3 INPUT, #dlg3 TEXTAREA {
+		background-color: #000000;
+		color: #ffffff;
+		width: 90%;
+		font-size: 17px;
+		margin: 4px;
+	}
+	#dlg3 TEXTAREA {
+		height: 160px;
+	}
+	.dlgTitle {
+		font-family: Helvetica;
+		font-size: 17px;
+		margin: 14px 14px;
+	}
+	</style>
+	
+	<style>
+	#dlg4 {
+		top: 25%;
+		left: 25%;
+		width: 700px;
+		height: 550px;
+	}
+	#dlg4 TABLE {
+		margin: 20px;
+	}
+	#dlg4 INPUT, #dlg4 TEXTAREA {
+		background-color: #000000;
+		color: #ffffff;
+		width: 90%;
+		font-size: 17px;
+		margin: 4px;
+	}
+	#dlg4 TEXTAREA {
+		height: 160px;
+	}
+	.dlgTitle {
+		font-family: Helvetica;
+		font-size: 17px;
+		margin: 14px 14px;
+	}
+	</style>
+	
+	<style>
+	#dlg5 {
+		top: 25%;
+		left: 25%;
+		width: 700px;
+		height: 550px;
+	}
+	#dlg5 TABLE {
+		margin: 20px;
+	}
+	#dlg5 INPUT, #dlg5 TEXTAREA {
+		background-color: #000000;
+		color: #ffffff;
+		width: 90%;
+		font-size: 17px;
+		margin: 4px;
+	}
+	#dlg5 TEXTAREA {
+		height: 160px;
+	}
+	.dlgTitle {
+		font-family: Helvetica;
+		font-size: 17px;
+		margin: 14px 14px;
+	}
+	</style>
+	
+	<style>
+	#dlg6 {
+		top: 25%;
+		left: 25%;
+		width: 700px;
+		height: 550px;
+	}
+	#dlg6 TABLE {
+		margin: 20px;
+	}
+	#dlg6 INPUT, #dlg6 TEXTAREA {
+		background-color: #000000;
+		color: #ffffff;
+		width: 90%;
+		font-size: 17px;
+		margin: 4px;
+	}
+	#dlg6 TEXTAREA {
+		height: 160px;
+	}
+	.dlgTitle {
+		font-family: Helvetica;
+		font-size: 17px;
+		margin: 14px 14px;
+	}
+	</style>
+	
+</head>
+<body style="visibility:hidden;">
+<datalist id="values">
+		<select data-dojo-type="dijit.form.DataList" data-dojo-props='id:"values"' >
+				<option selected>שלו&#1501!</option>
+				<option >Hello!</option>
+				
+		</select>
+		</datalist>
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	 <h2 data-dojo-type="dojox.mobile.Heading">Dialog</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir LTR</h1>
+		
+		<button onclick="show1()">Show Dialog</button>
+		
+	<div id="dlg1" data-dojo-type="dojox.mobile.SimpleDialog" data-dojo-props='closeButton:true'>
+		<div class="dlgTitle" >Dialog for Text dir test
+			<button data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:150px;float:right;" data-dojo-props='textDir:"ltr"'>שלום עולם !</button>
+		</div>
+		
+		<table style="width:100%">
+			<tr>
+				<td style="width:250px"><img alt="" src="../images/pic1.jpg" width="230" height="230"></td>
+				<td style="vertical-align:top">
+					<input data-dojo-type="dojox.mobile.TextBox" value="Hello World !" data-dojo-props='textDir:"ltr"' ><br>
+					<input data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello עולם!", list:"values", textDir:"ltr"'>
+					
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2"><textarea data-dojo-type="dojox.mobile.TextArea" data-dojo-props='textDir:"ltr"'>שלום World!</textarea></td>
+			</tr>
+		</table>
+	</div>
+		
+		
+		
+
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir RTL</h1>
+		
+		<button onclick="show2()">Show Dialog</button>
+		
+	<div id="dlg2" data-dojo-type="dojox.mobile.SimpleDialog" data-dojo-props='closeButton:true'>
+		<div class="dlgTitle" >Dialog for Text dir test
+			<button data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:150px;float:right;" data-dojo-props='textDir:"rtl"'>שלום עולם !</button>
+		</div>
+		
+		<table style="width:100%">
+			<tr>
+				<td style="width:250px"><img alt="" src="../images/pic1.jpg" width="230" height="230"></td>
+				<td style="vertical-align:top">
+					<input data-dojo-type="dojox.mobile.TextBox" data-dojo-props='value:"Hello World !", textDir:"rtl"' 	><br>
+					<input data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello עולם!", list:"values", textDir:"rtl"'>
+					
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2"><textarea data-dojo-type="dojox.mobile.TextArea" data-dojo-props='textDir:"rtl"'>שלום World!</textarea></td>
+			</tr>
+		</table>
+		</div>
+	</div>	
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir AUTO</h1>
+		<button onclick="show3()">Show Dialog</button>
+		
+	<div id="dlg3" data-dojo-type="dojox.mobile.SimpleDialog" data-dojo-props='closeButton:true'>
+		<div class="dlgTitle" >Dialog for Text dir test
+			<button data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:150px;float:right;" data-dojo-props='textDir:"auto"'>שלום עולם !</button>
+		</div>
+		
+		<table style="width:100%">
+			<tr>
+				<td style="width:250px"><img alt="" src="../images/pic1.jpg" width="230" height="230"></td>
+				<td style="vertical-align:top">
+					<input data-dojo-type="dojox.mobile.TextBox" value="Hello World !" data-dojo-props='textDir:"auto"' ><br>
+					<input data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello עולם!", list:"values", textDir:"auto"'>
+					
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2"><textarea data-dojo-type="dojox.mobile.TextArea" data-dojo-props='textDir:"auto"'>שלום World!</textarea></td>
+			</tr>
+		</table>
+		</div>
+	</div>	
+	 
+	<div id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir LTR</h1>
+		
+		<button onclick="show4()">Show Dialog</button>
+		
+	<div id="dlg4" dir="rtl" data-dojo-type="dojox.mobile.SimpleDialog" data-dojo-props='closeButton:true'>
+		<div class="dlgTitle" >Dialog for Text dir test
+			<button data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:150px;float:right;" data-dojo-props='textDir:"ltr"'>שלום עולם !</button>
+		</div>
+		
+		<table style="width:100%">
+			<tr>
+				<td style="width:250px"><img alt="" src="../images/pic1.jpg" width="230" height="230"></td>
+				<td style="vertical-align:top">
+					<input data-dojo-type="dojox.mobile.TextBox" value="Hello World !" data-dojo-props='textDir:"ltr"' ><br>
+					<input data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello עולם!", list:"values", textDir:"ltr"'>
+					
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2"><textarea data-dojo-type="dojox.mobile.TextArea" data-dojo-props='textDir:"ltr"'>שלום World!</textarea></td>
+			</tr>
+		</table>
+	</div>
+		
+		
+		
+		
+	</div>
+	<div id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDirRTR</h1>
+		
+		<button onclick="show5()">Show Dialog</button>
+		
+	<div id="dlg5" dir="rtl" data-dojo-type="dojox.mobile.SimpleDialog" data-dojo-props='closeButton:true'>
+		<div class="dlgTitle" >Dialog for Text dir test
+			<button data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:150px;float:right;" data-dojo-props='textDir:"rtl"'>שלום עולם !</button>
+		</div>
+		
+		<table style="width:100%">
+			<tr>
+				<td style="width:250px"><img alt="" src="../images/pic1.jpg" width="230" height="230"></td>
+				<td style="vertical-align:top">
+					<input data-dojo-type="dojox.mobile.TextBox" data-dojo-props='value:"Hello World !", textDir:"rtl"' 	><br>
+					<input data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello עולם!", list:"values", textDir:"rtl"'>
+					
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2"><textarea data-dojo-type="dojox.mobile.TextArea" data-dojo-props='textDir:"rtl"'>שלום World!</textarea></td>
+			</tr>
+		</table>
+		</div>
+		
+		
+		
+	</div>	
+	<div id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir AUTO</h1>
+		
+		<button onclick="show6()">Show Dialog</button>
+		
+	<div id="dlg6" dir="rtl" data-dojo-type="dojox.mobile.SimpleDialog" data-dojo-props='closeButton:true'>
+		<div class="dlgTitle" >Dialog for Text dir test
+			<button data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:150px;float:right;" data-dojo-props='textDir:"auto"'>שלום עולם !</button>
+		</div>
+		
+		<table style="width:100%">
+			<tr>
+				<td style="width:250px"><img alt="" src="../images/pic1.jpg" width="230" height="230"></td>
+				<td style="vertical-align:top">
+					<input data-dojo-type="dojox.mobile.TextBox" value="Hello World !" data-dojo-props='textDir:"auto"' ><br>
+					<input data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"Hello עולם!", list:"values", textDir:"auto"'>
+					
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2"><textarea data-dojo-type="dojox.mobile.TextArea" data-dojo-props='textDir:"auto"'>שלום World!</textarea></td>
+			</tr>
+		</table>
+		</div>
+		
+		
+			
+	</div>	
+</div>
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeCategoryList.html b/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeCategoryList.html
new file mode 100644
index 0000000..580e3dd
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeCategoryList.html
@@ -0,0 +1,439 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bidi Mobile test - EdgeToEdgeCategoryList</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true,  has: { 'dojo-bidi': true }"></script>
+
+<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",	
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/EdgeToEdgeCategory",				
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView"
+		], function(connect, ready, array, dom, registry){
+			
+			
+			ready(function(){
+			
+				
+				//change label 
+				var btnlbl1 = registry.byId("btnLbl");
+				btnlbl1.connect(btnlbl1, "onClick", function(){
+					registry.byId("category_auto1").set("label", "Start \u05e9\u05dc\u05d5\u05dd!	");	
+				        registry.byId("category_auto2").set("label", "\u05e9\u05dc\u05d5\u05dd End!	");			
+				});
+			
+				//change textDir for roundrect List	
+				var btn1 = registry.byId("btn1");	
+				btn1.connect(btn1, "onClick", function(){
+					registry.byId("category1").set("textDir", "ltr");
+					
+				});	
+				
+				var btn2 = registry.byId("btn2");	
+				btn2.connect(btn2, "onClick", function(){
+					registry.byId("category1").set("textDir", "rtl");
+					
+				});	
+					
+				var btn3 = registry.byId("btn3");	
+				btn3.connect(btn3, "onClick", function(){
+					registry.byId("category1").set("textDir", "auto");
+				
+				});
+				
+			});
+			
+			
+			
+		});
+	
+	</script>  
+</head>
+	
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategoryList widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectCategoryList</h2>
+		<button data-dojo-type="dojox.mobile.Button" id="btn1" class="mblRedButton" data-dojo-props='label:"Set first Category to textDir ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn2" class="mblRedButton" data-dojo-props='label:"Set first Category to textDir rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn3" class="mblRedButton" data-dojo-props='label:"Set first Category to textDir auto"'></button>		
+		<br>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" id="category1" data-dojo-props='textDir:"ltr"'>Hello world!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"ltr"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"ltr"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" id="category4" data-dojo-props='textDir:"ltr"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+			
+	
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategory</h2>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>Hello world!</h2>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World!
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+		
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategory</h2>
+		<br>
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text for two first Categories</button>
+		<br>
+		<br>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" id="category_auto1" data-dojo-props='textDir:"auto"'>Hello world!</h2>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World!
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" id="category_auto2" data-dojo-props='textDir:"auto"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"auto"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"auto"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+		
+		
+	</div>	
+	 
+	 
+	<div  id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategory</h2>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"ltr"'>Hello world!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"ltr"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"ltr"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"ltr"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+		
+			
+	</div>
+		
+	
+	
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategory</h2>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>Hello world!</h2>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World!
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+		
+		
+	</div>	
+	
+	<div id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>		
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategory</h2>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"auto"'>Hello world!</h2>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" dir=rtl data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World!
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"auto"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" dir=rtl data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"auto"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" dir=rtl data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"auto"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" dir=rtl data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeDataList.html b/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeDataList.html
new file mode 100644
index 0000000..373a5ba
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeDataList.html
@@ -0,0 +1,213 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bidi Mobile test - EdgeToEdgeDataList</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true,  has: { 'dojo-bidi': true }"></script>
+
+<script type="text/javascript">
+		require([
+			"dojo/data/ItemFileWriteStore",
+			"dijit/registry",
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",
+			"dojo/_base/lang",		
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",			
+			"dojox/mobile/RoundRectDataList",
+			"dojox/mobile/EdgeToEdgeDataList"
+		], function(ItemFileWriteStore, registry, runner, dom, ready, query, lang){
+			var static_data1 = {
+				items: [			
+				{ label: "Hello world!", icon: "../images/i-icon-1.png", moveTo: "wifi" },
+				{ label: "שלום עולם!", icon: "../images/i-icon-2.png", moveTo: "bright" },
+				{ label: "Hello עולם!", icon: "../images/i-icon-3.png", moveTo: "picture" },
+				{ label: "שלום World!", icon: "../images/i-icon-5.png", moveTo: "wifi" }
+				]				
+			};
+
+			var static_data2 = {
+				items: [			
+				{label: "שלום World!", 	moveTo: "dummy"},
+				{label: "Hello עולם!", 	moveTo: "dummy"},
+				{label: "שלום עולם!", 	moveTo: "dummy"},
+				{label: "Hello world!", 	moveTo: "dummy"}
+				]				
+			};
+			store1 = new ItemFileWriteStore({data: lang.clone(static_data1), clearOnClose: true});
+			store2 = new ItemFileWriteStore({data: lang.clone(static_data2), clearOnClose: true});
+			store = store1;
+			var newItems = [[],[]];
+			
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("roundrect_list1").setStore(store);
+				registry.byId("edgetoedge_list1").setStore(store);
+				registry.byId("roundrect_list2").setStore(store);
+				registry.byId("edgetoedge_list2").setStore(store);
+				registry.byId("roundrect_list3").setStore(store);
+				registry.byId("edgetoedge_list3").setStore(store);
+				registry.byId("roundrect_list4").setStore(store);
+				registry.byId("edgetoedge_list4").setStore(store);
+				registry.byId("roundrect_list5").setStore(store);
+				registry.byId("edgetoedge_list5").setStore(store);
+				registry.byId("roundrect_list6").setStore(store);
+				registry.byId("edgetoedge_list6").setStore(store);				
+			};
+			// add a new item
+			add1 = function(){
+				var item = store.newItem({label: "שלום World (new)!", moveTo: "dummy"});
+				newItems[(store == store1) ? 1 : 0].push(item);
+			};
+		});
+	</script>  
+</head>
+	
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectDataList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectDataList" id="roundrect_list1" data-dojo-props='textDir:"ltr", store:store, query:{label: "*"}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="edgetoedge_list1" data-dojo-props='textDir:"ltr", store:store, query:{label: "*"}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>		
+		
+			
+	
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+			
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectDataList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectDataList" id="roundrect_list2" data-dojo-props='textDir:"rtl", store:store, query:{label: "*"}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="edgetoedge_list2" data-dojo-props='textDir:"rtl", store:store, query:{label: "*"}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>			
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectDataList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectDataList" id="roundrect_list3" data-dojo-props='textDir:"auto", store:store, query:{label: "*"}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="edgetoedge_list3" data-dojo-props='textDir:"auto", store:store, query:{label: "*"}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>	
+		
+	</div>	
+	 
+	 
+	<div  id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectDataList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectDataList" dir=rtl id="roundrect_list4" data-dojo-props='textDir:"ltr", store:store, query:{label: "*"}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" dir=rtl id="edgetoedge_list4" data-dojo-props='textDir:"ltr", store:store, query:{label: "*"}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>	
+			
+			
+	</div>
+		
+	
+	
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectDataList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectDataList" id="roundrect_list5" data-dojo-props='textDir:"rtl", store:store, query:{label: "*"}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="edgetoedge_list5" data-dojo-props='textDir:"rtl", store:store, query:{label: "*"}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>		
+		
+		
+	</div>	
+	
+	<div id="view6" dir="rtl"  data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectDataList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectDataList" id="roundrect_list6"  data-dojo-props='textDir:"auto", store:store, query:{label: "*"}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="edgetoedge_list6"  data-dojo-props='textDir:"auto", store:store, query:{label: "*"}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>	
+				
+		
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeList.html b/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeList.html
new file mode 100644
index 0000000..ec0d3e0
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeList.html
@@ -0,0 +1,294 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - List</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/Heading",
+			"dojox/mobile/EdgeToEdgeList",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView"
+		], function(connect, ready, array, dom, registry, Heading, EdgeToEdgeList, ListItem){
+			ready(function(){
+				//create list programmaticaly
+				var view = registry.byId("view2");
+					
+				heading = new Heading({label:"Created programmatically EdgeToEdgeList, textDir is set to ListItem"});
+				view.addChild(heading);
+				list = new EdgeToEdgeList({iconBase:"../images/i-icon-all.png", textDir:"rtl"});
+				demoWidget = new ListItem({iconPos:"0,87,29,29", textDir:"rtl", rightIcon:"mblDomButtonBluePlus", label:"\u05e9\u05dc\u05d5\u05dd item1!"});
+				list.addChild(demoWidget);
+
+				demoWidget = new ListItem({iconPos:"0,116,29,29", textDir:"rtl", rightIcon:"mblDomButtonRedMinus", label:"RTL textDir set to ListItem!", rightText:"\u05e9\u05dc\u05d5\u05dd item2!"});
+				list.addChild(demoWidget);
+
+				view.addChild(list);
+				
+				//change label and rightText
+				var btn1 = registry.byId("btn1");
+				btn1.connect(btn1, "onClick", function(){
+					registry.byId("a1").set("label", "TEST for \u05e9\u05dc\u05d5\u05dd	!!");	
+					registry.byId("a2").set("label", "\u05e9\u05dc\u05d5\u05dd for TEST!!");			
+				});
+				var btn2 = registry.byId("btn2");
+				btn2.connect(btn2, "onClick", function(){
+					registry.byId("a1").set("rightText", "\u05e9\u05dc\u05d5\u05dd for mac!");
+					registry.byId("a2").set("rightText", "new for mac!");				
+				});
+				//change textDir for labelItem	
+				var btn0 = registry.byId("btn0");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("first4").set("textDir", "ltr");
+				});				
+	
+			});
+	
+	});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url('../images/red-button-bg.png');
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	 <h2 data-dojo-type="dojox.mobile.Heading">List widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir LTR</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"ltr"'>
+			<li id="01" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello World!</li>
+			<li id="02" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום עולם!</li>
+			<li id="03" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello עולם!</li>
+			<li id="04" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום World!</li>
+		</ul>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"ltr"'>
+			<li id="first" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-1.png"'>
+				<font style="font-style:italic; font-size: 16pt">שלום עולם </font>direction!!
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li id="second" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-2.png",rightText:"mac.", moveTo:"hello."'>
+				 חדש-Wi-Fi! 		
+				 <span>חדש-internet!</span> 				
+				 חדש-speedy! 
+				 <font style="font-style:italic">LTR direction!</font> 		
+			</li>
+			<li id="third" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-3.png", rightText:"AcmePhone.", moveTo:"hello."'>
+				Direction חדש!
+			</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">List textDir "ltr", list item textDir "rtl" or "auto"</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"ltr"'>
+			<li id="first4" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='textDir:"rtl",icon:"../images/i-icon-1.png", rightText:"mac."'>
+				<font style="font-style:italic; font-size: 16pt">חדש </font>direction RTL!!
+			</li>
+			<li id="second4" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='textDir:"ltr", icon:"../images/i-icon-2.png",rightText:"mac.", moveTo:"hello."'>
+				 חדש-Wi-Fi! 		
+				 <span>חדש-internet!</span> 				
+				 חדש-speedy! 
+				 <font style="font-style:italic">AUTO direction!</font> 				
+			</li>
+		</ul>
+		<button data-dojo-type="dojox.mobile.Button" id="btn0" >Set textDir ltr to Item rtl</button>		
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li id="r1" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello World!</li>
+			<li id="r2" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום עולם!</li>
+			<li id="r3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello עולם!</li>
+			<li id="r4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום World!</li>
+		</ul>			
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li id="first2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-1.png"'>
+				<font style="font-style:italic; font-size: 16pt">חדש </font>direction!!
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li id="second2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-2.png",rightText:"mac.", moveTo:"hello."'>
+				 חדש-Wi-Fi! 		
+				 <span>חדש-internet!</span> 				
+				 חדש-speedy! 
+				 <font style="font-style:italic">Rtl direction!</font> 				
+			</li>
+			<li id="third2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-3.png", rightText:"AcmePhone.", moveTo:"hello."'>
+				Direction חדש!
+			</li>
+		</ul>
+	</div>	
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir AUTO</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li id="a1" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello World!</li>
+			<li id="a2" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום עולם!</li>
+			<li id="a3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello עולם!</li>
+			<li id="a4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום World!</li>
+		</ul>		
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li id="first3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-1.png"'>
+				<font style="font-style:italic; font-size: 16pt">חדש </font>direction!!
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li id="second3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-2.png", rightText:"חדש for mac!", moveTo:"hello."'>
+				 חדש-Wi-Fi! 		
+				 <span>חדש-internet!</span> 				
+				 חדש-speedy! 
+				 <font style="font-style:italic">AUTO direction!</font> 				
+			</li>
+			<li id="third3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-3.png", rightText:"AcmePhone (חדש)", moveTo:"hello."'>
+				Direction חדש!
+			</li>
+			</ul>
+			<button data-dojo-type="dojox.mobile.Button" id="btn1" >Set new text to list Item label</button>
+			<button data-dojo-type="dojox.mobile.Button" id="btn2" >Set new text to list Item right text</button>
+			<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>complicated - link, table</h1>
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+					Sarah Connor Hardcover<br>
+					Eligible for FREE Super Saver Shipping<br>
+					<span style="color:red">$14.50 (50%)</span> In Stock<br>
+					# (531)
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true, textDir:"rtl"' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="../images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse...</a><br>
+									<b>TEXT DIR RTL in this LIST ITEM...</b><br>
+									Steven Young Hardcover...<br>
+									Eligible for FREE Super Saver Shipping...<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+	</div>	
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir LTR</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"ltr"'>
+			<li id="rl1" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello World!</li>
+			<li id="rl2" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום עולם!</li>
+			<li id="rl3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello עולם!</li>
+			<li id="rl4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום World!</li>
+		</ul>			
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"ltr"'>
+			<li id="first21" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-1.png"'>
+				<font style="font-style:italic; font-size: 16pt">חדש </font>direction!!
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li id="second21" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-2.png",rightText:"mac.", moveTo:"hello."'>
+				 Wi-Fi! 		
+				 <span>Internet!</span> 				
+				 Speedy! 
+				 <font style="font-style:italic">LTR direction!</font> 				
+			</li>
+			<li id="third21" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-3.png", rightText:"AcmePhone.", moveTo:"hello."'>
+				Direction חדש!
+			</li>
+		</ul>
+	</div>
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li id="rr1" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello World!</li>
+			<li id="rr2" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום עולם!</li>
+			<li id="rr3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello עולם!</li>
+			<li id="rr4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום World!</li>
+		</ul>		
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li id="first22" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-1.png"'>
+				<font style="font-style:italic; font-size: 16pt">חדש </font>direction!!
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li id="second22" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-2.png",rightText:"mac.", moveTo:"hello."'>
+				 Wi-Fi! 		
+				 <span>Internet!</span> 				
+				 Speedy! 
+				 <font style="font-style:italic">Rtl direction!</font> 				
+			</li>
+			<li id="third22" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-3.png", rightText:"AcmePhone.", moveTo:"hello."'>
+				Direction חדש!
+			</li>
+		</ul>
+	</div>	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir AUTO</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li id="ra1" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello World!</li>
+			<li id="ra2" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום עולם!</li>
+			<li id="ra3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>Hello עולם!</li>
+			<li id="ra4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/i-icon-2.png"'>שלום World!</li>
+		</ul>			
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li id="first23" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-1.png"'>
+				<font style="font-style:italic; font-size: 16pt">חדש </font>direction!!
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li id="second23" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-2.png",rightText:"חדש for mac!", moveTo:"hello."'>
+				 חדש! 		
+				 <span>חדש!</span> 				
+				 חדש! 
+				 <font style="font-style:italic">Auto direction!</font> 				
+			</li>
+			<li id="third23" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-3.png", rightText:"AcmePhone.", moveTo:"hello."'>
+				Direction חדש!
+			</li>
+			</ul>
+	</div>	
+</div>
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeStoreList.html b/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeStoreList.html
new file mode 100644
index 0000000..4ed91a8
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_EdgeToEdgeStoreList.html
@@ -0,0 +1,213 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bidi Mobile test - EdgeToEdgeStoreList</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true,  has: { 'dojo-bidi': true }"></script>
+
+<script type="text/javascript">
+		require([
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",		
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/RoundRectStoreList",
+			"dojox/mobile/EdgeToEdgeStoreList"	
+		], function(Memory, Observable, registry, runner, dom, ready, query){
+			var static_data1 = {
+				items: [			
+				{ label: "Hello world!", icon: "../images/i-icon-1.png", moveTo: "wifi" },
+				{ label: "שלום עולם!", icon: "../images/i-icon-2.png", moveTo: "bright" },
+				{ label: "Hello עולם!", icon: "../images/i-icon-3.png", moveTo: "picture" },
+				{ label: "שלום World!", icon: "../images/i-icon-5.png", moveTo: "wifi" }
+				]				
+			};
+
+			var static_data2 = {
+				items: [			
+				{label: "שלום World!", 	moveTo: "dummy"},
+				{label: "Hello עולם!", 	moveTo: "dummy"},
+				{label: "שלום עולם!", 	moveTo: "dummy"},
+				{label: "Hello world!", 	moveTo: "dummy"}
+				]				
+			};
+			store1 = Observable(new Memory({idProperty:"label", data: static_data1}));
+			store2 = Observable(new Memory({idProperty:"label", data: static_data2}));
+			store1.__counter = store2.__counter = 1;
+			store = store1;
+			
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("roundrect_list1").setStore(store);
+				registry.byId("edgetoedge_list1").setStore(store);
+				registry.byId("roundrect_list2").setStore(store);
+				registry.byId("edgetoedge_list2").setStore(store);
+				registry.byId("roundrect_list3").setStore(store);
+				registry.byId("edgetoedge_list3").setStore(store);
+				registry.byId("roundrect_list4").setStore(store);
+				registry.byId("edgetoedge_list4").setStore(store);
+				registry.byId("roundrect_list5").setStore(store);
+				registry.byId("edgetoedge_list5").setStore(store);
+				registry.byId("roundrect_list6").setStore(store);
+				registry.byId("edgetoedge_list6").setStore(store);				
+			};
+			// add a new item
+			add1 = function(){
+				store.add({label: "חדש"+(store.__counter++)+ "!",icon: "../images/i-icon-1.png",moveTo: "dummy"});
+			};
+		});
+	</script>  
+</head>
+	
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectStoreList" id="roundrect_list1" data-dojo-props='textDir:"ltr", store:store, query:{}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="edgetoedge_list1" data-dojo-props='textDir:"ltr", store:store, query:{}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>		
+		
+			
+	
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+			
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectStoreList" id="roundrect_list2" data-dojo-props='textDir:"rtl", store:store, query:{}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="edgetoedge_list2" data-dojo-props='textDir:"rtl", store:store, query:{}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>			
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectStoreList" id="roundrect_list3" data-dojo-props='textDir:"auto", store:store, query:{}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="edgetoedge_list3" data-dojo-props='textDir:"auto", store:store, query:{}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>	
+		
+	</div>	
+	 
+	 
+	<div  id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectStoreList" dir=rtl id="roundrect_list4" data-dojo-props='textDir:"ltr", store:store, query:{}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" dir=rtl id="edgetoedge_list4" data-dojo-props='textDir:"ltr", store:store, query:{}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>	
+			
+			
+	</div>
+		
+	
+	
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectStoreList" id="roundrect_list5" data-dojo-props='textDir:"rtl", store:store, query:{}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="edgetoedge_list5" data-dojo-props='textDir:"rtl", store:store, query:{}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>		
+		
+		
+	</div>	
+	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectStoreList" id="roundrect_list6" data-dojo-props='textDir:"auto", store:store, query:{}'></ul>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="edgetoedge_list6" data-dojo-props='textDir:"auto", store:store, query:{}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add1()">
+		</td></tr></table>	
+				
+		
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_Heading.html b/dojox/mobile/tests/bidi/Bidi_Heading.html
new file mode 100644
index 0000000..fe66478
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_Heading.html
@@ -0,0 +1,218 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - Heading</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/Heading",			
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/ListItem"
+		], function(connect, ready, array, dom, registry, Heading){
+			ready(function(){
+				var view = registry.byId("view2");
+				var demoWidget = new Heading({label:"Programm Heading!", textDir:"rtl", id:"hdn", back:"\u05e9\u05d9\u05de\u05d5\u05e9\u0020\u05d1\u05ea\u05d2\u05d9\u05d5\u05ea back..."});
+				view.addChild(demoWidget);	
+				//change textDir, text
+				var btnLtr = registry.byId("btn5");				
+				btnLtr.connect(btnLtr, "onClick", function(){
+					registry.byId("h1").set("textDir", "ltr");
+				});
+				var btnRtl = registry.byId("btn6");
+				btnLtr.connect(btnRtl, "onClick", function(){
+					registry.byId("h1").set("textDir", "rtl");
+				});	
+				var btnAuto = registry.byId("btn7");
+				btnAuto.connect(btnAuto, "onClick", function(){
+					registry.byId("h1").set("textDir", "auto");				
+				});						
+				var btnLbl = registry.byId("btnLbl");
+				btnLbl.connect(btnLbl, "onClick", function(){
+					registry.byId("hAuto").set("label", "\u05e9\u05dc\u05d5\u05dd for test!");
+					registry.byId("hAuto").set("back", "\u05e9\u05dc\u05d5\u05dd for test!");
+					registry.byId("tbAuto").set("label", "\u05e9\u05dc\u05d5\u05dd for test!");
+				});				
+		});
+	
+	});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url('../images/red-button-bg.png');
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	 <h2 data-dojo-type="dojox.mobile.Heading">Heading widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir LTR</h1>
+		<div data-dojo-type="dojox.mobile.Heading" id="h1" data-dojo-props='textDir:"ltr", label:"Hello World!", back:"Hello World!" '>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue"  >Hello World!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >Hello עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום World!</span>
+		</div><br>
+
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"ltr", back:"שלום עולם!"'>שלום עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props='textDir:"ltr",  back:"Hello עולם!"'>Hello עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"ltr", back:"שלום World!"'>שלום World!
+		</div><br>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn5" class="mblRedButton" data-dojo-props='label:"Set textDir ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn6" class="mblRedButton" data-dojo-props='label:"Set textDir rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn7" class="mblRedButton" data-dojo-props='label:"Set textDir auto"'></button>	
+		<hr>
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='textDir:"ltr", label:"RTL text Dir in ToolBarButton"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" defaultColor="mblColorBlue" data-dojo-props='icon:"mblDomButtonWhitePlus",textDir:"rtl", label:"Hello עולם!"' style="width:120px"></span>
+		</div><br>
+		
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+			<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir RTL</h1>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props='textDir:"rtl", label:"Hello World!", back:"Hello World!" '>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue"  >Hello World!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >Hello עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום World!</span>
+		</div><br>
+
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"rtl", back:"שלום עולם!"'>שלום עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props='textDir:"rtl",  back:"Hello עולם!"'>Hello עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"rtl", back:"שלום World!"'>שלום World!
+		</div><br>
+		<hr>
+		<h1 data-dojo-type="dojox.mobile.Heading">Programmatically created</h1>
+	
+	</div>	
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir AUTO</h1>
+		<div data-dojo-type="dojox.mobile.Heading" id="hAuto" data-dojo-props='textDir:"auto", label:"Hello World!", back:"Hello World!" '>
+			<span id="tbAuto" data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue"  >Hello World!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >Hello עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום World!</span>
+		</div><br>
+
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"auto", back:"שלום עולם!"'>שלום עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props='textDir:"auto",  back:"Hello עולם!"'>Hello עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"auto", back:"שלום World!"'>שלום World!
+		</div><br>
+		<hr>		
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text</button>		
+		
+	</div>	
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir LTR</h1>
+		<hr>
+		<div data-dojo-type="dojox.mobile.Heading" id="h11" data-dojo-props='textDir:"ltr", label:"Hello World!", back:"Hello World!" '>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue"  >Hello World!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >Hello עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום World!</span>
+		</div><br>
+
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"ltr", back:"שלום עולם!"'>שלום עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props='textDir:"ltr",  back:"Hello עולם!"'>Hello עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"ltr", back:"שלום World!"'>שלום World!
+		</div><br>
+		
+
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='textDir:"ltr", label:"RTL text Dir in ToolBarButton"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" defaultColor="mblColorBlue" data-dojo-props='icon:"mblDomButtonWhitePlus",textDir:"rtl", label:"Hello עולם!"' style="width:120px"></span>
+		</div><br>
+	</div>
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDirRTR</h1>
+		<hr>		
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props='textDir:"rtl", label:"Hello World!", back:"Hello World!" '>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue"  >Hello World!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >Hello עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום World!</span>
+		</div><br>
+
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"rtl", back:"שלום עולם!"'>שלום עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props='textDir:"rtl",  back:"Hello עולם!"'>Hello עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"rtl", back:"שלום World!"'>שלום World!
+		</div><br>
+	</div>	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir AUTO</h1>
+		<hr>	
+		<div data-dojo-type="dojox.mobile.Heading" id="hAuto1" data-dojo-props='textDir:"auto", label:"Hello World!", back:"Hello World!" '>
+			<span id="tbAuto1" data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue"  >Hello World!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >Hello עולם!</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"   defaultColor="mblColorBlue" >שלום World!</span>
+		</div><br>
+
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"auto", back:"שלום עולם!"'>שלום עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props='textDir:"auto",  back:"Hello עולם!"'>Hello עולם!
+		</div><br>
+		<div data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' textDir:"auto", back:"שלום World!"'>שלום World!
+		</div><br>
+	</div>	
+</div>
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_IconContainer.html b/dojox/mobile/tests/bidi/Bidi_IconContainer.html
new file mode 100644
index 0000000..1cbcff8
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_IconContainer.html
@@ -0,0 +1,176 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - Icon Container</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer','TabBar']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true, has: { 'dojo-bidi': true }"></script>
+
+<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/IconItem",  	
+			"dojox/mobile/Button",
+			"dojox/mobile/EdgeToEdgeDataList",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/ListItem"
+		], function(connect, ready, array, dom, registry){
+			ready(function(){
+				//change textDir for icon4	
+				var btn0 = registry.byId("btn0");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("icon4").set("textDir", "ltr");
+				});	
+				
+				var btn0 = registry.byId("btn1");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("icon4").set("textDir", "rtl");
+				});	
+					
+				var btn0 = registry.byId("btn2");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("icon4").set("textDir", "auto");
+				});
+				// change label for icon container				
+				var btnLbl = registry.byId("btnLbl");
+				btnLbl.connect(btnLbl, "onClick", function(){
+				var c = registry.byId("icon4_auto");
+				var l = c.get("label");
+				c.set("label", "new");
+				var n =  c.get("label");
+				
+					registry.byId("icon4_auto").set("label", "\u05e9\u05dc\u05d5\u05dd for test!");
+				});
+			});
+	
+	});
+	</script>  
+	
+	
+
+	<style>
+	.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url('../images/widget-bg.png');
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+	
+	
+</head>
+	
+<body style="visibility:hidden;">
+
+	<div id="view0" data-dojo-type="dojox.mobile.View">
+	        <h2 data-dojo-type="dojox.mobile.Heading">Icon Container widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='textDir:"ltr"'>
+			<li data-dojo-type="dojox.mobile.IconItem" id="icon1" data-dojo-props='label:"Hello world!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" id="icon2" data-dojo-props='label:"שלום עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Hello עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" id="icon4" data-dojo-props='label:"שלום World!", icon:"../images/icon1.png", href:"../data/fragment1.html", transition:"slide"'></li>
+			</ul>
+			
+			<button data-dojo-type="dojox.mobile.Button" id="btn0" >Set textDir for Icon container to ltr</button>
+			<button data-dojo-type="dojox.mobile.Button" id="btn1" >Set textDir for Icon container to rtl</button>
+			<button data-dojo-type="dojox.mobile.Button" id="btn2" >Set textDir for Icon container to auto</button>
+	
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+			
+			<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Hello world!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"שלום עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Hello עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"שלום World!", icon:"../images/icon1.png", href:"../data/fragment1.html", transition:"slide"'></li>
+			</ul>	
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.View">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Hello world!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"שלום עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Hello עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" id="icon4_auto" data-dojo-props='label:"שלום World!", icon:"../images/icon1.png", href:"../data/fragment1.html", transition:"slide"'></li>
+			</ul>
+				
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text Button</button>
+	</div>	
+	 
+	 
+	<div dir=rtl  id="view4" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		
+		<ul data-dojo-type="dojox.mobile.IconContainer" dir="rtl" data-dojo-props='textDir:"ltr"'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Hello world!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"שלום עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Hello עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"שלום World!", icon:"../images/icon1.png", href:"../data/fragment1.html", transition:"slide"'></li>
+			</ul>
+	</div>
+	
+	
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+			<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Hello world!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"שלום עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Hello עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"שלום World!", icon:"../images/icon1.png", href:"../data/fragment1.html", transition:"slide"'></li>
+			</ul>	
+		
+	</div>	
+	
+	<div dir=rtl id="view6" data-dojo-type="dojox.mobile.View">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+			
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.IconItem" dir="rtl" data-dojo-props='label:"Hello world!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" dir="rtl" data-dojo-props='label:"שלום עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" dir=rtl data-dojo-props='label:"Hello עולם!", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" dir=rtl data-dojo-props='label:"שלום World!", icon:"../images/icon1.png", href:"../data/fragment1.html", transition:"slide"'></li>
+			</ul>
+				
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_IconMenu.html b/dojox/mobile/tests/bidi/Bidi_IconMenu.html
new file mode 100644
index 0000000..1a22364
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_IconMenu.html
@@ -0,0 +1,196 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - TabBar</title>
+	
+	<link href="../../themes/common/domButtons/DomButtonYellowStar.css" rel="stylesheet"/>
+	<link href="../../themes/common/domButtons/DomButtonGrayStar.css" rel="stylesheet"/>	
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconMenu']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/IconMenu", 
+			"dojox/mobile/IconMenuItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/Heading",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/Heading"
+		], function(connect, ready, array, dom, registry, IconMenu, IconMenuItem){
+			ready(function(){
+				var view = registry.byId("view2");
+				var menu = new IconMenu({
+					cols: 1
+				}, "container");
+				menu.startup();
+
+				item = new IconMenuItem({
+					label: "Hello \u05e9\u05dc\u05d5\u05dd\u0021",
+					textDir:"rtl", 
+					selected:true
+				});
+				menu.addChild(item);
+				view.addChild(menu);	
+
+				//change textDir, text
+				var btnLtr = registry.byId("btn5");				
+				btnLtr.connect(btnLtr, "onClick", function(){
+					registry.byId("im1").set("textDir", "ltr");
+				});
+				var btnRtl = registry.byId("btn6");
+				btnLtr.connect(btnRtl, "onClick", function(){
+					registry.byId("im1").set("textDir", "rtl");
+				});	
+				var btnAuto = registry.byId("btn7");
+				btnAuto.connect(btnAuto, "onClick", function(){
+					registry.byId("im1").set("textDir", "auto");				
+				});						
+				var btnLbl = registry.byId("btnLbl");
+				btnLbl.connect(btnLbl, "onClick", function(){
+					registry.byId("tbAuto").set("label", "\u05e9\u05dc\u05d5\u05dd for test!");
+					//registry.byId("tbAuto").set("badge", "\u05e9\u05dc\u05d5\u05dd for test!");
+				});						
+		});
+	
+	});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url('../images/red-button-bg.png');
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	 <h2 data-dojo-type="dojox.mobile.Heading">IconMenu widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir LTR</h1>
+		<ul data-dojo-type="dojox.mobile.IconMenu" id="im1" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:2, textDir:"ltr"'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello World!", icon:"../images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום עולם!", icon:"../images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello עולם!", icon:"../images/tab-icon-30w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום World!", icon:"../images/tab-icon-16w.png"'></li>
+		</ul>
+		<hr>		
+		<button data-dojo-type="dojox.mobile.Button" id="btn5" class="mblRedButton" data-dojo-props='label:"Set textDir ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn6" class="mblRedButton" data-dojo-props='label:"Set textDir rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn7" class="mblRedButton" data-dojo-props='label:"Set textDir auto"'></button>		
+		<hr>
+		<h1 data-dojo-type="dojox.mobile.Heading" >IconMenu textDir LTR, IconMenuItem textDir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.IconMenu"  style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:1, textDir:"ltr"'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello World!", textDir:"rtl", icon:"../images/tab-icon-36w.png", selected:true'></li>
+		</ul>
+		<hr>		
+		
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.IconMenu" id="im2" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:2, textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello World!", icon:"../images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום עולם!", icon:"../images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello עולם!", icon:"../images/tab-icon-30w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום World!", icon:"../images/tab-icon-16w.png"'></li>
+		</ul>
+			<hr>
+			<h1 data-dojo-type="dojox.mobile.Heading">Programmatically created IconMenuItem</h1>
+			<div id="container" style="width:274px;height:210px;margin:20px;"></div>
+
+		
+	</div>	
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir AUTO</h1>
+		<ul data-dojo-type="dojox.mobile.IconMenu" id="im3" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:2, textDir:"auto"'>
+			<li id="tbAuto" data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello World!", icon:"../images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום עולם!", icon:"../images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello עולם!", icon:"../images/tab-icon-30w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום World!", icon:"../images/tab-icon-16w.png"'></li>
+		</ul>
+		<hr>		
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text</button>		
+		
+	</div>	
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir LTR</h1>
+		<hr>
+		<ul data-dojo-type="dojox.mobile.IconMenu" id="im11" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:2, textDir:"ltr"'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello World!", icon:"../images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום עולם!", icon:"../images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello עולם!", icon:"../images/tab-icon-30w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום World!", icon:"../images/tab-icon-16w.png"'></li>
+		</ul>
+		<hr>
+		<h1 data-dojo-type="dojox.mobile.Heading" >IconMenu textDir LTR, IconMenuItem textDir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.IconMenu"  style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:2, textDir:"ltr"'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello World!", textDir:"rtl", icon:"../images/tab-icon-36w.png", selected:true'></li>
+		</ul>
+	</div>
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDirRTR</h1>
+		<hr>		
+		<ul data-dojo-type="dojox.mobile.IconMenu" id="im22" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:2, textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello World!", icon:"../images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום עולם!", icon:"../images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello עולם!", icon:"../images/tab-icon-30w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום World!", icon:"../images/tab-icon-16w.png"'></li>
+		</ul>
+	</div>	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir AUTO</h1>
+		<hr>	
+		<ul data-dojo-type="dojox.mobile.IconMenu" id="im33" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:2, textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello World!", icon:"../images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום עולם!", icon:"../images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Hello עולם!", icon:"../images/tab-icon-30w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"שלום World!", icon:"../images/tab-icon-16w.png"'></li>
+		</ul>
+	</div>	
+</div>
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_Index.html b/dojox/mobile/tests/bidi/Bidi_Index.html
new file mode 100644
index 0000000..1f158bb
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_Index.html
@@ -0,0 +1,152 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<title>dojox.mobile</title>
+	<style>
+	body {
+		font-family: Helvetica;
+		font-size: 17px;
+	}
+	.section {
+		font-weight: bold;
+		color: #008080;
+	}
+	.titleBar {
+		padding: 10px 0;
+	}
+	.contents {
+		margin-left: 30px;
+		font-weight: normal;
+		color: #000000;
+	}
+	.item {
+		position: relative;
+		border-bottom: 1px solid gray;
+	}
+	.anchor {
+		display: block;
+		padding: 10px 0;
+		text-decoration: none;
+	}
+	</style>
+	<script src="Bidi_index.js"></script>
+	<script>
+		function setRightIcon(icon){
+			icon.src = "../../themes/common/domButtons/compat/mblDomButtonBlackRightArrow16.png";
+		}
+		function setDownIcon(icon){
+			icon.src = "../../themes/common/domButtons/compat/mblDomButtonBlackDownArrow16.png";
+		}
+		function isRightIcon(icon){
+			return (icon.src && icon.src.indexOf("Right") !== -1);
+		}
+
+		function sort(keys){
+			var data = [];
+			for(var i = 0; i < keys.length; i++){
+				var key = keys[i];
+				var items = [];
+				items.label = key.label;
+				for(var j = 0; j < tests.length; j++){
+					var item = tests[j];
+					var url = item.url;
+					var label = item.label || item.url;
+					var tags = item.tags ? item.tags.split(/,/) : [];
+					for(var k = 0; k < tags.length; k++){
+						if(tags[k] === key.tag){
+							items.push(item);
+						}
+					}
+				}
+				data.push(items);
+			}
+			return data;
+		}
+		function init(){
+			var theme = document.getElementById("sel1").value;
+			var container = document.getElementById("container");
+			container.innerHTML = "";
+			var data = sort(categories);
+			for(var i = 0; i < data.length; i++){
+				var items = data[i];
+				if(items.length == 0){ continue; }
+
+				var section = document.createElement("div");
+				section.className = "section";
+				container.appendChild(section);
+
+				var titleBar = document.createElement("div");
+				titleBar.className = "titleBar";
+				titleBar.onclick = toggleSection;
+				section.appendChild(titleBar);
+
+				var icon = document.createElement("img");
+				icon.className = "icon";
+				setRightIcon(icon);
+				titleBar.appendChild(icon);
+
+				var title = document.createElement("label");
+				title.className = "title";
+				title.innerHTML = items.label + " (" + items.length + ")";
+				titleBar.appendChild(title);
+
+				var contents = document.createElement("div");
+				contents.className = "contents";
+				contents.style.display = "none";
+				section.appendChild(contents);
+
+				for(var j = 0; j < items.length; j++){
+					var item = items[j];
+					var url = item.url;
+					var label = item.label || item.url;
+
+					var item = document.createElement("div");
+					item.className = "item";
+					contents.appendChild(item);
+
+					var anchor = document.createElement("a");
+					anchor.className = "anchor";
+					anchor.href = url + (theme ? "?theme=" + theme : "");
+					anchor.target = "_blank";
+					anchor.innerHTML = label;
+					item.appendChild(anchor);
+				}
+			}
+		}
+
+		function toggleSection(e){
+			e = e || event;
+			var node = e.srcElement ? e.srcElement : e.target;
+			var titleBar = (node.className == "titleBar") ? node : node.parentNode;
+			var img = titleBar.childNodes[0];
+			var label = titleBar.childNodes[1];
+			var contents = titleBar.nextSibling;
+			if (isRightIcon(img)){
+				setDownIcon(img);
+				contents.style.display = "block";
+			}
+			else {
+				setRightIcon(img);
+				contents.style.display = "none";
+			}
+			e.cancelBubble = true;
+		}
+
+		function onThemeChange(){
+			var theme = document.getElementById("sel1").value;
+			var nodes = document.getElementsByTagName("a");
+			for(var i = 0; i < nodes.length; i++){
+				var a = nodes[i];
+				a.href = a.href.replace(/(\?theme=.*)?$/, theme ? "?theme=" + theme : "");
+			}
+		}
+	</script>
+</head>
+<body onload="init()">
+	<div id="sel1" onchange="onThemeChange()">
+		
+	</div><br>
+	<div id="container"></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_RoundRectCategoryList.html b/dojox/mobile/tests/bidi/Bidi_RoundRectCategoryList.html
new file mode 100644
index 0000000..73255c2
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_RoundRectCategoryList.html
@@ -0,0 +1,441 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bidi Mobile test - EdgeToEdgeCategoryList</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true,  has: { 'dojo-bidi': true }"></script>
+
+<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",	
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/EdgeToEdgeCategory",				
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView"
+		], function(connect, ready, array, dom, registry){
+			
+			
+			ready(function(){
+			
+				
+				//change label 
+				var btnlbl1 = registry.byId("btnLbl");
+				btnlbl1.connect(btnlbl1, "onClick", function(){
+					registry.byId("category_auto1").set("label", "Start \u05e9\u05dc\u05d5\u05dd!	");	
+				        registry.byId("category_auto2").set("label", "\u05e9\u05dc\u05d5\u05dd End!	");			
+				});
+			
+				//change textDir for roundrect List	
+				var btn1 = registry.byId("btn1");	
+				btn1.connect(btn1, "onClick", function(){
+					registry.byId("category1").set("textDir", "ltr");
+					
+				});	
+				
+				var btn2 = registry.byId("btn2");	
+				btn2.connect(btn2, "onClick", function(){
+					registry.byId("category1").set("textDir", "rtl");
+					
+				});	
+					
+				var btn3 = registry.byId("btn3");	
+				btn3.connect(btn3, "onClick", function(){
+					registry.byId("category1").set("textDir", "auto");
+				
+				});
+				
+			});
+			
+			
+			
+		});
+			
+		
+	</script>  
+</head>
+	
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategoryList widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">RoundRectCategoryList</h2>
+		<button data-dojo-type="dojox.mobile.Button" id="btn1" class="mblRedButton" data-dojo-props='label:"Set first Category to textDir ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn2" class="mblRedButton" data-dojo-props='label:"Set first Category to textDir rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn3" class="mblRedButton" data-dojo-props='label:"Set first Category to textDir auto"'></button>		
+		<br>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory" id="category1" data-dojo-props='textDir:"ltr"'>Hello world!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"ltr"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"ltr"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" id="category4" data-dojo-props='textDir:"ltr"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+			
+	
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategory</h2>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>Hello world!</h2>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World!
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+		
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategory</h2>
+		<br>
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text for two first Categories</button>
+		<br>
+		<br>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" id="category_auto1" data-dojo-props='textDir:"auto"'>Hello world!</h2>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World!
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" id="category_auto2" data-dojo-props='textDir:"auto"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"auto"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"auto"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+		
+		
+	</div>	
+	 
+	 
+	<div  id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategory</h2>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"ltr"'>Hello world!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"ltr"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"ltr"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"ltr"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+		
+			
+	</div>
+		
+	
+	
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategory</h2>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>Hello world!</h2>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World!
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" data-dojo-props='textDir:"rtl"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+		
+		
+	</div>	
+	
+	<div id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>		
+		<h2 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeCategory</h2>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"auto"'>Hello world!</h2>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" dir=rtl data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello world!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hello עולם!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				שלום World!
+			</li>
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"auto"'>שלום עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" dir=rtl data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Hi!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				bye!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"auto"'>Hello עולם!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" dir=rtl data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				amir!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Sasha!
+			</li>
+	
+		</ul>
+		
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory" dir=rtl data-dojo-props='textDir:"auto"'>שלום World!</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" dir=rtl data-dojo-props='textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Lena!
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Tomer!
+			</li>
+	
+		</ul>
+		
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_SearchBox.html b/dojox/mobile/tests/bidi/Bidi_SearchBox.html
new file mode 100644
index 0000000..084d39e
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_SearchBox.html
@@ -0,0 +1,195 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bidi Mobile test - SearchBox</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SearchBox']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+
+	
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dijit/_base/manager",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/SearchBox",
+			"dojox/mobile/Button",
+			"dojox/mobile/EdgeToEdgeDataList",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/compat"
+		], function(connect, ready, array, dom, registry){
+			ready(function(){
+				//change textDir, text
+				var btnLtr = registry.byId("btn1");				
+				btnLtr.connect(btnLtr, "onClick", function(){
+					registry.byId("ltrSearchBox1").set("textDir", "ltr");
+					registry.byId("ltrSearchBox2").set("textDir", "ltr");
+					registry.byId("ltrSearchBox3").set("textDir", "ltr");
+					registry.byId("ltrSearchBox4").set("textDir", "ltr");
+				});
+				var btnRtl = registry.byId("btn2");
+				btnRtl.connect(btnRtl, "onClick", function(){
+					registry.byId("ltrSearchBox1").set("textDir", "rtl");
+					registry.byId("ltrSearchBox2").set("textDir", "rtl");
+					registry.byId("ltrSearchBox3").set("textDir", "rtl");
+					registry.byId("ltrSearchBox4").set("textDir", "rtl");				
+				});	
+				var btnAuto = registry.byId("btn3");
+				btnAuto.connect(btnAuto, "onClick", function(){
+					registry.byId("ltrSearchBox1").set("textDir", "auto");
+					registry.byId("ltrSearchBox2").set("textDir", "auto");
+					registry.byId("ltrSearchBox3").set("textDir", "auto");
+					registry.byId("ltrSearchBox4").set("textDir", "auto");					
+				});
+				
+				// change label for icon container				
+				var btnLbl = registry.byId("btnLbl");
+				btnLbl.connect(btnLbl, "onClick", function(){
+				var c = registry.byId("autoSearchBox1");
+				var l = c.get("label");
+				c.set("label", "new");
+				var n =  c.get("label");
+				
+					registry.byId("autoSearchBox1").set("placeHolder","\u05e9\u05dc\u05d5\u05dd END!");
+					registry.byId("autoSearchBox2").set("placeHolder","FIRST \u05e9\u05dc\u05d5\u05dd!");
+				});						
+			});
+			
+		});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	
+	</style>
+	
+	
+</head>
+<
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">SearchBox widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		<br>
+		
+		
+			<input data-dojo-type="dojox.mobile.SearchBox" type="search" id="ltrSearchBox1" selectOnClick="true" placeHolder="שלו&#1501!" data-dojo-props='name:"ltrSearchBox1",  textDir:"ltr"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" id="ltrSearchBox2" selectOnClick="true" placeHolder="Hello!" data-dojo-props='name:"ltrSearchBox2",  textDir:"ltr"'/>
+		  	    <br>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" id="ltrSearchBox3" selectOnClick="true" placeHolder="My name is אמי&#1512!" data-dojo-props='name:"ltrSearchBox3",  textDir:"ltr"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" id="ltrSearchBox4" selectOnClick="true" placeHolder="שמי הוא Amir!" data-dojo-props='name:"ltrSearchBox4",  textDir:"ltr"'/>
+
+		<br>
+		<br>
+		<button data-dojo-type="dojox.mobile.Button" id="btn1" class="mblRedButton" data-dojo-props='label:"Set textDir of SearchBox to ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn2" class="mblRedButton" data-dojo-props='label:"Set textDir of SearchBox to rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn3" class="mblRedButton" data-dojo-props='label:"Set textDir of SearchBox to auto"'></button>
+			
+	
+
+		
+
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		
+			<input data-dojo-type="dojox.mobile.SearchBox" type="search" id="rtlSearchBox1" selectOnClick="true" placeHolder="שלו&#1501!" data-dojo-props='name:"rtlSearchBox1",  textDir:"rtl"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" id="rtlSearchBox2" selectOnClick="true" placeHolder="Hello!" data-dojo-props='name:"rtlSearchBox2",  textDir:"rtl"'/>
+		  	    <br>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" id="rtlSearchBox3" selectOnClick="true" placeHolder="My name is אמי&#1512!" data-dojo-props='name:"rtlSearchBox3",  textDir:"rtl"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" id="rtlSearchBox4" selectOnClick="true" placeHolder="שמי הוא Amir!" data-dojo-props='name:"rtlSearchBox4",  textDir:"rtl"'/>
+		  	
+		
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		
+		<input data-dojo-type="dojox.mobile.SearchBox" type="search" id="autoSearchBox1" selectOnClick="true" placeHolder="שלו&#1501!" data-dojo-props='name:"autoSearchBox1",  textDir:"auto"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" id="autoSearchBox2" selectOnClick="true" placeHolder="Hello!" data-dojo-props='name:"autoSearchBox2",  textDir:"auto"'/>
+		  	    <br>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" id="autoSearchBox3" selectOnClick="true" placeHolder="My name is אמי&#1512!" data-dojo-props='name:"autoSearchBox3",  textDir:"auto"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" id="autoSearchBox4" selectOnClick="true" placeHolder="שמי הוא Amir!" data-dojo-props='name:"autoSearchBox4",  textDir:"auto"'/>
+
+		<br>
+		<br>
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text Button for SearchBoxes</button>
+	</div>	
+	 
+	 
+	<div id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		
+		<input data-dojo-type="dojox.mobile.SearchBox" dir="rtl" type="search" id="ltrSearchBox5" selectOnClick="true" placeHolder="שלו&#1501!" data-dojo-props='name:"ltrSearchBox1",  textDir:"ltr"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" dir="rtl" type="search" id="ltrSearchBox6" selectOnClick="true" placeHolder="Hello!" data-dojo-props='name:"ltrSearchBox2",  textDir:"ltr"'/>
+		  	    <br>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" dir="rtl" type="search" id="ltrSearchBox7" selectOnClick="true" placeHolder="My name is אמי&#1512!" data-dojo-props='name:"ltrSearchBox3",  textDir:"ltr"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" dir="rtl" type="search" id="ltrSearchBox8" selectOnClick="true" placeHolder="שמי הוא Amir!" data-dojo-props='name:"ltrSearchBox4",  textDir:"ltr"'/>
+
+		
+	</div>
+	
+	<div id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+			
+		<input data-dojo-type="dojox.mobile.SearchBox" type="search" dir="rtl" id="rtlSearchBox5" selectOnClick="true" placeHolder="שלו&#1501!" data-dojo-props='name:"rtlSearchBox1",  textDir:"rtl"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" dir="rtl" type="search" id="rtlSearchBox6" selectOnClick="true" placeHolder="Hello!" data-dojo-props='name:"rtlSearchBox2",  textDir:"rtl"'/>
+		  	    <br>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" dir="rtl" type="search" id="rtlSearchBox7" selectOnClick="true" placeHolder="My name is אמי&#1512!" data-dojo-props='name:"rtlSearchBox3",  textDir:"rtl"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" dir="rtl" type="search" id="rtlSearchBox8" selectOnClick="true" placeHolder="שמי הוא Amir!" data-dojo-props='name:"rtlSearchBox4",  textDir:"rtl"'/>
+		  	
+	</div>	
+	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		
+		<input data-dojo-type="dojox.mobile.SearchBox" type="search" dir="rtl" id="autoSearchBox5" selectOnClick="true" placeHolder="שלו&#1501!" data-dojo-props='name:"ltrSearchBox",  textDir:"auto"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" dir="rtl" id="autoSearchBox6" selectOnClick="true" placeHolder="Hello!" data-dojo-props='name:"ltrSearchBox",  textDir:"auto"'/>
+		  	    <br>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" dir="rtl" id="autoSearchBox7" selectOnClick="true" placeHolder="My name is אמי&#1512!" data-dojo-props='name:"ltrSearchBox",  textDir:"auto"'/>
+		  	    <input data-dojo-type="dojox.mobile.SearchBox" type="search" dir="rtl" id="autoSearchBox8" selectOnClick="true" placeHolder="שמי הוא Amir!" data-dojo-props='name:"ltrSearchBox",  textDir:"auto"'/>
+	
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_SpinWheel.html b/dojox/mobile/tests/bidi/Bidi_SpinWheel.html
new file mode 100644
index 0000000..d5ba5ec
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_SpinWheel.html
@@ -0,0 +1,266 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - SpinWheel</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dijit/_base/manager",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SpinWheel",	
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView"
+		], function(connect, ready, array, dom, registry){
+			ready(function(){
+				//change textDir, text
+				var btnLtr = registry.byId("btn5");				
+				btnLtr.connect(btnLtr, "onClick", function(){
+					registry.byId("first1").set("textDir", "ltr");
+				});
+				var btnRtl = registry.byId("btn6");
+				btnLtr.connect(btnRtl, "onClick", function(){
+					registry.byId("first1").set("textDir", "rtl");				
+				});	
+				var btnAuto = registry.byId("btn7");
+				btnAuto.connect(btnAuto, "onClick", function(){
+					registry.byId("first1").set("textDir", "auto");					
+				});
+		});
+	});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url(../images/red-button-bg.png);
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+</head>
+
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">SpinWheel widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btn5" class="mblRedButton" data-dojo-props='label:"Set Slot textDir ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn6" class="mblRedButton" data-dojo-props='label:"Set Slot textDir rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn7" class="mblRedButton" data-dojo-props='label:"Set Slot textDir auto"'></button>		
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		
+				
+		<div data-dojo-type="dojox/mobile/View">
+			<h1 data-dojo-type="dojox/mobile/Heading">textDir is set to SpinWheelSlot</h1>
+			<div id="spin1" data-dojo-type="dojox/mobile/SpinWheel">
+				<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['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']"
+					style="text-align:center;width:40px;"></div>
+				<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props='labelFrom:0, labelTo:9'
+					style="width:50px;"></div>
+				<div id="first1" data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'ltr'"
+					style="width:200px;"></div>
+				</div>
+			</div>
+			<h1 data-dojo-type="dojox/mobile/Heading">textDir is set to SpinWheel</h1>
+			<div id="spin11" data-dojo-type="dojox/mobile/SpinWheel" data-dojo-props="textDir:'ltr'" >
+				<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['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']"
+					style="text-align:center;width:40px;"></div>
+				<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props='labelFrom:0, labelTo:9'
+					style="width:50px;"></div>
+				<div id="first11" data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!']"
+					style="width:200px;"></div>
+				</div>
+			</div>			
+		</div>
+			
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		
+		<div data-dojo-type="dojox/mobile/View">
+			<h1 data-dojo-type="dojox/mobile/Heading">textDir is set to SpinWheelSlot</h1>
+			<div id="spin2" data-dojo-type="dojox/mobile/SpinWheel" >
+				<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['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']"
+					style="text-align:center;width:40px;"></div>
+				<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props='labelFrom:0, labelTo:9'
+					style="width:50px;"></div>
+				<div id="first2" data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'rtl'"
+					style="width:200px;"></div>
+				</div>
+			</div>
+			<h1 data-dojo-type="dojox/mobile/Heading">textDir is set to SpinWheel</h1>
+			<div id="spin22" data-dojo-type="dojox/mobile/SpinWheel" data-dojo-props="textDir:'rtl'">
+				<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['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']"
+					style="text-align:center;width:40px;"></div>
+				<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props='labelFrom:0, labelTo:9'
+					style="width:50px;"></div>
+				<div id="first22" data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!']"
+					style="width:200px;"></div>
+				</div>
+			</div>			
+		</div>
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div data-dojo-type="dojox/mobile/View">
+			<h1 data-dojo-type="dojox/mobile/Heading">textDir is set to SpinWheelSlot</h1>
+			<div id="spin3" data-dojo-type="dojox/mobile/SpinWheel">
+				<div id="s" data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['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']"
+					style="text-align:center;width:40px;"></div>
+				<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props='labelFrom:0, labelTo:9'
+					style="width:50px;"></div>
+				<div id="first3" data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'auto'"
+					style="width:200px;"></div>
+				</div>
+				<h1 data-dojo-type="dojox/mobile/Heading">textDir is set to SpinWheell</h1>
+			<div id="spin33" data-dojo-type="dojox/mobile/SpinWheel" data-dojo-props="textDir:'auto'">
+				<div id="ss" data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['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']"
+					style="text-align:center;width:40px;"></div>
+				<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props='labelFrom:0, labelTo:9'
+					style="width:50px;"></div>
+				<div id="first33" data-dojo-type="dojox/mobile/SpinWheelSlot"
+					data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!']"
+					style="width:200px;"></div>
+				</div>
+			</div>	
+		</div>			
+	</div>	
+	 
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true, textDir:"ltr"'>	
+		<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">textDir is set to SpinWheelSlot</h1>
+		<div id="spin4" data-dojo-type="dojox/mobile/SpinWheel">
+			<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:50px;"></div>
+			<div id="first4" data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'ltr'"
+				style="width:200px;"></div>
+			</div>
+		</div>
+		
+		
+		</div>
+		
+		
+	</div>
+	<div id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+			
+			<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">textDir is set to SpinWheelSlot</h1>
+		<div dir="rtl" id="spin5" data-dojo-type="dojox/mobile/SpinWheel" >
+			<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:50px;"></div>
+			<div id="first5" data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'rtl'"
+				style="width:200px;"></div>
+			</div>
+		</div>
+			
+			</div>
+				
+		
+		</div>	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">textDir is set to SpinWheelSlot</h1>
+		<div id="spin6" data-dojo-type="dojox/mobile/SpinWheel">
+			<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:50px;"></div>
+			<div id="first6" data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'auto'"
+				style="width:200px;"></div>
+			</div>
+		</div>	
+		
+		
+		</div>				
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_StoreCarousel.html b/dojox/mobile/tests/bidi/Bidi_StoreCarousel.html
new file mode 100644
index 0000000..a9acb61
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_StoreCarousel.html
@@ -0,0 +1,212 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bidi Mobile test - StoreCarousel</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true,  has: { 'dojo-bidi': true }"></script>
+
+
+<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojo/store/JsonRest",
+			"dojo/dom",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/StoreCarousel",			
+			"dojox/mobile/Carousel",
+			"dojox/mobile/Button",
+			"dijit/_base/manager",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		],
+		
+		function(connect, ready, array, dom, registry, JsonRest){
+			store1 = new JsonRest({target: "./Bidi_carousel-categ.json"});
+			ready(function(){
+			
+				
+				//change label 
+				var btn1 = registry.byId("btnlbl");
+				btn1.connect(btn1, "onClick", function(){
+					registry.byId("carousel11").set("title", "Start \u05e9\u05dc\u05d5\u05dd!	");	
+				registry.byId("carousel12").set("title", "\u05e9\u05dc\u05d5\u05dd End!	");			
+				});
+			
+				//change textDir for carousel4	
+				var btn0 = registry.byId("btn0");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("carousel4").set("textDir", "ltr");
+				});	
+				
+				var btn0 = registry.byId("btn1");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("carousel4").set("textDir", "rtl");
+				});	
+					
+				var btn0 = registry.byId("btn2");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("carousel4").set("textDir", "auto");
+				});
+			});
+			
+			
+		});
+		
+	</script>  
+	  
+
+<script type="text/javascript">
+		require(
+		function(JsonRest){
+			store1 = new JsonRest({target: "../data/Bidi_carousel-categ.json"});
+		}); 
+		
+		</script>
+
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	
+	</style>
+	
+	
+</head>
+	
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">StoredCarousel widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		
+			
+		<div id="foo1" data-dojo-type="dojox.mobile.View">
+			<div id="carousel1" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "ltr", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello world!"'></div>
+			<div id="carousel2" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "ltr", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום עולם!"'></div>
+			<div id="carousel3" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "ltr", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello עולם!"'></div>
+			<div id="carousel4" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "ltr", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום World!"'></div>
+		</div>
+		
+		<button data-dojo-type="dojox.mobile.Button" id="btn0" >Set textDir for Carousel to ltr</button>
+			<button data-dojo-type="dojox.mobile.Button" id="btn1" >Set textDir for Carousel to rtl</button>
+			<button data-dojo-type="dojox.mobile.Button" id="btn2" >Set textDir for Carousel to auto</button>
+	
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+			<div id="carousel5" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "rtl", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello world!"'></div>
+			<div id="carousel6" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "rtl", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום עולם!"'></div>
+			<div id="carousel7" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "rtl", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello עולם!"'></div>
+			<div id="carousel8" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "rtl", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום World!"'></div>
+					
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+			<div id="carouse9" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "auto", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello world!"'></div>
+			<div id="carousel0" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "auto", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום עולם!"'></div>
+			<div id="carousel11" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "auto", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello עולם!"'></div>
+			<div id="carousel12" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "auto", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום World!"'></div>
+				
+		<button data-dojo-type="dojox.mobile.Button" id="btnlbl" >Set new text Button for carousel</button>
+		
+	</div>	
+	 
+	 
+	<div  id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		<div id="foo2" data-dojo-type="dojox.mobile.View">
+			<div id="carousel13" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "ltr", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello world!"'></div>
+			<div id="carousel14" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "ltr", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום עולם!"'></div>
+			<div id="carousel15" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "ltr", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello עולם!"'></div>
+			<div id="carousel16" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "ltr", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום World!"'></div>
+			
+		</div>
+		
+	</div>
+	
+	<div id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+			<div id="carousel17" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "rtl", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello world!"'></div>
+			<div id="carousel18" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "rtl", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום עולם!"'></div>
+			<div id="carousel19" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "rtl", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello עולם!"'></div>
+			<div id="carousel20" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "rtl", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום World!"'></div>
+			
+		
+		
+	</div>	
+	
+	<div id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+			<div id="carousel21" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "auto", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello world!"'></div>
+			<div id="carousel22" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "auto", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום עולם!"'></div>
+			<div id="carousel23" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "auto", height:"150px", navButton:true, store:store1, numVisible:"1", title:"Hello עולם!"'></div>
+			<div id="carousel24" dir="rtl" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "auto", height:"150px", navButton:true, store:store1, numVisible:"1", title:"שלום World!"'></div>
+			
+		
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_Switch.html b/dojox/mobile/tests/bidi/Bidi_Switch.html
new file mode 100644
index 0000000..f06f616
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_Switch.html
@@ -0,0 +1,172 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>test</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Button",
+			"dojox/mobile/Switch",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/ScrollableView"
+		], function(connect, ready, array, dom, registry){
+			ready(function(){
+			
+				//change textDir for switch1	
+				var btn0 = registry.byId("btn0");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("switch1").set("textDir", "ltr");
+				});	
+				
+				var btn0 = registry.byId("btn1");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("switch1").set("textDir", "rtl");
+				});	
+					
+				var btn0 = registry.byId("btn2");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("switch1").set("textDir", "auto");
+				});
+				// change label for icon container				
+				var btnLbl = registry.byId("btnLbl");
+				btnLbl.connect(btnLbl, "onClick", function(){
+				var c = registry.byId("switch6");
+				var l = c.get("label");
+				c.set("label", "new");
+				var n =  c.get("label");
+				
+					registry.byId("switch6").set("leftLabel", "\u05e9\u05dc\u05d5\u05dd!");
+				});
+			});
+	
+	});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url(../images/red-button-bg.png);
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">Switch widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true, textDir:"ltr"'>
+				
+		<div  id="switch1" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Hello!", rightLabel:"שלום!"'></div>
+		<br>
+		<div  id="switch2" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Aסוף!", rightLabel:"אend!"'></div>
+		</div>
+		
+		<button data-dojo-type="dojox.mobile.Button" id="btn0" >Set textDir for switch to ltr</button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn1" >Set textDir for switch to rtl</button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn2" >Set textDir for switch to auto</button>
+		
+			
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true, textDir:"rtl"'>
+				
+		<div  id="switch3" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Hello!", rightLabel:"שלום!"'></div>
+		<br>
+		<div  id="switch4" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Aסוף!", rightLabel:"אend!"'></div>
+		</div>
+					
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+				
+		<div  id="switch5" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", textDir:"auto", leftLabel:"Hello!", rightLabel:"שלום!"'></div>
+		<br>
+		<div  id="switch6" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", textDir:"auto", leftLabel:"Aסוף!", rightLabel:"אend!"'></div>
+		</div>	
+		
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text Button</button>	
+		
+	</div>	
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true, textDir:"ltr"'>
+				
+		<div  id="switch7" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Hello!", rightLabel:"שלום!"'></div>
+		<br>
+		<div  id="switch8" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Aסוף!", rightLabel:"אend!"'></div>
+		</div>
+		
+		
+	</div>
+	<div id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true, textDir:"rtl"'>
+				
+		<div  id="switch9" dir="rtl" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Hello!", rightLabel:"שלום!"'></div>
+		<br>
+		<div  id="switch10" dir="rtl" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Aסוף!", rightLabel:"אend!"'></div>
+		</div>		
+		
+	</div>	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true, textDir:"auto"'>
+				
+		<div  id="switch11" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Hello!", rightLabel:"שלום!"'></div>
+		<br>
+		<div  id="switch12" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Aסוף!", rightLabel:"אend!"'></div>
+		</div>			
+		
+	</div>	
+</div>
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_TabBar.html b/dojox/mobile/tests/bidi/Bidi_TabBar.html
new file mode 100644
index 0000000..022417f
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_TabBar.html
@@ -0,0 +1,194 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - TabBar</title>
+	
+	<link href="../../themes/common/domButtons/DomButtonYellowStar.css" rel="stylesheet"/>
+	<link href="../../themes/common/domButtons/DomButtonGrayStar.css" rel="stylesheet"/>	
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojo/_base/window",			
+			"dojox/mobile/TabBar",
+			"dojox/mobile/TabBarButton",			
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/Heading"
+		], function(connect, ready, array, dom, registry, win, TabBar, TabBarButton){
+			ready(function(){
+				var view = registry.byId("view2");
+				var tabBar = new TabBar({barType:"segmentedControl"});
+				win.body().appendChild(tabBar.domNode);
+				tabBar.startup();
+
+				var tabBarButton = new TabBarButton({ textDir:"rtl", selected:"true", label:"Hello \u05e9\u05dc\u05d5\u05dd\u0021"});
+				tabBar.addChild(tabBarButton);
+				view.addChild(tabBar);	
+				//change textDir, text
+				var btnLtr = registry.byId("btn5");				
+				btnLtr.connect(btnLtr, "onClick", function(){
+					registry.byId("tab1").set("textDir", "ltr");
+				});
+				var btnRtl = registry.byId("btn6");
+				btnLtr.connect(btnRtl, "onClick", function(){
+					registry.byId("tab1").set("textDir", "rtl");
+				});	
+				var btnAuto = registry.byId("btn7");
+				btnAuto.connect(btnAuto, "onClick", function(){
+					registry.byId("tab1").set("textDir", "auto");				
+				});						
+				var btnLbl = registry.byId("btnLbl");
+				btnLbl.connect(btnLbl, "onClick", function(){
+					registry.byId("tbAuto").set("label", "\u05e9\u05dc\u05d5\u05dd for test!");
+					registry.byId("tbAuto1").set("label", "\u05e9\u05dc\u05d5\u05dd for test!");
+					registry.byId("tbAuto1").set("badge", "\u05e9\u05dc\u05d5\u05dd for test!");
+				});							
+		});
+	
+	});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url(../images/red-button-bg.png);
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	 <h2 data-dojo-type="dojox.mobile.Heading">TabBar widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir LTR</h1>
+		<ul data-dojo-type="dojox.mobile.TabBar" id="tab1" data-dojo-props='barType:"standardTab",  textDir:"ltr"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" >Hello World!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">שלום עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Hello עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">שלום World!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../images/tab-icon-21.png",  badge:"חדש!"'>badge.</li>
+		</ul><br>
+				<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn5" class="mblRedButton" data-dojo-props='label:"Set textDir ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn6" class="mblRedButton" data-dojo-props='label:"Set textDir rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn7" class="mblRedButton" data-dojo-props='label:"Set textDir auto"'></button>
+		
+		<hr>
+		<h1 data-dojo-type="dojox.mobile.Heading" >TabBar textDir LTR, TabBarButton textDir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", textDir:"ltr"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='textDir:"rtl"'>שלום World!</li>
+		</ul><br>
+
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"standardTab", textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" >Hello World!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">שלום עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Hello עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" >שלום World!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../images/tab-icon-21.png",  badge:"חדש!"'>Hello World!</li>			
+		</ul><br>
+			<hr>
+			<h1 data-dojo-type="dojox.mobile.Heading">Programmatically created TabBarButton</h1>
+		
+	</div>	
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir AUTO</h1>
+		<ul data-dojo-type="dojox.mobile.TabBar" id="tabAuto" data-dojo-props='barType:"standardTab", textDir:"auto"'>
+			<li id="tbAuto" data-dojo-type="dojox.mobile.TabBarButton" >Hello World!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">שלום עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Hello עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" >שלום World!</li>
+			<li id="tbAuto1" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../images/tab-icon-21.png",  badge:"new!"'>Hello World!</li>			
+		</ul><br>
+		<hr>		
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text</button>		
+		
+	</div>	
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir LTR</h1>
+		<hr>
+		<ul data-dojo-type="dojox.mobile.TabBar" id="tab11" data-dojo-props='barType:"standardTab",  textDir:"ltr"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" >Hello World!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">שלום עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Hello עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">שלום World!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../images/tab-icon-21.png",  badge:"חדש!"'>Hello World!</li>
+		</ul><br>	
+		<hr>
+		<h1 data-dojo-type="dojox.mobile.Heading" >TabBarButton textDir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", textDir:"ltr"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='textDir:"rtl"'>שלום World!</li>
+		</ul><br>
+	</div>
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDirRTR</h1>
+		<hr>		
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"standardTab", textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" >Hello World!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">שלום עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Hello עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" >שלום World!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../images/tab-icon-21.png",  badge:"חדש!"'>Hello World!</li>			
+		</ul><br>
+	</div>	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir AUTO</h1>
+		<hr>	
+		<ul data-dojo-type="dojox.mobile.TabBar"  data-dojo-props='barType:"standardTab", textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" >Hello World!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">שלום עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Hello עולם!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" >שלום World!</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../images/tab-icon-21.png",  badge:"חדש!"'>Hello World!</li>
+		</ul><br>
+	</div>	
+</div>
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_TextArea.html b/dojox/mobile/tests/bidi/Bidi_TextArea.html
new file mode 100644
index 0000000..3ab4dae
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_TextArea.html
@@ -0,0 +1,225 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bidi Mobile test - TextArea</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: { 'dojo-bidi': true }"></script>
+
+
+	
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/Button",
+			"dijit/_base/manager",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/TextArea",
+			"dojox/mobile/EdgeToEdgeDataList",
+			"dojox/mobile/compat"
+	], function(connect, ready, array, dom, registry){
+			ready(function(){
+			
+				//change textDir, text
+				var btnLtr = registry.byId("btn1");				
+				btnLtr.connect(btnLtr, "onClick", function(){
+					registry.byId("largeTextAreaLTR1").set("textDir", "ltr");
+					registry.byId("largeTextAreaLTR2").set("textDir", "ltr");
+					registry.byId("largeTextAreaLTR3").set("textDir", "ltr");
+					registry.byId("largeTextAreaLTR4").set("textDir", "ltr");
+					
+				});
+				var btnRtl = registry.byId("btn2");
+				btnRtl.connect(btnRtl, "onClick", function(){
+					registry.byId("largeTextAreaLTR1").set("textDir", "rtl");
+					registry.byId("largeTextAreaLTR2").set("textDir", "rtl");
+					registry.byId("largeTextAreaLTR3").set("textDir", "rtl");
+					registry.byId("largeTextAreaLTR4").set("textDir", "rtl");
+								
+				});	
+				var btnAuto = registry.byId("btn3");
+				btnAuto.connect(btnAuto, "onClick", function(){
+					registry.byId("largeTextAreaLTR1").set("textDir", "auto");
+					registry.byId("largeTextAreaLTR2").set("textDir", "auto");
+					registry.byId("largeTextAreaLTR3").set("textDir", "auto");
+					registry.byId("largeTextAreaLTR4").set("textDir", "auto");
+									
+				});
+				
+							
+			});
+			
+		});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	
+	</style>
+	
+	
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.View">
+	        <h2 data-dojo-type="dojox.mobile.Heading">TextArea widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>
+	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		<br>
+		
+			<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreaLTR1" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"ltr", placeHolder:"Hello world!", style:{width:"12em",height:"8em"}'></textarea>
+			
+			<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreaLTR2" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"ltr", style:{width:"12em",height:"8em"}'>שלום עולם!</textarea>
+		
+			<br>
+			
+			<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreaLTR3" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"ltr", style:{width:"12em",height:"8em"}'>Hello עולם!</textarea>
+			
+			<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreaLTR4" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"ltr", style:{width:"12em",height:"8em"}'>שלום World!</textarea>
+			    
+		<br>
+		<br>
+		
+		<button data-dojo-type="dojox.mobile.Button" id="btn1" class="mblRedButton" data-dojo-props='label:"Set textDir of TextBox to ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn2" class="mblRedButton" data-dojo-props='label:"Set textDir of TextBox to rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn3" class="mblRedButton" data-dojo-props='label:"Set textDir of TextBox to auto"'></button>
+			
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		
+		<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreartl1" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"rtl", placeHolder:"Hello world!", style:{width:"12em",height:"8em"}'></textarea>
+			
+			<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreartl2" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"rtl", style:{width:"12em",height:"8em"}'>שלום עולם!</textarea>
+		
+			<br>
+			
+			<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreartl3" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"rtl", style:{width:"12em",height:"8em"}'>Hello עולם!</textarea>
+			
+			<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreartl4" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"rtl", style:{width:"12em",height:"8em"}'>שלום World!</textarea>
+		
+			
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.View">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		
+		
+		<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreaauto1" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"auto", style:{width:"12em",height:"8em"}'>Hello world!</textarea>
+			
+			<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreaauto2" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"auto", style:{width:"12em",height:"8em"}'>שלום עולם!</textarea>
+		
+			<br>
+			
+			<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreaauto3" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"auto", style:{width:"12em",height:"8em"}'>Hello עולם!</textarea>
+			
+			<textarea data-dojo-type="dojox.mobile.TextArea" id="largeTextAreaauto4" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"auto", style:{width:"12em",height:"8em"}'>שלום World!</textarea>
+		
+	</div>	
+	 
+	 
+	<div id="view4" dir="rtl" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		
+		<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR", placeHolder:"ps!",
+			      textDir:"ltr", style:{width:"12em",height:"8em"}'>Hello world!</textarea>
+			
+			<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"ltr", style:{width:"12em",height:"8em"}'>שלום עולם!</textarea>
+		
+			<br>
+			
+			<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"ltr", style:{width:"12em",height:"8em"}'>Hello עולם!</textarea>
+			
+			<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"ltr", style:{width:"12em",height:"8em"}'>שלום World!</textarea>
+			
+	</div>
+	
+	<div id="view5" dir="rtl" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+			
+		<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"rtl", style:{width:"12em",height:"8em"}'>Hello world!</textarea>
+			
+			<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"rtl", style:{width:"12em",height:"8em"}'>שלום עולם!</textarea>
+		
+			<br>
+			
+			<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"rtl", style:{width:"12em",height:"8em"}'>Hello עולם!</textarea>
+			
+			<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"rtl", style:{width:"12em",height:"8em"}'>שלום World!</textarea>
+			
+	</div>	
+	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.View">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		
+		<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"auto", style:{width:"12em",height:"8em"}'>Hello world!</textarea>
+			
+			<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"auto", style:{width:"12em",height:"8em"}'>שלום עולם!</textarea>
+		
+			<br>
+			
+			<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"auto", style:{width:"12em",height:"8em"}'>Hello עולם!</textarea>
+			
+			<textarea dir="rtl" data-dojo-type="dojox.mobile.TextArea" data-dojo-props='name:"largeTextAreaLTR",
+			      textDir:"auto", style:{width:"12em",height:"8em"}'>שלום World!</textarea>
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_TextBox.html b/dojox/mobile/tests/bidi/Bidi_TextBox.html
new file mode 100644
index 0000000..90fdf23
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_TextBox.html
@@ -0,0 +1,191 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bidi Mobile test - TextBox</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: { 'dojo-bidi': true }"></script>
+
+
+	
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/Button",
+			"dijit/_base/manager",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/compat"
+		], function(connect, ready, array, dom, registry){
+			ready(function(){
+	
+				//change textDir, text
+				var btnLtr = registry.byId("btn1");				
+				btnLtr.connect(btnLtr, "onClick", function(){
+					registry.byId("ltrTextBox1").set("textDir", "ltr");
+					registry.byId("ltrTextBox2").set("textDir", "ltr");
+					registry.byId("ltrTextBox3").set("textDir", "ltr");
+					registry.byId("ltrTextBox4").set("textDir", "ltr");
+				});
+				var btnRtl = registry.byId("btn2");
+				btnRtl.connect(btnRtl, "onClick", function(){
+					registry.byId("ltrTextBox1").set("textDir", "rtl");
+					registry.byId("ltrTextBox2").set("textDir", "rtl");
+					registry.byId("ltrTextBox3").set("textDir", "rtl");
+					registry.byId("ltrTextBox4").set("textDir", "rtl");				
+				});	
+				var btnAuto = registry.byId("btn3");
+				btnAuto.connect(btnAuto, "onClick", function(){
+					registry.byId("ltrTextBox1").set("textDir", "auto");
+					registry.byId("ltrTextBox2").set("textDir", "auto");
+					registry.byId("ltrTextBox3").set("textDir", "auto");
+					registry.byId("ltrTextBox4").set("textDir", "auto");					
+				});
+				
+				// change label for icon container				
+				var btnLbl = registry.byId("btnLbl");
+				btnLbl.connect(btnLbl, "onClick", function(){
+				var c = registry.byId("ltrTextBox5");
+				var l = c.get("label");
+				c.set("label", "new");
+				var n =  c.get("label");
+				
+					registry.byId("ltrTextBox5").set("value","\u05e9\u05dc\u05d5\u05dd END!");
+					registry.byId("ltrTextBox6").set("value","FIRST \u05e9\u05dc\u05d5\u05dd!");
+				});						
+			});
+			
+		});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	
+	</style>
+	
+	
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">TextBox widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		<br>
+		
+		<input data-dojo-type="dojox.mobile.TextBox" id="ltrTextBox1" data-dojo-props='name:"ltrTextBox1", value:"Hello world!", textDir:"ltr"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" id="ltrTextBox2" data-dojo-props='name:"ltrTextBox2", value:"שלום עולם!", textDir:"ltr"'/>
+		<br>
+		<input data-dojo-type="dojox.mobile.TextBox" id="ltrTextBox3" data-dojo-props='name:"ltrTextBox3", value:"Hello עולם!", textDir:"ltr"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" id="ltrTextBox4" data-dojo-props='name:"ltrTextBox4", value:"שלום World!", textDir:"ltr"'/>
+		
+		<br>
+		<br>
+		<button data-dojo-type="dojox.mobile.Button" id="btn1" class="mblRedButton" data-dojo-props='label:"Set textDir of TextBox to ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn2" class="mblRedButton" data-dojo-props='label:"Set textDir of TextBox to rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn3" class="mblRedButton" data-dojo-props='label:"Set textDir of TextBox to auto"'></button>
+			
+	
+
+		
+
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		
+		
+		<input data-dojo-type="dojox.mobile.TextBox" data-dojo-props='textDir: "rtl" ' maxLength="9" selectOnClick="true" placeHolder="max 9 chars">
+		<input data-dojo-type="dojox.mobile.TextBox" data-dojo-props='name:"ltrTextBox1", value:"Hello world!", textDir:"rtl"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" data-dojo-props='name:"ltrTextBox2", value:"שלום עולם!", textDir:"rtl"'/>
+		<br>
+		<input data-dojo-type="dojox.mobile.TextBox" data-dojo-props='name:"ltrTextBox3", value:"Hello עולם!", textDir:"rtl"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" data-dojo-props='name:"ltrTextBox4", value:"שלום World!", textDir:"rtl"'/>
+		
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		
+		<input data-dojo-type="dojox.mobile.TextBox" id="ltrTextBox5" data-dojo-props='name:"ltrTextBox5", value:"Hello world!", textDir:"auto"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" id="ltrTextBox6" data-dojo-props='name:"ltrTextBox6", value:"שלום עולם!", textDir:"auto"'/>
+		<br>
+		<input data-dojo-type="dojox.mobile.TextBox" id="ltrTextBox7" data-dojo-props='name:"ltrTextBox7", value:"Hello עולם!", textDir:"auto"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" id="ltrTextBox8" data-dojo-props='name:"ltrTextBox8", value:"שלום World!", textDir:"auto"'/>
+		<br>
+		<br>
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text Button for Textboxes</button>
+	</div>	
+	 
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl" data-dojo-props='name:"ltrTextBox1", value:"Hello world!", textDir:"ltr"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl" data-dojo-props='name:"ltrTextBox2", value:"שלום עולם!", textDir:"ltr"'/>
+		<br>
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl" data-dojo-props='name:"ltrTextBox3", value:"Hello עולם!", textDir:"ltr"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl"  data-dojo-props='name:"ltrTextBox4", value:"שלום World!", textDir:"ltr"'/>
+		
+	</div>
+	
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+			
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl" data-dojo-props='name:"ltrTextBox1", value:"Hello world!", textDir:"rtl"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl" data-dojo-props='name:"ltrTextBox2", value:"שלום עולם!", textDir:"rtl"'/>
+		<br>
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl" data-dojo-props='name:"ltrTextBox3", value:"Hello עולם!", textDir:"rtl"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl" data-dojo-props='name:"ltrTextBox4", value:"שלום World!", textDir:"rtl"'/>
+		
+	</div>	
+	
+	<div dir="rtl" dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl" data-dojo-props='name:"ltrTextBox1", value:"Hello world!", textDir:"auto"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl" data-dojo-props='name:"ltrTextBox2", value:"שלום עולם!", textDir:"auto"'/>
+		<br>
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl" data-dojo-props='name:"ltrTextBox3", value:"Hello עולם!", textDir:"auto"'/>
+		<input data-dojo-type="dojox.mobile.TextBox" dir="rtl" data-dojo-props='name:"ltrTextBox4", value:"שלום World!", textDir:"auto"'/>	
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_ToggleButton.html b/dojox/mobile/tests/bidi/Bidi_ToggleButton.html
new file mode 100644
index 0000000..131139c
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_ToggleButton.html
@@ -0,0 +1,170 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - ToggleButton</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ToggleButton']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/Heading",
+			"dojox/mobile/ToggleButton",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/ListItem"
+		], function(connect, ready, array, dom, registry, Heading, ToggleButton){
+			ready(function(){
+				//create list programmaticaly
+				var view = registry.byId("view2");
+				var heading = new Heading({label:"Created programmatically"});
+				view.addChild(heading);
+				var button = new ToggleButton({label:"\u05e9\u05dc\u05d5\u05dd end!",  textDir:"rtl"});
+				view.addChild(button);
+				//change textDir, text
+				var btnLtr = registry.byId("btn5");				
+				btnLtr.connect(btnLtr, "onClick", function(){
+					array.forEach(["ltrbtn1", "ltrbtn2", "ltrbtn3", "ltrbtn4"], function (btnId){
+						registry.byId(btnId).set("textDir", "ltr");
+					});							
+				});
+				var btnRtl = registry.byId("btn6");
+				btnLtr.connect(btnRtl, "onClick", function(){
+					array.forEach(["ltrbtn1", "ltrbtn2", "ltrbtn3", "ltrbtn4"], function (btnId) {
+						registry.byId(btnId).set("textDir", "rtl");
+					});							
+				});	
+				var btnAuto = registry.byId("btn7");
+				btnAuto.connect(btnAuto, "onClick", function(){
+					array.forEach(["ltrbtn1", "ltrbtn2", "ltrbtn3", "ltrbtn4"], function (btnId) {
+						registry.byId(btnId).set("textDir", "auto");
+					});							
+				});						
+				var btnLbl = registry.byId("btnLbl");
+				btnLbl.connect(btnLbl, "onClick", function(){
+					registry.byId("autobtn1").set("label", "\u05e9\u05dc\u05d5\u05dd for test!");
+				});
+		});
+	
+	});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url(../images/red-button-bg.png);
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	 <h2 data-dojo-type="dojox.mobile.Heading">ToggleButton widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir LTR</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btn5" class="mblRedButton" data-dojo-props='label:"Set textDir ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn6" class="mblRedButton" data-dojo-props='label:"Set textDir rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn7" class="mblRedButton" data-dojo-props='label:"Set textDir auto"'></button>
+		<br>
+			<button type="button" class="mblRedButton" checked id="ltrbtn1" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"ltr"' label="שלו&#1501!"/>
+		  	  <button type="button" class="mblRedButton" checked id="ltrbtn2" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"ltr"' label="Hello!"/>
+		  	  <br>
+		  	  <br>
+		  	  <button type="button" class="mblRedButton" checked id="ltrbtn3" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"ltr"' label="My name is אמיר!"/>
+		  	  <button type="button" class="mblRedButton" checked id="ltrbtn4" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"ltr"' label="שמי הוא Amir!"/>
+		<br>
+		
+		
+
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir RTL</h1>
+		
+		<button type="button" class="mblRedButton" checked id="rtlbtn1" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"rtl"' label="שלו&#1501!"/>
+		  	  <button type="button" class="mblRedButton" checked id="rtlbtn2" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"rtl"' label="Hello!"/>
+		  	  <br>
+		  	  <button type="button" class="mblRedButton" checked id="rtlbtn3" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"rtl"' label="My name is אמיר"/>
+		  	  <button type="button" class="mblRedButton" checked id="rtlbtn4" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"rtl"' label="שמי הוא Amir"/>
+	</div>	
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>textDir AUTO</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btnLbl" >Set new text to Button</button>
+		<br>
+		<button type="button" class="mblRedButton" checked id="autobtn1" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"auto"' label="שלו&#1501!"/>
+		  	  <button type="button" class="mblRedButton" checked id="autobtn2" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"auto"' label="Hello!"/>
+		  	  <br>
+		  	  <button type="button" class="mblRedButton" checked id="autobtn3" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"auto"' label="My name is אמיר"/>
+		  	  <button type="button" class="mblRedButton" checked id="autobtn4" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"auto"' label="שמי הוא Amir"/>
+		<hr>
+		<br>		
+		
+	</div>	
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir LTR</h1>
+		<button type="button" dir=rtl class="mblBlueButton" checked id="ltrbtn11" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"ltr"' label="שלו&#1501!"/>
+		  	  <button type="button" dir=rtl class="mblBlueButton" checked id="ltrbtn21" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"ltr"' label="Hello!"/>
+		  	  <br>
+		  	  <button type="button" dir=rtl class="mblBlueButton" checked id="ltrbtn31" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"ltr"' label="My name is אמיר"/>
+		  	  <button type="button" dir=rtl class="mblBlueButton" checked id="ltrbtn41" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"ltr"' label="שמי הוא Amir"/>
+	</div>
+	
+	<div dir="rtl" id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDirRTL</h1>
+		<button type="button" dir=rtl class="mblBlueButton" checked id="rtlbtn11" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"rtl"' label="שלו&#1501!"/>
+		  	  <button type="button" dir=rtl class="mblBlueButton" checked id="rtlbtn21" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"rtl"' label="Hello!"/>
+		  	  <br>
+		  	  <button type="button" dir=rtl class="mblBlueButton" checked id="rtlbtn31" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"rtl"' label="My name is אמיר"/>
+		  	  <button type="button" dir=rtl class="mblBlueButton" checked id="rtlbtn41" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"rtl"' label="שמי הוא Amir"/>
+	</div>	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>dir RTL, textDir AUTO</h1>
+		<button type="button" dir=rtl class="mblBlueButton" checked id="autobtn11" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"auto"' label="שלו&#1501!"/>
+		  	  <button type="button" dir=rtl class="mblBlueButton" checked id="autobtn21" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"auto"' label="Hello!"/>
+		  	  <br>
+		  	  <button type="button" dir=rtl class="mblBlueButton" checked id="autobtn31" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"auto"' label="My name is אמיר"/>
+		  	  <button type="button" dir=rtl class="mblBlueButton" checked id="autobtn41" dojoType="dojox.mobile.ToggleButton" data-dojo-props='textDir:"auto"' label="שמי הוא Amir"/>
+	</div>	
+</div>
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_Tooltip.html b/dojox/mobile/tests/bidi/Bidi_Tooltip.html
new file mode 100644
index 0000000..4c531fe
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_Tooltip.html
@@ -0,0 +1,294 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - Tooltip</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Tooltip']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dijit/_base/manager",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Tooltip",
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/ListItem"
+		], function(connect, ready, array, dom, registry){
+			ready(function(){
+			
+				//change textDir 
+				var btn0 = registry.byId("btn0");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("textTooltip4").set("textDir", "ltr");
+				});	
+				
+				var btn0 = registry.byId("btn1");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("textTooltip4").set("textDir", "rtl");
+				});	
+					
+				var btn0 = registry.byId("btn2");	
+				btn0.connect(btn0, "onClick", function(){
+					registry.byId("textTooltip4").set("textDir", "auto");
+				});
+			});
+	
+	});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url(../images/red-button-bg.png);
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">Tooltip widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO (with Span tag)</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO (with Bold tag)</li>
+		</ul>	
+		
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip1" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"ltr"' class="mblTooltipBubble">Hello world!</div>					
+		<input readonly onclick="dijit.byId('textTooltip1').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip2" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"ltr"' class="mblTooltipBubble">שלום עולם!</div>					
+		<input readonly onclick="dijit.byId('textTooltip2').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip3" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"ltr"' class="mblTooltipBubble">Hello עולם!</div>					
+		<input readonly onclick="dijit.byId('textTooltip3').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div id="textTooltip4" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"ltr"' class="mblTooltipBubble">שלום World!</div>					
+		<input readonly onclick="dijit.byId('textTooltip4').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		
+		
+		<center>
+		<button readonly onclick="dijit.byId('textTooltip1').hide()"> Click to hide first text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip2').hide()"> Click to hide second text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip3').hide()"> Click to hide third text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip4').hide()"> Click to hide fourth text tooltip </button>
+		</center>
+		<br>
+		<br>
+		<center>
+		<button data-dojo-type="dojox.mobile.Button" id="btn0" >Set textDir for last Tooltip to ltr</button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn1" >Set textDir for last Tooltip to rtl</button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn2" >Set textDir for last Tooltip to auto</button>
+		</center>
+			
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip5" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"rtl"' class="mblTooltipBubble">Hello world!</div>					
+		<input readonly onclick="dijit.byId('textTooltip5').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip6" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"rtl"' class="mblTooltipBubble">שלום עולם!</div>					
+		<input readonly onclick="dijit.byId('textTooltip6').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip7" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"rtl"' class="mblTooltipBubble">Hello עולם!</div>					
+		<input readonly onclick="dijit.byId('textTooltip7').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div id="textTooltip8" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"rtl"' class="mblTooltipBubble">שלום World!</div>					
+		<input readonly onclick="dijit.byId('textTooltip8').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		
+		<center>
+		<button readonly onclick="dijit.byId('textTooltip5').hide()"> Click to hide first text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip6').hide()"> Click to hide second text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip7').hide()"> Click to hide third text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip8').hide()"> Click to hide fourth text tooltip </button>
+		</center>
+		
+		
+					
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div id="textTooltip9" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"auto"' class="mblTooltipBubble">Hello world!<br><span style="background-color:Lime">Hello world!</span></div>					
+		<input readonly onclick="dijit.byId('textTooltip9').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip10" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"auto"' class="mblTooltipBubble">שלום עולם!<br><span style="background-color:Lime">שלום עולם!</span></div>					
+		<input readonly onclick="dijit.byId('textTooltip10').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip11" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"auto"' class="mblTooltipBubble">Hello עולם!<br><span style="background-color:Lime">Hello עולם!</span></div>					
+		<input readonly onclick="dijit.byId('textTooltip11').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div id="textTooltip12" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"auto"' class="mblTooltipBubble">שלום World!<br><span style="background-color:Lime">שלום World!</span></div>					
+		<input readonly onclick="dijit.byId('textTooltip12').show(this, ['after','before','above','below'])" value="Click on me!" size="10">		
+		
+		</div>		
+		
+		<center>
+		<button readonly onclick="dijit.byId('textTooltip9').hide()"> Click to hide first text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip10').hide()"> Click to hide second text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip11').hide()"> Click to hide third text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip12').hide()"> Click to hide fourth text tooltip </button>
+		</center>
+		
+	</div>	
+	 
+	 
+	<div  id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true, textDir:"ltr"'>	
+		<div id="textTooltip13" data-dojo-type="dojox.mobile.Tooltip" class="mblTooltipBubble">Hello world!</div>					
+		<input readonly onclick="dijit.byId('textTooltip13').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip14" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"ltr"' class="mblTooltipBubble">שלום עולם!</div>					
+		<input readonly onclick="dijit.byId('textTooltip14').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip15" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"ltr"' class="mblTooltipBubble">Hello עולם!</div>					
+		<input readonly onclick="dijit.byId('textTooltip15').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div id="textTooltip16" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"ltr"' class="mblTooltipBubble">שלום World!</div>					
+		<input readonly onclick="dijit.byId('textTooltip16').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+	
+		
+		<center>
+		<button readonly onclick="dijit.byId('textTooltip13').hide()"> Click to hide first text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip14').hide()"> Click to hide second text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip15').hide()"> Click to hide third text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip16').hide()"> Click to hide fourth text tooltip </button>
+		</center>
+		
+	</div>
+	<div id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip17" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"rtl"' class="mblTooltipBubble">Hello world!</div>					
+		<input readonly onclick="dijit.byId('textTooltip17').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip18" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"rtl"' class="mblTooltipBubble">שלום עולם!</div>					
+		<input readonly onclick="dijit.byId('textTooltip18').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip19" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"rtl"' class="mblTooltipBubble">Hello עולם!</div>					
+		<input readonly onclick="dijit.byId('textTooltip19').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div id="textTooltip20" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"rtl"' class="mblTooltipBubble">שלום World!</div>					
+		<input readonly onclick="dijit.byId('textTooltip20').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+			
+			<center>
+		<button readonly onclick="dijit.byId('textTooltip17').hide()"> Click to hide first text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip18').hide()"> Click to hide second text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip19').hide()"> Click to hide third text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip20').hide()"> Click to hide fourth text tooltip </button>
+		</center>	
+		
+	</div>	
+	<div id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div id="textTooltip21" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"auto"' class="mblTooltipBubble">Hello world!<br><b style="background-color:Lime"> Hello world! </b></div>					
+		<input readonly onclick="dijit.byId('textTooltip21').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip22" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"auto"' class="mblTooltipBubble">שלום עולם!<br><b style="background-color:Lime">שלום עולם!</b></div>					
+		<input readonly onclick="dijit.byId('textTooltip22').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		<div id="textTooltip23" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"auto"' class="mblTooltipBubble">Hello עולם!<br><b style="background-color:Lime">Hello עולם!</b></div>					
+		<input readonly onclick="dijit.byId('textTooltip23').show(this, ['after','before','above','below'])" value="Click on me!" size="10">
+		</div>
+		<br>
+		<div dir="rtl" data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div id="textTooltip24" data-dojo-type="dojox.mobile.Tooltip" data-dojo-props='textDir:"auto"' class="mblTooltipBubble">שלום World!<br><b style="background-color:Lime">שלום World!</b></div>					
+		<input readonly onclick="dijit.byId('textTooltip24').show(this, ['after','before','above','below'])" value="Click on me!" size="10">		
+		
+		</div>				
+		
+		<center>
+		<button readonly onclick="dijit.byId('textTooltip21').hide()"> Click to hide first text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip22').hide()"> Click to hide second text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip23').hide()"> Click to hide third text tooltip </button>
+		<button readonly onclick="dijit.byId('textTooltip24').hide()"> Click to hide fourth text tooltip </button>
+		</center>
+	</div>	
+</div>
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_TreeView.html b/dojox/mobile/tests/bidi/Bidi_TreeView.html
new file mode 100644
index 0000000..34acd10
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_TreeView.html
@@ -0,0 +1,186 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bidi Mobile test - TreeView</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+
+	
+	<script type="text/javascript">
+		require([
+			"dojo/data/ItemFileReadStore",
+			"dijit/tree/TreeStoreModel",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TreeView"
+		], function(ItemFileReadStore, TreeStoreModel){
+			var store = new ItemFileReadStore({
+/*			
+			data: {	
+					identifier: 'id',
+					items: [{ id:"upper",path:"Upper!",type:"bidi", undefined: "Root!", children:[{_reference:"first"}, {_reference:"second"}, {_reference:"third"}] },
+					{id:"first",path:"first",type:"", undefined: "שלום world!"},
+					{id:"second",path:"second",type:"",undefined: "Hello world!"},						
+					{id:"third",path:"third",type:"",undefined: "Hello עולם!"}]
+				}
+			});
+*/
+			data: {	
+					identifier: 'id',
+					items: [{ id:"ltr",path:"ltr",type:"ltr", undefined: "Ltr", children:[{_reference:"first"}, {_reference:"second"}, {_reference:"third"}] },
+					{ id:"rtl",path:"rtl",type:"rtl", undefined: "Rtl", children:[{_reference:"first"}, {_reference:"second"}, {_reference:"third"}] },
+					{ id:"auto",path:"auto",type:"auto", undefined: "Auto", children:[{_reference:"first"}, {_reference:"second"}, {_reference:"third"}] },
+					{ id:"ltr2",path:"ltr2",type:"ltr2", undefined: "Ltr2", children:[{_reference:"first"}, {_reference:"second"}, {_reference:"third"}] },
+					{ id:"rtl2",path:"rtl2",type:"rtl2", undefined: "Rtl2", children:[{_reference:"first"}, {_reference:"second"}, {_reference:"third"}] },
+					{ id:"auto2",path:"auto2",type:"auto2", undefined: "Auto2", children:[{_reference:"first"}, {_reference:"second"}, {_reference:"third"}] },
+					
+					{id:"first",path:"first",type:"", undefined: "שלום world!"},
+					{id:"second",path:"second",type:"",undefined: "Hello world!"},						
+					{id:"third",path:"third",type:"",undefined: "Hello עולם!"}]
+				}
+			});
+			
+			treeModelLtr1 = new TreeStoreModel({
+				store: store,
+				rootLabel: "שלום World !",
+				childrenAttrs: ["children"],
+				newItemIdAttr: "path",
+				query:{type:'ltr'}
+			});
+
+			treeModelRtl1 = new TreeStoreModel({
+				store: store,
+				rootLabel: "שלום World !",
+				childrenAttrs: ["children"],
+				newItemIdAttr: "path",			
+				query:{type:'rtl'}
+			});
+
+			treeModelAuto1 = new TreeStoreModel({
+				store: store,
+				rootLabel: "שלום World !",
+				childrenAttrs: ["children"],
+				newItemIdAttr: "path",				
+				query:{type:'auto'}
+			});
+			
+			treeModelLtr2 = new TreeStoreModel({
+				store: store,
+				rootLabel: "שלום World !",
+				childrenAttrs: ["children"],
+				newItemIdAttr: "path",
+				query:{type:'ltr2'}
+			});
+
+			treeModelRtl2 = new TreeStoreModel({
+				store: store,
+				rootLabel: "שלום World !",
+				childrenAttrs: ["children"],
+				newItemIdAttr: "path",			
+				query:{type:'rtl2'}
+			});
+
+			treeModelAuto2 = new TreeStoreModel({
+				store: store,
+				rootLabel: "שלום World !",
+				childrenAttrs: ["children"],
+				newItemIdAttr: "path",				
+				query:{type:'auto2'}
+			});
+			
+			
+		});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	
+	</style>
+	
+	
+</head>
+
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">TreeView widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		
+			
+	<div id="treeView1" data-dojo-type="dojox.mobile.TreeView" data-dojo-props='textDir:"ltr", model: treeModelLtr1'></div>
+
+
+
+
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		
+		<div id="treeView2" data-dojo-type="dojox.mobile.TreeView" data-dojo-props='textDir:"rtl", model: treeModelRtl1'></div>
+					
+		
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		
+		<div id="treeView3" data-dojo-type="dojox.mobile.TreeView" data-dojo-props='textDir:"auto", model: treeModelAuto1'></div>
+		
+	</div>	
+	 
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		
+		<div id="treeView4" data-dojo-type="dojox.mobile.TreeView" data-dojo-props='textDir:"ltr", model: treeModelLtr2'></div>
+	</div>
+	
+	<div id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+			
+		<div id="treeView5" dir=rtl data-dojo-type="dojox.mobile.TreeView" data-dojo-props='textDir:"rtl", model: treeModelRtl2'></div>
+	</div>	
+	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		
+		<div id="treeView6" data-dojo-type="dojox.mobile.TreeView" data-dojo-props='textDir:"auto", model: treeModelAuto2'></div>				
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_ValuePicker.html b/dojox/mobile/tests/bidi/Bidi_ValuePicker.html
new file mode 100644
index 0000000..92d9b77
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_ValuePicker.html
@@ -0,0 +1,281 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Bidi Mobile test - ValuePicker</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dijit/_base/manager",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ValuePicker",	
+			"dojox/mobile/ValuePickerSlot",		
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/ListItem"
+		], function(connect, ready, array, dom, registry){
+			ready(function(){
+			
+				//change label 
+				var btn1 = registry.byId("btnlbl");
+				btn1.connect(btn1, "onClick", function(){
+					registry.byId("first3").set("value","\u05e9\u05dc\u05d5\u05dd for TEST!");	
+						
+				});
+	
+			
+				//change textDir, text
+				var btnLtr = registry.byId("btn5");				
+				btnLtr.connect(btnLtr, "onClick", function(){
+					registry.byId("first1").set("textDir", "ltr");
+				});
+				var btnRtl = registry.byId("btn6");
+				btnLtr.connect(btnRtl, "onClick", function(){
+					registry.byId("first1").set("textDir", "rtl");				
+				});	
+				var btnAuto = registry.byId("btn7");
+				btnAuto.connect(btnAuto, "onClick", function(){
+					registry.byId("first1").set("textDir", "auto");					
+				});						
+		});
+	});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 180px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: url(../images/red-button-bg.png);
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+	<div id="view0" data-dojo-type="dojox.mobile.ScrollableView">
+	        <h2 data-dojo-type="dojox.mobile.Heading">ValuePicker widget</h2>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir LTR</h1>	
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/LTR.png", moveTo:"view1"'>Tex Dir LTR</li>
+			<li id="l2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/RTL.png", moveTo:"view2"'>Tex Dir RTL</li>
+			<li id="l3" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view3"'>Tex Dir AUTO</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">dir RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" >
+			<li id="l4" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/LTR.png", moveTo:"view4"'>Tex Dir LTR</li>
+			<li id="l5" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/RTL.png", moveTo:"view5"'>Tex Dir RTL</li>
+			<li id="l6" data-dojo-type="dojox.mobile.ListItem"  data-dojo-props='icon:"../images/auto.png", moveTo:"view6"'>Tex Dir AUTO</li>
+		</ul>	
+	</div>	
+	
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir LTR</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btn5" class="mblRedButton" data-dojo-props='label:"Set Slot textDir ltr"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn6" class="mblRedButton" data-dojo-props='label:"Set Slot textDir rtl"'></button>
+		<button data-dojo-type="dojox.mobile.Button" id="btn7" class="mblRedButton" data-dojo-props='label:"Set Slot textDir auto"'></button>		
+		
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		
+				
+		<div data-dojo-type="dojox/mobile/View">
+			<h1 data-dojo-type="dojox/mobile/Heading">TextDir is set to ValuePickerSlot</h1>
+			<div id="spin1" data-dojo-type="dojox/mobile/ValuePicker">
+				<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+					data-dojo-props="labels:['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']"
+					style="text-align:center;width:40px;"></div>
+				<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+					data-dojo-props='labelFrom:0, labelTo:9'
+					style="width:50px;"></div>
+				<div id="first1" data-dojo-type="dojox/mobile/ValuePickerSlot"
+					data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'ltr'"
+					style="width:200px;"></div>
+				</div>
+			</div>
+		<h1 data-dojo-type="dojox/mobile/Heading">TextDir is set to ValuePicker</h1>
+		<div id="spin11" data-dojo-type="dojox/mobile/ValuePicker" data-dojo-props="textDir:'ltr'">
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:50px;"></div>
+			<div id="first11" data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!']"
+				style="width:200px;"></div>
+			</div>
+		</div>			
+		</div>
+			
+	</div>
+	
+		
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir RTL</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+		
+		<div data-dojo-type="dojox/mobile/View">
+			<h1 data-dojo-type="dojox/mobile/Heading">TextDir is set to ValuePickerSlot</h1>
+			<div id="spin2" data-dojo-type="dojox/mobile/ValuePicker" >
+				<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+					data-dojo-props="labels:['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']"
+					style="text-align:center;width:40px;"></div>
+				<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+					data-dojo-props='labelFrom:0, labelTo:9'
+					style="width:50px;"></div>
+				<div id="first2" data-dojo-type="dojox/mobile/ValuePickerSlot"
+					data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'rtl'"
+					style="width:200px;"></div>
+				</div>
+			</div>
+			<h1 data-dojo-type="dojox/mobile/Heading">TextDir is set to ValuePicker</h1>
+			<div id="spin22" data-dojo-type="dojox/mobile/ValuePicker" data-dojo-props="textDir:'rtl'">
+				<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+					data-dojo-props="labels:['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']"
+					style="text-align:center;width:40px;"></div>
+				<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+					data-dojo-props='labelFrom:0, labelTo:9'
+					style="width:50px;"></div>
+				<div id="first22" data-dojo-type="dojox/mobile/ValuePickerSlot"
+					data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!']"
+					style="width:200px;"></div>
+				</div>
+			</div>			
+			
+		
+		</div>
+	</div>
+		
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir LTR | textDir AUTO</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">TextDir is set to ValuePickerSlot</h1>
+		<div id="spin3" data-dojo-type="dojox/mobile/ValuePicker">
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:50px;"></div>
+			<div id="first3" data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'auto'"
+				style="width:200px;"></div>
+			</div>
+		</div>		
+		<button data-dojo-type="dojox.mobile.Button" id="btnlbl" >Set new text Button for picker slot</button>
+		
+		</div>		
+		<h1 data-dojo-type="dojox/mobile/Heading">TextDir is set to ValuePicker</h1>
+		<div id="spin33" data-dojo-type="dojox/mobile/ValuePicker" data-dojo-props="textDir:'auto'">
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:50px;"></div>
+			<div id="first33" data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!']"
+				style="width:200px;"></div>
+			</div>
+		</div>				
+	</div>	
+	 
+	 
+	<div dir="rtl" id="view4" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir LTR</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true, textDir:"ltr"'>	
+		<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">TextDir is set to ValuePickerSlot</h1>
+		<div id="spin4" data-dojo-type="dojox/mobile/ValuePicker">
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:50px;"></div>
+			<div id="first4" data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'ltr'"
+				style="width:200px;"></div>
+			</div>
+		</div>
+		
+		
+		</div>
+		
+		
+	</div>
+	<div id="view5" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir RTL</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>	
+			
+			<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">TextDir is set to ValuePickerSlot</h1>
+		<div dir="rtl" id="spin5" data-dojo-type="dojox/mobile/ValuePicker" >
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:50px;"></div>
+			<div id="first5" data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'rtl'"
+				style="width:200px;"></div>
+			</div>
+		</div>
+			
+			</div>
+				
+		
+		</div>	
+	<div dir="rtl" id="view6" data-dojo-type="dojox.mobile.ScrollableView">	
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view0"'>Dir RTL | textDir AUTO</h1>
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+		<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">TextDir is set to ValuePickerSlot</h1>
+		<div id="spin6" data-dojo-type="dojox/mobile/ValuePicker">
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:50px;"></div>
+			<div id="first6" data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['Hello world!','שלום עולם!','Hello עולם!','שלום World!'],textDir:'auto'"
+				style="width:200px;"></div>
+			</div>
+		</div>	
+		
+		
+		</div>				
+		
+	</div>	
+
+
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/Bidi_carousel-categ.json b/dojox/mobile/tests/bidi/Bidi_carousel-categ.json
new file mode 100644
index 0000000..adeef6f
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_carousel-categ.json
@@ -0,0 +1,8 @@
+{
+	items: [
+		{src:"../images/dish1.jpg", value:"dish", headerText:"Hello world!"},
+		{src:"../images/glass1.jpg", value:"glass", headerText:"שלום עולם!"},
+		{src:"../images/stone1.jpg", value:"stone", headerText:"Hello עולם!"},
+		{src:"../images/shell1.jpg", value:"shell", headerText:"שלום World!"}
+	]
+}
diff --git a/dojox/mobile/tests/bidi/Bidi_index.js b/dojox/mobile/tests/bidi/Bidi_index.js
new file mode 100644
index 0000000..8891c37
--- /dev/null
+++ b/dojox/mobile/tests/bidi/Bidi_index.js
@@ -0,0 +1,51 @@
+var categories = [
+	
+	{ tag: "Bidi-text", label: "Bidi test for Mobile widgets"},
+	{ tag: "Bidi-mirroring", label: "Bidi mirroring for Mobile widgets"}
+];
+var tests = [
+	{ url: "Bidi_Accordion.html", tags: "Bidi-text" },
+	{ url: "Bidi_Button.html", tags: "Bidi-text" },
+	{ url: "Bidi_ComboBox.html", tags: "Bidi-text" },
+	{ url: "Bidi_Dialog.html", tags: "Bidi-text" },
+	{ url: "Bidi_EdgeToEdgeCategoryList.html", tags: "Bidi-text" },
+	{ url: "Bidi_EdgeToEdgeDataList.html", tags: "Bidi-text" },
+	{ url: "Bidi_EdgeToEdgeList.html", tags: "Bidi-text" },
+	{ url: "Bidi_EdgeToEdgeStoreList.html", tags: "Bidi-text" },
+	{ url: "Bidi_Heading.html", tags: "Bidi-text" },
+	{ url: "Bidi_IconContainer.html", tags: "Bidi-text" },
+	{ url: "Bidi_IconMenu.html", tags: "Bidi-text" },
+	{ url: "Bidi_RoundRectCategoryList.html", tags: "Bidi-text" },
+	{ url: "Bidi_SearchBox.html", tags: "Bidi-text" },
+	{ url: "Bidi_SpinWheel.html", tags: "Bidi-text" },
+	{ url: "Bidi_StoreCarousel.html", tags: "Bidi-text" },
+	{ url: "Bidi_Switch.html", tags: "Bidi-text" },
+	{ url: "Bidi_TabBar.html", tags: "Bidi-text" },
+	{ url: "Bidi_TextArea.html", tags: "Bidi-text" },
+	{ url: "Bidi_TextBox.html", tags: "Bidi-text" },
+	{ url: "Bidi_ToggleButton.html", tags: "Bidi-text" },
+	{ url: "Bidi_Tooltip.html", tags: "Bidi-text" },
+	{ url: "Bidi_TreeView.html", tags: "Bidi-text" },	
+	{ url: "Bidi_ValuePicker.html", tags: "Bidi-text" },
+	{ url: "test_Carousel_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_Carousel_rtl-compat.html", tags: "Bidi-mirroring" },
+	{ url: "test_ComboBox_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_EdgeToEdgeDataList_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_EdgeToEdgeList_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_EdgeToEdgeStoreList_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_FixedSplitter-H2_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_FixedSplitter-V2H2-change_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_Heading_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_IconContainer_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_IconMenu-standalone_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_RoundRectDataList_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_RoundRectList_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_RoundRectList-check_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_RoundRectStoreList_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_SpinWheel-custom_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_SwapView_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_Switch_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_TabBar_rtl.html", tags: "Bidi-mirroring" },
+	{ url: "test_ToggleButton_rtl.html", tags: "Bidi-mirroring" }
+
+];
diff --git a/dojox/mobile/tests/bidi/doh/ButtonTests.html b/dojox/mobile/tests/bidi/doh/ButtonTests.html
new file mode 100644
index 0000000..62df1e4
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/ButtonTests.html
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Button Bidi Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+<script language="JavaScript" type="text/javascript">
+
+	require([
+		"dojo/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions, 
+		"dojo/_base/window",
+		"dojox/mobile/bidi/common",
+		"dojox/mobile/Button",		
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(has, domConst, ready, registry, runner, win, common, Button){
+
+		function _createButtonProgrammatically(){
+			var demoWidget = new Button({"class":"redButton", style:"width:180px", label:"Pragramm Button!", id:"btn1", textDir:"rtl"});
+			win.body().appendChild(demoWidget.domNode);
+			win.body().appendChild(domConst.create("br"));
+			return demoWidget;			
+		}
+		ready(function(){
+			var lre = common.MARK.LRE;
+			var rle = common.MARK.RLE;
+			
+			var button1 = _createButtonProgrammatically();
+			var button2 = registry.byId("btn2");
+			var button3 = registry.byId("btn3");
+			var button4 = registry.byId("btn4");
+			var button5 = registry.byId("btn5");
+			var button6 = registry.byId("btn6");
+
+			function getFirstChar(btn){
+				var text = btn.domNode.innerHTML;
+				return text ? text.charAt(0) : "";
+			};
+				
+			runner.register("dojox.mobile.test.bidi.doh.ButtonTests", [			
+					
+				function test_LTR_TextDir(){
+					runner.assertEqual("ltr", button3.get("textDir"), "button textDir should be ltr");
+					runner.assertEqual(lre, getFirstChar(button3), "first char should be lte");
+				},
+				
+				function test_RTL_TextDir(){
+					runner.assertEqual( "rtl", button1.get("textDir"), "button textDir should be rtl");
+					runner.assertEqual(rle, getFirstChar(button1), "first char should be rle button1");						
+					runner.assertEqual("rtl", button2.get("textDir"), "button textDir should be rtl");
+					runner.assertEqual(rle, getFirstChar(button2), "first char should be rle button2");	
+					runner.assertEqual("rtl", button6.get("textDir"), "button textDir should be rtl");
+					runner.assertEqual(rle, getFirstChar(button6), "first char should be rle button6");						
+				},
+				
+				function test_auto_TextDir(){
+					runner.assertEqual("auto", button4.get("textDir"), "button textDir should be auto");
+					runner.assertEqual(rle, getFirstChar(button4),  "first char should be rle button4");						
+				},
+						
+				function test_change_textDir(){
+					button1.set("textDir", "ltr");
+					runner.assertEqual("ltr", button1.get("textDir"));
+					runner.assertEqual(lre, getFirstChar(button1));
+					button1.set("textDir", "rtl");
+					button2.set("textDir", "auto");
+					runner.assertEqual("auto", button2.get("textDir"));
+					runner.assertEqual(rle, getFirstChar(button2));
+					button2.set("textDir", "rtl");					
+					button3.set("textDir", "rtl");
+					runner.assertEqual("rtl", button3.get("textDir"));
+					runner.assertEqual(rle, getFirstChar(button3));
+					button3.set("textDir", "ltr");					
+				},
+				
+				function test_change_Label(){
+					button4.set("label", "New label...");
+					runner.assertEqual("auto", button4.get("textDir"));	
+					runner.assertEqual(lre, getFirstChar(button4));
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	    <h1 data-dojo-type="dojox.mobile.Heading">Button</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btn2" class="mblBlueButton"  data-dojo-props='textDir:"rtl"'>חדש blue RTL...</button>
+		textDir RTL
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn3"  data-dojo-props='textDir:"ltr"'  class="mblRedButton">חדש red default LTR...</button>
+		textDir LTR
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn4"  textDir="auto" disabled>חדש AUTO ...</button>
+		textDir AUTO
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn5"  disabled>חדש ...</button>
+		textDir not set
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn6" class="mblRedButton" data-dojo-props='label:"חדש -new !", textDir:"rtl"'></button>
+		textDir RTL
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/HeadingTests.html b/dojox/mobile/tests/bidi/doh/HeadingTests.html
new file mode 100644
index 0000000..01ccb41
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/HeadingTests.html
@@ -0,0 +1,144 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Heading Bidi Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+<script language="JavaScript" type="text/javascript">
+
+	require([
+		"dojo/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/_base/window",
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/bidi/common",
+		"dojox/mobile/Heading",	
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+		
+	], function(has, domConst, win, ready, registry, runner, common, Heading){
+
+		function _createHeadingProgrammatically(){
+			var demoWidget = new Heading({label:"Pragramm Heading!", textDir:"auto", id:"hdn", back:"\u05e9\u05d9\u05de\u05d5\u05e9\u0020\u05d1\u05ea\u05d2\u05d9\u05d5\u05ea BACK..."});
+			win.body().appendChild(demoWidget.domNode);
+			win.body().appendChild(domConst.create("br"));
+			return demoWidget;			
+		}
+		ready(function(){
+			var heading = _createHeadingProgrammatically();
+			var heading1 = registry.byId("hdg1");
+			var heading2 = registry.byId("hdg2");
+			var heading3 = registry.byId("hdg3");
+			var btn;
+			var lre = common.MARK.LRE;
+			var rle = common.MARK.RLE;
+			
+			function getFirstChar(obj){
+				var node = obj.labelDivNode || obj.labelNode;
+				var text = node.innerHTML;
+				return text ? text.charAt(0) : "";
+			};			
+		
+			runner.register("dojox.mobile.test.bidi.doh.HeadingTests", [			
+					
+				function test_LTR_TextDir(){
+					runner.assertEqual("ltr", heading1.get("textDir"));
+					runner.assertEqual(lre, getFirstChar(heading1));
+				},
+				
+				function test_RTL_TextDir(){
+					runner.assertEqual("rtl", heading2.get("textDir"));
+					runner.assertEqual(rle, getFirstChar(heading2));	
+				},
+				
+				function test_auto_TextDir(){
+					runner.assertEqual("auto", heading3.get("textDir"));
+					runner.assertEqual(rle, getFirstChar(heading3));						
+				},
+				
+				function test_ToolBarButton_TextDir(){
+					btn = registry.byId("btn11");
+					runner.assertNotEqual("rtl", btn.get("textDir"));
+					runner.assertEqual(lre, getFirstChar(btn));
+					btn = registry.byId("btn12");
+					runner.assertEqual(getFirstChar(btn), lre);
+					btn = registry.byId("btn21");
+					runner.assertEqual(getFirstChar(btn), rle);
+					btn = registry.byId("btn22");
+					runner.assertEqual(getFirstChar(btn), rle);
+					btn = registry.byId("btn24");
+					runner.assertEqual(btn.get("textDir"), "ltr");
+					runner.assertEqual(lre, getFirstChar(btn));
+					btn = registry.byId("btn31");
+					runner.assertEqual("auto", btn.get("textDir"));					
+					runner.assertEqual(rle, getFirstChar(btn));
+					btn = registry.byId("btn32");
+					runner.assertEqual(lre, getFirstChar(btn));					
+				},
+						
+				function test_change_textDir(){
+					runner.assertEqual("auto", heading.get("textDir"));
+					heading.set("textDir", "rtl");
+					runner.assertNotEqual("ltr", heading.get("textDir"));
+					runner.assertEqual(rle, getFirstChar(heading));
+					runner.assertEqual(rle, getFirstChar(heading.backButton));
+					btn = registry.byId("btn11");
+					btn.set("textDir", "rtl");
+					runner.assertEqual(rle, getFirstChar(btn));					
+				},
+				
+				function test_change_Label(){
+					heading3.set("label", "Text!");
+					runner.assertEqual(lre, getFirstChar(heading3));
+					heading3.set("label", "\u05e9\u05dc\u05d5\u05dd\u0021\u0021");
+					runner.assertEqual(rle, getFirstChar(heading3));
+					heading3.set("back", "\u05e9\u05dc\u05d5\u05dd\u0021\u0021 - back");
+					runner.assertEqual(rle, getFirstChar(heading3.backButton));	
+				},
+				
+				function test_change_Backlabel(){
+					heading3.set("back", "\u05e9\u05dc\u05d5\u05dd\u0021\u0021 - back");
+					runner.assertEqual(rle, getFirstChar(heading.backButton));	
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+
+
+	<div id="hdg1" data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"TextDir LTR...", textDir:"ltr"'>
+		<span id="btn11" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus",label:"DOM...  "' style="width:120px"></span>
+		<span id="btn12" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"../../images/tab-icon-33w.png",label:"חדש image..."' style="width:120px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"../../images/tab-icons.png",iconPos:"29,116,29,29",label:"Sprite"' style="width:120px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"></span>
+
+	</div><br>
+
+	<div id="hdg2" data-dojo-type="dojox.mobile.Heading"  data-dojo-props='textDir:"rtl", label:"חדש arrow  RTL...", back:"textDir RTL..."'>
+		<span id="btn21" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus",label:"DOM...  "' style="width:120px"></span>
+		<span id="btn22" data-dojo-type="dojox.mobile.ToolBarButton"  arrow="left" defaultColor="mblColorBlue" selColor="mblColorPink">חדש new...</span>
+		<span id="btn23" data-dojo-type="dojox.mobile.ToolBarButton"  data-dojo-props=''>Test...</span>
+		<span id="btn24" data-dojo-type="dojox.mobile.ToolBarButton"  data-dojo-props='arrow:"right", textDir:"ltr"'>Test ltr...</span>
+		<span id="btn25" data-dojo-type="dojox.mobile.ToolBarButton"  data-dojo-props=''>Test...</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton"  data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"></span>
+
+	</div><br>
+
+	<div id="hdg3" data-dojo-type="dojox.mobile.Heading"  data-dojo-props=' back:"חדש BB...", textDir:"auto"'>חדש labeled Icon
+		<span id="btn31" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus",label:"חדש DOM"'></span>
+		<span id="btn32" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"../../images/tab-icon-33w.png",label:"Image..."'></span>
+		<span id="btn33" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"../../images/tab-icons.png",iconPos:"29,116,29,29",label:"חדש Sprite"'></span>
+		<span id="btn34" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"></span>
+
+	</div><br></body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/IconMenuTests.html b/dojox/mobile/tests/bidi/doh/IconMenuTests.html
new file mode 100644
index 0000000..3e4b56c
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/IconMenuTests.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>IconMenu Bidi Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+<script language="JavaScript" type="text/javascript">
+
+	require([
+		"dojo/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/bidi/common",		
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
+		"dojox/mobile/IconMenu" 
+
+	], function(has, domConst, ready, registry, runner, common){
+
+		ready(function(){
+			var lre = common.MARK.LRE;
+			var rle = common.MARK.RLE;
+
+			function getFirstChar(item){
+				var text = item.labelNode.innerHTML;
+				return text ? text.charAt(0) : "";
+			};
+				
+			runner.register("dojox.mobile.test.bidi.doh.IconMenuTests", [			
+				
+				function test_LTR_TextDir(){
+					var item = registry.byId("item11");
+					runner.assertEqual(lre, getFirstChar(item));
+					item = registry.byId("item12");
+					runner.assertEqual(lre, getFirstChar(item));
+					item = registry.byId("item24");
+					runner.assertEqual(lre, getFirstChar(item));
+				},
+				
+				function test_RTL_TextDir(){
+					var item = registry.byId("item21");
+					runner.assertEqual(rle, getFirstChar(item));
+					item = registry.byId("item22");
+					runner.assertEqual(rle, getFirstChar(item));
+					item = registry.byId("item14");
+					runner.assertEqual(rle, getFirstChar(item));			
+				},
+				
+				function test_auto_TextDir(){
+					var item = registry.byId("item31");
+					runner.assertEqual(rle, getFirstChar(item));
+					item = registry.byId("item32");
+					runner.assertEqual(lre, getFirstChar(item));				
+				},
+						
+				function test_change_Label(){
+					var item = registry.byId("item34");				
+					item.set("label", "New label...");
+					runner.assertEqual("auto", item.get("textDir"));	
+					runner.assertEqual(lre, getFirstChar(item));
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+TextDir LTR
+		<ul data-dojo-type="dojox.mobile.IconMenu" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:2, textDir:"ltr"'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item11" data-dojo-props='label:"\u05e9\u05dc\u05d5\u05dd dojo!", icon:"images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item12" data-dojo-props='label:"Hello dojo!", icon:"images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item13" data-dojo-props='label:"speaker", icon:"images/tab-icon-30w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item14" data-dojo-props='label:"I am RTL!", icon:"images/tab-icon-16w.png", textDir:"rtl"'></li>
+		</ul>
+TextDir RTL
+		<ul data-dojo-type="dojox.mobile.IconMenu" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:2, textDir:"rtl"'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item21" data-dojo-props='label:"\u05e9\u05dc\u05d5\u05dd dojo!", icon:"images/tab-icon-36w.png", selected:true, textDir:"rtl"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item22" data-dojo-props='label:"Hello dojo!", icon:"images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item23" data-dojo-props='label:"speaker", icon:"images/tab-icon-30w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item24" data-dojo-props='label:"I am LTR!", icon:"images/tab-icon-16w.png", textDir:"ltr"'></li>
+		</ul>
+TextDir AUTO
+		<ul data-dojo-type="dojox.mobile.IconMenu" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:2, textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item31" data-dojo-props='label:"\u05e9\u05dc\u05d5\u05dd dojo!", icon:"images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item32" data-dojo-props='label:"Hello dojo!", icon:"images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item33" data-dojo-props='label:"speaker", icon:"images/tab-icon-30w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem"  id="item34" data-dojo-props='label:"\u05e9\u05dc\u05d5\u05dd!", icon:"images/tab-icon-16w.png"'></li>
+		</ul>			
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/TabBarTests.html b/dojox/mobile/tests/bidi/doh/TabBarTests.html
new file mode 100644
index 0000000..6c273da
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/TabBarTests.html
@@ -0,0 +1,170 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>TabBar Bidi Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+<script language="JavaScript" type="text/javascript">
+
+	require([
+		"dojo/sniff",
+		"dojo/_base/array",
+		"dojo/dom-construct", // dojo.place
+		"dojo/_base/window",		
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/bidi/common",		
+		"dojox/mobile/TabBar",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+
+	], function(has, array, domConst, win, ready, registry, runner, common, TabBar, TabBarButton){
+
+		function _createTabBarProgrammatically(){
+				domConst.create("div", {className:"label", innerHTML:"Segmented Control"}, win.body());
+				var tabBar = new TabBar({barType:"segmentedControl"});
+				win.body().appendChild(tabBar.domNode);
+				tabBar.startup();
+
+				var tabBarButton = new TabBarButton({moveTo:"view1", textDir:"rtl", selected:"true", label:"Hello \u05e9\u05dc\u05d5\u05dd\u0021"});
+				tabBar.addChild(tabBarButton);
+				tabBarButton = new TabBarButton({moveTo:"view2", textDir:"rtl", label:"\u05e9\u05dc\u05d5\u05dd\ - hello!"});
+				tabBar.addChild(tabBarButton);
+				tabBarButton = new TabBarButton({moveTo:"view3", textDir:"rtl", label:"Genius"});
+				tabBar.addChild(tabBarButton);
+				tabBar.resize();
+			
+			return tabBar;			
+		}
+		ready(function(){
+			var tabbar = _createTabBarProgrammatically();
+			var btn;
+			var lre = common.MARK.LRE;
+			var rle = common.MARK.RLE;
+			
+			function getFirstChar(obj){
+				var node = obj.labelNode;
+				var text = node.innerHTML;
+				return text ? text.charAt(0) : "";
+			};						
+		
+			runner.register("dojox.mobile.test.bidi.doh.HeadingTests", [			
+					
+				function test_LTR_TextDir_tabBarButton(){
+					btn = registry.byId("tbb13");
+					runner.assertEqual("ltr", btn.get("textDir"));
+					runner.assertEqual(lre, getFirstChar(btn));
+				},
+				
+				function test_RTL_TextDir_tabBarButton(){
+					btn = registry.byId("tbb11");
+					runner.assertEqual("rtl", btn.get("textDir"));
+					runner.assertEqual(rle, getFirstChar(btn));
+					btn = registry.byId("tbb12");
+				},
+				
+				function test_auto_TextDir_tabBarButton(){
+					btn = registry.byId("tbb21");
+					runner.assertEqual("auto", btn.get("textDir"));
+					runner.assertEqual(rle, getFirstChar(btn));
+					btn = registry.byId("tbb22");
+					runner.assertEqual("auto", btn.get("textDir"));
+					runner.assertEqual(lre, getFirstChar(btn));					
+				    btn = registry.byId("tbb23");
+					runner.assertEqual("auto", btn.get("textDir"));					
+					runner.assertEqual(lre, getFirstChar(btn));
+				},
+				
+				function test_TextDir_Badge(){
+					btn = registry.byId("tbb31");
+					runner.assertEqual("auto", btn.badgeObj.textDir);
+					runner.assertEqual(lre, btn.badgeObj.getValue().charAt(0));
+					btn = registry.byId("tbb32");
+					runner.assertEqual("auto", btn.badgeObj.textDir);
+					runner.assertEqual(rle, btn.badgeObj.getValue().charAt(0));
+					
+				},				
+				
+				function test_change_textDir(){
+					var tb = registry.byId("tab1");
+					tb.set("textDir", "rtl");
+					runner.assertEqual("rtl", tb.get("textDir"));
+					btn = registry.byId("tbb13");
+					runner.assertEqual("rtl", btn.get("textDir"));
+					runner.assertEqual(rle, getFirstChar(btn));					
+				},	
+
+				function test_change_Label(){
+					btn = registry.byId("tbb21");
+					btn.set("label", "New Label!")
+					runner.assertEqual("auto", btn.get("textDir"));
+					runner.assertEqual(lre, getFirstChar(btn));
+					btn = registry.byId("tbb22");
+					btn.set("label", "\u05e9\u05dc\u05d5\u05dd\u0021\u0021")
+					runner.assertEqual("auto", btn.get("textDir"));
+					runner.assertEqual(rle, getFirstChar(btn));					
+				}, 
+				
+				function test_program_created_TBButton(){
+					var children = tabbar.getChildren();
+					array.forEach(children, function(ch){
+						runner.assertEqual("rtl", ch.get("textDir"));
+						runner.assertEqual(rle, getFirstChar(ch));
+					}, this); 
+					
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+
+
+	<h3> textDir for TabBarButton </h3>
+	<ul data-dojo-type="dojox.mobile.TabBar" id="tab1" data-dojo-props='barType:"segmentedControl", textDir:"ltr"'>
+		<li data-dojo-type="dojox.mobile.TabBarButton" id="tbb11" data-dojo-props='selected:true, icon1:"../../images/tab-icon-21.png", icon2:"../../images/tab-icon-21h.png",textDir:"rtl"'>New חדש !</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" id="tbb12" data-dojo-props='textDir:"rtl"'>חדש RTL ...</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" id="tbb13" data-dojo-props='textDir:"ltr"'>חדש LTR...</li>
+	</ul>
+
+	<div class="label">textDir RTL in Heading, textDir AUTO in TabBar </div>
+	<div data-dojo-type="dojox.mobile.Heading" textDir="rtl">
+		<ul data-dojo-type="dojox.mobile.TabBar" id="tab2" data-dojo-props='barType:"segmentedControl", textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" id="tbb21" data-dojo-props='selected:true'>חדש Catalog</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" id="tbb22" >Share ...</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" id="tbb23" >Start חדש!! </li>
+		</ul>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props=''>Button...</span>
+	</div><br>
+	<h3> TabBar with badge textDir AUTO</h3>
+	<ul data-dojo-type="dojox.mobile.TabBar" id="tab3" data-dojo-props='barType:"standardTab", textDir:"auto", closable:true, center:false'>
+		<li data-dojo-type="dojox.mobile.TabBarButton" id="tbb31" data-dojo-props='selected:true,  badge:"New..."'>Dashboard...</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" id="tbb32" data-dojo-props='selected:true,  badge:"חדש..."'>חדש!</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+	</ul><br>	
+	
+	<h3> textDir for Mirrored TabBarButton </h3>
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"'>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true, icon1:"../../images/tab-icon-21.png", icon2:"../../images/tab-icon-21h.png",textDir:"auto"'>חדש New</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='textDir:"rtl"'>חדש RTL ...</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='textDir:"ltr"'>חדש LTR...</li>
+	</ul>	
+
+	<div data-dojo-type="dojox.mobile.Heading" textDir="rtl">
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", textDir:"auto"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>חדש Catalog</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Share ...</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Start חדש!! </li>
+		</ul>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props=''>Button...</span>
+	</div><br>	
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/module.js b/dojox/mobile/tests/bidi/doh/module.js
new file mode 100644
index 0000000..ae92dc6
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/module.js
@@ -0,0 +1,23 @@
+dojo.provide("dojox.mobile.tests.bidi.doh.module");
+
+try{
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.test_StoreCarousel-demo", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/test_StoreCarousel-demo.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.test_EdgeToEdgeList", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/test_EdgeToEdgeList.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.test_IconContainer", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/test_IconContainer.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.test_SpinWheel-custom", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/test_SpinWheel-custom.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.test_ValuePicker-custom", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/test_ValuePicker-custom.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.test_Switch", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/test_Switch.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.test_Tooltip", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/test_Tooltip.html"),999999);	
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.test_Accordion-demo", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/test_Accordion-demo.html"),999999);		
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.test_TreeView", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/test_TreeView.html"),999999);		
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.test_RoundRect-EdgeToEdgeDataList", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/test_RoundRect-EdgeToEdgeDataList.html"),999999);		
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.test_RoundRect-EdgeToEdgeStoreList", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/test_RoundRect-EdgeToEdgeStoreList.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.ButtonTests", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/ButtonTests.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.HeadingTests", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/HeadingTests.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.IconMenuTests", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/IconMenuTests.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.bidi.doh.TabBarTests", dojo.moduleUrl("dojox.mobile", "tests/bidi/doh/TabBarTests.html"),999999);	
+}catch(e){
+	doh.debug(e);
+}
+
+
diff --git a/dojox/mobile/tests/bidi/doh/runTests.html b/dojox/mobile/tests/bidi/doh/runTests.html
new file mode 100644
index 0000000..2235e5b
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.bidi.doh.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/bidi/doh/test_Accordion-demo.html b/dojox/mobile/tests/bidi/doh/test_Accordion-demo.html
new file mode 100644
index 0000000..5124f58
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/test_Accordion-demo.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Accordion</title>
+
+	<link href="../../../themes/common/dijit/dijit.css" rel="stylesheet"/>
+	<link href="../../../themes/common/domButtons/DomButtonBlackRightArrow16.css" rel="stylesheet"/>
+	<link href="../../../themes/common/domButtons/DomButtonWhiteDownArrow16.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Accordion','TabBar','dijit.Calendar']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true,  has: {'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",		
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",		
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Accordion",
+			"dojox/mobile/ContentPane",
+			"dojox/mobile/ScrollableView"		
+			], function(registry,runner,dom,ready,query){
+				ready(function(){
+					runner.register("Bidi Accordion", [
+						{
+							name: "mobile",					
+							runTest: function(){
+								query(".mblAccordionTitleLabel").forEach(function(node, index, arr){
+									runner.is(String.fromCharCode(8235), node.innerHTML.charAt(0), "node should have direction corresponding to 'textDir' property of Accordion container");	
+								});								
+							}
+						}
+					]);	 			
+					
+					runner.register("log", function(){
+						dom.byId('failures').innerHTML = runner._failureCount;
+						dom.byId('errors').innerHTML = runner._errorCount;
+					});
+
+					runner.run();
+				});
+		});
+	</script>
+
+	<style type="text/css">
+		html,body{
+			height: 100%;
+		}
+		.myPane {
+			background-image: -webkit-gradient(linear, left top, left bottom, from(#dcdcdc), to(#FFFFFF));
+			font-family: Times New Roman, Helvetica;
+			color: black;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+		<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">	
+			<div data-dojo-type="dojox.mobile.Accordion" data-dojo-props='textDir: "rtl",singleOpen:true, roundRect:true' style="height:400px;">
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"External Content!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"../../data/fragment1.html"'>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"RoundRectList!",icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"'>
+					<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='textDir:"rtl",iconBase:"../../images/tab-icon-11h.png"'>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u1space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u2space!
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							Wi-Fi!
+						</li>
+					</ul>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Dojo!", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"' class="myPane">
+					<div style="padding:10px">
+						<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+						<div style="border-top: 1px dashed gray;margin: 20px"></div>
+						<img alt="" src="../../images/dojo-logo1.png" style="float:left;margin-right:5px">
+						<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+						<p>Dojo's powerful, lightweight core makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.</p>
+					</div>
+				</div>
+			</div>
+		</div>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>		
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/test_EdgeToEdgeList.html b/dojox/mobile/tests/bidi/doh/test_EdgeToEdgeList.html
new file mode 100644
index 0000000..ad38a4a
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/test_EdgeToEdgeList.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Edge to Edge</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true,parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">	
+		require([
+			"dijit/registry",		
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",			
+			"dojox/mobile/ListItem",
+			"dojox/mobile/RoundRectCategory",			
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser",
+			"dojox/mobile/Button"			
+			], function(registry,runner,dom,ready,query){			
+				ready(function(){
+					runner.register("Bidi EdgeToEdgeList", [
+					{
+						name: "mobile",					
+						runTest: function(){
+							var LRE = String.fromCharCode(8234);					
+							var RLE = String.fromCharCode(8235);						
+							var secondListItem = registry.byId('second');						
+							var thirdListItem = registry.byId('third');
+					
+							runner.is(RLE, secondListItem.rightTextNode.innerHTML.charAt(0), "right text node of second list item inherits textDir attribute from EdgeToEdgeList container");						
+							runner.is(LRE, thirdListItem.rightTextNode.innerHTML.charAt(0), "direction of right text node of third list item has been set to 'ltr' explicitly");
+
+							var directionalMarksCount = 0;
+							query(" > *",dom.byId('second')).forEach(function(node, index, arr){		        					
+								if(node.nodeName.toUpperCase() === "IMG" && node.nextSibling.nodeType === 3
+											&& node.nextSibling.nodeValue === String.fromCharCode(8235)){
+									directionalMarksCount = 1;				            
+								} else if(node.className === "mblListItemRightIcon" && node.previousSibling.nodeType === 3
+											&& directionalMarksCount === 1 && node.previousSibling.nodeValue === String.fromCharCode(8236)){
+									directionalMarksCount = 2;
+								}
+							});
+							runner.assertEqual(2,directionalMarksCount,"set of text containing nodes should be enclosed in directional marks");
+
+							thirdListItem.set("textDir","rtl");
+							var node = query(".mblListItemLabel",dom.byId('third'))[0];
+							runner.is(RLE, node.innerHTML.charAt(0), "label node had direction changed after change of 'textDir'");		        
+						}
+					}
+				]);	 			
+				
+				runner.register("log", function(){
+					dom.byId('failures').innerHTML = runner._failureCount;
+					dom.byId('errors').innerHTML = runner._errorCount;
+				});
+
+				runner.run();
+			});
+		},
+		toggleTextDir = function(){		
+			w2 = dijit.registry.byId("second");
+			w2.set("textDir", (w2.get("textDir") !== "rtl") ? "rtl" : "ltr");
+		});		
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<button data-dojo-type="dojox.mobile.Button" data-dojo-props='type:"button", onClick:function(){ toggleTextDir(); }'>Toggle textDir of second item</button>
+	<br>
+	<div id="settings" data-dojo-type="dojox/mobile/View">
+		<h2 data-dojo-type="dojox/mobile/RoundRectCategory" data-dojo-props='textDir:"rtl"'>RTL RoundRectCategory!</h2>
+		<ul data-dojo-type="dojox/mobile/EdgeToEdgeList" data-dojo-props='textDir:"rtl"'>
+			<li id="first" data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../images/i-icon-1.png"'>
+				<font style="font-style:italic; font-size: 16pt">Rtl </font>direction!!
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li id="second" data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../images/i-icon-2.png",rightText:"mac.", moveTo:"hello."'>
+				 Wi-Fi! 		
+				 <span>Internet!</span> 				
+				 Speedy! 
+				 <font style="font-style:italic">Rtl direction!</font> 				
+			</li>
+			<li id="third" data-dojo-type="dojox/mobile/ListItem" data-dojo-props='icon:"../../images/i-icon-3.png",textDir:"ltr", rightText:"AcmePhone.", moveTo:"hello."'>
+				Rtl direction!
+			</li>
+		</ul>
+	</div>
+
+	<div id="hello" data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">Hello</h1>		
+		<ul data-dojo-type="dojox/mobile/EdgeToEdgeList">
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='moveTo:"settings"'>
+				Hello!
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" data-dojo-props='moveTo:"settings"'>
+				Carrier!!
+			</li>
+		</ul>
+	</div>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>		
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/test_IconContainer.html b/dojox/mobile/tests/bidi/doh/test_IconContainer.html
new file mode 100644
index 0000000..e33a630
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/test_IconContainer.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Icon Container (Multi - Below)</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: false, parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",		
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",
+			"dojox/mobile/IconContainer",			
+			"dojox/mobile/IconItem",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser"
+			], function(registry,runner,dom,ready,query){					
+				ready(function(){
+					runner.register("Bidi IconContainer", [
+						{
+							name: "mobile",
+							timeout: 2000,					
+							runTest: function(){
+								var LRE = String.fromCharCode(8234);					
+								var RLE = String.fromCharCode(8235);					
+								var firstListItem = registry.byId('first_li');
+								var secondListItem = registry.byId('second_li');
+								var deferred = new runner.Deferred();
+								
+								runner.is(RLE, firstListItem.labelNode.innerHTML.charAt(0), "label node of first list item inherits textDir attribute from IconContainer");
+								runner.is(RLE, firstListItem.paneWidget.labelNode.innerHTML.charAt(0), "paneWidget node of first list item inherits textDir attribute from IconContainer");
+								
+								runner.is(LRE, secondListItem.labelNode.innerHTML.charAt(0), "label node of second list item textDir has been set to 'ltr' explicitly");
+								runner.is(LRE, secondListItem.paneWidget.labelNode.innerHTML.charAt(0), "paneWidget node of second list item textDir has been set to 'ltr' explicitly");
+
+								runner.assertTrue(firstListItem._onTouchStartHandle, "'startup' call chain was successful, widget icon mouse click handle has been initialized");
+													   
+								deferred.getTestCallback(function(){
+									firstListItem.set("textDir","ltr");
+									runner.is(LRE, firstListItem.labelNode.innerHTML.charAt(0), "the text direction of label node of first list item has been changed on the fly");	                        
+									runner.is(LRE, firstListItem.paneWidget.labelNode.innerHTML.charAt(0), "the text direction of paneWidget node of first list item has been changed on the fly");                        
+									firstListItem.set("textDir","rtl");
+								})();
+															
+								return deferred;						
+							}
+						}
+					]);	 			
+					
+					runner.register("log", function(){
+						dom.byId('failures').innerHTML = runner._failureCount;
+						dom.byId('errors').innerHTML = runner._errorCount;
+					});
+
+					runner.run();
+				});
+		});		
+    </script>
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(../../images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">Icon Container (Multi - Below)</h1>
+		<ul data-dojo-type="dojox/mobile/IconContainer" data-dojo-props='textDir:"rtl" '>
+			<li id="first_li" data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app1!!", icon:"../../images/icon-1.png", lazy:true '><div class="box"></div></li>
+			<li id="second_li" data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app2!!", icon:"../../images/icon-1.png", lazy:true,textDir:"ltr" '><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app3!!", icon:"../../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"href?", icon:"../../images/icon-1.png", href:"../../test_RoundRectList.html", transition:"slide"'></li>
+		</ul>
+	</div>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>	
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/test_RoundRect-EdgeToEdgeDataList.html b/dojox/mobile/tests/bidi/doh/test_RoundRect-EdgeToEdgeDataList.html
new file mode 100644
index 0000000..b15c91b
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/test_RoundRect-EdgeToEdgeDataList.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Data Lists</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/data/ItemFileWriteStore",
+			"dijit/registry",
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",
+			"dojo/_base/lang",		
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/RoundRectDataList",
+			"dojox/mobile/EdgeToEdgeDataList"			
+		], function(ItemFileWriteStore, registry, runner, dom, ready, query, lang){
+			var static_data1 = {
+				items: [			
+				{ label: "Wi-Fi!", icon: "../../images/i-icon-1.png", moveTo: "wifi" },
+				{ label: "Brightness & Wallpaper!", icon: "../../images/i-icon-2.png", moveTo: "bright" },
+				{ label: "Picture Frame!", icon: "../../images/i-icon-3.png", moveTo: "picture" },
+				{ label: "Mail, Contacts, Calendars!", icon: "../../images/i-icon-5.png", moveTo: "wifi" }
+				]				
+			};
+
+			var static_data2 = {
+				items: [			
+				{label: "Apple!", 	moveTo: "dummy"},
+				{label: "Banana!", 	moveTo: "dummy"},
+				{label: "Cherry!", 	moveTo: "dummy"}
+				]				
+			};
+			store1 = new ItemFileWriteStore({data: lang.clone(static_data1), clearOnClose: true});
+			store2 = new ItemFileWriteStore({data: lang.clone(static_data2), clearOnClose: true});
+			store = store1;
+			var newItems = [[],[]];
+			
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;				
+				registry.byId("roundrect_list").setStore(store);
+				registry.byId("edgetoedge_list").setStore(store);				
+			};
+			// add a new item
+			add = function(){
+				var item = store.newItem({label: "New Item!", moveTo: "dummy"});
+				newItems[(store == store1) ? 1 : 0].push(item);
+			};
+			toggleTextDir = function(){
+				w1 = registry.byId("roundrect_list");
+				w1.set("textDir", (w1.get("textDir") !== "rtl") ? "rtl" : "ltr");
+					
+				w2 = registry.byId("edgetoedge_list");
+				w2.set("textDir", (w2.get("textDir") !== "rtl") ? "rtl" : "ltr");
+			};			
+			ready(function(){				
+				runner.register("Bidi Store Lists", [
+					{
+						name: "mobile",					
+						runTest: function(){		
+							query(".mblListItemLabel").forEach(function(node, index, arr){
+								if(node.innerHTML)
+									runner.is(String.fromCharCode(8235), node.innerHTML.charAt(0), "ListItem's label node should have direction correspondent to list's 'textDir'");										
+							});								
+						}
+					}
+				]);	 			
+				
+				runner.register("log", function(){
+					dom.byId('failures').innerHTML = runner._failureCount;
+					dom.byId('errors').innerHTML = runner._errorCount;
+				});
+				runner.run();
+			});				
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">RoundRectDataList</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectDataList" id="roundrect_list" data-dojo-props='textDir:"rtl", store:store, query:{label: "*"}'></ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="edgetoedge_list" data-dojo-props='textDir:"rtl", store:store, query:{label: "*"}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add()">
+		<input type="button" value="Toggle textDir" onclick="toggleTextDir()">		
+		</td></tr></table>		
+	</div>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>		
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/test_RoundRect-EdgeToEdgeStoreList.html b/dojox/mobile/tests/bidi/doh/test_RoundRect-EdgeToEdgeStoreList.html
new file mode 100644
index 0000000..27979b4
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/test_RoundRect-EdgeToEdgeStoreList.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Store Lists</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",		
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/RoundRectStoreList",
+			"dojox/mobile/EdgeToEdgeStoreList"			
+		], function(Memory, Observable, registry, runner, dom, ready, query){
+			var static_data1 = [
+				{ label: "Wi-Fi!", icon: "../../images/i-icon-1.png", moveTo: "wifi" },
+				{ label: "Brightness & Wallpaper!", icon: "../../images/i-icon-2.png", moveTo: "bright" },
+				{ label: "Picture Frame!", icon: "../../images/i-icon-3.png", moveTo: "picture" },
+				{ label: "Mail, Contacts, Calendars!", icon: "../../images/i-icon-5.png", moveTo: "wifi" }
+			];
+
+			var static_data2 = [
+				{label: "Apple!", 	moveTo: "dummy"},
+				{label: "Banana!", 	moveTo: "dummy"},
+				{label: "Cherry!", 	moveTo: "dummy"}
+			];
+			store1 = Observable(new Memory({idProperty:"label", data: static_data1}));
+			store2 = Observable(new Memory({idProperty:"label", data: static_data2}));
+			store1.__counter = store2.__counter = 1;
+			store = store1;
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("roundrect_list").setStore(store);
+				registry.byId("edgetoedge_list").setStore(store);				
+			};
+			// add a new item
+			add = function(){
+				store.add({label: "New Item "+(store.__counter++)+ "!",icon: "../../images/i-icon-1.png",moveTo: "dummy"});
+			};
+			
+			toggleTextDir = function(){
+				w1 = registry.byId("roundrect_list");
+				w1.set("textDir", (w1.get("textDir") !== "rtl") ? "rtl" : "ltr");
+					
+				w2 = registry.byId("edgetoedge_list");
+				w2.set("textDir", (w2.get("textDir") !== "rtl") ? "rtl" : "ltr");
+			};
+			ready(function(){				
+				runner.register("Bidi Store Lists", [
+					{
+						name: "mobile",					
+						runTest: function(){		
+							query(".mblListItemLabel").forEach(function(node, index, arr){
+								if(node.innerHTML)
+									runner.is(String.fromCharCode(8235), node.innerHTML.charAt(0), "ListItem's label node should have direction correspondent to list's 'textDir'");										
+							});								
+						}
+					}
+				]);	 			
+				
+				runner.register("log", function(){
+					dom.byId('failures').innerHTML = runner._failureCount;
+					dom.byId('errors').innerHTML = runner._errorCount;
+				});
+				runner.run();
+			});				
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectStoreList" id="roundrect_list" data-dojo-props='textDir:"rtl", store:store, query:{}'></ul>
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="edgetoedge_list" data-dojo-props='textDir:"rtl", store:store, query:{}'></ul>
+		<table border="1">  
+		<tr><th>Show the different set</th><th>Alter the object store</th></tr>
+		<tr><td>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		</td><td>
+		<input type="button" value="Add" onclick="add()">
+		<input type="button" value="Toggle textDir" onclick="toggleTextDir()">		
+		</td></tr></table>		
+	</div>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>		
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/test_SpinWheel-custom.html b/dojox/mobile/tests/bidi/doh/test_SpinWheel-custom.html
new file mode 100644
index 0000000..8b9714f
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/test_SpinWheel-custom.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Custom SpinWheel</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true,parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">	
+		require([
+			"dijit/registry",		
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",
+			"dojox/mobile/SpinWheel",			
+			"dojox/mobile/SpinWheelSlot",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser"
+			], function(registry,runner,dom,ready,query){			
+				ready(function(){
+						runner.register("Bidi SpinWheel", [
+						{
+							name: "mobile",					
+							runTest: function(){
+								query(".mblSpinWheelSlotLabel",dom.byId('first')).forEach(function(node, index, arr){						
+									runner.is(String.fromCharCode(8234), node.innerHTML.charAt(0), "label nodes have direction correspondent to 'textDir' of Speen Wheel Slot");
+								});
+								registry.byId('first').set("textDir","rtl");
+								var labelNode = query(".mblSpinWheelSlotLabel",dom.byId('first'))[0];
+								runner.is(String.fromCharCode(8235), labelNode.innerHTML.charAt(0), "label node had direction changed after change of 'textDir'");
+							}
+						}]);	 			
+				
+						runner.register("log", function(){
+								dom.byId('failures').innerHTML = runner._failureCount;
+								dom.byId('errors').innerHTML = runner._errorCount;
+						});
+				
+						runner.run();
+			});
+		});		
+	</script>
+	<style>
+	#spin1 {
+		width: 304px;
+		margin: 10px auto;
+	}
+	#pt {
+		width: 20px;
+	}
+	#txt {
+		width: 10px;
+		margin-left: -15px;
+		padding-top: 85px;
+		font-size: 24px;
+		font-weight: bold;
+		border: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">Custom SpinWheel</h1>
+		<div id="spin1" data-dojo-type="dojox/mobile/SpinWheel">
+			<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props='labelFrom:3000, labelTo:3100'
+				style="width:70px;"></div>
+			<div id="pt" class="mblSpinWheelSlot"></div>
+			<div id="txt" class="mblSpinWheelSlot">.</div>
+			<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:30px;"></div>
+			<div  id="first" data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props="labels:['pt.','px.','cm.'],textDir:'ltr' "
+				style="width:50px;"></div>
+			<div data-dojo-type="dojox/mobile/SpinWheelSlot"
+				data-dojo-props="labels:[
+					'<img src=../../images/i-icon-1.png>',
+					'<img src=../../images/i-icon-2.png>',
+					'<img src=../../images/i-icon-3.png>',
+					'<img src=../../images/i-icon-4.png>',
+					'<img src=../../images/i-icon-5.png>',
+					'<img src=../../images/i-icon-6.png>',
+					'<img src=../../images/i-icon-7.png>',
+					'<img src=../../images/i-icon-8.png>',
+					'<img src=../../images/i-icon-9.png>',
+					'<img src=../../images/i-icon-10.png>'
+				]"
+				style="width:70px;text-align: center;"></div>
+		</div>
+	</div>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>		
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/test_StoreCarousel-demo.html b/dojox/mobile/tests/bidi/doh/test_StoreCarousel-demo.html
new file mode 100644
index 0000000..ff1336e
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/test_StoreCarousel-demo.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel Demo (dojo.store)</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true,  has: {'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dijit/registry",
+			"dojo/store/Memory",
+			"doh/runner",
+			"dojo/dom",
+			"dojo/query",			
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/StoreCarousel",			
+			"dojox/mobile/Carousel",
+			"dojox/mobile/Button"
+		], function(connect, ready, registry, Memory, runner, dom, query){		
+			var categ = [
+				{src:"../../images/dish1.jpg", value:"שלום dish", headerText:"שלום dish!"},
+				{src:"../../images/glass1.jpg", value:"שלום glass", headerText:"שלום glass!"}
+			];
+						 
+			store1 = new Memory({data:categ, idProperty: "name"});
+			
+			ready(function(){
+				connect.subscribe("/dojox/mobile/carouselSelect", function(w, img, item, idx){
+					if(w.id == "carousel1"){
+						var dish = [
+							{src:"../../images/dish1.jpg", value:"שלום dish!", headerText:"שלום dish!"},
+							{src:"../../images/glass1.jpg", value:"שלום glass!", headerText:"שלום glass!"}						];
+						var glass = [
+							{src:"../../images/stone1.jpg", value:"שלום stone!", headerText:"שלום stone!"},
+							{src:"../../images/shell1.jpg", value:"שלום shell!", headerText:"שלום shell!"}
+						];
+						var store2 = Memory({data:eval(item.value.split(" ")[1]), idProperty: "name"});
+						
+						var w2 = registry.byId("carousel2");
+						w2.set("title", item.value);						
+						w2.setStore(store2);						
+						registry.byId("rect1").domNode.style.display = "none";
+					}
+				});
+				runner.register("Bidi Carousel", [
+					{
+						name: "mobile",					
+						runTest: function(){			
+							query(".mblCarouselItemHeaderText, .mblCarouselTitle").forEach(function(node, index, arr){					
+								if(node.innerHTML)							
+									runner.is(String.fromCharCode(8235), node.innerHTML.charAt(0), "CarouselItem's header should have direction correspondent to 'textDir'");
+							});								
+						}
+					}
+				]);	 			
+				
+				runner.register("log", function(){
+					dom.byId('failures').innerHTML = runner._failureCount;
+					dom.byId('errors').innerHTML = runner._errorCount;
+				});
+				runner.run();				
+			});
+		},
+		toggleTextDir = function(){		
+			w2 = dijit.registry.byId("carousel2");
+			w2.set("textDir", (w2.get("textDir") !== "rtl") ? "rtl" : "ltr");
+		});	
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+    <button data-dojo-type="dojox.mobile.Button" data-dojo-props='type:"button", onClick:function(){ toggleTextDir(); }'>Toggle second carousel textDir</button>
+	<br>
+	<div id="foo" data-dojo-type="dojox.mobile.ScrollableView">
+		<div id="carousel1" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "rtl", height:"150px", navButton:true, store:store1, itemWidth:156, title:"שלום Category!"'></div>
+		<div id="carousel2" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='textDir: "rtl", height:"110px", navButton:true, itemWidth:100'></div>
+		<div id="rect1" data-dojo-type="dojox.mobile.RoundRect" style="display:none"></div>
+	</div>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>		
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/test_Switch.html b/dojox/mobile/tests/bidi/doh/test_Switch.html
new file mode 100644
index 0000000..467ccbb
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/test_Switch.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Switch</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true,parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",		
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",			
+			"dojox/mobile/Switch",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser",
+			"dojox/mobile/Button"
+			], function(registry,runner,dom,ready,query){
+				ready(function(){
+					runner.register("Bidi Switch", [
+						{
+							name: "mobile",					
+							runTest: function(){						
+								runner.is(String.fromCharCode(8235), registry.byId('first').right.firstChild.innerHTML.charAt(0), "right text node of first switch item inherits textDir attribute from container");						
+								runner.is(String.fromCharCode(8235), registry.byId('third').right.firstChild.innerHTML.charAt(0), "text direction of right text node of third switch item has been set to 'rtl' explicitly");
+								
+								registry.byId('second').set("textDir","rtl");
+								var node = query(".mblSwitchTextRight",dom.byId('second'))[0];
+								runner.is(String.fromCharCode(8235), node.innerHTML.charAt(0), "node had direction changed after change of 'textDir'");			        
+							}
+						}
+					]);	 			
+					
+					runner.register("log", function(){
+						dom.byId('failures').innerHTML = runner._failureCount;
+						dom.byId('errors').innerHTML = runner._errorCount;
+					});
+
+					runner.run();
+				});
+		},
+		toggleTextDir = function(){		
+			w2 = dijit.registry.byId("first");
+			w2.set("textDir", (w2.get("textDir") !== "rtl") ? "rtl" : "ltr");
+		});		
+	</script>
+	
+	<style>
+	.color1 .mblSwitchBgLeft {
+		background: -webkit-gradient(linear, left top, left bottom, from(#28B159), to(#75FBAC), color-stop(0.5, #3FEB84), color-stop(0.5, #4CEE8E));
+	}
+	.color1 .mblSwitchBgRight {
+		background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+	}
+	.color2 .mblSwitchBgLeft {
+		background: -webkit-gradient(linear, left top, left bottom, from(#FF9D00), to(#FFCE80), color-stop(0.5, #FFBB4D), color-stop(0.5, #FFC871));
+	}
+	.color2 .mblSwitchBgRight {
+		background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+	}
+	.color1 .mblSwitchKnob,
+	.color2 .mblSwitchKnob {
+		background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#FAFAFA), color-stop(0.5, #BBBBBB), color-stop(0.5, #CACACA));
+	}
+	.mblSwitch {
+		margin-right: 10px;
+	}
+	.bold {
+		font-weight: bold;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<button data-dojo-type="dojox.mobile.Button" data-dojo-props='type:"button", onClick:function(){ toggleTextDir(); }'>Toggle textDir of first switch</button>
+	<br>
+	<div data-dojo-type="dojox/mobile/View">
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true, textDir:"rtl"'>
+			<span class="bold">Default Shape</span><br>
+			<div data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"off"'></div>
+			<div  id="first" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Start.", rightLabel:"Stop."'></div>
+		</div>
+
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Square Shape</span><br>
+			<div class="mblSwSquareShape" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"off"'></div>
+			<div  id="second" class="color2" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on", leftLabel:"Start.", rightLabel:"Stop.", shape:"mblSwSquareShape"'></div>
+		</div>
+
+		<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true, textDir:"ltr"'>
+			<span class="bold">Round Shape 1</span><br>
+			<div class="mblSwRoundShape1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"off" '></div>
+			<div  id="third" class="color1" data-dojo-type="dojox/mobile/Switch" data-dojo-props='value:"on",textDir:"rtl", leftLabel:"Start.", rightLabel:"Stop.", shape:"mblSwRoundShape1"'></div>
+		</div>
+	</div>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>			
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/test_Tooltip.html b/dojox/mobile/tests/bidi/doh/test_Tooltip.html
new file mode 100644
index 0000000..5d5490f
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/test_Tooltip.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>test Tooltip</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel','Tooltip']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",		
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",			
+			"dojox/mobile/Tooltip",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser"			
+			], function(registry,runner,dom,ready,query){		
+				ready(function(){
+					runner.register("Bidi Tooltip", [
+						{
+							name: "mobile",					
+							runTest: function(){
+								var tooltip1 = registry.byId('textTooltip1');				        
+								tooltip1.set("textDir","rtl");		        
+								query(" > *",dom.byId('textTooltip1')).forEach(function(node, index, arr){
+									var currentNode = (node.nodeType === 1 && node.childNodes.length === 1) ? node.firstChild : node;
+									if(currentNode.nodeType === 1 && currentNode.childNodes.length === 1 && currentNode.nodeValue)					
+										runner.is(String.fromCharCode(8235), currentNode.nodeValue.charAt(0), "bidi nodes of first tooltip have direction correspondent to 'textDir'");    
+								});
+								
+								query("> *",dom.byId('textTooltip2')).forEach(function(node, index, arr){
+									var currentNode = (node.nodeType === 1 && node.childNodes.length === 1) ? node.firstChild : node;
+									if(currentNode.nodeType === 1 && currentNode.childNodes.length === 1 && currentNode.nodeValue)					
+										runner.is(String.fromCharCode(8235), currentNode.nodeValue.charAt(0), "bidi nodes of second tooltip have direction correspondent to 'textDir'");    
+								});				        			        				        
+							}
+						}
+					]);	 			
+					
+					runner.register("log", function(){
+						dom.byId('failures').innerHTML = runner._failureCount;
+						dom.byId('errors').innerHTML = runner._errorCount;
+					});
+
+					runner.run();
+				});
+			},
+			toggleTextDir = function(){		
+				w2 = dijit.registry.byId("textTooltip1");
+				w2.set("textDir", (w2.get("textDir") !== "rtl") ? "rtl" : "ltr");
+			});			
+	</script>
+
+	<style>
+	.dj_phone BUTTON {
+		display:none;
+	}
+	INPUT {
+		font-family: monospace;
+		border-radius: 0px;
+	}
+	#spin1 {
+		width: 304px;
+ 	}
+	#pt {
+		width: 20px;
+		background-color: #C4C9DB;
+		opacity: 0.2;
+	}
+	#txt {
+		width: 10px;
+		margin-left: -15px;
+		padding-top: 85px;
+		font-size: 24px;
+		font-weight: bold;
+		border: none;
+	}
+	HTML {
+		min-height: 100%; /* workaround for android 3.x position:fixed bug */
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<center style="width:100%;">	
+		<input readonly onclick="dijit.byId('textTooltip1').show(this, ['above-centered','below-centered','after','before'])" value="below" size="5">
+		<br><br><b>Click boundary nodes to see tooltips</b>
+		<br><input id="btn" type="button" onclick="toggleTextDir()" value="Toggle tooltip textDir"><br>		
+	</center>
+	<center id="bot" class="bottom" style="position:fixed;bottom:10%;width:100%;">
+		<input readonly tabindex="0" onclick="dijit.byId('textTooltip1').show(this, ['above-centered','below-centered','before','after'])" value="above" size="5">
+	</center>
+	<center style="position:fixed;bottom:33%;width:100%;">
+		<input readonly onclick="dijit.byId('textTooltip1').hide()" value="click to hide text tooltip" size="26">
+	</center>
+	<div style="position:fixed;top:50%;left:1px;direction:ltr;">
+		<input readonly onclick="dijit.byId('textTooltip1').show(this, ['before','after','below-centered','above-centered'])" value="right" size="5">
+	</div>
+	<div style="position:fixed;bottom:50%;right:1px;direction:rtl;">
+		<input readonly onclick="dijit.byId('textTooltip1').show(this, ['after','before','below','above'])" value="left" size="4">
+	</div>
+
+	<div id="textTooltip1" data-dojo-type="dojox/mobile/Tooltip"  class="mblTooltipBubble">Dear friend!<br><span style="background-color:Lime">Enter any value.</span><br><center>Please!</center><div style="border:solid; text-align:center"> Thanks.</div> </div>
+	<div id="textTooltip2" data-dojo-type="dojox/mobile/Tooltip" data-dojo-props='textDir:"rtl"' class="mblTooltipBubble">Dear friend!<br><span style="background-color:Lime">Enter any value.</span><br><center>Please!</center><div style="border:solid; text-align:center"> Thanks.</div> </div>
+
+	<div style="position:fixed;bottom:0;">	
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>	
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/test_TreeView.html b/dojox/mobile/tests/bidi/doh/test_TreeView.html
new file mode 100644
index 0000000..d884f09
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/test_TreeView.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Tree View example (FileStore)</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",		
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",
+			"dojo/on",
+			"dojo/data/ItemFileReadStore",
+			"dijit/tree/ForestStoreModel",
+			"dojox/mobile/ListItem",			
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TreeView",			
+			"dojox/mobile/EdgeToEdgeDataList"
+		], function(registry,runner,dom,ready,query,on,ItemFileReadStore, ForestStoreModel,ListItem){
+				var store = new ItemFileReadStore({
+					data: {
+						identifier: 'id',
+						label: 'name',
+						items: [{id:"1",name:"First!",type:"",undefined: "שלום First Item!"},{id:"2",name:"שלום  Second!",type:"",undefined: "Second Item!"}]
+					}
+				});	
+				
+				treeModel = new ForestStoreModel({
+					store: store,
+					rootLabel: "שלום Tree Items!",
+					childrenAttrs: ["children"],
+					query:{type:'*'}
+				});
+				
+				ready(function(){				
+					runner.register("Bidi TreeView", [
+						{
+							name: "mobile",					
+							runTest: function(){
+								var label = "Left-to-right ListItem!";
+								listItem = new ListItem({label: label,noArrow: true});
+								registry.byId("list").addChild(listItem);							
+								var listItemLabels = query(".mblListItemLabel",dom.byId('list'));
+								runner.is(label.charAt(0),listItemLabels[0].innerHTML.charAt(0), "ListItem's label has default direction and shouldn't contain UCC marks");
+								listItem.destroy();
+								
+								var treeView = registry.byId('treeView');
+								var children = treeView.getChildren();
+								if(children[0] && children[0].getChildren() && children[0].getChildren()[0].declaredClass === "dojox.mobile.ListItem"){
+									children[0].getChildren()[0].on("click", function(){
+										query(".mblListItemLabel").forEach(function(node, index, arr){										
+											runner.is(String.fromCharCode(8235), node.innerHTML.charAt(0), "ListItem's label node should have direction correspondent to 'textDir'");
+										});
+									});
+								}
+		        
+								query(".mblListItemLabel",dom.byId('treeView')).forEach(function(node, index, arr){							
+									runner.is(String.fromCharCode(8235), node.innerHTML.charAt(0), "ListItem's label node should have direction correspondent to 'textDir'");										
+								});								
+							}
+						}
+					]);	 			
+					
+					runner.register("log", function(){
+						dom.byId('failures').innerHTML = runner._failureCount;
+						dom.byId('errors').innerHTML = runner._errorCount;
+					});
+					runner.run();
+				});				
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+
+	<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="list" data-dojo-props='append:true'></ul>
+	
+	<div id="treeView" data-dojo-type="dojox.mobile.TreeView" data-dojo-props='textDir:"rtl", model: treeModel'></div>
+	
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>		
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/doh/test_ValuePicker-custom.html b/dojox/mobile/tests/bidi/doh/test_ValuePicker-custom.html
new file mode 100644
index 0000000..e852243
--- /dev/null
+++ b/dojox/mobile/tests/bidi/doh/test_ValuePicker-custom.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Custom ValuePicker</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true,parseOnLoad: true,  has: {'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",		
+			"doh/runner",
+			"dojo/dom",
+			"dojo/ready",
+			"dojo/query",
+			"dojox/mobile/ValuePicker",			
+			"dojox/mobile/ValuePickerSlot",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser"
+			], function(registry,runner,dom,ready,query){					
+				ready(function(){
+					runner.register("Bidi ValuePicker", [
+						{
+							name: "mobile",					
+							runTest: function(){
+								var firstSlotWidget = registry.byId('first');			    
+								var node = query(".mblValuePickerSlotInput",dom.byId('first'))[0];
+								runner.is(String.fromCharCode(8234), node.value.charAt(0), "label node has direction correspondent to 'textDir' of Value Picker Slot");
+								firstSlotWidget.set("textDir","rtl");
+								runner.is(String.fromCharCode(8235), node.value.charAt(0), "label node had direction changed after change of 'textDir'");				
+								runner.assertEqual(firstSlotWidget.get("value"),firstSlotWidget.value,"No UCC directional characters are to be present in obtained value");
+							}
+						}
+					]);	 			
+					
+					runner.register("log", function(){
+						dom.byId('failures').innerHTML = runner._failureCount;
+						dom.byId('errors').innerHTML = runner._errorCount;
+					});
+
+					runner.run();
+				});
+		});
+    </script>
+</head>
+<body style="visibility:hidden;background-color:#424142;">
+	<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">Custom ValuePicker</h1>
+		<div id="spin1" data-dojo-type="dojox/mobile/ValuePicker">
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props='labelFrom:3000, labelTo:3100'
+				style="width:70px;"></div>
+			<div data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:50px;"></div>
+			<div id="first" data-dojo-type="dojox/mobile/ValuePickerSlot"
+				data-dojo-props="labels:['pt.','px.','cm.'],textDir:'ltr'"
+				style="width:50px;"></div>
+		</div>
+	</div>
+	<br><font style="background-color: White">Errors: <span id="errors">?</span></font>
+	<br><font style="background-color: White">Failures: <span id="failures">?</span></font>		
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/settings.json b/dojox/mobile/tests/bidi/settings.json
similarity index 100%
rename from dojox/mobile/tests/doh/settings.json
rename to dojox/mobile/tests/bidi/settings.json
diff --git a/dojox/mobile/tests/bidi/test_Carousel_rtl-compat.html b/dojox/mobile/tests/bidi/test_Carousel_rtl-compat.html
new file mode 100644
index 0000000..591d38b
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_Carousel_rtl-compat.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel Rtl</title>
+	<style type="text/css">
+		@import "../../themes/iphone/base.css";
+		@import "../../themes/iphone/Carousel.css";
+		@import "../../themes/iphone/PageIndicator.css";
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true,  has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SwapView",
+			"dojox/mobile/Carousel"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.View" dir="rtl">
+		<div id="carousel1" data-dojo-type="dojox.mobile.Carousel"
+			data-dojo-props='height:"150px", navButton:true, numVisible:2, title:"Category"'>
+
+			<div data-dojo-type="dojox.mobile.SwapView" >
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish1.jpg", value:"dish1", headerText:"dish1"'></div>
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish2.jpg", value:"dish2", headerText:"dish2"'></div>
+			</div>
+
+			<div data-dojo-type="dojox.mobile.SwapView">
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish3.jpg", value:"dish3", headerText:"dish3"'></div>
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish4.jpg", value:"dish4", headerText:"dish4"'></div>
+			</div>
+
+			<div data-dojo-type="dojox.mobile.SwapView" lazy="true">
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish5.jpg", value:"dish5", headerText:"dish5"'></div>
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish6.jpg", value:"dish6", headerText:"dish6"'></div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_Carousel_rtl.html b/dojox/mobile/tests/bidi/test_Carousel_rtl.html
new file mode 100644
index 0000000..4755182
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_Carousel_rtl.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel Rtl</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true,  has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SwapView",
+			"dojox/mobile/Carousel"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.View" dir="rtl">
+		<div id="carousel1" data-dojo-type="dojox.mobile.Carousel"
+			data-dojo-props='height:"150px", navButton:true, numVisible:2, title:"Category"'>
+
+			<div data-dojo-type="dojox.mobile.SwapView" >
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish1.jpg", value:"dish1", headerText:"dish1"'></div>
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish2.jpg", value:"dish2", headerText:"dish2"'></div>
+			</div>
+
+			<div data-dojo-type="dojox.mobile.SwapView">
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish3.jpg", value:"dish3", headerText:"dish3"'></div>
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish4.jpg", value:"dish4", headerText:"dish4"'></div>
+			</div>
+
+			<div data-dojo-type="dojox.mobile.SwapView" lazy="true">
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish5.jpg", value:"dish5", headerText:"dish5"'></div>
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"../images/dish6.jpg", value:"dish6", headerText:"dish6"'></div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_ComboBox_rtl.html b/dojox/mobile/tests/bidi/test_ComboBox_rtl.html
new file mode 100644
index 0000000..3ce0cc2
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_ComboBox_rtl.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>mobile ComboBox Rtl tests</title>
+
+	<style type="text/css">
+		@import "../../themes/iphone/TextBox.css";
+		@import "../../themes/iphone/ComboBox.css";
+		@import "../../themes/iphone/ComboBox_rtl.css";
+	</style>
+
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad: true, isDebug: true,  has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dojox.mobile");			// This is a mobile app.
+		dojo.require("dojo.parser"); //dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
+		dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
+		dojo.require("dijit.form.DataList");
+		dojo.require("dojox.mobile.ComboBox");
+
+		dojo.ready(function(){
+
+			doh.register("attributes", [
+				{
+					name: "mobile",
+					runTest: function(){
+						var widget = dijit.byId('mobile_attributes');
+						doh.is("", widget.textbox.value, "mobile original value");
+						doh.is("", widget.get('value'), "mobile original get('value')");
+						doh.is(Infinity, widget.get('pageSize'), "mobile original get('pageSize')");
+						widget.set('pageSize', 9);
+						widget.set('value', "test");
+						doh.is("test", widget.textbox.value, "mobile value");
+						doh.is("test", widget.get('value'), "mobile get('value')");
+						doh.is(9, widget.get('pageSize'), "mobile get('pageSize')");
+					}
+	 			}
+			]);
+
+			var d, focusHandle, blurHandle, widget, nop = function(){ return false; };
+			doh.register("events", [
+				{
+					name: "mobile",
+					timeout: 2000,
+					runTest: function(){
+						d = new doh.Deferred();
+						widget = dijit.byId('mobile_events');
+
+						function onFocus(){
+							widget.disconnect(focusHandle);
+							focusHandle = null;
+							widget.set('displayedValue', "Focus");
+							blurHandle = widget.connect(widget.textbox, 'onblur', onBlur);
+							dojo.byId('blurry').focus();
+						}
+						function onBlur(){
+							widget.disconnect(blurHandle);
+							blurHandle = null;
+							widget.set('onChange', onChange);
+							widget.set('displayedValue', widget.get('displayedValue')+"Blur");
+						}
+						function onChange(){
+							widget.set('onChange', nop);
+							d.getTestCallback(function(){
+								doh.is("FocusBlur", widget.textbox.value);
+							})();
+						}
+						doh.is(nop.toString(), widget.get('onChange').toString(), "get('onChange')");
+						focusHandle = widget.connect(widget, 'openDropDown', onFocus);
+						setTimeout(dojo.hitch(widget, "focus"), 0);
+
+						return d;
+					},
+					tearDown: function(){
+						d.cancel();
+						if(blurHandle){ widget.disconnect(blurHandle); }
+						if(focusHandle){ widget.disconnect(focusHandle); }
+						widget.closeDropDown();
+					}
+	 			}
+			]);
+
+			doh.register("programmatic", [
+				{
+					name: "mobile",
+					timeout: 4000,
+					runTest: function(){
+						widget = new dojox.mobile.ComboBox({id:"mobile_programmatic", list:"states", value:"Alabama", dir:"rtl" });
+						widget.placeAt("mobile_programmatic_container", "first");
+						focusHandle = widget.connect(widget, 'openDropDown',
+							function(){
+								d.getTestCallback(function(){
+									widget.disconnect(focusHandle);
+									focusHandle = null;
+									var pos = dojo.position(widget.domNode, true);
+									doh.t(pos.w > 0 && pos.h > 0 && pos.x > 0 && pos.y > 0, 'mobile position');
+									doh.is("Alabama", widget.textbox.value, 'mobile textbox value');
+									doh.is("Alabama", widget.get('value'), 'mobile widget value');
+								})();
+							}
+						);
+						d = new doh.Deferred();
+						setTimeout(dojo.hitch(widget, "focus"), 0);
+
+						return d;
+					},
+					tearDown: function(){
+						d.cancel();
+						if(focusHandle){ widget.disconnect(focusHandle); }
+						widget.closeDropDown();
+					}
+	 			}
+			]);
+
+			doh.register("log", function(){
+				dojo.byId('failures').innerHTML = doh._failureCount;
+				dojo.byId('errors').innerHTML = doh._errorCount;
+			});
+
+			doh.run();
+		});
+	</script>
+</head>
+<body style="visibility:hidden;" dir="rtl">
+	<h1 class="testTitle">mobile ComboBox non-robot tests</h1>
+	<datalist id="states">
+	<select data-dojo-type="dijit.form.DataList" data-dojo-props='id:"states"' >
+		<option value="AL">Alabama</option>
+		<option value="AK">Alaska</option>
+		<option value="AS">American Samoa</option>
+		<option value="AZ">Arizona</option>
+		<option value="AR">Arkansas</option>
+		<option value="AE">Armed Forces Europe</option>
+		<option value="AP">Armed Forces Pacific</option>
+		<option value="AA">Armed Forces the Americas</option>
+		<option value="CA">California</option>
+		<option value="CO">Colorado</option>
+		<option value="CT">Connecticut</option>
+		<option value="DE">Delaware</option>
+		<option value="DC">District of Columbia</option>
+		<option value="FM">Federated States of Micronesia</option>
+		<option value="FL">Florida</option>
+		<option value="GA">Georgia</option>
+		<option value="GU">Guam</option>
+		<option value="HI">Hawaii</option>
+		<option value="ID">Idaho</option>
+		<option value="IL">Illinois</option>
+		<option value="IN">Indiana</option>
+		<option value="IA">Iowa</option>
+		<option value="KS">Kansas</option>
+		<option value="KY">Kentucky</option>
+		<option value="LA">Louisiana</option>
+		<option value="ME">Maine</option>
+		<option value="MH">Marshall Islands</option>
+		<option value="MD">Maryland</option>
+		<option value="MA">Massachusetts</option>
+		<option value="MI">Michigan</option>
+		<option value="MN">Minnesota</option>
+		<option value="MS">Mississippi</option>
+		<option value="MO">Missouri</option>
+		<option value="MT">Montana</option>
+		<option value="NE">Nebraska</option>
+		<option value="NV">Nevada</option>
+		<option value="NH">New Hampshire</option>
+		<option value="NJ">New Jersey</option>
+		<option value="NM">New Mexico</option>
+		<option value="NY">New York</option>
+		<option value="NC">North Carolina</option>
+		<option value="ND">North Dakota</option>
+		<option value="MP">Northern Mariana Islands</option>
+		<option value="OH">Ohio</option>
+		<option value="OK">Oklahoma</option>
+		<option value="OR">Oregon</option>
+		<option value="PA">Pennsylvania</option>
+		<option value="PR">Puerto Rico</option>
+		<option value="RI">Rhode Island</option>
+		<option value="SC">South Carolina</option>
+		<option value="SD">South Dakota</option>
+		<option value="TN">Tennessee</option>
+		<option value="TX">Texas</option>
+		<option value="UT">Utah</option>
+		<option value="VT">Vermont</option>
+		<option value="VI">Virgin Islands, U.S.</option>
+		<option value="VA">Virginia</option>
+		<option value="WA">Washington</option>
+		<option value="WV">West Virginia</option>
+		<option value="WI">Wisconsin</option>
+		<option value="WY">Wyoming</option>
+	</select>
+	</datalist>
+	<table id="table" cellspacing="20">
+		<tr>
+			<td class="layout">I follow table direction</td>
+			<td class="layout"><input id="mobile_attributes" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"", list:"states"'></td>
+		</tr>
+		<tr>
+			<td class="layout">I am LTR</td>
+			<td class="layout" dir="ltr"><input id="mobile_events" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"", list:"states", onChange:function(){ return false; }'></td>
+		</tr>
+		<tr>
+			<td class="layout">programmatic</td>
+			<td class="layout" id="mobile_programmatic_container"></td>
+		</tr>
+	</table>
+	<input tyle="checkbox" id="blurry" style="opacity:0;border:0px none;"/>
+	<br>Errors: <span id="errors">?</span>
+	<br>Failures: <span id="failures">?</span>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_EdgeToEdgeDataList_rtl.html b/dojox/mobile/tests/bidi/test_EdgeToEdgeDataList_rtl.html
new file mode 100644
index 0000000..b7af4ec
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_EdgeToEdgeDataList_rtl.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeDataList Rtl</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dojo/data/ItemFileWriteStore",
+			"dijit/registry",
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeDataList"
+		], function(lang, ItemFileWriteStore, registry){
+			var static_data = { 
+				items: [ 
+					{label: "Apple", 	moveTo: "dummy"},
+					{label: "LTR",	 	moveTo: "dummy",	dir: "ltr"},
+					{label: "Cherry", 	moveTo: "dummy"},
+					{label: "Grape", 	moveTo: "dummy"},
+					{label: "Kiwi", 	moveTo: "dummy"},
+					{label: "Lemon", 	moveTo: "dummy"},
+					{label: "Melon", 	moveTo: "dummy"},
+					{label: "Orange", 	moveTo: "dummy"},
+					{label: "Peach", 	moveTo: "dummy"}
+				]
+			};
+			store1 = new ItemFileWriteStore({url: "settings.json", clearOnClose: true});
+			store2 = new ItemFileWriteStore({data: lang.clone(static_data), clearOnClose: true});
+			store = store1;
+			var newItems = [[],[]];
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("list").setStore(store);
+			};
+			// add a new item
+			add1 = function(){
+				var item = store.newItem({label: "New Item", moveTo: "dummy"});
+				newItems[(store == store1) ? 1 : 0].push(item);
+			};
+			// delete the added item
+			delete1 = function(){
+				var item = newItems[(store == store1) ? 1 : 0].pop();
+				if(item){
+					store.deleteItem(item);
+				}
+			};
+			reload1 = function(){
+				store.save({onComplete: function(){console.log("Saved");}, onError: function(e){console.log(e);}});
+				if(store === store2){
+					store.data = lang.clone(static_data);
+				}
+				store.close();
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList Rtl</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="list" data-dojo-props='store:store, query:{label: "*"}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+		<input type="button" value="Reload" onclick="reload1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_EdgeToEdgeList_rtl.html b/dojox/mobile/tests/bidi/test_EdgeToEdgeList_rtl.html
new file mode 100644
index 0000000..3719558
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_EdgeToEdgeList_rtl.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Edge to Edge</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base','Switch']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,  has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;" dir="ltr">
+	<div id="settings" data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1 data-dojo-type="dojox.mobile.Heading">Settings</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-1.png"'>
+				Airplane Mode
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-2.png", rightText:"mac", moveTo:"hello"'>
+				Wi-Fi
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-3.png", rightText:"AcmePhone", moveTo:"hello"'>
+				Carrier
+			</li>
+		</ul>
+	</div>
+
+	<div id="hello" data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1 data-dojo-type="dojox.mobile.Heading">Hello</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"settings"' dir="ltr">
+				Hello
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"settings"'>
+				Carrier
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_EdgeToEdgeStoreList_rtl.html b/dojox/mobile/tests/bidi/test_EdgeToEdgeStoreList_rtl.html
new file mode 100644
index 0000000..1735782
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_EdgeToEdgeStoreList_rtl.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList RTL</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: {'dojo-bidi':true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojo/store/Cache",
+			"dojo/store/JsonRest",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeStoreList"
+		], function(Deferred, Cache, JsonRest, Memory, Observable, registry){
+			var static_data1 = [
+				{ label: "Category 1", header: true },
+				{ label: "LTR", icon: "../images/i-icon-1.png", moveTo: "wifi", dir: "ltr" },
+				{ label: "Brightness & Wallpaper", icon: "../images/i-icon-2.png", moveTo: "bright" },
+				{ label: "Picture Frame", icon: "../images/i-icon-3.png", moveTo: "picture" },
+				{ label: "General", icon: "../images/i-icon-4.png", moveTo: "general", "selected": "true" },
+				{ label: "Mail, Contacts, Calendars", icon: "../images/i-icon-5.png", moveTo: "wifi" },
+				{ label: "Safari", icon: "../images/i-icon-6.png", moveTo: "bright" },
+				{ label: "iPod", icon: "../images/i-icon-7.png", moveTo: "picture" },
+				{ label: "Category 2", header: true },
+				{ label: "Video", icon: "../images/i-icon-8.png", moveTo: "general" },
+				{ label: "Photos", icon: "../images/i-icon-9.png", moveTo: "wifi" },
+				{ label: "Store", icon: "../images/i-icon-10.png", moveTo: "bright" }
+			];
+
+			var static_data2 = [
+				{label: "Apple", 	moveTo: "dummy"},
+				{label: "LTR", 		moveTo: "dummy", dir: "ltr"},
+				{label: "Cherry", 	moveTo: "dummy"},
+				{label: "Grape", 	moveTo: "dummy"},
+				{label: "Kiwi", 	moveTo: "dummy"},
+				{label: "Lemon", 	moveTo: "dummy"},
+				{label: "Melon", 	moveTo: "dummy"},
+				{label: "Orange", 	moveTo: "dummy"},
+				{label: "Peach", 	moveTo: "dummy"}
+			];
+			store1 = Observable(new Memory({idProperty:"label", data: static_data1}));
+			store2 = Observable(new Memory({idProperty:"label", data: static_data2}));
+			store1.__counter = store2.__counter = 1;
+			store = store1;
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("list").setStore(store);
+			};
+			// add a new item
+			add1 = function(){
+				store.add({
+					label: "New Item "+(store.__counter++),
+					icon: "../images/i-icon-1.png",
+					moveTo: "dummy"
+				});
+			};
+			// delete the added item
+			delete1 = function(){
+				if(store.__counter > 1){
+					store.remove("New Item "+(--store.__counter));
+				}
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList RTL</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="list" data-dojo-props='store:store, query:{}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_FixedSplitter-H2_rtl.html b/dojox/mobile/tests/bidi/test_FixedSplitter-H2_rtl.html
new file mode 100644
index 0000000..9a53837
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_FixedSplitter-H2_rtl.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<title>FixedSplitter Test RTL</title>
+
+	
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true,has: {'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/parser",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Pane"
+		]);
+	</script>
+
+	<style type="text/css">
+		html, body{
+			width: 100%;
+			height: 100%;
+			padding: 0px;
+			margin: 0px;
+			overflow: hidden;
+		}
+	</style>
+</head>
+<body dir="rtl">
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Pane" style="background-color:yellow;width:200px;">
+			pane #1 (width=200px)
+		</div>
+		<div data-dojo-type="dojox.mobile.Pane" style="background-color:pink;">
+			pane #2
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_FixedSplitter-V2H2-change_rtl.html b/dojox/mobile/tests/bidi/test_FixedSplitter-V2H2-change_rtl.html
new file mode 100644
index 0000000..d8dbe2d
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_FixedSplitter-V2H2-change_rtl.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<title>FixedSplitter Test RTL</title>
+
+	<link href="../../themes/iphone/FixedSplitter.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: {'dojo-bidi':true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojo/parser",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Pane"
+		], function(connect, dom, domClass, ready, registry){
+			change = function(e) {
+				var splitter = registry.byId(e.target.id == "btn1" ? "splitter1" : "splitter2");
+				splitter.set("orientation", splitter.orientation === "H" ? "V" : "H");
+			};
+			ready(function(){
+				connect.connect(dom.byId("btn1"), "onclick", "change");
+				connect.connect(dom.byId("btn2"), "onclick", "change");
+			});
+		});
+	</script>
+
+	<style type="text/css">
+		html, body{
+			width: 100%;
+			height: 100%;
+			padding: 0px;
+			margin: 0px;
+			overflow: hidden;
+		}
+
+		.mblFixedSplitterH > #pane1, .mblFixedSplitterH > #pane2 {
+			width:20%;
+		}
+		.mblFixedSplitterV > #pane1, .mblFixedSplitterV > #pane2 {
+			height:20%;
+		}
+	</style>
+</head>
+<body dir="rtl">
+	<div id="splitter1" data-dojo-type="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" data-dojo-props='orientation:"V"'>
+		<div id="pane1" data-dojo-type="dojox.mobile.Pane" style="background-color:yellow;">
+			pane #1
+	 		<input type="button" id="btn1" value="H <-> V">
+		</div>
+
+		<div id="splitter2" data-dojo-type="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" data-dojo-props='orientation:"H"'>
+			<div id="pane2" data-dojo-type="dojox.mobile.Pane" style="background-color:pink;">
+				pane #2
+	 			<input type="button" id="btn2" value="H <-> V">
+			</div>
+			<div id="pane3" data-dojo-type="dojox.mobile.Pane" style="background-color:cyan;">
+				pane #3
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_Heading_rtl.html b/dojox/mobile/tests/bidi/test_Heading_rtl.html
new file mode 100644
index 0000000..fe05803
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_Heading_rtl.html
@@ -0,0 +1,191 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Heading RTL</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js"
+		data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base','TabBar','ToolBarButton-compat','ToolBarButton','dojox/mobile/themes/common/domButtons.css']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: {'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TabBar"
+		], function(ready, registry){
+			ready(function(){
+				var btn1 = registry.byId("btn1");
+				btn1.connect(btn1, "onClick", function(){
+					console.log(this.label + " button was clicked");
+				});
+			});
+		});
+	</script>
+
+<style>
+	.mblColorPink {
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#ff9DE9), to(#cc62DD), color-stop(0.5, #ff6EDF), color-stop(0.5, #ff5FDC));
+		background-image: -moz-linear-gradient(top, #ff9DE9 0%, #ff6EDF 50%, #ff5FDC 50%, #cc62DD 100%);
+		background-color: pink;
+	}
+	
+	.mblColorPink45 {
+		background-image: -webkit-gradient(linear, left top, right bottom, from(#ff9DE9), to(#cc62DD), color-stop(0.5, #ff6EDF), color-stop(0.5, #ff5FDC));
+		background-image: -moz-linear-gradient(top left, #ff9DE9 0%, #ff6EDF 50%, #ff5FDC 50%, #cc62DD 100%);
+		background-color: pink;
+	}	
+</style>
+</head>
+<body style="visibility:hidden;" dir="rtl">
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Arrow"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" arrow="left" defaultColor="mblColorBlue" selColor="mblColorPink">MMMM</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props=''>MMMM</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='arrow:"right"'>MMMM</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props=''>MMMM</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:left;"></span>
+
+	</div><br>
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Labeled Icon"' >
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus",label:"DOM"'></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"../images/tab-icon-33w.png",label:"Image"'></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"../images/tab-icons.png",iconPos:"29,116,29,29",label:"Sprite"'></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"></span>
+
+	</div><br>
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Fixed Width"' dir="rtl">
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus",label:"DOM"' style="width:120px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"../images/tab-icon-33w.png",label:"Image"' style="width:120px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"../images/tab-icons.png",iconPos:"29,116,29,29",label:"Sprite"' style="width:120px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:left;"></span>
+
+	</div><br>
+
+	<div id="general" data-dojo-type="dojox.mobile.View" dir="rtl">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Settings", moveTo:"settings", label:"General"' dir="rtl">
+		    <div style="float:right; display:none;"></div>
+		</div>
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Long Button", moveTo:"settings"'>Very Very Long Title May Not Be Displayed in the Narrow Space - Very Very Long Title May Not Be Displayed in the Narrow Space</div>
+	</div>
+
+	<h3>Heading with buttons</h3>
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"World Clock"' dir="rtl">
+		<span id="btn1" data-dojo-type="dojox.mobile.ToolBarButton">Edit</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;" onclick="console.log('+ was clicked')"></span>
+
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" dir="rtl">
+		<span data-dojo-type="dojox.mobile.ToolBarButton">Edit</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"></span>
+		Alarm Clock
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Voice Memos"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"Speaker"'></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"Done"' defaultColor="mblColorBlue" style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Updates"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"Update All"' style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"News", back:"Bookmarks", moveTo:"bookmarks"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"Done"' defaultColor="mblColorBlue" style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"Done"' defaultColor="mblColorBlue"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"New Folder"' style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='toggle:true'>New</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='toggle:true'>Toggle</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"../images/tab-icon-18h.png", moveTo:"view3"' style="padding:0 10px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"../images/tab-icons.png", iconPos:"29,0,29,29", moveTo:"view3"' style="padding:0 10px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus", moveTo:"view3"' style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" style="width:80px" data-dojo-props='selected:true'>Catalog</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" style="width:80px">Share</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" style="width:80px">Download</li>
+		</ul>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhiteSearch"' style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+	  <table cellpadding="0" cellspacing="0" style="width:100%;"><tr>
+		<td><span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"'></span></td>
+        <td align="center"><table cellpadding="0" cellspacing="0"><tr>
+		<td align="center"><div data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"' style="margin:auto;">
+			<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true' style="width:80px">Search</div>
+			<div data-dojo-type="dojox.mobile.TabBarButton" style="width:80px">Directions</div>
+		</div></td>
+		</tr></table></td>
+		<td align="right"><span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"../images/tab-icon-15h.png"' style="float:right;"></span></td>
+	  </tr></table>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+	  <table cellpadding="0" cellspacing="0" align="center"><tr>
+		<td align="center"><div data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"' style="margin:auto;">
+			<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true' style="width:80px">Search</div>
+			<div data-dojo-type="dojox.mobile.TabBarButton" style="width:80px">Directions</div>
+		</div></td>
+	  </tr></table>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+	  <table cellpadding="0" cellspacing="0" align="right"><tr>
+		<td align="center"><div data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"' style="margin:auto;">
+			<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true' style="width:80px">Search</div>
+			<div data-dojo-type="dojox.mobile.TabBarButton" style="width:80px">Directions</div>
+		</div></td>
+	  </tr></table>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Inbox", label:"1 of 10"'>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", selectOne:false' style="float:right;">
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon:"mblDomButtonWhiteUpArrow"'></li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon:"mblDomButtonWhiteDownArrow"'></li>
+		</ul>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", label:"Inbox(32)"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhiteSearch"' style="float:right;"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhiteUpArrow"' style="float:right;"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhiteDownArrow"' style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Inbox", label:"1 of 10"'>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", selectOne:false' style="float:right;">
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon:"mblDomButtonWhiteUpArrow"'></li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon:"mblDomButtonWhiteSearch"'></li>
+		</ul>
+	</div><br>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_IconContainer_rtl.html b/dojox/mobile/tests/bidi/test_IconContainer_rtl.html
new file mode 100644
index 0000000..bf30b02
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_IconContainer_rtl.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Icon Container (Multi - Below) RTL</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config=" 'dojo-bidi': true, mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: {'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;" dir="rtl">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container (Multi - Below)</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"../images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"../images/icon-1.png", href:"test_RoundRectList_rtl.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"hrefTarget", icon:"../images/icon-1.png", href:"test_RoundRectList_rtl.html", hrefTarget:"_blank"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url", icon:"../images/icon-1.png", url:"../data/view-sample.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url-async", icon:"../images/icon-1.png", url:"../data/view-sample.html", transition:"slide", sync:false'></li>
+		</ul>
+	</div>
+
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Icon Container", moveTo:"view1"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_IconMenu-standalone_rtl.html b/dojox/mobile/tests/bidi/test_IconMenu-standalone_rtl.html
new file mode 100644
index 0000000..2733b34
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_IconMenu-standalone_rtl.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>IconMenu (standalone) RTL </title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base','IconMenu']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: {'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconMenu"
+		]);
+	</script>
+</head>
+<body style="background-color:#B8B6B9">
+	<div dir="ltr">
+		<div dir="rtl">
+			<ul data-dojo-type="dojox.mobile.IconMenu" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:3'>
+				<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"mute", icon:"../images/tab-icon-36w.png", selected:true'></li>
+				<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"keypad", icon:"../images/tab-icon-32w.png"'></li>
+				<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"speaker", icon:"../images/tab-icon-30w.png", selected:true'></li>
+				<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"add call", icon:"../images/tab-icon-16w.png"'></li>
+				<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"hold", icon:"../images/tab-icon-19w.png"'></li>
+				<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"contacts", icon:"../images/tab-icon-29w.png"'></li>
+			</ul>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_RoundRectDataList_rtl.html b/dojox/mobile/tests/bidi/test_RoundRectDataList_rtl.html
new file mode 100644
index 0000000..a73f7f6
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_RoundRectDataList_rtl.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectDataList Rtl</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: {'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dojo/data/ItemFileWriteStore",
+			"dijit/registry",
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/RoundRectDataList"
+		], function(lang, ItemFileWriteStore, registry){
+			var static_data = { 
+				items: [ 
+					{label: "Apple", 	moveTo: "dummy"},
+					{label: "LTR",	 	moveTo: "dummy",	dir: "ltr"},
+					{label: "Cherry", 	moveTo: "dummy"},
+					{label: "Grape", 	moveTo: "dummy"},
+					{label: "Kiwi", 	moveTo: "dummy"},
+					{label: "Lemon", 	moveTo: "dummy"},
+					{label: "Melon", 	moveTo: "dummy"},
+					{label: "Orange", 	moveTo: "dummy"},
+					{label: "Peach", 	moveTo: "dummy"}
+				]
+			};
+			store1 = new ItemFileWriteStore({url: "settings.json", clearOnClose: true});
+			store2 = new ItemFileWriteStore({data: lang.clone(static_data), clearOnClose: true});
+			store = store1;
+			var newItems = [[],[]];
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("list").setStore(store);
+			};
+			// add a new item
+			add1 = function(){
+				var item = store.newItem({label: "New Item", moveTo: "dummy"});
+				newItems[(store == store1) ? 1 : 0].push(item);
+			};
+			// delete the added item
+			delete1 = function(){
+				var item = newItems[(store == store1) ? 1 : 0].pop();
+				if(item){
+					store.deleteItem(item);
+				}
+			};
+			reload1 = function(){
+				store.save({onComplete: function(){console.log("Saved");}, onError: function(e){console.log(e);}});
+				if(store === store2){
+					store.data = lang.clone(static_data);
+				}
+				store.close();
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1 data-dojo-type="dojox.mobile.Heading">RoundRectDataList RTL</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectDataList" id="list" data-dojo-props='store:store, query:{label: "*"}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+		<input type="button" value="Reload" onclick="reload1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_RoundRectList-check_rtl.html b/dojox/mobile/tests/bidi/test_RoundRectList-check_rtl.html
new file mode 100644
index 0000000..1bef975
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_RoundRectList-check_rtl.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Selectable RoundRectDataList</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base','ListItem']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojo/has",
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, dom, ready, registry, has){
+			check = function(){
+				registry.byId("item1").set("checked", true);
+			};
+			uncheck = function(){
+				registry.byId("item1").set("checked", false);
+			};
+			callback = function(item, state){
+				var span = dom.byId("msgArea");
+				span.innerHTML += "onCheckStateChanged: "+item.labelNode.innerHTML+", "+state+"<br>";
+				setTimeout(function(){
+					span.innerHTML = "";
+				}, 1000);
+			};
+			ready(function(){
+				connect.connect(registry.byId("list1"), "onCheckStateChanged", null, callback);
+				connect.connect(registry.byId("list2"), "onCheckStateChanged", null, callback);
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1 data-dojo-type="dojox.mobile.Heading">Selectable List</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Single Select</h2>
+		<ul id="list1" data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"single"'>
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true'>
+				Cube
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Dissolve
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Ripple
+			</li>
+		</ul>
+		<input type="button" onclick="check()" value="check">
+		<input type="button" onclick="uncheck()" value="uncheck">
+
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Multiple Select</h2>
+		<ul id="list2" data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"multiple"' dir="rtl">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true' dir="rtl">
+				Cube
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Dissolve
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Ripple
+			</li>
+		</ul>
+
+		<div id="msgArea" style="margin-left:10px;"></div><br><br>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_RoundRectList_rtl.html b/dojox/mobile/tests/bidi/test_RoundRectList_rtl.html
new file mode 100644
index 0000000..7b98411
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_RoundRectList_rtl.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Animation</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has :{'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" dir="rtl">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-1.png", moveTo:"bar", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-2.png", moveTo:"bar", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-3.png", moveTo:"bar", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
+
+	<div id="bar" data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"foo"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_RoundRectStoreList_rtl.html b/dojox/mobile/tests/bidi/test_RoundRectStoreList_rtl.html
new file mode 100644
index 0000000..f85784a
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_RoundRectStoreList_rtl.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectStoreList RTL</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojo/store/Cache",
+			"dojo/store/JsonRest",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/RoundRectStoreList"
+		], function(Deferred, Cache, JsonRest, Memory, Observable, registry){
+			var static_data1 = [
+				{ label: "LTR", icon: "../images/i-icon-1.png", moveTo: "wifi", dir: "ltr" },
+				{ label: "Brightness & Wallpaper", icon: "../images/i-icon-2.png", moveTo: "bright" },
+				{ label: "Picture Frame", icon: "../images/i-icon-3.png", moveTo: "picture" },
+				{ label: "General", icon: "../images/i-icon-4.png", moveTo: "general", "selected": "true" },
+				{ label: "Mail, Contacts, Calendars", icon: "../images/i-icon-5.png", moveTo: "wifi" },
+				{ label: "Safari", icon: "../images/i-icon-6.png", moveTo: "bright" },
+				{ label: "iPod", icon: "../images/i-icon-7.png", moveTo: "picture" },
+				{ label: "Video", icon: "../images/i-icon-8.png", moveTo: "general" },
+				{ label: "Photos", icon: "../images/i-icon-9.png", moveTo: "wifi" },
+				{ label: "Store", icon: "../images/i-icon-10.png", moveTo: "bright" }
+			];
+
+			var static_data2 = [
+				{label: "Apple", 	moveTo: "dummy"},
+				{label: "LTR",	 	moveTo: "dummy",	dir: "ltr"},
+				{label: "Cherry", 	moveTo: "dummy"},
+				{label: "Grape", 	moveTo: "dummy"},
+				{label: "Kiwi", 	moveTo: "dummy"},
+				{label: "Lemon", 	moveTo: "dummy"},
+				{label: "Melon", 	moveTo: "dummy"},
+				{label: "Orange", 	moveTo: "dummy"},
+				{label: "Peach", 	moveTo: "dummy"}
+			];
+			store1 = Observable(new Memory({idProperty:"label", data: static_data1}));
+			store2 = Observable(new Memory({idProperty:"label", data: static_data2}));
+			store1.__counter = store2.__counter = 1;
+			store = store1;
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("list").setStore(store);
+			};
+			// add a new item
+			add1 = function(){
+				store.add({
+					label: "New Item "+(store.__counter++),
+					icon: "../images/i-icon-1.png",
+					moveTo: "dummy"
+				});
+			};
+			// delete the added item
+			delete1 = function(){
+				if(store.__counter > 1){
+					store.remove("New Item "+(--store.__counter));
+				}
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList RTL</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectStoreList" id="list" data-dojo-props='store:store, query:{}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_SpinWheel-custom_rtl.html b/dojox/mobile/tests/bidi/test_SpinWheel-custom_rtl.html
new file mode 100644
index 0000000..0c9a7ad
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_SpinWheel-custom_rtl.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Custom SpinWheel RTL</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: {'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SpinWheel"
+		]);
+	</script>
+
+	<style>
+	#spin1 {
+		width: 304px;
+		margin: 10px auto;
+	}
+	#pt {
+		width: 20px;
+	}
+	#txt {
+		width: 10px;
+		margin-right: -15px;
+		padding-top: 85px;
+		font-size: 24px;
+		font-weight: bold;
+		border: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;" dir="ltr">
+	<div data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1 data-dojo-type="dojox.mobile.Heading">Custom SpinWheel RTL</h1>
+		<div id="spin1" data-dojo-type="dojox.mobile.SpinWheel">
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props='labelFrom:3000, labelTo:3100'
+				style="width:70px;"></div>
+			<div id="pt" class="mblSpinWheelSlot"></div>
+			<div id="txt" class="mblSpinWheelSlot">.</div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:30px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:['pt','px','cm']"
+				style="width:50px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:[
+					'<img src=../images/i-icon-1.png>',
+					'<img src=../images/i-icon-2.png>',
+					'<img src=../images/i-icon-3.png>',
+					'<img src=../images/i-icon-4.png>',
+					'<img src=../images/i-icon-5.png>',
+					'<img src=../images/i-icon-6.png>',
+					'<img src=../images/i-icon-7.png>',
+					'<img src=../images/i-icon-8.png>',
+					'<img src=../images/i-icon-9.png>',
+					'<img src=../images/i-icon-10.png>'
+				]"
+				style="width:70px;text-align: center;"></div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_SwapView_rtl.html b/dojox/mobile/tests/bidi/test_SwapView_rtl.html
new file mode 100644
index 0000000..7ca41a3
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_SwapView_rtl.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>SwapView RTL</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true, has: {'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/SwapView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+		margin: 0px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;" dir="rtl">
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Page flipping demo</h1>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			Swipe the screen left or right to flip between the views.
+			There are 4 views in this demo.
+			Vertical scrolling and page indicator are not supported.
+		</div>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+		</ul>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container 1</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"app1", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"app2", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"app3", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"moveTo", icon:"../images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"href", icon:"../images/icon-1.png", href:"test_RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"url", icon:"../images/icon-1.png", url:"../data/view-sample.html", transition:"slide"'></li>
+		</ul>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container 2</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"test1", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"test2", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"test3", icon:"../images/icon-1.png", lazy:true'><div class="box"></div></li>
+		</ul>
+	</div>
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_Switch_rtl.html b/dojox/mobile/tests/bidi/test_Switch_rtl.html
new file mode 100644
index 0000000..70a8c26
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_Switch_rtl.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Switch RTL</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has: { 'dojo-bidi': true }"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+	
+	<style>
+	.color1 .mblSwitchBgLeft {
+		background: -webkit-gradient(linear, left top, left bottom, from(#28B159), to(#75FBAC), color-stop(0.5, #3FEB84), color-stop(0.5, #4CEE8E));
+	}
+	.color1 .mblSwitchBgRight {
+		background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+	}
+	.color2 .mblSwitchBgLeft {
+		background: -webkit-gradient(linear, left top, left bottom, from(#FF9D00), to(#FFCE80), color-stop(0.5, #FFBB4D), color-stop(0.5, #FFC871));
+	}
+	.color2 .mblSwitchBgRight {
+		background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+	}
+	.color1 .mblSwitchKnob,
+	.color2 .mblSwitchKnob {
+		background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#FAFAFA), color-stop(0.5, #BBBBBB), color-stop(0.5, #CACACA));
+	}
+	.mblSwitch {
+		margin-right: 10px;
+	}
+	.bold {
+		font-weight: bold;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View" dir="rtl">
+		<div>
+			<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true' dir="ltr">
+				<span class="bold">Default Shape with LTR Direction</span><br>
+				<div data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+				<div class="color1" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop"'></div>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true' >
+			<span class="bold">Square Shape</span><br>
+			<div class="mblSwSquareShape" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+			<div class="color2" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop", shape:"mblSwSquareShape"'></div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Round Shape 1</span><br>
+			<div class="mblSwRoundShape1" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+			<div class="color1" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop", shape:"mblSwRoundShape1"'></div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Round Shape 2</span><br>
+			<div class="mblSwRoundShape2" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+			<div class="color2" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop", shape:"mblSwRoundShape2"'></div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Arc Shape 1</span><br>
+			<div class="mblSwArcShape1" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+			<div class="color1" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop", shape:"mblSwArcShape1"'></div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Arc Shape 2</span><br>
+			<div class="mblSwArcShape2" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+			<div class="color2" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop", shape:"mblSwArcShape2"'></div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_TabBar_rtl.html b/dojox/mobile/tests/bidi/test_TabBar_rtl.html
new file mode 100644
index 0000000..eae6d2e
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_TabBar_rtl.html
@@ -0,0 +1,175 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>TabBar</title>
+
+	<link href="../../themes/common/domButtons/DomButtonYellowStar.css" rel="stylesheet"/>
+	<link href="../../themes/common/domButtons/DomButtonGrayStar.css" rel="stylesheet"/>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="'dojo-bidi': true, mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TabBar"
+		]);
+	</script>
+
+	<style>
+	h3 {
+		font-style: italic;
+		margin: 20px 0px 3px 8px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<h3>tabBar</h3>
+	<div dir="ltr">
+		<div dir="rtl">
+			<div>
+			<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='iconBase:"../images/tab-icons.png"'>
+				<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+					icon1:"../images/tab-icon-16.png",
+					icon2:"../images/tab-icon-16h.png",
+					selected:true'>Image</li>
+				<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+					iconPos1:"0,29,29,29",
+					iconPos2:"29,29,29,29"'>Sprite</li>
+				<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+					icon1:"mblDomButtonGrayStar",
+					icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+			</ul>
+			</div>
+		</div>
+	</div>
+
+
+
+	<h3>segmentedControl</h3>
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"' dir="rtl">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true, icon1:"../images/tab-icon-21.png", icon2:"../images/tab-icon-21h.png"'>New</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Dramatic</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Insight</li>
+	</ul>
+
+	<div class="label">(in a Heading)</div>
+	<div data-dojo-type="dojox.mobile.Heading" dir="rtl">
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Catalog</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Share</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Download</li>
+		</ul>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props=''>MMMM</span>
+	</div><br>
+
+
+
+	<h3>standardTab</h3>
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"standardTab"' dir="rtl">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+	</ul><br>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"standardTab", closable:true, center:false' dir="rtl">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+	</ul><br>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='
+		barType:"standardTab", center:false, iconBase:"../images/tab-icons.png"' dir="rtl">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			icon1:"../images/tab-icon-21.png",
+			icon2:"../images/tab-icon-21h.png",
+			selected:true'>Image</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			iconPos1:"0,29,29,29",
+			iconPos2:"29,29,29,29"'>Sprite</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			icon1:"mblDomButtonGrayStar",
+			icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+	</ul>
+
+
+
+	<h3>slimTab</h3>
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"slimTab"' dir="rtl">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Event</li>
+	</ul><br>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"slimTab", closable:true, center:false' dir="rtl">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+	</ul><br>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='
+		barType:"slimTab", center:false, iconBase:"../images/tab-icons.png"' dir="rtl">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			icon1:"../images/tab-icon-21.png",
+			icon2:"../images/tab-icon-21h.png",
+			selected:true'>Image</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			iconPos1:"0,29,29,29",
+			iconPos2:"29,29,29,29"'>Sprite</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			icon1:"mblDomButtonGrayStar",
+			icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+	</ul>
+
+
+
+	<h3>flatTab</h3>
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"flatTab"' dir="rtl">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Event</li>
+	</ul><br>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"flatTab", closable:true, center:false' dir="rtl">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+	</ul><br>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='
+		barType:"flatTab", center:false, iconBase:"../images/tab-icons.png"' dir="rtl">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			icon1:"../images/tab-icon-21.png",
+			icon2:"../images/tab-icon-21h.png",
+			selected:true'>Image</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			iconPos1:"0,29,29,29",
+			iconPos2:"29,29,29,29"'>Sprite</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			icon1:"mblDomButtonGrayStar",
+			icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+	</ul>
+
+
+
+	<h3>tallTab</h3>
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='
+		barType:"tallTab", iconBase:"../images/tab-icons.png"' dir="rtl">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			icon1:"../images/tab-icon-21.png",
+			icon2:"../images/tab-icon-21h.png",
+			selected:true'>Image</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			iconPos1:"0,29,29,29",
+			iconPos2:"29,29,29,29"'>Sprite</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+			icon1:"mblDomButtonGrayStar",
+			icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+	</ul><br>
+</body>
+</html>
diff --git a/dojox/mobile/tests/bidi/test_ToggleButton_rtl.html b/dojox/mobile/tests/bidi/test_ToggleButton_rtl.html
new file mode 100644
index 0000000..2a87698
--- /dev/null
+++ b/dojox/mobile/tests/bidi/test_ToggleButton_rtl.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Toggle Button</title>
+		<link href="../../themes/android/base.css" rel="stylesheet">
+		<link href="../../themes/android/base-compat.css" rel="stylesheet">
+		<link href="../../themes/android/ToggleButton.css" rel="stylesheet">
+		<link href="../../themes/android/ToggleButton_rtl.css" rel="stylesheet">
+		
+		<style type="text/css">
+			@import "../../themes/android/android.css";
+		</style>
+	
+		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has: {'dojo-bidi': true}"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojox.mobile");			// This is a mobile app.
+			dojo.require("dojo.parser");   //dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
+			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
+			dojo.require("dojox.mobile.Button");	
+			dojo.require("dojox.mobile.ToggleButton");	
+		</script>
+	</head>
+	<body style="visibility:hidden;" dir="rtl">
+		<div id="settings" dojoType="dojox.mobile.View" selected="true">
+			<div>
+				<div>
+					<button data-dojo-type="dojox.mobile.ToggleButton" dir="rtl">Toggle me RTL</button>
+					</br></br>
+					<button data-dojo-type="dojox.mobile.ToggleButton" dir="ltr">Toggle me Left</button>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js b/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js
index ef3fb06..ebc13f3 100644
--- a/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js
@@ -88,12 +88,12 @@ dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
 			}
 		});
 //
-//    this.connect(dijit.byId("listWidget").domNode, "onmousedown", function(event){
-//      _this.controller.showAlertDialog({
-//        title: "MDown",
-//        text: "type: " + dojox.mobile.app.isIPhone//event.target.className
-//      })
-//    });
+//	  this.connect(dijit.byId("listWidget").domNode, "onmousedown", function(event){
+//		_this.controller.showAlertDialog({
+//		  title: "MDown",
+//		  text: "type: " + dojox.mobile.app.isIPhone//event.target.className
+//		})
+//	  });
 
 	},
 
diff --git a/dojox/mobile/tests/complexListApp/index.html b/dojox/mobile/tests/complexListApp/index.html
index 2447e0c..4fbb7b5 100644
--- a/dojox/mobile/tests/complexListApp/index.html
+++ b/dojox/mobile/tests/complexListApp/index.html
@@ -12,7 +12,7 @@
 			text-decoration: none;
 		}
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false"></script>
     
 		<script language="JavaScript" type="text/javascript">
 			dojo.require("dojox.mobile.app");
diff --git a/dojox/mobile/tests/data/FixedSplitterfragment1.html b/dojox/mobile/tests/data/FixedSplitterfragment1.html
new file mode 100644
index 0000000..0d36a67
--- /dev/null
+++ b/dojox/mobile/tests/data/FixedSplitterfragment1.html
@@ -0,0 +1,4 @@
+<div>
+  <h3>FixedSplitter fragment example</h3>
+  pane #1
+</div>
diff --git a/dojox/mobile/tests/data/FixedSplitterfragment2.html b/dojox/mobile/tests/data/FixedSplitterfragment2.html
new file mode 100644
index 0000000..29ba889
--- /dev/null
+++ b/dojox/mobile/tests/data/FixedSplitterfragment2.html
@@ -0,0 +1,4 @@
+<div>
+  <h3>FixedSplitter fragment example</h3>
+  pane #2
+</div>
diff --git a/dojox/mobile/tests/data/FixedSplitterfragment3.html b/dojox/mobile/tests/data/FixedSplitterfragment3.html
new file mode 100644
index 0000000..bf25295
--- /dev/null
+++ b/dojox/mobile/tests/data/FixedSplitterfragment3.html
@@ -0,0 +1,4 @@
+<div>
+  <h3>FixedSplitter fragment example</h3>
+  pane #3
+</div>
diff --git a/dojox/mobile/tests/carousel-categ.json b/dojox/mobile/tests/data/carousel-categ.json
similarity index 100%
rename from dojox/mobile/tests/carousel-categ.json
rename to dojox/mobile/tests/data/carousel-categ.json
diff --git a/dojox/mobile/tests/carousel-dish.json b/dojox/mobile/tests/data/carousel-dish.json
similarity index 100%
rename from dojox/mobile/tests/carousel-dish.json
rename to dojox/mobile/tests/data/carousel-dish.json
diff --git a/dojox/mobile/tests/carousel-glass.json b/dojox/mobile/tests/data/carousel-glass.json
similarity index 100%
rename from dojox/mobile/tests/carousel-glass.json
rename to dojox/mobile/tests/data/carousel-glass.json
diff --git a/dojox/mobile/tests/carousel-shell.json b/dojox/mobile/tests/data/carousel-shell.json
similarity index 100%
rename from dojox/mobile/tests/carousel-shell.json
rename to dojox/mobile/tests/data/carousel-shell.json
diff --git a/dojox/mobile/tests/carousel-stone.json b/dojox/mobile/tests/data/carousel-stone.json
similarity index 100%
rename from dojox/mobile/tests/carousel-stone.json
rename to dojox/mobile/tests/data/carousel-stone.json
diff --git a/dojox/mobile/tests/data/carousel-widget.json b/dojox/mobile/tests/data/carousel-widget.json
new file mode 100644
index 0000000..981819e
--- /dev/null
+++ b/dojox/mobile/tests/data/carousel-widget.json
@@ -0,0 +1,8 @@
+{
+	items: [
+		{type:"dojox.mobile.ContentPane", props:'href:"data/fragment4.html"'},
+		{src:"images/shell1.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "3,300yen", headerText:"shell", footerText:"Free"},
+		{type:"dojox.mobile.CarouselItem", props:'src:"images/dish1.jpg",footerText:"Free",headerText:"dish"'},
+		{src:"images/shell2.jpg", design:"Lion", model: "984", produced: "1990'", size: "H3.5cm W4cm", price: "2,800yen"}
+	]
+}
diff --git a/dojox/mobile/tests/data/cvfragment1.html b/dojox/mobile/tests/data/cvfragment1.html
new file mode 100644
index 0000000..55c06e7
--- /dev/null
+++ b/dojox/mobile/tests/data/cvfragment1.html
@@ -0,0 +1,12 @@
+<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#home"'>ContentView fragment1</h1>
+<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+	<li data-dojo-type="dojox.mobile.ListItem">
+		Jack Coleman
+	</li>
+	<li data-dojo-type="dojox.mobile.ListItem">
+		James Evans
+	</li>
+	<li data-dojo-type="dojox.mobile.ListItem">
+		Jason Griffin
+	</li>
+</ul>
diff --git a/dojox/mobile/tests/data/cvfragment2.html b/dojox/mobile/tests/data/cvfragment2.html
new file mode 100644
index 0000000..fe58f6d
--- /dev/null
+++ b/dojox/mobile/tests/data/cvfragment2.html
@@ -0,0 +1,7 @@
+<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#home", transition:"flip", label:"ContentView fragment2"'></h1>
+<h2 data-dojo-type="dojox.mobile.RoundRectCategory" data-dojo-props='label:"Fruits"'></h2>
+<ul data-dojo-type="dojox.mobile.RoundRectList">
+	<li dojoType="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#home", transition:"flip", label:"Apple"'></li>
+	<li dojoType="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#home", transition:"flip", label:"Banana"'></li>
+	<li dojoType="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#home", transition:"flip", label:"Cherry"'></li>
+</ul>
diff --git a/dojox/mobile/tests/data/cvfragment3.html b/dojox/mobile/tests/data/cvfragment3.html
new file mode 100644
index 0000000..f3b7699
--- /dev/null
+++ b/dojox/mobile/tests/data/cvfragment3.html
@@ -0,0 +1,14 @@
+<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"ContentView fragment1"'></h1>
+<ul data-dojo-type="dojox.mobile.RoundRectList">
+	<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", label:"Airplane Mode"'>
+		<div data-dojo-type="dojox.mobile.Switch"></div>
+	</li>
+	<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", rightText:"mac", href:"test_IconContainer.html", label:"Wi-Fi"'></li>
+	<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", rightText:"AcmePhone", moveTo:"#home", label:"Carrier", transition:"fade"'></li>
+</ul>
+
+<ul data-dojo-type="dojox.mobile.RoundRectList">
+	<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"#home", label:"Sounds", transition:"fade"'></li>
+	<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"#home", label:"Brightness", transition:"fade"'></li>
+	<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"#home", label:"Wallpaper", transition:"fade"'></li>
+</ul>
diff --git a/dojox/mobile/tests/data/dialog1.html b/dojox/mobile/tests/data/dialog1.html
new file mode 100644
index 0000000..d0fde32
--- /dev/null
+++ b/dojox/mobile/tests/data/dialog1.html
@@ -0,0 +1,3 @@
+<div class="mblSimpleDialogTitle">Information</div>
+<div class="mblSimpleDialogText">This is a sample dialog.</div>
+<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton" style="width:100px;" onclick="hide('dlg_message')">OK</button>
diff --git a/dojox/mobile/tests/data/dialog2.html b/dojox/mobile/tests/data/dialog2.html
new file mode 100644
index 0000000..b1700f2
--- /dev/null
+++ b/dojox/mobile/tests/data/dialog2.html
@@ -0,0 +1,4 @@
+<div class="mblSimpleDialogTitle">Rain Alert</div>
+<div class="mblSimpleDialogText">Do you have an umbrella?</div>
+<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton" onclick="hide('dlg_confirm')">No</button>
+<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton mblBlueButton" onclick="hide('dlg_confirm')">Yes</button>
diff --git a/dojox/mobile/tests/data/dialog3.html b/dojox/mobile/tests/data/dialog3.html
new file mode 100644
index 0000000..b93d9ea
--- /dev/null
+++ b/dojox/mobile/tests/data/dialog3.html
@@ -0,0 +1,6 @@
+<div class="mblSimpleDialogTitle">Mobile Community</div>
+<div class="mblSimpleDialogText">Enter your ID and Password</div>
+<input data-dojo-type="dojox.mobile.TextBox" class="mblSimpleDialogInput" type="text" data-dojo-props='selectOnClick:true, placeHolder:"ID"' style="margin-bottom: 0;" required>
+<input data-dojo-type="dojox.mobile.TextBox" class="mblSimpleDialogInput" type="password" data-dojo-props='selectOnClick:true, placeHolder:"Password"' style="margin-top: 0;" required>
+<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton2l" onclick="hide('dlg_login')">Cancel</button>
+<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton2r mblBlueButton" onclick="hide('dlg_login')">OK</button>
diff --git a/dojox/mobile/tests/data/dialog4.html b/dojox/mobile/tests/data/dialog4.html
new file mode 100644
index 0000000..6dcbd63
--- /dev/null
+++ b/dojox/mobile/tests/data/dialog4.html
@@ -0,0 +1,3 @@
+<div class="mblSimpleDialogText">Please wait for 5 seconds.</div>
+<div class="mblSimpleDialogText" id="progress_indicator_container"></div>
+<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton mblRedButton" onclick="hide_progress_indicator('dlg_progress')">Cancel</button>
diff --git a/dojox/mobile/tests/data/dialog5.html b/dojox/mobile/tests/data/dialog5.html
new file mode 100644
index 0000000..f82a672
--- /dev/null
+++ b/dojox/mobile/tests/data/dialog5.html
@@ -0,0 +1,9 @@
+<div class="mblSimpleDialogTitle">Volume</div>
+<div class="mblSimpleDialogText">Ringtone</div>
+<input data-dojo-type="dojox.mobile.Slider" value="0" min="0" max="20" step="0.1" type="range" style="width:90%;">
+<div class="mblSimpleDialogText">Media</div>
+<input data-dojo-type="dojox.mobile.Slider" value="0" min="0" max="20" step="0.1" type="range" style="width:90%;">
+<div class="mblSimpleDialogText">Alarm</div>
+<input data-dojo-type="dojox.mobile.Slider" value="0" min="0" max="20" step="0.1" type="range" style="width:90%;">
+<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton2l" onclick="hide('dlg_volume')">OK</button>
+<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton2r" onclick="hide('dlg_volume')">Cancel</button>
diff --git a/dojox/mobile/tests/data/dialog6.html b/dojox/mobile/tests/data/dialog6.html
new file mode 100644
index 0000000..81d9184
--- /dev/null
+++ b/dojox/mobile/tests/data/dialog6.html
@@ -0,0 +1,13 @@
+<div class="mblSimpleDialogTitle">Animation</div>
+<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='select:"single"'>
+	<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checkClass:"mblDomButtonSilverCircleGreenButton", uncheckClass:"mblDomButtonSilverCircleGrayButton"'>
+		No animations
+	</li>
+	<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checkClass:"mblDomButtonSilverCircleGreenButton", uncheckClass:"mblDomButtonSilverCircleGrayButton"'>
+		Some animations
+	</li>
+	<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checkClass:"mblDomButtonSilverCircleGreenButton", uncheckClass:"mblDomButtonSilverCircleGrayButton", checked:true'>
+		All animations
+	</li>
+</ul>
+<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton" style="width:60%;" onclick="hide('dlg_select')">Cancel</button>
diff --git a/dojox/mobile/tests/data/dojotoolkitblog_rss2.xml b/dojox/mobile/tests/data/dojotoolkitblog_rss2.xml
new file mode 100644
index 0000000..160bcc0
--- /dev/null
+++ b/dojox/mobile/tests/data/dojotoolkitblog_rss2.xml
@@ -0,0 +1,298 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<rss version="2.0"
+	xmlns:content="http://purl.org/rss/1.0/modules/content/"
+	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
+	xmlns:dc="http://purl.org/dc/elements/1.1/"
+	xmlns:atom="http://www.w3.org/2005/Atom"
+	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
+	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
+	>
+
+<channel>
+	<title>The Dojo Toolkit Blog</title>
+	<atom:link href="http://dojotoolkit.org/blog/feed" rel="self" type="application/rss+xml" />
+	<link>http://dojotoolkit.org/blog</link>
+	<description>Unbeatable JavaScript Tools</description>
+	<lastBuildDate>Wed, 13 Jul 2011 14:59:51 +0000</lastBuildDate>
+	<language>en</language>
+	<sy:updatePeriod>hourly</sy:updatePeriod>
+	<sy:updateFrequency>1</sy:updateFrequency>
+	<generator>http://wordpress.org/?v=3.0.1</generator>
+		<item>
+		<title>DojoConf Tickets Now On Sale!</title>
+		<link>http://dojotoolkit.org/blog/dojoconf-tickets-now-on-sale</link>
+		<comments>http://dojotoolkit.org/blog/dojoconf-tickets-now-on-sale#comments</comments>
+		<pubDate>Wed, 13 Jul 2011 14:59:36 +0000</pubDate>
+		<dc:creator>Dylan Schiemann</dc:creator>
+				<category><![CDATA[Announcements]]></category>
+		<category><![CDATA[Events]]></category>
+		<category><![CDATA[News]]></category>
+
+		<guid isPermaLink="false">http://dojotoolkit.org/blog/?p=261</guid>
+		<description><![CDATA[The first ever DojoConf will be a premier event for the Dojo community and JavaScript community at large. it is run by the amazing team behind JSConf and TXJS, so you can plan on amazing presentations followed up by outstanding … <a href="http://dojotoolkit.org/blog/dojoconf-tickets-now-on-sale">Continue reading <span class="meta-nav">→</span></a>]]></description>
+			<content:encoded><![CDATA[<p>The first ever <a href="http://dojoconf.com/">DojoConf</a> will be a premier event for the Dojo community and JavaScript community at large. it is run by the amazing team behind JSConf and TXJS, so you can plan on amazing presentations followed up by outstanding social events.</p>
+<ul>
+<li>Where: Washington, DC (Palomar Hotel)</li>
+<li>When: Evening of September 15th, all-day September 16 and 17, 2011</li>
+<li>Who: Speakers including Peter Higgins, Dylan Schiemann, Alex Russell, Patrick Ruzand, James Thomas and many more presenting on everything from the future of Dojo to Dojo Mobile. Attendees will include anyone interested in Dojo, including committers, contributors, web developers, designers, project managers, and software architects.</li>
+<li>How: <a href="http://dojoconf2011.eventbrite.com">Tickets for DojoConf are available for US $650 for General Admission</a>, and are currently on sale with very limited supplies. Hotel rooms are available for the low price of US $149 and can be reserved once you register.</li>
+<li>What’s included: The ticket cost covers full access to all three parties and all of the conference day-of events, basically everything is taken care of for you!</li>
+</ul>
+<p>Early bird tickets have already gone on sale and sold out in a matter of hours, we have opened up a few more Early Bird tickets with this blog post to ensure that those who need/want them can get them. Get them now, they will sell out quickly!</li>
+]]></content:encoded>
+			<wfw:commentRss>http://dojotoolkit.org/blog/dojoconf-tickets-now-on-sale/feed</wfw:commentRss>
+		<slash:comments>0</slash:comments>
+		</item>
+		<item>
+		<title>Dojo Web Builder Source on GitHub</title>
+		<link>http://dojotoolkit.org/blog/dojo-web-builder-source-on-github</link>
+		<comments>http://dojotoolkit.org/blog/dojo-web-builder-source-on-github#comments</comments>
+		<pubDate>Thu, 16 Jun 2011 16:52:12 +0000</pubDate>
+		<dc:creator>Dylan Schiemann</dc:creator>
+				<category><![CDATA[Announcements]]></category>
+		<category><![CDATA[News]]></category>
+
+		<guid isPermaLink="false">http://dojotoolkit.org/blog/?p=257</guid>
+		<description><![CDATA[Last month we launched the Dojo Web Builder, an online solution to generate customised versions of The Dojo Toolkit using just your web browser. We are pleased to announce that the technology behind the Dojo Web Builder is now available … <a href="http://dojotoolkit.org/blog/dojo-web-builder-source-on-github">Continue reading <span class="meta-nav">→</span></a>]]></description>
+			<content:encoded><![CDATA[<p>Last month we launched the <a href="http://dojotoolkit.org/blog/introducing-the-new-dojo-web-builder">Dojo Web Builder</a>, an online solution to generate customised versions of The Dojo Toolkit using just your web browser. We are pleased to announce that the technology behind the <a href="https://github.com/dojo/dwb">Dojo Web Builder is now available on Github</a> as an official Dojo Foundation project.</p>
+<p>Users can now run the tool locally, which provides access to two really important features….</p>
+<ul>
+<li>Generate custom Dojo builds for older versions of the Dojo Toolkit. The Web Builder can be easily configured to work with older versions of the toolkit, whereas the hosted version only provides access to the latest version of Dojo. This allows users who aren’t using the latest version of Dojo within their application to generate customised builds with the tool.</li>
+<li>Expose custom application modules through the Web Builder. Plug your local Dojo modules into the Web Builder and the tool will automatically allow users to build optimised application layers from all modules it has discovered.</li>
+</ul>
+<p>Follow the simple instructions in the <a href="https://github.com/dojo/dwb/blob/master/README.md">project’s README file</a> for full details on both of these modes.</p>
+<p>Visit the <a href="https://github.com/dojo/dwb">Dojo Web Builder GitHub project</a> and start using it today!</p>
+]]></content:encoded>
+			<wfw:commentRss>http://dojotoolkit.org/blog/dojo-web-builder-source-on-github/feed</wfw:commentRss>
+		<slash:comments>0</slash:comments>
+		</item>
+		<item>
+		<title>Dojo 1.6.1, 1.7 Beta, Tutorials, Dojo Beer, DojoConf, and more…</title>
+		<link>http://dojotoolkit.org/blog/dojo-1-6-1-1-7-beta-tutorials-dojo-beer-dojoconf-and-more</link>
+		<comments>http://dojotoolkit.org/blog/dojo-1-6-1-1-7-beta-tutorials-dojo-beer-dojoconf-and-more#comments</comments>
+		<pubDate>Wed, 08 Jun 2011 21:56:49 +0000</pubDate>
+		<dc:creator>Dylan Schiemann</dc:creator>
+				<category><![CDATA[Announcements]]></category>
+		<category><![CDATA[Events]]></category>
+		<category><![CDATA[News]]></category>
+
+		<guid isPermaLink="false">http://dojotoolkit.org/blog/?p=253</guid>
+		<description><![CDATA[If you haven’t been following us on Twitter, it’s been a very busy month in our community, with many exciting announcements and upcoming events. Recent News Dojo 1.6.1 released. Many minor enhancements and fixes were made, along with official support … <a href="http://dojotoolkit.org/blog/dojo-1-6-1-1-7-beta-tutorials-dojo-beer-dojoconf-and-more">Continue reading <span class="meta-nav">→</span></a>]]></description>
+			<content:encoded><![CDATA[<p>If you haven’t been following us on Twitter, it’s been a very busy month in our community, with many exciting announcements and upcoming events.</p>
+<h2>Recent News</h2>
+<ul>
+<li><a href="http://dojotoolkit.org/download/">Dojo 1.6.1 released</a>. Many minor enhancements and fixes were made, along with official support for Internet Explorer 9 and Firefox 4.</li>
+<li><a href="http://download.dojotoolkit.org/release-1.7.0b1/">Dojo 1.7 beta released</a>. Please start testing your applications now and report issues. A <a href="http://docs.dojocampus.org/releasenotes/1.7">draft of the 1.7 release notes is in progress</a>. 1.7 final is slated for release in the next 3-6 weeks.</li>
+<li><a href="http://dojotoolkit.org/documentation/">Dojo Tutorials</a>. In case you missed it, we now have 28 new tutorials, all updated for Dojo 1.6, covering a variety of areas of Dojo and Dojo Mobile, as well as a new section of Dojo Recipes, for solving complex real-world problems.</a>
+</ul>
+<h2>Upcoming Events</h2>
+<ul>
+<li><a href="http://www.sitepen.com/services/workshops/">Dojo Workshops</a> in your area. SitePen has been offering a number of workshops, with the next <a href="http://www.sitepen.com/services/workshops/index.php?dojo-workshop-washington-dc-06-2011">Dojo Workshop in Washington DC</a>. Register now for one of the last few slots.</li>
+<li><a href="http://www.sitepen.com/blog/2011/05/26/heads-up-dojo-beer-dc-june-22-2011/">Dojo Beer DC</a>. Even if you cannot make the workshop, join us for free <a href="http://www.sitepen.com/blog/2011/05/26/heads-up-dojo-beer-dc-june-22-2011/">Dojo Beer in DC</a>, or any upcoming Dojo Beer event.</a></li>
+<li>The first ever <a href="http://dojoconf.com/">DojoConf</a> is coming. Run by the same great team that brings us JSConf, DojoConf will be an amazing event. Stay tuned for tickets, which go on sale in a few weeks. Or submit a talk idea by this Friday, June 10th.</li>
+<li>The <a href="http://londonajax.com/">London Ajax Mobile Event</a> will feature a number of great talks on mobile, including Dojo Mobile, EmbedJS, WinkToolkit, and more on July 2nd in London. A few tickets remain, register before it sells out.</li>
+</ul>
+<p>We hope to see you at one of these, or many other upcoming Dojo events.</p>
+]]></content:encoded>
+			<wfw:commentRss>http://dojotoolkit.org/blog/dojo-1-6-1-1-7-beta-tutorials-dojo-beer-dojoconf-and-more/feed</wfw:commentRss>
+		<slash:comments>2</slash:comments>
+		</item>
+		<item>
+		<title>Dojo 1.6.1 Release Candidate 1</title>
+		<link>http://dojotoolkit.org/blog/dojo161rc1</link>
+		<comments>http://dojotoolkit.org/blog/dojo161rc1#comments</comments>
+		<pubDate>Thu, 14 Apr 2011 15:20:15 +0000</pubDate>
+		<dc:creator>Dylan Schiemann</dc:creator>
+				<category><![CDATA[Announcements]]></category>
+		<category><![CDATA[News]]></category>
+
+		<guid isPermaLink="false">http://dojotoolkit.org/blog/?p=235</guid>
+		<description><![CDATA[Dojo 1.6.1rc1 is now available. 1.6.1rc1 contains many fixes, with a special focus on IE9 and FF4 support, browsers released just after Dojo 1.6.0 was completed. Please test 1.6.1rc1, especially against IE9 and FF4 browsers, and send us your feedback … <a href="http://dojotoolkit.org/blog/dojo161rc1">Continue reading <span class="meta-nav">→</span></a>]]></description>
+			<content:encoded><![CDATA[<p><a href="http://download.dojotoolkit.org/release-1.6.1rc1/">Dojo 1.6.1rc1</a> is now available.</p>
+<p><a href="http://bugs.dojotoolkit.org/query?status=assigned&status=closed&status=new&status=reopened&group=status&order=priority&milestone=1.6.1&col=id&col=summary&col=type&col=priority&col=component">1.6.1rc1 contains many fixes</a>, with a special focus on IE9 and FF4 support, browsers released just after Dojo 1.6.0 was completed.</p>
+<p>Please test 1.6.1rc1, especially against IE9 and FF4 browsers, and send us your feedback and/or file any bugs you find.  April 20, 2011 is the target release date for 1.6.1.</p>
+]]></content:encoded>
+			<wfw:commentRss>http://dojotoolkit.org/blog/dojo161rc1/feed</wfw:commentRss>
+		<slash:comments>3</slash:comments>
+		</item>
+		<item>
+		<title>Introducing the New Dojo Web Builder</title>
+		<link>http://dojotoolkit.org/blog/introducing-the-new-dojo-web-builder</link>
+		<comments>http://dojotoolkit.org/blog/introducing-the-new-dojo-web-builder#comments</comments>
+		<pubDate>Tue, 05 Apr 2011 16:09:28 +0000</pubDate>
+		<dc:creator>Dylan Schiemann</dc:creator>
+				<category><![CDATA[Announcements]]></category>
+		<category><![CDATA[News]]></category>
+
+		<guid isPermaLink="false">http://dojotoolkit.org/blog/?p=189</guid>
+		<description><![CDATA[Background Dojo’s build system has long been considered as one of the toolkit’s most important features. Using the build system will dramatically improve the performance of your Dojo application by optimising the JavaScript modules and CSS files. This reduces the … <a href="http://dojotoolkit.org/blog/introducing-the-new-dojo-web-builder">Continue reading <span class="meta-nav">→</span></a>]]></description>
+			<content:encoded><![CDATA[<h2>Background</h2>
+<p><a href="http://dojotoolkit.org/reference-guide/build/">Dojo’s build system</a> has long been considered as one of the toolkit’s most important features. Using the build system will dramatically improve the performance of your Dojo application by optimising the JavaScript modules and CSS files. This reduces the download size and number of HTTP connections needed to load your application. </p>
+<p>Today, The Dojo Toolkit’s build tools are about to improve even further with the launching of a brand new solution, The Dojo Web Builder!</p>
+<p>The Web Builder is an online solution providing an intuitive web interface to the existing build tools, allowing you to create customised Dojo builds using just your web browser and much more. This new tool will dramatically lower the barrier to entry for the build system, easing new users into the process of using a build tool and improving the performance of unoptimised Dojo applications everywhere!</p>
+<p>To start, <a href="http://build.dojotoolkit.org">use the Dojo Web Builder tool</a>, or continue reading for more details. We have produced a number of screencasts showing off the tool’s features and walking you through the steps required for some common example builds:</p>
+<p><iframe src="http://player.vimeo.com/video/21689343" width="400" height="250" frameborder="0"></iframe>
+<p><a href="http://vimeo.com/21689343">Dojo Web Builder – Custom Builds</a> from <a href="http://vimeo.com/dojotoolkit">Dojo Toolkit</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
+<p><iframe src="http://player.vimeo.com/video/21689631" width="400" height="250" frameborder="0"></iframe>
+<p><a href="http://vimeo.com/21689631">Dojo Web Builder – Auto Analysis</a> from <a href="http://vimeo.com/dojotoolkit">Dojo Toolkit</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
+<p><iframe src="http://player.vimeo.com/video/21689724" width="400" height="250" frameborder="0"></iframe>
+<p><a href="http://vimeo.com/21689724">Dojo Web Builder – Advanced Mode</a> from <a href="http://vimeo.com/dojotoolkit">Dojo Toolkit</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
+<h2>Features</h2>
+<ul>
+<li>Browse catalogue of every module in Dojo, Dijit and DojoX, using text searching to quickly filter the entire results. Simply select desired modules to include those in a custom build. Currently serving over eight hundred modules for the 1.6 release.</li>
+<li>Automatically generate custom Dojo builds using our remote service, no need to open terminals and run the intensive build system locally. When the build is complete, it will automatically start the download of the result. Progress indicator keeps you informed of status during a custom build.</li>
+<li>Auto-analyse existing Dojo applications to discover module dependencies. Provide the Web Builder with a remote URL, upload a HTML page, zip archive or an existing build profile to have the tool show you any Dojo Toolkit or custom module dependencies uncovered. Custom builds using the results will automatically include your custom modules.</li>
+<li>Customise builds even further in “Advanced Mode”. Want to include a Dijit theme with compressed CSS? Want to use Google’s Closure compiler for aggressive compression? Want to build multiple application layers? Want to generate builds for the WebKit platform? Need to generate a cross-domain build? Switch to using the Web Builder in “Advanced Mode” to unleash the ability to heavily customise build parameters.</li>
+</ul>
+<h2>Open source</h2>
+<p>The Dojo Web Builder project consists of two new components that were developed:</p>
+<ul>
+<li>Dojo-based web application providing the interface to the build system through a web browser.</li>
+<li>Backend service, allowing existing build system to be controlled through a RESTful interface.</li>
+</ul>
+<p>The entire project will shortly be open-sourced, living on the Dojo Foundation’s Github repository, allowing anyone to contribute to its continuing development. More importantly, other users will be able to run local versions of the tool pointing at their own modules. For example, an organisation might provide an internal version allowing teams to easily generate new custom builds of a project’s modules, without having to distribute the entire project source. In addition,  [...]
+<h2>Conclusion</h2>
+<p>Start using the <a href="http://build.dojotoolkit.org">Dojo Web Builder</a> today. The hosted version is configured to provide access to the custom builds using the latest version of The Dojo Toolkit, 1.6. </p>
+]]></content:encoded>
+			<wfw:commentRss>http://dojotoolkit.org/blog/introducing-the-new-dojo-web-builder/feed</wfw:commentRss>
+		<slash:comments>9</slash:comments>
+		</item>
+		<item>
+		<title>This Week in Dojo: New Tutorials, Mobile Showcase and more</title>
+		<link>http://dojotoolkit.org/blog/this-week-in-dojo</link>
+		<comments>http://dojotoolkit.org/blog/this-week-in-dojo#comments</comments>
+		<pubDate>Mon, 04 Apr 2011 19:43:36 +0000</pubDate>
+		<dc:creator>iTorrey</dc:creator>
+				<category><![CDATA[News]]></category>
+		<category><![CDATA[Uncategorized]]></category>
+
+		<guid isPermaLink="false">http://dojotoolkit.org/blog/?p=183</guid>
+		<description><![CDATA[In the past three weeks SitePen engineers have released a flurry of new tutorials (13 and counting) including two tutorials focused on building Web Apps using Dojo Mobile! Speaking of Dojo Mobile There is now a Dojo Mobile Showcase which … <a href="http://dojotoolkit.org/blog/this-week-in-dojo">Continue reading <span class="meta-nav">→</span></a>]]></description>
+			<content:encoded><![CDATA[<p>In the past three weeks <a href="http://www.sitepen.com">SitePen</a> engineers have released a flurry of new <a href="/documentation">tutorials</a> (13 and counting) including two tutorials focused on building Web Apps using Dojo Mobile!</p>
+<h2>Speaking of Dojo Mobile</h2>
+<p>There is now a <a href="http://chrism.dojotoolkit.org/mobile-0.2/make_samples/dojo-samples/demos/mobile-gallery/demo.html">Dojo Mobile Showcase</a> which shows the various widgets available in Dojo 1.6 and gives a glimpse at what’s coming in Dojo 1.7.</p>
+<h3>Boilerplate</h3>
+<p>Boilerplates are all the rage these days, and sure you can get a sweet HTML5 boilerplate but what about Dojo? Stepping up to the plate is Rebecca Murphy and Colin Snover with their initial release of their <a href="http://blog.rebeccamurphey.com/a-dojo-boilerplate">Dojo 1.6 boilerplate</a>!  </p>
+]]></content:encoded>
+			<wfw:commentRss>http://dojotoolkit.org/blog/this-week-in-dojo/feed</wfw:commentRss>
+		<slash:comments>4</slash:comments>
+		</item>
+		<item>
+		<title>Dojo 1.6 Released!</title>
+		<link>http://dojotoolkit.org/blog/dojo-1-6-released</link>
+		<comments>http://dojotoolkit.org/blog/dojo-1-6-released#comments</comments>
+		<pubDate>Tue, 15 Mar 2011 20:41:19 +0000</pubDate>
+		<dc:creator>Dylan Schiemann</dc:creator>
+				<category><![CDATA[Announcements]]></category>
+		<category><![CDATA[News]]></category>
+
+		<guid isPermaLink="false">http://dojotoolkit.org/blog/?p=159</guid>
+		<description><![CDATA[Now available, and ready for your web app! The Dojo 1.6 release was a substantial undertaking and involves efforts from the largest Dojo team ever. We’re reinventing Dojo for the present and the future, and this release is the first … <a href="http://dojotoolkit.org/blog/dojo-1-6-released">Continue reading <span class="meta-nav">→</span></a>]]></description>
+			<content:encoded><![CDATA[<h2>Now available, and ready for your web app!</h2>
+<p>The <a href="http://dojotoolkit.org/download/">Dojo 1.6 release</a> was a substantial undertaking and involves efforts from the largest Dojo team ever. We’re reinventing Dojo for the present and the future, and this release is the first major step towards our plans for Dojo 2.0. The tremendous efforts and work of the Dojo community has made this release possible, with significant improvements in a short amount of time.</p>
+<p><a class="blueButton" href="http://dojotoolkit.org/download/">Get Dojo</a> </p>
+<h2>What’s New in 1.6?</h2>
+<p>Dojo 1.6 contains a number of great additions and refinements. Key highlights include:</p>
+<ul>
+<li><a href="http://dojotoolkit.org/features/1.6/object-store">Object store: Rethinking data stores in a manner that’s generally easier to work with and more flexible than dojo.data.</a></li>
+<li>LESS Dijit themes: Use the popular LESS CSS framework for simplified theme creation.</li>
+<li><a href="http://dojotoolkit.org/features/1.6/html5data-attributes">HTML5 data attributes: Use data-* attributes instead of custom attributes, so your markup will validate against the HTML5 validator.</a></li>
+<li><a href="http://dojotoolkit.org/features/1.6/widget-watch">Widget watch(): Follow changes to widget attributes with watch().</a></li>
+<li><a href="http://dojotoolkit.org/features/1.6/dojo-websocket">Dojo WebSocket: A simple API for working with WebSockets and other real-time Comet techniques.</a></li>
+<li><a href="http://dojotoolkit.org/features/1.6/async-modules">CommonJS AMD: Dojo now supports the CommonJS AMD format for defining modules.</a></li>
+<li>Charts: The project now contains new Spider and Gantt charts, and support for Canvas text.</li>
+<li>Scene Graph: Dojo Mobile’s scene graph implementation enables powerful replay capabilities.</li>
+<li>Fixes: Many, many improvements to support new browsers including IE9, compatibility with non-browser environments, widget improvements, and shiny polish all around.</li>
+</ul>
+<p>We’ve also made substantial progress on <a href="http://dojotoolkit.org/features/mobile">Dojo Mobile</a>, available now for your mobile web apps!</p>
+<p>Visit the new <a href="http://dojotoolkit.org/features/">Dojo Features</a> section to watch interviews with key Dojo committers and users and learn more about this release, as well as the thousands of outstanding features that have been in Dojo for several years.</p>
+<p><a class="blueButton" href="http://dojotoolkit.org/features/">Learn More</a> </p>
+<h2>Testing and Compatibility</h2>
+<p>In total, we’ve resolved more than 600 issues since Dojo 1.5. The DOH test suite of tens of thousands of tests passes in all officially supported browsers:</p>
+<ul>
+<li>Chrome: 8.x and newer</li>
+<li>Firefox: 3.5.x and 3.6.x</li>
+<li>Internet Explorer: 6, 7, and 8</li>
+<li>Opera: 11.x</li>
+<li>Safari: 4.1.x and 5.0.x</li>
+</ul>
+<p>The code was completed before Internet Explorer 9 and Firefox 4 were released. That said, we’ve fixed all known issues with these browsers as well (testing was done with IE9 RC and Firefox 4 RC1).</p>
+<p>Dojo is also tested with popular mobile browsers including iOS 4.x, Android 2.x and 3.x, and passes for all supported features in Dojo Mobile, and most features throughout Dojo. Work is also near completion for support with Blackberry 6 on mobile phones and the PlayBook.</p>
+<h2>Use Direct from the CDN, or Download</h2>
+<p><a href="http://dojotoolkit.org/download/">Get the Dojo release</a> that’s right for you. Choose from CDN, optimized builds, or source versions with full demos and utilities.</p>
+<p><a class="blueButton" href="http://dojotoolkit.org/download/">Get Dojo</a> </p>
+<h2>Documentation</h2>
+<p>Many improvements have been made to the <a href="http://dojotoolkit.org/documentation/">Dojo documentation</a>. Most notable is a <a href="http://staging.dojotoolkit.org/documentation/">collection of new tutorials</a> on using Dojo 1.6, in addition to the <a href="http://dojotoolkit.org/reference-guide/">reference guide and </a><a href="http://dojotoolkit.org/api/">API documentation</a>.</p>
+<p><a class="blueButton" href="http://dojotoolkit.org/documentation/">Documentation</a> </p>
+<h2>Roadmap</h2>
+<p>Work on Dojo 1.7 is already underway. We’re anticipating releases every 3 months in 2011 as we make progress towards Dojo 2.0! A full roadmap will be available shortly so you’re aware of the latest changes, and to know how to get involved.</p>
+<h2>Release Notes</h2>
+<p>Read the complete <a href="http://dojotoolkit.org/reference-guide/releasenotes/1.6.html">Dojo 1.6 release notes</a> for full details on everything that has changed with Dojo since 1.5.</p>
+<h2>Thanks!</h2>
+<p>And as always, we appreciate your interest and usage. If you find an issue with Dojo, have a suggestion, or see anything on the site or within the documentation that you think should be better, please register for a <a href="http://my.dojofoundation.org/">Dojo Foundation account</a> and <a href="http://bugs.dojotoolkit.org/">open a ticket</a>.</p>
+]]></content:encoded>
+			<wfw:commentRss>http://dojotoolkit.org/blog/dojo-1-6-released/feed</wfw:commentRss>
+		<slash:comments>13</slash:comments>
+		</item>
+		<item>
+		<title>Upcoming Dojo Beer Events</title>
+		<link>http://dojotoolkit.org/blog/upcoming-dojo-beer-events</link>
+		<comments>http://dojotoolkit.org/blog/upcoming-dojo-beer-events#comments</comments>
+		<pubDate>Tue, 22 Feb 2011 13:51:26 +0000</pubDate>
+		<dc:creator>Dylan Schiemann</dc:creator>
+				<category><![CDATA[Events]]></category>
+
+		<guid isPermaLink="false">http://dojotoolkit.org/blog/?p=155</guid>
+		<description><![CDATA[We’re planning the following upcoming Dojo Beer events: February 26: Phoenix, Arizona March 10: London (and if you want to attend QCon, use the discount code DOJO to save £50) April 8: Chicago April 11: Las Vegas Let us know … <a href="http://dojotoolkit.org/blog/upcoming-dojo-beer-events">Continue reading <span class="meta-nav">→</span></a>]]></description>
+			<content:encoded><![CDATA[<p>We’re planning the following upcoming Dojo Beer events:</p>
+<ul>
+<li><a href="http://plancast.com/p/3ild">February 26: Phoenix, Arizona</a></li>
+<li><a href="https://secure.trifork.com/london-2011/freeevent/index.jsp?eventOID=3032">March 10: London</a> (and if you want to <a href="https://secure.trifork.com/london-2011/registration/processConference.jsp">attend QCon</a>, use the discount code DOJO to save £50)</li>
+<li><a href="http://plancast.com/p/3uym">April 8: Chicago</a></li>
+<li><a href="http://plancast.com/p/40x9">April 11: Las Vegas</a></li>
+</ul>
+<p>Let us know if you plan to make it, and we’ll update the details as they become available.</p>
+]]></content:encoded>
+			<wfw:commentRss>http://dojotoolkit.org/blog/upcoming-dojo-beer-events/feed</wfw:commentRss>
+		<slash:comments>2</slash:comments>
+		</item>
+		<item>
+		<title>Dojo 1.6 Beta 1</title>
+		<link>http://dojotoolkit.org/blog/dojo-1-6-beta-1</link>
+		<comments>http://dojotoolkit.org/blog/dojo-1-6-beta-1#comments</comments>
+		<pubDate>Sun, 16 Jan 2011 17:08:43 +0000</pubDate>
+		<dc:creator>Dylan Schiemann</dc:creator>
+				<category><![CDATA[Announcements]]></category>
+
+		<guid isPermaLink="false">http://dojotoolkit.org/blog/?p=146</guid>
+		<description><![CDATA[We’re pleased to announce the first Dojo 1.6 beta. When Dojo 1.6 final is released in February, it will be our first release that includes a number of retrofitted, backwards-compatible, significant changes towards Dojo 2.0. Because there are a number … <a href="http://dojotoolkit.org/blog/dojo-1-6-beta-1">Continue reading <span class="meta-nav">→</span></a>]]></description>
+			<content:encoded><![CDATA[<p>We’re pleased to announce the first <a href="http://download.dojotoolkit.org/release-1.6.0b1/">Dojo 1.6 beta</a>.</p>
+<p>When Dojo 1.6 final is released in February, it will be our first release that includes a number of retrofitted, backwards-compatible, significant changes towards Dojo 2.0.</p>
+<p>Because there are a number of changes in progress, we will also soon release Dojo 1.5.1 which includes just the most important fixes for what has been our most stable and popular release ever.</p>
+<p>Please check out the in draft <a href="http://docs.dojocampus.org/releasenotes/1.6">Dojo 1.6 beta release notes</a> and the list of <a href="http://bugs.dojotoolkit.org/query?milestone=1.6&resolution=fixed">resolved issues</a> for more details. Try it out, and as usual file tickets in <a href="http://bugs.dojotoolkit.org/">http://bugs.dojotoolkit.org/</a>. And if you’re interested in Dojo Mobile, many significant additions and improvements have landed in trunk, with many mo [...]
+<p>Stay tuned in February for the Dojo 1.6 release.</p>
+]]></content:encoded>
+			<wfw:commentRss>http://dojotoolkit.org/blog/dojo-1-6-beta-1/feed</wfw:commentRss>
+		<slash:comments>6</slash:comments>
+		</item>
+		<item>
+		<title>Dojo, Eye-Fi, and CES</title>
+		<link>http://dojotoolkit.org/blog/dojo-eye-fi-and-ces</link>
+		<comments>http://dojotoolkit.org/blog/dojo-eye-fi-and-ces#comments</comments>
+		<pubDate>Mon, 10 Jan 2011 17:35:22 +0000</pubDate>
+		<dc:creator>Dylan Schiemann</dc:creator>
+				<category><![CDATA[News]]></category>
+
+		<guid isPermaLink="false">http://dojotoolkit.org/blog/?p=142</guid>
+		<description><![CDATA[Long-time Dojo user Eye-Fi was at CES in Las Vegas showing our their current wi-fi enabled SD memory card and photo sync services. Here’s a video interview where they show off the camera and application, and discuss the benefits of … <a href="http://dojotoolkit.org/blog/dojo-eye-fi-and-ces">Continue reading <span class="meta-nav">→</span></a>]]></description>
+			<content:encoded><![CDATA[<p>Long-time Dojo user <a href="http://eye.fi/">Eye-Fi</a> was at CES in Las Vegas showing our their current wi-fi enabled SD memory card and photo sync services.</p>
+<p>Here’s a video interview where they show off the camera and application, and discuss the benefits of using Dojo within their platform, as they transitioned from a traditional web app to an AIR-based application:</p>
+<p><object width="640" height="390"><param name="movie" value="http://www.youtube.com/v/MV5XsrvSzMc&hl=en_US&feature=player_embedded&version=3"></param><param name="allowFullScreen" value="true"></param><param name="allowScriptAccess" value="always"></param><embed src="http://www.youtube.com/v/MV5XsrvSzMc&hl=en_US&feature=player_embedded&version=3" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="640" height="390" [...]
+<p>Additional commentary and context is available at TheNextWeb’s post on how to <a href="http://thenextweb.com/gadgets/2011/01/10/upload-pictures-straight-from-your-digital-camera-to-your-social-networks/?awesm=tnw.to_17J8v&utm_content=twitter-publisher-main&utm_medium=tnw.to-twitter&utm_source=direct-tnw.to">Upload pictures straight from your digital camera to your social networks</a>.</p>
+<p>Great work by the Eye-Fi team, in creating an amazing hardware+software platform for simplifying the photo sync process, with the Dojo Toolkit as a key component in that effort!</p>
+]]></content:encoded>
+			<wfw:commentRss>http://dojotoolkit.org/blog/dojo-eye-fi-and-ces/feed</wfw:commentRss>
+		<slash:comments>1</slash:comments>
+		</item>
+	</channel>
+</rss>
diff --git a/dojox/mobile/tests/data/fake_service.php b/dojox/mobile/tests/data/fake_service.php
new file mode 100644
index 0000000..e26e564
--- /dev/null
+++ b/dojox/mobile/tests/data/fake_service.php
@@ -0,0 +1,14 @@
+<?php
+error_reporting(1);
+$count = $_GET['count'] ? $_GET['count'] : 10;
+$start = $_GET['start'] ? $_GET['start'] : 1;
+echo "{items:[\n";
+for ($i = $start; $i < $start + $count; $i++) {
+	echo "{label:'Item #" . $i . "'}";
+	if ($i < $start + $count - 1) {
+		echo ",";
+	}
+	echo "\n";
+}
+echo "]}\n";
+?>
diff --git a/dojox/mobile/tests/fragment1.html b/dojox/mobile/tests/data/fragment1.html
similarity index 100%
rename from dojox/mobile/tests/fragment1.html
rename to dojox/mobile/tests/data/fragment1.html
diff --git a/dojox/mobile/tests/data/fragment2.html b/dojox/mobile/tests/data/fragment2.html
new file mode 100644
index 0000000..fac5f3d
--- /dev/null
+++ b/dojox/mobile/tests/data/fragment2.html
@@ -0,0 +1,4 @@
+<div dojoType="dojox.mobile.RoundRect" shadow="true">
+  <p><img src="images/dojo-logo1.png" align="left" width="60" height="60">
+Dojo saves you time and scales with your development process, using web standards as its platform. It's the toolkit experienced developers turn to for building high quality desktop and mobile web applications.</p>
+</div>
diff --git a/dojox/mobile/tests/data/fragment3.html b/dojox/mobile/tests/data/fragment3.html
new file mode 100644
index 0000000..e4a698c
--- /dev/null
+++ b/dojox/mobile/tests/data/fragment3.html
@@ -0,0 +1,6 @@
+<script>
+    alert("hello");
+</script>
+<div dojoType="dojox.mobile.RoundRect" shadow="true">
+Did you see an alert box? If not, something is wrong.
+</div>
diff --git a/dojox/mobile/tests/data/fragment4.html b/dojox/mobile/tests/data/fragment4.html
new file mode 100644
index 0000000..0bb77bf
--- /dev/null
+++ b/dojox/mobile/tests/data/fragment4.html
@@ -0,0 +1,4 @@
+<div dojoType="dojox.mobile.RoundRect" shadow="true">
+  <p><img src="images/tab-icon-33h.png" align="left" width="60" height="60">
+Dojo Mobile is a world class HTML5 mobile JavaScript framework that enables rapid development of mobile web applications with a native look and feel on modern webkit-enabled mobile devices.</p>
+</div>
diff --git a/dojox/mobile/tests/data/fruits.json b/dojox/mobile/tests/data/fruits.json
new file mode 100644
index 0000000..7bd7af7
--- /dev/null
+++ b/dojox/mobile/tests/data/fruits.json
@@ -0,0 +1,13 @@
+{
+	items: [
+		{label: "Apple"},
+		{label: "Banana"},
+		{label: "Cherry"},
+		{label: "Grape"},
+		{label: "Kiwi"},
+		{label: "Lemon"},
+		{label: "Melon"},
+		{label: "Orange"},
+		{label: "Peach"}
+	]
+}
diff --git a/dojox/mobile/tests/insurance-car-coverage.html b/dojox/mobile/tests/data/insurance-car-coverage.html
similarity index 100%
rename from dojox/mobile/tests/insurance-car-coverage.html
rename to dojox/mobile/tests/data/insurance-car-coverage.html
diff --git a/dojox/mobile/tests/insurance-car-safe.html b/dojox/mobile/tests/data/insurance-car-safe.html
similarity index 100%
rename from dojox/mobile/tests/insurance-car-safe.html
rename to dojox/mobile/tests/data/insurance-car-safe.html
diff --git a/dojox/mobile/tests/data/insurance-car.json b/dojox/mobile/tests/data/insurance-car.json
new file mode 100644
index 0000000..7c435fa
--- /dev/null
+++ b/dojox/mobile/tests/data/insurance-car.json
@@ -0,0 +1,6 @@
+{
+  "items" : [
+    { label: "Coverage Options", icon: "images/i-icon-1.png", url: "data/insurance-car-coverage.html" },
+    { label: "Safe Driving Bonus", icon: "images/i-icon-1.png", url: "data/insurance-car-safe.html" }
+  ]
+}
diff --git a/dojox/mobile/tests/insurance-life-child.html b/dojox/mobile/tests/data/insurance-life-child.html
similarity index 100%
rename from dojox/mobile/tests/insurance-life-child.html
rename to dojox/mobile/tests/data/insurance-life-child.html
diff --git a/dojox/mobile/tests/insurance-life-long.html b/dojox/mobile/tests/data/insurance-life-long.html
similarity index 100%
rename from dojox/mobile/tests/insurance-life-long.html
rename to dojox/mobile/tests/data/insurance-life-long.html
diff --git a/dojox/mobile/tests/data/insurance-life.json b/dojox/mobile/tests/data/insurance-life.json
new file mode 100644
index 0000000..162bcaa
--- /dev/null
+++ b/dojox/mobile/tests/data/insurance-life.json
@@ -0,0 +1,6 @@
+{
+  "items" : [
+    { label: "Long Term Care", icon: "images/i-icon-2.png", url: "data/insurance-life-long.html" },
+    { label: "Child's Education", icon: "images/i-icon-2.png", url: "data/insurance-life-child.html" }
+  ]
+}
diff --git a/dojox/mobile/tests/insurance-sports-boat.html b/dojox/mobile/tests/data/insurance-sports-boat.html
similarity index 100%
rename from dojox/mobile/tests/insurance-sports-boat.html
rename to dojox/mobile/tests/data/insurance-sports-boat.html
diff --git a/dojox/mobile/tests/insurance-sports-moto.html b/dojox/mobile/tests/data/insurance-sports-moto.html
similarity index 100%
rename from dojox/mobile/tests/insurance-sports-moto.html
rename to dojox/mobile/tests/data/insurance-sports-moto.html
diff --git a/dojox/mobile/tests/insurance-sports-snow.html b/dojox/mobile/tests/data/insurance-sports-snow.html
similarity index 100%
rename from dojox/mobile/tests/insurance-sports-snow.html
rename to dojox/mobile/tests/data/insurance-sports-snow.html
diff --git a/dojox/mobile/tests/data/insurance-sports.json b/dojox/mobile/tests/data/insurance-sports.json
new file mode 100644
index 0000000..692a853
--- /dev/null
+++ b/dojox/mobile/tests/data/insurance-sports.json
@@ -0,0 +1,7 @@
+{
+  "items" : [
+    { label: "Motorcycle", icon: "images/i-icon-10.png", url: "data/insurance-sports-moto.html" },
+    { label: "Snowmobile", icon: "images/i-icon-10.png", url: "data/insurance-sports-snow.html" },
+    { label: "Boat", icon: "images/i-icon-10.png", url: "data/insurance-sports-boat.html" }
+  ]
+}
diff --git a/dojox/mobile/tests/data/insurance.json b/dojox/mobile/tests/data/insurance.json
new file mode 100644
index 0000000..b974c89
--- /dev/null
+++ b/dojox/mobile/tests/data/insurance.json
@@ -0,0 +1,7 @@
+{
+  "items" : [
+    { label: "Car Insurance", id: "CarInsurance", icon: "images/tab-icon-11h.png", data: "data/insurance-car.json", moveTo: "#" },
+    { label: "Life Insurance", id: "LifeInsurance", icon: "images/tab-icon-15h.png", data: "data/insurance-life.json", moveTo: "#" },
+    { label: "Sports Insurance", id: "SportsInsurance", icon: "images/tab-icon-10h.png", data: "data/insurance-sports.json", moveTo: "#" }
+  ]
+}
diff --git a/dojox/mobile/tests/data/settings-itemMap.json b/dojox/mobile/tests/data/settings-itemMap.json
new file mode 100644
index 0000000..aa34414
--- /dev/null
+++ b/dojox/mobile/tests/data/settings-itemMap.json
@@ -0,0 +1,14 @@
+{
+  "items" : [
+    { "text" : "Wi-Fi",                        "profile_image_url" : "images/i-icon-1.png",   "moveTo": "wifi"                              },
+    { "text" : "Brightness & Wallpaper",       "profile_image_url" : "images/i-icon-2.png",   "moveTo": "bright"                            },
+    { "text" : "Picture Frame",                "profile_image_url" : "images/i-icon-3.png",   "moveTo": "picture"                           },
+    { "text" : "General",                      "profile_image_url" : "images/i-icon-4.png",   "moveTo": "general",  "selected": "true"      },
+    { "text" : "Mail, Contacts, Calendars",    "profile_image_url" : "images/i-icon-5.png",   "moveTo": "wifi"                              },
+    { "text" : "Safari",                       "profile_image_url" : "images/i-icon-6.png",   "moveTo": "bright"                            },
+    { "text" : "iPod",                         "profile_image_url" : "images/i-icon-7.png",   "moveTo": "picture"                           },
+    { "text" : "Video",                        "profile_image_url" : "images/i-icon-8.png",   "moveTo": "general"                           },
+    { "text" : "Photos",                       "profile_image_url" : "images/i-icon-9.png",   "moveTo": "wifi"                              },
+    { "text" : "Store",                        "profile_image_url" : "images/i-icon-10.png",  "moveTo": "bright"                            }
+  ]
+}
diff --git a/dojox/mobile/tests/settings.json b/dojox/mobile/tests/data/settings.json
similarity index 100%
rename from dojox/mobile/tests/settings.json
rename to dojox/mobile/tests/data/settings.json
diff --git a/dojox/mobile/tests/data/simple1.html b/dojox/mobile/tests/data/simple1.html
new file mode 100644
index 0000000..fb057f0
--- /dev/null
+++ b/dojox/mobile/tests/data/simple1.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Simple HTML</title>
+</head>
+<body>
+	Hello<br>
+	Hello<br>
+	Hello<br>
+	Hello<br>
+	Hello<br>
+	Hello<br>
+	Hello<br>
+	Hello<br>
+	Hello<br>
+	Hello<br>
+	Hello<br>
+	Hello<br>
+</body>
+</html>
diff --git a/dojox/mobile/tests/data/view-sample.html b/dojox/mobile/tests/data/view-sample.html
new file mode 100644
index 0000000..f6fe936
--- /dev/null
+++ b/dojox/mobile/tests/data/view-sample.html
@@ -0,0 +1,38 @@
+<div id="bar" dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="view1">View Sample</h1>
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+			1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+			Sarah Connor Hardcover<br>
+			Eligible for FREE Super Saver Shipping<br>
+			<font color="red">$14.50 (50%)</font> In Stock<br>
+			# (531)
+		</li>
+		<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+			2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+			Martin Parker Hardcover<br>
+			<font color="red">$14.00 (60%)</font> In Stock<br>
+			# (173)
+		</li>
+		<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+			3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+			Steven Young Hardcover<br>
+			Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
+			Eligible for FREE Super Saver Shipping<br>
+			<font color="red">$9.50 (62%)</font> In Stock<br>
+			# (1199)
+		</li>
+		<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+			4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+			Marco Rodriguez Hardcover<br>
+			<font color="blue">Not Available</font>
+		</li>
+		<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+			5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+			Melissa Morgan Hardcover<br>
+			Eligible for FREE Super Saver Shipping<br>
+			<font color="red">$12.00 (60%)</font> In Stock<br>
+			# (1847)
+		</li>
+	</ul>
+</div>
diff --git a/dojox/mobile/tests/data/view1.html b/dojox/mobile/tests/data/view1.html
new file mode 100644
index 0000000..bb6ab80
--- /dev/null
+++ b/dojox/mobile/tests/data/view1.html
@@ -0,0 +1,14 @@
+<div id="view1" dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home">view1.html</h1>
+	<ul dojoType="dojox.mobile.EdgeToEdgeList">
+		<li dojoType="dojox.mobile.ListItem">
+			Jack Coleman
+		</li>
+		<li dojoType="dojox.mobile.ListItem">
+			James Evans
+		</li>
+		<li dojoType="dojox.mobile.ListItem">
+			Jason Griffin
+		</li>
+	</ul>
+</div>
diff --git a/dojox/mobile/tests/data/view1.json b/dojox/mobile/tests/data/view1.json
new file mode 100644
index 0000000..c1b8fe5
--- /dev/null
+++ b/dojox/mobile/tests/data/view1.json
@@ -0,0 +1,19 @@
+{
+  "dojox.mobile.View": {
+    "@id": "view1",
+    "dojox.mobile.Heading": {
+      "@back": "Home",
+      "@moveTo": "home",
+      "@label": "view1.json"
+    },
+    "dojox.mobile.EdgeToEdgeList": {
+      "dojox.mobile.ListItem": [{
+        "@label": "Jack Coleman"
+      }, {
+        "@label": "James Evans"
+      }, {
+        "@label": "Jason Griffin"
+      }]
+    }
+  }
+}
diff --git a/dojox/mobile/tests/data/view2.html b/dojox/mobile/tests/data/view2.html
new file mode 100644
index 0000000..ef84147
--- /dev/null
+++ b/dojox/mobile/tests/data/view2.html
@@ -0,0 +1,9 @@
+<div id="view2" dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home" label="view2.html"></h1>
+	<h2 dojoType="dojox.mobile.RoundRectCategory" label="Transition Effects"></h2>
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="home" transition="slide" label="Slide"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="home" transition="flip" label="Flip"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="home" transition="fade" label="Fade"></li>
+	</ul>
+</div>
diff --git a/dojox/mobile/tests/data/view2.json b/dojox/mobile/tests/data/view2.json
new file mode 100644
index 0000000..926f5dd
--- /dev/null
+++ b/dojox/mobile/tests/data/view2.json
@@ -0,0 +1,32 @@
+{
+  "dojox.mobile.View": {
+    "@id": "view2",
+    "dojox.mobile.Heading": {
+      "@back": "Home",
+      "@label": "view2.json",
+      "@moveTo": "home"
+    },
+    "dojox.mobile.RoundRectCategory": {
+      "@label": "Transition Effects"
+    },
+    "dojox.mobile.RoundRectList": {
+      "dojox.mobile.ListItem": [{
+        "@icon": "images/i-icon-1.png",
+        "@label": "Slide",
+        "@moveTo": "home",
+        "@transition": "slide"
+      }, {
+        "@icon": "images/i-icon-2.png",
+        "@label": "Flip",
+        "@moveTo": "home",
+        "@transition": "flip"
+      }, {
+        "@icon": "images/i-icon-3.png",
+        "@label": "Fade",
+        "@moveTo": "home",
+        "@transition": "fade"
+      }]
+    }
+  }
+}
+
diff --git a/dojox/mobile/tests/data/view3.html b/dojox/mobile/tests/data/view3.html
new file mode 100644
index 0000000..dce8d44
--- /dev/null
+++ b/dojox/mobile/tests/data/view3.html
@@ -0,0 +1,17 @@
+<div id="view3" dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" label="view3.html"></h1>
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
+			Airplane Mode
+			<div dojoType="dojox.mobile.Switch"></div>
+		</li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="mac" href="test_iPhone-Icon.html" label="Wi-Fi"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="AcmePhone" moveTo="home" label="Carrier"></li>
+	</ul>
+
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="home" label="Sounds"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="home" label="Brightness"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="home" label="Wallpaper"></li>
+	</ul>
+</div>
diff --git a/dojox/mobile/tests/data/view3.json b/dojox/mobile/tests/data/view3.json
new file mode 100644
index 0000000..e8dc72e
--- /dev/null
+++ b/dojox/mobile/tests/data/view3.json
@@ -0,0 +1,41 @@
+{
+  "dojox.mobile.View": {
+    "@id": "view3",
+    "dojox.mobile.Heading": {
+      "@label": "view3.json"
+    },
+    "dojox.mobile.RoundRectList": [{
+      "dojox.mobile.ListItem": [{
+        "@icon": "images/i-icon-1.png",
+        "@label": "Airplane Mode",
+        "dojox.mobile.Switch": {
+        }
+      }, {
+        "@href": "test_iPhone-Icon.html",
+        "@icon": "images/i-icon-2.png",
+        "@label": "Wi-Fi",
+        "@rightText": "mac"
+      }, {
+        "@icon": "images/i-icon-3.png",
+        "@label": "Carrier",
+        "@moveTo": "home",
+        "@rightText": "AcmePhone"
+      }]
+    }, {
+      "dojox.mobile.ListItem": [{
+        "@icon": "images/i-icon-4.png",
+        "@label": "Sounds",
+        "@moveTo": "home"
+      }, {
+        "@icon": "images/i-icon-5.png",
+        "@label": "Brightness",
+        "@moveTo": "home"
+      }, {
+        "@icon": "images/i-icon-6.png",
+        "@label": "Wallpaper",
+        "@moveTo": "home"
+      }]
+    }]
+  }
+}
+
diff --git a/dojox/mobile/tests/data/view4.html b/dojox/mobile/tests/data/view4.html
new file mode 100644
index 0000000..beee1b9
--- /dev/null
+++ b/dojox/mobile/tests/data/view4.html
@@ -0,0 +1,17 @@
+<div id="view4" dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home" label="view4.html"></h1>
+
+	<h2 dojoType="dojox.mobile.RoundRectCategory" label="Category 1"></h2>
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="home" transition="slide" label="Item 1"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="home" transition="flip" label="Item 2"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="home" transition="fade" label="Item 3"></li>
+	</ul>
+
+	<h2 dojoType="dojox.mobile.RoundRectCategory" label="Category 2"></h2>
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="home" transition="slide" label="Item 1"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="home" transition="flip" label="Item 2"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="home" transition="fade" label="Item 3"></li>
+	</ul>
+</div>
diff --git a/dojox/mobile/tests/data/view4.json b/dojox/mobile/tests/data/view4.json
new file mode 100644
index 0000000..834857c
--- /dev/null
+++ b/dojox/mobile/tests/data/view4.json
@@ -0,0 +1,78 @@
+{
+  "class": "dojox.mobile.View",
+  "@id": "view4",
+  "children": [
+
+    {
+      "class": "dojox.mobile.Heading",
+      "@back": "Home",
+      "@moveTo": "home",
+      "@label": "view4.json"
+    },
+
+    {
+      "class": "dojox.mobile.RoundRectCategory",
+      "@label": "Category 1"
+    },
+
+    {
+      "class": "dojox.mobile.RoundRectList",
+      "children": [
+        {
+          "class": "dojox.mobile.ListItem",
+          "@icon": "images/i-icon-1.png",
+          "@moveTo": "home",
+          "@transition": "slide",
+          "@label": "Item 1"
+        },
+        {
+          "class": "dojox.mobile.ListItem",
+          "@icon": "images/i-icon-2.png",
+          "@moveTo": "home",
+          "@transition": "flip",
+          "@label": "Item 2"
+        },
+        {
+          "class": "dojox.mobile.ListItem",
+          "@icon": "images/i-icon-3.png",
+          "@moveTo": "home",
+          "@transition": "fade",
+          "@label": "Item 3"
+        }
+      ]
+    },
+
+    {
+      "class": "dojox.mobile.RoundRectCategory",
+      "@label": "Category 2"
+    },
+
+    {
+      "class": "dojox.mobile.RoundRectList",
+      "children": [
+        {
+          "class": "dojox.mobile.ListItem",
+          "@icon": "images/i-icon-1.png",
+          "@moveTo": "home",
+          "@transition": "slide",
+          "@label": "Item 1"
+        },
+        {
+          "class": "dojox.mobile.ListItem",
+          "@icon": "images/i-icon-2.png",
+          "@moveTo": "home",
+          "@transition": "flip",
+          "@label": "Item 2"
+        },
+        {
+          "class": "dojox.mobile.ListItem",
+          "@icon": "images/i-icon-3.png",
+          "@moveTo": "home",
+          "@transition": "fade",
+          "@label": "Item 3"
+        }
+      ]
+    }
+
+  ]
+}
diff --git a/dojox/mobile/tests/data/view5.html b/dojox/mobile/tests/data/view5.html
new file mode 100644
index 0000000..354e85b
--- /dev/null
+++ b/dojox/mobile/tests/data/view5.html
@@ -0,0 +1,7 @@
+<div id="view5" dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home" label="view5.html"></h1>
+	<div id="spin1" data-dojo-type="dojox.mobile.SpinWheel" style="margin:10px auto;width:304px">
+		<div data-dojo-type="dojox.mobile.SpinWheelSlot" labels="A,B,C,D,E"
+			style="text-align:center;width:300px;"></div>
+	</div>
+</div>
diff --git a/dojox/mobile/tests/data/view5.json b/dojox/mobile/tests/data/view5.json
new file mode 100644
index 0000000..2ab9798
--- /dev/null
+++ b/dojox/mobile/tests/data/view5.json
@@ -0,0 +1,26 @@
+{
+  "class": "dojox.mobile.View",
+  "@id": "view5",
+  "children": [
+
+    {
+      "class": "dojox.mobile.Heading",
+      "@back": "Home",
+      "@moveTo": "home",
+      "@label": "view5.json"
+    },
+
+    {
+      "class": "dojox.mobile.SpinWheel",
+      "@id": "spin1",
+      "@style": {"margin":"10px auto","width":"304px"},
+      "children": [
+        {
+          "class": "dojox.mobile.SpinWheelSlot",
+          "@labels": "A,B,C,D,E",
+	  "@style": {"textAlign":"center","width":"300px"}
+        }
+      ]
+    }
+  ]
+}
diff --git a/dojox/mobile/tests/dialogApp/index.html b/dojox/mobile/tests/dialogApp/index.html
index 4b4fc90..f1cfc45 100644
--- a/dojox/mobile/tests/dialogApp/index.html
+++ b/dojox/mobile/tests/dialogApp/index.html
@@ -12,7 +12,7 @@
                 text-decoration: none;
             }
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false"></script>
     
 		<script language="JavaScript" type="text/javascript">
 			dojo.require("dojox.mobile.app");
diff --git a/dojox/mobile/tests/doh/Button.html b/dojox/mobile/tests/doh/Button.html
deleted file mode 100644
index 3259830..0000000
--- a/dojox/mobile/tests/doh/Button.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Button</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-		<style>
-		.redButton {
-			border-color: #cc3333;
-			background-image: url(../images/red-button-bg.png);
-			background: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
-		}
-		.redButtonSelected {
-			background-image: url(../images/red-button-sel-bg.png);
-			background: -webkit-gradient(linear, left top, left bottom, from(#AF333C), to(#880E17), color-stop(0.5, #952B33), color-stop(0.5, #870F18));
-		}
-		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.Button");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-	        dojo.require("doh.runner");
-
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.Button", [
-					function test_Button_Verification(){
-						var demoWidget = dijit.byId("btn1");
-						doh.assertEqual('mblButton mblBlueButton', demoWidget.domNode.className);
-						doh.assertEqual('Default Button', demoWidget.domNode.childNodes[0].nodeValue);
-						demoWidget = dijit.byId("btn2");
-						doh.assertEqual('mblButton redButton', demoWidget.domNode.className);
-						doh.assertEqual('Custom Button', demoWidget.domNode.childNodes[0].nodeValue);
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body style="padding: 20px;visibility:visible">
-		<button id="btn1" dojoType="dojox.mobile.Button" class="mblBlueButton" style="width:120px">Default Button</button>
-		<p></p>
-		<button id="btn2" dojoType="dojox.mobile.Button" class="redButton" style="width:120px">Custom Button</button>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/Button_Programmatic.html b/dojox/mobile/tests/doh/Button_Programmatic.html
deleted file mode 100644
index 20b4c5a..0000000
--- a/dojox/mobile/tests/doh/Button_Programmatic.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Button</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-		<style>
-		.redButton {
-			border-color: #cc3333;
-			background-image: url(../images/red-button-bg.png);
-			background: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
-		}
-		.redButtonSelected {
-			background-image: url(../images/red-button-sel-bg.png);
-			background: -webkit-gradient(linear, left top, left bottom, from(#AF333C), to(#880E17), color-stop(0.5, #952B33), color-stop(0.5, #870F18));
-		}
-		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.Button");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-	        dojo.require("doh.runner");
-
-			dojo.addOnLoad(function(){
-				var demoWidget = new dojox.mobile.Button({"class":"mblBlueButton", style:"width:120px", label:"Default Button"});
-				dojo.doc.body.appendChild(demoWidget.domNode);
-
-				var child = dojo.create("P", null, dojo.doc.body);
-
-				demoWidget = new dojox.mobile.Button({"class":"redButton", style:"width:120px", label:"Custom Button"});
-				dojo.doc.body.appendChild(demoWidget.domNode);
-
-				doh.register("dojox.mobile.test.doh.Button", [
-					function test_Button_Verification(){
-						var demoWidget = dijit.byId("dojox_mobile_Button_0");
-						doh.assertEqual('mblButton mblBlueButton', demoWidget.domNode.className);
-						doh.assertEqual('Default Button', demoWidget.domNode.childNodes[0].nodeValue);
-						demoWidget = dijit.byId("dojox_mobile_Button_1");
-						doh.assertEqual('mblButton redButton', demoWidget.domNode.className);
-						doh.assertEqual('Custom Button', demoWidget.domNode.childNodes[0].nodeValue);
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body style="padding: 20px;visibility:visible">
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/CreateListItem2_Programmatic.js b/dojox/mobile/tests/doh/CreateListItem2_Programmatic.js
deleted file mode 100644
index 72f0b9d..0000000
--- a/dojox/mobile/tests/doh/CreateListItem2_Programmatic.js
+++ /dev/null
@@ -1,21 +0,0 @@
-dojo.addOnLoad(function(){
-	var view = dijit.byId("foo");
-
-	var list = new dojox.mobile.RoundRectList({iconBase:"../images/i-icon-all.png"});
-	view.addChild(list);
-
-	var demoWidget = new dojox.mobile.ListItem({iconPos:"0,87,29,29", moveTo:"general", label:"Sounds"});
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({iconPos:"0,116,29,29", moveTo:"general", label:"Brightness"});
-	list.addChild(demoWidget);
-
-	list = new dojox.mobile.EdgeToEdgeList({iconBase:"../images/i-icon-all.png"});
-	demoWidget = new dojox.mobile.ListItem({iconPos:"0,87,29,29", btnClass:"mblDomButtonBluePlus", label:"XX Widget"});
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({iconPos:"0,116,29,29", btnClass:"mblDomButtonRedMinus", label:"YY Widget"});
-	list.addChild(demoWidget);
-
-	view.addChild(list);
-});
diff --git a/dojox/mobile/tests/doh/CreateListItem_Programmatic.js b/dojox/mobile/tests/doh/CreateListItem_Programmatic.js
deleted file mode 100644
index 153ed5c..0000000
--- a/dojox/mobile/tests/doh/CreateListItem_Programmatic.js
+++ /dev/null
@@ -1,50 +0,0 @@
-dojo.addOnLoad(function(){
-	var list = dijit.byId("dojox_mobile_RoundRectList_0");
-	var demoWidget = new dojox.mobile.ListItem({icon:"../images/i-icon-1.png", transition:"slide", url:"../view1.html", label:"External View #1 (sync)"});
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({icon:"../images/i-icon-2.png", transition:"flip", url:"../view2.html", sync:false, label:"External View #2 (async)"});
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({icon:"../images/i-icon-3.png", transition:"fade", url:"../view3.html", label:"External View #3 (sync)"});
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({rightText:"Off", label:"Video"});
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({icon:"../images/i-icon-1.png", rightText:"VPN", label:"Maps"});
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({label:"Jack Coleman"});
-	list.addChild(demoWidget);
-
-	list = dijit.byId("dojox_mobile_RoundRectList_1");
-	demoWidget = new dojox.mobile.ListItem({iconPos:"0,87,29,29", moveTo:"general", label:"Sounds"});
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({iconPos:"0,116,29,29", moveTo:"general", label:"Brightness"});
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({iconPos:"29,0,29,29", moveTo:"general", label:"Wallpaper"});
-	list.addChild(demoWidget);
-
-	list = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
-	demoWidget = new dojox.mobile.ListItem({icon:"../images/i-icon-1.png", btnClass:"mblDomButtonBluePlus", label:"XX Widget"});
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({icon:"../images/i-icon-2.png", btnClass:"mblDomButtonRedMinus", label:"YY Widget"});
-	list.addChild(demoWidget);
-
-	list = dijit.byId("dojox_mobile_EdgeToEdgeList_1");
-	demoWidget = new dojox.mobile.ListItem({btnClass:"mblDomButtonCheckboxOff", label:"Use wireless networks", variableHeight:"true"});
-	var child = dojo.create("DIV", {className:"mblListItemSubText"}, demoWidget.domNode.childNodes[0].childNodes[4]);
-	child.appendChild(dojo.doc.createTextNode("See location in applications (such as Maps) using wireless networks"));
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({btnClass:"mblDomButtonCheckboxOn", label:"Use GPS satellites", variableHeight:"true"});
-	child = dojo.create("DIV", {className:"mblListItemSubText", innerHTML:"When locating, accurate to street level (uncheck to conserve battery)"}, demoWidget.domNode.childNodes[0].childNodes[4]);
-	list.addChild(demoWidget);
-
-	demoWidget = new dojox.mobile.ListItem({label:" Set unlock pattern"});
-	list.addChild(demoWidget);
-});
diff --git a/dojox/mobile/tests/doh/CustomListItem.js b/dojox/mobile/tests/doh/CustomListItem.js
new file mode 100644
index 0000000..1b48ed1
--- /dev/null
+++ b/dojox/mobile/tests/doh/CustomListItem.js
@@ -0,0 +1,5 @@
+define(["dojo/_base/declare", "dojox/mobile/ListItem"], function(declare, ListItem){
+	return declare(ListItem, {
+		customProp: true
+	});
+})
\ No newline at end of file
diff --git a/dojox/mobile/tests/doh/DataListTests.js b/dojox/mobile/tests/doh/DataListTests.js
new file mode 100644
index 0000000..9eefeb3
--- /dev/null
+++ b/dojox/mobile/tests/doh/DataListTests.js
@@ -0,0 +1,106 @@
+var fruits11, fruits12, fruits13, fruits21, fruits22, fruits23;
+
+require([
+	"dojo/_base/lang", //dojo.clone
+	"dojo/data/ItemFileWriteStore", // dojo.data.ItemFileWriteStore
+	"dojo/dom-construct", // dojo.place
+	"dojo/ready", // dojo.ready
+	"dijit/registry",  // dijit.byId
+	"doh/runner",	//doh functions
+	"dojox/mobile/EdgeToEdgeDataList",
+	"dojox/mobile/RoundRectDataList",
+	"dojox/mobile",				// This is a mobile app.
+	"dojox/mobile/View",		// This mobile app uses mobile view
+	"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+	"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+], function(lang, ItemFileWriteStore, domConst, ready, registry, runner, EdgeToEdgeDataList, RoundRectDataList){
+
+	var CLASS_NAME;
+	var DataList;
+	var testName;
+
+	if(IsEdgeToEdgeList){
+		CLASS_NAME = "mblEdgeToEdgeList";
+		DataList = EdgeToEdgeDataList;
+		testName = "dojox.mobile.test.doh.EdgeToEdgeDataListTests";
+	}else{
+		CLASS_NAME = "mblRoundRectList";
+		DataList = RoundRectDataList;
+		testName = "dojox.mobile.test.doh.RoundRectDataListTests";
+	}
+	var fruitsData = { 
+		items:[ 
+			{label:"Apple",		moveTo:"dummy"},
+			{label:"Banana", 	moveTo:"dummy"},
+			{label:"Cherry", 	moveTo:"dummy"}
+		]};
+					
+	fruits11 = new ItemFileWriteStore({data:lang.clone(fruitsData)});
+	fruits12 = new ItemFileWriteStore({data:lang.clone(fruitsData)});
+	fruits13 = new ItemFileWriteStore({data:lang.clone(fruitsData)});
+	fruits21 = new ItemFileWriteStore({data:lang.clone(fruitsData)});
+	fruits22 = new ItemFileWriteStore({data:lang.clone(fruitsData)});
+	fruits23 = new ItemFileWriteStore({data:lang.clone(fruitsData)});
+			
+	function _createDataListDeclaratively(id) {
+		return registry.byId(id);
+	};
+	
+	function _createDataListProgrammatically(fruits, placeHolderId){
+		var widget = new DataList({store:fruits, query:{label:"*"}});
+		runner.assertNotEqual(null, widget);
+		domConst.place(widget.domNode, placeHolderId, "replace");
+		widget.startup();
+		return widget;
+	};
+	
+	function _createDataListProgrammaticallyWithSourceNodeReference(fruits, id){
+		var widget = new DataList({store:fruits, query:{label:"*"}}, id);
+		widget.startup();
+		return widget;
+	};
+
+	function _assertCorrectDataList(fruits, dataList){
+		runner.assertNotEqual(null, dataList);
+		
+		runner.assertEqual(CLASS_NAME, dataList.domNode.className, dataList.toString());
+		runner.assertEqual(fruitsData.items.length, dataList.domNode.children.length, "length id=" + dataList.domNode.id);
+		
+		var item = fruits.newItem({label: "Date", moveTo: "dummy"});
+		runner.assertEqual(fruits._arrayOfTopLevelItems.length, dataList.domNode.children.length, "new length id=" + dataList.domNode.id);
+		
+		fruits.deleteItem(item);
+		runner.assertEqual(fruits._arrayOfTopLevelItems.length, dataList.domNode.children.length, "delete length id=" + dataList.domNode.id);
+	};
+	
+	function _showView2(){
+		var view1 = registry.byId("view1");
+		view1.performTransition("view2", 1, "none");
+	};
+
+	ready(function(){
+		runner.register(testName, [
+			function testInView1(){
+				var dataList1 = _createDataListDeclaratively("view1-dataList1");
+				var dataList2 = _createDataListProgrammatically(fruits12, "view1-dataList2");
+				var dataList3 = _createDataListProgrammaticallyWithSourceNodeReference(fruits13, "view1-dataList3");
+		
+				_assertCorrectDataList(fruits11, dataList1);
+				_assertCorrectDataList(fruits12, dataList2);
+				_assertCorrectDataList(fruits13, dataList3);
+			},
+			function testInView2(){
+				var dataList1 = _createDataListDeclaratively("view2-dataList1");
+				var dataList2 = _createDataListProgrammatically(fruits22, "view2-dataList2");
+				var dataList3 = _createDataListProgrammaticallyWithSourceNodeReference(fruits23, "view2-dataList3");
+				
+				_showView2();
+				
+				_assertCorrectDataList(fruits21, dataList1);
+				_assertCorrectDataList(fruits22, dataList2);
+				_assertCorrectDataList(fruits23, dataList3);
+			}
+		]);
+		runner.run();
+	});
+})
diff --git a/dojox/mobile/tests/doh/EdgeToEdgeCatagory.js b/dojox/mobile/tests/doh/EdgeToEdgeCatagory.js
deleted file mode 100644
index 5e22ade..0000000
--- a/dojox/mobile/tests/doh/EdgeToEdgeCatagory.js
+++ /dev/null
@@ -1,71 +0,0 @@
-dojo.addOnLoad(function(){
-	doh.register("dojox.mobile.test.doh.EdgeToEdgeList", [
-		{
-			name: "EdgeToEdgeList Verification",
-			timeout: 4000,
-			runTest: function(){
-				var d = new doh.Deferred();
-				setTimeout(d.getTestCallback(function(){
-					var demoWidget = dijit.byId("Category");
-					doh.assertEqual('mblEdgeToEdgeCategory', demoWidget.domNode.className);
-					doh.assertEqual('Spaces', demoWidget.domNode.innerHTML);
-
-
-					demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
-					doh.assertEqual('mblEdgeToEdgeList', demoWidget.domNode.className);
-					verifyListItem("item1", 'u1space', 'Off', "mblDomButtonArrow", true, true, false);
-					verifyListItem("item2", 'u2space', 'On', "mblDomButtonArrow", true, true, false);
-					verifyListItem("item3", 'Wi-Fi', 'Off', "mblDomButtonArrow", false, true, false);
-					
-				}));
-				return d;
-			}
-		},
-		{
-			name: "EdgeToEdgeList Verification2",
-			timeout: 1000,
-			runTest: function(){
-				var d = new doh.Deferred();
-				var demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
-				demoWidget.set({transition :"flip"});
-				doh.assertEqual("flip", demoWidget.get("transition"));
-				demoWidget.set({transition :"fade"});
-				doh.assertEqual("fade", demoWidget.get("transition"));
-
-				fireOnClick("item3");
-				var view = dijit.byId("foo");
-				dojo.connect(view, "onAfterTransitionOut", this, d.getTestCallback(function(){
-					var demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeCategory_0");
-					doh.assertEqual('mblEdgeToEdgeCategory', demoWidget.domNode.className);
-					doh.assertEqual('Applications', demoWidget.domNode.innerHTML);
-
-					demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_1");
-					doh.assertEqual('mblEdgeToEdgeList', demoWidget.domNode.className);
-
-					verifyListItem("dojox_mobile_ListItem_0", 'Video', 'Off', "", false, false, false);
-					verifyListItem("dojox_mobile_ListItem_1", 'Maps', 'VPN', "", true, false, false);
-					verifyListItem("dojox_mobile_ListItem_2", 'Phone Number', 'Off', "", false, false, false);
-				}));
-				return d;
-			}
-		},
-		{
-			name: "EdgeToEdgeCategory getLabel",
-			timeout: 1000,
-			runTest: function(){
-				doh.assertEqual("Spaces", dijit.byId("Category").get("label")); 
-			}
-		},
-		{
-			name: "EdgeToEdgeCategory setLabel",
-			timeout: 1000,
-			runTest: function(){
-				var demoWidget = dijit.byId("Category");
-				demoWidget.set({label :"Value Changed"});
-				doh.assertEqual("Value Changed", demoWidget.get("label"));
-				doh.assertEqual('Value Changed', demoWidget.domNode.innerHTML);
-			}
-		}
-	]);
-	doh.run();
-});
diff --git a/dojox/mobile/tests/doh/EdgeToEdgeCategory.html b/dojox/mobile/tests/doh/EdgeToEdgeCategory.html
deleted file mode 100644
index 0c02ea4..0000000
--- a/dojox/mobile/tests/doh/EdgeToEdgeCategory.html
+++ /dev/null
@@ -1,41 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Edge To Edge List</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-//			dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script type="text/javascript" src="EdgeToEdgeCatagory.js"></script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
-			<h2 id="Category" dojoType="dojox.mobile.EdgeToEdgeCategory">Spaces</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li id="item1" dojoType="dojox.mobile.ListItem" icon="../images/i-icon-1.png" rightText="Off" moveTo="bar">u1space</li>
-				<li id="item2" dojoType="dojox.mobile.ListItem" icon="../images/i-icon-2.png" rightText="On" moveTo="bar">u2space</li>
-				<li id="item3" dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="bar">Wi-Fi</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="foo">u1space</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Applications</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">Video</li>
-				<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-1.png" rightText="VPN">Maps</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">Phone Number</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/EdgeToEdgeDataList.html b/dojox/mobile/tests/doh/EdgeToEdgeDataList.html
deleted file mode 100644
index 3eb6635..0000000
--- a/dojox/mobile/tests/doh/EdgeToEdgeDataList.html
+++ /dev/null
@@ -1,155 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>EdgeToEdgeDataList</title>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.data.ItemFileWriteStore");
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.EdgeToEdgeDataList");
-
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-	        dojo.require("doh.runner");
-
-			var static_data = { 
-				items: [ 
-					{label: "Apple", 	moveTo: "dummy"},
-					{label: "Banana", 	moveTo: "dummy"},
-					{label: "Cherry", 	moveTo: "dummy"},
-					{label: "Grape", 	moveTo: "dummy"},
-					{label: "Kiwi", 	moveTo: "dummy"},
-					{label: "Lemon", 	moveTo: "dummy"},
-					{label: "Melon", 	moveTo: "dummy"},
-					{label: "Orange", 	moveTo: "dummy"},
-					{label: "Peach", 	moveTo: "dummy"}
-				]
-			};
-			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
-			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
-			var store = store1;
-			var newItems = [[],[]];
-
-			// switch to the selected store
-			function switchTo(store){
-				window.store = store;
-				dijit.byId("list").setStore(store);
-			}
-			// add a new item
-			function add1(){
-				var item = store.newItem({label: "New Item", moveTo: "dummy"});
-				this.newItems[(store == store1) ? 1 : 0].push(item);
-			}
-			// delete the added item
-			function delete1(){
-				var item = this.newItems[(store == store1) ? 1 : 0].pop();
-				if(item){
-					store.deleteItem(item);
-				}
-			}
-
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.EdgeToEdgeDataList", [
-					{
-						name: "EdgeToEdgeDataList Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_ListItem_0");
-								doh.assertEqual('mblListItem', demoWidget.domNode.className);
-								doh.assertEqual('mblListItemIcon', demoWidget.domNode.childNodes[0].className);
-								doh.assertTrue(demoWidget.domNode.childNodes[0].src.search(/i-icon-1.png/i) != -1);
-								doh.assertEqual('mblListItemAnchor', demoWidget.domNode.childNodes[1].className);
-								doh.assertEqual('mblListItemTextBox', demoWidget.domNode.childNodes[1].childNodes[0].className);
-								doh.assertEqual('Wi-Fi', demoWidget.domNode.childNodes[1].childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblDomButtonArrow mblRightButton mblDomButton', demoWidget.domNode.childNodes[1].childNodes[1].className);
-
-								demoWidget = dijit.byId("dojox_mobile_ListItem_3");
-								doh.assertEqual('mblListItem mblItemSelected', demoWidget.domNode.className);
-								doh.assertEqual('mblListItemIcon', demoWidget.domNode.childNodes[0].className);
-								doh.assertTrue(demoWidget.domNode.childNodes[0].src.search(/i-icon-4.png/i) != -1);
-								doh.assertEqual('mblListItemAnchor', demoWidget.domNode.childNodes[1].className);
-								doh.assertEqual('mblListItemTextBox', demoWidget.domNode.childNodes[1].childNodes[0].className);
-								doh.assertEqual('General', demoWidget.domNode.childNodes[1].childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblDomButtonArrow mblRightButton mblDomButton', demoWidget.domNode.childNodes[1].childNodes[1].className);
-								
-							}),500);
-							return d;
-						}
-					},
-					{
-						name: "EdgeToEdgeDataList Verification2",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-
-								add1();
-								add1();
-								add1();
-								var demoWidget = dijit.byId("dojox_mobile_ListItem_12");
-								doh.assertEqual('mblListItem', demoWidget.domNode.className);
-								doh.assertEqual('mblListItemAnchor mblListItemAnchorNoIcon', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblListItemTextBox', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('New Item', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblDomButtonArrow mblRightButton mblDomButton', demoWidget.domNode.childNodes[0].childNodes[1].className);
-
-								delete1();
-								demoWidget = dijit.byId("dojox_mobile_ListItem_12");
-								doh.assertTrue(!demoWidget);
-
-								demoWidget = dijit.byId("dojox_mobile_ListItem_11");
-								doh.assertEqual('mblListItem', demoWidget.domNode.className);
-								doh.assertEqual('mblListItemAnchor mblListItemAnchorNoIcon', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblListItemTextBox', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('New Item', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblDomButtonArrow mblRightButton mblDomButton', demoWidget.domNode.childNodes[0].childNodes[1].className);
-							}),1500);
-							return d;
-						}
-					},
-					{
-						name: "EdgeToEdgeDataList Verification2",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-
-								switchTo(store2);
-								var demoWidget = dijit.byId("dojox_mobile_ListItem_13");
-								doh.assertEqual('mblListItem', demoWidget.domNode.className);
-								doh.assertEqual('mblListItemAnchor mblListItemAnchorNoIcon', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblListItemTextBox', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('Apple', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblDomButtonArrow mblRightButton mblDomButton', demoWidget.domNode.childNodes[0].childNodes[1].className);
-
-
-							}),2500);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">EdgeToEdgeDataList</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeDataList" id="list" store="store" query="{label: '*'}"></ul>
-			<h1 dojoType="dojox.mobile.Heading">EdgeToEdgeDataList</h1>
-			<p>show the different set:<br>
-			<input type="button" value="Set1" onclick="switchTo(store1)">
-			<input type="button" value="Set2" onclick="switchTo(store2)">
-			<p>alter the object store:<br>
-			<input type="button" value="Add" onclick="add1()">
-			<input type="button" value="Delete" onclick="delete1()">
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/EdgeToEdgeDataList_Programmatic.html b/dojox/mobile/tests/doh/EdgeToEdgeDataList_Programmatic.html
deleted file mode 100644
index 1e50f44..0000000
--- a/dojox/mobile/tests/doh/EdgeToEdgeDataList_Programmatic.html
+++ /dev/null
@@ -1,157 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>EdgeToEdgeDataList</title>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.data.ItemFileWriteStore");
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.EdgeToEdgeDataList");
-
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-	        dojo.require("doh.runner");
-
-			var static_data = { 
-				items: [ 
-					{label: "Apple", 	moveTo: "dummy"},
-					{label: "Banana", 	moveTo: "dummy"},
-					{label: "Cherry", 	moveTo: "dummy"},
-					{label: "Grape", 	moveTo: "dummy"},
-					{label: "Kiwi", 	moveTo: "dummy"},
-					{label: "Lemon", 	moveTo: "dummy"},
-					{label: "Melon", 	moveTo: "dummy"},
-					{label: "Orange", 	moveTo: "dummy"},
-					{label: "Peach", 	moveTo: "dummy"}
-				]
-			};
-			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
-			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
-			var store = store1;
-			var newItems = [[],[]];
-
-			// switch to the selected store
-			function switchTo(store){
-				window.store = store;
-				dijit.byId("list").setStore(store);
-			}
-			// add a new item
-			function add1(){
-				var item = store.newItem({label: "New Item", moveTo: "dummy"});
-				this.newItems[(store == store1) ? 1 : 0].push(item);
-			}
-			// delete the added item
-			function delete1(){
-				var item = this.newItems[(store == store1) ? 1 : 0].pop();
-				if(item){
-					store.deleteItem(item);
-				}
-			}
-
-			dojo.addOnLoad(function(){
-				var view = dijit.byId("foo");
-				var demoWidget = new dojox.mobile.EdgeToEdgeDataList({id:"list", store:store, query:{label: '*'}});
-				view.addChild(demoWidget);
-
-				doh.register("dojox.mobile.test.doh.EdgeToEdgeDataList", [
-					{
-						name: "EdgeToEdgeDataList Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_ListItem_0");
-								doh.assertEqual('mblListItem', demoWidget.domNode.className);
-								doh.assertEqual('mblListItemIcon', demoWidget.domNode.childNodes[0].className);
-								doh.assertTrue(demoWidget.domNode.childNodes[0].src.search(/i-icon-1.png/i) != -1);
-								doh.assertEqual('mblListItemAnchor', demoWidget.domNode.childNodes[1].className);
-								doh.assertEqual('mblListItemTextBox', demoWidget.domNode.childNodes[1].childNodes[0].className);
-								doh.assertEqual('Wi-Fi', demoWidget.domNode.childNodes[1].childNodes[0].innerHTML);
-								doh.assertEqual('mblArrow', demoWidget.domNode.childNodes[1].childNodes[1].className);
-
-								demoWidget = dijit.byId("dojox_mobile_ListItem_3");
-								doh.assertEqual('mblListItem mblItemSelected', demoWidget.domNode.className);
-								doh.assertEqual('mblListItemIcon', demoWidget.domNode.childNodes[0].className);
-								doh.assertTrue(demoWidget.domNode.childNodes[0].src.search(/i-icon-4.png/i) != -1);
-								doh.assertEqual('mblListItemAnchor', demoWidget.domNode.childNodes[1].className);
-								doh.assertEqual('mblListItemTextBox', demoWidget.domNode.childNodes[1].childNodes[0].className);
-								doh.assertEqual('General', demoWidget.domNode.childNodes[1].childNodes[0].innerHTML);
-								doh.assertEqual('mblArrow', demoWidget.domNode.childNodes[1].childNodes[1].className);
-								
-							}),500);
-							return d;
-						}
-					},
-					{
-						name: "EdgeToEdgeDataList Verification2",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-
-								add1();
-								add1();
-								add1();
-								var demoWidget = dijit.byId("dojox_mobile_ListItem_12");
-								doh.assertEqual('mblListItem', demoWidget.domNode.className);
-								doh.assertEqual('mblListItemAnchor mblListItemAnchorNoIcon', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblListItemTextBox', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('New Item', demoWidget.domNode.childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblArrow', demoWidget.domNode.childNodes[0].childNodes[1].className);
-
-								delete1();
-								demoWidget = dijit.byId("dojox_mobile_ListItem_12");
-								doh.assertTrue(!demoWidget);
-
-								demoWidget = dijit.byId("dojox_mobile_ListItem_11");
-								doh.assertEqual('mblListItem', demoWidget.domNode.className);
-								doh.assertEqual('mblListItemAnchor mblListItemAnchorNoIcon', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblListItemTextBox', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('New Item', demoWidget.domNode.childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblArrow', demoWidget.domNode.childNodes[0].childNodes[1].className);
-							}),1500);
-							return d;
-						}
-					},
-					{
-						name: "EdgeToEdgeDataList Verification2",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-
-								switchTo(store2);
-								var demoWidget = dijit.byId("dojox_mobile_ListItem_13");
-								doh.assertEqual('mblListItem', demoWidget.domNode.className);
-								doh.assertEqual('mblListItemAnchor mblListItemAnchorNoIcon', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblListItemTextBox', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('Apple', demoWidget.domNode.childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblArrow', demoWidget.domNode.childNodes[0].childNodes[1].className);
-
-
-							}),2500);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">EdgeToEdgeDataList</h1>
-			<p>show the different set:<br>
-			<input type="button" value="Set1" onclick="switchTo(store1)">
-			<input type="button" value="Set2" onclick="switchTo(store2)">
-			<p>alter the object store:<br>
-			<input type="button" value="Add" onclick="add1()">
-			<input type="button" value="Delete" onclick="delete1()">
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/HTML5-attribute-compliance.html b/dojox/mobile/tests/doh/HTML5-attribute-compliance.html
new file mode 100644
index 0000000..91adee5
--- /dev/null
+++ b/dojox/mobile/tests/doh/HTML5-attribute-compliance.html
@@ -0,0 +1,197 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>HTML5 Attribute Compliance</title>
+
+	<!-- DOH test for the changes introduced for HTML5 compliance 
+		of attributes (#16188) -->
+	
+	<script type="text/javascript" src="../../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"doh/runner",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/SwapView",
+			"dojox/mobile/Carousel",
+			"dojox/mobile/CarouselItem"
+		], function(dom, domClass, ready, registry, runner){
+			
+			ready(function(){
+				doh.register("dojox/mobile/test.doh.HTML5compliance", [
+					function testInView1(){
+						// Check support for "fixed" attribute on widgets
+						var view = registry.byId("view1");
+						var header = registry.byId("fixedTop1");
+						var footer = registry.byId("fixedBottom1");
+						runner.assertTrue(view.fixedHeader == header.domNode, "wrong header");
+						runner.assertTrue(view.fixedFooter == footer.domNode, "wrong footer");
+					},
+					function testInView2(){
+						// Check support for "fixed" attribute on HTML elements
+						var view = registry.byId("view2");
+						var header = dom.byId("fixedTop2");
+						var footer = dom.byId("fixedBottom2");
+						runner.assertTrue(view.fixedHeader == header, "wrong header");
+						runner.assertTrue(view.fixedFooter == footer, "wrong footer");
+					},
+					function testInView3(){
+						// Check support for "data-mobile-fixed" attribute on widgets (new in Dojo 1.9)
+						var view = registry.byId("view3");
+						var header = registry.byId("fixedTop3");
+						var footer = registry.byId("fixedBottom3");
+						runner.assertTrue(view.fixedHeader == header.domNode, "wrong header");
+						runner.assertTrue(view.fixedFooter == footer.domNode, "wrong footer");
+					},
+					function testInView4(){
+						// Check support for "data-mobile-fixed" attribute on HTML elements (new in Dojo 1.9)
+						var view = registry.byId("view4");
+						var header = dom.byId("fixedTop4");
+						var footer = dom.byId("fixedBottom4");
+						runner.assertTrue(view.fixedHeader == header, "wrong header");
+						runner.assertTrue(view.fixedFooter == footer, "wrong footer");
+					},
+					function testInView5(){
+						// Check support for "lazy":
+						// - as attribute (legacy), or
+						// - in data-dojo-props (new in Dojo 1.9);
+						var swapview = registry.byId("swapview1");
+						runner.assertTrue(!!swapview._instantiated, 
+							"wrong instanciation of swapview1 (not lazy)");
+						swapview = registry.byId("swapview2");
+						runner.assertFalse(!!swapview._instantiated, 
+							"wrong instanciation of swapview2 (lazy attribute)");
+						swapview = registry.byId("swapview3");
+						runner.assertFalse(!!swapview._instantiated, 
+							"wrong instanciation of swapview3 (lazy in data-dojo-props)");
+					},
+					function testInView6(){
+						// Check support for "layout" / "data-mobile-layout" attributes 
+						// on ListItem children:
+						// - "layout" (legacy), or
+						// - "data-mobile-layout" (new in Dojo 1.9);
+						
+						var child = dom.byId("listItemChild1"); // left
+						runner.assertTrue(domClass.contains(child, "mblListItemLayoutLeft"), "layout - Left");
+						child = dom.byId("listItemChild2"); // center
+						runner.assertTrue(domClass.contains(child, "mblListItemLayoutCenter"), "layout - Center");
+						child = dom.byId("listItemChild3"); // center
+						runner.assertTrue(domClass.contains(child, "mblListItemLayoutRight"), "layout - Right");
+						
+						child = dom.byId("listItemChild4"); // left
+						runner.assertTrue(domClass.contains(child, "mblListItemLayoutLeft"), "data-mobile-layout - Left");
+						child = dom.byId("listItemChild5"); // center
+						runner.assertTrue(domClass.contains(child, "mblListItemLayoutCenter"), "data-mobile-layout - Center");
+						child = dom.byId("listItemChild6"); // center
+						runner.assertTrue(domClass.contains(child, "mblListItemLayoutRight"), "data-mobile-layout - Right");
+					}
+				]);
+				runner.run();
+			});
+		})
+	</script>
+
+</head>
+<body>
+	<!-- 1. "fixed" / "data-mobile-fixed" attribute for view header/footer --> 
+	
+	<!-- Using fixed as attribute (legacy) on widgets -->
+	<div id="view1" data-dojo-type="dojox/mobile/ScrollableView">
+		<!-- "fixed" attribute on widgets -->
+		<h1 id="fixedTop1" data-dojo-type="dojox/mobile/Heading" 
+			fixed="top">Top 1</h1>
+		<h1 id="fixedBottom1" data-dojo-type="dojox/mobile/Heading" 
+			fixed="bottom">Bottom 1</h1>
+	</div>
+	
+	<!-- Using fixed as attribute (legacy) on HTML elements -->
+	<div id="view2" data-dojo-type="dojox/mobile/ScrollableView">
+		<!-- "fixed" attribute on HTML elements -->
+		<h1 id="fixedTop2" fixed="top">Top 2</h1>
+		<h1 id="fixedBottom2" fixed="bottom">Bottom 2</h1>
+	</div>
+	
+	<!-- Using data-mobile-fixed as attribute (new in Dojo 1.9) on widgets -->
+	<div id="view3" data-dojo-type="dojox/mobile/ScrollableView">
+		<!-- "data-mobilefixed" attribute on widgets -->
+		<h1 id="fixedTop3" data-dojo-type="dojox/mobile/Heading" 
+			data-mobile-fixed="top">Top 1</h1>
+		<h1 id="fixedBottom3" data-dojo-type="dojox/mobile/Heading" 
+			data-mobile-fixed="bottom">Bottom 1</h1>
+	</div>
+	
+	<!-- Using data-mobile fixed as attribute (new in Dojo 1.9) on HTML elements -->
+	<div id="view4" data-dojo-type="dojox/mobile/ScrollableView">
+		<!-- "data-mobile-fixed" attribute on HTML elements -->
+		<h1 id="fixedTop4" data-mobile-fixed="top">Top 2</h1>
+		<h1 id="fixedBottom4" data-mobile-fixed="bottom">Bottom 2</h1>
+	</div>	
+	
+	<!-- 2. "lazy" / "data-mobile-lazy" attribute for Carusel's children --> 
+	
+	<div id="view5" data-dojo-type="dojox/mobile/View">
+		<div id="carousel1" data-dojo-type="dojox/mobile/Carousel"
+			data-dojo-props='height:"150px", navButton:true, numVisible:2, title:"Category"'>
+
+			<div id="swapview1" data-dojo-type="dojox/mobile/SwapView">
+				<div data-dojo-type="dojox/mobile/CarouselItem"
+					data-dojo-props='src:"../images/dish1.jpg", value:"dish1", headerText:"dish1"'></div>
+				<div data-dojo-type="dojox/mobile/CarouselItem"
+					data-dojo-props='src:"../images/dish2.jpg", value:"dish2", headerText:"dish2"'></div>
+			</div>
+
+			<!-- Using lazy as attribute (legacy) --> 
+			<div id="swapview2" data-dojo-type="dojox/mobile/SwapView" lazy="true">
+				<div data-dojo-type="dojox/mobile/CarouselItem"
+					data-dojo-props='src:"../images/dish3.jpg", value:"dish3", headerText:"dish3"'></div>
+				<div data-dojo-type="dojox/mobile/CarouselItem"
+					data-dojo-props='src:"../images/dish4.jpg", value:"dish4", headerText:"dish4"'></div>
+			</div>
+			
+			<!-- Using lazy in data-dojo-props (new in Dojo 1.9) --> 
+			<div id="swapview3" data-dojo-type="dojox/mobile/SwapView" data-dojo-props="lazy:'true'">
+				<div data-dojo-type="dojox/mobile/CarouselItem"
+					data-dojo-props='src:"../images/dish5.jpg", value:"dish5", headerText:"dish5"'></div>
+				<div data-dojo-type="dojox/mobile/CarouselItem"
+					data-dojo-props='src:"../images/dish6.jpg", value:"dish6", headerText:"dish6"'></div>
+			</div>
+		</div>
+	</div>
+
+	<div id="view6" data-dojo-type="dojox/mobile/View">
+		<ul data-dojo-type="dojox/mobile/RoundRectList">
+			<li data-dojo-type="dojox/mobile/ListItem">
+				<div id="listItemChild1" layout="left"><div>Left</div></div>
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem">
+				<div id="listItemChild2" layout="center">Center</div>
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem">
+				<div id="listItemChild3" layout="right">Right</div>
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem">
+				<div id="listItemChild4" data-mobile-layout="left">Left</div>
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem">
+				<div id="listItemChild5" data-mobile-layout="center">Center</div>
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem">
+				<div id="listItemChild6" data-mobile-layout="right">Right</div>
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/Heading.html b/dojox/mobile/tests/doh/Heading.html
deleted file mode 100644
index 7b15059..0000000
--- a/dojox/mobile/tests/doh/Heading.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Heading</title>
-		<link href="../../themes/android/base.css" rel="stylesheet">
-		<link href="../../themes/common/domButtons.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-	        dojo.require("doh.runner");
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.Heading1", [
-					{
-						name: "Heading Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_Heading_0");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-								doh.assertEqual('General', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-
-								demoWidget = dijit.byId("dojox_mobile_Heading_1");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-								doh.assertEqual('Very Very Long Title May Not Be Displayed in the Narrow Space', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-								
-								demoWidget = dijit.byId("dojox_mobile_Heading_2");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-								doh.assertEqual('World Clock', demoWidget.domNode.childNodes[0].childNodes[0].nodeValue);
-
-								demoWidget = dijit.byId("dojox_mobile_Heading_3");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-							}));
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div id="general" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">General</h1>
-			<h1 dojoType="dojox.mobile.Heading" back="Long Button" moveTo="settings">Very Very Long Title May Not Be Displayed in the Narrow Space</h1>
-		</div>
-
-		<h1 dojoType="dojox.mobile.Heading" label="World Clock"></h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButtonWhitePlus" style="float:right;"></div>Alarm Clock</h1><br>
-
-
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/Heading2.html b/dojox/mobile/tests/doh/Heading2.html
deleted file mode 100644
index 966ac43..0000000
--- a/dojox/mobile/tests/doh/Heading2.html
+++ /dev/null
@@ -1,166 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Heading</title>
-		<link href="../../themes/android/base.css" rel="stylesheet">
-		<link href="../../themes/common/domButtons.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.Heading2", [
-					{
-						name: "Heading Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_Heading_0");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-								doh.assertEqual('General', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('Settings', demoWidget.domNode.childNodes[0].childNodes[1].innerHTML);
-
-								demoWidget = dijit.byId("dojox_mobile_Heading_1");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-								doh.assertEqual('Test', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('Go To', demoWidget.domNode.childNodes[0].childNodes[1].innerHTML);
-
-								demoWidget = dijit.byId("dojox_mobile_Heading_2");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-								doh.assertEqual('Test', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('Settings', demoWidget.domNode.childNodes[0].childNodes[1].innerHTML);
-
-								demoWidget = dijit.byId("dojox_mobile_Heading_3");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-								doh.assertEqual('Very Very Long Title May Not Be Displayed in the Narrow Space', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('3', demoWidget.domNode.childNodes.length);
-								doh.assertEqual('Long Button', demoWidget.domNode.childNodes[0].childNodes[1].innerHTML);
-							}));
-							return d;
-						}
-					},
-					{
-						name: "Set",
-						timeout: 1000,
-						runTest: function(){
-							var demoWidget = dijit.byId("dojox_mobile_Heading_2");
-							demoWidget.set({back:"Value Changed", label:"Value Changed", moveTo:"bar", transition:"flip"});
-							doh.assertEqual("Value Changed", demoWidget.get("label"));
-							doh.assertEqual("Value Changed", demoWidget.get("back"));
-							doh.assertEqual("bar", demoWidget.get("moveTo"));
-							doh.assertEqual("flip", demoWidget.get("transition"));
-							doh.assertEqual('Value Changed', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-							doh.assertEqual('Value Changed', demoWidget.domNode.childNodes[0].childNodes[1].innerHTML);
-
-							demoWidget = dijit.byId("dojox_mobile_Heading_5");
-							demoWidget.set({transition:"fade"});
-							doh.assertEqual("fade", demoWidget.get("transition"));
-						}
-					},
-					{
-						name: "moveTo",
-						timeout: 1000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var demoWidget = dijit.byId("dojox_mobile_Heading_2");
-							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[1]);
-							setTimeout(d.getTestCallback(function(){
-
-								var demoWidget = dijit.byId("bar");
-								doh.assertEqual('visible', demoWidget.domNode.style.visibility);
-							}));
-							return d;
-						}
-					},
-					{
-						name: "moveTo",
-						timeout: 1000,
-						runTest: function(){
-							setTimeout(function(){
-								var d = new doh.Deferred();
-								var demoWidget = dijit.byId("dojox_mobile_Heading_5");
-								fireOnClick(demoWidget.domNode.childNodes[0].childNodes[1]);
-								setTimeout(d.getTestCallback(function(){
-									var demoWidget = dijit.byId("general");
-									doh.assertEqual('visible', demoWidget.domNode.style.visibility);
-								}));
-								return d;
-							},1500);
-						}
-/*					},
-					{
-						name: "moveTo",
-						timeout: 1000,
-						runTest: function(){
-							var demoWidget = dijit.byId("dojox_mobile_Heading_1");
-							demoWidget.set({href:"about:blank"});
-							doh.assertEqual("about:blank", demoWidget.get("href"));
-
-							var d = new doh.Deferred();
-							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[1]);
-							setTimeout(d.getTestCallback(function(){
-							}));
-							return d;
-						}
-*/
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div id="general" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="foo">General</h1>
-			<h1 dojoType="dojox.mobile.Heading" back="Go To" href="http://dojotoolkit.org/">Test</h1>
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="foo">Test</h1>
-			<h1 dojoType="dojox.mobile.Heading" back="Long Button" moveTo="bar">Very Very Long Title May Not Be Displayed in the Narrow Space</h1>
-		</div>
-
-		<div id="foo" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="item1" dojoType="dojox.mobile.ListItem" icon="../images/a-icon-10.png" rightText="Off" moveTo="general">
-					u1space
-				</li>
-				<li id="item2" dojoType="dojox.mobile.ListItem" icon="../images/a-icon-11.png" rightText="Off" moveTo="general">
-					u2space
-				</li>
-				<li id="item3" dojoType="dojox.mobile.ListItem" icon="../images/a-icon-12.png" rightText="Off" moveTo="general">
-					Wi-Fi
-				</li>
-				<li id="item4" dojoType="dojox.mobile.ListItem" icon="../images/a-icon-13.png" rightText="VPN" moveTo="general">
-					VPN
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="general">u1space</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">
-					Video
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="../images/a-icon-2.png" rightText="VPN">
-					Maps
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">
-					Phone Number
-				</li>
-			</ul>
-		</div>
-
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/Heading2_Programmatic.html b/dojox/mobile/tests/doh/Heading2_Programmatic.html
deleted file mode 100644
index 3a9e1d3..0000000
--- a/dojox/mobile/tests/doh/Heading2_Programmatic.html
+++ /dev/null
@@ -1,164 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Heading</title>
-		<link href="../../themes/android/android.css" rel="stylesheet">
-		<link href="../../themes/common/domButtons.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				var view = dijit.byId("general");
-				var demoWidget = new dojox.mobile.Heading({back:"Settings", moveTo:"foo", label:"General"});
-				view.addChild(demoWidget);
-
-				demoWidget = new dojox.mobile.Heading({back:"Go To", href:"http://dojotoolkit.org/", label:"Test"});
-				view.addChild(demoWidget);
-
-				demoWidget = new dojox.mobile.Heading({back:"Settings", moveTo:"foo", label:"Test"});
-				view.addChild(demoWidget);
-
-				demoWidget = new dojox.mobile.Heading();
-				demoWidget.set({back:"Long Button", moveTo:"bar", label:"Very Very Long Title May Not Be Displayed in the Narrow Space"});
-				view.addChild(demoWidget);
-			});
-		</script>
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.Heading2", [
-					{
-						name: "Heading Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_Heading_0");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-								doh.assertEqual('General', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('Settings', demoWidget.domNode.childNodes[0].childNodes[1].innerHTML);
-
-								demoWidget = dijit.byId("dojox_mobile_Heading_1");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-								doh.assertEqual('Test', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('Go To', demoWidget.domNode.childNodes[0].childNodes[1].innerHTML);
-
-								demoWidget = dijit.byId("dojox_mobile_Heading_2");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-								doh.assertEqual('Test', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('Settings', demoWidget.domNode.childNodes[0].childNodes[1].innerHTML);
-
-								demoWidget = dijit.byId("dojox_mobile_Heading_3");
-								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-								doh.assertEqual('3', demoWidget.domNode.childNodes.length);
-								doh.assertEqual('Very Very Long Title May Not Be Displayed in the Narrow Space', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('Long Button', demoWidget.domNode.childNodes[0].childNodes[1].innerHTML);
-							}));
-							return d;
-						}
-					},
-					{
-						name: "Set",
-						timeout: 1000,
-						runTest: function(){
-							var demoWidget = dijit.byId("dojox_mobile_Heading_2");
-							demoWidget.set({back:"Value Changed", label:"Value Changed", moveTo:"bar", transition:"flip"});
-							doh.assertEqual("Value Changed", demoWidget.get("label"));
-							doh.assertEqual("Value Changed", demoWidget.get("back"));
-							doh.assertEqual("bar", demoWidget.get("moveTo"));
-							doh.assertEqual("flip", demoWidget.get("transition"));
-							doh.assertEqual('Value Changed', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-							doh.assertEqual('Value Changed', demoWidget.domNode.childNodes[0].childNodes[1].innerHTML);
-
-							demoWidget = dijit.byId("dojox_mobile_Heading_5");
-							demoWidget.set({transition:"fade"});
-							doh.assertEqual("fade", demoWidget.get("transition"));
-						}
-					},
-					{
-						name: "moveTo",
-						timeout: 1000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var demoWidget = dijit.byId("dojox_mobile_Heading_2");
-							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[1]);
-
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("bar");
-								doh.assertEqual('visible', demoWidget.domNode.style.visibility);
-							}));
-							return d;
-						}
-					},
-					{
-						name: "moveTo",
-						timeout: 1000,
-						runTest: function(){
-							setTimeout(function(){
-								var d = new doh.Deferred();
-								var demoWidget = dijit.byId("dojox_mobile_Heading_5");
-								fireOnClick(demoWidget.domNode.childNodes[0].childNodes[1]);
-
-								setTimeout(d.getTestCallback(function(){
-									var demoWidget = dijit.byId("general");
-									doh.assertEqual('visible', demoWidget.domNode.style.visibility);
-								}));
-								return d;
-							},1500);
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div id="general" dojoType="dojox.mobile.View" selected="true">
-		</div>
-
-		<div id="foo" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" id="dojox_mobile_Heading_4">Mobile Mashup</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="item1" dojoType="dojox.mobile.ListItem" icon="../images/a-icon-10.png" rightText="Off" moveTo="general">
-					u1space
-				</li>
-				<li id="item2" dojoType="dojox.mobile.ListItem" icon="../images/a-icon-11.png" rightText="Off" moveTo="general">
-					u2space
-				</li>
-				<li id="item3" dojoType="dojox.mobile.ListItem" icon="../images/a-icon-12.png" rightText="Off" moveTo="general">
-					Wi-Fi
-				</li>
-				<li id="item4" dojoType="dojox.mobile.ListItem" icon="../images/a-icon-13.png" rightText="VPN" moveTo="general">
-					VPN
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="general" id="dojox_mobile_Heading_5">u1space</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">
-					Video
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="../images/a-icon-2.png" rightText="VPN">
-					Maps
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">
-					Phone Number
-				</li>
-			</ul>
-		</div>
-
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/HeadingFixedBarsTests.html b/dojox/mobile/tests/doh/HeadingFixedBarsTests.html
new file mode 100644
index 0000000..9242a48
--- /dev/null
+++ b/dojox/mobile/tests/doh/HeadingFixedBarsTests.html
@@ -0,0 +1,116 @@
+<!DOCTYPE HTML>
+	<html>
+	        <head>
+	        <title>App and View Fixed Bars</title>
+	        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	        <meta name="viewport"
+	                content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+	        <meta name="apple-mobile-web-app-capable" content="yes" />
+	        <script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js"></script>
+	        <script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, async:true, mblFixedBarSupportForViews: true"></script>
+	        <script type="text/javascript" charset="utf-8">
+	                require([
+	                         "dojo/ready",
+ 							 "dijit/registry",  // dijit.byId
+							 "doh/runner",	//doh functions
+							 "dojo/dom",
+	                         "dojo/dom-style",
+	                         "dojox/mobile/parser",
+	                         "dojox/mobile",
+	                         "dojox/mobile/ScrollableView",
+	                         "dojox/mobile/Heading",
+	                         "dojox/mobile/ToolBarButton"], function(ready, registry, runner, dom, domStyle) {
+	                	
+	                	var populateView = function(view, headerLabel, previousViewId, nextViewId) {
+	                		var header, footer, previousButton, NextButton;
+	                		header = new dojox.mobile.Heading({id: view.domNode.id + "Header", label: headerLabel, fixed: 'top'});
+	                		if (previousViewId) {
+		                		previousButton = new dojox.mobile.ToolBarButton({label: 'Previous', arrow: 'left', transitionDir: -1, moveTo: previousViewId});
+		                		header.addChild(previousButton);
+	                		}
+	                		if (nextViewId) {
+		                		nextButton = new dojox.mobile.ToolBarButton({label: 'Next', arrow: 'right', moveTo: nextViewId});
+		                		domStyle.set(nextButton.domNode, "float", "right");
+		                		header.addChild(nextButton);
+	                		}
+ 	                		if (view.addFixedBar) {
+		                		view.addFixedBar(header);
+	                		} else {
+		                		view.addChild(header);	                			
+ 	                		}
+	                		footer = new dojox.mobile.Heading({id: view.domNode.id + "Footer", label: 'status ' + view.domNode.id, fixed: 'bottom'});
+ 	                		if (view.addFixedBar) {
+		                		view.addFixedBar(footer);
+	                		} else {
+		                		view.addChild(footer);	                			
+ 	                		}
+	                	}
+	                	
+	                	ready(function() {
+	                		
+	                		// Create views programmaticaly
+   	                		var view = new dojox.mobile.ScrollableView({}, "view3");
+	                		populateView(view, "Programmatic ScrollableView", "view2");
+	                		view.startup();
+	                		
+	                		// Test suite
+	     					runner.register("dojox.mobile.test.doh.HeadingFixedBarsTests", [
+           						{
+           							name: "Verify ticket #16681 is fixed",
+           							timeout: 10000,
+           							setUp: function() {
+	    								this.data = {runner: runner,
+	    											 dom: dom,
+	    										     appHeader: dom.byId("appHeader"),
+	    										     appFooter: dom.byId("appFooter"),
+	    										     view2Header: dom.byId("view2Header"),
+	    										     view2Footer: dom.byId("view2Footer")
+	    										    };
+           							},
+           							runTest: function(){
+           								var d = new runner.Deferred();
+           								// verify view2 layout
+										runner.assertEqual(0, this.data.appHeader.offsetTop);
+										runner.assertEqual(0, this.data.view2Header.offsetTop);
+										runner.assertTrue(this.data.view2Footer.offsetTop > this.data.view2Header.offsetHeight);
+										runner.assertTrue(this.data.appFooter.offsetTop == this.data.view2Footer.offsetTop + this.data.view2Footer.offsetHeight + this.data.view2Header.offsetHeight);
+										// click the transition button
+           								// verify there is no padding top on the second view
+           								registry.byId("rightButton")._onClick({});
+	           							setTimeout(d.getTestCallback(function(){
+										    var view3Header = this.fixture.data.dom.byId("view3Header");
+										    var view3Footer = this.fixture.data.dom.byId("view3Footer");
+	 										// verify view3 layout
+ 											this.fixture.data.runner.assertEqual(0, this.fixture.data.appHeader.offsetTop);
+											this.fixture.data.runner.assertEqual(0, view3Header.offsetTop);
+											this.fixture.data.runner.assertTrue(view3Footer.offsetTop > view3Header.offsetHeight);
+											this.fixture.data.runner.assertTrue(this.fixture.data.appFooter.offsetTop == view3Footer.offsetTop + view3Footer.offsetHeight + view3Header.offsetHeight);
+           								}), 2000);
+           								return d;
+           							}
+           						}]);
+           					runner.run();
+
+ 	                	});
+	                });   
+	        </script>
+	        </head>
+	        <body style="visibility:hidden;">
+        		<!-- App header -->
+                 	<div id="appHeader" data-dojo-type="dojox.mobile.Heading" data-dojo-props="fixed: 'top', label: 'App header'"></div>
+ 
+        		<!-- Scrollable View -->
+	                <div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+                	<div id="view2Header" data-dojo-type="dojox.mobile.Heading" data-dojo-props="fixed: 'top', label: 'ScrollableView Header'">
+                		<div id="rightButton" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props="arrow: 'right', moveTo: 'view3'" style="float: right;">Next</div>
+					</div>
+	            	<div id="view2Footer" data-dojo-type="dojox.mobile.Heading" data-dojo-props="fixed: 'bottom'">ScrollableView Footer</div>
+                </div>
+
+        		<!-- Programmatic Scrollable View -->
+        		<div id="view3"></div>
+
+        		<!-- App footer -->
+                	<div id="appFooter" data-dojo-type="dojox.mobile.Heading" data-dojo-props="fixed: 'bottom'">App Footer</div>
+	        </body>
+	</html>
diff --git a/dojox/mobile/tests/doh/Heading_Programmatic.html b/dojox/mobile/tests/doh/Heading_Programmatic.html
deleted file mode 100644
index fc15805..0000000
--- a/dojox/mobile/tests/doh/Heading_Programmatic.html
+++ /dev/null
@@ -1,70 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Heading</title>
-		<link href="../../themes/android/base.css" rel="stylesheet">
-		<link href="../../themes/common/domButtons.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.require("dojo.window");
-			
-	        dojo.require("doh.runner");
-			dojo.addOnLoad(function(){
-				var view = dijit.byId("general");
-				var demoWidget = new dojox.mobile.Heading({back:"Settings", moveTo:"settings", label:"General"});
-				view.addChild(demoWidget);
-
-				demoWidget = new dojox.mobile.Heading({back:"Long Button", moveTo:"settings"});
-				demoWidget.set({label:"Very Very Long Title May Not Be Displayed in the Narrow Space"});
-				view.addChild(demoWidget);
-
-				demoWidget = new dojox.mobile.Heading({label:"World Clock"});
-				dojo.doc.body.appendChild(demoWidget.domNode);
-
-				demoWidget = new dojox.mobile.Heading();
-				dojo.doc.body.appendChild(demoWidget.domNode);
-				var childWidget = new dojox.mobile.ToolBarButton({lable:"Edit"});
-				childWidget.domNode.style.padding = "0px 14px";
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({className:"mblDomButtonWhitePlus"});
-				childWidget.domNode.style.float = "right";
-				demoWidget.addChild(childWidget);
-				demoWidget.domNode.appendChild(dojo.doc.createTextNode("Alarm Clock"));
-
-
-				doh.register("dojox.mobile.test.doh.Heading1", [
-					function test_Heading_Verification(){
-						var demoWidget = dijit.byId("dojox_mobile_Heading_0");
-						doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-						doh.assertEqual('General', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-
-						demoWidget = dijit.byId("dojox_mobile_Heading_1");
-						doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-						doh.assertEqual('Very Very Long Title May Not Be Displayed in the Narrow Space', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
-						
-						demoWidget = dijit.byId("dojox_mobile_Heading_2");
-						doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-						doh.assertEqual('World Clock', demoWidget.domNode.childNodes[0].childNodes[0].nodeValue);
-
-						demoWidget = dijit.byId("dojox_mobile_Heading_3");
-						doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
-					}
-				]);
-				doh.run();
-			});
-
-		</script>
-	</head>
-	<body>
-		<div id="general" dojoType="dojox.mobile.View" selected="true">
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/IconContainer.html b/dojox/mobile/tests/doh/IconContainer.html
deleted file mode 100644
index eea0299..0000000
--- a/dojox/mobile/tests/doh/IconContainer.html
+++ /dev/null
@@ -1,151 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon</title>
-		<link href="../../themes/iphone/base.css" rel="stylesheet">
-		<link href="../../themes/iphone/IconContainer.css" rel="stylesheet">
-
-		<style>
-			.box {
-				border: 1px solid #A7C0E0;
-				width: 300px;
-				height: 250px;
-				background-image: url(../images/widget-bg.png);
-				background-repeat: no-repeat;
-				background-color: white;
-			}
-		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.IconContainer");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.IconContainer", [
-					{
-						name: "IconContainer Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
-								doh.assertEqual('mblIconContainer', demoWidget.domNode.className);
-								
-							}));
-							return d;
-						}
-					},
-					{
-						name: "IconItem Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
-							var e;
-							doh.assertEqual('none', demoWidget.contentNode.style.display);
-							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0]);
-
-							demoWidget = dijit.byId("dojox_mobile_IconItem_1");
-							doh.assertEqual('none', demoWidget.contentNode.style.display);
-							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0]);
-
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/icon-1.png/i) != -1);
-								}
-								doh.assertEqual('app1', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('', demoWidget.contentNode.style.display);
-								doh.assertEqual('mblIconContentHeading', demoWidget.contentNode.childNodes[0].className);
-								doh.assertEqual('mblDomButtonBlueMinus mblDomButton', demoWidget.contentNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('app1', demoWidget.contentNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-
-								demoWidget = dijit.byId("dojox_mobile_IconItem_1");
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/icon-1.png/i) != -1);
-								}
-								doh.assertEqual('app2', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('', demoWidget.contentNode.style.display);
-								doh.assertEqual('mblIconContentHeading', demoWidget.contentNode.childNodes[0].className);
-								doh.assertEqual('mblDomButtonBlueMinus mblDomButton', demoWidget.contentNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('app2', demoWidget.contentNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								
-							}),2000);
-							return d;
-						}
-					},
-					{
-						name: "IconContainer set",
-						timeout: 4000,
-						runTest: function(){
-							var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
-							demoWidget.set({defaultIcon:"../images/a-icon-2-41x41.png", transition:"slide", pressedIconOpacity:"0.8"});
-
-							doh.assertEqual(0.8, demoWidget.get("pressedIconOpacity"));
-							doh.assertEqual("slide", demoWidget.get("transition"));
-							doh.assertEqual("../images/a-icon-2-41x41.png", demoWidget.get("defaultIcon"));
-
-							demoWidget = dijit.byId("dojox_mobile_IconItem_0");
-							demoWidget.set({icon:"notexist.gif"});
-							doh.assertEqual("notexist.gif", demoWidget.get("icon"));
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
-								doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/a-icon-2-41x41.png/i) != -1);
-							}),2000);
-							return d;
-						}
-					},
-					{
-						name: "IconItem set",
-						timeout: 1000,
-						runTest: function(){
-							var demoWidget = dijit.byId("dojox_mobile_IconItem_1");
-							demoWidget.set({icon:"../images/a-icon-1-41x41.png"});
-							doh.assertEqual("../images/a-icon-1-41x41.png", demoWidget.get("icon"));
-							doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/a-icon-1-41x41.png/i) != -1);
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="app1" icon="../images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app2" icon="../images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app3" icon="../images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="moveTo" icon="../images/icon-1.png" moveTo="about" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="href" icon="../images/icon-1.png" href="../test_iPhone-RoundRectList.html" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="url" icon="../images/icon-1.png" url="../view-sample.html" transition="slide"></li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/IconContainer2.html b/dojox/mobile/tests/doh/IconContainer2.html
deleted file mode 100644
index 035d491..0000000
--- a/dojox/mobile/tests/doh/IconContainer2.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-		<link href="../../themes/common/domButtons.css" rel="stylesheet">
-
-		<style>
-			.box {
-				border: 1px solid #A7C0E0;
-				width: 300px;
-				height: 250px;
-				background-image: url(../images/widget-bg.png);
-				background-repeat: no-repeat;
-				background-color: white;
-			}
-		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.IconContainer");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.IconContainer", [
-					{
-						name: "IconContainer Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
-								doh.assertEqual('mblIconContainer', demoWidget.domNode.className);
-								
-							}));
-							return d;
-						}
-					},
-					{
-						name: "IconItem Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
-							doh.assertEqual('none', demoWidget.contentNode.style.display);
-							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0]);
-							demoWidget = dijit.byId("dojox_mobile_IconItem_1");
-							doh.assertEqual('none', demoWidget.contentNode.style.display);
-							var t = 1000;
-							if(dojo.isIE || dojo.isAndroid || dojo.isIPhone || dojo.isBB) {
-								t=2500;
-							}
-
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
-								if(!dojo.isIE && !dojo.isFF) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/a-icon-2-41x41.png/i) != -1);
-								}
-								doh.assertEqual('app1', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('', demoWidget.contentNode.style.display);
-								doh.assertEqual('mblIconContentHeading', demoWidget.contentNode.childNodes[0].className);
-								doh.assertEqual('mblDomButtonBlueMinus mblDomButton', demoWidget.contentNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('app1', demoWidget.contentNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-
-								demoWidget = dijit.byId("dojox_mobile_IconItem_1");
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/icon-1.png/i) != -1);
-								}
-								doh.assertEqual('app2', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('none', demoWidget.contentNode.style.display);
-								doh.assertEqual('mblIconContentHeading', demoWidget.contentNode.childNodes[0].className);
-								doh.assertEqual('mblDomButtonBlueMinus mblDomButton', demoWidget.contentNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('app2', demoWidget.contentNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								
-							}),t);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
-			<ul dojoType="dojox.mobile.IconContainer" defaultIcon="../images/a-icon-2-41x41.png" transition="slide" pressedIconOpacity="0.8">
-				<li dojoType="dojox.mobile.IconItem" label="app1" icon="../images/notexist.gif" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app2" icon="../images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app3" icon="../images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="moveTo" icon="../images/icon-1.png" moveTo="about" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="href" icon="../images/icon-1.png" href="../test_iPhone-RoundRectList.html" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="url" icon="../images/icon-1.png" url="../view-sample.html" transition="slide"></li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/IconContainer3.html b/dojox/mobile/tests/doh/IconContainer3.html
deleted file mode 100644
index 5016fca..0000000
--- a/dojox/mobile/tests/doh/IconContainer3.html
+++ /dev/null
@@ -1,125 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon</title>
-		<link href="../../themes/iphone/base.css" rel="stylesheet">
-		<link href="../../themes/iphone/IconContainer.css" rel="stylesheet">
-
-		<style>
-			.box {
-				border: 1px solid #A7C0E0;
-				width: 300px;
-				height: 250px;
-				background-image: url(../images/widget-bg.png);
-				background-repeat: no-repeat;
-				background-color: white;
-			}
-		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.IconContainer");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.IconContainer", [
-					{
-						name: "IconContainer Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
-								doh.assertEqual('mblIconContainer', demoWidget.domNode.className);
-								
-							}));
-							return d;
-						}
-					},
-					{
-						name: "IconItem Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
-							var e;
-							doh.assertEqual('none', demoWidget.contentNode.style.display);
-							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0]);
-
-							demoWidget = dijit.byId("dojox_mobile_IconItem_1");
-							doh.assertEqual('none', demoWidget.contentNode.style.display);
-							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0]);
-
-							var t = 1000;
-							if(dojo.isIE || dojo.isAndroid || dojo.isIPhone || dojo.isBB) {
-								t=2500;
-							}
-
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/i-icon-all.png/i) != -1);
-								}
-								verifyRect(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0], "0px", "58px", "58px", "0px");
-								doh.assertEqual('app1', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('none', demoWidget.contentNode.style.display);
-								doh.assertEqual('mblIconContentHeading', demoWidget.contentNode.childNodes[0].className);
-								doh.assertEqual('mblDomButtonBlueMinus mblDomButton', demoWidget.contentNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('app1', demoWidget.contentNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-
-								demoWidget = dijit.byId("dojox_mobile_IconItem_1");
-								if(!dojo.isIE && !dojo.isFF) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/i-icon-all.png/i) != -1);
-								}
-								doh.assertEqual('app2', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('', demoWidget.contentNode.style.display);
-								doh.assertEqual('mblIconContentHeading', demoWidget.contentNode.childNodes[0].className);
-								doh.assertEqual('mblDomButtonBlueMinus mblDomButton', demoWidget.contentNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('app2', demoWidget.contentNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								
-							}),t);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
-			<ul dojoType="dojox.mobile.IconContainer" transition="slide" single="true" pressedIconOpacity="0.8" iconBase="../images/i-icon-all.png" iconPos="0,0,58,58" back="Test" label="test">
-				<li dojoType="dojox.mobile.IconItem" label="app1" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app2" iconPos="0,29,58,58" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app3" iconPos="0,29,58,58" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="moveTo" iconPos="0,29,58,58" moveTo="about" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="href" iconPos="0,29,58,58" href="../test_iPhone-RoundRectList.html" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="url" iconPos="0,29,58,58" url="../view-sample.html" transition="slide"></li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/IconContainerBadgeTests.html b/dojox/mobile/tests/doh/IconContainerBadgeTests.html
new file mode 100644
index 0000000..6b23ce2
--- /dev/null
+++ b/dojox/mobile/tests/doh/IconContainerBadgeTests.html
@@ -0,0 +1,182 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Badge (IconContainer) Tests</title>
+<link href="../../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+<link href="../../themes/common/domButtons/DomButtonGreenBadge.css" rel="stylesheet"/>
+<link href="../../themes/common/domButtons/DomButtonBlueBadge.css" rel="stylesheet"/>
+<link href="css/test.css" rel="stylesheet"/>
+<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles:['base','IconContainer']"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	var ICON_ITEM_CLASSNAME1 = "mblIconItem";
+	var ICON_ITEM_CLASSNAME2 = "mblIconArea";
+	var ICON_BADGE_CLASSNAME1 = "mblBadge";
+	var ICON_BADGE_CLASSNAME2 = "mblDomButton";
+	var ICON_BADGE_CLASSNAME3 = "mblDomButtonRedBadge";
+	var ICON_BADGE_CLASSNAME4 = "mblDomButtonBlueBadge";
+	var ICON_BADGE_CLASSNAME5 = "mblDomButtonGreenBadge";
+	var ICON_BADGE_VALUE = "55";
+	var WIDGET_CLASSNAME = "mblIconContainer";
+	var ICON_ITEM_SRC_REGEXP = /icon3.png/i;
+	var CHILD_ITEM_PROPS = [{label:"app1", icon:"../images/icon3.png", lazy:"true", badge:"55"}, 
+						    {label:"app2", icon:"../images/icon2.png", lazy:"true", badge:"2350", badgeClass:"mblDomButtonBlueBadge"},
+						    {label:"app3", iconPos:"0,0,65,65", lazy:true, badge:"001", badgeClass:"mblDomButtonGreenBadge"}];
+
+	var CHILD_ITEM_CONTAINERS = ['<div class="box"></div>', 
+							  	 '<div class="box"></div>',
+							  	 '<div class="box"></div>'];
+
+	require([
+		"dojo/_base/array", // dojo.forEach
+		"dojo/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/dom-class", // dojo.hasClass
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/IconContainer",
+		"dojox/mobile/IconItem",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
+		"dojox/mobile/View"		// This mobile app uses mobile view
+	], function(array, has, domConst, domClass, ready, registry, runner, IconContainer, IconItem){
+		function _createIconContainerDeclaratively(widgetId) {
+			return registry.byId(widgetId);
+		}
+		function _createIconContainerProgrammatically(placeHolderId, widgetId){
+			// Create IconContainer
+			var r = new IconContainer({id:widgetId, iconBase:"../images/icon-all.png"});
+			runner.assertNotEqual(null, r);
+			domConst.place(r.domNode, placeHolderId, "replace");
+
+			// Create IconItems
+			for(var i = 0, len = CHILD_ITEM_PROPS.length; i < len; i++){
+				var childWidget = new IconItem(CHILD_ITEM_PROPS[i]);
+				r.addChild(childWidget);
+				if(CHILD_ITEM_CONTAINERS[i]){
+					childWidget.set("content", CHILD_ITEM_CONTAINERS[i]);
+				}
+			}
+			r.startup();
+			return r;
+		}
+		function _createIconContainerProgrammaticallyWithSourceNodeReference(widgetId){
+			// Create IconContainer
+			var r = new IconContainer({iconBase:"../images/icon-all.png"}, widgetId);
+
+			// Create IconItems
+			var index = 0;
+			for(var i = 0, len = r.domNode.childNodes.length; i < len; i++){
+				var n = r.domNode.childNodes[i];
+				if(n.nodeType === 1 && n.id){
+					new IconItem(CHILD_ITEM_PROPS[index++], n.id);
+				}
+			}
+			r.startup();
+			return r;
+		}
+		function _setBadges(Ids){
+			array.forEach(Ids, function(Id){
+				registry.byId(Id).set("badge", "55");
+			});			
+		}
+		function _assertCorrectIconContainer(widget){
+			runner.assertNotEqual(null, widget, "IconContainer: Did not instantiate.");
+			runner.assertEqual(WIDGET_CLASSNAME, widget.domNode.className, "id=" + widget.domNode.id);
+			var index = 0;
+			array.forEach(widget.getChildren(), function(iconItem){
+				_assertCorrectIconItem(iconItem, CHILD_ITEM_PROPS[index++]);
+			});
+			
+		}
+		function _assertCorrectIconItem(widget, props){
+			runner.assertNotEqual(null, widget, "IconItem: Did not instantiate.");
+			runner.assertEqual(ICON_ITEM_CLASSNAME1, widget.domNode.className, "id=" + widget.domNode.id);
+			runner.assertEqual(ICON_ITEM_CLASSNAME2, widget.domNode.childNodes[0].className, "id=" + widget.domNode.id);
+			runner.assertNotEqual(null, widget.badgeObj, "IconItem badgeObj: Did not instantiate. id=" + widget.domNode.id);
+			runner.assertTrue(domClass.contains(widget.badgeObj.domNode, ICON_BADGE_CLASSNAME1), ICON_BADGE_CLASSNAME1 + " id=" + widget.domNode.id + " value=" + widget.domNode.className);
+			runner.assertTrue(domClass.contains(widget.badgeObj.domNode, ICON_BADGE_CLASSNAME2), ICON_BADGE_CLASSNAME2 + " id=" + widget.domNode.id + " value=" + widget.domNode.className);
+			var badgeClass = props.badgeClass || ICON_BADGE_CLASSNAME3;
+			runner.assertTrue(domClass.contains(widget.badgeObj.domNode, badgeClass), badgeClass + " id=" + widget.domNode.id + " value=" + widget.domNode.className);
+			var badgeValue = props.badge;
+			runner.assertEqual(badgeValue, widget.badgeObj.domNode.childNodes[0].innerHTML, "id=" + widget.domNode.id);
+			runner.assertEqual(badgeValue, widget.badgeObj.getValue(), "id=" + widget.domNode.id);
+			if((!has("ie") || has("ie") > 6) && props.icon === "../images/icon3.png"){
+				runner.assertTrue(widget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(ICON_ITEM_SRC_REGEXP) != -1, ICON_ITEM_SRC_REGEXP.toString() + " id=" + widget.domNode.id);
+			}
+			runner.assertEqual(widget.label, widget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue, "id=" + widget.domNode.id);
+		}
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		}
+		dojo.ready(function(){
+			doh.register("dojox.mobile.test.doh.IconContainerTests", [
+				function testInView1(){
+					var widget1 = _createIconContainerDeclaratively("dojox_mobile_IconContainer_0");
+					var widget2 = _createIconContainerProgrammatically("view1-IconContainer2place", "view1-IconContainer2");
+					var widget3 = _createIconContainerProgrammaticallyWithSourceNodeReference("view1-IconContainer3");
+
+//					_setBadges(["dojox_mobile_IconItem_1","dojox_mobile_IconItem_5", "view1-IconContainer3-IconItem2"]);
+					_assertCorrectIconContainer(widget1);
+					_assertCorrectIconContainer(widget2);
+					_assertCorrectIconContainer(widget3);
+				},
+				function testInView2(){
+					var widget1 = _createIconContainerDeclaratively("dojox_mobile_IconContainer_1");
+					var widget2 = _createIconContainerProgrammatically("view2-IconContainer2place", "view2-IconContainer2");
+					var widget3 = _createIconContainerProgrammaticallyWithSourceNodeReference("view2-IconContainer3");
+
+					_showView2();
+
+//					_setBadges(["dojox_mobile_IconItem_3","dojox_mobile_IconItem_7", "view2-IconContainer3-IconItem2"]);
+					_assertCorrectIconContainer(widget1);
+					_assertCorrectIconContainer(widget2);
+					_assertCorrectIconContainer(widget3);
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='iconBase:"../images/icon-all.png"'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"../images/icon3.png", lazy:true, badge:"55"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"../images/icon2.png", lazy:true, badge:"2350", badgeClass:"mblDomButtonBlueBadge"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", iconPos:"0,0,65,65", lazy:true, badge:"001", badgeClass:"mblDomButtonGreenBadge"'><div class="box"></div></li>
+		</ul>
+		<br/>
+		<div id="view1-IconContainer2place"></div>
+		<br/>
+		<ul id="view1-IconContainer3">
+			<li id="view1-IconContainer3-IconItem1"><div class="box"></div></li>
+			<li id="view1-IconContainer3-IconItem2"><div class="box"></div></li>
+			<li id="view1-IconContainer3-IconItem3"><div class="box"></div></li>
+		</ul>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='iconBase:"../images/icon-all.png"'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"../images/icon3.png", lazy:true, badge:"55"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"../images/icon2.png", lazy:true, badge:"2350", badgeClass:"mblDomButtonBlueBadge"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", iconPos:"0,0,65,65", lazy:true, badge:"001", badgeClass:"mblDomButtonGreenBadge"'><div class="box"></div></li>
+		</ul>
+		<br/>
+		<div id="view2-IconContainer2place"></div>
+		<br/>
+		<ul id="view2-IconContainer3">
+			<li id="view2-IconContainer3-IconItem1"><div class="box"></div></li>
+			<li id="view2-IconContainer3-IconItem2"><div class="box"></div></li>
+			<li id="view2-IconContainer3-IconItem3"><div class="box"></div></li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/IconContainer_Programmatic.html b/dojox/mobile/tests/doh/IconContainer_Programmatic.html
deleted file mode 100644
index e8e235e..0000000
--- a/dojox/mobile/tests/doh/IconContainer_Programmatic.html
+++ /dev/null
@@ -1,148 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon</title>
-		<link href="../../themes/iphone/base.css" rel="stylesheet">
-		<link href="../../themes/iphone/IconContainer.css" rel="stylesheet">
-
-		<style>
-			.box {
-				border: 1px solid #A7C0E0;
-				width: 300px;
-				height: 250px;
-				background-image: url(../images/widget-bg.png);
-				background-repeat: no-repeat;
-				background-color: white;
-			}
-		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.IconContainer");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-			dojo.require("doh.runner");
-
-			dojo.addOnLoad(function(){
-
-				var view = dijit.byId("foo");
-				var container = new dojox.mobile.IconContainer();
-				var demoWidget = new dojox.mobile.IconItem({label:"app1", icon:"../images/icon-1.png", lazy:"true"});
-//This position works fine.
-//				view.addChild(container);
-				demoWidget.containerNode.innerHTML='<div class="box"></div>';
-				container.addChild(demoWidget);
-
-				demoWidget = new dojox.mobile.IconItem({label:"app2", icon:"../images/icon-1.png", lazy:"true"});
-				container.addChild(demoWidget);
-				demoWidget.containerNode.innerHTML='<div class="box"></div>';
-
-				demoWidget = new dojox.mobile.IconItem({label:"app3", icon:"../images/icon-1.png", lazy:"true"});
-				demoWidget.containerNode.innerHTML='<div class="box"></div>';
-				container.addChild(demoWidget);
-
-				demoWidget = new dojox.mobile.IconItem({label:"moveTo", icon:"../images/icon-1.png", moveTo:"about", transition:"slide"});
-				container.addChild(demoWidget);
-
-				demoWidget = new dojox.mobile.IconItem({label:"href", icon:"../images/icon-1.png", href:"../test_iPhone-RoundRectList.html", transition:"slide"});
-				container.addChild(demoWidget);
-
-				demoWidget = new dojox.mobile.IconItem({label:"url", icon:"../images/icon-1.png", href:"../view-sample.html", transition:"slide"});
-				container.addChild(demoWidget);
-//This position makes error.
-				view.addChild(container);
-			});
-		</script>
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.IconContainer", [
-					{
-						name: "IconContainer Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
-								doh.assertEqual('mblIconContainer', demoWidget.domNode.className);
-								
-							}));
-							return d;
-						}
-					},
-					{
-						name: "IconItem Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
-							var e;
-							doh.assertEqual('none', demoWidget.contentNode.style.display);
-							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0]);
-
-							demoWidget = dijit.byId("dojox_mobile_IconItem_1");
-							doh.assertEqual('none', demoWidget.contentNode.style.display);
-							demoWidget = dijit.byId("dojox_mobile_IconItem_0");
-							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0]);
-
-							var t = 500;
-							if(dojo.isIE){
-								t=2000;
-							}
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/icon-1.png/i) != -1);
-								}
-								doh.assertEqual('app1', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('', demoWidget.contentNode.style.display);
-								doh.assertEqual('mblIconContentHeading', demoWidget.contentNode.childNodes[0].className);
-								doh.assertEqual('mblDomButtonBlueMinus mblDomButton', demoWidget.contentNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('app1', demoWidget.contentNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-
-								demoWidget = dijit.byId("dojox_mobile_IconItem_1");
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/icon-1.png/i) != -1);
-								}
-								doh.assertEqual('app2', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								doh.assertEqual('none', demoWidget.contentNode.style.display);
-								doh.assertEqual('mblIconContentHeading', demoWidget.contentNode.childNodes[0].className);
-								doh.assertEqual('mblDomButtonBlueMinus mblDomButton', demoWidget.contentNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('app2', demoWidget.contentNode.childNodes[0].childNodes[1].childNodes[0].nodeValue);
-								
-							}),t);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/ItemBase_subclasses_Programmatic.html b/dojox/mobile/tests/doh/ItemBase_subclasses_Programmatic.html
new file mode 100644
index 0000000..15a4f84
--- /dev/null
+++ b/dojox/mobile/tests/doh/ItemBase_subclasses_Programmatic.html
@@ -0,0 +1,312 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>ListItem Programmatic 3</title>
+<script type="text/javascript" src="../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" 
+	data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	require([
+		"dojo/_base/declare",
+		"dojox/mobile/parser",
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	// doh functions
+		"dojox/mobile/Heading",
+		"dojox/mobile/ListItem",
+		"dojox/mobile/IconItem",
+		"dojox/mobile/IconContainer",
+		"dojox/mobile/IconMenuItem",
+		"dojox/mobile/IconMenu",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/ToolBarButton",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat"		// This mobile app supports running on desktop browsers
+	], function(declare, parser, ready, registry, runner, 
+				Heading, ListItem, IconItem, IconContainer,
+				IconMenuItem, IconMenu, TabBarButton, TabBar, ToolBarButton){
+
+		// This test mimics a particular case which happens in dojox/mvc due to 
+		// the binding mechanism: the values of widget properties are set before 
+		// the widget is actually started, that is before this.inherited completed. 
+		// This holds for the following properties:
+		// ListItem: icon, checked, deleteIcon, rightIcon, rightIcon2, uncheckIcon.
+		// IconItem: icon
+		// IconMenuItem: icon
+		// TabBarButton: icon (icon1 and icon2 are not delayed)
+		// ToolBarButton: icon
+		// For these properties, the widgets use a mechanism which reapplies the setters 
+		// once the startup is completed. 
+		// The present test checks that these properties have the expected values even
+		// if the setters are called before startup completion.
+					
+		function _createListItem1(){
+			var MyListItem1 = declare(
+				"dojox.mobile.MyListItem1",
+				ListItem,	{
+				startup: function(){
+					this.set("checked", true);
+					this.inherited(arguments);
+				}
+			});
+			var list = registry.byId("listInSelectMode");
+			var item = new MyListItem1();
+			list.addChild(item);
+			return item;
+		};
+		function _assertCorrectListItem1(widget){
+			runner.assertTrue(widget.get("checked"), 
+				"'checked' property not correctly set if setter called before startup completed");
+		};
+		
+		// 2. Test the icon-related properties for a ListItem added to a list which is in "select" mode.
+		// In "select" mode, the values of the properties "rightIcon" and "uncheckIcon" are overridden 
+		// by the setter of "checked".
+		function _createListItem2(){
+			var MyListItem2 = declare(
+				"dojox.mobile.MyListItem2",
+				ListItem,	{
+				startup: function(){
+					this.set("icon", "../images/a-icon1.png");
+					this.set("deleteIcon", "../images/a-icon2.png");
+					this.set("rightIcon", "../images/a-icon3.png");
+					this.set("rightIcon2", "../images/a-icon4.png");
+					this.set("uncheckIcon", "../images/a-icon5.png");
+
+					this.inherited(arguments);
+				}
+			});
+			var list = registry.byId("listInSelectMode");
+			var item = new MyListItem2();
+			list.addChild(item);
+			return item;
+		};
+		function _assertCorrectListItem2(widget){
+			runner.assertEqual("../images/a-icon1.png", widget.get("icon"),
+				"'icon' property not correctly set if setter called before startup completed (list in select mode)");
+			runner.assertEqual("../images/a-icon2.png", widget.get("deleteIcon"),
+				"'deleteIcon' property not correctly set if setter called before startup completed (list in select mode)");
+			runner.assertEqual("mblDomButtonCheck", widget.get("rightIcon"),
+			 	"'rightIcon' property not correctly set if setter called before startup completed (list in select mode)");
+			runner.assertEqual("../images/a-icon4.png", widget.get("rightIcon2"),
+				"'rightIcon2' property not correctly set if setter called before startup completed (list in select mode)");
+			runner.assertEqual(undefined, widget.get("uncheckIcon"),
+				"'uncheckIcon' property not correctly set if setter called before startup completed (list in select mode)");
+		};
+		
+		// 3. Test the icon-related properties for a ListItem added to a list which is not in "select" mode.
+		// In this case, the values of the properties "rightIcon" and "uncheckIcon" are not overridden 
+		// by the setter of "checked" (because the setter is not called).).
+		function _createListItem3(){
+			var MyListItem3 = declare(
+				"dojox.mobile.MyListItem3",
+				ListItem,	{
+				startup: function(){
+					// This mimics what happens in dojox/mvc due to the binding mechanism:
+					// the values of properties are set before the widget is actually started,
+					// that is before this.inherited completed its execution.
+					// The properties below are among those for which ListItem uses a mechanism 
+					// which reapplies the setters once the startup is completed. 
+					this.set("icon", "../images/a-icon1.png");
+					this.set("deleteIcon", "../images/a-icon2.png");
+					this.set("rightIcon", "../images/a-icon3.png");
+					this.set("rightIcon2", "../images/a-icon4.png");
+					this.set("uncheckIcon", "../images/a-icon5.png");
+
+					this.inherited(arguments);
+				}
+			});
+			var list = registry.byId("listNotInSelectMode");
+			var item = new MyListItem3();
+			list.addChild(item);
+			return item;
+		};
+		function _assertCorrectListItem3(widget){
+			runner.assertEqual("../images/a-icon1.png", widget.get("icon"),
+				"'icon' property not correctly set if setter called before startup completed (list not in select mode)");
+			runner.assertEqual("../images/a-icon2.png", widget.get("deleteIcon"),
+				"'deleteIcon' property not correctly set if setter called before startup completed (list not in select mode)");
+			runner.assertEqual("../images/a-icon3.png", widget.get("rightIcon"),
+			 	"'rightIcon' property not correctly set if setter called before startup completed (list not in select mode)");
+			runner.assertEqual("../images/a-icon4.png", widget.get("rightIcon2"),
+				"'rightIcon2' property not correctly set if setter called before startup completed (list not in select mode)");
+			runner.assertEqual("../images/a-icon5.png", widget.get("uncheckIcon"),
+				"'uncheckIcon' property not correctly set if setter called before startup completed (list not in select mode)");
+		};
+		
+		// 4. Test the icon property for an IconItem added to an IconContainer
+		function _createIconItem(){
+			var MyIconItem = declare(
+				"dojox.mobile.MyIconItem",
+				IconItem,	{
+				startup: function(){
+					this.set("icon", "../images/a-icon1.png");
+					this.inherited(arguments);
+				}
+			});
+			var list = registry.byId("iconContainer");
+			var item = new MyIconItem();
+			list.addChild(item);
+			return item;
+		};
+		function _assertCorrectIconItem(widget){
+			runner.assertEqual("../images/a-icon1.png", widget.get("icon"),
+				"'icon' property not correctly set if setter called before startup completed (IconItem)");
+		};
+		
+		// 5. Test the icon property for an IconMenuItem added to an IconMenu
+		function _createIconMenuItem(){
+			var MyIconMenuItem = declare(
+				"dojox.mobile.MyIconMenuItem",
+				IconMenuItem,	{
+				startup: function(){
+					this.set("icon", "../images/a-icon1.png");
+					this.inherited(arguments);
+				}
+			});
+			var list = registry.byId("iconMenu");
+			var item = new MyIconMenuItem();
+			list.addChild(item);
+			return item;
+		};
+		function _assertCorrectIconMenuItem(widget){
+			runner.assertEqual("../images/a-icon1.png", widget.get("icon"),
+				"'icon' property not correctly set if setter called before startup completed (IconMenuItem)");
+		};
+		
+		// 6. Test the icon1 and icon2 properties for a TabBarButton added to a TabBar
+		function _createTabBarButton(){
+			var MyTabBarButton = declare(
+				"dojox.mobile.MyTabBarButton",
+				TabBarButton,	{
+				startup: function(){
+					this.set("icon", "../images/a-icon1.png");
+					this.set("icon1", "../images/a-icon2.png");
+					this.set("icon2", "../images/a-icon3.png");
+					this.inherited(arguments);
+				}
+			});
+			var list = registry.byId("tabBar");
+			var item = new MyTabBarButton();
+			list.addChild(item);
+			return item;
+		};
+		function _assertCorrectIconTabBarButton(widget){
+			runner.assertEqual("../images/a-icon1.png", widget.get("icon"),
+			 	"'icon' property not correctly set if setter called before startup completed (TabBarButton)");
+			runner.assertEqual("../images/a-icon2.png", widget.get("icon1"),
+				"'icon1' property not correctly set if setter called before startup completed (TabBarButton)");
+			runner.assertEqual("../images/a-icon3.png", widget.get("icon2"),
+				"'icon2' property not correctly set if setter called before startup completed (TabBarButton)");
+		};
+		
+		// 7. Test the icon property for a ToolBarButton added to a parent
+		function _createToolBarButton(){
+			var MyToolBarButton = declare(
+				"dojox.mobile.MyToolBarButton",
+				ToolBarButton,	{
+				startup: function(){
+					this.set("icon", "../images/a-icon1.png");
+					this.inherited(arguments);
+				}
+			});
+			var list = registry.byId("toolBar");
+			var item = new MyToolBarButton();
+			list.addChild(item);
+			return item;
+		};
+		function _assertCorrectIconToolBarButton(widget){
+			runner.assertEqual("../images/a-icon1.png", widget.get("icon"),
+				"'icon' property not correctly set if setter called before startup completed (ToolBarButton)");
+		};
+		
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.ItemBase_subclasses_Programmatic", [
+				{
+					name: "ItemBase_subclasses_Programmatic ListItem.checked",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createListItem1();
+						_assertCorrectListItem1(widget);
+					}
+				},
+				{
+					name: "ItemBase_subclasses_Programmatic ListItem.icon (select mode)",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createListItem2();
+						_assertCorrectListItem2(widget);
+					}
+				},
+				{
+					name: "ItemBase_subclasses_Programmatic ListItem.icon (not select mode)",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createListItem3();
+						_assertCorrectListItem3(widget);
+					}
+				},
+				{
+					name: "ItemBase_subclasses_Programmatic IconItem.icon",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createIconItem();
+						_assertCorrectIconItem(widget);
+					}
+				},
+				{
+					name: "ItemBase_subclasses_Programmatic IconMenuItem.icon",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createIconMenuItem();
+						_assertCorrectIconMenuItem(widget);
+					}
+				},
+				{
+					name: "ItemBase_subclasses_Programmatic TabBarButton.icon/icon1/icon2",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createTabBarButton();
+						_assertCorrectIconTabBarButton(widget);
+					}
+				},
+				{
+					name: "ItemBase_subclasses_Programmatic ToolBarButton.icon",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createToolBarButton();
+						_assertCorrectIconToolBarButton(widget);
+					}
+				}
+			]);
+			runner.run();
+		});
+	});
+</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view" data-dojo-type="dojox/mobile/View" selected="true">
+		<h1 data-dojo-type="dojox/mobile/Heading">RoundRectList</h1>
+		<!-- A list in single select mode -->
+		<ul id="listInSelectMode" data-dojo-type="dojox/mobile/RoundRectList" 
+			data-dojo-props="select:'single'">
+		</ul>
+		<!-- A list which is not in a select mode -->
+		<ul id="listNotInSelectMode" data-dojo-type="dojox/mobile/RoundRectList">
+		</ul>
+		<ul id="iconContainer" data-dojo-type="dojox/mobile/IconContainer">
+		</ul>
+		<ul id="iconMenu" data-dojo-type="dojox/mobile/IconMenu">
+		</ul>
+		<ul id="tabBar" data-dojo-type="dojox/mobile/TabBar">
+		</ul>
+		<div id="toolBar" data-dojo-type="dojox/mobile/Heading">
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/ListItem.html b/dojox/mobile/tests/doh/ListItem.html
deleted file mode 100644
index cb5798a..0000000
--- a/dojox/mobile/tests/doh/ListItem.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ListItem</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-		<link href="../../themes/common/domButtons/DomButtonColorButtons.css" rel="stylesheet">
-		<link href="../../themes/common/domButtons/DomButtonCheckboxOn.css" rel="stylesheet">
-		<link href="../../themes/common/domButtons/DomButtonCheckboxOff.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script type="text/javascript" src="ListItem.js"></script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-1.png" transition="slide" url="../view1.html">External View #1 (sync)</li>
-				<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-2.png" transition="flip" url="../view2.html" sync="false">External View #2 (async)</li>
-				<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-3.png" transition="fade" url="../view3.html">External View #3 (sync)</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">Video</li>
-				<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-1.png" rightText="VPN">Maps</li>
-				<li dojoType="dojox.mobile.ListItem">Jack Coleman</li>
-			</ul>
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="../images/i-icon-all.png">
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">Sounds</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" moveTo="general">Brightness</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29" moveTo="general">Wallpaper</li>
-			</ul>
-			<ul id="list1" dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-1.png" btnClass="mblDomButtonBluePlus">XX Widget</li>
-				<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-2.png" btnClass="mblDomButtonRedMinus">YY Widget</li>
-			</ul>
-		    <ul id="list2" dojoType="dojox.mobile.EdgeToEdgeList">
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" btnClass="mblDomButtonCheckboxOff">
-				    Use wireless networks
-				    <div class="mblListItemSubText">
-					    See location in applications (such as Maps) using wireless networks
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" btnClass="mblDomButtonCheckboxOn">
-				    Use GPS satellites
-				    <div class="mblListItemSubText">
-					    When locating, accurate to street level (uncheck to conserve battery)
-				    </div>
-			    </li>
-			    <li dojoType="dojox.mobile.ListItem">
-			       Set unlock pattern
-			    </li>
-		    </ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/ListItem.js b/dojox/mobile/tests/doh/ListItem.js
deleted file mode 100644
index dd2611d..0000000
--- a/dojox/mobile/tests/doh/ListItem.js
+++ /dev/null
@@ -1,113 +0,0 @@
-dojo.addOnLoad(function(){
-	doh.register("dojox.mobile.test.doh.ListItem", [
-		{
-			name: "ListItem Verification",
-			timeout: 4000,
-			runTest: function(){
-				var d = new doh.Deferred();
-				setTimeout(d.getTestCallback(function(){
-					verifyListItem("dojox_mobile_ListItem_0", 'External View #1 (sync)', '', "mblDomButtonArrow", true, true, false, false, /i-icon-1.png/i);
-					verifyListItem("dojox_mobile_ListItem_1", 'External View #2 (async)', '', "mblDomButtonArrow", true, true, false);
-					verifyListItem("dojox_mobile_ListItem_2", 'External View #3 (sync)', '', "mblDomButtonArrow", true, true, false);
-					verifyListItem("dojox_mobile_ListItem_3", 'Video', 'Off', "", false, false, false);
-					verifyListItem("dojox_mobile_ListItem_4", 'Maps', 'VPN', "", true, false, false);
-					verifyListItem("dojox_mobile_ListItem_5", 'Jack Coleman', '', "", false, false, false);
-					verifyListItem("dojox_mobile_ListItem_6", 'Sounds', '', "mblDomButtonArrow", true, true, false);
-					verifyListItem("dojox_mobile_ListItem_7", 'Brightness', '', "mblDomButtonArrow", true, true, false);
-					verifyListItem("dojox_mobile_ListItem_8", 'Wallpaper', '', "mblDomButtonArrow", true, true, false);
-					verifyListItem("dojox_mobile_ListItem_9", 'XX Widget', '', "mblDomButtonBluePlus", true, true, false);
-					verifyListItem("dojox_mobile_ListItem_10", 'YY Widget', '', "mblDomButtonRedMinus", true, true, false);
-					verifyListItem("dojox_mobile_ListItem_11", 'Use wireless networks', '', "mblDomButtonCheckboxOff", false, true, false, true);
-					verifyListItem("dojox_mobile_ListItem_12", 'Use GPS satellites', '', "mblDomButtonCheckboxOn", false, true, false, true);
-					verifyListItem("dojox_mobile_ListItem_13", 'Set unlock pattern', '', "", false, false, false);
-				}));
-				return d;
-			}
-		},
-		{
-			name: "ListItem set",
-			timeout: 1000,
-			runTest: function(){
-				var demoWidget = dijit.byId("dojox_mobile_ListItem_0");
-				demoWidget.set({transition :"flip", url:"../view2.html", noArrow:true, selected:true, anchorLabel:true, rightText:"Value Changed"});
-				doh.assertEqual("flip", demoWidget.get("transition"));
-				doh.assertEqual("../view2.html", demoWidget.get("url"));
-				doh.assertTrue(demoWidget.get("noArrow"), 'get("noArrow")');
-				doh.assertTrue(demoWidget.get("selected"), 'get("selected")');
-				doh.assertTrue(demoWidget.get("anchorLabel"), 'get("anchorLabel")');
-				doh.assertEqual("Value Changed", demoWidget.get("rightText"));
-
-				verifyListItem("dojox_mobile_ListItem_0", 'External View #1 (sync)', 'Value Changed', "mblDomButtonArrow", true, true, false);
-			}
-		},
-		{
-			name: "ListItem set",
-			timeout: 1000,
-			runTest: function(){
-				var demoWidget = dijit.byId("dojox_mobile_ListItem_1");
-				demoWidget.set({icon :"../images/i-icon-4.png", label:"Value Changed", clickable:true, url:"../view3.html", transition :"slide", transitionDir:-1, sync:false, toggle:true, _duration:1600});
-
-				doh.assertEqual("slide", demoWidget.get("transition"));
-				doh.assertEqual("../view3.html", demoWidget.get("url"));
-				doh.assertEqual(-1, demoWidget.get("transitionDir"));
-				doh.assertTrue(demoWidget.get("clickable"), 'get("clickable")');
-				doh.assertFalse(demoWidget.get("sync"), 'get("sync")');
-				doh.assertTrue(demoWidget.get("toggle"), 'get("toggle")');
-				doh.assertEqual(1600, demoWidget.get("_duration"));
-				doh.assertEqual("Value Changed", demoWidget.get("label"));
-
-				verifyListItem("dojox_mobile_ListItem_1", 'Value Changed', '', "mblDomButtonArrow", true, true, false, false, /i-icon-4.png/i);
-			}
-		},
-		{
-			name: "ListItem set",
-			timeout: 1000,
-			runTest: function(){
-				var demoWidget = dijit.byId("dojox_mobile_ListItem_6");
-				demoWidget.set({iconPos :"0,116,29,29", moveTo:"bar", transition :"fade"});
-
-				doh.assertEqual("bar", demoWidget.get("moveTo"));
-				doh.assertEqual("0,116,29,29", demoWidget.get("iconPos"));
-				doh.assertEqual("fade", demoWidget.get("transition"));
-
-				verifyListItem("dojox_mobile_ListItem_6", 'Sounds', '', "mblDomButtonArrow", true, true, false, false, /i-icon-all.png/i);
-			}
-		},
-		{
-
-//Todo
-			name: "ListItem set",
-			timeout: 1000,
-			runTest: function(){
-				var demoWidget = dijit.byId("dojox_mobile_ListItem_6");
-				demoWidget.set({href :"", hrefTarget:""});
-
-				doh.assertEqual("", demoWidget.get("href"));
-				doh.assertEqual("", demoWidget.get("hrefTarget"));
-
-			}
-		},
-		{
-			name: "ListItem set",
-			timeout: 1000,
-			runTest: function(){
-				var demoWidget = dijit.byId("dojox_mobile_ListItem_9");
-				demoWidget.set({btnClass:"mblDomButtonRedMinus"});
-				verifyListItem("dojox_mobile_ListItem_9", 'XX Widget', '', "mblDomButtonRedMinus", true, true, false);
-//							doh.assertEqual("mblDomButtonRedMinus", demoWidget.get("btnClass"));
-			}
-		},
-		{
-			name: "ListItem set",
-			timeout: 1000,
-			runTest: function(){
-				var demoWidget = dijit.byId("dojox_mobile_ListItem_11");
-				demoWidget.set({btnClass:"mblDomButtonCheckboxOn"});
-
-				verifyListItem("dojox_mobile_ListItem_11", 'Use wireless networks', '', "mblDomButtonCheckboxOn", false, true, false, true);
-//							doh.assertEqual("mblDomButtonCheckboxOn", demoWidget.get("btnClass"));
-			}
-		}
-	]);
-	doh.run();
-});
diff --git a/dojox/mobile/tests/doh/ListItem2.html b/dojox/mobile/tests/doh/ListItem2.html
deleted file mode 100644
index e06ea75..0000000
--- a/dojox/mobile/tests/doh/ListItem2.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ListItem</title>
-		<link href="../../themes/iphone/base.css" rel="stylesheet">
-		<link href="../../themes/iphone/IconContainer.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script type="text/javascript" src="ListItem2.js"></script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="../images/i-icon-all.png">
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">Sounds</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" moveTo="general">Brightness</li>
-			</ul>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" iconBase="../images/i-icon-all.png">
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" btnClass="mblDomButtonBluePlus">XX Widget</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" btnClass="mblDomButtonRedMinus">YY Widget</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/ListItem2.js b/dojox/mobile/tests/doh/ListItem2.js
deleted file mode 100644
index 5aeee8d..0000000
--- a/dojox/mobile/tests/doh/ListItem2.js
+++ /dev/null
@@ -1,44 +0,0 @@
-dojo.addOnLoad(function(){
-	doh.register("dojox.mobile.test.doh.ListItem", [
-		{
-			name: "ListItem Verification",
-			timeout: 4000,
-			runTest: function(){
-				var d = new doh.Deferred();
-				setTimeout(d.getTestCallback(function(){
-
-					verifyListItem("dojox_mobile_ListItem_0", 'Sounds', '', "mblDomButtonArrow", true, true, false, false, /i-icon-all.png/i);
-					verifyListItemPos("dojox_mobile_ListItem_0", "0px", "116px", "29px", "87px", "0px", "-87px");
-
-					verifyListItem("dojox_mobile_ListItem_1", 'Brightness', '', "mblDomButtonArrow", true, true, false, false, /i-icon-all.png/i);
-					verifyListItemPos("dojox_mobile_ListItem_1", "0px", "145px", "29px", "116px", "0px", "-116px");
-
-					verifyListItem("dojox_mobile_ListItem_2", 'XX Widget', '', "mblDomButtonBluePlus", true, true, false, false, /i-icon-all.png/i);								verifyListItemPos("dojox_mobile_ListItem_2", "0px", "116px", "29px", "87px", "0px", "-87px");
-
-					verifyListItem("dojox_mobile_ListItem_3", 'YY Widget', '', "mblDomButtonRedMinus", true, true, false, false, /i-icon-all.png/i);								verifyListItemPos("dojox_mobile_ListItem_3", "0px", "145px", "29px", "116px", "0px", "-116px");
-				}));
-				return d;
-			}
-		},
-		{
-			name: "ListItem set",
-			timeout: 1000,
-			runTest: function(){
-				var demoWidget = dijit.byId("dojox_mobile_RoundRectList_0");
-				demoWidget.set({iconBase :""});
-				doh.assertEqual("", demoWidget.get("iconBase"));
-
-				verifyListItem("dojox_mobile_ListItem_0", 'Sounds', '', "mblDomButtonArrow", true, true, false, false, /i-icon-all.png/i);
-				verifyListItemPos("dojox_mobile_ListItem_0", "0px", "116px", "29px", "87px", "0px", "-87px");
-
-				demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
-				demoWidget.set({iconBase :""});
-				doh.assertEqual("", demoWidget.get("iconBase"));
-
-				verifyListItem("dojox_mobile_ListItem_2", 'XX Widget', '', "mblDomButtonBluePlus", true, true, false, false, /i-icon-all.png/i)
-				verifyListItemPos("dojox_mobile_ListItem_2", "0px", "116px", "29px", "87px", "0px", "-87px");
-			}
-		}
-	]);
-	doh.run();
-});
diff --git a/dojox/mobile/tests/doh/ListItem2_Programmatic.html b/dojox/mobile/tests/doh/ListItem2_Programmatic.html
deleted file mode 100644
index 7bb8ce5..0000000
--- a/dojox/mobile/tests/doh/ListItem2_Programmatic.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ListItem</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-
-		<script type="text/javascript" src="CreateListItem2_Programmatic.js"></script>
-
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script type="text/javascript" src="ListItem2.js"></script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/ListItem_Programmatic.html b/dojox/mobile/tests/doh/ListItem_Programmatic.html
deleted file mode 100644
index 05b6828..0000000
--- a/dojox/mobile/tests/doh/ListItem_Programmatic.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Switch</title>
-		<link href="../../themes/iphone/base.css" rel="stylesheet">
-		<link href="../../themes/common/domButtons.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-
-		<script type="text/javascript" src="CreateListItem_Programmatic.js"></script>
-
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script type="text/javascript" src="ListItem.js"></script>
-
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<ul dojoType="dojox.mobile.RoundRectList">
-			</ul>
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="../images/i-icon-all.png">
-			</ul>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-			</ul>
-		    <ul dojoType="dojox.mobile.EdgeToEdgeList">
-		    </ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/ListTests.js b/dojox/mobile/tests/doh/ListTests.js
new file mode 100644
index 0000000..6d4af64
--- /dev/null
+++ b/dojox/mobile/tests/doh/ListTests.js
@@ -0,0 +1,91 @@
+require([
+	"dojo/dom-construct", // dojo.place
+	"dojo/ready", // dojo.ready
+	"dijit/registry",  // dijit.byId
+	"doh/runner",	//doh functions
+	"dojox/mobile/EdgeToEdgeList",
+	"dojox/mobile/RoundRectList",
+	"dojox/mobile/ListItem",
+	"dojox/mobile",				// This is a mobile app.
+	"dojox/mobile/View",		// This mobile app uses mobile view
+	"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+	"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+], function(domConst, ready, registry, runner, EdgeToEdgeList, RoundRectList, ListItem){
+
+	var ITEM_LABEL, ListObject, testName;
+	
+	if(IsEdgeToEdgeList){
+		ITEM_LABEL = "Edge To Edge";
+		ListObject = EdgeToEdgeList;
+		testName = "dojox.mobile.test.doh.EdgeToEdgeListTests";
+	}else{
+		ITEM_LABEL = "Round Rect";
+		ListObject = RoundRectList;
+		testName = "dojox.mobile.test.doh.RoundRectListTests";
+	}
+
+	function _createListObjectDeclaratively(id) {
+		return registry.byId(id);
+	};
+	
+	function _createListObjectProgrammatically(placeHolderId){
+		var widget = new ListObject({select:"single"});
+		runner.assertNotEqual(null, widget);
+		var item = new ListItem({label:ITEM_LABEL + " 1", checked:true});
+		widget.addChild(item);
+		item = new ListItem({label:ITEM_LABEL + " 2"});
+		widget.addChild(item);
+		domConst.place(widget.domNode, placeHolderId, "replace");
+		widget.startup();
+		return widget;
+	};
+	
+	function _createListObjectProgrammaticallyWithSourceNodeReference(id){
+		var list = new ListObject({select:"single"}, id);
+		var item = new ListItem({label:ITEM_LABEL + " 1", checked:true});
+		list.addChild(item);
+		item = new ListItem({label:ITEM_LABEL + " 2"});
+		list.addChild(item);
+		list.startup();
+		return list;
+	};
+
+	function _assertCorrectListObject(list){
+		runner.assertNotEqual(null, list);
+		var children = list.getChildren();
+		var length = children.length;
+		runner.assertEqual(2, length, list.toString());
+		runner.assertTrue(children[0].checked, children[0].toString());
+	};
+	
+	function _showView2(){
+		var view1 = registry.byId("view1");
+		view1.performTransition("view2", 1, "none");
+	};
+
+	ready(function(){
+		runner.register("dojox.mobile.test.doh.EdgeToEdgeListTests", [
+			function testInView1(){
+				var list1 = _createListObjectDeclaratively("view1-list1");
+				var list2 = _createListObjectProgrammatically("view1-list2");
+				var list3 = _createListObjectProgrammaticallyWithSourceNodeReference("view1-list3");
+		
+				_assertCorrectListObject(list1);
+				_assertCorrectListObject(list2);
+				_assertCorrectListObject(list3);
+			},
+			function testInView2(){
+				var list1 = _createListObjectDeclaratively("view2-list1");
+				var list2 = _createListObjectProgrammatically("view2-list2");
+				var list3 = _createListObjectProgrammaticallyWithSourceNodeReference("view2-list3");
+				
+				_showView2();
+				
+				_assertCorrectListObject(list1);
+				_assertCorrectListObject(list2);
+				_assertCorrectListObject(list3);
+			}
+		]);
+		runner.run();
+	});
+})
diff --git a/dojox/mobile/tests/doh/MblCSS3TransitionTests.html b/dojox/mobile/tests/doh/MblCSS3TransitionTests.html
new file mode 100644
index 0000000..af6f29c
--- /dev/null
+++ b/dojox/mobile/tests/doh/MblCSS3TransitionTests.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+        <head>
+        <title>ICS Bug</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        <meta name="viewport"
+                content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+        <meta name="apple-mobile-web-app-capable" content="yes" />
+        <script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="mblCSS3Transition:'dojox/css3/transit', parseOnLoad:true, async:true"></script>
+		<script language="JavaScript" type="text/javascript">
+			require([
+				"dijit/registry",  // dijit.byId
+				"doh/runner",	//doh functions
+				"dojo/ready",
+				"dojo/dom",
+				"dojox/mobile",
+				"dojox/mobile/deviceTheme",
+				"dojox/mobile/parser"], function(registry, runner, ready, dom){
+		
+				ready(function(){
+ 					runner.register("dojox.mobile.test.doh.MBLCSS3TransitionTests", [
+						{
+							name: "Verify ticket #16592 is fixed",
+							timeout: 10000,
+							setUp: function() {
+								this.data = {runner: runner, view2: dom.byId("view2")};
+							},
+							runTest: function(){
+								var d = new runner.Deferred();
+								// verify there is no padding top on the second view
+								runner.assertFalse(this.data.view2.style.paddingTop, "No padding top value expected for view2 before transition");
+								registry.byId("slideItem")._onClick({});
+								setTimeout(d.getTestCallback(function(){
+									var pt = this.fixture.data.view2.style.paddingTop;
+									this.fixture.data.runner.assertFalse(!!pt, "No value was expected for padding top after transition (" + pt + " observed)");
+								}), 2000);
+								return d;
+							}
+						}]);
+					runner.run();
+				});
+			})
+		</script>
+        </head>
+        <body style="visibility:hidden;">
+        		<!-- Views for test "Verify ticket #16592 is fixed" -->
+                <div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+                        <ul data-dojo-type="dojox.mobile.RoundRectList">
+                                <li id="slideItem"
+                                	data-dojo-type="dojox.mobile.ListItem"
+                                        moveTo="view2"
+                                        transition="slide">Slide this view</li>
+                        </ul>
+                </div>
+                <div id="view2" data-dojo-type="dojox.mobile.View">
+                        <h1 data-dojo-type="dojox.mobile.Heading" back="Back"
+                                moveTo="view1">View 2</h1>
+                </div>
+                <!-- End of views for test "Verify ticket #16592 is fixed" -->
+                
+        </body>
+</html>
diff --git a/dojox/mobile/tests/doh/MyDataHandler.js b/dojox/mobile/tests/doh/MyDataHandler.js
new file mode 100644
index 0000000..f3b84a3
--- /dev/null
+++ b/dojox/mobile/tests/doh/MyDataHandler.js
@@ -0,0 +1,18 @@
+define([
+	"dojo/_base/declare",
+	"dojox/mobile/dh/DataHandler"
+], function(declare, DataHandler){
+
+	// module:
+	//		dojox/mobile/tests/doh/MyDataHandler
+	// summary:
+
+	return declare("dojox.mobile.tsets.doh.DataHandler", DataHandler, {
+
+		constructor: function(){
+			console.log("This is MyDataHandler");
+			window._MyDataHandlerFlag = true;
+			this.inherited(arguments);
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/mobile/tests/doh/MyDataSource.js b/dojox/mobile/tests/doh/MyDataSource.js
new file mode 100644
index 0000000..5701d13
--- /dev/null
+++ b/dojox/mobile/tests/doh/MyDataSource.js
@@ -0,0 +1,13 @@
+define([
+	"dojo/_base/declare",
+	"dojox/mobile/dh/UrlDataSource"
+], function(declare, UrlDataSource){
+
+	return declare("dojox.mobile.tests.doh.MyDataSource", UrlDataSource, {
+		constructor: function(){
+			console.log("This is MyDataSource");
+			window._MyDataSourceFlag = true;
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dojox/mobile/tests/doh/MyFileTypeMap.js b/dojox/mobile/tests/doh/MyFileTypeMap.js
new file mode 100644
index 0000000..aace7c5
--- /dev/null
+++ b/dojox/mobile/tests/doh/MyFileTypeMap.js
@@ -0,0 +1,27 @@
+define([
+	"dojo/_base/lang"
+], function(lang){
+
+	var o = lang.getObject("dojox.mobile.tests.doh.MyFileTypeMap", true);
+
+	o.map = {
+		"html": "html",
+		"json": "json",
+		"mydata": "json"
+	};
+
+	o.add = function(/*String*/ key, /*String*/ contentType){
+		this.map[key] = contentType;
+	};
+
+	o.getContentType = function(/*String*/ fileName){
+		var fileType = (fileName || "").replace(/.*\./, "");
+		return this.map[fileType];
+	};
+	
+	console.log("This is MyFileTypeMap");
+	window._MyFileTypeMapFlag = true;
+
+	return o;
+
+});
\ No newline at end of file
diff --git a/dojox/mobile/tests/doh/README b/dojox/mobile/tests/doh/README
new file mode 100644
index 0000000..a0c2eb1
--- /dev/null
+++ b/dojox/mobile/tests/doh/README
@@ -0,0 +1,16 @@
+DOH tests for Dojo Mobile.
+
+All tests are dispatched into sub module. each module has the name of the dojox.mobile class it tests, except for:
+* transition, that globally test the transitions;
+* templating, that test the templates support for widgets and views.
+
+To run all tests, launch dojox/mobile/tests/doh/runTests.html in the target browser.
+To launch the tests for one module, launch dojox/mobile/tests/doh/module_name/runTests.html 
+in the target browser.
+
+Notes: 
+1. Before running the tests, you need to ensure the browser zoom is at 1:1. This 
+   impacts some of the tests which perform dimensional checks.
+2. When running in IE, the following tests: ButtonsTests.html, ExpandingTextAreaTests.html, and 
+   TextAreaTests.html, the dimensional checks are calibrated for execution in IE9, 
+   and the checks are skipped in older IE versions.   
diff --git a/dojox/mobile/tests/doh/RoundRect.html b/dojox/mobile/tests/doh/RoundRect.html
deleted file mode 100644
index ece544c..0000000
--- a/dojox/mobile/tests/doh/RoundRect.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Round Rect</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-	        dojo.require("doh.runner");
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.RoundRect", [
-					{
-						name: "RoundRect Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_RoundRect_0");
-								if(dojo.isIE){
-									doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
-								}else{
-									doh.assertEqual('mblRoundRect mblShadow', demoWidget.domNode.className);
-								}
-
-								demoWidget = dijit.byId("dojox_mobile_RoundRect_1");
-								doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
-							}));
-							return d;
-						}
-					},
-					{
-						name: "Set",
-						timeout: 4000,
-						runTest: function(){
-							var demoWidget = dijit.byId("dojox_mobile_RoundRect_0");
-							demoWidget.set({shadow :false});
-
-							demoWidget.set({shadow :false});
-//							doh.assertFalse(demoWidget.get("shadow"));
-//							doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Round Rectangle</h2>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				This module provides some widgets that can be used to build web-based
-				applications for mobile devices such as iPhone or Android.
-			</div>
-			<div dojoType="dojox.mobile.RoundRect">
-				This module provides some widgets that can be used to build web-based
-				applications for mobile devices such as iPhone or Android.
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/RoundRectDataList.html b/dojox/mobile/tests/doh/RoundRectDataList.html
deleted file mode 100644
index f8a6fb6..0000000
--- a/dojox/mobile/tests/doh/RoundRectDataList.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>RoundRectDataList</title>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.data.ItemFileWriteStore");
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.RoundRectDataList");
-
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-			var static_data = { 
-				items: [ 
-					{label: "Apple", 	moveTo: "dummy"},
-					{label: "Banana", 	moveTo: "dummy"},
-					{label: "Cherry", 	moveTo: "dummy"},
-					{label: "Grape", 	moveTo: "dummy"},
-					{label: "Kiwi", 	moveTo: "dummy"},
-					{label: "Lemon", 	moveTo: "dummy"},
-					{label: "Melon", 	moveTo: "dummy"},
-					{label: "Orange", 	moveTo: "dummy"},
-					{label: "Peach", 	moveTo: "dummy"}
-				]
-			};
-			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
-			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
-			var store = store1;
-			var newItems = [[],[]];
-
-			// switch to the selected store
-			function switchTo(store){
-				window.store = store;
-				dijit.byId("list").setStore(store);
-			}
-			// add a new item
-			function add1(){
-				var item = store.newItem({label: "New Item", moveTo: "dummy"});
-				this.newItems[(store == store1) ? 1 : 0].push(item);
-			}
-			// delete the added item
-			function delete1(){
-				var item = this.newItems[(store == store1) ? 1 : 0].pop();
-				if(item){
-					store.deleteItem(item);
-				}
-			}
-		</script>
-
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script type="text/javascript" src="RoundRectDataList.js"></script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">RoundRectDataList</h1>
-			<ul dojoType="dojox.mobile.RoundRectDataList" id="list" store="store" query="{label: '*'}"></ul>
-			<h1 dojoType="dojox.mobile.Heading">RoundRectDataList</h1>
-			<p>show the different set:<br>
-			<input type="button" value="Set1" onclick="switchTo(store1)">
-			<input type="button" value="Set2" onclick="switchTo(store2)">
-			<p>alter the object store:<br>
-			<input type="button" value="Add" onclick="add1()">
-			<input type="button" value="Delete" onclick="delete1()">
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/RoundRectDataList_Programmatic.html b/dojox/mobile/tests/doh/RoundRectDataList_Programmatic.html
deleted file mode 100644
index 5068448..0000000
--- a/dojox/mobile/tests/doh/RoundRectDataList_Programmatic.html
+++ /dev/null
@@ -1,77 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>RoundRectDataList</title>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.data.ItemFileWriteStore");
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.RoundRectDataList");
-
-	        dojo.require("doh.runner");
-
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-			var static_data = { 
-				items: [ 
-					{label: "Apple", 	moveTo: "dummy"},
-					{label: "Banana", 	moveTo: "dummy"},
-					{label: "Cherry", 	moveTo: "dummy"},
-					{label: "Grape", 	moveTo: "dummy"},
-					{label: "Kiwi", 	moveTo: "dummy"},
-					{label: "Lemon", 	moveTo: "dummy"},
-					{label: "Melon", 	moveTo: "dummy"},
-					{label: "Orange", 	moveTo: "dummy"},
-					{label: "Peach", 	moveTo: "dummy"}
-				]
-			};
-			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
-			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
-			var store = store1;
-			var newItems = [[],[]];
-
-			// switch to the selected store
-			function switchTo(store){
-				window.store = store;
-				dijit.byId("list").setStore(store);
-			}
-			// add a new item
-			function add1(){
-				var item = store.newItem({label: "New Item", moveTo: "dummy"});
-				this.newItems[(store == store1) ? 1 : 0].push(item);
-			}
-			// delete the added item
-			function delete1(){
-				var item = this.newItems[(store == store1) ? 1 : 0].pop();
-				if(item){
-					store.deleteItem(item);
-				}
-			}
-
-			dojo.addOnLoad(function(){
-				var view = dijit.byId("foo");
-				var demoWidget = new dojox.mobile.RoundRectDataList({id:"list", store:store, query:{label: '*'}});
-				view.addChild(demoWidget);
-			});
-		</script>
-
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script type="text/javascript" src="RoundRectDataList.js"></script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">RoundRectDataList</h1>
-			<p>show the different set:<br>
-			<input type="button" value="Set1" onclick="switchTo(store1)">
-			<input type="button" value="Set2" onclick="switchTo(store2)">
-			<p>alter the object store:<br>
-			<input type="button" value="Add" onclick="add1()">
-			<input type="button" value="Delete" onclick="delete1()">
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/RoundRectList.html b/dojox/mobile/tests/doh/RoundRectList.html
deleted file mode 100644
index 78e8610..0000000
--- a/dojox/mobile/tests/doh/RoundRectList.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Round Rect List</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-//			dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script type="text/javascript" src="RoundRectList.js"></script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
-			<h2 id="Category" dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="item1" dojoType="dojox.mobile.ListItem" icon="../images/i-icon-1.png" rightText="Off" moveTo="bar">u1space</li>
-				<li id="item2" dojoType="dojox.mobile.ListItem" icon="../images/i-icon-2.png" rightText="On" moveTo="bar">u2space</li>
-				<li id="item3" dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="bar">Wi-Fi</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="foo">u1space</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
-			<ul dojoType="dojox.mobile.RoundRectList" transition="fade">
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="foo">Video</li>
-				<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-1.png" rightText="VPN">Maps</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">Phone Number</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/RoundRectList.js b/dojox/mobile/tests/doh/RoundRectList.js
deleted file mode 100644
index 099b1f9..0000000
--- a/dojox/mobile/tests/doh/RoundRectList.js
+++ /dev/null
@@ -1,71 +0,0 @@
-
-dojo.addOnLoad(function(){
-	doh.register("dojox.mobile.test.doh.RoundRectList", [
-		{
-			name: "RoundRectList Verification",
-			timeout: 4000,
-			runTest: function(){
-				var d = new doh.Deferred();
-				setTimeout(d.getTestCallback(function(){
-					var demoWidget = dijit.byId("Category");
-					doh.assertEqual('mblRoundRectCategory', demoWidget.domNode.className);
-					doh.assertEqual('Spaces', demoWidget.domNode.innerHTML);
-
-					demoWidget = dijit.byId("dojox_mobile_RoundRectList_0");
-					doh.assertEqual('mblRoundRectList', demoWidget.domNode.className);
-					verifyListItem("item1", 'u1space', 'Off', "mblDomButtonArrow", true, true, false);
-					verifyListItem("item2", 'u2space', 'On', "mblDomButtonArrow", true, true, false);
-					verifyListItem("item3", 'Wi-Fi', 'Off', "mblDomButtonArrow", false, true, false);
-					
-				}));
-				return d;
-			}
-		},
-		{
-			name: "RoundRectList Verification2",
-			timeout: 1000,
-			runTest: function(){
-				var d = new doh.Deferred();
-				var demoWidget = dijit.byId("dojox_mobile_RoundRectList_0");
-				demoWidget.set({transition :"flip"});
-				doh.assertEqual("flip", demoWidget.get("transition"));
-				demoWidget.set({transition :"fade"});
-				doh.assertEqual("fade", demoWidget.get("transition"));
-
-				fireOnClick("item3");
-				var view = dijit.byId("foo");
-				dojo.connect(view, "onAfterTransitionOut", this, d.getTestCallback(function(){
-					var demoWidget = dijit.byId("dojox_mobile_RoundRectCategory_0");
-					doh.assertEqual('mblRoundRectCategory', demoWidget.domNode.className);
-					doh.assertEqual('Applications', demoWidget.domNode.innerHTML);
-
-					demoWidget = dijit.byId("dojox_mobile_RoundRectList_1");
-					doh.assertEqual('mblRoundRectList', demoWidget.domNode.className);
-
-					verifyListItem("dojox_mobile_ListItem_0", 'Video', 'Off', "", false, true, false);
-					verifyListItem("dojox_mobile_ListItem_1", 'Maps', 'VPN', "", true, false, false);
-					verifyListItem("dojox_mobile_ListItem_2", 'Phone Number', 'Off', "", false, false, false);
-				}));
-				return d;
-			}
-		},
-		{
-			name: "RoundRectCategory getLabel",
-			timeout: 1000,
-			runTest: function(){
-				doh.assertEqual("Spaces", dijit.byId("Category").get("label")); 
-			}
-		},
-		{
-			name: "RoundRectCategory setLabel",
-			timeout: 1000,
-			runTest: function(){
-				var demoWidget = dijit.byId("Category");
-				demoWidget.set({label :"Value Changed"});
-				doh.assertEqual("Value Changed", demoWidget.get("label"));
-				doh.assertEqual('Value Changed', demoWidget.domNode.innerHTML);
-			}
-		}
-	]);
-	doh.run();
-});
diff --git a/dojox/mobile/tests/doh/RoundRectList_Programmatic.html b/dojox/mobile/tests/doh/RoundRectList_Programmatic.html
deleted file mode 100644
index 9f98e04..0000000
--- a/dojox/mobile/tests/doh/RoundRectList_Programmatic.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Round Rect List</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-//			dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				var view = dijit.byId("foo");
-				var demoWidget = new dojox.mobile.RoundRectList();
-				view.addChild(demoWidget);
-
-				var childWidget = new dojox.mobile.ListItem({id:"item1", icon:"../images/i-icon-1.png", rightText:"Off", moveTo:"bar", label:"u1space"});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ListItem({id:"item2", icon:"../images/i-icon-2.png", rightText:"On", moveTo:"bar",label:"u2space"});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ListItem({id:"item3"});
-				demoWidget.addChild(childWidget);
-				childWidget.set({rightText:"Off", moveTo:"bar", label :"Wi-Fi"});
-
-				view = dijit.byId("bar");
-				demoWidget = new dojox.mobile.RoundRectList();
-				view.addChild(demoWidget);
-
-				childWidget = new dojox.mobile.ListItem({rightText:"Off", label:"Video"});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ListItem({icon:"../images/i-icon-1.png", rightText:"VPN", label:"Maps"});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ListItem({rightText:"Off", label:"Phone Number"});
-				demoWidget.addChild(childWidget);
-			});
-		</script>
-		</script>
-
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script type="text/javascript" src="RoundRectList.js"></script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
-			<h2 id="Category" dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
-			<ul id="RoundRectList1" dojoType="dojox.mobile.RoundRectList">
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="foo">u1space</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/RoundRect_Programmatic.html b/dojox/mobile/tests/doh/RoundRect_Programmatic.html
deleted file mode 100644
index fee850e..0000000
--- a/dojox/mobile/tests/doh/RoundRect_Programmatic.html
+++ /dev/null
@@ -1,70 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Round Rect</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-	        dojo.require("doh.runner");
-			dojo.addOnLoad(function(){
-				var view = dijit.byId("foo");
-				var demoWidget = new dojox.mobile.RoundRect({shadow:"true"});
-				demoWidget.domNode.appendChild(dojo.doc.createTextNode("This module provides some widgets that can be used to build web-based applications for mobile devices such as iPhone or Android."));
-				view.addChild(demoWidget);
-
-				demoWidget = new dojox.mobile.RoundRect();
-				demoWidget.domNode.appendChild(dojo.doc.createTextNode("This module provides some widgets that can be used to build web-based applications for mobile devices such as iPhone or Android."));
-				view.addChild(demoWidget);
-
-				doh.register("dojox.mobile.test.doh.RoundRect", [
-					{
-						name: "RoundRect Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_RoundRect_0");
-								if(dojo.isIE){
-									doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
-								}else{
-									doh.assertEqual('mblRoundRect mblShadow', demoWidget.domNode.className);
-								}
-
-								demoWidget = dijit.byId("dojox_mobile_RoundRect_1");
-								doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
-							}));
-							return d;
-						}
-					},
-					{
-						name: "Set",
-						timeout: 4000,
-						runTest: function(){
-							var demoWidget = dijit.byId("dojox_mobile_RoundRect_0");
-							demoWidget.set({shadow :false});
-
-							demoWidget.set({shadow :false});
-//							doh.assertFalse(demoWidget.get("shadow"));
-//							doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Round Rectangle</h2>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/Switch.html b/dojox/mobile/tests/doh/Switch.html
deleted file mode 100644
index c52b661..0000000
--- a/dojox/mobile/tests/doh/Switch.html
+++ /dev/null
@@ -1,143 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Switch</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<style>
-		.color1 .mblSwitchBgLeft {
-			background: -webkit-gradient(linear, left top, left bottom, from(#28B159), to(#75FBAC), color-stop(0.5, #3FEB84), color-stop(0.5, #4CEE8E));
-		}
-		.color1 .mblSwitchBgRight {
-			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
-		}
-		.color2 .mblSwitchBgLeft {
-			background: -webkit-gradient(linear, left top, left bottom, from(#FF9D00), to(#FFCE80), color-stop(0.5, #FFBB4D), color-stop(0.5, #FFC871));
-		}
-		.color2 .mblSwitchBgRight {
-			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
-		}
-		.color1 .mblSwitchKnob,
-		.color2 .mblSwitchKnob {
-			background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#FAFAFA), color-stop(0.5, #BBBBBB), color-stop(0.5, #CACACA));
-		}
-		.float {
-			float: left;
-			margin-right: 10px;
-		}
-		.bold {
-			font-weight: bold;
-		}
-		</style>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-	        dojo.require("doh.runner");
-
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.Switch", [
-					{
-						name: "Switch Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_Switch_0");
-								doh.assertTrue(demoWidget.domNode.className.search(/mblSwitch/i) != -1);
-								doh.assertTrue(demoWidget.domNode.className.search(/mblSwitchOff/i) != -1);
-								doh.assertTrue(demoWidget.domNode.className.search(/float/i) != -1);
-								doh.assertEqual('mblSwitchInner', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblSwitchBg mblSwitchBgLeft', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('none', demoWidget.domNode.childNodes[0].childNodes[0].style.display);
-								doh.assertEqual('mblSwitchText mblSwitchTextLeft', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className);
-								doh.assertEqual('ON', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblSwitchBg mblSwitchBgRight', demoWidget.domNode.childNodes[0].childNodes[1].className);
-								doh.assertEqual('mblSwitchText mblSwitchTextRight', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].className);
-								doh.assertEqual('OFF', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].innerHTML);
-								doh.assertEqual('mblSwitchKnob', demoWidget.domNode.childNodes[0].childNodes[2].className);
-
-								demoWidget = dijit.byId("dojox_mobile_Switch_1");
-								doh.assertEqual('mblSwitch mblSwitchOn', demoWidget.domNode.className);
-								doh.assertEqual('mblSwitchInner', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblSwitchBg mblSwitchBgLeft', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('mblSwitchText mblSwitchTextLeft', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className);
-								doh.assertEqual('Start', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblSwitchBg mblSwitchBgRight', demoWidget.domNode.childNodes[0].childNodes[1].className);
-								doh.assertEqual('none', demoWidget.domNode.childNodes[0].childNodes[1].style.display);
-								doh.assertEqual('mblSwitchText mblSwitchTextRight', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].className);
-								doh.assertEqual('Stop', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].innerHTML);
-								doh.assertEqual('mblSwitchKnob', demoWidget.domNode.childNodes[0].childNodes[2].className);
-								
-							}));
-							return d;
-						}
-					},
-					{
-						name: "Switch set",
-						timeout: 1000,
-						runTest: function(){
-							var demoWidget = dijit.byId("dojox_mobile_Switch_0");
-							demoWidget.set({value :"on"});
-							doh.assertEqual("on", demoWidget.get("value"));
-//							doh.assertEqual('none', demoWidget.domNode.childNodes[0].childNodes[1].style.display);
-						}
-					},
-					{
-						name: "Switch set",
-						timeout: 1000,
-						runTest: function(){
-							var demoWidget = dijit.byId("dojox_mobile_Switch_0");
-							demoWidget.set({leftLabel :"Start", rightLabel:"Stop"});
-							doh.assertEqual("Start", demoWidget.get("leftLabel"));
-							doh.assertEqual("Stop", demoWidget.get("rightLabel"));
-							doh.assertEqual('Start', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].innerHTML);
-							doh.assertEqual('Stop', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].innerHTML);
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body style="padding:15px;visibility:visible">
-		<div dojoType="dojox.mobile.View" selected="true">
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Default Shape</span><br>
-				<div class="float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Round Shape 1</span><br>
-				<div class="mblSwRoundShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwRoundShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Round Shape 2</span><br>
-				<div class="mblSwRoundShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwRoundShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Arc Shape 1</span><br>
-				<div class="mblSwArcShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwArcShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Arc Shape 2</span><br>
-				<div class="mblSwArcShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwArcShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/Switch_Programmatic.html b/dojox/mobile/tests/doh/Switch_Programmatic.html
deleted file mode 100644
index e97f757..0000000
--- a/dojox/mobile/tests/doh/Switch_Programmatic.html
+++ /dev/null
@@ -1,126 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Switch</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<style>
-		.color1 .mblSwitchBgLeft {
-			background: -webkit-gradient(linear, left top, left bottom, from(#28B159), to(#75FBAC), color-stop(0.5, #3FEB84), color-stop(0.5, #4CEE8E));
-		}
-		.color1 .mblSwitchBgRight {
-			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
-		}
-		.color2 .mblSwitchBgLeft {
-			background: -webkit-gradient(linear, left top, left bottom, from(#FF9D00), to(#FFCE80), color-stop(0.5, #FFBB4D), color-stop(0.5, #FFC871));
-		}
-		.color2 .mblSwitchBgRight {
-			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
-		}
-		.color1 .mblSwitchKnob,
-		.color2 .mblSwitchKnob {
-			background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#FAFAFA), color-stop(0.5, #BBBBBB), color-stop(0.5, #CACACA));
-		}
-		.float {
-			float: left;
-			margin-right: 10px;
-		}
-		.bold {
-			font-weight: bold;
-		}
-		</style>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-	        dojo.require("doh.runner");
-
-			dojo.addOnLoad(function(){
-				var roundRect = dijit.byId("dojox_mobile_RoundRect_0");
-				var demoWidget = new dojox.mobile.Switch({value:"off"});
-				dojo.addClass(demoWidget.domNode, "float");
-				roundRect.addChild(demoWidget);
-				demoWidget = new dojox.mobile.Switch({value:"on", leftLabel:"Start", rightLabel:"Stop"});
-				roundRect.addChild(demoWidget);
-
-			
-				doh.register("dojox.mobile.test.doh.Switch", [
-					{
-						name: "Switch Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_Switch_0");
-								doh.assertTrue(demoWidget.domNode.className.search(/mblSwitch/i) != -1);
-								doh.assertTrue(demoWidget.domNode.className.search(/mblSwitchOff/i) != -1);
-								doh.assertTrue(demoWidget.domNode.className.search(/float/i) != -1);
-								doh.assertEqual('mblSwitchInner', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblSwitchBg mblSwitchBgLeft', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('none', demoWidget.domNode.childNodes[0].childNodes[0].style.display);
-								doh.assertEqual('mblSwitchText mblSwitchTextLeft', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className);
-								doh.assertEqual('ON', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblSwitchBg mblSwitchBgRight', demoWidget.domNode.childNodes[0].childNodes[1].className);
-								doh.assertEqual('mblSwitchText mblSwitchTextRight', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].className);
-								doh.assertEqual('OFF', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].innerHTML);
-								doh.assertEqual('mblSwitchKnob', demoWidget.domNode.childNodes[0].childNodes[2].className);
-
-								demoWidget = dijit.byId("dojox_mobile_Switch_1");
-								doh.assertEqual('mblSwitch mblSwitchOn', demoWidget.domNode.className);
-								doh.assertEqual('mblSwitchInner', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblSwitchBg mblSwitchBgLeft', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('mblSwitchText mblSwitchTextLeft', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className);
-								doh.assertEqual('Start', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].innerHTML);
-								doh.assertEqual('mblSwitchBg mblSwitchBgRight', demoWidget.domNode.childNodes[0].childNodes[1].className);
-								doh.assertEqual('none', demoWidget.domNode.childNodes[0].childNodes[1].style.display);
-								doh.assertEqual('mblSwitchText mblSwitchTextRight', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].className);
-								doh.assertEqual('Stop', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].innerHTML);
-								doh.assertEqual('mblSwitchKnob', demoWidget.domNode.childNodes[0].childNodes[2].className);
-								
-							}));
-							return d;
-						}
-					},
-					{
-						name: "Switch set",
-						timeout: 1000,
-						runTest: function(){
-							var demoWidget = dijit.byId("dojox_mobile_Switch_0");
-							demoWidget.set({value :"on"});
-							doh.assertEqual("on", demoWidget.get("value"));
-//							doh.assertEqual('none', demoWidget.domNode.childNodes[0].childNodes[1].style.display);
-						}
-					},
-					{
-						name: "Switch set",
-						timeout: 1000,
-						runTest: function(){
-							var demoWidget = dijit.byId("dojox_mobile_Switch_0");
-							demoWidget.set({leftLabel :"Start", rightLabel:"Stop"});
-							doh.assertEqual("Start", demoWidget.get("leftLabel"));
-							doh.assertEqual("Stop", demoWidget.get("rightLabel"));
-							doh.assertEqual('Start', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].innerHTML);
-							doh.assertEqual('Stop', demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].innerHTML);
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body style="padding:15px;visibility:visible">
-		<div dojoType="dojox.mobile.View" selected="true">
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Default Shape</span><br>
-			</div>
-
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/TabBar.html b/dojox/mobile/tests/doh/TabBar.html
deleted file mode 100644
index 4772fee..0000000
--- a/dojox/mobile/tests/doh/TabBar.html
+++ /dev/null
@@ -1,143 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>TabBar</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-		<style>
-		.label {
-			font-family: "Helvetica Neue", Helvetica;
-			font-size: 13px;
-			margin-top: 20px;
-		}
-		.view {
-			font-size: 30px;
-			margin-top: 30px;
-			text-align: center;
-		}
-		</style>
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.TabBar");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-			dojo.require("doh.runner");
-		</script>
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.TabBar", [
-					{
-						name: "TabBar and TabBarButton Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_TabBar_0");
-								doh.assertEqual('mblTabPanelHeader mblTabBarTop', demoWidget.domNode.className);
-
-								demoWidget = dijit.byId("dojox_mobile_TabBarButton_0");
-								doh.assertEqual('mblTabButton mblTabButtonSelected', demoWidget.domNode.className);
-								doh.assertEqual('mblTabBarButtonAnchor', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonDiv', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonIcon', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className);
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0].src.search(/tab-icon-16.png/i) != -1);
-								}
-								doh.assertEqual('hidden', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.visibility);
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].src.search(/tab-icon-16h.png/i) != -1);
-								}
-								doh.assertEqual('', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].style.visibility);
-								doh.assertEqual('New', dojo.trim(demoWidget.domNode.childNodes[0].childNodes[1].innerHTML));
-
-								demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-								doh.assertEqual('mblTabBar', demoWidget.domNode.className);
-
-								demoWidget = dijit.byId("dojox_mobile_TabBarButton_3");
-								doh.assertEqual('mblTabBarButton mblTabButtonSelected', demoWidget.domNode.className);
-								doh.assertEqual('mblTabBarButtonAnchor', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonDiv', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonIcon', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className);
-								doh.assertEqual('', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.display);
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0].src.search(/tab-icon-16.png/i) != -1);
-								}
-								doh.assertEqual('hidden', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.visibility);
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].src.search(/tab-icon-16h.png/i) != -1);
-								}
-								doh.assertEqual('', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].style.visibility);
-								doh.assertEqual('New', dojo.trim(demoWidget.domNode.childNodes[0].childNodes[1].innerHTML));
-
-								demoWidget = dijit.byId("dojox_mobile_TabBar_2");
-								doh.assertEqual('mblTabBar', demoWidget.domNode.className);
-
-								demoWidget = dijit.byId("dojox_mobile_TabBarButton_6");
-								doh.assertEqual('mblTabBarButton mblTabButtonSelected', demoWidget.domNode.className);
-								doh.assertEqual('mblTabBarButtonAnchor', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonDiv', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonIcon', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className);
-								doh.assertEqual('', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.display);
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0].src.search(/tab-icons.png/i) != -1);
-								}
-								doh.assertEqual('hidden', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.visibility);
-								verifyRect(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0], "0px", "29px", "29px", "0px");
-
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].src.search(/tab-icons.png/i) != -1);
-								}
-								doh.assertEqual('', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].style.visibility);
-
-								verifyRect(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0], "0px", "29px", "29px", "0px");
-								doh.assertEqual('Featured', dojo.trim(demoWidget.domNode.childNodes[0].childNodes[1].innerHTML));
-							}),500);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-		<div class="label">Segmented Control</div>
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-16.png" icon2="../images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-15.png" icon2="../images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-10.png" icon2="../images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar</div>
-		<ul dojoType="dojox.mobile.TabBar">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-16.png" icon2="../images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-15.png" icon2="../images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-10.png" icon2="../images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar (CSS Sprite)</div>
-		<ul dojoType="dojox.mobile.TabBar" iconBase="../images/tab-icons.png">
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Featured</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,29,29,29" iconPos2="29,29,29,29">Categories</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,58,29,29" iconPos2="29,58,29,29">Top 25</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,87,29,29" iconPos2="29,87,29,29">Search</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,116,29,29" iconPos2="29,116,29,29">Updates</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<div class="view">View 1</div>
-		</div>
-		<div id="view2" dojoType="dojox.mobile.View">
-			<div class="view">View 2</div>
-		</div>
-		<div id="view3" dojoType="dojox.mobile.View">
-			<div class="view">View 3</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/TabBar_Programmatic.html b/dojox/mobile/tests/doh/TabBar_Programmatic.html
deleted file mode 100644
index 527dfbc..0000000
--- a/dojox/mobile/tests/doh/TabBar_Programmatic.html
+++ /dev/null
@@ -1,161 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>TabBar</title>
-		<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-		<style>
-		.label {
-			font-family: "Helvetica Neue", Helvetica;
-			font-size: 13px;
-			margin-top: 20px;
-		}
-		.view {
-			font-size: 30px;
-			margin-top: 30px;
-			text-align: center;
-		}
-		</style>
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.TabBar");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				dojo.create("div", {className:"label", innerHTML:"Segmented Control"}, dojo.doc.body);
-				var tabBar = new dojox.mobile.TabBar({barType:"segmentedControl"});
-				dojo.doc.body.appendChild(tabBar.domNode);
-				tabBar.startup();
-				var tabBarButton = new dojox.mobile.TabBarButton({icon1:"../images/tab-icon-16.png", icon2:"../images/tab-icon-16h.png", moveTo:"view1", selected:"true", label:"New"});
-				tabBar.addChild(tabBarButton);
-				tabBarButton = new dojox.mobile.TabBarButton({icon1:"../images/tab-icon-15.png", icon2:"../images/tab-icon-15h.png", moveTo:"view2", label:"What's Hot"});
-				tabBar.addChild(tabBarButton);
-				tabBarButton = new dojox.mobile.TabBarButton({icon1:"../images/tab-icon-10.png", icon2:"../images/tab-icon-10h.png", moveTo:"view3", label:"Genius"});
-				tabBar.addChild(tabBarButton);
-
-				dojo.create("div", {className:"label", innerHTML:"Tab Bar"}, dojo.doc.body);
-				tabBar = new dojox.mobile.TabBar();
-				tabBarButton = new dojox.mobile.TabBarButton({icon1:"../images/tab-icon-16.png", icon2:"../images/tab-icon-16h.png", moveTo:"view1", selected:"true", label:"New"});
-				tabBar.addChild(tabBarButton);
-				tabBarButton = new dojox.mobile.TabBarButton({icon1:"../images/tab-icon-15.png", icon2:"../images/tab-icon-15h.png", moveTo:"view2", label:"What's Hot"});
-				tabBar.addChild(tabBarButton);
-				tabBarButton = new dojox.mobile.TabBarButton({icon1:"../images/tab-icon-10.png", icon2:"../images/tab-icon-10h.png", moveTo:"view3", label:"Genius"});
-				tabBar.addChild(tabBarButton);
-				dojo.doc.body.appendChild(tabBar.domNode);
-				tabBar.startup();
-
-				dojo.create("div", {className:"label", innerHTML:"Tab Bar (CSS Sprite)"}, dojo.doc.body);
-				tabBar = new dojox.mobile.TabBar({iconBase:"../images/tab-icons.png"});
-				dojo.doc.body.appendChild(tabBar.domNode);
-				tabBarButton = new dojox.mobile.TabBarButton({iconPos1:"0,0,29,29", iconPos2:"29,0,29,29", selected:"true", label:"Featured"});
-				tabBar.addChild(tabBarButton);
-				tabBarButton = new dojox.mobile.TabBarButton({iconPos1:"0,29,29,29", iconPos2:"29,29,29,29", label:"Categories"});
-				tabBar.addChild(tabBarButton);
-				tabBarButton = new dojox.mobile.TabBarButton({iconPos1:"0,58,29,29", iconPos2:"29,58,29,29", label:"Top 25"});
-				tabBar.addChild(tabBarButton);
-				tabBarButton = new dojox.mobile.TabBarButton({iconPos1:"0,87,29,29", iconPos2:"29,87,29,29", label:"Search"});
-				tabBar.addChild(tabBarButton);
-				tabBarButton = new dojox.mobile.TabBarButton({iconPos1:"0,116,29,29", iconPos2:"29,116,29,29", label:"Updates"});
-				tabBar.addChild(tabBarButton);
-				tabBar.startup();
-
-				var view = new dojox.mobile.View({id:"view1", selected:"true", innerHTML:'<div class="view">View 1</div>'});
-				dojo.doc.body.appendChild(view.domNode);
-				view.startup();
-
-				view = new dojox.mobile.View({id:"view2", innerHTML:'<div class="view">View 2</div>'});
-				dojo.doc.body.appendChild(view.domNode);
-				view.startup();
-
-				view = new dojox.mobile.View({id:"view3", innerHTML:'<div class="view">View 3</div>'});
-				dojo.doc.body.appendChild(view.domNode);
-				view.startup();
-			});
-		</script>
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.doh.TabBar", [
-					{
-						name: "TabBar and TabBarButton Verification",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								var demoWidget = dijit.byId("dojox_mobile_TabBar_0");
-								doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabPanelHeader'));
-
-								demoWidget = dijit.byId("dojox_mobile_TabBarButton_0");
-								doh.assertEqual('mblTabButton mblTabButtonSelected', demoWidget.domNode.className);
-								doh.assertEqual('mblTabBarButtonAnchor', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonDiv', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonIcon', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className);
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0].src.search(/tab-icon-16.png/i) != -1);
-								}
-								doh.assertEqual('hidden', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.visibility);
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].src.search(/tab-icon-16h.png/i) != -1);
-								}
-								doh.assertEqual('', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].style.visibility);
-								doh.assertEqual('New', dojo.trim(demoWidget.domNode.childNodes[0].childNodes[1].innerHTML));
-
-								demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-								doh.assertEqual('mblTabBar', demoWidget.domNode.className);
-
-								demoWidget = dijit.byId("dojox_mobile_TabBarButton_3");
-								doh.assertEqual('mblTabBarButton mblTabButtonSelected', demoWidget.domNode.className);
-								doh.assertEqual('mblTabBarButtonAnchor', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonDiv', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonIcon', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className);
-								doh.assertEqual('', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.display);
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0].src.search(/tab-icon-16.png/i) != -1);
-								}
-								doh.assertEqual('hidden', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.visibility);
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].src.search(/tab-icon-16h.png/i) != -1);
-								}
-								doh.assertEqual('', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].style.visibility);
-								doh.assertEqual('New', dojo.trim(demoWidget.domNode.childNodes[0].childNodes[1].innerHTML));
-
-								demoWidget = dijit.byId("dojox_mobile_TabBar_2");
-								doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBar'));
-
-								demoWidget = dijit.byId("dojox_mobile_TabBarButton_6");
-								doh.assertEqual('mblTabBarButton mblTabButtonSelected', demoWidget.domNode.className);
-								doh.assertEqual('mblTabBarButtonAnchor', demoWidget.domNode.childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonDiv', demoWidget.domNode.childNodes[0].childNodes[0].className);
-								doh.assertEqual('mblTabBarButtonIcon', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className);
-								doh.assertEqual('', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.display);
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0].src.search(/tab-icons.png/i) != -1);
-								}
-								doh.assertEqual('hidden', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.visibility);
-								verifyRect(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0], "0px", "29px", "29px", "0px");
-								if(!dojo.isIE) {
-									doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].src.search(/tab-icons.png/i) != -1);
-								}
-
-								doh.assertEqual('', demoWidget.domNode.childNodes[0].childNodes[0].childNodes[1].childNodes[0].style.visibility);
-								verifyRect(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0], "0px", "29px", "29px", "0px");
-								doh.assertEqual('Featured', dojo.trim(demoWidget.domNode.childNodes[0].childNodes[1].innerHTML));
-							}),500);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-	</head>
-	<body>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/TestHelper.js b/dojox/mobile/tests/doh/TestHelper.js
new file mode 100644
index 0000000..2459adb
--- /dev/null
+++ b/dojox/mobile/tests/doh/TestHelper.js
@@ -0,0 +1,52 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/sniff",
+	"dojo/dom-class",
+	"dijit/registry",
+	"doh/runner"
+], function(declare, lang, has, domClass, registry, runner){
+
+	// module:
+	//		dojox/mobile/tests/doh/TestHelper
+	// summary:
+	//		A DOH test Helper class
+
+	var TestHelper = new function(){
+
+		this.fireOnClick = function(obj){
+			var node;
+			if(typeof obj === "string"){
+				var widget = registry.byId(obj);
+				node = widget.domNode;
+			}else{
+				node = obj;
+			}
+			if (has("ie") >= 10){
+				this.fireOnEvent(node, "MSPointerDown");
+				this.fireOnEvent(node, "MSPointerUp");
+			}else{
+				this.fireOnEvent(node, "mousedown");
+				this.fireOnEvent(node, "mouseup");
+			}
+		};
+
+		this.fireOnEvent = function(node, evstr){
+			if(has("ie")<9){
+				node.fireEvent( "on" + evstr );
+			}else{
+				var e = document.createEvent('Events');
+				e.initEvent(evstr, true, true);
+				node.dispatchEvent(e);
+			}
+		};
+		this.verifyImageSrc = function(node, regExp, hintPrefix, hintSuffix) {
+			hintPrefix = hintPrefix || "";
+			hintSuffix = hintSuffix || "";
+			if(!has("ie") && regExp && node){
+				doh.assertTrue(node.src.search(regExp) != -1, hintPrefix + "search " + regExp.toString() + hintSuffix);
+			}
+		};
+	};
+	return TestHelper;
+});
diff --git a/dojox/mobile/tests/doh/TestURLProp.html b/dojox/mobile/tests/doh/TestURLProp.html
new file mode 100644
index 0000000..d6a771d
--- /dev/null
+++ b/dojox/mobile/tests/doh/TestURLProp.html
@@ -0,0 +1,214 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Ajax</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+	var timeoutInterval = 3000;
+		require([
+			"dojo/dom-construct", // dojo.place
+			"dojo/ready", // dojo.ready
+			"dijit/registry",  // dijit.byId
+			"dojox/mobile/tests/doh/TestHelper",
+			"doh/runner",	//doh functions
+			"dojox/mobile",				// This is a mobile app.
+			"dojox/mobile/View",		// This mobile app uses mobile view
+			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+			"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
+			"dojox/mobile/SpinWheel"
+		], function(domConst, ready, registry, TestHelper, runner){
+			ready(function(){
+				runner.register("dojox.mobile.test.doh.DataHandler", [
+					{
+						name: "DataHandlerding Verification1",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							TestHelper.fireOnClick("dojox_mobile_ListItem_0");
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("view1");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+								demoWidget = registry.byId("dojox_mobile_EdgeToEdgeList_0");
+								runner.assertNotEqual(null, demoWidget);
+
+								//Back to Home
+								TestHelper.fireOnClick("dojox_mobile_ToolBarButton_0");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "Home",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("home");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+
+								TestHelper.fireOnClick("dojox_mobile_ListItem_1");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "DataHandlerding Verification2",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("view2");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+								demoWidget = registry.byId("dojox_mobile_RoundRectCategory_1");
+								runner.assertNotEqual(null, demoWidget);
+
+								//Back to Home
+								TestHelper.fireOnClick("dojox_mobile_ListItem_8");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "Home2",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("home");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+
+								TestHelper.fireOnClick("dojox_mobile_ListItem_2");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "DataHandlerding Verification3",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("view3");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+								demoWidget = registry.byId("dojox_mobile_RoundRectList_2");
+								runner.assertNotEqual(null, demoWidget);
+
+								//Back to Home
+								TestHelper.fireOnClick("dojox_mobile_ListItem_13");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "Home3",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("home");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+
+								TestHelper.fireOnClick("dojox_mobile_ListItem_3");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "DataHandlerding Verification4",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("view4");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+								demoWidget = registry.byId("dojox_mobile_RoundRectCategory_3");
+								runner.assertNotEqual(null, demoWidget);
+
+								//Back to Home
+								TestHelper.fireOnClick("dojox_mobile_ToolBarButton_2");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "Home4",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("home");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+
+								TestHelper.fireOnClick("dojox_mobile_ListItem_4");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "DataHandlerding Verification5",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("view5");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+								demoWidget = registry.byId("spin1");
+								runner.assertNotEqual(null, demoWidget);
+							}), timeoutInterval);
+							return d;
+						}
+					}
+				]);
+				runner.run();
+			});
+		})
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Ajax (HTML)</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">External Views</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-1.png", transition:"slide", url:"data/view1.html"'>
+				External View #1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-2.png", transition:"flip", url:"data/view2.html"'>
+				External View #2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-3.png", transition:"fade", url:"data/view3.html"'>
+				External View #3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-4.png", transition:"slide", url:"data/view4.html"'>
+				External View #4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-5.png", transition:"slide", url:"data/view5.html"'>
+				External View #5
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/TestURLProp2.html b/dojox/mobile/tests/doh/TestURLProp2.html
new file mode 100644
index 0000000..85e6bb3
--- /dev/null
+++ b/dojox/mobile/tests/doh/TestURLProp2.html
@@ -0,0 +1,259 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Ajax</title>
+
+	<script type="text/javascript" src="../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+	var timeoutInterval = 3000;
+		require([
+			"dojo/dom-construct", // dojo.place
+			"dojo/ready", // dojo.ready
+			"dijit/registry",  // dijit.byId
+			"dojox/mobile/tests/doh/TestHelper",
+			"doh/runner",	//doh functions
+			"dojox/mobile/dh/SuffixFileTypeMap",
+			"dojox/mobile/dh/ContentTypeMap",
+			"dojox/mobile",				// This is a mobile app.
+			"dojox/mobile/View",		// This mobile app uses mobile view
+			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+			"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
+			"dojox/mobile/SpinWheel"
+		], function(domConst, ready, registry, TestHelper, runner, SuffixFileTypeMap, ContentTypeMap){
+			SuffixFileTypeMap.add('myjson','json');
+			ContentTypeMap.add('myhtml','dojox/mobile/dh/HtmlScriptContentHandler');
+			ready(function(){
+				runner.register("dojox.mobile.test.doh.DataHandler", [
+					{
+						name: "DataHandlerding Verification1",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							TestHelper.fireOnClick("dojox_mobile_ListItem_0");
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("view1");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+								demoWidget = registry.byId("dojox_mobile_RoundRectList_2");
+								runner.assertNotEqual(null, demoWidget);
+
+								//Back to Home
+								TestHelper.fireOnClick("dojox_mobile_ListItem_6");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "Home",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("home");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+
+								TestHelper.fireOnClick("dojox_mobile_ListItem_1");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "DataHandlerding Verification2",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("view2");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+								demoWidget = registry.byId("dojox_mobile_RoundRectCategory_1");
+								runner.assertNotEqual(null, demoWidget);
+								runner.assertEqual(window._MyDataHandlerFlag, true);
+
+								//Back to Home
+								TestHelper.fireOnClick("dojox_mobile_ListItem_12");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "Home2",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("home");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+
+								TestHelper.fireOnClick("dojox_mobile_ListItem_2");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "DataHandlerding Verification3",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("view3");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+								demoWidget = registry.byId("dojox_mobile_RoundRectList_2");
+								runner.assertNotEqual(null, demoWidget);
+								runner.assertEqual(window._MyFileTypeMapFlag, true);
+
+								//Back to Home
+								TestHelper.fireOnClick("dojox_mobile_ListItem_17");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "Home3",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("home");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+
+								TestHelper.fireOnClick("dojox_mobile_ListItem_3");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "DataHandlerding Verification4",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("view4");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+								demoWidget = registry.byId("dojox_mobile_RoundRectCategory_3");
+								runner.assertNotEqual(null, demoWidget);
+								runner.assertEqual(window._MyDataSourceFlag, true);
+
+								//Back to Home
+								TestHelper.fireOnClick("dojox_mobile_ToolBarButton_1");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "Home4",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("home");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+
+								TestHelper.fireOnClick("dojox_mobile_ListItem_4");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "DataHandlerding Verification5",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("view5");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+								demoWidget = registry.byId("dojox_mobile_EdgeToEdgeList_0");
+								runner.assertNotEqual(null, demoWidget);
+
+								//Back to Home
+								TestHelper.fireOnClick("dojox_mobile_ToolBarButton_2");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "Home5",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("home");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+
+								TestHelper.fireOnClick("dojox_mobile_ListItem_5");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "DataHandlerding Verification6",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget = registry.byId("view6");
+								var v = demoWidget.declaredClass;
+								runner.assertEqual('visible', demoWidget.domNode.style.visibility);
+								runner.assertEqual(window._ScriptInView6, true);
+
+							}), timeoutInterval);
+							return d;
+						}
+					}
+				]);
+				runner.run();
+			});
+		})
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Ajax (HTML)</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">External Views</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-1.png", transition:"slide", url:"data/view1.myjson"'>
+				External View #1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-2.png", transition:"flip", url:"data/view2.html", transitionOptions:{dataHandlerClass:"dojox/mobile/tests/doh/MyDataHandler"}'>
+				External View #2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-3.png", transition:"slide", url:"data/view3.mydata", transitionOptions:{fileTypeMapClass:"dojox/mobile/tests/doh/MyFileTypeMap"}'>
+				External View #3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-4.png", transition:"slide", url:"data/view4.html", transitionOptions:{dataSourceClass:"dojox/mobile/tests/doh/MyDataSource"}'>
+				External View #4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-5.png", transition:"slide", url:"data/view5.mydata2", transitionOptions:{contentType:"json"}'>
+				External View #5
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../images/i-icon-6.png", transition:"slide", url:"data/view6.myhtml", transitionOptions:{contentType:"myhtml"}'>
+				External View #6
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/TestUtil.js b/dojox/mobile/tests/doh/TestUtil.js
index de560ba..bb4f9b6 100644
--- a/dojox/mobile/tests/doh/TestUtil.js
+++ b/dojox/mobile/tests/doh/TestUtil.js
@@ -1,10 +1,32 @@
-dojo.require("doh.runner");
+//dojo.require("dojo.has");
+
+require([
+	"dijit/_base/manager",  // dijit.byId
+	"doh/runner"	//doh functions
+]);
+
+function fireOnInput(obj){
+	var anchorNode;
+	if(typeof obj === "string"){
+		var demoWidget = dijit.byId(obj);
+		anchorNode = demoWidget.domNode;
+	}else{
+		anchorNode = obj;
+	}
+	if(dojo.isIE<9){
+		anchorNode.fireEvent( "onpropertychange" );
+	}else{
+		var e = document.createEvent('Events');
+		e.initEvent('input', true, true);
+		anchorNode.dispatchEvent(e);
+	}
+}
 
 function fireOnClick(obj){
 	var anchorNode;
 	if(typeof obj === "string"){
 		var demoWidget = dijit.byId(obj);
-		anchorNode = demoWidget.anchorNode;
+		anchorNode = demoWidget.domNode;
 	}else{
 		anchorNode = obj;
 	}
@@ -17,48 +39,134 @@ function fireOnClick(obj){
 	}
 }
 
+function fireOnMouseDown(obj){
+	var anchorNode;
+	if(typeof obj === "string"){
+		var demoWidget = dijit.byId(obj);
+		anchorNode = demoWidget.domNode;
+	}else{
+		anchorNode = obj;
+	}
+	if(dojo.isIE<9){
+		anchorNode.fireEvent( "onmousedown" );
+	}else{
+		var eventName = "mousedown";
+		if (dojo.isIE >= 10){
+			eventName = "MSPointerDown";
+		}
+		var e = document.createEvent('Events');
+		e.initEvent(eventName, true, true);
+		anchorNode.dispatchEvent(e);
+	}
+}
+function fireOnMouseUp(obj){
+	var anchorNode;
+	if(typeof obj === "string"){
+		var demoWidget = dijit.byId(obj);
+		anchorNode = demoWidget.domNode;
+	}else{
+		anchorNode = obj;
+	}
+	if(dojo.isIE<9){
+		anchorNode.fireEvent( "onmouseup" );
+	}else{
+		var eventName = "mouseup";
+		if (dojo.isIE >= 10){
+			eventName = "MSPointerUp";
+		}
+		var e = document.createEvent('Events');
+		e.initEvent(eventName, true, true);
+		anchorNode.dispatchEvent(e);
+	}
+}
+
+function fireTouchEvent(eventtype, node, x, y){
+	var e;
+	if(dojo.isIE<9){
+		e = document.createEventObject(window.event);
+		e.button = 1;
+		e.pageX = x;
+		e.pageY = y;
+		node.fireEvent( "on" + eventtype[1], e );
+	}else{
+		e = document.createEvent('Events');
+		e.initEvent( dojo.has('touch') ? eventtype[0] : eventtype[1], true, true);
+		e.touches = [ { pageX: x, pageY: y } ];
+		e.pageX = x;
+		e.pageY = y;
+		e.changedTouches = e.touches;
+		node.dispatchEvent(e);
+	}
+}
+
+/*
+function fireTouchStart(node, x, y){
+	fireTouchEvent(["touchstart", "mousedown"], node, x, y);
+}
 
-function verifyListItem(id, text, rightText, domButtonType, hasIcon, hasRightIcon, hasIcon2, hasVariableHeight, regExp, hasSelected) {
-	demoWidget = dijit.byId(id);
-	doh.assertEqual('mblListItem' + (hasVariableHeight ?" mblVariableHeight":"") + (hasSelected ?" mblItemSelected":""), demoWidget.domNode.className);
-	var childNodes = demoWidget.domNode.childNodes;
-	doh.assertEqual('mblListItemAnchor' + (hasIcon?'':' mblListItemAnchorNoIcon'), childNodes[0].className);
+function fireTouchEnd(node, x, y){
+	fireTouchEvent(["touchend", "mouseup"], node, x, y);
+}
+
+function fireTouchMove(node, x, y){
+	fireTouchEvent(["touchmove", "mousemove"], node, x, y);
+}
+*/
+
+function verifyListItem(id, text, rightText, domButtonType, hasIcon, hasRightIcon, hasIcon2, hasVariableHeight, regExp, hasSelected, isSprite){
+	var demoWidget = dijit.byId(id);
+	doh.assertNotEqual(null, demoWidget, "ListItem: Did not instantiate. id=" + id);
+	doh.assertEqual('mblListItem' + (hasVariableHeight ?" mblVariableHeight":"") + (hasSelected ?" mblListItemSelected":""), demoWidget.domNode.className, "id=" + id);
+	var childNodes = demoWidget.domNode.children;
+//	doh.assertEqual('mblListItemAnchor' + (hasIcon?'':' mblListItemAnchorNoIcon'), childNodes[0].className);
 	
-	doh.assertEqual('A', childNodes[0].tagName);
+//	doh.assertEqual('A', childNodes[0].tagName);
 	
-	childNodes = childNodes[0].childNodes;
+//	childNodes = childNodes[0].childNodes;
 
 	var i=0;
 	if(hasIcon){
 		if(!dojo.isIE && regExp){
-			doh.assertTrue(childNodes[i].childNodes[0].src.search(regExp) != -1, "search " + regExp.toString());
+			if(isSprite){
+				doh.assertTrue(childNodes[i].childNodes[0].src.search(regExp) != -1, "search " + regExp.toString());
+			}else{
+				doh.assertTrue(childNodes[i].src.search(regExp) != -1, "search " + regExp.toString());
+			}
 		}
-		doh.assertEqual('mblListItemIcon', childNodes[i++].className);
+		doh.assertTrue(dojo.hasClass(childNodes[i], 'mblListItemIcon'), 'mblListItemIcon id=' + id + " got: " + childNodes[i].className);
+		i++;
 	}
 
 	if(hasRightIcon){
 		if(domButtonType){
-			doh.assertEqual(domButtonType + ' mblDomButton', childNodes[i].childNodes[0].className);
+			doh.assertEqual(domButtonType + ' mblDomButton', childNodes[i].childNodes[0].className, "id=" + id);
 		}
-		doh.assertEqual('mblListItemRightIcon', childNodes[i++].className);
+		doh.assertTrue(dojo.hasClass(childNodes[i], 'mblListItemRightIcon'), 'mblListItemRightIcon id=' + id + " got: " + childNodes[i].className);
+		i++;
 	}
 
 	if(hasIcon2){
-		doh.assertEqual('mblListItemRightIcon2', childNodes[i++].className);
+		doh.assertTrue(dojo.hasClass(childNodes[i], 'mblListItemRightIcon2'), 'mblListItemRightIcon2 id=' + id + " got: " + childNodes[i].className);
+		i++;
 	}
 
 	if(rightText){
-		doh.assertEqual(rightText, dojo.isFF ==3.6 ? childNodes[i].childNodes[0].innerHTML : childNodes[i].innerHTML); //2 0r 3
-		doh.assertEqual('mblListItemRightText', childNodes[i++].className);
+		doh.assertEqual(rightText, dojo.isFF ==3.6 ? childNodes[i].childNodes[0].innerHTML : childNodes[i].innerHTML, "id=" + id); //2 0r 3
+		doh.assertEqual('mblListItemRightText', childNodes[i++].className, "id=" + id);
+	}
+	if(!hasVariableHeight){
+		doh.assertEqual('mblListItemLabel', childNodes[i].className, "id=" + id);
+		doh.assertEqual('DIV', childNodes[i].tagName, "id=" + id);
+	}else{
+		doh.assertEqual('mblListItemLabel', childNodes[i+1].className, "id=" + id);
+		doh.assertEqual('DIV', childNodes[i+1].tagName, "id=" + id);
 	}
-	doh.assertEqual('mblListItemTextBox', childNodes[i].className);
-	doh.assertEqual('DIV', childNodes[i].tagName);
 
 	try{
-		doh.assertEqual(text, dojo.trim(childNodes[i].childNodes[0].innerHTML.replace(/\r\n/g,"")));
+		doh.assertEqual(text, dojo.trim(childNodes[i].innerHTML.replace(/\r\n|\n|\t/g,"")), "id=" + id);
 	} catch (e) {
 		if(dojo.isFF ==3.6){
-			doh.assertEqual(text, dojo.trim(childNodes[i].childNodes[0].childNodes[0].innerHTML.replace(/\r\n/g,"")));
+			doh.assertEqual(text, dojo.trim(childNodes[i].childNodes[0].innerHTML.replace(/\r\n|\n|\t/g,"")), "id=" + id);
 		}else{
 			throw e;
 		}
@@ -66,12 +174,18 @@ function verifyListItem(id, text, rightText, domButtonType, hasIcon, hasRightIco
 
 }
 
-function verifyListItemPos(id, rTop, rRight, rBottom, rLeft, sTop, sLeft) {
+function verifyListItemPos(id, rTop, rRight, rBottom, rLeft, sTop, sLeft, isSprite) {
 	var demoWidget = dijit.byId(id);
-	verifyRect(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0], rTop, rRight, rBottom, rLeft);
+	var node;
+	if(isSprite){
+		node = demoWidget.domNode.childNodes[0].childNodes[0];
+	}else{
+		node = demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0];
+	}
+	verifyRect(node, rTop, rRight, rBottom, rLeft);
 
-	doh.assertEqual(sTop, demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.top);
-	doh.assertEqual(sLeft, demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].style.left);
+	doh.assertEqual(sTop, node.style.top);
+	doh.assertEqual(sLeft, node.style.left);
 }
 
 function verifyRect(node, rTop, rRight, rBottom, rLeft) {
@@ -81,3 +195,53 @@ function verifyRect(node, rTop, rRight, rBottom, rLeft) {
 	doh.assertEqual(rBottom, rectArray[2]);
 	doh.assertEqual(rLeft+")", rectArray[3]);
 }
+
+function verifyIconItem(id, text, display, regExp, isSprite){
+	var demoWidget = dijit.byId(id);
+	if(!dojo.isIE && !dojo.isFF) {
+		if(isSprite){
+			doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0].src.search(regExp) != -1, "search " + regExp.toString() + " id=" +id);
+		}else{
+			doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(regExp) != -1, "search " + regExp.toString() + " id=" +id);
+		}
+	}
+	doh.assertEqual(text, demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue, "id=" +id);
+	doh.assertEqual(display, demoWidget.paneWidget.domNode.style.display, "id=" +id);
+	doh.assertEqual('mblIconItemPaneHeading', demoWidget.paneWidget.domNode.childNodes[0].className, "id=" +id);
+	doh.assertEqual('mblDomButtonBlueMinus mblDomButton', demoWidget.paneWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className, "id=" +id);
+	doh.assertEqual(text, demoWidget.paneWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue, "id=" +id);
+}
+
+function verifyTabBarButton(id, text, classNames, visibility1, visibility2, regExp1, regExp2, isSprite){
+	var demoWidget = dijit.byId(id);
+	for(var i = 0; i < classNames.length;i++){
+		doh.assertTrue(dojo.hasClass(demoWidget.domNode, classNames[i]), classNames[i] + " id=" +id + " className:"+demoWidget.domNode.className);
+	}
+	doh.assertEqual('mblTabBarButtonIconArea', demoWidget.domNode.childNodes[0].className, "id=" +id);
+	doh.assertEqual('mblTabBarButtonLabel', demoWidget.domNode.childNodes[1].className, "id=" +id);
+	if(demoWidget.iconNode1){
+		if(!dojo.isIE) {
+			if(isSprite){
+				doh.assertTrue(demoWidget.iconNode1.childNodes[0].src.search(regExp1) != -1, "search " + regExp1.toString() + " id=" +id);
+			}else{
+				doh.assertTrue(demoWidget.iconNode1.src.search(regExp1) != -1, "search " + regExp1.toString() + " id=" +id);
+			}
+		}
+//		doh.assertEqual(visibility1, demoWidget.iconNode1.style.visibility, "id=" +id);
+	}else{
+		console.log("There is no iconNode1. id=" + id);
+	}
+	if(demoWidget.iconNode2){
+		if(!dojo.isIE){
+			if(isSprite){
+				doh.assertTrue(demoWidget.iconNode2.childNodes[0].src.search(regExp2) != -1, "search " + regExp2.toString() + " id=" +id);
+			}else{
+				doh.assertTrue(demoWidget.iconNode2.src.search(regExp2) != -1, "search " + regExp2.toString() + " id=" +id);
+			}
+		}
+		doh.assertEqual(visibility2, demoWidget.iconNode2.style.visibility, "id=" +id);
+	}else{
+		console.log("There is no iconNode2. id=" + id);
+	}
+	doh.assertEqual(text, dojo.trim(demoWidget.labelNode.innerHTML), "id=" +id);
+}
diff --git a/dojox/mobile/tests/doh/ToggleButtonTests.html b/dojox/mobile/tests/doh/ToggleButtonTests.html
new file mode 100644
index 0000000..f55200d
--- /dev/null
+++ b/dojox/mobile/tests/doh/ToggleButtonTests.html
@@ -0,0 +1,95 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>ToggleButton Tests</title>
+<script type="text/javascript" src="../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	var BUTTON_LABEL = "Button";
+	var BUTTON_WIDTH = 73;
+	var BUTTON_WIDTH_IE = 81;
+	var BUTTON_HEIGHT = 27;
+	var BUTTON_HEIGHT_IE = 25;
+
+	require([
+		"dojo/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/ToggleButton",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(has, domConst, ready, registry, runner, ToggleButton){
+		function _createToggleButtonDeclaratively(buttonId) {
+			return registry.byId(buttonId);
+		}
+		function _createToggleButtonProgrammatically(placeHolderId){
+			var button = new ToggleButton({label:BUTTON_LABEL});
+			runner.assertNotEqual(null, button, placeHolderId);
+			domConst.place(button.domNode, placeHolderId, "replace");
+			button.startup();
+			return button;
+		}
+		function _createToggleButtonProgrammaticallyWithSourceNodeReference(buttonId){
+			return new ToggleButton({label:BUTTON_LABEL}, buttonId);
+		}
+		function _assertCorrectToggleButton(width, height, button){
+			runner.assertNotEqual(null, button);
+			runner.assertEqual(width, button.domNode.clientWidth, "width id=" + button.domNode.id);
+			runner.assertEqual(height, button.domNode.clientHeight, "height id=" + button.domNode.id);
+		}
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		}
+		ready(function(){
+			var buttonWidth = has("ie") ? BUTTON_WIDTH_IE : BUTTON_WIDTH;
+			var buttonHeight = has("ie") ? BUTTON_HEIGHT_IE : BUTTON_HEIGHT;
+			runner.register("dojox.mobile.test.doh.ToggleButtonTests", [
+				function testInView1(){
+					var button1 = _createToggleButtonDeclaratively("view1-button1");
+					var button2 = _createToggleButtonProgrammatically("view1-button2");
+					var button3 = _createToggleButtonProgrammaticallyWithSourceNodeReference("view1-button3");
+			
+					_assertCorrectToggleButton(buttonWidth, buttonHeight, button1);
+					_assertCorrectToggleButton(buttonWidth, buttonHeight, button2);
+					_assertCorrectToggleButton(buttonWidth, buttonHeight, button3);
+				},
+				function testInView2(){
+					var button1 = _createToggleButtonDeclaratively("view2-button1");
+					var button2 = _createToggleButtonProgrammatically("view2-button2");
+					var button3 = _createToggleButtonProgrammaticallyWithSourceNodeReference("view2-button3");
+					
+					_showView2();
+					
+					_assertCorrectToggleButton(buttonWidth, buttonHeight, button1);
+					_assertCorrectToggleButton(buttonWidth, buttonHeight, button2);
+					_assertCorrectToggleButton(buttonWidth, buttonHeight, button3);
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<button id="view1-button1" data-dojo-type="dojox.mobile.ToggleButton">Button</button>
+		<div id="view1-button2"></div>
+		<button id="view1-button3"></button>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<button id="view2-button1" data-dojo-type="dojox.mobile.ToggleButton">Button</button>
+		<div id="view2-button2"></div>
+		<button id="view2-button3"></button>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/ToolBarButton.html b/dojox/mobile/tests/doh/ToolBarButton.html
deleted file mode 100644
index 8b85abc..0000000
--- a/dojox/mobile/tests/doh/ToolBarButton.html
+++ /dev/null
@@ -1,89 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ToolBarButton</title>
-		<link href="../../themes/iphone/base.css" rel="stylesheet">
-		<link href="../../themes/iphone/TabBar.css" rel="stylesheet">
-		<link href="../../themes/common/domButtons.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.TabBar");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-			dojo.require("doh.runner");
-		</script>
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script type="text/javascript" src="ToolBarButton.js"></script>
-	</head>
-	<body>
-		<h1 dojoType="dojox.mobile.Heading" label="World Clock">
-			<div id="btn1" dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButtonWhitePlus" style="float:right;" onclick="console.log('+ was clicked')"></div>
-
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButtonWhitePlus" style="float:right;"></div>
-			Alarm Clock
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Voice Memos">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Speaker"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Updates">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="News" back="Bookmarks" moveTo="bookmarks">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="New Folder" style="float:right;"></div>
-		</h1><br>
-
-
-		<div dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">New</div>
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">Toggle</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="../images/a-icon-12.png" moveTo="view3"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="../images/tab-icons.png" iconPos="29,0,29,29" moveTo="view3"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButtonWhitePlus" moveTo="view3" style="float:right;"></div>
-		</div><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButtonWhiteSearch" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" align="center">
-		  <table cellpadding="0" cellspacing="0" style="width:100%;"><tr>
-			<td><div dojoType="dojox.mobile.ToolBarButton" class="mblDomButtonWhitePlus"></div></td>
-			<td align="right"><div dojoType="dojox.mobile.ToolBarButton" icon="../images/tab-icon-15h.png" style="float:right;"></div></td>
-		  </tr></table>
-		</h1><br>
-
-		<h1 dojoType="dojox.mobile.Heading" back="Top" label="Inbox(32)">
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButtonWhiteSearch" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButtonWhiteUpArrow" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" class="mblDomButtonWhiteDownArrow" style="float:right;"></div>
-		</h1><br>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/ToolBarButton.js b/dojox/mobile/tests/doh/ToolBarButton.js
deleted file mode 100644
index 0de8cf2..0000000
--- a/dojox/mobile/tests/doh/ToolBarButton.js
+++ /dev/null
@@ -1,93 +0,0 @@
-dojo.addOnLoad(function(){
-	doh.register("dojox.mobile.test.ToolBarButton", [
-		function test_Heading_Verification(){
-			var demoWidget = dijit.byId("btn1");
-
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-			doh.assertEqual('Edit', demoWidget.domNode.childNodes[0].nodeValue);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_0");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblDomButton mblToolBarButtonDomButton mblDomButtonWhitePlus', demoWidget.domNode.className);
-			
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_1");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-			doh.assertEqual('Edit', demoWidget.domNode.childNodes[0].nodeValue);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_2");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblDomButton mblToolBarButtonDomButton mblDomButtonWhitePlus', demoWidget.domNode.className);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_3");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-			doh.assertEqual('Speaker', demoWidget.domNode.childNodes[0].nodeValue);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_4");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblToolBarButtonText mblColorBlue', demoWidget.domNode.className);
-			doh.assertEqual('Done', demoWidget.domNode.childNodes[0].nodeValue);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_5");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-			doh.assertEqual('Update All', demoWidget.domNode.childNodes[0].nodeValue);
-			
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_6");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblToolBarButtonText mblColorBlue', demoWidget.domNode.className);
-			doh.assertEqual('Done', demoWidget.domNode.childNodes[0].nodeValue);
-			
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_7");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblToolBarButtonText mblColorBlue', demoWidget.domNode.className);
-			doh.assertEqual('Done', demoWidget.domNode.childNodes[0].nodeValue);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_8");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-			doh.assertEqual('New Folder', demoWidget.domNode.childNodes[0].nodeValue);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_9");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-			doh.assertEqual('New', demoWidget.domNode.childNodes[0].nodeValue);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_10");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-			doh.assertEqual('Toggle', demoWidget.domNode.childNodes[0].nodeValue);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_11");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault', demoWidget.domNode.className);
-			if(dojo.isIE===6){
-				doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].href.search(/a-icon-12.png/) != -1, "a-icon-12.png");
-			}else{
-				doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].src.search(/a-icon-12.png/) != -1, "a-icon-12.png");
-			}
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_12");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault', demoWidget.domNode.className);
-			doh.assertEqual('mblToolBarButtonSpriteIcon', demoWidget.domNode.childNodes[0].childNodes[0].className);
-			verifyRect(demoWidget.domNode.childNodes[0].childNodes[0], "29px", "29px", "58px", "0px");
-			doh.assertEqual('-29px', demoWidget.domNode.childNodes[0].childNodes[0].style.top);
-			doh.assertEqual('0px', demoWidget.domNode.childNodes[0].childNodes[0].style.left);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_13");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblDomButton mblToolBarButtonDomButton mblDomButtonWhitePlus', demoWidget.domNode.className);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_14");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblDomButton mblToolBarButtonDomButton mblDomButtonWhiteSearch', demoWidget.domNode.className);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_15");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblDomButton mblToolBarButtonDomButton mblDomButtonWhitePlus', demoWidget.domNode.className);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_16");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault', demoWidget.domNode.className);
-			if(dojo.isIE!=6){
-				doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].src.search(/tab-icon-15h.png/) != -1, "tab-icon-15h.png");
-			}
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_17");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblDomButton mblToolBarButtonDomButton mblDomButtonWhiteSearch', demoWidget.domNode.className);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_18");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblDomButton mblToolBarButtonDomButton mblDomButtonWhiteUpArrow', demoWidget.domNode.className);
-
-			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_19");
-			doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblDomButton mblToolBarButtonDomButton mblDomButtonWhiteDownArrow', demoWidget.domNode.className);
-		}
-	]);
-	doh.run();
-});
-
diff --git a/dojox/mobile/tests/doh/ToolBarButton_Programmatic.html b/dojox/mobile/tests/doh/ToolBarButton_Programmatic.html
deleted file mode 100644
index 4b3538c..0000000
--- a/dojox/mobile/tests/doh/ToolBarButton_Programmatic.html
+++ /dev/null
@@ -1,195 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ToolBarButton</title>
-		<link href="../../themes/iphone/base.css" rel="stylesheet">
-		<link href="../../themes/iphone/TabBar.css" rel="stylesheet">
-		<link href="../../themes/common/domButtons.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.TabBar");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-			dojo.addOnLoad(function(){
-
-				var view = dijit.byId("general");
-				var demoWidget = new dojox.mobile.Heading({label:"World Clock"});
-				view.addChild(demoWidget);
-				var childWidget = new dojox.mobile.ToolBarButton({id:"btn1", label:"Edit", style:{padding:"0px 14px"}});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({btnClass:"mblDomButton mblDomButtonWhitePlus", style:"float:right;", onclick:"console.log('+ was clicked')"});
-				demoWidget.addChild(childWidget);
-
-				demoWidget = new dojox.mobile.Heading({label:"Alarm Clock"});
-				view.addChild(demoWidget);
-				childWidget = new dojox.mobile.ToolBarButton({label:"Edit", style:{padding:"0px 14px"}});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({btnClass:"mblDomButtonWhitePlus", style:{float:"right"}});
-				demoWidget.addChild(childWidget);
-
-				demoWidget = new dojox.mobile.Heading({label:"Voice Memos"});
-				view.addChild(demoWidget);
-				childWidget = new dojox.mobile.ToolBarButton({label:"Speaker"});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({label:"Done", btnClass:"mblColorBlue", style:{width:"45px", float:"right"}});
-				dojo.removeClass(childWidget.domNode, "mblColorDefault ");
-				demoWidget.addChild(childWidget);
-
-				demoWidget = new dojox.mobile.Heading({label:"Updatess"});
-				view.addChild(demoWidget);
-				childWidget = new dojox.mobile.ToolBarButton({label:"Update All", style:{float:"right"}});
-				demoWidget.addChild(childWidget);
-
-				demoWidget = new dojox.mobile.Heading({label:"News", back:"Bookmarks", moveTo:"bookmarks"});
-				view.addChild(demoWidget);
-				childWidget = new dojox.mobile.ToolBarButton({label:"Done", btnClass:"mblColorBlue", style:{width:"45px", float:"right"}});
-				dojo.removeClass(childWidget.domNode, "mblColorDefault ");
-				demoWidget.addChild(childWidget);
-
-				demoWidget = new dojox.mobile.Heading();
-				view.addChild(demoWidget);
-				childWidget = new dojox.mobile.ToolBarButton({label:"Done", btnClass:"mblColorBlue"});
-				dojo.removeClass(childWidget.domNode, "mblColorDefault ");
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({label:"New Folder", style:{float:"right"}});
-				demoWidget.addChild(childWidget);
-
-				demoWidget = new dojox.mobile.Heading();
-				view.addChild(demoWidget);
-				childWidget = new dojox.mobile.ToolBarButton({label:"New", toggle:"true"});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({label:"Toggle", toggle:"true"});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({icon:"../images/a-icon-12.png", moveTo:"view3"});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({icon:"../images/tab-icons.png", iconPos:"29,0,29,29", moveTo:"view3"});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({btnClass:"mblDomButtonWhitePlus", iconPos:"29,0,29,29", style:{float:"right"}});
-				demoWidget.addChild(childWidget);
-
-				demoWidget = new dojox.mobile.Heading();
-				view.addChild(demoWidget);
-				childWidget = new dojox.mobile.ToolBarButton({btnClass:"mblDomButtonWhiteSearch", style:{float:"right"}});
-				demoWidget.addChild(childWidget);
-
-				demoWidget = new dojox.mobile.Heading({align:"center"});
-				view.addChild(demoWidget);
-				childWidget = new dojox.mobile.ToolBarButton({btnClass:"mblDomButtonWhitePlus"});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({icon:"../images/tab-icon-15h.png", style:{float:"right"}});
-				demoWidget.addChild(childWidget);
-
-				demoWidget = new dojox.mobile.Heading({label:"Inbox(32)", back:"Top"});
-				view.addChild(demoWidget);
-				childWidget = new dojox.mobile.ToolBarButton({btnClass:"mblDomButtonWhiteSearch", style:{float:"right"}});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({btnClass:"mblDomButtonWhiteUpArrow", style:{float:"right"}});
-				demoWidget.addChild(childWidget);
-				childWidget = new dojox.mobile.ToolBarButton({btnClass:"mblDomButtonWhiteDownArrow", style:{float:"right"}});
-				demoWidget.addChild(childWidget);
-			});
-		</script>
-		<script type="text/javascript" src="TestUtil.js"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.addOnLoad(function(){
-				doh.register("dojox.mobile.test.ToolBarButton", [
-					function test_Heading_Verification(){
-						var demoWidget = dijit.byId("btn1");
-
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-						doh.assertEqual('Edit', demoWidget.domNode.childNodes[0].nodeValue);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_0");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText mblDomButton mblDomButtonWhitePlus mblToolBarButtonDomButton', demoWidget.domNode.className);
-						
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_1");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-						doh.assertEqual('Edit', demoWidget.domNode.childNodes[0].nodeValue);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_2");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText mblDomButtonWhitePlus mblDomButton mblToolBarButtonDomButton', demoWidget.domNode.className);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_3");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-						doh.assertEqual('Speaker', demoWidget.domNode.childNodes[0].nodeValue);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_4");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblToolBarButtonText mblColorBlue', demoWidget.domNode.className);
-						doh.assertEqual('Done', demoWidget.domNode.childNodes[0].nodeValue);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_5");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-						doh.assertEqual('Update All', demoWidget.domNode.childNodes[0].nodeValue);
-						
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_6");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblToolBarButtonText mblColorBlue', demoWidget.domNode.className);
-						doh.assertEqual('Done', demoWidget.domNode.childNodes[0].nodeValue);
-						
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_7");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblToolBarButtonText mblColorBlue', demoWidget.domNode.className);
-						doh.assertEqual('Done', demoWidget.domNode.childNodes[0].nodeValue);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_8");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-						doh.assertEqual('New Folder', demoWidget.domNode.childNodes[0].nodeValue);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_9");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-						doh.assertEqual('New', demoWidget.domNode.childNodes[0].nodeValue);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_10");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText', demoWidget.domNode.className);
-						doh.assertEqual('Toggle', demoWidget.domNode.childNodes[0].nodeValue);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_11");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault', demoWidget.domNode.className);
-						doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].src.search(/a-icon-12.png/) != -1);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_12");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault', demoWidget.domNode.className);
-						doh.assertEqual('mblToolBarButtonSpriteIcon', demoWidget.domNode.childNodes[0].childNodes[0].className);
-						verifyRect(demoWidget.domNode.childNodes[0].childNodes[0], "29px", "29px", "58px", "0px");
-						doh.assertEqual('-29px', demoWidget.domNode.childNodes[0].childNodes[0].style.top);
-						doh.assertEqual('0px', demoWidget.domNode.childNodes[0].childNodes[0].style.left);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_13");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText mblDomButtonWhitePlus mblDomButton mblToolBarButtonDomButton', demoWidget.domNode.className);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_14");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText mblDomButtonWhiteSearch mblDomButton mblToolBarButtonDomButton', demoWidget.domNode.className);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_15");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText mblDomButtonWhitePlus mblDomButton mblToolBarButtonDomButton', demoWidget.domNode.className);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_16");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault', demoWidget.domNode.className);
-						doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].src.search(/tab-icon-15h.png/) != -1);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_17");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText mblDomButtonWhiteSearch mblDomButton mblToolBarButtonDomButton', demoWidget.domNode.className);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_18");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText mblDomButtonWhiteUpArrow mblDomButton mblToolBarButtonDomButton', demoWidget.domNode.className);
-
-						demoWidget = dijit.byId("dojox_mobile_ToolBarButton_19");
-						doh.assertEqual('mblToolBarButton mblArrowButtonText mblColorDefault mblToolBarButtonText mblDomButtonWhiteDownArrow mblDomButton mblToolBarButtonDomButton', demoWidget.domNode.className);
-					}
-				]);
-				doh.run();
-			});
-
-		</script>
-	</head>
-	<body>
-		<div id="general" dojoType="dojox.mobile.View" selected="true">
-		</div>
-
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/View-demo.html b/dojox/mobile/tests/doh/View-demo.html
deleted file mode 100644
index e0a8e46..0000000
--- a/dojox/mobile/tests/doh/View-demo.html
+++ /dev/null
@@ -1,821 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>ScrollableView demo</title>
-	<link href="../../themes/iphone/base.css" rel="stylesheet">
-	<link href="../../themes/iphone/TabBar.css" rel="stylesheet">
-	<style>
-	html,body{
-		height: 100%;
-		overflow: hidden;
-	}
-	.list1 li{
-		border-style: solid;
-		border-width: 1px 0px 1px 0px;
-		border-top-color: #BABABC;
-		border-bottom-color: #89898C;
-		background-color: #ACACAF;
-		line-height: 0px;
-	}
-	.list1 li table{
-		line-height: normal;
-	}
-	.list1 li:nth-child(even){
-		background-color: #97979B;
-	}
-	#list2 li:nth-child(even){
-		background-color: #eeeeee;
-	}
-	#categ1 {
-		font-size: 18px;
-	}
-	#categ1 li{
-		line-height: 70px;
-	}
-	.lnk {
-		font-size: 14px;
-		color: #0B5199;
-		text-decoration: none;
-	}
-	.content {
-		padding:0px 10px;
-		background-color: white;
-	}
-	p {
-		font-family: Helvetica;
-		font-size: 12px;
-	}
-	.title {
-		color: blue;
-		margin-bottom: 4px;
-	}
-	.subtitle {
-		font-style: italic;
-		color: gray;
-		margin: 0px;
-		margin-bottom: 4px;
-	}
-	.subsubtitle {
-		margin: 16px 0px 0px 0px;
-	}
-	.lst {
-		margin: 0px;
-		padding: 0px 14px;
-	}
-	.lst li {
-		font-family: Helvetica;
-		font-size: 12px;
-		margin: 0px;
-		list-style-type: square;
-	}
-	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		//dojo.require("dojo.parser"); // Use the lightweight parser.
-		dojo.require("dojox.mobile.parser");
-		dojo.require("dojox.mobile");
-		dojo.require("dojox.mobile.ScrollableView");
-		dojo.require("dojox.mobile.TabBar");
-		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
-	</script>
-	<script type="text/javascript" src="TestUtil.js"></script>
-	<script language="JavaScript" type="text/javascript">
-		dojo.addOnLoad(function(){
-			doh.register("dojox.mobile.test.doh.View", [
-				{
-
-					name: "View Verification",
-					timeout: 4000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						setTimeout(d.getTestCallback(function(){
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view2");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view3");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("categ");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-							
-							demoWidget = dijit.byId("top25");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("search");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("article");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-						}),500);
-						return d;
-					}
-				},
-				{
-					name: "View Verification2",
-					timeout: 2000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						fireOnClick("dojox_mobile_TabBarButton_1");
-						setTimeout(d.getTestCallback(function(){
-
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view2");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view3");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("categ");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-							
-							demoWidget = dijit.byId("top25");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("search");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("article");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-						}),1000);
-						return d;
-					}
-				},
-				{
-					name: "View Verification3",
-					timeout: 20000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						fireOnClick("dojox_mobile_TabBarButton_2");
-						setTimeout(d.getTestCallback(function(){
-
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view2");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view3");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("categ");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-							
-							demoWidget = dijit.byId("top25");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("search");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("article");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-						}),500);
-						return d;
-					}
-				},
-				{
-					name: "View Verification4",
-					timeout: 10000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						fireOnClick("dojox_mobile_TabBarButton_4");
-						setTimeout(d.getTestCallback(function(){
-
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view2");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view3");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("categ");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-							
-							demoWidget = dijit.byId("top25");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("search");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("article");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-						}),1000);
-						return d;
-					}
-				},
-				{
-					name: "View Verification5",
-					timeout: 10000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						fireOnClick("dojox_mobile_TabBarButton_5");
-						setTimeout(d.getTestCallback(function(){
-
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view2");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view3");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("categ");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-							
-							demoWidget = dijit.byId("top25");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("search");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("article");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-						}),500);
-						return d;
-					}
-				},
-				{
-					name: "View Verification6",
-					timeout: 10000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						fireOnClick("dojox_mobile_TabBarButton_6");
-						setTimeout(d.getTestCallback(function(){
-
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view2");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view3");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("categ");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-							
-							demoWidget = dijit.byId("top25");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("search");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("article");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-						}),500);
-						return d;
-					}
-				},
-				{
-					name: "View Verification7",
-					timeout: 10000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						fireOnClick("dojox_mobile_TabBarButton_7");
-						setTimeout(d.getTestCallback(function(){
-
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view2");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view3");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("categ");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-							
-							demoWidget = dijit.byId("top25");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("search");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("article");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-						}),500);
-						return d;
-					}
-				},
-				{
-					name: "View Verification8",
-					timeout: 10000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						fireOnClick("dojox_mobile_TabBarButton_3");
-						setTimeout(d.getTestCallback(function(){
-
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view2");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view3");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("categ");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-							
-							demoWidget = dijit.byId("top25");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("search");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("article");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-						}),500);
-						return d;
-					}
-				},
-				{
-					name: "View Verification9",
-					timeout: 10000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						fireOnClick("dojox_mobile_TabBarButton_0");
-						setTimeout(d.getTestCallback(function(){
-
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('', demoWidget.domNode.style.display, "group1");
-
-							demoWidget = dijit.byId("view1");
-							doh.assertEqual('', demoWidget.domNode.style.display, "view1");
-
-							demoWidget = dijit.byId("view2");
-							doh.assertEqual('none', demoWidget.domNode.style.display, "view2");
-
-							demoWidget = dijit.byId("view3");
-							doh.assertEqual('none', demoWidget.domNode.style.display, "view3");
-
-							demoWidget = dijit.byId("categ");
-							doh.assertEqual('none', demoWidget.domNode.style.display, "categ");
-							
-							demoWidget = dijit.byId("top25");
-							doh.assertEqual('none', demoWidget.domNode.style.display, "top25");
-
-							demoWidget = dijit.byId("search");
-							doh.assertEqual('none', demoWidget.domNode.style.display, "search");
-
-							demoWidget = dijit.byId("article");
-							doh.assertEqual('none', demoWidget.domNode.style.display, "article");
-
-							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-							doh.assertEqual('', demoWidget.domNode.style.display, "dojox_mobile_TabBar_1");
-						}),800);
-						return d;
-					}
-				},
-				{
-					name: "View Verification10",
-					timeout: 10000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						fireOnClick("dojox_mobile_TabBarButton_1");
-						setTimeout(d.getTestCallback(function(){
-
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view2");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view3");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("categ");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-							
-							demoWidget = dijit.byId("top25");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("search");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("article");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-						}),500);
-						return d;
-					}
-				},
-				{
-					name: "View Verification11",
-					timeout: 10000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						fireOnClick("dojox_mobile_TabBarButton_2");
-						setTimeout(d.getTestCallback(function(){
-
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view1");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view2");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("view3");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("categ");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-							
-							demoWidget = dijit.byId("top25");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("search");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("article");
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-
-							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
-							doh.assertEqual('', demoWidget.domNode.style.display);
-						}),500);
-						return d;
-					}
-				}
-			]);
-			doh.run();
-		});
-	</script>
-</head>
-<body>
-	<div id="group1" dojoType="dojox.mobile.View" selected="true">
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" fixed="top">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-16.png" icon2="../images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-15.png" icon2="../images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-10.png" icon2="../images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="../images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-									Sarah Connor Hardcover<br>
-									Eligible for FREE Super Saver Shipping
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="../images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
-									Martin Parker Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="../images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Total Solar Eclipse</a><br>
-									Steven Young Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="../images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The History of Java Coffee</a><br>
-									Marco Rodriguez Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="../images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-									Melissa Morgan Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-			</ul>
-		</div>
-
-		<div id="view2" dojoType="dojox.mobile.ScrollableView">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list2">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="../images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-									Melissa Morgan Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="../images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The History of Java Coffee</a><br>
-									Marco Rodriguez Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="../images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-									Sarah Connor Hardcover<br>
-									Eligible for FREE Super Saver Shipping
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="../images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Total Solar Eclipse</a><br>
-									Steven Young Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-			</ul>
-		</div>
-
-		<div id="view3" dojoType="dojox.mobile.ScrollableView">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="10">
-					Videos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="96">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2">
-					Applications
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-					Capacity
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-					Available
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-					Version
-				</li>
-			</ul>
-		</div>
-	</div>
-
-	<div id="categ" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Categories</h1>
-		<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1" id="categ1">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 1</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 2</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 3</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 4</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 5</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 6</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 7</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 8</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 9</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 10</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 11</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 12</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 13</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 14</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 15</li>
-		</ul>
-	</div>
-
-	<div id="top25" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">News</h1>
-		<h2 dojoType="dojox.mobile.RoundRectCategory">Top Stories</h2>
-		<ul dojoType="dojox.mobile.RoundRectList">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Top 10 news stories of the decade
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Create client-side diagrammatic interaction in Web applications with GFX
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
-			</li>
-		</ul>
-	</div>
-
-	<div id="search" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Search Result</h1>
-		<ul dojoType="dojox.mobile.RoundRectList">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-				Sarah Connor Hardcover<br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$14.50 (50%)</font> In Stock<br>
-				# (531)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-				Martin Parker Hardcover<br>
-				<font color="red">$14.00 (60%)</font> In Stock<br>
-				# (173)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-				Steven Young Hardcover<br>
-				Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$9.50 (62%)</font> In Stock<br>
-				# (1199)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-				Marco Rodriguez Hardcover<br>
-				<font color="blue">Not Available</font>
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-				Melissa Morgan Hardcover<br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$12.00 (60%)</font> In Stock<br>
-				# (1847)
-			</li>
-		</ul>
-	</div>
-
-	<div id="article" dojoType="dojox.mobile.ScrollableView" style="background-color:white;height:100%">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Article</h1>
-		<div class="content">
-			<h3 class="title">Did you know?</h3>
-			<h4 class="subtitle">Features of dojox.mobile</h4>
-			<h5 class="subsubtitle">No images are used</h5>
-			<ul class="lst">
-			  	<li>UI parts consist of DOM and CSS3.</li>
-				<li>Only application icons are images.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
-			<ul class="lst">
-			  	<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Support for CSS sprite</h5>
-			<ul class="lst">
-				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
-			<ul class="lst">
-				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
-			</ul>
-		</div>
-	</div>
-
-	<ul dojoType="dojox.mobile.TabBar" fixed="bottom" style="border-bottom:none;">
-		<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-16.png" icon2="../images/tab-icon-16h.png" selected="true" moveTo="group1">Featured</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-15.png" icon2="../images/tab-icon-15h.png" moveTo="categ">Categories</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-10.png" icon2="../images/tab-icon-10h.png" moveTo="top25">Top 25</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-11.png" icon2="../images/tab-icon-11h.png" moveTo="search">Search</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="../images/tab-icon-13.png" icon2="../images/tab-icon-13h.png" moveTo="article">Updates</li>
-	</ul>
-</body>
-</html>
diff --git a/dojox/mobile/tests/doh/View.html b/dojox/mobile/tests/doh/View.html
deleted file mode 100644
index c7c0153..0000000
--- a/dojox/mobile/tests/doh/View.html
+++ /dev/null
@@ -1,122 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>View</title>
-	<link href="../../themes/iphone/base.css" rel="stylesheet">
-	<style>
-	html,body{
-		height: 100%;
-		overflow: hidden;
-	}
-	.list1 li{
-		border-style: solid;
-		border-width: 1px 0px 1px 0px;
-		border-top-color: #BABABC;
-		border-bottom-color: #89898C;
-		background-color: #ACACAF;
-		line-height: 0px;
-	}
-	.list1 li table{
-		line-height: normal;
-	}
-	.list1 li:nth-child(even){
-		background-color: #97979B;
-	}
-	#list2 li:nth-child(even){
-		background-color: #eeeeee;
-	}
-	#categ1 {
-		font-size: 18px;
-	}
-	#categ1 li{
-		line-height: 70px;
-	}
-	.lnk {
-		font-size: 14px;
-		color: #0B5199;
-		text-decoration: none;
-	}
-	.content {
-		padding:0px 10px;
-		background-color: white;
-	}
-	p {
-		font-family: Helvetica;
-		font-size: 12px;
-	}
-	.title {
-		color: blue;
-		margin-bottom: 4px;
-	}
-	.subtitle {
-		font-style: italic;
-		color: gray;
-		margin: 0px;
-		margin-bottom: 4px;
-	}
-	.subsubtitle {
-		margin: 16px 0px 0px 0px;
-	}
-	.lst {
-		margin: 0px;
-		padding: 0px 14px;
-	}
-	.lst li {
-		font-family: Helvetica;
-		font-size: 12px;
-		margin: 0px;
-		list-style-type: square;
-	}
-	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		//dojo.require("dojo.parser"); // Use the lightweight parser.
-		dojo.require("dojox.mobile.parser");
-		dojo.require("dojox.mobile");
-		dojo.require("dojox.mobile.ScrollableView");
-		dojo.require("dojox.mobile.TabBar");
-		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
-
-        dojo.require("doh.runner");
-
-		dojo.addOnLoad(function(){
-			doh.register("dojox.mobile.test.doh.View", [
-				{
-					name: "test View Verification",
-					timeout: 3000,
-					runTest: function (){
-						var demoWidget = dijit.byId("group1");
-						doh.assertEqual('mblView', demoWidget.domNode.className);
-						doh.assertEqual('visible', demoWidget.domNode.style.visibility);
-
-						demoWidget = dijit.byId("categ");
-						doh.assertEqual('mblView mblScrollableView', demoWidget.domNode.className);
-						doh.assertEqual('none', demoWidget.domNode.style.display);
-					}
-				}
-			]);
-			setTimeout(function(){ // to get the correct dimension
-				doh.run();
-			}, 500);
-		});
-	</script>
-</head>
-<body>
-	<div id="group1" dojoType="dojox.mobile.View" selected="true">
-	aaa
-
-	</div>
-
-	<div id="categ" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Categories</h1>
-		bbb
-	</div>
-
-
-</body>
-</html>
diff --git a/dojox/mobile/tests/doh/View2_Programmatic.html b/dojox/mobile/tests/doh/View2_Programmatic.html
deleted file mode 100644
index 9650c8f..0000000
--- a/dojox/mobile/tests/doh/View2_Programmatic.html
+++ /dev/null
@@ -1,199 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>View</title>
-	<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-	<style>
-	html,body{
-		height: 100%;
-		overflow: hidden;
-	}
-	.list1 li{
-		border-style: solid;
-		border-width: 1px 0px 1px 0px;
-		border-top-color: #BABABC;
-		border-bottom-color: #89898C;
-		background-color: #ACACAF;
-		line-height: 0px;
-	}
-	.list1 li table{
-		line-height: normal;
-	}
-	.list1 li:nth-child(even){
-		background-color: #97979B;
-	}
-	#list2 li:nth-child(even){
-		background-color: #eeeeee;
-	}
-	#categ1 {
-		font-size: 18px;
-	}
-	#categ1 li{
-		line-height: 70px;
-	}
-	.lnk {
-		font-size: 14px;
-		color: #0B5199;
-		text-decoration: none;
-	}
-	.content {
-		padding:0px 10px;
-		background-color: white;
-	}
-	p {
-		font-family: Helvetica;
-		font-size: 12px;
-	}
-	.title {
-		color: blue;
-		margin-bottom: 4px;
-	}
-	.subtitle {
-		font-style: italic;
-		color: gray;
-		margin: 0px;
-		margin-bottom: 4px;
-	}
-	.subsubtitle {
-		margin: 16px 0px 0px 0px;
-	}
-	.lst {
-		margin: 0px;
-		padding: 0px 14px;
-	}
-	.lst li {
-		font-family: Helvetica;
-		font-size: 12px;
-		margin: 0px;
-		list-style-type: square;
-	}
-	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		//dojo.require("dojo.parser"); // Use the lightweight parser.
-		dojo.require("dojox.mobile.parser");
-		dojo.require("dojox.mobile");
-		dojo.require("dojox.mobile.ScrollableView");
-		dojo.require("dojox.mobile.TabBar");
-		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
-
-        dojo.require("doh.runner");
-		dojo.addOnLoad(function(){
-
-			doh.register("dojox.mobile.test.doh.View", [
-				{
-					name: "test View Verification",
-					timeout: 4000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						setTimeout(d.getTestCallback(function(){
-							demoWidget = dijit.byId("dojox_mobile_ScrollableView_0");
-							demoWidget.set({scrollDir:"hv"});
-							doh.assertEqual('hv', demoWidget.get("scrollDir"));
-							doh.assertEqual('mblView mblScrollableView', demoWidget.domNode.className);
-							doh.assertEqual('', demoWidget.domNode.style.display);
-						}));
-						return d;
-					}
-				}
-			]);
-			doh.run();
-		});
-	</script>
-</head>
-<body>
-		<div dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
-			<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;background-color:white;">
-<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>644</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-3.png</td><td>2010/04/13</td><td>06:37</td><td>1,346</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>677</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-10.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>680</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-3.png</td><td>2010/03/23</td><td>13:03</td><td>682</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>697</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-5.png</td><td>2010/03/23</td><td>13:03</td><td>693</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-6.png</td><td>2010/03/23</td><td>13:03</td><td>694</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-7.png</td><td>2010/03/23</td><td>13:03</td><td>691</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-8.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-9.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-all.png</td><td>2010/03/23</td><td>13:03</td><td>4,450</td><td>mobile/tests/images</td></tr>
-<tr><td>icon-1.png</td><td>2010/05/06</td><td>08:57</td><td>2,626</td><td>mobile/tests/images</td></tr>
-<tr><td>not-images.png</td><td>2010/04/13</td><td>06:37</td><td>18,459</td><td>mobile/tests/images</td></tr>
-<tr><td>red-button-bg.png</td><td>2010/04/13</td><td>06:37</td><td>178</td><td>mobile/tests/images</td></tr>
-<tr><td>red-button-sel-bg.png</td><td>2010/04/13</td><td>06:37</td><td>185</td><td>mobile/tests/images</td></tr>
-<tr><td>test_Android-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,750</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,835</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,615</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,634</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,142</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Settings.html</td><td>2010/10/05</td><td>21:08</td><td>4,375</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>1,000</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,031</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,570</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-H2-prog.html</td><td>2010/10/03</td><td>22:28</td><td>1,089</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-H2.html</td><td>2010/10/03</td><td>22:28</td><td>872</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-V2H2.html</td><td>2010/10/03</td><td>22:28</td><td>1,088</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-V3.html</td><td>2010/10/03</td><td>22:28</td><td>996</td><td>mobile/tests</td></tr>
-<tr><td>test_ajax-html.html</td><td>2010/10/05</td><td>21:09</td><td>1,505</td><td>mobile/tests</td></tr>
-<tr><td>test_ajax-json.html</td><td>2010/10/05</td><td>21:08</td><td>1,505</td><td>mobile/tests</td></tr>
-<tr><td>test_anchor-label.html</td><td>2010/10/05</td><td>21:08</td><td>2,959</td><td>mobile/tests</td></tr>
-<tr><td>test_bookmarkable.html</td><td>2010/10/05</td><td>21:09</td><td>4,443</td><td>mobile/tests</td></tr>
-<tr><td>test_buttons.html</td><td>2010/10/05</td><td>21:08</td><td>972</td><td>mobile/tests</td></tr>
-<tr><td>test_css-sprite.html</td><td>2010/10/05</td><td>21:09</td><td>5,779</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-icons.html</td><td>2010/10/05</td><td>21:08</td><td>2,080</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-items.html</td><td>2010/10/05</td><td>21:08</td><td>3,375</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-view.html</td><td>2010/10/05</td><td>21:09</td><td>1,657</td><td>mobile/tests</td></tr>
-<tr><td>test_hash-parameter.html</td><td>2010/10/05</td><td>21:09</td><td>2,679</td><td>mobile/tests</td></tr>
-<tr><td>test_iPad-Settings-fixed.html</td><td>2010/10/03</td><td>22:28</td><td>8,866</td><td>mobile/tests</td></tr>
-<tr><td>test_iPad-Settings.html</td><td>2010/10/03</td><td>22:28</td><td>6,904</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Animation.html</td><td>2010/10/05</td><td>21:08</td><td>3,343</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Button.html</td><td>2010/10/05</td><td>21:09</td><td>1,766</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,135</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,809</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,613</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Heading.html</td><td>2010/10/05</td><td>21:08</td><td>1,136</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,588</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconMulti.html</td><td>2010/10/05</td><td>21:08</td><td>1,863</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconSingle.html</td><td>2010/10/05</td><td>21:09</td><td>1,814</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconSingleBelow.html</td><td>2010/10/05</td><td>21:08</td><td>1,815</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-ResultList.html</td><td>2010/10/05</td><td>21:08</td><td>2,708</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-RoundRect.html</td><td>2010/10/05</td><td>21:08</td><td>1,155</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,136</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Settings.html</td><td>2010/10/05</td><td>21:09</td><td>5,666</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>998</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,262</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,550</td><td>mobile/tests</td></tr>
-<tr><td>test_progress-indicator.html</td><td>2010/10/05</td><td>21:08</td><td>3,124</td><td>mobile/tests</td></tr>
-<tr><td>test_transition-to-dynamic-view.html</td><td>2010/10/05</td><td>21:08</td><td>2,525</td><td>mobile/tests</td></tr>
-<tr><td>view-sample.html</td><td>2010/05/06</td><td>20:30</td><td>1,724</td><td>mobile/tests</td></tr>
-<tr><td>view1.html</td><td>2010/05/06</td><td>20:28</td><td>378</td><td>mobile/tests</td></tr>
-<tr><td>view1.json</td><td>2010/05/28</td><td>00:30</td><td>371</td><td>mobile/tests</td></tr>
-<tr><td>view2.html</td><td>2010/05/06</td><td>21:20</td><td>619</td><td>mobile/tests</td></tr>
-<tr><td>view2.json</td><td>2010/05/28</td><td>00:30</td><td>737</td><td>mobile/tests</td></tr>
-<tr><td>view3.html</td><td>2010/10/05</td><td>21:09</td><td>963</td><td>mobile/tests</td></tr>
-<tr><td>view3.json</td><td>2010/10/05</td><td>21:09</td><td>1,054</td><td>mobile/tests</td></tr>
-<tr><td>widget-bg.png</td><td>2010/03/23</td><td>13:03</td><td>26,234</td><td>mobile/tests/images</td></tr>
-			</table>
-			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">View Footer Bar</h1>
-		</div>
-</body>
-</html>
diff --git a/dojox/mobile/tests/doh/View3_Programmatic.html b/dojox/mobile/tests/doh/View3_Programmatic.html
deleted file mode 100644
index f0406b3..0000000
--- a/dojox/mobile/tests/doh/View3_Programmatic.html
+++ /dev/null
@@ -1,139 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>View</title>
-	<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-	<style>
-	html,body{
-		height: 100%;
-		overflow: hidden;
-	}
-	.list1 li{
-		border-style: solid;
-		border-width: 1px 0px 1px 0px;
-		border-top-color: #BABABC;
-		border-bottom-color: #89898C;
-		background-color: #ACACAF;
-		line-height: 0px;
-	}
-	.list1 li table{
-		line-height: normal;
-	}
-	.list1 li:nth-child(even){
-		background-color: #97979B;
-	}
-	#list2 li:nth-child(even){
-		background-color: #eeeeee;
-	}
-	#categ1 {
-		font-size: 18px;
-	}
-	#categ1 li{
-		line-height: 70px;
-	}
-	.lnk {
-		font-size: 14px;
-		color: #0B5199;
-		text-decoration: none;
-	}
-	.content {
-		padding:0px 10px;
-		background-color: white;
-	}
-	p {
-		font-family: Helvetica;
-		font-size: 12px;
-	}
-	.title {
-		color: blue;
-		margin-bottom: 4px;
-	}
-	.subtitle {
-		font-style: italic;
-		color: gray;
-		margin: 0px;
-		margin-bottom: 4px;
-	}
-	.subsubtitle {
-		margin: 16px 0px 0px 0px;
-	}
-	.lst {
-		margin: 0px;
-		padding: 0px 14px;
-	}
-	.lst li {
-		font-family: Helvetica;
-		font-size: 12px;
-		margin: 0px;
-		list-style-type: square;
-	}
-	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		//dojo.require("dojo.parser"); // Use the lightweight parser.
-		dojo.require("dojox.mobile.parser");
-		dojo.require("dojox.mobile");
-		dojo.require("dojox.mobile.FlippableView");
-		dojo.require("dojox.mobile.IconContainer");
-		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
-
-        dojo.require("doh.runner");
-		dojo.addOnLoad(function(){
-
-			var view = new dojox.mobile.FlippableView({id:"foo", selected:"true"});
-			dojo.doc.body.appendChild(view.domNode);
-			var demoWidget = new dojox.mobile.RoundRectCategory({label:"Page flipping demo"});
-			view.addChild(demoWidget);
-
-			demoWidget = new dojox.mobile.RoundRect({innerHTML:"Swipe the screen left or right to flip between the views. There are 4 views in this demo. Vertical scrolling and page indicator are not supported."});
-			view.addChild(demoWidget);
-			view.startup();
-
-			view = new dojox.mobile.SwapView({id:"bar"});
-			dojo.doc.body.appendChild(view.domNode);
-			var list = new dojox.mobile.RoundRectList();
-			demoWidget = new dojox.mobile.ListItem({className:"mblVariableHeight"});
-//			demoWidget.domNode.style = {font-size:"10px"};
-			view.addChild(list);
-			demoWidget.domNode.innerHTML ='1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br> Sarah Connor Hardcover<br> Eligible for FREE Super Saver Shipping<br> <font color="red">$14.50 (50%)</font> In Stock<br> # (531)';
-			list.addChild(demoWidget);
-			view.startup();
-
-
-			
-			view = new dojox.mobile.FlippableView({id:"icon1"});
-			demoWidget = new dojox.mobile.Heading({label:"Icon Container 1"});
-			dojo.doc.body.appendChild(view.domNode);
-			view.addChild(demoWidget);
-//			container = new dojox.mobile.IconContainer();
-
-
-			view.startup();
-			doh.register("dojox.mobile.test.doh.View", [
-				{
-					name: "test View Verification",
-					timeout: 4000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						setTimeout(d.getTestCallback(function(){
-							demoWidget = dijit.byId("foo");
-							doh.assertEqual('f', demoWidget.get("scrollDir"));
-							doh.assertEqual('mblView mblSwapView', demoWidget.domNode.className);
-							doh.assertEqual('', demoWidget.domNode.style.display);
-						}));
-						return d;
-					}
-				}
-			]);
-			doh.run();
-		});
-	</script>
-</head>
-<body>
-</body>
-</html>
diff --git a/dojox/mobile/tests/doh/View_Programmatic.html b/dojox/mobile/tests/doh/View_Programmatic.html
deleted file mode 100644
index 36b7007..0000000
--- a/dojox/mobile/tests/doh/View_Programmatic.html
+++ /dev/null
@@ -1,139 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>View</title>
-	<link href="../../themes/iphone/iphone.css" rel="stylesheet">
-	<style>
-	html,body{
-		height: 100%;
-		overflow: hidden;
-	}
-	.list1 li{
-		border-style: solid;
-		border-width: 1px 0px 1px 0px;
-		border-top-color: #BABABC;
-		border-bottom-color: #89898C;
-		background-color: #ACACAF;
-		line-height: 0px;
-	}
-	.list1 li table{
-		line-height: normal;
-	}
-	.list1 li:nth-child(even){
-		background-color: #97979B;
-	}
-	#list2 li:nth-child(even){
-		background-color: #eeeeee;
-	}
-	#categ1 {
-		font-size: 18px;
-	}
-	#categ1 li{
-		line-height: 70px;
-	}
-	.lnk {
-		font-size: 14px;
-		color: #0B5199;
-		text-decoration: none;
-	}
-	.content {
-		padding:0px 10px;
-		background-color: white;
-	}
-	p {
-		font-family: Helvetica;
-		font-size: 12px;
-	}
-	.title {
-		color: blue;
-		margin-bottom: 4px;
-	}
-	.subtitle {
-		font-style: italic;
-		color: gray;
-		margin: 0px;
-		margin-bottom: 4px;
-	}
-	.subsubtitle {
-		margin: 16px 0px 0px 0px;
-	}
-	.lst {
-		margin: 0px;
-		padding: 0px 14px;
-	}
-	.lst li {
-		font-family: Helvetica;
-		font-size: 12px;
-		margin: 0px;
-		list-style-type: square;
-	}
-	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		//dojo.require("dojo.parser"); // Use the lightweight parser.
-		dojo.require("dojox.mobile.parser");
-		dojo.require("dojox.mobile");
-		dojo.require("dojox.mobile.ScrollableView");
-		dojo.require("dojox.mobile.TabBar");
-		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
-
-        dojo.require("doh.runner");
-		dojo.addOnLoad(function(){
-			var view = new dojox.mobile.View({id:"group1", selected:"true", innerHTML:"aaa"});
-			dojo.doc.body.appendChild(view.domNode);
-			var roundRectList = new dojox.mobile.RoundRectList();
-			view.addChild(roundRectList);
-			var demoWidget = new dojox.mobile.ListItem({moveTo:"dojox_mobile_ScrollableView_0"});
-			roundRectList.addChild(demoWidget);
-			view.startup();
-			
-			view = new dojox.mobile.ScrollableView();
-			demoWidget = new dojox.mobile.Heading({fixed:"top", label:"Categories", back:"Back To", moveTo:"group1"});
-			dojo.doc.body.appendChild(view.domNode);
-			view.addChild(demoWidget);
-			view.domNode.appendChild(dojo.doc.createTextNode("bbbb"));
-			roundRectList = new dojox.mobile.EdgeToEdgeList();
-			view.addChild(roundRectList);
-			for(var i = 0;i<20;i++){
-				demoWidget = new dojox.mobile.ListItem({label:"Test" + i});
-				roundRectList.addChild(demoWidget)
-			}
-
-			view.startup();
-			doh.register("dojox.mobile.test.doh.View", [
-				{
-					name: "test View Verification",
-					timeout: 4000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						var t = 500;
-						if(dojo.isIE){
-							t = 2000;
-						}
-						setTimeout(d.getTestCallback(function(){
-							var demoWidget = dijit.byId("group1");
-							doh.assertEqual('mblView', demoWidget.domNode.className);
-							doh.assertEqual('visible', demoWidget.domNode.style.visibility);
-
-							demoWidget = dijit.byId("dojox_mobile_ScrollableView_0");
-							doh.assertEqual('mblView mblScrollableView', demoWidget.domNode.className);
-							doh.assertEqual('none', demoWidget.domNode.style.display);
-						}),t);
-						return d;
-					}
-				}
-			]);
-			doh.run();
-		});
-	</script>
-</head>
-<body>
-
-
-</body>
-</html>
diff --git a/dojox/mobile/tests/doh/accordion/AccordionTests.html b/dojox/mobile/tests/doh/accordion/AccordionTests.html
new file mode 100644
index 0000000..f2a8905
--- /dev/null
+++ b/dojox/mobile/tests/doh/accordion/AccordionTests.html
@@ -0,0 +1,201 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Accordion Tests</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Accordion','TabBar']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+	<style type="text/css">
+		@import "../../../themes/common/domButtons/DomButtonBlackRightArrow16.css";
+		@import "../../../themes/common/domButtons/DomButtonWhiteDownArrow16.css";
+		@import "../../../themes/common/dijit/dijit.css";
+		html,body{
+			height: 100%;
+		}
+		.myPane {
+			background-image: -webkit-gradient(linear, left top, left bottom, from(#dcdcdc), to(#FFFFFF));
+			font-family: Times New Roman, Helvetica;
+			color: black;
+		}
+	</style>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom-construct", // dojo.place
+			"dojo/dom-class", // dojo.hasClass
+			"dojo/ready", // dojo.ready
+			"dijit/registry",  // dijit.byId
+			"doh/runner",	//doh functions
+			"dojox/mobile/Accordion",
+			"dojox/mobile/ContentPane",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/View"
+		], function(domConst, domClass, ready, registry, runner, Accordion, ContentPane){
+			function _createAccordionDeclaratively(widgetId){
+				return registry.byId(widgetId);
+			}
+			
+			function _createAccordionProgrammatically(placeHolderId, widgetId){
+				var r = new Accordion({id:widgetId, iconBase:"../../images/icons16.png"});
+				runner.assertNotEqual(null, r);
+				domConst.place(r.domNode, placeHolderId, "replace");
+				r.startup();
+				var childWidget = ContentPane({label:"External Content 2", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"dojo.html"});
+				r.addChild(childWidget);
+				return r;
+			}
+			
+			function _createAccordionProgrammaticallyWithSourceNodeReference(widgetId, childWidgetId){
+				var r = new Accordion({iconBase:"../../images/icons16.png"}, widgetId);
+				r.startup();
+				return r;
+			}
+			function _assertCorrectAccordion(widget){
+				var childWidgets = widget.getChildren();
+				runner.assertEqual(1, childWidgets.length, "id= " + widget.domNode.id + " childWidgets.length=" + childWidgets.length);
+				var child = childWidgets[0];
+				runner.assertEqual("none", child.domNode.style.display, "id= " + widget.domNode.id);
+				
+			}
+			function _showView2(){
+				var view1 = registry.byId("view1");
+				view1.performTransition("view2", 1, "none");
+			}
+			dojo.ready(function(){
+				doh.register("dojox.mobile.test.doh.AccordionTests", [
+					function testInView1(){
+						var widget1 = _createAccordionDeclaratively("dojox_mobile_Accordion_0");
+						var widget2 = _createAccordionProgrammatically("view1-Accordion2place", "view1-Accordion2");
+						var widget3 = _createAccordionProgrammaticallyWithSourceNodeReference("view1-Accordion3");
+
+						setTimeout(function() {
+							_assertCorrectAccordion(widget1);
+							_assertCorrectAccordion(widget2);
+							_assertCorrectAccordion(widget3);
+						}, 1000);
+					},
+					function testInView2(){
+						var widget1 = _createAccordionDeclaratively("dojox_mobile_Accordion_1");
+						var widget2 = _createAccordionProgrammatically("view2-Accordion2place", "view2-Accordion2");
+						var widget3 = _createAccordionProgrammaticallyWithSourceNodeReference("view2-Accordion3");
+
+						_showView2();
+
+						setTimeout(function() {
+							_assertCorrectAccordion(widget1);
+							_assertCorrectAccordion(widget2);
+							_assertCorrectAccordion(widget3);
+						}, 1000);
+					},
+					{
+						name: "testInView3.1",
+						timeout: 3000,
+						runTest: function(){
+ 							// Test case for #15064: destroy right after startup()
+ 							var accordion = 
+ 								new Accordion({iconBase:"../../images/icons16.png", fixedHeight: true}, 
+ 									"accordion");
+							var d = new runner.Deferred();
+							var errorCounter = 0;
+							var errorMsg;
+							// Before the fix of #15064, there used to be an error thrown when destroying 
+							// right after startup(). To test it, we cannot use a simple try-catch, because
+							// this is about an error thrown by the setTimeout function which used to be set 
+							// Accordion's startup(). Hence:
+							window.onerror = function(msg, url, lineNumber){
+								errorCounter++;
+								errorMsg = "After destroy: " + msg + "\nURL: " + url + 
+									"\nLine number: " + lineNumber;
+								console.log(errorMsg);
+							};
+							accordion.startup();
+							accordion.destroyRecursive(false/*preserveDom*/);
+							// Check that no error has been thrown
+							setTimeout(d.getTestCallback(function(){
+								runner.assertEqual(0, errorCounter, errorMsg);
+							}), 2000); // smaller than the total timeout of the test case
+						
+							return d;
+						}
+					},
+					{
+						name: "testInView3.2",
+						timeout: 3000,
+						runTest: function(){
+ 							// Test case for #15064: destroy right after addChild()
+ 							var accordion = 
+ 								new Accordion({iconBase:"../../images/icons16.png", fixedHeight: true}, 
+ 									"accordion");
+							var d = new runner.Deferred();
+							var errorCounter = 0;
+							var errorMsg;
+							// Before the fix of #15064, there used to be an error thrown when destroying 
+							// right after startup(). To test it, we cannot use a simple try-catch, because
+							// this is about an error thrown by the setTimeout function which used to be set 
+							// Accordion's startup(). Hence:
+							window.onerror = function(msg, url, lineNumber){
+								errorCounter++;
+								errorMsg = "After destroy: " + msg + "\nURL: " + url + 
+									"\nLine number: " + lineNumber;
+								console.log(errorMsg);
+							};
+							accordion.startup();
+							var childWidget = 
+								ContentPane({label:"External Content 2", 
+									icon1:"mblDomButtonBlackRightArrow16", 
+									icon2:"mblDomButtonWhiteDownArrow16", href:"dojo.html"});
+							accordion.addChild(childWidget);
+							accordion.destroyRecursive(false/*preserveDom*/);
+							// Check that no error has been thrown
+							setTimeout(d.getTestCallback(function(){
+								runner.assertEqual(0, errorCounter, errorMsg);
+							}), 2000); // smaller than the total timeout of the test case
+							
+							return d;
+						}
+					}
+				]);
+				runner.run();
+			});
+		})
+	</script>
+
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1>View 1</h1>
+		<div data-dojo-type="dojox.mobile.Accordion" data-dojo-props='iconBase:"../../images/icons16.png"'>
+			<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"External Content 1", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"dojo.html"'>
+			</div>
+		</div>
+		<div id="view1-Accordion2place"></div>
+		<div id="view1-Accordion3">
+			<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"External Content 3", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"dojo.html"'>
+			</div>
+		</div>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<div data-dojo-type="dojox.mobile.Accordion" data-dojo-props='iconBase:"../../images/icons16.png"'>
+			<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"External Content 1", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"dojo.html"'>
+			</div>
+		</div>
+		<div id="view2-Accordion2place"></div>
+		<div id="view2-Accordion3">
+			<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"External Content 3", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"dojo.html"'>
+			</div>
+		</div>
+	</div>
+	
+	<div id="view3" data-dojo-type="dojox.mobile.View">
+		<h1>View ""</h1>
+		<div id="accordion">
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/accordion/dojo.html b/dojox/mobile/tests/doh/accordion/dojo.html
new file mode 100644
index 0000000..ea84076
--- /dev/null
+++ b/dojox/mobile/tests/doh/accordion/dojo.html
@@ -0,0 +1,7 @@
+<div style="padding:10px">
+	<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+	<div style="border-top: 1px dashed gray;margin: 20px"></div>
+	<img alt="" src="../../images/dojo-logo1.png" style="float:left;margin-right:5px">
+	<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+	<p>Dojo's powerful, lightweight core makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.</p>
+</div>
diff --git a/dojox/mobile/tests/doh/accordion/module.js b/dojox/mobile/tests/doh/accordion/module.js
new file mode 100644
index 0000000..15eb839
--- /dev/null
+++ b/dojox/mobile/tests/doh/accordion/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.Accordion", require.toUrl("./AccordionTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/accordion/runTests.html b/dojox/mobile/tests/doh/accordion/runTests.html
new file mode 100644
index 0000000..56ef224
--- /dev/null
+++ b/dojox/mobile/tests/doh/accordion/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.accordion.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/badge/BadgeTests.html b/dojox/mobile/tests/doh/badge/BadgeTests.html
new file mode 100644
index 0000000..eed10da
--- /dev/null
+++ b/dojox/mobile/tests/doh/badge/BadgeTests.html
@@ -0,0 +1,163 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Carousel Tests</title>
+<link href="../../../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+<link href="../../../themes/common/domButtons/DomButtonGreenBadge.css" rel="stylesheet"/>
+<link href="../../../themes/common/domButtons/DomButtonBlueBadge.css" rel="stylesheet"/>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	var store1;
+	require([
+		"dojo/dom",
+		"dojo/dom-class", // dojo.hasClass
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/Badge",
+		"dojox/mobile/Pane",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(dom, domClass, domConst, ready, registry, runner, Badge){
+
+		var WIDGET_VALUE1 = "6";
+		var WIDGET_VALUE2 = "48";
+		var WIDGET_VALUE3 = "320";
+		var WIDGET_CLASSNAME1 = "mblBadge";
+		var WIDGET_CLASSNAME2 = "mblDomButton";
+		var WIDGET_CLASSNAME3 = "mblDomButtonRedBadge";
+		var WIDGET_CLASSNAME4 = "mblDomButtonBlueBadge";
+		var WIDGET_CLASSNAME5 = "mblDomButtonGreenBadge";
+
+		function _createBadgeDeclaratively(id) {
+			return registry.byId(id);
+		};
+		
+		function _createBadgeProgrammatically(placeHolderIds, ids){
+			var widget1 = new Badge({value:WIDGET_VALUE1});
+			runner.assertNotEqual(null, widget1);
+			widget1.domNode.id = ids[0];
+			domConst.place(widget1.domNode, placeHolderIds[0], "replace");
+			var widget2 = new Badge({value:WIDGET_VALUE2, className:"mblDomButtonBlueBadge"});
+			runner.assertNotEqual(null, widget2);
+			widget2.domNode.id = ids[1];
+			domConst.place(widget2.domNode, placeHolderIds[1], "replace");
+			var widget3 = new Badge({value:WIDGET_VALUE3, className:"mblDomButtonGreenBadge", fontSize:11});
+			runner.assertNotEqual(null, widget3);
+			widget3.domNode.id = ids[2];
+			domConst.place(widget3.domNode, placeHolderIds[2], "replace");
+			return widget1;
+		};
+		
+		function _createBadgeProgrammaticallyWithSourceNodeReference(ids){
+			var widget1 = new Badge({value:WIDGET_VALUE1}, dom.byId(ids[0]));
+			runner.assertNotEqual(null, widget1);
+			var widget2 = new Badge({value:WIDGET_VALUE2, className:"mblDomButtonBlueBadge"}, dom.byId(ids[1]));
+			runner.assertNotEqual(null, widget2);
+			var widget3 = new Badge({value:WIDGET_VALUE3, className:"mblDomButtonGreenBadge", fontSize:11}, dom.byId(ids[2]));
+			runner.assertNotEqual(null, widget3);
+			return widget1;
+		};
+
+		function _assertBadge(ids){
+			var widget1 = dom.byId(ids[0]);
+			runner.assertNotEqual(null, widget1, ids[0]);
+			runner.assertEqual(WIDGET_VALUE1, widget1.childNodes[0].innerHTML, widget1.id)
+			runner.assertTrue(domClass.contains(widget1, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + widget1.id + " value=" + widget1.className);
+			runner.assertTrue(domClass.contains(widget1, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " id=" + widget1.id + " value=" + widget1.className);
+			runner.assertTrue(domClass.contains(widget1, WIDGET_CLASSNAME3), WIDGET_CLASSNAME3 + " id=" + widget1.id + " value=" + widget1.className);
+
+			var widget2 = dom.byId(ids[1]);
+			runner.assertNotEqual(null, widget2, ids[1]);
+			runner.assertEqual(WIDGET_VALUE2, widget2.childNodes[0].innerHTML, widget2.id)
+			runner.assertTrue(domClass.contains(widget2, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + widget2.id + " value=" + widget2.className);
+			runner.assertTrue(domClass.contains(widget2, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " id=" + widget2.id + " value=" + widget2.className);
+			runner.assertTrue(domClass.contains(widget2, WIDGET_CLASSNAME4), WIDGET_CLASSNAME4 + " id=" + widget2.id + " value=" + widget2.className);
+
+			var widget3 = dom.byId(ids[2]);
+			runner.assertNotEqual(null, widget3, ids[2]);
+			runner.assertEqual(WIDGET_VALUE3, widget3.childNodes[0].innerHTML, widget3.id)
+			runner.assertTrue(domClass.contains(widget3, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + widget3.id + " value=" + widget3.className);
+			runner.assertTrue(domClass.contains(widget3, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " id=" + widget3.id + " value=" + widget3.className);
+			runner.assertTrue(domClass.contains(widget3, WIDGET_CLASSNAME5), WIDGET_CLASSNAME5 + " id=" + widget3.id + " value=" + widget3.className);
+		};
+		
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		};
+
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.CarouselTests", [
+				{
+					name: "Carousel Verification1",
+					timeout: 4000,
+					runTest: function(){
+						var badge1 = _createBadgeDeclaratively("view1-Badge11");
+						var badge2 = _createBadgeProgrammatically(["view1-Badge21place", "view1-Badge22place", "view1-Badge23place"], ["view1-Badge21", "view1-Badge22", "view1-Badge23"]);
+						var badge3 = _createBadgeProgrammaticallyWithSourceNodeReference(["view1-Badge31", "view1-Badge32", "view1-Badge33"]);
+
+						_assertBadge(["view1-Badge11", "view1-Badge12", "view1-Badge13"]);
+						_assertBadge(["view1-Badge21", "view1-Badge22", "view1-Badge23"]);
+						_assertBadge(["view1-Badge31", "view1-Badge32", "view1-Badge33"]);
+					}
+				},
+				{
+					name: "Carousel Verification2",
+					timeout: 4000,
+					runTest: function(){
+						var badge1 = _createBadgeDeclaratively("view2-Badge11");
+						var badge2 = _createBadgeProgrammatically(["view2-Badge21place", "view2-Badge22place", "view2-Badge23place"], ["view2-Badge21", "view2-Badge22", "view2-Badge23"]);
+						var badge3 = _createBadgeProgrammaticallyWithSourceNodeReference(["view2-Badge31", "view2-Badge32", "view2-Badge33"]);
+						
+						_showView2();
+
+						_assertBadge(["view2-Badge11", "view2-Badge12", "view2-Badge13"]);
+						_assertBadge(["view2-Badge21", "view2-Badge22", "view2-Badge23"]);
+						_assertBadge(["view2-Badge31", "view2-Badge32", "view2-Badge33"]);
+					}
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<div data-dojo-type="dojox.mobile.Pane" style="padding:0px 30px 0px 30px;">
+			<div id="view1-Badge11" data-dojo-type="dojox.mobile.Badge" class="mblDomButtonRedBadge" data-dojo-props='value:"6"'></div>
+			<div id="view1-Badge12" data-dojo-type="dojox.mobile.Badge" class="mblDomButtonBlueBadge" data-dojo-props='value:"48"'></div>
+			<div id="view1-Badge13" data-dojo-type="dojox.mobile.Badge" class="mblDomButtonGreenBadge" data-dojo-props='value:"320",fontSize:11'></div>
+			<div id="view1-Badge21place"></div>
+			<div id="view1-Badge22place"></div>
+			<div id="view1-Badge23place"></div>
+			<div id="view1-Badge31"></div>
+			<div id="view1-Badge32"></div>
+			<div id="view1-Badge33"></div>
+		</div>
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<div data-dojo-type="dojox.mobile.Pane" style="padding:0px 30px 0px 30px;">
+			<div id="view2-Badge11" data-dojo-type="dojox.mobile.Badge" class="mblDomButtonRedBadge" data-dojo-props='value:"6"'></div>
+			<div id="view2-Badge12" data-dojo-type="dojox.mobile.Badge" class="mblDomButtonBlueBadge" data-dojo-props='value:"48"'></div>
+			<div id="view2-Badge13" data-dojo-type="dojox.mobile.Badge" class="mblDomButtonGreenBadge" data-dojo-props='value:"320",fontSize:11'></div>
+			<div id="view2-Badge21place"></div>
+			<div id="view2-Badge22place"></div>
+			<div id="view2-Badge23place"></div>
+			<div id="view2-Badge31"></div>
+			<div id="view2-Badge32"></div>
+			<div id="view2-Badge33"></div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/badge/module.js b/dojox/mobile/tests/doh/badge/module.js
new file mode 100644
index 0000000..7f0aa0d
--- /dev/null
+++ b/dojox/mobile/tests/doh/badge/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.Badge", require.toUrl("./BadgeTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/badge/runTests.html b/dojox/mobile/tests/doh/badge/runTests.html
new file mode 100644
index 0000000..fa6b38f
--- /dev/null
+++ b/dojox/mobile/tests/doh/badge/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.badge.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/bidi/ComboBoxTests_Rtl.html b/dojox/mobile/tests/doh/bidi/ComboBoxTests_Rtl.html
new file mode 100644
index 0000000..94fa60c
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/ComboBoxTests_Rtl.html
@@ -0,0 +1,142 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Combo Box Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','base']"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script language="JavaScript" type="text/javascript">
+	var timeoutInterval = 1000;
+	require([
+		"dojo/_base/connect",
+		"dojo/_base/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/dom-class", // dojo.hasClass
+		"dojo/store/Memory", // dojo.store.Memory
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/ComboBox",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(connect, has, domConst, domClass, Memory, ready, registry, runner, ComboBox){
+
+		var FRUITS = new Memory({
+				idProperty:"name",
+				data:[
+					{name:"Apple"},
+					{name:"Banana"},
+					{name:"Cherry"}
+			]});
+
+		function _createComboBoxDeclaratively(id) {
+			return registry.byId(id);
+		};
+		
+		function _createComboBoxProgrammatically(placeHolderId){
+			var widget = new ComboBox({store:FRUITS, id:placeHolderId, value:'Apple'});
+			runner.assertNotEqual(null, widget);
+			domConst.place(widget.domNode, placeHolderId, "replace");
+			widget.startup();
+			return widget;
+		};
+		
+		function _createComboBoxProgrammaticallyWithSourceNodeReference(id){
+			var widget = new ComboBox({store:FRUITS, value:'Apple'}, id);
+			widget.startup();
+			return widget;
+		};
+
+		function _assertCorrectComboBox(comboBox){
+			runner.assertNotEqual(null, comboBox);
+			runner.assertEqual(FRUITS.data[0].name, comboBox.domNode.value, comboBox.toString());
+			comboBox.set("value", FRUITS.data[1].name);
+			runner.assertEqual(FRUITS.data[1].name, comboBox.domNode.value, comboBox.toString());
+		};
+
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		};
+
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.ComboBoxTests", [
+				{
+					name: "testInView1",
+					timeout: 4000,
+					runTest: function(){
+
+						var d = new runner.Deferred();
+						var comboBox1 = _createComboBoxDeclaratively("view1-comboBox1");
+						var comboBox2 = _createComboBoxProgrammatically("view1-comboBox2");
+						var comboBox3 = _createComboBoxProgrammaticallyWithSourceNodeReference("view1-comboBox3");
+						setTimeout(d.getTestCallback(function(){
+							var comboBox1 = registry.byId("view1-comboBox1");
+							var comboBox2 = registry.byId("view1-comboBox2");
+							var comboBox3 = registry.byId("view1-comboBox3");
+							_assertCorrectComboBox(comboBox1);
+							_assertCorrectComboBox(comboBox2);
+							_assertCorrectComboBox(comboBox3);
+						}), timeoutInterval);
+						return d;
+					}
+				},
+				{
+					name: "testInView2",
+					timeout: 4000,
+					runTest: function(){
+						var d = new runner.Deferred();
+						var comboBox1 = _createComboBoxDeclaratively("view2-comboBox1");
+						var comboBox2 = _createComboBoxProgrammatically("view2-comboBox2");
+						var comboBox3 = _createComboBoxProgrammaticallyWithSourceNodeReference("view2-comboBox3");
+						
+						_showView2();
+						
+						setTimeout(d.getTestCallback(function(){
+							var comboBox1 = registry.byId("view2-comboBox1");
+							var comboBox2 = registry.byId("view2-comboBox2");
+							var comboBox3 = registry.byId("view2-comboBox3");
+							_assertCorrectComboBox(comboBox1);
+							_assertCorrectComboBox(comboBox2);
+							_assertCorrectComboBox(comboBox3);
+						}), timeoutInterval);
+						return d;
+					}
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true" dir="ltr">
+		<h1>View 1</h1>
+		<datalist id="fruits">
+			<select data-dojo-type="dijit.form.DataList" data-dojo-props="id:'fruits'">
+				<option value="fruit1">Apple</option>
+				<option value="fruit2">Banana</option>
+				<option value="fruit3">Cherry</option>
+			</select>
+		</datalist>
+		<input id="view1-comboBox1" type="text" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props="value:'Apple', list:'fruits'"></input>
+		<div id="view1-comboBox2"></div>
+		<input id="view1-comboBox3" type="text"></input>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1>View 2</h1>
+		<select data-dojo-type="dijit.form.DataList" data-dojo-props="id:'fruits2'">
+			<option>Apple</option>
+			<option>Banana</option>
+			<option>Cherry</option>
+		</select>
+		<input id="view2-comboBox1" type="text" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props="value:'Apple', list:'fruits2'"></input>
+		<div id="view2-comboBox2"></div>
+		<input id="view2-comboBox3" type="text"></input>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/EdgeToEdgeCatagory_Rtl.js b/dojox/mobile/tests/doh/bidi/EdgeToEdgeCatagory_Rtl.js
new file mode 100644
index 0000000..99fc535
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/EdgeToEdgeCatagory_Rtl.js
@@ -0,0 +1,72 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.EdgeToEdgeList", [
+		{
+			name: "EdgeToEdgeList Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("Category");
+					doh.assertEqual('mblEdgeToEdgeCategory', demoWidget.domNode.className);
+					doh.assertEqual('Spaces', demoWidget.domNode.innerHTML);
+
+
+					demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
+					doh.assertEqual('mblEdgeToEdgeList', demoWidget.domNode.className);
+					verifyListItem("item1", 'u1space', 'Off', "mblDomButtonArrow", true, true, false);
+					verifyListItem("item2", 'u2space', 'On', "mblDomButtonArrow", true, true, false);
+					verifyListItem("item3", 'Wi-Fi', 'Off', "mblDomButtonArrow", false, true, false);
+					
+				}));
+				return d;
+			}
+		},
+		{
+			name: "EdgeToEdgeList Verification2",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				var demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
+				demoWidget.set({transition :"flip"});
+				doh.assertEqual("flip", demoWidget.get("transition"));
+				demoWidget.set({transition :"fade"});
+				doh.assertEqual("fade", demoWidget.get("transition"));
+
+				fireOnMouseDown("item3");
+				fireOnMouseUp("item3");
+				var view = dijit.byId("foo");
+				dojo.connect(view, "onAfterTransitionOut", this, d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeCategory_0");
+					doh.assertEqual('mblEdgeToEdgeCategory', demoWidget.domNode.className);
+					doh.assertEqual('Applications', demoWidget.domNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_1");
+					doh.assertEqual('mblEdgeToEdgeList', demoWidget.domNode.className);
+
+					verifyListItem("dojox_mobile_ListItem_0", 'Video', 'Off', "", false, false, false);
+					verifyListItem("dojox_mobile_ListItem_1", 'Maps', 'VPN', "", true, false, false);
+					verifyListItem("dojox_mobile_ListItem_2", 'Phone Number', 'Off', "", false, false, false);
+				}));
+				return d;
+			}
+		},
+		{
+			name: "EdgeToEdgeCategory getLabel",
+			timeout: 1000,
+			runTest: function(){
+				doh.assertEqual("Spaces", dijit.byId("Category").get("label")); 
+			}
+		},
+		{
+			name: "EdgeToEdgeCategory setLabel",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("Category");
+				demoWidget.set({label :"Value Changed"});
+				doh.assertEqual("Value Changed", demoWidget.get("label"));
+				doh.assertEqual('Value Changed', demoWidget.domNode.innerHTML);
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/bidi/EdgeToEdgeCategory_Rtl.html b/dojox/mobile/tests/doh/bidi/EdgeToEdgeCategory_Rtl.html
new file mode 100644
index 0000000..5fb6305
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/EdgeToEdgeCategory_Rtl.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Edge To Edge List</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/iphone_rtl.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/ListItem.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/ListItem_rtl.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+		<script type="text/javascript" src="TestUtil_Rtl.js"></script>
+		<script type="text/javascript" src="EdgeToEdgeCatagory_Rtl.js"></script>
+	</head>
+	<body dir="rtl">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
+			<h2 id="Category" dojoType="dojox.mobile.EdgeToEdgeCategory">Spaces</h2>
+			<ul dojoType="dojox.mobile.EdgeToEdgeList">
+				<li id="item1" dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightText="Off" moveTo="bar">u1space</li>
+				<li id="item2" dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-2.png" rightText="On" moveTo="bar">u2space</li>
+				<li id="item3" dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="bar">Wi-Fi</li>
+			</ul>
+		</div>
+
+		<div id="bar" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="foo">u1space</h1>
+			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Applications</h2>
+			<ul dojoType="dojox.mobile.EdgeToEdgeList">
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">Video</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightText="VPN">Maps</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">Phone Number</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/EdgeToEdgeDataList_Rtl.html b/dojox/mobile/tests/doh/bidi/EdgeToEdgeDataList_Rtl.html
new file mode 100644
index 0000000..bdeee09
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/EdgeToEdgeDataList_Rtl.html
@@ -0,0 +1,72 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>EdgeToEdgeDataList</title>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.data.ItemFileWriteStore");
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojox.mobile.themeFiles = ['base','base_rtl'];
+			dojo.require("dojox.mobile.deviceTheme");
+			dojo.require("dojox.mobile.EdgeToEdgeDataList");
+
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+
+			var static_data = { 
+				items: [ 
+					{label: "Apple", 	moveTo: "dummy"},
+					{label: "Banana", 	moveTo: "dummy"},
+					{label: "Cherry", 	moveTo: "dummy"},
+					{label: "Grape", 	moveTo: "dummy"},
+					{label: "Kiwi", 	moveTo: "dummy"},
+					{label: "Lemon", 	moveTo: "dummy"},
+					{label: "Melon", 	moveTo: "dummy"},
+					{label: "Orange", 	moveTo: "dummy"},
+					{label: "Peach", 	moveTo: "dummy"}
+				]
+			};
+			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
+			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
+			var store = store1;
+			var newItems = [[],[]];
+
+			// switch to the selected store
+			function switchTo(store){
+				window.store = store;
+				dijit.byId("list").setStore(store);
+			}
+			// add a new item
+			function add1(){
+				var item = store.newItem({label: "New Item", moveTo: "dummy"});
+				this.newItems[(store == store1) ? 1 : 0].push(item);
+			}
+			// delete the added item
+			function delete1(){
+				var item = this.newItems[(store == store1) ? 1 : 0].pop();
+				if(item){
+					store.deleteItem(item);
+				}
+			}
+		</script>
+		<script type="text/javascript" src="TestUtil_Rtl.js"></script>
+		<script type="text/javascript" src="RoundRectDataList_Rtl.js"></script>
+	</head>
+	<body dir="rtl">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">EdgeToEdgeDataList</h1>
+			<ul dojoType="dojox.mobile.EdgeToEdgeDataList" id="list" store="store" query="{label: '*'}"></ul>
+			<p>show the different set:<br>
+			<input type="button" value="Set1" onclick="switchTo(store1)">
+			<input type="button" value="Set2" onclick="switchTo(store2)">
+			<p>alter the object store:<br>
+			<input type="button" value="Add" onclick="add1()">
+			<input type="button" value="Delete" onclick="delete1()">
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/EdgeToEdgeStoreList_Rtl.html b/dojox/mobile/tests/doh/bidi/EdgeToEdgeStoreList_Rtl.html
new file mode 100644
index 0000000..04c202c
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/EdgeToEdgeStoreList_Rtl.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','base_rtl']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+	<script type="text/javascript">
+		var IsEdgeToEdgeList = true;
+	</script>
+	<script type="text/javascript" src="StoreList_Rtl.js"></script>
+</head>
+<body style="visibility:hidden;" dir="rtl">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="list" data-dojo-props='store:store, query:{}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/FixedSplitterTests1_Rtl.html b/dojox/mobile/tests/doh/bidi/FixedSplitterTests1_Rtl.html
new file mode 100644
index 0000000..10d6919
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/FixedSplitterTests1_Rtl.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>FixedSplitter Test</title>
+<link href="css/FixedSplitterTest.css" rel="stylesheet"/>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY =0;
+</script>
+<script type="text/javascript" src="FixedSplitterTests_rtl.js"></script>
+</head>
+<body dir="rtl">
+	<div dojoType="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" orientation="V">
+		<div dojoType="dojox.mobile.Container" style="background-color:yellow;height:20%">
+			pane #1
+		</div>
+
+		<div dojoType="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" orientation="H">
+			<div dojoType="dojox.mobile.Container" style="background-color:pink;width:20%;">
+				pane #2
+			</div>
+			<div dojoType="dojox.mobile.Container" style="background-color:cyan;">
+				pane #3
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/FixedSplitterTests2_Rtl.html b/dojox/mobile/tests/doh/bidi/FixedSplitterTests2_Rtl.html
new file mode 100644
index 0000000..310cd7d
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/FixedSplitterTests2_Rtl.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>FixedSplitter Test</title>
+<link href="css/FixedSplitterTest.css" rel="stylesheet"/>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY =1;
+</script>
+<script type="text/javascript" src="../fixedsplitter/FixedSplitterTests.js"></script>
+</head>
+<body dir="rtl">
+	<div id="FixedSplitterPlace"></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/FixedSplitterTests3_Rtl.html b/dojox/mobile/tests/doh/bidi/FixedSplitterTests3_Rtl.html
new file mode 100644
index 0000000..48bce96
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/FixedSplitterTests3_Rtl.html
@@ -0,0 +1,32 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>FixedSplitter Test</title>
+<link href="css/FixedSplitterTest.css" rel="stylesheet"/>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY =2;
+</script>
+<script type="text/javascript" src="../fixedsplitter/FixedSplitterTests.js"></script>
+</head>
+<body dir="rtl">
+	<div id="dojox_mobile_FixedSplitter_0">
+		<div id="dojox_mobile_Container_0">
+			pane #1
+		</div>
+
+		<div id="dojox_mobile_FixedSplitter_1">
+			<div id="dojox_mobile_Container_1">
+				pane #2
+			</div>
+			<div id="dojox_mobile_Container_2">
+				pane #3
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/FixedSplitterTests_rtl.js b/dojox/mobile/tests/doh/bidi/FixedSplitterTests_rtl.js
new file mode 100644
index 0000000..e24d569
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/FixedSplitterTests_rtl.js
@@ -0,0 +1,136 @@
+var timeoutInterval = 1500;
+
+var FIXEDSPLITER_CLASSNAME = "mblFixedSplitter";
+var FIXEDSPLITERPANE_CLASSNAME1 = "mblContainer";
+var FIXEDSPLITERPANE_CLASSNAME2 = "mblFixedSplitterV";
+var FIXEDSPLITERPANE_CLASSNAME3 = "mblFixedSplitterH";
+
+var HEIGHT_RATIO1 = 0.2;
+var HEIGHT_RATIO2 = 1 - HEIGHT_RATIO1;
+var WIDTH_RATIO1 = 0.2;
+var WIDTH_RATIO2 = 1 - WIDTH_RATIO1;
+var WIDGET_PROPS = [{style:{width:"100%", height:"100%"}, orientation:"V"},
+					{style:{backgroundColor:"yellow", height:"20%"}},
+					{style:{width:"100%", height:"100%"}, orientation:"H"},
+					{style:{backgroundColor:"pink", width:"20%"}},
+					{style:{backgroundColor:"cyan"}}];
+var WIDGET_INNERHTML = [{},
+						{innerHTML:"pane #1"},
+						{},
+						{innerHTML:"pane #2"},
+						{innerHTML:"pane #3"}];
+var WIDGET_IDS = [{id:"dojox_mobile_FixedSplitter_0"},
+				  {id:"dojox_mobile_Container_0"},
+				  {id:"dojox_mobile_FixedSplitter_1"},
+				  {id:"dojox_mobile_Container_1"},
+				  {id:"dojox_mobile_Container_2"}];
+
+require([
+	"dojo/_base/connect",
+	"dojo/_base/lang", // dojo.mixin
+	"dojo/dom-construct", // dojo.place
+	"dojo/dom-class", // dojo.hasClass
+	"dojo/dom-geometry",
+	"dojo/window", // dojo.window.getBox
+	"dojo/ready", // dojo.ready
+	"dijit/registry",  // dijit.byId
+	"doh/runner",	//doh functions
+	"dojox/mobile/FixedSplitter",
+	"dojox/mobile/Container",
+	"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+], function(connect, lang, domConst, domClass, domGeometry, window, ready, registry, runner, FixedSplitter, Container){
+	function _createFixedSplitterDeclaratively(widgetId) {
+		return registry.byId(widgetId);
+	}
+	function _createFixedSplitterProgrammatically(placeHolderId){
+		// Create FixedSplitter
+		var widget1 = new FixedSplitter(lang.mixin(WIDGET_IDS[0], WIDGET_PROPS[0], WIDGET_INNERHTML[0]));
+		runner.assertNotEqual(null, widget1);
+		domConst.place(widget1.domNode, placeHolderId, "replace");
+		widget1.startup();
+
+		var pane1 = new Container(lang.mixin(WIDGET_IDS[1], WIDGET_PROPS[1], WIDGET_INNERHTML[1]));
+		var widget2 = new FixedSplitter(lang.mixin(WIDGET_IDS[2], WIDGET_PROPS[2], WIDGET_INNERHTML[2]));
+		var pane2 = new Container(lang.mixin(WIDGET_IDS[3], WIDGET_PROPS[3], WIDGET_INNERHTML[3]));
+		var pane3 = new Container(lang.mixin(WIDGET_IDS[4], WIDGET_PROPS[4], WIDGET_INNERHTML[4]));
+
+		widget1.addChild(pane1);
+		widget1.addChild(widget2);
+		widget2.addChild(pane2);
+		widget2.addChild(pane3);
+
+		return widget1;
+	}
+	function _createFixedSplitterProgrammaticallyWithSourceNodeReference(){
+		// Create FixedSplitter
+		var widget1 = new FixedSplitter(WIDGET_PROPS[0], WIDGET_IDS[0].id);
+		runner.assertNotEqual(null, widget1);
+
+		var pane1 = new Container(WIDGET_PROPS[1], WIDGET_IDS[1].id);
+		var widget2 = new FixedSplitter(WIDGET_PROPS[2], WIDGET_IDS[2].id);
+		var pane2 = new Container(WIDGET_PROPS[3], WIDGET_IDS[3].id);
+		var pane3 = new Container(WIDGET_PROPS[4], WIDGET_IDS[4].id);
+		widget1.startup();
+
+		return widget1;
+	}
+	function _assertCorrectFixedSplitter(widget, height, width, className){
+		_assertCorrectFixedSplitterHW(widget, height, width);
+		runner.assertTrue(domClass.contains(widget.domNode, FIXEDSPLITER_CLASSNAME), FIXEDSPLITER_CLASSNAME);
+		if(className){
+			runner.assertTrue(domClass.contains(widget.domNode, className),  "expected: " + className + " but got " + widget.domNode.className);
+		}
+	}
+	function _assertCorrectContainer(widget, height, width, className){
+		_assertCorrectFixedSplitterHW(widget, height, width);
+		runner.assertTrue(domClass.contains(widget.domNode, FIXEDSPLITERPANE_CLASSNAME1), FIXEDSPLITERPANE_CLASSNAME1);
+		if(className){
+			runner.assertTrue(domClass.contains(widget.domNode, className), className);
+		}
+	}
+	function _assertCorrectFixedSplitterHW(widget, height, width){
+		runner.assertNotEqual(null, widget, "FixedSplitter: Did not instantiate.");
+		runner.assertTrue( (height - 2) < widget.domNode.offsetHeight && widget.domNode.offsetHeight < (height + 2), "expected: " +height + "+-2 but got " + widget.domNode.offsetHeight + "height: id = " + widget.domNode.id);
+		runner.assertTrue( (width - 2) < widget.domNode.offsetWidth && widget.domNode.offsetWidth < (width + 2), "expected: " +width + "+-2 but got " + widget.domNode.offsetWidth + "offsetWidth: id = " + widget.domNode.id);
+	}
+	ready(function(){
+		if(WIDGET_PROGRAMMATICALLY === 1){
+			_createFixedSplitterProgrammatically("FixedSplitterPlace");
+		}else if(WIDGET_PROGRAMMATICALLY === 2){
+			_createFixedSplitterProgrammaticallyWithSourceNodeReference();
+		}
+
+		runner.register("dojox.mobile.test.doh.FixedSplitter", [
+			{
+				name: "FixedSplitter Verification",
+				timeout: 4000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var box = window.getBox();
+						
+						var widget1 = registry.byId("dojox_mobile_FixedSplitter_0");
+						var widget2 = registry.byId("dojox_mobile_Container_0");
+						var widget3 = registry.byId("dojox_mobile_FixedSplitter_1");
+						var widget4 = registry.byId("dojox_mobile_Container_1");
+						var widget5 = registry.byId("dojox_mobile_Container_2");
+
+						var box2 = domGeometry.getMarginBox(widget1.domNode);
+
+						runner.assertEqual(box.h, widget2.domNode.offsetHeight + widget5.domNode.offsetHeight);
+						runner.assertEqual(box.w, widget4.domNode.offsetWidth + widget5.domNode.offsetWidth);
+
+						_assertCorrectFixedSplitter(widget1, 0, box2.w);
+						_assertCorrectContainer(widget2, Math.round(box.h * HEIGHT_RATIO1), box.w);
+						_assertCorrectFixedSplitter(widget3, Math.round(box.h * HEIGHT_RATIO2), box.w, FIXEDSPLITERPANE_CLASSNAME3);
+						_assertCorrectContainer(widget4, Math.round(box.h * HEIGHT_RATIO2), Math.round(box.w * WIDTH_RATIO1));
+						_assertCorrectContainer(widget5, Math.round(box.h * HEIGHT_RATIO2), Math.round(box.w * WIDTH_RATIO2));
+					}), timeoutInterval);
+					return d;
+				}
+			}
+		]);
+		runner.run();
+	});
+})
+
diff --git a/dojox/mobile/tests/doh/bidi/Heading2_Rtl.html b/dojox/mobile/tests/doh/bidi/Heading2_Rtl.html
new file mode 100644
index 0000000..eb9a2a6
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/Heading2_Rtl.html
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Heading</title>
+		<link href="../../../themes/android/base.css" rel="stylesheet"/>
+		<link href="../../../themes/android/base_rtl.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="Heading2_rtl.js"></script>
+	</head>
+	<body dir="rtl">
+		<div id="general" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="foo">General</h1>
+			<h1 dojoType="dojox.mobile.Heading" back="Go To" href="http://dojotoolkit.org/">Test</h1>
+			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="foo">Test</h1>
+			<h1 dojoType="dojox.mobile.Heading" back="Long Button" moveTo="bar">Very Very Long Title May Not Be Displayed in the Narrow Space</h1>
+		</div>
+
+		<div id="foo" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="item1" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-10.png" rightText="Off" moveTo="general">
+					u1space
+				</li>
+				<li id="item2" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-11.png" rightText="Off" moveTo="general">
+					u2space
+				</li>
+				<li id="item3" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-12.png" rightText="Off" moveTo="general">
+					Wi-Fi
+				</li>
+				<li id="item4" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-13.png" rightText="VPN" moveTo="general">
+					VPN
+				</li>
+			</ul>
+		</div>
+
+		<div id="bar" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="general">u1space</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">
+					Video
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-2.png" rightText="VPN">
+					Maps
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">
+					Phone Number
+				</li>
+			</ul>
+		</div>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/Heading2_rtl.js b/dojox/mobile/tests/doh/bidi/Heading2_rtl.js
new file mode 100644
index 0000000..f26d58b
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/Heading2_rtl.js
@@ -0,0 +1,87 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.Heading2", [
+		{
+			name: "Heading Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_Heading_0");
+					doh.assertTrue('mblHeading mblHeadingRtl mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className, "Heading 0: class name(s) of demo widget dom node is " + demoWidget.domNode.className);
+					doh.assertEqual('General', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+					doh.assertEqual('Settings', demoWidget.backButton.labelNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_Heading_1");
+					doh.assertTrue('mblHeading mblHeadingRtl mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className, "Heading 1: class name(s) of demo widget dom node is " + demoWidget.domNode.className);
+					doh.assertEqual('Test', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+					doh.assertEqual('Go To', demoWidget.backButton.labelNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_Heading_2");
+					doh.assertTrue('mblHeading mblHeadingRtl mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className, "Heading 2: class name(s) of demo widget dom node is " + demoWidget.domNode.className);
+					doh.assertEqual('Test', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+					doh.assertEqual('Settings', demoWidget.backButton.labelNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_Heading_3");
+					// The thiord header has a very long title, so it might not be centered if the test windows width is too small
+					doh.assertTrue('mblHeading mblHeadingRtl mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading mblHeadingRtl' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className, "Heading 3: class name(s) of demo widget dom node is " + demoWidget.domNode.className);
+					doh.assertEqual('Very Very Long Title May Not Be Displayed in the Narrow Space', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+					doh.assertEqual('3', demoWidget.domNode.childNodes.length);
+					doh.assertEqual('Long Button', demoWidget.backButton.labelNode.innerHTML);
+				}));
+				return d;
+			}
+		},
+		{
+			name: "Set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_Heading_2");
+				demoWidget.set({back:"Value Changed", label:"Value Changed", moveTo:"bar", transition:"flip"});
+				doh.assertEqual("Value Changed", demoWidget.get("label"), 'get("label")');
+				doh.assertEqual("Value Changed", demoWidget.get("back"), 'get("back")');
+				doh.assertEqual("bar", demoWidget.get("moveTo"));
+				doh.assertEqual("flip", demoWidget.get("transition"));
+				doh.assertEqual('Value Changed', demoWidget.backButton.label, "demoWidget.backButton.label");
+				doh.assertEqual('Value Changed', demoWidget.backButton.labelNode.innerHTML, "demoWidget.backButton.labelNode.innerHTML");
+
+				demoWidget = dijit.byId("dojox_mobile_Heading_5");
+				demoWidget.set({transition:"fade"});
+				doh.assertEqual("fade", demoWidget.get("transition"));
+			}
+		},
+		{
+			name: "moveTo",
+			timeout: 1000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				var demoWidget = dijit.byId("dojox_mobile_Heading_2");
+//				fireOnClick(demoWidget.domNode.childNodes[0].childNodes[1]);
+				fireOnMouseDown(demoWidget.backButton.domNode);
+				fireOnMouseUp(demoWidget.backButton.domNode);
+				setTimeout(d.getTestCallback(function(){
+
+					var demoWidget = dijit.byId("bar");
+					doh.assertEqual('visible', demoWidget.domNode.style.visibility);
+				}));
+				return d;
+			}
+		},
+		{
+			name: "moveTo",
+			timeout: 1000,
+			runTest: function(){
+				setTimeout(function(){
+					var d = new doh.Deferred();
+					var demoWidget = dijit.byId("dojox_mobile_Heading_5");
+					fireOnClick(demoWidget.domNode.childNodes[0].childNodes[1]);
+					setTimeout(d.getTestCallback(function(){
+						var demoWidget = dijit.byId("general");
+						doh.assertEqual('visible', demoWidget.domNode.style.visibility);
+					}));
+					return d;
+				},1500);
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/bidi/HeadingTests_Rtl.html b/dojox/mobile/tests/doh/bidi/HeadingTests_Rtl.html
new file mode 100644
index 0000000..feded24
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/HeadingTests_Rtl.html
@@ -0,0 +1,151 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Heading Tests</title>
+<link href="css/test.css" rel="stylesheet"/>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script language="JavaScript" type="text/javascript">
+	var TEXTAREA_ROWS = 3;
+	var TEXTAREA_COLS = 20;
+	var TEXTAREA_INNERHTML = "ExpandingTextArea";
+	var TEXTAREA_NEW_VALUE = "This is mobile ExpandingTextArea.\nThis text area is automaticaly Expanding.\nHello dojox.mobile";
+	var WIDGET_CLASSNAME1 = "mblHeading mblHeadingRtl";
+	var WIDGET_CLASSNAME2 = "mblHeadingCenterTitle";
+	var WIDGET_SPANTITLE_CLASSNAME = "mblHeadingSpanTitle";
+	var WIDGET_DIVTITLE_CLASSNAME = "mblHeadingDivTitle";
+	var WIDGET_BUTTON_CLASSNAME = "mblToolBarButton mblToolBarButtonRtl mblToolBarButtonHasRightArrow";
+	var WIDGET_BUTTON_HEAD_CLASSNAME = "mblToolBarButtonArrow mblColorDefault mblColorDefault45 mblToolBarButtonRightArrow";
+	var WIDGET_BUTTON_HEAD_CLASSNAME_IE = "mblToolBarButtonArrow mblToolBarButtonRightArrow";
+	var WIDGET_BUTTON_BODY_CLASSNAME = "mblToolBarButtonBody mblColorDefault";
+	var WIDGET_TITLE_TEXT1 = "View 1";
+	var WIDGET_TITLE_TEXT2 = "View 2";
+	var WIDGET_BACK_TEXT = "Settings";
+	var WIDGET_HEIGHT1 = "44";
+	var WIDGET_OFFSETHEIGHT1 = 44;
+	var WIDGET_OFFSETHEIGHT1_IE10 = 42; // IE10
+	var WIDGET_OFFSETHEIGHT2 = 90;
+
+	require([
+		"dojo/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/dom-class", // dojo.hasClass
+		"dojo/ready", // dojo.ready
+		"dojo/_base/lang", // lang.trim
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	// doh functions
+		"dojox/mobile/Heading",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(has, domConst, domClass, ready, lang, registry, runner, Heading){
+
+		function _createHeadingDeclaratively(widgetId) {
+			return registry.byId(widgetId);
+		};
+
+		function _createHeadingProgrammatically(placeHolderId, widgetId, labelText){
+			// Create SwapView
+			var r = new Heading({id:widgetId, back:"Settings", moveTo:"settings", label:labelText});
+			runner.assertNotEqual(null, r);
+			domConst.place(r.domNode, placeHolderId, "replace");
+			r.startup();
+			
+			return r;
+		};
+
+		function _createHeadingProgrammaticallyWithSourceNodeReference(widgetId){
+			// Create IconContainer
+			var r = new Heading({back:"Settings", moveTo:"settings"}, widgetId);
+
+			r.startup();
+			return r;
+		};
+
+		function _assertCorrectHeading(widget, titleText, backText, backClassName){
+			runner.assertNotEqual(null, widget, "IconItem: Did not instantiate.");
+			runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + widget.domNode.id);
+			runner.assertEqual(has("ie") >= 10 ? WIDGET_OFFSETHEIGHT1_IE10 : WIDGET_OFFSETHEIGHT1, widget.domNode.offsetHeight, "style.height id=" + widget.domNode.id);
+			runner.assertEqual(WIDGET_SPANTITLE_CLASSNAME, widget.labelNode.className);
+			runner.assertEqual(WIDGET_DIVTITLE_CLASSNAME, widget.labelDivNode.className);
+			runner.assertEqual(titleText, widget.labelNode.innerHTML, "widget.labelNode.innerHTML");
+			runner.assertEqual(titleText, widget.labelDivNode.innerHTML, "widget.labelDivNode.innerHTML");
+			runner.assertEqual(backClassName, widget.backButton.domNode.className);
+			runner.assertEqual(has("ie") < 10 ? WIDGET_BUTTON_HEAD_CLASSNAME_IE : WIDGET_BUTTON_HEAD_CLASSNAME,
+			    // calling trim() because of a blank that ToolBarButton.js adds at the end of widget's className attribute value 
+				lang.trim(widget.backButton.arrowNode.className));
+			runner.assertEqual(WIDGET_BUTTON_BODY_CLASSNAME, widget.backButton.bodyNode.className);
+			runner.assertEqual(backText, widget.backButton.labelNode.innerHTML, "widget.labelDivNode.innerHTML");
+		};
+
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		};
+
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.Heading", [
+				{
+					name: "Heading Verification1",
+					timeout: 4000,
+					runTest: function(){
+						var widget1 = _createHeadingDeclaratively("dojox_mobile_Heading_0");
+						var widget2 = _createHeadingProgrammatically("view1-Heading2place", "view1-Heading2", WIDGET_TITLE_TEXT1);
+						var widget3 = _createHeadingProgrammaticallyWithSourceNodeReference("view1-Heading3");
+
+						_assertCorrectHeading(widget1, WIDGET_TITLE_TEXT1, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+						_assertCorrectHeading(widget2, WIDGET_TITLE_TEXT1, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+						_assertCorrectHeading(widget3, WIDGET_TITLE_TEXT1, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+
+					}
+				},
+				{
+					name: "Heading Verification2",
+					timeout: 4000,
+					runTest: function(){
+						var widget1 = _createHeadingDeclaratively("dojox_mobile_Heading_1");
+						var widget2 = _createHeadingProgrammatically("view2-Heading2place", "view2-Heading2", WIDGET_TITLE_TEXT2);
+						var widget3 = _createHeadingProgrammaticallyWithSourceNodeReference("view2-Heading3");
+
+						var d = new runner.Deferred();
+						var handle2 = dojo.subscribe("/dojox/mobile/afterTransitionIn", d.getTestCallback(function(view){
+							if(view.id=="view2"){
+								dojo.unsubscribe(handle2);
+							}
+							var widget1 = registry.byId("dojox_mobile_Heading_1");
+							var widget2 = registry.byId("view2-Heading2");
+							var widget3 = registry.byId("view2-Heading3");
+							_assertCorrectHeading(widget1, WIDGET_TITLE_TEXT2, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+							_assertCorrectHeading(widget2, WIDGET_TITLE_TEXT2, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+							_assertCorrectHeading(widget3, WIDGET_TITLE_TEXT2, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+						}));
+						_showView2();
+						return d;
+					}
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body style="visibility:hidden;" dir="rtl">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Settings", moveTo:"settings", label:"View 1"'></h1>
+		<div id="view1-Heading2place"></div>
+		<h1 id="view1-Heading3">View 1</h1>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Settings", moveTo:"settings", label:"View 2"'></h1>
+		<div id="view2-Heading2place"></div>
+		<h1 id="view2-Heading3">View 2</h1>
+	</div>
+	<div id="settings" data-dojo-type="dojox.mobile.View">
+		<h1>settings</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/Heading_Rtl.html b/dojox/mobile/tests/doh/bidi/Heading_Rtl.html
new file mode 100644
index 0000000..c714028
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/Heading_Rtl.html
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Heading</title>
+		<link href="../../../themes/android/base.css" rel="stylesheet"/>
+		<link href="../../../themes/android/base_rtl.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+			dojo.addOnLoad(function(){
+				doh.register("dojox.mobile.test.doh.Heading1", [
+					{
+						name: "Heading Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = dijit.byId("dojox_mobile_Heading_0");
+								doh.assertTrue('mblHeading mblHeadingRtl mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+								doh.assertEqual('General', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+
+								demoWidget = dijit.byId("dojox_mobile_Heading_1");
+								doh.assertTrue('mblHeading mblHeadingRtl mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+								doh.assertEqual('Very Very Long Title May Not Be Displayed in the Narrow Space', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+								
+								demoWidget = dijit.byId("dojox_mobile_Heading_2");
+								doh.assertTrue('mblHeading mblHeadingRtl mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+								doh.assertEqual('World Clock', demoWidget.domNode.childNodes[0].childNodes[0].nodeValue);
+
+								demoWidget = dijit.byId("dojox_mobile_Heading_3");
+								doh.assertTrue('mblHeading mblHeadingRtl mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+							}));
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body dir="rtl">
+		<div id="general" data-dojo-type="dojox.mobile.View" selected="true">
+			<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Settings", moveTo:"settings"'>General</h1>
+			<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Long Button", moveTo:"settings"'>Very Very Long Title May Not Be Displayed in the Narrow Space</h1>
+		</div>
+
+		<h1 data-dojo-type="dojox.mobile.Heading" label="World Clock"></h1><br>
+
+
+		<h1 data-dojo-type="dojox.mobile.Heading">
+			<button data-dojo-type="dojox.mobile.ToolBarButton" style="padding: 0px 14px">Edit</button>
+			<button data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"></button>Alarm Clock</h1><br>
+
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/IconContainer2_Rtl.html b/dojox/mobile/tests/doh/bidi/IconContainer2_Rtl.html
new file mode 100644
index 0000000..6012c1b
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/IconContainer2_Rtl.html
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Icon</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/iphone_rtl.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+
+		<style>
+			.box {
+				border: 1px solid #A7C0E0;
+				width: 300px;
+				height: 250px;
+				background-image: url(../images/widget-bg.png);
+				background-repeat: no-repeat;
+				background-color: white;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.View");
+			dojo.require("dojox.mobile.IconContainer");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.addOnLoad(function(){
+				doh.register("dojox.mobile.test.doh.IconContainer", [
+					{
+						name: "IconContainer Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
+								doh.assertEqual('mblIconContainer mblIconContainerRtl', demoWidget.domNode.className);
+								
+							}));
+							return d;
+						}
+					},
+					{
+						name: "IconItem Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
+							doh.assertEqual('none', demoWidget.paneWidget.domNode.style.display);
+//							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0]);
+							fireOnMouseDown(demoWidget.domNode);
+							fireOnMouseUp(demoWidget.domNode);
+							demoWidget = dijit.byId("dojox_mobile_IconItem_1");
+							doh.assertEqual('none', demoWidget.paneWidget.domNode.style.display);
+							var t = 1000;
+							if(dojo.isIE || dojo.isAndroid || dojo.isIPhone || dojo.isBB) {
+								t=2500;
+							}
+
+							setTimeout(d.getTestCallback(function(){
+								verifyIconItem("dojox_mobile_IconItem_0", 'app1', '', /icon1.png/i);
+								verifyIconItem("dojox_mobile_IconItem_1", 'app2', 'none', /icon3.png/i);
+								
+							}),t);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body dir="rtl">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
+			<ul dojoType="dojox.mobile.IconContainer" defaultIcon="../../images/icon1.png" transition="slide" pressedIconOpacity="0.8">
+				<li dojoType="dojox.mobile.IconItem" label="app1" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app2" icon="../../images/icon3.png" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app3" icon="../../images/icon3.png" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="moveTo" icon="../../images/icon3.png" moveTo="about" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="href" icon="../../images/icon3.png" href="../../test_iPhone-RoundRectList.html" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="url" icon="../../images/icon3.png" url="../../view-sample.html" transition="slide"></li>
+			</ul>
+		</div>
+
+		<div id="about" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Network											   
+				</li>												   
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Line
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="1024">
+					Songs
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/IconContainer3_Rtl.html b/dojox/mobile/tests/doh/bidi/IconContainer3_Rtl.html
new file mode 100644
index 0000000..634d751
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/IconContainer3_Rtl.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Icon</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/IconContainer.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/base_rtl.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/IconContainer_rtl.css" rel="stylesheet"/>
+
+		<style>
+			.box {
+				border: 1px solid #A7C0E0;
+				width: 300px;
+				height: 250px;
+				background-image: url(../images/widget-bg.png);
+				background-repeat: no-repeat;
+				background-color: white;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.View");
+			dojo.require("dojox.mobile.IconContainer");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+
+			dojo.addOnLoad(function(){
+				doh.register("dojox.mobile.test.doh.IconContainer", [
+					{
+						name: "IconContainer Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
+								doh.assertEqual('mblIconContainer mblIconContainerRtl', demoWidget.domNode.className);
+								
+							}));
+							return d;
+						}
+					},
+					{
+						name: "IconItem Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
+							fireOnMouseDown(demoWidget.domNode);
+							fireOnMouseUp(demoWidget.domNode);
+
+							demoWidget = dijit.byId("dojox_mobile_IconItem_1");
+							doh.assertEqual('none', demoWidget.paneWidget.domNode.style.display);
+							fireOnMouseDown(demoWidget.domNode);
+							fireOnMouseUp(demoWidget.domNode);
+							var t = 1000;
+							if(dojo.isIE || dojo.isAndroid || dojo.isIPhone || dojo.isBB) {
+								t=2500;
+							}
+
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
+								verifyRect(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0], "0px", "64px", "64px", "0px");
+								verifyIconItem("dojox_mobile_IconItem_0", 'app1', 'none', /icon-all.png/i, true);
+								verifyIconItem("dojox_mobile_IconItem_1", 'app2', '', /icon-all.png/i, true);
+								
+							}),t);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body dir="rtl">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
+			<ul dojoType="dojox.mobile.IconContainer" transition="slide" single="true" pressedIconOpacity="0.8" iconBase="../../images/icon-all.png" iconPos="0,0,64,64" back="Test" label="test">
+				<li dojoType="dojox.mobile.IconItem" label="app1" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app2" iconPos="0,64,64,64" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app3" iconPos="0,64,64,64" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="moveTo" iconPos="0,64,64,64" moveTo="about" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="href" iconPos="0,64,64,64" href="../../test_iPhone-RoundRectList.html" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="url" iconPos="0,64,64,64" url="../../view-sample.html" transition="slide"></li>
+			</ul>
+		</div>
+
+		<div id="about" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Network											   
+				</li>												   
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Line
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="1024">
+					Songs
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/IconContainerTests_Rtl.html b/dojox/mobile/tests/doh/bidi/IconContainerTests_Rtl.html
new file mode 100644
index 0000000..3ea1826
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/IconContainerTests_Rtl.html
@@ -0,0 +1,216 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>IconContainer and IconItem Tests</title>
+<link href="css/test.css" rel="stylesheet"/>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script language="JavaScript" type="text/javascript">
+	var ICON_ITEM_CLASSNAME1 = "mblIconItem mblIconItemRtl";
+	var ICON_ITEM_CLASSNAME2 = "mblIconArea";
+	var WIDGET_CLASSNAME = "mblIconContainer mblIconContainerRtl";
+	var ICON_ITEM_SRC_REGEXP = /icon-1.png/i;
+	var CHILD_ITEM_PROPS = [{label:"app1", icon:"../../images/icon-1.png", lazy:"true"}, 
+							  {label:"app2", icon:"../../images/icon-1.png", lazy:"true"}, 
+							  {label:"app3", icon:"../../images/icon-1.png", lazy:"true"},
+							  {label:"moveTo", icon:"../../images/icon-1.png", moveTo:"about", transition:"slide"},
+							  {label:"href", icon:"../../images/icon-1.png", href:"../../test_iPhone-RoundRectList.html", transition:"slide"},
+							  {label:"url" , icon:"../../images/icon-1.png", url:"../../view-sample.html", transition:"slide"}];
+
+	var CHILD_ITEM_CONTAINERS = ['<div class="box"></div>', 
+							  	   '<div class="box"></div>', 
+							       '<div class="box"></div>',
+							       '',
+							       '',
+							       ''];
+
+	require([
+		"dojo/_base/array", // dojo.forEach
+		"dojo/_base/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/IconContainer",
+		"dojox/mobile/IconItem",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
+		"dojox/mobile/View"		// This mobile app uses mobile view
+	], function(array, has, domConst, ready, registry, runner, IconContainer, IconItem){
+		function _createIconContainerDeclaratively(widgetId) {
+			return registry.byId(widgetId);
+		}
+		function _createIconContainerProgrammatically(placeHolderId, widgetId){
+			// Create IconContainer
+			var r = new IconContainer({id:widgetId});
+			runner.assertNotEqual(null, r);
+			domConst.place(r.domNode, placeHolderId, "replace");
+
+			// Create IconItems
+			for(var i = 0, len = CHILD_ITEM_PROPS.length; i < len; i++){
+				var childWidget = new IconItem(CHILD_ITEM_PROPS[i]);
+				r.addChild(childWidget);
+				if(CHILD_ITEM_CONTAINERS[i]){
+					childWidget.set("content", CHILD_ITEM_CONTAINERS[i]);
+				}
+			}
+			r.startup();
+			return r;
+		}
+		function _createIconContainerProgrammaticallyWithSourceNodeReference(widgetId){
+			// Create IconContainer
+			var r = new IconContainer({}, widgetId);
+
+			// Create IconItems
+			var index = 0;
+			for(var i = 0, len = r.domNode.childNodes.length; i < len; i++){
+				var n = r.domNode.childNodes[i];
+				if(n.nodeType === 1 && n.id){
+					new IconItem(CHILD_ITEM_PROPS[index++], n.id);
+				}
+			}
+			r.startup();
+			return r;
+		}
+		function _assertCorrectIconContainer(widget){
+			runner.assertNotEqual(null, widget, "IconContainer: Did not instantiate.");
+			runner.assertEqual(WIDGET_CLASSNAME, widget.domNode.className, "id=" + widget.domNode.id);
+			array.forEach(widget.getChildren(), function(iconItem){
+				_assertCorrectIconItem(iconItem);
+			});
+			
+		}
+		function _assertCorrectIconItem(widget){
+			runner.assertNotEqual(null, widget, "IconItem: Did not instantiate.");
+			runner.assertEqual(ICON_ITEM_CLASSNAME1, widget.domNode.className, "id=" + widget.domNode.id);
+			runner.assertEqual(ICON_ITEM_CLASSNAME2, widget.domNode.childNodes[0].className, "id=" + widget.domNode.id);
+			if(!has("ie") || has("ie") > 6){
+				runner.assertTrue(widget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(ICON_ITEM_SRC_REGEXP) != -1, ICON_ITEM_SRC_REGEXP.toString() + " id=" + widget.domNode.id);
+			}
+			runner.assertEqual(widget.label, widget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue, "id=" + widget.domNode.id);
+		}
+		function _assertCorrectIconItemPos(widgetId1, widgetId2, widgetId3, widgetId4){
+			var widget1 = registry.byId(widgetId1);
+			var widget2 = registry.byId(widgetId2);
+			var widget3 = registry.byId(widgetId3);
+			var widget4 = registry.byId(widgetId4);
+			
+			
+			runner.assertNotEqual(null, widget1, "Widget (Id=" +  widgetId1 + ") dose not exist.");
+			runner.assertNotEqual(null, widget2, "Widget (Id=" +  widgetId2 + ") dose not exist.");
+			runner.assertNotEqual(null, widget3, "Widget (Id=" +  widgetId3 + ") dose not exist.");
+			runner.assertNotEqual(null, widget4, "Widget (Id=" +  widgetId4 + ") dose not exist.");
+			runner.assertEqual(widget2.domNode.offsetTop, widget1.domNode.offsetTop, "id=" + widgetId1);
+			runner.assertEqual(widget3.domNode.offsetLeft, widget1.domNode.offsetLeft, "left id=" + widgetId1);
+			runner.assertEqual(widget3.domNode.offsetTop, widget4.domNode.offsetTop, "id=" + widgetId3);
+			runner.assertEqual(widget2.domNode.offsetLeft, widget4.domNode.offsetLeft, "left id=" + widgetId4);
+		}
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		}
+		dojo.ready(function(){
+			doh.register("dojox.mobile.test.doh.IconContainerTests", [
+				function testInView1(){
+					var widget1 = _createIconContainerDeclaratively("dojox_mobile_IconContainer_0");
+					var widget2 = _createIconContainerProgrammatically("view1-IconContainer2place", "view1-IconContainer2");
+					var widget3 = _createIconContainerProgrammaticallyWithSourceNodeReference("view1-IconContainer3");
+
+					_assertCorrectIconContainer(widget1);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("dojox_mobile_IconItem_0", "dojox_mobile_IconItem_2", "dojox_mobile_IconItem_3", "dojox_mobile_IconItem_5");
+					}
+					_assertCorrectIconContainer(widget2);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("dojox_mobile_IconItem_12", "dojox_mobile_IconItem_14", "dojox_mobile_IconItem_15", "dojox_mobile_IconItem_17");
+					}
+					_assertCorrectIconContainer(widget3);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("view1-IconContainer3-IconItem1", "view1-IconContainer3-IconItem3", "view1-IconContainer3-IconItem4", "view1-IconContainer3-IconItem6");
+					}
+				},
+				function testInView2(){
+					var widget1 = _createIconContainerDeclaratively("dojox_mobile_IconContainer_1");
+					var widget2 = _createIconContainerProgrammatically("view2-IconContainer2place", "view2-IconContainer2");
+					var widget3 = _createIconContainerProgrammaticallyWithSourceNodeReference("view2-IconContainer3");
+
+					_showView2();
+
+					_assertCorrectIconContainer(widget1);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("dojox_mobile_IconItem_6", "dojox_mobile_IconItem_8", "dojox_mobile_IconItem_9", "dojox_mobile_IconItem_11");
+					}
+					_assertCorrectIconContainer(widget2);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("dojox_mobile_IconItem_18", "dojox_mobile_IconItem_20", "dojox_mobile_IconItem_21", "dojox_mobile_IconItem_23");
+					}
+					_assertCorrectIconContainer(widget3);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("view2-IconContainer3-IconItem1", "view2-IconContainer3-IconItem3", "view2-IconContainer3-IconItem4", "view2-IconContainer3-IconItem6");
+					}
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body dir="rtl">
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<table  style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<ul data-dojo-type="dojox.mobile.IconContainer">
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"../../images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"../../images/icon-1.png", href:"../../test_iPhone-RoundRectList.html", transition:"slide"'></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url" , icon:"../../images/icon-1.png", url:"../../view-sample.html", transition:"slide"'></li>
+			</ul>
+		</td></tr></tbody></table>
+		<table style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<div id="view1-IconContainer2place"></div>
+		</td></tr></tbody></table>
+		<table style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<ul id="view1-IconContainer3">
+				<li id="view1-IconContainer3-IconItem1"><div class="box"></div></li>
+				<li id="view1-IconContainer3-IconItem2"><div class="box"></div></li>
+				<li id="view1-IconContainer3-IconItem3"><div class="box"></div></li>
+				<li id="view1-IconContainer3-IconItem4"></li>
+				<li id="view1-IconContainer3-IconItem5"></li>
+				<li id="view1-IconContainer3-IconItem6"></li>
+			</ul>
+		</td></tr></tbody></table>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<table style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<ul data-dojo-type="dojox.mobile.IconContainer">
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"../../images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"../../images/icon-1.png", href:"../../test_iPhone-RoundRectList.html", transition:"slide"'></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url" , icon:"../../images/icon-1.png", url:"../../view-sample.html", transition:"slide"'></li>
+			</ul>
+		</td></tr></tbody></table>
+		<table style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<div id="view2-IconContainer2place"></div>
+		</td></tr></tbody></table>
+		<table style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<ul id="view2-IconContainer3">
+				<li id="view2-IconContainer3-IconItem1"><div class="box"></div></li>
+				<li id="view2-IconContainer3-IconItem2"><div class="box"></div></li>
+				<li id="view2-IconContainer3-IconItem3"><div class="box"></div></li>
+				<li id="view2-IconContainer3-IconItem4"></li>
+				<li id="view2-IconContainer3-IconItem5"></li>
+				<li id="view2-IconContainer3-IconItem6"></li>
+			</ul>
+		</td></tr></tbody></table>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/IconContainer_Rtl.html b/dojox/mobile/tests/doh/bidi/IconContainer_Rtl.html
new file mode 100644
index 0000000..a74ceae
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/IconContainer_Rtl.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Icon</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/base_rtl.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/IconContainer.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/IconContainer_rtl.css" rel="stylesheet"/>
+		<style>
+			.box {
+				border: 1px solid #A7C0E0;
+				width: 300px;
+				height: 250px;
+				background-image: url(../images/widget-bg.png);
+				background-repeat: no-repeat;
+				background-color: white;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.View");
+			dojo.require("dojox.mobile.IconContainer");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+		<script type="text/javascript" src="TestUtil_Rtl.js"></script>
+		<script type="text/javascript" src="IconContainer_Rtl.js"></script>
+	</head>
+	<body dir="rtl">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
+			<ul dojoType="dojox.mobile.IconContainer">
+				<li dojoType="dojox.mobile.IconItem" label="app1" icon="../../images/icon3.png" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app2" icon="../../images/icon3.png" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app3" icon="../../images/icon3.png" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="moveTo" icon="../../images/icon3.png" moveTo="about" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="href" icon="../../images/icon3.png" href="../../test_iPhone-RoundRectList.html" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="url" icon="../../images/icon3.png" url="../../view-sample.html" transition="slide"></li>
+			</ul>
+		</div>
+
+		<div id="about" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Network											   
+				</li>												   
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Line
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="1024">
+					Songs
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/IconContainer_Rtl.js b/dojox/mobile/tests/doh/bidi/IconContainer_Rtl.js
new file mode 100644
index 0000000..44ef27d
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/IconContainer_Rtl.js
@@ -0,0 +1,64 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.IconContainer", [
+		{
+			name: "IconContainer Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
+					doh.assertEqual('mblIconContainer mblIconContainerRtl', demoWidget.domNode.className);
+					
+				}));
+				return d;
+			}
+		},
+		{
+			name: "IconItem Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
+				var e;
+				//lazy loading
+
+				doh.assertEqual('none', demoWidget.paneWidget.domNode.style.display);
+				fireOnMouseDown(demoWidget.domNode);
+				fireOnMouseUp(demoWidget.domNode);
+
+				demoWidget = dijit.byId("dojox_mobile_IconItem_1");
+				doh.assertEqual('none', demoWidget.paneWidget.domNode.style.display);
+				fireOnMouseDown(demoWidget.domNode);
+				fireOnMouseUp(demoWidget.domNode);
+
+				setTimeout(d.getTestCallback(function(){
+					verifyIconItem("dojox_mobile_IconItem_0", 'app1', '', /icon3.png/i);
+					verifyIconItem("dojox_mobile_IconItem_1", 'app2', '', /icon3.png/i);
+				}),2000);
+				return d;
+			}
+		},
+		{
+			name: "IconContainer set",
+			timeout: 4000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
+				demoWidget.set({transition:"slide", pressedIconOpacity:"0.8"});
+
+				doh.assertEqual(0.8, demoWidget.get("pressedIconOpacity"));
+				doh.assertEqual("slide", demoWidget.get("transition"));
+			}
+		},
+		{
+			name: "IconItem set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_IconItem_1");
+				demoWidget.set({icon:"../../images/icon1.png"});
+				doh.assertEqual("../../images/icon1.png", demoWidget.get("icon"));
+				doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/icon1.png/i) != -1);
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/bidi/IconMenuTests_Rtl.html b/dojox/mobile/tests/doh/bidi/IconMenuTests_Rtl.html
new file mode 100644
index 0000000..9a42460
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/IconMenuTests_Rtl.html
@@ -0,0 +1,201 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Accordion Tests</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','base_rtl','IconMenu','IconMenu_rtl']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true, has:{'dojo-bidi': true}"></script>
+	<style type="text/css">
+		@import "../../../themes/common/domButtons/DomButtonBlackRightArrow16.css";
+		@import "../../../themes/common/domButtons/DomButtonWhiteDownArrow16.css";
+		@import "../../../themes/common/dijit/dijit.css";
+		html,body{
+			height: 100%;
+		}
+		.myPane {
+			background-image: -webkit-gradient(linear, left top, left bottom, from(#dcdcdc), to(#FFFFFF));
+			font-family: Times New Roman, Helvetica;
+			color: black;
+		}
+	</style>
+
+	<script type="text/javascript">
+		var WIDGET_PROPS = [{icon:"../../images/tab-icon-36w.png", selected:true},
+							{icon:"../../images/tab-icon-32w.png"},
+							{icon:"../../images/tab-icon-30w.png"},
+							{icon:"../../images/tab-icon-16w.png"},
+							{icon:"../../images/tab-icon-19w.png"},
+							{icon:"../../images/tab-icon-29w.png"}];
+		var WIDGET_LABELS = [{label:"Mute"},
+							{label:"Keypad"},
+							{label:"Settings"},
+							{label:"Info"},
+							{label:"Tour"},
+							{label:"Contacts"}];
+		var WIDGET_CLASS = "mblIconMenu";
+		var WIDGET_CLASS_RTL = "mblIconMenu mblIconMenuRtl";
+		var WIDGET_ICON_SEL = "mblIconMenuItemSel";
+		var ITEM_NUM = 6;
+		var CHILDWIDGET_CLASSNAME1 = "mblIconMenuItem";
+		var CHILDWIDGET_CLASSNAME2 = "mblIconMenuItemFirstColumn";
+		var CHILDWIDGET_CLASSNAME3 = "mblIconMenuItemLastColumn";
+		var CHILDWIDGET_CLASSNAME4 = "mblIconMenuItemFirstRow";
+		var CHILDWIDGET_CLASSNAME5 = "mblIconMenuItemLastRow";
+		var COL_NUM = 3;
+
+		require([
+			"dojo/_base/array",
+			"dojo/_base/lang", // dojo.mixin
+			"dojo/dom-construct", // dojo.place
+			"dojo/dom-class", // dojo.hasClass
+			"dojo/ready", // dojo.ready
+			"dijit/registry",  // dijit.byId
+			"doh/runner",	//doh functions
+			"dojox/mobile/IconMenuItem",
+			"dojox/mobile/IconMenu",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/View"
+		], function(array, lang, domConst, domClass, ready, registry, runner, IconMenuItem, IconMenu){
+			function _createAccordionDeclaratively(widgetId){
+				return registry.byId(widgetId);
+			}
+			
+			function _createAccordionProgrammatically(placeHolderId, widgetId){
+				var r = new IconMenu({id:widgetId, style:{width:"274px", height:"210px", margin:"20px"}, cols:"3"});
+				runner.assertNotEqual(null, r);
+				domConst.place(r.domNode, placeHolderId, "replace");
+				r.startup();
+				var childWidget, prop;
+				for(var i = 0, len =Math.min(WIDGET_PROPS.length, WIDGET_LABELS.length); i<len ;i++){
+					childWidget = IconMenuItem(lang.mixin(prop, WIDGET_PROPS[i], WIDGET_LABELS[i]));
+					r.addChild(childWidget);
+				}
+				return r;
+			}
+			
+			function _createAccordionProgrammaticallyWithSourceNodeReference(widgetId, childWidgetId){
+				var r = new IconMenu({cols:"3"}, widgetId);
+				r.startup();
+				children = array.filter(r.domNode.childNodes, function(node){ return node.nodeType == 1; });
+				var childWidget;
+				for(var i = 0, len =Math.min(WIDGET_PROPS.length, children.length); i<len ;i++){
+					childWidget = IconMenuItem(WIDGET_PROPS[i], children[i]);
+					r.addChild(childWidget);
+				}
+				return r;
+			}
+
+			function _assertCorrectAccordion(widget){
+				if(widget.domNode.dir=="rtl"){
+					runner.assertEqual(WIDGET_CLASS_RTL, widget.domNode.className, "id= " + widget.domNode.id);
+				}else{
+					runner.assertEqual(WIDGET_CLASS, widget.domNode.className, "id= " + widget.domNode.id);
+				}
+				
+
+				var childWidgets = widget.getChildren();
+				runner.assertEqual(ITEM_NUM, childWidgets.length, "id= " + widget.domNode.id + " childWidgets.length=" + childWidgets.length);
+
+				runner.assertTrue(domClass.contains(childWidgets[0].domNode, WIDGET_ICON_SEL), WIDGET_ICON_SEL + " id=" + childWidgets[0].domNode.id);
+				for(var i=0;i< ITEM_NUM;i++){
+	 				runner.assertEqual(WIDGET_LABELS[i].label, dojo.trim(childWidgets[i].labelNode.innerHTML.replace(/\r\n|\n|\t/g,"")), "id=" + childWidgets[i].domNode.id);
+	 				switch(i % COL_NUM){
+						case 0:
+							runner.assertTrue(domClass.contains(childWidgets[i].domNode, CHILDWIDGET_CLASSNAME2), CHILDWIDGET_CLASSNAME2 + " id=" + childWidgets[i].domNode.id);
+							break;
+						case (COL_NUM-1):
+							runner.assertTrue(domClass.contains(childWidgets[i].domNode, CHILDWIDGET_CLASSNAME3), CHILDWIDGET_CLASSNAME3 + " id=" + childWidgets[i].domNode.id);
+							break;
+					}
+	 				switch(Math.floor(i / COL_NUM)){
+						case 0:
+							runner.assertTrue(domClass.contains(childWidgets[i].domNode, CHILDWIDGET_CLASSNAME4), CHILDWIDGET_CLASSNAME4 + " id=" + childWidgets[i].domNode.id);
+							break;
+						case (Math.floor(ITEM_NUM/COL_NUM) -1):
+							runner.assertTrue(domClass.contains(childWidgets[i].domNode, CHILDWIDGET_CLASSNAME5), CHILDWIDGET_CLASSNAME5 + " id=" + childWidgets[i].domNode.id);
+							break;
+					}
+				}
+			}
+
+			function _showView2(){
+				var view1 = registry.byId("view1");
+				view1.performTransition("view2", 1, "none");
+			}
+			dojo.ready(function(){
+				doh.register("dojox.mobile.test.doh.AccordionTests", [
+					function testInView1(){
+						var widget1 = _createAccordionDeclaratively("dojox_mobile_IconMenu_0");
+						var widget2 = _createAccordionProgrammatically("view1-IconMenu2place", "view1-IconMenu2");
+						var widget3 = _createAccordionProgrammaticallyWithSourceNodeReference("view1-IconMenu3");
+
+						_assertCorrectAccordion(widget1);
+						_assertCorrectAccordion(widget2);
+						_assertCorrectAccordion(widget3);
+					},
+					function testInView2(){
+						var widget1 = _createAccordionDeclaratively("dojox_mobile_IconMenu_1");
+						var widget2 = _createAccordionProgrammatically("view2-IconMenu2place", "view2-IconMenu2place");
+						var widget3 = _createAccordionProgrammaticallyWithSourceNodeReference("view2-IconMenu3");
+
+						_showView2();
+
+						_assertCorrectAccordion(widget1);
+						_assertCorrectAccordion(widget2);
+						_assertCorrectAccordion(widget3);
+					}
+				]);
+				runner.run();
+			});
+		})
+	</script>
+
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1>View 1</h1>
+		<ul data-dojo-type="dojox.mobile.IconMenu" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:3'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Mute", icon:"../../images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Keypad", icon:"../../images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Settings", icon:"../../images/tab-icon-30w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Info", icon:"../../images/tab-icon-16w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Tour", icon:"../../images/tab-icon-19w.png", moveTo:"view2", transition:"slide", closeOnAction:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Contacts", icon:"../../images/tab-icon-29w.png"'></li>
+		</ul>
+		<div id="view1-IconMenu2place"></div>
+		<div id="view1-IconMenu3" style="width:274px;height:210px;margin:20px;" >
+			<li>Mute</li>
+			<li>Keypad</li>
+			<li>Settings</li>
+			<li>Info</li>
+			<li>Tour</li>
+			<li>Contacts</li>
+		</div>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<ul data-dojo-type="dojox.mobile.IconMenu" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:3' dir="rtl">
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Mute", icon:"../../images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Keypad", icon:"../../images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Settings", icon:"../../images/tab-icon-30w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Info", icon:"../../images/tab-icon-16w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Tour", icon:"../../images/tab-icon-19w.png", moveTo:"view2", transition:"slide", closeOnAction:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Contacts", icon:"../../images/tab-icon-29w.png"'></li>
+		</ul>
+		<div id="view2-IconMenu2place"></div>
+		<div id="view2-IconMenu3" style="width:274px;height:210px;margin:20px;" >
+			<li>Mute</li>
+			<li>Keypad</li>
+			<li>Settings</li>
+			<li>Info</li>
+			<li>Tour</li>
+			<li>Contacts</li>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/ListItem2_Rtl.html b/dojox/mobile/tests/doh/bidi/ListItem2_Rtl.html
new file mode 100644
index 0000000..79f98ef
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/ListItem2_Rtl.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>ListItem</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/base_rtl.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/IconContainer.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/IconContainer_rtl.css" rel="stylesheet"/>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+
+		<script type="text/javascript" src="TestUtil_Rtl.js"></script>
+		<script type="text/javascript" src="../listitem/ListItem2.js"></script>
+	</head>
+	<body dir="rtl">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<ul dojoType="dojox.mobile.RoundRectList" iconBase="../../images/i-icon-all.png">
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">Sounds</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" moveTo="general">Brightness</li>
+			</ul>
+			<ul dojoType="dojox.mobile.EdgeToEdgeList" iconBase="../../images/i-icon-all.png">
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" rightIcon="mblDomButtonBluePlus">XX Widget</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" rightIcon="mblDomButtonRedMinus">YY Widget</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/ListItem_Rtl.html b/dojox/mobile/tests/doh/bidi/ListItem_Rtl.html
new file mode 100644
index 0000000..b3c50f1
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/ListItem_Rtl.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>ListItem</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/iphone_rtl.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons/DomButtonColorButtons.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons/DomButtonCheckboxOn.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons/DomButtonCheckboxOff.css" rel="stylesheet"/>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="../listitem/ListItem.js"></script>
+	</head>
+	<body div="rtl">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" transition="slide" url="../../view1.html">External View #1 (sync)</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-2.png" transition="flip" url="../../view2.html" sync="false">External View #2 (async)</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-3.png" transition="fade" url="../../view3.html">External View #3 (sync)</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">Video</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightText="VPN">Maps</li>
+				<li dojoType="dojox.mobile.ListItem">Jack Coleman</li>
+			</ul>
+			<ul dojoType="dojox.mobile.RoundRectList" iconBase="../../images/i-icon-all.png">
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">Sounds</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" moveTo="general">Brightness</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29" moveTo="general">Wallpaper</li>
+			</ul>
+			<ul id="list1" dojoType="dojox.mobile.EdgeToEdgeList">
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightIcon="mblDomButtonBluePlus">XX Widget</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-2.png" rightIcon="mblDomButtonRedMinus">YY Widget</li>
+			</ul>
+		    <ul id="list2" dojoType="dojox.mobile.EdgeToEdgeList">
+			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" rightIcon="mblDomButtonCheckboxOff">
+					Use wireless networks
+					<div class="mblListItemSubText">
+						See location in applications (such as Maps) using wireless networks
+					</div>
+			    </li>
+			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" rightIcon="mblDomButtonCheckboxOn">
+					Use GPS satellites
+					<div class="mblListItemSubText">
+						When locating, accurate to street level (uncheck to conserve battery)
+					</div>
+			    </li>
+			    <li dojoType="dojox.mobile.ListItem">
+					Set unlock pattern
+			    </li>
+		    </ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/RoundRectDataList_Rtl.html b/dojox/mobile/tests/doh/bidi/RoundRectDataList_Rtl.html
new file mode 100644
index 0000000..26d1983
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/RoundRectDataList_Rtl.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>RoundRectDataList</title>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.data.ItemFileWriteStore");
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.deviceTheme");
+			dojo.require("dojox.mobile.RoundRectDataList");
+
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+			var static_data = { 
+				items: [ 
+					{label: "Apple", 	moveTo: "dummy"},
+					{label: "Banana", 	moveTo: "dummy"},
+					{label: "Cherry", 	moveTo: "dummy"},
+					{label: "Grape", 	moveTo: "dummy"},
+					{label: "Kiwi", 	moveTo: "dummy"},
+					{label: "Lemon", 	moveTo: "dummy"},
+					{label: "Melon", 	moveTo: "dummy"},
+					{label: "Orange", 	moveTo: "dummy"},
+					{label: "Peach", 	moveTo: "dummy"}
+				]
+			};
+			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
+			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
+			var store = store1;
+			var newItems = [[],[]];
+
+			// switch to the selected store
+			function switchTo(store){
+				window.store = store;
+				dijit.byId("list").setStore(store);
+			}
+			// add a new item
+			function add1(){
+				var item = store.newItem({label: "New Item", moveTo: "dummy"});
+				this.newItems[(store == store1) ? 1 : 0].push(item);
+			}
+			// delete the added item
+			function delete1(){
+				var item = this.newItems[(store == store1) ? 1 : 0].pop();
+				if(item){
+					store.deleteItem(item);
+				}
+			}
+		</script>
+
+		<script type="text/javascript" src="TestUtil_Rtl.js"></script>
+		
+		<script type="text/javascript" src="RoundRectDataList_Rtl.js"></script>
+	</head>
+	<body dir="rtl">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">RoundRectDataList</h1>
+			<ul dojoType="dojox.mobile.RoundRectDataList" id="list" store="store" query="{label: '*'}"></ul>
+			<p>show the different set:<br>
+			<input type="button" value="Set1" onclick="switchTo(store1)">
+			<input type="button" value="Set2" onclick="switchTo(store2)">
+			<p>alter the object store:<br>
+			<input type="button" value="Add" onclick="add1()">
+			<input type="button" value="Delete" onclick="delete1()">
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/RoundRectDataList_Rtl.js b/dojox/mobile/tests/doh/bidi/RoundRectDataList_Rtl.js
new file mode 100644
index 0000000..dac4483
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/RoundRectDataList_Rtl.js
@@ -0,0 +1,55 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.RoundRectDataList", [
+		{
+			name: "RoundRectDataList Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					verifyListItem("dojox_mobile_ListItem_0", 'Wi-Fi', '', "mblDomButtonArrow", true, true, false, false, /i-icon-1.png/i);
+
+					verifyListItem("dojox_mobile_ListItem_3", 'General', '', "mblDomButtonArrow", true, true, false, false, /i-icon-4.png/i, true);
+					
+				}),500);
+				return d;
+			}
+		},
+		{
+			name: "RoundRectDataList Verification2",
+			timeout: 10000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+
+					add1();
+					add1();
+					add1();
+					verifyListItem("dojox_mobile_ListItem_12", 'New Item', '', "mblDomButtonArrow", false, true, false, false);
+
+					delete1();
+					demoWidget = dijit.byId("dojox_mobile_ListItem_12");
+					doh.assertTrue(!demoWidget);
+
+					verifyListItem("dojox_mobile_ListItem_11", 'New Item', '', "mblDomButtonArrow", false, true, false, false);
+
+				}),1500);
+				return d;
+			}
+		},
+		{
+			name: "RoundRectDataList Verification3",
+			timeout: 10000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+
+					switchTo(store2);
+					verifyListItem("dojox_mobile_ListItem_13", 'Apple', '', "mblDomButtonArrow", false, true, false, false);
+
+				}),2500);
+				return d;
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/bidi/RoundRectList_Rtl.html b/dojox/mobile/tests/doh/bidi/RoundRectList_Rtl.html
new file mode 100644
index 0000000..c263f6c
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/RoundRectList_Rtl.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Round Rect List</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/iphone_rtl.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		
+		</script>
+
+		<script type="text/javascript" src="TestUtil_Rtl.js"></script>
+		<script type="text/javascript" src="RoundRectList_Rtl.js"></script>
+	</head>
+	<body dir="rtl">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true" >
+			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
+			<h2 id="Category" dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="item1" dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightText="Off" moveTo="bar">u1space</li>
+				<li id="item2" dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-2.png" rightText="On" moveTo="bar">u2space</li>
+				<li id="item3" dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="bar">Wi-Fi</li>
+			</ul>
+		</div>
+
+		<div id="bar" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="foo">u1space</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
+			<ul dojoType="dojox.mobile.RoundRectList" transition="fade">
+				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="foo">Video</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightText="VPN">Maps</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">Phone Number</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/RoundRectList_Rtl.js b/dojox/mobile/tests/doh/bidi/RoundRectList_Rtl.js
new file mode 100644
index 0000000..912697a
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/RoundRectList_Rtl.js
@@ -0,0 +1,73 @@
+
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.RoundRectList", [
+		{
+			name: "RoundRectList Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("Category");
+					doh.assertEqual('mblRoundRectCategory mblRoundRectCategoryRtl', demoWidget.domNode.className);
+					doh.assertEqual('Spaces', demoWidget.domNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_RoundRectList_0");
+					doh.assertEqual('mblRoundRectList mblRoundRectListRtl', demoWidget.domNode.className);
+					verifyListItem("item1", 'u1space', 'Off', "mblDomButtonArrow", true, true, false);
+					verifyListItem("item2", 'u2space', 'On', "mblDomButtonArrow", true, true, false);
+					verifyListItem("item3", 'Wi-Fi', 'Off', "mblDomButtonArrow", false, true, false);
+					
+				}));
+				return d;
+			}
+		},
+		{
+			name: "RoundRectList Verification2",
+			timeout: 1000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				var demoWidget = dijit.byId("dojox_mobile_RoundRectList_0");
+				demoWidget.set({transition :"flip"});
+				doh.assertEqual("flip", demoWidget.get("transition"));
+				demoWidget.set({transition :"fade"});
+				doh.assertEqual("fade", demoWidget.get("transition"));
+
+//				fireOnClick("item3");
+				fireOnMouseDown("item3");
+				fireOnMouseUp("item3");
+				var view = dijit.byId("foo");
+				dojo.connect(view, "onAfterTransitionOut", this, d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_RoundRectCategory_0");
+					doh.assertEqual('mblRoundRectCategory mblRoundRectCategoryRtl', demoWidget.domNode.className);
+					doh.assertEqual('Applications', demoWidget.domNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_RoundRectList_1");
+					doh.assertEqual('mblRoundRectList mblRoundRectListRtl', demoWidget.domNode.className);
+
+					verifyListItem("dojox_mobile_ListItem_0", 'Video', 'Off', "", false, true, false);
+					verifyListItem("dojox_mobile_ListItem_1", 'Maps', 'VPN', "", true, false, false);
+					verifyListItem("dojox_mobile_ListItem_2", 'Phone Number', 'Off', "", false, false, false);
+				}));
+				return d;
+			}
+		},
+		{
+			name: "RoundRectCategory getLabel",
+			timeout: 1000,
+			runTest: function(){
+				doh.assertEqual("Spaces", dijit.byId("Category").get("label")); 
+			}
+		},
+		{
+			name: "RoundRectCategory setLabel",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("Category");
+				demoWidget.set({label :"Value Changed"});
+				doh.assertEqual("Value Changed", demoWidget.get("label"));
+				doh.assertEqual('Value Changed', demoWidget.domNode.innerHTML);
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/bidi/RoundRectStoreList_Rtl.html b/dojox/mobile/tests/doh/bidi/RoundRectStoreList_Rtl.html
new file mode 100644
index 0000000..5a79e1f
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/RoundRectStoreList_Rtl.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectStoreList</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','base_rtl']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+	<script type="text/javascript">
+		var IsEdgeToEdgeList = false;
+	</script>
+	<script type="text/javascript" src="StoreList_Rtl.js"></script>
+</head>
+<body style="visibility:hidden;" dir="rtl">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectStoreList" id="list" data-dojo-props='store:store, query:{}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/SpinWheel_Programmatic_Rtl.html b/dojox/mobile/tests/doh/bidi/SpinWheel_Programmatic_Rtl.html
new file mode 100644
index 0000000..8d42010
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/SpinWheel_Programmatic_Rtl.html
@@ -0,0 +1,153 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Custom SpinWheel</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','base_rtl','SpinWheel','SpinWheel_rtl']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom-construct", // dojo.place
+			"dojo/ready", // dojo.ready
+			"dijit/registry",  // dijit.byId
+			"doh/runner",	//doh functions
+			"dojox/mobile/SpinWheel",
+			"dojox/mobile/SpinWheelSlot",
+			"dojox/mobile",				// This is a mobile app.
+			"dojox/mobile/View",		// This mobile app uses mobile view
+			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+			"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+		], function(domConst, ready, registry, runner, SpinWheel, SpinWheelSlot){
+			ready(function(){
+				var view = registry.byId("view1");
+				var demoWidget = new SpinWheel({id:"spin1"});
+				demoWidget.placeAt(view.containerNode);
+				
+				// No initial value specified
+				var slot0 = new SpinWheelSlot({labels:['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'], 
+					style:"text-align:center;width:40px;"});
+				demoWidget.addChild(slot0);
+				
+				// Initial value: C
+				var slot1 = new SpinWheelSlot({labels:['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'], 
+					value:'C', style:"text-align:center;width:40px;"});
+				demoWidget.addChild(slot1);
+
+				// No initial value specified
+				var slot2 = new SpinWheelSlot({labelFrom:3000, labelTo:3100, style:"width:70px;"});
+				demoWidget.addChild(slot2);
+				
+				// Initial value: 3009 
+				var slot3 = new SpinWheelSlot({labelFrom:3000, labelTo:3100, value:3009, style:"width:70px;"});
+				demoWidget.addChild(slot3);
+
+				domConst.create("div", {className: "mblSpinWheelSlot", id:"pt"}, demoWidget.containerNode);
+				domConst.create("div", {className: "mblSpinWheelSlot", id:"txt", innerHTML:"."}, demoWidget.containerNode);
+
+				var slot4 = new SpinWheelSlot({labelFrom:0, labelTo:9, style:"width:30px;"});
+				demoWidget.addChild(slot4);
+
+				var slot5 = new SpinWheelSlot({labels:['pt','px','cm'], style:"width:50px;"});
+				demoWidget.addChild(slot5);
+
+				var slot6 = new SpinWheelSlot({
+					labels:[
+					'<img src=../images/i-icon-1.png>',
+					'<img src=../images/i-icon-2.png>',
+					'<img src=../images/i-icon-3.png>',
+					'<img src=../images/i-icon-4.png>',
+					'<img src=../images/i-icon-5.png>',
+					'<img src=../images/i-icon-6.png>',
+					'<img src=../images/i-icon-7.png>',
+					'<img src=../images/i-icon-8.png>',
+					'<img src=../images/i-icon-9.png>',
+					'<img src=../images/i-icon-10.png>'
+					],
+					style:"width:70px;text-align: center;"
+				});
+				demoWidget.addChild(slot6);
+
+				var slot7 = new SpinWheelSlot({
+					items:[
+						['key1', 'value1'], 
+						['key2', 'value2'],
+						['key2', 'value2']
+					],
+					value:'value2',
+					style:"text-align:center;width:40px;"});
+				demoWidget.addChild(slot7);
+
+				demoWidget.reset();
+			});
+		})
+	</script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready", // dojo.ready
+			"dijit/registry",  // dijit.byId
+			"doh/runner",	//doh functions
+			"dojox/mobile/SpinWheel",
+			"dojox/mobile/SpinWheelSlot",
+			"dojox/mobile",				// This is a mobile app.
+			"dojox/mobile/View",		// This mobile app uses mobile view
+			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+			"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+		], function(ready, registry, runner, SpinWheel, SpinWheelSlot){
+			ready(function(){
+				runner.register("dojox.mobile.test.doh.SpinWheel", [
+					{
+						name: "SpinWheel Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = registry.byId("spin1");
+								var slots = demoWidget.getSlots();
+								doh.assertEqual('A', slots[0].get("value"));
+								doh.assertEqual('C', slots[1].get("value"));
+								doh.assertEqual('3000', slots[2].get("value"));
+								doh.assertEqual('3009', slots[3].get("value"));
+								doh.assertEqual('0', slots[4].get("value"));
+								doh.assertEqual('pt', slots[5].get("value"));
+								doh.assertEqual('<img src=../images/i-icon-1.png>', slots[6].get("value"));
+								doh.assertEqual('value2', slots[7].get("value"));
+							}),2000);
+							return d;
+						}
+					}
+				]);
+				runner.run();
+			});
+			
+		})
+	</script>
+
+	<style>
+	#spin1 {
+		width: 304px;
+		margin: 10px auto;
+	}
+	#pt {
+		width: 20px;
+	}
+	#txt {
+		width: 10px;
+		margin-left: -15px;
+		padding-top: 85px;
+		font-size: 24px;
+		font-weight: bold;
+		border: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;" dir="rtl">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Custom SpinWheel</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/StoreList_Rtl.js b/dojox/mobile/tests/doh/bidi/StoreList_Rtl.js
new file mode 100644
index 0000000..8dc4742
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/StoreList_Rtl.js
@@ -0,0 +1,152 @@
+require([
+	"dojo/_base/Deferred",
+	"dojo/store/Cache",
+	"dojo/store/JsonRest",
+	"dojo/store/Memory",
+	"dojo/store/Observable",
+	"dojo/ready", // dojo.ready
+	"dijit/registry",
+	"doh/runner",	//doh functions
+	"dojox/mobile/EdgeToEdgeStoreList",
+	"dojox/mobile/RoundRectStoreList",
+	"dojox/mobile/parser",
+	"dojox/mobile",
+	"dojox/mobile/compat"
+], function(Deferred, Cache, JsonRest, Memory, Observable, ready, registry, runner, EdgeToEdgeStoreList, RoundRectStoreList){
+
+	var CLASS_NAME;
+	var DataList;
+	var testName;
+
+	if(IsEdgeToEdgeList){
+		CLASS_NAME = "mblEdgeToEdgeList";
+		DataList = EdgeToEdgeStoreList;
+		testName = "dojox.mobile.test.doh.EdgeToEdgeStoreList_Rtl";
+	}else{
+		CLASS_NAME = "mblRoundRectList";
+		DataList = RoundRectStoreList;
+		testName = "dojox.mobile.test.doh.RoundRectStoreList_Rtl";
+	}
+
+	var static_data2 = [
+		{label: "Apple", 	moveTo: "dummy"},
+		{label: "Banana", 	moveTo: "dummy"},
+		{label: "Cherry", 	moveTo: "dummy"},
+		{label: "Grape", 	moveTo: "dummy"},
+		{label: "Kiwi", 	moveTo: "dummy"},
+		{label: "Lemon", 	moveTo: "dummy"},
+		{label: "Melon", 	moveTo: "dummy"},
+		{label: "Orange", 	moveTo: "dummy"},
+		{label: "Peach", 	moveTo: "dummy"}
+	];
+	var url = "settings2.json";
+	store1 = new JsonRest({idProperty:"label", target: url});
+	store2 = Observable(new Memory({idProperty:"label", data: static_data2}));
+	store1.__counter = store2.__counter = 1;
+	store = store1;
+
+	// switch to the selected store
+	switchTo = function(store){
+		window.store = store;
+		registry.byId("list").setStore(store);
+	};
+	// add a new item
+	add1 = function(){
+		store.add({
+			label: "New Item "+(store.__counter++),
+			icon: "../../images/i-icon-1.png",
+			moveTo: "dummy"
+		});
+	};
+	// delete the added item
+	delete1 = function(){
+		if(store.__counter > 1){
+			store.remove("New Item "+(--store.__counter));
+		}
+	};
+
+	ready(function(){
+		runner.register(testName, [
+			{
+				name: DataList + " Verification",
+				timeout: 4000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var demoWidget = registry.byId("dojox_mobile_ListItem_0");
+						runner.assertEqual('mblListItem mblListItemRtl', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertTrue(demoWidget.iconNode.src.search(/i-icon-1.png/i) != -1);
+						runner.assertEqual('mblListItemRightIcon', demoWidget.rightIconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('Wi-Fi', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						demoWidget = registry.byId("dojox_mobile_ListItem_3");
+						runner.assertEqual('mblListItem mblListItemRtl mblListItemSelected', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertTrue(demoWidget.iconNode.src.search(/i-icon-4.png/i) != -1);
+						runner.assertEqual('mblListItemRightIcon', demoWidget.rightIconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('General', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+						
+					}),500);
+					return d;
+				}
+			},
+			{
+				name: DataList + " Verification2",
+				timeout: 10000,
+				runTest: function(){
+					var d = new doh.Deferred();
+					setTimeout(d.getTestCallback(function(){
+
+						switchTo(store2);
+						var demoWidget = registry.byId("dojox_mobile_ListItem_13");
+						runner.assertEqual('mblListItem mblListItemRtl', demoWidget.domNode.className);
+						runner.assertEqual(null, demoWidget.iconNode);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('Grape', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+
+					}),2500);
+					return d;
+				}
+			},
+			{
+				name: DataList + " Verification3",
+				timeout: 10000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+
+						add1();
+						add1();
+						add1();
+						var demoWidget = registry.byId("dojox_mobile_ListItem_19");
+						runner.assertEqual('mblListItem mblListItemRtl', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('New Item 1', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						delete1();
+						demoWidget = registry.byId("dojox_mobile_ListItem_21");
+						runner.assertTrue(!demoWidget);
+
+						demoWidget = registry.byId("dojox_mobile_ListItem_20");
+						runner.assertEqual('mblListItem mblListItemRtl', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('New Item 2', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+					}),1500);
+					return d;
+				}
+			}
+		]);
+		runner.run();
+	});
+});
diff --git a/dojox/mobile/tests/doh/bidi/SwapViewTests1_Rtl.html b/dojox/mobile/tests/doh/bidi/SwapViewTests1_Rtl.html
new file mode 100644
index 0000000..6b6cfaa
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/SwapViewTests1_Rtl.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>SwapView Tests</title>
+<link href="css/test.css" rel="stylesheet"/>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY = 0;
+</script>
+<script type="text/javascript" src="SwapViewTests_rtl.js"></script>
+</head>
+<body style="visibility:hidden;" dir="rtl">
+	<div id="foo" data-dojo-type="dojox.mobile.SwapView" data-dojo-props='selected:true'>
+		<h1>SwapView 1</h1>
+	</div>
+
+	<div id="bar" data-dojo-type="dojox.mobile.SwapView">
+		<h1>SwapView 2</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/SwapViewTests_rtl.js b/dojox/mobile/tests/doh/bidi/SwapViewTests_rtl.js
new file mode 100644
index 0000000..82841a6
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/SwapViewTests_rtl.js
@@ -0,0 +1,101 @@
+require([
+	"dojo/_base/connect",
+	"dojo/dom-construct", // dojo.place
+	"dojo/dom-class", // dojo.hasClass
+	"dojo/ready", // dojo.ready
+	"dijit/registry",  // dijit.byId
+	"doh/runner",	//doh functions
+	"dojox/mobile/SwapView",	// This mobile app uses mobile view
+	"dojox/mobile",				// This is a mobile app.
+	"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+	"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+], function(connect, domConst, domClass, ready, registry, runner, SwapView){
+
+
+	var timeoutInterval = 1000;
+	var WIDGET_CLASSNAME1 = "mblView";
+	var WIDGET_CLASSNAME2 = "mblSwapView";
+
+
+	function _createSwapViewDeclaratively(widgetId) {
+		return registry.byId(widgetId);
+	};
+
+	function _createSwapViewProgrammatically(placeHolderId, widgetId, selected, innerHTML){
+		// Create SwapView
+		var r = new dojox.mobile.SwapView({id:widgetId, selected:selected, innerHTML:innerHTML});
+		runner.assertNotEqual(null, r);
+		domConst.place(r.domNode, placeHolderId, "replace");
+		r.startup();
+		
+		return r;
+	};
+
+	function _createSwapViewProgrammaticallyWithSourceNodeReference(widgetId, selected){
+		// Create IconContainer
+		var r = new SwapView({selected:selected}, widgetId);
+
+		r.startup();
+		return r;
+	};
+
+	function _assertCorrectSwapView(widget, display){
+		runner.assertNotEqual(null, widget, "IconContainer: Did not instantiate.");
+		runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1);
+		runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2);
+		runner.assertEqual(display?"":"none", widget.domNode.style.display, "widget.domNode.style.display");
+		
+	};
+
+	function _assertCorrectSwapViewPos(widgetId, top, left){
+	};
+
+
+	ready(function(){
+		if(WIDGET_PROGRAMMATICALLY === 1){
+			_createSwapViewProgrammatically("fooPlace", "foo", true, "<h1>SwapView 1</h1>");
+			_createSwapViewProgrammatically("barPlace", "bar", false, "<h1>SwapView 2</h1>");
+		}else if(WIDGET_PROGRAMMATICALLY === 2){
+			_createSwapViewProgrammaticallyWithSourceNodeReference("foo", true);
+			_createSwapViewProgrammaticallyWithSourceNodeReference("bar", false);
+		}
+
+		runner.register("dojox.mobile.test.doh.SwapViewTests", [
+			{
+				name: "SwapView Verification1",
+				timeout: 4000,
+				runTest: function(){
+
+					var widget1 = registry.byId("foo");
+					var widget2 = registry.byId("bar");
+
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var widget1 = registry.byId("foo");
+						var widget2 = registry.byId("bar");
+						_assertCorrectSwapView(widget1, true);
+						_assertCorrectSwapView(widget2, false);
+						widget1.goTo(-1);
+					}), timeoutInterval);
+					return d;
+			
+				}
+			},
+			{
+				name: "SwapView Verification2",
+				timeout: 4000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var widget1 = registry.byId("foo");
+						var widget2 = registry.byId("bar");
+						_assertCorrectSwapView(widget1, false);
+						_assertCorrectSwapView(widget2, true);
+					}), timeoutInterval);
+					return d;
+				}
+			}
+		]);
+		runner.run();
+	});
+})
diff --git a/dojox/mobile/tests/doh/bidi/SwitchTests_Rtl.html b/dojox/mobile/tests/doh/bidi/SwitchTests_Rtl.html
new file mode 100644
index 0000000..24b073d
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/SwitchTests_Rtl.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Switch Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script language="JavaScript" type="text/javascript">
+	require([
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/Switch",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(domConst, ready, registry, runner, Switch){
+		function _createSwitchDeclaratively(id) {
+			return registry.byId(id);
+		};
+		
+		function _createSwitchProgrammatically(placeHolderId){
+			var widget = new Switch();
+			runner.assertNotEqual(null, widget);
+			domConst.place(widget.domNode, placeHolderId, "replace");
+			widget.startup();
+			return widget;
+		};
+		
+		function _createSwitchProgrammaticallyWithSourceNodeReference(id){
+			var widget = new Switch({}, id);
+			widget.startup();
+			return widget;
+		};
+
+		function _assertCorrectSwitch(switchButton){
+			runner.assertNotEqual(null, switchButton);
+			runner.assertEqual("on", switchButton.value);
+			switchButton.set("value", "off");
+			runner.assertEqual("off", switchButton.value);		
+		};
+		
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		};
+
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.SwitchTests", [
+				function testInView1(){
+					var switch1 = _createSwitchDeclaratively("view1-switch1");
+					var switch2 = _createSwitchProgrammatically("view1-switch2");
+					var switch3 = _createSwitchProgrammaticallyWithSourceNodeReference("view1-switch3");
+			
+					_assertCorrectSwitch(switch1);
+					_assertCorrectSwitch(switch2);
+					_assertCorrectSwitch(switch3);
+				},
+				function testInView2(){
+					var switch1 = _createSwitchDeclaratively("view2-switch1");
+					var switch2 = _createSwitchProgrammatically("view2-switch2");
+					var switch3 = _createSwitchProgrammaticallyWithSourceNodeReference("view2-switch3");
+					
+					_showView2();
+					
+					_assertCorrectSwitch(switch1);
+					_assertCorrectSwitch(switch2);
+					_assertCorrectSwitch(switch3);
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true" dir="rtl">
+		<h1>View 1</h1>
+		<div id="view1-switch1" data-dojo-type="dojox.mobile.Switch"></div>
+		<div id="view1-switch2"></div>
+		<div id="view1-switch3"></div>
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.View" dir="rtl">
+		<h1>View 2</h1>
+		<div id="view2-switch1" data-dojo-type="dojox.mobile.Switch"></div>
+		<div id="view2-switch2"></div>
+		<div id="view2-switch3"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/Switch_Rtl.html b/dojox/mobile/tests/doh/bidi/Switch_Rtl.html
new file mode 100644
index 0000000..0507a9d
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/Switch_Rtl.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Switch RTL</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/iphone_rtl.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<style>
+		.color1 .mblSwitchBgLeft {
+			background: -webkit-gradient(linear, left top, left bottom, from(#28B159), to(#75FBAC), color-stop(0.5, #3FEB84), color-stop(0.5, #4CEE8E));
+		}
+		.color1 .mblSwitchBgRight {
+			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+		}
+		.color2 .mblSwitchBgLeft {
+			background: -webkit-gradient(linear, left top, left bottom, from(#FF9D00), to(#FFCE80), color-stop(0.5, #FFBB4D), color-stop(0.5, #FFC871));
+		}
+		.color2 .mblSwitchBgRight {
+			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+		}
+		.color1 .mblSwitchKnob,
+		.color2 .mblSwitchKnob {
+			background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#FAFAFA), color-stop(0.5, #BBBBBB), color-stop(0.5, #CACACA));
+		}
+		.float {
+			float: right;
+			margin-right: 10px;
+		}
+		.bold {
+			font-weight: bold;
+		}
+		</style>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+
+		</script>
+		<script type="text/javascript" src="Switch_rtl.js"></script>
+	</head>
+	<body style="padding:15px;visibility:visible">
+		<div dojoType="dojox.mobile.View" selected="true" dir="rtl">
+			<div dojoType="dojox.mobile.RoundRect" shadow="true">
+				<span class="bold">Default Shape</span><br>
+				<div class="float" dojoType="dojox.mobile.Switch" value="off"></div>
+				<div dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+			</div>
+
+			<div dojoType="dojox.mobile.RoundRect" shadow="true">
+				<span class="bold">Round Shape 1</span><br>
+				<div class="mblSwRoundShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
+				<div class="mblSwRoundShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+			</div>
+
+			<div dojoType="dojox.mobile.RoundRect" shadow="true">
+				<span class="bold">Round Shape 2</span><br>
+				<div class="mblSwRoundShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
+				<div class="mblSwRoundShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+			</div>
+
+			<div dojoType="dojox.mobile.RoundRect" shadow="true">
+				<span class="bold">Arc Shape 1</span><br>
+				<div class="mblSwArcShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
+				<div class="mblSwArcShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+			</div>
+
+			<div dojoType="dojox.mobile.RoundRect" shadow="true">
+				<span class="bold">Arc Shape 2</span><br>
+				<div class="mblSwArcShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
+				<div class="mblSwArcShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/Switch_rtl.js b/dojox/mobile/tests/doh/bidi/Switch_rtl.js
new file mode 100644
index 0000000..87506fe
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/Switch_rtl.js
@@ -0,0 +1,64 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.Switch", [
+		{
+			name: "Switch Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_Switch_0");
+					doh.assertTrue(demoWidget.domNode.className.search(/mblSwitch/i) != -1);
+					doh.assertTrue(demoWidget.domNode.className.search(/mblSwitchOff/i) != -1);
+					doh.assertTrue(demoWidget.domNode.className.search(/float/i) != -1);
+
+					doh.assertEqual('mblSwitchInner', demoWidget.inner.className);
+					doh.assertEqual('mblSwitchBg mblSwitchBgLeft mblSwitchBgLeftRtl', demoWidget.inner.childNodes[0].className);
+					doh.assertEqual('none', demoWidget.inner.childNodes[0].style.display);
+					doh.assertEqual('mblSwitchText mblSwitchTextLeft mblSwitchTextLeftRtl', demoWidget.inner.childNodes[0].childNodes[0].className);
+					doh.assertEqual('ON', demoWidget.inner.childNodes[0].childNodes[0].innerHTML);
+					doh.assertEqual('mblSwitchBg mblSwitchBgRight mblSwitchBgRightRtl', demoWidget.inner.childNodes[1].className);
+					doh.assertEqual('mblSwitchText mblSwitchTextRight mblSwitchTextRightRtl', demoWidget.inner.childNodes[1].childNodes[0].className);
+					doh.assertEqual('OFF', demoWidget.inner.childNodes[1].childNodes[0].innerHTML);
+					doh.assertEqual('mblSwitchKnob', demoWidget.inner.childNodes[2].className);
+
+					demoWidget = dijit.byId("dojox_mobile_Switch_1");
+					doh.assertEqual('mblSwitch mblSwitchRtl mblSwDefaultShape mblSwitchOn', demoWidget.domNode.className);
+					doh.assertEqual('mblSwitchInner', demoWidget.inner.className);
+					doh.assertEqual('mblSwitchBg mblSwitchBgLeft mblSwitchBgLeftRtl', demoWidget.inner.childNodes[0].className);
+					doh.assertEqual('mblSwitchText mblSwitchTextLeft mblSwitchTextLeftRtl', demoWidget.inner.childNodes[0].childNodes[0].className);
+					doh.assertEqual('Start', demoWidget.inner.childNodes[0].childNodes[0].innerHTML);
+					doh.assertEqual('mblSwitchBg mblSwitchBgRight mblSwitchBgRightRtl', demoWidget.inner.childNodes[1].className);
+					doh.assertEqual('none', demoWidget.inner.childNodes[1].style.display);
+					doh.assertEqual('mblSwitchText mblSwitchTextRight mblSwitchTextRightRtl', demoWidget.inner.childNodes[1].childNodes[0].className);
+					doh.assertEqual('Stop', demoWidget.inner.childNodes[1].childNodes[0].innerHTML);
+					doh.assertEqual('mblSwitchKnob', demoWidget.inner.childNodes[2].className);
+					
+				}));
+				return d;
+			}
+		},
+		{
+			name: "Switch set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_Switch_0");
+				demoWidget.set({value :"on"});
+				doh.assertEqual("on", demoWidget.get("value"));
+//							doh.assertEqual('none', demoWidget.inner.childNodes[1].style.display);
+			}
+		},
+		{
+			name: "Switch set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_Switch_0");
+				demoWidget.set({leftLabel :"Start", rightLabel:"Stop"});
+				doh.assertEqual("Start", demoWidget.get("leftLabel"));
+				doh.assertEqual("Stop", demoWidget.get("rightLabel"));
+				doh.assertEqual('Start', demoWidget.inner.childNodes[0].childNodes[0].innerHTML);
+				doh.assertEqual('Stop', demoWidget.inner.childNodes[1].childNodes[0].innerHTML);
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/bidi/TabBarTests_Rtl.html b/dojox/mobile/tests/doh/bidi/TabBarTests_Rtl.html
new file mode 100644
index 0000000..9141a2b
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/TabBarTests_Rtl.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Tab Bar Tests</title>
+<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+<link href="../../../themes/iphone/iphone_rtl.css" rel="stylesheet"/>
+<script type="text/javascript" src="../../../../../dojo/dojo.js"
+	djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+<script language="JavaScript" type="text/javascript">
+	require([
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/TabBar",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(domConst, ready, registry, runner, TabBar, TabBarButton){
+
+		function _assertCorrectTabBar(tabBar){
+			var tabBarButton = registry.byId(tabBar.domNode.children[0].id);
+			runner.assertNotEqual(null, tabBarButton);
+			
+			var tabBarWidth = tabBar.domNode.clientWidth;
+			var tabBarButtonWidth = tabBarButton.domNode.clientWidth;
+			var tabBarButtonMarginRight = parseInt(tabBarButton.domNode.style.marginRight);
+			var actualOffsetLeft = Math.floor((tabBarWidth - tabBarButtonWidth) / 2);
+
+			var offsetLeft = tabBar.domNode.children[0].offsetLeft;
+			var clientWidth = tabBar.domNode.clientWidth;
+			runner.assertTrue( (((actualOffsetLeft *0.95) < offsetLeft) && (offsetLeft < (actualOffsetLeft *1.05))) || (offsetLeft <= 6), "expected: " +actualOffsetLeft + "+-5% but got " + offsetLeft + tabBar.toString());
+		}
+
+		function _createTabBarDeclaratively(tabBarId){
+			return registry.byId(tabBarId);
+		};
+		
+		function _createTabBarProgrammatically(placeHolderId){
+			var tabBar = new TabBar();
+			var tabBarButton = new TabBarButton({label:"Tab Bar Button",icon1:"../../images/tab-icon-16.png",icon2:"../../images/tab-icon-16h.png",selected:true});
+			runner.assertNotEqual(null, tabBarButton, "id=" + placeHolderId);
+			tabBar.addChild(tabBarButton);
+			domConst.place(tabBar.domNode, placeHolderId, "replace");
+			tabBar.startup();
+			return tabBar;
+		};
+		
+		function _createTabBarProgrammaticallyWithSourceNodeReference(tabBarId){
+			var tabBar = new TabBar({}, tabBarId);
+			var tabBarButton = new TabBarButton({label:"Tab Bar Button",icon1:"../../images/tab-icon-16.png",icon2:"../../images/tab-icon-16h.png",selected:true});
+			runner.assertNotEqual(null, tabBarButton, "id=" + tabBarId);
+			tabBar.addChild(tabBarButton);
+			tabBar.startup();
+			return tabBar;
+		};
+
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		};
+
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.TabBarTests", [
+				function testInView1(){
+					var tabBar1 = _createTabBarDeclaratively("view1-tabBar1");
+					tabBar1.resize();
+			
+					var tabBar2 = _createTabBarProgrammatically("view1-tabBar2");
+					var tabBar3 = _createTabBarProgrammaticallyWithSourceNodeReference("view1-tabBar3");
+					
+					_assertCorrectTabBar(tabBar1);
+					_assertCorrectTabBar(tabBar2);
+					_assertCorrectTabBar(tabBar3);
+				},
+				function testInView2(){
+					var tabBar1 = _createTabBarDeclaratively("view2-tabBar1");
+					var tabBar2 = _createTabBarProgrammatically("view2-tabBar2");
+					var tabBar3 = _createTabBarProgrammaticallyWithSourceNodeReference("view2-tabBar3");
+					
+					_showView2();
+					
+					_assertCorrectTabBar(tabBar1);
+					_assertCorrectTabBar(tabBar2);
+					_assertCorrectTabBar(tabBar3);				
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<ul id="view1-tabBar1" data-dojo-type="dojox.mobile.TabBar">
+			<li id="view1-tabBarButton" data-dojo-type="dojox.mobile.TabBarButton" label="Tab Bar Button" icon1="../../images/tab-icon-16.png" icon2="../../images/tab-icon-16h.png" selected=true></li>
+		</ul>
+		<div id="view1-tabBar2"></div>
+		<ul id="view1-tabBar3"></ul>		
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<ul id="view2-tabBar1" data-dojo-type="dojox.mobile.TabBar">
+			<li id="view2-tabBarButton" data-dojo-type="dojox.mobile.TabBarButton" icon1="../../images/tab-icon-16.png" icon2="../../images/tab-icon-16h.png" selected="true">Tab Bar Button</li>
+		</ul>
+		<div id="view2-tabBar2"></div>
+		<ul id="view2-tabBar3"></ul>		
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/TabBar_Rtl.html b/dojox/mobile/tests/doh/bidi/TabBar_Rtl.html
new file mode 100644
index 0000000..bfab484
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/TabBar_Rtl.html
@@ -0,0 +1,69 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>TabBar</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/iphone_rtl.css" rel="stylesheet"/>
+		<style>
+		.label {
+			font-family: "Helvetica Neue", Helvetica;
+			font-size: 13px;
+			margin-top: 20px;
+		}
+		.view {
+			font-size: 30px;
+			margin-top: 30px;
+			text-align: center;
+		}
+		</style>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.TabBar");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+	        dojo.require("doh.runner");
+		</script>
+		<script type="text/javascript" src="TestUtil_Rtl.js"></script>
+		<script type="text/javascript" src="TabBar_rtl.js"></script>
+	</head>
+	<body dir="rtl">
+		<div class="label">Segmented Control</div>
+		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
+			<li dojoType="dojox.mobile.TabBarButton" moveTo="view1" selected="true">New</li>
+			<li dojoType="dojox.mobile.TabBarButton" moveTo="view2">What's Hot</li>
+			<li dojoType="dojox.mobile.TabBarButton" moveTo="view3">Genius</li>
+		</ul>
+
+		<div class="label">Tab Bar</div>
+		<ul dojoType="dojox.mobile.TabBar">
+			<li dojoType="dojox.mobile.TabBarButton" icon1="../../images/tab-icon-16.png" icon2="../../images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
+			<li dojoType="dojox.mobile.TabBarButton" icon1="../../images/tab-icon-15.png" icon2="../../images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
+			<li dojoType="dojox.mobile.TabBarButton" icon1="../../images/tab-icon-10.png" icon2="../../images/tab-icon-10h.png" moveTo="view3">Genius</li>
+		</ul>
+
+		<div class="label">Tab Bar (CSS Sprite)</div>
+		<ul dojoType="dojox.mobile.TabBar" iconBase="../../images/tab-icons.png">
+			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Featured</li>
+			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,29,29,29" iconPos2="29,29,29,29">Categories</li>
+			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,58,29,29" iconPos2="29,58,29,29">Top 25</li>
+			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,87,29,29" iconPos2="29,87,29,29">Search</li>
+			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,116,29,29" iconPos2="29,116,29,29">Updates</li>
+		</ul>
+
+		<div id="view1" dojoType="dojox.mobile.View" selected="true">
+			<div class="view">View 1</div>
+		</div>
+		<div id="view2" dojoType="dojox.mobile.View">
+			<div class="view">View 2</div>
+		</div>
+		<div id="view3" dojoType="dojox.mobile.View">
+			<div class="view">View 3</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/TabBar_rtl.js b/dojox/mobile/tests/doh/bidi/TabBar_rtl.js
new file mode 100644
index 0000000..725bb77
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/TabBar_rtl.js
@@ -0,0 +1,66 @@
+dojo.addOnLoad(function(){
+	var CLASSNAMES1 = ["mblTabBarButton", "mblTabBarButtonRtl", "mblTabBarButtonSelected"];
+	var CLASSNAMES2 = ["mblTabBarButton", "mblTabBarButtonRtl", "mblTabBarButtonHasIcon", "mblTabBarButtonSelected"];
+	doh.register("dojox.mobile.test.doh.TabBar", [
+		{
+			name: "TabBar and TabBarButton Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_TabBar_0");
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBar mblTabBarRtl'),'mblTabBar mblTabBarRtl ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBarSegmentedControl'), 'mblTabBarSegmentedControl ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+
+					verifyTabBarButton("dojox_mobile_TabBarButton_0", 'New', CLASSNAMES1, 'hidden', '', /tab-icon-16.png/i, /tab-icon-16h.png/);
+
+					demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBar mblTabBarRtl'),'mblTabBar mblTabBarRtl ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBarTabBar'), 'mblTabBarTabBar ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+
+					verifyTabBarButton("dojox_mobile_TabBarButton_3", 'New', CLASSNAMES2, 'hidden', '', /tab-icon-16.png/i, /tab-icon-16h.png/);
+
+					demoWidget = dijit.byId("dojox_mobile_TabBar_2");
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBar mblTabBarRtl'),'mblTabBar mblTabBarRtl ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBarTabBar'), 'mblTabBarTabBar ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+
+					verifyTabBarButton("dojox_mobile_TabBarButton_6", 'Featured', CLASSNAMES2, 'hidden', '', /tab-icons.png/i, /tab-icons.png/i, true);
+					demoWidget = dijit.byId("dojox_mobile_TabBarButton_6");
+					verifyRect(demoWidget.iconNode1.childNodes[0], "0px", "29px", "29px", "0px");
+					verifyRect(demoWidget.iconNode2.childNodes[0], "29px", "29px", "58px", "0px");
+				}),500);
+				return d;
+			}
+		},
+		{
+			name: "TabBar and TabBarButton set",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_TabBar_0");
+
+
+					demoWidget = dijit.byId("dojox_mobile_TabBarButton_2");
+					demoWidget.set({label:"New Value"});
+					demoWidget.set({selected:true});
+
+					verifyTabBarButton("dojox_mobile_TabBarButton_2", 'New Value', CLASSNAMES1, 'hidden', '', /tab-icon-10.png/i, /tab-icon-10h.png/);
+					demoWidget = dijit.byId("dojox_mobile_TabBarButton_5");
+					demoWidget.set({label:"New Value", icon1:"../../images/tab-icon-11.png", icon2:"../../images/tab-icon-11h.png"});
+					demoWidget.set("selected",true);
+
+					verifyTabBarButton("dojox_mobile_TabBarButton_5", 'New Value', CLASSNAMES2, 'hidden', '', /tab-icon-11.png/i, /tab-icon-11h.png/)
+
+					demoWidget = dijit.byId("dojox_mobile_TabBarButton_4");
+					demoWidget.set({icon1:null, icon2:null});
+					doh.assertEqual(null, demoWidget.iconNode1, demoWidget.domNode.id);
+					doh.assertEqual(null, demoWidget.iconNode2, demoWidget.domNode.id);
+
+				}),500);
+				return d;
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/bidi/TestUtil_Rtl.js b/dojox/mobile/tests/doh/bidi/TestUtil_Rtl.js
new file mode 100644
index 0000000..f0206a8
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/TestUtil_Rtl.js
@@ -0,0 +1,174 @@
+//dojo.require("dojo.has");
+
+require([
+	"dijit/_base/manager",  // dijit.byId
+	"doh/runner"	//doh functions
+]);
+
+function fireOnMouseDown(obj){
+	var anchorNode;
+	if(typeof obj === "string"){
+		var demoWidget = dijit.byId(obj);
+		anchorNode = demoWidget.domNode;
+	}else{
+		anchorNode = obj;
+	}
+	if(dojo.isIE<9){
+		anchorNode.fireEvent( "onmousedown" );
+	}else{
+		var eventName = "mousedown";
+		if (dojo.isIE >= 10){
+			eventName = "MSPointerDown";
+		}
+		var e = document.createEvent('Events');
+		e.initEvent(eventName, true, true);
+		anchorNode.dispatchEvent(e);
+	}
+}
+function fireOnMouseUp(obj){
+	var anchorNode;
+	if(typeof obj === "string"){
+		var demoWidget = dijit.byId(obj);
+		anchorNode = demoWidget.domNode;
+	}else{
+		anchorNode = obj;
+	}
+	if(dojo.isIE<9){
+		anchorNode.fireEvent( "onmouseup" );
+	}else{
+		var eventName = "mouseup";
+		if (dojo.isIE >= 10){
+			eventName = "MSPointerUp";
+		}
+		var e = document.createEvent('Events');
+		e.initEvent(eventName, true, true);
+		anchorNode.dispatchEvent(e);
+	}
+}
+
+function verifyListItem(id, text, rightText, domButtonType, hasIcon, hasRightIcon, hasIcon2, hasVariableHeight, regExp, hasSelected, isSprite){
+	var demoWidget = dijit.byId(id);
+	doh.assertNotEqual(null, demoWidget, "ListItem: Did not instantiate. id=" + id);
+	doh.assertEqual('mblListItem mblListItemRtl' + (hasVariableHeight ?" mblVariableHeight":"") + (hasSelected ?" mblListItemSelected":""), demoWidget.domNode.className, "id=" + id);
+	var childNodes = demoWidget.domNode.children;
+	var i=0;
+	if(hasIcon){
+		if(!dojo.isIE && regExp){
+			if(isSprite){
+				doh.assertTrue(childNodes[i].childNodes[0].src.search(regExp) != -1, "search " + regExp.toString());
+			}else{
+				doh.assertTrue(childNodes[i].src.search(regExp) != -1, "search " + regExp.toString());
+			}
+		}
+		doh.assertTrue(dojo.hasClass(childNodes[i], 'mblListItemIcon'), 'mblListItemIcon id=' + id + " got: " + childNodes[i].className);
+		i++;
+	}
+
+	if(hasRightIcon){
+		if(domButtonType){
+			doh.assertEqual(domButtonType + ' mblDomButton', childNodes[i].childNodes[0].className, "id=" + id);
+		}
+		doh.assertTrue(dojo.hasClass(childNodes[i], 'mblListItemRightIcon'), 'mblListItemRightIcon id=' + id + " got: " + childNodes[i].className);
+		i++;
+	}
+
+	if(hasIcon2){
+		doh.assertTrue(dojo.hasClass(childNodes[i], 'mblListItemRightIcon2'), 'mblListItemRightIcon2 id=' + id + " got: " + childNodes[i].className);
+		i++;
+	}
+
+	if(rightText){
+		doh.assertEqual(rightText, dojo.isFF ==3.6 ? childNodes[i].childNodes[0].innerHTML : childNodes[i].innerHTML, "id=" + id); //2 0r 3
+		doh.assertEqual('mblListItemRightText', childNodes[i++].className, "id=" + id);
+	}
+	if(!hasVariableHeight){
+		doh.assertEqual('mblListItemLabel', childNodes[i].className, "id=" + id);
+		doh.assertEqual('DIV', childNodes[i].tagName, "id=" + id);
+	}else{
+		doh.assertEqual('mblListItemLabel', childNodes[i+1].className, "id=" + id);
+		doh.assertEqual('DIV', childNodes[i+1].tagName, "id=" + id);
+	}
+
+	try{
+		doh.assertEqual(text, dojo.trim(childNodes[i].innerHTML.replace(/\r\n|\n|\t/g,"")), "id=" + id);
+	} catch (e) {
+		if(dojo.isFF ==3.6){
+			doh.assertEqual(text, dojo.trim(childNodes[i].childNodes[0].innerHTML.replace(/\r\n|\n|\t/g,"")), "id=" + id);
+		}else{
+			throw e;
+		}
+	}
+
+}
+
+function verifyListItemPos(id, rTop, rRight, rBottom, rLeft, sTop, sLeft, isSprite) {
+	var demoWidget = dijit.byId(id);
+	var node;
+	if(isSprite){
+		node = demoWidget.domNode.childNodes[0].childNodes[0];
+	}else{
+		node = demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0];
+	}
+	verifyRect(node, rTop, rRight, rBottom, rLeft);
+
+	doh.assertEqual(sTop, node.style.top);
+	doh.assertEqual(sLeft, node.style.left);
+}
+
+function verifyRect(node, rTop, rRight, rBottom, rLeft) {
+	var rectArray = node.style.clip.split(/[, ]+/);
+	doh.assertEqual("rect("+rTop, rectArray[0]);
+	doh.assertEqual(rRight, rectArray[1]);
+	doh.assertEqual(rBottom, rectArray[2]);
+	doh.assertEqual(rLeft+")", rectArray[3]);
+}
+
+function verifyIconItem(id, text, display, regExp, isSprite){
+	var demoWidget = dijit.byId(id);
+	if(!dojo.isIE && !dojo.isFF) {
+		if(isSprite){
+			doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0].src.search(regExp) != -1, "search " + regExp.toString() + " id=" +id);
+		}else{
+			doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(regExp) != -1, "search " + regExp.toString() + " id=" +id);
+		}
+	}
+	doh.assertEqual(text, demoWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue, "id=" +id);
+	doh.assertEqual(display, demoWidget.paneWidget.domNode.style.display, "id=" +id);
+	doh.assertEqual('mblIconItemPaneHeading', demoWidget.paneWidget.domNode.childNodes[0].className, "id=" +id);
+	doh.assertEqual('mblDomButtonBlueMinus mblDomButton', demoWidget.paneWidget.domNode.childNodes[0].childNodes[0].childNodes[0].className, "id=" +id);
+	doh.assertEqual(text, demoWidget.paneWidget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue, "id=" +id);
+}
+
+function verifyTabBarButton(id, text, classNames, visibility1, visibility2, regExp1, regExp2, isSprite){
+	var demoWidget = dijit.byId(id);
+	for(var i = 0; i < classNames.length;i++){
+		doh.assertTrue(dojo.hasClass(demoWidget.domNode, classNames[i]), classNames[i] + " id=" +id + " className:"+demoWidget.domNode.className);
+	}
+	doh.assertEqual('mblTabBarButtonIconAreaRtl', demoWidget.domNode.childNodes[0].className, "id=" +id);
+	doh.assertEqual('mblTabBarButtonLabel', demoWidget.domNode.childNodes[1].className, "id=" +id);
+	if(demoWidget.iconNode1){
+		if(!dojo.isIE) {
+			if(isSprite){
+				doh.assertTrue(demoWidget.iconNode1.childNodes[0].src.search(regExp1) != -1, "search " + regExp1.toString() + " id=" +id);
+			}else{
+				doh.assertTrue(demoWidget.iconNode1.src.search(regExp1) != -1, "search " + regExp1.toString() + " id=" +id);
+			}
+		}
+
+	}else{
+		console.log("There is no iconNode1. id=" + id);
+	}
+	if(demoWidget.iconNode2){
+		if(!dojo.isIE){
+			if(isSprite){
+				doh.assertTrue(demoWidget.iconNode2.childNodes[0].src.search(regExp2) != -1, "search " + regExp2.toString() + " id=" +id);
+			}else{
+				doh.assertTrue(demoWidget.iconNode2.src.search(regExp2) != -1, "search " + regExp2.toString() + " id=" +id);
+			}
+		}
+		doh.assertEqual(visibility2, demoWidget.iconNode2.style.visibility, "id=" +id);
+	}else{
+		console.log("There is no iconNode2. id=" + id);
+	}
+	doh.assertEqual(text, dojo.trim(demoWidget.labelNode.innerHTML), "id=" +id);
+}
diff --git a/dojox/mobile/tests/doh/bidi/ToggleButtonTests_Rtl.html b/dojox/mobile/tests/doh/bidi/ToggleButtonTests_Rtl.html
new file mode 100644
index 0000000..3bcf1f1
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/ToggleButtonTests_Rtl.html
@@ -0,0 +1,92 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>ToggleButton Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+<script language="JavaScript" type="text/javascript">
+	var BUTTON_LABEL = "Button";
+	var BUTTON_HEIGHT = 27;
+	var BUTTON_HEIGHT_IE = 25;
+	var BUTTON_HEIGHT_IE10 = 52;
+
+	require([
+		"dojo/_base/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/ToggleButton",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(has, domConst, ready, registry, runner, ToggleButton){
+		function _createToggleButtonDeclaratively(buttonId) {
+			return registry.byId(buttonId);
+		}
+		function _createToggleButtonProgrammatically(placeHolderId){
+			var button = new ToggleButton({label:BUTTON_LABEL});
+			runner.assertNotEqual(null, button, placeHolderId);
+			domConst.place(button.domNode, placeHolderId, "replace");
+			button.startup();
+			return button;
+		}
+		function _createToggleButtonProgrammaticallyWithSourceNodeReference(buttonId){
+			return new ToggleButton({label:BUTTON_LABEL}, buttonId);
+		}
+		function _assertCorrectToggleButton(height, button){
+			runner.assertNotEqual(null, button);
+			runner.assertEqual(height, button.domNode.clientHeight, "height id=" + button.domNode.id);
+		}
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		}
+		ready(function(){
+			var buttonHeight = has("ie") >= 10 ? BUTTON_HEIGHT_IE10 : BUTTON_HEIGHT;
+			runner.register("dojox.mobile.test.doh.ToggleButtonTests", [
+				function testInView1(){
+					var button1 = _createToggleButtonDeclaratively("view1-button1");
+					var button2 = _createToggleButtonProgrammatically("view1-button2");
+					var button3 = _createToggleButtonProgrammaticallyWithSourceNodeReference("view1-button3");
+			
+					_assertCorrectToggleButton(buttonHeight, button1);
+					_assertCorrectToggleButton(buttonHeight, button2);
+					_assertCorrectToggleButton(buttonHeight, button3);
+				},
+				function testInView2(){
+					var button1 = _createToggleButtonDeclaratively("view2-button1");
+					var button2 = _createToggleButtonProgrammatically("view2-button2");
+					var button3 = _createToggleButtonProgrammaticallyWithSourceNodeReference("view2-button3");
+					
+					_showView2();
+					
+					_assertCorrectToggleButton(buttonHeight, button1);
+					_assertCorrectToggleButton(buttonHeight, button2);
+					_assertCorrectToggleButton(buttonHeight, button3);
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body dir="rtl">
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<button id="view1-button1" data-dojo-type="dojox.mobile.ToggleButton">Button</button>
+		<div id="view1-button2"></div>
+		<button id="view1-button3"></button>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<button id="view2-button1" data-dojo-type="dojox.mobile.ToggleButton">Button</button>
+		<div id="view2-button2" dir="ltr"></div>
+		<button id="view2-button3"></button>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/ToolBarButtonSetter_rtl.html b/dojox/mobile/tests/doh/bidi/ToolBarButtonSetter_rtl.html
new file mode 100644
index 0000000..a400c21
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/ToolBarButtonSetter_rtl.html
@@ -0,0 +1,171 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Heading</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js"
+		data-dojo-config="mblThemeFiles: ['base','TabBar','base_rtl','TabBar_rtl','dojox/mobile/themes/common/domButtons.css']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+	<script type="text/javascript">
+		var timeoutInterval = 300;
+		var WIDGET_CLASSNAME1 = "mblDomButtonWhitePlus";
+		var WIDGET_CLASSNAME2 = "mblToolBarButtonSelected";
+		var WIDGET_LABEL1 = "XXXX";
+		require([
+			"dojo/dom-class", // dojo.hasClass
+			"dojo/ready",
+			"dijit/registry",
+			"doh/runner",	//doh functions
+			"dojox/mobile/tests/doh/TestHelper",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TabBar"
+		], function(domClass, ready, registry, runner, TestHelper){
+			ready(function(){
+				runner.register("dojox.mobile.test.doh.ToolBarButton", [
+					{
+						name: "ToolBarButton setter 1",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							var demoWidget1 = registry.byId("btn1");
+							var demoWidget2 = registry.byId("btn2");
+							var demoWidget3 = registry.byId("btn3");
+							demoWidget1.set("icon", WIDGET_CLASSNAME1);
+							demoWidget2.set("icon", WIDGET_CLASSNAME1);
+							demoWidget3.set("icon", WIDGET_CLASSNAME1);
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget1 = registry.byId("btn1");
+								var demoWidget2 = registry.byId("btn2");
+								var demoWidget3 = registry.byId("btn3");
+								runner.assertTrue(domClass.contains(demoWidget1.iconNode.childNodes[0], WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " value=" + demoWidget1.iconNode.childNodes[0].className);
+								runner.assertTrue(domClass.contains(demoWidget2.iconNode.childNodes[0], WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " value=" + demoWidget2.iconNode.childNodes[0].className);
+								runner.assertTrue(domClass.contains(demoWidget3.iconNode.childNodes[0], WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " value=" + demoWidget3.iconNode.childNodes[0].className);
+
+								demoWidget1.set("icon", "../../images/tab-icon-33w.png");
+								demoWidget2.set("icon", "../../images/tab-icon-33w.png");
+								demoWidget3.set("icon", "../../images/tab-icon-33w.png");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "ToolBarButton setter 2",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget1 = registry.byId("btn1");
+								var demoWidget2 = registry.byId("btn2");
+								var demoWidget3 = registry.byId("btn3");
+								TestHelper.verifyImageSrc(demoWidget1.iconNode.childNodes[0], /tab-icon-33w.png/i);
+								TestHelper.verifyImageSrc(demoWidget2.iconNode.childNodes[0], /tab-icon-33w.png/i);
+								TestHelper.verifyImageSrc(demoWidget3.iconNode.childNodes[0], /tab-icon-33w.png/i);
+
+								demoWidget1.set("iconPos", "29,116,29,29");
+								demoWidget1.set("icon", "../../images/tab-icons.png");
+								demoWidget2.set("iconPos", "29,116,29,29");
+								demoWidget2.set("icon", "../../images/tab-icons.png");
+								demoWidget3.set("iconPos", "29,116,29,29");
+								demoWidget3.set("icon", "../../images/tab-icons.png");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "ToolBarButton setter 3",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget1 = registry.byId("btn1");
+								var demoWidget2 = registry.byId("btn2");
+								var demoWidget3 = registry.byId("btn3");
+								TestHelper.verifyImageSrc(demoWidget1.iconNode.childNodes[0], /tab-icons.png/i);
+								TestHelper.verifyImageSrc(demoWidget2.iconNode.childNodes[0], /tab-icons.png/i);
+								TestHelper.verifyImageSrc(demoWidget3.iconNode.childNodes[0], /tab-icons.png/i);
+								demoWidget1.set("selected", true);
+								demoWidget2.set("selected", true);
+								demoWidget3.set("selected", true);
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "ToolBarButton setter 4",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget1 = registry.byId("btn1");
+								var demoWidget2 = registry.byId("btn2");
+								var demoWidget3 = registry.byId("btn3");
+								runner.assertTrue(domClass.contains(demoWidget1.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget1.iconNode.childNodes[0].className);
+								runner.assertTrue(domClass.contains(demoWidget2.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget2.iconNode.childNodes[0].className);
+								runner.assertTrue(domClass.contains(demoWidget3.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget3.iconNode.childNodes[0].className);
+								runner.assertTrue(demoWidget1.get("selected"), 'return value of get("selected") should be true');
+								runner.assertTrue(demoWidget2.get("selected"), 'return value of get("selected") should be true');
+								runner.assertTrue(demoWidget3.get("selected"), 'return value of get("selected") should be true');
+								demoWidget1.set("selected", false);
+								demoWidget2.set("selected", false);
+								demoWidget3.set("selected", false);
+								demoWidget1.set("label", WIDGET_LABEL1);
+								demoWidget2.set("label", WIDGET_LABEL1);
+								demoWidget3.set("label", WIDGET_LABEL1);
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "ToolBarButton setter 5",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget1 = registry.byId("btn1");
+								var demoWidget2 = registry.byId("btn2");
+								var demoWidget3 = registry.byId("btn3");
+								runner.assertFalse(domClass.contains(demoWidget1.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget1.iconNode.childNodes[0].className);
+								runner.assertFalse(domClass.contains(demoWidget2.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget2.iconNode.childNodes[0].className);
+								runner.assertFalse(domClass.contains(demoWidget3.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget3.iconNode.childNodes[0].className);
+								runner.assertFalse(demoWidget1.get("selected"), 'return value of get("selected") should be false');
+								runner.assertFalse(demoWidget2.get("selected"), 'return value of get("selected") should be false');
+								runner.assertFalse(demoWidget3.get("selected"), 'return value of get("selected") should be false');
+								runner.assertEqual(WIDGET_LABEL1, demoWidget1.labelNode.innerHTML);
+								runner.assertEqual(WIDGET_LABEL1, demoWidget2.labelNode.innerHTML);
+								runner.assertEqual(WIDGET_LABEL1, demoWidget3.labelNode.innerHTML);
+								runner.assertEqual(WIDGET_LABEL1, demoWidget1.get("label"), 'return value of get("label") should be ' + WIDGET_LABEL1);
+								runner.assertEqual(WIDGET_LABEL1, demoWidget2.get("label"), 'return value of get("label") should be ' + WIDGET_LABEL1);
+								runner.assertEqual(WIDGET_LABEL1, demoWidget3.get("label"), 'return value of get("label") should be ' + WIDGET_LABEL1);
+							}), timeoutInterval);
+							return d;
+						}
+					}
+				]);
+				runner.run();
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;" dir="rtl">
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Arrow"'>
+		<button id="btn1" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='light:false'>MMMM</button>
+	</div>
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Arrow"'>
+		<button id="btn2" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='light:false, arrow:"left"'>MMMM</button>
+	</div>
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Arrow"'>
+		<button id="btn3" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='light:false, arrow:"right"'>MMMM</button>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/ToolBarButton_Rtl.js b/dojox/mobile/tests/doh/bidi/ToolBarButton_Rtl.js
new file mode 100644
index 0000000..a1883b5
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/ToolBarButton_Rtl.js
@@ -0,0 +1,117 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.ToolBarButton", [
+		function test_Heading_Verification(){
+			var demoWidget = dijit.byId("btn1");
+
+			doh.assertEqual('Edit', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_0");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhitePlus mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+			
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_1");
+			doh.assertEqual('Edit', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_2");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhitePlus mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_3");
+			doh.assertEqual('Speaker', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_4");
+			doh.assertEqual('Done', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_5");
+			doh.assertEqual('Update All', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_6");
+			doh.assertEqual('mblToolBarButton mblToolBarButtonRtl mblToolBarButtonHasRightArrow', demoWidget.domNode.className, "id= "+ demoWidget.domNode.id);
+			doh.assertEqual('Bookmarks', demoWidget.labelNode.innerHTML);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_7");
+			doh.assertEqual('Done', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_8");
+			doh.assertEqual('Done', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_9");
+			doh.assertEqual('New Folder', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_10");
+			doh.assertEqual('New', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_11");
+			doh.assertEqual('Toggle', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_12");
+			if(!dojo.isIE){
+				doh.assertTrue(demoWidget.iconNode.src.search(/a-icon-12.png/) != -1, "a-icon-12.png", "id= "+ demoWidget.domNode.id);
+			}
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_13");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblSpriteIcon', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+			verifyRect(demoWidget.iconNode.childNodes[0], "29px", "29px", "58px", "0px");
+			doh.assertEqual('-29px', demoWidget.iconNode.childNodes[0].style.top, "id= "+ demoWidget.domNode.id);
+			doh.assertEqual('0px', demoWidget.iconNode.childNodes[0].style.left, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_14");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhitePlus mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_15");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhiteSearch mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_16");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhitePlus mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_17");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblImageIcon', demoWidget.iconNode.className, "id= "+ demoWidget.domNode.id);
+			if(!dojo.isIE){
+				doh.assertTrue(demoWidget.iconNode.src.search(/tab-icon-15h.png/) != -1, "tab-icon-15h.png");
+			}
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_18");
+			doh.assertEqual('mblToolBarButton mblToolBarButtonRtl mblToolBarButtonHasRightArrow', demoWidget.domNode.className, "id= "+ demoWidget.domNode.id);
+			doh.assertEqual('Top', demoWidget.labelNode.innerHTML);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_19");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhiteSearch mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_20");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhiteUpArrow mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_21");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhiteDownArrow mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+		},
+		function test_Heading_Set(){
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_4");
+			demoWidget.set({label:"New Value"})
+			doh.assertEqual('New Value', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+			
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_2");
+			demoWidget.set({icon:"mblDomButtonBlueCirclePlus"})
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonBlueCirclePlus mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+		}
+	]);
+	doh.run();
+});
+
diff --git a/dojox/mobile/tests/doh/bidi/ToolBarButton_rtl.html b/dojox/mobile/tests/doh/bidi/ToolBarButton_rtl.html
new file mode 100644
index 0000000..5f48c72
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/ToolBarButton_rtl.html
@@ -0,0 +1,91 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>ToolBarButton</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/base_rtl.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/TabBar.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/TabBar_rtl.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, has:{'dojo-bidi': true}"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser"); // Use the lightweight parser.
+			//dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.TabBar");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+			dojo.require("doh.runner");
+		</script>
+		<script type="text/javascript" src="TestUtil_Rtl.js"></script>
+		<script type="text/javascript" src="ToolBarButton_Rtl.js"></script>
+	</head>
+	<body dir="rtl">
+		<h1 dojoType="dojox.mobile.Heading" label="World Clock">
+			<div id="btn1" dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px">Edit</div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;" onclick="console.log('+ was clicked')"></div>
+
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading">
+			<div dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px">Edit</div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;"></div>
+			Alarm Clock
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading" label="Voice Memos">
+			<div dojoType="dojox.mobile.ToolBarButton" label="Speaker"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="float:right;"></div>
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading" label="Updates">
+			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="float:right;"></div>
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading" label="News" back="Bookmarks" moveTo="bookmarks">
+			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="float:right;"></div>
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading">
+			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" label="New Folder" style="float:right;"></div>
+		</h1><br>
+
+
+		<div dojoType="dojox.mobile.Heading">
+			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">New</div>
+			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">Toggle</div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="../../images/a-icon-12.png" moveTo="view3"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="../../images/tab-icons.png" iconPos="29,0,29,29" moveTo="view3"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" moveTo="view3" style="float:right;"></div>
+		</div><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading">
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading" align="center">
+		  <table cellpadding="0" cellspacing="0" style="width:100%;"><tr>
+			<td><div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus"></div></td>
+			<td align="right"><div dojoType="dojox.mobile.ToolBarButton" icon="../../images/tab-icon-15h.png" style="float:right;"></div></td>
+		  </tr></table>
+		</h1><br>
+
+		<h1 dojoType="dojox.mobile.Heading" back="Top" label="Inbox(32)">
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteUpArrow" style="float:right;"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteDownArrow" style="float:right;"></div>
+		</h1><br>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/bidi/module.js b/dojox/mobile/tests/doh/bidi/module.js
new file mode 100644
index 0000000..2b9bc5b
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/module.js
@@ -0,0 +1,55 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+	
+	// Edge To Edge List
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./EdgeToEdgeCategory_Rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./EdgeToEdgeDataList_Rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./EdgeToEdgeStoreList_Rtl.html"),999999);
+	// List Item
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./ListItem_Rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./ListItem2_Rtl.html"),999999);
+	// RoundRect List
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./RoundRectDataList_Rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./RoundRectList_Rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./RoundRectStoreList_Rtl.html"),999999);
+	// ComboBox
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./ComboBoxTests_Rtl.html"),999999);
+	// Toggle Button
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./ToggleButtonTests_Rtl.html"),999999);
+	// Switch
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./SwitchTests_Rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./Switch_Rtl.html"),999999); 
+	// Heading
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./Heading_Rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./Heading2_Rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./HeadingTests_Rtl.html"),999999);
+	// Fixed Splitter
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./FixedSplitterTests1_Rtl.html"),999999);
+		doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./FixedSplitterTests2_Rtl.html"),999999);
+		doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./FixedSplitterTests3_Rtl.html"),999999);
+	}
+	// TabBar
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./TabBarTests_Rtl.html"),999999);
+	}
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./TabBar_Rtl.html"),999999);
+	// ToolbarButton
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./ToolBarButton_rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./ToolBarButtonSetter_rtl.html"),999999);
+	// Spin wheel
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./SpinWheel_Programmatic_Rtl.html"),999999);
+	// Icon Menu
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./IconMenuTests_Rtl.html"),999999);
+	// Icon Container
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./IconContainer_Rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./IconContainer2_Rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./IconContainer3_Rtl.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./IconContainerTests_Rtl.html"),999999);
+	
+	// Swap View
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.Bidi", require.toUrl("./SwapViewTests1_Rtl.html"),999999);
+	}
+
+});
+
diff --git a/dojox/mobile/tests/doh/bidi/runTests.html b/dojox/mobile/tests/doh/bidi/runTests.html
new file mode 100644
index 0000000..36538c3
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.bidi.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/bidi/settings.json b/dojox/mobile/tests/doh/bidi/settings.json
new file mode 100644
index 0000000..5be971a
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/settings.json
@@ -0,0 +1,14 @@
+{
+  "items" : [
+    { "label" : "Wi-Fi",                        "icon" : "../../images/i-icon-1.png",   "moveTo": "wifi"                              },
+    { "label" : "Brightness & Wallpaper",       "icon" : "../../images/i-icon-2.png",   "moveTo": "bright"                            },
+    { "label" : "Picture Frame",                "icon" : "../../images/i-icon-3.png",   "moveTo": "picture"                           },
+    { "label" : "General",                      "icon" : "../../images/i-icon-4.png",   "moveTo": "general",  "selected": "true"      },
+    { "label" : "Mail, Contacts, Calendars",    "icon" : "../../images/i-icon-5.png",   "moveTo": "wifi"                              },
+    { "label" : "Safari",                       "icon" : "../../images/i-icon-6.png",   "moveTo": "bright"                            },
+    { "label" : "iPod",                         "icon" : "../../images/i-icon-7.png",   "moveTo": "picture"                           },
+    { "label" : "Video",                        "icon" : "../../images/i-icon-8.png",   "moveTo": "general"                           },
+    { "label" : "Photos",                       "icon" : "../../images/i-icon-9.png",   "moveTo": "wifi"                              },
+    { "label" : "Store",                        "icon" : "../../images/i-icon-10.png",  "moveTo": "bright"                            }
+  ]
+}
diff --git a/dojox/mobile/tests/doh/bidi/settings2.json b/dojox/mobile/tests/doh/bidi/settings2.json
new file mode 100644
index 0000000..71b3484
--- /dev/null
+++ b/dojox/mobile/tests/doh/bidi/settings2.json
@@ -0,0 +1,12 @@
+[
+    { "label" : "Wi-Fi",                        "icon" : "../../images/i-icon-1.png",   "moveTo": "wifi"                              },
+    { "label" : "Brightness & Wallpaper",       "icon" : "../../images/i-icon-2.png",   "moveTo": "bright"                            },
+    { "label" : "Picture Frame",                "icon" : "../../images/i-icon-3.png",   "moveTo": "picture"                           },
+    { "label" : "General",                      "icon" : "../../images/i-icon-4.png",   "moveTo": "general",  "selected": "true"      },
+    { "label" : "Mail, Contacts, Calendars",    "icon" : "../../images/i-icon-5.png",   "moveTo": "wifi"                              },
+    { "label" : "Safari",                       "icon" : "../../images/i-icon-6.png",   "moveTo": "bright"                            },
+    { "label" : "iPod",                         "icon" : "../../images/i-icon-7.png",   "moveTo": "picture"                           },
+    { "label" : "Video",                        "icon" : "../../images/i-icon-8.png",   "moveTo": "general"                           },
+    { "label" : "Photos",                       "icon" : "../../images/i-icon-9.png",   "moveTo": "wifi"                              },
+    { "label" : "Store",                        "icon" : "../../images/i-icon-10.png",  "moveTo": "bright"                            }
+ ]
diff --git a/dojox/mobile/tests/doh/button/Button.html b/dojox/mobile/tests/doh/button/Button.html
new file mode 100644
index 0000000..10f6250
--- /dev/null
+++ b/dojox/mobile/tests/doh/button/Button.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Button</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<style>
+		.redButton {
+			border-color: #cc3333;
+			background-image: url(../../images/red-button-bg.png);
+			background: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		}
+		.redButtonSelected {
+			background-image: url(../../images/red-button-sel-bg.png);
+			background: -webkit-gradient(linear, left top, left bottom, from(#AF333C), to(#880E17), color-stop(0.5, #952B33), color-stop(0.5, #870F18));
+		}
+		</style>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.Button");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+
+			dojo.addOnLoad(function(){
+				doh.register("dojox.mobile.test.doh.Button", [
+					function test_Button_Verification(){
+						var demoWidget = dijit.byId("btn1");
+						doh.assertEqual('mblButton mblBlueButton', demoWidget.domNode.className);
+						doh.assertEqual('Default Button', demoWidget.domNode.childNodes[0].nodeValue);
+						demoWidget = dijit.byId("btn2");
+						doh.assertEqual('mblButton redButton', demoWidget.domNode.className);
+						doh.assertEqual('Custom Button', demoWidget.domNode.childNodes[0].nodeValue);
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body style="padding: 20px;visibility:visible">
+		<button id="btn1" dojoType="dojox.mobile.Button" class="mblBlueButton" style="width:120px">Default Button</button>
+		<p></p>
+		<button id="btn2" dojoType="dojox.mobile.Button" class="redButton" style="width:120px">Custom Button</button>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/button/ButtonTests.html b/dojox/mobile/tests/doh/button/ButtonTests.html
new file mode 100644
index 0000000..ed2d481
--- /dev/null
+++ b/dojox/mobile/tests/doh/button/ButtonTests.html
@@ -0,0 +1,103 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Button Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	var BUTTON_LABEL = "Button";
+	var BUTTON_WIDTH = 58;
+	var BUTTON_WIDTH_FF = 64;
+	var BUTTON_WIDTH_IE = 64; // IE10
+	var BUTTON_HEIGHT = 27;
+	var BUTTON_HEIGHT_IE = 28; // IE10
+
+	require([
+		"dojo/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/Button",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(has, domConst, ready, registry, runner, Button){
+		function _createButtonDeclaratively(buttonId) {
+			return registry.byId(buttonId);
+		}
+		function _createButtonProgrammatically(placeHolderId){
+			var button = new Button({label:BUTTON_LABEL});
+			runner.assertNotEqual(null, button, placeHolderId);
+			domConst.place(button.domNode, placeHolderId, "replace");
+			button.startup();
+			return button;
+		}
+		function _createButtonProgrammaticallyWithSourceNodeReference(buttonId){
+			return new Button({label:BUTTON_LABEL}, buttonId);
+		}
+		function _assertCorrectButton(width, height, button){
+			if(width < 0){
+				return; // Skip for IE<9 (a negative width is the convention we use for skipping) 
+			}
+			runner.assertNotEqual(null, button);
+			runner.assertEqual(width, button.domNode.clientWidth, "width id=" + button.domNode.id);
+			runner.assertEqual(height, button.domNode.clientHeight, "height id=" + button.domNode.id);
+		}
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		}
+		ready(function(){
+			var buttonWidth = has("ie") >= 10 ? BUTTON_WIDTH_IE : has("ff") ? BUTTON_WIDTH_FF : BUTTON_WIDTH;
+			var buttonHeight = has("ie") >= 10 ? BUTTON_HEIGHT_IE : BUTTON_HEIGHT;
+			// Skip the checks for IE<9
+			if(has("ie") < 9){
+				buttonWidth = -1; // negative value as convention for skipping tests
+			} 
+			runner.register("dojox.mobile.test.doh.ButtonTests", [
+				function testInView1(){
+					var button1 = _createButtonDeclaratively("view1-button1");
+					var button2 = _createButtonProgrammatically("view1-button2");
+					var button3 = _createButtonProgrammaticallyWithSourceNodeReference("view1-button3");
+			
+					_assertCorrectButton(buttonWidth, buttonHeight, button1);
+					_assertCorrectButton(buttonWidth, buttonHeight, button2);
+					_assertCorrectButton(buttonWidth, buttonHeight, button3);
+				},
+				function testInView2(){
+					var button1 = _createButtonDeclaratively("view2-button1");
+					var button2 = _createButtonProgrammatically("view2-button2");
+					var button3 = _createButtonProgrammaticallyWithSourceNodeReference("view2-button3");
+					
+					_showView2();
+					
+					_assertCorrectButton(buttonWidth, buttonHeight, button1);
+					_assertCorrectButton(buttonWidth, buttonHeight, button2);
+					_assertCorrectButton(buttonWidth, buttonHeight, button3);
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<button id="view1-button1" data-dojo-type="dojox.mobile.Button">Button</button>
+		<div id="view1-button2"></div>
+		<button id="view1-button3"></button>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<button id="view2-button1" data-dojo-type="dojox.mobile.Button">Button</button>
+		<div id="view2-button2"></div>
+		<button id="view2-button3"></button>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/button/Button_Programmatic.html b/dojox/mobile/tests/doh/button/Button_Programmatic.html
new file mode 100644
index 0000000..6c3e8f8
--- /dev/null
+++ b/dojox/mobile/tests/doh/button/Button_Programmatic.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Button</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<style>
+		.redButton {
+			border-color: #cc3333;
+			background-image: url(../../images/red-button-bg.png);
+			background: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		}
+		.redButtonSelected {
+			background-image: url(../../images/red-button-sel-bg.png);
+			background: -webkit-gradient(linear, left top, left bottom, from(#AF333C), to(#880E17), color-stop(0.5, #952B33), color-stop(0.5, #870F18));
+		}
+		</style>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.Button");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+
+			dojo.addOnLoad(function(){
+				var demoWidget = new dojox.mobile.Button({"class":"mblBlueButton", style:"width:120px", label:"Default Button"});
+				dojo.doc.body.appendChild(demoWidget.domNode);
+
+				var child = dojo.create("P", null, dojo.doc.body);
+
+				demoWidget = new dojox.mobile.Button({"class":"redButton", style:"width:120px", label:"Custom Button"});
+				dojo.doc.body.appendChild(demoWidget.domNode);
+
+				doh.register("dojox.mobile.test.doh.Button", [
+					function test_Button_Verification(){
+						var demoWidget = dijit.byId("dojox_mobile_Button_0");
+						doh.assertEqual('mblButton mblBlueButton', demoWidget.domNode.className);
+						doh.assertEqual('Default Button', demoWidget.domNode.childNodes[0].nodeValue);
+						demoWidget = dijit.byId("dojox_mobile_Button_1");
+						doh.assertEqual('mblButton redButton', demoWidget.domNode.className);
+						doh.assertEqual('Custom Button', demoWidget.domNode.childNodes[0].nodeValue);
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body style="padding: 20px;visibility:visible">
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/button/module.js b/dojox/mobile/tests/doh/button/module.js
new file mode 100644
index 0000000..404efaf
--- /dev/null
+++ b/dojox/mobile/tests/doh/button/module.js
@@ -0,0 +1,9 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.Button", require.toUrl("./Button.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Button", require.toUrl("./Button_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Button", require.toUrl("./ButtonTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/button/runTests.html b/dojox/mobile/tests/doh/button/runTests.html
new file mode 100644
index 0000000..6945ca4
--- /dev/null
+++ b/dojox/mobile/tests/doh/button/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.button.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/checkbox/CheckBoxTests.html b/dojox/mobile/tests/doh/checkbox/CheckBoxTests.html
new file mode 100644
index 0000000..9fddbf1
--- /dev/null
+++ b/dojox/mobile/tests/doh/checkbox/CheckBoxTests.html
@@ -0,0 +1,87 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Check Box Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	require([
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/CheckBox",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(domConst, ready, registry, runner, CheckBox){
+		function _createCheckBoxDeclaratively(checkBoxId) {
+			return registry.byId(checkBoxId);
+		}
+		function _createCheckBoxProgrammatically(placeHolderId){
+			var checkBox = new CheckBox();
+			runner.assertNotEqual(null, checkBox);
+			domConst.place(checkBox.domNode, placeHolderId, "replace");
+			checkBox.startup();
+			return checkBox;
+		}
+		function _createCheckBoxProgrammaticallyWithSourceNodeReference(checkBoxId){
+			return new CheckBox({}, checkBoxId);
+		}
+		function _assertCorrectCheckBox(checkBox){
+			runner.assertNotEqual(null, checkBox);
+			runner.assertFalse(checkBox.checked, "unchecked id=" + checkBox.domNode.id);
+			checkBox.set("checked", true);
+			runner.assertTrue(checkBox.checked, "checked id=" + checkBox.domNode.id);
+		}
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		}
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.CheckBoxTests", [
+				function testInView1(){
+					var checkBox1 = _createCheckBoxDeclaratively("view1-checkBox1");
+					var checkBox2 = _createCheckBoxProgrammatically("view1-checkBox2");
+					var checkBox3 = _createCheckBoxProgrammaticallyWithSourceNodeReference("view1-checkBox3");
+			
+					_assertCorrectCheckBox(checkBox1);
+					_assertCorrectCheckBox(checkBox2);
+					_assertCorrectCheckBox(checkBox3);
+				},
+				function testInView2(){
+					var checkBox1 = _createCheckBoxDeclaratively("view2-checkBox1");
+					var checkBox2 = _createCheckBoxProgrammatically("view2-checkBox2");
+					var checkBox3 = _createCheckBoxProgrammaticallyWithSourceNodeReference("view2-checkBox3");
+					
+					_showView2();
+					
+					_assertCorrectCheckBox(checkBox1);
+					_assertCorrectCheckBox(checkBox2);
+					_assertCorrectCheckBox(checkBox3);
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<input id="view1-checkBox1" type="checkbox" data-dojo-type="dojox.mobile.CheckBox"></input>
+		<div id="view1-checkBox2"></div>
+		<input id="view1-checkBox3" type="checkbox"></input>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<input id="view2-checkBox1" type="checkbox" data-dojo-type="dojox.mobile.CheckBox"></input>
+		<div id="view2-checkBox2"></div>
+		<input id="view2-checkBox3" type="checkbox"></input>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/checkbox/module.js b/dojox/mobile/tests/doh/checkbox/module.js
new file mode 100644
index 0000000..efa891e
--- /dev/null
+++ b/dojox/mobile/tests/doh/checkbox/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.CheckBox", require.toUrl("./CheckBoxTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/checkbox/runTests.html b/dojox/mobile/tests/doh/checkbox/runTests.html
new file mode 100644
index 0000000..2f2f703
--- /dev/null
+++ b/dojox/mobile/tests/doh/checkbox/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.checkbox.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/combobox/ComboBoxTests.html b/dojox/mobile/tests/doh/combobox/ComboBoxTests.html
new file mode 100644
index 0000000..8dfdca2
--- /dev/null
+++ b/dojox/mobile/tests/doh/combobox/ComboBoxTests.html
@@ -0,0 +1,230 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Combo Box Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../TestUtil.js"></script>
+<script language="JavaScript" type="text/javascript">
+	var timeoutInterval = 1000;
+	require([
+		"dojo/_base/connect",
+		"dojo/sniff",
+		"dojo/Deferred",
+		"dojo/dom",
+		"dojo/dom-construct", // dojo.place
+		"dojo/dom-class", // dojo.hasClass
+		"dojo/dom-style",
+		"dojo/store/Memory", // dojo.store.Memory
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/ComboBox",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(connect, has, Deferred, dom, domConst, domClass, domStyle, Memory, ready, registry, runner, ComboBox){
+
+		var FRUITS = new Memory({
+				idProperty:"name",
+				data:[
+					{name:"Apple"},
+					{name:"Banana"},
+					{name:"Cherry"}
+			]});
+
+		function _createComboBoxDeclaratively(id) {
+			return registry.byId(id);
+		};
+		
+		function _createComboBoxProgrammatically(placeHolderId){
+			var widget = new ComboBox({store:FRUITS, id:placeHolderId, value:'Apple'});
+			runner.assertNotEqual(null, widget);
+			domConst.place(widget.domNode, placeHolderId, "replace");
+			widget.startup();
+			return widget;
+		};
+		
+		function _createComboBoxProgrammaticallyWithSourceNodeReference(id){
+			var widget = new ComboBox({store:FRUITS, value:'Apple'}, id);
+			widget.startup();
+			return widget;
+		};
+
+		function _assertCorrectComboBox(comboBox, def){
+ 			runner.assertNotEqual(null, comboBox, "combobox shouldn't be null");
+			runner.assertEqual(FRUITS.data[0].name, comboBox.domNode.value, comboBox.toString() + " value is not the expected one at init");
+			// Display the dropdown
+			fireOnClick(comboBox.domNode);
+			setTimeout(def.getTestErrback(function(){
+				var dropDownNode = dom.byId(comboBox.id + "_dropdown");
+				runner.assertNotEqual(null, dropDownNode, "can't find dropdown node for " + comboBox.toString());
+				runner.assertEqual("block", domStyle.get(dropDownNode, "display"), " dropdown node for " + comboBox.toString() + " should be visible after click");
+				// Verify available options
+				_checkComboBoxOptions(comboBox, [{containsClass: "mblComboBoxMenuPreviousButton", displayed: false},
+		                                          {label: "Apple", displayed: true},
+		                                          {label: "Banana", displayed: true},
+		                                          {label: "Cherry", displayed: true},
+		                                          {containsClass: "mblComboBoxMenuNextButton", displayed: false}]);
+				// Type letter c in the input field
+ 				comboBox.domNode.value = "c";
+				fireOnInput(comboBox.domNode);
+				setTimeout(def.getTestErrback(function(){
+					// Verify available options
+					_checkComboBoxOptions(comboBox, [{containsClass: "mblComboBoxMenuPreviousButton", displayed: false},
+													{label: "Cherry", displayed: true},
+													{containsClass: "mblComboBoxMenuNextButton", displayed: false}]);
+					// click in the dropdown to select an option
+					fireOnClick(dom.byId(comboBox.id + "_popup0"));
+					setTimeout(def.getTestCallback(function(){
+						// check that the dropdown is not visible anymore
+						runner.assertEqual("none", domStyle.get(dropDownNode, "display"), " dropdown node for " + comboBox.toString() + " should be invisible after click");
+						// check the clicked option value is now the input field value
+						runner.assertEqual("Cherry", comboBox.domNode.value, comboBox.toString()  + " value is not the expected one after clicking the option");						
+						// programmatically set value
+		  				comboBox.set("value", FRUITS.data[1].name);
+						runner.assertEqual(FRUITS.data[1].name, comboBox.domNode.value, comboBox.toString()  + " value is not the expected one after programmatic set");
+					}), 500);
+				}), 500);
+			}), 500);
+ 		};
+
+		function _checkComboBoxOptions(comboBox, expected){
+			var options = dom.byId(comboBox.id + "_dropdown").firstChild.firstChild.children;
+			var i = 0;
+			runner.assertEqual(expected.length, options.length, "The number of options is not the expected one for " + comboBox.id);
+			for(i = 0; i < options.length; i++){
+				if(expected[i].label){
+					runner.assertEqual(expected[i].label, options[i].innerText || options[i].textContent, "label for option " + i + " of " + comboBox.id + " is not the expected one");
+				}
+				if(expected[i].containsClass){
+					runner.assertTrue(domClass.contains(options[i], expected[i].containsClass), "class for option " + i + " of " + comboBox.id + " is not the expected one");
+				}
+			}
+		};
+
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		};
+
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.ComboBoxTests", [
+				{
+					name: "test view1-comboBox1",
+					timeout: 4000,
+					runTest: function(){
+
+						var d = new runner.Deferred();
+						var comboBox1 = _createComboBoxDeclaratively("view1-comboBox1");
+						setTimeout(d.getTestErrback(function(){
+							_assertCorrectComboBox(comboBox1, d);
+						}), timeoutInterval);
+						return d;
+					}
+				},
+				{
+					name: "test view1-comboBox2",
+					timeout: 4000,
+					runTest: function(){
+
+						var d = new runner.Deferred();
+						var comboBox2 = _createComboBoxProgrammatically("view1-comboBox2");
+						setTimeout(d.getTestErrback(function(){
+ 							_assertCorrectComboBox(comboBox2, d);
+						}), timeoutInterval);
+						return d;
+					}
+				},
+				{
+					name: "test view1-comboBox3",
+					timeout: 4000,
+					runTest: function(){
+
+						var d = new runner.Deferred();
+						var comboBox3 = _createComboBoxProgrammaticallyWithSourceNodeReference("view1-comboBox3");
+						setTimeout(d.getTestErrback(function(){
+							_assertCorrectComboBox(comboBox3, d);
+						}), timeoutInterval);
+						return d;
+					}
+				},
+				{
+					name: "test view2-comboBox1",
+					timeout: 4000,
+					runTest: function(){
+
+						var d = new runner.Deferred();
+						var comboBox1 = _createComboBoxDeclaratively("view2-comboBox1");
+						_createComboBoxProgrammatically("view2-comboBox2");
+						_createComboBoxProgrammaticallyWithSourceNodeReference("view2-comboBox3");
+						_showView2();
+						setTimeout(d.getTestErrback(function(){
+							_assertCorrectComboBox(comboBox1, d);
+						}), timeoutInterval);
+						return d;
+					}
+				},
+				{
+					name: "test view2-comboBox2",
+					timeout: 4000,
+					runTest: function(){
+
+						var d = new runner.Deferred();
+						var comboBox2 = registry.byId("view2-comboBox2");
+						setTimeout(d.getTestErrback(function(){
+ 							_assertCorrectComboBox(comboBox2, d);
+						}), timeoutInterval);
+						return d;
+					}
+				},
+				{
+					name: "test view2-comboBox3",
+					timeout: 4000,
+					runTest: function(){
+
+						var d = new runner.Deferred();
+						var comboBox3 = registry.byId("view2-comboBox3");
+						setTimeout(d.getTestErrback(function(){
+							_assertCorrectComboBox(comboBox3, d);
+						}), timeoutInterval);
+						return d;
+					}
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<datalist id="fruits">
+			<select data-dojo-type="dijit.form.DataList" data-dojo-props="id:'fruits'">
+				<option value="fruit1">Apple</option>
+				<option value="fruit2">Banana</option>
+				<option value="fruit3">Cherry</option>
+			</select>
+		</datalist>
+		<input id="view1-comboBox1" type="text" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props="value:'Apple', list:'fruits'"></input>
+		<div id="view1-comboBox2"></div>
+		<input id="view1-comboBox3" type="text"></input>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<select data-dojo-type="dijit.form.DataList" data-dojo-props="id:'fruits2'">
+			<option>Apple</option>
+			<option>Banana</option>
+			<option>Cherry</option>
+		</select>
+		<input id="view2-comboBox1" type="text" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props="value:'Apple', list:'fruits2'"></input>
+		<div id="view2-comboBox2"></div>
+		<input id="view2-comboBox3" type="text"></input>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/combobox/module.js b/dojox/mobile/tests/doh/combobox/module.js
new file mode 100644
index 0000000..b69143d
--- /dev/null
+++ b/dojox/mobile/tests/doh/combobox/module.js
@@ -0,0 +1,9 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+	if(has("ie") >= 10){
+		// ComboBox is broken on IE10 with the native WindowsPhone theme
+		doh.registerUrl("dojox.mobile.tests.doh.ComboBoxTests", require.toUrl("./ComboBoxTests.html?theme=iPhone"),999999);
+	}else{
+		doh.registerUrl("dojox.mobile.tests.doh.ComboBoxTests", require.toUrl("./ComboBoxTests.html"),999999);
+	}
+});
+
diff --git a/dojox/mobile/tests/doh/combobox/runTests.html b/dojox/mobile/tests/doh/combobox/runTests.html
new file mode 100644
index 0000000..5705810
--- /dev/null
+++ b/dojox/mobile/tests/doh/combobox/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.combobox.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/contentpane/ContentPaneTests.html b/dojox/mobile/tests/doh/contentpane/ContentPaneTests.html
new file mode 100644
index 0000000..3c484d4
--- /dev/null
+++ b/dojox/mobile/tests/doh/contentpane/ContentPaneTests.html
@@ -0,0 +1,235 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>ContentPane Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, async: true"></script>
+<script language="JavaScript" type="text/javascript">
+	var WIDGET_CLASSNAME1 = "mblContentPane";
+	var WIDGET2_CLASSNAME1 = "mblRoundRect";
+	var WIDGET2_CLASSNAME2 = "mblShadow";
+	var WIDGET_INNERHTML1 = "Pane 1 : Thank you!";
+	var WIDGET_INNERHTML2 = "Pane 2 : HTML fragment example";
+	var WIDGET_INNERHTML3 = "Pane 3 : Thank you!";
+	var WIDGET_INNERHTML4 = "Pane 4 : HTML fragment example";
+	var WIDGET_INNERHTML5 = "Pane 5 : DOM Tree";
+
+	require([
+		"dojo/_base/connect",
+		"dojo/dom-construct", // dojo.place, dojo.create
+		"dojo/dom-class",
+		"dojo/ready", // dojo.ready
+		"dojo/string", // dojo.trim
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/ContentPane",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
+		"dojox/mobile/RoundRect"
+	], function(connect, domConst, domClass, ready, string, registry, runner, ContentPane){
+		function _initContentPane(widgetIds){
+			registry.byId(widgetIds[0]).set("content", "<div data-dojo-type='dojox.mobile.RoundRect' shadow='true'>Pane 3 : Thank you!</div>");
+			registry.byId(widgetIds[1]).set("href", "fragment2.html");
+
+			var dom = domConst.create("DIV", {
+				dojoType: "dojox.mobile.RoundRect",
+				shadow: "true"
+			});
+			dom.innerHTML = "Pane 5 : DOM Tree";
+			registry.byId(widgetIds[2]).set("content", dom);
+			
+		}
+		function _createContentPaneProgrammatically(widgetIds, placeHolderId){
+			var r = new ContentPane({id:widgetIds[0], content:"<div data-dojo-type='dojox.mobile.RoundRect' shadow='true'>Pane 1 : Thank you!</div>"});
+			domConst.place(r.domNode, placeHolderId[0], "replace");
+			r.startup();
+			r = new ContentPane({id:widgetIds[1], href:"fragment1.html"});
+			domConst.place(r.domNode, placeHolderId[1], "replace");
+			r.startup();
+			r = new ContentPane({id:widgetIds[2]});
+			domConst.place(r.domNode, placeHolderId[2], "replace");
+			r.startup();
+			r = new ContentPane({id:widgetIds[3]});
+			domConst.place(r.domNode, placeHolderId[3], "replace");
+			r.startup();
+			r = new ContentPane({id:widgetIds[4]});
+			domConst.place(r.domNode, placeHolderId[4], "replace");
+			r.startup();
+		}
+		function _createContentPaneProgrammaticallyWithSourceNodeReference(widgetIds){
+			new ContentPane({content:"<div data-dojo-type='dojox.mobile.RoundRect' shadow='true'>Pane 1 : Thank you!</div>"}, widgetIds[0]);
+			new ContentPane({href:"fragment1.html"}, widgetIds[1]);
+			new ContentPane({}, widgetIds[2]);
+			new ContentPane({}, widgetIds[3]);
+			new ContentPane({}, widgetIds[4]);
+
+		}
+		function _assertCorrectContentPanes(widgetIds){
+			var widget = registry.byId(widgetIds[0]);
+			_assertCorrectContentPane(widget, WIDGET_INNERHTML1);
+			widget = registry.byId(widgetIds[1]);
+			_assertCorrectContentPane(widget, WIDGET_INNERHTML2);
+			widget = registry.byId(widgetIds[2]);
+			_assertCorrectContentPane(widget, WIDGET_INNERHTML3);
+			widget = registry.byId(widgetIds[3]);
+			_assertCorrectContentPane(widget, WIDGET_INNERHTML4);
+			widget = registry.byId(widgetIds[4]);
+			_assertCorrectContentPane(widget, WIDGET_INNERHTML5);
+		}
+		function _assertCorrectContentPane(widget, titleText){
+			runner.assertNotEqual(null, widget, "ContentPane: Did not instantiate.");
+			runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + widget.domNode.id);
+			var c = widget.getChildren();
+			runner.assertNotEqual(null, c, "ContentPane: Does not have children (null).");
+			runner.assertNotEqual(undefined, c, "ContentPane: Does not have children (undefined).");
+			runner.assertNotEqual(null, c[0], "ContentPane: Did not instantiate first child (null). id=" + 
+				widget.domNode.id + " c=" + c + " c[0]=" + c[0]);
+			runner.assertNotEqual(undefined, c[0], "ContentPane: Did not instantiate first child (undefined). id=" + 
+				widget.domNode.id + " c=" + c + " c[0]=" + c[0]);
+			runner.assertTrue(domClass.contains(c[0].domNode, WIDGET2_CLASSNAME1), WIDGET2_CLASSNAME1 + " id=" + c[0].domNode.id);
+			runner.assertTrue(domClass.contains(c[0].domNode, WIDGET2_CLASSNAME2), WIDGET2_CLASSNAME2 + " id=" + c[0].domNode.id);
+			runner.assertEqual(titleText, string.trim(c[0].domNode.innerHTML.replace(/\r\n/g,"")), "id=" + c[0].domNode.id);
+		}
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		}
+		ready(function(){
+			_initContentPane(["view1-pane3","view1-pane4","view1-pane5"]);
+			_createContentPaneProgrammatically(["view1-pane6","view1-pane7","view1-pane8","view1-pane9","view1-pane10"], 
+				["view1-pane6place","view1-pane7place","view1-pane8place","view1-pane9place","view1-pane10place"]);
+			_initContentPane(["view1-pane8","view1-pane9","view1-pane10"]);
+			_createContentPaneProgrammaticallyWithSourceNodeReference(["view1-pane11","view1-pane12","view1-pane13","view1-pane14","view1-pane15"]);
+			_initContentPane(["view1-pane13","view1-pane14","view1-pane15"]);
+
+			_showView2();
+			_initContentPane(["view2-pane3","view2-pane4","view2-pane5"]);
+			_createContentPaneProgrammatically(["view2-pane6","view2-pane7","view2-pane8","view2-pane9","view2-pane10"], 
+				["view2-pane6place","view2-pane7place","view2-pane8place","view2-pane9place","view2-pane10place"]);
+			_initContentPane(["view2-pane8","view2-pane9","view2-pane10"]);
+			_createContentPaneProgrammaticallyWithSourceNodeReference(["view2-pane11","view2-pane12","view2-pane13","view2-pane14","view2-pane15"]);
+			_initContentPane(["view2-pane13","view2-pane14","view2-pane15"]);
+
+			runner.register("dojox.mobile.test.doh.ContentPane", [
+				{
+					name: "ContentPane Verification1",
+					timeout: 10000,
+					runTest: function(){
+ 						var widget = registry.byId("view1-pane14");
+						var d = new runner.Deferred();
+						// The loading of the content of the different ContentPane instances is performed 
+						// asynchronously in an undefined order. Hence the use of setTimeout such that the
+						// checks are performed after the loading of all ContentPanes in view1.
+						setTimeout(d.getTestCallback(function(){
+								_assertCorrectContentPanes(["view1-pane1","view1-pane2","view1-pane3","view1-pane4","view1-pane5"]);
+								_assertCorrectContentPanes(["view1-pane6","view1-pane7","view1-pane8","view1-pane9","view1-pane10"]);
+								_assertCorrectContentPanes(["view1-pane11","view1-pane12","view1-pane13","view1-pane14","view1-pane15"]);
+						}), 5000);
+						return d;
+					}
+				},
+				{
+					name: "ContentPane Verification2",
+					timeout: 10000,
+					runTest: function(){
+ 						var widget = registry.byId("view2-pane14");
+						var d = new runner.Deferred();
+						// The loading of the content of the different ContentPane instances is performed 
+						// asynchronously in an undefined order. Hence the use of setTimeout such that the
+						// checks are performed after the loading of all ContentPanes in view1.
+						setTimeout(d.getTestCallback(function(){
+							_assertCorrectContentPanes(["view2-pane1","view2-pane2","view2-pane3","view2-pane4","view2-pane5"]);
+							_assertCorrectContentPanes(["view2-pane6","view2-pane7","view2-pane8","view2-pane9","view2-pane10"]);
+							_assertCorrectContentPanes(["view2-pane11","view2-pane12","view2-pane13","view2-pane14","view2-pane15"]);
+						}), 5000);
+						return d;
+					}
+				}
+			]);
+			
+			runner.run();
+
+		});
+	})
+</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" dojoType="dojox.mobile.View">
+		<h1>View 1</h1>
+
+		<div id="view1-pane1" data-dojo-type="dojox.mobile.ContentPane"
+		     data-dojo-props='content:"<div data-dojo-type='dojox.mobile.RoundRect' shadow='true'>Pane 1 : Thank you!</div>"'></div>
+
+		<div id="view1-pane2" data-dojo-type="dojox.mobile.ContentPane"
+		     data-dojo-props='href:"fragment1.html"'></div>
+
+		<div id="view1-pane3" data-dojo-type="dojox.mobile.ContentPane"></div>
+
+		<div id="view1-pane4" data-dojo-type="dojox.mobile.ContentPane"></div>
+
+		<div id="view1-pane5" data-dojo-type="dojox.mobile.ContentPane"></div>
+		<hr/>
+		<div id="view1-pane6place"></div>
+
+		<div id="view1-pane7place"></div>
+
+		<div id="view1-pane8place"></div>
+
+		<div id="view1-pane9place"></div>
+
+		<div id="view1-pane10place"></div>
+		<hr/>
+		<div id="view1-pane11"></div>
+
+		<div id="view1-pane12"></div>
+
+		<div id="view1-pane13"></div>
+
+		<div id="view1-pane14"></div>
+
+		<div id="view1-pane15"></div>
+
+	</div>
+	<div id="view2" dojoType="dojox.mobile.View">
+		<h1>View 2</h1>
+
+		<div id="view2-pane1" data-dojo-type="dojox.mobile.ContentPane"
+		     data-dojo-props='content:"<div data-dojo-type='dojox.mobile.RoundRect' shadow='true'>Pane 1 : Thank you!</div>"'></div>
+
+		<div id="view2-pane2" data-dojo-type="dojox.mobile.ContentPane"
+		     data-dojo-props='href:"fragment1.html"'></div>
+
+		<div id="view2-pane3" data-dojo-type="dojox.mobile.ContentPane"></div>
+
+		<div id="view2-pane4" data-dojo-type="dojox.mobile.ContentPane"></div>
+
+		<div id="view2-pane5" data-dojo-type="dojox.mobile.ContentPane"></div>
+		<hr/>
+		<div id="view2-pane6place"></div>
+
+		<div id="view2-pane7place"></div>
+
+		<div id="view2-pane8place"></div>
+
+		<div id="view2-pane9place"></div>
+
+		<div id="view2-pane10place"></div>
+		<hr/>
+		<div id="view2-pane11"></div>
+
+		<div id="view2-pane12"></div>
+
+		<div id="view2-pane13"></div>
+
+		<div id="view2-pane14"></div>
+
+		<div id="view2-pane15"></div>
+
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/contentpane/fragment1.html b/dojox/mobile/tests/doh/contentpane/fragment1.html
new file mode 100644
index 0000000..7ff1a2c
--- /dev/null
+++ b/dojox/mobile/tests/doh/contentpane/fragment1.html
@@ -0,0 +1,3 @@
+<div dojoType="dojox.mobile.RoundRect" shadow="true">
+  Pane 2 : HTML fragment example
+</div>
diff --git a/dojox/mobile/tests/doh/contentpane/fragment2.html b/dojox/mobile/tests/doh/contentpane/fragment2.html
new file mode 100644
index 0000000..e9a4d66
--- /dev/null
+++ b/dojox/mobile/tests/doh/contentpane/fragment2.html
@@ -0,0 +1,3 @@
+<div dojoType="dojox.mobile.RoundRect" shadow="true">
+  Pane 4 : HTML fragment example
+</div>
diff --git a/dojox/mobile/tests/doh/contentpane/module.js b/dojox/mobile/tests/doh/contentpane/module.js
new file mode 100644
index 0000000..8fc918a
--- /dev/null
+++ b/dojox/mobile/tests/doh/contentpane/module.js
@@ -0,0 +1,9 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.ContentPane", require.toUrl("./ContentPaneTests.html"),999999);
+	}
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/contentpane/runTests.html b/dojox/mobile/tests/doh/contentpane/runTests.html
new file mode 100644
index 0000000..4745cce
--- /dev/null
+++ b/dojox/mobile/tests/doh/contentpane/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.contentpane.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/data/view1.html b/dojox/mobile/tests/doh/data/view1.html
new file mode 100644
index 0000000..bb6ab80
--- /dev/null
+++ b/dojox/mobile/tests/doh/data/view1.html
@@ -0,0 +1,14 @@
+<div id="view1" dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home">view1.html</h1>
+	<ul dojoType="dojox.mobile.EdgeToEdgeList">
+		<li dojoType="dojox.mobile.ListItem">
+			Jack Coleman
+		</li>
+		<li dojoType="dojox.mobile.ListItem">
+			James Evans
+		</li>
+		<li dojoType="dojox.mobile.ListItem">
+			Jason Griffin
+		</li>
+	</ul>
+</div>
diff --git a/dojox/mobile/tests/doh/data/view1.myjson b/dojox/mobile/tests/doh/data/view1.myjson
new file mode 100644
index 0000000..defb2f2
--- /dev/null
+++ b/dojox/mobile/tests/doh/data/view1.myjson
@@ -0,0 +1,41 @@
+{
+  "dojox.mobile.View": {
+    "@id": "view1",
+    "dojox.mobile.Heading": {
+      "@label": "view1.myjson"
+    },
+    "dojox.mobile.RoundRectList": [{
+      "dojox.mobile.ListItem": [{
+        "@icon": "../images/i-icon-1.png",
+        "@label": "Airplane Mode",
+        "dojox.mobile.Switch": {
+        }
+      }, {
+        "@moveTo": "test_iPhone-Icon.html",
+        "@icon": "../images/i-icon-2.png",
+        "@label": "Wi-Fi",
+        "@rightText": "mac"
+      }, {
+        "@icon": "../images/i-icon-3.png",
+        "@label": "Carrier",
+        "@moveTo": "home",
+        "@rightText": "AcmePhone"
+      }]
+    }, {
+      "dojox.mobile.ListItem": [{
+        "@icon": "../images/i-icon-4.png",
+        "@label": "Sounds",
+        "@moveTo": "home"
+      }, {
+        "@icon": "../images/i-icon-5.png",
+        "@label": "Brightness",
+        "@moveTo": "home"
+      }, {
+        "@icon": "../images/i-icon-6.png",
+        "@label": "Wallpaper",
+        "@moveTo": "home"
+      }]
+    }]
+  }
+}
+
diff --git a/dojox/mobile/tests/doh/data/view2.html b/dojox/mobile/tests/doh/data/view2.html
new file mode 100644
index 0000000..f6c6d62
--- /dev/null
+++ b/dojox/mobile/tests/doh/data/view2.html
@@ -0,0 +1,9 @@
+<div id="view2" dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home" label="view2.html"></h1>
+	<h2 dojoType="dojox.mobile.RoundRectCategory" label="Transition Effects"></h2>
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-1.png" moveTo="home" transition="slide" label="Slide"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-2.png" moveTo="home" transition="flip" label="Flip"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-3.png" moveTo="home" transition="fade" label="Fade"></li>
+	</ul>
+</div>
diff --git a/dojox/mobile/tests/doh/data/view3.html b/dojox/mobile/tests/doh/data/view3.html
new file mode 100644
index 0000000..fab752b
--- /dev/null
+++ b/dojox/mobile/tests/doh/data/view3.html
@@ -0,0 +1,16 @@
+<div id="view3" dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" label="view3.html"></h1>
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-1.png" label="Airplane Mode">
+			<div dojoType="dojox.mobile.Switch"></div>
+		</li>
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-2.png" rightText="mac" href="test_iPhone-Icon.html" label="Wi-Fi"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-3.png" rightText="AcmePhone" moveTo="home" label="Carrier"></li>
+	</ul>
+
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-4.png" moveTo="home" label="Sounds"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-5.png" moveTo="home" label="Brightness"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-6.png" moveTo="home" label="Wallpaper"></li>
+	</ul>
+</div>
diff --git a/dojox/mobile/tests/doh/data/view3.mydata b/dojox/mobile/tests/doh/data/view3.mydata
new file mode 100644
index 0000000..8252b21
--- /dev/null
+++ b/dojox/mobile/tests/doh/data/view3.mydata
@@ -0,0 +1,27 @@
+{
+  "dojox.mobile.View": {
+    "@id": "view3",
+    "dojox.mobile.Heading": {
+      "@label": "view3.mydata"
+    },
+    "dojox.mobile.RoundRectList": [{
+      "dojox.mobile.ListItem": [{
+        "@icon": "../images/i-icon-1.png",
+        "@label": "Airplane Mode",
+        "dojox.mobile.Switch": {
+        }
+      }, {
+        "@href": "test_iPhone-Icon.html",
+        "@icon": "../images/i-icon-2.png",
+        "@label": "Wi-Fi",
+        "@rightText": "mac"
+      }, {
+        "@icon": "../images/i-icon-3.png",
+        "@label": "Carrier",
+        "@moveTo": "home",
+        "@rightText": "AcmePhone"
+      }]
+    }]
+  }
+}
+
diff --git a/dojox/mobile/tests/doh/data/view4.html b/dojox/mobile/tests/doh/data/view4.html
new file mode 100644
index 0000000..f65914a
--- /dev/null
+++ b/dojox/mobile/tests/doh/data/view4.html
@@ -0,0 +1,17 @@
+<div id="view4" dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home" label="view4.html"></h1>
+
+	<h2 dojoType="dojox.mobile.RoundRectCategory" label="Category 1"></h2>
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-1.png" moveTo="home" transition="slide" label="Item 1"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-2.png" moveTo="home" transition="flip" label="Item 2"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-3.png" moveTo="home" transition="fade" label="Item 3"></li>
+	</ul>
+
+	<h2 dojoType="dojox.mobile.RoundRectCategory" label="Category 2"></h2>
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-1.png" moveTo="home" transition="slide" label="Item 1"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-2.png" moveTo="home" transition="flip" label="Item 2"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="../images/i-icon-3.png" moveTo="home" transition="fade" label="Item 3"></li>
+	</ul>
+</div>
diff --git a/dojox/mobile/tests/doh/data/view5.html b/dojox/mobile/tests/doh/data/view5.html
new file mode 100644
index 0000000..354e85b
--- /dev/null
+++ b/dojox/mobile/tests/doh/data/view5.html
@@ -0,0 +1,7 @@
+<div id="view5" dojoType="dojox.mobile.View">
+	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home" label="view5.html"></h1>
+	<div id="spin1" data-dojo-type="dojox.mobile.SpinWheel" style="margin:10px auto;width:304px">
+		<div data-dojo-type="dojox.mobile.SpinWheelSlot" labels="A,B,C,D,E"
+			style="text-align:center;width:300px;"></div>
+	</div>
+</div>
diff --git a/dojox/mobile/tests/doh/data/view5.mydata2 b/dojox/mobile/tests/doh/data/view5.mydata2
new file mode 100644
index 0000000..b3623df
--- /dev/null
+++ b/dojox/mobile/tests/doh/data/view5.mydata2
@@ -0,0 +1,39 @@
+{
+  "class": "dojox.mobile.View",
+  "@id": "view5",
+  "children": [
+
+    {
+      "class": "dojox.mobile.Heading",
+      "@back": "Home",
+      "@moveTo": "home",
+      "@label": "view5.json"
+    },
+    {
+      "class": "dojox.mobile.EdgeToEdgeList",
+      "children": [
+        {
+          "class": "dojox.mobile.ListItem",
+          "@icon": "../images/i-icon-1.png",
+          "@moveTo": "home",
+          "@transition": "slide",
+          "@label": "Item 1"
+        },
+        {
+          "class": "dojox.mobile.ListItem",
+          "@icon": "../images/i-icon-2.png",
+          "@moveTo": "home",
+          "@transition": "flip",
+          "@label": "Item 2"
+        },
+        {
+          "class": "dojox.mobile.ListItem",
+          "@icon": "../images/i-icon-3.png",
+          "@moveTo": "home",
+          "@transition": "fade",
+          "@label": "Item 3"
+        }
+      ]
+    }
+  ]
+}
diff --git a/dojox/mobile/tests/doh/data/view6.myhtml b/dojox/mobile/tests/doh/data/view6.myhtml
new file mode 100644
index 0000000..24374d0
--- /dev/null
+++ b/dojox/mobile/tests/doh/data/view6.myhtml
@@ -0,0 +1,8 @@
+<div id="view6" data-dojo-type="dojox.mobile.View">
+	<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"home"'>view6 (HTML)</h1>
+	<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Script Views</h2>
+	<script>
+		console.log("This is Script in View6");
+		window._ScriptInView6 = true;
+	</script>
+</div>
diff --git a/dojox/mobile/tests/doh/edgetoedgecategory/EdgeToEdgeCatagory.js b/dojox/mobile/tests/doh/edgetoedgecategory/EdgeToEdgeCatagory.js
new file mode 100644
index 0000000..99fc535
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgecategory/EdgeToEdgeCatagory.js
@@ -0,0 +1,72 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.EdgeToEdgeList", [
+		{
+			name: "EdgeToEdgeList Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("Category");
+					doh.assertEqual('mblEdgeToEdgeCategory', demoWidget.domNode.className);
+					doh.assertEqual('Spaces', demoWidget.domNode.innerHTML);
+
+
+					demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
+					doh.assertEqual('mblEdgeToEdgeList', demoWidget.domNode.className);
+					verifyListItem("item1", 'u1space', 'Off', "mblDomButtonArrow", true, true, false);
+					verifyListItem("item2", 'u2space', 'On', "mblDomButtonArrow", true, true, false);
+					verifyListItem("item3", 'Wi-Fi', 'Off', "mblDomButtonArrow", false, true, false);
+					
+				}));
+				return d;
+			}
+		},
+		{
+			name: "EdgeToEdgeList Verification2",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				var demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
+				demoWidget.set({transition :"flip"});
+				doh.assertEqual("flip", demoWidget.get("transition"));
+				demoWidget.set({transition :"fade"});
+				doh.assertEqual("fade", demoWidget.get("transition"));
+
+				fireOnMouseDown("item3");
+				fireOnMouseUp("item3");
+				var view = dijit.byId("foo");
+				dojo.connect(view, "onAfterTransitionOut", this, d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeCategory_0");
+					doh.assertEqual('mblEdgeToEdgeCategory', demoWidget.domNode.className);
+					doh.assertEqual('Applications', demoWidget.domNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_1");
+					doh.assertEqual('mblEdgeToEdgeList', demoWidget.domNode.className);
+
+					verifyListItem("dojox_mobile_ListItem_0", 'Video', 'Off', "", false, false, false);
+					verifyListItem("dojox_mobile_ListItem_1", 'Maps', 'VPN', "", true, false, false);
+					verifyListItem("dojox_mobile_ListItem_2", 'Phone Number', 'Off', "", false, false, false);
+				}));
+				return d;
+			}
+		},
+		{
+			name: "EdgeToEdgeCategory getLabel",
+			timeout: 1000,
+			runTest: function(){
+				doh.assertEqual("Spaces", dijit.byId("Category").get("label")); 
+			}
+		},
+		{
+			name: "EdgeToEdgeCategory setLabel",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("Category");
+				demoWidget.set({label :"Value Changed"});
+				doh.assertEqual("Value Changed", demoWidget.get("label"));
+				doh.assertEqual('Value Changed', demoWidget.domNode.innerHTML);
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/edgetoedgecategory/EdgeToEdgeCategory.html b/dojox/mobile/tests/doh/edgetoedgecategory/EdgeToEdgeCategory.html
new file mode 100644
index 0000000..14bc701
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgecategory/EdgeToEdgeCategory.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Edge To Edge List</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+//			dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="EdgeToEdgeCatagory.js"></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
+			<h2 id="Category" dojoType="dojox.mobile.EdgeToEdgeCategory">Spaces</h2>
+			<ul dojoType="dojox.mobile.EdgeToEdgeList">
+				<li id="item1" dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightText="Off" moveTo="bar">u1space</li>
+				<li id="item2" dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-2.png" rightText="On" moveTo="bar">u2space</li>
+				<li id="item3" dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="bar">Wi-Fi</li>
+			</ul>
+		</div>
+
+		<div id="bar" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="foo">u1space</h1>
+			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Applications</h2>
+			<ul dojoType="dojox.mobile.EdgeToEdgeList">
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">Video</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightText="VPN">Maps</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">Phone Number</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/edgetoedgecategory/EdgeToEdgeCategoryTests.html b/dojox/mobile/tests/doh/edgetoedgecategory/EdgeToEdgeCategoryTests.html
new file mode 100644
index 0000000..317873f
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgecategory/EdgeToEdgeCategoryTests.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Edge To Edge Category Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	require([
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/EdgeToEdgeCategory",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(domConst, ready, registry, runner, EdgeToEdgeCategory){
+
+		var CATEGORY_LABEL = "Edge To Edge Category";
+		var WIDGET_CLASSNAME1 = "mblEdgeToEdgeCategory";
+
+		function _createEdgeToEdgeCategoryDeclaratively(id) {
+			return registry.byId(id);
+		};
+		
+		function _createEdgeToEdgeCategoryProgrammatically(placeHolderId){
+			var widget = new EdgeToEdgeCategory({label:CATEGORY_LABEL});
+			runner.assertNotEqual(null, widget);
+			domConst.place(widget.domNode, placeHolderId, "replace");
+			widget.startup();
+			return widget;
+		};
+		
+		function _createEdgeToEdgeCategoryProgrammaticallyWithSourceNodeReference(id){
+			return new EdgeToEdgeCategory({label:CATEGORY_LABEL}, id);
+		};
+
+		function _assertCorrectEdgeToEdgeCategory(category){
+			runner.assertNotEqual(null, category);
+			runner.assertEqual(CATEGORY_LABEL, category.label, category.toString())
+			runner.assertEqual(CATEGORY_LABEL, category.domNode.innerHTML, "innerHTML id=" + category.domNode.id)
+			runner.assertEqual(WIDGET_CLASSNAME1, category.domNode.className, "id=" + category.domNode.id)
+		};
+		
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		};
+
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.EdgeToEdgeCategoryTests", [
+				function testInView1(){
+					var category1 = _createEdgeToEdgeCategoryDeclaratively("view1-category1");
+					var category2 = _createEdgeToEdgeCategoryProgrammatically("view1-category2");
+					var category3 = _createEdgeToEdgeCategoryProgrammaticallyWithSourceNodeReference("view1-category3");
+			
+					_assertCorrectEdgeToEdgeCategory(category1);
+					_assertCorrectEdgeToEdgeCategory(category2);
+					_assertCorrectEdgeToEdgeCategory(category3);
+				},
+				function testInView2(){
+					var category1 = _createEdgeToEdgeCategoryDeclaratively("view2-category1");
+					var category2 = _createEdgeToEdgeCategoryProgrammatically("view2-category2");
+					var category3 = _createEdgeToEdgeCategoryProgrammaticallyWithSourceNodeReference("view2-category3");
+					
+					_showView2();
+					
+					_assertCorrectEdgeToEdgeCategory(category1);
+					_assertCorrectEdgeToEdgeCategory(category2);
+					_assertCorrectEdgeToEdgeCategory(category3);
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<h2 id="view1-category1" data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Edge To Edge Category</h2>		
+		<div id="view1-category2"></div>
+		<h2 id="view1-category3"></h2>
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<h2 id="view2-category1" data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Edge To Edge Category</h2>		
+		<div id="view2-category2"></div>
+		<h2 id="view2-category3"></h2>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/edgetoedgecategory/module.js b/dojox/mobile/tests/doh/edgetoedgecategory/module.js
new file mode 100644
index 0000000..987e891
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgecategory/module.js
@@ -0,0 +1,8 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.EdgeToEdgeCategory", require.toUrl("./EdgeToEdgeCategory.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.EdgeToEdgeCategory", require.toUrl("./EdgeToEdgeCategoryTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/edgetoedgecategory/runTests.html b/dojox/mobile/tests/doh/edgetoedgecategory/runTests.html
new file mode 100644
index 0000000..dafabf8
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgecategory/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.edgetoedgecategory.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/edgetoedgedatalist/EdgeToEdgeDataList.html b/dojox/mobile/tests/doh/edgetoedgedatalist/EdgeToEdgeDataList.html
new file mode 100644
index 0000000..609db67
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgedatalist/EdgeToEdgeDataList.html
@@ -0,0 +1,71 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>EdgeToEdgeDataList</title>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.data.ItemFileWriteStore");
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.deviceTheme");
+			dojo.require("dojox.mobile.EdgeToEdgeDataList");
+
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+
+			var static_data = { 
+				items: [ 
+					{label: "Apple", 	moveTo: "dummy"},
+					{label: "Banana", 	moveTo: "dummy"},
+					{label: "Cherry", 	moveTo: "dummy"},
+					{label: "Grape", 	moveTo: "dummy"},
+					{label: "Kiwi", 	moveTo: "dummy"},
+					{label: "Lemon", 	moveTo: "dummy"},
+					{label: "Melon", 	moveTo: "dummy"},
+					{label: "Orange", 	moveTo: "dummy"},
+					{label: "Peach", 	moveTo: "dummy"}
+				]
+			};
+			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
+			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
+			var store = store1;
+			var newItems = [[],[]];
+
+			// switch to the selected store
+			function switchTo(store){
+				window.store = store;
+				dijit.byId("list").setStore(store);
+			}
+			// add a new item
+			function add1(){
+				var item = store.newItem({label: "New Item", moveTo: "dummy"});
+				this.newItems[(store == store1) ? 1 : 0].push(item);
+			}
+			// delete the added item
+			function delete1(){
+				var item = this.newItems[(store == store1) ? 1 : 0].pop();
+				if(item){
+					store.deleteItem(item);
+				}
+			}
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="../RoundRectDataList.js"></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">EdgeToEdgeDataList</h1>
+			<ul dojoType="dojox.mobile.EdgeToEdgeDataList" id="list" store="store" query="{label: '*'}"></ul>
+			<p>show the different set:<br>
+			<input type="button" value="Set1" onclick="switchTo(store1)">
+			<input type="button" value="Set2" onclick="switchTo(store2)">
+			<p>alter the object store:<br>
+			<input type="button" value="Add" onclick="add1()">
+			<input type="button" value="Delete" onclick="delete1()">
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/edgetoedgedatalist/EdgeToEdgeDataListTests.html b/dojox/mobile/tests/doh/edgetoedgedatalist/EdgeToEdgeDataListTests.html
new file mode 100644
index 0000000..b49700c
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgedatalist/EdgeToEdgeDataListTests.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Edge To Edge Data List Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var IsEdgeToEdgeList = true;
+</script>
+<script type="text/javascript" src="../DataListTests.js"></script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<ul id="view1-dataList1" data-dojo-type="dojox.mobile.EdgeToEdgeDataList" store="fruits11" query="{label: '*'}"></ul>
+		<div id="view1-dataList2"></div>
+		<ul id="view1-dataList3"></ul>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<ul id="view2-dataList1" data-dojo-type="dojox.mobile.EdgeToEdgeDataList" store="fruits21" query="{label: '*'}"></ul>
+		<div id="view2-dataList2"></div>
+		<ul id="view2-dataList3"></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/edgetoedgedatalist/EdgeToEdgeDataList_Programmatic.html b/dojox/mobile/tests/doh/edgetoedgedatalist/EdgeToEdgeDataList_Programmatic.html
new file mode 100644
index 0000000..33ea4b5
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgedatalist/EdgeToEdgeDataList_Programmatic.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>EdgeToEdgeDataList</title>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.data.ItemFileWriteStore");
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.deviceTheme");
+			dojo.require("dojox.mobile.EdgeToEdgeDataList");
+
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+
+			var static_data = { 
+				items: [ 
+					{label: "Apple", 	moveTo: "dummy"},
+					{label: "Banana", 	moveTo: "dummy"},
+					{label: "Cherry", 	moveTo: "dummy"},
+					{label: "Grape", 	moveTo: "dummy"},
+					{label: "Kiwi", 	moveTo: "dummy"},
+					{label: "Lemon", 	moveTo: "dummy"},
+					{label: "Melon", 	moveTo: "dummy"},
+					{label: "Orange", 	moveTo: "dummy"},
+					{label: "Peach", 	moveTo: "dummy"}
+				]
+			};
+			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
+			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
+			var store = store1;
+			var newItems = [[],[]];
+
+			// switch to the selected store
+			function switchTo(store){
+				window.store = store;
+				dijit.byId("list").setStore(store);
+			}
+			// add a new item
+			function add1(){
+				var item = store.newItem({label: "New Item", moveTo: "dummy"});
+				this.newItems[(store == store1) ? 1 : 0].push(item);
+			}
+			// delete the added item
+			function delete1(){
+				var item = this.newItems[(store == store1) ? 1 : 0].pop();
+				if(item){
+					store.deleteItem(item);
+				}
+			}
+
+			dojo.addOnLoad(function(){
+				var view = dijit.byId("foo");
+				var demoWidget = new dojox.mobile.EdgeToEdgeDataList({id:"list", store:store, query:{label: '*'}});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+			});
+
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="../RoundRectDataList.js"></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">EdgeToEdgeDataList</h1>
+			<p>show the different set:<br>
+			<input type="button" value="Set1" onclick="switchTo(store1)">
+			<input type="button" value="Set2" onclick="switchTo(store2)">
+			<p>alter the object store:<br>
+			<input type="button" value="Add" onclick="add1()">
+			<input type="button" value="Delete" onclick="delete1()">
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/edgetoedgedatalist/module.js b/dojox/mobile/tests/doh/edgetoedgedatalist/module.js
new file mode 100644
index 0000000..2130334
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgedatalist/module.js
@@ -0,0 +1,11 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.EdgeToEdgeDataList", require.toUrl("./EdgeToEdgeDataList.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.EdgeToEdgeDataList", require.toUrl("./EdgeToEdgeDataList_Programmatic.html"),999999);
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.EdgeToEdgeDataList", require.toUrl("./EdgeToEdgeDataListTests.html"),999999);
+	}
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/edgetoedgedatalist/runTests.html b/dojox/mobile/tests/doh/edgetoedgedatalist/runTests.html
new file mode 100644
index 0000000..e88ba34
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgedatalist/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.edgetoedgedatalist.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/edgetoedgedatalist/settings.json b/dojox/mobile/tests/doh/edgetoedgedatalist/settings.json
new file mode 100644
index 0000000..5be971a
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgedatalist/settings.json
@@ -0,0 +1,14 @@
+{
+  "items" : [
+    { "label" : "Wi-Fi",                        "icon" : "../../images/i-icon-1.png",   "moveTo": "wifi"                              },
+    { "label" : "Brightness & Wallpaper",       "icon" : "../../images/i-icon-2.png",   "moveTo": "bright"                            },
+    { "label" : "Picture Frame",                "icon" : "../../images/i-icon-3.png",   "moveTo": "picture"                           },
+    { "label" : "General",                      "icon" : "../../images/i-icon-4.png",   "moveTo": "general",  "selected": "true"      },
+    { "label" : "Mail, Contacts, Calendars",    "icon" : "../../images/i-icon-5.png",   "moveTo": "wifi"                              },
+    { "label" : "Safari",                       "icon" : "../../images/i-icon-6.png",   "moveTo": "bright"                            },
+    { "label" : "iPod",                         "icon" : "../../images/i-icon-7.png",   "moveTo": "picture"                           },
+    { "label" : "Video",                        "icon" : "../../images/i-icon-8.png",   "moveTo": "general"                           },
+    { "label" : "Photos",                       "icon" : "../../images/i-icon-9.png",   "moveTo": "wifi"                              },
+    { "label" : "Store",                        "icon" : "../../images/i-icon-10.png",  "moveTo": "bright"                            }
+  ]
+}
diff --git a/dojox/mobile/tests/doh/edgetoedgelist/EdgeToEdgeList.js b/dojox/mobile/tests/doh/edgetoedgelist/EdgeToEdgeList.js
new file mode 100644
index 0000000..c05956c
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgelist/EdgeToEdgeList.js
@@ -0,0 +1,77 @@
+dojo.require("dojo.parser"); // Use the lightweight parser.
+dojo.require("dojox.mobile.parser");
+dojo.require("dojox.mobile");
+dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+dojo.require("doh.runner");
+
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.EdgeToEdgeList", [
+		{
+			name: "EdgeToEdgeList Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("Category");
+					doh.assertEqual('mblEdgeToEdgeCategory', demoWidget.domNode.className);
+					doh.assertEqual('Spaces', demoWidget.domNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
+					doh.assertEqual('mblEdgeToEdgeList', demoWidget.domNode.className);
+					verifyListItem("item1", 'u1space', 'Off', "mblDomButtonArrow", true, true, false);
+					verifyListItem("item2", 'u2space', 'On', "mblDomButtonArrow", true, true, false);
+					verifyListItem("item3", 'Wi-Fi', 'Off', "mblDomButtonArrow", false, true, false);
+					
+				}));
+				return d;
+			}
+		},
+		{
+			name: "EdgeToEdgeList Verification2",
+			timeout: 1000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				var demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
+				demoWidget.set({transition :"flip"});
+				doh.assertEqual("flip", demoWidget.get("transition"));
+				demoWidget.set({transition :"fade"});
+				doh.assertEqual("fade", demoWidget.get("transition"));
+
+				fireOnClick("item3");
+				var view = dijit.byId("foo");
+				dojo.connect(view, "onAfterTransitionOut", this, d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeCategory_0");
+					doh.assertEqual('mblEdgeToEdgeCategory', demoWidget.domNode.className);
+					doh.assertEqual('Applications', demoWidget.domNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_ListItem_1");
+					doh.assertEqual('mblRoundRectList', demoWidget.domNode.className);
+
+					verifyListItem("dojox_mobile_ListItem_0", 'Video', 'Off', "", false, true, false);
+					verifyListItem("dojox_mobile_ListItem_1", 'Maps', 'VPN', "", true, false, false);
+					verifyListItem("dojox_mobile_ListItem_2", 'Phone Number', 'Off', "", false, false, false);
+				}));
+				return d;
+			}
+		},
+		{
+			name: "EdgeToEdgeCategory getLabel",
+			timeout: 1000,
+			runTest: function(){
+				doh.assertEqual("Spaces", dijit.byId("Category").get("label")); 
+			}
+		},
+		{
+			name: "EdgeToEdgeCategory setLabel",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("Category");
+				demoWidget.set({label :"Value Changed"});
+				doh.assertEqual("Value Changed", demoWidget.get("label"));
+				doh.assertEqual('Value Changed', demoWidget.domNode.innerHTML);
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/edgetoedgelist/EdgeToEdgeListTests.html b/dojox/mobile/tests/doh/edgetoedgelist/EdgeToEdgeListTests.html
new file mode 100644
index 0000000..80a5e03
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgelist/EdgeToEdgeListTests.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Edge To Edge List Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var IsEdgeToEdgeList = true;
+</script>
+<script type="text/javascript" src="../ListTests.js"></script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1>View 1</h1>
+		<ul id="view1-list1" data-dojo-type="dojox.mobile.EdgeToEdgeList" select="single">
+			<li data-dojo-type="dojox.mobile.ListItem" checked="true">Edge To Edge 1</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Edge To Edge 2</li>
+		</ul>		
+		<div id="view1-list2"></div>
+		<ul id="view1-list3"></ul>
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<ul id="view2-list1" data-dojo-type="dojox.mobile.EdgeToEdgeList" select="single">
+			<li data-dojo-type="dojox.mobile.ListItem" checked="true">Edge To Edge 1</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Edge To Edge 2</li>
+		</ul>		
+		<div id="view2-list2"></div>
+		<ul id="view2-list3"></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/edgetoedgelist/module.js b/dojox/mobile/tests/doh/edgetoedgelist/module.js
new file mode 100644
index 0000000..cde6993
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgelist/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.EdgeToEdgeList", require.toUrl("./EdgeToEdgeListTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/edgetoedgelist/runTests.html b/dojox/mobile/tests/doh/edgetoedgelist/runTests.html
new file mode 100644
index 0000000..416b549
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgelist/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.edgetoedgelist.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/edgetoedgestorelist/EdgeToEdgeStoreList-itemMap-updates.html b/dojox/mobile/tests/doh/edgetoedgestorelist/EdgeToEdgeStoreList-itemMap-updates.html
new file mode 100644
index 0000000..18d8ec1
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgestorelist/EdgeToEdgeStoreList-itemMap-updates.html
@@ -0,0 +1,152 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" 
+		data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../TestUtil.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"doh/runner",
+			"dojo/query",
+			"dojo/_base/lang",
+			"dojo/_base/array",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeStoreList"
+		], function(ready, runner, query, lang, array, Memory, Observable, registry){
+			var static_data1 = [
+				{ id: 1, text: "Category 1", header: true },
+				{ id: 2, text: "Wi-Fi", profile_image_url: "../../images/i-icon-1.png", moveTo: "wifi" },
+				{ id: 3, text: "Brightness & Wallpaper", profile_image_url: "../../images/i-icon-2.png", moveTo: "bright" },
+				{ id: 4, text: "Picture Frame", profile_image_url: "../../images/i-icon-3.png", moveTo: "picture" },
+				{ id: 5, text: "General", profile_image_url: "../../images/i-icon-4.png", moveTo: "general", "selected": "true" },
+				{ id: 6, text: "Mail, Contacts, Calendars", profile_image_url: "../../images/i-icon-5.png", moveTo: "wifi" },
+				{ id: 7, text: "Safari", profile_image_url: "../../images/i-icon-6.png", moveTo: "bright" },
+				{ id: 8, text: "iPod", profile_image_url: "../../images/i-icon-7.png", moveTo: "picture" },
+				{ id: 9, text: "Category 2", header: true },
+				{ id: 10, text: "Video", profile_image_url: "../../images/i-icon-8.png", moveTo: "general" },
+				{ id: 11, text: "Photos", profile_image_url: "../../images/i-icon-9.png", moveTo: "wifi" },
+				{ id: 12, text: "Store", profile_image_url: "../../images/i-icon-10.png", moveTo: "bright" }
+			];
+
+			var static_data2 = [
+				{id: 1, label: "Apple", 	moveTo: "dummy"},
+				{id: 2, label: "Banana", 	moveTo: "dummy"},
+				{id: 3, label: "Cherry", 	moveTo: "dummy"},
+				{id: 4, label: "Grape", 	moveTo: "dummy"},
+				{id: 5, label: "Kiwi", 	moveTo: "dummy"},
+				{id: 6, label: "Lemon", 	moveTo: "dummy"},
+				{id: 7, label: "Melon", 	moveTo: "dummy"},
+				{id: 8, label: "Orange", 	moveTo: "dummy"},
+				{id: 9, label: "Peach", 	moveTo: "dummy"}
+			];
+			store1 = Observable(new Memory({data: static_data1}));
+			store2 = Observable(new Memory({data: static_data2}));
+			store1.__counter = store2.__counter = 1;
+			store = store1;
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("list").setStore(store);
+			};
+			// add a new item
+			add1 = function(){
+				store.add({
+					id: 100 + store.__counter,
+					label: "New Item "+(store.__counter++),
+					icon: "images/i-icon-1.png",
+					moveTo: "dummy"
+				});
+			};
+			// update all items text or label
+			update1 = function(){
+				array.forEach(store.query({}), function(item, i){
+					var newItem = lang.clone(item);
+					if(newItem.text){
+						newItem.text = newItem.text+"-Updated";
+					}else{
+						newItem.label = newItem.label+"-Updated";
+					}
+					store.put(newItem);
+				});
+			};
+			// delete the added item
+			delete1 = function(){
+				if(store.__counter > 1){
+					store.remove(100 + (--store.__counter));
+				}
+			};
+			
+			// Tests
+			ready(function(){
+				runner.register("dojox.mobile.test.doh.scrollablepane.ScrollablePaneTests", [
+					{
+						name: "Verify that ticket #17093 is fixed",
+						timeout: 4000,
+						runTest: function(){
+							var referenceValues = lang.clone(static_data1);
+							var nodeIndex = 0;
+							// Verify what is displayed
+							var nodes = query(".mblListItemLabel", "list");
+							runner.assertEqual(referenceValues.length, nodes.length, 
+								"Before update, number of elements in the list is not the expected one");
+							nodes.forEach(function(node){
+								var text = node.textContent || node.innerText;
+								runner.assertEqual(text, referenceValues[nodeIndex].text);
+								nodeIndex++;
+							});
+							// Click the update button
+							fireOnClick(document.getElementById("updateButton"));
+							// Verify what is displayed
+							var def = new runner.Deferred();
+							setTimeout(def.getTestCallback(function(){
+								nodeIndex = 0;
+								var nodes = query(".mblListItemLabel", "list");
+								runner.assertEqual(referenceValues.length, nodes.length, 
+									"After update, number of elements in the list is not the expected one");
+								nodes.forEach(function(node){
+									var text = node.textContent || node.innerText;
+									runner.assertEqual(text, referenceValues[nodeIndex].text + "-Updated");
+									nodeIndex++;
+								});
+								}), 2000);
+							return def;
+							}
+						}
+					]);
+				runner.run();
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" id="list" 
+			data-dojo-props='store:store, query:{}, itemMap:{text:"label", profile_image_url:"icon"}'>
+		</ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" id="updateButton" value="Update" onclick="update1()">
+		<input type="button" value="Delete" onclick="delete1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/edgetoedgestorelist/EdgeToEdgeStoreList.html b/dojox/mobile/tests/doh/edgetoedgestorelist/EdgeToEdgeStoreList.html
new file mode 100644
index 0000000..de95de1
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgestorelist/EdgeToEdgeStoreList.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		var IsEdgeToEdgeList = true;
+	</script>
+	<script type="text/javascript" src="StoreList.js"></script>
+</head>
+<body style="visibility:hidden;">
+	<script type="dojo/require">
+		CustomListItem: "dojox/mobile/tests/doh/CustomListItem"
+	</script>
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="list"
+			data-dojo-props="store:store, query:{}, itemRenderer: CustomListItem"></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/edgetoedgestorelist/EdgeToEdgeStoreList_Programmatic.html b/dojox/mobile/tests/doh/edgetoedgestorelist/EdgeToEdgeStoreList_Programmatic.html
new file mode 100644
index 0000000..4f12365
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgestorelist/EdgeToEdgeStoreList_Programmatic.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"dojo/ready", // dojo.ready
+			"dijit/registry",  // dijit.byId
+			"dojox/mobile/tests/doh/CustomListItem",
+			"dojox/mobile/EdgeToEdgeStoreList",
+			"dojox/mobile",				// This is a mobile app.
+			"dojox/mobile/View",		// This mobile app uses mobile view
+			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+			"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+		], function(ready, registry, CustomListItem, EdgeToEdgeStoreList){
+			ready(function(){
+				var view = registry.byId("foo");
+				var demoWidget = new EdgeToEdgeStoreList({id:"list", store:store, query:{}, itemRenderer: CustomListItem});
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+			});
+		});
+</script>
+	<script type="text/javascript">
+		var IsEdgeToEdgeList = true;
+	</script>
+	<script type="text/javascript" src="StoreList.js"></script>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/edgetoedgestorelist/StoreList.js b/dojox/mobile/tests/doh/edgetoedgestorelist/StoreList.js
new file mode 100644
index 0000000..e4835a1
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgestorelist/StoreList.js
@@ -0,0 +1,217 @@
+require([
+	"dojo/parser",
+	"dojo/_base/Deferred",
+	"dojo/store/Cache",
+	"dojo/store/JsonRest",
+	"dojo/store/Memory",
+	"dojo/store/Observable",
+	"dojo/ready", // dojo.ready
+	"dijit/registry",
+	"doh/runner",	//doh functions
+	"dojox/mobile/EdgeToEdgeStoreList",
+	"dojox/mobile/RoundRectStoreList",
+	"dojox/mobile/tests/doh/CustomListItem",
+	/*"dojox/mobile/parser",*/
+	"dojox/mobile",
+	"dojox/mobile/compat"
+], function(parser, Deferred, Cache, JsonRest, Memory, Observable, ready, registry, runner, EdgeToEdgeStoreList, RoundRectStoreList){
+
+	var CLASS_NAME;
+	var DataList;
+	var testName;
+
+	if(IsEdgeToEdgeList){
+		CLASS_NAME = "mblEdgeToEdgeList";
+		DataList = EdgeToEdgeStoreList;
+		testName = "dojox.mobile.test.doh.EdgeToEdgeStoreList";
+	}else{
+		CLASS_NAME = "mblRoundRectList";
+		DataList = RoundRectStoreList;
+		testName = "dojox.mobile.test.doh.RoundRectStoreList";
+	}
+
+	var static_data2 = [
+		{label: "Apple", 	moveTo: "dummy"},
+		{label: "Banana", 	moveTo: "dummy"},
+		{label: "Cherry", 	moveTo: "dummy"},
+		{label: "Grape", 	moveTo: "dummy"},
+		{label: "Kiwi", 	moveTo: "dummy"},
+		{label: "Lemon", 	moveTo: "dummy"},
+		{label: "Melon", 	moveTo: "dummy"},
+		{label: "Orange", 	moveTo: "dummy"},
+		{label: "Peach", 	moveTo: "dummy"}
+	];
+	var url = "settings2.json";
+	store1 = new JsonRest({idProperty:"label", target: url});
+	store2 = Observable(new Memory({idProperty:"label", data: static_data2}));
+	store1.__counter = store2.__counter = 1;
+	store = store1;
+
+	// switch to the selected store
+	switchTo = function(store){
+		window.store = store;
+		registry.byId("list").setStore(store);
+	};
+	// add a new item
+	add1 = function(){
+		store.add({
+			label: "New Item "+(store.__counter++),
+			icon: "../../images/i-icon-1.png",
+			moveTo: "dummy"
+		});
+	};
+	// delete the added item
+	delete1 = function(){
+		if(store.__counter > 1){
+			store.remove("New Item "+(--store.__counter));
+		}
+	};
+	// modify the added item
+	var modif_counter = 0;
+	modify1 = function(){
+		if(store.__counter > 1){
+			store.put({
+				label: "New Item "+(store.__counter-1),
+				rightText: ++modif_counter + " changes"
+			});
+		}
+	};
+
+	ready(function(){
+		runner.register(testName, [
+			{
+				name: DataList + " Verification",
+				timeout: 4000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var demoWidget = registry.byId("dojox_mobile_ListItem_0");
+						// check whether we correctly constructed a custom item
+						runner.assertTrue(demoWidget.customProp);
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertTrue(demoWidget.iconNode.src.search(/i-icon-1.png/i) != -1);
+						runner.assertEqual('mblListItemRightIcon', demoWidget.rightIconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('Wi-Fi', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						demoWidget = registry.byId("dojox_mobile_ListItem_3");
+						runner.assertEqual('mblListItem mblListItemSelected', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertTrue(demoWidget.iconNode.src.search(/i-icon-4.png/i) != -1);
+						runner.assertEqual('mblListItemRightIcon', demoWidget.rightIconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('General', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+						
+					}),500);
+					return d;
+				}
+			},
+			{
+				name: DataList + " Verification2",
+				timeout: 10000,
+				runTest: function(){
+					var d = new doh.Deferred();
+					setTimeout(d.getTestCallback(function(){
+
+						switchTo(store2);
+						var demoWidget = registry.byId("dojox_mobile_ListItem_13");
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual(null, demoWidget.iconNode);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('Grape', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+
+					}),2500);
+					return d;
+				}
+			},
+			{
+				name: DataList + " Verification3",
+				timeout: 10000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+
+						add1();
+						add1();
+						add1();
+						var demoWidget = registry.byId("dojox_mobile_ListItem_19");
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('New Item 1', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						delete1();
+						demoWidget = registry.byId("dojox_mobile_ListItem_21");
+						runner.assertTrue(!demoWidget);
+
+						demoWidget = registry.byId("dojox_mobile_ListItem_20");
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('New Item 2', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						modify1();
+						runner.assertEqual(modif_counter+' changes', demoWidget.get("rightText"), "modify store item");
+					}),1500);
+					return d;
+				}
+			},
+			{
+				name: DataList + " Verification4 (1.8 compat mode)",
+				timeout: 10000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+
+						// Check compatibility with old-style widgets that define only an onUpdate method and no onAdd method
+						// (like in Dojo Mobile 1.8). In that case onUpdate is called instead of onAdd, and put() is not handled.
+						var listWidget = registry.byId("list");
+						listWidget.onAdd = undefined;
+						listWidget.onUpdate = function(/*Object*/item, /*Number*/insertedInto){
+							// summary:
+							//		Adds a new item or updates an existing item.
+							if(insertedInto === this.getChildren().length){
+								this.addChild(this.createListItem(item)); // add a new ListItem
+							}else{
+								this.getChildren()[insertedInto].set(item); // update the existing ListItem
+							}
+						};
+
+						add1();
+						add1();
+						add1();
+						var demoWidget = registry.byId("dojox_mobile_ListItem_22");
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('New Item 3', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						delete1();
+						demoWidget = registry.byId("dojox_mobile_ListItem_24");
+						runner.assertTrue(!demoWidget);
+
+						demoWidget = registry.byId("dojox_mobile_ListItem_23");
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('New Item 4', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						modify1();
+						runner.assertEqual("", demoWidget.get("rightText"), "modify store item (noop in compat mode)");
+					}),1500);
+					return d;
+				}
+			}
+		]);
+		runner.run();
+	});
+});
diff --git a/dojox/mobile/tests/doh/edgetoedgestorelist/module.js b/dojox/mobile/tests/doh/edgetoedgestorelist/module.js
new file mode 100644
index 0000000..5ef4ff8
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgestorelist/module.js
@@ -0,0 +1,9 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.EdgeToEdgeStoreList", require.toUrl("./EdgeToEdgeStoreList.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.EdgeToEdgeStoreList", require.toUrl("./EdgeToEdgeStoreList_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.EdgeToEdgeStoreList", require.toUrl("./EdgeToEdgeStoreList-itemMap-updates.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/edgetoedgestorelist/runTests.html b/dojox/mobile/tests/doh/edgetoedgestorelist/runTests.html
new file mode 100644
index 0000000..d6f6cfe
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgestorelist/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.edgetoedgestorelist.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/edgetoedgestorelist/settings2.json b/dojox/mobile/tests/doh/edgetoedgestorelist/settings2.json
new file mode 100644
index 0000000..71b3484
--- /dev/null
+++ b/dojox/mobile/tests/doh/edgetoedgestorelist/settings2.json
@@ -0,0 +1,12 @@
+[
+    { "label" : "Wi-Fi",                        "icon" : "../../images/i-icon-1.png",   "moveTo": "wifi"                              },
+    { "label" : "Brightness & Wallpaper",       "icon" : "../../images/i-icon-2.png",   "moveTo": "bright"                            },
+    { "label" : "Picture Frame",                "icon" : "../../images/i-icon-3.png",   "moveTo": "picture"                           },
+    { "label" : "General",                      "icon" : "../../images/i-icon-4.png",   "moveTo": "general",  "selected": "true"      },
+    { "label" : "Mail, Contacts, Calendars",    "icon" : "../../images/i-icon-5.png",   "moveTo": "wifi"                              },
+    { "label" : "Safari",                       "icon" : "../../images/i-icon-6.png",   "moveTo": "bright"                            },
+    { "label" : "iPod",                         "icon" : "../../images/i-icon-7.png",   "moveTo": "picture"                           },
+    { "label" : "Video",                        "icon" : "../../images/i-icon-8.png",   "moveTo": "general"                           },
+    { "label" : "Photos",                       "icon" : "../../images/i-icon-9.png",   "moveTo": "wifi"                              },
+    { "label" : "Store",                        "icon" : "../../images/i-icon-10.png",  "moveTo": "bright"                            }
+ ]
diff --git a/dojox/mobile/tests/doh/expandingtextarea/ExpandingTextAreaTests.html b/dojox/mobile/tests/doh/expandingtextarea/ExpandingTextAreaTests.html
new file mode 100644
index 0000000..d7bf1ed
--- /dev/null
+++ b/dojox/mobile/tests/doh/expandingtextarea/ExpandingTextAreaTests.html
@@ -0,0 +1,158 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>ExpandingTextArea Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	var TEXTAREA_ROWS = 3;
+	var TEXTAREA_COLS = 20;
+	var TEXTAREA_INNERHTML = "ExpandingTextArea";
+	var TEXTAREA_NEW_VALUE = "This is mobile ExpandingTextArea.\nThis text area is automaticaly Expanding.\nHello dojox.mobile";
+	var WIDGET_CLASSNAME1 = "mblTextArea";
+	var WIDGET_CLASSNAME2 = "mblExpandingTextArea";
+	var WIDGET_HEIGHT1 = "16px";
+	var WIDGET_HEIGHT1_FF = "33px";
+	var WIDGET_HEIGHT1_FF19 = "37px";
+//	var WIDGET_HEIGHT1_IE6 = "24px";
+	var WIDGET_HEIGHT1_IE10 = "24px"; // IE10
+//	var WIDGET_HEIGHT1_IE8 = "26px";
+	var WIDGET_HEIGHT1_IE = "25px"; // IE9
+	var WIDGET_OFFSETHEIGHT1 = 26;
+	var WIDGET_OFFSETHEIGHT1_FF = 43;
+	var WIDGET_OFFSETHEIGHT1_FF19 = 47;
+	var WIDGET_OFFSETHEIGHT1_IE = 35; // IE9
+	var WIDGET_OFFSETHEIGHT1_IE10 = 28; // IE10
+	var WIDGET_OFFSETHEIGHT2 = 90;
+//	var WIDGET_OFFSETHEIGHT2_IE8 = "133";
+	var WIDGET_OFFSETHEIGHT2_IE = "125"; // IE9
+	var WIDGET_OFFSETHEIGHT2_IE10 = "67";
+
+	require([
+		"dojo/_base/connect",
+		"dojo/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/dom-class", // dojo.hasClass
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/ExpandingTextArea",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(connect, has, domConst, domClass, ready, registry, runner, ExpandingTextArea){
+		function _createExpandingTextAreaDeclaratively(widgetId) {
+			return registry.byId(widgetId);
+		}
+		function _createExpandingTextAreaProgrammatically(placeHolderId, widgetId, rows, cols, innerHTML){
+			var r = new ExpandingTextArea({id:widgetId, rows:rows, cols:cols, innerHTML:innerHTML});
+			runner.assertNotEqual(null, r);
+			domConst.place(r.domNode, placeHolderId, "replace");
+			r.startup();
+			
+			return r;
+		}
+		function _createExpandingTextAreaProgrammaticallyWithSourceNodeReference(widgetId){
+			// Create IconContainer
+			var r = new ExpandingTextArea({}, widgetId);
+
+			r.startup();
+			return r;
+		}
+		function _assertCorrectExpandingTextArea(widget, styleHeight, offsetHeight1, offsetHeight2){
+			if(styleHeight < 0){
+				return; // Skip for IE<9 (a negative styleHeight is the convention we use for skipping) 
+			}
+			runner.assertNotEqual(null, widget, "IconItem: Did not instantiate.");
+			runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + widget.domNode.id);
+			runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " id=" + widget.domNode.id);
+			runner.assertEqual(styleHeight, widget.domNode.style.height, "style.height id=" + widget.domNode.id);
+			runner.assertEqual(offsetHeight1, widget.domNode.offsetHeight, "offsetHeight1 id=" + widget.domNode.id);
+			runner.assertEqual(TEXTAREA_INNERHTML, widget.textbox.value, 'textbox value');
+			runner.assertEqual(TEXTAREA_INNERHTML, widget.get('value'), 'widget value');
+			widget.set('value', TEXTAREA_NEW_VALUE);
+			runner.assertEqual(offsetHeight2, widget.domNode.offsetHeight, "offsetHeight2 id=" + widget.domNode.id);
+			runner.assertEqual(TEXTAREA_NEW_VALUE, widget.textbox.value.replace(/\r\n/g, "\n"), 'textbox new value');
+			runner.assertEqual(TEXTAREA_NEW_VALUE, widget.get('value').replace(/\r\n/g, "\n"), 'widget new value');
+		}
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		}
+		ready(function(){
+			var styleHeight =  has("ie") ? (has("ie") >= 10 ? WIDGET_HEIGHT1_IE10 : WIDGET_HEIGHT1_IE) : has("ff") ?
+				(has("ff") >= 19 ? WIDGET_HEIGHT1_FF19 : WIDGET_HEIGHT1_FF) : WIDGET_HEIGHT1;
+			var offsetHeight1 = has("ie") ? (has("ie") >= 10 ? WIDGET_OFFSETHEIGHT1_IE10 : WIDGET_OFFSETHEIGHT1_IE) : has("ff") ?
+				(has("ff") >= 19 ? WIDGET_OFFSETHEIGHT1_FF19 : WIDGET_OFFSETHEIGHT1_FF) : WIDGET_OFFSETHEIGHT1;
+			var offsetHeight2 = has("ie") ? (has("ie") >= 10 ? WIDGET_OFFSETHEIGHT2_IE10 : WIDGET_OFFSETHEIGHT2_IE) :WIDGET_OFFSETHEIGHT2;
+			// Skip the checks for IE<9
+			if(has("ie") < 9){
+				styleHeight = -1; // negative value as convention for skipping tests
+			} 
+			runner.register("dojox.mobile.test.doh.ExpandingTextArea", [
+				{
+					name: "ExpandingTextArea Verification1",
+					timeout: 4000,
+					runTest: function(){
+						var widget1 = _createExpandingTextAreaDeclaratively("dojox_mobile_ExpandingTextArea_0");
+						var widget2 = _createExpandingTextAreaProgrammatically("view1-ExpandingTextArea2place", "view1-ExpandingTextArea2", TEXTAREA_ROWS, TEXTAREA_COLS, TEXTAREA_INNERHTML);
+						var widget3 = _createExpandingTextAreaProgrammaticallyWithSourceNodeReference("view1-ExpandingTextArea3");
+
+						var d = new runner.Deferred();
+						setTimeout(d.getTestCallback(function(){
+							var widget1 = registry.byId("dojox_mobile_ExpandingTextArea_0");
+							var widget2 = registry.byId("view1-ExpandingTextArea2");
+							var widget3 = registry.byId("view1-ExpandingTextArea3");
+							_assertCorrectExpandingTextArea(widget1, styleHeight, offsetHeight1, offsetHeight2);
+							_assertCorrectExpandingTextArea(widget2, styleHeight, offsetHeight1, offsetHeight2);
+							_assertCorrectExpandingTextArea(widget3, styleHeight, offsetHeight1, offsetHeight2);
+						}), 2000);
+						return d;
+					}
+				},
+				{
+					name: "ExpandingTextArea Verification2",
+					timeout: 4000,
+					runTest: function(){
+						var widget1 = _createExpandingTextAreaDeclaratively("dojox_mobile_ExpandingTextArea_1");
+						var widget2 = _createExpandingTextAreaProgrammatically("view2-ExpandingTextArea2place", "view2-ExpandingTextArea2", TEXTAREA_ROWS, TEXTAREA_COLS, TEXTAREA_INNERHTML);
+						var widget3 = _createExpandingTextAreaProgrammaticallyWithSourceNodeReference("view2-ExpandingTextArea3");
+
+						_showView2();
+						var d = new runner.Deferred();
+						setTimeout(d.getTestCallback(function(){
+							var widget1 = registry.byId("dojox_mobile_ExpandingTextArea_1");
+							var widget2 = registry.byId("view2-ExpandingTextArea2");
+							var widget3 = registry.byId("view2-ExpandingTextArea3");
+							_assertCorrectExpandingTextArea(widget1, styleHeight, offsetHeight1, offsetHeight2);
+							_assertCorrectExpandingTextArea(widget2, styleHeight, offsetHeight1, offsetHeight2);
+							_assertCorrectExpandingTextArea(widget3, styleHeight, offsetHeight1, offsetHeight2);
+						}), 2000);
+						return d;
+					}
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<textarea data-dojo-type="dojox.mobile.ExpandingTextArea" rows="3" cols="20">ExpandingTextArea</textarea><br>
+		<div id="view1-ExpandingTextArea2place"></div><br>
+		<textarea id="view1-ExpandingTextArea3" rows="3" cols="20">ExpandingTextArea</textarea><br>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<textarea data-dojo-type="dojox.mobile.ExpandingTextArea" rows="3" cols="20">ExpandingTextArea</textarea><br>
+		<div id="view2-ExpandingTextArea2place"></div><br>
+		<textarea id="view2-ExpandingTextArea3" rows="3" cols="20">ExpandingTextArea</textarea><br>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/expandingtextarea/module.js b/dojox/mobile/tests/doh/expandingtextarea/module.js
new file mode 100644
index 0000000..56256a2
--- /dev/null
+++ b/dojox/mobile/tests/doh/expandingtextarea/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.ExpandingTextArea", require.toUrl("./ExpandingTextAreaTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/expandingtextarea/runTests.html b/dojox/mobile/tests/doh/expandingtextarea/runTests.html
new file mode 100644
index 0000000..fccfd88
--- /dev/null
+++ b/dojox/mobile/tests/doh/expandingtextarea/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.expandingtextarea.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/filteredlistmixin/FilteredListTests.html b/dojox/mobile/tests/doh/filteredlistmixin/FilteredListTests.html
new file mode 100644
index 0000000..cd3a98c
--- /dev/null
+++ b/dojox/mobile/tests/doh/filteredlistmixin/FilteredListTests.html
@@ -0,0 +1,374 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Filtered List Tests</title>
+
+	<!-- DOH test for the filtering capabilities added to all list widgets by dojox/mobile/FilteredListMixin -->
+	
+	<script type="text/javascript" src="../../../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/dom-construct",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"doh/runner",
+			"dojo/store/Memory",
+			"dojo/data/ItemFileReadStore",
+			"dojox/mobile/EdgeToEdgeStoreList",
+			"dojox/mobile/EdgeToEdgeDataList",
+			"dojox/mobile/FilteredListMixin",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/SearchBox"
+		], function(declare, domConstruct, domClass, ready, registry, runner, 
+					Memory, ItemFileReadStore, EdgeToEdgeStoreList, EdgeToEdgeDataList, 
+					FilteredListMixin){
+			
+			var EDGE_TO_EDGE_LIST_FILTER_BOX_CLASSNAME = "mblFilteredEdgeToEdgeListSearchBox";
+			var ROUND_RECT_LIST_FILTER_BOX_CLASSNAME = "mblFilteredRoundRectListSearchBox";
+			var CUSTOM_FILTER_BOX_CLASSNAME = "myCustomClass";
+			
+			var static_data = { 
+				items: [ 
+					{label: "Alabama"},
+					{label: "Alaska"},
+					{label: "American Samoa"},
+					{label: "Arizona"},
+					{label: "Arkansas"},
+					{label: "Armed Forces Europe"},
+					{label: "Armed Forces Pacific"},
+					{label: "Armed Forces the Americas"},
+					{label: "California"},
+					{label: "Colorado"},
+					{label: "Connecticut"},
+					{label: "Delaware"},
+					{label: "District of Columbia"},
+					{label: "Federated States of Micronesia"},
+					{label: "Florida"},
+					{label: "Georgia"},
+					{label: "Guam"},
+					{label: "Hawaii"},
+					{label: "Idaho"},
+					{label: "Illinois"},
+					{label: "Indiana"},
+					{label: "Iowa"},
+					{label: "Kansas"},
+					{label: "Kentucky"},
+					{label: "Louisiana"},
+					{label: "Maine"},
+					{label: "Marshall Islands"},
+					{label: "Maryland"},
+					{label: "Massachusetts"},
+					{label: "Michigan"},
+					{label: "Minnesota"},
+					{label: "Mississippi"},
+					{label: "Missouri"},
+					{label: "Montana"},
+					{label: "Nebraska"},
+					{label: "Nevada"},
+					{label: "New Hampshire"},
+					{label: "New Jersey"},
+					{label: "New Mexico"},
+					{label: "New York"},
+					{label: "North Carolina"},
+					{label: "North Dakota"},
+					{label: "Northern Mariana Islands"},
+					{label: "Ohio"},
+					{label: "Oklahoma"},
+					{label: "Oregon"},
+					{label: "Pennsylvania"},
+					{label: "Puerto Rico"},
+					{label: "Rhode Island"},
+					{label: "South Carolina"},
+					{label: "South Dakota"},
+					{label: "Tennessee"},
+					{label: "Texas"},
+					{label: "Utah"},
+					{label: "Vermont"},
+					{label: "Virgin Islands, U.S."},
+					{label: "Virginia"},
+					{label: "Washington"},
+					{label: "West Virginia"},
+					{label: "Wisconsin"},
+					{label: "Wyoming"}
+				]
+			};
+			
+			// store for the dojox/mobile/EdgeToEdgeStoreList
+			store = new Memory({idProperty:"label", data: static_data});
+			
+			// dojo/data store for dojox/mobile/EdgeToEdgeDataList
+			dataStore = new ItemFileReadStore({data: static_data});
+			
+			ready(function(){
+				doh.register("dojox.mobile.test.doh.filteredlistmixin", [
+					function testInView1(){
+						// EdgeToEdgeStoreList filtered using FilteredListMixin.
+						// Use-case: markup; SearchBox and ScrollableView created automatically by the mixin.
+						var list = registry.byId("list1");
+						var filterBox = list.getFilterBox();
+						runner.assertNotEqual(null, filterBox);
+						runner.assertNotEqual(null, list.getScrollableView());
+						// Check that the class specified by EdgeToEdgeList.filterBoxClass is added by the
+						// mixin to the SearchBox:
+						runner.assertTrue(domClass.contains(filterBox.domNode.parentNode, EDGE_TO_EDGE_LIST_FILTER_BOX_CLASSNAME),
+							EDGE_TO_EDGE_LIST_FILTER_BOX_CLASSNAME + " id=" + filterBox.id + 
+							" value=" + filterBox.domNode.className);
+						// Check that the filtering actually works
+						var n = list.getChildren().length;
+						runner.assertEqual(61, n);
+						filterBox.on("search", function(results, query, options){
+							runner.assertEqual(2, list.getChildren().length);
+						});
+						filterBox._startSearch("Co"); // Matches 2 items (Colorado and Connecticut)
+					},
+					function testInView2(){
+						// EdgeToEdgeStoreList filtered using FilteredListMixin.
+						// Use-case: markup; SearchBox and ScrollableView are provided.
+						var list = registry.byId("list2");
+						var filterBox = list.getFilterBox();
+						runner.assertNotEqual(null, filterBox);
+						// Check that the class specified by the user for the SearchBox is preserved:
+						runner.assertTrue(domClass.contains(filterBox.domNode, CUSTOM_FILTER_BOX_CLASSNAME),
+							CUSTOM_FILTER_BOX_CLASSNAME + " id=" + filterBox.id + 
+							" value=" + filterBox.domNode.className);
+						// Check that the filtering actually works
+						var n = list.getChildren().length;
+						runner.assertEqual(61, n);
+						filterBox.set("searchDelay", 0); // to help testing
+						var expectedNumberOfMatchingItems;
+						runner.assertEqual("Search", filterBox.placeHolder);
+						filterBox.on("search", function(results, query, options){
+							runner.assertEqual(expectedNumberOfMatchingItems, list.getChildren().length);
+						});
+						expectedNumberOfMatchingItems = 2;
+						filterBox._startSearch("Co"); // Matches 2 items (Colorado and Connecticut)
+						
+						// Test changing parameters of the SearchBox
+						filterBox.set("queryExpr", "*${0}*"); // switched from "starts with..." to "contains"
+						// wait 500 ms to give time to the first asynchronous search, otherwise the 
+						// second search cancels the first one
+						setTimeout(function(){
+							expectedNumberOfMatchingItems = 12;
+							filterBox._startSearch("or"); // Matches 12 items
+						}, 500); 
+					},
+					function testInView3(){
+						// EdgeToEdgeStoreList filtered using FilteredListMixin.
+						// Use-case: markup; SearchBox and ScrollableView are provided; SearchBox with custom placeHolder.
+						var list = registry.byId("list3");
+						var filterBox = list.getFilterBox();
+						runner.assertNotEqual(null, filterBox);
+						// Check that the class specified by the user for the SearchBox is preserved:
+						runner.assertTrue(domClass.contains(filterBox.domNode, CUSTOM_FILTER_BOX_CLASSNAME),
+							CUSTOM_FILTER_BOX_CLASSNAME + " id=" + filterBox.id + 
+							" value=" + filterBox.domNode.className);
+						// Check that the filtering actually works
+						var n = list.getChildren().length;
+						runner.assertEqual(61, n);
+						// Check that the placeHolder set on the provided SearchBox
+						// takes precedence over the placeHolder set on the filtered list.
+						runner.assertEqual("CustomPlaceHolder", filterBox.placeHolder);
+					},
+					function testInView4(){
+						// EdgeToEdgeDataList filtered using FilteredListMixin.
+						// Use-case: markup; SearchBox and ScrollableView are provided.
+						var list = registry.byId("list4");
+						var filterBox = list.getFilterBox();
+						runner.assertNotEqual(null, filterBox);
+						// Check that the class specified by the user for the SearchBox is preserved:
+						runner.assertTrue(domClass.contains(filterBox.domNode, CUSTOM_FILTER_BOX_CLASSNAME),
+							CUSTOM_FILTER_BOX_CLASSNAME + " id=" + filterBox.id + 
+							" value=" + filterBox.domNode.className);
+						// Check that the filtering actually works
+						var n = list.getChildren().length;
+						runner.assertEqual(61, n);
+						filterBox.on("search", function(results, query, options){
+							runner.assertEqual(2, list.getChildren().length);
+						});
+						filterBox._startSearch("Co"); // Matches 2 items (Colorado and Connecticut)
+					},
+					function testInView5(){
+						// EdgeToEdgeStoreList filtered using FilteredListMixin.
+						// Use-case: programmatic; SearchBox and ScrollableView created automatically by the mixin.
+						var list = new declare([EdgeToEdgeStoreList, FilteredListMixin])(
+								{placeHolder: 'Search', store: store}, "list5");
+						list.startup();
+						var filterBox = list.getFilterBox();
+						runner.assertNotEqual(null, filterBox);
+						runner.assertNotEqual(null, list.getScrollableView());
+						// Check that the class specified by EdgeToEdgeList.filterBoxClass is added by the
+						// mixin to the SearchBox:
+						runner.assertTrue(domClass.contains(filterBox.domNode.parentNode, EDGE_TO_EDGE_LIST_FILTER_BOX_CLASSNAME),
+							EDGE_TO_EDGE_LIST_FILTER_BOX_CLASSNAME + " id=" + filterBox.id + 
+							" value=" + filterBox.domNode.className);
+						// Check that the filtering actually works
+						var n = list.getChildren().length;
+						runner.assertEqual(61, n);
+						filterBox.on("search", function(results, query, options){
+							runner.assertEqual(2, list.getChildren().length);
+						});
+						filterBox._startSearch("Co"); // Matches 2 items (Colorado and Connecticut)
+					},
+					function testInView6(){
+						// RoundRectList filtered using FilteredListMixin.
+						// Use-case: markup; SearchBox and ScrollableView created automatically by the mixin.
+						var list = registry.byId("list6");
+						var filterBox = list.getFilterBox();
+						runner.assertNotEqual(null, filterBox);
+						runner.assertNotEqual(null, list.getScrollableView());
+						// Check that the class specified by RoundReectList.filterBoxClass is added by the
+						// mixin to the SearchBox:
+						runner.assertTrue(domClass.contains(filterBox.domNode.parentNode, ROUND_RECT_LIST_FILTER_BOX_CLASSNAME),
+							ROUND_RECT_LIST_FILTER_BOX_CLASSNAME + " id=" + filterBox.id + 
+							" value=" + filterBox.domNode.className);
+						// Check that the filtering actually works
+						var n = list.getChildren().length;
+						runner.assertEqual(61, n);
+						filterBox.on("search", function(results, query, options){
+							runner.assertEqual(2, list.getChildren().length);
+						});
+						filterBox._startSearch("Co"); // Matches 2 items (Colorado and Connecticut)
+					}
+				]);
+				runner.run();
+			});
+		})
+	</script>
+
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox/mobile/View">
+		<!-- EdgeToEdgeStoreList filtered using FilteredListMixin. -->
+		<!-- Use-case: markup; SearchBox and ScrollableView created automatically by the mixin. -->
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" id="list1"
+			data-dojo-mixins="dojox/mobile/FilteredListMixin"
+			data-dojo-props="placeHolder: 'Search', store: store"></ul>
+	</div>
+	<div id="view2" data-dojo-type="dojox/mobile/View">
+		<!-- EdgeToEdgeStoreList filtered using FilteredListMixin. -->
+		<!-- Use-case: markup; SearchBox and ScrollableView are provided. -->
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered EdgeToEdgeStoreList</h1>
+		<input data-dojo-type="dojox/mobile/SearchBox" type="search" id="filterBox2"
+			class="myCustomClass mblFilteredEdgeToEdgeListSearchBox">
+		<div data-dojo-type="dojox/mobile/ScrollableView">
+			<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" id="list2"
+				data-dojo-mixins="dojox/mobile/FilteredListMixin"
+				data-dojo-props="filterBoxRef: 'filterBox2', placeHolder: 'Search', store: store"></ul>
+		</div>
+	</div>
+	<div id="view3" data-dojo-type="dojox/mobile/View">
+		<!-- EdgeToEdgeStoreList filtered using FilteredListMixin. -->
+		<!-- Use-case: markup; SearchBox and ScrollableView are provided; SearchBox with custom placeHolder. -->
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered EdgeToEdgeStoreList</h1>
+		<input data-dojo-type="dojox/mobile/SearchBox" type="search" id="filterBox3"
+			data-dojo-props="filterBoxRef: 'filterBox', placeHolder: 'CustomPlaceHolder', store: store"
+			class="myCustomClass mblFilteredEdgeToEdgeListSearchBox">
+		<div data-dojo-type="dojox/mobile/ScrollableView">
+			<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" id="list3"
+				data-dojo-mixins="dojox/mobile/FilteredListMixin"
+				data-dojo-props="filterBoxRef: 'filterBox3', placeHolder: 'Search', store: store"></ul>
+		</div>
+	</div>
+	<div id="view4" data-dojo-type="dojox/mobile/View">
+		<!-- EdgeToEdgeDataList filtered using FilteredListMixin. -->
+		<!-- Use-case: markup; SearchBox and ScrollableView are provided. -->
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered EdgeToEdgeDataList</h1>
+		<input data-dojo-type="dojox/mobile/SearchBox" type="search" id="filterBox4"
+			class="myCustomClass mblFilteredEdgeToEdgeListSearchBox">
+		<div data-dojo-type="dojox/mobile/ScrollableView">
+			<ul data-dojo-type="dojox/mobile/EdgeToEdgeDataList" id="list4" 
+				data-dojo-mixins="dojox/mobile/FilteredListMixin"
+				data-dojo-props="filterBoxRef: 'filterBox4', placeHolder: 'Search', store: dataStore"></ul>
+		</div>
+	</div>
+	<div id="view5" data-dojo-type="dojox/mobile/View">
+		<!-- EdgeToEdgeStoreList filtered using FilteredListMixin. -->
+		<!-- Use-case: programmatic; SearchBox and ScrollableView created automatically by the mixin. -->
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered EdgeToEdgeStoreList</h1>
+		<div id="list5" style="height:100%"></div>
+	</div>
+	<div id="view6" data-dojo-type="dojox/mobile/View">
+		<!-- RoundRectList filtered using FilteredListMixin. -->
+		<!-- Use-case: markup; SearchBox and ScrollableView created automatically by the mixin. -->
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered RoundRectList</h1>
+		<ul id="list6" data-dojo-type="dojox/mobile/RoundRectList"
+			data-dojo-mixins="dojox/mobile/FilteredListMixin"
+			data-dojo-props="placeHolder: 'Search'">
+			<li data-dojo-type="dojox/mobile/ListItem">Alabama</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Alaska</li>
+			<li data-dojo-type="dojox/mobile/ListItem">American Samoa</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Arizona</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Arkansas</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Armed Forces Europe</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Armed Forces Pacific</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Armed Forces the Americas</li>
+			<li data-dojo-type="dojox/mobile/ListItem">California</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Colorado</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Connecticut</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Delaware</li>
+			<li data-dojo-type="dojox/mobile/ListItem">District of Columbia</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Federated States of Micronesia</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Florida</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Georgia</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Guam</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Hawaii</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Idaho</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Illinois</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Indiana</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Iowa</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Kansas</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Kentucky</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Louisiana</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Maine</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Marshall Islands</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Maryland</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Massachusetts</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Michigan</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Minnesota</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Mississippi</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Missouri</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Montana</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Nebraska</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Nevada</li>
+			<li data-dojo-type="dojox/mobile/ListItem">New Hampshire</li>
+			<li data-dojo-type="dojox/mobile/ListItem">New Jersey</li>
+			<li data-dojo-type="dojox/mobile/ListItem">New Mexico</li>
+			<li data-dojo-type="dojox/mobile/ListItem">New York</li>
+			<li data-dojo-type="dojox/mobile/ListItem">North Carolina</li>
+			<li data-dojo-type="dojox/mobile/ListItem">North Dakota</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Northern Mariana Islands</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Ohio</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Oklahoma</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Oregon</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Pennsylvania</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Puerto Rico</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Rhode Island</li>
+			<li data-dojo-type="dojox/mobile/ListItem">South Carolina</li>
+			<li data-dojo-type="dojox/mobile/ListItem">South Dakota</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Tennessee</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Texas</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Utah</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Vermont</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Virgin Islands, U.S.</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Virginia</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Washington</li>
+			<li data-dojo-type="dojox/mobile/ListItem">West Virginia</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Wisconsin</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Wyoming</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/filteredlistmixin/module.js b/dojox/mobile/tests/doh/filteredlistmixin/module.js
new file mode 100644
index 0000000..8cfe01f
--- /dev/null
+++ b/dojox/mobile/tests/doh/filteredlistmixin/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.filteredlistmixin", require.toUrl("./FilteredListTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/filteredlistmixin/runTests.html b/dojox/mobile/tests/doh/filteredlistmixin/runTests.html
new file mode 100644
index 0000000..d09d843
--- /dev/null
+++ b/dojox/mobile/tests/doh/filteredlistmixin/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.filteredlistmixin.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/fixedbars/CustomFixedBarsTests.html b/dojox/mobile/tests/doh/fixedbars/CustomFixedBarsTests.html
new file mode 100644
index 0000000..5b6740c
--- /dev/null
+++ b/dojox/mobile/tests/doh/fixedbars/CustomFixedBarsTests.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+	<html>
+	        <head>
+	        <title>View Custom Fixed Bars</title>
+	        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	        <meta name="viewport"
+	                content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+	        <meta name="apple-mobile-web-app-capable" content="yes" />
+	        <script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, async:true"></script>
+	        <script type="text/javascript" charset="utf-8">
+	                require(["dojo/ready",
+	                         "dojo/dom",
+	                         "doh/runner",
+	                         "dojox/mobile/parser",
+	                         "dojox/mobile",
+	                         "dojox/mobile/deviceTheme",
+	                         "dojox/mobile/ScrollableView"], function(ready, dom, runner, domGeometry) {
+	                	
+	    				ready(function(){
+	     					runner.register("dojox.mobile.test.doh.fixedbars.CustomFixedBarsTests", [
+	    						{
+	    							name: "Verify ticket #16671 is fixed",
+	    							timeout: 10000,
+	    							setUp: function() {
+	    								this.data = {runner: runner, topBar: dom.byId("topBar"), bottomBar: dom.byId("bottomBar")};
+	    							},
+	    							runTest: function(){
+	    								var d = new runner.Deferred();
+	    								setTimeout(d.getTestCallback(function(){
+	    									this.fixture.data.runner.assertEqual(0, this.fixture.data.topBar.offsetTop);
+	    									this.fixture.data.runner.assertTrue(this.fixture.data.bottomBar.offsetTop > this.fixture.data.topBar.offsetHeight, "Bottom bar has not the expected position");
+	    								}), 2000);
+	    								return d;
+	    							}
+	    						}]);
+	    					runner.run();
+	    				});
+	                });   
+	        </script>
+	        </head>
+	        <body style="visibility:hidden;">
+
+	        		<!-- Scrollable View -->
+ 	                <div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+ 	                	<div id="topBar" fixed="top" style="height: 55px; background: yellow;">Custom header for ScrollView</div>
+	                	<div id= "bottomBar" fixed="bottom" style="height: 25px; background: yellow;">Custom footer for ScrollView</div>
+ 	                </div>
+
+	        </body>
+	</html>
diff --git a/dojox/mobile/tests/doh/fixedbars/DeclaredFixedFooterTests.html b/dojox/mobile/tests/doh/fixedbars/DeclaredFixedFooterTests.html
new file mode 100644
index 0000000..77cd95f
--- /dev/null
+++ b/dojox/mobile/tests/doh/fixedbars/DeclaredFixedFooterTests.html
@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Test that TabBar is at the bottom of the viewport on each view</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript" src="../TestUtil.js"></script>
+	<script type="text/javascript">
+		require([
+				 "doh/runner",	//doh functions
+				 "dojo/ready",
+                 "dojo/dom",
+                 "dojo/dom-style",
+                 "dojo/window",
+                 "dojo/_base/window",
+                 "dojox/mobile/sniff",
+		         "dojox/mobile/parser",
+		         "dojox/mobile",
+		         "dojox/mobile/compat",
+		         "dojox/mobile/ScrollableView",
+		         "dojox/mobile/TabBar"
+		     ], function(runner, ready, dom, domStyle, win, winUtils, has){
+				ready(function(){
+					var tabBar = dom.byId("thetabbar");
+					var tabHome1 = dom.byId("tabHome1");
+					var tabHome2 = dom.byId("tabHome2");
+					var statusBar = dom.byId("statusbar");
+					var tabEvents = dom.byId("tabEvents");
+					// there is 8px of extra padding -in the body) with the WindowsPhone theme
+					var extraPadding = 0;
+					if (has("ie") && has("ie")>=10){
+						extraPadding = 8;
+					}
+					doh.register("dojox.mobile.test.doh.fixedbars.DeclaredFixedFooterTests", [
+   						{
+ 							name: "ticket #17006: verify tabbar is correct on view Home1",
+ 							timeout: 10000,
+ 							runTest: function(){
+ 								var d = new runner.Deferred();
+ 								setTimeout(d.getTestCallback(function(){
+ 									var viewport = win.getBox();
+ 									runner.assertEqual(tabHome1.offsetHeight, tabBar.offsetTop, "tabbar should be right below tabHome1");
+ 									runner.assertEqual(viewport.h, tabBar.offsetTop + tabBar.offsetHeight + extraPadding, "tabbar should be at the bottom of the viewport when tabHome1 is displayed");
+ 								}), 1000);
+ 								return d;
+ 							}
+ 						},{
+ 							name: "ticket #17006: verify tabbar is correct on view Home2",
+ 							timeout: 10000,
+ 							runTest: function(){
+ 								var d = new runner.Deferred();
+								fireOnMouseDown("mvToHome2");
+								fireOnMouseUp("mvToHome2");
+ 								setTimeout(d.getTestCallback(function(){
+ 									var viewport = win.getBox();
+ 									runner.assertEqual(tabHome2.offsetHeight, tabBar.offsetTop, "tabbar should be right below tabHome2");
+ 									runner.assertEqual(viewport.h, tabBar.offsetTop + tabBar.offsetHeight + extraPadding, "tabbar should be at the bottom of the viewport when tabHome2 is displayed");
+ 									runner.assertEqual(tabHome2.offsetHeight, statusBar.offsetTop + statusBar.offsetHeight, "statusbar should be at the bottom of tabHome2");
+ 								}), 1000);
+ 								return d;
+ 							}
+ 						},{
+ 							name: "ticket #17006: verify tabbar is correct on view Events",
+ 							timeout: 10000,
+ 							runTest: function(){
+ 								var d = new runner.Deferred();
+								fireOnMouseDown("mvToTabEvents");
+								fireOnMouseUp("mvToTabEvents");
+ 								setTimeout(d.getTestCallback(function(){
+ 									var viewport = win.getBox();
+ 									runner.assertEqual(tabEvents.offsetHeight, tabBar.offsetTop, "tabbar should be right below tabEvents");
+ 									runner.assertEqual(viewport.h, tabBar.offsetTop + tabBar.offsetHeight + extraPadding, "tabbar should be at the bottom of the viewport when tabEvents is displayed");
+ 								}), 1000);
+ 								return d;
+ 							}
+ 						}]);
+					runner.run();
+				});
+		});
+	</script>
+
+</head>
+<body style="visibility:hidden;">
+
+    <div id="tabBar" data-dojo-type="dojox.mobile.View">
+    
+        <div id="groups" data-dojo-type="dojox.mobile.View">    
+            <div id="tabHome1" data-dojo-type="dojox.mobile.ScrollableView"
+                selected="true" fixedFooter="thetabbar">
+                <h1 data-dojo-type="dojox.mobile.Heading" fixed="top">Home1</h1>
+                <div data-dojo-type="dojox.mobile.EdgeToEdgeList"
+                    class="edgeToEdgeList">
+                    <li id="mvToHome2" data-dojo-type="dojox.mobile.ListItem" moveTo="tabHome2">To Home2</li>
+                </div>
+            </div>
+            <div id="tabHome2" data-dojo-type="dojox.mobile.ScrollableView" fixedFooter="thetabbar">
+                <h1 data-dojo-type="dojox.mobile.Heading" fixed="top">Home2</h1>
+                <div data-dojo-type="dojox.mobile.EdgeToEdgeList"
+                    class="edgeToEdgeList">
+                    <li data-dojo-type="dojox.mobile.ListItem" moveTo="tabHome1">To Home1</li>
+                </div>
+                <h1 id="statusbar" data-dojo-type="dojox.mobile.Heading" fixed="bottom">status bar</h1>
+            </div>            
+        </div>
+        
+        <div id="tabEvents" data-dojo-type="dojox.mobile.ScrollableView">
+            <h1 data-dojo-type="dojox.mobile.Heading" fixed="top">Events</h1>
+            <div data-dojo-type="dojox.mobile.RoundRect" shadow="true">Events</div>
+        </div>
+
+        <ul id="thetabbar" data-dojo-type="dojox.mobile.TabBar" fixed="bottom"
+            iconBase="../../images/tab-icons.png">
+            <li data-dojo-type="dojox.mobile.TabBarButton" moveTo="groups"
+                iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Home</li>
+            <li id="mvToTabEvents" data-dojo-type="dojox.mobile.TabBarButton" moveTo="tabEvents"
+                iconPos1="0,29,29,29" iconPos2="29,29,29,29">Events</li>
+        </ul>
+    </div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/fixedbars/module.js b/dojox/mobile/tests/doh/fixedbars/module.js
new file mode 100644
index 0000000..b0e7c8f
--- /dev/null
+++ b/dojox/mobile/tests/doh/fixedbars/module.js
@@ -0,0 +1,8 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.FixedBars", require.toUrl("./CustomFixedBarsTests.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.FixedBars", require.toUrl("./DeclaredFixedFooterTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/fixedbars/runTests.html b/dojox/mobile/tests/doh/fixedbars/runTests.html
new file mode 100644
index 0000000..99cc639
--- /dev/null
+++ b/dojox/mobile/tests/doh/fixedbars/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.fixedbars.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests.js b/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests.js
new file mode 100644
index 0000000..18dc025
--- /dev/null
+++ b/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests.js
@@ -0,0 +1,164 @@
+var timeoutInterval = 1500;
+
+var FIXEDSPLITER_CLASSNAME = "mblFixedSplitter";
+var FIXEDSPLITERPANE_CLASSNAME1 = "mblContainer";
+var FIXEDSPLITERPANE_CLASSNAME2 = "mblFixedSplitterV";
+var FIXEDSPLITERPANE_CLASSNAME3 = "mblFixedSplitterH";
+
+var HEIGHT_RATIO1 = 0.2;
+var HEIGHT_RATIO2 = 1 - HEIGHT_RATIO1;
+var WIDTH_RATIO1 = 0.2;
+var WIDTH_RATIO2 = 1 - WIDTH_RATIO1;
+var WIDGET_PROPS = [{style:{width:"100%", height:"100%"}, orientation:"V"},
+					{style:{backgroundColor:"yellow", height:"20%"}},
+					{style:{width:"100%", height:"100%"}, orientation:"H"},
+					{style:{backgroundColor:"pink", width:"20%"}},
+					{style:{backgroundColor:"cyan"}}];
+var WIDGET_INNERHTML = [{},
+						{innerHTML:"pane #1"},
+						{},
+						{innerHTML:"pane #2"},
+						{innerHTML:"pane #3"}];
+var WIDGET_IDS = [{id:"dojox_mobile_FixedSplitter_0"},
+				  {id:"dojox_mobile_Container_0"},
+				  {id:"dojox_mobile_FixedSplitter_1"},
+				  {id:"dojox_mobile_Container_1"},
+				  {id:"dojox_mobile_Container_2"}];
+
+require([
+	"dojo/_base/connect",
+	"dojo/_base/lang", // dojo.mixin
+	"dojo/dom-construct", // dojo.place
+	"dojo/dom-class", // dojo.hasClass
+	"dojo/dom-geometry",
+	"dojo/window", // dojo.window.getBox
+	"dojo/ready", // dojo.ready
+	"dijit/registry",  // dijit.byId
+	"doh/runner",	//doh functions
+	"dojox/mobile/FixedSplitter",
+	"dojox/mobile/Container",
+	"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+], function(connect, lang, domConst, domClass, domGeometry, window, ready, registry, runner, FixedSplitter, Container){
+	function _createFixedSplitterDeclaratively(widgetId) {
+		return registry.byId(widgetId);
+	}
+	function _createFixedSplitterProgrammatically(placeHolderId){
+		// Create FixedSplitter
+		var widget1 = new FixedSplitter(lang.mixin(WIDGET_IDS[0], WIDGET_PROPS[0], WIDGET_INNERHTML[0]));
+		runner.assertNotEqual(null, widget1);
+		domConst.place(widget1.domNode, placeHolderId, "replace");
+		widget1.startup();
+
+		var pane1 = new Container(lang.mixin(WIDGET_IDS[1], WIDGET_PROPS[1], WIDGET_INNERHTML[1]));
+		var widget2 = new FixedSplitter(lang.mixin(WIDGET_IDS[2], WIDGET_PROPS[2], WIDGET_INNERHTML[2]));
+		var pane2 = new Container(lang.mixin(WIDGET_IDS[3], WIDGET_PROPS[3], WIDGET_INNERHTML[3]));
+		var pane3 = new Container(lang.mixin(WIDGET_IDS[4], WIDGET_PROPS[4], WIDGET_INNERHTML[4]));
+
+		widget1.addChild(pane1);
+		widget1.addChild(widget2);
+		widget2.addChild(pane2);
+		widget2.addChild(pane3);
+
+		return widget1;
+	}
+	function _createFixedSplitterProgrammaticallyWithSourceNodeReference(){
+		// Create FixedSplitter
+		var widget1 = new FixedSplitter(WIDGET_PROPS[0], WIDGET_IDS[0].id);
+		runner.assertNotEqual(null, widget1);
+
+		var pane1 = new Container(WIDGET_PROPS[1], WIDGET_IDS[1].id);
+		var widget2 = new FixedSplitter(WIDGET_PROPS[2], WIDGET_IDS[2].id);
+		var pane2 = new Container(WIDGET_PROPS[3], WIDGET_IDS[3].id);
+		var pane3 = new Container(WIDGET_PROPS[4], WIDGET_IDS[4].id);
+		widget1.startup();
+
+		return widget1;
+	}
+	function _assertCorrectFixedSplitter(widget, height, width, className){
+		_assertCorrectFixedSplitterHW(widget, height, width);
+		runner.assertTrue(domClass.contains(widget.domNode, FIXEDSPLITER_CLASSNAME), FIXEDSPLITER_CLASSNAME);
+		if(className){
+			runner.assertTrue(domClass.contains(widget.domNode, className),  "expected: " + className + " but got " + widget.domNode.className);
+		}
+	}
+	function _assertCorrectContainer(widget, height, width, className){
+		_assertCorrectFixedSplitterHW(widget, height, width);
+		runner.assertTrue(domClass.contains(widget.domNode, FIXEDSPLITERPANE_CLASSNAME1), FIXEDSPLITERPANE_CLASSNAME1);
+		if(className){
+			runner.assertTrue(domClass.contains(widget.domNode, className), className);
+		}
+	}
+	function _assertCorrectFixedSplitterHW(widget, height, width){
+		runner.assertNotEqual(null, widget, "FixedSplitter: Did not instantiate.");
+		runner.assertTrue( (height - 2) < widget.domNode.offsetHeight && widget.domNode.offsetHeight < (height + 2), "expected: " +height + "+-2 but got " + widget.domNode.offsetHeight + "height: id = " + widget.domNode.id);
+		runner.assertTrue( (width - 2) < widget.domNode.offsetWidth && widget.domNode.offsetWidth < (width + 2), "expected: " +width + "+-2 but got " + widget.domNode.offsetWidth + "offsetWidth: id = " + widget.domNode.id);
+	}
+	ready(function(){
+		if(WIDGET_PROGRAMMATICALLY === 1){
+			_createFixedSplitterProgrammatically("FixedSplitterPlace");
+		}else if(WIDGET_PROGRAMMATICALLY === 2){
+			_createFixedSplitterProgrammaticallyWithSourceNodeReference();
+		}
+
+		runner.register("dojox.mobile.test.doh.FixedSplitter", [
+			{
+				name: "FixedSplitter Verification",
+				timeout: 4000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var box = window.getBox();
+						
+						var widget1 = registry.byId("dojox_mobile_FixedSplitter_0");
+						var widget2 = registry.byId("dojox_mobile_Container_0");
+						var widget3 = registry.byId("dojox_mobile_FixedSplitter_1");
+						var widget4 = registry.byId("dojox_mobile_Container_1");
+						var widget5 = registry.byId("dojox_mobile_Container_2");
+
+						var box2 = domGeometry.getMarginBox(widget1.domNode);
+
+						runner.assertEqual(box.h, widget2.domNode.offsetHeight + widget5.domNode.offsetHeight);
+						runner.assertEqual(box.w, widget4.domNode.offsetWidth + widget5.domNode.offsetWidth);
+
+						_assertCorrectFixedSplitter(widget1, 0, box2.w);
+						_assertCorrectContainer(widget2, Math.round(box.h * HEIGHT_RATIO1), box.w);
+						_assertCorrectFixedSplitter(widget3, Math.round(box.h * HEIGHT_RATIO2), box.w, FIXEDSPLITERPANE_CLASSNAME3);
+						_assertCorrectContainer(widget4, Math.round(box.h * HEIGHT_RATIO2), Math.round(box.w * WIDTH_RATIO1));
+						_assertCorrectContainer(widget5, Math.round(box.h * HEIGHT_RATIO2), Math.round(box.w * WIDTH_RATIO2));
+					}), timeoutInterval);
+					return d;
+				}
+			},
+			{
+				name: "FixedSplitter Verification 2",
+				timeout: 4000,
+				runTest: function(){
+					var widget = new FixedSplitter();
+					var d = new runner.Deferred();
+					var errorCounter = 0;
+					var errorMsg;
+					// Before the fix of #15064, there used to be an error thrown when destroying 
+					// right after startup(). To test it, we cannot use a simple try-catch, because
+					// this is about an error thrown by the setTimeout function which used to be set 
+					// FixedSplitter's startup(). Hence:
+					window.onerror = function(msg, url, lineNumber){
+						errorCounter++;
+						errorMsg = "After destroy: " + msg + "\nURL: " + url + 
+							"\nLine number: " + lineNumber;
+						console.log(errorMsg);
+					};
+					widget.startup();
+					widget.destroyRecursive(false/*preserveDom*/);
+					// Check that no error has been thrown
+					setTimeout(d.getTestCallback(function(){
+						runner.assertEqual(0, errorCounter, errorMsg);
+					}), 2000); // smaller than the total timeout of the test case
+					
+					return d;
+				}
+			}
+		]);
+		runner.run();
+	});
+})
+
diff --git a/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests1.html b/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests1.html
new file mode 100644
index 0000000..cec66b9
--- /dev/null
+++ b/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests1.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>FixedSplitter Test</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY =0;
+</script>
+<script type="text/javascript" src="FixedSplitterTests.js"></script>
+</head>
+<body>
+	<div dojoType="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" orientation="V">
+		<div dojoType="dojox.mobile.Container" style="background-color:yellow;height:20%">
+			pane #1
+		</div>
+
+		<div dojoType="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" orientation="H">
+			<div dojoType="dojox.mobile.Container" style="background-color:pink;width:20%;">
+				pane #2
+			</div>
+			<div dojoType="dojox.mobile.Container" style="background-color:cyan;">
+				pane #3
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests2.html b/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests2.html
new file mode 100644
index 0000000..b63a8de
--- /dev/null
+++ b/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests2.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>FixedSplitter Test</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY =1;
+</script>
+<script type="text/javascript" src="FixedSplitterTests.js"></script>
+</head>
+<body>
+	<div id="FixedSplitterPlace"></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests3.html b/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests3.html
new file mode 100644
index 0000000..354ee4f
--- /dev/null
+++ b/dojox/mobile/tests/doh/fixedsplitter/FixedSplitterTests3.html
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>FixedSplitter Test</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY =2;
+</script>
+<script type="text/javascript" src="FixedSplitterTests.js"></script>
+</head>
+<body>
+	<div id="dojox_mobile_FixedSplitter_0">
+		<div id="dojox_mobile_Container_0">
+			pane #1
+		</div>
+
+		<div id="dojox_mobile_FixedSplitter_1">
+			<div id="dojox_mobile_Container_1">
+				pane #2
+			</div>
+			<div id="dojox_mobile_Container_2">
+				pane #3
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/fixedsplitter/module.js b/dojox/mobile/tests/doh/fixedsplitter/module.js
new file mode 100644
index 0000000..7db52b3
--- /dev/null
+++ b/dojox/mobile/tests/doh/fixedsplitter/module.js
@@ -0,0 +1,11 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.FixedSplitter", require.toUrl("./FixedSplitterTests1.html"),999999);
+		doh.registerUrl("dojox.mobile.tests.doh.FixedSplitter", require.toUrl("./FixedSplitterTests2.html"),999999);
+		doh.registerUrl("dojox.mobile.tests.doh.FixedSplitter", require.toUrl("./FixedSplitterTests3.html"),999999);
+	}
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/fixedsplitter/runTests.html b/dojox/mobile/tests/doh/fixedsplitter/runTests.html
new file mode 100644
index 0000000..bda89ba
--- /dev/null
+++ b/dojox/mobile/tests/doh/fixedsplitter/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.fixedsplitter.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/heading/Heading.html b/dojox/mobile/tests/doh/heading/Heading.html
new file mode 100644
index 0000000..9046098
--- /dev/null
+++ b/dojox/mobile/tests/doh/heading/Heading.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Heading</title>
+		<link href="../../../themes/android/base.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+			dojo.addOnLoad(function(){
+				doh.register("dojox.mobile.test.doh.Heading1", [
+					{
+						name: "Heading Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = dijit.byId("dojox_mobile_Heading_0");
+								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+								doh.assertEqual('General', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+
+								demoWidget = dijit.byId("dojox_mobile_Heading_1");
+								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+								doh.assertEqual('Very Very Long Title May Not Be Displayed in the Narrow Space', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+								
+								demoWidget = dijit.byId("dojox_mobile_Heading_2");
+								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+								doh.assertEqual('World Clock', demoWidget.domNode.childNodes[0].childNodes[0].nodeValue);
+
+								demoWidget = dijit.byId("dojox_mobile_Heading_3");
+								doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+							}));
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body>
+		<div id="general" data-dojo-type="dojox.mobile.View" selected="true">
+			<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Settings", moveTo:"settings"'>General</h1>
+			<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Long Button", moveTo:"settings"'>Very Very Long Title May Not Be Displayed in the Narrow Space</h1>
+		</div>
+
+		<h1 data-dojo-type="dojox.mobile.Heading" label="World Clock"></h1><br>
+
+
+		<h1 data-dojo-type="dojox.mobile.Heading">
+			<button data-dojo-type="dojox.mobile.ToolBarButton" style="padding: 0px 14px">Edit</button>
+			<button data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"></button>Alarm Clock</h1><br>
+
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/heading/Heading2.html b/dojox/mobile/tests/doh/heading/Heading2.html
new file mode 100644
index 0000000..8e20456
--- /dev/null
+++ b/dojox/mobile/tests/doh/heading/Heading2.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Heading</title>
+		<link href="../../../themes/android/base.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="Heading2.js"></script>
+	</head>
+	<body>
+		<div id="general" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="foo">General</h1>
+			<h1 dojoType="dojox.mobile.Heading" back="Go To" href="http://dojotoolkit.org/">Test</h1>
+			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="foo">Test</h1>
+			<h1 dojoType="dojox.mobile.Heading" back="Long Button" moveTo="bar">Very Very Long Title May Not Be Displayed in the Narrow Space</h1>
+		</div>
+
+		<div id="foo" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="item1" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-10.png" rightText="Off" moveTo="general">
+					u1space
+				</li>
+				<li id="item2" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-11.png" rightText="Off" moveTo="general">
+					u2space
+				</li>
+				<li id="item3" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-12.png" rightText="Off" moveTo="general">
+					Wi-Fi
+				</li>
+				<li id="item4" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-13.png" rightText="VPN" moveTo="general">
+					VPN
+				</li>
+			</ul>
+		</div>
+
+		<div id="bar" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="general">u1space</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">
+					Video
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-2.png" rightText="VPN">
+					Maps
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">
+					Phone Number
+				</li>
+			</ul>
+		</div>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/heading/Heading2.js b/dojox/mobile/tests/doh/heading/Heading2.js
new file mode 100644
index 0000000..8fe2a4d
--- /dev/null
+++ b/dojox/mobile/tests/doh/heading/Heading2.js
@@ -0,0 +1,102 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.Heading2", [
+		{
+			name: "Heading Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_Heading_0");
+					doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+					doh.assertEqual('General', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+					doh.assertEqual('Settings', demoWidget.backButton.labelNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_Heading_1");
+					doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+					doh.assertEqual('Test', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+					doh.assertEqual('Go To', demoWidget.backButton.labelNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_Heading_2");
+					doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+					doh.assertEqual('Test', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+					doh.assertEqual('Settings', demoWidget.backButton.labelNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_Heading_3");
+					doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+					doh.assertEqual('Very Very Long Title May Not Be Displayed in the Narrow Space', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+					doh.assertEqual('3', demoWidget.domNode.childNodes.length);
+					doh.assertEqual('Long Button', demoWidget.backButton.labelNode.innerHTML);
+				}));
+				return d;
+			}
+		},
+		{
+			name: "Set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_Heading_2");
+				demoWidget.set({back:"Value Changed", label:"Value Changed", moveTo:"bar", transition:"flip"});
+				doh.assertEqual("Value Changed", demoWidget.get("label"), 'get("label")');
+				doh.assertEqual("Value Changed", demoWidget.get("back"), 'get("back")');
+				doh.assertEqual("bar", demoWidget.get("moveTo"));
+				doh.assertEqual("flip", demoWidget.get("transition"));
+				doh.assertEqual('Value Changed', demoWidget.backButton.label, "demoWidget.backButton.label");
+				doh.assertEqual('Value Changed', demoWidget.backButton.labelNode.innerHTML, "demoWidget.backButton.labelNode.innerHTML");
+
+				demoWidget = dijit.byId("dojox_mobile_Heading_5");
+				demoWidget.set({transition:"fade"});
+				doh.assertEqual("fade", demoWidget.get("transition"));
+			}
+		},
+		{
+			name: "moveTo",
+			timeout: 1000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				var demoWidget = dijit.byId("dojox_mobile_Heading_2");
+//				fireOnClick(demoWidget.domNode.childNodes[0].childNodes[1]);
+				fireOnMouseDown(demoWidget.backButton.domNode);
+				fireOnMouseUp(demoWidget.backButton.domNode);
+				setTimeout(d.getTestCallback(function(){
+
+					var demoWidget = dijit.byId("bar");
+					doh.assertEqual('visible', demoWidget.domNode.style.visibility);
+				}));
+				return d;
+			}
+		},
+		{
+			name: "moveTo",
+			timeout: 1000,
+			runTest: function(){
+				setTimeout(function(){
+					var d = new doh.Deferred();
+					var demoWidget = dijit.byId("dojox_mobile_Heading_5");
+					fireOnClick(demoWidget.domNode.childNodes[0].childNodes[1]);
+					setTimeout(d.getTestCallback(function(){
+						var demoWidget = dijit.byId("general");
+						doh.assertEqual('visible', demoWidget.domNode.style.visibility);
+					}));
+					return d;
+				},1500);
+			}
+/*		},
+		{
+			name: "moveTo",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_Heading_1");
+				demoWidget.set({href:"about:blank"});
+				doh.assertEqual("about:blank", demoWidget.get("href"));
+
+				var d = new doh.Deferred();
+				fireOnClick(demoWidget.domNode.childNodes[0].childNodes[1]);
+				setTimeout(d.getTestCallback(function(){
+				}));
+				return d;
+			}
+*/
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/heading/Heading2_Programmatic.html b/dojox/mobile/tests/doh/heading/Heading2_Programmatic.html
new file mode 100644
index 0000000..757ff4c
--- /dev/null
+++ b/dojox/mobile/tests/doh/heading/Heading2_Programmatic.html
@@ -0,0 +1,86 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Heading</title>
+		<link href="../../../themes/android/android.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.addOnLoad(function(){
+				var view = dijit.byId("general");
+				var demoWidget = new dojox.mobile.Heading({back:"Settings", moveTo:"foo", label:"General"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading({back:"Go To", href:"http://dojotoolkit.org/", label:"Test"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading({back:"Settings", moveTo:"foo", label:"Test"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading();
+				demoWidget.set({back:"Long Button", moveTo:"bar", label:"Very Very Long Title May Not Be Displayed in the Narrow Space"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+			});
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="Heading2.js"></script>
+	</head>
+	<body>
+		<div id="general" dojoType="dojox.mobile.View" selected="true">
+		</div>
+
+		<div id="foo" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" id="dojox_mobile_Heading_4">Mobile Mashup</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="item1" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-10.png" rightText="Off" moveTo="general">
+					u1space
+				</li>
+				<li id="item2" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-11.png" rightText="Off" moveTo="general">
+					u2space
+				</li>
+				<li id="item3" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-12.png" rightText="Off" moveTo="general">
+					Wi-Fi
+				</li>
+				<li id="item4" dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-13.png" rightText="VPN" moveTo="general">
+					VPN
+				</li>
+			</ul>
+		</div>
+
+		<div id="bar" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="general" id="dojox_mobile_Heading_5">u1space</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">
+					Video
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/a-icon-2.png" rightText="VPN">
+					Maps
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">
+					Phone Number
+				</li>
+			</ul>
+		</div>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/heading/HeadingTests.html b/dojox/mobile/tests/doh/heading/HeadingTests.html
new file mode 100644
index 0000000..c104804
--- /dev/null
+++ b/dojox/mobile/tests/doh/heading/HeadingTests.html
@@ -0,0 +1,151 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Heading Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	var TEXTAREA_ROWS = 3;
+	var TEXTAREA_COLS = 20;
+	var TEXTAREA_INNERHTML = "ExpandingTextArea";
+	var TEXTAREA_NEW_VALUE = "This is mobile ExpandingTextArea.\nThis text area is automaticaly Expanding.\nHello dojox.mobile";
+	var WIDGET_CLASSNAME1 = "mblHeading";
+	var WIDGET_CLASSNAME2 = "mblHeadingCenterTitle";
+	var WIDGET_SPANTITLE_CLASSNAME = "mblHeadingSpanTitle";
+	var WIDGET_DIVTITLE_CLASSNAME = "mblHeadingDivTitle";
+	var WIDGET_BUTTON_CLASSNAME = "mblToolBarButton mblToolBarButtonHasLeftArrow";
+	var WIDGET_BUTTON_HEAD_CLASSNAME = "mblToolBarButtonArrow mblToolBarButtonLeftArrow mblColorDefault mblColorDefault45";
+	var WIDGET_BUTTON_HEAD_CLASSNAME_IE = "mblToolBarButtonArrow mblToolBarButtonLeftArrow";
+	var WIDGET_BUTTON_BODY_CLASSNAME = "mblToolBarButtonBody mblColorDefault";
+	var WIDGET_TITLE_TEXT1 = "View 1";
+	var WIDGET_TITLE_TEXT2 = "View 2";
+	var WIDGET_BACK_TEXT = "Settings";
+	var WIDGET_HEIGHT1 = "44";
+	var WIDGET_OFFSETHEIGHT1 = 44;
+	var WIDGET_OFFSETHEIGHT1_IE10 = 42;
+	var WIDGET_OFFSETHEIGHT2 = 90;
+
+	require([
+		"dojo/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/dom-class", // dojo.hasClass
+		"dojo/ready", // dojo.ready
+		"dojo/_base/lang", // lang.trim
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	// doh functions
+		"dojox/mobile/Heading",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(has, domConst, domClass, ready, lang, registry, runner, Heading){
+
+		function _createHeadingDeclaratively(widgetId) {
+			return registry.byId(widgetId);
+		};
+
+		function _createHeadingProgrammatically(placeHolderId, widgetId, labelText){
+			// Create SwapView
+			var r = new Heading({id:widgetId, back:"Settings", moveTo:"settings", label:labelText});
+			runner.assertNotEqual(null, r);
+			domConst.place(r.domNode, placeHolderId, "replace");
+			r.startup();
+			
+			return r;
+		};
+
+		function _createHeadingProgrammaticallyWithSourceNodeReference(widgetId){
+			// Create IconContainer
+			var r = new Heading({back:"Settings", moveTo:"settings"}, widgetId);
+
+			r.startup();
+			return r;
+		};
+
+		function _assertCorrectHeading(widget, titleText, backText, backClassName){
+			runner.assertNotEqual(null, widget, "IconItem: Did not instantiate.");
+			runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + widget.domNode.id);
+	//		runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " id=" + widget.domNode.id);
+			runner.assertEqual(has("ie")>=10 ? WIDGET_OFFSETHEIGHT1_IE10 : WIDGET_OFFSETHEIGHT1, widget.domNode.offsetHeight, "style.height id=" + widget.domNode.id);
+			runner.assertEqual(WIDGET_SPANTITLE_CLASSNAME, widget.labelNode.className);
+			runner.assertEqual(WIDGET_DIVTITLE_CLASSNAME, widget.labelDivNode.className);
+			runner.assertEqual(titleText, widget.labelNode.innerHTML, "widget.labelNode.innerHTML");
+			runner.assertEqual(titleText, widget.labelDivNode.innerHTML, "widget.labelDivNode.innerHTML");
+			runner.assertEqual(backClassName, widget.backButton.domNode.className);
+			runner.assertEqual(has("ie")<10 ? WIDGET_BUTTON_HEAD_CLASSNAME_IE : WIDGET_BUTTON_HEAD_CLASSNAME,
+			    // calling trim() because of a blank that ToolBarButton.js adds at the end of widget's className attribute value 
+				lang.trim(widget.backButton.arrowNode.className));
+			runner.assertEqual(WIDGET_BUTTON_BODY_CLASSNAME, widget.backButton.bodyNode.className);
+			runner.assertEqual(backText, widget.backButton.labelNode.innerHTML, "widget.labelDivNode.innerHTML");
+		};
+
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		};
+
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.Heading", [
+				{
+					name: "Heading Verification1",
+					timeout: 4000,
+					runTest: function(){
+						var widget1 = _createHeadingDeclaratively("dojox_mobile_Heading_0");
+						var widget2 = _createHeadingProgrammatically("view1-Heading2place", "view1-Heading2", WIDGET_TITLE_TEXT1);
+						var widget3 = _createHeadingProgrammaticallyWithSourceNodeReference("view1-Heading3");
+
+						_assertCorrectHeading(widget1, WIDGET_TITLE_TEXT1, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+						_assertCorrectHeading(widget2, WIDGET_TITLE_TEXT1, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+						_assertCorrectHeading(widget3, WIDGET_TITLE_TEXT1, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+
+					}
+				},
+				{
+					name: "Heading Verification2",
+					timeout: 4000,
+					runTest: function(){
+						var widget1 = _createHeadingDeclaratively("dojox_mobile_Heading_1");
+						var widget2 = _createHeadingProgrammatically("view2-Heading2place", "view2-Heading2", WIDGET_TITLE_TEXT2);
+						var widget3 = _createHeadingProgrammaticallyWithSourceNodeReference("view2-Heading3");
+
+						var d = new runner.Deferred();
+						var handle2 = dojo.subscribe("/dojox/mobile/afterTransitionIn", d.getTestCallback(function(view){
+							if(view.id=="view2"){
+								dojo.unsubscribe(handle2);
+							}
+							var widget1 = registry.byId("dojox_mobile_Heading_1");
+							var widget2 = registry.byId("view2-Heading2");
+							var widget3 = registry.byId("view2-Heading3");
+							_assertCorrectHeading(widget1, WIDGET_TITLE_TEXT2, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+							_assertCorrectHeading(widget2, WIDGET_TITLE_TEXT2, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+							_assertCorrectHeading(widget3, WIDGET_TITLE_TEXT2, WIDGET_BACK_TEXT, WIDGET_BUTTON_CLASSNAME);
+						}));
+						_showView2();
+						return d;
+					}
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Settings", moveTo:"settings", label:"View 1"'></h1>
+		<div id="view1-Heading2place"></div>
+		<h1 id="view1-Heading3">View 1</h1>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Settings", moveTo:"settings", label:"View 2"'></h1>
+		<div id="view2-Heading2place"></div>
+		<h1 id="view2-Heading3">View 2</h1>
+	</div>
+	<div id="settings" data-dojo-type="dojox.mobile.View">
+		<h1>settings</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/heading/Heading_Programmatic.html b/dojox/mobile/tests/doh/heading/Heading_Programmatic.html
new file mode 100644
index 0000000..f59a802
--- /dev/null
+++ b/dojox/mobile/tests/doh/heading/Heading_Programmatic.html
@@ -0,0 +1,172 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Heading</title>
+		<link href="../../../themes/android/base.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			dojo.require("dojo.window");
+			
+	        dojo.require("doh.runner");
+			dojo.addOnLoad(function(){
+				var view = dijit.byId("general");
+				var demoWidget = new dojox.mobile.Heading({back:"Settings", moveTo:"settings", label:"General"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading({back:"Long Button", moveTo:"settings"});
+				demoWidget.set({label:"Very Very Long Title May Not Be Displayed in the Narrow Space"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading({label:"World Clock"});
+				dojo.doc.body.appendChild(demoWidget.containerNode);
+				demoWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading();
+				dojo.doc.body.appendChild(demoWidget.containerNode);
+				demoWidget.startup();
+				var childWidget = new dojox.mobile.ToolBarButton({label:"Edit"});
+				childWidget.domNode.style.padding = "0px 14px";
+//				demoWidget.addChild(childWidget);
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"mblDomButtonWhitePlus"});
+				childWidget.domNode.style.float = "right";
+//				demoWidget.addChild(childWidget);
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				demoWidget.domNode.appendChild(dojo.doc.createTextNode("Alarm Clock"));
+
+				// Test case for #16275 and #16991
+				demoWidget = new dojox.mobile.Heading();
+				dojo.doc.body.appendChild(demoWidget.containerNode);
+				
+				demoWidget.set("moveTo", "view1");
+				demoWidget.set("back", "Back");
+				demoWidget.set("moveTo", "view2");
+				// If #16275 is not fixed, this is needed for changing the moveTo afterwards:
+				// demoWidget.backButton.set("moveTo", "view2");
+				
+				demoWidget.startup();
+				
+				// Test case for #16349
+				demoWidget = new dojox.mobile.Heading();
+				dojo.doc.body.appendChild(demoWidget.containerNode);
+				
+				demoWidget.set("href", "fragment1.html");
+				demoWidget.set("transition", "flip");
+				demoWidget.set("back", "Back");
+				demoWidget.set("href", "fragment2.html");
+				demoWidget.set("transition", "fade");
+				// If #16349 is not fixed, this is needed for changing the href or transition afterwards:
+				// demoWidget.backButton.set("href", "fragment2.html");
+				// demoWidget.backButton.set("transition", "fade");
+				
+				doh.register("dojox.mobile.test.doh.Heading1", [
+					function test_Heading_Verification(){
+						var demoWidget = dijit.byId("dojox_mobile_Heading_0");
+						doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+						doh.assertEqual('General', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+
+						demoWidget = dijit.byId("dojox_mobile_Heading_1");
+						doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+						doh.assertEqual('Very Very Long Title May Not Be Displayed in the Narrow Space', demoWidget.domNode.childNodes[1].childNodes[0].nodeValue);
+						
+						demoWidget = dijit.byId("dojox_mobile_Heading_2");
+						doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+						doh.assertEqual('World Clock', demoWidget.domNode.childNodes[0].childNodes[0].nodeValue);
+
+						demoWidget = dijit.byId("dojox_mobile_Heading_3");
+						doh.assertTrue('mblHeading mblHeadingCenterTitle' == demoWidget.domNode.className || 'mblHeading' == demoWidget.domNode.className);
+						
+						// Test case for #16275
+						demoWidget = dijit.byId("dojox_mobile_Heading_4");
+						doh.assertTrue(demoWidget.backButton.get("moveTo") == "view2", "when changing Heading.moveTo afterwards");
+						
+						// Test case for #16349
+						demoWidget = dijit.byId("dojox_mobile_Heading_5");
+						doh.assertTrue(demoWidget.backButton.get("href") == "fragment2.html", "when changing Heading.href afterwards");
+						doh.assertTrue(demoWidget.backButton.get("transition") == "fade", "when changing Heading.transition afterwards");
+						
+						// Test case for #16313 
+						var noError = true; 
+						try{
+							demoWidget.set("busy", false);
+						}catch(err){ 
+							noError = false;
+						} 
+						doh.assertTrue(noError, "Setting busy to false before ever being set to true shouldn't throw an exception!");
+						
+						// Test case for #16991
+						demoWidget.set("moveTo", "view2");
+						demoWidget.set("href", "");
+						doh.assertFalse(demoWidget.backButton.get("back"), 
+							"heading.backButton.back should be false when moveTo is specified");
+						
+						demoWidget.set("moveTo", "");
+						demoWidget.set("href", "fragment2.html");
+						doh.assertFalse(demoWidget.backButton.get("back"), 
+							"heading.backButton.back should be false when href is specified");
+							
+						demoWidget.set("moveTo", "view2");
+						demoWidget.set("href", "fragment2.html");
+						doh.assertFalse(demoWidget.backButton.get("back"), 
+							"heading.backButton.back should be false when moveTo and href are specified");
+						
+						demoWidget.set("moveTo", "");
+						demoWidget.set("href", "");
+						doh.assertTrue(demoWidget.backButton.get("back"), 
+							"heading.backButton.back should be true when moveTo and href are NOT specified");
+					},
+					{
+						name: "test_Heading_Verification2",
+						timeout: 3000,
+						runTest: function(){
+							// Test case for #15064.
+							var widget = new dojox.mobile.Heading();
+							var d = new doh.Deferred();
+							var errorCounter = 0;
+							var errorMsg;
+							// Before the fix of #15064, there used to be an error thrown when destroying 
+							// right after startup(). To test it, we cannot use a simple try-catch, because
+							// this is about an error thrown by the setTimeout function which used to be set 
+							// Heading's startup(). Hence:
+							window.onerror = function(msg, url, lineNumber){
+								errorCounter++;
+								errorMsg = "After destroy: " + msg + "\nURL: " + url + 
+									"\nLine number: " + lineNumber;
+								console.log(errorMsg);
+							};
+							widget.startup();
+							widget.destroyRecursive(false/*preserveDom*/);
+							// Check that no error has been thrown
+							setTimeout(d.getTestCallback(function(){
+								doh.assertEqual(0, errorCounter, errorMsg);
+							}), 2000); // smaller than the total timeout of the test case
+						
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+
+		</script>
+	</head>
+	<body>
+		<div id="general" dojoType="dojox.mobile.View" selected="true">
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/heading/module.js b/dojox/mobile/tests/doh/heading/module.js
new file mode 100644
index 0000000..265e0dd
--- /dev/null
+++ b/dojox/mobile/tests/doh/heading/module.js
@@ -0,0 +1,11 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.Heading", require.toUrl("./Heading.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Heading", require.toUrl("./Heading2.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Heading", require.toUrl("./Heading_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Heading", require.toUrl("./Heading2_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Heading", require.toUrl("./HeadingTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/heading/runTests.html b/dojox/mobile/tests/doh/heading/runTests.html
new file mode 100644
index 0000000..c33ddc1
--- /dev/null
+++ b/dojox/mobile/tests/doh/heading/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.heading.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/iconcontainer/IconContainer.html b/dojox/mobile/tests/doh/iconcontainer/IconContainer.html
new file mode 100644
index 0000000..c57629a
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconcontainer/IconContainer.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Icon</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/IconContainer.css" rel="stylesheet"/>
+
+		<style>
+			.box {
+				border: 1px solid #A7C0E0;
+				width: 300px;
+				height: 250px;
+				background-image: url(../../images/widget-bg.png);
+				background-repeat: no-repeat;
+				background-color: white;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.View");
+			dojo.require("dojox.mobile.IconContainer");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src=IconContainer.js></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
+			<ul dojoType="dojox.mobile.IconContainer">
+				<li dojoType="dojox.mobile.IconItem" label="app1" icon="../../images/icon3.png" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app2" icon="../../images/icon3.png" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app3" icon="../../images/icon3.png" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="moveTo" icon="../../images/icon3.png" moveTo="about" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="href" icon="../../images/icon3.png" href="../../test_iPhone-RoundRectList.html" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="url" icon="../../images/icon3.png" url="../../view-sample.html" transition="slide"></li>
+			</ul>
+		</div>
+
+		<div id="about" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Network											   
+				</li>												   
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Line
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="1024">
+					Songs
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/iconcontainer/IconContainer.js b/dojox/mobile/tests/doh/iconcontainer/IconContainer.js
new file mode 100644
index 0000000..964749f
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconcontainer/IconContainer.js
@@ -0,0 +1,89 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.IconContainer", [
+		{
+			name: "IconContainer Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
+					doh.assertEqual('mblIconContainer', demoWidget.domNode.className);
+					
+				}));
+				return d;
+			}
+		},
+		{
+			name: "IconItem Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
+				var e;
+				//lazy loading
+
+				doh.assertEqual('none', demoWidget.paneWidget.domNode.style.display);
+//				fireOnClick(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0]);
+				fireOnMouseDown(demoWidget.domNode);
+				fireOnMouseUp(demoWidget.domNode);
+
+				demoWidget = dijit.byId("dojox_mobile_IconItem_1");
+				doh.assertEqual('none', demoWidget.paneWidget.domNode.style.display);
+//				fireOnClick(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0]);
+				fireOnMouseDown(demoWidget.domNode);
+				fireOnMouseUp(demoWidget.domNode);
+
+				setTimeout(d.getTestCallback(function(){
+					verifyIconItem("dojox_mobile_IconItem_0", 'app1', '', /icon3.png/i);
+					verifyIconItem("dojox_mobile_IconItem_1", 'app2', '', /icon3.png/i);
+				}),2000);
+				return d;
+			}
+		},
+		{
+			name: "IconContainer set",
+			timeout: 4000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
+				demoWidget.set({transition:"slide", pressedIconOpacity:"0.8"});
+
+				doh.assertEqual(0.8, demoWidget.get("pressedIconOpacity"));
+				doh.assertEqual("slide", demoWidget.get("transition"));
+			}
+		},
+		{
+			name: "IconItem set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_IconItem_1");
+				demoWidget.set({icon:"../../images/icon1.png"});
+				doh.assertEqual("../../images/icon1.png", demoWidget.get("icon"));
+				doh.assertTrue(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(/icon1.png/i) != -1);
+			}
+		},
+		{
+			name: "IconItem add/removeChild and pane widgets consistency",
+			timeout: 1000,
+			runTest: function(){
+				// Checks that pane widgets are added/removed to the pane container by addChild/removeChild
+				
+				var container = dijit.byId("dojox_mobile_IconContainer_0");
+				var item = dijit.byId("dojox_mobile_IconItem_1");
+				
+				doh.assertEqual(container.paneContainerWidget, item.paneWidget.getParent(), "wrong pane parent at startup");
+				doh.assertEqual(item.getIndexInParent(), item.paneWidget.getIndexInParent(), "wrong pane index at startup");
+
+				var index = item.getIndexInParent();				
+				container.removeChild(item);
+
+				doh.assertEqual(null, item.paneWidget.getParent(), "wrong pane parent after remove");
+				
+				container.addChild(item, index);
+
+				doh.assertEqual(container.paneContainerWidget, item.paneWidget.getParent(), "wrong pane parent after add");
+				doh.assertEqual(item.getIndexInParent(), item.paneWidget.getIndexInParent(), "wrong pane index after add");
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/iconcontainer/IconContainer2.html b/dojox/mobile/tests/doh/iconcontainer/IconContainer2.html
new file mode 100644
index 0000000..be5f436
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconcontainer/IconContainer2.html
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Icon</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+
+		<style>
+			.box {
+				border: 1px solid #A7C0E0;
+				width: 300px;
+				height: 250px;
+				background-image: url(../../images/widget-bg.png);
+				background-repeat: no-repeat;
+				background-color: white;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.View");
+			dojo.require("dojox.mobile.IconContainer");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.addOnLoad(function(){
+				doh.register("dojox.mobile.test.doh.IconContainer", [
+					{
+						name: "IconContainer Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
+								doh.assertEqual('mblIconContainer', demoWidget.domNode.className);
+								
+							}));
+							return d;
+						}
+					},
+					{
+						name: "IconItem Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
+							doh.assertEqual('none', demoWidget.paneWidget.domNode.style.display);
+//							fireOnClick(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0]);
+							fireOnMouseDown(demoWidget.domNode);
+							fireOnMouseUp(demoWidget.domNode);
+							demoWidget = dijit.byId("dojox_mobile_IconItem_1");
+							doh.assertEqual('none', demoWidget.paneWidget.domNode.style.display);
+							var t = 1000;
+							if(dojo.isIE || dojo.isAndroid || dojo.isIPhone || dojo.isBB) {
+								t=2500;
+							}
+
+							setTimeout(d.getTestCallback(function(){
+								verifyIconItem("dojox_mobile_IconItem_0", 'app1', '', /icon1.png/i);
+								verifyIconItem("dojox_mobile_IconItem_1", 'app2', 'none', /icon3.png/i);
+								
+							}),t);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
+			<ul dojoType="dojox.mobile.IconContainer" defaultIcon="../../images/icon1.png" transition="slide" pressedIconOpacity="0.8">
+				<li dojoType="dojox.mobile.IconItem" label="app1" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app2" icon="../../images/icon3.png" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app3" icon="../../images/icon3.png" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="moveTo" icon="../../images/icon3.png" moveTo="about" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="href" icon="../../images/icon3.png" href="../../test_iPhone-RoundRectList.html" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="url" icon="../../images/icon3.png" url="../../view-sample.html" transition="slide"></li>
+			</ul>
+		</div>
+
+		<div id="about" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Network											   
+				</li>												   
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Line
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="1024">
+					Songs
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/iconcontainer/IconContainer3.html b/dojox/mobile/tests/doh/iconcontainer/IconContainer3.html
new file mode 100644
index 0000000..44f202a
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconcontainer/IconContainer3.html
@@ -0,0 +1,110 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Icon</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/IconContainer.css" rel="stylesheet"/>
+
+		<style>
+			.box {
+				border: 1px solid #A7C0E0;
+				width: 300px;
+				height: 250px;
+				background-image: url(../../images/widget-bg.png);
+				background-repeat: no-repeat;
+				background-color: white;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.View");
+			dojo.require("dojox.mobile.IconContainer");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+
+			dojo.addOnLoad(function(){
+				doh.register("dojox.mobile.test.doh.IconContainer", [
+					{
+						name: "IconContainer Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = dijit.byId("dojox_mobile_IconContainer_0");
+								doh.assertEqual('mblIconContainer', demoWidget.domNode.className);
+								
+							}));
+							return d;
+						}
+					},
+					{
+						name: "IconItem Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
+							fireOnMouseDown(demoWidget.domNode);
+							fireOnMouseUp(demoWidget.domNode);
+
+							demoWidget = dijit.byId("dojox_mobile_IconItem_1");
+							doh.assertEqual('none', demoWidget.paneWidget.domNode.style.display);
+							fireOnMouseDown(demoWidget.domNode);
+							fireOnMouseUp(demoWidget.domNode);
+							var t = 1000;
+							if(dojo.isIE || dojo.isAndroid || dojo.isIPhone || dojo.isBB) {
+								t=2500;
+							}
+
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = dijit.byId("dojox_mobile_IconItem_0");
+								verifyRect(demoWidget.domNode.childNodes[0].childNodes[0].childNodes[0].childNodes[0], "0px", "64px", "64px", "0px");
+								verifyIconItem("dojox_mobile_IconItem_0", 'app1', 'none', /icon-all.png/i, true);
+								verifyIconItem("dojox_mobile_IconItem_1", 'app2', '', /icon-all.png/i, true);
+								
+							}),t);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
+			<ul dojoType="dojox.mobile.IconContainer" transition="slide" single="true" pressedIconOpacity="0.8" iconBase="../../images/icon-all.png" iconPos="0,0,64,64" back="Test" label="test">
+				<li dojoType="dojox.mobile.IconItem" label="app1" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app2" iconPos="0,64,64,64" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="app3" iconPos="0,64,64,64" lazy="true"><div class="box"></div></li>
+				<li dojoType="dojox.mobile.IconItem" label="moveTo" iconPos="0,64,64,64" moveTo="about" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="href" iconPos="0,64,64,64" href="../../test_iPhone-RoundRectList.html" transition="slide"></li>
+				<li dojoType="dojox.mobile.IconItem" label="url" iconPos="0,64,64,64" url="../../view-sample.html" transition="slide"></li>
+			</ul>
+		</div>
+
+		<div id="about" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Network											   
+				</li>												   
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Line
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="1024">
+					Songs
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/iconcontainer/IconContainerTests.html b/dojox/mobile/tests/doh/iconcontainer/IconContainerTests.html
new file mode 100644
index 0000000..1b8f870
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconcontainer/IconContainerTests.html
@@ -0,0 +1,215 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>IconContainer and IconItem Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	var ICON_ITEM_CLASSNAME1 = "mblIconItem";
+	var ICON_ITEM_CLASSNAME2 = "mblIconArea";
+	var WIDGET_CLASSNAME = "mblIconContainer";
+	var ICON_ITEM_SRC_REGEXP = /icon-1.png/i;
+	var CHILD_ITEM_PROPS = [{label:"app1", icon:"../../images/icon-1.png", lazy:"true"}, 
+							  {label:"app2", icon:"../../images/icon-1.png", lazy:"true"}, 
+							  {label:"app3", icon:"../../images/icon-1.png", lazy:"true"},
+							  {label:"moveTo", icon:"../../images/icon-1.png", moveTo:"about", transition:"slide"},
+							  {label:"href", icon:"../../images/icon-1.png", href:"../../test_iPhone-RoundRectList.html", transition:"slide"},
+							  {label:"url" , icon:"../../images/icon-1.png", url:"../../view-sample.html", transition:"slide"}];
+
+	var CHILD_ITEM_CONTAINERS = ['<div class="box"></div>', 
+							  	   '<div class="box"></div>', 
+							       '<div class="box"></div>',
+							       '',
+							       '',
+							       ''];
+
+	require([
+		"dojo/_base/array", // dojo.forEach
+		"dojo/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/IconContainer",
+		"dojox/mobile/IconItem",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
+		"dojox/mobile/View"		// This mobile app uses mobile view
+	], function(array, has, domConst, ready, registry, runner, IconContainer, IconItem){
+		function _createIconContainerDeclaratively(widgetId) {
+			return registry.byId(widgetId);
+		}
+		function _createIconContainerProgrammatically(placeHolderId, widgetId){
+			// Create IconContainer
+			var r = new IconContainer({id:widgetId});
+			runner.assertNotEqual(null, r);
+			domConst.place(r.domNode, placeHolderId, "replace");
+
+			// Create IconItems
+			for(var i = 0, len = CHILD_ITEM_PROPS.length; i < len; i++){
+				var childWidget = new IconItem(CHILD_ITEM_PROPS[i]);
+				r.addChild(childWidget);
+				if(CHILD_ITEM_CONTAINERS[i]){
+					childWidget.set("content", CHILD_ITEM_CONTAINERS[i]);
+				}
+			}
+			r.startup();
+			return r;
+		}
+		function _createIconContainerProgrammaticallyWithSourceNodeReference(widgetId){
+			// Create IconContainer
+			var r = new IconContainer({}, widgetId);
+
+			// Create IconItems
+			var index = 0;
+			for(var i = 0, len = r.domNode.childNodes.length; i < len; i++){
+				var n = r.domNode.childNodes[i];
+				if(n.nodeType === 1 && n.id){
+					new IconItem(CHILD_ITEM_PROPS[index++], n.id);
+				}
+			}
+			r.startup();
+			return r;
+		}
+		function _assertCorrectIconContainer(widget){
+			runner.assertNotEqual(null, widget, "IconContainer: Did not instantiate.");
+			runner.assertEqual(WIDGET_CLASSNAME, widget.domNode.className, "id=" + widget.domNode.id);
+			array.forEach(widget.getChildren(), function(iconItem){
+				_assertCorrectIconItem(iconItem);
+			});
+			
+		}
+		function _assertCorrectIconItem(widget){
+			runner.assertNotEqual(null, widget, "IconItem: Did not instantiate.");
+			runner.assertEqual(ICON_ITEM_CLASSNAME1, widget.domNode.className, "id=" + widget.domNode.id);
+			runner.assertEqual(ICON_ITEM_CLASSNAME2, widget.domNode.childNodes[0].className, "id=" + widget.domNode.id);
+			if(!has("ie") || has("ie") > 6){
+				runner.assertTrue(widget.domNode.childNodes[0].childNodes[0].childNodes[0].src.search(ICON_ITEM_SRC_REGEXP) != -1, ICON_ITEM_SRC_REGEXP.toString() + " id=" + widget.domNode.id);
+			}
+			runner.assertEqual(widget.label, widget.domNode.childNodes[0].childNodes[1].childNodes[0].nodeValue, "id=" + widget.domNode.id);
+		}
+		function _assertCorrectIconItemPos(widgetId1, widgetId2, widgetId3, widgetId4){
+			var widget1 = registry.byId(widgetId1);
+			var widget2 = registry.byId(widgetId2);
+			var widget3 = registry.byId(widgetId3);
+			var widget4 = registry.byId(widgetId4);
+			
+			
+			runner.assertNotEqual(null, widget1, "Widget (Id=" +  widgetId1 + ") dose not exist.");
+			runner.assertNotEqual(null, widget2, "Widget (Id=" +  widgetId2 + ") dose not exist.");
+			runner.assertNotEqual(null, widget3, "Widget (Id=" +  widgetId3 + ") dose not exist.");
+			runner.assertNotEqual(null, widget4, "Widget (Id=" +  widgetId4 + ") dose not exist.");
+			runner.assertEqual(widget2.domNode.offsetTop, widget1.domNode.offsetTop, "id=" + widgetId1);
+			runner.assertEqual(widget3.domNode.offsetLeft, widget1.domNode.offsetLeft, "left id=" + widgetId1);
+			runner.assertEqual(widget3.domNode.offsetTop, widget4.domNode.offsetTop, "id=" + widgetId3);
+			runner.assertEqual(widget2.domNode.offsetLeft, widget4.domNode.offsetLeft, "left id=" + widgetId4);
+		}
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		}
+		dojo.ready(function(){
+			doh.register("dojox.mobile.test.doh.IconContainerTests", [
+				function testInView1(){
+					var widget1 = _createIconContainerDeclaratively("dojox_mobile_IconContainer_0");
+					var widget2 = _createIconContainerProgrammatically("view1-IconContainer2place", "view1-IconContainer2");
+					var widget3 = _createIconContainerProgrammaticallyWithSourceNodeReference("view1-IconContainer3");
+
+					_assertCorrectIconContainer(widget1);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("dojox_mobile_IconItem_0", "dojox_mobile_IconItem_2", "dojox_mobile_IconItem_3", "dojox_mobile_IconItem_5");
+					}
+					_assertCorrectIconContainer(widget2);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("dojox_mobile_IconItem_12", "dojox_mobile_IconItem_14", "dojox_mobile_IconItem_15", "dojox_mobile_IconItem_17");
+					}
+					_assertCorrectIconContainer(widget3);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("view1-IconContainer3-IconItem1", "view1-IconContainer3-IconItem3", "view1-IconContainer3-IconItem4", "view1-IconContainer3-IconItem6");
+					}
+				},
+				function testInView2(){
+					var widget1 = _createIconContainerDeclaratively("dojox_mobile_IconContainer_1");
+					var widget2 = _createIconContainerProgrammatically("view2-IconContainer2place", "view2-IconContainer2");
+					var widget3 = _createIconContainerProgrammaticallyWithSourceNodeReference("view2-IconContainer3");
+
+					_showView2();
+
+					_assertCorrectIconContainer(widget1);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("dojox_mobile_IconItem_6", "dojox_mobile_IconItem_8", "dojox_mobile_IconItem_9", "dojox_mobile_IconItem_11");
+					}
+					_assertCorrectIconContainer(widget2);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("dojox_mobile_IconItem_18", "dojox_mobile_IconItem_20", "dojox_mobile_IconItem_21", "dojox_mobile_IconItem_23");
+					}
+					_assertCorrectIconContainer(widget3);
+					if(!has("ie")){
+						_assertCorrectIconItemPos("view2-IconContainer3-IconItem1", "view2-IconContainer3-IconItem3", "view2-IconContainer3-IconItem4", "view2-IconContainer3-IconItem6");
+					}
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<table  style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<ul data-dojo-type="dojox.mobile.IconContainer">
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"../../images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"../../images/icon-1.png", href:"../../test_iPhone-RoundRectList.html", transition:"slide"'></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url" , icon:"../../images/icon-1.png", url:"../../view-sample.html", transition:"slide"'></li>
+			</ul>
+		</td></tr></tbody></table>
+		<table style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<div id="view1-IconContainer2place"></div>
+		</td></tr></tbody></table>
+		<table style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<ul id="view1-IconContainer3">
+				<li id="view1-IconContainer3-IconItem1"><div class="box"></div></li>
+				<li id="view1-IconContainer3-IconItem2"><div class="box"></div></li>
+				<li id="view1-IconContainer3-IconItem3"><div class="box"></div></li>
+				<li id="view1-IconContainer3-IconItem4"></li>
+				<li id="view1-IconContainer3-IconItem5"></li>
+				<li id="view1-IconContainer3-IconItem6"></li>
+			</ul>
+		</td></tr></tbody></table>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<table style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<ul data-dojo-type="dojox.mobile.IconContainer">
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"../../images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"../../images/icon-1.png", href:"../../test_iPhone-RoundRectList.html", transition:"slide"'></li>
+				<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url" , icon:"../../images/icon-1.png", url:"../../view-sample.html", transition:"slide"'></li>
+			</ul>
+		</td></tr></tbody></table>
+		<table style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<div id="view2-IconContainer2place"></div>
+		</td></tr></tbody></table>
+		<table style="position:relative"><tbody><tr><td style="width:310px;"><img src="../../../images/blank.png" width="310" height="1" alt=""/>
+			<ul id="view2-IconContainer3">
+				<li id="view2-IconContainer3-IconItem1"><div class="box"></div></li>
+				<li id="view2-IconContainer3-IconItem2"><div class="box"></div></li>
+				<li id="view2-IconContainer3-IconItem3"><div class="box"></div></li>
+				<li id="view2-IconContainer3-IconItem4"></li>
+				<li id="view2-IconContainer3-IconItem5"></li>
+				<li id="view2-IconContainer3-IconItem6"></li>
+			</ul>
+		</td></tr></tbody></table>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/iconcontainer/IconContainerTests2.html b/dojox/mobile/tests/doh/iconcontainer/IconContainerTests2.html
new file mode 100644
index 0000000..7569ceb
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconcontainer/IconContainerTests2.html
@@ -0,0 +1,180 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>IconContainer and IconItem Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	require([
+		"dojo/ready",
+		"dijit/registry",
+		"doh/runner",
+		"dojox/mobile/IconContainer",
+		"dojox/mobile/IconItem",
+		"dojox/mobile",
+		"dojox/mobile/compat",
+		"dojox/mobile/parser"
+	], function(ready, registry, runner, IconContainer, IconItem){
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.IconContainerTests2", [
+				{
+					name: "test1",
+					timeout: 3000,
+					runTest: function(){
+ 						// Test case for #16868
+						var editableIconContainer = registry.byId("editableIconContainer1");
+						var item = registry.byId("item1");
+						try{
+							editableIconContainer.deleteItem(item);
+						}catch(err){
+							runner.assertTrue(false, "deleteItem throws error! (#16868)");
+						}
+					}
+				},
+				{
+					name: "test2",
+					timeout: 3000,
+					runTest: function(){
+ 						// Test case for #15064
+						var editableIconContainer = registry.byId("editableIconContainer2");
+						var d = new runner.Deferred();
+						var errorCounter = 0;
+						var errorMsg;
+						// Before the fix of #15064, there used to be an error thrown when destroying 
+						// right after startEdit(). To test it, we cannot use a simple try-catch, because
+						// this is about an error thrown by the setTimeout function which used to be set 
+						// by startEdit() in an editable IconContainer. Hence:
+						window.onerror = function(msg, url, lineNumber){
+							errorCounter++;
+							errorMsg = "After destroy: " + msg + "\nURL: " + url + 
+								"\nLine number: " + lineNumber;
+							console.log(errorMsg);
+						};
+						editableIconContainer.startEdit();
+						editableIconContainer.destroyRecursive(false/*preserveDom*/);
+						// Check that no error has been thrown
+						setTimeout(d.getTestCallback(function(){
+							runner.assertEqual(0, errorCounter, errorMsg);
+						}), 2000); // smaller than the total timeout of the test case
+						
+						return d;
+					}
+				},
+				{
+					name: "test3",
+					timeout: 3000,
+					runTest: function(){
+ 						// Test case for #15064
+						var editableIconContainer = registry.byId("editableIconContainer3");
+						var item = registry.byId("item3");
+						var d = new runner.Deferred();
+						var errorCounter = 0;
+						var errorMsg;
+						// Before the fix of #15064, there used to be an error thrown when destroying 
+						// right after deleteItem(). To test it, we cannot use a simple try-catch, because
+						// this is about an error thrown by the setTimeout function which used to be set 
+						// (indirectly) by deleteItem() in an editable IconContainer. Hence:
+						window.onerror = function(msg, url, lineNumber){
+							errorCounter++;
+							errorMsg = "After destroy: " + msg + "\nURL: " + url + 
+								"\nLine number: " + lineNumber;
+							console.log(errorMsg);
+						};
+						editableIconContainer.deleteItem(item);
+						editableIconContainer.destroyRecursive(false/*preserveDom*/);
+						// Check that no error has been thrown
+						setTimeout(d.getTestCallback(function(){
+							runner.assertEqual(0, errorCounter, errorMsg);
+						}), 2000); // smaller than the total timeout of the test case
+						
+						return d;
+					}
+				},
+				{
+					name: "test4",
+					timeout: 3000,
+					runTest: function(){
+ 						// Test case for #15064
+						var editableIconContainer = registry.byId("editableIconContainer4");
+						var item = registry.byId("item4");
+						var d = new runner.Deferred();
+						var errorCounter = 0;
+						var errorMsg;
+						// Before the fix of #15064, there used to be an error thrown when destroying 
+						// right after IconItem.highlight(). To test it, we cannot use a simple try-catch, because
+						// this is about an error thrown by the setTimeout function which used to be set 
+						// by IconItem.highlight(). Hence:
+						window.onerror = function(msg, url, lineNumber){
+							errorCounter++;
+							errorMsg = "After destroy: " + msg + "\nURL: " + url + 
+								"\nLine number: " + lineNumber;
+							console.log(errorMsg);
+						};
+						item.highlight();
+						editableIconContainer.destroyRecursive(false/*preserveDom*/);
+						// Check that no error has been thrown
+						setTimeout(d.getTestCallback(function(){
+							runner.assertEqual(0, errorCounter, errorMsg);
+						}), 2000); // smaller than the total timeout of the test case
+						
+						return d;
+					}
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<!-- Test case for #16868 -->
+	<div data-dojo-type="dojox/mobile/View">
+		<h1>View 1</h1>
+		<ul id="editableIconContainer1" data-dojo-type="dojox/mobile/IconContainer"
+			data-dojo-props="editable: true">
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app1", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li id="item1" data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app2", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app3", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"moveTo", icon:"../../images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"href", icon:"../../images/icon-1.png", href:"../../test_iPhone-RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"url" , icon:"../../images/icon-1.png", url:"../../view-sample.html", transition:"slide"'></li>
+		</ul>
+	</div>
+	
+	<!-- Test cases for #15064 -->
+	<div id="view2" data-dojo-type="dojox/mobile/View">
+		<h1>View 2</h1>
+		<ul id="editableIconContainer2" data-dojo-type="dojox/mobile/IconContainer"
+			data-dojo-props="editable: true">
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app1", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app2", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app3", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"moveTo", icon:"../../images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"href", icon:"../../images/icon-1.png", href:"../../test_iPhone-RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"url" , icon:"../../images/icon-1.png", url:"../../view-sample.html", transition:"slide"'></li>
+		</ul>
+		<ul id="editableIconContainer3" data-dojo-type="dojox/mobile/IconContainer"
+			data-dojo-props="editable: true">
+			<li id="item3" data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app1", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app2", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app3", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"moveTo", icon:"../../images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"href", icon:"../../images/icon-1.png", href:"../../test_iPhone-RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"url" , icon:"../../images/icon-1.png", url:"../../view-sample.html", transition:"slide"'></li>
+		</ul>
+		<ul id="editableIconContainer4" data-dojo-type="dojox/mobile/IconContainer"
+			data-dojo-props="editable: true">
+			<li id="item4" data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app1", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app2", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"app3", icon:"../../images/icon-1.png", lazy:"true"'><div class="box"></div></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"moveTo", icon:"../../images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"href", icon:"../../images/icon-1.png", href:"../../test_iPhone-RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox/mobile/IconItem" data-dojo-props='label:"url" , icon:"../../images/icon-1.png", url:"../../view-sample.html", transition:"slide"'></li>
+		</ul>
+	</div>
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/iconcontainer/IconContainer_Programmatic.html b/dojox/mobile/tests/doh/iconcontainer/IconContainer_Programmatic.html
new file mode 100644
index 0000000..3c5d347
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconcontainer/IconContainer_Programmatic.html
@@ -0,0 +1,91 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Icon</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/IconContainer.css" rel="stylesheet"/>
+
+		<style>
+			.box {
+				border: 1px solid #A7C0E0;
+				width: 300px;
+				height: 250px;
+				background-image: url(../../images/widget-bg.png);
+				background-repeat: no-repeat;
+				background-color: white;
+			}
+		</style>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.View");
+			dojo.require("dojox.mobile.IconContainer");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+			dojo.require("doh.runner");
+
+			dojo.addOnLoad(function(){
+
+				var view = dijit.byId("foo");
+				var container = new dojox.mobile.IconContainer();
+				var demoWidget = new dojox.mobile.IconItem({label:"app1", icon:"../../images/icon3.png", lazy:"true"});
+//This position works fine.
+//				view.addChild(container);
+				container.placeAt(view.containerNode);
+				container.startup();
+				container.addChild(demoWidget);
+				demoWidget.set("content", '<div class="box"></div>');
+
+				demoWidget = new dojox.mobile.IconItem({label:"app2", icon:"../../images/icon3.png", lazy:"true"});
+				container.addChild(demoWidget);
+				demoWidget.set("content", '<div class="box"></div>');
+
+				demoWidget = new dojox.mobile.IconItem({label:"app3", icon:"../../images/icon3.png", lazy:"true"});
+				demoWidget.set("content", '<div class="box"></div>');
+//This position makes error. //Fixed
+				container.addChild(demoWidget);
+
+				demoWidget = new dojox.mobile.IconItem({label:"moveTo", icon:"../../images/icon3.png", moveTo:"about", transition:"slide"});
+				container.addChild(demoWidget);
+
+				demoWidget = new dojox.mobile.IconItem({label:"href", icon:"../../images/icon3.png", href:"../../test_iPhone-RoundRectList.html", transition:"slide"});
+				container.addChild(demoWidget);
+
+				demoWidget = new dojox.mobile.IconItem({label:"url", icon:"../../images/icon3.png", href:"../../view-sample.html", transition:"slide"});
+				container.addChild(demoWidget);
+//This position makes error.
+//				view.addChild(container);
+//				container.placeAt(view.containerNode);
+//				container.startup();
+			});
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src=IconContainer.js></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
+		</div>
+
+		<div id="about" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Network											   
+				</li>												   
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Line
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="1024">
+					Songs
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/iconcontainer/module.js b/dojox/mobile/tests/doh/iconcontainer/module.js
new file mode 100644
index 0000000..5d08bd1
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconcontainer/module.js
@@ -0,0 +1,12 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.IconContainer", require.toUrl("./IconContainer.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.IconContainer", require.toUrl("./IconContainer2.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.IconContainer", require.toUrl("./IconContainer3.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.IconContainer", require.toUrl("./IconContainer_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.IconContainer", require.toUrl("./IconContainerTests.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.IconContainer", require.toUrl("./IconContainerTests2.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/iconcontainer/runTests.html b/dojox/mobile/tests/doh/iconcontainer/runTests.html
new file mode 100644
index 0000000..78839f2
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconcontainer/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.iconcontainer.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/iconmenu/IconMenuTests.html b/dojox/mobile/tests/doh/iconmenu/IconMenuTests.html
new file mode 100644
index 0000000..c99e728
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconmenu/IconMenuTests.html
@@ -0,0 +1,195 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Accordion Tests</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconMenu']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+	<style type="text/css">
+		@import "../../../themes/common/domButtons/DomButtonBlackRightArrow16.css";
+		@import "../../../themes/common/domButtons/DomButtonWhiteDownArrow16.css";
+		@import "../../../themes/common/dijit/dijit.css";
+		html,body{
+			height: 100%;
+		}
+		.myPane {
+			background-image: -webkit-gradient(linear, left top, left bottom, from(#dcdcdc), to(#FFFFFF));
+			font-family: Times New Roman, Helvetica;
+			color: black;
+		}
+	</style>
+
+	<script type="text/javascript">
+		var WIDGET_PROPS = [{icon:"../../images/tab-icon-36w.png", selected:true},
+							{icon:"../../images/tab-icon-32w.png"},
+							{icon:"../../images/tab-icon-30w.png"},
+							{icon:"../../images/tab-icon-16w.png"},
+							{icon:"../../images/tab-icon-19w.png"},
+							{icon:"../../images/tab-icon-29w.png"}];
+		var WIDGET_LABELS = [{label:"Mute"},
+							{label:"Keypad"},
+							{label:"Settings"},
+							{label:"Info"},
+							{label:"Tour"},
+							{label:"Contacts"}];
+		var WIDGET_CLASS = "mblIconMenu";
+		var WIDGET_ICON_SEL = "mblIconMenuItemSel";
+		var ITEM_NUM = 6;
+		var CHILDWIDGET_CLASSNAME1 = "mblIconMenuItem";
+		var CHILDWIDGET_CLASSNAME2 = "mblIconMenuItemFirstColumn";
+		var CHILDWIDGET_CLASSNAME3 = "mblIconMenuItemLastColumn";
+		var CHILDWIDGET_CLASSNAME4 = "mblIconMenuItemFirstRow";
+		var CHILDWIDGET_CLASSNAME5 = "mblIconMenuItemLastRow";
+		var COL_NUM = 3;
+
+		require([
+			"dojo/_base/array",
+			"dojo/_base/lang", // dojo.mixin
+			"dojo/dom-construct", // dojo.place
+			"dojo/dom-class", // dojo.hasClass
+			"dojo/ready", // dojo.ready
+			"dijit/registry",  // dijit.byId
+			"doh/runner",	//doh functions
+			"dojox/mobile/IconMenuItem",
+			"dojox/mobile/IconMenu",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/View"
+		], function(array, lang, domConst, domClass, ready, registry, runner, IconMenuItem, IconMenu){
+			function _createAccordionDeclaratively(widgetId){
+				return registry.byId(widgetId);
+			}
+			
+			function _createAccordionProgrammatically(placeHolderId, widgetId){
+				var r = new IconMenu({id:widgetId, style:{width:"274px", height:"210px", margin:"20px"}, cols:"3"});
+				runner.assertNotEqual(null, r);
+				domConst.place(r.domNode, placeHolderId, "replace");
+				r.startup();
+				var childWidget, prop;
+				for(var i = 0, len =Math.min(WIDGET_PROPS.length, WIDGET_LABELS.length); i<len ;i++){
+					childWidget = IconMenuItem(lang.mixin(prop, WIDGET_PROPS[i], WIDGET_LABELS[i]));
+					r.addChild(childWidget);
+				}
+				return r;
+			}
+			
+			function _createAccordionProgrammaticallyWithSourceNodeReference(widgetId, childWidgetId){
+				var r = new IconMenu({cols:"3"}, widgetId);
+				r.startup();
+				children = array.filter(r.domNode.childNodes, function(node){ return node.nodeType == 1; });
+				var childWidget;
+				for(var i = 0, len =Math.min(WIDGET_PROPS.length, children.length); i<len ;i++){
+					childWidget = IconMenuItem(WIDGET_PROPS[i], children[i]);
+					r.addChild(childWidget);
+				}
+				return r;
+			}
+
+			function _assertCorrectAccordion(widget){
+				runner.assertEqual(WIDGET_CLASS, widget.domNode.className, "id= " + widget.domNode.id);
+
+				var childWidgets = widget.getChildren();
+				runner.assertEqual(ITEM_NUM, childWidgets.length, "id= " + widget.domNode.id + " childWidgets.length=" + childWidgets.length);
+
+				runner.assertTrue(domClass.contains(childWidgets[0].domNode, WIDGET_ICON_SEL), WIDGET_ICON_SEL + " id=" + childWidgets[0].domNode.id);
+				for(var i=0;i< ITEM_NUM;i++){
+	 				runner.assertEqual(WIDGET_LABELS[i].label, dojo.trim(childWidgets[i].labelNode.innerHTML.replace(/\r\n|\n|\t/g,"")), "id=" + childWidgets[i].domNode.id);
+	 				switch(i % COL_NUM){
+						case 0:
+							runner.assertTrue(domClass.contains(childWidgets[i].domNode, CHILDWIDGET_CLASSNAME2), CHILDWIDGET_CLASSNAME2 + " id=" + childWidgets[i].domNode.id);
+							break;
+						case (COL_NUM-1):
+							runner.assertTrue(domClass.contains(childWidgets[i].domNode, CHILDWIDGET_CLASSNAME3), CHILDWIDGET_CLASSNAME3 + " id=" + childWidgets[i].domNode.id);
+							break;
+					}
+	 				switch(Math.floor(i / COL_NUM)){
+						case 0:
+							runner.assertTrue(domClass.contains(childWidgets[i].domNode, CHILDWIDGET_CLASSNAME4), CHILDWIDGET_CLASSNAME4 + " id=" + childWidgets[i].domNode.id);
+							break;
+						case (Math.floor(ITEM_NUM/COL_NUM) -1):
+							runner.assertTrue(domClass.contains(childWidgets[i].domNode, CHILDWIDGET_CLASSNAME5), CHILDWIDGET_CLASSNAME5 + " id=" + childWidgets[i].domNode.id);
+							break;
+					}
+				}
+			}
+
+			function _showView2(){
+				var view1 = registry.byId("view1");
+				view1.performTransition("view2", 1, "none");
+			}
+			dojo.ready(function(){
+				doh.register("dojox.mobile.test.doh.AccordionTests", [
+					function testInView1(){
+						var widget1 = _createAccordionDeclaratively("dojox_mobile_IconMenu_0");
+						var widget2 = _createAccordionProgrammatically("view1-IconMenu2place", "view1-IconMenu2");
+						var widget3 = _createAccordionProgrammaticallyWithSourceNodeReference("view1-IconMenu3");
+
+						_assertCorrectAccordion(widget1);
+						_assertCorrectAccordion(widget2);
+						_assertCorrectAccordion(widget3);
+					},
+					function testInView2(){
+						var widget1 = _createAccordionDeclaratively("dojox_mobile_IconMenu_1");
+						var widget2 = _createAccordionProgrammatically("view2-IconMenu2place", "view2-IconMenu2place");
+						var widget3 = _createAccordionProgrammaticallyWithSourceNodeReference("view2-IconMenu3");
+
+						_showView2();
+
+						_assertCorrectAccordion(widget1);
+						_assertCorrectAccordion(widget2);
+						_assertCorrectAccordion(widget3);
+					}
+				]);
+				runner.run();
+			});
+		})
+	</script>
+
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1>View 1</h1>
+		<ul data-dojo-type="dojox.mobile.IconMenu" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:3'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Mute", icon:"../../images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Keypad", icon:"../../images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Settings", icon:"../../images/tab-icon-30w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Info", icon:"../../images/tab-icon-16w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Tour", icon:"../../images/tab-icon-19w.png", moveTo:"view2", transition:"slide", closeOnAction:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Contacts", icon:"../../images/tab-icon-29w.png"'></li>
+		</ul>
+		<div id="view1-IconMenu2place"></div>
+		<div id="view1-IconMenu3" style="width:274px;height:210px;margin:20px;" >
+			<li>Mute</li>
+			<li>Keypad</li>
+			<li>Settings</li>
+			<li>Info</li>
+			<li>Tour</li>
+			<li>Contacts</li>
+		</div>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<ul data-dojo-type="dojox.mobile.IconMenu" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:3'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Mute", icon:"../../images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Keypad", icon:"../../images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Settings", icon:"../../images/tab-icon-30w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Info", icon:"../../images/tab-icon-16w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Tour", icon:"../../images/tab-icon-19w.png", moveTo:"view2", transition:"slide", closeOnAction:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Contacts", icon:"../../images/tab-icon-29w.png"'></li>
+		</ul>
+		<div id="view2-IconMenu2place"></div>
+		<div id="view2-IconMenu3" style="width:274px;height:210px;margin:20px;" >
+			<li>Mute</li>
+			<li>Keypad</li>
+			<li>Settings</li>
+			<li>Info</li>
+			<li>Tour</li>
+			<li>Contacts</li>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/iconmenu/module.js b/dojox/mobile/tests/doh/iconmenu/module.js
new file mode 100644
index 0000000..24debf8
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconmenu/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.IconMenu", require.toUrl("./IconMenuTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/iconmenu/runTests.html b/dojox/mobile/tests/doh/iconmenu/runTests.html
new file mode 100644
index 0000000..3b72378
--- /dev/null
+++ b/dojox/mobile/tests/doh/iconmenu/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.iconmenu.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/index.html b/dojox/mobile/tests/doh/index.html
index bb4ce30..a749612 100644
--- a/dojox/mobile/tests/doh/index.html
+++ b/dojox/mobile/tests/doh/index.html
@@ -2,46 +2,55 @@
 <html>
 	<head>
 		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<title>dojox.mobile</title>
+		<title>dojox.mobile tests</title>
 	</head>
 	<body>
-		<a href="Button.html">Button.html</a><br>
-		<a href="Button_Programmatic.html">Button_Programmatic.html</a><br>
-		<a href="EdgeToEdgeCategory.html">EdgeToEdgeCategory.html</a><br>
-		<a href="EdgeToEdgeDataList.html">EdgeToEdgeDataList.html</a><br>
-		<a href="EdgeToEdgeDataList_Programmatic.html">EdgeToEdgeDataList_Programmatic.html</a><br>
-		<a href="Heading.html">Heading.html</a><br>
-		<a href="Heading2.html">Heading2.html</a><br>
-		<a href="Heading_Programmatic.html">Heading_Programmatic.html</a><br>
-		<a href="Heading2_Programmatic.html">Heading2_Programmatic.html</a><br>
-		<a href="IconContainer.html">IconContainer.html</a><br>
-		<a href="IconContainer2.html">IconContainer2.html</a><br>
-		<a href="IconContainer3.html">IconContainer3.html</a><br>
-		<a href="IconContainer_Programmatic.html">IconContainer_Programmatic.html</a><br>
-		<a href="ListItem.html">ListItem.html</a><br>
-		<a href="ListItem2.html">ListItem2.html</a><br>
-		<a href="ListItem_Programmatic.html">ListItem_Programmatic.html</a><br>
-		<a href="ListItem2_Programmatic.html">ListItem2_Programmatic.html</a><br>
-		<a href="progress-indicator.html">progress-indicator.html</a><br>
-		<a href="RoundRect.html">RoundRect.html</a><br>
-		<a href="RoundRect_Programmatic.html">RoundRect_Programmatic.html</a><br>
-		<a href="RoundRectDataList.html">RoundRectDataList.html</a><br>
-		<a href="RoundRectDataList_Programmatic.html">RoundRectDataList_Programmatic.html</a><br>
-		<a href="RoundRectList.html">RoundRectList.html</a><br>
-		<a href="RoundRectList_Programmatic.html">RoundRectList_Programmatic.html</a><br>
-		<a href="Switch.html">Switch.html</a><br>
-		<a href="Switch_Programmatic.html">Switch_Programmatic.html</a><br>
-		<a href="TabBar.html">TabBar.html</a><br>
-		<a href="TabBar_Programmatic.html">TabBar_Programmatic.html</a><br>
-		<a href="ToolBarButton.html">ToolBarButton.html</a><br>
-		<a href="ToolBarButton_Programmatic.html">ToolBarButton_Programmatic.html</a><br>
-		<a href="View.html">View.html</a><br>
-		<a href="View_Programmatic.html">View_Programmatic.html</a><br>
-		<a href="View2_Programmatic.html">View2_Programmatic.html</a><br>
-		<a href="View3_Programmatic.html">View3_Programmatic.html</a><br>
-		<a href="View-demo.html">View-demo.html</a><br>
+		<h1>Click the test module to run, or click "Run all tests" at the end of the list:</h1>
+		<a target="_test" href="accordion/runTests.html">Accordion</a><br>
+		<a target="_test" href="badge/runTests.html">Badge</a><br>
+		<a target="_test" href="bidi/runTests.html">Bidi</a><br>
+		<a target="_test" href="button/runTests.html">Button</a><br>
+		<a target="_test" href="checkbox/runTests.html">CheckBox</a><br>
+		<a target="_test" href="combobox/runTests.html">ComboBox</a><br>
+		<a target="_test" href="contentpane/runTests.html">ContentPane</a><br>
+		<a target="_test" href="edgetoedgecategory/runTests.html">EdgeToEdgeCategory</a><br>
+		<a target="_test" href="edgetoedgedatalist/runTests.html">EdgeToEdgeDataList</a><br>
+		<a target="_test" href="edgetoedgelist/runTests.html">EdgeToEdgeList</a><br>
+		<a target="_test" href="edgetoedgestorelist/runTests.html">EdgeToEdgeStoreList</a><br>
+		<a target="_test" href="expandingtextarea/runTests.html">ExpandingTextArea</a><br>
+		<a target="_test" href="filteredlistmixin/runTests.html">FilteredListMixin</a><br>
+		<a target="_test" href="fixedbars/runTests.html">FixedBars</a><br>
+		<a target="_test" href="fixedsplitter/runTests.html">FixedSplitter</a><br>
+		<a target="_test" href="heading/runTests.html">Heading</a><br>
+		<a target="_test" href="iconcontainer/runTests.html">IconContainer</a><br>
+		<a target="_test" href="iconmenu/runTests.html">IconMenu</a><br>
+		<a target="_test" href="listitem/runTests.html">ListItem</a><br>
+		<a target="_test" href="longlistmixin/runTests.html">LongListMixin</a><br>
+		<a target="_test" href="opener/runTests.html">Opener</a><br>
+		<a target="_test" href="pageindicator/runTests.html">PageIndicator</a><br>
+		<a target="_test" href="progressindicator/runTests.html">ProgressIndicator</a><br>
+		<a target="_test" href="radiobutton/runTests.html">RadioButton</a><br>
+		<a target="_test" href="roundrect/runTests.html">RoundRect</a><br>
+		<a target="_test" href="roundrectdatalist/runTests.html">RoundRectDataList</a><br>
+		<a target="_test" href="roundrectlist/runTests.html">RoundRectList</a><br>
+		<a target="_test" href="roundrectstorelist/runTests.html">RoundRectStoreList</a><br>
+		<a target="_test" href="scrollablepane/runTests.html">ScrollablePane</a><br>
+		<a target="_test" href="slider/runTests.html">Slider</a><br>
+		<a target="_test" href="spinwheel/runTests.html">SpinWheel</a><br>
+		<a target="_test" href="spinwheeldatepicker/runTests.html">SpinWheelDatePicker</a><br>
+		<a target="_test" href="swapview/runTests.html">SwapView</a><br>
+		<a target="_test" href="switch/runTests.html">Switch</a><br>
+		<a target="_test" href="tabbar/runTests.html">TabBar</a><br>
+		<a target="_test" href="templating/runTests.html">templating</a><br>
+		<a target="_test" href="textarea/runTests.html">TextArea</a><br>
+		<a target="_test" href="textbox/runTests.html">TextBox</a><br>
+		<a target="_test" href="toolbarbutton/runTests.html">ToolBarButton</a><br>
+		<a target="_test" href="transition/runTests.html">transitions</a><br>
+		<a target="_test" href="valuepickerdatepicker/runTests.html">ValuePickerDatePicker</a><br>
+		<a target="_test" href="valuepickertimepicker/runTests.html">ValuePickerTimePicker</a><br>
+		<a target="_test" href="view/runTests.html">View</a><br>
 		<hr>
-		<a href="runTests.html">runTests.html</a><br>
+		<a target="_test" href="runTests.html">Run all tests</a><br>
 	
 
-</body></html>
\ No newline at end of file
+</body></html>
diff --git a/dojox/mobile/tests/doh/listitem/CreateListItem2_Programmatic.js b/dojox/mobile/tests/doh/listitem/CreateListItem2_Programmatic.js
new file mode 100644
index 0000000..d068c25
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/CreateListItem2_Programmatic.js
@@ -0,0 +1,21 @@
+dojo.addOnLoad(function(){
+	var view = dijit.byId("foo");
+
+	var list = new dojox.mobile.RoundRectList({iconBase:"../../images/i-icon-all.png"});
+	view.addChild(list);
+
+	var demoWidget = new dojox.mobile.ListItem({iconPos:"0,87,29,29", moveTo:"general", label:"Sounds"});
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({iconPos:"0,116,29,29", moveTo:"general", label:"Brightness"});
+	list.addChild(demoWidget);
+
+	list = new dojox.mobile.EdgeToEdgeList({iconBase:"../../images/i-icon-all.png"});
+	demoWidget = new dojox.mobile.ListItem({iconPos:"0,87,29,29", rightIcon:"mblDomButtonBluePlus", label:"XX Widget"});
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({iconPos:"0,116,29,29", rightIcon:"mblDomButtonRedMinus", label:"YY Widget"});
+	list.addChild(demoWidget);
+
+	view.addChild(list);
+});
diff --git a/dojox/mobile/tests/doh/listitem/CreateListItem_Programmatic.js b/dojox/mobile/tests/doh/listitem/CreateListItem_Programmatic.js
new file mode 100644
index 0000000..5346ae7
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/CreateListItem_Programmatic.js
@@ -0,0 +1,52 @@
+dojo.addOnLoad(function(){
+	var list = dijit.byId("dojox_mobile_RoundRectList_0");
+	var demoWidget = new dojox.mobile.ListItem({icon:"../../images/i-icon-1.png", transition:"slide", url:"../../view1.html", label:"External View #1 (sync)"});
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({icon:"../../images/i-icon-2.png", transition:"flip", url:"../../view2.html", sync:false, label:"External View #2 (async)"});
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({icon:"../../images/i-icon-3.png", transition:"fade", url:"../../view3.html", label:"External View #3 (sync)"});
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({rightText:"Off", label:"Video"});
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({icon:"../../images/i-icon-1.png", rightText:"VPN", label:"Maps"});
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({label:"Jack Coleman"});
+	list.addChild(demoWidget);
+
+	list = dijit.byId("dojox_mobile_RoundRectList_1");
+	demoWidget = new dojox.mobile.ListItem({iconPos:"0,87,29,29", moveTo:"general", label:"Sounds"});
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({iconPos:"0,116,29,29", moveTo:"general", label:"Brightness"});
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({iconPos:"29,0,29,29", moveTo:"general", label:"Wallpaper"});
+	list.addChild(demoWidget);
+
+	list = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
+	demoWidget = new dojox.mobile.ListItem({icon:"../../images/i-icon-1.png", rightIcon:"mblDomButtonBluePlus", label:"XX Widget"});
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({icon:"../../images/i-icon-2.png", rightIcon:"mblDomButtonRedMinus", label:"YY Widget"});
+	list.addChild(demoWidget);
+
+	list = dijit.byId("dojox_mobile_EdgeToEdgeList_1");
+	demoWidget = new dojox.mobile.ListItem({rightIcon:"mblDomButtonCheckboxOff", variableHeight:"true"});
+	dojo.create(dojo.doc.createTextNode("Use wireless networks"), null, demoWidget.labelNode, "before");
+	var child = dojo.create("DIV", {className:"mblListItemSubText"}, demoWidget.labelNode, "before");
+	child.appendChild(dojo.doc.createTextNode("See location in applications (such as Maps) using wireless networks"));
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({rightIcon:"mblDomButtonCheckboxOn", variableHeight:"true"});
+	dojo.create(dojo.doc.createTextNode("Use GPS satellites"), null, demoWidget.labelNode, "before");
+	child = dojo.create("DIV", {className:"mblListItemSubText", innerHTML:"When locating, accurate to street level (uncheck to conserve battery)"}, demoWidget.labelNode, "before");
+	list.addChild(demoWidget);
+
+	demoWidget = new dojox.mobile.ListItem({label:" Set unlock pattern"});
+	list.addChild(demoWidget);
+});
diff --git a/dojox/mobile/tests/doh/listitem/ListItem.html b/dojox/mobile/tests/doh/listitem/ListItem.html
new file mode 100644
index 0000000..a672635
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/ListItem.html
@@ -0,0 +1,61 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>ListItem</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons/DomButtonColorButtons.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons/DomButtonCheckboxOn.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons/DomButtonCheckboxOff.css" rel="stylesheet"/>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="ListItem.js"></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" transition="slide" url="../../view1.html">External View #1 (sync)</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-2.png" transition="flip" url="../../view2.html" sync="false">External View #2 (async)</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-3.png" transition="fade" url="../../view3.html">External View #3 (sync)</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">Video</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightText="VPN">Maps</li>
+				<li dojoType="dojox.mobile.ListItem">Jack Coleman</li>
+			</ul>
+			<ul dojoType="dojox.mobile.RoundRectList" iconBase="../../images/i-icon-all.png">
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">Sounds</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" moveTo="general">Brightness</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29" moveTo="general">Wallpaper</li>
+			</ul>
+			<ul id="list1" dojoType="dojox.mobile.EdgeToEdgeList">
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightIcon="mblDomButtonBluePlus">XX Widget</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-2.png" rightIcon="mblDomButtonRedMinus">YY Widget</li>
+			</ul>
+		    <ul id="list2" dojoType="dojox.mobile.EdgeToEdgeList">
+			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" rightIcon="mblDomButtonCheckboxOff">
+					Use wireless networks
+					<div class="mblListItemSubText">
+						See location in applications (such as Maps) using wireless networks
+					</div>
+			    </li>
+			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" rightIcon="mblDomButtonCheckboxOn">
+					Use GPS satellites
+					<div class="mblListItemSubText">
+						When locating, accurate to street level (uncheck to conserve battery)
+					</div>
+			    </li>
+			    <li dojoType="dojox.mobile.ListItem">
+					Set unlock pattern
+			    </li>
+		    </ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/listitem/ListItem.js b/dojox/mobile/tests/doh/listitem/ListItem.js
new file mode 100644
index 0000000..ecb4706
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/ListItem.js
@@ -0,0 +1,134 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.ListItem", [
+		{
+			name: "ListItem Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					verifyListItem("dojox_mobile_ListItem_0", 'External View #1 (sync)', '', "mblDomButtonArrow", true, true, false, false, /i-icon-1.png/i);
+					verifyListItem("dojox_mobile_ListItem_1", 'External View #2 (async)', '', "mblDomButtonArrow", true, true, false);
+					verifyListItem("dojox_mobile_ListItem_2", 'External View #3 (sync)', '', "mblDomButtonArrow", true, true, false);
+					verifyListItem("dojox_mobile_ListItem_3", 'Video', 'Off', "", false, false, false);
+					verifyListItem("dojox_mobile_ListItem_4", 'Maps', 'VPN', "", true, false, false);
+					verifyListItem("dojox_mobile_ListItem_5", 'Jack Coleman', '', "", false, false, false);
+					verifyListItem("dojox_mobile_ListItem_6", 'Sounds', '', "mblDomButtonArrow", true, true, false);
+					verifyListItem("dojox_mobile_ListItem_7", 'Brightness', '', "mblDomButtonArrow", true, true, false);
+					verifyListItem("dojox_mobile_ListItem_8", 'Wallpaper', '', "mblDomButtonArrow", true, true, false);
+					verifyListItem("dojox_mobile_ListItem_9", 'XX Widget', '', "mblDomButtonBluePlus", true, true, false);
+					verifyListItem("dojox_mobile_ListItem_10", 'YY Widget', '', "mblDomButtonRedMinus", true, true, false);
+					
+					var txt = 'See location in applications (such as Maps) using wireless networks';
+					verifyListItem("dojox_mobile_ListItem_11", txt, '', "mblDomButtonCheckboxOff", false, true, false, true);
+					
+					txt = 'When locating, accurate to street level (uncheck to conserve battery)';
+					verifyListItem("dojox_mobile_ListItem_12", txt, '', "mblDomButtonCheckboxOn", false, true, false, true);
+
+					verifyListItem("dojox_mobile_ListItem_13", 'Set unlock pattern', '', "", false, false, false);
+				}));
+				return d;
+			}
+		},
+		{
+			name: "ListItem set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_ListItem_0");
+				demoWidget.set({transition :"flip", url:"../../view2.html", noArrow:true, selected:true, anchorLabel:true, rightText:"Value Changed"});
+				doh.assertEqual("flip", demoWidget.get("transition"));
+				doh.assertEqual("../../view2.html", demoWidget.get("url"));
+				doh.assertTrue(demoWidget.get("noArrow"), 'get("noArrow")');
+				doh.assertTrue(demoWidget.get("selected"), 'get("selected")');
+				doh.assertTrue(demoWidget.get("anchorLabel"), 'get("anchorLabel")');
+				doh.assertEqual("Value Changed", demoWidget.get("rightText"));
+
+				verifyListItem("dojox_mobile_ListItem_0", 'External View #1 (sync)', 'Value Changed', "mblDomButtonArrow", true, true, false, false, null, true);
+			}
+		},
+		{
+			name: "ListItem set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_ListItem_1");
+				demoWidget.set({icon :"../../images/i-icon-4.png", label:"Value Changed", clickable:true, url:"../../view3.html", transition :"slide", transitionDir:-1, sync:false, toggle:true, _duration:1600});
+
+				doh.assertEqual("slide", demoWidget.get("transition"));
+				doh.assertEqual("../../view3.html", demoWidget.get("url"));
+				doh.assertEqual(-1, demoWidget.get("transitionDir"));
+				doh.assertTrue(demoWidget.get("clickable"), 'get("clickable")');
+				doh.assertFalse(demoWidget.get("sync"), 'get("sync")');
+				doh.assertTrue(demoWidget.get("toggle"), 'get("toggle")');
+				doh.assertEqual(1600, demoWidget.get("_duration"));
+				doh.assertEqual("Value Changed", demoWidget.get("label"));
+
+				verifyListItem("dojox_mobile_ListItem_1", 'Value Changed', '', "mblDomButtonArrow", true, true, false, false, /i-icon-4.png/i);
+			}
+		},
+		{
+			name: "ListItem set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_ListItem_6");
+				demoWidget.set({iconPos :"0,116,29,29", moveTo:"bar", transition :"fade"});
+
+				doh.assertEqual("bar", demoWidget.get("moveTo"));
+				doh.assertEqual("0,116,29,29", demoWidget.get("iconPos"));
+				doh.assertEqual("fade", demoWidget.get("transition"));
+
+				verifyListItem("dojox_mobile_ListItem_6", 'Sounds', '', "mblDomButtonArrow", true, true, false, false, /i-icon-all.png/i, false, true);
+			}
+		},
+		{
+
+//Todo
+			name: "ListItem set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_ListItem_6");
+				demoWidget.set({href :"", hrefTarget:""});
+
+				doh.assertEqual("", demoWidget.get("href"));
+				doh.assertEqual("", demoWidget.get("hrefTarget"));
+
+			}
+		},
+		{
+			name: "ListItem set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_ListItem_9");
+				demoWidget.set({rightIcon:"mblDomButtonRedMinus"});
+				verifyListItem("dojox_mobile_ListItem_9", 'XX Widget', '', "mblDomButtonRedMinus", true, true, false);
+//							doh.assertEqual("mblDomButtonRedMinus", demoWidget.get("icon"));
+			}
+		},
+		{
+			name: "ListItem set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_ListItem_11");
+				demoWidget.set({rightIcon:"mblDomButtonCheckboxOn"});
+
+				var txt = 'See location in applications (such as Maps) using wireless networks';
+				verifyListItem("dojox_mobile_ListItem_11", txt, '', "mblDomButtonCheckboxOn", false, true, false, true);
+//							doh.assertEqual("mblDomButtonCheckboxOn", demoWidget.get("icon"));
+			}
+		},
+		{
+			name: "ListItem set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_ListItem_11");
+				// Test case for #16314
+				var noError = true;
+				try{
+					demoWidget.set("busy", false);
+				}catch(err){
+					noError = false; 
+				}
+				doh.assertTrue(noError, "Setting busy to false before ever being set to true shouldn't throw an exception!");
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/listitem/ListItem2.html b/dojox/mobile/tests/doh/listitem/ListItem2.html
new file mode 100644
index 0000000..24f9e93
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/ListItem2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>ListItem</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/IconContainer.css" rel="stylesheet"/>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="ListItem2.js"></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<ul dojoType="dojox.mobile.RoundRectList" iconBase="../../images/i-icon-all.png">
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">Sounds</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" moveTo="general">Brightness</li>
+			</ul>
+			<ul dojoType="dojox.mobile.EdgeToEdgeList" iconBase="../../images/i-icon-all.png">
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" rightIcon="mblDomButtonBluePlus">XX Widget</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" rightIcon="mblDomButtonRedMinus">YY Widget</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/listitem/ListItem2.js b/dojox/mobile/tests/doh/listitem/ListItem2.js
new file mode 100644
index 0000000..7f51efd
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/ListItem2.js
@@ -0,0 +1,46 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.ListItem", [
+		{
+			name: "ListItem Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+
+					verifyListItem("dojox_mobile_ListItem_0", 'Sounds', '', "mblDomButtonArrow", true, true, false, false, /i-icon-all.png/i, false, true);
+					verifyListItemPos("dojox_mobile_ListItem_0", "0px", "116px", "29px", "87px", "0px", "-87px", true);
+
+					verifyListItem("dojox_mobile_ListItem_1", 'Brightness', '', "mblDomButtonArrow", true, true, false, false, /i-icon-all.png/i, false, true);
+					verifyListItemPos("dojox_mobile_ListItem_1", "0px", "145px", "29px", "116px", "0px", "-116px", true);
+
+					verifyListItem("dojox_mobile_ListItem_2", 'XX Widget', '', "mblDomButtonBluePlus", true, true, false, false, /i-icon-all.png/i, false, true);
+					verifyListItemPos("dojox_mobile_ListItem_2", "0px", "116px", "29px", "87px", "0px", "-87px", true);
+
+					verifyListItem("dojox_mobile_ListItem_3", 'YY Widget', '', "mblDomButtonRedMinus", true, true, false, false, /i-icon-all.png/i, false, true);
+					verifyListItemPos("dojox_mobile_ListItem_3", "0px", "145px", "29px", "116px", "0px", "-116px", true);
+				}));
+				return d;
+			}
+		},
+		{
+			name: "ListItem set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_RoundRectList_0");
+				demoWidget.set({iconBase :""});
+				doh.assertEqual("", demoWidget.get("iconBase"));
+
+				verifyListItem("dojox_mobile_ListItem_0", 'Sounds', '', "mblDomButtonArrow", true, true, false, false, /i-icon-all.png/i, false, true);
+				verifyListItemPos("dojox_mobile_ListItem_0", "0px", "116px", "29px", "87px", "0px", "-87px", true);
+
+				demoWidget = dijit.byId("dojox_mobile_EdgeToEdgeList_0");
+				demoWidget.set({iconBase :""});
+				doh.assertEqual("", demoWidget.get("iconBase"));
+
+				verifyListItem("dojox_mobile_ListItem_2", 'XX Widget', '', "mblDomButtonBluePlus", true, true, false, false, /i-icon-all.png/i, false, true)
+				verifyListItemPos("dojox_mobile_ListItem_2", "0px", "116px", "29px", "87px", "0px", "-87px", true);
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/listitem/ListItem2_Programmatic.html b/dojox/mobile/tests/doh/listitem/ListItem2_Programmatic.html
new file mode 100644
index 0000000..3910637
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/ListItem2_Programmatic.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>ListItem</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+
+		<script type="text/javascript" src="CreateListItem2_Programmatic.js"></script>
+
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="ListItem2.js"></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/listitem/ListItem3_Programmatic.html b/dojox/mobile/tests/doh/listitem/ListItem3_Programmatic.html
new file mode 100644
index 0000000..e7ebb8d
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/ListItem3_Programmatic.html
@@ -0,0 +1,218 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>ListItem Programmatic 3</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" 
+	data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	require([
+		"dojox/mobile/parser",
+		"dojo/ready",
+		"dijit/registry",
+		"doh/runner",
+		"dojox/mobile/Heading",
+		"dojox/mobile/ListItem",
+		"dojox/mobile",
+		"dojox/mobile/View",
+		"dojox/mobile/compat"
+	], function(parser, ready, registry, runner, Heading, ListItem){
+
+		// This main purpose of this test is to check the correct handling of 
+		// calls AFTER startup of setters for the following properties of ListItem:
+		// clickable, moveTo, href, url, and the property _selStartMethod of _ItemBase. 
+		// Their value impacts the way ListItem treats the click events. We test it
+		// by directly checking item._handleClick and item._onTouchStartHandle.
+		// Trac: #16133.
+		
+		// 1. ListItem with "clickable" set at false via the constructor
+		function _createListItem1(){
+			var list = registry.byId("list");
+			var item = new ListItem({clickable: false});
+			list.addChild(item);
+			return item;
+		};
+		
+		// 2. ListItem with "clickable" set at true via the constructor
+		function _createListItem2(){
+			var list = registry.byId("list");
+			var item = new ListItem({clickable: true});
+			list.addChild(item);
+			return item;
+		};
+		
+		// 3. ListItem created with "clickable" at true and set at false before startup
+		function _createListItem3(){
+			var list = registry.byId("list");
+			var item = new ListItem({clickable: true});
+			item.set("clickable", false); // before startup
+			list.addChild(item);
+			return item;
+		};
+		
+		// 4. ListItem created with "clickable" at true and set at false after startup
+		function _createListItem4(){
+			var list = registry.byId("list");
+			var item = new ListItem({clickable: true});
+			list.addChild(item);
+			item.set("clickable", false); // after startup
+			return item;
+		};
+		
+		// 5. ListItem created with "clickable" at true and set at false after startup
+		function _createListItem5(){
+			var list = registry.byId("list");
+			var item = new ListItem({clickable: true});
+			list.addChild(item);
+			item.set("clickable", false); // after startup
+			item.set("_selStartMethod", "none");
+			return item;
+		};
+		
+		// 6. ListItem created with "clickable" at false and moveTo set after startup
+		function _createListItem6(){
+			var list = registry.byId("list");
+			var item = new ListItem({clickable: false});
+			list.addChild(item);
+			item.set("moveTo", "view2"); // after startup
+			return item;
+		};
+		
+		// 7. ListItem created with "clickable" at false and href set after startup
+		function _createListItem7(){
+			var list = registry.byId("list");
+			var item = new ListItem({clickable: false});
+			list.addChild(item);
+			item.set("href", "someurl"); // after startup
+			return item;
+		};
+		
+		// 8. ListItem created with "clickable" at false and url set after startup
+		function _createListItem8(){
+			var list = registry.byId("list");
+			var item = new ListItem({clickable: false});
+			list.addChild(item);
+			item.set("url", "someurl"); // after startup
+			return item;
+		};
+		
+		function _assertCorrectListItem(widget, expectedValueOfClickable, 
+										expectedValueOfSelStartMethod, caseName){
+			runner.assertEqual(expectedValueOfClickable, widget.get("clickable"), 
+				"Unexpected value of clickable for " + caseName);
+			runner.assertEqual(expectedValueOfSelStartMethod, widget.get("_selStartMethod"), 
+				"Unexpected value of _selStartMethod for " + caseName);	
+			
+			// ListItem sets _handleClick at true if any of the properties 
+			//    clickable, moveTo, href, and url
+			// is set to a non-empty/null value. 
+			if(widget.get("clickable") || widget.get("moveTo") || widget.get("href") || widget.get("url")){
+				runner.assertTrue(widget._handleClick, 
+					"'item._handleClick' should be true for " + caseName);
+				if(widget.get("_selStartMethod") === "touch"){
+					runner.assertNotEqual(null, widget._onTouchStartHandle,
+						"'item._onTouchStartHandle' should not be null for " + caseName);
+				}
+			}else{
+				runner.assertFalse(widget._handleClick, 
+					"'item._handleClick' should be false for " + caseName);
+				runner.assertEqual(null, widget._onTouchStartHandle, 
+					"'item._onTouchStartHandle' should be null for " + caseName);			
+			}
+		};
+		
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.ListItem3_Programmatic", [
+				{
+					name: "ListItem3_Programmatic for ListItem created with clickable at false",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createListItem1();
+						_assertCorrectListItem(widget, false, "touch", 
+							"ListItem created with clickable at false");
+					}
+				},
+				{
+					name: "ListItem3_Programmatic for ListItem created with clickable at true",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createListItem2();
+						_assertCorrectListItem(widget, true, "touch", 
+							"ListItem created with clickable at true");
+					}
+				},
+				{
+					name: "ListItem3_Programmatic for ListItem created with clickable at true and set at false before startup",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createListItem3();
+						_assertCorrectListItem(widget, false, "touch", 
+							"ListItem created with clickable at true and set at false before startup");
+					}
+				},
+				{
+					name: "ListItem3_Programmatic for ListItem created with clickable at true and set at false after startup",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createListItem4();
+						_assertCorrectListItem(widget, false, "touch", 
+							"ListItem created with clickable at true and set at false after startup");
+					}
+				},
+				{
+					name: "ListItem3_Programmatic for ListItem created with clickable at true and set at false after startup " +
+							"while _selStartMethod is set at none",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createListItem5();
+						_assertCorrectListItem(widget, false, "none", 
+							"ListItem created with clickable at true and set at false " + 
+							"after startup while _selStartMethod is set at none");
+					}
+				},
+				{
+					name: "ListItem3_Programmatic for ListItem created with clickable at false and moveTo set after startup",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createListItem6();
+						_assertCorrectListItem(widget, false, "touch", 
+							"ListItem created with clickable at false and moveTo set after startup");
+					}
+				},
+				{
+					name: "ListItem3_Programmatic for ListItem created with clickable at false and href set after startup",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createListItem7();
+						_assertCorrectListItem(widget, false, "touch", 
+							"ListItem created with clickable at false and href set after startup");
+					}
+				},
+				{
+					name: "ListItem3_Programmatic for ListItem created with clickable at false and url set after startup",
+					timeout: 2000,
+					runTest: function(){
+						var widget = _createListItem8();
+						_assertCorrectListItem(widget, false, "touch", 
+							"ListItem created with clickable at false and url set after startup");
+					}
+				}
+			]);
+			runner.run();
+		});
+	});
+</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox/mobile/View" selected="true">
+		<h1 data-dojo-type="dojox/mobile/Heading">RoundRectList</h1>
+		<ul id="list" data-dojo-type="dojox/mobile/RoundRectList">
+		</ul>
+	</div>
+	<div id="view2" data-dojo-type="dojox/mobile/View">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/listitem/ListItemTests.js b/dojox/mobile/tests/doh/listitem/ListItemTests.js
new file mode 100644
index 0000000..1ed9ecf
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/ListItemTests.js
@@ -0,0 +1,150 @@
+var WIDGET_CLASSNAME1 = "mblListItem";
+var WIDGET_ANCHOR_CLASSNAME1 = "mblListItemAnchor";
+var WIDGET_ANCHOR_CLASSNAME2 = "mblListItemAnchorNoIcon";
+var WIDGET_ICON_CLASSNAME1 = "mblListItemIcon";
+var WIDGET_RIGHTICON_CLASSNAME1 = "mblListItemRightIcon";
+var WIDGET_DOMBUTTON_ARROW = "mblDomButtonArrow";
+var WIDGET_DOMBUTTON_BLUEPLUS = "mblDomButtonBluePlus";
+var WIDGET_DOMBUTTON_CHECKBOX_ON = "mblDomButtonCheckboxOn";
+
+require([
+	"dojo/_base/connect",
+	"dojo/dom-class", // dojo.hasClass
+	"dojo/ready", // dojo.ready
+	"dijit/registry",  // dijit.byId
+	"dojo/string", // dojo.trim
+	"doh/runner",	//doh functions
+	"dojox/mobile/ListItem",
+	"dojox/mobile/RoundRectList",
+	"dojox/mobile/EdgeToEdgeList",
+	"dojox/mobile",				// This is a mobile app.
+	"dojox/mobile/View",		// This mobile app uses mobile view
+	"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+	"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+], function(connect, domClass, ready, registry, string, runner, ListItem){
+
+
+	function _createListItemDeclaratively(widgetId) {
+		return registry.byId(widgetId);
+	};
+
+	function _createListItemProgrammatically(parentId, widgetId){
+		// Create SwapView
+		parentWidget = registry.byId(parentId);;
+		runner.assertNotEqual(null, parentWidget, "No parentWidget id=" + parentId);
+		var r;
+		r = new ListItem({id:widgetId[0], icon:"../../images/i-icon-1.png", rightText:"Off", moveTo:"bar", label:"u1space"});
+		parentWidget.addChild(r);
+		r = new ListItem({id:widgetId[1], label:"u2space"});
+		parentWidget.addChild(r);
+		r = new ListItem({id:widgetId[2], rightIcon:"mblDomButtonBluePlus", label:"Wi-Fi"});
+		parentWidget.addChild(r);
+		r = new ListItem({id:widgetId[3], rightIcon:"mblDomButtonCheckboxOn", label:"VPN"});
+		parentWidget.addChild(r);
+		r = new ListItem({id:widgetId[4], variableHeight:"true", style:"font-size:10px", label:'<div>1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>Sarah Connor Hardcover<br>Eligible for FREE Super Saver Shipping<br><font color="red">$14.50 (50%)</font> In Stock<br># (531)</div>'});
+		parentWidget.addChild(r);
+		
+		return parentWidget;
+	};
+
+	function _createListItemProgrammaticallyWithSourceNodeReference(widgetId){
+		// Create IconContainer
+		var r;
+		r = new ListItem({icon:"../../images/i-icon-1.png", rightText:"Off", moveTo:"bar"}, widgetId[0]);
+		r.startup();
+		r = new ListItem({}, widgetId[1]);
+		r.startup();
+		r = new ListItem({rightIcon:"mblDomButtonBluePlus"}, widgetId[2]);
+		r.startup();
+		r = new ListItem({rightIcon:"mblDomButtonCheckboxOn"}, widgetId[3]);
+		r.startup();
+		r = new ListItem({variableHeight:"true"}, widgetId[4]);
+		r.startup();
+
+		return r;
+	};
+
+
+
+	function _assertCorrectListItems(widgetId){
+		_assertCorrectListItem(widgetId[0], false, WIDGET_DOMBUTTON_ARROW, "", "Off", "u1space");
+		_assertCorrectListItem(widgetId[1], true, "", "", "", "u2space");
+		_assertCorrectListItem(widgetId[2], true, WIDGET_DOMBUTTON_BLUEPLUS, "", "", "Wi-Fi");
+		_assertCorrectListItem(widgetId[3], true, WIDGET_DOMBUTTON_CHECKBOX_ON, "", "", "VPN");
+		_assertCorrectListItem(widgetId[4], true, "", "", "", '');
+	};
+
+	function _assertCorrectListItem(widgetId, noIcon, rightIcon, rightIcon2, rightText, boxText){
+		var widget = registry.byId(widgetId);
+		doh.assertNotEqual(null, widget, "ListItem: Did not instantiate.");
+		runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + widget.domNode.id);
+		if(!noIcon){
+			runner.assertTrue(widget.iconNode, "iconNode: There is no iconNode. id=" + widget.domNode.id);
+			runner.assertTrue(domClass.contains(widget.iconNode, WIDGET_ICON_CLASSNAME1), WIDGET_ICON_CLASSNAME1 + " id=" + widget.domNode.id);
+			if(dojo.isIE!=6){
+				runner.assertTrue(!!widget.iconNode.src, "iconNode: There is no src in iconNode. id=" + widget.domNode.id);
+			}
+		}
+		if(rightIcon){
+			runner.assertTrue(widget.rightIconNode, "rightIconNode: There is no rightIconNode. id=" + widget.domNode.id);
+			runner.assertEqual(WIDGET_RIGHTICON_CLASSNAME1, widget.rightIconNode.className);
+			runner.assertTrue(domClass.contains(widget.rightIconNode.childNodes[0], rightIcon), rightIcon + " id=" + widget.domNode.id);
+		}
+		if(rightIcon2){
+			runner.assertTrue(widget.rightIconNode2, "rightIconNode2: There is no rightIconNode2. id=" + widget.domNode.id);
+			runner.assertTrue(domClass.contains(widget.rightIconNode2, rightIcon2), rightIcon2 + " id=" + widget.domNode.id);
+		}
+		if(rightText){
+			runner.assertTrue(widget.rightTextNode, "rightTextNode: There is no rightTextNode. id=" + widget.domNode.id);
+			runner.assertEqual(rightText, widget.rightTextNode.innerHTML);
+		}
+		if(boxText){
+			runner.assertTrue(widget.labelNode, "box: There is no box. id=" + widget.domNode.id);
+			var innerHTML = string.trim(widget.labelNode.innerHTML.replace(/\r\n/g,""));
+			runner.assertEqual(boxText, innerHTML, "id=" + widget.domNode.id);
+		}
+	};
+
+	function _showView2(){
+		var view1 = registry.byId("view1");
+		view1.performTransition("view2", 1, "none");
+	};
+
+	ready(function(){
+		runner.register("dojox.mobile.test.doh.Heading", [
+			{
+				name: "ListItem Verification1",
+				timeout: 4000,
+				runTest: function(){
+					_createListItemProgrammatically("view1-RoundRectList2", ["view1-item6", "view1-item7", "view1-item8", "view1-item9", "view1-item10"]);
+					_createListItemProgrammaticallyWithSourceNodeReference(["view1-item11", "view1-item12", "view1-item13", "view1-item14", "view1-item15"]);
+
+					_assertCorrectListItems(["view1-item1", "view1-item2", "view1-item3", "view1-item4", "view1-item5"]);
+					_assertCorrectListItems(["view1-item6", "view1-item7", "view1-item8", "view1-item9", "view1-item10"]);
+					_assertCorrectListItems(["view1-item11", "view1-item12", "view1-item13", "view1-item14", "view1-item15"]);
+				}
+			},
+			{
+				name: "ListItem Verification2",
+				timeout: 4000,
+				runTest: function(){
+					_createListItemProgrammatically("view2-RoundRectList2", ["view2-item6", "view2-item7", "view2-item8", "view2-item9", "view2-item10"]);
+					_createListItemProgrammaticallyWithSourceNodeReference(["view2-item11", "view2-item12", "view2-item13", "view2-item14", "view2-item15"]);
+
+					var d = new runner.Deferred();
+					var handle2 = connect.subscribe("/dojox/mobile/afterTransitionIn", d.getTestCallback(function(view){
+						if(view.id=="view2"){
+							connect.unsubscribe(handle2);
+						}
+						_assertCorrectListItems(["view2-item1", "view2-item2", "view2-item3", "view2-item4", "view2-item5"]);
+						_assertCorrectListItems(["view2-item6", "view2-item7", "view2-item8", "view2-item9", "view2-item10"]);
+						_assertCorrectListItems(["view2-item11", "view2-item12", "view2-item13", "view2-item14", "view2-item15"]);
+					}));
+					_showView2();
+					return d;
+				}
+			}
+		]);
+		runner.run();
+	});
+})
diff --git a/dojox/mobile/tests/doh/listitem/ListItemTests1.html b/dojox/mobile/tests/doh/listitem/ListItemTests1.html
new file mode 100644
index 0000000..e6db817
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/ListItemTests1.html
@@ -0,0 +1,108 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>ListItem Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="ListItemTests.js"></script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1>View1</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li id="view1-item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../../images/i-icon-1.png", rightText:"Off", moveTo:"bar"'>
+				u1space
+			</li>
+			<li id="view1-item2" data-dojo-type="dojox.mobile.ListItem">
+				u2space
+			</li>
+			<li id="view1-item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightIcon:"mblDomButtonBluePlus"'>
+				Wi-Fi
+			</li>
+			<li id="view1-item4" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightIcon:"mblDomButtonCheckboxOn"'>
+				VPN
+			</li>
+			<li id="view1-item5" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:"true"' style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<font color="red">$14.50 (50%)</font> In Stock<br>
+				# (531)
+			</li>
+		</ul>
+		<ul id="view1-RoundRectList2" data-dojo-type="dojox.mobile.RoundRectList">
+		</ul>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li id="view1-item11">
+				u1space
+			</li>
+			<li id="view1-item12">
+				u2space
+			</li>
+			<li id="view1-item13">
+				Wi-Fi
+			</li>
+			<li id="view1-item14">
+				VPN
+			</li>
+			<li id="view1-item15" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<font color="red">$14.50 (50%)</font> In Stock<br>
+				# (531)
+			</li>
+		</ul>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View2</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li id="view2-item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../../images/i-icon-1.png", rightText:"Off", moveTo:"bar"'>
+				u1space
+			</li>
+			<li id="view2-item2" data-dojo-type="dojox.mobile.ListItem">
+				u2space
+			</li>
+			<li id="view2-item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightIcon:"mblDomButtonBluePlus"'>
+				Wi-Fi
+			</li>
+			<li id="view2-item4" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightIcon:"mblDomButtonCheckboxOn"'>
+				VPN
+			</li>
+			<li id="view2-item5" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:"true"' style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<font color="red">$14.50 (50%)</font> In Stock<br>
+				# (531)
+			</li>
+		</ul>
+		<ul id="view2-RoundRectList2" data-dojo-type="dojox.mobile.RoundRectList">
+		</ul>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li id="view2-item11">
+				u1space
+			</li>
+			<li id="view2-item12">
+				u2space
+			</li>
+			<li id="view2-item13">
+				Wi-Fi
+			</li>
+			<li id="view2-item14">
+				VPN
+			</li>
+			<li id="view2-item15" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<font color="red">$14.50 (50%)</font> In Stock<br>
+				# (531)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/listitem/ListItemTests2.html b/dojox/mobile/tests/doh/listitem/ListItemTests2.html
new file mode 100644
index 0000000..f642b28
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/ListItemTests2.html
@@ -0,0 +1,108 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>ListItem Tests</title>
+<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+<script type="text/javascript" src="ListItemTests.js"></script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View1</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li id="view1-item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../../images/i-icon-1.png", rightText:"Off", moveTo:"bar"'>
+				u1space
+			</li>
+			<li id="view1-item2" data-dojo-type="dojox.mobile.ListItem">
+				u2space
+			</li>
+			<li id="view1-item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightIcon:"mblDomButtonBluePlus"'>
+				Wi-Fi
+			</li>
+			<li id="view1-item4" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightIcon:"mblDomButtonCheckboxOn"'>
+				VPN
+			</li>
+			<li id="view1-item5" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:"true"' style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<font color="red">$14.50 (50%)</font> In Stock<br>
+				# (531)
+			</li>
+		</ul>
+		<ul id="view1-RoundRectList2" data-dojo-type="dojox.mobile.EdgeToEdgeList">
+		</ul>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li id="view1-item11">
+				u1space
+			</li>
+			<li id="view1-item12">
+				u2space
+			</li>
+			<li id="view1-item13">
+				Wi-Fi
+			</li>
+			<li id="view1-item14">
+				VPN
+			</li>
+			<li id="view1-item15" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<font color="red">$14.50 (50%)</font> In Stock<br>
+				# (531)
+			</li>
+		</ul>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View2</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li id="view2-item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"../../images/i-icon-1.png", rightText:"Off", moveTo:"bar"'>
+				u1space
+			</li>
+			<li id="view2-item2" data-dojo-type="dojox.mobile.ListItem">
+				u2space
+			</li>
+			<li id="view2-item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightIcon:"mblDomButtonBluePlus"'>
+				Wi-Fi
+			</li>
+			<li id="view2-item4" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightIcon:"mblDomButtonCheckboxOn"'>
+				VPN
+			</li>
+			<li id="view2-item5" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:"true"' style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<font color="red">$14.50 (50%)</font> In Stock<br>
+				# (531)
+			</li>
+		</ul>
+		<ul id="view2-RoundRectList2" data-dojo-type="dojox.mobile.EdgeToEdgeList">
+		</ul>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li id="view2-item11">
+				u1space
+			</li>
+			<li id="view2-item12">
+				u2space
+			</li>
+			<li id="view2-item13">
+				Wi-Fi
+			</li>
+			<li id="view2-item14">
+				VPN
+			</li>
+			<li id="view2-item15" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<font color="red">$14.50 (50%)</font> In Stock<br>
+				# (531)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/listitem/ListItem_Programmatic.html b/dojox/mobile/tests/doh/listitem/ListItem_Programmatic.html
new file mode 100644
index 0000000..dc1985c
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/ListItem_Programmatic.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Switch</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+
+		<script type="text/javascript" src="CreateListItem_Programmatic.js"></script>
+
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="ListItem.js"></script>
+
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<ul dojoType="dojox.mobile.RoundRectList">
+			</ul>
+			<ul dojoType="dojox.mobile.RoundRectList" iconBase="../../images/i-icon-all.png">
+			</ul>
+			<ul dojoType="dojox.mobile.EdgeToEdgeList">
+			</ul>
+		    <ul dojoType="dojox.mobile.EdgeToEdgeList">
+		    </ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/listitem/module.js b/dojox/mobile/tests/doh/listitem/module.js
new file mode 100644
index 0000000..29e32e3
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/module.js
@@ -0,0 +1,15 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.ListItem", require.toUrl("./ListItem.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.ListItem", require.toUrl("./ListItem2.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.ListItem", require.toUrl("./ListItem_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.ListItem", require.toUrl("./ListItem2_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.ListItem", require.toUrl("./ListItem3_Programmatic.html"),999999);
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.ListItem", require.toUrl("./ListItemTests1.html"),999999);
+		doh.registerUrl("dojox.mobile.tests.doh.ListItem", require.toUrl("./ListItemTests2.html"),999999);
+	}	
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/listitem/runTests.html b/dojox/mobile/tests/doh/listitem/runTests.html
new file mode 100644
index 0000000..136bbaf
--- /dev/null
+++ b/dojox/mobile/tests/doh/listitem/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.listitem.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/longlistmixin/LongListMixin.html b/dojox/mobile/tests/doh/longlistmixin/LongListMixin.html
new file mode 100644
index 0000000..ef88142
--- /dev/null
+++ b/dojox/mobile/tests/doh/longlistmixin/LongListMixin.html
@@ -0,0 +1,270 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>LongListMixin Tests</title>
+
+	<!-- DOH test for dojox/mobile/LongListMixin (performance booster for long scrollable lists) -->
+	
+	<script type="text/javascript" src="../../../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"doh/runner",
+			"dojo/query",
+			"dojo/dom-geometry",
+			"dojox/mobile/ListItem",
+			"dojo/store/Memory",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/RoundRectList",
+			"dojox/mobile/RoundRectStoreList",
+			"dojox/mobile/LongListMixin"
+		], function(ready, registry, runner, query, domGeometry, ListItem, MemoryStore){
+			
+			function fillList(list, variableHeight){
+				list = registry.byId(list);
+				var c = list.getChildren();
+				var i;
+				for(i = 0; i < c.length; i++){
+					list.removeChild(c[i]);
+				}
+				doh.assertEqual(0, list.getChildren().length, "list not empty after removing all children");
+				for(i = 0; i < 1000; i++){
+					list.addChild(new ListItem(
+						!variableHeight ? 
+						{ 
+							label: "Item " + i
+						} :
+						{
+							variableHeight: true,
+						  	innerHTML: "Item " + i + "<br/>Some more content<br/>in the list item<br/>etc..." 
+						}
+					));
+				}
+				doh.assertEqual(1000, list.getChildren().length, "list should have 1000 children");
+			}
+			
+			function fillStoreList(list){
+				list = registry.byId(list);
+				var data = [];
+				for(i = 0; i < 1000; i++){
+					data.push({	label: "Store item " + i });
+				}
+				
+				var store = new MemoryStore({idProperty: "label", data: data});
+				list.setStore(store);
+				
+				doh.assertEqual(1000, list.getChildren().length, "list should have 1000 children");
+			}
+			
+			function verifyList(list){
+				list = registry.byId(list);
+				var itemHeight = list.getChildren()[0].domNode.offsetHeight;
+
+				if (itemHeight > 0){
+					var item = list.getChildren()[0].domNode,
+						itemMargin = Math.max(parseFloat(window.getComputedStyle(item).marginTop),
+							parseFloat(window.getComputedStyle(item).marginBottom));
+					if (!isNaN(itemMargin)){
+						itemHeight += itemMargin;
+					}
+				}
+
+				var viewHeight = list.getParent().domNode.offsetHeight;
+				var pageSize = list.pageSize;
+				
+				// total list height (should be approx nitems *itemHeight, modulo margin collapsing)
+				var expectedListHeight = itemHeight * list.getChildren().length;
+				var actualListHeight = list.domNode.offsetHeight;
+				var delta = 3*list.getChildren().length;
+				if(list.getChildren()[0].variableHeight){
+					delta *= 2;
+				}
+				doh.assertTrue(Math.abs(expectedListHeight-actualListHeight) < delta, "wrong list height: " + actualListHeight + " != " + expectedListHeight);
+				
+				// expected number of items in list DOM: multiple of pageSize, less than maxPages*pageSize
+				var count = query(".mblListItem", list.containerNode).length;
+				doh.assertTrue(count % pageSize == 0, "not a multiple of pageSize: " + count);
+				doh.assertTrue(count < pageSize * list.maxPages, "more than maxPages: " + count);
+				
+				// check that the visible area is actually filled by items
+				var listBox = domGeometry.getContentBox(list.containerNode);
+				var viewBox = domGeometry.getContentBox(list.getParent().domNode);
+				doh.assertTrue(listBox.t <= viewBox.t, "empty space at top " + listBox.t + " > " + viewBox.t);
+				doh.assertTrue(listBox.t + listBox.h >= viewBox.t + viewBox.h, "empty space at bottom "  + (listBox.t+listBox.h) + " < " + (viewBox.t+viewBox.h));
+			}
+			
+			ready(function(){
+				doh.register("dojox.mobile.test.doh.LongListMixinTests", [
+					{
+						name: "LongListMixin - initial items",
+						timeout: 200,
+						setUp: function(){
+							fillList("list1");
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								verifyList("list1");
+							}), 200);
+							return d;
+						}
+					},
+					{
+						name: "LongListMixin - scroll",
+						timeout: 1000,
+						setUp: function(){
+							fillList("list1")
+							var view = registry.byId("view1");
+							view.scrollTo({y:-1000});
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								verifyList("list1");
+							}), 200);
+							return d;
+						}
+					},
+					{
+						name: "LongListMixin - slide",
+						timeout: 1000,
+						setUp: function(){
+							fillList("list1");
+							var view = registry.byId("view1");
+							view.scrollTo({y:-1000});
+							view.slideTo({y:-1200}, 0.3, "ease-out");
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								verifyList("list1");
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "LongListMixin - variable height - initial items",
+						timeout: 200,
+						setUp: function(){
+							fillList("list1", true);
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								verifyList("list1");
+							}), 200);
+							return d;
+						}
+					},
+					{
+						name: "LongListMixin - variable height - scroll",
+						timeout: 1000,
+						setUp: function(){
+							fillList("list1", true)
+							var view = registry.byId("view1");
+							view.scrollTo({y:-5000});
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								verifyList("list1");
+							}), 200);
+							return d;
+						}
+					},
+					{
+						name: "LongListMixin - variable height - slide",
+						timeout: 1000,
+						setUp: function(){
+							fillList("list1", true);
+							var view = registry.byId("view1");
+							view.scrollTo({y:-5000});
+							view.slideTo({y:-5200}, 0.3, "ease-out");
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								verifyList("list1");
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "LongListMixin + store - initial items",
+						timeout: 200,
+						setUp: function(){
+							registry.byId("view2").show();
+							fillStoreList("list2");
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								verifyList("list1");
+							}), 200);
+							return d;
+						}
+					},
+					{
+						name: "LongListMixin + store - scroll",
+						timeout: 1000,
+						setUp: function(){
+							fillStoreList("list2")
+							var view = registry.byId("view2");
+							view.scrollTo({y:-1000});
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								verifyList("list1");
+							}), 200);
+							return d;
+						}
+					},
+					{
+						name: "LongListMixin + store - slide",
+						timeout: 1000,
+						setUp: function(){
+							fillStoreList("list2");
+							var view = registry.byId("view2");
+							view.scrollTo({y:-1000});
+							view.slideTo({y:-1200}, 0.3, "ease-out");
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								verifyList("list1");
+							}), 500);
+							return d;
+						}
+					}
+				]);
+				runner.run();
+			});
+		})
+	</script>
+
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox/mobile/ScrollableView" data-dojo-props="height:'400px'">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">LongListMixin - no store</h1>
+		<ul data-dojo-type="dojox/mobile/RoundRectList" id="list1"
+			data-dojo-mixins="dojox/mobile/LongListMixin"></ul>
+	</div>
+	<div id="view2" data-dojo-type="dojox/mobile/ScrollableView" data-dojo-props="height:'400px'">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">LongListMixin + store</h1>
+		<ul data-dojo-type="dojox/mobile/RoundRectStoreList" id="list2"
+			data-dojo-mixins="dojox/mobile/LongListMixin"></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/longlistmixin/module.js b/dojox/mobile/tests/doh/longlistmixin/module.js
new file mode 100644
index 0000000..77822af
--- /dev/null
+++ b/dojox/mobile/tests/doh/longlistmixin/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.LongListMixin", require.toUrl("./LongListMixin.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/longlistmixin/runTests.html b/dojox/mobile/tests/doh/longlistmixin/runTests.html
new file mode 100644
index 0000000..d85c880
--- /dev/null
+++ b/dojox/mobile/tests/doh/longlistmixin/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.longlistmixin.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/module.js b/dojox/mobile/tests/doh/module.js
index 3a70a77..472f7e1 100644
--- a/dojox/mobile/tests/doh/module.js
+++ b/dojox/mobile/tests/doh/module.js
@@ -1,42 +1,55 @@
-dojo.provide("dojox.mobile.tests.doh.module");
-
-try{
-	doh.registerUrl("dojox.mobile.tests.doh.Button", dojo.moduleUrl("dojox.mobile", "tests/doh/Button.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.Button", dojo.moduleUrl("dojox.mobile", "tests/doh/Button_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.EdgeToEdgeCategory", dojo.moduleUrl("dojox.mobile", "tests/doh/EdgeToEdgeCategory.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.Heading", dojo.moduleUrl("dojox.mobile", "tests/doh/Heading.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.Heading", dojo.moduleUrl("dojox.mobile", "tests/doh/Heading2.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.Heading", dojo.moduleUrl("dojox.mobile", "tests/doh/Heading_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.Heading", dojo.moduleUrl("dojox.mobile", "tests/doh/Heading2_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.IconContainer", dojo.moduleUrl("dojox.mobile", "tests/doh/IconContainer.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.IconContainer", dojo.moduleUrl("dojox.mobile", "tests/doh/IconContainer2.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.IconContainer", dojo.moduleUrl("dojox.mobile", "tests/doh/IconContainer3.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.IconContainer", dojo.moduleUrl("dojox.mobile", "tests/doh/IconContainer_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.IconContainer", dojo.moduleUrl("dojox.mobile", "tests/doh/View.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.RoundRectList", dojo.moduleUrl("dojox.mobile", "tests/doh/RoundRect.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.ListItem", dojo.moduleUrl("dojox.mobile", "tests/doh/ListItem.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.ListItem", dojo.moduleUrl("dojox.mobile", "tests/doh/ListItem2.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.ListItem", dojo.moduleUrl("dojox.mobile", "tests/doh/ListItem_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.ListItem", dojo.moduleUrl("dojox.mobile", "tests/doh/ListItem2_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.Progress-indicator", dojo.moduleUrl("dojox.mobile", "tests/doh/progress-indicator.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.RoundRect", dojo.moduleUrl("dojox.mobile", "tests/doh/RoundRect.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.RoundRect", dojo.moduleUrl("dojox.mobile", "tests/doh/RoundRect_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.RoundRectDataList", dojo.moduleUrl("dojox.mobile", "tests/doh/RoundRectDataList.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.RoundRectDataList", dojo.moduleUrl("dojox.mobile", "tests/doh/RoundRectDataList_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.RoundRectList", dojo.moduleUrl("dojox.mobile", "tests/doh/RoundRectList.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.Switch", dojo.moduleUrl("dojox.mobile", "tests/doh/Switch.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.Switch", dojo.moduleUrl("dojox.mobile", "tests/doh/Switch_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.TabBar", dojo.moduleUrl("dojox.mobile", "tests/doh/TabBar.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.TabBar", dojo.moduleUrl("dojox.mobile", "tests/doh/TabBar_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.ToolBarButton", dojo.moduleUrl("dojox.mobile", "tests/doh/ToolBarButton.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.ToolBarButton", dojo.moduleUrl("dojox.mobile", "tests/doh/ToolBarButton_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.View", dojo.moduleUrl("dojox.mobile", "tests/doh/View.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.View", dojo.moduleUrl("dojox.mobile", "tests/doh/View_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.View", dojo.moduleUrl("dojox.mobile", "tests/doh/View2_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.View", dojo.moduleUrl("dojox.mobile", "tests/doh/View3_Programmatic.html"),999999);
-	doh.registerUrl("dojox.mobile.tests.doh.View", dojo.moduleUrl("dojox.mobile", "tests/doh/View-demo.html"),999999);
-}catch(e){
-	doh.debug(e);
-}
-
-
+define([
+	"doh/runner",
+	"dojo/sniff",
+	"require",
+	"./accordion/module",
+	"./badge/module",
+	"./bidi/module",
+	"./button/module",
+	"./checkbox/module",
+	"./combobox/module",
+	"./contentpane/module",
+	"./edgetoedgecategory/module",
+	"./edgetoedgedatalist/module",
+	"./edgetoedgelist/module",
+	"./edgetoedgestorelist/module",
+	"./expandingtextarea/module",
+	"./filteredlistmixin/module",
+	"./fixedbars/module",
+	"./fixedsplitter/module",
+	"./heading/module",
+	"./iconcontainer/module",
+	"./iconmenu/module",
+	"./listitem/module",
+	"./longlistmixin/module",
+	"./opener/module",
+	"./pageindicator/module",
+	"./progressindicator/module",
+	"./radiobutton/module",
+	"./roundrect/module",
+	"./roundrectdatalist/module",
+	"./roundrectlist/module",
+	"./roundrectstorelist/module",
+	"./scrollablepane/module",
+	"./slider/module",
+	"./spinwheel/module",
+	"./spinwheeldatepicker/module",
+	"./swapview/module",
+	"./switch/module",
+	"./tabbar/module",
+	"./templating/module",
+	"./textarea/module",
+	"./textbox/module",
+	"./toolbarbutton/module",
+	"./transition/module",
+	"./valuepickerdatepicker/module",
+	"./valuepickertimepicker/module",
+	"./view/module"
+], function(doh, has, require){
+	try{
+		doh.registerUrl("dojox.mobile.tests.doh.URLProperty", require.toUrl("./TestURLProp.html"),999999);
+		doh.registerUrl("dojox.mobile.tests.doh.URLProperty", require.toUrl("./TestURLProp2.html"),999999);
+	}catch(e){
+		doh.debug(e);
+	}
+});
diff --git a/dojox/mobile/tests/doh/opener/OpenerTests1.html b/dojox/mobile/tests/doh/opener/OpenerTests1.html
new file mode 100644
index 0000000..92ec75e
--- /dev/null
+++ b/dojox/mobile/tests/doh/opener/OpenerTests1.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Opener Tests (Overlay and Tooltip)</title>
+
+	<!-- Test for #16880 affecting Overlay and Tooltip (thus, Opener) -->
+	
+	<script type="text/javascript" src="../../../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"doh/runner",
+			"dijit/registry",
+			"dojo/ready",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Opener",
+			"dojox/mobile/Tooltip",
+			"dojox/mobile/Overlay",
+			"dojox/mobile/SpinWheelDatePicker",
+			"dojox/mobile/ScrollableView"
+		], function(runner, registry, ready){
+			var testInView = function(id){
+				var spinWheel = registry.byId(id);
+				// When spinwheel's centerPos is 0, the wheel is broken. Hence, using
+				// it for detecting the failure case. 
+				runner.assertTrue(spinWheel.centerPos > 0, 
+					id + ": centerPos should be > 0! got: " + spinWheel.centerPos);
+			};
+					
+			ready(function(){
+				runner.register("dojox.mobile.test.doh.OpenerTests", [
+					function testInView2(){
+						testInView("spin2");
+					}, 
+					function testInView3(){
+						testInView("spin3");
+					},
+					function testInView4(){
+						testInView("spin4");
+					},
+					function testInView5(){
+						testInView("spin5");
+					}
+				]);
+				runner.run();
+			});
+		})
+	</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox/mobile/View" data-dojo-props="selected: true">
+		<ul data-dojo-type="dojox/mobile/RoundRectList">
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props="moveTo: 'view2'">view2 (SpinWheel in ScrollableView)</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props="moveTo: 'view3'">view3 (SpinWheel in Opener lazy:false)</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props="moveTo: 'view4'">view4 (SpinWheel in Overlay)</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props="moveTo: 'view5'">view5 (SpinWheel in Tooltip)</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props="moveTo: 'view6'">view6 (SpinWheel in Opener lazy:true)</li>
+		</ul>
+	</div>
+	
+	<div id="view2" data-dojo-type="dojox/mobile/ScrollableView" data-dojo-props="selected: false">
+		<div id="spin2" data-dojo-type="dojox/mobile/SpinWheelDatePicker"></div>
+	</div>
+	
+	<div id="view3" data-dojo-type="dojox/mobile/ScrollableView" data-dojo-props="selected: false">
+		<div data-dojo-type="dojox/mobile/Opener" 
+			data-dojo-props="lazy:false">
+			<div id="spin3" data-dojo-type="dojox/mobile/SpinWheelDatePicker"></div>
+		</div>
+	</div>
+	
+	<div id="view4" data-dojo-type="dojox/mobile/ScrollableView" data-dojo-props="selected: false">
+		<div data-dojo-type="dojox/mobile/Overlay">
+			<div id="spin4" data-dojo-type="dojox/mobile/SpinWheelDatePicker"></div>
+		</div>
+	</div>
+	
+	<div id="view5" data-dojo-type="dojox/mobile/ScrollableView" data-dojo-props="selected: false">
+		<div data-dojo-type="dojox/mobile/Tooltip">
+			<div id="spin5" data-dojo-type="dojox/mobile/SpinWheelDatePicker"></div>
+		</div>
+	</div>
+	
+	<div id="view6" data-dojo-type="dojox/mobile/ScrollableView" data-dojo-props="selected: false">
+		<div data-dojo-type="dojox/mobile/Opener" 
+			data-dojo-props="lazy:true">
+			<div id="spin6" data-dojo-type="dojox/mobile/SpinWheelDatePicker"></div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/opener/module.js b/dojox/mobile/tests/doh/opener/module.js
new file mode 100644
index 0000000..6415eb5
--- /dev/null
+++ b/dojox/mobile/tests/doh/opener/module.js
@@ -0,0 +1,6 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.Opener", require.toUrl("./OpenerTests1.html"),999999);
+	}
+});
\ No newline at end of file
diff --git a/dojox/mobile/tests/doh/opener/runTests.html b/dojox/mobile/tests/doh/opener/runTests.html
new file mode 100644
index 0000000..724c737
--- /dev/null
+++ b/dojox/mobile/tests/doh/opener/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.opener.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests.js b/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests.js
new file mode 100644
index 0000000..14ef099
--- /dev/null
+++ b/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests.js
@@ -0,0 +1,190 @@
+var timeoutInterval = 3000;
+
+var WIDGET_CLASSNAME1 = "mblPageIndicator";
+var WIDGET_CLASSNAME2 = "mblFixedBottomBar";
+var WIDGET_DOT_CLASSNAME1 = "mblPageIndicatorDot";
+var WIDGET_DOT_CLASSNAME2 = "mblPageIndicatorDotSelected";
+var WIDGET_PAGENUM = 5;
+
+require([
+	"dojo/_base/connect",
+	"dojo/sniff",
+	"dojo/dom-construct", // dojo.place
+	"dojo/dom-class", // dojo.hasClass
+	"dojo/ready", // dojo.ready
+	"dijit/registry",  // dijit.byId
+	"doh/runner",	//doh functions
+	"dojox/mobile/PageIndicator",
+	"dojox/mobile",				// This is a mobile app.
+	"dojox/mobile/SwapView",		// This mobile app uses mobile view
+	"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+	"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+], function(connect, has, domConst, domClass, ready, registry, runner, PageIndicator){
+	function fireOnClick(node){
+		if(has("ie")<9){
+			var e = document.createEventObject();
+			e.layerX = 0;
+			node.fireEvent( "onclick" );
+		}else{
+			var e = document.createEvent('Events');
+			e.initEvent('click', true, true);
+			e.layerX = 0;
+			node.dispatchEvent(e);
+		}
+	}
+	function _createPageIndicatorDeclaratively(widgetId) {
+		return registry.byId(widgetId);
+	};
+	function _createPageIndicatorProgrammatically(placeHolderId, widgetId){
+		// Create SwapView
+		var r = new PageIndicator({id:widgetId, fixed:"bottom"});
+		runner.assertNotEqual(null, r);
+		domConst.place(r.domNode, placeHolderId, "replace");
+		
+		r.startup();
+		_initAppBars();
+
+		return r;
+	};
+	function _createPageIndicatorProgrammaticallyWithSourceNodeReference(widgetId){
+		// Create IconContainer
+		var r = new PageIndicator({}, widgetId);
+
+		r.startup();
+		_initAppBars();
+
+		return r;
+	};
+	function _initAppBars(){
+		var view1 = registry.byId("dojox_mobile_SwapView_0");
+		view1.findAppBars();
+		view1.resize();
+
+		var view2 = registry.byId("dojox_mobile_SwapView_1");
+		view2.findAppBars();
+		view2.resize();
+
+		var view3 = registry.byId("dojox_mobile_SwapView_2");
+		view3.findAppBars();
+		view3.resize();
+
+		var view4 = registry.byId("dojox_mobile_SwapView_3");
+		view4.findAppBars();
+		view4.resize();
+
+		var view5 = registry.byId("dojox_mobile_SwapView_4");
+		view5.findAppBars();
+		view5.resize();
+	};
+	function _assertCorrectPageIndicator(widget, col){
+		runner.assertNotEqual(null, widget, "IconContainer: Did not instantiate.");
+		runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1);
+		runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2);
+		var r = widget._tblNode.rows[0];
+		runner.assertEqual(WIDGET_PAGENUM, widget._tblNode.rows[0].cells.length, "Number of page");
+		for(i = 0; i < r.cells.length; i++){
+			dot = r.cells[i].firstChild;
+			runner.assertTrue(domClass.contains(dot, WIDGET_DOT_CLASSNAME1), WIDGET_DOT_CLASSNAME1);
+			if(i+1 === col){
+				runner.assertTrue(domClass.contains(dot, WIDGET_DOT_CLASSNAME2), WIDGET_DOT_CLASSNAME2);
+			}
+		}
+	};
+	ready(function(){
+		if(WIDGET_PROGRAMMATICALLY === 1){
+			_createPageIndicatorProgrammatically("dojox_mobile_PageIndicator_0Place", "dojox_mobile_PageIndicator_0");
+		}else if(WIDGET_PROGRAMMATICALLY === 2){
+			_createPageIndicatorProgrammaticallyWithSourceNodeReference("dojox_mobile_PageIndicator_0");
+		}
+
+		runner.register("dojox.mobile.test.doh.PageIndicator", [
+			{
+				name: "PageIndicator Verification1",
+				timeout: 4000,
+				runTest: function(){
+
+					var view1 = registry.byId("dojox_mobile_SwapView_0");
+					var view2 = registry.byId("dojox_mobile_SwapView_1");
+					var widget1 = registry.byId("dojox_mobile_PageIndicator_0");
+
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						_assertCorrectPageIndicator(widget1, 1);
+						view1.goTo(1);
+					}), timeoutInterval);
+					return d;
+			
+				}
+			},
+			{
+				name: "PageIndicator Verification2",
+				timeout: 4000,
+				runTest: function(){
+					var view2 = registry.byId("dojox_mobile_SwapView_1");
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var widget1 = registry.byId("dojox_mobile_PageIndicator_0");
+						_assertCorrectPageIndicator(widget1, 2);
+						view2.goTo(1);
+					}), timeoutInterval);
+					return d;
+				}
+			},
+			{
+				name: "PageIndicator Verification3",
+				timeout: 4000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var widget1 = registry.byId("dojox_mobile_PageIndicator_0");
+						_assertCorrectPageIndicator(widget1, 3);
+						fireOnClick(widget1.domNode);
+					}), timeoutInterval);
+					return d;
+				}
+			},
+			{
+				name: "PageIndicator Verification4",
+				timeout: 4000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var widget1 = registry.byId("dojox_mobile_PageIndicator_0");
+						_assertCorrectPageIndicator(widget1, 2);
+					}), timeoutInterval);
+					return d;
+				}
+			},
+			{
+				name: "PageIndicator Verification5",
+				timeout: 3000,
+				runTest: function(){
+					// Test case for #15064: destroy right after startup()
+					var widget = new PageIndicator();
+					var d = new runner.Deferred();
+					var errorCounter = 0;
+					var errorMsg;
+					// Before the fix of #15064, there used to be an error thrown when destroying 
+					// right after startup(). To test it, we cannot use a simple try-catch, because
+					// this is about an error thrown by the setTimeout function which used to be set 
+					// PageIndicator's startup(). Hence:
+					window.onerror = function(msg, url, lineNumber){
+						errorCounter++;
+						errorMsg = "After destroy: " + msg + "\nURL: " + url + 
+							"\nLine number: " + lineNumber;
+						console.log(errorMsg);
+					};
+					widget.startup();
+					widget.destroyRecursive(false/*preserveDom*/);
+					// Check that no error has been thrown
+					setTimeout(d.getTestCallback(function(){
+						runner.assertEqual(0, errorCounter, errorMsg);
+					}), 2000); // smaller than the total timeout of the test case
+						
+					return d;
+				}
+			}
+		]);
+		runner.run();
+	});
+})
diff --git a/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests1.html b/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests1.html
new file mode 100644
index 0000000..66c13c4
--- /dev/null
+++ b/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests1.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>PageIndicator Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','PageIndicator']"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY =0;
+</script>
+<script type="text/javascript" src="PageIndicatorTests.js"></script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 1</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 2</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 3</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 4</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 5</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.PageIndicator" data-dojo-props='fixed:"bottom"'></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests2.html b/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests2.html
new file mode 100644
index 0000000..76078af
--- /dev/null
+++ b/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests2.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>PageIndicator Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','PageIndicator']"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY = 1;
+</script>
+<script type="text/javascript" src="PageIndicatorTests.js"></script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 1</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 2</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 3</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 4</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 5</h1>
+	</div>
+
+	<div id="dojox_mobile_PageIndicator_0Place"></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests3.html b/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests3.html
new file mode 100644
index 0000000..52c2b16
--- /dev/null
+++ b/dojox/mobile/tests/doh/pageindicator/PageIndicatorTests3.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>PageIndicator Tests</title>
+<title>PageIndicator Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','PageIndicator']"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY = 2;
+</script>
+<script type="text/javascript" src="PageIndicatorTests.js"></script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 1</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 2</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 3</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 4</h1>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>View 5</h1>
+	</div>
+
+	<div id="dojox_mobile_PageIndicator_0" fixed="bottom"></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/pageindicator/module.js b/dojox/mobile/tests/doh/pageindicator/module.js
new file mode 100644
index 0000000..bd8f60a
--- /dev/null
+++ b/dojox/mobile/tests/doh/pageindicator/module.js
@@ -0,0 +1,11 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.PageIndicator", require.toUrl("./PageIndicatorTests1.html"),999999);
+		doh.registerUrl("dojox.mobile.tests.doh.PageIndicator", require.toUrl("./PageIndicatorTests2.html"),999999);
+		doh.registerUrl("dojox.mobile.tests.doh.PageIndicator", require.toUrl("./PageIndicatorTests3.html"),999999);
+	}
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/pageindicator/runTests.html b/dojox/mobile/tests/doh/pageindicator/runTests.html
new file mode 100644
index 0000000..8369077
--- /dev/null
+++ b/dojox/mobile/tests/doh/pageindicator/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.pageindicator.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/progress-indicator.html b/dojox/mobile/tests/doh/progress-indicator.html
deleted file mode 100644
index 4ddf277..0000000
--- a/dojox/mobile/tests/doh/progress-indicator.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Progress Indicator</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojo.hash");
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-	        dojo.require("doh.runner");
-	        
-			dojo.addOnLoad(function(){
-				var container = dojo.byId("home");
-				container.innerHTML = "";
-				var prog = dojox.mobile.ProgressIndicator.getInstance();
-				container.appendChild(prog.domNode);
-				prog.start();
-				doh.register("dojox.mobile.test.doh.ProgressIndicator", [
-					function test_RoundRectList_Verification(){
-						var demoWidget = dijit.byId("home");
-						doh.assertEqual('mblProgContainer', demoWidget.containerNode.childNodes[0].className);
-						doh.assertEqual(12, demoWidget.containerNode.childNodes[0].childNodes[0].childNodes.length);
-
-					}
-				]);
-				setTimeout(function(){ // to get the correct dimension
-					doh.run();
-				}, 0);
-			});
-		</script>
-	</head>
-	<body>
-		<div id="home" dojoType="dojox.mobile.View" selected="true">
-		</div>
-
-	</body>
-</html>
diff --git a/dojox/mobile/tests/doh/progressindicator/module.js b/dojox/mobile/tests/doh/progressindicator/module.js
new file mode 100644
index 0000000..4271792
--- /dev/null
+++ b/dojox/mobile/tests/doh/progressindicator/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.ProgressIndicator", require.toUrl("./progress-indicator.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/progressindicator/progress-indicator.html b/dojox/mobile/tests/doh/progressindicator/progress-indicator.html
new file mode 100644
index 0000000..64a20b9
--- /dev/null
+++ b/dojox/mobile/tests/doh/progressindicator/progress-indicator.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Progress Indicator</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojo.hash");
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+	        
+			dojo.addOnLoad(function(){
+				var container = dojo.byId("home");
+				container.innerHTML = "";
+				var prog = dojox.mobile.ProgressIndicator.getInstance();
+				container.appendChild(prog.domNode);
+				prog.start();
+				doh.register("dojox.mobile.test.doh.ProgressIndicator", [
+					function test_RoundRectList_Verification(){
+						var demoWidget = dijit.byId("home");
+						doh.assertEqual('mblProgressIndicator mblProgressIndicatorCenter', demoWidget.containerNode.childNodes[0].className);
+						doh.assertEqual(12, demoWidget.containerNode.childNodes[0].childNodes[0].childNodes[0].childNodes.length);
+
+					}
+				]);
+				setTimeout(function(){ // to get the correct dimension
+					doh.run();
+				}, 0);
+			});
+		</script>
+	</head>
+	<body>
+		<div id="home" dojoType="dojox.mobile.View" selected="true">
+		</div>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/progressindicator/runTests.html b/dojox/mobile/tests/doh/progressindicator/runTests.html
new file mode 100644
index 0000000..d0d09c1
--- /dev/null
+++ b/dojox/mobile/tests/doh/progressindicator/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.progressindicator.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/radiobutton/RadioButtonTests.html b/dojox/mobile/tests/doh/radiobutton/RadioButtonTests.html
new file mode 100644
index 0000000..2060987
--- /dev/null
+++ b/dojox/mobile/tests/doh/radiobutton/RadioButtonTests.html
@@ -0,0 +1,139 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Radio Button Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+require([
+	"dojo/dom-construct", // dojo.place
+	"dojo/dom-class", // dojo.hasClass
+	"dojo/ready", // dojo.ready
+	"dijit/registry",  // dijit.byId
+	"doh/runner",	//doh functions
+	"dojox/mobile/RadioButton",
+	"dojox/mobile",				// This is a mobile app.
+	"dojox/mobile/View",		// This mobile app uses mobile view
+	"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+	"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+], function(domConst, domClass, ready, registry, runner, RadioButton){
+
+	function _createRadioButtonDeclaratively(buttonId) {
+		return registry.byId(buttonId);
+	};
+	
+	function _createRadioButtonProgrammatically(buttonValue, buttonName, placeHolderId){
+		var button = new RadioButton({value:buttonValue, name:buttonName});
+		runner.assertNotEqual(null, button);
+		domConst.place(button.domNode, placeHolderId, "replace");
+		button.startup();
+		return button;
+	};
+	
+	function _createRadioButtonProgrammaticallyWithSourceNodeReference(buttonValue, buttonName, buttonId){
+		return new RadioButton({value:buttonValue, name:buttonName}, buttonId);
+	};
+
+	function _assertCorrectRadioButton(button1, button2, button3){
+		runner.assertNotEqual(null, button1, button1.toString());
+		runner.assertNotEqual(null, button2, button2.toString());
+		runner.assertNotEqual(null, button3, button3.toString());
+		
+		runner.assertFalse(button1.checked, button1.toString());
+		runner.assertFalse(button2.checked, button2.toString());
+		runner.assertFalse(button3.checked, button3.toString());
+		
+		button1.set("checked", true);
+		runner.assertTrue(button1.checked, button1.toString());
+		runner.assertFalse(button2.checked, button2.toString());
+		runner.assertFalse(button3.checked, button3.toString());
+		
+		button2.set("checked", true);
+		runner.assertFalse(button1.checked, button1.toString());
+		runner.assertTrue(button2.checked, button2.toString());
+		runner.assertFalse(button3.checked, button3.toString());
+	};
+	
+	function _showView2(){
+		var view1 = registry.byId("view1");
+		view1.performTransition("view2", 1, "none");
+	};
+
+	ready(function(){
+		runner.register("dojox.mobile.test.doh.ButtonTests", [
+			function testInView1(){
+				var button11 = _createRadioButtonDeclaratively("view1-button11");
+				var button12 = _createRadioButtonDeclaratively("view1-button12");
+				var button13 = _createRadioButtonDeclaratively("view1-button13");
+				
+				var button21 = _createRadioButtonProgrammatically("1", "view1-button2", "view1-button21");
+				var button22 = _createRadioButtonProgrammatically("2", "view1-button2", "view1-button22");
+				var button23 = _createRadioButtonProgrammatically("3", "view1-button2", "view1-button23");
+
+				var button31 = _createRadioButtonProgrammaticallyWithSourceNodeReference("1", "view1-button3", "view1-button31");
+				var button32 = _createRadioButtonProgrammaticallyWithSourceNodeReference("2", "view1-button3", "view1-button32");
+				var button33 = _createRadioButtonProgrammaticallyWithSourceNodeReference("3", "view1-button3", "view1-button33");
+		
+				_assertCorrectRadioButton(button11, button12, button13);
+				_assertCorrectRadioButton(button21, button22, button23);
+				_assertCorrectRadioButton(button31, button32, button33);
+			},
+			function testInView2(){
+				var button11 = _createRadioButtonDeclaratively("view2-button11");
+				var button12 = _createRadioButtonDeclaratively("view2-button12");
+				var button13 = _createRadioButtonDeclaratively("view2-button13");
+				
+				var button21 = _createRadioButtonProgrammatically("1", "view2-button2", "view2-button21");
+				var button22 = _createRadioButtonProgrammatically("2", "view2-button2", "view2-button22");
+				var button23 = _createRadioButtonProgrammatically("3", "view2-button2", "view2-button23");
+
+				var button31 = _createRadioButtonProgrammaticallyWithSourceNodeReference("1", "view2-button3", "view2-button31");
+				var button32 = _createRadioButtonProgrammaticallyWithSourceNodeReference("2", "view2-button3", "view2-button32");
+				var button33 = _createRadioButtonProgrammaticallyWithSourceNodeReference("3", "view2-button3", "view2-button33");
+				
+				_showView2();
+				
+				_assertCorrectRadioButton(button11, button12, button13);
+				_assertCorrectRadioButton(button21, button22, button23);
+				_assertCorrectRadioButton(button31, button32, button33);
+			}
+		]);
+		runner.run();
+	});
+})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<input id="view1-button11" type="radio" name="view1-button1" value="1" data-dojo-type="dojox.mobile.RadioButton">
+		<input id="view1-button12" type="radio" name="view1-button1" value="2" data-dojo-type="dojox.mobile.RadioButton">
+		<input id="view1-button13" type="radio" name="view1-button1" value="3" data-dojo-type="dojox.mobile.RadioButton">
+		<br>
+		<div id="view1-button21"></div>
+		<div id="view1-button22"></div>
+		<div id="view1-button23"></div>
+		<br>
+		<input id="view1-button31" type="radio">
+		<input id="view1-button32" type="radio">
+		<input id="view1-button33" type="radio">
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<input id="view2-button11" type="radio" name="view2-button1" value="1" data-dojo-type="dojox.mobile.RadioButton">
+		<input id="view2-button12" type="radio" name="view2-button1" value="2" data-dojo-type="dojox.mobile.RadioButton">
+		<input id="view2-button13" type="radio" name="view2-button1" value="3" data-dojo-type="dojox.mobile.RadioButton">
+		<br>
+		<div id="view2-button21"></div>
+		<div id="view2-button22"></div>
+		<div id="view2-button23"></div>
+		<br>
+		<input id="view2-button31" type="radio">
+		<input id="view2-button32" type="radio">
+		<input id="view2-button33" type="radio">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/radiobutton/module.js b/dojox/mobile/tests/doh/radiobutton/module.js
new file mode 100644
index 0000000..0fe9b20
--- /dev/null
+++ b/dojox/mobile/tests/doh/radiobutton/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.RadioButton", require.toUrl("./RadioButtonTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/radiobutton/runTests.html b/dojox/mobile/tests/doh/radiobutton/runTests.html
new file mode 100644
index 0000000..56f4708
--- /dev/null
+++ b/dojox/mobile/tests/doh/radiobutton/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.radiobutton.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/roundrect/RoundRect.html b/dojox/mobile/tests/doh/roundrect/RoundRect.html
new file mode 100644
index 0000000..8362386
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrect/RoundRect.html
@@ -0,0 +1,69 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Round Rect</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+			dojo.addOnLoad(function(){
+				doh.register("dojox.mobile.test.doh.RoundRect", [
+					{
+						name: "RoundRect Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = dijit.byId("dojox_mobile_RoundRect_0");
+								if(dojo.isIE < 10){
+									doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
+								}else{
+									doh.assertEqual('mblRoundRect mblShadow', demoWidget.domNode.className);
+								}
+
+								demoWidget = dijit.byId("dojox_mobile_RoundRect_1");
+								doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
+							}));
+							return d;
+						}
+					},
+					{
+						name: "Set",
+						timeout: 4000,
+						runTest: function(){
+							var demoWidget = dijit.byId("dojox_mobile_RoundRect_0");
+							demoWidget.set({shadow :false});
+
+							demoWidget.set({shadow :false});
+//							doh.assertFalse(demoWidget.get("shadow"));
+//							doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Round Rectangle</h2>
+			<div dojoType="dojox.mobile.RoundRect" shadow="true">
+				This module provides some widgets that can be used to build web-based
+				applications for mobile devices such as iPhone or Android.
+			</div>
+			<div dojoType="dojox.mobile.RoundRect">
+				This module provides some widgets that can be used to build web-based
+				applications for mobile devices such as iPhone or Android.
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/roundrect/RoundRect_Programmatic.html b/dojox/mobile/tests/doh/roundrect/RoundRect_Programmatic.html
new file mode 100644
index 0000000..2d2894f
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrect/RoundRect_Programmatic.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Round Rect</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+			dojo.addOnLoad(function(){
+				var view = dijit.byId("foo");
+				var demoWidget = new dojox.mobile.RoundRect({shadow:"true"});
+				demoWidget.domNode.appendChild(dojo.doc.createTextNode("This module provides some widgets that can be used to build web-based applications for mobile devices such as iPhone or Android."));
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+
+				demoWidget = new dojox.mobile.RoundRect();
+				demoWidget.domNode.appendChild(dojo.doc.createTextNode("This module provides some widgets that can be used to build web-based applications for mobile devices such as iPhone or Android."));
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+
+				doh.register("dojox.mobile.test.doh.RoundRect", [
+					{
+						name: "RoundRect Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = dijit.byId("dojox_mobile_RoundRect_0");
+								if(dojo.isIE < 10){
+									doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
+								}else{
+									doh.assertEqual('mblRoundRect mblShadow', demoWidget.domNode.className);
+								}
+
+								demoWidget = dijit.byId("dojox_mobile_RoundRect_1");
+								doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
+							}));
+							return d;
+						}
+					},
+					{
+						name: "Set",
+						timeout: 4000,
+						runTest: function(){
+							var demoWidget = dijit.byId("dojox_mobile_RoundRect_0");
+							demoWidget.set({shadow :false});
+
+							demoWidget.set({shadow :false});
+//							doh.assertFalse(demoWidget.get("shadow"));
+//							doh.assertEqual('mblRoundRect', demoWidget.domNode.className);
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Round Rectangle</h2>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/roundrect/module.js b/dojox/mobile/tests/doh/roundrect/module.js
new file mode 100644
index 0000000..10abf1e
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrect/module.js
@@ -0,0 +1,8 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.RoundRect", require.toUrl("./RoundRect.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.RoundRect", require.toUrl("./RoundRect_Programmatic.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/roundrect/runTests.html b/dojox/mobile/tests/doh/roundrect/runTests.html
new file mode 100644
index 0000000..5b6aee0
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrect/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.roundrect.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataList.html b/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataList.html
new file mode 100644
index 0000000..1789ab1
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataList.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>RoundRectDataList</title>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.data.ItemFileWriteStore");
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.deviceTheme");
+			dojo.require("dojox.mobile.RoundRectDataList");
+
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+			var static_data = { 
+				items: [ 
+					{label: "Apple", 	moveTo: "dummy"},
+					{label: "Banana", 	moveTo: "dummy"},
+					{label: "Cherry", 	moveTo: "dummy"},
+					{label: "Grape", 	moveTo: "dummy"},
+					{label: "Kiwi", 	moveTo: "dummy"},
+					{label: "Lemon", 	moveTo: "dummy"},
+					{label: "Melon", 	moveTo: "dummy"},
+					{label: "Orange", 	moveTo: "dummy"},
+					{label: "Peach", 	moveTo: "dummy"}
+				]
+			};
+			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
+			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
+			var store = store1;
+			var newItems = [[],[]];
+
+			// switch to the selected store
+			function switchTo(store){
+				window.store = store;
+				dijit.byId("list").setStore(store);
+			}
+			// add a new item
+			function add1(){
+				var item = store.newItem({label: "New Item", moveTo: "dummy"});
+				this.newItems[(store == store1) ? 1 : 0].push(item);
+			}
+			// delete the added item
+			function delete1(){
+				var item = this.newItems[(store == store1) ? 1 : 0].pop();
+				if(item){
+					store.deleteItem(item);
+				}
+			}
+		</script>
+
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="RoundRectDataList.js"></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">RoundRectDataList</h1>
+			<ul dojoType="dojox.mobile.RoundRectDataList" id="list" store="store" query="{label: '*'}"></ul>
+			<p>show the different set:<br>
+			<input type="button" value="Set1" onclick="switchTo(store1)">
+			<input type="button" value="Set2" onclick="switchTo(store2)">
+			<p>alter the object store:<br>
+			<input type="button" value="Add" onclick="add1()">
+			<input type="button" value="Delete" onclick="delete1()">
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataList.js b/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataList.js
new file mode 100644
index 0000000..dac4483
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataList.js
@@ -0,0 +1,55 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.RoundRectDataList", [
+		{
+			name: "RoundRectDataList Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					verifyListItem("dojox_mobile_ListItem_0", 'Wi-Fi', '', "mblDomButtonArrow", true, true, false, false, /i-icon-1.png/i);
+
+					verifyListItem("dojox_mobile_ListItem_3", 'General', '', "mblDomButtonArrow", true, true, false, false, /i-icon-4.png/i, true);
+					
+				}),500);
+				return d;
+			}
+		},
+		{
+			name: "RoundRectDataList Verification2",
+			timeout: 10000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+
+					add1();
+					add1();
+					add1();
+					verifyListItem("dojox_mobile_ListItem_12", 'New Item', '', "mblDomButtonArrow", false, true, false, false);
+
+					delete1();
+					demoWidget = dijit.byId("dojox_mobile_ListItem_12");
+					doh.assertTrue(!demoWidget);
+
+					verifyListItem("dojox_mobile_ListItem_11", 'New Item', '', "mblDomButtonArrow", false, true, false, false);
+
+				}),1500);
+				return d;
+			}
+		},
+		{
+			name: "RoundRectDataList Verification3",
+			timeout: 10000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+
+					switchTo(store2);
+					verifyListItem("dojox_mobile_ListItem_13", 'Apple', '', "mblDomButtonArrow", false, true, false, false);
+
+				}),2500);
+				return d;
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataListTests.html b/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataListTests.html
new file mode 100644
index 0000000..310932f
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataListTests.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Round Rect Data List Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var IsEdgeToEdgeList = false;
+</script>
+<script type="text/javascript" src="../DataListTests.js"></script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<ul id="view1-dataList1" data-dojo-type="dojox.mobile.RoundRectDataList" store="fruits11" query="{label: '*'}"></ul>
+		<div id="view1-dataList2"></div>
+		<ul id="view1-dataList3"></ul>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<ul id="view2-dataList1" data-dojo-type="dojox.mobile.RoundRectDataList" store="fruits21" query="{label: '*'}"></ul>
+		<div id="view2-dataList2"></div>
+		<ul id="view2-dataList3"></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataList_Programmatic.html b/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataList_Programmatic.html
new file mode 100644
index 0000000..aa21e01
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectdatalist/RoundRectDataList_Programmatic.html
@@ -0,0 +1,79 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>RoundRectDataList</title>
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.data.ItemFileWriteStore");
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.deviceTheme");
+			dojo.require("dojox.mobile.RoundRectDataList");
+
+	        dojo.require("doh.runner");
+
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+			var static_data = { 
+				items: [ 
+					{label: "Apple", 	moveTo: "dummy"},
+					{label: "Banana", 	moveTo: "dummy"},
+					{label: "Cherry", 	moveTo: "dummy"},
+					{label: "Grape", 	moveTo: "dummy"},
+					{label: "Kiwi", 	moveTo: "dummy"},
+					{label: "Lemon", 	moveTo: "dummy"},
+					{label: "Melon", 	moveTo: "dummy"},
+					{label: "Orange", 	moveTo: "dummy"},
+					{label: "Peach", 	moveTo: "dummy"}
+				]
+			};
+			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
+			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
+			var store = store1;
+			var newItems = [[],[]];
+
+			// switch to the selected store
+			function switchTo(store){
+				window.store = store;
+				dijit.byId("list").setStore(store);
+			}
+			// add a new item
+			function add1(){
+				var item = store.newItem({label: "New Item", moveTo: "dummy"});
+				this.newItems[(store == store1) ? 1 : 0].push(item);
+			}
+			// delete the added item
+			function delete1(){
+				var item = this.newItems[(store == store1) ? 1 : 0].pop();
+				if(item){
+					store.deleteItem(item);
+				}
+			}
+
+			dojo.addOnLoad(function(){
+				var view = dijit.byId("foo");
+				var demoWidget = new dojox.mobile.RoundRectDataList({id:"list", store:store, query:{label: '*'}});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+			});
+		</script>
+
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="RoundRectDataList.js"></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">RoundRectDataList</h1>
+			<p>show the different set:<br>
+			<input type="button" value="Set1" onclick="switchTo(store1)">
+			<input type="button" value="Set2" onclick="switchTo(store2)">
+			<p>alter the object store:<br>
+			<input type="button" value="Add" onclick="add1()">
+			<input type="button" value="Delete" onclick="delete1()">
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/roundrectdatalist/module.js b/dojox/mobile/tests/doh/roundrectdatalist/module.js
new file mode 100644
index 0000000..c712e9e
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectdatalist/module.js
@@ -0,0 +1,11 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.RoundRectDataList", require.toUrl("./RoundRectDataList.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.RoundRectDataList", require.toUrl("./RoundRectDataList_Programmatic.html"),999999);
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.RoundRectDataList", require.toUrl("./RoundRectDataListTests.html"),999999);
+	}
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/roundrectdatalist/runTests.html b/dojox/mobile/tests/doh/roundrectdatalist/runTests.html
new file mode 100644
index 0000000..37bc431
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectdatalist/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.roundrectdatalist.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/roundrectdatalist/settings.json b/dojox/mobile/tests/doh/roundrectdatalist/settings.json
new file mode 100644
index 0000000..5be971a
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectdatalist/settings.json
@@ -0,0 +1,14 @@
+{
+  "items" : [
+    { "label" : "Wi-Fi",                        "icon" : "../../images/i-icon-1.png",   "moveTo": "wifi"                              },
+    { "label" : "Brightness & Wallpaper",       "icon" : "../../images/i-icon-2.png",   "moveTo": "bright"                            },
+    { "label" : "Picture Frame",                "icon" : "../../images/i-icon-3.png",   "moveTo": "picture"                           },
+    { "label" : "General",                      "icon" : "../../images/i-icon-4.png",   "moveTo": "general",  "selected": "true"      },
+    { "label" : "Mail, Contacts, Calendars",    "icon" : "../../images/i-icon-5.png",   "moveTo": "wifi"                              },
+    { "label" : "Safari",                       "icon" : "../../images/i-icon-6.png",   "moveTo": "bright"                            },
+    { "label" : "iPod",                         "icon" : "../../images/i-icon-7.png",   "moveTo": "picture"                           },
+    { "label" : "Video",                        "icon" : "../../images/i-icon-8.png",   "moveTo": "general"                           },
+    { "label" : "Photos",                       "icon" : "../../images/i-icon-9.png",   "moveTo": "wifi"                              },
+    { "label" : "Store",                        "icon" : "../../images/i-icon-10.png",  "moveTo": "bright"                            }
+  ]
+}
diff --git a/dojox/mobile/tests/doh/roundrectlist/RoundRectList.html b/dojox/mobile/tests/doh/roundrectlist/RoundRectList.html
new file mode 100644
index 0000000..fb10ba1
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectlist/RoundRectList.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Round Rect List</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+//			dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="RoundRectList.js"></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
+			<h2 id="Category" dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="item1" dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightText="Off" moveTo="bar">u1space</li>
+				<li id="item2" dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-2.png" rightText="On" moveTo="bar">u2space</li>
+				<li id="item3" dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="bar">Wi-Fi</li>
+			</ul>
+		</div>
+
+		<div id="bar" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="foo">u1space</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
+			<ul dojoType="dojox.mobile.RoundRectList" transition="fade">
+				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="foo">Video</li>
+				<li dojoType="dojox.mobile.ListItem" icon="../../images/i-icon-1.png" rightText="VPN">Maps</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off">Phone Number</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/roundrectlist/RoundRectList.js b/dojox/mobile/tests/doh/roundrectlist/RoundRectList.js
new file mode 100644
index 0000000..ed9df83
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectlist/RoundRectList.js
@@ -0,0 +1,73 @@
+
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.RoundRectList", [
+		{
+			name: "RoundRectList Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("Category");
+					doh.assertEqual('mblRoundRectCategory', demoWidget.domNode.className);
+					doh.assertEqual('Spaces', demoWidget.domNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_RoundRectList_0");
+					doh.assertEqual('mblRoundRectList', demoWidget.domNode.className);
+					verifyListItem("item1", 'u1space', 'Off', "mblDomButtonArrow", true, true, false);
+					verifyListItem("item2", 'u2space', 'On', "mblDomButtonArrow", true, true, false);
+					verifyListItem("item3", 'Wi-Fi', 'Off', "mblDomButtonArrow", false, true, false);
+					
+				}));
+				return d;
+			}
+		},
+		{
+			name: "RoundRectList Verification2",
+			timeout: 1000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				var demoWidget = dijit.byId("dojox_mobile_RoundRectList_0");
+				demoWidget.set({transition :"flip"});
+				doh.assertEqual("flip", demoWidget.get("transition"));
+				demoWidget.set({transition :"fade"});
+				doh.assertEqual("fade", demoWidget.get("transition"));
+
+//				fireOnClick("item3");
+				fireOnMouseDown("item3");
+				fireOnMouseUp("item3");
+				var view = dijit.byId("foo");
+				dojo.connect(view, "onAfterTransitionOut", this, d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_RoundRectCategory_0");
+					doh.assertEqual('mblRoundRectCategory', demoWidget.domNode.className);
+					doh.assertEqual('Applications', demoWidget.domNode.innerHTML);
+
+					demoWidget = dijit.byId("dojox_mobile_RoundRectList_1");
+					doh.assertEqual('mblRoundRectList', demoWidget.domNode.className);
+
+					verifyListItem("dojox_mobile_ListItem_0", 'Video', 'Off', "", false, true, false);
+					verifyListItem("dojox_mobile_ListItem_1", 'Maps', 'VPN', "", true, false, false);
+					verifyListItem("dojox_mobile_ListItem_2", 'Phone Number', 'Off', "", false, false, false);
+				}));
+				return d;
+			}
+		},
+		{
+			name: "RoundRectCategory getLabel",
+			timeout: 1000,
+			runTest: function(){
+				doh.assertEqual("Spaces", dijit.byId("Category").get("label")); 
+			}
+		},
+		{
+			name: "RoundRectCategory setLabel",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("Category");
+				demoWidget.set({label :"Value Changed"});
+				doh.assertEqual("Value Changed", demoWidget.get("label"));
+				doh.assertEqual('Value Changed', demoWidget.domNode.innerHTML);
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/roundrectlist/RoundRectListTests.html b/dojox/mobile/tests/doh/roundrectlist/RoundRectListTests.html
new file mode 100644
index 0000000..67f663f
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectlist/RoundRectListTests.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Edge To Edge List Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var IsEdgeToEdgeList = false;
+</script>
+<script type="text/javascript" src="../ListTests.js"></script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<ul id="view1-list1" data-dojo-type="dojox.mobile.RoundRectList" select="single">
+			<li data-dojo-type="dojox.mobile.ListItem" checked="true">Round Rect 1</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Round Rect 2</li>
+		</ul>		
+		<div id="view1-list2"></div>
+		<ul id="view1-list3"></ul>
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<ul id="view2-list1" data-dojo-type="dojox.mobile.RoundRectList" select="single">
+			<li data-dojo-type="dojox.mobile.ListItem" checked="true">Round Rect 1</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Round Rect 2</li>
+		</ul>		
+		<div id="view2-list2"></div>
+		<ul id="view2-list3"></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/roundrectlist/RoundRectList_Programmatic.html b/dojox/mobile/tests/doh/roundrectlist/RoundRectList_Programmatic.html
new file mode 100644
index 0000000..33ad28b
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectlist/RoundRectList_Programmatic.html
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Round Rect List</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+//			dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+		<script language="JavaScript" type="text/javascript">
+			dojo.addOnLoad(function(){
+				var view = dijit.byId("foo");
+				var demoWidget = new dojox.mobile.RoundRectList();
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+
+				var childWidget = new dojox.mobile.ListItem({id:"item1", icon:"../../images/i-icon-1.png", rightText:"Off", moveTo:"bar", label:"u1space"});
+				demoWidget.addChild(childWidget);
+				childWidget = new dojox.mobile.ListItem({id:"item2", icon:"../../images/i-icon-2.png", rightText:"On", moveTo:"bar",label:"u2space"});
+				demoWidget.addChild(childWidget);
+//				childWidget = new dojox.mobile.ListItem({id:"item3"});
+				childWidget = new dojox.mobile.ListItem({id:"item3", rightText:"Off", moveTo:"bar", label:"Wi-Fi"});
+				demoWidget.addChild(childWidget);
+//				childWidget.set({rightText:"Off", moveTo:"bar", label :"Wi-Fi"});
+
+				view = dijit.byId("bar");
+				demoWidget = new dojox.mobile.RoundRectList();
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+
+				childWidget = new dojox.mobile.ListItem({rightText:"Off", label:"Video", moveTo:"foo"});
+				demoWidget.addChild(childWidget);
+				childWidget = new dojox.mobile.ListItem({icon:"../../images/i-icon-1.png", rightText:"VPN", label:"Maps"});
+				demoWidget.addChild(childWidget);
+				childWidget = new dojox.mobile.ListItem({rightText:"Off", label:"Phone Number"});
+				demoWidget.addChild(childWidget);
+			});
+		</script>
+		</script>
+
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="RoundRectList.js"></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
+			<h2 id="Category" dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
+			<ul id="RoundRectList1" dojoType="dojox.mobile.RoundRectList">
+			</ul>
+		</div>
+
+		<div id="bar" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="foo">u1space</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/roundrectlist/module.js b/dojox/mobile/tests/doh/roundrectlist/module.js
new file mode 100644
index 0000000..b64bda6
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectlist/module.js
@@ -0,0 +1,9 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.RoundRectList", require.toUrl("./RoundRectList_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.RoundRectList", require.toUrl("./RoundRectList.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.RoundRectList", require.toUrl("./RoundRectListTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/roundrectlist/runTests.html b/dojox/mobile/tests/doh/roundrectlist/runTests.html
new file mode 100644
index 0000000..0fc67ba
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectlist/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.roundrectlist.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/roundrectstorelist/RoundRectStoreList.html b/dojox/mobile/tests/doh/roundrectstorelist/RoundRectStoreList.html
new file mode 100644
index 0000000..5f2e51e
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectstorelist/RoundRectStoreList.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectStoreList</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+	<script type="text/javascript">
+		var IsEdgeToEdgeList = false;
+	</script>
+	<script type="text/javascript" src="StoreList.js"></script>
+</head>
+<body style="visibility:hidden;">
+	<script type="dojo/require">
+		CustomListItem: "dojox/mobile/tests/doh/CustomListItem"
+	</script>
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectStoreList" id="list" data-dojo-props='store:store, query:{}, itemRenderer: CustomListItem'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/roundrectstorelist/RoundRectStoreList_Programmatic.html b/dojox/mobile/tests/doh/roundrectstorelist/RoundRectStoreList_Programmatic.html
new file mode 100644
index 0000000..1be16f6
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectstorelist/RoundRectStoreList_Programmatic.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectStoreList</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"dojo/ready", // dojo.ready
+			"dijit/registry",  // dijit.byId
+			"dojox/mobile/tests/doh/CustomListItem",
+			"dojox/mobile/RoundRectStoreList",
+			"dojox/mobile",				// This is a mobile app.
+			"dojox/mobile/View",		// This mobile app uses mobile view
+			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+			"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+		], function(ready, registry, CustomListItem, RoundRectStoreList){
+			ready(function(){
+				var view = registry.byId("foo");
+				var demoWidget = new RoundRectStoreList({id:"list", store:store, query:{}, itemRenderer: CustomListItem});
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+			});
+		});
+</script>
+	<script type="text/javascript">
+		var IsEdgeToEdgeList = false;
+	</script>
+	<script type="text/javascript" src="StoreList.js"></script>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+		<h1 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/roundrectstorelist/StoreList.js b/dojox/mobile/tests/doh/roundrectstorelist/StoreList.js
new file mode 100644
index 0000000..e4835a1
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectstorelist/StoreList.js
@@ -0,0 +1,217 @@
+require([
+	"dojo/parser",
+	"dojo/_base/Deferred",
+	"dojo/store/Cache",
+	"dojo/store/JsonRest",
+	"dojo/store/Memory",
+	"dojo/store/Observable",
+	"dojo/ready", // dojo.ready
+	"dijit/registry",
+	"doh/runner",	//doh functions
+	"dojox/mobile/EdgeToEdgeStoreList",
+	"dojox/mobile/RoundRectStoreList",
+	"dojox/mobile/tests/doh/CustomListItem",
+	/*"dojox/mobile/parser",*/
+	"dojox/mobile",
+	"dojox/mobile/compat"
+], function(parser, Deferred, Cache, JsonRest, Memory, Observable, ready, registry, runner, EdgeToEdgeStoreList, RoundRectStoreList){
+
+	var CLASS_NAME;
+	var DataList;
+	var testName;
+
+	if(IsEdgeToEdgeList){
+		CLASS_NAME = "mblEdgeToEdgeList";
+		DataList = EdgeToEdgeStoreList;
+		testName = "dojox.mobile.test.doh.EdgeToEdgeStoreList";
+	}else{
+		CLASS_NAME = "mblRoundRectList";
+		DataList = RoundRectStoreList;
+		testName = "dojox.mobile.test.doh.RoundRectStoreList";
+	}
+
+	var static_data2 = [
+		{label: "Apple", 	moveTo: "dummy"},
+		{label: "Banana", 	moveTo: "dummy"},
+		{label: "Cherry", 	moveTo: "dummy"},
+		{label: "Grape", 	moveTo: "dummy"},
+		{label: "Kiwi", 	moveTo: "dummy"},
+		{label: "Lemon", 	moveTo: "dummy"},
+		{label: "Melon", 	moveTo: "dummy"},
+		{label: "Orange", 	moveTo: "dummy"},
+		{label: "Peach", 	moveTo: "dummy"}
+	];
+	var url = "settings2.json";
+	store1 = new JsonRest({idProperty:"label", target: url});
+	store2 = Observable(new Memory({idProperty:"label", data: static_data2}));
+	store1.__counter = store2.__counter = 1;
+	store = store1;
+
+	// switch to the selected store
+	switchTo = function(store){
+		window.store = store;
+		registry.byId("list").setStore(store);
+	};
+	// add a new item
+	add1 = function(){
+		store.add({
+			label: "New Item "+(store.__counter++),
+			icon: "../../images/i-icon-1.png",
+			moveTo: "dummy"
+		});
+	};
+	// delete the added item
+	delete1 = function(){
+		if(store.__counter > 1){
+			store.remove("New Item "+(--store.__counter));
+		}
+	};
+	// modify the added item
+	var modif_counter = 0;
+	modify1 = function(){
+		if(store.__counter > 1){
+			store.put({
+				label: "New Item "+(store.__counter-1),
+				rightText: ++modif_counter + " changes"
+			});
+		}
+	};
+
+	ready(function(){
+		runner.register(testName, [
+			{
+				name: DataList + " Verification",
+				timeout: 4000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var demoWidget = registry.byId("dojox_mobile_ListItem_0");
+						// check whether we correctly constructed a custom item
+						runner.assertTrue(demoWidget.customProp);
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertTrue(demoWidget.iconNode.src.search(/i-icon-1.png/i) != -1);
+						runner.assertEqual('mblListItemRightIcon', demoWidget.rightIconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('Wi-Fi', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						demoWidget = registry.byId("dojox_mobile_ListItem_3");
+						runner.assertEqual('mblListItem mblListItemSelected', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertTrue(demoWidget.iconNode.src.search(/i-icon-4.png/i) != -1);
+						runner.assertEqual('mblListItemRightIcon', demoWidget.rightIconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('General', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+						
+					}),500);
+					return d;
+				}
+			},
+			{
+				name: DataList + " Verification2",
+				timeout: 10000,
+				runTest: function(){
+					var d = new doh.Deferred();
+					setTimeout(d.getTestCallback(function(){
+
+						switchTo(store2);
+						var demoWidget = registry.byId("dojox_mobile_ListItem_13");
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual(null, demoWidget.iconNode);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('Grape', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+
+					}),2500);
+					return d;
+				}
+			},
+			{
+				name: DataList + " Verification3",
+				timeout: 10000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+
+						add1();
+						add1();
+						add1();
+						var demoWidget = registry.byId("dojox_mobile_ListItem_19");
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('New Item 1', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						delete1();
+						demoWidget = registry.byId("dojox_mobile_ListItem_21");
+						runner.assertTrue(!demoWidget);
+
+						demoWidget = registry.byId("dojox_mobile_ListItem_20");
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('New Item 2', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						modify1();
+						runner.assertEqual(modif_counter+' changes', demoWidget.get("rightText"), "modify store item");
+					}),1500);
+					return d;
+				}
+			},
+			{
+				name: DataList + " Verification4 (1.8 compat mode)",
+				timeout: 10000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+
+						// Check compatibility with old-style widgets that define only an onUpdate method and no onAdd method
+						// (like in Dojo Mobile 1.8). In that case onUpdate is called instead of onAdd, and put() is not handled.
+						var listWidget = registry.byId("list");
+						listWidget.onAdd = undefined;
+						listWidget.onUpdate = function(/*Object*/item, /*Number*/insertedInto){
+							// summary:
+							//		Adds a new item or updates an existing item.
+							if(insertedInto === this.getChildren().length){
+								this.addChild(this.createListItem(item)); // add a new ListItem
+							}else{
+								this.getChildren()[insertedInto].set(item); // update the existing ListItem
+							}
+						};
+
+						add1();
+						add1();
+						add1();
+						var demoWidget = registry.byId("dojox_mobile_ListItem_22");
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('New Item 3', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						delete1();
+						demoWidget = registry.byId("dojox_mobile_ListItem_24");
+						runner.assertTrue(!demoWidget);
+
+						demoWidget = registry.byId("dojox_mobile_ListItem_23");
+						runner.assertEqual('mblListItem', demoWidget.domNode.className);
+						runner.assertEqual('mblImageIcon mblListItemIcon', demoWidget.iconNode.className);
+						runner.assertEqual('mblListItemLabel', demoWidget.labelNode.className);
+						runner.assertEqual('New Item 4', demoWidget.labelNode.innerHTML);
+						runner.assertEqual('mblDomButtonArrow mblDomButton', demoWidget.rightIconNode.childNodes[0].className);
+
+						modify1();
+						runner.assertEqual("", demoWidget.get("rightText"), "modify store item (noop in compat mode)");
+					}),1500);
+					return d;
+				}
+			}
+		]);
+		runner.run();
+	});
+});
diff --git a/dojox/mobile/tests/doh/roundrectstorelist/module.js b/dojox/mobile/tests/doh/roundrectstorelist/module.js
new file mode 100644
index 0000000..5bc234d
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectstorelist/module.js
@@ -0,0 +1,8 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.RoundRectStoreList", require.toUrl("./RoundRectStoreList.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.RoundRectStoreList", require.toUrl("./RoundRectStoreList_Programmatic.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/roundrectstorelist/runTests.html b/dojox/mobile/tests/doh/roundrectstorelist/runTests.html
new file mode 100644
index 0000000..3ff39e3
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectstorelist/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.roundrectstorelist.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/roundrectstorelist/settings2.json b/dojox/mobile/tests/doh/roundrectstorelist/settings2.json
new file mode 100644
index 0000000..71b3484
--- /dev/null
+++ b/dojox/mobile/tests/doh/roundrectstorelist/settings2.json
@@ -0,0 +1,12 @@
+[
+    { "label" : "Wi-Fi",                        "icon" : "../../images/i-icon-1.png",   "moveTo": "wifi"                              },
+    { "label" : "Brightness & Wallpaper",       "icon" : "../../images/i-icon-2.png",   "moveTo": "bright"                            },
+    { "label" : "Picture Frame",                "icon" : "../../images/i-icon-3.png",   "moveTo": "picture"                           },
+    { "label" : "General",                      "icon" : "../../images/i-icon-4.png",   "moveTo": "general",  "selected": "true"      },
+    { "label" : "Mail, Contacts, Calendars",    "icon" : "../../images/i-icon-5.png",   "moveTo": "wifi"                              },
+    { "label" : "Safari",                       "icon" : "../../images/i-icon-6.png",   "moveTo": "bright"                            },
+    { "label" : "iPod",                         "icon" : "../../images/i-icon-7.png",   "moveTo": "picture"                           },
+    { "label" : "Video",                        "icon" : "../../images/i-icon-8.png",   "moveTo": "general"                           },
+    { "label" : "Photos",                       "icon" : "../../images/i-icon-9.png",   "moveTo": "wifi"                              },
+    { "label" : "Store",                        "icon" : "../../images/i-icon-10.png",  "moveTo": "bright"                            }
+ ]
diff --git a/dojox/mobile/tests/doh/scrollablepane/ScrollablePaneTests.html b/dojox/mobile/tests/doh/scrollablepane/ScrollablePaneTests.html
new file mode 100644
index 0000000..6a0bc62
--- /dev/null
+++ b/dojox/mobile/tests/doh/scrollablepane/ScrollablePaneTests.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>ScrollablePane Tests</title>
+<script type="text/javascript" src="../../../../../dojox/mobile/deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	require([
+			"dojo/ready",
+			"dojo/sniff",
+			"dojo/dom",
+			"dojo/dom-geometry",
+			"doh/runner",
+		 	"dojox/mobile",				// This is a mobile app.
+			"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
+			"dojox/mobile/ScrollablePane"
+	], function(ready, has, dom, domGeom, runner){
+		ready(function(){
+			var view = dom.byId("view");
+			var containerDiv = dom.byId("containerDiv");
+			var scrollablePane = dom.byId("scrollablePane");
+			runner.register("dojox.mobile.test.doh.scrollablepane.ScrollablePaneTests", [
+				{
+					name: "Verify that ticket #15761 is fixed",
+					timeout: 4000,
+					runTest: function(){
+						var bodyTopPadding = has("ie")>=10?8:0;
+						var viewPosition = domGeom.position(view, false);
+						console.log(viewPosition);
+						runner.assertEqual(0 + bodyTopPadding, viewPosition.y, "view position y is not the expected one");
+						runner.assertEqual(180, viewPosition.h, "view position h is not the expected one");
+						var containerDivPosition = domGeom.position(containerDiv, false);
+						runner.assertEqual(20 + bodyTopPadding, containerDivPosition.y, "container DIV position y is not the expected one");
+						runner.assertEqual(140, containerDivPosition.h, "container DIV position h is not the expected one");
+						console.log(containerDivPosition);
+						var scrollablePanePosition = domGeom.position(scrollablePane, false);
+						console.log(scrollablePanePosition);
+						runner.assertEqual(40 + bodyTopPadding, scrollablePanePosition.y, "scrollable pane position y is not the expected one");
+						runner.assertEqual(100, scrollablePanePosition.h, "scrollable pane position h is not the expected one");
+					}
+				}
+			]);
+			runner.run();
+		});
+	});
+</script>
+<style type="text/css">
+</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view" data-dojo-type="dojox.mobile.View" style="border-top: 20px solid blue; border-bottom: 20px solid blue;">
+		<div id="containerDiv" style="border-top: 20px solid green; border-bottom: 20px solid green; height: 100px; position: relative;">
+			<div id="scrollablePane" data-dojo-type="dojox.mobile.ScrollablePane" height="inherit" style="border-top: 20px solid white; border-bottom: 20px solid white; background-color: red; color: white;">
+				This is a first scrollable pane.
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/scrollablepane/module.js b/dojox/mobile/tests/doh/scrollablepane/module.js
new file mode 100644
index 0000000..946dc44
--- /dev/null
+++ b/dojox/mobile/tests/doh/scrollablepane/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require"], function(doh, require){
+
+	doh.registerUrl("dojox.mobile.tests.doh.ScrollablePane", require.toUrl("./ScrollablePaneTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/scrollablepane/runTests.html b/dojox/mobile/tests/doh/scrollablepane/runTests.html
new file mode 100644
index 0000000..361713f
--- /dev/null
+++ b/dojox/mobile/tests/doh/scrollablepane/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.scrollablepane.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/slider/SliderTests.html b/dojox/mobile/tests/doh/slider/SliderTests.html
new file mode 100644
index 0000000..877417f
--- /dev/null
+++ b/dojox/mobile/tests/doh/slider/SliderTests.html
@@ -0,0 +1,157 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Slider Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+require([
+	"dojo/dom-construct", // dojo.place
+	"dojo/dom-class", // dojo.hasClass
+	"dojo/ready", // dojo.ready
+	"dijit/registry",  // dijit.byId
+	"doh/runner",	//doh functions
+	"dojox/mobile/Slider",
+	"dojox/mobile",				// This is a mobile app.
+	"dojox/mobile/View",		// This mobile app uses mobile view
+	"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+	"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+], function(domConst, domClass, ready, registry, runner, Slider){
+
+	var WIDGET_CLASSNAME1 = "mblSlider";
+	var WIDGET_VALUE = "31.4";
+	var WIDGET_VALUE2 = WIDGET_VALUE + "%";
+
+	function _createSliderDeclaratively(widgetId) {
+		return registry.byId(widgetId);
+	};
+
+	function _createSliderProgrammatically(placeHolderId, widgetId){
+		var r = new Slider({id:widgetId, name:"sh2", value:"31.4", min:"0", max:"100", step:"0.1", type:"range", style:"width:150px"});
+		runner.assertNotEqual(null, r);
+		domConst.place(r.domNode, placeHolderId, "replace");
+		r.startup();
+		
+		return r;
+	};
+
+	function _createSliderProgrammaticallyWithSourceNodeReference(widgetId){
+		// Create IconContainer
+		var r = new Slider({}, widgetId);
+		r.startup();
+
+		return r;
+	};
+
+
+
+	function _assertCorrectSlider(widget, noIcon, rightIcon, rightIcon2, rightText, boxText){
+		runner.assertNotEqual(null, widget, "Slider: Did not instantiate. id=" + widget.domNode.id);
+		runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + widget.domNode.id);
+		runner.assertEqual(WIDGET_VALUE, widget.valueNode.value);
+		runner.assertEqual(WIDGET_VALUE, widget.get('value'));
+		runner.assertEqual(WIDGET_VALUE2, widget.progressBar.style.width);
+		runner.assertEqual(WIDGET_VALUE2, widget.handle.style.left);
+	};
+
+	function _showView2(){
+		var view1 = registry.byId("view1");
+		view1.performTransition("view2", 1, "none");
+	};
+
+	ready(function(){
+		runner.register("dojox.mobile.test.doh.Slider", [
+			{
+				name: "Slider Verification1",
+				timeout: 4000,
+				runTest: function(){
+					var widget1 = _createSliderDeclaratively("view1-Slider1");
+					var widget2 = _createSliderProgrammatically("view1-Slider2Place", "view1-Slider2");
+					var widget3 = _createSliderProgrammaticallyWithSourceNodeReference("view1-Slider3");
+
+					_assertCorrectSlider(widget1);
+					_assertCorrectSlider(widget2);
+//					_assertCorrectSlider(widget3);
+				}
+			},
+			{
+				name: "Slider Verification2",
+				timeout: 4000,
+				runTest: function(){
+					var widget1 = _createSliderDeclaratively("view2-Slider1");
+					var widget2 = _createSliderProgrammatically("view2-Slider2Place", "view2-Slider2");
+					var widget3 = _createSliderProgrammaticallyWithSourceNodeReference("view2-Slider3");
+
+					var d = new runner.Deferred();
+					var handle2 = dojo.subscribe("/dojox/mobile/afterTransitionIn", d.getTestCallback(function(view){
+						if(view.id=="view2"){
+							dojo.unsubscribe(handle2);
+						}
+						_assertCorrectSlider(widget1);
+						_assertCorrectSlider(widget2);
+//						_assertCorrectSlider(widget3);
+					}));
+					_showView2();
+					return d;
+				}
+			}
+		]);
+		runner.run();
+	});
+})
+</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:"true"'>
+		<h1>View1</h1>
+		<table>
+			<tr>
+				<td>0</td>
+				<td><input id="view1-Slider1" data-dojo-type="dojox.mobile.Slider" name="sh1" value="31.4" min="0" max="100" step="0.1" type="range" style="width:150px;"></td>
+				<td>100</td>
+			</tr>
+		</table>
+		<table>
+			<tr>
+				<td>0</td>
+				<td><div id="view1-Slider2Place"></div></td>
+				<td>100</td>
+			</tr>
+		</table>
+		<table>
+			<tr>
+				<td>0</td>
+				<td><input id="view1-Slider3" name="sh3" value="31.4" min="0" max="100" step="0.1" type="range" style="width:150px;"></td>
+				<td>100</td>
+			</tr>
+		</table>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View2</h1>
+		<table>
+			<tr>
+				<td>0</td>
+				<td><input id="view2-Slider1" data-dojo-type="dojox.mobile.Slider" name="sh1" value="31.4" min="0" max="100" step="0.1" type="range" style="width:150px;"></td>
+				<td>100</td>
+			</tr>
+		</table>
+		<table>
+			<tr>
+				<td>0</td>
+				<td><div id="view2-Slider2Place"></div></td>
+				<td>100</td>
+			</tr>
+		</table>
+		<table>
+			<tr>
+				<td>0</td>
+				<td><input id="view2-Slider3" name="sh3" value="31.4" min="0" max="100" step="0.1" type="range" style="width:150px;"></td>
+				<td>100</td>
+			</tr>
+		</table>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/slider/module.js b/dojox/mobile/tests/doh/slider/module.js
new file mode 100644
index 0000000..351c71e
--- /dev/null
+++ b/dojox/mobile/tests/doh/slider/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.Slider", require.toUrl("./SliderTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/slider/runTests.html b/dojox/mobile/tests/doh/slider/runTests.html
new file mode 100644
index 0000000..a856e9f
--- /dev/null
+++ b/dojox/mobile/tests/doh/slider/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.slider.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/spinwheel/SpinWheel_Programmatic.html b/dojox/mobile/tests/doh/spinwheel/SpinWheel_Programmatic.html
new file mode 100644
index 0000000..3050756
--- /dev/null
+++ b/dojox/mobile/tests/doh/spinwheel/SpinWheel_Programmatic.html
@@ -0,0 +1,195 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Custom SpinWheel</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom-construct", // dojo.place
+			"dojo/ready", // dojo.ready
+			"dijit/registry",  // dijit.byId
+			"doh/runner",	//doh functions
+			"dojox/mobile/SpinWheel",
+			"dojox/mobile/SpinWheelSlot",
+			"dojox/mobile",				// This is a mobile app.
+			"dojox/mobile/View",		// This mobile app uses mobile view
+			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+			"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+		], function(domConst, ready, registry, runner, SpinWheel, SpinWheelSlot){
+			ready(function(){
+				var view = registry.byId("view1");
+				var demoWidget = new SpinWheel({id:"spin1"});
+				demoWidget.placeAt(view.containerNode);
+				
+				// No initial value specified
+				var slot0 = new SpinWheelSlot({labels:['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'], 
+					style:"text-align:center;width:40px;"});
+				slot0._valueBeforeStartup = slot0.get("value");
+				slot0._keyBeforeStartup = slot0.get("key");
+				demoWidget.addChild(slot0);
+				
+				// Initial value: C
+				var slot1 = new SpinWheelSlot({labels:['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'], 
+					value:'C', style:"text-align:center;width:40px;"});
+				demoWidget.addChild(slot1);
+
+				// No initial value specified
+				var slot2 = new SpinWheelSlot({labelFrom:3000, labelTo:3100, style:"width:70px;"});
+				demoWidget.addChild(slot2);
+				
+				// Initial value: 3009 
+				var slot3 = new SpinWheelSlot({labelFrom:3000, labelTo:3100, value:3009, style:"width:70px;"});
+				demoWidget.addChild(slot3);
+
+				domConst.create("div", {className: "mblSpinWheelSlot", id:"pt"}, demoWidget.containerNode);
+				domConst.create("div", {className: "mblSpinWheelSlot", id:"txt", innerHTML:"."}, demoWidget.containerNode);
+
+				var slot4 = new SpinWheelSlot({labelFrom:0, labelTo:9, style:"width:30px;"});
+				demoWidget.addChild(slot4);
+
+				var slot5 = new SpinWheelSlot({labels:['pt','px','cm'], style:"width:50px;"});
+				demoWidget.addChild(slot5);
+
+				var slot6 = new SpinWheelSlot({
+					labels:[
+					'<img src=../../images/i-icon-1.png>',
+					'<img src=../../images/i-icon-2.png>',
+					'<img src=../../images/i-icon-3.png>',
+					'<img src=../../images/i-icon-4.png>',
+					'<img src=../../images/i-icon-5.png>',
+					'<img src=../../images/i-icon-6.png>',
+					'<img src=../../images/i-icon-7.png>',
+					'<img src=../../images/i-icon-8.png>',
+					'<img src=../../images/i-icon-9.png>',
+					'<img src=../../images/i-icon-10.png>'
+					],
+					style:"width:70px;text-align: center;"
+				});
+				demoWidget.addChild(slot6);
+
+				var slot7 = new SpinWheelSlot({
+					items:[
+						['key1', 'value1'], 
+						['key2', 'value2'],
+						['key2', 'value2']
+					],
+					value:'value2',
+					style:"text-align:center;width:40px;"});
+				demoWidget.addChild(slot7);
+
+				demoWidget.reset();
+			});
+		})
+	</script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready", // dojo.ready
+			"dijit/registry",  // dijit.byId
+			"doh/runner",	//doh functions
+			"dojox/mobile/SpinWheel",
+			"dojox/mobile/SpinWheelSlot",
+			"dojox/mobile",				// This is a mobile app.
+			"dojox/mobile/View",		// This mobile app uses mobile view
+			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+			"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+		], function(ready, registry, runner, SpinWheel, SpinWheelSlot){
+			ready(function(){
+				
+				var testEmptySlot = function(emptySlot){
+					// Test for the edge-case of slots with no items. 
+					// Mainly checks that no error is thrown.
+					emptySlot.setInitialValue();
+					emptySlot.resize();
+					doh.assertEqual("", emptySlot.get("value"));
+					emptySlot.set("value", "some value"); // no-op for empty slot
+					doh.assertEqual("", emptySlot.get("value"));
+				};
+				
+				runner.register("dojox.mobile.test.doh.SpinWheel", [
+					{
+						name: "SpinWheel Verification",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								var demoWidget = registry.byId("spin1");
+								var slots = demoWidget.getSlots();
+								doh.assertEqual('A', slots[0].get("value"));
+								doh.assertEqual('C', slots[1].get("value"));
+								doh.assertEqual('3000', slots[2].get("value"));
+								doh.assertEqual('3009', slots[3].get("value"));
+								doh.assertEqual('0', slots[4].get("value"));
+								doh.assertEqual('pt', slots[5].get("value"));
+								doh.assertEqual('<img src=../../images/i-icon-1.png>', slots[6].get("value"));
+								doh.assertEqual('value2', slots[7].get("value"));
+								doh.assertEqual('A', slots[0]._valueBeforeStartup);
+								doh.assertEqual(0, slots[0]._keyBeforeStartup);
+								
+								// Test case for #16519
+								var noError = true; 
+								var slot8 = new SpinWheelSlot({
+									items:[
+										['key1', 'value1'], 
+										['key2', 'value2'],
+										['key2', 'value2']
+									],
+									value:'value2',
+									style:"text-align:center;width:40px;"});
+								try{
+									slot8.disableValues(2);
+								}catch(error){
+									noError = false;
+								}
+								doh.assertTrue(noError, "Calling SpinWheelSlot.disableValues shouldn't throw an exception!");
+								
+								// Test case for #16701 (support for the edge-case of empty slots)
+								// (without the fix of #16701, leads to infinite loop)
+								testEmptySlot(new SpinWheelSlot({
+									items:[] // empty
+								}));
+								testEmptySlot(new SpinWheelSlot({
+									labels:[] // empty 
+								}));
+								testEmptySlot(new SpinWheelSlot()); // empty
+							}),2000);
+							return d;
+						}
+					}
+				]);
+				runner.run();
+			});
+			
+		})
+	</script>
+
+	<style>
+	#spin1 {
+		width: 304px;
+		margin: 10px auto;
+	}
+	#pt {
+		width: 20px;
+	}
+	#txt {
+		width: 10px;
+		margin-left: -15px;
+		padding-top: 85px;
+		font-size: 24px;
+		font-weight: bold;
+		border: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Custom SpinWheel</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/spinwheel/module.js b/dojox/mobile/tests/doh/spinwheel/module.js
new file mode 100644
index 0000000..acebe6b
--- /dev/null
+++ b/dojox/mobile/tests/doh/spinwheel/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.SpinWheel", require.toUrl("./SpinWheel_Programmatic.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/spinwheel/runTests.html b/dojox/mobile/tests/doh/spinwheel/runTests.html
new file mode 100644
index 0000000..8b1400e
--- /dev/null
+++ b/dojox/mobile/tests/doh/spinwheel/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.spinwheel.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/spinwheeldatepicker/SpinWheelDatePicker.html b/dojox/mobile/tests/doh/spinwheeldatepicker/SpinWheelDatePicker.html
new file mode 100644
index 0000000..046d89a
--- /dev/null
+++ b/dojox/mobile/tests/doh/spinwheeldatepicker/SpinWheelDatePicker.html
@@ -0,0 +1,267 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport"
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>SpinWheelDatePicker</title>
+
+	<script type="text/javascript"
+		src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript"
+		src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		var onYearSet, onMonthSet, onDaySet;
+		require([
+			"dojo/ready", "dijit/registry", "doh/runner", "dojo/_base/array",
+			"dojo/dom-class", "dojox/mobile", "dojox/mobile/compat", "dojox/mobile/parser", 
+			"dojox/mobile/SpinWheelDatePicker"],
+			function(ready, registry, runner, array, domClass){
+						
+			var onYearSetCounter = 0, onMonthSetCounter = 0, onDaySetCounter = 0,
+				yearWatchCounter = 0, monthWatchCounter = 0, dayWatchCounter = 0;
+			var initCounters, checkCounters;
+
+			onYearSet = function(){
+				onYearSetCounter++;
+			};
+			onMonthSet = function(){
+				onMonthSetCounter++;
+			};
+			onDaySet = function(){
+				onDaySetCounter++;
+			};
+
+			var initCounters = function(){
+				onYearSetCounter = onMonthSetCounter = onDaySetCounter = 0;
+				yearWatchCounter = monthWatchCounter = dayWatchCounter = 0;
+			};
+
+			ready(function(){
+				var picker = registry.byId("picker1"),
+					yearSlot = picker.slots[0],
+					monthSlot = picker.slots[1],
+					daySlot = picker.slots[2];
+
+				yearSlot.watch("value", function(name, oldVal, newVal){
+					yearWatchCounter++;
+				});
+				monthSlot.watch("value", function(name, oldVal, newVal){
+					monthWatchCounter++;
+				});
+				daySlot.watch("value", function(name, oldVal, newVal){
+					dayWatchCounter++;
+				});
+
+				var showCounters = function(txt){
+					// Just for debugging.
+					console.log("==============================");
+					if(txt) console.log(txt + ":");
+					console.log("yearSetCounter: " + onYearSetCounter);
+					console.log("monthSetCounter: " + onMonthSetCounter);
+					console.log("daySetCounter: " + onDaySetCounter);
+					console.log("yearWatchCounter: " + yearWatchCounter);
+					console.log("monthWatchCounter: " + monthWatchCounter);
+					console.log("dayWatchCounter: " + dayWatchCounter);
+					console.log("==============================");
+				};
+				
+				var checkCounters = function(
+						expectedOnYearSetCounter, expectedOnMonthSetCounter, expectedOnDaySetCounter,
+						expectedYearWatchCounter, expectedMonthWatchCounter, expectedDayWatchCounter){
+					// showCounters();
+					runner.assertEqual(expectedOnYearSetCounter, onYearSetCounter, "Unexpected onYearSetCounter");
+					runner.assertEqual(expectedOnMonthSetCounter, onMonthSetCounter, "Unexpected onMonthSetCounter");
+					runner.assertEqual(expectedOnDaySetCounter, onDaySetCounter, "Unexpected onDaySetCounter");
+					runner.assertEqual(expectedYearWatchCounter, yearWatchCounter, "Unexpected yearWatchCounter");
+					runner.assertEqual(expectedMonthWatchCounter, monthWatchCounter, "Unexpected monthWatchCounter");
+					runner.assertEqual(expectedDayWatchCounter, dayWatchCounter, "Unexpected dayWatchCounter");
+				};
+				
+				var checkSlotValues = function(expectedYear, expectedMonth, expectedDay){
+					runner.assertEqual(expectedYear, picker.slots[0].get("value"), "Unexpected value of year slot");
+					runner.assertEqual(expectedDay, picker.slots[2].get("value"), "Unexpected value of day slot");
+					// For the month, note that the label (and value) of the month slot is 
+					// localized, and is also browser-dependant (for instance, on IE8 in English
+					// locale, the value for the fifth month is "may", while on other browsers
+					// it is "May". Hence, in this test, instead of comparing directly the
+					// value of the slot with a given string ("May"), we start from the month
+					// number and we compare the current value of the slot with the label 
+					// at the corresponding index. Thus the test is independent on locale 
+					// and browser localization of month names.  
+					var monthSlot = picker.slots[1];
+					var expectedMonthLabel = monthSlot.labels[expectedMonth - 1];
+					runner.assertEqual(expectedMonthLabel, monthSlot.get("value"), "Unexpected value of month slot");
+				};
+				
+				var checkGrayedDaySlots = function(minGrayDay, title){
+					minGrayDay--; // index 0 holds for day 1
+					var daySlot = picker.slots[2];
+					var child, i;
+					array.forEach(daySlot.panelNodes, function(panel){
+						for(i = 0; i < minGrayDay; i++){
+							child = panel.childNodes[i];
+							runner.assertFalse(domClass.contains(child, "mblSpinWheelSlotLabelGray"),
+								" Day " + (i + 1) + " should NOT be grayed. " + 
+								"Actual child.className: " + child.className + " (" + title + ")");
+						}
+					});
+					array.forEach(daySlot.panelNodes, function(panel){
+						for(i = minGrayDay; i < panel.childNodes.length; i++){
+							child = panel.childNodes[i];
+							runner.assertTrue(domClass.contains(child, "mblSpinWheelSlotLabelGray"),
+								" Day " + (i + 1) + " should be grayed. " + 
+								"Actual child.className: " + child.className + " (" + title + ")");
+						}
+					});
+				};
+				
+				// Test case for #16502
+				runner.register("dojox.mobile.test.doh.SpinWheelTests", [
+					{
+						name: "SpinWheelTest1",
+						timeout: 4000,
+						runTest: function(){
+							picker.set('value', '2020-06-06');
+							// setTimeout used because the handlers onYearSet, onMonthSet 
+							// and onDaySet are called asynchronously
+							var d = new runner.Deferred();
+							setTimeout(function(){
+								initCounters();
+								// ensure year, month, and day change:
+								picker.set('value', '2019-05-05');
+								// setTimeout used because the handlers onYearSet, onMonthSet 
+								// and onDaySet are called asynchronously
+								setTimeout(d.getTestCallback(function(){
+									// notifications for year, month and day
+									checkCounters(1, 1, 1, 1, 1, 1);
+									checkSlotValues("2019", 5/*"May"*/, "5");
+  								}), 1000);
+							}, 1000);
+							return d;
+						}
+					},
+					{
+						name: "SpinWheelTest2",
+						timeout: 4000,
+						runTest: function(){
+							picker.set('value', '2020-06-06');
+							// setTimeout used because the handlers onYearSet, onMonthSet 
+							// and onDaySet are called asynchronously
+							var d = new runner.Deferred();
+							setTimeout(function(){
+								initCounters();
+								// now only the year changes
+								picker.set('value', '2021-06-06');
+								// setTimeout used because the handlers onYearSet, onMonthSet 
+								// and onDaySet are called asynchronously
+								setTimeout(d.getTestCallback(function(){
+									// notifications for year, not for month and day
+									checkCounters(1, 0, 0, 1, 0, 0);
+									checkSlotValues("2021", 6/*"Jun"*/, "6");
+  								}), 1000);
+							}, 1000);
+							return d;
+						}
+					},
+					{
+						name: "SpinWheelTest3",
+						timeout: 4000,
+						runTest: function(){
+							picker.set('value', '2013-01-31');
+							// setTimeout used because the handlers onYearSet, onMonthSet 
+							// and onDaySet are called asynchronously
+							var d = new runner.Deferred();
+							setTimeout(function(){
+								initCounters();
+								// now change the month from Jan to Feb
+								// The labels/values being localized, let's set 
+								var februaryLabel = picker.slots[1].labels[1]; // the second label is for February
+								picker.slots[1].set("value", februaryLabel);
+								// setTimeout used because the handlers onYearSet, onMonthSet 
+								// and onDaySet are called asynchronously
+								setTimeout(d.getTestCallback(function(){
+									// notifications for month and day, not for year
+									checkCounters(0, 1, 1, 0, 1, 1);
+									// Check that changing the month also changes the day value 
+									// to the last day of Feb. 2012 (leap year, hence last day is 29).
+									checkSlotValues("2013", 2/*"Feb"*/, "28");
+									checkGrayedDaySlots(29, "SpinWheelTest3"); // grayed out starting with day 29
+  								}), 1000);
+							}, 1000);
+							return d;
+						}
+					},
+					{
+						name: "SpinWheelTest4",
+						timeout: 4000,
+						runTest: function(){
+							picker.set('value', '2012-02-29');
+							// setTimeout used because the handlers onYearSet, onMonthSet 
+							// and onDaySet are called asynchronously
+							var d = new runner.Deferred();
+							setTimeout(function(){
+								initCounters();
+								// now change the year to 2013
+								picker.slots[0].set("value", "2013");
+								// setTimeout used because the handlers onYearSet, onMonthSet 
+								// and onDaySet are called asynchronously
+								setTimeout(d.getTestCallback(function(){
+									// notifications for year and day, not for month
+									checkCounters(1, 0, 1, 1, 0, 1);
+									// Check that changing the year also changes the day value 
+									// to the last day of Feb. 2013 (non leap year, hence last day is 28).
+									checkSlotValues("2013", 2/*"Feb"*/, "28");
+									checkGrayedDaySlots(29, "SpinWheelTest4"); // grayed out starting with day 29
+  								}), 1000);
+							}, 1000);
+							return d;
+						}
+					},
+					{
+						name: "SpinWheelTest5",
+						timeout: 4000,
+						runTest: function(){
+							picker.set('value', '2012-02-29');
+							// setTimeout used because the handlers onYearSet, onMonthSet 
+							// and onDaySet are called asynchronously
+							var d = new runner.Deferred();
+							setTimeout(function(){
+								initCounters();
+								// now try to change the day to Feb. 31 which is an invalid date
+								picker.slots[2].spin(-2);
+								// setTimeout used because the handlers onYearSet, onMonthSet 
+								// and onDaySet are called asynchronously
+								setTimeout(d.getTestCallback(function(){
+									// no notifications for year, month or day
+									checkCounters(0, 0, 0, 0, 0, 0);
+									// Check that the slots kept their initial value after trying
+									// to set an invalid day
+									checkSlotValues("2012", 2/*"Feb"*/, "29");
+									checkGrayedDaySlots(30, "SpinWheelTest5"); // grayed out starting with day 30
+  								}), 1000);
+							}, 1000);
+							return d;
+						}
+					}
+				]);
+				
+				runner.run();
+			});
+		});
+		</script>
+	</head>
+	<body style="visibility:hidden;">
+		<div data-dojo-type="dojox/mobile/View">
+			<form>
+				<div data-dojo-type="dojox/mobile/Heading">
+					SpinWheel
+				</div>
+				<div id="picker1" data-dojo-type="dojox/mobile/SpinWheelDatePicker"
+					data-dojo-props="onYearSet: onYearSet, onMonthSet: onMonthSet, onDaySet: onDaySet"></div>
+			</form>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/spinwheeldatepicker/module.js b/dojox/mobile/tests/doh/spinwheeldatepicker/module.js
new file mode 100644
index 0000000..fe7f433
--- /dev/null
+++ b/dojox/mobile/tests/doh/spinwheeldatepicker/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.SpinWheelDatePicker", require.toUrl("./SpinWheelDatePicker.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/spinwheeldatepicker/runTests.html b/dojox/mobile/tests/doh/spinwheeldatepicker/runTests.html
new file mode 100644
index 0000000..e051954
--- /dev/null
+++ b/dojox/mobile/tests/doh/spinwheeldatepicker/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.spinwheeldatepicker.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/swapview/SwapViewTests.js b/dojox/mobile/tests/doh/swapview/SwapViewTests.js
new file mode 100644
index 0000000..b53bb81
--- /dev/null
+++ b/dojox/mobile/tests/doh/swapview/SwapViewTests.js
@@ -0,0 +1,101 @@
+require([
+	"dojo/_base/connect",
+	"dojo/dom-construct", // dojo.place
+	"dojo/dom-class", // dojo.hasClass
+	"dojo/ready", // dojo.ready
+	"dijit/registry",  // dijit.byId
+	"doh/runner",	//doh functions
+	"dojox/mobile/SwapView",	// This mobile app uses mobile view
+	"dojox/mobile",				// This is a mobile app.
+	"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+	"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+], function(connect, domConst, domClass, ready, registry, runner, SwapView){
+
+
+	var timeoutInterval = 1000;
+	var WIDGET_CLASSNAME1 = "mblView";
+	var WIDGET_CLASSNAME2 = "mblSwapView";
+
+
+	function _createSwapViewDeclaratively(widgetId) {
+		return registry.byId(widgetId);
+	};
+
+	function _createSwapViewProgrammatically(placeHolderId, widgetId, selected, innerHTML){
+		// Create SwapView
+		var r = new dojox.mobile.SwapView({id:widgetId, selected:selected, innerHTML:innerHTML});
+		runner.assertNotEqual(null, r);
+		domConst.place(r.domNode, placeHolderId, "replace");
+		r.startup();
+		
+		return r;
+	};
+
+	function _createSwapViewProgrammaticallyWithSourceNodeReference(widgetId, selected){
+		// Create IconContainer
+		var r = new SwapView({selected:selected}, widgetId);
+
+		r.startup();
+		return r;
+	};
+
+	function _assertCorrectSwapView(widget, display){
+		runner.assertNotEqual(null, widget, "IconContainer: Did not instantiate.");
+		runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1);
+		runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2);
+		runner.assertEqual(display?"":"none", widget.domNode.style.display, "widget.domNode.style.display");
+		
+	};
+
+	function _assertCorrectSwapViewPos(widgetId, top, left){
+	};
+
+
+	ready(function(){
+		if(WIDGET_PROGRAMMATICALLY === 1){
+			_createSwapViewProgrammatically("fooPlace", "foo", true, "<h1>SwapView 1</h1>");
+			_createSwapViewProgrammatically("barPlace", "bar", false, "<h1>SwapView 2</h1>");
+		}else if(WIDGET_PROGRAMMATICALLY === 2){
+			_createSwapViewProgrammaticallyWithSourceNodeReference("foo", true);
+			_createSwapViewProgrammaticallyWithSourceNodeReference("bar", false);
+		}
+
+		runner.register("dojox.mobile.test.doh.SwapViewTests", [
+			{
+				name: "SwapView Verification1",
+				timeout: 4000,
+				runTest: function(){
+
+					var widget1 = registry.byId("foo");
+					var widget2 = registry.byId("bar");
+
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var widget1 = registry.byId("foo");
+						var widget2 = registry.byId("bar");
+						_assertCorrectSwapView(widget1, true);
+						_assertCorrectSwapView(widget2, false);
+						widget1.goTo(1);
+					}), timeoutInterval);
+					return d;
+			
+				}
+			},
+			{
+				name: "SwapView Verification2",
+				timeout: 4000,
+				runTest: function(){
+					var d = new runner.Deferred();
+					setTimeout(d.getTestCallback(function(){
+						var widget1 = registry.byId("foo");
+						var widget2 = registry.byId("bar");
+						_assertCorrectSwapView(widget1, false);
+						_assertCorrectSwapView(widget2, true);
+					}), timeoutInterval);
+					return d;
+				}
+			}
+		]);
+		runner.run();
+	});
+})
diff --git a/dojox/mobile/tests/doh/swapview/SwapViewTests1.html b/dojox/mobile/tests/doh/swapview/SwapViewTests1.html
new file mode 100644
index 0000000..174544c
--- /dev/null
+++ b/dojox/mobile/tests/doh/swapview/SwapViewTests1.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>SwapView Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY = 0;
+</script>
+<script type="text/javascript" src="SwapViewTests.js"></script>
+</head>
+<body style="visibility:hidden;">
+<!--
+	<div id="foo">
+		<h1>SwapView 1</h1>
+	</div>
+
+	<div id="bar">
+		<h1>SwapView 2</h1>
+	</div>
+
+	<div id="fooPlace"><h1>SwapView 1</h1></div>
+	<div id="barPlace"><h1>SwapView 2</h1></div>
+-->
+	<div id="foo" data-dojo-type="dojox.mobile.SwapView" data-dojo-props='selected:true'>
+		<h1>SwapView 1</h1>
+	</div>
+
+	<div id="bar" data-dojo-type="dojox.mobile.SwapView">
+		<h1>SwapView 2</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/swapview/SwapViewTests2.html b/dojox/mobile/tests/doh/swapview/SwapViewTests2.html
new file mode 100644
index 0000000..729801c
--- /dev/null
+++ b/dojox/mobile/tests/doh/swapview/SwapViewTests2.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>SwapView Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY = 1;
+</script>
+<script type="text/javascript" src="SwapViewTests.js"></script>
+</head>
+<body style="visibility:hidden;">
+	<div id="fooPlace"><h1>SwapView 1</h1></div>
+	<div id="barPlace"><h1>SwapView 2</h1></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/swapview/SwapViewTests3.html b/dojox/mobile/tests/doh/swapview/SwapViewTests3.html
new file mode 100644
index 0000000..05cd4e9
--- /dev/null
+++ b/dojox/mobile/tests/doh/swapview/SwapViewTests3.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>SwapView Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+var WIDGET_PROGRAMMATICALLY = 2;
+</script>
+<script type="text/javascript" src="SwapViewTests.js"></script>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo">
+		<h1>SwapView 1</h1>
+	</div>
+
+	<div id="bar">
+		<h1>SwapView 2</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/swapview/module.js b/dojox/mobile/tests/doh/swapview/module.js
new file mode 100644
index 0000000..197f613
--- /dev/null
+++ b/dojox/mobile/tests/doh/swapview/module.js
@@ -0,0 +1,11 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.SwapView", require.toUrl("./SwapViewTests1.html"),999999);
+		doh.registerUrl("dojox.mobile.tests.doh.SwapView", require.toUrl("./SwapViewTests2.html"),999999);
+		doh.registerUrl("dojox.mobile.tests.doh.SwapView", require.toUrl("./SwapViewTests3.html"),999999);
+	}
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/swapview/runTests.html b/dojox/mobile/tests/doh/swapview/runTests.html
new file mode 100644
index 0000000..0e696c7
--- /dev/null
+++ b/dojox/mobile/tests/doh/swapview/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.swapview.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/switch/Switch.html b/dojox/mobile/tests/doh/switch/Switch.html
new file mode 100644
index 0000000..dec1769
--- /dev/null
+++ b/dojox/mobile/tests/doh/switch/Switch.html
@@ -0,0 +1,81 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Switch</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<style>
+		.color1 .mblSwitchBgLeft {
+			background: -webkit-gradient(linear, left top, left bottom, from(#28B159), to(#75FBAC), color-stop(0.5, #3FEB84), color-stop(0.5, #4CEE8E));
+		}
+		.color1 .mblSwitchBgRight {
+			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+		}
+		.color2 .mblSwitchBgLeft {
+			background: -webkit-gradient(linear, left top, left bottom, from(#FF9D00), to(#FFCE80), color-stop(0.5, #FFBB4D), color-stop(0.5, #FFC871));
+		}
+		.color2 .mblSwitchBgRight {
+			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+		}
+		.color1 .mblSwitchKnob,
+		.color2 .mblSwitchKnob {
+			background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#FAFAFA), color-stop(0.5, #BBBBBB), color-stop(0.5, #CACACA));
+		}
+		.float {
+			float: left;
+			margin-right: 10px;
+		}
+		.bold {
+			font-weight: bold;
+		}
+		</style>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+
+		</script>
+		<script type="text/javascript" src="Switch.js"></script>
+	</head>
+	<body style="padding:15px;visibility:visible">
+		<div dojoType="dojox.mobile.View" selected="true">
+			<div dojoType="dojox.mobile.RoundRect" shadow="true">
+				<span class="bold">Default Shape</span><br>
+				<div class="float" dojoType="dojox.mobile.Switch" value="off"></div>
+				<div dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+			</div>
+
+			<div dojoType="dojox.mobile.RoundRect" shadow="true">
+				<span class="bold">Round Shape 1</span><br>
+				<div class="mblSwRoundShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
+				<div class="mblSwRoundShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+			</div>
+
+			<div dojoType="dojox.mobile.RoundRect" shadow="true">
+				<span class="bold">Round Shape 2</span><br>
+				<div class="mblSwRoundShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
+				<div class="mblSwRoundShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+			</div>
+
+			<div dojoType="dojox.mobile.RoundRect" shadow="true">
+				<span class="bold">Arc Shape 1</span><br>
+				<div class="mblSwArcShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
+				<div class="mblSwArcShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+			</div>
+
+			<div dojoType="dojox.mobile.RoundRect" shadow="true">
+				<span class="bold">Arc Shape 2</span><br>
+				<div class="mblSwArcShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
+				<div class="mblSwArcShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/switch/Switch.js b/dojox/mobile/tests/doh/switch/Switch.js
new file mode 100644
index 0000000..365babd
--- /dev/null
+++ b/dojox/mobile/tests/doh/switch/Switch.js
@@ -0,0 +1,64 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.doh.Switch", [
+		{
+			name: "Switch Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_Switch_0");
+					doh.assertTrue(demoWidget.domNode.className.search(/mblSwitch/i) != -1);
+					doh.assertTrue(demoWidget.domNode.className.search(/mblSwitchOff/i) != -1);
+					doh.assertTrue(demoWidget.domNode.className.search(/float/i) != -1);
+
+					doh.assertEqual('mblSwitchInner', demoWidget.inner.className);
+					doh.assertEqual('mblSwitchBg mblSwitchBgLeft', demoWidget.inner.childNodes[0].className);
+					doh.assertEqual('none', demoWidget.inner.childNodes[0].style.display);
+					doh.assertEqual('mblSwitchText mblSwitchTextLeft', demoWidget.inner.childNodes[0].childNodes[0].className);
+					doh.assertEqual('ON', demoWidget.inner.childNodes[0].childNodes[0].innerHTML);
+					doh.assertEqual('mblSwitchBg mblSwitchBgRight', demoWidget.inner.childNodes[1].className);
+					doh.assertEqual('mblSwitchText mblSwitchTextRight', demoWidget.inner.childNodes[1].childNodes[0].className);
+					doh.assertEqual('OFF', demoWidget.inner.childNodes[1].childNodes[0].innerHTML);
+					doh.assertEqual('mblSwitchKnob', demoWidget.inner.childNodes[2].className);
+
+					demoWidget = dijit.byId("dojox_mobile_Switch_1");
+					doh.assertEqual('mblSwitch mblSwDefaultShape mblSwitchOn', demoWidget.domNode.className);
+					doh.assertEqual('mblSwitchInner', demoWidget.inner.className);
+					doh.assertEqual('mblSwitchBg mblSwitchBgLeft', demoWidget.inner.childNodes[0].className);
+					doh.assertEqual('mblSwitchText mblSwitchTextLeft', demoWidget.inner.childNodes[0].childNodes[0].className);
+					doh.assertEqual('Start', demoWidget.inner.childNodes[0].childNodes[0].innerHTML);
+					doh.assertEqual('mblSwitchBg mblSwitchBgRight', demoWidget.inner.childNodes[1].className);
+					doh.assertEqual('none', demoWidget.inner.childNodes[1].style.display);
+					doh.assertEqual('mblSwitchText mblSwitchTextRight', demoWidget.inner.childNodes[1].childNodes[0].className);
+					doh.assertEqual('Stop', demoWidget.inner.childNodes[1].childNodes[0].innerHTML);
+					doh.assertEqual('mblSwitchKnob', demoWidget.inner.childNodes[2].className);
+					
+				}));
+				return d;
+			}
+		},
+		{
+			name: "Switch set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_Switch_0");
+				demoWidget.set({value :"on"});
+				doh.assertEqual("on", demoWidget.get("value"));
+//							doh.assertEqual('none', demoWidget.inner.childNodes[1].style.display);
+			}
+		},
+		{
+			name: "Switch set",
+			timeout: 1000,
+			runTest: function(){
+				var demoWidget = dijit.byId("dojox_mobile_Switch_0");
+				demoWidget.set({leftLabel :"Start", rightLabel:"Stop"});
+				doh.assertEqual("Start", demoWidget.get("leftLabel"));
+				doh.assertEqual("Stop", demoWidget.get("rightLabel"));
+				doh.assertEqual('Start', demoWidget.inner.childNodes[0].childNodes[0].innerHTML);
+				doh.assertEqual('Stop', demoWidget.inner.childNodes[1].childNodes[0].innerHTML);
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/switch/SwitchTests.html b/dojox/mobile/tests/doh/switch/SwitchTests.html
new file mode 100644
index 0000000..bbaed7b
--- /dev/null
+++ b/dojox/mobile/tests/doh/switch/SwitchTests.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Switch Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	require([
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/Switch",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(domConst, ready, registry, runner, Switch){
+		function _createSwitchDeclaratively(id) {
+			return registry.byId(id);
+		};
+		
+		function _createSwitchProgrammatically(placeHolderId){
+			var widget = new Switch();
+			runner.assertNotEqual(null, widget);
+			domConst.place(widget.domNode, placeHolderId, "replace");
+			widget.startup();
+			return widget;
+		};
+		
+		function _createSwitchProgrammaticallyWithSourceNodeReference(id){
+			var widget = new Switch({}, id);
+			widget.startup();
+			return widget;
+		};
+
+		function _assertCorrectSwitch(switchButton){
+			runner.assertNotEqual(null, switchButton);
+			runner.assertEqual("on", switchButton.value);
+			switchButton.set("value", "off");
+			runner.assertEqual("off", switchButton.value);		
+		};
+		
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		};
+
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.SwitchTests", [
+				function testInView1(){
+					var switch1 = _createSwitchDeclaratively("view1-switch1");
+					var switch2 = _createSwitchProgrammatically("view1-switch2");
+					var switch3 = _createSwitchProgrammaticallyWithSourceNodeReference("view1-switch3");
+			
+					_assertCorrectSwitch(switch1);
+					_assertCorrectSwitch(switch2);
+					_assertCorrectSwitch(switch3);
+				},
+				function testInView2(){
+					var switch1 = _createSwitchDeclaratively("view2-switch1");
+					var switch2 = _createSwitchProgrammatically("view2-switch2");
+					var switch3 = _createSwitchProgrammaticallyWithSourceNodeReference("view2-switch3");
+					
+					_showView2();
+					
+					_assertCorrectSwitch(switch1);
+					_assertCorrectSwitch(switch2);
+					_assertCorrectSwitch(switch3);
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<div id="view1-switch1" data-dojo-type="dojox.mobile.Switch"></div>
+		<div id="view1-switch2"></div>
+		<div id="view1-switch3"></div>
+	</div>	
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<div id="view2-switch1" data-dojo-type="dojox.mobile.Switch"></div>
+		<div id="view2-switch2"></div>
+		<div id="view2-switch3"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/switch/Switch_Programmatic.html b/dojox/mobile/tests/doh/switch/Switch_Programmatic.html
new file mode 100644
index 0000000..4f3729e
--- /dev/null
+++ b/dojox/mobile/tests/doh/switch/Switch_Programmatic.html
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Switch</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<style>
+		.color1 .mblSwitchBgLeft {
+			background: -webkit-gradient(linear, left top, left bottom, from(#28B159), to(#75FBAC), color-stop(0.5, #3FEB84), color-stop(0.5, #4CEE8E));
+		}
+		.color1 .mblSwitchBgRight {
+			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+		}
+		.color2 .mblSwitchBgLeft {
+			background: -webkit-gradient(linear, left top, left bottom, from(#FF9D00), to(#FFCE80), color-stop(0.5, #FFBB4D), color-stop(0.5, #FFC871));
+		}
+		.color2 .mblSwitchBgRight {
+			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+		}
+		.color1 .mblSwitchKnob,
+		.color2 .mblSwitchKnob {
+			background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#FAFAFA), color-stop(0.5, #BBBBBB), color-stop(0.5, #CACACA));
+		}
+		.float {
+			float: left;
+			margin-right: 10px;
+		}
+		.bold {
+			font-weight: bold;
+		}
+		</style>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+
+			dojo.addOnLoad(function(){
+				var roundRect = dijit.byId("dojox_mobile_RoundRect_0");
+				var demoWidget = new dojox.mobile.Switch({value:"off"});
+				dojo.addClass(demoWidget.domNode, "float");
+//				roundRect.addChild(demoWidget);
+				demoWidget.placeAt(roundRect.containerNode);
+				demoWidget = new dojox.mobile.Switch({value:"on", leftLabel:"Start", rightLabel:"Stop"});
+				demoWidget.placeAt(roundRect.containerNode);
+//				roundRect.addChild(demoWidget);
+			});
+		</script>
+		<script type="text/javascript" src="Switch.js"></script>
+	</head>
+	<body style="visibility:visible">
+		<div data-dojo-type="dojox.mobile.View">
+			<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+				<span class="bold">Default Shape</span><br>
+			</div>
+
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/switch/module.js b/dojox/mobile/tests/doh/switch/module.js
new file mode 100644
index 0000000..fd43a99
--- /dev/null
+++ b/dojox/mobile/tests/doh/switch/module.js
@@ -0,0 +1,9 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.Switch", require.toUrl("./Switch.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Switch", require.toUrl("./Switch_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.Switch", require.toUrl("./SwitchTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/switch/runTests.html b/dojox/mobile/tests/doh/switch/runTests.html
new file mode 100644
index 0000000..748f959
--- /dev/null
+++ b/dojox/mobile/tests/doh/switch/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.switch.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/tabbar/TabBar.html b/dojox/mobile/tests/doh/tabbar/TabBar.html
new file mode 100644
index 0000000..c1f1ca2
--- /dev/null
+++ b/dojox/mobile/tests/doh/tabbar/TabBar.html
@@ -0,0 +1,159 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>TabBar</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<style>
+		.label {
+			font-family: "Helvetica Neue", Helvetica;
+			font-size: 13px;
+			margin-top: 20px;
+		}
+		.view {
+			font-size: 30px;
+			margin-top: 30px;
+			text-align: center;
+		}
+		</style>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.ScrollableView");
+			dojo.require("dojox.mobile.TabBar");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+	        dojo.require("doh.runner");
+	        dojo.require("dojo/dom-geometry");
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="TabBar.js"></script>
+	</head>
+	<body>
+		<div dojoType="dojox.mobile.ScrollableView">
+			<div class="label">Segmented Control</div>
+			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
+				<li dojoType="dojox.mobile.TabBarButton" moveTo="view1" selected="true">New</li>
+				<li dojoType="dojox.mobile.TabBarButton" moveTo="view2">What's Hot</li>
+				<li dojoType="dojox.mobile.TabBarButton" moveTo="view3">Genius</li>
+			</ul>
+	
+			<div class="label">Tab Bar</div>
+			<ul dojoType="dojox.mobile.TabBar">
+				<li dojoType="dojox.mobile.TabBarButton" icon1="../../images/tab-icon-16.png" icon2="../../images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
+				<li dojoType="dojox.mobile.TabBarButton" icon1="../../images/tab-icon-15.png" icon2="../../images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
+				<li dojoType="dojox.mobile.TabBarButton" icon1="../../images/tab-icon-10.png" icon2="../../images/tab-icon-10h.png" moveTo="view3">Genius</li>
+			</ul>
+	
+			<div class="label">Tab Bar (CSS Sprite)</div>
+			<ul dojoType="dojox.mobile.TabBar" iconBase="../../images/tab-icons.png">
+				<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Featured</li>
+				<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,29,29,29" iconPos2="29,29,29,29">Categories</li>
+				<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,58,29,29" iconPos2="29,58,29,29">Top 25</li>
+				<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,87,29,29" iconPos2="29,87,29,29">Search</li>
+				<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,116,29,29" iconPos2="29,116,29,29">Updates</li>
+			</ul>
+	
+			<div class="label">slimTab Tab Bar</div>
+		  	<div data-dojo-type="dojox.mobile.TabBar" data-dojo-props="barType:'slimTab'">
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Info</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Friends</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Albums</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Emails</div>
+			</div>
+	
+			<div class="label">standardTab Tab Bar</div>
+		  	<div data-dojo-type="dojox.mobile.TabBar" data-dojo-props="barType:'standardTab'">
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Info</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Friends</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Albums</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Emails</div>
+			</div>
+	
+			<div class="label">flatTab Tab Bar</div>
+		  	<div data-dojo-type="dojox.mobile.TabBar" data-dojo-props="barType:'flatTab'">
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Info</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Friends</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Albums</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Emails</div>
+			</div>
+	
+			<div class="label">tallTab Tab Bar</div>
+		  	<div data-dojo-type="dojox.mobile.TabBar" data-dojo-props="barType:'tallTab'">
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Info</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Friends</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Albums</div>
+					<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Emails</div>
+			</div>
+	
+			<div class="label">Segmented Control with fill = 'always'</div>
+			<ul id="spread-sc" dojoType="dojox.mobile.TabBar" barType="segmentedControl" fill="always">
+				<li id="spread-sc-button1" dojoType="dojox.mobile.TabBarButton" moveTo="view1" selected="true">New</li>
+				<li id="spread-sc-button2" dojoType="dojox.mobile.TabBarButton" moveTo="view2">What's Hot</li>
+				<li id="spread-sc-button3" dojoType="dojox.mobile.TabBarButton" moveTo="view3">Genius</li>
+			</ul>
+	
+			<div class="label">Tab Bar with fill = 'always'</div>
+			<ul id="spread-tb" dojoType="dojox.mobile.TabBar" data-dojo-props="fill: 'always'">
+				<li id="spread-tb-button1" dojoType="dojox.mobile.TabBarButton" icon1="../../images/tab-icon-16.png" icon2="../../images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
+				<li id="spread-tb-button2" dojoType="dojox.mobile.TabBarButton" icon1="../../images/tab-icon-15.png" icon2="../../images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
+				<li id="spread-tb-button3" dojoType="dojox.mobile.TabBarButton" icon1="../../images/tab-icon-10.png" icon2="../../images/tab-icon-10h.png" moveTo="view3">Genius</li>
+			</ul>
+	
+			<div class="label">Tab Bar (CSS Sprite) with fill = 'always'</div>
+			<ul id="spread-tb-css" dojoType="dojox.mobile.TabBar" data-dojo-props="fill: 'always'" iconBase="../../images/tab-icons.png">
+				<li id="spread-tb-css-button1" dojoType="dojox.mobile.TabBarButton" iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Featured</li>
+				<li id="spread-tb-css-button2" dojoType="dojox.mobile.TabBarButton" iconPos1="0,29,29,29" iconPos2="29,29,29,29">Categories</li>
+				<li id="spread-tb-css-button3" dojoType="dojox.mobile.TabBarButton" iconPos1="0,58,29,29" iconPos2="29,58,29,29">Top 25</li>
+				<li id="spread-tb-css-button4" dojoType="dojox.mobile.TabBarButton" iconPos1="0,87,29,29" iconPos2="29,87,29,29">Search</li>
+				<li id="spread-tb-css-button5" dojoType="dojox.mobile.TabBarButton" iconPos1="0,116,29,29" iconPos2="29,116,29,29">Updates</li>
+			</ul>
+	
+			<div class="label">slimTab Tab Bar with fill = 'always'</div>
+		  	<div id="spread-st" data-dojo-type="dojox.mobile.TabBar" data-dojo-props="barType:'slimTab', fill: 'always'">
+					<div id="spread-st-button1" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Info</div>
+					<div id="spread-st-button2" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Friends</div>
+					<div id="spread-st-button3" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Albums</div>
+					<div id="spread-st-button4" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Emails</div>
+			</div>
+	
+			<div class="label">standardTab Tab Bar with fill = 'always'</div>
+		  	<div id="spread-std" data-dojo-type="dojox.mobile.TabBar" data-dojo-props="barType:'standardTab', fill: 'always'">
+					<div id="spread-std-button1" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Info</div>
+					<div id="spread-std-button2" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Friends</div>
+					<div id="spread-std-button3" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Albums</div>
+					<div id="spread-std-button4" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Emails</div>
+			</div>
+	
+			<div class="label">flatTab Tab Bar with fill = 'always'</div>
+		  	<div id="spread-flat" data-dojo-type="dojox.mobile.TabBar" data-dojo-props="barType:'flatTab', fill: 'always'">
+					<div id="spread-flat-button1" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Info</div>
+					<div id="spread-flat-button2" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Friends</div>
+					<div id="spread-flat-button3" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Albums</div>
+					<div id="spread-flat-button4" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Emails</div>
+			</div>
+	
+			<div class="label">tallTab Tab Bar with fill = 'always'</div>
+		  	<div id="spread-tall" data-dojo-type="dojox.mobile.TabBar" data-dojo-props="barType:'tallTab', fill: 'always'">
+					<div id="spread-tall-button1" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Info</div>
+					<div id="spread-tall-button2" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Friends</div>
+					<div id="spread-tall-button3" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Albums</div>
+					<div id="spread-tall-button4" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props="href: 'index.html'">Emails</div>
+			</div>
+	
+			<div id="view1" dojoType="dojox.mobile.View" selected="true">
+				<div class="view">View 1</div>
+			</div>
+			<div id="view2" dojoType="dojox.mobile.View">
+				<div class="view">View 2</div>
+			</div>
+			<div id="view3" dojoType="dojox.mobile.View">
+				<div class="view">View 3</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/tabbar/TabBar.js b/dojox/mobile/tests/doh/tabbar/TabBar.js
new file mode 100644
index 0000000..f3ff378
--- /dev/null
+++ b/dojox/mobile/tests/doh/tabbar/TabBar.js
@@ -0,0 +1,161 @@
+dojo.addOnLoad(function(){
+	var CLASSNAMES1 = ["mblTabBarButton", "mblTabBarButtonSelected"];
+	var CLASSNAMES2 = ["mblTabBarButton", "mblTabBarButtonHasIcon", "mblTabBarButtonSelected"];
+	var geom = require("dojo/dom-geometry");
+	var checkSpreadedChildren = function(/* String */ tabBarId, /* Number */ nbOfButtons, /* Number */ tabBarPaddingPlusBorderPlusMarginWidth){
+		var tabBarPosition = geom.position(tabBarId);
+		var tabBarButtonsPositions = [];
+		for (var i=1; i <= nbOfButtons; i++){
+			var node = dojo.byId(tabBarId + "-button" + i);
+			tabBarButtonsPositions[i] = geom.position(node);
+		}
+		console.log(tabBarId);
+		console.log(tabBarPosition);
+		console.log(tabBarButtonsPositions);
+		doh.assertEqual(Math.round(tabBarPosition.w - tabBarPaddingPlusBorderPlusMarginWidth), Math.round(tabBarButtonsPositions[1].w * nbOfButtons), tabBarId + " > button 1 size");
+		for (var j=2; j <= nbOfButtons; j++){
+			doh.assertEqual(Math.round(tabBarButtonsPositions[1].w), Math.round(tabBarButtonsPositions[j].w), tabBarId + " > button " + j + " size");
+		}
+	};
+	doh.register("dojox.mobile.test.doh.TabBar", [
+		{
+			name: "TabBar and TabBarButton Verification",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_TabBar_0");
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBar'),'mblTabBar ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBarSegmentedControl'), 'mblTabBarSegmentedControl ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+
+					verifyTabBarButton("dojox_mobile_TabBarButton_0", 'New', CLASSNAMES1, 'hidden', '', /tab-icon-16.png/i, /tab-icon-16h.png/);
+
+					demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBar'),'mblTabBar ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBarTabBar'), 'mblTabBarTabBar ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+
+					verifyTabBarButton("dojox_mobile_TabBarButton_3", 'New', CLASSNAMES2, 'hidden', '', /tab-icon-16.png/i, /tab-icon-16h.png/);
+
+					demoWidget = dijit.byId("dojox_mobile_TabBar_2");
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBar'),'mblTabBar ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+					doh.assertTrue(dojo.hasClass(demoWidget.domNode, 'mblTabBarTabBar'), 'mblTabBarTabBar ' + " id=" + demoWidget.id + " value=" + demoWidget.domNode.className);
+
+					verifyTabBarButton("dojox_mobile_TabBarButton_6", 'Featured', CLASSNAMES2, 'hidden', '', /tab-icons.png/i, /tab-icons.png/i, true);
+					demoWidget = dijit.byId("dojox_mobile_TabBarButton_6");
+					verifyRect(demoWidget.iconNode1.childNodes[0], "0px", "29px", "29px", "0px");
+					verifyRect(demoWidget.iconNode2.childNodes[0], "29px", "29px", "58px", "0px");
+				}),500);
+				return d;
+			}
+		},
+		{
+			name: "TabBar and TabBarButton set",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					var demoWidget = dijit.byId("dojox_mobile_TabBar_0");
+
+
+					demoWidget = dijit.byId("dojox_mobile_TabBarButton_2");
+					demoWidget.set({label:"New Value"});
+//					demoWidget.select();
+					demoWidget.set({selected:true});
+
+					verifyTabBarButton("dojox_mobile_TabBarButton_2", 'New Value', CLASSNAMES1, 'hidden', '', /tab-icon-10.png/i, /tab-icon-10h.png/);
+					demoWidget = dijit.byId("dojox_mobile_TabBarButton_5");
+					demoWidget.set({label:"New Value", icon1:"../../images/tab-icon-11.png", icon2:"../../images/tab-icon-11h.png"});
+//					demoWidget.select();
+					demoWidget.set("selected",true);
+
+					verifyTabBarButton("dojox_mobile_TabBarButton_5", 'New Value', CLASSNAMES2, 'hidden', '', /tab-icon-11.png/i, /tab-icon-11h.png/)
+
+					demoWidget = dijit.byId("dojox_mobile_TabBarButton_4");
+					demoWidget.set({icon1:null, icon2:null});
+					doh.assertEqual(null, demoWidget.iconNode1, demoWidget.domNode.id);
+					doh.assertEqual(null, demoWidget.iconNode2, demoWidget.domNode.id);
+
+				}),500);
+				return d;
+			}
+		},
+		{
+			name: "fill='always' on segmented control",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					checkSpreadedChildren("spread-sc", 3, 12);
+				}),500);
+				return d;
+			}
+		},
+		{
+			name: "fill='always' on tab Bar",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					checkSpreadedChildren("spread-tb", 3, 12);
+				}),500);
+				return d;
+			}
+		},
+		{
+			name: "fill='always' on tab Bar (CSS Sprite)",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					checkSpreadedChildren("spread-tb-css", 5, 12);
+				}),500);
+				return d;
+			}
+		},
+		{
+			name: "fill='always' on slim tab",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					checkSpreadedChildren("spread-st", 4, 2);
+				}),500);
+				return d;
+			}
+		},
+		{
+			name: "fill='always' on standard bar",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					checkSpreadedChildren("spread-std", 4, 12);
+				}),500);
+				return d;
+			}
+		},
+		{
+			name: "fill='always' on flat bar",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					checkSpreadedChildren("spread-flat", 4, 0);
+				}),500);
+				return d;
+			}
+		},
+		{
+			name: "fill='always' on tall bar",
+			timeout: 4000,
+			runTest: function(){
+				var d = new doh.Deferred();
+				setTimeout(d.getTestCallback(function(){
+					checkSpreadedChildren("spread-tall", 4, 12);
+				}),500);
+				return d;
+			}
+		}
+	]);
+	doh.run();
+});
diff --git a/dojox/mobile/tests/doh/tabbar/TabBarTests.html b/dojox/mobile/tests/doh/tabbar/TabBarTests.html
new file mode 100644
index 0000000..cd08fd2
--- /dev/null
+++ b/dojox/mobile/tests/doh/tabbar/TabBarTests.html
@@ -0,0 +1,116 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Tab Bar Tests</title>
+<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+<script type="text/javascript" src="../../../../../dojo/dojo.js"
+	data-dojo-config="parseOnLoad: true"></script>
+
+<script language="JavaScript" type="text/javascript">
+	require([
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/TabBar",
+		"dojox/mobile/TabBarButton",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(domConst, ready, registry, runner, TabBar, TabBarButton){
+
+		function _assertCorrectTabBar(tabBar){
+			var tabBarButton = registry.byId(tabBar.domNode.children[0].id);
+			runner.assertNotEqual(null, tabBarButton);
+			
+			var tabBarWidth = tabBar.domNode.clientWidth;
+			var tabBarButtonWidth = tabBarButton.domNode.clientWidth;
+			var tabBarButtonMarginRight = parseInt(tabBarButton.domNode.style.marginRight);
+			var actualOffsetLeft = Math.floor((tabBarWidth - tabBarButtonWidth) / 2);
+
+			var offsetLeft = tabBar.domNode.children[0].offsetLeft;
+			var clientWidth = tabBar.domNode.clientWidth;
+			runner.assertTrue( (((actualOffsetLeft *0.95) < offsetLeft) && (offsetLeft < (actualOffsetLeft *1.05))) || (offsetLeft <= 6), "expected: " +actualOffsetLeft + "+-5% but got " + offsetLeft + tabBar.toString());
+		}
+
+		function _createTabBarDeclaratively(tabBarId){
+			return registry.byId(tabBarId);
+		};
+		
+		function _createTabBarProgrammatically(placeHolderId){
+			var tabBar = new TabBar();
+			var tabBarButton = new TabBarButton({label:"Tab Bar Button",icon1:"../../images/tab-icon-16.png",icon2:"../../images/tab-icon-16h.png",selected:true});
+			runner.assertNotEqual(null, tabBarButton, "id=" + placeHolderId);
+			tabBar.addChild(tabBarButton);
+			domConst.place(tabBar.domNode, placeHolderId, "replace");
+			tabBar.startup();
+			return tabBar;
+		};
+		
+		function _createTabBarProgrammaticallyWithSourceNodeReference(tabBarId){
+			var tabBar = new TabBar({}, tabBarId);
+			var tabBarButton = new TabBarButton({label:"Tab Bar Button",icon1:"../../images/tab-icon-16.png",icon2:"../../images/tab-icon-16h.png",selected:true});
+			runner.assertNotEqual(null, tabBarButton, "id=" + tabBarId);
+			tabBar.addChild(tabBarButton);
+			tabBar.startup();
+			return tabBar;
+		};
+
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		};
+
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.TabBarTests", [
+				function testInView1(){
+					var tabBar1 = _createTabBarDeclaratively("view1-tabBar1");
+					tabBar1.resize();
+			
+					var tabBar2 = _createTabBarProgrammatically("view1-tabBar2");
+					var tabBar3 = _createTabBarProgrammaticallyWithSourceNodeReference("view1-tabBar3");
+					
+					_assertCorrectTabBar(tabBar1);
+					_assertCorrectTabBar(tabBar2);
+					_assertCorrectTabBar(tabBar3);
+				},
+				function testInView2(){
+					var tabBar1 = _createTabBarDeclaratively("view2-tabBar1");
+					var tabBar2 = _createTabBarProgrammatically("view2-tabBar2");
+					var tabBar3 = _createTabBarProgrammaticallyWithSourceNodeReference("view2-tabBar3");
+					
+					_showView2();
+					
+					_assertCorrectTabBar(tabBar1);
+					_assertCorrectTabBar(tabBar2);
+					_assertCorrectTabBar(tabBar3);				
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<ul id="view1-tabBar1" data-dojo-type="dojox.mobile.TabBar">
+			<li id="view1-tabBarButton" data-dojo-type="dojox.mobile.TabBarButton" label="Tab Bar Button" icon1="../../images/tab-icon-16.png" icon2="../../images/tab-icon-16h.png" selected=true></li>
+		</ul>
+		<div id="view1-tabBar2"></div>
+		<ul id="view1-tabBar3"></ul>		
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<ul id="view2-tabBar1" data-dojo-type="dojox.mobile.TabBar">
+			<li id="view2-tabBarButton" data-dojo-type="dojox.mobile.TabBarButton" icon1="../../images/tab-icon-16.png" icon2="../../images/tab-icon-16h.png" selected="true">Tab Bar Button</li>
+		</ul>
+		<div id="view2-tabBar2"></div>
+		<ul id="view2-tabBar3"></ul>		
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/tabbar/TabBar_Programmatic.html b/dojox/mobile/tests/doh/tabbar/TabBar_Programmatic.html
new file mode 100644
index 0000000..b4720ed
--- /dev/null
+++ b/dojox/mobile/tests/doh/tabbar/TabBar_Programmatic.html
@@ -0,0 +1,158 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>TabBar</title>
+		<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+		<style>
+		.label {
+			font-family: "Helvetica Neue", Helvetica;
+			font-size: 13px;
+			margin-top: 20px;
+		}
+		.view {
+			font-size: 30px;
+			margin-top: 30px;
+			text-align: center;
+		}
+		</style>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.TabBar");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+			dojo.addOnLoad(function(){
+
+				dojo.create("div", {className:"label", innerHTML:"Segmented Control"}, dojo.doc.body);
+				var tabBar = new dojox.mobile.TabBar({barType:"segmentedControl"});
+				dojo.doc.body.appendChild(tabBar.domNode);
+				tabBar.startup();
+
+				var tabBarButton = new dojox.mobile.TabBarButton({moveTo:"view1", selected:"true", label:"New"});
+//				var tabBarButton = new dojox.mobile.TabBarButton({moveTo:"view1", label:"New"});
+				tabBar.addChild(tabBarButton);
+				//work around code
+//				tabBarButton.set("selected", true);
+				
+				tabBarButton = new dojox.mobile.TabBarButton({moveTo:"view2", label:"What's Hot"});
+				tabBar.addChild(tabBarButton);
+				tabBarButton = new dojox.mobile.TabBarButton({moveTo:"view3", label:"Genius"});
+				tabBar.addChild(tabBarButton);
+				tabBar.resize();
+
+				dojo.create("div", {className:"label", innerHTML:"Tab Bar"}, dojo.doc.body);
+				tabBar = new dojox.mobile.TabBar();
+				tabBarButton = new dojox.mobile.TabBarButton({icon1:"../../images/tab-icon-16.png", icon2:"../../images/tab-icon-16h.png", moveTo:"view1", selected:"true", label:"New"});
+//				tabBarButton = new dojox.mobile.TabBarButton({icon1:"../../images/tab-icon-16.png", icon2:"../../images/tab-icon-16h.png", moveTo:"view1", label:"New"});
+				tabBar.addChild(tabBarButton);
+				//work around code
+//				tabBarButton.set("selected", true);
+
+				tabBarButton = new dojox.mobile.TabBarButton({icon1:"../../images/tab-icon-15.png", icon2:"../../images/tab-icon-15h.png", moveTo:"view2", label:"What's Hot"});
+				tabBar.addChild(tabBarButton);
+				tabBarButton = new dojox.mobile.TabBarButton({icon1:"../../images/tab-icon-10.png", icon2:"../../images/tab-icon-10h.png", moveTo:"view3", label:"Genius"});
+				tabBar.addChild(tabBarButton);
+				dojo.doc.body.appendChild(tabBar.domNode);
+				tabBar.startup();
+
+				dojo.create("div", {className:"label", innerHTML:"Tab Bar (CSS Sprite)"}, dojo.doc.body);
+				tabBar = new dojox.mobile.TabBar({iconBase:"../../images/tab-icons.png"});
+				dojo.doc.body.appendChild(tabBar.domNode);
+//				tabBar.startup();
+//				tabBarButton = new dojox.mobile.TabBarButton({iconPos1:"0,0,29,29", iconPos2:"29,0,29,29", selected:"true", label:"Featured"});
+				tabBarButton = new dojox.mobile.TabBarButton({iconPos1:"0,0,29,29", iconPos2:"29,0,29,29", label:"Featured"});
+				tabBar.addChild(tabBarButton);
+				//work around code
+				tabBarButton.set("selected", true);
+				tabBarButton = new dojox.mobile.TabBarButton({iconPos1:"0,29,29,29", iconPos2:"29,29,29,29", label:"Categories"});
+				tabBar.addChild(tabBarButton);
+				tabBarButton = new dojox.mobile.TabBarButton({iconPos1:"0,58,29,29", iconPos2:"29,58,29,29", label:"Top 25"});
+				tabBar.addChild(tabBarButton);
+				tabBarButton = new dojox.mobile.TabBarButton({iconPos1:"0,87,29,29", iconPos2:"29,87,29,29", label:"Search"});
+				tabBar.addChild(tabBarButton);
+				tabBarButton = new dojox.mobile.TabBarButton({iconPos1:"0,116,29,29", iconPos2:"29,116,29,29", label:"Updates"});
+				tabBar.addChild(tabBarButton);
+				tabBar.startup();
+
+				dojo.create("div", {className:"label", innerHTML:"segmented control with fill = 'always'"}, dojo.doc.body);
+				tabBar = new dojox.mobile.TabBar({id: "spread-sc", barType:"segmentedControl", fill: "always"});
+				dojo.doc.body.appendChild(tabBar.domNode);
+				for (var i=1; i <= 3; i++){
+					tabBar.addChild(new dojox.mobile.TabBarButton({id:"spread-sc-button" + i, innerHTML:"Button"}));
+				}
+				tabBar.startup();
+
+				dojo.create("div", {className:"label", innerHTML:"tabBar with fill = 'always'"}, dojo.doc.body);
+				tabBar = new dojox.mobile.TabBar({id: "spread-tb", fill: "always"});
+				dojo.doc.body.appendChild(tabBar.domNode);
+				for (var i=1; i <= 3; i++){
+					tabBar.addChild(new dojox.mobile.TabBarButton({id:"spread-tb-button" + i, icon1:"../../images/tab-icon-16.png", icon2:"../../images/tab-icon-16h.png", moveTo:"view1", selected:"true", label:"New"}));
+				}
+				tabBar.startup();
+
+				dojo.create("div", {className:"label", innerHTML:"tabBar with fill = 'always' (CSS sprite)"}, dojo.doc.body);
+				tabBar = new dojox.mobile.TabBar({id: "spread-tb-css", fill: "always", iconBase:"../../images/tab-icons.png"});
+				dojo.doc.body.appendChild(tabBar.domNode);
+				for (var i=1; i <= 5; i++){
+					tabBar.addChild(new dojox.mobile.TabBarButton({id:"spread-tb-css-button" + i, iconPos1:"0,29,29,29", iconPos2:"29,29,29,29", label:"Categories"}));
+				}
+				tabBar.startup();
+
+				dojo.create("div", {className:"label", innerHTML:"slimTab with fill = 'always'"}, dojo.doc.body);
+				tabBar = new dojox.mobile.TabBar({id: "spread-st", barType:"slimTab", fill: "always"});
+				dojo.doc.body.appendChild(tabBar.domNode);
+				for (var i=1; i <= 4; i++){
+					tabBar.addChild(new dojox.mobile.TabBarButton({id:"spread-st-button" + i, innerHTML:"Button"}));
+				}
+				tabBar.startup();
+
+				dojo.create("div", {className:"label", innerHTML:"standardTab with fill = 'always'"}, dojo.doc.body);
+				tabBar = new dojox.mobile.TabBar({id: "spread-std", barType:"standardTab", fill: "always"});
+				dojo.doc.body.appendChild(tabBar.domNode);
+				for (var i=1; i <= 4; i++){
+					tabBar.addChild(new dojox.mobile.TabBarButton({id:"spread-std-button" + i, innerHTML:"Button"}));
+				}
+				tabBar.startup();
+
+				dojo.create("div", {className:"label", innerHTML:"flatTab with fill = 'always'"}, dojo.doc.body);
+				tabBar = new dojox.mobile.TabBar({id: "spread-flat", barType:"flatTab", fill: "always"});
+				dojo.doc.body.appendChild(tabBar.domNode);
+				for (var i=1; i <= 4; i++){
+					tabBar.addChild(new dojox.mobile.TabBarButton({id:"spread-flat-button" + i, innerHTML:"Button"}));
+				}
+				tabBar.startup();
+
+				dojo.create("div", {className:"label", innerHTML:"tallTab with fill = 'always'"}, dojo.doc.body);
+				tabBar = new dojox.mobile.TabBar({id: "spread-tall", barType:"tallTab", fill: "always"});
+				dojo.doc.body.appendChild(tabBar.domNode);
+				for (var i=1; i <= 4; i++){
+					tabBar.addChild(new dojox.mobile.TabBarButton({id:"spread-tall-button" + i, innerHTML:"Button"}));
+				}
+				tabBar.startup();
+
+				var view = new dojox.mobile.View({id:"view1", selected:"true", innerHTML:'<div class="view">View 1</div>'});
+				dojo.doc.body.appendChild(view.domNode);
+				view.startup();
+
+				view = new dojox.mobile.View({id:"view2", innerHTML:'<div class="view">View 2</div>'});
+				dojo.doc.body.appendChild(view.domNode);
+				view.startup();
+
+				view = new dojox.mobile.View({id:"view3", innerHTML:'<div class="view">View 3</div>'});
+				dojo.doc.body.appendChild(view.domNode);
+				view.startup();
+			});
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="TabBar.js"></script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/tabbar/module.js b/dojox/mobile/tests/doh/tabbar/module.js
new file mode 100644
index 0000000..0c672d9
--- /dev/null
+++ b/dojox/mobile/tests/doh/tabbar/module.js
@@ -0,0 +1,11 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.TabBar", require.toUrl("./TabBar.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.TabBar", require.toUrl("./TabBar_Programmatic.html"),999999);
+	if(!(has("ie") < 10)){
+		doh.registerUrl("dojox.mobile.tests.doh.TabBar", require.toUrl("./TabBarTests.html"),999999);
+	}
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/tabbar/runTests.html b/dojox/mobile/tests/doh/tabbar/runTests.html
new file mode 100644
index 0000000..0259621
--- /dev/null
+++ b/dojox/mobile/tests/doh/tabbar/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.tabbar.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/templating/TemplatedWidgetsTests.html b/dojox/mobile/tests/doh/templating/TemplatedWidgetsTests.html
new file mode 100644
index 0000000..e7ae9e0
--- /dev/null
+++ b/dojox/mobile/tests/doh/templating/TemplatedWidgetsTests.html
@@ -0,0 +1,608 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Templated Widgets Tests</title>
+
+	<!-- DOH test for the dojox/mobile widgets which support templatization:
+		 Button, CheckBox, Heading, ListItem, RadioButton, Slider, 
+		 Switch, ToggleButton, and View. -->
+	
+	<script type="text/javascript" src="../../../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		// Templates
+		
+		// Without widgets (pure HTML); with attach point for label node.
+		var templateListItem1 = // pure HTML
+			"<div>A template." +
+			"  <div data-dojo-attach-point=\'labelNode\'></div>" +
+			"</div>";
+		
+		// With widgets; with attach point for labelNode.
+		var templateListItem2 = 
+			"<div>" +
+			"  <div data-dojo-type='dojox/mobile/RoundRect'>" +
+			"    A template." +
+			"    <div data-dojo-attach-point='labelNode'></div>" +
+			"  </div>" +
+			"</div>";
+			
+		// With widgets; without attach point for labelNode.
+		var templateListItem3 = 
+			"<div>" +
+			"  <div data-dojo-type='dojox/mobile/RoundRect'>" +
+			"    A template." +
+			"  </div>" +
+			"</div>";
+			
+		var templateHeading1 =
+			"<div class='mblHeading mblHeadingCenterTitle'>" +
+			"  <span data-dojo-type='dojox/mobile/ToolBarButton'" +
+			"    data-dojo-attach-point='backButton'" +
+			"    data-dojo-props='arrow: \"left\", back: true, transitionDir: -1'>" +
+			"  </span>" +
+			"  <ul data-dojo-type='dojox/mobile/TabBar'" +
+			"    style='float:right;'" +
+			"    data-dojo-props='barType:\"segmentedControl\", selectOne:false'>" +
+			"    <li data-dojo-type='dojox/mobile/TabBarButton'" +
+			"      data-dojo-props='icon:\"mblDomButtonWhiteUpArrow\"'></li>" +
+			"    <li data-dojo-type='dojox/mobile/TabBarButton'" +
+			"      data-dojo-props='icon:\"mblDomButtonWhiteDownArrow\"'></li>" +
+			"  </ul>" +
+			"  <span class='mblHeadingSpanTitle'" +
+			"    data-dojo-attach-point='labelNode'>" +
+			"  </span>" +
+			"  <div class='mblHeadingDivTitle'" +
+			"    data-dojo-attach-point='labelDivNode'>" +
+			"  </div>" +
+			"</div>";
+			
+		var templateSlider1 =
+		"<div class='mblSlider mblSliderH' tabindex='0'" +
+		"  aria-valuenow='${value}'" +
+		"  data-dojo-attach-point='focusNode'>" +
+		"  <input data-dojo-attach-point='valueNode'" +
+		"    type='hidden' value='${value}'>" +
+		"  <div data-dojo-attach-point='relativeParent'" +
+		"    style='position: relative; height: 100%; width: 100%;'>" +
+		"    <div data-dojo-attach-point='progressBar'" +
+		"      style='position: absolute; left: 0px; width: 100%;'" +
+		"      class='mblSliderProgressBar mblSliderTransition'>" +
+		"    </div>" +
+		"    <div data-dojo-attach-point='touchBox'" +
+		"      style='position: absolute;' class='mblSliderTouchBox'>" +
+		"    </div>" +
+		"    <div data-dojo-attach-point='handle'" +
+		"      style='position: absolute; left: 100%;'" +
+		"      class='mblSliderHandle mblSliderTransition'>" +
+		"    </div>" +
+		"  </div>" +
+		"</div>";
+			
+		var templateButton1 =
+			"<button class='${baseClass}' data-dojo-attach-point='containerNode'></button>";
+		
+		var templateToggleButton1 =
+			"<span>" +
+			"	<button class='${baseClass}' tabindex='0'" +
+			"		style='-webkit-user-select: none;' aria-pressed='true'" +
+			"		data-dojo-attach-point='containerNode'>" +
+			"	</button>" +
+			"</span>";
+		
+		var templateCheckBox1 = 
+			"<input type='checkbox'" +
+			"  class='mblCheckBox mblCheckBoxChecked' value='${value}' tabindex='0'" +
+			"  style='-webkit-user-select: none;' aria-checked='true'>";
+		
+		var templateRadioButton1 =
+			"<input type='radio' value='Small' class='mblRadioButton mblRadioButtonChecked'" + 
+			"	tabindex='0' style='-webkit-user-select: none;' aria-checked='true'>";
+		
+		var templateSwitch1 =
+			"<span class='mblSwitch mblSwDefaultShape mblSwitchOn' tabindex='0' >" +
+			"	<div class='mblSwitchInner' data-dojo-attach-point='inner'>" +
+			"		<div class='mblSwitchBg mblSwitchBgLeft'" +
+			"			data-dojo-attach-point='left'>" +
+			"			<div class='mblSwitchText mblSwitchTextLeft'>ON</div>" +
+			"		</div>" +
+			"		<div class='mblSwitchBg mblSwitchBgRight' style='display: none;'" +
+			"			data-dojo-attach-point='right'>" +
+			"			<div class='mblSwitchText mblSwitchTextRight'>OFF</div>" +
+			"		</div>" +
+			"		<div class='mblSwitchKnob' data-dojo-attach-point='knob'></div>" +
+			"		<input type='hidden' value='on' data-dojo-attach-point='input'>" +
+			"	</div>" +
+			"</span>";
+			
+		var templateView1 =
+			"<div>" +
+			"	<div data-dojo-type='dojox/mobile/Heading'" +
+			"		data-dojo-props='label: \"Templated View\"'>" +
+			"	</div>" +
+			"	<div data-dojo-attach-point='myAttachPoint'>" +
+			"${myProp}" + // no indentation here such that we can test by comparing the
+			"</div>" +    // innerHTML of the attach point with the value of myProp 
+			"	<ul data-dojo-type='dojox/mobile/RoundRectList'>" +
+			"		<li data-dojo-type='dojox/mobile/ListItem'>" +
+			"			Apple" +
+			"		</li>" +
+			"		<li data-dojo-type='dojox/mobile/ListItem'>" +
+			"			Banana" +
+			"		</li>";
+			"	</ul>" +
+			"</div>";
+		
+		// Templated widget classes
+		var TemplatedListItem1, TemplatedWithWidgetsListItem1, 
+			TemplatedWithWidgetsHeading1, TemplatedSwitch, TemplatedView1;
+		
+		require([
+			"dojo/ready",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/sniff",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojo/_base/declare",
+			"dojo/dom-construct",
+			"doh/runner",
+			"dijit/_TemplatedMixin",
+			"dijit/_WidgetsInTemplateMixin", 
+			"dojox/mobile/ListItem",
+			"dojox/mobile/Heading",
+			"dojox/mobile/Switch",
+			"dojox/mobile/View",
+			"dojox/mobile/Button",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/TabBarButton",
+			"dojox/mobile/CheckBox",
+			"dojox/mobile/ToggleButton",
+			"dojox/mobile/RadioButton",
+			"dojox/mobile/Slider",
+			"dojox/mobile/RoundRect",
+			"dojox/mobile/RoundRectList",
+			"dojox/mobile/ScrollableView"
+		], function(ready, dom, domClass, has, registry, parser, mobile, compat, declare, domConstruct,
+					runner, TemplatedMixin, WidgetsInTemplateMixin, 
+					ListItem, Heading, Switch, View){
+
+		// 2.1 Without widgets (pure HTML); with attach point for labelNode and label property specified
+		TemplatedListItem1 = declare(
+			[ListItem, TemplatedMixin], {
+				label: "Some label",
+				templateString: templateListItem1 
+			}
+		);
+		
+		// 2.2 With widgets; with attach point for labelNode but no label property specified
+		TemplatedWithWidgetsListItem1 = declare( 
+			[ListItem, TemplatedMixin, WidgetsInTemplateMixin], {
+				templateString: templateListItem2 
+			}
+		);
+		
+		// 2.3 With widgets; without attach point for labelNode and no label property specified
+		TemplatedWithWidgetsListItem2 = declare( 
+			[ListItem, TemplatedMixin, WidgetsInTemplateMixin], {
+				templateString: templateListItem3 
+			}
+		);
+		
+		// 2.4 With widgets; without attach point for labelNode but label property specified
+		// (error case)
+		TemplatedWithWidgetsListItem3 = declare( 
+			[ListItem, TemplatedMixin, WidgetsInTemplateMixin], {
+				label: "Some label",
+				templateString: templateListItem3 
+			}
+		);
+		
+		TemplatedWithWidgetsHeading1 = declare( 
+			[Heading, TemplatedMixin, WidgetsInTemplateMixin], {
+				templateString: templateHeading1
+			}
+		);
+		
+		TemplatedWithWidgetsHeading2 = declare( 
+			[Heading, TemplatedMixin, WidgetsInTemplateMixin], {
+				back:"Back",
+				label: "Templated by: <code>Heading2.html</code> (using declare)",
+				templateString: templateHeading1
+			}
+		);
+		
+		TemplatedSwitch = declare( 
+			[Switch, TemplatedMixin], {
+				templateString: templateSwitch1
+			}
+		);
+		
+		TemplatedView1 = declare( 
+			[View, TemplatedMixin, WidgetsInTemplateMixin], {
+				myProp: "myValue",
+				templateString: templateView1
+			}
+		);
+		
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.TemplatedWidgetsTests", [
+				function testTemplatedListItem(){
+					// 1. Using markup 
+					
+					// 1.1 With attach point for labelNode and label property specified
+					var listItem = registry.byId("listItem1");
+					runner.assertTrue(!!listItem.domNode);
+					runner.assertTrue(domClass.contains(listItem.domNode, "mblListItem"));
+					runner.assertEqual("Some label", listItem.label);
+					runner.assertTrue(!!listItem.labelNode, "1.1 labelNode");
+					runner.assertEqual("Some label", listItem.labelNode.innerHTML, "1.1 labelNode.innerHTML");
+					
+					// 1.2 With attach point for labelNode but no label property specified
+					listItem = registry.byId("listItem2");
+					runner.assertTrue(!!listItem.domNode);
+					runner.assertTrue(domClass.contains(listItem.domNode, "mblListItem"));
+					runner.assertFalse(!!listItem.label, "1.2 label");
+					runner.assertTrue(!!listItem.labelNode, "1.2 labelNode");
+					
+					// 1.3 Without attach point for labelNode and no label property specified
+					listItem = registry.byId("listItem3");
+					runner.assertTrue(!!listItem.domNode);
+					runner.assertTrue(domClass.contains(listItem.domNode, "mblListItem"));
+					runner.assertFalse(!!listItem.label, "1.2 label");
+					runner.assertFalse(!!listItem.labelNode, "1.2 labelNode");
+					
+					// 2. Using declare
+					
+					// 2.1 With attach point for labelNode and label property specified
+					listItem = registry.byId("listItem4");
+					runner.assertTrue(!!listItem.domNode);
+					runner.assertTrue(domClass.contains(listItem.domNode, "mblListItem"));
+					runner.assertEqual("Some label", listItem.label);
+					runner.assertTrue(!!listItem.labelNode);
+					runner.assertEqual("Some label", listItem.labelNode.innerHTML, "2.1 labelNode.innerHTML");
+										
+					// 2.2 With attach point for labelNode but no label property specified
+					listItem = registry.byId("listItem5");
+					runner.assertTrue(!!listItem.domNode);
+					runner.assertTrue(domClass.contains(listItem.domNode, "mblListItem"));
+					runner.assertFalse(!!listItem.label, "2.2 label");
+					runner.assertTrue(!!listItem.labelNode, "2.2 labelNode");
+					
+					// 2.3 Without attach point for labelNode and no label property specified
+					listItem = registry.byId("listItem6");
+					runner.assertTrue(!!listItem.domNode);
+					runner.assertTrue(domClass.contains(listItem.domNode, "mblListItem"));
+					runner.assertFalse(!!listItem.label, "2.3 label");
+					runner.assertFalse(!!listItem.labelNode, "2.3 labelNode");
+
+					// 2.4 Without attach point for labelNode but label property specified
+					// (error case)
+					try{
+						new TemplatedWithWidgetsListItem3({
+								label: "Some label"
+						});
+						runner.assertTrue(false, 
+							"Creating a templated ListItem without attach point for labelNode " +
+							"should throw Error if label property is set");
+					}catch(err){
+						// error as expected
+					} 
+				},
+				function testTemplatedHeading(){
+					// 3. Using markup 
+					
+					// 3.1 With back specified and no attach point
+					var heading = registry.byId("heading1");
+					runner.assertTrue(!!heading.domNode);
+					runner.assertTrue(domClass.contains(heading.domNode, "mblHeading"));
+					runner.assertFalse(!!heading.label);
+					runner.assertFalse(!!heading.labelNode);
+					runner.assertFalse(!!heading.labelDivNode);
+					runner.assertTrue(!!heading.backButton, "3.1 backButton");
+					runner.assertEqual("Back", heading.backButton.label, "1.1 backButton.label");
+					
+					// 3.2 With attach points; back and label specified
+					heading = registry.byId("heading2");
+					runner.assertTrue(!!heading.domNode, "heading2.domNode");
+					runner.assertTrue(domClass.contains(heading.domNode, "mblHeading"));
+					runner.assertEqual("Some label", heading.label);
+					runner.assertTrue(!!heading.labelNode);
+					runner.assertTrue(!!heading.labelDivNode);
+					runner.assertEqual("Some label", heading.labelNode.innerHTML);
+					runner.assertTrue(!!heading.backButton, "3.2 backButton");
+					runner.assertEqual("Back", heading.backButton.label, "1.1 backButton.label");
+					
+					// 3.3 Without attach point for backButton but back property specified
+					// (error case)
+					try{
+						new TemplatedWithWidgetsHeading1({
+								back: "Back"
+						});
+						runner.assertTrue(false, 
+							"Creating a templated Heading without attach point for backButton " +
+							"should throw Error if back property is set");
+					}catch(err){
+						// error as expected
+					} 
+					
+					// 3.4 Without attach point for labelNode but label property specified
+					// (error case)
+					try{
+						new TemplatedWithWidgetsHeading1({
+								label: "Some label"
+						});
+						runner.assertTrue(false, 
+							"Creating a templated Heading without attach point for labelNode " +
+							"should throw Error if label property is set");
+					}catch(err){
+						// error as expected
+					} 
+				},
+				function testTemplatedFormControls(){
+					// Button
+					var widget = registry.byId("button1");
+					runner.assertTrue(!!widget.domNode);
+					runner.assertTrue(domClass.contains(widget.domNode, "mblButton"));
+					
+					// Slider
+					widget = registry.byId("slider1");
+					runner.assertTrue(!!widget.domNode);
+					runner.assertTrue(domClass.contains(widget.domNode, "mblSlider"));
+					runner.assertTrue(!!widget.focusNode);
+					runner.assertTrue(!!widget.valueNode);
+					runner.assertTrue(!!widget.relativeParent);
+					runner.assertTrue(!!widget.progressBar);
+					runner.assertTrue(!!widget.touchBox);
+					runner.assertTrue(!!widget.handle);
+					
+					// CheckBox
+					widget = registry.byId("checkbox1");
+					runner.assertTrue(!!widget.domNode);
+					runner.assertTrue(domClass.contains(widget.domNode, has("windows-theme") ?
+						"mblCheckableInputContainer" : "mblCheckBox"));
+					
+					// ToggleButton
+					widget = registry.byId("togglebutton1");
+					runner.assertTrue(!!widget.domNode);
+					runner.assertTrue(domClass.contains(widget.domNode, "mblToggleButton"));
+					
+					// Switch
+					widget = registry.byId("switch1");
+					runner.assertTrue(!!widget.domNode);
+					runner.assertTrue(domClass.contains(widget.domNode, has("windows-theme") ?
+						"mblSwitchContainer" : "mblSwitch"));
+					runner.assertTrue(!!widget.inner);
+					runner.assertTrue(!!widget.left);
+					runner.assertTrue(!!widget.right);
+					runner.assertTrue(!!widget.knob);
+					runner.assertTrue(!!widget.input);
+					runner.assertTrue(domClass.contains(widget.inner, "mblSwitchInner"));
+					runner.assertTrue(domClass.contains(widget.left, "mblSwitchBg"));
+					runner.assertTrue(domClass.contains(widget.left, "mblSwitchBgLeft"));
+					runner.assertTrue(domClass.contains(widget.right, "mblSwitchBg"));
+					runner.assertTrue(domClass.contains(widget.right, "mblSwitchBgRight"));
+					runner.assertTrue(domClass.contains(widget.knob, "mblSwitchKnob"));
+					
+					widget = registry.byId("switch2"); // using declare
+					runner.assertTrue(!!widget.domNode);
+					runner.assertTrue(domClass.contains(widget.domNode, has("windows-theme") ?
+						"mblSwitchContainer" : "mblSwitch"));
+					runner.assertTrue(!!widget.inner);
+					runner.assertTrue(!!widget.left);
+					runner.assertTrue(!!widget.right);
+					runner.assertTrue(!!widget.knob);
+					runner.assertTrue(!!widget.input);
+					runner.assertTrue(domClass.contains(widget.inner, "mblSwitchInner"));
+					runner.assertTrue(domClass.contains(widget.left, "mblSwitchBg"));
+					runner.assertTrue(domClass.contains(widget.left, "mblSwitchBgLeft"));
+					runner.assertTrue(domClass.contains(widget.right, "mblSwitchBg"));
+					runner.assertTrue(domClass.contains(widget.right, "mblSwitchBgRight"));
+					runner.assertTrue(domClass.contains(widget.knob, "mblSwitchKnob"));
+					
+					// RadioButton
+					widget = registry.byId("rb1"); // using declare
+					runner.assertTrue(!!widget.domNode);
+					runner.assertTrue(domClass.contains(widget.domNode, has("windows-theme") ?
+						"mblCheckableInputContainer" : "mblRadioButton"));
+				},
+				function testTemplatedView(){
+					var view = registry.byId("view1");
+					runner.assertTrue(!!view.domNode);
+					runner.assertTrue(domClass.contains(view.domNode, "mblView"));
+					runner.assertTrue(!!view.myAttachPoint);
+					runner.assertTrue(!!view.myAttachPoint.innerHTML);
+					runner.assertEqual("myValue", view.myAttachPoint.innerHTML, "view.myAttachPoint.innerHTML");
+				}
+				]);
+				runner.run();
+			});
+		})
+	</script>
+	
+	<style type="text/css">
+		html,body{
+			height: 100%;
+		}
+		.mblRoundRect {
+			margin-left: 32px;
+			margin-right: 32px;
+		}
+		.bold {
+			font-weight: bold;
+		}
+	</style>
+</head>
+
+<body>
+	<div id="main" data-dojo-type="dojox/mobile/View">
+		<!-- Templated ListItem -->
+		<div id="ListItem" data-dojo-type="dojox/mobile/ScrollableView">
+			<ul id="list" data-dojo-type="dojox/mobile/RoundRectList" 
+				data-dojo-props="variableHeight: true">
+				
+				<!-- Templated ListItem -->
+				
+				<!-- 1. In markup -->
+				<!-- 1.1 With attach point for labelNode and label property specified -->
+				<li id="listItem1" data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-mixins="dijit/_TemplatedMixin"
+					data-dojo-props="label:'Some label', 
+						templateString: '<div>My inline <i>HTML</i> template (markup)<div data-dojo-attach-point=\'labelNode\'></div></div>'">
+				</li>
+				<!-- 1.2 With attach point for labelNode but no label property specified -->
+				<li id="listItem2" data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-mixins="dijit/_TemplatedMixin"
+					data-dojo-props="templateString: '<div>My inline <i>HTML</i> template (markup)<div data-dojo-attach-point=\'labelNode\'></div></div>'">
+				</li>
+				<!-- 1.3 Without attach point for labelNode and no label property specified -->
+				<li id="listItem3" data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-mixins="dijit/_TemplatedMixin"
+					data-dojo-props="templateString: '<div><div>My inline, multiline <i>HTML</i><br>template (markup)</div></div>'">
+				</li>
+				
+				<!-- 2. In markup using classes created with declare -->
+				<!-- 2.1 Without widgets (pure HTML); with attach point for labelNode and label property specified -->
+				<li id="listItem4" data-dojo-type=TemplatedListItem1>
+				</li>
+				<!-- 2.2 With widgets; with attach point for labelNode but no label property specified -->
+				<li id="listItem5" data-dojo-type=TemplatedWithWidgetsListItem1>
+				</li>
+				<!-- 2.3 Without attach point for labelNode and no label property specified -->
+				<li id="listItem6" data-dojo-type=TemplatedWithWidgetsListItem2>
+				</li>
+				
+				<!-- Templated Heading -->
+				<!-- 3.1 With back specified and no attach point -->
+				<div id="heading1" data-dojo-type="dojox/mobile/Heading" 
+					data-dojo-props="back:'Back', 
+						templateString: '<div>My inline <i>HTML</i> template (markup)</div>'"
+					data-dojo-mixins="dijit/_TemplatedMixin">
+				</div>
+				<!-- 3.2 With attach points; back and label specified -->
+				<div id="heading2" data-dojo-type=TemplatedWithWidgetsHeading1 
+					data-dojo-props="back:'Back', label: 'Some label'">
+				</div>
+				
+				<!-- Templated Button -->
+				<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+				<table style="width:100%">
+					<tr>
+					<td><span class="bold">Button</span></td>
+					<td style="text-align:right">
+						<button id="button1" data-dojo-type="dojox/mobile/Button" 
+							data-dojo-props="templateString: templateButton1"
+							data-dojo-mixins="dijit/_TemplatedMixin">
+							Press me!
+						</button>
+					</td>
+					</tr>
+				</table>
+				</div>
+				
+				<!-- Templated Slider -->
+				<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+				<table style="width:100%">
+					<tr>
+					<td><span class="bold">Slider</span></td>
+					<td style="float:right">
+						<input id="slider1" data-dojo-type="dojox/mobile/Slider"
+							style="width:200px;" type="range"
+							data-dojo-props="templateString: templateSlider1, 
+								value:10, min:0, max:40, step:0.1"
+							data-dojo-mixins="dijit/_TemplatedMixin">
+					</td>
+					</tr>
+				</table>
+				</div>
+				
+				<!-- Templated CheckBox -->
+				<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+				<table style="width:100%">
+					<tr>
+					<td><span class="bold">CheckBox</span></td>
+					<td style="text-align:right">
+						<label for="checkbox1">Click me</label>
+						<input type="checkbox" id="checkbox1"
+							data-dojo-type="dojox/mobile/CheckBox"
+							data-dojo-props="templateString: templateCheckBox1">
+					</td>
+					</tr>
+				</table>
+				</div>
+				
+				<!-- Templated ToggleButton -->
+				<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+				<table style="width:100%">
+					<tr>
+					<td><span class="bold">ToggleButton</span></td>
+					<td style="text-align:right">
+						<button id="togglebutton1" data-dojo-type="dojox/mobile/ToggleButton"
+							data-dojo-props="templateString: templateToggleButton1">
+								Toggle me
+						</button>
+					</td>
+					</tr>
+				</table>
+				</div>
+				
+				<!-- Templated Switch -->
+				<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+				<table style="width:100%">
+					<tr>
+					<td><span class="bold">Switch</span></td>
+					<td style="text-align:right">
+						<input id="switch1" type="checkbox" value="on"
+							data-dojo-type="dojox/mobile/Switch"
+							data-dojo-props="templateString: templateSwitch1"
+							data-dojo-mixins="dijit/_TemplatedMixin, dijit/_WidgetsInTemplateMixin">
+					</td>
+					<td style="text-align:right">
+						<input id="switch2" type="checkbox" value="on"
+							data-dojo-type=TemplatedSwitch>
+					</td>
+					</tr>
+				</table>
+				</div>
+				
+				<!-- Templated RadioButton -->
+				<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+				<table style="width:100%">
+					<tr>
+					<td><span class="bold">Radio Button</span></td>
+					<td style="text-align:right">
+						<input type="radio" id="rb1" data-dojo-type="dojox/mobile/RadioButton" 
+							data-dojo-props="templateString: templateRadioButton1"
+							name="mobileRadio" value="Large" checked>
+						<label for="rb1">1</label>
+						
+						<input type="radio" id="rb2" data-dojo-type="dojox/mobile/RadioButton" 
+							data-dojo-props="templateString: templateRadioButton1"
+							name="mobileRadio" value="Large">
+						<label for="rb2">2</label>
+						
+						<input type="radio" id="rb3" data-dojo-type="dojox/mobile/RadioButton" 
+							data-dojo-props="templateString: templateRadioButton1"
+							name="mobileRadio" value="Large">
+						<label for="rb3">3</label>
+					</tr>
+				</table>
+				</div>
+			</ul>
+		</div>
+	
+		<!-- Templated View -->
+		<div id="view1" data-dojo-type=TemplatedView1>
+		</div>
+	</div>
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/templating/module.js b/dojox/mobile/tests/doh/templating/module.js
new file mode 100644
index 0000000..2e43019
--- /dev/null
+++ b/dojox/mobile/tests/doh/templating/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.templating", require.toUrl("./TemplatedWidgetsTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/templating/runTests.html b/dojox/mobile/tests/doh/templating/runTests.html
new file mode 100644
index 0000000..b443b10
--- /dev/null
+++ b/dojox/mobile/tests/doh/templating/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.templating.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/textarea/TextAreaTests.html b/dojox/mobile/tests/doh/textarea/TextAreaTests.html
new file mode 100644
index 0000000..fd6106f
--- /dev/null
+++ b/dojox/mobile/tests/doh/textarea/TextAreaTests.html
@@ -0,0 +1,170 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>TextArea Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	var TEXTAREA_ROWS = 3;
+	var TEXTAREA_COLS = 20;
+	var TEXTAREA_INNERHTML = "TextArea";
+	var TEXTAREA_NEW_VALUE = "This is mobile TextArea.\nThis is fixed text area.\nScroll bar comes up automatically.\nHello dojox.mobile";
+	var WIDGET_CLASSNAME1 = "mblTextArea";
+	var WIDGET_OFFSETHEIGHT1 = 58;
+	var WIDGET_OFFSETHEIGHT1_FF = 75;
+	var WIDGET_OFFSETHEIGHT1_FF19 = 79;
+	var WIDGET_OFFSETHEIGHT1_IE = 55; // IE9
+	var WIDGET_OFFSETHEIGHT1_IE10 = 63; // IE10
+	var WIDGET_OFFSETHEIGHT2 = 58;
+	var WIDGET_OFFSETHEIGHT2_IE = "34"; // IE9
+	var WIDGET_SCROLLHEIGHT1 = 56;
+	var WIDGET_SCROLLHEIGHT1_IE = 23; // IE9
+	var WIDGET_SCROLLHEIGHT1_IE10 = 20; // IE10
+	var WIDGET_SCROLLHEIGHT1_FF = 65;
+	var WIDGET_SCROLLHEIGHT1_FF19 = 69;
+	var WIDGET_SCROLLHEIGHT2 = 88;
+	var WIDGET_SCROLLHEIGHT2_IE = 113; // IE9
+	var WIDGET_SCROLLHEIGHT2_IE10 = 78; // IE10
+	var WIDGET_SCROLLHEIGHT2_FF = 80;
+
+	require([
+		"dojo/_base/connect",
+		"dojo/sniff",
+		"dojo/dom-construct", // dojo.place
+		"dojo/dom-class", // dojo.hasClass
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/TextArea",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(connect, has, domConst, domClass, ready, registry, runner, TextArea){
+
+		function _createTextAreaDeclaratively(widgetId) {
+			return registry.byId(widgetId);
+		};
+
+		function _createTextAreaProgrammatically(placeHolderId, widgetId, rows, cols, innerHTML){
+			// Create SwapView
+			var r = new TextArea({id:widgetId, rows:rows, cols:cols, innerHTML:innerHTML});
+			runner.assertNotEqual(null, r);
+			domConst.place(r.domNode, placeHolderId, "replace");
+			r.startup();
+			
+			return r;
+		};
+
+		function _createTextAreaProgrammaticallyWithSourceNodeReference(widgetId){
+			// Create IconContainer
+			var r = new TextArea({}, widgetId);
+
+			r.startup();
+			return r;
+		};
+
+		function _assertCorrectTextArea(widget, offsetHeight1, offsetHeight2, scrollHeight1, scrollHeight2){
+			if(offsetHeight1 < 0){
+				return; // Skip for IE<9 (a negative offsetHeight1 is the convention we use for skipping) 
+			}
+			runner.assertNotEqual(null, widget, "TextArea: Did not instantiate.");
+			runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + widget.domNode.id);
+			runner.assertEqual(offsetHeight1, widget.domNode.offsetHeight, "offsetHeight1 id=" + widget.domNode.id);
+			runner.assertEqual(scrollHeight1, widget.domNode.scrollHeight, "scrollHeight1 id=" + widget.domNode.id);
+			runner.assertEqual(TEXTAREA_INNERHTML, widget.textbox.value, 'textbox value');
+			runner.assertEqual(TEXTAREA_INNERHTML, widget.get('value'), 'widget value');
+			widget.set('value', TEXTAREA_NEW_VALUE);
+			runner.assertEqual(offsetHeight2, widget.domNode.offsetHeight, "offsetHeight2 id=" + widget.domNode.id);
+			runner.assertEqual(scrollHeight2, widget.domNode.scrollHeight, "scrollHeight2 id=" + widget.domNode.id);
+			runner.assertEqual(TEXTAREA_NEW_VALUE, widget.textbox.value.replace(/\r\n/g, "\n"), 'textbox new value');
+			runner.assertEqual(TEXTAREA_NEW_VALUE, widget.get('value').replace(/\r\n/g, "\n"), 'widget new value');
+		};
+
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "");
+		};
+
+		ready(function(){
+			var offsetHeight1 = has("ie") ? (has("ie") >= 10 ? WIDGET_OFFSETHEIGHT1_IE10 : WIDGET_OFFSETHEIGHT1_IE) :
+				has("ff") ? 
+					(has("ff") >= 19 ? WIDGET_OFFSETHEIGHT1_FF19 : WIDGET_OFFSETHEIGHT1_FF) : 
+					WIDGET_OFFSETHEIGHT1;
+			var offsetHeight2 = offsetHeight1;
+			var scrollHeight1 = has("ie") ? (has("ie") >= 10 ? WIDGET_SCROLLHEIGHT1_IE10 : WIDGET_SCROLLHEIGHT1_IE) :
+				has("ff") ? 
+					(has("ff") >= 19 ? WIDGET_SCROLLHEIGHT1_FF19 : WIDGET_SCROLLHEIGHT1_FF) : 
+					WIDGET_SCROLLHEIGHT1;
+			var scrollHeight2 = has("ie") ? (has("ie") >= 10 ? WIDGET_SCROLLHEIGHT2_IE10 : WIDGET_SCROLLHEIGHT2_IE) :
+				has("ff") ? WIDGET_SCROLLHEIGHT2_FF:WIDGET_SCROLLHEIGHT2;
+			// Skip the checks for IE<9
+			if(has("ie") < 9){
+				offsetHeight1 = -1; // negative value as convention for skipping tests
+			} 
+			runner.register("dojox.mobile.test.doh.TextArea", [
+				{
+					name: "TextArea Verification1",
+					timeout: 10000,
+					runTest: function(){
+						var widget1 = _createTextAreaDeclaratively("view1-TextArea1");
+						var widget2 = _createTextAreaProgrammatically("view1-TextArea2place", "view1-TextArea2", TEXTAREA_ROWS, TEXTAREA_COLS, TEXTAREA_INNERHTML);
+						var widget3 = _createTextAreaProgrammaticallyWithSourceNodeReference("view1-TextArea3");
+
+						var d = new runner.Deferred();
+						setTimeout(d.getTestCallback(function(){
+							var widget1 = registry.byId("view1-TextArea1");
+							var widget2 = registry.byId("view1-TextArea2");
+							var widget3 = registry.byId("view1-TextArea3");
+							_assertCorrectTextArea(widget1, offsetHeight1, offsetHeight2, scrollHeight1, scrollHeight2);
+							_assertCorrectTextArea(widget2, offsetHeight1, offsetHeight2, scrollHeight1, scrollHeight2);
+							_assertCorrectTextArea(widget3, offsetHeight1, offsetHeight2, scrollHeight1, scrollHeight2);
+						}), 2000);
+						return d;
+					}
+				},
+				{
+					name: "TextArea Verification2",
+					timeout: 10000,
+					runTest: function(){
+						var widget1 = _createTextAreaDeclaratively("view2-TextArea1");
+						var widget2 = _createTextAreaProgrammatically("view2-TextArea2place", "view2-TextArea2", TEXTAREA_ROWS, TEXTAREA_COLS, TEXTAREA_INNERHTML);
+						var widget3 = _createTextAreaProgrammaticallyWithSourceNodeReference("view2-TextArea3");
+
+						_showView2();
+						var d = new runner.Deferred();
+						setTimeout(d.getTestCallback(function(){
+							var widget1 = registry.byId("view2-TextArea1");
+							var widget2 = registry.byId("view2-TextArea2");
+							var widget3 = registry.byId("view2-TextArea3");
+							_assertCorrectTextArea(widget1, offsetHeight1, offsetHeight2, scrollHeight1, scrollHeight2);
+							_assertCorrectTextArea(widget2, offsetHeight1, offsetHeight2, scrollHeight1, scrollHeight2);
+							_assertCorrectTextArea(widget3, offsetHeight1, offsetHeight2, scrollHeight1, scrollHeight2);
+						}), 2000);
+						return d;
+					}
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<textarea id="view2-TextArea1" data-dojo-type="dojox.mobile.TextArea" rows="3" cols="20">TextArea</textarea><br>
+		<div id="view2-TextArea2place"></div><br>
+		<textarea id="view2-TextArea3" rows="3" cols="20">TextArea</textarea><br>
+	</div>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<textarea id="view1-TextArea1" data-dojo-type="dojox.mobile.TextArea" rows="3" cols="20">TextArea</textarea><br>
+		<div id="view1-TextArea2place"></div><br>
+		<textarea id="view1-TextArea3" rows="3" cols="20">TextArea</textarea><br>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/textarea/module.js b/dojox/mobile/tests/doh/textarea/module.js
new file mode 100644
index 0000000..06e9a96
--- /dev/null
+++ b/dojox/mobile/tests/doh/textarea/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.TextArea", require.toUrl("./TextAreaTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/textarea/runTests.html b/dojox/mobile/tests/doh/textarea/runTests.html
new file mode 100644
index 0000000..199d809
--- /dev/null
+++ b/dojox/mobile/tests/doh/textarea/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.textarea.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/textbox/TextBoxTests.html b/dojox/mobile/tests/doh/textbox/TextBoxTests.html
new file mode 100644
index 0000000..3d7d119
--- /dev/null
+++ b/dojox/mobile/tests/doh/textbox/TextBoxTests.html
@@ -0,0 +1,159 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>TextBox Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	var WIDGET_CLASSNAME1 = "mblTextBox";
+	var WIDGET_ANCHOR_CLASSNAME1 = "mblListItemAnchor";
+	var WIDGET_ANCHOR_CLASSNAME2 = "mblListItemAnchorNoIcon";
+	var WIDGET_ICON_CLASSNAME1 = "mblListItemIcon";
+	var WIDGET_RIGHTICON_CLASSNAME1 = "mblListItemRightIcon";
+	var WIDGET_DOMBUTTON_ARROW = "mblDomButtonArrow";
+	var WIDGET_DOMBUTTON_BLUEPLUS = "mblDomButtonBluePlus";
+	var WIDGET_DOMBUTTON_CHECKBOX_ON = "mblDomButtonCheckboxOn";
+	var WIDGET_VALUE = "";
+	var WIDGET_NEW_VALUE = "123456789";
+
+	require([
+		"dojo/_base/connect",
+		"dojo/dom-construct", // dojo.place
+		"dojo/dom-class", // dojo.hasClass
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"dojo/string", // dojo.trim
+		"doh/runner",	//doh functions
+		"dojox/mobile/TextBox",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(connect, domConst, domClass, ready, registry, string, runner, TextBox){
+
+		function _createTextBoxDeclaratively(widgetId) {
+			return registry.byId(widgetId);
+		};
+
+		function _createTextBoxProgrammatically(placeHolderId, widgetId){
+			var r = new TextBox({id:widgetId, maxLength:"9", placeHolder:"max 9 chars", selectOnClick:"true"});
+			runner.assertNotEqual(null, r);
+			domConst.place(r.domNode, placeHolderId, "replace");
+			r.startup();
+			
+			return r;
+		};
+
+		function _createTextBoxProgrammaticallyWithSourceNodeReference(widgetId){
+			// Create IconContainer
+			var r = new TextBox({selectOnClick:"true"}, widgetId);
+			r.startup();
+
+			return r;
+		};
+
+		function _assertCorrectTextBox(widget, noIcon, rightIcon, rightIcon2, rightText, boxText){
+			runner.assertNotEqual(null, widget, "TextBox: Did not instantiate. id=" + widget.domNode.id);
+			runner.assertTrue(domClass.contains(widget.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + widget.domNode.id);
+			runner.assertEqual(WIDGET_VALUE, widget.textbox.value);
+			runner.assertEqual(WIDGET_VALUE, widget.get('value'));
+			widget.set('value', WIDGET_NEW_VALUE);
+			runner.assertEqual(WIDGET_NEW_VALUE, widget.get('value'));
+			runner.assertEqual(WIDGET_NEW_VALUE, widget.textbox.value);
+		};
+
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		};
+
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.TextBox", [
+				{
+					name: "TextBox Verification1",
+					timeout: 4000,
+					runTest: function(){
+						var widget1 = _createTextBoxDeclaratively("view1-TextBox1");
+						var widget2 = _createTextBoxProgrammatically("view1-TextBox2Place", "view1-TextBox2");
+						var widget3 = _createTextBoxProgrammaticallyWithSourceNodeReference("view1-TextBox3");
+
+						_assertCorrectTextBox(widget1);
+						_assertCorrectTextBox(widget2);
+						_assertCorrectTextBox(widget3);
+					}
+				},
+				{
+					name: "TextBox Verification2",
+					timeout: 4000,
+					runTest: function(){
+						var widget1 = _createTextBoxDeclaratively("view2-TextBox1");
+						var widget2 = _createTextBoxProgrammatically("view2-TextBox2Place", "view2-TextBox2");
+						var widget3 = _createTextBoxProgrammaticallyWithSourceNodeReference("view2-TextBox3");
+
+						var d = new runner.Deferred();
+						var handle2 = connect.subscribe("/dojox/mobile/afterTransitionIn", d.getTestCallback(function(view){
+							if(view.id=="view2"){
+								connect.unsubscribe(handle2);
+							}
+							_assertCorrectTextBox(widget1);
+							_assertCorrectTextBox(widget2);
+							_assertCorrectTextBox(widget3);
+						}));
+						_showView2();
+						return d;
+					}
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:"true"'>
+		<h1>View1</h1>
+		<table>
+			<tr>
+				<td valign="top"><span class="bold">TextBox</span></td>
+				<td align="right"><input id="view1-TextBox1" data-dojo-type="dojox.mobile.TextBox" maxLength="9" placeHolder="max 9 chars" data-dojo-props='selectOnClick:"true"'></td>
+			</tr>
+		</table>
+		<table>
+			<tr>
+				<td valign="top"><span class="bold">TextBox</span></td>
+				<td align="right"><div id="view1-TextBox2Place"></div></td>
+			</tr>
+		</table>
+		<table>
+			<tr>
+				<td valign="top"><span class="bold">TextBox</span></td>
+				<td align="right"><input id="view1-TextBox3" maxLength="9" placeHolder="max 9 chars"></td>
+			</tr>
+		</table>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View2</h1>
+		<table>
+			<tr>
+				<td valign="top"><span class="bold">TextBox</span></td>
+				<td align="right"><input id="view2-TextBox1" data-dojo-type="dojox.mobile.TextBox" maxLength="9" placeHolder="max 9 chars" data-dojo-props='selectOnClick:"true"'></td>
+			</tr>
+		</table>
+		<table>
+			<tr>
+				<td valign="top"><span class="bold">TextBox</span></td>
+				<td align="right"><div id="view2-TextBox2Place"></div></td>
+			</tr>
+		</table>
+		<table>
+			<tr>
+				<td valign="top"><span class="bold">TextBox</span></td>
+				<td align="right"><input id="view2-TextBox3" maxLength="9" placeHolder="max 9 chars"></td>
+			</tr>
+		</table>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/textbox/module.js b/dojox/mobile/tests/doh/textbox/module.js
new file mode 100644
index 0000000..f477583
--- /dev/null
+++ b/dojox/mobile/tests/doh/textbox/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.TextBox", require.toUrl("./TextBoxTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/textbox/runTests.html b/dojox/mobile/tests/doh/textbox/runTests.html
new file mode 100644
index 0000000..228345a
--- /dev/null
+++ b/dojox/mobile/tests/doh/textbox/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.textbox.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/toolbarbutton/ToolBarButton.html b/dojox/mobile/tests/doh/toolbarbutton/ToolBarButton.html
new file mode 100644
index 0000000..2ea28a6
--- /dev/null
+++ b/dojox/mobile/tests/doh/toolbarbutton/ToolBarButton.html
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>ToolBarButton</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/TabBar.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.TabBar");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+			dojo.require("doh.runner");
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="ToolBarButton.js"></script>
+	</head>
+	<body>
+		<h1 dojoType="dojox.mobile.Heading" label="World Clock">
+			<div id="btn1" dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px">Edit</div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;" onclick="console.log('+ was clicked')"></div>
+
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading">
+			<div dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px">Edit</div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;"></div>
+			Alarm Clock
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading" label="Voice Memos">
+			<div dojoType="dojox.mobile.ToolBarButton" label="Speaker"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="float:right;"></div>
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading" label="Updates">
+			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="float:right;"></div>
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading" label="News" back="Bookmarks" moveTo="bookmarks">
+			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="float:right;"></div>
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading">
+			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" label="New Folder" style="float:right;"></div>
+		</h1><br>
+
+
+		<div dojoType="dojox.mobile.Heading">
+			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">New</div>
+			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">Toggle</div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="../../images/a-icon-12.png" moveTo="view3"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="../../images/tab-icons.png" iconPos="29,0,29,29" moveTo="view3"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" moveTo="view3" style="float:right;"></div>
+		</div><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading">
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
+		</h1><br>
+
+
+		<h1 dojoType="dojox.mobile.Heading" align="center">
+		  <table cellpadding="0" cellspacing="0" style="width:100%;"><tr>
+			<td><div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus"></div></td>
+			<td align="right"><div dojoType="dojox.mobile.ToolBarButton" icon="../../images/tab-icon-15h.png" style="float:right;"></div></td>
+		  </tr></table>
+		</h1><br>
+
+		<h1 dojoType="dojox.mobile.Heading" back="Top" label="Inbox(32)">
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteUpArrow" style="float:right;"></div>
+			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteDownArrow" style="float:right;"></div>
+		</h1><br>
+		
+		<!-- Test cases for #16771 -->
+		<!-- a) With arrow but no label (nor icon) -->
+		<h1 dojoType="dojox.mobile.Heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton"
+					data-dojo-props="arrow: 'left'"/>
+		</h1><br>
+		
+		<h1 dojoType="dojox.mobile.Heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton"
+					data-dojo-props="arrow: 'right'"/>
+		</h1><br>
+		
+		<!-- b) With arrow, icon and label -->
+		<div data-dojo-type="dojox.mobile.Heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton"
+				data-dojo-props="arrow: 'left', icon: 'mblDomButtonWhiteDownArrow', label: 'some label'"/>
+		</div><br>
+			
+		<div data-dojo-type="dojox.mobile.Heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton"
+				data-dojo-props="arrow: 'right', icon: 'mblDomButtonWhiteDownArrow', label: 'some label'"/>
+		</div><br>
+		<!-- End of test cases for #16771 -->
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/toolbarbutton/ToolBarButton.js b/dojox/mobile/tests/doh/toolbarbutton/ToolBarButton.js
new file mode 100644
index 0000000..9a0781a
--- /dev/null
+++ b/dojox/mobile/tests/doh/toolbarbutton/ToolBarButton.js
@@ -0,0 +1,144 @@
+dojo.addOnLoad(function(){
+	doh.register("dojox.mobile.test.ToolBarButton", [
+		function test_Heading_Verification(){
+			var demoWidget = dijit.byId("btn1");
+
+			doh.assertEqual('Edit', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_0");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhitePlus mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+			
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_1");
+			doh.assertEqual('Edit', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_2");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhitePlus mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_3");
+			doh.assertEqual('Speaker', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_4");
+			doh.assertEqual('Done', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_5");
+			doh.assertEqual('Update All', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_6");
+			doh.assertEqual('mblToolBarButton mblToolBarButtonHasLeftArrow', demoWidget.domNode.className, "id= "+ demoWidget.domNode.id);
+			doh.assertEqual('Bookmarks', demoWidget.labelNode.innerHTML);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_7");
+			doh.assertEqual('Done', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_8");
+			doh.assertEqual('Done', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_9");
+			doh.assertEqual('New Folder', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_10");
+			doh.assertEqual('New', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_11");
+			doh.assertEqual('Toggle', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_12");
+			if(!dojo.isIE){
+				doh.assertTrue(demoWidget.iconNode.src.search(/a-icon-12.png/) != -1, "a-icon-12.png", "id= "+ demoWidget.domNode.id);
+			}
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_13");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblSpriteIcon', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+			verifyRect(demoWidget.iconNode.childNodes[0], "29px", "29px", "58px", "0px");
+			doh.assertEqual('-29px', demoWidget.iconNode.childNodes[0].style.top, "id= "+ demoWidget.domNode.id);
+			doh.assertEqual('0px', demoWidget.iconNode.childNodes[0].style.left, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_14");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhitePlus mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_15");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhiteSearch mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_16");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhitePlus mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_17");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblImageIcon', demoWidget.iconNode.className, "id= "+ demoWidget.domNode.id);
+			if(!dojo.isIE){
+				doh.assertTrue(demoWidget.iconNode.src.search(/tab-icon-15h.png/) != -1, "tab-icon-15h.png");
+			}
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_18");
+			doh.assertEqual('mblToolBarButton mblToolBarButtonHasLeftArrow', demoWidget.domNode.className, "id= "+ demoWidget.domNode.id);
+			doh.assertEqual('Top', demoWidget.labelNode.innerHTML);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_19");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhiteSearch mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_20");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhiteUpArrow mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_21");
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonWhiteDownArrow mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+			
+			// Test cases for #16771
+			// a) 
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_22");
+			doh.assertTrue(dojo.style(demoWidget.bodyNode, "height") > 0, 
+				"the height of button's body should be larger than 0! (left arrow) id= "+ 
+				demoWidget.domNode.id + 
+				" actual height: " + dojo.style(demoWidget.bodyNode, "height"));
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_23");
+			doh.assertTrue(dojo.style(demoWidget.bodyNode, "height") > 0, 
+				"the height of button's body should be larger than 0! (right arrow) id= "+ 
+				demoWidget.domNode.id + 
+				" actual height: " + dojo.style(demoWidget.bodyNode, "height"));
+				
+			// b) With arrow, icon and label
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_24");
+			var bodyBox = dojo.getMarginBox(demoWidget.bodyNode);
+			var arrowBox = dojo.getMarginBox(demoWidget.arrowNode);
+			doh.assertTrue(bodyBox.l > arrowBox.l - (dojo.isFF ? 2 : 0), 
+				"The body should not cover the arrow! (left arrow) id= "+ demoWidget.domNode.id + " bodyBox.l: " + bodyBox.l + " arrowBox.l: " + arrowBox.l);
+			
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_25");
+			bodyBox = dojo.getMarginBox(demoWidget.bodyNode);
+			arrowBox = dojo.getMarginBox(demoWidget.arrowNode);
+			doh.assertTrue(arrowBox.l + arrowBox.w > bodyBox.l + bodyBox.w, 
+				"The body should not cover the arrow! (right arrow) id= "+ demoWidget.domNode.id);
+			// end of test cases for #16771
+		},
+		function test_Heading_Set(){
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_4");
+			demoWidget.set({label:"New Value"})
+			doh.assertEqual('New Value', demoWidget.labelNode.innerHTML, "id= "+ demoWidget.domNode.id);
+			
+			demoWidget = dijit.byId("dojox_mobile_ToolBarButton_2");
+			demoWidget.set({icon:"mblDomButtonBlueCirclePlus"})
+			doh.assertTrue(demoWidget.iconNode, "there is no iconNode. id= "+ demoWidget.domNode.id);
+			doh.assertTrue(demoWidget.iconNode.childNodes, "there is no iconNode.childNodes. id= "+ demoWidget.domNode.id);
+			doh.assertEqual('mblDomButtonBlueCirclePlus mblDomButton', demoWidget.iconNode.childNodes[0].className, "id= "+ demoWidget.domNode.id);
+		}
+	]);
+	doh.run();
+});
+
diff --git a/dojox/mobile/tests/doh/toolbarbutton/ToolBarButtonSetter.html b/dojox/mobile/tests/doh/toolbarbutton/ToolBarButtonSetter.html
new file mode 100644
index 0000000..9156c9e
--- /dev/null
+++ b/dojox/mobile/tests/doh/toolbarbutton/ToolBarButtonSetter.html
@@ -0,0 +1,171 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Heading</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js"
+		data-dojo-config="mblThemeFiles: ['base','TabBar','dojox/mobile/themes/common/domButtons.css']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		var timeoutInterval = 300;
+		var WIDGET_CLASSNAME1 = "mblDomButtonWhitePlus";
+		var WIDGET_CLASSNAME2 = "mblToolBarButtonSelected";
+		var WIDGET_LABEL1 = "XXXX";
+		require([
+			"dojo/dom-class", // dojo.hasClass
+			"dojo/ready",
+			"dijit/registry",
+			"doh/runner",	//doh functions
+			"dojox/mobile/tests/doh/TestHelper",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TabBar"
+		], function(domClass, ready, registry, runner, TestHelper){
+			ready(function(){
+				runner.register("dojox.mobile.test.doh.ToolBarButton", [
+					{
+						name: "ToolBarButton setter 1",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							var demoWidget1 = registry.byId("btn1");
+							var demoWidget2 = registry.byId("btn2");
+							var demoWidget3 = registry.byId("btn3");
+							demoWidget1.set("icon", WIDGET_CLASSNAME1);
+							demoWidget2.set("icon", WIDGET_CLASSNAME1);
+							demoWidget3.set("icon", WIDGET_CLASSNAME1);
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget1 = registry.byId("btn1");
+								var demoWidget2 = registry.byId("btn2");
+								var demoWidget3 = registry.byId("btn3");
+								runner.assertTrue(domClass.contains(demoWidget1.iconNode.childNodes[0], WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " value=" + demoWidget1.iconNode.childNodes[0].className);
+								runner.assertTrue(domClass.contains(demoWidget2.iconNode.childNodes[0], WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " value=" + demoWidget2.iconNode.childNodes[0].className);
+								runner.assertTrue(domClass.contains(demoWidget3.iconNode.childNodes[0], WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " value=" + demoWidget3.iconNode.childNodes[0].className);
+
+								demoWidget1.set("icon", "../../images/tab-icon-33w.png");
+								demoWidget2.set("icon", "../../images/tab-icon-33w.png");
+								demoWidget3.set("icon", "../../images/tab-icon-33w.png");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "ToolBarButton setter 2",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget1 = registry.byId("btn1");
+								var demoWidget2 = registry.byId("btn2");
+								var demoWidget3 = registry.byId("btn3");
+								TestHelper.verifyImageSrc(demoWidget1.iconNode.childNodes[0], /tab-icon-33w.png/i);
+								TestHelper.verifyImageSrc(demoWidget2.iconNode.childNodes[0], /tab-icon-33w.png/i);
+								TestHelper.verifyImageSrc(demoWidget3.iconNode.childNodes[0], /tab-icon-33w.png/i);
+
+								demoWidget1.set("iconPos", "29,116,29,29");
+								demoWidget1.set("icon", "../../images/tab-icons.png");
+								demoWidget2.set("iconPos", "29,116,29,29");
+								demoWidget2.set("icon", "../../images/tab-icons.png");
+								demoWidget3.set("iconPos", "29,116,29,29");
+								demoWidget3.set("icon", "../../images/tab-icons.png");
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "ToolBarButton setter 3",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget1 = registry.byId("btn1");
+								var demoWidget2 = registry.byId("btn2");
+								var demoWidget3 = registry.byId("btn3");
+								TestHelper.verifyImageSrc(demoWidget1.iconNode.childNodes[0], /tab-icons.png/i);
+								TestHelper.verifyImageSrc(demoWidget2.iconNode.childNodes[0], /tab-icons.png/i);
+								TestHelper.verifyImageSrc(demoWidget3.iconNode.childNodes[0], /tab-icons.png/i);
+								demoWidget1.set("selected", true);
+								demoWidget2.set("selected", true);
+								demoWidget3.set("selected", true);
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "ToolBarButton setter 4",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget1 = registry.byId("btn1");
+								var demoWidget2 = registry.byId("btn2");
+								var demoWidget3 = registry.byId("btn3");
+								runner.assertTrue(domClass.contains(demoWidget1.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget1.iconNode.childNodes[0].className);
+								runner.assertTrue(domClass.contains(demoWidget2.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget2.iconNode.childNodes[0].className);
+								runner.assertTrue(domClass.contains(demoWidget3.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget3.iconNode.childNodes[0].className);
+								runner.assertTrue(demoWidget1.get("selected"), 'return value of get("selected") should be true');
+								runner.assertTrue(demoWidget2.get("selected"), 'return value of get("selected") should be true');
+								runner.assertTrue(demoWidget3.get("selected"), 'return value of get("selected") should be true');
+								demoWidget1.set("selected", false);
+								demoWidget2.set("selected", false);
+								demoWidget3.set("selected", false);
+								demoWidget1.set("label", WIDGET_LABEL1);
+								demoWidget2.set("label", WIDGET_LABEL1);
+								demoWidget3.set("label", WIDGET_LABEL1);
+							}), timeoutInterval);
+							return d;
+						}
+					},
+					{
+						name: "ToolBarButton setter 5",
+						timeout: 4000,
+						runTest: function(){
+							var d = new runner.Deferred();
+							setTimeout(d.getTestCallback(function(){
+
+								var demoWidget1 = registry.byId("btn1");
+								var demoWidget2 = registry.byId("btn2");
+								var demoWidget3 = registry.byId("btn3");
+								runner.assertFalse(domClass.contains(demoWidget1.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget1.iconNode.childNodes[0].className);
+								runner.assertFalse(domClass.contains(demoWidget2.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget2.iconNode.childNodes[0].className);
+								runner.assertFalse(domClass.contains(demoWidget3.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " value=" + demoWidget3.iconNode.childNodes[0].className);
+								runner.assertFalse(demoWidget1.get("selected"), 'return value of get("selected") should be false');
+								runner.assertFalse(demoWidget2.get("selected"), 'return value of get("selected") should be false');
+								runner.assertFalse(demoWidget3.get("selected"), 'return value of get("selected") should be false');
+								runner.assertEqual(WIDGET_LABEL1, demoWidget1.labelNode.innerHTML);
+								runner.assertEqual(WIDGET_LABEL1, demoWidget2.labelNode.innerHTML);
+								runner.assertEqual(WIDGET_LABEL1, demoWidget3.labelNode.innerHTML);
+								runner.assertEqual(WIDGET_LABEL1, demoWidget1.get("label"), 'return value of get("label") should be ' + WIDGET_LABEL1);
+								runner.assertEqual(WIDGET_LABEL1, demoWidget2.get("label"), 'return value of get("label") should be ' + WIDGET_LABEL1);
+								runner.assertEqual(WIDGET_LABEL1, demoWidget3.get("label"), 'return value of get("label") should be ' + WIDGET_LABEL1);
+							}), timeoutInterval);
+							return d;
+						}
+					}
+				]);
+				runner.run();
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Arrow"'>
+		<button id="btn1" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='light:false'>MMMM</button>
+	</div>
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Arrow"'>
+		<button id="btn2" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='light:false, arrow:"left"'>MMMM</button>
+	</div>
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Arrow"'>
+		<button id="btn3" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='light:false, arrow:"right"'>MMMM</button>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/toolbarbutton/ToolBarButtonTests.html b/dojox/mobile/tests/doh/toolbarbutton/ToolBarButtonTests.html
new file mode 100644
index 0000000..dfa0038
--- /dev/null
+++ b/dojox/mobile/tests/doh/toolbarbutton/ToolBarButtonTests.html
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Button Tests</title>
+<script type="text/javascript" src="../../../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	var BUTTON_LABEL = "Button";
+	var WIDGET_CLASSNAME1 = "mblToolBarButton";
+	var WIDGET_CLASSNAME2 = "mblToolBarButtonHasRightArrow";
+	var WIDGET_ICON_CLASSNAME1 = "mblDomButtonWhiteSearch";
+	var WIDGET_ICON_CLASSNAME2 = "mblDomButton";
+
+	require([
+		"dojo/sniff",
+		"dojo/dom-class", // dojo.hasClass
+		"dojo/dom-construct", // dojo.place
+		"dojo/ready", // dojo.ready
+		"dijit/registry",  // dijit.byId
+		"doh/runner",	//doh functions
+		"dojox/mobile/ToolBarButton",
+		"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/View",		// This mobile app uses mobile view
+		"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(has, domClass, domConst, ready, registry, runner, Button){
+		function _createButtonDeclaratively(buttonId) {
+			return registry.byId(buttonId);
+		}
+		function _createButtonProgrammatically(placeHolderId){
+			var button = new Button({label:BUTTON_LABEL, arrow:"right", icon:"mblDomButtonWhiteSearch"});
+			runner.assertNotEqual(null, button, placeHolderId);
+			domConst.place(button.domNode, placeHolderId, "replace");
+			button.startup();
+			return button;
+		}
+		function _createButtonProgrammaticallyWithSourceNodeReference(buttonId){
+			var button = new Button({label:BUTTON_LABEL, arrow:"right", icon:"mblDomButtonWhiteSearch"}, buttonId);
+			button.startup();
+			return button;
+		}
+		function _assertCorrectButton(button){
+			runner.assertNotEqual(null, button);
+			runner.assertEqual(BUTTON_LABEL, button.labelNode.innerHTML, "id=" + button.domNode.id);
+			runner.assertTrue(domClass.contains(button.domNode, WIDGET_CLASSNAME1), WIDGET_CLASSNAME1 + " id=" + button.domNode.id + " class=" + button.domNode.className);
+			runner.assertTrue(domClass.contains(button.domNode, WIDGET_CLASSNAME2), WIDGET_CLASSNAME2 + " id=" + button.domNode.id + " class=" + button.domNode.className);
+			runner.assertTrue(button.iconNode, "iconNode: There is no iconNode. id=" + button.domNode.id);
+			runner.assertTrue(domClass.contains(button.iconNode.childNodes[0], WIDGET_ICON_CLASSNAME1), WIDGET_ICON_CLASSNAME1 + " id=" + button.domNode.id + " class=" + button.iconNode.childNodes[0].className);
+			runner.assertTrue(domClass.contains(button.iconNode.childNodes[0], WIDGET_ICON_CLASSNAME2), WIDGET_ICON_CLASSNAME2 + " id=" + button.domNode.id + " class=" + button.iconNode.childNodes[0].className);
+		}
+		function _showView2(){
+			var view1 = registry.byId("view1");
+			view1.performTransition("view2", 1, "none");
+		}
+		ready(function(){
+			runner.register("dojox.mobile.test.doh.ButtonTests", [
+				function testInView1(){
+					var button1 = _createButtonDeclaratively("view1-button1");
+					var button2 = _createButtonProgrammatically("view1-button2");
+					var button3 = _createButtonProgrammaticallyWithSourceNodeReference("view1-button3");
+			
+					_assertCorrectButton(button1);
+					_assertCorrectButton(button2);
+					_assertCorrectButton(button3);
+				},
+				function testInView2(){
+					var button1 = _createButtonDeclaratively("view2-button1");
+					var button2 = _createButtonProgrammatically("view2-button2");
+					var button3 = _createButtonProgrammaticallyWithSourceNodeReference("view2-button3");
+					
+					_showView2();
+					
+					_assertCorrectButton(button1);
+					_assertCorrectButton(button2);
+					_assertCorrectButton(button3);
+				}
+			]);
+			runner.run();
+		});
+	})
+</script>
+</head>
+<body>
+	<div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+		<h1>View 1</h1>
+		<div id="view1-button1" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props="arrow:'right', icon:'mblDomButtonWhiteSearch'">Button</div>
+		<div id="view1-button2"></div>
+		<div id="view1-button3"></div>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1>View 2</h1>
+		<div id="view2-button1" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props="arrow:'right', icon:'mblDomButtonWhiteSearch'">Button</div>
+		<div id="view2-button2"></div>
+		<div id="view2-button3"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/toolbarbutton/ToolBarButton_Programmatic.html b/dojox/mobile/tests/doh/toolbarbutton/ToolBarButton_Programmatic.html
new file mode 100644
index 0000000..af8e9dd
--- /dev/null
+++ b/dojox/mobile/tests/doh/toolbarbutton/ToolBarButton_Programmatic.html
@@ -0,0 +1,181 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>ToolBarButton</title>
+		<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../../../themes/iphone/TabBar.css" rel="stylesheet"/>
+		<link href="../../../themes/common/domButtons.css" rel="stylesheet"/>
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.TabBar");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+	        dojo.require("doh.runner");
+			dojo.addOnLoad(function(){
+
+				var view = dijit.byId("general");
+				var demoWidget = new dojox.mobile.Heading({label:"World Clock"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				var childWidget = new dojox.mobile.ToolBarButton({id:"btn1", label:"Edit", style:{padding:"0px 14px"}});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"mblDomButtonWhitePlus", style:"float:right;", onclick:"console.log('+ was clicked')"});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading({label:"Alarm Clock"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({label:"Edit", style:{padding:"0px 14px"}});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"mblDomButtonWhitePlus", style:{float:"right"}});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading({label:"Voice Memos"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({label:"Speaker"});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({label:"Done", btnClass:"mblColorBlue", style:{float:"right"}});
+				dojo.removeClass(childWidget.domNode, "mblColorDefault ");
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading({label:"Updatess"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({label:"Update All", style:{float:"right"}});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading({label:"News", back:"Bookmarks", moveTo:"bookmarks"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({label:"Done", btnClass:"mblColorBlue", style:{float:"right"}});
+				dojo.removeClass(childWidget.domNode, "mblColorDefault ");
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading();
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({label:"Done", btnClass:"mblColorBlue"});
+				dojo.removeClass(childWidget.domNode, "mblColorDefault ");
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({label:"New Folder", style:{float:"right"}});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading();
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({label:"New", toggle:"true"});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({label:"Toggle", toggle:"true"});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"../../images/a-icon-12.png", moveTo:"view3"});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"../../images/tab-icons.png", iconPos:"29,0,29,29", moveTo:"view3"});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"mblDomButtonWhitePlus", iconPos:"29,0,29,29", style:{float:"right"}});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading();
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"mblDomButtonWhiteSearch", style:{float:"right"}});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading({align:"center"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"mblDomButtonWhitePlus"});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"../../images/tab-icon-15h.png", style:{float:"right"}});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+
+				demoWidget = new dojox.mobile.Heading({label:"Inbox(32)", back:"Top"});
+//				view.addChild(demoWidget);
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"mblDomButtonWhiteSearch", style:{float:"right"}});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"mblDomButtonWhiteUpArrow", style:{float:"right"}});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({icon:"mblDomButtonWhiteDownArrow", style:{float:"right"}});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				
+				// Test cases for #16771
+				// a) With arrow but no label (nor icon)
+				demoWidget = new dojox.mobile.Heading();
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({arrow:"left"});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				
+				demoWidget = new dojox.mobile.Heading();
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({arrow:"right"});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				
+				// b) With arrow, icon and label
+				demoWidget = new dojox.mobile.Heading();
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({arrow:"left", icon:"mblDomButtonWhiteDownArrow", label:"some label"});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				
+				demoWidget = new dojox.mobile.Heading();
+				demoWidget.placeAt(view.containerNode);
+				demoWidget.startup();
+				childWidget = new dojox.mobile.ToolBarButton({arrow:"right", icon:"mblDomButtonWhiteDownArrow", label:"some label"});
+				childWidget.placeAt(demoWidget.containerNode);
+				childWidget.startup();
+				// end of test cases for #16771
+			});
+		</script>
+		<script type="text/javascript" src="../TestUtil.js"></script>
+		<script type="text/javascript" src="ToolBarButton.js"></script>
+	</head>
+	<body>
+		<div id="general" dojoType="dojox.mobile.View" selected="true">
+		</div>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/toolbarbutton/module.js b/dojox/mobile/tests/doh/toolbarbutton/module.js
new file mode 100644
index 0000000..e7902ca
--- /dev/null
+++ b/dojox/mobile/tests/doh/toolbarbutton/module.js
@@ -0,0 +1,10 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.ToolBarButton", require.toUrl("./ToolBarButton.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.ToolBarButton", require.toUrl("./ToolBarButton_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.ToolBarButton", require.toUrl("./ToolBarButtonSetter.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.ToolBarButton", require.toUrl("./ToolBarButtonTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/toolbarbutton/runTests.html b/dojox/mobile/tests/doh/toolbarbutton/runTests.html
new file mode 100644
index 0000000..f57d471
--- /dev/null
+++ b/dojox/mobile/tests/doh/toolbarbutton/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.toolbarbutton.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/topHeading_defect.html b/dojox/mobile/tests/doh/topHeading_defect.html
index 96037e6..1235784 100644
--- a/dojox/mobile/tests/doh/topHeading_defect.html
+++ b/dojox/mobile/tests/doh/topHeading_defect.html
@@ -4,10 +4,10 @@
 		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 		<meta name="apple-mobile-web-app-capable" content="yes" />
 		<title>Heading</title>
-		<link href="../../themes/android/android.css" rel="stylesheet">
-		<link href="../../themes/domButtons.css" rel="stylesheet">
+		<link href="../../themes/android/android.css" rel="stylesheet"/>
+		<link href="../../themes/domButtons.css" rel="stylesheet"/>
 
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
 
 		<script language="JavaScript" type="text/javascript">
 			//dojo.require("dojo.parser"); // Use the lightweight parser.
diff --git a/dojox/mobile/tests/doh/transition/MblCSS3TransitionTests.html b/dojox/mobile/tests/doh/transition/MblCSS3TransitionTests.html
new file mode 100644
index 0000000..e9ba4b5
--- /dev/null
+++ b/dojox/mobile/tests/doh/transition/MblCSS3TransitionTests.html
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<html>
+        <head>
+        <title>ICS Bug</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+        <meta name="viewport"
+                content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+        <meta name="apple-mobile-web-app-capable" content="yes" />
+        <script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="mblCSS3Transition:'dojox/css3/transit', parseOnLoad:true, async:true"></script>
+		<script language="JavaScript" type="text/javascript">
+			require([
+				"dijit/registry",  // dijit.byId
+				"doh/runner",	//doh functions
+				"dojo/ready",
+				"dojo/dom",
+				"dojox/mobile",
+				"dojox/mobile/deviceTheme",
+				"dojox/mobile/parser"], function(registry, runner, ready, dom){
+		
+				ready(function(){
+ 					runner.register("dojox.mobile.test.doh.MBLCSS3TransitionTests", [
+						{
+							name: "Verify ticket #16592 is fixed",
+							timeout: 10000,
+							setUp: function() {
+								this.data = {runner: runner, view2: dom.byId("view2")};
+							},
+							runTest: function(){
+								var d = new runner.Deferred();
+								// verify there is no padding top on the second view
+								runner.assertFalse(this.data.view2.style.paddingTop, "No padding top value expected for view2 before transition");
+								registry.byId("slideItem")._onClick({});
+								setTimeout(d.getTestCallback(function(){
+									var pt = this.fixture.data.view2.style.paddingTop;
+									this.fixture.data.runner.assertFalse(!!pt, "No value was expected for padding top after transition (" + pt + " observed)");
+								}), 2000);
+								return d;
+							}
+						}]);
+					runner.run();
+				});
+			})
+		</script>
+        </head>
+        <body style="visibility:hidden;">
+        		<!-- Views for test "Verify ticket #16592 is fixed" -->
+                <div id="view1" data-dojo-type="dojox.mobile.View" selected="true">
+                        <ul data-dojo-type="dojox.mobile.RoundRectList">
+                                <li id="slideItem"
+                                	data-dojo-type="dojox.mobile.ListItem"
+                                        moveTo="view2"
+                                        transition="slide">Slide this view</li>
+                        </ul>
+                </div>
+                <div id="view2" data-dojo-type="dojox.mobile.View">
+                        <h1 data-dojo-type="dojox.mobile.Heading" back="Back"
+                                moveTo="view1">View 2</h1>
+                </div>
+                <!-- End of views for test "Verify ticket #16592 is fixed" -->
+                
+        </body>
+</html>
diff --git a/dojox/mobile/tests/doh/transition/module.js b/dojox/mobile/tests/doh/transition/module.js
new file mode 100644
index 0000000..2e6008c
--- /dev/null
+++ b/dojox/mobile/tests/doh/transition/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.transition", require.toUrl("./MblCSS3TransitionTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/transition/runTests.html b/dojox/mobile/tests/doh/transition/runTests.html
new file mode 100644
index 0000000..943df8f
--- /dev/null
+++ b/dojox/mobile/tests/doh/transition/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.transition.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/valuepickerdatepicker/DatePickerIso.html b/dojox/mobile/tests/doh/valuepickerdatepicker/DatePickerIso.html
new file mode 100644
index 0000000..c674b7d
--- /dev/null
+++ b/dojox/mobile/tests/doh/valuepickerdatepicker/DatePickerIso.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ValuePickerDatePicker (ISO)</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/kernel"
+		], function(dojo){
+			var lang = location.search.match(/lang=(\w*)/) ? RegExp.$1 : null;
+			if(lang){ dojo.locale = lang; }
+			require([
+				"dojo/_base/window",
+				"dojo/dom",
+				"dojo/ready",
+				"dijit/registry",
+				"dojo/date/stamp",
+				"doh/runner",
+				"dojo/_base/xhr",
+				"dojox/mobile/parser",
+				"dojox/mobile",
+				"dojox/mobile/compat",
+				"dojox/mobile/ValuePickerDatePicker"
+			], function(win, dom, ready, registry, datestamp, doh){
+				changeLocale = function(){
+					win.doc.forms[0].submit();
+				}
+				gotoToday = function(){
+					registry.byId("picker1").set("value", datestamp.toISOString(new Date(), { selector: "date" }));
+				}
+				showSelectedValue = function(){
+					var w = registry.byId("picker1");
+					document.getElementById("msg").innerHTML = w.get("value");
+				}
+				ready(function(){
+					doh.register("dojox.mobile.test.doh.DatePickerIso", [
+					function test_DatePickerIso(){
+						
+					// Test getter:
+					var v = registry.byId("picker1").get("value");
+					var today = datestamp.toISOString(new Date(), { selector: "date" });
+					doh.assertEqual(today, v);
+					
+					// Test setter:
+					var b = new Date(2000, 0, 1, 0, 0, 0, 0);
+					registry.byId("picker1").set("value", datestamp.toISOString(b, { selector: "date" }));
+					v = registry.byId("picker1").get("date");
+					doh.assertEqual(b.getFullYear(), v.getFullYear());
+					doh.assertEqual(b.getMonth(), v.getMonth());
+					doh.assertEqual(b.getDate(), v.getDate());
+					
+					// Test error thrown on invalid date:
+					var errThrown;
+					try {
+						registry.byId("picker1").set("value", "not a date");
+					} catch(err){
+						errThrown = true;
+					}
+					doh.assertTrue(errThrown);
+					
+					}]);
+					doh.run();
+				});
+			});
+		});
+	</script>
+
+	<style>
+	#picker1 {
+		margin: 20px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;background-color:#424142;">
+	<div data-dojo-type="dojox.mobile.View">
+		<form>
+			<div data-dojo-type="dojox.mobile.Heading">
+				<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="showSelectedValue()" data-dojo-props='label:"OK"'></span>
+				<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="gotoToday()" data-dojo-props='label:"Today"'></span>
+				<select id="sel" name="lang" onchange="changeLocale()" style="float:left;margin-top:10px;">
+					<option value=""></option>
+					<option value="ar">ar</option>
+					<option value="ca">ca</option>
+					<option value="cs">cs</option>
+					<option value="da">da</option>
+					<option value="de">de</option>
+					<option value="el">el</option>
+					<option value="en">en</option>
+					<option value="en-au">en-au</option>
+					<option value="en-ca">en-ca</option>
+					<option value="en-gb">en-gb</option>
+					<option value="es">es</option>
+					<option value="fi">fi</option>
+					<option value="fr">fr</option>
+					<option value="fr-ch">fr-ch</option>
+					<option value="he">he</option>
+					<option value="hu">hu</option>
+					<option value="it">it</option>
+					<option value="ja">ja</option>
+					<option value="ko">ko</option>
+					<option value="nb">nb</option>
+					<option value="nl">nl</option>
+					<option value="pl">pl</option>
+					<option value="pt">pt</option>
+					<option value="pt-pt">pt-pt</option>
+					<option value="ro">ro</option>
+					<option value="ru">ru</option>
+					<option value="sk">sk</option>
+					<option value="sl">sl</option>
+					<option value="sv">sv</option>
+					<option value="th">th</option>
+					<option value="tr">tr</option>
+					<option value="zh">zh</option>
+					<option value="zh-hant">zh-hant</option>
+					<option value="zh-hk">zh-hk</option>
+					<option value="zh-tw">zh-tw</option>
+				</select>
+			</div>
+		</form>
+		<div id="picker1" data-dojo-type="dojox.mobile.ValuePickerDatePicker"></div>
+		<div id="msg"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/valuepickerdatepicker/ValuePickerDatePicker.html b/dojox/mobile/tests/doh/valuepickerdatepicker/ValuePickerDatePicker.html
new file mode 100644
index 0000000..eb2b6cf
--- /dev/null
+++ b/dojox/mobile/tests/doh/valuepickerdatepicker/ValuePickerDatePicker.html
@@ -0,0 +1,224 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport"
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ValuePickerDatePicker</title>
+
+	<script type="text/javascript"
+		src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript"
+		src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		var onYearSet, onMonthSet, onDaySet;
+		require([
+			"dojo/ready", "dijit/registry", "doh/runner", 
+			"dojox/mobile", "dojox/mobile/compat", "dojox/mobile/parser", 
+			"dojox/mobile/ValuePickerDatePicker"],
+			function(ready, registry, runner){
+						
+			var onYearSetCounter = 0, onMonthSetCounter = 0, onDaySetCounter = 0,
+				yearWatchCounter = 0, monthWatchCounter = 0, dayWatchCounter = 0;
+			var initCounters, checkCounters;
+
+			onYearSet = function(){
+				onYearSetCounter++;
+			};
+			onMonthSet = function(){
+				onMonthSetCounter++;
+			};
+			onDaySet = function(){
+				onDaySetCounter++;
+			};
+
+			var initCounters = function(){
+				onYearSetCounter = onMonthSetCounter = onDaySetCounter = 0;
+				yearWatchCounter = monthWatchCounter = dayWatchCounter = 0;
+			};
+
+			ready(function(){
+				var picker = registry.byId("picker1"),
+					yearSlot = picker.slots[0],
+					monthSlot = picker.slots[1],
+					daySlot = picker.slots[2];
+
+				yearSlot.watch("value", function(name, oldVal, newVal){
+					yearWatchCounter++;
+				});
+				monthSlot.watch("value", function(name, oldVal, newVal){
+					monthWatchCounter++;
+				});
+				daySlot.watch("value", function(name, oldVal, newVal){
+					dayWatchCounter++;
+				});
+
+				var showCounters = function(txt){
+					// Just for debugging.
+					console.log("==============================");
+					if(txt) console.log(txt + ":");
+					console.log("yearSetCounter: " + onYearSetCounter);
+					console.log("monthSetCounter: " + onMonthSetCounter);
+					console.log("daySetCounter: " + onDaySetCounter);
+					console.log("yearWatchCounter: " + yearWatchCounter);
+					console.log("monthWatchCounter: " + monthWatchCounter);
+					console.log("dayWatchCounter: " + dayWatchCounter);
+					console.log("==============================");
+				};
+				
+				var checkCounters = function(
+						expectedOnYearSetCounter, expectedOnMonthSetCounter, expectedOnDaySetCounter,
+						expectedYearWatchCounter, expectedMonthWatchCounter, expectedDayWatchCounter){
+					// showCounters();
+					runner.assertEqual(expectedOnYearSetCounter, onYearSetCounter, "Unexpected onYearSetCounter");
+					runner.assertEqual(expectedOnMonthSetCounter, onMonthSetCounter, "Unexpected onMonthSetCounter");
+					runner.assertEqual(expectedOnDaySetCounter, onDaySetCounter, "Unexpected onDaySetCounter");
+					runner.assertEqual(expectedYearWatchCounter, yearWatchCounter, "Unexpected yearWatchCounter");
+					runner.assertEqual(expectedMonthWatchCounter, monthWatchCounter, "Unexpected monthWatchCounter");
+					runner.assertEqual(expectedDayWatchCounter, dayWatchCounter, "Unexpected dayWatchCounter");
+				};
+				
+				var checkSlotValues = function(expectedYear, expectedMonth, expectedDay){
+					runner.assertEqual(expectedYear, picker.slots[0].get("value"), "Unexpected value of year slot");
+					runner.assertEqual(expectedDay, picker.slots[2].get("value"), "Unexpected value of day slot");
+					// For the month, note that the label (and value) of the month slot is 
+					// localized, and is also browser-dependant (for instance, on IE8 in English
+					// locale, the value for the fifth month is "may", while on other browsers
+					// it is "May". Hence, in this test, instead of comparing directly the
+					// value of the slot with a given string ("May"), we start from the month
+					// number and we compare the current value of the slot with the label 
+					// at the corresponding index. Thus the test is independent on locale 
+					// and browser localization of month names.  
+					var monthSlot = picker.slots[1];
+					var expectedMonthLabel = monthSlot.labels[expectedMonth - 1];
+					runner.assertEqual(expectedMonthLabel, monthSlot.get("value"), "Unexpected value of month slot");
+				};
+				
+				var checkEndDaysOfMonth = function(nDaysInMonth, title){
+					var daySlot = picker.slots[2];
+					runner.assertEqual(nDaysInMonth, daySlot.items.length, title);
+				};
+				
+				// Test case for #16502
+				runner.register("dojox.mobile.test.doh.SpinWheelTests", [
+					{
+						name: "SpinWheelTest1",
+						timeout: 4000,
+						runTest: function(){
+							picker.set('value', '2020-06-06');
+							// setTimeout used because the handlers onYearSet, onMonthSet 
+							// and onDaySet are called asynchronously
+							var d = new runner.Deferred();
+							setTimeout(function(){
+								initCounters();
+								// ensure year, month, and day change:
+								picker.set('value', '2019-05-05');
+								// setTimeout used because the handlers onYearSet, onMonthSet 
+								// and onDaySet are called asynchronously
+								setTimeout(d.getTestCallback(function(){
+									// notifications for year, month and day
+									checkCounters(1, 1, 1, 1, 1, 1);
+									checkSlotValues("2019", 5/*"May"*/, "5");
+  								}), 1000);
+							}, 1000);
+							return d;
+						}
+					},
+					{
+						name: "SpinWheelTest2",
+						timeout: 4000,
+						runTest: function(){
+							picker.set('value', '2020-06-06');
+							// setTimeout used because the handlers onYearSet, onMonthSet 
+							// and onDaySet are called asynchronously
+							var d = new runner.Deferred();
+							setTimeout(function(){
+								initCounters();
+								// now only the year changes
+								picker.set('value', '2021-06-06');
+								// setTimeout used because the handlers onYearSet, onMonthSet 
+								// and onDaySet are called asynchronously
+								setTimeout(d.getTestCallback(function(){
+									// notifications for year, not for month and day
+									checkCounters(1, 0, 0, 1, 0, 0);
+									checkSlotValues("2021", 6/*"Jun"*/, "6");
+  								}), 1000);
+							}, 1000);
+							return d;
+						}
+					},
+					{
+						name: "SpinWheelTest3",
+						timeout: 4000,
+						runTest: function(){
+							picker.set('value', '2013-01-31');
+							// setTimeout used because the handlers onYearSet, onMonthSet 
+							// and onDaySet are called asynchronously
+							var d = new runner.Deferred();
+							setTimeout(function(){
+								initCounters();
+								// now change the month from Jan to Feb
+								// The labels/values being localized, let's set 
+								var februaryLabel = picker.slots[1].labels[1]; // the second label is for February
+								picker.slots[1].set("value", februaryLabel);
+								// setTimeout used because the handlers onYearSet, onMonthSet 
+								// and onDaySet are called asynchronously
+								setTimeout(d.getTestCallback(function(){
+									// notifications for month and day, not for year
+									checkCounters(0, 1, 1, 0, 1, 1);
+									// Check that changing the month also changes the day value 
+									// to the last day of Feb. 2012 (leap year, hence last day is 29).
+									checkSlotValues("2013", 2/*"Feb"*/, "28");
+									checkEndDaysOfMonth(28, "SpinWheelTest3"); // grayed out starting with day 29
+  								}), 1000);
+							}, 1000);
+							return d;
+						}
+					},
+					{
+						name: "SpinWheelTest4",
+						timeout: 4000,
+						runTest: function(){
+							picker.set('value', '2012-02-29');
+							// setTimeout used because the handlers onYearSet, onMonthSet 
+							// and onDaySet are called asynchronously
+							var d = new runner.Deferred();
+							setTimeout(function(){
+								initCounters();
+								// now change the year to 2013
+								picker.slots[0].set("value", "2013");
+								// setTimeout used because the handlers onYearSet, onMonthSet 
+								// and onDaySet are called asynchronously
+								setTimeout(d.getTestCallback(function(){
+									// notifications for year and day, not for month
+									checkCounters(1, 0, 1, 1, 0, 1);
+									// Check that changing the year also changes the day value 
+									// to the last day of Feb. 2013 (non leap year, hence last day is 28).
+									checkSlotValues("2013", 2/*"Feb"*/, "28");
+									checkEndDaysOfMonth(28, "SpinWheelTest4"); // grayed out starting with day 29
+  								}), 1000);
+							}, 1000);
+							return d;
+						}
+					}
+				]);
+				
+				runner.run();
+			});
+		});				
+		</script>
+	</head>
+	<body style="visibility:hidden;">
+		<div data-dojo-type="dojox/mobile/View">
+			<form>
+				<div data-dojo-type="dojox/mobile/Heading">
+					SpinWheel
+				</div>
+				<div id="picker1" data-dojo-type="dojox/mobile/ValuePickerDatePicker"
+					data-dojo-props="onYearSet: onYearSet, onMonthSet: onMonthSet, onDaySet: onDaySet"></div>
+			</form>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/doh/valuepickerdatepicker/module.js b/dojox/mobile/tests/doh/valuepickerdatepicker/module.js
new file mode 100644
index 0000000..2c0d89a
--- /dev/null
+++ b/dojox/mobile/tests/doh/valuepickerdatepicker/module.js
@@ -0,0 +1,8 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.ValuePickerDatePicker", require.toUrl("./DatePickerIso.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.ValuePickerDatePicker", require.toUrl("./ValuePickerDatePicker.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/valuepickerdatepicker/runTests.html b/dojox/mobile/tests/doh/valuepickerdatepicker/runTests.html
new file mode 100644
index 0000000..f9d16d4
--- /dev/null
+++ b/dojox/mobile/tests/doh/valuepickerdatepicker/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.valuepickerdatepicker.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/valuepickertimepicker/ValuePickerTimePickerTests.html b/dojox/mobile/tests/doh/valuepickertimepicker/ValuePickerTimePickerTests.html
new file mode 100644
index 0000000..c51ab12
--- /dev/null
+++ b/dojox/mobile/tests/doh/valuepickertimepicker/ValuePickerTimePickerTests.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ValuePicker on SimpleDialog</title>
+
+	<script type="text/javascript" src="../../../../../dojox/mobile/deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+		    "doh/runner",
+			"dojo/date/locale",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ValuePickerTimePicker"
+		], function(runner, locale, dom, ready, registry){
+				onTimeChanged = function(){
+					var d = registry.byId("picker2").get("date");
+					if(d){
+						dom.byId("changedValue").innerHTML =
+							locale.format(d, {timePattern:"h:mm a",selector:"time"});
+					}
+				};
+				
+				ready(function(){
+					var picker = registry.byId("picker2");
+					// Tests
+					runner.register("dojox.mobile.test.doh.ValuePickerTimePickerTests", [
+       					{
+       						name: "Verify ticket #16740 is fixed",
+       						timeout: 4000,
+       						runTest: function(){
+       							// Initialize the value of the time picker
+       							picker.set("values", ["22", "10"]);
+       							var d = new runner.Deferred();
+       							setTimeout(function(){
+   									runner.assertEqual("10:10 PM", dom.byId("changedValue").innerHTML);
+       								picker.onBtnClick();
+       								setTimeout(d.getTestCallback(function(){
+       									runner.assertEqual("10:10 AM", dom.byId("changedValue").innerHTML);
+         								}), 1000);
+       							}, 1000);
+       							return d;
+       						}
+       					}
+       				]);
+                                				
+   				runner.run();
+				});
+			});
+
+	</script>
+
+</head>
+<body style="visibility:hidden;">
+	<div id="view" data-dojo-type="dojox.mobile.View">
+		<div id="picker2" data-dojo-type="dojox.mobile.ValuePickerTimePicker" data-dojo-props="is24h:false,onValueChanged:onTimeChanged"></div>
+		<div id="changedValue"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/valuepickertimepicker/module.js b/dojox/mobile/tests/doh/valuepickertimepicker/module.js
new file mode 100644
index 0000000..7ef1bdc
--- /dev/null
+++ b/dojox/mobile/tests/doh/valuepickertimepicker/module.js
@@ -0,0 +1,7 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.ValuePickerTimePickerTests", require.toUrl("./ValuePickerTimePickerTests.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/valuepickertimepicker/runTests.html b/dojox/mobile/tests/doh/valuepickertimepicker/runTests.html
new file mode 100644
index 0000000..0d61fd6
--- /dev/null
+++ b/dojox/mobile/tests/doh/valuepickertimepicker/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.valuepickertimepicker.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/doh/view/View-demo.html b/dojox/mobile/tests/doh/view/View-demo.html
new file mode 100644
index 0000000..a0e16e1
--- /dev/null
+++ b/dojox/mobile/tests/doh/view/View-demo.html
@@ -0,0 +1,838 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>View demo</title>
+
+	<script type="text/javascript" src="../../../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		//dojo.require("dojo.parser"); // Use the lightweight parser.
+		dojo.require("dojox.mobile.parser");
+		dojo.require("dojox.mobile");
+		dojo.require("dojox.mobile.ScrollableView");
+		dojo.require("dojox.mobile.TabBar");
+		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
+
+        dojo.require("doh.runner");
+	</script>
+	<script type="text/javascript" src="../TestUtil.js"></script>
+	<script language="JavaScript" type="text/javascript">
+		dojo.addOnLoad(function(){
+			doh.register("dojox.mobile.test.doh.View", [
+				{
+
+					name: "View Verification",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						setTimeout(d.getTestCallback(function(){
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view2");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view3");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("categ");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+							
+							demoWidget = dijit.byId("top25");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("search");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("article");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+						}),500);
+						return d;
+					}
+				},
+				{
+					name: "View Verification2",
+					timeout: 2000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						fireOnMouseDown("dojox_mobile_TabBarButton_1");
+						fireOnMouseUp("dojox_mobile_TabBarButton_1");
+						setTimeout(d.getTestCallback(function(){
+
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view2");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view3");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("categ");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+							
+							demoWidget = dijit.byId("top25");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("search");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("article");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}),1000);
+						return d;
+					}
+				},
+				{
+					name: "View Verification3",
+					timeout: 20000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						fireOnMouseDown("dojox_mobile_TabBarButton_2");
+						fireOnMouseUp("dojox_mobile_TabBarButton_2");
+						setTimeout(d.getTestCallback(function(){
+
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view2");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view3");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("categ");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+							
+							demoWidget = dijit.byId("top25");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("search");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("article");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}),500);
+						return d;
+					}
+				},
+				{
+					name: "View Verification4",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						fireOnMouseDown("dojox_mobile_TabBarButton_4");
+						fireOnMouseUp("dojox_mobile_TabBarButton_4");
+						setTimeout(d.getTestCallback(function(){
+
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view2");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view3");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("categ");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+							
+							demoWidget = dijit.byId("top25");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("search");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("article");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}),1000);
+						return d;
+					}
+				},
+				{
+					name: "View Verification5",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						fireOnMouseDown("dojox_mobile_TabBarButton_5");
+						fireOnMouseUp("dojox_mobile_TabBarButton_5");
+						setTimeout(d.getTestCallback(function(){
+
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view2");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view3");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("categ");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+							
+							demoWidget = dijit.byId("top25");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("search");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("article");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}),500);
+						return d;
+					}
+				},
+				{
+					name: "View Verification6",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						fireOnMouseDown("dojox_mobile_TabBarButton_6");
+						fireOnMouseUp("dojox_mobile_TabBarButton_6");
+						setTimeout(d.getTestCallback(function(){
+
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view2");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view3");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("categ");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+							
+							demoWidget = dijit.byId("top25");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("search");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("article");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}),500);
+						return d;
+					}
+				},
+				{
+					name: "View Verification7",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						fireOnMouseDown("dojox_mobile_TabBarButton_7");
+						fireOnMouseUp("dojox_mobile_TabBarButton_7");
+						setTimeout(d.getTestCallback(function(){
+
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view2");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view3");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("categ");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+							
+							demoWidget = dijit.byId("top25");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("search");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("article");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}),500);
+						return d;
+					}
+				},
+				{
+					name: "View Verification8",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						fireOnMouseDown("dojox_mobile_TabBarButton_3");
+						fireOnMouseUp("dojox_mobile_TabBarButton_3");
+						setTimeout(d.getTestCallback(function(){
+
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view2");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view3");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("categ");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+							
+							demoWidget = dijit.byId("top25");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("search");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("article");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}),500);
+						return d;
+					}
+				},
+				{
+					name: "View Verification9",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						fireOnMouseDown("dojox_mobile_TabBarButton_0");
+						fireOnMouseUp("dojox_mobile_TabBarButton_0");
+						setTimeout(d.getTestCallback(function(){
+
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view2");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view3");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("categ");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+							
+							demoWidget = dijit.byId("top25");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("search");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("article");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}),500);
+						return d;
+					}
+				},
+				{
+					name: "View Verification10",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						fireOnMouseDown("dojox_mobile_TabBarButton_1");
+						fireOnMouseUp("dojox_mobile_TabBarButton_1");
+						setTimeout(d.getTestCallback(function(){
+
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view2");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view3");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("categ");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+							
+							demoWidget = dijit.byId("top25");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("search");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("article");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}),500);
+						return d;
+					}
+				},
+				{
+					name: "View Verification11",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						fireOnMouseDown("dojox_mobile_TabBarButton_2");
+						fireOnMouseUp("dojox_mobile_TabBarButton_2");
+						setTimeout(d.getTestCallback(function(){
+
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view1");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view2");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("view3");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("categ");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+							
+							demoWidget = dijit.byId("top25");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("search");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("article");
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+
+							demoWidget = dijit.byId("dojox_mobile_TabBar_1");
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}),500);
+						return d;
+					}
+				}
+			]);
+			doh.run();
+		});
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	.list1 li{
+		border-style: solid;
+		border-width: 1px 0px 1px 0px;
+		border-top-color: #BABABC;
+		border-bottom-color: #89898C;
+		background-color: #ACACAF;
+		line-height: 0px;
+	}
+	.list1 li table{
+		line-height: normal;
+	}
+	.list1 li:nth-child(even){
+		background-color: #97979B;
+	}
+	#list2 li:nth-child(even){
+		background-color: #eeeeee;
+	}
+	#categ1 {
+		font-size: 18px;
+	}
+	#categ1 li{
+		line-height: 70px;
+	}
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	.content {
+		padding:0px 10px;
+		background-color: white;
+	}
+	p {
+		font-family: Helvetica;
+		font-size: 12px;
+	}
+	.title {
+		color: blue;
+		margin-bottom: 4px;
+	}
+	.subtitle {
+		font-style: italic;
+		color: gray;
+		margin: 0px;
+		margin-bottom: 4px;
+	}
+	.subsubtitle {
+		margin: 16px 0px 0px 0px;
+	}
+	.lst {
+		margin: 0px;
+		padding: 0px 14px;
+	}
+	.lst li {
+		font-family: Helvetica;
+		font-size: 12px;
+		margin: 0px;
+		list-style-type: square;
+	}
+	.iphone_theme .mblTabBarSegmentedControl .mblTabBarButtonIconArea {
+		display: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:{"iphone_theme":"segmentedControl","*":"tallTab"}, fixed:"top"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../../images/tab-icon-16.png", icon2:"../../images/tab-icon-16h.png", moveTo:"view1", selected:true'>New</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../../images/tab-icon-15.png", icon2:"../../images/tab-icon-15h.png", moveTo:"view2"'>What's Hot</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../../images/tab-icon-10.png", icon2:"../../images/tab-icon-10h.png", moveTo:"view3"'>Genius</li>
+		</ul>
+
+		<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" class="list1">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="../../images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="../../images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+									Martin Parker Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="../../images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="../../images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="../../images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" id="list2">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="../../images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="../../images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="../../images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="../../images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+					Network											   
+				</li>												   
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+					Line
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+					Songs
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+					Videos
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+					Photos
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+					Applications
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+					Capacity
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+					Available
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+					Version
+				</li>
+			</ul>
+		</div>
+	</div>
+
+	<div id="categ" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Categories</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" class="list1" id="categ1">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 1</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 2</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 3</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 4</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 5</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 6</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 7</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 8</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 9</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 10</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 11</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 12</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 13</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 14</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 15</li>
+		</ul>
+	</div>
+
+	<div id="top25" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>News</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Top Stories</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+				Top 10 news stories of the decade
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+				Create client-side diagrammatic interaction in Web applications with GFX
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+	</div>
+
+	<div id="search" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+
+	<div id="article" data-dojo-type="dojox.mobile.ScrollableView" style="background-color:white;height:100%">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Article</h1>
+		<div class="content">
+			<h3 class="title">Did you know?</h3>
+			<h4 class="subtitle">Features of dojox.mobile</h4>
+			<h5 class="subsubtitle">No images are used</h5>
+			<ul class="lst">
+				<li>UI parts consist of DOM and CSS3.</li>
+				<li>Only application icons are images.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
+			<ul class="lst">
+				<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Support for CSS sprite</h5>
+			<ul class="lst">
+				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Possible to use the webkitMobile build profile (when PC browser support is unnecessary)</h5>
+			<ul class="lst">
+				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
+			</ul>
+		</div>
+	</div>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../../images/tab-icon-16.png", icon2:"../../images/tab-icon-16h.png", selected:true, moveTo:"group1"'>Featured</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../../images/tab-icon-15.png", icon2:"../../images/tab-icon-15h.png", moveTo:"categ"'>Categories</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../../images/tab-icon-10.png", icon2:"../../images/tab-icon-10h.png", moveTo:"top25"'>Top 25</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../../images/tab-icon-11.png", icon2:"../../images/tab-icon-11h.png", moveTo:"search"'>Search</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"../../images/tab-icon-13.png", icon2:"../../images/tab-icon-13h.png", moveTo:"article"'>Updates</li>
+	</ul>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/view/View.html b/dojox/mobile/tests/doh/view/View.html
new file mode 100644
index 0000000..3162e8c
--- /dev/null
+++ b/dojox/mobile/tests/doh/view/View.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+	<title>View</title>
+	<link href="../../../themes/iphone/base.css" rel="stylesheet"/>
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	.list1 li{
+		border-style: solid;
+		border-width: 1px 0px 1px 0px;
+		border-top-color: #BABABC;
+		border-bottom-color: #89898C;
+		background-color: #ACACAF;
+		line-height: 0px;
+	}
+	.list1 li table{
+		line-height: normal;
+	}
+	.list1 li:nth-child(even){
+		background-color: #97979B;
+	}
+	#list2 li:nth-child(even){
+		background-color: #eeeeee;
+	}
+	#categ1 {
+		font-size: 18px;
+	}
+	#categ1 li{
+		line-height: 70px;
+	}
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	.content {
+		padding:0px 10px;
+		background-color: white;
+	}
+	p {
+		font-family: Helvetica;
+		font-size: 12px;
+	}
+	.title {
+		color: blue;
+		margin-bottom: 4px;
+	}
+	.subtitle {
+		font-style: italic;
+		color: gray;
+		margin: 0px;
+		margin-bottom: 4px;
+	}
+	.subsubtitle {
+		margin: 16px 0px 0px 0px;
+	}
+	.lst {
+		margin: 0px;
+		padding: 0px 14px;
+	}
+	.lst li {
+		font-family: Helvetica;
+		font-size: 12px;
+		margin: 0px;
+		list-style-type: square;
+	}
+	</style>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		//dojo.require("dojo.parser"); // Use the lightweight parser.
+		dojo.require("dojox.mobile.parser");
+		dojo.require("dojox.mobile");
+		dojo.require("dojox.mobile.ScrollableView");
+		dojo.require("dojox.mobile.TabBar");
+		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
+
+        dojo.require("doh.runner");
+
+		dojo.addOnLoad(function(){
+			doh.register("dojox.mobile.test.doh.View", [
+				{
+					name: "test View Verification",
+					timeout: 3000,
+					runTest: function (){
+						var demoWidget = dijit.byId("group1");
+						doh.assertEqual('mblView', demoWidget.domNode.className);
+						doh.assertEqual('visible', demoWidget.domNode.style.visibility);
+
+						demoWidget = dijit.byId("categ");
+						doh.assertEqual('mblView mblScrollableView', demoWidget.domNode.className);
+						doh.assertEqual('none', demoWidget.domNode.style.display);
+					}
+				}
+			]);
+			setTimeout(function(){ // to get the correct dimension
+				doh.run();
+			}, 500);
+		});
+	</script>
+</head>
+<body>
+	<div id="group1" dojoType="dojox.mobile.View" selected="true">
+	aaa
+
+	</div>
+
+	<div id="categ" dojoType="dojox.mobile.ScrollableView">
+		<h1 dojoType="dojox.mobile.Heading" fixed="top">Categories</h1>
+		bbb
+	</div>
+
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/view/View2_Programmatic.html b/dojox/mobile/tests/doh/view/View2_Programmatic.html
new file mode 100644
index 0000000..eee9219
--- /dev/null
+++ b/dojox/mobile/tests/doh/view/View2_Programmatic.html
@@ -0,0 +1,199 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+	<title>View</title>
+	<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	.list1 li{
+		border-style: solid;
+		border-width: 1px 0px 1px 0px;
+		border-top-color: #BABABC;
+		border-bottom-color: #89898C;
+		background-color: #ACACAF;
+		line-height: 0px;
+	}
+	.list1 li table{
+		line-height: normal;
+	}
+	.list1 li:nth-child(even){
+		background-color: #97979B;
+	}
+	#list2 li:nth-child(even){
+		background-color: #eeeeee;
+	}
+	#categ1 {
+		font-size: 18px;
+	}
+	#categ1 li{
+		line-height: 70px;
+	}
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	.content {
+		padding:0px 10px;
+		background-color: white;
+	}
+	p {
+		font-family: Helvetica;
+		font-size: 12px;
+	}
+	.title {
+		color: blue;
+		margin-bottom: 4px;
+	}
+	.subtitle {
+		font-style: italic;
+		color: gray;
+		margin: 0px;
+		margin-bottom: 4px;
+	}
+	.subsubtitle {
+		margin: 16px 0px 0px 0px;
+	}
+	.lst {
+		margin: 0px;
+		padding: 0px 14px;
+	}
+	.lst li {
+		font-family: Helvetica;
+		font-size: 12px;
+		margin: 0px;
+		list-style-type: square;
+	}
+	</style>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		//dojo.require("dojo.parser"); // Use the lightweight parser.
+		dojo.require("dojox.mobile.parser");
+		dojo.require("dojox.mobile");
+		dojo.require("dojox.mobile.ScrollableView");
+		dojo.require("dojox.mobile.TabBar");
+		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
+
+        dojo.require("doh.runner");
+		dojo.addOnLoad(function(){
+
+			doh.register("dojox.mobile.test.doh.View", [
+				{
+					name: "test View Verification",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						setTimeout(d.getTestCallback(function(){
+							demoWidget = dijit.byId("dojox_mobile_ScrollableView_0");
+							demoWidget.set({scrollDir:"hv"});
+							doh.assertEqual('hv', demoWidget.get("scrollDir"));
+							doh.assertEqual('mblView mblScrollableView', demoWidget.domNode.className);
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}));
+						return d;
+					}
+				}
+			]);
+			doh.run();
+		});
+	</script>
+</head>
+<body>
+		<div dojoType="dojox.mobile.ScrollableView" selected="true">
+			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
+			<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;background-color:white;">
+<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>644</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-3.png</td><td>2010/04/13</td><td>06:37</td><td>1,346</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>677</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-10.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>680</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-3.png</td><td>2010/03/23</td><td>13:03</td><td>682</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>697</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-5.png</td><td>2010/03/23</td><td>13:03</td><td>693</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-6.png</td><td>2010/03/23</td><td>13:03</td><td>694</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-7.png</td><td>2010/03/23</td><td>13:03</td><td>691</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-8.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-9.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-all.png</td><td>2010/03/23</td><td>13:03</td><td>4,450</td><td>mobile/tests/images</td></tr>
+<tr><td>icon-1.png</td><td>2010/05/06</td><td>08:57</td><td>2,626</td><td>mobile/tests/images</td></tr>
+<tr><td>not-images.png</td><td>2010/04/13</td><td>06:37</td><td>18,459</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-bg.png</td><td>2010/04/13</td><td>06:37</td><td>178</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-sel-bg.png</td><td>2010/04/13</td><td>06:37</td><td>185</td><td>mobile/tests/images</td></tr>
+<tr><td>test_Android-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,750</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,835</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,615</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,634</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,142</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Settings.html</td><td>2010/10/05</td><td>21:08</td><td>4,375</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>1,000</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,031</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,570</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2-prog.html</td><td>2010/10/03</td><td>22:28</td><td>1,089</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2.html</td><td>2010/10/03</td><td>22:28</td><td>872</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V2H2.html</td><td>2010/10/03</td><td>22:28</td><td>1,088</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V3.html</td><td>2010/10/03</td><td>22:28</td><td>996</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-html.html</td><td>2010/10/05</td><td>21:09</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-json.html</td><td>2010/10/05</td><td>21:08</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_anchor-label.html</td><td>2010/10/05</td><td>21:08</td><td>2,959</td><td>mobile/tests</td></tr>
+<tr><td>test_bookmarkable.html</td><td>2010/10/05</td><td>21:09</td><td>4,443</td><td>mobile/tests</td></tr>
+<tr><td>test_buttons.html</td><td>2010/10/05</td><td>21:08</td><td>972</td><td>mobile/tests</td></tr>
+<tr><td>test_css-sprite.html</td><td>2010/10/05</td><td>21:09</td><td>5,779</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-icons.html</td><td>2010/10/05</td><td>21:08</td><td>2,080</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-items.html</td><td>2010/10/05</td><td>21:08</td><td>3,375</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-view.html</td><td>2010/10/05</td><td>21:09</td><td>1,657</td><td>mobile/tests</td></tr>
+<tr><td>test_hash-parameter.html</td><td>2010/10/05</td><td>21:09</td><td>2,679</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings-fixed.html</td><td>2010/10/03</td><td>22:28</td><td>8,866</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings.html</td><td>2010/10/03</td><td>22:28</td><td>6,904</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Animation.html</td><td>2010/10/05</td><td>21:08</td><td>3,343</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Button.html</td><td>2010/10/05</td><td>21:09</td><td>1,766</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,135</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,809</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,613</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Heading.html</td><td>2010/10/05</td><td>21:08</td><td>1,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,588</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconMulti.html</td><td>2010/10/05</td><td>21:08</td><td>1,863</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingle.html</td><td>2010/10/05</td><td>21:09</td><td>1,814</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingleBelow.html</td><td>2010/10/05</td><td>21:08</td><td>1,815</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ResultList.html</td><td>2010/10/05</td><td>21:08</td><td>2,708</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRect.html</td><td>2010/10/05</td><td>21:08</td><td>1,155</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Settings.html</td><td>2010/10/05</td><td>21:09</td><td>5,666</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>998</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,262</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,550</td><td>mobile/tests</td></tr>
+<tr><td>test_progress-indicator.html</td><td>2010/10/05</td><td>21:08</td><td>3,124</td><td>mobile/tests</td></tr>
+<tr><td>test_transition-to-dynamic-view.html</td><td>2010/10/05</td><td>21:08</td><td>2,525</td><td>mobile/tests</td></tr>
+<tr><td>view-sample.html</td><td>2010/05/06</td><td>20:30</td><td>1,724</td><td>mobile/tests</td></tr>
+<tr><td>view1.html</td><td>2010/05/06</td><td>20:28</td><td>378</td><td>mobile/tests</td></tr>
+<tr><td>view1.json</td><td>2010/05/28</td><td>00:30</td><td>371</td><td>mobile/tests</td></tr>
+<tr><td>view2.html</td><td>2010/05/06</td><td>21:20</td><td>619</td><td>mobile/tests</td></tr>
+<tr><td>view2.json</td><td>2010/05/28</td><td>00:30</td><td>737</td><td>mobile/tests</td></tr>
+<tr><td>view3.html</td><td>2010/10/05</td><td>21:09</td><td>963</td><td>mobile/tests</td></tr>
+<tr><td>view3.json</td><td>2010/10/05</td><td>21:09</td><td>1,054</td><td>mobile/tests</td></tr>
+<tr><td>widget-bg.png</td><td>2010/03/23</td><td>13:03</td><td>26,234</td><td>mobile/tests/images</td></tr>
+			</table>
+			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">View Footer Bar</h1>
+		</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/view/View3_Programmatic.html b/dojox/mobile/tests/doh/view/View3_Programmatic.html
new file mode 100644
index 0000000..8d81005
--- /dev/null
+++ b/dojox/mobile/tests/doh/view/View3_Programmatic.html
@@ -0,0 +1,144 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+	<title>View</title>
+	<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	.list1 li{
+		border-style: solid;
+		border-width: 1px 0px 1px 0px;
+		border-top-color: #BABABC;
+		border-bottom-color: #89898C;
+		background-color: #ACACAF;
+		line-height: 0px;
+	}
+	.list1 li table{
+		line-height: normal;
+	}
+	.list1 li:nth-child(even){
+		background-color: #97979B;
+	}
+	#list2 li:nth-child(even){
+		background-color: #eeeeee;
+	}
+	#categ1 {
+		font-size: 18px;
+	}
+	#categ1 li{
+		line-height: 70px;
+	}
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	.content {
+		padding:0px 10px;
+		background-color: white;
+	}
+	p {
+		font-family: Helvetica;
+		font-size: 12px;
+	}
+	.title {
+		color: blue;
+		margin-bottom: 4px;
+	}
+	.subtitle {
+		font-style: italic;
+		color: gray;
+		margin: 0px;
+		margin-bottom: 4px;
+	}
+	.subsubtitle {
+		margin: 16px 0px 0px 0px;
+	}
+	.lst {
+		margin: 0px;
+		padding: 0px 14px;
+	}
+	.lst li {
+		font-family: Helvetica;
+		font-size: 12px;
+		margin: 0px;
+		list-style-type: square;
+	}
+	</style>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		//dojo.require("dojo.parser"); // Use the lightweight parser.
+		dojo.require("dojox.mobile.parser");
+		dojo.require("dojox.mobile");
+		dojo.require("dojox.mobile.SwapView");
+		dojo.require("dojox.mobile.IconContainer");
+		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
+
+        dojo.require("doh.runner");
+		dojo.addOnLoad(function(){
+
+			var view = new dojox.mobile.SwapView({id:"foo", selected:"true"});
+			dojo.doc.body.appendChild(view.domNode);
+			var demoWidget = new dojox.mobile.RoundRectCategory({label:"Page flipping demo"});
+//			view.addChild(demoWidget);
+			demoWidget.placeAt(view.containerNode);
+
+			demoWidget = new dojox.mobile.RoundRect({innerHTML:"Swipe the screen left or right to flip between the views. There are 4 views in this demo. Vertical scrolling and page indicator are not supported."});
+//			view.addChild(demoWidget);
+			demoWidget.placeAt(view.containerNode);
+			view.startup();
+
+			view = new dojox.mobile.SwapView({id:"bar"});
+			dojo.doc.body.appendChild(view.domNode);
+			view.startup();
+			var list = new dojox.mobile.RoundRectList();
+			demoWidget = new dojox.mobile.ListItem({className:"mblVariableHeight"});
+//			demoWidget.domNode.style = {font-size:"10px"};
+//			view.addChild(list);
+			list.placeAt(view.containerNode);
+			demoWidget.domNode.innerHTML ='1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br> Sarah Connor Hardcover<br> Eligible for FREE Super Saver Shipping<br> <font color="red">$14.50 (50%)</font> In Stock<br> # (531)';
+			list.addChild(demoWidget);
+//			view.startup();
+
+
+			
+			view = new dojox.mobile.SwapView({id:"icon1"});
+			demoWidget = new dojox.mobile.Heading({label:"Icon Container 1"});
+			dojo.doc.body.appendChild(view.domNode);
+//			view.addChild(demoWidget);
+			demoWidget.placeAt(view.containerNode);
+//			container = new dojox.mobile.IconContainer();
+
+
+			view.startup();
+			doh.register("dojox.mobile.test.doh.View", [
+				{
+					name: "test View Verification",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						setTimeout(d.getTestCallback(function(){
+							demoWidget = dijit.byId("foo");
+							doh.assertEqual('f', demoWidget.get("scrollDir"));
+							doh.assertEqual('mblView mblSwapView', demoWidget.domNode.className);
+							doh.assertEqual('', demoWidget.domNode.style.display);
+						}));
+						return d;
+					}
+				}
+			]);
+			doh.run();
+		});
+	</script>
+</head>
+<body>
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/view/View_Programmatic.html b/dojox/mobile/tests/doh/view/View_Programmatic.html
new file mode 100644
index 0000000..06b3ce0
--- /dev/null
+++ b/dojox/mobile/tests/doh/view/View_Programmatic.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+	<title>View</title>
+	<link href="../../../themes/iphone/iphone.css" rel="stylesheet"/>
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	.list1 li{
+		border-style: solid;
+		border-width: 1px 0px 1px 0px;
+		border-top-color: #BABABC;
+		border-bottom-color: #89898C;
+		background-color: #ACACAF;
+		line-height: 0px;
+	}
+	.list1 li table{
+		line-height: normal;
+	}
+	.list1 li:nth-child(even){
+		background-color: #97979B;
+	}
+	#list2 li:nth-child(even){
+		background-color: #eeeeee;
+	}
+	#categ1 {
+		font-size: 18px;
+	}
+	#categ1 li{
+		line-height: 70px;
+	}
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	.content {
+		padding:0px 10px;
+		background-color: white;
+	}
+	p {
+		font-family: Helvetica;
+		font-size: 12px;
+	}
+	.title {
+		color: blue;
+		margin-bottom: 4px;
+	}
+	.subtitle {
+		font-style: italic;
+		color: gray;
+		margin: 0px;
+		margin-bottom: 4px;
+	}
+	.subsubtitle {
+		margin: 16px 0px 0px 0px;
+	}
+	.lst {
+		margin: 0px;
+		padding: 0px 14px;
+	}
+	.lst li {
+		font-family: Helvetica;
+		font-size: 12px;
+		margin: 0px;
+		list-style-type: square;
+	}
+	</style>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		//dojo.require("dojo.parser"); // Use the lightweight parser.
+		dojo.require("dojox.mobile.parser");
+		dojo.require("dojox.mobile");
+		dojo.require("dojox.mobile.ScrollableView");
+		dojo.require("dojox.mobile.TabBar");
+		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
+
+        dojo.require("doh.runner");
+		dojo.addOnLoad(function(){
+			var view = new dojox.mobile.View({id:"group1", selected:"true", innerHTML:"aaa"});
+			dojo.doc.body.appendChild(view.domNode);
+			var roundRectList = new dojox.mobile.RoundRectList();
+//			view.addChild(roundRectList);
+			roundRectList.placeAt(view.containerNode);
+			roundRectList.startup();
+			var demoWidget = new dojox.mobile.ListItem({moveTo:"dojox_mobile_ScrollableView_0"});
+			roundRectList.addChild(demoWidget);
+			view.startup();
+			
+			view = new dojox.mobile.ScrollableView();
+			demoWidget = new dojox.mobile.Heading({fixed:"top", label:"Categories", back:"Back To", moveTo:"group1"});
+			dojo.doc.body.appendChild(view.domNode);
+//			view.addChild(demoWidget);
+			demoWidget.placeAt(view.containerNode);
+			demoWidget.startup();
+			view.domNode.appendChild(dojo.doc.createTextNode("bbbb"));
+			roundRectList = new dojox.mobile.EdgeToEdgeList();
+//			view.addChild(roundRectList);
+			demoWidget.placeAt(view.containerNode);
+			demoWidget.startup();
+			for(var i = 0;i<20;i++){
+				demoWidget = new dojox.mobile.ListItem({label:"Test" + i});
+				roundRectList.addChild(demoWidget)
+			}
+
+			view.startup();
+			doh.register("dojox.mobile.test.doh.View", [
+				{
+					name: "test View Verification",
+					timeout: 4000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						var t = 500;
+						if(dojo.isIE){
+							t = 2000;
+						}
+						setTimeout(d.getTestCallback(function(){
+							var demoWidget = dijit.byId("group1");
+							doh.assertEqual('mblView', demoWidget.domNode.className);
+							doh.assertEqual('visible', demoWidget.domNode.style.visibility);
+
+							demoWidget = dijit.byId("dojox_mobile_ScrollableView_0");
+							doh.assertEqual('mblView mblScrollableView', demoWidget.domNode.className);
+							doh.assertEqual('none', demoWidget.domNode.style.display);
+						}),t);
+						return d;
+					}
+				}
+			]);
+			doh.run();
+		});
+	</script>
+</head>
+<body>
+
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/doh/view/module.js b/dojox/mobile/tests/doh/view/module.js
new file mode 100644
index 0000000..ae8899a
--- /dev/null
+++ b/dojox/mobile/tests/doh/view/module.js
@@ -0,0 +1,11 @@
+define(["doh/main", "require", "dojo/sniff"], function(doh, require, has){
+
+	doh.registerUrl("dojox.mobile.tests.doh.View", require.toUrl("./View.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.View", require.toUrl("./View_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.View", require.toUrl("./View2_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.View", require.toUrl("./View3_Programmatic.html"),999999);
+	doh.registerUrl("dojox.mobile.tests.doh.View", require.toUrl("./View-demo.html"),999999);
+});
+
+
+
diff --git a/dojox/mobile/tests/doh/view/runTests.html b/dojox/mobile/tests/doh/view/runTests.html
new file mode 100644
index 0000000..9bf2c7e
--- /dev/null
+++ b/dojox/mobile/tests/doh/view/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>dojox.mobile Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mobile.tests.doh.view.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-image-view-assistant.js b/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-image-view-assistant.js
index 23ec791..6468d0b 100644
--- a/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-image-view-assistant.js
+++ b/dojox/mobile/tests/imageControlsApp/app/assistants/flickr-image-view-assistant.js
@@ -107,11 +107,11 @@ dojo.declare("FlickrImageViewAssistant", dojox.mobile.app.SceneAssistant, {
 					"flickr.groups.pools.getPhotos";
 					
 //		"http://api.flickr.com/services/rest/?method=flickr.groups.pools.getPhotos"
-//      + "&api_key=" + lib.API_KEY
-//      + "&group_id=" + group.id
-//      + "&extras=owner_name"
-//      + "&per_page=" + (perPage || 10)
-//      + "&format=json&nojsoncallback=1"
+//		+ "&api_key=" + lib.API_KEY
+//		+ "&group_id=" + group.id
+//		+ "&extras=owner_name"
+//		+ "&per_page=" + (perPage || 10)
+//		+ "&format=json&nojsoncallback=1"
 
 		var deferred = dojo.io.script.get({
 			url: url,
diff --git a/dojox/mobile/tests/imageControlsApp/index.html b/dojox/mobile/tests/imageControlsApp/index.html
index b4c8e04..6da5024 100644
--- a/dojox/mobile/tests/imageControlsApp/index.html
+++ b/dojox/mobile/tests/imageControlsApp/index.html
@@ -13,7 +13,7 @@
 		}
 		</style>
 		<script type="text/javascript" src="../../../../dojo/dojo.js" 
-				djConfig="parseOnLoad: false, mobileAnim:'slide'"></script>
+				data-dojo-config="parseOnLoad: false, mobileAnim:'slide'"></script>
     
 		<script language="JavaScript" type="text/javascript">
 			dojo.require("dojo.io.script");
diff --git a/dojox/mobile/tests/images/LTR.png b/dojox/mobile/tests/images/LTR.png
new file mode 100644
index 0000000..657b04c
Binary files /dev/null and b/dojox/mobile/tests/images/LTR.png differ
diff --git a/dojox/mobile/tests/images/Mountain.jpg b/dojox/mobile/tests/images/Mountain.jpg
new file mode 100644
index 0000000..0e9b2f9
Binary files /dev/null and b/dojox/mobile/tests/images/Mountain.jpg differ
diff --git a/dojox/mobile/tests/images/RTL.png b/dojox/mobile/tests/images/RTL.png
new file mode 100644
index 0000000..9a77f61
Binary files /dev/null and b/dojox/mobile/tests/images/RTL.png differ
diff --git a/dojox/mobile/tests/images/auto.png b/dojox/mobile/tests/images/auto.png
new file mode 100644
index 0000000..d5149ab
Binary files /dev/null and b/dojox/mobile/tests/images/auto.png differ
diff --git a/dojox/mobile/tests/images/chart.png b/dojox/mobile/tests/images/chart.png
index 3887ba8..ca08f83 100644
Binary files a/dojox/mobile/tests/images/chart.png and b/dojox/mobile/tests/images/chart.png differ
diff --git a/dojox/mobile/tests/images/contacts16.png b/dojox/mobile/tests/images/contacts16.png
new file mode 100644
index 0000000..e1ca4ba
Binary files /dev/null and b/dojox/mobile/tests/images/contacts16.png differ
diff --git a/dojox/mobile/tests/images/dojo-logo1.png b/dojox/mobile/tests/images/dojo-logo1.png
new file mode 100644
index 0000000..e374ade
Binary files /dev/null and b/dojox/mobile/tests/images/dojo-logo1.png differ
diff --git a/dojox/mobile/tests/images/icons16.png b/dojox/mobile/tests/images/icons16.png
new file mode 100644
index 0000000..47c727d
Binary files /dev/null and b/dojox/mobile/tests/images/icons16.png differ
diff --git a/dojox/mobile/tests/images/menu1.jpg b/dojox/mobile/tests/images/menu1.jpg
new file mode 100644
index 0000000..bce036a
Binary files /dev/null and b/dojox/mobile/tests/images/menu1.jpg differ
diff --git a/dojox/mobile/tests/images/menu2.jpg b/dojox/mobile/tests/images/menu2.jpg
new file mode 100644
index 0000000..18a22ca
Binary files /dev/null and b/dojox/mobile/tests/images/menu2.jpg differ
diff --git a/dojox/mobile/tests/images/menu3.jpg b/dojox/mobile/tests/images/menu3.jpg
new file mode 100644
index 0000000..4057300
Binary files /dev/null and b/dojox/mobile/tests/images/menu3.jpg differ
diff --git a/dojox/mobile/tests/images/menu4.jpg b/dojox/mobile/tests/images/menu4.jpg
new file mode 100644
index 0000000..88fc4b0
Binary files /dev/null and b/dojox/mobile/tests/images/menu4.jpg differ
diff --git a/dojox/mobile/tests/images/menu5.jpg b/dojox/mobile/tests/images/menu5.jpg
new file mode 100644
index 0000000..94c301e
Binary files /dev/null and b/dojox/mobile/tests/images/menu5.jpg differ
diff --git a/dojox/mobile/tests/images/menu6.jpg b/dojox/mobile/tests/images/menu6.jpg
new file mode 100644
index 0000000..c3ac026
Binary files /dev/null and b/dojox/mobile/tests/images/menu6.jpg differ
diff --git a/dojox/mobile/tests/images/pic1.jpg b/dojox/mobile/tests/images/pic1.jpg
index a8ef25f..6086759 100644
Binary files a/dojox/mobile/tests/images/pic1.jpg and b/dojox/mobile/tests/images/pic1.jpg differ
diff --git a/dojox/mobile/tests/images/pic10.jpg b/dojox/mobile/tests/images/pic10.jpg
index eed3321..82d438c 100644
Binary files a/dojox/mobile/tests/images/pic10.jpg and b/dojox/mobile/tests/images/pic10.jpg differ
diff --git a/dojox/mobile/tests/images/pic2.jpg b/dojox/mobile/tests/images/pic2.jpg
index 5998cec..edcddcc 100644
Binary files a/dojox/mobile/tests/images/pic2.jpg and b/dojox/mobile/tests/images/pic2.jpg differ
diff --git a/dojox/mobile/tests/images/pic3.jpg b/dojox/mobile/tests/images/pic3.jpg
index 10c593b..43bf051 100644
Binary files a/dojox/mobile/tests/images/pic3.jpg and b/dojox/mobile/tests/images/pic3.jpg differ
diff --git a/dojox/mobile/tests/images/pic4.jpg b/dojox/mobile/tests/images/pic4.jpg
index 7abbaa9..25ec11e 100644
Binary files a/dojox/mobile/tests/images/pic4.jpg and b/dojox/mobile/tests/images/pic4.jpg differ
diff --git a/dojox/mobile/tests/images/pic5.jpg b/dojox/mobile/tests/images/pic5.jpg
index 7c02ed7..155013b 100644
Binary files a/dojox/mobile/tests/images/pic5.jpg and b/dojox/mobile/tests/images/pic5.jpg differ
diff --git a/dojox/mobile/tests/images/pic6.jpg b/dojox/mobile/tests/images/pic6.jpg
index a3045f2..33e123a 100644
Binary files a/dojox/mobile/tests/images/pic6.jpg and b/dojox/mobile/tests/images/pic6.jpg differ
diff --git a/dojox/mobile/tests/images/pic7.jpg b/dojox/mobile/tests/images/pic7.jpg
index c182569..5327189 100644
Binary files a/dojox/mobile/tests/images/pic7.jpg and b/dojox/mobile/tests/images/pic7.jpg differ
diff --git a/dojox/mobile/tests/images/pic8.jpg b/dojox/mobile/tests/images/pic8.jpg
index d83c21d..91ca019 100644
Binary files a/dojox/mobile/tests/images/pic8.jpg and b/dojox/mobile/tests/images/pic8.jpg differ
diff --git a/dojox/mobile/tests/images/pic9.jpg b/dojox/mobile/tests/images/pic9.jpg
index 663ae58..0195f44 100644
Binary files a/dojox/mobile/tests/images/pic9.jpg and b/dojox/mobile/tests/images/pic9.jpg differ
diff --git a/dojox/mobile/tests/progressBarAnim.gif b/dojox/mobile/tests/images/progressBarAnim.gif
similarity index 100%
rename from dojox/mobile/tests/progressBarAnim.gif
rename to dojox/mobile/tests/images/progressBarAnim.gif
diff --git a/dojox/mobile/tests/images/pull-arrow.png b/dojox/mobile/tests/images/pull-arrow.png
new file mode 100644
index 0000000..d916bb9
Binary files /dev/null and b/dojox/mobile/tests/images/pull-arrow.png differ
diff --git a/dojox/mobile/tests/images/release-arrow.png b/dojox/mobile/tests/images/release-arrow.png
new file mode 100644
index 0000000..0875f72
Binary files /dev/null and b/dojox/mobile/tests/images/release-arrow.png differ
diff --git a/dojox/mobile/tests/sliderHthumb.png b/dojox/mobile/tests/images/sliderHthumb.png
similarity index 100%
rename from dojox/mobile/tests/sliderHthumb.png
rename to dojox/mobile/tests/images/sliderHthumb.png
diff --git a/dojox/mobile/tests/sliderVthumb.png b/dojox/mobile/tests/images/sliderVthumb.png
similarity index 100%
rename from dojox/mobile/tests/sliderVthumb.png
rename to dojox/mobile/tests/images/sliderVthumb.png
diff --git a/dojox/mobile/tests/images/star-2.png b/dojox/mobile/tests/images/star-2.png
new file mode 100644
index 0000000..f98041b
Binary files /dev/null and b/dojox/mobile/tests/images/star-2.png differ
diff --git a/dojox/mobile/tests/images/star-3.png b/dojox/mobile/tests/images/star-3.png
new file mode 100644
index 0000000..6eab8be
Binary files /dev/null and b/dojox/mobile/tests/images/star-3.png differ
diff --git a/dojox/mobile/tests/images/star-4.png b/dojox/mobile/tests/images/star-4.png
new file mode 100644
index 0000000..74825e4
Binary files /dev/null and b/dojox/mobile/tests/images/star-4.png differ
diff --git a/dojox/mobile/tests/images/star-5.png b/dojox/mobile/tests/images/star-5.png
new file mode 100644
index 0000000..dbd6c06
Binary files /dev/null and b/dojox/mobile/tests/images/star-5.png differ
diff --git a/dojox/mobile/tests/images/star-6.png b/dojox/mobile/tests/images/star-6.png
new file mode 100644
index 0000000..18ade22
Binary files /dev/null and b/dojox/mobile/tests/images/star-6.png differ
diff --git a/dojox/mobile/tests/images/star-blue.png b/dojox/mobile/tests/images/star-blue.png
new file mode 100644
index 0000000..4954c08
Binary files /dev/null and b/dojox/mobile/tests/images/star-blue.png differ
diff --git a/dojox/mobile/tests/images/star-green.png b/dojox/mobile/tests/images/star-green.png
new file mode 100644
index 0000000..fad1e8f
Binary files /dev/null and b/dojox/mobile/tests/images/star-green.png differ
diff --git a/dojox/mobile/tests/images/star-orange.png b/dojox/mobile/tests/images/star-orange.png
new file mode 100644
index 0000000..9fbf601
Binary files /dev/null and b/dojox/mobile/tests/images/star-orange.png differ
diff --git a/dojox/mobile/tests/images/star-yellow.png b/dojox/mobile/tests/images/star-yellow.png
new file mode 100644
index 0000000..e074f47
Binary files /dev/null and b/dojox/mobile/tests/images/star-yellow.png differ
diff --git a/dojox/mobile/tests/index.html b/dojox/mobile/tests/index.html
index aa18e7a..0ad0be3 100644
--- a/dojox/mobile/tests/index.html
+++ b/dojox/mobile/tests/index.html
@@ -1,187 +1,158 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<title>dojox.mobile</title>
-	</head>
-	<body>
-		<a href="test_iPhone-Animation.html">test_iPhone-Animation.html</a><br>
-		<a href="test_iPhone-Button.html">test_iPhone-Button.html</a><br>
-		<a href="test_iPhone-ButtonList.html">test_iPhone-ButtonList.html</a><br>
-		<a href="test_iPhone-EdgeToEdge.html">test_iPhone-EdgeToEdge.html</a><br>
-		<a href="test_iPhone-EdgeToEdgeCategory.html">test_iPhone-EdgeToEdgeCategory.html</a><br>
-		<a href="test_iPhone-Heading.html">test_iPhone-Heading.html</a><br>
-		<a href="test_iPhone-Icon.html">test_iPhone-Icon.html</a><br>
-		<a href="test_iPhone-IconMulti.html">test_iPhone-IconMulti.html</a><br>
-		<a href="test_iPhone-IconSingle.html">test_iPhone-IconSingle.html</a><br>
-		<a href="test_iPhone-IconSingleBelow.html">test_iPhone-IconSingleBelow.html</a><br>
-		<a href="test_iPhone-Icon-sprite.html">test_iPhone-Icon-sprite.html</a><br>
-		<a href="test_iPhone-ResultList.html">test_iPhone-ResultList.html</a><br>
-		<a href="test_iPhone-RoundRect.html">test_iPhone-RoundRect.html</a><br>
-		<a href="test_iPhone-RoundRectList.html">test_iPhone-RoundRectList.html</a><br>
-		<a href="test_iPhone-Settings.html">test_iPhone-Settings.html</a><br>
-		<a href="test_iPhone-Switch.html">test_iPhone-Switch.html</a><br>
-		<a href="test_iPhone-TabBar.html">test_iPhone-TabBar.html</a><br>
-		<a href="test_iPhone-TabBar-seg.html">test_iPhone-TabBar-seg.html</a><br>
-		<a href="test_iPhone-TabBar-seg-grouped.html">test_iPhone-TabBar-seg-grouped.html</a><br>
-		<a href="test_iPhone-TabBar-seg-grouped-scroll.html">test_iPhone-TabBar-seg-grouped-scroll.html</a><br>
-		<a href="test_iPhone-VariableHeightList.html">test_iPhone-VariableHeightList.html</a><br>
-		<a href="test_Switch-setter.html?theme=iPhone">test_Switch-setter.html</a><br>
-		<a href="test_FormControls.html?theme=iPhone">test_FormControls.html</a><br>
-		<a href="test_RoundRectList-check.html?theme=iPhone">test_RoundRectList-check.html</a><br>
-		<a href="test_EdgeToEdgeList-check.html?theme=iPhone">test_EdgeToEdgeList-check.html</a><br>
-		<a href="test_list-domButtons.html?theme=iPhone">test_list-domButtons.html</a><br>
-		<hr>
-		<a href="test_Android-ButtonList.html">test_Android-ButtonList.html</a><br>
-		<a href="test_Android-EdgeToEdge.html">test_Android-EdgeToEdge.html</a><br>
-		<a href="test_Android-EdgeToEdgeCategory.html">test_Android-EdgeToEdgeCategory.html</a><br>
-		<a href="test_Android-Heading.html">test_Android-Heading.html</a><br>
-		<a href="test_Android-Icon.html">test_Android-Icon.html</a><br>
-		<a href="test_Android-RoundRectList.html">test_Android-RoundRectList.html</a><br>
-		<a href="test_Android-Settings.html">test_Android-Settings.html</a><br>
-		<a href="test_Android-Switch.html">test_Android-Switch.html</a><br>
-		<a href="test_Android-TabBar.html">test_Android-TabBar.html</a><br>
-		<a href="test_Android-VariableHeightList.html">test_Android-VariableHeightList.html</a><br>
-		<a href="test_Switch-setter.html?theme=Android">test_Switch-setter.html</a><br>
-		<a href="test_FormControls.html?theme=Android">test_FormControls.html</a><br>
-		<a href="test_RoundRectList-check.html?theme=Android">test_RoundRectList-check.html</a><br>
-		<a href="test_EdgeToEdgeList-check.html?theme=Android">test_EdgeToEdgeList-check.html</a><br>
-		<a href="test_list-domButtons.html?theme=Android">test_list-domButtons.html</a><br>
-		<hr>
-		<a href="test_BlackBerry-EdgeToEdgeList.html">test_BlackBerry-EdgeToEdgeList.html</a><br>
-		<a href="test_BlackBerry-SwapView.html">test_BlackBerry-SwapView.html</a><br>
-		<a href="test_BlackBerry-Heading.html">test_BlackBerry-Heading.html</a><br>
-		<a href="test_BlackBerry-IconContainer.html">test_BlackBerry-IconContainer.html</a><br>
-		<a href="test_BlackBerry-RoundRectList.html">test_BlackBerry-RoundRectList.html</a><br>
-		<a href="test_BlackBerry-ScrollableView.html">test_BlackBerry-ScrollableView.html</a><br>
-		<a href="test_BlackBerry-Settings.html">test_BlackBerry-Settings.html</a><br>
-		<a href="test_BlackBerry-Switch.html">test_BlackBerry-Switch.html</a><br>
-		<a href="test_BlackBerry-TabBar.html">test_BlackBerry-TabBar.html</a><br>
-		<a href="test_BlackBerry-VariableHeightList.html">test_BlackBerry-VariableHeightList.html</a><br>
-		<a href="test_Switch-setter.html?theme=BlackBerry">test_Switch-setter.html</a><br>
-		<a href="test_FormControls.html?theme=BlackBerry">test_FormControls.html</a><br>
-		<a href="test_RoundRectList-check.html?theme=BlackBerry">test_RoundRectList-check.html</a><br>
-		<a href="test_EdgeToEdgeList-check.html?theme=BlackBerry">test_EdgeToEdgeList-check.html</a><br>
-		<a href="test_list-domButtons.html?theme=BlackBerry">test_list-domButtons.html</a><br>
-		<hr>
-		<a href="test_Custom-Settings.html">test_Custom-Settings.html</a><br>
-		<a href="test_Custom-Heading.html">test_Custom-Heading.html</a><br>
-		<a href="test_Custom-EdgeToEdgeList.html">test_Custom-EdgeToEdgeList.html</a><br>
-		<a href="test_Custom-RoundRectList.html">test_Custom-RoundRectList.html</a><br>
-		<a href="test_Custom-list-domButtons.html">test_Custom-list-domButtons.html</a><br>
-		<a href="test_Custom-css-sprite.html">test_Custom-css-sprite.html</a><br>
-		<a href="test_Custom-Icon.html">test_Custom-Icon.html</a><br>
-		<a href="test_Custom-FormControls.html">test_Custom-FormControls.html</a><br>
-		<a href="test_Custom-TabBar.html">test_Custom-TabBar.html</a><br>
-		<a href="test_Custom-Tooltip.html">test_Custom-Tooltip.html</a><br>
-		<a href="test_Custom-Opener.html">test_Custom-Opener.html</a> <br>
-		<hr><br>
-		<a href="test_iPhone-ScrollableView-demo.html">test_iPhone-ScrollableView-demo.html</a><br>
-		<a href="test_iPhone-ScrollableView-demo-long.html">test_iPhone-ScrollableView-demo-long.html</a><br>
-		<a href="test_iPhone-ScrollableView-v.html">test_iPhone-ScrollableView-v.html</a><br>
-		<a href="test_iPhone-ScrollableView-v-vh.html">test_iPhone-ScrollableView-v-vh.html</a><br>
-		<a href="test_iPhone-ScrollableView-v-vh-vf.html">test_iPhone-ScrollableView-v-vh-vf.html</a><br>
-		<a href="test_iPhone-ScrollableView-short.html">test_iPhone-ScrollableView-short.html</a><br>
-		<a href="test_iPhone-ScrollableView-v-vh-af.html">test_iPhone-ScrollableView-v-vh-af.html</a><br>
-		<a href="test_iPhone-ScrollableView-v-ah-af.html">test_iPhone-ScrollableView-v-ah-af.html</a><br>
-		<a href="test_iPhone-ScrollableView-h.html">test_iPhone-ScrollableView-h.html</a><br>
-		<a href="test_iPhone-ScrollableView-hv.html">test_iPhone-ScrollableView-hv.html</a><br>
-		<a href="test_iPhone-ScrollableView-hv-vh-vf.html">test_iPhone-ScrollableView-hv-vh-vf.html</a><br>
-		<a href="test_iPhone-ScrollableView-hv-ah-af.html">test_iPhone-ScrollableView-hv-ah-af.html</a><br>
-		<a href="test_iPhone-SwapView.html">test_iPhone-SwapView.html</a><br>
-		<a href="test_iPhone-SwapView-slideshow.html">test_iPhone-SwapView-slideshow.html</a><br>
-		<a href="test_iPhone-SwapView-demo.html">test_iPhone-SwapView-demo.html</a><br>
-		<a href="test_Carousel.html">test_Carousel.html</a><br>
-		<a href="test_Carousel-slideshow.html">test_Carousel-slideshow.html</a><br>
-		<hr>
-		<a href="test_ScrollableMixin-custom.html">test_ScrollableMixin-custom.html</a><br>
-		<a href="test_scrollable-no-dojo.html">test_scrollable-no-dojo.html</a><br>
-		<a href="test_scrollable-no-dojo-ah.html">test_scrollable-no-dojo-ah.html</a><br>
-		<a href="test_scrollable-no-dojo-af.html">test_scrollable-no-dojo-af.html</a><br>
-		<a href="test_scrollable-no-dojo-ah-af.html">test_scrollable-no-dojo-ah-af.html</a><br>
-		<hr>
-		<a href="test_iPad-Settings.html">test_iPad-Settings.html</a><br>
-		<a href="test_iPad-Heading.html">test_iPad-Heading.html</a><br>
-		<a href="test_iPad-TabBar.html">test_iPad-TabBar.html</a><br>
-		<a href="test_screen-size-aware.html">test_screen-size-aware.html</a><br>
-		<a href="test_screen-size-aware-demo.html">test_screen-size-aware-demo.html</a><br>
-		<hr>
-		<a href="test_domButtons.html">test_domButtons.html</a><br>
-		<a href="test_bookmarkable.html">test_bookmarkable.html</a><br>
-		<a href="test_hash-parameter.html">test_hash-parameter.html</a><br>
-		<a href="test_progress-indicator.html">test_progress-indicator.html</a><br>
-		<a href="test_dynamic-items.html">test_dynamic-items.html</a><br>
-		<a href="test_dynamic-icons.html">test_dynamic-icons.html</a><br>
-		<a href="test_dynamic-view.html">test_dynamic-view.html</a><br>
-		<a href="test_dynamic-ScrollableView-ah-af.html">test_dynamic-ScrollableView-ah-af.html</a><br>
-		<a href="test_dynamic-ScrollableView-vh-vf.html">test_dynamic-ScrollableView-vh-vf.html</a><br>
-		<a href="test_ajax-html.html">test_ajax-html.html</a><br>
-		<a href="test_ajax-json.html">test_ajax-json.html</a><br>
-		<a href="test_anchor-label.html">test_anchor-label.html</a><br>
-		<a href="test_css-sprite.html">test_css-sprite.html</a><br>
-		<a href="test_transition-to-dynamic-view.html">test_transition-to-dynamic-view.html</a><br>
-		<a href="test_grouped-views.html">test_grouped-views.html</a><br>
-		<a href="test_grouped-scrollable-views.html">test_grouped-scrollable-views.html</a><br>
-		<a href="test_orientation-transition.html">test_orientation-transition.html</a><br>
-		<a href="test_transition-animations.html">test_transition-animations.html</a><br>
-		<a href="test_transition-animations2.html">test_transition-animations2.html</a><br>
-		<a href="test_list-actions.html">test_list-actions.html</a><br>
-		<a href="test_i18n.html">test_i18n.html</a><br>
-		<a href="test_html-form-controls.html">test_html-form-controls.html</a><br>
-		<hr>
-		<a href="test_transition-connect.html">test_transition-connect.html</a><br>
-		<a href="test_transition-pubsub.html">test_transition-pubsub.html</a><br>
-		<hr>
-		<a href="test_FixedSplitter-H2.html">test_FixedSplitter-H2.html</a><br>
-		<a href="test_FixedSplitter-H2-prog.html">test_FixedSplitter-H2-prog.html</a><br>
-		<a href="test_FixedSplitter-V3.html">test_FixedSplitter-V3.html</a><br>
-		<a href="test_FixedSplitter-V2H2.html">test_FixedSplitter-V2H2.html</a><br>
-		<hr>
-		<a href="test_SpinWheelDatePicker.html">test_SpinWheelDatePicker.html</a><br>
-		<a href="test_SpinWheelTimePicker.html">test_SpinWheelTimePicker.html</a><br>
-		<a href="test_SpinWheel-icons.html">test_SpinWheel-icons.html</a><br>
-		<a href="test_SpinWheel-custom.html">test_SpinWheel-custom.html</a><br>
-		<a href="test_SpinWheelDatePicker-sv.html">test_SpinWheelDatePicker-sv.html</a><br>
-		<a href="test_SpinWheel-1slot.html">test_SpinWheel-1slot.html</a><br>
-		<hr>
-		<a href="test_RoundRectDataList.html">test_RoundRectDataList.html</a><br>
-		<a href="test_EdgeToEdgeDataList.html">test_EdgeToEdgeDataList.html</a><br>
-		<hr>
-		<a href="test_Tooltip.html">test_Tooltip.html</a><br>
-		<a href="test_Overlay.html">test_Overlay.html</a><br>
-		<a href="test_Opener-Calendar-async.html">test_Opener-Calendar-async.html</a><br>
-		<a href="test_Opener-ColorPalette-async.html">test_Opener-ColorPalette-async.html</a><br>
-		<a href="test_Opener-ColorPicker.html">test_Opener-ColorPicker.html</a><br>
-		<a href="test_Opener-DateSpinWheel-async.html">test_Opener-DateSpinWheel-async.html</a><br>
-		<a href="test_Opener-RoundSelectList-async.html">test_Opener-RoundSelectList-async.html</a><br>
-		<a href="test_Opener-SearchList-async.html">test_Opener-SearchList-async.html</a><br>
-		<a href="test_Opener-ActionSheet-async.html">test_Opener-ActionSheet-async.html</a><br>
-		(Example ColorPalette, ColorPicker, Calendar, DatePickers which open differently on phone vs. tablet/desktop)<br>
-		<hr>
-		<a href="test_Accessibility_Support.html">test_Accessibility_Support.html</a><br>
-		<hr>
-		<a href="test_iPhone-Animation-async.html">test_iPhone-Animation-async.html</a><br>
-		<a href="test_iPhone-ScrollableView-demo-async.html">test_iPhone-ScrollableView-demo-async.html</a><br>
-		<a href="test_iPhone-SwapView-demo-async.html">test_iPhone-SwapView-demo-async.html</a><br>
-		<a href="test_iPhone-SwapView-slideshow-async.html">test_iPhone-SwapView-slideshow-async.html</a><br>
-		<a href="test_iPad-Settings-async.html">test_iPad-Settings-async.html</a><br>
-		<a href="test_Carousel-async.html">test_Carousel-async.html</a><br>
-		<a href="test_screen-size-aware-async.html">test_screen-size-aware-async.html</a><br>
-		<hr>
-		<a href="test_iPhone-ScrollableView-v-inp.html">test_iPhone-ScrollableView-v-inp.html</a><br>
-		<a href="test_iPhone-ScrollableView-v-vh-inp.html">test_iPhone-ScrollableView-v-vh-inp.html</a><br>
-		<a href="test_iPhone-ScrollableView-v-vh-vf-inp.html">test_iPhone-ScrollableView-v-vh-vf-inp.html</a><br>
-		<a href="test_iPhone-ScrollableView-short-inp.html">test_iPhone-ScrollableView-short.html</a><br>
-		<a href="test_iPhone-ScrollableView-v-vh-af-inp.html">test_iPhone-ScrollableView-v-vh-af-inp.html</a><br>
-		<a href="test_iPhone-ScrollableView-v-ah-af-inp.html">test_iPhone-ScrollableView-v-ah-af-inp.html</a><br>
-		<a href="test_html-inputs.html">test_html-inputs.html</a><br>
-		<hr>
-		<a href="simpleApp">Simple Full App</a><br>
-		<a href="simpleListApp">Simple Full App Using a List</a><br>
-		<a href="multiSceneApp">Multi-Scene Full App</a><br>
-		<a href="complexListApp">Full App Using a Complex List</a><br>
-		<a href="dialogApp">Full App with Dialogs</a><br>
-		<a href="inputApp">Full App with Form Inputs</a><br>
-		<a href="imageControlsApp">Full App with Image Widgets</a><br>
-	</body>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<title>dojox.mobile</title>
+	<style>
+	body {
+		font-family: Helvetica;
+		font-size: 17px;
+	}
+	.section {
+		font-weight: bold;
+		color: #008080;
+	}
+	.titleBar {
+		padding: 10px 0;
+	}
+	.contents {
+		margin-left: 30px;
+		font-weight: normal;
+		color: #000000;
+	}
+	.item {
+		position: relative;
+		border-bottom: 1px solid gray;
+	}
+	.anchor {
+		display: block;
+		padding: 10px 0;
+		text-decoration: none;
+	}
+	</style>
+	<script src="index.js"></script>
+	<script>
+		function setRightIcon(icon){
+			icon.src = "../themes/common/domButtons/compat/mblDomButtonBlackRightArrow16.png";
+		}
+		function setDownIcon(icon){
+			icon.src = "../themes/common/domButtons/compat/mblDomButtonBlackDownArrow16.png";
+		}
+		function isRightIcon(icon){
+			return (icon.src && icon.src.indexOf("Right") !== -1);
+		}
+
+		function sort(keys){
+			var data = [];
+			for(var i = 0; i < keys.length; i++){
+				var key = keys[i];
+				var items = [];
+				items.label = key.label;
+				for(var j = 0; j < tests.length; j++){
+					var item = tests[j];
+					var url = item.url;
+					var label = item.label || item.url;
+					var tags = item.tags ? item.tags.split(/,/) : [];
+					for(var k = 0; k < tags.length; k++){
+						if(tags[k] === key.tag){
+							items.push(item);
+						}
+					}
+				}
+				data.push(items);
+			}
+			return data;
+		}
+		function init(){
+			var theme = document.getElementById("sel1").value;
+			var container = document.getElementById("container");
+			container.innerHTML = "";
+			var data = sort(categories);
+			for(var i = 0; i < data.length; i++){
+				var items = data[i];
+				if(items.length == 0){ continue; }
+
+				var section = document.createElement("div");
+				section.className = "section";
+				container.appendChild(section);
+
+				var titleBar = document.createElement("div");
+				titleBar.className = "titleBar";
+				titleBar.onclick = toggleSection;
+				section.appendChild(titleBar);
+
+				var icon = document.createElement("img");
+				icon.className = "icon";
+				setRightIcon(icon);
+				titleBar.appendChild(icon);
+
+				var title = document.createElement("label");
+				title.className = "title";
+				title.innerHTML = items.label + " (" + items.length + ")";
+				titleBar.appendChild(title);
+
+				var contents = document.createElement("div");
+				contents.className = "contents";
+				contents.style.display = "none";
+				section.appendChild(contents);
+
+				for(var j = 0; j < items.length; j++){
+					var item = items[j];
+					var url = item.url;
+					var label = item.label || item.url;
+
+					var item = document.createElement("div");
+					item.className = "item";
+					contents.appendChild(item);
+
+					var anchor = document.createElement("a");
+					anchor.className = "anchor";
+					anchor.href = url + (theme ? "?theme=" + theme : "");
+					anchor.target = "_blank";
+					anchor.innerHTML = label;
+					item.appendChild(anchor);
+				}
+			}
+		}
+
+		function toggleSection(e) {
+			e = e || event;
+			var node = e.srcElement ? e.srcElement : e.target;
+			var titleBar = (node.className == "titleBar") ? node : node.parentNode;
+			var img = titleBar.childNodes[0];
+			var label = titleBar.childNodes[1];
+			var contents = titleBar.nextSibling;
+			if (isRightIcon(img)){
+				setDownIcon(img);
+				contents.style.display = "block";
+			}
+			else {
+				setRightIcon(img);
+				contents.style.display = "none";
+			}
+			e.cancelBubble = true;
+		}
+
+		function onThemeChange(){
+			var theme = document.getElementById("sel1").value;
+			var nodes = document.getElementsByTagName("a");
+			for(var i = 0; i < nodes.length; i++){
+				var a = nodes[i];
+				a.href = a.href.replace(/(\?theme=.*)?$/, theme ? "?theme=" + theme : "");
+			}
+		}
+	</script>
+</head>
+<body onload="init()">
+	<select id="sel1" onchange="onThemeChange()">
+		<option value=""></option>
+		<option value="iPhone">iPhone</option>
+		<option value="Android">Android</option>
+		<option value="Holodark">Holodark</option>
+		<option value="BlackBerry">BlackBerry</option>
+		<option value="WindowsPhone">WindowsPhone</option>
+		<option value="Custom">Custom</option>
+	</select><br>
+	<div id="container"></div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/index.js b/dojox/mobile/tests/index.js
new file mode 100755
index 0000000..2c472ef
--- /dev/null
+++ b/dojox/mobile/tests/index.js
@@ -0,0 +1,314 @@
+var categories = [
+	{ tag: "Accordion", label: "Accordion"},
+	{ tag: "Badge", label: "Badge"},
+	{ tag: "Button", label: "Button"},
+	{ tag: "Carousel", label: "Carousel"},
+	{ tag: "ContentPane", label: "ContentPane"},
+	{ tag: "DataCarousel", label: "DataCarousel"},
+	{ tag: "DatePicker", label: "DatePicker"},
+	{ tag: "EdgeToEdgeCategory", label: "EdgeToEdgeCategory"},
+	{ tag: "EdgeToEdgeDataList", label: "EdgeToEdgeDataList"},
+	{ tag: "EdgeToEdgeList", label: "EdgeToEdgeList"},
+	{ tag: "EdgeToEdgeStoreList", label: "EdgeToEdgeStoreList"},
+	{ tag: "FixedSplitter", label: "FixedSplitter"},
+	{ tag: "FormControls", label: "FormControls"},
+	{ tag: "GridLayout", label: "GridLayout"},
+	{ tag: "Heading", label: "Heading"},
+	{ tag: "Icon", label: "Icon"},
+	{ tag: "IconContainer", label: "IconContainer"},
+	{ tag: "IconMenu", label: "IconMenu"},
+	{ tag: "ListItem", label: "ListItem"},
+	{ tag: "Media", label: "Media"},
+	{ tag: "Opener", label: "Opener"},
+	{ tag: "ProgressIndicator", label: "ProgressIndicator"},
+	{ tag: "Rating", label: "Rating"},
+	{ tag: "RoundRect", label: "RoundRect"},
+	{ tag: "RoundRectDataList", label: "RoundRectDataList"},
+	{ tag: "RoundRectList", label: "RoundRectList"},
+	{ tag: "ScreenSizeAware", label: "ScreenSizeAware"},
+	{ tag: "ScrollablePane", label: "ScrollablePane"},
+	{ tag: "ScrollableView", label: "ScrollableView"},
+	{ tag: "SimpleDialog", label: "SimpleDialog"},
+	{ tag: "SpinWheel", label: "SpinWheel"},
+	{ tag: "StoreCarousel", label: "StoreCarousel"},
+	{ tag: "SwapView", label: "SwapView"},
+	{ tag: "Switch", label: "Switch"},
+	{ tag: "TabBar", label: "TabBar"},
+	{ tag: "TimePicker", label: "TimePicker"},
+	{ tag: "ToolBarButton", label: "ToolBarButton"},
+	{ tag: "TreeView", label: "TreeView"},
+	{ tag: "ValuePicker", label: "ValuePicker"},
+	{ tag: "bookmarkable", label: "bookmarkable"},
+	{ tag: "domButton", label: "domButton"},
+	{ tag: "dynamic", label: "dynamic"},
+	{ tag: "misc", label: "misc"},
+	{ tag: "pageTurn", label: "pageTurn"},
+	{ tag: "transition", label: "transition"},
+	{ tag: "FilteredLists", label: "FilteredLists"},
+	{ tag: "TemplatedWidgets", label: "TemplatedWidgets"}
+];
+var tests = [
+	{ url: "test_Accordion-demo.html", tags: "Accordion" },
+	{ url: "test_Audio-single-source.html", tags: "Media" },
+	{ url: "test_Audio.html", tags: "Media" },
+	{ url: "test_Badge.html", tags: "Badge" },
+	{ url: "test_Button.html", tags: "Button" },
+	{ url: "test_Calendar.html", tags: "misc" },
+	{ url: "test_Carousel-prog.html", tags: "Carousel" },
+	{ url: "test_Carousel.html", tags: "Carousel" },
+	{ url: "test_CarouselItem.html", tags: "Carousel" },
+	{ url: "test_ComboBox-sv.html", tags: "FormControls" },
+	{ url: "test_ComboBox-widepage.html", tags: "FormControls" },
+	{ url: "test_ComboBox.html", tags: "FormControls" },
+	{ url: "test_ContentPane.html", tags: "ContentPane" },
+	{ url: "test_DataCarousel-demo.html", tags: "DataCarousel" },
+	{ url: "test_DataCarousel.html", tags: "DataCarousel" },
+	{ url: "test_DatePicker.html", tags: "DatePicker" },
+	{ url: "test_DatePicker2.html", tags: "DatePicker" },
+	{ url: "test_EdgeToEdgeCategory.html", tags: "EdgeToEdgeCategory" },
+	{ url: "test_EdgeToEdgeDataList-auto-sv.html", tags: "EdgeToEdgeDataList" },
+	{ url: "test_EdgeToEdgeDataList-auto-v.html", tags: "EdgeToEdgeDataList" },
+	{ url: "test_EdgeToEdgeDataList-itemMap.html", tags: "EdgeToEdgeDataList"},
+	{ url: "test_EdgeToEdgeDataList-lazy.html", tags: "EdgeToEdgeDataList"},
+	{ url: "test_EdgeToEdgeDataList-more-sv.html", tags: "EdgeToEdgeDataList" },
+	{ url: "test_EdgeToEdgeDataList-more-v.html", tags: "EdgeToEdgeDataList" },
+	{ url: "test_EdgeToEdgeDataList.html", tags: "EdgeToEdgeDataList" },
+	{ url: "test_EdgeToEdgeList-check.html", tags: "EdgeToEdgeList" },
+	{ url: "test_EdgeToEdgeList-editable-a11y.html", tags: "EdgeToEdgeList" },
+	{ url: "test_EdgeToEdgeList-editable-sv.html", tags: "EdgeToEdgeList" },
+	{ url: "test_EdgeToEdgeList-editable.html", tags: "EdgeToEdgeList" },
+	{ url: "test_EdgeToEdgeList-syncWithViews.html", tags: "EdgeToEdgeList" },
+	{ url: "test_EdgeToEdgeList-variable.html", tags: "EdgeToEdgeList"},
+	{ url: "test_EdgeToEdgeList.html", tags: "EdgeToEdgeList" },
+	{ url: "test_EdgeToEdgeStoreList-auto-sv.html", tags: "EdgeToEdgeStoreList" },
+	{ url: "test_EdgeToEdgeStoreList-auto-v.html", tags: "EdgeToEdgeStoreList" },
+	{ url: "test_EdgeToEdgeStoreList-categ.html", tags: "EdgeToEdgeStoreList" },
+	{ url: "test_EdgeToEdgeStoreList-itemMap.html", tags: "EdgeToEdgeStoreList"},
+	{ url: "test_EdgeToEdgeStoreList-itemMap-updates.html", tags: "EdgeToEdgeStoreList"},
+	{ url: "test_EdgeToEdgeStoreList-lazy.html", tags: "EdgeToEdgeStoreList"},
+	{ url: "test_EdgeToEdgeStoreList-more-sv.html", tags: "EdgeToEdgeStoreList" },
+	{ url: "test_EdgeToEdgeStoreList-more-v.html", tags: "EdgeToEdgeStoreList" },
+	{ url: "test_EdgeToEdgeStoreList.html", tags: "EdgeToEdgeStoreList" },
+	{ url: "test_FixedSplitter-H2-prog.html", tags: "FixedSplitter" },
+	{ url: "test_FixedSplitter-H2.html", tags: "FixedSplitter" },
+	{ url: "test_FixedSplitter-V2H2-ContentPane.html", tags: "FixedSplitter" },
+	{ url: "test_FixedSplitter-V2H2-change.html", tags: "FixedSplitter" },
+	{ url: "test_FixedSplitter-V2H2.html", tags: "FixedSplitter" },
+	{ url: "test_FixedSplitter-V3-var0.html", tags: "FixedSplitter" },
+	{ url: "test_FixedSplitter-V3-var1.html", tags: "FixedSplitter" },
+	{ url: "test_FixedSplitter-V3-var2.html", tags: "FixedSplitter" },
+	{ url: "test_FixedSplitter-V3.html", tags: "FixedSplitter" },
+	{ url: "test_FixedSplitter-orientation.html", tags: "FixedSplitter" },
+	{ url: "test_FormControls.html", tags: "FormControls" },
+	{ url: "test_FormLayout.html", tags: "FormControls"},
+	{ url: "test_GridLayout-2cols.html", tags: "GridLayout"},
+	{ url: "test_GridLayout-3cols.html", tags: "GridLayout"},
+	{ url: "test_GridLayout-change.html", tags: "GridLayout"},
+	{ url: "test_GridLayout-demo.html", tags: "GridLayout"},
+	{ url: "test_Heading.html", tags: "Heading" },
+	{ url: "test_Icon.html", tags: "Icon" },
+	{ url: "test_IconContainer-badge.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-connect.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-editable-a11y.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-editable.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-highlight.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-multi.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-prog.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-pubsub.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-removeConfirmation.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-single-below.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-single.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-sprite.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-transition-below.html", tags: "IconContainer" },
+	{ url: "test_IconContainer-transition-zoom.html", tags: "IconContainer" },
+	{ url: "test_IconContainer.html", tags: "IconContainer" },
+	{ url: "test_IconMenu-6up.html", tags: "IconMenu" },
+	{ url: "test_IconMenu-programmatic.html", tags: "IconMenu" },
+	{ url: "test_IconMenu-standalone.html", tags: "IconMenu" },
+	{ url: "test_ListItem-actions.html", tags: "ListItem" },
+	{ url: "test_ListItem-button.html", tags: "ListItem" },
+	{ url: "test_ListItem-domButtons.html", tags: "ListItem" },
+	{ url: "test_ListItem-layout.html", tags: "ListItem" },
+	{ url: "test_ListItem-sprite.html", tags: "ListItem" },
+	{ url: "test_ListItem-transOpt.html", tags: "ListItem" },
+	{ url: "test_Opener-ActionSheet-async.html", tags: "Opener" },
+	{ url: "test_Opener-Calendar-lazy-prog.html", tags: "Opener" },
+	{ url: "test_Opener-Calendar-lazy.html", tags: "Opener" },
+	{ url: "test_Opener-Calendar.html", tags: "Opener" },
+	{ url: "test_Opener-ColorPalette-lazy.html", tags: "Opener" },
+	{ url: "test_Opener-ColorPalette.html", tags: "Opener" },
+	{ url: "test_Opener-DateSpinWheel-lazy.html", tags: "Opener" },
+	{ url: "test_Opener-DateSpinWheel.html", tags: "Opener" },
+	{ url: "test_Opener-RoundSelectList-async.html", tags: "Opener" },
+	{ url: "test_Opener-SearchList-async.html", tags: "Opener" },
+	{ url: "test_Overlay.html", tags: "Opener" },
+	{ url: "test_ProgressBar.html", tags: "ProgressBar"},
+	{ url: "test_ProgressIndicator-color.html", tags: "ProgressIndicator" },
+	{ url: "test_ProgressIndicator-heading.html", tags: "ProgressIndicator" },
+	{ url: "test_ProgressIndicator-list.html", tags: "ProgressIndicator" },
+	{ url: "test_ProgressIndicator-size.html", tags: "ProgressIndicator" },
+	{ url: "test_ProgressIndicator.html", tags: "ProgressIndicator" },
+	{ url: "test_Rating-prog.html", tags: "Rating" },
+	{ url: "test_Rating-setter.html", tags: "Rating" },
+	{ url: "test_Rating.html", tags: "Rating" },
+	{ url: "test_RoundRect.html", tags: "RoundRect" },
+	{ url: "test_RoundRectCategory.html", tags: "RoundRectList" },
+	{ url: "test_RoundRectDataList.html", tags: "RoundRectDataList" },
+	{ url: "test_RoundRectList-check.html", tags: "RoundRectList" },
+	{ url: "test_RoundRectList-editable-sv.html", tags: "RoundRectList" },
+	{ url: "test_RoundRectList-editable.html", tags: "RoundRectList" },
+	{ url: "test_RoundRectList-icons.html", tags: "RoundRectList" },
+	{ url: "test_RoundRectList-inherit.html", tags: "RoundRectList" },
+	{ url: "test_RoundRectList-variable.html", tags: "RoundRectList"},
+	{ url: "test_RoundRectList-vh-icons.html", tags: "RoundRectList" },
+	{ url: "test_RoundRectList.html", tags: "RoundRectList" },
+	{ url: "test_RoundRectStoreList.html", tags: "RoundRectList" },
+	{ url: "test_ScreenSizeAware-demo-prop.html", tags: "ScreenSizeAware" },
+	{ url: "test_ScreenSizeAware-demo-tag.html", tags: "ScreenSizeAware" },
+	{ url: "test_ScreenSizeAware-icon.html", tags: "ScreenSizeAware" },
+	{ url: "test_ScreenSizeAware-prop.html", tags: "ScreenSizeAware" },
+	{ url: "test_ScreenSizeAware-tag.html", tags: "ScreenSizeAware" },
+	{ url: "test_ScrollableMixin-custom.html", tags: "ScrollableView" },
+	{ url: "test_ScrollablePane-demo.html", tags: "ScrollablePane" },
+	{ url: "test_ScrollablePane-h.html", tags: "ScrollablePane" },
+	{ url: "test_ScrollablePane-mask.html", tags: "ScrollablePane" },
+	{ url: "test_ScrollablePane.html", tags: "ScrollablePane" },
+	{ url: "test_ScrollableView-demo-long.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-demo.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-h.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-hv-ah-af.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-hv-vh-vf.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-hv.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-short-inp.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-short.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-v-ah-af-inp.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-v-ah-af.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-v-ah-inp.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-v-inp.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-v-vh-af-inp.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-v-vh-af.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-v-vh-inp.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-v-vh-vf-inp.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-v-vh-vf.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-v-vh.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-v.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-scrollEvents.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-pullToRefresh.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-fixedFooters.html", tags: "ScrollableView" },
+	{ url: "test_ScrollableView-HTML-inputs.html", tags: "ScrollableView" },
+	{ url: "test_SimpleDialog-large.html", tags: "SimpleDialog" },
+	{ url: "test_SimpleDialog-load.html", tags: "SimpleDialog" },
+	{ url: "test_SimpleDialog-spinWheel.html", tags: "SimpleDialog" },
+	{ url: "test_SimpleDialog.html", tags: "SimpleDialog" },
+	{ url: "test_Slider.html", tags: "FormControls" },
+	{ url: "test_SpinWheel-1slot.html", tags: "SpinWheel" },
+	{ url: "test_SpinWheel-custom.html", tags: "SpinWheel" },
+	{ url: "test_SpinWheel-icons.html", tags: "SpinWheel" },
+	{ url: "test_SpinWheelDatePicker-setter.html", tags: "SpinWheel" },
+	{ url: "test_SpinWheelDatePicker-sv.html", tags: "SpinWheel" },
+	{ url: "test_SpinWheelDatePicker.html", tags: "SpinWheel" },
+	{ url: "test_SpinWheelTimePicker-setter.html", tags: "SpinWheel" },
+	{ url: "test_SpinWheelTimePicker.html", tags: "SpinWheel" },
+	{ url: "test_StoreCarousel-demo.html", tags: "StoreCarousel" },
+	{ url: "test_StoreCarousel-prog.html", tags: "StoreCarousel" },
+	{ url: "test_StoreCarousel-resize.html", tags: "StoreCarousel" },
+	{ url: "test_StoreCarousel-slideshow.html", tags: "StoreCarousel" },
+	{ url: "test_StoreCarousel-widgets.html", tags: "StoreCarousel" },
+	{ url: "test_StoreCarousel.html", tags: "StoreCarousel" },
+	{ url: "test_SwapView-demo.html", tags: "SwapView" },
+	{ url: "test_SwapView-slideshow.html", tags: "SwapView" },
+	{ url: "test_SwapView.html", tags: "SwapView" },
+	{ url: "test_SwapView-show.html", tags: "SwapView" },
+	{ url: "test_Switch-setter.html", tags: "Switch" },
+	{ url: "test_Switch.html", tags: "Switch" },
+	{ url: "test_TabBar-badge.html", tags: "TabBar" },
+	{ url: "test_TabBar-seg-grouped-scroll.html", tags: "TabBar" },
+	{ url: "test_TabBar-seg-grouped.html", tags: "TabBar" },
+	{ url: "test_TabBar-seg.html", tags: "TabBar" },
+	{ url: "test_TabBar-syncWithViews.html", tags: "TabBar" },
+	{ url: "test_TabBar.html", tags: "TabBar" },
+	{ url: "test_TimePicker.html", tags: "TimePicker" },
+	{ url: "test_ToolBarButton-setter.html", tags: "ToolBarButton" },
+	{ url: "test_Tooltip.html", tags: "Opener" },
+	{ url: "test_TreeView.html", tags: "TreeView" },
+	{ url: "test_ValuePicker-1slot.html", tags: "ValuePicker" },
+	{ url: "test_ValuePicker-custom.html", tags: "ValuePicker" },
+	{ url: "test_ValuePicker-dialog.html", tags: "ValuePicker" },
+	{ url: "test_ValuePickerDatePicker-setter.html", tags: "ValuePicker" },
+	{ url: "test_ValuePickerDatePicker.html", tags: "ValuePicker" },
+	{ url: "test_ValuePickerSlot.html", tags: "ValuePicker" },
+	{ url: "test_ValuePickerTimePicker-setter.html", tags: "ValuePicker" },
+	{ url: "test_ValuePickerTimePicker.html", tags: "ValuePicker" },
+	{ url: "test_Video-single-source.html", tags: "Media" },
+	{ url: "test_Video.html", tags: "Media" },
+
+	{ url: "test_a11y.html", tags: "misc" },
+	{ url: "test_add-to-home-screen-sample.html", tags: "misc" },
+	{ url: "test_ajax-html-sync.html", tags: "misc" },
+	{ url: "test_ajax-html.html", tags: "misc" },
+	{ url: "test_ajax-json-sync.html", tags: "misc" },
+	{ url: "test_ajax-json.html", tags: "misc" },
+	{ url: "test_anchor-label.html", tags: "misc" },
+	{ url: "test_bg-view.html", tags: "misc" },
+	{ url: "test_bg.html", tags: "misc" },
+	{ url: "test_bk-ScrollableView-demo.html", tags: "bookmarkable" },
+	{ url: "test_bk-content-view.html", tags: "bookmarkable" },
+	{ url: "test_bk-grouped-views.html", tags: "bookmarkable" },
+	{ url: "test_bk-list.html", tags: "bookmarkable" },
+	{ url: "test_bk-split-views.html", tags: "bookmarkable" },
+	{ url: "test_bk-tablet-settings.html", tags: "bookmarkable" },
+	{ url: "test_bk_force-ScrollableView-demo.html", tags: "bookmarkable" },
+	{ url: "test_bk_force-content-view.html", tags: "bookmarkable" },
+	{ url: "test_bk_force-grouped-views.html", tags: "bookmarkable" },
+	{ url: "test_bk_force-list.html", tags: "bookmarkable" },
+	{ url: "test_bk_force-split-views.html", tags: "bookmarkable" },
+	{ url: "test_bk_force-tablet-settings.html", tags: "bookmarkable" },
+	{ url: "test_data-handlers.html", tags: "transition" },
+	{ url: "test_domButtons.html", tags: "domButton" },
+	{ url: "test_domButtons16.html", tags: "domButton" },
+	{ url: "test_domButtonsBadge.html", tags: "domButton" },
+	{ url: "test_dynamic-ScrollableView-ah-af.html", tags: "dynamic" },
+	{ url: "test_dynamic-ScrollableView-vh-vf.html", tags: "dynamic" },
+	{ url: "test_dynamic-icons.html", tags: "dynamic" },
+	{ url: "test_dynamic-items.html", tags: "dynamic" },
+	{ url: "test_grouped-scrollable-views.html", tags: "misc" },
+	{ url: "test_grouped-views.html", tags: "misc" },
+	{ url: "test_hash-parameter.html", tags: "misc" },
+	{ url: "test_html-form-controls.html", tags: "misc" },
+	{ url: "test_html-inputs.html", tags: "misc" },
+	{ url: "test_i18n-sync.html", tags: "misc" },
+	{ url: "test_i18n.html", tags: "misc" },
+	{ url: "test_migrationAssist.html", tags: "misc" },
+	{ url: "test_new_transition-animations-standard.html", tags: "transition" },
+	{ url: "test_new_transition-animations.html", tags: "transition" },
+	{ url: "test_new_transition-animations2.html", tags: "transition" },
+	{ url: "test_orientation-transition.html", tags: "misc" },
+	{ url: "test_pageTurningUtils-add-remove.html", tags: "pageTurn" },
+	{ url: "test_pageTurningUtils-callback.html", tags: "pageTurn" },
+	{ url: "test_pageTurningUtils-pageType.html", tags: "pageTurn" },
+	{ url: "test_pageTurningUtils.html", tags: "pageTurn" },
+	{ url: "test_phone-settings.html", tags: "misc" },
+	{ url: "test_tablet-settings.html", tags: "misc" },
+	{ url: "test_theme-switch.html", tags: "misc" },
+	{ url: "test_theme-iOS6.html", tags: "misc" },
+	{ url: "test_transition-animations-extended1.html", tags: "transition" },
+	{ url: "test_transition-animations-extended2.html", tags: "transition" },
+	{ url: "test_transition-animations-extended3.html", tags: "transition" },
+	{ url: "test_transition-animations-extended4.html", tags: "transition" },
+	{ url: "test_transition-animations-extended5.html", tags: "transition" },
+	{ url: "test_transition-animations-standard.html", tags: "transition" },
+	{ url: "test_transition-animations.html", tags: "transition" },
+	{ url: "test_transition-animations2.html", tags: "transition" },
+	{ url: "test_transition-connect.html", tags: "transition" },
+	{ url: "test_transition-pubsub.html", tags: "transition" },
+	{ url: "test_FilteredList-EdgeToEdgeDataList-demo.html", tags: "FilteredLists" },
+	{ url: "test_FilteredList-EdgeToEdgeStoreList-auto.html", tags: "FilteredLists" },
+	{ url: "test_FilteredList-EdgeToEdgeStoreList-auto-prog.html", tags: "FilteredLists" },
+	{ url: "test_FilteredList-EdgeToEdgeStoreList-demo.html", tags: "FilteredLists" },
+	{ url: "test_FilteredList-EdgeToEdgeStoreList-prog.html", tags: "FilteredLists" },
+	{ url: "test_FilteredList-EdgeToEdgeStoreList-simple.html", tags: "FilteredLists" },
+	{ url: "test_FilteredList-RoundRectList-auto.html", tags: "FilteredLists" },
+	{ url: "test_FilteredList-RoundRectList-demo.html", tags: "FilteredLists" },
+	{ url: "test_LongListMixin.html", tags: "ScrollableView" },
+	{ url: "test_Templated-widgets.html", tags: "TemplatedWidgets" }
+];
diff --git a/dojox/mobile/tests/inputApp/index.html b/dojox/mobile/tests/inputApp/index.html
index 361aeb4..cf01c93 100644
--- a/dojox/mobile/tests/inputApp/index.html
+++ b/dojox/mobile/tests/inputApp/index.html
@@ -12,7 +12,7 @@
 		}
 		</style>
 		
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false"></script>
 
 		<script language="JavaScript" type="text/javascript">
 			dojo.require("dojox.mobile.app");
diff --git a/dojox/mobile/tests/insurance-car.json b/dojox/mobile/tests/insurance-car.json
deleted file mode 100644
index 23ce8d0..0000000
--- a/dojox/mobile/tests/insurance-car.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "items" : [
-    { label: "Coverage Options", icon: "images/i-icon-1.png", url: "insurance-car-coverage.html" },
-    { label: "Safe Driving Bonus", icon: "images/i-icon-1.png", url: "insurance-car-safe.html" }
-  ]
-}
diff --git a/dojox/mobile/tests/insurance-life.json b/dojox/mobile/tests/insurance-life.json
deleted file mode 100644
index dab22f8..0000000
--- a/dojox/mobile/tests/insurance-life.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "items" : [
-    { label: "Long Term Care", icon: "images/i-icon-2.png", url: "insurance-life-long.html" },
-    { label: "Child's Education", icon: "images/i-icon-2.png", url: "insurance-life-child.html" }
-  ]
-}
diff --git a/dojox/mobile/tests/insurance-sports.json b/dojox/mobile/tests/insurance-sports.json
deleted file mode 100644
index a3c24d4..0000000
--- a/dojox/mobile/tests/insurance-sports.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "items" : [
-    { label: "Motorcycle", icon: "images/i-icon-10.png", url: "insurance-sports-moto.html" },
-    { label: "Snowmobile", icon: "images/i-icon-10.png", url: "insurance-sports-snow.html" },
-    { label: "Boat", icon: "images/i-icon-10.png", url: "insurance-sports-boat.html" }
-  ]
-}
diff --git a/dojox/mobile/tests/insurance.json b/dojox/mobile/tests/insurance.json
deleted file mode 100644
index df4dafd..0000000
--- a/dojox/mobile/tests/insurance.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "items" : [
-    { label: "Car Insurance", id: "CarInsurance", icon: "images/tab-icon-11h.png", data: "insurance-car.json", moveTo: "#" },
-    { label: "Life Insurance", id: "LifeInsurance", icon: "images/tab-icon-15h.png", data: "insurance-life.json", moveTo: "#" },
-    { label: "Sports Insurance", id: "SportsInsurance", icon: "images/tab-icon-10h.png", data: "insurance-sports.json", moveTo: "#" }
-  ]
-}
diff --git a/dojox/mobile/tests/items.json b/dojox/mobile/tests/items.json
deleted file mode 100644
index b724415..0000000
--- a/dojox/mobile/tests/items.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  items: [
-	{ title:'Top 10 news stories', href:'http://dojotoolkit.org/' },
-	{ title:'Web applications with GFX', href:'http://dojotoolkit.org/' },
-	{ title:'Explores advanced topics', href:'http://dojotoolkit.org/' }
-  ]
-}
diff --git a/dojox/mobile/tests/multiSceneApp/index.html b/dojox/mobile/tests/multiSceneApp/index.html
index cd97251..1f6aa07 100644
--- a/dojox/mobile/tests/multiSceneApp/index.html
+++ b/dojox/mobile/tests/multiSceneApp/index.html
@@ -12,7 +12,7 @@
 		}
 		</style>
 		<script type="text/javascript" src="../../../../dojo/dojo.js" 
-			djConfig="parseOnLoad: false,mobileAnim:'slide'"></script>
+			data-dojo-config="parseOnLoad: false,mobileAnim:'slide'"></script>
     
 		<script language="JavaScript" type="text/javascript">
 			dojo.require("dojox.mobile.app");
diff --git a/dojox/mobile/tests/nls/it/sample.js b/dojox/mobile/tests/nls/it/sample.js
index 74963ee..74e0183 100644
--- a/dojox/mobile/tests/nls/it/sample.js
+++ b/dojox/mobile/tests/nls/it/sample.js
@@ -1,11 +1,10 @@
 define(
-//begin v1.x content
 ({
 	"MINUTES": "%1 Minuto",
 	"Second": "secondo",
 	"Day of the Week": "giorno della settimana",
+	"Today": "Oggi",
 	"Sunday": "Domenica",
 	"Monday": "Lunedì"
 })
-//end v1.x content
 );
diff --git a/dojox/mobile/tests/nls/ja/sample.js b/dojox/mobile/tests/nls/ja/sample.js
index de5a707..86f2626 100644
--- a/dojox/mobile/tests/nls/ja/sample.js
+++ b/dojox/mobile/tests/nls/ja/sample.js
@@ -1,13 +1,12 @@
 define(
-//begin v1.x content
 ({
 	"MINUTES": "%1 分",
 	"Second": "秒",
 	"Day of the Week": "曜日",
+	"Today": "今日",
 	"Sunday": "日曜日",
 	"Monday": "月曜日",
 	"ON": "オン",
 	"OFF": "オフ"
 })
-//end v1.x content
 );
diff --git a/dojox/mobile/tests/robot/Animation.html b/dojox/mobile/tests/robot/Animation.html
index bf15bbb..7092355 100644
--- a/dojox/mobile/tests/robot/Animation.html
+++ b/dojox/mobile/tests/robot/Animation.html
@@ -2,61 +2,116 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Tooltip Mouse Quirks Test</title>
+		<title>runner.robot Tooltip Mouse Quirks Test</title>
 
 		<style>
 			@import "../../../../util/doh/robot/robot.css";
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<!-- script type="text/javascript" src="../helpers.js"></script -->
-
-		<script type="text/javascript">
-			dojo.require("dojo.parser");
-			dojo.require("dijit.robotx");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.IconContainer");
-	        dojo.require("doh.runner");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_iPhone-Animation.html");
-
-				doh.register("dojox.mobile.Animation mouse tests", [
-					{
-						name: "Animation mouse tests",
-						timeout: 40000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_0").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_1").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_1").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_1").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_2").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.assertEqual("Search Result",  dijit.byId("dojox_mobile_Heading_1").get("label"));
-							}), 500);
-							return d;
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			require([
+				"dojo/_base/kernel",
+				"dojo/ready", // dojo.ready
+				"doh/runner",	//doh functions
+				"dijit/registry",  // dijit.registry.byId
+				"dijit/robotx"
+			], function(kernel, ready, runner, registry){
+				ready(function(){
+
+					runner.robot.initRobot("../test_transition-connect.html");
+					var reg=null;
+
+					runner.register("dojox.mobile.Animation mouse tests", [
+						{
+							name: "Animation mouse tests",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+								reg = kernel.global.dijit.registry;
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_0").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual("none",  reg.byId("view1").domNode.style.display);
+									runner.assertEqual("",  reg.byId("view2").domNode.style.display);
+								}), 1500);
+								return d;
+							}
+						},
+						{
+							name: "Animation mouse tests",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ToolBarButton_0").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+								
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual("",  reg.byId("view1").domNode.style.display);
+									runner.assertEqual("none",  reg.byId("view2").domNode.style.display);
+								}), 1500);
+								return d;
+							}
+						},
+						{
+							name: "Animation mouse tests",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_1").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual("none",  reg.byId("view1").domNode.style.display);
+									runner.assertEqual("",  reg.byId("view2").domNode.style.display);
+								}), 1500);
+								return d;
+							}
+						},
+						{
+							name: "Animation mouse tests",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ToolBarButton_0").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual("",  reg.byId("view1").domNode.style.display);
+									runner.assertEqual("none",  reg.byId("view2").domNode.style.display);
+								}), 1500);
+								return d;
+							}
+						},
+						{
+							name: "Animation mouse tests",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_2").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual("none",  reg.byId("view1").domNode.style.display);
+									runner.assertEqual("",  reg.byId("view2").domNode.style.display);
+								}), 2000);
+								return d;
+							}
 						}
-					}
-				]);
+					]);
 
-				doh.run();
+					runner.run();
+				});
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/Animation2.html b/dojox/mobile/tests/robot/Animation2.html
index bf15bbb..581d2f8 100644
--- a/dojox/mobile/tests/robot/Animation2.html
+++ b/dojox/mobile/tests/robot/Animation2.html
@@ -9,54 +9,109 @@
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<!-- script type="text/javascript" src="../helpers.js"></script -->
-
-		<script type="text/javascript">
-			dojo.require("dojo.parser");
-			dojo.require("dijit.robotx");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.IconContainer");
-	        dojo.require("doh.runner");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_iPhone-Animation.html");
-
-				doh.register("dojox.mobile.Animation mouse tests", [
-					{
-						name: "Animation mouse tests",
-						timeout: 40000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_0").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_1").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_1").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_1").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_2").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.assertEqual("Search Result",  dijit.byId("dojox_mobile_Heading_1").get("label"));
-							}), 500);
-							return d;
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			require([
+				"dojo/_base/kernel",
+				"dojo/ready", // dojo.ready
+				"doh/runner",	//doh functions
+				"dijit/registry",  // dijit.registry.byId
+				"dijit/robotx"
+			], function(kernel, ready, runner, registry){
+				ready(function(){
+
+					runner.robot.initRobot("../test_transition-pubsub.html");
+					var reg = null;
+
+					runner.register("dojox.mobile.Animation mouse tests", [
+						{
+							name: "Animation mouse tests",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+								reg = kernel.global.dijit.registry;
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_0").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual("none",  reg.byId("view1").domNode.style.display);
+									runner.assertEqual("",  reg.byId("view2").domNode.style.display);
+								}), 1500);
+								return d;
+							}
+						},
+						{
+							name: "Animation mouse tests",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ToolBarButton_0").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+								
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual("",  reg.byId("view1").domNode.style.display);
+									runner.assertEqual("none",  reg.byId("view2").domNode.style.display);
+								}), 100);
+								return d;
+							}
+						},
+						{
+							name: "Animation mouse tests",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_1").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual("none",  reg.byId("view1").domNode.style.display);
+									runner.assertEqual("",  reg.byId("view2").domNode.style.display);
+								}), 1500);
+								return d;
+							}
+						},
+						{
+							name: "Animation mouse tests",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ToolBarButton_0").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual("",  reg.byId("view1").domNode.style.display);
+									runner.assertEqual("none",  reg.byId("view2").domNode.style.display);
+								}), 1500);
+								return d;
+							}
+						},
+						{
+							name: "Animation mouse tests",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_2").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual("none",  reg.byId("view1").domNode.style.display);
+									runner.assertEqual("",  reg.byId("view2").domNode.style.display);
+								}), 2000);
+								return d;
+							}
 						}
-					}
-				]);
+					]);
 
-				doh.run();
+					runner.run();
+				});
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/ButtonList.html b/dojox/mobile/tests/robot/ButtonList.html
index c56183d..253dc07 100644
--- a/dojox/mobile/tests/robot/ButtonList.html
+++ b/dojox/mobile/tests/robot/ButtonList.html
@@ -9,42 +9,49 @@
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<!-- script type="text/javascript" src="../helpers.js"></script -->
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_Android-ButtonList.html");
-
-				doh.register("dojox.mobile.ButtonList mouse tests", [
-					{
-						name: "ButtonList mouse tests",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt(dojo.query(".mblDomButton", dijit.byId("dojox_mobile_ListItem_0").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblDomButton", dijit.byId("dojox_mobile_ListItem_1").domNode)[0], 500);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.assertTrue(dojo.hasClass(dojo.query(".mblDomButton", dijit.byId("dojox_mobile_ListItem_0").domNode)[0], "mblDomButtonCheckboxOn"));
-								doh.assertTrue(dojo.hasClass(dojo.query(".mblDomButton", dijit.byId("dojox_mobile_ListItem_1").domNode)[0], "mblDomButtonCheckboxOff"));
-							}), 500);
-							return d;
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			require([
+				"dojo/_base/kernel",
+				"dojo/dom-class", // dojo.hasClass
+				"dojo/ready", // dojo.ready
+				"doh/runner",	//doh functions
+				"dijit/registry",  // dijit.registry.byId
+				"dijit/robotx"
+			], function(kernel, domClass, ready, runner, registry){
+				ready(function(){
+
+					runner.robot.initRobot("../test_EdgeToEdgeList-check.html");
+
+					runner.register("dojox.mobile.ButtonList mouse tests", [
+						{
+							name: "ButtonList mouse tests",
+							timeout: 10000,
+							runTest: function(){
+								var d = new runner.Deferred();
+								var reg = kernel.global.dijit.registry;
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_0").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_1").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									doh.assertTrue(domClass.contains(reg.byId("item1").domNode, "mblListItemUnchecked"), "item1");
+									doh.assertTrue(domClass.contains(reg.byId("dojox_mobile_ListItem_0").domNode, "mblListItemUnchecked"), "dojox_mobile_ListItem_0");
+									doh.assertTrue(domClass.contains(reg.byId("dojox_mobile_ListItem_1").domNode, "mblListItemChecked"), "dojox_mobile_ListItem_1");
+								}), 1000);
+								return d;
+							}
 						}
-					}
-				]);
-
-				doh.run();
+					]);
+					runner.run();
+				});
 			});
 		</script>
 	</head>
+	<body>
+	
+	</body>
 </html>
diff --git a/dojox/mobile/tests/robot/ButtonList2.html b/dojox/mobile/tests/robot/ButtonList2.html
index b9ecd49..69a53ff 100644
--- a/dojox/mobile/tests/robot/ButtonList2.html
+++ b/dojox/mobile/tests/robot/ButtonList2.html
@@ -9,42 +9,51 @@
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<!-- script type="text/javascript" src="../helpers.js"></script -->
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_iPhone-ButtonList.html");
-
-				doh.register("dojox.mobile.ButtonList mouse tests", [
-					{
-						name: "ButtonList mouse tests",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt(dojo.query(".mblDomButton", dijit.byId("dojox_mobile_ListItem_0").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblDomButton", dijit.byId("dojox_mobile_ListItem_1").domNode)[0], 500);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.assertTrue(dojo.hasClass(dojo.query(".mblDomButton", dijit.byId("dojox_mobile_ListItem_0").domNode)[0], "mblDomButtonRedMinus"));
-								doh.assertTrue(dojo.hasClass(dojo.query(".mblDomButton", dijit.byId("dojox_mobile_ListItem_1").domNode)[0], "mblDomButtonBluePlus"));
-							}), 500);
-							return d;
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			require([
+				"dojo/_base/kernel",
+				"dojo/dom-class", // dojo.hasClass
+				"dojo/ready", // dojo.ready
+				"doh/runner",	//doh functions
+				"dijit/registry",  // dijit.registry.byId
+				"dijit/robotx"
+			], function(kernel, domClass, ready, runner, registry){
+				ready(function(){
+
+					runner.robot.initRobot("../test_RoundRectList-check.html");
+
+					runner.register("dojox.mobile.ButtonList mouse tests", [
+						{
+							name: "ButtonList mouse tests",
+							timeout: 10000,
+							runTest: function(){
+								var d = new runner.Deferred();
+								var reg = kernel.global.dijit.registry;
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_2").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_3").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_4").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									doh.assertTrue(domClass.contains(reg.byId("dojox_mobile_ListItem_2").domNode, "mblListItemUnchecked"), "dojox_mobile_ListItem_2");
+									doh.assertTrue(domClass.contains(reg.byId("dojox_mobile_ListItem_3").domNode, "mblListItemChecked"), "dojox_mobile_ListItem_3");
+									doh.assertTrue(domClass.contains(reg.byId("dojox_mobile_ListItem_4").domNode, "mblListItemChecked"), "dojox_mobile_ListItem_3");
+								}), 1000);
+								return d;
+							}
 						}
-					}
-				]);
-
-				doh.run();
+					]);
+					runner.run();
+				});
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/Flippable.html b/dojox/mobile/tests/robot/Flippable.html
index e16bda7..7cbb90f 100644
--- a/dojox/mobile/tests/robot/Flippable.html
+++ b/dojox/mobile/tests/robot/Flippable.html
@@ -9,48 +9,47 @@
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
-		<!-- functions to help test -->
-		<!-- script type="text/javascript" src="../helpers.js"></script -->
-
-		<script type="text/javascript">
-			dojo.require("dojo.parser");
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo._base.kernel");
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.registry");
+			dojo.require("dijit.ready");
+			dojo.require("doh.runner");
 			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.IconContainer");
-	        dojo.require("doh.runner");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_iPhone-SwapView.html");
-
-				doh.register("dojox.mobile.FlippableView mouse tests", [
-					{
-						name: "FlippableView mouse tests",
-						timeout: 40000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var dim = dojox.mobile.getScreenSize();
-
-							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100, (dim.w -30),100);
-							doh.robot.mousePress({left: true}, 1000);
-
-							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,(dim.w -30)/2,0);
-
-							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,0,100);
-							doh.robot.mouseRelease({left: true}, 50);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.assertEqual("",  dijit.byId("bar").domNode.style.display);
-							}), 500);
-							return d;
+				dojo.ready(function(){
+					doh.robot.initRobot("../test_SwapView.html");
+					var reg = null;
+
+					doh.register("dojox.mobile.SwapView mouse tests", [
+						{
+							name: "SwapView mouse tests",
+							timeout: 40000,
+							runTest: function(){
+								var d = new doh.Deferred();
+								reg = kernel.global.dijit.registry;
+								var dim = dojox.mobile.getScreenSize();
+
+								doh.robot.mouseMoveAt(reg.byId("dojox_mobile_SwapView_0").domNode, 1000,100, (dim.w -30),100);
+								doh.robot.mousePress({left: true}, 1000);
+
+								doh.robot.mouseMoveAt(reg.byId("dojox_mobile_SwapView_0").domNode, 1000,100,(dim.w -30)/2,0);
+
+								doh.robot.mouseMoveAt(reg.byId("dojox_mobile_SwapView_0").domNode, 1000,100,10,100);
+								doh.robot.mouseRelease({left: true}, 50);
+								
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.assertEqual("none",  reg.byId("dojox_mobile_SwapView_0").domNode.style.display);
+									doh.assertEqual("",  reg.byId("dojox_mobile_SwapView_1").domNode.style.display);
+								}), 1000);
+								return d;
+							}
 						}
-					}
-				]);
-
-				doh.run();
-			});
+					]);
+					doh.run();
+				});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/Icon.html b/dojox/mobile/tests/robot/Icon.html
index fc2b0d8..390a535 100644
--- a/dojox/mobile/tests/robot/Icon.html
+++ b/dojox/mobile/tests/robot/Icon.html
@@ -9,42 +9,42 @@
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<!-- script type="text/javascript" src="../helpers.js"></script -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dojo.parser");
-			dojo.require("dijit.robotx");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.IconContainer");
-	        dojo.require("doh.runner");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_iPhone-Icon.html");
-
-				doh.register("dojox.mobile.Icon mouse tests", [
-					{
-						name: "Icon mouse tests",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt(dojo.query(".mblIconArea", dijit.byId("dojox_mobile_IconContainer_0").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.assertEqual("",  dijit.byId("dojox_mobile_IconItem_0").subNode.style.display);
-							}), 500);
-							return d;
+			require([
+				"dojo/_base/kernel",
+				"dojo/ready", // dojo.ready
+				"doh/runner",	//doh functions
+				"dijit/registry",  // dijit.registry.byId
+				"dijit/robotx"
+			], function(kernel, ready, runner, registry){
+				ready(function(){
+					doh.robot.initRobot("../test_IconContainer.html");
+					var reg = null;
+
+					doh.register("dojox.mobile.Icon mouse tests", [
+						{
+							name: "Icon mouse tests",
+							timeout: 4000,
+							runTest: function(){
+								var d = new doh.Deferred();
+								reg = kernel.global.dijit.registry;
+
+								doh.robot.mouseMoveAt(reg.byId("dojox_mobile_IconItem_0").iconNode, 1000);
+								doh.robot.mouseClick({left: true}, 500);
+
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.assertEqual("",  reg.byId("dojox_mobile__IconItemPane_0").domNode.style.display);
+								}), 500);
+								return d;
+							}
 						}
-					}
-				]);
-
-				doh.run();
+					]);
+					doh.run();
+				});
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/Icon2.html b/dojox/mobile/tests/robot/Icon2.html
index 2ff50a0..aaccefe 100644
--- a/dojox/mobile/tests/robot/Icon2.html
+++ b/dojox/mobile/tests/robot/Icon2.html
@@ -9,42 +9,42 @@
 		</style>
 
 		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
-
-		<!-- functions to help test -->
-		<!-- script type="text/javascript" src="../helpers.js"></script -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 
 		<script type="text/javascript">
-			dojo.require("dojo.parser");
-			dojo.require("dijit.robotx");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.IconContainer");
-	        dojo.require("doh.runner");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_Android-Icon.html");
-
-				doh.register("dojox.mobile.Icon mouse tests", [
-					{
-						name: "Icon mouse tests",
-						timeout: 4000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt(dojo.query(".mblIconArea", dijit.byId("dojox_mobile_IconContainer_0").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.assertEqual("",  dijit.byId("dojox_mobile_IconItem_0").subNode.style.display);
-							}), 500);
-							return d;
+			require([
+				"dojo/_base/kernel",
+				"dojo/ready", // dojo.ready
+				"doh/runner",	//doh functions
+				"dijit/registry",  // dijit.registry.byId
+				"dijit/robotx"
+			], function(kernel, ready, runner, registry){
+				ready(function(){
+					doh.robot.initRobot("../test_IconContainer.html?theme=Android");
+					var reg = null;
+
+					doh.register("dojox.mobile.Icon mouse tests", [
+						{
+							name: "Icon mouse tests",
+							timeout: 4000,
+							runTest: function(){
+								var d = new doh.Deferred();
+								reg = kernel.global.dijit.registry;
+
+								doh.robot.mouseMoveAt(reg.byId("dojox_mobile_IconItem_0").iconNode, 1000);
+								doh.robot.mouseClick({left: true}, 500);
+
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.assertEqual("",  reg.byId("dojox_mobile__IconItemPane_0").domNode.style.display);
+								}), 1000);
+								return d;
+							}
 						}
-					}
-				]);
-
-				doh.run();
+					]);
+					doh.run();
+				});
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/ListItem.html b/dojox/mobile/tests/robot/ListItem.html
index d74ef80..1b68b9b 100644
--- a/dojox/mobile/tests/robot/ListItem.html
+++ b/dojox/mobile/tests/robot/ListItem.html
@@ -10,13 +10,14 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- functions to help test -->
 		<!-- script type="text/javascript" src="../helpers.js"></script -->
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
+			dojo.require("dijit.registry");
 
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot("../test_ajax-html.html");
@@ -24,17 +25,18 @@
 				doh.register("dojox.mobile.ListItem mouse tests", [
 					{
 						name: "ListItem mouse tests",
-						timeout: 4000,
+						timeout: 7000,
 						runTest: function(){
 							var d = new doh.Deferred();
+							var reg=dojo.global.dijit.registry;
 
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemTextBox", dijit.byId("dojox_mobile_ListItem_0").domNode)[0], 2000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_0").domNode, 2000);
 							doh.robot.mouseClick({left: true}, 500);
 
-
+							// FIXME: this animation can be very slow on mobile, it would be nice to register an event handler.
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("view1.html", dijit.byId("dojox_mobile_Heading_1").get("label"));
-							}), 500);
+								doh.is("view1.html", reg.byId("dojox_mobile_Heading_1").get("label"));
+							}), 2000);
 							return d;
 						}
 					}
@@ -44,4 +46,5 @@
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/RoundRectListConnect.html b/dojox/mobile/tests/robot/RoundRectListConnect.html
new file mode 100644
index 0000000..3ea507d
--- /dev/null
+++ b/dojox/mobile/tests/robot/RoundRectListConnect.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot Tooltip Mouse Quirks Test</title>
+
+		<style>
+			@import "../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/ready", // dojo.ready
+				"doh/runner",	//doh functions
+				"dojo/dom",
+				"dojo/query",
+				"dijit/robotx"
+			], function(ready, runner, dom, query){
+					ready(function(){
+
+					runner.robot.initRobot("../test_RoundRectList-connect.html");
+	
+					runner.register("dojox.mobile.RoundRectList mouse tests", [
+						{
+							name: "RoundRectList mouse tests",
+							timeout: 10000,
+							runTest: function(){
+								// The encapsulation of the query in an anonymous function ensure that the query is evaluated only 
+								// when the movement begin.	Therefore the requested element has the time to appear.							
+								var getInTime = function (/*String*/ root, /*String?*/ className){
+									className = "." + (className || "mblDomButtonGrayKnob");
+									return function(){return query(className, dom.byId(root))[0];};
+								}
+
+								var d = new runner.Deferred();
+								var btn = dom.byId("btn1");
+								
+								// Start editing
+								runner.robot.mouseMoveAt(btn, 100, 200);
+								runner.robot.mouseClick({left: true}, 100);
+								
+								// drag n drop
+								runner.robot.mouseMoveAt(getInTime("item1"), 100, 200);
+								runner.robot.mousePress({left: true}, 100);
+								runner.robot.mouseMoveAt(dom.byId("msgArea1"), 100, 500);
+								runner.robot.mouseRelease({left: true}, 100);
+								
+								// drag n drop
+								runner.robot.mouseMoveAt(getInTime("item7"), 100, 200);
+								runner.robot.mousePress({left: true}, 100);
+								runner.robot.mouseMoveAt(dom.byId("item4"), 100, 500);
+								runner.robot.mouseRelease({left: true}, 100);
+								
+								// delete
+								runner.robot.mouseMoveAt(getInTime("item7", "mblDomButtonRedCircleMinus"), 100, 200);
+								runner.robot.mouseClick({left: true}, 100);
+								runner.robot.mouseMoveAt(getInTime("item7", "mblDomButtonMyRedButton_0"), 100, 200);
+								runner.robot.mouseClick({left: true}, 100);
+								
+								
+								// drag n drop
+								runner.robot.mouseMoveAt(getInTime("item8"), 100, 200);
+								runner.robot.mousePress({left: true}, 100);
+								runner.robot.mouseMoveAt(dom.byId("item2"), 100, 500);
+								runner.robot.mouseRelease({left: true}, 100);
+								
+								//End editing
+								runner.robot.mouseMoveAt(btn, 100, 200);
+								runner.robot.mouseClick({left: true}, 100);
+								
+								runner.robot.sequence(d.getTestCallback(function(){
+									doh.assertTrue(dom.byId("msgArea1").innerHTML === "Start editing...", "onStartEdit Error");
+									doh.assertTrue(dom.byId("msgArea2").innerHTML === "MoveItem: Item 1 (0 -> 7) " + 
+																					  "MoveItem: Item 7 (5 -> 2) " +
+																					  "MoveItem: Item 8 (5 -> 0) ", "onMoveItem Error");
+									doh.assertTrue(dom.byId("msgArea3").innerHTML === "DeleteItem: Item 7", "onDeleteItem Error");
+									doh.assertTrue(dom.byId("msgArea4").innerHTML === "End editing !", "onEndEdit Error");
+									
+								}), 1000);
+								
+								return d;
+							}
+						}
+					]);
+					runner.run();
+				});
+			});
+		</script>
+	</head>
+	<body>
+		
+	</body>
+</html>
diff --git a/dojox/mobile/tests/robot/ScrollableView.html b/dojox/mobile/tests/robot/ScrollableView.html
index e75e2e4..18d2d6e 100644
--- a/dojox/mobile/tests/robot/ScrollableView.html
+++ b/dojox/mobile/tests/robot/ScrollableView.html
@@ -10,7 +10,7 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- functions to help test -->
 		<!-- script type="text/javascript" src="../helpers.js"></script -->
@@ -23,7 +23,7 @@
 	        dojo.require("doh.runner");
 
 			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_iPhone-ScrollableView-v.html");
+				doh.robot.initRobot("../test_ScrollableView-v.html");
 
 				doh.register("dojox.mobile.ScrollableView mouse tests", [
 					{
@@ -32,14 +32,14 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,300);
+							doh.robot.mouseMoveAt(dijit.registry.byId("view1").domNode, 1000,100,100,300);
 							doh.robot.mousePress({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,50);
+							doh.robot.mouseMoveAt(dijit.registry.byId("view1").domNode, 1000,100,100,50);
 							doh.robot.mouseRelease({left: true}, 0,5000);
 							
 							doh.robot.sequence(d.getTestCallback(function(){
-								var pos = dijit.byId("foo").getPos();
+								var pos = dijit.registry.byId("view1").getPos();
 								doh.assertTrue(pos.y<0);
 							}), 500);
 							return d;
@@ -51,4 +51,5 @@
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/ScrollableView2.html b/dojox/mobile/tests/robot/ScrollableView2.html
index d14dd71..590e179 100644
--- a/dojox/mobile/tests/robot/ScrollableView2.html
+++ b/dojox/mobile/tests/robot/ScrollableView2.html
@@ -10,7 +10,7 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- functions to help test -->
 		<!-- script type="text/javascript" src="../helpers.js"></script -->
@@ -23,7 +23,7 @@
 	        dojo.require("doh.runner");
 
 			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_iPhone-ScrollableView-v-vh-af.html");
+				doh.robot.initRobot("../test_ScrollableView-v-vh-af.html");
 
 				doh.register("dojox.mobile.ScrollableView mouse tests", [
 					{
@@ -32,14 +32,14 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,150);
+							doh.robot.mouseMoveAt(dijit.registry.byId("view1").domNode, 1000,100,100,150);
 							doh.robot.mousePress({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,50);
+							doh.robot.mouseMoveAt(dijit.registry.byId("view1").domNode, 1000,100,100,50);
 							doh.robot.mouseRelease({left: true}, 0,5000);
 							
 							doh.robot.sequence(d.getTestCallback(function(){
-								var pos = dijit.byId("foo").getPos();
+								var pos = dijit.registry.byId("view1").getPos();
 								doh.assertTrue(pos.y<0);
 							}), 500);
 							return d;
@@ -51,4 +51,5 @@
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/ScrollableView3.html b/dojox/mobile/tests/robot/ScrollableView3.html
index 1de9573..13cbedb 100644
--- a/dojox/mobile/tests/robot/ScrollableView3.html
+++ b/dojox/mobile/tests/robot/ScrollableView3.html
@@ -10,7 +10,7 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- functions to help test -->
 		<!-- script type="text/javascript" src="../helpers.js"></script -->
@@ -23,7 +23,7 @@
 	        dojo.require("doh.runner");
 
 			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_iPhone-ScrollableView-v-vh-vf.html");
+				doh.robot.initRobot("../test_ScrollableView-v-vh-vf.html");
 
 				doh.register("dojox.mobile.ScrollableView mouse tests", [
 					{
@@ -32,14 +32,14 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,150);
+							doh.robot.mouseMoveAt(dijit.registry.byId("view1").domNode, 1000,100,100,150);
 							doh.robot.mousePress({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dijit.byId("foo").domNode, 1000,100,100,50);
+							doh.robot.mouseMoveAt(dijit.registry.byId("view1").domNode, 1000,100,100,50);
 							doh.robot.mouseRelease({left: true}, 0,5000);
 							
 							doh.robot.sequence(d.getTestCallback(function(){
-								var pos = dijit.byId("foo").getPos();
+								var pos = dijit.registry.byId("view1").getPos();
 								doh.assertTrue(pos.y<0);
 							}), 500);
 							return d;
@@ -51,4 +51,5 @@
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/Settings.html b/dojox/mobile/tests/robot/Settings.html
index 28ac414..6a747fb 100644
--- a/dojox/mobile/tests/robot/Settings.html
+++ b/dojox/mobile/tests/robot/Settings.html
@@ -10,7 +10,7 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- functions to help test -->
 		<!-- script type="text/javascript" src="../helpers.js"></script -->
@@ -23,90 +23,72 @@
 	        dojo.require("doh.runner");
 
 			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_iPad-Settings.html");
+				doh.robot.initRobot("../test_tablet-settings.html");
 
 				doh.register("dojox.mobile.Settings mouse tests", [
 					{
 						name: "Settings mouse tests",
-						timeout: 40000,
+						timeout: 50000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_20").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_0").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_19").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_21").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_22").domNode)[0], 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_1").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_23").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_2").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_3").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_24").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_4").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_5").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_25").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_6").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_7").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_26").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_8").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_9").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_27").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_10").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_11").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_28").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_12").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_13").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_29").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_14").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_15").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblListItemAnchor", dijit.byId("dojox_mobile_ListItem_30").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_16").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblArrowButtonBody", dijit.byId("dojox_mobile_Heading_2").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(dijit.registry.byId("dojox_mobile_ListItem_17").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.assertEqual("General",  dijit.byId("dojox_mobile_Heading_1").get("label"));
-							}), 500);
+								doh.assertEqual("",  dijit.registry.byId("general").domNode.style.display);
+							}), 1500);
 							return d;
 						}
 					}
@@ -116,4 +98,5 @@
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/Switch.html b/dojox/mobile/tests/robot/Switch.html
index daf458b..cf44fbf 100644
--- a/dojox/mobile/tests/robot/Switch.html
+++ b/dojox/mobile/tests/robot/Switch.html
@@ -10,7 +10,7 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- functions to help test -->
 		<!-- script type="text/javascript" src="../helpers.js"></script -->
@@ -19,32 +19,109 @@
 			dojo.require("dijit.robotx");
 
 			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_iPhone-Switch.html");
-
+				doh.robot.initRobot("../test_Switch.html");
+				var reg=null;
 				doh.register("dojox.mobile.Switch mouse tests", [
 					{
 						name: "Switch mouse tests",
-						timeout: 4000,
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							reg = dojo.global.dijit.registry;
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_0").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_1").domNode, 500);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("on", reg.byId("dojox_mobile_Switch_0").get("value"));
+								doh.is("off", reg.byId("dojox_mobile_Switch_1").get("value"));
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "Switch mouse tests",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_2").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_3").domNode, 500);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("on", reg.byId("dojox_mobile_Switch_2").get("value"));
+								doh.is("off", reg.byId("dojox_mobile_Switch_3").get("value"));
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "Switch mouse tests",
+						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt(dojo.query(".mblSwitchKnob", dijit.byId("dojox_mobile_Switch_0").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_4").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblSwitchKnob", dijit.byId("dojox_mobile_Switch_1").domNode)[0], 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_5").domNode, 500);
 							doh.robot.mouseClick({left: true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("on", dijit.byId("dojox_mobile_Switch_0").get("value"));
-								doh.is("off", dijit.byId("dojox_mobile_Switch_1").get("value"));
+								doh.is("on", reg.byId("dojox_mobile_Switch_4").get("value"));
+								doh.is("off", reg.byId("dojox_mobile_Switch_5").get("value"));
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "Switch mouse tests",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_6").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_7").domNode, 500);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("on", reg.byId("dojox_mobile_Switch_6").get("value"));
+								doh.is("off", reg.byId("dojox_mobile_Switch_7").get("value"));
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "Switch mouse tests",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_8").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_9").domNode, 500);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("on", reg.byId("dojox_mobile_Switch_8").get("value"));
+								doh.is("off", reg.byId("dojox_mobile_Switch_9").get("value"));
 							}), 500);
 							return d;
 						}
 					}
 				]);
-
 				doh.run();
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/Switch2.html b/dojox/mobile/tests/robot/Switch2.html
index aba8a98..df59dee 100644
--- a/dojox/mobile/tests/robot/Switch2.html
+++ b/dojox/mobile/tests/robot/Switch2.html
@@ -10,7 +10,7 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- functions to help test -->
 		<!-- script type="text/javascript" src="../helpers.js"></script -->
@@ -19,32 +19,109 @@
 			dojo.require("dijit.robotx");
 
 			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_Android-Switch.html");
-
+				doh.robot.initRobot("../test_Switch.html?theme=Android");
+				var reg=null;
 				doh.register("dojox.mobile.Switch mouse tests", [
 					{
 						name: "Switch mouse tests",
-						timeout: 4000,
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							reg = dojo.global.dijit.registry;
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_0").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_1").domNode, 500);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("on", reg.byId("dojox_mobile_Switch_0").get("value"));
+								doh.is("off", reg.byId("dojox_mobile_Switch_1").get("value"));
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "Switch mouse tests",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_2").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_3").domNode, 500);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("on", reg.byId("dojox_mobile_Switch_2").get("value"));
+								doh.is("off", reg.byId("dojox_mobile_Switch_3").get("value"));
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "Switch mouse tests",
+						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt(dojo.query(".mblSwitchKnob", dijit.byId("dojox_mobile_Switch_0").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_4").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblSwitchKnob", dijit.byId("dojox_mobile_Switch_1").domNode)[0], 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_5").domNode, 500);
 							doh.robot.mouseClick({left: true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("on", dijit.byId("dojox_mobile_Switch_0").get("value"));
-								doh.is("off", dijit.byId("dojox_mobile_Switch_1").get("value"));
+								doh.is("on", reg.byId("dojox_mobile_Switch_4").get("value"));
+								doh.is("off", reg.byId("dojox_mobile_Switch_5").get("value"));
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "Switch mouse tests",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_6").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_7").domNode, 500);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("on", reg.byId("dojox_mobile_Switch_6").get("value"));
+								doh.is("off", reg.byId("dojox_mobile_Switch_7").get("value"));
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "Switch mouse tests",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_8").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_Switch_9").domNode, 500);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("on", reg.byId("dojox_mobile_Switch_8").get("value"));
+								doh.is("off", reg.byId("dojox_mobile_Switch_9").get("value"));
 							}), 500);
 							return d;
 						}
 					}
 				]);
-
 				doh.run();
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/TabBar.html b/dojox/mobile/tests/robot/TabBar.html
index ae617b0..d8d5347 100644
--- a/dojox/mobile/tests/robot/TabBar.html
+++ b/dojox/mobile/tests/robot/TabBar.html
@@ -10,7 +10,7 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- functions to help test -->
 		<!-- script type="text/javascript" src="../helpers.js"></script -->
@@ -20,37 +20,117 @@
 			dojo.require("dojox.mobile.TabBar");
 
 			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_iPhone-TabBar.html");
+				doh.robot.initRobot("../test_TabBar.html");
 
 				doh.register("dojox.mobile.TabBar mouse tests", [
 					{
 						name: "TabBar mouse tests",
-						timeout: 15000,
+						timeout: 100000,
 						runTest: function(){
 							var d = new doh.Deferred();
+							var reg = dojo.global.dijit.registry;
 							
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[1], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_1").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_0").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_2").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_3").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_4").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_5").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_6").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_7").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_8").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_ToolBarButton_0").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
 
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[2], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_9").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_10").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_11").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_12").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_13").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_14").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[1], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_15").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_16").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_17").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_18").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_19").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_20").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[2], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_21").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_22").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_23").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_24").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_25").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_26").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_27").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_28").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_29").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_30").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_31").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_32").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_33").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_34").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_35").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_36").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_37").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_38").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.assertEqual("none",  dijit.byId("view1").srcNodeRef.style.display);
-								doh.assertEqual("none",  dijit.byId("view2").srcNodeRef.style.display);
-								doh.assertEqual("",  dijit.byId("view3").srcNodeRef.style.display);
+								doh.assertTrue(dojo.hasClass(reg.byId("dojox_mobile_TabBarButton_2").domNode, "mblTabBarButtonSelected"), "id =" + "dojox_mobile_TabBarButton_2");
+								doh.assertTrue(dojo.hasClass(reg.byId("dojox_mobile_TabBarButton_5").domNode, "mblTabBarButtonSelected"), "id =" + "dojox_mobile_TabBarButton_5");
+								doh.assertTrue(dojo.hasClass(reg.byId("dojox_mobile_TabBarButton_8").domNode, "mblTabBarButtonSelected"), "id =" + "dojox_mobile_TabBarButton_5");
+								doh.assertTrue(dojo.hasClass(reg.byId("dojox_mobile_TabBarButton_17").domNode, "mblTabBarButtonSelected"), "id =" + "dojox_mobile_TabBarButton_5");
+								doh.assertTrue(dojo.hasClass(reg.byId("dojox_mobile_TabBarButton_38").domNode, "mblTabBarButtonSelected"), "id =" + "dojox_mobile_TabBarButton_38");
 							}), 1000);
 
 							return d;
@@ -62,4 +142,5 @@
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/TabBar2.html b/dojox/mobile/tests/robot/TabBar2.html
index 8cfa227..410b86b 100644
--- a/dojox/mobile/tests/robot/TabBar2.html
+++ b/dojox/mobile/tests/robot/TabBar2.html
@@ -10,7 +10,7 @@
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- functions to help test -->
 		<!-- script type="text/javascript" src="../helpers.js"></script -->
@@ -20,37 +20,117 @@
 			dojo.require("dojox.mobile.TabBar");
 
 			dojo.addOnLoad(function(){
-				doh.robot.initRobot("../test_Android-TabBar.html");
+				doh.robot.initRobot("../test_TabBar.html?theme=Android");
 
 				doh.register("dojox.mobile.TabBar mouse tests", [
 					{
 						name: "TabBar mouse tests",
-						timeout: 15000,
+						timeout: 100000,
 						runTest: function(){
 							var d = new doh.Deferred();
+							var reg = dojo.global.dijit.registry;
 							
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[1], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_1").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_0").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_2").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_3").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_4").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_5").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_6").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_7").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_8").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_ToolBarButton_0").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
 
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[2], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_9").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_10").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_11").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_0").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_12").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_13").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_14").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[1], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_15").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_16").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_17").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[0], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_18").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_19").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_20").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.mouseMoveAt(dojo.query(".mblTabBarButtonAnchor", dijit.byId("dojox_mobile_TabBar_1").domNode)[2], 1000);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_21").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_22").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_23").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_24").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_25").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_26").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_27").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_28").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_29").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_30").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_31").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_32").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_33").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_34").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_35").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_36").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_37").domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(reg.byId("dojox_mobile_TabBarButton_38").domNode, 1000);
 							doh.robot.mouseClick({left: true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.assertEqual("none",  dijit.byId("view1").srcNodeRef.style.display);
-								doh.assertEqual("none",  dijit.byId("view2").srcNodeRef.style.display);
-								doh.assertEqual("",  dijit.byId("view3").srcNodeRef.style.display);
+								doh.assertTrue(dojo.hasClass(reg.byId("dojox_mobile_TabBarButton_2").domNode, "mblTabBarButtonSelected"), "id =" + "dojox_mobile_TabBarButton_2");
+								doh.assertTrue(dojo.hasClass(reg.byId("dojox_mobile_TabBarButton_5").domNode, "mblTabBarButtonSelected"), "id =" + "dojox_mobile_TabBarButton_5");
+								doh.assertTrue(dojo.hasClass(reg.byId("dojox_mobile_TabBarButton_8").domNode, "mblTabBarButtonSelected"), "id =" + "dojox_mobile_TabBarButton_5");
+								doh.assertTrue(dojo.hasClass(reg.byId("dojox_mobile_TabBarButton_17").domNode, "mblTabBarButtonSelected"), "id =" + "dojox_mobile_TabBarButton_5");
+								doh.assertTrue(dojo.hasClass(reg.byId("dojox_mobile_TabBarButton_38").domNode, "mblTabBarButtonSelected"), "id =" + "dojox_mobile_TabBarButton_38");
 							}), 1000);
 
 							return d;
@@ -62,4 +142,5 @@
 			});
 		</script>
 	</head>
+	<body />
 </html>
diff --git a/dojox/mobile/tests/robot/Transitions.html b/dojox/mobile/tests/robot/Transitions.html
new file mode 100644
index 0000000..53ddcba
--- /dev/null
+++ b/dojox/mobile/tests/robot/Transitions.html
@@ -0,0 +1,170 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>runner.robot Transitions Test</title>
+
+		<style>
+			@import "../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			require([
+				"dojo/_base/kernel",
+				"dojo/ready", // dojo.ready
+				"doh/runner",	//doh functions
+				"dijit/registry",  // dijit.registry.byId
+				"dojo/_base/connect",
+				"dijit/robotx"
+			], function(kernel, ready, runner, registry, connect){
+				ready(function(){
+
+					runner.robot.initRobot("../test_transition-connect.html");
+					var reg = null;
+					var seq = [];
+
+
+					runner.register("dojox.mobile.Transitions", [
+						{
+							name: "slideIn",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+								reg = kernel.global.dijit.registry;
+
+								connect.connect(reg.byId("view1"), "onBeforeTransitionOut", null, function(moveTo, dir, transition, context, method){
+									seq.push("onBeforeTransitionOut1,"+moveTo+","+dir+","+transition);
+								});
+								connect.connect(reg.byId("view1"), "onBeforeTransitionIn", null, function(moveTo, dir, transition, context, method){
+									seq.push("onBeforeTransitionIn1,"+moveTo+","+dir+","+transition);
+								});
+								connect.connect(reg.byId("view1"), "onAfterTransitionOut", null, function(moveTo, dir, transition, context, method){
+									seq.push("onAfterTransitionOut1,"+moveTo+","+dir+","+transition);
+								});
+								connect.connect(reg.byId("view1"), "onAfterTransitionIn", null, function(moveTo, dir, transition, context, method){
+									seq.push("onAfterTransitionIn1,"+moveTo+","+dir+","+transition);
+								});
+
+								connect.connect(reg.byId("view2"), "onBeforeTransitionOut", null, function(moveTo, dir, transition, context, method){
+									seq.push("onBeforeTransitionOut2,"+moveTo+","+dir+","+transition);
+								});
+								connect.connect(reg.byId("view2"), "onBeforeTransitionIn", null, function(moveTo, dir, transition, context, method){
+									seq.push("onBeforeTransitionIn2,"+moveTo+","+dir+","+transition);
+								});
+								connect.connect(reg.byId("view2"), "onAfterTransitionOut", null, function(moveTo, dir, transition, context, method){
+									seq.push("onAfterTransitionOut2,"+moveTo+","+dir+","+transition);
+								});
+								connect.connect(reg.byId("view2"), "onAfterTransitionIn", null, function(moveTo, dir, transition, context, method){
+									seq.push("onAfterTransitionIn2,"+moveTo+","+dir+","+transition);
+								});
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_0").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual(["onBeforeTransitionOut1,view2,1,slide",
+														"onBeforeTransitionIn2,view2,1,slide",
+														"onAfterTransitionOut1,view2,1,slide",
+														"onAfterTransitionIn2,view2,1,slide"], seq);
+								}), 1500);
+								return d;
+							}
+						},
+						{
+							name: "slideOut",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								seq = [];
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ToolBarButton_0").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+								
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual(["onBeforeTransitionOut2,view1,-1,slide",
+														"onBeforeTransitionIn1,view1,-1,slide",
+														"onAfterTransitionOut2,view1,-1,slide",
+														"onAfterTransitionIn1,view1,-1,slide"], seq);
+								}), 1500);
+								return d;
+							}
+						},
+						{
+							name: "flipIn",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								seq = [];
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_1").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual(["onBeforeTransitionOut1,view2,1,flip",
+														"onBeforeTransitionIn2,view2,1,flip",
+														"onAfterTransitionOut1,view2,1,flip",
+														"onAfterTransitionIn2,view2,1,flip"], seq);
+								}), 1500);
+								return d;
+							}
+						},
+						{
+							name: "slideOut2",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								seq = [];
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ToolBarButton_0").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual(["onBeforeTransitionOut2,view1,-1,slide",
+														"onBeforeTransitionIn1,view1,-1,slide",
+														"onAfterTransitionOut2,view1,-1,slide",
+														"onAfterTransitionIn1,view1,-1,slide"], seq);
+								}), 1500);
+								return d;
+							}
+						},
+						{
+							name: "fadeIn",
+							timeout: 50000,
+							runTest: function(){
+								var d = new runner.Deferred();
+
+								seq = [];
+
+								runner.robot.mouseMoveAt(reg.byId("dojox_mobile_ListItem_2").domNode, 1000);
+								runner.robot.mouseClick({left: true}, 500);
+
+								runner.robot.sequence(d.getTestCallback(function(){
+									runner.assertEqual(["onBeforeTransitionOut1,view2,1,fade",
+														"onBeforeTransitionIn2,view2,1,fade",
+														"onAfterTransitionOut1,view2,1,fade",
+														"onAfterTransitionIn2,view2,1,fade"], seq);
+								}), 2000);
+								return d;
+							}
+						},
+						{
+							name: "init",
+							runTest: function(){
+								runner.assertEqual(true, kernel.global._testInitCallback);
+							}
+						}
+					]);
+
+					runner.run();
+				});
+			});
+		</script>
+	</head>
+	<body />
+</html>
diff --git a/dojox/mobile/tests/robot/index.html b/dojox/mobile/tests/robot/index.html
new file mode 100644
index 0000000..ae88c96
--- /dev/null
+++ b/dojox/mobile/tests/robot/index.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<title>dojox.mobile</title>
+	</head>
+	<body>
+		<a href="Animation.html">Animation.html</a><br>
+		<a href="Animation2.html">Animation2.html</a><br>
+		<a href="ButtonList.html">ButtonList.html</a><br>
+		<a href="ButtonList2.html">ButtonList2.html</a><br>
+		<a href="Flippable.html">Flippable.html</a><br>
+		<a href="Icon.html">Icon.html</a><br>
+		<a href="Icon2.html">Icon2.html</a><br>
+		<a href="ListItem.html">ListItem.html</a><br>
+		<a href="ScrollableView.html">ScrollableView.html</a><br>
+		<a href="ScrollableView2.html">ScrollableView2.html</a><br>
+		<a href="ScrollableView3.html">ScrollableView3.html</a><br>
+		<a href="Settings.html">Settings.html</a><br>
+		<a href="Switch.html">Switch.html</a><br>
+		<a href="Switch2.html">Switch2.html</a><br>
+		<a href="TabBar.html">TabBar.html</a><br>
+		<a href="TabBar2.html">TabBar2.html</a><br>
+		<hr>
+		<a href="runTests.html">runTests.html</a><br>
+	
+
+</body></html>
\ No newline at end of file
diff --git a/dojox/mobile/tests/robot/module.js b/dojox/mobile/tests/robot/module.js
index 2db94d1..0cee177 100644
--- a/dojox/mobile/tests/robot/module.js
+++ b/dojox/mobile/tests/robot/module.js
@@ -3,8 +3,9 @@ dojo.provide("dojox.mobile.tests.robot.module");
 try{
 	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?"),
 		test_robot = true;
-
+		
 	if(test_robot){
+		doh.registerUrl("dojox.mobile.tests.robot.RoundRectList", dojo.moduleUrl("dojox.mobile", "tests/robot/RoundRectListConnect.html"), 999999);
 		doh.registerUrl("dojox.mobile.tests.robot.ButtonList", dojo.moduleUrl("dojox.mobile", "tests/robot/ButtonList.html"), 999999);
 		doh.registerUrl("dojox.mobile.tests.robot.ButtonList", dojo.moduleUrl("dojox.mobile", "tests/robot/ButtonList2.html"), 999999);
 		doh.registerUrl("dojox.mobile.tests.robot.switch", dojo.moduleUrl("dojox.mobile", "tests/robot/Switch.html"), 999999);
@@ -12,12 +13,12 @@ try{
 		doh.registerUrl("dojox.mobile.tests.robot.ListItem", dojo.moduleUrl("dojox.mobile", "tests/robot/ListItem.html"), 999999);
 		doh.registerUrl("dojox.mobile.tests.robot.tabBar", dojo.moduleUrl("dojox.mobile", "tests/robot/TabBar.html"), 999999);
 		doh.registerUrl("dojox.mobile.tests.robot.tabBar", dojo.moduleUrl("dojox.mobile", "tests/robot/TabBar2.html"), 999999);
-		doh.registerUrl("dojox.mobile.tests.robot.IconItem", dojo.moduleUrl("dojox.mobile", "tests/robot/Icon.html",999999));
-		doh.registerUrl("dojox.mobile.tests.robot.IconItem", dojo.moduleUrl("dojox.mobile", "tests/robot/Icon2.html",999999));
+//		doh.registerUrl("dojox.mobile.tests.robot.IconItem", dojo.moduleUrl("dojox.mobile", "tests/robot/Icon.html",999999));
+//		doh.registerUrl("dojox.mobile.tests.robot.IconItem", dojo.moduleUrl("dojox.mobile", "tests/robot/Icon2.html",999999));
 		doh.registerUrl("dojox.mobile.tests.robot.Animation", dojo.moduleUrl("dojox.mobile", "tests/robot/Animation.html"),999999);
 		if(!dojo.isSafari) {
 			doh.registerUrl("dojox.mobile.tests.robot.Settings", dojo.moduleUrl("dojox.mobile", "tests/robot/Settings.html"),999999);
-			doh.registerUrl("dojox.mobile.tests.robot.Flippable", dojo.moduleUrl("dojox.mobile", "tests/robot/Flippable.html"),999999);
+//			doh.registerUrl("dojox.mobile.tests.robot.Flippable", dojo.moduleUrl("dojox.mobile", "tests/robot/Flippable.html"),999999);
 			doh.registerUrl("dojox.mobile.tests.robot.Scrollable", dojo.moduleUrl("dojox.mobile", "tests/robot/ScrollableView.html"),999999);
 			doh.registerUrl("dojox.mobile.tests.robot.Scrollable", dojo.moduleUrl("dojox.mobile", "tests/robot/ScrollableView2.html"),999999);
 			doh.registerUrl("dojox.mobile.tests.robot.Scrollable", dojo.moduleUrl("dojox.mobile", "tests/robot/ScrollableView3.html"),999999);
diff --git a/dojox/mobile/tests/simpleApp/index.html b/dojox/mobile/tests/simpleApp/index.html
index 213c094..abedf6a 100644
--- a/dojox/mobile/tests/simpleApp/index.html
+++ b/dojox/mobile/tests/simpleApp/index.html
@@ -11,7 +11,7 @@
 			text-decoration: none;
 		}
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false"></script>
     
 		<script language="JavaScript" type="text/javascript">
 			dojo.require("dojox.mobile.app");
diff --git a/dojox/mobile/tests/simpleListApp/index.html b/dojox/mobile/tests/simpleListApp/index.html
index 5640c38..8924aa0 100644
--- a/dojox/mobile/tests/simpleListApp/index.html
+++ b/dojox/mobile/tests/simpleListApp/index.html
@@ -11,7 +11,7 @@
 			text-decoration: none;
 		}
 		</style>
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="parseOnLoad: false"></script>
     
 		<script language="JavaScript" type="text/javascript">
 			dojo.require("dojox.mobile.app");
diff --git a/dojox/mobile/tests/templates/Button1.html b/dojox/mobile/tests/templates/Button1.html
new file mode 100644
index 0000000..883ed10
--- /dev/null
+++ b/dojox/mobile/tests/templates/Button1.html
@@ -0,0 +1 @@
+<button class="${baseClass}" data-dojo-attach-point="containerNode"></button>
diff --git a/dojox/mobile/tests/templates/CheckBox1.html b/dojox/mobile/tests/templates/CheckBox1.html
new file mode 100644
index 0000000..45d375d
--- /dev/null
+++ b/dojox/mobile/tests/templates/CheckBox1.html
@@ -0,0 +1,3 @@
+<input type="checkbox" 
+	class="mblCheckBox mblCheckBoxChecked" value="${value}" tabindex="0" 
+	style="-webkit-user-select: none;" aria-checked="true">
diff --git a/dojox/mobile/tests/templates/Heading1.html b/dojox/mobile/tests/templates/Heading1.html
new file mode 100644
index 0000000..8c426f3
--- /dev/null
+++ b/dojox/mobile/tests/templates/Heading1.html
@@ -0,0 +1,17 @@
+<div class="mblHeading mblHeadingCenterTitle">
+	<span data-dojo-type="dojox/mobile/ToolBarButton" arrow="left" 
+		defaultColor="mblColorBlue" selColor="mblColorPink">MMMM</span>
+	<span data-dojo-type="dojox/mobile/ToolBarButton">MMMM</span>
+	<span data-dojo-type="dojox/mobile/ToolBarButton" 
+		data-dojo-props="arrow:'right'">MMMM</span>
+	<span data-dojo-type="dojox/mobile/ToolBarButton">MMMM</span>
+	<span data-dojo-type="dojox/mobile/ToolBarButton" 
+		data-dojo-props="icon:'mblDomButtonWhitePlus'"
+		style="float:right;"></span>
+	<span class="mblHeadingSpanTitle" style=""
+		data-dojo-attach-point="labelNode">
+	</span>
+	<div class="mblHeadingDivTitle"
+		data-dojo-attach-point="labelDivNode">
+	</div>
+</span>
diff --git a/dojox/mobile/tests/templates/Heading2.html b/dojox/mobile/tests/templates/Heading2.html
new file mode 100644
index 0000000..c3b6feb
--- /dev/null
+++ b/dojox/mobile/tests/templates/Heading2.html
@@ -0,0 +1,20 @@
+<div class="mblHeading mblHeadingCenterTitle">
+	<span data-dojo-type="dojox/mobile/ToolBarButton"
+		data-dojo-attach-point="backButton"
+		data-dojo-props="arrow: 'left', back: true, transitionDir: -1">
+	</span>
+	<ul data-dojo-type="dojox/mobile/TabBar"
+		style="float:right;"
+		data-dojo-props="barType:'segmentedControl', selectOne:false">
+		<li data-dojo-type="dojox/mobile/TabBarButton" 
+			data-dojo-props="icon:'mblDomButtonWhiteUpArrow'"></li>
+		<li data-dojo-type="dojox/mobile/TabBarButton" 
+			data-dojo-props="icon:'mblDomButtonWhiteDownArrow'"></li>
+	</ul>
+	<span class="mblHeadingSpanTitle" style=""
+		data-dojo-attach-point="labelNode">
+	</span>
+	<div class="mblHeadingDivTitle"
+		data-dojo-attach-point="labelDivNode">
+	</div>
+</div>
diff --git a/dojox/mobile/tests/templates/ListItem1.html b/dojox/mobile/tests/templates/ListItem1.html
new file mode 100644
index 0000000..5a28f7e
--- /dev/null
+++ b/dojox/mobile/tests/templates/ListItem1.html
@@ -0,0 +1,5 @@
+<div>
+	Template: <code>ListItem1.html</code><br>
+	Pure HTML (no widget). The template embeds text from the label property of the ListItem: 
+	<div data-dojo-attach-point="labelNode"></div>
+</div>
diff --git a/dojox/mobile/tests/templates/ListItem2.html b/dojox/mobile/tests/templates/ListItem2.html
new file mode 100644
index 0000000..c6d2ed5
--- /dev/null
+++ b/dojox/mobile/tests/templates/ListItem2.html
@@ -0,0 +1,16 @@
+<div>
+	<div data-dojo-type="dojox/mobile/RoundRect" shadow="true">
+		Template: <code>ListItem2.html.</code><br>
+		Contains two <code>RoundRect</code> widgets.
+		The template embeds text from the label property of the ListItem:
+		<div data-dojo-attach-point="labelNode"></div>
+	</div>
+	<div data-dojo-type="dojox/mobile/RoundRect" shadow="true">
+		<p>
+		<img src="images/tab-icon-33h.png" align="left" width="60" height="60">
+		Dojo Mobile is a world class HTML5 mobile JavaScript framework that enables 
+		rapid development of mobile web applications with a native look and feel on 
+		modern webkit-enabled mobile devices.
+		</p>
+	</div>
+</div>
diff --git a/dojox/mobile/tests/templates/ListItem3.html b/dojox/mobile/tests/templates/ListItem3.html
new file mode 100644
index 0000000..9255cce
--- /dev/null
+++ b/dojox/mobile/tests/templates/ListItem3.html
@@ -0,0 +1,10 @@
+<div>
+	Template: <code>ListItem3.html</code>. Contains a <code>dojox/mobile/TabBar</code>.
+	<ul data-dojo-type="dojox/mobile/TabBar" 
+		data-dojo-props="barType:'segmentedControl', selectOne:false" style="float:right;">
+		<li data-dojo-type="dojox/mobile/TabBarButton" 
+			data-dojo-props="icon:'mblDomButtonWhiteUpArrow'"></li>
+		<li data-dojo-type="dojox/mobile/TabBarButton" 
+			data-dojo-props="icon:'mblDomButtonWhiteDownArrow'"></li>
+	</ul>
+</div>
diff --git a/dojox/mobile/tests/templates/RadioButton1.html b/dojox/mobile/tests/templates/RadioButton1.html
new file mode 100644
index 0000000..a649d3c
--- /dev/null
+++ b/dojox/mobile/tests/templates/RadioButton1.html
@@ -0,0 +1,2 @@
+<input type="radio" value="Small" class="mblRadioButton mblRadioButtonChecked" 
+	tabindex="0" style="-webkit-user-select: none;" aria-checked="true">
diff --git a/dojox/mobile/tests/templates/Slider1.html b/dojox/mobile/tests/templates/Slider1.html
new file mode 100644
index 0000000..b848194
--- /dev/null
+++ b/dojox/mobile/tests/templates/Slider1.html
@@ -0,0 +1,20 @@
+<div class="mblSlider mblSliderH" tabindex="0"
+	aria-valuenow="${value}"
+	data-dojo-attach-point="focusNode">
+	<input data-dojo-attach-point="valueNode"
+		type="hidden" value="${value}">
+	<div data-dojo-attach-point="relativeParent"
+		style="position: relative; height: 100%; width: 100%;">
+		<div data-dojo-attach-point="progressBar"
+			style="position: absolute; left: 0px; width: 100%;" 
+			class="mblSliderProgressBar mblSliderTransition">
+		</div>
+		<div data-dojo-attach-point="touchBox"
+			style="position: absolute;" class="mblSliderTouchBox">
+		</div>
+		<div data-dojo-attach-point="handle"
+			style="position: absolute; left: 100%;" 
+			class="mblSliderHandle mblSliderTransition">
+		</div>
+	</div>
+</div>
diff --git a/dojox/mobile/tests/templates/Switch1.html b/dojox/mobile/tests/templates/Switch1.html
new file mode 100644
index 0000000..44dc969
--- /dev/null
+++ b/dojox/mobile/tests/templates/Switch1.html
@@ -0,0 +1,14 @@
+<span class="mblSwitch mblSwDefaultShape mblSwitchOn" tabindex="0" >
+	<div class="mblSwitchInner" data-dojo-attach-point="inner">
+		<div class="mblSwitchBg mblSwitchBgLeft"
+			data-dojo-attach-point="left">
+			<div class="mblSwitchText mblSwitchTextLeft">ON</div>
+		</div>
+		<div class="mblSwitchBg mblSwitchBgRight" style="display: none;"
+			data-dojo-attach-point="right">
+			<div class="mblSwitchText mblSwitchTextRight">OFF</div>
+		</div>
+		<div class="mblSwitchKnob" data-dojo-attach-point="knob"></div>
+		<input type="hidden" value="on" data-dojo-attach-point="input">
+	</div>
+</span>
diff --git a/dojox/mobile/tests/templates/ToggleButton1.html b/dojox/mobile/tests/templates/ToggleButton1.html
new file mode 100644
index 0000000..40524eb
--- /dev/null
+++ b/dojox/mobile/tests/templates/ToggleButton1.html
@@ -0,0 +1,6 @@
+<span>
+	<button class="${baseClass}" tabindex="0" 
+		style="-webkit-user-select: none;" aria-pressed="true"
+		data-dojo-attach-point="containerNode">
+	</button>
+</span>
diff --git a/dojox/mobile/tests/templates/View1.html b/dojox/mobile/tests/templates/View1.html
new file mode 100644
index 0000000..87b0afc
--- /dev/null
+++ b/dojox/mobile/tests/templates/View1.html
@@ -0,0 +1,43 @@
+<div>
+	<div data-dojo-type="dojox/mobile/Heading"
+		data-dojo-props="label: 'Templated View'">
+	</div>
+	<ul data-dojo-type="dojox/mobile/RoundRectList">
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props='icon:"images/i-icon-1.png"'>
+				Apple
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props='icon:"images/i-icon-2.png"'>
+				Banana
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props='icon:"images/i-icon-3.png"'>
+				Cherry
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props='icon:"images/i-icon-4.png"'>
+				Grape
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props='icon:"images/i-icon-5.png"'>
+				Kiwi
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props='icon:"images/i-icon-6.png"'>
+				Lemon
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props='icon:"images/i-icon-7.png"'>
+				Melon
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props='icon:"images/i-icon-8.png"'>
+				Orange
+			</li>
+			<li data-dojo-type="dojox/mobile/ListItem" 
+				data-dojo-props='icon:"images/i-icon-9.png"'>
+				Peach
+			</li>
+		</ul>
+</div>
diff --git a/dojox/mobile/tests/test_Accessibility_Support.html b/dojox/mobile/tests/test_Accessibility_Support.html
deleted file mode 100644
index 552e343..0000000
--- a/dojox/mobile/tests/test_Accessibility_Support.html
+++ /dev/null
@@ -1,116 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Accessibility</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-		<link href="../themes/common/domButtons.css" rel="stylesheet">
-		<link href="../themes/iphone/IconContainer.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<style>
-			.box {
-				border: 1px solid #A7C0E0;
-				width: 300px;
-				height: 250px;
-				background-image: url(images/widget-bg.png);
-				background-repeat: no-repeat;
-				background-color: white;
-			}
-		</style>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-			dojo.require("dojox.mobile.IconContainer");
-			dojo.addOnLoad(function(){
-				var btn1 = dijit.byId("btn1");
-				btn1.connect(btn1.domNode, "onclick", function(){
-					console.log(this.label + " button was clicked");
-				});
-			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="item1" dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" alt="Orangy Icon" rightText="Go To" moveTo="view2">
-					Heading Sample
-				</li>
-				<li id="item2" dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" alt="Green Icon" rightText="Go To" moveTo="view3">
-					ListItem Sample
-				</li>
-				<li id="item3" dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="Go To" moveTo="view4">
-					Icon Sample
-				</li>
-			</ul>
-		</div>
-
-		<div id="view2" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" tabindex="0">
-				<div id="btn1" dojoType="dojox.mobile.ToolBarButton" title="Edit" role="button" tabindex="0">Edit</div>
-				<div id="btn2" dojoType="dojox.mobile.ToolBarButton" title="+" role="button"  tabindex="0" class="mblDomButtonWhitePlus" style="float:right;" onclick="console.log('+ was clicked')"></div>
-				World Clock
-			</h1><br>
-
-
-			<h1 dojoType="dojox.mobile.Heading" tabindex="0">
-				<div dojoType="dojox.mobile.ToolBarButton" title="New" role="button" tabindex="0" toggle="true">New</div>
-				<div dojoType="dojox.mobile.ToolBarButton" title="Toggle" role="button" tabindex="0" toggle="true">Toggle</div>
-				<div dojoType="dojox.mobile.ToolBarButton" title="Information" role="button" tabindex="0" alt="Information" icon="images/a-icon-12.png" moveTo="view3"></div>
-				<div dojoType="dojox.mobile.ToolBarButton" title="Hint" role="button" tabindex="0" alt="Hint" icon="images/tab-icons.png" iconPos="29,0,29,29" moveTo="view3"></div>
-				<div dojoType="dojox.mobile.ToolBarButton" title="Search" role="button" tabindex="0" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
-			</h1><br>
-
-			<h1 dojoType="dojox.mobile.Heading" back="Inbox" backProp='{className: "mblArrowButton", role:"button", title:"Inbox", tabindex:"0"}' moveTo="view1" tabindex="0">
-				<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:right;margin-right:6px;">
-					<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" title="Up" role="button" tabindex="0" selectOne="false"></li>
-					<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteDownArrow" title="Down" role="button" tabindex="0" selectOne="false"></li>
-				</ul>
-				1 of 10
-			</h1><br>
-
-			<h1 dojoType="dojox.mobile.Heading" back="Top" backProp='{className: "mblArrowButton", role:"button", title:"Top", tabindex:"0"}' label="Inbox(32)" tabindex="0">
-				<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" title="Search" role="button" tabindex="0" style="float:right;"></div>
-				<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteUpArrow" title="Up" role="button" tabindex="0" style="float:right;"></div>
-				<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteDownArrow" title="Down" role="button" tabindex="0" style="float:right;"></div>
-			</h1><br>
-
-
-		</div>
-
-		<div id="view3" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading">Settings</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" tabindex="0">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch" prop='{tabindex:"0"}'></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="mac" moveTo="view1" tabindex="0">
-					Wi-Fi
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="AcmePhone" moveTo="view1" tabindex="0">
-					Carrier
-				</li>
-			</ul>
-		</div>
-
-		<div id="view4" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" backProp='{className: "mblArrowButton", role:"button", title:"Top", tabindex:"0"}' moveTo="view1">Icon Container</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="app1" icon="images/icon-1.png" lazy="true" closeBtnProp='{title:"Close", role:"button"}'><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app2" icon="images/icon-1.png" lazy="true" closeBtnProp='{title:"Close", role:"button"}'><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app3" icon="images/icon-1.png" lazy="true" closeBtnProp='{title:"Close", role:"button"}'><div class="box"></div></li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Accordion-demo.html b/dojox/mobile/tests/test_Accordion-demo.html
new file mode 100644
index 0000000..f73dd0b
--- /dev/null
+++ b/dojox/mobile/tests/test_Accordion-demo.html
@@ -0,0 +1,171 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Accordion</title>
+
+	<link href="../themes/common/dijit/dijit.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonBlackRightArrow16.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonWhiteDownArrow16.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Accordion','TabBar','dijit.Calendar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Accordion",
+			"dojox/mobile/ContentPane",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style type="text/css">
+		html,body{
+			height: 100%;
+		}
+		html:not(.windows_theme) .myPane {
+			background-image: -webkit-gradient(linear, left top, left bottom, from(#dcdcdc), to(#FFFFFF));
+			font-family: Times New Roman, Helvetica;
+			color: black;
+		}
+		.windows_theme .mblAccordionPane {
+			background-color: transparent !important;
+		}
+		.windows_theme .mblScrollableViewContainer > div {
+			color: white !important;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="group1" data-dojo-type="dojox.mobile.View">
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", fixed:"top"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view1"'>Fixed</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view2", selected:true'>Multi</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view3"'>Single</li>
+		</ul>
+
+		<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+			<div data-dojo-type="dojox.mobile.Accordion" data-dojo-props='fixedHeight:true, roundRect:true' style="height:380px;">
+				<div data-dojo-type="dojox.mobile.ScrollableView" style="background-color:white"
+					data-dojo-props='label:"ScrollableView", height:"inherit", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", propagatable:false, appBars:false'>
+					<div style="padding:10px;color:black;">
+						A<br>B<br>C<br>D<br>E<br>F<br>G<br>H<br>I<br>J<br>K<br>L<br>M<br>N<br>O<br>P<br>Q<br>R<br>S<br>T<br>U<br>V<br>W<br>X<br>Y<br>Z
+					</div>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"External Content", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16", href:"data/fragment1.html"'>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"RoundRectList", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"'>
+					<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"images/tab-icon-11h.png"'>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u1space
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u2space
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							Wi-Fi
+						</li>
+					</ul>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Dojo", icon1:"mblDomButtonBlackRightArrow16", icon2:"mblDomButtonWhiteDownArrow16"' class="myPane">
+					<div style="padding:10px">
+						<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+						<div style="border-top: 1px dashed gray;margin: 20px"></div>
+						<img alt="" src="images/dojo-logo1.png" style="float:left;margin-right:5px">
+						<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+					</div>
+				</div>
+			</div>
+		</div>
+
+		<div id="view2" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='selected:true'>
+			<div data-dojo-type="dojox.mobile.Accordion" data-dojo-props='iconBase:"images/icons16.png"'>
+				<div data-dojo-type="dojox.mobile.ScrollableView" style="background-color:white"
+					data-dojo-props='label:"ScrollableView", iconPos1:"16,16,16,16", height:"100px", propagatable:false, appBars:false'>
+					<div style="padding:10px;color:black;">
+						A<br>B<br>C<br>D<br>E<br>F<br>G<br>H<br>I<br>J<br>K<br>L<br>M<br>N<br>O<br>P<br>Q<br>R<br>S<br>T<br>U<br>V<br>W<br>X<br>Y<br>Z
+					</div>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"External Content", iconPos1:"16,32,16,16", href:"data/fragment1.html"'>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"RoundRectList", iconPos1:"16,48,16,16"'>
+					<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"images/tab-icon-11h.png"'>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u1space
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u2space
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							Wi-Fi
+						</li>
+					</ul>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Dojo", iconPos1:"32,16,16,16"' class="myPane">
+					<div style="padding:10px">
+						<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+						<div style="border-top: 1px dashed gray;margin: 20px"></div>
+						<img alt="" src="images/dojo-logo1.png" style="float:left;margin-right:5px">
+						<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+						<p>Dojo's powerful, lightweight core makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.</p>
+					</div>
+				</div>
+			</div>
+		</div>
+
+		<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">
+			<div data-dojo-type="dojox.mobile.Accordion" data-dojo-props='singleOpen:true'>
+				<div data-dojo-type="dojox.mobile.ScrollableView" style="background-color:white"
+					data-dojo-props='label:"ScrollableView", height:"100px", propagatable:false, appBars:false'>
+					<div style="padding:10px;color:black;">
+						A<br>B<br>C<br>D<br>E<br>F<br>G<br>H<br>I<br>J<br>K<br>L<br>M<br>N<br>O<br>P<br>Q<br>R<br>S<br>T<br>U<br>V<br>W<br>X<br>Y<br>Z
+					</div>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"External Content", href:"data/fragment1.html"'>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"RoundRectList"'>
+					<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"images/tab-icon-11h.png"'>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u1space
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							u2space
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+							Wi-Fi
+						</li>
+					</ul>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Dojo"' class="myPane">
+					<div style="padding:10px">
+						<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+						<div style="border-top: 1px dashed gray;margin: 20px"></div>
+						<img alt="" src="images/dojo-logo1.png" style="float:left;margin-right:5px">
+						<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+						<p>Dojo's powerful, lightweight core makes common tasks quicker and easier. Animate elements, manipulate the DOM, and query with easy CSS syntax, all without sacrificing performance.</p>
+					</div>
+				</div>
+				<div data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='label:"Calendar (Lazy)", lazy:true' height="304px">
+					<div style="padding:10px">
+						<div data-dojo-type="dijit.CalendarLite"></div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+
+	<div id="group2" data-dojo-type="dojox.mobile.ScrollableView">
+	  group2
+	</div>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", selected:true, moveTo:"group1"'>Group1</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"group2"'>Group2</li>
+	</ul>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Android-ButtonList.html b/dojox/mobile/tests/test_Android-ButtonList.html
deleted file mode 100644
index a24b92f..0000000
--- a/dojox/mobile/tests/test_Android-ButtonList.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-
-		<title>Button List</title>
-		<link href="../themes/android/base.css" rel="stylesheet">
-		<link href="../themes/common/domButtons/DomButtonCheckboxOn.css" rel="stylesheet">
-		<link href="../themes/common/domButtons/DomButtonCheckboxOff.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.ready(function(){
-				var ul = dojo.byId("list");
-				for(var i = 0, len = ul.childNodes.length; i < len; i++){
-					var li = ul.childNodes[i];
-					if(li.nodeType != 1 || li.tagName != "LI"){ continue; }
-					var w = dijit.byNode(li);
-					dojo.connect(w.rightIconNode, "onclick", btnClicked);
-				}
-			});
-			function btnClicked(e){
-				var listItem = dijit.getEnclosingWidget(e.currentTarget);
-				var btnDiv = listItem.rightIconNode.firstChild;
-				if(dojo.hasClass(btnDiv, "mblDomButtonCheckboxOn")){
-					listItem.set("btnClass", "mblDomButtonCheckboxOff");
-				}else if(dojo.hasClass(btnDiv, "mblDomButtonCheckboxOff")){
-					listItem.set("btnClass", "mblDomButtonCheckboxOn");
-				}
-			}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-	    <div id="settings" dojoType="dojox.mobile.View" selected="true">
-		    <h1 dojoType="dojox.mobile.Heading">Location & security settings</h1>
-		    <h2 class="mblHeading">My Location</h2>
-		    <ul id="list" dojoType="dojox.mobile.EdgeToEdgeList">
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" btnClass="mblDomButtonCheckboxOff">
-				    Use wireless networks
-				    <div class="mblListItemSubText">
-					    See location in applications (such as Maps) using wireless networks
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" btnClass="mblDomButtonCheckboxOn">
-				    Use GPS satellites
-				    <div class="mblListItemSubText">
-					    When locating, accurate to street level (uncheck to conserve battery)
-				    </div>
-			    </li>
-		    </ul>
-		    <h2 class="mblHeading">My Location</h2>
-		     <ul dojoType="dojox.mobile.EdgeToEdgeList">
-			    <li dojoType="dojox.mobile.ListItem">
-			       Set unlock pattern
-			    </li>
-		    </ul>
-	    </div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Android-EdgeToEdge.html b/dojox/mobile/tests/test_Android-EdgeToEdge.html
deleted file mode 100644
index a096bed..0000000
--- a/dojox/mobile/tests/test_Android-EdgeToEdge.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Edge to Edge</title>
-		<link href="../themes/android/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Settings</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-2-41x41.png">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-2-41x41.png" rightText="mac" moveTo="hello">
-					Wi-Fi
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-2-41x41.png" rightText="AcmePhone" moveTo="hello">
-					Carrier
-				</li>
-			</ul>
-		</div>
-
-		<div id="hello" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading">Hello</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="settings">
-					Hello
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="settings">
-					Carrier
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Android-EdgeToEdgeCategory.html b/dojox/mobile/tests/test_Android-EdgeToEdgeCategory.html
deleted file mode 100644
index 7201f86..0000000
--- a/dojox/mobile/tests/test_Android-EdgeToEdgeCategory.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Edge to Edge</title>
-		<link href="../themes/android/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Edge-to-Edge List</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">J</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem">
-					Jack Coleman
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					James Evans
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Jason Griffin
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">K</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem">
-					Karen Hughes
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Kelly Perry
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Kevin Rivera
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Android-Heading.html b/dojox/mobile/tests/test_Android-Heading.html
deleted file mode 100644
index 58f6ae9..0000000
--- a/dojox/mobile/tests/test_Android-Heading.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Heading</title>
-		<link href="../themes/android/base.css" rel="stylesheet">
-		<link href="../themes/android/TabBar.css" rel="stylesheet">
-		<link href="../themes/common/domButtons.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-			dojo.ready(function(){
-				var btn1 = dijit.byId("btn1");
-				btn1.connect(btn1.domNode, "onclick", function(){
-					console.log(this.label + " button was clicked");
-				});
-			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="general" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">General</h1>
-			<h1 dojoType="dojox.mobile.Heading" back="Long Button" moveTo="settings">Very Very Long Title May Not Be Displayed in the Narrow Space - Very Very Long Title May Not Be Displayed in the Narrow Space</h1>
-		</div>
-
-		<h3>Heading with buttons</h3>
-
-		<h1 dojoType="dojox.mobile.Heading" label="World Clock">
-			<div id="btn1" dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px;float:left">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;" onclick="console.log('+ was clicked')"></div>
-
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px;float:left;">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;"></div>
-			Alarm Clock
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Voice Memos">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Speaker" style="float:left"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Updates">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="News" back="Bookmarks" moveTo="bookmarks">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="New Folder" style="float:right;"></div>
-		</h1><br>
-
-
-		<div dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">New</div>
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">Toggle</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icon-18h.png" moveTo="view3" style="padding:0 10px"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icons.png" iconPos="29,0,29,29" moveTo="view3" style="padding:0 10px"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" moveTo="view3" style="float:right;"></div>
-		</div><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:left;margin-left:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px" selected="true">Catalog</li>
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px">Share</li>
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px">Download</li>
-			</ul>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" align="center">
-		  <table cellpadding="0" cellspacing="0" style="width:100%;"><tr>
-			<td><div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus"></div></td>
-			<td align="center"><div dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="margin:auto;">
-				<div dojoType="dojox.mobile.TabBarButton" selected="true" style="width:80px">Search</div>
-				<div dojoType="dojox.mobile.TabBarButton" style="width:80px">Directions</div>
-			</div></td>
-			<td align="right"><div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icon-15h.png" style="float:right;"></div></td>
-		  </tr></table>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Inbox" label="1 of 10">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:right;margin-right:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteDownArrow" selectOne="false"></li>
-			</ul>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Top" label="Inbox(32)">
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteUpArrow" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteDownArrow" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Inbox" label="1 of 10">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:right;margin-right:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteSearch" selectOne="false"></li>
-			</ul>
-		</h1><br>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Android-Icon.html b/dojox/mobile/tests/test_Android-Icon.html
deleted file mode 100755
index e17eaee..0000000
--- a/dojox/mobile/tests/test_Android-Icon.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon</title>
-		<link href="../themes/android/base.css" rel="stylesheet">
-		<link href="../themes/android/IconContainer.css" rel="stylesheet">
-
-		<style>
-			.box {
-				border: 1px solid #A7C0E0;
-				width: 300px;
-				height: 250px;
-				background-image: url(images/widget-bg.png);
-				background-repeat: no-repeat;
-				background-color: white;
-			}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="app1" icon="images/a-icon-3.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app2" icon="images/a-icon-3.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app3" icon="images/a-icon-3.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="moveTo" icon="images/a-icon-3.png" moveTo="about" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="href" icon="images/a-icon-3.png" href="test_Android-RoundRectList.html" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="url" icon="images/a-icon-3.png" url="view-sample.html" transition="slide"></li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View" style="background-color:black">
-			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Android-RoundRectList.html b/dojox/mobile/tests/test_Android-RoundRectList.html
deleted file mode 100755
index 9f62148..0000000
--- a/dojox/mobile/tests/test_Android-RoundRectList.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Round Rect List</title>
-		<link href="../themes/android/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="item1" dojoType="dojox.mobile.ListItem" icon="images/a-icon-10.png" rightText="Off" moveTo="bar">
-					u1space
-				</li>
-				<li id="item2" dojoType="dojox.mobile.ListItem" icon="images/a-icon-11.png" rightText="Off" moveTo="bar">
-					u2space
-				</li>
-				<li id="item3" dojoType="dojox.mobile.ListItem" icon="images/a-icon-12.png" rightText="Off" moveTo="bar">
-					Wi-Fi
-				</li>
-				<li id="item4" dojoType="dojox.mobile.ListItem" icon="images/a-icon-13.png" rightText="VPN" moveTo="bar">
-					VPN
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="foo">u1space</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">
-					Video
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-2.png" rightText="VPN">
-					Maps
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">
-					Phone Number
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Android-Settings.html b/dojox/mobile/tests/test_Android-Settings.html
deleted file mode 100644
index bcc05a7..0000000
--- a/dojox/mobile/tests/test_Android-Settings.html
+++ /dev/null
@@ -1,108 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Settings</title>
-		<link href="../themes/android/base.css" rel="stylesheet">
-		<link href="../themes/common/domButtons/DomButtonCheckOn.css" rel="stylesheet">
-		<link href="../themes/common/domButtons/DomButtonCheckOff.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.ready(function(){
-				var ul = dojo.byId("list");
-				for(var i = 0, len = ul.childNodes.length; i < len; i++){
-					var li = ul.childNodes[i];
-					if(li.nodeType != 1 || li.tagName != "LI"){ continue; }
-					var w = dijit.byNode(li);
-					dojo.connect(w.btnNode, "onclick", btnClicked);
-				}
-			});
-			function btnClicked(e){
-				var btnDiv = e.currentTarget;
-				if(dojo.hasClass(btnDiv, "mblCheckOffButton")){
-					dojo.removeClass(btnDiv, "mblCheckOffButton");
-					dojo.addClass(btnDiv, "mblCheckOnButton");
-				}else if(dojo.hasClass(btnDiv, "mblCheckOnButton")){
-					dojo.removeClass(btnDiv, "mblCheckOnButton");
-					dojo.addClass(btnDiv, "mblCheckOffButton");
-				}
-				if(dojo.isBB){
-					btnDiv.parentNode.appendChild(btnDiv.parentNode.removeChild(btnDiv));
-				}
-			}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Settings</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" iconBase="images/a-icon-1-41x41.png">
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-10.png" moveTo="location">
-					Wireless & networks
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-11.png" moveTo="location">
-					Call settings
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-12.png" moveTo="location">
-					Sound & display
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-13.png" moveTo="location">
-					Location & security
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-14.png" moveTo="location">
-					Applications
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-15.png" moveTo="location">
-					Accounts & sync
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-16.png" moveTo="location">
-					Privacy
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-17.png" moveTo="location">
-					SD card &amp phone storage
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-18.png" moveTo="location">
-					Search
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-10.png" moveTo="location">
-					Language & keyboard
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-11.png" moveTo="location">
-					Accessibility
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/a-icon-12.png" moveTo="location">
-					Text-to-speech
-				</li>
-			</ul>
-		</div>
-		<div id="location" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">Location & security settings</h1>
-			<h2 class="mblHeading">My Location</h2>
-			<ul id="list" dojoType="dojox.mobile.EdgeToEdgeList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" btnClass="mblDomButtonCheckOff">
-					Use wireless networks
-					<div class="mblListItemSubText">
-						See location in applications (such as Maps) using wireless networks
-					</div>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" btnClass="mblDomButtonCheckOn">
-					Use GPS satellites
-					<div class="mblListItemSubText">
-						When locating, accurate to street level (uncheck to conserve battery)
-					</div>
-				</li>
-			</ul>
-			<h2 class="mblHeading">My Location</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem">
-					Set unlock pattern
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Android-Switch.html b/dojox/mobile/tests/test_Android-Switch.html
deleted file mode 100644
index 3a983cd..0000000
--- a/dojox/mobile/tests/test_Android-Switch.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Switch</title>
-		<link href="../themes/android/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-
-		<style>
-		.color1 .mblSwitchBgLeft {
-			background: -webkit-gradient(linear, left top, left bottom, from(#28B159), to(#75FBAC), color-stop(0.5, #3FEB84), color-stop(0.5, #4CEE8E));
-		}
-		.color1 .mblSwitchBgRight {
-			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
-		}
-		.color2 .mblSwitchBgLeft {
-			background: -webkit-gradient(linear, left top, left bottom, from(#FF9D00), to(#FFCE80), color-stop(0.5, #FFBB4D), color-stop(0.5, #FFC871));
-		}
-		.color2 .mblSwitchBgRight {
-			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
-		}
-		.color1 .mblSwitchKnob,
-		.color2 .mblSwitchKnob {
-			background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#FAFAFA), color-stop(0.5, #BBBBBB), color-stop(0.5, #CACACA));
-		}
-		.float {
-			float: left;
-			margin-right: 10px;
-		}
-		.bold {
-			font-weight: bold;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojoType="dojox.mobile.View" selected="true">
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Default Shape</span><br>
-				<div class="float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Round Shape 1</span><br>
-				<div class="mblSwRoundShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwRoundShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Round Shape 2</span><br>
-				<div class="mblSwRoundShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwRoundShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Arc Shape 1</span><br>
-				<div class="mblSwArcShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwArcShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Arc Shape 2</span><br>
-				<div class="mblSwArcShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwArcShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Android-TabBar.html b/dojox/mobile/tests/test_Android-TabBar.html
deleted file mode 100644
index a02bdef..0000000
--- a/dojox/mobile/tests/test_Android-TabBar.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>TabBar</title>
-		<link href="../themes/android/base.css" rel="stylesheet">
-		<link href="../themes/android/TabBar.css" rel="stylesheet">
-		<style>
-		.label {
-			font-family: "Helvetica Neue", Helvetica;
-			font-size: 13px;
-			margin-top: 20px;
-		}
-		.view {
-			font-size: 30px;
-			padding-top: 30px;
-			text-align: center;
-		}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div class="label">Segmented Control</div>
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar</div>
-		<ul dojoType="dojox.mobile.TabBar">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar (CSS Sprite)</div>
-		<ul dojoType="dojox.mobile.TabBar" iconBase="images/tab-icons.png">
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Featured</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,29,29,29" iconPos2="29,29,29,29">Categories</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,58,29,29" iconPos2="29,58,29,29">Top 25</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,87,29,29" iconPos2="29,87,29,29">Search</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,116,29,29" iconPos2="29,116,29,29">Updates</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<div class="view">View 1</div>
-		</div>
-		<div id="view2" dojoType="dojox.mobile.View">
-			<div class="view">View 2</div>
-		</div>
-		<div id="view3" dojoType="dojox.mobile.View">
-			<div class="view">View 3</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Android-VariableHeightList.html b/dojox/mobile/tests/test_Android-VariableHeightList.html
deleted file mode 100755
index b8f23e2..0000000
--- a/dojox/mobile/tests/test_Android-VariableHeightList.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>News</title>
-		<link href="../themes/android/base.css" rel="stylesheet">
-		<style>
-		.content {
-			padding:0px 10px;
-			background-color: white;
-			color: black;
-		}
-		p {
-			font-family: Helvetica;
-			font-size: 12px;
-		}
-		.title {
-			color: blue;
-			margin-bottom: 4px;
-		}
-		.subtitle {
-			font-style: italic;
-			color: gray;
-			margin: 0px;
-			margin-bottom: 4px;
-		}
-		.subsubtitle {
-			margin: 16px 0px 0px 0px;
-		}
-		.lst {
-			margin: 0px;
-			padding: 0px 14px;
-		}
-		.lst li {
-			font-family: Helvetica;
-			font-size: 12px;
-			margin: 0px;
-			list-style-type: square;
-		}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="home" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">News</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Top Stories</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" moveTo="#article" transition="slide">
-					Top 10 news stories of the decade
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" moveTo="#article" transition="flip">
-					Create client-side diagrammatic interaction in Web applications with GFX
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" moveTo="#article" transition="fade">
-					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
-				</li>
-			</ul>
-		</div>
-
-		<div id="article" dojoType="dojox.mobile.View" style="background-color:white;height:100%">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="#home">Article</h1>
-			<div class="content">
-				<h3 class="title">Did you know?</h3>
-				<h4 class="subtitle">Features of dojox.mobile</h4>
-				<h5 class="subsubtitle">No images are used</h5>
-				<ul class="lst">
-				  	<li>UI parts consist of DOM and CSS3.</li>
-					<li>Only application icons are images.</li>
-				</ul>
-				<p>For example, none of the UI parts below are images.<br></p>
-				<img src="images/not-images.png">
-
-				<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
-				<ul class="lst">
-				  	<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
-				</ul>
-
-				<h5 class="subsubtitle">Support for CSS sprite</h5>
-				<ul class="lst">
-					<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
-				</ul>
-
-				<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
-				<ul class="lst">
-					<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
-				</ul>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Animation.html b/dojox/mobile/tests/test_Animation.html
deleted file mode 100755
index 0973164..0000000
--- a/dojox/mobile/tests/test_Animation.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Animation</title>
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");// This app uses theme detection
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Animations</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Audio-single-source.html b/dojox/mobile/tests/test_Audio-single-source.html
new file mode 100644
index 0000000..98832f8
--- /dev/null
+++ b/dojox/mobile/tests/test_Audio-single-source.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Audio</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Audio"
+		]);
+	</script>
+</head>
+<body>
+	<audio data-dojo-type="dojox.mobile.Audio" controls>
+		<source src="audio/sample.mp3" type="audio/mpeg">
+		<p>To play the music, A browser which supported audio tag is required.</p>
+	</audio>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Audio.html b/dojox/mobile/tests/test_Audio.html
new file mode 100644
index 0000000..8ecfc16
--- /dev/null
+++ b/dojox/mobile/tests/test_Audio.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Audio</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Audio"
+		]);
+	</script>
+</head>
+<body>
+	<audio data-dojo-type="dojox.mobile.Audio" controls>
+		<source src="audio/sample.mp3" type="audio/mpeg">
+		<source src="audio/sample.ogg" type="audio/ogg">
+		<source src="audio/sample.wav" type="audio/wav">
+		<p>To play the music, A browser which supported audio tag is required.</p>
+	</audio>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Badge.html b/dojox/mobile/tests/test_Badge.html
new file mode 100644
index 0000000..a3eb693
--- /dev/null
+++ b/dojox/mobile/tests/test_Badge.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Badge</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonGreenBadge.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonBlueBadge.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom",
+			"dojox/mobile/Badge",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(dom, Badge){
+			dojo.ready(function(){
+				var b1 = new Badge();
+				b1.setValue("33");
+				dom.byId("container1").appendChild(b1.domNode);
+
+				var b2 = new Badge({value:"22"});
+				dom.byId("container1").appendChild(b2.domNode);
+
+				var b3 = new Badge({value:"33",className:"mblDomButtonBlueBadge"});
+				dom.byId("container1").appendChild(b3.domNode);
+
+				var b4 = new Badge({value:"44",className:"mblDomButtonBlueBadge",fontSize:11});
+				dom.byId("container1").appendChild(b4.domNode);
+
+				var c = 0;
+				var id = setInterval(function() {
+					c += 7;
+					if(c >= 100){
+						clearInterval(id);
+					}
+					btn1.setValue(c);
+				}, 500);
+			});
+		});
+	</script>
+</head>
+<body style="background-color:#9E9EA0;padding:30px;">
+	<div data-dojo-type="dojox.mobile.Badge" class="mblDomButtonRedBadge" data-dojo-props='value:"6"'></div>
+	<div data-dojo-type="dojox.mobile.Badge" class="mblDomButtonBlueBadge" data-dojo-props='value:"48"'></div>
+	<div data-dojo-type="dojox.mobile.Badge" class="mblDomButtonGreenBadge" data-dojo-props='value:"320"'></div>
+	<hr>
+ 	<div id="container1"></div>
+	<hr>
+	<div data-dojo-id="btn1" data-dojo-type="dojox.mobile.Badge" class="mblDomButtonRedBadge"></div>
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_BlackBerry-EdgeToEdgeList.html b/dojox/mobile/tests/test_BlackBerry-EdgeToEdgeList.html
deleted file mode 100755
index d7841ca..0000000
--- a/dojox/mobile/tests/test_BlackBerry-EdgeToEdgeList.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Edge to Edge List</title>
-		<link href="../themes/blackberry/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Options</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Network</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-6.png">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-3.png">
-					Wi-Fi
-					<div style="position:absolute;top:6px;right:12px;">
-						<select>
-							<option selected>ON</option>
-							<option>OFF</option>
-						</select>
-					</div>
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Sound</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-2.png">
-					Alarm
-					<div style="position:absolute;top:6px;right:12px;">
-						<input type="radio" name="alarm" checked>ON
-						<input type="radio" name="alarm">OFF<br>
-					</div>
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Display</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-1.png">
-					Font
-					<div style="position:absolute;top:6px;right:12px;">
-						<input type="checkbox" checked>Bold
-						<input type="checkbox">Italic<br>
-					</div>
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_BlackBerry-Heading.html b/dojox/mobile/tests/test_BlackBerry-Heading.html
deleted file mode 100755
index eff7d53..0000000
--- a/dojox/mobile/tests/test_BlackBerry-Heading.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Heading</title>
-		<link href="../themes/blackberry/base.css" rel="stylesheet">
-		<link href="../themes/blackberry/TabBar.css" rel="stylesheet">
-		<link href="../themes/common/domButtons.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-			dojo.ready(function(){
-				var btn1 = dijit.byId("btn1");
-				btn1.connect(btn1.domNode, "onclick", function(){
-					console.log(this.label + " button was clicked");
-				});
-			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="general" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">General</h1>
-			<h1 dojoType="dojox.mobile.Heading" back="Long Button" moveTo="settings">Very Very Long Title May Not Be Displayed in the Narrow Space - Very Very Long Title May Not Be Displayed in the Narrow Space</h1>
-		</div>
-
-		<h3>Heading with buttons</h3>
-
-		<h1 dojoType="dojox.mobile.Heading" label="World Clock">
-			<div id="btn1" dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px;float:left">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;" onclick="console.log('+ was clicked')"></div>
-
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px;float:left;">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;"></div>
-			Alarm Clock
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Voice Memos">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Speaker" style="float:left"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Updates">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="News" back="Bookmarks" moveTo="bookmarks">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="New Folder" style="float:right;"></div>
-		</h1><br>
-
-
-		<div dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">New</div>
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">Toggle</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icon-18h.png" moveTo="view3" style="padding:0 10px"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icons.png" iconPos="29,0,29,29" moveTo="view3" style="padding:0 10px"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" moveTo="view3" style="float:right;"></div>
-		</div><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:left;margin-left:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px" selected="true">Catalog</li>
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px">Share</li>
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px">Download</li>
-			</ul>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" align="center">
-		  <table cellpadding="0" cellspacing="0" style="width:100%;"><tr>
-			<td><div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus"></div></td>
-			<td align="center"><div dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="margin:auto;">
-				<div dojoType="dojox.mobile.TabBarButton" selected="true" style="width:80px">Search</div>
-				<div dojoType="dojox.mobile.TabBarButton" style="width:80px">Directions</div>
-			</div></td>
-			<td align="right"><div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icon-15h.png" style="float:right;"></div></td>
-		  </tr></table>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Inbox" label="1 of 10">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:right;margin-right:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteDownArrow" selectOne="false"></li>
-			</ul>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Top" label="Inbox(32)">
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteUpArrow" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteDownArrow" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Inbox" label="1 of 10">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:right;margin-right:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteSearch" selectOne="false"></li>
-			</ul>
-		</h1><br>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_BlackBerry-IconContainer.html b/dojox/mobile/tests/test_BlackBerry-IconContainer.html
deleted file mode 100755
index f879b99..0000000
--- a/dojox/mobile/tests/test_BlackBerry-IconContainer.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon Container</title>
-		<link href="../themes/blackberry/base.css" rel="stylesheet">
-		<link href="../themes/blackberry/IconContainer.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-
-		<style>
-		.mblIconArea {
-			color: white;
-		}
-		</style>
-		
-	</head>
-	<body style="visibility:hidden;background-color: black;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="Messages" icon="images/b-app-icon-1.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Text" icon="images/b-app-icon-2.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Contacts" icon="images/b-app-icon-3.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Browser" icon="images/b-app-icon-4.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Media" icon="images/b-app-icon-5.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Calendar" icon="images/b-app-icon-6.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Phone" icon="images/b-app-icon-7.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Social Feeds" icon="images/b-app-icon-8.png" moveTo="about" transition="fade"></li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo" transition="fade">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_BlackBerry-RoundRectList.html b/dojox/mobile/tests/test_BlackBerry-RoundRectList.html
deleted file mode 100755
index 6a7d3a3..0000000
--- a/dojox/mobile/tests/test_BlackBerry-RoundRectList.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Round Rectangle List</title>
-		<link href="../themes/blackberry/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Options</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Network</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-6.png">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-3.png">
-					Wi-Fi
-					<div style="position:absolute;top:6px;right:12px;">
-						<select>
-							<option selected>ON</option>
-							<option>OFF</option>
-						</select>
-					</div>
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Sound</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-2.png">
-					Alarm
-					<div style="position:absolute;top:6px;right:12px;">
-						<input type="radio" name="alarm" checked>ON
-						<input type="radio" name="alarm">OFF<br>
-					</div>
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Display</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-1.png">
-					Font
-					<div style="position:absolute;top:6px;right:12px;">
-						<input type="checkbox" checked>Bold
-						<input type="checkbox">Italic<br>
-					</div>
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_BlackBerry-ScrollableView.html b/dojox/mobile/tests/test_BlackBerry-ScrollableView.html
deleted file mode 100755
index 1bbdacf..0000000
--- a/dojox/mobile/tests/test_BlackBerry-ScrollableView.html
+++ /dev/null
@@ -1,396 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>ScrollableView demo</title>
-	<link href="../themes/blackberry/base.css" rel="stylesheet">
-	<link href="../themes/blackberry/TabBar.css" rel="stylesheet">
-	<style>
-	html,body{
-		height: 100%;
-		overflow: hidden;
-	}
-	.list1 li{
-		border-style: solid;
-		border-width: 1px 0px 1px 0px;
-		border-top-color: #BABABC;
-		border-bottom-color: #89898C;
-		background-color: black;
-		line-height: 0px;
-		color: #AAAAAA;
-	}
-	.list1 li table{
-		line-height: normal;
-	}
-	.list1 li:nth-child(even){
-		background-color: #333333;
-	}
-	#list2 .lnk {
-		color: black;
-	}
-	#list2 li:nth-child(even){
-		background-color: #eeeeee;
-	}
-	#categ1 {
-		font-size: 18px;
-	}
-	#categ1 li{
-		line-height: 70px;
-	}
-	.lnk {
-		font-size: 14px;
-		color: white;
-		text-decoration: none;
-	}
-	.content {
-		padding:0px 10px;
-		background-color: white;
-	}
-	p {
-		font-family: Helvetica;
-		font-size: 12px;
-	}
-	.title {
-		color: blue;
-		margin-bottom: 4px;
-	}
-	.subtitle {
-		font-style: italic;
-		color: gray;
-		margin: 0px;
-		margin-bottom: 4px;
-	}
-	.subsubtitle {
-		margin: 16px 0px 0px 0px;
-	}
-	.lst {
-		margin: 0px;
-		padding: 0px 14px;
-	}
-	.lst li {
-		font-family: Helvetica;
-		font-size: 12px;
-		margin: 0px;
-		list-style-type: square;
-	}
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		dojo.require("dojox.mobile");			// This is a mobile app.
-		dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-		dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		dojo.require("dojox.mobile.ScrollableView");
-		dojo.require("dojox.mobile.TabBar");
-	</script>
-</head>
-<body style="visibility:hidden;">
-	<div id="group1" dojoType="dojox.mobile.View" selected="true">
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" fixed="top">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/b-app-icon-6.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-									Sarah Connor Hardcover<br>
-									Eligible for FREE Super Saver Shipping
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/b-app-icon-6.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
-									Martin Parker Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/b-app-icon-6.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Total Solar Eclipse</a><br>
-									Steven Young Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/b-app-icon-6.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The History of Java Coffee</a><br>
-									Marco Rodriguez Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/b-app-icon-6.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-									Melissa Morgan Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-			</ul>
-		</div>
-
-		<div id="view2" dojoType="dojox.mobile.ScrollableView">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list2">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/b-icon-4.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-									Melissa Morgan Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/b-icon-4.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The History of Java Coffee</a><br>
-									Marco Rodriguez Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/b-icon-4.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-									Sarah Connor Hardcover<br>
-									Eligible for FREE Super Saver Shipping
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/b-icon-4.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Total Solar Eclipse</a><br>
-									Steven Young Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-			</ul>
-		</div>
-
-		<div id="view3" dojoType="dojox.mobile.ScrollableView">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="10">
-					Videos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="96">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2">
-					Applications
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-					Capacity
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-					Available
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-					Version
-				</li>
-			</ul>
-		</div>
-	</div>
-
-	<div id="categ" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Categories</h1>
-		<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1" id="categ1">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 1</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 2</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 3</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 4</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 5</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 6</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 7</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 8</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 9</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 10</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 11</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 12</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 13</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 14</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 15</li>
-		</ul>
-	</div>
-
-	<div id="top25" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">News</h1>
-		<h2 dojoType="dojox.mobile.RoundRectCategory">Top Stories</h2>
-		<ul dojoType="dojox.mobile.RoundRectList">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Top 10 news stories of the decade
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Create client-side diagrammatic interaction in Web applications with GFX
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
-			</li>
-		</ul>
-	</div>
-
-	<div id="search" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Search Result</h1>
-		<ul dojoType="dojox.mobile.RoundRectList">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-				Sarah Connor Hardcover<br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$14.50 (50%)</font> In Stock<br>
-				# (531)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-				Martin Parker Hardcover<br>
-				<font color="red">$14.00 (60%)</font> In Stock<br>
-				# (173)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-				Steven Young Hardcover<br>
-				Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$9.50 (62%)</font> In Stock<br>
-				# (1199)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-				Marco Rodriguez Hardcover<br>
-				<font color="blue">Not Available</font>
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-				Melissa Morgan Hardcover<br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$12.00 (60%)</font> In Stock<br>
-				# (1847)
-			</li>
-		</ul>
-	</div>
-
-	<div id="article" dojoType="dojox.mobile.ScrollableView" style="background-color:white;height:100%">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Article</h1>
-		<div class="content">
-			<h3 class="title">Did you know?</h3>
-			<h4 class="subtitle">Features of dojox.mobile</h4>
-			<h5 class="subsubtitle">No images are used</h5>
-			<ul class="lst">
-			  	<li>UI parts consist of DOM and CSS3.</li>
-				<li>Only application icons are images.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
-			<ul class="lst">
-			  	<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Support for CSS sprite</h5>
-			<ul class="lst">
-				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
-			<ul class="lst">
-				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
-			</ul>
-		</div>
-	</div>
-
-	<ul dojoType="dojox.mobile.TabBar" fixed="bottom" style="border-bottom:none;">
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" selected="true" moveTo="group1">Featured</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="categ">Categories</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="top25">Top 25</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-11.png" icon2="images/tab-icon-11h.png" moveTo="search">Search</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-13.png" icon2="images/tab-icon-13h.png" moveTo="article">Updates</li>
-	</ul>
-</body>
-</html>
diff --git a/dojox/mobile/tests/test_BlackBerry-Settings.html b/dojox/mobile/tests/test_BlackBerry-Settings.html
deleted file mode 100755
index 0d71162..0000000
--- a/dojox/mobile/tests/test_BlackBerry-Settings.html
+++ /dev/null
@@ -1,111 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-
-		<title>Setting</title>
-		<link href="../themes/blackberry/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-	    <div id="options" dojoType="dojox.mobile.View" selected="true">
-		    <h1 dojoType="dojox.mobile.Heading">Options</h1>
-		    <ul dojoType="dojox.mobile.EdgeToEdgeList" transition=fade>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-6.png" noArrow="true" moveTo="settings">
-				    Sounds and Ring Tones
-				    <div class="mblListItemSubText">
-					    Ring tones, reminders, profiles
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-3.png" noArrow="true" moveTo="settings">
-				    Networks and Connections
-				    <div class="mblListItemSubText">
-					    Bluetooth connections, WiFi mode
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-2.png" noArrow="true" moveTo="settings">
-				    Display
-				    <div class="mblListItemSubText">
-					    Date, time, themes, screen
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-1.png" noArrow="true" moveTo="settings">
-				    Typing and Input
-				    <div class="mblListItemSubText">
-					    Language, keyboard, text input
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-6.png" noArrow="true" moveTo="settings">
-				    Device
-				    <div class="mblListItemSubText">
-					    PIN, auto on/off, battery, storage
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-5.png" noArrow="true" moveTo="settings">
-				    Call Management
-				    <div class="mblListItemSubText">
-					    Call behavior, voice mail, speed dial
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-7.png" noArrow="true" moveTo="settings">
-				    Security
-				    <div class="mblListItemSubText">
-					    Password ,encryption, firewall
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-8.png" noArrow="true" moveTo="settings">
-				    Accessibility
-				    <div class="mblListItemSubText">
-					    Display, sound and input options
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-6.png" noArrow="true" moveTo="settings">
-				    Third Party Applications
-				    <div class="mblListItemSubText">
-					    Options for third-party applications
-				    </div>
-			    </li>
-		    </ul>
-	    </div>
-
-	    <div id="settings" dojoType="dojox.mobile.View">
-		    <h1 dojoType="dojox.mobile.Heading">Sounds and Ring Tones</h1>
-		    <ul dojoType="dojox.mobile.EdgeToEdgeList" transition="fade">
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-3.png" noArrow="true" moveTo="options">
-				    Phone Ring Tone
-				    <div class="mblListItemSubText">
-					    Set ring tone for chosen profile
-				    </div>
-			    </li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-2.png" noArrow="true" moveTo="options">
-				    Sounds for Selected Profile
-				    <div class="mblListItemSubText">
-					    Set any alert in chosen profile
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-1.png" noArrow="true" moveTo="options">
-				    Sounds for Contacts
-				    <div class="mblListItemSubText">
-					    Add alert for one or more contacts
-				    </div>
-			    </li>
-			    <li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" clickable="true" icon="images/b-icon-6.png" noArrow="true" moveTo="options">
-				    Profile Management
-				    <div class="mblListItemSubText">
-					    Add, edit or delete a sound profile
-				    </div>
-			    </li>
-		    </ul>
-	    </div>
-
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_BlackBerry-SwapView.html b/dojox/mobile/tests/test_BlackBerry-SwapView.html
deleted file mode 100755
index 7d0ddfa..0000000
--- a/dojox/mobile/tests/test_BlackBerry-SwapView.html
+++ /dev/null
@@ -1,92 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>SwapView</title>
-		<link href="../themes/blackberry/base.css" rel="stylesheet">
-		<link href="../themes/blackberry/IconContainer.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-			margin: 0px;
-		}
-		.mobile body {
-			background-color: black;
-		}
-		.mblIconArea {
-			height: 90px;
-			width: 90px;
-			color: white;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.IconContainer");
-			dojo.require("dojox.mobile.SwapView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.SwapView" selected="true">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Page flipping demo</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				Swipe the screen left or right to flip between the views.
-				There are 4 views in this demo.
-				Vertical scrolling and page indicator are not supported.
-			</ul>
-		</div>
-
-		<div id="icon1" dojoType="dojox.mobile.SwapView">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container 1</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="Messages" icon="images/b-app-icon-1.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Text Messages" icon="images/b-app-icon-2.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Contacts" icon="images/b-app-icon-3.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Browser" icon="images/b-app-icon-4.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Media" icon="images/b-app-icon-5.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Calendar" icon="images/b-app-icon-6.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Phone" icon="images/b-app-icon-7.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Social Feeds" icon="images/b-app-icon-8.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="App World" icon="images/b-app-icon-1.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Maps" icon="images/b-app-icon-2.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Camera" icon="images/b-app-icon-3.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Clock" icon="images/b-app-icon-4.png" moveTo="about" transition="fade"></li>
-			</ul>
-		</div>
-
-		<div id="icon2" dojoType="dojox.mobile.SwapView">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container 2</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="Media" icon="images/b-app-icon-5.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Calendar" icon="images/b-app-icon-6.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Phone" icon="images/b-app-icon-7.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Social Feeds" icon="images/b-app-icon-8.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="App World" icon="images/b-app-icon-1.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Maps" icon="images/b-app-icon-2.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Camera" icon="images/b-app-icon-3.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Clock" icon="images/b-app-icon-4.png" moveTo="about" transition="fade"></li>
-			</ul>
-		</div>
-
-		<div id="icon3" dojoType="dojox.mobile.SwapView">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container 3</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="App World" icon="images/b-app-icon-1.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Maps" icon="images/b-app-icon-2.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Camera" icon="images/b-app-icon-3.png" moveTo="about" transition="fade"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Clock" icon="images/b-app-icon-4.png" moveTo="about" transition="fade"></li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_BlackBerry-Switch.html b/dojox/mobile/tests/test_BlackBerry-Switch.html
deleted file mode 100755
index 44da622..0000000
--- a/dojox/mobile/tests/test_BlackBerry-Switch.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Switch</title>
-		<link href="../themes/blackberry/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-		
-		<style>
-		.color1 .mblSwitchBgLeft {
-			background: -webkit-gradient(linear, left top, left bottom, from(#28B159), to(#75FBAC), color-stop(0.5, #3FEB84), color-stop(0.5, #4CEE8E));
-		}
-		.color1 .mblSwitchBgRight {
-			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
-		}
-		.color2 .mblSwitchBgLeft {
-			background: -webkit-gradient(linear, left top, left bottom, from(#FF9D00), to(#FFCE80), color-stop(0.5, #FFBB4D), color-stop(0.5, #FFC871));
-		}
-		.color2 .mblSwitchBgRight {
-			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
-		}
-		.color1 .mblSwitchKnob,
-		.color2 .mblSwitchKnob {
-			background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#FAFAFA), color-stop(0.5, #BBBBBB), color-stop(0.5, #CACACA));
-		}
-		.float {
-			float: left;
-			margin-right: 10px;
-		}
-		.bold {
-			font-weight: bold;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojoType="dojox.mobile.View" selected="true">
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Default Shape</span><br>
-				<div class="float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Round Shape 1</span><br>
-				<div class="mblSwRoundShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwRoundShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Round Shape 2</span><br>
-				<div class="mblSwRoundShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwRoundShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Arc Shape 1</span><br>
-				<div class="mblSwArcShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwArcShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Arc Shape 2</span><br>
-				<div class="mblSwArcShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwArcShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_BlackBerry-TabBar.html b/dojox/mobile/tests/test_BlackBerry-TabBar.html
deleted file mode 100755
index 8a66a52..0000000
--- a/dojox/mobile/tests/test_BlackBerry-TabBar.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>TabBar</title>
-		<link href="../themes/blackberry/base.css" rel="stylesheet">
-		<link href="../themes/blackberry/TabBar.css" rel="stylesheet">
-		<style>
-		.label {
-			font-family: "Helvetica Neue", Helvetica;
-			font-size: 13px;
-			margin-top: 20px;
-		}
-		.view {
-			font-size: 30px;
-			padding-top: 30px;
-			text-align: center;
-		}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div class="label">Segmented Control</div>
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar</div>
-		<ul dojoType="dojox.mobile.TabBar">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar (CSS Sprite)</div>
-		<ul dojoType="dojox.mobile.TabBar" iconBase="images/tab-icons.png">
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Featured</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,29,29,29" iconPos2="29,29,29,29">Categories</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,58,29,29" iconPos2="29,58,29,29">Top 25</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,87,29,29" iconPos2="29,87,29,29">Search</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,116,29,29" iconPos2="29,116,29,29">Updates</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<div class="view">View 1</div>
-		</div>
-		<div id="view2" dojoType="dojox.mobile.View">
-			<div class="view">View 2</div>
-		</div>
-		<div id="view3" dojoType="dojox.mobile.View">
-			<div class="view">View 3</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_BlackBerry-VariableHeightList.html b/dojox/mobile/tests/test_BlackBerry-VariableHeightList.html
deleted file mode 100755
index e293dda..0000000
--- a/dojox/mobile/tests/test_BlackBerry-VariableHeightList.html
+++ /dev/null
@@ -1,99 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>News</title>
-		<link href="../themes/blackberry/base.css" rel="stylesheet">
-		<style>
-		.content {
-			padding:0px 10px;
-			background-color: white;
-			color: black;
-		}
-		p {
-			font-family: Helvetica;
-			font-size: 12px;
-		}
-		.title {
-			color: blue;
-			margin-bottom: 4px;
-		}
-		.subtitle {
-			font-style: italic;
-			color: gray;
-			margin: 0px;
-			margin-bottom: 4px;
-		}
-		.subsubtitle {
-			margin: 16px 0px 0px 0px;
-		}
-		.lst {
-			margin: 0px;
-			padding: 0px 14px;
-		}
-		.lst li {
-			font-family: Helvetica;
-			font-size: 12px;
-			margin: 0px;
-			list-style-type: square;
-		}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.hash");
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="home" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">News</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Top Stories</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" moveTo="#article" transition="slide">
-					Top 10 news stories of the decade
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" moveTo="#article" transition="flip">
-					Create client-side diagrammatic interaction in Web applications with GFX
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" moveTo="#article" transition="fade">
-					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
-				</li>
-			</ul>
-		</div>
-
-		<div id="article" dojoType="dojox.mobile.View" style="background-color:white;height:100%">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="#home">Article</h1>
-			<div class="content">
-				<h3 class="title">Did you know?</h3>
-				<h4 class="subtitle">Features of dojox.mobile</h4>
-				<h5 class="subsubtitle">No images are used</h5>
-				<ul class="lst">
-				  	<li>UI parts consist of DOM and CSS3.</li>
-					<li>Only application icons are images.</li>
-				</ul>
-				<p>For example, none of the UI parts below are images.<br></p>
-				<img src="images/not-images.png">
-
-				<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
-				<ul class="lst">
-				  	<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
-				</ul>
-
-				<h5 class="subsubtitle">Support for CSS sprite</h5>
-				<ul class="lst">
-					<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
-				</ul>
-
-				<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
-				<ul class="lst">
-					<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
-				</ul>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Button.html b/dojox/mobile/tests/test_Button.html
new file mode 100644
index 0000000..87526ff
--- /dev/null
+++ b/dojox/mobile/tests/test_Button.html
@@ -0,0 +1,95 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no">
+	<meta name="apple-mobile-web-app-capable" content="yes">
+	<title>Button</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Button']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dojo/_base/array",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Button"
+		], function(connect, ready, array, dom, registry){
+			ready(function(){
+				array.forEach(["btn1", "btn2", "btn3", "btn4", "btn5"], function(btnId){
+					var btnWidget = registry.byId(btnId);
+					connect.connect(btnWidget.domNode, "click", onBtnClicked);
+				});
+			});
+			function onBtnClicked(){
+				var span = dom.byId("msgArea");
+				span.innerHTML = """ + dom.byId(this.id).innerHTML + "" button was clicked.";
+				setTimeout(function(){
+					span.innerHTML = "";
+				}, 1000);
+			};
+		});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	hr {
+		border: none;
+		margin: 0;
+	}
+	button {
+		width: 120px;
+		margin: 15px 10px 0;
+	}
+	button.customButton {
+		border-color: #cc3333;
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+		color: #ffffff;
+	}
+	button.customButtonSelected {
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#AF333C), to(#880E17), color-stop(0.5, #952B33), color-stop(0.5, #870F18));
+	}
+	.dj_gecko button.customButton {
+		background-image: url(images/red-button-bg.png);
+	}
+	.dj_gecko button.customButtonSelected {
+		background-image: url(images/red-button-sel-bg.png);
+	}
+	.dj_ie button.customButton {
+		background-image: url(images/red-button-bg.png);
+	}
+	.dj_ie button.customButtonSelected {
+		background-image: url(images/red-button-sel-bg.png);
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+	    <h1 data-dojo-type="dojox.mobile.Heading">Button</h1>
+		<button data-dojo-type="dojox.mobile.Button" id="btn1">Default</button>
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn2" class="mblBlueButton">Blue</button>
+		class="mblBlueButton"
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn3" class="mblRedButton">Red</button>
+		class="mblRedButton"
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn4" disabled>Disabled</button>
+		disabled
+		<hr>
+		<button data-dojo-type="dojox.mobile.Button" id="btn5" class="customButton">Custom</button>
+		class="customButton"
+		<hr>
+		<div id="msgArea" style="margin:15px"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Calendar.html b/dojox/mobile/tests/test_Calendar.html
new file mode 100644
index 0000000..d1ed371
--- /dev/null
+++ b/dojox/mobile/tests/test_Calendar.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html style="overflow:hidden;">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>dijit.Calendar</title>
+	<link href="../../../dijit/themes/dijit.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','dijit.Calendar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dijit/Calendar"
+		]);
+	</script>
+</head>
+<body>
+	<div dojoType="dojox.mobile.View">
+		<h1 dojoType="dojox.mobile.Heading">dijit Calendar</h1>
+		<div dojoType='dijit.Calendar' style="margin: 0 auto;"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Carousel-async.html b/dojox/mobile/tests/test_Carousel-async.html
deleted file mode 100644
index dfbf69e..0000000
--- a/dojox/mobile/tests/test_Carousel-async.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Carousel</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/Carousel.css" rel="stylesheet">
-		<link href="../themes/iphone/PageIndicator.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-		require([
-			"dojo/_base/kernel",
-			"dojo/ready",
-			"dojo/_base/connect",	// dojo.subscribe()  (TODO: switch to use on())
-			"dojo/data/ItemFileReadStore",
-			"dojox/mobile",			// This is a mobile app.
-			"dojox/mobile/compat", 	// This mobile app supports running on desktop browsers
-			"dojox/mobile/parser", 	// This mobile app uses declarative programming with fast mobile parser
-			"dojo/data/ItemFileReadStore",
-			"dojox/mobile/ScrollableView",
-			"dojox/mobile/Carousel"
-		], function(dojo){
-			dojo.ready(function(){
-				store1 = new dojo.data.ItemFileReadStore({url: "carousel-categ.json"});
-				dojox.mobile.parser.parse();
-				dojo.subscribe("/dojox/mobile/carouselSelect", function(w, img, item, idx){
-					if(w.id == "carousel1"){
-						var store2 = new dojo.data.ItemFileReadStore({url: "carousel-"+item.value+".json"});
-						var w2 = dijit.byId("carousel2");
-						w2.set("title", item.value);
-						w2.setStore(store2);
-						dijit.byId("rect1").domNode.style.display = "none";
-					}else if(w.id == "carousel2"){
-						var rect1 = dijit.byId("rect1");
-						var u = "unknown";
-						var desc = "<div style='float:right;font:14px arial;width:49%'>Model: "+(item.model?item.model:u)+"<br>"+
-							"Design: "+(item.design?item.design:u)+"<br>"+
-							"Produced: "+(item.produced?item.produced:u)+"<br>"+
-							"Size: "+(item.size?item.size:u)+"<br>"+
-							"Price: "+(item.price?item.price:u)+"<br></div>";
-						rect1.domNode.innerHTML = "<img src='"+item.src+"' width='50%' align='top'>"+desc;
-						rect1.domNode.style.display = "";
-					}
-				});
-			});
-		});
-		</script>
-	</head>
-	<body style="visibility:hidden;background-color:#6D6D6D">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView">
-			<div id="carousel1" dojoType="dojox.mobile.Carousel" height="150px" navButton="true" store="store1" numVisible="2" title="Category"></div>
-			<div id="carousel2" dojoType="dojox.mobile.Carousel" height="120px" navButton="true"></div>
-			<div id="rect1" dojoType="dojox.mobile.RoundRect" style="display:none"></div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Carousel-prog.html b/dojox/mobile/tests/test_Carousel-prog.html
new file mode 100644
index 0000000..966bbbd
--- /dev/null
+++ b/dojox/mobile/tests/test_Carousel-prog.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel - prog</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/SwapView",
+			"dojox/mobile/Carousel",
+			"dojox/mobile/CarouselItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(ready, registry, SwapView, Carousel, CarouselItem){
+			ready(function(){
+				var view, item;
+				var carousel1 = new Carousel({height:"150px", navButton:true, numVisible:2, title:"Category"}, "carousel1");
+
+				// View #1
+				view = new SwapView();
+				carousel1.addChild(view);
+
+				item = new CarouselItem({src:"images/dish1.jpg", value:"dish1", headerText:"dish1"});
+				item.placeAt(view.containerNode);
+
+				item = new CarouselItem({src:"images/dish2.jpg", value:"dish2", headerText:"dish2"});
+				item.placeAt(view.containerNode);
+
+				// View #2
+				view = new SwapView();
+				carousel1.addChild(view);
+
+				item = new CarouselItem({src:"images/dish3.jpg", value:"dish3", headerText:"dish3"});
+				item.placeAt(view.containerNode);
+
+				item = new CarouselItem({src:"images/dish4.jpg", value:"dish4", headerText:"dish4"});
+				item.placeAt(view.containerNode);
+
+				carousel1.startup();
+			})
+		});
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<div id="carousel1"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Carousel-slideshow.html b/dojox/mobile/tests/test_Carousel-slideshow.html
deleted file mode 100644
index e189eb3..0000000
--- a/dojox/mobile/tests/test_Carousel-slideshow.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Lazy-loadable Carousel Photo Gallery</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.data.ItemFileReadStore");
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.Carousel");
-			dojo.require("dojox.mobile.ScrollableView");
-
-			var json = {
-				items: [
-					{src:"images/pic1.jpg"},
-					{src:"images/pic2.jpg"},
-					{src:"images/pic3.jpg"},
-					{src:"images/pic4.jpg"},
-					{src:"images/pic5.jpg"},
-					{src:"images/pic6.jpg"},
-					{src:"images/pic7.jpg"},
-					{src:"images/pic8.jpg"},
-					{src:"images/pic9.jpg"},
-					{src:"images/pic10.jpg"}
-				]
-			};
-		</script>
-	</head>
-	<body style="visibility:hidden;background-color:#6D6D6D">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView">
-			<span jsId="store1" dojoType="dojo.data.ItemFileReadStore" data="json"></span>
-			<div id="carousel1" dojoType="dojox.mobile.Carousel" height="280px" store="store1" numVisible="1" title="Photo Gallery"></div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Carousel.html b/dojox/mobile/tests/test_Carousel.html
index 783d958..5e323c7 100644
--- a/dojox/mobile/tests/test_Carousel.html
+++ b/dojox/mobile/tests/test_Carousel.html
@@ -1,49 +1,52 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Carousel</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.data.ItemFileReadStore");
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.Carousel");
-			dojo.require("dojox.mobile.ScrollableView");
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
 
-			var store1 = new dojo.data.ItemFileReadStore({url: "carousel-categ.json"});
-			dojo.ready(function(){
-				dojo.subscribe("/dojox/mobile/carouselSelect", function(w, img, item, idx){
-					if(w.id == "carousel1"){
-						var store2 = new dojo.data.ItemFileReadStore({url: "carousel-"+item.value+".json"});
-						var w2 = dijit.byId("carousel2");
-						w2.set("title", item.value);
-						w2.setStore(store2);
-						dijit.byId("rect1").domNode.style.display = "none";
-					}else if(w.id == "carousel2"){
-						var rect1 = dijit.byId("rect1");
-						var u = "unknown";
-						var desc = "<div style='float:right;font:14px arial;width:49%'>Model: "+(item.model?item.model:u)+"<br>"+
-							"Design: "+(item.design?item.design:u)+"<br>"+
-							"Produced: "+(item.produced?item.produced:u)+"<br>"+
-							"Size: "+(item.size?item.size:u)+"<br>"+
-							"Price: "+(item.price?item.price:u)+"<br></div>";
-						rect1.containerNode.innerHTML = desc+"<img src='"+item.src+"' width='50%' align='top'>";
-						rect1.domNode.style.display = "";
-					}
-				});
-			});
-		</script>
-	</head>
-	<body style="visibility:hidden;background-color:#6D6D6D">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView">
-			<div id="carousel1" dojoType="dojox.mobile.Carousel" height="150px" navButton="true" store="store1" numVisible="2" title="Category"></div>
-			<div id="carousel2" dojoType="dojox.mobile.Carousel" height="120px" navButton="true"></div>
-			<div id="rect1" dojoType="dojox.mobile.RoundRect" style="display:none"></div>
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SwapView",
+			"dojox/mobile/Carousel"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<div id="carousel1" data-dojo-type="dojox.mobile.Carousel"
+			data-dojo-props='height:"150px", navButton:true, numVisible:2, title:"Category"'>
+
+			<div data-dojo-type="dojox.mobile.SwapView">
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"images/dish1.jpg", value:"dish1", headerText:"dish1"'></div>
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"images/dish2.jpg", value:"dish2", headerText:"dish2"'></div>
+			</div>
+
+			<div data-dojo-type="dojox.mobile.SwapView">
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"images/dish3.jpg", value:"dish3", headerText:"dish3"'></div>
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"images/dish4.jpg", value:"dish4", headerText:"dish4"'></div>
+			</div>
+
+			<div data-dojo-type="dojox.mobile.SwapView" lazy="true">
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"images/dish5.jpg", value:"dish5", headerText:"dish5"'></div>
+				<div data-dojo-type="dojox.mobile.CarouselItem"
+					data-dojo-props='src:"images/dish6.jpg", value:"dish6", headerText:"dish6"'></div>
+			</div>
 		</div>
-	</body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_CarouselItem.html b/dojox/mobile/tests/test_CarouselItem.html
new file mode 100644
index 0000000..3d58e4b
--- /dev/null
+++ b/dojox/mobile/tests/test_CarouselItem.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>CarouselItem</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/CarouselItem"
+		]);
+	</script>
+<style>
+.mblCarouselItem {
+	height: 150px;
+	margin: 0 10px;
+	float: left;
+}
+</style>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div data-dojo-type="dojox.mobile.CarouselItem"
+		data-dojo-props='src:"images/glass1.jpg", headerText:"My Header", footerText:"My Footer"'></div>
+
+	<div data-dojo-type="dojox.mobile.CarouselItem"
+		data-dojo-props='src:"images/glass1.jpg", headerText:"My Header"'></div>
+
+	<div data-dojo-type="dojox.mobile.CarouselItem"
+		data-dojo-props='src:"images/glass1.jpg", footerText:"My Footer"'></div>
+
+	<div data-dojo-type="dojox.mobile.CarouselItem"
+		data-dojo-props='src:"images/glass1.jpg"'></div>
+
+
+	<div style="position:absolute;width:100%;height:150px;border:1px dashed red;"></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ComboBox-sv.html b/dojox/mobile/tests/test_ComboBox-sv.html
new file mode 100644
index 0000000..789e68b
--- /dev/null
+++ b/dojox/mobile/tests/test_ComboBox-sv.html
@@ -0,0 +1,178 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+
+	<title>ComboBox in ScrollableView</title>
+
+	<link href="../themes/custom/custom.css" rel="stylesheet">
+        
+	<script src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true"></script>
+        
+	<script>
+		dojo.require("dojox.mobile");
+		dojo.require("dojox.mobile.parser");
+		dojo.require("dojox.mobile.compat");
+		dojo.require("dojox.mobile.ScrollableView");
+		dojo.require("dojox.mobile.RoundRect");
+		dojo.require("dojox.mobile.Heading");
+		dojo.require("dojox.mobile.ComboBox");
+	</script>
+</head>
+<body style="visibility:hidden;">
+  	<datalist>
+		<select data-dojo-type="dijit.form.DataList" data-dojo-props='id:"states"' >
+			<option value="top">top</option>
+			<option value="AL">Alabama</option>
+			<option value="AK">Alaska</option>
+			<option value="AS">American Samoa</option>
+			<option value="AZ">Arizona</option>
+			<option value="AR">Arkansas</option>
+			<option value="AE">Armed Forces Europe</option>
+			<option value="AP">Armed Forces Pacific</option>
+			<option value="AA">Armed Forces the Americas</option>
+			<option value="CA">California</option>
+			<option value="CO">Colorado</option>
+			<option value="CT">Connecticut</option>
+			<option value="DE">Delaware</option>
+			<option value="DC">District of Columbia</option>
+			<option value="FM">Federated States of Micronesia</option>
+			<option value="FL">Florida</option>
+			<option value="GA">Georgia</option>
+			<option value="GU">Guam</option>
+			<option value="HI">Hawaii</option>
+			<option value="ID">Idaho</option>
+			<option value="IL">Illinois</option>
+			<option value="IN">Indiana</option>
+			<option value="IA">Iowa</option>
+			<option value="KS">Kansas</option>
+			<option value="KY">Kentucky</option>
+			<option value="LA">Louisiana</option>
+			<option value="ME">Maine</option>
+			<option value="MH">Marshall Islands</option>
+			<option value="MD">Maryland</option>
+			<option value="MA">Massachusetts</option>
+			<option value="MI">Michigan</option>
+			<option value="MN">Minnesota</option>
+			<option value="MS">Mississippi</option>
+			<option value="MO">Missouri</option>
+			<option value="MT">Montana</option>
+			<option value="NE">Nebraska</option>
+			<option value="NV">Nevada</option>
+			<option value="NH">New Hampshire</option>
+			<option value="NJ">New Jersey</option>
+			<option value="NM">New Mexico</option>
+			<option value="NY">New York</option>
+			<option value="NC">North Carolina</option>
+			<option value="ND">North Dakota</option>
+			<option value="MP">Northern Mariana Islands</option>
+			<option value="OH">Ohio</option>
+			<option value="OK">Oklahoma</option>
+			<option value="OR">Oregon</option>
+			<option value="PA">Pennsylvania</option>
+			<option value="PR">Puerto Rico</option>
+			<option value="RI">Rhode Island</option>
+			<option value="SC">South Carolina</option>
+			<option value="SD">South Dakota</option>
+			<option value="TN">Tennessee</option>
+			<option value="TX">Texas</option>
+			<option value="UT">Utah</option>
+			<option value="VT">Vermont</option>
+			<option value="VI">Virgin Islands, U.S.</option>
+			<option value="VA">Virginia</option>
+			<option value="WA">Washington</option>
+			<option value="WV">West Virginia</option>
+			<option value="WI">Wisconsin</option>
+			<option value="WY">Wyoming</option>
+			<option value="bottom">bottom</option>
+		</select>
+	</datalist>
+
+        <div data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props="selected:true">
+          	<h1 data-dojo-type="dojox.mobile.Heading">top</h1>
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			<p>Test</p>
+			<p>
+			<input type="text" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"", list:"states"'>
+			</p>
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Marimba
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Alarm
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Ascending
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Bark
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Bell Tower
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Blues
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Boing
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Crickets
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Digital
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Doorbell
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Duck
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Harp
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Motorcycle
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Old Car Horn
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Old Phone
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Piano Roll
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Pinball
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Robot
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Sci-Fi
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Sonar
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Strum
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Timba
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Time Passing
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Trill
+		</div>
+		<div dojoType="dojox.mobile.RoundRect">
+			Xylophone
+		</div>
+          	<h1 data-dojo-type="dojox.mobile.Heading" fixed="bottom">bottom</h1>
+        </div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ComboBox-widepage.html b/dojox/mobile/tests/test_ComboBox-widepage.html
new file mode 100644
index 0000000..b30dfaa
--- /dev/null
+++ b/dojox/mobile/tests/test_ComboBox-widepage.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="msapplication-tap-highlight" content="no"/>
+	<meta http-equiv="X-UA-Compatible" content="IE=edge">
+	<title>Combobox test - wide page</title>
+
+	<!-- Test case for #17157.
+		Known issue: the popup closes unexpectedly on some desktop browsers. -->
+		
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile",
+			"dijit/form/DataList",
+			"dojox/mobile/parser",
+			"dojox/mobile/ComboBox"
+		]);
+	</script>
+</head>
+<body style="visibility: hidden;">
+	<datalist>
+		<select data-dojo-type="dijit/form/DataList" 
+			data-dojo-props="id: 'states'">
+			<option value="AL">Alabama</option>
+			<option value="AK">Alaska</option>
+			<option value="AS">American Samoa</option>
+			<option value="AZ">Arizona</option>
+			<option value="AR">Arkansas</option>
+			<option value="AE">Armed Forces Europe</option>
+			<option value="AP">Armed Forces Pacific</option>
+			<option value="AA">Armed Forces the Americas</option>
+			<option value="CA">California</option>
+			<option value="CO">Colorado</option>
+			<option value="CT">Connecticut</option>
+			<option value="DE">Delaware</option>
+			<option value="DC">District of Columbia</option>
+			<option value="FM">Federated States of Micronesia</option>
+			<option value="FL">Florida</option>
+			<option value="GA">Georgia</option>
+			<option value="GU">Guam</option>
+			<option value="HI">Hawaii</option>
+			<option value="ID">Idaho</option>
+			<option value="IL">Illinois</option>
+			<option value="IN">Indiana</option>
+			<option value="IA">Iowa</option>
+			<option value="KS">Kansas</option>
+			<option value="KY">Kentucky</option>
+			<option value="LA">Louisiana</option>
+			<option value="ME">Maine</option>
+			<option value="MH">Marshall Islands</option>
+			<option value="MD">Maryland</option>
+			<option value="MA">Massachusetts</option>
+			<option value="MI">Michigan</option>
+			<option value="MN">Minnesota</option>
+			<option value="MS">Mississippi</option>
+			<option value="MO">Missouri</option>
+			<option value="MT">Montana</option>
+			<option value="NE">Nebraska</option>
+			<option value="NV">Nevada</option>
+			<option value="NH">New Hampshire</option>
+			<option value="NJ">New Jersey</option>
+			<option value="NM">New Mexico</option>
+			<option value="NY">New York</option>
+			<option value="NC">North Carolina</option>
+			<option value="ND">North Dakota</option>
+			<option value="MP">Northern Mariana Islands</option>
+			<option value="OH">Ohio</option>
+			<option value="OK">Oklahoma</option>
+			<option value="OR">Oregon</option>
+			<option value="PA">Pennsylvania</option>
+			<option value="PR">Puerto Rico</option>
+			<option value="RI">Rhode Island</option>
+			<option value="SC">South Carolina</option>
+			<option value="SD">South Dakota</option>
+			<option value="TN">Tennessee</option>
+			<option value="TX">Texas</option>
+			<option value="UT">Utah</option>
+			<option value="VT">Vermont</option>
+			<option value="VI">Virgin Islands, U.S.</option>
+			<option value="VA">Virginia</option>
+			<option value="WA">Washington</option>
+			<option value="WV">West Virginia</option>
+			<option value="WI">Wisconsin</option>
+			<option value="WY">Wyoming</option>
+		</select>
+	</datalist>
+
+	<div data-dojo-type="dojox/mobile/View">
+		<h3 data-dojo-type="dojox/mobile/Heading">ComboBox test</h3>
+			Scroll to the bottom to find the ComboBox control
+		<div style="height: 2000px; position: relative;"></div>
+	</div>
+	<h3 data-dojo-type="dojox/mobile/Heading">ComboBox</h3>
+	<input id="dropDown" type="text" 
+		data-dojo-type="dojox/mobile/ComboBox" 
+		data-dojo-props="list: 'states'">
+</body>
+</html>
\ No newline at end of file
diff --git a/dojox/mobile/tests/test_ComboBox.html b/dojox/mobile/tests/test_ComboBox.html
index d9ce66a..79840a9 100644
--- a/dojox/mobile/tests/test_ComboBox.html
+++ b/dojox/mobile/tests/test_ComboBox.html
@@ -88,7 +88,7 @@
 					name: "mobile",
 					timeout: 4000,
 					runTest: function(){
-						widget = new dojox.mobile.ComboBox({id:"mobile_programmatic", list:"states"});
+						widget = new dojox.mobile.ComboBox({id:"mobile_programmatic", list:"states", value:"Alabama" });
 						widget.placeAt("mobile_programmatic_container", "first");
 						focusHandle = widget.connect(widget, 'openDropDown',
 							function(){
diff --git a/dojox/mobile/tests/test_ContentPane.html b/dojox/mobile/tests/test_ContentPane.html
index 573cd3d..1d1c3b8 100644
--- a/dojox/mobile/tests/test_ContentPane.html
+++ b/dojox/mobile/tests/test_ContentPane.html
@@ -1,50 +1,57 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ContentPane</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ContentPane</title>
 
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.ContentPane");
-			dojo.ready(function(){
-				dijit.byId("pane3").set("content", "<div dojoType='dojox.mobile.RoundRect' shadow='true'>Thank you!</div>");
-				dijit.byId("pane4").set("href", "fragment1.html");
-				var dom = dojo.create("DIV", {
-					dojoType: "dojox.mobile.RoundRect",
-					shadow: true
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom-construct",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ContentPane"
+		], function(domConstruct, ready, registry){
+			ready(function(){
+				registry.byId("pane3").set("content", "<div data-dojo-type='dojox.mobile.RoundRect' shadow='true'>Thank you!</div>");
+				registry.byId("pane4").set("href", "data/fragment1.html");
+				var dom = domConstruct.create("DIV", {
+					"data-dojo-type": "dojox.mobile.RoundRect",
+					"data-dojo-props": "shadow:true"
 				});
 				dom.innerHTML = "DOM Tree";
-				dijit.byId("pane5").set("content", dom);
+				registry.byId("pane5").set("content", dom);
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">ContentPane</h1>
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">ContentPane</h1>
 
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Pane1</h2>
-			<div id="pane1" dojoType="dojox.mobile.ContentPane"
-			     content="<div dojoType='dojox.mobile.RoundRect' shadow='true'>Thank you!</div>"></div>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Pane1</h2>
+		<div id="pane1" data-dojo-type="dojox.mobile.ContentPane"
+		     content="<div data-dojo-type='dojox.mobile.RoundRect' shadow='true'>Thank you!</div>"></div>
 
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Pane2</h2>
-			<div id="pane2" dojoType="dojox.mobile.ContentPane"
-			     href="fragment1.html"></div>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Pane2</h2>
+		<div id="pane2" data-dojo-type="dojox.mobile.ContentPane"
+		     href="data/fragment1.html"></div>
 
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Pane3</h2>
-			<div id="pane3" dojoType="dojox.mobile.ContentPane"></div>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Pane3</h2>
+		<div id="pane3" data-dojo-type="dojox.mobile.ContentPane"></div>
 
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Pane4</h2>
-			<div id="pane4" dojoType="dojox.mobile.ContentPane"></div>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Pane4</h2>
+		<div id="pane4" data-dojo-type="dojox.mobile.ContentPane"></div>
 
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Pane5</h2>
-			<div id="pane5" dojoType="dojox.mobile.ContentPane"></div>
-		</div>
-	</body>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Pane5</h2>
+		<div id="pane5" data-dojo-type="dojox.mobile.ContentPane"></div>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_Custom-EdgeToEdgeList.html b/dojox/mobile/tests/test_Custom-EdgeToEdgeList.html
deleted file mode 100644
index 5d82fe2..0000000
--- a/dojox/mobile/tests/test_Custom-EdgeToEdgeList.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Edge to Edge List</title>
-		<link href="../themes/custom/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Options</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Network</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-6.png">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-3.png">
-					Wi-Fi
-					<div style="position:absolute;top:0;right:12px;">
-						<select>
-							<option selected>ON</option>
-							<option>OFF</option>
-						</select>
-					</div>
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Sound</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-2.png">
-					Alarm
-					<div style="position:absolute;top:0;right:12px;">
-						<input type="radio" name="alarm" checked>ON
-						<input type="radio" name="alarm">OFF<br>
-					</div>
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Display</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-1.png">
-					Font
-					<div style="position:absolute;top:0;right:12px;">
-						<input type="checkbox" checked>Bold
-						<input type="checkbox">Italic<br>
-					</div>
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Custom-FormControls.html b/dojox/mobile/tests/test_Custom-FormControls.html
deleted file mode 100644
index 25deac8..0000000
--- a/dojox/mobile/tests/test_Custom-FormControls.html
+++ /dev/null
@@ -1,173 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Form Controls</title>
-		<link href="../themes/custom/custom.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			// mobile form controls
-			dojo.require("dojox.mobile.Button");
-			dojo.require("dojox.mobile.CheckBox");
-			dojo.require("dojox.mobile.ComboBox");
-			dojo.require("dojox.mobile.RadioButton");
-			dojo.require("dojox.mobile.Slider");
-			dojo.require("dojox.mobile.TextBox");
-			dojo.require("dojox.mobile.ExpandingTextArea");
-			dojo.require("dojox.mobile.ToggleButton");
-		</script>
-		
-		<style>
-		.bold {
-			/*font-weight: bold;*/
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<datalist>
-			<select dojoType="dijit.form.DataList" data-dojo-props='id:"states"' >
-				<option value="AL">Alabama</option>
-				<option value="AK">Alaska</option>
-				<option value="AS">American Samoa</option>
-				<option value="AZ">Arizona</option>
-				<option value="AR">Arkansas</option>
-				<option value="AE">Armed Forces Europe</option>
-				<option value="AP">Armed Forces Pacific</option>
-				<option value="AA">Armed Forces the Americas</option>
-				<option value="CA">California</option>
-				<option value="CO">Colorado</option>
-				<option value="CT">Connecticut</option>
-				<option value="DE">Delaware</option>
-				<option value="DC">District of Columbia</option>
-				<option value="FM">Federated States of Micronesia</option>
-				<option value="FL">Florida</option>
-				<option value="GA">Georgia</option>
-				<option value="GU">Guam</option>
-				<option value="HI">Hawaii</option>
-				<option value="ID">Idaho</option>
-				<option value="IL">Illinois</option>
-				<option value="IN">Indiana</option>
-				<option value="IA">Iowa</option>
-				<option value="KS">Kansas</option>
-				<option value="KY">Kentucky</option>
-				<option value="LA">Louisiana</option>
-				<option value="ME">Maine</option>
-				<option value="MH">Marshall Islands</option>
-				<option value="MD">Maryland</option>
-				<option value="MA">Massachusetts</option>
-				<option value="MI">Michigan</option>
-				<option value="MN">Minnesota</option>
-				<option value="MS">Mississippi</option>
-				<option value="MO">Missouri</option>
-				<option value="MT">Montana</option>
-				<option value="NE">Nebraska</option>
-				<option value="NV">Nevada</option>
-				<option value="NH">New Hampshire</option>
-				<option value="NJ">New Jersey</option>
-				<option value="NM">New Mexico</option>
-				<option value="NY">New York</option>
-				<option value="NC">North Carolina</option>
-				<option value="ND">North Dakota</option>
-				<option value="MP">Northern Mariana Islands</option>
-				<option value="OH">Ohio</option>
-				<option value="OK">Oklahoma</option>
-				<option value="OR">Oregon</option>
-				<option value="PA">Pennsylvania</option>
-				<option value="PR">Puerto Rico</option>
-				<option value="RI">Rhode Island</option>
-				<option value="SC">South Carolina</option>
-				<option value="SD">South Dakota</option>
-				<option value="TN">Tennessee</option>
-				<option value="TX">Texas</option>
-				<option value="UT">Utah</option>
-				<option value="VT">Vermont</option>
-				<option value="VI">Virgin Islands, U.S.</option>
-				<option value="VA">Virginia</option>
-				<option value="WA">Washington</option>
-				<option value="WV">West Virginia</option>
-				<option value="WI">Wisconsin</option>
-				<option value="WY">Wyoming</option>
-			</select>
-		</datalist>
-
-		<div dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">dojox.mobile - form controls</h1>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">			
-				<table width="100%">
-					<tr>
-						<td><span class="bold">Button</span></td>
-						<td align="right"><button dojoType="dojox.mobile.Button">Help</button>
-							<input type="submit" class="mblBlueButton" dojoType="dojox.mobile.Button" value="Submit">
-							<button class="mblRedButton" dojoType="dojox.mobile.Button">Cancel</button></td>
-					</tr>
-				</table>
-			</div>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">			
-				<table width="100%">
-					<tr>
-						<td><span class="bold">CheckBox</span></td>
-						<td align="right"><label for="cbox">Click me</label><input type="checkbox" id="cbox" dojoType="dojox.mobile.CheckBox"></td>
-					</tr>
-					<tr>
-						<td><span class="bold">ToggleButton</span></td>
-						<td align="right"><button dojoType="dojox.mobile.ToggleButton">Toggle me</button></td>
-					</tr>
-					<tr>
-						<td><span class="bold">Switch</span></td>
-						<td align="right"><input type="checkbox" dojoType="dojox.mobile.Switch" value="on"></td>
-					</tr>
-				</table>
-			</div>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">			
-				<table width="100%">
-					<tr>
-						<td><span class="bold">Radio Button</span></td>
-						<td align="right"><input type="radio" id="rb1" dojoType="dojox.mobile.RadioButton" name="mobileRadio" value="Large" checked><label for="rb1">1</label>
-							<input type="radio" id="rb2" dojoType="dojox.mobile.RadioButton" name="mobileRadio" value="Medium"><label for="rb2">2</label>
-							<input type="radio" id="rb3" dojoType="dojox.mobile.RadioButton" name="mobileRadio" value="Small"><label for="rb3">3</label></td>
-					</tr>
-				</table>
-			</div>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">			
-				<table width="100%">
-					<tr>
-						<td><span class="bold">Slider</span></td>
-						<td align="right">
-							<table>
-								<tr>
-									<td>0</td>
-									<td><input id="sh" name="sh" dojoType="dojox.mobile.Slider" value="0" min="0" max="20" step="0.1" type="range" style="width:150px;"></td>
-									<td>20</td>
-								</tr>
-							</table>
-						</td>
-					</tr>
-				</table>
-			</div>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">			
-				<table width="100%">
-					<tr>
-						<td><span class="bold">ComboBox</span></td>
-						<td align="right"><input type="text" dojoType="dojox.mobile.ComboBox" data-dojo-props='value:"", list:"states"'></td>
-					</tr>
-					<tr>
-						<td valign="top"><span class="bold">TextArea</span></td>
-						<td align="right">
-							<textarea dojoType="dojox.mobile.TextArea" rows="3" cols="20">TextArea</textarea><br>
-							<textarea dojoType="dojox.mobile.ExpandingTextArea" rows="3" cols="20">ExpandingTextArea</textarea>
-						</td>
-					</tr>
-					<tr>
-						<td valign="top"><span class="bold">TextBox</span></td>
-						<td align="right"><input dojoType="dojox.mobile.TextBox" maxLength="9" selectOnClick="true" placeHolder="max 9 chars"></td>
-					</tr>
-				</table>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Custom-Heading.html b/dojox/mobile/tests/test_Custom-Heading.html
deleted file mode 100644
index e9c03a7..0000000
--- a/dojox/mobile/tests/test_Custom-Heading.html
+++ /dev/null
@@ -1,121 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Heading</title>
-		<link href="../themes/custom/custom.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-			dojo.ready(function(){
-				var btn1 = dijit.byId("btn1");
-				btn1.connect(btn1.domNode, "onclick", function(){
-					console.log(this.label + " button was clicked");
-				});
-			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="general" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">General</h1>
-			<h1 dojoType="dojox.mobile.Heading" back="Long Button" moveTo="settings">Very Very Long Title May Not Be Displayed in the Narrow Space - Very Very Long Title May Not Be Displayed in the Narrow Space</h1>
-		</div>
-
-		<h3>Heading with buttons</h3>
-
-		<h1 dojoType="dojox.mobile.Heading" label="World Clock">
-			<div id="btn1" dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px;float:left">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;" onclick="console.log('+ was clicked')"></div>
-
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px;float:left;">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;"></div>
-			Alarm Clock
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Voice Memos">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Speaker" style="float:left"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Updates">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="News" back="Bookmarks" moveTo="bookmarks">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="New Folder" style="float:right;"></div>
-		</h1><br>
-
-
-		<div dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">New</div>
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">Toggle</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icon-18h.png" moveTo="view3" style="padding:0 10px"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icons.png" iconPos="29,0,29,29" moveTo="view3" style="padding:0 10px"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" moveTo="view3" style="float:right;"></div>
-		</div><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:left;margin-left:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px" selected="true">Catalog</li>
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px">Share</li>
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px">Download</li>
-			</ul>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" align="center">
-		  <table cellpadding="0" cellspacing="0" style="width:100%;"><tr>
-			<td><div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus"></div></td>
-			<td align="center"><div dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="margin:auto;">
-				<div dojoType="dojox.mobile.TabBarButton" selected="true" style="width:80px">Search</div>
-				<div dojoType="dojox.mobile.TabBarButton" style="width:80px">Directions</div>
-			</div></td>
-			<td align="right"><div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icon-15h.png" style="float:right;"></div></td>
-		  </tr></table>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Inbox" label="1 of 10">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:right;margin-right:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteDownArrow" selectOne="false"></li>
-			</ul>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Top" label="Inbox(32)">
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteUpArrow" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteDownArrow" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Inbox" label="1 of 10">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:right;margin-right:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteSearch" selectOne="false"></li>
-			</ul>
-		</h1><br>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Custom-Icon.html b/dojox/mobile/tests/test_Custom-Icon.html
deleted file mode 100644
index 081b90f..0000000
--- a/dojox/mobile/tests/test_Custom-Icon.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon</title>
-		<link href="../themes/custom/base.css" rel="stylesheet">
-		<link href="../themes/custom/IconContainer.css" rel="stylesheet">
-
-		<style>
-			.box {
-				border: 1px solid #A7C0E0;
-				width: 300px;
-				height: 250px;
-				background-image: url(images/widget-bg.png);
-				background-repeat: no-repeat;
-				background-color: white;
-			}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="app1" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app2" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app3" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="moveTo" icon="images/icon-1.png" moveTo="about" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="href" icon="images/icon-1.png" href="test_Custom-RoundRectList.html" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="url" icon="images/icon-1.png" url="view-sample.html" transition="slide"></li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Custom-Opener.html b/dojox/mobile/tests/test_Custom-Opener.html
deleted file mode 100644
index 0c3232f..0000000
--- a/dojox/mobile/tests/test_Custom-Opener.html
+++ /dev/null
@@ -1,156 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html style="overflow:hidden;">
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>test Opener</title>
-	<link href="../themes/common/SpinWheel.css" rel="stylesheet">
-	<link href="../themes/common/dijit/dijit.css" rel="stylesheet">
-	<link href="../themes/custom/custom.css" rel="stylesheet">
-	<style>
-		.mblTooltip.mblOpener DIV[label='Cancel'] {
-			display: none;
-		}
-		HTML {
-			min-height: 100%; /* workaround for android 3.x position:fixed bug */
-		}
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		dojo.require("dojox.mobile");			// This is a mobile app.
-		dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-		dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		dojo.require("dojox.mobile.SpinWheelDatePicker");
-		dojo.require("dojox.mobile.Opener");
-		dojo.require("dijit.CalendarLite");
-		dojo.require("dijit.ColorPalette");
-		dojo.require("dojox.widget.ColorPicker");
-
-		function getDate(node, v){
-			if(v === true){ // Done clicked
-				node.value = dijit.byId("spin1").getValue().join('-');
-			}
-		}
-		function setDate(node){
-			var v = node.value.split(/-/);
-			if(v.length == 3){
-				var w = dijit.byId("spin1");
-				w.setValue(v);
-			}
-		}
-
-		function getDate2(node, v){
-			if(v === true){ // Done clicked
-				var w = dijit.byId("cal");
-				var date;
-				try {
-					date = w.get("value");
-				} catch (e) {
-					return;
-				}
-				node.value = date;
-			}
-		}
-		function setDate2(node){
-			var v = node.value.split(/-/);
-			if(v.length == 3){
-				var w = dijit.byId("cal");
-				w.setValue(v);
-			}
-		}
-		function getColor1(node, v){
-			if(v === true){ // Done clicked
-				var w = dijit.byId("colorPalette");
-				var color = w.get("value");
-				node.value = color;
-				node.style.backgroundColor = color;
-				node.style.color =  "#" + (255-parseInt(color.substr(1,2), 16)).toString(16)
-							+ (255-parseInt(color.substr(3,2), 16)).toString(16)
-							+ (255-parseInt(color.substr(5,2), 16)).toString(16);
-			}
-		}
-		function getColor2(node, v){
-			if(v === true){ // Done clicked
-				var w = dijit.byId("colorPicker");
-				var color = w.get("value");
-				node.value = color;
-				node.style.backgroundColor = color;
-				node.style.color =  "#" + (255-parseInt(color.substr(1,2), 16)).toString(16)
-							+ (255-parseInt(color.substr(3,2), 16)).toString(16)
-							+ (255-parseInt(color.substr(5,2), 16)).toString(16);
-			}
-		}
-	</script>
-</head>
-<body style="visibility:hidden;">
-	<table cellspacing="20">
-	<tr>
-		<td style="text-align:right;">Date (SpinWheel)</td>
-		<td><input id="date1" readOnly value=""
-			onclick="dijit.byId('datePicker').show(this, ['above-centered','below-centered','after','before'])"></td>
-	</tr>
-	<tr>
-		<td style="text-align:right;">Date (Calendar)</td>
-		<td><input id="date3" readOnly value=""
-			onclick="dijit.byId('calPicker').show(this, ['above-centered','below-centered','after','before'])"></td>
-	</tr>
-	<tr>
-		<td style="text-align:right;">Color (Palette)</td>
-		<td><input id="color1" readOnly value="transparent" style="background-color:transparent;"
-			onclick="dijit.byId('colorPicker1').show(this, ['above-centered','below-centered','after','before'])"></td>
-	</tr>
-	<tr>
-		<td style="text-align:right;">Color (Picker)</td>
-		<td><input id="color2" readOnly value="transparent" style="background-color:transparent;"
-			onclick="dijit.byId('colorPicker2').show(this, ['above-centered','below-centered','after','before'])"></td>
-	</tr>
-	</table>
-	<center style="position:fixed;bottom:0;width:100%;">
-		<label for="date2">Date (SpinWheel above): </label>
-		<input id="date2" readOnly value=""
-			onclick="dijit.byId('datePicker').show(this, ['above-centered','below-centered','after','before'])">
-	</center>
-
-	<div id="datePicker" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getDate, onShow:setDate">
- 		<h1 dojoType="dojox.mobile.Heading" label="Date Picker">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
-				onclick="dijit.byId('datePicker').hide(true)"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
-				onclick="dijit.byId('datePicker').hide(false)"></div>
-		</h1>
-		<div id="spin1" dojoType="dojox.mobile.SpinWheelDatePicker"></div>
-	</div>
-
-	<div id="calPicker" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getDate2, onShow:setDate2">
- 		<h1 dojoType="dojox.mobile.Heading" label="Select a Date">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
-				onclick="dijit.byId('calPicker').hide(true)"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
-				onclick="dijit.byId('calPicker').hide(false)"></div>
-		</h1>
-		<div id="cal" dojoType='dijit.CalendarLite'></div>
-	</div>
-
-	<div id="colorPicker1" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getColor1">
- 		<h1 dojoType="dojox.mobile.Heading" label="Select a Color">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
-				onclick="dijit.byId('colorPicker1').hide(true)"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
-				onclick="dijit.byId('colorPicker1').hide(false)"></div>
-		</h1>
-		<div id="colorPalette" dojoType='dijit.ColorPalette'></div>
-	</div>
-
-	<div id="colorPicker2" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getColor2">
- 		<h1 dojoType="dojox.mobile.Heading" label="Select a Color">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
-				onclick="dijit.byId('colorPicker2').hide(true)"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
-				onclick="dijit.byId('colorPicker2').hide(false)"></div>
-		</h1>
-		<div id="colorPicker" dojoType='dojox.widget.ColorPicker'></div>
-	</div>
-
-</body>
-</html>
diff --git a/dojox/mobile/tests/test_Custom-RoundRectList.html b/dojox/mobile/tests/test_Custom-RoundRectList.html
deleted file mode 100644
index a1968d8..0000000
--- a/dojox/mobile/tests/test_Custom-RoundRectList.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Round Rectangle List</title>
-		<link href="../themes/custom/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Options</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Network</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-6.png">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-3.png">
-					Wi-Fi
-					<div style="position:absolute;top:0;right:12px;">
-						<select>
-							<option selected>ON</option>
-							<option>OFF</option>
-						</select>
-					</div>
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Sound</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-2.png">
-					Alarm
-					<div style="position:absolute;top:0;right:12px;">
-						<input type="radio" name="alarm" checked>ON
-						<input type="radio" name="alarm">OFF<br>
-					</div>
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Display</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/b-icon-1.png">
-					Font
-					<div style="position:absolute;top:0;right:12px;">
-						<input type="checkbox" checked>Bold
-						<input type="checkbox">Italic<br>
-					</div>
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Custom-Settings.html b/dojox/mobile/tests/test_Custom-Settings.html
deleted file mode 100644
index 518365a..0000000
--- a/dojox/mobile/tests/test_Custom-Settings.html
+++ /dev/null
@@ -1,167 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Settings</title>
-		<link href="../themes/custom/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Settings</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="mac" href="test_iPhone-Icon.html">
-					Wi-Fi
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="AcmePhone" moveTo="general">
-					Carrier
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-					Sounds
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="general">
-					Brightness
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="general">
-					Wallpaper
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="general">
-					General
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="general">
-					Mail, Contacts, Calendars
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="general">
-					Phone
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="general">
-					Safari
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="general">
-					SMS/MMS
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="general">
-					iPod
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="general">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-					Store
-				</li>
-			</ul>
-		</div>
-
-		<div id="general" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">General</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					About
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2h 40m" moveTo="about">
-					Usage
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Network
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Bluetooth
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Location Services
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="1 Minute" moveTo="about">
-					Auto-Lock
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Passcode Lock
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Restrictions
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Home
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Date & Time					   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Keyboard					   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					International				   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Accessibility
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Reset
-				</li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="General" moveTo="general">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="10">
-					Videos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="96">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2">
-					Applications
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-					Capacity
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-					Available
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-					Version
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Custom-TabBar.html b/dojox/mobile/tests/test_Custom-TabBar.html
deleted file mode 100644
index 70ae2b2..0000000
--- a/dojox/mobile/tests/test_Custom-TabBar.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>TabBar</title>
-		<link href="../themes/custom/base.css" rel="stylesheet">
-		<link href="../themes/custom/TabBar.css" rel="stylesheet">
-		<style>
-		.label {
-			font-family: "Helvetica Neue", Helvetica;
-			font-size: 13px;
-			margin-top: 20px;
-		}
-		.view {
-			font-size: 30px;
-			padding-top: 30px;
-			text-align: center;
-		}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div class="label">Segmented Control</div>
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar</div>
-		<ul dojoType="dojox.mobile.TabBar">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar (CSS Sprite)</div>
-		<ul dojoType="dojox.mobile.TabBar" iconBase="images/tab-icons.png">
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Featured</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,29,29,29" iconPos2="29,29,29,29">Categories</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,58,29,29" iconPos2="29,58,29,29">Top 25</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,87,29,29" iconPos2="29,87,29,29">Search</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,116,29,29" iconPos2="29,116,29,29">Updates</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<div class="view">View 1</div>
-		</div>
-		<div id="view2" dojoType="dojox.mobile.View">
-			<div class="view">View 2</div>
-		</div>
-		<div id="view3" dojoType="dojox.mobile.View">
-			<div class="view">View 3</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Custom-Tooltip.html b/dojox/mobile/tests/test_Custom-Tooltip.html
deleted file mode 100644
index c56f468..0000000
--- a/dojox/mobile/tests/test_Custom-Tooltip.html
+++ /dev/null
@@ -1,117 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html style="overflow:hidden;">
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>test Tooltip</title>
-		<link href="../themes/common/SpinWheel.css" rel="stylesheet">
-		<link href="../themes/custom/custom.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<style>
-		.dj_phone BUTTON {
-			display:none;
-		}
-		INPUT {
-			font-family: monospace;
-			border-radius: 0px;
-		}
-		#spin1 {
-			width: 304px;
- 		}
-		#pt {
-			width: 20px;
-			background-color: #C4C9DB;
-			opacity: 0.2;
-		}
-		#txt {
-			width: 10px;
-			margin-left: -15px;
-			padding-top: 85px;
-			font-size: 24px;
-			font-weight: bold;
-			border: none;
-		}
-		HTML {
-			min-height: 100%; /* workaround for android 3.x position:fixed bug */
-		}
-		</style>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.SpinWheel");
-			dojo.require("dojox.mobile.SpinWheelSlot");
-			dojo.require("dojox.mobile.Tooltip");
-			dojo.require("dojox.mobile.common");
-			dojo.addOnLoad(function(){
-				dojo.byId('bot').scrollIntoView(false);
-			});
-
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<center style="width:100%;">
-			<button type="button" onclick="dijit.byId('customPicker').show(this, ['above','below-centered','before','after'])">below</button>
-			<input readonly onclick="dijit.byId('textTooltip').show(this, ['above-centered','below-centered','after','before'])" value="below" size="5">
-			<br><br><b>Click boundary nodes to see tooltips</b>
-		</center>
-		<center id="bot" class="bottom" style="position:fixed;bottom:0;width:100%;">
-			<input readonly tabindex="0" onclick="dijit.byId('textTooltip').show(this, ['above-centered','below-centered','before','after'])" value="above" size="5">
-			<button type="button" tabindex="0" onclick="dijit.byId('customPicker').show(this, ['below','above-centered','after','before'])">above</button>
-		</center>
-		<center style="position:fixed;top:33%;width:100%;">
-			<button type="button" onclick="dijit.byId('customPicker').hide()">click to hide spin wheels</button>
-		</center>
-		<center style="position:fixed;bottom:33%;width:100%;">
-			<input readonly onclick="dijit.byId('textTooltip').hide()" value="click to hide text tooltip" size="26">
-		</center>
-		<div style="position:fixed;top:50%;left:1px;direction:ltr;">
-			<input readonly onclick="dijit.byId('textTooltip').show(this, ['before','after','below-centered','above-centered'])" value="right" size="5">
-			<br>
-			<br>
-			<button type="button" onclick="dijit.byId('customPicker').show(this, ['before','after','below-centered','above-centered'])">right</button>
-		</div>
-		<div style="position:fixed;bottom:50%;right:1px;direction:rtl;">
-			<button type="button" onclick="dijit.byId('customPicker').show(this, ['after','before','above','below'])">left</button>
-			<br>
-			<br>
-			<input readonly onclick="dijit.byId('textTooltip').show(this, ['after','before','below','above'])" value="left" size="4">
-		</div>
-
-		<div id="textTooltip" dojoType="dojox.mobile.Tooltip" class="mblTooltipBubble">Enter a value.<br><center>Please!</center></div>
-
-		<div id="customPicker" dojoType="dojox.mobile.Tooltip">
-			<div id="spin1" dojoType="dojox.mobile.SpinWheel">
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="['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']"
-					style="text-align:center;width:40px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labelFrom="3000" labelTo="3100"
-					style="width:70px;"></div>
-				<div id="pt" class="mblSpinWheelSlot"></div>
-				<div id="txt" class="mblSpinWheelSlot">.</div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labelFrom="0" labelTo="9"
-					style="width:30px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="['pt','px','cm']"
-					style="width:50px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="[
-						'<img src=images/i-icon-1.png>',
-						'<img src=images/i-icon-2.png>',
-						'<img src=images/i-icon-3.png>',
-						'<img src=images/i-icon-4.png>',
-						'<img src=images/i-icon-5.png>',
-						'<img src=images/i-icon-6.png>',
-						'<img src=images/i-icon-7.png>',
-						'<img src=images/i-icon-8.png>',
-						'<img src=images/i-icon-9.png>',
-						'<img src=images/i-icon-10.png>'
-					]"
-					style="width:70px;text-align: center;"></div>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Custom-css-sprite.html b/dojox/mobile/tests/test_Custom-css-sprite.html
deleted file mode 100644
index 757e457..0000000
--- a/dojox/mobile/tests/test_Custom-css-sprite.html
+++ /dev/null
@@ -1,170 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Settings</title>
-		<link href="../themes/custom/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			if(dojo.isBB){
-				console.log("CSS Sprite is not supported for the BlackBerry browser");
-			}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Settings</h1>
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,29,29,29" rightText="mac" href="test_Custom-Icon.html">
-					Wi-Fi
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29" rightText="AcmePhone" moveTo="general">
-					Carrier
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">
-					Sounds
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" moveTo="general">
-					Brightness
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29" moveTo="general">
-					Wallpaper
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,29,29,29" moveTo="general">
-					General
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,58,29,29" moveTo="general">
-					Mail, Contacts, Calendars
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,87,29,29" moveTo="general">
-					Phone
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,116,29,29" moveTo="general">
-					Safari
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" moveTo="general">
-					SMS/MMS
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,29,29,29" moveTo="general">
-					iPod
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29" moveTo="general">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">
-					Store
-				</li>
-			</ul>
-		</div>
-
-		<div id="general" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">General</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					About
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2h 40m" moveTo="about">
-					Usage
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Network
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Bluetooth
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Location Services
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="1 Minute" moveTo="about">
-					Auto-Lock
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Passcode Lock
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Restrictions
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Home
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Date & Time					   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Keyboard					   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					International				   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Accessibility
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Reset
-				</li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="General" moveTo="general">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="10">
-					Videos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="96">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2">
-					Applications
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-					Capacity
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-					Available
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-					Version
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_Custom-list-domButtons.html b/dojox/mobile/tests/test_Custom-list-domButtons.html
deleted file mode 100644
index e4a4fed..0000000
--- a/dojox/mobile/tests/test_Custom-list-domButtons.html
+++ /dev/null
@@ -1,227 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>List with domButtons</title>
-		<link href="../themes/custom/base.css" rel="stylesheet">
-		<link href="../themes/common/domButtons.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			function setRightIcon2Value(id, val){
-				var txt = dojo.doc.createTextNode(val);
-				dijit.byId(id).rightIcon2Node.firstChild.firstChild.appendChild(txt);
-			}
-			function setIconValue(id, val){
-				var txt = dojo.doc.createTextNode(val);
-				dijit.byId(id).iconNode.firstChild.firstChild.firstChild.firstChild.appendChild(txt);
-			}
-			dojo.ready(function(){
-				setRightIcon2Value("item1", "32");
-				setRightIcon2Value("item2", "5");
-				setRightIcon2Value("item3", "108");
-				setIconValue("item42", "3");
-				dojo.forEach(dijit.byId("list1").getChildren(), function(w){
-					dojo.connect(w.iconNode, "onclick", w, function(e){
-						console.log(this);
-						dijit.byId("list1").removeChild(this);
-					});
-				});
-				dojo.forEach(dijit.byId("list5").getChildren(), function(w){
-					dojo.connect(w.iconNode, "onclick", w, function(e){
-						console.log(this);
-						dijit.byId("list5").removeChild(this);
-					});
-				});
-			});
-		</script>
-		<style>
-		#item1, #item2, #item3 {
-			font-weight: normal;
-			font-size: 12px;
-		}
-		.subject {
-			font: bold 16px Helvetica;
-		}
-		
-		/* Note: The class name of DOM buttons must start with "mblDomButton". */
-		
-		/* === My Custom Button1 ==*/
-		.mblDomButtonMyCustomButton1 {
-			position: relative;
-			width: 30px;
-			height: 30px;
-			border-width: 1px;
-			border-style: outset;
-			border-color: #A5A2A5;
-			color: white;
-			-webkit-border-radius: 3px;
-			background-color: #D6D3D6;
-			background: -webkit-gradient(linear, left top, left bottom, from(#EFF3EF), to(#BDBEBD));
-		}
-		.mblDomButtonMyCustomButton1 > DIV {
-			position: absolute;
-			top: 13px;
-			left: 5px;
-			width: 20px;
-			height: 4px;
-			margin: 0px;
-			font-size: 1px;
-			background-color: red;
-			-webkit-border-radius: 2px;
-			-webkit-transform: rotate(45deg);
-		}
-		.mblDomButtonMyCustomButton1 > DIV > DIV {
-			position: absolute;
-			top: -8px;
-			left: 8px;
-			width: 4px;
-			height: 20px;
-			margin: 0px;
-			font-size: 1px;
-			background-color: red;
-			-webkit-border-radius: 2px;
-		}
-		
-		/* === My Custom Button2 ==*/
-		.mblDomButtonMyCustomButton2 {
-			position: relative;
-			width: 29px;
-			height: 29px;
-		}
-		
-		.mblDomButtonMyCustomButton2 > DIV {
-			position: relative;
-			top: 2px;
-			left: 2px;
-			width: 22px;
-			height: 22px;
-			border: 1px solid #B5B6B5;
-			-webkit-border-radius: 12px;
-			-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
-		}
-		.mblDomButtonMyCustomButton2 > DIV > DIV {
-			position: relative;
-			top: 2px;
-			left: 2px;
-			width: 18px;
-			height: 18px;
-			-webkit-border-radius: 9px;
-			background-color: green;
-		}
-		.mblDomButtonMyCustomButton2 > DIV > DIV > DIV {
-			position: relative;
-			color: white;
-			text-align: center;
-			line-height: 17px;
-			font-size: 14px;
-		}
-		.mblDomButtonMyCustomButton2 > DIV > DIV > DIV > DIV {
-			display: none;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">View 1</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">RoundRectList</h2>
-			<ul id="list1" dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus"
-				    moveTo="view2" arrowClass="mblDomButtonSilverCircleDownArrow">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus"
-				    moveTo="view2" arrowClass="mblDomButtonSilverCircleGreenButton">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus"
-				    moveTo="view2" arrowClass="mblDomButtonSilverCircleRedCross">
-					Fade
-				</li>
-			</ul>
-		</div>
-
-		<div id="view2" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="view1">View 2</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Dom Button with Text</h2>
-			<ul id="list2" dojoType="dojox.mobile.RoundRectList">
-				<li id="item1" class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    icon="mblDomButtonBlueBall" moveTo="view3" btnClass2="mblDomButtonGrayRoundRect">
-					<div class="subject">Dojo: Traditional Karate-do Spirit</div>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock
-				</li>
-				<li id="item2" class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    icon="mblDomButtonTransparent19" moveTo="view3" btnClass2="mblDomButtonGrayRoundRect">
-					<div class="subject">Japanese Martial Arts Dojo</div>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock
-				</li>
-				<li id="item3" class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    icon="mblDomButtonGreenBall" moveTo="view3" btnClass2="mblDomButtonGrayRoundRect">
-					<div class="subject">Total Solar Eclipse</div>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock
-				</li>
-			</ul>
-		</div>
-
-		<div id="view3" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="view2">View 3</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Variable Height List</h2>
-			<ul id="list3" dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    moveTo="view4" arrowClass="mblDomButtonBlueCircleArrow">
-					Top 10 news stories of the decade
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    moveTo="view4" arrowClass="mblDomButtonBlueCircleArrow">
-					Create client-side diagrammatic interaction in Web applications with GFX
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    moveTo="view4" arrowClass="mblDomButtonBlueCircleArrow">
-					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
-				</li>
-			</ul>
-		</div>
-
-		<div id="view4" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="view3">View 4</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Custom DOM Buttons</h2>
-			<ul id="list4" dojoType="dojox.mobile.RoundRectList">
-				<li id="item41" dojoType="dojox.mobile.ListItem" icon="mblDomButtonMyCustomButton1"
-				    moveTo="view5">
-					My Custom Button 1
-				</li>
-				<li id="item42" dojoType="dojox.mobile.ListItem" icon="mblDomButtonMyCustomButton2"
-				    moveTo="view5">
-					My Custom Button 2
-				</li>
-			</ul>
-		</div>
-
-		<div id="view5" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="view4">View 5</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">EdgeToEdgeList</h2>
-			<ul id="list5" dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus" rightText="mac" moveTo="view1">
-					Wi-Fi
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus" rightText="AcmePhone" moveTo="view1">
-					Carrier
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_DataCarousel-demo.html b/dojox/mobile/tests/test_DataCarousel-demo.html
new file mode 100644
index 0000000..cc0cab1
--- /dev/null
+++ b/dojox/mobile/tests/test_DataCarousel-demo.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel Demo (dojo.data)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/data/ItemFileReadStore",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/DataCarousel"
+		], function(connect, ItemFileReadStore, ready, registry){
+			store1 = new ItemFileReadStore({url: "data/carousel-categ.json"});
+			ready(function(){
+				connect.subscribe("/dojox/mobile/carouselSelect", function(w, img, item, idx){
+					if(w.id == "carousel1"){
+						var store2 = new ItemFileReadStore({url: "data/carousel-"+item.value+".json"});
+						var w2 = registry.byId("carousel2");
+						w2.set("title", item.value);
+						w2.setStore(store2);
+						registry.byId("rect1").domNode.style.display = "none";
+					}else if(w.id == "carousel2"){
+						var rect1 = registry.byId("rect1");
+						var u = "unknown";
+						var desc = "<div style='float:right;font:14px arial;width:49%'>Model: "+(item.model?item.model:u)+"<br>"+
+							"Design: "+(item.design?item.design:u)+"<br>"+
+							"Produced: "+(item.produced?item.produced:u)+"<br>"+
+							"Size: "+(item.size?item.size:u)+"<br>"+
+							"Price: "+(item.price?item.price:u)+"<br></div>";
+						rect1.containerNode.innerHTML = desc+"<img src='"+item.src+"' width='50%' align='top'>";
+						rect1.domNode.style.display = "";
+					}
+				});
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.ScrollableView">
+		<div id="carousel1" data-dojo-type="dojox.mobile.DataCarousel"
+			data-dojo-props='height:"150px", navButton:true, store:store1, itemWidth:156, title:"Category"'></div>
+		<div id="carousel2" data-dojo-type="dojox.mobile.DataCarousel"
+			data-dojo-props='height:"110px", navButton:true, itemWidth:100'></div>
+		<div id="rect1" data-dojo-type="dojox.mobile.RoundRect" style="display:none"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_DataCarousel.html b/dojox/mobile/tests/test_DataCarousel.html
new file mode 100644
index 0000000..095acdc
--- /dev/null
+++ b/dojox/mobile/tests/test_DataCarousel.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel (dojo.data)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/data/ItemFileReadStore",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/View",
+			"dojox/mobile/DataCarousel"
+		], function(ItemFileReadStore){
+			store1 = new ItemFileReadStore({url: "data/carousel-dish.json"});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<div id="carousel1" data-dojo-type="dojox.mobile.DataCarousel"
+			data-dojo-props='height:"150px", navButton:true, store:store1, numVisible:2, title:"Category"'></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_DatePicker.html b/dojox/mobile/tests/test_DatePicker.html
new file mode 100644
index 0000000..84427ac
--- /dev/null
+++ b/dojox/mobile/tests/test_DatePicker.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>DatePicker</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','DatePicker']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/DatePicker"
+		], function(registry){
+			gotoToday = function(){
+				registry.byId("picker1").reset();
+			}
+			showSelectedValue = function(){
+				var w = registry.byId("picker1");
+				document.getElementById("msg").innerHTML =
+					w.slots[0].get("value")+ ":" + w.slots[1].get("value") + ":" + w.slots[2].get("value");
+			}
+		});
+	</script>
+
+	<style>
+	#picker1 {
+		margin: 20px;
+	}
+	.windows_theme #picker1 {
+		margin: 20px 0px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="showSelectedValue()" data-dojo-props='label:"OK"'></span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="gotoToday()" data-dojo-props='label:"Today"'></span>
+		</div>
+		<div id="picker1" data-dojo-type="dojox.mobile.DatePicker"></div>
+		<div id="msg"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_DatePicker2.html b/dojox/mobile/tests/test_DatePicker2.html
new file mode 100644
index 0000000..72a5ac6
--- /dev/null
+++ b/dojox/mobile/tests/test_DatePicker2.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>DatePicker2</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" ></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: false"></script>
+	
+	<script type="text/javascript">
+		var opener, updateDate, showDatePicker, onShow, onHide, datePicker1, datePicker2;
+		onShow = function(){
+				// console.log("Set datePicker to current date: ", date.toISOString());
+				datePicker2.set("value", date);
+			};
+		onHide = function(node, v){
+				if(v){
+					var newDate = datePicker2.get("value");
+					// console.log("newDate: ", newDate);
+					node.value = newDate;
+					// set new Date
+					date = newDate;
+				}
+		};
+		require(["dojo/ready","dojox/mobile/parser",
+			"dijit/registry", "dojox/mobile/DatePicker", "dojo/date/stamp", "dojox/mobile/Opener", "dojox/mobile/compat",
+			"dojox/mobile/Heading", "dojox/mobile/ToolBarButton"], 
+	function(ready, parser, registry, DatePicker, stamp) {
+		ready(function() {
+			parser.parse();
+					
+			// First DatePicker:
+			datePicker1 = registry.byId("datePicker1");
+			// set the value of a picker already displayed, after construction time
+			datePicker1.set("value", "2020-01-01");
+
+			// Second DatePicker:
+			datePicker2 = registry.byId("datePicker2");
+			opener = registry.byId("opener");
+			// initialize the globale Date variable as today
+			date = stamp.toISOString(new Date(), {selector: "date"});
+			// console.log("Initial date is: ", date);
+			
+			showDatePicker = function(toto) {
+				opener.show(toto, ['below-centered','above-centered','after','before']);
+			};
+			updateDate = function() {
+				// console.log("update date to new Date:", date);
+				var newDate = new Date(stamp.fromISOString(date));
+				newDate.setFullYear("2020");
+				date = stamp.toISOString(newDate, {selector: "date"});
+			}
+		});
+	});
+</script>
+</head>
+<body>
+
+<div>
+	<div style="text-align:left;font-weight:bold">The date picker below should be 
+		displaying: Jan-01-2020</div>
+	<div id="datePicker1" data-dojo-type="dojox/mobile/DatePicker"></div>
+	<hr>
+	<div style="text-align:left;font-weight:bold">The date picker below should display 
+		the current date unless you change the year using the button</div>
+	<input readOnly value="" placeholder="Select a date" 
+		onclick="showDatePicker(this)"></input>
+	<div id="opener" data-dojo-type="dojox/mobile/Opener"
+		data-dojo-props="onShow: onShow, onHide: onHide">
+		<h1 data-dojo-type="dojox/mobile/Heading" label="Date Picker">
+			<span data-dojo-type="dojox/mobile/ToolBarButton" 
+				data-dojo-props="label:'Done'" class="mblColorBlue"
+				onclick="opener.hide(true)" 
+				style="position:absolute;width:45px;right:0;">
+			</span>
+			<span data-dojo-type="dojox/mobile/ToolBarButton" 
+				data-dojo-props="label:'Cancel'" class="mblColorBlue" 
+				onclick="opener.hide(false)"
+				style="position:absolute;width:45px;left:0;">
+			</span>
+		</h1>
+		<div id="datePicker2" data-dojo-type="dojox/mobile/DatePicker"></div>
+	</div>
+	<button onclick="updateDate();">Change year to 2020</button>
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeCategory.html b/dojox/mobile/tests/test_EdgeToEdgeCategory.html
new file mode 100644
index 0000000..76053ef
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeCategory.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Edge to Edge Category</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="settings" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Edge-to-Edge List</h1>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">J</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Jack Coleman
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				James Evans
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Jason Griffin
+			</li>
+		</ul>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">K</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Karen Hughes
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Kelly Perry
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Kevin Rivera
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeDataList-auto-sv.html b/dojox/mobile/tests/test_EdgeToEdgeDataList-auto-sv.html
new file mode 100644
index 0000000..7dd4a98
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeDataList-auto-sv.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeDataList - Auto Load</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojo/dom-class",
+			"dojox/data/QueryReadStore",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ProgressIndicator",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/EdgeToEdgeDataList"
+		], function(Deferred, domClass, QueryReadStore, ready, registry, ProgressIndicator){
+			//var url = "data/fruits.json";
+			var url = "data/fake_service.php";
+			store = new QueryReadStore({url: url});
+
+			var start = 1,
+				count = 5,
+				prog1 = null,
+				list = null;
+			function loadMore(){
+				busy(true);
+				setTimeout(function(){ // to simulate network latency
+					Deferred.when(list.setQuery({start:start, count:count}), function(){
+						busy(false);
+					});
+					start += count;
+					return false;
+				}, 1000);
+			};
+
+			function busy(flag){
+				if(!prog1){
+					prog1 = new ProgressIndicator({size:30, center:false});
+					prog1.domNode.style.position = "absolute";
+					prog1.domNode.style.margin = "5px";
+					domClass.add(prog1.domNode, "mblProgWhite");
+				}
+				if(flag){
+					var head1 = registry.byId("head1");
+					prog1.placeAt(head1.domNode);
+					prog1.start();
+				}else{
+					prog1.stop();
+				}
+			}
+
+			adjustDestination = function(to, pos, dim){
+				var dim = this.getDim();
+				var h = dim.c.h; // container height
+				var disp = dim.d.h; // display height
+				if(to.y < disp - h){
+					loadMore();
+					to.y = disp - h;
+				}
+				return true;
+			}
+
+			ready(function(){
+				list = registry.byId("list");
+				list.setStore(store, {start:start, count:count});
+				start += count;
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='adjustDestination:adjustDestination'>
+		<h1 data-dojo-type="dojox.mobile.Heading" id="head1" data-dojo-props='fixed:"top"'>EdgeToEdgeDataList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="list" data-dojo-props='append:true'></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeDataList-auto-v.html b/dojox/mobile/tests/test_EdgeToEdgeDataList-auto-v.html
new file mode 100644
index 0000000..5af9b50
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeDataList-auto-v.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeDataList - Auto Load</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/_base/window",
+			"dojox/data/QueryReadStore",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeDataList"
+		], function(connect, win, QueryReadStore, ready, registry){
+			//var url = "data/fruits.json";
+			var url = "data/fake_service.php";
+			store = new QueryReadStore({url: url});
+
+			var start = 1,
+				count = 5,
+				list = null;
+			function loadMore(){
+				setTimeout(function(){ // to simulate network latency
+					list.setQuery({start:start, count:count});
+					start += count;
+				}, 1000);
+			};
+
+			ready(function(){
+				list = registry.byId("list");
+				list.setStore(store, {start:start, count:count});
+				start += count;
+				connect.connect(win.global, "onscroll", null, function(e){
+					var h = win.global.innerHeight||win.doc.documentElement.clientHeight||win.doc.documentElement.offsetHeight;
+					if(win.body().scrollTop + h === win.body().offsetHeight){
+						loadMore();
+					}
+				})
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" id="head1">EdgeToEdgeDataList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="list" data-dojo-props='append:true'></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeDataList-itemMap.html b/dojox/mobile/tests/test_EdgeToEdgeDataList-itemMap.html
new file mode 100644
index 0000000..6b329fb
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeDataList-itemMap.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeDataList</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dojo/data/ItemFileWriteStore",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeDataList"
+		], function(lang, ItemFileWriteStore, registry){
+			var static_data = { 
+				items: [ 
+					{label: "Apple", 	moveTo: "dummy"},
+					{label: "Banana", 	moveTo: "dummy"},
+					{label: "Cherry", 	moveTo: "dummy"},
+					{label: "Grape", 	moveTo: "dummy"},
+					{label: "Kiwi", 	moveTo: "dummy"},
+					{label: "Lemon", 	moveTo: "dummy"},
+					{label: "Melon", 	moveTo: "dummy"},
+					{label: "Orange", 	moveTo: "dummy"},
+					{label: "Peach", 	moveTo: "dummy"}
+				]
+			};
+			store1 = new ItemFileWriteStore({url: "data/settings-itemMap.json", clearOnClose: true});
+			store2 = new ItemFileWriteStore({data: lang.clone(static_data), clearOnClose: true});
+			store = store1;
+			var newItems = [[],[]];
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("list").setStore(store);
+			};
+			// add a new item
+			add1 = function(){
+				var item = store.newItem({label: "New Item", moveTo: "dummy"});
+				newItems[(store == store1) ? 1 : 0].push(item);
+			};
+			// delete the added item
+			delete1 = function(){
+				var item = newItems[(store == store1) ? 1 : 0].pop();
+				if(item){
+					store.deleteItem(item);
+				}
+			};
+			reload1 = function(){
+				store.save({onComplete: function(){console.log("Saved");}, onError: function(e){console.log(e);}});
+				if(store === store2){
+					store.data = lang.clone(static_data);
+				}
+				store.close();
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="list" data-dojo-props='store:store, query:{text: "*"}, itemMap:{text:"label", profile_image_url:"icon"}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+		<input type="button" value="Reload" onclick="reload1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeDataList-more-sv.html b/dojox/mobile/tests/test_EdgeToEdgeDataList-more-sv.html
new file mode 100644
index 0000000..bdaccb8
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeDataList-more-sv.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeDataList - Load More</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojox/data/QueryReadStore",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/EdgeToEdgeDataList"
+		], function(Deferred, QueryReadStore, ready, registry, ListItem){
+			//var url = "data/fruits.json";
+			var url = "data/fake_service.php";
+			store = new QueryReadStore({url: url});
+
+			var start = 1,
+				count = 5,
+				loadMoreItem = null,
+				list = null;
+			function loadMore(){
+				loadMoreItem.set({
+					busy: true,
+					label: "Loading More Items..."
+				});
+				setTimeout(function(){ // to simulate network latency
+					Deferred.when(list.setQuery({start:start, count:count}), function(){
+						loadMoreItem.set({
+							busy: false,
+							label: "Load More Items..."
+						});
+						list.removeChild(loadMoreItem);
+						list.addChild(loadMoreItem);
+					});
+					start += count;
+					return false;
+				}, 3000);
+			};
+			function addLoadMoreItem(){
+				if(!loadMoreItem){
+					loadMoreItem = new ListItem({
+						label: "Load More Items...",
+						onClick: loadMore,
+						moveTo: "#",
+						noArrow: true
+					});
+				}
+				list.addChild(loadMoreItem);
+			}
+
+			ready(function(){
+				list = registry.byId("list");
+				Deferred.when(list.setStore(store, {start:start, count:count}), addLoadMoreItem);
+				start += count;
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>EdgeToEdgeDataList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="list" data-dojo-props='append:true'></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeDataList-more-v.html b/dojox/mobile/tests/test_EdgeToEdgeDataList-more-v.html
new file mode 100644
index 0000000..64d31fa
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeDataList-more-v.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeDataList - Load More</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojox/data/QueryReadStore",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeDataList"
+		], function(Deferred, QueryReadStore, ready, registry, ListItem){
+			//var url = "data/fruits.json";
+			var url = "data/fake_service.php";
+			store = new QueryReadStore({url: url});
+
+			var start = 1,
+				count = 5,
+				loadMoreItem = null,
+				list = null;
+			function loadMore(){
+				loadMoreItem.set({
+					busy: true,
+					label: "Loading More Items..."
+				});
+				setTimeout(function(){ // to simulate network latency
+					Deferred.when(list.setQuery({start:start, count:count}), function(){
+						loadMoreItem.set({
+							busy: false,
+							label: "Load More Items..."
+						});
+						list.removeChild(loadMoreItem);
+						list.addChild(loadMoreItem);
+					});
+					start += count;
+					return false;
+				}, 3000);
+			};
+			function addLoadMoreItem(){
+				if(!loadMoreItem){
+					loadMoreItem = new ListItem({
+						label: "Load More Items...",
+						onClick: loadMore,
+						moveTo: "#",
+						noArrow: true
+					});
+				}
+				list.addChild(loadMoreItem);
+			}
+
+			ready(function(){
+				list = registry.byId("list");
+				Deferred.when(list.setStore(store, {start:start, count:count}), addLoadMoreItem);
+				start += count;
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="list" data-dojo-props='append:true'></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeDataList.html b/dojox/mobile/tests/test_EdgeToEdgeDataList.html
index df4ec46..2af4498 100644
--- a/dojox/mobile/tests/test_EdgeToEdgeDataList.html
+++ b/dojox/mobile/tests/test_EdgeToEdgeDataList.html
@@ -1,17 +1,24 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>EdgeToEdgeDataList</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.data.ItemFileWriteStore");
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.EdgeToEdgeDataList");
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeDataList</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dojo/data/ItemFileWriteStore",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeDataList"
+		], function(lang, ItemFileWriteStore, registry){
 			var static_data = { 
 				items: [ 
 					{label: "Apple", 	moveTo: "dummy"},
@@ -25,40 +32,49 @@
 					{label: "Peach", 	moveTo: "dummy"}
 				]
 			};
-			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
-			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
-			var store = store1;
+			store1 = new ItemFileWriteStore({url: "data/settings.json", clearOnClose: true});
+			store2 = new ItemFileWriteStore({data: lang.clone(static_data), clearOnClose: true});
+			store = store1;
 			var newItems = [[],[]];
 
 			// switch to the selected store
-			function switchTo(store){
+			switchTo = function(store){
 				window.store = store;
-				dijit.byId("list").setStore(store);
-			}
+				registry.byId("list").setStore(store);
+			};
 			// add a new item
-			function add1(){
+			add1 = function(){
 				var item = store.newItem({label: "New Item", moveTo: "dummy"});
-				this.newItems[(store == store1) ? 1 : 0].push(item);
-			}
+				newItems[(store == store1) ? 1 : 0].push(item);
+			};
 			// delete the added item
-			function delete1(){
-				var item = this.newItems[(store == store1) ? 1 : 0].pop();
+			delete1 = function(){
+				var item = newItems[(store == store1) ? 1 : 0].pop();
 				if(item){
 					store.deleteItem(item);
 				}
-			}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">EdgeToEdgeDataList</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeDataList" id="list" store="store" query="{label: '*'}"></ul>
-			<p>show the different set:<br>
-			<input type="button" value="Set1" onclick="switchTo(store1)">
-			<input type="button" value="Set2" onclick="switchTo(store2)">
-			<p>alter the object store:<br>
-			<input type="button" value="Add" onclick="add1()">
-			<input type="button" value="Delete" onclick="delete1()">
-		</div>
-	</body>
+			};
+			reload1 = function(){
+				store.save({onComplete: function(){console.log("Saved");}, onError: function(e){console.log(e);}});
+				if(store === store2){
+					store.data = lang.clone(static_data);
+				}
+				store.close();
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeDataList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="list" data-dojo-props='store:store, query:{label: "*"}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+		<input type="button" value="Reload" onclick="reload1()">
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeList-check.html b/dojox/mobile/tests/test_EdgeToEdgeList-check.html
index 4ae56e6..7e9a2fb 100644
--- a/dojox/mobile/tests/test_EdgeToEdgeList-check.html
+++ b/dojox/mobile/tests/test_EdgeToEdgeList-check.html
@@ -1,66 +1,76 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Selectable Edge-To-Edge List</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			function check(){
-				dijit.byId("item1").set("checked", true);
-			}
-			function uncheck(){
-				dijit.byId("item1").set("checked", false);
-			}
-			function callback(item, state){
-				var span = dojo.byId("msgArea");
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Selectable Edge-To-Edge List</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, dom, ready, registry){
+			check = function(){
+				registry.byId("item1").set("checked", true);
+			};
+			uncheck = function(){
+				registry.byId("item1").set("checked", false);
+			};
+			callback = function(item, state){
+				var span = dom.byId("msgArea");
 				span.innerHTML += "onCheckStateChanged: "+item.labelNode.innerHTML+", "+state+"<br>";
 				setTimeout(function(){
 					span.innerHTML = "";
 				}, 1000);
-			}
-			dojo.addOnLoad(function(){
-				dojo.connect(dijit.byId("list1"), "onCheckStateChanged", null, callback);
-				dojo.connect(dijit.byId("list2"), "onCheckStateChanged", null, callback);
+			};
+			ready(function(){
+				connect.connect(registry.byId("list1"), "onCheckStateChanged", null, callback);
+				connect.connect(registry.byId("list2"), "onCheckStateChanged", null, callback);
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Selectable List</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Single Select</h2>
-			<ul id="list1" dojoType="dojox.mobile.EdgeToEdgeList" select="single">
-				<li id="item1" dojoType="dojox.mobile.ListItem" checked="true">
-					Cube
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Ripple
-				</li>
-			</ul>
-			<input type="button" onclick="check()" value="check">
-			<input type="button" onclick="uncheck()" value="uncheck">
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Selectable List</h1>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Single Select</h2>
+		<ul id="list1" data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='select:"single"'>
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true'>
+				Cube
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Dissolve
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Ripple
+			</li>
+		</ul>
+		<input type="button" onclick="check()" value="check">
+		<input type="button" onclick="uncheck()" value="uncheck">
 
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Multiple Select</h2>
-			<ul id="list2" dojoType="dojox.mobile.EdgeToEdgeList" select="multiple">
-				<li dojoType="dojox.mobile.ListItem" checked="true">
-					Cube
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Ripple
-				</li>
-			</ul>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Multiple Select</h2>
+		<ul id="list2" data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='select:"multiple"'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true'>
+				Cube
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Dissolve
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Ripple
+			</li>
+		</ul>
 
-			<div id="msgArea" style="margin-left:10px;"></div><br><br>
-		</div>
-	</body>
+		<div id="msgArea" style="margin-left:10px;"></div><br><br>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeList-editable-a11y.html b/dojox/mobile/tests/test_EdgeToEdgeList-editable-a11y.html
new file mode 100644
index 0000000..cc95900
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeList-editable-a11y.html
@@ -0,0 +1,173 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeList - editable</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedCircleMinus.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonGrayKnob.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom-class",
+			"dojo/dom-construct",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, domClass, domConstruct, ready, registry){
+			var delItem, handler, btn1, list1;
+
+			function showDeleteButton(item){
+		
+				hideDeleteButton();
+				delItem = item;
+				item.rightIconNode.style.display = "none";
+				if(!item.rightIcon2Node){
+					item.set("rightIcon2", "mblDomButtonMyRedButton_0");
+					item.rightIcon2Node.tabIndex = "0";
+					item.rightIcon2Node.firstChild.innerHTML = "Delete";
+					connect.connect(item.rightIcon2Node, "onkeydown", onDelete);
+				}
+				item.rightIcon2Node.style.display = "";
+				handler = connect.connect(list1.domNode, "onclick", onClick);
+			}
+
+			function hideDeleteButton(){
+				if(delItem){
+					delItem.rightIconNode.style.display = "";
+					delItem.rightIcon2Node.style.display = "none";
+					delItem = null;
+				}
+				connect.disconnect(handler);
+			}
+
+			function onClick(e){
+				var item = registry.getEnclosingWidget(e.target);
+				if(domClass.contains(e.target, "mblDomButtonMyRedButton_0")){
+					setTimeout(function(){
+						item.destroy();
+					}, 0);
+				}
+				hideDeleteButton();
+			}
+
+			function onDelete(e){
+				if(e && e.type === "keydown" && e.keyCode !== 13){ return; }
+				var item = registry.getEnclosingWidget(e.target);
+				setTimeout(function(){
+					item.destroy();
+				}, 0);
+			}
+
+			function onKeydown(e){
+				if(e.keyCode == 40 && e.shiftKey){ // down
+					var item = registry.getEnclosingWidget(e.target);
+					var next = item.getNextSibling();
+					if(next){
+						domConstruct.place(item.domNode, next.domNode, "after");
+						item.domNode.focus();
+					}
+				}else if(e.keyCode == 38 && e.shiftKey){ // down
+					var item = registry.getEnclosingWidget(e.target);
+					var prev = item.getPreviousSibling();
+					if(prev){
+						domConstruct.place(item.domNode, prev.domNode, "before");
+						item.domNode.focus();
+					}
+				}
+			}
+
+			connect.subscribe("/dojox/mobile/deleteListItem", function(item){
+				showDeleteButton(item);
+			});
+
+			edit = function(){
+				var flag = btn1._flag = !btn1._flag; // true: editable
+				if(flag){
+					list1.startEdit();
+					btn1.set("label", "Done");
+					keyHandler = connect.connect(list1.domNode, "onkeydown", onKeydown);
+				}else{
+					hideDeleteButton();
+					list1.endEdit();
+					btn1.set("label", "Edit");
+					connect.disconnect(keyHandler);
+				}
+			}
+
+			ready(function(){
+				btn1 = registry.byId("btn1");
+				list1 = registry.byId("list1");
+			});
+		});
+	</script>
+
+	<style>
+	/* inline custom DOM Button */
+	.mblDomButtonMyRedButton_0 {
+		position: relative;
+		height: 29px;
+		line-height: 29px;
+		padding: 0px 8px;
+		color: white;
+		font-family: Helvetica;
+		font-size: 13px;
+		font-weight: bold;
+		border: 1px outset #9cacc0;
+		border-radius: 5px;
+		background: -webkit-gradient(linear, left top, left bottom, from(#d3656d), to(#bc1320), color-stop(0.5, #c9404b), color-stop(0.5, #bc1421));
+		background-color: #c9404b;
+		text-align: center;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Editable EdgeToEdgeList"'>
+			<span id="btn1" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='toggle:true' style="padding: 0px 14px;float:left" onclick="edit">Edit</span>
+		</div>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Transition Effects</h2>
+		<ul id="list1" data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='editable:true,deleteIconTitle:"delete",deleteIconRole:"button"'>
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Slide
+			</li>
+			<li id="item2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Flip
+			</li>
+			<li id="item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Fade
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 1"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 2"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 3"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 4"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 5"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 6"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 7"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 8"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 9"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item a"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item b"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item c"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item d"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item e"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item f"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item g"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item h"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item i"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item j"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item k"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item l"'></li>
+
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeList-editable-sv.html b/dojox/mobile/tests/test_EdgeToEdgeList-editable-sv.html
new file mode 100644
index 0000000..aec4080
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeList-editable-sv.html
@@ -0,0 +1,147 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeList - editable</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedCircleMinus.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonGrayKnob.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		], function(connect, domClass, ready, registry){
+			var delItem, handler, btn1, list1;
+
+			function showDeleteButton(item){
+				hideDeleteButton();
+				delItem = item;
+				item.rightIconNode.style.display = "none";
+				if(!item.rightIcon2Node){
+					item.set("rightIcon2", "mblDomButtonMyRedButton_0");
+					item.rightIcon2Node.firstChild.innerHTML = "Delete";
+				}
+				item.rightIcon2Node.style.display = "";
+				handler = connect.connect(list1.domNode, "onclick", onClick);
+			}
+
+			function hideDeleteButton(){
+				if(delItem){
+					delItem.rightIconNode.style.display = "";
+					delItem.rightIcon2Node.style.display = "none";
+					delItem = null;
+				}
+				connect.disconnect(handler);
+			}
+
+			function onClick(e){
+				var item = registry.getEnclosingWidget(e.target);
+				if(domClass.contains(e.target, "mblDomButtonMyRedButton_0")){
+					setTimeout(function(){
+						item.destroy();
+					}, 0);
+				}
+				hideDeleteButton();
+			}
+
+			connect.subscribe("/dojox/mobile/deleteListItem", function(item){
+				showDeleteButton(item);
+			});
+
+			edit = function(){
+				var flag = btn1._flag = !btn1._flag; // true: editable
+				if(flag){
+					list1.startEdit();
+					btn1.set("label", "Done");
+				}else{
+					hideDeleteButton();
+					list1.endEdit();
+					btn1.set("label", "Edit");
+				}
+			}
+
+			ready(function(){
+				btn1 = registry.byId("btn1");
+				list1 = registry.byId("list1");
+			});
+		});
+	</script>
+
+	<style>
+	/* inline custom DOM Button */
+	.mblDomButtonMyRedButton_0 {
+		position: relative;
+		height: 29px;
+		line-height: 29px;
+		padding: 0px 8px;
+		color: white;
+		font-family: Helvetica;
+		font-size: 13px;
+		font-weight: bold;
+		border: 1px outset #9cacc0;
+		border-radius: 5px;
+		background: -webkit-gradient(linear, left top, left bottom, from(#d3656d), to(#bc1320), color-stop(0.5, #c9404b), color-stop(0.5, #bc1421));
+		background-color: #c9404b;
+		text-align: center;
+	}
+	.windows_theme .mblFixedHeaderBar {
+		background-color: black;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", label:"Editable EdgeToEdgeList"'>
+			<span id="btn1" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='toggle:true' style="padding: 0px 14px;float:left" onclick="edit">Edit</span>
+		</div>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Transition Effects</h2>
+		<ul id="list1" data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='editable:true'>
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Slide
+			</li>
+			<li id="item2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Flip
+			</li>
+			<li id="item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Fade
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 1"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 2"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 3"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 4"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 5"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 6"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 7"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 8"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 9"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item a"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item b"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item c"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item d"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item e"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item f"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item g"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item h"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item i"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item j"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item k"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item l"'></li>
+
+		</ul>
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"'>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeList-editable.html b/dojox/mobile/tests/test_EdgeToEdgeList-editable.html
new file mode 100644
index 0000000..9a3417b
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeList-editable.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeList - editable</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedCircleMinus.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonGrayKnob.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, domClass, ready, registry){
+			var delItem, handler, btn1, list1;
+
+			function showDeleteButton(item){
+				hideDeleteButton();
+				delItem = item;
+				item.rightIconNode.style.display = "none";
+				if(!item.rightIcon2Node){
+					item.set("rightIcon2", "mblDomButtonMyRedButton_0");
+					item.rightIcon2Node.firstChild.innerHTML = "Delete";
+				}
+				item.rightIcon2Node.style.display = "";
+				handler = connect.connect(list1.domNode, "onclick", onClick);
+			}
+
+			function hideDeleteButton(){
+				if(delItem){
+					delItem.rightIconNode.style.display = "";
+					delItem.rightIcon2Node.style.display = "none";
+					delItem = null;
+				}
+				connect.disconnect(handler);
+			}
+
+			function onClick(e){
+				var item = registry.getEnclosingWidget(e.target);
+				if(domClass.contains(e.target, "mblDomButtonMyRedButton_0")){
+					setTimeout(function(){
+						item.destroy();
+					}, 0);
+				}
+				hideDeleteButton();
+			}
+
+			connect.subscribe("/dojox/mobile/deleteListItem", function(item){
+				showDeleteButton(item);
+			});
+
+			edit = function(){
+				var flag = btn1._flag = !btn1._flag; // true: editable
+				if(flag){
+					list1.startEdit();
+					btn1.set("label", "Done");
+				}else{
+					hideDeleteButton();
+					list1.endEdit();
+					btn1.set("label", "Edit");
+				}
+			}
+
+			ready(function(){
+				btn1 = registry.byId("btn1");
+				list1 = registry.byId("list1");
+			});
+		});
+	</script>
+
+	<style>
+	/* inline custom DOM Button */
+	.mblDomButtonMyRedButton_0 {
+		position: relative;
+		height: 29px;
+		line-height: 29px;
+		padding: 0px 8px;
+		color: white;
+		font-family: Helvetica;
+		font-size: 13px;
+		font-weight: bold;
+		border: 1px outset #9cacc0;
+		border-radius: 5px;
+		background: -webkit-gradient(linear, left top, left bottom, from(#d3656d), to(#bc1320), color-stop(0.5, #c9404b), color-stop(0.5, #bc1421));
+		background-color: #c9404b;
+		text-align: center;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Editable EdgeToEdgeList"'>
+			<span id="btn1" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='toggle:true' style="padding: 0px 14px;float:left" onclick="edit">Edit</span>
+		</div>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Transition Effects</h2>
+		<ul id="list1" data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='editable:true'>
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Slide
+			</li>
+			<li id="item2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Flip
+			</li>
+			<li id="item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Fade
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 1"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 2"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 3"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 4"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 5"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 6"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 7"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 8"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 9"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item a"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item b"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item c"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item d"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item e"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item f"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item g"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item h"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item i"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item j"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item k"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item l"'></li>
+
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeList-syncWithViews.html b/dojox/mobile/tests/test_EdgeToEdgeList-syncWithViews.html
new file mode 100644
index 0000000..e9fd58a
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeList-syncWithViews.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeList - syncWithViews</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FixedSplitter"
+		]);
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Container" style="width:300px;border-right:1px solid black;">
+			<div id="settings" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading">Settings</h1>
+				<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='transition:"flip", stateful:true, syncWithViews:true'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						Wi-Fi
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Brightness & Wallpaper
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Picture Frame
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general"'>
+						General
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"mail"'>
+						Mail, Contacts, Calendars
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Container">
+
+			<div id="wifi" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading">Wi-Fi Networks</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"bright"'>
+						Next View
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"mail", transitionDir:-1'>
+						Previous View
+					</li>
+				</ul>
+			</div>
+
+			<div id="bright" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading">Brightness & Wallpaper</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"picture"'>
+						Next View
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"wifi", transitionDir:-1'>
+						Previous View
+					</li>
+				</ul>
+			</div>
+
+			<div id="picture" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading">Picture Frame</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"general"'>
+						Next View
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"bright", transitionDir:-1'>
+						Previous View
+					</li>
+				</ul>
+			</div>
+
+			<div id="general" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading">General</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"mail"'>
+						Next View
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"picture", transitionDir:-1'>
+						Previous View
+					</li>
+				</ul>
+			</div>
+
+			<div id="mail" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading">Mail, Contacts, Calendars</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"wifi"'>
+						Next View
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"general", transitionDir:-1'>
+						Previous View
+					</li>
+				</ul>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeList-variable.html b/dojox/mobile/tests/test_EdgeToEdgeList-variable.html
new file mode 100644
index 0000000..38ec95e
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeList-variable.html
@@ -0,0 +1,100 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Variable Height List (Edge-to-Edge)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+	<style>
+		.content {
+			padding:0px 10px;
+			background-color: white;
+		}
+		p {
+			font-family: Helvetica;
+			font-size: 12px;
+		}
+		.title {
+			color: blue;
+			margin-bottom: 4px;
+		}
+		.subtitle {
+			font-style: italic;
+			color: gray;
+			margin: 0px;
+			margin-bottom: 4px;
+		}
+		.subsubtitle {
+			margin: 16px 0px 0px 0px;
+		}
+		.lst {
+			margin: 0px;
+			padding: 0px 14px;
+		}
+		.lst li {
+			font-family: Helvetica;
+			font-size: 12px;
+			margin: 0px;
+			list-style-type: square;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Variable Height List Item</h1>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Top Stories</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#article", transition:"slide"'>
+				Top 10 news stories of the decade
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#article", transition:"flip"'>
+				Create client-side diagrammatic interaction in Web applications with GFX
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#article", transition:"fade"'>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+	</div>
+
+	<div id="article" data-dojo-type="dojox.mobile.View" style="color:black;background-color:white;height:100%">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#home"'>Article</h1>
+		<div class="content">
+			<h3 class="title">Did you know?</h3>
+			<h4 class="subtitle">Features of dojox.mobile</h4>
+			<h5 class="subsubtitle">No images are used</h5>
+			<ul class="lst">
+			  	<li>UI parts consist of DOM and CSS3.</li>
+				<li>Only application icons are images.</li>
+			</ul>
+			<p>For example, none of the UI parts below are images.<br></p>
+			<img src="images/not-images.png">
+
+			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
+			<ul class="lst">
+			  	<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Support for CSS sprite</h5>
+			<ul class="lst">
+				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
+			<ul class="lst">
+				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
+			</ul>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeList.html b/dojox/mobile/tests/test_EdgeToEdgeList.html
new file mode 100644
index 0000000..5c3917c
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeList.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Edge to Edge</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="settings" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Settings</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Airplane Mode
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", rightText:"mac", moveTo:"hello"'>
+				Wi-Fi
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", rightText:"AcmePhone", moveTo:"hello"'>
+				Carrier
+			</li>
+		</ul>
+	</div>
+
+	<div id="hello" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Hello</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"settings"'>
+				Hello
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"settings"'>
+				Carrier
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeStoreList-auto-sv.html b/dojox/mobile/tests/test_EdgeToEdgeStoreList-auto-sv.html
new file mode 100644
index 0000000..23ac861
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeStoreList-auto-sv.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList - Auto Load</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojo/dom-class",
+			"dojo/store/Cache",
+			"dojo/store/JsonRest",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ProgressIndicator",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/EdgeToEdgeStoreList"
+		], function(Deferred, domClass, Cache, JsonRest, Memory, Observable, ready, registry, ProgressIndicator){
+			//var url = "data/fruits.json";
+			var url = "data/fake_service.php";
+			var memoryStore = new Memory({idProperty:"label"});
+			var restStore = new JsonRest({idProperty:"label", target: url});
+			store = new Cache(restStore, memoryStore);
+
+			var start = 1,
+				count = 5,
+				prog1 = null,
+				list = null;
+			function loadMore(){
+				busy(true);
+				setTimeout(function(){ // to simulate network latency
+					Deferred.when(list.setQuery({start:start, count:count}), function(){
+						busy(false);
+					});
+					start += count;
+					return false;
+				}, 1000);
+			};
+
+			function busy(flag){
+				if(!prog1){
+					prog1 = new ProgressIndicator({size:30, center:false});
+					prog1.domNode.style.position = "absolute";
+					prog1.domNode.style.margin = "5px";
+					domClass.add(prog1.domNode, "mblProgWhite");
+				}
+				if(flag){
+					var head1 = registry.byId("head1");
+					prog1.placeAt(head1.domNode);
+					prog1.start();
+				}else{
+					prog1.stop();
+				}
+			}
+
+			adjustDestination = function(to, pos, dim){
+				var dim = this.getDim();
+				var h = dim.c.h; // container height
+				var disp = dim.d.h; // display height
+				if(to.y < disp - h){
+					loadMore();
+					to.y = disp - h;
+				}
+				return true;
+			}
+
+			ready(function(){
+				list = registry.byId("list");
+				list.setStore(store, {start:start, count:count});
+				start += count;
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='adjustDestination:adjustDestination'>
+		<h1 data-dojo-type="dojox.mobile.Heading" id="head1" data-dojo-props='fixed:"top"'>EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="list" data-dojo-props='append:true'></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeStoreList-auto-v.html b/dojox/mobile/tests/test_EdgeToEdgeStoreList-auto-v.html
new file mode 100644
index 0000000..4496f95
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeStoreList-auto-v.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList - Auto Load</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/_base/window",
+			"dojo/store/Cache",
+			"dojo/store/JsonRest",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeStoreList"
+		], function(connect, win, Cache, JsonRest, Memory, Observable, ready, registry){
+			//var url = "data/fruits.json";
+			var url = "data/fake_service.php";
+			var memoryStore = new Memory({idProperty:"label"});
+			var restStore = new JsonRest({idProperty:"label", target: url});
+			store = new Cache(restStore, memoryStore);
+
+			var start = 1,
+				count = 5,
+				list = null;
+			function loadMore(){
+				setTimeout(function(){ // to simulate network latency
+					list.setQuery({start:start, count:count});
+					start += count;
+				}, 1000);
+			};
+
+			ready(function(){
+				list = registry.byId("list");
+				list.setStore(store, {start:start, count:count});
+				start += count;
+				connect.connect(win.global, "onscroll", null, function(e){
+					var h = win.global.innerHeight||win.doc.documentElement.clientHeight||win.doc.documentElement.offsetHeight;
+					if(win.body().scrollTop + h === win.body().offsetHeight){
+						loadMore();
+					}
+				})
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" id="head1">EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="list" data-dojo-props='append:true'></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeStoreList-categ.html b/dojox/mobile/tests/test_EdgeToEdgeStoreList-categ.html
new file mode 100644
index 0000000..ff91273
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeStoreList-categ.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList - Categorized List</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojo/store/Cache",
+			"dojo/store/JsonRest",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeStoreList"
+		], function(Deferred, Cache, JsonRest, Memory, Observable, registry){
+			var static_data1 = [
+				{ label: "Category 1", header: true,
+				  children: [
+					{ label: "Wi-Fi", icon: "images/i-icon-1.png", moveTo: "wifi" },
+					{ label: "Brightness & Wallpaper", icon: "images/i-icon-2.png", moveTo: "bright" },
+					{ label: "Picture Frame", icon: "images/i-icon-3.png", moveTo: "picture" },
+					{ label: "General", icon: "images/i-icon-4.png", moveTo: "general", "selected": "true" },
+					{ label: "Mail, Contacts, Calendars", icon: "images/i-icon-5.png", moveTo: "wifi" },
+					{ label: "Safari", icon: "images/i-icon-6.png", moveTo: "bright" },
+					{ label: "iPod", icon: "images/i-icon-7.png", moveTo: "picture" }
+				  ]
+				},
+				{ label: "Category 2", header: true,
+				  children: [
+					{ label: "Video", icon: "images/i-icon-8.png", moveTo: "general" },
+					{ label: "Photos", icon: "images/i-icon-9.png", moveTo: "wifi" },
+					{ label: "Store", icon: "images/i-icon-10.png", moveTo: "bright" }
+				  ]
+				}
+			];
+
+			var static_data2 = [
+				{label: "Apple", 	moveTo: "dummy"},
+				{label: "Banana", 	moveTo: "dummy"},
+				{label: "Cherry", 	moveTo: "dummy"},
+				{label: "Grape", 	moveTo: "dummy"},
+				{label: "Kiwi", 	moveTo: "dummy"},
+				{label: "Lemon", 	moveTo: "dummy"},
+				{label: "Melon", 	moveTo: "dummy"},
+				{label: "Orange", 	moveTo: "dummy"},
+				{label: "Peach", 	moveTo: "dummy"}
+			];
+			store1 = Observable(new Memory({idProperty:"label", data: static_data1}));
+			store2 = Observable(new Memory({idProperty:"label", data: static_data2}));
+			store1.__counter = store2.__counter = 1;
+			store = store1;
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("list").setStore(store);
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="list" data-dojo-props='store:store, query:{}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeStoreList-itemMap-updates.html b/dojox/mobile/tests/test_EdgeToEdgeStoreList-itemMap-updates.html
new file mode 100644
index 0000000..7936f51
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeStoreList-itemMap-updates.html
@@ -0,0 +1,133 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList - updates</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" 
+		data-dojo-config="mblThemeFiles: ['base', 'Button']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dojo/_base/array",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeStoreList",
+			"dojox/mobile/Button"
+		], function(lang, array, Memory, Observable, registry){
+			var updateCounter = 0;
+			
+			var static_data1 = [
+				{ id: 1, text: "Category 1", header: true },
+				{ id: 2, text: "Wi-Fi", profile_image_url: "images/i-icon-1.png", moveTo: "wifi" },
+				{ id: 3, text: "Brightness & Wallpaper", profile_image_url: "images/i-icon-2.png", moveTo: "bright" },
+				{ id: 4, text: "Picture Frame", profile_image_url: "images/i-icon-3.png", moveTo: "picture" },
+				{ id: 5, text: "General", profile_image_url: "images/i-icon-4.png", moveTo: "general", "selected": "true" },
+				{ id: 6, text: "Mail, Contacts, Calendars", profile_image_url: "images/i-icon-5.png", moveTo: "wifi" },
+				{ id: 7, text: "Safari", profile_image_url: "images/i-icon-6.png", moveTo: "bright" },
+				{ id: 8, text: "iPod", profile_image_url: "images/i-icon-7.png", moveTo: "picture" },
+				{ id: 9, text: "Category 2", header: true },
+				{ id: 10, text: "Video", profile_image_url: "images/i-icon-8.png", moveTo: "general" },
+				{ id: 11, text: "Photos", profile_image_url: "images/i-icon-9.png", moveTo: "wifi" },
+				{ id: 12, text: "Store", profile_image_url: "images/i-icon-10.png", moveTo: "bright" }
+			];
+
+			var static_data2 = [
+				{id: 1, label: "Apple", 	moveTo: "dummy"},
+				{id: 2, label: "Banana", 	moveTo: "dummy"},
+				{id: 3, label: "Cherry", 	moveTo: "dummy"},
+				{id: 4, label: "Grape", 	moveTo: "dummy"},
+				{id: 5, label: "Kiwi", 	moveTo: "dummy"},
+				{id: 6, label: "Lemon", 	moveTo: "dummy"},
+				{id: 7, label: "Melon", 	moveTo: "dummy"},
+				{id: 8, label: "Orange", 	moveTo: "dummy"},
+				{id: 9, label: "Peach", 	moveTo: "dummy"}
+			];
+			store1 = Observable(new Memory({data: static_data1}));
+			store2 = Observable(new Memory({data: static_data2}));
+			store1.__counter = store2.__counter = 1;
+			store = store1;
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("list").setStore(store);
+			};
+			// add a new item
+			add1 = function(){
+				store.add({
+					id: 100 + store.__counter,
+					label: "New Item "+(store.__counter++),
+					icon: "images/i-icon-1.png",
+					moveTo: "dummy"
+				});
+			};
+			// update the text or label of all items
+			var updateSuffix = " update #";
+			var updateUtil = function(str){
+				// Skip the category items (for esthetic reasons)
+				if(str.startsWith("Category")){
+					return str;
+				}
+				var idx = str.indexOf(updateSuffix);
+				return idx >= 0 ?
+					// already updated: just update the counter
+					str.substring(0, idx) + updateSuffix + updateCounter :
+					// first update: append to str
+					str + updateSuffix + updateCounter;
+			};
+			
+			update1 = function(){
+				updateCounter++;
+				array.forEach(store.query({}), function(item, i){
+					// Changes of the data items of the store must only be done
+					// through the API of the store. Hence the cloning.
+					var newItem = lang.clone(item);
+					if(newItem.text){
+						newItem.text = updateUtil(newItem.text);
+					}else{
+						newItem.label = updateUtil(newItem.label)
+					}
+					store.put(newItem);
+				});
+			};
+			// delete the added item
+			delete1 = function(){
+				if(store.__counter > 1){
+					store.remove(100 + (--store.__counter));
+				}
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading">EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" id="list" 
+			data-dojo-props='store: store, query: {}, itemMap: {text:"label", profile_image_url: "icon"}'>
+		</ul>
+		<p>Select the data store:<br>
+		<input data-dojo-type="dojox/mobile/Button" type="button" value="Set1" 
+			onclick="switchTo(store1)">
+		<input data-dojo-type="dojox/mobile/Button" type="button" value="Set2" 
+			onclick="switchTo(store2)">
+		<p>Alter the data store:<br>
+		<input data-dojo-type="dojox/mobile/Button" type="button" value="Add" 
+			onclick="add1()">
+		<input data-dojo-type="dojox/mobile/Button" type="button" value="Update" 
+			onclick="update1()">
+		<input data-dojo-type="dojox/mobile/Button" type="button" value="Delete" 
+			onclick="delete1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeStoreList-itemMap.html b/dojox/mobile/tests/test_EdgeToEdgeStoreList-itemMap.html
new file mode 100644
index 0000000..57ad4b1
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeStoreList-itemMap.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojo/store/Cache",
+			"dojo/store/JsonRest",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeStoreList"
+		], function(Deferred, Cache, JsonRest, Memory, Observable, registry){
+			var static_data1 = [
+				{ text: "Category 1", header: true },
+				{ text: "Wi-Fi", profile_image_url: "images/i-icon-1.png", moveTo: "wifi" },
+				{ text: "Brightness & Wallpaper", profile_image_url: "images/i-icon-2.png", moveTo: "bright" },
+				{ text: "Picture Frame", profile_image_url: "images/i-icon-3.png", moveTo: "picture" },
+				{ text: "General", profile_image_url: "images/i-icon-4.png", moveTo: "general", "selected": "true" },
+				{ text: "Mail, Contacts, Calendars", profile_image_url: "images/i-icon-5.png", moveTo: "wifi" },
+				{ text: "Safari", profile_image_url: "images/i-icon-6.png", moveTo: "bright" },
+				{ text: "iPod", profile_image_url: "images/i-icon-7.png", moveTo: "picture" },
+				{ text: "Category 2", header: true },
+				{ text: "Video", profile_image_url: "images/i-icon-8.png", moveTo: "general" },
+				{ text: "Photos", profile_image_url: "images/i-icon-9.png", moveTo: "wifi" },
+				{ text: "Store", profile_image_url: "images/i-icon-10.png", moveTo: "bright" }
+			];
+
+			var static_data2 = [
+				{label: "Apple", 	moveTo: "dummy"},
+				{label: "Banana", 	moveTo: "dummy"},
+				{label: "Cherry", 	moveTo: "dummy"},
+				{label: "Grape", 	moveTo: "dummy"},
+				{label: "Kiwi", 	moveTo: "dummy"},
+				{label: "Lemon", 	moveTo: "dummy"},
+				{label: "Melon", 	moveTo: "dummy"},
+				{label: "Orange", 	moveTo: "dummy"},
+				{label: "Peach", 	moveTo: "dummy"}
+			];
+			store1 = Observable(new Memory({idProperty:"label", data: static_data1}));
+			store2 = Observable(new Memory({idProperty:"label", data: static_data2}));
+			store1.__counter = store2.__counter = 1;
+			store = store1;
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("list").setStore(store);
+			};
+			// add a new item
+			add1 = function(){
+				store.add({
+					label: "New Item "+(store.__counter++),
+					icon: "images/i-icon-1.png",
+					moveTo: "dummy"
+				});
+			};
+			// delete the added item
+			delete1 = function(){
+				if(store.__counter > 1){
+					store.remove("New Item "+(--store.__counter));
+				}
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="list" data-dojo-props='store:store, query:{}, itemMap:{text:"label", profile_image_url:"icon"}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeStoreList-lazy.html b/dojox/mobile/tests/test_EdgeToEdgeStoreList-lazy.html
new file mode 100644
index 0000000..50b1acf
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeStoreList-lazy.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList with lazy data loading</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true"></script>
+
+	<script type="text/javascript">
+		var store;
+		require([
+			"dojo/parser",
+			"dojo/ready",
+			"dojo/on",
+			"dojo/when",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"dojox/mobile/compat"
+		], function(parser, ready, on, when, Memory, Observable, registry){
+			ready(function(){
+				var data = [
+					{ label: "label1" }, { label: "label2" }, { label: "label3" }, { label: "label4" }, { label: "label5" },
+					{ label: "label6" }, { label: "label7" }, { label: "label8" }, { label: "label9" }, { label: "labela" },
+					{ label: "labelb" }, { label: "labelc" }, { label: "labeld" }, { label: "labele" }, { label: "labelf" },
+					{ label: "labelg" }, { label: "labelh" }, { label: "labeli" }, { label: "labelj" }, { label: "labelk" },
+					{ label: "labell" }, { label: "labelm" }, { label: "labeln" }, { label: "labelo" }, { label: "labelp" },
+					{ label: "labelq" }, { label: "labelr" }, { label: "labels" }, { label: "labelt" }, { label: "labelu" },
+					{ label: "labelv" }, { label: "labelw" }, { label: "labelx" }, { label: "labely" }, { label: "labelz" },
+					{ label: "label1" }, { label: "label2" }, { label: "label3" }, { label: "label4" }, { label: "label5" },
+					{ label: "label6" }, { label: "label7" }, { label: "label8" }, { label: "label9" }, { label: "labela" },
+					{ label: "labelb" }, { label: "labelc" }, { label: "labeld" }, { label: "labele" }, { label: "labelf" },
+					{ label: "labelg" }, { label: "labelh" }, { label: "labeli" }, { label: "labelj" }, { label: "labelk" },
+					{ label: "labell" }, { label: "labelm" }, { label: "labeln" }, { label: "labelo" }, { label: "labelp" },
+					{ label: "labelq" }, { label: "labelr" }, { label: "labels" }, { label: "labelt" }, { label: "labelu" },
+					{ label: "labelv" }, { label: "labelw" }, { label: "labelx" }, { label: "labely" }, { label: "labelz" },
+					{ label: "label1" }, { label: "label2" }, { label: "label3" }, { label: "label4" }, { label: "label5" },
+					{ label: "label6" }, { label: "label7" }, { label: "label8" }, { label: "label9" }, { label: "labela" },
+					{ label: "labelb" }, { label: "labelc" }, { label: "labeld" }, { label: "labele" }, { label: "labelf" },
+					{ label: "labelg" }, { label: "labelh" }, { label: "labeli" }, { label: "labelj" }, { label: "labelk" },
+					{ label: "labell" }, { label: "labelm" }, { label: "labeln" }, { label: "labelo" }, { label: "labelp" },
+					{ label: "labelq" }, { label: "labelr" }, { label: "labels" }, { label: "labelt" }, { label: "labelu" },
+					{ label: "labelv" }, { label: "labelw" }, { label: "labelx" }, { label: "labely" }, { label: "labelz" },
+					{ label: "label1" }, { label: "label2" }, { label: "label3" }, { label: "label4" }, { label: "label5" },
+					{ label: "label6" }, { label: "label7" }, { label: "label8" }, { label: "label9" }, { label: "labela" },
+					{ label: "labelb" }, { label: "labelc" }, { label: "labeld" }, { label: "labele" }, { label: "labelf" },
+					{ label: "labelg" }, { label: "labelh" }, { label: "labeli" }, { label: "labelj" }, { label: "labelk" },
+					{ label: "labell" }, { label: "labelm" }, { label: "labeln" }, { label: "labelo" }, { label: "labelp" },
+					{ label: "labelq" }, { label: "labelr" }, { label: "labels" }, { label: "labelt" }, { label: "labelu" },
+					{ label: "labelv" }, { label: "labelw" }, { label: "labelx" }, { label: "labely" }, { label: "labelz" },
+					{ label: "label1" }, { label: "label2" }, { label: "label3" }, { label: "label4" }, { label: "label5" },
+					{ label: "label6" }, { label: "label7" }, { label: "label8" }, { label: "label9" }, { label: "labela" },
+					{ label: "labelb" }, { label: "labelc" }, { label: "labeld" }, { label: "labele" }, { label: "labelf" },
+					{ label: "labelg" }, { label: "labelh" }, { label: "labeli" }, { label: "labelj" }, { label: "labelk" },
+					{ label: "labell" }, { label: "labelm" }, { label: "labeln" }, { label: "labelo" }, { label: "labelp" },
+					{ label: "labelq" }, { label: "labelr" }, { label: "labels" }, { label: "labelt" }, { label: "labelu" },
+					{ label: "labelv" }, { label: "labelw" }, { label: "labelx" }, { label: "labely" }, { label: "labelz" }
+				];
+				store = Observable(new Memory({idProperty:"label", data: data}));
+				when(parser.parse(), function(){
+					var list = registry.byId("list");
+					var scroll = registry.byId("scroll");
+					var itemHeight = 43;
+					var busy = false;
+ 					on(scroll, "afterscroll", function(evt){
+	 					if(evt.afterBottom){
+	 						if(!busy){
+								var start = list.pageSize;
+								console.log("load more items");
+								busy = true;
+								setTimeout(function(){
+									when(list.setQuery({}, {start: start, count: list.pageSize}), function(){
+										busy = false;
+										scroll.resize();
+									});
+								// simulate network latency with timeout
+								}, 1000);
+								start += list.pageSize;
+	 						}
+	 					}
+					});
+				});
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="scroll" data-dojo-type="dojox/mobile/ScrollableView">
+		<h1 data-dojo-type="dojox/mobile/Heading"  data-dojo-props="fixed: 'top'">EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" data-dojo-mixins="dojox/mobile/LongListMixin"
+			id="list" data-dojo-props="append: true, constraint: false, store:store, query:{}, queryOptions: { count: 20, start: 0}"></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeStoreList-more-sv.html b/dojox/mobile/tests/test_EdgeToEdgeStoreList-more-sv.html
new file mode 100644
index 0000000..368669a
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeStoreList-more-sv.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList - Load More</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojo/store/Cache",
+			"dojo/store/JsonRest",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/EdgeToEdgeStoreList"
+		], function(Deferred, Cache, JsonRest, Memory, Observable, ready, registry, ListItem){
+			//var url = "data/fruits.json";
+			var url = "data/fake_service.php";
+			var memoryStore = new Memory({idProperty:"label"});
+			var restStore = new JsonRest({idProperty:"label", target: url});
+			store = new Cache(restStore, memoryStore);
+
+			var start = 1,
+				count = 5,
+				loadMoreItem = null,
+				list = null;
+			function loadMore(){
+				loadMoreItem.set({
+					busy: true,
+					label: "Loading More Items..."
+				});
+				setTimeout(function(){ // to simulate network latency
+					Deferred.when(list.setQuery({start:start, count:count}), function(){
+						loadMoreItem.set({
+							busy: false,
+							label: "Load More Items..."
+						});
+						list.removeChild(loadMoreItem);
+						list.addChild(loadMoreItem);
+					});
+					start += count;
+					return false;
+				}, 3000);
+			};
+			function addLoadMoreItem(){
+				if(!loadMoreItem){
+					loadMoreItem = new ListItem({
+						label: "Load More Items...",
+						onClick: loadMore,
+						moveTo: "#",
+						noArrow: true
+					});
+				}
+				list.addChild(loadMoreItem);
+			}
+
+			ready(function(){
+				list = registry.byId("list");
+				Deferred.when(list.setStore(store, {start:start, count:count}), addLoadMoreItem);
+				start += count;
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="list" data-dojo-props='append:true'></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeStoreList-more-v.html b/dojox/mobile/tests/test_EdgeToEdgeStoreList-more-v.html
new file mode 100644
index 0000000..d76d9fd
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeStoreList-more-v.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList - Load More</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojo/store/Cache",
+			"dojo/store/JsonRest",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeStoreList"
+		], function(Deferred, Cache, JsonRest, Memory, Observable, ready, registry, ListItem){
+			//var url = "data/fruits.json";
+			var url = "data/fake_service.php";
+			var memoryStore = new Memory({idProperty:"label"});
+			var restStore = new JsonRest({idProperty:"label", target: url});
+			store = new Cache(restStore, memoryStore);
+
+			var start = 1,
+				count = 5,
+				loadMoreItem = null,
+				list = null;
+			function loadMore(){
+				loadMoreItem.set({
+					busy: true,
+					label: "Loading More Items..."
+				});
+				setTimeout(function(){ // to simulate network latency
+					Deferred.when(list.setQuery({start:start, count:count}), function(){
+						loadMoreItem.set({
+							busy: false,
+							label: "Load More Items..."
+						});
+						list.removeChild(loadMoreItem);
+						list.addChild(loadMoreItem);
+					});
+					start += count;
+					return false;
+				}, 3000);
+			};
+			function addLoadMoreItem(){
+				if(!loadMoreItem){
+					loadMoreItem = new ListItem({
+						label: "Load More Items...",
+						onClick: loadMore,
+						moveTo: "#",
+						noArrow: true
+					});
+				}
+				list.addChild(loadMoreItem);
+			}
+
+			ready(function(){
+				list = registry.byId("list");
+				Deferred.when(list.setStore(store, {start:start, count:count}), addLoadMoreItem);
+				start += count;
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="list" data-dojo-props='append:true'></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_EdgeToEdgeStoreList.html b/dojox/mobile/tests/test_EdgeToEdgeStoreList.html
new file mode 100644
index 0000000..b543700
--- /dev/null
+++ b/dojox/mobile/tests/test_EdgeToEdgeStoreList.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>EdgeToEdgeStoreList</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojo/store/Cache",
+			"dojo/store/JsonRest",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/EdgeToEdgeStoreList"
+		], function(Deferred, Cache, JsonRest, Memory, Observable, registry){
+			var static_data1 = [
+				{ label: "Category 1", header: true },
+				{ label: "Wi-Fi", icon: "images/i-icon-1.png", moveTo: "wifi" },
+				{ label: "Brightness & Wallpaper", icon: "images/i-icon-2.png", moveTo: "bright" },
+				{ label: "Picture Frame", icon: "images/i-icon-3.png", moveTo: "picture" },
+				{ label: "General", icon: "images/i-icon-4.png", moveTo: "general", "selected": "true" },
+				{ label: "Mail, Contacts, Calendars", icon: "images/i-icon-5.png", moveTo: "wifi" },
+				{ label: "Safari", icon: "images/i-icon-6.png", moveTo: "bright" },
+				{ label: "iPod", icon: "images/i-icon-7.png", moveTo: "picture" },
+				{ label: "Category 2", header: true },
+				{ label: "Video", icon: "images/i-icon-8.png", moveTo: "general" },
+				{ label: "Photos", icon: "images/i-icon-9.png", moveTo: "wifi" },
+				{ label: "Store", icon: "images/i-icon-10.png", moveTo: "bright" }
+			];
+
+			var static_data2 = [
+				{label: "Apple", 	moveTo: "dummy"},
+				{label: "Banana", 	moveTo: "dummy"},
+				{label: "Cherry", 	moveTo: "dummy"},
+				{label: "Grape", 	moveTo: "dummy"},
+				{label: "Kiwi", 	moveTo: "dummy"},
+				{label: "Lemon", 	moveTo: "dummy"},
+				{label: "Melon", 	moveTo: "dummy"},
+				{label: "Orange", 	moveTo: "dummy"},
+				{label: "Peach", 	moveTo: "dummy"}
+			];
+			store1 = Observable(new Memory({idProperty:"label", data: static_data1}));
+			store2 = Observable(new Memory({idProperty:"label", data: static_data2}));
+			store1.__counter = store2.__counter = 1;
+			store = store1;
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("list").setStore(store);
+			};
+			// add a new item
+			add1 = function(){
+				store.add({
+					label: "New Item "+(store.__counter++),
+					icon: "images/i-icon-1.png",
+					moveTo: "dummy"
+				});
+			};
+			// delete the added item
+			delete1 = function(){
+				if(store.__counter > 1){
+					store.remove("New Item "+(--store.__counter));
+				}
+			};
+			// modify the added item
+			var modif_counter = 0;
+			modify1 = function(){
+				if(store.__counter > 1){
+					store.put({
+						label: "New Item "+(store.__counter-1),
+						rightText: ++modif_counter + " changes"
+					});
+				}
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeStoreList" id="list" data-dojo-props='store:store, query:{}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+		<input type="button" value="Modify" onclick="modify1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FilteredList-EdgeToEdgeDataList-demo.html b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeDataList-demo.html
new file mode 100644
index 0000000..cc4ba0d
--- /dev/null
+++ b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeDataList-demo.html
@@ -0,0 +1,221 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Filtered EdgeToEdgeDataList - demo</title>
+	
+	<!-- This test shows a dojox/mobile/EdgeToEdgeDataList filtered using dojox/mobile/FilteredListMixin. -->
+	<!-- Use-case: markup; demonstrates the customization of filtering criteria. -->
+	
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+	
+	<script type="text/javascript">
+		var dataStore;
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojo/ready",
+			"dijit/registry",
+			"dojo/data/ItemFileReadStore",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/EdgeToEdgeDataList",
+			"dojox/mobile/FilteredListMixin",
+			"dojox/mobile/SearchBox",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/RoundRect",
+			"dojox/mobile/Button",
+			"dojox/mobile/RadioButton",
+			"dojox/mobile/Switch"
+			], function(parser, mobile, compat, ready, registry, 
+						ItemFileReadStore, ScrollableView, EdgeToEdgeDataList, FilteredListMixin,
+						SearchBox, SimpleDialog, RoundRect, Button, RadioButton, Switch){
+			
+			var filterBox;
+			var static_data = { 
+				items: [ 
+					{label: "Alabama"},
+					{label: "Alaska"},
+					{label: "American Samoa"},
+					{label: "Arizona"},
+					{label: "Arkansas"},
+					{label: "Armed Forces Europe"},
+					{label: "Armed Forces Pacific"},
+					{label: "Armed Forces the Americas"},
+					{label: "California"},
+					{label: "Colorado"},
+					{label: "Connecticut"},
+					{label: "Delaware"},
+					{label: "District of Columbia"},
+					{label: "Federated States of Micronesia"},
+					{label: "Florida"},
+					{label: "Georgia"},
+					{label: "Guam"},
+					{label: "Hawaii"},
+					{label: "Idaho"},
+					{label: "Illinois"},
+					{label: "Indiana"},
+					{label: "Iowa"},
+					{label: "Kansas"},
+					{label: "Kentucky"},
+					{label: "Louisiana"},
+					{label: "Maine"},
+					{label: "Marshall Islands"},
+					{label: "Maryland"},
+					{label: "Massachusetts"},
+					{label: "Michigan"},
+					{label: "Minnesota"},
+					{label: "Mississippi"},
+					{label: "Missouri"},
+					{label: "Montana"},
+					{label: "Nebraska"},
+					{label: "Nevada"},
+					{label: "New Hampshire"},
+					{label: "New Jersey"},
+					{label: "New Mexico"},
+					{label: "New York"},
+					{label: "North Carolina"},
+					{label: "North Dakota"},
+					{label: "Northern Mariana Islands"},
+					{label: "Ohio"},
+					{label: "Oklahoma"},
+					{label: "Oregon"},
+					{label: "Pennsylvania"},
+					{label: "Puerto Rico"},
+					{label: "Rhode Island"},
+					{label: "South Carolina"},
+					{label: "South Dakota"},
+					{label: "Tennessee"},
+					{label: "Texas"},
+					{label: "Utah"},
+					{label: "Vermont"},
+					{label: "Virgin Islands, U.S."},
+					{label: "Virginia"},
+					{label: "Washington"},
+					{label: "West Virginia"},
+					{label: "Wisconsin"},
+					{label: "Wyoming"}
+				]
+			};
+
+			// dojo/data store for dojox/mobile/EdgeToEdgeDataList
+			dataStore = new ItemFileReadStore({data: static_data});
+			
+			// Shows the Search Options dialog.
+			showOptions = function(dlg){
+				registry.byId(dlg).show();
+			};
+
+			// Hides the Search Options dialog. Optionally, applies the new search options.
+			hideOptions = function(dlg, applyOptions){
+				registry.byId(dlg).hide();
+				if(applyOptions){
+					filterBox.ignoreCase = registry.byId("ignoreCaseSwitch").value == "on";
+					filterBox.set("incremental", registry.byId("incrementalSwitch").value == "on");
+					if (registry.byId("radioStartsWith").checked){
+						filterBox.queryExpr = "${0}*";
+					}else if(registry.byId("radioContains").checked){
+						filterBox.queryExpr = "*${0}*";
+					}else if(registry.byId("radioIs").checked){
+						filterBox.queryExpr = "${0}";
+					}
+				}
+			};
+			
+			ready(function(){
+				filterBox = registry.byId("list").getFilterBox();
+			});
+		});
+	</script>
+	
+	<style>
+		.mblSimpleDialogButton {
+			margin: 7px 0 0;
+			width: 262px;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialogButton2l {
+			float: left;
+			width: 127px;
+			margin: 7px 0 0;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialogButton2r {
+			float: right;
+			width: 127px;
+			margin: 7px 0 0;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+	</style>
+</head>
+
+<body style="visibility:hidden;background-color:#424142;">
+	<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered EdgeToEdgeDataList</h1>
+		<input data-dojo-type="dojox/mobile/SearchBox" type="search" id="filterBox"
+			style="width:50%; float: left; margin-top: 2px" class="mblFilteredEdgeToEdgeListSearchBox">
+		<button style="float:right" onclick="showOptions('dlg_options')">Options</button>
+		<div style="clear:left" data-dojo-type="dojox/mobile/ScrollableView">
+			<ul data-dojo-type="dojox/mobile/EdgeToEdgeDataList" id="list" 
+				data-dojo-mixins="dojox/mobile/FilteredListMixin"
+				data-dojo-props="filterBoxRef: 'filterBox', placeHolder: 'Search', store: dataStore"></ul>
+		</div>
+	</div>
+	
+	<div id="dlg_options" data-dojo-type="dojox/mobile/SimpleDialog">
+		<div class="mblSimpleDialogTitle">Search Options</div>
+		<table style="width:100%">
+			<tr>
+				<td><span class="bold">Ignore case</span></td>
+				<td style="text-align:left">
+					<input type="checkbox" data-dojo-type="dojox/mobile/Switch" 
+						id="ignoreCaseSwitch" value="on"></td>
+			</tr>
+			<tr>
+				<td><span class="bold">Incremental</span></td>
+				<td style="text-align:left">
+					<input type="checkbox" data-dojo-type="dojox/mobile/Switch" 
+						id="incrementalSwitch" value="on">
+				</td>
+			</tr>
+			<tr>
+				<td style="text-align:left">
+					<input type="radio" id="radioStartsWith" data-dojo-type="dojox/mobile/RadioButton" 
+						name="mobileRadio" value="Starts with" checked>
+					<label for="radioStartsWith">Starts with</label>
+				</td>
+			</tr>
+			<tr>
+				<td style="text-align:left">
+					<input type="radio" id="radioContains" data-dojo-type="dojox/mobile/RadioButton" 
+						name="mobileRadio" value="Contains">
+					<label for="radioContains">Contains</label>
+				</td>
+			</tr>
+			<tr>
+				<td style="text-align:left">
+					<input type="radio" id="radioIs" data-dojo-type="dojox/mobile/RadioButton" 
+						name="mobileRadio" value="Is">
+					<label for="radioIs">Is</label>
+				</td>
+			</tr>
+		</table>
+
+		<button data-dojo-type="dojox/mobile/Button" class="mblSimpleDialogButton2l" 
+			onclick="hideOptions('dlg_options', false)">Cancel</button>
+		<button data-dojo-type="dojox/mobile/Button" class="mblSimpleDialogButton2r mblBlueButton" 
+			onclick="hideOptions('dlg_options', true)">OK</button>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-auto-prog.html b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-auto-prog.html
new file mode 100644
index 0000000..c2ad1fd
--- /dev/null
+++ b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-auto-prog.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Filtered EdgeToEdgeStoreList - auto - prog</title>
+
+	<!-- This test shows a dojox/mobile/EdgeToEdgeStoreList filtered using dojox/mobile/FilteredListMixin. -->
+	<!-- Use-case: programmatic; SearchBox and ScrollableView created automatically by the mixin. -->
+	
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base', 'SearchBox']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/ready",
+			"dojo/dom",
+			"dojo/store/Memory",
+			"dojox/mobile/EdgeToEdgeStoreList",
+			"dojox/mobile/FilteredListMixin",
+			"dojox/mobile/Heading",
+			"dojox/mobile",
+			"dojox/mobile/View",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser"
+		], function(declare, ready, dom, Memory, EdgeToEdgeStoreList, FilteredListMixin){
+			var static_data = { 
+				items: [ 
+					{label: "Alabama"},
+					{label: "Alaska"},
+					{label: "American Samoa"},
+					{label: "Arizona"},
+					{label: "Arkansas"},
+					{label: "Armed Forces Europe"},
+					{label: "Armed Forces Pacific"},
+					{label: "Armed Forces the Americas"},
+					{label: "California"},
+					{label: "Colorado"},
+					{label: "Connecticut"},
+					{label: "Delaware"},
+					{label: "District of Columbia"},
+					{label: "Federated States of Micronesia"},
+					{label: "Florida"},
+					{label: "Georgia"},
+					{label: "Guam"},
+					{label: "Hawaii"},
+					{label: "Idaho"},
+					{label: "Illinois"},
+					{label: "Indiana"},
+					{label: "Iowa"},
+					{label: "Kansas"},
+					{label: "Kentucky"},
+					{label: "Louisiana"},
+					{label: "Maine"},
+					{label: "Marshall Islands"},
+					{label: "Maryland"},
+					{label: "Massachusetts"},
+					{label: "Michigan"},
+					{label: "Minnesota"},
+					{label: "Mississippi"},
+					{label: "Missouri"},
+					{label: "Montana"},
+					{label: "Nebraska"},
+					{label: "Nevada"},
+					{label: "New Hampshire"},
+					{label: "New Jersey"},
+					{label: "New Mexico"},
+					{label: "New York"},
+					{label: "North Carolina"},
+					{label: "North Dakota"},
+					{label: "Northern Mariana Islands"},
+					{label: "Ohio"},
+					{label: "Oklahoma"},
+					{label: "Oregon"},
+					{label: "Pennsylvania"},
+					{label: "Puerto Rico"},
+					{label: "Rhode Island"},
+					{label: "South Carolina"},
+					{label: "South Dakota"},
+					{label: "Tennessee"},
+					{label: "Texas"},
+					{label: "Utah"},
+					{label: "Vermont"},
+					{label: "Virgin Islands, U.S."},
+					{label: "Virginia"},
+					{label: "Washington"},
+					{label: "West Virginia"},
+					{label: "Wisconsin"},
+					{label: "Wyoming"}
+				]
+			};
+			
+			// store for the dojox/mobile/EdgeToEdgeStoreList
+			var store = new Memory({idProperty: "label", data: static_data});
+		    
+			ready(function(){
+				var listWidget = new declare([EdgeToEdgeStoreList, FilteredListMixin])(
+					{placeHolder: 'Search', store: store}, "list");
+				listWidget.startup();
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view" data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered EdgeToEdgeStoreList</h1>
+		<div id="list" style="height:100%"></div>
+	</div>
+</body>
+</html>
+
diff --git a/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-auto.html b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-auto.html
new file mode 100644
index 0000000..c35dc5c
--- /dev/null
+++ b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-auto.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Filtered EdgeToEdgeStoreList - auto</title>
+	
+	<!-- This test shows a dojox/mobile/EdgeToEdgeStoreList filtered using dojox/mobile/FilteredListMixin. -->
+	<!-- Use-case: markup; SearchBox and ScrollableView created automatically by the mixin. -->
+	
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		var store;
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojo/store/Memory",
+			"dojox/mobile/EdgeToEdgeStoreList",
+			"dojox/mobile/FilteredListMixin"
+			], function(parser, mobile, compat, Memory, ScrollableView, 
+						EdgeToEdgeStoreList, FilteredListMixin){
+							
+			var static_data = { 
+				items: [ 
+					{label: "Alabama"},
+					{label: "Alaska"},
+					{label: "American Samoa"},
+					{label: "Arizona"},
+					{label: "Arkansas"},
+					{label: "Armed Forces Europe"},
+					{label: "Armed Forces Pacific"},
+					{label: "Armed Forces the Americas"},
+					{label: "California"},
+					{label: "Colorado"},
+					{label: "Connecticut"},
+					{label: "Delaware"},
+					{label: "District of Columbia"},
+					{label: "Federated States of Micronesia"},
+					{label: "Florida"},
+					{label: "Georgia"},
+					{label: "Guam"},
+					{label: "Hawaii"},
+					{label: "Idaho"},
+					{label: "Illinois"},
+					{label: "Indiana"},
+					{label: "Iowa"},
+					{label: "Kansas"},
+					{label: "Kentucky"},
+					{label: "Louisiana"},
+					{label: "Maine"},
+					{label: "Marshall Islands"},
+					{label: "Maryland"},
+					{label: "Massachusetts"},
+					{label: "Michigan"},
+					{label: "Minnesota"},
+					{label: "Mississippi"},
+					{label: "Missouri"},
+					{label: "Montana"},
+					{label: "Nebraska"},
+					{label: "Nevada"},
+					{label: "New Hampshire"},
+					{label: "New Jersey"},
+					{label: "New Mexico"},
+					{label: "New York"},
+					{label: "North Carolina"},
+					{label: "North Dakota"},
+					{label: "Northern Mariana Islands"},
+					{label: "Ohio"},
+					{label: "Oklahoma"},
+					{label: "Oregon"},
+					{label: "Pennsylvania"},
+					{label: "Puerto Rico"},
+					{label: "Rhode Island"},
+					{label: "South Carolina"},
+					{label: "South Dakota"},
+					{label: "Tennessee"},
+					{label: "Texas"},
+					{label: "Utah"},
+					{label: "Vermont"},
+					{label: "Virgin Islands, U.S."},
+					{label: "Virginia"},
+					{label: "Washington"},
+					{label: "West Virginia"},
+					{label: "Wisconsin"},
+					{label: "Wyoming"}
+				]
+			};
+			
+			// store for the dojox/mobile/EdgeToEdgeStoreList
+			store = new Memory({idProperty: "label", data: static_data});
+		});
+	</script>
+</head>
+
+<body style="visibility:hidden;background-color:#424142;">
+	<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered EdgeToEdgeStoreList</h1>
+		<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" id="list"
+			data-dojo-mixins="dojox/mobile/FilteredListMixin"
+			data-dojo-props="placeHolder: 'Search', store: store"></ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-demo.html b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-demo.html
new file mode 100644
index 0000000..c34af3b
--- /dev/null
+++ b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-demo.html
@@ -0,0 +1,221 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Filtered EdgeToEdgeStoreList - demo</title>
+	
+	<!-- This test shows a dojox/mobile/EdgeToEdgeStoreList filtered using dojox/mobile/FilteredListMixin. -->
+	<!-- Use-case: markup; demonstrates the customization of filtering criteria. -->
+	
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		var store;
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojo/ready",
+			"dijit/registry",
+			"dojo/store/Memory",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/EdgeToEdgeStoreList",
+			"dojox/mobile/FilteredListMixin",
+			"dojox/mobile/SearchBox",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/RoundRect",
+			"dojox/mobile/Button",
+			"dojox/mobile/RadioButton",
+			"dojox/mobile/Switch"
+			], function(parser, mobile, compat, ready, registry, 
+						Memory, ScrollableView, EdgeToEdgeStoreList, FilteredListMixin,
+						SearchBox, SimpleDialog, RoundRect, Button, RadioButton, Switch){
+							
+			var filterBox;
+			var static_data = { 
+				items: [ 
+					{label: "Alabama"},
+					{label: "Alaska"},
+					{label: "American Samoa"},
+					{label: "Arizona"},
+					{label: "Arkansas"},
+					{label: "Armed Forces Europe"},
+					{label: "Armed Forces Pacific"},
+					{label: "Armed Forces the Americas"},
+					{label: "California"},
+					{label: "Colorado"},
+					{label: "Connecticut"},
+					{label: "Delaware"},
+					{label: "District of Columbia"},
+					{label: "Federated States of Micronesia"},
+					{label: "Florida"},
+					{label: "Georgia"},
+					{label: "Guam"},
+					{label: "Hawaii"},
+					{label: "Idaho"},
+					{label: "Illinois"},
+					{label: "Indiana"},
+					{label: "Iowa"},
+					{label: "Kansas"},
+					{label: "Kentucky"},
+					{label: "Louisiana"},
+					{label: "Maine"},
+					{label: "Marshall Islands"},
+					{label: "Maryland"},
+					{label: "Massachusetts"},
+					{label: "Michigan"},
+					{label: "Minnesota"},
+					{label: "Mississippi"},
+					{label: "Missouri"},
+					{label: "Montana"},
+					{label: "Nebraska"},
+					{label: "Nevada"},
+					{label: "New Hampshire"},
+					{label: "New Jersey"},
+					{label: "New Mexico"},
+					{label: "New York"},
+					{label: "North Carolina"},
+					{label: "North Dakota"},
+					{label: "Northern Mariana Islands"},
+					{label: "Ohio"},
+					{label: "Oklahoma"},
+					{label: "Oregon"},
+					{label: "Pennsylvania"},
+					{label: "Puerto Rico"},
+					{label: "Rhode Island"},
+					{label: "South Carolina"},
+					{label: "South Dakota"},
+					{label: "Tennessee"},
+					{label: "Texas"},
+					{label: "Utah"},
+					{label: "Vermont"},
+					{label: "Virgin Islands, U.S."},
+					{label: "Virginia"},
+					{label: "Washington"},
+					{label: "West Virginia"},
+					{label: "Wisconsin"},
+					{label: "Wyoming"}
+				]
+			};
+			
+			// store for the dojox/mobile/EdgeToEdgeStoreList
+			store = new Memory({idProperty: "label", data: static_data});
+		    
+			// Shows the Search Options dialog.
+			showOptions = function(dlg){
+				registry.byId(dlg).show();
+			};
+
+			// Hides the Search Options dialog. Optionally, applies the new search options.
+			hideOptions = function(dlg, applyOptions){
+				registry.byId(dlg).hide();
+				if(applyOptions){
+					filterBox.ignoreCase = registry.byId("ignoreCaseSwitch").value == "on";
+					filterBox.set("incremental", registry.byId("incrementalSwitch").value == "on");
+					if (registry.byId("radioStartsWith").checked){
+						filterBox.queryExpr = "${0}*";
+					}else if(registry.byId("radioContains").checked){
+						filterBox.queryExpr = "*${0}*";
+					}else if(registry.byId("radioIs").checked){
+						filterBox.queryExpr = "${0}";
+					}
+				}
+			};
+			
+			ready(function(){
+				filterBox = registry.byId("list").getFilterBox();
+			});
+		});
+	</script>
+	
+	<style>
+		.mblSimpleDialogButton {
+			margin: 7px 0 0;
+			width: 262px;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialogButton2l {
+			float: left;
+			width: 127px;
+			margin: 7px 0 0;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialogButton2r {
+			float: right;
+			width: 127px;
+			margin: 7px 0 0;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+	</style>
+</head>
+
+<body style="visibility:hidden;background-color:#424142;">
+	<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered EdgeToEdgeStoreList</h1>
+		<input data-dojo-type="dojox/mobile/SearchBox" type="search" id="filterBox"
+			style="width:50%; float: left; margin-top: 2px" class="mblFilteredEdgeToEdgeListSearchBox">
+		<button style="float:right" onclick="showOptions('dlg_options')">Options</button>
+		<div style="clear:left" data-dojo-type="dojox/mobile/ScrollableView">
+			<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList" id="list"
+				data-dojo-mixins="dojox/mobile/FilteredListMixin"
+				data-dojo-props="filterBoxRef: 'filterBox', placeHolder: 'Search', store: store"></ul>
+		</div>
+	</div>
+	
+	<div id="dlg_options" data-dojo-type="dojox/mobile/SimpleDialog">
+		<div class="mblSimpleDialogTitle">Search Options</div>
+		<table style="width:100%">
+			<tr>
+				<td><span class="bold">Ignore case</span></td>
+				<td style="text-align:left">
+					<input type="checkbox" data-dojo-type="dojox/mobile/Switch" 
+						id="ignoreCaseSwitch" value="on"></td>
+			</tr>
+			<tr>
+				<td><span class="bold">Incremental</span></td>
+				<td style="text-align:left">
+					<input type="checkbox" data-dojo-type="dojox/mobile/Switch" 
+						id="incrementalSwitch" value="on">
+				</td>
+			</tr>
+			<tr>
+				<td style="text-align:left">
+					<input type="radio" id="radioStartsWith" data-dojo-type="dojox/mobile/RadioButton" 
+						name="mobileRadio" value="Starts with" checked>
+					<label for="radioStartsWith">Starts with</label>
+				</td>
+			</tr>
+			<tr>
+				<td style="text-align:left">
+					<input type="radio" id="radioContains" data-dojo-type="dojox/mobile/RadioButton" 
+						name="mobileRadio" value="Contains">
+					<label for="radioContains">Contains</label>
+				</td>
+			</tr>
+			<tr>
+				<td style="text-align:left">
+					<input type="radio" id="radioIs" data-dojo-type="dojox/mobile/RadioButton" 
+						name="mobileRadio" value="Is">
+					<label for="radioIs">Is</label>
+				</td>
+			</tr>
+		</table>
+
+		<button data-dojo-type="dojox/mobile/Button" class="mblSimpleDialogButton2l" 
+			onclick="hideOptions('dlg_options', false)">Cancel</button>
+		<button data-dojo-type="dojox/mobile/Button" class="mblSimpleDialogButton2r mblBlueButton" 
+			onclick="hideOptions('dlg_options', true)">OK</button>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-prog.html b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-prog.html
new file mode 100644
index 0000000..5fe11ed
--- /dev/null
+++ b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-prog.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Filtered EdgeToEdgeStoreList - prog</title>
+
+	<!-- This test shows a dojox/mobile/EdgeToEdgeStoreList filtered using dojox/mobile/FilteredListMixin. -->
+	<!-- Use-case: programmatic; without customization of filtering criteria. -->
+	
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base', 'SearchBox']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/ready",
+			"dijit/registry",
+			"dojo/store/Memory",
+			"dojox/mobile/EdgeToEdgeStoreList",
+			"dojox/mobile/FilteredListMixin",
+			"dojox/mobile/SearchBox",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/Heading",
+			"dojox/mobile",
+			"dojox/mobile/View",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser"
+		], function(declare, ready, registry, Memory, EdgeToEdgeStoreList, FilteredListMixin){
+			var static_data = { 
+				items: [ 
+					{label: "Alabama"},
+					{label: "Alaska"},
+					{label: "American Samoa"},
+					{label: "Arizona"},
+					{label: "Arkansas"},
+					{label: "Armed Forces Europe"},
+					{label: "Armed Forces Pacific"},
+					{label: "Armed Forces the Americas"},
+					{label: "California"},
+					{label: "Colorado"},
+					{label: "Connecticut"},
+					{label: "Delaware"},
+					{label: "District of Columbia"},
+					{label: "Federated States of Micronesia"},
+					{label: "Florida"},
+					{label: "Georgia"},
+					{label: "Guam"},
+					{label: "Hawaii"},
+					{label: "Idaho"},
+					{label: "Illinois"},
+					{label: "Indiana"},
+					{label: "Iowa"},
+					{label: "Kansas"},
+					{label: "Kentucky"},
+					{label: "Louisiana"},
+					{label: "Maine"},
+					{label: "Marshall Islands"},
+					{label: "Maryland"},
+					{label: "Massachusetts"},
+					{label: "Michigan"},
+					{label: "Minnesota"},
+					{label: "Mississippi"},
+					{label: "Missouri"},
+					{label: "Montana"},
+					{label: "Nebraska"},
+					{label: "Nevada"},
+					{label: "New Hampshire"},
+					{label: "New Jersey"},
+					{label: "New Mexico"},
+					{label: "New York"},
+					{label: "North Carolina"},
+					{label: "North Dakota"},
+					{label: "Northern Mariana Islands"},
+					{label: "Ohio"},
+					{label: "Oklahoma"},
+					{label: "Oregon"},
+					{label: "Pennsylvania"},
+					{label: "Puerto Rico"},
+					{label: "Rhode Island"},
+					{label: "South Carolina"},
+					{label: "South Dakota"},
+					{label: "Tennessee"},
+					{label: "Texas"},
+					{label: "Utah"},
+					{label: "Vermont"},
+					{label: "Virgin Islands, U.S."},
+					{label: "Virginia"},
+					{label: "Washington"},
+					{label: "West Virginia"},
+					{label: "Wisconsin"},
+					{label: "Wyoming"}
+				]
+			};
+			
+			// store for the dojox/mobile/EdgeToEdgeStoreList
+			var store = new Memory({idProperty:"label", data: static_data});
+		    
+			ready(function(){
+				var view = registry.byId("scrollableView");
+				
+				var listWidget =
+					new declare([EdgeToEdgeStoreList, FilteredListMixin])(
+						{filterBoxRef: 'filterBox', placeHolder: 'Search', store: store});
+				
+				listWidget.placeAt(view.containerNode);
+				listWidget.startup();
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered EdgeToEdgeStoreList</h1>
+		<input data-dojo-type="dojox/mobile/SearchBox" type="search" id="filterBox"
+			class="mblFilteredEdgeToEdgeListSearchBox">
+		<div id="scrollableView" data-dojo-type="dojox/mobile/ScrollableView"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-simple.html b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-simple.html
new file mode 100644
index 0000000..40d998a
--- /dev/null
+++ b/dojox/mobile/tests/test_FilteredList-EdgeToEdgeStoreList-simple.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Filtered EdgeToEdgeStoreList - simple</title>
+	
+	<!-- This test shows a dojox/mobile/EdgeToEdgeStoreList filtered using dojox/mobile/FilteredListMixin. -->
+	<!-- Use-case: markup; without customization of filtering criteria. -->
+	
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		var store;
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojo/ready",
+			"dijit/registry",
+			"dojo/store/Memory",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/EdgeToEdgeStoreList",
+			"dojox/mobile/FilteredListMixin"
+			], function(parser, mobile, compat, ready, registry, 
+						Memory, ScrollableView, EdgeToEdgeStoreList, FilteredListMixin){
+							
+			var static_data = { 
+				items: [ 
+					{label: "Alabama"},
+					{label: "Alaska"},
+					{label: "American Samoa"},
+					{label: "Arizona"},
+					{label: "Arkansas"},
+					{label: "Armed Forces Europe"},
+					{label: "Armed Forces Pacific"},
+					{label: "Armed Forces the Americas"},
+					{label: "California"},
+					{label: "Colorado"},
+					{label: "Connecticut"},
+					{label: "Delaware"},
+					{label: "District of Columbia"},
+					{label: "Federated States of Micronesia"},
+					{label: "Florida"},
+					{label: "Georgia"},
+					{label: "Guam"},
+					{label: "Hawaii"},
+					{label: "Idaho"},
+					{label: "Illinois"},
+					{label: "Indiana"},
+					{label: "Iowa"},
+					{label: "Kansas"},
+					{label: "Kentucky"},
+					{label: "Louisiana"},
+					{label: "Maine"},
+					{label: "Marshall Islands"},
+					{label: "Maryland"},
+					{label: "Massachusetts"},
+					{label: "Michigan"},
+					{label: "Minnesota"},
+					{label: "Mississippi"},
+					{label: "Missouri"},
+					{label: "Montana"},
+					{label: "Nebraska"},
+					{label: "Nevada"},
+					{label: "New Hampshire"},
+					{label: "New Jersey"},
+					{label: "New Mexico"},
+					{label: "New York"},
+					{label: "North Carolina"},
+					{label: "North Dakota"},
+					{label: "Northern Mariana Islands"},
+					{label: "Ohio"},
+					{label: "Oklahoma"},
+					{label: "Oregon"},
+					{label: "Pennsylvania"},
+					{label: "Puerto Rico"},
+					{label: "Rhode Island"},
+					{label: "South Carolina"},
+					{label: "South Dakota"},
+					{label: "Tennessee"},
+					{label: "Texas"},
+					{label: "Utah"},
+					{label: "Vermont"},
+					{label: "Virgin Islands, U.S."},
+					{label: "Virginia"},
+					{label: "Washington"},
+					{label: "West Virginia"},
+					{label: "Wisconsin"},
+					{label: "Wyoming"}
+				]
+			};
+			
+			// store for the dojox/mobile/EdgeToEdgeStoreList
+			store = new Memory({idProperty: "label", data: static_data});
+		});
+	</script>
+</head>
+
+<body style="visibility:hidden;background-color:#424142;">
+	<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered EdgeToEdgeStoreList</h1>
+		<input data-dojo-type="dojox/mobile/SearchBox" type="search" id="filterBox"
+			class="mblFilteredEdgeToEdgeListSearchBox">
+		<div data-dojo-type="dojox/mobile/ScrollableView">
+			<ul data-dojo-type="dojox/mobile/EdgeToEdgeStoreList"
+				data-dojo-mixins="dojox/mobile/FilteredListMixin"
+				data-dojo-props="filterBoxRef: 'filterBox', placeHolder: 'Search', store: store"></ul>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FilteredList-RoundRectList-auto.html b/dojox/mobile/tests/test_FilteredList-RoundRectList-auto.html
new file mode 100644
index 0000000..4460f30
--- /dev/null
+++ b/dojox/mobile/tests/test_FilteredList-RoundRectList-auto.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Filtered RoundRectList - auto</title>
+	
+	<!-- This test shows a dojox/mobile/RoundRectList filtered using dojox/mobile/FilteredListMixin. -->
+	<!-- Use-case: markup; SearchBox and ScrollableView created automatically by the mixin. -->
+	
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+	
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FilteredListMixin"
+			]);
+	</script>
+	
+	<style>
+		body,html{
+			width: 100%;
+		}
+	</style>
+</head>
+
+<body style="visibility:hidden;background-color:#424142;">
+	<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered RoundRectList</h1>
+		<ul id="list" data-dojo-type="dojox/mobile/RoundRectList"
+			data-dojo-mixins="dojox/mobile/FilteredListMixin"
+			data-dojo-props="placeHolder: 'Search'">
+			<li data-dojo-type="dojox/mobile/ListItem">Alabama</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Alaska</li>
+			<li data-dojo-type="dojox/mobile/ListItem">American Samoa</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Arizona</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Arkansas</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Armed Forces Europe</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Armed Forces Pacific</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Armed Forces the Americas</li>
+			<li data-dojo-type="dojox/mobile/ListItem">California</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Colorado</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Connecticut</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Delaware</li>
+			<li data-dojo-type="dojox/mobile/ListItem">District of Columbia</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Federated States of Micronesia</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Florida</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Georgia</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Guam</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Hawaii</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Idaho</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Illinois</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Indiana</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Iowa</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Kansas</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Kentucky</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Louisiana</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Maine</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Marshall Islands</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Maryland</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Massachusetts</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Michigan</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Minnesota</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Mississippi</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Missouri</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Montana</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Nebraska</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Nevada</li>
+			<li data-dojo-type="dojox/mobile/ListItem">New Hampshire</li>
+			<li data-dojo-type="dojox/mobile/ListItem">New Jersey</li>
+			<li data-dojo-type="dojox/mobile/ListItem">New Mexico</li>
+			<li data-dojo-type="dojox/mobile/ListItem">New York</li>
+			<li data-dojo-type="dojox/mobile/ListItem">North Carolina</li>
+			<li data-dojo-type="dojox/mobile/ListItem">North Dakota</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Northern Mariana Islands</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Ohio</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Oklahoma</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Oregon</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Pennsylvania</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Puerto Rico</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Rhode Island</li>
+			<li data-dojo-type="dojox/mobile/ListItem">South Carolina</li>
+			<li data-dojo-type="dojox/mobile/ListItem">South Dakota</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Tennessee</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Texas</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Utah</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Vermont</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Virgin Islands, U.S.</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Virginia</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Washington</li>
+			<li data-dojo-type="dojox/mobile/ListItem">West Virginia</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Wisconsin</li>
+			<li data-dojo-type="dojox/mobile/ListItem">Wyoming</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FilteredList-RoundRectList-demo.html b/dojox/mobile/tests/test_FilteredList-RoundRectList-demo.html
new file mode 100644
index 0000000..0adb765
--- /dev/null
+++ b/dojox/mobile/tests/test_FilteredList-RoundRectList-demo.html
@@ -0,0 +1,228 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Filtered RoundRectList - demo</title>
+	
+	<!-- This test shows a dojox/mobile/RoundRectList filtered using dojox/mobile/FilteredListMixin. -->
+	<!-- Use-case: markup; demonstrates the customization of filtering criteria. -->
+
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/FilteredListMixin",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/RoundRect",
+			"dojox/mobile/Button",
+			"dojox/mobile/RadioButton",
+			"dojox/mobile/Switch"
+			], function(parser, mobile, compat, ready, registry, 
+						FilteredListMixin, ScrollableView, SimpleDialog, RoundRect, Button, RadioButton, Switch){
+			
+			var filterBox;
+			
+			// Shows the Search Options dialog.
+			showOptions = function(dlg){
+				registry.byId(dlg).show();
+			};
+
+			// Hides the Search Options dialog. Optionally, applies the new search options.
+			hideOptions = function(dlg, applyOptions){
+				registry.byId(dlg).hide();
+				if(applyOptions){
+					filterBox.set("ignoreCase", registry.byId("ignoreCaseSwitch").value == "on");
+					filterBox.set("incremental", registry.byId("incrementalSwitch").value == "on");
+					if (registry.byId("radioStartsWith").checked){
+						filterBox.queryExpr = "${0}*";
+					}else if(registry.byId("radioContains").checked){
+						filterBox.queryExpr = "*${0}*";
+					}else if(registry.byId("radioIs").checked){
+						filterBox.queryExpr = "${0}";
+					}
+				}
+			};
+			
+			ready(function(){
+				filterBox = registry.byId("filterBox");
+			});
+		});
+	</script>
+	
+	<style>
+		/* Fit the margin defined by mblRoundRectList in all themes but ipad */
+		.searchOptions {
+			float: right; 
+			margin-right: 9px;
+		}
+		/* Fit the margin defined by mblRoundRectList for ipad */
+		.dj_ipad.dj_tablet .searchOptions {
+			float: right; 
+			margin-right: 30px;
+		}
+		.lnk {
+			font-size: 14px;
+			color: #0B5199;
+			text-decoration: none;
+		}
+		.mblSimpleDialogButton {
+			margin: 7px 0 0;
+			width: 262px;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialogButton2l {
+			float: left;
+			width: 127px;
+			margin: 7px 0 0;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialogButton2r {
+			float: right;
+			width: 127px;
+			margin: 7px 0 0;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+	</style>
+</head>
+
+<body style="visibility:hidden;background-color:#424142;">
+	<div data-dojo-type="dojox/mobile/View">
+		<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="fixed: 'top'">Filtered RoundRectList</h1>
+		<div class="mblFilteredRoundRectListSearchBox">
+			<input data-dojo-type="dojox/mobile/SearchBox" type="search" id="filterBox"
+				data-dojo-props="filterBoxRef: 'filterBox'"
+				style="width: 50%; float: left">
+		</div>
+		<button class="searchOptions" onclick="showOptions('dlg_options')">Options</button>
+		<div data-dojo-type="dojox/mobile/ScrollableView">
+			<ul id="list" data-dojo-type="dojox/mobile/RoundRectList"
+				data-dojo-mixins="dojox/mobile/FilteredListMixin"
+				data-dojo-props="filterBoxRef: 'filterBox', placeHolder: 'Search'">
+				<li data-dojo-type="dojox/mobile/ListItem">Alabama</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Alaska</li>
+				<li data-dojo-type="dojox/mobile/ListItem">American Samoa</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Arizona</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Arkansas</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Armed Forces Europe</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Armed Forces Pacific</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Armed Forces the Americas</li>
+				<li data-dojo-type="dojox/mobile/ListItem">California</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Colorado</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Connecticut</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Delaware</li>
+				<li data-dojo-type="dojox/mobile/ListItem">District of Columbia</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Federated States of Micronesia</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Florida</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Georgia</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Guam</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Hawaii</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Idaho</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Illinois</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Indiana</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Iowa</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Kansas</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Kentucky</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Louisiana</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Maine</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Marshall Islands</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Maryland</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Massachusetts</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Michigan</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Minnesota</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Mississippi</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Missouri</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Montana</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Nebraska</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Nevada</li>
+				<li data-dojo-type="dojox/mobile/ListItem">New Hampshire</li>
+				<li data-dojo-type="dojox/mobile/ListItem">New Jersey</li>
+				<li data-dojo-type="dojox/mobile/ListItem">New Mexico</li>
+				<li data-dojo-type="dojox/mobile/ListItem">New York</li>
+				<li data-dojo-type="dojox/mobile/ListItem">North Carolina</li>
+				<li data-dojo-type="dojox/mobile/ListItem">North Dakota</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Northern Mariana Islands</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Ohio</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Oklahoma</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Oregon</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Pennsylvania</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Puerto Rico</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Rhode Island</li>
+				<li data-dojo-type="dojox/mobile/ListItem">South Carolina</li>
+				<li data-dojo-type="dojox/mobile/ListItem">South Dakota</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Tennessee</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Texas</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Utah</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Vermont</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Virgin Islands, U.S.</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Virginia</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Washington</li>
+				<li data-dojo-type="dojox/mobile/ListItem">West Virginia</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Wisconsin</li>
+				<li data-dojo-type="dojox/mobile/ListItem">Wyoming</li>
+			</ul>
+		</div>
+	</div>
+	
+	<div id="dlg_options" data-dojo-type="dojox/mobile/SimpleDialog">
+		<div class="mblSimpleDialogTitle">Search Options</div>
+		<table style="width:100%">
+			<tr>
+				<td><span class="bold">Ignore case</span></td>
+				<td style="text-align:left">
+					<input type="checkbox" data-dojo-type="dojox/mobile/Switch" 
+						id="ignoreCaseSwitch" value="on"></td>
+			</tr>
+			<tr>
+				<td><span class="bold">Incremental</span></td>
+				<td style="text-align:left">
+					<input type="checkbox" data-dojo-type="dojox/mobile/Switch" 
+						id="incrementalSwitch" value="on">
+				</td>
+			</tr>
+			<tr>
+				<td style="text-align:left">
+					<input type="radio" id="radioStartsWith" data-dojo-type="dojox/mobile/RadioButton" 
+						name="mobileRadio" value="Starts with" checked>
+					<label for="radioStartsWith">Starts with</label>
+				</td>
+			</tr>
+			<tr>
+				<td style="text-align:left">
+					<input type="radio" id="radioContains" data-dojo-type="dojox/mobile/RadioButton" 
+						name="mobileRadio" value="Contains">
+					<label for="radioContains">Contains</label>
+				</td>
+			</tr>
+			<tr>
+				<td style="text-align:left">
+					<input type="radio" id="radioIs" data-dojo-type="dojox/mobile/RadioButton" 
+						name="mobileRadio" value="Is">
+					<label for="radioIs">Is</label>
+				</td>
+			</tr>
+		</table>
+
+		<button data-dojo-type="dojox/mobile/Button" class="mblSimpleDialogButton2l" 
+			onclick="hideOptions('dlg_options', false)">Cancel</button>
+		<button data-dojo-type="dojox/mobile/Button" class="mblSimpleDialogButton2r mblBlueButton" 
+			onclick="hideOptions('dlg_options', true)">OK</button>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-H2-prog.html b/dojox/mobile/tests/test_FixedSplitter-H2-prog.html
index a46763a..909738d 100644
--- a/dojox/mobile/tests/test_FixedSplitter-H2-prog.html
+++ b/dojox/mobile/tests/test_FixedSplitter-H2-prog.html
@@ -1,45 +1,53 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<title>FixedSplitter Test</title>
-		<style type="text/css">
-			@import "../themes/common/FixedSplitter.css";
-			html, body{
-				width: 100%;
-				height: 100%;
-				padding: 0px;
-				margin: 0px;
-				overflow: hidden;
-			}
-		</style>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<title>FixedSplitter Test</title>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+	<link href="../themes/iphone/FixedSplitter.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.parser");
-			dojo.require("dojox.mobile.FixedSplitter");
-			dojo.ready(function(){
-					var w = new dojox.mobile.FixedSplitter({
-						orientation: "H"
-					}, dojo.byId("container"));
-					w.startup();
+	<script type="text/javascript">
+		require([
+			"dojo/dom",
+			"dojo/ready",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Pane",
+			"dojox/mobile/parser"
+		], function(dom, ready, FixedSplitter, Pane){
+			ready(function(){
+				var w = new FixedSplitter({
+					orientation: "H"
+				}, dom.byId("container"));
+				w.startup();
 
-					var p0 = new dojox.mobile.FixedSplitterPane({
-						innerHTML: "pane #1 (width=200px)"
-					});
-					p0.domNode.style.backgroundColor = "yellow";
-					p0.domNode.style.width = "200px";
-					w.addChild(p0);
+				var p0 = new Pane({
+					innerHTML: "pane #1 (width=200px)"
+				});
+				p0.domNode.style.backgroundColor = "yellow";
+				p0.domNode.style.width = "200px";
+				w.addChild(p0);
 
-					var p1 = new dojox.mobile.FixedSplitterPane({
-						innerHTML: "pane #2"
-					});
-					p1.domNode.style.backgroundColor = "pink";
-					w.addChild(p1);
+				var p1 = new Pane({
+					innerHTML: "pane #2"
+				});
+				p1.domNode.style.backgroundColor = "pink";
+				w.addChild(p1);
 			});
-		</script>
-	</head>
-	<body>
-		<div id="container"></div>
-	</body>
+		});
+	</script>
+
+	<style type="text/css">
+		html, body{
+			width: 100%;
+			height: 100%;
+			padding: 0px;
+			margin: 0px;
+			overflow: hidden;
+		}
+	</style>
+</head>
+<body>
+	<div id="container"></div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-H2.html b/dojox/mobile/tests/test_FixedSplitter-H2.html
index 4b224dc..7469633 100644
--- a/dojox/mobile/tests/test_FixedSplitter-H2.html
+++ b/dojox/mobile/tests/test_FixedSplitter-H2.html
@@ -1,31 +1,38 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<title>FixedSplitter Test</title>
-		<style type="text/css">
-			@import "../themes/common/FixedSplitter.css";
-			html, body{
-				width: 100%;
-				height: 100%;
-				padding: 0px;
-				margin: 0px;
-				overflow: hidden;
-			}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.parser");
-			dojo.require("dojox.mobile.FixedSplitter");
-		</script>
-	</head>
-	<body>
-		<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:yellow;width:200px;">
-				pane #1 (width=200px)
-			</div>
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:pink;">
-				pane #2
-			</div>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<title>FixedSplitter Test</title>
+
+	<link href="../themes/iphone/FixedSplitter.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Pane"
+		]);
+	</script>
+
+	<style type="text/css">
+		html, body{
+			width: 100%;
+			height: 100%;
+			padding: 0px;
+			margin: 0px;
+			overflow: hidden;
+		}
+	</style>
+</head>
+<body>
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Pane" style="background-color:yellow;width:200px;">
+			pane #1 (width=200px)
 		</div>
-	</body>
+		<div data-dojo-type="dojox.mobile.Pane" style="background-color:pink;">
+			pane #2
+		</div>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-V2H2-ContentPane.html b/dojox/mobile/tests/test_FixedSplitter-V2H2-ContentPane.html
new file mode 100644
index 0000000..ccc5b85
--- /dev/null
+++ b/dojox/mobile/tests/test_FixedSplitter-V2H2-ContentPane.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<title>FixedSplitter Test</title>
+
+	<link href="../themes/iphone/FixedSplitter.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile/ContentPane",
+			"dojox/mobile/FixedSplitter"
+		]);
+	</script>
+
+	<style type="text/css">
+		html, body{
+			width: 100%;
+			height: 100%;
+			padding: 0px;
+			margin: 0px;
+			overflow: hidden;
+		}
+	</style>
+</head>
+<body>
+	<div data-dojo-type="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" data-dojo-props='orientation:"V"'>
+		<div data-dojo-type="dojox.mobile.ContentPane" style="background-color:yellow;height:20%" href="data/FixedSplitterfragment1.html">
+		</div>
+
+		<div data-dojo-type="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" data-dojo-props='orientation:"H"'>
+			<div data-dojo-type="dojox.mobile.ContentPane" style="background-color:pink;width:20%;" href="data/FixedSplitterfragment2.html">
+			</div>
+			<div data-dojo-type="dojox.mobile.ContentPane" style="background-color:cyan;" href="data/FixedSplitterfragment3.html">
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-V2H2-change.html b/dojox/mobile/tests/test_FixedSplitter-V2H2-change.html
new file mode 100644
index 0000000..21e3fb8
--- /dev/null
+++ b/dojox/mobile/tests/test_FixedSplitter-V2H2-change.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<title>FixedSplitter Test</title>
+
+	<link href="../themes/iphone/FixedSplitter.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Pane"
+		], function(connect, dom, domClass, ready, registry){
+			change = function(e) {
+				var splitter = registry.byId(e.target.id == "btn1" ? "splitter1" : "splitter2");
+				splitter.set("orientation", splitter.orientation === "H" ? "V" : "H");
+			};
+			ready(function(){
+				connect.connect(dom.byId("btn1"), "onclick", "change");
+				connect.connect(dom.byId("btn2"), "onclick", "change");
+			});
+		});
+	</script>
+
+	<style type="text/css">
+		html, body{
+			width: 100%;
+			height: 100%;
+			padding: 0px;
+			margin: 0px;
+			overflow: hidden;
+		}
+
+		.mblFixedSplitterH > #pane1, .mblFixedSplitterH > #pane2 {
+			width:20%;
+		}
+		.mblFixedSplitterV > #pane1, .mblFixedSplitterV > #pane2 {
+			height:20%;
+		}
+	</style>
+</head>
+<body>
+	<div id="splitter1" data-dojo-type="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" data-dojo-props='orientation:"V"'>
+		<div id="pane1" data-dojo-type="dojox.mobile.Pane" style="background-color:yellow;">
+			pane #1
+	 		<input type="button" id="btn1" value="H <-> V">
+		</div>
+
+		<div id="splitter2" data-dojo-type="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" data-dojo-props='orientation:"H"'>
+			<div id="pane2" data-dojo-type="dojox.mobile.Pane" style="background-color:pink;">
+				pane #2
+	 			<input type="button" id="btn2" value="H <-> V">
+			</div>
+			<div id="pane3" data-dojo-type="dojox.mobile.Pane" style="background-color:cyan;">
+				pane #3
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-V2H2.html b/dojox/mobile/tests/test_FixedSplitter-V2H2.html
index 50be726..552aaea 100644
--- a/dojox/mobile/tests/test_FixedSplitter-V2H2.html
+++ b/dojox/mobile/tests/test_FixedSplitter-V2H2.html
@@ -1,37 +1,44 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<title>FixedSplitter Test</title>
-		<style type="text/css">
-			@import "../themes/common/FixedSplitter.css";
-			html, body{
-				width: 100%;
-				height: 100%;
-				padding: 0px;
-				margin: 0px;
-				overflow: hidden;
-			}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.parser");
-			dojo.require("dojox.mobile.FixedSplitter");
-		</script>
-	</head>
-	<body>
-		<div dojoType="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" orientation="V">
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:yellow;height:20%">
-				pane #1
-			</div>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<title>FixedSplitter Test</title>
+
+	<link href="../themes/iphone/FixedSplitter.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Pane"
+		]);
+	</script>
 
-			<div dojoType="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" orientation="H">
-				<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:pink;width:20%;">
-					pane #2
-				</div>
-				<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:cyan;">
-					pane #3
-				</div>
+	<style type="text/css">
+		html, body{
+			width: 100%;
+			height: 100%;
+			padding: 0px;
+			margin: 0px;
+			overflow: hidden;
+		}
+	</style>
+</head>
+<body>
+	<div data-dojo-type="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" data-dojo-props='orientation:"V"'>
+		<div data-dojo-type="dojox.mobile.Pane" style="background-color:yellow;height:20%">
+			pane #1
+		</div>
+
+		<div data-dojo-type="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" data-dojo-props='orientation:"H"'>
+			<div data-dojo-type="dojox.mobile.Pane" style="background-color:pink;width:20%;">
+				pane #2
+			</div>
+			<div data-dojo-type="dojox.mobile.Pane" style="background-color:cyan;">
+				pane #3
 			</div>
 		</div>
-	</body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-V3-var0.html b/dojox/mobile/tests/test_FixedSplitter-V3-var0.html
new file mode 100644
index 0000000..7a43648
--- /dev/null
+++ b/dojox/mobile/tests/test_FixedSplitter-V3-var0.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<title>FixedSplitter Test</title>
+
+	<link href="../themes/iphone/FixedSplitter.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Pane"
+		], function(connect, ready, registry){
+			ready(function(){
+				connect.connect(null, "onresize", function(){
+					registry.byId("splitter1").resize();
+				});
+			});
+		});
+	</script>
+
+	<style type="text/css">
+	html, body{
+		width: 100%;
+		height: 100%;
+		padding: 0px;
+		margin: 0px;
+		overflow: hidden;
+	}
+	#pane0 {
+		background-color: cyan;
+	}
+	#pane1 {
+		background-color: yellow;
+		border-bottom: 1px solid black;
+		height: 100px;
+	}
+	#pane2 {
+		background-color: pink;
+		height: 100px;
+	}
+	</style>
+</head>
+<body>
+	<div id="splitter1" data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"V", variablePane:0'>
+		<div id="pane0" data-dojo-type="dojox.mobile.Pane">
+			pane #0 (height=variable)
+		</div>
+		<div id="pane1" data-dojo-type="dojox.mobile.Pane">
+			pane #1 (height=100px)
+		</div>
+		<div id="pane2" data-dojo-type="dojox.mobile.Pane">
+			pane #2 (height=100px)
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-V3-var1.html b/dojox/mobile/tests/test_FixedSplitter-V3-var1.html
new file mode 100644
index 0000000..bcd98eba
--- /dev/null
+++ b/dojox/mobile/tests/test_FixedSplitter-V3-var1.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<title>FixedSplitter Test</title>
+
+	<link href="../themes/iphone/FixedSplitter.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Pane"
+		], function(connect, ready, registry){
+			ready(function(){
+				connect.connect(null, "onresize", function(){
+					registry.byId("splitter1").resize();
+				});
+			});
+		});
+	</script>
+
+	<style type="text/css">
+	html, body{
+		width: 100%;
+		height: 100%;
+		padding: 0px;
+		margin: 0px;
+		overflow: hidden;
+	}
+	#pane0 {
+		background-color: cyan;
+		height: 100px;
+	}
+	#pane1 {
+		background-color: yellow;
+		border-bottom: 1px solid black;
+	}
+	#pane2 {
+		background-color: pink;
+		height: 100px;
+	}
+	</style>
+</head>
+<body>
+	<div id="splitter1" data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"V", variablePane:1'>
+		<div id="pane0" data-dojo-type="dojox.mobile.Pane">
+			pane #0 (height=100px)
+		</div>
+		<div id="pane1" data-dojo-type="dojox.mobile.Pane">
+			pane #1 (height=variable)
+		</div>
+		<div id="pane2" data-dojo-type="dojox.mobile.Pane">
+			pane #2 (height=100px)
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-V3-var2.html b/dojox/mobile/tests/test_FixedSplitter-V3-var2.html
new file mode 100644
index 0000000..2c3983a
--- /dev/null
+++ b/dojox/mobile/tests/test_FixedSplitter-V3-var2.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<title>FixedSplitter Test</title>
+
+	<link href="../themes/iphone/FixedSplitter.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Pane"
+		], function(connect, ready, registry){
+			ready(function(){
+				connect.connect(null, "onresize", function(){
+					registry.byId("splitter1").resize();
+				});
+			});
+		});
+	</script>
+
+	<style type="text/css">
+	html, body{
+		width: 100%;
+		height: 100%;
+		padding: 0px;
+		margin: 0px;
+		overflow: hidden;
+	}
+	#pane0 {
+		background-color: cyan;
+		height: 100px;
+	}
+	#pane1 {
+		background-color: yellow;
+		border-bottom: 1px solid black;
+		height: 100px;
+	}
+	#pane2 {
+		background-color: pink;
+	}
+	</style>
+</head>
+<body>
+	<div id="splitter1" data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"V"'>
+		<div id="pane0" data-dojo-type="dojox.mobile.Pane">
+			pane #0 (height=100px)
+		</div>
+		<div id="pane1" data-dojo-type="dojox.mobile.Pane">
+			pane #1 (height=100px)
+		</div>
+		<div id="pane2" data-dojo-type="dojox.mobile.Pane">
+			pane #2 (height=variable)
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-V3.html b/dojox/mobile/tests/test_FixedSplitter-V3.html
index 850774a..5249279 100644
--- a/dojox/mobile/tests/test_FixedSplitter-V3.html
+++ b/dojox/mobile/tests/test_FixedSplitter-V3.html
@@ -1,34 +1,41 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<title>FixedSplitter Test</title>
-		<style type="text/css">
-			@import "../themes/common/FixedSplitter.css";
-			html, body{
-				width: 100%;
-				height: 100%;
-				padding: 0px;
-				margin: 0px;
-				overflow: hidden;
-			}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.parser");
-			dojo.require("dojox.mobile.FixedSplitter");
-		</script>
-	</head>
-	<body>
-		<div dojoType="dojox.mobile.FixedSplitter" orientation="V">
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:cyan;height:200px;">
-				pane #1 (height=200px)
-			</div>
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:yellow;height:100px;border-bottom:1px solid black">
-				pane #2 (height=100px)
-			</div>
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:pink;">
-				pane #3
-			</div>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<title>FixedSplitter Test</title>
+
+	<link href="../themes/iphone/FixedSplitter.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Pane"
+		]);
+	</script>
+
+	<style type="text/css">
+		html, body{
+			width: 100%;
+			height: 100%;
+			padding: 0px;
+			margin: 0px;
+			overflow: hidden;
+		}
+	</style>
+</head>
+<body>
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"V"'>
+		<div data-dojo-type="dojox.mobile.Pane" style="background-color:cyan;height:200px;">
+			pane #1 (height=200px)
 		</div>
-	</body>
+		<div data-dojo-type="dojox.mobile.Pane" style="background-color:yellow;height:100px;border-bottom:1px solid black">
+			pane #2 (height=100px)
+		</div>
+		<div data-dojo-type="dojox.mobile.Pane" style="background-color:pink;">
+			pane #3
+		</div>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-orientation.html b/dojox/mobile/tests/test_FixedSplitter-orientation.html
new file mode 100644
index 0000000..995ac4f
--- /dev/null
+++ b/dojox/mobile/tests/test_FixedSplitter-orientation.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>FixedSplitter Test</title>
+
+	<link href="../../../dijit/themes/tundra/tundra.css" rel="stylesheet"/>
+	<link href="../themes/iphone/FixedSplitter.css" rel="stylesheet"/>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/_base/window",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/sniff",
+			"dojox/mobile/parser",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Container",
+			"dojox/mobile/Pane",
+			"dijit/Calendar"
+		], function(connect, win, dom, domClass, ready, registry, has){
+			var change = function() {
+				var splitter = registry.byId("splitter1");
+				var h = win.global.innerHeight || win.doc.documentElement.clientHeight;
+				var w = win.global.innerWidth || win.doc.documentElement.clientWidth;
+				splitter.set("orientation", h > w ? "V" : "H");
+			};
+			ready(function(){
+				connect.connect(null, (win.global.onorientationchange !== undefined && !has('android'))
+					? "onorientationchange" : "onresize", null, change);
+				setTimeout(function(){
+					change();
+				}, 0);
+			});
+		});
+	</script>
+
+	<style type="text/css">
+		html, body{
+			width: 100%;
+			height: 100%;
+			padding: 0px;
+			margin: 0px;
+			overflow: hidden;
+		}
+
+		.mblFixedSplitterH > #pane2 {
+			width: 240px;
+		}
+		.mblFixedSplitterV > #pane2 {
+			height: 240px;
+		}
+
+		#cal {
+			margin: 10px;
+		}
+	</style>
+</head>
+<body class="tundra">
+	<div id="splitter1" data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='variablePane:0'>
+		<div id="pane1" data-dojo-type="dojox.mobile.Pane" style="background-color:yellow;">
+			pane #1
+		</div>
+
+		<div id="pane2" data-dojo-type="dojox.mobile.Container" style="background-color:pink;">
+			<div id="cal" dojoType='dijit.Calendar'></div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_FormControls.html b/dojox/mobile/tests/test_FormControls.html
index c414f53..1e8be98 100644
--- a/dojox/mobile/tests/test_FormControls.html
+++ b/dojox/mobile/tests/test_FormControls.html
@@ -1,173 +1,197 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Form Controls</title>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+	<title>Form Controls</title>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			// mobile form controls
-			dojo.require("dojox.mobile.Button");
-			dojo.require("dojox.mobile.CheckBox");
-			dojo.require("dojox.mobile.ComboBox");
-			dojo.require("dojox.mobile.RadioButton");
-			dojo.require("dojox.mobile.Slider");
-			dojo.require("dojox.mobile.TextBox");
-			dojo.require("dojox.mobile.ExpandingTextArea");
-			dojo.require("dojox.mobile.ToggleButton");
-		</script>
-		
-		<style>
-		.bold {
-			font-weight: bold;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<datalist>
-			<select dojoType="dijit.form.DataList" data-dojo-props='id:"states"' >
-				<option value="AL">Alabama</option>
-				<option value="AK">Alaska</option>
-				<option value="AS">American Samoa</option>
-				<option value="AZ">Arizona</option>
-				<option value="AR">Arkansas</option>
-				<option value="AE">Armed Forces Europe</option>
-				<option value="AP">Armed Forces Pacific</option>
-				<option value="AA">Armed Forces the Americas</option>
-				<option value="CA">California</option>
-				<option value="CO">Colorado</option>
-				<option value="CT">Connecticut</option>
-				<option value="DE">Delaware</option>
-				<option value="DC">District of Columbia</option>
-				<option value="FM">Federated States of Micronesia</option>
-				<option value="FL">Florida</option>
-				<option value="GA">Georgia</option>
-				<option value="GU">Guam</option>
-				<option value="HI">Hawaii</option>
-				<option value="ID">Idaho</option>
-				<option value="IL">Illinois</option>
-				<option value="IN">Indiana</option>
-				<option value="IA">Iowa</option>
-				<option value="KS">Kansas</option>
-				<option value="KY">Kentucky</option>
-				<option value="LA">Louisiana</option>
-				<option value="ME">Maine</option>
-				<option value="MH">Marshall Islands</option>
-				<option value="MD">Maryland</option>
-				<option value="MA">Massachusetts</option>
-				<option value="MI">Michigan</option>
-				<option value="MN">Minnesota</option>
-				<option value="MS">Mississippi</option>
-				<option value="MO">Missouri</option>
-				<option value="MT">Montana</option>
-				<option value="NE">Nebraska</option>
-				<option value="NV">Nevada</option>
-				<option value="NH">New Hampshire</option>
-				<option value="NJ">New Jersey</option>
-				<option value="NM">New Mexico</option>
-				<option value="NY">New York</option>
-				<option value="NC">North Carolina</option>
-				<option value="ND">North Dakota</option>
-				<option value="MP">Northern Mariana Islands</option>
-				<option value="OH">Ohio</option>
-				<option value="OK">Oklahoma</option>
-				<option value="OR">Oregon</option>
-				<option value="PA">Pennsylvania</option>
-				<option value="PR">Puerto Rico</option>
-				<option value="RI">Rhode Island</option>
-				<option value="SC">South Carolina</option>
-				<option value="SD">South Dakota</option>
-				<option value="TN">Tennessee</option>
-				<option value="TX">Texas</option>
-				<option value="UT">Utah</option>
-				<option value="VT">Vermont</option>
-				<option value="VI">Virgin Islands, U.S.</option>
-				<option value="VA">Virginia</option>
-				<option value="WA">Washington</option>
-				<option value="WV">West Virginia</option>
-				<option value="WI">Wisconsin</option>
-				<option value="WY">Wyoming</option>
-			</select>
-		</datalist>
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-		<div dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">dojox.mobile - form controls</h1>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">			
-				<table width="100%">
-					<tr>
-						<td><span class="bold">Button</span></td>
-						<td align="right"><button dojoType="dojox.mobile.Button">Help</button>
-							<input type="submit" class="mblBlueButton" dojoType="dojox.mobile.Button" value="Submit">
-							<button class="mblRedButton" dojoType="dojox.mobile.Button">Cancel</button></td>
-					</tr>
-				</table>
-			</div>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">			
-				<table width="100%">
-					<tr>
-						<td><span class="bold">CheckBox</span></td>
-						<td align="right"><label for="cbox">Click me</label><input type="checkbox" id="cbox" dojoType="dojox.mobile.CheckBox"></td>
-					</tr>
-					<tr>
-						<td><span class="bold">ToggleButton</span></td>
-						<td align="right"><button dojoType="dojox.mobile.ToggleButton">Toggle me</button></td>
-					</tr>
-					<tr>
-						<td><span class="bold">Switch</span></td>
-						<td align="right"><input type="checkbox" dojoType="dojox.mobile.Switch" value="on"></td>
-					</tr>
-				</table>
-			</div>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">			
-				<table width="100%">
-					<tr>
-						<td><span class="bold">Radio Button</span></td>
-						<td align="right"><input type="radio" id="rb1" dojoType="dojox.mobile.RadioButton" name="mobileRadio" value="Large" checked><label for="rb1">1</label>
-							<input type="radio" id="rb2" dojoType="dojox.mobile.RadioButton" name="mobileRadio" value="Medium"><label for="rb2">2</label>
-							<input type="radio" id="rb3" dojoType="dojox.mobile.RadioButton" name="mobileRadio" value="Small"><label for="rb3">3</label></td>
-					</tr>
-				</table>
-			</div>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">			
-				<table width="100%">
-					<tr>
-						<td><span class="bold">Slider</span></td>
-						<td align="right">
-							<table>
-								<tr>
-									<td>0</td>
-									<td><input id="sh" name="sh" dojoType="dojox.mobile.Slider" value="0" min="0" max="20" step="0.1" type="range" style="width:150px;"></td>
-									<td>20</td>
-								</tr>
-							</table>
-						</td>
-					</tr>
-				</table>
-			</div>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">			
-				<table width="100%">
-					<tr>
-						<td><span class="bold">ComboBox</span></td>
-						<td align="right"><input type="text" dojoType="dojox.mobile.ComboBox" data-dojo-props='value:"", list:"states"'></td>
-					</tr>
-					<tr>
-						<td valign="top"><span class="bold">TextArea</span></td>
-						<td align="right">
-							<textarea dojoType="dojox.mobile.TextArea" rows="3" cols="20">TextArea</textarea><br>
-							<textarea dojoType="dojox.mobile.ExpandingTextArea" rows="3" cols="20">ExpandingTextArea</textarea>
-						</td>
-					</tr>
-					<tr>
-						<td valign="top"><span class="bold">TextBox</span></td>
-						<td align="right"><input dojoType="dojox.mobile.TextBox" maxLength="9" selectOnClick="true" placeHolder="max 9 chars"></td>
-					</tr>
-				</table>
-			</div>
+	<script type="text/javascript">
+		require([
+			"dojox/mobile",
+			"dojox/mobile/parser",
+			"dojox/mobile/compat",
+			"dojox/mobile/Button",
+			"dojox/mobile/CheckBox",
+			"dojox/mobile/ComboBox",
+			"dojox/mobile/RadioButton",
+			"dojox/mobile/Slider",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/SearchBox",
+			"dojox/mobile/ExpandingTextArea",
+			"dojox/mobile/ToggleButton"
+		]);
+
+		myOnSearch = function(results, query, options){
+			if(results.length){
+				console.log('first paged result ' + (options.start+1) + ' of ' + results.total + ': label = ' + results[0].name + ', value = ' + results[0].value);
+				console.log('last paged result ' + (options.start+results.length) + ' of ' + results.total + ': label = ' + results[results.length-1].name + ', value = ' + results[results.length-1].value);
+			}else if(results.total == 0){
+				console.log('no matching results');
+			}
+			if((options.start+results.length) < results.total){
+				results.nextPage();
+			}
+		};
+	</script>
+	
+	<style>
+	.bold {
+		font-weight: bold;
+	}
+	.windows_theme .mblSlider {
+		margin: 0 15px;
+		width: 150px !important;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<datalist>
+		<select data-dojo-type="dijit.form.DataList" data-dojo-props='id:"states"' >
+			<option value="AL">Alabama</option>
+			<option value="AK">Alaska</option>
+			<option value="AS">American Samoa</option>
+			<option value="AZ">Arizona</option>
+			<option value="AR">Arkansas</option>
+			<option value="AE">Armed Forces Europe</option>
+			<option value="AP">Armed Forces Pacific</option>
+			<option value="AA">Armed Forces the Americas</option>
+			<option value="CA">California</option>
+			<option value="CO">Colorado</option>
+			<option value="CT">Connecticut</option>
+			<option value="DE">Delaware</option>
+			<option value="DC">District of Columbia</option>
+			<option value="FM">Federated States of Micronesia</option>
+			<option value="FL">Florida</option>
+			<option value="GA">Georgia</option>
+			<option value="GU">Guam</option>
+			<option value="HI">Hawaii</option>
+			<option value="ID">Idaho</option>
+			<option value="IL">Illinois</option>
+			<option value="IN">Indiana</option>
+			<option value="IA">Iowa</option>
+			<option value="KS">Kansas</option>
+			<option value="KY">Kentucky</option>
+			<option value="LA">Louisiana</option>
+			<option value="ME">Maine</option>
+			<option value="MH">Marshall Islands</option>
+			<option value="MD">Maryland</option>
+			<option value="MA">Massachusetts</option>
+			<option value="MI">Michigan</option>
+			<option value="MN">Minnesota</option>
+			<option value="MS">Mississippi</option>
+			<option value="MO">Missouri</option>
+			<option value="MT">Montana</option>
+			<option value="NE">Nebraska</option>
+			<option value="NV">Nevada</option>
+			<option value="NH">New Hampshire</option>
+			<option value="NJ">New Jersey</option>
+			<option value="NM">New Mexico</option>
+			<option value="NY">New York</option>
+			<option value="NC">North Carolina</option>
+			<option value="ND">North Dakota</option>
+			<option value="MP">Northern Mariana Islands</option>
+			<option value="OH">Ohio</option>
+			<option value="OK">Oklahoma</option>
+			<option value="OR">Oregon</option>
+			<option value="PA">Pennsylvania</option>
+			<option value="PR">Puerto Rico</option>
+			<option value="RI">Rhode Island</option>
+			<option value="SC">South Carolina</option>
+			<option value="SD">South Dakota</option>
+			<option value="TN">Tennessee</option>
+			<option value="TX">Texas</option>
+			<option value="UT">Utah</option>
+			<option value="VT">Vermont</option>
+			<option value="VI">Virgin Islands, U.S.</option>
+			<option value="VA">Virginia</option>
+			<option value="WA">Washington</option>
+			<option value="WV">West Virginia</option>
+			<option value="WI">Wisconsin</option>
+			<option value="WY">Wyoming</option>
+		</select>
+	</datalist>
+
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">dojox.mobile - form controls</h1>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<table style="width:100%">
+				<tr>
+					<td><span class="bold">Button</span></td>
+					<td style="text-align:right"><button data-dojo-type="dojox.mobile.Button">Help</button>
+						<input type="submit" class="mblBlueButton" data-dojo-type="dojox.mobile.Button" value="Submit">
+						<button class="mblRedButton" data-dojo-type="dojox.mobile.Button">Cancel</button></td>
+				</tr>
+			</table>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<table style="width:100%">
+				<tr>
+					<td><span class="bold">CheckBox</span></td>
+					<td style="text-align:right"><label for="cbox">Click me</label><input type="checkbox" id="cbox" data-dojo-type="dojox.mobile.CheckBox"></td>
+				</tr>
+				<tr>
+					<td><span class="bold">ToggleButton</span></td>
+					<td style="text-align:right"><button data-dojo-type="dojox.mobile.ToggleButton">Toggle me</button></td>
+				</tr>
+				<tr>
+					<td><span class="bold">Switch</span></td>
+					<td style="text-align:right"><input type="checkbox" data-dojo-type="dojox.mobile.Switch" value="on"></td>
+				</tr>
+			</table>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<table style="width:100%">
+				<tr>
+					<td><span class="bold">Radio Button</span></td>
+					<td style="text-align:right"><input type="radio" id="rb1" data-dojo-type="dojox.mobile.RadioButton" name="mobileRadio" value="Large" checked><label for="rb1">1</label>
+						<input type="radio" id="rb2" data-dojo-type="dojox.mobile.RadioButton" name="mobileRadio" value="Medium"><label for="rb2">2</label>
+						<input type="radio" id="rb3" data-dojo-type="dojox.mobile.RadioButton" name="mobileRadio" value="Small"><label for="rb3">3</label></td>
+				</tr>
+			</table>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<table style="width:100%">
+				<tr>
+					<td><span class="bold">Slider</span></td>
+					<td style="text-align:right">
+						<table>
+							<tr>
+								<td>0</td>
+								<td><input id="sh" name="sh" data-dojo-type="dojox.mobile.Slider" value="0" min="0" max="20" step="0.1" type="range" style="width:150px;"></td>
+								<td>20</td>
+							</tr>
+						</table>
+					</td>
+				</tr>
+			</table>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<table style="width:100%">
+				<tr>
+					<td><span class="bold">ComboBox</span></td>
+					<td style="text-align:right"><input type="text" data-dojo-type="dojox.mobile.ComboBox" data-dojo-props='value:"", list:"states"'></td>
+				</tr>
+				<tr>
+					<td style="vertical-align:top"><span class="bold">TextArea</span></td>
+					<td style="text-align:right">
+						<textarea data-dojo-type="dojox.mobile.TextArea" rows="3" cols="20">TextArea</textarea><br>
+						<textarea data-dojo-type="dojox.mobile.ExpandingTextArea" rows="3" cols="20">ExpandingTextArea</textarea>
+					</td>
+				</tr>
+				<tr>
+					<td style="vertical-align:top"><span class="bold">TextBox</span></td>
+					<td style="text-align:right"><input data-dojo-type="dojox.mobile.TextBox" intermediateChanges="true" maxLength="9" selectOnClick="true" placeHolder="max 9 chars" onChange="console.log('onChange fired with ' + arguments[0])"></td>
+				</tr>
+				<tr>
+					<td style="vertical-align:top"><span class="bold">SearchBox</span></td>
+					<td style="text-align:right"><input data-dojo-type="dojox.mobile.SearchBox" type="search" selectOnClick="true" placeHolder="Search" data-dojo-props='list:"states", pageSize:5, onSearch:myOnSearch'></td>
+				</tr>
+			</table>
 		</div>
-	</body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_FormLayout.html b/dojox/mobile/tests/test_FormLayout.html
new file mode 100644
index 0000000..abba120
--- /dev/null
+++ b/dojox/mobile/tests/test_FormLayout.html
@@ -0,0 +1,253 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport"
+		  content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Form Layout</title>
+
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+			data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile",
+			"dojox/mobile/parser",
+			"dojox/mobile/compat",
+			"dojox/mobile/Button",
+			"dojox/mobile/CheckBox",
+			"dojox/mobile/ComboBox",
+			"dojox/mobile/RadioButton",
+			"dojox/mobile/Slider",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/SearchBox",
+			"dojox/mobile/ExpandingTextArea",
+			"dojox/mobile/ToggleButton",
+			"dojox/mobile/FormLayout"
+		]);
+
+		myOnSearch = function (results, query, options) {
+			if (results.length) {
+				console.log('first paged result ' + (options.start + 1) + ' of ' + results.total + ': label = ' + results[0].name + ', value = ' + results[0].value);
+				console.log('last paged result ' + (options.start + results.length) + ' of ' + results.total + ': label = ' + results[results.length - 1].name + ', value = ' + results[results.length - 1].value);
+			} else if (results.total == 0) {
+				console.log('no matching results');
+			}
+			if ((options.start + results.length) < results.total) {
+				results.nextPage();
+			}
+		};
+	</script>
+</head>
+<body style="visibility:hidden;">
+<datalist>
+	<select data-dojo-type="dijit.form.DataList" data-dojo-props='id:"states"'>
+		<option value="AL">Alabama</option>
+		<option value="AK">Alaska</option>
+		<option value="AS">American Samoa</option>
+		<option value="AZ">Arizona</option>
+		<option value="AR">Arkansas</option>
+		<option value="AE">Armed Forces Europe</option>
+		<option value="AP">Armed Forces Pacific</option>
+		<option value="AA">Armed Forces the Americas</option>
+		<option value="CA">California</option>
+		<option value="CO">Colorado</option>
+		<option value="CT">Connecticut</option>
+		<option value="DE">Delaware</option>
+		<option value="DC">District of Columbia</option>
+		<option value="FM">Federated States of Micronesia</option>
+		<option value="FL">Florida</option>
+		<option value="GA">Georgia</option>
+		<option value="GU">Guam</option>
+		<option value="HI">Hawaii</option>
+		<option value="ID">Idaho</option>
+		<option value="IL">Illinois</option>
+		<option value="IN">Indiana</option>
+		<option value="IA">Iowa</option>
+		<option value="KS">Kansas</option>
+		<option value="KY">Kentucky</option>
+		<option value="LA">Louisiana</option>
+		<option value="ME">Maine</option>
+		<option value="MH">Marshall Islands</option>
+		<option value="MD">Maryland</option>
+		<option value="MA">Massachusetts</option>
+		<option value="MI">Michigan</option>
+		<option value="MN">Minnesota</option>
+		<option value="MS">Mississippi</option>
+		<option value="MO">Missouri</option>
+		<option value="MT">Montana</option>
+		<option value="NE">Nebraska</option>
+		<option value="NV">Nevada</option>
+		<option value="NH">New Hampshire</option>
+		<option value="NJ">New Jersey</option>
+		<option value="NM">New Mexico</option>
+		<option value="NY">New York</option>
+		<option value="NC">North Carolina</option>
+		<option value="ND">North Dakota</option>
+		<option value="MP">Northern Mariana Islands</option>
+		<option value="OH">Ohio</option>
+		<option value="OK">Oklahoma</option>
+		<option value="OR">Oregon</option>
+		<option value="PA">Pennsylvania</option>
+		<option value="PR">Puerto Rico</option>
+		<option value="RI">Rhode Island</option>
+		<option value="SC">South Carolina</option>
+		<option value="SD">South Dakota</option>
+		<option value="TN">Tennessee</option>
+		<option value="TX">Texas</option>
+		<option value="UT">Utah</option>
+		<option value="VT">Vermont</option>
+		<option value="VI">Virgin Islands, U.S.</option>
+		<option value="VA">Virginia</option>
+		<option value="WA">Washington</option>
+		<option value="WV">West Virginia</option>
+		<option value="WI">Wisconsin</option>
+		<option value="WY">Wyoming</option>
+	</select>
+</datalist>
+
+<div data-dojo-type="dojox.mobile.View">
+	<h1 data-dojo-type="dojox.mobile.Heading">Form Layout</h1>
+
+	<div data-dojo-type="dojox.mobile.RoundRect">
+		<div data-dojo-type="dojox.mobile.FormLayout" data-dojo-props="rightAlign: false, columns:'single'">
+			<div>
+				<label>Buttons</label>
+				<fieldset>
+					<button data-dojo-type="dojox.mobile.Button">Help</button>
+					<input type="submit" class="mblBlueButton" data-dojo-type="dojox.mobile.Button" value="Submit">
+					<button class="mblRedButton" data-dojo-type="dojox.mobile.Button">Cancel</button>
+				</fieldset>
+			</div>
+			<div>
+				<label>Checkbox</label>
+				<fieldset><input type="checkbox" data-dojo-type="dojox.mobile.CheckBox"><label>Click me</label>
+				</fieldset>
+			</div>
+			<div>
+				<label>Toggle Button</label>
+				<fieldset>
+					<button data-dojo-type="dojox.mobile.ToggleButton">Toggle me</button>
+				</fieldset>
+			</div>
+			<div>
+				<label>Switch</label>
+				<fieldset><input type="checkbox" data-dojo-type="dojox.mobile.Switch" value="on"></fieldset>
+			</div>
+			<div>
+				<label>Radio Button</label>
+				<fieldset>
+					<input type="radio" id="rb1" data-dojo-type="dojox.mobile.RadioButton" name="mobileRadio"
+						   value="Large" checked><label for="rb1">1</label>
+					<input type="radio" id="rb2" data-dojo-type="dojox.mobile.RadioButton" name="mobileRadio"
+						   value="Medium"><label for="rb2">2</label>
+					<input type="radio" id="rb3" data-dojo-type="dojox.mobile.RadioButton" name="mobileRadio"
+						   value="Small"><label for="rb3">3</label>
+				</fieldset>
+			</div>
+			<div>
+				<label>Slider</label>
+				<fieldset><input id="sh" name="shb" data-dojo-type="dojox.mobile.Slider" value="0" min="0" max="20"
+								 step="0.1" type="range" style="width:150px;"></fieldset>
+			</div>
+			<div>
+				<label>ComboBox</label>
+				<fieldset><input type="text" data-dojo-type="dojox.mobile.ComboBox"
+								 data-dojo-props='value:"", list:"states"'></fieldset>
+			</div>
+			<div>
+				<label>TextArea</span></label>
+				<fieldset>
+					<textarea data-dojo-type="dojox.mobile.TextArea" rows="3" cols="20">TextArea</textarea><br>
+					<textarea data-dojo-type="dojox.mobile.ExpandingTextArea" rows="3"
+							  cols="20">ExpandingTextArea</textarea>
+				</fieldset>
+			</div>
+			<div>
+				<label>TextBox</label>
+				<fieldset><input data-dojo-type="dojox.mobile.TextBox" intermediateChanges="true" maxLength="9"
+								 selectOnClick="true" placeHolder="max 9 chars"
+								 onChange="console.log('onChange fired with ' + arguments[0])"></fieldset>
+			</div>
+			<div>
+				<label>SearchBox</span></label>
+				<fieldset><input data-dojo-type="dojox.mobile.SearchBox" type="search" selectOnClick="true"
+								 placeHolder="Search" data-dojo-props='list:"states", pageSize:5, onSearch:myOnSearch'>
+				</fieldset>
+			</div>
+		</div>
+	</div>
+	<div data-dojo-type="dojox.mobile.RoundRect">
+		<div data-dojo-type="dojox.mobile.FormLayout" data-dojo-props="rightAlign: true">
+			<div>
+				<label>Button</label>
+				<fieldset>
+					<button data-dojo-type="dojox.mobile.Button">Help</button>
+					<input type="submit" class="mblBlueButton" data-dojo-type="dojox.mobile.Button" value="Submit">
+					<button class="mblRedButton" data-dojo-type="dojox.mobile.Button">Cancel</button>
+				</fieldset>
+			</div>
+			<div>
+				<label>Checkbox</label>
+				<fieldset><input type="checkbox" data-dojo-type="dojox.mobile.CheckBox"><label>Click me</label>
+				</fieldset>
+			</div>
+			<div>
+				<label>Toggle Button</label>
+				<fieldset>
+					<button data-dojo-type="dojox.mobile.ToggleButton">Toggle me</button>
+				</fieldset>
+			</div>
+			<div>
+				<label>Switch</label>
+				<fieldset><input type="checkbox" data-dojo-type="dojox.mobile.Switch" value="on"></fieldset>
+			</div>
+			<div>
+				<label>Radio Button</label>
+				<fieldset>
+					<input type="radio" id="rb1b" data-dojo-type="dojox.mobile.RadioButton" name="mobileRadio"
+						   value="Large" checked><label for="rb1b">1</label>
+					<input type="radio" id="rb2b" data-dojo-type="dojox.mobile.RadioButton" name="mobileRadio"
+						   value="Medium"><label for="rb2b">2</label>
+					<input type="radio" id="rb3b" data-dojo-type="dojox.mobile.RadioButton" name="mobileRadio"
+						   value="Small"><label for="rb3b">3</label>
+				</fieldset>
+			</div>
+			<div>
+				<label>Slider</label>
+				<fieldset><input id="shb" name="shb" data-dojo-type="dojox.mobile.Slider" value="0" min="0" max="20"
+								 step="0.1" type="range" style="width:150px;"></fieldset>
+			</div>
+			<div>
+				<label>ComboBox</label>
+				<fieldset><input type="text" data-dojo-type="dojox.mobile.ComboBox"
+								 data-dojo-props='value:"", list:"states"'></fieldset>
+			</div>
+			<div>
+				<label>TextArea</span></label>
+				<fieldset>
+					<textarea data-dojo-type="dojox.mobile.TextArea" style="margin-right: 0" rows="3"
+							  cols="20">TextArea</textarea><br>
+					<textarea data-dojo-type="dojox.mobile.ExpandingTextArea" rows="3"
+							  cols="20">ExpandingTextArea</textarea>
+				</fieldset>
+			</div>
+			<div>
+				<label>TextBox</label>
+				<fieldset><input type="text" data-dojo-type="dojox.mobile.TextBox" intermediateChanges="true"
+								 maxLength="9" selectOnClick="true" placeHolder="max 9 chars"
+								 onChange="console.log('onChange fired with ' + arguments[0])"></fieldset>
+			</div>
+			<div>
+				<label>SearchBox</span></label>
+				<fieldset><input data-dojo-type="dojox.mobile.SearchBox" type="search" selectOnClick="true"
+								 placeHolder="Search" data-dojo-props='list:"states", pageSize:5, onSearch:myOnSearch'>
+				</fieldset>
+			</div>
+		</div>
+	</div>
+</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_GridLayout-2cols.html b/dojox/mobile/tests/test_GridLayout-2cols.html
new file mode 100644
index 0000000..45f0b47
--- /dev/null
+++ b/dojox/mobile/tests/test_GridLayout-2cols.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>GridLayout</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Button','GridLayout']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/GridLayout",
+			"dojox/mobile/Pane",
+			"dojox/mobile/Button"
+		]);
+	</script>
+	<style>
+		.mblButton {
+			width: 100%;
+			height: 100%;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.GridLayout" data-dojo-props='cols:2' style="height: 200px;">
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 1</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 2</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 3</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 4</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 5</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 6</button></div>
+		</div>
+	</div>
+</body>
+</html>
+
diff --git a/dojox/mobile/tests/test_GridLayout-3cols.html b/dojox/mobile/tests/test_GridLayout-3cols.html
new file mode 100644
index 0000000..879f2c9
--- /dev/null
+++ b/dojox/mobile/tests/test_GridLayout-3cols.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>GridLayout</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Button','GridLayout']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/GridLayout",
+			"dojox/mobile/Pane",
+			"dojox/mobile/Button"
+		]);
+	</script>
+	<style>
+		.mblButton {
+			width: 100%;
+			height: 100%;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.GridLayout" data-dojo-props='cols:3' style="height: 200px;">
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 1</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 2</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 3</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 4</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 5</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 6</button></div>
+		</div>
+	</div>
+</body>
+</html>
+
diff --git a/dojox/mobile/tests/test_GridLayout-change.html b/dojox/mobile/tests/test_GridLayout-change.html
new file mode 100644
index 0000000..d78f0b8
--- /dev/null
+++ b/dojox/mobile/tests/test_GridLayout-change.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>GridLayout</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Button','GridLayout']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/GridLayout",
+			"dojox/mobile/Pane",
+			"dojox/mobile/Button"
+		]);
+	</script>
+	<style>
+		.mblButton {
+			width: 150px;
+			height: 100px;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.GridLayout">
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 1</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 2</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 3</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 4</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 5</button></div>
+			<div data-dojo-type="dojox.mobile.Pane"><button class="mblBlueButton" data-dojo-type="dojox.mobile.Button">Button 6</button></div>
+		</div>
+	</div>
+</body>
+</html>
+
diff --git a/dojox/mobile/tests/test_GridLayout-demo.html b/dojox/mobile/tests/test_GridLayout-demo.html
new file mode 100644
index 0000000..b824262
--- /dev/null
+++ b/dojox/mobile/tests/test_GridLayout-demo.html
@@ -0,0 +1,220 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>GridLayout</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Button','EdgeToEdgeCategory','GridLayout','dojox/mobile/themes/common/domButtons.css']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/TransitionEvent",
+			"dojox/mobile/iconUtils",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/GridLayout",
+			"dojox/mobile/Pane",
+			"dojox/mobile/Button",
+			"dojox/mobile/EdgeToEdgeCategory",
+			"dojox/mobile/TextBox"
+		], function(connect, dom, ready, registry, TransitionEvent, iconUtils){
+			ready(function(){
+				iconUtils.createDomButton(dom.byId("Minus"));
+				iconUtils.createDomButton(dom.byId("Plus"));
+			});
+
+			goToSubMenu = function(id){
+				var widget = registry.byId("pane1");
+				var opts = {moveTo: "view2", transition: "slide", transitionDir: 1};
+				var ev = new TransitionEvent(widget.domNode, opts);
+				ev.dispatch()
+			};
+
+			goToOrder = function(id){
+				var widget = registry.byId("pane2-1");
+				var opts = {moveTo: "view3", transition: "slide", transitionDir: 1};
+				var ev = new TransitionEvent(widget.domNode, opts);
+				ev.dispatch()
+			};
+
+
+			plus = function(){
+				var widget = registry.byId("num");
+				valueInt = parseInt(widget.textbox.value);
+				valueInt = isNaN(valueInt) ? 0 : valueInt + 1;
+				widget.textbox.value = valueInt.toString()
+			};
+
+			minus = function(){
+				var widget = registry.byId("num");
+				valueInt = parseInt(widget.textbox.value);
+				valueInt = isNaN(valueInt) || valueInt <=0 ? 0 : valueInt - 1;
+				widget.textbox.value = valueInt.toString()
+			};
+			
+			cancel = function(){
+				var widget = registry.byId("cancel");
+				var opts = {moveTo: "view2", transition: "slide", transitionDir: -1};
+				var ev = new TransitionEvent(widget.domNode, opts);
+				ev.dispatch()
+			};
+
+			ok = function(){
+				var widget = registry.byId("ok");
+				var opts = {moveTo: "view1", transition: "fade", transitionDir: -1};
+				var ev = new TransitionEvent(widget.domNode, opts);
+				ev.dispatch()
+			}
+			
+		});
+	</script>
+	<style>
+		.myPane {
+			width: 100%;
+			height: 50px;
+		}
+		.line {
+			margin: 0;
+			position:relative;
+			border: 1px groove white;
+			width: 100%;
+			height: 100%;
+		}
+		.myIcon {
+			margin-top:28px;
+			margin-left:2px;
+			border-radius: 10px;
+			width:50px;
+			height:42px;
+			float:left;
+		}
+		.price {
+			float:right;
+			border-radius: 4px;
+			margin-top:0px;
+			margin-right:3px;
+			border: 2px groove #959da0;
+			padding: 0px 7px 0px 5px;
+			background-image: -webkit-gradient(linear, left top, left bottom, from(#959da0), to(#515761));
+			color: white;
+			font-size: 18px;
+		}
+		.OrderItem {
+			margin-top:15px;
+			margin-left:3px;
+			font-size: 18px;
+		}
+		.SubCategory {
+			margin-top:38px;
+			margin-left:55px;
+			font-size: 24px;
+		}
+		.Discription {
+			margin-top:17px;
+			margin-left:13px;
+			font-size: 18px;
+		}
+		.mybutton {
+			margin-top:30px;
+			margin-left:15%;
+			margin-right:15%;
+			width:70%;
+		}
+		.title {
+			color:white;
+			font-style:italic;
+			text-shadow:0px -1px 10px blue,1px 0px 10px blue,0px 1px 10px blue,-1px 0px 10px blue;
+			font-size:50px;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.GridLayout" data-dojo-props='cols:1' style="height:600px;">
+			<div data-dojo-type="dojox.mobile.Pane" style="width:100%;position:relative">
+				<img alt="" src='images/Mountain.jpg' style="width:100%;height:100%"/>
+				<div style="position:absolute;top:40%;left:10%;" class="title">Airport lounge <br>cafe</div>
+			</div>
+			<div data-dojo-type="dojox.mobile.GridLayout" data-dojo-props='cols:2' style="height: 300px;">
+				<div id="pane1" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToSubMenu(1)">
+					<div class="line"><img alt="" src='images/menu1.jpg' class="myIcon"/><div class="SubCategory">Caff</div></div>
+				</div>
+				<div id="pane2" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToSubMenu(2)">
+					<div class="line"><img alt="" src='images/menu2.jpg' class="myIcon"/><div class="SubCategory">Bakery</div></div>
+				</div>
+				<div id="pane3" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToSubMenu(3)">
+					<div class="line"><img alt="" src='images/menu3.jpg' class="myIcon"/><div class="SubCategory">Tea</div></div>
+				</div>
+				<div id="pane4" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToSubMenu(4)">
+					<div class="line"><img alt="" src='images/menu4.jpg' class="myIcon"/><div class="SubCategory">Cake</div></div>
+				</div>
+				<div id="pane5" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToSubMenu(5)">
+					<div class="line"><img alt="" src='images/menu5.jpg' class="myIcon"/><div class="SubCategory">Beverage</div></div>
+				</div>
+				<div id="pane6" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToSubMenu(6)">
+					<div class="line"><img alt="" src='images/menu6.jpg' class="myIcon"/><div class="SubCategory">Icecream</div></div>
+				</div>
+			</div>
+		</div>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view1"'></div>
+			<div data-dojo-type="dojox.mobile.GridLayout" data-dojo-props='cols:2' style="height: 300px;">
+				<div id="pane2-1" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToOrder(1)">
+					<div class="line"><div class="Discription">Coffee<div class="price">4.00</div></div></div>
+				</div>
+				<div id="pane2-2" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToOrder(2)">
+					<div class="line"><div class="Discription">Cappuccino<div class="price">5.00</div></div></div>
+				</div>
+				<div id="pane2-3" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToOrder(3)">
+					<div class="line"><div class="Discription">Cafe' au lait<div class="price">5.00</div></div></div>
+				</div>
+				<div id="pane2-4" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToOrder(4)">
+					<div class="line"><div class="Discription">Espresso<div class="price">4.00</div></div></div>
+				</div>
+				<div id="pane2-5" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToOrder(5)">
+					<div class="line"><div class="Discription">Ice Coffee<div class="price">4.00</div></div></div>
+				</div>
+				<div id="pane2-6" data-dojo-type="dojox.mobile.Pane" class="myPane" onclick="goToOrder(6)">
+					<div class="line"><div class="Discription">Ice Cafe' au lait<div class="price">5.00</div></div></div>
+				</div>
+			</div>
+	</div>
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.GridLayout" data-dojo-props='cols:2'>
+			<div data-dojo-type="dojox.mobile.Pane">
+				<div data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Order</div>
+				<div id="pane7" style="width:100%;height:50px;position:relative"">
+					<div class="line"><div class="OrderItem"><span id="OrderItem">Espresso<span><div id="OrderPrice" class="price">5.00</div></div></div>
+				</div>
+			</div>
+			<div data-dojo-type="dojox.mobile.Pane">
+				<div data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Count</div>
+
+				<table style="position:relative;width:100%">
+					<tr>
+						<td><input id="num" data-dojo-type="dojox.mobile.TextBox" data-dojo-props='value:1, placeHolder:"Count", size:3' style="width:80%;height:40px;text-align:right;font-size: 18px;"></td>
+						<td><div id ="Plus" class="mblDomButtonBluePlus" onclick="plus()" style="margin:0 auto 0 auto;"></div></td>
+						<td><div id ="Minus" class="mblDomButtonBlueMinus" onclick="minus()" style="margin:0 auto 0 auto;"></div></td>
+					</tr>
+				</table>
+			</div>
+			<div data-dojo-type="dojox.mobile.Pane">
+				<button id ="cancel"  data-dojo-type="dojox.mobile.Button" class="mblRedButton" onclick="cancel()" style="margin-top:10px;margin-left:5%;margin-right:5%;width:90%;height:40px;">Cancel</button>
+			</div>
+			<div data-dojo-type="dojox.mobile.Pane">
+				<button id="ok" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="ok()" style="margin-top:10px;margin-left:5%;margin-right:5%;width:90%;height:40px;">OK</button>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Heading.html b/dojox/mobile/tests/test_Heading.html
new file mode 100644
index 0000000..29f3fb1
--- /dev/null
+++ b/dojox/mobile/tests/test_Heading.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Heading</title>
+
+	<script type="text/javascript" src="../deviceTheme.js"
+		data-dojo-config="mblThemeFiles: ['base','TabBar','dojox/mobile/themes/common/domButtons.css']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TabBar"
+		], function(ready, registry){
+			ready(function(){
+				var btn1 = registry.byId("btn1");
+				btn1.connect(btn1, "onClick", function(){
+					console.log(this.label + " button was clicked");
+				});
+			});
+		});
+	</script>
+
+<style>
+	.mblColorPink {
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#ff9DE9), to(#cc62DD), color-stop(0.5, #ff6EDF), color-stop(0.5, #ff5FDC));
+		background-image: -moz-linear-gradient(top, #ff9DE9 0%, #ff6EDF 50%, #ff5FDC 50%, #cc62DD 100%);
+		background-color: pink;
+	}
+	
+	.mblColorPink45 {
+		background-image: -webkit-gradient(linear, left top, right bottom, from(#ff9DE9), to(#cc62DD), color-stop(0.5, #ff6EDF), color-stop(0.5, #ff5FDC));
+		background-image: -moz-linear-gradient(top left, #ff9DE9 0%, #ff6EDF 50%, #ff5FDC 50%, #cc62DD 100%);
+		background-color: pink;
+	}	
+</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Arrow"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" arrow="left" defaultColor="mblColorBlue" selColor="mblColorPink">MMMM</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props=''>MMMM</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='arrow:"right"'>MMMM</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props=''>MMMM</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"></span>
+
+	</div><br>
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Labeled Icon"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus",label:"DOM"'></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"images/tab-icon-33w.png",label:"Image"'></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"images/tab-icons.png",iconPos:"29,116,29,29",label:"Sprite"'></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"></span>
+
+	</div><br>
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Fixed Width"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus",label:"DOM"' style="width:120px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"images/tab-icon-33w.png",label:"Image"' style="width:120px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"images/tab-icons.png",iconPos:"29,116,29,29",label:"Sprite"' style="width:120px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"></span>
+
+	</div><br>
+
+	<div id="general" data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Settings", moveTo:"settings", label:"General"'>
+		    <div style="float:right; display:none;"></div>
+		</div>
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Long Button", moveTo:"settings"'>Very Very Long Title May Not Be Displayed in the Narrow Space - Very Very Long Title May Not Be Displayed in the Narrow Space</div>
+	</div>
+
+	<h3>Heading with buttons</h3>
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"World Clock"'>
+		<span id="btn1" data-dojo-type="dojox.mobile.ToolBarButton">Edit</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;" onclick="console.log('+ was clicked')"></span>
+
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+		<span data-dojo-type="dojox.mobile.ToolBarButton">Edit</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"></span>
+		Alarm Clock
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Voice Memos"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"Speaker"'></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"Done"' defaultColor="mblColorBlue" style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Updates"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"Update All"' style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"News", back:"Bookmarks", moveTo:"bookmarks"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"Done"' defaultColor="mblColorBlue" style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"Done"' defaultColor="mblColorBlue"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='label:"New Folder"' style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='toggle:true'>New</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='toggle:true'>Toggle</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"images/tab-icon-18h.png", moveTo:"view3"' style="padding:0 10px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"images/tab-icons.png", iconPos:"29,0,29,29", moveTo:"view3"' style="padding:0 10px"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus", moveTo:"view3"' style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" style="width:80px" data-dojo-props='selected:true'>Catalog</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" style="width:80px">Share</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" style="width:80px">Download</li>
+		</ul>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhiteSearch"' style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+	  <table cellpadding="0" cellspacing="0" style="width:100%;"><tr>
+		<td><span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus"'></span></td>
+        <td align="center"><table cellpadding="0" cellspacing="0"><tr>
+		<td align="center"><div data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"' style="margin:auto;">
+			<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true' style="width:80px">Search</div>
+			<div data-dojo-type="dojox.mobile.TabBarButton" style="width:80px">Directions</div>
+		</div></td>
+		</tr></table></td>
+		<td align="right"><span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"images/tab-icon-15h.png"' style="float:right;"></span></td>
+	  </tr></table>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+	  <table cellpadding="0" cellspacing="0" align="center"><tr>
+		<td align="center"><div data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"' style="margin:auto;">
+			<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true' style="width:80px">Search</div>
+			<div data-dojo-type="dojox.mobile.TabBarButton" style="width:80px">Directions</div>
+		</div></td>
+	  </tr></table>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading">
+	  <table cellpadding="0" cellspacing="0" align="right"><tr>
+		<td align="center"><div data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"' style="margin:auto;">
+			<div data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true' style="width:80px">Search</div>
+			<div data-dojo-type="dojox.mobile.TabBarButton" style="width:80px">Directions</div>
+		</div></td>
+	  </tr></table>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Inbox", label:"1 of 10"'>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", selectOne:false' style="float:right;">
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon:"mblDomButtonWhiteUpArrow"'></li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon:"mblDomButtonWhiteDownArrow"'></li>
+		</ul>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", label:"Inbox(32)"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhiteSearch"' style="float:right;"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhiteUpArrow"' style="float:right;"></span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhiteDownArrow"' style="float:right;"></span>
+	</div><br>
+
+
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Inbox", label:"1 of 10"'>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", selectOne:false' style="float:right;">
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon:"mblDomButtonWhiteUpArrow"'></li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon:"mblDomButtonWhiteSearch"'></li>
+		</ul>
+	</div><br>
+	
+	<!-- Test cases for #16771 -->
+	<!-- a) With arrow but no label (nor icon) -->
+	<h1 dojoType="dojox.mobile.Heading"
+		data-dojo-props="label: 'ToolBarButon with left arrow and no label'">
+		<span data-dojo-type="dojox.mobile.ToolBarButton"
+			data-dojo-props="arrow: 'left'"/>
+	</h1><br>
+		
+	<h1 dojoType="dojox.mobile.Heading"
+		data-dojo-props="label: 'ToolBarButon with right arrow and no label'">
+		<span data-dojo-type="dojox.mobile.ToolBarButton"
+			data-dojo-props="arrow: 'right'"/>
+	</h1><br>
+		
+	<!-- b) With arrow, icon and label -->
+	<div data-dojo-type="dojox.mobile.Heading"
+		data-dojo-props="label: 'ToolBarButon with left arrow, icon and label'">
+		<span data-dojo-type="dojox.mobile.ToolBarButton"
+			data-dojo-props="arrow: 'left', icon: 'mblDomButtonWhiteDownArrow', label: 'some label'"/>
+	</div><br>
+			
+	<div data-dojo-type="dojox.mobile.Heading"
+		data-dojo-props="label: 'ToolBarButon with right arrow, icon and label'">
+		<span data-dojo-type="dojox.mobile.ToolBarButton"
+			data-dojo-props="arrow: 'right', icon: 'mblDomButtonWhiteDownArrow', label: 'some label'"/>
+	</div><br>
+	<!-- End of test cases for #16771 -->
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Icon.html b/dojox/mobile/tests/test_Icon.html
new file mode 100644
index 0000000..5a54349
--- /dev/null
+++ b/dojox/mobile/tests/test_Icon.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>domButtons</title>
+
+	<script type="text/javascript" src="../deviceTheme.js"
+		data-dojo-config="mblThemeFiles: ['base','dojox/mobile/themes/common/domButtons.css']"></script>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dojox/mobile/Icon",
+			"dojox/mobile/parser",
+			"dojox/mobile/compat"
+		], function(ready, Icon){
+			ready(function(){
+				// online (=connected to the document) instantiation
+				var icon1 = new Icon({icon:"images/tab-icon-23h.png"}, document.getElementById("icon1"));
+				var icon2 = new Icon({icon:"images/tab-icons.png",iconPos:"29,116,29,29"}, document.getElementById("icon2"));
+				var icon3 = new Icon({icon:"mblDomButtonBlueCircleArrow"}, document.getElementById("icon3"));
+
+				// offline (=disconnected to the document) instantiation
+				var icon4 = new Icon({icon:"images/tab-icon-23h.png"});
+				document.body.appendChild(icon4.domNode);
+				var icon5 = new Icon({icon:"images/tab-icons.png",iconPos:"29,116,29,29"});
+				document.body.appendChild(icon5.domNode);
+				var icon6 = new Icon({icon:"mblDomButtonBlueCircleArrow"});
+				document.body.appendChild(icon6.domNode);
+			});
+		});
+	</script>
+</head>
+<body>
+  markup:
+  <div data-dojo-type="dojox.mobile.Icon" data-dojo-props='icon:"images/tab-icon-23h.png"'></div>
+  <div data-dojo-type="dojox.mobile.Icon" data-dojo-props='icon:"images/tab-icons.png",iconPos:"29,116,29,29"'></div>
+  <div data-dojo-type="dojox.mobile.Icon" data-dojo-props='icon:"mblDomButtonBlueCircleArrow"'></div>
+  <hr>online:
+  <div id="icon1"></div>
+  <div id="icon2"></div>
+  <div id="icon3"></div>
+  <hr>offline:
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-badge.html b/dojox/mobile/tests/test_IconContainer-badge.html
new file mode 100644
index 0000000..a40a1e4
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-badge.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Icon (badge)</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		], function(dom, registry){
+			test = function(i){
+				var w = registry.byId("icon"+i);
+				var badgeVal = w.get("badge");
+				var val = dom.byId("val").value || "0";
+				w.set("badge", badgeVal ? null : val);
+			}
+		});
+	</script>
+
+	<style>
+		.label {
+			font-family: "Helvetica Neue", Helvetica;
+			font-size: 13px;
+			margin-top: 20px;
+		}
+		.view {
+			font-size: 30px;
+			padding-top: 30px;
+			text-align: center;
+		}
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon (Badge)</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li id="icon0" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"images/icon-1.png", lazy:true, badge:"55"'><div class="box"></div></li>
+			<li id="icon1" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li id="icon2" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li id="icon3" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+			<li id="icon4" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"images/icon-1.png", href:"test_RoundRectList.html", transition:"slide"'></li>
+			<li id="icon5" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url", icon:"images/icon-1.png", url:"data/view-sample.html", transition:"slide"'></li>
+			<li id="icon6" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url-async", icon:"images/icon-1.png", url:"data/view-sample.html", transition:"slide", sync:false'></li>
+		</ul>
+		<div style="margin-bottom:10px;">Badge value: <input id="val" type="text" value="25"></div>
+		<input type="button" onclick="test(0)" value="app1">
+		<input type="button" onclick="test(1)" value="app2">
+		<input type="button" onclick="test(2)" value="app3">
+		<input type="button" onclick="test(3)" value="moveTo">
+		<input type="button" onclick="test(4)" value="href">
+		<input type="button" onclick="test(5)" value="url">
+		<input type="button" onclick="test(6)" value="url-async">
+	</div>
+
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Icon Container", moveTo:"view1"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-connect.html b/dojox/mobile/tests/test_IconContainer-connect.html
new file mode 100644
index 0000000..cec3afb
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-connect.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Editable Icon Container (Connect)</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView"
+		], function(connect, dom, ready, registry){
+			startEdit = function(){
+				registry.byId("iconContainer").startEdit();
+			}
+			endEdit = function(){
+				registry.byId("iconContainer").endEdit();
+			}			
+			ready(function(){
+				var msgArea = dom.byId("msgArea");
+				var ic = registry.byId("iconContainer");
+				connect.connect(ic, "onStartEdit", null, function(){
+					msgArea.innerHTML = "StartEdit";
+					dom.byId("btn1").style.display = "none";
+					dom.byId("btn2").style.display = "";				
+				});
+				connect.connect(ic, "onEndEdit", null, function(){
+					msgArea.innerHTML = "EndEdit";
+					dom.byId("btn1").style.display = "";
+					dom.byId("btn2").style.display = "none";				
+				});
+				connect.connect(ic, "onDeleteItem", null, function(widget){
+					msgArea.innerHTML = "DeleteIconItem: " + widget.label;
+				});
+				connect.connect(ic, "onMoveItem", null, function(widget, from, to){
+					msgArea.innerHTML = "MoveIconItem: " + widget.label + " (" + from + " -> " + to + ")";
+				});
+			});
+		});
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Editable Icon Container (Connect)</h1>
+		<ul id="iconContainer" data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='editable:true'>
+			<li id="icon1" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"images/icon1.png", lazy:true, badge:"55"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"images/icon2.png", lazy:true, deletable:false'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"images/icon3.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app4", icon:"images/icon4.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app5", icon:"images/icon5.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app6", icon:"images/icon6.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app7", icon:"images/icon7.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app8", icon:"images/icon8.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app9", icon:"images/icon9.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app10", icon:"images/icon10.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"images/icon1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"images/icon2.png", href:"test_RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url", icon:"images/icon3.png", url:"data/view-sample.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url-async", icon:"images/icon4.png", url:"data/view-sample.html", transition:"slide", sync:false'></li>
+		</ul>
+		<button id="btn1" onclick="startEdit();">Start Edit</button>
+		<button id="btn2" onclick="endEdit();" style="display:none;">End Edit</button>
+		<div id="msgArea" style="margin-top:10px; margin-left:10px;"></div>
+	</div>
+	
+	<div id="dlg_confirm" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div class="mblSimpleDialogTitle">Delete Confirmation</div>
+		<div id="dlg_txt" class="mblSimpleDialogText">Are you sure you want to delete this app?</div>
+		<button id="dlg_btn1" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:60px;">Delete</button>
+		<button id="dlg_btn2" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:60px;">Cancel</button>
+	</div>
+	
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Icon Container", moveTo:"view1"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-editable-a11y.html b/dojox/mobile/tests/test_IconContainer-editable-a11y.html
new file mode 100644
index 0000000..c7c2096
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-editable-a11y.html
@@ -0,0 +1,120 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Editable Icon Container</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/dom-construct",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/ScrollableView"
+		], function(connect, dom, domConstruct, ready, registry){
+			function onKeydown(e){
+				if(e.keyCode == 39 && e.shiftKey){ // right
+					var item = registry.getEnclosingWidget(e.target);
+					var next = item.getNextSibling();
+					if(next){
+						domConstruct.place(item.domNode, next.domNode, "after");
+						item.domNode.focus();
+					}
+				}else if(e.keyCode == 37 && e.shiftKey){ // left
+					var item = registry.getEnclosingWidget(e.target);
+					var prev = item.getPreviousSibling();
+					if(prev){
+						domConstruct.place(item.domNode, prev.domNode, "before");
+						item.domNode.focus();
+					}
+				}else if(e.keyCode == 46){ // Delete
+					var item = registry.getEnclosingWidget(e.target);
+					if(item.deletable){
+						widget.deleteItem(item);
+					}
+				}
+			}
+			startEdit = function(){
+				widget.startEdit();
+			}
+			endEdit = function(){
+				widget.endEdit();
+			}			
+			ready(function(){
+				widget = registry.byId("iconContainer"); // IconContainer widget
+				connect.connect(widget, "onStartEdit", function(){
+					dom.byId("btn1").style.display = "none";
+					dom.byId("btn2").style.display = "";
+					keyHandler = connect.connect(widget.domNode, "onkeydown", onKeydown);
+				});
+				dojo.connect(widget, "onEndEdit", function(){
+					dom.byId("btn1").style.display = "";
+					dom.byId("btn2").style.display = "none";
+					connect.disconnect(keyHandler);
+				});				
+			});
+		});
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Editable Icon Container</h1>
+		<ul id="iconContainer" data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='editable:true, deleteIconTitle:"delete", deleteIconRole:"button"'>
+			<li id="icon1" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"images/icon1.png", badge:"55"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"images/icon2.png", deletable:false'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"images/icon3.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app4", icon:"images/icon4.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app5", icon:"images/icon5.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app6", icon:"images/icon6.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app7", icon:"images/icon7.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app8", icon:"images/icon8.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app9", icon:"images/icon9.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app10", icon:"images/icon10.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"images/icon1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"images/icon2.png", href:"test_RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url", icon:"images/icon3.png", url:"data/view-sample.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url-async", icon:"images/icon4.png", url:"data/view-sample.html", transition:"slide", sync:false'></li>
+		</ul>
+		<button id="btn1" onclick="startEdit();">Start Edit</button>
+		<button id="btn2" onclick="endEdit();" style="display:none;">End Edit</button>
+	</div>
+
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Icon Container", moveTo:"view1"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-editable.html b/dojox/mobile/tests/test_IconContainer-editable.html
new file mode 100644
index 0000000..c94d7be
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-editable.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Editable Icon Container</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/ScrollableView"
+		], function(connect, dom, ready, registry){
+			startEdit = function(){
+				registry.byId("iconContainer").startEdit();
+			}
+			endEdit = function(){
+				registry.byId("iconContainer").endEdit();
+			}			
+			ready(function(){
+				connect.connect(registry.byId("iconContainer"), "onStartEdit", function(){
+					dom.byId("btn1").style.display = "none";
+					dom.byId("btn2").style.display = "";				
+				});
+				dojo.connect(registry.byId("iconContainer"), "onEndEdit", function(){
+					dom.byId("btn1").style.display = "";
+					dom.byId("btn2").style.display = "none";				
+				});				
+			});
+		});
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Editable Icon Container</h1>
+		<ul id="iconContainer" data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='editable:true'>
+			<li id="icon1" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"images/icon1.png", badge:"55"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"images/icon2.png", deletable:false'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"images/icon3.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app4", icon:"images/icon4.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app5", icon:"images/icon5.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app6", icon:"images/icon6.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app7", icon:"images/icon7.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app8", icon:"images/icon8.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app9", icon:"images/icon9.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app10", icon:"images/icon10.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"images/icon1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"images/icon2.png", href:"test_RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url", icon:"images/icon3.png", url:"data/view-sample.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url-async", icon:"images/icon4.png", url:"data/view-sample.html", transition:"slide", sync:false'></li>
+		</ul>
+		<button id="btn1" onclick="startEdit();">Start Edit</button>
+		<button id="btn2" onclick="endEdit();" style="display:none;">End Edit</button>
+	</div>
+
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Icon Container", moveTo:"view1"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-highlight.html b/dojox/mobile/tests/test_IconContainer-highlight.html
new file mode 100644
index 0000000..cfcadc8
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-highlight.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Icon (Highlight)</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/ScrollableView"
+		], function(dom, registry){
+			highlight = function(i){
+				var w = registry.byId("icon"+i);
+				w.unhighlight();
+				w.highlight(dom.byId("val").value);
+			}
+		});
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon (Highlight)</h1>
+		<ul id="iconContainer" data-dojo-type="dojox.mobile.IconContainer">
+			<li id="icon0" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"images/icon-1.png", lazy:true, badge:"55"'><div class="box"></div></li>
+			<li id="icon1" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li id="icon2" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li id="icon3" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+			<li id="icon4" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"images/icon-1.png", href:"test_RoundRectList.html", transition:"slide"'></li>
+			<li id="icon5" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url", icon:"images/icon-1.png", url:"data/view-sample.html", transition:"slide"'></li>
+			<li id="icon6" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url-async", icon:"images/icon-1.png", url:"data/view-sample.html", transition:"slide", sync:false'></li>
+		</ul>
+		<div style="margin-bottom:10px;">Duration (second): <input id="val" type="text" value="2"></div>
+		<input type="button" onclick="highlight(0)" value="app1">
+		<input type="button" onclick="highlight(1)" value="app2">
+		<input type="button" onclick="highlight(2)" value="app3">
+		<input type="button" onclick="highlight(3)" value="moveTo">
+		<input type="button" onclick="highlight(4)" value="href">
+		<input type="button" onclick="highlight(5)" value="url">
+		<input type="button" onclick="highlight(6)" value="url-async">
+	</div>
+
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Icon Container", moveTo:"view1"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-multi.html b/dojox/mobile/tests/test_IconContainer-multi.html
new file mode 100644
index 0000000..c1d9d42
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-multi.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Icon Container (Multi - NewPane)</title>
+
+	<link href="../themes/common/dijit/dijit.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer','dijit.Calendar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container (Multi - NewPane)</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='transition:"flip"'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Calendar", icon:"images/icon-1.png"' lazy="true">
+				<div id="cal" data-dojo-type="dijit.CalendarLite"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Color Palette", icon:"images/icon-1.png"' lazy="true">
+				<div data-dojo-type="dijit.ColorPalette"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Progress Bar", icon:"images/icon-1.png"' lazy="true">
+				<div data-dojo-type="dijit.ProgressBar"></div>
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-prog.html b/dojox/mobile/tests/test_IconContainer-prog.html
new file mode 100644
index 0000000..f14b391
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-prog.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Dynamic Icons</title>
+
+	<link href="../../../dijit/themes/tundra/tundra.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Button','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: false, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/IconItem",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/Button",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, dom, ready, registry, IconItem){
+			ready(function(){
+				var iconContainer = registry.byId("ic1");
+				addIcon = function(e){
+					var item = new IconItem({
+						icon: "images/icon-1.png",
+						label: dom.byId("label").value || "new icon",
+						lazy: true
+					});
+					var s = dom.byId("addIndex").value;
+					var index = s ? s - 0 : undefined;
+					iconContainer.addChild(item, index);
+					item.containerNode.innerHTML = "<div data-dojo-type='dijit._Calendar'></div>";
+				};
+				removeIcon = function(e){
+					var index = dom.byId("removeIndex").value - 0;
+					iconContainer.removeChild(index);
+				};
+				openIcon = function(e){
+					var index = dom.byId("openIndex").value - 0;
+					iconContainer.getChildren()[index].open();
+				};
+				closeIcon = function(e){
+					var index = dom.byId("closeIndex").value - 0;
+					iconContainer.getChildren()[index].close();
+				};
+				closeAll = function(e){
+					iconContainer.closeAll();
+				};
+			});
+		});
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;" class="tundra">
+	<div id="myhome" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<table>
+			<tr><td><input type="button" onclick="addIcon()" value="Add" style="width:70px"></td><td> index:<input id="addIndex" style="width:20px;text-align:right"></td><td> label:<input id="label" value="new icon" style="width:80px"></td>
+			<tr><td><input type="button" onclick="removeIcon()" value="Remove" style="width:70px"></td><td> index:<input id="removeIndex" style="width:20px;text-align:right" value="0"></td><td></td>
+			<tr><td><input type="button" onclick="openIcon()" value="Open" style="width:70px"></td><td> index:<input id="openIndex" style="width:20px;text-align:right" value="0"></td><td></td>
+			<tr><td><input type="button" onclick="closeIcon()" value="Close" style="width:70px"></td><td> index:<input id="closeIndex" style="width:20px;text-align:right" value="0"></td><td></td>
+			<tr><td><input type="button" onclick="closeAll()" value="CloseAll" style="width:70px"></td><td></td><td></td>
+		</table>
+		<ul id="ic1" data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"test1", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-pubsub.html b/dojox/mobile/tests/test_IconContainer-pubsub.html
new file mode 100644
index 0000000..22d09cc
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-pubsub.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Editable Icon Container (PubSub)</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView"
+		], function(connect, dom, ready, registry){
+			startEdit = function(){
+				registry.byId("iconContainer").startEdit();
+			}
+			endEdit = function(){
+				registry.byId("iconContainer").endEdit();
+			}			
+			ready(function(){
+				var msgArea = dom.byId("msgArea");
+				var ic = registry.byId("iconContainer");
+				connect.subscribe("/dojox/mobile/startEdit", function(iconContainer){
+					msgArea.innerHTML = "StartEdit";
+					dom.byId("btn1").style.display = "none";
+					dom.byId("btn2").style.display = "";				
+				});
+				connect.subscribe("/dojox/mobile/endEdit", function(iconContainer){
+					msgArea.innerHTML = "EndEdit";
+					dom.byId("btn1").style.display = "";
+					dom.byId("btn2").style.display = "none";				
+				});
+				connect.subscribe("/dojox/mobile/deleteIconItem", function(iconContainer, widget){
+					msgArea.innerHTML = "DeleteIconItem: " + widget.label;
+				});
+				connect.subscribe("/dojox/mobile/moveIconItem", function(iconContainer, widget, from, to){
+					msgArea.innerHTML = "MoveIconItem: " + widget.label + " (" + from + " -> " + to + ")";
+				});
+			});
+		});
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Editable Icon Container (PubSub)</h1>
+		<ul id="iconContainer" data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='editable:true'>
+			<li id="icon1" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"images/icon1.png", lazy:true, badge:"55"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"images/icon2.png", lazy:true, deletable:false'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"images/icon3.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app4", icon:"images/icon4.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app5", icon:"images/icon5.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app6", icon:"images/icon6.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app7", icon:"images/icon7.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app8", icon:"images/icon8.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app9", icon:"images/icon9.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app10", icon:"images/icon10.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"images/icon1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"images/icon2.png", href:"test_RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url", icon:"images/icon3.png", url:"data/view-sample.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url-async", icon:"images/icon4.png", url:"data/view-sample.html", transition:"slide", sync:false'></li>
+		</ul>
+		<button id="btn1" onclick="startEdit();">Start Edit</button>
+		<button id="btn2" onclick="endEdit();" style="display:none;">End Edit</button>
+		<div id="msgArea" style="margin-top:10px; margin-left:10px;"></div>
+	</div>
+	
+	<div id="dlg_confirm" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div class="mblSimpleDialogTitle">Delete Confirmation</div>
+		<div id="dlg_txt" class="mblSimpleDialogText">Are you sure you want to delete this app?</div>
+		<button id="dlg_btn1" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:60px;">Delete</button>
+		<button id="dlg_btn2" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:60px;">Cancel</button>
+	</div>
+	
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Icon Container", moveTo:"view1"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-removeConfirmation.html b/dojox/mobile/tests/test_IconContainer-removeConfirmation.html
new file mode 100644
index 0000000..8707625
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-removeConfirmation.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Editable Icon Container (Remove Confirmation)</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer','SimpleDialog','Button']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/_EditableIconMixin",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/Button",
+			"dojox/mobile/ScrollableView"
+		], function(declare, connect, dom, ready, registry){
+			showDialog = function(widget){
+				dom.byId("dlg_txt").innerHTML = "Are you sure you want to delete " + widget.label + "?";
+				registry.byId("dlg_confirm").show();					
+			}
+			hideDialog = function(){
+				registry.byId("dlg_confirm").hide();		
+			}
+			ready(function(){
+				connect.connect(registry.byId("dlg_btn1"), "onClick", null, function(e){
+					hideDialog();
+					registry.byId("iconContainer").deleteCurrentIcon();
+				});
+				connect.connect(registry.byId("dlg_btn2"), "onClick", null, function(e){
+					hideDialog();
+				});
+			});
+
+			dojox.mobile.EditableIconContainer = declare(
+				"dojox.mobile.EditableIconContainer",
+				[dojox.mobile.IconContainer, dojox.mobile._EditableIconMixin],
+			{
+				_currentIcon: null,
+				deleteIconClicked: function(e){
+					var item = this._currentIcon = registry.getEnclosingWidget(e.target);
+					showDialog(item);
+					return false;
+				},
+				deleteCurrentIcon: function(){
+					if(this._currentIcon){
+						this.deleteItem(this._currentIcon);
+						this._currentIcon = null;
+					}
+				}
+			});
+		});
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container (Remove Confirmation)</h1>
+		<ul id="iconContainer" data-dojo-type="dojox.mobile.EditableIconContainer" data-dojo-props='editable:true'>
+			<li id="icon1" data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"images/icon1.png", badge:"55"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"images/icon2.png", deletable:false'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"images/icon3.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app4", icon:"images/icon4.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app5", icon:"images/icon5.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app6", icon:"images/icon6.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app7", icon:"images/icon7.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app8", icon:"images/icon8.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app9", icon:"images/icon9.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app10", icon:"images/icon10.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"images/icon1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"images/icon2.png", href:"test_RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url", icon:"images/icon3.png", url:"data/view-sample.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url-async", icon:"images/icon4.png", url:"data/view-sample.html", transition:"slide", sync:false'></li>
+		</ul>
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			Hold down on one of the icons until they start shaking.
+		</div>
+	</div>
+	
+	<div id="dlg_confirm" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div class="mblSimpleDialogTitle">Remove Confirmation</div>
+		<div id="dlg_txt" class="mblSimpleDialogText">Are you sure you want to remove this app?</div>
+		<button id="dlg_btn1" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:65px;">Remove</button>
+		<button id="dlg_btn2" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:65px;">Cancel</button>
+	</div>
+	
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Icon Container", moveTo:"view1"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-single-below.html b/dojox/mobile/tests/test_IconContainer-single-below.html
new file mode 100644
index 0000000..0097cbc
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-single-below.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Icon Container (Single - Below)</title>
+
+	<link href="../themes/common/dijit/dijit.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer','dijit.Calendar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container (Single - Below)</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='transition:"below", single:true'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Calendar", icon:"images/icon-1.png"' lazy="true">
+				<div data-dojo-type="dijit.CalendarLite"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Color Palette", icon:"images/icon-1.png"' lazy="true">
+				<div data-dojo-type="dijit.ColorPalette"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Progress Bar", icon:"images/icon-1.png"' lazy="true">
+				<div data-dojo-type="dijit.ProgressBar"></div>
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-single.html b/dojox/mobile/tests/test_IconContainer-single.html
new file mode 100644
index 0000000..1ebbbd2
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-single.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Icon Container (Single - NewPane)</title>
+
+	<link href="../themes/common/dijit/dijit.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer','dijit.Calendar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container (Single - NewPane)</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='transition:"flip", single:true'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Calendar", icon:"images/icon-1.png"' lazy="true">
+				<div data-dojo-type="dijit.CalendarLite"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Color Palette", icon:"images/icon-1.png"' lazy="true">
+				<div data-dojo-type="dijit.ColorPalette"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Progress Bar", icon:"images/icon-1.png"' lazy="true">
+				<div data-dojo-type="dijit.ProgressBar"></div>
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-sprite.html b/dojox/mobile/tests/test_IconContainer-sprite.html
new file mode 100644
index 0000000..cf7230b
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-sprite.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Icon (css sprite)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
+
+	<style>
+		html,body{
+			overflow: hidden;
+		}
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Sprite Icons</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='iconBase:"images/icon-all.png"'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", iconPos:"0,0,65,65"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", iconPos:"0,65,65,65"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", iconPos:"0,130,65,65"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", iconPos:"0,195,65,65", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", iconPos:"0,260,65,65", href:"test_RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url", iconPos:"65,0,65,65", url:"data/view-sample.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url-async", iconPos:"65,65,65,65", url:"data/view-sample.html", transition:"slide", sync:false'></li>
+		</ul>
+	</div>
+
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Icon Container", moveTo:"view1"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-transition-below.html b/dojox/mobile/tests/test_IconContainer-transition-below.html
new file mode 100644
index 0000000..c74c2a9
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-transition-below.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Icon Container (below transition)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container (below transition)</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='transition:"below", single:true'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"images/icon1.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"images/icon2.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"images/icon3.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app4", icon:"images/icon4.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app5", icon:"images/icon5.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app6", icon:"images/icon6.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app7", icon:"images/icon7.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app8", icon:"images/icon8.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app9", icon:"images/icon9.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app10", icon:"images/icon10.png"'><div class="box"></div></li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer-transition-zoom.html b/dojox/mobile/tests/test_IconContainer-transition-zoom.html
new file mode 100644
index 0000000..41d7213
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer-transition-zoom.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Icon Container (Zoom In/Out transition)</title>
+
+	<link href="../themes/common/transitions.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container (ZoomIn transition)</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='transition:"zoomIn", single:true'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"images/icon1.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"images/icon2.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"images/icon3.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app4", icon:"images/icon4.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app5", icon:"images/icon5.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app6", icon:"images/icon6.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app7", icon:"images/icon7.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app8", icon:"images/icon8.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app9", icon:"images/icon9.png"'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"images/icon10.png", moveTo:"about", transition:"zoomIn"'></li>
+		</ul>
+	</div>
+
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Icon Container", moveTo:"view1", transition:"zoomOut"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconContainer.html b/dojox/mobile/tests/test_IconContainer.html
new file mode 100644
index 0000000..7c75fcd
--- /dev/null
+++ b/dojox/mobile/tests/test_IconContainer.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Icon Container (Multi - Below)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container (Multi - Below)</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"moveTo", icon:"images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"href", icon:"images/icon-1.png", href:"test_RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"hrefTarget", icon:"images/icon-1.png", href:"test_RoundRectList.html", hrefTarget:"_self", transition:"swirl"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url", icon:"images/icon-1.png", url:"data/view-sample.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"url-async", icon:"images/icon-1.png", url:"data/view-sample.html", transition:"slide", sync:false'></li>
+		</ul>
+	</div>
+
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Icon Container", moveTo:"view1"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconMenu-6up.html b/dojox/mobile/tests/test_IconMenu-6up.html
new file mode 100644
index 0000000..5f633b7
--- /dev/null
+++ b/dojox/mobile/tests/test_IconMenu-6up.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>IconMenu (6up)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconMenu','SimpleDialog']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconMenu",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/Button"
+		], function(ready, registry){
+			show = function(){
+				registry.byId("dlg1").show();
+			}
+			hide = function(){
+				registry.byId("dlg1").hide();
+			}
+			ready(function(){
+				show();
+			});
+		});
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	#dlg1 {
+		width: 274px;
+		height: 210px;
+	}
+
+	.windows_theme .mblButton {
+		position: absolute;
+		bottom: 10px;
+		width: 45% !important;
+	}
+
+	.windows_theme .mblButton:first-of-type {
+		right: 10px;
+	}
+
+	.windows_theme .mblView {
+		height: 100%;
+	}
+
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="dlg1" data-dojo-type="dojox.mobile.SimpleDialog" data-dojo-props='modal:false'>
+		<ul data-dojo-type="dojox.mobile.IconMenu" data-dojo-props='cols:3'>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Mute", icon:"images/tab-icon-36w.png", selected:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Keypad", icon:"images/tab-icon-32w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Settings", icon:"images/tab-icon-30w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Info", icon:"images/tab-icon-16w.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Tour", icon:"images/tab-icon-19w.png", moveTo:"view2", transition:"slide", closeOnAction:true'></li>
+			<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"Contacts", icon:"images/tab-icon-29w.png"'></li>
+		</ul>
+	</div>
+
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">6-up Icon Menu</h1>
+		<button data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:100px;margin:10px;" onclick="show()">Show</button>
+		<button data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:100px;margin:10px;" onclick="hide()">Hide</button>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.View" style="background-color:white;height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"view1"'>View2</h1>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"view1"'>View3</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconMenu-programmatic.html b/dojox/mobile/tests/test_IconMenu-programmatic.html
new file mode 100644
index 0000000..76ff81c
--- /dev/null
+++ b/dojox/mobile/tests/test_IconMenu-programmatic.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>IconMenu (programmatic)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconMenu']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dojox/mobile/IconMenu",
+			"dojox/mobile/IconMenuItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(ready, IconMenu, IconMenuItem){
+			ready(function(){
+				var item, row;
+				var menu = new IconMenu({
+					cols: 3
+				}, "container");
+				menu.startup();
+
+				item = new IconMenuItem({
+					label: "mute",
+					icon: "images/tab-icon-36w.png",
+					selected: true
+				});
+				menu.addChild(item);
+
+				item = new IconMenuItem({
+					label: "keypad",
+					icon: "images/tab-icon-32w.png"
+				});
+				menu.addChild(item);
+
+				item = new IconMenuItem({
+					label: "speaker",
+					icon: "images/tab-icon-30w.png"
+				});
+				menu.addChild(item);
+
+				item = new IconMenuItem({
+					label: "addcall",
+					icon: "images/tab-icon-16w.png"
+				});
+				menu.addChild(item);
+
+				item = new IconMenuItem({
+					label: "hold",
+					icon: "images/tab-icon-19w.png"
+				});
+				menu.addChild(item);
+
+				item = new IconMenuItem({
+					label: "contacts",
+					icon: "images/tab-icon-29w.png"
+				});
+				menu.addChild(item);
+			});
+		});
+	</script>
+</head>
+<body style="background-color:#B8B6B9">
+	<div id="container" style="width:274px;height:210px;margin:20px;"></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_IconMenu-standalone.html b/dojox/mobile/tests/test_IconMenu-standalone.html
new file mode 100644
index 0000000..7d0e1df
--- /dev/null
+++ b/dojox/mobile/tests/test_IconMenu-standalone.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>IconMenu (standalone)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconMenu']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconMenu"
+		]);
+	</script>
+</head>
+<body style="background-color:#B8B6B9">
+	<ul data-dojo-type="dojox.mobile.IconMenu" style="width:274px;height:210px;margin:20px;" data-dojo-props='cols:3'>
+		<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"mute", icon:"images/tab-icon-36w.png", selected:true'></li>
+		<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"keypad", icon:"images/tab-icon-32w.png"'></li>
+		<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"speaker", icon:"images/tab-icon-30w.png", selected:true'></li>
+		<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"add call", icon:"images/tab-icon-16w.png"'></li>
+		<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"hold", icon:"images/tab-icon-19w.png"'></li>
+		<li data-dojo-type="dojox.mobile.IconMenuItem" data-dojo-props='label:"contacts", icon:"images/tab-icon-29w.png"'></li>
+	</ul>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ListItem-actions.html b/dojox/mobile/tests/test_ListItem-actions.html
new file mode 100644
index 0000000..9fc8365
--- /dev/null
+++ b/dojox/mobile/tests/test_ListItem-actions.html
@@ -0,0 +1,238 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ListItem Actions</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/_base/window",
+			"dojo/dom-construct",
+			"dojo/ready",
+			"dijit/registry",
+			"dojo/data/ItemFileReadStore",
+			"dojox/mobile/ProgressIndicator",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/RoundRectDataList",
+			"dojox/mobile/ContentPane"
+		], function(connect, win, domConstruct, ready, registry, ItemFileReadStore, ProgressIndicator, ListItem, parser){
+			var static_data = { 
+				items: [ 
+					{label: "Apple", moveTo: "home", icon: "images/i-icon-1.png"},
+					{label: "Banana", moveTo: "home", icon: "images/i-icon-2.png"},
+					{label: "Cherry", moveTo: "home", icon: "images/i-icon-3.png"},
+					{label: "Grape", moveTo: "home", icon: "images/i-icon-4.png"},
+					{label: "Kiwi", moveTo: "home", icon: "images/i-icon-5.png"},
+					{label: "Lemon", moveTo: "home", icon: "images/i-icon-6.png"},
+					{label: "Melon", moveTo: "home", icon: "images/i-icon-7.png"},
+					{label: "Orange", moveTo: "home", icon: "images/i-icon-8.png"},
+					{label: "Peach", moveTo: "home", icon: "images/i-icon-9.png"}
+				]
+			};
+
+			// Update existing view content and make transition
+			myAction1 = function(){
+				var rect = registry.byId("rect1");
+				rect.containerNode.innerHTML = new Date();
+				this.transitionTo("view1");
+			}
+
+			// Load content into existing view and make transition
+			myAction2 = function(){
+				var view2 = registry.byId("view2"); // destination view
+				var listItem = this;
+				var prog = ProgressIndicator.getInstance();
+				win.body().appendChild(prog.domNode);
+				prog.start();
+				view2.destroyDescendants();
+
+				/*
+				var url = "http://..."; // or var url = listItem.url;
+				dojo.xhrGet({
+					url: url,
+					handleAs: "text",
+					load: function(response, ioArgs){
+						var container = view2.containerNode;
+						container.innerHTML = response;
+						parser.parse(container);
+						prog.stop();
+						listItem.transitionTo("view2");
+					}
+				});
+				*/
+				setTimeout(function(){ // network latency simulation
+					var markup = '<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props=\'back:"Home", moveTo:"home"\'>Loaded View 1</h1>' +
+						'<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props=\'shadow:true\'>Thank you!</div>';
+					var container = view2.containerNode;
+					container.innerHTML = markup;
+					parser.parse(container);
+					prog.stop();
+					listItem.transitionTo("view2");
+				}, 5000);
+			}
+
+			// Make transition and load content into existing view
+			myAction3 = function(){
+				var view3 = registry.byId("view3"); // destination view
+				var listItem = this;
+				var prog = ProgressIndicator.getInstance();
+				win.body().appendChild(prog.domNode);
+				prog.start();
+				view3.destroyDescendants();
+				listItem.transitionTo("view3");
+
+				/*
+				var url = "http://..."; // or var url = listItem.url;
+				dojo.xhrGet({
+					url: url,
+					handleAs: "text",
+					load: function(response, ioArgs){
+						var container = view3.containerNode;
+						container.innerHTML = response;
+						parser.parse(container);
+						prog.stop();
+					}
+				});
+				*/
+				setTimeout(function(){ // network latency simulation
+					var markup = '<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props=\'back:"Home", moveTo:"home"\'>Loaded View 2</h1>' +
+						'<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props=\'shadow:true\'>Gracias!</div>';
+					var container = view3.containerNode;
+					container.innerHTML = markup;
+					parser.parse(container);
+					prog.stop();
+				}, 5000);
+			}
+
+			// Create a new view and make transition
+			myAction4 = function(){
+				if(!registry.byId("view4")){
+					var view4 = new dojox.mobile.View({
+						id: "view4",
+						selected: true
+					}, domConstruct.create("DIV", null, win.body()));
+					view4.startup();
+
+					var heading1 = new dojox.mobile.Heading({
+						label: "Dynamic View",
+						back: "Home",
+						moveTo: "home"
+					});
+					heading1.placeAt(view4.containerNode);
+					heading1.startup();
+
+					var categ1 = new dojox.mobile.RoundRectCategory({
+						label: "Documents"
+					});
+					categ1.placeAt(view4.containerNode);
+					categ1.startup();
+
+					var list1 = new dojox.mobile.RoundRectList();
+					list1.placeAt(view4.containerNode);
+					list1.startup();
+
+					var counter = 4;
+					for(var i = 1; i <= 3; i++){
+						var item1 = new dojox.mobile.ListItem({
+							icon: "images/i-icon-"+i+".png",
+							label: "Document 000"+counter
+						});
+						item1.placeAt(list1.containerNode);
+						item1.startup();
+						counter++;
+					}
+				}
+				this.transitionTo("view4");
+			}
+
+			// Update DataList
+			myAction5 = function(){
+				var list1 = registry.byId("list1");
+				if(!list1.store){
+					var store1 = new ItemFileReadStore({data: static_data});
+					list1.setStore(store1, {label: '*e'}); // items whose label ends with 'e'
+				}
+				this.transitionTo("view5");
+			}
+
+			// Partial Update using dojox.mobile.ContentPane
+			myAction6 = function(){
+				var pane1 = registry.byId("pane1");
+				if(!pane1.domNode.innerHTML){ // nothing has been loaded yet
+					connect.connect(pane1, "onLoad", this, function(){
+						// onLoad fires when the content is ready
+						this.transitionTo("view6");
+					});
+					pane1.set("href", "data/fragment1.html");
+				}else{
+					this.transitionTo("view6");
+				}
+			}
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<h1 data-dojo-type="dojox.mobile.Heading">Action and Transition</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">ListItem Actions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#", transition:"slide", onClick:myAction1'>
+				Update View
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#", transition:"slide", onClick:myAction2'>
+				Load and Move (async)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#", transition:"slide", onClick:myAction3'>
+				Move and Load (async)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"#", transition:"slide", onClick:myAction4'>
+				Create View
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"#", transition:"slide", onClick:myAction5'>
+				Data List
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"#", transition:"slide", onClick:myAction6'>
+				Partial Update (async)
+			</li>
+		</ul>
+	</div>
+
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"home"'>Current Status</h1>
+		Local Time:
+		<div id="rect1" data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'></div>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View">
+	</div>
+
+	<div id="view5" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">RoundRectDataList</h1>
+		<ul id="list1" data-dojo-type="dojox.mobile.RoundRectDataList"></ul>
+	</div>
+
+	<div id="view6" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"home", fixed:"top"'>Partial Update</h1>
+		Dynamic Content:
+		<div id="pane1" data-dojo-type="dojox.mobile.ContentPane"></div>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"home", transitionDir:-1'>
+				Home
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ListItem-button.html b/dojox/mobile/tests/test_ListItem-button.html
new file mode 100644
index 0000000..cc748b8
--- /dev/null
+++ b/dojox/mobile/tests/test_ListItem-button.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Button List</title>
+
+	<link href="../themes/common/domButtons/DomButtonColorButtons.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, dom, domClass, ready, registry){
+			function btnClicked(e){
+				var listItem = registry.getEnclosingWidget(e.currentTarget);
+				var btnDiv = listItem.rightIconNode.firstChild;
+				if(domClass.contains(btnDiv, "mblDomButtonBluePlus")){
+					listItem.set("rightIcon", "mblDomButtonRedMinus");
+				}else if(domClass.contains(btnDiv, "mblDomButtonRedMinus")){
+					listItem.set("rightIcon", "mblDomButtonBluePlus");
+				}
+			}
+			ready(function(){
+				var ul = dom.byId("list");
+				for(var i = 0, len = ul.childNodes.length; i < len; i++){
+					var li = ul.childNodes[i];
+					if(li.nodeType != 1 || li.tagName != "LI"){ continue; }
+					var w = registry.byNode(li);
+					connect.connect(w.rightIconNode, "onclick", btnClicked);
+				}
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="mashups" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Mashups</h1>
+		<ul id="list" data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", rightIcon:"mblDomButtonBluePlus"'>
+				XX Widget
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", rightIcon:"mblDomButtonRedMinus"'>
+				YY Widget
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ListItem-domButtons.html b/dojox/mobile/tests/test_ListItem-domButtons.html
new file mode 100644
index 0000000..9015369
--- /dev/null
+++ b/dojox/mobile/tests/test_ListItem-domButtons.html
@@ -0,0 +1,244 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>List with domButtons</title>
+
+	<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/array",
+			"dojo/_base/connect",
+			"dojo/_base/window",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(array, connect, win, ready, registry){
+			function setRightIcon2Value(id, val){
+				var txt = win.doc.createTextNode(val);
+				registry.byId(id).rightIcon2Node.firstChild.firstChild.appendChild(txt);
+			}
+			function setIconValue(id, val){
+				var txt = win.doc.createTextNode(val);
+				registry.byId(id).iconNode.firstChild.firstChild.firstChild.firstChild.appendChild(txt);
+			}
+			ready(function(){
+				setRightIcon2Value("item1", "32");
+				setRightIcon2Value("item2", "5");
+				setRightIcon2Value("item3", "108");
+				setIconValue("item42", "3");
+				array.forEach(registry.byId("list1").getChildren(), function(w){
+					connect.connect(w.iconNode, "onclick", w, function(e){
+						console.log(this);
+						registry.byId("list1").removeChild(this);
+					});
+				});
+				array.forEach(registry.byId("list5").getChildren(), function(w){
+					connect.connect(w.iconNode, "onclick", w, function(e){
+						console.log(this);
+						registry.byId("list5").removeChild(this);
+					});
+				});
+			});
+		});
+	</script>
+	<style>
+	#item1, #item2, #item3 {
+		font-weight: normal;
+		font-size: 12px;
+	}
+	.subject {
+		font: bold 16px Helvetica;
+	}
+	.textBox {
+		overflow: hidden;
+	}
+	
+	/* Note: The class name of DOM buttons must start with "mblDomButton". */
+	
+	/* === My Custom Button1 ==*/
+	.mblDomButtonMyCustomButton1 {
+		position: relative;
+		width: 30px;
+		height: 30px;
+		border-width: 1px;
+		border-style: outset;
+		border-color: #A5A2A5;
+		color: white;
+		-webkit-border-radius: 3px;
+		background-color: #D6D3D6;
+		background: -webkit-gradient(linear, left top, left bottom, from(#EFF3EF), to(#BDBEBD));
+	}
+	.mblDomButtonMyCustomButton1 > DIV {
+		position: absolute;
+		top: 13px;
+		left: 5px;
+		width: 20px;
+		height: 4px;
+		margin: 0px;
+		font-size: 1px;
+		background-color: red;
+		-webkit-border-radius: 2px;
+		-webkit-transform: rotate(45deg);
+	}
+	.mblDomButtonMyCustomButton1 > DIV > DIV {
+		position: absolute;
+		top: -8px;
+		left: 8px;
+		width: 4px;
+		height: 20px;
+		margin: 0px;
+		font-size: 1px;
+		background-color: red;
+		-webkit-border-radius: 2px;
+	}
+	
+	/* === My Custom Button2 ==*/
+	.mblDomButtonMyCustomButton2 {
+		position: relative;
+		width: 29px;
+		height: 29px;
+	}
+	
+	.mblDomButtonMyCustomButton2 > DIV {
+		position: relative;
+		top: 2px;
+		left: 2px;
+		width: 22px;
+		height: 22px;
+		border: 1px solid #B5B6B5;
+		-webkit-border-radius: 12px;
+		-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+	}
+	.mblDomButtonMyCustomButton2 > DIV > DIV {
+		position: relative;
+		top: 2px;
+		left: 2px;
+		width: 18px;
+		height: 18px;
+		-webkit-border-radius: 9px;
+		background-color: green;
+	}
+	.mblDomButtonMyCustomButton2 > DIV > DIV > DIV {
+		position: relative;
+		color: white;
+		text-align: center;
+		line-height: 17px;
+		font-size: 14px;
+	}
+	.mblDomButtonMyCustomButton2 > DIV > DIV > DIV > DIV {
+		display: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<h1 data-dojo-type="dojox.mobile.Heading">View 1</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">RoundRectList</h2>
+		<ul id="list1" data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"mblDomButtonRedCircleMinus"
+			   , moveTo:"view2", arrowClass:"mblDomButtonSilverCircleDownArrow"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"mblDomButtonRedCircleMinus"
+			   , moveTo:"view2", arrowClass:"mblDomButtonSilverCircleGreenButton"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"mblDomButtonRedCircleMinus"
+			   , moveTo:"view2", arrowClass:"mblDomButtonSilverCircleRedCross"'>
+				Fade
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view1"'>View 2</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Dom Button with Text</h2>
+		<ul id="list2" data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='icon:"mblDomButtonBlueBall", moveTo:"view3", rightIcon2:"mblDomButtonGrayRoundRect"'>
+				<div class="textBox">
+					<div class="subject">Dojo: Traditional Karate-do Spirit</div>
+					Sarah Connor Hardcover<br>
+					Eligible for FREE Super Saver Shipping<br>
+					<span style="color:red">$14.50 (50%)</span> In Stock
+				</div>
+			</li>
+			<li id="item2" data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='icon:"mblDomButtonTransparent19", moveTo:"view3", rightIcon2:"mblDomButtonGrayRoundRect"'>
+				<div class="textBox">
+					<div class="subject">Japanese Martial Arts Dojo</div>
+					Martin Parker Hardcover<br>
+					<span style="color:red">$14.00 (60%)</span> In Stock
+				</div>
+			</li>
+			<li id="item3" data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='icon:"mblDomButtonGreenBall", moveTo:"view3", rightIcon2:"mblDomButtonGrayRoundRect"'>
+				<div class="textBox">
+					<div class="subject">Total Solar Eclipse</div>
+					Steven Young Hardcover<br>
+					Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+					Eligible for FREE Super Saver Shipping<br>
+					<span style="color:red">$9.50 (62%)</span> In Stock
+				</div>
+			</li>
+		</ul>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view2"'>View 3</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Variable Height List</h2>
+		<ul id="list3" data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='moveTo:"view4", arrowClass:"mblDomButtonBlueCircleArrow"'>
+				Top 10 news stories of the decade
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='moveTo:"view4", arrowClass:"mblDomButtonBlueCircleArrow"'>
+				Create client-side diagrammatic interaction in Web applications with GFX
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='moveTo:"view4", arrowClass:"mblDomButtonBlueCircleArrow"'>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+	</div>
+
+	<div id="view4" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view3"'>View 4</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Custom DOM Buttons</h2>
+		<ul id="list4" data-dojo-type="dojox.mobile.RoundRectList">
+			<li id="item41" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"mblDomButtonMyCustomButton1", moveTo:"view5"'>
+				My Custom Button 1
+			</li>
+			<li id="item42" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"mblDomButtonMyCustomButton2", moveTo:"view5"'>
+				My Custom Button 2
+			</li>
+		</ul>
+	</div>
+
+	<div id="view5" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Back", moveTo:"view4"'>View 5</h1>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">EdgeToEdgeList</h2>
+		<ul id="list5" data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"mblDomButtonRedCircleMinus"'>
+				Airplane Mode
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"mblDomButtonRedCircleMinus", rightText:"mac", moveTo:"view1"'>
+				Wi-Fi
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"mblDomButtonRedCircleMinus", rightText:"AcmePhone", moveTo:"view1"'>
+				Carrier
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ListItem-layout.html b/dojox/mobile/tests/test_ListItem-layout.html
new file mode 100644
index 0000000..5ccb8ae
--- /dev/null
+++ b/dojox/mobile/tests/test_ListItem-layout.html
@@ -0,0 +1,134 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ListItem - layout</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dijit/_WidgetBase",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(declare, WidgetBase){
+			PlainWidget = declare("PlainWidget", WidgetBase, {
+				buildRendering: function(){
+					this.inherited(arguments);
+					this.domNode.style.backgroundColor = "gray";
+					this.domNode.style.display = "inline";
+					this.domNode.style.lineHeight = "normal";
+				}
+			});
+		});
+
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">ListItem Layout</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Examples</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="left"><div data-dojo-type="PlainWidget">Left Widget</div></div>
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="center"><div data-dojo-type="PlainWidget">Center Widget</div></div>
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="right"><div data-dojo-type="PlainWidget">Right Widget</div></div>
+			</li>
+
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="left"><span data-dojo-type="dojox.mobile.ToolBarButton">Left</span></div>
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="center"><span data-dojo-type="dojox.mobile.ToolBarButton">Center</span></div>
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="right"><span data-dojo-type="dojox.mobile.ToolBarButton">Right</span></div>
+			</li>
+
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="center"><span data-dojo-type="dojox.mobile.ToolBarButton">Center</span></div>
+				<div layout="left"><span data-dojo-type="dojox.mobile.ToolBarButton">Left</span></div>
+				<div layout="right"><span data-dojo-type="dojox.mobile.ToolBarButton">Right</span></div>
+			</li>
+
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="left">Left Node</div>
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="center">Center Node</div>
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="right">Right Node</div>
+			</li>
+
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="left"><input></div>
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="center"><input></div>
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="right"><input></div>
+			</li>
+
+
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div layout="left">Left Node</div>
+				<div layout="right">Right Node</div>
+				<div layout="center">Center Node</div>
+			</li>
+
+
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"bar"'>
+				<div layout="left">Left Node</div>
+				<div layout="right">Right Node</div>
+				<div layout="center">Center Node</div>
+			</li>
+
+
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"bar", label:"Label"'>
+				<div layout="left">Left Node</div>
+				<div layout="right">Right Node</div>
+				<div layout="center">Center Node</div>
+			</li>
+
+
+			<li data-dojo-type="dojox.mobile.ListItem"
+	 			data-dojo-props='icon:"images/i-icon-1.png", moveTo:"bar", variableHeight:true, label:"Label<br>Label<br>Label"'>
+				<div data-dojo-type="PlainWidget" layout="left">Left Widget</div>
+				<div data-dojo-type="PlainWidget" data-dojo-props='layout:"right"'>Right Widget</div>
+				<div layout="center"><div data-dojo-type="PlainWidget">Center Widget</div></div>
+			</li>
+
+
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"bar", variableHeight:true'>
+				<div data-dojo-type="PlainWidget" layout="left">Left Widget</div>
+				<div data-dojo-type="PlainWidget" data-dojo-props='layout:"right"'>Right Widget</div>
+				<div layout="center"><div data-dojo-type="PlainWidget">Center Widget</div></div>
+				Label<br>Label<br>Label
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ListItem-sprite.html b/dojox/mobile/tests/test_ListItem-sprite.html
new file mode 100644
index 0000000..0265235
--- /dev/null
+++ b/dojox/mobile/tests/test_ListItem-sprite.html
@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Settings</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="settings" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Settings</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"images/i-icon-all.png"'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"0,0,29,29"'>
+				Airplane Mode
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"0,29,29,29", rightText:"mac", href:"test_IconContainer.html"'>
+				Wi-Fi
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"0,58,29,29", rightText:"AcmePhone", moveTo:"general"'>
+				Carrier
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"images/i-icon-all.png"'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"0,87,29,29", moveTo:"general"'>
+				Sounds
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"0,116,29,29", moveTo:"general"'>
+				Brightness
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"29,0,29,29", moveTo:"general"'>
+				Wallpaper
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='iconBase:"images/i-icon-all.png"'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"29,29,29,29", moveTo:"general"'>
+				General
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"29,58,29,29", moveTo:"general"'>
+				Mail, Contacts, Calendars
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"29,87,29,29", moveTo:"general"'>
+				Phone
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"29,116,29,29", moveTo:"general"'>
+				Safari
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"0,0,29,29", moveTo:"general"'>
+				SMS/MMS
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"0,29,29,29", moveTo:"general"'>
+				iPod
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"0,58,29,29", moveTo:"general"'>
+				Photos
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='iconPos:"0,87,29,29", moveTo:"general"'>
+				Store
+			</li>
+		</ul>
+	</div>
+
+	<div id="general" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Settings", moveTo:"settings"'>General</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				About
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2h 40m", moveTo:"about"'>
+				Usage
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+				Bluetooth
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Location Services
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1 Minute", moveTo:"about"'>
+				Auto-Lock
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+				Passcode Lock
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+				Restrictions
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Home
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Date & Time					   
+			</li>							   
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Keyboard					   
+			</li>							   
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				International				   
+			</li>							   
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Accessibility
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Reset
+			</li>
+		</ul>
+	</div>
+
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"General", moveTo:"general"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network											   
+			</li>												   
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+				Videos
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+				Photos
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+				Applications
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+				Capacity
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+				Available
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+				Version
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ListItem-transOpt.html b/dojox/mobile/tests/test_ListItem-transOpt.html
new file mode 100644
index 0000000..8ed89df
--- /dev/null
+++ b/dojox/mobile/tests/test_ListItem-transOpt.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Animation</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png",
+				transitionOptions:{moveTo:"bar", transition:"slide"}'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png",
+				transitionOptions:{moveTo:"bar", transition:"flip"}'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png",
+				transitionOptions:{moveTo:"bar", transition:"fade"}'>
+				Fade
+			</li>
+		</ul>
+	</div>
+
+	<div id="bar" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"foo"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_LongListMixin.html b/dojox/mobile/tests/test_LongListMixin.html
new file mode 100644
index 0000000..57df7bf
--- /dev/null
+++ b/dojox/mobile/tests/test_LongListMixin.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Dojo Mobile Test</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+		    "dojo/ready",
+		    "dijit/registry",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/TabBarButton",
+			"dojox/mobile/RoundRectList",
+			"dojox/mobile/LongListMixin"
+		], function(ready, registry, ListItem){
+			fillList = function(list){
+				for(var i = 0; i < 2000; i++){
+					list.addChild(new ListItem({
+						variableHeight:true,
+						style:"font-size:10px",
+						innerHTML: 	i + '. <a href="#" class="lnk">Book Title '+i+'</a><br>'+
+									'Author '+i+'<br>'+
+									'Eligible for FREE Super Saver Shipping<br>'+
+									'<span style="color:red">$14.50 (50%)</span> In Stock<br>'+
+									'# ('+i+')'
+					}));
+				}
+			};
+			ready(function(){
+				fillList(list1);
+				registry.byId("view2").on("beforeTransitionIn", function(){
+					if(list2.getChildren().length == 0){
+						fillList(list2);
+					}
+				})
+			});
+		});
+	</script>
+
+	<style type="text/css">
+	</style>
+</head>
+
+<body style="visibility:hidden;">
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", fixed:"top"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view1", selected:true'>With Mixin</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view2"'>Without Mixin</li>
+		</ul>
+		<div data-dojo-type="dojox/mobile/ScrollableView" id="view1">
+			<div data-dojo-id="list1" data-dojo-type="dojox/mobile/EdgeToEdgeList" data-dojo-mixins="dojox/mobile/LongListMixin"></div>
+		</div>
+		<div data-dojo-type="dojox/mobile/ScrollableView" id="view2">
+			<div data-dojo-id="list2" data-dojo-type="dojox/mobile/EdgeToEdgeList"></div>
+		</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Opener-ActionSheet-async.html b/dojox/mobile/tests/test_Opener-ActionSheet-async.html
index 603b881..0727714 100644
--- a/dojox/mobile/tests/test_Opener-ActionSheet-async.html
+++ b/dojox/mobile/tests/test_Opener-ActionSheet-async.html
@@ -48,11 +48,11 @@
 			-webkit-box-shadow: none !important;
 		}
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, async:true"></script>
 	<script language="JavaScript" type="text/javascript">
 		require([
-			"dojo/_base/html",			// dojo.byId
-			"dijit/_base/manager",		// dijit.byId
+			"dojo/_base/html", // dojo.byId
+			"dijit/_base/manager",  // dijit.byId
 			"dojox/mobile",				// This is a mobile app.
 			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
 			"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
@@ -75,7 +75,7 @@
 <body style="visibility:hidden;">
 	<center>
 	<button dojoType="dojox.mobile.Button" class="mblBlueButton" style="margin-top:20px;width:200px;"
-			onclick="dijit.byId('actionSheet').show(this, ['above-centered','below-centered','after','before'])">Open Action Sheet</button>
+			onclick="dijit.byId('actionSheet').show(this.domNode, ['above-centered','below-centered','after','before'])">Open Action Sheet</button>
 	<div id="msgArea" style="margin-top:5px;"></div>
 	</center>
 
diff --git a/dojox/mobile/tests/test_Opener-Calendar-async.html b/dojox/mobile/tests/test_Opener-Calendar-async.html
deleted file mode 100644
index f403625..0000000
--- a/dojox/mobile/tests/test_Opener-Calendar-async.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html style="overflow:hidden;">
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>test Opener with Calendar</title>
-	<link href="../themes/common/dijit/dijit.css" rel="stylesheet">
-	<style>
-		.mblTooltip.mblOpener DIV[label='Cancel'] {
-			display: none;
-		}
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async:true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		require([
-			"dojox/mobile",				// This is a mobile app.
-			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
-			"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
-			"dojox/mobile/deviceTheme",	// This mobile app automatically changes it's theme to match devices
-			"dojox/mobile/Opener",
-			"dijit/Calendar"
-		]);
-
-		function getDate2(node, v){
-			if(v === true){ // Done clicked
-				var w = dijit.byId("cal");
-				var date;
-				try {
-					date = w.get("value");
-				} catch (e) {
-					return;
-				}
-				node.value = date;
-			}
-		}
-		function setDate2(node){
-			var v = node.value.split(/-/);
-			if(v.length == 3){
-				var w = dijit.byId("cal");
-				w.setValue(v);
-			}
-		}
-	</script>
-</head>
-<body style="visibility:hidden;">
-	<table cellspacing="20">
-	<tr>
-		<td style="text-align:right;">Date (Calendar)</td>
-		<td><input id="date3" readOnly value=""
-			onclick="dijit.byId('calPicker').show(this, ['above-centered','below-centered','after','before'])"></td>
-	</tr>
-	</table>
-	<div id="calPicker" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getDate2, onShow:setDate2">
-		<h1 dojoType="dojox.mobile.Heading" label="Select a Date">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
-				onclick="dijit.byId('calPicker').hide(true)"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
-				onclick="dijit.byId('calPicker').hide(false)"></div>
-		</h1>
-		<div id="cal" dojoType='dijit.CalendarLite'></div>
-	</div>
-
-</body>
-</html>
diff --git a/dojox/mobile/tests/test_Opener-Calendar-lazy-prog.html b/dojox/mobile/tests/test_Opener-Calendar-lazy-prog.html
new file mode 100644
index 0000000..53ea0b1
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-Calendar-lazy-prog.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>test Opener with Calendar</title>
+
+	<link href="../../../dijit/themes/dijit.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Overlay','Tooltip','dijit.Calendar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"dojo/ready",
+			"dojo/dom-construct",
+			"dojox/mobile",
+			"dojox/mobile/Opener",
+			"dojox/mobile/ToolBarButton",
+			"dojox/mobile/Heading",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser",
+			"dijit/_base/manager" // dijit.byId
+		], function(ready, domConstruct, mobile, Opener, ToolBarButton, Heading, manager){
+			ready(function(){
+				var opener = new Opener({onHide:getDate2, onShow:setDate2, lazy:true}, "calPicker");
+				var headingNode = domConstruct.create("div", {dojoType:"dojox.mobile.Heading", label:"Dates"}, opener.domNode);
+				domConstruct.create("div", {dojoType:"dojox.mobile.ToolBarButton", label:"Done", style:"position:absolute;width:40px;right:0;", onclick:"dijit.byId('calPicker').hide(true)"}, headingNode);
+				domConstruct.create("div", {dojoType:"dojox.mobile.ToolBarButton", label:"Cancel", style:"position:absolute;width:40px;left:0;", onclick:"dijit.byId('calPicker').hide(false)"}, headingNode);
+				domConstruct.create("div", {dojoType:"dijit.CalendarLite", id:"cal"}, opener.domNode);
+			});
+		});
+
+		function getDate2(node, v){
+			if(v === true){ // Done clicked
+				var w = dijit.byId("cal");
+				var date;
+				try {
+					date = w.get("value");
+				} catch (e) {
+					return;
+				}
+				node.value = date;
+			}
+		}
+		function setDate2(node){
+			var v = node.value.split(/-/);
+			if(v.length == 3){
+				var w = dijit.byId("cal");
+				w.setValue(v);
+			}
+		}
+	</script>
+
+	<style>
+		html, body{
+			overflow: hidden;
+		}
+		.mblTooltip.mblOpener DIV[label='Cancel'] {
+			display: none;
+		}
+		.windows_theme .mblToolBarButton {
+			width: 100% !important;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<table cellspacing="20">
+	<tr>
+		<td style="text-align:right;">Date</td>
+		<td><input id="date3" readOnly value=""
+			onclick="dijit.byId('calPicker').show(this, ['above-centered','below-centered','after','before'])"></td>
+	</tr>
+	</table>
+	<div id="calPicker"></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Opener-Calendar-lazy.html b/dojox/mobile/tests/test_Opener-Calendar-lazy.html
new file mode 100644
index 0000000..0047fba
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-Calendar-lazy.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>test Opener with Calendar</title>
+
+	<link href="../../../dijit/themes/dijit.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Overlay','Tooltip','dijit.Calendar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser",
+			"dojox/mobile/Opener",
+			"dijit/_base/manager" // dijit.byId
+		]);
+
+		function getDate2(node, v){
+			if(v === true){ // Done clicked
+				var w = dijit.byId("cal");
+				var date;
+				try {
+					date = w.get("value");
+				} catch (e) {
+					return;
+				}
+				node.value = date;
+			}
+		}
+		function setDate2(node){
+			var v = node.value.split(/-/);
+			if(v.length == 3){
+				var w = dijit.byId("cal");
+				w.setValue(v);
+			}
+		}
+	</script>
+
+	<style>
+		html, body{
+			overflow: hidden;
+		}
+		.mblTooltip.mblOpener DIV[label='Cancel'] {
+			display: none;
+		}
+		.windows_theme .mblToolBarButton {
+			width: 100% !important;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<table cellspacing="20">
+	<tr>
+		<td style="text-align:right;">Date</td>
+		<td><input id="date3" readOnly value=""
+			onclick="dijit.byId('calPicker').show(this, ['above-centered','below-centered','after','before'])"></td>
+	</tr>
+	</table>
+	<div id="calPicker" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getDate2, onShow:setDate2, lazy:true">
+		<h1 dojoType="dojox.mobile.Heading" label="Dates">
+			<span dojoType="dojox.mobile.ToolBarButton" label="Done" style="position:absolute;width:45px;right:0;"
+				onclick="dijit.byId('calPicker').hide(true)"></span>
+			<span dojoType="dojox.mobile.ToolBarButton" label="Cancel" style="position:absolute;width:45px;left:0;"
+				onclick="dijit.byId('calPicker').hide(false)"></span>
+		</h1>
+		<div id="cal" dojoType='dijit.CalendarLite'></div>
+	</div>
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Opener-Calendar.html b/dojox/mobile/tests/test_Opener-Calendar.html
new file mode 100644
index 0000000..36a4f61
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-Calendar.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>test Opener with Calendar</title>
+
+	<link href="../../../dijit/themes/dijit.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Overlay','Tooltip','dijit.Calendar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser",
+			"dojox/mobile/Opener",
+			"dijit/_base/manager", // dijit.byId
+			"dijit/CalendarLite"
+		]);
+
+		function getDate2(node, v){
+			if(v === true){ // Done clicked
+				var w = dijit.byId("cal");
+				var date;
+				try {
+					date = w.get("value");
+				} catch (e) {
+					return;
+				}
+				node.value = date;
+			}
+		}
+		function setDate2(node){
+			var v = node.value.split(/-/);
+			if(v.length == 3){
+				var w = dijit.byId("cal");
+				w.setValue(v);
+			}
+		}
+	</script>
+
+	<style>
+		html, body{
+			overflow: hidden;
+		}
+		.mblTooltip.mblOpener DIV[label='Cancel'] {
+			display: none;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<table cellspacing="20">
+	<tr>
+		<td style="text-align:right;">Date</td>
+		<td><input id="date3" readOnly value=""
+			onclick="dijit.byId('calPicker').show(this, ['above-centered','below-centered','after','before'])"></td>
+	</tr>
+	</table>
+	<div id="calPicker" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getDate2, onShow:setDate2">
+		<h1 dojoType="dojox.mobile.Heading" label="Dates">
+			<span dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
+				onclick="dijit.byId('calPicker').hide(true)"></span>
+			<span dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
+				onclick="dijit.byId('calPicker').hide(false)"></span>
+		</h1>
+		<div id="cal" dojoType='dijit.CalendarLite'></div>
+	</div>
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Opener-ColorPalette-async.html b/dojox/mobile/tests/test_Opener-ColorPalette-async.html
deleted file mode 100644
index cd932c1..0000000
--- a/dojox/mobile/tests/test_Opener-ColorPalette-async.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html style="overflow:hidden;">
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>Test Opener with ColorPalette</title>
-	<link href="../themes/common/dijit/dijit.css" rel="stylesheet">
-	<style>
-		.mblTooltip.mblOpener DIV[label='Cancel'] {
-			display: none;
-		}
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async:true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		require([
-			"dojox/mobile",				// This is a mobile app.
-			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
-			"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
-			"dojox/mobile/deviceTheme",	// This mobile app automatically changes it's theme to match devices
-			"dojox/mobile/Opener",
-			"dijit/ColorPalette"
-		]);
-
-		function getColor1(node, v){
-			if(v === true){ // Done clicked
-				var w = dijit.byId("colorPalette");
-				var color = w.get("value");
-				if(color){
-					node.value = color;
-					node.style.backgroundColor = color;
-					node.style.color =  "#" + ("0" +(255-parseInt(color.substr(1,2), 16)).toString(16)).slice(-2)
-							+ ("0" + (255-parseInt(color.substr(3,2), 16)).toString(16)).slice(-2)
-							+ ("0" + (255-parseInt(color.substr(5,2), 16)).toString(16)).slice(-2);
-				}
-			}
-		}
-	</script>
-</head>
-<body style="visibility:hidden;">
-	<table cellspacing="20">
-	<tr>
-		<td style="text-align:right;">Color (Palette)</td>
-		<td><input id="color1" readOnly value="transparent" style="background-color:transparent;"
-			onclick="dijit.byId('colorPicker1').show(this, ['above-centered','below-centered','after','before'])"></td>
-	</tr>
-	</table>
-
-	<div id="colorPicker1" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getColor1">
-		<h1 dojoType="dojox.mobile.Heading" label="Select a Color">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
-				onclick="dijit.byId('colorPicker1').hide(true)"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
-				onclick="dijit.byId('colorPicker1').hide(false)"></div>
-		</h1>
-		<div id="colorPalette" dojoType='dijit.ColorPalette'></div>
-	</div>
-</body>
-</html>
diff --git a/dojox/mobile/tests/test_Opener-ColorPalette-lazy.html b/dojox/mobile/tests/test_Opener-ColorPalette-lazy.html
new file mode 100644
index 0000000..dbd9c0f
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-ColorPalette-lazy.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Test Opener with ColorPalette</title>
+
+	<link href="../themes/common/dijit/dijit.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Overlay','Tooltip']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser",
+			"dojox/mobile/Opener",
+			"dijit/_base/manager" // dijit.byId
+		]);
+
+		function getColor1(node, v){
+			if(v === true){ // Done clicked
+				var w = dijit.byId("colorPalette");
+				var color = w.get("value");
+				if(color){
+					node.value = color;
+					node.style.backgroundColor = color;
+					node.style.color =  "#" + ("0" +(255-parseInt(color.substr(1,2), 16)).toString(16)).slice(-2)
+							+ ("0" + (255-parseInt(color.substr(3,2), 16)).toString(16)).slice(-2)
+							+ ("0" + (255-parseInt(color.substr(5,2), 16)).toString(16)).slice(-2);
+				}
+			}
+		}
+	</script>
+
+	<style>
+		html, body{
+			overflow: hidden;
+		}
+		.mblTooltip.mblOpener DIV[label='Cancel'] {
+			display: none;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<table cellspacing="20">
+	<tr>
+		<td style="text-align:right;">Color (Palette)</td>
+		<td><input id="color1" readOnly value="transparent" style="background-color:transparent;"
+			onclick="dijit.byId('colorPicker1').show(this, ['above-centered','below-centered','after','before'])"></td>
+	</tr>
+	</table>
+
+	<div id="colorPicker1" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getColor1, lazy:true">
+		<h1 dojoType="dojox.mobile.Heading" label="Select a Color">
+			<span dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
+				onclick="dijit.byId('colorPicker1').hide(true)"></span>
+			<span dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
+				onclick="dijit.byId('colorPicker1').hide(false)"></span>
+		</h1>
+		<div id="colorPalette" dojoType='dijit.ColorPalette'></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Opener-ColorPalette.html b/dojox/mobile/tests/test_Opener-ColorPalette.html
new file mode 100644
index 0000000..9549fcb
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-ColorPalette.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Test Opener with ColorPalette</title>
+
+	<link href="../themes/common/dijit/dijit.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Overlay','Tooltip']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser",
+			"dojox/mobile/Opener",
+			"dijit/_base/manager", // dijit.byId
+			"dijit/ColorPalette"
+		]);
+
+		function getColor1(node, v){
+			if(v === true){ // Done clicked
+				var w = dijit.byId("colorPalette");
+				var color = w.get("value");
+				if(color){
+					node.value = color;
+					node.style.backgroundColor = color;
+					node.style.color =  "#" + ("0" +(255-parseInt(color.substr(1,2), 16)).toString(16)).slice(-2)
+							+ ("0" + (255-parseInt(color.substr(3,2), 16)).toString(16)).slice(-2)
+							+ ("0" + (255-parseInt(color.substr(5,2), 16)).toString(16)).slice(-2);
+				}
+			}
+		}
+	</script>
+
+	<style>
+		html, body{
+			overflow: hidden;
+		}
+		.mblTooltip.mblOpener DIV[label='Cancel'] {
+			display: none;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<table cellspacing="20">
+	<tr>
+		<td style="text-align:right;">Color (Palette)</td>
+		<td><input id="color1" readOnly value="transparent" style="background-color:transparent;"
+			onclick="dijit.byId('colorPicker1').show(this, ['above-centered','below-centered','after','before'])"></td>
+	</tr>
+	</table>
+
+	<div id="colorPicker1" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getColor1">
+		<h1 dojoType="dojox.mobile.Heading" label="Select a Color">
+			<span dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
+				onclick="dijit.byId('colorPicker1').hide(true)"></span>
+			<span dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
+				onclick="dijit.byId('colorPicker1').hide(false)"></span>
+		</h1>
+		<div id="colorPalette" dojoType='dijit.ColorPalette'></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Opener-ColorPicker.html b/dojox/mobile/tests/test_Opener-ColorPicker.html
deleted file mode 100644
index 0250f16..0000000
--- a/dojox/mobile/tests/test_Opener-ColorPicker.html
+++ /dev/null
@@ -1,58 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html style="overflow:hidden;">
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>Test Opener with ColorPicker</title>
-	<link href="../themes/common/dijit/dijit.css" rel="stylesheet">
-	<style>
-		.mblTooltip.mblOpener DIV[label='Cancel'] {
-			display: none;
-		}
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		require([
-			"dojox/mobile",				// This is a mobile app.
-			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
-			"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
-			"dojox/mobile/deviceTheme",	// This mobile app automatically changes it's theme to match devices
-			"dojox/mobile/Opener",
-			"dojox/widget/ColorPicker"
-		]);
-
-		function getColor2(node, v){
-			if(v === true){ // Done clicked
-				var w = dijit.byId("colorPicker");
-				var color = w.get("value");
-				node.value = color;
-				node.style.backgroundColor = color;
-				node.style.color =  "#" + (255-parseInt(color.substr(1,2), 16)).toString(16)
-							+ (255-parseInt(color.substr(3,2), 16)).toString(16)
-							+ (255-parseInt(color.substr(5,2), 16)).toString(16);
-			}
-		}
-	</script>
-</head>
-<body style="visibility:hidden;">
-	<table cellspacing="20">
-	<tr>
-		<td style="text-align:right;">Color (Picker)</td>
-		<td><input id="color2" readOnly value="transparent" style="background-color:transparent;"
-			onclick="dijit.byId('colorPicker2').show(this, ['above-centered','below-centered','after','before'])"></td>
-	</tr>
-	</table>
-
-	<div id="colorPicker2" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getColor2">
-		<h1 dojoType="dojox.mobile.Heading" label="Select a Color">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
-				onclick="dijit.byId('colorPicker2').hide(true)"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
-				onclick="dijit.byId('colorPicker2').hide(false)"></div>
-		</h1>
-		<div id="colorPicker" dojoType='dojox.widget.ColorPicker'></div>
-	</div>
-
-</body>
-</html>
diff --git a/dojox/mobile/tests/test_Opener-DateSpinWheel-async.html b/dojox/mobile/tests/test_Opener-DateSpinWheel-async.html
deleted file mode 100644
index 900ba08..0000000
--- a/dojox/mobile/tests/test_Opener-DateSpinWheel-async.html
+++ /dev/null
@@ -1,63 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html style="overflow:hidden;">
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>Test Opener with DateSpinWheel</title>
-	<link href="../themes/common/SpinWheel.css" rel="stylesheet">
-	<link href="../themes/common/dijit/dijit.css" rel="stylesheet">
-	<style>
-		.mblTooltip.mblOpener DIV[label='Cancel'] {
-			display: none;
-		}
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async:true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		require([
-			"dijit/_base/manager",  // dijit.byId
-			"dojox/mobile",				// This is a mobile app.
-			"dojox/mobile/compat",		// This mobile app supports running on desktop browsers
-			"dojox/mobile/parser",		// This mobile app uses declarative programming with fast mobile parser
-			"dojox/mobile/deviceTheme",	// This mobile app automatically changes it's theme to match devices
-			"dojox/mobile/SpinWheelDatePicker",
-			"dojox/mobile/Opener"
-		]);
-
-		function getDate(node, v){
-			if(v === true){ // Done clicked
-				node.value = dijit.byId("spin1").getValue().join('-');
-			}
-		}
-		function setDate(node){
-			var v = node.value.split(/-/);
-			if(v.length == 3){
-				var w = dijit.byId("spin1");
-				w.setValue(v);
-			}
-		}
-
-
-	</script>
-</head>
-<body style="visibility:hidden;">
-	<table cellspacing="20">
-	<tr>
-		<td style="text-align:right;">Date (SpinWheel)</td>
-		<td><input id="date1" readOnly value=""
-			onclick="dijit.byId('datePicker').show(this, ['above-centered','below-centered','after','before'])"></td>
-	</tr>
-	</table>
-
-	<div id="datePicker" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getDate, onShow:setDate">
- 		<h1 dojoType="dojox.mobile.Heading" label="Date Picker">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
-				onclick="dijit.byId('datePicker').hide(true)"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
-				onclick="dijit.byId('datePicker').hide(false)"></div>
-		</h1>
-		<div id="spin1" dojoType="dojox.mobile.SpinWheelDatePicker"></div>
-	</div>
-
-</body>
-</html>
diff --git a/dojox/mobile/tests/test_Opener-DateSpinWheel-lazy.html b/dojox/mobile/tests/test_Opener-DateSpinWheel-lazy.html
new file mode 100644
index 0000000..b62d49d
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-DateSpinWheel-lazy.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html style="overflow:hidden;">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Test Opener with DateSpinWheel</title>
+
+	<link href="../themes/common/dijit/dijit.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Overlay','Tooltip','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"dijit/_base/manager",  // dijit.byId
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser",
+			"dojox/mobile/Opener"
+		]);
+
+		function getDate(node, v){
+			if(v === true){ // Done clicked
+				node.value = dijit.byId("spin1").get("values").join('-');
+			}
+		}
+		function setDate(node){
+			var v = node.value.split(/-/);
+			if(v.length == 3){
+				var w = dijit.byId("spin1");
+				w.set("values", v);
+			}
+		}
+	</script>
+
+	<style>
+		html, body{
+			overflow: hidden;
+		}
+		.mblTooltip.mblOpener DIV[label='Cancel'] {
+			display: none;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<table cellspacing="20">
+	<tr>
+		<td style="text-align:right;">Date</td>
+		<td><input id="date1" readOnly value=""
+			onclick="dijit.byId('datePicker').show(this, ['above-centered','below-centered','after','before'])"></td>
+	</tr>
+	</table>
+
+	<div id="datePicker" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getDate, onShow:setDate, lazy:true">
+ 		<h1 dojoType="dojox.mobile.Heading" label="Date Picker">
+			<span dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
+				onclick="dijit.byId('datePicker').hide(true)"></span>
+			<span dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
+				onclick="dijit.byId('datePicker').hide(false)"></span>
+		</h1>
+		<div id="spin1" dojoType="dojox.mobile.SpinWheelDatePicker"></div>
+	</div>
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Opener-DateSpinWheel.html b/dojox/mobile/tests/test_Opener-DateSpinWheel.html
new file mode 100644
index 0000000..60d7dcf
--- /dev/null
+++ b/dojox/mobile/tests/test_Opener-DateSpinWheel.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html style="overflow:hidden;">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Test Opener with DateSpinWheel</title>
+
+	<link href="../themes/common/dijit/dijit.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Overlay','Tooltip','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		require([
+			"dijit/_base/manager",  // dijit.byId
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/parser",
+			"dojox/mobile/Opener",
+			"dojox/mobile/SpinWheelDatePicker"
+		]);
+
+		function getDate(node, v){
+			if(v === true){ // Done clicked
+				node.value = dijit.byId("spin1").get("values").join('-');
+			}
+		}
+		function setDate(node){
+			var v = node.value.split(/-/);
+			if(v.length == 3){
+				var w = dijit.byId("spin1");
+				w.set("values", v);
+			}
+		}
+	</script>
+
+	<style>
+		html, body{
+			overflow: hidden;
+		}
+		.mblTooltip.mblOpener DIV[label='Cancel'] {
+			display: none;
+		}
+		.windows_theme .mblToolBarButton {
+			width: 100% !important;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<table cellspacing="20">
+	<tr>
+		<td style="text-align:right;">Date</td>
+		<td><input id="date1" readOnly value=""
+			onclick="dijit.byId('datePicker').show(this, ['above-centered','below-centered','after','before'])"></td>
+	</tr>
+	</table>
+
+	<div id="datePicker" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getDate, onShow:setDate">
+ 		<h1 dojoType="dojox.mobile.Heading" label="Date Picker">
+			<span dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
+				onclick="dijit.byId('datePicker').hide(true)"></span>
+			<span dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
+				onclick="dijit.byId('datePicker').hide(false)"></span>
+		</h1>
+		<div id="spin1" dojoType="dojox.mobile.SpinWheelDatePicker"></div>
+	</div>
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Opener-RoundSelectList-async.html b/dojox/mobile/tests/test_Opener-RoundSelectList-async.html
index b791267..16d72a2 100644
--- a/dojox/mobile/tests/test_Opener-RoundSelectList-async.html
+++ b/dojox/mobile/tests/test_Opener-RoundSelectList-async.html
@@ -15,7 +15,7 @@
 			height: 200px;
 		}
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, async: true"></script>
 
 	<script type="text/javascript">
 		var ringtone, listPicker, trim;
@@ -69,10 +69,10 @@
 	<!-- override user's custom z-index --> 
 	<div id="listPicker" style="z-index:10000;" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getSelectedRingtone, onShow:setSelectedRingtone, onBlur:function(){ return true; }">
 		<h1 id="header1" dojoType="dojox.mobile.Heading" label="Ringtone">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
-				onclick="listPicker.hide(true)"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
-				onclick="listPicker.hide(false)"></div>
+			<span dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
+				onclick="listPicker.hide(true)"></span>
+			<span dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
+				onclick="listPicker.hide(false)"></span>
 		</h1>
 		<div dojoType="dojox.mobile.ScrollableView" selected="true" height="auto">
 			<ul id="list1" dojoType="dojox.mobile.RoundRectList" select="single" data-dojo-props="onCheckStateChanged:onCheck">
diff --git a/dojox/mobile/tests/test_Opener-SearchList-async.html b/dojox/mobile/tests/test_Opener-SearchList-async.html
index 0954ebd..b16c6e6 100644
--- a/dojox/mobile/tests/test_Opener-SearchList-async.html
+++ b/dojox/mobile/tests/test_Opener-SearchList-async.html
@@ -5,8 +5,7 @@
 	<meta name="apple-mobile-web-app-capable" content="yes" />
 	<title>Opener-SearchList</title>
 	<style>
-		.mblTooltip.mblOpener DIV[label='Done'],
-		.mblTooltip.mblOpener DIV[label='Cancel'] {
+		.mblTooltip.mblOpener .mblToolBarButton {
 			display: none;
 		}
 		#search1 {
@@ -21,7 +20,7 @@
 			height: 200px;
 		}
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, async:true"></script>
 
 	<script language="JavaScript" type="text/javascript">
 		require([
@@ -68,10 +67,10 @@
 
 	<div id="listPicker" data-dojo-type="dojox.mobile.Opener" data-dojo-props="onHide:getSelectedContact, onShow:setSearch">
 		<h1 dojoType="dojox.mobile.Heading" label="">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
-				onclick="dijit.byId('listPicker').hide(true)"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
-				onclick="dijit.byId('listPicker').hide(false)"></div>
+			<span dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="position:absolute;width:45px;right:0;"
+				onclick="dijit.byId('listPicker').hide(true)"></span>
+			<span dojoType="dojox.mobile.ToolBarButton" label="Cancel" class="mblColorBlue" style="position:absolute;width:45px;left:0;"
+				onclick="dijit.byId('listPicker').hide(false)"></span>
 			<input id="search1" type="search" results="5" autosave="myrecentcontactsearches" name="searchContacts" placeholder="Search" />
 		</h1>
 		<div dojoType="dojox.mobile.ScrollableView" selected="true" height="auto">
diff --git a/dojox/mobile/tests/test_Overlay.html b/dojox/mobile/tests/test_Overlay.html
index dcf3167..95ab40a 100644
--- a/dojox/mobile/tests/test_Overlay.html
+++ b/dojox/mobile/tests/test_Overlay.html
@@ -1,86 +1,88 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>test Overlay</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<style>
-		#spin1 {
-			width: 304px;
-			margin: 10px auto;
- 		}
-		#pt {
-			width: 20px;
-			background-color: #C4C9DB;
-			opacity: 0.2;
-		}
-		#txt {
-			width: 10px;
-			margin-left: -15px;
-			padding-top: 85px;
-			font-size: 24px;
-			font-weight: bold;
-			border: none;
-		}
-		</style>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+	<title>test Overlay</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile.deviceTheme");
-		</script>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Overlay','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.Overlay");
-			dojo.require("dojox.mobile.SpinWheel");
-			dojo.require("dojox.mobile.SpinWheelSlot");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<br>
-		<button onclick="dijit.byId('customPicker').show()">pop up</button>
-		<button onclick="dijit.byId('customPicker').hide()">pop down</button>
-		<div id="customPicker" dojoType="dojox.mobile.Overlay">
-			<h1 dojoType="dojox.mobile.Heading" label="Custom Picker">
-				<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;" onClick="dijit.byId('customPicker').hide()"></div>
-			</h1>
-			<div id="spin1" dojoType="dojox.mobile.SpinWheel">
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="['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']"
-					style="text-align:center;width:40px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labelFrom="3000" labelTo="3100"
-					style="width:70px;"></div>
-				<div id="pt" class="mblSpinWheelSlot"></div>
-				<div id="txt" class="mblSpinWheelSlot">.</div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labelFrom="0" labelTo="9"
-					style="width:30px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="['pt','px','cm']"
-					style="width:50px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="[
-						'<img src=images/i-icon-1.png>',
-						'<img src=images/i-icon-2.png>',
-						'<img src=images/i-icon-3.png>',
-						'<img src=images/i-icon-4.png>',
-						'<img src=images/i-icon-5.png>',
-						'<img src=images/i-icon-6.png>',
-						'<img src=images/i-icon-7.png>',
-						'<img src=images/i-icon-8.png>',
-						'<img src=images/i-icon-9.png>',
-						'<img src=images/i-icon-10.png>'
-					]"
-					style="width:70px;text-align: center;"></div>
-			</div>
+	<script type="text/javascript">
+		require([
+			"dijit/_base/manager",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/Overlay",
+			"dojox/mobile/SpinWheel",
+			"dojox/mobile/compat"
+		]);
+	</script>
+
+	<style>
+	#spin1 {
+		width: 304px;
+		margin: 10px auto;
+	}
+	#pt {
+		width: 20px;
+		background-color: #C4C9DB;
+		opacity: 0.2;
+	}
+	#txt {
+		width: 10px;
+		margin-left: -15px;
+		padding-top: 85px;
+		font-size: 24px;
+		font-weight: bold;
+		border: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<br>
+	<button onclick="dijit.byId('customPicker').show()">pop up</button>
+	<button onclick="dijit.byId('customPicker').hide()">pop down</button>
+	<div id="customPicker" data-dojo-type="dojox.mobile.Overlay">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Custom Picker"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"  data-dojo-props='label:"Done"' class="mblColorBlue" style="width:45px;float:right;" onClick="dijit.byId('customPicker').hide()"></span>
+		</h1>
+		<div id="spin1" data-dojo-type="dojox.mobile.SpinWheel">
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props='labelFrom:3000, labelTo:3100'
+				style="width:70px;"></div>
+			<div id="pt" class="mblSpinWheelSlot"></div>
+			<div id="txt" class="mblSpinWheelSlot">.</div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:30px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:['pt','px','cm']"
+				style="width:50px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:[
+					'<img src=images/i-icon-1.png>',
+					'<img src=images/i-icon-2.png>',
+					'<img src=images/i-icon-3.png>',
+					'<img src=images/i-icon-4.png>',
+					'<img src=images/i-icon-5.png>',
+					'<img src=images/i-icon-6.png>',
+					'<img src=images/i-icon-7.png>',
+					'<img src=images/i-icon-8.png>',
+					'<img src=images/i-icon-9.png>',
+					'<img src=images/i-icon-10.png>'
+				]"
+				style="width:70px;text-align: center;"></div>
 		</div>
-		<div style="height:2500px;border:0px solid red;"></div>
-		<button onclick="dijit.byId('customPicker').show()">pop up</button>
-		<button onclick="dijit.byId('customPicker').hide()">pop down</button>
-		<br>
-		<br>
-	</body>
+	</div>
+	<div style="height:2500px;border:0px solid red;"></div>
+	<button onclick="dijit.byId('customPicker').show()">pop up</button>
+	<button onclick="dijit.byId('customPicker').hide()">pop down</button>
+	<br>
+	<br>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_ProgressBar.html b/dojox/mobile/tests/test_ProgressBar.html
new file mode 100644
index 0000000..b14cbfb
--- /dev/null
+++ b/dojox/mobile/tests/test_ProgressBar.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ProgressBar</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ProgressBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ProgressBar"
+		], function(connect, dom, domClass, ready, registry){
+			update = function(v){
+				var prog1 = registry.byId("prog1");
+				prog1.set("value", v);
+				prog1.set("label", v);
+			};
+			onChange = function(value, max, percent){
+				var msg = percent + "% " + value + "/" + max;
+				dom.byId("statusMsg").innerHTML = msg;
+			};
+			ready(function(){
+				var prog1 = registry.byId("prog1");
+				var v = 0;
+				var timer = setInterval(function(){
+					prog1.set("value", v);
+					prog1.set("label", v);
+					if(v >= 200){ clearTimeout(timer); }
+					v += 40;
+				}, 1000);
+			});
+		});
+	</script>
+	<style>
+#statusMsg {
+	color: #adaead;
+	font-family: Helvetica;
+	font-size: 14px;
+	font-weight: bold;
+	margin-top: 4px;
+}
+	</style>
+</head>
+<body style="visibility:hidden;xbackground-color:#212021;padding:10px;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<div id="prog1" data-dojo-type="dojox.mobile.ProgressBar"
+		     data-dojo-props='maximum:200, onChange:onChange'
+		     style="width:275px"></div>
+		<div id="statusMsg"></div>
+	</div>
+	<input type="button" onclick="update('0')" value="0">
+	<input type="button" onclick="update('70')" value="70">
+	<input type="button" onclick="update('100')" value="100">
+	<input type="button" onclick="update('200')" value="200">
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ProgressIndicator-color.html b/dojox/mobile/tests/test_ProgressIndicator-color.html
new file mode 100644
index 0000000..b2d3b4c
--- /dev/null
+++ b/dojox/mobile/tests/test_ProgressIndicator-color.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Progress Indicator - color</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<style>
+		.mblProgPink .mblProg0Color {
+		  background-color: rgba(255,0,255,0.1);
+		}
+		.mblProgPink .mblProg1Color {
+		  background-color: rgba(255,0,255,0.1);
+		}
+		.mblProgPink .mblProg2Color {
+		  background-color: rgba(255,0,255,0.1);
+		}
+		.mblProgPink .mblProg3Color {
+		  background-color: rgba(255,0,255,0.1);
+		}
+		.mblProgPink .mblProg4Color {
+		  background-color: rgba(255,0,255,0.1);
+		}
+		.mblProgPink .mblProg5Color {
+		  background-color: rgba(255,0,255,0.1);
+		}
+		.mblProgPink .mblProg6Color {
+		  background-color: rgba(255,0,255,0.2);
+		}
+		.mblProgPink .mblProg7Color {
+		  background-color: rgba(255,0,255,0.3);
+		}
+		.mblProgPink .mblProg8Color {
+		  background-color: rgba(255,0,255,0.4);
+		}
+		.mblProgPink .mblProg9Color {
+		  background-color: rgba(255,0,255,0.5);
+		}
+		.mblProgPink .mblProg10Color {
+		  background-color: rgba(255,0,255,0.6);
+		}
+		.mblProgPink .mblProg11Color {
+		  background-color: rgba(255,0,255,1);
+		}
+	</style>
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.ProgressIndicator" startSpinning="true" size="120" center="false"></div>
+	<div data-dojo-type="dojox.mobile.ProgressIndicator" startSpinning="true" size="120" center="false" class="mblProgWhite"></div>
+	<div data-dojo-type="dojox.mobile.ProgressIndicator" startSpinning="true" size="120" center="false" class="mblProgPink"></div>
+	<div data-dojo-type="dojox.mobile.ProgressIndicator" startSpinning="true" size="120" center="false"
+	     colors="['red','yellow','pink','orange','green','magenta','cyan','black','white','blue','gray','lightgreen']"></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ProgressIndicator-heading.html b/dojox/mobile/tests/test_ProgressIndicator-heading.html
new file mode 100644
index 0000000..55a4d0d
--- /dev/null
+++ b/dojox/mobile/tests/test_ProgressIndicator-heading.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Progress Indicator on Heading</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ProgressIndicator",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(domClass, ready, registry, ProgressIndicator){
+			ready(function(){
+				var prog1 = new ProgressIndicator({size:30, center:false});
+				prog1.domNode.style.position = "absolute";
+				prog1.domNode.style.margin = "5px";
+				domClass.add(prog1.domNode, "mblProgWhite");
+				var head1 = registry.byId("head1");
+				prog1.placeAt(head1.domNode);
+				prog1.start();
+				setTimeout(function(){ // network latency simulation
+					prog1.stop();
+					head1.set("label", "Done");
+				}, 5000);
+
+				var prog2 = new ProgressIndicator({size:30, center:false});
+				prog2.domNode.style.position = "absolute";
+				prog2.domNode.style.margin = "5px";
+				prog2.domNode.style.right = "0px";
+				domClass.add(prog2.domNode, "mblProgWhite");
+				var head2 = registry.byId("head2");
+				prog2.placeAt(head2.domNode);
+				prog2.start();
+				setTimeout(function(){ // network latency simulation
+					prog2.stop();
+					head2.set("label", "Done");
+				}, 5000);
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<h1 id="head1" data-dojo-type="dojox.mobile.Heading">Loading...</h1>
+	 	<br><br>
+		<h1 id="head2" data-dojo-type="dojox.mobile.Heading">Loading...</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ProgressIndicator-list.html b/dojox/mobile/tests/test_ProgressIndicator-list.html
new file mode 100644
index 0000000..2052a31
--- /dev/null
+++ b/dojox/mobile/tests/test_ProgressIndicator-list.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Progress Indicator on ListItem</title>
+
+	<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ProgressIndicator",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(domClass, ready, registry, ProgressIndicator){
+			ready(function(){
+				var item4 = registry.byId("item4");
+				item4.set("busy", true);
+				setTimeout(function(){ // network latency simulation
+					item4.set("busy", false);
+				}, 5000);
+			});
+		});
+	</script>
+
+	<style>
+	.mblListItem {
+		font-weight: normal;
+		font-size: 12px;
+	}
+	.subject {
+		font: bold 16px Helvetica;
+	}
+	#item4 {
+		padding-top: 30px;
+		padding-bottom: 30px;
+	}
+	.loading1 {
+		font: bold 18px Helvetica;
+		color: gray;
+	}
+	.loading2 {
+		font: bold 14px Helvetica;
+		color: gray;
+	}
+	.textBox {
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='icon:"mblDomButtonBlueBall", moveTo:"#", variableHeight:true'>
+				<div class="textBox">
+					<div class="subject">Dojo: Traditional Karate-do Spirit</div>
+					Sarah Connor Hardcover<br>
+					Eligible for FREE Super Saver Shipping<br>
+					<span style="color:red">$14.50 (50%)</span> In Stock
+				</div>
+			</li>
+			<li id="item2" data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='icon:"mblDomButtonBlueBall", moveTo:"#", variableHeight:true'>
+				<div class="textBox">
+					<div class="subject">Japanese Martial Arts Dojo</div>
+					Martin Parker Hardcover<br>
+					<span style="color:red">$14.00 (60%)</span> In Stock
+				</div>
+			</li>
+			<li id="item3" data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='icon:"mblDomButtonBlueBall", moveTo:"#", variableHeight:true'>
+				<div class="textBox">
+					<div class="subject">Total Solar Eclipse</div>
+					Steven Young Hardcover<br>
+					Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+					Eligible for FREE Super Saver Shipping<br>
+					<span style="color:red">$9.50 (62%)</span> In Stock
+				</div>
+			</li>
+			<li id="item4" data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='icon:"mblDomButtonBlueBall", moveTo:"#", variableHeight:true'>
+				<div class="textBox">
+					<div class="loading1">Loading More Items...</div>
+					<div class="loading2">more than 45 items</div>
+				</div>
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ProgressIndicator-size.html b/dojox/mobile/tests/test_ProgressIndicator-size.html
new file mode 100644
index 0000000..c27bfe4
--- /dev/null
+++ b/dojox/mobile/tests/test_ProgressIndicator-size.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Progress Indicator - size</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/window",
+			"dojo/ready",
+			"dojox/mobile/ProgressIndicator",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(win, ready, ProgressIndicator){
+			ready(function(){
+				var prog1 = new ProgressIndicator({size:80, center:false});
+				win.body().appendChild(prog1.domNode);
+				prog1.start();
+
+				var prog2 = new ProgressIndicator({size:40, center:false});
+				win.body().appendChild(prog2.domNode);
+				prog2.start();
+
+				var prog3 = new ProgressIndicator({size:20, center:false});
+				win.body().appendChild(prog3.domNode);
+				prog3.start();
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+<div data-dojo-type="dojox.mobile.ProgressIndicator" startSpinning="true" size="120" center="false"></div>
+<div data-dojo-type="dojox.mobile.ProgressIndicator" startSpinning="true"></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ProgressIndicator.html b/dojox/mobile/tests/test_ProgressIndicator.html
new file mode 100644
index 0000000..d1a1adf
--- /dev/null
+++ b/dojox/mobile/tests/test_ProgressIndicator.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Progress Indicator</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/dom",
+			"dojox/mobile/parser",
+			"dojox/mobile/ProgressIndicator",
+			"dojox/mobile",
+			"dojox/mobile/bookmarkable",
+			"dojox/mobile/compat"
+		], function(declare, dom, parser, ProgressIndicator){
+			function loadPage(moveTo){
+				if(!(moveTo.match(/#(\w+)/))){ return; }
+				moveTo.match(/#(\w+)(.*)/);
+				var id = RegExp.$1;
+				var param = RegExp.$2;
+				if(!param){ return; }
+				var container = dom.byId(id);
+				container.innerHTML = "";
+				var prog = ProgressIndicator.getInstance();
+				container.appendChild(prog.domNode);
+				prog.start();
+				setTimeout(function(){ // network latency simulation
+					prog.stop();
+					container.innerHTML = '<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props=\'back:"Home", moveTo:"#home"\'>'+param+'</h1>\n'+param;
+					parser.parse(container);
+				}, 5000);
+			}
+			dojox.mobile.ViewEx = declare(
+				"dojox.mobile.ViewEx",
+				dojox.mobile.View,
+			{
+				onStartView: function(){
+					loadPage(location.hash);
+				},
+				onBeforeTransitionIn: function(moveTo, dir, transition, context, method){
+					loadPage("#"+moveTo);
+				}
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<h1 data-dojo-type="dojox.mobile.Heading">Progress Indicator</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">External Documents</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#view2?myParam=0001"'>
+				Document 0001
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#view2?myParam=0002"'>
+				Document 0002
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#view2?myParam=0003"'>
+				Document 0003
+			</li>
+		</ul>
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			A progress indicator shows up about 5 seconds before a view content is displayed.
+			After you move to other views, you should also be able to navigate through the views with browser's back and forward buttons. Also, views should be bookmarkable. Note that you can pass parameters (e.g. ?myParam=001) to a destination view.
+		</div>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ViewEx"></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Rating-prog.html b/dojox/mobile/tests/test_Rating-prog.html
new file mode 100644
index 0000000..22b8947
--- /dev/null
+++ b/dojox/mobile/tests/test_Rating-prog.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Rating</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base'],mblUserAgent:'iPhone'"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dojo/_base/window",
+			"dojox/mobile/Rating",
+			"dojox/mobile"
+		], function(ready, win, Rating){
+			ready(function(){
+				var widget = new Rating({
+					image: "images/star-orange.png",
+					numStars: 10,
+					value: 5.5
+				});
+				win.body().appendChild(widget.domNode);
+			});
+		});
+	</script>
+</head>
+<body>
+<h3>Programmatic Example</h3>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Rating-setter.html b/dojox/mobile/tests/test_Rating-setter.html
new file mode 100644
index 0000000..02bf309
--- /dev/null
+++ b/dojox/mobile/tests/test_Rating-setter.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Rating</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base'],mblUserAgent:'iPhone'"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		var val = 0;
+		require([
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Rating"
+		], function(registry){
+			increment = function(){
+				if(val == 7){ return; }
+				val += 0.5;
+				registry.byId("star").set("value", val);
+				document.getElementById("value").innerHTML = val;
+			};
+			decrement = function(){
+				if(val == 0){ return; }
+				val -= 0.5;
+				registry.byId("star").set("value", val);
+				document.getElementById("value").innerHTML = val;
+			};
+		});
+	</script>
+	<style>
+	button {
+		width: 100px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<span id="star" data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",numStars:7'></span>
+	<span id="value">0</span><br>
+	<button type="button" onclick="decrement()">−</button>
+	<button type="button" onclick="increment()">+</button>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Rating.html b/dojox/mobile/tests/test_Rating.html
new file mode 100644
index 0000000..4c46e67
--- /dev/null
+++ b/dojox/mobile/tests/test_Rating.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Rating</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base'],mblUserAgent:'iPhone'"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Rating"
+		]);
+	</script>
+	<style>
+	.group {
+		margin: 20px;
+		padding: 10px;
+		border: 1px solid gray;
+		border-radius: 6px;
+	}
+	.group2 .mblRating .mblSpriteIconParent {
+		-webkit-box-reflect: below 0 -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,0)), color-stop(0.1, rgba(0,0,0,0)), to(rgba(0,0,0,0.3)));
+	}
+	.group3 {
+	}
+	.group4 {
+		background-color: black;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;background-color:white;">
+	<div class="group group1">
+		Rating is <span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",value:0'></span> 0<br>
+		Rating is <span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",value:0.5'></span> 0.5<br>
+		Rating is <span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",value:1'></span> 1<br>
+		Rating is <span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",value:1.5'></span> 1.5<br>
+		Rating is <span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",value:2'></span> 2<br>
+		Rating is <span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",value:5'></span> 5<br>
+	</div>
+
+	<div class="group group2">
+		Rating is <span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",numStars:3,value:0'></span> 0<br>
+		Rating is <span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",numStars:3,value:0.5'></span> 0.5<br>
+		Rating is <span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",numStars:3,value:1'></span> 1<br>
+		Rating is <span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",numStars:3,value:1.5'></span> 1.5<br>
+		Rating is <span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",numStars:3,value:3'></span> 3<br>
+	</div>
+
+	<div class="group group3">
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-yellow.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-green.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-blue.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-2.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-3.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-4.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-5.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-6.png",numStars:5,value:2.5'></span><br>
+	</div>
+
+	<div class="group group4">
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-orange.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-yellow.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-green.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-blue.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-2.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-3.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-4.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-5.png",numStars:5,value:2.5'></span><br>
+		<span data-dojo-type="dojox.mobile.Rating" data-dojo-props='image:"images/star-6.png",numStars:5,value:2.5'></span><br>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRect.html b/dojox/mobile/tests/test_RoundRect.html
new file mode 100644
index 0000000..bf37cab
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRect.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Round Rect</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Round Rectangle</h2>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			This module provides some widgets that can be used to build web-based
+			applications for mobile devices such as iPhone or Android.
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRectCategory.html b/dojox/mobile/tests/test_RoundRectCategory.html
new file mode 100644
index 0000000..6cc818f
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectCategory.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Round Rectangle Category</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="settings" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Round Rectangle List</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">J</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Jack Coleman
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				James Evans
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Jason Griffin
+			</li>
+		</ul>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">K</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Karen Hughes
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Kelly Perry
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Kevin Rivera
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRectDataList.html b/dojox/mobile/tests/test_RoundRectDataList.html
index ba27d5a..f843215 100644
--- a/dojox/mobile/tests/test_RoundRectDataList.html
+++ b/dojox/mobile/tests/test_RoundRectDataList.html
@@ -1,20 +1,24 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>RoundRectDataList</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.data.ItemFileWriteStore");
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.RoundRectDataList");
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectDataList</title>
 
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dojo/data/ItemFileWriteStore",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/RoundRectDataList"
+		], function(lang, ItemFileWriteStore, registry){
 			var static_data = { 
 				items: [ 
 					{label: "Apple", 	moveTo: "dummy"},
@@ -28,40 +32,49 @@
 					{label: "Peach", 	moveTo: "dummy"}
 				]
 			};
-			var store1 = new dojo.data.ItemFileWriteStore({url: "settings.json", clearOnClose: true});
-			var store2 = new dojo.data.ItemFileWriteStore({data: dojo.clone(static_data)});
-			var store = store1;
+			store1 = new ItemFileWriteStore({url: "data/settings.json", clearOnClose: true});
+			store2 = new ItemFileWriteStore({data: lang.clone(static_data), clearOnClose: true});
+			store = store1;
 			var newItems = [[],[]];
 
 			// switch to the selected store
-			function switchTo(store){
+			switchTo = function(store){
 				window.store = store;
-				dijit.byId("list").setStore(store);
-			}
+				registry.byId("list").setStore(store);
+			};
 			// add a new item
-			function add1(){
+			add1 = function(){
 				var item = store.newItem({label: "New Item", moveTo: "dummy"});
-				this.newItems[(store == store1) ? 1 : 0].push(item);
-			}
+				newItems[(store == store1) ? 1 : 0].push(item);
+			};
 			// delete the added item
-			function delete1(){
-				var item = this.newItems[(store == store1) ? 1 : 0].pop();
+			delete1 = function(){
+				var item = newItems[(store == store1) ? 1 : 0].pop();
 				if(item){
 					store.deleteItem(item);
 				}
-			}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">RoundRectDataList</h1>
-			<ul dojoType="dojox.mobile.RoundRectDataList" id="list" store="store" query="{label: '*'}"></ul>
-			<p>show the different set:<br>
-			<input type="button" value="Set1" onclick="switchTo(store1)">
-			<input type="button" value="Set2" onclick="switchTo(store2)">
-			<p>alter the object store:<br>
-			<input type="button" value="Add" onclick="add1()">
-			<input type="button" value="Delete" onclick="delete1()">
-		</div>
-	</body>
+			};
+			reload1 = function(){
+				store.save({onComplete: function(){console.log("Saved");}, onError: function(e){console.log(e);}});
+				if(store === store2){
+					store.data = lang.clone(static_data);
+				}
+				store.close();
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">RoundRectDataList</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectDataList" id="list" data-dojo-props='store:store, query:{label: "*"}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+		<input type="button" value="Reload" onclick="reload1()">
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_RoundRectList-check.html b/dojox/mobile/tests/test_RoundRectList-check.html
index 7e8eefc..4bed3e9 100644
--- a/dojox/mobile/tests/test_RoundRectList-check.html
+++ b/dojox/mobile/tests/test_RoundRectList-check.html
@@ -1,65 +1,76 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Selectable Round Rect List</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			function check(){
-				dijit.byId("item1").set("checked", true);
-			}
-			function uncheck(){
-				dijit.byId("item1").set("checked", false);
-			}
-			function callback(item, state){
-				var span = dojo.byId("msgArea");
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Selectable RoundRectDataList</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, dom, ready, registry){
+			check = function(){
+				registry.byId("item1").set("checked", true);
+			};
+			uncheck = function(){
+				registry.byId("item1").set("checked", false);
+			};
+			callback = function(item, state){
+				var span = dom.byId("msgArea");
 				span.innerHTML += "onCheckStateChanged: "+item.labelNode.innerHTML+", "+state+"<br>";
 				setTimeout(function(){
 					span.innerHTML = "";
 				}, 1000);
-			}
-			dojo.addOnLoad(function(){
-				dojo.connect(dijit.byId("list1"), "onCheckStateChanged", null, callback);
-				dojo.connect(dijit.byId("list2"), "onCheckStateChanged", null, callback);
+			};
+			ready(function(){
+				connect.connect(registry.byId("list1"), "onCheckStateChanged", null, callback);
+				connect.connect(registry.byId("list2"), "onCheckStateChanged", null, callback);
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Selectable List</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Single Select</h2>
-			<ul id="list1" dojoType="dojox.mobile.RoundRectList" select="single">
-				<li id="item1" dojoType="dojox.mobile.ListItem" checked="true">
-					Cube
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Ripple
-				</li>
-			</ul>
-			<input type="button" onclick="check()" value="check">
-			<input type="button" onclick="uncheck()" value="uncheck">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Multiple Select</h2>
-			<ul id="list2" dojoType="dojox.mobile.RoundRectList" select="multiple">
-				<li dojoType="dojox.mobile.ListItem" checked="true">
-					Cube
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Ripple
-				</li>
-			</ul>
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Selectable List</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Single Select</h2>
+		<ul id="list1" data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"single"'>
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true'>
+				Cube
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Dissolve
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Ripple
+			</li>
+		</ul>
+		<input type="button" onclick="check()" value="check">
+		<input type="button" onclick="uncheck()" value="uncheck">
+
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Multiple Select</h2>
+		<ul id="list2" data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"multiple"'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true'>
+				Cube
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Dissolve
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Ripple
+			</li>
+		</ul>
 
-			<div id="msgArea" style="margin-left:10px;"></div><br><br>
-		</div>
-	</body>
+		<div id="msgArea" style="margin-left:10px;"></div><br><br>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_RoundRectList-connect.html b/dojox/mobile/tests/test_RoundRectList-connect.html
new file mode 100644
index 0000000..08e99f1
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectList-connect.html
@@ -0,0 +1,136 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectList - connect</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedCircleMinus.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonGrayKnob.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom-class",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, domClass, dom, ready, registry){
+			var delItem, handler, btn1, list1;
+
+			function showDeleteButton(item){
+				hideDeleteButton();
+				delItem = item;
+				item.rightIconNode.style.display = "none";
+				if(!item.rightIcon2Node){
+					item.set("rightIcon2", "mblDomButtonMyRedButton_0");
+					item.rightIcon2Node.firstChild.innerHTML = "Delete";
+				}
+				item.rightIcon2Node.style.display = "";
+				handler = connect.connect(list1.domNode, "onclick", onClick);
+			}
+
+			function hideDeleteButton(){
+				if(delItem){
+					delItem.rightIconNode.style.display = "";
+					delItem.rightIcon2Node.style.display = "none";
+					delItem = null;
+				}
+				connect.disconnect(handler);
+			}
+
+			function onClick(e){
+				var item = registry.getEnclosingWidget(e.target);
+				if(domClass.contains(e.target, "mblDomButtonMyRedButton_0")){
+					setTimeout(function(){
+						item.destroy();
+					}, 0);
+				}
+				hideDeleteButton();
+			}
+
+			connect.subscribe("/dojox/mobile/deleteListItem", function(item){
+				showDeleteButton(item);
+			});
+
+			
+			edit = function(){
+				var flag = btn1._flag = !btn1._flag; // true: editable
+				if(flag){
+					list1.startEdit();
+					btn1.set("label", "Done");
+				}else{
+					hideDeleteButton();
+					list1.endEdit();
+					btn1.set("label", "Edit");
+				}
+			}
+			
+			ready(function(){
+				btn1 = registry.byId("btn1");
+				list1 = registry.byId("list1");
+				connect.connect(list1, "onStartEdit", null, function(){
+					dom.byId("msgArea1").innerHTML = "Start editing...";
+				});
+				connect.connect(list1, "onMoveItem", null, function(widget, from, to){
+					dom.byId("msgArea2").innerHTML += "MoveItem: " + widget.label + " (" + from + " -> " + to + ") ";
+				});
+				connect.connect(list1, "onDeleteItem", null, function(widget){
+					dom.byId("msgArea3").innerHTML = "DeleteItem: " + widget.label;
+				});
+				connect.connect(list1, "onEndEdit", null, function(){
+					dom.byId("msgArea4").innerHTML = "End editing !";
+				});
+			});
+		});
+	</script>
+
+	<style>
+	/* inline custom DOM Button */
+	.mblDomButtonMyRedButton_0 {
+		position: relative;
+		height: 29px;
+		line-height: 29px;
+		padding: 0px 8px;
+		color: white;
+		font-family: Helvetica;
+		font-size: 13px;
+		font-weight: bold;
+		border: 1px outset #9cacc0;
+		border-radius: 5px;
+		background: -webkit-gradient(linear, left top, left bottom, from(#d3656d), to(#bc1320), color-stop(0.5, #c9404b), color-stop(0.5, #bc1421));
+		background-color: #c9404b;
+		text-align: center;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"RoundRectList - Connect"'>
+			<span id="btn1" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='toggle:true' style="padding: 0px 14px;float:left" onclick="edit">Edit</span>
+		</div>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul id="list1" data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='editable:true'>
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", label:"Item 1"'></li>
+			<li id="item2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", label:"Item 2"'></li>
+			<li id="item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", label:"Item 3"'></li>
+			<li id="item4" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", label:"Item 4"'></li>
+			<li id="item5" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", label:"Item 5"'></li>
+			<li id="item6" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 6"'></li>
+			<li id="item7" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 7"'></li>
+			<li id="item8" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 8"'></li>
+		</ul>
+			
+		<div id="msgArea1" style="margin-top:10px; margin-left:10px;"></div>
+		<div id="msgArea2" style="margin-top:10px; margin-left:10px;"></div>
+		<div id="msgArea3" style="margin-top:10px; margin-left:10px;"></div>
+		<div id="msgArea4" style="margin-top:10px; margin-left:10px;"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRectList-editable-sv.html b/dojox/mobile/tests/test_RoundRectList-editable-sv.html
new file mode 100644
index 0000000..75c969f
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectList-editable-sv.html
@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectList - editable</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedCircleMinus.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonGrayKnob.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		], function(connect, domClass, ready, registry){
+			var delItem, handler, btn1, list1;
+
+			function showDeleteButton(item){
+				hideDeleteButton();
+				delItem = item;
+				item.rightIconNode.style.display = "none";
+				if(!item.rightIcon2Node){
+					item.set("rightIcon2", "mblDomButtonMyRedButton_0");
+					item.rightIcon2Node.firstChild.innerHTML = "Delete";
+				}
+				item.rightIcon2Node.style.display = "";
+				handler = connect.connect(list1.domNode, "onclick", onClick);
+			}
+
+			function hideDeleteButton(){
+				if(delItem){
+					delItem.rightIconNode.style.display = "";
+					delItem.rightIcon2Node.style.display = "none";
+					delItem = null;
+				}
+				connect.disconnect(handler);
+			}
+
+			function onClick(e){
+				var item = registry.getEnclosingWidget(e.target);
+				if(domClass.contains(e.target, "mblDomButtonMyRedButton_0")){
+					setTimeout(function(){
+						item.destroy();
+					}, 0);
+				}
+				hideDeleteButton();
+			}
+
+			connect.subscribe("/dojox/mobile/deleteListItem", function(item){
+				showDeleteButton(item);
+			});
+
+			edit = function(){
+				var flag = btn1._flag = !btn1._flag; // true: editable
+				if(flag){
+					list1.startEdit();
+					btn1.set("label", "Done");
+				}else{
+					hideDeleteButton();
+					list1.endEdit();
+					btn1.set("label", "Edit");
+				}
+			}
+
+			ready(function(){
+				btn1 = registry.byId("btn1");
+				list1 = registry.byId("list1");
+			});
+		});
+	</script>
+
+	<style>
+	/* inline custom DOM Button */
+	.mblDomButtonMyRedButton_0 {
+		position: relative;
+		height: 29px;
+		line-height: 29px;
+		padding: 0px 8px;
+		color: white;
+		font-family: Helvetica;
+		font-size: 13px;
+		font-weight: bold;
+		border: 1px outset #9cacc0;
+		border-radius: 5px;
+		background: -webkit-gradient(linear, left top, left bottom, from(#d3656d), to(#bc1320), color-stop(0.5, #c9404b), color-stop(0.5, #bc1421));
+		background-color: #c9404b;
+		text-align: center;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", label:"Editable RoundRectList"'>
+			<span id="btn1" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='toggle:true' style="padding: 0px 14px;float:left" onclick="edit">Edit</span>
+		</div>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul id="list1" data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='editable:true'>
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Slide
+			</li>
+			<li id="item2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Flip
+			</li>
+			<li id="item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Fade
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 1"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 2"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 3"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 4"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 5"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 6"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 7"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 8"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item 9"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item a"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item b"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item c"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item d"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item e"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item f"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item g"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item h"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item i"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item j"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item k"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", label:"Item l"'></li>
+
+		</ul>
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"'>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRectList-editable.html b/dojox/mobile/tests/test_RoundRectList-editable.html
new file mode 100644
index 0000000..2a04275
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectList-editable.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectList - editable</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedCircleMinus.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonGrayKnob.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, domClass, ready, registry){
+			var delItem, handler, btn1, list1;
+
+			function showDeleteButton(item){
+				hideDeleteButton();
+				delItem = item;
+				item.rightIconNode.style.display = "none";
+				if(!item.rightIcon2Node){
+					item.set("rightIcon2", "mblDomButtonMyRedButton_0");
+					item.rightIcon2Node.firstChild.innerHTML = "Delete";
+				}
+				item.rightIcon2Node.style.display = "";
+				handler = connect.connect(list1.domNode, "onclick", onClick);
+			}
+
+			function hideDeleteButton(){
+				if(delItem){
+					delItem.rightIconNode.style.display = "";
+					delItem.rightIcon2Node.style.display = "none";
+					delItem = null;
+				}
+				connect.disconnect(handler);
+			}
+
+			function onClick(e){
+				var item = registry.getEnclosingWidget(e.target);
+				if(domClass.contains(e.target, "mblDomButtonMyRedButton_0")){
+					setTimeout(function(){
+						item.destroy();
+					}, 0);
+				}
+				hideDeleteButton();
+			}
+
+			connect.subscribe("/dojox/mobile/deleteListItem", function(item){
+				showDeleteButton(item);
+			});
+
+			edit = function(){
+				var flag = btn1._flag = !btn1._flag; // true: editable
+				if(flag){
+					list1.startEdit();
+					btn1.set("label", "Done");
+				}else{
+					hideDeleteButton();
+					list1.endEdit();
+					btn1.set("label", "Edit");
+				}
+			}
+
+			ready(function(){
+				btn1 = registry.byId("btn1");
+				list1 = registry.byId("list1");
+			});
+		});
+	</script>
+
+	<style>
+	/* inline custom DOM Button */
+	.mblDomButtonMyRedButton_0 {
+		position: relative;
+		height: 29px;
+		line-height: 29px;
+		padding: 0px 8px;
+		color: white;
+		font-family: Helvetica;
+		font-size: 13px;
+		font-weight: bold;
+		border: 1px outset #9cacc0;
+		border-radius: 5px;
+		background: -webkit-gradient(linear, left top, left bottom, from(#d3656d), to(#bc1320), color-stop(0.5, #c9404b), color-stop(0.5, #bc1421));
+		background-color: #c9404b;
+		text-align: center;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Editable RoundRectList"'>
+			<span id="btn1" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='toggle:true' style="padding: 0px 14px;float:left" onclick="edit">Edit</span>
+		</div>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul id="list1" data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='editable:true'>
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Slide
+			</li>
+			<li id="item2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Flip
+			</li>
+			<li id="item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Fade
+			</li>
+
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 1"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 2"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 3"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 4"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 5"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 6"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 7"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 8"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item 9"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item a"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item b"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item c"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item d"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item e"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item f"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item g"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item h"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item i"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item j"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item k"'></li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", label:"Item l"'></li>
+
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRectList-icons.html b/dojox/mobile/tests/test_RoundRectList-icons.html
new file mode 100644
index 0000000..a1dbe72
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectList-icons.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectList - icons</title>
+
+	<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">News</h1>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='
+				deleteIcon:"images/i-icon-1.png",
+				icon:"images/i-icon-2.png",
+				rightIcon:"images/i-icon-4.png",
+				rightIcon2:"images/i-icon-3.png"'>
+				Image Icon.
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='
+				deleteIcon:"images/i-icon-all.png", deleteIconPos:"0,0,29,29",
+				icon:"images/i-icon-all.png", iconPos:"0,29,29,29",
+				rightIcon:"images/i-icon-all.png", rightIconPos:"0,87,29,29",
+				rightIcon2:"images/i-icon-all.png", rightIcon2Pos:"0,58,29,29"'>
+				Sprite Icon.
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='
+				deleteIcon:"mblDomButtonRedCircleMinus",
+				icon:"mblDomButtonSilverCircleDownArrow",
+				rightIcon:"mblDomButtonSilverCircleGreenButton",
+				rightIcon2:"mblDomButtonSilverCircleOrangeButton"'>
+				Dom Button.
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Check List</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"multiple"'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='
+				checkClass:"images/i-icon-1.png"'>
+				Image Icon.
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='
+				checkClass:"images/i-icon-all.png", rightIconPos:"0,0,29,29"'>
+				Sprite Icon.
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='
+				checkClass:"mblDomButtonSilverCircleGreenButton"'>
+				Dom Button.
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Check List (with unchecked icon)</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"multiple"'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='
+				checkClass:"images/i-icon-1.png",
+				uncheckClass:"images/i-icon-2.png"'>
+				Image Icon.
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='
+				checkClass:"images/i-icon-all.png", rightIconPos:"0,0,29,29",
+				uncheckClass:"images/i-icon-all.png", uncheckIconPos:"0,29,29,29"'>
+				Sprite Icon.
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='
+				checkClass:"mblDomButtonSilverCircleGreenButton",
+				uncheckClass:"mblDomButtonSilverCircleGrayButton"'>
+				Dom Button.
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRectList-inherit.html b/dojox/mobile/tests/test_RoundRectList-inherit.html
new file mode 100644
index 0000000..da952d6
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectList-inherit.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectList - inherit</title>
+
+	<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+	<style>
+	.textBox {
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">News</h1>
+
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Image Icon</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='
+			variableHeight:true,
+			deleteIconBase:"images/i-icon-1.png",
+			iconBase:"images/i-icon-2.png",
+			rightIconBase:"images/i-icon-4.png",
+			rightIcon2Base:"images/i-icon-3.png"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div class="textBox">
+					Image Icon.<br>
+					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 1
+				</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div class="textBox">
+					Image Icon.<br>
+					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 2
+				</div>
+			</li>
+		</ul>
+
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Sprite Icon</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='
+			variableHeight:true,
+			deleteIconBase:"images/i-icon-all.png", deleteIconPos:"0,0,29,29",
+			iconBase:"images/i-icon-all.png", iconPos:"0,29,29,29",
+			rightIconBase:"images/i-icon-all.png", rightIconPos:"0,87,29,29",
+			rightIcon2Base:"images/i-icon-all.png", rightIcon2Pos:"0,58,29,29"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div class="textBox">
+					Sprite Icon.<br>
+					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 1
+				</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div class="textBox">
+					Sprite Icon.<br>
+					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 2
+				</div>
+			</li>
+		</ul>
+
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Dom Button</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='
+			variableHeight:true,
+			deleteIconBase:"mblDomButtonRedCircleMinus",
+			iconBase:"mblDomButtonSilverCircleDownArrow",
+			rightIconBase:"mblDomButtonSilverCircleGreenButton",
+			rightIcon2Base:"mblDomButtonSilverCircleOrangeButton"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div class="textBox">
+					Dom Button.<br>
+					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 1
+				</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<div class="textBox">
+					Dom Button.<br>
+					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 2
+				</div>
+			</li>
+		</ul>
+
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Check List</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='
+			select:"multiple",
+			variableHeight:true,
+			checkClass:"images/i-icon-1.png"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Image Icon.<br>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Image Icon.<br>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 2
+			</li>
+		</ul>
+
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Check List (with unchecked icon)</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='
+			select:"multiple",
+			variableHeight:true,
+			checkClass:"images/i-icon-1.png",
+			uncheckClass:"images/i-icon-2.png"'>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Image Icon.<br>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				Image Icon.<br>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 2
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRectList-variable.html b/dojox/mobile/tests/test_RoundRectList-variable.html
new file mode 100644
index 0000000..28a1c27
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectList-variable.html
@@ -0,0 +1,100 @@
+<!doctype html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Variable Height List (Round Rectangle)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+	<style>
+		.content {
+			padding:0px 10px;
+			background-color: white;
+		}
+		p {
+			font-family: Helvetica;
+			font-size: 12px;
+		}
+		.title {
+			color: blue;
+			margin-bottom: 4px;
+		}
+		.subtitle {
+			font-style: italic;
+			color: gray;
+			margin: 0px;
+			margin-bottom: 4px;
+		}
+		.subsubtitle {
+			margin: 16px 0px 0px 0px;
+		}
+		.lst {
+			margin: 0px;
+			padding: 0px 14px;
+		}
+		.lst li {
+			font-family: Helvetica;
+			font-size: 12px;
+			margin: 0px;
+			list-style-type: square;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Variable Height List Item</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Top Stories</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#article", transition:"slide"'>
+				Top 10 news stories of the decade
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#article", transition:"flip"'>
+				Create client-side diagrammatic interaction in Web applications with GFX
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#article", transition:"fade"'>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+	</div>
+
+	<div id="article" data-dojo-type="dojox.mobile.View" style="color:black;background-color:white;height:100%">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#home"'>Article</h1>
+		<div class="content">
+			<h3 class="title">Did you know?</h3>
+			<h4 class="subtitle">Features of dojox.mobile</h4>
+			<h5 class="subsubtitle">No images are used</h5>
+			<ul class="lst">
+			  	<li>UI parts consist of DOM and CSS3.</li>
+				<li>Only application icons are images.</li>
+			</ul>
+			<p>For example, none of the UI parts below are images.<br></p>
+			<img src="images/not-images.png">
+
+			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
+			<ul class="lst">
+			  	<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Support for CSS sprite</h5>
+			<ul class="lst">
+				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
+			<ul class="lst">
+				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
+			</ul>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRectList-vh-icons.html b/dojox/mobile/tests/test_RoundRectList-vh-icons.html
new file mode 100644
index 0000000..e5b096f
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectList-vh-icons.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectList - variableHeight</title>
+
+	<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+	<style>
+	.textBox {
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">News</h1>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true,
+				deleteIcon:"images/i-icon-1.png",
+				icon:"images/i-icon-2.png",
+				rightIcon:"images/i-icon-4.png",
+				rightIcon2:"images/i-icon-3.png"'>
+				<div class="textBox">
+					Image Icon.<br>
+					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 1
+				</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true,
+				deleteIcon:"images/i-icon-all.png", deleteIconPos:"0,0,29,29",
+				icon:"images/i-icon-all.png", iconPos:"0,29,29,29",
+				rightIcon:"images/i-icon-all.png", rightIconPos:"0,87,29,29",
+				rightIcon2:"images/i-icon-all.png", rightIcon2Pos:"0,58,29,29"'>
+				<div class="textBox">
+					Sprite Icon.<br>
+					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 2
+				</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true,
+				deleteIcon:"mblDomButtonRedCircleMinus",
+				icon:"mblDomButtonSilverCircleDownArrow",
+				rightIcon:"mblDomButtonSilverCircleGreenButton",
+				rightIcon2:"mblDomButtonSilverCircleOrangeButton"'>
+				<div class="textBox">
+					Dom Button.<br>
+					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+				</div>
+			</li>
+		</ul>
+
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Check List</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"multiple"'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true,
+				checkClass:"images/i-icon-1.png"'>
+				Image Icon.<br>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true,
+				checkClass:"images/i-icon-all.png", rightIconPos:"0,0,29,29"'>
+				Sprite Icon.<br>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true,
+				checkClass:"mblDomButtonSilverCircleGreenButton"'>
+				Dom Button.<br>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Check List (with unchecked icon)</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"multiple"'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true,
+				checkClass:"images/i-icon-1.png",
+				uncheckClass:"images/i-icon-2.png"'>
+				Image Icon.<br>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true,
+				checkClass:"images/i-icon-all.png", rightIconPos:"0,0,29,29",
+				uncheckClass:"images/i-icon-all.png", uncheckIconPos:"0,29,29,29"'>
+				Sprite Icon.<br>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true,
+				checkClass:"mblDomButtonSilverCircleGreenButton",
+				uncheckClass:"mblDomButtonSilverCircleGrayButton"'>
+				Dom Button.<br>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRectList.html b/dojox/mobile/tests/test_RoundRectList.html
new file mode 100644
index 0000000..4e6ffa5
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectList.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Animation</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"bar", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bar", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"bar", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
+
+	<div id="bar" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"foo"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_RoundRectStoreList.html b/dojox/mobile/tests/test_RoundRectStoreList.html
new file mode 100644
index 0000000..3a42f6e
--- /dev/null
+++ b/dojox/mobile/tests/test_RoundRectStoreList.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>RoundRectStoreList</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/Deferred",
+			"dojo/store/Cache",
+			"dojo/store/JsonRest",
+			"dojo/store/Memory",
+			"dojo/store/Observable",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/RoundRectStoreList"
+		], function(Deferred, Cache, JsonRest, Memory, Observable, registry){
+			var static_data1 = [
+				{ label: "Wi-Fi", icon: "images/i-icon-1.png", moveTo: "wifi" },
+				{ label: "Brightness & Wallpaper", icon: "images/i-icon-2.png", moveTo: "bright" },
+				{ label: "Picture Frame", icon: "images/i-icon-3.png", moveTo: "picture" },
+				{ label: "General", icon: "images/i-icon-4.png", moveTo: "general", "selected": "true" },
+				{ label: "Mail, Contacts, Calendars", icon: "images/i-icon-5.png", moveTo: "wifi" },
+				{ label: "Safari", icon: "images/i-icon-6.png", moveTo: "bright" },
+				{ label: "iPod", icon: "images/i-icon-7.png", moveTo: "picture" },
+				{ label: "Video", icon: "images/i-icon-8.png", moveTo: "general" },
+				{ label: "Photos", icon: "images/i-icon-9.png", moveTo: "wifi" },
+				{ label: "Store", icon: "images/i-icon-10.png", moveTo: "bright" }
+			];
+
+			var static_data2 = [
+				{label: "Apple", 	moveTo: "dummy"},
+				{label: "Banana", 	moveTo: "dummy"},
+				{label: "Cherry", 	moveTo: "dummy"},
+				{label: "Grape", 	moveTo: "dummy"},
+				{label: "Kiwi", 	moveTo: "dummy"},
+				{label: "Lemon", 	moveTo: "dummy"},
+				{label: "Melon", 	moveTo: "dummy"},
+				{label: "Orange", 	moveTo: "dummy"},
+				{label: "Peach", 	moveTo: "dummy"}
+			];
+			store1 = Observable(new Memory({idProperty:"label", data: static_data1}));
+			store2 = Observable(new Memory({idProperty:"label", data: static_data2}));
+			store1.__counter = store2.__counter = 1;
+			store = store1;
+
+			// switch to the selected store
+			switchTo = function(store){
+				window.store = store;
+				registry.byId("list").setStore(store);
+			};
+			// add a new item
+			add1 = function(){
+				store.add({
+					label: "New Item "+(store.__counter++),
+					icon: "images/i-icon-1.png",
+					moveTo: "dummy"
+				});
+			};
+			// delete the added item
+			delete1 = function(){
+				if(store.__counter > 1){
+					store.remove("New Item "+(--store.__counter));
+				}
+			};
+			// modify the added item
+			var modif_counter = 0;
+			modify1 = function(){
+				if(store.__counter > 1){
+					store.put({
+						label: "New Item "+(store.__counter-1),
+						rightText: ++modif_counter + " changes"
+					});
+				}
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">RoundRectStoreList</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectStoreList" id="list" data-dojo-props='store:store, query:{}'></ul>
+		<p>show the different set:<br>
+		<input type="button" value="Set1" onclick="switchTo(store1)">
+		<input type="button" value="Set2" onclick="switchTo(store2)">
+		<p>alter the object store:<br>
+		<input type="button" value="Add" onclick="add1()">
+		<input type="button" value="Delete" onclick="delete1()">
+		<input type="button" value="Modify" onclick="modify1()">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScreenSizeAware-demo-prop.html b/dojox/mobile/tests/test_ScreenSizeAware-demo-prop.html
new file mode 100644
index 0000000..9f2f1b3
--- /dev/null
+++ b/dojox/mobile/tests/test_ScreenSizeAware-demo-prop.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Screen Size Aware Demo</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/data/ItemFileWriteStore",
+			"dojo/dom-construct",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/Heading",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/EdgeToEdgeDataList",
+			"dojox/mobile/ScreenSizeAware",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Container"
+		], function(connect, ItemFileWriteStore, domConstruct, ready, registry, Heading,
+					ScrollableView, EdgeToEdgeDataList, ScreenSizeAware){
+			var viewCache = {};
+			function leftItemSelected(e){
+				var item = e ? registry.getEnclosingWidget(e.target) : registry.byId("list1").getChildren()[0];
+				if(!item){ return; }
+				var id = viewCache[item.data];
+				if(!id){
+					// Dynamically creates a new view
+					id = item.id ? item.id + "View" : undefined;
+					var view = new ScrollableView({
+						id: id
+					}, domConstruct.create("DIV", null, "rightPane"));
+					id = viewCache[item.data] = view.id;
+
+					var heading = new Heading({
+						label: item.label,
+						back: "Home",
+						moveTo: "view1",
+						fixed: "top"
+					});
+					view.addFixedBar(heading);
+
+					var store = new ItemFileWriteStore({url: item.data});
+					var list = new EdgeToEdgeDataList({
+						store: store
+					});
+					list.placeAt(view.containerNode);
+
+					this.updateBackButton();
+					this.updateTransition();
+
+					view.startup();
+				}
+				item.transitionTo(id);
+			}
+			function leftItemsLoaded(){
+				if(!ssa.isPhone()){
+					ssa.leftItemSelected();
+					ssa.updateSelectedItem();
+				}
+			}
+			ready(function(){
+				ssa = ScreenSizeAware.getInstance();
+				connect.connect(registry.byId("list1").domNode, "onclick", ssa, leftItemSelected);
+				connect.connect(registry.byId("list1"), "onComplete", null, leftItemsLoaded);
+				connect.connect(ssa, "leftItemSelected", ssa, leftItemSelected);
+				connect.connect(ssa, "getDestinationId", null, function(item){
+					return viewCache[item.data];
+				});
+			});
+			store1 = new ItemFileWriteStore({url: "data/insurance.json"});
+		});
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	.iphone_theme #leftPane, .blackberry_theme #leftPane {
+		border-right: 1px solid black;
+	}
+	.android_theme #leftPane {
+		border-right: 1px solid gray;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H", screenSizeAware:true'>
+		<div id="leftPane" data-dojo-type="dojox.mobile.Container" style="width:300px;">
+			<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Insurance</h1>
+				<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="list1" data-dojo-props='store:store1, query:{label: "*"}, stateful:true'></ul>
+			</div>
+		</div>
+
+		<div id="rightPane" data-dojo-type="dojox.mobile.Container"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScreenSizeAware-demo-tag.html b/dojox/mobile/tests/test_ScreenSizeAware-demo-tag.html
new file mode 100644
index 0000000..5da8b87
--- /dev/null
+++ b/dojox/mobile/tests/test_ScreenSizeAware-demo-tag.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Screen Size Aware Demo</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/data/ItemFileWriteStore",
+			"dojo/dom-construct",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/Heading",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/EdgeToEdgeDataList",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/ScreenSizeAware",
+			"dojox/mobile/Container"
+		], function(connect, ItemFileWriteStore, domConstruct, ready, registry, Heading, ScrollableView, EdgeToEdgeDataList){
+			var viewCache = {};
+			function leftItemSelected(e){
+				var item = e ? registry.getEnclosingWidget(e.target) : registry.byId("list1").getChildren()[0];
+				if(!item){ return; }
+				var id = viewCache[item.data];
+				if(!id){
+					// Dynamically creates a new view
+					id = item.id ? item.id + "View" : undefined;
+					var view = new ScrollableView({
+						id: id
+					}, domConstruct.create("DIV", null, "rightPane"));
+					id = viewCache[item.data] = view.id;
+
+					var heading = new Heading({
+						label: item.label,
+						back: "Home",
+						moveTo: "view1",
+						fixed: "top"
+					});
+					view.addFixedBar(heading);
+
+					var store = new ItemFileWriteStore({url: item.data});
+					var list = new EdgeToEdgeDataList({
+						store: store
+					});
+					list.placeAt(view.containerNode);
+
+					this.updateBackButton();
+					this.updateTransition();
+
+					view.startup();
+				}
+				item.transitionTo(id);
+			}
+			function leftItemsLoaded(){
+				if(!ssa.isPhone()){
+					ssa.leftItemSelected();
+					ssa.updateSelectedItem();
+				}
+			}
+			ready(function(){
+				connect.connect(registry.byId("list1").domNode, "onclick", ssa, leftItemSelected);
+				connect.connect(registry.byId("list1"), "onComplete", null, leftItemsLoaded);
+				connect.connect(ssa, "leftItemSelected", ssa, leftItemSelected);
+				connect.connect(ssa, "getDestinationId", null, function(item){
+					return viewCache[item.data];
+				});
+			});
+			store1 = new ItemFileWriteStore({url: "data/insurance.json"});
+		});
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	.iphone_theme #leftPane, .blackberry_theme #leftPane {
+		border-right: 1px solid black;
+	}
+	.android_theme #leftPane {
+		border-right: 1px solid gray;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<span data-dojo-id="ssa" data-dojo-type="dojox.mobile.ScreenSizeAware"></span>
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div id="leftPane" data-dojo-type="dojox.mobile.Container" style="width:300px;">
+			<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Insurance</h1>
+				<ul data-dojo-type="dojox.mobile.EdgeToEdgeDataList" id="list1" data-dojo-props='store:store1, query:{label: "*"}, stateful:true'></ul>
+			</div>
+		</div>
+
+		<div id="rightPane" data-dojo-type="dojox.mobile.Container"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScreenSizeAware-icon.html b/dojox/mobile/tests/test_ScreenSizeAware-icon.html
new file mode 100644
index 0000000..45782fb
--- /dev/null
+++ b/dojox/mobile/tests/test_ScreenSizeAware-icon.html
@@ -0,0 +1,196 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Screen Size Aware</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/ScreenSizeAware",
+			"dojox/mobile/Container"
+		]);
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	.dj_tablet .mblEdgeToEdgeList {
+		background-color: #DBDDE2;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<span data-dojo-type="dojox.mobile.ScreenSizeAware"></span>
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Container" style="width:300px;border-right:1px solid black;">
+			<div id="settings" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='selected:true'>
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Settings</h1>
+
+				<ul data-dojo-type="dojox.mobile.IconContainer">
+					<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='icon:"images/icon1.png", moveTo:"wifi", label:"Wi-Fi"'></li>
+					<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='icon:"images/icon2.png", moveTo:"bright", label:"Brightness & Wallpaper"'></li>
+					<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='icon:"images/icon3.png", moveTo:"picture", label:"Picture Frame"'></li>
+					<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='icon:"images/icon4.png", moveTo:"general", selected:true, label:"General"'></li>
+					<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='icon:"images/icon5.png", moveTo:"wifi", label:"Mail, Contacts, Calendars"'></li>
+					<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='icon:"images/icon6.png", moveTo:"bright", label:"Safari"'></li>
+					<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='icon:"images/icon7.png", moveTo:"picture", label:"iPod"'></li>
+					<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='icon:"images/icon8.png", moveTo:"general", label:"Video"'></li>
+					<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='icon:"images/icon9.png", moveTo:"wifi", label:"Photos"'></li>
+					<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='icon:"images/icon10.png", moveTo:"bright", label:"Store"'></li>
+				</ul>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Container">
+
+			<div id="general" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='selected:true'>
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>General</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						About
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2h 40m", moveTo:"about"'>
+						Usage
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Network
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Bluetooth
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Location Services
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1 Minute", moveTo:"about"'>
+						Auto-Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Passcode Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Restrictions
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Home
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Date & Time					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Keyboard					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						International				   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Accessibility
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Reset
+					</li>
+				</ul>
+			</div>
+
+			<div id="about" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"General", moveTo:"general"'>About</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Network											   
+					</li>												   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Line
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+						Songs
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+						Videos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+						Photos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+						Applications
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+						Capacity
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+						Available
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+						Version
+					</li>
+				</ul>
+			</div>
+
+			<div id="wifi" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>Wi-Fi Networks</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Wi-Fi
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<input type="text">
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<select><option>Songs</option><option>Videos</option><option>Photos</option></select>
+					</li>
+				</ul>
+			</div>
+
+			<div id="bright" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>Brightness & Wallpaper</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Auto-Brightness
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+				</ul>
+			</div>
+
+			<div id="picture" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>Picture Frame</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"single"'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true'>
+						Dissolve
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Origami
+					</li>
+				</ul>
+			</div>
+
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScreenSizeAware-prop.html b/dojox/mobile/tests/test_ScreenSizeAware-prop.html
new file mode 100644
index 0000000..52a763a
--- /dev/null
+++ b/dojox/mobile/tests/test_ScreenSizeAware-prop.html
@@ -0,0 +1,239 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Screen Size Aware</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/Container"
+		]);
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	.dj_tablet .mblEdgeToEdgeList {
+		background-color: #DBDDE2;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H", screenSizeAware:true'>
+		<div data-dojo-type="dojox.mobile.Container" style="width:300px;border-right:1px solid black;">
+			<div id="settings" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='selected:true'>
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Settings</h1>
+				<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='transition:"flip", stateful:true'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						Wi-Fi
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Brightness & Wallpaper
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Picture Frame
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general", selected:true'>
+						General
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"wifi"'>
+						Mail, Contacts, Calendars
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"bright"'>
+						Safari
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"picture"'>
+						iPod
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"general"'>
+						Video
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"wifi"'>
+						Photos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"bright"'>
+						Store
+					</li>
+					<li class="mblEdgeToEdgeCategory">
+						Apps
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						News
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Weather
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Books
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general"'>
+						 Business
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						Navigation
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Sports
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Social
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general"'>
+						Music
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Container">
+
+			<div id="general" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='selected:true'>
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>General</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						About
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2h 40m", moveTo:"about"'>
+						Usage
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Network
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Bluetooth
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Location Services
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1 Minute", moveTo:"about"'>
+						Auto-Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Passcode Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Restrictions
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Home
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Date & Time					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Keyboard					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						International				   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Accessibility
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Reset
+					</li>
+				</ul>
+			</div>
+
+			<div id="about" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"General", moveTo:"general"'>About</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Network											   
+					</li>												   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Line
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+						Songs
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+						Videos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+						Photos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+						Applications
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+						Capacity
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+						Available
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+						Version
+					</li>
+				</ul>
+			</div>
+
+			<div id="wifi" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>Wi-Fi Networks</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Wi-Fi
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<input type="text">
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<select><option>Songs</option><option>Videos</option><option>Photos</option></select>
+					</li>
+				</ul>
+			</div>
+
+			<div id="bright" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>Brightness & Wallpaper</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Auto-Brightness
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+				</ul>
+			</div>
+
+			<div id="picture" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>Picture Frame</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"single"'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true'>
+						Dissolve
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Origami
+					</li>
+				</ul>
+			</div>
+
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScreenSizeAware-tag.html b/dojox/mobile/tests/test_ScreenSizeAware-tag.html
new file mode 100644
index 0000000..e95b1b3
--- /dev/null
+++ b/dojox/mobile/tests/test_ScreenSizeAware-tag.html
@@ -0,0 +1,241 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Screen Size Aware</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/ScreenSizeAware",
+			"dojox/mobile/Container"
+		]);
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	.dj_tablet .mblEdgeToEdgeList {
+		background-color: #DBDDE2;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<span data-dojo-type="dojox.mobile.ScreenSizeAware"></span>
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Container" style="width:300px;border-right:1px solid black;">
+			<div id="settings" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='selected:true'>
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Settings</h1>
+				<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='transition:"flip", stateful:true'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						Wi-Fi
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Brightness & Wallpaper
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Picture Frame
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general", selected:true'>
+						General
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"wifi"'>
+						Mail, Contacts, Calendars
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"bright"'>
+						Safari
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"picture"'>
+						iPod
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"general"'>
+						Video
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"wifi"'>
+						Photos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"bright"'>
+						Store
+					</li>
+					<li class="mblEdgeToEdgeCategory">
+						Apps
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						News
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Weather
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Books
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general"'>
+						 Business
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						Navigation
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Sports
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Social
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general"'>
+						Music
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Container">
+
+			<div id="general" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='selected:true'>
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>General</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						About
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2h 40m", moveTo:"about"'>
+						Usage
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Network
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Bluetooth
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Location Services
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1 Minute", moveTo:"about"'>
+						Auto-Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Passcode Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Restrictions
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Home
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Date & Time					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Keyboard					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						International				   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Accessibility
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Reset
+					</li>
+				</ul>
+			</div>
+
+			<div id="about" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"General", moveTo:"general"'>About</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Network											   
+					</li>												   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Line
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+						Songs
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+						Videos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+						Photos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+						Applications
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+						Capacity
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+						Available
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+						Version
+					</li>
+				</ul>
+			</div>
+
+			<div id="wifi" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>Wi-Fi Networks</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Wi-Fi
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<input type="text">
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<select><option>Songs</option><option>Videos</option><option>Photos</option></select>
+					</li>
+				</ul>
+			</div>
+
+			<div id="bright" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>Brightness & Wallpaper</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Auto-Brightness
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+				</ul>
+			</div>
+
+			<div id="picture" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Settings", moveTo:"settings"'>Picture Frame</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"single"'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true'>
+						Dissolve
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Origami
+					</li>
+				</ul>
+			</div>
+
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableMixin-custom.html b/dojox/mobile/tests/test_ScrollableMixin-custom.html
index 8b18872..be18a80 100644
--- a/dojox/mobile/tests/test_ScrollableMixin-custom.html
+++ b/dojox/mobile/tests/test_ScrollableMixin-custom.html
@@ -1,43 +1,32 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableMixin-custom</title>
-		<style>
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			width: 100%;
-			margin: 0px;
-			padding: 0px;
-		}
-		#foo {
-			position: relative;
-			height: 100%;
-			overflow: hidden;
-		}
-		#header1 {
-			position: relative;
-			margin: 0px;
-			width: 100%;
-			top: 0px;
-			background-color: cyan;
-			z-index: 1;
-		}
-			
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile._ScrollableMixin");
-			dojo.declare("dojox.mobile.ScrollablePane",
-				[dijit._WidgetBase, dojox.mobile._ScrollableMixin, dijit._Container, dijit._Contained],{
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableMixin-custom</title>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/_base/window",
+			"dijit/_WidgetBase",
+			"dijit/_Container",
+			"dijit/_Contained",
+			"dojox/mobile/_ScrollableMixin",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(declare, win, WidgetBase, Container, Contained, ScrollableMixin){
+			dojox.mobile.ScrollablePane = declare(
+				"dojox.mobile.ScrollablePane",
+				[WidgetBase, Container, Contained, ScrollableMixin],
+			{
 				buildRendering: function(){
 					this.inherited(arguments);
-					this.containerNode = dojo.doc.createElement("DIV");
+					this.containerNode = win.doc.createElement("DIV");
 					this.containerNode.className = "mblScrollableViewContainer";
 					this.containerNode.style.backgroundColor = "yellow";
 					this.containerNode.style.border = "1px solid red";
@@ -50,54 +39,118 @@
 					this.domNode.appendChild(this.containerNode);
 				}
 			});
-			
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<h1 id="header1">Fixed Header</h1>
-		<div id="foo" dojoType="dojox.mobile.ScrollablePane">
-			<ol>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-				<li>Item</li>
-			</ol>
-		</div>
-	</body>
+		});
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		width: 100%;
+		margin: 0px;
+		padding: 0px;
+	}
+	#view1 {
+		position: relative;
+		height: 100%;
+		overflow: hidden;
+	}
+	#header1 {
+		position: relative;
+		margin: 0px;
+		width: 100%;
+		top: 0px;
+		background-color: cyan;
+		z-index: 1;
+	}
+		
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<h1 id="header1">Fixed Header</h1>
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollablePane">
+		<ol>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+			<li>Item</li>
+		</ol>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_ScrollablePane-demo.html b/dojox/mobile/tests/test_ScrollablePane-demo.html
new file mode 100644
index 0000000..35825f2
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollablePane-demo.html
@@ -0,0 +1,251 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollablePane Demo</title>
+
+	<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','PageIndicator','FixedSplitter','ScrollablePane']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/SwapView",
+			"dojox/mobile/PageIndicator",
+			"dojox/mobile/ScrollablePane"
+		]);
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	.mblRoundRectList, .mblRoundRect {
+		margin: 7px 9px 7px 9px;
+	}
+	.mblListItem {
+		color: white;
+	}
+	.subtitle {
+		color: gray;
+		font-size: 12px;
+	}
+	#news {
+		font-size: 14px;
+	}
+	.list1 li{
+	}
+	.list1 li:nth-child(even){
+		background-color: #00575F;
+	}
+	.list1 li:nth-child(odd){
+		background-color: #013042;
+	}
+	.list1 .mblListItemTextBox {
+		padding-right: 5px;
+	}
+	.c1 {
+		width: 120px;
+		float: left;
+	}
+	.c2 {
+		width: 80px;
+		text-align: right;
+		float: left;
+	}
+	.c3 {
+		text-align: right;
+		width: 70px;
+		color: white;
+		padding: 0px 4px;
+		margin-top: 4px;
+		height: 30px;
+		line-height: 32px;
+		float: right;
+		-webkit-border-radius: 4px;
+		-moz-border-radius: 4px;
+	}
+	.android_theme .c3 {
+		margin-top: 15px;
+	}
+	.android_theme .mblRoundRectList {
+		border-color: #666666;
+	}
+	.blackberry_theme .c3 {
+		margin-top: 13px;
+	}
+	.c3a {
+		border: 2px solid #598F3A;
+		background-color: #6FB248;
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#6FB248), to(#54972D), color-stop(0.5, #5FA238), color-stop(0.5, #54972D));
+	}
+	.c3b {
+		border: 2px solid #9B322D;
+		background-color: #C13E37;
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#C13E37), to(#A6231C), color-stop(0.5, #B6332C), color-stop(0.5, #A8251E));
+	}
+	#tbl1 {
+		margin: auto;
+	}
+	#tbl1 td {
+		text-align: right;
+		border-bottom: 1px solid #DEE9F5;
+		font: bold 13px arial,helvetica,clean,sans-serif;
+	}
+	#tbl1 td:first-child {
+		text-align: left;
+	}
+	#tbl1 td.g {
+		color: #008800
+	}
+	#tbl1 td.r {
+		color: #CC0000
+	}
+
+	.windows_theme .mblRoundRectList, .mblRoundRect {
+		margin: 0;
+	}
+
+	.windows_theme #general {
+		margin-left: 15px;
+	}
+
+	.windows_theme .c3 {
+		width: auto;
+	}
+
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="general" data-dojo-type="dojox.mobile.ScrollablePane" data-dojo-props='height:"200px",roundCornerMask:true'>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" class="list1" data-dojo-props='stateful:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+				<div class="c1">Gold</div>
+				<div class="c2">3,400.20</div>
+				<div class="c3 c3a">+1.57%</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+				<div class="c1">Oil</div>
+				<div class="c2">347.26</div>
+				<div class="c3 c3b">-0.82%</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+				<div class="c1">Commodities</div>
+				<div class="c2">541.77</div>
+				<div class="c3 c3b">-0.43%</div>
+				
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+				<div class="c1">Silver</div>
+				<div class="c2">12,823.94</div>
+				<div class="c3 c3a">+0.17%</div>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+				<div class="c1">Soybeans</div>
+				<div class="c2">18.19</div>
+				<div class="c3 c3a">+2.77%</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+				<div class="c1">Wheat</div>
+				<div class="c2">3,335</div>
+				<div class="c3 c3a">+1.62%</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+				<div class="c1">Corn</div>
+				<div class="c2">29,930</div>
+				<div class="c3 c3a">+1.15%</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+				<div class="c1">Sugar</div>
+				<div class="c2">172.15</div>
+				<div class="c3 c3a">+0.00%</div>
+			</li>
+		</ul>
+	</div>
+
+	<div style="position:relative">
+		<div id="swap1" data-dojo-type="dojox.mobile.SwapView">
+			<div data-dojo-type="dojox.mobile.ScrollablePane" data-dojo-props='height:"200px",roundCornerMask:true'>
+				<ul id="news" class="list1" data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+					<li data-dojo-type="dojox.mobile.ListItem"
+						data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+						Oil prices rise as dollar weakens
+						<div class="subtitle">Daily News - 2011/05/02 15:40</div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem"
+						data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+						Same Old Story For Air Service Costs
+						<div class="subtitle">Daily News - 2011/05/02 14:30</div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem"
+						data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+						Local stocks mixed despite new trade data
+						<div class="subtitle">Daily News - 2011/05/02 14:10</div>
+					</li>
+
+					<li data-dojo-type="dojox.mobile.ListItem"
+						data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+						Stocks point higher after economic data
+						<div class="subtitle">Daily News - 2011/05/02 11:00</div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem"
+						data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+						Wall St seen higher after industry forecasts
+						<div class="subtitle">Daily News - 2011/05/01 16:05</div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem"
+						data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+						Stocks drop on slower job creation
+						<div class="subtitle">Daily News - 2011/05/01 15:50</div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem"
+						data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+						Dollar initially falls after revised jobs report
+						<div class="subtitle">Daily News - 2011/05/01 13:20</div>
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div id="swap2" data-dojo-type="dojox.mobile.SwapView">
+			<div data-dojo-type="dojox.mobile.ScrollablePane" data-dojo-props='height:"200px",roundCornerMask:true'>
+				<div data-dojo-type="dojox.mobile.RoundRect" style="position:relative;background-color:#00575F;color:white;">
+				<table id="tbl1" style="width:90%">
+					<tr><td>2 Yr Bond</td><td>113.75</td><td>0.00</td><td class="g">0.00%</td></tr>
+					<tr><td>N225</td><td>10,004.20</td><td>154.46</td><td class="g">1.57%</td></tr>
+					<tr><td>JKSE</td><td>3,816.44</td><td>32.87</td><td class="r">-0.85%</td></tr>
+					<tr><td>Seoul</td><td>2,200.73</td><td>28.23</td><td class="g">1.27%</td></tr>
+					<tr><td>TW</td><td>8,946.08</td><td>61.79</td><td class="r">-0.69%</td></tr>
+					<tr><td>Tokyo</td><td>2,932.19</td><td>20.68</td><td class="r">-0.71%</td></tr>
+					<tr><td>Osaka</td><td>113.75</td><td>0.00</td><td class="g">0.00%</td></tr>
+					<tr><td>HSI</td><td>10,004.20</td><td>154.46</td><td class="g">1.57%</td></tr>
+					<tr><td>AORD</td><td>3,816.44</td><td>32.87</td><td class="r">-0.85%</td></tr>
+					<tr><td>BSESN</td><td>2,200.73</td><td>28.23</td><td class="g">1.27%</td></tr>
+					<tr><td>PSEI</td><td>8,946.08</td><td>61.79</td><td class="r">-0.69%</td></tr>
+					<tr><td>STI</td><td>2,932.19</td><td>20.68</td><td class="r">-0.71%</td></tr>
+					<tr><td>All</td><td>4,854.70</td><td>41.50</td><td class="r">-0.85%</td></tr>
+				</table>
+				</div>
+			</div>
+		</div>
+
+		<div id="swap3" data-dojo-type="dojox.mobile.SwapView">
+			<div data-dojo-type="dojox.mobile.ScrollablePane" data-dojo-props='height:"200px",roundCornerMask:true'>
+				<div data-dojo-type="dojox.mobile.RoundRect" style="overflow:hidden;background-color:#00575F;">
+					<img src="images/chart.png" alt="">
+				</div>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.PageIndicator" data-dojo-props='fixed:"bottom"'></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollablePane-h.html b/dojox/mobile/tests/test_ScrollablePane-h.html
new file mode 100644
index 0000000..f5ba173
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollablePane-h.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollablePane - horiz</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ScrollablePane']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/ScrollablePane",
+			"dojox/mobile/compat"
+		], function(connect, dom, domClass, ready, registry){
+		});
+	</script>
+
+<style>
+.mblScrollablePane {
+	background-color: yellow;
+}
+</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" style="height:100px">
+		<div id="pane1" data-dojo-type="dojox.mobile.ScrollablePane" data-dojo-props='height:"inherit",scrollDir:"h"'>
+		<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;color:black;background-color:white;white-space: nowrap;">
+<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td>
+    <td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td>
+    <td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td>
+    <td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td>
+    <td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
+		</table>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollablePane-mask.html b/dojox/mobile/tests/test_ScrollablePane-mask.html
new file mode 100644
index 0000000..1df7b99
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollablePane-mask.html
@@ -0,0 +1,138 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollablePane - mask</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ScrollablePane']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/ScrollablePane",
+			"dojox/mobile/ContentPane",
+			"dojox/mobile/RoundRectCategory",
+			"dojox/mobile/compat"
+		]);
+	</script>
+	<style>
+	h3 {
+		margin-bottom: 0px;
+	}
+	.mblRoundRectList, .mblRoundRect, .myPane {
+		margin: 5px 9px 7px 9px;
+	}
+	.myPane {
+		background-color: white;
+		padding: 8px;
+		border-radius: 8px;
+		color: black;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h3 data-dojo-type="dojox.mobile.RoundRectCategory">RoundRectList</h3>
+		<div data-dojo-type="dojox.mobile.ScrollablePane" data-dojo-props='height:"100px",roundCornerMask:true'>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+					Slide
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+					Flip
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+					Fade
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+					Slide
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+					Flip
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+					Fade
+				</li>
+			</ul>
+		</div>
+
+		<h3 data-dojo-type="dojox.mobile.RoundRectCategory">RoundRect</h3>
+		<div data-dojo-type="dojox.mobile.ScrollablePane" data-dojo-props='height:"100px",roundCornerMask:true'>
+			<div data-dojo-type="dojox.mobile.RoundRect">
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+			</div>
+		</div>
+
+		<h3 data-dojo-type="dojox.mobile.RoundRectCategory"><div></h3>
+		<div data-dojo-type="dojox.mobile.ScrollablePane" data-dojo-props='height:"100px",roundCornerMask:true'>
+			<div class="myPane">
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+			</div>
+		</div>
+
+		<h3 data-dojo-type="dojox.mobile.RoundRectCategory">ContentPane (inline)</h3>
+		<div data-dojo-type="dojox.mobile.ScrollablePane" data-dojo-props='height:"100px",roundCornerMask:true'>
+			<div data-dojo-type="dojox.mobile.ContentPane" class="myPane">
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+				Hello<br>
+			</div>
+		</div>
+
+		<h3 data-dojo-type="dojox.mobile.RoundRectCategory">ContentPane (href)</h3>
+		<div data-dojo-type="dojox.mobile.ScrollablePane" data-dojo-props='height:"100px",roundCornerMask:true'>
+			<div data-dojo-type="dojox.mobile.ContentPane" class="myPane" data-dojo-props='href:"data/simple1.html"'>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollablePane.html b/dojox/mobile/tests/test_ScrollablePane.html
new file mode 100644
index 0000000..50533f2
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollablePane.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollablePane</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ScrollablePane']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/ScrollablePane",
+			"dojox/mobile/compat"
+		], function(connect, dom, domClass, ready, registry){
+		});
+	</script>
+
+<style>
+.mblScrollablePane {
+	background-color: yellow;
+	color: black;
+}
+</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" style="height:100px">
+		<div id="pane1" data-dojo-type="dojox.mobile.ScrollablePane" data-dojo-props='height:"inherit"'>
+		  hello<br>
+		  hello<br>
+		  hello<br>
+		  hello<br>
+		  hello<br>
+		  hello<br>
+		  hello<br>
+		  hello<br>
+		  hello<br>
+		  hello<br>
+		  hello<br>
+		  hello<br>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-HTML-inputs.html b/dojox/mobile/tests/test_ScrollableView-HTML-inputs.html
new file mode 100755
index 0000000..0cc3bad
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-HTML-inputs.html
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+	<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+	<title>ScrollableView-HTML-inputs</title>
+	<!-- Test case particularly for #17036 -->
+
+	<script type="text/javascript" src="../../../dojox/mobile/deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="async: true, parseOnLoad: true"></script>
+	<script language="JavaScript" type="text/javascript">
+		require([
+		 	"dojox/mobile",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/parser"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view" data-dojo-type="dojox/mobile/ScrollableView">
+		<div style="background-color: white; width: 100%;">
+			Text: <input type="text" size="40" maxlength="40"
+				value="click to select and then scroll the view"
+				onchange="alert('test failed !');" onkeypress="alert('test failed !');"
+				onkeydown="alert('test failed !');" onkeyup="alert('test failed !');">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Password: <input type="password">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Button: <input type="button" value="Click">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Checkbox: <input type="checkbox">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Color: <input type="color">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Date: <input type="date">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Datetime: <input type="datetime">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Datetime local: <input type="datetime-local">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Email: <input type="email">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			File: <input type="file">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Image: <input type="image">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Month: <input type="month">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Number: <input type="number">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Radio: <input type="radio">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Range: <input type="range">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Reset: <input type="reset">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Search: <input type="search">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Submit: <input type="submit">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Tel: <input type="tel">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Time: <input type="time">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Url: <input type="url">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			Week: <input type="week" max="2012-W01">
+		</div>
+		<div style="background-color: white; width: 100%;">
+			<textarea cols="40" maxlength="40" placeholder="click to select and then scroll the view"
+				onchange="alert('test failed !');" onkeypress="alert('test failed !');"
+				onkeydown="alert('test failed !');" onkeyup="alert('test failed !');">
+			</textarea>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-demo-long.html b/dojox/mobile/tests/test_ScrollableView-demo-long.html
new file mode 100644
index 0000000..494f619
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-demo-long.html
@@ -0,0 +1,395 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView demo</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/TabBar"
+		], function(ready, registry, ListItem){
+			ready(function(){
+				var w = registry.byId("categ1");
+				for(var i = 1; i <= 300; i++){
+					var item = new ListItem({label:"Category "+i, variableHeight: true});
+					w.addChild(item);
+				}
+			});
+		});
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	.list1 li{
+		border-style: solid;
+		border-width: 1px 0px 1px 0px;
+		border-top-color: #BABABC;
+		border-bottom-color: #89898C;
+		background-color: #ACACAF;
+		line-height: 0px;
+	}
+	.list1 li table{
+		line-height: normal;
+	}
+	.list1 li:nth-child(even){
+		background-color: #97979B;
+	}
+	#list2 li:nth-child(even){
+		background-color: #eeeeee;
+	}
+	#categ1 {
+		font-size: 18px;
+	}
+	#categ1 li{
+		line-height: 70px;
+	}
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	.content {
+		padding:0px 10px;
+		background-color: white;
+	}
+	p {
+		font-family: Helvetica;
+		font-size: 12px;
+	}
+	.title {
+		color: blue;
+		margin-bottom: 4px;
+	}
+	.subtitle {
+		font-style: italic;
+		color: gray;
+		margin: 0px;
+		margin-bottom: 4px;
+	}
+	.subsubtitle {
+		margin: 16px 0px 0px 0px;
+	}
+	.lst {
+		margin: 0px;
+		padding: 0px 14px;
+	}
+	.lst li {
+		font-family: Helvetica;
+		font-size: 12px;
+		margin: 0px;
+		list-style-type: square;
+	}
+	.iphone_theme .mblTabBarSegmentedControl .mblTabBarButtonIconArea {
+		display: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:{"iphone_theme":"segmentedControl","*":"tallTab"}, fixed:"top"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", moveTo:"view1", selected:true'>New</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"view2"'>What's Hot</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-10.png", icon2:"images/tab-icon-10h.png", moveTo:"view3"'>Genius</li>
+		</ul>
+
+		<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" class="list1">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+									Martin Parker Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" id="list2">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+					Network											   
+				</li>												   
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+					Line
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+					Songs
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+					Videos
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+					Photos
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+					Applications
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+					Capacity
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+					Available
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+					Version
+				</li>
+			</ul>
+		</div>
+	</div>
+
+	<div id="categ" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Categories</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" class="list1" id="categ1">
+		</ul>
+	</div>
+
+	<div id="top25" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>News</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Top Stories</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+				Top 10 news stories of the decade
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+				Create client-side diagrammatic interaction in Web applications with GFX
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+	</div>
+
+	<div id="search" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+
+	<div id="article" data-dojo-type="dojox.mobile.ScrollableView" style="color:black;background-color:white;height:100%">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Article</h1>
+		<div class="content">
+			<h3 class="title">Did you know?</h3>
+			<h4 class="subtitle">Features of dojox.mobile</h4>
+			<h5 class="subsubtitle">No images are used</h5>
+			<ul class="lst">
+				<li>UI parts consist of DOM and CSS3.</li>
+				<li>Only application icons are images.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
+			<ul class="lst">
+				<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Support for CSS sprite</h5>
+			<ul class="lst">
+				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
+			<ul class="lst">
+				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
+			</ul>
+		</div>
+	</div>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", selected:true, moveTo:"group1"'>Featured</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"categ"'>Categories</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-10.png", icon2:"images/tab-icon-10h.png", moveTo:"top25"'>Top 25</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-11.png", icon2:"images/tab-icon-11h.png", moveTo:"search"'>Search</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-13.png", icon2:"images/tab-icon-13h.png", moveTo:"article"'>Updates</li>
+	</ul>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-demo.html b/dojox/mobile/tests/test_ScrollableView-demo.html
new file mode 100644
index 0000000..339980b
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-demo.html
@@ -0,0 +1,399 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView demo</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/TabBar"
+		]);
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	.list1 li{
+		border-style: solid;
+		border-width: 1px 0px 1px 0px;
+		border-top-color: #BABABC;
+		border-bottom-color: #89898C;
+		background-color: #ACACAF;
+		line-height: 0px;
+	}
+	.list1 li table{
+		line-height: normal;
+	}
+	.list1 li:nth-child(even){
+		background-color: #97979B;
+	}
+	#list2 li:nth-child(even){
+		background-color: #eeeeee;
+	}
+	#categ1 {
+		font-size: 18px;
+	}
+	#categ1 li{
+		line-height: 70px;
+	}
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	.content {
+		padding:0px 10px;
+		background-color: white;
+	}
+	p {
+		font-family: Helvetica;
+		font-size: 12px;
+	}
+	.title {
+		color: blue;
+		margin-bottom: 4px;
+	}
+	.subtitle {
+		font-style: italic;
+		color: gray;
+		margin: 0px;
+		margin-bottom: 4px;
+	}
+	.subsubtitle {
+		margin: 16px 0px 0px 0px;
+	}
+	.lst {
+		margin: 0px;
+		padding: 0px 14px;
+	}
+	.lst li {
+		font-family: Helvetica;
+		font-size: 12px;
+		margin: 0px;
+		list-style-type: square;
+	}
+	.iphone_theme .mblTabBarSegmentedControl .mblTabBarButtonIconArea {
+		display: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:{"iphone_theme":"segmentedControl","*":"tallTab"}, fixed:"top"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", moveTo:"view1", selected:true'>New</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"view2"'>What's Hot</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-10.png", icon2:"images/tab-icon-10h.png", moveTo:"view3"'>Genius</li>
+		</ul>
+
+		<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" class="list1">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+									Martin Parker Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" id="list2">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+					Network											   
+				</li>												   
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+					Line
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+					Songs
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+					Videos
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+					Photos
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+					Applications
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+					Capacity
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+					Available
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+					Version
+				</li>
+			</ul>
+		</div>
+	</div>
+
+	<div id="categ" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Categories</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" class="list1" id="categ1">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 1</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 2</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 3</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 4</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 5</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 6</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 7</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 8</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 9</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 10</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 11</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 12</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 13</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 14</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 15</li>
+		</ul>
+	</div>
+
+	<div id="top25" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>News</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Top Stories</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+				Top 10 news stories of the decade
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+				Create client-side diagrammatic interaction in Web applications with GFX
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+	</div>
+
+	<div id="search" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+
+	<div id="article" data-dojo-type="dojox.mobile.ScrollableView" style="color:black;background-color:white;height:100%">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Article</h1>
+		<div class="content">
+			<h3 class="title">Did you know?</h3>
+			<h4 class="subtitle">Features of dojox.mobile</h4>
+			<h5 class="subsubtitle">No images are used</h5>
+			<ul class="lst">
+				<li>UI parts consist of DOM and CSS3.</li>
+				<li>Only application icons are images.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
+			<ul class="lst">
+				<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Support for CSS sprite</h5>
+			<ul class="lst">
+				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
+			<ul class="lst">
+				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
+			</ul>
+		</div>
+	</div>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", selected:true, moveTo:"group1"'>Featured</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"categ"'>Categories</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-10.png", icon2:"images/tab-icon-10h.png", moveTo:"top25"'>Top 25</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-11.png", icon2:"images/tab-icon-11h.png", moveTo:"search"'>Search</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-13.png", icon2:"images/tab-icon-13h.png", moveTo:"article"'>Updates</li>
+	</ul>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-fixedFooters.html b/dojox/mobile/tests/test_ScrollableView-fixedFooters.html
new file mode 100644
index 0000000..70813dc
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-fixedFooters.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Test that TabBar is at the bottom of the viewport on each view</title>
+
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+		         "dojox/mobile/parser",
+		         "dojox/mobile",
+		         "dojox/mobile/compat",
+		         "dojox/mobile/ScrollableView",
+		         "dojox/mobile/TabBar"
+		     ]);
+	</script>
+
+</head>
+<body style="visibility:hidden;">
+
+    <div id="tabBar" data-dojo-type="dojox.mobile.View">
+    
+        <div id="groups" data-dojo-type="dojox.mobile.View">    
+            <div id="tabHome1" data-dojo-type="dojox.mobile.ScrollableView"
+                selected="true" fixedFooter="thetabbar">
+                <h1 data-dojo-type="dojox.mobile.Heading" fixed="top">Home1</h1>
+                <div data-dojo-type="dojox.mobile.EdgeToEdgeList"
+                    class="edgeToEdgeList">
+                    <li data-dojo-type="dojox.mobile.ListItem" moveTo="tabHome2">To Home2</li>
+                </div>
+            </div>
+            <div id="tabHome2" data-dojo-type="dojox.mobile.ScrollableView" fixedFooter="thetabbar">
+                <h1 data-dojo-type="dojox.mobile.Heading" fixed="top">Home2</h1>
+                <div data-dojo-type="dojox.mobile.EdgeToEdgeList"
+                    class="edgeToEdgeList">
+                    <li data-dojo-type="dojox.mobile.ListItem" moveTo="tabHome1">To Home1</li>
+                </div>
+                <h1 data-dojo-type="dojox.mobile.Heading" fixed="bottom">status bar</h1>
+            </div>            
+        </div>
+        
+        <div id="tabEvents" data-dojo-type="dojox.mobile.ScrollableView">
+            <h1 data-dojo-type="dojox.mobile.Heading" fixed="top">Events</h1>
+            <div data-dojo-type="dojox.mobile.RoundRect" shadow="true">Events</div>
+        </div>
+
+        <ul id="thetabbar" data-dojo-type="dojox.mobile.TabBar" fixed="bottom"
+            iconBase="images/tab-icons.png">
+            <li data-dojo-type="dojox.mobile.TabBarButton" moveTo="groups"
+                iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Home</li>
+            <li data-dojo-type="dojox.mobile.TabBarButton" moveTo="tabEvents"
+                iconPos1="0,29,29,29" iconPos2="29,29,29,29">Events</li>
+        </ul>
+    </div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-h.html b/dojox/mobile/tests/test_ScrollableView-h.html
new file mode 100644
index 0000000..1b65c84
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-h.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-h</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	td {
+		white-space: nowrap;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='scrollDir:"h"'>
+		<!-- h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Animations</h1 -->
+		<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;color:black;background-color:white;">
+<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
+		</table>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-hv-ah-af.html b/dojox/mobile/tests/test_ScrollableView-hv-ah-af.html
new file mode 100644
index 0000000..f2493f7
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-hv-ah-af.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-hv-ah-af</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	td {
+		white-space: nowrap;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Application Header Bar</h1>
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='scrollDir:"hv"'>
+		<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;color:black;background-color:white;">
+<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>644</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-3.png</td><td>2010/04/13</td><td>06:37</td><td>1,346</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>677</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-10.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>680</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-3.png</td><td>2010/03/23</td><td>13:03</td><td>682</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>697</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-5.png</td><td>2010/03/23</td><td>13:03</td><td>693</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-6.png</td><td>2010/03/23</td><td>13:03</td><td>694</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-7.png</td><td>2010/03/23</td><td>13:03</td><td>691</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-8.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-9.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-all.png</td><td>2010/03/23</td><td>13:03</td><td>4,450</td><td>mobile/tests/images</td></tr>
+<tr><td>icon-1.png</td><td>2010/05/06</td><td>08:57</td><td>2,626</td><td>mobile/tests/images</td></tr>
+<tr><td>not-images.png</td><td>2010/04/13</td><td>06:37</td><td>18,459</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-bg.png</td><td>2010/04/13</td><td>06:37</td><td>178</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-sel-bg.png</td><td>2010/04/13</td><td>06:37</td><td>185</td><td>mobile/tests/images</td></tr>
+<tr><td>test_Android-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,750</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,835</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,615</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,634</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,142</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Settings.html</td><td>2010/10/05</td><td>21:08</td><td>4,375</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>1,000</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,031</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,570</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2-prog.html</td><td>2010/10/03</td><td>22:28</td><td>1,089</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2.html</td><td>2010/10/03</td><td>22:28</td><td>872</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V2H2.html</td><td>2010/10/03</td><td>22:28</td><td>1,088</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V3.html</td><td>2010/10/03</td><td>22:28</td><td>996</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-html.html</td><td>2010/10/05</td><td>21:09</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-json.html</td><td>2010/10/05</td><td>21:08</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_anchor-label.html</td><td>2010/10/05</td><td>21:08</td><td>2,959</td><td>mobile/tests</td></tr>
+<tr><td>test_bookmarkable.html</td><td>2010/10/05</td><td>21:09</td><td>4,443</td><td>mobile/tests</td></tr>
+<tr><td>test_buttons.html</td><td>2010/10/05</td><td>21:08</td><td>972</td><td>mobile/tests</td></tr>
+<tr><td>test_css-sprite.html</td><td>2010/10/05</td><td>21:09</td><td>5,779</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-icons.html</td><td>2010/10/05</td><td>21:08</td><td>2,080</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-items.html</td><td>2010/10/05</td><td>21:08</td><td>3,375</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-view.html</td><td>2010/10/05</td><td>21:09</td><td>1,657</td><td>mobile/tests</td></tr>
+<tr><td>test_hash-parameter.html</td><td>2010/10/05</td><td>21:09</td><td>2,679</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings-fixed.html</td><td>2010/10/03</td><td>22:28</td><td>8,866</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings.html</td><td>2010/10/03</td><td>22:28</td><td>6,904</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Animation.html</td><td>2010/10/05</td><td>21:08</td><td>3,343</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Button.html</td><td>2010/10/05</td><td>21:09</td><td>1,766</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,135</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,809</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,613</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Heading.html</td><td>2010/10/05</td><td>21:08</td><td>1,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,588</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconMulti.html</td><td>2010/10/05</td><td>21:08</td><td>1,863</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingle.html</td><td>2010/10/05</td><td>21:09</td><td>1,814</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingleBelow.html</td><td>2010/10/05</td><td>21:08</td><td>1,815</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ResultList.html</td><td>2010/10/05</td><td>21:08</td><td>2,708</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRect.html</td><td>2010/10/05</td><td>21:08</td><td>1,155</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Settings.html</td><td>2010/10/05</td><td>21:09</td><td>5,666</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>998</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,262</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,550</td><td>mobile/tests</td></tr>
+<tr><td>test_progress-indicator.html</td><td>2010/10/05</td><td>21:08</td><td>3,124</td><td>mobile/tests</td></tr>
+<tr><td>test_transition-to-dynamic-view.html</td><td>2010/10/05</td><td>21:08</td><td>2,525</td><td>mobile/tests</td></tr>
+<tr><td>view-sample.html</td><td>2010/05/06</td><td>20:30</td><td>1,724</td><td>mobile/tests</td></tr>
+<tr><td>view1.html</td><td>2010/05/06</td><td>20:28</td><td>378</td><td>mobile/tests</td></tr>
+<tr><td>view1.json</td><td>2010/05/28</td><td>00:30</td><td>371</td><td>mobile/tests</td></tr>
+<tr><td>view2.html</td><td>2010/05/06</td><td>21:20</td><td>619</td><td>mobile/tests</td></tr>
+<tr><td>view2.json</td><td>2010/05/28</td><td>00:30</td><td>737</td><td>mobile/tests</td></tr>
+<tr><td>view3.html</td><td>2010/10/05</td><td>21:09</td><td>963</td><td>mobile/tests</td></tr>
+<tr><td>view3.json</td><td>2010/10/05</td><td>21:09</td><td>1,054</td><td>mobile/tests</td></tr>
+<tr><td>widget-bg.png</td><td>2010/03/23</td><td>13:03</td><td>26,234</td><td>mobile/tests/images</td></tr>
+		</table>
+	</div>
+	<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Application Footer Bar</h1>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-hv-vh-vf.html b/dojox/mobile/tests/test_ScrollableView-hv-vh-vf.html
new file mode 100644
index 0000000..53f1734
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-hv-vh-vf.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-hv-vh-vf</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	td {
+		white-space: nowrap;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='scrollDir:"hv"'>
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View Header Bar</h1>
+		<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;color:black;background-color:white;">
+<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>644</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-3.png</td><td>2010/04/13</td><td>06:37</td><td>1,346</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>677</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-10.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>680</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-3.png</td><td>2010/03/23</td><td>13:03</td><td>682</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>697</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-5.png</td><td>2010/03/23</td><td>13:03</td><td>693</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-6.png</td><td>2010/03/23</td><td>13:03</td><td>694</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-7.png</td><td>2010/03/23</td><td>13:03</td><td>691</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-8.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-9.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-all.png</td><td>2010/03/23</td><td>13:03</td><td>4,450</td><td>mobile/tests/images</td></tr>
+<tr><td>icon-1.png</td><td>2010/05/06</td><td>08:57</td><td>2,626</td><td>mobile/tests/images</td></tr>
+<tr><td>not-images.png</td><td>2010/04/13</td><td>06:37</td><td>18,459</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-bg.png</td><td>2010/04/13</td><td>06:37</td><td>178</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-sel-bg.png</td><td>2010/04/13</td><td>06:37</td><td>185</td><td>mobile/tests/images</td></tr>
+<tr><td>test_Android-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,750</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,835</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,615</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,634</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,142</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Settings.html</td><td>2010/10/05</td><td>21:08</td><td>4,375</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>1,000</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,031</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,570</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2-prog.html</td><td>2010/10/03</td><td>22:28</td><td>1,089</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2.html</td><td>2010/10/03</td><td>22:28</td><td>872</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V2H2.html</td><td>2010/10/03</td><td>22:28</td><td>1,088</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V3.html</td><td>2010/10/03</td><td>22:28</td><td>996</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-html.html</td><td>2010/10/05</td><td>21:09</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-json.html</td><td>2010/10/05</td><td>21:08</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_anchor-label.html</td><td>2010/10/05</td><td>21:08</td><td>2,959</td><td>mobile/tests</td></tr>
+<tr><td>test_bookmarkable.html</td><td>2010/10/05</td><td>21:09</td><td>4,443</td><td>mobile/tests</td></tr>
+<tr><td>test_buttons.html</td><td>2010/10/05</td><td>21:08</td><td>972</td><td>mobile/tests</td></tr>
+<tr><td>test_css-sprite.html</td><td>2010/10/05</td><td>21:09</td><td>5,779</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-icons.html</td><td>2010/10/05</td><td>21:08</td><td>2,080</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-items.html</td><td>2010/10/05</td><td>21:08</td><td>3,375</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-view.html</td><td>2010/10/05</td><td>21:09</td><td>1,657</td><td>mobile/tests</td></tr>
+<tr><td>test_hash-parameter.html</td><td>2010/10/05</td><td>21:09</td><td>2,679</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings-fixed.html</td><td>2010/10/03</td><td>22:28</td><td>8,866</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings.html</td><td>2010/10/03</td><td>22:28</td><td>6,904</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Animation.html</td><td>2010/10/05</td><td>21:08</td><td>3,343</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Button.html</td><td>2010/10/05</td><td>21:09</td><td>1,766</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,135</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,809</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,613</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Heading.html</td><td>2010/10/05</td><td>21:08</td><td>1,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,588</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconMulti.html</td><td>2010/10/05</td><td>21:08</td><td>1,863</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingle.html</td><td>2010/10/05</td><td>21:09</td><td>1,814</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingleBelow.html</td><td>2010/10/05</td><td>21:08</td><td>1,815</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ResultList.html</td><td>2010/10/05</td><td>21:08</td><td>2,708</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRect.html</td><td>2010/10/05</td><td>21:08</td><td>1,155</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Settings.html</td><td>2010/10/05</td><td>21:09</td><td>5,666</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>998</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,262</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,550</td><td>mobile/tests</td></tr>
+<tr><td>test_progress-indicator.html</td><td>2010/10/05</td><td>21:08</td><td>3,124</td><td>mobile/tests</td></tr>
+<tr><td>test_transition-to-dynamic-view.html</td><td>2010/10/05</td><td>21:08</td><td>2,525</td><td>mobile/tests</td></tr>
+<tr><td>view-sample.html</td><td>2010/05/06</td><td>20:30</td><td>1,724</td><td>mobile/tests</td></tr>
+<tr><td>view1.html</td><td>2010/05/06</td><td>20:28</td><td>378</td><td>mobile/tests</td></tr>
+<tr><td>view1.json</td><td>2010/05/28</td><td>00:30</td><td>371</td><td>mobile/tests</td></tr>
+<tr><td>view2.html</td><td>2010/05/06</td><td>21:20</td><td>619</td><td>mobile/tests</td></tr>
+<tr><td>view2.json</td><td>2010/05/28</td><td>00:30</td><td>737</td><td>mobile/tests</td></tr>
+<tr><td>view3.html</td><td>2010/10/05</td><td>21:09</td><td>963</td><td>mobile/tests</td></tr>
+<tr><td>view3.json</td><td>2010/10/05</td><td>21:09</td><td>1,054</td><td>mobile/tests</td></tr>
+<tr><td>widget-bg.png</td><td>2010/03/23</td><td>13:03</td><td>26,234</td><td>mobile/tests/images</td></tr>
+		</table>
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">View Footer Bar</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-hv.html b/dojox/mobile/tests/test_ScrollableView-hv.html
new file mode 100644
index 0000000..f5595b3
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-hv.html
@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-hv</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	td {
+		white-space: nowrap;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='scrollDir:"hv"'>
+		<!-- h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Animations</h1 -->
+		<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;color:black;background-color:white;">
+<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>644</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-3.png</td><td>2010/04/13</td><td>06:37</td><td>1,346</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>677</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-10.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>680</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-3.png</td><td>2010/03/23</td><td>13:03</td><td>682</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>697</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-5.png</td><td>2010/03/23</td><td>13:03</td><td>693</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-6.png</td><td>2010/03/23</td><td>13:03</td><td>694</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-7.png</td><td>2010/03/23</td><td>13:03</td><td>691</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-8.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-9.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-all.png</td><td>2010/03/23</td><td>13:03</td><td>4,450</td><td>mobile/tests/images</td></tr>
+<tr><td>icon-1.png</td><td>2010/05/06</td><td>08:57</td><td>2,626</td><td>mobile/tests/images</td></tr>
+<tr><td>not-images.png</td><td>2010/04/13</td><td>06:37</td><td>18,459</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-bg.png</td><td>2010/04/13</td><td>06:37</td><td>178</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-sel-bg.png</td><td>2010/04/13</td><td>06:37</td><td>185</td><td>mobile/tests/images</td></tr>
+<tr><td>test_Android-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,750</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,835</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,615</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,634</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,142</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Settings.html</td><td>2010/10/05</td><td>21:08</td><td>4,375</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>1,000</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,031</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,570</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2-prog.html</td><td>2010/10/03</td><td>22:28</td><td>1,089</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2.html</td><td>2010/10/03</td><td>22:28</td><td>872</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V2H2.html</td><td>2010/10/03</td><td>22:28</td><td>1,088</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V3.html</td><td>2010/10/03</td><td>22:28</td><td>996</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-html.html</td><td>2010/10/05</td><td>21:09</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-json.html</td><td>2010/10/05</td><td>21:08</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_anchor-label.html</td><td>2010/10/05</td><td>21:08</td><td>2,959</td><td>mobile/tests</td></tr>
+<tr><td>test_bookmarkable.html</td><td>2010/10/05</td><td>21:09</td><td>4,443</td><td>mobile/tests</td></tr>
+<tr><td>test_buttons.html</td><td>2010/10/05</td><td>21:08</td><td>972</td><td>mobile/tests</td></tr>
+<tr><td>test_css-sprite.html</td><td>2010/10/05</td><td>21:09</td><td>5,779</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-icons.html</td><td>2010/10/05</td><td>21:08</td><td>2,080</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-items.html</td><td>2010/10/05</td><td>21:08</td><td>3,375</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-view.html</td><td>2010/10/05</td><td>21:09</td><td>1,657</td><td>mobile/tests</td></tr>
+<tr><td>test_hash-parameter.html</td><td>2010/10/05</td><td>21:09</td><td>2,679</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings-fixed.html</td><td>2010/10/03</td><td>22:28</td><td>8,866</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings.html</td><td>2010/10/03</td><td>22:28</td><td>6,904</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Animation.html</td><td>2010/10/05</td><td>21:08</td><td>3,343</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Button.html</td><td>2010/10/05</td><td>21:09</td><td>1,766</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,135</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,809</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,613</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Heading.html</td><td>2010/10/05</td><td>21:08</td><td>1,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,588</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconMulti.html</td><td>2010/10/05</td><td>21:08</td><td>1,863</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingle.html</td><td>2010/10/05</td><td>21:09</td><td>1,814</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingleBelow.html</td><td>2010/10/05</td><td>21:08</td><td>1,815</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ResultList.html</td><td>2010/10/05</td><td>21:08</td><td>2,708</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRect.html</td><td>2010/10/05</td><td>21:08</td><td>1,155</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Settings.html</td><td>2010/10/05</td><td>21:09</td><td>5,666</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>998</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,262</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,550</td><td>mobile/tests</td></tr>
+<tr><td>test_progress-indicator.html</td><td>2010/10/05</td><td>21:08</td><td>3,124</td><td>mobile/tests</td></tr>
+<tr><td>test_transition-to-dynamic-view.html</td><td>2010/10/05</td><td>21:08</td><td>2,525</td><td>mobile/tests</td></tr>
+<tr><td>view-sample.html</td><td>2010/05/06</td><td>20:30</td><td>1,724</td><td>mobile/tests</td></tr>
+<tr><td>view1.html</td><td>2010/05/06</td><td>20:28</td><td>378</td><td>mobile/tests</td></tr>
+<tr><td>view1.json</td><td>2010/05/28</td><td>00:30</td><td>371</td><td>mobile/tests</td></tr>
+<tr><td>view2.html</td><td>2010/05/06</td><td>21:20</td><td>619</td><td>mobile/tests</td></tr>
+<tr><td>view2.json</td><td>2010/05/28</td><td>00:30</td><td>737</td><td>mobile/tests</td></tr>
+<tr><td>view3.html</td><td>2010/10/05</td><td>21:09</td><td>963</td><td>mobile/tests</td></tr>
+<tr><td>view3.json</td><td>2010/10/05</td><td>21:09</td><td>1,054</td><td>mobile/tests</td></tr>
+<tr><td>widget-bg.png</td><td>2010/03/23</td><td>13:03</td><td>26,234</td><td>mobile/tests/images</td></tr>
+		</table>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-pullToRefresh.html b/dojox/mobile/tests/test_ScrollableView-pullToRefresh.html
new file mode 100644
index 0000000..288f20c
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-pullToRefresh.html
@@ -0,0 +1,186 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Pull to refresh</title>
+
+	<style type="text/css">
+
+		#pullToRefreshPanel {
+ 			position: absolute;
+			top: 0px;
+			width: 100%;
+			z-index: 100;
+			font-weight: bold;
+			overflow: hidden;
+			background-color: #E4E7EE;
+			padding-left: 20px;
+		}
+
+		#pullToRefreshPanel > div {
+			position: inherit;
+			bottom: 12px;
+			padding-left: 22px;
+			width: 100%;
+			height: 100%;
+			color: #6E8098;
+			background-repeat: no-repeat;
+			background-position: bottom left;
+		}
+
+		#pullToRefreshPanel > div > div {
+			position: absolute;
+			bottom: 4px;
+		}
+
+		.pullDownToUpdate > div {
+ 			background-image: url('images/pull-arrow.png');
+		}
+
+		.pullDownToUpdate > div > div:before {
+			content: "Pull down to update";
+		}
+
+		.releaseToUpdate > div {
+ 			background-image: url('images/release-arrow.png');
+		}
+		
+		.releaseToUpdate > div > div:before {
+			content: "Release to update";
+		}
+
+	</style>
+
+	<link rel="stylesheet" type="text/css" href="../themes/iphone/iphone.css"></link>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+	<script type="text/javascript">
+	require([
+	     	"dojo/ready",
+	     	"dojo/on",
+	     	"dojo/dom",
+	     	"dojo/dom-class",
+	     	"dijit/registry",
+	     	"dojox/mobile/parser",
+	     	"dojox/mobile",
+	     	"dojox/mobile/compat",
+	     	"dojox/mobile/ScrollableView",
+	     	"dojox/mobile/Heading",
+	     	"dojox/mobile/RoundRect",
+	     	"dojox/mobile/RoundRectList"
+	     ], function(ready, on, dom, domClass, registry){
+	     	ready(function(){				
+	     		var pullToRefreshPanel = dom.byId("pullToRefreshPanel");
+	     		var topMessage = dom.byId("topMessage");
+	     		var scrollableView = registry.byId("sview");
+	     		var pullToRefreshPanelDisplayed = false;
+	     		var refreshOnTouchEnd = false;
+	     		var numberOfUpdates = 0;
+
+	     		var displayPullToRefreshPanel = function() {
+ 					pullToRefreshPanelDisplayed = true;
+ 					pullToRefreshPanel.style.display="block";
+	     		};
+
+	     		var hidePullToRefreshPanel = function() {
+ 					pullToRefreshPanelDisplayed = false;
+ 					pullToRefreshPanel.style.display="none";
+	     		};
+	     		
+	     		scrollableView.on("beforescroll", function(evt){
+	     			if(evt.beforeTop){
+	     				// display the pullToRefreshPanel panel if it is not
+	     				if(!pullToRefreshPanelDisplayed){
+	     					displayPullToRefreshPanel();
+	     				}
+	     				// resize the pullToRefreshPanel according to the scroll destination
+	     				pullToRefreshPanel.style.height= evt.beforeTopHeight + "px";
+	     				pullToRefreshPanel.style.top= -evt.beforeTopHeight + "px";
+	     			}else{
+	     				// hide the pullToRefreshPanel panel if it is displayed
+	     				if(pullToRefreshPanelDisplayed){
+	     					hidePullToRefreshPanel();
+	     				}
+	     			}
+	     			if(evt.beforeTopHeight > 80){
+	     				domClass.remove(pullToRefreshPanel, "pullDownToUpdate");
+	     				domClass.add(pullToRefreshPanel, "releaseToUpdate");
+	     				refreshOnTouchEnd = true;
+	     			}else{
+	     				domClass.remove(pullToRefreshPanel, "releaseToUpdate");
+	     				domClass.add(pullToRefreshPanel, "pullDownToUpdate");
+	     				refreshOnTouchEnd = false;
+	     			}
+	     		});
+
+	     		scrollableView.on("touchend", function(evt){
+	     			// We're done scrolling:
+	     			// - hide the pullToRefreshPanel if it is displayed
+	     			// - perform refresh if specified
+     				if(pullToRefreshPanelDisplayed){
+     					hidePullToRefreshPanel();
+     				}
+     				if(refreshOnTouchEnd){
+     					refreshOnTouchEnd = false;
+     					topMessage.innerHTML = "Content updated " + ++numberOfUpdates + " time !";
+     				}
+	     		});
+
+	     	});
+	     });
+	</script>
+
+</head>
+<body style="visibility:hidden;">
+	<div id="sview" data-dojo-type="dojox.mobile.ScrollableView">
+ 		<h1 data-dojo-type="dojox.mobile.Heading" fixed="top">Pull to refresh</h1>
+		<div id="pullToRefreshPanel" style="display: none;">
+			<div><div></div></div>
+		</div>
+		<div id="topMessage" data-dojo-type="dojox.mobile.RoundRect">
+			This page implements a demo of the "pull to refresh" feature that can be seen in iOS applications like Facebook. Touch the screen and pull down to reveal the feature...
+		</div>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem">Item 001</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 002</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 003</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 004</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 005</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 006</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 007</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 008</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 009</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 010</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 011</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 012</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 013</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 014</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 015</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 016</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 017</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 018</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 019</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 020</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 021</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 022</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 023</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 024</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 025</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 026</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 027</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 028</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 029</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 030</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 031</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 032</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 033</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 034</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 035</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 036</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 037</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 038</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-scrollEvents.html b/dojox/mobile/tests/test_ScrollableView-scrollEvents.html
new file mode 100644
index 0000000..d4263d1
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-scrollEvents.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Scrollable events</title>
+
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dojo/on",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/Heading",
+			"dojox/mobile/RoundRect",
+			"dojox/mobile/RoundRectList"
+		], function(ready, on, registry){
+			ready(function(){
+				on(registry.byId("sview"), "beforescroll", function(evt){
+					console.log("beforescroll event received: beforeTopHeight=" + evt.beforeTopHeight + ", afterBottomHeight=" + evt.afterBottomHeight);
+					if(evt.afterBottomHeight > 40 || evt.beforeTopHeight > 40){
+						return false;
+					}
+				});
+				on(registry.byId("sview"), "afterscroll", function(evt){
+					console.log("afterscroll event received");
+					console.log(evt);
+				});
+			});
+		});
+	</script>
+
+</head>
+<body style="visibility:hidden;">
+	<div id="sview" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" fixed="top">Scroll Events</h1>
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			This is a scrollable view. It sends two different events, "beforescroll" and
+			"afterscroll" when it is scrolled. In this demo,
+			reception of afterscroll events are logged to the console, and scrolling more
+			than 40 pixels before or after the content of the view is disabled by the beforescroll
+			handler.
+		</div>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem">Item 001</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 002</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 003</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 004</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 005</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 006</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 007</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 008</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 009</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 010</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 011</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 012</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 013</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 014</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 015</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 016</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 017</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 018</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 019</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 020</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 021</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 022</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 023</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 024</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 025</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 026</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 027</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 028</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 029</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 030</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 031</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 032</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 033</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 034</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 035</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 036</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 037</li>
+			<li data-dojo-type="dojox.mobile.ListItem">Item 038</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading" fixed="bottom"></h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-short-inp.html b/dojox/mobile/tests/test_ScrollableView-short-inp.html
new file mode 100644
index 0000000..36cebdf
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-short-inp.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v-vh-vf</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	input{
+		width: 200px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View Header Bar</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="1">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="2">
+			</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">View Footer Bar</h1>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Another View Footer Bar</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-short.html b/dojox/mobile/tests/test_ScrollableView-short.html
new file mode 100644
index 0000000..b41e92f
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-short.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v-vh-vf</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View Header Bar</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 2
+			</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">View Footer Bar</h1>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Another View Footer Bar</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-v-ah-af-inp.html b/dojox/mobile/tests/test_ScrollableView-v-ah-af-inp.html
new file mode 100644
index 0000000..88ae5a5
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-v-ah-af-inp.html
@@ -0,0 +1,180 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v-ah-af</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	input{
+		width: 200px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Application Header Bar</h1>
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			scrollDir: vertical<br>
+			header: application-header<br>
+			footer: application-footer<br>
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="1">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="2">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="3">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="4">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="5">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="6">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="7">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="8">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="9">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="10">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="11">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="12">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="13">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="14">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="15">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="16">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="17">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="18">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="19">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="20">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="21">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="22">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="23">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="24">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="25">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="26">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="27">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="28">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="29">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="30">
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+	<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Application Footer Bar</h1>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-v-ah-af.html b/dojox/mobile/tests/test_ScrollableView-v-ah-af.html
new file mode 100644
index 0000000..14e647c
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-v-ah-af.html
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v-ah-af</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Application Header Bar</h1>
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			scrollDir: vertical<br>
+			header: application-header<br>
+			footer: application-footer<br>
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 5
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 6
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 7
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 8
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 9
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 10
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 11
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 12
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 13
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 14
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 15
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 16
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 17
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 18
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 19
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 20
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 21
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 22
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 23
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 24
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 25
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 26
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 27
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+	<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Application Footer Bar</h1>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-v-ah-inp.html b/dojox/mobile/tests/test_ScrollableView-v-ah-inp.html
new file mode 100644
index 0000000..112a2f1
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-v-ah-inp.html
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v-ah-af</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	input{
+		width: 200px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Application Header Bar</h1>
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			scrollDir: vertical<br>
+			header: application-header<br>
+			footer: application-footer<br>
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="1">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="2">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="3">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="4">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="5">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="6">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="7">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="8">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="9">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="10">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="11">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="12">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="13">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="14">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="15">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="16">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="17">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="18">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="19">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="20">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="21">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="22">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="23">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="24">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="25">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="26">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="27">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="28">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="29">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="30">
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-v-inp.html b/dojox/mobile/tests/test_ScrollableView-v-inp.html
new file mode 100644
index 0000000..28ebf6f
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-v-inp.html
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	input{
+		width: 200px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			scrollDir: vertical<br>
+			header: none<br>
+			footer: none<br>
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="1">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="2">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="3">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="4">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="5">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="6">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="7">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="8">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="9">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="10">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="11">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="12">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="13">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="14">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="15">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="16">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="17">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="18">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="19">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="20">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="21">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="22">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="23">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="24">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="25">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="26">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="27">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="28">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="29">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="30">
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-v-vh-af-inp.html b/dojox/mobile/tests/test_ScrollableView-v-vh-af-inp.html
new file mode 100644
index 0000000..f025738
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-v-vh-af-inp.html
@@ -0,0 +1,181 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v-vh-af</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	input{
+		width: 200px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View Header Bar</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			scrollDir: vertical<br>
+			header: view-header<br>
+			footer: application-footer<br>
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="1">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="2">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="3">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="4">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="5">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="6">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="7">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="8">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="9">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="10">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="11">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="12">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="13">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="14">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="15">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="16">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="17">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="18">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="19">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="20">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="21">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="22">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="23">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="24">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="25">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="26">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="27">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="28">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="29">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="30">
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+	<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Application Footer Bar</h1>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-v-vh-af.html b/dojox/mobile/tests/test_ScrollableView-v-vh-af.html
new file mode 100644
index 0000000..4b253ad
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-v-vh-af.html
@@ -0,0 +1,169 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v-vh-af</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View Header Bar</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			scrollDir: vertical<br>
+			header: view-header<br>
+			footer: application-footer<br>
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 5
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 6
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 7
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 8
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 9
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 10
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 11
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 12
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 13
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 14
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 15
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 16
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 17
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 18
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 19
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 20
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 21
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 22
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 23
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 24
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 25
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 26
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 27
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+	<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Application Footer Bar</h1>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-v-vh-inp.html b/dojox/mobile/tests/test_ScrollableView-v-vh-inp.html
new file mode 100644
index 0000000..073a56e
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-v-vh-inp.html
@@ -0,0 +1,180 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v-vh</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	input{
+		width: 200px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View Header Bar</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			scrollDir: vertical<br>
+			header: view-header<br>
+			footer: none<br>
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="1">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="2">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="3">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="4">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="5">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="6">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="7">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="8">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="9">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="10">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="11">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="12">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="13">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="14">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="15">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="16">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="17">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="18">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="19">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="20">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="21">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="22">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="23">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="24">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="25">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="26">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="27">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="28">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="29">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="30">
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-v-vh-vf-inp.html b/dojox/mobile/tests/test_ScrollableView-v-vh-vf-inp.html
new file mode 100644
index 0000000..d2be151
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-v-vh-vf-inp.html
@@ -0,0 +1,182 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v-vh-vf</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	input{
+		width: 200px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View Header Bar</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			scrollDir: vertical<br>
+			header: view-header<br>
+			footer: view-footer<br>
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="1">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="2">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="3">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="4">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="5">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="6">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="7">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="8">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="9">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				<input value="10">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				<input value="11">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				<input value="12">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				<input value="13">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				<input value="14">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				<input value="15">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="16">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="17">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="18">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="19">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="20">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="21">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="22">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="23">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="24">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="25">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="26">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="27">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+				<input value="28">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+				<input value="29">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+				<input value="30">
+			</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">View Footer Bar</h1>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Another View Footer Bar</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-v-vh-vf.html b/dojox/mobile/tests/test_ScrollableView-v-vh-vf.html
new file mode 100644
index 0000000..c6c16cb
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-v-vh-vf.html
@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v-vh-vf</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View Header Bar</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			scrollDir: vertical<br>
+			header: view-header<br>
+			footer: view-footer<br>
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 5
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 6
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 7
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 8
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 9
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 10
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 11
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 12
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 13
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 14
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 15
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 16
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 17
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 18
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 19
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 20
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 21
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 22
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 23
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 24
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 25
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 26
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 27
+			</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">View Footer Bar</h1>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">Another View Footer Bar</h1>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-v-vh.html b/dojox/mobile/tests/test_ScrollableView-v-vh.html
new file mode 100644
index 0000000..75d9ba5
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-v-vh.html
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v-vh</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View Header Bar</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			scrollDir: vertical<br>
+			header: view-header<br>
+			footer: none<br>
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 5
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 6
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 7
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 8
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 9
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 10
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 11
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 12
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 13
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 14
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 15
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 16
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 17
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 18
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 19
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 20
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 21
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 22
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 23
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 24
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 25
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 26
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 27
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableView-v.html b/dojox/mobile/tests/test_ScrollableView-v.html
new file mode 100644
index 0000000..c844ef2
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableView-v.html
@@ -0,0 +1,167 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ScrollableView-v</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			scrollDir: vertical<br>
+			header: none<br>
+			footer: none<br>
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 5
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 6
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 7
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 8
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 9
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 10
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 11
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 12
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 13
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 14
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 15
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 16
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 17
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 18
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 19
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 20
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 21
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 22
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 23
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 24
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 25
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 26
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 27
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_SimpleDialog-large.html b/dojox/mobile/tests/test_SimpleDialog-large.html
new file mode 100644
index 0000000..f96ff2a
--- /dev/null
+++ b/dojox/mobile/tests/test_SimpleDialog-large.html
@@ -0,0 +1,132 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Animation</title>
+
+	<link href="../themes/common/domButtons/DomButtonSilverCircleRedCross.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SimpleDialog','TextBox','Button']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/Button"
+		], function(registry){
+			show = function(){
+				registry.byId("dlg1").show();
+			}
+		});
+	</script>
+
+	<style>
+	#dlg1 {
+		top: 25%;
+		left: 25%;
+		width: 700px;
+		height: 550px;
+	}
+	#dlg1 TABLE {
+		margin: 20px;
+	}
+	#dlg1 INPUT, #dlg1 TEXTAREA {
+		background-color: #000000;
+		color: #ffffff;
+		width: 90%;
+		font-size: 17px;
+		margin: 4px;
+	}
+	#dlg1 TEXTAREA {
+		height: 160px;
+	}
+	.dlgTitle {
+		font-family: Helvetica;
+		font-size: 17px;
+		margin: 14px 14px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="dlg1" data-dojo-type="dojox.mobile.SimpleDialog" data-dojo-props='closeButton:true'>
+		<div class="dlgTitle">Account Information
+			<button id="btn1" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:60px;float:right;">Edit</button>
+		</div>
+		<hr/>
+		<table style="width:100%">
+			<tr>
+				<td style="width:250px"><img alt="" src="images/pic1.jpg" width="230" height="230"></td>
+				<td style="vertical-align:top">
+					<input data-dojo-type="dojox.mobile.TextBox" value="Kirena Kobe" readOnly="readOnly"><br>
+					<input data-dojo-type="dojox.mobile.TextBox" value="123-456-7891"><br>
+					<input data-dojo-type="dojox.mobile.TextBox" value="kkobe at acme.com">
+				</td>
+			</tr>
+			<tr>
+				<td colspan="2"><textarea>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi. Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis. Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae risus.</textarea></td>
+			</tr>
+		</table>
+	</div>
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<button onclick="show()">Show Dialog</button>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_SimpleDialog-load.html b/dojox/mobile/tests/test_SimpleDialog-load.html
new file mode 100644
index 0000000..194e8cf
--- /dev/null
+++ b/dojox/mobile/tests/test_SimpleDialog-load.html
@@ -0,0 +1,160 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Simple Dialog Test</title>
+
+	<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SimpleDialog','TextBox','Button','Slider']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/ProgressIndicator",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/Button",
+			"dojox/mobile/Slider",
+			"dojox/mobile/_ContentPaneMixin"
+		], function(dom, registry, ProgressIndicator){
+			show = function(dlg){
+				registry.byId(dlg).show();
+			}
+			hide = function(dlg){
+				registry.byId(dlg).hide();
+			}
+			var prog;
+			show_progress_indicator = function(dlg,cont){
+				show(dlg);
+				var container = dom.byId(cont);
+				prog = ProgressIndicator.getInstance();
+				container.appendChild(prog.domNode);
+				prog.start();
+				setTimeout(function(){
+					hide_progress_indicator(dlg);
+				}, 5000);
+			}
+			hide_progress_indicator = function(dlg){
+				prog.stop();
+				hide(dlg);
+			}
+		});
+
+	</script>
+
+	<style>
+		.mblSimpleDialogInput {
+			margin: 7px 0 14px;
+			width: 260px;
+		}
+		.mblSimpleDialogButton {
+			margin: 7px 0 0;
+			width: 262px;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialogButton2l {
+			float: left;
+			width: 127px;
+			margin: 7px 0 0;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialogButton2r {
+			float: right;
+			width: 127px;
+			margin: 7px 0 0;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialog .mblProgressIndicator {
+			position: relative;
+			margin: 14px 0 7px;
+			top: 0;
+		}
+
+		.mblSimpleDialog .mblListItem {
+			text-align: left;
+		}
+		
+		.windows_theme .mblDomButtonSilverCircleGrayButton > div,
+		.windows_theme .mblDomButtonSilverCircleGreenButton > div {
+			background-color: transparent !important;
+			background-image: none !important;
+			border: 2px solid white;
+			border-radius: 25px;
+		}
+		.windows_theme .mblDomButtonSilverCircleGrayButton > div > div {
+			background-color: transparent !important;
+			background-image: none !important;
+			border: none !important;
+		}
+		.windows_theme .mblDomButtonSilverCircleGreenButton > div > div {
+			background-color: white !important;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="dlg_message"
+		data-dojo-type="dojox.mobile.SimpleDialog"
+		data-dojo-mixins="dojox.mobile._ContentPaneMixin"
+		data-dojo-props='href:"data/dialog1.html"'></div>
+
+	<div id="dlg_confirm"
+		data-dojo-type="dojox.mobile.SimpleDialog"
+		data-dojo-mixins="dojox.mobile._ContentPaneMixin"
+		data-dojo-props='href:"data/dialog2.html"'></div>
+	
+	<div id="dlg_login"
+		data-dojo-type="dojox.mobile.SimpleDialog"
+		data-dojo-mixins="dojox.mobile._ContentPaneMixin"
+		data-dojo-props='href:"data/dialog3.html"'></div>
+
+	<div id="dlg_progress"
+		data-dojo-type="dojox.mobile.SimpleDialog"
+		data-dojo-mixins="dojox.mobile._ContentPaneMixin"
+		data-dojo-props='href:"data/dialog4.html"'></div>
+
+	<div id="dlg_volume"
+		data-dojo-type="dojox.mobile.SimpleDialog"
+		data-dojo-mixins="dojox.mobile._ContentPaneMixin"
+		data-dojo-props='href:"data/dialog5.html"'></div>
+
+	<div id="dlg_select"
+		data-dojo-type="dojox.mobile.SimpleDialog"
+		data-dojo-mixins="dojox.mobile._ContentPaneMixin"
+		data-dojo-props='href:"data/dialog6.html"'></div>
+
+	<div id="view" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Message Box <button onclick="show('dlg_message')">Show Dialog</button>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Confirmation Dialog <button onclick="show('dlg_confirm')">Show Dialog</button>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Login Dialog <button onclick="show('dlg_login')">Show Dialog</button>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Progress Indicator <button onclick="show_progress_indicator('dlg_progress','progress_indicator_container')">Show Dialog</button>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Volume Control <button onclick="show('dlg_volume')">Show Dialog</button>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Selectable List <button onclick="show('dlg_select')">Show Dialog</button>
+		</div>
+	</div>
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_SimpleDialog-spinWheel.html b/dojox/mobile/tests/test_SimpleDialog-spinWheel.html
new file mode 100644
index 0000000..7b4dfbd
--- /dev/null
+++ b/dojox/mobile/tests/test_SimpleDialog-spinWheel.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Simple Dialog with SpinWheel Test</title>
+
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+	require(["dojo/parser",
+	         "dojox/mobile",
+	         "dojox/mobile/Button",
+	         "dojox/mobile/SimpleDialog",
+	         "dojox/mobile/SpinWheel"]);
+	</script>
+
+</head>
+<body style="visibility:hidden;">
+    <div data-dojo-type="dojox/mobile/SimpleDialog" id="dialog" data-dojo-props="closeButton:true">
+        <div id="spin1" data-dojo-type="dojox/mobile/SpinWheel">
+             <div data-dojo-type="dojox/mobile/SpinWheelSlot"
+                 labelFrom="3000" labelTo="3100"
+                 style="width:70px;"></div>
+        </div>
+    </div>
+    
+    <button data-dojo-type="dojox/mobile/Button" data-dojo-props="label:'Click me'">
+        <script type="dojo/on" data-dojo-event="click">
+            require(['dijit/registry'], function(registry) {
+                registry.byId('dialog').show();
+                // the following won't be needed anymore when #15628 will be fixed
+                registry.byId('spin1').resize();
+            });
+        </script>   
+    </button>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_SimpleDialog.html b/dojox/mobile/tests/test_SimpleDialog.html
new file mode 100644
index 0000000..ebdc733
--- /dev/null
+++ b/dojox/mobile/tests/test_SimpleDialog.html
@@ -0,0 +1,185 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Simple Dialog Test</title>
+
+	<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SimpleDialog','TextBox','Button','Slider']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/ProgressIndicator",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/Button",
+			"dojox/mobile/Slider"
+		], function(dom, registry, ProgressIndicator){
+			show = function(dlg){
+				registry.byId(dlg).show();
+			}
+			hide = function(dlg){
+				registry.byId(dlg).hide();
+			}
+			var prog;
+			show_progress_indicator = function(dlg,cont){
+				show(dlg);
+				var container = dom.byId(cont);
+				prog = ProgressIndicator.getInstance();
+				container.appendChild(prog.domNode);
+				prog.start();
+				setTimeout(function(){
+					hide_progress_indicator(dlg);
+				}, 5000);
+			}
+			hide_progress_indicator = function(dlg){
+				prog.stop();
+				hide(dlg);
+			}
+		});
+
+	</script>
+
+	<style>
+		.mblSimpleDialogInput {
+			margin: 7px 0 14px;
+			width: 260px;
+		}
+		.mblSimpleDialogButton {
+			margin: 7px 0 0;
+			width: 262px;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialogButton2l {
+			float: left;
+			width: 127px;
+			margin: 7px 0 0;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialogButton2r {
+			float: right;
+			width: 127px;
+			margin: 7px 0 0;
+			font-size: 17px;
+			font-weight: bold;
+			opacity: 0.95;
+		}
+		.mblSimpleDialog .mblProgressIndicator {
+			position: relative;
+			margin: 14px 0 7px;
+			top: 0;
+		}
+
+		.mblSimpleDialog .mblListItem {
+			text-align: left;
+		}
+
+		.windows_theme .mblDomButtonSilverCircleGrayButton > div,
+		.windows_theme .mblDomButtonSilverCircleGreenButton > div {
+			background-color: transparent !important;
+			background-image: none !important;
+			border: 2px solid white;
+			border-radius: 25px;
+		}
+		.windows_theme .mblDomButtonSilverCircleGrayButton > div > div {
+			background-color: transparent !important;
+			background-image: none !important;
+			border: none !important;
+		}
+		.windows_theme .mblDomButtonSilverCircleGreenButton > div > div {
+			background-color: white !important;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="dlg_message" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div class="mblSimpleDialogTitle">Information</div>
+		<div class="mblSimpleDialogText">This is a sample dialog.</div>
+		<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton" style="width:100px;" onclick="hide('dlg_message')">OK</button>
+	</div>
+
+	<div id="dlg_confirm" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div class="mblSimpleDialogTitle">Rain Alert</div>
+		<div class="mblSimpleDialogText">Do you have an umbrella?</div>
+		<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton" onclick="hide('dlg_confirm')">No</button>
+		<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton mblBlueButton" onclick="hide('dlg_confirm')">Yes</button>
+	</div>
+	
+	<div id="dlg_login" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div class="mblSimpleDialogTitle">Mobile Community</div>
+		<div class="mblSimpleDialogText">Enter your ID and Password</div>
+		<input data-dojo-type="dojox.mobile.TextBox" class="mblSimpleDialogInput" type="text" data-dojo-props='selectOnClick:true, placeHolder:"ID"' style="margin-bottom: 0;" required>
+		<input data-dojo-type="dojox.mobile.TextBox" class="mblSimpleDialogInput" type="password" data-dojo-props='selectOnClick:true, placeHolder:"Password"' style="margin-top: 0;" required>
+		<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton2l" onclick="hide('dlg_login')">Cancel</button>
+		<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton2r mblBlueButton" onclick="hide('dlg_login')">OK</button>
+	</div>
+
+	<div id="dlg_progress" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div class="mblSimpleDialogText">Please wait for 5 seconds.</div>
+		<div class="mblSimpleDialogText" id="progress_indicator_container"></div>
+		<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton mblRedButton" onclick="hide_progress_indicator('dlg_progress')">Cancel</button>
+	</div>
+
+	<div id="dlg_volume" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div class="mblSimpleDialogTitle">Volume</div>
+		<div class="mblSimpleDialogText">Ringtone</div>
+		<input data-dojo-type="dojox.mobile.Slider" value="0" min="0" max="20" step="0.1" type="range" style="width:90%;">
+		<div class="mblSimpleDialogText">Media</div>
+		<input data-dojo-type="dojox.mobile.Slider" value="0" min="0" max="20" step="0.1" type="range" style="width:90%;">
+		<div class="mblSimpleDialogText">Alarm</div>
+		<input data-dojo-type="dojox.mobile.Slider" value="0" min="0" max="20" step="0.1" type="range" style="width:90%;">
+		<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton2l" onclick="hide('dlg_volume')">OK</button>
+		<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton2r" onclick="hide('dlg_volume')">Cancel</button>
+	</div>
+
+	<div id="dlg_select" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div class="mblSimpleDialogTitle">Animation</div>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='select:"single"'>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checkClass:"mblDomButtonSilverCircleGreenButton", uncheckClass:"mblDomButtonSilverCircleGrayButton"'>
+				No animations
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checkClass:"mblDomButtonSilverCircleGreenButton", uncheckClass:"mblDomButtonSilverCircleGrayButton"'>
+				Some animations
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checkClass:"mblDomButtonSilverCircleGreenButton", uncheckClass:"mblDomButtonSilverCircleGrayButton", checked:true'>
+				All animations
+			</li>
+		</ul>
+		<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton" style="width:60%;" onclick="hide('dlg_select')">Cancel</button>
+	</div>
+
+	<div id="view" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Message Box <button onclick="show('dlg_message')">Show Dialog</button>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Confirmation Dialog <button onclick="show('dlg_confirm')">Show Dialog</button>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Login Dialog <button onclick="show('dlg_login')">Show Dialog</button>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Progress Indicator <button onclick="show_progress_indicator('dlg_progress','progress_indicator_container')">Show Dialog</button>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Volume Control <button onclick="show('dlg_volume')">Show Dialog</button>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Selectable List <button onclick="show('dlg_select')">Show Dialog</button>
+		</div>
+	</div>
+			
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Slider.html b/dojox/mobile/tests/test_Slider.html
index 914fef1..6b8edec 100644
--- a/dojox/mobile/tests/test_Slider.html
+++ b/dojox/mobile/tests/test_Slider.html
@@ -3,70 +3,81 @@
 <head>
 	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
 	<title>Mobile Slider unit tests</title>
-	<style>
-		@import "../themes/iphone/Slider.css";
-		/* test overrides */
-		.mblSlider {
-			zoom: 1.1; /* for testing, to make it easier to touch the handle */
-		}
-		.mblSliderV {
-			width: 1px;
-			border: 0px none;
-		}
-		.mblSliderH .mblSliderProgressBar {
-			background:transparent url(progressBarAnim.gif) repeat;
-		}
-		.mblSliderV .mblSliderHandle {
-			background:transparent url(sliderVthumb.png) no-repeat;
-			border-width:0px;
-			border-radius:0;
-		}
-	</style>
 
-	<script src="../../../dojo/dojo.js" djConfig="parseOnLoad:true, isDebug: true"></script>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Slider']"></script>
+	<script src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, isDebug: true"></script>
 	<script type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dojox.mobile");		// This is a mobile app.
-		dojo.require("dojox.mobile.parser");	// This mobile app uses declarative programming with fast mobile parser
-		dojo.require("dojox.mobile.compat");	// This mobile app supports running on desktop browsers
-		dojo.require("dojox.mobile.deviceTheme");
-		dojo.require("dojox.mobile.Slider");
-		dojo.addOnLoad(function(){
-			var hasTouch = !!dojox.mobile.hasTouch;
+		require([
+			"doh/runner",
+			"dojo/sniff",
+			"dojo/ready",
+			"dojo/_base/window",
+			"dojo/dom",
+			"dojo/dom-style",
+			"dojo/dom-geometry",
+			"dijit/registry",
+			"dojox/mobile",
+			"dojox/mobile/parser",
+			"dojox/mobile/compat",
+			"dojox/mobile/Slider"
+		], function(doh, has, ready, win, dom, domStyle, domGeometry, registry) {	
+		ready(function(){
+			var hasTouch = has("touch");
+			var msPointer = navigator.msPointerEnabled;
+			var touchstart = msPointer?"MSPointerDown":"touchstart";
+			var touchmove = msPointer?"MSPointerMove":"touchmove";
+			var touchend = msPointer?"MSPointerUp":"touchend";
+			var transitionDuration = has("webkit")?"WebkitTransitionDuration":"transitionDuration";
+			function getZoom(widget){
+				var node = widget.domNode;
+				var bodyZoom = domStyle.get(win.body(), "zoom") || 1;
+				var nodeZoom = (has("ie") ? parseFloat(domStyle.get(node).getPropertyValue("zoom"))/100 : domStyle.get(node, "zoom")) || 1;
+				return nodeZoom * bodyZoom;
+			}
 			function fireTouchEvent(type, widget, x, y, delay){
 				function doit(){
 					var node = widget.domNode;
 					var handle = widget.handle;
-					var bodyZoom = dojo.style(dojo.body(), "zoom") || 1;
-					var nodeZoom = dojo.style(node, "zoom") || 1;
-					var scroll = dojo._docScroll();
-					var pos = dojo.position(node, false);
-					var handlePos = dojo.position(handle, false);
-					handlePos.l = handlePos.x * nodeZoom * bodyZoom + scroll.x;
-					handlePos.t = handlePos.y * nodeZoom * bodyZoom + scroll.y;
-					handlePos.r = handlePos.l + (handlePos.w - 1) * nodeZoom * bodyZoom;
-					handlePos.b = handlePos.t + (handlePos.h - 1) * nodeZoom * bodyZoom;
-					var touchX = (x + pos.x) * nodeZoom * bodyZoom + scroll.x;
-					var touchY = (y + pos.y) * nodeZoom * bodyZoom + scroll.y;
+					var zoom = getZoom(widget);
+					if(has("ie")){
+						x *= zoom;
+						y *= zoom;
+						zoom = 1;
+					}
+					var scroll = domGeometry.docScroll();
+					var pos = domGeometry.position(node, false);
+					var handlePos = domGeometry.position(handle, false);
+					handlePos.l = handlePos.x * zoom + scroll.x;
+					handlePos.t = handlePos.y * zoom + scroll.y;
+					handlePos.r = handlePos.l + (handlePos.w - 1) * zoom;
+					handlePos.b = handlePos.t + (handlePos.h - 1) * zoom;
+					var touchX = (x + pos.x) * zoom + scroll.x;
+					var touchY = (y + pos.y) * zoom + scroll.y;
 					var target = widget.touchBox;
 					// see if handle is under the touch pos
 					if(touchX >= handlePos.l && touchX <= handlePos.r && touchY >= handlePos.t && touchY <= handlePos.b){
 						target = handle;
 					}
-					var e = document.createEvent('Events');
-					if(!hasTouch){
+					var e = document.createEvent ? document.createEvent('Events') : document.createEventObject();
+					if(!hasTouch&&!msPointer){
 						switch(type){
-							case 'touchstart': type = 'mousedown'; break;
-							case 'touchmove': type = 'mousemove'; break;
-							case 'touchend': type = 'mouseup'; break;
+							case touchstart: type = 'mousedown'; break;
+							case touchmove: type = 'mousemove'; break;
+							case touchend: type = 'mouseup'; break;
 						}
 					}
-					e.initEvent(type, true, true);
+					if(document.createEvent){
+						e.initEvent(type, true, true);
+					}
 					e.touches = [ { pageX: touchX, pageY: touchY } ];
 					e.pageX = touchX;
 					e.pageY = touchY;
 					e.changedTouches = e.touches;
-					target.dispatchEvent(e);
+					if(document.createEvent){
+						target.dispatchEvent(e);
+					}else{
+						target.fireEvent("on"+type, e);
+					}
 				}
 				if(delay){
 					setTimeout(doit, delay);
@@ -74,20 +85,20 @@
 					doit();
 				}
 			}
-			var sh = dijit.byId('sh');
+			var sh = registry.byId('sh');
 			var sh_width = sh.domNode.offsetWidth;
 			var sh_height = sh.domNode.offsetHeight;
 			var sh_handle_width = sh.handle.offsetWidth;
 			var sh_handle_height = sh.handle.offsetHeight;
-			var sv = dijit.byId('sv');
+			var sv = registry.byId('sv');
 			var sv_width = sv.domNode.offsetWidth;
 			var sv_height = sv.domNode.offsetHeight;
 			var sv_handle_width = sv.handle.offsetWidth;
 			var sv_handle_height = sv.handle.offsetHeight;
 			var handle;
 			var speed = 0; // should be 0 unless it's a demo
-			dojo.style(sh.handle, "WebkitTransitionDuration", (speed >> 1) + "ms");
-			dojo.style(sv.handle, "WebkitTransitionDuration", (speed >> 1) + "ms");
+			domStyle.set(sh.handle, transitionDuration, (speed >> 1) + "ms");
+			domStyle.set(sv.handle, transitionDuration, (speed >> 1) + "ms");
 
 			doh.register("tap", [
 				{
@@ -101,11 +112,11 @@
 						}
 						var d = new doh.Deferred();
 						handle = sh.connect(sh, 'onChange', onChange);
-						fireTouchEvent('touchstart', sh, sh_width, sh_height >> 1, speed);
+						fireTouchEvent(touchstart, sh, sh_width, sh_height >> 1, speed);
 						return d;
 					},
 					tearDown: function(){
-						fireTouchEvent('touchend', sh, sh_width, sh_height >> 1);
+						fireTouchEvent(touchend, sh, sh_width, sh_height >> 1);
 						sh.disconnect(handle);
 					}
 				},
@@ -120,11 +131,11 @@
 						}
 						var d = new doh.Deferred();
 						handle = sh.connect(sh, 'onChange', onChange);
-						fireTouchEvent('touchstart', sh, 0, sh_height >> 1, speed);
+						fireTouchEvent(touchstart, sh, 0, sh_height >> 1, speed);
 						return d;
 					},
 					tearDown: function(){
-						fireTouchEvent('touchend', sh, 0, sh_height >> 1);
+						fireTouchEvent(touchend, sh, 0, sh_height >> 1);
 						sh.disconnect(handle);
 					}
 				},
@@ -139,11 +150,11 @@
 						}
 						var d = new doh.Deferred();
 						handle = sh.connect(sh, 'onChange', onChange);
-						fireTouchEvent('touchstart', sh, sh_width >> 1, sh_height >> 1, speed);
+						fireTouchEvent(touchstart, sh, sh_width >> 1, sh_height >> 1, speed);
 						return d;
 					},
 					tearDown: function(){
-						fireTouchEvent('touchend', sh, sh_width >> 1, sh_height >> 1);
+						fireTouchEvent(touchend, sh, sh_width >> 1, sh_height >> 1);
 						sh.disconnect(handle);
 					}
 				},
@@ -158,11 +169,11 @@
 						}
 						var d = new doh.Deferred();
 						handle = sv.connect(sv, 'onChange', onChange);
-						fireTouchEvent('touchstart', sv, sv_width >> 1, 0, speed);
+						fireTouchEvent(touchstart, sv, sv_width >> 1, 0, speed);
 						return d;
 					},
 					tearDown: function(){
-						fireTouchEvent('touchend', sv, sv_width >> 1, 0);
+						fireTouchEvent(touchend, sv, sv_width >> 1, 0);
 						sv.disconnect(handle);
 					}
 				},
@@ -177,11 +188,11 @@
 						}
 						var d = new doh.Deferred();
 						handle = sv.connect(sv, 'onChange', onChange);
-						fireTouchEvent('touchstart', sv, sv_width >> 1, sv_height, speed);
+						fireTouchEvent(touchstart, sv, sv_width >> 1, sv_height, speed);
 						return d;
 					},
 					tearDown: function(){
-						fireTouchEvent('touchend', sv, sv_width >> 1, sv_height);
+						fireTouchEvent(touchend, sv, sv_width >> 1, sv_height);
 						sv.disconnect(handle);
 					}
 				},
@@ -196,11 +207,11 @@
 						}
 						var d = new doh.Deferred();
 						handle = sv.connect(sv, 'onChange', onChange);
-						fireTouchEvent('touchstart', sv, sv_width >> 1, sv_height >> 1, speed);
+						fireTouchEvent(touchstart, sv, sv_width >> 1, sv_height >> 1, speed);
 						return d;
 					},
 					tearDown: function(){
-						fireTouchEvent('touchend', sv, sv_width >> 1, sv_height >> 1);
+						fireTouchEvent(touchend, sv, sv_width >> 1, sv_height >> 1);
 						sv.disconnect(handle);
 					}
 				}
@@ -218,9 +229,9 @@
 						}
 						var d = new doh.Deferred();
 						handle = sh.connect(sh, 'onChange', onChange);
-						fireTouchEvent('touchstart', sh, sh_width >> 1, sh_height >> 1);
-						fireTouchEvent('touchmove', sh, sh_width, sh_height >> 1, speed);
-						fireTouchEvent('touchend', sh, sh_width, sh_height >> 1, speed*2);
+						fireTouchEvent(touchstart, sh, sh_width >> 1, sh_height >> 1);
+						fireTouchEvent(touchmove, sh, sh_width, sh_height >> 1, speed);
+						fireTouchEvent(touchend, sh, sh_width, sh_height >> 1, speed*2);
 						return d;
 					},
 					tearDown: function(){
@@ -238,9 +249,9 @@
 						}
 						var d = new doh.Deferred();
 						handle = sh.connect(sh, 'onChange', onChange);
-						fireTouchEvent('touchstart', sh, sh_width, sh_height >> 1);
-						fireTouchEvent('touchmove', sh, 0, sh_height >> 1, speed);
-						fireTouchEvent('touchend', sh, 0, sh_height >> 1, speed*2);
+						fireTouchEvent(touchstart, sh, sh_width, sh_height >> 1);
+						fireTouchEvent(touchmove, sh, 0, sh_height >> 1, speed);
+						fireTouchEvent(touchend, sh, 0, sh_height >> 1, speed*2);
 						return d;
 					},
 					tearDown: function(){
@@ -258,8 +269,8 @@
 						}
 						var d = new doh.Deferred();
 						handle = sv.connect(sv, 'onChange', onChange);
-						fireTouchEvent('touchstart', sv, sv_width >> 1, sv_height >> 1);
-						fireTouchEvent('touchmove', sv, sv_width >> 1, 0, speed);
+						fireTouchEvent(touchstart, sv, sv_width >> 1, sv_height >> 1);
+						fireTouchEvent(touchmove, sv, sv_width >> 1, 0, speed);
 						return d;
 					},
 					tearDown: function(){
@@ -277,11 +288,11 @@
 						}
 						var d = new doh.Deferred();
 						handle = sv.connect(sv, 'onChange', onChange);
-						fireTouchEvent('touchmove', sv, sv_width >> 1, sv_height, speed);
+						fireTouchEvent(touchmove, sv, sv_width >> 1, sv_height, speed);
 						return d;
 					},
 					tearDown: function(){
-						fireTouchEvent('touchend', sv, sv_width >> 1, sv_height);
+						fireTouchEvent(touchend, sv, sv_width >> 1, sv_height);
 						sv.disconnect(handle);
 					}
 				}
@@ -296,8 +307,8 @@
 						sh.set('value', mid, true);
 						doh.is(mid, sh.get('value'), 'initial value');
 						var d = new doh.Deferred();
-						fireTouchEvent('touchstart', sh, (sh_width >> 1) + (sh_handle_width >> 2), sh_height >> 1, speed);
-						fireTouchEvent('touchend', sh, (sh_width >> 1) + (sh_handle_width >> 2), sh_height >> 1, speed);
+						fireTouchEvent(touchstart, sh, (sh_width >> 1) + (sh_handle_width >> 2), sh_height >> 1, speed);
+						fireTouchEvent(touchend, sh, (sh_width >> 1) + (sh_handle_width >> 2), sh_height >> 1, speed);
 						setTimeout(d.getTestCallback(function(){
 							doh.is(mid, sh.get('value'), 'right value');
 						}), 500+speed);
@@ -312,8 +323,8 @@
 						sh.set('value', mid, true);
 						doh.is(mid, sh.get('value'), 'initial value');
 						var d = new doh.Deferred();
-						fireTouchEvent('touchstart', sh, (sh_width >> 1) - (sh_handle_width >> 2), sh_height >> 1);
-						fireTouchEvent('touchend', sh, (sh_width >> 1) - (sh_handle_width >> 2), sh_height >> 1);
+						fireTouchEvent(touchstart, sh, (sh_width >> 1) - (sh_handle_width >> 2), sh_height >> 1);
+						fireTouchEvent(touchend, sh, (sh_width >> 1) - (sh_handle_width >> 2), sh_height >> 1);
 						setTimeout(d.getTestCallback(function(){
 							doh.is(mid, sh.get('value'), 'left value');
 						}), 500+speed);
@@ -328,8 +339,8 @@
 						sh.set('value', mid, true);
 						doh.is(mid, sh.get('value'), 'initial value');
 						var d = new doh.Deferred();
-						fireTouchEvent('touchstart', sh, (sh_width >> 1) + (sh_handle_width >> 1) + 2, sh_height >> 1, speed >> 1);
-						fireTouchEvent('touchend', sh, (sh_width >> 1) + (sh_handle_width >> 1) + 2, sh_height >> 1, speed >> 1);
+						fireTouchEvent(touchstart, sh, (sh_width >> 1) + (sh_handle_width >> 1) + 2, sh_height >> 1, speed >> 1);
+						fireTouchEvent(touchend, sh, (sh_width >> 1) + (sh_handle_width >> 1) + 2, sh_height >> 1, speed >> 1);
 						setTimeout(d.getTestCallback(function(){
 							doh.t(sh.get('value') > mid, 'right changed value ' + sh.get('value'));
 						}), 500+speed);
@@ -344,8 +355,8 @@
 						sh.set('value', mid, true);
 						doh.is(mid, sh.get('value'), 'initial value');
 						var d = new doh.Deferred();
-						fireTouchEvent('touchstart', sh, (sh_width >> 1) - ((sh_handle_width >> 1) + 2), sh_height >> 1, speed >> 1);
-						fireTouchEvent('touchend', sh, (sh_width >> 1) - ((sh_handle_width >> 1) + 2), sh_height >> 1, speed >> 1);
+						fireTouchEvent(touchstart, sh, (sh_width >> 1) - ((sh_handle_width >> 1) + 2), sh_height >> 1, speed >> 1);
+						fireTouchEvent(touchend, sh, (sh_width >> 1) - ((sh_handle_width >> 1) + 2), sh_height >> 1, speed >> 1);
 						setTimeout(d.getTestCallback(function(){
 							doh.t(sh.get('value') < mid, 'left changed value ' + sh.get('value'));
 						}), 500+speed);
@@ -360,8 +371,8 @@
 						sv.set('value', mid, true);
 						doh.is(mid, sv.get('value'), 'initial value');
 						var d = new doh.Deferred();
-						fireTouchEvent('touchstart', sv, sv_width >> 1, (sv_height >> 1) + (sv_handle_height >> 2), speed);
-						fireTouchEvent('touchend', sv, sv_width >> 1, (sv_height >> 1) + (sv_handle_height >> 2), speed);
+						fireTouchEvent(touchstart, sv, sv_width >> 1, (sv_height >> 1) + (sv_handle_height >> 2), speed);
+						fireTouchEvent(touchend, sv, sv_width >> 1, (sv_height >> 1) + (sv_handle_height >> 2), speed);
 						setTimeout(d.getTestCallback(function(){
 							doh.is(mid, sv.get('value'), 'bottom value');
 						}), 500+speed);
@@ -376,8 +387,8 @@
 						sv.set('value', mid, true);
 						doh.is(mid, sv.get('value'), 'initial value');
 						var d = new doh.Deferred();
-						fireTouchEvent('touchstart', sv, sv_width >> 1, (sv_height >> 1) - (sv_handle_height >> 2));
-						fireTouchEvent('touchend', sv, sv_width >> 1, (sv_height >> 1) - (sv_handle_height >> 2));
+						fireTouchEvent(touchstart, sv, sv_width >> 1, (sv_height >> 1) - (sv_handle_height >> 2));
+						fireTouchEvent(touchend, sv, sv_width >> 1, (sv_height >> 1) - (sv_handle_height >> 2));
 						setTimeout(d.getTestCallback(function(){
 							doh.is(mid, sv.get('value'), 'top value');
 						}), 500+speed);
@@ -392,8 +403,8 @@
 						sv.set('value', mid, true);
 						doh.is(mid, sv.get('value'), 'initial value');
 						var d = new doh.Deferred();
-						fireTouchEvent('touchstart', sv, sv_width >> 1, (sv_height >> 1) + (sv_handle_height >> 1) + 2, speed >> 1);
-						fireTouchEvent('touchend', sv, sv_width >> 1, (sv_height >> 1) + (sv_handle_height >> 1) + 2, speed >> 1);
+						fireTouchEvent(touchstart, sv, sv_width >> 1, (sv_height >> 1) + (sv_handle_height >> 1) + 2, speed >> 1);
+						fireTouchEvent(touchend, sv, sv_width >> 1, (sv_height >> 1) + (sv_handle_height >> 1) + 2, speed >> 1);
 						setTimeout(d.getTestCallback(function(){
 							doh.t(sv.get('value') < mid, 'bottom changed value ' + sv.get('value'));
 						}), 500+speed);
@@ -408,8 +419,8 @@
 						sv.set('value', mid, true);
 						doh.is(mid, sv.get('value'), 'initial value');
 						var d = new doh.Deferred();
-						fireTouchEvent('touchstart', sv, sv_width >> 1, (sv_height >> 1) - ((sv_handle_height >> 1) + 2), speed >> 1);
-						fireTouchEvent('touchend', sv, sv_width >> 1, (sv_height >> 1) - ((sv_handle_height >> 1) + 2), speed >> 1);
+						fireTouchEvent(touchstart, sv, sv_width >> 1, (sv_height >> 1) - ((sv_handle_height >> 1) + 2), speed >> 1);
+						fireTouchEvent(touchend, sv, sv_width >> 1, (sv_height >> 1) - ((sv_handle_height >> 1) + 2), speed >> 1);
 						setTimeout(d.getTestCallback(function(){
 							doh.t(sv.get('value') > mid, 'top changed value ' + sv.get('value'));
 						}), 500+speed);
@@ -418,45 +429,72 @@
 				}
 			]);
 
-			if(dojo.isWebKit){
+			if(has("webkit") || has("ie") >= 10){
 				doh.register("animation", {
 					name: "horizontal 100%",
 					timeout: 2000,
 					runTest: function(){
 						var d = new doh.Deferred();
-						fireTouchEvent('touchstart', sh, 0, sh_height >> 1, 0);
-						fireTouchEvent('touchend', sh, 0, sh_height >> 1, 0);
-						var startX = Math.round(dojo.position(sh.handle).x), midX, endX;
-						dojo.style(sh.handle, "WebkitTransitionDuration", "1000ms");
-						fireTouchEvent('touchstart', sh, sh_width, sh_height >> 1, 0);
-						fireTouchEvent('touchend', sh, sh_width, sh_height >> 1, 0);
+						fireTouchEvent(touchstart, sh, 0, sh_height >> 1, 0);
+						fireTouchEvent(touchend, sh, 0, sh_height >> 1, 0);
+						var startX = Math.round(domGeometry.position(sh.handle).x), midX, endX;
+						domStyle.set(sh.handle, transitionDuration, "1000ms");
+						fireTouchEvent(touchstart, sh, sh_width, sh_height >> 1, 0);
+						fireTouchEvent(touchend, sh, sh_width, sh_height >> 1, 0);
 						sh.set('value', sh.max, true);
 						setTimeout(function(){
-							midX = dojo.position(sh.handle).x;
+							midX = domGeometry.position(sh.handle).x;
 						}, 400); 
 						setTimeout(d.getTestCallback(function(){
-							endX = Math.round(dojo.position(sh.handle).x);
+							endX = Math.round(domGeometry.position(sh.handle).x);
 							doh.t(midX > startX, "started sliding");
 							doh.t(midX < endX, "continued sliding");
-							doh.t(Math.abs(Math.abs(endX-startX)-sh_width) <= 2, "stopped sliding end="+endX+',start='+startX+',width='+sh_width);
+							var zoom = has("ie") ? getZoom(sh) : 1;
+							doh.t(Math.abs(Math.abs(endX-startX)-sh_width*zoom) <= 3, "stopped sliding end="+endX+',start='+startX+',width='+sh_width*zoom);
 						}), 1100);
 						return d;
 					},
 					tearDown: function(){
-						dojo.style(sh.handle, "WebkitTransitionDuration", "");
-						dojo.style(sv.handle, "WebkitTransitionDuration", "");
+						domStyle.set(sh.handle, transitionDuration, "");
+						domStyle.set(sv.handle, transitionDuration, "");
 					}
 				})
 			}
 
 			doh.register("log", function(){
-				dojo.byId('failures').innerHTML = doh._failureCount;
-				dojo.byId('errors').innerHTML = doh._errorCount;
+				dom.byId('failures').innerHTML = doh._failureCount;
+				dom.byId('errors').innerHTML = doh._errorCount;
 			});
 
 			doh.run();
 		});
+		});
 	</script>
+
+	<style>
+		/* test overrides */
+		.mblSlider {
+			zoom: 1.1; /* for testing, to make it easier to touch the handle */
+		}
+		.mblSliderV {
+			width: 1px;
+			border: 0px none;
+		}
+		.mblSliderH .mblSliderProgressBar {
+			background:transparent url(images/progressBarAnim.gif) repeat;
+		}
+		.mblSliderV .mblSliderHandle {
+			background:transparent url(images/sliderVthumb.png) no-repeat;
+			border-width:0px;
+			border-radius:0;
+		}
+		.windows_theme .mblSliderV .mblSliderHandle {
+			background: white none;
+		}
+		.windows_theme .mblSliderH {
+			zoom: 0;
+		}
+	</style>
 </head>
 <body style="visibility:hidden;zoom:1.2;">
 	<form>
@@ -464,7 +502,7 @@
 		<center>
 			<table><tr>
 				<td>0</td>
-				<td><input id="sh" data-dojo-type="dojox.mobile.Slider" type="range" data-dojo-props='value:0, min:0, max:20, step:0.1, onChange:function(v){ dojo.byId("sh_val").innerHTML=this.value; }' style="width:200px;" /></td>
+				<td><input id="sh" data-dojo-type="dojox/mobile/Slider" type="range" data-dojo-props='value:0, min:0, max:20, step:0.1, onChange:function(v){ document.getElementById("sh_val").innerHTML=this.value; }' style="width:200px;" /></td>
 				<td>20</td>
 			</tr><tr>
 				<td></td><td><center>Value: <span id="sh_val">0</span></center></td><td></td>
@@ -475,7 +513,7 @@
 			<table><tr><td style="width:100px;">
 				<center>
 					20<br>
-					<input id="sv" name="sv" data-dojo-type="dojox.mobile.Slider" type="range" data-dojo-props='value:0, min:-20, max:20, step:1, intermediateChanges:true, onChange:function(v){ dojo.byId("sv_val").innerHTML=this.value; }' style="width:2px;height:200px;" />
+					<input id="sv" name="sv" data-dojo-type="dojox/mobile/Slider" type="range" data-dojo-props='value:0, min:-20, max:20, step:1, intermediateChanges:true, onChange:function(v){ document.getElementById("sv_val").innerHTML=this.value; }' style="width:2px;height:200px;" />
 					-20
 				</center>
 			</td><td style="width:80px;">
diff --git a/dojox/mobile/tests/test_SpinWheel-1slot.html b/dojox/mobile/tests/test_SpinWheel-1slot.html
index f5d30cb..653fce3 100644
--- a/dojox/mobile/tests/test_SpinWheel-1slot.html
+++ b/dojox/mobile/tests/test_SpinWheel-1slot.html
@@ -1,4 +1,4 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <!--
   A SpinWheel that has only one slot.
@@ -6,23 +6,27 @@
   Note that this test case does not load dojox.mobile themes such as iphone.css.
   Nor does it load the dojox.mobile base, i.e., not requiring "dojox.mobile".
 -->
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>One Slot SpinWheel</title>
-		<link href="../themes/common/SpinWheel.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>One Slot SpinWheel</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile.SpinWheel");
-			dojo.require("dojox.mobile.compat");
-		</script>
-	</head>
-	<body>
-		<div dojoType="dojox.mobile.SpinWheel" style="width:200px;padding-right:4px;">
-			<div dojoType="dojox.mobile.SpinWheelSlot"
-				labelFrom="3000" labelTo="3100" style="text-align:center;width:100%;"></div>
-		</div>
-	</body>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile/compat",
+			"dojox/mobile/SpinWheel"
+		]);
+	</script>
+</head>
+<body>
+	<div data-dojo-type="dojox.mobile.SpinWheel" style="width:200px;padding-right:4px;">
+		<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+			data-dojo-props='labelFrom:3000, labelTo:3100' style="text-align:center;width:100%;"></div>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_SpinWheel-custom.html b/dojox/mobile/tests/test_SpinWheel-custom.html
index 2563835..c173c4d 100644
--- a/dojox/mobile/tests/test_SpinWheel-custom.html
+++ b/dojox/mobile/tests/test_SpinWheel-custom.html
@@ -1,70 +1,74 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Custom SpinWheel</title>
-		<link href="../themes/common/SpinWheel.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<style>
-		#spin1 {
-			width: 304px;
-			margin: 10px auto;
- 		}
-		#pt {
-			width: 20px;
-		}
-		#txt {
-			width: 10px;
-			margin-left: -15px;
-			padding-top: 85px;
-			font-size: 24px;
-			font-weight: bold;
-			border: none;
-		}
-		</style>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Custom SpinWheel</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.SpinWheel");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojotype="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Custom SpinWheel</h1>
-			<div id="spin1" dojoType="dojox.mobile.SpinWheel">
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="['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']"
-					style="text-align:center;width:40px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labelFrom="3000" labelTo="3100"
-					style="width:70px;"></div>
-				<div id="pt" class="mblSpinWheelSlot"></div>
-				<div id="txt" class="mblSpinWheelSlot">.</div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labelFrom="0" labelTo="9"
-					style="width:30px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="['pt','px','cm']"
-					style="width:50px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="[
-						'<img src=images/i-icon-1.png>',
-						'<img src=images/i-icon-2.png>',
-						'<img src=images/i-icon-3.png>',
-						'<img src=images/i-icon-4.png>',
-						'<img src=images/i-icon-5.png>',
-						'<img src=images/i-icon-6.png>',
-						'<img src=images/i-icon-7.png>',
-						'<img src=images/i-icon-8.png>',
-						'<img src=images/i-icon-9.png>',
-						'<img src=images/i-icon-10.png>'
-					]"
-					style="width:70px;text-align: center;"></div>
-			</div>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SpinWheel"
+		]);
+	</script>
+
+	<style>
+	#spin1 {
+		width: 304px;
+		margin: 10px auto;
+	}
+	#pt {
+		width: 20px;
+	}
+	#txt {
+		width: 10px;
+		margin-left: -15px;
+		padding-top: 85px;
+		font-size: 24px;
+		font-weight: bold;
+		border: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Custom SpinWheel</h1>
+		<div id="spin1" data-dojo-type="dojox.mobile.SpinWheel">
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props='labelFrom:3000, labelTo:3100'
+				style="width:70px;"></div>
+			<div id="pt" class="mblSpinWheelSlot"></div>
+			<div id="txt" class="mblSpinWheelSlot">.</div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:30px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:['pt','px','cm']"
+				style="width:50px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:[
+					'<img src=images/i-icon-1.png>',
+					'<img src=images/i-icon-2.png>',
+					'<img src=images/i-icon-3.png>',
+					'<img src=images/i-icon-4.png>',
+					'<img src=images/i-icon-5.png>',
+					'<img src=images/i-icon-6.png>',
+					'<img src=images/i-icon-7.png>',
+					'<img src=images/i-icon-8.png>',
+					'<img src=images/i-icon-9.png>',
+					'<img src=images/i-icon-10.png>'
+				]"
+				style="width:70px;text-align: center;"></div>
 		</div>
-	</body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_SpinWheel-icons.html b/dojox/mobile/tests/test_SpinWheel-icons.html
index 6b5a56a..f3f3c2a 100644
--- a/dojox/mobile/tests/test_SpinWheel-icons.html
+++ b/dojox/mobile/tests/test_SpinWheel-icons.html
@@ -1,32 +1,37 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>SpinWheel with Icons</title>
-		<link href="../themes/common/SpinWheel.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<style>
-		#spin1 {
-			width: 312px;
-			margin: 10px auto;
-		}
-		</style>
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.SpinWheel");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojotype="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">SpinWheel with Icons</h1>
-			<div id="spin1" dojoType="dojox.mobile.SpinWheel">
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-				labels="[
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>SpinWheel with Icons</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SpinWheel"
+		]);
+	</script>
+
+	<style>
+	#spin1 {
+		width: 312px;
+		margin: 10px auto;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">SpinWheel with Icons</h1>
+		<div id="spin1" data-dojo-type="dojox.mobile.SpinWheel">
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:[
 					'<img src=images/i-icon-1.png>',
 					'<img src=images/i-icon-2.png>',
 					'<img src=images/i-icon-3.png>',
@@ -39,9 +44,9 @@
 					'<img src=images/i-icon-10.png>'
 				]"
 				style="text-align: center;">
-				</div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-				labels="[
+			</div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:[
 					'<img src=images/i-icon-1.png>',
 					'<img src=images/i-icon-2.png>',
 					'<img src=images/i-icon-3.png>',
@@ -54,9 +59,9 @@
 					'<img src=images/i-icon-10.png>'
 				]"
 				style="text-align: center;">
-				</div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-				labels="[
+			</div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:[
 					'<img src=images/i-icon-1.png>',
 					'<img src=images/i-icon-2.png>',
 					'<img src=images/i-icon-3.png>',
@@ -69,8 +74,8 @@
 					'<img src=images/i-icon-10.png>'
 				]"
 				style="text-align: center;">
-				</div>
 			</div>
 		</div>
-	</body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_SpinWheelDatePicker-setter.html b/dojox/mobile/tests/test_SpinWheelDatePicker-setter.html
new file mode 100644
index 0000000..786f8e3
--- /dev/null
+++ b/dojox/mobile/tests/test_SpinWheelDatePicker-setter.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>SpinWheel Date Picker - setter</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/SpinWheelDatePicker",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(ready, registry, SpinWheelDatePicker){
+			ready(function(){
+				registry.byId("picker1").set("value", "2000-10-24");
+				registry.byId("picker2").set("values", [2000,10,24]);
+
+				var picker5 = new SpinWheelDatePicker({value:"2000-10-24"}, "picker5");
+				picker5.startup();
+
+				var picker6 = new SpinWheelDatePicker({values:[2000,10,24]}, "picker6");
+				picker6.startup();
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<!-- All these widgets should display the same value. -->
+		<div id="picker1" data-dojo-type="dojox.mobile.SpinWheelDatePicker"></div><br>
+		<div id="picker2" data-dojo-type="dojox.mobile.SpinWheelDatePicker"></div><br>
+		<div id="picker3" data-dojo-type="dojox.mobile.SpinWheelDatePicker" data-dojo-props="value:'2000-10-24'"></div><br>
+		<div id="picker4" data-dojo-type="dojox.mobile.SpinWheelDatePicker" data-dojo-props="values:[2000,10,24]"></div><br>
+		<div id="picker5"></div><br>
+		<div id="picker6"></div><br>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_SpinWheelDatePicker-sv.html b/dojox/mobile/tests/test_SpinWheelDatePicker-sv.html
index d1406aa..9897c32 100644
--- a/dojox/mobile/tests/test_SpinWheelDatePicker-sv.html
+++ b/dojox/mobile/tests/test_SpinWheelDatePicker-sv.html
@@ -1,101 +1,108 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>SpinWheel Date Picker on ScrollableView</title>
-		<link href="../themes/common/SpinWheel.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<style>
-		#spin1 {
-			margin: 10px auto;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile.deviceTheme");
-		</script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-			dojo.require("dojox.mobile.SpinWheelDatePicker");
-			function gotoToday(){
-				dijit.byId("spin1").reset();
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>SpinWheel Date Picker on ScrollableView</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/SpinWheelDatePicker"
+		], function(registry){
+			gotoToday = function(){
+				registry.byId("spin1").reset();
 			}
-			function showSelectedValue() {
-				var w = dijit.byId("spin1");
-				console.log(w.slots[0].getValue()+ ":" + w.slots[1].getValue() + ":" + w.slots[2].getValue());
+			showSelectedValue = function(){
+				var w = registry.byId("spin1");
+				document.getElementById("msg").innerHTML =
+					w.slots[0].get("value")+ ":" + w.slots[1].get("value") + ":" + w.slots[2].get("value");
 			}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojotype="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">
-				<div dojoType="dojox.mobile.ToolBarButton" onClick="showSelectedValue()" label="OK"></div>
-				<div dojoType="dojox.mobile.ToolBarButton" onClick="gotoToday()" label="Today"></div>
-			</h1>
-			<div id="spin1" dojoType="dojox.mobile.SpinWheelDatePicker"></div>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					Item
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					Item
-				</li>
-			</ul>
+		});
+	</script>
+
+	<style>
+	#spin1 {
+		margin: 10px auto;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="showSelectedValue()" data-dojo-props='label:"OK"'></span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="gotoToday()" data-dojo-props='label:"Today"'></span>
 		</div>
-	</body>
+		<div id="spin1" data-dojo-type="dojox.mobile.SpinWheelDatePicker"></div>
+		<div id="msg"> </div>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Item
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Item
+			</li>
+		</ul>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_SpinWheelDatePicker.html b/dojox/mobile/tests/test_SpinWheelDatePicker.html
index 97793eb..de21134 100644
--- a/dojox/mobile/tests/test_SpinWheelDatePicker.html
+++ b/dojox/mobile/tests/test_SpinWheelDatePicker.html
@@ -1,38 +1,137 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>SpinWheel Date Picker</title>
-		<link href="../themes/common/SpinWheel.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<style>
-		#spin1 {
-			margin: 10px auto;
-		}
-		</style>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.SpinWheelDatePicker");
-			function gotoToday(){
-				dijit.byId("spin1").reset();
-			}
-			function showSelectedValue() {
-				var w = dijit.byId("spin1");
-				console.log(w.slots[0].getValue()+ ":" + w.slots[1].getValue() + ":" + w.slots[2].getValue());
-			}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojotype="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">
-				<div dojoType="dojox.mobile.ToolBarButton" onClick="showSelectedValue()" label="OK"></div>
-				<div dojoType="dojox.mobile.ToolBarButton" onClick="gotoToday()" label="Today"></div>
-			</h1>
-			<div id="spin1" dojoType="dojox.mobile.SpinWheelDatePicker"></div>
-		</div>
-	</body>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>SpinWheel Date Picker</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		var changeLocale, gotoToday, showSelectedValue;
+		var onYearSet, onMonthSet, onDaySet;
+		require([
+			"dojo/_base/kernel"
+		], function(dojo){
+			var lang = location.search.match(/lang=(\w*)/) ? RegExp.$1 : null;
+			if(lang){ dojo.locale = lang; }
+			require([
+				"dojo/_base/window",
+				"dojo/dom",
+				"dojo/ready",
+				"dijit/registry",
+				"dojo/_base/xhr",
+				"dojox/mobile/parser",
+				"dojox/mobile",
+				"dojox/mobile/compat",
+				"dojox/mobile/SpinWheelDatePicker"
+			], function(win, dom, ready, registry){
+				changeLocale = function(){
+					win.doc.forms[0].submit();
+				}
+				gotoToday = function(){
+					registry.byId("picker1").reset();
+				}
+				showSelectedValue = function(){
+					var w = registry.byId("picker1");
+					document.getElementById("msg").innerHTML =
+						w.slots[0].get("value")+ ":" + w.slots[1].get("value") + ":" + w.slots[2].get("value");
+				}
+				onYearSet = function(){
+					console.log("onYearSet value: " + this.slots[0].get("value"));
+				}
+				onMonthSet = function(){
+					console.log("onMonthSet value: " + this.slots[1].get("value"));
+				}
+				onDaySet = function(){
+					console.log("onDaySet value: " + this.slots[2].get("value"));
+				}
+				ready(function(){
+					dom.byId("sel").value = lang;
+								
+					var picker = registry.byId("picker1"),
+						yearSlot = picker.slots[0],
+						monthSlot = picker.slots[1],
+						daySlot = picker.slots[2];
+
+					yearSlot.watch("value", function(name, oldVal, newVal){
+						console.log("watch value of year slot: oldVal: " + oldVal + " newVal: " + newVal);
+  						document.getElementById("msg").innerHTML = 
+  							"watch value of year slot: oldVal: " + oldVal + " newVal: " + newVal;
+					});
+					monthSlot.watch("value", function(name, oldVal, newVal){
+						console.log("watch value of month slot: oldVal: " + oldVal + " newVal: " + newVal);
+  						document.getElementById("msg").innerHTML = 
+  							"watch value of month slot: oldVal: " + oldVal + " newVal: " + newVal;
+					});
+					daySlot.watch("value", function(name, oldVal, newVal){
+						console.log("watch value of day slot: oldVal: " + oldVal + " newVal: " + newVal);
+  						document.getElementById("msg").innerHTML = 
+  							"watch value of day slot: oldVal: " + oldVal + " newVal: " + newVal;
+					});
+				});
+			});
+		});
+	</script>
+
+	<style>
+	#picker1 {
+		margin: 10px auto;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<form>
+			<div data-dojo-type="dojox.mobile.Heading">
+				<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="showSelectedValue()" data-dojo-props='label:"OK"'></span>
+				<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="gotoToday()" data-dojo-props='label:"Today"'></span>
+				<select id="sel" name="lang" onchange="changeLocale()" style="float:left;margin-top:10px;">
+					<option value=""></option>
+					<option value="ar">ar</option>
+					<option value="ca">ca</option>
+					<option value="cs">cs</option>
+					<option value="da">da</option>
+					<option value="de">de</option>
+					<option value="el">el</option>
+					<option value="en">en</option>
+					<option value="en-au">en-au</option>
+					<option value="en-ca">en-ca</option>
+					<option value="en-gb">en-gb</option>
+					<option value="es">es</option>
+					<option value="fi">fi</option>
+					<option value="fr">fr</option>
+					<option value="fr-ch">fr-ch</option>
+					<option value="he">he</option>
+					<option value="hu">hu</option>
+					<option value="it">it</option>
+					<option value="ja">ja</option>
+					<option value="ko">ko</option>
+					<option value="nb">nb</option>
+					<option value="nl">nl</option>
+					<option value="pl">pl</option>
+					<option value="pt">pt</option>
+					<option value="pt-pt">pt-pt</option>
+					<option value="ro">ro</option>
+					<option value="ru">ru</option>
+					<option value="sk">sk</option>
+					<option value="sl">sl</option>
+					<option value="sv">sv</option>
+					<option value="th">th</option>
+					<option value="tr">tr</option>
+					<option value="zh">zh</option>
+					<option value="zh-hant">zh-hant</option>
+					<option value="zh-hk">zh-hk</option>
+					<option value="zh-tw">zh-tw</option>
+				</select>
+			</div>
+			<div id="picker1" data-dojo-type="dojox.mobile.SpinWheelDatePicker"
+				data-dojo-props="onYearSet: onYearSet, onMonthSet: onMonthSet, onDaySet: onDaySet">
+			</div>
+			<div id="msg"></div>
+		</form>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_SpinWheelTimePicker-setter.html b/dojox/mobile/tests/test_SpinWheelTimePicker-setter.html
new file mode 100644
index 0000000..34f8017
--- /dev/null
+++ b/dojox/mobile/tests/test_SpinWheelTimePicker-setter.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>SpinWheel Time Picker - setter</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/SpinWheelTimePicker",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(ready, registry, SpinWheelTimePicker){
+			ready(function(){
+				registry.byId("picker1").set("values", ["22","06"]);
+
+				var picker3 = new SpinWheelTimePicker({values:["22","06"]}, "picker3");
+				picker3.startup();
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<!-- All these widgets should display the same value. -->
+		<div id="picker1" data-dojo-type="dojox.mobile.SpinWheelTimePicker"></div><br>
+		<div id="picker2" data-dojo-type="dojox.mobile.SpinWheelTimePicker" data-dojo-props="values:['22','06']"></div><br>
+		<div id="picker3"></div><br>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_SpinWheelTimePicker.html b/dojox/mobile/tests/test_SpinWheelTimePicker.html
index a2c2e0c..e7b0f89 100644
--- a/dojox/mobile/tests/test_SpinWheelTimePicker.html
+++ b/dojox/mobile/tests/test_SpinWheelTimePicker.html
@@ -1,39 +1,47 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>SpinWheel Time Picker</title>
-		<link href="../themes/common/SpinWheel.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<style>
-		#spin1 {
-			margin: 10px auto;
-		}
-		</style>
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.SpinWheelTimePicker");
-			function gotoToday(){
-				dijit.byId("spin1").reset();
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>SpinWheel Time Picker</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SpinWheelTimePicker"
+		], function(registry){
+			gotoToday = function(){
+				registry.byId("spin1").reset();
 			}
-			function showSelectedValue() {
-				var w = dijit.byId("spin1");
-				console.log(w.slots[0].getValue()+ ":" + w.slots[1].getValue());
+			showSelectedValue = function(){
+				var w = registry.byId("spin1");
+				document.getElementById("msg").innerHTML =
+					w.slots[0].get("value")+ ":" + w.slots[1].get("value");
 			}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojotype="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">
-				<div dojoType="dojox.mobile.ToolBarButton" onClick="showSelectedValue()" label="OK"></div>
-				<div dojoType="dojox.mobile.ToolBarButton" onClick="gotoToday()" label="Now"></div>
-			</h1>
-			<div id="spin1" dojoType="dojox.mobile.SpinWheelTimePicker"></div>
+		});
+	</script>
+
+	<style>
+	#spin1 {
+		margin: 10px auto;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="showSelectedValue()" data-dojo-props='label:"OK"'></span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="gotoToday()" data-dojo-props='label:"Now"'></span>
 		</div>
-	</body>
+		<div id="spin1" data-dojo-type="dojox.mobile.SpinWheelTimePicker"></div>
+		<div id="msg"></div>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_StoreCarousel-demo.html b/dojox/mobile/tests/test_StoreCarousel-demo.html
new file mode 100644
index 0000000..9aa3d00
--- /dev/null
+++ b/dojox/mobile/tests/test_StoreCarousel-demo.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel Demo (dojo.store)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/store/JsonRest",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/StoreCarousel"
+		], function(connect, JsonRest, ready, registry){
+			store1 = new JsonRest({target: "data/carousel-categ.json"});
+			ready(function(){
+				connect.subscribe("/dojox/mobile/carouselSelect", function(w, img, item, idx){
+					if(w.id == "carousel1"){
+						var store2 = new JsonRest({target: "data/carousel-"+item.value+".json"});
+						var w2 = registry.byId("carousel2");
+						w2.set("title", item.value);
+						w2.setStore(store2);
+						registry.byId("rect1").domNode.style.display = "none";
+					}else if(w.id == "carousel2"){
+						var rect1 = registry.byId("rect1");
+						var u = "unknown";
+						var desc = "<div style='float:right;font:14px arial;width:49%'>Model: "+(item.model?item.model:u)+"<br>"+
+							"Design: "+(item.design?item.design:u)+"<br>"+
+							"Produced: "+(item.produced?item.produced:u)+"<br>"+
+							"Size: "+(item.size?item.size:u)+"<br>"+
+							"Price: "+(item.price?item.price:u)+"<br></div>";
+						rect1.containerNode.innerHTML = desc+"<img src='"+item.src+"' width='50%' align='top'>";
+						rect1.domNode.style.display = "";
+					}
+				});
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.ScrollableView">
+		<div id="carousel1" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='height:"150px", navButton:true, store:store1, itemWidth:156, title:"Category"'></div>
+		<div id="carousel2" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='height:"110px", navButton:true, itemWidth:100'></div>
+		<div id="rect1" data-dojo-type="dojox.mobile.RoundRect" style="display:none"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_StoreCarousel-prog.html b/dojox/mobile/tests/test_StoreCarousel-prog.html
new file mode 100644
index 0000000..2cdae54
--- /dev/null
+++ b/dojox/mobile/tests/test_StoreCarousel-prog.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel (dojo.store)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/_base/lang",
+			"dojo/ready",
+			"dojo/store/JsonRest",
+			"dojox/mobile/StoreCarousel",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/View"
+		], function(declare, lang, ready, JsonRest, StoreCarousel){
+			ready(function(){
+				var store1 = new JsonRest({target: "data/carousel-dish.json"});
+				var carousel1 = new StoreCarousel({height:"150px", navButton:true, store:store1, numVisible:"2", title:"Category"}, "carousel1");
+				carousel1.startup();
+			})
+		});
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<div id="carousel1"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_StoreCarousel-resize.html b/dojox/mobile/tests/test_StoreCarousel-resize.html
new file mode 100644
index 0000000..fefb777
--- /dev/null
+++ b/dojox/mobile/tests/test_StoreCarousel-resize.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel - resize</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/store/JsonRest",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/View",
+			"dojox/mobile/StoreCarousel"
+		], function(JsonRest){
+			store1 = new JsonRest({target: "data/carousel-shell.json"});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<div id="carousel1" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='height:"150px", navButton:true, store:store1, itemWidth:156, title:"Category"'></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_StoreCarousel-slideshow.html b/dojox/mobile/tests/test_StoreCarousel-slideshow.html
new file mode 100644
index 0000000..aa26eea
--- /dev/null
+++ b/dojox/mobile/tests/test_StoreCarousel-slideshow.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Lazy-loadable Carousel Photo Gallery</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/store/Memory",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/StoreCarousel"
+		]);
+
+		var json = [
+			{src:"images/pic1.jpg", alt:"Wally"},
+			{src:"images/pic2.jpg"},
+			{src:"images/pic3.jpg"},
+			{src:"images/pic4.jpg"},
+			{src:"images/pic5.jpg"},
+			{src:"images/pic6.jpg"},
+			{src:"images/pic7.jpg"},
+			{src:"images/pic8.jpg"},
+			{src:"images/pic9.jpg"},
+			{src:"images/pic10.jpg"}
+		];
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.ScrollableView">
+		<span data-dojo-id="store1" data-dojo-type="dojo.store.Memory" data-dojo-props='data:json'></span>
+		<div data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='height:"280px", store:store1, numVisible:1, title:"Photo Gallery", selectable:false'></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_StoreCarousel-widgets.html b/dojox/mobile/tests/test_StoreCarousel-widgets.html
new file mode 100644
index 0000000..b4f8a56
--- /dev/null
+++ b/dojox/mobile/tests/test_StoreCarousel-widgets.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel - widgets</title>
+
+	<link href="../../../dijit/themes/tundra/tundra.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator','SimpleDialog']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/store/JsonRest",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/StoreCarousel"
+		], function(connect, JsonRest, ready, registry){
+			store1 = new JsonRest({target: "data/carousel-widget.json"});
+			ready(function(){
+				connect.subscribe("/dojox/mobile/carouselSelect", function(carousel, itemWidget, item, idx){
+					if(carousel.id == "carousel1"){
+						console.log("selected: "+itemWidget);
+					}
+				});
+			});
+		});
+	</script>
+	<style>
+	.dijitCalendar {
+		color: black;
+	}
+	</style>
+</head>
+<body class="tundra" style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.ScrollableView">
+		<div id="carousel1" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='height:"250px", store:store1, numVisible:"1", title:"Category", selectable:false'></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_StoreCarousel.html b/dojox/mobile/tests/test_StoreCarousel.html
new file mode 100644
index 0000000..92e1b17
--- /dev/null
+++ b/dojox/mobile/tests/test_StoreCarousel.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Carousel (dojo.store)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Carousel','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/store/JsonRest",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/View",
+			"dojox/mobile/StoreCarousel"
+		], function(JsonRest){
+			store1 = new JsonRest({target: "data/carousel-dish.json"});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<div id="carousel1" data-dojo-type="dojox.mobile.StoreCarousel"
+			data-dojo-props='height:"150px", navButton:true, store:store1, numVisible:"2", title:"Category"'></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_SwapView-demo.html b/dojox/mobile/tests/test_SwapView-demo.html
new file mode 100644
index 0000000..a724a42
--- /dev/null
+++ b/dojox/mobile/tests/test_SwapView-demo.html
@@ -0,0 +1,241 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>SwapView Demo</title>
+
+	<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','PageIndicator','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/Pane",
+			"dojox/mobile/Container",
+			"dojox/mobile/SwapView",
+			"dojox/mobile/PageIndicator"
+		]);
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	.subtitle {
+		color: gray;
+		font-size: 12px;
+	}
+	#news {
+		font-size: 14px;
+	}
+	.list1 li{
+		color: black;
+	}
+	.list1 li.mblListItemSelected {
+		color: white;
+	}
+	.list1 li:nth-child(even){
+		background-color: #EAEAEA;
+	}
+	.list1 li:nth-child(odd){
+		background-color: white;
+	}
+	.list1 .mblListItemTextBox {
+		padding-right: 5px;
+	}
+	.c1 {
+		width: 120px;
+		float: left;
+	}
+	.c2 {
+		width: 80px;
+		text-align: right;
+		float: left;
+	}
+	.c3 {
+		text-align: right;
+		width: 70px;
+		color: white;
+		padding: 0px 4px;
+		margin-top: 4px;
+		height: 30px;
+		line-height: 32px;
+		float: right;
+		-webkit-border-radius: 4px;
+		-moz-border-radius: 4px;
+	}
+	.android_theme .c3 {
+		margin-top: 15px;
+	}
+	.android_theme .mblRoundRectList {
+		border-color: #666666;
+	}
+	.blackberry_theme .c3 {
+		margin-top: 13px;
+	}
+	.windows_theme .c3 {
+		width: 80px;
+	}
+	.c3a {
+		border: 2px solid #598F3A;
+		background-color: #6FB248;
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#6FB248), to(#54972D), color-stop(0.5, #5FA238), color-stop(0.5, #54972D));
+	}
+	.c3b {
+		border: 2px solid #9B322D;
+		background-color: #C13E37;
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#C13E37), to(#A6231C), color-stop(0.5, #B6332C), color-stop(0.5, #A8251E));
+	}
+	#tbl1 {
+		margin: auto;
+	}
+	#tbl1 td {
+		text-align: right;
+		border-bottom: 1px solid #DEE9F5;
+		font: bold 13px arial,helvetica,clean,sans-serif;
+	}
+	#tbl1 td:first-child {
+		text-align: left;
+	}
+	#tbl1 td.g {
+		color: #008800
+	}
+	#tbl1 td.r {
+		color: #CC0000
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"V"'>
+		<div data-dojo-type="dojox.mobile.Container" style="height:50%;overflow:hidden;">
+			<div id="general" data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='height:"inherit"'>
+				<ul data-dojo-type="dojox.mobile.RoundRectList" class="list1" data-dojo-props='stateful:true'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+						<div class="c1">Gold</div>
+						<div class="c2">3,400.20</div>
+						<div class="c3 c3a">+1.57%</div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+						<div class="c1">Oil</div>
+						<div class="c2">347.26</div>
+						<div class="c3 c3b">-0.82%</div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+						<div class="c1">Commodities</div>
+						<div class="c2">541.77</div>
+						<div class="c3 c3b">-0.43%</div>
+						
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+						<div class="c1">Silver</div>
+						<div class="c2">12,823.94</div>
+						<div class="c3 c3a">+0.17%</div>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+						<div class="c1">Soybeans</div>
+						<div class="c2">18.19</div>
+						<div class="c3 c3a">+2.77%</div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+						<div class="c1">Wheat</div>
+						<div class="c2">3,335</div>
+						<div class="c3 c3a">+1.62%</div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+						<div class="c1">Corn</div>
+						<div class="c2">29,930</div>
+						<div class="c3 c3a">+1.15%</div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#"'>
+						<div class="c1">Sugar</div>
+						<div class="c2">172.15</div>
+						<div class="c3 c3a">+0.00%</div>
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Pane" style="height:10px;overflow:hidden;">
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Container" style="overflow:hidden;">
+			<div id="swap1" data-dojo-type="dojox.mobile.SwapView">
+				<div data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='height:"100%"'>
+					<ul id="news" data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+						<li data-dojo-type="dojox.mobile.ListItem"
+							data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+							Oil prices rise as dollar weakens
+							<div class="subtitle">Daily News - 2011/05/02 15:40</div>
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem"
+							data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+							Same Old Story For Air Service Costs
+							<div class="subtitle">Daily News - 2011/05/02 14:30</div>
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem"
+							data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+							Local stocks mixed despite new trade data
+							<div class="subtitle">Daily News - 2011/05/02 14:10</div>
+						</li>
+
+						<li data-dojo-type="dojox.mobile.ListItem"
+							data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+							Stocks point higher after economic data
+							<div class="subtitle">Daily News - 2011/05/02 11:00</div>
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem"
+							data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+							Wall St seen higher after industry forecasts
+							<div class="subtitle">Daily News - 2011/05/01 16:05</div>
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem"
+							data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+							Stocks drop on slower job creation
+							<div class="subtitle">Daily News - 2011/05/01 15:50</div>
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem"
+							data-dojo-props='href:"test_ScrollableView-demo.html", hrefTarget:"_blank", arrowClass:"mblDomButtonBlueCircleArrow"'>
+							Dollar initially falls after revised jobs report
+							<div class="subtitle">Daily News - 2011/05/01 13:20</div>
+						</li>
+					</ul>
+				</div>
+			</div>
+
+			<div id="swap2" data-dojo-type="dojox.mobile.SwapView">
+				<div data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='height:"100%"'>
+					<div data-dojo-type="dojox.mobile.RoundRect" style="position:relative;">
+					<table id="tbl1" style="width:90%">
+						<tr><td>2 Yr Bond</td><td>113.75</td><td>0.00</td><td class="g">0.00%</td></tr>
+						<tr><td>N225</td><td>10,004.20</td><td>154.46</td><td class="g">1.57%</td></tr>
+						<tr><td>JKSE</td><td>3,816.44</td><td>32.87</td><td class="r">-0.85%</td></tr>
+						<tr><td>Seoul</td><td>2,200.73</td><td>28.23</td><td class="g">1.27%</td></tr>
+						<tr><td>TW</td><td>8,946.08</td><td>61.79</td><td class="r">-0.69%</td></tr>
+						<tr><td>Tokyo</td><td>2,932.19</td><td>20.68</td><td class="r">-0.71%</td></tr>
+						<tr><td>All</td><td>4,854.70</td><td>41.50</td><td class="r">-0.85%</td></tr>
+					</table>
+					</div>
+				</div>
+			</div>
+
+			<div id="swap3" data-dojo-type="dojox.mobile.SwapView">
+				<div data-dojo-type="dojox.mobile.ScrollableView" data-dojo-props='height:"100%"'>
+					<div data-dojo-type="dojox.mobile.RoundRect" style="overflow:hidden">
+						<img src="images/chart.png" alt="">
+					</div>
+				</div>
+			</div>
+
+			<div data-dojo-type="dojox.mobile.PageIndicator" data-dojo-props='fixed:"bottom"'></div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_SwapView-show.html b/dojox/mobile/tests/test_SwapView-show.html
new file mode 100644
index 0000000..b6a66b2
--- /dev/null
+++ b/dojox/mobile/tests/test_SwapView-show.html
@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+	<meta charset="utf-8">
+  	<title>Test Dojo</title>
+  	<link rel="stylesheet" href="../../../dojox/mobile/themes/iphone/iphone.css"/>
+  	<link rel="stylesheet" href="../../../dojox/mobile/themes/iphone/iphone-compat.css"/>
+  	<script src="../../../dojo/dojo.js" data-dojo-config="async:true, parseOnLoad:true, locale:'en', isDebug:true"></script>
+  	<script>
+  	    require([
+		"dojo/parser",
+		"dojo/ready",
+		// non referenced includes
+		"dojox/mobile",
+		"dojox/mobile/compat",
+		"dojox/mobile/SwapView",
+		"dojox/mobile/PageIndicator"
+	], function (parser, ready) {
+
+	    ready(function () {
+	        Button1.on('click', function(){
+	        	Pane1.show();
+	        	PageIndicator.reset();
+	        });
+	        
+	        Button2.on('click', function(){
+	        	var activeView = Pane1.getShowingView();
+	        	activeView.goTo(-1, 'Pane1');
+	        });
+	    });
+	});
+  	</script>
+  	<style>
+		.mblView {
+		  border-top: 1px solid transparent;
+		  border-bottom: 10px solid red;
+		}
+  	</style>
+</head>
+<body style="visibility:hidden;">
+	<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props="label:'Test SwapView'">
+		<span data-dojo-id="Button1" data-dojo-type="dojox/mobile/ToolBarButton">Go to Pane1</span>
+		<span data-dojo-id="Button2" data-dojo-type="dojox/mobile/ToolBarButton">Slide to Pane1</span>
+	</h1>
+		
+ 	<div data-dojo-type="dojox/mobile/PageIndicator" data-dojo-id="PageIndicator">
+  		</div>
+	
+	<div data-dojo-type="dojox/mobile/SwapView" data-dojo-id="Pane1" id="Pane1">
+    	<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+    		Swipe me to the left until Pane 3 is displayed, then click the Go to Pane1 button and check that everything is ok (including the page indicator value). Then do the same using the Slide to Pane1 button.
+    	</div>
+  	</div>
+
+  	<div data-dojo-type="dojox/mobile/SwapView" data-dojo-id="Pane2">
+    	<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+    		Pane 2
+    	</div>
+  	</div>
+
+  	<div data-dojo-type="dojox/mobile/SwapView" data-dojo-id="Pane3">
+    	<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props='shadow:true'>
+    		Pane 3
+    	</div>
+  	</div>
+  	
+</body>
+</html> 
\ No newline at end of file
diff --git a/dojox/mobile/tests/test_SwapView-slideshow.html b/dojox/mobile/tests/test_SwapView-slideshow.html
new file mode 100644
index 0000000..66ce32c
--- /dev/null
+++ b/dojox/mobile/tests/test_SwapView-slideshow.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>SwapView Slideshow</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','PageIndicator']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SwapView",
+			"dojox/mobile/PageIndicator"
+		]);
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+		margin: 0px;
+	}
+	img {
+		-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+		width: 90%;
+	}
+	h1 {
+		background-color: #3A3A3B;
+		color: #B1B1B1;
+		font: bold 16px arial,helvetica,clean,sans-serif;
+		margin: 0px 0px 15px 0px;
+		height: 45px;
+		line-height: 45px;
+		-webkit-box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.5);
+	}
+	.mblSwapView {
+		text-align: center;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;background-color:#6D6D6D">
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>My Pictures</h1>
+		<img alt="" src="images/pic1.jpg">
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>May 3, 2011</h1>
+		<img alt="" src="images/pic2.jpg">
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>May 3, 2011</h1>
+		<img alt="" src="images/pic3.jpg">
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>May 3, 2011</h1>
+		<img alt="" src="images/pic4.jpg">
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>Apr 24, 2011</h1>
+		<img alt="" src="images/pic5.jpg">
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>Apr 24, 2011</h1>
+		<img alt="" src="images/pic6.jpg">
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>Apr 24, 2011</h1>
+		<img alt="" src="images/pic7.jpg">
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>Apr 24, 2011</h1>
+		<img alt="" src="images/pic8.jpg">
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>Apr 24, 2011</h1>
+		<img alt="" src="images/pic9.jpg">
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1>Apr 24, 2011</h1>
+		<img alt="" src="images/pic10.jpg">
+	</div>
+
+	<div data-dojo-type="dojox.mobile.PageIndicator" data-dojo-props='fixed:"bottom"'></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_SwapView.html b/dojox/mobile/tests/test_SwapView.html
new file mode 100644
index 0000000..399f356
--- /dev/null
+++ b/dojox/mobile/tests/test_SwapView.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>SwapView</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/SwapView"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	html,body{
+		height: 100%;
+		overflow: hidden;
+		margin: 0px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Page flipping demo</h1>
+
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			Swipe the screen left or right to flip between the views.
+			There are 4 views in this demo.
+			Vertical scrolling and page indicator are not supported.
+		</div>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+		</ul>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container 1</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"app1", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"app2", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"app3", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"moveTo", icon:"images/icon-1.png", moveTo:"about", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"href", icon:"images/icon-1.png", href:"test_RoundRectList.html", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"url", icon:"images/icon-1.png", url:"data/view-sample.html", transition:"slide"'></li>
+		</ul>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.SwapView">
+		<h1 data-dojo-type="dojox.mobile.Heading">Icon Container 2</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"test1", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"test2", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem"
+			    data-dojo-props='label:"test3", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+		</ul>
+	</div>
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Switch-setter.html b/dojox/mobile/tests/test_Switch-setter.html
index d7499f7..e10db34 100644
--- a/dojox/mobile/tests/test_Switch-setter.html
+++ b/dojox/mobile/tests/test_Switch-setter.html
@@ -1,43 +1,99 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Switch setter/getter</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblThemeFiles: ['base']"></script>
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			function swOn(){
-				var w = dijit.byId("sw");
-				w.set("value", "on");
+<head>
+<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>Switch setter/getter</title>
+
+<script type="text/javascript" src="../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js"	data-dojo-config="async: true, parseOnLoad: true"></script>
+
+<script type="text/javascript">
+	require([
+		"dojo/_base/connect",
+		"dojo/dom",
+		"dojo/ready",
+		"dijit/registry",
+		"dojox/mobile/parser",
+		"dojox/mobile",
+		"dojox/mobile/compat"
+	], function(connect, dom, ready, registry, parser) {
+		swOn = function() {
+			var w = registry.byId("sw");
+			w.set("value", "on");
+		}
+		swOff = function() {
+			var w = registry.byId("sw");
+			w.set("value", "off");
+		}
+		swEnable = function() {
+			var w = registry.byId("sw2");
+			w.set("value", "on");
+		}
+		swDisable = function() {
+			var w = registry.byId("sw2");
+			w.set("value", "off");
+		}
+		setDisplay = function(id) {
+			var element = dom.byId(id);
+			var span = dom.byId("displayMsg");
+
+			var swId
+			// change state
+			swId = registry.byId(id + "1");
+			swId.set("value", (swId.get("value") == "on") ? "off" : "on");
+
+			// display
+			if (element) {
+				element.style.display = "inline";
+				span.innerHTML = "setting element " + id + " display = " + element.style.display;
+			} else {
+				span.innerHTML = "element " + id + " not found.";
 			}
-			function swOff(){
-				var w = dijit.byId("sw");
-				w.set("value", "off");
-			}
-			dojo.ready(function(){
-				var w = dijit.byId("sw");
-				dojo.connect(w, "onStateChanged", null, function(value){
-					var span = dojo.byId("msgArea");
-					span.innerHTML = "onStateChanged: "+value;
-					setTimeout(function(){
-						span.innerHTML = "";
-					}, 1000);
-				});
+			setTimeout(function() {
+				span.innerHTML = "";
+			}, 1000);
+		}
+
+		ready(function() {
+		    var w = registry.byId("sw");
+		    var w2 = registry.byId("sw2");
+		    connect.connect(w, "onStateChanged", null, function(value) {
+				var span = dom.byId("msgArea");
+				span.innerHTML = "onStateChanged: " + value;
+				setTimeout(function() {
+				    span.innerHTML = "";
+				}, 1000);
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojoType="dojox.mobile.View" selected="true" style="padding:10px">
-			<br>
-			<input type="checkbox" id="sw" name="swName" dojoType="dojox.mobile.Switch" value="off"><br>
+		});
+	});
+</script>
+</head>
+<body style="visibility: hidden;">
+	<div data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Switch</span><br />
+			<input type="checkbox" id="sw" name="swName" data-dojo-type="dojox.mobile.Switch" value="off"><br>
 			<input type="button" onclick="swOn()" value="on">
-			<input type="button" onclick="swOff()" value="off">
-			<span id="msgArea"></span>
+			<input type="button" onclick="swOff()" value="off"><br />
+			<span  id="msgArea"></span>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Initial state = off</span><br />
+			<input type="button" onclick="setDisplay('swOff')" value="Set state=on and display"><br />
+			<div id="swOff" style="display: none">
+				<input type="checkbox" id="swOff1" name="swName" data-dojo-type="dojox.mobile.Switch" value="off"><br />
+			</div>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Initial state = on</span><br />
+			<input type="button" onclick="setDisplay('swOn')" value="Set state=off and display"><br />
+			<div id="swOn" style="display: none">
+				<input type="checkbox" id="swOn1" name="swName" data-dojo-type="dojox.mobile.Switch" value="on"><br />
+			</div>
 		</div>
-	</body>
+		<span id="displayMsg"></span>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_Switch.html b/dojox/mobile/tests/test_Switch.html
new file mode 100644
index 0000000..3bc3254
--- /dev/null
+++ b/dojox/mobile/tests/test_Switch.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Switch</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+	
+	<style>
+	.color1 .mblSwitchBgLeft {
+		background: -webkit-gradient(linear, left top, left bottom, from(#28B159), to(#75FBAC), color-stop(0.5, #3FEB84), color-stop(0.5, #4CEE8E));
+	}
+	.color1 .mblSwitchBgRight {
+		background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+	}
+	.color2 .mblSwitchBgLeft {
+		background: -webkit-gradient(linear, left top, left bottom, from(#FF9D00), to(#FFCE80), color-stop(0.5, #FFBB4D), color-stop(0.5, #FFC871));
+	}
+	.color2 .mblSwitchBgRight {
+		background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+	}
+	.color1 .mblSwitchKnob,
+	.color2 .mblSwitchKnob {
+		background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#FAFAFA), color-stop(0.5, #BBBBBB), color-stop(0.5, #CACACA));
+	}
+	.mblSwitch {
+		margin-right: 10px;
+	}
+	.bold {
+		font-weight: bold;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Default Shape</span><br>
+			<div data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+			<div class="color1" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop"'></div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Square Shape</span><br>
+			<div class="mblSwSquareShape" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+			<div class="color2" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop", shape:"mblSwSquareShape"'></div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Round Shape 1</span><br>
+			<div class="mblSwRoundShape1" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+			<div class="color1" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop", shape:"mblSwRoundShape1"'></div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Round Shape 2</span><br>
+			<div class="mblSwRoundShape2" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+			<div class="color2" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop", shape:"mblSwRoundShape2"'></div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Arc Shape 1</span><br>
+			<div class="mblSwArcShape1" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+			<div class="color1" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop", shape:"mblSwArcShape1"'></div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			<span class="bold">Arc Shape 2</span><br>
+			<div class="mblSwArcShape2" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"off"'></div>
+			<div class="color2" data-dojo-type="dojox.mobile.Switch" data-dojo-props='value:"on", leftLabel:"Start", rightLabel:"Stop", shape:"mblSwArcShape2"'></div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_TabBar-badge.html b/dojox/mobile/tests/test_TabBar-badge.html
new file mode 100644
index 0000000..f8daf4f
--- /dev/null
+++ b/dojox/mobile/tests/test_TabBar-badge.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>TabBar with badge</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TabBar"
+		], function(registry){
+			test = function(i){
+				var w = registry.byId("btn"+i);
+				var badgeVal = w.get("badge");
+				w.set("badge", badgeVal ? null : "25");
+			}
+		});
+	</script>
+
+	<style>
+	.label {
+		font-family: "Helvetica Neue", Helvetica;
+		font-size: 13px;
+		margin-top: 20px;
+	}
+	.view {
+		font-size: 30px;
+		padding-top: 30px;
+		text-align: center;
+	}
+	</style>
+</head>
+<body style="padding-top:100px">
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='iconBase:"images/tab-icons.png"'>
+		<li id="btn0" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='iconPos1:"0,0,29,29", iconPos2:"29,0,29,29", selected:true, badge:"55"'>Featured</li>
+		<li id="btn1" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='iconPos1:"0,29,29,29", iconPos2:"29,29,29,29"'>Categories</li>
+		<li id="btn2" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='iconPos1:"0,58,29,29", iconPos2:"29,58,29,29"'>Top 25</li>
+		<li id="btn3" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='iconPos1:"0,87,29,29", iconPos2:"29,87,29,29"'>Search</li>
+		<li id="btn4" data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='iconPos1:"0,116,29,29", iconPos2:"29,116,29,29"'>Updates</li>
+	</ul>
+
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<div class="view">View 1</div>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<div class="view">View 2</div>
+	</div>
+	<div id="view3" data-dojo-type="dojox.mobile.View">
+		<div class="view">View 3</div>
+	</div>
+	<input type="button" onclick="test(0)" value="Featured">
+	<input type="button" onclick="test(1)" value="Categories">
+	<input type="button" onclick="test(2)" value="Top 25">
+	<input type="button" onclick="test(3)" value="Search">
+	<input type="button" onclick="test(4)" value="Updates">
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_TabBar-seg-grouped-scroll.html b/dojox/mobile/tests/test_TabBar-seg-grouped-scroll.html
new file mode 100644
index 0000000..9fa84da
--- /dev/null
+++ b/dojox/mobile/tests/test_TabBar-seg-grouped-scroll.html
@@ -0,0 +1,184 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>TabBar - Segmented Control</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+
+	<style>
+		html,body{
+			height: 100%;
+			overflow: hidden;
+		}
+		#list1 li{
+			border-style: solid;
+			border-width: 1px 0px 1px 0px;
+			border-top-color: #BABABC;
+			border-bottom-color: #89898C;
+			background-color: #ACACAF;
+			line-height: 0px;
+		}
+		#list1 li table{
+			line-height: normal;
+		}
+		#list1 li:nth-child(even){
+			background-color: #97979B;
+		}
+		.lnk {
+			font-size: 17px;
+			color: #0B5199;
+			text-decoration: none;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="group1" data-dojo-type="dojox.mobile.ScrollableView">
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", fixed:"top"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view1", selected:true'>New</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view2"'>What's Hot</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view3"'>Genius</li>
+		</ul>
+
+		<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" id="list1">
+				<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+									Martin Parker Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"hello"'>
+					Sounds
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"hello"'>
+					Brightness
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"hello"'>
+					Wallpaper
+				</li>
+			</ul>
+		</div>
+
+		<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"hello"'>
+					General
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"hello"'>
+					Mail, Contacts, Calendars
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"hello"'>
+					Phone
+				</li>
+			</ul>
+		</div>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.ScrollableView" id="hello">
+		<h1 data-dojo-type="dojox.mobile.Heading">
+			Hello
+		</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"group1"'>
+				Hello
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"group1"'>
+				Carrier
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_TabBar-seg-grouped.html b/dojox/mobile/tests/test_TabBar-seg-grouped.html
new file mode 100644
index 0000000..14d1691
--- /dev/null
+++ b/dojox/mobile/tests/test_TabBar-seg-grouped.html
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>TabBar - Segmented Control</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TabBar"
+		]);
+	</script>
+
+	<style>
+		#list1 li{
+			border-style: solid;
+			border-width: 1px 0px 1px 0px;
+			border-top-color: #BABABC;
+			border-bottom-color: #89898C;
+			background-color: #ACACAF;
+			line-height: 0px;
+		}
+		#list1 li table{
+			line-height: normal;
+		}
+		#list1 li:nth-child(even){
+			background-color: #97979B;
+		}
+		.lnk {
+			font-size: 17px;
+			color: #0B5199;
+			text-decoration: none;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="group1" data-dojo-type="dojox.mobile.View">
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view1", selected:true'>New</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view2"'>What's Hot</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view3"'>Genius</li>
+		</ul>
+
+		<div id="view1" data-dojo-type="dojox.mobile.View">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" id="list1">
+				<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+									Martin Parker Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view2" data-dojo-type="dojox.mobile.View">
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"hello"'>
+					Sounds
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"hello"'>
+					Brightness
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"hello"'>
+					Wallpaper
+				</li>
+			</ul>
+		</div>
+
+		<div id="view3" data-dojo-type="dojox.mobile.View">
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"hello"'>
+					General
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"hello"'>
+					Mail, Contacts, Calendars
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"hello"'>
+					Phone
+				</li>
+			</ul>
+		</div>
+	</div>
+
+	<div data-dojo-type="dojox.mobile.View" id="hello">
+		<h1 data-dojo-type="dojox.mobile.Heading">
+			Hello
+		</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"group1"'>
+				Hello
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"group1"'>
+				Carrier
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_TabBar-seg.html b/dojox/mobile/tests/test_TabBar-seg.html
new file mode 100644
index 0000000..92a700e
--- /dev/null
+++ b/dojox/mobile/tests/test_TabBar-seg.html
@@ -0,0 +1,163 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>TabBar - Segmented Control</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TabBar"
+		]);
+	</script>
+
+	<style>
+		#list1 li{
+			border-style: solid;
+			border-width: 1px 0px 1px 0px;
+			border-top-color: #BABABC;
+			border-bottom-color: #89898C;
+			background-color: #ACACAF;
+			line-height: 0px;
+		}
+		#list1 li table{
+			line-height: normal;
+		}
+		#list1 li:nth-child(even){
+			background-color: #97979B;
+		}
+		.lnk {
+			font-size: 17px;
+			color: #0B5199;
+			text-decoration: none;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"'>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view1", selected:true'>New</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view2"'>What's Hot</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view3"'>Genius</li>
+	</ul>
+
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" id="list1">
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+				<table>
+					<tbody>
+						<tr>
+							<td>
+								<img alt="" src="images/icon-1.png">
+							</td>
+							<td>
+								<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+								Sarah Connor Hardcover<br>
+								Eligible for FREE Super Saver Shipping
+							</td>
+						</tr>
+					</tbody>
+				</table>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+				<table>
+					<tbody>
+						<tr>
+							<td>
+								<img alt="" src="images/icon-1.png">
+							</td>
+							<td>
+								<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+								Martin Parker Hardcover<br>
+								Eligible for FREE Super Saver Shipping<br>
+							</td>
+						</tr>
+					</tbody>
+				</table>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+				<table>
+					<tbody>
+						<tr>
+							<td>
+								<img alt="" src="images/icon-1.png">
+							</td>
+							<td>
+								<a class="lnk" href="#">Total Solar Eclipse</a><br>
+								Steven Young Hardcover<br>
+								Eligible for FREE Super Saver Shipping<br>
+							</td>
+						</tr>
+					</tbody>
+				</table>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+				<table>
+					<tbody>
+						<tr>
+							<td>
+								<img alt="" src="images/icon-1.png">
+							</td>
+							<td>
+								<a class="lnk" href="#">The History of Java Coffee</a><br>
+								Marco Rodriguez Hardcover<br>
+								Eligible for FREE Super Saver Shipping<br>
+							</td>
+						</tr>
+					</tbody>
+				</table>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size: 10px;" data-dojo-props='variableHeight:true'>
+				<table>
+					<tbody>
+						<tr>
+							<td>
+								<img alt="" src="images/icon-1.png">
+							</td>
+							<td>
+								<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+								Melissa Morgan Hardcover<br>
+								Eligible for FREE Super Saver Shipping<br>
+							</td>
+						</tr>
+					</tbody>
+				</table>
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Sounds
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+				Brightness
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+				Wallpaper
+			</li>
+		</ul>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View">
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+				General
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+				Mail, Contacts, Calendars
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+				Phone
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_TabBar-syncWithViews.html b/dojox/mobile/tests/test_TabBar-syncWithViews.html
new file mode 100644
index 0000000..71cd2c3
--- /dev/null
+++ b/dojox/mobile/tests/test_TabBar-syncWithViews.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>TabBar - syncWithViews</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/TabBar"
+		]);
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="featured" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Featured</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"categ"'>
+				Next View
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"updates", transitionDir:-1'>
+				Previous View
+			</li>
+		</ul>
+	</div>
+
+	<div id="categ" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Category</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"top25"'>
+				Next View
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"featured", transitionDir:-1'>
+				Previous View
+			</li>
+		</ul>
+	</div>
+
+	<div id="top25" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Top 25</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"search"'>
+				Next View
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"categ", transitionDir:-1'>
+				Previous View
+			</li>
+		</ul>
+	</div>
+
+	<div id="search" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Search</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"updates"'>
+				Next View
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"top25", transitionDir:-1'>
+				Previous View
+			</li>
+		</ul>
+	</div>
+
+	<div id="updates" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Updates</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"featured"'>
+				Next View
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"search", transitionDir:-1'>
+				Previous View
+			</li>
+		</ul>
+	</div>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='fixed:"bottom", syncWithViews:true' style="border-bottom:none;">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", moveTo:"featured"'>Featured</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"categ"'>Categories</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-10.png", icon2:"images/tab-icon-10h.png", moveTo:"top25"'>Top 25</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-11.png", icon2:"images/tab-icon-11h.png", moveTo:"search"'>Search</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-13.png", icon2:"images/tab-icon-13h.png", moveTo:"updates"'>Updates</li>
+	</ul>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_TabBar.html b/dojox/mobile/tests/test_TabBar.html
new file mode 100644
index 0000000..db6fab5
--- /dev/null
+++ b/dojox/mobile/tests/test_TabBar.html
@@ -0,0 +1,288 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>TabBar</title>
+
+	<link href="../themes/common/domButtons/DomButtonYellowStar.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonGrayStar.css" rel="stylesheet"/>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/TabBar"
+		]);
+	</script>
+
+	<style>
+	h3 {
+		font-style: italic;
+		margin: 20px 0px 3px 8px;
+	}
+	
+	.label {
+		padding-top: 10px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+
+ 	<div data-dojo-type="dojox.mobile.ScrollableView">
+		<h3>tabBar</h3>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='iconBase:"images/tab-icons.png"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"images/tab-icon-16.png",
+				icon2:"images/tab-icon-16h.png",
+				selected:true'>Image</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				iconPos1:"0,29,29,29",
+				iconPos2:"29,29,29,29"'>Sprite</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"mblDomButtonGrayStar",
+				icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+		</ul>
+		
+		<div class="label">With fill='always':</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='iconBase:"images/tab-icons.png", fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"images/tab-icon-16.png",
+				icon2:"images/tab-icon-16h.png",
+				selected:true'>Image</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				iconPos1:"0,29,29,29",
+				iconPos2:"29,29,29,29"'>Sprite</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"mblDomButtonGrayStar",
+				icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+		</ul>
+	
+	
+	
+		<h3>segmentedControl</h3>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true, icon1:"images/tab-icon-21.png", icon2:"images/tab-icon-21h.png"'>New</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Dramatic</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Insight</li>
+		</ul>
+	
+		<div class="label">With fill='always':</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true, icon1:"images/tab-icon-21.png", icon2:"images/tab-icon-21h.png"'>New</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Dramatic</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Insight</li>
+		</ul>
+	
+		<div class="label">(in a Heading)</div>
+		<div data-dojo-type="dojox.mobile.Heading">
+			<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"'>
+				<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Catalog</li>
+				<li data-dojo-type="dojox.mobile.TabBarButton">Share</li>
+				<li data-dojo-type="dojox.mobile.TabBarButton">Download</li>
+			</ul>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props=''>MMMM</span>
+		</div><br>
+	
+		<h3>standardTab</h3>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"standardTab"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"standardTab", closable:true, center:false'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='
+			barType:"standardTab", center:false, iconBase:"images/tab-icons.png"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"images/tab-icon-21.png",
+				icon2:"images/tab-icon-21h.png",
+				selected:true'>Image</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				iconPos1:"0,29,29,29",
+				iconPos2:"29,29,29,29"'>Sprite</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"mblDomButtonGrayStar",
+				icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+		</ul>
+	
+		<div class="label">With fill='always':</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"standardTab", fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"standardTab", closable:true, center:false, fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='
+			barType:"standardTab", center:false, iconBase:"images/tab-icons.png", fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"images/tab-icon-21.png",
+				icon2:"images/tab-icon-21h.png",
+				selected:true'>Image</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				iconPos1:"0,29,29,29",
+				iconPos2:"29,29,29,29"'>Sprite</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"mblDomButtonGrayStar",
+				icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+		</ul>
+	
+	
+		<h3>slimTab</h3>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"slimTab"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"slimTab", closable:true, center:false'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='
+			barType:"slimTab", center:false, iconBase:"images/tab-icons.png"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"images/tab-icon-21.png",
+				icon2:"images/tab-icon-21h.png",
+				selected:true'>Image</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				iconPos1:"0,29,29,29",
+				iconPos2:"29,29,29,29"'>Sprite</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"mblDomButtonGrayStar",
+				icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+		</ul>
+	
+		<div class="label">With fill='always':</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"slimTab", fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"slimTab", closable:true, center:false, fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='
+			barType:"slimTab", center:false, iconBase:"images/tab-icons.png", fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"images/tab-icon-21.png",
+				icon2:"images/tab-icon-21h.png",
+				selected:true'>Image</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				iconPos1:"0,29,29,29",
+				iconPos2:"29,29,29,29"'>Sprite</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"mblDomButtonGrayStar",
+				icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+		</ul>
+	
+	
+		<h3>flatTab</h3>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"flatTab"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"flatTab", closable:true, center:false'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='
+			barType:"flatTab", center:false, iconBase:"images/tab-icons.png"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"images/tab-icon-21.png",
+				icon2:"images/tab-icon-21h.png",
+				selected:true'>Image</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				iconPos1:"0,29,29,29",
+				iconPos2:"29,29,29,29"'>Sprite</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"mblDomButtonGrayStar",
+				icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+		</ul>
+	
+		<div class="label">With fill='always':</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"flatTab", fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"flatTab", closable:true, center:false, fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>Dashboard</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Plan</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton">Today's Main Event</li>
+		</ul><br>
+	
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='
+			barType:"flatTab", center:false, iconBase:"images/tab-icons.png", fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"images/tab-icon-21.png",
+				icon2:"images/tab-icon-21h.png",
+				selected:true'>Image</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				iconPos1:"0,29,29,29",
+				iconPos2:"29,29,29,29"'>Sprite</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"mblDomButtonGrayStar",
+				icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+		</ul>
+	
+	
+		<h3>tallTab</h3>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='
+			barType:"tallTab", iconBase:"images/tab-icons.png"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"images/tab-icon-21.png",
+				icon2:"images/tab-icon-21h.png",
+				selected:true'>Image</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				iconPos1:"0,29,29,29",
+				iconPos2:"29,29,29,29"'>Sprite</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"mblDomButtonGrayStar",
+				icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+		</ul><br>
+		
+		<div class="label">With fill='always':</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"tallTab", iconBase:"images/tab-icons.png", fill: "always"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"images/tab-icon-21.png",
+				icon2:"images/tab-icon-21h.png",
+				selected:true'>Image</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				iconPos1:"0,29,29,29",
+				iconPos2:"29,29,29,29"'>Sprite</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='
+				icon1:"mblDomButtonGrayStar",
+				icon2:"mblDomButtonYellowStar"'>DOM Button</li>
+		</ul><br>	
+ 	</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_Templated-widgets.html b/dojox/mobile/tests/test_Templated-widgets.html
new file mode 100644
index 0000000..742a93b
--- /dev/null
+++ b/dojox/mobile/tests/test_Templated-widgets.html
@@ -0,0 +1,375 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" 
+		content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Templated Mobile Widgets</title>
+
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		// Templates
+		var templateListItem1, templateListItem2, templateListItem3,
+			templateHeading1, templateHeading2, templateButton1, templateCheckBox1, 
+			templateToggleButton1, templateSwitch1, templateSlider1, templateRadioButton1,
+			templateView1;
+
+		// Templated widget classes
+		var TemplatedListItem, TemplatedWithWidgetsListItem, 
+			TemplatedHeading, TemplatedWithWidgetsHeading1, 
+			TemplatedWithWidgetsHeading2, TemplatedSwitch;
+		
+		var showMsg;
+		var onclick1 = function(e){
+			showMsg("msgArea1", "Click!");
+		};
+		var onclick2 = function(e){
+			showMsg("msgArea2", "Click!");
+		};
+		
+		require([
+			"dojo/ready",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojo/_base/declare",
+			"dojo/dom-construct",
+			"dijit/_TemplatedMixin",
+			"dijit/_WidgetsInTemplateMixin", 
+			"dojo/text!./templates/Button1.html",
+			"dojo/text!./templates/CheckBox1.html",
+			"dojo/text!./templates/Heading1.html",
+			"dojo/text!./templates/Heading2.html",
+			"dojo/text!./templates/ListItem1.html", // pure HTML
+			"dojo/text!./templates/ListItem2.html", // contains widgets
+			"dojo/text!./templates/ListItem3.html", // contains widgets
+			"dojo/text!./templates/RadioButton1.html",
+			"dojo/text!./templates/Slider1.html",
+			"dojo/text!./templates/Switch1.html",
+			"dojo/text!./templates/ToggleButton1.html",
+			"dojo/text!./templates/View1.html",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/Heading",
+			"dojox/mobile/Switch",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/TabBarButton",
+			"dojox/mobile/ScrollableView"
+		], function(ready, dom, registry, parser, mobile, compat, declare, domConstruct, 
+					TemplatedMixin, WidgetsInTemplateMixin, 
+					myTemplateButton1, myTemplateCheckBox1, myTemplateHeading1,
+					myTemplateHeading2, myTemplateListItem1, myTemplateListItem2, 
+					myTemplateListItem3, myTemplateRadioButton1, myTemplateSlider1, 
+					myTemplateSwitch1, myTemplateToggleButton1, myTemplateView1,
+					ListItem, Heading, Switch){
+		
+		templateListItem1 = myTemplateListItem1;
+		templateListItem2 = myTemplateListItem2;
+		templateListItem3 = myTemplateListItem3;
+		templateHeading1 = myTemplateHeading1;
+		templateHeading2 = myTemplateHeading2;
+		templateButton1 = myTemplateButton1; 
+		templateCheckBox1 = myTemplateCheckBox1;
+		templateToggleButton1 = myTemplateToggleButton1;
+		templateRadioButton1 = myTemplateRadioButton1;
+		templateSwitch1 = myTemplateSwitch1;
+		templateSlider1 = myTemplateSlider1;
+		templateView1 = myTemplateView1;
+			
+		TemplatedListItem = declare(
+			[ListItem, TemplatedMixin], {
+				templateString: "<div>My inline <i>HTML</i> template (using declare)<div data-dojo-attach-point=\'labelNode\'></div></div>",
+				clickable: true,
+				onClick: onclick1
+			}
+		);
+		
+		TemplatedWithWidgetsListItem1 = declare( 
+			[ListItem, TemplatedMixin], {
+				label: "Some label",
+				templateString: templateListItem1, // pure HTML
+				clickable: true,
+				onClick: onclick1
+			}
+		);
+		
+		TemplatedWithWidgetsListItem2 = declare( 
+			[ListItem, TemplatedMixin, WidgetsInTemplateMixin], {
+				label: "Some label",
+				templateString: templateListItem2, // contains widgets
+				clickable: true,
+				onClick: onclick1
+			}
+		);
+		
+		TemplatedHeading = declare( 
+			[Heading, TemplatedMixin], {
+				back:"Back",
+				templateString: "<div>My inline <i>HTML</i> template (programmatic)</div>"
+			}
+		);
+		
+		TemplatedWithWidgetsHeading1 = declare( 
+			[Heading, TemplatedMixin, WidgetsInTemplateMixin], {
+				back:"Back",
+				templateString: templateHeading1
+			}
+		);
+		
+		TemplatedWithWidgetsHeading2 = declare( 
+			[Heading, TemplatedMixin, WidgetsInTemplateMixin], {
+				back:"Back",
+				label: "Templated by: <code>Heading2.html</code> (using declare)",
+				templateString: templateHeading2
+			}
+		);
+		
+		TemplatedSwitch = declare( 
+			[Switch, TemplatedMixin], {
+				templateString: templateSwitch1
+			}
+		);
+		
+		var timer;
+		showMsg = function(msgAreaId, msg){
+			if(timer){
+				clearTimeout(timer);
+			}
+			var msgArea = dom.byId(msgAreaId);
+			msgArea.innerHTML = msg;
+			timer = setTimeout(function(){
+				msgArea.innerHTML = ""; // clear, don't keep it too long
+			}, 1000);
+		};
+		
+		ready(function(){
+			// Testing the dynamic addition
+			registry.byId("list").addChild(new TemplatedListItem({
+				label: "added dynamically",
+				clickable: true, onClick: onclick1}));
+		});
+	});
+	</script>
+
+	<style type="text/css">
+		html,body{
+			height: 100%;
+		}
+		.mblRoundRect {
+			margin-left: 12px;
+			margin-right: 12px;
+		}
+		.bold {
+			font-weight: bold;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="main" data-dojo-type="dojox/mobile/View">
+		<ul data-dojo-type="dojox/mobile/TabBar" 
+			data-dojo-props="barType: 'slimTab', fixed: 'top'">
+			<li data-dojo-type="dojox/mobile/TabBarButton" 
+				data-dojo-props="moveTo:'ListItem', selected: true">ListItem</li>
+			<li data-dojo-type="dojox/mobile/TabBarButton" 
+				data-dojo-props="moveTo:'Heading'">Heading</li>
+			<li data-dojo-type="dojox/mobile/TabBarButton" 
+				data-dojo-props="moveTo:'FormControls'">Form Controls</li>
+			<li data-dojo-type="dojox/mobile/TabBarButton" 
+				data-dojo-props="moveTo:'View'">View</li>
+		</ul>
+
+		<!-- Templated ListItem -->
+		<div id="ListItem" data-dojo-type="dojox/mobile/ScrollableView">
+			<div id="msgArea1" style="margin-left: 40px; margin-top: 4px; height: 20px"></div>
+			<ul id="list" data-dojo-type="dojox/mobile/RoundRectList" 
+				data-dojo-props="iconBase:'images/tab-icon-11h.png', variableHeight: true">
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-mixins="dijit/_TemplatedMixin"
+					data-dojo-props="label:'Some label', 
+						clickable: true, onClick: onclick1,
+						templateString: '<div>My inline <i>HTML</i> template (markup)<div data-dojo-attach-point=\'labelNode\'></div></div>'">
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-mixins="dijit/_TemplatedMixin"
+					data-dojo-props="clickable: true, onClick: onclick1,
+						templateString: '<div><div>My inline, multiline <i>HTML</i><br>template (markup)</div></div>'">
+				</li>
+				<li data-dojo-type=TemplatedListItem>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-mixins="dijit/_TemplatedMixin"
+					data-dojo-props="label: '(markup, using data-dojo-mixins)', 
+						templateString: templateListItem1,
+						clickable: true, onClick: onclick1">
+				</li>
+				<li data-dojo-type=TemplatedWithWidgetsListItem1
+					data-dojo-props="label: '(markup, using declare)'">
+				</li>
+				<li data-dojo-type=TemplatedWithWidgetsListItem2>
+				</li>
+				<li data-dojo-type="dojox/mobile/ListItem"
+					data-dojo-mixins="dijit/_TemplatedMixin, dijit/_WidgetsInTemplateMixin"
+					data-dojo-props="templateString: templateListItem3,
+						clickable: true, onClick: onclick1">
+				</li>
+			</ul>
+		</div>
+		
+		<!-- Templated Form Controls -->
+		<div id="FormControls" data-dojo-type="dojox/mobile/ScrollableView">
+			<h1 data-dojo-type="dojox/mobile/Heading">Form Controls</h1>
+			<div id="msgArea2" style="margin-left: 40px; margin-top: 4px; height: 20px"></div>
+			<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+			<table style="width:100%">
+				<tr>
+					<td><span class="bold">Button</span></td>
+					<td style="text-align:right">
+						<button data-dojo-type="dojox/mobile/Button" 
+							data-dojo-props="templateString: '<button class=\'${baseClass}\' data-dojo-attach-point=\'containerNode\'></button>', onClick: onclick2"
+							data-dojo-mixins="dijit/_TemplatedMixin">
+							 Press me! (inline template)
+						</button>
+						<button data-dojo-type="dojox/mobile/Button" 
+							data-dojo-props="templateString: templateButton1, onClick: onclick2"
+							data-dojo-mixins="dijit/_TemplatedMixin">
+							Press me! (external template)
+						</button>
+					</td>
+				</tr>
+			</table>
+			</div>
+			
+			<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+			<table style="width:100%">
+				<tr>
+					<td><span class="bold">Slider</span></td>
+					<td style="float:right">
+						<input data-dojo-type="dojox/mobile/Slider"
+							style="width:150px;" type="range"
+							data-dojo-props="templateString: templateSlider1, 
+								value:10, min:0, max:40, step:0.1, 
+								onChange:function(v){ showMsg('msgArea2', 'value: ' + this.get('value')); }"
+							data-dojo-mixins="dijit/_TemplatedMixin">
+					</td>
+				</tr>
+			</table>
+			</div>
+			
+			<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+			<table style="width:100%">
+				<tr>
+					<td><span class="bold">CheckBox</span></td>
+					<td style="text-align:right">
+						<label for="cbox">Click me</label>
+						<input type="checkbox" id="cbox"
+							data-dojo-type="dojox/mobile/CheckBox"
+							data-dojo-props="templateString: templateCheckBox1, 
+								onChange:function(v){ showMsg('msgArea2', 'checked: ' + this.get('checked')); }">
+					</td>
+				</tr>
+			</table>
+			</div>
+			
+			<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+			<table style="width:100%">
+				<tr>
+					<td><span class="bold">ToggleButton</span></td>
+					<td style="text-align:right">
+						<button data-dojo-type="dojox/mobile/ToggleButton"
+							data-dojo-props="templateString: templateToggleButton1,
+								onChange:function(v){ showMsg('msgArea2', 'checked: ' + this.get('checked')); }">
+								Toggle me
+						</button>
+					</td>
+				</tr>
+			</table>
+			</div>
+			
+			<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+			<table style="width:100%">
+				<tr>
+					<td><span class="bold">Switch</span></td>
+					<td style="text-align:right">
+						<input type="checkbox" value="on"
+							data-dojo-type="dojox/mobile/Switch"
+							data-dojo-props="templateString: templateSwitch1,
+								onStateChanged:function(v){ showMsg('msgArea2', 'value: ' + v); }"
+							data-dojo-mixins="dijit/_TemplatedMixin, dijit/_WidgetsInTemplateMixin">
+					</td>
+					<td style="text-align:right">
+						<input type="checkbox" value="on"
+							data-dojo-type=TemplatedSwitch
+							data-dojo-props="onStateChanged:function(v){ showMsg('msgArea2', 'value: ' + v); }">
+					</td>
+				</tr>
+			</table>
+			</div>
+			
+			<div data-dojo-type="dojox/mobile/RoundRect" data-dojo-props="shadow:true">
+			<table style="width:100%">
+				<tr>
+					<td><span class="bold">Radio Button</span></td>
+					<td style="text-align:right">
+						<input type="radio" id="rb1" data-dojo-type="dojox/mobile/RadioButton" 
+							data-dojo-props="templateString: templateRadioButton1,
+								onChange:function(v){ if(this.get('checked')) showMsg('msgArea2', 'checked RadioButton 1'); }"
+							name="mobileRadio" value="Large" checked>
+						<label for="rb1">1</label>
+						
+						<input type="radio" id="rb2" data-dojo-type="dojox/mobile/RadioButton" 
+							data-dojo-props="templateString: templateRadioButton1,
+								onChange:function(v){ if(this.get('checked')) showMsg('msgArea2', 'checked RadioButton 2'); }"
+							name="mobileRadio" value="Large">
+						<label for="rb2">2</label>
+						
+						<input type="radio" id="rb3" data-dojo-type="dojox/mobile/RadioButton" 
+							data-dojo-props="templateString: templateRadioButton1,
+								onChange:function(v){ if(this.get('checked')) showMsg('msgArea2', 'checked RadioButton 3'); }"
+							name="mobileRadio" value="Large">
+						<label for="rb3">3</label>
+				</tr>
+			</table>
+			</div>
+		</div>
+		
+		<!-- Templated Heading -->
+		<div id="Heading" data-dojo-type="dojox/mobile/ScrollableView">
+			<!-- Template containing widgets -->
+			<div data-dojo-type="dojox/mobile/Heading" 
+				data-dojo-props="label:'Some label', templateString: templateHeading1"
+				data-dojo-mixins="dijit/_TemplatedMixin, dijit/_WidgetsInTemplateMixin">
+			</div>
+			<!-- Pure HTML template -->
+			<div data-dojo-type="dojox/mobile/Heading" 
+				data-dojo-props="back:'Back', 
+					templateString: '<div>My inline <i>HTML</i> template (markup)</div>'"
+				data-dojo-mixins="dijit/_TemplatedMixin">
+			</div>
+			<div data-dojo-type="dojox/mobile/Heading" 
+				data-dojo-props="back:'Back',
+					label: 'Templated by: <code>Heading2.html</code> (using data-dojo-mixins)', 
+					templateString: templateHeading2"
+				data-dojo-mixins="dijit/_TemplatedMixin, dijit/_WidgetsInTemplateMixin">
+			</div>
+			<div data-dojo-type=TemplatedHeading>
+			</div>
+			<div data-dojo-type=TemplatedWithWidgetsHeading1>
+			</div>
+			<div data-dojo-type=TemplatedWithWidgetsHeading2
+				data-dojo-props="back: 'Back'">
+			</div>
+		</div>
+		
+		<!-- Templated View -->
+		<div id="View" data-dojo-type="dojox/mobile/View"
+			data-dojo-props="templateString: templateView1"
+			data-dojo-mixins="dijit/_TemplatedMixin, dijit/_WidgetsInTemplateMixin">
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_TextBox-in-ScrollableView.html b/dojox/mobile/tests/test_TextBox-in-ScrollableView.html
new file mode 100644
index 0000000..8ced4cb
--- /dev/null
+++ b/dojox/mobile/tests/test_TextBox-in-ScrollableView.html
@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>TextBox inside ScrollableView</title>
+
+	<script type="text/javascript" src="../deviceTheme.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+		data-dojo-config="async: true, parseOnLoad: true, mblHideAddressBar: true, mblAlwaysHideAddressBar: false"></script>
+
+	<!-- The purpose of this test is to allow testing the behavior of ScrollableView when 
+		it contains TextBoxes and fixed headers and footers. -->
+		
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/TabBarButton",
+			"dojox/mobile/TextBox"
+		]);
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="group1" data-dojo-type="dojox.mobile.View">
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:{"iphone_theme":"segmentedControl","*":"tallTab"}, fixed:"top"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", selected:true'>New</li>
+
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png"'>What's Hot</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-10.png", icon2:"images/tab-icon-10h.png"'>Genius</li>
+		</ul>
+		<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" class="list1">
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field1"' style="margin-bottom: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field2"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field3"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field4"' style="margin-top: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field5"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field6"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field7"' style="margin-bottom: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field8"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field9"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field10"' style="margin-top: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field11"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field12"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field13"' style="margin-bottom: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field14"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field15"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field16"' style="margin-top: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field17"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field18"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field19"' style="margin-bottom: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field20"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field21"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field22"' style="margin-top: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field23"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field24"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field25"' style="margin-bottom: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field26"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field27"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field28"' style="margin-top: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field29"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field30"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field31"' style="margin-bottom: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field32"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field33"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field34"' style="margin-top: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field35"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field36"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field37"' style="margin-bottom: 0;" required>
+				</li>
+
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field38"' style="margin-top: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="text" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field39"' style="margin-bottom: 0;" required>
+				</li>
+				<li>
+				<input data-dojo-type="dojox.mobile.TextBox" type="password" data-dojo-props='scrollOnFocus:true, selectOnClick:true, placeHolder:"field40"' style="margin-top: 0;" required>
+				</li>
+
+			</ul>
+		</div>
+
+	</div>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='fixed:"bottom"' style="border-bottom:none;">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", selected:true'>Featured</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png"'>Categories</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-10.png", icon2:"images/tab-icon-10h.png"'>Top 25</li>
+
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-11.png", icon2:"images/tab-icon-11h.png"'>Search</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-13.png", icon2:"images/tab-icon-13h.png"'>Updates</li>
+	</ul>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_TimePicker.html b/dojox/mobile/tests/test_TimePicker.html
new file mode 100644
index 0000000..42e741c
--- /dev/null
+++ b/dojox/mobile/tests/test_TimePicker.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>TimePicker</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TimePicker']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TimePicker"
+		], function(registry){
+			gotoToday = function(){
+				registry.byId("picker1").reset();
+			}
+			showSelectedValue = function(){
+				var w = registry.byId("picker1");
+				document.getElementById("msg").innerHTML =
+					w.slots[0].get("value")+ ":" + w.slots[1].get("value");
+			}
+		});
+	</script>
+
+	<style>
+	#picker1 {
+		margin: 20px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="showSelectedValue()" data-dojo-props='label:"OK"'></span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="gotoToday()" data-dojo-props='label:"Now"'></span>
+		</div>
+		<div id="picker1" data-dojo-type="dojox.mobile.TimePicker"></div>
+		<div id="msg"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ToolBarButton-setter.html b/dojox/mobile/tests/test_ToolBarButton-setter.html
new file mode 100644
index 0000000..fbd9e7e
--- /dev/null
+++ b/dojox/mobile/tests/test_ToolBarButton-setter.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Heading</title>
+
+	<script type="text/javascript" src="../deviceTheme.js"
+		data-dojo-config="mblThemeFiles: ['base','TabBar','dojox/mobile/themes/common/domButtons.css']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/window",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TabBar"
+		], function(win, dom, ready, registry){
+			win.doc.dojoClick = false; // disable dojo/touch clicks for native radios buttons
+			var btn1;
+			setIcon = function(flag){
+				if(flag == 1){
+					btn1.set("iconPos", "");
+					btn1.set("icon", "mblDomButtonWhitePlus");
+				}else if(flag == 2){
+					btn1.set("iconPos", "");
+					btn1.set("icon", "images/tab-icon-33w.png");
+				}else if(flag == 3){
+					btn1.set("iconPos", "29,116,29,29");
+					btn1.set("icon", "images/tab-icons.png");
+				}else if(flag == 4){
+					btn1.set("iconPos", "");
+					btn1.set("icon", "");
+				}
+			}
+			setSelected = function(flag){
+				btn1.set("selected", flag);
+			}
+			setLabel = function(){
+				btn1.set("label", dom.byId("txt1").value);
+			}
+
+			ready(function(){
+				btn1 = registry.byId("btn1");
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Arrow"'>
+		<span id="btn1" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='light:false'>MMMM</span>
+	</div>
+	<table style="margin:20px">
+		<tr>
+			<td style="margin-right:20px">Icon</td>
+			<td><input id="icon1" type="radio" name="icon" onclick="setIcon(1)"><label for="icon1">DOM Buttn</label>
+				<input id="icon2" type="radio" name="icon" onclick="setIcon(2)"><label for="icon2">Image</label>
+				<input id="icon3" type="radio" name="icon" onclick="setIcon(3)"><label for="icon3">Sprite</label>
+				<input id="icon4" type="radio" name="icon" onclick="setIcon(4)" checked><label for="icon4">none</label></td>
+		</tr>
+		<tr>
+			<td style="margin-right:20px">Selected</td>
+			<td><input id="sel1" type="radio" name="selected" onclick="setSelected(true)" value="on"><label for="sel1">on</label>
+				<input id="sel2" type="radio" name="selected" onclick="setSelected(false)" value="off" checked><label for="sel2">off</label></td>
+		</tr>
+		<tr>
+			<td style="margin-right:20px">Label</td>
+			<td><input id="txt1" type="text" value="MMMM"> <input type="button" value="Set" onclick="setLabel()"></td>
+		</tr>
+	</table>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Tooltip.html b/dojox/mobile/tests/test_Tooltip.html
index fd61873..7be0336 100644
--- a/dojox/mobile/tests/test_Tooltip.html
+++ b/dojox/mobile/tests/test_Tooltip.html
@@ -1,117 +1,122 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html style="overflow:hidden;">
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>test Tooltip</title>
-		<link href="../themes/common/SpinWheel.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<style>
-		.dj_phone BUTTON {
-			display:none;
-		}
-		INPUT {
-			font-family: monospace;
-			border-radius: 0px;
-		}
-		#spin1 {
-			width: 304px;
- 		}
-		#pt {
-			width: 20px;
-			background-color: #C4C9DB;
-			opacity: 0.2;
-		}
-		#txt {
-			width: 10px;
-			margin-left: -15px;
-			padding-top: 85px;
-			font-size: 24px;
-			font-weight: bold;
-			border: none;
-		}
-		HTML {
-			min-height: 100%; /* workaround for android 3.x position:fixed bug */
-		}
-		</style>
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>test Tooltip</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.SpinWheel");
-			dojo.require("dojox.mobile.SpinWheelSlot");
-			dojo.require("dojox.mobile.Tooltip");
-			dojo.require("dojox.mobile.common");
-			dojo.ready(function(){
-				dojo.byId('bot').scrollIntoView(false);
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel','Tooltip']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/_base/manager", // dijit.byId in markup
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SpinWheel",
+			"dojox/mobile/Tooltip"
+		], function(dom, ready){
+			ready(function(){
+				dom.byId('bot').scrollIntoView(false);
 			});
+		});
+	</script>
 
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<center style="width:100%;">
-			<button type="button" onclick="dijit.byId('customPicker').show(this, ['above','below-centered','before','after'])">below</button>
-			<input readonly onclick="dijit.byId('textTooltip').show(this, ['above-centered','below-centered','after','before'])" value="below" size="5">
-			<br><br><b>Click boundary nodes to see tooltips</b>
-		</center>
-		<center id="bot" class="bottom" style="position:fixed;bottom:0;width:100%;">
-			<input readonly tabindex="0" onclick="dijit.byId('textTooltip').show(this, ['above-centered','below-centered','before','after'])" value="above" size="5">
-			<button type="button" tabindex="0" onclick="dijit.byId('customPicker').show(this, ['below','above-centered','after','before'])">above</button>
-		</center>
-		<center style="position:fixed;top:33%;width:100%;">
-			<button type="button" onclick="dijit.byId('customPicker').hide()">click to hide spin wheels</button>
-		</center>
-		<center style="position:fixed;bottom:33%;width:100%;">
-			<input readonly onclick="dijit.byId('textTooltip').hide()" value="click to hide text tooltip" size="26">
-		</center>
-		<div style="position:fixed;top:50%;left:1px;direction:ltr;">
-			<input readonly onclick="dijit.byId('textTooltip').show(this, ['before','after','below-centered','above-centered'])" value="right" size="5">
-			<br>
-			<br>
-			<button type="button" onclick="dijit.byId('customPicker').show(this, ['before','after','below-centered','above-centered'])">right</button>
-		</div>
-		<div style="position:fixed;bottom:50%;right:1px;direction:rtl;">
-			<button type="button" onclick="dijit.byId('customPicker').show(this, ['after','before','above','below'])">left</button>
-			<br>
-			<br>
-			<input readonly onclick="dijit.byId('textTooltip').show(this, ['after','before','below','above'])" value="left" size="4">
-		</div>
+	<style>
+	.dj_phone BUTTON {
+		display:none;
+	}
+	INPUT {
+		font-family: monospace;
+		border-radius: 0px;
+	}
+	#spin1 {
+		width: 304px;
+ 	}
+	#pt {
+		width: 20px;
+		background-color: #C4C9DB;
+		opacity: 0.2;
+	}
+	#txt {
+		width: 10px;
+		margin-left: -15px;
+		padding-top: 85px;
+		font-size: 24px;
+		font-weight: bold;
+		border: none;
+	}
+	HTML {
+		min-height: 100%; /* workaround for android 3.x position:fixed bug */
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<center style="width:100%;">
+		<button type="button" onclick="dijit.byId('customPicker').show(this, ['above','below-centered','before','after'])">below</button>
+		<input readonly onclick="dijit.byId('textTooltip').show(this, ['above-centered','below-centered','after','before'])" value="below" size="5">
+		<br><br><b>Click boundary nodes to see tooltips</b>
+	</center>
+	<center id="bot" class="bottom" style="position:fixed;bottom:0;width:100%;">
+		<input readonly tabindex="0" onclick="dijit.byId('textTooltip').show(this, ['above-centered','below-centered','before','after'])" value="above" size="5">
+		<button type="button" tabindex="0" onclick="dijit.byId('customPicker').show(this, ['below','above-centered','after','before'])">above</button>
+	</center>
+	<center style="position:fixed;top:33%;width:100%;">
+		<button type="button" onclick="dijit.byId('customPicker').hide()">click to hide spin wheels</button>
+	</center>
+	<center style="position:fixed;bottom:33%;width:100%;">
+		<input readonly onclick="dijit.byId('textTooltip').hide()" value="click to hide text tooltip" size="26">
+	</center>
+	<div style="position:fixed;top:50%;left:1px;direction:ltr;">
+		<input readonly onclick="dijit.byId('textTooltip').show(this, ['before','after','below-centered','above-centered'])" value="right" size="5">
+		<br>
+		<br>
+		<button type="button" onclick="dijit.byId('customPicker').show(this, ['before','after','below-centered','above-centered'])">right</button>
+	</div>
+	<div style="position:fixed;bottom:50%;right:1px;direction:rtl;">
+		<button type="button" onclick="dijit.byId('customPicker').show(this, ['after','before','above','below'])">left</button>
+		<br>
+		<br>
+		<input readonly onclick="dijit.byId('textTooltip').show(this, ['after','before','below','above'])" value="left" size="4">
+	</div>
 
-		<div id="textTooltip" dojoType="dojox.mobile.Tooltip" class="mblTooltipBubble">Enter a value.<br><center>Please!</center></div>
+	<div id="textTooltip" data-dojo-type="dojox.mobile.Tooltip" class="mblTooltipBubble">Enter a value.<br><center>Please!</center></div>
 
-		<div id="customPicker" dojoType="dojox.mobile.Tooltip">
-			<div id="spin1" dojoType="dojox.mobile.SpinWheel">
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="['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']"
-					style="text-align:center;width:40px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labelFrom="3000" labelTo="3100"
-					style="width:70px;"></div>
-				<div id="pt" class="mblSpinWheelSlot"></div>
-				<div id="txt" class="mblSpinWheelSlot">.</div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labelFrom="0" labelTo="9"
-					style="width:30px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="['pt','px','cm']"
-					style="width:50px;"></div>
-				<div dojoType="dojox.mobile.SpinWheelSlot"
-					labels="[
-						'<img src=images/i-icon-1.png>',
-						'<img src=images/i-icon-2.png>',
-						'<img src=images/i-icon-3.png>',
-						'<img src=images/i-icon-4.png>',
-						'<img src=images/i-icon-5.png>',
-						'<img src=images/i-icon-6.png>',
-						'<img src=images/i-icon-7.png>',
-						'<img src=images/i-icon-8.png>',
-						'<img src=images/i-icon-9.png>',
-						'<img src=images/i-icon-10.png>'
-					]"
-					style="width:70px;text-align: center;"></div>
-			</div>
+	<div id="customPicker" data-dojo-type="dojox.mobile.Tooltip">
+		<div id="spin1" data-dojo-type="dojox.mobile.SpinWheel">
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props='labelFrom:3000, labelTo:3100'
+				style="width:70px;"></div>
+			<div id="pt" class="mblSpinWheelSlot"></div>
+			<div id="txt" class="mblSpinWheelSlot">.</div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:30px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:['pt','px','cm']"
+				style="width:50px;"></div>
+			<div data-dojo-type="dojox.mobile.SpinWheelSlot"
+				data-dojo-props="labels:[
+					'<img src=images/i-icon-1.png>',
+					'<img src=images/i-icon-2.png>',
+					'<img src=images/i-icon-3.png>',
+					'<img src=images/i-icon-4.png>',
+					'<img src=images/i-icon-5.png>',
+					'<img src=images/i-icon-6.png>',
+					'<img src=images/i-icon-7.png>',
+					'<img src=images/i-icon-8.png>',
+					'<img src=images/i-icon-9.png>',
+					'<img src=images/i-icon-10.png>'
+				]"
+				style="width:70px;text-align: center;"></div>
 		</div>
-	</body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_TreeView.html b/dojox/mobile/tests/test_TreeView.html
new file mode 100644
index 0000000..f1316fc
--- /dev/null
+++ b/dojox/mobile/tests/test_TreeView.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Tree View example (FileStore)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/data/FileStore",
+			"dijit/tree/ForestStoreModel",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TreeView"
+		], function(FileStore, ForestStoreModel){
+			var store = new FileStore({
+				url: "../../data/demos/stores/filestore_dojotree.php",
+				id: "theStore",
+				label: "name",
+				pathAsQueryParam: true
+			});
+			treeModel = new ForestStoreModel({
+				store: store,
+				rootLabel: "Files",
+				childrenAttrs: ["children"],
+				newItemIdAttr: "path"
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.TreeView"
+	 data-dojo-props='model: treeModel'></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ValuePicker-1slot.html b/dojox/mobile/tests/test_ValuePicker-1slot.html
new file mode 100644
index 0000000..a542f0d
--- /dev/null
+++ b/dojox/mobile/tests/test_ValuePicker-1slot.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+<!--
+  A ValuePicker that has only one slot.
+  Note that this test case does not load dojox.mobile themes such as iphone.css.
+  Nor does it load the dojox.mobile base, i.e., not requiring "dojox.mobile".
+-->
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>One Slot ValuePicker</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ValuePicker"
+		]);
+	</script>
+
+	<style>
+		.windows_theme .mblValuePickerSlot {
+			width: 100px !important;
+		}
+	</style>
+</head>
+<body>
+	<div data-dojo-type="dojox.mobile.ValuePicker">
+		<div data-dojo-type="dojox.mobile.ValuePickerSlot"
+			data-dojo-props='labelFrom:3000, labelTo:3100, style:{width:"72px"}'></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ValuePicker-custom.html b/dojox/mobile/tests/test_ValuePicker-custom.html
new file mode 100644
index 0000000..9f0367d
--- /dev/null
+++ b/dojox/mobile/tests/test_ValuePicker-custom.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Custom ValuePicker</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ValuePicker"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#424142;">
+	<div data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Custom ValuePicker</h1>
+		<div id="spin1" data-dojo-type="dojox.mobile.ValuePicker">
+			<div data-dojo-type="dojox.mobile.ValuePickerSlot"
+				data-dojo-props="labels:['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']"
+				style="text-align:center;width:40px;"></div>
+			<div data-dojo-type="dojox.mobile.ValuePickerSlot"
+				data-dojo-props='labelFrom:3000, labelTo:3100'
+				style="width:70px;"></div>
+			<div data-dojo-type="dojox.mobile.ValuePickerSlot"
+				data-dojo-props='labelFrom:0, labelTo:9'
+				style="width:50px;"></div>
+			<div data-dojo-type="dojox.mobile.ValuePickerSlot"
+				data-dojo-props="labels:['pt','px','cm']"
+				style="width:50px;"></div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ValuePicker-dialog.html b/dojox/mobile/tests/test_ValuePicker-dialog.html
new file mode 100644
index 0000000..ad62e61
--- /dev/null
+++ b/dojox/mobile/tests/test_ValuePicker-dialog.html
@@ -0,0 +1,186 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ValuePicker on SimpleDialog</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SimpleDialog','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/date/locale",
+			"dojo/dom",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ProgressIndicator",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/Button",
+			"dojox/mobile/ValuePickerDatePicker",
+			"dojox/mobile/ValuePickerTimePicker"
+		], function(locale, dom, ready, registry, ProgressIndicator){
+			var date;
+			show = function(dlg){
+				if(dlg == "dlg1"){
+					date = registry.byId("picker1").get("values");
+				}else if(dlg == "dlg2"){
+					date = registry.byId("picker2").get("values");
+				}
+				registry.byId(dlg).show();
+			};
+			hide = function(dlg){
+				registry.byId(dlg).hide();
+			};
+			cancel = function(dlg){
+				if(dlg == "dlg1"){
+					registry.byId("picker1").set("values", date);
+				}else if(dlg == "dlg2"){
+					registry.byId("picker2").set("values", date);
+				}
+				registry.byId(dlg).show();
+				hide(dlg);
+			};
+
+			// Dialog Box
+			updateDateDialog = function(){
+				var d = registry.byId("picker1").get("date");
+				if(d){
+					dom.byId("msg1").innerHTML =
+						locale.format(d, {formatLength:"full",selector:"date"});
+				}
+			};
+			updateTimeDialog = function(){
+				var d = registry.byId("picker2").get("date");
+				if(d){
+					dom.byId("msg2").innerHTML =
+						locale.format(d, {timePattern:is24h?"H:mm":"h:mm a",selector:"time"});
+				}
+			};
+			onValueChanged1 = function(){
+				updateDateDialog();
+			};
+			onValueChanged2 = function(){
+				updateTimeDialog();
+			};
+
+
+			// ListItem
+			updateDateListItem = function(){
+				var d = registry.byId("picker1").get("date");
+				if(d){
+					dom.byId("dateMsg").innerHTML =
+						locale.format(d, {formatLength:"short",selector:"date"});
+				}
+			};
+			updateTimeListItem = function(){
+				var d = registry.byId("picker2").get("date");
+				if(d){
+					dom.byId("timeMsg").innerHTML =
+						locale.format(d, {timePattern:is24h?"H:mm":"h:mm a",selector:"time"});
+				}
+			};
+
+			setDate = function(){
+				updateDateListItem();
+				hide('dlg1');
+			};
+			setTime = function(){
+				updateTimeListItem();
+				hide('dlg2');
+			};
+
+			is24h = true;
+			use24h = function(){
+				var listItem = registry.byId("item1")
+				if(is24h){
+					listItem.set("rightIcon", "mblDomButtonCheckboxOff");
+					dom.byId("use24hMsg").innerHTML = "1:00 pm";
+					registry.byId("picker2").set("is24h", false);
+				}else{
+					listItem.set("rightIcon", "mblDomButtonCheckboxOn");
+					dom.byId("use24hMsg").innerHTML = "13:00";
+					registry.byId("picker2").set("is24h", true);
+				}
+				is24h = !is24h;
+				updateTimeDialog();
+				updateTimeListItem();
+			};
+
+			ready(function(){
+				updateDateListItem();
+				updateTimeListItem();
+//				show("dlg1");
+			})
+		});
+
+	</script>
+
+	<style>
+	.mblValuePicker {
+		display: inline-block; /* to align center */
+	}
+	#dlg1, #dlg2 {
+		width: 300px;
+		padding: 0;
+	}
+	span.dlgBtn {
+		padding: 0;
+		width: 130px;
+	}
+	.subtitle {
+		color: #00e7e6;
+		font-size: 12px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="dlg1" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div style="text-align:left;margin:6px">
+			<img src="images/tab-icon-19.png" style="vertical-align:middle">
+			<span id="msg1"></span>
+		</div>
+		<div id="picker1" data-dojo-type="dojox.mobile.ValuePickerDatePicker" data-dojo-props="onValueChanged:onValueChanged1"></div>
+		<div style="background-color:#bdbabd;margin-top:6px;">
+			<span data-dojo-type="dojox.mobile.ToolBarButton" class="dlgBtn" onclick="setDate()">Set</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" class="dlgBtn" onclick="cancel('dlg1')">Cancel</span>
+		</div>
+	</div>
+
+	<div id="dlg2" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div style="text-align:left;margin:6px">
+			<img src="images/tab-icon-19.png" style="vertical-align:middle">
+			<span id="msg2"></span>
+		</div>
+		<div id="picker2" data-dojo-type="dojox.mobile.ValuePickerTimePicker" data-dojo-props="is24h:true,onValueChanged:onValueChanged2"></div>
+		<div style="background-color:#bdbabd;margin-top:6px;">
+			<span data-dojo-type="dojox.mobile.ToolBarButton" class="dlgBtn" onclick="setTime()">Set</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" class="dlgBtn" onclick="cancel('dlg2')">Cancel</span>
+		</div>
+	</div>
+
+	<div id="view" data-dojo-type="dojox.mobile.View">
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='clickable:true,noArrow:true,onClick:function(){show("dlg1")}'>
+				Set date
+				<div id="dateMsg" class="subtitle">2012/02/23</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='clickable:true,noArrow:true,onClick:function(){show("dlg2")}'>
+				Set time
+				<div id="timeMsg" class="subtitle">22:34</div>
+			</li>
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem"
+				data-dojo-props='clickable:true,noArrow:true,rightIcon:"mblDomButtonCheckboxOn",onClick:function(){use24h()}'>
+				Use 24-hour format
+				<div id="use24hMsg" class="subtitle">13:00</div>
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ValuePickerDatePicker-setter.html b/dojox/mobile/tests/test_ValuePickerDatePicker-setter.html
new file mode 100644
index 0000000..3bb58cc
--- /dev/null
+++ b/dojox/mobile/tests/test_ValuePickerDatePicker-setter.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ValuePicker Date Picker - setter</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ValuePickerDatePicker",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(ready, registry, ValuePickerDatePicker){
+			ready(function(){
+				registry.byId("picker1").set("value", "2000-10-24");
+				registry.byId("picker2").set("values", [2000,10,24]);
+
+				var picker5 = new ValuePickerDatePicker({value:"2000-10-24"}, "picker5");
+				picker5.startup();
+
+				var picker6 = new ValuePickerDatePicker({values:[2000,10,24]}, "picker6");
+				picker6.startup();
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<!-- All these widgets should display the same value. -->
+		<div id="picker1" data-dojo-type="dojox.mobile.ValuePickerDatePicker"></div><br>
+		<div id="picker2" data-dojo-type="dojox.mobile.ValuePickerDatePicker"></div><br>
+		<div id="picker3" data-dojo-type="dojox.mobile.ValuePickerDatePicker" data-dojo-props="value:'2000-10-24'"></div><br>
+		<div id="picker4" data-dojo-type="dojox.mobile.ValuePickerDatePicker" data-dojo-props="values:[2000,10,24]"></div><br>
+		<div id="picker5"></div><br>
+		<div id="picker6"></div><br>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ValuePickerDatePicker.html b/dojox/mobile/tests/test_ValuePickerDatePicker.html
new file mode 100644
index 0000000..d318e75
--- /dev/null
+++ b/dojox/mobile/tests/test_ValuePickerDatePicker.html
@@ -0,0 +1,137 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ValuePickerDatePicker</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		var changeLocale, gotoToday, showSelectedValue;
+		var onYearSet, onMonthSet, onDaySet;
+		require([
+			"dojo/_base/kernel"
+		], function(dojo){
+			var lang = location.search.match(/lang=(\w*)/) ? RegExp.$1 : null;
+			if(lang){ dojo.locale = lang; }
+			require([
+				"dojo/_base/window",
+				"dojo/dom",
+				"dojo/ready",
+				"dijit/registry",
+				"dojo/_base/xhr",
+				"dojox/mobile/parser",
+				"dojox/mobile",
+				"dojox/mobile/compat",
+				"dojox/mobile/ValuePickerDatePicker"
+			], function(win, dom, ready, registry){
+				changeLocale = function(){
+					win.doc.forms[0].submit();
+				}
+				gotoToday = function(){
+					registry.byId("picker1").reset();
+				}
+				showSelectedValue = function(){
+					var w = registry.byId("picker1");
+					document.getElementById("msg").innerHTML =
+						w.slots[0].get("value")+ ":" + w.slots[1].get("value") + ":" + w.slots[2].get("value");
+				}
+				onYearSet = function(){
+					console.log("onYearSet value: " + this.slots[0].get("value"));
+				}
+				onMonthSet = function(){
+					console.log("onMonthSet value: " + this.slots[1].get("value"));
+				}
+				onDaySet = function(){
+					console.log("onDaySet value: " + this.slots[2].get("value"));
+				}
+				ready(function(){
+					dom.byId("sel").value = lang;
+					
+					var picker = registry.byId("picker1"),
+						yearSlot = picker.slots[0],
+						monthSlot = picker.slots[1],
+						daySlot = picker.slots[2];
+
+					yearSlot.watch("value", function(name, oldVal, newVal){
+						console.log("watch value of year slot: oldVal: " + oldVal + " newVal: " + newVal);
+  						document.getElementById("msg").innerHTML = 
+  							"watch value of year slot: oldVal: " + oldVal + " newVal: " + newVal;
+					});
+					monthSlot.watch("value", function(name, oldVal, newVal){
+						console.log("watch value of month slot: oldVal: " + oldVal + " newVal: " + newVal);
+  						document.getElementById("msg").innerHTML = 
+  							"watch value of month slot: oldVal: " + oldVal + " newVal: " + newVal;
+					});
+					daySlot.watch("value", function(name, oldVal, newVal){
+						console.log("watch value of day slot: oldVal: " + oldVal + " newVal: " + newVal);
+  						document.getElementById("msg").innerHTML = 
+  							"watch value of day slot: oldVal: " + oldVal + " newVal: " + newVal;
+					});
+				});
+			});
+		});
+	</script>
+
+	<style>
+	#picker1 {
+		margin: 20px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;background-color:#424142;">
+	<div data-dojo-type="dojox.mobile.View">
+		<form>
+			<div data-dojo-type="dojox.mobile.Heading">
+				<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="showSelectedValue()" data-dojo-props='label:"OK"'></span>
+				<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="gotoToday()" data-dojo-props='label:"Today"'></span>
+				<select id="sel" name="lang" onchange="changeLocale()" style="float:left;margin-top:10px;">
+					<option value=""></option>
+					<option value="ar">ar</option>
+					<option value="ca">ca</option>
+					<option value="cs">cs</option>
+					<option value="da">da</option>
+					<option value="de">de</option>
+					<option value="el">el</option>
+					<option value="en">en</option>
+					<option value="en-au">en-au</option>
+					<option value="en-ca">en-ca</option>
+					<option value="en-gb">en-gb</option>
+					<option value="es">es</option>
+					<option value="fi">fi</option>
+					<option value="fr">fr</option>
+					<option value="fr-ch">fr-ch</option>
+					<option value="he">he</option>
+					<option value="hu">hu</option>
+					<option value="it">it</option>
+					<option value="ja">ja</option>
+					<option value="ko">ko</option>
+					<option value="nb">nb</option>
+					<option value="nl">nl</option>
+					<option value="pl">pl</option>
+					<option value="pt">pt</option>
+					<option value="pt-pt">pt-pt</option>
+					<option value="ro">ro</option>
+					<option value="ru">ru</option>
+					<option value="sk">sk</option>
+					<option value="sl">sl</option>
+					<option value="sv">sv</option>
+					<option value="th">th</option>
+					<option value="tr">tr</option>
+					<option value="zh">zh</option>
+					<option value="zh-hant">zh-hant</option>
+					<option value="zh-hk">zh-hk</option>
+					<option value="zh-tw">zh-tw</option>
+				</select>
+			</div>
+		</form>
+		<div id="picker1" data-dojo-type="dojox.mobile.ValuePickerDatePicker"
+			data-dojo-props="onYearSet: onYearSet, onMonthSet: onMonthSet, onDaySet: onDaySet">
+		</div>
+		<div id="msg"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ValuePickerSlot.html b/dojox/mobile/tests/test_ValuePickerSlot.html
new file mode 100644
index 0000000..3a9a4a8
--- /dev/null
+++ b/dojox/mobile/tests/test_ValuePickerSlot.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ValuePickerSlot</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ValuePickerSlot"
+		], function(registry){
+			spin = function(steps){
+				registry.byId("picker1").spin(steps);
+				registry.byId("picker2").spin(steps);
+			};
+		});
+	</script>
+	<style>
+	</style>
+</head>
+<body style="visibility:hidden;background-color:#424142;padding:10px;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<div id="picker1" data-dojo-type="dojox.mobile.ValuePickerSlot"
+		     data-dojo-props='labelFrom:1, labelTo:3'
+		     style="width:72px;float:left"></div>
+		<div id="picker2" data-dojo-type="dojox.mobile.ValuePickerSlot"
+		     data-dojo-props="labels:['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']"
+		     style="width:72px;float:left;margin-left:10px;"></div>
+		<p style="clear:both;height:10px"></p>
+		<input type="button" onclick="spin(1)" value="+1">
+		<input type="button" onclick="spin(-1)" value="−1">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ValuePickerTimePicker-setter.html b/dojox/mobile/tests/test_ValuePickerTimePicker-setter.html
new file mode 100644
index 0000000..5741b01
--- /dev/null
+++ b/dojox/mobile/tests/test_ValuePickerTimePicker-setter.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ValuePicker Time Picker - setter</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ValuePickerTimePicker",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(ready, registry, ValuePickerTimePicker){
+			ready(function(){
+				registry.byId("picker1").set("values", ["22","06"]);
+
+				var picker3 = new ValuePickerTimePicker({values:["22","06"]}, "picker3");
+				picker3.startup();
+
+				var picker4 = new ValuePickerTimePicker({values12:["10","06","PM"]}, "picker4");
+				picker4.startup();
+			});
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<!-- All these widgets should display the same value. -->
+		<div id="picker1" data-dojo-type="dojox.mobile.ValuePickerTimePicker"></div><br>
+		<div id="picker2" data-dojo-type="dojox.mobile.ValuePickerTimePicker" data-dojo-props="values:['22','06']"></div><br>
+		<div id="picker3"></div><br>
+		<div id="picker4"></div><br>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ValuePickerTimePicker.html b/dojox/mobile/tests/test_ValuePickerTimePicker.html
new file mode 100644
index 0000000..9a1a739
--- /dev/null
+++ b/dojox/mobile/tests/test_ValuePickerTimePicker.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>ValuePicker Time Picker</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','ValuePicker']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ValuePickerTimePicker"
+		], function(registry){
+			gotoToday = function(){
+				registry.byId("picker1").reset();
+			}
+			showSelectedValue = function(){
+				var w = registry.byId("picker1");
+				var values = w.get("values");
+				document.getElementById("msg").innerHTML =
+					values[0] + ":" + values[1];
+			}
+		});
+	</script>
+
+	<style>
+	#picker1 {
+		margin: 20px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="showSelectedValue()" data-dojo-props='label:"OK"'></span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" onClick="gotoToday()" data-dojo-props='label:"Now"'></span>
+		</div>
+		<div id="picker1" data-dojo-type="dojox.mobile.ValuePickerTimePicker"></div>
+		<div id="msg"></div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Video-single-source.html b/dojox/mobile/tests/test_Video-single-source.html
new file mode 100644
index 0000000..fbf5a85
--- /dev/null
+++ b/dojox/mobile/tests/test_Video-single-source.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Video</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Video"
+		]);
+	</script>
+</head>
+<body>
+	<video data-dojo-type="dojox.mobile.Video" width="320" height="240" controls>
+		<source src="video/sample.mp4" type="video/mp4">
+		<p>To show the movie, A browser which supported video tag is required.</p>
+	</video>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_Video.html b/dojox/mobile/tests/test_Video.html
new file mode 100644
index 0000000..b5530bc
--- /dev/null
+++ b/dojox/mobile/tests/test_Video.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Video</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Video"
+		]);
+	</script>
+</head>
+<body>
+	<video data-dojo-type="dojox.mobile.Video" width="320" height="240" controls>
+		<source src="video/sample.mp4" type="video/mp4">
+		<source src="video/sample.ogv" type="video/ogg">
+		<source src="video/sample.webm" type="video/webm">
+		<p>To show the movie, A browser which supported video tag is required.</p>
+	</video>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_a11y.html b/dojox/mobile/tests/test_a11y.html
new file mode 100644
index 0000000..27f8878
--- /dev/null
+++ b/dojox/mobile/tests/test_a11y.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Accessibility</title>
+
+	<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer','TabBar','RadioButton']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/RadioButton"
+		]);
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" role="heading">Mobile Mashup</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Spaces</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" role="list">
+			<li id="item1" role="button" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", alt:"Orange", rightText:"Go To", rightIconTitle:"", moveTo:"view2"'>
+				Heading Sample
+			</li>
+			<li id="item2" role="button" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", alt:"Green", rightText:"Go To", rightIconTitle:"", moveTo:"view3"'>
+				ListItem Sample
+			</li>
+			<li id="item3" role="button" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", alt:"Blue", rightText:"Go To", rightIconTitle:"", moveTo:"view4"'>
+				Icon Sample
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading">
+			<span id="btn1" data-dojo-type="dojox.mobile.ToolBarButton" title="Edit" role="button">Edit</span>
+			<span id="btn2" data-dojo-type="dojox.mobile.ToolBarButton" data-dojo-props='icon:"mblDomButtonWhitePlus", alt:"Plus"' title="plus" role="button" style="float:right;" onclick="console.log('+ was clicked')"></span>
+			World Clock
+		</div><br>
+
+		<div data-dojo-type="dojox.mobile.Heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton" title="New" role="button" data-dojo-props='toggle:true'>New</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" title="Toggle" role="button" data-dojo-props='toggle:true'>Toggle</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" title="Information" role="button" data-dojo-props='alt:"Information", icon:"images/a-icon-12.png"'></span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" title="Hint" role="button" data-dojo-props='alt:"Hint", icon:"images/tab-icons.png", iconPos:"29,0,29,29"'></span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" title="Search" role="button" data-dojo-props='alt:"Search", icon:"mblDomButtonWhiteSearch"' style="float:right;"></span>
+		</div><br>
+
+		<div data-dojo-type="dojox.mobile.Heading">
+			<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"' style="float:right;margin-right:6px;" role="tablist">
+				<li data-dojo-type="dojox.mobile.TabBarButton" title="Up" role="button" data-dojo-props='icon:"mblDomButtonWhiteUpArrow", selectOne:false'></li>
+				<li data-dojo-type="dojox.mobile.TabBarButton" title="Down" role="button" data-dojo-props='icon:"mblDomButtonWhiteDownArrow", selectOne:false'></li>
+			</ul>
+			1 of 10
+		</div><br>
+
+		<div data-dojo-type="dojox.mobile.Heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton" title="Back" role="button" style="float:left;" data-dojo-props='arrow:"left", moveTo:"view1", transitionDir:-1'>Back</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" title="Search" role="button" style="float:right;" data-dojo-props='icon:"mblDomButtonWhiteSearch", alt:"Search"'></span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" title="Up" role="button" style="float:right;" data-dojo-props='icon:"mblDomButtonWhiteUpArrow", alt:"Up"'></span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" title="Down" role="button" style="float:right;" data-dojo-props='icon:"mblDomButtonWhiteDownArrow", alt:"Down"'></span>
+		</div>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading" role="heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton" title="Back" role="button" style="float:left;" data-dojo-props='arrow:"left", moveTo:"view1", transitionDir:-1'>Back</span>
+			Settings
+		</div>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" role="list">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", alt:""' role="listitem">
+				Airplane Mode
+				<div data-dojo-type="dojox.mobile.Switch" title="switch" role="button"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", alt:""' role="listitem">
+				Wi-Fi
+				<div style="float:right;">
+					<input type="radio" id="rb1" dojoType="dojox.mobile.RadioButton" value="Medium" checked><label for="rb1">On</label>
+					<input type="radio" id="rb2" dojoType="dojox.mobile.RadioButton" value="Small"><label for="rb2">Off</label>		
+				</div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", alt:"", rightText:"AcmePhone", moveTo:"view1"' role="button">
+				Carrier
+			</li>
+		</ul>
+	</div>
+
+	<div id="view4" data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.Heading" role="heading">
+			<span data-dojo-type="dojox.mobile.ToolBarButton" title="Back" role="button" style="float:left;" data-dojo-props='arrow:"left", moveTo:"view1", transitionDir:-1'>Back</span>
+			Icon Container
+		</div>
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='iconItemPaneProps:{closeIconTitle:"Close", closeIconRole:"button"}' role="list">
+			<li data-dojo-type="dojox.mobile.IconItem" lazy="true" data-dojo-props='label:"app1", icon:"images/icon-1.png", alt:"icon1"' role="listitem"><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" lazy="true" data-dojo-props='label:"app2", icon:"images/icon-1.png", alt:"icon2"' role="listitem"><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" lazy="true" data-dojo-props='label:"app3", icon:"images/icon-1.png", alt:"icon3"' role="listitem"><div class="box"></div></li>
+		</ul>
+	</div>
+
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_add-to-home-screen-sample.html b/dojox/mobile/tests/test_add-to-home-screen-sample.html
new file mode 100644
index 0000000..4bc3973
--- /dev/null
+++ b/dojox/mobile/tests/test_add-to-home-screen-sample.html
@@ -0,0 +1,218 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Add to Home Screen</title>
+
+	<link href="../themes/common/domButtons/DomButtonSilverCircleRedCross.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Button','Tooltip']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/cookie",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile",
+			"dojox/mobile/iconUtils",
+			"dojox/mobile/parser",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/Button",
+			"dojox/mobile/Tooltip"
+		], function(connect, cookie, dom, domClass, ready, registry, common, iconUtils){
+			var timerShow, timerHide;
+			var handler;
+			dlgShow = function(){
+				dom.byId('dlgRef').style.top = common.getScreenSize().h - 5 + "px";
+				registry.byId('dlgBody').show(dom.byId('dlgRef'), ['above-centered']);
+				timerHide = setTimeout(function(){
+					timerHide = 0;
+					dlgHide();
+				}, 10000);
+			}
+			dlgHide = function(){
+				if(timerShow){
+					clearTimeout(timerShow);
+				}
+				if(timerHide){
+					clearTimeout(timerHide);
+				}
+				if(handler){
+					connect.disconnect(handler);
+				}
+				registry.byId('dlgBody').hide();
+			}
+			setCookie = function(){
+				cookie("disable-AtHS-Notification", true, {expires:1});
+				if(cookie("disable-AtHS-Notification") != undefined){
+					registry.byId('clearBtn').set("disabled", false);
+				}
+			}
+			clearCookie = function(){
+				cookie("disable-AtHS-Notification", null, {expires:-1});
+				registry.byId('clearBtn').set("disabled", true);
+			}
+			ready(function(){
+				iconUtils.createDomButton(dom.byId('dlgClose'));
+				if(cookie("disable-AtHS-Notification") == undefined){
+					timerShow = setTimeout(function(){
+						timerShow = 0;
+						dlgShow();
+					}, 2000);
+					// To hide tooltip window by force before starting view transition
+					handler = connect.connect(registry.byId("foo"), "onBeforeTransitionOut", null, function(moveTo, dir, transition, context, method){
+						dlgHide();
+					});
+				}else{
+					registry.byId('clearBtn').set("disabled", false);
+				}
+			});
+		});
+	</script>
+
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+
+	/* sample code */
+	#dlgRef {
+		position: absolute;
+		left: 0;
+		width: 100%;
+	}
+	#dlgBody {
+		width: 75%;
+		font-family: Helvetica;
+		font-size: 14px;
+		-webkit-box-shadow: 0 1px 2px 2px rgba(0,0,0,0.3);
+		opacity: .9;
+	}
+	#dlgBody td {
+		vertical-align:top;
+	}
+	/* sample code */
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<!-- sample code -->
+	<div id="dlgRef">
+		<div id="dlgBody" data-dojo-type="dojox.mobile.Tooltip" class="mblTooltipBubble">
+			<table>
+				<tr>
+					<td><img alt="" src="images/tab-icon-12.png"></td>
+					<td width="99%"><b>Sample of "Add to Home Screen" notification</b><br><br>
+					This window will be hidden in ten seconds automatically.<br>
+					If you click the close button, the window is not displayed from next time until you click the "Clear Cookie" button.</td>
+					<td><div id="dlgClose" class="mblDomButtonSilverCircleRedCross" onclick="setCookie();dlgHide()"></div></td>
+				</tr>
+			</table>
+		</div>
+	</div>
+	<!-- sample code -->
+	
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			<b>Sample of "Add to Home Screen" notification using the Tooltip widget.</b><br>
+			<br>
+			<button id="clearBtn" data-dojo-type="dojox.mobile.Button" disabled onclick="clearCookie()">Clear Cookie</button><br>
+			- When "Clear Cookie" button is active, the notification window is not displayed.<br>
+			- After clicking button, reload this page by manually.
+		</div>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 5
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 6
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"slide"'>
+				Slide 7
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"flip"'>
+				Flip 8
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"fade"'>
+				Fade 9
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide 10
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip 11
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade 12
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"slide"'>
+				Slide 13
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"flip"'>
+				Flip 14
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view2", transition:"fade"'>
+				Fade 15
+			</li>
+		</ul>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"Home", moveTo:"view1"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ajax-html-sync.html b/dojox/mobile/tests/test_ajax-html-sync.html
new file mode 100644
index 0000000..b06e586
--- /dev/null
+++ b/dojox/mobile/tests/test_ajax-html-sync.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Ajax</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: false, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Ajax (HTML)</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">External Views</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", transition:"slide", url:"data/view1.html"'>
+				External View #1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", transition:"flip", url:"data/view2.html"'>
+				External View #2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", transition:"fade", url:"data/view3.html"'>
+				External View #3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", transition:"slide", url:"data/view4.html"'>
+				External View #4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", transition:"slide", url:"data/view5.html"'>
+				External View #5
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ajax-html.html b/dojox/mobile/tests/test_ajax-html.html
index e201134..c0d8ae6 100644
--- a/dojox/mobile/tests/test_ajax-html.html
+++ b/dojox/mobile/tests/test_ajax-html.html
@@ -1,33 +1,43 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Ajax</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Ajax</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Ajax (HTML)</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">External Views</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" transition="slide" url="view1.html">
-					External View #1 (sync)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" transition="flip" url="view2.html" sync="false">
-					External View #2 (async)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" transition="fade" url="view3.html">
-					External View #3 (sync)
-				</li>
-			</ul>
-		</div>
-	</body>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Ajax (HTML)</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">External Views</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", transition:"slide", url:"data/view1.html"'>
+				External View #1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", transition:"flip", url:"data/view2.html"'>
+				External View #2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", transition:"fade", url:"data/view3.html"'>
+				External View #3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", transition:"slide", url:"data/view4.html"'>
+				External View #4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", transition:"slide", url:"data/view5.html"'>
+				External View #5
+			</li>
+		</ul>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_ajax-json-sync.html b/dojox/mobile/tests/test_ajax-json-sync.html
new file mode 100644
index 0000000..a12408b
--- /dev/null
+++ b/dojox/mobile/tests/test_ajax-json-sync.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Ajax</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: false, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Ajax (JSON)</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">External Views</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", transition:"slide", url:"data/view1.json"'>
+				External View #1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", transition:"flip", url:"data/view2.json"'>
+				External View #2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", transition:"fade", url:"data/view3.json"'>
+				External View #3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", transition:"slide", url:"data/view4.json"'>
+				External View #4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", transition:"slide", url:"data/view5.json"'>
+				External View #5
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_ajax-json.html b/dojox/mobile/tests/test_ajax-json.html
index 28b1802..0605994 100644
--- a/dojox/mobile/tests/test_ajax-json.html
+++ b/dojox/mobile/tests/test_ajax-json.html
@@ -1,33 +1,43 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Ajax</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Ajax</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Ajax (JSON)</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">External Views</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" transition="slide" url="view1.json">
-					External View #1 (sync)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" transition="flip" url="view2.json" sync="false">
-					External View #2 (async)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" transition="fade" url="view3.json">
-					External View #3 (sync)
-				</li>
-			</ul>
-		</div>
-	</body>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Ajax (JSON)</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">External Views</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", transition:"slide", url:"data/view1.json"'>
+				External View #1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", transition:"flip", url:"data/view2.json"'>
+				External View #2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", transition:"fade", url:"data/view3.json"'>
+				External View #3
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", transition:"slide", url:"data/view4.json"'>
+				External View #4
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", transition:"slide", url:"data/view5.json"'>
+				External View #5
+			</li>
+		</ul>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_anchor-label.html b/dojox/mobile/tests/test_anchor-label.html
index ca0af5f..cca4fcb 100644
--- a/dojox/mobile/tests/test_anchor-label.html
+++ b/dojox/mobile/tests/test_anchor-label.html
@@ -1,73 +1,78 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Anchor Label</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Anchor Label</title>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: false, parseOnLoad: true"></script>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-
-			dojo.declare(
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(declare, ListItem){
+			dojox.mobile.ListItemEx = declare(
 				"dojox.mobile.ListItemEx",
-				dojox.mobile.ListItem,
+				ListItem,
 			{
 				onAnchorLabelClicked: function(e){
 					if(this.id == "item1" || this.id == "item2"){
 						// go to a different html page
-						var href = "test_iPhone-Icon.html";
+						var href = "test_IconContainer.html";
 						this.transitionTo(null, href);
 					}else if(this.id == "item3" || this.id == "item4"){
 						// load an external view into the current html page
-						var url = "view2.html";
+						var url = "data/view2.html";
 						this.transitionTo(null, null, url);
 					}
 				}
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Anchor Label</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Items</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="item1" dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-1.png" moveTo="bar" anchorLabel="true">
-					Different page
-				</li>
-				<li id="item2" dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-2.png" moveTo="bar" anchorLabel="true">
-					Different page
-				</li>
-				<li id="item3" dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-3.png" moveTo="bar" anchorLabel="true">
-					External view
-				</li>
-				<li id="item4" dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-4.png" moveTo="bar" anchorLabel="true">
-					External view
-				</li>
-			</ul>
-			<div dojoType="dojox.mobile.RoundRect">
-				Tapping on an item label text opens a different page (test_iPhone-Icon.html) or loads an external view (view2.html), while tapping on right-hand side of the label text shows another view in the same page.
-			</div>
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<h1 data-dojo-type="dojox.mobile.Heading">Anchor Label</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Items</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li id="item1" data-dojo-type="dojox.mobile.ListItemEx" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"bar", anchorLabel:true'>
+				Different page
+			</li>
+			<li id="item2" data-dojo-type="dojox.mobile.ListItemEx" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bar", anchorLabel:true'>
+				Different page
+			</li>
+			<li id="item3" data-dojo-type="dojox.mobile.ListItemEx" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"bar", anchorLabel:true'>
+				External view
+			</li>
+			<li id="item4" data-dojo-type="dojox.mobile.ListItemEx" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"bar", anchorLabel:true'>
+				External view
+			</li>
+		</ul>
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			Tapping on an item label text opens a different page (test_IconContainer.html) or loads an external view (view2.html), while tapping on right-hand side of the label text shows another view in the same page.
 		</div>
+	</div>
 
-		<div id="bar" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="foo">u1space</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">
-					Video
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" rightText="VPN">
-					Maps
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">
-					Phone Number
-				</li>
-			</ul>
-		</div>
-	</body>
+	<div id="bar" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Spaces", moveTo:"home"'>u1space</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Applications</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+				Video
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", rightText:"VPN"'>
+				Maps
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off"'>
+				Phone Number
+			</li>
+		</ul>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_bg-view.html b/dojox/mobile/tests/test_bg-view.html
new file mode 100644
index 0000000..f960b06
--- /dev/null
+++ b/dojox/mobile/tests/test_bg-view.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Background image (View)</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	#home{
+		height: 100%;
+		background-image: url("images/Mountain.jpg");
+		background-size: cover;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Home</h1>
+		<ul id="iconContainer" data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='transition:"slide", single:true'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", moveTo:"about", icon:"images/icon1.png", badge:"55"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", moveTo:"about", icon:"images/icon2.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", moveTo:"about", icon:"images/icon3.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app4", moveTo:"about", icon:"images/icon4.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app5", moveTo:"about", icon:"images/icon5.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app6", moveTo:"about", icon:"images/icon6.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app7", moveTo:"about", icon:"images/icon7.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app8", moveTo:"about", icon:"images/icon8.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app9", moveTo:"about", icon:"images/icon9.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app10", moveTo:"about", icon:"images/icon10.png"'></li>
+		</ul>
+	</div>
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"home"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bg.html b/dojox/mobile/tests/test_bg.html
new file mode 100644
index 0000000..0489a82
--- /dev/null
+++ b/dojox/mobile/tests/test_bg.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Background image</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	body{
+		background-image: url("images/Mountain.jpg");
+		background-size: cover;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Home</h1>
+		<ul id="iconContainer" data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='transition:"slide", single:true'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app1", moveTo:"about", icon:"images/icon1.png", badge:"55"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app2", moveTo:"about", icon:"images/icon2.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app3", moveTo:"about", icon:"images/icon3.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app4", moveTo:"about", icon:"images/icon4.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app5", moveTo:"about", icon:"images/icon5.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app6", moveTo:"about", icon:"images/icon6.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app7", moveTo:"about", icon:"images/icon7.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app8", moveTo:"about", icon:"images/icon8.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app9", moveTo:"about", icon:"images/icon9.png"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"app10", moveTo:"about", icon:"images/icon10.png"'></li>
+		</ul>
+	</div>
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"home"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">My Phone</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk-ScrollableView-demo.html b/dojox/mobile/tests/test_bk-ScrollableView-demo.html
new file mode 100644
index 0000000..1cd7854
--- /dev/null
+++ b/dojox/mobile/tests/test_bk-ScrollableView-demo.html
@@ -0,0 +1,429 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bookmarkable - ScrollableView demo</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/bookmarkable",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/TabBar"
+		]);
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	.list1 li{
+		border-style: solid;
+		border-width: 1px 0px 1px 0px;
+		border-top-color: #BABABC;
+		border-bottom-color: #89898C;
+		background-color: #ACACAF;
+		line-height: 0px;
+	}
+	.list1 li table{
+		line-height: normal;
+	}
+	.list1 li:nth-child(even){
+		background-color: #97979B;
+	}
+	#list2 li:nth-child(even){
+		background-color: #eeeeee;
+	}
+	#categ1 {
+		font-size: 18px;
+	}
+	#categ1 li{
+		line-height: 70px;
+	}
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	.content {
+		padding:0px 10px;
+		background-color: white;
+	}
+	p {
+		font-family: Helvetica;
+		font-size: 12px;
+	}
+	.title {
+		color: blue;
+		margin-bottom: 4px;
+	}
+	.subtitle {
+		font-style: italic;
+		color: gray;
+		margin: 0px;
+		margin-bottom: 4px;
+	}
+	.subsubtitle {
+		margin: 16px 0px 0px 0px;
+	}
+	.lst {
+		margin: 0px;
+		padding: 0px 14px;
+	}
+	.lst li {
+		font-family: Helvetica;
+		font-size: 12px;
+		margin: 0px;
+		list-style-type: square;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", fixed:"top", syncWithViews:true'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"#view1", selected:true'>New</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"#view2"'>What's Hot</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"#view3"'>Genius</li>
+		</ul>
+
+		<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" class="list1">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+									Martin Parker Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" id="list2">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+					Network											   
+				</li>												   
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+					Line
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+					Songs
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+					Videos
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+					Photos
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+					Applications
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+					Capacity
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+					Available
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+					Version
+				</li>
+			</ul>
+		</div>
+	</div>
+
+	<div id="categ" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Categories</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" class="list1" id="categ1">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 1</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 2</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 3</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 4</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 5</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 6</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 7</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 8</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 9</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 10</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 11</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 12</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 13</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 14</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 15</li>
+		</ul>
+	</div>
+
+	<div id="top25" data-dojo-type="dojox.mobile.View">
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", fixed:"top", syncWithViews:true'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", moveTo:"#news1", selected:true'>News1</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"#news2"'>News2</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-10.png", icon2:"images/tab-icon-10h.png", moveTo:"#news3"'>News3</li>
+		</ul>
+
+		<div id="news1" data-dojo-type="dojox.mobile.ScrollableView">
+			<h1 data-dojo-type="dojox.mobile.Heading">News 1</h1>
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Top Stories</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Top 10 news stories of the decade
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Create client-side diagrammatic interaction in Web applications with GFX
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+				</li>
+			</ul>
+		</div>
+
+		<div id="news2" data-dojo-type="dojox.mobile.ScrollableView">
+			<h1 data-dojo-type="dojox.mobile.Heading">News 2</h1>
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Top Stories</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Top 10 news stories of the decade
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Create client-side diagrammatic interaction in Web applications with GFX
+				</li>
+			</ul>
+		</div>
+
+		<div id="news3" data-dojo-type="dojox.mobile.ScrollableView">
+			<h1 data-dojo-type="dojox.mobile.Heading">News 3</h1>
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Top Stories</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Top 10 news stories of the decade
+				</li>
+			</ul>
+		</div>
+
+	</div>
+
+	<div id="search" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+
+	<div id="article" data-dojo-type="dojox.mobile.ScrollableView" style="color:black;background-color:white;height:100%">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Article</h1>
+		<div class="content">
+			<h3 class="title">Did you know?</h3>
+			<h4 class="subtitle">Features of dojox.mobile</h4>
+			<h5 class="subsubtitle">No images are used</h5>
+			<ul class="lst">
+				<li>UI parts consist of DOM and CSS3.</li>
+				<li>Only application icons are images.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
+			<ul class="lst">
+				<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Support for CSS sprite</h5>
+			<ul class="lst">
+				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
+			<ul class="lst">
+				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
+			</ul>
+		</div>
+	</div>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='fixed:"bottom", syncWithViews:true' style="border-bottom:none;">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", selected:true, moveTo:"#group1"'>Featured</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"#categ"'>Categories</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-10.png", icon2:"images/tab-icon-10h.png", moveTo:"#top25"'>Top 25</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-11.png", icon2:"images/tab-icon-11h.png", moveTo:"#search"'>Search</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-13.png", icon2:"images/tab-icon-13h.png", moveTo:"#article"'>Updates</li>
+	</ul>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk-content-view.html b/dojox/mobile/tests/test_bk-content-view.html
new file mode 100644
index 0000000..7ca8e4f
--- /dev/null
+++ b/dojox/mobile/tests/test_bk-content-view.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Ajax</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/bookmarkable",
+			"dojox/mobile/compat",
+			"dojox/mobile/_ContentPaneMixin"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Ajax (HTML)</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">External Views</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", transition:"slide", moveTo:"#view1"'>
+				ContentView #1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", transition:"flip", moveTo:"#view2"'>
+				ContentView #2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", transition:"fade", moveTo:"#view3"'>
+				ContentView #3
+			</li>
+		</ul>
+	</div>
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-mixins="dojox.mobile._ContentPaneMixin" data-dojo-props='href:"data/cvfragment1.html", lazy:true'></div>
+	<div id="view2" data-dojo-type="dojox.mobile.View" data-dojo-mixins="dojox.mobile._ContentPaneMixin" data-dojo-props='href:"data/cvfragment2.html", lazy:true'></div>
+	<div id="view3" data-dojo-type="dojox.mobile.View" data-dojo-mixins="dojox.mobile._ContentPaneMixin" data-dojo-props='href:"data/cvfragment3.html", lazy:true'></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk-grouped-views.html b/dojox/mobile/tests/test_bk-grouped-views.html
new file mode 100644
index 0000000..0272a13
--- /dev/null
+++ b/dojox/mobile/tests/test_bk-grouped-views.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Grouped Views</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/bookmarkable",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<div id="view11" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+			<h1 data-dojo-type="dojox.mobile.Heading">View 1-1</h1>
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Grouped View Example</h2>
+			<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+				<pre style="font-size:12px">
+ - View 1 (container)
+     |
+     *-- View 1-1
+         View 1-2
+ - View 2</pre>
+			</div>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#view12", transition:"slide"'>
+					View 1-2
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#view2", transition:"slide"'>
+					View 2
+				</li>
+			</ul>
+		</div>
+
+		<div id="view12" data-dojo-type="dojox.mobile.View">
+			<h1 data-dojo-type="dojox.mobile.Heading">View 1-2</h1>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#view11", transition:"slide", transitionDir:-1'>
+					View 1-1
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#view2", transition:"slide"'>
+					View 2
+				</li>
+			</ul>
+		</div>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">View 2</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#view1", transition:"slide", transitionDir:-1'>
+				View 1
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk-list.html b/dojox/mobile/tests/test_bk-list.html
new file mode 100644
index 0000000..14cc913
--- /dev/null
+++ b/dojox/mobile/tests/test_bk-list.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bookmarkable - list</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/bookmarkable"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Bookmarkable</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#page1", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#page2", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#page3", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			After you move to other views, you should also be able to navigate through the views with browser's back and forward buttons. Also, views should be bookmarkable.
+		</div>
+	</div>
+
+	<div id="page1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#home", transition:"slide"'>Page 1</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#result1"'>
+				Item 1
+			</li>
+		</ul>
+	</div>
+
+	<div id="page2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#home", transition:"flip"'>Page 2</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#result2"'>
+				Item 2
+			</li>
+		</ul>
+	</div>
+
+	<div id="page3" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#home", transition:"fade"'>Page 3</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#result3"'>
+				Item 3
+			</li>
+		</ul>
+	</div>
+
+	<div id="result1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Page 1", moveTo:"#page1"'>Search Result 1</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <span class="lnk">Dojo: Traditional Karate-do Spirit</span><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+		</ul>
+	</div>
+
+	<div id="result2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Page 2", moveTo:"#page2"'>Search Result 2</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <span class="lnk">Japanese Martial Arts Dojo</span><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+		</ul>
+	</div>
+
+	<div id="result3" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Page 3", moveTo:"#page3"'>Search Result 3</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <span class="lnk">Total Solar Eclipse</span><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk-split-views.html b/dojox/mobile/tests/test_bk-split-views.html
new file mode 100644
index 0000000..b4f17e6
--- /dev/null
+++ b/dojox/mobile/tests/test_bk-split-views.html
@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bookmarkable - Split Views</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/bookmarkable",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Container"
+		]);
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Container" style="width:50%;border-right:1px solid black;">
+			<div id="foo1" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#bar11", transition:"slide"'>
+						Slide
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#bar12", transition:"flip"'>
+						Flip
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#bar13", transition:"fade"'>
+						Fade
+					</li>
+				</ul>
+			</div>
+
+			<div id="bar11" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#foo1"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						1. <span class="lnk">Dojo: Traditional Karate-do Spirit</span><br>
+						Sarah Connor Hardcover<br>
+						Eligible for FREE Super Saver Shipping<br>
+						<span style="color:red">$14.50 (50%)</span> In Stock<br>
+						# (531)
+					</li>
+				</ul>
+			</div>
+			<div id="bar12" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#foo1", transition:"flip"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						2. <span class="lnk">Japanese Martial Arts Dojo</span><br>
+						Martin Parker Hardcover<br>
+						<span style="color:red">$14.00 (60%)</span> In Stock<br>
+						# (173)
+					</li>
+				</ul>
+			</div>
+			<div id="bar13" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#foo1", transition:"fade"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						3. <span class="lnk">Total Solar Eclipse</span><br>
+						Steven Young Hardcover<br>
+						Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+						Eligible for FREE Super Saver Shipping<br>
+						<span style="color:red">$9.50 (62%)</span> In Stock<br>
+						# (1199)
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Container">
+			<div id="foo2" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#bar21", transition:"slide"'>
+						Slide
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#bar22", transition:"flip"'>
+						Flip
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#bar23", transition:"fade"'>
+						Fade
+					</li>
+				</ul>
+			</div>
+
+			<div id="bar21" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#foo2"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						1. <span class="lnk">Dojo: Traditional Karate-do Spirit</span><br>
+						Sarah Connor Hardcover<br>
+						Eligible for FREE Super Saver Shipping<br>
+						<span style="color:red">$14.50 (50%)</span> In Stock<br>
+						# (531)
+					</li>
+				</ul>
+			</div>
+			<div id="bar22" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#foo2", transition:"flip"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						2. <span class="lnk">Japanese Martial Arts Dojo</span><br>
+						Martin Parker Hardcover<br>
+						<span style="color:red">$14.00 (60%)</span> In Stock<br>
+						# (173)
+					</li>
+				</ul>
+			</div>
+			<div id="bar23" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"#foo2", transition:"fade"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						3. <span class="lnk">Total Solar Eclipse</span><br>
+						Steven Young Hardcover<br>
+						Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+						Eligible for FREE Super Saver Shipping<br>
+						<span style="color:red">$9.50 (62%)</span> In Stock<br>
+						# (1199)
+					</li>
+				</ul>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk-tablet-settings.html b/dojox/mobile/tests/test_bk-tablet-settings.html
new file mode 100644
index 0000000..efce1ec
--- /dev/null
+++ b/dojox/mobile/tests/test_bk-tablet-settings.html
@@ -0,0 +1,240 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bookmarkable - Tablet Settings</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/bookmarkable",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/Container"
+		]);
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	.mblEdgeToEdgeList {
+		background-color: #DBDDE2;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Container" style="width:300px;border-right:1px solid black;">
+			<div id="settings" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Settings</h1>
+				<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='transition:"flip", stateful:true, syncWithViews:true'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#wifi"'>
+						Wi-Fi
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#bright"'>
+						Brightness & Wallpaper
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#picture"'>
+						Picture Frame
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"#general", selected:true'>
+						General
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"#wifi"'>
+						Mail, Contacts, Calendars
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"#bright"'>
+						Safari
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"#picture"'>
+						iPod
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"#general"'>
+						Video
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"#wifi"'>
+						Photos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"#bright"'>
+						Store
+					</li>
+					<li class="mblEdgeToEdgeCategory">
+						Apps
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#wifi"'>
+						News
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#bright"'>
+						Weather
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#picture"'>
+						Books
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"#general"'>
+						 Business
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#wifi"'>
+						Navigation
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#bright"'>
+						Sports
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#picture"'>
+						Social
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"#general"'>
+						Music
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Container">
+
+			<div id="general" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>General</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#about"'>
+						About
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2h 40m", moveTo:"#about"'>
+						Usage
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#about"'>
+						Network
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"#about"'>
+						Bluetooth
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#about"'>
+						Location Services
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1 Minute", moveTo:"#about"'>
+						Auto-Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"#about"'>
+						Passcode Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"#about"'>
+						Restrictions
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#about"'>
+						Home
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#about"'>
+						Date & Time					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#about"'>
+						Keyboard					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#about"'>
+						International				   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#about"'>
+						Accessibility
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#about"'>
+						Reset
+					</li>
+				</ul>
+			</div>
+
+			<div id="about" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"General", moveTo:"#general"'>About</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Network											   
+					</li>												   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Line
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+						Songs
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+						Videos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+						Photos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+						Applications
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+						Capacity
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+						Available
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+						Version
+					</li>
+				</ul>
+			</div>
+
+			<div id="wifi" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Wi-Fi Networks</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Wi-Fi
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<input type="text">
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<select><option>Songs</option><option>Videos</option><option>Photos</option></select>
+					</li>
+				</ul>
+			</div>
+
+			<div id="bright" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Brightness & Wallpaper</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Auto-Brightness
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+				</ul>
+			</div>
+
+			<div id="picture" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Picture Frame</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"single"'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true'>
+						Dissolve
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Origami
+					</li>
+				</ul>
+			</div>
+
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk_force-ScrollableView-demo.html b/dojox/mobile/tests/test_bk_force-ScrollableView-demo.html
new file mode 100644
index 0000000..339950a
--- /dev/null
+++ b/dojox/mobile/tests/test_bk_force-ScrollableView-demo.html
@@ -0,0 +1,429 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bookmarkable - ScrollableView demo</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true, mblForceBookmarkable: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/bookmarkable",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/TabBar"
+		]);
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	.list1 li{
+		border-style: solid;
+		border-width: 1px 0px 1px 0px;
+		border-top-color: #BABABC;
+		border-bottom-color: #89898C;
+		background-color: #ACACAF;
+		line-height: 0px;
+	}
+	.list1 li table{
+		line-height: normal;
+	}
+	.list1 li:nth-child(even){
+		background-color: #97979B;
+	}
+	#list2 li:nth-child(even){
+		background-color: #eeeeee;
+	}
+	#categ1 {
+		font-size: 18px;
+	}
+	#categ1 li{
+		line-height: 70px;
+	}
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	.content {
+		padding:0px 10px;
+		background-color: white;
+	}
+	p {
+		font-family: Helvetica;
+		font-size: 12px;
+	}
+	.title {
+		color: blue;
+		margin-bottom: 4px;
+	}
+	.subtitle {
+		font-style: italic;
+		color: gray;
+		margin: 0px;
+		margin-bottom: 4px;
+	}
+	.subsubtitle {
+		margin: 16px 0px 0px 0px;
+	}
+	.lst {
+		margin: 0px;
+		padding: 0px 14px;
+	}
+	.lst li {
+		font-family: Helvetica;
+		font-size: 12px;
+		margin: 0px;
+		list-style-type: square;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="group1" data-dojo-type="dojox.mobile.View" data-dojo-props='keepScrollPos:false'><!-- keepScrollPos=false is to improve performance -->
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", fixed:"top", syncWithViews:true'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view1", selected:true'>New</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view2"'>What's Hot</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"view3"'>Genius</li>
+		</ul>
+
+		<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" class="list1">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+									Martin Parker Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+			<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" id="list2">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img alt="" src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+					Network											   
+				</li>												   
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+					Line
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+					Songs
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+					Videos
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+					Photos
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+					Applications
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+					Capacity
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+					Available
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+					Version
+				</li>
+			</ul>
+		</div>
+	</div>
+
+	<div id="categ" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Categories</h1>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" class="list1" id="categ1">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 1</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 2</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 3</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 4</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 5</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 6</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 7</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 8</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 9</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 10</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 11</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 12</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 13</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 14</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>Category 15</li>
+		</ul>
+	</div>
+
+	<div id="top25" data-dojo-type="dojox.mobile.View">
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl", fixed:"top", syncWithViews:true'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", moveTo:"news1", selected:true'>News1</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"news2"'>News2</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-10.png", icon2:"images/tab-icon-10h.png", moveTo:"news3"'>News3</li>
+		</ul>
+
+		<div id="news1" data-dojo-type="dojox.mobile.ScrollableView">
+			<h1 data-dojo-type="dojox.mobile.Heading">News 1</h1>
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Top Stories</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Top 10 news stories of the decade
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Create client-side diagrammatic interaction in Web applications with GFX
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+				</li>
+			</ul>
+		</div>
+
+		<div id="news2" data-dojo-type="dojox.mobile.ScrollableView">
+			<h1 data-dojo-type="dojox.mobile.Heading">News 2</h1>
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Top Stories</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Top 10 news stories of the decade
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Create client-side diagrammatic interaction in Web applications with GFX
+				</li>
+			</ul>
+		</div>
+
+		<div id="news3" data-dojo-type="dojox.mobile.ScrollableView">
+			<h1 data-dojo-type="dojox.mobile.Heading">News 3</h1>
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Top Stories</h2>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true'>
+					Top 10 news stories of the decade
+				</li>
+			</ul>
+		</div>
+
+	</div>
+
+	<div id="search" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='variableHeight:true' style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+
+	<div id="article" data-dojo-type="dojox.mobile.ScrollableView" style="color:black;background-color:white;height:100%">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Article</h1>
+		<div class="content">
+			<h3 class="title">Did you know?</h3>
+			<h4 class="subtitle">Features of dojox.mobile</h4>
+			<h5 class="subsubtitle">No images are used</h5>
+			<ul class="lst">
+				<li>UI parts consist of DOM and CSS3.</li>
+				<li>Only application icons are images.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
+			<ul class="lst">
+				<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Support for CSS sprite</h5>
+			<ul class="lst">
+				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
+			<ul class="lst">
+				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
+			</ul>
+		</div>
+	</div>
+
+	<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='fixed:"bottom", syncWithViews:true' style="border-bottom:none;">
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", selected:true, moveTo:"group1"'>Featured</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"categ"'>Categories</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-10.png", icon2:"images/tab-icon-10h.png", moveTo:"top25"'>Top 25</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-11.png", icon2:"images/tab-icon-11h.png", moveTo:"search"'>Search</li>
+		<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-13.png", icon2:"images/tab-icon-13h.png", moveTo:"article"'>Updates</li>
+	</ul>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk_force-content-view.html b/dojox/mobile/tests/test_bk_force-content-view.html
new file mode 100644
index 0000000..b86786b
--- /dev/null
+++ b/dojox/mobile/tests/test_bk_force-content-view.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Ajax</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblForceBookmarkable: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/bookmarkable",
+			"dojox/mobile/compat",
+			"dojox/mobile/_ContentPaneMixin"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Ajax (HTML)</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">External Views</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", transition:"slide", moveTo:"view1"'>
+				ContentView #1
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", transition:"flip", moveTo:"view2"'>
+				ContentView #2
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", transition:"fade", moveTo:"view3"'>
+				ContentView #3
+			</li>
+		</ul>
+	</div>
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-mixins="dojox.mobile._ContentPaneMixin" data-dojo-props='href:"data/cvfragment1.html", lazy:true'></div>
+	<div id="view2" data-dojo-type="dojox.mobile.View" data-dojo-mixins="dojox.mobile._ContentPaneMixin" data-dojo-props='href:"data/cvfragment2.html", lazy:true'></div>
+	<div id="view3" data-dojo-type="dojox.mobile.View" data-dojo-mixins="dojox.mobile._ContentPaneMixin" data-dojo-props='href:"data/cvfragment3.html", lazy:true'></div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk_force-grouped-views.html b/dojox/mobile/tests/test_bk_force-grouped-views.html
new file mode 100644
index 0000000..6a6e7b0
--- /dev/null
+++ b/dojox/mobile/tests/test_bk_force-grouped-views.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Grouped Views</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblForceBookmarkable: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/bookmarkable",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<div id="view11" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+			<h1 data-dojo-type="dojox.mobile.Heading">View 1-1</h1>
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Grouped View Example</h2>
+			<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+				<pre style="font-size:12px">
+ - View 1 (container)
+     |
+     *-- View 1-1
+         View 1-2
+ - View 2</pre>
+			</div>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view12", transition:"slide"'>
+					View 1-2
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"slide"'>
+					View 2
+				</li>
+			</ul>
+		</div>
+
+		<div id="view12" data-dojo-type="dojox.mobile.View">
+			<h1 data-dojo-type="dojox.mobile.Heading">View 1-2</h1>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view11", transition:"slide", transitionDir:-1'>
+					View 1-1
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"slide"'>
+					View 2
+				</li>
+			</ul>
+		</div>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">View 2</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view1", transition:"slide", transitionDir:-1'>
+				View 1
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk_force-list.html b/dojox/mobile/tests/test_bk_force-list.html
new file mode 100644
index 0000000..171357e
--- /dev/null
+++ b/dojox/mobile/tests/test_bk_force-list.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bookmarkable - list</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblForceBookmarkable: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/bookmarkable"
+		]);
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Bookmarkable</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"page1", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"page2", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"page3", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			After you move to other views, you should also be able to navigate through the views with browser's back and forward buttons. Also, views should be bookmarkable.
+		</div>
+	</div>
+
+	<div id="page1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"home", transition:"slide"'>Page 1</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"result1"'>
+				Item 1
+			</li>
+		</ul>
+	</div>
+
+	<div id="page2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"home", transition:"flip"'>Page 2</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"result2"'>
+				Item 2
+			</li>
+		</ul>
+	</div>
+
+	<div id="page3" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"home", transition:"fade"'>Page 3</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"result3"'>
+				Item 3
+			</li>
+		</ul>
+	</div>
+
+	<div id="result1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Page 1", moveTo:"page1"'>Search Result 1</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				1. <span class="lnk">Dojo: Traditional Karate-do Spirit</span><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+		</ul>
+	</div>
+
+	<div id="result2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Page 2", moveTo:"page2"'>Search Result 2</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				2. <span class="lnk">Japanese Martial Arts Dojo</span><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+		</ul>
+	</div>
+
+	<div id="result3" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Page 3", moveTo:"page3"'>Search Result 3</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='variableHeight:true'>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px">
+				3. <span class="lnk">Total Solar Eclipse</span><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk_force-split-views.html b/dojox/mobile/tests/test_bk_force-split-views.html
new file mode 100644
index 0000000..a5c7190
--- /dev/null
+++ b/dojox/mobile/tests/test_bk_force-split-views.html
@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bookmarkable - Split Views</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true, mblForceBookmarkable: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/bookmarkable",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Container"
+		]);
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Container" style="width:50%;border-right:1px solid black;">
+			<div id="foo1" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"bar11", transition:"slide"'>
+						Slide
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bar12", transition:"flip"'>
+						Flip
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"bar13", transition:"fade"'>
+						Fade
+					</li>
+				</ul>
+			</div>
+
+			<div id="bar11" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"foo1"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						1. <span class="lnk">Dojo: Traditional Karate-do Spirit</span><br>
+						Sarah Connor Hardcover<br>
+						Eligible for FREE Super Saver Shipping<br>
+						<span style="color:red">$14.50 (50%)</span> In Stock<br>
+						# (531)
+					</li>
+				</ul>
+			</div>
+			<div id="bar12" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"foo1", transition:"flip"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						2. <span class="lnk">Japanese Martial Arts Dojo</span><br>
+						Martin Parker Hardcover<br>
+						<span style="color:red">$14.00 (60%)</span> In Stock<br>
+						# (173)
+					</li>
+				</ul>
+			</div>
+			<div id="bar13" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"foo1", transition:"fade"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						3. <span class="lnk">Total Solar Eclipse</span><br>
+						Steven Young Hardcover<br>
+						Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+						Eligible for FREE Super Saver Shipping<br>
+						<span style="color:red">$9.50 (62%)</span> In Stock<br>
+						# (1199)
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Container">
+			<div id="foo2" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"bar21", transition:"slide"'>
+						Slide
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bar22", transition:"flip"'>
+						Flip
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"bar23", transition:"fade"'>
+						Fade
+					</li>
+				</ul>
+			</div>
+
+			<div id="bar21" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"foo2"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						1. <span class="lnk">Dojo: Traditional Karate-do Spirit</span><br>
+						Sarah Connor Hardcover<br>
+						Eligible for FREE Super Saver Shipping<br>
+						<span style="color:red">$14.50 (50%)</span> In Stock<br>
+						# (531)
+					</li>
+				</ul>
+			</div>
+			<div id="bar22" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"foo2", transition:"flip"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						2. <span class="lnk">Japanese Martial Arts Dojo</span><br>
+						Martin Parker Hardcover<br>
+						<span style="color:red">$14.00 (60%)</span> In Stock<br>
+						# (173)
+					</li>
+				</ul>
+			</div>
+			<div id="bar23" data-dojo-type="dojox.mobile.View">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"foo2", transition:"fade"'>Search Result</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+						3. <span class="lnk">Total Solar Eclipse</span><br>
+						Steven Young Hardcover<br>
+						Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+						Eligible for FREE Super Saver Shipping<br>
+						<span style="color:red">$9.50 (62%)</span> In Stock<br>
+						# (1199)
+					</li>
+				</ul>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bk_force-tablet-settings.html b/dojox/mobile/tests/test_bk_force-tablet-settings.html
new file mode 100644
index 0000000..a785ffa
--- /dev/null
+++ b/dojox/mobile/tests/test_bk_force-tablet-settings.html
@@ -0,0 +1,240 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Bookmarkable - Tablet Settings</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true, mblForceBookmarkable: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/bookmarkable",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/Container"
+		]);
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	.mblEdgeToEdgeList {
+		background-color: #DBDDE2;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Container" style="width:300px;border-right:1px solid black;">
+			<div id="settings" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Settings</h1>
+				<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='transition:"flip", stateful:true, syncWithViews:true'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						Wi-Fi
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Brightness & Wallpaper
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Picture Frame
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general", selected:true'>
+						General
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"#wifi"'>
+						Mail, Contacts, Calendars
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"#bright"'>
+						Safari
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"#picture"'>
+						iPod
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"#general"'>
+						Video
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"wifi"'>
+						Photos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"bright"'>
+						Store
+					</li>
+					<li class="mblEdgeToEdgeCategory">
+						Apps
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						News
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Weather
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Books
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general"'>
+						 Business
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#wifi"'>
+						Navigation
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#bright"'>
+						Sports
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#picture"'>
+						Social
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"#general"'>
+						Music
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Container">
+
+			<div id="general" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>General</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						About
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2h 40m", moveTo:"#about"'>
+						Usage
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Network
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"#about"'>
+						Bluetooth
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Location Services
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1 Minute", moveTo:"about"'>
+						Auto-Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"#about"'>
+						Passcode Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Restrictions
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Home
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#about"'>
+						Date & Time					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Keyboard					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"#about"'>
+						International				   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Accessibility
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Reset
+					</li>
+				</ul>
+			</div>
+
+			<div id="about" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"General", moveTo:"general"'>About</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Network											   
+					</li>												   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Line
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+						Songs
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+						Videos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+						Photos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+						Applications
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+						Capacity
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+						Available
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+						Version
+					</li>
+				</ul>
+			</div>
+
+			<div id="wifi" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Wi-Fi Networks</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Wi-Fi
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<input type="text">
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<select><option>Songs</option><option>Videos</option><option>Photos</option></select>
+					</li>
+				</ul>
+			</div>
+
+			<div id="bright" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Brightness & Wallpaper</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Auto-Brightness
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+				</ul>
+			</div>
+
+			<div id="picture" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Picture Frame</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"single"'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true'>
+						Dissolve
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Origami
+					</li>
+				</ul>
+			</div>
+
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_bookmarkable.html b/dojox/mobile/tests/test_bookmarkable.html
deleted file mode 100755
index f8b9b2d..0000000
--- a/dojox/mobile/tests/test_bookmarkable.html
+++ /dev/null
@@ -1,111 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Bookmarkable</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.hash");
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="home" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Bookmarkable</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="#page1" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="#page2" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="#page3" transition="fade">
-					Fade
-				</li>
-			</ul>
-			<div dojoType="dojox.mobile.RoundRect">
-				After you move to other views, you should also be able to navigate through the views with browser's back and forward buttons. Also, views should be bookmarkable.
-			</div>
-		</div>
-
-		<div id="page1" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="#home" transition="slide">Page 1</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="#result1">
-					Item 1
-				</li>
-			</ul>
-		</div>
-
-		<div id="page2" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="#home" transition="flip">Page 2</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="#result2">
-					Item 2
-				</li>
-			</ul>
-		</div>
-
-		<div id="page3" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="#home" transition="fade">Page 3</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="#result3">
-					Item 3
-				</li>
-			</ul>
-		</div>
-
-		<div id="result1" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Page 1" moveTo="#page1">Search Result 1</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-			</ul>
-		</div>
-
-		<div id="result2" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Page 2" moveTo="#page2">Search Result 2</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-			</ul>
-		</div>
-
-		<div id="result3" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Page 3" moveTo="#page3">Search Result 3</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_css-sprite.html b/dojox/mobile/tests/test_css-sprite.html
deleted file mode 100644
index 74f8617..0000000
--- a/dojox/mobile/tests/test_css-sprite.html
+++ /dev/null
@@ -1,170 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Settings</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			if(dojo.isBB){
-				console.log("CSS Sprite is not supported for the BlackBerry browser");
-			}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Settings</h1>
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,29,29,29" rightText="mac" href="test_iPhone-Icon.html">
-					Wi-Fi
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29" rightText="AcmePhone" moveTo="general">
-					Carrier
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">
-					Sounds
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" moveTo="general">
-					Brightness
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29" moveTo="general">
-					Wallpaper
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,29,29,29" moveTo="general">
-					General
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,58,29,29" moveTo="general">
-					Mail, Contacts, Calendars
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,87,29,29" moveTo="general">
-					Phone
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,116,29,29" moveTo="general">
-					Safari
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" moveTo="general">
-					SMS/MMS
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,29,29,29" moveTo="general">
-					iPod
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29" moveTo="general">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">
-					Store
-				</li>
-			</ul>
-		</div>
-
-		<div id="general" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">General</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					About
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2h 40m" moveTo="about">
-					Usage
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Network
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Bluetooth
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Location Services
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="1 Minute" moveTo="about">
-					Auto-Lock
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Passcode Lock
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Restrictions
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Home
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Date & Time					   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Keyboard					   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					International				   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Accessibility
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Reset
-				</li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="General" moveTo="general">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="10">
-					Videos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="96">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2">
-					Applications
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-					Capacity
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-					Available
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-					Version
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_data-handlers.html b/dojox/mobile/tests/test_data-handlers.html
new file mode 100644
index 0000000..7d404d1
--- /dev/null
+++ b/dojox/mobile/tests/test_data-handlers.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Data Handlers</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Button','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/window",
+			"dojo/_base/Deferred",
+			"dijit/registry",
+			"dojox/mobile/ViewController",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/Button"
+		], function(win, Deferred, registry, ViewController){
+			var vc = ViewController.getInstance();
+			onBtn1Clicked = function(e){
+				vc.openExternalView({url:"data/view1.html", transition:"slide"}, win.body());
+			};
+			onBtn2Clicked = function(e){
+				vc.openExternalView({url:"data/view2.html", noTransition:true}, win.body());
+			};
+			onBtn3Clicked = function(e){
+				vc.openExternalView({url:"data/view3.html", transition:"none"}, registry.byId("container").containerNode);
+			};
+			onBtn4Clicked = function(e){
+				vc.openExternalView({url:"data/view4.json", transition:"flip"}, registry.byId("container").containerNode);
+			};
+			onBtn5Clicked = function(e){
+				Deferred.when(vc.openExternalView({url:"data/view5.json", transition:"flip"}, win.body()), function(){
+					console.log("view5 is ready");
+				});
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Data Handlers</h1>
+		<div>
+			Load HTML fragment as a child of body, and perform slide transition<br/>
+			<button id="btn1" data-dojo-type="dojox.mobile.Button" data-dojo-props='onClick:onBtn1Clicked'>Load view1</button>
+		</div>
+		<hr>
+		<div>
+			Load HTML fragment as a child of body, but do not perform transition<br/>
+			Note that this child is automatically hidden by ViewController,<br/>
+			so nothing will be shown.</br>
+			<button id="btn2" data-dojo-type="dojox.mobile.Button" data-dojo-props='onClick:onBtn2Clicked'>Load view2</button>
+		</div>
+		<hr>
+		<div>
+			Load HTML fragment as a child of "container" view, and perform transition without animation<br/>
+			<button id="btn3" data-dojo-type="dojox.mobile.Button" data-dojo-props='onClick:onBtn3Clicked'>Load view3</button>
+		</div>
+		<hr>
+		<div>
+			Load JSON as a child of "container" view, and perform flip transition<br/>
+			<button id="btn4" data-dojo-type="dojox.mobile.Button" data-dojo-props='onClick:onBtn4Clicked'>Load view4</button>
+		</div>
+		<hr>
+		<div>
+			Load JSON as a child of "container" view, and write a console message when the view is ready<br/>
+			<button id="btn5" data-dojo-type="dojox.mobile.Button" data-dojo-props='onClick:onBtn5Clicked'>Load view5</button>
+		</div>
+	</div>
+	<div id="container" data-dojo-type="dojox.mobile.View">
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_domButtons.html b/dojox/mobile/tests/test_domButtons.html
index 664a642..9334745 100644
--- a/dojox/mobile/tests/test_domButtons.html
+++ b/dojox/mobile/tests/test_domButtons.html
@@ -1,85 +1,102 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>domButtons</title>
-		<link href="../themes/common/domButtons.css" rel="stylesheet">
-		<link href="../themes/common/domButtons/DomButtonGrayArrow.css" rel="stylesheet">
-		<link href="../themes/common/domButtons/DomButtonWhiteArrow.css" rel="stylesheet">
-		<link href="../themes/common/domButtons/DomButtonDarkBlueCheck.css" rel="stylesheet">
-		<link href="../themes/common/domButtons/DomButtonWhiteCheck.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>domButtons</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
+	<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonGrayArrow.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonWhiteArrow.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonDarkBlueCheck.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonWhiteCheck.css" rel="stylesheet"/>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/window",
+			"dojo/dom",
+			"dojo/ready",
+			"dojox/mobile/iconUtils",
+			"dojox/mobile",
+			"dojox/mobile/parser",
+			"dojox/mobile/compat"
+		], function(win, dom, ready, iconUtils){
 			function setIconValue(id, val){
-				var txt = dojo.doc.createTextNode(val);
-				dojo.byId(id).firstChild.appendChild(txt);
+				var txt = win.doc.createTextNode(val);
+				dom.byId(id).firstChild.appendChild(txt);
 			}
-			dojo.ready(function(){
+			ready(function(){
 				var nodes = dojo.doc.getElementsByTagName("div");
 				for(var i = 0; i < nodes.length; i++){
 					var div = nodes[i];
 					if(div.nodeType != 1 || div.className.indexOf("mblDomButton") == -1){ continue; }
 					div.style.border = "1px solid red";
-					dojox.mobile.createDomButton(div);
+					iconUtils.createDomButton(div);
 				}
 				setIconValue("btn1", "32");
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;background-color:#C5CCD3;font-family:Helvetica;font-size:12px;">
-		<table border="0">
-			<tr><td><div class="mblDomButtonWhiteUpArrow"></div></td><td>mblDomButtonWhiteUpArrow</td></tr>
-			<tr><td><div class="mblDomButtonWhiteDownArrow"></div></td><td>mblDomButtonWhiteDownArrow</td></tr>
-			<tr><td><div class="mblDomButtonWhitePlus"></div></td><td>mblDomButtonWhitePlus</td></tr>
-			<tr><td><div class="mblDomButtonWhiteSearch"></div></td><td>mblDomButtonWhiteSearch</td></tr>
-			<tr><td><div class="mblDomButtonDarkBlueCheck"></div></td><td>mblDomButtonDarkBlueCheck</td></tr>
-			<tr><td><div class="mblDomButtonWhiteCheck"></div></td><td>mblDomButtonWhiteCheck</td></tr>
-			<tr><td><div class="mblDomButtonGrayArrow"></div></td><td>mblDomButtonGrayArrow</td></tr>
-			<tr><td><div class="mblDomButtonWhiteArrow"></div></td><td>mblDomButtonWhiteArrow</td></tr>
-			<tr><td><div class="mblDomButtonBlueMinus"></div></td><td>mblDomButtonBlueMinus</td></tr>
-			<tr><td><div class="mblDomButtonBluePlus"></div></td><td>mblDomButtonBluePlus</td></tr>
-			<tr><td><div class="mblDomButtonDarkBlueMinus"></div></td><td>mblDomButtonDarkBlueMinus</td></tr>
-			<tr><td><div class="mblDomButtonDarkBluePlus"></div></td><td>mblDomButtonDarkBluePlus</td></tr>
-			<tr><td><div class="mblDomButtonRedMinus"></div></td><td>mblDomButtonRedMinus</td></tr>
-			<tr><td><div class="mblDomButtonRedPlus"></div></td><td>mblDomButtonRedPlus</td></tr>
-			<tr><td><div class="mblDomButtonCheckboxOn"></div></td><td>mblDomButtonCheckboxOn</td></tr>
-			<tr><td><div class="mblDomButtonCheckboxOff"></div></td><td>mblDomButtonCheckboxOff</td></tr>
+		});
+	</script>
+</head>
+<body style="visibility:hidden;background-color:#C5CCD3;font-family:Helvetica;font-size:12px;">
+	<table style="border:none">
+		<tr><td><div class="mblDomButtonWhiteUpArrow"></div></td><td>mblDomButtonWhiteUpArrow</td></tr>
+		<tr><td><div class="mblDomButtonWhiteDownArrow"></div></td><td>mblDomButtonWhiteDownArrow</td></tr>
+		<tr><td><div class="mblDomButtonWhitePlus"></div></td><td>mblDomButtonWhitePlus</td></tr>
+		<tr><td><div class="mblDomButtonWhiteMinus"></div></td><td>mblDomButtonWhiteMinus</td></tr>
+		<tr><td><div class="mblDomButtonWhiteSearch"></div></td><td>mblDomButtonWhiteSearch</td></tr>
+		<tr><td><div class="mblDomButtonDarkBlueCheck"></div></td><td>mblDomButtonDarkBlueCheck</td></tr>
+		<tr><td><div class="mblDomButtonWhiteCheck"></div></td><td>mblDomButtonWhiteCheck</td></tr>
+		<tr><td><div class="mblDomButtonGrayArrow"></div></td><td>mblDomButtonGrayArrow</td></tr>
+		<tr><td><div class="mblDomButtonWhiteArrow"></div></td><td>mblDomButtonWhiteArrow</td></tr>
+		<tr><td><div class="mblDomButtonBlueMinus"></div></td><td>mblDomButtonBlueMinus</td></tr>
+		<tr><td><div class="mblDomButtonBluePlus"></div></td><td>mblDomButtonBluePlus</td></tr>
+		<tr><td><div class="mblDomButtonDarkBlueMinus"></div></td><td>mblDomButtonDarkBlueMinus</td></tr>
+		<tr><td><div class="mblDomButtonDarkBluePlus"></div></td><td>mblDomButtonDarkBluePlus</td></tr>
+		<tr><td><div class="mblDomButtonRedMinus"></div></td><td>mblDomButtonRedMinus</td></tr>
+		<tr><td><div class="mblDomButtonRedPlus"></div></td><td>mblDomButtonRedPlus</td></tr>
+		<tr><td><div class="mblDomButtonCheckboxOn"></div></td><td>mblDomButtonCheckboxOn</td></tr>
+		<tr><td><div class="mblDomButtonCheckboxOff"></div></td><td>mblDomButtonCheckboxOff</td></tr>
+
+		<tr><td><div class="mblDomButtonBlueCircleMinus"></div></td><td>mblDomButtonBlueCircleMinus</td></tr>
+		<tr><td><div class="mblDomButtonBlueCirclePlus"></div></td><td>mblDomButtonBlueCirclePlus</td></tr>
+		<tr><td><div class="mblDomButtonBlueCircleArrow"></div></td><td>mblDomButtonBlueCircleArrow</td></tr>
+
+		<tr><td><div class="mblDomButtonRedCircleMinus"></div></td><td>mblDomButtonRedCircleMinus</td></tr>
+		<tr><td><div class="mblDomButtonRedCirclePlus"></div></td><td>mblDomButtonRedCirclePlus</td></tr>
+		<tr><td><div class="mblDomButtonRedCircleArrow"></div></td><td>mblDomButtonRedCircleArrow</td></tr>
 
-			<tr><td><div class="mblDomButtonBlueCircleMinus"></div></td><td>mblDomButtonBlueCircleMinus</td></tr>
-			<tr><td><div class="mblDomButtonBlueCirclePlus"></div></td><td>mblDomButtonBlueCirclePlus</td></tr>
-			<tr><td><div class="mblDomButtonBlueCircleArrow"></div></td><td>mblDomButtonBlueCircleArrow</td></tr>
+		<tr><td><div class="mblDomButtonGreenCircleMinus"></div></td><td>mblDomButtonGreenCircleMinus</td></tr>
+		<tr><td><div class="mblDomButtonGreenCirclePlus"></div></td><td>mblDomButtonGreenCirclePlus</td></tr>
+		<tr><td><div class="mblDomButtonGreenCircleArrow"></div></td><td>mblDomButtonGreenCircleArrow</td></tr>
+		<tr><td><div class="mblDomButtonBlackCircleCross"></div></td><td>mblDomButtonBlackCircleCross</td></tr>
 
-			<tr><td><div class="mblDomButtonRedCircleMinus"></div></td><td>mblDomButtonRedCircleMinus</td></tr>
-			<tr><td><div class="mblDomButtonRedCirclePlus"></div></td><td>mblDomButtonRedCirclePlus</td></tr>
-			<tr><td><div class="mblDomButtonRedCircleArrow"></div></td><td>mblDomButtonRedCircleArrow</td></tr>
+		<tr><td><div id="btn1" class="mblDomButtonGrayRoundRect"></div></td><td>mblDomButtonGrayRoundRect</td></tr>
 
-			<tr><td><div class="mblDomButtonGreenCircleMinus"></div></td><td>mblDomButtonGreenCircleMinus</td></tr>
-			<tr><td><div class="mblDomButtonGreenCirclePlus"></div></td><td>mblDomButtonGreenCirclePlus</td></tr>
-			<tr><td><div class="mblDomButtonGreenCircleArrow"></div></td><td>mblDomButtonGreenCircleArrow</td></tr>
-			<tr><td><div class="mblDomButtonBlackCircleCross"></div></td><td>mblDomButtonBlackCircleCross</td></tr>
 
-			<tr><td><div id="btn1" class="mblDomButtonGrayRoundRect"></div></td><td>mblDomButtonGrayRoundRect</td></tr>
+		<tr><td><div class="mblDomButtonSilverCircleDownArrow"></div></td><td>mblDomButtonSilverCircleDownArrow</td></tr>
+		<tr><td><div class="mblDomButtonSilverCircleGreenButton"></div></td><td>mblDomButtonSilverCircleGreenButton</td></tr>
+		<tr><td><div class="mblDomButtonSilverCircleGrayButton"></div></td><td>mblDomButtonSilverCircleGrayButton</td></tr>
+		<tr><td><div class="mblDomButtonSilverCircleOrangeButton"></div></td><td>mblDomButtonSilverCircleOrangeButton</td></tr>
+		<tr><td><div class="mblDomButtonSilverCircleGreenPlus"></div></td><td>mblDomButtonSilverCircleGreenPlus</td></tr>
+		<tr><td><div class="mblDomButtonSilverCircleRedCross"></div></td><td>mblDomButtonSilverCircleRedCross</td></tr>
 
+		<tr><td><div class="mblDomButtonBlueBall"></div></td><td>mblDomButtonBlueBall</td></tr>
+		<tr><td><div class="mblDomButtonGreenBall"></div></td><td>mblDomButtonGreenBall</td></tr>
+		<tr><td><div class="mblDomButtonOrangeBall"></div></td><td>mblDomButtonOrangeBall</td></tr>
+		<tr><td><div class="mblDomButtonRedBall"></div></td><td>mblDomButtonRedBall</td></tr>
 
-			<tr><td><div class="mblDomButtonSilverCircleDownArrow"></div></td><td>mblDomButtonSilverCircleDownArrow</td></tr>
-			<tr><td><div class="mblDomButtonSilverCircleGreenButton"></div></td><td>mblDomButtonSilverCircleGreenButton</td></tr>
-			<tr><td><div class="mblDomButtonSilverCircleGrayButton"></div></td><td>mblDomButtonSilverCircleGrayButton</td></tr>
-			<tr><td><div class="mblDomButtonSilverCircleOrangeButton"></div></td><td>mblDomButtonSilverCircleOrangeButton</td></tr>
-			<tr><td><div class="mblDomButtonSilverCircleGreenPlus"></div></td><td>mblDomButtonSilverCircleGreenPlus</td></tr>
-			<tr><td><div class="mblDomButtonSilverCircleRedCross"></div></td><td>mblDomButtonSilverCircleRedCross</td></tr>
+		<tr><td><div class="mblDomButtonYellowStar"></div></td><td>mblDomButtonYellowStar</td></tr>
+		<tr><td><div class="mblDomButtonGrayStar"></div></td><td>mblDomButtonGrayStar</td></tr>
+		<tr><td><div class="mblDomButtonGrayCross"></div></td><td>mblDomButtonGrayCross</td></tr>
 
-			<tr><td><div class="mblDomButtonBlueBall"></div></td><td>mblDomButtonBlueBall</td></tr>
-			<tr><td><div class="mblDomButtonGreenBall"></div></td><td>mblDomButtonGreenBall</td></tr>
-			<tr><td><div class="mblDomButtonOrangeBall"></div></td><td>mblDomButtonOrangeBall</td></tr>
-			<tr><td><div class="mblDomButtonRedBall"></div></td><td>mblDomButtonRedBall</td></tr>
+		<tr><td><div class="mblDomButtonGrayKnob"></div></td><td>mblDomButtonGrayKnob</td></tr>
 
-			<tr><td><div class="mblDomButtonYellowStar"></div></td><td>mblDomButtonYellowStar</td></tr>
-			<tr><td><div class="mblDomButtonGrayStar"></div></td><td>mblDomButtonGrayStar</td></tr>
-		</table>
-	</body>
+		<tr><td><div class="mblDomButtonGrayPlus"></div></td><td>mblDomButtonGrayPlus</td></tr>
+		<tr><td><div class="mblDomButtonGrayMinus"></div></td><td>mblDomButtonGrayMinus</td></tr>
+	</table>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_domButtons16.html b/dojox/mobile/tests/test_domButtons16.html
new file mode 100644
index 0000000..6f6c454
--- /dev/null
+++ b/dojox/mobile/tests/test_domButtons16.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>domButtons16</title>
+
+	<link href="../themes/common/domButtons/DomButtonBlackRightArrow16.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonBlackDownArrow16.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonBlackLeftArrow16.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonBlackUpArrow16.css" rel="stylesheet"/>
+
+	<link href="../themes/common/domButtons/DomButtonWhiteRightArrow16.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonWhiteDownArrow16.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonWhiteLeftArrow16.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonWhiteUpArrow16.css" rel="stylesheet"/>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/window",
+			"dojo/ready",
+			"dojox/mobile/iconUtils",
+			"dojox/mobile/parser",
+			"dojox/mobile/compat"
+		], function(win, ready, iconUtils){
+			ready(function(){
+				var nodes = win.doc.getElementsByTagName("div");
+				for(var i = 0; i < nodes.length; i++){
+					var div = nodes[i];
+					if(div.nodeType != 1 || div.className.indexOf("mblDomButton") == -1){ continue; }
+					div.style.border = "1px solid red";
+					iconUtils.createDomButton(div);
+				}
+			});
+		});
+	</script>
+</head>
+<body style="background-color:#C5CCD3;font-family:Helvetica;font-size:12px;">
+	<table style="border:none">
+		<tr><td><div class="mblDomButtonBlackRightArrow16"></div></td><td>mblDomButtonBlackRightArrow16</td></tr>
+		<tr><td><div class="mblDomButtonBlackDownArrow16"></div></td><td>mblDomButtonBlackDownArrow16</td></tr>
+		<tr><td><div class="mblDomButtonBlackLeftArrow16"></div></td><td>mblDomButtonBlackLeftArrow16</td></tr>
+		<tr><td><div class="mblDomButtonBlackUpArrow16"></div></td><td>mblDomButtonBlackUpArrow16</td></tr>
+
+		<tr><td><div class="mblDomButtonWhiteRightArrow16"></div></td><td>mblDomButtonWhiteRightArrow16</td></tr>
+		<tr><td><div class="mblDomButtonWhiteDownArrow16"></div></td><td>mblDomButtonWhiteDownArrow16</td></tr>
+		<tr><td><div class="mblDomButtonWhiteLeftArrow16"></div></td><td>mblDomButtonWhiteLeftArrow16</td></tr>
+		<tr><td><div class="mblDomButtonWhiteUpArrow16"></div></td><td>mblDomButtonWhiteUpArrow16</td></tr>
+	</table>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_domButtonsBadge.html b/dojox/mobile/tests/test_domButtonsBadge.html
new file mode 100644
index 0000000..bab22fd
--- /dev/null
+++ b/dojox/mobile/tests/test_domButtonsBadge.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>domButtonsBadge</title>
+
+	<link href="../themes/common/domButtons/DomButtonRedBadge.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonBlueBadge.css" rel="stylesheet"/>
+	<link href="../themes/common/domButtons/DomButtonGreenBadge.css" rel="stylesheet"/>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/window",
+			"dojo/dom",
+			"dojo/ready",
+			"dojox/mobile/iconUtils",
+			"dojox/mobile",
+			"dojox/mobile/parser",
+			"dojox/mobile/compat"
+		], function(win, dom, ready, iconUtils){
+			function setIconValue(id, val){
+				var txt = win.doc.createTextNode(val);
+				dom.byId(id).firstChild.appendChild(txt);
+			}
+			ready(function(){
+				var nodes = win.doc.getElementsByTagName("div");
+				for(var i = 0, c = 0; i < nodes.length; i++){
+					var div = nodes[i];
+					if(div.nodeType != 1 || div.className.indexOf("mblDomButton") == -1){ continue; }
+					div.style.border = "1px solid red";
+					iconUtils.createDomButton(div);
+					setIconValue("btn"+c++, "15");
+				}
+			});
+		});
+	</script>
+</head>
+<body style="background-color:#C5CCD3;font-family:Helvetica;font-size:12px;">
+	<table style="border:none">
+		<tr><td><div id="btn0" class="mblDomButtonRedBadge"></div></td><td>mblDomButtonRedBadge</td></tr>
+		<tr><td><div id="btn1" class="mblDomButtonBlueBadge"></div></td><td>mblDomButtonBlueBadge</td></tr>
+		<tr><td><div id="btn2" class="mblDomButtonGreenBadge"></div></td><td>mblDomButtonGreenBadge</td></tr>
+		<tr><td><div id="btn3" class="mblDomButtonRedBadge" style="font-size:11px;color:pink;"></div></td><td>mblDomButtonRedBadge (small)</td></tr>
+		<tr><td><div id="btn4" class="mblDomButtonBlueBadge" style="font-size:11px;color:pink;"></div></td><td>mblDomButtonBlueBadge (small)</td></tr>
+		<tr><td><div id="btn5" class="mblDomButtonGreenBadge" style="font-size:11px;color:pink;"></div></td><td>mblDomButtonGreenBadge (small)</td></tr>
+	</table>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_dynamic-ScrollableView-ah-af.html b/dojox/mobile/tests/test_dynamic-ScrollableView-ah-af.html
index 94a53e0..2bb6c49 100644
--- a/dojox/mobile/tests/test_dynamic-ScrollableView-ah-af.html
+++ b/dojox/mobile/tests/test_dynamic-ScrollableView-ah-af.html
@@ -1,76 +1,77 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Dynamic ScrollableView (app header / app footer)</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Dynamic ScrollableView (app header / app footer)</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-			dojo.ready(function(){
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dojox/mobile/Heading",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/RoundRectCategory",
+			"dojox/mobile/RoundRectList",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/RoundRect",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(ready, Heading, ScrollableView, RoundRectCategory, RoundRectList, ListItem, RoundRect){
+			ready(function(){
 				// ==== App Header has to be at the top position ====
-				var heading1 = new dojox.mobile.Heading({
+				var heading1 = new Heading({
 					label: "Fixed App Header",
 					fixed: "top"
-				});
-				dojo.body().appendChild(heading1.domNode);
-
+				}, "heading1");
+				heading1.startup();
 
 				// ==== view1 ====
-				var view1 = new dojox.mobile.ScrollableView({
-					id: "foo",
-					selected: true
-				});
-				dojo.body().appendChild(view1.domNode);
-				view1.startup();
+				var view1 = new ScrollableView(null, "view1");
 
-				var categ1 = new dojox.mobile.RoundRectCategory({
+				var categ1 = new RoundRectCategory({
 					label: "Documents"
 				});
-				view1.addChild(categ1);
+				categ1.placeAt(view1.containerNode);
 
-				var list1 = new dojox.mobile.RoundRectList();
-				view1.addChild(list1);
+				var list1 = new RoundRectList();
+				list1.placeAt(view1.containerNode);
 
 				var counter = 4;
 				for(var i = 1; i <= 3; i++){
-					var item1 = new dojox.mobile.ListItem({
+					var item1 = new ListItem({
 						icon: "images/i-icon-"+i+".png",
 						label: "Document 000"+counter,
-						moveTo: "bar"
+						moveTo: "view2"
 					});
 					list1.addChild(item1);
 					counter++;
 				}
 
+				view1.startup();
+
 				// ==== view2 ====
-				var view2 = new dojox.mobile.ScrollableView({
-					id: "bar"
-				});
-				dojo.body().appendChild(view2.domNode);
-				view2.startup();
+				var view2 = new ScrollableView(null, "view2");
 
-				var rect1 = new dojox.mobile.RoundRect();
+				var rect1 = new RoundRect();
 				rect1.containerNode.innerHTML = "Go Back";
-				view2.addChild(rect1);
+				rect1.placeAt(view2.containerNode);
 				rect1.connect(rect1.domNode, "onclick", function(){
-					view2.performTransition("foo", -1, "slide");
+					view2.performTransition("view1", -1, "slide");
 				});
 
+				view2.startup();
 
 				// ==== App Footer has to be at the last position ====
-				var heading2 = new dojox.mobile.Heading({
+				var heading2 = new Heading({
 					label: "Fixed App Footer",
 					fixed: "bottom"
-				});
-				dojo.body().appendChild(heading2.domNode);
-
+				}, "heading2");
+				heading2.startup();
 
 				// ==== Initialize each view when the dom is ready ====
 				view1.findAppBars();
@@ -78,8 +79,13 @@
 				view2.findAppBars();
 				view2.resize();
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-	</body>
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="heading1"></div>
+	<div id="view1"></div>
+	<div id="view2"></div>
+	<div id="heading2"></div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_dynamic-ScrollableView-vh-vf.html b/dojox/mobile/tests/test_dynamic-ScrollableView-vh-vf.html
index f6fb30c..174bfd7 100644
--- a/dojox/mobile/tests/test_dynamic-ScrollableView-vh-vf.html
+++ b/dojox/mobile/tests/test_dynamic-ScrollableView-vh-vf.html
@@ -1,75 +1,81 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Dynamic ScrollableView (view header / view footer)</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Dynamic ScrollableView (view header / view footer)</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-			dojo.ready(function(){
+	<script type="text/javascript">
+		require([
+			"dojo/ready",
+			"dojox/mobile/Heading",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/RoundRectCategory",
+			"dojox/mobile/RoundRectList",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/RoundRect",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(ready, Heading, ScrollableView, RoundRectCategory, RoundRectList, ListItem, RoundRect){
+			ready(function(){
 				// ==== view1 ====
-				var view1 = new dojox.mobile.ScrollableView({
-					id: "foo",
-					selected: true
-				});
-				dojo.body().appendChild(view1.domNode);
-				view1.startup();
+				var view1 = new ScrollableView(null, "view1");
 
-				var heading2 = new dojox.mobile.Heading({
+				var heading2 = new Heading({
 					label: "Fixed View Footer",
 					fixed: "bottom"
 				});
-				view1.addChild(heading2);
+				view1.addFixedBar(heading2);
 
-				var categ1 = new dojox.mobile.RoundRectCategory({
+				var categ1 = new RoundRectCategory({
 					label: "Documents"
 				});
-				view1.addChild(categ1);
+				categ1.placeAt(view1.containerNode);
 
-				var list1 = new dojox.mobile.RoundRectList();
-				view1.addChild(list1);
+				var list1 = new RoundRectList();
+				list1.placeAt(view1.containerNode);
 
 				var counter = 4;
 				for(var i = 1; i <= 3; i++){
-					var item1 = new dojox.mobile.ListItem({
+					var item1 = new ListItem({
 						icon: "images/i-icon-"+i+".png",
 						label: "Document 000"+counter,
-						moveTo: "bar"
+						moveTo: "view2"
 					});
 					list1.addChild(item1);
 					counter++;
 				}
 
-				var heading1 = new dojox.mobile.Heading({
+				var heading1 = new Heading({
 					label: "Fixed View Header",
 					fixed: "top"
 				});
-				view1.addChild(heading1);
+				view1.addFixedBar(heading1);
 
+				view1.startup();
 
 				// ==== view2 ====
-				var view2 = new dojox.mobile.View({
-					id: "bar"
-				});
-				dojo.body().appendChild(view2.domNode);
-				view2.startup();
+				var view2 = new ScrollableView(null, "view2");
 
-				var rect1 = new dojox.mobile.RoundRect();
+				var rect1 = new RoundRect();
 				rect1.containerNode.innerHTML = "Go Back";
-				view2.addChild(rect1);
+				rect1.placeAt(view2.containerNode);
 				rect1.connect(rect1.domNode, "onclick", function(){
-					view2.performTransition("foo", -1, "slide");
+					view2.performTransition("view1", -1, "slide");
 				});
+
+				view2.startup();
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-	</body>
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1"></div>
+	<div id="view2"></div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_dynamic-icons.html b/dojox/mobile/tests/test_dynamic-icons.html
index 5faee56..723bc80 100644
--- a/dojox/mobile/tests/test_dynamic-icons.html
+++ b/dojox/mobile/tests/test_dynamic-icons.html
@@ -1,55 +1,61 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Dynamic Icons</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/IconContainer.css" rel="stylesheet">
-		<link href="../themes/iphone/Button.css" rel="stylesheet">
-		<link href="../../../dijit/themes/tundra/tundra.css" rel="stylesheet">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Dynamic Icons</title>
 
-		<style>
-			.box {
-				border: 1px solid #A7C0E0;
-				width: 300px;
-				height: 250px;
-				background-image: url(images/widget-bg.png);
-				background-repeat: no-repeat;
-				background-color: white;
-			}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+	<link href="../../../dijit/themes/tundra/tundra.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Button','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: false, parseOnLoad: true"></script>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.IconContainer");
-			dojo.require("dojox.mobile.Button");
-
-			dojo.ready(function(){
-				var btnWidget = dijit.byId("btn1");
-				dojo.connect(btnWidget.domNode, "onclick", onBtnClicked);
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/IconItem",
+			"dojox/mobile/IconContainer",
+			"dojox/mobile/Button",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, ready, registry, IconItem){
+			ready(function(){
+				var btnWidget = registry.byId("btn1");
+				connect.connect(btnWidget.domNode, "onclick", onBtnClicked);
 				function onBtnClicked(e){
-					var iconContainerWidget = dijit.byId("ic1");
-					var itemWidget = new dojox.mobile.IconItem({
+					var iconContainerWidget = registry.byId("ic1");
+					var itemWidget = new IconItem({
 						icon: "images/icon-1.png",
 						label: "new icon",
 						lazy: true
 					});
-					itemWidget.containerNode.innerHTML = "<div dojoType='dijit._Calendar'></div>";
+					itemWidget.set("content", "<div data-dojo-type='dijit._Calendar'></div>");
 					iconContainerWidget.addChild(itemWidget);
 				}
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;" class="tundra">
-		<div id="myhome" dojoType="dojox.mobile.View" selected="true">
-			<ul id="ic1" dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="test1" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-			</ul>
-			<button id="btn1" dojoType="dojox.mobile.Button" class="mblBlueButton" style="width:80px;margin-left:10px">More...</button>
-		</div>
-	</body>
+		});
+	</script>
+
+	<style>
+		.box {
+			border: 1px solid #A7C0E0;
+			width: 300px;
+			height: 250px;
+			background-image: url(images/widget-bg.png);
+			background-repeat: no-repeat;
+			background-color: white;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;" class="tundra">
+	<div id="myhome" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<ul id="ic1" data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"test1", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+		</ul>
+		<button id="btn1" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:80px;margin-left:10px">More...</button>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_dynamic-items.html b/dojox/mobile/tests/test_dynamic-items.html
old mode 100755
new mode 100644
index dde7657..777a218
--- a/dojox/mobile/tests/test_dynamic-items.html
+++ b/dojox/mobile/tests/test_dynamic-items.html
@@ -1,31 +1,38 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Dynamic Items</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Dynamic Items</title>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojo.hash");
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.Button");
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','Button','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: false, parseOnLoad: true"></script>
 
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/_base/declare",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/ProgressIndicator",
+			"dojox/mobile/View",
+			"dojox/mobile/parser",
+			"dojox/mobile/Button",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, declare, ready, registry, ListItem, ProgressIndicator, View, parser){
 			var counter = 4;
-			dojo.ready(function(){
-				var btnWidget = dijit.byId("btn1");
-				dojo.connect(btnWidget.domNode, "onclick", onBtnClicked);
+			ready(function(){
+				var btnWidget = registry.byId("btn1");
+				connect.connect(btnWidget.domNode, "onclick", onBtnClicked);
 				function onBtnClicked(e){
-					var listWidget = dijit.byId("list1");
+					var listWidget = registry.byId("list1");
 					for(var i = 1; i <= 3; i++){
-						var itemWidget = new dojox.mobile.ListItem({
+						var itemWidget = new ListItem({
 							icon: "images/i-icon-"+i+".png",
-							moveTo: "#bar&myParam=000"+counter,
+							moveTo: "#view2&myParam=000"+counter,
 							label: "Document 000"+counter
 						});
 						listWidget.addChild(itemWidget);
@@ -33,7 +40,6 @@
 					}
 				}
 			});
-
 			function loadPage(moveTo){
 				if(!(moveTo.match(/#(\w+)/))){ return; }
 				moveTo.match(/#(\w+)(.*)/);
@@ -42,16 +48,19 @@
 				if(!param){ return; }
 				var container = dojo.byId(id);
 				container.innerHTML = "";
-				var prog = dojox.mobile.ProgressIndicator.getInstance();
+				var prog = ProgressIndicator.getInstance();
 				container.appendChild(prog.domNode);
 				prog.start();
 				setTimeout(function(){ // network latency simulation
 					prog.stop();
-					container.innerHTML = '<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="#home">'+param+'</h1>\n'+param;
-					dojox.mobile.parser.parse(container);
+					container.innerHTML = '<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props=\'back:"Home", moveTo:"#home"\'>'+param+'</h1>\n'+param;
+					parser.parse(container);
 				}, 5000);
 			}
-			dojo.declare("dojox.mobile.ViewEx",dojox.mobile.View,{
+			dojox.mobile.ViewEx = declare(
+				"dojox.mobile.ViewEx",
+				View,
+			{
 				onStartView: function(){
 					loadPage(location.hash);
 				},
@@ -59,26 +68,27 @@
 					loadPage("#"+moveTo);
 				}
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="home" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Dynamic Items</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">External Documents</h2>
-			<ul id="list1" dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="#bar&myParam=0001">
-					Document 0001
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="#bar&myParam=0002">
-					Document 0002
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="#bar&myParam=0003">
-					Document 0003
-				</li>
-			</ul>
-			<button id="btn1" dojoType="dojox.mobile.Button" class="mblBlueButton" style="width:80px;margin-left:10px">More...</button>
-		</div>
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Dynamic Items</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">External Documents</h2>
+		<ul id="list1" data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#view2&myParam=0001"'>
+				Document 0001
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#view2&myParam=0002"'>
+				Document 0002
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#view2&myParam=0003"'>
+				Document 0003
+			</li>
+		</ul>
+		<button id="btn1" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" style="width:80px;margin-left:10px">More...</button>
+	</div>
 
-		<div id="bar" dojoType="dojox.mobile.ViewEx"></div>
-	</body>
+	<div id="view2" data-dojo-type="dojox.mobile.ViewEx"></div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_dynamic-view.html b/dojox/mobile/tests/test_dynamic-view.html
deleted file mode 100644
index c619e16..0000000
--- a/dojox/mobile/tests/test_dynamic-view.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Dynamic View</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-
-			dojo.ready(function(){
-				var view1 = new dojox.mobile.View({
-					id: "foo",
-					selected: true
-				}, "view1");
-				view1.startup();
-
-				var heading1 = new dojox.mobile.Heading({
-					label: "Dynamic View"
-				});
-				view1.addChild(heading1);
-
-				var categ1 = new dojox.mobile.RoundRectCategory({
-					label: "Documents"
-				});
-				view1.addChild(categ1);
-
-				var list1 = new dojox.mobile.RoundRectList();
-				view1.addChild(list1);
-
-				var counter = 4;
-				for(var i = 1; i <= 3; i++){
-					var item1 = new dojox.mobile.ListItem({
-						icon: "images/i-icon-"+i+".png",
-						label: "Document 000"+counter
-					});
-					list1.addChild(item1);
-					counter++;
-				}
-			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1"></div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_grouped-scrollable-views.html b/dojox/mobile/tests/test_grouped-scrollable-views.html
index ed25f85..5daab47 100644
--- a/dojox/mobile/tests/test_grouped-scrollable-views.html
+++ b/dojox/mobile/tests/test_grouped-scrollable-views.html
@@ -1,62 +1,66 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Grouped ScrollableViews</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Grouped ScrollableViews</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<div id="view11" dojoType="dojox.mobile.ScrollableView" selected="true">
-				<h1 dojoType="dojox.mobile.Heading" fixed="top">View 1-1</h1>
-				<h2 dojoType="dojox.mobile.RoundRectCategory">Grouped View Example</h2>
-				<div dojoType="dojox.mobile.RoundRect" shadow="true">
-					<pre style="font-size:12px">
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<div id="view11" data-dojo-type="dojox.mobile.ScrollableView">
+			<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View 1-1</h1>
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Grouped View Example</h2>
+			<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+				<pre style="font-size:12px">
  - View 1 (container)
      |
      *-- View 1-1
          View 1-2
  - View 2</pre>
-				</div>
-				<ul dojoType="dojox.mobile.RoundRectList">
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view12" transition="slide">
-						View 1-2
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="slide">
-						View 2
-					</li>
-				</ul>
-			</div>
-
-			<div id="view12" dojoType="dojox.mobile.ScrollableView">
-				<h1 dojoType="dojox.mobile.Heading" fixed="top">View 1-2</h1>
-				<ul dojoType="dojox.mobile.RoundRectList">
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view11" transition="slide" transitionDir="-1">
-						View 1-1
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="slide">
-						View 2
-					</li>
-				</ul>
 			</div>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view12", transition:"slide"'>
+					View 1-2
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"slide"'>
+					View 2
+				</li>
+			</ul>
 		</div>
 
-		<div id="view2" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">View 2</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view1" transition="slide" transitionDir="-1">
-					View 1
+		<div id="view12" data-dojo-type="dojox.mobile.ScrollableView">
+			<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View 1-2</h1>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view11", transition:"slide", transitionDir:"-1"'>
+					View 1-1
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"slide"'>
+					View 2
 				</li>
 			</ul>
 		</div>
-	</body>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>View 2</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view1", transition:"slide", transitionDir:"-1"'>
+				View 1
+			</li>
+		</ul>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_grouped-views.html b/dojox/mobile/tests/test_grouped-views.html
index 9aee6a1..022e7b5 100644
--- a/dojox/mobile/tests/test_grouped-views.html
+++ b/dojox/mobile/tests/test_grouped-views.html
@@ -1,61 +1,65 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Grouped Views</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Grouped Views</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<div id="view11" dojoType="dojox.mobile.View" selected="true">
-				<h1 dojoType="dojox.mobile.Heading">View 1-1</h1>
-				<h2 dojoType="dojox.mobile.RoundRectCategory">Grouped View Example</h2>
-				<div dojoType="dojox.mobile.RoundRect" shadow="true">
-					<pre style="font-size:12px">
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<div id="view11" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+			<h1 data-dojo-type="dojox.mobile.Heading">View 1-1</h1>
+			<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Grouped View Example</h2>
+			<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+				<pre style="font-size:12px">
  - View 1 (container)
      |
      *-- View 1-1
          View 1-2
  - View 2</pre>
-				</div>
-				<ul dojoType="dojox.mobile.RoundRectList">
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view12" transition="slide">
-						View 1-2
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="slide">
-						View 2
-					</li>
-				</ul>
-			</div>
-
-			<div id="view12" dojoType="dojox.mobile.View">
-				<h1 dojoType="dojox.mobile.Heading">View 1-2</h1>
-				<ul dojoType="dojox.mobile.RoundRectList">
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view11" transition="slide" transitionDir="-1">
-						View 1-1
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="slide">
-						View 2
-					</li>
-				</ul>
 			</div>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view12", transition:"slide"'>
+					View 1-2
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"slide"'>
+					View 2
+				</li>
+			</ul>
 		</div>
 
-		<div id="view2" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading">View 2</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view1" transition="slide" transitionDir="-1">
-					View 1
+		<div id="view12" data-dojo-type="dojox.mobile.View">
+			<h1 data-dojo-type="dojox.mobile.Heading">View 1-2</h1>
+			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view11", transition:"slide", transitionDir:"-1"'>
+					View 1-1
+				</li>
+				<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"slide"'>
+					View 2
 				</li>
 			</ul>
 		</div>
-	</body>
+	</div>
+
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">View 2</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view1", transition:"slide", transitionDir:"-1"'>
+				View 1
+			</li>
+		</ul>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_hash-parameter.html b/dojox/mobile/tests/test_hash-parameter.html
old mode 100755
new mode 100644
index b973f9a..d550cbd
--- a/dojox/mobile/tests/test_hash-parameter.html
+++ b/dojox/mobile/tests/test_hash-parameter.html
@@ -1,38 +1,35 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Transition Parameter</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		</style>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Transition Parameter</title>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.hash");
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/dom",
+			"dojox/mobile/parser",
+			"dojo/hash",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(declare, dom, parser){
 			function loadPage(moveTo){
 				if(!(moveTo.match(/#(\w+)/))){ return; }
 				moveTo.match(/#(\w+)(.*)/);
 				var id = RegExp.$1;
 				var param = RegExp.$2;
 				if(!param){ return; }
-				var container = dojo.byId(id);
+				var container = dom.byId(id);
 				// You may want to dynamically load page contents here
-				container.innerHTML = '<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="#home">'+param+'</h1>\n'+param;
-				dojox.mobile.parser.parse(container);
+				container.innerHTML = '<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props=\'back:"Home", moveTo:"#home"\'>'+param+'</h1>\n'+param;
+				parser.parse(container);
 			}
-			dojo.declare(
+			dojox.mobile.ViewEx = declare(
 				"dojox.mobile.ViewEx",
 				dojox.mobile.View,
 			{
@@ -43,28 +40,37 @@
 					loadPage("#"+moveTo);
 				}
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="home" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Animations</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="#bar&myParam=0001">
-					Document 0001
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="#bar&myParam=0002">
-					Document 0002
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="#bar&myParam=0003">
-					Document 0003
-				</li>
-			</ul>
-			<div dojoType="dojox.mobile.RoundRect">
-				After you move to other views, you should also be able to navigate through the views with browser's back and forward buttons. Also, views should be bookmarkable. Note that you can pass parameters (e.g. &myParam=001) to a destination view.
-			</div>
+		});
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="home" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"#view2&myParam=0001"'>
+				Document 0001
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"#view2&myParam=0002"'>
+				Document 0002
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"#view2&myParam=0003"'>
+				Document 0003
+			</li>
+		</ul>
+		<div data-dojo-type="dojox.mobile.RoundRect">
+			After you move to other views, you should also be able to navigate through the views with browser's back and forward buttons. Also, views should be bookmarkable. Note that you can pass parameters (e.g. &myParam=001) to a destination view.
 		</div>
+	</div>
 
-		<div id="bar" dojoType="dojox.mobile.ViewEx">bar</div>
-	</body>
+	<div id="view2" data-dojo-type="dojox.mobile.ViewEx">view2</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_html-form-controls.html b/dojox/mobile/tests/test_html-form-controls.html
index a596854..c327f41 100644
--- a/dojox/mobile/tests/test_html-form-controls.html
+++ b/dojox/mobile/tests/test_html-form-controls.html
@@ -1,67 +1,79 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>HTML Form Controls</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>HTML Form Controls</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.ScrollableView");
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading">HTML</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">HTML Form Controls</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem">
-					<button style="line-height:normal">Button Element</button>
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					<input type="button" value="Input Button">
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					<input type="submit" value="Submit Button">
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					<input type="reset" value="Reset Button">
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					<input type="text"> text
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					<input type="password"> password
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					<input type="checkbox"> checkbox
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					<input type="radio" name="chk1" checked="checked">
-					<input type="radio" name="chk1"> radio
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					<select>
-						<option>Option 1</option>
-						<option>Option 2</option>
-						<option>Option 3</option>
-						<option>Option 4</option>
-						<option>Option 5</option>
-						<option>Option 6</option>
-					</select>
-				</li>
-			</ul>
-			<textarea style="margin-left:10px"></textarea>
-		</div>
-	</body>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/window",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		], function(win){
+			// disable synthetic clicks from dojo/touch
+			win.doc.dojoClick = false; 
+		});
+	</script>
+
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	button,input{
+		-webkit-tap-highlight-color: rgba(0,0,0,0.3);
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading">HTML</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">HTML Form Controls</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<button style="line-height:normal">Button Element</button>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<input type="button" value="Input Button">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<input type="submit" value="Submit Button">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<input type="reset" value="Reset Button">
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<input type="text"> text
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<input type="password"> password
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<input type="checkbox"> checkbox
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<input type="radio" name="chk1" checked="checked">
+				<input type="radio" name="chk1"> radio
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem">
+				<select>
+					<option>Option 1</option>
+					<option>Option 2</option>
+					<option>Option 3</option>
+					<option>Option 4</option>
+					<option>Option 5</option>
+					<option>Option 6</option>
+				</select>
+			</li>
+		</ul>
+		<textarea style="margin-left:10px"></textarea>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_html-inputs.html b/dojox/mobile/tests/test_html-inputs.html
index 8a569a0..2d1554d 100644
--- a/dojox/mobile/tests/test_html-inputs.html
+++ b/dojox/mobile/tests/test_html-inputs.html
@@ -1,55 +1,59 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>many input fields</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>many input fields</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile.compat");
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojoType="dojox.mobile.View">
-			<div dojoType="dojox.mobile.ScrollableView">
-				<input type="url" value="1"><br>
-				<input type="url" value="2"><br>
-				<input type="url" value="3"><br>
-				<input type="url" value="4"><br>
-				<input type="url" value="5"><br>
-				<input type="url" value="6"><br>
-				<input type="url" value="7"><br>
-				<input type="url" value="8"><br>
-				<input type="url" value="9"><br>
-				<input type="url" value="10"><br>
-				<input type="url" value="11"><br>
-				<input type="url" value="12"><br>
-				<input type="url" value="13"><br>
-				<input type="url" value="14"><br>
-				<input type="url" value="15"><br>
-				<input type="url" value="16"><br>
-				<input type="url" value="17"><br>
-				<input type="url" value="18"><br>
-				<input type="url" value="19"><br>
-				<input type="url" value="20"><br>
-				<input type="url" value="21"><br>
-				<input type="url" value="22"><br>
-				<input type="url" value="23"><br>
-				<input type="url" value="24"><br>
-				<input type="url" value="25"><br>
-				<input type="url" value="26"><br>
-				<input type="url" value="27"><br>
-				<input type="url" value="28"><br>
-				<input type="url" value="29"><br>
-				<input type="url" value="30"><br>
-				<input type="url" value="31"><br>
-				<input type="url" value="32"><br>
-			</div>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.View">
+		<div data-dojo-type="dojox.mobile.ScrollableView">
+			<input type="text" value="1"><br>
+			<input type="text" value="2"><br>
+			<input type="text" value="3"><br>
+			<input type="text" value="4"><br>
+			<input type="text" value="5"><br>
+			<input type="text" value="6"><br>
+			<input type="text" value="7"><br>
+			<input type="text" value="8"><br>
+			<input type="text" value="9"><br>
+			<input type="text" value="10"><br>
+			<input type="text" value="11"><br>
+			<input type="text" value="12"><br>
+			<input type="text" value="13"><br>
+			<input type="text" value="14"><br>
+			<input type="text" value="15"><br>
+			<input type="text" value="16"><br>
+			<input type="text" value="17"><br>
+			<input type="text" value="18"><br>
+			<input type="text" value="19"><br>
+			<input type="text" value="20"><br>
+			<input type="text" value="21"><br>
+			<input type="text" value="22"><br>
+			<input type="text" value="23"><br>
+			<input type="text" value="24"><br>
+			<input type="text" value="25"><br>
+			<input type="text" value="26"><br>
+			<input type="text" value="27"><br>
+			<input type="text" value="28"><br>
+			<input type="text" value="29"><br>
+			<input type="text" value="30"><br>
+			<input type="text" value="31"><br>
+			<input type="text" value="32"><br>
 		</div>
-	</body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_i18n-sync.html b/dojox/mobile/tests/test_i18n-sync.html
new file mode 100644
index 0000000..b08d256
--- /dev/null
+++ b/dojox/mobile/tests/test_i18n-sync.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Settings</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: false, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/window",
+			"dojo/dom",
+			"dijit/registry",
+			"dojox/mobile/i18n",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/TabBar",
+			"dojox/mobile/IconContainer"
+		], function(win, dom, registry, i18n){
+			var lang = location.search.match(/lang=(\w*)/) ? RegExp.$1 : null;
+			var bundle = i18n.load("dojox.mobile.tests", "sample", lang);
+			changeLocale = function(){
+				win.doc.forms[0].submit();
+			}
+			dojo.ready(function(){
+				dom.byId("sel").value = lang;
+				registry.byId("item1").set("label", bundle["MINUTES"].replace("%1", "30"));
+			});
+		});
+	</script>
+	<style>
+	#item2 .mblListItemLabel, #item3 .mblListItemLabel {
+		margin-right: 100px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="settings" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Today", back:"Sunday", moveTo:"#"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" style="float:right;" data-dojo-props='label:"Monday"'></span>
+		</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"#", selected:true'>Sunday</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"#", label:"Monday"'></li>
+		</ul>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Today</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", rightText:"Second"'>
+				Sunday
+			</li>
+			<li id="item2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", label:"Monday"'>
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+		</ul>
+
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Today</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li id="item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", label:"Sunday"'>
+				<div data-dojo-type="dojox.mobile.Switch" data-dojo-props='leftLabel:"ON"'></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", rightText:"Second", moveTo:"#", label:"Monday"'>
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='label:"Today", back:"Second", transition:"slide"'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Sunday", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Monday", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.TabBar">
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", moveTo:"#", selected:true'>Sunday</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"#", label:"Monday"'></li>
+		</ul>
+
+		<form style="margin: 10px;">
+			Locale: 
+			<select id="sel" name="lang" onchange="changeLocale()">
+				<option value=""></option>
+				<option value="en">en</option>
+				<option value="it">it</option>
+				<option value="ja">ja</option>
+			</select>
+		</form>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_i18n.html b/dojox/mobile/tests/test_i18n.html
index 5c8685e..c3b3a95 100644
--- a/dojox/mobile/tests/test_i18n.html
+++ b/dojox/mobile/tests/test_i18n.html
@@ -1,82 +1,98 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Settings</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-		<link href="../themes/iphone/IconContainer.css" rel="stylesheet">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Settings</title>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','TabBar','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-		<script language="JavaScript" type="text/javascript">
+	<script type="text/javascript">
+		require([
+			"dojo/_base/kernel"
+		], function(dojo){
 			var lang = location.search.match(/lang=(\w*)/) ? RegExp.$1 : null;
-
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.i18n");
-			dojo.require("dojox.mobile.TabBar");
-			dojo.require("dojox.mobile.IconContainer");
-			var bundle = dojox.mobile.i18n.load("dojox.mobile.tests", "sample", lang);
-			function changeLocale(){
-				document.forms[0].submit();
-			}
-			dojo.ready(function(){
-				document.getElementById("sel").value = lang;
-				dijit.byId("item1").set("label", bundle["MINUTES"].replace("%1", "30"));
+			if(lang){ dojo.locale = lang; }
+			require([
+				"dojo/_base/window",
+				"dojo/dom",
+				"dojo/ready",
+				"dijit/registry",
+				"dojo/i18n!dojox/mobile/tests/nls/sample",
+				"dojox/mobile/i18n",
+				"dojox/mobile/parser",
+				"dojox/mobile",
+				"dojox/mobile/compat",
+				"dojox/mobile/TabBar",
+				"dojox/mobile/IconContainer"
+			], function(win, dom, ready, registry, sample, i18n){
+				var bundle = i18n.registerBundle(sample);
+				changeLocale = function(){
+					win.doc.forms[0].submit();
+				}
+				ready(function(){
+					dom.byId("sel").value = lang;
+					registry.byId("item1").set("label", bundle["MINUTES"].replace("%1", "30"));
+				});
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" label="Day of the Week" back="Sunday" moveTo="#">
-				<div dojoType="dojox.mobile.ToolBarButton" style="float:right;" label="Monday"></div>
-			</h1>
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-				<li dojoType="dojox.mobile.TabBarButton" moveTo="#" selected="true">Sunday</li>
-				<li dojoType="dojox.mobile.TabBarButton" moveTo="#" label="Monday"></li>
-			</ul>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Day of the Week</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="item1" dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" rightText="Second">
-					Sunday
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" label="Monday">
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-			</ul>
+		});
+
+	</script>
+	<style>
+	#item2 .mblListItemLabel, #item3 .mblListItemLabel {
+		margin-right: 100px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="settings" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Today", back:"Sunday", moveTo:"#"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" style="float:right;" data-dojo-props='label:"Monday"'></span>
+		</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"'>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"#", selected:true'>Sunday</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='moveTo:"#", label:"Monday"'></li>
+		</ul>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Today</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li id="item1" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", rightText:"Second"'>
+				Sunday
+			</li>
+			<li id="item2" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", label:"Monday"'>
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+		</ul>
 
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Day of the Week</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					Sunday
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch" leftLabel="ON"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="Second" moveTo="#" label="Monday">
-				</li>
-			</ul>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Today</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li id="item3" data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", label:"Sunday"'>
+				<div data-dojo-type="dojox.mobile.Switch" data-dojo-props='leftLabel:"ON"'></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", rightText:"Second", moveTo:"#", label:"Monday"'>
+			</li>
+		</ul>
 
-			<ul dojoType="dojox.mobile.IconContainer" label="Day of the Week" back="Second" transition="slide">
-				<li dojoType="dojox.mobile.IconItem" label="Sunday" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="Monday" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-			</ul>
+		<ul data-dojo-type="dojox.mobile.IconContainer" data-dojo-props='label:"Today", back:"Second", transition:"slide"'>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Sunday", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Monday", icon:"images/icon-1.png", lazy:true'><div class="box"></div></li>
+		</ul>
 
-			<ul dojoType="dojox.mobile.TabBar">
-				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="#" selected="true">Sunday</li>
-				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="#" label="Monday"></li>
-			</ul>
+		<ul data-dojo-type="dojox.mobile.TabBar">
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-16.png", icon2:"images/tab-icon-16h.png", moveTo:"#", selected:true'>Sunday</li>
+			<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='icon1:"images/tab-icon-15.png", icon2:"images/tab-icon-15h.png", moveTo:"#", label:"Monday"'></li>
+		</ul>
 
-			<form style="margin: 10px;">
-				Locale: 
-				<select id="sel" name="lang" onchange="changeLocale()">
-					<option value=""></option>
-					<option value="en">en</option>
-					<option value="it">it</option>
-					<option value="ja">ja</option>
-				</select>
-			</form>
-		</div>
-	</body>
+		<form style="margin: 10px;">
+			Locale: 
+			<select id="sel" name="lang" onchange="changeLocale()">
+				<option value=""></option>
+				<option value="en">en</option>
+				<option value="it">it</option>
+				<option value="ja">ja</option>
+			</select>
+		</form>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_iPad-Heading.html b/dojox/mobile/tests/test_iPad-Heading.html
deleted file mode 100644
index 8e9896f..0000000
--- a/dojox/mobile/tests/test_iPad-Heading.html
+++ /dev/null
@@ -1,124 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Heading</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-		<link href="../themes/common/domButtons.css" rel="stylesheet">
-		<link href="../themes/iphone/ipad.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-			dojo.ready(function(){
-				var btn1 = dijit.byId("btn1");
-				btn1.connect(btn1.domNode, "onclick", function(){
-					console.log(this.label + " button was clicked");
-				});
-			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="general" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">General</h1>
-			<h1 dojoType="dojox.mobile.Heading" back="Long Button" moveTo="settings">Very Very Long Title May Not Be Displayed in the Narrow Space - Very Very Long Title May Not Be Displayed in the Narrow Space</h1>
-		</div>
-
-		<h3>Heading with buttons</h3>
-
-		<h1 dojoType="dojox.mobile.Heading" label="World Clock">
-			<div id="btn1" dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px;float:left">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;" onclick="console.log('+ was clicked')"></div>
-
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px;float:left;">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;"></div>
-			Alarm Clock
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Voice Memos">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Speaker" style="float:left"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Updates">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="News" back="Bookmarks" moveTo="bookmarks">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="New Folder" style="float:right;"></div>
-		</h1><br>
-
-
-		<div dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">New</div>
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">Toggle</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icon-18h.png" moveTo="view3" style="padding:0 10px"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icons.png" iconPos="29,0,29,29" moveTo="view3" style="padding:0 10px"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" moveTo="view3" style="float:right;"></div>
-		</div><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:left;margin-left:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px" selected="true">Catalog</li>
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px">Share</li>
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px">Download</li>
-			</ul>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" align="center">
-		  <table cellpadding="0" cellspacing="0" style="width:100%;"><tr>
-			<td><div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus"></div></td>
-			<td align="center"><div dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="margin:auto;">
-				<div dojoType="dojox.mobile.TabBarButton" selected="true" style="width:80px">Search</div>
-				<div dojoType="dojox.mobile.TabBarButton" style="width:80px">Directions</div>
-			</div></td>
-			<td align="right"><div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icon-15h.png" style="float:right;"></div></td>
-		  </tr></table>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Inbox" label="1 of 10">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:right;margin-right:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteDownArrow" selectOne="false"></li>
-			</ul>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Top" label="Inbox(32)">
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteUpArrow" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteDownArrow" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Inbox" label="1 of 10">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:right;margin-right:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteSearch" selectOne="false"></li>
-			</ul>
-		</h1><br>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPad-Settings-async.html b/dojox/mobile/tests/test_iPad-Settings-async.html
deleted file mode 100644
index 5de8426..0000000
--- a/dojox/mobile/tests/test_iPad-Settings-async.html
+++ /dev/null
@@ -1,241 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>iPad Settings</title>
-		<style>
-		@import "../themes/iphone/base.css";
-		@import "../themes/iphone/ipad.css";
-		@import "../themes/common/FixedSplitter.css";
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			position: relative;
-		}
-		.mblEdgeToEdgeList {
-			background-color: #DBDDE2;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, mblAlwaysHideAddressBar: true, async: true"></script>
-		<script language="JavaScript" type="text/javascript">
-		require([
-			"dojox/mobile/parser", 	// This mobile app uses declarative programming with fast mobile parser
-			"dojox/mobile",			// This is a mobile app.
-			"dojox/mobile/FixedSplitter",
-			"dojox/mobile/ScrollableView",
-			"dojox/mobile/EdgeToEdgeList",
-			"dojox/mobile/EdgeToEdgeCategory",
-			"dojox/mobile/Heading",
-			"dojox/mobile/FixedSplitterPane",
-			"dojox/mobile/compat" 	// This mobile app supports running on desktop browsers
-			// "domReady!" // Enable if user code placed in the callback here that needs DOMReady
-		]);
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="width:300px;border-right:1px solid black;">
-				<div id="settings" dojoType="dojox.mobile.ScrollableView" selected="true">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">Settings</h1>
-					<ul dojoType="dojox.mobile.EdgeToEdgeList" transition="flip" stateful="true">
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							Wi-Fi
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Brightness & Wallpaper
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Picture Frame
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general" selected="true">
-							General
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="wifi">
-							Mail, Contacts, Calendars
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bright">
-							Safari
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="picture">
-							iPod
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="general">
-							Video
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="wifi">
-							Photos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="bright">
-							Store
-						</li>
-						<li class="mblEdgeToEdgeCategory">
-							Apps
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							News
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Weather
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Books
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-							 Business
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							Navigation
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Sports
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Social
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-							Music
-						</li>
-					</ul>
-				</div>
-			</div>
-
-			<div dojoType="dojox.mobile.FixedSplitterPane">
-
-				<div id="general" dojoType="dojox.mobile.ScrollableView" selected="true">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">General</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							About
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="2h 40m" moveTo="about">
-							Usage
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Network
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Bluetooth
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Location Services
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" rightText="1 Minute" moveTo="about">
-							Auto-Lock
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Passcode Lock
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Restrictions
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Home
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Date & Time					   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Keyboard					   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							International				   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Accessibility
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Reset
-						</li>
-					</ul>
-				</div>
-
-				<div id="about" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="General" moveTo="general">About</h1>
-					<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-							Network											   
-						</li>												   
-						<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-							Line
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="1024">
-							Songs
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="10">
-							Videos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="96">
-							Photos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="2">
-							Applications
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-							Capacity
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-							Available
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-							Version
-						</li>
-					</ul>
-				</div>
-
-				<div id="wifi" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">Wi-Fi Networks</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem">
-							Wi-Fi
-							<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							<input type="text">
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							<select><option>Songs</option><option>Videos</option><option>Photos</option></select>
-						</li>
-					</ul>
-				</div>
-
-				<div id="bright" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">Brightness & Wallpaper</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem">
-							Auto-Brightness
-							<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-						</li>
-					</ul>
-				</div>
-
-				<div id="picture" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">Picture Frame</h1>
-					<h2 dojoType="dojox.mobile.RoundRectCategory">Transition</h2>
-					<ul dojoType="dojox.mobile.RoundRectList" select="single">
-						<li dojoType="dojox.mobile.ListItem" checked="true">
-							Dissolve
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							Origami
-						</li>
-					</ul>
-				</div>
-
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPad-Settings.html b/dojox/mobile/tests/test_iPad-Settings.html
deleted file mode 100644
index c57614b..0000000
--- a/dojox/mobile/tests/test_iPad-Settings.html
+++ /dev/null
@@ -1,235 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>iPad Settings</title>
-		<style>
-		@import "../themes/iphone/base.css";
-		@import "../themes/iphone/ipad.css";
-		@import "../themes/common/FixedSplitter.css";
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			position: relative;
-		}
-		.mblEdgeToEdgeList {
-			background-color: #DBDDE2;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.FixedSplitter");
-			dojo.require("dojox.mobile.ScrollableView");
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="width:300px;border-right:1px solid black;">
-				<div id="settings" dojoType="dojox.mobile.ScrollableView" selected="true">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">Settings</h1>
-					<ul dojoType="dojox.mobile.EdgeToEdgeList" transition="flip" stateful="true">
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							Wi-Fi
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Brightness & Wallpaper
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Picture Frame
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general" selected="true">
-							General
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="wifi">
-							Mail, Contacts, Calendars
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bright">
-							Safari
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="picture">
-							iPod
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="general">
-							Video
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="wifi">
-							Photos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="bright">
-							Store
-						</li>
-						<li class="mblEdgeToEdgeCategory">
-							Apps
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							News
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Weather
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Books
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-							 Business
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							Navigation
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Sports
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Social
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-							Music
-						</li>
-					</ul>
-				</div>
-			</div>
-
-			<div dojoType="dojox.mobile.FixedSplitterPane">
-
-				<div id="general" dojoType="dojox.mobile.ScrollableView" selected="true">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">General</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							About
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="2h 40m" moveTo="about">
-							Usage
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Network
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Bluetooth
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Location Services
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" rightText="1 Minute" moveTo="about">
-							Auto-Lock
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Passcode Lock
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Restrictions
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Home
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Date & Time					   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Keyboard					   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							International				   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Accessibility
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Reset
-						</li>
-					</ul>
-				</div>
-
-				<div id="about" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="General" moveTo="general">About</h1>
-					<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-							Network											   
-						</li>												   
-						<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-							Line
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="1024">
-							Songs
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="10">
-							Videos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="96">
-							Photos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="2">
-							Applications
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-							Capacity
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-							Available
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-							Version
-						</li>
-					</ul>
-				</div>
-
-				<div id="wifi" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">Wi-Fi Networks</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem">
-							Wi-Fi
-							<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							<input type="text">
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							<select><option>Songs</option><option>Videos</option><option>Photos</option></select>
-						</li>
-					</ul>
-				</div>
-
-				<div id="bright" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">Brightness & Wallpaper</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem">
-							Auto-Brightness
-							<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-						</li>
-					</ul>
-				</div>
-
-				<div id="picture" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">Picture Frame</h1>
-					<h2 dojoType="dojox.mobile.RoundRectCategory">Transition</h2>
-					<ul dojoType="dojox.mobile.RoundRectList" select="single">
-						<li dojoType="dojox.mobile.ListItem" checked="true">
-							Dissolve
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							Origami
-						</li>
-					</ul>
-				</div>
-
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPad-TabBar.html b/dojox/mobile/tests/test_iPad-TabBar.html
deleted file mode 100644
index 1011092..0000000
--- a/dojox/mobile/tests/test_iPad-TabBar.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>TabBar</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-		<link href="../themes/iphone/ipad.css" rel="stylesheet">
-		<style>
-		.label {
-			font-family: "Helvetica Neue", Helvetica;
-			font-size: 13px;
-			margin-top: 20px;
-		}
-		.view {
-			font-size: 30px;
-			padding-top: 30px;
-			text-align: center;
-		}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div class="label">Segmented Control</div>
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar</div>
-		<ul dojoType="dojox.mobile.TabBar">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar (CSS Sprite)</div>
-		<ul dojoType="dojox.mobile.TabBar" iconBase="images/tab-icons.png">
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Featured</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,29,29,29" iconPos2="29,29,29,29">Categories</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,58,29,29" iconPos2="29,58,29,29">Top 25</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,87,29,29" iconPos2="29,87,29,29">Search</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,116,29,29" iconPos2="29,116,29,29">Updates</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<div class="view">View 1</div>
-		</div>
-		<div id="view2" dojoType="dojox.mobile.View">
-			<div class="view">View 2</div>
-		</div>
-		<div id="view3" dojoType="dojox.mobile.View">
-			<div class="view">View 3</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-Animation-async.html b/dojox/mobile/tests/test_iPhone-Animation-async.html
deleted file mode 100644
index 0dedca5..0000000
--- a/dojox/mobile/tests/test_iPhone-Animation-async.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Animation</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="async: true, parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			require([
-				"dojox/mobile/parser",
-				"dojox/mobile",
-				"dojox/mobile/compat"
-			]);
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Animations</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-Animation.html b/dojox/mobile/tests/test_iPhone-Animation.html
deleted file mode 100644
index 9920579..0000000
--- a/dojox/mobile/tests/test_iPhone-Animation.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Animation</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Animations</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-Button.html b/dojox/mobile/tests/test_iPhone-Button.html
deleted file mode 100755
index 5fd53d5..0000000
--- a/dojox/mobile/tests/test_iPhone-Button.html
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Button</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/Button.css" rel="stylesheet">
-		<style>
-		button.redButton {
-			border-color: #cc3333;
-			background-image: url(images/red-button-bg.png);
-			background: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
-		}
-		button.redButtonSelected {
-			background-image: url(images/red-button-sel-bg.png);
-			background: -webkit-gradient(linear, left top, left bottom, from(#AF333C), to(#880E17), color-stop(0.5, #952B33), color-stop(0.5, #870F18));
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.Button");
-
-			dojo.ready(function(){
-				var btnWidget = dijit.byId("btn1");
-				dojo.connect(btnWidget.domNode, "onclick", onBtnClicked);
-				function onBtnClicked(e){
-					// do something
-				}
-			});
-		</script>
-	</head>
-	<body style="padding: 20px;visibility:visible">
-		<button id="btn1" dojoType="dojox.mobile.Button" class="mblBlueButton" style="width:120px">Default Button</button>
-		<p></p>
-		<button id="btn2" dojoType="dojox.mobile.Button" class="redButton" style="width:120px">Custom Button</button>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ButtonList.html b/dojox/mobile/tests/test_iPhone-ButtonList.html
deleted file mode 100644
index 39334fd..0000000
--- a/dojox/mobile/tests/test_iPhone-ButtonList.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Button List</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/common/domButtons/DomButtonColorButtons.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.ready(function(){
-				var ul = dojo.byId("list");
-				for(var i = 0, len = ul.childNodes.length; i < len; i++){
-					var li = ul.childNodes[i];
-					if(li.nodeType != 1 || li.tagName != "LI"){ continue; }
-					var w = dijit.byNode(li);
-					dojo.connect(w.rightIconNode, "onclick", btnClicked);
-				}
-			});
-			function btnClicked(e){
-				var listItem = dijit.getEnclosingWidget(e.currentTarget);
-				var btnDiv = listItem.rightIconNode.firstChild;
-				if(dojo.hasClass(btnDiv, "mblDomButtonBluePlus")){
-					listItem.set("btnClass", "mblDomButtonRedMinus");
-				}else if(dojo.hasClass(btnDiv, "mblDomButtonRedMinus")){
-					listItem.set("btnClass", "mblDomButtonBluePlus");
-				}
-			}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="mashups" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mashups</h1>
-			<ul id="list" dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" btnClass="mblDomButtonBluePlus">
-					XX Widget
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" btnClass="mblDomButtonRedMinus">
-					YY Widget
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-EdgeToEdge.html b/dojox/mobile/tests/test_iPhone-EdgeToEdge.html
deleted file mode 100644
index 9117567..0000000
--- a/dojox/mobile/tests/test_iPhone-EdgeToEdge.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Edge to Edge</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.View");
-			dojo.require("dojox.mobile.Heading");
-			dojo.require("dojox.mobile.EdgeToEdgeList");
-			dojo.require("dojox.mobile.ListItem");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Settings</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="mac" moveTo="hello">
-					Wi-Fi
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="AcmePhone" moveTo="hello">
-					Carrier
-				</li>
-			</ul>
-		</div>
-
-		<div id="hello" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading">Hello</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="settings">
-					Hello
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="settings">
-					Carrier
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-EdgeToEdgeCategory.html b/dojox/mobile/tests/test_iPhone-EdgeToEdgeCategory.html
deleted file mode 100644
index 0d24a9e..0000000
--- a/dojox/mobile/tests/test_iPhone-EdgeToEdgeCategory.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Edge to Edge</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Edge-to-Edge List</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">J</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem">
-					Jack Coleman
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					James Evans
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Jason Griffin
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">K</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem">
-					Karen Hughes
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Kelly Perry
-				</li>
-				<li dojoType="dojox.mobile.ListItem">
-					Kevin Rivera
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-Heading.html b/dojox/mobile/tests/test_iPhone-Heading.html
deleted file mode 100644
index 269190b..0000000
--- a/dojox/mobile/tests/test_iPhone-Heading.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Heading</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-		<link href="../themes/common/domButtons.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-			dojo.ready(function(){
-				var btn1 = dijit.byId("btn1");
-				btn1.connect(btn1.domNode, "onclick", function(){
-					console.log(this.label + " button was clicked");
-				});
-			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="general" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">General</h1>
-			<h1 dojoType="dojox.mobile.Heading" back="Long Button" moveTo="settings">Very Very Long Title May Not Be Displayed in the Narrow Space - Very Very Long Title May Not Be Displayed in the Narrow Space</h1>
-		</div>
-
-		<h3>Heading with buttons</h3>
-
-		<h1 dojoType="dojox.mobile.Heading" label="World Clock">
-			<div id="btn1" dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px;float:left">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;" onclick="console.log('+ was clicked')"></div>
-
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" style="padding: 0px 14px;float:left;">Edit</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" style="float:right;"></div>
-			Alarm Clock
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Voice Memos">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Speaker" style="float:left"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="Updates">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Update All" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" label="News" back="Bookmarks" moveTo="bookmarks">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" label="New Folder" style="float:right;"></div>
-		</h1><br>
-
-
-		<div dojoType="dojox.mobile.Heading">
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">New</div>
-			<div dojoType="dojox.mobile.ToolBarButton" toggle="true">Toggle</div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icon-18h.png" moveTo="view3" style="padding:0 10px"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icons.png" iconPos="29,0,29,29" moveTo="view3" style="padding:0 10px"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus" moveTo="view3" style="float:right;"></div>
-		</div><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:left;margin-left:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px" selected="true">Catalog</li>
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px">Share</li>
-				<li dojoType="dojox.mobile.TabBarButton" style="width:80px">Download</li>
-			</ul>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" align="center">
-		  <table cellpadding="0" cellspacing="0" style="width:100%;"><tr>
-			<td><div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhitePlus"></div></td>
-			<td align="center"><div dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="margin:auto;">
-				<div dojoType="dojox.mobile.TabBarButton" selected="true" style="width:80px">Search</div>
-				<div dojoType="dojox.mobile.TabBarButton" style="width:80px">Directions</div>
-			</div></td>
-			<td align="right"><div dojoType="dojox.mobile.ToolBarButton" icon="images/tab-icon-15h.png" style="float:right;"></div></td>
-		  </tr></table>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Inbox" label="1 of 10">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:right;margin-right:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteDownArrow" selectOne="false"></li>
-			</ul>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Top" label="Inbox(32)">
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteSearch" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteUpArrow" style="float:right;"></div>
-			<div dojoType="dojox.mobile.ToolBarButton" icon="mblDomButtonWhiteDownArrow" style="float:right;"></div>
-		</h1><br>
-
-
-		<h1 dojoType="dojox.mobile.Heading" back="Inbox" label="1 of 10">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" style="float:right;margin-right:6px;">
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteUpArrow" selectOne="false"></li>
-				<li dojoType="dojox.mobile.TabBarButton" icon="mblDomButtonWhiteSearch" selectOne="false"></li>
-			</ul>
-		</h1><br>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-Icon-sprite.html b/dojox/mobile/tests/test_iPhone-Icon-sprite.html
deleted file mode 100644
index 245dd83..0000000
--- a/dojox/mobile/tests/test_iPhone-Icon-sprite.html
+++ /dev/null
@@ -1,62 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon (css sprite)</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/IconContainer.css" rel="stylesheet">
-
-		<style>
-			html,body{
-				overflow: hidden;
-			}
-			.box {
-				border: 1px solid #A7C0E0;
-				width: 300px;
-				height: 250px;
-				background-image: url(images/widget-bg.png);
-				background-repeat: no-repeat;
-				background-color: white;
-			}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Sprite Icons</h1>
-			<ul dojoType="dojox.mobile.IconContainer" iconBase="images/icon-all.png">
-				<li dojoType="dojox.mobile.IconItem" label="app1" iconPos="0,0,65,65" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app2" iconPos="0,65,65,65" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app3" iconPos="0,130,65,65" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="moveTo" iconPos="0,195,65,65" moveTo="about" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="href" iconPos="0,260,65,65" href="test_iPhone-RoundRectList.html" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="url" iconPos="65,0,65,65" url="view-sample.html" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="url-async" iconPos="65,65,65,65" url="view-sample.html" transition="slide" sync="false"></li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-Icon.html b/dojox/mobile/tests/test_iPhone-Icon.html
deleted file mode 100644
index b898456..0000000
--- a/dojox/mobile/tests/test_iPhone-Icon.html
+++ /dev/null
@@ -1,63 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/IconContainer.css" rel="stylesheet">
-
-		<style>
-			.box {
-				border: 1px solid #A7C0E0;
-				width: 300px;
-				height: 250px;
-				background-image: url(images/widget-bg.png);
-				background-repeat: no-repeat;
-				background-color: white;
-			}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.IconContainer");
-			dojo.require("dojox.mobile.RoundRectCategory");
-			dojo.require("dojox.mobile.RoundRectList");
-			dojo.require("dojox.mobile.ListItem");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="app1" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app2" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app3" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="moveTo" icon="images/icon-1.png" moveTo="about" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="href" icon="images/icon-1.png" href="test_iPhone-RoundRectList.html" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="hrefTarget" icon="images/icon-1.png" href="test_iPhone-RoundRectList.html" hrefTarget="_blank"></li>
-				<li dojoType="dojox.mobile.IconItem" label="url" icon="images/icon-1.png" url="view-sample.html" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="url-async" icon="images/icon-1.png" url="view-sample.html" transition="slide" sync="false"></li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Icon Container" moveTo="foo">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">My Phone</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-IconMulti.html b/dojox/mobile/tests/test_iPhone-IconMulti.html
deleted file mode 100644
index 9d6355d..0000000
--- a/dojox/mobile/tests/test_iPhone-IconMulti.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon Container (Multi Apps)</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/IconContainer.css" rel="stylesheet">
-		<link href="../themes/common/dijit/dijit.css" rel="stylesheet">
-		<style>
-			#cal>thead {
-				display: table-header-group;
-				vertical-align: middle;
-				border-color: inherit;
-				background-image: -webkit-gradient(linear, left top, left bottom, from(#F6F6F6), to(#CCCCD1));
-			}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-	</head>
-	<body style="visibility:hidden;background-color:white">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container (Multi Apps)</h1>
-			<ul dojoType="dojox.mobile.IconContainer" transition="flip">
-				<li dojoType="dojox.mobile.IconItem" label="Calendar" icon="images/icon-1.png" lazy="true">
-					<div id="cal" dojoType='dijit.CalendarLite'></div>
-				</li>
-				<li dojoType="dojox.mobile.IconItem" label="Color Palette" icon="images/icon-1.png" lazy="true">
-					<div dojoType='dijit.ColorPalette'></div>
-				</li>
-				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true">
-					<div dojoType='dijit.ProgressBar'></div>
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-IconSingle.html b/dojox/mobile/tests/test_iPhone-IconSingle.html
deleted file mode 100644
index b86ad0e..0000000
--- a/dojox/mobile/tests/test_iPhone-IconSingle.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon Container (Single App)</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/IconContainer.css" rel="stylesheet">
-		<link href="../themes/common/dijit/dijit.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-	</head>
-	<body class="tundra" style="visibility:hidden;background-color:white">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container (Single App)</h1>
-			<ul dojoType="dojox.mobile.IconContainer" transition="flip" single="true">
-				<li dojoType="dojox.mobile.IconItem" label="Calendar" icon="images/icon-1.png" lazy="true">
-					<div dojoType='dijit.CalendarLite'></div>
-				</li>
-				<li dojoType="dojox.mobile.IconItem" label="Color Palette" icon="images/icon-1.png" lazy="true">
-					<div dojoType='dijit.ColorPalette'></div>
-				</li>
-				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true">
-					<div dojoType='dijit.ProgressBar'></div>
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-IconSingleBelow.html b/dojox/mobile/tests/test_iPhone-IconSingleBelow.html
deleted file mode 100644
index 9a8eec5..0000000
--- a/dojox/mobile/tests/test_iPhone-IconSingleBelow.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Icon Container (Single App)</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/IconContainer.css" rel="stylesheet">
-		<link href="../themes/common/dijit/dijit.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-	</head>
-	<body class="tundra" style="visibility:hidden;background-color:white">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container (Single App)</h1>
-			<ul dojoType="dojox.mobile.IconContainer" transition="below" single="true">
-				<li dojoType="dojox.mobile.IconItem" label="Calendar" icon="images/icon-1.png" lazy="true">
-					<div dojoType='dijit.CalendarLite'></div>
-				</li>
-				<li dojoType="dojox.mobile.IconItem" label="Color Palette" icon="images/icon-1.png" lazy="true">
-					<div dojoType='dijit.ColorPalette'></div>
-				</li>
-				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true">
-					<div dojoType='dijit.ProgressBar'></div>
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ResultList.html b/dojox/mobile/tests/test_iPhone-ResultList.html
deleted file mode 100644
index aadbf9c..0000000
--- a/dojox/mobile/tests/test_iPhone-ResultList.html
+++ /dev/null
@@ -1,64 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Result List</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-			.lnk {
-				font-size: 14px;
-				color: #0B5199;
-				text-decoration: none;
-			}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-RoundRect.html b/dojox/mobile/tests/test_iPhone-RoundRect.html
deleted file mode 100644
index 2054fca..0000000
--- a/dojox/mobile/tests/test_iPhone-RoundRect.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Round Rect</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Round Rectangle</h2>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				This module provides some widgets that can be used to build web-based
-				applications for mobile devices such as iPhone or Android.
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-RoundRectList.html b/dojox/mobile/tests/test_iPhone-RoundRectList.html
deleted file mode 100644
index ef03989..0000000
--- a/dojox/mobile/tests/test_iPhone-RoundRectList.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Round Rect List</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="item1" dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" rightText="Off" moveTo="bar">
-					u1space
-				</li>
-				<li id="item2" dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="Off" moveTo="bar">
-					u2space
-				</li>
-				<li id="item3" dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="Off" moveTo="bar">
-					Wi-Fi
-				</li>
-				<li id="item4" dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" rightText="VPN" moveTo="bar">
-					VPN
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Spaces" moveTo="foo">u1space</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Applications</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">
-					Video
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" rightText="VPN">
-					Maps
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off">
-					Phone Number
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-demo-async.html b/dojox/mobile/tests/test_iPhone-ScrollableView-demo-async.html
deleted file mode 100644
index 55c8a37..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-demo-async.html
+++ /dev/null
@@ -1,393 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>ScrollableView demo</title>
-	<link href="../themes/iphone/base.css" rel="stylesheet">
-	<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-	<style>
-	html,body{
-		height: 100%;
-		overflow: hidden;
-	}
-	.list1 li{
-		border-style: solid;
-		border-width: 1px 0px 1px 0px;
-		border-top-color: #BABABC;
-		border-bottom-color: #89898C;
-		background-color: #ACACAF;
-		line-height: 0px;
-	}
-	.list1 li table{
-		line-height: normal;
-	}
-	.list1 li:nth-child(even){
-		background-color: #97979B;
-	}
-	#list2 li:nth-child(even){
-		background-color: #eeeeee;
-	}
-	#categ1 {
-		font-size: 18px;
-	}
-	#categ1 li{
-		line-height: 70px;
-	}
-	.lnk {
-		font-size: 14px;
-		color: #0B5199;
-		text-decoration: none;
-	}
-	.content {
-		padding:0px 10px;
-		background-color: white;
-	}
-	p {
-		font-family: Helvetica;
-		font-size: 12px;
-	}
-	.title {
-		color: blue;
-		margin-bottom: 4px;
-	}
-	.subtitle {
-		font-style: italic;
-		color: gray;
-		margin: 0px;
-		margin-bottom: 4px;
-	}
-	.subsubtitle {
-		margin: 16px 0px 0px 0px;
-	}
-	.lst {
-		margin: 0px;
-		padding: 0px 14px;
-	}
-	.lst li {
-		font-family: Helvetica;
-		font-size: 12px;
-		margin: 0px;
-		list-style-type: square;
-	}
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async:true, mblAlwaysHideAddressBar: true"></script>
-	<script language="JavaScript" type="text/javascript">
-		require([
-			"dojox/mobile/parser", 	// This mobile app uses declarative programming with fast mobile parser
-			"dojox/mobile",			// This is a mobile app.
-			"dojox/mobile/ScrollableView",
-			"dojox/mobile/TabBar",
-			"dojox/mobile/compat" 	// This mobile app supports running on desktop browsers
-		]);
-	</script>
-</head>
-<body style="visibility:hidden;">
-	<div id="group1" dojoType="dojox.mobile.View" selected="true">
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" fixed="top">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-									Sarah Connor Hardcover<br>
-									Eligible for FREE Super Saver Shipping
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
-									Martin Parker Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Total Solar Eclipse</a><br>
-									Steven Young Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The History of Java Coffee</a><br>
-									Marco Rodriguez Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-									Melissa Morgan Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-			</ul>
-		</div>
-
-		<div id="view2" dojoType="dojox.mobile.ScrollableView">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list2">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-									Melissa Morgan Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The History of Java Coffee</a><br>
-									Marco Rodriguez Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-									Sarah Connor Hardcover<br>
-									Eligible for FREE Super Saver Shipping
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Total Solar Eclipse</a><br>
-									Steven Young Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-			</ul>
-		</div>
-
-		<div id="view3" dojoType="dojox.mobile.ScrollableView">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="10">
-					Videos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="96">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2">
-					Applications
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-					Capacity
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-					Available
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-					Version
-				</li>
-			</ul>
-		</div>
-	</div>
-
-	<div id="categ" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Categories</h1>
-		<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1" id="categ1">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 1</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 2</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 3</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 4</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 5</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 6</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 7</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 8</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 9</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 10</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 11</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 12</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 13</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 14</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 15</li>
-		</ul>
-	</div>
-
-	<div id="top25" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">News</h1>
-		<h2 dojoType="dojox.mobile.RoundRectCategory">Top Stories</h2>
-		<ul dojoType="dojox.mobile.RoundRectList">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Top 10 news stories of the decade
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Create client-side diagrammatic interaction in Web applications with GFX
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
-			</li>
-		</ul>
-	</div>
-
-	<div id="search" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Search Result</h1>
-		<ul dojoType="dojox.mobile.RoundRectList">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-				Sarah Connor Hardcover<br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$14.50 (50%)</font> In Stock<br>
-				# (531)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-				Martin Parker Hardcover<br>
-				<font color="red">$14.00 (60%)</font> In Stock<br>
-				# (173)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-				Steven Young Hardcover<br>
-				Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$9.50 (62%)</font> In Stock<br>
-				# (1199)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-				Marco Rodriguez Hardcover<br>
-				<font color="blue">Not Available</font>
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-				Melissa Morgan Hardcover<br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$12.00 (60%)</font> In Stock<br>
-				# (1847)
-			</li>
-		</ul>
-	</div>
-
-	<div id="article" dojoType="dojox.mobile.ScrollableView" style="background-color:white;height:100%">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Article</h1>
-		<div class="content">
-			<h3 class="title">Did you know?</h3>
-			<h4 class="subtitle">Features of dojox.mobile</h4>
-			<h5 class="subsubtitle">No images are used</h5>
-			<ul class="lst">
-			  	<li>UI parts consist of DOM and CSS3.</li>
-				<li>Only application icons are images.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
-			<ul class="lst">
-			  	<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Support for CSS sprite</h5>
-			<ul class="lst">
-				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
-			<ul class="lst">
-				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
-			</ul>
-		</div>
-	</div>
-
-	<ul dojoType="dojox.mobile.TabBar" fixed="bottom" style="border-bottom:none;">
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" selected="true" moveTo="group1">Featured</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="categ">Categories</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="top25">Top 25</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-11.png" icon2="images/tab-icon-11h.png" moveTo="search">Search</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-13.png" icon2="images/tab-icon-13h.png" moveTo="article">Updates</li>
-	</ul>
-</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-demo-long.html b/dojox/mobile/tests/test_iPhone-ScrollableView-demo-long.html
deleted file mode 100644
index 1d0809c..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-demo-long.html
+++ /dev/null
@@ -1,389 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>ScrollableView demo</title>
-	<link href="../themes/iphone/base.css" rel="stylesheet">
-	<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-	<style>
-	html,body{
-		height: 100%;
-		overflow: hidden;
-	}
-	.list1 li{
-		border-style: solid;
-		border-width: 1px 0px 1px 0px;
-		border-top-color: #BABABC;
-		border-bottom-color: #89898C;
-		background-color: #ACACAF;
-		line-height: 0px;
-	}
-	.list1 li table{
-		line-height: normal;
-	}
-	.list1 li:nth-child(even){
-		background-color: #97979B;
-	}
-	#list2 li:nth-child(even){
-		background-color: #eeeeee;
-	}
-	#categ1 {
-		font-size: 18px;
-	}
-	#categ1 li{
-		line-height: 70px;
-	}
-	.lnk {
-		font-size: 14px;
-		color: #0B5199;
-		text-decoration: none;
-	}
-	.content {
-		padding:0px 10px;
-		background-color: white;
-	}
-	p {
-		font-family: Helvetica;
-		font-size: 12px;
-	}
-	.title {
-		color: blue;
-		margin-bottom: 4px;
-	}
-	.subtitle {
-		font-style: italic;
-		color: gray;
-		margin: 0px;
-		margin-bottom: 4px;
-	}
-	.subsubtitle {
-		margin: 16px 0px 0px 0px;
-	}
-	.lst {
-		margin: 0px;
-		padding: 0px 14px;
-	}
-	.lst li {
-		font-family: Helvetica;
-		font-size: 12px;
-		margin: 0px;
-		list-style-type: square;
-	}
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-	<script language="JavaScript" type="text/javascript">
-		require([
-			"dojo/ready",
-			"dijit/_base/manager",	// for dijit.byId()
-			"dojox/mobile",			// This is a mobile app.
-			"dojox/mobile/compat", 	// This mobile app supports running on desktop browsers
-			"dojox/mobile/parser", 	// This mobile app uses declarative programming with fast mobile parser
-			"dojox/mobile/ScrollableView",
-			"dojox/mobile/TabBar"
-		], function(ready, dijit){
-			dojo.ready(function(){
-				var w = dijit.byId("categ1");
-				for(var i = 1; i <= 300; i++){
-					var item = new dojox.mobile.ListItem({label:"Category "+i});
-					item.domNode.className = "mblVariableHeight";
-					w.addChild(item);
-				}
-			});
-		});
-	</script>
-</head>
-<body style="visibility:hidden;">
-	<div id="group1" dojoType="dojox.mobile.View" selected="true" keepScrollPos="false"><!-- keepScrollPos=false is to improve performance -->
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" fixed="top">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-									Sarah Connor Hardcover<br>
-									Eligible for FREE Super Saver Shipping
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
-									Martin Parker Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Total Solar Eclipse</a><br>
-									Steven Young Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The History of Java Coffee</a><br>
-									Marco Rodriguez Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-									Melissa Morgan Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-			</ul>
-		</div>
-
-		<div id="view2" dojoType="dojox.mobile.ScrollableView">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list2">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-									Melissa Morgan Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The History of Java Coffee</a><br>
-									Marco Rodriguez Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-									Sarah Connor Hardcover<br>
-									Eligible for FREE Super Saver Shipping
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Total Solar Eclipse</a><br>
-									Steven Young Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-			</ul>
-		</div>
-
-		<div id="view3" dojoType="dojox.mobile.ScrollableView">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="10">
-					Videos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="96">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2">
-					Applications
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-					Capacity
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-					Available
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-					Version
-				</li>
-			</ul>
-		</div>
-	</div>
-
-	<div id="categ" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Categories</h1>
-		<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1" id="categ1">
-		</ul>
-	</div>
-
-	<div id="top25" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">News</h1>
-		<h2 dojoType="dojox.mobile.RoundRectCategory">Top Stories</h2>
-		<ul dojoType="dojox.mobile.RoundRectList">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Top 10 news stories of the decade
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Create client-side diagrammatic interaction in Web applications with GFX
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
-			</li>
-		</ul>
-	</div>
-
-	<div id="search" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Search Result</h1>
-		<ul dojoType="dojox.mobile.RoundRectList">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-				Sarah Connor Hardcover<br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$14.50 (50%)</font> In Stock<br>
-				# (531)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-				Martin Parker Hardcover<br>
-				<font color="red">$14.00 (60%)</font> In Stock<br>
-				# (173)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-				Steven Young Hardcover<br>
-				Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$9.50 (62%)</font> In Stock<br>
-				# (1199)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-				Marco Rodriguez Hardcover<br>
-				<font color="blue">Not Available</font>
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-				Melissa Morgan Hardcover<br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$12.00 (60%)</font> In Stock<br>
-				# (1847)
-			</li>
-		</ul>
-	</div>
-
-	<div id="article" dojoType="dojox.mobile.ScrollableView" style="background-color:white;height:100%">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Article</h1>
-		<div class="content">
-			<h3 class="title">Did you know?</h3>
-			<h4 class="subtitle">Features of dojox.mobile</h4>
-			<h5 class="subsubtitle">No images are used</h5>
-			<ul class="lst">
-			  	<li>UI parts consist of DOM and CSS3.</li>
-				<li>Only application icons are images.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
-			<ul class="lst">
-			  	<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Support for CSS sprite</h5>
-			<ul class="lst">
-				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
-			<ul class="lst">
-				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
-			</ul>
-		</div>
-	</div>
-
-	<ul dojoType="dojox.mobile.TabBar" fixed="bottom" style="border-bottom:none;">
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" selected="true" moveTo="group1">Featured</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="categ">Categories</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="top25">Top 25</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-11.png" icon2="images/tab-icon-11h.png" moveTo="search">Search</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-13.png" icon2="images/tab-icon-13h.png" moveTo="article">Updates</li>
-	</ul>
-</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-demo.html b/dojox/mobile/tests/test_iPhone-ScrollableView-demo.html
deleted file mode 100644
index 597338c..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-demo.html
+++ /dev/null
@@ -1,395 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-	<meta name="apple-mobile-web-app-capable" content="yes" />
-	<title>ScrollableView demo</title>
-	<link href="../themes/iphone/base.css" rel="stylesheet">
-	<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-	<style>
-	html,body{
-		height: 100%;
-		overflow: hidden;
-	}
-	.list1 li{
-		border-style: solid;
-		border-width: 1px 0px 1px 0px;
-		border-top-color: #BABABC;
-		border-bottom-color: #89898C;
-		background-color: #ACACAF;
-		line-height: 0px;
-	}
-	.list1 li table{
-		line-height: normal;
-	}
-	.list1 li:nth-child(even){
-		background-color: #97979B;
-	}
-	#list2 li:nth-child(even){
-		background-color: #eeeeee;
-	}
-	#categ1 {
-		font-size: 18px;
-	}
-	#categ1 li{
-		line-height: 70px;
-	}
-	.lnk {
-		font-size: 14px;
-		color: #0B5199;
-		text-decoration: none;
-	}
-	.content {
-		padding:0px 10px;
-		background-color: white;
-	}
-	p {
-		font-family: Helvetica;
-		font-size: 12px;
-	}
-	.title {
-		color: blue;
-		margin-bottom: 4px;
-	}
-	.subtitle {
-		font-style: italic;
-		color: gray;
-		margin: 0px;
-		margin-bottom: 4px;
-	}
-	.subsubtitle {
-		margin: 16px 0px 0px 0px;
-	}
-	.lst {
-		margin: 0px;
-		padding: 0px 14px;
-	}
-	.lst li {
-		font-family: Helvetica;
-		font-size: 12px;
-		margin: 0px;
-		list-style-type: square;
-	}
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		//dojo.require("dojo.parser"); // Use the lightweight parser.
-		dojo.require("dojox.mobile.parser");
-		dojo.require("dojox.mobile");
-		dojo.require("dojox.mobile.ScrollableView");
-		dojo.require("dojox.mobile.TabBar");
-		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
-		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
-	</script>
-</head>
-<body style="visibility:hidden;">
-	<div id="group1" dojoType="dojox.mobile.View" selected="true">
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" fixed="top">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-									Sarah Connor Hardcover<br>
-									Eligible for FREE Super Saver Shipping
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
-									Martin Parker Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Total Solar Eclipse</a><br>
-									Steven Young Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The History of Java Coffee</a><br>
-									Marco Rodriguez Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-									Melissa Morgan Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-			</ul>
-		</div>
-
-		<div id="view2" dojoType="dojox.mobile.ScrollableView">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list2">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-									Melissa Morgan Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The History of Java Coffee</a><br>
-									Marco Rodriguez Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-									Sarah Connor Hardcover<br>
-									Eligible for FREE Super Saver Shipping
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/a-icon-2-41x41.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Total Solar Eclipse</a><br>
-									Steven Young Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-			</ul>
-		</div>
-
-		<div id="view3" dojoType="dojox.mobile.ScrollableView">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="10">
-					Videos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="96">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2">
-					Applications
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-					Capacity
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-					Available
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-					Version
-				</li>
-			</ul>
-		</div>
-	</div>
-
-	<div id="categ" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Categories</h1>
-		<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1" id="categ1">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 1</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 2</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 3</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 4</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 5</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 6</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 7</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 8</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 9</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 10</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 11</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 12</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 13</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 14</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 15</li>
-		</ul>
-	</div>
-
-	<div id="top25" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">News</h1>
-		<h2 dojoType="dojox.mobile.RoundRectCategory">Top Stories</h2>
-		<ul dojoType="dojox.mobile.RoundRectList">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Top 10 news stories of the decade
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Create client-side diagrammatic interaction in Web applications with GFX
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
-				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
-			</li>
-		</ul>
-	</div>
-
-	<div id="search" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Search Result</h1>
-		<ul dojoType="dojox.mobile.RoundRectList">
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-				Sarah Connor Hardcover<br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$14.50 (50%)</font> In Stock<br>
-				# (531)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-				Martin Parker Hardcover<br>
-				<font color="red">$14.00 (60%)</font> In Stock<br>
-				# (173)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-				Steven Young Hardcover<br>
-				Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$9.50 (62%)</font> In Stock<br>
-				# (1199)
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-				Marco Rodriguez Hardcover<br>
-				<font color="blue">Not Available</font>
-			</li>
-			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-				Melissa Morgan Hardcover<br>
-				Eligible for FREE Super Saver Shipping<br>
-				<font color="red">$12.00 (60%)</font> In Stock<br>
-				# (1847)
-			</li>
-		</ul>
-	</div>
-
-	<div id="article" dojoType="dojox.mobile.ScrollableView" style="background-color:white;height:100%">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Article</h1>
-		<div class="content">
-			<h3 class="title">Did you know?</h3>
-			<h4 class="subtitle">Features of dojox.mobile</h4>
-			<h5 class="subsubtitle">No images are used</h5>
-			<ul class="lst">
-			  	<li>UI parts consist of DOM and CSS3.</li>
-				<li>Only application icons are images.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
-			<ul class="lst">
-			  	<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Support for CSS sprite</h5>
-			<ul class="lst">
-				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
-			</ul>
-
-			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
-			<ul class="lst">
-				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
-			</ul>
-		</div>
-	</div>
-
-	<ul dojoType="dojox.mobile.TabBar" fixed="bottom" style="border-bottom:none;">
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" selected="true" moveTo="group1">Featured</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="categ">Categories</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="top25">Top 25</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-11.png" icon2="images/tab-icon-11h.png" moveTo="search">Search</li>
-		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-13.png" icon2="images/tab-icon-13h.png" moveTo="article">Updates</li>
-	</ul>
-</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-h.html b/dojox/mobile/tests/test_iPhone-ScrollableView-h.html
deleted file mode 100644
index bb3e29d..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-h.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-h</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		td {
-			white-space: nowrap;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true" scrollDir="h">
-			<!-- h1 dojoType="dojox.mobile.Heading" fixed="top">Animations</h1 -->
-			<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;background-color:white;">
-<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
-			</table>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-hv-ah-af.html b/dojox/mobile/tests/test_iPhone-ScrollableView-hv-ah-af.html
deleted file mode 100644
index f0044b7..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-hv-ah-af.html
+++ /dev/null
@@ -1,121 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-hv-ah-af</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		td {
-			white-space: nowrap;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Application Header Bar</h1>
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true" scrollDir="hv">
-			<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;background-color:white;">
-<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>644</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-3.png</td><td>2010/04/13</td><td>06:37</td><td>1,346</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>677</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-10.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>680</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-3.png</td><td>2010/03/23</td><td>13:03</td><td>682</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>697</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-5.png</td><td>2010/03/23</td><td>13:03</td><td>693</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-6.png</td><td>2010/03/23</td><td>13:03</td><td>694</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-7.png</td><td>2010/03/23</td><td>13:03</td><td>691</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-8.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-9.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-all.png</td><td>2010/03/23</td><td>13:03</td><td>4,450</td><td>mobile/tests/images</td></tr>
-<tr><td>icon-1.png</td><td>2010/05/06</td><td>08:57</td><td>2,626</td><td>mobile/tests/images</td></tr>
-<tr><td>not-images.png</td><td>2010/04/13</td><td>06:37</td><td>18,459</td><td>mobile/tests/images</td></tr>
-<tr><td>red-button-bg.png</td><td>2010/04/13</td><td>06:37</td><td>178</td><td>mobile/tests/images</td></tr>
-<tr><td>red-button-sel-bg.png</td><td>2010/04/13</td><td>06:37</td><td>185</td><td>mobile/tests/images</td></tr>
-<tr><td>test_Android-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,750</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,835</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,615</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,634</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,142</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Settings.html</td><td>2010/10/05</td><td>21:08</td><td>4,375</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>1,000</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,031</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,570</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-H2-prog.html</td><td>2010/10/03</td><td>22:28</td><td>1,089</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-H2.html</td><td>2010/10/03</td><td>22:28</td><td>872</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-V2H2.html</td><td>2010/10/03</td><td>22:28</td><td>1,088</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-V3.html</td><td>2010/10/03</td><td>22:28</td><td>996</td><td>mobile/tests</td></tr>
-<tr><td>test_ajax-html.html</td><td>2010/10/05</td><td>21:09</td><td>1,505</td><td>mobile/tests</td></tr>
-<tr><td>test_ajax-json.html</td><td>2010/10/05</td><td>21:08</td><td>1,505</td><td>mobile/tests</td></tr>
-<tr><td>test_anchor-label.html</td><td>2010/10/05</td><td>21:08</td><td>2,959</td><td>mobile/tests</td></tr>
-<tr><td>test_bookmarkable.html</td><td>2010/10/05</td><td>21:09</td><td>4,443</td><td>mobile/tests</td></tr>
-<tr><td>test_buttons.html</td><td>2010/10/05</td><td>21:08</td><td>972</td><td>mobile/tests</td></tr>
-<tr><td>test_css-sprite.html</td><td>2010/10/05</td><td>21:09</td><td>5,779</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-icons.html</td><td>2010/10/05</td><td>21:08</td><td>2,080</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-items.html</td><td>2010/10/05</td><td>21:08</td><td>3,375</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-view.html</td><td>2010/10/05</td><td>21:09</td><td>1,657</td><td>mobile/tests</td></tr>
-<tr><td>test_hash-parameter.html</td><td>2010/10/05</td><td>21:09</td><td>2,679</td><td>mobile/tests</td></tr>
-<tr><td>test_iPad-Settings-fixed.html</td><td>2010/10/03</td><td>22:28</td><td>8,866</td><td>mobile/tests</td></tr>
-<tr><td>test_iPad-Settings.html</td><td>2010/10/03</td><td>22:28</td><td>6,904</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Animation.html</td><td>2010/10/05</td><td>21:08</td><td>3,343</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Button.html</td><td>2010/10/05</td><td>21:09</td><td>1,766</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,135</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,809</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,613</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Heading.html</td><td>2010/10/05</td><td>21:08</td><td>1,136</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,588</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconMulti.html</td><td>2010/10/05</td><td>21:08</td><td>1,863</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconSingle.html</td><td>2010/10/05</td><td>21:09</td><td>1,814</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconSingleBelow.html</td><td>2010/10/05</td><td>21:08</td><td>1,815</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-ResultList.html</td><td>2010/10/05</td><td>21:08</td><td>2,708</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-RoundRect.html</td><td>2010/10/05</td><td>21:08</td><td>1,155</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,136</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Settings.html</td><td>2010/10/05</td><td>21:09</td><td>5,666</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>998</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,262</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,550</td><td>mobile/tests</td></tr>
-<tr><td>test_progress-indicator.html</td><td>2010/10/05</td><td>21:08</td><td>3,124</td><td>mobile/tests</td></tr>
-<tr><td>test_transition-to-dynamic-view.html</td><td>2010/10/05</td><td>21:08</td><td>2,525</td><td>mobile/tests</td></tr>
-<tr><td>view-sample.html</td><td>2010/05/06</td><td>20:30</td><td>1,724</td><td>mobile/tests</td></tr>
-<tr><td>view1.html</td><td>2010/05/06</td><td>20:28</td><td>378</td><td>mobile/tests</td></tr>
-<tr><td>view1.json</td><td>2010/05/28</td><td>00:30</td><td>371</td><td>mobile/tests</td></tr>
-<tr><td>view2.html</td><td>2010/05/06</td><td>21:20</td><td>619</td><td>mobile/tests</td></tr>
-<tr><td>view2.json</td><td>2010/05/28</td><td>00:30</td><td>737</td><td>mobile/tests</td></tr>
-<tr><td>view3.html</td><td>2010/10/05</td><td>21:09</td><td>963</td><td>mobile/tests</td></tr>
-<tr><td>view3.json</td><td>2010/10/05</td><td>21:09</td><td>1,054</td><td>mobile/tests</td></tr>
-<tr><td>widget-bg.png</td><td>2010/03/23</td><td>13:03</td><td>26,234</td><td>mobile/tests/images</td></tr>
-			</table>
-		</div>
-		<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">Application Footer Bar</h1>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-hv-vh-vf.html b/dojox/mobile/tests/test_iPhone-ScrollableView-hv-vh-vf.html
deleted file mode 100644
index 2e322e4..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-hv-vh-vf.html
+++ /dev/null
@@ -1,121 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-hv-vh-vf</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		td {
-			white-space: nowrap;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true" scrollDir="hv">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
-			<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;background-color:white;">
-<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>644</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-3.png</td><td>2010/04/13</td><td>06:37</td><td>1,346</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>677</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-10.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>680</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-3.png</td><td>2010/03/23</td><td>13:03</td><td>682</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>697</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-5.png</td><td>2010/03/23</td><td>13:03</td><td>693</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-6.png</td><td>2010/03/23</td><td>13:03</td><td>694</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-7.png</td><td>2010/03/23</td><td>13:03</td><td>691</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-8.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-9.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-all.png</td><td>2010/03/23</td><td>13:03</td><td>4,450</td><td>mobile/tests/images</td></tr>
-<tr><td>icon-1.png</td><td>2010/05/06</td><td>08:57</td><td>2,626</td><td>mobile/tests/images</td></tr>
-<tr><td>not-images.png</td><td>2010/04/13</td><td>06:37</td><td>18,459</td><td>mobile/tests/images</td></tr>
-<tr><td>red-button-bg.png</td><td>2010/04/13</td><td>06:37</td><td>178</td><td>mobile/tests/images</td></tr>
-<tr><td>red-button-sel-bg.png</td><td>2010/04/13</td><td>06:37</td><td>185</td><td>mobile/tests/images</td></tr>
-<tr><td>test_Android-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,750</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,835</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,615</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,634</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,142</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Settings.html</td><td>2010/10/05</td><td>21:08</td><td>4,375</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>1,000</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,031</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,570</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-H2-prog.html</td><td>2010/10/03</td><td>22:28</td><td>1,089</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-H2.html</td><td>2010/10/03</td><td>22:28</td><td>872</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-V2H2.html</td><td>2010/10/03</td><td>22:28</td><td>1,088</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-V3.html</td><td>2010/10/03</td><td>22:28</td><td>996</td><td>mobile/tests</td></tr>
-<tr><td>test_ajax-html.html</td><td>2010/10/05</td><td>21:09</td><td>1,505</td><td>mobile/tests</td></tr>
-<tr><td>test_ajax-json.html</td><td>2010/10/05</td><td>21:08</td><td>1,505</td><td>mobile/tests</td></tr>
-<tr><td>test_anchor-label.html</td><td>2010/10/05</td><td>21:08</td><td>2,959</td><td>mobile/tests</td></tr>
-<tr><td>test_bookmarkable.html</td><td>2010/10/05</td><td>21:09</td><td>4,443</td><td>mobile/tests</td></tr>
-<tr><td>test_buttons.html</td><td>2010/10/05</td><td>21:08</td><td>972</td><td>mobile/tests</td></tr>
-<tr><td>test_css-sprite.html</td><td>2010/10/05</td><td>21:09</td><td>5,779</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-icons.html</td><td>2010/10/05</td><td>21:08</td><td>2,080</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-items.html</td><td>2010/10/05</td><td>21:08</td><td>3,375</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-view.html</td><td>2010/10/05</td><td>21:09</td><td>1,657</td><td>mobile/tests</td></tr>
-<tr><td>test_hash-parameter.html</td><td>2010/10/05</td><td>21:09</td><td>2,679</td><td>mobile/tests</td></tr>
-<tr><td>test_iPad-Settings-fixed.html</td><td>2010/10/03</td><td>22:28</td><td>8,866</td><td>mobile/tests</td></tr>
-<tr><td>test_iPad-Settings.html</td><td>2010/10/03</td><td>22:28</td><td>6,904</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Animation.html</td><td>2010/10/05</td><td>21:08</td><td>3,343</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Button.html</td><td>2010/10/05</td><td>21:09</td><td>1,766</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,135</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,809</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,613</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Heading.html</td><td>2010/10/05</td><td>21:08</td><td>1,136</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,588</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconMulti.html</td><td>2010/10/05</td><td>21:08</td><td>1,863</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconSingle.html</td><td>2010/10/05</td><td>21:09</td><td>1,814</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconSingleBelow.html</td><td>2010/10/05</td><td>21:08</td><td>1,815</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-ResultList.html</td><td>2010/10/05</td><td>21:08</td><td>2,708</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-RoundRect.html</td><td>2010/10/05</td><td>21:08</td><td>1,155</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,136</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Settings.html</td><td>2010/10/05</td><td>21:09</td><td>5,666</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>998</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,262</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,550</td><td>mobile/tests</td></tr>
-<tr><td>test_progress-indicator.html</td><td>2010/10/05</td><td>21:08</td><td>3,124</td><td>mobile/tests</td></tr>
-<tr><td>test_transition-to-dynamic-view.html</td><td>2010/10/05</td><td>21:08</td><td>2,525</td><td>mobile/tests</td></tr>
-<tr><td>view-sample.html</td><td>2010/05/06</td><td>20:30</td><td>1,724</td><td>mobile/tests</td></tr>
-<tr><td>view1.html</td><td>2010/05/06</td><td>20:28</td><td>378</td><td>mobile/tests</td></tr>
-<tr><td>view1.json</td><td>2010/05/28</td><td>00:30</td><td>371</td><td>mobile/tests</td></tr>
-<tr><td>view2.html</td><td>2010/05/06</td><td>21:20</td><td>619</td><td>mobile/tests</td></tr>
-<tr><td>view2.json</td><td>2010/05/28</td><td>00:30</td><td>737</td><td>mobile/tests</td></tr>
-<tr><td>view3.html</td><td>2010/10/05</td><td>21:09</td><td>963</td><td>mobile/tests</td></tr>
-<tr><td>view3.json</td><td>2010/10/05</td><td>21:09</td><td>1,054</td><td>mobile/tests</td></tr>
-<tr><td>widget-bg.png</td><td>2010/03/23</td><td>13:03</td><td>26,234</td><td>mobile/tests/images</td></tr>
-			</table>
-			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">View Footer Bar</h1>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-hv.html b/dojox/mobile/tests/test_iPhone-ScrollableView-hv.html
deleted file mode 100644
index d9c7e70..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-hv.html
+++ /dev/null
@@ -1,120 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-hv</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		td {
-			white-space: nowrap;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true" scrollDir="hv">
-			<!-- h1 dojoType="dojox.mobile.Heading" fixed="top">Animations</h1 -->
-			<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;background-color:white;">
-<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>644</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-3.png</td><td>2010/04/13</td><td>06:37</td><td>1,346</td><td>mobile/tests/images</td></tr>
-<tr><td>a-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>677</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-10.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>680</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-3.png</td><td>2010/03/23</td><td>13:03</td><td>682</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>697</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-5.png</td><td>2010/03/23</td><td>13:03</td><td>693</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-6.png</td><td>2010/03/23</td><td>13:03</td><td>694</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-7.png</td><td>2010/03/23</td><td>13:03</td><td>691</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-8.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-9.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
-<tr><td>i-icon-all.png</td><td>2010/03/23</td><td>13:03</td><td>4,450</td><td>mobile/tests/images</td></tr>
-<tr><td>icon-1.png</td><td>2010/05/06</td><td>08:57</td><td>2,626</td><td>mobile/tests/images</td></tr>
-<tr><td>not-images.png</td><td>2010/04/13</td><td>06:37</td><td>18,459</td><td>mobile/tests/images</td></tr>
-<tr><td>red-button-bg.png</td><td>2010/04/13</td><td>06:37</td><td>178</td><td>mobile/tests/images</td></tr>
-<tr><td>red-button-sel-bg.png</td><td>2010/04/13</td><td>06:37</td><td>185</td><td>mobile/tests/images</td></tr>
-<tr><td>test_Android-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,750</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,835</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,615</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,634</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,142</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Settings.html</td><td>2010/10/05</td><td>21:08</td><td>4,375</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>1,000</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,031</td><td>mobile/tests</td></tr>
-<tr><td>test_Android-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,570</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-H2-prog.html</td><td>2010/10/03</td><td>22:28</td><td>1,089</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-H2.html</td><td>2010/10/03</td><td>22:28</td><td>872</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-V2H2.html</td><td>2010/10/03</td><td>22:28</td><td>1,088</td><td>mobile/tests</td></tr>
-<tr><td>test_FixedSplitter-V3.html</td><td>2010/10/03</td><td>22:28</td><td>996</td><td>mobile/tests</td></tr>
-<tr><td>test_ajax-html.html</td><td>2010/10/05</td><td>21:09</td><td>1,505</td><td>mobile/tests</td></tr>
-<tr><td>test_ajax-json.html</td><td>2010/10/05</td><td>21:08</td><td>1,505</td><td>mobile/tests</td></tr>
-<tr><td>test_anchor-label.html</td><td>2010/10/05</td><td>21:08</td><td>2,959</td><td>mobile/tests</td></tr>
-<tr><td>test_bookmarkable.html</td><td>2010/10/05</td><td>21:09</td><td>4,443</td><td>mobile/tests</td></tr>
-<tr><td>test_buttons.html</td><td>2010/10/05</td><td>21:08</td><td>972</td><td>mobile/tests</td></tr>
-<tr><td>test_css-sprite.html</td><td>2010/10/05</td><td>21:09</td><td>5,779</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-icons.html</td><td>2010/10/05</td><td>21:08</td><td>2,080</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-items.html</td><td>2010/10/05</td><td>21:08</td><td>3,375</td><td>mobile/tests</td></tr>
-<tr><td>test_dynamic-view.html</td><td>2010/10/05</td><td>21:09</td><td>1,657</td><td>mobile/tests</td></tr>
-<tr><td>test_hash-parameter.html</td><td>2010/10/05</td><td>21:09</td><td>2,679</td><td>mobile/tests</td></tr>
-<tr><td>test_iPad-Settings-fixed.html</td><td>2010/10/03</td><td>22:28</td><td>8,866</td><td>mobile/tests</td></tr>
-<tr><td>test_iPad-Settings.html</td><td>2010/10/03</td><td>22:28</td><td>6,904</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Animation.html</td><td>2010/10/05</td><td>21:08</td><td>3,343</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Button.html</td><td>2010/10/05</td><td>21:09</td><td>1,766</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,135</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,809</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,613</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Heading.html</td><td>2010/10/05</td><td>21:08</td><td>1,136</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,588</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconMulti.html</td><td>2010/10/05</td><td>21:08</td><td>1,863</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconSingle.html</td><td>2010/10/05</td><td>21:09</td><td>1,814</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-IconSingleBelow.html</td><td>2010/10/05</td><td>21:08</td><td>1,815</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-ResultList.html</td><td>2010/10/05</td><td>21:08</td><td>2,708</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-RoundRect.html</td><td>2010/10/05</td><td>21:08</td><td>1,155</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,136</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Settings.html</td><td>2010/10/05</td><td>21:09</td><td>5,666</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>998</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,262</td><td>mobile/tests</td></tr>
-<tr><td>test_iPhone-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,550</td><td>mobile/tests</td></tr>
-<tr><td>test_progress-indicator.html</td><td>2010/10/05</td><td>21:08</td><td>3,124</td><td>mobile/tests</td></tr>
-<tr><td>test_transition-to-dynamic-view.html</td><td>2010/10/05</td><td>21:08</td><td>2,525</td><td>mobile/tests</td></tr>
-<tr><td>view-sample.html</td><td>2010/05/06</td><td>20:30</td><td>1,724</td><td>mobile/tests</td></tr>
-<tr><td>view1.html</td><td>2010/05/06</td><td>20:28</td><td>378</td><td>mobile/tests</td></tr>
-<tr><td>view1.json</td><td>2010/05/28</td><td>00:30</td><td>371</td><td>mobile/tests</td></tr>
-<tr><td>view2.html</td><td>2010/05/06</td><td>21:20</td><td>619</td><td>mobile/tests</td></tr>
-<tr><td>view2.json</td><td>2010/05/28</td><td>00:30</td><td>737</td><td>mobile/tests</td></tr>
-<tr><td>view3.html</td><td>2010/10/05</td><td>21:09</td><td>963</td><td>mobile/tests</td></tr>
-<tr><td>view3.json</td><td>2010/10/05</td><td>21:09</td><td>1,054</td><td>mobile/tests</td></tr>
-<tr><td>widget-bg.png</td><td>2010/03/23</td><td>13:03</td><td>26,234</td><td>mobile/tests/images</td></tr>
-			</table>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-short-inp.html b/dojox/mobile/tests/test_iPhone-ScrollableView-short-inp.html
deleted file mode 100644
index 4d29717..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-short-inp.html
+++ /dev/null
@@ -1,84 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v-vh-vf</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					<input value="1">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					<input value="2">
-				</li>
-			</ul>
-			<h1 onclick="dijit.byNode(this).goTo('bar')" dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">View Footer Bar</h1>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">Another View Footer Bar</h1>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-short.html b/dojox/mobile/tests/test_iPhone-ScrollableView-short.html
deleted file mode 100644
index 08a0301..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-short.html
+++ /dev/null
@@ -1,84 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v-vh-vf</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide 1
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip 2
-				</li>
-			</ul>
-			<h1 onclick="dijit.byNode(this).goTo('bar')" dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">View Footer Bar</h1>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">Another View Footer Bar</h1>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af-inp.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af-inp.html
deleted file mode 100644
index ab006c7..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af-inp.html
+++ /dev/null
@@ -1,172 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v-ah-af</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Application Header Bar</h1>
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<div dojoType="dojox.mobile.RoundRect">
-				scrollDir: vertical<br>
-				header: application-header<br>
-				footer: application-footer<br>
-			</div>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					<input value="1">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					<input value="2">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					<input value="3">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
-					<input value="4">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
-					<input value="5">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
-					<input value="6">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="7">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="8">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="9">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					<input value="10">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					<input value="11">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					<input value="12">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
-					<input value="13">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
-					<input value="14">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
-					<input value="15">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="16">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="17">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="18">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="19">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="20">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="21">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="22">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="23">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="24">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="25">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="26">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="27">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="28">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="29">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="30">
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-		<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">Application Footer Bar</h1>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af.html
deleted file mode 100644
index b1da855..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af.html
+++ /dev/null
@@ -1,163 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v-ah-af</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Application Header Bar</h1>
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<div dojoType="dojox.mobile.RoundRect">
-				scrollDir: vertical<br>
-				header: application-header<br>
-				footer: application-footer<br>
-			</div>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide 1
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip 2
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade 3
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
-					Slide 4
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
-					Flip 5
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
-					Fade 6
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 7
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 8
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 9
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide 10
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip 11
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade 12
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
-					Slide 13
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
-					Flip 14
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
-					Fade 15
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 16
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 17
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 18
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 19
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 20
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 21
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 22
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 23
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 24
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 25
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 26
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 27
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-		<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">Application Footer Bar</h1>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-inp.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-inp.html
deleted file mode 100644
index 91b5586..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-inp.html
+++ /dev/null
@@ -1,171 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<div dojoType="dojox.mobile.RoundRect">
-				scrollDir: vertical<br>
-				header: none<br>
-				footer: none<br>
-			</div>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					<input value="1">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					<input value="2">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					<input value="3">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
-					<input value="4">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
-					<input value="5">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
-					<input value="6">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="7">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="8">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="9">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					<input value="10">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					<input value="11">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					<input value="12">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
-					<input value="13">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
-					<input value="14">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
-					<input value="15">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="16">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="17">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="18">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="19">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="20">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="21">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="22">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="23">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="24">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="25">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="26">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="27">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="28">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="29">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="30">
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" back="Home">
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-af-inp.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-af-inp.html
deleted file mode 100644
index d07f9de..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-af-inp.html
+++ /dev/null
@@ -1,173 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v-vh-af</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<div dojoType="dojox.mobile.RoundRect">
-				scrollDir: vertical<br>
-				header: view-header<br>
-				footer: application-footer<br>
-			</div>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					<input value="1">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					<input value="2">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					<input value="3">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
-					<input value="4">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
-					<input value="5">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
-					<input value="6">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="7">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="8">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="9">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					<input value="10">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					<input value="11">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					<input value="12">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
-					<input value="13">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
-					<input value="14">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
-					<input value="15">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="16">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="17">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="18">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="19">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="20">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="21">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="22">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="23">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="24">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="25">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="26">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="27">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="28">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="29">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="30">
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-		<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">Application Footer Bar</h1>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-af.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-af.html
deleted file mode 100644
index 3247e1f..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-af.html
+++ /dev/null
@@ -1,164 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v-vh-af</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<div dojoType="dojox.mobile.RoundRect">
-				scrollDir: vertical<br>
-				header: view-header<br>
-				footer: application-footer<br>
-			</div>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide 1
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip 2
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade 3
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
-					Slide 4
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
-					Flip 5
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
-					Fade 6
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 7
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 8
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 9
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide 10
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip 11
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade 12
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
-					Slide 13
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
-					Flip 14
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
-					Fade 15
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 16
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 17
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 18
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 19
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 20
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 21
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 22
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 23
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 24
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 25
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 26
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 27
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-		<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">Application Footer Bar</h1>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-inp.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-inp.html
deleted file mode 100644
index 931d8c5..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-inp.html
+++ /dev/null
@@ -1,172 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v-vh</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<div dojoType="dojox.mobile.RoundRect">
-				scrollDir: vertical<br>
-				header: view-header<br>
-				footer: none<br>
-			</div>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					<input value="1">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					<input value="2">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					<input value="3">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
-					<input value="4">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
-					<input value="5">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
-					<input value="6">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="7">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="8">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="9">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					<input value="10">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					<input value="11">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					<input value="12">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
-					<input value="13">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
-					<input value="14">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
-					<input value="15">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="16">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="17">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="18">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="19">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="20">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="21">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="22">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="23">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="24">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="25">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="26">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="27">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="28">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="29">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="30">
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-vf-inp.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-vf-inp.html
deleted file mode 100644
index a7db815..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-vf-inp.html
+++ /dev/null
@@ -1,174 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v-vh-vf</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<div dojoType="dojox.mobile.RoundRect">
-				scrollDir: vertical<br>
-				header: view-header<br>
-				footer: view-footer<br>
-			</div>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					<input value="1">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					<input value="2">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					<input value="3">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
-					<input value="4">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
-					<input value="5">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
-					<input value="6">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="7">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="8">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="9">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					<input value="10">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					<input value="11">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					<input value="12">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
-					<input value="13">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
-					<input value="14">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
-					<input value="15">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="16">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="17">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="18">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="19">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="20">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="21">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="22">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="23">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="24">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="25">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="26">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="27">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png">
-					<input value="28">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png">
-					<input value="29">
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png">
-					<input value="30">
-				</li>
-			</ul>
-			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">View Footer Bar</h1>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">Another View Footer Bar</h1>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-vf.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-vf.html
deleted file mode 100644
index 9781cda..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-vf.html
+++ /dev/null
@@ -1,165 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v-vh-vf</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<div dojoType="dojox.mobile.RoundRect">
-				scrollDir: vertical<br>
-				header: view-header<br>
-				footer: view-footer<br>
-			</div>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide 1
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip 2
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade 3
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
-					Slide 4
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
-					Flip 5
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
-					Fade 6
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 7
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 8
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 9
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide 10
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip 11
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade 12
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
-					Slide 13
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
-					Flip 14
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
-					Fade 15
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 16
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 17
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 18
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 19
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 20
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 21
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 22
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 23
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 24
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 25
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 26
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 27
-				</li>
-			</ul>
-			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">View Footer Bar</h1>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">Another View Footer Bar</h1>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh.html
deleted file mode 100644
index 490cffc..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh.html
+++ /dev/null
@@ -1,163 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v-vh</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<div dojoType="dojox.mobile.RoundRect">
-				scrollDir: vertical<br>
-				header: view-header<br>
-				footer: none<br>
-			</div>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide 1
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip 2
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade 3
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
-					Slide 4
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
-					Flip 5
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
-					Fade 6
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 7
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 8
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 9
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide 10
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip 11
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade 12
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
-					Slide 13
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
-					Flip 14
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
-					Fade 15
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 16
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 17
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 18
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 19
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 20
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 21
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 22
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 23
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 24
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 25
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 26
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 27
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v.html
deleted file mode 100644
index b07b3fb..0000000
--- a/dojox/mobile/tests/test_iPhone-ScrollableView-v.html
+++ /dev/null
@@ -1,162 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ScrollableView-v</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-
-			<div dojoType="dojox.mobile.RoundRect">
-				scrollDir: vertical<br>
-				header: none<br>
-				footer: none<br>
-			</div>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide 1
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip 2
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade 3
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
-					Slide 4
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
-					Flip 5
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
-					Fade 6
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 7
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 8
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 9
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
-					Slide 10
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
-					Flip 11
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
-					Fade 12
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
-					Slide 13
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
-					Flip 14
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
-					Fade 15
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 16
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 17
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 18
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 19
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 20
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 21
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 22
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 23
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 24
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
-					Slide 25
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
-					Flip 26
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
-					Fade 27
-				</li>
-			</ul>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock<br>
-					# (1199)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-					Marco Rodriguez Hardcover<br>
-					<font color="blue">Not Available</font>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-					Melissa Morgan Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$12.00 (60%)</font> In Stock<br>
-					# (1847)
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-Settings.html b/dojox/mobile/tests/test_iPhone-Settings.html
deleted file mode 100644
index 8934298..0000000
--- a/dojox/mobile/tests/test_iPhone-Settings.html
+++ /dev/null
@@ -1,167 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Settings</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="settings" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Settings</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="mac" href="test_iPhone-Icon.html">
-					Wi-Fi
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="AcmePhone" moveTo="general">
-					Carrier
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-					Sounds
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="general">
-					Brightness
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="general">
-					Wallpaper
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="general">
-					General
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="general">
-					Mail, Contacts, Calendars
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="general">
-					Phone
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="general">
-					Safari
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="general">
-					SMS/MMS
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="general">
-					iPod
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="general">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-					Store
-				</li>
-			</ul>
-		</div>
-
-		<div id="general" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">General</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					About
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2h 40m" moveTo="about">
-					Usage
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Network
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Bluetooth
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Location Services
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="1 Minute" moveTo="about">
-					Auto-Lock
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Passcode Lock
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-					Restrictions
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Home
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Date & Time					   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Keyboard					   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					International				   
-				</li>							   
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Accessibility
-				</li>
-			</ul>
-
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="about">
-					Reset
-				</li>
-			</ul>
-		</div>
-
-		<div id="about" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="General" moveTo="general">About</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Network											   
-				</li>												   
-				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-					Line
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="1024">
-					Songs
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="10">
-					Videos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="96">
-					Photos
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="2">
-					Applications
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-					Capacity
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-					Available
-				</li>
-				<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-					Version
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-SwapView-demo-async.html b/dojox/mobile/tests/test_iPhone-SwapView-demo-async.html
deleted file mode 100644
index 0bd141c..0000000
--- a/dojox/mobile/tests/test_iPhone-SwapView-demo-async.html
+++ /dev/null
@@ -1,219 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>SwapView</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/PageIndicator.css" rel="stylesheet">
-		<link href="../themes/common/FixedSplitter.css" rel="stylesheet">
-		<link href="../themes/common/domButtons.css" rel="stylesheet">
-		<style>
-		html,body{
-			height: 100%;
-			overflow: hidden;
-			position: relative;
-		}
-		.subtitle {
-			color: gray;
-			font-size: 12px;
-		}
-		#news {
-			font-size: 14px;
-		}
-		.list1 li{
-		}
-		.list1 li:nth-child(even){
-			background-color: #EAEAEA;
-		}
-		.list1 .mblListItemTextBox {
-			padding-right: 5px;
-		}
-		.c1 {
-			width: 100px;
-			float: left;
-		}
-		.c2 {
-			width: 80px;
-			text-align: right;
-			float: left;
-		}
-		.c3 {
-			text-align: right;
-			width: 70px;
-			color: white;
-			padding: 0px 4px;
-			margin-top: 4px;
-			height: 30px;
-			line-height: 32px;
-			float: right;
-			-webkit-border-radius: 4px;
-			-moz-border-radius: 4px;
-		}
-		.c3a {
-			border: 2px solid #598F3A;
-			background-color: #6FB248;
-			background-image: -webkit-gradient(linear, left top, left bottom, from(#6FB248), to(#54972D), color-stop(0.5, #5FA238), color-stop(0.5, #54972D));
-		}
-		.c3b {
-			border: 2px solid #9B322D;
-			background-color: #C13E37;
-			background-image: -webkit-gradient(linear, left top, left bottom, from(#C13E37), to(#A6231C), color-stop(0.5, #B6332C), color-stop(0.5, #A8251E));
-		}
-		#tbl1 {
-			margin: auto;
-		}
-		#tbl1 td {
-			text-align: right;
-			border-bottom: 1px solid #DEE9F5;
-			font: bold 13px arial,helvetica,clean,sans-serif;
-		}
-		#tbl1 td:first-child {
-			text-align: left;
-		}
-		#tbl1 td.g {
-			color: #008800
-		}
-		#tbl1 td.r {
-			color: #CC0000
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async: true, mblAlwaysHideAddressBar: true"></script>
-		<script language="JavaScript" type="text/javascript">
-		require([
-			"dojox/mobile/parser", 	// This mobile app uses declarative programming with fast mobile parser
-			"dojox/mobile",			// This is a mobile app.
-			"dojox/mobile/FixedSplitter",
-			"dojox/mobile/ScrollableView",
-			"dojox/mobile/SwapView",
-			"dojox/mobile/PageIndicator",
-			"dojox/mobile/compat" 	// This mobile app supports running on desktop browsers
-			// "domReady!" // Enable if user code placed in the callback here that needs DOMReady
-		]);
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojoType="dojox.mobile.FixedSplitter" orientation="V">
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="height:50%;overflow:hidden;">
-				<div id="general" dojoType="dojox.mobile.ScrollableView" height="inherit">
-					<ul dojoType="dojox.mobile.RoundRectList" class="list1" stateful="true">
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Gold</div>
-							<div class="c2">3,400.20</div>
-							<div class="c3 c3a">+1.57%</div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Oil</div>
-							<div class="c2">347.26</div>
-							<div class="c3 c3b">-0.82%</div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Commodities</div>
-							<div class="c2">541.77</div>
-							<div class="c3 c3b">-0.43%</div>
-							
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Silver</div>
-							<div class="c2">12,823.94</div>
-							<div class="c3 c3a">+0.17%</div>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Soybeans</div>
-							<div class="c2">18.19</div>
-							<div class="c3 c3a">+2.77%</div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Wheat</div>
-							<div class="c2">3,335</div>
-							<div class="c3 c3a">+1.62%</div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Corn</div>
-							<div class="c2">29,930</div>
-							<div class="c3 c3a">+1.15%</div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Sugar</div>
-							<div class="c2">172.15</div>
-							<div class="c3 c3a">+0.00%</div>
-						</li>
-					</ul>
-				</div>
-			</div>
-
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="height:10px;overflow:hidden;">
-			</div>
-
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="overflow:hidden;">
-				<div id="swap1" dojoType="dojox.mobile.SwapView">
-					<div dojoType="dojox.mobile.ScrollableView" height="100%">
-						<ul id="news" dojoType="dojox.mobile.RoundRectList">
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Oil prices rise as dollar weakens
-								<div class="subtitle">Daily News - 2011/05/02 15:40</div>
-							</li>
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Same Old Story For Air Service Costs
-								<div class="subtitle">Daily News - 2011/05/02 14:30</div>
-							</li>
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Local stocks mixed despite new trade data
-								<div class="subtitle">Daily News - 2011/05/02 14:10</div>
-							</li>
-
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Stocks point higher after economic data
-								<div class="subtitle">Daily News - 2011/05/02 11:00</div>
-							</li>
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Wall St seen higher after industry forecasts
-								<div class="subtitle">Daily News - 2011/05/01 16:05</div>
-							</li>
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Stocks drop on slower job creation
-								<div class="subtitle">Daily News - 2011/05/01 15:50</div>
-							</li>
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Dollar initially falls after revised jobs report
-								<div class="subtitle">Daily News - 2011/05/01 13:20</div>
-							</li>
-						</ul>
-					</div>
-				</div>
-
-				<div id="swap2" dojoType="dojox.mobile.SwapView">
-					<div dojoType="dojox.mobile.ScrollableView" height="100%">
-						<div dojoType="dojox.mobile.RoundRect" style="position:relative;">
-						<table id="tbl1" cellpadding="0" cellspacing="0" width="90%">
-							<tr><td>2 Yr Bond</td><td>113.75</td><td>0.00</td><td class="g">0.00%</td></tr>
-							<tr><td>N225</td><td>10,004.20</td><td>154.46</td><td class="g">1.57%</td></tr>
-							<tr><td>JKSE</td><td>3,816.44</td><td>32.87</td><td class="r">-0.85%</td></tr>
-							<tr><td>Seoul</td><td>2,200.73</td><td>28.23</td><td class="g">1.27%</td></tr>
-							<tr><td>TW</td><td>8,946.08</td><td>61.79</td><td class="r">-0.69%</td></tr>
-							<tr><td>Tokyo</td><td>2,932.19</td><td>20.68</td><td class="r">-0.71%</td></tr>
-							<tr><td>All</td><td>4,854.70</td><td>41.50</td><td class="r">-0.85%</td></tr>
-						</table>
-						</div>
-					</div>
-				</div>
-
-				<div id="swap3" dojoType="dojox.mobile.SwapView">
-					<div dojoType="dojox.mobile.ScrollableView" height="100%">
-						<div dojoType="dojox.mobile.RoundRect" style="overflow:hidden">
-							<img src="images/chart.png">
-						</div>
-					</div>
-				</div>
-
-				<div dojoType="dojox.mobile.PageIndicator" fixed="bottom"></div>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-SwapView-demo.html b/dojox/mobile/tests/test_iPhone-SwapView-demo.html
deleted file mode 100644
index 1c5300b..0000000
--- a/dojox/mobile/tests/test_iPhone-SwapView-demo.html
+++ /dev/null
@@ -1,217 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>SwapView</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/PageIndicator.css" rel="stylesheet">
-		<link href="../themes/common/FixedSplitter.css" rel="stylesheet">
-		<link href="../themes/common/domButtons.css" rel="stylesheet">
-		<style>
-		html,body{
-			height: 100%;
-			overflow: hidden;
-			position: relative;
-		}
-		.subtitle {
-			color: gray;
-			font-size: 12px;
-		}
-		#news {
-			font-size: 14px;
-		}
-		.list1 li{
-		}
-		.list1 li:nth-child(even){
-			background-color: #EAEAEA;
-		}
-		.list1 .mblListItemTextBox {
-			padding-right: 5px;
-		}
-		.c1 {
-			width: 100px;
-			float: left;
-		}
-		.c2 {
-			width: 80px;
-			text-align: right;
-			float: left;
-		}
-		.c3 {
-			text-align: right;
-			width: 70px;
-			color: white;
-			padding: 0px 4px;
-			margin-top: 4px;
-			height: 30px;
-			line-height: 32px;
-			float: right;
-			-webkit-border-radius: 4px;
-			-moz-border-radius: 4px;
-		}
-		.c3a {
-			border: 2px solid #598F3A;
-			background-color: #6FB248;
-			background-image: -webkit-gradient(linear, left top, left bottom, from(#6FB248), to(#54972D), color-stop(0.5, #5FA238), color-stop(0.5, #54972D));
-		}
-		.c3b {
-			border: 2px solid #9B322D;
-			background-color: #C13E37;
-			background-image: -webkit-gradient(linear, left top, left bottom, from(#C13E37), to(#A6231C), color-stop(0.5, #B6332C), color-stop(0.5, #A8251E));
-		}
-		#tbl1 {
-			margin: auto;
-		}
-		#tbl1 td {
-			text-align: right;
-			border-bottom: 1px solid #DEE9F5;
-			font: bold 13px arial,helvetica,clean,sans-serif;
-		}
-		#tbl1 td:first-child {
-			text-align: left;
-		}
-		#tbl1 td.g {
-			color: #008800
-		}
-		#tbl1 td.r {
-			color: #CC0000
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.FixedSplitter");
-			dojo.require("dojox.mobile.SwapView");
-			dojo.require("dojox.mobile.PageIndicator");
-			dojo.require("dojox.mobile.ScrollableView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojoType="dojox.mobile.FixedSplitter" orientation="V">
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="height:50%;overflow:hidden;">
-				<div id="general" dojoType="dojox.mobile.ScrollableView" height="inherit">
-					<ul dojoType="dojox.mobile.RoundRectList" class="list1" stateful="true">
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Gold</div>
-							<div class="c2">3,400.20</div>
-							<div class="c3 c3a">+1.57%</div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Oil</div>
-							<div class="c2">347.26</div>
-							<div class="c3 c3b">-0.82%</div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Commodities</div>
-							<div class="c2">541.77</div>
-							<div class="c3 c3b">-0.43%</div>
-							
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Silver</div>
-							<div class="c2">12,823.94</div>
-							<div class="c3 c3a">+0.17%</div>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Soybeans</div>
-							<div class="c2">18.19</div>
-							<div class="c3 c3a">+2.77%</div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Wheat</div>
-							<div class="c2">3,335</div>
-							<div class="c3 c3a">+1.62%</div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Corn</div>
-							<div class="c2">29,930</div>
-							<div class="c3 c3a">+1.15%</div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="#">
-							<div class="c1">Sugar</div>
-							<div class="c2">172.15</div>
-							<div class="c3 c3a">+0.00%</div>
-						</li>
-					</ul>
-				</div>
-			</div>
-
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="height:10px;overflow:hidden;">
-			</div>
-
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="overflow:hidden;">
-				<div id="swap1" dojoType="dojox.mobile.SwapView">
-					<div dojoType="dojox.mobile.ScrollableView" height="100%">
-						<ul id="news" dojoType="dojox.mobile.RoundRectList">
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Oil prices rise as dollar weakens
-								<div class="subtitle">Daily News - 2011/05/02 15:40</div>
-							</li>
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Same Old Story For Air Service Costs
-								<div class="subtitle">Daily News - 2011/05/02 14:30</div>
-							</li>
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Local stocks mixed despite new trade data
-								<div class="subtitle">Daily News - 2011/05/02 14:10</div>
-							</li>
-
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Stocks point higher after economic data
-								<div class="subtitle">Daily News - 2011/05/02 11:00</div>
-							</li>
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Wall St seen higher after industry forecasts
-								<div class="subtitle">Daily News - 2011/05/01 16:05</div>
-							</li>
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Stocks drop on slower job creation
-								<div class="subtitle">Daily News - 2011/05/01 15:50</div>
-							</li>
-							<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-								href="test_iPhone-ScrollableView-demo.html" hrefTarget="_blank" arrowClass="mblDomButtonBlueCircleArrow">
-								Dollar initially falls after revised jobs report
-								<div class="subtitle">Daily News - 2011/05/01 13:20</div>
-							</li>
-						</ul>
-					</div>
-				</div>
-
-				<div id="swap2" dojoType="dojox.mobile.SwapView">
-					<div dojoType="dojox.mobile.ScrollableView" height="100%">
-						<div dojoType="dojox.mobile.RoundRect" style="position:relative;">
-						<table id="tbl1" cellpadding="0" cellspacing="0" width="90%">
-							<tr><td>2 Yr Bond</td><td>113.75</td><td>0.00</td><td class="g">0.00%</td></tr>
-							<tr><td>N225</td><td>10,004.20</td><td>154.46</td><td class="g">1.57%</td></tr>
-							<tr><td>JKSE</td><td>3,816.44</td><td>32.87</td><td class="r">-0.85%</td></tr>
-							<tr><td>Seoul</td><td>2,200.73</td><td>28.23</td><td class="g">1.27%</td></tr>
-							<tr><td>TW</td><td>8,946.08</td><td>61.79</td><td class="r">-0.69%</td></tr>
-							<tr><td>Tokyo</td><td>2,932.19</td><td>20.68</td><td class="r">-0.71%</td></tr>
-							<tr><td>All</td><td>4,854.70</td><td>41.50</td><td class="r">-0.85%</td></tr>
-						</table>
-						</div>
-					</div>
-				</div>
-
-				<div id="swap3" dojoType="dojox.mobile.SwapView">
-					<div dojoType="dojox.mobile.ScrollableView" height="100%">
-						<div dojoType="dojox.mobile.RoundRect" style="overflow:hidden">
-							<img src="images/chart.png">
-						</div>
-					</div>
-				</div>
-
-				<div dojoType="dojox.mobile.PageIndicator" fixed="bottom"></div>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-SwapView-slideshow-async.html b/dojox/mobile/tests/test_iPhone-SwapView-slideshow-async.html
deleted file mode 100644
index 4bfd4da..0000000
--- a/dojox/mobile/tests/test_iPhone-SwapView-slideshow-async.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>SwapView Slideshow</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/PageIndicator.css" rel="stylesheet">
-		<style>
-		html,body{
-			height: 100%;
-			overflow: hidden;
-			margin: 0px;
-		}
-		img {
-			-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
-			width: 90%;
-		}
-		h1 {
-			background-color: #3A3A3B;
-			color: #B1B1B1;
-			font: bold 16px arial,helvetica,clean,sans-serif;
-			margin: 0px 0px 15px 0px;
-			height: 45px;
-			line-height: 45px;
-			-webkit-box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.5);
-		}
-		.mblSwapView {
-			text-align: center;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-		require([
-			"dojox/mobile/parser", 	// This mobile app uses declarative programming with fast mobile parser
-			"dojox/mobile",			// This is a mobile app.
-			"dojox/mobile/SwapView",
-			"dojox/mobile/PageIndicator",
-			"dojox/mobile/compat" 	// This mobile app supports running on desktop browsers
-			// "domReady!" // Enable if user code placed in the callback here that needs DOMReady
-		]);
-		</script>
-	</head>
-	<body style="visibility:hidden;background-color:#6D6D6D">
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>My Pictures</h1>
-			<img src="images/pic1.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>May 3, 2011</h1>
-			<img src="images/pic2.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>May 3, 2011</h1>
-			<img src="images/pic3.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>May 3, 2011</h1>
-			<img src="images/pic4.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic5.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic6.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic7.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic8.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic9.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic10.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.PageIndicator" fixed="bottom"></div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-SwapView-slideshow.html b/dojox/mobile/tests/test_iPhone-SwapView-slideshow.html
deleted file mode 100644
index 04ef8c4..0000000
--- a/dojox/mobile/tests/test_iPhone-SwapView-slideshow.html
+++ /dev/null
@@ -1,95 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>SwapView Slideshow</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/PageIndicator.css" rel="stylesheet">
-		<style>
-		html,body{
-			height: 100%;
-			overflow: hidden;
-			margin: 0px;
-		}
-		img {
-			-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
-			width: 90%;
-		}
-		h1 {
-			background-color: #3A3A3B;
-			color: #B1B1B1;
-			font: bold 16px arial,helvetica,clean,sans-serif;
-			margin: 0px 0px 15px 0px;
-			height: 45px;
-			line-height: 45px;
-			-webkit-box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.5);
-		}
-		.mblSwapView {
-			text-align: center;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.SwapView");
-			dojo.require("dojox.mobile.PageIndicator");
-		</script>
-	</head>
-	<body style="visibility:hidden;background-color:#6D6D6D">
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>My Pictures</h1>
-			<img src="images/pic1.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>May 3, 2011</h1>
-			<img src="images/pic2.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>May 3, 2011</h1>
-			<img src="images/pic3.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>May 3, 2011</h1>
-			<img src="images/pic4.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic5.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic6.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic7.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic8.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic9.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.SwapView">
-			<h1>Apr 24, 2011</h1>
-			<img src="images/pic10.jpg">
-		</div>
-
-		<div dojoType="dojox.mobile.PageIndicator" fixed="bottom"></div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-SwapView.html b/dojox/mobile/tests/test_iPhone-SwapView.html
deleted file mode 100644
index a545500..0000000
--- a/dojox/mobile/tests/test_iPhone-SwapView.html
+++ /dev/null
@@ -1,83 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>SwapView</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/IconContainer.css" rel="stylesheet">
-		<style>
-		.lnk {
-			font-size: 14px;
-			color: #0B5199;
-			text-decoration: none;
-		}
-		html,body{
-			height: 100%;
-			overflow: hidden;
-			margin: 0px;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.IconContainer");
-			dojo.require("dojox.mobile.SwapView");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="foo" dojoType="dojox.mobile.SwapView" selected="true">
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Page flipping demo</h2>
-
-			<div dojoType="dojox.mobile.RoundRect">
-				Swipe the screen left or right to flip between the views.
-				There are 4 views in this demo.
-				Vertical scrolling and page indicator are not supported.
-			</div>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.SwapView">
-			<h1 dojoType="dojox.mobile.Heading">Search Result</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock<br>
-					# (531)
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock<br>
-					# (173)
-				</li>
-			</ul>
-		</div>
-
-		<div id="icon1" dojoType="dojox.mobile.SwapView">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container 1</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="app1" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app2" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="app3" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="moveTo" icon="images/icon-1.png" moveTo="about" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="href" icon="images/icon-1.png" href="test_iPhone-RoundRectList.html" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="url" icon="images/icon-1.png" url="view-sample.html" transition="slide"></li>
-			</ul>
-		</div>
-
-		<div id="icon2" dojoType="dojox.mobile.SwapView">
-			<h1 dojoType="dojox.mobile.Heading">Icon Container 2</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="test1" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="test2" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-				<li dojoType="dojox.mobile.IconItem" label="test3" icon="images/icon-1.png" lazy="true"><div class="box"></div></li>
-			</ul>
-		</div>
-
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-Switch.html b/dojox/mobile/tests/test_iPhone-Switch.html
deleted file mode 100644
index 42c4be6..0000000
--- a/dojox/mobile/tests/test_iPhone-Switch.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Switch</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-		
-		<style>
-		.color1 .mblSwitchBgLeft {
-			background: -webkit-gradient(linear, left top, left bottom, from(#28B159), to(#75FBAC), color-stop(0.5, #3FEB84), color-stop(0.5, #4CEE8E));
-		}
-		.color1 .mblSwitchBgRight {
-			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
-		}
-		.color2 .mblSwitchBgLeft {
-			background: -webkit-gradient(linear, left top, left bottom, from(#FF9D00), to(#FFCE80), color-stop(0.5, #FFBB4D), color-stop(0.5, #FFC871));
-		}
-		.color2 .mblSwitchBgRight {
-			background: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
-		}
-		.color1 .mblSwitchKnob,
-		.color2 .mblSwitchKnob {
-			background: -webkit-gradient(linear, left top, left bottom, from(#999999), to(#FAFAFA), color-stop(0.5, #BBBBBB), color-stop(0.5, #CACACA));
-		}
-		.float {
-			float: left;
-			margin-right: 10px;
-		}
-		.bold {
-			font-weight: bold;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojoType="dojox.mobile.View" selected="true">
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Default Shape</span><br>
-				<div class="float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Round Shape 1</span><br>
-				<div class="mblSwRoundShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwRoundShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Round Shape 2</span><br>
-				<div class="mblSwRoundShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwRoundShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Arc Shape 1</span><br>
-				<div class="mblSwArcShape1 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwArcShape1 color1" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				<span class="bold">Arc Shape 2</span><br>
-				<div class="mblSwArcShape2 float" dojoType="dojox.mobile.Switch" value="off"></div>
-				<div class="mblSwArcShape2 color2" dojoType="dojox.mobile.Switch" value="on" leftLabel="Start" rightLabel="Stop"></div>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped-scroll.html b/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped-scroll.html
deleted file mode 100644
index 8f3830e..0000000
--- a/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped-scroll.html
+++ /dev/null
@@ -1,182 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>TabBar - Segmented Control</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-
-		<style>
-			html,body{
-				height: 100%;
-				overflow: hidden;
-			}
-			#list1 li{
-				border-style: solid;
-				border-width: 1px 0px 1px 0px;
-				border-top-color: #BABABC;
-				border-bottom-color: #89898C;
-				background-color: #ACACAF;
-				line-height: 0px;
-			}
-			#list1 li table{
-				line-height: normal;
-			}
-			#list1 li:nth-child(even){
-				background-color: #97979B;
-			}
-			.lnk {
-				font-size: 17px;
-				color: #0B5199;
-				text-decoration: none;
-			}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.ScrollableView");
-			dojo.require("dojox.mobile.TabBar");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="group1" dojoType="dojox.mobile.View" selected="true">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" fixed="top">
-				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-			</ul>
-
-			<div id="view1" dojoType="dojox.mobile.ScrollableView" selected="true">
-				<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list1">
-					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-						<table>
-							<tbody>
-								<tr>
-									<td>
-										<img src="images/icon-1.png">
-									</td>
-									<td>
-										<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-										Sarah Connor Hardcover<br>
-										Eligible for FREE Super Saver Shipping
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</li>
-					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-						<table>
-							<tbody>
-								<tr>
-									<td>
-										<img src="images/icon-1.png">
-									</td>
-									<td>
-										<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
-										Martin Parker Hardcover<br>
-										Eligible for FREE Super Saver Shipping<br>
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</li>
-					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-						<table>
-							<tbody>
-								<tr>
-									<td>
-										<img src="images/icon-1.png">
-									</td>
-									<td>
-										<a class="lnk" href="#">Total Solar Eclipse</a><br>
-										Steven Young Hardcover<br>
-										Eligible for FREE Super Saver Shipping<br>
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</li>
-					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-						<table>
-							<tbody>
-								<tr>
-									<td>
-										<img src="images/icon-1.png">
-									</td>
-									<td>
-										<a class="lnk" href="#">The History of Java Coffee</a><br>
-										Marco Rodriguez Hardcover<br>
-										Eligible for FREE Super Saver Shipping<br>
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</li>
-					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-						<table>
-							<tbody>
-								<tr>
-									<td>
-										<img src="images/icon-1.png">
-									</td>
-									<td>
-										<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-										Melissa Morgan Hardcover<br>
-										Eligible for FREE Super Saver Shipping<br>
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</li>
-				</ul>
-			</div>
-
-			<div id="view2" dojoType="dojox.mobile.ScrollableView">
-				<ul dojoType="dojox.mobile.RoundRectList">
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="hello">
-						Sounds
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="hello">
-						Brightness
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="hello">
-						Wallpaper
-					</li>
-				</ul>
-			</div>
-
-			<div id="view3" dojoType="dojox.mobile.ScrollableView">
-				<ul dojoType="dojox.mobile.RoundRectList">
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="hello">
-						General
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="hello">
-						Mail, Contacts, Calendars
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="hello">
-						Phone
-					</li>
-				</ul>
-			</div>
-		</div>
-
-		<div dojoType="dojox.mobile.ScrollableView" id="hello">
-			<h1 dojoType="dojox.mobile.Heading">
-				Hello
-			</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="group1">
-					Hello
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="group1">
-					Carrier
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped.html b/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped.html
deleted file mode 100644
index c5f7d79..0000000
--- a/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped.html
+++ /dev/null
@@ -1,177 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>TabBar - Segmented Control</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-
-		<style>
-			#list1 li{
-				border-style: solid;
-				border-width: 1px 0px 1px 0px;
-				border-top-color: #BABABC;
-				border-bottom-color: #89898C;
-				background-color: #ACACAF;
-				line-height: 0px;
-			}
-			#list1 li table{
-				line-height: normal;
-			}
-			#list1 li:nth-child(even){
-				background-color: #97979B;
-			}
-			.lnk {
-				font-size: 17px;
-				color: #0B5199;
-				text-decoration: none;
-			}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="group1" dojoType="dojox.mobile.View" selected="true">
-			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-			</ul>
-
-			<div id="view1" dojoType="dojox.mobile.View" selected="true">
-				<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list1">
-					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-						<table>
-							<tbody>
-								<tr>
-									<td>
-										<img src="images/icon-1.png">
-									</td>
-									<td>
-										<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-										Sarah Connor Hardcover<br>
-										Eligible for FREE Super Saver Shipping
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</li>
-					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-						<table>
-							<tbody>
-								<tr>
-									<td>
-										<img src="images/icon-1.png">
-									</td>
-									<td>
-										<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
-										Martin Parker Hardcover<br>
-										Eligible for FREE Super Saver Shipping<br>
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</li>
-					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-						<table>
-							<tbody>
-								<tr>
-									<td>
-										<img src="images/icon-1.png">
-									</td>
-									<td>
-										<a class="lnk" href="#">Total Solar Eclipse</a><br>
-										Steven Young Hardcover<br>
-										Eligible for FREE Super Saver Shipping<br>
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</li>
-					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-						<table>
-							<tbody>
-								<tr>
-									<td>
-										<img src="images/icon-1.png">
-									</td>
-									<td>
-										<a class="lnk" href="#">The History of Java Coffee</a><br>
-										Marco Rodriguez Hardcover<br>
-										Eligible for FREE Super Saver Shipping<br>
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</li>
-					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-						<table>
-							<tbody>
-								<tr>
-									<td>
-										<img src="images/icon-1.png">
-									</td>
-									<td>
-										<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-										Melissa Morgan Hardcover<br>
-										Eligible for FREE Super Saver Shipping<br>
-									</td>
-								</tr>
-							</tbody>
-						</table>
-					</li>
-				</ul>
-			</div>
-
-			<div id="view2" dojoType="dojox.mobile.View">
-				<ul dojoType="dojox.mobile.RoundRectList">
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="hello">
-						Sounds
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="hello">
-						Brightness
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="hello">
-						Wallpaper
-					</li>
-				</ul>
-			</div>
-
-			<div id="view3" dojoType="dojox.mobile.View">
-				<ul dojoType="dojox.mobile.RoundRectList">
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="hello">
-						General
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="hello">
-						Mail, Contacts, Calendars
-					</li>
-					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="hello">
-						Phone
-					</li>
-				</ul>
-			</div>
-		</div>
-
-		<div dojoType="dojox.mobile.View" id="hello">
-			<h1 dojoType="dojox.mobile.Heading">
-				Hello
-			</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="group1">
-					Hello
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="group1">
-					Carrier
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-TabBar-seg.html b/dojox/mobile/tests/test_iPhone-TabBar-seg.html
deleted file mode 100644
index b101769..0000000
--- a/dojox/mobile/tests/test_iPhone-TabBar-seg.html
+++ /dev/null
@@ -1,161 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>TabBar - Segmented Control</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-
-		<style>
-			#list1 li{
-				border-style: solid;
-				border-width: 1px 0px 1px 0px;
-				border-top-color: #BABABC;
-				border-bottom-color: #89898C;
-				background-color: #ACACAF;
-				line-height: 0px;
-			}
-			#list1 li table{
-				line-height: normal;
-			}
-			#list1 li:nth-child(even){
-				background-color: #97979B;
-			}
-			.lnk {
-				font-size: 17px;
-				color: #0B5199;
-				text-decoration: none;
-			}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list1">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
-									Sarah Connor Hardcover<br>
-									Eligible for FREE Super Saver Shipping
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
-									Martin Parker Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">Total Solar Eclipse</a><br>
-									Steven Young Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The History of Java Coffee</a><br>
-									Marco Rodriguez Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
-					<table>
-						<tbody>
-							<tr>
-								<td>
-									<img src="images/icon-1.png">
-								</td>
-								<td>
-									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
-									Melissa Morgan Hardcover<br>
-									Eligible for FREE Super Saver Shipping<br>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</li>
-			</ul>
-		</div>
-
-		<div id="view2" dojoType="dojox.mobile.View">
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
-					Sounds
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
-					Brightness
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
-					Wallpaper
-				</li>
-			</ul>
-		</div>
-
-		<div id="view3" dojoType="dojox.mobile.View">
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
-					General
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
-					Mail, Contacts, Calendars
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
-					Phone
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-TabBar.html b/dojox/mobile/tests/test_iPhone-TabBar.html
deleted file mode 100644
index 4c1620b..0000000
--- a/dojox/mobile/tests/test_iPhone-TabBar.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>TabBar</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<link href="../themes/iphone/TabBar.css" rel="stylesheet">
-		<style>
-		.label {
-			font-family: "Helvetica Neue", Helvetica;
-			font-size: 13px;
-			margin-top: 20px;
-		}
-		.view {
-			font-size: 30px;
-			padding-top: 30px;
-			text-align: center;
-		}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.TabBar");
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div class="label">Segmented Control</div>
-		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar</div>
-		<ul dojoType="dojox.mobile.TabBar">
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
-			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
-		</ul>
-
-		<div class="label">Tab Bar (CSS Sprite)</div>
-		<ul dojoType="dojox.mobile.TabBar" iconBase="images/tab-icons.png">
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Featured</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,29,29,29" iconPos2="29,29,29,29">Categories</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,58,29,29" iconPos2="29,58,29,29">Top 25</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,87,29,29" iconPos2="29,87,29,29">Search</li>
-			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,116,29,29" iconPos2="29,116,29,29">Updates</li>
-		</ul>
-
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<div class="view">View 1</div>
-		</div>
-		<div id="view2" dojoType="dojox.mobile.View">
-			<div class="view">View 2</div>
-		</div>
-		<div id="view3" dojoType="dojox.mobile.View">
-			<div class="view">View 3</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_iPhone-VariableHeightList.html b/dojox/mobile/tests/test_iPhone-VariableHeightList.html
deleted file mode 100755
index 8de6ba0..0000000
--- a/dojox/mobile/tests/test_iPhone-VariableHeightList.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>News</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		.content {
-			padding:0px 10px;
-			background-color: white;
-		}
-		p {
-			font-family: Helvetica;
-			font-size: 12px;
-		}
-		.title {
-			color: blue;
-			margin-bottom: 4px;
-		}
-		.subtitle {
-			font-style: italic;
-			color: gray;
-			margin: 0px;
-			margin-bottom: 4px;
-		}
-		.subsubtitle {
-			margin: 16px 0px 0px 0px;
-		}
-		.lst {
-			margin: 0px;
-			padding: 0px 14px;
-		}
-		.lst li {
-			font-family: Helvetica;
-			font-size: 12px;
-			margin: 0px;
-			list-style-type: square;
-		}
-		</style>
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.hash");
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="home" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">News</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Top Stories</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" moveTo="#article" transition="slide">
-					Top 10 news stories of the decade
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" moveTo="#article" transition="flip">
-					Create client-side diagrammatic interaction in Web applications with GFX
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" moveTo="#article" transition="fade">
-					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
-				</li>
-			</ul>
-		</div>
-
-		<div id="article" dojoType="dojox.mobile.View" style="background-color:white;height:100%">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="#home">Article</h1>
-			<div class="content">
-				<h3 class="title">Did you know?</h3>
-				<h4 class="subtitle">Features of dojox.mobile</h4>
-				<h5 class="subsubtitle">No images are used</h5>
-				<ul class="lst">
-				  	<li>UI parts consist of DOM and CSS3.</li>
-					<li>Only application icons are images.</li>
-				</ul>
-				<p>For example, none of the UI parts below are images.<br></p>
-				<img src="images/not-images.png">
-
-				<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
-				<ul class="lst">
-				  	<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
-				</ul>
-
-				<h5 class="subsubtitle">Support for CSS sprite</h5>
-				<ul class="lst">
-					<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
-				</ul>
-
-				<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
-				<ul class="lst">
-					<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
-				</ul>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_ios6.html b/dojox/mobile/tests/test_ios6.html
new file mode 100644
index 0000000..c3fb0d4
--- /dev/null
+++ b/dojox/mobile/tests/test_ios6.html
@@ -0,0 +1,102 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>iOS6 showcase</title>
+<script type="text/javascript" src="../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	require([
+	 	"dijit/registry",
+	 	"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/ScrollableView",		// This mobile app uses mobile view
+		"dojox/mobile/Heading",
+		"dojox/mobile/RoundRectList",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/Opener",
+		"dojox/mobile/SimpleDialog",
+		"dojox/mobile/Button",
+		"dojox/mobile/SpinWheelDatePicker",
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(registry) {
+ 		show = function(dlg, node){
+		    registry.byId(dlg).show(node);
+		  };
+		  hide = function(dlg){
+		    registry.byId(dlg).hide();
+		  };
+	});
+</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back: "Back", label:"Settings"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" style="float: right;">Edit</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"
+			        data-dojo-props='label:"Done",defaultColor:"mblColorBlue"'
+			        style="float:right;"></span>
+		</div>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Round Rect Category</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem">Airplane Mode
+				<div data-dojo-type="dojox.mobile.Switch" class="mblItemSwitch"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText: "IBM", moveTo: "view2"'>Wi-Fi</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo: "view2"'>Bluetooth</li>
+		</ul>
+		<div data-dojo-type="dojox.mobile.Heading" fixed="bottom">
+		</div>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Second View"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"
+			        data-dojo-props='arrow:"right",
+			                         moveTo:"view3",
+			                         transition:"slide",
+			                         transitionDir:1'
+               		style="float: right;">Next</span>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+		  This view displays a segmented control tab bar, at the bottom.
+		</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"' fixed="bottom">
+		  <li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>New</li>
+		  <li data-dojo-type="dojox.mobile.TabBarButton">What's Hot</li>
+		  <li data-dojo-type="dojox.mobile.TabBarButton">Genius</li>
+		</ul>
+	</div>
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Third View"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"
+			        data-dojo-props='arrow:"right",
+			                         moveTo:"view1",
+			                         transition:"slide",
+			                         transitionDir:1'
+               		style="float: right;">Next</span>
+		</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"standardTab"'>
+		  <li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>New</li>
+		  <li data-dojo-type="dojox.mobile.TabBarButton">What's Hot</li>
+		  <li data-dojo-type="dojox.mobile.TabBarButton">Genius</li>
+		</ul>
+
+		<button data-dojo-type="dojox.mobile.Button" onclick="show('customPicker', this.domNode)">Show Opener</button>
+		<div id="customPicker" data-dojo-type="dojox.mobile.Opener">
+		      <h1 data-dojo-type="dojox.mobile.Heading" label="Custom Picker">
+		              <div data-dojo-type="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;" onClick="hide('customPicker')"></div>
+		      </h1>
+		      <div id="spin1" data-dojo-type="dojox.mobile.SpinWheelDatePicker"></div>
+		</div>
+
+		<div id="dlg_message" data-dojo-type="dojox.mobile.SimpleDialog">
+		  <div class="mblSimpleDialogTitle">Information</div>
+		  <div class="mblSimpleDialogText">This is a sample dialog.</div>
+		  <button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton"
+		          style="width:100px;" onclick="hide('dlg_message')">OK</button>
+		</div>		
+		<button onclick="show('dlg_message')">Show Dialog</button>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_list-actions.html b/dojox/mobile/tests/test_list-actions.html
deleted file mode 100644
index 2231b72..0000000
--- a/dojox/mobile/tests/test_list-actions.html
+++ /dev/null
@@ -1,225 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>ListItem Actions</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile.deviceTheme");
-		</script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.data.ItemFileReadStore");
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.RoundRectDataList");
-			dojo.require("dojox.mobile.ScrollableView");
-			dojo.require("dojox.mobile.ContentPane");
-
-			var static_data = { 
-				items: [ 
-					{label: "Apple", moveTo: "home", icon: "images/i-icon-1.png"},
-					{label: "Banana", moveTo: "home", icon: "images/i-icon-2.png"},
-					{label: "Cherry", moveTo: "home", icon: "images/i-icon-3.png"},
-					{label: "Grape", moveTo: "home", icon: "images/i-icon-4.png"},
-					{label: "Kiwi", moveTo: "home", icon: "images/i-icon-5.png"},
-					{label: "Lemon", moveTo: "home", icon: "images/i-icon-6.png"},
-					{label: "Melon", moveTo: "home", icon: "images/i-icon-7.png"},
-					{label: "Orange", moveTo: "home", icon: "images/i-icon-8.png"},
-					{label: "Peach", moveTo: "home", icon: "images/i-icon-9.png"}
-				]
-			};
-
-			// Update existing view content and make transition
-			function myAction1(li){
-				var rect = dijit.byId("rect1");
-				rect.containerNode.innerHTML = new Date();
-				dijit.byNode(li).transitionTo("view1");
-			}
-
-			// Load content into existing view and make transition
-			function myAction2(li){
-				var view2 = dijit.byId("view2"); // destination view
-				var listItem = dijit.byNode(li);
-				var prog = dojox.mobile.ProgressIndicator.getInstance();
-				dojo.body().appendChild(prog.domNode);
-				prog.start();
-				view2.destroyDescendants();
-
-				/*
-				var url = "http://..."; // or var url = listItem.url;
-				dojo.xhrGet({
-					url: url,
-					handleAs: "text",
-					load: function(response, ioArgs){
-						var container = view2.containerNode;
-						container.innerHTML = response;
-						dojo.parser.parse(container);
-						prog.stop();
-						listItem.transitionTo("view2");
-					}
-				});
-				*/
-				setTimeout(function(){ // network latency simulation
-					var markup = '<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home">Loaded View 1</h1>' +
-						'<div dojoType="dojox.mobile.RoundRect" shadow="true">Thank you!</div>';
-					var container = view2.containerNode;
-					container.innerHTML = markup;
-					dojo.parser.parse(container);
-					prog.stop();
-					listItem.transitionTo("view2");
-				}, 5000);
-			}
-
-			// Make transition and load content into existing view
-			function myAction3(li){
-				var view3 = dijit.byId("view3"); // destination view
-				var listItem = dijit.byNode(li);
-				var prog = dojox.mobile.ProgressIndicator.getInstance();
-				dojo.body().appendChild(prog.domNode);
-				prog.start();
-				view3.destroyDescendants();
-				listItem.transitionTo("view3");
-
-				/*
-				var url = "http://..."; // or var url = listItem.url;
-				dojo.xhrGet({
-					url: url,
-					handleAs: "text",
-					load: function(response, ioArgs){
-						var container = view3.containerNode;
-						container.innerHTML = response;
-						dojo.parser.parse(container);
-						prog.stop();
-					}
-				});
-				*/
-				setTimeout(function(){ // network latency simulation
-					var markup = '<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home">Loaded View 2</h1>' +
-						'<div dojoType="dojox.mobile.RoundRect" shadow="true">Gracias!</div>';
-					var container = view3.containerNode;
-					container.innerHTML = markup;
-					dojo.parser.parse(container);
-					prog.stop();
-				}, 5000);
-			}
-
-			// Create a new view and make transition
-			function myAction4(li){
-				if(!dijit.byId("view4")){
-					var view4 = new dojox.mobile.View({
-						id: "view4",
-						selected: true
-					}, dojo.create("DIV", null, dojo.body()));
-					view4.startup();
-
-					var heading1 = new dojox.mobile.Heading({
-						label: "Dynamic View",
-						back: "Home",
-						moveTo: "home"
-					});
-					view4.addChild(heading1);
-
-					var categ1 = new dojox.mobile.RoundRectCategory({
-						label: "Documents"
-					});
-					view4.addChild(categ1);
-
-					var list1 = new dojox.mobile.RoundRectList();
-					view4.addChild(list1);
-
-					var counter = 4;
-					for(var i = 1; i <= 3; i++){
-						var item1 = new dojox.mobile.ListItem({
-							icon: "images/i-icon-"+i+".png",
-							label: "Document 000"+counter
-						});
-						list1.addChild(item1);
-						counter++;
-					}
-				}
-				dijit.byNode(li).transitionTo("view4");
-			}
-
-			// Update DataList
-			function myAction5(li){
-				var list1 = dijit.byId("list1");
-				if(!list1.store){
-					var store1 = new dojo.data.ItemFileReadStore({data: static_data});
-					list1.setStore(store1, {label: '*e'}); // items whose label ends with 'e'
-				}
-				dijit.byNode(li).transitionTo("view5");
-			}
-
-			// Partial Update using dojox.mobile.ContentPane
-			function myAction6(li){
-				var pane1 = dijit.byId("pane1");
-				if(!pane1.domNode.innerHTML){ // nothing has been loaded yet
-					dojo.connect(pane1, "onLoad", null, function(){
-						// onLoad fires when the content is ready
-						dijit.byNode(li).transitionTo("view6");
-					});
-					pane1.set("href", "fragment1.html");
-				}else{
-					dijit.byNode(li).transitionTo("view6");
-				}
-			}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="home" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Action and Transition</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">ListItem Actions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="#" transition="slide" onclick="myAction1(this)">
-					Update View
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="#" transition="slide" onclick="myAction2(this)">
-					Load and Move (async)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="#" transition="slide" onclick="myAction3(this)">
-					Move and Load (async)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="#" transition="slide" onclick="myAction4(this)">
-					Create View
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="#" transition="slide" onclick="myAction5(this)">
-					Data List
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="#" transition="slide" onclick="myAction6(this)">
-					Partial Update (async)
-				</li>
-			</ul>
-		</div>
-
-		<div id="view1" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home">Current Status</h1>
-			Local Time:
-			<div id="rect1" dojoType="dojox.mobile.RoundRect" shadow="true"></div>
-		</div>
-
-		<div id="view2" dojoType="dojox.mobile.View">
-		</div>
-
-		<div id="view3" dojoType="dojox.mobile.View">
-		</div>
-
-		<div id="view5" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading">RoundRectDataList</h1>
-			<ul id="list1" dojoType="dojox.mobile.RoundRectDataList"></ul>
-		</div>
-
-		<div id="view6" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="home" fixed="top">Partial Update</h1>
-			Dynamic Content:
-			<div id="pane1" dojoType="dojox.mobile.ContentPane"></div>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="home" transitionDir="-1">
-					Home
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_list-domButtons.html b/dojox/mobile/tests/test_list-domButtons.html
deleted file mode 100644
index 6dd7134..0000000
--- a/dojox/mobile/tests/test_list-domButtons.html
+++ /dev/null
@@ -1,227 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>List with domButtons</title>
-		<link href="../themes/common/domButtons.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.deviceTheme");
-			function setRightIcon2Value(id, val){
-				var txt = dojo.doc.createTextNode(val);
-				dijit.byId(id).rightIcon2Node.firstChild.firstChild.appendChild(txt);
-			}
-			function setIconValue(id, val){
-				var txt = dojo.doc.createTextNode(val);
-				dijit.byId(id).iconNode.firstChild.firstChild.firstChild.firstChild.appendChild(txt);
-			}
-			dojo.ready(function(){
-				setRightIcon2Value("item1", "32");
-				setRightIcon2Value("item2", "5");
-				setRightIcon2Value("item3", "108");
-				setIconValue("item42", "3");
-				dojo.forEach(dijit.byId("list1").getChildren(), function(w){
-					dojo.connect(w.iconNode, "onclick", w, function(e){
-						console.log(this);
-						dijit.byId("list1").removeChild(this);
-					});
-				});
-				dojo.forEach(dijit.byId("list5").getChildren(), function(w){
-					dojo.connect(w.iconNode, "onclick", w, function(e){
-						console.log(this);
-						dijit.byId("list5").removeChild(this);
-					});
-				});
-			});
-		</script>
-		<style>
-		#item1, #item2, #item3 {
-			font-weight: normal;
-			font-size: 12px;
-		}
-		.subject {
-			font: bold 16px Helvetica;
-		}
-		
-		/* Note: The class name of DOM buttons must start with "mblDomButton". */
-		
-		/* === My Custom Button1 ==*/
-		.mblDomButtonMyCustomButton1 {
-			position: relative;
-			width: 30px;
-			height: 30px;
-			border-width: 1px;
-			border-style: outset;
-			border-color: #A5A2A5;
-			color: white;
-			-webkit-border-radius: 3px;
-			background-color: #D6D3D6;
-			background: -webkit-gradient(linear, left top, left bottom, from(#EFF3EF), to(#BDBEBD));
-		}
-		.mblDomButtonMyCustomButton1 > DIV {
-			position: absolute;
-			top: 13px;
-			left: 5px;
-			width: 20px;
-			height: 4px;
-			margin: 0px;
-			font-size: 1px;
-			background-color: red;
-			-webkit-border-radius: 2px;
-			-webkit-transform: rotate(45deg);
-		}
-		.mblDomButtonMyCustomButton1 > DIV > DIV {
-			position: absolute;
-			top: -8px;
-			left: 8px;
-			width: 4px;
-			height: 20px;
-			margin: 0px;
-			font-size: 1px;
-			background-color: red;
-			-webkit-border-radius: 2px;
-		}
-		
-		/* === My Custom Button2 ==*/
-		.mblDomButtonMyCustomButton2 {
-			position: relative;
-			width: 29px;
-			height: 29px;
-		}
-		
-		.mblDomButtonMyCustomButton2 > DIV {
-			position: relative;
-			top: 2px;
-			left: 2px;
-			width: 22px;
-			height: 22px;
-			border: 1px solid #B5B6B5;
-			-webkit-border-radius: 12px;
-			-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
-		}
-		.mblDomButtonMyCustomButton2 > DIV > DIV {
-			position: relative;
-			top: 2px;
-			left: 2px;
-			width: 18px;
-			height: 18px;
-			-webkit-border-radius: 9px;
-			background-color: green;
-		}
-		.mblDomButtonMyCustomButton2 > DIV > DIV > DIV {
-			position: relative;
-			color: white;
-			text-align: center;
-			line-height: 17px;
-			font-size: 14px;
-		}
-		.mblDomButtonMyCustomButton2 > DIV > DIV > DIV > DIV {
-			display: none;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">View 1</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">RoundRectList</h2>
-			<ul id="list1" dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus"
-				    moveTo="view2" arrowClass="mblDomButtonSilverCircleDownArrow">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus"
-				    moveTo="view2" arrowClass="mblDomButtonSilverCircleGreenButton">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus"
-				    moveTo="view2" arrowClass="mblDomButtonSilverCircleRedCross">
-					Fade
-				</li>
-			</ul>
-		</div>
-
-		<div id="view2" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="view1">View 2</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Dom Button with Text</h2>
-			<ul id="list2" dojoType="dojox.mobile.RoundRectList">
-				<li id="item1" class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    icon="mblDomButtonBlueBall" moveTo="view3" btnClass2="mblDomButtonGrayRoundRect">
-					<div class="subject">Dojo: Traditional Karate-do Spirit</div>
-					Sarah Connor Hardcover<br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$14.50 (50%)</font> In Stock
-				</li>
-				<li id="item2" class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    icon="mblDomButtonTransparent19" moveTo="view3" btnClass2="mblDomButtonGrayRoundRect">
-					<div class="subject">Japanese Martial Arts Dojo</div>
-					Martin Parker Hardcover<br>
-					<font color="red">$14.00 (60%)</font> In Stock
-				</li>
-				<li id="item3" class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    icon="mblDomButtonGreenBall" moveTo="view3" btnClass2="mblDomButtonGrayRoundRect">
-					<div class="subject">Total Solar Eclipse</div>
-					Steven Young Hardcover<br>
-					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-					Eligible for FREE Super Saver Shipping<br>
-					<font color="red">$9.50 (62%)</font> In Stock
-				</li>
-			</ul>
-		</div>
-
-		<div id="view3" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="view2">View 3</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Variable Height List</h2>
-			<ul id="list3" dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    moveTo="view4" arrowClass="mblDomButtonBlueCircleArrow">
-					Top 10 news stories of the decade
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    moveTo="view4" arrowClass="mblDomButtonBlueCircleArrow">
-					Create client-side diagrammatic interaction in Web applications with GFX
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem"
-				    moveTo="view4" arrowClass="mblDomButtonBlueCircleArrow">
-					Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
-				</li>
-			</ul>
-		</div>
-
-		<div id="view4" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="view3">View 4</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Custom DOM Buttons</h2>
-			<ul id="list4" dojoType="dojox.mobile.RoundRectList">
-				<li id="item41" dojoType="dojox.mobile.ListItem" icon="mblDomButtonMyCustomButton1"
-				    moveTo="view5">
-					My Custom Button 1
-				</li>
-				<li id="item42" dojoType="dojox.mobile.ListItem" icon="mblDomButtonMyCustomButton2"
-				    moveTo="view5">
-					My Custom Button 2
-				</li>
-			</ul>
-		</div>
-
-		<div id="view5" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="view4">View 5</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">EdgeToEdgeList</h2>
-			<ul id="list5" dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus">
-					Airplane Mode
-					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus" rightText="mac" moveTo="view1">
-					Wi-Fi
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="mblDomButtonRedCircleMinus" rightText="AcmePhone" moveTo="view1">
-					Carrier
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_migrationAssist.html b/dojox/mobile/tests/test_migrationAssist.html
new file mode 100644
index 0000000..65ec385
--- /dev/null
+++ b/dojox/mobile/tests/test_migrationAssist.html
@@ -0,0 +1,123 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Heading</title>
+		<link href="../themes/iphone/base.css" rel="stylesheet"/>
+		<link href="../themes/iphone/TabBar.css" rel="stylesheet"/>
+		<link href="../themes/common/domButtons.css" rel="stylesheet"/>
+		<link href="../themes/common/FixedSplitter.css" rel="stylesheet"/>
+		<link href="../themes/common/SpinWheel.css" rel="stylesheet"/>
+
+		<link href="../themes/iphone/SpinWheel.css" rel="stylesheet"/>
+
+		<style type="text/css">
+			@import "../themes/common/FixedSplitter.css";
+			@import "../themes/common/SpinWheel.css";
+		</style>
+
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojox.mobile");			// This is a mobile app.
+			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
+			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
+			dojo.require("dojox.mobile.TabBar");
+			dojo.require("dojox.mobile.Heading");
+			dojo.require("dojox.mobile.Switch");
+			dojo.require("dojox.mobile.FixedSplitter");
+			dojo.require("dojox.mobile.View");
+			dojo.require("dojox.mobile.EdgeToEdgeCategory");
+			dojo.require("dojox.mobile.SpinWheel");
+			dojo.require("dojox.mobile.SpinWheelSlot");
+			dojo.require("dojox.mobile.migrationAssist");
+			dojo.ready(function(){
+				widget = new dojox.mobile.Heading();
+				dojo.place(widget.domNode, "Heading2-placeHolder", "replace");
+				var childWidget = new dojox.mobile.ToolBarButton({label:"Edit"});
+				childWidget.domNode.style.padding = "0px 14px";
+				widget.addChild(childWidget);
+				childWidget = new dojox.mobile.ToolBarButton({icon:"mblDomButtonWhitePlus"});
+				childWidget.domNode.style.float = "right";
+				widget.addChild(childWidget);
+				widget.domNode.appendChild(dojo.doc.createTextNode("Alarm Clock"));
+				widget.startup();
+				
+				widget.getIndexOfChild(childWidget);
+				console.log('Retun value of getIndexOfChild = ' + widget.getIndexOfChild(childWidget) + " (It should be 1.)");
+				
+				var roundRect = dijit.byId("dojox_mobile_RoundRect_0");
+				var sw2= new dojox.mobile.Switch();
+				roundRect.addChild(sw2);
+				
+				var button1 = dijit.byId("dojox_mobile_ToolBarButton_1");
+				button1.select();
+				
+				var button2 = dijit.byId("dojox_mobile_TabBarButton_2");
+				button2.select();
+				
+				var view = dijit.byId("bar");
+				ecat = new dojox.mobile.EdgeToEdgeCategory({label:"EdgeToEdgeCategory"});
+				view.addChild(ecat);
+
+				dojox.mobile.createDomButton(dojo.byId("addBtn"));
+				dojox.mobile.createDomButton(dojo.byId("delBtn"));
+
+			});
+		</script>
+	</head>
+	<body style="visibility:hidden;">
+		<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"V"'>
+			<div data-dojo-type="dojox.mobile.FixedSplitterPane">
+				<div id="bar" dojoType="dojox.mobile.View">
+					<h1 dojoType="dojox.mobile.Heading" label="Voice Memos">
+						<span dojoType="dojox.mobile.ToolBarButton" class="mblDomButtonWhitePlus"></span>
+						<span dojoType="dojox.mobile.ToolBarButton" label="Speaker" style="float:left"></span>
+						<span dojoType="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;"></span>
+					</h1><br>
+					<div id="Heading2-placeHolder"></div>
+
+					<ul dojoType="dojox.mobile.RoundRectList">
+						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
+							Airplane Mode
+							<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
+						</li>
+						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="mac" href="test_IconContainer.html" sync="false">
+							Wi-Fi
+						</li>
+						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="AcmePhone" moveTo="general">
+							Carrier
+						</li>
+					</ul>
+					<ul dojoType="dojox.mobile.RoundRect">
+					</ul>
+					<ul dojoType="dojox.mobile.TabBar">
+						<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" selected="true">New</li>
+						<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png">What's Hot</li>
+						<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png">Genius</li>
+					</ul>
+					<div style="float:right;padding-right:16px;">
+						<div id="delBtn" class="mblDomButtonRedMinus" style="float:right;"></div>
+						<div id="addBtn" class="mblDomButtonBluePlus" style="float:right;"></div>
+					</div>
+				</div>
+			</div>
+			<div dojoType="dojox.mobile.FixedSplitterPane" style="background-color:pink;height:200px;">
+				pane #2
+				<div id="spin1" dojoType="dojox.mobile.SpinWheel" style="width:312px;">
+					<div dojoType="dojox.mobile.SpinWheelSlot"
+						labels="[10,20,30,40,50,60,70,80,90,00]"
+						style="text-align:center;width:100px;"></div>
+					<div dojoType="dojox.mobile.SpinWheelSlot"
+						labels="['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']"
+						style="text-align:center;width:100px;"></div>
+					<div dojoType="dojox.mobile.SpinWheelSlot"
+						labelFrom="3000" labelTo="3100"
+						style="text-align:center;width:100px;"></div>
+				</div>
+			</div>
+		</div>
+
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_new_transition-animations-standard.html b/dojox/mobile/tests/test_new_transition-animations-standard.html
index 38e38e3..42698f7 100644
--- a/dojox/mobile/tests/test_new_transition-animations-standard.html
+++ b/dojox/mobile/tests/test_new_transition-animations-standard.html
@@ -1,85 +1,90 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Standard Transitions</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblCSS3Transition: 'dojox/css3/transit'"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Standard Transitions</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app uses declarative programming with fast mobile parser
-//			dojo.require("dojox.mobile.compat");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.deviceTheme");
-		</script>
-		<style>
-		html,body {
-			height: 100%;
-			overflow: hidden;
-		}
-		.mblRoundRectCategory {
-			color: black;
-			text-shadow: rgba(192,192,192,1) 1px 1px 0px;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true" style="background-color:#855AA0;height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" style="background: -webkit-gradient(linear, left top, left bottom, from(#CDB0BC), to(#A26D84), color-stop(0.5, #B3889B), color-stop(0.5, #AF8195));" back="Top" href="test_transition-animations.html" transition="none">View 1</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view2" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view3" transition="slide" transitionDir="-1">
-					Slide (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view2" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="fade">
-					Fade
-				</li>
-			</ul>
-		</div>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblCSS3Transition: 'dojox/css3/transit'"></script>
 
-		<div id="view2" dojoType="dojox.mobile.View" style="background-color:#009BB9;height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 2</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view3" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view1" transition="slide" transitionDir="-1">
-					Slide (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view3" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view3" transition="fade">
-					Fade
-				</li>
-			</ul>
-		</div>
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
 
-		<div id="view3" dojoType="dojox.mobile.View" style="background-color:#FFCC00;height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" style="background: -webkit-gradient(linear, left top, left bottom, from(#B0CDBC), to(#6DA284), color-stop(0.5, #88B39B), color-stop(0.5, #81AF95));" back="Top" href="test_transition-animations.html" transition="none">View 3</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view1" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view2" transition="slide" transitionDir="-1">
-					Slide (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view1" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view1" transition="fade">
-					Fade
-				</li>
-			</ul>
-		</div>
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	.mblRoundRectCategory {
+		color: black;
+		text-shadow: rgba(192,192,192,1) 1px 1px 0px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" style="background-color:#855AA0;height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_new_transition-animations.html", transition:"none"' style="background: -webkit-gradient(linear, left top, left bottom, from(#CDB0BC), to(#A26D84), color-stop(0.5, #B3889B), color-stop(0.5, #AF8195));">View 1</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view3", transition:"slide", transitionDir:-1'>
+				Slide (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
 
-	</body>
+	<div id="view2" data-dojo-type="dojox.mobile.View" style="background-color:#009BB9;height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_new_transition-animations.html", transition:"none"'>View 2</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view1", transition:"slide", transitionDir:-1'>
+				Slide (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View" style="background-color:#FFCC00;height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_new_transition-animations.html", transition:"none"' style="background: -webkit-gradient(linear, left top, left bottom, from(#B0CDBC), to(#6DA284), color-stop(0.5, #88B39B), color-stop(0.5, #81AF95));">View 3</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view1", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide", transitionDir:-1'>
+				Slide (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view1", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view1", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
+
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_new_transition-animations.html b/dojox/mobile/tests/test_new_transition-animations.html
index ce917db..e87713e 100644
--- a/dojox/mobile/tests/test_new_transition-animations.html
+++ b/dojox/mobile/tests/test_new_transition-animations.html
@@ -1,65 +1,70 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Sample of View Transitions</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblCSS3Transition: 'dojox/css3/transit'"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Sample of View Transitions</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app uses declarative programming with fast mobile parser
-//			dojo.require("dojox.mobile.compat");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.deviceTheme");
-		</script>
-		<style>
-		.mblListItemSubText {
-			color: gray;
-			font-size: 13px;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="top" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Sample of View Transitions</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_new_transition-animations-standard.html" transition="none">
-					Standard Transitions 
-				    <div class="mblListItemSubText">
-					    Slide, Flip, Fade
-				    </div>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_transition-animations-extended1.html" transition="none">
-					Extended Transitions 1
-				    <div class="mblListItemSubText">
-					    Dissolve, Flip2, Slide Vertical
-				    </div>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_transition-animations-extended2.html" transition="none">
-					Extended Transitions 2
-				    <div class="mblListItemSubText">
-					    Cover, Cover Vertical
-				    </div>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_transition-animations-extended3.html" transition="none">
-					Extended Transitions 3
-				    <div class="mblListItemSubText">
-					    Reveal, Reveal Vertical
-				    </div>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_transition-animations-extended4.html" transition="none">
-					Extended Transitions 4
-				    <div class="mblListItemSubText">
-					    Zoom In/Out, Scale In/Out
-				    </div>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_transition-animations-extended5.html" transition="none">
-					Extended Transitions 5
-				    <div class="mblListItemSubText">
-					    Swirl
-				    </div>
-				</li>
-			</ul>
-		</div>
-	</body>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblCSS3Transition: 'dojox/css3/transit'"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+
+	<style>
+	.mblListItemSubText {
+		color: gray;
+		font-size: 13px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="top" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Sample of View Transitions</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_new_transition-animations-standard.html", transition:"none", variableHeight:true'>
+				Standard Transitions 
+			    <div class="mblListItemSubText">
+				    Slide, Flip, Fade
+			    </div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_transition-animations-extended1.html", transition:"none", variableHeight:true'>
+				Extended Transitions 1
+			    <div class="mblListItemSubText">
+				    Dissolve, Slide Vertical
+			    </div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_transition-animations-extended2.html", transition:"none", variableHeight:true'>
+				Extended Transitions 2
+			    <div class="mblListItemSubText">
+				    Cover, Cover Vertical
+			    </div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_transition-animations-extended3.html", transition:"none", variableHeight:true'>
+				Extended Transitions 3
+			    <div class="mblListItemSubText">
+				    Reveal, Reveal Vertical
+			    </div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_transition-animations-extended4.html", transition:"none", variableHeight:true'>
+				Extended Transitions 4
+			    <div class="mblListItemSubText">
+				    Zoom In/Out, Scale In/Out
+			    </div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_transition-animations-extended5.html", transition:"none", variableHeight:true'>
+				Extended Transitions 5
+			    <div class="mblListItemSubText">
+				    Swirl, Swap, Cube
+			    </div>
+			</li>
+		</ul>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_new_transition-animations2.html b/dojox/mobile/tests/test_new_transition-animations2.html
index de5f2bc..b9d81d9 100644
--- a/dojox/mobile/tests/test_new_transition-animations2.html
+++ b/dojox/mobile/tests/test_new_transition-animations2.html
@@ -1,260 +1,91 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Transition Animations on ScrollableView</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar:true, mblCSS3Transition: 'dojox/css3/transit'"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Transition Animations on ScrollableView</title>
 
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.ScrollableView");
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar:true, mblCSS3Transition: 'dojox/css3/transit'"></script>
 
-//			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-		<style>
-		.mblRoundRectCategory {
-			color: black;
-			text-shadow: rgba(192,192,192,1) 1px 1px 0px;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.ScrollableView" selected="true" style="background-color:#855AA0;height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" style="background: -webkit-gradient(linear, left top, left bottom, from(#CDB0BC), to(#A26D84), color-stop(0.5, #B3889B), color-stop(0.5, #AF8195));">View 1</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view2" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view3" transition="slide" transitionDir="-1">
-					Slide (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view2" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="fade">
-					Fade
-				</li>
-			</ul>
-<!-- These are not supported in 1.7 using dojox/css3/transition.js module... 
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Extended Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="dissolve">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="view2" transition="flip2">
-					Flip2
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view2" transition="cover">
-					Cover
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view3" transition="cover" transitionDir="-1">
-					Cover (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="reveal">
-					Reveal
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view3" transition="reveal" transitionDir="-1">
-					Reveal (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view2" transition="slidev">
-					Slide Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view3" transition="slidev" transitionDir="-1">
-					Slide Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view2" transition="coverv">
-					Cover Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view3" transition="coverv" transitionDir="-1">
-					Cover Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view2" transition="revealv">
-					Reveal Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view3" transition="revealv" transitionDir="-1">
-					Reveal Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view2" transition="swirl">
-					Swirl
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view3" transition="swirl" transitionDir="-1">
-					Swirl (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view2" transition="zoomOut">
-					Zoom Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view2" transition="zoomIn">
-					Zoom In
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view2" transition="scaleOut">
-					Scale Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view2" transition="scaleIn">
-					Scale In
-				</li>
-			</ul>
--->
-		</div>
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
 
-		<div id="view2" dojoType="dojox.mobile.ScrollableView" style="background-color:#009BB9;height:100%;">
-			<h1 dojoType="dojox.mobile.Heading">View 2</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view3" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view1" transition="slide" transitionDir="-1">
-					Slide (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view3" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view3" transition="fade">
-					Fade
-				</li>
-			</ul>
-<!--
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Extended Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view3" transition="dissolve">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="view3" transition="flip2">
-					Flip2
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view3" transition="cover">
-					Cover
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view1" transition="cover" transitionDir="-1">
-					Cover (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view3" transition="reveal">
-					Reveal
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view1" transition="reveal" transitionDir="-1">
-					Reveal (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view3" transition="slidev">
-					Slide Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view1" transition="slidev" transitionDir="-1">
-					Slide Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view3" transition="coverv">
-					Cover Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view1" transition="coverv" transitionDir="-1">
-					Cover Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view3" transition="revealv">
-					Reveal Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view1" transition="revealv" transitionDir="-1">
-					Reveal Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view3" transition="swirl">
-					Swirl
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view1" transition="swirl" transitionDir="-1">
-					Swirl (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view3" transition="zoomOut">
-					Zoom Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view3" transition="zoomIn">
-					Zoom In
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view3" transition="scaleOut">
-					Scale Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view3" transition="scaleIn">
-					Scale In
-				</li>
-			</ul>
--->
-		</div>
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	.mblRoundRectCategory {
+		color: black;
+		text-shadow: rgba(192,192,192,1) 1px 1px 0px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView" style="background-color:#855AA0;height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" style="background: -webkit-gradient(linear, left top, left bottom, from(#CDB0BC), to(#A26D84), color-stop(0.5, #B3889B), color-stop(0.5, #AF8195));">View 1</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view3", transition:"slide", transitionDir:-1'>
+				Slide (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
 
-		<div id="view3" dojoType="dojox.mobile.ScrollableView" style="background-color:#FFCC00;height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" style="background: -webkit-gradient(linear, left top, left bottom, from(#B0CDBC), to(#6DA284), color-stop(0.5, #88B39B), color-stop(0.5, #81AF95));">View 3</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view1" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view2" transition="slide" transitionDir="-1">
-					Slide (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view1" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view1" transition="fade">
-					Fade
-				</li>
-			</ul>
-<!--
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Extended Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view1" transition="dissolve">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="view1" transition="flip2">
-					Flip2
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view1" transition="cover">
-					Cover
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view2" transition="cover" transitionDir="-1">
-					Cover (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view1" transition="reveal">
-					Reveal
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="reveal" transitionDir="-1">
-					Reveal (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view1" transition="slidev">
-					Slide Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view2" transition="slidev" transitionDir="-1">
-					Slide Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view1" transition="coverv">
-					Cover Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view2" transition="coverv" transitionDir="-1">
-					Cover Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view1" transition="revealv">
-					Reveal Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="revealv" transitionDir="-1">
-					Reveal Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view1" transition="swirl">
-					Swirl
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view2" transition="swirl" transitionDir="-1">
-					Swirl (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view1" transition="zoomOut">
-					Zoom Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view1" transition="zoomIn">
-					Zoom In
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view1" transition="scaleOut">
-					Scale Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view1" transition="scaleIn">
-					Scale In
-				</li>
-			</ul>
--->
-		</div>
-	</body>
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView" style="background-color:#009BB9;height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading">View 2</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view3", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view1", transition:"slide", transitionDir:-1'>
+				Slide (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view3", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view3", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView" style="background-color:#FFCC00;height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" style="background: -webkit-gradient(linear, left top, left bottom, from(#B0CDBC), to(#6DA284), color-stop(0.5, #88B39B), color-stop(0.5, #81AF95));">View 3</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view1", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide", transitionDir:-1'>
+				Slide (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view1", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view1", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
+
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_orientation-transition.html b/dojox/mobile/tests/test_orientation-transition.html
index 206fe22..21edfbe 100644
--- a/dojox/mobile/tests/test_orientation-transition.html
+++ b/dojox/mobile/tests/test_orientation-transition.html
@@ -1,66 +1,78 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Transition on Orientation Change</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Transition on Orientation Change</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.ready(function(){
-				var portrait = dijit.byId("portrait");
-				var landscape = dijit.byId("landscape");
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/_base/window",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile",
+			"dojox/mobile/sniff",
+			"dojox/mobile/parser",
+			"dojox/mobile/compat"
+		], function(connect, win, dom, domClass, ready, registry, common, has){
+			ready(function(){
+				var portrait = registry.byId("portrait");
+				var landscape = registry.byId("landscape");
 				var timer;
 				var onChange = function(){
-					var dim = dojox.mobile.getScreenSize();
+					var dim = common.getScreenSize();
 					var n, t;
 					if(timer){
 						clearTimeout(timer);
 					}
-					if(dim.h > dim.w && dojox.mobile.currentView != portrait){
+					if(dim.h > dim.w && common.currentView != portrait){
 						n = landscape.domNode;
-						t = (dojo.hasClass(n, "mblIn") || dojo.hasClass(n, "mblOut")) ? 2000 : 0;
+						t = (domClass.contains(n, "mblIn") || domClass.contains(n, "mblOut")) ? 2000 : 0;
 						timer = setTimeout(function(){
 							landscape.performTransition("portrait", 1, "fade");
 							timer = null;
 						}, t);
-					}else if (dim.h <= dim.w && dojox.mobile.currentView != landscape){
+					}else if (dim.h <= dim.w && common.currentView != landscape){
 						n = portrait.domNode;
-						t = (dojo.hasClass(n, "mblIn") || dojo.hasClass(n, "mblOut")) ? 2000 : 0;
+						t = (domClass.contains(n, "mblIn") || domClass.contains(n, "mblOut")) ? 2000 : 0;
 						timer = setTimeout(function(){
 							portrait.performTransition("landscape", 1, "fade");
 							timer = null;
 						}, t);
 					}
 				};
-				if(dojo.hasClass(dojo.doc.documentElement, "dj_landscape")){
+				if(domClass.contains(win.doc.documentElement, "dj_landscape")){
 					setTimeout(function(){
 						landscape.show();
 					}, 0);
 				}
-				dojo.connect(null, (dojo.global.onorientationchange !== undefined && !dojo.isAndroid)
+				connect.connect(null, (win.global.onorientationchange !== undefined && !has('android'))
 					? "onorientationchange" : "onresize", null, onChange);
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="portrait" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Portrait</h1>
-			<div style="text-align:center;padding-top:20px;">
-				<img src="images/a-icon-2-41x41.png">
-				<h2>View<br>for<br>portrait</h2>
-			</div>
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="portrait" data-dojo-type="dojox.mobile.View" data-dojo-props='selected:true'>
+		<h1 data-dojo-type="dojox.mobile.Heading">Portrait</h1>
+		<div style="text-align:center;padding-top:20px;">
+			<img alt="" src="images/a-icon-2-41x41.png">
+			<h2>View<br>for<br>portrait</h2>
 		</div>
+	</div>
 
-		<div id="landscape" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading">Landscape</h1>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true" style="text-align:center;">
-				<h2>View for landscape</h2>
-			</div>
+	<div id="landscape" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Landscape</h1>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true' style="text-align:center;">
+			<h2>View for landscape</h2>
 		</div>
-	</body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_pageTurningUtils-add-remove.html b/dojox/mobile/tests/test_pageTurningUtils-add-remove.html
new file mode 100644
index 0000000..49dd1ca
--- /dev/null
+++ b/dojox/mobile/tests/test_pageTurningUtils-add-remove.html
@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+	<title>Page Turning</title>
+	<link href="../themes/common/PageTurning.css" rel="stylesheet">
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom",
+			"dojo/dom-construct",
+			"dojo/ready",
+			"dojox/mobile/pageTurningUtils",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(dom, domConstruct, ready, pageTurningUtils){
+			utils = new pageTurningUtils();
+			
+			ready(function(){
+				// Set property values to pageTurningUtils object
+				utils.init(285, 388, "top", 2);
+				
+				// Initialize catalog node
+				utils.initCatalog(dom.byId("catalog"));
+			});
+			
+			prev = function(){
+				utils.turnToPrev();
+			};
+			
+			next = function(){
+				utils.turnToNext();
+			};
+			
+			var count = 0;
+			var createNewPageNode = function(){
+				count++;
+				var page = domConstruct.create("div", null);
+				page.innerHTML = '<div id="newfront' + count + '" class="myPane">' 
+									+ '<h1>New Page' + count + '</h1>'
+								+ '</div>' 
+								+ '<div id="newback' + count + '"></div>';
+				return page;
+			};
+			
+			add = function(){
+				var value = dom.byId("input_add").value,
+					index = value ? value - 0 : -1,
+					pages = utils.getPages(),
+					page = createNewPageNode();
+				if(index >= 0 && index < pages.length){
+					domConstruct.place(page, pages[index], "before");
+				}else{
+					// Place to last
+					domConstruct.place(page, dom.byId("catalog"));
+				}
+				
+				// Initialize a new page
+				utils.initPage(page);
+				
+				// Reset catalog
+				utils.resetCatalog();
+			};
+			
+			remove = function(){
+				var value = dom.byId("input_remove").value,
+					index = value ? value - 0 : -1,
+					pages = utils.getPages();
+				if(index >= 0 && index < pages.length){
+					domConstruct.destroy(pages[index]);
+				}
+				
+				// Reset catalog
+				utils.resetCatalog();
+			};
+		});
+	</script>
+	<style type="text/css">
+		.myPane {
+			background-image: -webkit-gradient(linear, left top, left bottom, from(#1E90FF), to(#FFFFFF));
+			font-family: Times New Roman, Helvetica;
+			color: black;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Page Turning</h1>
+		<table>
+			<tr><td><input type="button" onclick="add()" value="Add" style="width:50px"></td><td>index: <input id="input_add" style="width:20px;text-align:right" value=""></td></tr>
+			<tr><td><input type="button" onclick="remove()" value="Remove" style="width:50px"></td><td>index: <input id="input_remove" style="width:20px;text-align:right" value=""></td></tr>
+		</table>
+		<div style="margin:5px;">
+			<button onclick="prev()" style="width:50px">Prev</button>
+			<button onclick="next()" style="width:50px">Next</button>
+		</div>
+		<div id="msgArea" style="margin:10px;">onPageTurned: </div>
+		<div id="catalog" style="margin:10px;">
+			<div id="page1">
+				<img alt="" id="front1" src="images/pic1.jpg"/>
+				<div id="back1"></div>
+			</div>
+			<div id="page2">
+				<img alt="" id="front2" src="images/pic2.jpg"/>
+				<div id="back2"></div>
+			</div>
+			<div id="page3">
+				<img alt="" id="front3" src="images/pic3.jpg"/>
+				<div id="back3"></div>
+			</div>
+			<div id="page4">
+				<img alt="" id="front4" src="images/pic4.jpg"/>
+				<div id="back4"></div>
+			</div>
+			<div id="page5">
+				<img alt="" id="front5" src="images/pic5.jpg"/>
+				<div id="back5"></div>
+			</div>
+			<div id="page6">
+				<img alt="" id="front6" src="images/pic6.jpg"/>
+				<div id="back6"></div>
+			</div>
+			<div id="page7">
+				<img alt="" id="front7" src="images/pic7.jpg"/>
+				<div id="back7"></div>
+			</div>
+			<div id="page8">
+				<img alt="" id="front8" src="images/pic8.jpg"/>
+				<div id="back8"></div>
+			</div>
+			<div id="page9">
+				<img alt="" id="front9" src="images/pic9.jpg"/>
+				<div id="back9"></div>
+			</div>
+			<div id="page10">
+				<img alt="" id="front10" src="images/pic10.jpg"/>
+				<div id="back10"></div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_pageTurningUtils-callback.html b/dojox/mobile/tests/test_pageTurningUtils-callback.html
new file mode 100644
index 0000000..e0ddaa8
--- /dev/null
+++ b/dojox/mobile/tests/test_pageTurningUtils-callback.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+	<title>Page Turning</title>
+	<link href="../themes/common/PageTurning.css" rel="stylesheet">
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/dom",
+			"dojo/ready",
+			"dojox/mobile/pageTurningUtils",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, dom, ready, pageTurningUtils){
+			utils = new pageTurningUtils();
+			
+			ready(function(){
+				// Set property values to pageTurningUtils object
+				utils.init(285, 388);
+				
+				// Initialize catalog node
+				utils.initCatalog(dom.byId("catalog"));
+				
+				// Connect to onPageTurned callback function
+				connect.connect(utils, "onPageTurned", null, function(pageNode){
+					dom.byId("msgArea").innerHTML = "onPageTurned: " + pageNode.id;
+				});
+			});
+			
+			prev = function(){
+				dom.byId("msgArea").innerHTML = "onPageTurned: ";
+				utils.turnToPrev();
+			};
+			
+			next = function(){
+				dom.byId("msgArea").innerHTML = "onPageTurned: ";
+				utils.turnToNext();
+			};
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Page Turning</h1>
+		<div style="margin:5px;">
+			<button onclick="prev()" style="width:50px">Prev</button>
+			<button onclick="next()" style="width:50px">Next</button>
+		</div>
+		<div id="msgArea" style="margin:10px;">onPageTurned: </div>
+		<div id="catalog" style="margin:10px;">
+			<div id="page1">
+				<img alt="" id="front1" src="images/pic1.jpg"/>
+				<div id="back1"></div>
+			</div>
+			<div id="page2">
+				<img alt="" id="front2" src="images/pic2.jpg"/>
+				<div id="back2"></div>
+			</div>
+			<div id="page3">
+				<img alt="" id="front3" src="images/pic3.jpg"/>
+				<div id="back3"></div>
+			</div>
+			<div id="page4">
+				<img alt="" id="front4" src="images/pic4.jpg"/>
+				<div id="back4"></div>
+			</div>
+			<div id="page5">
+				<img alt="" id="front5" src="images/pic5.jpg"/>
+				<div id="back5"></div>
+			</div>
+			<div id="page6">
+				<img alt="" id="front6" src="images/pic6.jpg"/>
+				<div id="back6"></div>
+			</div>
+			<div id="page7">
+				<img alt="" id="front7" src="images/pic7.jpg"/>
+				<div id="back7"></div>
+			</div>
+			<div id="page8">
+				<img alt="" id="front8" src="images/pic8.jpg"/>
+				<div id="back8"></div>
+			</div>
+			<div id="page9">
+				<img alt="" id="front9" src="images/pic9.jpg"/>
+				<div id="back9"></div>
+			</div>
+			<div id="page10">
+				<img alt="" id="front10" src="images/pic10.jpg"/>
+				<div id="back10"></div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_pageTurningUtils-pageType.html b/dojox/mobile/tests/test_pageTurningUtils-pageType.html
new file mode 100644
index 0000000..22fb01c
--- /dev/null
+++ b/dojox/mobile/tests/test_pageTurningUtils-pageType.html
@@ -0,0 +1,147 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+	<title>Page Turning (Various page types)</title>
+	<link href="../themes/common/PageTurning.css" rel="stylesheet">
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','SpinWheel']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/window",
+			"dojo/dom",
+			"dojo/ready",
+			"dojox/mobile/pageTurningUtils",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/SpinWheel",
+			"dojox/mobile/ContentPane"
+		], function(win, dom, ready, pageTurningUtils){
+			utils = new pageTurningUtils();
+			
+			ready(function(){
+				var bgColor = win.doc.defaultView.getComputedStyle(win.body(), '')["background-color"];
+				dom.byId("front4").style.backgroundColor = bgColor;
+				dom.byId("front5").style.backgroundColor = bgColor;
+				dom.byId("front6").style.backgroundColor = bgColor;
+				
+				// Set property values to pageTurningUtils object
+				utils.init(320, 400);
+				
+				// Initialize catalog node
+				utils.initCatalog(dom.byId("catalog"));
+			});
+			
+			prev = function(){
+				utils.turnToPrev();
+			};
+			
+			next = function(){
+				utils.turnToNext();
+			};
+		});
+	</script>
+	
+	<style type="text/css">
+		.myPane {
+			background-image: -webkit-gradient(linear, left top, left bottom, from(#dcdcdc), to(#FFFFFF));
+			font-family: Times New Roman, Helvetica;
+			color: black;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Page Turning (Various page types)</h1>
+		<div style="margin:5px;">
+			<button onclick="prev()" style="width:50px">Prev</button>
+			<button onclick="next()" style="width:50px">Next</button>
+		</div>
+		<div id="catalog" style="margin:10px;">
+			<div id="page0"> <!-- image element -->
+				<img alt="" id="front0" src="images/pic1.jpg"/>
+				<div id="back0"></div>
+			</div>
+			<div id="page1"> <!-- image element under div element -->
+				<div>
+					<img alt="" id="front1" src="images/pic2.jpg" style="width:100%;height:100%"/>
+				</div>
+				<div id="back1"></div>
+			</div>
+			<div id="page2"> <!-- iframe -->
+				<div id="front2" class="myPane">
+					<iframe src="data/fragment1.html" style="width:99%;height:99%"></iframe>
+				</div>
+				<div id="back2"></div>
+			</div>
+			<div id="page3"> <!-- div contents -->
+				<div id="front3" class="myPane">
+					<div style="padding:10px;">
+						<div style="font-size: 24px">Unbeatable JavaScript Tools</div>
+						<div style="border-top: 1px dashed gray;margin: 20px"></div>
+						<img alt="" src="images/dojo-logo1.png" style="float:left;margin-right:5px">
+						<p>Dojo saves you time, delivers powerful performance, and scales with your development process. It's the toolkit experienced developers turn to for building superior desktop and mobile web experiences.</p>
+					</div>
+				</div>
+				<div id="back3"></div>
+			</div>
+			<div id="page4"> <!-- dojox.mobile.View widget -->
+				<div id="front4" data-dojo-type="dojox.mobile.View" style="height:100%;">
+					<h1 data-dojo-type="dojox.mobile.Heading">View</h1>
+					<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+						<p><img alt="" src="images/dojo-logo1.png" width="60" height="60" style="text-align:left">
+						Dojo saves you time and scales with your development process, using web standards as its platform. It's the toolkit experienced developers turn to for building high quality desktop and mobile web applications.</p>
+					</div>
+				</div>
+				<div id="back4"></div>
+			</div>
+			<div id="page5"> <!-- dojox.mobile.ScrollableView widget -->
+				<div id="front5" data-dojo-type="dojox.mobile.ScrollableView" style="height:100%;">
+					<h1 data-dojo-type="dojox.mobile.Heading">ScrollableView</h1>
+					<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+							Item 1
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png"'>
+							Item 2
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png"'>
+							Item 3
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png"'>
+							Item 4
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png"'>
+							Item 5
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png"'>
+							Item 6
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png"'>
+							Item 7
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png"'>
+							Item 8
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png"'>
+							Item 9
+						</li>
+						<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png"'>
+							Item 10
+						</li>
+					</ul>
+				</div>
+				<div id="back5"></div>
+			</div>
+			<div id="page6"> <!-- dojox.mobile.ContentPane widget -->
+				<div id="front6" data-dojo-type="dojox.mobile.ContentPane" data-dojo-props='href:"data/view5.html"'></div>
+				<div id="back6"></div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_pageTurningUtils.html b/dojox/mobile/tests/test_pageTurningUtils.html
new file mode 100644
index 0000000..28c74a5
--- /dev/null
+++ b/dojox/mobile/tests/test_pageTurningUtils.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes" />
+	<title>Page Turning</title>
+	<link href="../themes/common/PageTurning.css" rel="stylesheet">
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/dom",
+			"dojo/ready",
+			"dojox/mobile/pageTurningUtils",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(dom, ready, pageTurningUtils){
+			utils = new pageTurningUtils();
+			
+			ready(function(){
+				init();
+			});
+			
+			init = function(){
+				// Get property values from input fields
+				var w = dom.byId("input_w").value - 0;
+				var h = dom.byId("input_h").value - 0;
+				var page = dom.byId("input_page").value - 0;
+				var dogear = dom.byId("input_dogear").value - 0;
+				var duration = dom.byId("input_duration").value - 0;
+				
+				var s = dom.byId("input_turnfrom");
+				var turnfrom = s.options[s.selectedIndex].value;
+				
+				var alwaysDogeared = false;
+				var r = document.getElementsByName("input_alwaysDogeared");
+				for(var i=0; i<r.length; i++){
+					if(r[i].checked){
+						alwaysDogeared = (r[i].value === 'true') ? true : false;
+					}
+				}
+				
+				// Set property values to pageTurningUtils object
+				utils.init(w, h, turnfrom, page, dogear, duration, alwaysDogeared);
+				
+				// Initialize catalog node
+				utils.initCatalog(dom.byId("catalog"));
+			};
+			
+			prev = function(){
+				utils.turnToPrev();
+			};
+			
+			next = function(){
+				utils.turnToNext();
+			};
+		});
+	</script>
+	
+	<style type="text/css">
+		img{
+			width:100%;
+			height:100%;
+		}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Page Turning (callback)</h1>
+		<table>
+			<tr><td><input type="button" onclick="init()" value="Set" style="width:50px"></td><td></td></tr>
+			<tr><td>width: (pixel)</td><td><input id="input_w" style="width:50px;text-align:right" value="285"></td></tr>
+			<tr><td>height: (pixel)</td><td><input id="input_h" style="width:50px;text-align:right" value="388"></td></tr>
+			<tr><td>turnfrom:</td><td><select id="input_turnfrom"><option value="top" selected>top</option><option value="bottom">bottom</option><option value="left">left</option></select></td></tr>
+			<tr><td>page:</td><td><select id="input_page"><option value="1" selected>1</option><option value="2">2</option></select></td></tr>
+			<tr><td>dogear: (0-1.0)</td><td><input id="input_dogear" style="width:50px;text-align:right" value="1.0"></td></tr>
+			<tr><td>duration: (seconds)</td><td><input id="input_duration" style="width:50px;text-align:right" value="2.0"></td></tr>
+			<tr><td>alwaysDogeared:</td><td><input type="radio" name="input_alwaysDogeared" value="true">true<input type="radio" name="input_alwaysDogeared" value="false" checked>false</td></tr>
+		</table>
+		<div style="margin:5px;">
+			<button onclick="prev()" style="width:50px">Prev</button>
+			<button onclick="next()" style="width:50px">Next</button>
+		</div>
+		<div id="catalog" style="margin:10px;">
+			<div id="page1">
+				<div id="front1"><img alt="" src="images/pic1.jpg"></div>
+				<div id="back1"></div>
+			</div>
+			<div id="page2">
+				<div id="front2"><img alt="" src="images/pic2.jpg"></div>
+				<div id="back2"><img alt="" src="images/pic3.jpg"></div>
+			</div>
+			<div id="page3">
+				<div id="front3"><img alt="" src="images/pic4.jpg"></div>
+				<div id="back3"></div>
+			</div>
+			<div id="page4">
+				<div id="front4"><img alt="" src="images/pic5.jpg"></div>
+				<div id="back4"><img alt="" src="images/pic6.jpg"></div>
+			</div>
+			<div id="page5">
+				<div id="front5"><img alt="" src="images/pic7.jpg"></div>
+				<div id="back5"><img alt="" src="images/pic8.jpg"></div>
+			</div>
+			<div id="page6">
+				<div id="front6"><img alt="" src="images/pic9.jpg"></div>
+				<div id="back6"></div>
+			</div>
+			<div id="page7">
+				<div id="front7"><img alt="" src="images/pic10.jpg"></div>
+				<div id="back7"></div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_phone-settings.html b/dojox/mobile/tests/test_phone-settings.html
new file mode 100644
index 0000000..e41ce1d
--- /dev/null
+++ b/dojox/mobile/tests/test_phone-settings.html
@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Settings</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="settings" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Settings</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png"'>
+				Airplane Mode
+				<div data-dojo-type="dojox.mobile.Switch"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", rightText:"mac", href:"test_IconContainer.html"'>
+				Wi-Fi
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", rightText:"AcmePhone", moveTo:"general"'>
+				Carrier
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general"'>
+				Sounds
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"general"'>
+				Brightness
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"general"'>
+				Wallpaper
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"general"'>
+				General
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"general"'>
+				Mail, Contacts, Calendars
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"general"'>
+				Phone
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"general"'>
+				Safari
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"general"'>
+				SMS/MMS
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"general"'>
+				iPod
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"general"'>
+				Photos
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general"'>
+				Store
+			</li>
+		</ul>
+	</div>
+
+	<div id="general" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Settings", moveTo:"settings"'>General</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				About
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2h 40m", moveTo:"about"'>
+				Usage
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Network
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+				Bluetooth
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Location Services
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1 Minute", moveTo:"about"'>
+				Auto-Lock
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+				Passcode Lock
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+				Restrictions
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Home
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Date & Time					   
+			</li>							   
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Keyboard					   
+			</li>							   
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				International				   
+			</li>							   
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Accessibility
+			</li>
+		</ul>
+
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+				Reset
+			</li>
+		</ul>
+	</div>
+
+	<div id="about" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"General", moveTo:"general"'>About</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Network											   
+			</li>												   
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+				Line
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+				Songs
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+				Videos
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+				Photos
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+				Applications
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+				Capacity
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+				Available
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+				Version
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_progress-indicator.html b/dojox/mobile/tests/test_progress-indicator.html
deleted file mode 100755
index 0ce90bc..0000000
--- a/dojox/mobile/tests/test_progress-indicator.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Progress Indicator</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.hash");
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			// Use animated GIF icon as a progress indicator.
-			function loadPage(moveTo){
-				if(!(moveTo.match(/#(\w+)/))){ return; }
-				moveTo.match(/#(\w+)(.*)/);
-				var id = RegExp.$1;
-				var param = RegExp.$2;
-				if(!param){ return; }
-				var container = dojo.byId(id);
-				container.innerHTML = "";
-				var prog = dojox.mobile.ProgressIndicator.getInstance();
-				container.appendChild(prog.domNode);
-				prog.start();
-				setTimeout(function(){ // network latency simulation
-					prog.stop();
-					container.innerHTML = '<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="#home">'+param+'</h1>\n'+param;
-					dojox.mobile.parser.parse(container);
-				}, 5000);
-			}
-			dojo.declare("dojox.mobile.ViewEx",dojox.mobile.View,{
-				onStartView: function(){
-					loadPage(location.hash);
-				},
-				onBeforeTransitionIn: function(moveTo, dir, transition, context, method){
-					loadPage("#"+moveTo);
-				}
-			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="home" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Progress Indicator</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">External Documents</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="#bar&myParam=0001">
-					Document 0001
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="#bar&myParam=0002">
-					Document 0002
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="#bar&myParam=0003">
-					Document 0003
-				</li>
-			</ul>
-			<div dojoType="dojox.mobile.RoundRect">
-				A progress indicator shows up about 5 seconds before a view content is displayed.
-				After you move to other views, you should also be able to navigate through the views with browser's back and forward buttons. Also, views should be bookmarkable. Note that you can pass parameters (e.g. &myParam=001) to a destination view.
-			</div>
-		</div>
-
-		<div id="bar" dojoType="dojox.mobile.ViewEx"></div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_screen-size-aware-async.html b/dojox/mobile/tests/test_screen-size-aware-async.html
deleted file mode 100644
index 46c5b8e..0000000
--- a/dojox/mobile/tests/test_screen-size-aware-async.html
+++ /dev/null
@@ -1,315 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Screen Size Aware</title>
-		<style>
-		@import "../themes/iphone/base.css";
-		@import "../themes/iphone/ipad.css";
-		@import "../themes/common/FixedSplitter.css";
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			position: relative;
-		}
-		.dj_tablet .mblEdgeToEdgeList {
-			background-color: #DBDDE2;
-		}
-		.dj_tablet .leftPane {
-			width:300px;
-		}
-		.dj_phone .leftPane {
-			width: 0px;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, async: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-		require([
-			"dojo/_base/kernel",
-			"dojo/_base/connect",	// dojo.subscribe() (TODO: use on() instead)
-			"dojo/_base/html",		// dojo.byId
-			"dijit/_base/manager",	// dijit.byId
-			"dojox/mobile/parser", 	// This mobile app uses declarative programming with fast mobile parser
-			"dojox/mobile",			// This is a mobile app.
-			"dojox/mobile/FixedSplitter",
-			"dojox/mobile/ScrollableView",
-			"dojox/mobile/Heading",
-			"dojox/mobile/ListItem",
-			"dojox/mobile/RoundRectList",
-			"dojox/mobile/FixedSplitterPane",
-			"dojox/mobile/compat"	// This mobile app supports running on desktop browsers
-			// "domReady!" // Enable if user code placed in the callback here that needs DOMReady
-		], function(dojo){
-				dojo.subscribe("/dojox/mobile/screenSize/tablet", function(dim){
-					setStateful(true);
-					showBackButton(false);
-					setTransition("none");
-					moveList("left");
-					showLeftView();
-					selectItem(showRightView().id);
-				});
-
-				dojo.subscribe("/dojox/mobile/screenSize/phone", function(dim){
-					setStateful(false);
-					showBackButton(true);
-					setTransition("slide");
-					moveList("right");
-					showLeftView();
-					selectItem(null);
-				});
-			}
-		);
-
-		function setStateful(flag){
-			dijit.byId("list1").set("stateful", flag);
-		}
-		function showBackButton(flag){
-			dojo.forEach(dijit.byId("list1").getChildren(), function(item){
-				var view = dijit.byId(item.moveTo);
-				var heading = dojo.filter(view.getChildren(), function(c){ return (c instanceof dojox.mobile.Heading); })[0];
-				heading.backBtnNode.style.display = flag ? "" : "none";
-			});
-		}
-		function setTransition(transition){
-			dojo.forEach(dijit.byId("list1").getChildren(), function(item){
-				item.set("transition", transition);
-			});
-		}
-		function moveList(to){
-			if(to == "right"){
-				dojo.byId("rightPane").appendChild(dojo.byId("settings"));
-			}else{
-				dojo.byId("leftPane").appendChild(dojo.byId("settings"));
-			}
-		}
-		function showLeftView(){
-			dijit.byId("settings").show();
-		}
-		function selectItem(id){
-			var list1 = dijit.byId("list1");
-			if(id){
-				var items = dojo.filter(list1.getChildren(), function(c){ return c.moveTo === id; });
-				if(items && items.length > 0){
-					items[0].select();
-				}
-			}else{
-				list1.deselectAll();
-			}
-		}
-		function showRightView(){
-			var rightPane = dijit.byId("rightPane");
-			var showing = dijit.byId("general").getShowingView() ||
-				dojo.filter(rightPane.getChildren(), function(c){ return c.selected; })[0];
-			showing.show();
-			return showing;
-		}
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
-			<div id="leftPane" class="leftPane" dojoType="dojox.mobile.FixedSplitterPane" style="border-right:1px solid black;">
-				<div id="settings" dojoType="dojox.mobile.ScrollableView" selected="true">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">Settings</h1>
-					<ul id="list1" dojoType="dojox.mobile.EdgeToEdgeList" transition="none" stateful="true">
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							Wi-Fi
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Brightness & Wallpaper
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Picture Frame
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general" selected="true">
-							General
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="wifi">
-							Mail, Contacts, Calendars
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bright">
-							Safari
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="picture">
-							iPod
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="general">
-							Video
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="wifi">
-							Photos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="bright">
-							Store
-						</li>
-						<li class="mblEdgeToEdgeCategory">
-							Apps
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							News
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Weather
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Books
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-							 Business
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							Navigation
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Sports
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Social
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-							Music
-						</li>
-					</ul>
-				</div>
-			</div>
-
-			<div id="rightPane" class="rightPane" dojoType="dojox.mobile.FixedSplitterPane">
-
-				<div id="general" dojoType="dojox.mobile.ScrollableView" selected="true">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Settings" moveTo="settings">General</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							About
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="2h 40m" moveTo="about">
-							Usage
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Network
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Bluetooth
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Location Services
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" rightText="1 Minute" moveTo="about">
-							Auto-Lock
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Passcode Lock
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Restrictions
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Home
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Date & Time					   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Keyboard					   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							International				   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Accessibility
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Reset
-						</li>
-					</ul>
-				</div>
-
-				<div id="about" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="General" moveTo="general">About</h1>
-					<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-							Network											   
-						</li>												   
-						<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-							Line
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="1024">
-							Songs
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="10">
-							Videos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="96">
-							Photos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="2">
-							Applications
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-							Capacity
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-							Available
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-							Version
-						</li>
-					</ul>
-				</div>
-
-				<div id="wifi" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Settings" moveTo="settings">Wi-Fi Networks</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem">
-							Wi-Fi
-							<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							<input type="text">
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							<select><option>Songs</option><option>Videos</option><option>Photos</option></select>
-						</li>
-					</ul>
-				</div>
-
-				<div id="bright" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Settings" moveTo="settings">Brightness & Wallpaper</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem">
-							Auto-Brightness
-							<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-						</li>
-					</ul>
-				</div>
-
-				<div id="picture" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Settings" moveTo="settings">Picture Frame</h1>
-					<h2 dojoType="dojox.mobile.RoundRectCategory">Transition</h2>
-					<ul dojoType="dojox.mobile.RoundRectList" select="single">
-						<li dojoType="dojox.mobile.ListItem" checked="true">
-							Dissolve
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							Origami
-						</li>
-					</ul>
-				</div>
-
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_screen-size-aware-demo.html b/dojox/mobile/tests/test_screen-size-aware-demo.html
deleted file mode 100644
index 245b6f4..0000000
--- a/dojox/mobile/tests/test_screen-size-aware-demo.html
+++ /dev/null
@@ -1,175 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Screen Size Aware Demo</title>
-		<style>
-		@import "../themes/iphone/base.css";
-		@import "../themes/iphone/ipad.css";
-		@import "../themes/common/FixedSplitter.css";
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			position: relative;
-		}
-		.dj_tablet .leftPane {
-			width:300px;
-		}
-		.dj_phone .leftPane {
-			width: 0px;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojo.data.ItemFileWriteStore");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile.compat");
-			dojo.require("dojox.mobile.FixedSplitter");
-			dojo.require("dojox.mobile.FixedSplitterPane");
-			dojo.require("dojox.mobile.ScrollableView");
-			dojo.require("dojox.mobile.EdgeToEdgeDataList");
-
-			var viewCache = {};
-			function isPhone(){
-				return dojo.hasClass(dojo.doc.documentElement, "dj_phone");
-			}
-			function getShowingView(){
-				var rightPane = dijit.byId("rightPane");
-				var firstView =
-					dojo.filter(rightPane.getChildren(), function(c){ return c instanceof dojox.mobile.View; })[0];
-				if(!firstView){ return null; }
-				return firstView.getShowingView() ||
-					dojo.filter(rightPane.getChildren(), function(c){ return c.selected; })[0] ||
-					firstView;
-			}
-
-			function updateStateful(){
-				dijit.byId("list1").set("stateful", !isPhone());
-			}
-			function updateBackButton(){
-				dojo.forEach(dijit.byId("list1").getChildren(), function(item){
-					var view = dijit.byId(viewCache[item.data]);
-					if(view){
-						var heading = dojo.filter(view.getChildren(), function(c){ return (c instanceof dojox.mobile.Heading); })[0];
-						heading.backBtnNode.style.display = isPhone() ? "" : "none";
-					}
-				});
-			}
-			function updateTransition(){
-				var transition = isPhone() ? "slide" : "none";
-				dojo.forEach(dijit.byId("list1").getChildren(), function(item){
-					item.set("transition", transition);
-				});
-			}
-			function moveList(){
-				var to = isPhone() ? "right" : "left";
-				dojo.byId(to + "Pane").appendChild(dojo.byId("view1"));
-			}
-			function showLeftView(){
-				dijit.byId("view1").show();
-			}
-			function showRightView(){
-				if(isPhone()){ return; }
-				var view = getShowingView();
-				if(view){
-					view.show();
-				}else{
-					leftItemSelected();
-				}					
-			}
-			function updateSelectedItem(){
-				var id;
-				var view = getShowingView();
-				if(view && !isPhone()){
-					id = view.id;
-				}
-				var list1 = dijit.byId("list1");
-				if(id){
-					var items = dojo.filter(list1.getChildren(), function(c){ return viewCache[c.data] === id; });
-					if(items && items.length > 0){
-						items[0].select();
-					}
-				}else{
-					list1.deselectAll();
-				}
-			}
-			function leftItemSelected(e){
-				var item = e ? dijit.getEnclosingWidget(e.target) : dijit.byId("list1").getChildren()[0];
-				if(!item){ return; }
-				var id = viewCache[item.data];
-				if(!id){
-					// Dynamically creates a new view
-					id = item.id ? item.id + "View" : undefined;
-					var view = new dojox.mobile.ScrollableView({
-						id: id,
-						selected: true
-					}, dojo.create("DIV", null, "rightPane"));
-					view.startup();
-					id = viewCache[item.data] = view.id;
-
-					var heading = new dojox.mobile.Heading({
-						label: item.label,
-						back: "Home",
-						moveTo: "view1",
-						fixed: "top"
-					});
-					view.addChild(heading);
-
-					var store = new dojo.data.ItemFileWriteStore({url: item.data});
-					var list = new dojox.mobile.EdgeToEdgeDataList({
-						store: store
-					});
-					view.addChild(list);
-					updateBackButton();
-					updateTransition();
-
-					view.resize();
-				}
-				item.transitionTo(id);
-			}
-			function leftItemsLoaded(){
-				if(!isPhone()){
-					leftItemSelected();
-					updateSelectedItem();
-				}
-			}
-			function transformUI(){
-				updateStateful();
-				updateBackButton();
-				updateTransition();
-				moveList();
-				showLeftView();
-				showRightView();
-				updateSelectedItem();
-			}
-
-			dojo.subscribe("/dojox/mobile/screenSize/tablet", function(dim){
-				transformUI();
-			});
-			dojo.subscribe("/dojox/mobile/screenSize/phone", function(dim){
-				transformUI();
-			});
-
-			dojo.ready(function(){
-				dojo.connect(dijit.byId("list1").domNode, "onclick", null, leftItemSelected);
-				dojo.connect(dijit.byId("list1"), "onComplete", null, leftItemsLoaded);
-			});
-			var store1 = new dojo.data.ItemFileWriteStore({url: "insurance.json"});
-		</script>
-	</head>
-	<body style="visibility:hidden;background-color:white;">
-		<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
-			<div id="leftPane" class="leftPane" dojoType="dojox.mobile.FixedSplitterPane" style="border-right:1px solid black;">
-				<div id="view1" dojoType="dojox.mobile.ScrollableView" selected="true">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">Insurance</h1>
-					<ul dojoType="dojox.mobile.EdgeToEdgeDataList" id="list1" store="store1" query="{label: '*'}" stateful="true"></ul>
-				</div>
-			</div>
-
-			<div id="rightPane" class="rightPane" dojoType="dojox.mobile.FixedSplitterPane"></div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_screen-size-aware.html b/dojox/mobile/tests/test_screen-size-aware.html
deleted file mode 100644
index fd3501b..0000000
--- a/dojox/mobile/tests/test_screen-size-aware.html
+++ /dev/null
@@ -1,308 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Screen Size Aware</title>
-		<style>
-		@import "../themes/iphone/base.css";
-		@import "../themes/iphone/ipad.css";
-		@import "../themes/common/FixedSplitter.css";
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			position: relative;
-		}
-		.dj_tablet .mblEdgeToEdgeList {
-			background-color: #DBDDE2;
-		}
-		.dj_tablet .leftPane {
-			width:300px;
-		}
-		.dj_phone .leftPane {
-			width: 0px;
-		}
-		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.FixedSplitter");
-			dojo.require("dojox.mobile.FixedSplitterPane");
-			dojo.require("dojox.mobile.ScrollableView");
-			dojo.require("dojox.mobile.Heading");
-			dojo.require("dojox.mobile.ListItem");
-			dojo.require("dojox.mobile.RoundRectList");
-
-			function setStateful(flag){
-				dijit.byId("list1").set("stateful", flag);
-			}
-			function showBackButton(flag){
-				dojo.forEach(dijit.byId("list1").getChildren(), function(item){
-					var view = dijit.byId(item.moveTo);
-					var heading = dojo.filter(view.getChildren(), function(c){ return (c instanceof dojox.mobile.Heading); })[0];
-					heading.backBtnNode.style.display = flag ? "" : "none";
-				});
-			}
-			function setTransition(transition){
-				dojo.forEach(dijit.byId("list1").getChildren(), function(item){
-					item.set("transition", transition);
-				});
-			}
-			function moveList(to){
-				if(to == "right"){
-					dojo.byId("rightPane").appendChild(dojo.byId("settings"));
-				}else{
-					dojo.byId("leftPane").appendChild(dojo.byId("settings"));
-				}
-			}
-			function showLeftView(){
-				dijit.byId("settings").show();
-			}
-			function selectItem(id){
-				var list1 = dijit.byId("list1");
-				if(id){
-					var items = dojo.filter(list1.getChildren(), function(c){ return c.moveTo === id; });
-					if(items && items.length > 0){
-						items[0].select();
-					}
-				}else{
-					list1.deselectAll();
-				}
-			}
-			function showRightView(){
-				var rightPane = dijit.byId("rightPane");
-				var showing = dijit.byId("general").getShowingView() ||
-					dojo.filter(rightPane.getChildren(), function(c){ return c.selected; })[0];
-				showing.show();
-				return showing;
-			}
-
-			dojo.subscribe("/dojox/mobile/screenSize/tablet", function(dim){
-				setStateful(true);
-				showBackButton(false);
-				setTransition("none");
-				moveList("left");
-				showLeftView();
-				selectItem(showRightView().id);
-			});
-
-			dojo.subscribe("/dojox/mobile/screenSize/phone", function(dim){
-				setStateful(false);
-				showBackButton(true);
-				setTransition("slide");
-				moveList("right");
-				showLeftView();
-				selectItem(null);
-			});
-
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
-			<div id="leftPane" class="leftPane" dojoType="dojox.mobile.FixedSplitterPane" style="border-right:1px solid black;">
-				<div id="settings" dojoType="dojox.mobile.ScrollableView" selected="true">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top">Settings</h1>
-					<ul id="list1" dojoType="dojox.mobile.EdgeToEdgeList" transition="none" stateful="true">
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							Wi-Fi
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Brightness & Wallpaper
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Picture Frame
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general" selected="true">
-							General
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="wifi">
-							Mail, Contacts, Calendars
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bright">
-							Safari
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="picture">
-							iPod
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="general">
-							Video
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="wifi">
-							Photos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="bright">
-							Store
-						</li>
-						<li class="mblEdgeToEdgeCategory">
-							Apps
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							News
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Weather
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Books
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-							 Business
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="wifi">
-							Navigation
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bright">
-							Sports
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="picture">
-							Social
-						</li>
-						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
-							Music
-						</li>
-					</ul>
-				</div>
-			</div>
-
-			<div id="rightPane" class="rightPane" dojoType="dojox.mobile.FixedSplitterPane">
-
-				<div id="general" dojoType="dojox.mobile.ScrollableView" selected="true">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Settings" moveTo="settings">General</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							About
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="2h 40m" moveTo="about">
-							Usage
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Network
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Bluetooth
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Location Services
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" rightText="1 Minute" moveTo="about">
-							Auto-Lock
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Passcode Lock
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
-							Restrictions
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Home
-						</li>
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Date & Time					   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Keyboard					   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							International				   
-						</li>							   
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Accessibility
-						</li>
-					</ul>
-
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" moveTo="about">
-							Reset
-						</li>
-					</ul>
-				</div>
-
-				<div id="about" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="General" moveTo="general">About</h1>
-					<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-							Network											   
-						</li>												   
-						<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
-							Line
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="1024">
-							Songs
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="10">
-							Videos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="96">
-							Photos
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="2">
-							Applications
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
-							Capacity
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
-							Available
-						</li>
-						<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
-							Version
-						</li>
-					</ul>
-				</div>
-
-				<div id="wifi" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Settings" moveTo="settings">Wi-Fi Networks</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem">
-							Wi-Fi
-							<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							<input type="text">
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							<select><option>Songs</option><option>Videos</option><option>Photos</option></select>
-						</li>
-					</ul>
-				</div>
-
-				<div id="bright" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Settings" moveTo="settings">Brightness & Wallpaper</h1>
-					<ul dojoType="dojox.mobile.RoundRectList">
-						<li dojoType="dojox.mobile.ListItem">
-							Auto-Brightness
-							<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-						</li>
-					</ul>
-				</div>
-
-				<div id="picture" dojoType="dojox.mobile.ScrollableView">
-					<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Settings" moveTo="settings">Picture Frame</h1>
-					<h2 dojoType="dojox.mobile.RoundRectCategory">Transition</h2>
-					<ul dojoType="dojox.mobile.RoundRectList" select="single">
-						<li dojoType="dojox.mobile.ListItem" checked="true">
-							Dissolve
-						</li>
-						<li dojoType="dojox.mobile.ListItem">
-							Origami
-						</li>
-					</ul>
-				</div>
-
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_scrollable-no-dojo-af.html b/dojox/mobile/tests/test_scrollable-no-dojo-af.html
deleted file mode 100644
index ab4fe46..0000000
--- a/dojox/mobile/tests/test_scrollable-no-dojo-af.html
+++ /dev/null
@@ -1,147 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html class="mobile">
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>scrollable no-dojo with app footer</title>
-		<!--
-			scrollable.js is a hybrid module, which can be used with or without dojo.
-			In this example, scrollable.js is used without dojo.
-			scrollable.js has several methods that simulate dojo APIs, which are used
-			when you use scrollable.js without dojo.
-			Note that those methods are surrounded by excludeStart/excludeEnd pragmas,
-			and will be removed if you do typical dojo build.
-			If that is the case, this example does not work.
-		-->
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			visibility: visible;
-		}
-		.domNode {
-			position: relative;
-			height: 100%;
-			overflow: hidden;
-		}
-		.containerNode {
-			position: absolute;
-			width: 100%;
-		}
-		#footer1 {
-			position: absolute;
-			width: 100%;
-			bottom: 0px;
-		}
-		</style>
-		<script type="text/javascript" src="../scrollable.js"></script>
-
-		<script language="JavaScript" type="text/javascript">
-		function onLoad(){
-			var scrollable = new dojox.mobile.scrollable();
-			scrollable.init({
-				domNode: document.getElementById("outer"),
-				containerNode: document.getElementById("inner"),
-				fixedFooterHeight: document.getElementById("footer1").offsetHeight
-			});
-			dojo.connect(dojo.global, (dojo.global.onorientationchange !== undefined)
-				? "onorientationchange" : "onresize", scrollable, "resize");
-		}
-		</script>
-	</head>
-	<body onload="onLoad()">
-		<div id="outer" class="domNode">
-			<div id="inner" class="containerNode">
-				<h2 class="mblRoundRectCategory">Transition Effects</h2>
-				<ul class="mblRoundRectList">
-					<li class="mblListItem">
-						<img class="mblListItemIcon" src="images/i-icon-1.png">
-						<a class="mblListItemAnchor">
-							<div class="mblListItemTextBox">Slide</div>
-						</a>
-					</li>
-					<li class="mblListItem">
-						<img class="mblListItemIcon" src="images/i-icon-2.png">
-						<a class="mblListItemAnchor">
-							<div class="mblListItemTextBox">Flip</div>
-						</a>
-					</li>
-					<li class="mblListItem">
-						<img class="mblListItemIcon" src="images/i-icon-3.png">
-						<a class="mblListItemAnchor">
-							<div class="mblListItemTextBox">Fade</div>
-						</a>
-					</li>
-				</ul>
-
-				<div class="mblRoundRect">
-					<ol>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-					</ol>
-				</div>
-			</div>
-		</div>
-
-		<div id="footer1" class="mblTabBar">Fixed Footer</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_scrollable-no-dojo-ah-af.html b/dojox/mobile/tests/test_scrollable-no-dojo-ah-af.html
deleted file mode 100644
index 5e0fa54..0000000
--- a/dojox/mobile/tests/test_scrollable-no-dojo-ah-af.html
+++ /dev/null
@@ -1,153 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html class="mobile">
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>scrollable no-dojo with app header/footer</title>
-		<!--
-			scrollable.js is a hybrid module, which can be used with or without dojo.
-			In this example, scrollable.js is used without dojo.
-			scrollable.js has several methods that simulate dojo APIs, which are used
-			when you use scrollable.js without dojo.
-			Note that those methods are surrounded by excludeStart/excludeEnd pragmas,
-			and will be removed if you do typical dojo build.
-			If that is the case, this example does not work.
-		-->
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			visibility: visible;
-		}
-		.domNode {
-			position: relative;
-			height: 100%;
-			overflow: hidden;
-		}
-		.containerNode {
-			position: absolute;
-			width: 100%;
-		}
-		#header1 {
-			position: relative;
-			width: 100%;
-		}
-		#footer1 {
-			position: absolute;
-			width: 100%;
-			bottom: 0px;
-		}
-		</style>
-		<script type="text/javascript" src="../scrollable.js"></script>
-
-		<script language="JavaScript" type="text/javascript">
-		function onLoad(){
-			var scrollable = new dojox.mobile.scrollable();
-			scrollable.init({
-				domNode: document.getElementById("outer"),
-				containerNode: document.getElementById("inner"),
-				fixedFooterHeight: document.getElementById("footer1").offsetHeight
-			});
-			dojo.connect(dojo.global, (dojo.global.onorientationchange !== undefined)
-				? "onorientationchange" : "onresize", scrollable, "resize");
-		}
-		</script>
-	</head>
-	<body onload="onLoad()">
-		<h1 id="header1" class="mblHeading">Fixed Header (No-Dojo)</h1>
-
-		<div id="outer" class="domNode">
-			<div id="inner" class="containerNode">
-				<h2 class="mblRoundRectCategory">Transition Effects</h2>
-				<ul class="mblRoundRectList">
-					<li class="mblListItem">
-						<img class="mblListItemIcon" src="images/i-icon-1.png">
-						<a class="mblListItemAnchor">
-							<div class="mblListItemTextBox">Slide</div>
-						</a>
-					</li>
-					<li class="mblListItem">
-						<img class="mblListItemIcon" src="images/i-icon-2.png">
-						<a class="mblListItemAnchor">
-							<div class="mblListItemTextBox">Flip</div>
-						</a>
-					</li>
-					<li class="mblListItem">
-						<img class="mblListItemIcon" src="images/i-icon-3.png">
-						<a class="mblListItemAnchor">
-							<div class="mblListItemTextBox">Fade</div>
-						</a>
-					</li>
-				</ul>
-
-				<div class="mblRoundRect">
-					<ol>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-					</ol>
-				</div>
-			</div>
-		</div>
-
-		<div id="footer1" class="mblTabBar">Fixed Footer</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_scrollable-no-dojo-ah.html b/dojox/mobile/tests/test_scrollable-no-dojo-ah.html
deleted file mode 100644
index 481d9b5..0000000
--- a/dojox/mobile/tests/test_scrollable-no-dojo-ah.html
+++ /dev/null
@@ -1,145 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html class="mobile">
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>scrollable no-dojo with app header</title>
-		<!--
-			scrollable.js is a hybrid module, which can be used with or without dojo.
-			In this example, scrollable.js is used without dojo.
-			scrollable.js has several methods that simulate dojo APIs, which are used
-			when you use scrollable.js without dojo.
-			Note that those methods are surrounded by excludeStart/excludeEnd pragmas,
-			and will be removed if you do typical dojo build.
-			If that is the case, this example does not work.
-		-->
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<style>
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			visibility: visible;
-		}
-		.domNode {
-			position: relative;
-			height: 100%;
-			overflow: hidden;
-		}
-		.containerNode {
-			position: absolute;
-			width: 100%;
-		}
-		#header1 {
-			position: relative;
-			width: 100%;
-		}
-		</style>
-		<script type="text/javascript" src="../scrollable.js"></script>
-
-		<script language="JavaScript" type="text/javascript">
-		function onLoad(){
-			var scrollable = new dojox.mobile.scrollable();
-			scrollable.init({
-				domNode: document.getElementById("outer"),
-				containerNode: document.getElementById("inner")
-			});
-			dojo.connect(dojo.global, (dojo.global.onorientationchange !== undefined)
-				? "onorientationchange" : "onresize", scrollable, "resize");
-		}
-		</script>
-	</head>
-	<body onload="onLoad()">
-		<h1 id="header1" class="mblHeading">Fixed Header (No-Dojo)</h1>
-
-		<div id="outer" class="domNode">
-			<div id="inner" class="containerNode">
-				<h2 class="mblRoundRectCategory">Transition Effects</h2>
-				<ul class="mblRoundRectList">
-					<li class="mblListItem">
-						<img class="mblListItemIcon" src="images/i-icon-1.png">
-						<a class="mblListItemAnchor">
-							<div class="mblListItemTextBox">Slide</div>
-						</a>
-					</li>
-					<li class="mblListItem">
-						<img class="mblListItemIcon" src="images/i-icon-2.png">
-						<a class="mblListItemAnchor">
-							<div class="mblListItemTextBox">Flip</div>
-						</a>
-					</li>
-					<li class="mblListItem">
-						<img class="mblListItemIcon" src="images/i-icon-3.png">
-						<a class="mblListItemAnchor">
-							<div class="mblListItemTextBox">Fade</div>
-						</a>
-					</li>
-				</ul>
-
-				<div class="mblRoundRect">
-					<ol>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-						<li>Item</li>
-					</ol>
-				</div>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_scrollable-no-dojo.html b/dojox/mobile/tests/test_scrollable-no-dojo.html
deleted file mode 100644
index 1f671fe..0000000
--- a/dojox/mobile/tests/test_scrollable-no-dojo.html
+++ /dev/null
@@ -1,122 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>scrollable no-dojo</title>
-		<!--
-			scrollable.js is a hybrid module, which can be used with or without dojo.
-			In this example, scrollable.js is used without dojo.
-			scrollable.js has several methods that simulate dojo APIs, which are used
-			when you use scrollable.js without dojo.
-			Note that those methods are surrounded by excludeStart/excludeEnd pragmas,
-			and will be removed if you do typical dojo build.
-			If that is the case, this example does not work.
-		-->
-		<style>
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			width: 100%;
-			margin: 0px;
-			padding: 0px;
-		}
-		.domNode {
-			position: relative;
-			height: 100%;
-			overflow: hidden;
-		}
-		#header1 {
-			position: relative;
-			margin: 0px;
-			width: 100%;
-			background-color: cyan;
-			z-index: 1;
-			font-size: 20px;
-		}
-			
-		</style>
-		<script type="text/javascript" src="../scrollable.js"></script>
-
-		<script language="JavaScript" type="text/javascript">
-		function onLoad(){
-			var scrollable = new dojox.mobile.scrollable();
-			scrollable.init({
-				domNode: document.getElementById("outer"),
-				containerNode: document.getElementById("inner")
-			});
-			dojo.connect(dojo.global, (dojo.global.onorientationchange !== undefined)
-				? "onorientationchange" : "onresize", scrollable, "resize");
-		}
-		</script>
-	</head>
-	<body onload="onLoad()">
-		<h1 id="header1">Fixed Header (No-Dojo)</h1>
-		<div id="outer" class="domNode">
-			<div id="inner" class="containerNode" style="position:absolute;width:100%">
-				<ol>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-					<li>Item</li>
-				</ol>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/test_tablet-settings.html b/dojox/mobile/tests/test_tablet-settings.html
new file mode 100644
index 0000000..836c1a9
--- /dev/null
+++ b/dojox/mobile/tests/test_tablet-settings.html
@@ -0,0 +1,239 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Tablet Settings</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','FixedSplitter']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/Container"
+		]);
+	</script>
+
+	<style>
+	html, body{
+		height: 100%;
+		overflow: hidden;
+		position: relative;
+	}
+	.mblEdgeToEdgeList {
+		background-color: #DBDDE2;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Container" style="width:300px;border-right:1px solid black;">
+			<div id="settings" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Settings</h1>
+				<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" data-dojo-props='transition:"flip", stateful:true'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						Wi-Fi
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Brightness & Wallpaper
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Picture Frame
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general", selected:true'>
+						General
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"wifi"'>
+						Mail, Contacts, Calendars
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"bright"'>
+						Safari
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"picture"'>
+						iPod
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"general"'>
+						Video
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"wifi"'>
+						Photos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"bright"'>
+						Store
+					</li>
+					<li class="mblEdgeToEdgeCategory">
+						Apps
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						News
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Weather
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Books
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general"'>
+						 Business
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"wifi"'>
+						Navigation
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bright"'>
+						Sports
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"picture"'>
+						Social
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"general"'>
+						Music
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Container">
+
+			<div id="general" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>General</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						About
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2h 40m", moveTo:"about"'>
+						Usage
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Network
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Bluetooth
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Location Services
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1 Minute", moveTo:"about"'>
+						Auto-Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Passcode Lock
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"Off", moveTo:"about"'>
+						Restrictions
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Home
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Date & Time					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Keyboard					   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						International				   
+					</li>							   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Accessibility
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"about"'>
+						Reset
+					</li>
+				</ul>
+			</div>
+
+			<div id="about" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top", back:"General", moveTo:"general"'>About</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Network											   
+					</li>												   
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"AcmePhone"'>
+						Line
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"1024"'>
+						Songs
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"10"'>
+						Videos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"96"'>
+						Photos
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"2"'>
+						Applications
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"29.3 BG"'>
+						Capacity
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"28.0 BG"'>
+						Available
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText:"3.0 (7A341)"'>
+						Version
+					</li>
+				</ul>
+			</div>
+
+			<div id="wifi" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Wi-Fi Networks</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Wi-Fi
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<input type="text">
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						<select><option>Songs</option><option>Videos</option><option>Photos</option></select>
+					</li>
+				</ul>
+			</div>
+
+			<div id="bright" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Brightness & Wallpaper</h1>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Auto-Brightness
+						<div data-dojo-type="dojox.mobile.Switch"></div>
+					</li>
+				</ul>
+			</div>
+
+			<div id="picture" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Picture Frame</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList" data-dojo-props='select:"single"'>
+					<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='checked:true'>
+						Dissolve
+					</li>
+					<li data-dojo-type="dojox.mobile.ListItem">
+						Origami
+					</li>
+				</ul>
+			</div>
+
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_theme-iOS6.html b/dojox/mobile/tests/test_theme-iOS6.html
new file mode 100644
index 0000000..c3fb0d4
--- /dev/null
+++ b/dojox/mobile/tests/test_theme-iOS6.html
@@ -0,0 +1,102 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
+<meta name="apple-mobile-web-app-capable" content="yes" />
+<title>iOS6 showcase</title>
+<script type="text/javascript" src="../deviceTheme.js"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+<script language="JavaScript" type="text/javascript">
+	require([
+	 	"dijit/registry",
+	 	"dojox/mobile",				// This is a mobile app.
+		"dojox/mobile/ScrollableView",		// This mobile app uses mobile view
+		"dojox/mobile/Heading",
+		"dojox/mobile/RoundRectList",
+		"dojox/mobile/TabBar",
+		"dojox/mobile/Opener",
+		"dojox/mobile/SimpleDialog",
+		"dojox/mobile/Button",
+		"dojox/mobile/SpinWheelDatePicker",
+		"dojox/mobile/parser"		// This mobile app uses declarative programming with fast mobile parser
+	], function(registry) {
+ 		show = function(dlg, node){
+		    registry.byId(dlg).show(node);
+		  };
+		  hide = function(dlg){
+		    registry.byId(dlg).hide();
+		  };
+	});
+</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='back: "Back", label:"Settings"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton" style="float: right;">Edit</span>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"
+			        data-dojo-props='label:"Done",defaultColor:"mblColorBlue"'
+			        style="float:right;"></span>
+		</div>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Round Rect Category</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem">Airplane Mode
+				<div data-dojo-type="dojox.mobile.Switch" class="mblItemSwitch"></div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='rightText: "IBM", moveTo: "view2"'>Wi-Fi</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo: "view2"'>Bluetooth</li>
+		</ul>
+		<div data-dojo-type="dojox.mobile.Heading" fixed="bottom">
+		</div>
+	</div>
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Second View"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"
+			        data-dojo-props='arrow:"right",
+			                         moveTo:"view3",
+			                         transition:"slide",
+			                         transitionDir:1'
+               		style="float: right;">Next</span>
+		</div>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+		  This view displays a segmented control tab bar, at the bottom.
+		</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"segmentedControl"' fixed="bottom">
+		  <li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>New</li>
+		  <li data-dojo-type="dojox.mobile.TabBarButton">What's Hot</li>
+		  <li data-dojo-type="dojox.mobile.TabBarButton">Genius</li>
+		</ul>
+	</div>
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">
+		<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Third View"'>
+			<span data-dojo-type="dojox.mobile.ToolBarButton"
+			        data-dojo-props='arrow:"right",
+			                         moveTo:"view1",
+			                         transition:"slide",
+			                         transitionDir:1'
+               		style="float: right;">Next</span>
+		</div>
+		<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"standardTab"'>
+		  <li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true'>New</li>
+		  <li data-dojo-type="dojox.mobile.TabBarButton">What's Hot</li>
+		  <li data-dojo-type="dojox.mobile.TabBarButton">Genius</li>
+		</ul>
+
+		<button data-dojo-type="dojox.mobile.Button" onclick="show('customPicker', this.domNode)">Show Opener</button>
+		<div id="customPicker" data-dojo-type="dojox.mobile.Opener">
+		      <h1 data-dojo-type="dojox.mobile.Heading" label="Custom Picker">
+		              <div data-dojo-type="dojox.mobile.ToolBarButton" label="Done" class="mblColorBlue" style="width:45px;float:right;" onClick="hide('customPicker')"></div>
+		      </h1>
+		      <div id="spin1" data-dojo-type="dojox.mobile.SpinWheelDatePicker"></div>
+		</div>
+
+		<div id="dlg_message" data-dojo-type="dojox.mobile.SimpleDialog">
+		  <div class="mblSimpleDialogTitle">Information</div>
+		  <div class="mblSimpleDialogText">This is a sample dialog.</div>
+		  <button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton"
+		          style="width:100px;" onclick="hide('dlg_message')">OK</button>
+		</div>		
+		<button onclick="show('dlg_message')">Show Dialog</button>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_theme-switch.html b/dojox/mobile/tests/test_theme-switch.html
new file mode 100644
index 0000000..16af632
--- /dev/null
+++ b/dojox/mobile/tests/test_theme-switch.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Dynamic Theme Switch</title>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblThemeFiles: ['base','TabBar']"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/deviceTheme",
+			"dojox/mobile/TabBar"
+		]);
+		change = function(ua){
+			deviceTheme.loadDeviceTheme(ua);
+		}
+	</script>
+
+	<style>
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	.mblColorPink {
+		background-image: -webkit-gradient(linear, left top, left bottom, from(#ff9DE9), to(#cc62DD), color-stop(0.5, #ff6EDF), color-stop(0.5, #ff5FDC));
+		background-image: -moz-linear-gradient(top, #ff9DE9 0%, #ff6EDF 50%, #ff5FDC 50%, #cc62DD 100%);
+		background-color: pink;
+	}
+	.mblColorPink45 {
+		background-image: -webkit-gradient(linear, left top, right bottom, from(#ff9DE9), to(#cc62DD), color-stop(0.5, #ff6EDF), color-stop(0.5, #ff5FDC));
+		background-image: -moz-linear-gradient(top left, #ff9DE9 0%, #ff6EDF 50%, #ff5FDC 50%, #cc62DD 100%);
+	}
+	#themeHeading {
+		overflow: visible;
+		height: auto;
+	}
+	#themeHeading .mblTabBarSlimTab {
+  		display: inline;
+  		float: left;
+  		height: auto;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="foo" data-dojo-type="dojox.mobile.View">
+		<div id="themeHeading" data-dojo-type="dojox.mobile.Heading">
+			<ul data-dojo-type="dojox.mobile.TabBar" data-dojo-props='barType:"slimTab"' style="float:left">
+				<li data-dojo-type="dojox.mobile.TabBarButton" data-dojo-props='selected:true' onclick="change('iPhone')">iPhone</li>
+				<li data-dojo-type="dojox.mobile.TabBarButton" onclick="change('iPad')">iPad</li>
+				<li data-dojo-type="dojox.mobile.TabBarButton" onclick="change('Android')">Android</li>
+				<li data-dojo-type="dojox.mobile.TabBarButton" onclick="change('BlackBerry')">BlackBerry</li>
+				<li data-dojo-type="dojox.mobile.TabBarButton" onclick="change('Custom')">Custom</li>
+			</ul>
+		</div>
+	<div data-dojo-type="dojox.mobile.Heading" data-dojo-props='label:"Arrow"'>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" arrow="left" defaultColor="mblColorBlue" selColor="mblColorPink">MMMM</span>
+		<span data-dojo-type="dojox.mobile.ToolBarButton" arrow="right">MMMM</span>
+	</div>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Dynamic Theme Switch</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"bar", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"bar", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"bar", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
+
+	<div id="bar" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"foo"'>Search Result</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$14.50 (50%)</span> In Stock<br>
+				# (531)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<span style="color:red">$14.00 (60%)</span> In Stock<br>
+				# (173)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <span style="color:green"><b>16 hours</b></span><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$9.50 (62%)</span> In Stock<br>
+				# (1199)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<span style="color:blue">Not Available</span>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" style="font-size:10px" data-dojo-props='variableHeight:true'>
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<span style="color:red">$12.00 (60%)</span> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_transition-animations-extended1.html b/dojox/mobile/tests/test_transition-animations-extended1.html
index e7dd8e1..b20962f 100644
--- a/dojox/mobile/tests/test_transition-animations-extended1.html
+++ b/dojox/mobile/tests/test_transition-animations-extended1.html
@@ -1,66 +1,72 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Extended Transitions 1</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Extended Transitions 1</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.compat");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-		<style>
-		html,body {
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 1</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Extended Transitions 1</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="dissolve">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view2" transition="slidev">
-					Slide Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view3" transition="slidev" transitionDir="-1">
-					Slide Vertical (Reverse)
-				</li>
-			</ul>
-		</div>
+	<link href="../themes/common/transitions.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-		<div id="view2" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 2</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Extended Transitions 1</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="dissolve">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="slidev">
-					Slide Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view1" transition="slidev" transitionDir="-1">
-					Slide Vertical (Reverse)
-				</li>
-			</ul>
-		</div>
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
 
-		<div id="view3" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 3</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="Dissolve" icon="images/icon9.png" lazy="true" moveTo="view1" transition="dissolve"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Slide Vertical" icon="images/icon2.png" lazy="true" moveTo="view1" transition="slidev"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Slide Vertical (Reverse)" icon="images/icon3.png" lazy="true" moveTo="view2" transition="slidev" transitionDir="-1"></li>
-			</ul>
-		</div>
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 1</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Extended Transitions 1</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"dissolve"'>
+				Dissolve
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"slidev"'>
+				Slide Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view3", transition:"slidev", transitionDir:-1'>
+				Slide Vertical (Reverse)
+			</li>
+		</ul>
+	</div>
 
-	</body>
+	<div id="view2" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 2</h1>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Extended Transitions 1</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"dissolve"'>
+				Dissolve
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"slidev"'>
+				Slide Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view1", transition:"slidev", transitionDir:-1'>
+				Slide Vertical (Reverse)
+			</li>
+		</ul>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 3</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Dissolve", icon:"images/icon9.png", lazy:true, moveTo:"view1", transition:"dissolve"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Slide Vertical", icon:"images/icon2.png", lazy:true, moveTo:"view1", transition:"slidev"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Slide Vertical (Reverse)", icon:"images/icon3.png", lazy:true, moveTo:"view2", transition:"slidev", transitionDir:-1'></li>
+		</ul>
+	</div>
+
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_transition-animations-extended2.html b/dojox/mobile/tests/test_transition-animations-extended2.html
index d787662..21e4121 100644
--- a/dojox/mobile/tests/test_transition-animations-extended2.html
+++ b/dojox/mobile/tests/test_transition-animations-extended2.html
@@ -1,85 +1,91 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Extended Transitions 2</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Extended Transitions 2</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.compat");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-		<style>
-		html,body {
-			height: 100%;
-			overflow: hidden;
-		}
-		.mblView {
-			background-color: #c5ccd3;
-		}
-		.android_theme .mblView {
-			background-color: black;
-		}
-		.blackberry_theme .mblView {
-			background-color: #DEDFDE;
-		}
-		.custom_theme .mblView {
-			background-color: #eff1f3;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 1</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Extended Transitions 2</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="cover">
-					Cover
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view3" transition="cover" transitionDir="-1">
-					Cover (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="coverv">
-					Cover Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view3" transition="coverv" transitionDir="-1">
-					Cover Vertical (Reverse)
-				</li>
-			</ul>
-		</div>
+	<link href="../themes/common/transitions.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-		<div id="view2" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 2</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Extended Transitions 2</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="cover">
-					Cover
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view1" transition="cover" transitionDir="-1">
-					Cover (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="coverv">
-					Cover Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view1" transition="coverv" transitionDir="-1">
-					Cover Vertical (Reverse)
-				</li>
-			</ul>
-		</div>
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
 
-		<div id="view3" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 3</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="Cover" icon="images/icon9.png" lazy="true" moveTo="view1" transition="cover"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Cover (Reverse)" icon="images/icon2.png" lazy="true" moveTo="view2" transition="cover" transitionDir="-1"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Cover Vertical" icon="images/icon3.png" lazy="true" moveTo="view1" transition="coverv"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Cover Vertical (Reverse)" icon="images/icon1.png" lazy="true" moveTo="view2" transition="coverv" transitionDir="-1"></li>
-			</ul>
-		</div>
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	.mblView {
+		background-color: #c5ccd3;
+	}
+	.android_theme .mblView {
+		background-color: black;
+	}
+	.blackberry_theme .mblView {
+		background-color: #DEDFDE;
+	}
+	.custom_theme .mblView {
+		background-color: #eff1f3;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 1</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Extended Transitions 2</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"cover"'>
+				Cover
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view3", transition:"cover", transitionDir:-1'>
+				Cover (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"coverv"'>
+				Cover Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view3", transition:"coverv", transitionDir:-1'>
+				Cover Vertical (Reverse)
+			</li>
+		</ul>
+	</div>
 
-	</body>
+	<div id="view2" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 2</h1>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Extended Transitions 2</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"cover"'>
+				Cover
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view1", transition:"cover", transitionDir:-1'>
+				Cover (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"coverv"'>
+				Cover Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view1", transition:"coverv", transitionDir:-1'>
+				Cover Vertical (Reverse)
+			</li>
+		</ul>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 3</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Cover", icon:"images/icon9.png", lazy:true, moveTo:"view1", transition:"cover"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Cover (Reverse)", icon:"images/icon2.png", lazy:true, moveTo:"view2", transition:"cover", transitionDir:-1'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Cover Vertical", icon:"images/icon3.png", lazy:true, moveTo:"view1", transition:"coverv"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Cover Vertical (Reverse)", icon:"images/icon1.png", lazy:true, moveTo:"view2", transition:"coverv", transitionDir:-1'></li>
+		</ul>
+	</div>
+
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_transition-animations-extended3.html b/dojox/mobile/tests/test_transition-animations-extended3.html
index 0a19e4f..082fe1d 100644
--- a/dojox/mobile/tests/test_transition-animations-extended3.html
+++ b/dojox/mobile/tests/test_transition-animations-extended3.html
@@ -1,85 +1,91 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Extended Transitions 3</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Extended Transitions 3</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.compat");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-		<style>
-		html,body {
-			height: 100%;
-			overflow: hidden;
-		}
-		.mblView {
-			background-color: #c5ccd3;
-		}
-		.android_theme .mblView {
-			background-color: black;
-		}
-		.blackberry_theme .mblView {
-			background-color: #DEDFDE;
-		}
-		.custom_theme .mblView {
-			background-color: #eff1f3;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 1</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Extended Transitions 3</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="reveal">
-					Reveal
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view3" transition="reveal" transitionDir="-1">
-					Reveal (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="revealv">
-					Reveal Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view3" transition="revealv" transitionDir="-1">
-					Reveal Vertical (Reverse)
-				</li>
-			</ul>
-		</div>
+	<link href="../themes/common/transitions.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-		<div id="view2" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 2</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Extended Transitions 3</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="reveal">
-					Reveal
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view1" transition="reveal" transitionDir="-1">
-					Reveal (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="revealv">
-					Reveal Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view1" transition="revealv" transitionDir="-1">
-					Reveal Vertical (Reverse)
-				</li>
-			</ul>
-		</div>
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
 
-		<div id="view3" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 3</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="Reveal" icon="images/icon9.png" lazy="true" moveTo="view1" transition="reveal"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Reveal (Reverse)" icon="images/icon2.png" lazy="true" moveTo="view2" transition="reveal" transitionDir="-1"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Reveal Vertical" icon="images/icon3.png" lazy="true" moveTo="view1" transition="revealv"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Reveal Vertical (Reverse)" icon="images/icon1.png" lazy="true" moveTo="view2" transition="revealv" transitionDir="-1"></li>
-			</ul>
-		</div>
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	.mblView {
+		background-color: #c5ccd3;
+	}
+	.android_theme .mblView {
+		background-color: black;
+	}
+	.blackberry_theme .mblView {
+		background-color: #DEDFDE;
+	}
+	.custom_theme .mblView {
+		background-color: #eff1f3;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 1</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Extended Transitions 3</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"reveal"'>
+				Reveal
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view3", transition:"reveal", transitionDir:-1'>
+				Reveal (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"revealv"'>
+				Reveal Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view3", transition:"revealv", transitionDir:-1'>
+				Reveal Vertical (Reverse)
+			</li>
+		</ul>
+	</div>
 
-	</body>
+	<div id="view2" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 2</h1>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Extended Transitions 3</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"reveal"'>
+				Reveal
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view1", transition:"reveal", transitionDir:-1'>
+				Reveal (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"revealv"'>
+				Reveal Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view1", transition:"revealv", transitionDir:-1'>
+				Reveal Vertical (Reverse)
+			</li>
+		</ul>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 3</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Reveal", icon:"images/icon9.png", lazy:true, moveTo:"view1", transition:"reveal"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Reveal (Reverse)", icon:"images/icon2.png", lazy:true, moveTo:"view2", transition:"reveal", transitionDir:-1'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Reveal Vertical", icon:"images/icon3.png", lazy:true, moveTo:"view1", transition:"revealv"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Reveal Vertical (Reverse)", icon:"images/icon1.png", lazy:true, moveTo:"view2", transition:"revealv", transitionDir:-1'></li>
+		</ul>
+	</div>
+
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_transition-animations-extended4.html b/dojox/mobile/tests/test_transition-animations-extended4.html
index 0b49c94..6ed5eeb 100644
--- a/dojox/mobile/tests/test_transition-animations-extended4.html
+++ b/dojox/mobile/tests/test_transition-animations-extended4.html
@@ -1,73 +1,79 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Extended Transitions 4</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Extended Transitions 4</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.compat");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-		<style>
-		html,body {
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 1</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Extended Transitions 4</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="zoomOut">
-					Zoom Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view2" transition="zoomIn">
-					Zoom In
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="scaleOut">
-					Scale Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view2" transition="scaleIn">
-					Scale In
-				</li>
-			</ul>
-		</div>
+	<link href="../themes/common/transitions.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-		<div id="view2" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 2</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Extended Transitions 4</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="zoomOut">
-					Zoom Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="zoomIn">
-					Zoom In
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="scaleOut">
-					Scale Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="scaleIn">
-					Scale In
-				</li>
-			</ul>
-		</div>
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
 
-		<div id="view3" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 3</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="Zoom Out" icon="images/icon9.png" lazy="true" moveTo="view1" transition="zoomOut"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Zoom In" icon="images/icon2.png" lazy="true" moveTo="view1" transition="zoomIn"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Scale Out" icon="images/icon3.png" lazy="true" moveTo="view1" transition="scaleOut"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Scale In" icon="images/icon1.png" lazy="true" moveTo="view1" transition="scaleIn"></li>
-			</ul>
-		</div>
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 1</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Extended Transitions 4</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"zoomOut"'>
+				Zoom Out
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"zoomIn"'>
+				Zoom In
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"scaleOut"'>
+				Scale Out
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"scaleIn"'>
+				Scale In
+			</li>
+		</ul>
+	</div>
 
-	</body>
+	<div id="view2" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 2</h1>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Extended Transitions 4</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"zoomOut"'>
+				Zoom Out
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"zoomIn"'>
+				Zoom In
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"scaleOut"'>
+				Scale Out
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"scaleIn"'>
+				Scale In
+			</li>
+		</ul>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 3</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Zoom Out", icon:"images/icon9.png", lazy:true, moveTo:"view1", transition:"zoomOut"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Zoom In", icon:"images/icon2.png", lazy:true, moveTo:"view1", transition:"zoomIn"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Scale Out", icon:"images/icon3.png", lazy:true, moveTo:"view1", transition:"scaleOut"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Scale In", icon:"images/icon1.png", lazy:true, moveTo:"view1", transition:"scaleIn"'></li>
+		</ul>
+	</div>
+
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_transition-animations-extended5.html b/dojox/mobile/tests/test_transition-animations-extended5.html
index af7bf39..34a035c 100644
--- a/dojox/mobile/tests/test_transition-animations-extended5.html
+++ b/dojox/mobile/tests/test_transition-animations-extended5.html
@@ -1,59 +1,99 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Extended Transitions 5</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Extended Transitions 5</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.compat");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-		<style>
-		html,body {
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 1</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Extended Transitions 5</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="swirl">
-					Swirl
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view3" transition="swirl" transitionDir="-1">
-					Swirl (Reverse)
-				</li>
-			</ul>
-		</div>
+	<link href="../themes/common/transitions.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-		<div id="view2" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 2</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Extended Transitions 5</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="swirl">
-					Swirl
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view1" transition="swirl" transitionDir="-1">
-					Swirl (Reverse)
-				</li>
-			</ul>
-		</div>
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
 
-		<div id="view3" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 3</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="Swirl" icon="images/icon9.png" lazy="true" moveTo="view1" transition="swirl"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Swirl (Reverse)" icon="images/icon2.png" lazy="true" moveTo="view2" transition="swirl" transitionDir="-1"></li>
-			</ul>
-		</div>
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 1</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Extended Transitions 5</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"swirl"'>
+				Swirl
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view3", transition:"swirl", transitionDir:-1'>
+				Swirl (Reverse)
+			</li>
+			<!-- 1.8 -->
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"swap"'>
+				Swap
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view3", transition:"swap", transitionDir:-1'>
+				Swap (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"cube"'>
+				Cube
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view3", transition:"cube", transitionDir:-1'>
+				Cube (Reverse)
+			</li>
+			<!-- 1.8 -->
+		</ul>
+	</div>
 
-	</body>
+	<div id="view2" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 2</h1>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Extended Transitions 5</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<!-- 1.8 -->
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view3", transition:"swirl"'>
+				Swirl
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view1", transition:"swirl", transitionDir:-1'>
+				Swirl (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view3", transition:"swap"'>
+				Swap
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view1", transition:"swap", transitionDir:-1'>
+				Swap (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view3", transition:"cube"'>
+				Cube
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-6.png", moveTo:"view1", transition:"cube", transitionDir:-1'>
+				Cube (Reverse)
+			</li>
+			<!-- 1.8 -->
+		</ul>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 3</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Swirl", icon:"images/icon9.png", lazy:true, moveTo:"view1", transition:"swirl"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Swirl (Reverse)", icon:"images/icon2.png", lazy:true, moveTo:"view2", transition:"swirl", transitionDir:-1'></li>
+			<!-- 1.8 -->
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Swap", icon:"images/icon3.png", moveTo:"view1", transition:"swap"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Swap (Reverse)", icon:"images/icon1.png", moveTo:"view2", transition:"swap", transitionDir:-1'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Cube", icon:"images/icon7.png", moveTo:"view1", transition:"cube"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Cube (Reverse)", icon:"images/icon6.png", moveTo:"view2", transition:"cube", transitionDir:-1'></li>
+			<!-- 1.8 -->
+		</ul>
+	</div>
+
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_transition-animations-standard.html b/dojox/mobile/tests/test_transition-animations-standard.html
index 4f485d2..99997ac 100644
--- a/dojox/mobile/tests/test_transition-animations-standard.html
+++ b/dojox/mobile/tests/test_transition-animations-standard.html
@@ -1,73 +1,79 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Standard Transitions</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Standard Transitions</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.compat");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.IconContainer");
-		</script>
-		<style>
-		html,body {
-			height: 100%;
-			overflow: hidden;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 1</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view3" transition="slide" transitionDir="-1">
-					Slide (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view2" transition="fade">
-					Fade
-				</li>
-			</ul>
-		</div>
+	<link href="../themes/common/transitions.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base','IconContainer']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
-		<div id="view2" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 2</h1>
-			<h2 dojoType="dojox.mobile.EdgeToEdgeCategory">Standard Transitions</h2>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList">
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view1" transition="slide" transitionDir="-1">
-					Slide (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" moveTo="view3" transition="fade">
-					Fade
-				</li>
-			</ul>
-		</div>
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/IconContainer"
+		]);
+	</script>
 
-		<div id="view3" dojoType="dojox.mobile.View" style="height:100%;">
-			<h1 dojoType="dojox.mobile.Heading" back="Top" href="test_transition-animations.html" transition="none">View 3</h1>
-			<ul dojoType="dojox.mobile.IconContainer">
-				<li dojoType="dojox.mobile.IconItem" label="Slide" icon="images/icon9.png" lazy="true" moveTo="view1" transition="slide"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Slide (Reverse)" icon="images/icon2.png" lazy="true" moveTo="view2" transition="slide" transitionDir="-1"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Flip" icon="images/icon3.png" lazy="true" moveTo="view1" transition="flip"></li>
-				<li dojoType="dojox.mobile.IconItem" label="Fade" icon="images/icon1.png" lazy="true" moveTo="view1" transition="fade"></li>
-			</ul>
-		</div>
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 1</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view3", transition:"slide", transitionDir:-1'>
+				Slide (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
 
-	</body>
+	<div id="view2" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 2</h1>
+		<h2 data-dojo-type="dojox.mobile.EdgeToEdgeCategory">Standard Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.EdgeToEdgeList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view1", transition:"slide", transitionDir:-1'>
+				Slide (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='moveTo:"view3", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
+
+	<div id="view3" data-dojo-type="dojox.mobile.View" style="height:100%;">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Top", href:"test_transition-animations.html", transition:"none"'>View 3</h1>
+		<ul data-dojo-type="dojox.mobile.IconContainer">
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Slide", icon:"images/icon9.png", lazy:true, moveTo:"view1", transition:"slide"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Slide (Reverse)", icon:"images/icon2.png", lazy:true, moveTo:"view2", transition:"slide", transitionDir:-1'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Flip", icon:"images/icon3.png", lazy:true, moveTo:"view1", transition:"flip"'></li>
+			<li data-dojo-type="dojox.mobile.IconItem" data-dojo-props='label:"Fade", icon:"images/icon1.png", lazy:true, moveTo:"view1", transition:"fade"'></li>
+		</ul>
+	</div>
+
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_transition-animations.html b/dojox/mobile/tests/test_transition-animations.html
index 96c3095..da746fb 100644
--- a/dojox/mobile/tests/test_transition-animations.html
+++ b/dojox/mobile/tests/test_transition-animations.html
@@ -1,65 +1,70 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Sample of View Transitions</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Sample of View Transitions</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app uses declarative programming with fast mobile parser
-			dojo.require("dojox.mobile.compat");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.deviceTheme");
-		</script>
-		<style>
-		.mblListItemSubText {
-			color: gray;
-			font-size: 13px;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="top" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Sample of View Transitions</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_transition-animations-standard.html" transition="none">
-					Standard Transitions 
-				    <div class="mblListItemSubText">
-					    Slide, Flip, Fade
-				    </div>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_transition-animations-extended1.html" transition="none">
-					Extended Transitions 1
-				    <div class="mblListItemSubText">
-					    Dissolve, Slide Vertical
-				    </div>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_transition-animations-extended2.html" transition="none">
-					Extended Transitions 2
-				    <div class="mblListItemSubText">
-					    Cover, Cover Vertical
-				    </div>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_transition-animations-extended3.html" transition="none">
-					Extended Transitions 3
-				    <div class="mblListItemSubText">
-					    Reveal, Reveal Vertical
-				    </div>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_transition-animations-extended4.html" transition="none">
-					Extended Transitions 4
-				    <div class="mblListItemSubText">
-					    Zoom In/Out, Scale In/Out
-				    </div>
-				</li>
-				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" href="test_transition-animations-extended5.html" transition="none">
-					Extended Transitions 5
-				    <div class="mblListItemSubText">
-					    Swirl
-				    </div>
-				</li>
-			</ul>
-		</div>
-	</body>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		]);
+	</script>
+
+	<style>
+	.mblListItemSubText {
+		color: gray;
+		font-size: 13px;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="top" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Sample of View Transitions</h1>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_transition-animations-standard.html", transition:"none", variableHeight:true'>
+				Standard Transitions 
+			    <div class="mblListItemSubText">
+				    Slide, Flip, Fade
+			    </div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_transition-animations-extended1.html", transition:"none", variableHeight:true'>
+				Extended Transitions 1
+			    <div class="mblListItemSubText">
+				    Dissolve, Slide Vertical
+			    </div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_transition-animations-extended2.html", transition:"none", variableHeight:true'>
+				Extended Transitions 2
+			    <div class="mblListItemSubText">
+				    Cover, Cover Vertical
+			    </div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_transition-animations-extended3.html", transition:"none", variableHeight:true'>
+				Extended Transitions 3
+			    <div class="mblListItemSubText">
+				    Reveal, Reveal Vertical
+			    </div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_transition-animations-extended4.html", transition:"none", variableHeight:true'>
+				Extended Transitions 4
+			    <div class="mblListItemSubText">
+				    Zoom In/Out, Scale In/Out
+			    </div>
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='href:"test_transition-animations-extended5.html", transition:"none", variableHeight:true'>
+				Extended Transitions 5
+			    <div class="mblListItemSubText">
+				    Swirl, Swap, Cube
+			    </div>
+			</li>
+		</ul>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_transition-animations2.html b/dojox/mobile/tests/test_transition-animations2.html
index e05d6dd..1b1c1b8 100644
--- a/dojox/mobile/tests/test_transition-animations2.html
+++ b/dojox/mobile/tests/test_transition-animations2.html
@@ -1,258 +1,262 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Transition Animations on ScrollableView</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar:true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Transition Animations on ScrollableView</title>
 
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile.parser");
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.deviceTheme");
-			dojo.require("dojox.mobile.ScrollableView");
+	<link href="../themes/common/transitions.css" rel="stylesheet"/>
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true, mblAlwaysHideAddressBar:true"></script>
 
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-		</script>
-		<style>
-		html,body {
-			height: 100%;
-			overflow: hidden;
-		}
-		.mblView {
-			background-color: #c5ccd3;
-		}
-		.android_theme .mblView {
-			background-color: black;
-		}
-		.blackberry_theme .mblView {
-			background-color: #DEDFDE;
-		}
-		.custom_theme .mblView {
-			background-color: #eff1f3;
-		}
-		</style>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.ScrollableView" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">View 1</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view2" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view3" transition="slide" transitionDir="-1">
-					Slide (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view2" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="fade">
-					Fade
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Extended Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="dissolve">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view2" transition="cover">
-					Cover
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view3" transition="cover" transitionDir="-1">
-					Cover (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="reveal">
-					Reveal
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view3" transition="reveal" transitionDir="-1">
-					Reveal (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view2" transition="slidev">
-					Slide Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view3" transition="slidev" transitionDir="-1">
-					Slide Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view2" transition="coverv">
-					Cover Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view3" transition="coverv" transitionDir="-1">
-					Cover Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view2" transition="revealv">
-					Reveal Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view3" transition="revealv" transitionDir="-1">
-					Reveal Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view2" transition="swirl">
-					Swirl
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view3" transition="swirl" transitionDir="-1">
-					Swirl (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view2" transition="zoomOut">
-					Zoom Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view2" transition="zoomIn">
-					Zoom In
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view2" transition="scaleOut">
-					Scale Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view2" transition="scaleIn">
-					Scale In
-				</li>
-			</ul>
-		</div>
+	<script type="text/javascript">
+		require([
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/ScrollableView"
+		]);
+	</script>
 
-		<div id="view2" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading">View 2</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view3" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view1" transition="slide" transitionDir="-1">
-					Slide (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view3" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view3" transition="fade">
-					Fade
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Extended Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view3" transition="dissolve">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view3" transition="cover">
-					Cover
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view1" transition="cover" transitionDir="-1">
-					Cover (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view3" transition="reveal">
-					Reveal
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view1" transition="reveal" transitionDir="-1">
-					Reveal (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view3" transition="slidev">
-					Slide Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view1" transition="slidev" transitionDir="-1">
-					Slide Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view3" transition="coverv">
-					Cover Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view1" transition="coverv" transitionDir="-1">
-					Cover Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view3" transition="revealv">
-					Reveal Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view1" transition="revealv" transitionDir="-1">
-					Reveal Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view3" transition="swirl">
-					Swirl
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view1" transition="swirl" transitionDir="-1">
-					Swirl (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view3" transition="zoomOut">
-					Zoom Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view3" transition="zoomIn">
-					Zoom In
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view3" transition="scaleOut">
-					Scale Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view3" transition="scaleIn">
-					Scale In
-				</li>
-			</ul>
-		</div>
+	<style>
+	html,body {
+		height: 100%;
+		overflow: hidden;
+	}
+	.mblView {
+		background-color: #c5ccd3;
+	}
+	.android_theme .mblView {
+		background-color: black;
+	}
+	.blackberry_theme .mblView {
+		background-color: #DEDFDE;
+	}
+	.custom_theme .mblView {
+		background-color: #eff1f3;
+	}
+	</style>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading">View 1</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view3", transition:"slide", transitionDir:-1'>
+				Slide (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Extended Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"dissolve"'>
+				Dissolve
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"cover"'>
+				Cover
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view3", transition:"cover", transitionDir:-1'>
+				Cover (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"reveal"'>
+				Reveal
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view3", transition:"reveal", transitionDir:-1'>
+				Reveal (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"slidev"'>
+				Slide Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view3", transition:"slidev", transitionDir:-1'>
+				Slide Vertical (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"coverv"'>
+				Cover Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view3", transition:"coverv", transitionDir:-1'>
+				Cover Vertical (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"revealv"'>
+				Reveal Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view3", transition:"revealv", transitionDir:-1'>
+				Reveal Vertical (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"view2", transition:"swirl"'>
+				Swirl
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"view3", transition:"swirl", transitionDir:-1'>
+				Swirl (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"zoomOut"'>
+				Zoom Out
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"zoomIn"'>
+				Zoom In
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"scaleOut"'>
+				Scale Out
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view2", transition:"scaleIn"'>
+				Scale In
+			</li>
+		</ul>
+	</div>
 
-		<div id="view3" dojoType="dojox.mobile.ScrollableView">
-			<h1 dojoType="dojox.mobile.Heading">View 3</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view1" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view2" transition="slide" transitionDir="-1">
-					Slide (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view1" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view1" transition="fade">
-					Fade
-				</li>
-			</ul>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Extended Transitions</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view1" transition="dissolve">
-					Dissolve
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view1" transition="cover">
-					Cover
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="view2" transition="cover" transitionDir="-1">
-					Cover (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view1" transition="reveal">
-					Reveal
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="reveal" transitionDir="-1">
-					Reveal (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view1" transition="slidev">
-					Slide Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="view2" transition="slidev" transitionDir="-1">
-					Slide Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view1" transition="coverv">
-					Cover Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="view2" transition="coverv" transitionDir="-1">
-					Cover Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view1" transition="revealv">
-					Reveal Vertical
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="view2" transition="revealv" transitionDir="-1">
-					Reveal Vertical (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view1" transition="swirl">
-					Swirl
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="view2" transition="swirl" transitionDir="-1">
-					Swirl (Reverse)
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view1" transition="zoomOut">
-					Zoom Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view1" transition="zoomIn">
-					Zoom In
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view1" transition="scaleOut">
-					Scale Out
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="view1" transition="scaleIn">
-					Scale In
-				</li>
-			</ul>
-		</div>
+	<div id="view2" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading">View 2</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view3", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view1", transition:"slide", transitionDir:-1'>
+				Slide (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view3", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view3", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Extended Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view3", transition:"dissolve"'>
+				Dissolve
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view3", transition:"cover"'>
+				Cover
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view1", transition:"cover", transitionDir:-1'>
+				Cover (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view3", transition:"reveal"'>
+				Reveal
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view1", transition:"reveal", transitionDir:-1'>
+				Reveal (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view3", transition:"slidev"'>
+				Slide Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view1", transition:"slidev", transitionDir:-1'>
+				Slide Vertical (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view3", transition:"coverv"'>
+				Cover Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view1", transition:"coverv", transitionDir:-1'>
+				Cover Vertical (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view3", transition:"revealv"'>
+				Reveal Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view1", transition:"revealv", transitionDir:-1'>
+				Reveal Vertical (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"view3", transition:"swirl"'>
+				Swirl
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"view1", transition:"swirl", transitionDir:-1'>
+				Swirl (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view3", transition:"zoomOut"'>
+				Zoom Out
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view3", transition:"zoomIn"'>
+				Zoom In
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view3", transition:"scaleOut"'>
+				Scale Out
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view3", transition:"scaleIn"'>
+				Scale In
+			</li>
+		</ul>
+	</div>
 
-	</body>
+	<div id="view3" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading">View 3</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Standard Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view1", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide", transitionDir:-1'>
+				Slide (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view1", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view1", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Extended Transitions</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view1", transition:"dissolve"'>
+				Dissolve
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view1", transition:"cover"'>
+				Cover
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-7.png", moveTo:"view2", transition:"cover", transitionDir:-1'>
+				Cover (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view1", transition:"reveal"'>
+				Reveal
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"reveal", transitionDir:-1'>
+				Reveal (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view1", transition:"slidev"'>
+				Slide Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-5.png", moveTo:"view2", transition:"slidev", transitionDir:-1'>
+				Slide Vertical (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view1", transition:"coverv"'>
+				Cover Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-4.png", moveTo:"view2", transition:"coverv", transitionDir:-1'>
+				Cover Vertical (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view1", transition:"revealv"'>
+				Reveal Vertical
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-9.png", moveTo:"view2", transition:"revealv", transitionDir:-1'>
+				Reveal Vertical (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"view1", transition:"swirl"'>
+				Swirl
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-10.png", moveTo:"view2", transition:"swirl", transitionDir:-1'>
+				Swirl (Reverse)
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view1", transition:"zoomOut"'>
+				Zoom Out
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view1", transition:"zoomIn"'>
+				Zoom In
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view1", transition:"scaleOut"'>
+				Scale Out
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-8.png", moveTo:"view1", transition:"scaleIn"'>
+				Scale In
+			</li>
+		</ul>
+	</div>
+
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_transition-connect.html b/dojox/mobile/tests/test_transition-connect.html
index 148d3b6..4e46105 100644
--- a/dojox/mobile/tests/test_transition-connect.html
+++ b/dojox/mobile/tests/test_transition-connect.html
@@ -1,16 +1,23 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Transition Listener (dojo.connect)</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Transition Listener (dojo.connect)</title>
+
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojo/ready",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect, ready, registry){
 			var print = function(name, view, moveTo, dir, transition, context, method){
 				console.log(name +
 							": view=" + view +
@@ -21,48 +28,50 @@
 							", method=" + method +
 							", movedFrom=" + view.movedFrom);
 			};
-			dojo.ready(function(){
-				var view1 = dijit.byId("view1");
-				dojo.connect(view1, "onStartView", null, function(){
+			ready(function(){
+				var view1 = registry.byId("view1");
+				connect.connect(view1, "onStartView", null, function(){
 					console.log("startView: view="+this);
+					_testInitCallback = true;
 				});
-				dojo.connect(view1, "onBeforeTransitionOut", null, function(moveTo, dir, transition, context, method){
+				connect.connect(view1, "onBeforeTransitionOut", null, function(moveTo, dir, transition, context, method){
 					print("onBeforeTransitionOut", this, moveTo, dir, transition, context, method);
 				});
-				dojo.connect(view1, "onBeforeTransitionIn", null, function(moveTo, dir, transition, context, method){
+				connect.connect(view1, "onBeforeTransitionIn", null, function(moveTo, dir, transition, context, method){
 					print("onBeforeTransitionIn", this, moveTo, dir, transition, context, method);
 				});
-				dojo.connect(view1, "onAfterTransitionOut", null, function(moveTo, dir, transition, context, method){
+				connect.connect(view1, "onAfterTransitionOut", null, function(moveTo, dir, transition, context, method){
 					print("afterTransitionOut", this, moveTo, dir, transition, context, method);
 				});
-				dojo.connect(view1, "onAfterTransitionIn", null, function(moveTo, dir, transition, context, method){
+				connect.connect(view1, "onAfterTransitionIn", null, function(moveTo, dir, transition, context, method){
 					print("afterTransitionIn", this, moveTo, dir, transition, context, method);
 				});
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Animations</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view2" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view2" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="fade">
-					Fade
-				</li>
-			</ul>
-		</div>
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
 
-		<div id="view2" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="view1">Search Result</h1>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				Open the browser console to see transition event logs.
-			</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"view1"'>Search Result</h1>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Open the browser console to see transition event logs.
 		</div>
-	</body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_transition-pubsub.html b/dojox/mobile/tests/test_transition-pubsub.html
index 6d6bab7..0c22ffc 100644
--- a/dojox/mobile/tests/test_transition-pubsub.html
+++ b/dojox/mobile/tests/test_transition-pubsub.html
@@ -1,17 +1,21 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Transition Listener (pub/sub)</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>Transition Listener (pub/sub)</title>
 
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
+	<script type="text/javascript" src="../deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, parseOnLoad: true"></script>
 
+	<script type="text/javascript">
+		require([
+			"dojo/_base/connect",
+			"dojox/mobile/parser",
+			"dojox/mobile",
+			"dojox/mobile/compat"
+		], function(connect){
 			var print = function(name, view, moveTo, dir, transition, context, method){
 				console.log(name +
 							": view=" + view +
@@ -23,45 +27,46 @@
 							", movedFrom=" + view.movedFrom);
 			};
 
-			dojo.subscribe("/dojox/mobile/startView", function(view){
+			connect.subscribe("/dojox/mobile/startView", function(view){
 				console.log("startView: view="+view);
 			});
-			dojo.subscribe("/dojox/mobile/beforeTransitionOut", function(view, moveTo, dir, transition, context, method){
+			connect.subscribe("/dojox/mobile/beforeTransitionOut", function(view, moveTo, dir, transition, context, method){
 				print("onBeforeTransitionOut", view, moveTo, dir, transition, context, method);
 			});
-			dojo.subscribe("/dojox/mobile/beforeTransitionIn", function(view, moveTo, dir, transition, context, method){
+			connect.subscribe("/dojox/mobile/beforeTransitionIn", function(view, moveTo, dir, transition, context, method){
 				print("onBeforeTransitionIn", view, moveTo, dir, transition, context, method);
 			});
-			dojo.subscribe("/dojox/mobile/afterTransitionOut", function(view, moveTo, dir, transition, context, method){
+			connect.subscribe("/dojox/mobile/afterTransitionOut", function(view, moveTo, dir, transition, context, method){
 				print("afterTransitionOut", view, moveTo, dir, transition, context, method);
 			});
-			dojo.subscribe("/dojox/mobile/afterTransitionIn", function(view, moveTo, dir, transition, context, method){
+			connect.subscribe("/dojox/mobile/afterTransitionIn", function(view, moveTo, dir, transition, context, method){
 				print("afterTransitionIn", view, moveTo, dir, transition, context, method);
 			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="view1" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Animations</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view2" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="view2" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="fade">
-					Fade
-				</li>
-			</ul>
-		</div>
+		});
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div id="view1" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading">Animations</h1>
+		<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+		<ul data-dojo-type="dojox.mobile.RoundRectList">
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-1.png", moveTo:"view2", transition:"slide"'>
+				Slide
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-2.png", moveTo:"view2", transition:"flip"'>
+				Flip
+			</li>
+			<li data-dojo-type="dojox.mobile.ListItem" data-dojo-props='icon:"images/i-icon-3.png", moveTo:"view2", transition:"fade"'>
+				Fade
+			</li>
+		</ul>
+	</div>
 
-		<div id="view2" dojoType="dojox.mobile.View">
-			<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="view1">Search Result</h1>
-			<div dojoType="dojox.mobile.RoundRect" shadow="true">
-				Open the browser console to see transition event logs.
-			</div>
+	<div id="view2" data-dojo-type="dojox.mobile.View">
+		<h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='back:"Home", moveTo:"view1"'>Search Result</h1>
+		<div data-dojo-type="dojox.mobile.RoundRect" data-dojo-props='shadow:true'>
+			Open the browser console to see transition event logs.
 		</div>
-	</body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mobile/tests/test_transition-to-dynamic-view.html b/dojox/mobile/tests/test_transition-to-dynamic-view.html
deleted file mode 100644
index 8e93f05..0000000
--- a/dojox/mobile/tests/test_transition-to-dynamic-view.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Transition To A Dynamic View</title>
-		<link href="../themes/iphone/base.css" rel="stylesheet">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-		<script language="JavaScript" type="text/javascript">
-			dojo.require("dojox.mobile");			// This is a mobile app.
-			dojo.require("dojox.mobile.parser");	// This mobile app supports running on desktop browsers
-			dojo.require("dojox.mobile.compat");	// This mobile app uses declarative programming with fast mobile parser
-
-			dojo.declare("dojox.mobile.ListItemEx",dojox.mobile.ListItem,{
-				onClick: function(e){
-					if(this.url){
-						var text = dojo.trim(dojo._getText(this.url));
-						var obj = dojo.fromJson(text);
-						if(!obj.items){ return; }
-						var items = obj.items;
-						var container = dojo.create("div", {}, dojo.body());
-						var view1 = new dojox.mobile.View({selected:true}, container);
-						view1.startup();
-						var heading1 = new dojox.mobile.Heading({
-							label: "New Dynamic View",
-							back: "Home",
-							moveTo: "home"
-						});
-						view1.addChild(heading1);
-						heading1.startup();
-						var categ1 = new dojox.mobile.RoundRectCategory({
-							label: "Documents"
-						});
-						view1.addChild(categ1);
-						var list1 = new dojox.mobile.RoundRectList();
-						view1.addChild(list1);
-						for(var i = 0; i < items.length; i++){
-							var item1 = new dojox.mobile.ListItem({
-								icon: "images/i-icon-"+(i+1)+".png",
-								label: items[i].title,
-								href: items[i].href
-							});
-							list1.addChild(item1);
-						}
-						var id = view1.id;
-						this.url = "";
-						this.moveTo = dojo.hash ? "#" + id : id;						
-					}
-					this.inherited(arguments);
-				}
-			});
-		</script>
-	</head>
-	<body style="visibility:hidden;">
-		<div id="home" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Animations</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-1.png" url="items.json" transition="slide">
-					Slide
-				</li>
-				<li dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-2.png" url="items.json" transition="flip">
-					Flip
-				</li>
-				<li dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-3.png" url="items.json" transition="fade">
-					Fade
-				</li>
-			</ul>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mobile/tests/video/sample.mp4 b/dojox/mobile/tests/video/sample.mp4
new file mode 100644
index 0000000..6d59262
Binary files /dev/null and b/dojox/mobile/tests/video/sample.mp4 differ
diff --git a/dojox/mobile/tests/video/sample.ogv b/dojox/mobile/tests/video/sample.ogv
new file mode 100644
index 0000000..5a64ed4
Binary files /dev/null and b/dojox/mobile/tests/video/sample.ogv differ
diff --git a/dojox/mobile/tests/video/sample.webm b/dojox/mobile/tests/video/sample.webm
new file mode 100644
index 0000000..a3a48fd
Binary files /dev/null and b/dojox/mobile/tests/video/sample.webm differ
diff --git a/dojox/mobile/tests/view-sample.html b/dojox/mobile/tests/view-sample.html
deleted file mode 100644
index c866328..0000000
--- a/dojox/mobile/tests/view-sample.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<div id="bar" dojoType="dojox.mobile.View">
-	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">View Sample</h1>
-	<ul dojoType="dojox.mobile.RoundRectList">
-		<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-			1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
-			Sarah Connor Hardcover<br>
-			Eligible for FREE Super Saver Shipping<br>
-			<font color="red">$14.50 (50%)</font> In Stock<br>
-			# (531)
-		</li>
-		<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-			2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
-			Martin Parker Hardcover<br>
-			<font color="red">$14.00 (60%)</font> In Stock<br>
-			# (173)
-		</li>
-		<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-			3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
-			Steven Young Hardcover<br>
-			Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
-			Eligible for FREE Super Saver Shipping<br>
-			<font color="red">$9.50 (62%)</font> In Stock<br>
-			# (1199)
-		</li>
-		<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-			4. <a href="#" class="lnk">The History of Java Coffee</a><br>
-			Marco Rodriguez Hardcover<br>
-			<font color="blue">Not Available</font>
-		</li>
-		<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
-			5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
-			Melissa Morgan Hardcover<br>
-			Eligible for FREE Super Saver Shipping<br>
-			<font color="red">$12.00 (60%)</font> In Stock<br>
-			# (1847)
-		</li>
-	</ul>
-</div>
diff --git a/dojox/mobile/tests/view1.html b/dojox/mobile/tests/view1.html
deleted file mode 100644
index bf57f44..0000000
--- a/dojox/mobile/tests/view1.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<div dojoType="dojox.mobile.View">
-	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">view1.html</h1>
-	<ul dojoType="dojox.mobile.EdgeToEdgeList">
-		<li dojoType="dojox.mobile.ListItem">
-			Jack Coleman
-		</li>
-		<li dojoType="dojox.mobile.ListItem">
-			James Evans
-		</li>
-		<li dojoType="dojox.mobile.ListItem">
-			Jason Griffin
-		</li>
-	</ul>
-</div>
diff --git a/dojox/mobile/tests/view1.json b/dojox/mobile/tests/view1.json
deleted file mode 100644
index 65ac978..0000000
--- a/dojox/mobile/tests/view1.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "dojox.mobile.View": {
-    "dojox.mobile.Heading": {
-      "@back": "Home",
-      "@moveTo": "foo",
-      "@label": "view1.json"
-    },
-    "dojox.mobile.EdgeToEdgeList": {
-      "dojox.mobile.ListItem": [{
-        "@label": "Jack Coleman"
-      }, {
-        "@label": "James Evans"
-      }, {
-        "@label": "Jason Griffin"
-      }]
-    }
-  }
-}
diff --git a/dojox/mobile/tests/view2.html b/dojox/mobile/tests/view2.html
deleted file mode 100644
index 4573b73..0000000
--- a/dojox/mobile/tests/view2.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<div dojoType="dojox.mobile.View">
-	<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="foo" label="view2.html"></h1>
-	<h2 dojoType="dojox.mobile.RoundRectCategory" label="Transition Effects"></h2>
-	<ul dojoType="dojox.mobile.RoundRectList">
-		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="foo" transition="slide" label="Slide"></li>
-		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="foo" transition="flip" label="Flip"></li>
-		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="foo" transition="fade" label="Fade"></li>
-	</ul>
-</div>
diff --git a/dojox/mobile/tests/view2.json b/dojox/mobile/tests/view2.json
deleted file mode 100644
index d1c35be..0000000
--- a/dojox/mobile/tests/view2.json
+++ /dev/null
@@ -1,31 +0,0 @@
-{
-  "dojox.mobile.View": {
-    "dojox.mobile.Heading": {
-      "@back": "Home",
-      "@label": "view2.json",
-      "@moveTo": "foo"
-    },
-    "dojox.mobile.RoundRectCategory": {
-      "@label": "Transition Effects"
-    },
-    "dojox.mobile.RoundRectList": {
-      "dojox.mobile.ListItem": [{
-        "@icon": "images/i-icon-1.png",
-        "@label": "Slide",
-        "@moveTo": "foo",
-        "@transition": "slide"
-      }, {
-        "@icon": "images/i-icon-2.png",
-        "@label": "Flip",
-        "@moveTo": "foo",
-        "@transition": "flip"
-      }, {
-        "@icon": "images/i-icon-3.png",
-        "@label": "Fade",
-        "@moveTo": "foo",
-        "@transition": "fade"
-      }]
-    }
-  }
-}
-
diff --git a/dojox/mobile/tests/view3.html b/dojox/mobile/tests/view3.html
deleted file mode 100644
index 6a0207a..0000000
--- a/dojox/mobile/tests/view3.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<div id="settings" dojoType="dojox.mobile.View">
-	<h1 dojoType="dojox.mobile.Heading" label="view3.html"></h1>
-	<ul dojoType="dojox.mobile.RoundRectList">
-		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" label="Airplane Mode">
-			<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
-		</li>
-		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="mac" href="test_iPhone-Icon.html" label="Wi-Fi"></li>
-		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="AcmePhone" moveTo="foo" label="Carrier"></li>
-	</ul>
-
-	<ul dojoType="dojox.mobile.RoundRectList">
-		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="foo" label="Sounds"></li>
-		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="foo" label="Brightness"></li>
-		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="foo" label="Wallpaper"></li>
-	</ul>
-</div>
diff --git a/dojox/mobile/tests/view3.json b/dojox/mobile/tests/view3.json
deleted file mode 100644
index b734e31..0000000
--- a/dojox/mobile/tests/view3.json
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-  "dojox.mobile.View": {
-    "@id": "settings",
-    "dojox.mobile.Heading": {
-      "@label": "view3.json"
-    },
-    "dojox.mobile.RoundRectList": [{
-      "dojox.mobile.ListItem": [{
-        "@icon": "images/i-icon-1.png",
-        "@label": "Airplane Mode",
-        "dojox.mobile.Switch": {
-          "@class": "mblItemSwitch"
-        }
-      }, {
-        "@href": "test_iPhone-Icon.html",
-        "@icon": "images/i-icon-2.png",
-        "@label": "Wi-Fi",
-        "@rightText": "mac"
-      }, {
-        "@icon": "images/i-icon-3.png",
-        "@label": "Carrier",
-        "@moveTo": "foo",
-        "@rightText": "AcmePhone"
-      }]
-    }, {
-      "dojox.mobile.ListItem": [{
-        "@icon": "images/i-icon-4.png",
-        "@label": "Sounds",
-        "@moveTo": "foo"
-      }, {
-        "@icon": "images/i-icon-5.png",
-        "@label": "Brightness",
-        "@moveTo": "foo"
-      }, {
-        "@icon": "images/i-icon-6.png",
-        "@label": "Wallpaper",
-        "@moveTo": "foo"
-      }]
-    }]
-  }
-}
-
diff --git a/dojox/mobile/themes/android/Accordion-compat.css b/dojox/mobile/themes/android/Accordion-compat.css
new file mode 100644
index 0000000..10f943f
--- /dev/null
+++ b/dojox/mobile/themes/android/Accordion-compat.css
@@ -0,0 +1,25 @@
+/* dojox.mobile.Accordion */
+.mblAccordionTitle {
+  background-color: #f8f8f8;
+}
+.mblAccordionTitleSelected {
+  background-color: #00ba00;
+}
+.dj_gecko .mblAccordionTitle {
+  background-image: -moz-linear-gradient(top, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+}
+.dj_gecko .mblAccordionTitleSelected {
+  background-image: -moz-linear-gradient(top, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
+}
+.dj_ff3 .mblAccordionRoundRect {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitle:first-child {
+  -moz-border-radius-topleft: 8px;
+  -moz-border-radius-topright: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitleLast,
+.dj_ff3 .mblAccordionRoundRect .mblAccordionPane:last-child {
+  -moz-border-radius-bottomleft: 8px;
+  -moz-border-radius-bottomright: 8px;
+}
diff --git a/dojox/mobile/themes/android/Accordion.css b/dojox/mobile/themes/android/Accordion.css
new file mode 100644
index 0000000..0735913
--- /dev/null
+++ b/dojox/mobile/themes/android/Accordion.css
@@ -0,0 +1,73 @@
+/* dojox.mobile.Accordion */
+.mblAccordion {
+  border-style: outset;
+  border-width: 1px;
+  border-color: #8c8f91;
+}
+.mblAccordionRoundRect {
+  margin: 7px 9px 16px 9px;
+  padding: 0;
+  border: 1px solid #adaaad;
+  border-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitle:first-child {
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitleLast,
+.mblAccordionRoundRect .mblAccordionPane:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
+}
+.mblAccordionTitle {
+  position: relative;
+  height: 30px;
+  width: 100%;
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  line-height: 30px;
+  vertical-align: middle;
+  white-space: nowrap;
+  border-top: 1px solid #8c8f91;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#cecece), color-stop(0.5, #f8f8f8), color-stop(0.5, #eeeeee));
+  background-image: linear-gradient(to bottom, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+}
+.mblAccordionTitle:first-child {
+  border-top: none;
+}
+.mblAccordionTitleAnchor {
+  display: block;
+  height: 100%;
+  text-decoration: none;
+  white-space: nowrap;
+  color: black;
+  cursor: pointer;
+}
+.mblAccordionIconParent {
+  float: left;
+  margin: 6px 4px 0 6px;
+  line-height: normal;
+}
+.mblAccordionIconParent1 {
+  display: block;
+}
+.mblAccordionIconParent2 {
+  display: none;
+}
+.mblAccordionTitleSelected {
+  border-bottom: 1px solid #8c8f91;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#00a200), to(#00d300), color-stop(0.2, #00ba00), color-stop(0.2, #00ba00));
+  background-image: linear-gradient(to bottom, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
+  color: white;
+}
+.mblAccordionTitleSelected .mblAccordionTitleAnchor {
+  color: white;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent1 {
+  display: none;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent2 {
+  display: block;
+}
diff --git a/dojox/mobile/themes/android/Button-compat.css b/dojox/mobile/themes/android/Button-compat.css
index c1bd8cf..3a39ce9 100644
--- a/dojox/mobile/themes/android/Button-compat.css
+++ b/dojox/mobile/themes/android/Button-compat.css
@@ -1,33 +1,41 @@
 /* dojox.mobile.Button */
 .mblButton {
-	background-color: #cfcfcf;
-	background-image: url(compat/button-bg.png);
-	background-repeat: repeat-x;
-	-moz-border-radius: 3px;
-	-o-border-radius: 3px;
-	-ms-border-radius: 3px;
-	border-radius: 3px;
+  background-image: url(compat/button-bg.png);
+  background-repeat: repeat-x;
 }
 .mblButtonSelected {
-	background-color: #ffab00;
-	background-image: url(compat/button-sel-bg.png);
-}
-.mblButtonDisabled {
-	background-image: none;
+  background-image: url(compat/button-sel-bg.png);
 }
 .mblBlueButton {
-	background-color: #2261dd;
-	background-image: url(compat/blue-button-bg.png);
+  background-image: url(compat/blue-button-bg.png);
 }
 .mblBlueButtonSelected {
-	background-color: #ffab00;
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/blue-button-sel-bg.png);
 }
 .mblRedButton {
-	background-color: #ee4115;
-	background-image: url(compat/red-button-bg.png);
+  background-image: url(compat/red-button-bg.png);
 }
 .mblRedButtonSelected {
-	background-color: #ffab00;
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/red-button-sel-bg.png);
+}
+.dj_gecko .mblButton {
+  background-image: -moz-linear-gradient(top, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+}
+.dj_gecko .mblButtonSelected {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_gecko .mblBlueButton {
+  background-image: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblBlueButtonSelected {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_gecko .mblRedButton {
+  background-image: -moz-linear-gradient(top, #fa9d58 0%, #ff4d25 50%, #ed4d15 50%, #ee4115 100%);
+}
+.dj_gecko .mblRedButtonSelected {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_ff3 .mblButton {
+  -moz-border-radius: 3px;
 }
diff --git a/dojox/mobile/themes/android/Button.css b/dojox/mobile/themes/android/Button.css
index 2eb8311..89b9942 100644
--- a/dojox/mobile/themes/android/Button.css
+++ b/dojox/mobile/themes/android/Button.css
@@ -1,45 +1,47 @@
 /* dojox.mobile.Button */
 .mblButton {
-  cursor: pointer;
-  outline: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  padding: 0px 10px;
+  padding: 0 10px;
   height: 29px;
-  border: #9CACC0 1px outset;
-  -webkit-border-radius: 3px;
+  border-style: outset;
+  border-width: 1px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#cecece), color-stop(0.5, #f8f8f8), color-stop(0.5, #eeeeee));
-  color: black;
+  background-image: linear-gradient(to bottom, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
   font-family: Helvetica;
-  font-size: 13px;
   line-height: 29px;
-}
-.mblButton.mblBlueButton {
+  cursor: pointer;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  border-color: #9CACC0;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
-  color: white;
+  border-color: #9cacc0;
+  border-radius: 3px;
+  color: black;
+  font-size: 13px;
 }
-.mblButton.mblBlueButtonSelected {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
+.mblButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
   color: white;
 }
-.mblButton.mblRedButton {
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  border-color: #9CACC0;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#fa9d58), to(#ee4115), color-stop(0.5, #ff4d25), color-stop(0.5, #ed4d15));
-  color: white;
+.mblButtonDisabled,
+.mblButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
 }
-.mblButton.mblRedButtonSelected {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
+.mblBlueButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
   color: white;
 }
-.mblButtonSelected {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
+.mblBlueButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.mblRedButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fa9d58), to(#ee4115), color-stop(0.5, #ff4d25), color-stop(0.5, #ed4d15));
+  background-image: linear-gradient(to bottom, #fa9d58 0%, #ff4d25 50%, #ed4d15 50%, #ee4115 100%);
   color: white;
 }
-.mblButtonDisabled, .mblButton:disabled {
-  cursor: default;
-  border-color: grey;
-  background-image: none;
-  color: grey;
+.mblRedButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
 }
diff --git a/dojox/mobile/themes/android/Button.less b/dojox/mobile/themes/android/Button.less
deleted file mode 100644
index ab3a96c..0000000
--- a/dojox/mobile/themes/android/Button.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Button.less";
diff --git a/dojox/mobile/themes/android/Carousel.css b/dojox/mobile/themes/android/Carousel.css
index a415950..4439d46 100644
--- a/dojox/mobile/themes/android/Carousel.css
+++ b/dojox/mobile/themes/android/Carousel.css
@@ -1,30 +1,17 @@
 /* dojox.mobile.Carousel */
 .mblCarousel {
   overflow: hidden;
+  height: 300px;
 }
-.mblCarouselBox {
+.mblCarouselSlot {
   position: relative;
   float: left;
-}
-.mblCarouselImg {
-  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
-  vertical-align: bottom;
-}
-.mblCarouselImgSelected {
-  border: 1px dashed #C0C0C0;
-  -webkit-box-shadow: none;
-}
-.mblCarouselImgHeaderText {
-  color: white;
-  font: 14px arial, helvetica, clean, sans-serif;
-}
-.mblCarouselImgFooterText {
-  color: white;
-  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: left;
+  box-sizing: border-box;
 }
 .mblCarouselHeaderBar {
-  background-color: #3A3A3B;
-  color: #B1B1B1;
+  background-color: #3a3a3b;
+  color: #b1b1b1;
   font: bold 16px arial, helvetica, clean, sans-serif;
   padding: 1px;
 }
@@ -58,3 +45,35 @@
   position: relative;
   text-align: center;
 }
+/* dojox.mobile._CarouselItem */
+.mblCarouselItem {
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblCarouselItemHeaderText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 8px;
+  margin-bottom: 5px;
+}
+.mblCarouselItemFooterText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 5px;
+  margin-bottom: 8px;
+}
+.mblCarouselItemImage {
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  vertical-align: bottom;
+}
+.mblCarouselItemBlank {
+  display: none;
+}
+.mblCarouselSlotSelected .mblCarouselItemImage {
+  opacity: 0.6;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
diff --git a/dojox/mobile/themes/android/Carousel.less b/dojox/mobile/themes/android/Carousel.less
deleted file mode 100644
index d717397..0000000
--- a/dojox/mobile/themes/android/Carousel.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Carousel.less";
diff --git a/dojox/mobile/themes/android/Carousel_rtl.css b/dojox/mobile/themes/android/Carousel_rtl.css
new file mode 100644
index 0000000..45abf85
--- /dev/null
+++ b/dojox/mobile/themes/android/Carousel_rtl.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.Carousel Rtl */
+.mblCarouselItemRtl.mblCarouselSlot {
+  float: right;
+}
+.mblCarouselRtl .mblCarouselBtnContainer {
+  float: left;
+}
+.mblCarouselRtl .mblCarouselTitle {
+  margin: 2px 0px 2px 4px;
+}
+.mblCarouselRtl .mblCarouselHeaderBar .mblPageIndicator {
+  float: left;
+}
diff --git a/dojox/mobile/themes/android/CheckBox-compat.css b/dojox/mobile/themes/android/CheckBox-compat.css
index 1a37a2a..54a244a 100644
--- a/dojox/mobile/themes/android/CheckBox-compat.css
+++ b/dojox/mobile/themes/android/CheckBox-compat.css
@@ -1,37 +1,38 @@
 /* dojox.mobile.CheckBox */
 .mblCheckBox {
-	background-image: url(compat/button-bg.png);
-	-moz-border-radius: 3px;
-	-o-border-radius: 3px;
-	-ms-border-radius: 3px;
-	border-radius: 3px;
-	-moz-appearance: none;
-	-o-appearance: none;
-	-ms-appearance: none;
-	appearance: none;
-	-o-transform: translateY(0.45em);
-	-ms-transform: translateY(0.45em);
-	transform: translateY(0.45em);
+  background-image: url(compat/button-bg.png);
 }
 .mblCheckBoxSelected {
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/button-sel-bg.png);
 }
 .mblCheckBoxChecked,
 .mblCheckBox:checked {
-	background-image: url(compat/togglebutton-chk-bg.png);
-}
-.mblCheckBoxChecked::after,
-.mblCheckBox:checked::after {
-	-moz-transform: rotate(45deg);
-	-o-transform: rotate(45deg);
-	-ms-transform: rotate(45deg);
-	transform: rotate(45deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
-}
-.mblCheckBoxChecked.mblCheckBoxSelected {
-	background-image: url(compat/button-sel-bg.png);
-}
-
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblCheckBox {
+  background-image: -moz-linear-gradient(top, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+  -moz-appearance: none;
+}
+.dj_gecko .mblCheckBoxSelected {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_gecko .mblCheckBoxChecked,
+.dj_gecko .mblCheckBox:checked {
+  background-image: -moz-linear-gradient(top, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
+}
+.dj_gecko .mblCheckBoxChecked::after,
+.dj_gecko .mblCheckBox:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblCheckBoxChecked.mblCheckBoxSelected,
+.dj_gecko .mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_ff3 .mblCheckBox {
+  -moz-border-radius: 3px;
+}
diff --git a/dojox/mobile/themes/android/CheckBox.css b/dojox/mobile/themes/android/CheckBox.css
index bf3c3f5..0630887 100644
--- a/dojox/mobile/themes/android/CheckBox.css
+++ b/dojox/mobile/themes/android/CheckBox.css
@@ -1,44 +1,49 @@
 /* dojox.mobile.CheckBox */
 .mblCheckBox {
   position: relative;
-  cursor: pointer;
-  outline: none;
-  -webkit-appearance: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
   margin: -0.5em 3px 0.3em 4px;
   width: 1em;
   height: 1em;
-  border: #9CACC0 1px outset;
-  -webkit-border-radius: 3px;
+  border-style: outset;
+  border-width: 1px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#cecece), color-stop(0.5, #f8f8f8), color-stop(0.5, #eeeeee));
+  background-image: linear-gradient(to bottom, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
   font: inherit;
-  -webkit-transform: translatey(0.45em);
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  border-color: #9cacc0;
+  border-radius: 3px;
 }
 .mblCheckBoxSelected {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
-  border-color: #9CACC0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
 }
-.mblCheckBoxChecked, .mblCheckBox:checked {
-  border-color: #9CACC0;
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#00a200), to(#00d300), color-stop(0.2, #00ba00), color-stop(0.2, #00ba00));
+  background-image: linear-gradient(to bottom, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
 }
-.mblCheckBoxChecked::after, .mblCheckBox:checked::after {
+.mblCheckBoxChecked::after,
+.mblCheckBox:checked::after {
   position: absolute;
   content: "";
   width: 0.3em;
   height: 0.6em;
   top: 0;
   left: 0.3em;
-  border-color: white;
   border-width: 0.15em;
   border-style: none solid solid none;
   -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
   -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: white;
 }
-.mblCheckBoxChecked.mblCheckBoxSelected, .mblCheckBox:checked.mblCheckBoxSelected {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
-  border-color: #9CACC0;
-}
-.mblCheckBoxChecked.mblCheckBoxSelected::after, .mblCheckBox:checked.mblCheckBoxSelected::after {
-  border-color: #9CACC0;
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
 }
diff --git a/dojox/mobile/themes/android/CheckBox.less b/dojox/mobile/themes/android/CheckBox.less
deleted file mode 100644
index 09f93b2..0000000
--- a/dojox/mobile/themes/android/CheckBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/CheckBox.less";
diff --git a/dojox/mobile/themes/android/ComboBox-compat.css b/dojox/mobile/themes/android/ComboBox-compat.css
index d9e9fa9..57b2c20 100644
--- a/dojox/mobile/themes/android/ComboBox-compat.css
+++ b/dojox/mobile/themes/android/ComboBox-compat.css
@@ -1,7 +1,7 @@
 /* dojox.mobile.ComboBox */
-.dijitPopup {
-	-moz-box-shadow: 0px 0px 50px black;
-	-o-box-shadow: 0px 0px 50px black;
-	-ms-box-shadow: 0px 0px 50px black;
-	box-shadow: 0px 0px 50px black;
+.dj_gecko .dijitPopup {
+  -moz-box-shadow: 0 0 50px #000000;
+}
+.dj_gecko .mblComboBoxMenuItemSelected {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
 }
diff --git a/dojox/mobile/themes/android/ComboBox.css b/dojox/mobile/themes/android/ComboBox.css
index 8556a91..74e35f4 100644
--- a/dojox/mobile/themes/android/ComboBox.css
+++ b/dojox/mobile/themes/android/ComboBox.css
@@ -5,8 +5,9 @@
   position: absolute;
   border: 0;
   background-color: transparent;
-  -webkit-box-shadow: 0px 0px 50px black;
-  -webkit-border-radius: 0px;
+  -webkit-box-shadow: 0 0 50px #000000;
+  box-shadow: 0 0 50px #000000;
+  border-radius: 0;
 }
 .mblReset {
   margin: 0;
@@ -17,29 +18,30 @@
   color: inherit;
 }
 .mblComboBoxMenu {
-  overflow-y: hidden !important;
   position: relative;
+  overflow-y: hidden !important;
   overflow: hidden;
   border: 1px solid black;
-  -webkit-border-radius: 0px;
+  border-radius: 0;
   background-color: white;
   color: black;
 }
 .mblComboBoxMenuItem {
-  white-space: nowrap;
   padding: .1em .2em;
   border-width: 1px 0 1px 0;
   border-style: solid;
+  text-align: left;
+  white-space: nowrap;
   border-color: #ffffff;
   color: inherit;
-  text-align: left;
 }
 .mblComboBoxMenuItemSelected {
-  background-color: black;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#048bf4), to(#005ce5));
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
   color: white;
 }
-.mblComboBoxMenuPreviousButton, .mblComboBoxMenuNextButton {
+.mblComboBoxMenuPreviousButton,
+.mblComboBoxMenuNextButton {
   font-style: italic;
   overflow: hidden;
 }
diff --git a/dojox/mobile/themes/android/ComboBox.less b/dojox/mobile/themes/android/ComboBox.less
deleted file mode 100644
index ab9458c..0000000
--- a/dojox/mobile/themes/android/ComboBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ComboBox.less";
diff --git a/dojox/mobile/themes/android/ComboBox_rtl.css b/dojox/mobile/themes/android/ComboBox_rtl.css
new file mode 100644
index 0000000..01b9527
--- /dev/null
+++ b/dojox/mobile/themes/android/ComboBox_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.ComboBox Rtl*/
+.mblComboBoxMenuItemRtl {
+  text-align: right;
+}
diff --git a/dojox/mobile/themes/android/DatePicker.css b/dojox/mobile/themes/android/DatePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/android/DatePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/android/EdgeToEdgeCategory.css b/dojox/mobile/themes/android/EdgeToEdgeCategory.css
index f585a35..c7c8af2 100644
--- a/dojox/mobile/themes/android/EdgeToEdgeCategory.css
+++ b/dojox/mobile/themes/android/EdgeToEdgeCategory.css
@@ -1,18 +1,18 @@
 /* dojox.mobile.EdgeToEdgeCategory */
 .mblEdgeToEdgeCategory {
   position: relative;
+  margin: 0;
+  padding: 0 10px;
   overflow: hidden;
-  white-space: nowrap;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
   text-overflow: ellipsis;
-  margin: 0px;
-  padding: 0px 10px;
+  white-space: nowrap;
   height: 22px;
   border-bottom: 1px solid #393439;
   background-color: #212021;
-  font-family: Helvetica;
-  font-size: 16px;
-  font-weight: bold;
   color: white;
   line-height: 22px;
-  text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+  text-shadow: rgba(0, 0, 0, 0.6) 0 -1px 0;
 }
diff --git a/dojox/mobile/themes/android/EdgeToEdgeCategory.less b/dojox/mobile/themes/android/EdgeToEdgeCategory.less
deleted file mode 100644
index 3bb63da..0000000
--- a/dojox/mobile/themes/android/EdgeToEdgeCategory.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/EdgeToEdgeCategory.less";
diff --git a/dojox/mobile/themes/android/EdgeToEdgeList.css b/dojox/mobile/themes/android/EdgeToEdgeList.css
index 83e2a57..3b83b86 100644
--- a/dojox/mobile/themes/android/EdgeToEdgeList.css
+++ b/dojox/mobile/themes/android/EdgeToEdgeList.css
@@ -1,10 +1,7 @@
 /* dojox.mobile.EdgeToEdgeList */
 .mblEdgeToEdgeList {
-  position: relative;
-  /* IE needs this */
-
-  margin: 0px;
-  padding: 0px;
+  margin: 0;
+  padding: 0;
   background-color: black;
 }
 .mblEdgeToEdgeList .mblListItem:last-child {
diff --git a/dojox/mobile/themes/android/FixedSplitter.css b/dojox/mobile/themes/android/FixedSplitter.css
new file mode 100644
index 0000000..f53833d
--- /dev/null
+++ b/dojox/mobile/themes/android/FixedSplitter.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.FixedSplitter */
+.mblFixedSplitter {
+  width: 100%;
+  height: 100%;
+}
+/* For FixedSplitter's child panes */
+.mblFixedSplitter > * {
+  position: absolute;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.mblFixedSplitterH > * {
+  height: 100%;
+  top: 0px;
+}
+.mblFixedSplitterV > * {
+  width: 100%;
+  left: 0px;
+}
diff --git a/dojox/mobile/themes/android/FormLayout.css b/dojox/mobile/themes/android/FormLayout.css
new file mode 100644
index 0000000..bb00da1
--- /dev/null
+++ b/dojox/mobile/themes/android/FormLayout.css
@@ -0,0 +1,190 @@
+/* Single Column Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (max-width: 500px) {
+  .mblFormLayout.mblFormLayoutAuto fieldset {
+    padding-left: 0;
+    padding-right: 0;
+  }
+  /* A gap between rows */
+  .mblFormLayout.mblFormLayoutAuto > * + * {
+    margin-top: 0.6em;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 100%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'single' ***/
+.mblFormLayout.mblFormLayoutSingleCol fieldset {
+  padding-left: 0;
+  padding-right: 0;
+}
+/* A gap between rows */
+.mblFormLayout.mblFormLayoutSingleCol > * + * {
+  margin-top: 0.6em;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 100%;
+  box-sizing: border-box;
+}
+/* Two Columns Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (min-width: 500px) {
+  /* Form layout selector*/
+  .mblFormLayout.mblFormLayoutAuto {
+    display: table;
+    width: 100%;
+  }
+  /* Form rows */
+  .mblFormLayout.mblFormLayoutAuto > * {
+    display: table-row;
+  }
+  /* Form cells */
+  .mblFormLayout.mblFormLayoutAuto > * > * {
+    display: table-cell;
+    vertical-align: top;
+    padding: 0.5em 0;
+  }
+  /* Left cells */
+  .mblFormLayout.mblFormLayoutAuto > * > *:first-child {
+    width: 20%;
+    padding-right: 0.5em;
+  }
+  /* mblFormLayoutRightAlign optional selector definition */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child {
+    text-align: right;
+  }
+  /* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+    margin-right: 0;
+  }
+  /* The Slider sticks to its bounds when margin=10px */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+    display: inline-block;
+    margin-right: 10px;
+    margin-top: 0px;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 50%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'two' ***/
+/* Form layout selector*/
+.mblFormLayout.mblFormLayoutTwoCol {
+  display: table;
+  width: 100%;
+}
+/* Form rows */
+.mblFormLayout.mblFormLayoutTwoCol > * {
+  display: table-row;
+}
+/* Form cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > * {
+  display: table-cell;
+  vertical-align: top;
+  padding: 0.5em 0;
+}
+/* Left cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > *:first-child {
+  width: 20%;
+  padding-right: 0.5em;
+}
+/* mblFormLayoutRightAlign optional selector definition */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child {
+  text-align: right;
+}
+/* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+  margin-right: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+  display: inline-block;
+  margin-right: 10px;
+  margin-top: 0px;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 50%;
+  box-sizing: border-box;
+}
+/* Common Rules*/
+/**********************************************************************************************************************/
+.mblFormLayout fieldset {
+  border: none;
+  margin: 0;
+}
+/* Bold widget labels */
+.mblFormLayout > * > *:first-child {
+  font-weight: bold;
+}
+/* Whatever the screen width, force left margin of first elements and elements following a <br> */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Button"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ToggleButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.CheckBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Switch"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.RadioButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.SearchBox"] {
+  margin-left: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > .mblSlider:first-child {
+  display: inline-block;
+  margin-left: 10px;
+  margin-top: 0;
+  margin-bottom: 0;
+}
diff --git a/dojox/mobile/themes/android/GridLayout.css b/dojox/mobile/themes/android/GridLayout.css
new file mode 100644
index 0000000..628fd9f
--- /dev/null
+++ b/dojox/mobile/themes/android/GridLayout.css
@@ -0,0 +1,24 @@
+/* dojox.mobile.GridLayout */
+.mblGridLayout {
+  width: 100%;
+  height: 100%;
+  padding: 0;
+}
+.mblGridLayout > div {
+  margin: 0;
+  border: 0;
+  padding: 0;
+  float: left;
+  min-height: 1px;
+}
+.mblGridItemFirstColumn {
+  clear: left;
+}
+.mblGridItemTerminator {
+  clear: both;
+}
+.mblGridItemLastItem:after {
+  content: "";
+  display: block;
+  clear: both;
+}
diff --git a/dojox/mobile/themes/android/Heading-compat.css b/dojox/mobile/themes/android/Heading-compat.css
index 8b9b01f..9f7f0c2 100644
--- a/dojox/mobile/themes/android/Heading-compat.css
+++ b/dojox/mobile/themes/android/Heading-compat.css
@@ -1,22 +1,10 @@
-/* mbl.widget.Heading */
+/* dojox.mobile.Heading */
 .mblHeading {
-	background-image: url(compat/heading-bg.png);
+  background-image: url(compat/heading-bg.png);
 }
 .mblHeadingSpanTitle {
-	white-space: normal;
+  white-space: normal;
 }
-
-/* Heading Arrow Button */
-.mblArrowButtonHead {
-	position: absolute;
-	top: 0px;
-	left: 3px;
-	width: 19px;
-	height: 29px;
-	border-style: none;
-	background-image: url(compat/arrow-button-head.png);
-}
-.mblArrowButtonBody {
-	padding: 0px 10px 0px 3px;
-	background-image: url(compat/arrow-button-bg.png);
+.dj_gecko .mblHeading {
+  background-image: -moz-linear-gradient(top, #9c9e9c 0%, #848284 100%);
 }
diff --git a/dojox/mobile/themes/android/Heading.css b/dojox/mobile/themes/android/Heading.css
index 8147058..f84610d 100644
--- a/dojox/mobile/themes/android/Heading.css
+++ b/dojox/mobile/themes/android/Heading.css
@@ -1,25 +1,25 @@
 /* dojox.mobile.Heading */
 .mblHeading {
   position: relative;
-  margin: 0px;
+  margin: 0;
   width: 100%;
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
   z-index: 1;
-  padding: 0px 0px 0px 4px;
-  height: 25px;
-  background-color: #8C8A8C;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9e9c), to(#848284));
-  border-top: 1px solid #CDD5DF;
-  border-bottom: 1px solid #2D3642;
-  color: white;
+  padding: 0;
+  height: 42px;
   font-family: Helvetica;
-  font-size: 14px;
+  font-size: 20px;
   font-weight: bold;
   text-align: center;
-  line-height: 26px;
-  text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+  line-height: 44px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9e9c), to(#848284));
+  background-image: linear-gradient(to bottom, #9c9e9c 0%, #848284 100%);
+  border-top: 1px solid #cdd5df;
+  border-bottom: 1px solid #2d3642;
+  color: white;
+  text-shadow: rgba(0, 0, 0, 0.6) 0 -1px 0;
 }
 .mblHeading * {
   z-index: 2;
@@ -28,7 +28,7 @@
   position: absolute;
   width: 100%;
   display: none;
-  left: 0px;
+  left: 0;
   z-index: 1;
 }
 .mblHeadingCenterTitle .mblHeadingDivTitle {
@@ -37,45 +37,3 @@
 .mblHeadingCenterTitle .mblHeadingSpanTitle {
   display: none;
 }
-/* Heading Arrow Button */
-.mblArrowButton {
-  position: relative;
-  float: left;
-  height: 25px;
-  margin-right: 10px;
-}
-.mblArrowButtonHead {
-  position: absolute;
-  top: 4px;
-  left: 6px;
-  width: 14px;
-  height: 14px;
-  border: 1px solid #555555;
-  -webkit-transform: scale(0.8, 1) rotate(45deg);
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#e5e5e5), to(#7f7f7f), color-stop(0.5, #adadad), color-stop(0.5, #909090));
-}
-.dj_chrome .mblArrowButtonHead {
-  border: 1px outset #555555;
-}
-.mblArrowButtonBody {
-  position: absolute;
-  cursor: pointer;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  top: 0px;
-  left: 14px;
-  padding: 0px 10px 0px 3px;
-  height: 22px;
-  border-width: 1px 1px 1px 0px;
-  border-style: solid;
-  border-color: #555555;
-  font-family: Helvetica;
-  font-size: 13px;
-  color: white;
-  line-height: 23px;
-  background-color: #ADADAD;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#e5e5e5), to(#7f7f7f), color-stop(0.5, #adadad), color-stop(0.5, #909090));
-}
-.mblArrowButtonSelected .mblArrowButtonHead, .mblArrowButtonSelected .mblArrowButtonBody {
-  background-color: #FFC700;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
-}
diff --git a/dojox/mobile/themes/android/Heading.less b/dojox/mobile/themes/android/Heading.less
deleted file mode 100644
index cfc8580..0000000
--- a/dojox/mobile/themes/android/Heading.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Heading.less";
diff --git a/dojox/mobile/themes/android/IconContainer-compat.css b/dojox/mobile/themes/android/IconContainer-compat.css
index adf6d49..bafb264 100644
--- a/dojox/mobile/themes/android/IconContainer-compat.css
+++ b/dojox/mobile/themes/android/IconContainer-compat.css
@@ -1,11 +1,13 @@
 @import url("../common/domButtons/DomButtonColorButtons-compat.css");
 
-/* dojox.mobile.IconItem */
-.mblIconArea div {
-	*font-size: 60px; /* IE 7 quirks */
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+/* dojox.mobile.IconContainer */
+.mblIconItemPaneHeading {
+  background-image: url(compat/icon-content-heading-bg.png);
 }
-
-/* Icon Content Heading */
-.mblIconContentHeading {
-	background-image: url(compat/icon-content-heading-bg.png);
+.dj_gecko .mblIconItemPaneHeading {
+  background-image: -moz-linear-gradient(top, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
+}
+.dj_ie7 .mblIconAreaInner {
+  font-size: 60px;
 }
diff --git a/dojox/mobile/themes/android/IconContainer-compat.less b/dojox/mobile/themes/android/IconContainer-compat.less
new file mode 100644
index 0000000..e2df985
--- /dev/null
+++ b/dojox/mobile/themes/android/IconContainer-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer-compat.less";
diff --git a/dojox/mobile/themes/android/IconContainer.css b/dojox/mobile/themes/android/IconContainer.css
index 9e11d7b..b80d49d 100644
--- a/dojox/mobile/themes/android/IconContainer.css
+++ b/dojox/mobile/themes/android/IconContainer.css
@@ -1,13 +1,17 @@
 @import url("../common/domButtons/DomButtonColorButtons.css");
 
- at import url("../common/IconContainer_keyframes.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
 /* dojox.mobile.IconContainer */
 .mblIconContainer {
-  margin: 20px 0px 0px 10px;
-  padding: 0px 0px 40px 0px;
+  margin: 20px 10px;
+  padding: 0;
 }
 /* dojox.mobile.IconItem */
 .mblIconItem {
+  position: relative;
+  overflow: hidden;
+  /* for focus frame */
+
   list-style-type: none;
   float: left;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
@@ -15,31 +19,36 @@
 .mblIconItemTerminator {
   list-style-type: none;
   clear: both;
-  height: 20px;
 }
-.mblIconItemSub {
+.mblIconItemPane {
   list-style-type: none;
-  margin-left: -10px;
   background-color: white;
   color: black;
 }
 .mblIconArea {
-  margin-bottom: 10px;
+  position: relative;
   height: 78px;
-  width: 74px;
   font-family: Helvetica;
   font-size: 12px;
-  color: white;
   text-align: center;
+  margin-top: 5px;
+  margin-bottom: 5px;
+  width: 74px;
+  color: white;
 }
-.mblIconArea div {
+.mblIconArea img {
+  vertical-align: middle;
+}
+.mblIconAreaInner {
   position: relative;
   height: 65px;
   line-height: 65px;
   text-align: center;
 }
-.mblIconArea img {
-  vertical-align: middle;
+.mblIconItemDeleteIcon {
+  position: absolute;
+  top: -4px;
+  left: -2px;
 }
 .mblIconItemSpriteIcon {
   position: absolute;
@@ -54,46 +63,199 @@ table.mblClose {
 }
 .mblVibrate {
   position: relative;
-  -webkit-animation-duration: .5s;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
   -webkit-animation-timing-function: ease-in-out;
-  -webkit-animation-iteration-count: 20;
+  animation-timing-function: ease-in-out;
+  -webkit-animation-iteration-count: infinite;
+  animation-iteration-count: infinite;
   -webkit-animation-name: mblVibrate;
+  animation-name: mblVibrate;
   -webkit-transform: rotate(0deg);
+  transform: rotate(0deg);
 }
 .mblCloseContent {
-  -webkit-animation-duration: .3s;
+  -webkit-animation-duration: 0.3s;
+  animation-duration: 0.3s;
   -webkit-animation-timing-function: ease-in-out;
+  animation-timing-function: ease-in-out;
   -webkit-animation-name: mblShrink;
+  animation-name: mblShrink;
   -webkit-transform: scale(0.01);
+  transform: scale(0.01);
 }
 .mblCloseContent.mblShrink0 {
   -webkit-animation-name: mblShrink0;
+  animation-name: mblShrink0;
 }
 .mblCloseContent.mblShrink1 {
   -webkit-animation-name: mblShrink1;
+  animation-name: mblShrink1;
 }
 .mblCloseContent.mblShrink2 {
   -webkit-animation-name: mblShrink2;
+  animation-name: mblShrink2;
 }
 .mblCloseContent.mblShrink3 {
   -webkit-animation-name: mblShrink3;
+  animation-name: mblShrink3;
 }
-/* Icon Content Heading */
-.mblIconContentHeading {
+/* dojox.mobile._IconItemPane */
+.mblIconItemPaneHeading {
   position: relative;
   clear: both;
   overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
   margin-top: 0px;
   padding-left: 40px;
   height: 25px;
-  border-top: 1px solid #F1F3F4;
-  border-bottom: 1px solid #717D85;
+  border-top: 1px solid #f1f3f4;
+  border-bottom: 1px solid #717d85;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#e0e4e7), to(#b4bec6), color-stop(0.5, #c4ccd2), color-stop(0.5, #bfc8ce));
+  background-image: linear-gradient(to bottom, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
   font-family: Helvetica;
   font-size: 14px;
   color: white;
   line-height: 26px;
   text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.mblIconItemPaneIcon {
+  position: absolute;
+  top: -2px;
+  left: 1px;
+}
+ at -webkit-keyframes mblVibrate {
+  0% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    -webkit-transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    -webkit-transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    -webkit-transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at keyframes mblVibrate {
+  0% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at -webkit-keyframes mblShrink {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(0.01);
+  }
+}
+ at keyframes mblShrink {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink0 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink0 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink1 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink1 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink2 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink2 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink3 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink3 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(40%, -70%) scale(0.01);
+  }
 }
diff --git a/dojox/mobile/themes/android/IconContainer.less b/dojox/mobile/themes/android/IconContainer.less
index 963eae6..729745a 100644
--- a/dojox/mobile/themes/android/IconContainer.less
+++ b/dojox/mobile/themes/android/IconContainer.less
@@ -1,5 +1,5 @@
 @import url("../common/domButtons/DomButtonColorButtons.css");
- at import url("../common/IconContainer_keyframes.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
 
 @import "variables.less";
 @import "../common/IconContainer.less";
diff --git a/dojox/mobile/themes/android/IconContainer_rtl.css b/dojox/mobile/themes/android/IconContainer_rtl.css
new file mode 100644
index 0000000..f5b8c10
--- /dev/null
+++ b/dojox/mobile/themes/android/IconContainer_rtl.css
@@ -0,0 +1,14 @@
+/* dojox.mobile.IconItem Rtl */
+.mblIconItemRtl {
+  float: right;
+}
+.mblIconItemRtl .mblIconItemDeleteIcon {
+  right: -2px;
+}
+/* dojox.mobile._IconItemPane Rtl*/
+.mblIconItemPaneRtl .mblIconItemPaneHeading {
+  padding-right: 40px;
+}
+.mblIconItemPaneRtl .mblIconItemPaneIcon {
+  right: 1px;
+}
diff --git a/dojox/mobile/themes/android/IconMenu-compat.css b/dojox/mobile/themes/android/IconMenu-compat.css
new file mode 100644
index 0000000..e66fd12
--- /dev/null
+++ b/dojox/mobile/themes/android/IconMenu-compat.css
@@ -0,0 +1,34 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+  background-color: #404040;
+}
+.mblIconMenuItemSel {
+  background-color: #3578b1;
+}
+.dj_gecko .mblIconMenu {
+  background-color: rgba(64, 64, 64, 0.85);
+}
+.dj_gecko .mblIconMenuItem {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblIconMenuItemSel {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_ff3 .mblIconMenu {
+  -moz-border-radius: 6px;
+}
+.dj_ff3 .mblIconMenuItemIcon img {
+  border: 1px solid red;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-left-radius: 6px;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-right-radius: 6px;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-left-radius: 6px;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-right-radius: 6px;
+}
diff --git a/dojox/mobile/themes/android/IconMenu.css b/dojox/mobile/themes/android/IconMenu.css
new file mode 100644
index 0000000..52184dc
--- /dev/null
+++ b/dojox/mobile/themes/android/IconMenu.css
@@ -0,0 +1,64 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+  width: 100%;
+  height: 100%;
+  border-radius: 6px;
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  padding: 0;
+  background-color: rgba(64, 64, 64, 0.85);
+  border: 2px solid #eeeeee;
+}
+/* dojox.mobile.IconMenuItem */
+.mblIconMenuItem {
+  float: left;
+  list-style-type: none;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border-left: 1px solid rgba(96, 96, 96, 0.85);
+  border-bottom: 1px solid rgba(96, 96, 96, 0.85);
+}
+.mblIconMenuItemIcon {
+  position: relative;
+  margin-left: auto;
+  margin-right: auto;
+}
+.mblIconMenuItemFirstColumn {
+  border-left: none;
+}
+.mblIconMenuItemLastRow {
+  border-bottom: none;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  border-top-left-radius: 6px;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  border-top-right-radius: 6px;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  border-bottom-left-radius: 6px;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  border-bottom-right-radius: 6px;
+}
+.mblIconMenuItemAnchor {
+  display: block;
+  height: 100%;
+  font-family: Helvetica;
+  text-decoration: none;
+  font-size: 13px;
+  color: white;
+  cursor: pointer;
+}
+.mblIconMenuItemTable {
+  width: 100%;
+  height: 100%;
+}
+.mblIconMenuItemTable img {
+  border: none;
+}
+.mblIconMenuItemSel {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+  color: white;
+}
diff --git a/dojox/mobile/themes/android/IconMenu_rtl-compat.css b/dojox/mobile/themes/android/IconMenu_rtl-compat.css
new file mode 100644
index 0000000..67d04b0
--- /dev/null
+++ b/dojox/mobile/themes/android/IconMenu_rtl-compat.css
@@ -0,0 +1,17 @@
+/* dojox.mobile.IconMenu Rtl */
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-right-radius: 6px;
+  -moz-border-top-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-left-radius: 6px;
+  -moz-border-top-right-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-right-radius: 6px;
+  -moz-border-bottom-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-left-radius: 6px;
+  -moz-border-bottom-right-radius: 0px;
+}
diff --git a/dojox/mobile/themes/android/IconMenu_rtl.css b/dojox/mobile/themes/android/IconMenu_rtl.css
new file mode 100644
index 0000000..0675ffc
--- /dev/null
+++ b/dojox/mobile/themes/android/IconMenu_rtl.css
@@ -0,0 +1,23 @@
+.mblIconMenuItemRtl {
+  float: right;
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstColumn {
+  border-right: none;
+  border-left: 1px solid rgba(96, 96, 96, 0.85);
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  border-top-right-radius: 6px;
+  border-top-left-radius: 0px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  border-top-right-radius: 0px;
+  border-top-left-radius: 6px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  border-bottom-right-radius: 6px;
+  border-bottom-left-radius: 0px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  border-bottom-right-radius: 0px;
+  border-bottom-left-radius: 6px;
+}
diff --git a/dojox/mobile/themes/android/ListItem-compat.css b/dojox/mobile/themes/android/ListItem-compat.css
index 5ced8fe..82b2b3c 100644
--- a/dojox/mobile/themes/android/ListItem-compat.css
+++ b/dojox/mobile/themes/android/ListItem-compat.css
@@ -1,26 +1,13 @@
 @import url("../common/domButtons/DomButtonGrayArrow-compat.css");
- at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
 
-/* mbl.widget.ListItem */
-*html li.mblListItem.mblVariableHeight { /* IE6 hack */
-	height: 0;
+ at import url("../common/domButtons/DomButtonWhiteCheck-compat.css");
+/* dojox.mobile.ListItem */
+.mblListItemSelected {
+  background-color: #3578b1;
 }
-
-.mblListItemIcon {
-	top: 18px;
-}
-.mblListItem .mblArrow {
-	border-style: none;
-	width: 9px;
-	height: 13px;
-	background-image: url(compat/gray-arrow.png);
-}
-.mblItemSelected .mblArrow {
-	background-image: url(compat/white-arrow.png);
-}
-*html .mblListItemTextBox { /* IE6 hack */
-	height: 100%;
+.dj_gecko .mblListItemSelected {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
 }
-*html li.mblListItem.mblVariableHeight .mblListItemTextBox { /* IE6 hack */
-	height: auto;
+.dj_ie6 .mblListItem {
+  vertical-align: bottom;
 }
diff --git a/dojox/mobile/themes/android/ListItem-compat.less b/dojox/mobile/themes/android/ListItem-compat.less
new file mode 100644
index 0000000..a15be6b
--- /dev/null
+++ b/dojox/mobile/themes/android/ListItem-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayArrow-compat.css");
+ at import url("../common/domButtons/DomButtonWhiteCheck-compat.css");
+
+ at import "variables.less";
+ at import "../common/ListItem-compat.less";
diff --git a/dojox/mobile/themes/android/ListItem.css b/dojox/mobile/themes/android/ListItem.css
index 8d61090..ce49a43 100644
--- a/dojox/mobile/themes/android/ListItem.css
+++ b/dojox/mobile/themes/android/ListItem.css
@@ -4,81 +4,116 @@
 /* dojox.mobile.ListItem */
 .mblListItem {
   position: relative;
-  list-style-type: none;
-  vertical-align: bottom;
-  /* To avoid IE6 LI bug */
+  overflow: hidden;
+  /* for focus frame */
 
-  padding: 0px 0px 0px 7px;
+  padding: 0 8px;
   height: 64px;
-  border-bottom: solid 1px #313431;
+  list-style-type: none;
+  line-height: 64px;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  border-bottom: 1px solid #313431;
   background-color: black;
   font-size: 21px;
   color: white;
-  line-height: 64px;
 }
 .mblListItem.mblVariableHeight {
+  padding: 11px 8px;
   height: auto;
-  padding: 11px 0px 10px 6px;
   line-height: normal;
 }
-.mblListItem .mblListItemAnchor {
-  display: block;
-  height: 100%;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  background-position: 14px 17px;
-  text-decoration: none;
-  padding-right: 7px;
+.mblListItemSelected {
+  color: #ffffff;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
 }
-.mblListItem .mblListItemAnchor * {
-  -webkit-tap-highlight-color: rgba(0, 0, 0, 0.2);
+.mblListItemSelected .mblDomButton div {
+  border-color: white;
 }
-.mblItemSelected {
-  background-color: #FFC700;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
+.mblListItemLabelSelected {
+  background-color: #048bf4;
 }
-.mblItemSelected .mblListItemAnchor {
-  color: black;
+.mblListItemChecked .mblListItemRightIcon {
+  visibility: visible;
 }
-.mblItemSelected .mblDomButton div {
-  border-color: white;
+.mblListItemChecked .mblListItemUncheckIcon {
+  position: absolute;
+  visibility: hidden;
 }
-.mblListItemTextBoxSelected {
-  background-color: #048BF4;
+.mblListItemUnchecked .mblListItemRightIcon {
+  visibility: hidden;
 }
-.mblListItemIcon {
+.mblListItemUnchecked .mblListItemUncheckIcon {
+  visibility: visible;
+}
+.mblListItemDeleteIcon {
+  position: relative;
   float: left;
   line-height: normal;
-  margin-top: 17px;
+  margin-top: 17.5px;
+  margin-bottom: -17.5px;
   margin-right: 11px;
 }
-.mblListItemSpriteIcon {
-  position: absolute;
-  margin-top: 7px;
-  margin-left: 8px;
+.mblListItemIcon {
+  position: relative;
+  float: left;
+  line-height: normal;
+  margin-top: 17.5px;
+  margin-bottom: -17.5px;
+  margin-right: 11px;
 }
-.mblListItemRightIcon, .mblListItemRightIcon2 {
+.mblListItemRightIcon,
+.mblListItemRightIcon2,
+.mblListItemUncheckIcon {
   position: relative;
   float: right;
   line-height: normal;
-  margin-top: 17px;
-  margin-bottom: -17px;
+  margin-top: 17.5px;
+  margin-bottom: -17.5px;
 }
 .mblListItemRightText {
   position: relative;
   float: right;
   line-height: normal;
+  margin-right: 4px;
   color: white;
-  margin: 20px 4px 0 0;
+  margin-top: 20px;
 }
-.mblListItemTextBox {
+.mblListItemLabel {
+  position: relative;
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
+  height: 100%;
 }
-.mblVariableHeight .mblListItemTextBox {
+.mblVariableHeight .mblListItemLabel {
   white-space: normal;
 }
 .mblListItemSubText {
   font-size: 14px;
   color: gray;
 }
+.mblListItemLayoutLeft {
+  position: relative;
+  float: left;
+  margin-right: 11px;
+}
+.mblListItemLayoutCenter {
+  position: absolute;
+  width: 100%;
+  text-align: center;
+}
+.mblListItemLayoutRight {
+  position: relative;
+  float: right;
+}
+/* dojox.mobile._EditableListMixin */
+.mblListItemFloat {
+  position: absolute;
+  border: 1px solid gray;
+  opacity: 0.5;
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  border-radius: 0px !important;
+  -moz-border-radius: 0px !important;
+}
diff --git a/dojox/mobile/themes/android/ListItem_rtl-compat.css b/dojox/mobile/themes/android/ListItem_rtl-compat.css
new file mode 100644
index 0000000..f7deb99
--- /dev/null
+++ b/dojox/mobile/themes/android/ListItem_rtl-compat.css
@@ -0,0 +1 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl-compat.css");
diff --git a/dojox/mobile/themes/android/ListItem_rtl.css b/dojox/mobile/themes/android/ListItem_rtl.css
new file mode 100644
index 0000000..30e340f
--- /dev/null
+++ b/dojox/mobile/themes/android/ListItem_rtl.css
@@ -0,0 +1,29 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl.css");
+
+ at import url("../common/domButtons/DomButtonWhiteCheck_rtl.css");
+/* dojox.mobile.ListItem Rtl*/
+.mblListItemRtl .mblListItemDeleteIcon {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemIcon {
+  float: right;
+  margin-left: 11px;
+  margin-right: 0px;
+}
+.mblListItemRtl .mblListItemRightIcon,
+.mblListItemRtl .mblListItemRightIcon2,
+.mblListItemRtl .mblListItemUncheckIcon {
+  float: left;
+}
+.mblListItemRtl .mblListItemRightText {
+  float: left;
+  margin-left: 4px;
+}
+.mblListItemRtl .mblListItemLayoutLeft {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemLayoutRight {
+  float: left;
+}
diff --git a/dojox/mobile/themes/android/ListItem_rtl.less b/dojox/mobile/themes/android/ListItem_rtl.less
new file mode 100644
index 0000000..c21ef27
--- /dev/null
+++ b/dojox/mobile/themes/android/ListItem_rtl.less
@@ -0,0 +1,4 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl.css");
+ at import url("../common/domButtons/DomButtonWhiteCheck_rtl.css");
+
+ at import "../common/ListItem_rtl.less";
diff --git a/dojox/mobile/themes/android/Overlay-compat.css b/dojox/mobile/themes/android/Overlay-compat.css
index 3bc72a3..4d4216c 100644
--- a/dojox/mobile/themes/android/Overlay-compat.css
+++ b/dojox/mobile/themes/android/Overlay-compat.css
@@ -1,13 +1,14 @@
 /* dojox.mobile.Overlay */
 .mblOverlay {
-	_position: absolute;
-	text-align: center;
+  text-align: center;
 }
 .dj_gecko .mblOverlay {
-	text-align: -moz-center;
+  text-align: -moz-center;
 }
 .dj_ie9 .mblOverlay > *,
-.dj_ie8 .mblOverlay > *
-{
-	margin: 0 auto;
+.dj_ie8 .mblOverlay > * {
+  margin: 0 auto;
+}
+.dj_ie6 .mblOverlay {
+  *position: absolute;
 }
diff --git a/dojox/mobile/themes/android/Overlay.css b/dojox/mobile/themes/android/Overlay.css
index 40a1228..a11259a 100644
--- a/dojox/mobile/themes/android/Overlay.css
+++ b/dojox/mobile/themes/android/Overlay.css
@@ -13,6 +13,7 @@
   background-color: #333333;
   background-image: none;
 }
-.mblOverlayHidden *, .mblOverlayHidden {
+.mblOverlayHidden *,
+.mblOverlayHidden {
   visibility: hidden !important;
 }
diff --git a/dojox/mobile/themes/android/PageIndicator-compat.css b/dojox/mobile/themes/android/PageIndicator-compat.css
new file mode 100644
index 0000000..50412f7
--- /dev/null
+++ b/dojox/mobile/themes/android/PageIndicator-compat.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.PageIndicator */
+.mblPageIndicatorDot {
+	-moz-border-radius: 3px;
+}
diff --git a/dojox/mobile/themes/android/PageIndicator.css b/dojox/mobile/themes/android/PageIndicator.css
index a175ad6..c4384f3 100644
--- a/dojox/mobile/themes/android/PageIndicator.css
+++ b/dojox/mobile/themes/android/PageIndicator.css
@@ -16,8 +16,7 @@
   height: 6px;
   font-size: 1px;
   background-color: #949294;
-  -webkit-border-radius: 3px;
-  -moz-border-radius: 3px;
+  border-radius: 3px;
 }
 .mblPageIndicatorDotSelected {
   background-color: white;
diff --git a/dojox/mobile/themes/android/PageIndicator.less b/dojox/mobile/themes/android/PageIndicator.less
deleted file mode 100644
index 9bb6c49..0000000
--- a/dojox/mobile/themes/android/PageIndicator.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/PageIndicator.less";
diff --git a/dojox/mobile/themes/android/ProgressBar-compat.css b/dojox/mobile/themes/android/ProgressBar-compat.css
new file mode 100644
index 0000000..93c3746
--- /dev/null
+++ b/dojox/mobile/themes/android/ProgressBar-compat.css
@@ -0,0 +1,15 @@
+/* Progress Bar */
+.mblProgressBar {
+  background-color: #293031;
+}
+.mblProgressBarProgress {
+  background-color: #7bc708;
+}
+.dj_gecko .mblProgressBar {
+  background-image: -moz-linear-gradient(top, #545454 0%, #313031 30%, #293031 85%, #414141 100%);
+}
+.dj_gecko .mblProgressBarProgress {
+  -moz-transition-property: width;
+  -moz-transition-duration: 0.25s;
+  background-image: -moz-linear-gradient(top, #adf708 0%, #7bbe08 50%, #63a600 90%, #5a8e00 100%);
+}
diff --git a/dojox/mobile/themes/android/ProgressBar.css b/dojox/mobile/themes/android/ProgressBar.css
new file mode 100644
index 0000000..a9794ab
--- /dev/null
+++ b/dojox/mobile/themes/android/ProgressBar.css
@@ -0,0 +1,35 @@
+/* dojox.mobile.ProgressBar */
+.mblProgressBar {
+  position: relative;
+  border-radius: 6px;
+  height: 22px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#545454), to(#414141), color-stop(0.3, #313031), color-stop(0.85, #293031));
+  background-image: linear-gradient(to bottom, #545454 0%, #313031 30%, #293031 85%, #414141 100%);
+}
+.mblProgressBarProgress {
+  -webkit-transition-property: width;
+  transition-property: width;
+  -webkit-transition-duration: 0.25s;
+  transition-duration: 0.25s;
+  border-top-left-radius: 6px;
+  border-bottom-left-radius: 6px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#adf708), to(#5a8e00), color-stop(0.5, #7bbe08), color-stop(0.9, #63a600));
+  background-image: linear-gradient(to bottom, #adf708 0%, #7bbe08 50%, #63a600 90%, #5a8e00 100%);
+  height: 22px;
+}
+.mblProgressBarComplete {
+  border-radius: 6px;
+}
+.mblProgressBarNotStarted {
+  border-left: none;
+  border-right: none;
+}
+.mblProgressBarMsg {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  text-align: center;
+  font-size: 12px;
+  top: 3px;
+}
diff --git a/dojox/mobile/themes/android/ProgressIndicator-compat.css b/dojox/mobile/themes/android/ProgressIndicator-compat.css
index 4ee0810..cbabad7 100644
--- a/dojox/mobile/themes/android/ProgressIndicator-compat.css
+++ b/dojox/mobile/themes/android/ProgressIndicator-compat.css
@@ -1,46 +1,83 @@
 /* Progress Indicator */
-.mblProg {
-	position: absolute;
-	top: 0px;
-	width: 4px;
-	font-size: 1px;
-	height: 36px;
-	overflow: hidden;
-	background-color: #C0C0C0;
+.dj_ie .mblProg {
+  width: 4px;
+  height: 36px;
 }
-.mblProg0 {
-	left: 0px;
+.dj_ie .mblProg0 {
+  left: 0px;
 }
-.mblProg1 {
-	left: 8px;
+.dj_ie .mblProg1 {
+  left: 8px;
 }
-.mblProg2 {
-	left: 16px;
+.dj_ie .mblProg2 {
+  left: 16px;
 }
-.mblProg3 {
-	left: 24px;
+.dj_ie .mblProg3 {
+  left: 24px;
 }
-.mblProg4 {
-	left: 32px;
+.dj_ie .mblProg4 {
+  left: 32px;
 }
-.mblProg5 {
-	left: 40px;
+.dj_ie .mblProg5 {
+  left: 40px;
 }
-.mblProg6 {
-	left: 48px;
+.dj_ie .mblProg6 {
+  left: 48px;
 }
-.mblProg7 {
-	left: 56px;
+.dj_ie .mblProg7 {
+  left: 56px;
 }
-.mblProg8 {
-	left: 64px;
+.dj_ie .mblProg8 {
+  left: 64px;
 }
-.mblProg9 {
-	left: 72px;
+.dj_ie .mblProg9 {
+  left: 72px;
 }
-.mblProg10 {
-	left: 80px;
+.dj_ie .mblProg10 {
+  left: 80px;
 }
-.mblProg11 {
-	left: 80px;
+.dj_ie .mblProg11 {
+  left: 80px;
+}
+.dj_gecko .mblProgressIndicatorCenter .mblProgContainer {
+  -moz-transform-origin: 50% 0;
+}
+.dj_gecko .mblProg {
+  -moz-transform-origin: 0 2px;
+}
+.dj_gecko .mblProg0 {
+  -moz-transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.dj_gecko .mblProg1 {
+  -moz-transform: translate(22px, 11px) rotate(-60deg);
+}
+.dj_gecko .mblProg2 {
+  -moz-transform: translate(25px, 14px) rotate(-30deg);
+}
+.dj_gecko .mblProg3 {
+  -moz-transform: translate(26px, 18px) rotate(0deg);
+}
+.dj_gecko .mblProg4 {
+  -moz-transform: translate(25px, 22px) rotate(30deg);
+}
+.dj_gecko .mblProg5 {
+  -moz-transform: translate(22px, 25px) rotate(60deg);
+}
+.dj_gecko .mblProg6 {
+  -moz-transform: translate(18px, 26px) rotate(90.1deg);
+}
+.dj_gecko .mblProg7 {
+  -moz-transform: translate(14px, 25px) rotate(120deg);
+}
+.dj_gecko .mblProg8 {
+  -moz-transform: translate(11px, 22px) rotate(150deg);
+}
+.dj_gecko .mblProg9 {
+  -moz-transform: translate(10px, 18px) rotate(180deg);
+}
+.dj_gecko .mblProg10 {
+  -moz-transform: translate(11px, 14px) rotate(210deg);
+}
+.dj_gecko .mblProg11 {
+  -moz-transform: translate(14px, 11px) rotate(240deg);
 }
diff --git a/dojox/mobile/themes/android/ProgressIndicator.css b/dojox/mobile/themes/android/ProgressIndicator.css
index 2340637..17a8bda 100644
--- a/dojox/mobile/themes/android/ProgressIndicator.css
+++ b/dojox/mobile/themes/android/ProgressIndicator.css
@@ -1,11 +1,26 @@
 /* Progress Indicator */
+.mblProgressIndicator {
+  position: relative;
+  top: 0px;
+}
+.mblHeading .mblProgressIndicator {
+  margin: 5px;
+  float: left;
+}
 .mblProgContainer {
   position: absolute;
-  width: 40px;
-  height: 40px;
+  width: 100%;
+  height: 100%;
+}
+.mblProgressIndicatorCenter {
+  position: absolute;
   top: 180px;
   left: 50%;
-  margin: -18px 0px 0px -18px;
+}
+.mblProgressIndicatorCenter .mblProgContainer {
+  left: -50%;
+  -webkit-transform-origin: 50% 0;
+  transform-origin: 50% 0;
 }
 .mblProg {
   position: absolute;
@@ -16,43 +31,127 @@
   height: 4px;
   overflow: hidden;
   -webkit-transform-origin: 0 2px;
-  background-color: #C0C0C0;
-  -webkit-border-radius: 2px;
-  -moz-border-radius: 2px;
+  transform-origin: 0 2px;
+  background-color: #c0c0c0;
+  border-radius: 2px;
 }
 .mblProg0 {
   -webkit-transform: translate(18px, 10px) rotate(-90.1deg);
+  transform: translate(18px, 10px) rotate(-90.1deg);
 }
 .mblProg1 {
   -webkit-transform: translate(22px, 11px) rotate(-60deg);
+  transform: translate(22px, 11px) rotate(-60deg);
 }
 .mblProg2 {
   -webkit-transform: translate(25px, 14px) rotate(-30deg);
+  transform: translate(25px, 14px) rotate(-30deg);
 }
 .mblProg3 {
   -webkit-transform: translate(26px, 18px) rotate(0deg);
+  transform: translate(26px, 18px) rotate(0deg);
 }
 .mblProg4 {
   -webkit-transform: translate(25px, 22px) rotate(30deg);
+  transform: translate(25px, 22px) rotate(30deg);
 }
 .mblProg5 {
   -webkit-transform: translate(22px, 25px) rotate(60deg);
+  transform: translate(22px, 25px) rotate(60deg);
 }
 .mblProg6 {
   -webkit-transform: translate(18px, 26px) rotate(90.1deg);
+  transform: translate(18px, 26px) rotate(90.1deg);
 }
 .mblProg7 {
   -webkit-transform: translate(14px, 25px) rotate(120deg);
+  transform: translate(14px, 25px) rotate(120deg);
 }
 .mblProg8 {
   -webkit-transform: translate(11px, 22px) rotate(150deg);
+  transform: translate(11px, 22px) rotate(150deg);
 }
 .mblProg9 {
   -webkit-transform: translate(10px, 18px) rotate(180deg);
+  transform: translate(10px, 18px) rotate(180deg);
 }
 .mblProg10 {
   -webkit-transform: translate(11px, 14px) rotate(210deg);
+  transform: translate(11px, 14px) rotate(210deg);
 }
 .mblProg11 {
   -webkit-transform: translate(14px, 11px) rotate(240deg);
+  transform: translate(14px, 11px) rotate(240deg);
+}
+.mblProg0Color {
+  background-color: #c0c0c0;
+}
+.mblProg1Color {
+  background-color: #c0c0c0;
+}
+.mblProg2Color {
+  background-color: #c0c0c0;
+}
+.mblProg3Color {
+  background-color: #c0c0c0;
+}
+.mblProg4Color {
+  background-color: #c0c0c0;
+}
+.mblProg5Color {
+  background-color: #c0c0c0;
+}
+.mblProg6Color {
+  background-color: #b8b9b8;
+}
+.mblProg7Color {
+  background-color: #aeafae;
+}
+.mblProg8Color {
+  background-color: #a4a5a4;
+}
+.mblProg9Color {
+  background-color: #9a9a9a;
+}
+.mblProg10Color {
+  background-color: #8e8e8e;
+}
+.mblProg11Color {
+  background-color: #838383;
+}
+.mblProgWhite .mblProg0Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg1Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg2Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg3Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg4Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg5Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg6Color {
+  background-color: #acb9cb;
+}
+.mblProgWhite .mblProg7Color {
+  background-color: #b7c2d2;
+}
+.mblProgWhite .mblProg8Color {
+  background-color: #c4cdda;
+}
+.mblProgWhite .mblProg9Color {
+  background-color: #d1d8e2;
+}
+.mblProgWhite .mblProg10Color {
+  background-color: #dee3ea;
+}
+.mblProgWhite .mblProg11Color {
+  background-color: #eceff3;
 }
diff --git a/dojox/mobile/themes/android/ProgressIndicator.less b/dojox/mobile/themes/android/ProgressIndicator.less
deleted file mode 100644
index 2ab2a2d..0000000
--- a/dojox/mobile/themes/android/ProgressIndicator.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ProgressIndicator.less";
diff --git a/dojox/mobile/themes/android/RadioButton-compat.css b/dojox/mobile/themes/android/RadioButton-compat.css
index 17e473f..9a544f7 100644
--- a/dojox/mobile/themes/android/RadioButton-compat.css
+++ b/dojox/mobile/themes/android/RadioButton-compat.css
@@ -1,33 +1,32 @@
 /* dojox.mobile.RadioButton */
 .mblRadioButton {
-	background-image: url(compat/button-bg.png);
-	-moz-border-radius: 0.5em;
-	-o-border-radius: 0.5em;
-	-ms-border-radius: 0.5em;
-	border-radius: 0.5em;
-	-moz-appearance: none;
-	-o-appearance: none;
-	-ms-appearance: none;
-	appearance: none;
-	-o-transform: translateY(0.45em);
-	-ms-transform: translateY(0.45em);
-	transform: translateY(0.45em);
+  background-image: url(compat/button-bg.png);
 }
 .mblRadioButtonChecked,
 .mblRadioButton:checked {
-	background-image: url(compat/togglebutton-chk-bg.png);
-}
-.mblRadioButtonChecked::after,
-.mblRadioButton:checked::after {
-	-moz-transform: rotate(45deg);
-	-o-transform: rotate(45deg);
-	-ms-transform: rotate(45deg);
-	transform: rotate(45deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
-}
-.mblRadioButtonChecked.mblRadioButtonSelected {
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: url(compat/blue-button-sel-bg.png);
+}
+.dj_gecko .mblRadioButton {
+  background-image: -moz-linear-gradient(top, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+  -moz-appearance: none;
+}
+.dj_gecko .mblRadioButtonChecked,
+.dj_gecko .mblRadioButton:checked {
+  background-image: -moz-linear-gradient(top, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
+}
+.dj_gecko .mblRadioButtonChecked::after,
+.dj_gecko .mblRadioButton:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblRadioButtonChecked.mblRadioButtonSelected,
+.dj_gecko .mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_ff3 .mblRadioButton {
+  -moz-border-radius: 0.5em;
 }
diff --git a/dojox/mobile/themes/android/RadioButton.css b/dojox/mobile/themes/android/RadioButton.css
index 1f997dc..4978594 100644
--- a/dojox/mobile/themes/android/RadioButton.css
+++ b/dojox/mobile/themes/android/RadioButton.css
@@ -1,41 +1,49 @@
 /* dojox.mobile.RadioButton */
 .mblRadioButton {
   position: relative;
-  cursor: pointer;
-  outline: none;
-  -webkit-appearance: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
   margin: -0.5em 3px 0.3em 4px;
   width: 1em;
   height: 1em;
-  border: #9CACC0 1px outset;
-  -webkit-border-radius: 0.5em;
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 0.5em;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#cecece), color-stop(0.5, #f8f8f8), color-stop(0.5, #eeeeee));
+  background-image: linear-gradient(to bottom, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
   font: inherit;
-  -webkit-transform: translatey(0.45em);
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  border-color: #9cacc0;
 }
-.mblRadioButtonChecked, .mblRadioButton:checked {
-  border-color: #9CACC0;
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#00a200), to(#00d300), color-stop(0.2, #00ba00), color-stop(0.2, #00ba00));
+  background-image: linear-gradient(to bottom, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
 }
-.mblRadioButtonChecked::after, .mblRadioButton:checked::after {
+.mblRadioButtonChecked::after,
+.mblRadioButton:checked::after {
   position: absolute;
   content: "";
   width: 0.3em;
   height: 0.6em;
   top: 0;
   left: 0.25em;
-  border-color: white;
   border-width: 0.15em;
   border-style: none solid solid none;
-  border-color: white;
   -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
   -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: white;
 }
-.mblRadioButtonChecked.mblRadioButtonSelected, .mblRadioButton:checked.mblRadioButtonSelected {
-  border-color: #9CACC0;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
 }
-.mblRadioButtonChecked.mblRadioButtonSelected::after, .mblRadioButton:checked.mblRadioButtonSelected::after {
+.mblRadioButtonChecked.mblRadioButtonSelected::after,
+.mblRadioButton:checked.mblRadioButtonSelected::after {
   border-color: white;
 }
diff --git a/dojox/mobile/themes/android/RadioButton.less b/dojox/mobile/themes/android/RadioButton.less
deleted file mode 100644
index 0793ca6..0000000
--- a/dojox/mobile/themes/android/RadioButton.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RadioButton.less";
diff --git a/dojox/mobile/themes/android/RoundRect-compat.css b/dojox/mobile/themes/android/RoundRect-compat.css
index cf3ce84..13d639d 100644
--- a/dojox/mobile/themes/android/RoundRect-compat.css
+++ b/dojox/mobile/themes/android/RoundRect-compat.css
@@ -1,64 +1,73 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect.mblShadow {
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+}
+.dj_ff3 .mblRoundRect {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblRoundRect.mblShadow {
+  -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+}
 /* Round Corner */
-.mblRoundCorner {
-	background-color: black;
-	height: 1px;
-	font-size: 1px;
-	overflow: hidden;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRectContainer {
-	padding: 3px 8px;
-	background-color: black;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRectList .mblRoundRectContainer {
-	margin: 0px;
-	padding: 0px;
-}
-.mblRoundCorner0T {
-	height: 0px;
-}
-.mblRoundCorner1T {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
-}
-.mblRoundCorner2T {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner3T {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4T {
-	margin: 0px 1px;
-}
-.mblRoundCorner5T {
-	margin: 0px 1px;
-}
-
-.mblRoundCorner0B {
-	height: 0px;
-}
-.mblRoundCorner1B {
-	margin: 0px 1px;
-}
-.mblRoundCorner2B {
-	margin: 0px 1px;
-}
-.mblRoundCorner3B {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4B {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner5B {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
+.dj_ie .mblRoundCorner {
+  background-color: #000000;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #adaaad;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: #000000;
+  border-style: solid;
+  border-color: #adaaad;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #adaaad;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #adaaad;
+  margin: 0 5px;
 }
diff --git a/dojox/mobile/themes/android/RoundRect.css b/dojox/mobile/themes/android/RoundRect.css
index c76a82f..6aa24a8 100644
--- a/dojox/mobile/themes/android/RoundRect.css
+++ b/dojox/mobile/themes/android/RoundRect.css
@@ -2,12 +2,12 @@
 .mblRoundRect {
   margin: 7px 9px 16px;
   padding: 8px;
-  border: 1px solid #ADAAAD;
-  -webkit-border-radius: 8px;
-  -moz-border-radius: 8px;
+  border: 1px solid #adaaad;
+  border-radius: 8px;
+  background-color: #000000;
   color: white;
-  background-color: black;
 }
 .mblRoundRect.mblShadow {
   -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
 }
diff --git a/dojox/mobile/themes/android/RoundRect.less b/dojox/mobile/themes/android/RoundRect.less
deleted file mode 100644
index efec816..0000000
--- a/dojox/mobile/themes/android/RoundRect.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRect.less";
diff --git a/dojox/mobile/themes/android/RoundRectCategory.css b/dojox/mobile/themes/android/RoundRectCategory.css
index 9be5f0c..c76e11d 100644
--- a/dojox/mobile/themes/android/RoundRectCategory.css
+++ b/dojox/mobile/themes/android/RoundRectCategory.css
@@ -1,10 +1,11 @@
 /* dojox.mobile.RoundRectCategory */
 .mblRoundRectCategory {
+  margin: 18px 0 0 20px;
+  padding: 0;
+  font-family: Helvetica;
+  font-size: 16px;
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
-  margin: 18px 0px 0px 20px;
-  font-family: Helvetica;
-  font-size: 16px;
   color: white;
 }
diff --git a/dojox/mobile/themes/android/RoundRectCategory.less b/dojox/mobile/themes/android/RoundRectCategory.less
deleted file mode 100644
index e9148cc..0000000
--- a/dojox/mobile/themes/android/RoundRectCategory.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRectCategory.less";
diff --git a/dojox/mobile/themes/android/RoundRectCategory_rtl.css b/dojox/mobile/themes/android/RoundRectCategory_rtl.css
new file mode 100644
index 0000000..2a7ffc3
--- /dev/null
+++ b/dojox/mobile/themes/android/RoundRectCategory_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.RoundRectCategory Rtl */
+.mblRoundRectCategoryRtl {
+  margin: 18px 20px 0px 0px;
+}
diff --git a/dojox/mobile/themes/android/RoundRectList-compat.css b/dojox/mobile/themes/android/RoundRectList-compat.css
index cf3ce84..a7f809a 100644
--- a/dojox/mobile/themes/android/RoundRectList-compat.css
+++ b/dojox/mobile/themes/android/RoundRectList-compat.css
@@ -1,64 +1,78 @@
+/* dojox.mobile.RoundRectList */
+.dj_ff3 .mblRoundRectList {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:first-child {
+  -moz-border-radius-topleft: 8px;
+  -moz-border-radius-topright: 8px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:last-child {
+  -moz-border-radius-bottomleft: 8px;
+  -moz-border-radius-bottomright: 8px;
+}
 /* Round Corner */
-.mblRoundCorner {
-	background-color: black;
-	height: 1px;
-	font-size: 1px;
-	overflow: hidden;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRectContainer {
-	padding: 3px 8px;
-	background-color: black;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRectList .mblRoundRectContainer {
-	margin: 0px;
-	padding: 0px;
-}
-.mblRoundCorner0T {
-	height: 0px;
-}
-.mblRoundCorner1T {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
-}
-.mblRoundCorner2T {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner3T {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4T {
-	margin: 0px 1px;
-}
-.mblRoundCorner5T {
-	margin: 0px 1px;
-}
-
-.mblRoundCorner0B {
-	height: 0px;
-}
-.mblRoundCorner1B {
-	margin: 0px 1px;
-}
-.mblRoundCorner2B {
-	margin: 0px 1px;
-}
-.mblRoundCorner3B {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4B {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner5B {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
+.dj_ie .mblRoundRectList {
+  position: relative;
+}
+.dj_ie .mblRoundCorner {
+  background-color: #000000;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #adaaad;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: #000000;
+  border-style: solid;
+  border-color: #adaaad;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #adaaad;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #adaaad;
+  margin: 0 5px;
 }
diff --git a/dojox/mobile/themes/android/RoundRectList.css b/dojox/mobile/themes/android/RoundRectList.css
index 058587c..3de667a 100644
--- a/dojox/mobile/themes/android/RoundRectList.css
+++ b/dojox/mobile/themes/android/RoundRectList.css
@@ -1,25 +1,19 @@
 /* dojox.mobile.RoundRectList */
 .mblRoundRectList {
-  position: relative;
-  /* IE needs this */
-
   margin: 7px 9px 16px;
-  padding: 0px;
-  border: 1px solid #ADAAAD;
-  -webkit-border-radius: 8px;
-  -moz-border-radius: 8px;
-  background-color: white;
+  padding: 0;
+  border: 1px solid #adaaad;
+  border-radius: 8px;
+  background-color: #000000;
 }
-.mblRoundRectList .mblListItem:first-child {
-  -webkit-border-top-left-radius: 8px;
-  -webkit-border-top-right-radius: 8px;
-  -moz-border-radius-topleft: 8px;
-  -moz-border-radius-topright: 8px;
+.mblRoundRectList .mblListItem:first-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:first-child {
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
 }
-.mblRoundRectList .mblListItem:last-child {
-  border-bottom-width: 0px;
-  -webkit-border-bottom-left-radius: 8px;
-  -webkit-border-bottom-right-radius: 8px;
-  -moz-border-radius-bottomleft: 8px;
-  -moz-border-radius-bottomright: 8px;
+.mblRoundRectList .mblListItem:last-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
 }
diff --git a/dojox/mobile/themes/android/RoundRectList.less b/dojox/mobile/themes/android/RoundRectList.less
deleted file mode 100644
index 52e1164..0000000
--- a/dojox/mobile/themes/android/RoundRectList.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRectList.less";
diff --git a/dojox/mobile/themes/android/ScrollablePane.css b/dojox/mobile/themes/android/ScrollablePane.css
new file mode 100644
index 0000000..573d58f
--- /dev/null
+++ b/dojox/mobile/themes/android/ScrollablePane.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.mblScrollablePane */
+.mblScrollablePane {
+  position: relative;
+  overflow: hidden;
+}
+.mblScrollableViewContainer {
+  position: absolute;
+  top: 0px;
+}
+.mblScrollablePaneMask {
+  position: relative;
+}
diff --git a/dojox/mobile/themes/android/SearchBox-compat.css b/dojox/mobile/themes/android/SearchBox-compat.css
new file mode 100644
index 0000000..913c704
--- /dev/null
+++ b/dojox/mobile/themes/android/SearchBox-compat.css
@@ -0,0 +1,26 @@
+ at import url("TextBox-compat.css");
+/* dojox.mobile.SearchBox */
+.mblSearchBox {
+  height: auto;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  -moz-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/android/SearchBox.css b/dojox/mobile/themes/android/SearchBox.css
new file mode 100644
index 0000000..eb3511d
--- /dev/null
+++ b/dojox/mobile/themes/android/SearchBox.css
@@ -0,0 +1,61 @@
+ at import url("TextBox.css");
+/* dojox.mobile.SearchBox */
+.mblSearchBox.iphone4:focus::-webkit-search-cancel-button {
+  background: none !important;
+  border-color: transparent !important;
+}
+.mblSearchBox::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+  background-color: transparent;
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-size: 15px 15px;
+  background-image: -webkit-gradient(linear, left top, right bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #000000), color-stop(0.54, #000000), color-stop(0.54, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #000000), color-stop(0.54, #000000), color-stop(0.54, transparent), to(transparent)) !important;
+  border: 2px solid transparent;
+  box-sizing: border-box;
+  height: 15px;
+  width: 15px;
+  display: inline-block;
+  vertical-align: middle;
+  margin-left: 0.5em;
+  border-radius: 0;
+}
+.mblSearchBox::-webkit-search-results-decoration {
+  -webkit-appearance: none;
+  background-repeat: no-repeat;
+  background-size: 13px 13px, 9px 9px;
+  background-position: 0px 0px, 10px 10px;
+  background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 6, from(transparent), color-stop(0.65, transparent), color-stop(0.8, #000000), color-stop(0.95, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.425, transparent), color-stop(0.5, #000000), color-stop(0.575, transparent), to(transparent)) !important;
+  width: 15px;
+  height: 15px;
+  display: inline-block;
+  vertical-align: middle;
+}
+.mblSearchBox {
+  height: auto;
+}
+.dj_chrome .mblSearchBox {
+  border-radius: 0;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/android/SimpleDialog-compat.css b/dojox/mobile/themes/android/SimpleDialog-compat.css
new file mode 100644
index 0000000..6e83430
--- /dev/null
+++ b/dojox/mobile/themes/android/SimpleDialog-compat.css
@@ -0,0 +1,10 @@
+/* dojox.mobile.SimpleDialog */
+.mblSimpleDialogDecoration {
+  background-color: #404040;
+}
+.dj_gecko .mblSimpleDialogDecoration {
+  background-color: rgba(64, 64, 64, 0.85);
+}
+.dj_ff3 .mblSimpleDialogDecoration {
+  -moz-border-radius: 6px;
+}
diff --git a/dojox/mobile/themes/android/SimpleDialog.css b/dojox/mobile/themes/android/SimpleDialog.css
new file mode 100644
index 0000000..efb4ad0
--- /dev/null
+++ b/dojox/mobile/themes/android/SimpleDialog.css
@@ -0,0 +1,48 @@
+/* dojox.mobile.SimpleDialog */
+.mblSimpleDialog {
+  position: absolute;
+  z-index: 100;
+  margin: 0;
+  text-align: center;
+  outline: none;
+  padding: 5px;
+  width: 262px;
+}
+.mblSimpleDialogDecoration {
+  border-radius: 6px;
+  background-color: rgba(64, 64, 64, 0.85);
+  border: 2px solid #eeeeee;
+  color: white;
+}
+.mblSimpleDialogContainer {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.mblSimpleDialogCover {
+  background-color: #000000;
+  opacity: 0.5;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 99;
+}
+.mblSimpleDialogCloseBtn {
+  position: absolute !important;
+}
+.mblSimpleDialogTitle {
+  margin: 14px 0 7px -5px;
+  padding: 0 14px 14px;
+  width: 244px;
+  border-bottom: 1px solid rgba(96, 96, 96, 0.85);
+  font-size: 21px;
+  text-align: left;
+}
+.mblSimpleDialogText {
+  margin: 14px 9px;
+  width: 244px;
+  font-size: 18px;
+  text-align: left;
+}
diff --git a/dojox/mobile/themes/android/Slider-compat.css b/dojox/mobile/themes/android/Slider-compat.css
index c8a47f8..213f934 100644
--- a/dojox/mobile/themes/android/Slider-compat.css
+++ b/dojox/mobile/themes/android/Slider-compat.css
@@ -1,43 +1,40 @@
 /* dojox.mobile.Slider */
 .mblSlider {
-	background-image: url(compat/slider-h-bg.png);
-	-moz-border-radius: 2px;
-	-o-border-radius: 2px;
-	-ms-border-radius: 2px; 
-	border-radius: 2px;
-	-moz-user-select: none; /* prevent selection */
-	-o-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-	-moz-box-sizing: content-box; /* make width and height consistent with a DIV */
-	-o-box-sizing: content-box;
-	-ms-box-sizing: content-box;
-	box-sizing: content-box;
-}
-.mblSlider.mblSliderV {
-	background: #BDBEBD;
+  background-image: url(compat/slider-h-bg.png);
+  background-repeat: repeat-x;
 }
 .mblSliderProgressBar {
-	background-image: url(compat/slider-h-bar-bg.png);
-	background-repeat: repeat-x;
-	-moz-border-radius: 2px;
-	-o-border-radius: 2px;
-	-ms-border-radius: 2px; 
-	border-radius: 2px;
+  background-image: url(compat/slider-h-bar-bg.png);
+  background-repeat: repeat-x;
+}
+.mblSliderHandle {
+  background-image: url(compat/slider-handle-bg.png);
+}
+.mblSliderV {
+  background-color: #bdbebd;
+  background-image: none;
 }
 .mblSliderV .mblSliderProgressBar {
-	background: #00A200;
+  background-color: #00a200;
+  background-image: none;
 }
-.mblSliderHandle {
-	background-image: url(compat/slider-handle-bg.png);
-	-moz-border-radius: 2px;
-	-o-border-radius: 2px;
-	-ms-border-radius: 2px; 
-	border-radius: 2px;
-}
-.mblSliderTransition {
-	-moz-transition-duration: 400ms;
-	-o-transition-duration: 400ms;
-	-ms-transition-duration: 400ms;
-	transition-duration: 400ms;
+.dj_gecko .mblSlider {
+  background-image: -moz-linear-gradient(top, #bdbebd 0%, #f7f3f7 100%);
+  -moz-user-select: none;
+  -moz-box-sizing: content-box;
+}
+.dj_gecko .mblSliderProgressBar {
+  background-image: -moz-linear-gradient(top, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
+}
+.dj_gecko .mblSliderHandle {
+  background-image: -moz-linear-gradient(top, #9c9a9c 0%, #848284 100%);
+}
+.dj_ff3 .mblSlider {
+  -moz-border-radius: 2px;
+}
+.dj_ff3 .mblSliderProgressBar {
+  -moz-border-radius: 2px;
+}
+.dj_ff3 .mblSliderHandle {
+  -moz-border-radius: 2px;
 }
diff --git a/dojox/mobile/themes/android/Slider.css b/dojox/mobile/themes/android/Slider.css
index 4a16e82..7d8f756 100644
--- a/dojox/mobile/themes/android/Slider.css
+++ b/dojox/mobile/themes/android/Slider.css
@@ -1,18 +1,16 @@
 /* dojox.mobile.Slider */
 .mblSlider {
-  outline: none;
-  -webkit-user-select: none;
-  /* prevent selection */
-
-  -webkit-box-sizing: content-box;
-  /* make width and height consistent with a DIV */
-
   margin: 15px;
-  /* 1/2 handle width for hanging off the ends of the bar */
-
-  border: #B0B0B0 1px inset;
+  border-style: inset;
+  border-width: 1px;
+  border-radius: 2px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#bdbebd), to(#f7f3f7));
-  -webkit-border-radius: 2px;
+  background-image: linear-gradient(to bottom, #bdbebd 0%, #f7f3f7 100%);
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -webkit-box-sizing: content-box;
+  box-sizing: content-box;
+  border-color: #b0b0b0;
 }
 .mblSliderH {
   width: 200px;
@@ -35,19 +33,24 @@
   left: 50%;
 }
 .mblSliderProgressBar {
+  border-radius: 2px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#00a200), to(#00d300), color-stop(0.2, #00ba00), color-stop(0.2, #00ba00));
-  -webkit-border-radius: 2px;
+  background-image: linear-gradient(to bottom, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
 }
 .mblSliderHandle {
   margin: -10px 0 0 -10px;
   width: 18px;
   height: 18px;
-  border: #9D9D9D 1px outset;
-  -webkit-border-radius: 2px;
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 2px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9a9c), to(#848284));
+  background-image: linear-gradient(to bottom, #9c9a9c 0%, #848284 100%);
+  border-color: #9d9d9d;
 }
 .mblSliderTransition {
   -webkit-transition-duration: 400ms;
+  transition-duration: 400ms;
 }
 .mblSliderTouchBox {
   margin: 0;
diff --git a/dojox/mobile/themes/android/Slider.less b/dojox/mobile/themes/android/Slider.less
deleted file mode 100644
index 928972f..0000000
--- a/dojox/mobile/themes/android/Slider.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Slider.less";
diff --git a/dojox/mobile/themes/android/SpinWheel-compat.css b/dojox/mobile/themes/android/SpinWheel-compat.css
new file mode 100644
index 0000000..4d605d5
--- /dev/null
+++ b/dojox/mobile/themes/android/SpinWheel-compat.css
@@ -0,0 +1,36 @@
+.mblSpinWheel {
+  background-image: url(../common/compat/spinwheel-bg.png);
+}
+.mblSpinWheelBar {
+  background-image: url(../common/compat/spinwheel-bar.png);
+}
+.mblSpinWheelSlotTouch,
+.mblSpinWheelSlotPanel {
+  left: 0;
+}
+.dj_gecko .mblSpinWheel {
+  background-image: -moz-linear-gradient(top, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+}
+.dj_gecko .mblSpinWheelBar {
+  background-image: -moz-linear-gradient(top, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 1%);
+}
+.dj_ff3 .mblSpinWheel {
+  -moz-border-radius: 3px;
+}
+.dj_ie .mblSpinWheelBar {
+  filter: progid:DXImageTransform.Microsoft.alpha(opacity=60);
+}
+.dj_ie6 .mblSpinWheelBar,
+.dj_ie7 .mblSpinWheelBar {
+  z-index: -1;
+}
+.dj_ie7 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
+.dj_ie6 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
diff --git a/dojox/mobile/themes/android/SpinWheel.css b/dojox/mobile/themes/android/SpinWheel.css
new file mode 100644
index 0000000..8764541
--- /dev/null
+++ b/dojox/mobile/themes/android/SpinWheel.css
@@ -0,0 +1,77 @@
+/* dojox.mobile.SpinWheel */
+.mblSpinWheel {
+  position: relative;
+  overflow: hidden;
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #313137), color-stop(0.05, #73747d), color-stop(0.07, #92939b), color-stop(0.09, #ababb5), color-stop(0.12, #c5c6ce), color-stop(0.16, #dfe0e4), color-stop(0.22, #f4f5f6), color-stop(0.35, #fbfcfc), color-stop(0.5, #fbfcfc), color-stop(0.61, #fbfcfc), color-stop(0.61, #b4c1c7), color-stop(0.65, #fbfcfc), color-stop(0.78, #f4f5f6), color-stop(0.84, #dfe0e4), color-stop(0.88, #c5c6ce), color-stop(0.91, #ababb5), co [...]
+  background: linear-gradient(to bottom, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+  height: 200px;
+  border-left: solid 3px #000000;
+  border-right: solid 3px #000000;
+  color: #000000;
+  border-radius: 3px;
+}
+.mblSpinWheelBar {
+  position: absolute;
+  top: 79px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#edeef2), to(#a7adca), color-stop(0, #edeef2), color-stop(0.25, #c8cadd), color-stop(0.49, #bbbfd4), color-stop(0.51, #9fa8c6), color-stop(0.81, #a2a9c7), color-stop(0.82, #a6abc9), color-stop(1, #a7adca));
+  background: linear-gradient(to bottom, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 100%);
+  border: solid 1px #7b8497;
+  height: 42px;
+  width: 100%;
+  clear: both;
+  opacity: 0.6;
+}
+.mblSpinWheelDatePicker {
+  width: 312px;
+}
+.mblSpinWheelTimePicker {
+  width: 98px;
+}
+.mblSpinWheelSlot {
+  position: relative;
+  top: 0px;
+  float: left;
+  width: 100px;
+  height: 100%;
+  border-left: solid 2px #000000;
+  border-right: solid 2px #000000;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblSpinWheelSlotLabel {
+  padding: 0 8px;
+  height: 44px;
+  overflow: hidden;
+  font: bold 24px/44px Helvetica, sans-serif;
+}
+.mblSpinWheelSlotLabel img {
+  vertical-align: middle;
+  opacity: 0.7;
+}
+.mblSpinWheelSlotLabelGray {
+  color: #cccccc;
+}
+.mblSpinWheelSlotLabelBlue {
+  color: #0959d2;
+}
+.mblSpinWheelSlotContainer {
+  position: relative;
+}
+.mblSpinWheelSlotPanel {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+}
+.mblSpinWheelSlotTouch {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  z-index: 1;
+}
+.dj_ie .mblSpinWheelSlotTouch {
+  background-color: rgba(255, 255, 255, 0.01);
+}
+.dj_ie8 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+}
diff --git a/dojox/mobile/themes/android/SpinWheel_rtl-compat.css b/dojox/mobile/themes/android/SpinWheel_rtl-compat.css
new file mode 100644
index 0000000..98aab55
--- /dev/null
+++ b/dojox/mobile/themes/android/SpinWheel_rtl-compat.css
@@ -0,0 +1,4 @@
+.mblSpinWheelSlotRtl .mblSpinWheelSlotTouch,
+.mblSpinWheelSlotRtl .mblSpinWheelSlotPanel {
+  right: 0;
+}
diff --git a/dojox/mobile/themes/android/SpinWheel_rtl.css b/dojox/mobile/themes/android/SpinWheel_rtl.css
new file mode 100644
index 0000000..c3efc85
--- /dev/null
+++ b/dojox/mobile/themes/android/SpinWheel_rtl.css
@@ -0,0 +1,5 @@
+/* dojox.mobile.SpinWheel Rtl */
+.mblSpinWheelSlotRtl,
+.mblSpinWheelRtl .mblSpinWheelSlot {
+  float: right;
+}
diff --git a/dojox/mobile/themes/android/Switch-compat.css b/dojox/mobile/themes/android/Switch-compat.css
index 3756d95..a3502b3 100644
--- a/dojox/mobile/themes/android/Switch-compat.css
+++ b/dojox/mobile/themes/android/Switch-compat.css
@@ -1,70 +1,116 @@
-/* Switch - default */
-.mblSwitchBg {
-	border: none;
-}
-.mblSwitchBgLeft {
-	background: none;
-	background-image: url(compat/switch-default-l.gif);
-	background-repeat: no-repeat;
-}
-.mblSwitchBgRight {
-	background: none;
-	background-image: url(compat/switch-default-r.gif);
-	background-repeat: no-repeat;
-}
-.mblSwitchKnob {
-	top: 0px;
-	height: 27px;
-	background: none;
-	background-image: url(compat/switch-default-k.gif);
-	background-repeat: no-repeat;
-	border: none;
-}
-/* Switch - Round Shape1 */
+/* dojox.mobile.Switch */
+/* Switch - common */
+.dj_gecko .mblSwitchBg {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitchKnob {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitch .mblSwitchBgLeft {
+  background-image: -moz-linear-gradient(top, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
+}
+.dj_gecko .mblSwitch .mblSwitchBgRight {
+  background-image: -moz-linear-gradient(top, #bdbebd 0%, #f7f3f7 100%);
+}
+.dj_gecko .mblSwitch .mblSwitchKnob {
+  background-image: -moz-linear-gradient(top, #9c9a9c 0%, #848284 100%);
+}
+.dj_ie .mblSwitchBg {
+  border: none;
+  background: none;
+}
+.dj_ie .mblSwitchBgLeft {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchBgRight {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchKnob {
+  background: none;
+  background-repeat: no-repeat;
+  border: none;
+}
+/* Square Shape */
+.mblSwSquareShape .mblSwitchBg {
+  -moz-border-radius: 2px;
+}
+.mblSwSquareShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-square-l.gif);
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchKnob {
+  -moz-border-radius: 2px;
+  background-image: url(compat/switch-square-k.gif);
+}
+/* Round Shape1 */
+.mblSwRoundShape1 .mblSwitchBg {
+  -moz-border-radius: 14px;
+}
 .mblSwRoundShape1 .mblSwitchBgLeft {
-	background-image: url(compat/switch-round-l.gif);
+  background-image: url(compat/switch-round1-l.gif);
 }
 .mblSwRoundShape1 .mblSwitchBgRight {
-	background-image: url(compat/switch-round-r.gif);
+  background-image: url(compat/switch-round1-r.gif);
 }
 .mblSwRoundShape1 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-round1-k.gif);
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round1-k.gif);
+}
+/* Round Shape2 */
+.mblSwRoundShape2 .mblSwitchBg {
+  -moz-border-radius: 14px;
 }
-/* Switch - Round Shape2 */
 .mblSwRoundShape2 .mblSwitchBgLeft {
-	background-image: url(compat/switch-round-l.gif);
+  background-image: url(compat/switch-round2-l.gif);
 }
 .mblSwRoundShape2 .mblSwitchBgRight {
-	background-image: url(compat/switch-round-r.gif);
+  background-image: url(compat/switch-round2-r.gif);
 }
 .mblSwRoundShape2 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-round2-k.gif);
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round2-k.gif);
+}
+/* Arc Shape1 */
+.mblSwArcShape1 .mblSwitchBg {
+  -moz-border-radius: 5px/14px;
 }
-/* Switch - Arc Shape1 */
 .mblSwArcShape1 .mblSwitchBgLeft {
-	background-image: url(compat/switch-arc-l.gif);
+  background-image: url(compat/switch-arc1-l.gif);
 }
 .mblSwArcShape1 .mblSwitchBgRight {
-	background-image: url(compat/switch-arc-r.gif);
+  background-image: url(compat/switch-arc1-r.gif);
 }
 .mblSwArcShape1 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-arc1-k.gif);
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc1-k.gif);
 }
 /* Switch - Arc Shape2 */
+.mblSwArcShape2 .mblSwitchBg {
+  -moz-border-radius: 5px/14px;
+}
 .mblSwArcShape2 .mblSwitchBgLeft {
-	background-image: url(compat/switch-arc-l.gif);
+  background-image: url(compat/switch-arc2-l.gif);
 }
 .mblSwArcShape2 .mblSwitchBgRight {
-	background-image: url(compat/switch-arc-r.gif);
+  background-image: url(compat/switch-arc2-r.gif);
 }
 .mblSwArcShape2 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-arc2-k.gif);
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc2-k.gif);
+}
+/* Default Shape */
+.mblSwDefaultShape .mblSwitchBg {
+  -moz-border-radius: 2px;
+}
+.mblSwDefaultShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-square-l.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  -moz-border-radius: 2px;
+  background-image: url(compat/switch-square-k.gif);
 }
diff --git a/dojox/mobile/themes/android/Switch-compat.less b/dojox/mobile/themes/android/Switch-compat.less
new file mode 100644
index 0000000..f15894c
--- /dev/null
+++ b/dojox/mobile/themes/android/Switch-compat.less
@@ -0,0 +1,7 @@
+ at import "variables.less";
+ at import "../common/Switch-compat.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwSquareShape-styles;
+}
diff --git a/dojox/mobile/themes/android/Switch.css b/dojox/mobile/themes/android/Switch.css
index f8d1147..b15a0d5 100644
--- a/dojox/mobile/themes/android/Switch.css
+++ b/dojox/mobile/themes/android/Switch.css
@@ -1,18 +1,228 @@
- at import url("../common/Switch.css");
 /* dojox.mobile.Switch */
-.mblItemSwitch {
-  top: 18px;
+/* Switch - common */
+.mblSwitch {
+  margin: 0;
+  position: relative;
+  display: inline-block;
+  height: 27px;
+  line-height: 29px;
+  overflow: hidden;
+  text-align: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblListItem .mblSwitch {
+  position: absolute;
+  right: 12px;
+  top: 18.5px;
+}
+.mblSwitchInner {
+  position: absolute;
+  top: 0;
+  height: 27px;
+}
+.mblSwitchAnimation .mblSwitchInner {
+  -webkit-transition-property: left;
+  transition-property: left;
+  -webkit-transition-duration: 0.1s;
+  transition-duration: 0.1s;
+}
+.mblSwitchOn .mblSwitchInner {
+  left: 0;
 }
 .mblSwitchBg {
-  -webkit-border-radius: 2px;
+  position: absolute;
+  top: 0;
+  width: 94px;
+  height: 27px;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+  line-height: 29px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border: rgba(176, 176, 176, 0.5) 1px inset;
 }
 .mblSwitchBgLeft {
+  left: 0;
+  color: white;
+  background-color: #3f84eb;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#00a200), to(#00d300), color-stop(0.2, #00ba00), color-stop(0.2, #00ba00));
+  background-image: linear-gradient(to bottom, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
 }
 .mblSwitchBgRight {
+  color: #7f7f7f;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#bdbebd), to(#f7f3f7));
+  background-image: linear-gradient(to bottom, #bdbebd 0%, #f7f3f7 100%);
 }
 .mblSwitchKnob {
+  position: absolute;
+  top: 0;
+  height: 27px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9a9c), to(#848284));
-  -webkit-border-radius: 2px;
+  background-image: linear-gradient(to bottom, #9c9a9c 0%, #848284 100%);
+  font-size: 1px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border: rgba(157, 157, 157, 0.5) 1px outset;
+}
+.mblSwitchText {
+  position: relative;
+  top: 0;
+  width: 53px;
+  height: 27px;
+  padding: 0;
+  line-height: 28px;
+  text-align: center;
+}
+.mblSwitchTextLeft {
+  left: 0;
+}
+.mblSwitchTextRight {
+  left: 40px;
+}
+/* Square Shape */
+.mblSwSquareShape {
+  width: 94px;
+}
+.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBg {
+  border-radius: 2px;
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+  width: 41px;
+  border-radius: 2px;
+}
+.mblSwSquareShape .mblSwitchText {
+  width: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRight {
+  left: 40px;
+}
+/* Round Shape1 */
+.mblSwRoundShape1 {
+  width: 77px;
+}
+.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwRoundShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 14px;
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 13px;
+}
+.mblSwRoundShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Round Shape2 */
+.mblSwRoundShape2 {
+  width: 94px;
+}
+.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBg {
+  border-radius: 14px;
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 13px;
+}
+.mblSwRoundShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Arc Shape1 */
+.mblSwArcShape1 {
+  width: 77px;
+}
+.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwArcShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 5px/14px;
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Arc Shape2 */
+.mblSwArcShape2 {
+  width: 94px;
+}
+.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBg {
+  border-radius: 5px/14px;
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Default Shape */
+.mblSwDefaultShape {
+  width: 94px;
+}
+.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: -53px;
+}
+.mblSwDefaultShape .mblSwitchBg {
+  border-radius: 2px;
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  left: 53px;
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  left: 53px;
+  width: 41px;
+  border-radius: 2px;
+}
+.mblSwDefaultShape .mblSwitchText {
+  width: 53px;
+}
+.mblSwDefaultShape .mblSwitchTextRight {
+  left: 40px;
 }
diff --git a/dojox/mobile/themes/android/Switch.less b/dojox/mobile/themes/android/Switch.less
index 84a1146..51d10ad 100644
--- a/dojox/mobile/themes/android/Switch.less
+++ b/dojox/mobile/themes/android/Switch.less
@@ -1,4 +1,7 @@
- at import url("../common/Switch.css");
-
 @import "variables.less";
 @import "../common/Switch.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwSquareShape-styles;
+}
diff --git a/dojox/mobile/themes/android/Switch_rtl-compat.css b/dojox/mobile/themes/android/Switch_rtl-compat.css
new file mode 100644
index 0000000..5293453
--- /dev/null
+++ b/dojox/mobile/themes/android/Switch_rtl-compat.css
@@ -0,0 +1,43 @@
+/* dojox.mobile.Switch Rtl */
+/* Square Shape Rtl */
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
+/* Round Shape1 Rtl */
+.mblSwRoundShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round1-l.gif);
+}
+/* Round Shape2 Rtl */
+.mblSwRoundShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round2-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round2-l.gif);
+}
+/* Arc Shape1 Rtl */
+.mblSwArcShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc1-r.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc1-l.gif);
+}
+/* Switch - Arc Shape2 Rtl */
+.mblSwArcShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc2-r.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc2-l.gif);
+}
+/* Default Shape Rtl */
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
diff --git a/dojox/mobile/themes/android/Switch_rtl.css b/dojox/mobile/themes/android/Switch_rtl.css
new file mode 100644
index 0000000..5bb0935
--- /dev/null
+++ b/dojox/mobile/themes/android/Switch_rtl.css
@@ -0,0 +1,117 @@
+/* dojox.mobile.Switch Rtl */
+/* Switch - common Rtl */
+.mblSwitchRtl {
+  text-align: right;
+}
+.mblListItemRtl .mblSwitch {
+  left: 12px;
+  right: auto;
+}
+.mblSwitchRtl.mblSwitchOn .mblSwitchInner {
+  left: -50px;
+}
+.mblSwitchBgLeftRtl {
+  left: 51px;
+}
+.mblSwitchTextLeftRtl {
+  left: 0px;
+}
+.mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Square Shape Rtl*/
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Round Shape1 Rtl */
+.mblSwitchRtl.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Round Shape2 Rtl */
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Arc Shape1 Rtl */
+.mblSwitchRtl.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Arc Shape2 Rtl */
+.mblSwitchRtl.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Default Shape Rtl */
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwDefaultShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwDefaultShape .mblSwitchTextRightRtl {
+  left: -40px;
+}
diff --git a/dojox/mobile/themes/android/TabBar-compat.css b/dojox/mobile/themes/android/TabBar-compat.css
index 94fbb13..c39354a 100644
--- a/dojox/mobile/themes/android/TabBar-compat.css
+++ b/dojox/mobile/themes/android/TabBar-compat.css
@@ -1,35 +1,59 @@
-/* dojox.mobile.TabBarButton */
-.mblTabBar {
-	background-color: #1e1e1e;
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
+/* dojox.mobile.TabBar */
+.dj_ie6 .mblTabBar .mblTabBarButton {
+  display: inline;
 }
-.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
-	left: auto;
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  background-image: none;
+  background-color: #000000;
 }
-.dj_ie6 .mblTabBar .mblTabBarButton {
-  display: inline; /* IE bug*/
+.dj_ff3 .mblTabBarTabBar .mblTabBarButtonSelected {
+  -moz-border-radius: 3px;
+}
+/* barType="segmentedControl" | "standardTab" */
+.mblTabBarSegmentedControl,
+.mblTabBarStandardTab {
+  background-image: url(compat/heading-bg.png);
+}
+.mblTabBarSegmentedControl .mblTabBarButton,
+.mblTabBarStandardTab .mblTabBarButton {
+  background-image: url(compat/tab-seg-button-bg.png);
+}
+.mblTabBarSegmentedControl .mblTabBarButtonSelected,
+.mblTabBarStandardTab .mblTabBarButtonSelected {
+  background-image: url(compat/tab-seg-sel-button-bg.png);
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:first-child {
+  -moz-border-radius-topleft: 5px;
+  -moz-border-radius-bottomleft: 5px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:last-child {
+  -moz-border-radius-topright: 5px;
+  -moz-border-radius-bottomright: 5px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButton {
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 4px;
 }
-.mblTabBar .mblTabBarButton.mblTabButtonSelected {
-	-moz-border-radius: 3px;
-	background-image: none;
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  background-image: url(compat/tab-slim-bar-bg.png);
 }
-.mblTabPanelHeader .mblTabButton {
-	background-image: url(compat/tab-button-bg.png);
+.dj_gecko .mblTabBarSlimTab {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
 }
-.mblTabPanelHeader .mblTabButton.mblTabButtonSelected {
-	background-image: url(compat/tab-sel-button-bg.png);
+.dj_gecko .mblTabBarSlimTab .mblTabBarButton {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
 }
-*html .mblTabButton { /* IE6 hack */
-	behavior: expression(
-		(function(el){
-			if(!el.previousSibling)
-				el.style.borderWidth = "1px";
-			el.style.behavior = "none";
-		})(this)
-	);
+.dj_gecko .mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-image: -moz-linear-gradient(top, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
 }
-.dj_ie6 .mblTabPanelHeader .mblDomButton {
-	left: 0px;
+/* barType="flatTab" */
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  background-image: url(compat/tab-tall-bar-bg.png);
 }
-.mblHeading .mblTabPanelHeader .mblTabButton {
-	background-image: none;
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-color: #8c8e8c;
 }
diff --git a/dojox/mobile/themes/android/TabBar-compat.less b/dojox/mobile/themes/android/TabBar-compat.less
new file mode 100644
index 0000000..c0476f3
--- /dev/null
+++ b/dojox/mobile/themes/android/TabBar-compat.less
@@ -0,0 +1,3 @@
+ at import "variables.less";
+ at import "../common/TabBar-compat.less";
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
diff --git a/dojox/mobile/themes/android/TabBar.css b/dojox/mobile/themes/android/TabBar.css
index 99955c8..661b2e4 100644
--- a/dojox/mobile/themes/android/TabBar.css
+++ b/dojox/mobile/themes/android/TabBar.css
@@ -1,158 +1,256 @@
+ at import "../common/domButtons/DomButtonWhiteCross.css";
 /* dojox.mobile.TabBar */
 .mblTabBar {
   position: relative;
+  margin: 0px;
   overflow: hidden;
   white-space: nowrap;
-  margin: 0px;
-  padding: 0px;
-  height: 48px;
-  border-top: 1px solid #000000;
-  background-color: #000000;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000));
-  color: white;
+  text-overflow: ellipsis;
+  padding: 0px 6px;
+  height: 42px;
   text-align: center;
-}
-.mblTabBarNoIcons {
-  height: 34px;
-}
-.mblTabBarNoText {
-  height: 34px;
+  color: white;
+  border-top: 1px solid #cdd5df;
+  border-bottom: 1px solid #2d3642;
+  text-shadow: none;
 }
 /* dojox.mobile.TabBarButton */
+.mblTabBarFill .mblTabBarButton {
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
 .mblTabBarButton {
+  overflow: hidden;
   cursor: pointer;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-}
-.mblTabBar .mblTabBarButton {
   position: relative;
   list-style-type: none;
   float: left;
 }
-.mblTabBar .mblTabBarButton.mblTabButtonSelected {
-  -webkit-border-radius: 3px;
-  background-color: #404040;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424));
+.mblTabBarButtonIconArea {
+  margin: 0 auto;
+  width: 29px;
 }
-.mblTabBarButtonAnchor {
+.mblTabBarButtonIconParent1 {
   display: block;
-  text-decoration: none;
 }
-.mblTabBarButtonDiv {
-  position: relative;
-  margin-left: auto;
-  margin-right: auto;
-  width: 29px;
-  height: 32px;
-  margin-top: 2px;
+.mblTabBarButtonIconParent2 {
+  display: none;
 }
-.mblTabBarButtonIcon {
-  position: absolute;
-  left: 0px;
-  top: 0px;
+.mblTabBarButtonSelected .mblTabBarButtonIconParent1 {
+  display: none;
 }
-.mblTabBarButtonSpriteIcon {
-  position: absolute;
+.mblTabBarButtonSelected .mblTabBarButtonIconParent2 {
+  display: block;
 }
-.mblTabBarButtonTextBox {
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  height: 48px;
+  border-top: 1px solid #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #000000 100%);
+}
+.mblTabBarTabBar .mblTabBarButtonIconArea {
+  padding-top: 4px;
+}
+.mblTabBarTabBar .mblTabBarButtonLabel {
   font-family: "Helvetica Neue", Helvetica;
   font-size: 11px;
+  color: white;
 }
-.mblTabBarNoIcons .mblTabBarButtonDiv {
-  display: none;
+.mblTabBarTabBar .mblTabBarButtonSelected {
+  border-radius: 3px;
+  background-color: #404040;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424));
+  background-image: linear-gradient(to bottom, #484848 0%, #242424 100%);
 }
-.mblTabBarNoIcons .mblTabBarButtonTextBox {
-  line-height: 34px;
-  font-size: 20px;
+.mblTabBarTabBar .mblTabBarButtonSelected .mblTabBarButtonLabel {
+  color: white;
 }
-.mblTabBarTop .mblTabButton .mblTabBarButtonDiv {
-  height: 38px;
+/* barType="segmentedControl" */
+.mblTabBarSegmentedControl {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9e9c), to(#848284));
+  background-image: linear-gradient(to bottom, #9c9e9c 0%, #848284 100%);
 }
-.mblTabBarHead .mblTabButton .mblTabBarButtonDiv {
-  margin-top: -2px;
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButton {
+  width: auto;
+  padding: 0 3px;
 }
-.mblTabButton {
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconArea {
   position: relative;
-  float: left;
-  list-style-type: none;
-  cursor: pointer;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  margin-right: 2px;
-  width: 78px;
-  height: 61px;
-  border-width: 0px 1px 0px 1px;
-  border-style: solid;
-  border-color: black #182018 black #393C39;
-  background-color: #212421;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100c10), color-stop(0.1, #313031));
+}
+.mblTabBarSegmentedControl .mblTabBarButton {
+  margin: 6px 0;
+  width: 100px;
+  height: 29px;
+  border-width: 1px 1px 1px 0px;
   font-family: Helvetica;
   font-size: 13px;
-  color: white;
+  font-weight: bold;
   text-align: center;
+  line-height: 29px;
+  border-style: solid;
+  border-color: #555555;
+  color: #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dfdfdf), to(#a6a6a6));
+  background-image: linear-gradient(to bottom, #dfdfdf 0%, #a6a6a6 100%);
+}
+.mblTabBarSegmentedControl .mblTabBarButton:first-child {
+  border-left-width: 1px;
+  border-top-left-radius: 5px;
+  border-bottom-left-radius: 5px;
 }
-.mblTabButton img {
+.mblTabBarSegmentedControl .mblTabBarButton:last-child {
+  border-top-right-radius: 5px;
+  border-bottom-right-radius: 5px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconArea {
   position: absolute;
+  top: 0px;
   left: 0px;
-  margin-top: 8px;
 }
-.mblTabButtonSelected .mblTabBarButtonTextBox {
-  color: white;
+.mblTabBarSegmentedControl .mblTabBarButtonSelected {
+  color: #ffffff;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#313031), to(#959595), color-stop(0.5, #5a555a), color-stop(0.5, #616161));
+  background-image: linear-gradient(to bottom, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
 }
-.mblTabButtonSelected.mblTabButton {
-  background-color: #8C8E8C;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#a59ea5), to(#848284));
+.mblHeading .mblTabBarSegmentedControl {
+  display: inline;
+  float: left;
+  height: auto;
+  border: none;
 }
-.mblTabButtonHighlighted.mblTabButton {
-  background-color: #FFB600;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffcb00), to(#ff9a00));
+/* barType="standardTab" */
+.mblTabBarStandardTab {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9e9c), to(#848284));
+  background-image: linear-gradient(to bottom, #9c9e9c 0%, #848284 100%);
 }
-.mblTabButtonImgDiv {
-  position: relative;
-  margin-left: 24px;
-  height: 40px;
+.mblTabBarStandardTab .mblTabBarButton {
+  margin-top: 9px;
+  padding: 9px;
+  border: 1px solid #62676d;
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  color: #000000;
+  background-color: #c6c6c6;
+  /* TODO: to compat */
+
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dfdfdf), to(#a6a6a6));
+  background-image: linear-gradient(to bottom, #dfdfdf 0%, #a6a6a6 100%);
 }
-.mblTabPanelHeader {
-  position: relative;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  margin: 0px;
-  padding: 0px 0px 0px 0px;
-  height: 64px;
-  border-top: 1px solid #CDD5DF;
-  border-bottom: 2px solid #949694;
+.mblTabBarStandardTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 3px;
+  left: 0px;
+}
+.mblTabBarStandardTab .mblTabBarButtonSelected {
+  color: #ffffff;
+  background-color: #3578b1;
+  /* TODO: to compat */
+
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#313031), to(#959595), color-stop(0.5, #5a555a), color-stop(0.5, #616161));
+  background-image: linear-gradient(to bottom, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
+}
+.mblTabBarStandardTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  height: 30px;
+  padding: 0px;
+  border: 1px solid #2d3642;
   background-color: #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.mblTabBarSlimTab .mblTabBarButton {
+  padding: 7px;
+  border-right: 1px solid #4e4e4e;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
   font-family: Helvetica;
-  font-size: 20px;
+  font-size: 14px;
+  font-weight: bold;
   color: white;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
   text-align: center;
 }
-.mblTabPanelHeader .mblTabButton {
-  margin-top: 3px;
+.mblTabBarSlimTab .mblTabBarButton:first-child {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
 }
-.mblTabPanelHeader .mblTabButtonDomButton {
-  width: 43px;
+.mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-color: #404040;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#313031), to(#959595), color-stop(0.5, #5a555a), color-stop(0.5, #616161));
+  background-image: linear-gradient(to bottom, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
 }
-.mblTabPanelHeader .mblTabButtonDomButtonClass {
-  left: 8px;
+.mblTabBarSlimTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
 }
-.mblHeading .mblTabPanelHeader {
-  height: 25px;
+/* barType="flatTab" */
+.mblTabBarFlatTab {
+  height: 30px;
+  padding: 0px;
+  border-style: none;
+  background-color: transparent;
+  background-image: none;
 }
-.mblHeading .mblTabPanelHeader .mblTabButton {
-  margin-top: 0;
-  margin-right: 0;
-  height: 22px;
-  line-height: 23px;
-  border-width: 1px 1px 1px 0px;
+.mblTabBarFlatTab .mblTabBarButton {
+  padding: 7px;
+  background-image: none;
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
+  text-align: center;
+}
+.mblTabBarFlatTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+}
+.mblTabBarFlatTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  height: 64px;
+  border-top: 1px solid #cdd5df;
+  border-bottom: 2px solid #949694;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #000000 100%);
+}
+.mblTabBarTallTab .mblTabBarButton {
+  margin-top: 3px;
+  margin-right: 2px;
+  width: 78px;
+  height: 61px;
+  border-width: 0px 1px 0px 1px;
   border-style: solid;
-  border-color: #555555;
-  background-color: #ADADAD;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#e5e5e5), to(#7f7f7f), color-stop(0.5, #adadad), color-stop(0.5, #909090));
+  border-color: black #182018 black #393c39;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100c10), color-stop(0.1, #313031));
+  background-image: linear-gradient(to bottom, #181818 0%, #313031 10%, #100c10 100%);
+  font-family: Helvetica;
+  font-size: 13px;
+  color: white;
+  text-align: center;
 }
-.mblHeading .mblTabPanelHeader .mblTabButton:first-child {
-  border-left-width: 1px;
+.mblTabBarTallTab .mblTabBarButtonIconArea {
+  margin-top: 8px;
 }
-.mblHeading .mblTabPanelHeader .mblTabButtonSelected {
-  background-color: #FFC700;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
+.mblTabBarTallTab .mblTabBarButtonLabel {
+  font-family: "Helvetica Neue", Helvetica;
+  font-size: 11px;
+}
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#a59ea5), to(#848284));
+  background-image: linear-gradient(to bottom, #a59ea5 0%, #848284 100%);
 }
diff --git a/dojox/mobile/themes/android/TabBar.less b/dojox/mobile/themes/android/TabBar.less
index 4875c40..4066ecc 100644
--- a/dojox/mobile/themes/android/TabBar.less
+++ b/dojox/mobile/themes/android/TabBar.less
@@ -1,2 +1,3 @@
 @import "variables.less";
 @import "../common/TabBar.less";
+ at import "../common/domButtons/DomButtonWhiteCross.css";
diff --git a/dojox/mobile/themes/android/TabBar_rtl-compat.css b/dojox/mobile/themes/android/TabBar_rtl-compat.css
new file mode 100644
index 0000000..848279c
--- /dev/null
+++ b/dojox/mobile/themes/android/TabBar_rtl-compat.css
@@ -0,0 +1,19 @@
+/* barType="segmentedControl" | "standardTab" Rtl */
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  -moz-border-radius-topright: 5px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-bottomright: 5px;
+  -moz-border-radius-bottomleft: 0px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  -moz-border-radius-topleft: 5px;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomleft: 5px;
+  -moz-border-radius-bottomright: 0px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButtonRtl {
+  -moz-border-radius-topright: 4px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 0px;
+}
diff --git a/dojox/mobile/themes/android/TabBar_rtl.css b/dojox/mobile/themes/android/TabBar_rtl.css
new file mode 100644
index 0000000..5553209
--- /dev/null
+++ b/dojox/mobile/themes/android/TabBar_rtl.css
@@ -0,0 +1,89 @@
+/* dojox.mobile.TabBarButton Rtl */
+.mblTabBarButtonRtl {
+  float: right;
+}
+.mblTabBarButtonIconAreaRtl {
+  margin: 0 auto;
+  width: 29px;
+}
+/* barType="tabBar" Rtl */
+.mblTabBarTabBar .mblTabBarButtonIconAreaRtl {
+  padding-top: 4px;
+}
+/* barType="segmentedControl" Rtl */
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconAreaRtl {
+  position: relative;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl {
+  border-width: 1px 0px 1px 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  border-right-width: 1px !important;
+  border-left-width: 0px;
+  border-top-right-radius: 5px;
+  border-top-left-radius: 0px;
+  border-bottom-right-radius: 5px;
+  border-bottom-left-radius: 0px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  border-top-left-radius: 5px;
+  border-top-right-radius: 0px;
+  border-bottom-left-radius: 5px;
+  border-bottom-right-radius: 0px;
+  border-left-width: 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblHeading .mblTabBarSegmentedControl.mblTabBarRtl {
+  float: right;
+}
+/* barType="standardTab" Rtl */
+.mblTabBarStandardTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 3px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarStandardTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="slimTab" Rtl */
+.mblTabBarSlimTab .mblTabBarButtonRtl {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl:first-child {
+  border-right: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="flatTab" Rtl*/
+.mblTabBarFlatTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarFlatTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab .mblTabBarButtonRtl {
+  margin-left: 2px;
+}
+.mblTabBarTallTab .mblTabBarButtonIconAreaRtl {
+  margin-top: 8px;
+}
diff --git a/dojox/mobile/themes/android/TextArea-compat.css b/dojox/mobile/themes/android/TextArea-compat.css
index a4312f1..3fcbff1 100644
--- a/dojox/mobile/themes/android/TextArea-compat.css
+++ b/dojox/mobile/themes/android/TextArea-compat.css
@@ -1,7 +1,7 @@
 /* dojox.mobile.TextArea */
 .mblTextArea {
-	-moz-border-radius: 3px;
-	-o-border-radius: 3px;
-	-ms-border-radius: 3px;
-	border-radius: 3px;
+  overflow: auto;
+}
+.dj_ff3 .mblTextArea {
+  -moz-border-radius: 3px;
 }
diff --git a/dojox/mobile/themes/android/TextArea.css b/dojox/mobile/themes/android/TextArea.css
index 4cb389c..97a80b4 100644
--- a/dojox/mobile/themes/android/TextArea.css
+++ b/dojox/mobile/themes/android/TextArea.css
@@ -1,12 +1,12 @@
 /* dojox.mobile.TextArea */
 .mblTextArea {
   padding: 4px 1px;
-  border-color: #9CACC0;
   border-width: 1px;
   border-style: inset;
-  -webkit-border-radius: 3px;
   font-family: Helvetica;
   font-size: 13px;
+  border-color: #9cacc0;
+  border-radius: 3px;
 }
 /* dojox.mobile.ExpandingTextArea */
 .mblExpandingTextArea {
diff --git a/dojox/mobile/themes/android/TextArea.less b/dojox/mobile/themes/android/TextArea.less
deleted file mode 100644
index c16ffe0..0000000
--- a/dojox/mobile/themes/android/TextArea.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/TextArea.less";
diff --git a/dojox/mobile/themes/android/TextBox-compat.css b/dojox/mobile/themes/android/TextBox-compat.css
index 619c360..b04cce1 100644
--- a/dojox/mobile/themes/android/TextBox-compat.css
+++ b/dojox/mobile/themes/android/TextBox-compat.css
@@ -1,7 +1,4 @@
 /* dojox.mobile.TextBox */
-.mblTextBox {
-	-moz-border-radius: 3px;
-	-o-border-radius: 3px;
-	-ms-border-radius: 3px;
-	border-radius: 3px;
+.dj_ff3 .mblTextBox {
+  -moz-border-radius: 3px;
 }
diff --git a/dojox/mobile/themes/android/TextBox.css b/dojox/mobile/themes/android/TextBox.css
index d847ab5..f2ef466 100644
--- a/dojox/mobile/themes/android/TextBox.css
+++ b/dojox/mobile/themes/android/TextBox.css
@@ -1,8 +1,10 @@
 /* dojox.mobile.TextBox */
 .mblTextBox {
   height: 22px;
-  border: #9CACC0 1px inset;
-  -webkit-border-radius: 3px;
+  border-width: 1px;
+  border-style: inset;
   font-family: Helvetica;
   font-size: 13px;
+  border-color: #9cacc0;
+  border-radius: 3px;
 }
diff --git a/dojox/mobile/themes/android/TextBox.less b/dojox/mobile/themes/android/TextBox.less
deleted file mode 100644
index c83890a..0000000
--- a/dojox/mobile/themes/android/TextBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/TextBox.less";
diff --git a/dojox/mobile/themes/android/TimePicker.css b/dojox/mobile/themes/android/TimePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/android/TimePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/android/ToggleButton-compat.css b/dojox/mobile/themes/android/ToggleButton-compat.css
index 9891522..b18dfd4 100644
--- a/dojox/mobile/themes/android/ToggleButton-compat.css
+++ b/dojox/mobile/themes/android/ToggleButton-compat.css
@@ -1,30 +1,42 @@
 /* dojox.mobile.ToggleButton */
 .mblToggleButton {
-	background-image: url(compat/button-bg.png);
-	-moz-border-radius: 3px;
-	-o-border-radius: 3px;
-	-ms-border-radius: 3px;
-	border-radius: 3px;
+  background-image: url(compat/button-bg.png);
 }
 .mblToggleButtonSelected {
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/button-sel-bg.png);
 }
 .mblToggleButtonChecked {
-	background-image: url(compat/togglebutton-chk-bg.png);
-}
-.mblToggleButton.mblToggleButtonChecked::after {
-	-moz-transform: translate(-25px,0px) rotate(45deg) skew(10deg);
-	-o-transform: rotate(45deg) skew(10deg);
-	-ms-transform: rotate(45deg) skew(10deg);
-	transform: rotate(45deg) skew(10deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblToggleButton {
+  background-image: -moz-linear-gradient(top, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+}
+.dj_gecko .mblToggleButtonSelected {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_gecko .mblToggleButtonChecked {
+  background-image: -moz-linear-gradient(top, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
+}
+.dj_gecko .mblToggleButtonChecked:after {
+  -moz-transform: rotate(45deg) skew(10deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_ff3 .mblToggleButton {
+  -moz-border-radius: 3px;
 }
 .dj_ff3 .mblToggleButton.mblToggleButtonChecked::after {
-	-moz-transform: translate(-25px,-6px) rotate(45deg) skew(10deg);
+  -moz-transform: translate(-25px, -6px) rotate(45deg) skew(10deg);
 }
-.mblToggleButtonChecked.mblToggleButtonSelected {
-	background-image: url(compat/button-sel-bg.png);
+.dj_ie .mblToggleButtonChecked:after {
+  top: 9px;
+  left: 5px;
+  width: 12px;
+  border: none;
+  background-image: url(compat/togglebutton-chk-mark-bg.png);
 }
diff --git a/dojox/mobile/themes/android/ToggleButton.css b/dojox/mobile/themes/android/ToggleButton.css
index 31d0557..2ea22c0 100644
--- a/dojox/mobile/themes/android/ToggleButton.css
+++ b/dojox/mobile/themes/android/ToggleButton.css
@@ -1,52 +1,54 @@
 /* dojox.mobile.ToggleButton */
 .mblToggleButton {
   position: relative;
-  cursor: pointer;
-  outline: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  padding: 0px 10px 0px 25px;
+  padding: 0 10px 0 25px;
   height: 29px;
   border-width: 1px 1px 1px 1px;
   border-style: outset;
-  border-color: #9CACC0;
-  -webkit-border-radius: 3px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#cecece), color-stop(0.5, #f8f8f8), color-stop(0.5, #eeeeee));
+  background-image: linear-gradient(to bottom, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
   font-family: Helvetica;
+  line-height: 29px;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  border-color: #9cacc0;
+  border-radius: 3px;
   font-size: 13px;
   color: black;
-  line-height: 29px;
 }
-.mblToggleButton.mblToggleButtonSelected {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
+.mblToggleButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
+}
+.mblToggleButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
   color: white;
 }
-.mblToggleButton.mblToggleButtonChecked {
+.mblToggleButtonChecked {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#00a200), to(#00d300), color-stop(0.2, #00ba00), color-stop(0.2, #00ba00));
+  background-image: linear-gradient(to bottom, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
   color: white;
 }
-.mblToggleButton.mblToggleButtonChecked::after {
+.mblToggleButtonChecked:after {
   position: absolute;
   content: "";
   top: 6px;
   left: 7px;
   width: 5px;
   height: 10px;
-  border-color: white;
   border-width: 2px;
   border-style: none solid solid none;
   -webkit-transform: rotate(45deg) skew(10deg);
+  transform: rotate(45deg) skew(10deg);
   -webkit-transform-origin: 50% 50%;
-}
-.mblToggleButton.mblToggleButtonChecked.mblToggleButtonSelected {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
-  color: white;
-}
-.mblToggleButton.mblToggleButtonChecked.mblToggleButtonSelected::after {
+  transform-origin: 50% 50%;
   border-color: white;
 }
-.mblToggleButton:disabled {
-  cursor: default;
-  border-color: grey;
-  background-image: none;
-  color: grey;
+.mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+  color: white;
 }
diff --git a/dojox/mobile/themes/android/ToggleButton.less b/dojox/mobile/themes/android/ToggleButton.less
deleted file mode 100644
index bdce40f..0000000
--- a/dojox/mobile/themes/android/ToggleButton.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ToggleButton.less";
diff --git a/dojox/mobile/themes/android/ToggleButton_rtl.css b/dojox/mobile/themes/android/ToggleButton_rtl.css
new file mode 100644
index 0000000..16d136f
--- /dev/null
+++ b/dojox/mobile/themes/android/ToggleButton_rtl.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.ToggleButton Rtl */
+.mblToggleButtonRtl {
+  padding: 0 25px 0 10px!important;
+}
+.mblToggleButtonRtl.mblToggleButtonChecked:after {
+  right: 7px;
+}
diff --git a/dojox/mobile/themes/android/ToolBarButton-compat.css b/dojox/mobile/themes/android/ToolBarButton-compat.css
new file mode 100644
index 0000000..5363133
--- /dev/null
+++ b/dojox/mobile/themes/android/ToolBarButton-compat.css
@@ -0,0 +1,63 @@
+/* dojox.mobile.ToolBarButton */
+.dj_gecko .mblToolBarButtonArrow {
+  -moz-transform: scale(0.77, 1.05) rotate(45deg);
+}
+.dj_ff3 .mblToolBarButtonArrow {
+  -moz-border-radius: 1px;
+}
+.dj_ff3 .mblToolBarButtonBody {
+  -moz-border-radius: 0;
+}
+.dj_ff3 .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  -moz-border-radius-topleft: 0;
+  -moz-border-radius-bottomleft: 0;
+}
+.dj_ff3 .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 0;
+}
+.dj_ie .mblToolBarButtonLeftArrow {
+  top: 0;
+  left: -2px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonLeftArrow {
+  background-image: url(compat/arrow-button-head-sel.png);
+}
+.dj_ie .mblToolBarButtonRightArrow {
+  top: 0;
+  right: -3px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-right-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonRightArrow {
+  background-image: url(compat/arrow-button-right-head-sel.png);
+}
+.dj_ie .mblToolBarButtonBody {
+  background-image: url(compat/arrow-button-bg.png);
+  background-position: left bottom;
+}
+.dj_ie .mblToolBarButtonBodySelected {
+  background-image: url(compat/arrow-button-bg-sel.png);
+}
+.dj_ie .mblToolBarButtonBody table {
+  margin: 0;
+}
+.dj_ie .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.dj_ie .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.dj_ie6 .mblToolBarButton .mblToolBarButtonBody {
+  background-position: left top;
+}
diff --git a/dojox/mobile/themes/android/ToolBarButton.css b/dojox/mobile/themes/android/ToolBarButton.css
index 968b029..8450e66 100644
--- a/dojox/mobile/themes/android/ToolBarButton.css
+++ b/dojox/mobile/themes/android/ToolBarButton.css
@@ -1,31 +1,90 @@
 /* dojox.mobile.ToolBarButton */
 .mblToolBarButton {
-  float: left;
+  display: inline-block;
   position: relative;
-  overflow: hidden;
   cursor: pointer;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  margin: 0px 6px;
-  height: 22px;
-  border: 1px solid #555555;
+  margin: 6px;
+  padding: 0 10px;
+  height: 29px;
+  line-height: 29px;
+  text-align: center;
   font-family: Helvetica;
   font-size: 13px;
   font-weight: bold;
-  color: white;
-  line-height: 23px;
-  text-align: center;
+  vertical-align: middle;
+  text-shadow: none;
 }
-div.mblToolBarButtonDomButton {
-  height: 23px;
+.mblToolBarButtonHasIcon,
+.mblToolBarButtonLightIcon {
+  padding: 0;
 }
-.mblToolBarButtonIcon {
-  position: relative;
-  top: -2px;
-  padding: 0px;
+.mblHeading .mblToolBarButton {
+  float: left;
+}
+.mblHeading span.mblToolBarButtonLightIcon {
+  padding: 0;
+}
+.mblToolBarButtonHasLeftArrow {
+  padding-right: 0;
+  padding-left: 10px;
 }
-.mblToolBarButtonSpriteIcon {
+.mblToolBarButtonHasRightArrow {
+  padding-left: 0;
+  padding-right: 10px;
+}
+.mblToolBarButtonArrow {
   position: absolute;
+  top: 5px;
+  width: 20px;
+  height: 19px;
+  border-radius: 1px;
+  -webkit-transform: scale(0.7, 1.05) rotate(45deg);
+  transform: scale(0.7, 1.05) rotate(45deg);
+  border: 1px solid #3a4655;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: -1px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: -1px;
+}
+.mblToolBarButtonBody {
+  display: inline-block;
+  position: relative;
+  overflow: hidden;
+  border-radius: 0;
+  border: 1px solid #555555;
+}
+.mblToolBarButton .mblToolBarButtonBody {
+  width: 100%;
+}
+.mblToolBarButtonBody table {
+  margin: 0 auto;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-left-width: 0;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-right-width: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.mblToolBarButtonText .mblToolBarButtonIcon {
+  padding-left: 10px;
+}
+.mblToolBarButtonText .mblToolBarButtonLabel {
+  padding-right: 10px;
+  height: 29px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonIcon {
+  padding-left: 4px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonLabel {
+  padding-right: 4px;
 }
-.mblToolBarButtonText {
-  padding: 0px 10px;
+.mblToolBarButtonIcon > div {
+  height: 29px;
 }
diff --git a/dojox/mobile/themes/android/ToolBarButton.less b/dojox/mobile/themes/android/ToolBarButton.less
deleted file mode 100644
index 3b67bdc..0000000
--- a/dojox/mobile/themes/android/ToolBarButton.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ToolBarButton.less";
diff --git a/dojox/mobile/themes/android/ToolBarButton_rtl.css b/dojox/mobile/themes/android/ToolBarButton_rtl.css
new file mode 100644
index 0000000..9abae68
--- /dev/null
+++ b/dojox/mobile/themes/android/ToolBarButton_rtl.css
@@ -0,0 +1,18 @@
+/* dojox.mobile.ToolBarButton Rtl */
+.mblHeading .mblToolBarButtonRtl {
+  float: right;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonIcon {
+  padding-right: 10px;
+  padding-left: 0px;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonLabel {
+  padding-left: 10px;
+  padding-right: 0px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: -1px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: -2px;
+}
diff --git a/dojox/mobile/themes/android/Tooltip-compat.css b/dojox/mobile/themes/android/Tooltip-compat.css
index 6fd514d..9415367 100644
--- a/dojox/mobile/themes/android/Tooltip-compat.css
+++ b/dojox/mobile/themes/android/Tooltip-compat.css
@@ -1,47 +1,40 @@
 /* dojox.mobile.Tooltip */
 .mblTooltip {
-	-moz-border-radius: 8px;
-	-o-border-radius: 8px;
-	-ms-border-radius: 8px;
-	border-radius: 8px;
-	background-image: none;
+  background-image: none;
 }
-.mblTooltipBefore .mblTooltipArrow {
-	*right: 0; /* IE 7 quirks */
-}
-.mblTooltipAbove .mblTooltipArrow {
-	*bottom: 0px; /* IE 7 quirks */
-}
-.mblTooltipBefore .mblTooltipInnerArrow {
-	*right: -1px; /* IE 7 quirks */
-}
-.mblTooltipAbove .mblTooltipInnerArrow {
-	*bottom: -1px;  /* IE 7 quirks */
-}
-.mblTooltipBefore .mblTooltipInnerArrow {
-	border-right-color: #8C8A8C;
-}
-.mblTooltipAfter .mblTooltipInnerArrow {
-	border-left-color: #8C8A8C;
-}
-.mblTooltipAbove .mblTooltipInnerArrow {
-	border-bottom-color: #8C8A8C;
-}
-.mblTooltipBelow .mblTooltipInnerArrow {
-	border-top-color: #8C8A8C;
-}
-.mblTooltip .mblHeading {
-	*padding: 0 9px 12px;
-	*border-top: 1px solid #8C8A8C;
-	*border-bottom: 1px solid #8C8A8C;
-	*width: auto;
-	*height: auto;
-	*overflow: visible;
-	*line-height: normal;
+.dj_ff3 .mblTooltip {
+  -moz-border-radius: 3px;
 }
 .dj_ie9 .mblTooltip .mblHeading {
-	width: auto;
-}
-.mblTooltip .mblHeading .mblToolBarButton {
-	*margin: auto 6px;
+  width: auto;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipArrow {
+  right: 0;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipArrow {
+  bottom: 0;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipInnerArrow {
+  right: -1px;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipInnerArrow {
+  bottom: -1px;
+}
+.dj_ie6 .mblTooltip .mblHeading,
+.dj_ie7 .mblTooltip .mblHeading {
+  padding: 0 9px 12px;
+  border-top: 1px solid #8c8a8c;
+  border-bottom: 1px solid #8c8a8c;
+  width: auto;
+  height: auto;
+  overflow: visible;
+  line-height: normal;
+}
+.dj_ie6 .mblTooltip .mblHeading .mblToolBarButton,
+.dj_ie7 .mblTooltip .mblHeading .mblToolBarButton {
+  margin: auto 6px;
 }
diff --git a/dojox/mobile/themes/android/Tooltip.css b/dojox/mobile/themes/android/Tooltip.css
index cc28997..2f82d6c 100644
--- a/dojox/mobile/themes/android/Tooltip.css
+++ b/dojox/mobile/themes/android/Tooltip.css
@@ -5,30 +5,33 @@
   display: block;
   margin: 0;
   padding: 5px;
-  border: #ADAAAD 1px solid;
-  background-color: #8C8A8C;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9e9c), to(#848284));
-  -webkit-border-radius: 3px;
+  border-width: 1px;
+  border-style: solid;
   opacity: .97;
+  border-color: #adaaad;
+  border-radius: 3px;
+  background-color: #8c8a8c;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9e9c), to(#848284));
+  background-image: linear-gradient(to bottom, #9c9e9c 0%, #848284 100%);
 }
 .mblTooltipBubble {
   overflow: visible;
   padding: 3px;
-  background-color: #FFC700;
+  background-color: #306ea1;
   background-image: none;
-  color: black;
+  color: white;
 }
 .mblTooltipBubble.mblTooltipAbove .mblTooltipInnerArrow {
-  border-bottom-color: #FFC700;
+  border-bottom-color: #306ea1;
 }
 .mblTooltipBubble.mblTooltipBelow .mblTooltipInnerArrow {
-  border-top-color: #FFC700;
+  border-top-color: #306ea1;
 }
 .mblTooltipBubble.mblTooltipAfter .mblTooltipInnerArrow {
-  border-left-color: #FFC700;
+  border-left-color: #306ea1;
 }
 .mblTooltipBubble.mblTooltipBefore .mblTooltipInnerArrow {
-  border-right-color: #FFC700;
+  border-right-color: #306ea1;
 }
 .mblTooltip.mblTooltipAfter {
   margin-left: -11px;
@@ -75,7 +78,7 @@
   top: 0;
   bottom: auto;
   border-left-width: 0;
-  border-right-color: #ADAAAD;
+  border-right-color: #adaaad;
 }
 .mblTooltipAfter .mblTooltipArrow {
   left: 1px;
@@ -83,7 +86,7 @@
   top: 0;
   bottom: auto;
   border-right-width: 0;
-  border-left-color: #ADAAAD;
+  border-left-color: #adaaad;
 }
 .mblTooltipAbove .mblTooltipArrow {
   top: auto;
@@ -91,7 +94,7 @@
   left: auto;
   right: auto;
   border-top-width: 0;
-  border-bottom-color: #ADAAAD;
+  border-bottom-color: #adaaad;
 }
 .mblTooltipBelow .mblTooltipArrow {
   top: 1px;
@@ -99,7 +102,7 @@
   left: auto;
   right: auto;
   border-bottom-width: 0;
-  border-top-color: #ADAAAD;
+  border-top-color: #adaaad;
 }
 .mblTooltipInnerArrow {
   position: absolute;
@@ -124,7 +127,7 @@
   bottom: 0;
   left: 0;
   border-top-width: 0;
-  border-bottom-color: #9C9E9C;
+  border-bottom-color: #9c9e9c;
 }
 .mblTooltipBelow .mblTooltipInnerArrow {
   top: 0;
@@ -132,9 +135,14 @@
   border-bottom-width: 0;
   border-top-color: #848284;
 }
-.mblTooltipHidden, .mblTooltipHidden * {
+.mblTooltipHidden,
+.mblTooltipHidden * {
   visibility: hidden !important;
 }
+.mblTooltipHidden {
+  top: -99999px !important;
+  left: -99999px !important;
+}
 .mblTooltip .mblHeading {
   padding-bottom: 3px;
   border-top: 1px solid transparent;
diff --git a/dojox/mobile/themes/android/Tooltip.less b/dojox/mobile/themes/android/Tooltip.less
deleted file mode 100644
index 60af6d1..0000000
--- a/dojox/mobile/themes/android/Tooltip.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Tooltip.less";
diff --git a/dojox/mobile/themes/android/ValuePicker-compat.css b/dojox/mobile/themes/android/ValuePicker-compat.css
new file mode 100644
index 0000000..1918b9f
--- /dev/null
+++ b/dojox/mobile/themes/android/ValuePicker-compat.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.ValuePicker */
+.mblValuePickerSlotButton {
+  background-image: url(compat/valuepicker-button-bg.png);
+}
+.mblValuePickerSlotButtonSelected {
+  background-color: #3578b1;
+}
+.mblValuePickerSlotInputArea {
+  background-color: #f7f7f7;
+}
+.dj_gecko .mblValuePickerSlotButton {
+  background-image: -moz-linear-gradient(top, #f7f7f7 0%, #d6d3d6 50%, #bdbebd 90%, #d6d7d6 100%);
+}
+.dj_gecko .mblValuePickerSlotButtonSelected {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_gecko .mblValuePickerSlotInputArea {
+  background-image: -moz-linear-gradient(top, #adaead 0%, #d6d7d6 10%, #f7f7f7 50%, #f7f3f7 90%, #e7e3e7 100%);
+}
diff --git a/dojox/mobile/themes/android/ValuePicker.css b/dojox/mobile/themes/android/ValuePicker.css
new file mode 100644
index 0000000..e86d6b7
--- /dev/null
+++ b/dojox/mobile/themes/android/ValuePicker.css
@@ -0,0 +1,57 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+/* dojox.mobile.ValuePicker */
+.mblValuePicker {
+  height: 126px;
+}
+/* dojox.mobile.ValuePickerSlot */
+.mblValuePicker > .mblValuePickerSlot {
+  float: left;
+  margin: 0 5px;
+}
+.mblValuePickerSlotButton {
+  position: relative;
+  height: 38px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7f7f7), to(#d6d7d6), color-stop(0.5, #d6d3d6), color-stop(0.9, #bdbebd));
+  background-image: linear-gradient(to bottom, #f7f7f7 0%, #d6d3d6 50%, #bdbebd 90%, #d6d7d6 100%);
+}
+.mblValuePickerSlotPlusButton {
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+}
+.mblValuePickerSlotMinusButton {
+  border-bottom-left-radius: 5px;
+  border-bottom-right-radius: 5px;
+}
+.mblValuePickerSlotButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.mblValuePickerSlotIcon {
+  top: 5px;
+  margin: 0 auto;
+}
+.mblValuePickerSlotInputArea {
+  position: relative;
+  height: 48px;
+  border-top: 1px solid #7b797b;
+  border-bottom: 1px solid #c6c3c6;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#adaead), to(#e7e3e7), color-stop(0.1, #d6d7d6), color-stop(0.5, #f7f7f7), color-stop(0.9, #f7f3f7));
+  background-image: linear-gradient(to bottom, #adaead 0%, #d6d7d6 10%, #f7f7f7 50%, #f7f3f7 90%, #e7e3e7 100%);
+}
+.mblValuePickerSlotInput {
+  display: block;
+  width: 90%;
+  height: 90%;
+  margin: 5% auto;
+  padding: 0;
+  text-align: center;
+  border-style: none;
+  background-color: transparent;
+  font-size: 28px;
+}
+/* dojox.mobile.ValuePickerTimePicker */
+.mblValuePickerTimePicker > .mblToolBarButton {
+  top: 45px;
+}
diff --git a/dojox/mobile/themes/android/ValuePicker.less b/dojox/mobile/themes/android/ValuePicker.less
new file mode 100644
index 0000000..1561b85
--- /dev/null
+++ b/dojox/mobile/themes/android/ValuePicker.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+
+ at import "variables.less";
+ at import "../common/ValuePicker.less";
diff --git a/dojox/mobile/themes/android/android-app-compat.css b/dojox/mobile/themes/android/android-app-compat.css
index 8a55bc6..08492f6 100755
--- a/dojox/mobile/themes/android/android-app-compat.css
+++ b/dojox/mobile/themes/android/android-app-compat.css
@@ -1,6 +1,10 @@
 /* mbl.widget.Heading */
 @import url("android-compat.css");
 
+.alertDialogBody { /* 1.8 */
+	-moz-border-radius: 10px;
+}
+
 .alertTitle {
 	background-image: url(compat/heading-bg.png);
 }
diff --git a/dojox/mobile/themes/android/android-app.css b/dojox/mobile/themes/android/android-app.css
index cb58fa3..e073a0f 100644
--- a/dojox/mobile/themes/android/android-app.css
+++ b/dojox/mobile/themes/android/android-app.css
@@ -8,9 +8,9 @@
 }
 
 .alertDialogBody {
-	border: 1px solid #ADAAAD;
-	-webkit-border-radius: 10px;
-	-moz-border-radius: 10px;
+	border: 1px solid #adaaad;
+	border-radius: 10px;
+	/* 1.8  removed */
 	background-color: white;
 	margin-left: 2px;
 	margin-right: 4px;
@@ -20,10 +20,10 @@
 	height: 42px;
 	margin: 0px;
 	padding: 0px;
-	background-color: #889BB3;
-	background: -webkit-gradient(linear, left top, left bottom, from(#B0BCCD), to(#6D84A2), color-stop(0.5, #889BB3), color-stop(0.5, #8195AF));
-	border-top: 1px solid #CDD5DF;
-	border-bottom: 1px solid #2D3642;
+	background-color: #889bb3;
+	background: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), to(#6d84a2), color-stop(0.5, #889bb3), color-stop(0.5, #8195af));
+	border-top: 1px solid #cdd5df;
+	border-bottom: 1px solid #2d3642;
 	font-family: Helvetica;
 	font-size: 20px;
 	color: white;
@@ -154,7 +154,7 @@
 
 .listSelector {
 	position: absolute;
-	-webkit-border-radius: 10px;
+	border-radius: 10px;
 	-moz-border-radius: 10px;
 	border: 1px solid #666;
 	background-color: #ccc;
@@ -257,7 +257,7 @@ input {
 	overflow: hidden;
 	position: absolute;
 	-webkit-background-size: 100% 100%;
-	-webkit-border-radius: 5px;
+	border-radius: 5px;
 	width: 90px;
 	height: 90px;
 	z-index: 5;
@@ -341,9 +341,9 @@ input {
 }
 
 /* Back Button */
-.mblNativeBack .mblArrowButtonHead,
-.mblNativeBack .mblArrowButtonBody,
-.mblNativeBack .mblArrowButtonNeck {
+.mblNativeBack .mblBackButtonHead, /* 1.8 */
+.mblNativeBack .mblBackButtonBody, /* 1.8 */
+.mblNativeBack .mblBackButtonNeck { /* 1.8 */
 	display: none;
 }
 
diff --git a/dojox/mobile/themes/android/android-compat.css b/dojox/mobile/themes/android/android-compat.css
index f5a0140..3d25bdd 100755
--- a/dojox/mobile/themes/android/android-compat.css
+++ b/dojox/mobile/themes/android/android-compat.css
@@ -2,17 +2,23 @@
 
 /* common styles */
 @import url("../common/domButtons-compat.css");
- at import url("../common/SpinWheel-compat.css");
 
 /* widget styles */
+ at import url("Accordion-compat.css");
 @import url("Button-compat.css");
 @import url("CheckBox-compat.css");
 @import url("ComboBox-compat.css");
 @import url("IconContainer-compat.css");
+ at import url("IconMenu-compat.css");
 @import url("Opener-compat.css");
+ at import url("PageIndicator-compat.css");
 @import url("RadioButton-compat.css");
+ at import url("SearchBox-compat.css");
+ at import url("SimpleDialog-compat.css");
 @import url("Slider-compat.css");
+ at import url("SpinWheel-compat.css");
 @import url("TabBar-compat.css");
 @import url("TextArea-compat.css");
 @import url("TextBox-compat.css");
 @import url("ToggleButton-compat.css");
+ at import url("ValuePicker-compat.css");
diff --git a/dojox/mobile/themes/android/android.css b/dojox/mobile/themes/android/android.css
index a50e0ce..0a3b95f 100755
--- a/dojox/mobile/themes/android/android.css
+++ b/dojox/mobile/themes/android/android.css
@@ -2,21 +2,29 @@
 
 /* common styles */
 @import url("../common/domButtons.css");
- at import url("../common/FixedSplitter.css");
- at import url("../common/SpinWheel.css");
 @import url("../common/transitions.css");
 
 /* widget styles */
+ at import url("Accordion.css");
 @import url("Button.css");
 @import url("Carousel.css");
 @import url("CheckBox.css");
 @import url("ComboBox.css");
+ at import url("FixedSplitter.css");
+ at import url("GridLayout.css");
 @import url("IconContainer.css");
+ at import url("IconMenu.css");
 @import url("Opener.css");
 @import url("PageIndicator.css");
+ at import url("ProgressBar.css");
 @import url("RadioButton.css");
+ at import url("ScrollablePane.css");
+ at import url("SearchBox.css");
+ at import url("SimpleDialog.css");
 @import url("Slider.css");
+ at import url("SpinWheel.css");
 @import url("TabBar.css");
 @import url("TextArea.css");
- at import url("TextBox.css");
 @import url("ToggleButton.css");
+ at import url("ValuePicker.css");
+ at import url("FormLayout.css");
diff --git a/dojox/mobile/themes/android/android_rtl-compat.css b/dojox/mobile/themes/android/android_rtl-compat.css
new file mode 100644
index 0000000..0143aa0
--- /dev/null
+++ b/dojox/mobile/themes/android/android_rtl-compat.css
@@ -0,0 +1,7 @@
+ at import url("base_rtl-compat.css");
+
+ at import url("IconMenu_rtl-compat.css");
+
+ at import url("SpinWheel_rtl-compat.css");
+
+ at import url("TabBar_rtl-compat.css");
diff --git a/dojox/mobile/themes/android/android_rtl.css b/dojox/mobile/themes/android/android_rtl.css
new file mode 100644
index 0000000..f61e915
--- /dev/null
+++ b/dojox/mobile/themes/android/android_rtl.css
@@ -0,0 +1,15 @@
+ at import url("base_rtl.css");
+
+ at import url("Carousel_rtl.css");
+
+ at import url("ComboBox_rtl.css");
+
+ at import url("IconContainer_rtl.css");
+
+ at import url("IconMenu_rtl.css");
+
+ at import url("SpinWheel_rtl.css");
+
+ at import url("TabBar_rtl.css");
+
+ at import url("ToggleButton_rtl.css");
diff --git a/dojox/mobile/themes/android/base-compat.css b/dojox/mobile/themes/android/base-compat.css
index d12cf2b..6689f7c 100644
--- a/dojox/mobile/themes/android/base-compat.css
+++ b/dojox/mobile/themes/android/base-compat.css
@@ -1,7 +1,8 @@
+ at import url("common-compat.css");
 @import url("Heading-compat.css");
+ at import url("ToolBarButton-compat.css");
 @import url("RoundRect-compat.css");
 @import url("RoundRectList-compat.css");
- at import url("EdgeToEdgeCategory-compat.css");
 @import url("ListItem-compat.css");
 @import url("Switch-compat.css");
 @import url("ProgressIndicator-compat.css");
diff --git a/dojox/mobile/themes/android/base_rtl-compat.css b/dojox/mobile/themes/android/base_rtl-compat.css
new file mode 100644
index 0000000..71390e0
--- /dev/null
+++ b/dojox/mobile/themes/android/base_rtl-compat.css
@@ -0,0 +1,3 @@
+ at import url("ListItem_rtl-compat.css");
+
+ at import url("Switch_rtl-compat.css");
diff --git a/dojox/mobile/themes/android/base_rtl.css b/dojox/mobile/themes/android/base_rtl.css
new file mode 100644
index 0000000..16f6b6c
--- /dev/null
+++ b/dojox/mobile/themes/android/base_rtl.css
@@ -0,0 +1,7 @@
+ at import url("ToolBarButton_rtl.css");
+
+ at import url("RoundRectCategory_rtl.css");
+
+ at import url("ListItem_rtl.css");
+
+ at import url("Switch_rtl.css");
diff --git a/dojox/mobile/themes/android/common-compat.css b/dojox/mobile/themes/android/common-compat.css
new file mode 100644
index 0000000..4f4c927
--- /dev/null
+++ b/dojox/mobile/themes/android/common-compat.css
@@ -0,0 +1,18 @@
+.dj_gecko .mblColorBlue {
+  background-image: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblColorBlue45 {
+  background-image: -moz-linear-gradient(top left, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblColorDefault {
+  background-image: -moz-linear-gradient(top, #dfdfdf 0%, #a6a6a6 100%);
+}
+.dj_gecko .mblColorDefault45 {
+  background-image: -moz-linear-gradient(top left, #dfdfdf 0%, #a6a6a6 100%);
+}
+.dj_gecko .mblColorDefaultSel {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_gecko .mblColorDefaultSel45 {
+  background-image: -moz-linear-gradient(top left, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
diff --git a/dojox/mobile/themes/android/common.css b/dojox/mobile/themes/android/common.css
index 7cf6b02..ec2b38f 100644
--- a/dojox/mobile/themes/android/common.css
+++ b/dojox/mobile/themes/android/common.css
@@ -1,27 +1,58 @@
-html.mobile, .mobile body {
+html.mobile,
+.mobile body {
   width: 100%;
-  margin: 0px;
-  padding: 0px;
+  margin: 0;
+  padding: 0;
 }
 .mobile body {
   overflow-x: hidden;
   -webkit-text-size-adjust: none;
-  background-color: black;
   font-family: Helvetica;
   font-size: 17px;
   color: white;
 }
+.mblBackground {
+  background-color: black;
+}
 /* Button Colors */
 .mblColorBlue {
-  background-color: #366EDF;
+  color: #ffffff;
+  background-color: #366edf;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.mblColorBlue45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to right bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
 }
 /* Default Button Colors */
 .mblColorDefault {
-  background-color: #ADADAD;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#e5e5e5), to(#7f7f7f), color-stop(0.5, #adadad), color-stop(0.5, #909090));
+  color: #000000;
+  background-color: #c6c6c6;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dfdfdf), to(#a6a6a6));
+  background-image: linear-gradient(to bottom, #dfdfdf 0%, #a6a6a6 100%);
+}
+.mblColorDefault45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#dfdfdf), to(#a6a6a6));
+  background-image: linear-gradient(to right bottom, #dfdfdf 0%, #a6a6a6 100%);
 }
 .mblColorDefaultSel {
-  background-color: #FFC700;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
+  color: #ffffff;
+  background-color: #3578b1;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.mblColorDefaultSel45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to right bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.mblSpriteIcon {
+  position: absolute;
+}
+.mblSpriteIconParent {
+  position: relative;
+  font-size: 1px;
+}
+.mblImageIcon {
+  vertical-align: top;
 }
diff --git a/dojox/mobile/themes/android/common.less b/dojox/mobile/themes/android/common.less
deleted file mode 100644
index 4e57a5c..0000000
--- a/dojox/mobile/themes/android/common.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/common.less";
diff --git a/dojox/mobile/themes/android/compat/arrow-button-bg-sel.png b/dojox/mobile/themes/android/compat/arrow-button-bg-sel.png
new file mode 100644
index 0000000..5b85b72
Binary files /dev/null and b/dojox/mobile/themes/android/compat/arrow-button-bg-sel.png differ
diff --git a/dojox/mobile/themes/android/compat/arrow-button-bg.png b/dojox/mobile/themes/android/compat/arrow-button-bg.png
index 7ac8061..7871ed1 100755
Binary files a/dojox/mobile/themes/android/compat/arrow-button-bg.png and b/dojox/mobile/themes/android/compat/arrow-button-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/arrow-button-head-sel.png b/dojox/mobile/themes/android/compat/arrow-button-head-sel.png
new file mode 100644
index 0000000..f10e271
Binary files /dev/null and b/dojox/mobile/themes/android/compat/arrow-button-head-sel.png differ
diff --git a/dojox/mobile/themes/android/compat/arrow-button-head.png b/dojox/mobile/themes/android/compat/arrow-button-head.png
index 74ecb76..ac78b9e 100755
Binary files a/dojox/mobile/themes/android/compat/arrow-button-head.png and b/dojox/mobile/themes/android/compat/arrow-button-head.png differ
diff --git a/dojox/mobile/themes/android/compat/arrow-button-right-head-sel.png b/dojox/mobile/themes/android/compat/arrow-button-right-head-sel.png
new file mode 100644
index 0000000..068c601
Binary files /dev/null and b/dojox/mobile/themes/android/compat/arrow-button-right-head-sel.png differ
diff --git a/dojox/mobile/themes/android/compat/arrow-button-right-head.png b/dojox/mobile/themes/android/compat/arrow-button-right-head.png
new file mode 100644
index 0000000..cc92700
Binary files /dev/null and b/dojox/mobile/themes/android/compat/arrow-button-right-head.png differ
diff --git a/dojox/mobile/themes/android/compat/blue-button-sel-bg.png b/dojox/mobile/themes/android/compat/blue-button-sel-bg.png
new file mode 100644
index 0000000..d371d89
Binary files /dev/null and b/dojox/mobile/themes/android/compat/blue-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/button-arrow-head-bg.gif b/dojox/mobile/themes/android/compat/button-arrow-head-bg.gif
new file mode 100644
index 0000000..77b6e9e
Binary files /dev/null and b/dojox/mobile/themes/android/compat/button-arrow-head-bg.gif differ
diff --git a/dojox/mobile/themes/android/compat/button-chk-bg.png b/dojox/mobile/themes/android/compat/button-chk-bg.png
new file mode 100644
index 0000000..4bfad06
Binary files /dev/null and b/dojox/mobile/themes/android/compat/button-chk-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/button-sel-bg.png b/dojox/mobile/themes/android/compat/button-sel-bg.png
index 75ff0f8..d371d89 100644
Binary files a/dojox/mobile/themes/android/compat/button-sel-bg.png and b/dojox/mobile/themes/android/compat/button-sel-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/button-unsel-bg.png b/dojox/mobile/themes/android/compat/button-unsel-bg.png
new file mode 100644
index 0000000..d371d89
Binary files /dev/null and b/dojox/mobile/themes/android/compat/button-unsel-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/red-button-sel-bg.png b/dojox/mobile/themes/android/compat/red-button-sel-bg.png
new file mode 100644
index 0000000..d371d89
Binary files /dev/null and b/dojox/mobile/themes/android/compat/red-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/switch-arc-l.gif b/dojox/mobile/themes/android/compat/switch-arc-l.gif
deleted file mode 100644
index 3f01809..0000000
Binary files a/dojox/mobile/themes/android/compat/switch-arc-l.gif and /dev/null differ
diff --git a/dojox/mobile/themes/android/compat/switch-arc-r.gif b/dojox/mobile/themes/android/compat/switch-arc-r.gif
deleted file mode 100644
index 3bb5901..0000000
Binary files a/dojox/mobile/themes/android/compat/switch-arc-r.gif and /dev/null differ
diff --git a/dojox/mobile/themes/android/compat/switch-arc1-k.gif b/dojox/mobile/themes/android/compat/switch-arc1-k.gif
index 3dec6bd..b706766 100644
Binary files a/dojox/mobile/themes/android/compat/switch-arc1-k.gif and b/dojox/mobile/themes/android/compat/switch-arc1-k.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-arc1-l.gif b/dojox/mobile/themes/android/compat/switch-arc1-l.gif
new file mode 100644
index 0000000..873b9a7
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-arc1-l.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-arc1-r.gif b/dojox/mobile/themes/android/compat/switch-arc1-r.gif
new file mode 100644
index 0000000..2e70891
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-arc1-r.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-arc2-k.gif b/dojox/mobile/themes/android/compat/switch-arc2-k.gif
index 638e76a..7c74289 100644
Binary files a/dojox/mobile/themes/android/compat/switch-arc2-k.gif and b/dojox/mobile/themes/android/compat/switch-arc2-k.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-arc2-l.gif b/dojox/mobile/themes/android/compat/switch-arc2-l.gif
new file mode 100644
index 0000000..b9e9ea6
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-arc2-l.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-arc2-r.gif b/dojox/mobile/themes/android/compat/switch-arc2-r.gif
new file mode 100644
index 0000000..d92e181
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-arc2-r.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-default-k.gif b/dojox/mobile/themes/android/compat/switch-default-k.gif
deleted file mode 100644
index 61aca0b..0000000
Binary files a/dojox/mobile/themes/android/compat/switch-default-k.gif and /dev/null differ
diff --git a/dojox/mobile/themes/android/compat/switch-default-l.gif b/dojox/mobile/themes/android/compat/switch-default-l.gif
deleted file mode 100644
index 9903c39..0000000
Binary files a/dojox/mobile/themes/android/compat/switch-default-l.gif and /dev/null differ
diff --git a/dojox/mobile/themes/android/compat/switch-default-r.gif b/dojox/mobile/themes/android/compat/switch-default-r.gif
deleted file mode 100644
index 5dbc4bc..0000000
Binary files a/dojox/mobile/themes/android/compat/switch-default-r.gif and /dev/null differ
diff --git a/dojox/mobile/themes/android/compat/switch-round-l.gif b/dojox/mobile/themes/android/compat/switch-round-l.gif
deleted file mode 100644
index 0a50568..0000000
Binary files a/dojox/mobile/themes/android/compat/switch-round-l.gif and /dev/null differ
diff --git a/dojox/mobile/themes/android/compat/switch-round-r.gif b/dojox/mobile/themes/android/compat/switch-round-r.gif
deleted file mode 100644
index 1cd3c95..0000000
Binary files a/dojox/mobile/themes/android/compat/switch-round-r.gif and /dev/null differ
diff --git a/dojox/mobile/themes/android/compat/switch-round1-k.gif b/dojox/mobile/themes/android/compat/switch-round1-k.gif
index 2b4a9da..1bc8a14 100644
Binary files a/dojox/mobile/themes/android/compat/switch-round1-k.gif and b/dojox/mobile/themes/android/compat/switch-round1-k.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-round1-l.gif b/dojox/mobile/themes/android/compat/switch-round1-l.gif
new file mode 100644
index 0000000..f015cc2
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-round1-l.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-round1-r.gif b/dojox/mobile/themes/android/compat/switch-round1-r.gif
new file mode 100644
index 0000000..f62342a
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-round1-r.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-round2-k.gif b/dojox/mobile/themes/android/compat/switch-round2-k.gif
index 08eb031..7885243 100644
Binary files a/dojox/mobile/themes/android/compat/switch-round2-k.gif and b/dojox/mobile/themes/android/compat/switch-round2-k.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-round2-l.gif b/dojox/mobile/themes/android/compat/switch-round2-l.gif
new file mode 100644
index 0000000..0417737
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-round2-l.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-round2-r.gif b/dojox/mobile/themes/android/compat/switch-round2-r.gif
new file mode 100644
index 0000000..2cf1260
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-round2-r.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-square-k.gif b/dojox/mobile/themes/android/compat/switch-square-k.gif
new file mode 100644
index 0000000..cdab63e
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-square-k.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-square-l.gif b/dojox/mobile/themes/android/compat/switch-square-l.gif
new file mode 100644
index 0000000..e32a3dd
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-square-l.gif differ
diff --git a/dojox/mobile/themes/android/compat/switch-square-r.gif b/dojox/mobile/themes/android/compat/switch-square-r.gif
new file mode 100644
index 0000000..0c67709
Binary files /dev/null and b/dojox/mobile/themes/android/compat/switch-square-r.gif differ
diff --git a/dojox/mobile/themes/android/compat/tab-seg-button-bg.png b/dojox/mobile/themes/android/compat/tab-seg-button-bg.png
new file mode 100644
index 0000000..7871ed1
Binary files /dev/null and b/dojox/mobile/themes/android/compat/tab-seg-button-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/tab-seg-sel-button-bg.png b/dojox/mobile/themes/android/compat/tab-seg-sel-button-bg.png
new file mode 100644
index 0000000..7afa879
Binary files /dev/null and b/dojox/mobile/themes/android/compat/tab-seg-sel-button-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/tab-slim-bar-bg.png b/dojox/mobile/themes/android/compat/tab-slim-bar-bg.png
new file mode 100644
index 0000000..f982afb
Binary files /dev/null and b/dojox/mobile/themes/android/compat/tab-slim-bar-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/tab-tall-bar-bg.png b/dojox/mobile/themes/android/compat/tab-tall-bar-bg.png
new file mode 100644
index 0000000..50a2371
Binary files /dev/null and b/dojox/mobile/themes/android/compat/tab-tall-bar-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/togglebutton-chk-mark-bg.png b/dojox/mobile/themes/android/compat/togglebutton-chk-mark-bg.png
new file mode 100644
index 0000000..2262424
Binary files /dev/null and b/dojox/mobile/themes/android/compat/togglebutton-chk-mark-bg.png differ
diff --git a/dojox/mobile/themes/android/compat/valuepicker-button-bg.png b/dojox/mobile/themes/android/compat/valuepicker-button-bg.png
new file mode 100644
index 0000000..965db4b
Binary files /dev/null and b/dojox/mobile/themes/android/compat/valuepicker-button-bg.png differ
diff --git a/dojox/mobile/themes/android/dijit/Calendar-compat.css b/dojox/mobile/themes/android/dijit/Calendar-compat.css
new file mode 100644
index 0000000..51668b1
--- /dev/null
+++ b/dojox/mobile/themes/android/dijit/Calendar-compat.css
@@ -0,0 +1,35 @@
+/* dijit.Calendar */
+.dijitCalendar thead {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-month-bg.png);
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-datelabel-sel-bg.png);
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-datelabel-act-bg.png);
+}
+.dijitCalendarYearLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-year-bg.png);
+}
+.dj_gecko .dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  -moz-box-shadow: 0 0 0 transparent;
+}
+.dj_gecko .dijitCalendar thead {
+  background-image: -moz-linear-gradient(top, #84868c 0%, #52555a 50%, #292929 50%, #000000 100%);
+}
+.dj_gecko .dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-image: -moz-linear-gradient(top, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
+}
+.dj_gecko .dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-image: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dj_gecko .dijitCalendarYearLabel {
+  background-image: -moz-linear-gradient(top, #84868c 0%, #52555a 50%, #292929 50%, #000000 100%);
+}
+.dj_ff3 .dijitCalendar {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/android/dijit/Calendar-compat.less b/dojox/mobile/themes/android/dijit/Calendar-compat.less
new file mode 100644
index 0000000..88cd6f0
--- /dev/null
+++ b/dojox/mobile/themes/android/dijit/Calendar-compat.less
@@ -0,0 +1,2 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar-compat.less";
diff --git a/dojox/mobile/themes/android/dijit/Calendar.css b/dojox/mobile/themes/android/dijit/Calendar.css
new file mode 100644
index 0000000..04e6b95
--- /dev/null
+++ b/dojox/mobile/themes/android/dijit/Calendar.css
@@ -0,0 +1,119 @@
+/* if you link this style sheet, dijit/themes/dijit.css must be imported. */
+/* dijit.Calendar */
+.dijitCalendar {
+  padding: 0;
+  width: 320px;
+  border-radius: 0;
+  text-align: center;
+  border: none 0 transparent;
+  background-color: white;
+}
+.dijitCalendar thead {
+  border-color: inherit;
+  vertical-align: middle;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#84868c), to(#000000), color-stop(0.5, #52555a), color-stop(0.5, #292929));
+  background-image: linear-gradient(to bottom, #84868c 0%, #52555a 50%, #292929 50%, #000000 100%);
+}
+.dijitCalendarMonthLabel {
+  padding: 0 4px;
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0 1px 0px;
+  color: white;
+  font-size: 16px;
+}
+.dijitCalendarMonthMenu .dijitCalendarMonthLabel {
+  color: black;
+}
+.dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  padding: 0 3px 0 2px;
+  border: none;
+  background-color: transparent;
+  background-image: none;
+  -webkit-box-shadow: 0 0 0 transparent;
+  box-shadow: 0 0 0 transparent;
+}
+.dijitArrowButtonInner {
+  display: none;
+}
+.dijitCalendarMonthContainer th {
+  border-right: 1px solid transparent;
+}
+.dijitCalendarIncrementControl {
+  width: 0;
+  height: 0;
+  border: 6px solid transparent !important;
+}
+.dijitCalendarDecrease {
+  border-left-width: 0 !important;
+  border-right: 6px solid white !important;
+}
+.dijitCalendarIncrease {
+  border-right-width: 0 !important;
+  border-left: 6px solid white !important;
+}
+.dijitA11ySideArrow {
+  display: none;
+}
+.dijitCalendarDayLabelTemplate {
+  border-right: 1px solid transparent;
+  text-align: center;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  background-color: #292c31;
+  font-size: 12px;
+  color: white;
+}
+.dijitCalendarDateTemplate {
+  border-bottom: 1px solid lightGrey;
+  font-family: Helvetica;
+  font-size: 22px;
+  font-weight: normal;
+  text-align: center;
+  border-right: 1px solid lightGrey;
+  background-color: white;
+  color: black;
+}
+.dijitCalendarDateTemplate:last-child {
+  border-right: none;
+}
+.dijitCalendarDateTemplate .dijitCalendarDateLabel {
+  padding: 3px 5px 3px 4px;
+  display: block;
+  text-decoration: none;
+  border: none;
+}
+.dijitCalendarPreviousMonth .dijitCalendarDateLabel,
+.dijitCalendarNextMonth .dijitCalendarDateLabel {
+  color: lightGrey;
+}
+.dijitCalendarHoveredDate .dijitCalendarDateLabel {
+  color: grey;
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#00a200), to(#00d300), color-stop(0.2, #00ba00), color-stop(0.2, #00ba00));
+  background-image: linear-gradient(to bottom, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
+  color: white;
+  text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0;
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#306ea1), to(#266093), color-stop(0.06, #4090d3), color-stop(0.5, #306ea1));
+  background-image: linear-gradient(to bottom, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+}
+.dijitCalendarYearLabel {
+  margin: 0;
+  padding: 0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#84868c), to(#000000), color-stop(0.5, #52555a), color-stop(0.5, #292929));
+  background-image: linear-gradient(to bottom, #84868c 0%, #52555a 50%, #292929 50%, #000000 100%);
+}
+.dijitCalendarSelectedYear {
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  color: white;
+  font-size: 16px;
+}
+.dijitCalendarNextYear,
+.dijitCalendarPreviousYear {
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  padding: 1px 6px 3px 6px;
+  color: white;
+  font-size: 12px;
+}
diff --git a/dojox/mobile/themes/android/dijit/Calendar.less b/dojox/mobile/themes/android/dijit/Calendar.less
new file mode 100644
index 0000000..a590903
--- /dev/null
+++ b/dojox/mobile/themes/android/dijit/Calendar.less
@@ -0,0 +1,2 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar.less";
diff --git a/dojox/mobile/themes/android/dijit/compat/calendar-datelabel-act-bg.png b/dojox/mobile/themes/android/dijit/compat/calendar-datelabel-act-bg.png
new file mode 100644
index 0000000..688b46c
Binary files /dev/null and b/dojox/mobile/themes/android/dijit/compat/calendar-datelabel-act-bg.png differ
diff --git a/dojox/mobile/themes/android/dijit/compat/calendar-datelabel-sel-bg.png b/dojox/mobile/themes/android/dijit/compat/calendar-datelabel-sel-bg.png
new file mode 100644
index 0000000..bd89c1d
Binary files /dev/null and b/dojox/mobile/themes/android/dijit/compat/calendar-datelabel-sel-bg.png differ
diff --git a/dojox/mobile/themes/android/dijit/compat/calendar-month-bg.png b/dojox/mobile/themes/android/dijit/compat/calendar-month-bg.png
new file mode 100644
index 0000000..cfc5a64
Binary files /dev/null and b/dojox/mobile/themes/android/dijit/compat/calendar-month-bg.png differ
diff --git a/dojox/mobile/themes/android/dijit/compat/calendar-year-bg.png b/dojox/mobile/themes/android/dijit/compat/calendar-year-bg.png
new file mode 100644
index 0000000..3e27901
Binary files /dev/null and b/dojox/mobile/themes/android/dijit/compat/calendar-year-bg.png differ
diff --git a/dojox/mobile/themes/android/variables.less b/dojox/mobile/themes/android/variables.less
index c7ffdfb..9d8062f 100644
--- a/dojox/mobile/themes/android/variables.less
+++ b/dojox/mobile/themes/android/variables.less
@@ -1,172 +1,178 @@
+ at import "../common/css3.less";
+
+ at default-blue-button-color: white;
+ at default-blue-button-background-color: #366edf;
+.default-blue-button-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#7a9de9, #2362dd, 0.5, #366edf, 0.5, #215fdc); }
+ at default-blue-button-background-image-gecko: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+
+.mbl-color-blue-45 () { .background-image-linear-gradient-top-left-bottom-right-2-stops(#7a9de9, #2362dd, 0.5, #366edf, 0.5, #215fdc); }
+.mbl-color-default-45 () { .background-image-linear-gradient-top-left-bottom-right(#dfdfdf, #a6a6a6); }
+.mbl-color-default-sel-45 () { .background-image-linear-gradient-top-left-bottom-right-2-stops(#306ea1, #266093, 0.06, #4090d3, 0.5, #306ea1); }
+
+ at mbl-color-blue-45-gecko: -moz-linear-gradient(top left, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+ at mbl-color-default-45-gecko: -moz-linear-gradient(top left, #dfdfdf 0%, #a6a6a6 100%);
+ at mbl-color-default-sel-45-gecko: -moz-linear-gradient(top left, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+
+ at default-button-color: black;
+ at default-button-background-color: #c6c6c6;
+.default-button-background-image () { .background-image-linear-gradient-top-bottom(#dfdfdf, #a6a6a6); }
+ at default-button-background-image-gecko: -moz-linear-gradient(top, #dfdfdf 0%, #a6a6a6 100%);
+ at default-button-border-radius: 3px;
+
+ at default-button-selected-color: white;
+ at default-button-selected-background-color: #3578b1;
+.default-button-selected-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#306ea1, #266093, 0.06, #4090d3, 0.5, #306ea1); }
+ at default-button-selected-background-image-gecko: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+
+ at default-selected-color: white;
+ at default-selected-background-color: #3578b1;
+.default-selected-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#306ea1, #266093, 0.06, #4090d3, 0.5, #306ea1); }
+ at default-selected-background-image-gecko: -moz-linear-gradient(top, #306ea1 0%, #4090d3 6%, #306ea1 50%, #266093 100%);
+
+ at heading-background-color: #8c8a8c;
+.heading-background-image () { .background-image-linear-gradient-top-bottom(#9c9e9c, #848284); }
+ at heading-background-image-gecko: -moz-linear-gradient(top, #9c9e9c 0%, #848284 100%);
+ at heading-border-top-color: #cdd5df;
+ at heading-border-bottom-color: #2d3642;
+
+.default-button-border-styles () {
+	border-color: #9cacc0;
+	border-radius: @default-button-border-radius;
+}
+
+.mblToolBarButtonBodyInLeftArrow-styles () {
+  border-left-width: 0;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+.mblToolBarButtonBodyInRightArrow-styles () {
+  border-right-width: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+// background styles of form controls
+.mbl-button-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#fdfdfd, #cecece, 0.5, #f8f8f8, 0.5, #eeeeee); }
+.mbl-button-selected-background-image () { .default-button-selected-background-image(); }
+.mbl-blue-button-background-image () { .default-blue-button-background-image(); }
+.mbl-blue-button-selected-background-image () { .default-button-selected-background-image(); }
+.mbl-red-button-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#fa9d58, #ee4115, 0.5, #ff4d25, 0.5, #ed4d15); }
+.mbl-red-button-selected-background-image () { .default-button-selected-background-image(); }
+.mbl-button-checked-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#00a200, #00d300, 0.2, #00ba00, 0.2, #00ba00); }
+
+// background styles of form controls (for gecko)
+ at mbl-button-background-image-gecko: -moz-linear-gradient(top, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+ at mbl-button-selected-background-image-gecko: @default-button-selected-background-image-gecko;
+ at mbl-blue-button-background-image-gecko: @default-blue-button-background-image-gecko;
+ at mbl-blue-button-selected-background-image-gecko: @default-button-selected-background-image-gecko;
+ at mbl-red-button-background-image-gecko: -moz-linear-gradient(top, #fa9d58 0%, #ff4d25 50%, #ed4d15 50%, #ee4115 100%);
+ at mbl-red-button-selected-background-image-gecko: @default-button-selected-background-image-gecko;
+ at mbl-button-checked-background-image-gecko: -moz-linear-gradient(top, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
+
 // common.less
 .mobile-body-styles () {
-	background-color: black;
 	font-family: Helvetica;
 	font-size: 17px;
 	color: white;
 }
 
+.mblBackground-styles () {
+	background-color: black;
+}
+
 .mblView-styles () {
 	color: white;
 }
 
 .mblColorBlue-styles () {
-	background-color: #366EDF;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7A9DE9), to(#2362DD), color-stop(0.5, #366EDF), color-stop(0.5, #215FDC));
+	color: @default-blue-button-color;
+	background-color: @default-blue-button-background-color;
+	.default-blue-button-background-image();
 }
 .mblColorDefault-styles () {
-	background-color: #ADADAD;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#E5E5E5), to(#7F7F7F), color-stop(0.5, #ADADAD), color-stop(0.5, #909090));
+	color: @default-button-color;
+	background-color: @default-button-background-color;
+	.default-button-background-image();
 }
 .mblColorDefaultSel-styles () {
-	background-color: #FFC700;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
+	color: @default-button-selected-color;
+	background-color: @default-button-selected-background-color;
+	.default-button-selected-background-image();
 }
 
 // Heading.less
 .mblHeading-styles () {
-	padding: 0px 0px 0px 4px;
-	height: 25px;
-	background-color: #8C8A8C;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#9C9E9C), to(#848284));
-	border-top: 1px solid #CDD5DF;
-	border-bottom: 1px solid #2D3642;
+	.heading-background-image();
+	border-top: 1px solid @heading-border-top-color;
+	border-bottom: 1px solid @heading-border-bottom-color;
 	color: white;
-	font-family: Helvetica;
-	font-size: 14px;
-	font-weight: bold;
-	text-align: center;
-	line-height: 26px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
-}
-.mblArrowButton-styles () {
-	height: 25px;
-	margin-right: 10px;
-}
-.mblArrowButtonHead-styles () {
-	top: 4px;
-	left: 6px;
-	width: 14px;
-	height: 14px;
-	border: 1px solid #555555;
-	-webkit-transform: scale(.8,1) rotate(45deg);
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#E5E5E5), to(#7F7F7F), color-stop(0.5, #ADADAD), color-stop(0.5, #909090));
+	text-shadow: rgba(0,0,0,0.6) 0 -1px 0;
 }
-.mblArrowButtonHeadChrome-styles () {
-	border: 1px outset #555555;
+
+// ToolBarButton.less
+ at mbl-tool-bar-button-body-border-radius: 0;
+//
+.mblToolBarButton-styles () {
+	text-shadow: none;
 }
-.mblArrowButtonBody-styles () {
-	top: 0px;
-	left: 14px;
-	padding: 0px 10px 0px 3px;
-	height: 22px;
-	border-width: 1px 1px 1px 0px;
-	border-style: solid;
-	border-color: #555555;
-	font-family: Helvetica;
-	font-size: 13px;
-	color: white;
-	line-height: 23px;
-	background-color: #ADADAD;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#E5E5E5), to(#7F7F7F), color-stop(0.5, #ADADAD), color-stop(0.5, #909090));
+.mblToolBarButtonArrow-styles () {
+	border-radius: 1px;
+  .transform(scale(0.7, 1.05) rotate(45deg));
+	border: 1px solid #3a4655;
 }
-.mblArrowButtonSelected-styles () {
-	background-color: #FFC700;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
+.mblToolBarButtonArrowInHeading-styles () {
 }
-.mblArrowButtonHeadSelected-styles () {
+.mblToolBarButtonHasLeftArrowInHeading-styles () {
 }
-.mblArrowButtonBodySelected-styles () {
+.mblToolBarButtonHasLeftArrowInHeading-compat-gecko () {
 }
-
-// ToolBarButton.less
-.mblToolBarButton-styles () {
-	margin: 0px 6px;
-	height: 22px;
+.mblToolBarButtonHasRightArrowInHeading-styles () {
+}
+.mblToolBarButtonHasRightArrowInHeading-compat-gecko () {
+}
+.mblToolBarButtonArrowInLeftArrow-styles () {
+  left: -1px;
+}
+.mblToolBarButtonArrowInRightArrow-styles () {
+  right: -1px;
+}
+.mblToolBarButtonBody-styles () {
 	border: 1px solid #555555;
-	font-family: Helvetica;
-	font-size: 13px;
-	font-weight: bold;
-	color: white;
-	line-height: 23px;
-	text-align: center;
 }
-.mblToolBarButtonDomButton-styles () {
-	height: 23px;
+.mblToolBarButtonBodyInHeading-styles () {
 }
-.mblToolBarButtonIcon-styles () {
-	top: -2px;
-	padding: 0px;
+.mblToolBarButtonBodyInHeading-compat-gecko () {
 }
 
-// RoundRect.less
+// RoundRect.less & RoundRectList.less
+ at mbl-round-rect-border-color: #adaaad;
+ at mbl-round-rect-border-radius: 8px;
+ at mbl-round-rect-background-color: black;
+ at mbl-round-rect-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+//
 .mblRoundRect-styles () {
-	margin: 7px 9px 16px;
-	padding: 8px;
-	border: 1px solid #ADAAAD;
-	-webkit-border-radius: 8px;
-	-moz-border-radius: 8px;
 	color: white;
-	background-color: black;
-}
-.mblRoundRectShadowBox-styles () {
-	-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
 }
 
 // EdgeToEdgeCategory.less
 .mblEdgeToEdgeCategory-styles () {
-	margin: 0px;
-	padding: 0px 10px;
 	height: 22px;
 	border-bottom: 1px solid #393439;
 	background-color: #212021;
-	font-family: Helvetica;
-	font-size: 16px;
-	font-weight: bold;
 	color: white;
 	line-height: 22px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
+	text-shadow: rgba(0,0,0,0.6) 0 -1px 0;
 }
 
 // RoundRectCategory.less
+ at mbl-value-picker-slot-margin: 0 5px;
 .mblRoundRectCategory-styles () {
-	margin: 18px 0px 0px 20px;
-	font-family: Helvetica;
-	font-size: 16px;
 	color: white;
 }
 
-// RoundRectList.less
-.mblRoundRectList-styles () {
-	margin: 7px 9px 16px;
-	padding: 0px;
-	border: 1px solid #ADAAAD;
-	-webkit-border-radius: 8px;
-	-moz-border-radius: 8px;
-	background-color: white;
-}
-.mblRoundRectList-withCategory-styles () {
-}	
-.mblRoundRectList-FirstListItem-styles () {
-	-webkit-border-top-left-radius: 8px;
-	-webkit-border-top-right-radius: 8px;
-	-moz-border-radius-topleft: 8px;
-	-moz-border-radius-topright: 8px;
-}
-.mblRoundRectList-withCategory-FirstListItem-styles () {
-}
-.mblRoundRectList-LastListItem-styles () {
-	border-bottom-width: 0px;
-	-webkit-border-bottom-left-radius: 8px;
-	-webkit-border-bottom-right-radius: 8px;
-	-moz-border-radius-bottomleft: 8px;
-	-moz-border-radius-bottomright: 8px;
-}
-
 // EdgeToEdgeList.less
 .mblEdgeToEdgeList-styles () {
-	margin: 0px;
-	padding: 0px;
 	background-color: black;
 }
 .mblEdgeToEdgeList-LastListItem-styles () {
@@ -174,60 +180,26 @@
 }
 
 // ListItem.less
+ at mbl-list-item-height: 64px;
+//
 .mblListItem-styles () {
-	padding: 0px 0px 0px 7px;
-	height: 64px;
-	border-bottom: solid 1px #313431;
+	border-bottom: 1px solid #313431;
 	background-color: black;
 	font-size: 21px;
 	color: white;
-	line-height: 64px;
-}
-.mblListItem-mblVariableHeight-styles () {
-	padding: 11px 0px 10px 6px;
-	line-height: normal;
-}
-.mblListItem-mblListItemAnchor-styles () {
-	background-position: 14px 17px;
-	text-decoration: none;
-	padding-right: 7px;
-}
-.mblItemSelected-styles () {
-	background-color: #FFC700;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
 }
-.mblItemSelected-mblListItemAnchor-styles () {
-	color: black;
-}
-.mblItemSelected-mblDomButton-Div-styles () {
-	border-color: white;
+.mblListItemSelected-styles () {
+	color: @default-selected-color;
+	.default-selected-background-image();
 }
-.mblItemSelected-mblListItemSubText-styles () {
-}
-.mblListItemTextBoxSelected-styles () {
-	background-color: #048BF4;
+.mblListItemLabelSelected-styles () {
+	background-color: #048bf4;
 }
 .mblListItemChecked-styles () {
 }
-.mblListItemIcon-styles () {
-	margin-top: 17px;
-	margin-right: 11px;
-}
-.mblListItemSpriteIcon-styles () {
-	margin-top: 7px;
-	margin-left: 8px;
-}
-.mblListItemRightIcon-styles () {
-	margin-top: 17px;
-	margin-bottom: -17px;
-}
 .mblListItemRightText-styles () {
 	color: white;
-	margin: 20px 4px 0 0;
-}
-.mblListItemTextBox-styles () {
-}
-.mblListItemAnchorNoIcon-mblListItemTextBox-styles () {
+	margin-top: 20px;
 }
 .mblListItemSubText-styles () {
 	font-size: 14px;
@@ -235,428 +207,221 @@
 }
 
 // Switch.less
-.mblItemSwitch-styles () {
-	top: 18px;
-}
+ at mbl-switch-bg-left-background-color: #00a200;
+.mbl-switch-bg-left-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#00a200, #00d300, 0.2, #00ba00, 0.2, #00ba00); }
+ at mbl-switch-bg-right-background-color: #bdbebd;
+.mbl-switch-bg-right-background-image () { .background-image-linear-gradient-top-bottom(#bdbebd, #f7f3f7); }
+.mbl-switch-knob-background-image () { .background-image-linear-gradient-top-bottom(#9c9a9c, #848284); }
+//
+ at mbl-switch-bg-left-background-image-gecko: -moz-linear-gradient(top, #00a200 0%, #00ba00 20%, #00ba00 20%, #00d300 100%);
+ at mbl-switch-bg-right-background-image-gecko: -moz-linear-gradient(top, #bdbebd 0%, #f7f3f7 100%);
+ at mbl-switch-knob-background-image-gecko: -moz-linear-gradient(top, #9c9a9c 0%, #848284 100%);
+ at mbl-switch-square-border-radius: 2px;
+//
 .mblSwitchBg-styles () {
-	-webkit-border-radius: 2px;
-}
-.mblSwitchBgLeft-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#00A200), to(#00D300), color-stop(0.2, #00BA00), color-stop(0.2, #00BA00));
-}
-.mblSwitchBgRight-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#BDBEBD), to(#F7F3F7));
+	border: rgba(176,176,176,0.5) 1px inset;
 }
 .mblSwitchKnob-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#9C9A9C), to(#848284));
-	-webkit-border-radius: 2px;
+	border: rgba(157,157,157,0.5) 1px outset;
 }
 
 // Button.less
 .mblButton-styles () {
-	padding: 0px 10px;
-	height: 29px;
-	border: #9CACC0 1px outset;
-	-webkit-border-radius: 3px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FDFDFD), to(#CECECE), color-stop(0.5, #F8F8F8), color-stop(0.5, #EEEEEE));
+	.default-button-border-styles;
 	color: black;
-	font-family: Helvetica;
 	font-size: 13px;
-	line-height: 29px;
 }
-.mblButton-mblBlueButton-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7A9DE9), to(#2362DD), color-stop(0.5, #366EDF), color-stop(0.5, #215FDC));
+.mblButtonSelected-styles () {
 	color: white;
 }
-.mblButton-mblBlueButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
+.mblButton-mblBlueButton-styles () {
 	color: white;
 }
 .mblButton-mblRedButton-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FA9D58), to(#EE4115), color-stop(0.5, #FF4D25), color-stop(0.5, #ED4D15));
-	color: white;
-}
-.mblButton-mblRedButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
 	color: white;
 }
-.mblButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
-	color: white;
-}
-.mblButtonDisabled-styles () {
-	border-color: grey;
-	background-image: none;
-	color: grey;
-}
 
 // CheckBox.less
 .mblCheckBox-styles () {
-	margin: -0.5em 3px 0.3em 4px;
-	width: 1em;
-	height: 1em;
-	border: #9CACC0 1px outset;
-	-webkit-border-radius: 3px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FDFDFD), to(#CECECE), color-stop(0.5, #F8F8F8), color-stop(0.5, #EEEEEE));
-	font: inherit;
-	-webkit-transform: translateY(0.45em);
-}
-.mblCheckBoxSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
-	border-color: #9CACC0;
-}
-.mblCheckBoxChecked-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#00A200), to(#00D300), color-stop(0.2, #00BA00), color-stop(0.2, #00BA00));
+	.default-button-border-styles;
 }
 .mblCheckBoxChecked-after-styles () {
-	position: absolute;
-	content: "";
-	width: 0.3em;
-	height: 0.6em;
-	top: 0;
-	left: 0.3em;
 	border-color: white;
-	border-width: 0.15em;
-	border-style: none solid solid none;
-	-webkit-transform: rotate(45deg);
-	-webkit-transform-origin: 50% 50%;
-}
-.mblCheckBoxChecked-mblCheckBoxSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
-	border-color: #9CACC0;
 }
 .mblCheckBoxChecked-mblCheckBoxSelected-after-styles () {
-	border-color: #9CACC0;
 }
 
 // ComboBox.less
+ at mbl-combo-box-popup-box-shadow: 0 0 50px black;
+//
 .dijitPopup-styles () {
-	-webkit-box-shadow: 0px 0px 50px black;
-	-webkit-border-radius: 0px;
+	border-radius: 0;
 }
 .mblComboBoxMenu-styles () {
-	border: 1px solid black;
-	-webkit-border-radius: 0px;
+	border-radius: 0;
 	background-color: white;
 	color: black;
 }
-.mblComboBoxMenuItemSelected-styles () {
-	background-color: black;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#048BF4), to(#005CE5));
-	color: white;
-}
 .mblComboBoxMenuItem-styles () {
-	padding: .1em .2em;
-	border-width: 1px 0 1px 0;
-	border-style: solid;
 	border-color: #ffffff;
 	color: inherit;
-	text-align: left;
 }
-.mblComboBoxMenuPreviousButton-styles () {
-	font-style: italic;
-	overflow: hidden;
+.mblComboBoxMenuItemSelected-styles () {
+	.default-selected-background-image();
+	color: white;
 }
 
 // IconContainer.less
-.mblIconContainer-styles () {
-	margin: 20px 0px 0px 10px;
-	padding: 0px 0px 40px 0px;
-}
-
-// IconItem.less
-.mblIconItemTerminator-styles () {
-	height: 20px;
-}
 .mblIconItemSub-styles () {
-	margin-left: -10px;
 	background-color: white;
 	color: black;
 }
 .mblIconArea-styles () {
-	margin-bottom: 10px;
-	height: 78px;
+	margin-top: 5px;
+	margin-bottom: 5px;
 	width: 74px;
-	font-family: Helvetica;
-	font-size: 12px;
-	color: white;
-	text-align: center;
-}
-.mblContent-styles () {
-	padding-bottom: 20px;
-}
-.mblIconContentHeading-styles () {
-	margin-top: 0px;
-	padding-left: 40px;
-	height: 25px;
-	border-top: 1px solid #F1F3F4;
-	border-bottom: 1px solid #717D85;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#E0E4E7), to(#B4BEC6), color-stop(0.5, #C4CCD2), color-stop(0.5, #BFC8CE));
-	font-family: Helvetica;
-	font-size: 14px;
 	color: white;
-	line-height: 26px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
+}
+.mblIconItemDeleteIcon-styles () {
+	top: -4px;
+	left: -2px;
 }
 
 // RadioButton.less
 .mblRadioButton-styles () {
-	margin: -0.5em 3px 0.3em 4px;
-	width: 1em;
-	height: 1em;
-	border: #9CACC0 1px outset;
-	-webkit-border-radius: 0.5em;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FDFDFD), to(#CECECE), color-stop(0.5, #F8F8F8), color-stop(0.5, #EEEEEE));
-	font: inherit;
-	-webkit-transform: translateY(0.45em);
-}
-.mblRadioButtonChecked-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#00A200), to(#00D300), color-stop(0.2, #00BA00), color-stop(0.2, #00BA00));
+	border-color: #9cacc0;
 }
 .mblRadioButtonChecked-after-styles () {
-	content: "";
-	width: 0.3em;
-	height: 0.6em;
-	top: 0;
-	left: 0.25em;
-	border-color: white;
-	border-width: 0.15em;
-	border-style: none solid solid none;
 	border-color: white;
-	-webkit-transform: rotate(45deg);
-	-webkit-transform-origin: 50% 50%;
-}
-.mblRadioButtonChecked-Selected-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
 }
 .mblRadioButtonChecked-Selected-after-styles () {
 	border-color: white;
 }
 
 // Slider.less
+ at mbl-slider-bar-border-radius: 2px;
+ at mbl-slider-knob-border-radius: 2px;
+//
 .mblSlider-styles () {
-	margin: 15px; /* 1/2 handle width for hanging off the ends of the bar */
-	border: #B0B0B0 1px inset;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#BDBEBD), to(#F7F3F7));
-	-webkit-border-radius: 2px;
-}
-.mblSliderProgressBar-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#00A200), to(#00D300), color-stop(0.2, #00BA00), color-stop(0.2, #00BA00));
-	-webkit-border-radius: 2px;
+	border-color: #b0b0b0;
 }
 .mblSliderHandle-styles () {
-	margin: -10px 0 0 -10px;
-	width: 18px;
-	height: 18px;
-	border: #9D9D9D 1px outset;
-	-webkit-border-radius: 2px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#9C9A9C), to(#848284));
+	border-color: #9d9d9d;
 }
 
 // TabBar.less
 .mblTabBar-styles () {
-	margin: 0px;
-	padding: 0px;
-	height: 48px;
-	border-top: 1px solid #000000;
+	text-shadow: none;
+}
+
+// barType="tabBar"
+.mblTabBarTabBar-styles () {
+	.background-image-linear-gradient-top-bottom(#2d2d2d, #000000);
+}
+.mblTabBarTabBar-compat () {
 	background-color: #000000;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#2D2D2D), to(#000000));
-	color: white;
-	text-align: center;
 }
-.mblTabBar-TabBarButton-styles () {
+.mblTabBarTabBarButton-styles () {
+}
+.mblTabBarTabBarButtonIconArea-styles () {
+}
+.mblTabBarTabBarButtonLabel-styles () {
+	color: white;
 }
-.mblTabBar-TabBarButton-Selected-styles () {
-	-webkit-border-radius: 3px;
+.mblTabBarTabBarButtonSelected-styles () {
 	background-color: #404040;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424));
-}
-.mblTabBarButtonDiv-styles () {
-	width: 29px;
-	height: 32px;
-	margin-top: 2px;
-}
-.mblTabBarButtonIcon-styles () {
-	left: 0px;
-	top: 0px;
-}
-.mblTabBarButtonTextBox-styles () {
-	font-family: "Helvetica Neue", Helvetica;
-	font-size: 11px;
-}
-.mblTabBarNoIcons-TabBarButtonTextBox-styles () {
-	line-height: 34px;
-	font-size: 20px;
-}
-.mblTabButton-styles () {
-	margin-right: 2px;
-	width: 78px;
-	height: 61px;
-	border-width: 0px 1px 0px 1px;
-	border-style: solid;
-	border-color: black #182018 black #393C39;
-	background-color: #212421;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100C10), color-stop(0.1, #313031));
-	font-family: Helvetica;
-	font-size: 13px;
+	.background-image-linear-gradient-top-bottom(#484848, #242424);
+}
+.mblTabBarTabBarButtonLabelSelected-styles () {
 	color: white;
-	text-align: center;
 }
-.mblTabButton-TabBarButtonAnchor-styles () {
+
+// barType="segmentedControl"
+ at mbl-tab-bar-segmented-control-border-radius: 5px;
+//
+.mblTabBarSegmentedControl-styles () {
 }
-.mblTabBarTop-TabButton-TabBarButtonDiv-styles () {
-	height: 38px;
+.mblTabBarSegmentedControlButton-styles () {
+	border-style: solid;
+	border-color: #555555;
+	color: @default-button-color;
+	.default-button-background-image();
 }
-.mblTabBarHead-TabButton-TabBarButtonDiv-styles () {
-	margin-top: -2px;
+.mblTabBarSegmentedControlButton-compat-gecko () {
 }
-.mblTabButton-FirstTabButtom-styles () {
+.mblTabBarSegmentedControlButtonSelected-styles () {
+	color: @default-button-selected-color;
+	.background-image-linear-gradient-top-bottom-2-stops(#313031, #959595, 0.5, #5a555a, 0.5, #616161);
 }
-.mblTabButton-LastTabButton-styles () {
+
+// barType="standardTab"
+.mblTabBarStandardTab-styles () {
 }
-.mblTabButton-img-styles () {
-	position: absolute;
-	left: 0px;
-	margin-top: 8px;
+.mblTabBarStandardTabButton-styles () {
+	color: @default-button-color;
+	background-color: @default-button-background-color; /* TODO: to compat */
+	.default-button-background-image();
 }
-.mblTabBarButtonTextBoxSelected-styles () {
-	color: white;
+.mblTabBarStandardTabButtonIconArea-styles () {
 }
-.mblTabButtonSelected-styles () {
-	background-color: #8C8E8C;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#A59EA5), to(#848284));
-}
-.mblTabButtonHighlighted-styles () {
-	background-color: #FFB600;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FFCB00), to(#FF9A00));
-}
-.mblTabButtonImgDiv-styles () {
-	position: relative;
-	margin-left: 24px;
-	height: 40px;
-}
-.mblTabPanelHeader-styles () {
-	margin: 0px;
-	padding: 0px 0px 0px 0px;
-	height: 64px;
-	border-top: 1px solid #CDD5DF;
-	border-bottom: 2px solid #949694;
-	background-color: #000000;
-	font-family: Helvetica;
-	font-size: 20px;
-	color: white;
-	text-align: center;
+.mblTabBarStandardTabButtonLabel-styles () {
 }
-.mblTabPanelHeader-TabButton-styles () {
-	margin-top: 3px;
+.mblTabBarStandardTabButtonSelected-styles () {
+	color: @default-button-selected-color;
+	background-color: @default-button-selected-background-color; /* TODO: to compat */
+	.background-image-linear-gradient-top-bottom-2-stops(#313031, #959595, 0.5, #5a555a, 0.5, #616161);
 }
-.mblTabPanelHeader-TabButtonSelected-styles () {
-}	
-.mblTabPanelHeader-TabButtonDomButton-styles () {
-	width: 43px;
+.mblTabBarStandardTabButtonLabelSelected-styles () {
 }
-.mblTabPanelHeader-TabButtonDomButtonClass-styles () {
-	left: 8px;
+
+// barType="tallTab"
+.mblTabBarTallTab-styles () {
+	.background-image-linear-gradient-top-bottom(#2d2d2d, #000000);
 }
-.mblTabPanelHeader-DomButton-styles () {
+.mblTabBarTallTabButton-styles () {
 }
-.mblTabPanelHeader-inHeading-styles () {
-	height: 25px;
+.mblTabBarTallTabButton-FirstChild-styles () {
 }
-.mblTabPanelHeader-TabButton-inHeading-styles () {
-	margin-top: 0;
-	margin-right: 0;
-	height: 22px;
-	line-height: 23px;
-	border-width: 1px 1px 1px 0px;
-	border-style: solid;
-	border-color: #555555;
-	background-color: #ADADAD;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#e5e5e5), to(#7f7f7f), color-stop(0.5, #adadad), color-stop(0.5, #909090));
+.mblTabBarTallTabButton-LastChild-styles () {
+}
+.mblTabBarTallTabButtonIconArea-styles () {
 }
-.mblTabPanelHeader-TabButton-FirstTabButtom-inHeading-styles () {
-	border-left-width: 1px;
+.mblTabBarTallTabButtonLabel-styles () {
 }
-.mblTabPanelHeader-TabButton-LastTabButtom-inHeading-styles () {
+.mblTabBarTallTabButtonSelected-styles () {
 }
-.mblTabPanelHeader-TabButtonSelected-inHeading-styles () {
-	background-color: #FFC700;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#ad7500), to(#ffaa00), color-stop(0.06, #ffb200), color-stop(0.5, #ffc700));
+.mblTabBarTallTabButtonLabelSelected-styles () {
 }
 
 // TextArea.less
 .mblTextArea-styles () {
-	padding: 4px 1px;
-	border-color: #9CACC0;
-	border-width: 1px;
-	border-style: inset;
-	-webkit-border-radius: 3px;
-	font-family: Helvetica;
-	font-size: 13px;
-}
-.mblExpandingTextArea-styles () {
-	margin: 2px;
+	.default-button-border-styles;
 }
 
 // TextBox.less
 .mblTextBox-styles () {
-	height: 22px;
-	border: #9CACC0 1px inset;
-	-webkit-border-radius: 3px;
-	font-family: Helvetica;
-	font-size: 13px;
+	.default-button-border-styles;
 }
 
 // ToggleButton.less
 .mblToggleButton-styles () {
-	padding: 0px 10px 0px 25px;
-	height: 29px;
-	border-width: 1px 1px 1px 1px;
-	border-style: outset;
-	border-color: #9CACC0;
-	-webkit-border-radius: 3px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FDFDFD), to(#CECECE), color-stop(0.5, #F8F8F8), color-stop(0.5, #EEEEEE));
-	font-family: Helvetica;
+	.default-button-border-styles;
 	font-size: 13px;
 	color: black;
-	line-height: 29px;
 }
 .mblToggleButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
 	color: white;
 }
 .mblToggleButtonChecked-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#00A200), to(#00D300), color-stop(0.2, #00BA00), color-stop(0.2, #00BA00));
 	color: white;
 }
 .mblToggleButtonChecked-after-styles () {
-	content: "";
-	top: 6px;
-	left: 7px;
-	width: 5px;
-	height: 10px;
 	border-color: white;
-	border-width: 2px;
-	border-style: none solid solid none;
-	-webkit-transform: rotate(45deg) skew(10deg);
-	-webkit-transform-origin: 50% 50%;
 }
 .mblToggleButtonCheckedSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#AD7500), to(#FFAA00), color-stop(0.06, #FFB200), color-stop(0.5, #FFC700));
 	color: white;
 }
 .mblToggleButtonCheckedSelected-after-styles () {
-	border-color: white;
-}
-.mblToggleButtonDisabled-styles () {
-	border-color: grey;
-	background-image: none;
-	color: grey;
 }
 
 // Overlay.less
@@ -664,51 +429,52 @@
 	background-color: #333333;
 	background-image: none;
 }
+.mblOverlay-compat () {
+}
+.mblOverlay-compat-gecko () {
+}
 
 // Tooltip.less
+ at mbl-tooltip-border-radius: 3px;
+//
 .mblTooltip-styles () {
-	padding: 5px;
-	border: #ADAAAD 1px solid;
-	background-color: #8C8A8C;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#9C9E9C), to(#848284));
-	-webkit-border-radius: 3px;
-	opacity: .97;
+	border-color: #adaaad;
+	border-radius: @mbl-tooltip-border-radius;
+	background-color: #8c8a8c;
+	.background-image-linear-gradient-top-bottom(#9c9e9c, #848284);
 }
 .mblTooltipBubble-styles () {
-	background-color: #FFC700;
+	background-color: #306ea1;
 	background-image: none;
-	color: black;
+	color: white;
 }
 .mblTooltipInnerArrow-Bubble-Above-styles () {
-	border-bottom-color: #FFC700;
+	border-bottom-color: #306ea1;
 }
 .mblTooltipInnerArrow-Bubble-Below-styles () {
-	border-top-color: #FFC700;
+	border-top-color: #306ea1;
 }
 .mblTooltipInnerArrow-Bubble-After-styles () {
-	border-left-color: #FFC700;
+	border-left-color: #306ea1;
 }
 .mblTooltipInnerArrow-Bubble-Before-styles () {
-	border-right-color: #FFC700;
-}
-.mblTooltipArrow-styles () {
-	border: 11px solid transparent;
+	border-right-color: #306ea1;
 }
 .mblTooltipArrow-Before-styles () {
 	border-left-width: 0;
-	border-right-color: #ADAAAD;
+	border-right-color: #adaaad;
 }
 .mblTooltipArrow-After-styles () {
 	border-right-width: 0;
-	border-left-color: #ADAAAD;
+	border-left-color: #adaaad;
 }
 .mblTooltipArrow-Above-styles () {
 	border-top-width: 0;
-	border-bottom-color: #ADAAAD;
+	border-bottom-color: #adaaad;
 }
 .mblTooltipArrow-Below-styles () {
 	border-bottom-width: 0;
-	border-top-color: #ADAAAD;
+	border-top-color: #adaaad;
 }
 .mblTooltipInnerArrow-Before-styles () {
 	border-left-width: 0;
@@ -720,7 +486,7 @@
 }
 .mblTooltipInnerArrow-Above-styles () {
 	border-top-width: 0;
-	border-bottom-color: #9C9E9C;
+	border-bottom-color: #9c9e9c;
 }
 .mblTooltipInnerArrow-Below-styles () {
 	border-bottom-width: 0;
@@ -733,5 +499,255 @@
 	background-color: transparent;
 	background-image: none;
 }
+.mblTooltip-Heading-compat () {
+}
 .mblTooltip-Heading-ToolbarButton-styles () {
 }
+.mblTooltip-Heading-ToolbarButton-compat () {
+}
+
+// Accordion.less
+.mblAccordion-styles () {
+	border-color: #8c8f91;
+}
+.mblAccordionTitle-styles () {
+	border-top: 1px solid #8c8f91;
+	.mbl-button-background-image();
+}
+.mblAccordionTitle-compat () {
+	background-color: #f8f8f8;
+}
+.mblAccordionTitle-compat-gecko () {
+	background-image: @mbl-button-background-image-gecko;
+}
+.mblAccordionTitleSelected-styles () {
+	border-bottom: 1px solid #8c8f91;
+	.mbl-button-checked-background-image();
+	color: white;
+}
+.mblAccordionTitleSelected-compat () {
+	background-color: #00ba00;
+}
+.mblAccordionTitleSelected-compat-gecko () {
+	background-image: @mbl-button-checked-background-image-gecko;
+}
+.mblAccordionTitleAnchor-styles () {
+	color: black;
+}
+.mblAccordionTitleAnchorSelected-styles () {
+	color: white;
+}
+
+// SimpleDialog.less
+ at mbl-simple-dialog-border-radius: 6px;
+//
+.mblSimpleDialog-styles () {
+	padding: 5px;
+	width: 262px;
+}
+.mblSimpleDialogDecoration-styles () {
+	background-color: rgba(64,64,64,0.85);
+	border: 2px solid #eeeeee;
+	color: white;
+}
+.mblSimpleDialogDecoration-compat () {
+	background-color: #404040;
+}
+.mblSimpleDialogDecoration-compat-gecko () {
+	background-color: rgba(64,64,64,0.85);
+}
+.mblSimpleDialogTitle-styles () {
+	margin: 14px 0 7px -5px;
+	padding: 0 14px 14px;
+	width: 244px;
+	border-bottom: 1px solid rgba(96,96,96,0.85);
+	font-size: 21px;
+	text-align: left;
+}
+.mblSimpleDialogText-styles () {
+	margin: 14px 9px;
+	width: 244px;
+	font-size: 18px;
+	text-align: left;
+}
+
+// IconMenu.less
+ at mbl-icon-menu-border-radius: 6px;
+ at mbl-icon-menu-item-border-radius: 6px;
+//
+.mblIconMenu-styles () {
+	padding: 0;
+	background-color: rgba(64, 64, 64, 0.85);
+	border: 2px solid #eeeeee;
+}
+.mblIconMenu-compat () {
+	background-color: #404040;
+}
+.mblIconMenu-compat-gecko () {
+	background-color: rgba(64, 64, 64, 0.85);
+}
+.mblIconMenuItem-styles () {
+	border-left: 1px solid rgba(96, 96, 96, 0.85);
+	border-bottom: 1px solid rgba(96, 96, 96, 0.85);
+}
+.mblIconMenuItemAnchor-styles () {
+	font-size: 13px;
+	color: white;
+}
+.mblIconMenuItemSel-styles () {
+	.default-selected-background-image();
+	color: white;
+}
+.mblIconMenuItemSel-compat () {
+	background-color: @default-selected-background-color;
+}
+.mblIconMenuItemSel-compat-gecko () {
+	background-image: @default-selected-background-image-gecko;
+}
+
+// dijit.Calendar
+.dijitCalendar-styles () {
+	border: none 0 transparent;
+	background-color: white;
+}
+.dijitCalendar-thead-styles () {
+	.background-image-linear-gradient-top-bottom-2-stops(#84868c, #000000, 0.5, #52555a, 0.5, #292929);
+}
+.dijitCalendar-thead-compat () {
+	background-image: url(compat/calendar-month-bg.png);
+}
+.dijitCalendar-thead-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #84868c 0%, #52555a 50%, #292929 50%, #000000 100%);
+}
+.dijitCalendarMonthLabel-styles () {
+	color: white;
+	font-size: 16px;
+}
+.dijitCalendarMonthMenu-styles () {
+}
+.dijitCalendarMonthMenu-compat-ff3 () {
+}
+.dijitCalendarMonthMenu-Label-styles () {
+	color: black;
+}
+.dijitCalendarDecrease-styles () {
+	border-right: 6px solid white !important;
+}
+.dijitCalendarIncrease-styles () {
+	border-left: 6px solid white !important;
+}
+.dijitCalendarDayLabelTemplate-styles () {
+	background-color: #292c31;
+	font-size: 12px;
+	color: white;
+}
+.dijitCalendarDateTemplate-styles () {
+	border-right: 1px solid lightGrey;
+	background-color: white;
+	color: black;
+}
+.dijitCalendarDateTemplate-LastChild-styles () {
+	border-right: none;
+}
+.dijitCalendarDateLabel-DateTemplate-styles () {
+	border: none;
+}
+.dijitCalendarDateLabel-PrevMonth-styles () {
+	color: lightGrey;
+}
+.dijitCalendarDateLabel-Hovered-styles () {
+	color: grey;
+}
+.dijitCalendarDateLabel-Selected-styles () {
+	.mbl-button-checked-background-image();
+	color: white;
+	text-shadow: rgba(0,0,0,0.4) 0 1px 0;
+}
+.dijitCalendarDateLabel-Selected-compat () {
+	background-image: url(compat/calendar-datelabel-sel-bg.png);
+}
+.dijitCalendarDateLabel-Selected-compat-gecko () {
+	background-image: @mbl-button-checked-background-image-gecko;
+}
+.dijitCalendarDateLabel-Active-styles () {
+	.default-selected-background-image();
+}
+.dijitCalendarDateLabel-Active-compat () {
+	background-image: url(compat/calendar-datelabel-act-bg.png);
+}
+.dijitCalendarDateLabel-Active-compat-gecko () {
+	background-image: @default-selected-background-image-gecko;
+}
+.dijitCalendarYearLabel-styles () {
+	padding: 0;
+	.background-image-linear-gradient-top-bottom-2-stops(#84868c, #000000, 0.5, #52555a, 0.5, #292929);
+}
+.dijitCalendarYearLabel-compat () {
+	background-image: url(compat/calendar-year-bg.png);
+}
+.dijitCalendarYearLabel-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #84868c 0%, #52555a 50%, #292929 50%, #000000 100%);
+}
+.dijitCalendarSelectedYear-styles () {
+	color: white;
+	font-size: 16px;
+}
+.dijitCalendarNextYear-styles () {
+	padding: 1px 6px 3px 6px;
+	color: white;
+	font-size: 12px;
+}
+
+// SearchBox.less
+ at mbl-searchbox-cancel-button-color: black;
+ at mbl-searchbox-cancel-button-bg-color: transparent;
+.mblSearchBox-Cancel-Button-styles () {
+	border-radius: 0;
+}
+ at mbl-searchbox-results-decoration-color: black;
+
+// ProgressBar.less
+.mblProgressBar-styles () {
+	border-radius: 6px;
+	height: 22px;
+	.background-image-linear-gradient-top-bottom-2-stops(#545454, #414141, 0.3, #313031, 0.85, #293031);
+}
+.mblProgressBarProgress-styles () {
+	border-top-left-radius: 6px;
+	border-bottom-left-radius: 6px;
+	.background-image-linear-gradient-top-bottom-2-stops(#adf708, #5a8e00, 0.5, #7bbe08, 0.9, #63a600);
+	height: 22px;
+}
+.mblProgressBarComplete-styles () {
+	border-radius: 6px;
+}
+.mblProgressBarNotStarted-styles () {
+}
+.mblProgressBarMsg-styles () {
+	top: 3px;
+}
+.mblProgressBar-compat () {
+	background-color: #293031;
+}
+.mblProgressBarProgress-compat () {
+	background-color: #7bc708;
+}
+.mblProgressBar-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #545454 0%, #313031 30%, #293031 85%, #414141 100%);
+}
+.mblProgressBarProgress-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #adf708 0%, #7bbe08 50%, #63a600 90%, #5a8e00 100%);
+}
+
+// ValuePicker.less
+.mbl-value-picker-slot-button-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#f7f7f7, #D6D7D6, 0.5, #d6d3d6, 0.9, #bdbebd); }
+ at mbl-value-picker-slot-button-background-image-gecko: -moz-linear-gradient(top, #f7f7f7 0%, #d6d3d6 50%, #bdbebd 90%, #d6d7d6 100%);
+ at mbl-value-picker-slot-button-radius: 5px;
+.mbl-value-picker-slot-input-area-background-image () { .background-image-linear-gradient-top-bottom-3-stops(#adaead, #e7e3e7, 0.1, #d6d7d6, 0.5, #f7f7f7, 0.9, #f7f3f7); }
+ at mbl-value-picker-slot-input-area-background-image-gecko: -moz-linear-gradient(top, #adaead 0%, #d6d7d6 10%, #f7f7f7 50%, #f7f3f7 90%, #e7e3e7 100%);
+.mblValuePickerSlot-style () {
+  margin:  0 5px;
+}
+.mblValuePickerSlot-input-style () {
+  font-size: 28px;  
+}
diff --git a/dojox/mobile/themes/android/variables_rtl.less b/dojox/mobile/themes/android/variables_rtl.less
new file mode 100644
index 0000000..69bd170
--- /dev/null
+++ b/dojox/mobile/themes/android/variables_rtl.less
@@ -0,0 +1,32 @@
+// Carousel_rtl
+ at mbl-carousel-margin-rtl: ~"2px 0px 2px 4px";
+
+// IconContainer_rtl
+ at mbl-icon-container-right-rtl: -2px;
+
+// IconMenu_rtl-compat
+ at mbl-border-radius-rtl: 6px;
+
+// TabBar_rtl-compat
+ at mbl-moz-border-radius-rtl: 5px;
+
+// TabBar_rtl
+ at mbl-border-width-rtl: ~"1px 0px 1px 1px !important";
+ at mbl-tb-border-radius-rtl: 5px;
+
+// ThemeID
+ at theme-id: android;
+
+// Switch_rtl-compat
+ at mbl-bg-image-r-rtl: ~"url(compat/switch-square-r.gif)";
+ at mbl-bg-image-l-rtl: ~"url(compat/switch-square-l.gif)";
+
+// Switch_rtl
+ at mbl-switchOn-left-rtl: -53px;
+ at mbl-switchBg-left-rtl: 53px;
+ at mbl-switch-knob-rtl: 53px;
+ at mbl-switch-text-right-rtl: -40px;
+
+// ToolBarButton_rtl
+ at mbl-toolbar-right-arrow-rtl: -1px;
+ at mbl-toolbar-left-arrow-rtl: -2px;
diff --git a/dojox/mobile/themes/blackberry/Accordion-compat.css b/dojox/mobile/themes/blackberry/Accordion-compat.css
new file mode 100644
index 0000000..e86b2c0
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Accordion-compat.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.Accordion */
+.mblAccordionTitleSelected {
+  background-color: #0869c6;
+}
+.dj_gecko .mblAccordionTitleSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_ff3 .mblAccordionRoundRect {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitle:first-child {
+  -moz-border-radius-topleft: 8px;
+  -moz-border-radius-topright: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitleLast,
+.dj_ff3 .mblAccordionRoundRect .mblAccordionPane:last-child {
+  -moz-border-radius-bottomleft: 8px;
+  -moz-border-radius-bottomright: 8px;
+}
diff --git a/dojox/mobile/themes/blackberry/Accordion.css b/dojox/mobile/themes/blackberry/Accordion.css
new file mode 100644
index 0000000..2c07040
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Accordion.css
@@ -0,0 +1,72 @@
+/* dojox.mobile.Accordion */
+.mblAccordion {
+  border-style: outset;
+  border-width: 1px;
+  border-color: #9cacc0;
+}
+.mblAccordionRoundRect {
+  margin: 7px 9px 16px 9px;
+  padding: 0;
+  border: 1px solid #c6c7c6;
+  border-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitle:first-child {
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitleLast,
+.mblAccordionRoundRect .mblAccordionPane:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
+}
+.mblAccordionTitle {
+  position: relative;
+  height: 30px;
+  width: 100%;
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  line-height: 30px;
+  vertical-align: middle;
+  white-space: nowrap;
+  border-top: 1px outset #9cacc0;
+  background-color: white;
+}
+.mblAccordionTitle:first-child {
+  border-top: none;
+}
+.mblAccordionTitleAnchor {
+  display: block;
+  height: 100%;
+  text-decoration: none;
+  white-space: nowrap;
+  color: #000000;
+  cursor: pointer;
+}
+.mblAccordionIconParent {
+  float: left;
+  margin: 6px 4px 0 6px;
+  line-height: normal;
+}
+.mblAccordionIconParent1 {
+  display: block;
+}
+.mblAccordionIconParent2 {
+  display: none;
+}
+.mblAccordionTitleSelected {
+  border-bottom: 1px outset #9cacc0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
+  color: white;
+}
+.mblAccordionTitleSelected .mblAccordionTitleAnchor {
+  color: white;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent1 {
+  display: none;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent2 {
+  display: block;
+}
diff --git a/dojox/mobile/themes/blackberry/Button-compat.css b/dojox/mobile/themes/blackberry/Button-compat.css
index 359e510..3bd6290 100644
--- a/dojox/mobile/themes/blackberry/Button-compat.css
+++ b/dojox/mobile/themes/blackberry/Button-compat.css
@@ -1,33 +1,41 @@
 /* dojox.mobile.Button */
 .mblButton {
-	background-color: #cecfd6;
-	background-image: url(compat/button-bg.png);
-	background-repeat: repeat-x;
-	-moz-border-radius: 6px;
-	-o-border-radius: 6px;
-	-ms-border-radius: 6px;
-	border-radius: 6px;
+  background-image: url(compat/button-bg.png);
+  background-repeat: repeat-x;
 }
 .mblButtonSelected {
-	background-color: #0852ae;
-	background-image: url(compat/button-sel-bg.png);
-}
-.mblButtonDisabled {
-	background-image: none;
+  background-image: url(compat/button-sel-bg.png);
 }
 .mblBlueButton {
-	background-color: #2261dd;
-	background-image: url(compat/blue-button-bg.png);
+  background-image: url(compat/blue-button-bg.png);
 }
 .mblBlueButtonSelected {
-	background-color: #0852ae;
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/blue-button-sel-bg.png);
 }
 .mblRedButton {
-	background-color: #ee4115;
-	background-image: url(compat/red-button-bg.png);
+  background-image: url(compat/red-button-bg.png);
 }
 .mblRedButtonSelected {
-	background-color: #0852ae;
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/red-button-sel-bg.png);
+}
+.dj_gecko .mblButton {
+  background-image: -moz-linear-gradient(top, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.dj_gecko .mblButtonSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_gecko .mblBlueButton {
+  background-image: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblBlueButtonSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_gecko .mblRedButton {
+  background-image: -moz-linear-gradient(top, #fa9d58 0%, #ff4d25 50%, #ed4d15 50%, #ee4115 100%);
+}
+.dj_gecko .mblRedButtonSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_ff3 .mblButton {
+  -moz-border-radius: 6px;
 }
diff --git a/dojox/mobile/themes/blackberry/Button.css b/dojox/mobile/themes/blackberry/Button.css
index fa8dc66..01f52ca 100644
--- a/dojox/mobile/themes/blackberry/Button.css
+++ b/dojox/mobile/themes/blackberry/Button.css
@@ -1,45 +1,47 @@
 /* dojox.mobile.Button */
 .mblButton {
-  cursor: pointer;
-  outline: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  padding: 0px 10px;
+  padding: 0 10px;
   height: 29px;
-  border: #9CACC0 1px outset;
-  -webkit-border-radius: 6px;
+  border-style: outset;
+  border-width: 1px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
-  color: black;
+  background-image: linear-gradient(to bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
   font-family: Helvetica;
-  font-size: 16px;
   line-height: 29px;
-}
-.mblButton.mblBlueButton {
+  cursor: pointer;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  border-color: #9CACC0;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
-  color: white;
+  border-color: #9cacc0;
+  border-radius: 6px;
+  color: black;
+  font-size: 16px;
 }
-.mblButton.mblBlueButtonSelected {
+.mblButtonSelected {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
   color: white;
 }
-.mblButton.mblRedButton {
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  border-color: #9CACC0;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#fa9d58), to(#ee4115), color-stop(0.5, #ff4d25), color-stop(0.5, #ed4d15));
-  color: white;
+.mblButtonDisabled,
+.mblButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
 }
-.mblButton.mblRedButtonSelected {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+.mblBlueButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
   color: white;
 }
-.mblButtonSelected {
+.mblBlueButtonSelected {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.mblRedButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fa9d58), to(#ee4115), color-stop(0.5, #ff4d25), color-stop(0.5, #ed4d15));
+  background-image: linear-gradient(to bottom, #fa9d58 0%, #ff4d25 50%, #ed4d15 50%, #ee4115 100%);
   color: white;
 }
-.mblButtonDisabled, .mblButton:disabled {
-  cursor: default;
-  border-color: grey;
-  color: grey;
-  background-image: none;
+.mblRedButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
 }
diff --git a/dojox/mobile/themes/blackberry/Button.less b/dojox/mobile/themes/blackberry/Button.less
deleted file mode 100644
index ab3a96c..0000000
--- a/dojox/mobile/themes/blackberry/Button.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Button.less";
diff --git a/dojox/mobile/themes/blackberry/Carousel.css b/dojox/mobile/themes/blackberry/Carousel.css
index a415950..4439d46 100644
--- a/dojox/mobile/themes/blackberry/Carousel.css
+++ b/dojox/mobile/themes/blackberry/Carousel.css
@@ -1,30 +1,17 @@
 /* dojox.mobile.Carousel */
 .mblCarousel {
   overflow: hidden;
+  height: 300px;
 }
-.mblCarouselBox {
+.mblCarouselSlot {
   position: relative;
   float: left;
-}
-.mblCarouselImg {
-  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
-  vertical-align: bottom;
-}
-.mblCarouselImgSelected {
-  border: 1px dashed #C0C0C0;
-  -webkit-box-shadow: none;
-}
-.mblCarouselImgHeaderText {
-  color: white;
-  font: 14px arial, helvetica, clean, sans-serif;
-}
-.mblCarouselImgFooterText {
-  color: white;
-  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: left;
+  box-sizing: border-box;
 }
 .mblCarouselHeaderBar {
-  background-color: #3A3A3B;
-  color: #B1B1B1;
+  background-color: #3a3a3b;
+  color: #b1b1b1;
   font: bold 16px arial, helvetica, clean, sans-serif;
   padding: 1px;
 }
@@ -58,3 +45,35 @@
   position: relative;
   text-align: center;
 }
+/* dojox.mobile._CarouselItem */
+.mblCarouselItem {
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblCarouselItemHeaderText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 8px;
+  margin-bottom: 5px;
+}
+.mblCarouselItemFooterText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 5px;
+  margin-bottom: 8px;
+}
+.mblCarouselItemImage {
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  vertical-align: bottom;
+}
+.mblCarouselItemBlank {
+  display: none;
+}
+.mblCarouselSlotSelected .mblCarouselItemImage {
+  opacity: 0.6;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
diff --git a/dojox/mobile/themes/blackberry/Carousel.less b/dojox/mobile/themes/blackberry/Carousel.less
deleted file mode 100644
index d717397..0000000
--- a/dojox/mobile/themes/blackberry/Carousel.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Carousel.less";
diff --git a/dojox/mobile/themes/blackberry/Carousel_rtl.css b/dojox/mobile/themes/blackberry/Carousel_rtl.css
new file mode 100644
index 0000000..45abf85
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Carousel_rtl.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.Carousel Rtl */
+.mblCarouselItemRtl.mblCarouselSlot {
+  float: right;
+}
+.mblCarouselRtl .mblCarouselBtnContainer {
+  float: left;
+}
+.mblCarouselRtl .mblCarouselTitle {
+  margin: 2px 0px 2px 4px;
+}
+.mblCarouselRtl .mblCarouselHeaderBar .mblPageIndicator {
+  float: left;
+}
diff --git a/dojox/mobile/themes/blackberry/CheckBox-compat.css b/dojox/mobile/themes/blackberry/CheckBox-compat.css
index f926ffa..85cae61 100644
--- a/dojox/mobile/themes/blackberry/CheckBox-compat.css
+++ b/dojox/mobile/themes/blackberry/CheckBox-compat.css
@@ -1,34 +1,38 @@
 /* dojox.mobile.CheckBox */
 .mblCheckBox {
-	background-image: url(compat/button-bg.png);
-	-moz-border-radius: 3px;
-	-o-border-radius: 3px;
-	-ms-border-radius: 3px;
-	border-radius: 3px;
-	-moz-appearance: none;
-	-o-appearance: none;
-	-ms-appearance: none;
-	appearance: none;
-	-o-transform: translateY(0.4em);
-	-ms-transform: translateY(0.4em);
-	transform: translateY(0.4em);
+  background-image: url(compat/button-bg.png);
+}
+.mblCheckBoxSelected {
+  background-image: url(compat/button-sel-bg.png);
 }
 .mblCheckBoxChecked,
 .mblCheckBox:checked {
-	background-image: url(compat/button-bg.png);
-}
-.mblCheckBoxChecked::after,
-.mblCheckBox:checked::after {
-	-moz-transform: rotate(45deg);
-	-o-transform: rotate(45deg);
-	-ms-transform: rotate(45deg);
-	transform: rotate(45deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
-}
-.mblCheckBoxSelected,
-.mblCheckBoxChecked.mblCheckBoxSelected {
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblCheckBox {
+  background-image: -moz-linear-gradient(top, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+  -moz-appearance: none;
+}
+.dj_gecko .mblCheckBoxSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_gecko .mblCheckBoxChecked,
+.dj_gecko .mblCheckBox:checked {
+  background-image: -moz-linear-gradient(top, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.dj_gecko .mblCheckBoxChecked::after,
+.dj_gecko .mblCheckBox:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblCheckBoxChecked.mblCheckBoxSelected,
+.dj_gecko .mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_ff3 .mblCheckBox {
+  -moz-border-radius: 6px;
 }
diff --git a/dojox/mobile/themes/blackberry/CheckBox.css b/dojox/mobile/themes/blackberry/CheckBox.css
index 89f618c..d6432a1 100644
--- a/dojox/mobile/themes/blackberry/CheckBox.css
+++ b/dojox/mobile/themes/blackberry/CheckBox.css
@@ -1,44 +1,53 @@
 /* dojox.mobile.CheckBox */
 .mblCheckBox {
   position: relative;
-  cursor: pointer;
-  outline: none;
-  -webkit-appearance: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
   margin: -0.5em 3px 0.3em 4px;
   width: 1em;
   height: 1em;
-  border: #9CACC0 1px outset;
-  -webkit-border-radius: 3px;
+  border-style: outset;
+  border-width: 1px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
   font: inherit;
-  -webkit-transform: translatey(0.4em);
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  border-color: #9cacc0;
+  border-radius: 3px;
 }
 .mblCheckBoxSelected {
-  border-color: #9CACC0;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
 }
-.mblCheckBoxChecked, .mblCheckBox:checked {
-  border-color: #9CACC0;
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
 }
-.mblCheckBoxChecked::after, .mblCheckBox:checked::after {
+.mblCheckBoxChecked::after,
+.mblCheckBox:checked::after {
   position: absolute;
   content: "";
   width: 0.3em;
   height: 0.6em;
   top: 0;
   left: 0.3em;
-  border-color: #0851AD;
   border-width: 0.15em;
   border-style: none solid solid none;
   -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
   -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: #0851ad;
 }
-.mblCheckBoxChecked.mblCheckBoxSelected, .mblCheckBox:checked.mblCheckBoxSelected {
-  border-color: #9CACC0;
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
 }
-.mblCheckBoxChecked.mblCheckBoxSelected::after, .mblCheckBox:checked.mblCheckBoxSelected::after {
+.mblCheckBoxChecked.mblCheckBoxSelected::after,
+.mblCheckBox:checked.mblCheckBoxSelected::after {
   border-color: white;
 }
diff --git a/dojox/mobile/themes/blackberry/CheckBox.less b/dojox/mobile/themes/blackberry/CheckBox.less
deleted file mode 100644
index 09f93b2..0000000
--- a/dojox/mobile/themes/blackberry/CheckBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/CheckBox.less";
diff --git a/dojox/mobile/themes/blackberry/ComboBox-compat.css b/dojox/mobile/themes/blackberry/ComboBox-compat.css
index b0504e4..71827ab 100644
--- a/dojox/mobile/themes/blackberry/ComboBox-compat.css
+++ b/dojox/mobile/themes/blackberry/ComboBox-compat.css
@@ -1,17 +1,7 @@
 /* dojox.mobile.ComboBox */
-.dijitPopup {
-	-moz-box-shadow: none;
-	-o-box-shadow: none;
-	-ms-box-shadow: none;
-	box-shadow: none;
-	-moz-border-radius: 12px;
-	-o-border-radius: 12px;
-	-ms-border-radius: 12px;
-	border-radius: 12px;
+.dj_gecko .dijitPopup {
+  -moz-box-shadow: none;
 }
-.mblComboBoxMenu {
-	-moz-border-radius: 12px;
-	-o-border-radius: 12px;
-	-ms-border-radius: 12px;
-	border-radius: 12px;
+.dj_gecko .mblComboBoxMenuItemSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
 }
diff --git a/dojox/mobile/themes/blackberry/ComboBox-compat.less b/dojox/mobile/themes/blackberry/ComboBox-compat.less
new file mode 100644
index 0000000..cb21fbb
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ComboBox-compat.less
@@ -0,0 +1,2 @@
+ at import "variables.less";
+ at import "../common/ComboBox-compat.less";
diff --git a/dojox/mobile/themes/blackberry/ComboBox.css b/dojox/mobile/themes/blackberry/ComboBox.css
index 45dd699..a971caf 100644
--- a/dojox/mobile/themes/blackberry/ComboBox.css
+++ b/dojox/mobile/themes/blackberry/ComboBox.css
@@ -6,7 +6,8 @@
   border: 0;
   background-color: transparent;
   -webkit-box-shadow: none;
-  -webkit-border-radius: 12px;
+  box-shadow: none;
+  border-radius: 12px;
 }
 .mblReset {
   margin: 0;
@@ -17,28 +18,29 @@
   color: inherit;
 }
 .mblComboBoxMenu {
-  overflow-y: hidden !important;
   position: relative;
+  overflow-y: hidden !important;
   overflow: hidden;
   border: 1px solid black;
-  -webkit-border-radius: 12px;
+  border-radius: 12px;
   background-color: black;
 }
 .mblComboBoxMenuItem {
-  white-space: nowrap;
   padding: .1em .2em;
   border-width: 1px 0 1px 0;
   border-style: solid;
+  text-align: left;
+  white-space: nowrap;
   border-color: black;
   color: white;
-  text-align: left;
 }
 .mblComboBoxMenuItemSelected {
-  color: white;
-  background-color: black;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
+  color: white;
 }
-.mblComboBoxMenuPreviousButton, .mblComboBoxMenuNextButton {
+.mblComboBoxMenuPreviousButton,
+.mblComboBoxMenuNextButton {
   font-style: italic;
   overflow: hidden;
 }
diff --git a/dojox/mobile/themes/blackberry/ComboBox.less b/dojox/mobile/themes/blackberry/ComboBox.less
deleted file mode 100644
index ab9458c..0000000
--- a/dojox/mobile/themes/blackberry/ComboBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ComboBox.less";
diff --git a/dojox/mobile/themes/blackberry/ComboBox_rtl.css b/dojox/mobile/themes/blackberry/ComboBox_rtl.css
new file mode 100644
index 0000000..01b9527
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ComboBox_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.ComboBox Rtl*/
+.mblComboBoxMenuItemRtl {
+  text-align: right;
+}
diff --git a/dojox/mobile/themes/blackberry/DatePicker.css b/dojox/mobile/themes/blackberry/DatePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/DatePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.css b/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.css
index 5951a20..66ab4a5 100644
--- a/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.css
+++ b/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.css
@@ -1,18 +1,18 @@
 /* dojox.mobile.EdgeToEdgeCategory */
 .mblEdgeToEdgeCategory {
   position: relative;
+  margin: 0;
+  padding: 0 10px;
   overflow: hidden;
-  white-space: nowrap;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
   text-overflow: ellipsis;
-  margin: 0px;
-  padding: 0px 10px;
+  white-space: nowrap;
   height: 29px;
   border-top: 1px solid #313439;
-  border-bottom: 1px solid #ADAAAD;
+  border-bottom: 1px solid #adaaad;
   background-color: white;
-  font-family: Helvetica;
-  font-size: 16px;
-  font-weight: bold;
-  color: #7B7D84;
+  color: #7b7d84;
   line-height: 29px;
 }
diff --git a/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.less b/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.less
deleted file mode 100644
index 3bb63da..0000000
--- a/dojox/mobile/themes/blackberry/EdgeToEdgeCategory.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/EdgeToEdgeCategory.less";
diff --git a/dojox/mobile/themes/blackberry/EdgeToEdgeList.css b/dojox/mobile/themes/blackberry/EdgeToEdgeList.css
index baac042..6acbb2f 100644
--- a/dojox/mobile/themes/blackberry/EdgeToEdgeList.css
+++ b/dojox/mobile/themes/blackberry/EdgeToEdgeList.css
@@ -1,12 +1,9 @@
 /* dojox.mobile.EdgeToEdgeList */
 .mblEdgeToEdgeList {
-  position: relative;
-  /* IE needs this */
-
-  margin: 0px;
-  padding: 0px;
+  margin: 0;
+  padding: 0;
   background-color: white;
 }
 .mblEdgeToEdgeList .mblListItem:last-child {
-  border-bottom-width: 0px;
+  border-bottom-width: 0;
 }
diff --git a/dojox/mobile/themes/blackberry/EdgeToEdgeList.less b/dojox/mobile/themes/blackberry/EdgeToEdgeList.less
deleted file mode 100644
index 227627c..0000000
--- a/dojox/mobile/themes/blackberry/EdgeToEdgeList.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/EdgeToEdgeList.less";
diff --git a/dojox/mobile/themes/blackberry/FixedSplitter.css b/dojox/mobile/themes/blackberry/FixedSplitter.css
new file mode 100644
index 0000000..f53833d
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/FixedSplitter.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.FixedSplitter */
+.mblFixedSplitter {
+  width: 100%;
+  height: 100%;
+}
+/* For FixedSplitter's child panes */
+.mblFixedSplitter > * {
+  position: absolute;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.mblFixedSplitterH > * {
+  height: 100%;
+  top: 0px;
+}
+.mblFixedSplitterV > * {
+  width: 100%;
+  left: 0px;
+}
diff --git a/dojox/mobile/themes/blackberry/FormLayout.css b/dojox/mobile/themes/blackberry/FormLayout.css
new file mode 100644
index 0000000..bb00da1
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/FormLayout.css
@@ -0,0 +1,190 @@
+/* Single Column Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (max-width: 500px) {
+  .mblFormLayout.mblFormLayoutAuto fieldset {
+    padding-left: 0;
+    padding-right: 0;
+  }
+  /* A gap between rows */
+  .mblFormLayout.mblFormLayoutAuto > * + * {
+    margin-top: 0.6em;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 100%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'single' ***/
+.mblFormLayout.mblFormLayoutSingleCol fieldset {
+  padding-left: 0;
+  padding-right: 0;
+}
+/* A gap between rows */
+.mblFormLayout.mblFormLayoutSingleCol > * + * {
+  margin-top: 0.6em;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 100%;
+  box-sizing: border-box;
+}
+/* Two Columns Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (min-width: 500px) {
+  /* Form layout selector*/
+  .mblFormLayout.mblFormLayoutAuto {
+    display: table;
+    width: 100%;
+  }
+  /* Form rows */
+  .mblFormLayout.mblFormLayoutAuto > * {
+    display: table-row;
+  }
+  /* Form cells */
+  .mblFormLayout.mblFormLayoutAuto > * > * {
+    display: table-cell;
+    vertical-align: top;
+    padding: 0.5em 0;
+  }
+  /* Left cells */
+  .mblFormLayout.mblFormLayoutAuto > * > *:first-child {
+    width: 20%;
+    padding-right: 0.5em;
+  }
+  /* mblFormLayoutRightAlign optional selector definition */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child {
+    text-align: right;
+  }
+  /* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+    margin-right: 0;
+  }
+  /* The Slider sticks to its bounds when margin=10px */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+    display: inline-block;
+    margin-right: 10px;
+    margin-top: 0px;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 50%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'two' ***/
+/* Form layout selector*/
+.mblFormLayout.mblFormLayoutTwoCol {
+  display: table;
+  width: 100%;
+}
+/* Form rows */
+.mblFormLayout.mblFormLayoutTwoCol > * {
+  display: table-row;
+}
+/* Form cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > * {
+  display: table-cell;
+  vertical-align: top;
+  padding: 0.5em 0;
+}
+/* Left cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > *:first-child {
+  width: 20%;
+  padding-right: 0.5em;
+}
+/* mblFormLayoutRightAlign optional selector definition */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child {
+  text-align: right;
+}
+/* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+  margin-right: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+  display: inline-block;
+  margin-right: 10px;
+  margin-top: 0px;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 50%;
+  box-sizing: border-box;
+}
+/* Common Rules*/
+/**********************************************************************************************************************/
+.mblFormLayout fieldset {
+  border: none;
+  margin: 0;
+}
+/* Bold widget labels */
+.mblFormLayout > * > *:first-child {
+  font-weight: bold;
+}
+/* Whatever the screen width, force left margin of first elements and elements following a <br> */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Button"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ToggleButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.CheckBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Switch"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.RadioButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.SearchBox"] {
+  margin-left: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > .mblSlider:first-child {
+  display: inline-block;
+  margin-left: 10px;
+  margin-top: 0;
+  margin-bottom: 0;
+}
diff --git a/dojox/mobile/themes/blackberry/GridLayout.css b/dojox/mobile/themes/blackberry/GridLayout.css
new file mode 100644
index 0000000..628fd9f
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/GridLayout.css
@@ -0,0 +1,24 @@
+/* dojox.mobile.GridLayout */
+.mblGridLayout {
+  width: 100%;
+  height: 100%;
+  padding: 0;
+}
+.mblGridLayout > div {
+  margin: 0;
+  border: 0;
+  padding: 0;
+  float: left;
+  min-height: 1px;
+}
+.mblGridItemFirstColumn {
+  clear: left;
+}
+.mblGridItemTerminator {
+  clear: both;
+}
+.mblGridItemLastItem:after {
+  content: "";
+  display: block;
+  clear: both;
+}
diff --git a/dojox/mobile/themes/blackberry/Heading-compat.css b/dojox/mobile/themes/blackberry/Heading-compat.css
index 8c7dd88..460691d 100644
--- a/dojox/mobile/themes/blackberry/Heading-compat.css
+++ b/dojox/mobile/themes/blackberry/Heading-compat.css
@@ -1,25 +1,10 @@
-/* mbl.widget.Heading */
+/* dojox.mobile.Heading */
 .mblHeading {
-	background-image: url(compat/heading-bg.png);
+  background-image: url(compat/heading-bg.png);
 }
 .mblHeadingSpanTitle {
-	white-space: normal;
+  white-space: normal;
 }
-
-/* Heading Arrow Button */
-.mblArrowButtonHead {
-	position: absolute;
-	top: 0px;
-	left: 2px;
-	width: 19px;
-	height: 30px;
-	border-style: none;
-	background-image: url(compat/arrow-button-head.gif);
-}
-.mblArrowButtonBody {
-	padding: 0px 10px 0px 5px;
-	line-height: 28px;
-	-moz-border-radius-topright: 6px;
-	-moz-border-radius-bottomright: 6px;
-	background-image: url(compat/arrow-button-bg.png);
+.dj_gecko .mblHeading {
+  background-image: -moz-linear-gradient(top, #4a4d52 0%, #292c31 100%);
 }
diff --git a/dojox/mobile/themes/blackberry/Heading.css b/dojox/mobile/themes/blackberry/Heading.css
index d5267eb..397ada6 100644
--- a/dojox/mobile/themes/blackberry/Heading.css
+++ b/dojox/mobile/themes/blackberry/Heading.css
@@ -1,24 +1,24 @@
 /* dojox.mobile.Heading */
 .mblHeading {
   position: relative;
-  margin: 0px;
+  margin: 0;
   width: 100%;
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
   z-index: 1;
-  padding: 0px;
-  height: 38px;
-  background-color: #424142;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#4a4d52), to(#292c31));
-  border-top: 1px solid #63696B;
-  border-bottom: 1px solid #292C31;
-  color: white;
+  padding: 0;
+  height: 42px;
   font-family: Helvetica;
-  font-size: 18px;
-  font-weight: normal;
+  font-size: 20px;
+  font-weight: bold;
   text-align: center;
-  line-height: 40px;
+  line-height: 44px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#4a4d52), to(#292c31));
+  background-image: linear-gradient(to bottom, #4a4d52 0%, #292c31 100%);
+  border-top: 1px solid #63696b;
+  border-bottom: 1px solid #292c31;
+  color: white;
 }
 .mblHeading * {
   z-index: 2;
@@ -27,7 +27,7 @@
   position: absolute;
   width: 100%;
   display: none;
-  left: 0px;
+  left: 0;
   z-index: 1;
 }
 .mblHeadingCenterTitle .mblHeadingDivTitle {
@@ -36,48 +36,3 @@
 .mblHeadingCenterTitle .mblHeadingSpanTitle {
   display: none;
 }
-/* Heading Arrow Button */
-.mblArrowButton {
-  position: relative;
-  float: left;
-  height: 28px;
-  margin: 4px 3px 0px 0px;
-}
-.mblArrowButtonHead {
-  position: absolute;
-  top: 4px;
-  left: 4px;
-  width: 19px;
-  height: 19px;
-  border: 1px solid #39454A;
-  -webkit-transform: scale(0.8, 1) rotate(45deg);
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
-}
-.dj_chrome .mblArrowButtonHead {
-  height: 20px;
-  border: 1px inset #39454A;
-  -webkit-transform: scale(0.7, 1) rotate(45deg);
-}
-.mblArrowButtonBody {
-  position: absolute;
-  cursor: pointer;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  top: 1px;
-  left: 15px;
-  padding: 0px 10px 0px 5px;
-  height: 28px;
-  border: none;
-  font-family: Helvetica;
-  font-size: 14px;
-  font-weight: bold;
-  color: black;
-  line-height: 30px;
-  -webkit-border-top-right-radius: 6px;
-  -webkit-border-bottom-right-radius: 6px;
-  background-color: #CED3CE;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
-}
-.mblArrowButtonSelected .mblArrowButtonHead, .mblArrowButtonSelected .mblArrowButtonBody {
-  color: white;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
-}
diff --git a/dojox/mobile/themes/blackberry/Heading.less b/dojox/mobile/themes/blackberry/Heading.less
deleted file mode 100644
index cfc8580..0000000
--- a/dojox/mobile/themes/blackberry/Heading.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Heading.less";
diff --git a/dojox/mobile/themes/blackberry/IconContainer-compat.css b/dojox/mobile/themes/blackberry/IconContainer-compat.css
index adf6d49..bafb264 100644
--- a/dojox/mobile/themes/blackberry/IconContainer-compat.css
+++ b/dojox/mobile/themes/blackberry/IconContainer-compat.css
@@ -1,11 +1,13 @@
 @import url("../common/domButtons/DomButtonColorButtons-compat.css");
 
-/* dojox.mobile.IconItem */
-.mblIconArea div {
-	*font-size: 60px; /* IE 7 quirks */
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+/* dojox.mobile.IconContainer */
+.mblIconItemPaneHeading {
+  background-image: url(compat/icon-content-heading-bg.png);
 }
-
-/* Icon Content Heading */
-.mblIconContentHeading {
-	background-image: url(compat/icon-content-heading-bg.png);
+.dj_gecko .mblIconItemPaneHeading {
+  background-image: -moz-linear-gradient(top, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
+}
+.dj_ie7 .mblIconAreaInner {
+  font-size: 60px;
 }
diff --git a/dojox/mobile/themes/blackberry/IconContainer-compat.less b/dojox/mobile/themes/blackberry/IconContainer-compat.less
new file mode 100644
index 0000000..e2df985
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/IconContainer-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer-compat.less";
diff --git a/dojox/mobile/themes/blackberry/IconContainer.css b/dojox/mobile/themes/blackberry/IconContainer.css
index 73fa041..1c99bc4 100644
--- a/dojox/mobile/themes/blackberry/IconContainer.css
+++ b/dojox/mobile/themes/blackberry/IconContainer.css
@@ -1,13 +1,17 @@
 @import url("../common/domButtons/DomButtonColorButtons.css");
 
- at import url("../common/IconContainer_keyframes.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
 /* dojox.mobile.IconContainer */
 .mblIconContainer {
-  margin: 0px;
-  padding: 0px;
+  margin: 20px 10px;
+  padding: 0;
 }
 /* dojox.mobile.IconItem */
 .mblIconItem {
+  position: relative;
+  overflow: hidden;
+  /* for focus frame */
+
   list-style-type: none;
   float: left;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
@@ -15,29 +19,35 @@
 .mblIconItemTerminator {
   list-style-type: none;
   clear: both;
-  height: 0px;
 }
-.mblIconItemSub {
+.mblIconItemPane {
   list-style-type: none;
   background-color: white;
   color: black;
 }
 .mblIconArea {
-  margin-bottom: 5px;
+  position: relative;
   height: 78px;
-  width: 88px;
-  text-align: center;
   font-family: Helvetica;
   font-size: 12px;
+  text-align: center;
+  margin-top: 5px;
+  margin-bottom: 5px;
+  width: 88px;
+}
+.mblIconArea img {
+  vertical-align: middle;
 }
-.mblIconArea div {
+.mblIconAreaInner {
   position: relative;
   height: 65px;
   line-height: 65px;
   text-align: center;
 }
-.mblIconArea img {
-  vertical-align: middle;
+.mblIconItemDeleteIcon {
+  position: absolute;
+  top: -4px;
+  left: 2px;
 }
 .mblIconItemSpriteIcon {
   position: absolute;
@@ -52,46 +62,199 @@ table.mblClose {
 }
 .mblVibrate {
   position: relative;
-  -webkit-animation-duration: .5s;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
   -webkit-animation-timing-function: ease-in-out;
-  -webkit-animation-iteration-count: 20;
+  animation-timing-function: ease-in-out;
+  -webkit-animation-iteration-count: infinite;
+  animation-iteration-count: infinite;
   -webkit-animation-name: mblVibrate;
+  animation-name: mblVibrate;
   -webkit-transform: rotate(0deg);
+  transform: rotate(0deg);
 }
 .mblCloseContent {
-  -webkit-animation-duration: .3s;
+  -webkit-animation-duration: 0.3s;
+  animation-duration: 0.3s;
   -webkit-animation-timing-function: ease-in-out;
+  animation-timing-function: ease-in-out;
   -webkit-animation-name: mblShrink;
+  animation-name: mblShrink;
   -webkit-transform: scale(0.01);
+  transform: scale(0.01);
 }
 .mblCloseContent.mblShrink0 {
   -webkit-animation-name: mblShrink0;
+  animation-name: mblShrink0;
 }
 .mblCloseContent.mblShrink1 {
   -webkit-animation-name: mblShrink1;
+  animation-name: mblShrink1;
 }
 .mblCloseContent.mblShrink2 {
   -webkit-animation-name: mblShrink2;
+  animation-name: mblShrink2;
 }
 .mblCloseContent.mblShrink3 {
   -webkit-animation-name: mblShrink3;
+  animation-name: mblShrink3;
 }
-/* Icon Content Heading */
-.mblIconContentHeading {
+/* dojox.mobile._IconItemPane */
+.mblIconItemPaneHeading {
   position: relative;
   clear: both;
   overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
   margin-top: 0px;
   padding-left: 40px;
   height: 25px;
-  border-top: 1px solid #F1F3F4;
-  border-bottom: 1px solid #717D85;
+  border-top: 1px solid #f1f3f4;
+  border-bottom: 1px solid #717d85;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#e0e4e7), to(#b4bec6), color-stop(0.5, #c4ccd2), color-stop(0.5, #bfc8ce));
+  background-image: linear-gradient(to bottom, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
   font-family: Helvetica;
-  font-size: 16px;
+  font-size: 14px;
   color: white;
   line-height: 26px;
   text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.mblIconItemPaneIcon {
+  position: absolute;
+  top: -2px;
+  left: 1px;
+}
+ at -webkit-keyframes mblVibrate {
+  0% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    -webkit-transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    -webkit-transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    -webkit-transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at keyframes mblVibrate {
+  0% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at -webkit-keyframes mblShrink {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(0.01);
+  }
+}
+ at keyframes mblShrink {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink0 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink0 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink1 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink1 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink2 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink2 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink3 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink3 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(40%, -70%) scale(0.01);
+  }
 }
diff --git a/dojox/mobile/themes/blackberry/IconContainer.less b/dojox/mobile/themes/blackberry/IconContainer.less
index 963eae6..729745a 100644
--- a/dojox/mobile/themes/blackberry/IconContainer.less
+++ b/dojox/mobile/themes/blackberry/IconContainer.less
@@ -1,5 +1,5 @@
 @import url("../common/domButtons/DomButtonColorButtons.css");
- at import url("../common/IconContainer_keyframes.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
 
 @import "variables.less";
 @import "../common/IconContainer.less";
diff --git a/dojox/mobile/themes/blackberry/IconContainer_rtl.css b/dojox/mobile/themes/blackberry/IconContainer_rtl.css
new file mode 100644
index 0000000..714d65d
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/IconContainer_rtl.css
@@ -0,0 +1,14 @@
+/* dojox.mobile.IconItem Rtl */
+.mblIconItemRtl {
+  float: right;
+}
+.mblIconItemRtl .mblIconItemDeleteIcon {
+  right: 2px;
+}
+/* dojox.mobile._IconItemPane Rtl*/
+.mblIconItemPaneRtl .mblIconItemPaneHeading {
+  padding-right: 40px;
+}
+.mblIconItemPaneRtl .mblIconItemPaneIcon {
+  right: 1px;
+}
diff --git a/dojox/mobile/themes/blackberry/IconMenu-compat.css b/dojox/mobile/themes/blackberry/IconMenu-compat.css
new file mode 100644
index 0000000..d5f1b12
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/IconMenu-compat.css
@@ -0,0 +1,28 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenuItemSel {
+  background-color: #0869c6;
+}
+.dj_gecko .mblIconMenuItem {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblIconMenuItemSel {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_ff3 .mblIconMenu {
+  -moz-border-radius: 6px;
+}
+.dj_ff3 .mblIconMenuItemIcon img {
+  border: 1px solid red;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-left-radius: 0;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-right-radius: 0;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-left-radius: 0;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-right-radius: 0;
+}
diff --git a/dojox/mobile/themes/blackberry/IconMenu.css b/dojox/mobile/themes/blackberry/IconMenu.css
new file mode 100644
index 0000000..00334a7
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/IconMenu.css
@@ -0,0 +1,64 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+  width: 100%;
+  height: 100%;
+  border-radius: 6px;
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  padding: 8px;
+  background-color: #000000;
+  border: none;
+}
+/* dojox.mobile.IconMenuItem */
+.mblIconMenuItem {
+  float: left;
+  list-style-type: none;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border-left: 1px solid #000000;
+  border-bottom: 1px solid #000000;
+}
+.mblIconMenuItemIcon {
+  position: relative;
+  margin-left: auto;
+  margin-right: auto;
+}
+.mblIconMenuItemFirstColumn {
+  border-left: none;
+}
+.mblIconMenuItemLastRow {
+  border-bottom: none;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  border-top-left-radius: 0;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  border-top-right-radius: 0;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  border-bottom-left-radius: 0;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  border-bottom-right-radius: 0;
+}
+.mblIconMenuItemAnchor {
+  display: block;
+  height: 100%;
+  font-family: Helvetica;
+  text-decoration: none;
+  font-size: 16px;
+  color: white;
+  cursor: pointer;
+}
+.mblIconMenuItemTable {
+  width: 100%;
+  height: 100%;
+}
+.mblIconMenuItemTable img {
+  border: none;
+}
+.mblIconMenuItemSel {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
+  color: white;
+}
diff --git a/dojox/mobile/themes/blackberry/IconMenu_rtl-compat.css b/dojox/mobile/themes/blackberry/IconMenu_rtl-compat.css
new file mode 100644
index 0000000..94e75c4
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/IconMenu_rtl-compat.css
@@ -0,0 +1,17 @@
+/* dojox.mobile.IconMenu Rtl */
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-right-radius: 0px;
+  -moz-border-top-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-left-radius: 0px;
+  -moz-border-top-right-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-right-radius: 0px;
+  -moz-border-bottom-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-left-radius: 0px;
+  -moz-border-bottom-right-radius: 0px;
+}
diff --git a/dojox/mobile/themes/blackberry/IconMenu_rtl.css b/dojox/mobile/themes/blackberry/IconMenu_rtl.css
new file mode 100644
index 0000000..85bb1e1
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/IconMenu_rtl.css
@@ -0,0 +1,7 @@
+.mblIconMenuItemRtl {
+  float: right;
+}
+.mblIconMenuItemFirstColumn {
+  border-right: none;
+  border-left: 1px solid #000000;
+}
diff --git a/dojox/mobile/themes/blackberry/ListItem-compat.css b/dojox/mobile/themes/blackberry/ListItem-compat.css
index a44214e..191ffef 100644
--- a/dojox/mobile/themes/blackberry/ListItem-compat.css
+++ b/dojox/mobile/themes/blackberry/ListItem-compat.css
@@ -1,26 +1,13 @@
 @import url("../common/domButtons/DomButtonGrayArrow-compat.css");
- at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
-
-/* mbl.widget.ListItem */
-*html li.mblListItem.mblVariableHeight { /* IE6 hack */
-	height: 0;
-}
 
-.mblListItemIcon {
-	top: 13px;
-}
-.mblListItem .mblArrow {
-	border-style: none;
-	width: 9px;
-	height: 13px;
-	background-image: url(compat/gray-arrow.png);
-}
-.mblItemSelected .mblArrow {
-	background-image: url(compat/white-arrow.png);
+ at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
+/* dojox.mobile.ListItem */
+.mblListItemSelected {
+  background-color: #0869c6;
 }
-*html .mblListItemTextBox { /* IE6 hack */
-	height: 100%;
+.dj_gecko .mblListItemSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
 }
-*html li.mblListItem.mblVariableHeight .mblListItemTextBox { /* IE6 hack */
-	height: auto;
+.dj_ie6 .mblListItem {
+  vertical-align: bottom;
 }
diff --git a/dojox/mobile/themes/blackberry/ListItem-compat.less b/dojox/mobile/themes/blackberry/ListItem-compat.less
new file mode 100644
index 0000000..332107e
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ListItem-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayArrow-compat.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
+
+ at import "variables.less";
+ at import "../common/ListItem-compat.less";
diff --git a/dojox/mobile/themes/blackberry/ListItem.css b/dojox/mobile/themes/blackberry/ListItem.css
index b8f9f9d..580e91d 100644
--- a/dojox/mobile/themes/blackberry/ListItem.css
+++ b/dojox/mobile/themes/blackberry/ListItem.css
@@ -4,83 +4,115 @@
 /* dojox.mobile.ListItem */
 .mblListItem {
   position: relative;
-  list-style-type: none;
-  vertical-align: bottom;
-  /* To avoid IE6 LI bug */
+  overflow: hidden;
+  /* for focus frame */
 
-  padding: 6px;
-  height: 43px;
-  border-bottom: solid 1px #DEDFDE;
+  padding: 0 8px;
+  height: 59px;
+  list-style-type: none;
+  line-height: 59px;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  border-bottom: 1px solid #dedfde;
   font-size: 18px;
   color: black;
-  line-height: 43px;
 }
 .mblListItem.mblVariableHeight {
+  padding: 11px 8px;
   height: auto;
-  padding: 11px 0px 10px 6px;
   line-height: normal;
 }
-.mblListItem .mblListItemAnchor {
-  display: block;
-  height: 100%;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  background-position: 14px 17px;
-  text-decoration: none;
-  padding-right: 7px;
+.mblListItemSelected {
+  color: #ffffff;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
 }
-.mblListItem .mblListItemAnchor * {
-  -webkit-tap-highlight-color: rgba(0, 0, 0, 0.2);
+.mblListItemSelected .mblDomButton div {
+  border-color: white;
 }
-.mblItemSelected {
-  background-color: #0869C6;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+.mblListItemLabelSelected {
+  background-color: #0869c6;
 }
-.mblItemSelected .mblListItemSubText {
-  color: white;
+.mblListItemChecked .mblListItemRightIcon {
+  visibility: visible;
 }
-.mblItemSelected .mblListItemAnchor {
-  color: white;
+.mblListItemChecked .mblListItemUncheckIcon {
+  position: absolute;
+  visibility: hidden;
 }
-.mblItemSelected .mblDomButton div {
-  border-color: white;
+.mblListItemUnchecked .mblListItemRightIcon {
+  visibility: hidden;
 }
-.mblListItemTextBoxSelected {
-  background-color: #0869C6;
+.mblListItemUnchecked .mblListItemUncheckIcon {
+  visibility: visible;
 }
-.mblListItemIcon {
+.mblListItemDeleteIcon {
+  position: relative;
   float: left;
   line-height: normal;
-  margin-top: 7px;
+  margin-top: 15px;
+  margin-bottom: -15px;
   margin-right: 11px;
 }
-.mblListItemSpriteIcon {
-  position: absolute;
-  margin-top: 7px;
-  margin-left: 8px;
+.mblListItemIcon {
+  position: relative;
+  float: left;
+  line-height: normal;
+  margin-top: 15px;
+  margin-bottom: -15px;
+  margin-right: 11px;
 }
-.mblListItemRightIcon, .mblListItemRightIcon2 {
+.mblListItemRightIcon,
+.mblListItemRightIcon2,
+.mblListItemUncheckIcon {
   position: relative;
   float: right;
   line-height: normal;
-  margin-top: 7px;
-  margin-bottom: -7px;
+  margin-top: 15px;
+  margin-bottom: -15px;
 }
 .mblListItemRightText {
   position: relative;
   float: right;
   line-height: normal;
+  margin-right: 4px;
   color: black;
-  margin: 11px 4px 0 0;
+  margin-top: 19px;
 }
-.mblListItemTextBox {
+.mblListItemLabel {
+  position: relative;
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
+  height: 100%;
 }
-.mblVariableHeight .mblListItemTextBox {
+.mblVariableHeight .mblListItemLabel {
   white-space: normal;
 }
 .mblListItemSubText {
   font-size: 14px;
-  color: #7B7D48;
+  color: #7b7d48;
+}
+.mblListItemLayoutLeft {
+  position: relative;
+  float: left;
+  margin-right: 11px;
+}
+.mblListItemLayoutCenter {
+  position: absolute;
+  width: 100%;
+  text-align: center;
+}
+.mblListItemLayoutRight {
+  position: relative;
+  float: right;
+}
+/* dojox.mobile._EditableListMixin */
+.mblListItemFloat {
+  position: absolute;
+  border: 1px solid gray;
+  opacity: 0.5;
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  border-radius: 0px !important;
+  -moz-border-radius: 0px !important;
 }
diff --git a/dojox/mobile/themes/blackberry/ListItem_rtl-compat.css b/dojox/mobile/themes/blackberry/ListItem_rtl-compat.css
new file mode 100644
index 0000000..f7deb99
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ListItem_rtl-compat.css
@@ -0,0 +1 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl-compat.css");
diff --git a/dojox/mobile/themes/blackberry/ListItem_rtl.css b/dojox/mobile/themes/blackberry/ListItem_rtl.css
new file mode 100644
index 0000000..2987450
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ListItem_rtl.css
@@ -0,0 +1,29 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl.css");
+
+ at import url("../common/domButtons/DomButtonDarkBlueCheck_rtl.css");
+/* dojox.mobile.ListItem Rtl*/
+.mblListItemRtl .mblListItemDeleteIcon {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemIcon {
+  float: right;
+  margin-left: 11px;
+  margin-right: 0px;
+}
+.mblListItemRtl .mblListItemRightIcon,
+.mblListItemRtl .mblListItemRightIcon2,
+.mblListItemRtl .mblListItemUncheckIcon {
+  float: left;
+}
+.mblListItemRtl .mblListItemRightText {
+  float: left;
+  margin-left: 4px;
+}
+.mblListItemRtl .mblListItemLayoutLeft {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemLayoutRight {
+  float: left;
+}
diff --git a/dojox/mobile/themes/blackberry/ListItem_rtl.less b/dojox/mobile/themes/blackberry/ListItem_rtl.less
new file mode 100644
index 0000000..3d3e9eb
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ListItem_rtl.less
@@ -0,0 +1,4 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck_rtl.css");
+
+ at import "../common/ListItem_rtl.less";
diff --git a/dojox/mobile/themes/blackberry/Overlay-compat.css b/dojox/mobile/themes/blackberry/Overlay-compat.css
index 3bc72a3..4d4216c 100644
--- a/dojox/mobile/themes/blackberry/Overlay-compat.css
+++ b/dojox/mobile/themes/blackberry/Overlay-compat.css
@@ -1,13 +1,14 @@
 /* dojox.mobile.Overlay */
 .mblOverlay {
-	_position: absolute;
-	text-align: center;
+  text-align: center;
 }
 .dj_gecko .mblOverlay {
-	text-align: -moz-center;
+  text-align: -moz-center;
 }
 .dj_ie9 .mblOverlay > *,
-.dj_ie8 .mblOverlay > *
-{
-	margin: 0 auto;
+.dj_ie8 .mblOverlay > * {
+  margin: 0 auto;
+}
+.dj_ie6 .mblOverlay {
+  *position: absolute;
 }
diff --git a/dojox/mobile/themes/blackberry/Overlay.css b/dojox/mobile/themes/blackberry/Overlay.css
index 0073339..94a6c2c 100644
--- a/dojox/mobile/themes/blackberry/Overlay.css
+++ b/dojox/mobile/themes/blackberry/Overlay.css
@@ -13,6 +13,7 @@
   background-color: #000000;
   background-image: none;
 }
-.mblOverlayHidden *, .mblOverlayHidden {
+.mblOverlayHidden *,
+.mblOverlayHidden {
   visibility: hidden !important;
 }
diff --git a/dojox/mobile/themes/blackberry/PageIndicator-compat.css b/dojox/mobile/themes/blackberry/PageIndicator-compat.css
new file mode 100644
index 0000000..50412f7
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/PageIndicator-compat.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.PageIndicator */
+.mblPageIndicatorDot {
+	-moz-border-radius: 3px;
+}
diff --git a/dojox/mobile/themes/blackberry/PageIndicator.css b/dojox/mobile/themes/blackberry/PageIndicator.css
index a175ad6..c4384f3 100644
--- a/dojox/mobile/themes/blackberry/PageIndicator.css
+++ b/dojox/mobile/themes/blackberry/PageIndicator.css
@@ -16,8 +16,7 @@
   height: 6px;
   font-size: 1px;
   background-color: #949294;
-  -webkit-border-radius: 3px;
-  -moz-border-radius: 3px;
+  border-radius: 3px;
 }
 .mblPageIndicatorDotSelected {
   background-color: white;
diff --git a/dojox/mobile/themes/blackberry/PageIndicator.less b/dojox/mobile/themes/blackberry/PageIndicator.less
deleted file mode 100644
index 9bb6c49..0000000
--- a/dojox/mobile/themes/blackberry/PageIndicator.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/PageIndicator.less";
diff --git a/dojox/mobile/themes/blackberry/ProgressBar-compat.css b/dojox/mobile/themes/blackberry/ProgressBar-compat.css
new file mode 100644
index 0000000..c33f113
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ProgressBar-compat.css
@@ -0,0 +1,5 @@
+/* Progress Bar */
+.dj_gecko .mblProgressBarProgress {
+  -moz-transition-property: width;
+  -moz-transition-duration: 0.25s;
+}
diff --git a/dojox/mobile/themes/blackberry/ProgressBar.css b/dojox/mobile/themes/blackberry/ProgressBar.css
new file mode 100644
index 0000000..59179ff
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ProgressBar.css
@@ -0,0 +1,29 @@
+/* dojox.mobile.ProgressBar */
+.mblProgressBar {
+  position: relative;
+  height: 22px;
+  background-color: white;
+  padding: 1px;
+}
+.mblProgressBarProgress {
+  -webkit-transition-property: width;
+  transition-property: width;
+  -webkit-transition-duration: 0.25s;
+  transition-duration: 0.25s;
+  background-color: #298eff;
+  height: 22px;
+}
+.mblProgressBarNotStarted {
+  border-left: none;
+  border-right: none;
+}
+.mblProgressBarMsg {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  text-align: center;
+  font-size: 12px;
+  top: 2px;
+  font-size: 18px;
+}
diff --git a/dojox/mobile/themes/blackberry/ProgressIndicator-compat.css b/dojox/mobile/themes/blackberry/ProgressIndicator-compat.css
index 4ee0810..cbabad7 100644
--- a/dojox/mobile/themes/blackberry/ProgressIndicator-compat.css
+++ b/dojox/mobile/themes/blackberry/ProgressIndicator-compat.css
@@ -1,46 +1,83 @@
 /* Progress Indicator */
-.mblProg {
-	position: absolute;
-	top: 0px;
-	width: 4px;
-	font-size: 1px;
-	height: 36px;
-	overflow: hidden;
-	background-color: #C0C0C0;
+.dj_ie .mblProg {
+  width: 4px;
+  height: 36px;
 }
-.mblProg0 {
-	left: 0px;
+.dj_ie .mblProg0 {
+  left: 0px;
 }
-.mblProg1 {
-	left: 8px;
+.dj_ie .mblProg1 {
+  left: 8px;
 }
-.mblProg2 {
-	left: 16px;
+.dj_ie .mblProg2 {
+  left: 16px;
 }
-.mblProg3 {
-	left: 24px;
+.dj_ie .mblProg3 {
+  left: 24px;
 }
-.mblProg4 {
-	left: 32px;
+.dj_ie .mblProg4 {
+  left: 32px;
 }
-.mblProg5 {
-	left: 40px;
+.dj_ie .mblProg5 {
+  left: 40px;
 }
-.mblProg6 {
-	left: 48px;
+.dj_ie .mblProg6 {
+  left: 48px;
 }
-.mblProg7 {
-	left: 56px;
+.dj_ie .mblProg7 {
+  left: 56px;
 }
-.mblProg8 {
-	left: 64px;
+.dj_ie .mblProg8 {
+  left: 64px;
 }
-.mblProg9 {
-	left: 72px;
+.dj_ie .mblProg9 {
+  left: 72px;
 }
-.mblProg10 {
-	left: 80px;
+.dj_ie .mblProg10 {
+  left: 80px;
 }
-.mblProg11 {
-	left: 80px;
+.dj_ie .mblProg11 {
+  left: 80px;
+}
+.dj_gecko .mblProgressIndicatorCenter .mblProgContainer {
+  -moz-transform-origin: 50% 0;
+}
+.dj_gecko .mblProg {
+  -moz-transform-origin: 0 2px;
+}
+.dj_gecko .mblProg0 {
+  -moz-transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.dj_gecko .mblProg1 {
+  -moz-transform: translate(22px, 11px) rotate(-60deg);
+}
+.dj_gecko .mblProg2 {
+  -moz-transform: translate(25px, 14px) rotate(-30deg);
+}
+.dj_gecko .mblProg3 {
+  -moz-transform: translate(26px, 18px) rotate(0deg);
+}
+.dj_gecko .mblProg4 {
+  -moz-transform: translate(25px, 22px) rotate(30deg);
+}
+.dj_gecko .mblProg5 {
+  -moz-transform: translate(22px, 25px) rotate(60deg);
+}
+.dj_gecko .mblProg6 {
+  -moz-transform: translate(18px, 26px) rotate(90.1deg);
+}
+.dj_gecko .mblProg7 {
+  -moz-transform: translate(14px, 25px) rotate(120deg);
+}
+.dj_gecko .mblProg8 {
+  -moz-transform: translate(11px, 22px) rotate(150deg);
+}
+.dj_gecko .mblProg9 {
+  -moz-transform: translate(10px, 18px) rotate(180deg);
+}
+.dj_gecko .mblProg10 {
+  -moz-transform: translate(11px, 14px) rotate(210deg);
+}
+.dj_gecko .mblProg11 {
+  -moz-transform: translate(14px, 11px) rotate(240deg);
 }
diff --git a/dojox/mobile/themes/blackberry/ProgressIndicator.css b/dojox/mobile/themes/blackberry/ProgressIndicator.css
index 2340637..17a8bda 100644
--- a/dojox/mobile/themes/blackberry/ProgressIndicator.css
+++ b/dojox/mobile/themes/blackberry/ProgressIndicator.css
@@ -1,11 +1,26 @@
 /* Progress Indicator */
+.mblProgressIndicator {
+  position: relative;
+  top: 0px;
+}
+.mblHeading .mblProgressIndicator {
+  margin: 5px;
+  float: left;
+}
 .mblProgContainer {
   position: absolute;
-  width: 40px;
-  height: 40px;
+  width: 100%;
+  height: 100%;
+}
+.mblProgressIndicatorCenter {
+  position: absolute;
   top: 180px;
   left: 50%;
-  margin: -18px 0px 0px -18px;
+}
+.mblProgressIndicatorCenter .mblProgContainer {
+  left: -50%;
+  -webkit-transform-origin: 50% 0;
+  transform-origin: 50% 0;
 }
 .mblProg {
   position: absolute;
@@ -16,43 +31,127 @@
   height: 4px;
   overflow: hidden;
   -webkit-transform-origin: 0 2px;
-  background-color: #C0C0C0;
-  -webkit-border-radius: 2px;
-  -moz-border-radius: 2px;
+  transform-origin: 0 2px;
+  background-color: #c0c0c0;
+  border-radius: 2px;
 }
 .mblProg0 {
   -webkit-transform: translate(18px, 10px) rotate(-90.1deg);
+  transform: translate(18px, 10px) rotate(-90.1deg);
 }
 .mblProg1 {
   -webkit-transform: translate(22px, 11px) rotate(-60deg);
+  transform: translate(22px, 11px) rotate(-60deg);
 }
 .mblProg2 {
   -webkit-transform: translate(25px, 14px) rotate(-30deg);
+  transform: translate(25px, 14px) rotate(-30deg);
 }
 .mblProg3 {
   -webkit-transform: translate(26px, 18px) rotate(0deg);
+  transform: translate(26px, 18px) rotate(0deg);
 }
 .mblProg4 {
   -webkit-transform: translate(25px, 22px) rotate(30deg);
+  transform: translate(25px, 22px) rotate(30deg);
 }
 .mblProg5 {
   -webkit-transform: translate(22px, 25px) rotate(60deg);
+  transform: translate(22px, 25px) rotate(60deg);
 }
 .mblProg6 {
   -webkit-transform: translate(18px, 26px) rotate(90.1deg);
+  transform: translate(18px, 26px) rotate(90.1deg);
 }
 .mblProg7 {
   -webkit-transform: translate(14px, 25px) rotate(120deg);
+  transform: translate(14px, 25px) rotate(120deg);
 }
 .mblProg8 {
   -webkit-transform: translate(11px, 22px) rotate(150deg);
+  transform: translate(11px, 22px) rotate(150deg);
 }
 .mblProg9 {
   -webkit-transform: translate(10px, 18px) rotate(180deg);
+  transform: translate(10px, 18px) rotate(180deg);
 }
 .mblProg10 {
   -webkit-transform: translate(11px, 14px) rotate(210deg);
+  transform: translate(11px, 14px) rotate(210deg);
 }
 .mblProg11 {
   -webkit-transform: translate(14px, 11px) rotate(240deg);
+  transform: translate(14px, 11px) rotate(240deg);
+}
+.mblProg0Color {
+  background-color: #c0c0c0;
+}
+.mblProg1Color {
+  background-color: #c0c0c0;
+}
+.mblProg2Color {
+  background-color: #c0c0c0;
+}
+.mblProg3Color {
+  background-color: #c0c0c0;
+}
+.mblProg4Color {
+  background-color: #c0c0c0;
+}
+.mblProg5Color {
+  background-color: #c0c0c0;
+}
+.mblProg6Color {
+  background-color: #b8b9b8;
+}
+.mblProg7Color {
+  background-color: #aeafae;
+}
+.mblProg8Color {
+  background-color: #a4a5a4;
+}
+.mblProg9Color {
+  background-color: #9a9a9a;
+}
+.mblProg10Color {
+  background-color: #8e8e8e;
+}
+.mblProg11Color {
+  background-color: #838383;
+}
+.mblProgWhite .mblProg0Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg1Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg2Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg3Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg4Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg5Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg6Color {
+  background-color: #acb9cb;
+}
+.mblProgWhite .mblProg7Color {
+  background-color: #b7c2d2;
+}
+.mblProgWhite .mblProg8Color {
+  background-color: #c4cdda;
+}
+.mblProgWhite .mblProg9Color {
+  background-color: #d1d8e2;
+}
+.mblProgWhite .mblProg10Color {
+  background-color: #dee3ea;
+}
+.mblProgWhite .mblProg11Color {
+  background-color: #eceff3;
 }
diff --git a/dojox/mobile/themes/blackberry/ProgressIndicator.less b/dojox/mobile/themes/blackberry/ProgressIndicator.less
deleted file mode 100644
index 2ab2a2d..0000000
--- a/dojox/mobile/themes/blackberry/ProgressIndicator.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ProgressIndicator.less";
diff --git a/dojox/mobile/themes/blackberry/RadioButton-compat.css b/dojox/mobile/themes/blackberry/RadioButton-compat.css
index 6f85871..8101c09 100644
--- a/dojox/mobile/themes/blackberry/RadioButton-compat.css
+++ b/dojox/mobile/themes/blackberry/RadioButton-compat.css
@@ -1,33 +1,32 @@
 /* dojox.mobile.RadioButton */
 .mblRadioButton {
-	background-image: url(compat/button-bg.png);
-	-moz-border-radius: 0.5em;
-	-o-border-radius: 0.5em;
-	-ms-border-radius: 0.5em;
-	border-radius: 0.5em;
-	-moz-appearance: none;
-	-o-appearance: none;
-	-ms-appearance: none;
-	appearance: none;
-	-o-transform: translateY(0.4em);
-	-ms-transform: translateY(0.4em);
-	transform: translateY(0.4em);
+  background-image: url(compat/button-bg.png);
 }
 .mblRadioButtonChecked,
 .mblRadioButton:checked {
-	background-image: url(compat/button-bg.png);
-}
-.mblRadioButtonChecked::after,
-.mblRadioButton:checked::after {
-	-moz-transform: rotate(45deg);
-	-o-transform: rotate(45deg);
-	-ms-transform: rotate(45deg);
-	transform: rotate(45deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
-}
-.mblRadioButtonChecked.mblRadioButtonSelected {
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: url(compat/blue-button-sel-bg.png);
+}
+.dj_gecko .mblRadioButton {
+  background-image: -moz-linear-gradient(top, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+  -moz-appearance: none;
+}
+.dj_gecko .mblRadioButtonChecked,
+.dj_gecko .mblRadioButton:checked {
+  background-image: -moz-linear-gradient(top, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.dj_gecko .mblRadioButtonChecked::after,
+.dj_gecko .mblRadioButton:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblRadioButtonChecked.mblRadioButtonSelected,
+.dj_gecko .mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_ff3 .mblRadioButton {
+  -moz-border-radius: 0.5em;
 }
diff --git a/dojox/mobile/themes/blackberry/RadioButton.css b/dojox/mobile/themes/blackberry/RadioButton.css
index f2a88c2..c15b755 100644
--- a/dojox/mobile/themes/blackberry/RadioButton.css
+++ b/dojox/mobile/themes/blackberry/RadioButton.css
@@ -1,41 +1,49 @@
 /* dojox.mobile.RadioButton */
 .mblRadioButton {
   position: relative;
-  cursor: pointer;
-  outline: none;
-  -webkit-appearance: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
   margin: -0.5em 3px 0.3em 4px;
   width: 1em;
   height: 1em;
-  border: #9CACC0 1px outset;
-  -webkit-border-radius: 0.5em;
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 0.5em;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
   font: inherit;
-  -webkit-transform: translatey(0.4em);
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  border-color: #9cacc0;
 }
-.mblRadioButtonChecked, .mblRadioButton:checked {
-  border-color: #9CACC0;
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
 }
-.mblRadioButtonChecked::after, .mblRadioButton:checked::after {
+.mblRadioButtonChecked::after,
+.mblRadioButton:checked::after {
   position: absolute;
   content: "";
   width: 0.3em;
   height: 0.6em;
   top: 0;
   left: 0.25em;
-  border-color: white;
   border-width: 0.15em;
   border-style: none solid solid none;
-  border-color: #0851AD;
   -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
   -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: #0851ad;
 }
-.mblRadioButtonChecked.mblRadioButtonSelected, .mblRadioButton:checked.mblRadioButtonSelected {
-  border-color: #9CACC0;
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
 }
-.mblRadioButtonChecked.mblRadioButtonSelected::after, .mblRadioButton:checked.mblRadioButtonSelected::after {
+.mblRadioButtonChecked.mblRadioButtonSelected::after,
+.mblRadioButton:checked.mblRadioButtonSelected::after {
   border-color: white;
 }
diff --git a/dojox/mobile/themes/blackberry/RadioButton.less b/dojox/mobile/themes/blackberry/RadioButton.less
deleted file mode 100644
index 0793ca6..0000000
--- a/dojox/mobile/themes/blackberry/RadioButton.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RadioButton.less";
diff --git a/dojox/mobile/themes/blackberry/RoundRect-compat.css b/dojox/mobile/themes/blackberry/RoundRect-compat.css
index 0643874..b9f7694 100644
--- a/dojox/mobile/themes/blackberry/RoundRect-compat.css
+++ b/dojox/mobile/themes/blackberry/RoundRect-compat.css
@@ -1,64 +1,73 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect.mblShadow {
+  box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.35);
+}
+.dj_ff3 .mblRoundRect {
+  -moz-border-radius: 6px;
+}
+.dj_ff3 .mblRoundRect.mblShadow {
+  -moz-box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.35);
+}
 /* Round Corner */
-.mblRoundCorner {
-	background-color: white;
-	height: 1px;
-	font-size: 1px;
-	overflow: hidden;
-	border-style: solid;
-	border-color: #C6C7C6;
-	border-width: 0px 1px;
-}
-.mblRoundRectContainer {
-	padding: 3px 8px;
-	background-color: white;
-	border-style: solid;
-	border-color: #C6C7C6;
-	border-width: 0px 1px;
-}
-.mblRoundRectList .mblRoundRectContainer {
-	margin: 0px;
-	padding: 0px;
-}
-.mblRoundCorner0T {
-	height: 0px;
-}
-.mblRoundCorner1T {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
-}
-.mblRoundCorner2T {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner3T {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4T {
-	margin: 0px 1px;
-}
-.mblRoundCorner5T {
-	margin: 0px 1px;
-}
-
-.mblRoundCorner0B {
-	height: 0px;
-}
-.mblRoundCorner1B {
-	margin: 0px 1px;
-}
-.mblRoundCorner2B {
-	margin: 0px 1px;
-}
-.mblRoundCorner3B {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4B {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner5B {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
+.dj_ie .mblRoundCorner {
+  background-color: #ffffff;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #c6c7c6;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: #ffffff;
+  border-style: solid;
+  border-color: #c6c7c6;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #c6c7c6;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #c6c7c6;
+  margin: 0 5px;
 }
diff --git a/dojox/mobile/themes/blackberry/RoundRect.css b/dojox/mobile/themes/blackberry/RoundRect.css
index a1f9991..705d86a 100644
--- a/dojox/mobile/themes/blackberry/RoundRect.css
+++ b/dojox/mobile/themes/blackberry/RoundRect.css
@@ -1,13 +1,13 @@
 /* dojox.mobile.RoundRect */
 .mblRoundRect {
-  margin: 2px 3px 4px;
+  margin: 7px 9px 16px;
   padding: 8px;
-  border: 1px solid #C6C7C6;
-  -webkit-border-radius: 6px;
-  -moz-border-radius: 6px;
+  border: 1px solid #c6c7c6;
+  border-radius: 6px;
+  background-color: #ffffff;
   color: black;
-  background-color: white;
 }
 .mblRoundRect.mblShadow {
   -webkit-box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.35);
+  box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.35);
 }
diff --git a/dojox/mobile/themes/blackberry/RoundRect.less b/dojox/mobile/themes/blackberry/RoundRect.less
deleted file mode 100644
index efec816..0000000
--- a/dojox/mobile/themes/blackberry/RoundRect.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRect.less";
diff --git a/dojox/mobile/themes/blackberry/RoundRectCategory-compat.css b/dojox/mobile/themes/blackberry/RoundRectCategory-compat.css
new file mode 100644
index 0000000..14c5fd7
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RoundRectCategory-compat.css
@@ -0,0 +1,5 @@
+/* dojox.mobile.RoundRectCategory */
+.mblRoundRectCategory {
+	-moz-border-radius-topleft: 6px;
+	-moz-border-radius-topright: 6px;
+}
diff --git a/dojox/mobile/themes/blackberry/RoundRectCategory.css b/dojox/mobile/themes/blackberry/RoundRectCategory.css
index bc46c98..4959d41 100644
--- a/dojox/mobile/themes/blackberry/RoundRectCategory.css
+++ b/dojox/mobile/themes/blackberry/RoundRectCategory.css
@@ -1,20 +1,12 @@
 /* dojox.mobile.RoundRectCategory */
 .mblRoundRectCategory {
+  margin: 18px 0 0 20px;
+  padding: 0;
+  font-family: Helvetica;
+  font-size: 16px;
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
-  padding: 0px 6px;
-  margin: 3px 9px 0px;
-  height: 29px;
-  font-family: Helvetica;
-  font-size: 16px;
-  color: #7B7D84;
-  line-height: 29px;
-  background-color: white;
-  border: 1px solid #ADAAAD;
-  border-bottom-width: 0px;
-  -webkit-border-top-left-radius: 6px;
-  -webkit-border-top-right-radius: 6px;
-  -moz-border-radius-topleft: 6px;
-  -moz-border-radius-topright: 6px;
+  color: black;
+  text-shadow: #ffffff 0 1px 0;
 }
diff --git a/dojox/mobile/themes/blackberry/RoundRectCategory.less b/dojox/mobile/themes/blackberry/RoundRectCategory.less
deleted file mode 100644
index e9148cc..0000000
--- a/dojox/mobile/themes/blackberry/RoundRectCategory.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRectCategory.less";
diff --git a/dojox/mobile/themes/blackberry/RoundRectCategory_rtl.css b/dojox/mobile/themes/blackberry/RoundRectCategory_rtl.css
new file mode 100644
index 0000000..2a7ffc3
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/RoundRectCategory_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.RoundRectCategory Rtl */
+.mblRoundRectCategoryRtl {
+  margin: 18px 20px 0px 0px;
+}
diff --git a/dojox/mobile/themes/blackberry/RoundRectList-compat.css b/dojox/mobile/themes/blackberry/RoundRectList-compat.css
index 0643874..bb63c7f 100644
--- a/dojox/mobile/themes/blackberry/RoundRectList-compat.css
+++ b/dojox/mobile/themes/blackberry/RoundRectList-compat.css
@@ -1,64 +1,78 @@
+/* dojox.mobile.RoundRectList */
+.dj_ff3 .mblRoundRectList {
+  -moz-border-radius: 6px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:first-child {
+  -moz-border-radius-topleft: 6px;
+  -moz-border-radius-topright: 6px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:last-child {
+  -moz-border-radius-bottomleft: 6px;
+  -moz-border-radius-bottomright: 6px;
+}
 /* Round Corner */
-.mblRoundCorner {
-	background-color: white;
-	height: 1px;
-	font-size: 1px;
-	overflow: hidden;
-	border-style: solid;
-	border-color: #C6C7C6;
-	border-width: 0px 1px;
-}
-.mblRoundRectContainer {
-	padding: 3px 8px;
-	background-color: white;
-	border-style: solid;
-	border-color: #C6C7C6;
-	border-width: 0px 1px;
-}
-.mblRoundRectList .mblRoundRectContainer {
-	margin: 0px;
-	padding: 0px;
-}
-.mblRoundCorner0T {
-	height: 0px;
-}
-.mblRoundCorner1T {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
-}
-.mblRoundCorner2T {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner3T {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4T {
-	margin: 0px 1px;
-}
-.mblRoundCorner5T {
-	margin: 0px 1px;
-}
-
-.mblRoundCorner0B {
-	height: 0px;
-}
-.mblRoundCorner1B {
-	margin: 0px 1px;
-}
-.mblRoundCorner2B {
-	margin: 0px 1px;
-}
-.mblRoundCorner3B {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4B {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner5B {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
+.dj_ie .mblRoundRectList {
+  position: relative;
+}
+.dj_ie .mblRoundCorner {
+  background-color: #ffffff;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #c6c7c6;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: #ffffff;
+  border-style: solid;
+  border-color: #c6c7c6;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #c6c7c6;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #c6c7c6;
+  margin: 0 5px;
 }
diff --git a/dojox/mobile/themes/blackberry/RoundRectList.css b/dojox/mobile/themes/blackberry/RoundRectList.css
index 2830ad3..137fd8b 100644
--- a/dojox/mobile/themes/blackberry/RoundRectList.css
+++ b/dojox/mobile/themes/blackberry/RoundRectList.css
@@ -1,39 +1,19 @@
 /* dojox.mobile.RoundRectList */
 .mblRoundRectList {
-  position: relative;
-  /* IE needs this */
-
-  margin: 3px 9px;
-  padding: 0px;
-  border: 1px solid #ADAAAD;
-  -webkit-border-radius: 6px;
-  -moz-border-radius: 6px;
-  background-color: white;
+  margin: 7px 9px 16px;
+  padding: 0;
+  border: 1px solid #c6c7c6;
+  border-radius: 6px;
+  background-color: #ffffff;
 }
-.mblRoundRectList .mblListItem:first-child {
-  border-top-width: 0px;
-  -webkit-border-top-left-radius: 6px;
-  -webkit-border-top-right-radius: 6px;
-  -moz-border-radius-topleft: 6px;
-  -moz-border-radius-topright: 6px;
+.mblRoundRectList .mblListItem:first-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:first-child {
+  border-top-left-radius: 6px;
+  border-top-right-radius: 6px;
 }
-.mblRoundRectList .mblListItem:last-child {
-  border-bottom-width: 0px;
-  -webkit-border-bottom-left-radius: 6px;
-  -webkit-border-bottom-right-radius: 6px;
-  -moz-border-radius-bottomleft: 6px;
-  -moz-border-radius-bottomright: 6px;
-}
-.mblRoundRectCategory + .mblRoundRectList {
-  margin-top: 0;
-  -webkit-border-top-left-radius: 0px;
-  -webkit-border-top-right-radius: 0px;
-  -moz-border-radius-topleft: 0px;
-  -moz-border-radius-topright: 0px;
-}
-.mblRoundRectCategory + .mblRoundRectList .mblListItem:first-child {
-  -webkit-border-top-left-radius: 0px;
-  -webkit-border-top-right-radius: 0px;
-  -moz-border-radius-topleft: 0px;
-  -moz-border-radius-topright: 0px;
+.mblRoundRectList .mblListItem:last-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 6px;
+  border-bottom-right-radius: 6px;
 }
diff --git a/dojox/mobile/themes/blackberry/RoundRectList.less b/dojox/mobile/themes/blackberry/RoundRectList.less
deleted file mode 100644
index 52e1164..0000000
--- a/dojox/mobile/themes/blackberry/RoundRectList.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRectList.less";
diff --git a/dojox/mobile/themes/blackberry/ScrollablePane.css b/dojox/mobile/themes/blackberry/ScrollablePane.css
new file mode 100644
index 0000000..573d58f
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ScrollablePane.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.mblScrollablePane */
+.mblScrollablePane {
+  position: relative;
+  overflow: hidden;
+}
+.mblScrollableViewContainer {
+  position: absolute;
+  top: 0px;
+}
+.mblScrollablePaneMask {
+  position: relative;
+}
diff --git a/dojox/mobile/themes/blackberry/SearchBox-compat.css b/dojox/mobile/themes/blackberry/SearchBox-compat.css
new file mode 100644
index 0000000..913c704
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/SearchBox-compat.css
@@ -0,0 +1,26 @@
+ at import url("TextBox-compat.css");
+/* dojox.mobile.SearchBox */
+.mblSearchBox {
+  height: auto;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  -moz-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/blackberry/SearchBox.css b/dojox/mobile/themes/blackberry/SearchBox.css
new file mode 100644
index 0000000..b18aecc
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/SearchBox.css
@@ -0,0 +1,61 @@
+ at import url("TextBox.css");
+/* dojox.mobile.SearchBox */
+.mblSearchBox.iphone4:focus::-webkit-search-cancel-button {
+  background: none !important;
+  border-color: transparent !important;
+}
+.mblSearchBox::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+  background-color: #000000;
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-size: 15px 15px;
+  background-image: -webkit-gradient(linear, left top, right bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #ffffff), color-stop(0.54, #ffffff), color-stop(0.54, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #ffffff), color-stop(0.54, #ffffff), color-stop(0.54, transparent), to(transparent)) !important;
+  border: 2px solid #000000;
+  box-sizing: border-box;
+  height: 15px;
+  width: 15px;
+  display: inline-block;
+  vertical-align: middle;
+  margin-left: 0.5em;
+  border-radius: 1em;
+}
+.mblSearchBox::-webkit-search-results-decoration {
+  -webkit-appearance: none;
+  background-repeat: no-repeat;
+  background-size: 13px 13px, 9px 9px;
+  background-position: 0px 0px, 10px 10px;
+  background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 6, from(transparent), color-stop(0.65, transparent), color-stop(0.8, #000000), color-stop(0.95, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.425, transparent), color-stop(0.5, #000000), color-stop(0.575, transparent), to(transparent)) !important;
+  width: 15px;
+  height: 15px;
+  display: inline-block;
+  vertical-align: middle;
+}
+.mblSearchBox {
+  height: auto;
+}
+.dj_chrome .mblSearchBox {
+  border-radius: 0;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/blackberry/SimpleDialog-compat.css b/dojox/mobile/themes/blackberry/SimpleDialog-compat.css
new file mode 100644
index 0000000..6b9e604
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/SimpleDialog-compat.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.SimpleDialog */
+.dj_ff3 .mblSimpleDialogDecoration {
+  -moz-border-radius: 6px;
+}
diff --git a/dojox/mobile/themes/blackberry/SimpleDialog.css b/dojox/mobile/themes/blackberry/SimpleDialog.css
new file mode 100644
index 0000000..0c12190
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/SimpleDialog.css
@@ -0,0 +1,42 @@
+/* dojox.mobile.SimpleDialog */
+.mblSimpleDialog {
+  position: absolute;
+  z-index: 100;
+  margin: 0;
+  text-align: center;
+  outline: none;
+  padding: 8px;
+  width: 262px;
+}
+.mblSimpleDialogDecoration {
+  border-radius: 6px;
+  background-color: #000000;
+  border: none;
+  color: white;
+}
+.mblSimpleDialogContainer {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.mblSimpleDialogCover {
+  background-color: #000000;
+  opacity: 0.5;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 99;
+}
+.mblSimpleDialogCloseBtn {
+  position: absolute !important;
+}
+.mblSimpleDialogTitle {
+  margin: 7px 0 14px;
+  width: 262px;
+}
+.mblSimpleDialogText {
+  margin: 7px 0 14px;
+  width: 262px;
+}
diff --git a/dojox/mobile/themes/blackberry/Slider-compat.css b/dojox/mobile/themes/blackberry/Slider-compat.css
index d3ae9b6..293247f 100644
--- a/dojox/mobile/themes/blackberry/Slider-compat.css
+++ b/dojox/mobile/themes/blackberry/Slider-compat.css
@@ -1,43 +1,40 @@
 /* dojox.mobile.Slider */
 .mblSlider {
-	background-image: url(compat/slider-h-bg.png);
-	-moz-border-radius: 6px;
-	-o-border-radius: 6px;
-	-ms-border-radius: 6px; 
-	border-radius: 6px;
-	-moz-user-select: none; /* prevent selection */
-	-o-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-	-moz-box-sizing: content-box; /* make width and height consistent with a DIV */
-	-o-box-sizing: content-box;
-	-ms-box-sizing: content-box;
-	box-sizing: content-box;
-}
-.mblSlider.mblSliderV {
-	background: #F7F3F7;
+  background-image: url(compat/slider-h-bg.png);
+  background-repeat: repeat-x;
 }
 .mblSliderProgressBar {
-	background-image: url(compat/slider-h-bar-bg.png);
-	background-repeat: repeat-x;
-	-moz-border-radius: 6px;
-	-o-border-radius: 6px;
-	-ms-border-radius: 6px; 
-	border-radius: 6px;
+  background-image: url(compat/slider-h-bar-bg.png);
+  background-repeat: repeat-x;
+}
+.mblSliderHandle {
+  background-image: url(compat/slider-handle-bg.png);
+}
+.mblSliderV {
+  background-color: #f7f3f7;
+  background-image: none;
 }
 .mblSliderV .mblSliderProgressBar {
-	background: #088EEF;
+  background-color: #088eef;
+  background-image: none;
 }
-.mblSliderHandle {
-	background-image: url(compat/slider-handle-bg.png);
-	-moz-border-radius: 6px;
-	-o-border-radius: 6px;
-	-ms-border-radius: 6px; 
-	border-radius: 6px;
-}
-.mblSliderTransition {
-	-moz-transition-duration: 400ms;
-	-o-transition-duration: 400ms;
-	-ms-transition-duration: 400ms;
-	transition-duration: 400ms;
+.dj_gecko .mblSlider {
+  background-image: -moz-linear-gradient(top, #f7f3f7 0%, #ced3ce 50%, #cec5d6 100%);
+  -moz-user-select: none;
+  -moz-box-sizing: content-box;
+}
+.dj_gecko .mblSliderProgressBar {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_gecko .mblSliderHandle {
+  background-image: -moz-linear-gradient(top, #fafafa 0%, #bbbbbb 50%, #999999 100%);
+}
+.dj_ff3 .mblSlider {
+  -moz-border-radius: 6px;
+}
+.dj_ff3 .mblSliderProgressBar {
+  -moz-border-radius: 6px;
+}
+.dj_ff3 .mblSliderHandle {
+  -moz-border-radius: 6px;
 }
diff --git a/dojox/mobile/themes/blackberry/Slider.css b/dojox/mobile/themes/blackberry/Slider.css
index 5e3c183..5c17a11 100644
--- a/dojox/mobile/themes/blackberry/Slider.css
+++ b/dojox/mobile/themes/blackberry/Slider.css
@@ -1,18 +1,16 @@
 /* dojox.mobile.Slider */
 .mblSlider {
-  outline: none;
-  -webkit-user-select: none;
-  /* prevent selection */
-
-  -webkit-box-sizing: content-box;
-  /* make width and height consistent with a DIV */
-
   margin: 15px;
-  /* 1/2 handle width for hanging off the ends of the bar */
-
-  border: #B0B0B0 1px inset;
+  border-style: inset;
+  border-width: 1px;
+  border-radius: 6px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f7f3f7), to(#cec5d6), color-stop(0.5, #ced3ce));
-  -webkit-border-radius: 6px;
+  background-image: linear-gradient(to bottom, #f7f3f7 0%, #ced3ce 50%, #cec5d6 100%);
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -webkit-box-sizing: content-box;
+  box-sizing: content-box;
+  border-color: #b0b0b0;
 }
 .mblSliderH {
   width: 200px;
@@ -35,19 +33,24 @@
   left: 50%;
 }
 .mblSliderProgressBar {
+  border-radius: 6px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
-  -webkit-border-radius: 6px;
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
 }
 .mblSliderHandle {
   margin: -10px 0 0 -10px;
   width: 18px;
   height: 18px;
-  border: #9D9D9D 1px outset;
-  -webkit-border-radius: 6px;
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 6px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fafafa), to(#999999), color-stop(0.5, #bbbbbb));
+  background-image: linear-gradient(to bottom, #fafafa 0%, #bbbbbb 50%, #999999 100%);
+  border-color: #9d9d9d;
 }
 .mblSliderTransition {
   -webkit-transition-duration: 400ms;
+  transition-duration: 400ms;
 }
 .mblSliderTouchBox {
   margin: 0;
diff --git a/dojox/mobile/themes/blackberry/Slider.less b/dojox/mobile/themes/blackberry/Slider.less
deleted file mode 100644
index 928972f..0000000
--- a/dojox/mobile/themes/blackberry/Slider.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Slider.less";
diff --git a/dojox/mobile/themes/blackberry/SpinWheel-compat.css b/dojox/mobile/themes/blackberry/SpinWheel-compat.css
new file mode 100644
index 0000000..4d605d5
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/SpinWheel-compat.css
@@ -0,0 +1,36 @@
+.mblSpinWheel {
+  background-image: url(../common/compat/spinwheel-bg.png);
+}
+.mblSpinWheelBar {
+  background-image: url(../common/compat/spinwheel-bar.png);
+}
+.mblSpinWheelSlotTouch,
+.mblSpinWheelSlotPanel {
+  left: 0;
+}
+.dj_gecko .mblSpinWheel {
+  background-image: -moz-linear-gradient(top, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+}
+.dj_gecko .mblSpinWheelBar {
+  background-image: -moz-linear-gradient(top, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 1%);
+}
+.dj_ff3 .mblSpinWheel {
+  -moz-border-radius: 3px;
+}
+.dj_ie .mblSpinWheelBar {
+  filter: progid:DXImageTransform.Microsoft.alpha(opacity=60);
+}
+.dj_ie6 .mblSpinWheelBar,
+.dj_ie7 .mblSpinWheelBar {
+  z-index: -1;
+}
+.dj_ie7 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
+.dj_ie6 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
diff --git a/dojox/mobile/themes/blackberry/SpinWheel.css b/dojox/mobile/themes/blackberry/SpinWheel.css
new file mode 100644
index 0000000..8764541
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/SpinWheel.css
@@ -0,0 +1,77 @@
+/* dojox.mobile.SpinWheel */
+.mblSpinWheel {
+  position: relative;
+  overflow: hidden;
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #313137), color-stop(0.05, #73747d), color-stop(0.07, #92939b), color-stop(0.09, #ababb5), color-stop(0.12, #c5c6ce), color-stop(0.16, #dfe0e4), color-stop(0.22, #f4f5f6), color-stop(0.35, #fbfcfc), color-stop(0.5, #fbfcfc), color-stop(0.61, #fbfcfc), color-stop(0.61, #b4c1c7), color-stop(0.65, #fbfcfc), color-stop(0.78, #f4f5f6), color-stop(0.84, #dfe0e4), color-stop(0.88, #c5c6ce), color-stop(0.91, #ababb5), co [...]
+  background: linear-gradient(to bottom, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+  height: 200px;
+  border-left: solid 3px #000000;
+  border-right: solid 3px #000000;
+  color: #000000;
+  border-radius: 3px;
+}
+.mblSpinWheelBar {
+  position: absolute;
+  top: 79px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#edeef2), to(#a7adca), color-stop(0, #edeef2), color-stop(0.25, #c8cadd), color-stop(0.49, #bbbfd4), color-stop(0.51, #9fa8c6), color-stop(0.81, #a2a9c7), color-stop(0.82, #a6abc9), color-stop(1, #a7adca));
+  background: linear-gradient(to bottom, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 100%);
+  border: solid 1px #7b8497;
+  height: 42px;
+  width: 100%;
+  clear: both;
+  opacity: 0.6;
+}
+.mblSpinWheelDatePicker {
+  width: 312px;
+}
+.mblSpinWheelTimePicker {
+  width: 98px;
+}
+.mblSpinWheelSlot {
+  position: relative;
+  top: 0px;
+  float: left;
+  width: 100px;
+  height: 100%;
+  border-left: solid 2px #000000;
+  border-right: solid 2px #000000;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblSpinWheelSlotLabel {
+  padding: 0 8px;
+  height: 44px;
+  overflow: hidden;
+  font: bold 24px/44px Helvetica, sans-serif;
+}
+.mblSpinWheelSlotLabel img {
+  vertical-align: middle;
+  opacity: 0.7;
+}
+.mblSpinWheelSlotLabelGray {
+  color: #cccccc;
+}
+.mblSpinWheelSlotLabelBlue {
+  color: #0959d2;
+}
+.mblSpinWheelSlotContainer {
+  position: relative;
+}
+.mblSpinWheelSlotPanel {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+}
+.mblSpinWheelSlotTouch {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  z-index: 1;
+}
+.dj_ie .mblSpinWheelSlotTouch {
+  background-color: rgba(255, 255, 255, 0.01);
+}
+.dj_ie8 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+}
diff --git a/dojox/mobile/themes/blackberry/SpinWheel_rtl-compat.css b/dojox/mobile/themes/blackberry/SpinWheel_rtl-compat.css
new file mode 100644
index 0000000..98aab55
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/SpinWheel_rtl-compat.css
@@ -0,0 +1,4 @@
+.mblSpinWheelSlotRtl .mblSpinWheelSlotTouch,
+.mblSpinWheelSlotRtl .mblSpinWheelSlotPanel {
+  right: 0;
+}
diff --git a/dojox/mobile/themes/blackberry/SpinWheel_rtl.css b/dojox/mobile/themes/blackberry/SpinWheel_rtl.css
new file mode 100644
index 0000000..c3efc85
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/SpinWheel_rtl.css
@@ -0,0 +1,5 @@
+/* dojox.mobile.SpinWheel Rtl */
+.mblSpinWheelSlotRtl,
+.mblSpinWheelRtl .mblSpinWheelSlot {
+  float: right;
+}
diff --git a/dojox/mobile/themes/blackberry/Switch-compat.css b/dojox/mobile/themes/blackberry/Switch-compat.css
index 3756d95..b9caf0d 100644
--- a/dojox/mobile/themes/blackberry/Switch-compat.css
+++ b/dojox/mobile/themes/blackberry/Switch-compat.css
@@ -1,70 +1,116 @@
-/* Switch - default */
-.mblSwitchBg {
-	border: none;
-}
-.mblSwitchBgLeft {
-	background: none;
-	background-image: url(compat/switch-default-l.gif);
-	background-repeat: no-repeat;
-}
-.mblSwitchBgRight {
-	background: none;
-	background-image: url(compat/switch-default-r.gif);
-	background-repeat: no-repeat;
-}
-.mblSwitchKnob {
-	top: 0px;
-	height: 27px;
-	background: none;
-	background-image: url(compat/switch-default-k.gif);
-	background-repeat: no-repeat;
-	border: none;
-}
-/* Switch - Round Shape1 */
+/* dojox.mobile.Switch */
+/* Switch - common */
+.dj_gecko .mblSwitchBg {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitchKnob {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitch .mblSwitchBgLeft {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_gecko .mblSwitch .mblSwitchBgRight {
+  background-image: -moz-linear-gradient(top, #f7f3f7 0%, #ced3ce 50%, #cec5d6 100%);
+}
+.dj_gecko .mblSwitch .mblSwitchKnob {
+  background-image: -moz-linear-gradient(top, #fafafa 0%, #bbbbbb 50%, #999999 100%);
+}
+.dj_ie .mblSwitchBg {
+  border: none;
+  background: none;
+}
+.dj_ie .mblSwitchBgLeft {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchBgRight {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchKnob {
+  background: none;
+  background-repeat: no-repeat;
+  border: none;
+}
+/* Square Shape */
+.mblSwSquareShape .mblSwitchBg {
+  -moz-border-radius: 6px;
+}
+.mblSwSquareShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-square-l.gif);
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchKnob {
+  -moz-border-radius: 6px;
+  background-image: url(compat/switch-square-k.gif);
+}
+/* Round Shape1 */
+.mblSwRoundShape1 .mblSwitchBg {
+  -moz-border-radius: 14px;
+}
 .mblSwRoundShape1 .mblSwitchBgLeft {
-	background-image: url(compat/switch-round-l.gif);
+  background-image: url(compat/switch-round1-l.gif);
 }
 .mblSwRoundShape1 .mblSwitchBgRight {
-	background-image: url(compat/switch-round-r.gif);
+  background-image: url(compat/switch-round1-r.gif);
 }
 .mblSwRoundShape1 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-round1-k.gif);
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round1-k.gif);
+}
+/* Round Shape2 */
+.mblSwRoundShape2 .mblSwitchBg {
+  -moz-border-radius: 14px;
 }
-/* Switch - Round Shape2 */
 .mblSwRoundShape2 .mblSwitchBgLeft {
-	background-image: url(compat/switch-round-l.gif);
+  background-image: url(compat/switch-round2-l.gif);
 }
 .mblSwRoundShape2 .mblSwitchBgRight {
-	background-image: url(compat/switch-round-r.gif);
+  background-image: url(compat/switch-round2-r.gif);
 }
 .mblSwRoundShape2 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-round2-k.gif);
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round2-k.gif);
+}
+/* Arc Shape1 */
+.mblSwArcShape1 .mblSwitchBg {
+  -moz-border-radius: 5px/14px;
 }
-/* Switch - Arc Shape1 */
 .mblSwArcShape1 .mblSwitchBgLeft {
-	background-image: url(compat/switch-arc-l.gif);
+  background-image: url(compat/switch-arc1-l.gif);
 }
 .mblSwArcShape1 .mblSwitchBgRight {
-	background-image: url(compat/switch-arc-r.gif);
+  background-image: url(compat/switch-arc1-r.gif);
 }
 .mblSwArcShape1 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-arc1-k.gif);
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc1-k.gif);
 }
 /* Switch - Arc Shape2 */
+.mblSwArcShape2 .mblSwitchBg {
+  -moz-border-radius: 5px/14px;
+}
 .mblSwArcShape2 .mblSwitchBgLeft {
-	background-image: url(compat/switch-arc-l.gif);
+  background-image: url(compat/switch-arc2-l.gif);
 }
 .mblSwArcShape2 .mblSwitchBgRight {
-	background-image: url(compat/switch-arc-r.gif);
+  background-image: url(compat/switch-arc2-r.gif);
 }
 .mblSwArcShape2 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-arc2-k.gif);
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc2-k.gif);
+}
+/* Default Shape */
+.mblSwDefaultShape .mblSwitchBg {
+  -moz-border-radius: 6px;
+}
+.mblSwDefaultShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-square-l.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  -moz-border-radius: 6px;
+  background-image: url(compat/switch-square-k.gif);
 }
diff --git a/dojox/mobile/themes/blackberry/Switch-compat.less b/dojox/mobile/themes/blackberry/Switch-compat.less
new file mode 100644
index 0000000..f15894c
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Switch-compat.less
@@ -0,0 +1,7 @@
+ at import "variables.less";
+ at import "../common/Switch-compat.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwSquareShape-styles;
+}
diff --git a/dojox/mobile/themes/blackberry/Switch.css b/dojox/mobile/themes/blackberry/Switch.css
index b8d62c7..6dfe248 100644
--- a/dojox/mobile/themes/blackberry/Switch.css
+++ b/dojox/mobile/themes/blackberry/Switch.css
@@ -1,18 +1,228 @@
- at import url("../common/Switch.css");
 /* dojox.mobile.Switch */
-.mblItemSwitch {
-  top: 14px;
+/* Switch - common */
+.mblSwitch {
+  margin: 0;
+  position: relative;
+  display: inline-block;
+  height: 27px;
+  line-height: 29px;
+  overflow: hidden;
+  text-align: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblListItem .mblSwitch {
+  position: absolute;
+  right: 12px;
+  top: 16px;
+}
+.mblSwitchInner {
+  position: absolute;
+  top: 0;
+  height: 27px;
+}
+.mblSwitchAnimation .mblSwitchInner {
+  -webkit-transition-property: left;
+  transition-property: left;
+  -webkit-transition-duration: 0.1s;
+  transition-duration: 0.1s;
+}
+.mblSwitchOn .mblSwitchInner {
+  left: 0;
 }
 .mblSwitchBg {
-  -webkit-border-radius: 6px;
+  position: absolute;
+  top: 0;
+  width: 94px;
+  height: 27px;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+  line-height: 29px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border: rgba(176, 176, 176, 0.5) 1px inset;
 }
 .mblSwitchBgLeft {
+  left: 0;
+  color: white;
+  background-color: #3f84eb;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
 }
 .mblSwitchBgRight {
+  color: #7f7f7f;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f7f3f7), to(#cec5d6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to bottom, #f7f3f7 0%, #ced3ce 50%, #cec5d6 100%);
 }
 .mblSwitchKnob {
+  position: absolute;
+  top: 0;
+  height: 27px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fafafa), to(#999999), color-stop(0.5, #bbbbbb));
-  -webkit-border-radius: 6px;
+  background-image: linear-gradient(to bottom, #fafafa 0%, #bbbbbb 50%, #999999 100%);
+  font-size: 1px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border: rgba(156, 172, 192, 0.5) 1px outset;
+}
+.mblSwitchText {
+  position: relative;
+  top: 0;
+  width: 53px;
+  height: 27px;
+  padding: 0;
+  line-height: 28px;
+  text-align: center;
+}
+.mblSwitchTextLeft {
+  left: 0;
+}
+.mblSwitchTextRight {
+  left: 40px;
+}
+/* Square Shape */
+.mblSwSquareShape {
+  width: 94px;
+}
+.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBg {
+  border-radius: 6px;
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+  width: 41px;
+  border-radius: 6px;
+}
+.mblSwSquareShape .mblSwitchText {
+  width: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRight {
+  left: 40px;
+}
+/* Round Shape1 */
+.mblSwRoundShape1 {
+  width: 77px;
+}
+.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwRoundShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 14px;
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 13px;
+}
+.mblSwRoundShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Round Shape2 */
+.mblSwRoundShape2 {
+  width: 94px;
+}
+.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBg {
+  border-radius: 14px;
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 13px;
+}
+.mblSwRoundShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Arc Shape1 */
+.mblSwArcShape1 {
+  width: 77px;
+}
+.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwArcShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 5px/14px;
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Arc Shape2 */
+.mblSwArcShape2 {
+  width: 94px;
+}
+.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBg {
+  border-radius: 5px/14px;
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Default Shape */
+.mblSwDefaultShape {
+  width: 94px;
+}
+.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: -53px;
+}
+.mblSwDefaultShape .mblSwitchBg {
+  border-radius: 6px;
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  left: 53px;
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  left: 53px;
+  width: 41px;
+  border-radius: 6px;
+}
+.mblSwDefaultShape .mblSwitchText {
+  width: 53px;
+}
+.mblSwDefaultShape .mblSwitchTextRight {
+  left: 40px;
 }
diff --git a/dojox/mobile/themes/blackberry/Switch.less b/dojox/mobile/themes/blackberry/Switch.less
index 84a1146..51d10ad 100644
--- a/dojox/mobile/themes/blackberry/Switch.less
+++ b/dojox/mobile/themes/blackberry/Switch.less
@@ -1,4 +1,7 @@
- at import url("../common/Switch.css");
-
 @import "variables.less";
 @import "../common/Switch.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwSquareShape-styles;
+}
diff --git a/dojox/mobile/themes/blackberry/Switch_rtl-compat.css b/dojox/mobile/themes/blackberry/Switch_rtl-compat.css
new file mode 100644
index 0000000..5293453
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Switch_rtl-compat.css
@@ -0,0 +1,43 @@
+/* dojox.mobile.Switch Rtl */
+/* Square Shape Rtl */
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
+/* Round Shape1 Rtl */
+.mblSwRoundShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round1-l.gif);
+}
+/* Round Shape2 Rtl */
+.mblSwRoundShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round2-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round2-l.gif);
+}
+/* Arc Shape1 Rtl */
+.mblSwArcShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc1-r.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc1-l.gif);
+}
+/* Switch - Arc Shape2 Rtl */
+.mblSwArcShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc2-r.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc2-l.gif);
+}
+/* Default Shape Rtl */
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
diff --git a/dojox/mobile/themes/blackberry/Switch_rtl.css b/dojox/mobile/themes/blackberry/Switch_rtl.css
new file mode 100644
index 0000000..5bb0935
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/Switch_rtl.css
@@ -0,0 +1,117 @@
+/* dojox.mobile.Switch Rtl */
+/* Switch - common Rtl */
+.mblSwitchRtl {
+  text-align: right;
+}
+.mblListItemRtl .mblSwitch {
+  left: 12px;
+  right: auto;
+}
+.mblSwitchRtl.mblSwitchOn .mblSwitchInner {
+  left: -50px;
+}
+.mblSwitchBgLeftRtl {
+  left: 51px;
+}
+.mblSwitchTextLeftRtl {
+  left: 0px;
+}
+.mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Square Shape Rtl*/
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Round Shape1 Rtl */
+.mblSwitchRtl.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Round Shape2 Rtl */
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Arc Shape1 Rtl */
+.mblSwitchRtl.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Arc Shape2 Rtl */
+.mblSwitchRtl.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Default Shape Rtl */
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwDefaultShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwDefaultShape .mblSwitchTextRightRtl {
+  left: -40px;
+}
diff --git a/dojox/mobile/themes/blackberry/TabBar-compat.css b/dojox/mobile/themes/blackberry/TabBar-compat.css
index c1944a5..d912143 100644
--- a/dojox/mobile/themes/blackberry/TabBar-compat.css
+++ b/dojox/mobile/themes/blackberry/TabBar-compat.css
@@ -1,49 +1,59 @@
-/* dojox.mobile.TabBarButton */
-.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
-	left: auto;
-}
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
+/* dojox.mobile.TabBar */
 .dj_ie6 .mblTabBar .mblTabBarButton {
-	display: inline; /* IE bug*/
-}
-.mblTabBarButtonIcon {
-	position: absolute;
-	top: 2px;
-	left: 0px;
-}
-.dj_gecko .mblTabBar .mblTabBarButton.mblTabButtonSelected {
-	-moz-border-radius: 3px;
-}
-.dj_gecko .mblTabPanelHeader .mblTabButton {
-	-moz-border-radius-topleft: 6px;
-	-moz-border-radius-topright: 6px;
-}
-*html .mblTabButton { /* IE6 hack */
-	behavior: expression(
-		(function(el){
-			if(!el.previousSibling)
-				el.style.borderWidth = "1px";
-			el.style.behavior = "none";
-		})(this)
-	);
-}
-.dj_ie6 .mblTabPanelHeader .mblDomButton {
-	left: 0px;
-}
-.mblTabButton img {
-	position: absolute;
-	left: 0px;
-	top: 0px;
-	margin-top: 8px;
-}
-.dj_gecko .mblHeading .mblTabPanelHeader .mblTabButton {
-	-moz-border-radius-topleft: 0px;
-	-moz-border-radius-topright: 0px;
-}
-.dj_gecko .mblHeading .mblTabPanelHeader .mblTabButton:first-child {
-	-moz-border-radius-topleft: 6px;
-	-moz-border-radius-bottomleft: 6px;
-}
-.dj_gecko .mblHeading .mblTabPanelHeader .mblTabButton:last-child {
-	-moz-border-radius-topright: 6px;
-	-moz-border-radius-bottomright: 6px;
+  display: inline;
+}
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  background-image: none;
+  background-color: #212421;
+}
+.dj_ff3 .mblTabBarTabBar .mblTabBarButtonSelected {
+  -moz-border-radius: 3px;
+}
+/* barType="segmentedControl" | "standardTab" */
+.mblTabBarSegmentedControl,
+.mblTabBarStandardTab {
+  background-image: url(compat/heading-bg.png);
+}
+.mblTabBarSegmentedControl .mblTabBarButton,
+.mblTabBarStandardTab .mblTabBarButton {
+  background-image: url(compat/tab-seg-button-bg.png);
+}
+.mblTabBarSegmentedControl .mblTabBarButtonSelected,
+.mblTabBarStandardTab .mblTabBarButtonSelected {
+  background-image: url(compat/tab-seg-sel-button-bg.png);
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:first-child {
+  -moz-border-radius-topleft: 6px;
+  -moz-border-radius-bottomleft: 6px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:last-child {
+  -moz-border-radius-topright: 6px;
+  -moz-border-radius-bottomright: 6px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButton {
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 4px;
+}
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  background-image: url(compat/tab-slim-bar-bg.png);
+}
+.dj_gecko .mblTabBarSlimTab {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.dj_gecko .mblTabBarSlimTab .mblTabBarButton {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.dj_gecko .mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-image: -moz-linear-gradient(top, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
+}
+/* barType="flatTab" */
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  background-image: url(compat/tab-tall-bar-bg.png);
+}
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-color: #8c8e8c;
 }
diff --git a/dojox/mobile/themes/blackberry/TabBar-compat.less b/dojox/mobile/themes/blackberry/TabBar-compat.less
new file mode 100644
index 0000000..c0476f3
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TabBar-compat.less
@@ -0,0 +1,3 @@
+ at import "variables.less";
+ at import "../common/TabBar-compat.less";
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
diff --git a/dojox/mobile/themes/blackberry/TabBar.css b/dojox/mobile/themes/blackberry/TabBar.css
index 06bc550..c1c01a2 100644
--- a/dojox/mobile/themes/blackberry/TabBar.css
+++ b/dojox/mobile/themes/blackberry/TabBar.css
@@ -1,164 +1,258 @@
+ at import "../common/domButtons/DomButtonWhiteCross.css";
 /* dojox.mobile.TabBar */
 .mblTabBar {
   position: relative;
+  margin: 0px;
   overflow: hidden;
   white-space: nowrap;
-  margin: 0px;
-  padding: 0px;
-  height: 48px;
-  border-top: 1px solid #000000;
-  background-color: #212421;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100c10));
-  color: white;
+  text-overflow: ellipsis;
+  padding: 0px 6px;
+  height: 42px;
   text-align: center;
-}
-.mblTabBarNoIcons {
-  height: 34px;
-}
-.mblTabBarNoText {
-  height: 34px;
+  color: white;
+  border-top: 1px solid #63696b;
+  border-bottom: 1px solid #292c31;
+  text-shadow: none;
 }
 /* dojox.mobile.TabBarButton */
+.mblTabBarFill .mblTabBarButton {
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
 .mblTabBarButton {
+  overflow: hidden;
   cursor: pointer;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-}
-.mblTabBar .mblTabBarButton {
   position: relative;
   list-style-type: none;
   float: left;
 }
-.mblTabBar .mblTabBarButton.mblTabButtonSelected {
-  background-color: #404040;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424), color-stop(0.5, #353535));
-  -webkit-border-radius: 3px;
+.mblTabBarButtonIconArea {
+  margin: 0 auto;
+  width: 29px;
 }
-.mblTabBarButtonAnchor {
+.mblTabBarButtonIconParent1 {
   display: block;
-  text-decoration: none;
 }
-.mblTabBarButtonDiv {
-  position: relative;
-  margin-left: auto;
-  margin-right: auto;
-  height: 34px;
-  width: 29px;
+.mblTabBarButtonIconParent2 {
+  display: none;
 }
-.mblTabBarButtonIcon {
-  position: absolute;
-  left: 0;
-  top: 0;
+.mblTabBarButtonSelected .mblTabBarButtonIconParent1 {
+  display: none;
 }
-.mblTabBarButtonSpriteIcon {
-  position: absolute;
+.mblTabBarButtonSelected .mblTabBarButtonIconParent2 {
+  display: block;
 }
-.mblTabBarButtonTextBox {
-  color: #979797;
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  height: 48px;
+  border-top: 1px solid #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100c10));
+  background-image: linear-gradient(to bottom, #181818 0%, #100c10 100%);
+}
+.mblTabBarTabBar .mblTabBarButtonIconArea {
+  padding-top: 4px;
+}
+.mblTabBarTabBar .mblTabBarButtonLabel {
   font-family: "Helvetica Neue", Helvetica;
   font-size: 11px;
+  color: #979797;
 }
-.mblTabBarNoIcons .mblTabBarButtonDiv {
-  display: none;
+.mblTabBarTabBar .mblTabBarButtonSelected {
+  border-radius: 3px;
+  background-color: #404040;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424), color-stop(0.5, #353535));
+  background-image: linear-gradient(to bottom, #484848 0%, #353535 50%, #242424 100%);
+}
+.mblTabBarTabBar .mblTabBarButtonSelected .mblTabBarButtonLabel {
+  color: white;
 }
-.mblTabBarNoIcons .mblTabBarButtonTextBox {
-  line-height: 34px;
-  font-size: 20px;
+/* barType="segmentedControl" */
+.mblTabBarSegmentedControl {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#4a4d52), to(#292c31));
+  background-image: linear-gradient(to bottom, #4a4d52 0%, #292c31 100%);
 }
-.mblTabBarTop .mblTabButton .mblTabBarButtonDiv {
-  height: 40px;
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButton {
+  width: auto;
+  padding: 0 3px;
 }
-.mblTabButton {
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconArea {
   position: relative;
-  float: left;
-  list-style-type: none;
-  cursor: pointer;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  width: 78px;
-  height: 61px;
-  border-width: 1px 1px 0px 1px;
-  border-style: solid;
-  border-color: #7B7D84 #182018 black #393C39;
-  background-color: #212421;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100c10), color-stop(0.1, #313031));
+}
+.mblTabBarSegmentedControl .mblTabBarButton {
+  margin: 6px 0;
+  width: 100px;
+  height: 29px;
+  border-width: 1px 1px 1px 0px;
   font-family: Helvetica;
   font-size: 13px;
-  color: #979797;
+  font-weight: bold;
   text-align: center;
+  line-height: 29px;
+  border-style: solid;
+  border-color: #7b7d84 #182018 black #393c39;
+  color: #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.mblTabBarSegmentedControl .mblTabBarButton:first-child {
+  border-left-width: 1px;
+  border-top-left-radius: 6px;
+  border-bottom-left-radius: 6px;
 }
-.mblTabButton img {
+.mblTabBarSegmentedControl .mblTabBarButton:last-child {
+  border-top-right-radius: 6px;
+  border-bottom-right-radius: 6px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconArea {
   position: absolute;
+  top: 0px;
   left: 0px;
-  margin-top: 8px;
 }
-.mblTabButtonSelected .mblTabBarButtonTextBox {
-  color: white;
+.mblTabBarSegmentedControl .mblTabBarButtonSelected {
+  color: #ffffff;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
 }
-.mblTabButtonImgDiv {
-  position: relative;
-  margin-left: 24px;
-  height: 40px;
+.mblHeading .mblTabBarSegmentedControl {
+  display: inline;
+  float: left;
+  height: auto;
+  border: none;
 }
-.mblTabPanelHeader {
-  position: relative;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  margin: 0px;
-  padding: 0px 0px 0px 0px;
-  height: 64px;
-  border-top: 1px solid #CDD5DF;
-  border-bottom: 2px solid #949694;
+/* barType="standardTab" */
+.mblTabBarStandardTab {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#4a4d52), to(#292c31));
+  background-image: linear-gradient(to bottom, #4a4d52 0%, #292c31 100%);
+}
+.mblTabBarStandardTab .mblTabBarButton {
+  margin-top: 9px;
+  padding: 9px;
+  border: 1px solid #62676d;
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  color: #000000;
+  background-color: #ced3ce;
+  /* TODO: to compat */
+
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.mblTabBarStandardTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 3px;
+  left: 0px;
+}
+.mblTabBarStandardTab .mblTabBarButtonSelected {
+  color: #ffffff;
+  background-color: #0869c6;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.mblTabBarStandardTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  height: 30px;
+  padding: 0px;
+  border: 1px solid #292c31;
   background-color: #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.mblTabBarSlimTab .mblTabBarButton {
+  padding: 7px;
+  border-right: 1px solid #4e4e4e;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
   font-family: Helvetica;
-  font-size: 20px;
+  font-size: 14px;
+  font-weight: bold;
   color: white;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
   text-align: center;
 }
-.mblTabPanelHeader .mblTabButton {
-  margin-top: 3px;
-  -webkit-border-top-left-radius: 6px;
-  -webkit-border-top-right-radius: 6px;
+.mblTabBarSlimTab .mblTabBarButton:first-child {
+  border-left: 1px solid #4e4e4e;
 }
-.mblTabPanelHeader .mblTabButton.mblTabButtonSelected {
-  background-color: #404040;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424), color-stop(0.5, #353535));
-  color: white;
+.mblTabBarSlimTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
 }
-.mblTabPanelHeader .mblTabButtonDomButton {
-  width: 43px;
+.mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-color: #404040;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#313031), to(#959595), color-stop(0.5, #5a555a), color-stop(0.5, #616161));
+  background-image: linear-gradient(to bottom, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
 }
-.mblTabPanelHeader .mblTabButtonDomButtonClass {
-  left: 8px;
+.mblTabBarSlimTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
 }
-.mblHeading .mblTabPanelHeader {
-  height: 38px;
+/* barType="flatTab" */
+.mblTabBarFlatTab {
+  height: 30px;
+  padding: 0px;
+  border-style: none;
+  background-color: transparent;
+  background-image: none;
 }
-.mblHeading .mblTabPanelHeader .mblTabButton {
-  margin: 5px 0;
-  height: 28px;
-  border-width: 0px 1px 0px 0px;
-  border-style: solid;
-  border-color: #39454A;
-  -webkit-border-top-left-radius: 0;
-  -webkit-border-top-right-radius: 0;
-  background-color: #CED3CE;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+.mblTabBarFlatTab .mblTabBarButton {
+  padding: 7px;
+  background-image: none;
+  font-family: Helvetica;
   font-size: 14px;
   font-weight: bold;
-  line-height: 30px;
-  color: black;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
+  text-align: center;
 }
-.mblHeading .mblTabPanelHeader .mblTabButton:first-child {
-  -webkit-border-top-left-radius: 6px;
-  -webkit-border-bottom-left-radius: 6px;
+.mblTabBarFlatTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
 }
-.mblHeading .mblTabPanelHeader .mblTabButton:last-child {
-  -webkit-border-top-right-radius: 6px;
-  -webkit-border-bottom-right-radius: 6px;
-  border-right: none;
+.mblTabBarFlatTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
 }
-.mblHeading .mblTabPanelHeader .mblTabButtonSelected {
-  background-color: #0869C6;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  height: 64px;
+  border-top: 1px solid #cdd5df;
+  border-bottom: 2px solid #949694;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #000000 100%);
+}
+.mblTabBarTallTab .mblTabBarButton {
+  margin-top: 3px;
+  margin-right: 2px;
+  width: 78px;
+  height: 61px;
+  border-width: 0px 1px 0px 1px;
+  border-style: solid;
+  border-color: black #182018 black #393c39;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100c10), color-stop(0.1, #313031));
+  background-image: linear-gradient(to bottom, #181818 0%, #313031 10%, #100c10 100%);
+  font-family: Helvetica;
+  font-size: 13px;
   color: white;
+  text-align: center;
+  background-color: #212421;
+  background-image: none;
+}
+.mblTabBarTallTab .mblTabBarButtonIconArea {
+  margin-top: 8px;
+}
+.mblTabBarTallTab .mblTabBarButtonLabel {
+  font-family: "Helvetica Neue", Helvetica;
+  font-size: 11px;
+}
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#a59ea5), to(#848284));
+  background-image: linear-gradient(to bottom, #a59ea5 0%, #848284 100%);
+  background-color: #636363;
+  background-image: none;
 }
diff --git a/dojox/mobile/themes/blackberry/TabBar.less b/dojox/mobile/themes/blackberry/TabBar.less
index 4875c40..4066ecc 100644
--- a/dojox/mobile/themes/blackberry/TabBar.less
+++ b/dojox/mobile/themes/blackberry/TabBar.less
@@ -1,2 +1,3 @@
 @import "variables.less";
 @import "../common/TabBar.less";
+ at import "../common/domButtons/DomButtonWhiteCross.css";
diff --git a/dojox/mobile/themes/blackberry/TabBar_rtl-compat.css b/dojox/mobile/themes/blackberry/TabBar_rtl-compat.css
new file mode 100644
index 0000000..3ca54bc
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TabBar_rtl-compat.css
@@ -0,0 +1,19 @@
+/* barType="segmentedControl" | "standardTab" Rtl */
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  -moz-border-radius-topright: 6px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-bottomright: 6px;
+  -moz-border-radius-bottomleft: 0px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  -moz-border-radius-topleft: 6px;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomleft: 6px;
+  -moz-border-radius-bottomright: 0px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButtonRtl {
+  -moz-border-radius-topright: 4px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 0px;
+}
diff --git a/dojox/mobile/themes/blackberry/TabBar_rtl.css b/dojox/mobile/themes/blackberry/TabBar_rtl.css
new file mode 100644
index 0000000..d9ca29b
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TabBar_rtl.css
@@ -0,0 +1,89 @@
+/* dojox.mobile.TabBarButton Rtl */
+.mblTabBarButtonRtl {
+  float: right;
+}
+.mblTabBarButtonIconAreaRtl {
+  margin: 0 auto;
+  width: 29px;
+}
+/* barType="tabBar" Rtl */
+.mblTabBarTabBar .mblTabBarButtonIconAreaRtl {
+  padding-top: 4px;
+}
+/* barType="segmentedControl" Rtl */
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconAreaRtl {
+  position: relative;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl {
+  border-width: 1px 0px 1px 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  border-right-width: 1px !important;
+  border-left-width: 0px;
+  border-top-right-radius: 6px;
+  border-top-left-radius: 0px;
+  border-bottom-right-radius: 6px;
+  border-bottom-left-radius: 0px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  border-top-left-radius: 6px;
+  border-top-right-radius: 0px;
+  border-bottom-left-radius: 6px;
+  border-bottom-right-radius: 0px;
+  border-left-width: 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblHeading .mblTabBarSegmentedControl.mblTabBarRtl {
+  float: right;
+}
+/* barType="standardTab" Rtl */
+.mblTabBarStandardTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 3px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarStandardTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="slimTab" Rtl */
+.mblTabBarSlimTab .mblTabBarButtonRtl {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl:first-child {
+  border-right: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="flatTab" Rtl*/
+.mblTabBarFlatTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarFlatTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab .mblTabBarButtonRtl {
+  margin-left: 2px;
+}
+.mblTabBarTallTab .mblTabBarButtonIconAreaRtl {
+  margin-top: 8px;
+}
diff --git a/dojox/mobile/themes/blackberry/TextArea-compat.css b/dojox/mobile/themes/blackberry/TextArea-compat.css
index c68fb12..361e2cd 100644
--- a/dojox/mobile/themes/blackberry/TextArea-compat.css
+++ b/dojox/mobile/themes/blackberry/TextArea-compat.css
@@ -1,7 +1,7 @@
 /* dojox.mobile.TextArea */
 .mblTextArea {
-	-moz-border-radius: 6px;
-	-o-border-radius: 6px;
-	-ms-border-radius: 6px;
-	border-radius: 6px;
+  overflow: auto;
+}
+.dj_ff3 .mblTextArea {
+  -moz-border-radius: 6px;
 }
diff --git a/dojox/mobile/themes/blackberry/TextArea.css b/dojox/mobile/themes/blackberry/TextArea.css
index a39e681..40dc2e9 100644
--- a/dojox/mobile/themes/blackberry/TextArea.css
+++ b/dojox/mobile/themes/blackberry/TextArea.css
@@ -1,12 +1,12 @@
 /* dojox.mobile.TextArea */
 .mblTextArea {
   padding: 4px 1px;
-  border-color: #9CACC0;
   border-width: 1px;
   border-style: inset;
-  -webkit-border-radius: 6px;
   font-family: Helvetica;
   font-size: 13px;
+  border-color: #9cacc0;
+  border-radius: 6px;
 }
 /* dojox.mobile.ExpandingTextArea */
 .mblExpandingTextArea {
diff --git a/dojox/mobile/themes/blackberry/TextArea.less b/dojox/mobile/themes/blackberry/TextArea.less
deleted file mode 100644
index c16ffe0..0000000
--- a/dojox/mobile/themes/blackberry/TextArea.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/TextArea.less";
diff --git a/dojox/mobile/themes/blackberry/TextBox-compat.css b/dojox/mobile/themes/blackberry/TextBox-compat.css
index 8672e5f..bdd2526 100644
--- a/dojox/mobile/themes/blackberry/TextBox-compat.css
+++ b/dojox/mobile/themes/blackberry/TextBox-compat.css
@@ -1,7 +1,4 @@
 /* dojox.mobile.TextBox */
-.mblTextBox {
-	-moz-border-radius: 6px;
-	-o-border-radius: 6px;
-	-ms-border-radius: 6px;
-	border-radius: 6px;
+.dj_ff3 .mblTextBox {
+  -moz-border-radius: 6px;
 }
diff --git a/dojox/mobile/themes/blackberry/TextBox.css b/dojox/mobile/themes/blackberry/TextBox.css
index 126bae9..7b104bb 100644
--- a/dojox/mobile/themes/blackberry/TextBox.css
+++ b/dojox/mobile/themes/blackberry/TextBox.css
@@ -1,8 +1,10 @@
 /* dojox.mobile.TextBox */
 .mblTextBox {
   height: 22px;
-  border: #9CACC0 1px inset;
-  -webkit-border-radius: 6px;
+  border-width: 1px;
+  border-style: inset;
   font-family: Helvetica;
   font-size: 13px;
+  border-color: #9cacc0;
+  border-radius: 6px;
 }
diff --git a/dojox/mobile/themes/blackberry/TextBox.less b/dojox/mobile/themes/blackberry/TextBox.less
deleted file mode 100644
index c83890a..0000000
--- a/dojox/mobile/themes/blackberry/TextBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/TextBox.less";
diff --git a/dojox/mobile/themes/blackberry/TimePicker.css b/dojox/mobile/themes/blackberry/TimePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/TimePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/blackberry/ToggleButton-compat.css b/dojox/mobile/themes/blackberry/ToggleButton-compat.css
index 2f5214b..644175c 100644
--- a/dojox/mobile/themes/blackberry/ToggleButton-compat.css
+++ b/dojox/mobile/themes/blackberry/ToggleButton-compat.css
@@ -1,31 +1,42 @@
 /* dojox.mobile.ToggleButton */
 .mblToggleButton {
-	background-image: url(compat/button-bg.png);
-	-moz-border-radius: 6px;
-	-o-border-radius: 6px;
-	-ms-border-radius: 6px;
-	border-radius: 6px;
+  background-image: url(compat/button-bg.png);
 }
 .mblToggleButtonSelected {
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/button-sel-bg.png);
 }
 .mblToggleButtonChecked {
-	background-image: url(compat/button-bg.png);
-}
-.mblToggleButton.mblToggleButtonChecked::after {
-	-moz-transform: translate(-25px,0px) rotate(45deg) skew(10deg);
-	-o-transform: rotate(45deg) skew(10deg);
-	-ms-transform: rotate(45deg) skew(10deg);
-	transform: rotate(45deg) skew(10deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
-	
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblToggleButton {
+  background-image: -moz-linear-gradient(top, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.dj_gecko .mblToggleButtonSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_gecko .mblToggleButtonChecked {
+  background-image: -moz-linear-gradient(top, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.dj_gecko .mblToggleButtonChecked:after {
+  -moz-transform: rotate(45deg) skew(10deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_ff3 .mblToggleButton {
+  -moz-border-radius: 6px;
 }
 .dj_ff3 .mblToggleButton.mblToggleButtonChecked::after {
-	-moz-transform: translate(-25px,-6px) rotate(45deg) skew(10deg);
+  -moz-transform: translate(-25px, -6px) rotate(45deg) skew(10deg);
 }
-.mblToggleButtonChecked.mblToggleButtonSelected {
-	background-image: url(compat/button-sel-bg.png);
+.dj_ie .mblToggleButtonChecked:after {
+  top: 9px;
+  left: 5px;
+  width: 12px;
+  border: none;
+  background-image: url(compat/togglebutton-chk-mark-bg.png);
 }
diff --git a/dojox/mobile/themes/blackberry/ToggleButton.css b/dojox/mobile/themes/blackberry/ToggleButton.css
index 0658f5f..ebadf49 100644
--- a/dojox/mobile/themes/blackberry/ToggleButton.css
+++ b/dojox/mobile/themes/blackberry/ToggleButton.css
@@ -1,52 +1,57 @@
 /* dojox.mobile.ToggleButton */
 .mblToggleButton {
   position: relative;
-  cursor: pointer;
-  outline: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  padding: 0px 10px 0px 25px;
+  padding: 0 10px 0 25px;
   height: 29px;
   border-width: 1px 1px 1px 1px;
   border-style: outset;
-  border-color: #9CACC0;
-  -webkit-border-radius: 6px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
   font-family: Helvetica;
+  line-height: 29px;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  border-color: #9cacc0;
+  border-radius: 6px;
   font-size: 16px;
   color: black;
-  line-height: 29px;
 }
-.mblToggleButton.mblToggleButtonSelected {
+.mblToggleButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
+}
+.mblToggleButtonSelected {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
   color: white;
 }
-.mblToggleButton.mblToggleButtonChecked {
+.mblToggleButtonChecked {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
   color: black;
 }
-.mblToggleButton.mblToggleButtonChecked::after {
+.mblToggleButtonChecked:after {
   position: absolute;
   content: "";
   top: 6px;
   left: 7px;
   width: 5px;
   height: 10px;
-  border-color: #0851AD;
   border-width: 2px;
   border-style: none solid solid none;
   -webkit-transform: rotate(45deg) skew(10deg);
+  transform: rotate(45deg) skew(10deg);
   -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: #0851ad;
 }
-.mblToggleButton.mblToggleButtonChecked.mblToggleButtonSelected {
+.mblToggleButtonChecked.mblToggleButtonSelected {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
   color: white;
 }
-.mblToggleButton.mblToggleButtonChecked.mblToggleButtonSelected::after {
+.mblToggleButtonChecked.mblToggleButtonSelected:after {
   border-color: white;
 }
-.mblToggleButton:disabled {
-  cursor: default;
-  border-color: grey;
-  background-image: none;
-  color: grey;
-}
diff --git a/dojox/mobile/themes/blackberry/ToggleButton.less b/dojox/mobile/themes/blackberry/ToggleButton.less
deleted file mode 100644
index bdce40f..0000000
--- a/dojox/mobile/themes/blackberry/ToggleButton.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ToggleButton.less";
diff --git a/dojox/mobile/themes/blackberry/ToggleButton_rtl.css b/dojox/mobile/themes/blackberry/ToggleButton_rtl.css
new file mode 100644
index 0000000..16d136f
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ToggleButton_rtl.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.ToggleButton Rtl */
+.mblToggleButtonRtl {
+  padding: 0 25px 0 10px!important;
+}
+.mblToggleButtonRtl.mblToggleButtonChecked:after {
+  right: 7px;
+}
diff --git a/dojox/mobile/themes/blackberry/ToolBarButton-compat.css b/dojox/mobile/themes/blackberry/ToolBarButton-compat.css
new file mode 100644
index 0000000..6ed2c8d
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ToolBarButton-compat.css
@@ -0,0 +1,63 @@
+/* dojox.mobile.ToolBarButton */
+.dj_gecko .mblToolBarButtonArrow {
+  -moz-transform: scale(0.77, 1.05) rotate(45deg);
+}
+.dj_ff3 .mblToolBarButtonArrow {
+  -moz-border-radius: 1px;
+}
+.dj_ff3 .mblToolBarButtonBody {
+  -moz-border-radius: 5px;
+}
+.dj_ff3 .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  -moz-border-radius-topleft: 0;
+  -moz-border-radius-bottomleft: 0;
+}
+.dj_ff3 .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 0;
+}
+.dj_ie .mblToolBarButtonLeftArrow {
+  top: 0;
+  left: -2px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonLeftArrow {
+  background-image: url(compat/arrow-button-head-sel.png);
+}
+.dj_ie .mblToolBarButtonRightArrow {
+  top: 0;
+  right: -3px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-right-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonRightArrow {
+  background-image: url(compat/arrow-button-right-head-sel.png);
+}
+.dj_ie .mblToolBarButtonBody {
+  background-image: url(compat/arrow-button-bg.png);
+  background-position: left bottom;
+}
+.dj_ie .mblToolBarButtonBodySelected {
+  background-image: url(compat/arrow-button-bg-sel.png);
+}
+.dj_ie .mblToolBarButtonBody table {
+  margin: 0;
+}
+.dj_ie .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.dj_ie .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.dj_ie6 .mblToolBarButton .mblToolBarButtonBody {
+  background-position: left top;
+}
diff --git a/dojox/mobile/themes/blackberry/ToolBarButton.css b/dojox/mobile/themes/blackberry/ToolBarButton.css
index 29c8284..05ef12d 100644
--- a/dojox/mobile/themes/blackberry/ToolBarButton.css
+++ b/dojox/mobile/themes/blackberry/ToolBarButton.css
@@ -1,27 +1,90 @@
 /* dojox.mobile.ToolBarButton */
 .mblToolBarButton {
-  float: left;
+  display: inline-block;
   position: relative;
-  overflow: hidden;
   cursor: pointer;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  margin: 4px 3px;
+  margin: 6px;
+  padding: 0 10px;
   height: 29px;
-  font-family: Helvetica;
-  font-size: 14px;
-  font-weight: bold;
   line-height: 29px;
   text-align: center;
-  -webkit-border-radius: 6px;
-  -moz-border-radius: 6px;
+  font-family: Helvetica;
+  font-size: 13px;
+  font-weight: bold;
+  vertical-align: middle;
 }
-.mblToolBarButtonIcon {
-  position: relative;
-  top: 1px;
+.mblToolBarButtonHasIcon,
+.mblToolBarButtonLightIcon {
+  padding: 0;
 }
-.mblToolBarButtonSpriteIcon {
+.mblHeading .mblToolBarButton {
+  float: left;
+}
+.mblHeading span.mblToolBarButtonLightIcon {
+  padding: 0;
+}
+.mblToolBarButtonHasLeftArrow {
+  padding-right: 0;
+  padding-left: 10px;
+}
+.mblToolBarButtonHasRightArrow {
+  padding-left: 0;
+  padding-right: 10px;
+}
+.mblToolBarButtonArrow {
   position: absolute;
+  top: 5px;
+  width: 20px;
+  height: 19px;
+  border-radius: 1px;
+  -webkit-transform: scale(0.7, 1) rotate(45deg);
+  transform: scale(0.7, 1) rotate(45deg);
+  border: 1px solid #9cacc0;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: 1px;
+  border: 1px inset #9cacc0;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: 0px;
+  border: 1px inset #9cacc0;
 }
-.mblToolBarButtonText {
-  padding: 0px 10px;
+.mblToolBarButtonBody {
+  display: inline-block;
+  position: relative;
+  overflow: hidden;
+  border-radius: 5px;
+  border: 1px outset #9cacc0;
+}
+.mblToolBarButton .mblToolBarButtonBody {
+  width: 100%;
+}
+.mblHeading .mblToolBarButtonBody {
+  border: 1px inset #9cacc0;
+}
+.mblToolBarButtonBody table {
+  margin: 0 auto;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-left-width: 0;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-right-width: 0;
+}
+.mblToolBarButtonText .mblToolBarButtonIcon {
+  padding-left: 10px;
+}
+.mblToolBarButtonText .mblToolBarButtonLabel {
+  padding-right: 10px;
+  height: 29px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonIcon {
+  padding-left: 4px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonLabel {
+  padding-right: 4px;
+}
+.mblToolBarButtonIcon > div {
+  height: 29px;
 }
diff --git a/dojox/mobile/themes/blackberry/ToolBarButton.less b/dojox/mobile/themes/blackberry/ToolBarButton.less
deleted file mode 100644
index 3b67bdc..0000000
--- a/dojox/mobile/themes/blackberry/ToolBarButton.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ToolBarButton.less";
diff --git a/dojox/mobile/themes/blackberry/ToolBarButton_rtl.css b/dojox/mobile/themes/blackberry/ToolBarButton_rtl.css
new file mode 100644
index 0000000..4c54f0d
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ToolBarButton_rtl.css
@@ -0,0 +1,18 @@
+/* dojox.mobile.ToolBarButton Rtl */
+.mblHeading .mblToolBarButtonRtl {
+  float: right;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonIcon {
+  padding-right: 10px;
+  padding-left: 0px;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonLabel {
+  padding-left: 10px;
+  padding-right: 0px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: 1px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: 0px;
+}
diff --git a/dojox/mobile/themes/blackberry/Tooltip-compat.css b/dojox/mobile/themes/blackberry/Tooltip-compat.css
index bb5900d..9a45de5 100644
--- a/dojox/mobile/themes/blackberry/Tooltip-compat.css
+++ b/dojox/mobile/themes/blackberry/Tooltip-compat.css
@@ -1,47 +1,40 @@
 /* dojox.mobile.Tooltip */
 .mblTooltip {
-	-moz-border-radius: 8px;
-	-o-border-radius: 8px;
-	-ms-border-radius: 8px;
-	border-radius: 8px;
-	background-image: none;
+  background-image: none;
 }
-.mblTooltipBefore .mblTooltipArrow {
-	*right: 0; /* IE 7 quirks */
-}
-.mblTooltipAbove .mblTooltipArrow {
-	*bottom: 0px; /* IE 7 quirks */
-}
-.mblTooltipBefore .mblTooltipInnerArrow {
-	*right: -1px; /* IE 7 quirks */
-}
-.mblTooltipAbove .mblTooltipInnerArrow {
-	*bottom: -1px;  /* IE 7 quirks */
-}
-.mblTooltipBefore .mblTooltipInnerArrow {
-	border-right-color: #424142;
-}
-.mblTooltipAfter .mblTooltipInnerArrow {
-	border-left-color: #424142;
-}
-.mblTooltipAbove .mblTooltipInnerArrow {
-	border-bottom-color: #424142;
-}
-.mblTooltipBelow .mblTooltipInnerArrow {
-	border-top-color: #424142;
-}
-.mblTooltip .mblHeading {
-	*padding: 0 9px 12px;
-	*border-top: 1px solid #424142;
-	*border-bottom: 1px solid #424142;
-	*width: auto;
-	*height: auto;
-	*overflow: visible;
-	*line-height: normal;
+.dj_ff3 .mblTooltip {
+  -moz-border-radius: 6px;
 }
 .dj_ie9 .mblTooltip .mblHeading {
-	width: auto;
-}
-.mblTooltip .mblHeading .mblToolBarButton {
-	*margin: auto 6px;
+  width: auto;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipArrow {
+  right: 0;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipArrow {
+  bottom: 0;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipInnerArrow {
+  right: -1px;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipInnerArrow {
+  bottom: -1px;
+}
+.dj_ie6 .mblTooltip .mblHeading,
+.dj_ie7 .mblTooltip .mblHeading {
+  padding: 0 9px 12px;
+  border-top: 1px solid #424142;
+  border-bottom: 1px solid #424142;
+  width: auto;
+  height: auto;
+  overflow: visible;
+  line-height: normal;
+}
+.dj_ie6 .mblTooltip .mblHeading .mblToolBarButton,
+.dj_ie7 .mblTooltip .mblHeading .mblToolBarButton {
+  margin: auto 6px;
 }
diff --git a/dojox/mobile/themes/blackberry/Tooltip.css b/dojox/mobile/themes/blackberry/Tooltip.css
index e94715c..60e12c9 100644
--- a/dojox/mobile/themes/blackberry/Tooltip.css
+++ b/dojox/mobile/themes/blackberry/Tooltip.css
@@ -5,11 +5,14 @@
   display: block;
   margin: 0;
   padding: 5px;
-  border: #ADAAAD 1px solid;
+  border-width: 1px;
+  border-style: solid;
+  opacity: .97;
+  border-color: #adaaad;
+  border-radius: 6px;
   background-color: #424142;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#4a4d52), to(#292c31));
-  -webkit-border-radius: 6px;
-  opacity: .97;
+  background-image: linear-gradient(to bottom, #4a4d52 0%, #292c31 100%);
 }
 .mblTooltipBubble {
   overflow: visible;
@@ -75,7 +78,7 @@
   top: 0;
   bottom: auto;
   border-left-width: 0;
-  border-right-color: #ADAAAD;
+  border-right-color: #adaaad;
 }
 .mblTooltipAfter .mblTooltipArrow {
   left: 1px;
@@ -83,7 +86,7 @@
   top: 0;
   bottom: auto;
   border-right-width: 0;
-  border-left-color: #ADAAAD;
+  border-left-color: #adaaad;
 }
 .mblTooltipAbove .mblTooltipArrow {
   top: auto;
@@ -91,7 +94,7 @@
   left: auto;
   right: auto;
   border-top-width: 0;
-  border-bottom-color: #ADAAAD;
+  border-bottom-color: #adaaad;
 }
 .mblTooltipBelow .mblTooltipArrow {
   top: 1px;
@@ -99,7 +102,7 @@
   left: auto;
   right: auto;
   border-bottom-width: 0;
-  border-top-color: #ADAAAD;
+  border-top-color: #adaaad;
 }
 .mblTooltipInnerArrow {
   position: absolute;
@@ -112,29 +115,34 @@
   right: 0;
   top: 0;
   border-left-width: 0;
-  border-right-color: #4A4D52;
+  border-right-color: #4a4d52;
 }
 .mblTooltipAfter .mblTooltipInnerArrow {
   left: 0;
   top: 0;
   border-right-width: 0;
-  border-left-color: #4A4D52;
+  border-left-color: #4a4d52;
 }
 .mblTooltipAbove .mblTooltipInnerArrow {
   bottom: 0;
   left: 0;
   border-top-width: 0;
-  border-bottom-color: #4A4D52;
+  border-bottom-color: #4a4d52;
 }
 .mblTooltipBelow .mblTooltipInnerArrow {
   top: 0;
   left: 0;
   border-bottom-width: 0;
-  border-top-color: #292C31;
+  border-top-color: #292c31;
 }
-.mblTooltipHidden, .mblTooltipHidden * {
+.mblTooltipHidden,
+.mblTooltipHidden * {
   visibility: hidden !important;
 }
+.mblTooltipHidden {
+  top: -99999px !important;
+  left: -99999px !important;
+}
 .mblTooltip .mblHeading {
   border-top: 1px solid transparent;
   border-bottom: 1px solid transparent;
diff --git a/dojox/mobile/themes/blackberry/Tooltip.less b/dojox/mobile/themes/blackberry/Tooltip.less
deleted file mode 100644
index 60af6d1..0000000
--- a/dojox/mobile/themes/blackberry/Tooltip.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Tooltip.less";
diff --git a/dojox/mobile/themes/blackberry/ValuePicker-compat.css b/dojox/mobile/themes/blackberry/ValuePicker-compat.css
new file mode 100644
index 0000000..1303dd3
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ValuePicker-compat.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.ValuePicker */
+.mblValuePickerSlotButton {
+  background-image: url(compat/valuepicker-button-bg.png);
+}
+.mblValuePickerSlotButtonSelected {
+  background-color: #0869c6;
+}
+.mblValuePickerSlotInputArea {
+  background-color: #f7f7f7;
+}
+.dj_gecko .mblValuePickerSlotButton {
+  background-image: -moz-linear-gradient(top, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.dj_gecko .mblValuePickerSlotButtonSelected {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_gecko .mblValuePickerSlotInputArea {
+  background-image: -moz-linear-gradient(top, #fafafa 10%, #fafafa 20%, #ffffff 50%, #ffffff 90%);
+}
diff --git a/dojox/mobile/themes/blackberry/ValuePicker.css b/dojox/mobile/themes/blackberry/ValuePicker.css
new file mode 100644
index 0000000..96b1703
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ValuePicker.css
@@ -0,0 +1,57 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+/* dojox.mobile.ValuePicker */
+.mblValuePicker {
+  height: 126px;
+}
+/* dojox.mobile.ValuePickerSlot */
+.mblValuePicker > .mblValuePickerSlot {
+  float: left;
+  margin: 0 5px;
+}
+.mblValuePickerSlotButton {
+  position: relative;
+  height: 38px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.mblValuePickerSlotPlusButton {
+  border-top-left-radius: 3px;
+  border-top-right-radius: 3px;
+}
+.mblValuePickerSlotMinusButton {
+  border-bottom-left-radius: 3px;
+  border-bottom-right-radius: 3px;
+}
+.mblValuePickerSlotButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.mblValuePickerSlotIcon {
+  top: 5px;
+  margin: 0 auto;
+}
+.mblValuePickerSlotInputArea {
+  position: relative;
+  height: 48px;
+  border-top: 1px solid #7b797b;
+  border-bottom: 1px solid #c6c3c6;
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.1, #fafafa), color-stop(0.2, #fafafa), color-stop(0.5, #ffffff), color-stop(0.9, #ffffff));
+  background-image: linear-gradient(to bottom, #fafafa 10%, #fafafa 20%, #ffffff 50%, #ffffff 90%);
+}
+.mblValuePickerSlotInput {
+  display: block;
+  width: 90%;
+  height: 90%;
+  margin: 5% auto;
+  padding: 0;
+  text-align: center;
+  border-style: none;
+  background-color: transparent;
+  font: 24px/44px Helvetica, sans-serif;
+}
+/* dojox.mobile.ValuePickerTimePicker */
+.mblValuePickerTimePicker > .mblToolBarButton {
+  top: 45px;
+}
diff --git a/dojox/mobile/themes/blackberry/ValuePicker.less b/dojox/mobile/themes/blackberry/ValuePicker.less
new file mode 100644
index 0000000..1561b85
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/ValuePicker.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+
+ at import "variables.less";
+ at import "../common/ValuePicker.less";
diff --git a/dojox/mobile/themes/blackberry/base-compat.css b/dojox/mobile/themes/blackberry/base-compat.css
index d12cf2b..3f7a03b 100644
--- a/dojox/mobile/themes/blackberry/base-compat.css
+++ b/dojox/mobile/themes/blackberry/base-compat.css
@@ -1,7 +1,9 @@
+ at import url("common-compat.css");
 @import url("Heading-compat.css");
+ at import url("ToolBarButton-compat.css");
 @import url("RoundRect-compat.css");
 @import url("RoundRectList-compat.css");
- at import url("EdgeToEdgeCategory-compat.css");
+ at import url("RoundRectCategory-compat.css");
 @import url("ListItem-compat.css");
 @import url("Switch-compat.css");
 @import url("ProgressIndicator-compat.css");
diff --git a/dojox/mobile/themes/blackberry/base_rtl-compat.css b/dojox/mobile/themes/blackberry/base_rtl-compat.css
new file mode 100644
index 0000000..71390e0
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/base_rtl-compat.css
@@ -0,0 +1,3 @@
+ at import url("ListItem_rtl-compat.css");
+
+ at import url("Switch_rtl-compat.css");
diff --git a/dojox/mobile/themes/blackberry/base_rtl.css b/dojox/mobile/themes/blackberry/base_rtl.css
new file mode 100644
index 0000000..16f6b6c
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/base_rtl.css
@@ -0,0 +1,7 @@
+ at import url("ToolBarButton_rtl.css");
+
+ at import url("RoundRectCategory_rtl.css");
+
+ at import url("ListItem_rtl.css");
+
+ at import url("Switch_rtl.css");
diff --git a/dojox/mobile/themes/blackberry/blackberry-compat.css b/dojox/mobile/themes/blackberry/blackberry-compat.css
index f5a0140..3d25bdd 100644
--- a/dojox/mobile/themes/blackberry/blackberry-compat.css
+++ b/dojox/mobile/themes/blackberry/blackberry-compat.css
@@ -2,17 +2,23 @@
 
 /* common styles */
 @import url("../common/domButtons-compat.css");
- at import url("../common/SpinWheel-compat.css");
 
 /* widget styles */
+ at import url("Accordion-compat.css");
 @import url("Button-compat.css");
 @import url("CheckBox-compat.css");
 @import url("ComboBox-compat.css");
 @import url("IconContainer-compat.css");
+ at import url("IconMenu-compat.css");
 @import url("Opener-compat.css");
+ at import url("PageIndicator-compat.css");
 @import url("RadioButton-compat.css");
+ at import url("SearchBox-compat.css");
+ at import url("SimpleDialog-compat.css");
 @import url("Slider-compat.css");
+ at import url("SpinWheel-compat.css");
 @import url("TabBar-compat.css");
 @import url("TextArea-compat.css");
 @import url("TextBox-compat.css");
 @import url("ToggleButton-compat.css");
+ at import url("ValuePicker-compat.css");
diff --git a/dojox/mobile/themes/blackberry/blackberry.css b/dojox/mobile/themes/blackberry/blackberry.css
index a50e0ce..0a3b95f 100644
--- a/dojox/mobile/themes/blackberry/blackberry.css
+++ b/dojox/mobile/themes/blackberry/blackberry.css
@@ -2,21 +2,29 @@
 
 /* common styles */
 @import url("../common/domButtons.css");
- at import url("../common/FixedSplitter.css");
- at import url("../common/SpinWheel.css");
 @import url("../common/transitions.css");
 
 /* widget styles */
+ at import url("Accordion.css");
 @import url("Button.css");
 @import url("Carousel.css");
 @import url("CheckBox.css");
 @import url("ComboBox.css");
+ at import url("FixedSplitter.css");
+ at import url("GridLayout.css");
 @import url("IconContainer.css");
+ at import url("IconMenu.css");
 @import url("Opener.css");
 @import url("PageIndicator.css");
+ at import url("ProgressBar.css");
 @import url("RadioButton.css");
+ at import url("ScrollablePane.css");
+ at import url("SearchBox.css");
+ at import url("SimpleDialog.css");
 @import url("Slider.css");
+ at import url("SpinWheel.css");
 @import url("TabBar.css");
 @import url("TextArea.css");
- at import url("TextBox.css");
 @import url("ToggleButton.css");
+ at import url("ValuePicker.css");
+ at import url("FormLayout.css");
diff --git a/dojox/mobile/themes/blackberry/blackberry_rtl-compat.css b/dojox/mobile/themes/blackberry/blackberry_rtl-compat.css
new file mode 100644
index 0000000..0143aa0
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/blackberry_rtl-compat.css
@@ -0,0 +1,7 @@
+ at import url("base_rtl-compat.css");
+
+ at import url("IconMenu_rtl-compat.css");
+
+ at import url("SpinWheel_rtl-compat.css");
+
+ at import url("TabBar_rtl-compat.css");
diff --git a/dojox/mobile/themes/blackberry/blackberry_rtl.css b/dojox/mobile/themes/blackberry/blackberry_rtl.css
new file mode 100644
index 0000000..f61e915
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/blackberry_rtl.css
@@ -0,0 +1,15 @@
+ at import url("base_rtl.css");
+
+ at import url("Carousel_rtl.css");
+
+ at import url("ComboBox_rtl.css");
+
+ at import url("IconContainer_rtl.css");
+
+ at import url("IconMenu_rtl.css");
+
+ at import url("SpinWheel_rtl.css");
+
+ at import url("TabBar_rtl.css");
+
+ at import url("ToggleButton_rtl.css");
diff --git a/dojox/mobile/themes/blackberry/common-compat.css b/dojox/mobile/themes/blackberry/common-compat.css
new file mode 100644
index 0000000..0f33c5e
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/common-compat.css
@@ -0,0 +1,18 @@
+.dj_gecko .mblColorBlue {
+  background-image: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblColorBlue45 {
+  background-image: -moz-linear-gradient(top left, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblColorDefault {
+  background-image: -moz-linear-gradient(top, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.dj_gecko .mblColorDefault45 {
+  background-image: -moz-linear-gradient(top left, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.dj_gecko .mblColorDefaultSel {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_gecko .mblColorDefaultSel45 {
+  background-image: -moz-linear-gradient(top left, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
diff --git a/dojox/mobile/themes/blackberry/common.css b/dojox/mobile/themes/blackberry/common.css
index 489bccb..002c9aa 100644
--- a/dojox/mobile/themes/blackberry/common.css
+++ b/dojox/mobile/themes/blackberry/common.css
@@ -1,29 +1,57 @@
-html.mobile, .mobile body {
+html.mobile,
+.mobile body {
   width: 100%;
-  margin: 0px;
-  padding: 0px;
+  margin: 0;
+  padding: 0;
 }
 .mobile body {
   overflow-x: hidden;
   -webkit-text-size-adjust: none;
-  background-color: #DEDFDE;
   font-family: Helvetica;
   font-size: 18px;
 }
+.mblBackground {
+  background-color: #dedfde;
+}
 /* Button Colors */
 .mblColorBlue {
-  color: white;
-  background-color: #215fdc;
+  color: #ffffff;
+  background-color: #366edf;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.mblColorBlue45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to right bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
 }
 /* Default Button Colors */
 .mblColorDefault {
-  color: black;
-  background-color: #CED3CE;
+  color: #000000;
+  background-color: #ced3ce;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+}
+.mblColorDefault45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
+  background-image: linear-gradient(to right bottom, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
 }
 .mblColorDefaultSel {
-  color: white;
-  background-color: #0869C6;
+  color: #ffffff;
+  background-color: #0869c6;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.mblColorDefaultSel45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to right bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.mblSpriteIcon {
+  position: absolute;
+}
+.mblSpriteIconParent {
+  position: relative;
+  font-size: 1px;
+}
+.mblImageIcon {
+  vertical-align: top;
 }
diff --git a/dojox/mobile/themes/blackberry/common.less b/dojox/mobile/themes/blackberry/common.less
deleted file mode 100644
index 4e57a5c..0000000
--- a/dojox/mobile/themes/blackberry/common.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/common.less";
diff --git a/dojox/mobile/themes/blackberry/compat/arrow-button-bg-sel.png b/dojox/mobile/themes/blackberry/compat/arrow-button-bg-sel.png
new file mode 100644
index 0000000..5b85b72
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/arrow-button-bg-sel.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/arrow-button-bg.png b/dojox/mobile/themes/blackberry/compat/arrow-button-bg.png
index 55a6e27..7871ed1 100644
Binary files a/dojox/mobile/themes/blackberry/compat/arrow-button-bg.png and b/dojox/mobile/themes/blackberry/compat/arrow-button-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/arrow-button-head-sel.png b/dojox/mobile/themes/blackberry/compat/arrow-button-head-sel.png
new file mode 100644
index 0000000..f10e271
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/arrow-button-head-sel.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/arrow-button-head.png b/dojox/mobile/themes/blackberry/compat/arrow-button-head.png
new file mode 100644
index 0000000..ac78b9e
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/arrow-button-head.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/arrow-button-right-head-sel.png b/dojox/mobile/themes/blackberry/compat/arrow-button-right-head-sel.png
new file mode 100644
index 0000000..068c601
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/arrow-button-right-head-sel.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/arrow-button-right-head.png b/dojox/mobile/themes/blackberry/compat/arrow-button-right-head.png
new file mode 100644
index 0000000..cc92700
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/arrow-button-right-head.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/blue-button-sel-bg.png b/dojox/mobile/themes/blackberry/compat/blue-button-sel-bg.png
new file mode 100644
index 0000000..4e7384a
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/blue-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/button-arrow-head-bg.gif b/dojox/mobile/themes/blackberry/compat/button-arrow-head-bg.gif
new file mode 100644
index 0000000..77b6e9e
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/button-arrow-head-bg.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/button-chk-bg.png b/dojox/mobile/themes/blackberry/compat/button-chk-bg.png
new file mode 100644
index 0000000..ba69969
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/button-chk-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/button-unsel-bg.png b/dojox/mobile/themes/blackberry/compat/button-unsel-bg.png
new file mode 100644
index 0000000..4e7384a
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/button-unsel-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/heading-bg.png b/dojox/mobile/themes/blackberry/compat/heading-bg.png
index f0546b4..847e1b3 100644
Binary files a/dojox/mobile/themes/blackberry/compat/heading-bg.png and b/dojox/mobile/themes/blackberry/compat/heading-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/red-button-sel-bg.png b/dojox/mobile/themes/blackberry/compat/red-button-sel-bg.png
new file mode 100644
index 0000000..4e7384a
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/red-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-arc-l.gif b/dojox/mobile/themes/blackberry/compat/switch-arc-l.gif
deleted file mode 100644
index 9abb5fb..0000000
Binary files a/dojox/mobile/themes/blackberry/compat/switch-arc-l.gif and /dev/null differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-arc-r.gif b/dojox/mobile/themes/blackberry/compat/switch-arc-r.gif
deleted file mode 100644
index a787840..0000000
Binary files a/dojox/mobile/themes/blackberry/compat/switch-arc-r.gif and /dev/null differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-arc1-k.gif b/dojox/mobile/themes/blackberry/compat/switch-arc1-k.gif
index 6a4e89d..e764aee 100644
Binary files a/dojox/mobile/themes/blackberry/compat/switch-arc1-k.gif and b/dojox/mobile/themes/blackberry/compat/switch-arc1-k.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-arc1-l.gif b/dojox/mobile/themes/blackberry/compat/switch-arc1-l.gif
new file mode 100644
index 0000000..0766ac7
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-arc1-l.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-arc1-r.gif b/dojox/mobile/themes/blackberry/compat/switch-arc1-r.gif
new file mode 100644
index 0000000..923321d
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-arc1-r.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-arc2-k.gif b/dojox/mobile/themes/blackberry/compat/switch-arc2-k.gif
index 5193586..b8bf081 100644
Binary files a/dojox/mobile/themes/blackberry/compat/switch-arc2-k.gif and b/dojox/mobile/themes/blackberry/compat/switch-arc2-k.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-arc2-l.gif b/dojox/mobile/themes/blackberry/compat/switch-arc2-l.gif
new file mode 100644
index 0000000..fc41078
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-arc2-l.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-arc2-r.gif b/dojox/mobile/themes/blackberry/compat/switch-arc2-r.gif
new file mode 100644
index 0000000..33276ec
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-arc2-r.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-default-k.gif b/dojox/mobile/themes/blackberry/compat/switch-default-k.gif
deleted file mode 100644
index 193cb73..0000000
Binary files a/dojox/mobile/themes/blackberry/compat/switch-default-k.gif and /dev/null differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-default-l.gif b/dojox/mobile/themes/blackberry/compat/switch-default-l.gif
deleted file mode 100644
index 1fb3013..0000000
Binary files a/dojox/mobile/themes/blackberry/compat/switch-default-l.gif and /dev/null differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-default-r.gif b/dojox/mobile/themes/blackberry/compat/switch-default-r.gif
deleted file mode 100644
index 6511b8b..0000000
Binary files a/dojox/mobile/themes/blackberry/compat/switch-default-r.gif and /dev/null differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round-l.gif b/dojox/mobile/themes/blackberry/compat/switch-round-l.gif
deleted file mode 100644
index ed34d5d..0000000
Binary files a/dojox/mobile/themes/blackberry/compat/switch-round-l.gif and /dev/null differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round-r.gif b/dojox/mobile/themes/blackberry/compat/switch-round-r.gif
deleted file mode 100644
index 3825e83..0000000
Binary files a/dojox/mobile/themes/blackberry/compat/switch-round-r.gif and /dev/null differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round1-k.gif b/dojox/mobile/themes/blackberry/compat/switch-round1-k.gif
index 8d00c11..a8eda43 100644
Binary files a/dojox/mobile/themes/blackberry/compat/switch-round1-k.gif and b/dojox/mobile/themes/blackberry/compat/switch-round1-k.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round1-l.gif b/dojox/mobile/themes/blackberry/compat/switch-round1-l.gif
new file mode 100644
index 0000000..6ea1c7a
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-round1-l.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round1-r.gif b/dojox/mobile/themes/blackberry/compat/switch-round1-r.gif
new file mode 100644
index 0000000..d9945c2
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-round1-r.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round2-k.gif b/dojox/mobile/themes/blackberry/compat/switch-round2-k.gif
index c4c7969..1b5cd80 100644
Binary files a/dojox/mobile/themes/blackberry/compat/switch-round2-k.gif and b/dojox/mobile/themes/blackberry/compat/switch-round2-k.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round2-l.gif b/dojox/mobile/themes/blackberry/compat/switch-round2-l.gif
new file mode 100644
index 0000000..0f40814
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-round2-l.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-round2-r.gif b/dojox/mobile/themes/blackberry/compat/switch-round2-r.gif
new file mode 100644
index 0000000..b27caeb
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-round2-r.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-square-k.gif b/dojox/mobile/themes/blackberry/compat/switch-square-k.gif
new file mode 100644
index 0000000..5168fe0
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-square-k.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-square-l.gif b/dojox/mobile/themes/blackberry/compat/switch-square-l.gif
new file mode 100644
index 0000000..dbc8ce6
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-square-l.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/switch-square-r.gif b/dojox/mobile/themes/blackberry/compat/switch-square-r.gif
new file mode 100644
index 0000000..8ce696a
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/switch-square-r.gif differ
diff --git a/dojox/mobile/themes/blackberry/compat/tab-seg-button-bg.png b/dojox/mobile/themes/blackberry/compat/tab-seg-button-bg.png
new file mode 100644
index 0000000..ac946ce
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/tab-seg-button-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/tab-seg-sel-button-bg.png b/dojox/mobile/themes/blackberry/compat/tab-seg-sel-button-bg.png
new file mode 100644
index 0000000..9960f1f
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/tab-seg-sel-button-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/tab-slim-bar-bg.png b/dojox/mobile/themes/blackberry/compat/tab-slim-bar-bg.png
new file mode 100644
index 0000000..f982afb
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/tab-slim-bar-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/tab-tall-bar-bg.png b/dojox/mobile/themes/blackberry/compat/tab-tall-bar-bg.png
new file mode 100644
index 0000000..50a2371
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/tab-tall-bar-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/togglebutton-chk-mark-bg.png b/dojox/mobile/themes/blackberry/compat/togglebutton-chk-mark-bg.png
new file mode 100644
index 0000000..ddb4d3c
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/togglebutton-chk-mark-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/compat/valuepicker-button-bg.png b/dojox/mobile/themes/blackberry/compat/valuepicker-button-bg.png
new file mode 100644
index 0000000..d66127f
Binary files /dev/null and b/dojox/mobile/themes/blackberry/compat/valuepicker-button-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/dijit/Calendar-compat.css b/dojox/mobile/themes/blackberry/dijit/Calendar-compat.css
new file mode 100644
index 0000000..9693cbb
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/dijit/Calendar-compat.css
@@ -0,0 +1,38 @@
+/* dijit.Calendar */
+.dijitCalendar thead {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-month-bg.png);
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-datelabel-sel-bg.png);
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-datelabel-sel-bg.png);
+}
+.dijitCalendarYearLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-year-bg.png);
+}
+.dj_gecko .dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  -moz-box-shadow: 0 0 0 transparent;
+}
+.dj_gecko .dijitCalendar thead {
+  background-image: -moz-linear-gradient(top, #63696b 0%, #182021 100%);
+}
+.dj_gecko .dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_gecko .dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dj_gecko .dijitCalendarYearLabel {
+  background-image: -moz-linear-gradient(top, #63696b 0%, #182021 100%);
+}
+.dj_ff3 .dijitCalendar {
+  -moz-border-radius: 0;
+}
+.dj_ff3 .dijitCalendarMonthMenu {
+  -moz-border-radius: 6px;
+}
diff --git a/dojox/mobile/themes/blackberry/dijit/Calendar-compat.less b/dojox/mobile/themes/blackberry/dijit/Calendar-compat.less
new file mode 100644
index 0000000..88cd6f0
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/dijit/Calendar-compat.less
@@ -0,0 +1,2 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar-compat.less";
diff --git a/dojox/mobile/themes/blackberry/dijit/Calendar.css b/dojox/mobile/themes/blackberry/dijit/Calendar.css
new file mode 100644
index 0000000..fedafc1
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/dijit/Calendar.css
@@ -0,0 +1,125 @@
+/* if you link this style sheet, dijit/themes/dijit.css must be imported. */
+/* dijit.Calendar */
+.dijitCalendar {
+  padding: 0;
+  width: 320px;
+  border-radius: 0;
+  text-align: center;
+  border: none 0 transparent;
+  background-color: white;
+}
+.dijitCalendar thead {
+  border-color: inherit;
+  vertical-align: middle;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#63696b), to(#182021));
+  background-image: linear-gradient(to bottom, #63696b 0%, #182021 100%);
+}
+.dijitCalendarMonthLabel {
+  padding: 0 4px;
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0 1px 0px;
+  color: white;
+  font-size: 18px;
+}
+.dijitCalendarMonthMenu {
+  border: 1px solid black;
+  border-radius: 6px;
+  background-color: white;
+}
+.dijitCalendarMonthMenu .dijitCalendarMonthLabel {
+  color: black;
+}
+.dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  padding: 0 3px 0 2px;
+  border: none;
+  background-color: transparent;
+  background-image: none;
+  -webkit-box-shadow: 0 0 0 transparent;
+  box-shadow: 0 0 0 transparent;
+}
+.dijitArrowButtonInner {
+  display: none;
+}
+.dijitCalendarMonthContainer th {
+  border-right: 1px solid transparent;
+}
+.dijitCalendarIncrementControl {
+  width: 0;
+  height: 0;
+  border: 6px solid transparent !important;
+}
+.dijitCalendarDecrease {
+  border-left-width: 0 !important;
+  border-right: 6px solid white !important;
+}
+.dijitCalendarIncrease {
+  border-right-width: 0 !important;
+  border-left: 6px solid white !important;
+}
+.dijitA11ySideArrow {
+  display: none;
+}
+.dijitCalendarDayLabelTemplate {
+  border-right: 1px solid transparent;
+  text-align: center;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  background-color: #6b7173;
+  font-size: 14px;
+  color: white;
+}
+.dijitCalendarDateTemplate {
+  border-bottom: 1px solid lightGrey;
+  font-family: Helvetica;
+  font-size: 22px;
+  font-weight: normal;
+  text-align: center;
+  border-right: 1px solid lightGrey;
+  background-color: white;
+  color: black;
+}
+.dijitCalendarDateTemplate:last-child {
+  border-right: none;
+}
+.dijitCalendarDateTemplate .dijitCalendarDateLabel {
+  padding: 3px 5px 3px 4px;
+  display: block;
+  text-decoration: none;
+  border: none;
+}
+.dijitCalendarPreviousMonth .dijitCalendarDateLabel,
+.dijitCalendarNextMonth .dijitCalendarDateLabel {
+  background-color: #cecbce;
+  color: #adaeb5;
+}
+.dijitCalendarHoveredDate .dijitCalendarDateLabel {
+  color: grey;
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
+  color: white;
+  text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0;
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
+  background-image: linear-gradient(to bottom, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+.dijitCalendarYearLabel {
+  margin: 0;
+  padding: 0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#63696b), to(#182021));
+  background-image: linear-gradient(to bottom, #63696b 0%, #182021 100%);
+}
+.dijitCalendarSelectedYear {
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  color: white;
+  font-size: 16px;
+}
+.dijitCalendarNextYear,
+.dijitCalendarPreviousYear {
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  padding: 1px 6px 3px 6px;
+  color: white;
+  font-size: 12px;
+}
diff --git a/dojox/mobile/themes/blackberry/dijit/Calendar.less b/dojox/mobile/themes/blackberry/dijit/Calendar.less
new file mode 100644
index 0000000..a590903
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/dijit/Calendar.less
@@ -0,0 +1,2 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar.less";
diff --git a/dojox/mobile/themes/blackberry/dijit/compat/calendar-datelabel-sel-bg.png b/dojox/mobile/themes/blackberry/dijit/compat/calendar-datelabel-sel-bg.png
new file mode 100644
index 0000000..8c0a35a
Binary files /dev/null and b/dojox/mobile/themes/blackberry/dijit/compat/calendar-datelabel-sel-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/dijit/compat/calendar-month-bg.png b/dojox/mobile/themes/blackberry/dijit/compat/calendar-month-bg.png
new file mode 100644
index 0000000..7ab7049
Binary files /dev/null and b/dojox/mobile/themes/blackberry/dijit/compat/calendar-month-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/dijit/compat/calendar-year-bg.png b/dojox/mobile/themes/blackberry/dijit/compat/calendar-year-bg.png
new file mode 100644
index 0000000..aed24d4
Binary files /dev/null and b/dojox/mobile/themes/blackberry/dijit/compat/calendar-year-bg.png differ
diff --git a/dojox/mobile/themes/blackberry/variables.less b/dojox/mobile/themes/blackberry/variables.less
index 90d6e4b..b07f65e 100644
--- a/dojox/mobile/themes/blackberry/variables.less
+++ b/dojox/mobile/themes/blackberry/variables.less
@@ -1,705 +1,447 @@
+ at import "../common/css3.less";
+
+ at default-blue-button-color: white;
+ at default-blue-button-background-color: #366edf;
+.default-blue-button-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#7a9de9, #2362dd, 0.5, #366edf, 0.5, #215fdc); }
+ at default-blue-button-background-image-gecko: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+
+.mbl-color-blue-45 () { .background-image-linear-gradient-top-left-bottom-right-2-stops(#7a9de9, #2362dd, 0.5, #366edf, 0.5, #215fdc); }
+.mbl-color-default-45 () { .background-image-linear-gradient-top-left-bottom-right-1-stop(#f7fbf7, #cecfd6, 0.5, #ced3ce); }
+.mbl-color-default-sel-45 () { .background-image-linear-gradient-top-left-bottom-right-1-stop(#088eef, #0851ad, 0.5, #0869c6); }
+
+ at mbl-color-blue-45-gecko: -moz-linear-gradient(top left, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+ at mbl-color-default-45-gecko: -moz-linear-gradient(top left, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+ at mbl-color-default-sel-45-gecko: -moz-linear-gradient(top left, #088eef 0%, #0869c6 50%, #0851ad 100%);
+
+ at default-button-color: black;
+ at default-button-background-color: #ced3ce;
+.default-button-background-image () { .background-image-linear-gradient-top-bottom-1-stop(#f7fbf7, #cecfd6, 0.5, #ced3ce); }
+ at default-button-background-image-gecko: -moz-linear-gradient(top, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+ at default-button-border-radius: 6px;
+
+ at default-button-selected-color: white;
+ at default-button-selected-background-color: #0869c6;
+.default-button-selected-background-image () { .background-image-linear-gradient-top-bottom-1-stop(#088eef, #0851ad, 0.5, #0869c6); }
+ at default-button-selected-background-image-gecko: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+
+ at default-selected-color: white;
+ at default-selected-background-color: #0869c6;
+.default-selected-background-image () { .background-image-linear-gradient-top-bottom-1-stop(#088eef, #0851ad, 0.5, #0869c6); }
+ at default-selected-background-image-gecko: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+
+ at heading-background-color: #424142;
+.heading-background-image () { .background-image-linear-gradient-top-bottom(#4a4d52, #292c31); }
+ at heading-background-image-gecko: -moz-linear-gradient(top, #4a4d52 0%, #292c31 100%);
+ at heading-border-top-color: #63696b;
+ at heading-border-bottom-color: #292c31;
+
+.default-button-border-styles () {
+	border-color: #9cacc0;
+	border-radius: @default-button-border-radius;
+}
+
+.mblToolBarButtonBodyInLeftArrow-styles () {
+  border-left-width: 0;
+}
+
+.mblToolBarButtonBodyInRightArrow-styles () {
+  border-right-width: 0;
+}
+
+// background styles of form controls
+.mbl-button-background-image () { .default-button-background-image(); }
+.mbl-button-selected-background-image () { .default-button-selected-background-image(); }
+.mbl-blue-button-background-image () { .default-blue-button-background-image(); }
+.mbl-blue-button-selected-background-image () { .default-button-selected-background-image(); }
+.mbl-red-button-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#fa9d58, #ee4115, 0.5, #ff4d25, 0.5, #ed4d15); }
+.mbl-red-button-selected-background-image () { .default-button-selected-background-image(); }
+.mbl-button-checked-background-image () { .default-button-background-image(); }
+
+// background styles of form controls (for gecko)
+ at mbl-button-background-image-gecko: @default-button-background-image-gecko;
+ at mbl-button-selected-background-image-gecko: @default-button-selected-background-image-gecko;
+ at mbl-blue-button-background-image-gecko: @default-blue-button-background-image-gecko;
+ at mbl-blue-button-selected-background-image-gecko: @default-button-selected-background-image-gecko;
+ at mbl-red-button-background-image-gecko: -moz-linear-gradient(top, #fa9d58 0%, #ff4d25 50%, #ed4d15 50%, #ee4115 100%);
+ at mbl-red-button-selected-background-image-gecko: @default-button-selected-background-image-gecko;
+ at mbl-button-checked-background-image-gecko: @default-button-background-image-gecko;
+
 // common.less
 .mobile-body-styles () {
-	background-color: #DEDFDE;
 	font-family: Helvetica;
 	font-size: 18px;
 }
 
+.mblBackground-styles () {
+	background-color: #dedfde;
+}
+
 .mblView-styles () {
 	color: black;
 }
 
 .mblColorBlue-styles () {
-	color: white;
-	background-color: #215fdc;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+	color: @default-blue-button-color;
+	background-color: @default-blue-button-background-color;
+	.default-blue-button-background-image();
 }
 .mblColorDefault-styles () {
-	color: black;
-	background-color: #CED3CE;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7FBF7), to(#CECFD6), color-stop(0.5, #CED3CE));
+	color: @default-button-color;
+	background-color: @default-button-background-color;
+	.default-button-background-image();
 }
 .mblColorDefaultSel-styles () {
-	color: white;
-	background-color: #0869C6;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
+	color: @default-button-selected-color;
+	background-color: @default-button-selected-background-color;
+	.default-button-selected-background-image();
 }
 
 // Heading.less
 .mblHeading-styles () {
-	padding: 0px;
-	height: 38px;
-	background-color: #424142;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#4A4D52), to(#292C31));
-	border-top: 1px solid #63696B;
-	border-bottom: 1px solid #292C31;
-	color: white;
-	font-family: Helvetica;
-	font-size: 18px;
-	font-weight: normal;
-	text-align: center;
-	line-height: 40px;
-}
-.mblArrowButton-styles () {
-	height: 28px;
-	margin: 4px 3px 0px 0px;
-}
-.mblArrowButtonHead-styles () {
-	top: 4px;
-	left: 4px;
-	width: 19px;
-	height: 19px;
-	border: 1px solid #39454A;
-	-webkit-transform: scale(.8,1) rotate(45deg);
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7FBF7), to(#CECFD6), color-stop(0.5, #CED3CE));
-}
-.mblArrowButtonHeadChrome-styles () {
-	height: 20px;
-	border: 1px inset #39454A;
-	-webkit-transform: scale(0.7, 1) rotate(45deg);
-}
-.mblArrowButtonBody-styles () {
-	top: 1px;
-	left: 15px;
-	padding: 0px 10px 0px 5px;
-	height: 28px;
-	border: none;
-	font-family: Helvetica;
-	font-size: 14px;
-	font-weight: bold;
-	color: black;
-	line-height: 30px;
-	-webkit-border-top-right-radius: 6px;
-	-webkit-border-bottom-right-radius: 6px;
-	background-color: #CED3CE;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7FBF7), to(#CECFD6), color-stop(0.5, #CED3CE));
-}
-.mblArrowButtonSelected-styles () {
+	.heading-background-image();
+	border-top: 1px solid @heading-border-top-color;
+	border-bottom: 1px solid @heading-border-bottom-color;
 	color: white;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
-}
-.mblArrowButtonHeadSelected-styles () {
-}
-.mblArrowButtonBodySelected-styles () {
 }
 
 // ToolBarButton.less
+ at mbl-tool-bar-button-body-border-radius: 5px;
+//
 .mblToolBarButton-styles () {
-	margin: 4px 3px;
-	height: 29px;
-	font-family: Helvetica;
-	font-size: 14px;
-	font-weight: bold;
-	line-height: 29px;
-	text-align: center;
-	-webkit-border-radius: 6px;
-	-moz-border-radius: 6px;
 }
-.mblToolBarButtonDomButton-styles () {
+.mblToolBarButtonArrow-styles () {
+	border-radius: 1px;
+  .transform(scale(0.7, 1.0) rotate(45deg));
+  border: 1px solid #9cacc0;
+}
+.mblToolBarButtonArrowInHeading-styles () {
+}
+.mblToolBarButtonHasLeftArrowInHeading-styles () {
+}
+.mblToolBarButtonHasLeftArrowInHeading-compat-gecko () {
+}
+.mblToolBarButtonHasRightArrowInHeading-styles () {
+}
+.mblToolBarButtonHasRightArrowInHeading-compat-gecko () {
 }
-.mblToolBarButtonIcon-styles () {
-	top: 1px;
+.mblToolBarButtonArrowInLeftArrow-styles () {
+  left: 1px;
+  border: 1px inset #9cacc0;
+}
+.mblToolBarButtonArrowInRightArrow-styles () {
+  right: 0px;
+  border: 1px inset #9cacc0;
+}
+.mblToolBarButtonBody-styles () {
+	border: 1px outset #9cacc0;
+}
+.mblToolBarButtonBodyInHeading-styles () {
+	border: 1px inset #9cacc0;
+}
+.mblToolBarButtonBodyInHeading-compat-gecko () {
 }
 
-// RoundRect.less
+// RoundRect.less & RoundRectList.less
+ at mbl-round-rect-border-color: #c6c7c6;
+ at mbl-round-rect-border-radius: 6px;
+ at mbl-round-rect-background-color: white;
+ at mbl-round-rect-box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.35);
+//
 .mblRoundRect-styles () {
-	margin: 2px 3px 4px;
-	padding: 8px;
-	border: 1px solid #C6C7C6;
-	-webkit-border-radius: 6px;
-	-moz-border-radius: 6px;
 	color: black;
-	background-color: white;
-}
-.mblRoundRectShadowBox-styles () {
-	-webkit-box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.35);
 }
 
 // EdgeToEdgeCategory.less
 .mblEdgeToEdgeCategory-styles () {
-	margin: 0px;
-	padding: 0px 10px;
 	height: 29px;
 	border-top: 1px solid #313439;
-	border-bottom: 1px solid #ADAAAD;
+	border-bottom: 1px solid #adaaad;
 	background-color: white;
-	font-family: Helvetica;
-	font-size: 16px;
-	font-weight: bold;
-	color: #7B7D84;
+	color: #7b7d84;
 	line-height: 29px;
 }
 
 // RoundRectCategory.less
 .mblRoundRectCategory-styles () {
-	padding: 0px 6px;
-	margin: 3px 9px 0px;
-	height: 29px;
-	font-family: Helvetica;
-	font-size: 16px;
-	color: #7B7D84;
-	line-height: 29px;
-	background-color: white;
-	border: 1px solid #ADAAAD;
-	border-bottom-width: 0px;
-	-webkit-border-top-left-radius: 6px;
-	-webkit-border-top-right-radius: 6px;
-	-moz-border-radius-topleft: 6px;
-	-moz-border-radius-topright: 6px;
-}
-
-// RoundRectList.less
-.mblRoundRectList-styles () {
-	margin: 3px 9px;
-	padding: 0px;
-	border: 1px solid #ADAAAD;
-	-webkit-border-radius: 6px;
-	-moz-border-radius: 6px;
-	background-color: white;
-}
-.mblRoundRectList-withCategory-styles () {
-	margin-top: 0;
-	-webkit-border-top-left-radius: 0px;
-	-webkit-border-top-right-radius: 0px;
-	-moz-border-radius-topleft: 0px;
-	-moz-border-radius-topright: 0px;
-}	
-.mblRoundRectList-FirstListItem-styles () {
-	border-top-width: 0px;
-	-webkit-border-top-left-radius: 6px;
-	-webkit-border-top-right-radius: 6px;
-	-moz-border-radius-topleft: 6px;
-	-moz-border-radius-topright: 6px;
-}
-.mblRoundRectList-withCategory-FirstListItem-styles () {
-	-webkit-border-top-left-radius: 0px;
-	-webkit-border-top-right-radius: 0px;
-	-moz-border-radius-topleft: 0px;
-	-moz-border-radius-topright: 0px;
-}
-.mblRoundRectList-LastListItem-styles () {
-	border-bottom-width: 0px;
-	-webkit-border-bottom-left-radius: 6px;
-	-webkit-border-bottom-right-radius: 6px;
-	-moz-border-radius-bottomleft: 6px;
-	-moz-border-radius-bottomright: 6px;
+	color: black;
+	text-shadow: rgba(255, 255, 255, 1) 0 1px 0;
 }
 
 // EdgeToEdgeList.less
 .mblEdgeToEdgeList-styles () {
-	margin: 0px;
-	padding: 0px;
 	background-color: white;
 }
 .mblEdgeToEdgeList-LastListItem-styles () {
-	border-bottom-width: 0px;
+	border-bottom-width: 0;
 }
 
 // ListItem.less
+ at mbl-list-item-height: 59px;
+//
 .mblListItem-styles () {
-	padding: 6px;
-	height: 43px;
-	border-bottom: solid 1px #DEDFDE;
+	border-bottom: 1px solid #dedfde;
 	font-size: 18px;
 	color: black;
-	line-height: 43px;
-}
-.mblListItem-mblVariableHeight-styles () {
-	padding: 11px 0px 10px 6px;
-	line-height: normal;
-}
-.mblListItem-mblListItemAnchor-styles () {
-	background-position: 14px 17px;
-	text-decoration: none;
-	padding-right: 7px;
-}
-.mblItemSelected-styles () {
-	background-color: #0869C6;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
-}
-.mblItemSelected-mblListItemAnchor-styles () {
-	color: white;
 }
-.mblItemSelected-mblDomButton-Div-styles () {
-	border-color: white;
+.mblListItemSelected-styles () {
+	color: @default-selected-color;
+	.default-selected-background-image();
 }
-.mblItemSelected-mblListItemSubText-styles () {
-	color: white;
-}
-.mblListItemTextBoxSelected-styles () {
-	background-color: #0869C6;
+.mblListItemLabelSelected-styles () {
+	background-color: #0869c6;
 }
 .mblListItemChecked-styles () {
 }
-.mblListItemIcon-styles () {
-	margin-top: 7px;
-	margin-right: 11px;
-}
-.mblListItemSpriteIcon-styles () {
-	margin-top: 7px;
-	margin-left: 8px;
-}
-.mblListItemRightIcon-styles () {
-	margin-top: 7px;
-	margin-bottom: -7px;
-}
 .mblListItemRightText-styles () {
 	color: black;
-	margin: 11px 4px 0 0;
-}
-.mblListItemTextBox-styles () {
-}
-.mblListItemAnchorNoIcon-mblListItemTextBox-styles () {
+	margin-top: 19px;
 }
 .mblListItemSubText-styles () {
 	font-size: 14px;
-	color: #7B7D48;
+	color: #7b7d48;
 }
 
 // Switch.less
-.mblItemSwitch-styles () {
-	top: 14px;
-}
+ at mbl-switch-bg-left-background-color: #088eef;
+.mbl-switch-bg-left-background-image () { .background-image-linear-gradient-top-bottom-1-stop(#088eef, #0851ad, 0.5, #0869c6); }
+ at mbl-switch-bg-right-background-color: #f7f3f7;
+.mbl-switch-bg-right-background-image () { .background-image-linear-gradient-top-bottom-1-stop(#f7f3f7, #cec5d6, 0.5, #ced3ce); }
+.mbl-switch-knob-background-image () { .background-image-linear-gradient-top-bottom-1-stop(#fafafa, #999999, 0.5, #bbbbbb); }
+//
+ at mbl-switch-bg-left-background-image-gecko: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+ at mbl-switch-bg-right-background-image-gecko: -moz-linear-gradient(top, #f7f3f7 0%, #ced3ce 50%, #cec5d6 100%);
+ at mbl-switch-knob-background-image-gecko: -moz-linear-gradient(top, #fafafa 0%, #bbbbbb 50%, #999999 100%);
+ at mbl-switch-square-border-radius: 6px;
+//
 .mblSwitchBg-styles () {
-	-webkit-border-radius: 6px;
-}
-.mblSwitchBgLeft-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
-}
-.mblSwitchBgRight-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7F3F7), to(#CEC5D6), color-stop(0.5, #CED3CE));
+	border: rgba(176,176,176,0.5) 1px inset;
 }
 .mblSwitchKnob-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FAFAFA), to(#999999), color-stop(0.5, #BBBBBB));
-	-webkit-border-radius: 6px;
+	border: rgba(156,172,192,0.5) 1px outset;
 }
 
 // Button.less
 .mblButton-styles () {
-	padding: 0px 10px;
-	height: 29px;
-	border: #9CACC0 1px outset;
-	-webkit-border-radius: 6px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7FBF7), to(#CECFD6), color-stop(0.5, #CED3CE));
+	.default-button-border-styles;
 	color: black;
-	font-family: Helvetica;
 	font-size: 16px;
-	line-height: 29px;
 }
-.mblButton-mblBlueButton-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7A9DE9), to(#2362DD), color-stop(0.5, #366EDF), color-stop(0.5, #215FDC));
+.mblButtonSelected-styles () {
 	color: white;
 }
-.mblButton-mblBlueButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
+.mblButton-mblBlueButton-styles () {
 	color: white;
 }
 .mblButton-mblRedButton-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FA9D58), to(#EE4115), color-stop(0.5, #FF4D25), color-stop(0.5, #ED4D15));
-	color: white;
-}
-.mblButton-mblRedButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
-	color: white;
-}
-.mblButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
 	color: white;
 }
-.mblButtonDisabled-styles () {
-	border-color: grey;
-	color: grey;
-	background-image: none;
-}
 
 // CheckBox.less
 .mblCheckBox-styles () {
-	margin: -0.5em 3px 0.3em 4px;
-	width: 1em;
-	height: 1em;
-	border: #9CACC0 1px outset;
-	-webkit-border-radius: 3px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7FBF7), to(#CECFD6), color-stop(0.5, #CED3CE));
-	font: inherit;
-	-webkit-transform: translateY(0.4em);
-}
-.mblCheckBoxSelected-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
-}
-.mblCheckBoxChecked-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7FBF7), to(#CECFD6), color-stop(0.5, #CED3CE));
+	border-color: #9cacc0;
+	border-radius: 3px;
 }
 .mblCheckBoxChecked-after-styles () {
-	position: absolute;
-	content: "";
-	width: 0.3em;
-	height: 0.6em;
-	top: 0;
-	left: 0.3em;
-	border-color: #0851AD;
-	border-width: 0.15em;
-	border-style: none solid solid none;
-	-webkit-transform: rotate(45deg);
-	-webkit-transform-origin: 50% 50%;
-}
-.mblCheckBoxChecked-mblCheckBoxSelected-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
+	border-color: #0851ad;
 }
 .mblCheckBoxChecked-mblCheckBoxSelected-after-styles () {
 	border-color: white;
 }
 
 // ComboBox.less
+ at mbl-combo-box-popup-box-shadow: none;
+//
 .dijitPopup-styles () {
-	-webkit-box-shadow: none;
-	-webkit-border-radius: 12px;
+	border-radius: 12px;
 }
 .mblComboBoxMenu-styles () {
-	border: 1px solid black;
-	-webkit-border-radius: 12px;
-	background-color: black;
-}
-.mblComboBoxMenuItemSelected-styles () {
-	color: white;
+	border-radius: 12px;
 	background-color: black;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
 }
 .mblComboBoxMenuItem-styles () {
-	padding: .1em .2em;
-	border-width: 1px 0 1px 0;
-	border-style: solid;
 	border-color: black;
 	color: white;
-	text-align: left;
 }
-.mblComboBoxMenuPreviousButton-styles () {
-	font-style: italic;
-	overflow: hidden;
+.mblComboBoxMenuItemSelected-styles () {
+	.default-selected-background-image();
+	color: white;
 }
 
 // IconContainer.less
-.mblIconContainer-styles () {
-	margin: 0px;
-	padding: 0px;
-}
-
-// IconItem.less
-.mblIconItemTerminator-styles () {
-	height: 0px;
-}
 .mblIconItemSub-styles () {
 	background-color: white;
 	color: black;
 }
 .mblIconArea-styles () {
+	margin-top: 5px;
 	margin-bottom: 5px;
-	height: 78px;
 	width: 88px;
-	text-align: center;
-	font-family: Helvetica;
-	font-size: 12px;
 }
-.mblContent-styles () {
-	padding-bottom: 20px;
-}
-.mblIconContentHeading-styles () {
-	margin-top: 0px;
-	padding-left: 40px;
-	height: 25px;
-	border-top: 1px solid #F1F3F4;
-	border-bottom: 1px solid #717D85;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#E0E4E7), to(#B4BEC6), color-stop(0.5, #C4CCD2), color-stop(0.5, #BFC8CE));
-	font-family: Helvetica;
-	font-size: 16px;
-	color: white;
-	line-height: 26px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
+.mblIconItemDeleteIcon-styles () {
+	top: -4px;
+	left: 2px;
 }
 
 // RadioButton.less
 .mblRadioButton-styles () {
-	margin: -0.5em 3px 0.3em 4px;
-	width: 1em;
-	height: 1em;
-	border: #9CACC0 1px outset;
-	-webkit-border-radius: 0.5em;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7FBF7), to(#CECFD6), color-stop(0.5, #CED3CE));
-	font: inherit;
-	-webkit-transform: translateY(0.4em);
-}
-.mblRadioButtonChecked-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7FBF7), to(#CECFD6), color-stop(0.5, #CED3CE));
+	border-color: #9cacc0;
 }
 .mblRadioButtonChecked-after-styles () {
-	content: "";
-	width: 0.3em;
-	height: 0.6em;
-	top: 0;
-	left: 0.25em;
-	border-color: white;
-	border-width: 0.15em;
-	border-style: none solid solid none;
-	border-color: #0851AD;
-	-webkit-transform: rotate(45deg);
-	-webkit-transform-origin: 50% 50%;
-}
-.mblRadioButtonChecked-Selected-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
+	border-color: #0851ad;
 }
 .mblRadioButtonChecked-Selected-after-styles () {
 	border-color: white;
 }
 
 // Slider.less
+ at mbl-slider-bar-border-radius: @default-button-border-radius;
+ at mbl-slider-knob-border-radius: @default-button-border-radius;
+//
 .mblSlider-styles () {
-	margin: 15px; /* 1/2 handle width for hanging off the ends of the bar */
-	border: #B0B0B0 1px inset;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7F3F7), to(#CEC5D6), color-stop(0.5, #CED3CE));
-	-webkit-border-radius: 6px;
-}
-.mblSliderProgressBar-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
-	-webkit-border-radius: 6px;
+	border-color: #b0b0b0;
 }
 .mblSliderHandle-styles () {
-	margin: -10px 0 0 -10px;
-	width: 18px;
-	height: 18px;
-	border: #9D9D9D 1px outset;
-	-webkit-border-radius: 6px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FAFAFA), to(#999999), color-stop(0.5, #BBBBBB));
+	border-color: #9d9d9d;
 }
 
 // TabBar.less
 .mblTabBar-styles () {
-	margin: 0px;
-	padding: 0px;
-	height: 48px;
-	border-top: 1px solid #000000;
-	background-color: #212421;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100C10));
-	color: white;
-	text-align: center;
+	text-shadow: none;
 }
-.mblTabBar-TabBarButton-styles () {
+
+// barType="tabBar"
+.mblTabBarTabBar-styles () {
+	.background-image-linear-gradient-top-bottom(#181818, #100c10);
 }
-.mblTabBar-TabBarButton-Selected-styles () {
-	background-color: #404040;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424), color-stop(0.5, #353535));
-	-webkit-border-radius: 3px;
+.mblTabBarTabBar-compat () {
+	background-color: #212421;
 }
-.mblTabBarButtonDiv-styles () {
-	height: 34px;
-	width: 29px;
+.mblTabBarTabBarButton-styles () {
 }
-.mblTabBarButtonIcon-styles () {
-	left: 0;
-	top: 0;
+.mblTabBarTabBarButtonIconArea-styles () {
 }
-.mblTabBarButtonTextBox-styles () {
+.mblTabBarTabBarButtonLabel-styles () {
 	color: #979797;
-	font-family: "Helvetica Neue", Helvetica;
-	font-size: 11px;
-}
-.mblTabBarNoIcons-TabBarButtonTextBox-styles () {
-	line-height: 34px;
-	font-size: 20px;
 }
-.mblTabButton-styles () {
-	width: 78px;
-	height: 61px;
-	border-width: 1px 1px 0px 1px;
-	border-style: solid;
-	border-color: #7B7D84 #182018 black #393C39;
-	background-color: #212421;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100C10), color-stop(0.1, #313031));
-	font-family: Helvetica;
-	font-size: 13px;
-	color: #979797;
-	text-align: center;
+.mblTabBarTabBarButtonSelected-styles () {
+	background-color: #404040;
+	.background-image-linear-gradient-top-bottom-1-stop(#484848, #242424, 0.5, #353535);
 }
-.mblTabButton-TabBarButtonAnchor-styles () {
+.mblTabBarTabBarButtonLabelSelected-styles () {
+	color: white;
 }
-.mblTabBarTop-TabButton-TabBarButtonDiv-styles () {
-	height: 40px;
+
+// barType="segmentedControl"
+ at mbl-tab-bar-segmented-control-border-radius: @default-button-border-radius;
+//
+.mblTabBarSegmentedControl-styles () {
 }
-.mblTabBarHead-TabButton-TabBarButtonDiv-styles () {
+.mblTabBarSegmentedControlButton-styles () {
+	border-style: solid;
+	border-color: #7b7d84 #182018 black #393c39;
+	color: @default-button-color;
+	.default-button-background-image();
 }
-.mblTabButton-FirstTabButtom-styles () {
+.mblTabBarSegmentedControlButton-compat-gecko () {
 }
-.mblTabButton-LastTabButton-styles () {
+.mblTabBarSegmentedControlButtonSelected-styles () {
+	color: @default-button-selected-color;
+	.default-button-selected-background-image();
 }
-.mblTabButton-img-styles () {
-	position: absolute;
-	left: 0px;
-	margin-top: 8px;
+
+// barType="standardTab"
+.mblTabBarStandardTab-styles () {
 }
-.mblTabBarButtonTextBoxSelected-styles () {
-	color: white;
+.mblTabBarStandardTabButton-styles () {
+	color: @default-button-color;
+	background-color: @default-button-background-color; /* TODO: to compat */
+	.default-button-background-image();
 }
-.mblTabButtonSelected-styles () {
+.mblTabBarStandardTabButtonIconArea-styles () {
 }
-.mblTabButtonHighlighted-styles () {
+.mblTabBarStandardTabButtonLabel-styles () {
 }
-.mblTabButtonImgDiv-styles () {
-	position: relative;
-	margin-left: 24px;
-	height: 40px;
+.mblTabBarStandardTabButtonSelected-styles () {
+	color: @default-button-selected-color;
+	background-color: @default-button-selected-background-color;
+	.default-button-selected-background-image();
 }
-.mblTabPanelHeader-styles () {
-	margin: 0px;
-	padding: 0px 0px 0px 0px;
-	height: 64px;
-	border-top: 1px solid #CDD5DF;
-	border-bottom: 2px solid #949694;
-	background-color: #000000;
-	font-family: Helvetica;
-	font-size: 20px;
-	color: white;
-	text-align: center;
+.mblTabBarStandardTabButtonLabelSelected-styles () {
 }
-.mblTabPanelHeader-TabButton-styles () {
-	margin-top: 3px;
-	-webkit-border-top-left-radius: 6px;
-	-webkit-border-top-right-radius: 6px;
+
+// barType="tallTab"
+.mblTabBarTallTab-styles () {
+	.background-image-linear-gradient-top-bottom(#2d2d2d, #000000);
 }
-.mblTabPanelHeader-TabButtonSelected-styles () {
-	background-color: #404040;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424), color-stop(0.5, #353535));
-	color: white;
-}	
-.mblTabPanelHeader-TabButtonDomButton-styles () {
-	width: 43px;
+.mblTabBarTallTabButton-styles () {
+	background-color: #212421;
+	background-image: none;
 }
-.mblTabPanelHeader-TabButtonDomButtonClass-styles () {
-	left: 8px;
+.mblTabBarTallTabButton-FirstChild-styles () {
 }
-.mblTabPanelHeader-DomButton-styles () {
+.mblTabBarTallTabButton-LastChild-styles () {
 }
-.mblTabPanelHeader-inHeading-styles () {
-	height: 38px;
+.mblTabBarTallTabButtonIconArea-styles () {
 }
-.mblTabPanelHeader-TabButton-inHeading-styles () {
-	margin: 5px 0;
-	height: 28px;
-	border-width: 0px 1px 0px 0px;
-	border-style: solid;
-	border-color: #39454A;
-	-webkit-border-top-left-radius: 0;
-	-webkit-border-top-right-radius: 0;
-	background-color: #CED3CE;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#f7fbf7), to(#cecfd6), color-stop(0.5, #ced3ce));
-	font-size: 14px;
-	font-weight: bold;
-	line-height: 30px;
-	color: black;
+.mblTabBarTallTabButtonLabel-styles () {
 }
-.mblTabPanelHeader-TabButton-FirstTabButtom-inHeading-styles () {
-	-webkit-border-top-left-radius: 6px;
-	-webkit-border-bottom-left-radius: 6px;
+.mblTabBarTallTabButtonSelected-styles () {
+	background-color: #636363;
+	background-image: none;
 }
-.mblTabPanelHeader-TabButton-LastTabButtom-inHeading-styles () {
-	-webkit-border-top-right-radius: 6px;
-	-webkit-border-bottom-right-radius: 6px;
-	border-right: none;
+.mblTabBarTallTabButtonLabelSelected-styles () {
 }
-.mblTabPanelHeader-TabButtonSelected-inHeading-styles () {
-	background-color: #0869C6;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088eef), to(#0851ad), color-stop(0.5, #0869c6));
-	color: white;
-}	
 
 // TextArea.less
 .mblTextArea-styles () {
-	padding: 4px 1px;
-	border-color: #9CACC0;
-	border-width: 1px;
-	border-style: inset;
-	-webkit-border-radius: 6px;
-	font-family: Helvetica;
-	font-size: 13px;
-}
-.mblExpandingTextArea-styles () {
-	margin: 2px;
+	.default-button-border-styles;
 }
 
 // TextBox.less
 .mblTextBox-styles () {
-	height: 22px;
-	border: #9CACC0 1px inset;
-	-webkit-border-radius: 6px;
-	font-family: Helvetica;
-	font-size: 13px;
+	.default-button-border-styles;
 }
 
 // ToggleButton.less
 .mblToggleButton-styles () {
-	padding: 0px 10px 0px 25px;
-	height: 29px;
-	border-width: 1px 1px 1px 1px;
-	border-style: outset;
-	border-color: #9CACC0;
-	-webkit-border-radius: 6px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7FBF7), to(#CECFD6), color-stop(0.5, #CED3CE));
-	font-family: Helvetica;
+	.default-button-border-styles;
 	font-size: 16px;
 	color: black;
-	line-height: 29px;
 }
 .mblToggleButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
 	color: white;
 }
 .mblToggleButtonChecked-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F7FBF7), to(#CECFD6), color-stop(0.5, #CED3CE));
 	color: black;
 }
 .mblToggleButtonChecked-after-styles () {
-	content: "";
-	top: 6px;
-	left: 7px;
-	width: 5px;
-	height: 10px;
-	border-color: #0851AD;
-	border-width: 2px;
-	border-style: none solid solid none;
-	-webkit-transform: rotate(45deg) skew(10deg);
-	-webkit-transform-origin: 50% 50%;
+	border-color: #0851ad;
 }
 .mblToggleButtonCheckedSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#088EEF), to(#0851AD), color-stop(0.5, #0869C6));
 	color: white;
 }
 .mblToggleButtonCheckedSelected-after-styles () {
 	border-color: white;
 }
-.mblToggleButtonDisabled-styles () {
-	border-color: grey;
-	background-image: none;
-	color: grey;
-}
 
 // Overlay.less
 .mblOverlay-styles () {
 	background-color: #000000;
 	background-image: none;
 }
+.mblOverlay-compat () {
+}
+.mblOverlay-compat-gecko () {
+}
 
 // Tooltip.less
+ at mbl-tooltip-border-radius: 6px;
+//
 .mblTooltip-styles () {
-	padding: 5px;
-	border: #ADAAAD 1px solid;
+	border-color: #adaaad;
+	border-radius: @mbl-tooltip-border-radius;
 	background-color: #424142;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#4A4D52), to(#292C31));
-	-webkit-border-radius: 6px;
-	opacity: .97;
+	.background-image-linear-gradient-top-bottom(#4a4d52, #292c31);
 }
 .mblTooltipBubble-styles () {
 	background-color: #000000;
@@ -718,40 +460,37 @@
 .mblTooltipInnerArrow-Bubble-Before-styles () {
 	border-right-color: #000000;
 }
-.mblTooltipArrow-styles () {
-	border: 11px solid transparent;
-}
 .mblTooltipArrow-Before-styles () {
 	border-left-width: 0;
-	border-right-color: #ADAAAD;
+	border-right-color: #adaaad;
 }
 .mblTooltipArrow-After-styles () {
 	border-right-width: 0;
-	border-left-color: #ADAAAD;
+	border-left-color: #adaaad;
 }
 .mblTooltipArrow-Above-styles () {
 	border-top-width: 0;
-	border-bottom-color: #ADAAAD;
+	border-bottom-color: #adaaad;
 }
 .mblTooltipArrow-Below-styles () {
 	border-bottom-width: 0;
-	border-top-color: #ADAAAD;
+	border-top-color: #adaaad;
 }
 .mblTooltipInnerArrow-Before-styles () {
 	border-left-width: 0;
-	border-right-color: #4A4D52;
+	border-right-color: #4a4d52;
 }
 .mblTooltipInnerArrow-After-styles () {
 	border-right-width: 0;
-	border-left-color: #4A4D52;
+	border-left-color: #4a4d52;
 }
 .mblTooltipInnerArrow-Above-styles () {
 	border-top-width: 0;
-	border-bottom-color: #4A4D52;
+	border-bottom-color: #4a4d52;
 }
 .mblTooltipInnerArrow-Below-styles () {
 	border-bottom-width: 0;
-	border-top-color: #292C31;
+	border-top-color: #292c31;
 }
 .mblTooltip-Heading-styles () {
 	border-top: 1px solid transparent;
@@ -759,5 +498,243 @@
 	background-color: transparent;
 	background-image: none;
 }
+.mblTooltip-Heading-compat () {
+}
 .mblTooltip-Heading-ToolbarButton-styles () {
 }
+.mblTooltip-Heading-ToolbarButton-compat () {
+}
+
+// Accordion.less
+.mblAccordion-styles () {
+	border-color: #9cacc0;
+}
+.mblAccordionTitle-styles () {
+	border-top: 1px outset #9cacc0;
+	background-color: white;
+}
+.mblAccordionTitle-compat () {
+}
+.mblAccordionTitle-compat-gecko () {
+}
+.mblAccordionTitleSelected-styles () {
+	border-bottom: 1px outset #9cacc0;
+	.default-selected-background-image();
+	color: white;
+}
+.mblAccordionTitleSelected-compat () {
+	background-color: #0869c6;
+}
+.mblAccordionTitleSelected-compat-gecko () {
+	background-image: @default-selected-background-image-gecko;
+}
+.mblAccordionTitleAnchor-styles () {
+	color: #000000;
+}
+.mblAccordionTitleAnchorSelected-styles () {
+	color: white;
+}
+
+// SimpleDialog.less
+ at mbl-simple-dialog-border-radius: 6px;
+//
+.mblSimpleDialog-styles () {
+	padding: 8px;
+	width: 262px;
+}
+.mblSimpleDialogDecoration-styles () {
+	background-color: #000000;
+	border: none;
+	color: white;
+}
+.mblSimpleDialogDecoration-compat () {
+}
+.mblSimpleDialogDecoration-compat-gecko () {
+}
+.mblSimpleDialogTitle-styles () {
+	margin: 7px 0 14px;
+	width: 262px;
+}
+.mblSimpleDialogText-styles () {
+	margin: 7px 0 14px;
+	width: 262px;
+}
+
+// IconMenu.less
+ at mbl-icon-menu-border-radius: 6px;
+ at mbl-icon-menu-item-border-radius: 0;
+//
+.mblIconMenu-styles () {
+	padding: 8px;
+	background-color: #000000;
+	border: none;
+}
+.mblIconMenu-compat () {
+}
+.mblIconMenu-compat-gecko () {
+}
+.mblIconMenuItem-styles () {
+	border-left: 1px solid #000000;
+	border-bottom: 1px solid #000000;
+}
+.mblIconMenuItemAnchor-styles () {
+	font-size: 16px;
+	color: white;
+}
+.mblIconMenuItemSel-styles () {
+	.background-image-linear-gradient-top-bottom-1-stop(#088eef, #0851ad, 0.5, #0869c6);
+	color: white;
+}
+.mblIconMenuItemSel-compat () {
+	background-color: #0869c6;
+}
+.mblIconMenuItemSel-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #088eef 0%, #0869c6 50%, #0851ad 100%);
+}
+
+// dijit.Calendar
+.dijitCalendar-styles () {
+	border: none 0 transparent;
+	background-color: white;
+}
+.dijitCalendar-thead-styles () {
+	.background-image-linear-gradient-top-bottom(#63696b, #182021);
+}
+.dijitCalendar-thead-compat () {
+	background-image: url(compat/calendar-month-bg.png);
+}
+.dijitCalendar-thead-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #63696b 0%, #182021 100%);
+}
+.dijitCalendarMonthLabel-styles () {
+	color: white;
+	font-size: 18px;
+}
+.dijitCalendarMonthMenu-styles () {
+	border: 1px solid black;
+	border-radius: 6px;
+	background-color: white;
+}
+.dijitCalendarMonthMenu-compat-ff3 () {
+	-moz-border-radius: 6px;
+}
+.dijitCalendarMonthMenu-Label-styles () {
+	color: black;
+}
+.dijitCalendarDecrease-styles () {
+	border-right: 6px solid white !important;
+}
+.dijitCalendarIncrease-styles () {
+	border-left: 6px solid white !important;
+}
+.dijitCalendarDayLabelTemplate-styles () {
+	background-color: #6b7173;
+	font-size: 14px;
+	color: white;
+}
+.dijitCalendarDateTemplate-styles () {
+	border-right: 1px solid lightGrey;
+	background-color: white;
+	color: black;
+}
+.dijitCalendarDateTemplate-LastChild-styles () {
+	border-right: none;
+}
+.dijitCalendarDateLabel-DateTemplate-styles () {
+	border: none;
+}
+.dijitCalendarDateLabel-PrevMonth-styles () {
+	background-color: #cecbce;
+	color: #adaeb5;
+}
+.dijitCalendarDateLabel-Hovered-styles () {
+	color: grey;
+}
+.dijitCalendarDateLabel-Selected-styles () {
+	.default-selected-background-image();
+	color: white;
+	text-shadow: rgba(0,0,0,0.4) 0 1px 0;
+}
+.dijitCalendarDateLabel-Selected-compat () {
+	background-image: url(compat/calendar-datelabel-sel-bg.png);
+}
+.dijitCalendarDateLabel-Selected-compat-gecko () {
+	background-image: @default-selected-background-image-gecko;
+}
+.dijitCalendarDateLabel-Active-styles () {
+	.default-selected-background-image();
+}
+.dijitCalendarDateLabel-Active-compat () {
+	background-image: url(compat/calendar-datelabel-sel-bg.png);
+}
+.dijitCalendarDateLabel-Active-compat-gecko () {
+	background-image: @default-selected-background-image-gecko;
+}
+.dijitCalendarYearLabel-styles () {
+	padding: 0;
+	.background-image-linear-gradient-top-bottom(#63696b, #182021);
+}
+.dijitCalendarYearLabel-compat () {
+	background-image: url(compat/calendar-year-bg.png);
+}
+.dijitCalendarYearLabel-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #63696b 0%, #182021 100%);
+}
+.dijitCalendarSelectedYear-styles () {
+	color: white;
+	font-size: 16px;
+}
+.dijitCalendarNextYear-styles () {
+	padding: 1px 6px 3px 6px;
+	color: white;
+	font-size: 12px;
+}
+
+// SearchBox.less
+ at mbl-searchbox-cancel-button-color: white;
+ at mbl-searchbox-cancel-button-bg-color: black;
+.mblSearchBox-Cancel-Button-styles () {
+	border-radius: 1em;
+}
+ at mbl-searchbox-results-decoration-color: black;
+
+// ProgressBar.less
+.mblProgressBar-styles () {
+	height: 22px;
+	background-color: white;
+	padding: 1px;
+}
+.mblProgressBarProgress-styles () {
+	background-color: #298eff;
+	height: 22px;
+}
+.mblProgressBarComplete-styles () {
+}
+.mblProgressBarNotStarted-styles () {
+}
+.mblProgressBarMsg-styles () {
+	top: 2px;
+	font-size: 18px;
+}
+.mblProgressBar-compat () {
+}
+.mblProgressBarProgress-compat () {
+}
+.mblProgressBar-compat-gecko () {
+}
+.mblProgressBarProgress-compat-gecko () {
+}
+
+// ValuePicker.less
+.mbl-value-picker-slot-button-background-image () { .background-image-linear-gradient-top-bottom-1-stop(#f7fbf7, #cecfd6, 0.5, #ced3ce); }
+ at mbl-value-picker-slot-button-background-image-gecko: -moz-linear-gradient(top, #f7fbf7 0%, #ced3ce 50%, #cecfd6 100%);
+ at mbl-value-picker-slot-button-radius: 3px;
+.mbl-value-picker-slot-input-area-background-image () { .background-image-linear-gradient-top-bottom-4-stops-no-from-to(0.1, #fafafa, 0.2, #fafafa, 0.5, #ffffff, 0.9, #ffffff); }
+ at mbl-value-picker-slot-input-area-background-image-gecko: -moz-linear-gradient(top, #fafafa 10%, #fafafa 20%, #ffffff 50%, #ffffff 90%);
+
+.mblValuePickerSlot-style () {
+  margin:  0 5px;
+}
+.mblValuePickerSlot-input-style () {
+  font: 24px/44px Helvetica, sans-serif;
+}
diff --git a/dojox/mobile/themes/blackberry/variables_rtl.less b/dojox/mobile/themes/blackberry/variables_rtl.less
new file mode 100644
index 0000000..8fab97a
--- /dev/null
+++ b/dojox/mobile/themes/blackberry/variables_rtl.less
@@ -0,0 +1,32 @@
+// Carousel_rtl
+ at mbl-carousel-margin-rtl: ~"2px 0px 2px 4px";
+
+// IconContainer_rtl
+ at mbl-icon-container-right-rtl: 2px;
+
+// IconMenu_rtl-compat
+ at mbl-border-radius-rtl: 0px;
+
+// TabBar_rtl-compat
+ at mbl-moz-border-radius-rtl: 6px;
+
+// TabBar_rtl
+ at mbl-border-width-rtl: ~"1px 0px 1px 1px !important";
+ at mbl-tb-border-radius-rtl: 6px;
+
+// ThemeID
+ at theme-id: blackberry;
+
+// Switch_rtl-compat
+ at mbl-bg-image-r-rtl: ~"url(compat/switch-square-r.gif)";
+ at mbl-bg-image-l-rtl: ~"url(compat/switch-square-l.gif)";
+
+// Switch_rtl
+ at mbl-switchOn-left-rtl: -53px;
+ at mbl-switchBg-left-rtl: 53px;
+ at mbl-switch-knob-rtl: 53px;
+ at mbl-switch-text-right-rtl: -40px;
+
+// ToolBarButton_rtl
+ at mbl-toolbar-right-arrow-rtl: 1px;
+ at mbl-toolbar-left-arrow-rtl: 0px;
diff --git a/dojox/mobile/themes/common/Accordion-compat.less b/dojox/mobile/themes/common/Accordion-compat.less
new file mode 100644
index 0000000..08221d4
--- /dev/null
+++ b/dojox/mobile/themes/common/Accordion-compat.less
@@ -0,0 +1,30 @@
+/* dojox.mobile.Accordion */
+.mblAccordionTitle {
+	.mblAccordionTitle-compat;
+}
+.mblAccordionTitleSelected {
+	.mblAccordionTitleSelected-compat;
+}
+
+.dj_gecko {
+	.mblAccordionTitle {
+		.mblAccordionTitle-compat-gecko;
+	}
+	.mblAccordionTitleSelected {
+		.mblAccordionTitleSelected-compat-gecko;
+	}
+}
+
+.dj_ff3 {
+	.mblAccordionRoundRect {
+		-moz-border-radius: 8px;
+		.mblAccordionTitle:first-child {
+			-moz-border-radius-topleft: 8px;
+			-moz-border-radius-topright: 8px;
+		}
+		.mblAccordionTitleLast, .mblAccordionPane:last-child {
+			-moz-border-radius-bottomleft: 8px;
+			-moz-border-radius-bottomright: 8px;
+		}
+	}
+}
diff --git a/dojox/mobile/themes/common/Accordion.less b/dojox/mobile/themes/common/Accordion.less
new file mode 100644
index 0000000..08b035f
--- /dev/null
+++ b/dojox/mobile/themes/common/Accordion.less
@@ -0,0 +1,67 @@
+/* dojox.mobile.Accordion */
+.mblAccordion {
+	border-style: outset;
+	border-width: 1px;
+	.mblAccordion-styles;
+}
+.mblAccordionRoundRect {
+	margin: 7px 9px 16px 9px;
+	padding: 0;
+	border: 1px solid @mbl-round-rect-border-color;
+	border-radius: 8px;
+	.mblAccordionTitle:first-child {
+		border-top-left-radius: 8px;
+		border-top-right-radius: 8px;
+	}
+	.mblAccordionTitleLast, .mblAccordionPane:last-child {
+		border-bottom-width: 0;
+		border-bottom-left-radius: 8px;
+		border-bottom-right-radius: 8px;
+	}
+}
+.mblAccordionTitle {
+	position: relative;
+	height: 30px;
+	width: 100%;
+	font-family: Helvetica;
+	font-size: 17px;
+	font-weight: bold;
+	line-height: 30px;
+	vertical-align: middle;
+	white-space: nowrap;
+	.mblAccordionTitle-styles;
+	&:first-child {
+		border-top: none;
+	}
+}
+.mblAccordionTitleAnchor {
+	display: block;
+	height: 100%;
+	text-decoration: none;
+	white-space: nowrap;
+	.mblAccordionTitleAnchor-styles;
+  cursor: pointer;
+}
+.mblAccordionIconParent {
+	float: left;
+	margin: 6px 4px 0 6px;
+	line-height: normal;
+}
+.mblAccordionIconParent1 {
+	display: block;
+}
+.mblAccordionIconParent2 {
+	display: none;
+}
+.mblAccordionTitleSelected {
+	.mblAccordionTitleSelected-styles;
+	.mblAccordionTitleAnchor {
+		.mblAccordionTitleAnchorSelected-styles;
+	}
+	.mblAccordionIconParent1 {
+		display: none;
+	}
+	.mblAccordionIconParent2 {
+		display: block;
+	}
+}
diff --git a/dojox/mobile/themes/common/Button-compat.less b/dojox/mobile/themes/common/Button-compat.less
new file mode 100644
index 0000000..0fb4de8
--- /dev/null
+++ b/dojox/mobile/themes/common/Button-compat.less
@@ -0,0 +1,46 @@
+/* dojox.mobile.Button */
+.mblButton {
+	background-image: url(compat/button-bg.png);
+	background-repeat: repeat-x;
+}
+.mblButtonSelected {
+	background-image: url(compat/button-sel-bg.png);
+}
+.mblBlueButton {
+	background-image: url(compat/blue-button-bg.png);
+}
+.mblBlueButtonSelected {
+	background-image: url(compat/blue-button-sel-bg.png);
+}
+.mblRedButton {
+	background-image: url(compat/red-button-bg.png);
+}
+.mblRedButtonSelected {
+	background-image: url(compat/red-button-sel-bg.png);
+}
+
+.dj_gecko {
+	.mblButton {
+		background-image: @mbl-button-background-image-gecko;
+	}
+	.mblButtonSelected {
+		background-image: @mbl-button-selected-background-image-gecko;
+	}
+	.mblBlueButton {
+		background-image: @mbl-blue-button-background-image-gecko;
+	}
+	.mblBlueButtonSelected {
+		background-image: @mbl-blue-button-selected-background-image-gecko;
+	}
+	.mblRedButton {
+		background-image: @mbl-red-button-background-image-gecko;
+	}
+	.mblRedButtonSelected {
+		background-image: @mbl-red-button-selected-background-image-gecko;
+	}
+}
+.dj_ff3 {
+	.mblButton {
+		-moz-border-radius: @default-button-border-radius;
+	}
+}
diff --git a/dojox/mobile/themes/common/Button.less b/dojox/mobile/themes/common/Button.less
index d84460f..2a78773 100644
--- a/dojox/mobile/themes/common/Button.less
+++ b/dojox/mobile/themes/common/Button.less
@@ -1,29 +1,38 @@
 /* dojox.mobile.Button */
 .mblButton {
+	padding: 0 10px;
+	height: 29px;
+	border-style: outset;
+	border-width: 1px;
+	.mbl-button-background-image();
+	font-family: Helvetica;
+	line-height: 29px;
 	cursor: pointer;
-	outline: none;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
+	.tap-highlight-color(rgba(255,255,255,0));
 	.mblButton-styles;
-	&.mblBlueButton {
-		-webkit-tap-highlight-color: rgba(255,255,255,0);
-		.mblButton-mblBlueButton-styles;
-	}
-	&.mblBlueButtonSelected {
-		.mblButton-mblBlueButtonSelected-styles;
-	}
-	&.mblRedButton {
-		-webkit-tap-highlight-color: rgba(255,255,255,0);
-		.mblButton-mblRedButton-styles;
-	}
-	&.mblRedButtonSelected {
-		.mblButton-mblRedButtonSelected-styles;
-	}
 }
 .mblButtonSelected {
+	.mbl-button-selected-background-image();
 	.mblButtonSelected-styles;
 }
 .mblButtonDisabled,
 .mblButton:disabled {
+	border-color: grey;
+	background-image: none;
+	color: grey;
 	cursor: default;
-	.mblButtonDisabled-styles;
+}
+.mblBlueButton {
+	.mbl-blue-button-background-image();
+	.mblButton-mblBlueButton-styles;
+}
+.mblBlueButtonSelected {
+	.mbl-blue-button-selected-background-image();
+}
+.mblRedButton {
+	.mbl-red-button-background-image();
+	.mblButton-mblRedButton-styles;
+}
+.mblRedButtonSelected {
+	.mbl-red-button-selected-background-image();
 }
diff --git a/dojox/mobile/themes/common/Carousel.less b/dojox/mobile/themes/common/Carousel.less
index dd16627..e7d99c8 100644
--- a/dojox/mobile/themes/common/Carousel.less
+++ b/dojox/mobile/themes/common/Carousel.less
@@ -1,30 +1,19 @@
 /* dojox.mobile.Carousel */
 .mblCarousel {
 	overflow: hidden;
+	height: 300px;
 }
-.mblCarouselBox {
+.mblCarouselSlot {
 	position: relative;
 	float: left;
+	text-align: left;
+	box-sizing: border-box;
 }
-.mblCarouselImg {
-	-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
-	vertical-align: bottom;
-}
-.mblCarouselImgSelected {
-	border: 1px dashed #C0C0C0;
-	-webkit-box-shadow: none;
-}
-.mblCarouselImgHeaderText {
-	color: white;
-	font: 14px arial,helvetica,clean,sans-serif;
-}
-.mblCarouselImgFooterText {
-	color: white;
-	font: 14px arial,helvetica,clean,sans-serif;
+.mblCarouselSlotSelected {
 }
 .mblCarouselHeaderBar {
-	background-color: #3A3A3B;
-	color: #B1B1B1;
+	background-color: #3a3a3b;
+	color: #b1b1b1;
 	font: bold 16px arial,helvetica,clean,sans-serif;
 	padding: 1px;
 }
@@ -56,3 +45,34 @@
 	position: relative;
 	text-align: center;
 }
+
+/* dojox.mobile._CarouselItem */
+.mblCarouselItem {
+	text-align: center;
+	.tap-highlight-color(rgba(255, 255, 255, 0));
+}
+.mblCarouselItemHeaderText {
+	color: white;
+	font: 14px arial,helvetica,clean,sans-serif;
+	text-align: center;
+	margin-top: 8px;
+	margin-bottom: 5px;
+}
+.mblCarouselItemFooterText {
+	color: white;
+	font: 14px arial,helvetica,clean,sans-serif;
+	text-align: center;
+	margin-top: 5px;
+	margin-bottom: 8px;
+}
+.mblCarouselItemImage {
+	.box-shadow(5px 5px 5px rgba(0, 0, 0, 0.5));
+	vertical-align: bottom;
+}
+.mblCarouselItemBlank {
+	display: none;
+}
+.mblCarouselSlotSelected .mblCarouselItemImage {
+	opacity: 0.6;
+	.box-shadow(none);
+}
diff --git a/dojox/mobile/themes/common/Carousel_rtl.less b/dojox/mobile/themes/common/Carousel_rtl.less
new file mode 100644
index 0000000..214a8be
--- /dev/null
+++ b/dojox/mobile/themes/common/Carousel_rtl.less
@@ -0,0 +1,13 @@
+/* dojox.mobile.Carousel Rtl */
+.mblCarouselItemRtl.mblCarouselSlot {
+  float: right;
+}
+.mblCarouselRtl .mblCarouselBtnContainer {
+  float: left;
+}
+.mblCarouselRtl .mblCarouselTitle{
+  margin: @mbl-carousel-margin-rtl;
+}
+.mblCarouselRtl .mblCarouselHeaderBar .mblPageIndicator {
+  float: left;
+}
diff --git a/dojox/mobile/themes/common/CheckBox-compat.less b/dojox/mobile/themes/common/CheckBox-compat.less
new file mode 100644
index 0000000..6a0dfec
--- /dev/null
+++ b/dojox/mobile/themes/common/CheckBox-compat.less
@@ -0,0 +1,40 @@
+/* dojox.mobile.CheckBox */
+.mblCheckBox {
+	background-image: url(compat/button-bg.png);
+}
+.mblCheckBoxSelected {
+	background-image: url(compat/button-sel-bg.png);
+}
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
+	background-image: url(compat/button-chk-bg.png);
+	&.mblCheckBoxSelected {
+		background-image: url(compat/button-unsel-bg.png);
+	}
+}
+
+.dj_gecko {
+	.mblCheckBox {
+		background-image: @mbl-button-background-image-gecko;
+		-moz-appearance: none;
+	}
+	.mblCheckBoxSelected {
+		background-image: @mbl-button-selected-background-image-gecko;
+	}
+	.mblCheckBoxChecked,
+	.mblCheckBox:checked {
+		background-image: @mbl-button-checked-background-image-gecko;
+		&::after {
+			-moz-transform: rotate(45deg);
+			-moz-transform-origin: 50% 50%;
+		}
+		&.mblCheckBoxSelected {
+			background-image: @mbl-blue-button-selected-background-image-gecko;
+		}
+	}
+}
+.dj_ff3 {
+	.mblCheckBox {
+		-moz-border-radius: @default-button-border-radius;
+	}
+}
\ No newline at end of file
diff --git a/dojox/mobile/themes/common/CheckBox.less b/dojox/mobile/themes/common/CheckBox.less
index 49e56f3..abed7ac 100644
--- a/dojox/mobile/themes/common/CheckBox.less
+++ b/dojox/mobile/themes/common/CheckBox.less
@@ -1,23 +1,40 @@
 /* dojox.mobile.CheckBox */
 .mblCheckBox {
 	position: relative;
+	margin: -0.5em 3px 0.3em 4px;
+	width: 1em;
+	height: 1em;
+	border-style: outset;
+	border-width: 1px;
+	.mbl-button-background-image();
+	font: inherit;
 	cursor: pointer;
-	outline: none;
-	-webkit-appearance: none;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
+	.appearance(none);
+	.tap-highlight-color(rgba(255,255,255,0));
+	.transform(translateY(0.45em));
 	.mblCheckBox-styles;
 }
 .mblCheckBoxSelected {
-	.mblCheckBoxSelected-styles;
+	.mbl-button-selected-background-image();
 }
 .mblCheckBoxChecked,
 .mblCheckBox:checked {
-	.mblCheckBoxChecked-styles;
+	.mbl-button-checked-background-image();
 	&::after {
+		position: absolute;
+		content: "";
+		width: 0.3em;
+		height: 0.6em;
+		top: 0;
+		left: 0.3em;
+		border-width: 0.15em;
+		border-style: none solid solid none;
+		.transform(rotate(45deg));
+		.transform-origin(50% 50%);
 		.mblCheckBoxChecked-after-styles;
 	}
 	&.mblCheckBoxSelected {
-		.mblCheckBoxChecked-mblCheckBoxSelected-styles;
+		.mbl-blue-button-selected-background-image();
 		&::after {
 			.mblCheckBoxChecked-mblCheckBoxSelected-after-styles;
 		}
diff --git a/dojox/mobile/themes/common/ComboBox-compat.less b/dojox/mobile/themes/common/ComboBox-compat.less
new file mode 100644
index 0000000..c25fbe9
--- /dev/null
+++ b/dojox/mobile/themes/common/ComboBox-compat.less
@@ -0,0 +1,9 @@
+/* dojox.mobile.ComboBox */
+.dj_gecko {
+	.dijitPopup {
+		-moz-box-shadow: @mbl-combo-box-popup-box-shadow;
+	}
+	.mblComboBoxMenuItemSelected {
+		background-image: @default-selected-background-image-gecko;
+	}
+}
diff --git a/dojox/mobile/themes/common/ComboBox.less b/dojox/mobile/themes/common/ComboBox.less
index 4358887..82ffd1b 100644
--- a/dojox/mobile/themes/common/ComboBox.less
+++ b/dojox/mobile/themes/common/ComboBox.less
@@ -7,6 +7,7 @@
 	position: absolute;
 	border: 0;
 	background-color: transparent;
+	.box-shadow(@mbl-combo-box-popup-box-shadow);
 	.dijitPopup-styles;
 }
 .mblReset {
@@ -18,12 +19,17 @@
 	color: inherit;
 }
 .mblComboBoxMenu {
-	overflow-y: hidden !important;
 	position: relative;
+	overflow-y: hidden !important;
 	overflow: hidden;
+	border: 1px solid black;
 	.mblComboBoxMenu-styles;
 }
 .mblComboBoxMenuItem {
+	padding: .1em .2em;
+	border-width: 1px 0 1px 0;
+	border-style: solid;
+	text-align: left;
 	white-space: nowrap;
 	.mblComboBoxMenuItem-styles;
 }
@@ -36,5 +42,6 @@
 }
 .mblComboBoxMenuPreviousButton,
 .mblComboBoxMenuNextButton {
-	.mblComboBoxMenuPreviousButton-styles;
+	font-style: italic;
+	overflow: hidden;
 }
diff --git a/dojox/mobile/themes/common/ComboBox_rtl.less b/dojox/mobile/themes/common/ComboBox_rtl.less
new file mode 100644
index 0000000..01b9527
--- /dev/null
+++ b/dojox/mobile/themes/common/ComboBox_rtl.less
@@ -0,0 +1,4 @@
+/* dojox.mobile.ComboBox Rtl*/
+.mblComboBoxMenuItemRtl {
+  text-align: right;
+}
diff --git a/dojox/mobile/themes/common/EdgeToEdgeCategory.less b/dojox/mobile/themes/common/EdgeToEdgeCategory.less
index 13d78e4..0625319 100644
--- a/dojox/mobile/themes/common/EdgeToEdgeCategory.less
+++ b/dojox/mobile/themes/common/EdgeToEdgeCategory.less
@@ -1,8 +1,13 @@
 /* dojox.mobile.EdgeToEdgeCategory */
 .mblEdgeToEdgeCategory {
 	position: relative;
+	margin: 0;
+	padding: 0 10px;
 	overflow: hidden;
-	white-space: nowrap;
+	font-family: Helvetica;
+	font-size: 16px;
+	font-weight: bold;
 	text-overflow: ellipsis;
+	white-space: nowrap;
 	.mblEdgeToEdgeCategory-styles;
 }
diff --git a/dojox/mobile/themes/common/EdgeToEdgeList.less b/dojox/mobile/themes/common/EdgeToEdgeList.less
index 9fbed0e..d199da9 100644
--- a/dojox/mobile/themes/common/EdgeToEdgeList.less
+++ b/dojox/mobile/themes/common/EdgeToEdgeList.less
@@ -1,6 +1,8 @@
 /* dojox.mobile.EdgeToEdgeList */
 .mblEdgeToEdgeList {
-	position: relative; /* IE needs this */
+//cmp	position: relative; // IE needs this
+	margin: 0;
+	padding: 0;
 	.mblEdgeToEdgeList-styles;
 	.mblListItem:last-child {
 		.mblEdgeToEdgeList-LastListItem-styles;
diff --git a/dojox/mobile/themes/common/FixedSplitter.css b/dojox/mobile/themes/common/FixedSplitter.css
deleted file mode 100644
index 6788969..0000000
--- a/dojox/mobile/themes/common/FixedSplitter.css
+++ /dev/null
@@ -1,22 +0,0 @@
-.mblFixedSpliter {
-	width: 100%;
-	height: 100%;
-}
-
-.mblFixedSplitterPane {
-	position: absolute;
-	overflow-x: hidden;
-	overflow-y: auto;
-}
-
-.mblFixedSplitterPaneH {
-	position: absolute;
-	height: 100%;
-	top: 0px;
-}
-
-.mblFixedSplitterPaneV {
-	position: absolute;
-	width: 100%;
-	left: 0px;
-}
diff --git a/dojox/mobile/themes/common/FixedSplitter.less b/dojox/mobile/themes/common/FixedSplitter.less
new file mode 100644
index 0000000..8faab53
--- /dev/null
+++ b/dojox/mobile/themes/common/FixedSplitter.less
@@ -0,0 +1,22 @@
+/* dojox.mobile.FixedSplitter */
+.mblFixedSplitter {
+	width: 100%;
+	height: 100%;
+}
+
+/* For FixedSplitter's child panes */
+.mblFixedSplitter > * {
+	position: absolute;
+	overflow-x: hidden;
+	overflow-y: auto;
+}
+
+.mblFixedSplitterH > * {
+	height: 100%;
+	top: 0px;
+}
+
+.mblFixedSplitterV > * {
+	width: 100%;
+	left: 0px;
+}
diff --git a/dojox/mobile/themes/common/FormLayout.less b/dojox/mobile/themes/common/FormLayout.less
new file mode 100644
index 0000000..0525cf5
--- /dev/null
+++ b/dojox/mobile/themes/common/FormLayout.less
@@ -0,0 +1,218 @@
+/* Single Column Layout */
+/**********************************************************************************************************************/
+
+/*** columns == 'auto' ***/
+ at media all and (max-width: 500px) {
+	.mblFormLayout.mblFormLayoutAuto fieldset {
+		padding-left: 0;
+		padding-right: 0;
+	}
+
+	/* A gap between rows */
+	.mblFormLayout.mblFormLayoutAuto > * + * {
+		margin-top: 0.6em;
+	}
+
+	/* Text widgets */
+	.mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+	.mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+	.mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+	.mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+	.mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"]{
+		width: 100%;
+		box-sizing: border-box;
+	}
+}
+
+/*** columns == 'single' ***/
+.mblFormLayout.mblFormLayoutSingleCol fieldset {
+	padding-left: 0;
+	padding-right: 0;
+}
+
+/* A gap between rows */
+.mblFormLayout.mblFormLayoutSingleCol > * + * {
+	margin-top: 0.6em;
+}
+
+/* Text widgets */
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.SearchBox"]{
+	width: 100%;
+	box-sizing: border-box;
+}
+
+
+/* Two Columns Layout */
+/**********************************************************************************************************************/
+
+/*** columns == 'auto' ***/
+ at media all and (min-width: 500px) {
+	/* Form layout selector*/
+	.mblFormLayout.mblFormLayoutAuto {
+		display: table;
+		width: 100%;
+	}
+
+	/* Form rows */
+	.mblFormLayout.mblFormLayoutAuto > * {
+		display: table-row;
+	}
+	/* Form cells */
+	.mblFormLayout.mblFormLayoutAuto > * > * {
+		display: table-cell;
+		vertical-align: top;
+		padding: 0.5em 0;
+	}
+
+	/* Left cells */
+	.mblFormLayout.mblFormLayoutAuto > * > *:first-child {
+		width:20%;
+		padding-right: 0.5em;
+	}
+
+	/* mblFormLayoutRightAlign optional selector definition */
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child {
+		text-align: right;
+	}
+
+	/* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+		margin-right: 0;
+	}
+
+	/* The Slider sticks to its bounds when margin=10px */
+	.mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+		display: inline-block;
+		margin-right: 10px;
+		margin-top: 0px;
+	}
+
+	/* Text widgets */
+	.mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+	.mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+	.mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+	.mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+	.mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"]{
+		width: 50%;
+		box-sizing: border-box;
+	}
+}
+
+/*** columns == 'two' ***/
+
+/* Form layout selector*/
+.mblFormLayout.mblFormLayoutTwoCol {
+	display: table;
+	width: 100%;
+}
+
+/* Form rows */
+.mblFormLayout.mblFormLayoutTwoCol > * {
+	display: table-row;
+}
+/* Form cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > * {
+	display: table-cell;
+	vertical-align: top;
+	padding: 0.5em 0;
+}
+
+/* Left cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > *:first-child {
+	width:20%;
+	padding-right: 0.5em;
+}
+
+/* mblFormLayoutRightAlign optional selector definition */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child {
+	text-align: right;
+}
+
+/* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+	margin-right: 0;
+}
+
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+	display: inline-block;
+	margin-right: 10px;
+	margin-top: 0px;
+}
+
+/* Text widgets */
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.SearchBox"]{
+	width: 50%;
+	box-sizing: border-box;
+}
+
+/* Common Rules*/
+/**********************************************************************************************************************/
+
+.mblFormLayout fieldset {
+	border: none;
+	margin: 0;
+}
+
+/* Bold widget labels */
+.mblFormLayout > * > *:first-child {
+	font-weight: bold;
+}
+
+/* Whatever the screen width, force left margin of first elements and elements following a <br> */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Button"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ToggleButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.CheckBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Switch"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.RadioButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.SearchBox"] {
+	margin-left: 0;
+}
+
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > .mblSlider:first-child {
+	display: inline-block;
+	margin-left: 10px;
+	margin-top: 0;
+	margin-bottom: 0;
+}
diff --git a/dojox/mobile/themes/common/GridLayout.less b/dojox/mobile/themes/common/GridLayout.less
new file mode 100644
index 0000000..ca40798
--- /dev/null
+++ b/dojox/mobile/themes/common/GridLayout.less
@@ -0,0 +1,28 @@
+/* dojox.mobile.GridLayout */
+.mblGridLayout {
+	width: 100%;
+	height: 100%;
+	padding: 0;
+}
+
+.mblGridLayout > div {
+	margin: 0;
+	border: 0;
+	padding: 0;
+	float: left;
+	min-height:1px;
+}
+
+.mblGridItemFirstColumn {
+	clear:left;
+}
+
+.mblGridItemTerminator {
+	clear:both;
+}
+
+.mblGridItemLastItem:after {
+	content: "";
+	display: block;
+	clear:both;
+}
diff --git a/dojox/mobile/themes/common/Heading-compat.less b/dojox/mobile/themes/common/Heading-compat.less
new file mode 100644
index 0000000..65438ff
--- /dev/null
+++ b/dojox/mobile/themes/common/Heading-compat.less
@@ -0,0 +1,13 @@
+/* dojox.mobile.Heading */
+.mblHeading {
+	background-image: url(compat/heading-bg.png);
+}
+.mblHeadingSpanTitle {
+	white-space: normal;
+}
+
+.dj_gecko {
+	.mblHeading {
+		background-image: @heading-background-image-gecko;
+	}
+}
diff --git a/dojox/mobile/themes/common/Heading.less b/dojox/mobile/themes/common/Heading.less
index 38083f9..9e0d947 100644
--- a/dojox/mobile/themes/common/Heading.less
+++ b/dojox/mobile/themes/common/Heading.less
@@ -1,12 +1,19 @@
 /* dojox.mobile.Heading */
 .mblHeading {
 	position: relative;
-	margin: 0px;
+	margin: 0;
 	width: 100%;
 	overflow: hidden;
 	white-space: nowrap;
 	text-overflow: ellipsis;
 	z-index: 1;
+	padding: 0;
+	height: 42px;
+	font-family: Helvetica;
+	font-size: 20px;
+	font-weight: bold;
+	text-align: center;
+	line-height: 44px;
 	.mblHeading-styles;
 }
 .mblHeading * {
@@ -16,7 +23,7 @@
 	position: absolute;
 	width: 100%;
 	display: none;
-	left: 0px;
+	left: 0;
 	z-index: 1;
 }
 .mblHeadingCenterTitle .mblHeadingDivTitle {
@@ -25,34 +32,3 @@
 .mblHeadingCenterTitle .mblHeadingSpanTitle {
 	display: none;
 }
-
-/* Heading Arrow Button */
-.mblArrowButton {
-	position: relative;
-	float: left;
-	.mblArrowButton-styles;
-}
-.mblArrowButtonHead {
-	position: absolute;
-	.mblArrowButtonHead-styles;
-}
-.dj_chrome .mblArrowButtonHead {
-	.mblArrowButtonHeadChrome-styles;
-}
-.mblArrowButtonBody {
-	position: absolute;
-	cursor: pointer;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
-	.mblArrowButtonBody-styles;
-}
-.mblArrowButtonSelected {
-	.mblArrowButtonHead, .mblArrowButtonBody {
-		.mblArrowButtonSelected-styles;
-	}
-	.mblArrowButtonHead {
-		.mblArrowButtonHeadSelected-styles;
-	}
-	.mblArrowButtonBody {
-		.mblArrowButtonBodySelected-styles;
-	}
-}
diff --git a/dojox/mobile/themes/common/IconContainer-compat.less b/dojox/mobile/themes/common/IconContainer-compat.less
new file mode 100644
index 0000000..40d7bd8
--- /dev/null
+++ b/dojox/mobile/themes/common/IconContainer-compat.less
@@ -0,0 +1,16 @@
+/* dojox.mobile.IconContainer */
+.mblIconItemPaneHeading {
+	background-image: url(compat/icon-content-heading-bg.png);
+}
+
+.dj_gecko {
+	.mblIconItemPaneHeading {
+		background-image: -moz-linear-gradient(top, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
+	}
+}
+
+.dj_ie7 {
+	.mblIconAreaInner {
+		font-size: 60px;
+	}
+}
\ No newline at end of file
diff --git a/dojox/mobile/themes/common/IconContainer.less b/dojox/mobile/themes/common/IconContainer.less
index 0f47a0f..a3268f2 100644
--- a/dojox/mobile/themes/common/IconContainer.less
+++ b/dojox/mobile/themes/common/IconContainer.less
@@ -1,41 +1,52 @@
 /* dojox.mobile.IconContainer */
 .mblIconContainer {
-	.mblIconContainer-styles;
+	margin: 20px 10px;
+	padding: 0;
 }
 
 /* dojox.mobile.IconItem */
 .mblIconItem {
+	position: relative;
+	overflow: hidden; /* for focus frame */
 	list-style-type: none;
 	float: left;
-	-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+	.tap-highlight-color(rgba(255, 255, 255, 0));
 }
 .mblIconItemTerminator {
 	list-style-type: none;
 	clear: both;
-	.mblIconItemTerminator-styles;
 }
-.mblIconItemSub {
+.mblIconItemPane {
 	list-style-type: none;
 	.mblIconItemSub-styles;
 }
 .mblIconArea {
+	position: relative;
+	height: 78px;
+	font-family: Helvetica;
+	font-size: 12px;
+	text-align: center;
 	.mblIconArea-styles;
-	div {
-		position: relative;
-		height: 65px;
-		line-height: 65px;
-		text-align: center;
-	}
 	img {
 		vertical-align: middle;
 	}
 }
+.mblIconAreaInner {
+	position: relative;
+	height: 65px;
+	line-height: 65px;
+	text-align: center;
+}
+.mblIconItemDeleteIcon {
+	position: absolute;
+	.mblIconItemDeleteIcon-styles;
+}
 .mblIconItemSpriteIcon {
 	position: absolute;
 }
 .mblContent {
 	clear: both;
-	.mblContent-styles;
+	padding-bottom: 20px;
 }
 table.mblClose {
 	clear: both;
@@ -43,37 +54,65 @@ table.mblClose {
 }
 .mblVibrate{
 	position: relative;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-timing-function: ease-in-out;
-	-webkit-animation-iteration-count: 20;
-	-webkit-animation-name: mblVibrate;
-	-webkit-transform: rotate(0deg);
+	.animation-duration(.5s);
+	.animation-timing-function(ease-in-out);
+	.animation-iteration-count(infinite);
+	.animation-name(mblVibrate);
+	.transform(rotate(0deg));
 }
 .mblCloseContent{
-	-webkit-animation-duration: .3s;
-	-webkit-animation-timing-function: ease-in-out;
-	-webkit-animation-name: mblShrink;
-	-webkit-transform: scale(0.01);
+	.animation-duration(.3s);
+	.animation-timing-function(ease-in-out);
+	.animation-name(mblShrink);
+	.transform(scale(0.01));
 	&.mblShrink0{
-		-webkit-animation-name: mblShrink0;
+		.animation-name(mblShrink0);
 	}
 	&.mblShrink1{
-		-webkit-animation-name: mblShrink1;
+		.animation-name(mblShrink1);
 	}
 	&.mblShrink2{
-		-webkit-animation-name: mblShrink2;
+		.animation-name(mblShrink2);
 	}
 	&.mblShrink3{
-		-webkit-animation-name: mblShrink3;
+		.animation-name(mblShrink3);
 	}
 }
 
-/* Icon Content Heading */
-.mblIconContentHeading {
+/* dojox.mobile._IconItemPane */
+.mblIconItemPaneHeading {
 	position: relative;
 	clear: both;
 	overflow: hidden;
-	white-space: nowrap;
+	margin-top: 0px;
+	padding-left: 40px;
+	height: 25px;
+	border-top: 1px solid #f1f3f4;
+	border-bottom: 1px solid #717d85;
+	.background-image-linear-gradient-top-bottom-2-stops(#e0e4e7, #b4bec6, 0.5, #c4ccd2, 0.5, #bfc8ce);
+	font-family: Helvetica;
+	font-size: 14px;
+	color: white;
+	line-height: 26px;
+	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
 	text-overflow: ellipsis;
-	.mblIconContentHeading-styles;
+	white-space: nowrap;
 }
+.mblIconItemPaneIcon {
+	position: absolute;
+	top: -2px;
+	left: 1px;
+}
+
+ at -webkit-keyframes mblVibrate { .keyframes-vibrate-webkit(); }
+ at keyframes         mblVibrate { .keyframes-vibrate       (); }
+ at -webkit-keyframes mblShrink  { .keyframes-transform-from-to-webkit(scale(1), scale(0.01)); }
+ at keyframes         mblShrink  { .keyframes-transform-from-to       (scale(1), scale(0.01)); }
+ at -webkit-keyframes mblShrink0 { .keyframes-transform-from-to-webkit(scale(1), translate(-40%,-70%) scale(0.01)); }
+ at keyframes         mblShrink0 { .keyframes-transform-from-to       (scale(1), translate(-40%,-70%) scale(0.01)); }
+ at -webkit-keyframes mblShrink1 { .keyframes-transform-from-to-webkit(scale(1), translate(-14%,-70%) scale(0.01)); }
+ at keyframes         mblShrink1 { .keyframes-transform-from-to       (scale(1), translate(-14%,-70%) scale(0.01)); }
+ at -webkit-keyframes mblShrink2 { .keyframes-transform-from-to-webkit(scale(1), translate(14%,-70%)  scale(0.01)); }
+ at keyframes         mblShrink2 { .keyframes-transform-from-to       (scale(1), translate(14%,-70%)  scale(0.01)); }
+ at -webkit-keyframes mblShrink3 { .keyframes-transform-from-to-webkit(scale(1), translate(40%,-70%)  scale(0.01)); }
+ at keyframes         mblShrink3 { .keyframes-transform-from-to       (scale(1), translate(40%,-70%)  scale(0.01)); }
diff --git a/dojox/mobile/themes/common/IconContainer_rtl.less b/dojox/mobile/themes/common/IconContainer_rtl.less
new file mode 100644
index 0000000..fa7e839
--- /dev/null
+++ b/dojox/mobile/themes/common/IconContainer_rtl.less
@@ -0,0 +1,14 @@
+/* dojox.mobile.IconItem Rtl */
+.mblIconItemRtl {
+  float: right;
+}
+.mblIconItemRtl .mblIconItemDeleteIcon {
+  right: @mbl-icon-container-right-rtl;
+}
+/* dojox.mobile._IconItemPane Rtl*/
+.mblIconItemPaneRtl .mblIconItemPaneHeading {
+  padding-right: 40px;
+}
+.mblIconItemPaneRtl .mblIconItemPaneIcon {
+  right: 1px;
+}
diff --git a/dojox/mobile/themes/common/IconMenu-compat.less b/dojox/mobile/themes/common/IconMenu-compat.less
new file mode 100644
index 0000000..aeb80eb
--- /dev/null
+++ b/dojox/mobile/themes/common/IconMenu-compat.less
@@ -0,0 +1,44 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+	.mblIconMenu-compat;
+}
+.mblIconMenuItemSel {
+	.mblIconMenuItemSel-compat;
+}
+
+.dj_gecko {
+	.mblIconMenu {
+		.mblIconMenu-compat-gecko;
+	}
+	.mblIconMenuItem {
+		-moz-box-sizing: border-box;
+	}
+	.mblIconMenuItemSel {
+		.mblIconMenuItemSel-compat-gecko;
+	}
+}
+
+.dj_ff3 {
+	.mblIconMenu {
+		-moz-border-radius: @mbl-icon-menu-border-radius;
+	}
+	.mblIconMenuItemIcon img {
+	  border: 1px solid red;
+	}
+	.mblIconMenuItemFirstRow {
+		&.mblIconMenuItemFirstColumn {
+			-moz-border-top-left-radius: @mbl-icon-menu-item-border-radius;
+		}
+		&.mblIconMenuItemLastColumn {
+			-moz-border-top-right-radius: @mbl-icon-menu-item-border-radius;
+		}
+	}
+	.mblIconMenuItemLastRow {
+		&.mblIconMenuItemFirstColumn {
+			-moz-border-bottom-left-radius: @mbl-icon-menu-item-border-radius;
+		}
+		&.mblIconMenuItemLastColumn {
+			-moz-border-bottom-right-radius: @mbl-icon-menu-item-border-radius;
+		}
+	}
+}
diff --git a/dojox/mobile/themes/common/IconMenu.less b/dojox/mobile/themes/common/IconMenu.less
new file mode 100644
index 0000000..4fa2e34
--- /dev/null
+++ b/dojox/mobile/themes/common/IconMenu.less
@@ -0,0 +1,62 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+	width: 100%;
+	height: 100%;
+	border-radius: @mbl-icon-menu-border-radius;
+	text-align: center;
+	.tap-highlight-color(rgba(255, 255, 255, 0));
+	.mblIconMenu-styles;
+}
+
+/* dojox.mobile.IconMenuItem */
+.mblIconMenuItem {
+	float: left;
+	list-style-type: none;
+	.box-sizing(border-box);
+	.mblIconMenuItem-styles;
+}
+.mblIconMenuItemIcon {
+	position: relative;
+	margin-left: auto;
+	margin-right: auto;
+}
+.mblIconMenuItemFirstColumn {
+	border-left: none;
+}
+.mblIconMenuItemLastRow {
+	border-bottom: none;
+}
+.mblIconMenuItemFirstRow {
+	&.mblIconMenuItemFirstColumn {
+		border-top-left-radius: @mbl-icon-menu-item-border-radius;
+	}
+	&.mblIconMenuItemLastColumn {
+		border-top-right-radius: @mbl-icon-menu-item-border-radius;
+	}
+}
+.mblIconMenuItemLastRow {
+	&.mblIconMenuItemFirstColumn {
+		border-bottom-left-radius: @mbl-icon-menu-item-border-radius;
+	}
+	&.mblIconMenuItemLastColumn {
+		border-bottom-right-radius: @mbl-icon-menu-item-border-radius;
+	}
+}
+.mblIconMenuItemAnchor {
+	display: block;
+	height: 100%;
+	font-family: Helvetica;
+	text-decoration: none;
+	.mblIconMenuItemAnchor-styles;
+  cursor: pointer;
+}
+.mblIconMenuItemTable {
+	width: 100%;
+	height: 100%;
+	img {
+		border: none;
+	}
+}
+.mblIconMenuItemSel {
+	.mblIconMenuItemSel-styles;
+}
diff --git a/dojox/mobile/themes/common/IconMenu_rtl-compat.less b/dojox/mobile/themes/common/IconMenu_rtl-compat.less
new file mode 100644
index 0000000..7c05eae
--- /dev/null
+++ b/dojox/mobile/themes/common/IconMenu_rtl-compat.less
@@ -0,0 +1,19 @@
+/* dojox.mobile.IconMenu Rtl */
+
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-right-radius: @mbl-border-radius-rtl;
+  -moz-border-top-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-left-radius: @mbl-border-radius-rtl;
+  -moz-border-top-right-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-right-radius: @mbl-border-radius-rtl;
+  -moz-border-bottom-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-left-radius: @mbl-border-radius-rtl;
+  -moz-border-bottom-right-radius: 0px;
+}
+
diff --git a/dojox/mobile/themes/common/IconMenu_rtl.less b/dojox/mobile/themes/common/IconMenu_rtl.less
new file mode 100644
index 0000000..b6b51a2
--- /dev/null
+++ b/dojox/mobile/themes/common/IconMenu_rtl.less
@@ -0,0 +1,87 @@
+.mblIconMenuItemRtl {
+  float: right;
+}
+.first-column(@v){
+&.mblIconMenuItemFirstColumn{
+  border-right: none;
+  border-left: @v;
+}
+}
+
+.menu-item-first-column(@v){
+.mblIconMenuItemRtl{
+    .first-column (@v);
+    }
+}
+
+.top-radius(@r, @l){
+      border-top-right-radius: @r;
+      border-top-left-radius: @l;
+    }
+    
+.bottom-radius(@r, @l){
+    border-bottom-right-radius: @r;
+    border-bottom-left-radius: @l;
+    }    
+    
+.first-row-first-column(@r, @l: 0px){
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  .top-radius(@r, @l);
+}    
+}
+
+.first-row-last-column(@r: 0px, @l){
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  .top-radius(@r, @l);
+}
+}
+
+.last-row-first-column(@r, @l: 0px){
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  .bottom-radius(@r, @l);
+}   
+}
+
+.last-row-last-column(@r: 0px, @l){
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+   .bottom-radius(@r, @l);
+}
+}
+.mixin(android, @r:6px, @l: 0px, @v:~"1px solid rgba(96, 96, 96, 0.85)"){
+   .menu-item-first-column(@v);
+   .first-row-first-column(@r, @l);
+   .first-row-last-column(@l, @r);
+   .last-row-first-column(@r, @l);
+   .last-row-last-column(@l , at r);
+   
+}
+
+.mixin(iphone, @r:10px, @l: 0px, @v:~"1px solid #6b6c6f"){
+   .menu-item-first-column(@v);
+   .first-row-first-column(@r, @l);
+   .first-row-last-column(@l, @r);
+   .last-row-first-column(@r, @l);
+   .last-row-last-column(@l , at r);
+   
+}
+
+.mixin(custom, @r:3px, @l: 0px, @v:~"1px solid rgba(192, 192, 192, 0.85)"){
+   .menu-item-first-column(@v);
+   .first-row-first-column(@r, @l);
+   .first-row-last-column(@l, @r);
+   .last-row-first-column(@r, @l);
+   .last-row-last-column(@l , at r);
+   
+}
+.mixin(blackberry, @v:~"1px solid #000000"){
+    .first-column(@v);  
+}
+.mixin(holoDark, @r:6px, @l: 0px, @v:~"1px solid rgba(96, 96, 96, 0.85)"){
+   .menu-item-first-column(@v);
+   .first-row-first-column(@r, @l);
+   .first-row-last-column(@l, @r);
+   .last-row-first-column(@r, @l);
+   .last-row-last-column(@l , at r);
+   
+}
+.mixin(@theme-id);
diff --git a/dojox/mobile/themes/common/ListItem-compat.less b/dojox/mobile/themes/common/ListItem-compat.less
new file mode 100644
index 0000000..12b1c16
--- /dev/null
+++ b/dojox/mobile/themes/common/ListItem-compat.less
@@ -0,0 +1,16 @@
+/* dojox.mobile.ListItem */
+.mblListItemSelected {
+	background-color: @default-selected-background-color;
+}
+
+.dj_gecko {
+	.mblListItemSelected {
+		background-image: @default-selected-background-image-gecko;
+	}
+}
+
+.dj_ie6 {
+	.mblListItem {
+		vertical-align: bottom;
+	}
+}
diff --git a/dojox/mobile/themes/common/ListItem.less b/dojox/mobile/themes/common/ListItem.less
index 2b49a2a..ab11342 100644
--- a/dojox/mobile/themes/common/ListItem.less
+++ b/dojox/mobile/themes/common/ListItem.less
@@ -1,78 +1,117 @@
 /* dojox.mobile.ListItem */
 .mblListItem {
 	position: relative;
+	overflow: hidden; /* for focus frame */
+	padding: 0 8px;
+	height: @mbl-list-item-height;
 	list-style-type: none;
-	vertical-align: bottom; /* To avoid IE6 LI bug */
+	line-height: @mbl-list-item-height;
+	.tap-highlight-color(rgba(255,255,255,0));
 	.mblListItem-styles;
 	&.mblVariableHeight {
+		padding: 11px 8px;
 		height: auto;
-		.mblListItem-mblVariableHeight-styles;
-	}
-	.mblListItemAnchor {
-		display: block;
-		height: 100%;
-		-webkit-tap-highlight-color: rgba(255,255,255,0);
-		.mblListItem-mblListItemAnchor-styles;
-		* {
-			-webkit-tap-highlight-color: rgba(0, 0, 0, 0.2);
-		}
+		line-height: normal;
 	}
 }
-.mblItemSelected {
-	.mblItemSelected-styles;
-	.mblListItemSubText {
-		.mblItemSelected-mblListItemSubText-styles;
-	}
-	.mblListItemAnchor {
-		.mblItemSelected-mblListItemAnchor-styles;
-	}
+.mblListItemSelected {
+	.mblListItemSelected-styles;
 	.mblDomButton {
 		div {
-			.mblItemSelected-mblDomButton-Div-styles;
+			border-color: white;
 		}
 	}
 }
-.mblListItemTextBoxSelected {
-	.mblListItemTextBoxSelected-styles;
+.mblListItemLabelSelected {
+	.mblListItemLabelSelected-styles;
 }
 .mblListItemChecked {
 	.mblListItemChecked-styles;
 }
-.mblListItemIcon {
-	float: left;
-	line-height: normal;
-	.mblListItemIcon-styles;
+
+.mblListItemChecked .mblListItemRightIcon {
+	visibility: visible;
 }
-.mblListItemSpriteIcon {
+.mblListItemChecked .mblListItemUncheckIcon {
 	position: absolute;
-	.mblListItemSpriteIcon-styles;
+	visibility: hidden;
+}
 
+.mblListItemUnchecked .mblListItemRightIcon {
+	visibility: hidden;
+}
+.mblListItemUnchecked .mblListItemUncheckIcon {
+	visibility: visible;
+}
+
+.mblListItemDeleteIcon {
+	position: relative;
+	float: left;
+	line-height: normal;
+	margin-top: (@mbl-list-item-height - 29) / 2; // '29': Icon's height.
+	margin-bottom: -(@mbl-list-item-height - 29) / 2;
+	margin-right: 11px;
+}
+.mblListItemIcon {
+	position: relative;
+	float: left;
+	line-height: normal;
+	margin-top: (@mbl-list-item-height - 29) / 2;
+	margin-bottom: -(@mbl-list-item-height - 29) / 2;
+	margin-right: 11px;
 }
 .mblListItemRightIcon,
-.mblListItemRightIcon2 {
+.mblListItemRightIcon2,
+.mblListItemUncheckIcon {
 	position: relative;
 	float: right;
 	line-height: normal;
-	.mblListItemRightIcon-styles;
+	margin-top: (@mbl-list-item-height - 29) / 2;
+	margin-bottom: -(@mbl-list-item-height - 29) / 2;
 }
+
 .mblListItemRightText {
 	position: relative;
 	float: right;
 	line-height: normal;
+	margin-right: 4px;
 	.mblListItemRightText-styles;
 }
-.mblListItemTextBox {
+.mblListItemLabel {
+	position: relative;
 	overflow: hidden;
 	white-space: nowrap;
 	text-overflow: ellipsis;
-	.mblListItemTextBox-styles;
+	height: 100%;
 }
-.mblVariableHeight .mblListItemTextBox {
+.mblVariableHeight .mblListItemLabel {
 	white-space: normal;
 }
-.mblListItemAnchorNoIcon .mblListItemTextBox {
-	.mblListItemAnchorNoIcon-mblListItemTextBox-styles;
-}
 .mblListItemSubText {
 	.mblListItemSubText-styles;
 }
+
+.mblListItemLayoutLeft {
+	position: relative;
+	float: left;
+	margin-right: 11px;
+}
+.mblListItemLayoutCenter {
+	position: absolute;
+	width: 100%;
+	text-align: center;
+}
+.mblListItemLayoutRight {
+	position: relative;
+	float: right;
+}
+
+/* dojox.mobile._EditableListMixin */
+.mblListItemFloat {
+	position: absolute;
+	border: 1px solid gray;
+	opacity: 0.5;
+	.box-shadow(5px 5px 5px rgba(0, 0, 0, 0.5));
+	border-radius: 0px !important;
+	-moz-border-radius: 0px !important;
+}
diff --git a/dojox/mobile/themes/common/ListItem_rtl.less b/dojox/mobile/themes/common/ListItem_rtl.less
new file mode 100644
index 0000000..a755b9b
--- /dev/null
+++ b/dojox/mobile/themes/common/ListItem_rtl.less
@@ -0,0 +1,27 @@
+/* dojox.mobile.ListItem Rtl*/
+.mblListItemRtl .mblListItemDeleteIcon {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemIcon {
+  float: right;
+  margin-left: 11px;
+  margin-right: 0px;
+}
+.mblListItemRtl .mblListItemRightIcon,
+.mblListItemRtl .mblListItemRightIcon2,
+.mblListItemRtl .mblListItemUncheckIcon {
+  float: left;
+}
+.mblListItemRtl .mblListItemRightText {
+  float: left;
+  margin-left: 4px;
+}
+.mblListItemRtl .mblListItemLayoutLeft {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemLayoutRight {
+  float: left;
+}
+
diff --git a/dojox/mobile/themes/common/Overlay-compat.less b/dojox/mobile/themes/common/Overlay-compat.less
new file mode 100644
index 0000000..5d3bb6f
--- /dev/null
+++ b/dojox/mobile/themes/common/Overlay-compat.less
@@ -0,0 +1,22 @@
+/* dojox.mobile.Overlay */
+.mblOverlay {
+	text-align: center;
+	.mblOverlay-compat;
+}
+.dj_gecko {
+	.mblOverlay {
+		text-align: -moz-center;
+		.mblOverlay-compat-gecko;
+	}
+}
+.dj_ie9, .dj_ie8 {
+	.mblOverlay > *
+	{
+		margin: 0 auto;
+	}
+}
+.dj_ie6 {
+	.mblOverlay {
+		*position: absolute;
+	}
+}
diff --git a/dojox/mobile/themes/common/PageIndicator.less b/dojox/mobile/themes/common/PageIndicator.less
index 6678f9e..06f4176 100644
--- a/dojox/mobile/themes/common/PageIndicator.less
+++ b/dojox/mobile/themes/common/PageIndicator.less
@@ -3,7 +3,7 @@
 	position: relative;
 	width: 100%;
 	height: 20px;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
+	.tap-highlight-color(rgba(255,255,255,0));
 }
 .mblPageIndicatorContainer {
 	margin-top: 4px;
@@ -16,8 +16,7 @@
 	height: 6px;
 	font-size: 1px;
 	background-color: #949294;
-	-webkit-border-radius: 3px;
-	-moz-border-radius: 3px;
+	border-radius: 3px;
 }
 .mblPageIndicatorDotSelected {
 	background-color: white;
diff --git a/dojox/mobile/themes/common/PageTurning.css b/dojox/mobile/themes/common/PageTurning.css
new file mode 100644
index 0000000..35cffbe
--- /dev/null
+++ b/dojox/mobile/themes/common/PageTurning.css
@@ -0,0 +1,38 @@
+.mblPageTurningCatalog {
+	position: absolute;
+	overflow: hidden;
+}
+
+.mblPageTurningPage {
+	position: absolute;
+	overflow: hidden;
+	-webkit-transform-origin: 100% 0%;
+	-webkit-transition-property: -webkit-transform; 
+	-webkit-transition-duration: 0s;
+}
+
+.mblPageTurningFront {
+	position: absolute;
+	overflow: hidden;
+	-webkit-box-shadow: 0 0 11px rgba(0, 0, 0, .7);
+	-webkit-transform-origin: 0px 0px;
+	-webkit-transition-property: -webkit-transform, -webkit-transform-origin;
+	-webkit-transition-duration: 0s;
+}
+
+.mblPageTurningBack {
+	position: absolute;
+	background: white;
+	overflow: hidden;
+	-webkit-box-shadow: 0 0 11px rgba(0, 0, 0, .7);
+	-webkit-transform-origin:  0px 0px;
+	-webkit-transition-property: -webkit-transform, -webkit-transform-origin;
+	-webkit-transition-duration: 0s;
+}
+
+.mblPageTurningShadow {
+	position: absolute;
+	top: 0px;
+	width: 4px;
+	-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, .7);	
+}
\ No newline at end of file
diff --git a/dojox/mobile/themes/common/ProgressBar-compat.less b/dojox/mobile/themes/common/ProgressBar-compat.less
new file mode 100644
index 0000000..003f91a
--- /dev/null
+++ b/dojox/mobile/themes/common/ProgressBar-compat.less
@@ -0,0 +1,17 @@
+/* Progress Bar */
+.mblProgressBar {
+	.mblProgressBar-compat;
+}
+.mblProgressBarProgress {
+	.mblProgressBarProgress-compat;
+}
+.dj_gecko {
+	.mblProgressBar {
+		.mblProgressBar-compat-gecko;
+	}
+	.mblProgressBarProgress {
+		-moz-transition-property: width;
+		-moz-transition-duration: 0.25s;
+		.mblProgressBarProgress-compat-gecko;
+	}
+}
diff --git a/dojox/mobile/themes/common/ProgressBar.less b/dojox/mobile/themes/common/ProgressBar.less
new file mode 100644
index 0000000..5d99006
--- /dev/null
+++ b/dojox/mobile/themes/common/ProgressBar.less
@@ -0,0 +1,27 @@
+/* dojox.mobile.ProgressBar */
+.mblProgressBar {
+	position: relative;
+	.mblProgressBar-styles;
+}
+.mblProgressBarProgress {
+	.transition-property(width);
+	.transition-duration(0.25s);
+	.mblProgressBarProgress-styles;
+}
+.mblProgressBarComplete {
+	.mblProgressBarComplete-styles;
+}
+.mblProgressBarNotStarted {
+	border-left: none;
+	border-right: none;
+	.mblProgressBarNotStarted-styles;
+}
+.mblProgressBarMsg {
+	position: absolute;
+	top: 0px;
+	width: 100%;
+	height: 100%;
+	text-align: center;
+	font-size: 12px;
+	.mblProgressBarMsg-styles;
+}
diff --git a/dojox/mobile/themes/common/ProgressIndicator-compat.less b/dojox/mobile/themes/common/ProgressIndicator-compat.less
new file mode 100644
index 0000000..d1de0b4
--- /dev/null
+++ b/dojox/mobile/themes/common/ProgressIndicator-compat.less
@@ -0,0 +1,89 @@
+/* Progress Indicator */
+
+.dj_ie {
+	.mblProg {
+		width: 4px;
+		height: 36px;
+	}
+	.mblProg0 {
+		left: 0px;
+	}
+	.mblProg1 {
+		left: 8px;
+	}
+	.mblProg2 {
+		left: 16px;
+	}
+	.mblProg3 {
+		left: 24px;
+	}
+	.mblProg4 {
+		left: 32px;
+	}
+	.mblProg5 {
+		left: 40px;
+	}
+	.mblProg6 {
+		left: 48px;
+	}
+	.mblProg7 {
+		left: 56px;
+	}
+	.mblProg8 {
+		left: 64px;
+	}
+	.mblProg9 {
+		left: 72px;
+	}
+	.mblProg10 {
+		left: 80px;
+	}
+	.mblProg11 {
+		left: 80px;
+	}
+}
+
+.dj_gecko {
+	.mblProgressIndicatorCenter .mblProgContainer {
+	  -moz-transform-origin: 50% 0;
+	}
+	.mblProg {
+	  -moz-transform-origin: 0 2px;
+	}
+	.mblProg0 {
+	  -moz-transform: translate(18px, 10px) rotate(-90.1deg);
+	}
+	.mblProg1 {
+	  -moz-transform: translate(22px, 11px) rotate(-60deg);
+	}
+	.mblProg2 {
+	  -moz-transform: translate(25px, 14px) rotate(-30deg);
+	}
+	.mblProg3 {
+	  -moz-transform: translate(26px, 18px) rotate(0deg);
+	}
+	.mblProg4 {
+	  -moz-transform: translate(25px, 22px) rotate(30deg);
+	}
+	.mblProg5 {
+	  -moz-transform: translate(22px, 25px) rotate(60deg);
+	}
+	.mblProg6 {
+	  -moz-transform: translate(18px, 26px) rotate(90.1deg);
+	}
+	.mblProg7 {
+	  -moz-transform: translate(14px, 25px) rotate(120deg);
+	}
+	.mblProg8 {
+	  -moz-transform: translate(11px, 22px) rotate(150deg);
+	}
+	.mblProg9 {
+	  -moz-transform: translate(10px, 18px) rotate(180deg);
+	}
+	.mblProg10 {
+	  -moz-transform: translate(11px, 14px) rotate(210deg);
+	}
+	.mblProg11 {
+	  -moz-transform: translate(14px, 11px) rotate(240deg);
+	}
+}
diff --git a/dojox/mobile/themes/common/ProgressIndicator.less b/dojox/mobile/themes/common/ProgressIndicator.less
index 8d8b9ab..e33386a 100644
--- a/dojox/mobile/themes/common/ProgressIndicator.less
+++ b/dojox/mobile/themes/common/ProgressIndicator.less
@@ -1,11 +1,25 @@
 /* Progress Indicator */
+.mblProgressIndicator {
+	position: relative;
+	top: 0px;
+}
+.mblHeading .mblProgressIndicator {
+	margin: 5px;
+	float: left;
+}
 .mblProgContainer {
 	position: absolute;
-	width: 40px;
-	height: 40px;
+	width: 100%;
+	height: 100%;
+}
+.mblProgressIndicatorCenter {
+	position: absolute;
 	top: 180px;
 	left: 50%;
-	margin: -18px 0px 0px -18px;
+}
+.mblProgressIndicatorCenter .mblProgContainer {
+	left: -50%;
+	.transform-origin(50% 0);
 }
 .mblProg {
 	position: absolute;
@@ -15,44 +29,118 @@
 	font-size: 1px;
 	height: 4px;
 	overflow: hidden;
-	-webkit-transform-origin: 0 2px;
-	background-color: #C0C0C0;
-	-webkit-border-radius: 2px;
-	-moz-border-radius: 2px;
+	.transform-origin(0 2px);
+	background-color: #c0c0c0;
+	border-radius: 2px;
 }
 .mblProg0 {
-	-webkit-transform: translate(18px,10px) rotate(-90.1deg);
+	.transform(translate(18px,10px) rotate(-90.1deg));
 }
 .mblProg1 {
-	-webkit-transform: translate(22px,11px) rotate(-60deg);
+	.transform(translate(22px,11px) rotate(-60deg));
 }
 .mblProg2 {
-	-webkit-transform: translate(25px,14px) rotate(-30deg);
+	.transform(translate(25px,14px) rotate(-30deg));
 }
 .mblProg3 {
-	-webkit-transform: translate(26px,18px) rotate(0deg);
+	.transform(translate(26px,18px) rotate(0deg));
 }
 .mblProg4 {
-	-webkit-transform: translate(25px,22px) rotate(30deg);
+	.transform(translate(25px,22px) rotate(30deg));
 }
 .mblProg5 {
-	-webkit-transform: translate(22px,25px) rotate(60deg);
+	.transform(translate(22px,25px) rotate(60deg));
 }
 .mblProg6 {
-	-webkit-transform: translate(18px,26px) rotate(90.1deg);
+	.transform(translate(18px,26px) rotate(90.1deg));
 }
 .mblProg7 {
-	-webkit-transform: translate(14px,25px) rotate(120deg);
+	.transform(translate(14px,25px) rotate(120deg));
 }
 .mblProg8 {
-	-webkit-transform: translate(11px,22px) rotate(150deg);
+	.transform(translate(11px,22px) rotate(150deg));
 }
 .mblProg9 {
-	-webkit-transform: translate(10px,18px) rotate(180deg);
+	.transform(translate(10px,18px) rotate(180deg));
 }
 .mblProg10 {
-	-webkit-transform: translate(11px,14px) rotate(210deg);
+	.transform(translate(11px,14px) rotate(210deg));
 }
 .mblProg11 {
-	-webkit-transform: translate(14px,11px) rotate(240deg);
+	.transform(translate(14px,11px) rotate(240deg));
+}
+
+.mblProg0Color {
+	background-color: #c0c0c0;
+}
+.mblProg1Color {
+	background-color: #c0c0c0;
+}
+.mblProg2Color {
+	background-color: #c0c0c0;
+}
+.mblProg3Color {
+	background-color: #c0c0c0;
+}
+.mblProg4Color {
+	background-color: #c0c0c0;
+}
+.mblProg5Color {
+	background-color: #c0c0c0;
+}
+.mblProg6Color {
+	background-color: #b8b9b8;
+}
+.mblProg7Color {
+	background-color: #aeafae;
+}
+.mblProg8Color {
+	background-color: #a4a5a4;
+}
+.mblProg9Color {
+	background-color: #9a9a9a;
+}
+.mblProg10Color {
+	background-color: #8e8e8e;
+}
+.mblProg11Color {
+	background-color: #838383;
+}
+
+
+.mblProgWhite .mblProg0Color {
+	background-color: #adb9c9;
+}
+.mblProgWhite .mblProg1Color {
+	background-color: #adb9c9;
+}
+.mblProgWhite .mblProg2Color {
+	background-color: #adb9c9;
+}
+.mblProgWhite .mblProg3Color {
+	background-color: #adb9c9;
+}
+.mblProgWhite .mblProg4Color {
+	background-color: #adb9c9;
+}
+.mblProgWhite .mblProg5Color {
+	background-color: #adb9c9;
+}
+.mblProgWhite .mblProg6Color {
+	background-color: #acb9cb;
+}
+.mblProgWhite .mblProg7Color {
+	background-color: #b7c2d2;
+}
+.mblProgWhite .mblProg8Color {
+	background-color: #c4cdda;
+}
+.mblProgWhite .mblProg9Color {
+	background-color: #d1d8e2;
+}
+.mblProgWhite .mblProg10Color {
+	background-color: #dee3ea;
+}
+.mblProgWhite .mblProg11Color {
+	background-color: #eceff3;
 }
diff --git a/dojox/mobile/themes/common/RadioButton-compat.less b/dojox/mobile/themes/common/RadioButton-compat.less
new file mode 100644
index 0000000..8dd46f2
--- /dev/null
+++ b/dojox/mobile/themes/common/RadioButton-compat.less
@@ -0,0 +1,34 @@
+/* dojox.mobile.RadioButton */
+.mblRadioButton {
+	background-image: url(compat/button-bg.png);
+}
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
+	background-image: url(compat/button-chk-bg.png);
+	&.mblRadioButtonSelected {
+		background-image: url(compat/blue-button-sel-bg.png);
+	}
+}
+
+.dj_gecko {
+	.mblRadioButton {
+		background-image: @mbl-button-background-image-gecko;
+		-moz-appearance: none;
+	}
+	.mblRadioButtonChecked,
+	.mblRadioButton:checked {
+		background-image: @mbl-button-checked-background-image-gecko;
+		&::after {
+			-moz-transform: rotate(45deg);
+			-moz-transform-origin: 50% 50%;
+		}
+		&.mblRadioButtonSelected {
+			background-image: @mbl-blue-button-selected-background-image-gecko;
+		}	
+	}
+}
+.dj_ff3 {
+	.mblRadioButton {
+		-moz-border-radius: 0.5em;
+	}
+}
diff --git a/dojox/mobile/themes/common/RadioButton.less b/dojox/mobile/themes/common/RadioButton.less
index 0874ac8..7d390b5 100644
--- a/dojox/mobile/themes/common/RadioButton.less
+++ b/dojox/mobile/themes/common/RadioButton.less
@@ -1,21 +1,38 @@
 /* dojox.mobile.RadioButton */
 .mblRadioButton {
 	position: relative;
+	margin: -0.5em 3px 0.3em 4px;
+	width: 1em;
+	height: 1em;
+	border-style: outset;
+	border-width: 1px;
+	border-radius: 0.5em;
+	.mbl-button-background-image();
+	font: inherit;
 	cursor: pointer;
-	outline: none;
-	-webkit-appearance: none;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
+	.appearance(none);
+	.tap-highlight-color(rgba(255,255,255,0));
+	.transform(translateY(0.45em));
 	.mblRadioButton-styles;
 }
 .mblRadioButtonChecked,
 .mblRadioButton:checked {
-	.mblRadioButtonChecked-styles;
+	.mbl-button-checked-background-image();
 	&::after {
 		position: absolute;
+		content: "";
+		width: 0.3em;
+		height: 0.6em;
+		top: 0;
+		left: 0.25em;
+		border-width: 0.15em;
+		border-style: none solid solid none;
+		.transform(rotate(45deg));
+		.transform-origin(50% 50%);
 		.mblRadioButtonChecked-after-styles;
 	}
 	&.mblRadioButtonSelected {
-		.mblRadioButtonChecked-Selected-styles;
+		.mbl-blue-button-selected-background-image();
 		&::after {
 			.mblRadioButtonChecked-Selected-after-styles;
 		}
diff --git a/dojox/mobile/themes/common/RoundRect-compat.less b/dojox/mobile/themes/common/RoundRect-compat.less
new file mode 100644
index 0000000..e570ea4
--- /dev/null
+++ b/dojox/mobile/themes/common/RoundRect-compat.less
@@ -0,0 +1,80 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect.mblShadow {
+	box-shadow: @mbl-round-rect-box-shadow;
+}
+
+.dj_ff3 {
+	.mblRoundRect {
+		-moz-border-radius: @mbl-round-rect-border-radius;
+	}
+	.mblRoundRect.mblShadow {
+		-moz-box-shadow: @mbl-round-rect-box-shadow;
+	}
+}
+
+/* Round Corner */
+.dj_ie {
+	.mblRoundCorner {
+		background-color: @mbl-round-rect-background-color;
+		height: 1px;
+		font-size: 1px;
+		overflow: hidden;
+		border-style: solid;
+		border-color: @mbl-round-rect-border-color;
+		border-width: 0 1px;
+	}
+	.mblRoundRectContainer {
+		padding: 3px 8px;
+		background-color: @mbl-round-rect-background-color;
+		border-style: solid;
+		border-color: @mbl-round-rect-border-color;
+		border-width: 0 1px;
+	}
+	.mblRoundRectList .mblRoundRectContainer {
+		margin: 0;
+		padding: 0;
+	}
+	.mblRoundCorner0T {
+		height: 0;
+	}
+	.mblRoundCorner1T {
+		background-color: @mbl-round-rect-border-color;
+		margin: 0 5px;
+	}
+	.mblRoundCorner2T {
+		margin: 0 2px;
+		border-width: 0 3px;
+	}
+	.mblRoundCorner3T {
+		margin: 0 1px;
+		border-width: 0 2px;
+	}
+	.mblRoundCorner4T {
+		margin: 0 1px;
+	}
+	.mblRoundCorner5T {
+		margin: 0 1px;
+	}
+	
+	.mblRoundCorner0B {
+		height: 0;
+	}
+	.mblRoundCorner1B {
+		margin: 0 1px;
+	}
+	.mblRoundCorner2B {
+		margin: 0 1px;
+	}
+	.mblRoundCorner3B {
+		margin: 0 1px;
+		border-width: 0 2px;
+	}
+	.mblRoundCorner4B {
+		margin: 0 2px;
+		border-width: 0 3px;
+	}
+	.mblRoundCorner5B {
+		background-color: @mbl-round-rect-border-color;
+		margin: 0 5px;
+	}
+}
diff --git a/dojox/mobile/themes/common/RoundRect.less b/dojox/mobile/themes/common/RoundRect.less
index 0cd6361..7866e2d 100644
--- a/dojox/mobile/themes/common/RoundRect.less
+++ b/dojox/mobile/themes/common/RoundRect.less
@@ -1,7 +1,12 @@
 /* dojox.mobile.RoundRect */
 .mblRoundRect {
+	margin: 7px 9px 16px;
+	padding: 8px;
+	border: 1px solid @mbl-round-rect-border-color;
+	border-radius: @mbl-round-rect-border-radius;
+	background-color: @mbl-round-rect-background-color;
 	.mblRoundRect-styles;
 	&.mblShadow {
-		.mblRoundRectShadowBox-styles;
+		.box-shadow(@mbl-round-rect-box-shadow);
 	}
 }
diff --git a/dojox/mobile/themes/common/RoundRectCategory.less b/dojox/mobile/themes/common/RoundRectCategory.less
index cd4b311..5794ed5 100644
--- a/dojox/mobile/themes/common/RoundRectCategory.less
+++ b/dojox/mobile/themes/common/RoundRectCategory.less
@@ -1,5 +1,9 @@
 /* dojox.mobile.RoundRectCategory */
 .mblRoundRectCategory {
+	margin: 18px 0 0 20px;
+	padding: 0;
+	font-family: Helvetica;
+	font-size: 16px;
 	white-space: nowrap;
 	text-overflow: ellipsis;
 	overflow: hidden;
diff --git a/dojox/mobile/themes/common/RoundRectCategory_rtl.less b/dojox/mobile/themes/common/RoundRectCategory_rtl.less
new file mode 100644
index 0000000..2a7ffc3
--- /dev/null
+++ b/dojox/mobile/themes/common/RoundRectCategory_rtl.less
@@ -0,0 +1,4 @@
+/* dojox.mobile.RoundRectCategory Rtl */
+.mblRoundRectCategoryRtl {
+  margin: 18px 20px 0px 0px;
+}
diff --git a/dojox/mobile/themes/common/RoundRectList-compat.less b/dojox/mobile/themes/common/RoundRectList-compat.less
new file mode 100644
index 0000000..3155f7f
--- /dev/null
+++ b/dojox/mobile/themes/common/RoundRectList-compat.less
@@ -0,0 +1,84 @@
+/* dojox.mobile.RoundRectList */
+.dj_ff3 {
+	.mblRoundRectList {
+		-moz-border-radius: @mbl-round-rect-border-radius;
+	}
+	.mblRoundRectList .mblListItem:first-child {
+	  -moz-border-radius-topleft: @mbl-round-rect-border-radius;
+	  -moz-border-radius-topright: @mbl-round-rect-border-radius;
+	}
+	.mblRoundRectList .mblListItem:last-child {
+	  -moz-border-radius-bottomleft: @mbl-round-rect-border-radius;
+	  -moz-border-radius-bottomright: @mbl-round-rect-border-radius;
+	}
+}
+
+/* Round Corner */
+.dj_ie {
+	.mblRoundRectList {
+		position: relative;
+	}
+	.mblRoundCorner {
+		background-color: @mbl-round-rect-background-color;
+		height: 1px;
+		font-size: 1px;
+		overflow: hidden;
+		border-style: solid;
+		border-color: @mbl-round-rect-border-color;
+		border-width: 0 1px;
+	}
+	.mblRoundRectContainer {
+		padding: 3px 8px;
+		background-color: @mbl-round-rect-background-color;
+		border-style: solid;
+		border-color: @mbl-round-rect-border-color;
+		border-width: 0 1px;
+	}
+	.mblRoundRectList .mblRoundRectContainer {
+		margin: 0;
+		padding: 0;
+	}
+	.mblRoundCorner0T {
+		height: 0;
+	}
+	.mblRoundCorner1T {
+		background-color: @mbl-round-rect-border-color;
+		margin: 0 5px;
+	}
+	.mblRoundCorner2T {
+		margin: 0 2px;
+		border-width: 0 3px;
+	}
+	.mblRoundCorner3T {
+		margin: 0 1px;
+		border-width: 0 2px;
+	}
+	.mblRoundCorner4T {
+		margin: 0 1px;
+	}
+	.mblRoundCorner5T {
+		margin: 0 1px;
+	}
+	
+	.mblRoundCorner0B {
+		height: 0;
+	}
+	.mblRoundCorner1B {
+		margin: 0 1px;
+	}
+	.mblRoundCorner2B {
+		margin: 0 1px;
+	}
+	.mblRoundCorner3B {
+		margin: 0 1px;
+		border-width: 0 2px;
+	}
+	.mblRoundCorner4B {
+		margin: 0 2px;
+		border-width: 0 3px;
+	}
+	.mblRoundCorner5B {
+		background-color: @mbl-round-rect-border-color;
+		margin: 0 5px;
+	}
+}
diff --git a/dojox/mobile/themes/common/RoundRectList.less b/dojox/mobile/themes/common/RoundRectList.less
index b756d15..6c47d5e 100644
--- a/dojox/mobile/themes/common/RoundRectList.less
+++ b/dojox/mobile/themes/common/RoundRectList.less
@@ -1,17 +1,19 @@
 /* dojox.mobile.RoundRectList */
 .mblRoundRectList {
-	position: relative; /* IE needs this */
-	.mblRoundRectList-styles;
-	.mblListItem:first-child {
-		.mblRoundRectList-FirstListItem-styles;
+	margin: 7px 9px 16px;
+	padding: 0;
+	border: 1px solid @mbl-round-rect-border-color;
+	border-radius: @mbl-round-rect-border-radius;
+	background-color: @mbl-round-rect-background-color;
+	.mblListItem:first-child,
+	.mblEdgeToEdgeCategory:first-child {
+		border-top-left-radius: @mbl-round-rect-border-radius;
+		border-top-right-radius: @mbl-round-rect-border-radius;
 	}
-	.mblListItem:last-child {
-		.mblRoundRectList-LastListItem-styles;
-	}
-}
-.mblRoundRectCategory + .mblRoundRectList {
-	.mblRoundRectList-withCategory-styles;
-	.mblListItem:first-child {
-		.mblRoundRectList-withCategory-FirstListItem-styles;
+	.mblListItem:last-child,
+	.mblEdgeToEdgeCategory:last-child {
+		border-bottom-width: 0;
+		border-bottom-left-radius: @mbl-round-rect-border-radius;
+		border-bottom-right-radius: @mbl-round-rect-border-radius;
 	}
 }
diff --git a/dojox/mobile/themes/common/ScrollablePane.less b/dojox/mobile/themes/common/ScrollablePane.less
new file mode 100644
index 0000000..ed715a4
--- /dev/null
+++ b/dojox/mobile/themes/common/ScrollablePane.less
@@ -0,0 +1,12 @@
+/* dojox.mobile.mblScrollablePane */
+.mblScrollablePane {
+	position: relative;
+	overflow: hidden;
+}
+.mblScrollableViewContainer {
+	position: absolute;
+	top: 0px;
+}
+.mblScrollablePaneMask {
+	position: relative;
+}
diff --git a/dojox/mobile/themes/common/SearchBox-compat.less b/dojox/mobile/themes/common/SearchBox-compat.less
new file mode 100644
index 0000000..bbf9a19
--- /dev/null
+++ b/dojox/mobile/themes/common/SearchBox-compat.less
@@ -0,0 +1,31 @@
+/* dojox.mobile.SearchBox */
+ at import url("TextBox-compat.css");
+
+.mblSearchBox {
+  height: auto;
+}
+
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  -moz-box-sizing: border-box;
+}
+
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/common/SearchBox.less b/dojox/mobile/themes/common/SearchBox.less
new file mode 100644
index 0000000..caf7542
--- /dev/null
+++ b/dojox/mobile/themes/common/SearchBox.less
@@ -0,0 +1,110 @@
+/* dojox.mobile.SearchBox */
+ at import url("TextBox.css");
+
+.mblSearchBox.iphone4:focus::-webkit-search-cancel-button
+{ // cannot touch cancel button even if visible
+	background: none !important;
+	border-color: transparent !important;
+}
+
+.mblSearchBox::-webkit-search-cancel-button 
+{ 
+	.appearance(none);
+	background-color: @mbl-searchbox-cancel-button-bg-color;
+	background-repeat: no-repeat;
+	background-position: center center;
+	background-size: 15px 15px;
+	background-image:
+		-webkit-gradient(linear,
+			left top,
+			right bottom,
+			from(transparent),
+				color-stop(0.46,  transparent),
+				color-stop(0.46,  @mbl-searchbox-cancel-button-color),
+				color-stop(0.54,  @mbl-searchbox-cancel-button-color),
+				color-stop(0.54,  transparent),
+			to(transparent)
+		),
+		-webkit-gradient(linear,
+			right top,
+			left bottom,
+			from(transparent),
+				color-stop(0.46,  transparent),
+				color-stop(0.46,  @mbl-searchbox-cancel-button-color),
+				color-stop(0.54,  @mbl-searchbox-cancel-button-color),
+				color-stop(0.54,  transparent),
+			to(transparent)
+		)
+		!important;
+	border: 2px solid @mbl-searchbox-cancel-button-bg-color;
+	box-sizing: border-box;
+	height: 15px;
+	width: 15px;
+	display: inline-block;
+	vertical-align: middle;
+	margin-left: 0.5em;
+	.mblSearchBox-Cancel-Button-styles;
+} 
+
+.mblSearchBox::-webkit-search-results-decoration { 
+	.appearance(none); 
+	background-repeat: no-repeat;
+	background-size: 13px 13px, 9px 9px;
+	background-position: 0px 0px, 10px 10px;
+	background-image:
+		-webkit-gradient(radial,
+			50% 50%, 0,
+			50% 50%, 6,
+			from(transparent),
+				color-stop(0.65, transparent),
+			color-stop(0.8, @mbl-searchbox-results-decoration-color),
+				color-stop(0.95, transparent),
+			to(transparent)
+		),
+		-webkit-gradient(linear,
+			right top,
+			left bottom,
+			from(transparent),
+				color-stop(0.425,  transparent),
+			color-stop(0.5, @mbl-searchbox-results-decoration-color),
+				color-stop(0.575,  transparent),
+			to(transparent)
+		)
+		!important;
+	width: 15px;
+	height: 15px;
+	display: inline-block;
+	vertical-align: middle;
+}
+.mblSearchBox {
+	height: auto;
+}
+.dj_chrome .mblSearchBox {
+	border-radius: 0;
+}
+
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
+
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/common/SimpleDialog-compat.less b/dojox/mobile/themes/common/SimpleDialog-compat.less
new file mode 100644
index 0000000..20786be
--- /dev/null
+++ b/dojox/mobile/themes/common/SimpleDialog-compat.less
@@ -0,0 +1,16 @@
+/* dojox.mobile.SimpleDialog */
+.mblSimpleDialogDecoration {
+	.mblSimpleDialogDecoration-compat;
+}
+
+.dj_gecko {
+	.mblSimpleDialogDecoration {
+		.mblSimpleDialogDecoration-compat-gecko;
+	}
+}
+
+.dj_ff3 {
+	.mblSimpleDialogDecoration {
+		-moz-border-radius: @mbl-simple-dialog-border-radius;
+	}
+}
diff --git a/dojox/mobile/themes/common/SimpleDialog.less b/dojox/mobile/themes/common/SimpleDialog.less
new file mode 100644
index 0000000..9d92337
--- /dev/null
+++ b/dojox/mobile/themes/common/SimpleDialog.less
@@ -0,0 +1,37 @@
+/* dojox.mobile.SimpleDialog */
+.mblSimpleDialog {
+	position: absolute;
+	z-index: 100;
+	margin: 0;
+	text-align: center;
+	outline: none;
+	.mblSimpleDialog-styles;
+}
+.mblSimpleDialogDecoration {
+	border-radius: @mbl-simple-dialog-border-radius;
+	.mblSimpleDialogDecoration-styles;
+}
+.mblSimpleDialogContainer {
+	position: relative;
+	width: 100%;
+	height: 100%;
+}
+.mblSimpleDialogCover {
+	background-color: #000000;
+	opacity: 0.5;
+	position: absolute;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	z-index: 99;
+}
+.mblSimpleDialogCloseBtn {
+	position: absolute !important;
+}
+.mblSimpleDialogTitle {
+	.mblSimpleDialogTitle-styles;
+}
+.mblSimpleDialogText {
+	.mblSimpleDialogText-styles;
+}
diff --git a/dojox/mobile/themes/common/Slider-compat.less b/dojox/mobile/themes/common/Slider-compat.less
new file mode 100644
index 0000000..e863343
--- /dev/null
+++ b/dojox/mobile/themes/common/Slider-compat.less
@@ -0,0 +1,45 @@
+/* dojox.mobile.Slider */
+.mblSlider {
+	background-image: url(compat/slider-h-bg.png);
+	background-repeat: repeat-x;
+}
+.mblSliderProgressBar {
+	background-image: url(compat/slider-h-bar-bg.png);
+	background-repeat: repeat-x;
+}
+.mblSliderHandle {
+	background-image: url(compat/slider-handle-bg.png);
+}
+.mblSliderV {
+	background-color: @mbl-switch-bg-right-background-color;
+	background-image: none;
+	.mblSliderProgressBar {
+		background-color: @mbl-switch-bg-left-background-color;
+		background-image: none;
+	}
+}
+
+.dj_gecko {
+	.mblSlider {
+		background-image: @mbl-switch-bg-right-background-image-gecko;
+		-moz-user-select: none; // prevent selection
+		-moz-box-sizing: content-box; // make width and height consistent with a DIV
+	}
+	.mblSliderProgressBar {
+		background-image: @mbl-switch-bg-left-background-image-gecko;
+	}
+	.mblSliderHandle {
+		background-image: @mbl-switch-knob-background-image-gecko;
+	}
+}
+.dj_ff3 {
+	.mblSlider {
+		-moz-border-radius: @mbl-slider-bar-border-radius;
+	}
+	.mblSliderProgressBar {
+		-moz-border-radius: @mbl-slider-bar-border-radius;
+	}
+	.mblSliderHandle {
+		-moz-border-radius: @mbl-slider-knob-border-radius;
+	}
+}
diff --git a/dojox/mobile/themes/common/Slider.less b/dojox/mobile/themes/common/Slider.less
index ec57a17..fe8977f 100644
--- a/dojox/mobile/themes/common/Slider.less
+++ b/dojox/mobile/themes/common/Slider.less
@@ -1,8 +1,12 @@
 /* dojox.mobile.Slider */
 .mblSlider {
-	outline: none;
-	-webkit-user-select: none; /* prevent selection */
-	-webkit-box-sizing: content-box; /* make width and height consistent with a DIV */
+	margin: 15px; // 1/2 handle width for hanging off the ends of the bar
+	border-style: inset;
+	border-width: 1px;
+	border-radius: @mbl-slider-bar-border-radius;
+	.mbl-switch-bg-right-background-image();
+	.user-select(none); // prevent selection
+	.box-sizing(content-box); // make width and height consistent with a DIV
 	.mblSlider-styles;
 }
 .mblSliderH {
@@ -26,13 +30,21 @@
 	}
 }
 .mblSliderProgressBar {
-	.mblSliderProgressBar-styles;
+	border-radius: @mbl-slider-bar-border-radius;
+	.mbl-switch-bg-left-background-image();
 }
 .mblSliderHandle {
+	margin: -10px 0 0 -10px;
+	width: 18px;
+	height: 18px;
+	border-style: outset;
+	border-width: 1px;
+	border-radius: @mbl-slider-knob-border-radius;
+	.mbl-switch-knob-background-image();
 	.mblSliderHandle-styles;
 }
 .mblSliderTransition {
-	-webkit-transition-duration: 400ms;
+	.transition-duration(400ms);
 }
 .mblSliderTouchBox {
 	margin: 0;
@@ -43,5 +55,5 @@
 	width: 100%;
 	height: 100%;
 	background-color: transparent;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
+	.tap-highlight-color(rgba(255,255,255,0));
 }
diff --git a/dojox/mobile/themes/common/SpinWheel-compat.css b/dojox/mobile/themes/common/SpinWheel-compat.css
deleted file mode 100644
index 36865f2..0000000
--- a/dojox/mobile/themes/common/SpinWheel-compat.css
+++ /dev/null
@@ -1,36 +0,0 @@
-.mblSpinWheel {
-	background-color: #D6D7DC;
-	background-image: -moz-linear-gradient(top, #313137 0%, #73747D 5%, #92939B 7%, #ABABB5 9%, #C5C6CE 12%, #DFE0E4 16%, #F4F5F6 22%, #FBFCFC 35%, #FBFCFC 50%, #FBFCFC 61%, #B4C1C7 61%, #FBFCFC 65%, #F4F5F6 78%, #DFE0E4 84%, #C5C6CE 88%, #ABABB5 91%, #92939B 93%, #73747D 95%, #313137 100%);
-	-moz-border-radius: 3px;
-}
-.dj_ie .mblSpinWheel {
-	background-image: url(compat/spinwheel-bg.png);
-}
-
-.mblSpinWheelBar {
-	background-color: #C4CADC;
-	background-image: -moz-linear-gradient(top, #EDEEF2 0%, #C8CADD 25%, #BBBFD4 49%, #9FA8C6 51%, #A2A9C7 81%, #A6ABC9 82%, #A7ADCA 1%);
-	-khtml-opacity: 0.6;
-	-moz-opacity: 0.6;
-	opacity: 0.6;
-	filter: progid:DXImageTransform.Microsoft.alpha(opacity=60);
-}
-.dj_ie .mblSpinWheelBar {
-	background-image: url(compat/spinwheel-bar.png);
-}
-.dj_ie6 .mblSpinWheelBar, .dj_ie7 .mblSpinWheelBar {
-	z-index: -1;
-}
-*:first-child+html .mblSpinWheelSlotTouch { /* IE7 hack */
-	background: white;
-	filter: alpha(opacity=0);
-	height: 200px;
-}
-*html .mblSpinWheelSlotTouch { /* IE6 hack */
-	background: white;
-	filter: alpha(opacity=0);
-	height: 200px;
-}
-.mblSpinWheelSlotTouch, .mblSpinWheelSlotPanel {
-	left: 0px;
-}
diff --git a/dojox/mobile/themes/common/SpinWheel-compat.less b/dojox/mobile/themes/common/SpinWheel-compat.less
new file mode 100644
index 0000000..e8b480f
--- /dev/null
+++ b/dojox/mobile/themes/common/SpinWheel-compat.less
@@ -0,0 +1,48 @@
+.mblSpinWheel {
+	background-image: url(../common/compat/spinwheel-bg.png);
+}
+.mblSpinWheelBar {
+	background-image: url(../common/compat/spinwheel-bar.png);
+}
+.mblSpinWheelSlotTouch, .mblSpinWheelSlotPanel {
+	left: 0;
+}
+
+.dj_gecko {
+	.mblSpinWheel {
+		background-image: -moz-linear-gradient(top, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+	}
+	.mblSpinWheelBar {
+		background-image: -moz-linear-gradient(top, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 1%);
+	}
+}
+.dj_ff3 {
+	.mblSpinWheel {
+		-moz-border-radius: 3px;
+	}
+}
+
+.dj_ie {
+	.mblSpinWheelBar {
+		filter: ~"progid:DXImageTransform.Microsoft.alpha(opacity=60)";
+	}
+}
+.dj_ie6, .dj_ie7 {
+	.mblSpinWheelBar {
+		z-index: -1;
+	}
+}
+.dj_ie7 {
+	.mblSpinWheelSlotTouch {
+		background: white;
+		filter: ~"alpha(opacity=0)";
+		height: 200px;
+	}
+}
+.dj_ie6 {
+	.mblSpinWheelSlotTouch {
+		background: white;
+		filter: ~"alpha(opacity=0)";
+		height: 200px;
+	}
+}
diff --git a/dojox/mobile/themes/common/SpinWheel.css b/dojox/mobile/themes/common/SpinWheel.css
deleted file mode 100644
index e5eff56..0000000
--- a/dojox/mobile/themes/common/SpinWheel.css
+++ /dev/null
@@ -1,77 +0,0 @@
-.mblSpinWheel {
-	position: relative;
-	overflow: hidden;
-	background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #313137), color-stop(0.05, #73747D), color-stop(0.07, #92939B), color-stop(0.09, #ABABB5), color-stop(0.12, #C5C6CE), color-stop(0.16, #DFE0E4), color-stop(0.22, #F4F5F6), color-stop(0.35, #FBFCFC), color-stop(0.5, #FBFCFC), color-stop(0.61, #FBFCFC), color-stop(0.61, #B4C1C7), color-stop(0.65, #FBFCFC), color-stop(0.78, #F4F5F6), color-stop(0.84, #DFE0E4), color-stop(0.88, #C5C6CE), color-stop(0.91, #ABABB5), col [...]
-	height: 200px;
-	border-left: solid 3px #000000;
-	border-right: solid 3px #000000;
-	color: #000000;
-	-webkit-border-radius: 3px;
-}
-
-.mblSpinWheelBar {
-	position: absolute;
-	top: 79px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#EDEEF2), to(#A7ADCA), color-stop(0, #EDEEF2), color-stop(0.25, #C8CADD), color-stop(0.49, #BBBFD4), color-stop(0.51, #9FA8C6), color-stop(0.81, #A2A9C7), color-stop(0.82, #A6ABC9), color-stop(1, #A7ADCA));
-	border: solid 1px #7B8497;
-	height: 42px;
-	width: 100%;
-	clear: both;
-	-webkit-opacity: 0.6;
-}
-
-.mblSpinWheelDatePicker {
-	width: 312px;
-}
-
-.mblSpinWheelTimePicker {
-	width: 208px;
-}
-
-.mblSpinWheelSlot {
-	position: relative;
-	top: 0px;
-	float: left;
-	width: 100px;
-	height: 100%;
-	border-left: solid 2px #000000;
-	border-right: solid 2px #000000;
-}
-
-.mblSpinWheelSlotLabel {
-	padding: 0 8px;
-	height: 44px;
-	overflow: hidden;
-	font: bold 24px/44px Helvetica,sans-serif;
-}
-
-.mblSpinWheelSlotLabel img{
-	vertical-align: middle;
-	opacity: 0.7;
-}
-
-.mblSpinWheelSlotLabelGray {
-	color: #CCCCCC;
-}
-
-.mblSpinWheelSlotLabelBlue {
-	color: #0959D2;
-}
-
-.mblSpinWheelSlotContainer {
-	position: relative;
-}
-
-.mblSpinWheelSlotPanel {
-	position: absolute;
-	top: 0px;
-	width: 100%;
-}
-
-.mblSpinWheelSlotTouch {
-	position: absolute;
-	top: 0px;
-	width: 100%;
-	height: 100%;
-	z-index: 1;
-}
diff --git a/dojox/mobile/themes/common/SpinWheel.less b/dojox/mobile/themes/common/SpinWheel.less
new file mode 100644
index 0000000..7419dd9
--- /dev/null
+++ b/dojox/mobile/themes/common/SpinWheel.less
@@ -0,0 +1,92 @@
+/* dojox.mobile.SpinWheel */
+.mblSpinWheel {
+	position: relative;
+	overflow: hidden;
+  .background-spinwheel();
+	height: 200px;
+	border-left: solid 3px #000000;
+	border-right: solid 3px #000000;
+	color: #000000;
+	border-radius: 3px;
+}
+
+.mblSpinWheelBar {
+	position: absolute;
+	top: 79px;
+  .background-spinwheelbar();
+	border: solid 1px #7b8497;
+	height: 42px;
+	width: 100%;
+	clear: both;
+	opacity: 0.6;
+}
+
+.mblSpinWheelDatePicker {
+	width: 312px;
+}
+
+.mblSpinWheelTimePicker {
+	width: 98px;
+}
+
+.mblSpinWheelSlot {
+	position: relative;
+	top: 0px;
+	float: left;
+	width: 100px;
+	height: 100%;
+	border-left: solid 2px #000000;
+	border-right: solid 2px #000000;
+	.tap-highlight-color(rgba(255,255,255,0));
+}
+
+.mblSpinWheelSlotLabel {
+	padding: 0 8px;
+	height: 44px;
+	overflow: hidden;
+	font: bold 24px/44px Helvetica,sans-serif;
+}
+
+.mblSpinWheelSlotLabel img{
+	vertical-align: middle;
+	opacity: 0.7;
+}
+
+.mblSpinWheelSlotLabelGray {
+	color: #cccccc;
+}
+
+.mblSpinWheelSlotLabelBlue {
+	color: #0959d2;
+}
+
+.mblSpinWheelSlotContainer {
+	position: relative;
+}
+
+.mblSpinWheelSlotPanel {
+	position: absolute;
+	top: 0px;
+	width: 100%;
+}
+
+.mblSpinWheelSlotTouch {
+	position: absolute;
+	top: 0px;
+	width: 100%;
+	height: 100%;
+	z-index: 1;
+}
+
+.dj_ie {
+	.mblSpinWheelSlotTouch {
+		background-color: rgba(255, 255, 255, 0.01);
+	}
+}
+
+.dj_ie8 {
+	.mblSpinWheelSlotTouch {
+		background: white;
+		filter: ~"alpha(opacity=0)";
+	}
+}
\ No newline at end of file
diff --git a/dojox/mobile/themes/common/SpinWheel_rtl-compat.less b/dojox/mobile/themes/common/SpinWheel_rtl-compat.less
new file mode 100644
index 0000000..4791511
--- /dev/null
+++ b/dojox/mobile/themes/common/SpinWheel_rtl-compat.less
@@ -0,0 +1,4 @@
+.mblSpinWheelSlotRtl .mblSpinWheelSlotTouch, 
+.mblSpinWheelSlotRtl .mblSpinWheelSlotPanel {
+  right: 0;
+}
diff --git a/dojox/mobile/themes/common/SpinWheel_rtl.less b/dojox/mobile/themes/common/SpinWheel_rtl.less
new file mode 100644
index 0000000..c3efc85
--- /dev/null
+++ b/dojox/mobile/themes/common/SpinWheel_rtl.less
@@ -0,0 +1,5 @@
+/* dojox.mobile.SpinWheel Rtl */
+.mblSpinWheelSlotRtl,
+.mblSpinWheelRtl .mblSpinWheelSlot {
+  float: right;
+}
diff --git a/dojox/mobile/themes/common/Switch-compat.less b/dojox/mobile/themes/common/Switch-compat.less
new file mode 100644
index 0000000..311526f
--- /dev/null
+++ b/dojox/mobile/themes/common/Switch-compat.less
@@ -0,0 +1,139 @@
+/* dojox.mobile.Switch */
+/* Switch - common */
+.dj_gecko {
+	.mblSwitchBg {
+		-moz-box-sizing: border-box;
+	}
+	.mblSwitchKnob {
+		-moz-box-sizing: border-box;
+	}
+	.mblSwitch {
+		.mblSwitchBgLeft {
+			background-image: @mbl-switch-bg-left-background-image-gecko;
+		}
+		.mblSwitchBgRight {
+			background-image: @mbl-switch-bg-right-background-image-gecko;
+		}
+		.mblSwitchKnob {
+			background-image: @mbl-switch-knob-background-image-gecko;
+		}
+	}
+}
+
+.dj_ie {
+	.mblSwitchBg {
+		border: none;
+		background: none;
+	}
+	.mblSwitchBgLeft {
+		background-repeat: no-repeat;
+	}
+	.mblSwitchBgRight {
+		background-repeat: no-repeat;
+	}
+	.mblSwitchKnob {
+		background: none;
+		background-repeat: no-repeat;
+		border: none;
+	}
+}
+
+/* Square Shape */
+.mblSwSquareShape-styles () {
+	.mblSwitchBg {
+		-moz-border-radius: @mbl-switch-square-border-radius;
+	}
+	.mblSwitchBgLeft {
+		background-image: url(compat/switch-square-l.gif);
+	}
+	.mblSwitchBgRight {
+		background-image: url(compat/switch-square-r.gif);
+	}
+	.mblSwitchKnob {
+		-moz-border-radius: @mbl-switch-square-border-radius;
+		background-image: url(compat/switch-square-k.gif);
+	}
+}
+.mblSwSquareShape {
+	.mblSwSquareShape-styles;
+}
+
+/* Round Shape1 */
+.mblSwRoundShape1-styles () {
+	.mblSwitchBg {
+		-moz-border-radius: 14px;
+	}
+	.mblSwitchBgLeft {
+		background-image: url(compat/switch-round1-l.gif);
+	}
+	.mblSwitchBgRight {
+		background-image: url(compat/switch-round1-r.gif);
+	}
+	.mblSwitchKnob {
+		-moz-border-radius: 13px;
+		background-image: url(compat/switch-round1-k.gif);
+	}
+}
+.mblSwRoundShape1 {
+	.mblSwRoundShape1-styles;
+}
+
+/* Round Shape2 */
+.mblSwRoundShape2-styles () {
+	.mblSwitchBg {
+		-moz-border-radius: 14px;
+	}
+	.mblSwitchBgLeft {
+		background-image: url(compat/switch-round2-l.gif);
+	}
+	.mblSwitchBgRight {
+		background-image: url(compat/switch-round2-r.gif);
+	}
+	.mblSwitchKnob {
+		-moz-border-radius: 13px;
+		background-image: url(compat/switch-round2-k.gif);
+	}
+}
+.mblSwRoundShape2 {
+	.mblSwRoundShape2-styles;
+}
+
+/* Arc Shape1 */
+.mblSwArcShape1-styles () {
+	.mblSwitchBg {
+		-moz-border-radius: ~"5px/14px";
+	}
+	.mblSwitchBgLeft {
+		background-image: url(compat/switch-arc1-l.gif);
+	}
+	.mblSwitchBgRight {
+		background-image: url(compat/switch-arc1-r.gif);
+	}
+	.mblSwitchKnob {
+		-moz-border-radius: ~"5px/13px";
+		background-image: url(compat/switch-arc1-k.gif);
+	}
+}
+.mblSwArcShape1 {
+	.mblSwArcShape1-styles;
+}
+
+/* Switch - Arc Shape2 */
+.mblSwArcShape2-styles () {
+	.mblSwitchBg {
+		-moz-border-radius: ~"5px/14px";
+	}
+	.mblSwitchBgLeft {
+		background-image: url(compat/switch-arc2-l.gif);
+	}
+	.mblSwitchBgRight {
+		background-image: url(compat/switch-arc2-r.gif);
+	}
+	.mblSwitchKnob {
+		-moz-border-radius: ~"5px/13px";
+		background-image: url(compat/switch-arc2-k.gif);
+	}
+}
+.mblSwArcShape2 {
+	.mblSwArcShape2-styles;
+}
diff --git a/dojox/mobile/themes/common/Switch.css b/dojox/mobile/themes/common/Switch.css
deleted file mode 100644
index 3aed56d..0000000
--- a/dojox/mobile/themes/common/Switch.css
+++ /dev/null
@@ -1,224 +0,0 @@
-/* Switch - default */
-.mblSwitch {
-	margin: 0;
-	position: relative;
-	width: 94px;
-	height: 27px;
-	line-height: 29px;
-	overflow: hidden;
-	text-align: left;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
-}
-.mblItemSwitch {
-	position: absolute;
-	right: 12px;
-}
-.mblSwitchInner {
-	position: absolute;
-	top: 0px;
-	height: 27px;
-}
-.mblSwitchAnimation .mblSwitchInner {
-	-webkit-transition-property: left;
-	-webkit-transition-duration: .3s;
-}
-.mblSwitchOn .mblSwitchInner {
-	left: 0px;
-}
-.mblSwitchOff .mblSwitchInner {
-	left: -53px;
-}
-.mblSwitchBg {
-	position: absolute;
-	top: 0px;
-	height: 27px;
-	border-width: 1px;
-	border-style: inset;
-	border-color: #9CACC0;
-	font-family: Helvetica;
-	font-size: 16px;
-	font-weight: bold;
-	line-height: 29px;
-	-webkit-box-sizing: border-box;
-}
-.mblSwitchBgLeft {
-	left: 0px;
-	width: 94px;
-	color: white;
-	background-color: #3F84EB;
-}
-.mblSwitchBgRight {
-	left: 53px;
-	width: 94px;
-	color: #7F7F7F;
-}
-.mblSwitchKnob {
-	position: absolute;
-	top: 1px;
-	left: 53px;
-	width: 41px;
-	height: 26px;
-	font-size: 1px;
-	border-width: 1px;
-	border-style: solid;
-	border-color: #EFEFEF #A5A5A5 #969696 #325E9E;
-	-webkit-box-sizing: border-box;
-}
-.mblSwitchText {
-	position: relative;
-	top: 0px;
-	width: 53px;
-	height: 27px;
-	padding: 0px;
-	line-height: 28px;
-	text-align: center;
-}
-.mblSwitchTextLeft {
-	left: 0px;
-}
-.mblSwitchTextRight {
-	left: 40px;
-}
-
-/* Round Shape1 */
-.mblSwRoundShape1 {
-	height: 28px;
-	-webkit-mask-image: -webkit-canvas(mblSwRoundShape1Mask);
-}
-.mblSwRoundShape1.mblItemSwitch {
-	top: 8px;
-}
-.mblSwRoundShape1 .mblSwitchInner {
-	height: 28px;
-}
-.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
-	left: -67px;
-}
-.mblSwRoundShape1 .mblSwitchBg {
-	height: 28px;
-	-webkit-border-radius: 14px;
-}
-.mblSwRoundShape1 .mblSwitchBgLeft {
-}
-.mblSwRoundShape1 .mblSwitchBgRight {
-	left: 67px;
-}
-.mblSwRoundShape1 .mblSwitchKnob {
-	left: 67px;
-	width: 26px;
-	height: 26px;
-	-webkit-border-radius: 13px;
-}
-.mblSwRoundShape1 .mblSwitchText {
-	width: 67px;
-	height: 26px;
-}
-.mblSwRoundShape1 .mblSwitchTextRight {
-	left: 26px;
-}
-
-/* Round Shape2 */
-.mblSwRoundShape2 {
-	height: 28px;
-	-webkit-mask-image: -webkit-canvas(mblSwRoundShape2Mask);
-}
-.mblSwRoundShape2.mblItemSwitch {
-	top: 8px;
-}
-.mblSwRoundShape2 .mblSwitchInner {
-	height: 28px;
-}
-.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
-	left: -51px;
-}
-.mblSwRoundShape2 .mblSwitchBg {
-	height: 28px;
-	-webkit-border-radius: 14px;
-}
-.mblSwRoundShape2 .mblSwitchBgRight {
-	left: 51px;
-}
-.mblSwRoundShape2 .mblSwitchKnob {
-	left: 51px;
-	width: 42px;
-	height: 26px;
-	-webkit-border-radius: 13px;
-}
-.mblSwRoundShape2 .mblSwitchText {
-	width: 51px;
-	height: 28px;
-}
-.mblSwRoundShape2 .mblSwitchTextRight {
-	left: 42px;
-}
-
-/* Arc Shape1 */
-.mblSwArcShape1 {
-	height: 28px;
-	-webkit-border-radius: 6px/14px;
-}
-.mblSwArcShape1.mblItemSwitch {
-	top: 8px;
-}
-.mblSwArcShape1 .mblSwitchInner {
-	height: 28px;
-}
-.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
-	left: -67px;
-}
-.mblSwArcShape1 .mblSwitchBg {
-	height: 28px;
-	-webkit-border-radius: 6px/14px;
-}
-.mblSwArcShape1 .mblSwitchBgRight {
-	left: 67px;
-}
-.mblSwArcShape1 .mblSwitchKnob {
-	left: 67px;
-	width: 26px;
-	height: 26px;
-	-webkit-border-radius: 5px/13px;
-}
-.mblSwArcShape1 .mblSwitchText {
-	width: 67px;
-	height: 26px;
-}
-.mblSwArcShape1 .mblSwitchTextRight {
-	left: 26px;
-}
-
-/* Arc Shape2 */
-.mblSwArcShape2 {
-	height: 28px;
-	-webkit-border-radius: 6px/14px;
-}
-.mblSwArcShape2.mblItemSwitch {
-	top: 8px;
-}
-.mblSwArcShape2 .mblSwitchInner {
-	height: 28px;
-}
-.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
-	left: -51px;
-}
-.mblSwArcShape2 .mblSwitchBg {
-	height: 28px;
-	-webkit-border-radius: 6px/14px;
-}
-.mblSwArcShape2 .mblSwitchBgRight {
-	left: 51px;
-}
-.mblSwArcShape2 .mblSwitchKnob {
-	left: 51px;
-	width: 42px;
-	height: 26px;
-	-webkit-border-radius: 5px/13px;
-}
-.mblSwArcShape2 .mblSwitchText {
-	width: 51px;
-	height: 26px;
-}
-.mblSwArcShape2 .mblSwitchTextRight {
-	left: 42px;
-}
-
diff --git a/dojox/mobile/themes/common/Switch.less b/dojox/mobile/themes/common/Switch.less
index e9868bc..7732022 100644
--- a/dojox/mobile/themes/common/Switch.less
+++ b/dojox/mobile/themes/common/Switch.less
@@ -1,16 +1,219 @@
 /* dojox.mobile.Switch */
-.mblItemSwitch {
-	.mblItemSwitch-styles;
+/* Switch - common */
+ at mbl-switch-height: 27px;
+//
+.mblSwitch {
+	margin: 0;
+	position: relative;
+	display: inline-block;
+	height: @mbl-switch-height;
+	line-height: @mbl-switch-height + 2;
+	overflow: hidden;
+	text-align: left;
+	.tap-highlight-color(rgba(255,255,255,0));
+}
+.mblListItem .mblSwitch {
+	position: absolute;
+	right: 12px;
+	top: (@mbl-list-item-height - @mbl-switch-height) / 2;
+}
+.mblSwitchInner {
+	position: absolute;
+	top: 0;
+	height: @mbl-switch-height;
+}
+.mblSwitchAnimation .mblSwitchInner {
+	.transition-property(left);
+	.transition-duration(.1s);
+}
+.mblSwitchOn .mblSwitchInner {
+	left: 0;
 }
 .mblSwitchBg {
+	position: absolute;
+	top: 0;
+	width: 94px;
+	height: @mbl-switch-height;
+	font-family: Helvetica;
+	font-size: 16px;
+	font-weight: bold;
+	line-height: @mbl-switch-height + 2;
+	.box-sizing(border-box);
 	.mblSwitchBg-styles;
 }
 .mblSwitchBgLeft {
-	.mblSwitchBgLeft-styles;
+	left: 0;
+	color: white;
+	background-color: #3f84eb;
+	.mbl-switch-bg-left-background-image();
 }
 .mblSwitchBgRight {
-	.mblSwitchBgRight-styles;
+	color: #7f7f7f;
+	.mbl-switch-bg-right-background-image();
 }
 .mblSwitchKnob {
+	position: absolute;
+	top: 0;
+	height: @mbl-switch-height;
+	.mbl-switch-knob-background-image();
+	font-size: 1px;
+	.box-sizing(border-box);
 	.mblSwitchKnob-styles;
 }
+.mblSwitchText {
+	position: relative;
+	top: 0;
+	width: 53px;
+	height: @mbl-switch-height;
+	padding: 0;
+	line-height: 28px;
+	text-align: center;
+}
+.mblSwitchTextLeft {
+	left: 0;
+}
+.mblSwitchTextRight {
+	left: 40px;
+}
+
+/* Square Shape */
+.mblSwSquareShape-styles () {
+	width: 94px;
+	&.mblSwitchOff .mblSwitchInner {
+		left: -53px;
+	}
+	.mblSwitchBg {
+		border-radius: @mbl-switch-square-border-radius;
+	}
+	.mblSwitchBgRight {
+		left: 53px;
+	}
+	.mblSwitchKnob {
+		left: 53px;
+		width: 41px;
+		border-radius: @mbl-switch-square-border-radius;
+	}
+	.mblSwitchText {
+		width: 53px;
+	}
+	.mblSwitchTextRight {
+		left: 40px;
+	}
+}
+.mblSwSquareShape {
+	.mblSwSquareShape-styles;
+}
+
+/* Round Shape1 */
+.mblSwRoundShape1-styles () {
+	width: 77px;
+	&.mblSwitchOff .mblSwitchInner {
+		left: -50px;
+	}
+	.mblSwitchBg {
+		width: 77px;
+		border-radius: 14px;
+	}
+	.mblSwitchBgRight {
+		left: 50px;
+	}
+	.mblSwitchKnob {
+		left: 50px;
+		width: 27px;
+		border-radius: 13px;
+	}
+	.mblSwitchText {
+		width: 50px;
+	}
+	.mblSwitchTextRight {
+		left: 26px;
+	}
+}
+.mblSwRoundShape1 {
+	.mblSwRoundShape1-styles;
+}
+
+/* Round Shape2 */
+.mblSwRoundShape2-styles () {
+	width: 94px;
+	&.mblSwitchOff .mblSwitchInner {
+		left: -51px;
+	}
+	.mblSwitchBg {
+		border-radius: 14px;
+	}
+	.mblSwitchBgRight {
+		left: 51px;
+	}
+	.mblSwitchKnob {
+		left: 51px;
+		width: 43px;
+		border-radius: 13px;
+	}
+	.mblSwitchText {
+		width: 51px;
+	}
+	.mblSwitchTextRight {
+		left: 42px;
+	}
+}
+.mblSwRoundShape2 {
+	.mblSwRoundShape2-styles;
+}
+
+/* Arc Shape1 */
+.mblSwArcShape1-styles () {
+	width: 77px;
+	&.mblSwitchOff .mblSwitchInner {
+		left: -50px;
+	}
+	.mblSwitchBg {
+		width: 77px;
+		border-radius: ~"5px/14px";
+	}
+	.mblSwitchBgRight {
+		left: 50px;
+	}
+	.mblSwitchKnob {
+		left: 50px;
+		width: 27px;
+		border-radius: ~"5px/13px";
+	}
+	.mblSwitchText {
+		width: 50px;
+	}
+	.mblSwitchTextRight {
+		left: 26px;
+	}
+}
+.mblSwArcShape1 {
+	.mblSwArcShape1-styles;
+}
+
+/* Arc Shape2 */
+.mblSwArcShape2-styles () {
+	width: 94px;
+	&.mblSwitchOff .mblSwitchInner {
+		left: -51px;
+	}
+	.mblSwitchBg {
+		border-radius: ~"5px/14px";
+	}
+	.mblSwitchBgRight {
+		left: 51px;
+	}
+	.mblSwitchKnob {
+		left: 51px;
+		width: 43px;
+		border-radius: ~"5px/13px";
+	}
+	.mblSwitchText {
+		width: 51px;
+	}
+	.mblSwitchTextRight {
+		left: 42px;
+	}
+}
+.mblSwArcShape2 {
+	.mblSwArcShape2-styles;
+}
diff --git a/dojox/mobile/themes/common/Switch_rtl-compat.less b/dojox/mobile/themes/common/Switch_rtl-compat.less
new file mode 100644
index 0000000..df6b532
--- /dev/null
+++ b/dojox/mobile/themes/common/Switch_rtl-compat.less
@@ -0,0 +1,43 @@
+/* dojox.mobile.Switch Rtl */
+/* Square Shape Rtl */
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
+/* Round Shape1 Rtl */
+.mblSwRoundShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round1-l.gif);
+}
+/* Round Shape2 Rtl */
+.mblSwRoundShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round2-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round2-l.gif);
+}
+/* Arc Shape1 Rtl */
+.mblSwArcShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc1-r.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc1-l.gif);
+}
+/* Switch - Arc Shape2 Rtl */
+.mblSwArcShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc2-r.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc2-l.gif);
+}
+/* Default Shape Rtl */
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  background-image: @mbl-bg-image-r-rtl;
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  background-image: @mbl-bg-image-l-rtl;
+}
diff --git a/dojox/mobile/themes/common/Switch_rtl.less b/dojox/mobile/themes/common/Switch_rtl.less
new file mode 100644
index 0000000..9bfbe2c
--- /dev/null
+++ b/dojox/mobile/themes/common/Switch_rtl.less
@@ -0,0 +1,117 @@
+/* dojox.mobile.Switch Rtl */
+/* Switch - common Rtl */
+.mblSwitchRtl {
+  text-align: right;
+}
+.mblListItemRtl .mblSwitch {
+  left: 12px;
+  right: auto;
+}
+.mblSwitchRtl.mblSwitchOn .mblSwitchInner {
+  left: -50px;
+}
+.mblSwitchBgLeftRtl {
+  left: 51px;
+}
+.mblSwitchTextLeftRtl {
+  left: 0px;
+}
+.mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Square Shape Rtl*/
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Round Shape1 Rtl */
+.mblSwitchRtl.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Round Shape2 Rtl */
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Arc Shape1 Rtl */
+.mblSwitchRtl.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Arc Shape2 Rtl */
+.mblSwitchRtl.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Default Shape Rtl */
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOn .mblSwitchInner {
+  left: @mbl-switchOn-left-rtl;
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  left: @mbl-switchBg-left-rtl;
+}
+.mblSwitchRtl.mblSwDefaultShape .mblSwitchKnob {
+  left: @mbl-switch-knob-rtl;
+}
+.mblSwDefaultShape .mblSwitchTextRightRtl {
+  left: @mbl-switch-text-right-rtl;
+}
diff --git a/dojox/mobile/themes/common/TabBar-compat.less b/dojox/mobile/themes/common/TabBar-compat.less
new file mode 100644
index 0000000..54221b1
--- /dev/null
+++ b/dojox/mobile/themes/common/TabBar-compat.less
@@ -0,0 +1,81 @@
+/* dojox.mobile.TabBar */
+.mblTabBar {
+}
+.dj_ie6 .mblTabBar .mblTabBarButton {
+	display: inline; // IE bug
+}
+
+/* barType="tabBar" */
+.mblTabBarTabBar {
+	background-image: none;
+	.mblTabBarTabBar-compat;
+}
+.dj_ff3 {
+	.mblTabBarTabBar {
+		.mblTabBarButtonSelected {
+			-moz-border-radius: 3px;
+		}
+	}
+}
+
+/* barType="segmentedControl" | "standardTab" */
+.mblTabBarSegmentedControl, .mblTabBarStandardTab {
+	background-image: url(compat/heading-bg.png);
+	.mblTabBarButton {
+		background-image: url(compat/tab-seg-button-bg.png);
+	}
+	.mblTabBarButtonSelected {
+		background-image: url(compat/tab-seg-sel-button-bg.png);
+	}
+}
+.dj_gecko .mblTabBarSegmentedControl {
+	.mblTabBarButton {
+		.mblTabBarSegmentedControlButton-compat-gecko;
+	}
+}
+.dj_ff3 {
+	.mblTabBarSegmentedControl {
+		.mblTabBarButton {
+			&:first-child {
+				-moz-border-radius-topleft: @mbl-tab-bar-segmented-control-border-radius;
+				-moz-border-radius-bottomleft: @mbl-tab-bar-segmented-control-border-radius;
+			}
+			&:last-child {
+				-moz-border-radius-topright: @mbl-tab-bar-segmented-control-border-radius;
+				-moz-border-radius-bottomright: @mbl-tab-bar-segmented-control-border-radius;
+			}
+		}
+	}
+	.mblTabBarStandardTab {
+		.mblTabBarButton {
+			-moz-border-radius-topleft: 4px;
+			-moz-border-radius-topright: 4px;
+		}
+	}
+}
+
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+	background-image: url(compat/tab-slim-bar-bg.png);
+}
+.dj_gecko .mblTabBarSlimTab {
+	background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+	.mblTabBarButton {
+		background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+	}
+	.mblTabBarButtonSelected {
+		background-image: -moz-linear-gradient(top, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
+	}
+}
+
+/* barType="flatTab" */
+.mblTabBarFlatTab {
+}
+
+/* barType="tallTab" */
+.mblTabBarTallTab {
+	background-image: url(compat/tab-tall-bar-bg.png);
+	.mblTabBarButtonSelected {
+		background-color: #8c8e8c;
+	}
+}
diff --git a/dojox/mobile/themes/common/TabBar.less b/dojox/mobile/themes/common/TabBar.less
index a63497a..b840029 100644
--- a/dojox/mobile/themes/common/TabBar.less
+++ b/dojox/mobile/themes/common/TabBar.less
@@ -1,147 +1,273 @@
 /* dojox.mobile.TabBar */
 .mblTabBar {
 	position: relative;
+	margin: 0px;
 	overflow: hidden;
 	white-space: nowrap;
+	text-overflow: ellipsis;
+	padding: 0px 6px;
+	height: 42px;
+	text-align: center;
+	color: white;
+	border-top: 1px solid @heading-border-top-color;
+	border-bottom: 1px solid @heading-border-bottom-color;
 	.mblTabBar-styles;
 }
-.mblTabBarNoIcons {
-	height: 34px;
-}
-.mblTabBarNoText {
-	height: 34px;
-}
 
 /* dojox.mobile.TabBarButton */
+.mblTabBarFill .mblTabBarButton {
+	box-sizing: border-box;
+	-moz-box-sizing: border-box;
+	-webkit-box-sizing: border-box;
+}
+
 .mblTabBarButton {
+	overflow: hidden;
 	cursor: pointer;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
-}
-.mblTabBar .mblTabBarButton {
+	.tap-highlight-color(rgba(255,255,255,0));
 	position: relative;
 	list-style-type: none;
 	float: left;
-	.mblTabBar-TabBarButton-styles;
-	&.mblTabButtonSelected {
-		.mblTabBar-TabBarButton-Selected-styles;
-	}
 }
-.mblTabBarButtonAnchor {
-	display: block;
-	text-decoration: none;
+.mblTabBarButtonIconArea {
+	margin: 0 auto;
+	width: 29px;
 }
-.mblTabBarButtonDiv {
-	position: relative;
-	margin-left: auto;
-	margin-right: auto;
-	.mblTabBarButtonDiv-styles;
+.mblTabBarButtonIconParent1 {
+	display: block;
 }
-.mblTabBarButtonIcon {
-	position: absolute;
-	.mblTabBarButtonIcon-styles;
+.mblTabBarButtonIconParent2 {
+	display: none;
 }
-.mblTabBarButtonSpriteIcon {
-	position: absolute;
+.mblTabBarButtonSelected .mblTabBarButtonIconParent1 {
+	display: none;
 }
-.mblTabBarButtonTextBox {
-	.mblTabBarButtonTextBox-styles;
+.mblTabBarButtonSelected .mblTabBarButtonIconParent2 {
+	display: block;
 }
-.mblTabBarNoIcons {
-	.mblTabBarButtonDiv {
-		display: none;
+
+/* barType="tabBar" */
+.mblTabBarTabBar {
+	height: 48px;
+	border-top: 1px solid #000000;
+	.mblTabBarTabBar-styles;
+
+	.mblTabBarButton {
+		.mblTabBarTabBarButton-styles;
+	}
+	.mblTabBarButtonIconArea {
+		padding-top: 4px;
+		.mblTabBarTabBarButtonIconArea-styles;
+	}
+	.mblTabBarButtonLabel {
+		font-family: "Helvetica Neue", Helvetica;
+		font-size: 11px;
+		.mblTabBarTabBarButtonLabel-styles;
 	}
-	.mblTabBarButtonTextBox {
-		.mblTabBarNoIcons-TabBarButtonTextBox-styles;
+	.mblTabBarButtonSelected {
+		border-radius: 3px;
+		.mblTabBarTabBarButtonSelected-styles;
+	}
+	.mblTabBarButtonSelected .mblTabBarButtonLabel {
+		.mblTabBarTabBarButtonLabelSelected-styles;
 	}
 }
-.mblTabBarTop {
-	.mblTabButton {
-		.mblTabBarButtonDiv {
-			.mblTabBarTop-TabButton-TabBarButtonDiv-styles;
+/* barType="segmentedControl" */
+.mblTabBarSegmentedControl {
+	.heading-background-image();
+	.mblTabBarSegmentedControl-styles;
+
+	&.mblTabBarNoText {
+		.mblTabBarButton {
+			width: auto;
+			padding: 0 3px;
+		}
+		.mblTabBarButtonIconArea {
+			position: relative;
 		}
 	}
-}
-.mblTabBarHead {
-	.mblTabButton {
-		.mblTabBarButtonDiv {
-			.mblTabBarHead-TabButton-TabBarButtonDiv-styles;
+	.mblTabBarButton {
+		margin: 6px 0;
+		width: 100px;
+		height: 29px;
+		border-width: 1px 1px 1px 0px;
+		font-family: Helvetica;
+		font-size: 13px;
+		font-weight: bold;
+		text-align: center;
+		line-height: 29px;
+		.mblTabBarSegmentedControlButton-styles;
+		&:first-child {
+			border-left-width: 1px;
+			border-top-left-radius: @mbl-tab-bar-segmented-control-border-radius;
+			border-bottom-left-radius: @mbl-tab-bar-segmented-control-border-radius;
+		}
+		&:last-child {
+			border-top-right-radius: @mbl-tab-bar-segmented-control-border-radius;
+			border-bottom-right-radius: @mbl-tab-bar-segmented-control-border-radius;
 		}
 	}
+	.mblTabBarButtonIconArea {
+		position: absolute;
+		top: 0px;
+		left: 0px;
+	}
+	.mblTabBarButtonSelected {
+		.mblTabBarSegmentedControlButtonSelected-styles;
+	}
 }
-.mblTabButton {
-	position: relative;
+.mblHeading .mblTabBarSegmentedControl {
+	display: inline;
 	float: left;
-	list-style-type: none;
-	cursor: pointer;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
-	.mblTabButton-styles;
-	.mblTabBarButtonAnchor, .mblTabBarButtonDiv {
-		.mblTabButton-TabBarButtonAnchor-styles;
+	height: auto;
+	border: none;
+}
+
+/* barType="standardTab" */
+.mblTabBarStandardTab {
+	.heading-background-image();
+	.mblTabBarStandardTab-styles;
+
+	.mblTabBarButton {
+		margin-top: 9px;
+		padding: 9px;
+		border: 1px solid #62676d;
+		border-top-left-radius: 4px;
+		border-top-right-radius: 4px;
+		font-family: Helvetica;
+		font-size: 14px;
+		font-weight: bold;
+		.mblTabBarStandardTabButton-styles;
 	}
-	&:first-child {
-		.mblTabButton-FirstTabButtom-styles;
+	.mblTabBarButtonIconArea {
+		position: absolute;
+		top: 3px;
+		left: 0px;
+		.mblTabBarStandardTabButtonIconArea-styles;
 	}
-	&:last-child {
-		.mblTabButton-LastTabButton-styles;
+	.mblTabBarButtonLabel {
+		.mblTabBarStandardTabButtonLabel-styles;
 	}
-	img {
-		.mblTabButton-img-styles;
+	.mblTabBarButtonSelected {
+		.mblTabBarStandardTabButtonSelected-styles;
 	}
-}
-.mblTabButtonSelected {
-	.mblTabBarButtonTextBox {
-		.mblTabBarButtonTextBoxSelected-styles;
+	.mblTabBarButtonSelected .mblTabBarButtonLabel {
+		.mblTabBarStandardTabButtonLabelSelected-styles;
 	}
-	&.mblTabButton {
-		.mblTabButtonSelected-styles;
+	.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+		margin-left: 20px;
 	}
 }
-.mblTabButtonHighlighted {
-	&.mblTabButton {
-		.mblTabButtonHighlighted-styles;
+
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+	height: 30px;
+	padding: 0px;
+	border: 1px solid @heading-border-bottom-color;
+	background-color: #000000;
+	.background-image-linear-gradient-top-bottom-2-stops(#2d2d2d, #000000, 0.5, #141414, 0.5, #000000);
+
+	.mblTabBarButton {
+		padding: 7px;
+		border-right: 1px solid #4e4e4e;
+		.background-image-linear-gradient-top-bottom-2-stops(#2d2d2d, #000000, 0.5, #141414, 0.5, #000000);
+		font-family: Helvetica;
+		font-size: 14px;
+		font-weight: bold;
+		color: white;
+		text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
+		text-align: center;
+		&:first-child {
+			border-left: 1px solid #4e4e4e;
+		}
+		&:last-child {
+		}
+	}
+	.mblTabBarButtonIconArea {
+		position: absolute;
+		top: 0px;
+		left: 0px;
+	}
+	.mblTabBarButtonSelected {
+		background-color: #404040;
+		.background-image-linear-gradient-top-bottom-2-stops(#313031, #959595, 0.5, #5a555a, 0.5, #616161);
+	}
+	.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+		margin-left: 20px;
 	}
-}
-.mblTabButtonImgDiv {
-	.mblTabButtonImgDiv-styles;
 }
 
-.mblTabPanelHeader {
-	position: relative;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-	.mblTabPanelHeader-styles;
-	.mblTabButton {
-		.mblTabPanelHeader-TabButton-styles;
-		&.mblTabButtonSelected {
-			.mblTabPanelHeader-TabButtonSelected-styles;
-		}	
-	}
-	.mblTabButtonDomButton {
-		.mblTabPanelHeader-TabButtonDomButton-styles;
+/* barType="flatTab" */
+.mblTabBarFlatTab {
+	height: 30px;
+	padding: 0px;
+	border-style: none;
+	background-color: transparent;
+	background-image: none;
+
+	.mblTabBarButton {
+		padding: 7px;
+		background-image: none;
+		font-family: Helvetica;
+		font-size: 14px;
+		font-weight: bold;
+		text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
+		text-align: center;
 	}
-	.mblTabButtonDomButtonClass {
-		.mblTabPanelHeader-TabButtonDomButtonClass-styles;
+	.mblTabBarButtonIconArea {
+		position: absolute;
+		top: 0px;
+		left: 0px;
 	}
-	.mblDomButton {
-		.mblTabPanelHeader-DomButton-styles;
+	.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+		margin-left: 20px;
 	}
 }
 
-.mblHeading {
-	.mblTabPanelHeader {
-		.mblTabPanelHeader-inHeading-styles;
-		.mblTabButton {
-			.mblTabPanelHeader-TabButton-inHeading-styles;
-			&:first-child {
-				.mblTabPanelHeader-TabButton-FirstTabButtom-inHeading-styles;
-			}
-			&:last-child {
-				.mblTabPanelHeader-TabButton-LastTabButtom-inHeading-styles;
-			}
+/* barType="tallTab" */
+.mblTabBarTallTab {
+	height: 64px;
+	border-top: 1px solid #cdd5df;
+	border-bottom: 2px solid #949694;
+	.mblTabBarTallTab-styles;
+
+	.mblTabBarButton {
+		margin-top: 3px;
+		margin-right: 2px;
+		width: 78px;
+		height: 61px;
+		border-width: 0px 1px 0px 1px;
+		border-style: solid;
+		border-color: black #182018 black #393c39;
+		.background-image-linear-gradient-top-bottom-1-stop(#181818, #100c10, 0.1, #313031);
+		font-family: Helvetica;
+		font-size: 13px;
+		color: white;
+		text-align: center;
+		.mblTabBarTallTabButton-styles;
+		&:first-child {
+			.mblTabBarTallTabButton-FirstChild-styles;
 		}
-		.mblTabButtonSelected {
-			.mblTabPanelHeader-TabButtonSelected-inHeading-styles;
+		&:last-child {
+			.mblTabBarTallTabButton-LastChild-styles;
 		}
 	}
+	.mblTabBarButtonIconArea {
+		margin-top: 8px;
+		.mblTabBarTallTabButtonIconArea-styles;
+	}
+	.mblTabBarButtonLabel {
+		font-family: "Helvetica Neue", Helvetica;
+		font-size: 11px;
+		.mblTabBarTallTabButtonLabel-styles;
+	}
+	.mblTabBarButtonSelected {
+		.background-image-linear-gradient-top-bottom(#a59ea5, #848284);
+		.mblTabBarTallTabButtonSelected-styles;
+	}
+	.mblTabBarButtonSelected .mblTabBarButtonLabel {
+		.mblTabBarTallTabButtonLabelSelected-styles;
+	}
+	.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+	}
 }
diff --git a/dojox/mobile/themes/common/TabBar_rtl-compat.less b/dojox/mobile/themes/common/TabBar_rtl-compat.less
new file mode 100644
index 0000000..edb1b97
--- /dev/null
+++ b/dojox/mobile/themes/common/TabBar_rtl-compat.less
@@ -0,0 +1,20 @@
+/* barType="segmentedControl" | "standardTab" Rtl */
+
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  -moz-border-radius-topright: @mbl-moz-border-radius-rtl;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-bottomright: @mbl-moz-border-radius-rtl;
+  -moz-border-radius-bottomleft: 0px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  -moz-border-radius-topleft: @mbl-moz-border-radius-rtl;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomleft: @mbl-moz-border-radius-rtl;
+  -moz-border-radius-bottomright: 0px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButtonRtl {
+  -moz-border-radius-topright: 4px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 0px;
+}
diff --git a/dojox/mobile/themes/common/TabBar_rtl.less b/dojox/mobile/themes/common/TabBar_rtl.less
new file mode 100644
index 0000000..9063cb6
--- /dev/null
+++ b/dojox/mobile/themes/common/TabBar_rtl.less
@@ -0,0 +1,89 @@
+/* dojox.mobile.TabBarButton Rtl */
+.mblTabBarButtonRtl {
+  float: right;
+}
+.mblTabBarButtonIconAreaRtl {
+  margin: 0 auto;
+  width: 29px;
+}
+/* barType="tabBar" Rtl */
+.mblTabBarTabBar .mblTabBarButtonIconAreaRtl {
+  padding-top: 4px;
+}
+/* barType="segmentedControl" Rtl */
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconAreaRtl {
+  position: relative;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl {
+  border-width: @mbl-border-width-rtl;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  border-right-width: 1px !important;
+  border-left-width: 0px;
+  border-top-right-radius: @mbl-tb-border-radius-rtl;
+  border-top-left-radius: 0px;
+  border-bottom-right-radius: @mbl-tb-border-radius-rtl;
+  border-bottom-left-radius: 0px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  border-top-left-radius: @mbl-tb-border-radius-rtl;
+  border-top-right-radius: 0px;
+  border-bottom-left-radius: @mbl-tb-border-radius-rtl;
+  border-bottom-right-radius: 0px;
+  border-left-width: 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblHeading .mblTabBarSegmentedControl.mblTabBarRtl {
+  float: right;
+}
+/* barType="standardTab" Rtl */
+.mblTabBarStandardTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 3px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarStandardTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="slimTab" Rtl */
+.mblTabBarSlimTab .mblTabBarButtonRtl {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl:first-child {
+  border-right: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="flatTab" Rtl*/
+.mblTabBarFlatTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarFlatTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab .mblTabBarButtonRtl {
+  margin-left: 2px;
+}
+.mblTabBarTallTab .mblTabBarButtonIconAreaRtl {
+  margin-top: 8px;
+}
diff --git a/dojox/mobile/themes/common/TextArea-compat.less b/dojox/mobile/themes/common/TextArea-compat.less
new file mode 100644
index 0000000..81831a7
--- /dev/null
+++ b/dojox/mobile/themes/common/TextArea-compat.less
@@ -0,0 +1,10 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+	overflow: auto;
+}
+
+.dj_ff3 {
+	.mblTextArea {
+		-moz-border-radius: @default-button-border-radius;
+	}
+}
diff --git a/dojox/mobile/themes/common/TextArea.less b/dojox/mobile/themes/common/TextArea.less
index 57b80f9..25a4eb5 100644
--- a/dojox/mobile/themes/common/TextArea.less
+++ b/dojox/mobile/themes/common/TextArea.less
@@ -1,9 +1,14 @@
 /* dojox.mobile.TextArea */
 .mblTextArea {
+	padding: 4px 1px;
+	border-width: 1px;
+	border-style: inset;
+	font-family: Helvetica;
+	font-size: 13px;
 	.mblTextArea-styles;
 }
 
 /* dojox.mobile.ExpandingTextArea */
 .mblExpandingTextArea {
-	.mblExpandingTextArea-styles;
+	margin: 2px;
 }
diff --git a/dojox/mobile/themes/common/TextBox-compat.less b/dojox/mobile/themes/common/TextBox-compat.less
new file mode 100644
index 0000000..bb84a00
--- /dev/null
+++ b/dojox/mobile/themes/common/TextBox-compat.less
@@ -0,0 +1,6 @@
+/* dojox.mobile.TextBox */
+.dj_ff3 {
+	.mblTextBox {
+		-moz-border-radius: @default-button-border-radius;
+	}
+}
diff --git a/dojox/mobile/themes/common/TextBox.less b/dojox/mobile/themes/common/TextBox.less
index bee00c3..36427d1 100644
--- a/dojox/mobile/themes/common/TextBox.less
+++ b/dojox/mobile/themes/common/TextBox.less
@@ -1,4 +1,9 @@
 /* dojox.mobile.TextBox */
 .mblTextBox {
+	height: 22px;
+	border-width: 1px;
+	border-style: inset;
+	font-family: Helvetica;
+	font-size: 13px;
 	.mblTextBox-styles;
 }
diff --git a/dojox/mobile/themes/common/ToggleButton-compat.less b/dojox/mobile/themes/common/ToggleButton-compat.less
new file mode 100644
index 0000000..223f56e
--- /dev/null
+++ b/dojox/mobile/themes/common/ToggleButton-compat.less
@@ -0,0 +1,50 @@
+/* dojox.mobile.ToggleButton */
+.mblToggleButton {
+	background-image: url(compat/button-bg.png);
+}
+.mblToggleButtonSelected {
+	background-image: url(compat/button-sel-bg.png);
+}
+.mblToggleButtonChecked {
+	background-image: url(compat/button-chk-bg.png);
+	&.mblToggleButtonSelected {
+		background-image: url(compat/button-unsel-bg.png);
+	}
+}
+.dj_gecko {
+	.mblToggleButton {
+		background-image: @mbl-button-background-image-gecko;
+	}
+	.mblToggleButtonSelected {
+		background-image: @mbl-button-selected-background-image-gecko;
+	}
+	.mblToggleButtonChecked {
+		background-image: @mbl-button-checked-background-image-gecko;
+		&:after {
+			-moz-transform: rotate(45deg) skew(10deg);
+			-moz-transform-origin: 50% 50%;
+		}
+		&.mblToggleButtonSelected {
+			background-image: @mbl-blue-button-selected-background-image-gecko;
+		}
+	}
+}
+.dj_ff3 {
+	.mblToggleButton {
+		-moz-border-radius: @default-button-border-radius;
+	}
+	.mblToggleButton.mblToggleButtonChecked::after {
+		-moz-transform: translate(-25px,-6px) rotate(45deg) skew(10deg);
+	}
+}
+.dj_ie {
+	.mblToggleButtonChecked {
+		&:after {
+			top: 9px;
+			left: 5px;
+			width: 12px;
+			border: none;
+			background-image: url(compat/togglebutton-chk-mark-bg.png);
+		}
+	}
+}
diff --git a/dojox/mobile/themes/common/ToggleButton.less b/dojox/mobile/themes/common/ToggleButton.less
index 1796ab3..e35a753 100644
--- a/dojox/mobile/themes/common/ToggleButton.less
+++ b/dojox/mobile/themes/common/ToggleButton.less
@@ -1,28 +1,48 @@
 /* dojox.mobile.ToggleButton */
 .mblToggleButton {
 	position: relative;
+	padding: 0 10px 0 25px;
+	height: 29px;
+	border-width: 1px 1px 1px 1px;
+	border-style: outset;
+	.mbl-button-background-image();
+	font-family: Helvetica;
+	line-height: 29px;
 	cursor: pointer;
-	outline: none;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
+	.tap-highlight-color(rgba(255,255,255,0));
 	.mblToggleButton-styles;
-	&.mblToggleButtonSelected {
-		.mblToggleButtonSelected-styles;
-	}
-	&.mblToggleButtonChecked {
-		.mblToggleButtonChecked-styles;
-		&::after {
-			position: absolute;
-			.mblToggleButtonChecked-after-styles;
-		}
-		&.mblToggleButtonSelected {
-			.mblToggleButtonCheckedSelected-styles;
-			&::after {
-				.mblToggleButtonCheckedSelected-after-styles;
-			}
-		}
-	}
 	&:disabled {
+		border-color: grey;
+		background-image: none;
+		color: grey;
 		cursor: default;
-		.mblToggleButtonDisabled-styles;
+	}
+}
+.mblToggleButtonSelected {
+	.mbl-button-selected-background-image();
+	.mblToggleButtonSelected-styles;
+}
+.mblToggleButtonChecked {
+	.mbl-button-checked-background-image();
+	.mblToggleButtonChecked-styles;
+	&:after {
+		position: absolute;
+		content: "";
+		top: 6px;
+		left: 7px;
+		width: 5px;
+		height: 10px;
+		border-width: 2px;
+		border-style: none solid solid none;
+		.transform(rotate(45deg) skew(10deg));
+		.transform-origin(50% 50%);
+		.mblToggleButtonChecked-after-styles;
+	}
+	&.mblToggleButtonSelected {
+		.mbl-blue-button-selected-background-image();
+		.mblToggleButtonCheckedSelected-styles;
+		&:after {
+			.mblToggleButtonCheckedSelected-after-styles;
+		}
 	}
 }
diff --git a/dojox/mobile/themes/common/ToggleButton_rtl.less b/dojox/mobile/themes/common/ToggleButton_rtl.less
new file mode 100644
index 0000000..16d136f
--- /dev/null
+++ b/dojox/mobile/themes/common/ToggleButton_rtl.less
@@ -0,0 +1,7 @@
+/* dojox.mobile.ToggleButton Rtl */
+.mblToggleButtonRtl {
+  padding: 0 25px 0 10px!important;
+}
+.mblToggleButtonRtl.mblToggleButtonChecked:after {
+  right: 7px;
+}
diff --git a/dojox/mobile/themes/common/ToolBarButton-compat.less b/dojox/mobile/themes/common/ToolBarButton-compat.less
new file mode 100644
index 0000000..8e042ee
--- /dev/null
+++ b/dojox/mobile/themes/common/ToolBarButton-compat.less
@@ -0,0 +1,84 @@
+/* dojox.mobile.ToolBarButton */
+.dj_gecko {
+	.mblToolBarButtonArrow {
+		-moz-transform: scale(0.77, 1.05) rotate(45deg);
+	}
+	.mblHeading {
+		.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+			.mblToolBarButtonHasLeftArrowInHeading-compat-gecko;
+		}
+		.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+			.mblToolBarButtonHasRightArrowInHeading-compat-gecko;
+		}
+		.mblToolBarButtonBody {
+			.mblToolBarButtonBodyInHeading-compat-gecko;
+		}
+	}
+}
+.dj_ff3 {
+	.mblToolBarButtonArrow {
+		-moz-border-radius: 1px;
+	}
+	.mblToolBarButtonBody {
+		-moz-border-radius: @mbl-tool-bar-button-body-border-radius;
+	}
+	.mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+		-moz-border-radius-topleft: 0;
+		-moz-border-radius-bottomleft: 0;
+	}
+	.mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+		-moz-border-radius-topright: 0;
+		-moz-border-radius-bottomright: 0;
+	}
+}
+.dj_ie {
+	.mblToolBarButtonLeftArrow {
+		top: 0;
+		left: -2px;
+		width: 13px;
+		height: 31px;
+		border-style: none;
+		border-radius: 0;
+		background-image: url(compat/arrow-button-head.png);
+	}
+	.mblToolBarButtonSelected .mblToolBarButtonLeftArrow {
+		background-image: url(compat/arrow-button-head-sel.png);
+	}
+
+	.mblToolBarButtonRightArrow {
+		top: 0;
+		right: -3px;
+		width: 13px;
+		height: 31px;
+		border-style: none;
+		border-radius: 0;
+		background-image: url(compat/arrow-button-right-head.png);
+	}
+	.mblToolBarButtonSelected .mblToolBarButtonRightArrow {
+		background-image: url(compat/arrow-button-right-head-sel.png);
+	}
+	
+	.mblToolBarButtonBody {
+		background-image: url(compat/arrow-button-bg.png);
+		background-position: left bottom;
+	}
+	.mblToolBarButtonBodySelected {
+		background-image: url(compat/arrow-button-bg-sel.png);
+	}
+	.mblToolBarButtonBody table {
+		margin: 0;
+	}
+	.mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+		border-top-left-radius: 0;
+		border-bottom-left-radius: 0;
+	}
+	.mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+		border-top-right-radius: 0;
+		border-bottom-right-radius: 0;
+	}
+}
+.dj_ie6 {
+	.mblToolBarButton .mblToolBarButtonBody {
+	    background-position: left top;
+	}
+}
diff --git a/dojox/mobile/themes/common/ToolBarButton.less b/dojox/mobile/themes/common/ToolBarButton.less
index 3d8ee62..401292e 100644
--- a/dojox/mobile/themes/common/ToolBarButton.less
+++ b/dojox/mobile/themes/common/ToolBarButton.less
@@ -1,22 +1,100 @@
 /* dojox.mobile.ToolBarButton */
 .mblToolBarButton {
-	float: left;
+	display:inline-block;
 	position: relative;
-	overflow: hidden;
 	cursor: pointer;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
+	.tap-highlight-color(rgba(255,255,255,0));
+	margin: 6px;
+	padding: 0 10px;
+	height: 29px;
+	line-height: 29px;
+	text-align: center;
+	font-family: Helvetica;
+	font-size: 13px;
+	font-weight: bold;
+	vertical-align: middle;
 	.mblToolBarButton-styles;
 }
-div.mblToolBarButtonDomButton {
-	.mblToolBarButtonDomButton-styles;
+.mblToolBarButtonHasIcon, .mblToolBarButtonLightIcon {
+	padding: 0;
 }
-.mblToolBarButtonIcon {
-	position: relative;
-	.mblToolBarButtonIcon-styles;
+.mblHeading {
+	.mblToolBarButton {
+		float: left;
+	}
+	span.mblToolBarButtonLightIcon {
+		padding: 0;
+	}
+}
+.mblToolBarButtonHasLeftArrow {
+	padding-right: 0;
+	padding-left: 10px;
 }
-.mblToolBarButtonSpriteIcon {
+.mblToolBarButtonHasRightArrow {
+	padding-left: 0;
+	padding-right: 10px;
+}
+.mblToolBarButtonArrow {
 	position: absolute;
+	top: 5px;
+	width: 20px;
+	height: 19px;
+	.mblToolBarButtonArrow-styles;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  .mblToolBarButtonArrowInLeftArrow-styles;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  .mblToolBarButtonArrowInRightArrow-styles;
+}
+.mblHeading {
+	.mblToolBarButtonArrow {
+		.mblToolBarButtonArrowInHeading-styles;
+	}
+	.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+		.mblToolBarButtonHasLeftArrowInHeading-styles;
+	}
+	.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+		.mblToolBarButtonHasRightArrowInHeading-styles;
+	}
+}
+
+.mblToolBarButtonBody {
+	display: inline-block;
+	position: relative;
+	overflow: hidden;
+	border-radius: @mbl-tool-bar-button-body-border-radius;
+	.mblToolBarButtonBody-styles;
+}
+.mblToolBarButton .mblToolBarButtonBody {
+	width: 100%;
+}
+.mblHeading .mblToolBarButtonBody {
+	.mblToolBarButtonBodyInHeading-styles;
+}
+.mblToolBarButtonBody table {
+	margin: 0 auto;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  .mblToolBarButtonBodyInLeftArrow-styles;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  .mblToolBarButtonBodyInRightArrow-styles;
+}
+.mblToolBarButtonText .mblToolBarButtonIcon {
+	padding-left: 10px;
+}
+.mblToolBarButtonText .mblToolBarButtonLabel {
+	padding-right: 10px;
+	height: 29px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonIcon {
+	padding-left: 4px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonLabel {
+	padding-right: 4px;
 }
-.mblToolBarButtonText {
-	padding: 0px 10px;
+
+.mblToolBarButtonIcon > div {
+	height: 29px;
 }
diff --git a/dojox/mobile/themes/common/ToolBarButton_rtl.less b/dojox/mobile/themes/common/ToolBarButton_rtl.less
new file mode 100644
index 0000000..ffb4122
--- /dev/null
+++ b/dojox/mobile/themes/common/ToolBarButton_rtl.less
@@ -0,0 +1,18 @@
+/* dojox.mobile.ToolBarButton Rtl */
+.mblHeading .mblToolBarButtonRtl {
+  float: right;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonIcon {
+  padding-right: 10px;
+  padding-left: 0px;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonLabel {
+  padding-left: 10px;
+  padding-right: 0px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow{
+ right : @mbl-toolbar-right-arrow-rtl;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow{
+ left : @mbl-toolbar-left-arrow-rtl;
+}
diff --git a/dojox/mobile/themes/common/Tooltip-compat.less b/dojox/mobile/themes/common/Tooltip-compat.less
new file mode 100644
index 0000000..01d7411
--- /dev/null
+++ b/dojox/mobile/themes/common/Tooltip-compat.less
@@ -0,0 +1,51 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+	background-image: none;
+	.mblHeading {
+		.mblTooltip-Heading-compat;
+		.mblToolBarButton {
+			.mblTooltip-Heading-ToolbarButton-compat;
+		}
+	}
+}
+
+.dj_ff3 {
+	.mblTooltip {
+		-moz-border-radius: @mbl-tooltip-border-radius;
+	}
+}
+
+.dj_ie9 {
+	.mblTooltip .mblHeading {
+		width: auto;
+	}
+}
+
+.dj_ie6, .dj_ie7 {
+	.mblTooltipBefore .mblTooltipArrow {
+		right: 0;
+	}
+	.mblTooltipAbove .mblTooltipArrow {
+		bottom: 0;
+	}
+	.mblTooltipBefore .mblTooltipInnerArrow {
+		right: -1px;
+	}
+	.mblTooltipAbove .mblTooltipInnerArrow {
+		bottom: -1px;
+	}
+	.mblTooltip {
+		.mblHeading {
+			padding: 0 9px 12px;
+			border-top: 1px solid @heading-background-color;
+			border-bottom: 1px solid @heading-background-color;
+			width: auto;
+			height: auto;
+			overflow: visible;
+			line-height: normal;
+			.mblToolBarButton {
+				margin: auto 6px;
+			}
+		}
+	}
+}
diff --git a/dojox/mobile/themes/common/Tooltip.less b/dojox/mobile/themes/common/Tooltip.less
index 9c66e7d..38baa3b 100644
--- a/dojox/mobile/themes/common/Tooltip.less
+++ b/dojox/mobile/themes/common/Tooltip.less
@@ -4,6 +4,10 @@
 	z-index: 2000;
 	display: block;
 	margin: 0;
+	padding: 5px;
+	border-width: 1px;
+	border-style: solid;
+	opacity: .97;
 	.mblTooltip-styles;
 }
 .mblTooltipBubble {
@@ -60,7 +64,7 @@
 	width: 0;
 	height: 0;
 	line-height: 0;
-	.mblTooltipArrow-styles;
+	border: 11px solid transparent;
 }
 .mblTooltipBefore .mblTooltipArrow {
 	left: auto;
@@ -121,6 +125,10 @@
 .mblTooltipHidden * {
 	visibility: hidden !important;
 }
+.mblTooltipHidden {
+	top: -99999px !important;
+	left: -99999px !important;
+}
 
 // Headings and Button styles are overridden in Tooltips
 .mblTooltip .mblHeading {
diff --git a/dojox/mobile/themes/common/ValuePicker-compat.less b/dojox/mobile/themes/common/ValuePicker-compat.less
new file mode 100644
index 0000000..71f87a5
--- /dev/null
+++ b/dojox/mobile/themes/common/ValuePicker-compat.less
@@ -0,0 +1,23 @@
+/* dojox.mobile.ValuePicker */
+
+.mblValuePickerSlotButton {
+	background-image: url(compat/valuepicker-button-bg.png);
+}
+.mblValuePickerSlotButtonSelected {
+	background-color: @default-button-selected-background-color;
+}
+.mblValuePickerSlotInputArea {
+	background-color: #f7f7f7;
+}
+
+.dj_gecko {
+	.mblValuePickerSlotButton {
+		background-image: @mbl-value-picker-slot-button-background-image-gecko;
+	}
+	.mblValuePickerSlotButtonSelected {
+		background-image: @default-button-selected-background-image-gecko;
+	}
+	.mblValuePickerSlotInputArea {
+		background-image: @mbl-value-picker-slot-input-area-background-image-gecko;
+	}
+}
diff --git a/dojox/mobile/themes/common/ValuePicker.less b/dojox/mobile/themes/common/ValuePicker.less
new file mode 100644
index 0000000..7195c5b
--- /dev/null
+++ b/dojox/mobile/themes/common/ValuePicker.less
@@ -0,0 +1,54 @@
+/* dojox.mobile.ValuePicker */
+.mblValuePicker {
+  height: 126px;
+}
+/* dojox.mobile.ValuePickerSlot */
+.mblValuePicker > .mblValuePickerSlot {
+	float: left;
+	.mblValuePickerSlot-style;
+}
+.mblValuePickerSlotButton {
+	position: relative;
+	height: 38px;
+	.mbl-value-picker-slot-button-background-image();
+}
+.mblValuePickerSlotPlusButton {
+	border-top-left-radius: @mbl-value-picker-slot-button-radius;
+	border-top-right-radius: @mbl-value-picker-slot-button-radius;
+}
+
+.mblValuePickerSlotMinusButton {
+	border-bottom-left-radius: @mbl-value-picker-slot-button-radius;
+	border-bottom-right-radius: @mbl-value-picker-slot-button-radius;
+}
+
+.mblValuePickerSlotButtonSelected {
+	.default-button-selected-background-image();
+}
+.mblValuePickerSlotIcon {
+	top: 5px;
+	margin: 0 auto;
+}
+.mblValuePickerSlotInputArea {
+	position: relative;
+	height: 48px;
+	border-top: 1px solid #7b797b;
+	border-bottom: 1px solid #c6c3c6;
+	.mbl-value-picker-slot-input-area-background-image();
+}
+.mblValuePickerSlotInput {
+	display: block;
+	width: 90%;
+	height: 90%;
+	margin: 5% auto;
+	padding: 0;
+	text-align: center;
+	border-style: none;
+	background-color: transparent;
+	.mblValuePickerSlot-input-style;
+}
+
+/* dojox.mobile.ValuePickerTimePicker */
+.mblValuePickerTimePicker > .mblToolBarButton {
+	top: 45px;
+}
diff --git a/dojox/mobile/themes/common/common-compat.less b/dojox/mobile/themes/common/common-compat.less
new file mode 100644
index 0000000..441f256
--- /dev/null
+++ b/dojox/mobile/themes/common/common-compat.less
@@ -0,0 +1,20 @@
+.dj_gecko {
+	.mblColorBlue {
+		background-image: @default-blue-button-background-image-gecko;
+	}
+	.mblColorBlue45 {
+    background-image: @mbl-color-blue-45-gecko;
+  }
+	.mblColorDefault {
+		background-image: @default-button-background-image-gecko;
+	}
+	.mblColorDefault45 {
+    background-image: @mbl-color-default-45-gecko;
+  }
+	.mblColorDefaultSel {
+		background-image: @default-button-selected-background-image-gecko;
+	}
+	.mblColorDefaultSel45 {
+    background-image: @mbl-color-default-sel-45-gecko;
+  }
+}
diff --git a/dojox/mobile/themes/common/common.less b/dojox/mobile/themes/common/common.less
index 1c4ecf2..134559b 100644
--- a/dojox/mobile/themes/common/common.less
+++ b/dojox/mobile/themes/common/common.less
@@ -1,24 +1,51 @@
 html.mobile, .mobile body {
 	width: 100%;
-	margin: 0px;
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 }
 .mobile body {
 	overflow-x: hidden;
-	-webkit-text-size-adjust: none;
+	.text-size-adjust(none);
 	.mobile-body-styles;
 }
 
+.mblBackground {
+	.mblBackground-styles;
+}
+
 /* Button Colors */
 .mblColorBlue {
 	.mblColorBlue-styles;
 }
 
+.mblColorBlue45 {
+  .mbl-color-blue-45();
+}
+
 /* Default Button Colors */
 .mblColorDefault {
 	.mblColorDefault-styles;
 }
 
+.mblColorDefault45 {
+  .mbl-color-default-45();
+}
+
 .mblColorDefaultSel {
 	.mblColorDefaultSel-styles;
 }
+
+.mblColorDefaultSel45 {
+  .mbl-color-default-sel-45();
+}
+
+.mblSpriteIcon {
+	position: absolute;
+}
+.mblSpriteIconParent {
+	position: relative;
+	font-size: 1px;
+}
+.mblImageIcon {
+	vertical-align: top;
+}
diff --git a/dojox/mobile/themes/common/compile.js b/dojox/mobile/themes/common/compile.js
deleted file mode 100644
index 159d06b..0000000
--- a/dojox/mobile/themes/common/compile.js
+++ /dev/null
@@ -1,42 +0,0 @@
-// load libraries
-var fs = require("fs");
-var path = require("path");
-var less = require("less");
-
-// collect files
-var folders = ["../android", "../blackberry", "../iphone", "../custom"]; 
-var files = [];
-folders.forEach(function(folder){
-	files = files.concat(fs.readdirSync(folder).map(function(file){
-		return folder + "/" + file;
-	}));
-});
-files = files.filter(function(file){
-	return file && /\.less$/.test(file) && !/variables\.less$/.test(file);
-});
-
-// compile files
-files.forEach(function(file){
-	console.log("compiling " + file);
-	fs.readFile(file, "utf-8", function(error, data){
-		if(error){
-			console.error(error.message);
-			process.exit(1);
-		}
-		var parser = new(less.Parser)({paths: [path.dirname(file)], filename: file, optimization: 1});
-		parser.parse(data, function(error, tree){
-			if(error){
-				less.writeError(error);
-				process.exit(1);
-			}
-			try{
-				var css = tree.toCSS({compress: false});
-				var fd = fs.openSync(file.replace(".less", ".css"), "w");
-				fs.writeSync(fd, css, 0, "utf-8");
-			}catch(error){
-				less.writeError(error);
-				process.exit(2);
-			}
-		});
-	});
-});
diff --git a/dojox/mobile/themes/common/css3.less b/dojox/mobile/themes/common/css3.less
new file mode 100644
index 0000000..b6c571d
--- /dev/null
+++ b/dojox/mobile/themes/common/css3.less
@@ -0,0 +1,308 @@
+.transform (@v) {
+	-webkit-transform: @v;
+	transform: @v;
+}
+.transform-origin (@v) {
+	-webkit-transform-origin: @v;
+	transform-origin: @v;
+}
+.transform-style (@v) {
+	-webkit-transform-style: @v;
+// not supported in IE10
+}
+.transition-property (@v) {
+	-webkit-transition-property: @v;
+	transition-property: @v;
+}
+.transition-property-2 (@v1, @v2) {
+	-webkit-transition-property: @v1, @v2;
+	transition-property: @v1, @v2;
+}
+.transition-property-transform () {
+	-webkit-transition-property: -webkit-transform;
+	transition-property: transform;
+}
+.transition-duration (@v) {
+	-webkit-transition-duration: @v;
+	transition-duration: @v;
+}
+.transition-delay (@v) {
+	-webkit-transition-delay: @v;
+	transition-delay: @v;
+}
+.transition-timing-function (@v) {
+	-webkit-transition-timing-function: @v;
+	transition-timing-function: @v;
+}
+.animation-name (@v) {
+	-webkit-animation-name: @v;
+	animation-name: @v;
+}
+.animation-duration (@v) {
+	-webkit-animation-duration: @v;
+	animation-duration: @v;
+}
+.animation-timing-function (@v) {
+	-webkit-animation-timing-function: @v;
+	animation-timing-function: @v;
+}
+.animation-iteration-count (@v) {
+	-webkit-animation-iteration-count: @v;
+	animation-iteration-count: @v;
+}
+.box-shadow (@v) {
+	-webkit-box-shadow: @v;
+	box-shadow: @v;
+}
+.box-sizing (@v) {
+	-webkit-box-sizing: @v;
+	box-sizing: @v;
+}
+.appearance (@v) {
+	-webkit-appearance: @v;
+}
+.tap-highlight-color (@v) {
+	-webkit-tap-highlight-color: @v;
+}
+.text-size-adjust (@v) {
+	-webkit-text-size-adjust: @v;
+}
+.user-select (@v) {
+	-webkit-user-select: @v;
+	-ms-user-select: @v;
+}
+
+.background-image-linear-gradient-top-bottom (@from, @to) {
+	background-image: -webkit-gradient(linear, left top, left bottom, from(@from), to(@to));
+	background-image: linear-gradient(to bottom, @from 0%, @to 100%);
+}
+.background-linear-gradient-top-bottom (@from, @to) {
+	background: -webkit-gradient(linear, left top, left bottom, from(@from), to(@to));
+	background: linear-gradient(to bottom, @from 0%, @to 100%);
+}
+.background-image-linear-gradient-top-bottom-2-stops (@from, @to, @pos1, @color1, @pos2, @color2) {
+	background-image: -webkit-gradient(linear, left top, left bottom, from(@from), to(@to), color-stop(@pos1, @color1), color-stop(@pos2, @color2));
+	background-image: linear-gradient(to bottom, @from 0%, @color1 percentage(@pos1), @color2 percentage(@pos2), @to 100%);
+}
+.background-linear-gradient-top-bottom-2-stops (@from, @to, @pos1, @color1, @pos2, @color2) {
+	background: -webkit-gradient(linear, left top, left bottom, from(@from), to(@to), color-stop(@pos1, @color1), color-stop(@pos2, @color2));
+	background: linear-gradient(to bottom, @from 0%, @color1 percentage(@pos1), @color2 percentage(@pos2), @to 100%);
+}
+.background-image-linear-gradient-top-bottom-1-stop (@from, @to, @pos1, @color1) {
+	background-image: -webkit-gradient(linear, left top, left bottom, from(@from), to(@to), color-stop(@pos1, @color1));
+	background-image: linear-gradient(to bottom, @from 0%, @color1 percentage(@pos1), @to 100%);
+}
+.background-image-linear-gradient-top-bottom-3-stops (@from, @to, @pos1, @color1, @pos2, @color2, @pos3, @color3) {
+	background-image: -webkit-gradient(linear, left top, left bottom, from(@from), to(@to), color-stop(@pos1, @color1), color-stop(@pos2, @color2), color-stop(@pos3, @color3));
+	background-image: linear-gradient(to bottom, @from 0%, @color1 percentage(@pos1), @color2 percentage(@pos2), @color3 percentage(@pos3), @to 100%);
+}
+.background-image-linear-gradient-top-bottom-4-stops (@from, @to, @pos1, @color1, @pos2, @color2, @pos3, @color3, @pos4, @color4) {
+	background-image: -webkit-gradient(linear, left top, left bottom, from(@from), to(@to), color-stop(@pos1, @color1), color-stop(@pos2, @color2), color-stop(@pos3, @color3), color-stop(@pos4, @color4));
+	background-image: linear-gradient(to bottom, @from 0%, @color1 percentage(@pos1), @color2 percentage(@pos2), @color3 percentage(@pos3), @color4 percentage(@pos4), @to 100%);
+}
+.background-image-linear-gradient-top-bottom-4-stops-no-from-to (@pos1, @color1, @pos2, @color2, @pos3, @color3, @pos4, @color4) {
+	background-image: -webkit-gradient(linear, left top, left bottom, color-stop(@pos1, @color1), color-stop(@pos2, @color2), color-stop(@pos3, @color3), color-stop(@pos4, @color4));
+	background-image: linear-gradient(to bottom, @color1 percentage(@pos1), @color2 percentage(@pos2), @color3 percentage(@pos3), @color4 percentage(@pos4));
+}
+
+.background-image-linear-gradient-top-left-bottom-right (@from, @to) {
+	background-image: -webkit-gradient(linear, left top, right bottom, from(@from), to(@to));
+	background-image: linear-gradient(to right bottom, @from 0%, @to 100%);
+}
+.background-image-linear-gradient-top-left-bottom-right-1-stop (@from, @to, @pos1, @color1) {
+	background-image: -webkit-gradient(linear, left top, right bottom, from(@from), to(@to), color-stop(@pos1, @color1));
+	background-image: linear-gradient(to right bottom, @from 0%, @color1 percentage(@pos1), @to 100%);
+}
+.background-image-linear-gradient-top-left-bottom-right-2-stops (@from, @to, @pos1, @color1, @pos2, @color2) {
+	background-image: -webkit-gradient(linear, left top, right bottom, from(@from), to(@to), color-stop(@pos1, @color1), color-stop(@pos2, @color2));
+	background-image: linear-gradient(to right bottom, @from 0%, @color1 percentage(@pos1), @color2 percentage(@pos2), @to 100%);
+}
+.background-image-linear-gradient-top-left-bottom-right-3-stops (@from, @to, @pos1, @color1, @pos2, @color2, @pos3, @color3) {
+	background-image: -webkit-gradient(linear, left top, right bottom, from(@from), to(@to), color-stop(@pos1, @color1), color-stop(@pos2, @color2), color-stop(@pos3, @color3));
+	background-image: linear-gradient(to right bottom, @from 0%, @color1 percentage(@pos1), @color2 percentage(@pos2), @color3 percentage(@pos3), @to 100%);
+}
+
+.background-radial-gradient-center (@r, @from, @to) {
+	background: -webkit-gradient(radial, center center, 0, center center, @r, from(@from), to(@to));
+	background: radial-gradient(@r at center, @from 0%, @to 100%);
+}
+
+.background-spinwheel () {
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #313137), color-stop(0.05, #73747d), color-stop(0.07, #92939b), color-stop(0.09, #ababb5), color-stop(0.12, #c5c6ce), color-stop(0.16, #dfe0e4), color-stop(0.22, #f4f5f6), color-stop(0.35, #fbfcfc), color-stop(0.5, #fbfcfc), color-stop(0.61, #fbfcfc), color-stop(0.61, #b4c1c7), color-stop(0.65, #fbfcfc), color-stop(0.78, #f4f5f6), color-stop(0.84, #dfe0e4), color-stop(0.88, #c5c6ce), color-stop(0.91, #ababb5), col [...]
+	background: linear-gradient(to bottom, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+}
+
+.background-spinwheelbar () {
+	background: -webkit-gradient(linear, left top, left bottom, from(#edeef2), to(#a7adca), color-stop(0, #edeef2), color-stop(0.25, #c8cadd), color-stop(0.49, #bbbfd4), color-stop(0.51, #9fa8c6), color-stop(0.81, #a2a9c7), color-stop(0.82, #a6abc9), color-stop(1, #a7adca));
+	background: linear-gradient(to bottom, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 100%);
+}
+
+.holo-slider-background-image () {
+	background: -webkit-gradient(radial, 9 9, 3, 9 9, 9, from(@holo-color1), color-stop(0, @holo-color1), color-stop(0.01, @holo-slider-thumb-color), to(@holo-slider-thumb-color));
+	background-image: radial-gradient(circle closest-side at center, #FFFFFF 0%, #A435C5 50%, #251AE7 75%, #00A3EF 100%);
+}
+
+.keyframes-transform-from-to-webkit(@t1, @t2) {
+	from {
+		-webkit-transform: @t1;
+	}
+	to {
+		-webkit-transform: @t2;
+	}
+}
+
+.keyframes-transform-from-to(@t1, @t2) {
+	from {
+		transform: @t1;
+	}
+	to {
+		transform: @t2;
+	}
+}
+
+.keyframes-opacity-from-to(@o1, @o2) {
+	from {
+		opacity: @o1;
+	}
+	to {
+		opacity: @o2;
+	}
+}
+
+.keyframes-transform-opacity-from-to-webkit(@t1, @o1, @t2, @o2) {
+	from {
+		-webkit-transform: @t1;
+		opacity: @o1;
+	}
+	to {
+		-webkit-transform: @t2;
+		opacity: @o2;
+	}
+}
+
+.keyframes-transform-opacity-from-to(@t1, @o1, @t2, @o2) {
+	from {
+		transform: @t1;
+		opacity: @o1;
+	}
+	to {
+		transform: @t2;
+		opacity: @o2;
+	}
+}
+
+.keyframes-transform-0-50-100-webkit(@t1, @t2, @t3) {
+	0% {
+		-webkit-transform: @t1;
+	}
+	50% {
+		-webkit-transform: @t2;
+	}
+	100% {
+		-webkit-transform: @t3;
+	}
+}
+
+.keyframes-transform-0-50-100(@t1, @t2, @t3) {
+	0% {
+		transform: @t1;
+	}
+	50% {
+		transform: @t2;
+	}
+	100% {
+		transform: @t3;
+	}
+}
+
+.keyframes-z-index-transform-opacity-0-50-100-webkit(@i1, @t1, @o1, @i2, @t2, @o2, @i3, @t3, @o3) {
+	0% {
+		z-index: @i1;
+		-webkit-transform: @t1;
+		opacity: @o1;
+	}
+	50% {
+		z-index: @i2;
+		-webkit-transform: @t2;
+		opacity: @o2;
+	}
+	100% {
+		z-index: @i3;
+		-webkit-transform: @t3;
+		opacity: @o3;
+	}
+}
+
+.keyframes-z-index-transform-opacity-0-50-100(@i1, @t1, @o1, @i2, @t2, @o2, @i3, @t3, @o3) {
+	0% {
+		z-index: @i1;
+		transform: @t1;
+		opacity: @o1;
+	}
+	50% {
+		z-index: @i2;
+		transform: @t2;
+		opacity: @o2;
+	}
+	100% {
+		z-index: @i3;
+		transform: @t3;
+		opacity: @o3;
+	}
+}
+
+.keyframes-vibrate-webkit() {
+	0%{
+		-webkit-transform: rotate(-2deg);
+		bottom: -1px;
+		left: -1px;
+	}
+	25% {
+		-webkit-transform: rotate(1deg);
+		bottom: 2px;
+		left: 1px;
+	}
+	50% {
+		-webkit-transform: rotate(-1deg);
+		bottom: -2px;
+		left: -1px;
+	}
+	75% {
+		-webkit-transform: rotate(2deg);
+		bottom: 2px;
+		left: 1px;
+	}
+	100% {
+		-webkit-transform: rotate(-2deg);
+		bottom: -1px;
+		left: -1px;
+	}
+}
+
+.keyframes-vibrate() {
+	0%{
+		transform: rotate(-2deg);
+		bottom: -1px;
+		left: -1px;
+	}
+	25% {
+		transform: rotate(1deg);
+		bottom: 2px;
+		left: 1px;
+	}
+	50% {
+		transform: rotate(-1deg);
+		bottom: -2px;
+		left: -1px;
+	}
+	75% {
+		transform: rotate(2deg);
+		bottom: 2px;
+		left: 1px;
+	}
+	100% {
+		transform: rotate(-2deg);
+		bottom: -1px;
+		left: -1px;
+	}
+}
diff --git a/dojox/mobile/themes/common/dijit/Calendar-compat.css b/dojox/mobile/themes/common/dijit/Calendar-compat.css
deleted file mode 100644
index f180b2f..0000000
--- a/dojox/mobile/themes/common/dijit/Calendar-compat.css
+++ /dev/null
@@ -1,9 +0,0 @@
-.dijitCalendar thead {
-	background-image: url(compat/calendar-month-bg.png);
-}
-.dijitCalendarDayLabelTemplate {
-	background-image: url(compat/calendar-daylabel-bg.png);
-}
-.dijitCalendarYearLabel {
-	background-image: url(compat/calendar-year-bg.png);
-}
diff --git a/dojox/mobile/themes/common/dijit/Calendar-compat.less b/dojox/mobile/themes/common/dijit/Calendar-compat.less
new file mode 100644
index 0000000..876fb1d
--- /dev/null
+++ b/dojox/mobile/themes/common/dijit/Calendar-compat.less
@@ -0,0 +1,44 @@
+/* dijit.Calendar */
+.dijitCalendar thead {
+	background-repeat: repeat-x;
+	.dijitCalendar-thead-compat;
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+	background-repeat: repeat-x;
+	.dijitCalendarDateLabel-Selected-compat;
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+	background-repeat: repeat-x;
+	.dijitCalendarDateLabel-Active-compat;
+}
+.dijitCalendarYearLabel {
+	background-repeat: repeat-x;
+	.dijitCalendarYearLabel-compat;
+}
+
+.dj_gecko {
+	.dijitCalendar .dijitDropDownButton .dijitButtonNode {
+		-moz-box-shadow: 0 0 0 transparent;
+	}
+	.dijitCalendar thead {
+		.dijitCalendar-thead-compat-gecko;
+	}
+	.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+		.dijitCalendarDateLabel-Selected-compat-gecko;
+	}
+	.dijitCalendarActiveDate .dijitCalendarDateLabel {
+		.dijitCalendarDateLabel-Active-compat-gecko;
+	}
+	.dijitCalendarYearLabel {
+		.dijitCalendarYearLabel-compat-gecko;
+	}
+}
+
+.dj_ff3 {
+	.dijitCalendar {
+		-moz-border-radius: 0;
+	}
+	.dijitCalendarMonthMenu {
+		.dijitCalendarMonthMenu-compat-ff3;
+	}
+}
\ No newline at end of file
diff --git a/dojox/mobile/themes/common/dijit/Calendar.css b/dojox/mobile/themes/common/dijit/Calendar.css
deleted file mode 100644
index 4e27ae1..0000000
--- a/dojox/mobile/themes/common/dijit/Calendar.css
+++ /dev/null
@@ -1,135 +0,0 @@
-/*if you link this stylesheet directory, mobile/common/dijit/base.css must already be imported*/
-
-/* dijit base styles to override (based on claro) */
- at import url("../../../../../dijit/themes/claro/form/Common.css");
- at import url("../../../../../dijit/themes/claro/form/Button.css");
- at import url("../../../../../dijit/themes/claro/Calendar.css");
-
-.dijitCalendar {
-	border: solid 1px #B5BCC7;
-	background-color: #CFE5FA;
-	width: 320px;
-	text-align: center;
-	padding: 0px 0px 0px 0px;
-	-moz-border-radius: 0px;
-	border-radius: 0px;
-}
-.dijitCalendar thead {
-	vertical-align: middle;
-	border-color: inherit;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F6F6F6), to(#CCCCD1));
-}
-.dijitCalendarMonthLabel {
-	color: #545454;
-	font-size: 22px;
-	padding: 0 4px;
-	font-family: Helvetica;
-	text-shadow: rgba(247,247,247,0.6) 0px 1px 0px;
-}
-
-.dijitCalendar .dijitDropDownButton .dijitButtonNode {
-	background-color: transparent;
-	background-image: none;
-	padding: 0 3px 0 2px;
-	border: none;
-	-webkit-box-shadow: 0 0 0 transparent;
-	-moz-box-shadow: 0 0 0 transparent;
-	box-shadow: 0 0 0 transparent;
-	-moz-border-radius: 0px;
-	border-radius: 0px;
-}
-
-.dijitArrowButtonInner {
-	display: none;
-}
-
-.dijitCalendarDayLabelTemplate {
-	text-align: center;
-	font-size: 9px;
-	color: #545454;
-	text-shadow: rgba(247,247,247,0.6) 0px 1px 0px;
-}
-
-.dijitCalendarHoveredDate .dijitCalendarDateLabel {
-	background-color: #ABD6FF;
-	border: solid 1px #769DC0;
-	color: black;
-	-webkit-transition-duration: 0.2s;
-	-moz-transition-duration: 0.2s;
-	transition-duration: 0.2s;
-}
-
-.dijitCalendarDateTemplate {
-	text-align: center;
-	background-color: #DDDDE0;
-	border-bottom: 1px solid lightGrey;
-	padding-top: 0;
-/*				color: #545454;*/
-	color: #4A5B6E;
-	text-shadow: rgba(231,231,233,1.0) 0px 1px 0px;
-	font-size: 22px;
-	font-weight: normal;
-	font-family: Helvetica;
-	text-align: center;
-}
-
-.dijitCalendarDateTemplate .dijitCalendarDateLabel {
-	text-decoration: none;
-	display: block;
-	padding: 3px 5px 3px 4px;
-	border-top: solid 1px #ECEEEF; 
-	border-bottom: solid 1px #A6AAB3; 
-	border-left: solid 1px #A0A4AD; 
-	border-right: solid 1px #ECECED; 
-	background-color: rgba(171, 212, 251, 0);
-	-webkit-transition-property: background-color, border;
-	-moz-transition-property: background-color, border;
-	transition-property: background-color, border;
-	-webkit-transition-duration: 0.35s;
-	-moz-transition-duration: 0.35s;
-	transition-duration: 0.35s;
-}
-
-.dijitCalendarPreviousMonth .dijitCalendarDateLabel, 
-.dijitCalendarNextMonth .dijitCalendarDateLabel {
-	color: #9099A4;
-}
-
-.dijitCalendarSelectedDate .dijitCalendarDateLabel {
-	background-color: #1A80E5;
-	border-top: solid 1px #1037B3; 
-	border-bottom: solid 1px #1037B3; 
-	border-left: solid 1px #1037B3; 
-	border-right: solid 1px #1037B3; 
-	color: white;
-	text-shadow: rgba(0,0,0,0.4) 0px 1px 0px;
-}
-
-.dijitCalendarActiveDate .dijitCalendarDateLabel {
-	background-color: #1A80E5;
-	border: solid 1px white;
-	-webkit-transition-duration: 0.1s;
-	-moz-transition-duration: 0.1s;
-	transition-duration: 0.1s;
-}
-
-.dijitCalendarYearLabel {
-	padding: 2px 0 0 0;
-	margin: 0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F6F6F6), to(#CCCCD1));
-}
-
-.dijitCalendarSelectedYear {
-	font-size: 1.091em;
-	color: #545454;
-	font-family: Helvetica;
-	text-shadow: rgba(247,247,247,0.6) 0px 1px 0px;
-}
-
-.dijitCalendarNextYear, 
-.dijitCalendarPreviousYear {
-	padding: 1px 6px 1px 6px;
-	color: #545454;
-	text-shadow: rgba(247,247,247,0.6) 0px 1px 0px;
-	font-size: 0.909em;
-}
\ No newline at end of file
diff --git a/dojox/mobile/themes/common/dijit/Calendar.less b/dojox/mobile/themes/common/dijit/Calendar.less
new file mode 100644
index 0000000..70c45ca
--- /dev/null
+++ b/dojox/mobile/themes/common/dijit/Calendar.less
@@ -0,0 +1,106 @@
+/* if you link this style sheet, dijit/themes/dijit.css must be imported. */
+
+/* dijit.Calendar */
+.dijitCalendar {
+	padding: 0;
+	width: 320px;
+	border-radius: 0;
+	text-align: center;
+	.dijitCalendar-styles;
+}
+.dijitCalendar thead {
+	border-color: inherit;
+	vertical-align: middle;
+	.dijitCalendar-thead-styles;
+}
+.dijitCalendarMonthLabel {
+	padding: 0 4px;
+	font-family: Helvetica;
+	text-shadow: rgba(247,247,247,0.6) 0 1px 0px;
+	.dijitCalendarMonthLabel-styles;
+}
+.dijitCalendarMonthMenu {
+	.dijitCalendarMonthMenu-styles;
+}
+.dijitCalendarMonthMenu .dijitCalendarMonthLabel {
+	.dijitCalendarMonthMenu-Label-styles;
+}
+.dijitCalendar .dijitDropDownButton .dijitButtonNode {
+	padding: 0 3px 0 2px;
+	border: none;
+	background-color: transparent;
+	background-image: none;
+	.box-shadow(0 0 0 transparent);
+}
+.dijitArrowButtonInner {
+	display: none;
+}
+.dijitCalendarMonthContainer th {
+	border-right: 1px solid transparent;
+}
+.dijitCalendarIncrementControl {
+	width: 0;
+	height: 0;
+ 	border: 6px solid transparent !important;
+}
+.dijitCalendarDecrease {
+	border-left-width: 0 !important;
+	.dijitCalendarDecrease-styles;
+}
+.dijitCalendarIncrease {
+	border-right-width: 0 !important;
+	.dijitCalendarIncrease-styles;
+}
+.dijitA11ySideArrow {
+    display: none;
+}
+.dijitCalendarDayLabelTemplate {
+	border-right: 1px solid transparent;
+	text-align: center;
+	text-shadow: rgba(247,247,247,0.6) 0px 1px 0px;
+	.dijitCalendarDayLabelTemplate-styles;
+}
+.dijitCalendarDateTemplate {
+	border-bottom: 1px solid lightGrey;
+	font-family: Helvetica;
+	font-size: 22px;
+	font-weight: normal;
+	text-align: center;
+	.dijitCalendarDateTemplate-styles;
+}
+.dijitCalendarDateTemplate:last-child {
+	.dijitCalendarDateTemplate-LastChild-styles;
+}
+.dijitCalendarDateTemplate .dijitCalendarDateLabel {
+	padding: 3px 5px 3px 4px;
+	display: block;
+	text-decoration: none;
+	.dijitCalendarDateLabel-DateTemplate-styles;
+}
+.dijitCalendarPreviousMonth .dijitCalendarDateLabel, 
+.dijitCalendarNextMonth .dijitCalendarDateLabel {
+	.dijitCalendarDateLabel-PrevMonth-styles;
+}
+.dijitCalendarHoveredDate .dijitCalendarDateLabel {
+	.dijitCalendarDateLabel-Hovered-styles;
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+	.dijitCalendarDateLabel-Selected-styles;
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+	.dijitCalendarDateLabel-Active-styles;
+}
+.dijitCalendarYearLabel {
+	margin: 0;
+	.dijitCalendarYearLabel-styles;
+}
+.dijitCalendarSelectedYear {
+	font-family: Helvetica;
+	text-shadow: rgba(247,247,247,0.6) 0px 1px 0px;
+	.dijitCalendarSelectedYear-styles;
+}
+.dijitCalendarNextYear, 
+.dijitCalendarPreviousYear {
+	text-shadow: rgba(247,247,247,0.6) 0px 1px 0px;
+	.dijitCalendarNextYear-styles;
+}
diff --git a/dojox/mobile/themes/common/dijit/ColorPalette.css b/dojox/mobile/themes/common/dijit/ColorPalette.css
index 6184c9c..f2df3eb 100644
--- a/dojox/mobile/themes/common/dijit/ColorPalette.css
+++ b/dojox/mobile/themes/common/dijit/ColorPalette.css
@@ -1,8 +1,7 @@
 /*if you link this stylesheet directory, mobile/common/dijit/base.css must already be imported*/
 
 .dijitColorPalette {
-	border: 0 solid #B5BCC7;
-	outline: 0;
+	border: 0 solid #b5bcc7;
 	background: none;
 }
 .dijitColorPalette .dijitColorPaletteSwatch {
diff --git a/dojox/mobile/themes/common/dijit/ColorPicker.css b/dojox/mobile/themes/common/dijit/ColorPicker.css
index b3989b4..a38295e 100644
--- a/dojox/mobile/themes/common/dijit/ColorPicker.css
+++ b/dojox/mobile/themes/common/dijit/ColorPicker.css
@@ -6,7 +6,7 @@
 .dojoxColorPicker {
 	padding: 8px;
 	-moz-border-radius: 4pt;
-	-webkit-border-radius: 5pt;
+	border-radius: 5pt;
 	-webkit-drop-shadow: 3pt;
 	background: gray;
 }
diff --git a/dojox/mobile/themes/common/dijit/base.css b/dojox/mobile/themes/common/dijit/base.css
index 53c6ac8..a890089 100644
--- a/dojox/mobile/themes/common/dijit/base.css
+++ b/dojox/mobile/themes/common/dijit/base.css
@@ -10,6 +10,5 @@
 @import url("../../../../../dijit/themes/claro/claro_rtl.css");
 
 /* mobile styling variants of dijit and dojox desktop widgets */
- at import url("Calendar.css");
 @import url("ColorPalette.css");
 @import url("ColorPicker.css");
diff --git a/dojox/mobile/themes/common/dijit/dijit-compat.css b/dojox/mobile/themes/common/dijit/dijit-compat.css
deleted file mode 100644
index aea6c3c..0000000
--- a/dojox/mobile/themes/common/dijit/dijit-compat.css
+++ /dev/null
@@ -1 +0,0 @@
- at import url("Calendar-compat.css");
diff --git a/dojox/mobile/themes/common/dijit/dijit.css b/dojox/mobile/themes/common/dijit/dijit.css
index 5345028..19a66c1 100644
--- a/dojox/mobile/themes/common/dijit/dijit.css
+++ b/dojox/mobile/themes/common/dijit/dijit.css
@@ -1,4 +1,3 @@
 @import url("base.css");
- at import url("Calendar.css");
 @import url("ColorPalette.css");
 @import url("ColorPicker.css");
\ No newline at end of file
diff --git a/dojox/mobile/themes/common/domButtons-compat.css b/dojox/mobile/themes/common/domButtons-compat.css
index 751a376..956b290 100644
--- a/dojox/mobile/themes/common/domButtons-compat.css
+++ b/dojox/mobile/themes/common/domButtons-compat.css
@@ -1,5 +1,6 @@
 /* DOM Buttons */
 @import url("domButtons/DomButtonWhitePlus-compat.css");
+ at import url("domButtons/DomButtonWhiteMinus-compat.css");
 @import url("domButtons/DomButtonWhiteUpArrow-compat.css");
 @import url("domButtons/DomButtonWhiteDownArrow-compat.css");
 @import url("domButtons/DomButtonWhiteSearch-compat.css");
@@ -36,3 +37,12 @@
 
 @import url("domButtons/DomButtonYellowStar-compat.css");
 @import url("domButtons/DomButtonGrayStar-compat.css");
+
+ at import url("domButtons/DomButtonGrayCross-compat.css");
+ at import url("domButtons/DomButtonRedCross-compat.css");
+ at import url("domButtons/DomButtonWhiteCross-compat.css");
+
+ at import url("domButtons/DomButtonGrayKnob-compat.css");
+
+ at import url("domButtons/DomButtonGrayPlus-compat.css");
+ at import url("domButtons/DomButtonGrayMinus-compat.css");
diff --git a/dojox/mobile/themes/common/domButtons.css b/dojox/mobile/themes/common/domButtons.css
index 9a1bf58..97d0b78 100644
--- a/dojox/mobile/themes/common/domButtons.css
+++ b/dojox/mobile/themes/common/domButtons.css
@@ -1,5 +1,14 @@
 /* DOM Buttons */
+
+/* This file includes all the DOM buttons regardless of whether they
+   are actually used or not.
+   For performance reason, use of this file is not recommended except
+   during development.
+   You should include only the files your application needs.
+   Note also that IE has a limitation on the number of CSS files. */
+
 @import url("domButtons/DomButtonWhitePlus.css");
+ at import url("domButtons/DomButtonWhiteMinus.css");
 @import url("domButtons/DomButtonWhiteUpArrow.css");
 @import url("domButtons/DomButtonWhiteDownArrow.css");
 @import url("domButtons/DomButtonWhiteSearch.css");
@@ -40,3 +49,12 @@
 
 @import url("domButtons/DomButtonYellowStar.css");
 @import url("domButtons/DomButtonGrayStar.css");
+
+ at import url("domButtons/DomButtonGrayCross.css");
+ at import url("domButtons/DomButtonRedCross.css");
+ at import url("domButtons/DomButtonWhiteCross.css");
+
+ at import url("domButtons/DomButtonGrayKnob.css");
+
+ at import url("domButtons/DomButtonGrayPlus.css");
+ at import url("domButtons/DomButtonGrayMinus.css");
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross.css b/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross.css
index 47bbab9..bac3432 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross.css
@@ -1,49 +1,51 @@
 /* === Black Circle Cross Button ==*/
 .mblDomButtonBlackCircleCross {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
 .mblDomButtonBlackCircleCross > div {
-	position: relative;
-	top: 3px;
-	left: 3px;
-	width: 23px;
-	height: 23px;
-	background-color: white;
-	-webkit-border-radius: 12px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  position: relative;
+  top: 3px;
+  left: 3px;
+  width: 23px;
+  height: 23px;
+  background-color: white;
+  border-radius: 12px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
 }
 .mblDomButtonBlackCircleCross > div > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 19px;
-	height: 19px;
-	background-color: black;
-	-webkit-border-radius: 10px;
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 19px;
+  height: 19px;
+  background-color: black;
+  border-radius: 10px;
 }
 .mblDomButtonBlackCircleCross > div > div > div {
-	position: absolute;
-	top: 8px;
-	left: 3px;
-	width: 13px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	border-style: none;
-	background-color: white;
-	-webkit-transform: rotate(45deg);
-	-webkit-border-radius: 1px;
+  position: absolute;
+  top: 8px;
+  left: 3px;
+  width: 13px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  border-style: none;
+  background-color: white;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  border-radius: 1px;
 }
 .mblDomButtonBlackCircleCross > div > div > div > div {
-	position: absolute;
-	top: -5px;
-	left: 5px;
-	width: 3px;
-	height: 13px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-	-webkit-border-radius: 1px;
+  position: absolute;
+  top: -5px;
+  left: 5px;
+  width: 3px;
+  height: 13px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
+  border-radius: 1px;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross.less b/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross.less
new file mode 100644
index 0000000..7cbb2e4
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackCircleCross.less
@@ -0,0 +1,50 @@
+ at import "../css3.less";
+/* === Black Circle Cross Button ==*/
+.mblDomButtonBlackCircleCross {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonBlackCircleCross > div {
+	position: relative;
+	top: 3px;
+	left: 3px;
+	width: 23px;
+	height: 23px;
+	background-color: white;
+	border-radius: 12px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonBlackCircleCross > div > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 19px;
+	height: 19px;
+	background-color: black;
+	border-radius: 10px;
+}
+.mblDomButtonBlackCircleCross > div > div > div {
+	position: absolute;
+	top: 8px;
+	left: 3px;
+	width: 13px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	border-style: none;
+	background-color: white;
+	.transform(rotate(45deg));
+	border-radius: 1px;
+}
+.mblDomButtonBlackCircleCross > div > div > div > div {
+	position: absolute;
+	top: -5px;
+	left: 5px;
+	width: 3px;
+	height: 13px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+	border-radius: 1px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackDownArrow16-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonBlackDownArrow16-compat.css
new file mode 100644
index 0000000..c4cddb8
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackDownArrow16-compat.css
@@ -0,0 +1,8 @@
+/* === BlackDownArrow16 ==*/
+.mblDomButtonBlackDownArrow16 {
+	background-image: url(compat/mblDomButtonBlackDownArrow16.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonBlackDownArrow16 > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackDownArrow16.css b/dojox/mobile/themes/common/domButtons/DomButtonBlackDownArrow16.css
new file mode 100644
index 0000000..48c6b10
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackDownArrow16.css
@@ -0,0 +1,23 @@
+/* === BlackDownArrow16 ==*/
+.mblDomButtonBlackDownArrow16 {
+  position: relative;
+  width: 16px;
+  height: 16px;
+}
+.mblDomButtonBlackDownArrow16 > div {
+  position: absolute;
+  left: 0px;
+  clip: rect(4px 16px 16px 0px);
+}
+.mblDomButtonBlackDownArrow16 > div > div {
+  position: absolute;
+  top: 0px;
+  left: 3px;
+  width: 10px;
+  height: 10px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: black;
+  -webkit-transform: scaleX(0.5) rotate(45deg);
+  transform: scaleX(0.5) rotate(45deg);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackDownArrow16.less b/dojox/mobile/themes/common/domButtons/DomButtonBlackDownArrow16.less
new file mode 100644
index 0000000..8f5d80e
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackDownArrow16.less
@@ -0,0 +1,23 @@
+ at import "../css3.less";
+/* === BlackDownArrow16 ==*/
+.mblDomButtonBlackDownArrow16 {
+	position: relative;
+	width: 16px;
+	height: 16px;
+}
+.mblDomButtonBlackDownArrow16 > div {
+	position: absolute;
+	left: 0px;
+	clip: rect(4px 16px 16px 0px);
+}
+.mblDomButtonBlackDownArrow16 > div > div {
+	position: absolute;
+	top: 0px;
+	left: 3px;
+	width: 10px;
+	height: 10px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: black;
+	.transform(scaleX(0.5) rotate(45deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackLeftArrow16-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonBlackLeftArrow16-compat.css
new file mode 100644
index 0000000..f780948
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackLeftArrow16-compat.css
@@ -0,0 +1,8 @@
+/* === BlackLeftArrow16 ==*/
+.mblDomButtonBlackLeftArrow16 {
+	background-image: url(compat/mblDomButtonBlackLeftArrow16.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonBlackLeftArrow16 > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackLeftArrow16.css b/dojox/mobile/themes/common/domButtons/DomButtonBlackLeftArrow16.css
new file mode 100644
index 0000000..85cc5ac
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackLeftArrow16.css
@@ -0,0 +1,23 @@
+/* === BlackLeftArrow16 ==*/
+.mblDomButtonBlackLeftArrow16 {
+  position: relative;
+  width: 16px;
+  height: 16px;
+}
+.mblDomButtonBlackLeftArrow16 > div {
+  position: absolute;
+  left: 0px;
+  clip: rect(0px 12px 16px 4px);
+}
+.mblDomButtonBlackLeftArrow16 > div > div {
+  position: absolute;
+  top: 3px;
+  left: 6px;
+  width: 10px;
+  height: 10px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: black;
+  -webkit-transform: scaleY(0.5) rotate(45deg);
+  transform: scaleY(0.5) rotate(45deg);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackLeftArrow16.less b/dojox/mobile/themes/common/domButtons/DomButtonBlackLeftArrow16.less
new file mode 100644
index 0000000..3d78750
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackLeftArrow16.less
@@ -0,0 +1,23 @@
+ at import "../css3.less";
+/* === BlackLeftArrow16 ==*/
+.mblDomButtonBlackLeftArrow16 {
+	position: relative;
+	width: 16px;
+	height: 16px;
+}
+.mblDomButtonBlackLeftArrow16 > div {
+	position: absolute;
+	left: 0px;
+	clip: rect(0px 12px 16px 4px);
+}
+.mblDomButtonBlackLeftArrow16 > div > div {
+	position: absolute;
+	top: 3px;
+	left: 6px;
+	width: 10px;
+	height: 10px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: black;
+	.transform(scaleY(0.5) rotate(45deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackRightArrow16-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonBlackRightArrow16-compat.css
new file mode 100644
index 0000000..4f3910c
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackRightArrow16-compat.css
@@ -0,0 +1,8 @@
+/* === BlackRightArrow16 ==*/
+.mblDomButtonBlackRightArrow16 {
+	background-image: url(compat/mblDomButtonBlackRightArrow16.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonBlackRightArrow16 > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackRightArrow16.css b/dojox/mobile/themes/common/domButtons/DomButtonBlackRightArrow16.css
new file mode 100644
index 0000000..98449fb
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackRightArrow16.css
@@ -0,0 +1,23 @@
+/* === BlackRightArrow16 ==*/
+.mblDomButtonBlackRightArrow16 {
+  position: relative;
+  width: 16px;
+  height: 16px;
+}
+.mblDomButtonBlackRightArrow16 > div {
+  position: absolute;
+  left: 0px;
+  clip: rect(0px 16px 16px 4px);
+}
+.mblDomButtonBlackRightArrow16 > div > div {
+  position: absolute;
+  top: 3px;
+  left: 0px;
+  width: 10px;
+  height: 10px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: black;
+  -webkit-transform: scaleY(0.5) rotate(45deg);
+  transform: scaleY(0.5) rotate(45deg);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackRightArrow16.less b/dojox/mobile/themes/common/domButtons/DomButtonBlackRightArrow16.less
new file mode 100644
index 0000000..be0db8a
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackRightArrow16.less
@@ -0,0 +1,23 @@
+ at import "../css3.less";
+/* === BlackRightArrow16 ==*/
+.mblDomButtonBlackRightArrow16 {
+	position: relative;
+	width: 16px;
+	height: 16px;
+}
+.mblDomButtonBlackRightArrow16 > div {
+	position: absolute;
+	left: 0px;
+	clip: rect(0px 16px 16px 4px);
+}
+.mblDomButtonBlackRightArrow16 > div > div {
+	position: absolute;
+	top: 3px;
+	left: 0px;
+	width: 10px;
+	height: 10px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: black;
+	.transform(scaleY(0.5) rotate(45deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackUpArrow16-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonBlackUpArrow16-compat.css
new file mode 100644
index 0000000..7596dba
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackUpArrow16-compat.css
@@ -0,0 +1,8 @@
+/* === BlackUpArrow16 ==*/
+.mblDomButtonBlackUpArrow16 {
+	background-image: url(compat/mblDomButtonBlackUpArrow16.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonBlackUpArrow16 > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackUpArrow16.css b/dojox/mobile/themes/common/domButtons/DomButtonBlackUpArrow16.css
new file mode 100644
index 0000000..8f20edd
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackUpArrow16.css
@@ -0,0 +1,23 @@
+/* === BlackUpArrow16 ==*/
+.mblDomButtonBlackUpArrow16 {
+  position: relative;
+  width: 16px;
+  height: 16px;
+}
+.mblDomButtonBlackUpArrow16 > div {
+  position: absolute;
+  left: 0px;
+  clip: rect(0px 16px 12px 0px);
+}
+.mblDomButtonBlackUpArrow16 > div > div {
+  position: absolute;
+  top: 6px;
+  left: 3px;
+  width: 10px;
+  height: 10px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: black;
+  -webkit-transform: scaleX(0.5) rotate(45deg);
+  transform: scaleX(0.5) rotate(45deg);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlackUpArrow16.less b/dojox/mobile/themes/common/domButtons/DomButtonBlackUpArrow16.less
new file mode 100644
index 0000000..d37b503
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlackUpArrow16.less
@@ -0,0 +1,23 @@
+ at import "../css3.less";
+/* === BlackUpArrow16 ==*/
+.mblDomButtonBlackUpArrow16 {
+	position: relative;
+	width: 16px;
+	height: 16px;
+}
+.mblDomButtonBlackUpArrow16 > div {
+	position: absolute;
+	left: 0px;
+	clip: rect(0px 16px 12px 0px);
+}
+.mblDomButtonBlackUpArrow16 > div > div {
+	position: absolute;
+	top: 6px;
+	left: 3px;
+	width: 10px;
+	height: 10px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: black;
+	.transform(scaleX(0.5) rotate(45deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueBadge-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueBadge-compat.css
new file mode 100644
index 0000000..8a67aee
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueBadge-compat.css
@@ -0,0 +1,6 @@
+/* === Blue Badge ==*/
+.mblDomButtonBlueBadge > div {
+	-moz-border-radius: 12px;
+	background-color: #4282de;
+	background-image: -moz-linear-gradient(top, #6ba2e7 0%, #4282de 50%, #216dd6 50%, #216dd6 100%);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueBadge.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueBadge.css
new file mode 100644
index 0000000..e0a0bde
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueBadge.css
@@ -0,0 +1,29 @@
+/* === Blue Badge ==*/
+.mblDomButtonBlueBadge {
+  position: relative;
+  width: 29px;
+  height: 29px;
+  text-align: right;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+}
+.mblDomButtonBlueBadge > div {
+  position: absolute;
+  display: inline;
+  padding: 0px 5px;
+  top: 2px;
+  right: 2px;
+  color: white;
+  border: 2px solid white;
+  border-radius: 12px;
+  text-align: center;
+  background: -webkit-gradient(linear, left top, left bottom, from(#6ba2e7), to(#216dd6), color-stop(0.5, #4282de), color-stop(0.5, #216dd6));
+  background: linear-gradient(to bottom, #6ba2e7 0%, #4282de 50%, #216dd6 50%, #216dd6 100%);
+  background-clip: padding-box;
+  -webkit-box-shadow: 2px 3px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 2px 3px 2px rgba(0, 0, 0, 0.5);
+}
+.mblDomButtonBlueBadge > div > div {
+  display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueBadge.less b/dojox/mobile/themes/common/domButtons/DomButtonBlueBadge.less
new file mode 100644
index 0000000..6bc6cfe
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueBadge.less
@@ -0,0 +1,28 @@
+ at import "../css3.less";
+/* === Blue Badge ==*/
+.mblDomButtonBlueBadge {
+	position: relative;
+	width: 29px;
+	height: 29px;
+	text-align: right;
+	font-family: Helvetica;
+	font-size: 16px;
+	font-weight: bold;
+}
+.mblDomButtonBlueBadge > div {
+	position: absolute;
+	display: inline;
+	padding: 0px 5px;
+	top: 2px;
+	right: 2px;
+	color: white;
+	border: 2px solid white;
+	border-radius: 12px;
+	text-align: center;
+	.background-linear-gradient-top-bottom-2-stops(#6ba2e7, #216dd6, 0.5, #4282de, 0.5, #216dd6);
+	background-clip: padding-box;
+	.box-shadow(2px 3px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonBlueBadge > div > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueBall.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueBall.css
index 79eaf75..846a58e 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonBlueBall.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueBall.css
@@ -1,15 +1,16 @@
 /* === Blue Ball Button ==*/
 .mblDomButtonBlueBall {
-	position: relative;
-	width: 19px;
-	height: 29px;
+  position: relative;
+  width: 19px;
+  height: 29px;
 }
 .mblDomButtonBlueBall > div {
-	position: relative;
-	top: 8px;
-	left: 4px;
-	width: 14px;
-	height: 14px;
-	-webkit-border-radius: 7px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#84AFF4), to(#2758B3));
+  position: relative;
+  top: 8px;
+  left: 4px;
+  width: 14px;
+  height: 14px;
+  border-radius: 7px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#84aff4), to(#2758b3));
+  background: linear-gradient(to bottom, #84aff4 0%, #2758b3 100%);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueBall.less b/dojox/mobile/themes/common/domButtons/DomButtonBlueBall.less
new file mode 100644
index 0000000..a58ae86
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueBall.less
@@ -0,0 +1,16 @@
+ at import "../css3.less";
+/* === Blue Ball Button ==*/
+.mblDomButtonBlueBall {
+	position: relative;
+	width: 19px;
+	height: 29px;
+}
+.mblDomButtonBlueBall > div {
+	position: relative;
+	top: 8px;
+	left: 4px;
+	width: 14px;
+	height: 14px;
+	border-radius: 7px;
+	.background-linear-gradient-top-bottom(#84aff4, #2758b3);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow.css
index 2995fb1..c6447af 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow.css
@@ -1,48 +1,50 @@
 /* === Blue Circle Arrow Buttons ==*/
 .mblDomButtonBlueCircleArrow {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
-
 .mblDomButtonBlueCircleArrow > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 22px;
-	height: 22px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 12px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 22px;
+  height: 22px;
+  border: 1px solid #b5b6b5;
+  border-radius: 12px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
 }
 .mblDomButtonBlueCircleArrow > div > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 18px;
-	height: 18px;
-	-webkit-border-radius: 9px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#6BA2E7), to(#216DD6), color-stop(0.5, #4282DE), color-stop(0.5, #216DD6));
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 18px;
+  height: 18px;
+  border-radius: 9px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#6ba2e7), to(#216dd6), color-stop(0.5, #4282de), color-stop(0.5, #216dd6));
+  background: linear-gradient(to bottom, #6ba2e7 0%, #4282de 50%, #216dd6 50%, #216dd6 100%);
 }
 .mblDomButtonBlueCircleArrow > div > div > div {
-	position: absolute;
-	top: 5px;
-	left: 6px;
-	width: 8px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	border-style: none;
-	background: white;
-	-webkit-transform: rotate(45deg);
+  position: absolute;
+  top: 5px;
+  left: 6px;
+  width: 8px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  border-style: none;
+  background: white;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
 }
 .mblDomButtonBlueCircleArrow > div > div > div > div {
-	position: absolute;
-	top: 1px;
-	left: 6px;
-	width: 3px;
-	height: 8px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
+  position: absolute;
+  top: 1px;
+  left: 6px;
+  width: 3px;
+  height: 8px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow.less b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow.less
new file mode 100644
index 0000000..42433fb
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleArrow.less
@@ -0,0 +1,49 @@
+ at import "../css3.less";
+/* === Blue Circle Arrow Buttons ==*/
+.mblDomButtonBlueCircleArrow {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+
+.mblDomButtonBlueCircleArrow > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 22px;
+	height: 22px;
+	border: 1px solid #b5b6b5;
+	border-radius: 12px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonBlueCircleArrow > div > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 18px;
+	height: 18px;
+	border-radius: 9px;
+	.background-linear-gradient-top-bottom-2-stops(#6ba2e7, #216dd6, 0.5, #4282de, 0.5, #216dd6);
+}
+.mblDomButtonBlueCircleArrow > div > div > div {
+	position: absolute;
+	top: 5px;
+	left: 6px;
+	width: 8px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	border-style: none;
+	background: white;
+	.transform(rotate(45deg));
+}
+.mblDomButtonBlueCircleArrow > div > div > div > div {
+	position: absolute;
+	top: 1px;
+	left: 6px;
+	width: 3px;
+	height: 8px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus.css
index 24d24c7..29365dc 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus.css
@@ -1,37 +1,38 @@
 /* === Blue Circle Minus Buttons ==*/
 .mblDomButtonBlueCircleMinus {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
-
 .mblDomButtonBlueCircleMinus > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 22px;
-	height: 22px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 12px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 22px;
+  height: 22px;
+  border: 1px solid #b5b6b5;
+  border-radius: 12px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
 }
 .mblDomButtonBlueCircleMinus > div > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 18px;
-	height: 18px;
-	-webkit-border-radius: 9px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#6BA2E7), to(#216DD6), color-stop(0.5, #4282DE), color-stop(0.5, #216DD6));
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 18px;
+  height: 18px;
+  border-radius: 9px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#6ba2e7), to(#216dd6), color-stop(0.5, #4282de), color-stop(0.5, #216dd6));
+  background: linear-gradient(to bottom, #6ba2e7 0%, #4282de 50%, #216dd6 50%, #216dd6 100%);
 }
 .mblDomButtonBlueCircleMinus > div > div > div {
-	position: absolute;
-	top: 8px;
-	left: 3px;
-	width: 12px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	border-style: none;
-	background: white;
+  position: absolute;
+  top: 8px;
+  left: 3px;
+  width: 12px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  border-style: none;
+  background: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus.less b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus.less
new file mode 100644
index 0000000..53b444e
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCircleMinus.less
@@ -0,0 +1,38 @@
+ at import "../css3.less";
+/* === Blue Circle Minus Buttons ==*/
+.mblDomButtonBlueCircleMinus {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+
+.mblDomButtonBlueCircleMinus > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 22px;
+	height: 22px;
+	border: 1px solid #b5b6b5;
+	border-radius: 12px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonBlueCircleMinus > div > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 18px;
+	height: 18px;
+	border-radius: 9px;
+	.background-linear-gradient-top-bottom-2-stops(#6ba2e7, #216dd6, 0.5, #4282de, 0.5, #216dd6);
+}
+.mblDomButtonBlueCircleMinus > div > div > div {
+	position: absolute;
+	top: 8px;
+	left: 3px;
+	width: 12px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	border-style: none;
+	background: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus.css b/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus.css
index af1d6ad..be8f66c 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus.css
@@ -1,47 +1,48 @@
 /* === Blue Circle Plus Buttons ==*/
 .mblDomButtonBlueCirclePlus {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
-
 .mblDomButtonBlueCirclePlus > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 22px;
-	height: 22px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 12px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 22px;
+  height: 22px;
+  border: 1px solid #b5b6b5;
+  border-radius: 12px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
 }
 .mblDomButtonBlueCirclePlus > div > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 18px;
-	height: 18px;
-	-webkit-border-radius: 9px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#6BA2E7), to(#216DD6), color-stop(0.5, #4282DE), color-stop(0.5, #216DD6));
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 18px;
+  height: 18px;
+  border-radius: 9px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#6ba2e7), to(#216dd6), color-stop(0.5, #4282de), color-stop(0.5, #216dd6));
+  background: linear-gradient(to bottom, #6ba2e7 0%, #4282de 50%, #216dd6 50%, #216dd6 100%);
 }
 .mblDomButtonBlueCirclePlus > div > div > div {
-	position: absolute;
-	top: 8px;
-	left: 3px;
-	width: 13px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	border-style: none;
-	background: white;
+  position: absolute;
+  top: 8px;
+  left: 3px;
+  width: 13px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  border-style: none;
+  background: white;
 }
 .mblDomButtonBlueCirclePlus > div > div > div > div {
-	position: absolute;
-	top: -5px;
-	left: 5px;
-	width: 3px;
-	height: 13px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
+  position: absolute;
+  top: -5px;
+  left: 5px;
+  width: 3px;
+  height: 13px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus.less b/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus.less
new file mode 100644
index 0000000..d7e0cce
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonBlueCirclePlus.less
@@ -0,0 +1,48 @@
+ at import "../css3.less";
+/* === Blue Circle Plus Buttons ==*/
+.mblDomButtonBlueCirclePlus {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+
+.mblDomButtonBlueCirclePlus > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 22px;
+	height: 22px;
+	border: 1px solid #b5b6b5;
+	border-radius: 12px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonBlueCirclePlus > div > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 18px;
+	height: 18px;
+	border-radius: 9px;
+	.background-linear-gradient-top-bottom-2-stops(#6ba2e7, #216dd6, 0.5, #4282de, 0.5, #216dd6);
+}
+.mblDomButtonBlueCirclePlus > div > div > div {
+	position: absolute;
+	top: 8px;
+	left: 3px;
+	width: 13px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	border-style: none;
+	background: white;
+}
+.mblDomButtonBlueCirclePlus > div > div > div > div {
+	position: absolute;
+	top: -5px;
+	left: 5px;
+	width: 3px;
+	height: 13px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff.css b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff.css
index 66fdd9d..38de914 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff.css
@@ -1,40 +1,43 @@
 /* === Check Button (OFF) ==*/
 .mblDomButtonCheckboxOff {
-	position: relative;
-	width: 30px;
-	height: 30px;
-	border-width: 1px;
-	border-style: outset;
-	border-color: #A5A2A5;
-	color: white;
-	-webkit-border-radius: 3px;
-	background-color: #D6D3D6;
-	background: -webkit-gradient(linear, left top, left bottom, from(#EFF3EF), to(#BDBEBD));
+  position: relative;
+  width: 30px;
+  height: 30px;
+  border-width: 1px;
+  border-style: outset;
+  border-color: #a5a2a5;
+  color: white;
+  border-radius: 3px;
+  background-color: #d6d3d6;
+  background: -webkit-gradient(linear, left top, left bottom, from(#eff3ef), to(#bdbebd));
+  background: linear-gradient(to bottom, #eff3ef 0%, #bdbebd 100%);
 }
 .mblDomButtonCheckboxOff > div {
-	position: absolute;
-	top: 15px;
-	left: 3px;
-	width: 14px;
-	height: 4px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: #BDBABD;
-	border-bottom: 1px solid #8C8E8C;
-	-webkit-border-radius: 2px;
-	-webkit-transform: rotate(50deg);
+  position: absolute;
+  top: 15px;
+  left: 3px;
+  width: 14px;
+  height: 4px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #bdbabd;
+  border-bottom: 1px solid #8c8e8c;
+  border-radius: 2px;
+  -webkit-transform: rotate(50deg);
+  transform: rotate(50deg);
 }
 .mblDomButtonCheckboxOff > div > div {
-	position: absolute;
-	top: -10px;
-	left: 0px;
-	width: 20px;
-	height: 4px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: #BDBABD;
-	border-bottom: none;
-	border-top: 1px solid #8C8E8C;
-	-webkit-border-radius: 2px;
-	-webkit-transform: rotate(-100deg);
+  position: absolute;
+  top: -10px;
+  left: 0px;
+  width: 20px;
+  height: 4px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #bdbabd;
+  border-bottom: none;
+  border-top: 1px solid #8c8e8c;
+  border-radius: 2px;
+  -webkit-transform: rotate(-100deg);
+  transform: rotate(-100deg);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff.less b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff.less
new file mode 100644
index 0000000..7068e17
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOff.less
@@ -0,0 +1,41 @@
+ at import "../css3.less";
+/* === Check Button (OFF) ==*/
+.mblDomButtonCheckboxOff {
+	position: relative;
+	width: 30px;
+	height: 30px;
+	border-width: 1px;
+	border-style: outset;
+	border-color: #a5a2a5;
+	color: white;
+	border-radius: 3px;
+	background-color: #d6d3d6;
+	.background-linear-gradient-top-bottom(#eff3ef, #bdbebd);
+}
+.mblDomButtonCheckboxOff > div {
+	position: absolute;
+	top: 15px;
+	left: 3px;
+	width: 14px;
+	height: 4px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #bdbabd;
+	border-bottom: 1px solid #8c8e8c;
+	border-radius: 2px;
+	.transform(rotate(50deg));
+}
+.mblDomButtonCheckboxOff > div > div {
+	position: absolute;
+	top: -10px;
+	left: 0px;
+	width: 20px;
+	height: 4px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #bdbabd;
+	border-bottom: none;
+	border-top: 1px solid #8c8e8c;
+	border-radius: 2px;
+	.transform(rotate(-100deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn.css b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn.css
index 7c25a9e..0851f3c 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn.css
@@ -1,40 +1,43 @@
 /* === Check Button (ON) ==*/
 .mblDomButtonCheckboxOn {
-	position: relative;
-	width: 30px;
-	height: 30px;
-	border-width: 1px;
-	border-style: outset;
-	border-color: #A5A2A5;
-	color: white;
-	-webkit-border-radius: 3px;
-	background-color: #D6D3D6;
-	background: -webkit-gradient(linear, left top, left bottom, from(#EFF3EF), to(#BDBEBD));
+  position: relative;
+  width: 30px;
+  height: 30px;
+  border-width: 1px;
+  border-style: outset;
+  border-color: #a5a2a5;
+  color: white;
+  border-radius: 3px;
+  background-color: #d6d3d6;
+  background: -webkit-gradient(linear, left top, left bottom, from(#eff3ef), to(#bdbebd));
+  background: linear-gradient(to bottom, #eff3ef 0%, #bdbebd 100%);
 }
 .mblDomButtonCheckboxOn > div {
-	position: absolute;
-	top: 15px;
-	left: 3px;
-	width: 14px;
-	height: 4px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: #00CF00;
-	border-top: 1px solid #4A5A71;
-	-webkit-border-radius: 2px;
-	-webkit-transform: rotate(50deg);
+  position: absolute;
+  top: 15px;
+  left: 3px;
+  width: 14px;
+  height: 4px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #00cf00;
+  border-top: 1px solid #4a5a71;
+  border-radius: 2px;
+  -webkit-transform: rotate(50deg);
+  transform: rotate(50deg);
 }
 .mblDomButtonCheckboxOn > div > div {
-	position: absolute;
-	top: -10px;
-	left: 0px;
-	width: 20px;
-	height: 4px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: #00CF00;
-	border-top: none;
-	border-bottom: 1px solid #4A5A71;
-	-webkit-border-radius: 2px;
-	-webkit-transform: rotate(-100deg);
+  position: absolute;
+  top: -10px;
+  left: 0px;
+  width: 20px;
+  height: 4px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #00cf00;
+  border-top: none;
+  border-bottom: 1px solid #4a5a71;
+  border-radius: 2px;
+  -webkit-transform: rotate(-100deg);
+  transform: rotate(-100deg);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn.less b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn.less
new file mode 100644
index 0000000..581a035
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonCheckboxOn.less
@@ -0,0 +1,41 @@
+ at import "../css3.less";
+/* === Check Button (ON) ==*/
+.mblDomButtonCheckboxOn {
+	position: relative;
+	width: 30px;
+	height: 30px;
+	border-width: 1px;
+	border-style: outset;
+	border-color: #a5a2a5;
+	color: white;
+	border-radius: 3px;
+	background-color: #d6d3d6;
+	.background-linear-gradient-top-bottom(#eff3ef, #bdbebd);
+}
+.mblDomButtonCheckboxOn > div {
+	position: absolute;
+	top: 15px;
+	left: 3px;
+	width: 14px;
+	height: 4px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #00cf00;
+	border-top: 1px solid #4a5a71;
+	border-radius: 2px;
+	.transform(rotate(50deg));
+}
+.mblDomButtonCheckboxOn > div > div {
+	position: absolute;
+	top: -10px;
+	left: 0px;
+	width: 20px;
+	height: 4px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #00cf00;
+	border-top: none;
+	border-bottom: 1px solid #4a5a71;
+	border-radius: 2px;
+	.transform(rotate(-100deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonColorButtons.css b/dojox/mobile/themes/common/domButtons/DomButtonColorButtons.css
index 8017cf2..a355feb 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonColorButtons.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonColorButtons.css
@@ -1,55 +1,77 @@
 /* === Minus and Plus Buttons ==*/
-.mblDomButtonBlueMinus, .mblDomButtonBluePlus, .mblDomButtonDarkBlueMinus, .mblDomButtonDarkBluePlus, .mblDomButtonRedMinus, .mblDomButtonRedPlus {
-	position: relative;
-	width: 29px;
-	height: 29px;
+.mblDomButtonBlueMinus,
+.mblDomButtonBluePlus,
+.mblDomButtonDarkBlueMinus,
+.mblDomButtonDarkBluePlus,
+.mblDomButtonRedMinus,
+.mblDomButtonRedPlus {
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
-
-.mblDomButtonBlueMinus > div, .mblDomButtonBluePlus > div, .mblDomButtonDarkBlueMinus > div, .mblDomButtonDarkBluePlus > div, .mblDomButtonRedMinus > div, .mblDomButtonRedPlus > div {
-	position: relative;
-	top: 4px;
-	left: 3px;
-	width: 22px;
-	height: 18px;
-	border-width: 1px 1px 1px 0px;
-	border-style: outset;
-	color: white;
-	-webkit-border-radius: 3px;
+.mblDomButtonBlueMinus > div,
+.mblDomButtonBluePlus > div,
+.mblDomButtonDarkBlueMinus > div,
+.mblDomButtonDarkBluePlus > div,
+.mblDomButtonRedMinus > div,
+.mblDomButtonRedPlus > div {
+  position: relative;
+  top: 4px;
+  left: 3px;
+  width: 22px;
+  height: 18px;
+  border-width: 1px 1px 1px 0px;
+  border-style: outset;
+  color: white;
+  border-radius: 3px;
 }
-.mblDomButtonBlueMinus > div, .mblDomButtonBluePlus > div {
-	border-color: #6D89C7;
-	background-color: #366EDF;
-	background: -webkit-gradient(linear, left top, left bottom, from(#7A9DE9), to(#2362DD), color-stop(0.5, #366EDF), color-stop(0.5, #215FDC));
+.mblDomButtonBlueMinus > div,
+.mblDomButtonBluePlus > div {
+  border-color: #6d89c7;
+  background-color: #366edf;
+  background: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background: linear-gradient(to bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
 }
-.mblDomButtonDarkBlueMinus > div, .mblDomButtonDarkBluePlus > div {
-	border-color: #6D89C7;
-	background-color: #5877A2;
-	background: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
+.mblDomButtonDarkBlueMinus > div,
+.mblDomButtonDarkBluePlus > div {
+  border-color: #6d89c7;
+  background-color: #5877a2;
+  background: -webkit-gradient(linear, left top, left bottom, from(#8ea4c1), to(#4a6c9b), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
+  background: linear-gradient(to bottom, #8ea4c1 0%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
 }
-.mblDomButtonRedMinus > div, .mblDomButtonRedPlus > div {
-	border-color: #cc1122;
-	background-color: #C9404B;
-	background: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+.mblDomButtonRedMinus > div,
+.mblDomButtonRedPlus > div {
+  border-color: #cc1122;
+  background-color: #c9404b;
+  background: -webkit-gradient(linear, left top, left bottom, from(#d3656d), to(#bc1320), color-stop(0.5, #c9404b), color-stop(0.5, #bc1421));
+  background: linear-gradient(to bottom, #d3656d 0%, #c9404b 50%, #bc1421 50%, #bc1320 100%);
 }
-.mblDomButtonBlueMinus > div > div, .mblDomButtonBluePlus > div > div, .mblDomButtonDarkBlueMinus > div > div, .mblDomButtonDarkBluePlus > div > div, .mblDomButtonRedMinus > div > div, .mblDomButtonRedPlus > div > div {
-	position: absolute;
-	top: 7px;
-	left: 7px;
-	width: 8px;
-	height: 2px;
-	margin: 0px;
-	font-size: 1px;
-	border-style: none;
-	background: white;
-	border-top: 1px solid #4A5A71;
+.mblDomButtonBlueMinus > div > div,
+.mblDomButtonBluePlus > div > div,
+.mblDomButtonDarkBlueMinus > div > div,
+.mblDomButtonDarkBluePlus > div > div,
+.mblDomButtonRedMinus > div > div,
+.mblDomButtonRedPlus > div > div {
+  position: absolute;
+  top: 7px;
+  left: 7px;
+  width: 8px;
+  height: 2px;
+  margin: 0px;
+  font-size: 1px;
+  border-style: none;
+  background: white;
+  border-top: 1px solid #4a5a71;
 }
-.mblDomButtonBluePlus > div > div > div, .mblDomButtonDarkBluePlus > div > div > div, .mblDomButtonRedPlus > div > div > div {
-	position: absolute;
-	top: -3px;
-	left: 3px;
-	width: 2px;
-	height: 8px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
+.mblDomButtonBluePlus > div > div > div,
+.mblDomButtonDarkBluePlus > div > div > div,
+.mblDomButtonRedPlus > div > div > div {
+  position: absolute;
+  top: -3px;
+  left: 3px;
+  width: 2px;
+  height: 8px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonColorButtons.less b/dojox/mobile/themes/common/domButtons/DomButtonColorButtons.less
new file mode 100644
index 0000000..7d79233
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonColorButtons.less
@@ -0,0 +1,56 @@
+ at import "../css3.less";
+/* === Minus and Plus Buttons ==*/
+.mblDomButtonBlueMinus, .mblDomButtonBluePlus, .mblDomButtonDarkBlueMinus, .mblDomButtonDarkBluePlus, .mblDomButtonRedMinus, .mblDomButtonRedPlus {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+
+.mblDomButtonBlueMinus > div, .mblDomButtonBluePlus > div, .mblDomButtonDarkBlueMinus > div, .mblDomButtonDarkBluePlus > div, .mblDomButtonRedMinus > div, .mblDomButtonRedPlus > div {
+	position: relative;
+	top: 4px;
+	left: 3px;
+	width: 22px;
+	height: 18px;
+	border-width: 1px 1px 1px 0px;
+	border-style: outset;
+	color: white;
+	border-radius: 3px;
+}
+.mblDomButtonBlueMinus > div, .mblDomButtonBluePlus > div {
+	border-color: #6d89c7;
+	background-color: #366edf;
+	.background-linear-gradient-top-bottom-2-stops(#7a9de9, #2362dd, 0.5, #366edf, 0.5, #215fdc);
+}
+.mblDomButtonDarkBlueMinus > div, .mblDomButtonDarkBluePlus > div {
+	border-color: #6d89c7;
+	background-color: #5877a2;
+	.background-linear-gradient-top-bottom-2-stops(#8ea4c1, #4a6c9b, 0.5, #5877a2, 0.5, #476999);
+}
+.mblDomButtonRedMinus > div, .mblDomButtonRedPlus > div {
+	border-color: #cc1122;
+	background-color: #c9404b;
+	.background-linear-gradient-top-bottom-2-stops(#d3656d, #bc1320, 0.5, #c9404b, 0.5, #bc1421);
+}
+.mblDomButtonBlueMinus > div > div, .mblDomButtonBluePlus > div > div, .mblDomButtonDarkBlueMinus > div > div, .mblDomButtonDarkBluePlus > div > div, .mblDomButtonRedMinus > div > div, .mblDomButtonRedPlus > div > div {
+	position: absolute;
+	top: 7px;
+	left: 7px;
+	width: 8px;
+	height: 2px;
+	margin: 0px;
+	font-size: 1px;
+	border-style: none;
+	background: white;
+	border-top: 1px solid #4a5a71;
+}
+.mblDomButtonBluePlus > div > div > div, .mblDomButtonDarkBluePlus > div > div > div, .mblDomButtonRedPlus > div > div > div {
+	position: absolute;
+	top: -3px;
+	left: 3px;
+	width: 2px;
+	height: 8px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck.css b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck.css
index 6edc2b2..0978346 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck.css
@@ -1,18 +1,21 @@
 /* === Check Button ==*/
-.mblDomButtonDarkBlueCheck, .mblDomButtonCheck {
-	position: relative;
-	width: 20px;
-	height: 29px;
+.mblDomButtonDarkBlueCheck,
+.mblDomButtonCheck {
+  position: relative;
+  width: 20px;
+  height: 29px;
 }
-.mblDomButtonDarkBlueCheck > div, .mblDomButtonCheck > div {
-	position: absolute;
-	left: 0px;
-	top: 8px;
-	width: 16px;
-	height: 6px;
-	font-size: 1px;
-	-webkit-transform: scaleX(0.7) rotate(135deg);
-	border-width: 3px 4px 0px 0px;
-	border-style: solid;
-	border-color: #314E84;
+.mblDomButtonDarkBlueCheck > div,
+.mblDomButtonCheck > div {
+  position: absolute;
+  left: 0px;
+  top: 8px;
+  width: 16px;
+  height: 6px;
+  font-size: 1px;
+  -webkit-transform: scaleX(0.7) rotate(135deg);
+  transform: scaleX(0.7) rotate(135deg);
+  border-width: 3px 4px 0px 0px;
+  border-style: solid;
+  border-color: #314e84;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck.less b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck.less
new file mode 100644
index 0000000..35b6abb
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck.less
@@ -0,0 +1,19 @@
+ at import "../css3.less";
+/* === Check Button ==*/
+.mblDomButtonDarkBlueCheck, .mblDomButtonCheck {
+	position: relative;
+	width: 20px;
+	height: 29px;
+}
+.mblDomButtonDarkBlueCheck > div, .mblDomButtonCheck > div {
+	position: absolute;
+	left: 0px;
+	top: 8px;
+	width: 16px;
+	height: 6px;
+	font-size: 1px;
+	.transform(scaleX(0.7) rotate(135deg));
+	border-width: 3px 4px 0px 0px;
+	border-style: solid;
+	border-color: #314e84;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck_rtl.css b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck_rtl.css
new file mode 100644
index 0000000..3b27fe2
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck_rtl.css
@@ -0,0 +1,8 @@
+/* === Check Button Rtl ==*/
+.mblListItemRtl .mblDomButtonDarkBlueCheck > div,
+.mblListItemRtl .mblDomButtonCheck > div {
+  right: 0px;
+  -webkit-transform: scaleX(-0.7) rotate(-135deg);
+  transform: scaleX(-0.7) rotate(-135deg);
+  border-width: 3px 0px 0px 4px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck_rtl.less b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck_rtl.less
new file mode 100644
index 0000000..6a73971
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonDarkBlueCheck_rtl.less
@@ -0,0 +1,8 @@
+ at import "../css3.less";
+/* === Check Button Rtl ==*/
+.mblListItemRtl .mblDomButtonDarkBlueCheck > div,
+.mblListItemRtl .mblDomButtonCheck > div {
+	right: 0px;
+	.transform(scaleX(-0.7) rotate(-135deg));
+	border-width: 3px 0px 0px 4px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow.css
index bfad471..8fe3981 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow.css
@@ -1,18 +1,21 @@
 /* === Arrow ==*/
-.mblDomButtonGrayArrow, .mblDomButtonArrow {
-	position: relative;
-	width: 20px;
-	height: 29px;
+.mblDomButtonGrayArrow,
+.mblDomButtonArrow {
+  position: relative;
+  width: 20px;
+  height: 29px;
 }
-.mblDomButtonGrayArrow > div, .mblDomButtonArrow > div {
-	position: absolute;
-	top: 10px;
-	left: 6px;
-	width: 6px;
-	height: 6px;
-	font-size: 1px;
-	-webkit-transform: rotate(45deg);
-	border-width: 3px 3px 0px 0px;
-	border-style: solid;
-	border-color: #808080;
+.mblDomButtonGrayArrow > div,
+.mblDomButtonArrow > div {
+  position: absolute;
+  top: 10px;
+  left: 6px;
+  width: 6px;
+  height: 6px;
+  font-size: 1px;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  border-width: 3px 3px 0px 0px;
+  border-style: solid;
+  border-color: #808080;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow.less b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow.less
new file mode 100644
index 0000000..6b01e4b
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow.less
@@ -0,0 +1,19 @@
+ at import "../css3.less";
+/* === Arrow ==*/
+.mblDomButtonGrayArrow, .mblDomButtonArrow {
+	position: relative;
+	width: 20px;
+	height: 29px;
+}
+.mblDomButtonGrayArrow > div, .mblDomButtonArrow > div {
+	position: absolute;
+	top: 10px;
+	left: 6px;
+	width: 6px;
+	height: 6px;
+	font-size: 1px;
+	.transform(rotate(45deg));
+	border-width: 3px 3px 0px 0px;
+	border-style: solid;
+	border-color: #808080;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow_rtl-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow_rtl-compat.css
new file mode 100644
index 0000000..7db3f63
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow_rtl-compat.css
@@ -0,0 +1,6 @@
+/* === Arrow Button Rtl ==*/
+.mblListItemRtl .mblDomButtonGrayArrow, 
+.mblListItemRtl .mblDomButtonArrow {
+	background-image: url(compat/mblDomButtonGrayArrow_rtl.png);
+	background-repeat: no-repeat;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow_rtl.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow_rtl.css
new file mode 100644
index 0000000..eec14c3
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow_rtl.css
@@ -0,0 +1,8 @@
+/* === Arrow Rtl ==*/
+.mblListItemRtl .mblDomButtonGrayArrow > div,
+.mblListItemRtl .mblDomButtonArrow > div {
+  right: 6px;
+  -webkit-transform: rotate(-45deg);
+  transform: rotate(-45deg);
+  border-width: 3px 0px 0px 3px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow_rtl.less b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow_rtl.less
new file mode 100644
index 0000000..534b75a
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayArrow_rtl.less
@@ -0,0 +1,8 @@
+ at import "../css3.less";
+/* === Arrow Rtl ==*/
+.mblListItemRtl .mblDomButtonGrayArrow > div,
+.mblListItemRtl .mblDomButtonArrow > div {
+	right: 6px;
+	.transform(rotate(-45deg));
+	border-width: 3px 0px 0px 3px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayCross-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayCross-compat.css
new file mode 100644
index 0000000..dffcc92
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayCross-compat.css
@@ -0,0 +1,8 @@
+/* === Gray Cross Button ==*/
+.mblDomButtonGrayCross, .mblDomButtonCross {
+	background-image: url(compat/mblDomButtonGrayCross.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonGrayCross div, .mblDomButtonCross div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayCross.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayCross.css
new file mode 100644
index 0000000..276f0cb
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayCross.css
@@ -0,0 +1,33 @@
+/* === Gray Cross Button ==*/
+.mblDomButtonGrayCross {
+  position: relative;
+  width: 29px;
+  height: 29px;
+}
+.mblDomButtonGrayCross > div {
+  position: absolute;
+  top: 12px;
+  left: 7px;
+  width: 14px;
+  height: 2px;
+  margin: 0px;
+  font-size: 1px;
+  border: 1px solid #0d1721;
+  background-color: #6c6e6d;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  -moz-transform: rotate(45deg);
+  border-radius: 2px;
+}
+.mblDomButtonGrayCross > div > div {
+  position: absolute;
+  top: -7px;
+  left: 5px;
+  width: 2px;
+  height: 14px;
+  margin: 0px;
+  font-size: 1px;
+  border: 1px solid #0d1721;
+  background-color: #6c6e6d;
+  border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayCross.less b/dojox/mobile/themes/common/domButtons/DomButtonGrayCross.less
new file mode 100644
index 0000000..d5e961e
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayCross.less
@@ -0,0 +1,33 @@
+ at import "../css3.less";
+/* === Gray Cross Button ==*/
+.mblDomButtonGrayCross {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonGrayCross > div {
+	position: absolute;
+	top: 12px;
+	left: 7px;
+	width: 14px;
+	height: 2px;
+	margin: 0px;
+	font-size: 1px;
+	border: 1px solid #0d1721;
+	background-color: #6c6e6d;
+	.transform(rotate(45deg));
+	-moz-transform: rotate(45deg);
+	border-radius: 2px;
+}
+.mblDomButtonGrayCross > div > div {
+	position: absolute;
+	top: -7px;
+	left: 5px;
+	width: 2px;
+	height: 14px;
+	margin: 0px;
+	font-size: 1px;
+	border: 1px solid #0d1721;
+	background-color: #6c6e6d;
+	border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayKnob-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayKnob-compat.css
new file mode 100644
index 0000000..33c18bb
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayKnob-compat.css
@@ -0,0 +1,9 @@
+/* === Gray Knob Button ==*/
+.mblDomButtonGrayKnob {
+	background-image: url(compat/mblDomButtonGrayKnob.png);
+	background-repeat: no-repeat;
+}
+
+.mblDomButtonGrayKnob > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayKnob.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayKnob.css
new file mode 100644
index 0000000..6d5ca42
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayKnob.css
@@ -0,0 +1,45 @@
+/* === Gray Knob Button ==*/
+.mblDomButtonGrayKnob {
+  position: relative;
+  width: 29px;
+  height: 29px;
+}
+.mblDomButtonGrayKnob > div {
+  /* horiz line 1 */
+
+  position: absolute;
+  top: 6px;
+  left: 2px;
+  width: 23px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #cecfce;
+  border-width: 1px 1px 0 0;
+  border-style: solid;
+  border-color: #9c9e9c;
+}
+.mblDomButtonGrayKnob > div > div {
+  /* horiz line 2 */
+
+  position: absolute;
+  top: 6px;
+  width: 23px;
+  height: 3px;
+  background-color: #cecfce;
+  border-width: 1px 1px 0 0;
+  border-style: solid;
+  border-color: #9c9e9c;
+}
+.mblDomButtonGrayKnob > div > div > div {
+  /* horiz line 3 */
+
+  position: absolute;
+  top: 6px;
+  width: 23px;
+  height: 3px;
+  background-color: #cecfce;
+  border-width: 1px 1px 0 0;
+  border-style: solid;
+  border-color: #9c9e9c;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayKnob.less b/dojox/mobile/themes/common/domButtons/DomButtonGrayKnob.less
new file mode 100644
index 0000000..a6ce9e0
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayKnob.less
@@ -0,0 +1,40 @@
+ at import "../css3.less";
+/* === Gray Knob Button ==*/
+.mblDomButtonGrayKnob {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonGrayKnob > div { /* horiz line 1 */
+	position: absolute;
+	top: 6px;
+	left: 2px;
+	width: 23px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #cecfce;
+	border-width: 1px 1px 0 0;
+	border-style: solid;
+	border-color: #9c9e9c;
+}
+.mblDomButtonGrayKnob > div > div { /* horiz line 2 */
+	position: absolute;
+	top: 6px;
+	width: 23px;
+	height: 3px;
+	background-color: #cecfce;
+	border-width: 1px 1px 0 0;
+	border-style: solid;
+	border-color: #9c9e9c;
+}
+.mblDomButtonGrayKnob > div > div > div { /* horiz line 3 */
+	position: absolute;
+	top: 6px;
+	width: 23px;
+	height: 3px;
+	background-color: #cecfce;
+	border-width: 1px 1px 0 0;
+	border-style: solid;
+	border-color: #9c9e9c;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayMinus-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayMinus-compat.css
new file mode 100644
index 0000000..2f522c0
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayMinus-compat.css
@@ -0,0 +1,8 @@
+/* === Minus Button ==*/
+.mblDomButtonGrayMinus {
+	background-image: url(compat/mblDomButtonGrayMinus.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonGrayMinus div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayMinus.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayMinus.css
new file mode 100644
index 0000000..c916a93
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayMinus.css
@@ -0,0 +1,20 @@
+/* === Minus Button ==*/
+.mblDomButtonGrayMinus {
+  position: relative;
+  width: 29px;
+  height: 29px;
+}
+.mblDomButtonGrayMinus > div {
+  /* horiz line */
+
+  position: absolute;
+  top: 12px;
+  left: 6px;
+  width: 18px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #848684;
+  border-top: 1px solid #525152;
+  border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayMinus.less b/dojox/mobile/themes/common/domButtons/DomButtonGrayMinus.less
new file mode 100644
index 0000000..fe923ba
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayMinus.less
@@ -0,0 +1,19 @@
+ at import "../css3.less";
+/* === Minus Button ==*/
+.mblDomButtonGrayMinus {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonGrayMinus > div { /* horiz line */
+	position: absolute;
+	top: 12px;
+	left: 6px;
+	width: 18px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #848684;
+	border-top: 1px solid #525152;
+	border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayPlus-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayPlus-compat.css
new file mode 100644
index 0000000..29a998f
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayPlus-compat.css
@@ -0,0 +1,8 @@
+/* === Plus Button ==*/
+.mblDomButtonGrayPlus {
+	background-image: url(compat/mblDomButtonGrayPlus.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonGrayPlus div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayPlus.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayPlus.css
new file mode 100644
index 0000000..dde419c
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayPlus.css
@@ -0,0 +1,35 @@
+/* === Plus Button ==*/
+.mblDomButtonGrayPlus {
+  position: relative;
+  width: 29px;
+  height: 29px;
+}
+.mblDomButtonGrayPlus > div {
+  /* horiz line */
+
+  position: absolute;
+  top: 12px;
+  left: 6px;
+  width: 18px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #848684;
+  border-top: 1px solid #525152;
+  border-radius: 2px;
+}
+.mblDomButtonGrayPlus > div > div {
+  /* vert line */
+
+  position: absolute;
+  top: -8px;
+  left: 7px;
+  width: 3px;
+  height: 17px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #848684;
+  border-top: 1px solid #525152;
+  border-left: 1px solid #808080;
+  border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayPlus.less b/dojox/mobile/themes/common/domButtons/DomButtonGrayPlus.less
new file mode 100644
index 0000000..57672e6
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayPlus.less
@@ -0,0 +1,32 @@
+ at import "../css3.less";
+/* === Plus Button ==*/
+.mblDomButtonGrayPlus {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonGrayPlus > div { /* horiz line */
+	position: absolute;
+	top: 12px;
+	left: 6px;
+	width: 18px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #848684;
+	border-top: 1px solid #525152;
+	border-radius: 2px;
+}
+.mblDomButtonGrayPlus > div > div { /* vert line */
+	position: absolute;
+	top: -8px;
+	left: 7px;
+	width: 3px;
+	height: 17px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #848684;
+	border-top: 1px solid #525152;
+	border-left: 1px solid #808080;
+	border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect.css
index 5ceb481..51bb0c4 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect.css
@@ -1,23 +1,23 @@
 /* === Gray Round Rectangle Button ==*/
 .mblDomButtonGrayRoundRect {
-	position: relative;
-	width: 29px;
-	height: 29px;
-	text-align: right;
+  position: relative;
+  width: 29px;
+  height: 29px;
+  text-align: right;
 }
 .mblDomButtonGrayRoundRect > div {
-	position: absolute;
-	right: 0px;
-	display: inline;
-	padding: 0px 5px;
-	top: 7px;
-	color: white;
-	font-family: Helvetica;
-	font-size: 12px;
-	-webkit-border-radius: 4px;
-	background-color: #949BA5;
-	text-align: center;
+  position: absolute;
+  right: 0px;
+  display: inline;
+  padding: 0px 5px;
+  top: 7px;
+  color: white;
+  font-family: Helvetica;
+  font-size: 12px;
+  border-radius: 4px;
+  background-color: #949ba5;
+  text-align: center;
 }
 .mblDomButtonGrayRoundRect > div > div {
-	display: none;
+  display: none;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect.less b/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect.less
new file mode 100644
index 0000000..fb88f57
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayRoundRect.less
@@ -0,0 +1,24 @@
+ at import "../css3.less";
+/* === Gray Round Rectangle Button ==*/
+.mblDomButtonGrayRoundRect {
+	position: relative;
+	width: 29px;
+	height: 29px;
+	text-align: right;
+}
+.mblDomButtonGrayRoundRect > div {
+	position: absolute;
+	right: 0px;
+	display: inline;
+	padding: 0px 5px;
+	top: 7px;
+	color: white;
+	font-family: Helvetica;
+	font-size: 12px;
+	border-radius: 4px;
+	background-color: #949ba5;
+	text-align: center;
+}
+.mblDomButtonGrayRoundRect > div > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayStar.css b/dojox/mobile/themes/common/domButtons/DomButtonGrayStar.css
index 605de2c..b5a8113 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonGrayStar.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayStar.css
@@ -1,49 +1,52 @@
 /* === Gray Star ==*/
 .mblDomButtonGrayStar {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
 .mblDomButtonGrayStar > div {
-	position: absolute;
-	width: 0px;
-	height: 0px;
-	border-style: solid;
-	border-color: #BDBABD transparent transparent transparent;
-	top: 12px;
-	left: 3px;
-	border-width: 9px 12px 0px 12px;
-	-webkit-transform: rotate(0deg);
+  position: absolute;
+  width: 0px;
+  height: 0px;
+  border-style: solid;
+  border-color: #bdbabd transparent transparent transparent;
+  top: 12px;
+  left: 3px;
+  border-width: 9px 12px 0px 12px;
+  -webkit-transform: rotate(0deg);
+  transform: rotate(0deg);
 }
 .mblDomButtonGrayStar > div > div {
-	position: absolute;
-	width: 24px;
-	height: 0px;
-	border-style: solid;
-	border-color: #8C8E8C;
-	border-width: 1px 0px 0px 0px;
-	top: -10px;
-	left: -12px;
+  position: absolute;
+  width: 24px;
+  height: 0px;
+  border-style: solid;
+  border-color: #8c8e8c;
+  border-width: 1px 0px 0px 0px;
+  top: -10px;
+  left: -12px;
 }
 .mblDomButtonGrayStar > div > div > div {
-	position: absolute;
-	width: 0px;
-	height: 0px;
-	border-style: solid;
-	border-color: #BDBABD transparent transparent transparent;
-	top: 0px;
-	left: 0px;
-	border-width: 9px 12px 0px 12px;
-	-webkit-transform: rotate(72deg);
+  position: absolute;
+  width: 0px;
+  height: 0px;
+  border-style: solid;
+  border-color: #bdbabd transparent transparent transparent;
+  top: 0px;
+  left: 0px;
+  border-width: 9px 12px 0px 12px;
+  -webkit-transform: rotate(72deg);
+  transform: rotate(72deg);
 }
 .mblDomButtonGrayStar > div > div > div > div {
-	position: absolute;
-	width: 0px;
-	height: 0px;
-	border-style: solid;
-	border-color: #BDBABD transparent transparent transparent;
-	top: -10px;
-	left: -12px;
-	border-width: 9px 12px 0px 12px;
-	-webkit-transform: rotate(216deg);
+  position: absolute;
+  width: 0px;
+  height: 0px;
+  border-style: solid;
+  border-color: #bdbabd transparent transparent transparent;
+  top: -10px;
+  left: -12px;
+  border-width: 9px 12px 0px 12px;
+  -webkit-transform: rotate(216deg);
+  transform: rotate(216deg);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGrayStar.less b/dojox/mobile/themes/common/domButtons/DomButtonGrayStar.less
new file mode 100644
index 0000000..258d801
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGrayStar.less
@@ -0,0 +1,50 @@
+ at import "../css3.less";
+/* === Gray Star ==*/
+.mblDomButtonGrayStar {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonGrayStar > div {
+	position: absolute;
+	width: 0px;
+	height: 0px;
+	border-style: solid;
+	border-color: #bdbabd transparent transparent transparent;
+	top: 12px;
+	left: 3px;
+	border-width: 9px 12px 0px 12px;
+	.transform(rotate(0deg));
+}
+.mblDomButtonGrayStar > div > div {
+	position: absolute;
+	width: 24px;
+	height: 0px;
+	border-style: solid;
+	border-color: #8c8e8c;
+	border-width: 1px 0px 0px 0px;
+	top: -10px;
+	left: -12px;
+}
+.mblDomButtonGrayStar > div > div > div {
+	position: absolute;
+	width: 0px;
+	height: 0px;
+	border-style: solid;
+	border-color: #bdbabd transparent transparent transparent;
+	top: 0px;
+	left: 0px;
+	border-width: 9px 12px 0px 12px;
+	.transform(rotate(72deg));
+}
+.mblDomButtonGrayStar > div > div > div > div {
+	position: absolute;
+	width: 0px;
+	height: 0px;
+	border-style: solid;
+	border-color: #bdbabd transparent transparent transparent;
+	top: -10px;
+	left: -12px;
+	border-width: 9px 12px 0px 12px;
+	.transform(rotate(216deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenBadge-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenBadge-compat.css
new file mode 100644
index 0000000..7f2d90b
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenBadge-compat.css
@@ -0,0 +1,6 @@
+/* === Green Badge ==*/
+.mblDomButtonGreenBadge > div {
+	-moz-border-radius: 12px;
+	background-color: #6bc642;
+	background-image: -moz-linear-gradient(top, #7be75a 0%, #6bc642 50%, #4aad21 50%, #398c08 100%);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenBadge.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenBadge.css
new file mode 100644
index 0000000..33fc4fe
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenBadge.css
@@ -0,0 +1,29 @@
+/* === Green Badge ==*/
+.mblDomButtonGreenBadge {
+  position: relative;
+  width: 29px;
+  height: 29px;
+  text-align: right;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+}
+.mblDomButtonGreenBadge > div {
+  position: absolute;
+  display: inline;
+  padding: 0px 5px;
+  top: 2px;
+  right: 2px;
+  color: white;
+  border: 2px solid white;
+  border-radius: 12px;
+  text-align: center;
+  background: -webkit-gradient(linear, left top, left bottom, from(#7be75a), to(#398c08), color-stop(0.5, #6bc642), color-stop(0.5, #4aad21));
+  background: linear-gradient(to bottom, #7be75a 0%, #6bc642 50%, #4aad21 50%, #398c08 100%);
+  background-clip: padding-box;
+  -webkit-box-shadow: 2px 3px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 2px 3px 2px rgba(0, 0, 0, 0.5);
+}
+.mblDomButtonGreenBadge > div > div {
+  display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenBadge.less b/dojox/mobile/themes/common/domButtons/DomButtonGreenBadge.less
new file mode 100644
index 0000000..6a6207c
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenBadge.less
@@ -0,0 +1,28 @@
+ at import "../css3.less";
+/* === Green Badge ==*/
+.mblDomButtonGreenBadge {
+	position: relative;
+	width: 29px;
+	height: 29px;
+	text-align: right;
+	font-family: Helvetica;
+	font-size: 16px;
+	font-weight: bold;
+}
+.mblDomButtonGreenBadge > div {
+	position: absolute;
+	display: inline;
+	padding: 0px 5px;
+	top: 2px;
+	right: 2px;
+	color: white;
+	border: 2px solid white;
+	border-radius: 12px;
+	text-align: center;
+	.background-linear-gradient-top-bottom-2-stops(#7be75a, #398c08, 0.5, #6bc642, 0.5, #4aad21);
+	background-clip: padding-box;
+	.box-shadow(2px 3px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonGreenBadge > div > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenBall.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenBall.css
index f7e928f..bb447ac 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonGreenBall.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenBall.css
@@ -1,15 +1,16 @@
 /* === Green Ball Button ==*/
 .mblDomButtonGreenBall {
-	position: relative;
-	width: 19px;
-	height: 29px;
+  position: relative;
+  width: 19px;
+  height: 29px;
 }
 .mblDomButtonGreenBall > div {
-	position: relative;
-	top: 8px;
-	left: 4px;
-	width: 14px;
-	height: 14px;
-	-webkit-border-radius: 7px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#59E738), to(#0AA908));
+  position: relative;
+  top: 8px;
+  left: 4px;
+  width: 14px;
+  height: 14px;
+  border-radius: 7px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#59e738), to(#0aa908));
+  background: linear-gradient(to bottom, #59e738 0%, #0aa908 100%);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenBall.less b/dojox/mobile/themes/common/domButtons/DomButtonGreenBall.less
new file mode 100644
index 0000000..67b9285
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenBall.less
@@ -0,0 +1,16 @@
+ at import "../css3.less";
+/* === Green Ball Button ==*/
+.mblDomButtonGreenBall {
+	position: relative;
+	width: 19px;
+	height: 29px;
+}
+.mblDomButtonGreenBall > div {
+	position: relative;
+	top: 8px;
+	left: 4px;
+	width: 14px;
+	height: 14px;
+	border-radius: 7px;
+	.background-linear-gradient-top-bottom(#59e738, #0aa908);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow.css
index 53e6523..11b037e 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow.css
@@ -1,48 +1,50 @@
 /* === Green Circle Arrow Buttons ==*/
 .mblDomButtonGreenCircleArrow {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
-
 .mblDomButtonGreenCircleArrow > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 22px;
-	height: 22px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 12px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 22px;
+  height: 22px;
+  border: 1px solid #b5b6b5;
+  border-radius: 12px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
 }
 .mblDomButtonGreenCircleArrow > div > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 18px;
-	height: 18px;
-	-webkit-border-radius: 9px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#7BE75A), to(#398C08), color-stop(0.5, #6BC642), color-stop(0.5, #4AAD21));
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 18px;
+  height: 18px;
+  border-radius: 9px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#7be75a), to(#398c08), color-stop(0.5, #6bc642), color-stop(0.5, #4aad21));
+  background: linear-gradient(to bottom, #7be75a 0%, #6bc642 50%, #4aad21 50%, #398c08 100%);
 }
 .mblDomButtonGreenCircleArrow > div > div > div {
-	position: absolute;
-	top: 5px;
-	left: 6px;
-	width: 8px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	border-style: none;
-	background: white;
-	-webkit-transform: rotate(45deg);
+  position: absolute;
+  top: 5px;
+  left: 6px;
+  width: 8px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  border-style: none;
+  background: white;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
 }
 .mblDomButtonGreenCircleArrow > div > div > div > div {
-	position: absolute;
-	top: 1px;
-	left: 6px;
-	width: 3px;
-	height: 8px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
+  position: absolute;
+  top: 1px;
+  left: 6px;
+  width: 3px;
+  height: 8px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow.less b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow.less
new file mode 100644
index 0000000..e27ae46
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleArrow.less
@@ -0,0 +1,49 @@
+ at import "../css3.less";
+/* === Green Circle Arrow Buttons ==*/
+.mblDomButtonGreenCircleArrow {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+
+.mblDomButtonGreenCircleArrow > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 22px;
+	height: 22px;
+	border: 1px solid #b5b6b5;
+	border-radius: 12px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonGreenCircleArrow > div > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 18px;
+	height: 18px;
+	border-radius: 9px;
+	.background-linear-gradient-top-bottom-2-stops(#7be75a, #398c08, 0.5, #6bc642, 0.5, #4aad21);
+}
+.mblDomButtonGreenCircleArrow > div > div > div {
+	position: absolute;
+	top: 5px;
+	left: 6px;
+	width: 8px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	border-style: none;
+	background: white;
+	.transform(rotate(45deg));
+}
+.mblDomButtonGreenCircleArrow > div > div > div > div {
+	position: absolute;
+	top: 1px;
+	left: 6px;
+	width: 3px;
+	height: 8px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus.css
index b406543..9c5f26e 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus.css
@@ -1,37 +1,38 @@
 /* === Green Circle Minus Buttons ==*/
 .mblDomButtonGreenCircleMinus {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
-
 .mblDomButtonGreenCircleMinus > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 22px;
-	height: 22px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 12px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 22px;
+  height: 22px;
+  border: 1px solid #b5b6b5;
+  border-radius: 12px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
 }
 .mblDomButtonGreenCircleMinus > div > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 18px;
-	height: 18px;
-	-webkit-border-radius: 9px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#7BE75A), to(#398C08), color-stop(0.5, #6BC642), color-stop(0.5, #4AAD21));
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 18px;
+  height: 18px;
+  border-radius: 9px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#7be75a), to(#398c08), color-stop(0.5, #6bc642), color-stop(0.5, #4aad21));
+  background: linear-gradient(to bottom, #7be75a 0%, #6bc642 50%, #4aad21 50%, #398c08 100%);
 }
 .mblDomButtonGreenCircleMinus > div > div > div {
-	position: absolute;
-	top: 8px;
-	left: 3px;
-	width: 12px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	border-style: none;
-	background: white;
+  position: absolute;
+  top: 8px;
+  left: 3px;
+  width: 12px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  border-style: none;
+  background: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus.less b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus.less
new file mode 100644
index 0000000..2d0fd02
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCircleMinus.less
@@ -0,0 +1,38 @@
+ at import "../css3.less";
+/* === Green Circle Minus Buttons ==*/
+.mblDomButtonGreenCircleMinus {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+
+.mblDomButtonGreenCircleMinus > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 22px;
+	height: 22px;
+	border: 1px solid #b5b6b5;
+	border-radius: 12px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonGreenCircleMinus > div > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 18px;
+	height: 18px;
+	border-radius: 9px;
+	.background-linear-gradient-top-bottom-2-stops(#7be75a, #398c08, 0.5, #6bc642, 0.5, #4aad21);
+}
+.mblDomButtonGreenCircleMinus > div > div > div {
+	position: absolute;
+	top: 8px;
+	left: 3px;
+	width: 12px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	border-style: none;
+	background: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus.css b/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus.css
index 148dfa4..9361df1 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus.css
@@ -1,47 +1,48 @@
 /* === Green Circle Plus Buttons ==*/
 .mblDomButtonGreenCirclePlus {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
-
 .mblDomButtonGreenCirclePlus > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 22px;
-	height: 22px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 12px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 22px;
+  height: 22px;
+  border: 1px solid #b5b6b5;
+  border-radius: 12px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
 }
 .mblDomButtonGreenCirclePlus > div > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 18px;
-	height: 18px;
-	-webkit-border-radius: 9px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#7BE75A), to(#398C08), color-stop(0.5, #6BC642), color-stop(0.5, #4AAD21));
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 18px;
+  height: 18px;
+  border-radius: 9px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#7be75a), to(#398c08), color-stop(0.5, #6bc642), color-stop(0.5, #4aad21));
+  background: linear-gradient(to bottom, #7be75a 0%, #6bc642 50%, #4aad21 50%, #398c08 100%);
 }
 .mblDomButtonGreenCirclePlus > div > div > div {
-	position: absolute;
-	top: 8px;
-	left: 3px;
-	width: 13px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	border-style: none;
-	background: white;
+  position: absolute;
+  top: 8px;
+  left: 3px;
+  width: 13px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  border-style: none;
+  background: white;
 }
 .mblDomButtonGreenCirclePlus > div > div > div > div {
-	position: absolute;
-	top: -5px;
-	left: 5px;
-	width: 3px;
-	height: 13px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
+  position: absolute;
+  top: -5px;
+  left: 5px;
+  width: 3px;
+  height: 13px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus.less b/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus.less
new file mode 100644
index 0000000..8e9f8d7
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonGreenCirclePlus.less
@@ -0,0 +1,48 @@
+ at import "../css3.less";
+/* === Green Circle Plus Buttons ==*/
+.mblDomButtonGreenCirclePlus {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+
+.mblDomButtonGreenCirclePlus > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 22px;
+	height: 22px;
+	border: 1px solid #b5b6b5;
+	border-radius: 12px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonGreenCirclePlus > div > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 18px;
+	height: 18px;
+	border-radius: 9px;
+	.background-linear-gradient-top-bottom-2-stops(#7be75a, #398c08, 0.5, #6bc642, 0.5, #4aad21);
+}
+.mblDomButtonGreenCirclePlus > div > div > div {
+	position: absolute;
+	top: 8px;
+	left: 3px;
+	width: 13px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	border-style: none;
+	background: white;
+}
+.mblDomButtonGreenCirclePlus > div > div > div > div {
+	position: absolute;
+	top: -5px;
+	left: 5px;
+	width: 3px;
+	height: 13px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall.css b/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall.css
index 32b8659..84f7249 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall.css
@@ -1,15 +1,16 @@
 /* === Orange Ball Button ==*/
 .mblDomButtonOrangeBall {
-	position: relative;
-	width: 19px;
-	height: 29px;
+  position: relative;
+  width: 19px;
+  height: 29px;
 }
 .mblDomButtonOrangeBall > div {
-	position: relative;
-	top: 8px;
-	left: 4px;
-	width: 14px;
-	height: 14px;
-	-webkit-border-radius: 7px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#F9E20A), to(#FF6B0A));
+  position: relative;
+  top: 8px;
+  left: 4px;
+  width: 14px;
+  height: 14px;
+  border-radius: 7px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#f9e20a), to(#ff6b0a));
+  background: linear-gradient(to bottom, #f9e20a 0%, #ff6b0a 100%);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall.less b/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall.less
new file mode 100644
index 0000000..4fa8b71
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonOrangeBall.less
@@ -0,0 +1,16 @@
+ at import "../css3.less";
+/* === Orange Ball Button ==*/
+.mblDomButtonOrangeBall {
+	position: relative;
+	width: 19px;
+	height: 29px;
+}
+.mblDomButtonOrangeBall > div {
+	position: relative;
+	top: 8px;
+	left: 4px;
+	width: 14px;
+	height: 14px;
+	border-radius: 7px;
+	.background-linear-gradient-top-bottom(#f9e20a, #ff6b0a);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedBadge-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonRedBadge-compat.css
new file mode 100644
index 0000000..c5fed99
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedBadge-compat.css
@@ -0,0 +1,6 @@
+/* === Red Badge ==*/
+.mblDomButtonRedBadge > div {
+	-moz-border-radius: 12px;
+	background-color: #e44149;
+	background-image: -moz-linear-gradient(top, #f5bdc0 0%, #e44149 50%, #de151f 50%, #ae0001 100%);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedBadge.css b/dojox/mobile/themes/common/domButtons/DomButtonRedBadge.css
new file mode 100644
index 0000000..a00db52
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedBadge.css
@@ -0,0 +1,29 @@
+/* === Red Badge ==*/
+.mblDomButtonRedBadge {
+  position: relative;
+  width: 29px;
+  height: 29px;
+  text-align: right;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+}
+.mblDomButtonRedBadge > div {
+  position: absolute;
+  display: inline;
+  padding: 0px 5px;
+  top: 2px;
+  right: 2px;
+  color: white;
+  border: 2px solid white;
+  border-radius: 12px;
+  text-align: center;
+  background: -webkit-gradient(linear, left top, left bottom, from(#f5bdc0), to(#ae0001), color-stop(0.5, #e44149), color-stop(0.5, #de151f));
+  background: linear-gradient(to bottom, #f5bdc0 0%, #e44149 50%, #de151f 50%, #ae0001 100%);
+  background-clip: padding-box;
+  -webkit-box-shadow: 2px 3px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 2px 3px 2px rgba(0, 0, 0, 0.5);
+}
+.mblDomButtonRedBadge > div > div {
+  display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedBadge.less b/dojox/mobile/themes/common/domButtons/DomButtonRedBadge.less
new file mode 100644
index 0000000..49ae0fd
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedBadge.less
@@ -0,0 +1,28 @@
+ at import "../css3.less";
+/* === Red Badge ==*/
+.mblDomButtonRedBadge {
+	position: relative;
+	width: 29px;
+	height: 29px;
+	text-align: right;
+	font-family: Helvetica;
+	font-size: 16px;
+	font-weight: bold;
+}
+.mblDomButtonRedBadge > div {
+	position: absolute;
+	display: inline;
+	padding: 0px 5px;
+	top: 2px;
+	right: 2px;
+	color: white;
+	border: 2px solid white;
+	border-radius: 12px;
+	text-align: center;
+	.background-linear-gradient-top-bottom-2-stops(#f5bdc0, #ae0001, 0.5, #e44149, 0.5, #de151f);
+	background-clip: padding-box;
+	.box-shadow(2px 3px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonRedBadge > div > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedBall.css b/dojox/mobile/themes/common/domButtons/DomButtonRedBall.css
index 11a48cd..c46b3da 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonRedBall.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedBall.css
@@ -1,15 +1,16 @@
 /* === Red Ball Button ==*/
 .mblDomButtonRedBall {
-	position: relative;
-	width: 19px;
-	height: 29px;
+  position: relative;
+  width: 19px;
+  height: 29px;
 }
 .mblDomButtonRedBall > div {
-	position: relative;
-	top: 8px;
-	left: 4px;
-	width: 14px;
-	height: 14px;
-	-webkit-border-radius: 7px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#EC9B9D), to(#D73C3F));
+  position: relative;
+  top: 8px;
+  left: 4px;
+  width: 14px;
+  height: 14px;
+  border-radius: 7px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#ec9b9d), to(#d73c3f));
+  background: linear-gradient(to bottom, #ec9b9d 0%, #d73c3f 100%);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedBall.less b/dojox/mobile/themes/common/domButtons/DomButtonRedBall.less
new file mode 100644
index 0000000..37f5e81
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedBall.less
@@ -0,0 +1,16 @@
+ at import "../css3.less";
+/* === Red Ball Button ==*/
+.mblDomButtonRedBall {
+	position: relative;
+	width: 19px;
+	height: 29px;
+}
+.mblDomButtonRedBall > div {
+	position: relative;
+	top: 8px;
+	left: 4px;
+	width: 14px;
+	height: 14px;
+	border-radius: 7px;
+	.background-linear-gradient-top-bottom(#ec9b9d, #d73c3f);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow.css
index c1506e7..be17684 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow.css
@@ -1,48 +1,50 @@
 /* === Red Circle Arrow Buttons ==*/
 .mblDomButtonRedCircleArrow {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
-
 .mblDomButtonRedCircleArrow > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 22px;
-	height: 22px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 12px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 22px;
+  height: 22px;
+  border: 1px solid #b5b6b5;
+  border-radius: 12px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
 }
 .mblDomButtonRedCircleArrow > div > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 18px;
-	height: 18px;
-	-webkit-border-radius: 9px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 18px;
+  height: 18px;
+  border-radius: 9px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#d3656d), to(#bc1320), color-stop(0.5, #c9404b), color-stop(0.5, #bc1421));
+  background: linear-gradient(to bottom, #d3656d 0%, #c9404b 50%, #bc1421 50%, #bc1320 100%);
 }
 .mblDomButtonRedCircleArrow > div > div > div {
-	position: absolute;
-	top: 5px;
-	left: 6px;
-	width: 8px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	border-style: none;
-	background: white;
-	-webkit-transform: rotate(45deg);
+  position: absolute;
+  top: 5px;
+  left: 6px;
+  width: 8px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  border-style: none;
+  background: white;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
 }
 .mblDomButtonRedCircleArrow > div > div > div > div {
-	position: absolute;
-	top: 1px;
-	left: 6px;
-	width: 3px;
-	height: 8px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
+  position: absolute;
+  top: 1px;
+  left: 6px;
+  width: 3px;
+  height: 8px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow.less b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow.less
new file mode 100644
index 0000000..14f3bf9
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleArrow.less
@@ -0,0 +1,49 @@
+ at import "../css3.less";
+/* === Red Circle Arrow Buttons ==*/
+.mblDomButtonRedCircleArrow {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+
+.mblDomButtonRedCircleArrow > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 22px;
+	height: 22px;
+	border: 1px solid #b5b6b5;
+	border-radius: 12px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonRedCircleArrow > div > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 18px;
+	height: 18px;
+	border-radius: 9px;
+	.background-linear-gradient-top-bottom-2-stops(#d3656d, #bc1320, 0.5, #c9404b, 0.5, #bc1421);
+}
+.mblDomButtonRedCircleArrow > div > div > div {
+	position: absolute;
+	top: 5px;
+	left: 6px;
+	width: 8px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	border-style: none;
+	background: white;
+	.transform(rotate(45deg));
+}
+.mblDomButtonRedCircleArrow > div > div > div > div {
+	position: absolute;
+	top: 1px;
+	left: 6px;
+	width: 3px;
+	height: 8px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus.css b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus.css
index bd16b0c..e52e821 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus.css
@@ -1,37 +1,38 @@
 /* === Red Circle Minus Buttons ==*/
 .mblDomButtonRedCircleMinus {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
-
 .mblDomButtonRedCircleMinus > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 22px;
-	height: 22px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 12px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 22px;
+  height: 22px;
+  border: 1px solid #b5b6b5;
+  border-radius: 12px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
 }
 .mblDomButtonRedCircleMinus > div > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 18px;
-	height: 18px;
-	-webkit-border-radius: 9px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 18px;
+  height: 18px;
+  border-radius: 9px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#d3656d), to(#bc1320), color-stop(0.5, #c9404b), color-stop(0.5, #bc1421));
+  background: linear-gradient(to bottom, #d3656d 0%, #c9404b 50%, #bc1421 50%, #bc1320 100%);
 }
 .mblDomButtonRedCircleMinus > div > div > div {
-	position: absolute;
-	top: 8px;
-	left: 3px;
-	width: 12px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	border-style: none;
-	background: white;
+  position: absolute;
+  top: 8px;
+  left: 3px;
+  width: 12px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  border-style: none;
+  background: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus.less b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus.less
new file mode 100644
index 0000000..a4067d3
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCircleMinus.less
@@ -0,0 +1,38 @@
+ at import "../css3.less";
+/* === Red Circle Minus Buttons ==*/
+.mblDomButtonRedCircleMinus {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+
+.mblDomButtonRedCircleMinus > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 22px;
+	height: 22px;
+	border: 1px solid #b5b6b5;
+	border-radius: 12px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonRedCircleMinus > div > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 18px;
+	height: 18px;
+	border-radius: 9px;
+	.background-linear-gradient-top-bottom-2-stops(#d3656d, #bc1320, 0.5, #c9404b, 0.5, #bc1421);
+}
+.mblDomButtonRedCircleMinus > div > div > div {
+	position: absolute;
+	top: 8px;
+	left: 3px;
+	width: 12px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	border-style: none;
+	background: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus.css b/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus.css
index a507bdd..9f08916 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus.css
@@ -1,47 +1,48 @@
 /* === Red Circle Plus Buttons ==*/
 .mblDomButtonRedCirclePlus {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
-
 .mblDomButtonRedCirclePlus > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 22px;
-	height: 22px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 12px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 22px;
+  height: 22px;
+  border: 1px solid #b5b6b5;
+  border-radius: 12px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
 }
 .mblDomButtonRedCirclePlus > div > div {
-	position: relative;
-	top: 2px;
-	left: 2px;
-	width: 18px;
-	height: 18px;
-	-webkit-border-radius: 9px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#D3656D), to(#BC1320), color-stop(0.5, #C9404B), color-stop(0.5, #BC1421));
+  position: relative;
+  top: 2px;
+  left: 2px;
+  width: 18px;
+  height: 18px;
+  border-radius: 9px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#d3656d), to(#bc1320), color-stop(0.5, #c9404b), color-stop(0.5, #bc1421));
+  background: linear-gradient(to bottom, #d3656d 0%, #c9404b 50%, #bc1421 50%, #bc1320 100%);
 }
 .mblDomButtonRedCirclePlus > div > div > div {
-	position: absolute;
-	top: 8px;
-	left: 3px;
-	width: 13px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	border-style: none;
-	background: white;
+  position: absolute;
+  top: 8px;
+  left: 3px;
+  width: 13px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  border-style: none;
+  background: white;
 }
 .mblDomButtonRedCirclePlus > div > div > div > div {
-	position: absolute;
-	top: -5px;
-	left: 5px;
-	width: 3px;
-	height: 13px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
+  position: absolute;
+  top: -5px;
+  left: 5px;
+  width: 3px;
+  height: 13px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus.less b/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus.less
new file mode 100644
index 0000000..fcff523
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCirclePlus.less
@@ -0,0 +1,48 @@
+ at import "../css3.less";
+/* === Red Circle Plus Buttons ==*/
+.mblDomButtonRedCirclePlus {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+
+.mblDomButtonRedCirclePlus > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 22px;
+	height: 22px;
+	border: 1px solid #b5b6b5;
+	border-radius: 12px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+}
+.mblDomButtonRedCirclePlus > div > div {
+	position: relative;
+	top: 2px;
+	left: 2px;
+	width: 18px;
+	height: 18px;
+	border-radius: 9px;
+	.background-linear-gradient-top-bottom-2-stops(#d3656d, #bc1320, 0.5, #c9404b, 0.5, #bc1421);
+}
+.mblDomButtonRedCirclePlus > div > div > div {
+	position: absolute;
+	top: 8px;
+	left: 3px;
+	width: 13px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	border-style: none;
+	background: white;
+}
+.mblDomButtonRedCirclePlus > div > div > div > div {
+	position: absolute;
+	top: -5px;
+	left: 5px;
+	width: 3px;
+	height: 13px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCross-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonRedCross-compat.css
new file mode 100644
index 0000000..5f6ad6e
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCross-compat.css
@@ -0,0 +1,8 @@
+/* === Red Cross Button ==*/
+.mblDomButtonRedCross, .mblDomButtonCross {
+	background-image: url(compat/mblDomButtonRedCross.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonRedCross div, .mblDomButtonCross div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCross.css b/dojox/mobile/themes/common/domButtons/DomButtonRedCross.css
new file mode 100644
index 0000000..6bc2df3
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCross.css
@@ -0,0 +1,33 @@
+/* === Red Cross Button ==*/
+.mblDomButtonRedCross {
+  position: relative;
+  width: 29px;
+  height: 29px;
+}
+.mblDomButtonRedCross > div {
+  position: absolute;
+  top: 12px;
+  left: 7px;
+  width: 14px;
+  height: 2px;
+  margin: 0px;
+  font-size: 1px;
+  border: 1px solid #ad3213;
+  background-color: #e54d1f;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  -moz-transform: rotate(45deg);
+  border-radius: 2px;
+}
+.mblDomButtonRedCross > div > div {
+  position: absolute;
+  top: -7px;
+  left: 5px;
+  width: 2px;
+  height: 14px;
+  margin: 0px;
+  font-size: 1px;
+  border: 1px solid #ad3213;
+  background-color: #e54d1f;
+  border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonRedCross.less b/dojox/mobile/themes/common/domButtons/DomButtonRedCross.less
new file mode 100644
index 0000000..38698c6
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonRedCross.less
@@ -0,0 +1,33 @@
+ at import "../css3.less";
+/* === Red Cross Button ==*/
+.mblDomButtonRedCross {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonRedCross > div {
+	position: absolute;
+	top: 12px;
+	left: 7px;
+	width: 14px;
+	height: 2px;
+	margin: 0px;
+	font-size: 1px;
+	border: 1px solid #ad3213;
+	background-color: #e54d1f;
+	.transform(rotate(45deg));
+	-moz-transform: rotate(45deg);
+	border-radius: 2px;
+}
+.mblDomButtonRedCross > div > div {
+	position: absolute;
+	top: -7px;
+	left: 5px;
+	width: 2px;
+	height: 14px;
+	margin: 0px;
+	font-size: 1px;
+	border: 1px solid #ad3213;
+	background-color: #e54d1f;
+	border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow.css
index 3f70ab8..9276160 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow.css
@@ -1,43 +1,47 @@
 /* === Silver Circle Down Arrow ==*/
 .mblDomButtonSilverCircleDownArrow {
-	position: relative;
-	width: 30px;
-	height: 30px;
+  position: relative;
+  width: 30px;
+  height: 30px;
 }
 .mblDomButtonSilverCircleDownArrow > div {
-	position: relative;
-	top: 0px;
-	left: 0px;
-	width: 26px;
-	height: 26px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 13px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
-	background: -webkit-gradient(linear, left top, left bottom, from(#EFEFEF), to(#C2C2C2));
+  position: relative;
+  top: 0px;
+  left: 0px;
+  width: 26px;
+  height: 26px;
+  border: 1px solid #b5b6b5;
+  border-radius: 13px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  background: -webkit-gradient(linear, left top, left bottom, from(#efefef), to(#c2c2c2));
+  background: linear-gradient(to bottom, #efefef 0%, #c2c2c2 100%);
 }
 .mblDomButtonSilverCircleDownArrow > div > div {
-	position: relative;
-	top: 3px;
-	left: 3px;
-	width: 20px;
-	height: 20px;
-	-webkit-border-radius: 10px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#979797), to(#616161));
+  position: relative;
+  top: 3px;
+  left: 3px;
+  width: 20px;
+  height: 20px;
+  border-radius: 10px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#979797), to(#616161));
+  background: linear-gradient(to bottom, #979797 0%, #616161 100%);
 }
 .mblDomButtonSilverCircleDownArrow > div > div > div {
-	position: absolute;
-	left: 0px;
-	clip: rect(6px 50px 40px 0px);
+  position: absolute;
+  left: 0px;
+  clip: rect(6px 50px 40px 0px);
 }
 .mblDomButtonSilverCircleDownArrow > div > div > div > div {
-	position: absolute;
-	top: -5px;
-	left: 1px;
-	width: 18px;
-	height: 18px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: #D1D1D1;
-	border-top: 1px solid #4A5A71;
-	-webkit-transform: scaleX(0.7) rotate(45deg);
+  position: absolute;
+  top: -5px;
+  left: 1px;
+  width: 18px;
+  height: 18px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #d1d1d1;
+  border-top: 1px solid #4a5a71;
+  -webkit-transform: scaleX(0.7) rotate(45deg);
+  transform: scaleX(0.7) rotate(45deg);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow.less b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow.less
new file mode 100644
index 0000000..64359a8
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleDownArrow.less
@@ -0,0 +1,44 @@
+ at import "../css3.less";
+/* === Silver Circle Down Arrow ==*/
+.mblDomButtonSilverCircleDownArrow {
+	position: relative;
+	width: 30px;
+	height: 30px;
+}
+.mblDomButtonSilverCircleDownArrow > div {
+	position: relative;
+	top: 0px;
+	left: 0px;
+	width: 26px;
+	height: 26px;
+	border: 1px solid #b5b6b5;
+	border-radius: 13px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+	.background-linear-gradient-top-bottom(#efefef, #c2c2c2);
+}
+.mblDomButtonSilverCircleDownArrow > div > div {
+	position: relative;
+	top: 3px;
+	left: 3px;
+	width: 20px;
+	height: 20px;
+	border-radius: 10px;
+	.background-linear-gradient-top-bottom(#979797, #616161);
+}
+.mblDomButtonSilverCircleDownArrow > div > div > div {
+	position: absolute;
+	left: 0px;
+	clip: rect(6px 50px 40px 0px);
+}
+.mblDomButtonSilverCircleDownArrow > div > div > div > div {
+	position: absolute;
+	top: -5px;
+	left: 1px;
+	width: 18px;
+	height: 18px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #d1d1d1;
+	border-top: 1px solid #4a5a71;
+	.transform(scaleX(0.7) rotate(45deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton.css
index 0769c27..7f5579f 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton.css
@@ -1,27 +1,30 @@
 /* === Silver Circle Gray Button ==*/
 .mblDomButtonSilverCircleGrayButton {
-	position: relative;
-	width: 30px;
-	height: 30px;
+  position: relative;
+  width: 30px;
+  height: 30px;
 }
 .mblDomButtonSilverCircleGrayButton > div {
-	position: relative;
-	top: 0px;
-	left: 0px;
-	width: 26px;
-	height: 26px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 13px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
-	background: -webkit-gradient(linear, left top, left bottom, from(#EFEFEF), to(#C2C2C2));
+  position: relative;
+  top: 0px;
+  left: 0px;
+  width: 26px;
+  height: 26px;
+  border: 1px solid #b5b6b5;
+  border-radius: 13px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  background: -webkit-gradient(linear, left top, left bottom, from(#efefef), to(#c2c2c2));
+  background: linear-gradient(to bottom, #efefef 0%, #c2c2c2 100%);
 }
 .mblDomButtonSilverCircleGrayButton > div > div {
-	position: relative;
-	top: 6px;
-	left: 6px;
-	width: 12px;
-	height: 12px;
-	border: 1px inset #AEAEAE;
-	-webkit-border-radius: 7px;
-	background: -webkit-gradient(linear, left top, left bottom, from(#D4D4D4), to(#BABABA));
+  position: relative;
+  top: 6px;
+  left: 6px;
+  width: 12px;
+  height: 12px;
+  border: 1px inset #aeaeae;
+  border-radius: 7px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#d4d4d4), to(#bababa));
+  background: linear-gradient(to bottom, #d4d4d4 0%, #bababa 100%);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton.less b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton.less
new file mode 100644
index 0000000..2e25262
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGrayButton.less
@@ -0,0 +1,28 @@
+ at import "../css3.less";
+/* === Silver Circle Gray Button ==*/
+.mblDomButtonSilverCircleGrayButton {
+	position: relative;
+	width: 30px;
+	height: 30px;
+}
+.mblDomButtonSilverCircleGrayButton > div {
+	position: relative;
+	top: 0px;
+	left: 0px;
+	width: 26px;
+	height: 26px;
+	border: 1px solid #b5b6b5;
+	border-radius: 13px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+	.background-linear-gradient-top-bottom(#efefef, #c2c2c2);
+}
+.mblDomButtonSilverCircleGrayButton > div > div {
+	position: relative;
+	top: 6px;
+	left: 6px;
+	width: 12px;
+	height: 12px;
+	border: 1px inset #aeaeae;
+	border-radius: 7px;
+	.background-linear-gradient-top-bottom(#d4d4d4, #bababa);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton.css
index 2b59042..060adec 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton.css
@@ -1,27 +1,30 @@
 /* === Silver Circle Green Button ==*/
 .mblDomButtonSilverCircleGreenButton {
-	position: relative;
-	width: 30px;
-	height: 30px;
+  position: relative;
+  width: 30px;
+  height: 30px;
 }
 .mblDomButtonSilverCircleGreenButton > div {
-	position: relative;
-	top: 0px;
-	left: 0px;
-	width: 26px;
-	height: 26px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 13px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
-	background: -webkit-gradient(linear, left top, left bottom, from(#EFEFEF), to(#C2C2C2));
+  position: relative;
+  top: 0px;
+  left: 0px;
+  width: 26px;
+  height: 26px;
+  border: 1px solid #b5b6b5;
+  border-radius: 13px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  background: -webkit-gradient(linear, left top, left bottom, from(#efefef), to(#c2c2c2));
+  background: linear-gradient(to bottom, #efefef 0%, #c2c2c2 100%);
 }
 .mblDomButtonSilverCircleGreenButton > div > div {
-	position: relative;
-	top: 6px;
-	left: 6px;
-	width: 12px;
-	height: 12px;
-	border: 1px inset #1B991C;
-	-webkit-border-radius: 7px;
-	background: -webkit-gradient(radial, center center, 0, center center, 6, from(#17DF25), to(#1BA51C));
+  position: relative;
+  top: 6px;
+  left: 6px;
+  width: 12px;
+  height: 12px;
+  border: 1px inset #1b991c;
+  border-radius: 7px;
+  background: -webkit-gradient(radial, center center, 0, center center, 6, from(#17df25), to(#1ba51c));
+  background: radial-gradient(6 at center, #17df25 0%, #1ba51c 100%);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton.less b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton.less
new file mode 100644
index 0000000..8fcf594
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenButton.less
@@ -0,0 +1,28 @@
+ at import "../css3.less";
+/* === Silver Circle Green Button ==*/
+.mblDomButtonSilverCircleGreenButton {
+	position: relative;
+	width: 30px;
+	height: 30px;
+}
+.mblDomButtonSilverCircleGreenButton > div {
+	position: relative;
+	top: 0px;
+	left: 0px;
+	width: 26px;
+	height: 26px;
+	border: 1px solid #b5b6b5;
+	border-radius: 13px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+	.background-linear-gradient-top-bottom(#efefef, #c2c2c2);
+}
+.mblDomButtonSilverCircleGreenButton > div > div {
+	position: relative;
+	top: 6px;
+	left: 6px;
+	width: 12px;
+	height: 12px;
+	border: 1px inset #1b991c;
+	border-radius: 7px;
+	.background-radial-gradient-center(6, #17df25, #1ba51c);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus.css
index 9808e86..2a01841 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus.css
@@ -1,37 +1,39 @@
 /* === Silver Circle Green Plus Button ==*/
 .mblDomButtonSilverCircleGreenPlus {
-	position: relative;
-	width: 30px;
-	height: 30px;
+  position: relative;
+  width: 30px;
+  height: 30px;
 }
 .mblDomButtonSilverCircleGreenPlus > div {
-	position: relative;
-	top: 0px;
-	left: 0px;
-	width: 26px;
-	height: 26px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 13px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
-	background: -webkit-gradient(linear, left top, left bottom, from(#EFEFEF), to(#C2C2C2));
+  position: relative;
+  top: 0px;
+  left: 0px;
+  width: 26px;
+  height: 26px;
+  border: 1px solid #b5b6b5;
+  border-radius: 13px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  background: -webkit-gradient(linear, left top, left bottom, from(#efefef), to(#c2c2c2));
+  background: linear-gradient(to bottom, #efefef 0%, #c2c2c2 100%);
 }
 .mblDomButtonSilverCircleGreenPlus > div > div {
-	position: absolute;
-	top: 11px;
-	left: 4px;
-	width: 18px;
-	height: 4px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: #17DF25;
+  position: absolute;
+  top: 11px;
+  left: 4px;
+  width: 18px;
+  height: 4px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #17df25;
 }
 .mblDomButtonSilverCircleGreenPlus > div > div > div {
-	position: absolute;
-	top: -7px;
-	left: 7px;
-	width: 4px;
-	height: 18px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: #17DF25;
+  position: absolute;
+  top: -7px;
+  left: 7px;
+  width: 4px;
+  height: 18px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #17df25;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus.less b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus.less
new file mode 100644
index 0000000..2885206
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleGreenPlus.less
@@ -0,0 +1,38 @@
+ at import "../css3.less";
+/* === Silver Circle Green Plus Button ==*/
+.mblDomButtonSilverCircleGreenPlus {
+	position: relative;
+	width: 30px;
+	height: 30px;
+}
+.mblDomButtonSilverCircleGreenPlus > div {
+	position: relative;
+	top: 0px;
+	left: 0px;
+	width: 26px;
+	height: 26px;
+	border: 1px solid #b5b6b5;
+	border-radius: 13px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+	.background-linear-gradient-top-bottom(#efefef, #c2c2c2);
+}
+.mblDomButtonSilverCircleGreenPlus > div > div {
+	position: absolute;
+	top: 11px;
+	left: 4px;
+	width: 18px;
+	height: 4px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #17df25;
+}
+.mblDomButtonSilverCircleGreenPlus > div > div > div {
+	position: absolute;
+	top: -7px;
+	left: 7px;
+	width: 4px;
+	height: 18px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #17df25;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton.css
index 160ef4e..be1b792 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton.css
@@ -1,27 +1,30 @@
 /* === Silver Circle Orange Button ==*/
 .mblDomButtonSilverCircleOrangeButton {
-	position: relative;
-	width: 30px;
-	height: 30px;
+  position: relative;
+  width: 30px;
+  height: 30px;
 }
 .mblDomButtonSilverCircleOrangeButton > div {
-	position: relative;
-	top: 0px;
-	left: 0px;
-	width: 26px;
-	height: 26px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 13px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
-	background: -webkit-gradient(linear, left top, left bottom, from(#EFEFEF), to(#C2C2C2));
+  position: relative;
+  top: 0px;
+  left: 0px;
+  width: 26px;
+  height: 26px;
+  border: 1px solid #b5b6b5;
+  border-radius: 13px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  background: -webkit-gradient(linear, left top, left bottom, from(#efefef), to(#c2c2c2));
+  background: linear-gradient(to bottom, #efefef 0%, #c2c2c2 100%);
 }
 .mblDomButtonSilverCircleOrangeButton > div > div {
-	position: relative;
-	top: 6px;
-	left: 6px;
-	width: 12px;
-	height: 12px;
-	border: 1px inset #CA701A;
-	-webkit-border-radius: 7px;
-	background: -webkit-gradient(radial, center center, 0, center center, 6, from(#FF7A07), to(#E66B03));
+  position: relative;
+  top: 6px;
+  left: 6px;
+  width: 12px;
+  height: 12px;
+  border: 1px inset #ca701a;
+  border-radius: 7px;
+  background: -webkit-gradient(radial, center center, 0, center center, 6, from(#ff7a07), to(#e66b03));
+  background: radial-gradient(6 at center, #ff7a07 0%, #e66b03 100%);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton.less b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton.less
new file mode 100644
index 0000000..bebdd3d
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleOrangeButton.less
@@ -0,0 +1,28 @@
+ at import "../css3.less";
+/* === Silver Circle Orange Button ==*/
+.mblDomButtonSilverCircleOrangeButton {
+	position: relative;
+	width: 30px;
+	height: 30px;
+}
+.mblDomButtonSilverCircleOrangeButton > div {
+	position: relative;
+	top: 0px;
+	left: 0px;
+	width: 26px;
+	height: 26px;
+	border: 1px solid #b5b6b5;
+	border-radius: 13px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+	.background-linear-gradient-top-bottom(#efefef, #c2c2c2);
+}
+.mblDomButtonSilverCircleOrangeButton > div > div {
+	position: relative;
+	top: 6px;
+	left: 6px;
+	width: 12px;
+	height: 12px;
+	border: 1px inset #ca701a;
+	border-radius: 7px;
+	.background-radial-gradient-center(6, #ff7a07, #e66b03);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross.css b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross.css
index 14f4ec3..282d4ef 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross.css
@@ -1,38 +1,41 @@
 /* === Silver Circle Red Cross Button ==*/
 .mblDomButtonSilverCircleRedCross {
-	position: relative;
-	width: 30px;
-	height: 30px;
+  position: relative;
+  width: 30px;
+  height: 30px;
 }
 .mblDomButtonSilverCircleRedCross > div {
-	position: relative;
-	top: 0px;
-	left: 0px;
-	width: 26px;
-	height: 26px;
-	border: 1px solid #B5B6B5;
-	-webkit-border-radius: 13px;
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
-	background: -webkit-gradient(linear, left top, left bottom, from(#EFEFEF), to(#C2C2C2));
+  position: relative;
+  top: 0px;
+  left: 0px;
+  width: 26px;
+  height: 26px;
+  border: 1px solid #b5b6b5;
+  border-radius: 13px;
+  -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.5);
+  background: -webkit-gradient(linear, left top, left bottom, from(#efefef), to(#c2c2c2));
+  background: linear-gradient(to bottom, #efefef 0%, #c2c2c2 100%);
 }
 .mblDomButtonSilverCircleRedCross > div > div {
-	position: absolute;
-	top: 11px;
-	left: 4px;
-	width: 18px;
-	height: 4px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: #F00E5A;
-	-webkit-transform: rotate(45deg);
+  position: absolute;
+  top: 11px;
+  left: 4px;
+  width: 18px;
+  height: 4px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #f00e5a;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
 }
 .mblDomButtonSilverCircleRedCross > div > div > div {
-	position: absolute;
-	top: -7px;
-	left: 7px;
-	width: 4px;
-	height: 18px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: #F00E5A;
+  position: absolute;
+  top: -7px;
+  left: 7px;
+  width: 4px;
+  height: 18px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: #f00e5a;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross.less b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross.less
new file mode 100644
index 0000000..202f554
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonSilverCircleRedCross.less
@@ -0,0 +1,39 @@
+ at import "../css3.less";
+/* === Silver Circle Red Cross Button ==*/
+.mblDomButtonSilverCircleRedCross {
+	position: relative;
+	width: 30px;
+	height: 30px;
+}
+.mblDomButtonSilverCircleRedCross > div {
+	position: relative;
+	top: 0px;
+	left: 0px;
+	width: 26px;
+	height: 26px;
+	border: 1px solid #b5b6b5;
+	border-radius: 13px;
+	.box-shadow(0px 1px 2px rgba(0, 0, 0, 0.5));
+	.background-linear-gradient-top-bottom(#efefef, #c2c2c2);
+}
+.mblDomButtonSilverCircleRedCross > div > div {
+	position: absolute;
+	top: 11px;
+	left: 4px;
+	width: 18px;
+	height: 4px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #f00e5a;
+	.transform(rotate(45deg));
+}
+.mblDomButtonSilverCircleRedCross > div > div > div {
+	position: absolute;
+	top: -7px;
+	left: 7px;
+	width: 4px;
+	height: 18px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: #f00e5a;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonTransparent19.css b/dojox/mobile/themes/common/domButtons/DomButtonTransparent19.css
index 3626476..a373e1e 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonTransparent19.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonTransparent19.css
@@ -1,6 +1,6 @@
 /* === Transparent Button ==*/
 .mblDomButtonTransparent19 {
-	position: relative;
-	width: 19px;
-	height: 19px;
+  position: relative;
+  width: 19px;
+  height: 19px;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonTransparent19.less b/dojox/mobile/themes/common/domButtons/DomButtonTransparent19.less
new file mode 100644
index 0000000..12249a5
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonTransparent19.less
@@ -0,0 +1,7 @@
+ at import "../css3.less";
+/* === Transparent Button ==*/
+.mblDomButtonTransparent19 {
+	position: relative;
+	width: 19px;
+	height: 19px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonTransparent29.css b/dojox/mobile/themes/common/domButtons/DomButtonTransparent29.css
index 3eb4891..7d4de5e 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonTransparent29.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonTransparent29.css
@@ -1,6 +1,6 @@
 /* === Transparent Button ==*/
 .mblDomButtonTransparent29 {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonTransparent29.less b/dojox/mobile/themes/common/domButtons/DomButtonTransparent29.less
new file mode 100644
index 0000000..ae24ad3
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonTransparent29.less
@@ -0,0 +1,7 @@
+ at import "../css3.less";
+/* === Transparent Button ==*/
+.mblDomButtonTransparent29 {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonTransparent30.css b/dojox/mobile/themes/common/domButtons/DomButtonTransparent30.css
index b95baf7..90d49ee 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonTransparent30.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonTransparent30.css
@@ -1,6 +1,6 @@
 /* === Transparent Button ==*/
 .mblDomButtonTransparent30 {
-	position: relative;
-	width: 30px;
-	height: 30px;
+  position: relative;
+  width: 30px;
+  height: 30px;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonTransparent30.less b/dojox/mobile/themes/common/domButtons/DomButtonTransparent30.less
new file mode 100644
index 0000000..1965e7e
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonTransparent30.less
@@ -0,0 +1,7 @@
+ at import "../css3.less";
+/* === Transparent Button ==*/
+.mblDomButtonTransparent30 {
+	position: relative;
+	width: 30px;
+	height: 30px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow.css
index 9c9e332..2a4ddeb 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow.css
@@ -1,18 +1,21 @@
 /* === Arrow ==*/
-.mblDomButtonWhiteArrow, .mblDomButtonArrow {
-	position: relative;
-	width: 20px;
-	height: 29px;
+.mblDomButtonWhiteArrow,
+.mblDomButtonArrow {
+  position: relative;
+  width: 20px;
+  height: 29px;
 }
-.mblDomButtonWhiteArrow > div, .mblDomButtonArrow > div {
-	position: absolute;
-	top: 10px;
-	left: 6px;
-	width: 6px;
-	height: 6px;
-	font-size: 1px;
-	-webkit-transform: rotate(45deg);
-	border-width: 3px 3px 0px 0px;
-	border-style: solid;
-	border-color: white;
+.mblDomButtonWhiteArrow > div,
+.mblDomButtonArrow > div {
+  position: absolute;
+  top: 10px;
+  left: 6px;
+  width: 6px;
+  height: 6px;
+  font-size: 1px;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  border-width: 3px 3px 0px 0px;
+  border-style: solid;
+  border-color: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow.less
new file mode 100644
index 0000000..23019eb
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteArrow.less
@@ -0,0 +1,19 @@
+ at import "../css3.less";
+/* === Arrow ==*/
+.mblDomButtonWhiteArrow, .mblDomButtonArrow {
+	position: relative;
+	width: 20px;
+	height: 29px;
+}
+.mblDomButtonWhiteArrow > div, .mblDomButtonArrow > div {
+	position: absolute;
+	top: 10px;
+	left: 6px;
+	width: 6px;
+	height: 6px;
+	font-size: 1px;
+	.transform(rotate(45deg));
+	border-width: 3px 3px 0px 0px;
+	border-style: solid;
+	border-color: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck.css
index 1b51a8f..18d644a 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck.css
@@ -1,18 +1,21 @@
 /* === Check Button ==*/
-.mblDomButtonWhiteCheck, .mblDomButtonCheck {
-	position: relative;
-	width: 20px;
-	height: 29px;
+.mblDomButtonWhiteCheck,
+.mblDomButtonCheck {
+  position: relative;
+  width: 20px;
+  height: 29px;
 }
-.mblDomButtonWhiteCheck > div, .mblDomButtonCheck > div {
-	position: absolute;
-	left: 0px;
-	top: 8px;
-	width: 16px;
-	height: 6px;
-	font-size: 1px;
-	-webkit-transform: scaleX(0.7) rotate(135deg);
-	border-width: 3px 4px 0px 0px;
-	border-style: solid;
-	border-color: white;
+.mblDomButtonWhiteCheck > div,
+.mblDomButtonCheck > div {
+  position: absolute;
+  left: 0px;
+  top: 8px;
+  width: 16px;
+  height: 6px;
+  font-size: 1px;
+  -webkit-transform: scaleX(0.7) rotate(135deg);
+  transform: scaleX(0.7) rotate(135deg);
+  border-width: 3px 4px 0px 0px;
+  border-style: solid;
+  border-color: white;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck.less
new file mode 100644
index 0000000..0834277
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck.less
@@ -0,0 +1,19 @@
+ at import "../css3.less";
+/* === Check Button ==*/
+.mblDomButtonWhiteCheck, .mblDomButtonCheck {
+	position: relative;
+	width: 20px;
+	height: 29px;
+}
+.mblDomButtonWhiteCheck > div, .mblDomButtonCheck > div {
+	position: absolute;
+	left: 0px;
+	top: 8px;
+	width: 16px;
+	height: 6px;
+	font-size: 1px;
+	.transform(scaleX(0.7) rotate(135deg));
+	border-width: 3px 4px 0px 0px;
+	border-style: solid;
+	border-color: white;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck_rtl.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck_rtl.css
new file mode 100644
index 0000000..0c2edc2
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck_rtl.css
@@ -0,0 +1,8 @@
+/* === Check Button Rtl ==*/
+.mblListItemRtl .mblDomButtonWhiteCheck > div,
+.mblListItemRtl .mblDomButtonCheck > div {
+  right: 0px;
+  -webkit-transform: scaleX(-0.7) rotate(-135deg);
+  transform: scaleX(-0.7) rotate(-135deg);
+  border-width: 3px 0px 0px 4px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck_rtl.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck_rtl.less
new file mode 100644
index 0000000..5c807a7
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCheck_rtl.less
@@ -0,0 +1,8 @@
+ at import "../css3.less";
+/* === Check Button Rtl ==*/
+.mblListItemRtl .mblDomButtonWhiteCheck > div,
+.mblListItemRtl .mblDomButtonCheck > div {
+	right: 0px;
+	.transform(scaleX(-0.7) rotate(-135deg));
+	border-width: 3px 0px 0px 4px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteCross-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCross-compat.css
new file mode 100644
index 0000000..657ddaa
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCross-compat.css
@@ -0,0 +1,8 @@
+/* === White Cross Button ==*/
+.mblDomButtonWhiteCross, .mblDomButtonCross {
+	background-image: url(compat/mblDomButtonWhiteCross.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhiteCross div, .mblDomButtonCross div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteCross.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCross.css
new file mode 100644
index 0000000..084dba6
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCross.css
@@ -0,0 +1,33 @@
+/* === White Cross Button ==*/
+.mblDomButtonWhiteCross {
+  position: relative;
+  width: 29px;
+  height: 29px;
+}
+.mblDomButtonWhiteCross > div {
+  position: absolute;
+  top: 12px;
+  left: 7px;
+  width: 14px;
+  height: 2px;
+  margin: 0px;
+  font-size: 1px;
+  border: 1px solid #808080;
+  background-color: #ffffff;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  -moz-transform: rotate(45deg);
+  border-radius: 2px;
+}
+.mblDomButtonWhiteCross > div > div {
+  position: absolute;
+  top: -7px;
+  left: 5px;
+  width: 2px;
+  height: 14px;
+  margin: 0px;
+  font-size: 1px;
+  border: 1px solid #808080;
+  background-color: #ffffff;
+  border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteCross.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCross.less
new file mode 100644
index 0000000..e72e9cc
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteCross.less
@@ -0,0 +1,33 @@
+ at import "../css3.less";
+/* === White Cross Button ==*/
+.mblDomButtonWhiteCross {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonWhiteCross > div {
+	position: absolute;
+	top: 12px;
+	left: 7px;
+	width: 14px;
+	height: 2px;
+	margin: 0px;
+	font-size: 1px;
+	border: 1px solid #808080;
+	background-color: #ffffff;
+	.transform(rotate(45deg));
+	-moz-transform: rotate(45deg);
+	border-radius: 2px;
+}
+.mblDomButtonWhiteCross > div > div {
+	position: absolute;
+	top: -7px;
+	left: 5px;
+	width: 2px;
+	height: 14px;
+	margin: 0px;
+	font-size: 1px;
+	border: 1px solid #808080;
+	background-color: #ffffff;
+	border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow.css
index 33188b3..3fdd42d 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow.css
@@ -1,22 +1,23 @@
 /* === Down Arrow Button ==*/
 .mblDomButtonWhiteDownArrow {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
 .mblDomButtonWhiteDownArrow div {
-	position: absolute;
-	left: 0px;
-	clip: rect(7px 50px 40px 0px);
+  position: absolute;
+  left: 0px;
+  clip: rect(7px 50px 40px 0px);
 }
 .mblDomButtonWhiteDownArrow > div > div {
-	top: -10px;
-	left: 2px;
-	width: 25px;
-	height: 25px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-	border-top: 1px solid #4A5A71;
-	-webkit-transform: scaleX(0.6) rotate(45deg);
+  top: -10px;
+  left: 2px;
+  width: 25px;
+  height: 25px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
+  border-top: 1px solid #4a5a71;
+  -webkit-transform: scaleX(0.6) rotate(45deg);
+  transform: scaleX(0.6) rotate(45deg);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow.less
new file mode 100644
index 0000000..8721598
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow.less
@@ -0,0 +1,23 @@
+ at import "../css3.less";
+/* === Down Arrow Button ==*/
+.mblDomButtonWhiteDownArrow {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonWhiteDownArrow div {
+	position: absolute;
+	left: 0px;
+	clip: rect(7px 50px 40px 0px);
+}
+.mblDomButtonWhiteDownArrow > div > div {
+	top: -10px;
+	left: 2px;
+	width: 25px;
+	height: 25px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+	border-top: 1px solid #4a5a71;
+	.transform(scaleX(0.6) rotate(45deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow16-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow16-compat.css
new file mode 100644
index 0000000..9592042
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow16-compat.css
@@ -0,0 +1,8 @@
+/* === WhiteDownArrow16 ==*/
+.mblDomButtonWhiteDownArrow16 {
+	background-image: url(compat/mblDomButtonWhiteDownArrow16.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhiteDownArrow16 > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow16.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow16.css
new file mode 100644
index 0000000..9d9cf80
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow16.css
@@ -0,0 +1,23 @@
+/* === WhiteDownArrow16 ==*/
+.mblDomButtonWhiteDownArrow16 {
+  position: relative;
+  width: 16px;
+  height: 16px;
+}
+.mblDomButtonWhiteDownArrow16 > div {
+  position: absolute;
+  left: 0px;
+  clip: rect(4px 16px 16px 0px);
+}
+.mblDomButtonWhiteDownArrow16 > div > div {
+  position: absolute;
+  top: 0px;
+  left: 3px;
+  width: 10px;
+  height: 10px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
+  -webkit-transform: scaleX(0.5) rotate(45deg);
+  transform: scaleX(0.5) rotate(45deg);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow16.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow16.less
new file mode 100644
index 0000000..e97fa47
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteDownArrow16.less
@@ -0,0 +1,23 @@
+ at import "../css3.less";
+/* === WhiteDownArrow16 ==*/
+.mblDomButtonWhiteDownArrow16 {
+	position: relative;
+	width: 16px;
+	height: 16px;
+}
+.mblDomButtonWhiteDownArrow16 > div {
+	position: absolute;
+	left: 0px;
+	clip: rect(4px 16px 16px 0px);
+}
+.mblDomButtonWhiteDownArrow16 > div > div {
+	position: absolute;
+	top: 0px;
+	left: 3px;
+	width: 10px;
+	height: 10px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+	.transform(scaleX(0.5) rotate(45deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteLeftArrow16-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteLeftArrow16-compat.css
new file mode 100644
index 0000000..81fc9ed
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteLeftArrow16-compat.css
@@ -0,0 +1,8 @@
+/* === WhiteLeftArrow16 ==*/
+.mblDomButtonWhiteLeftArrow16 {
+	background-image: url(compat/mblDomButtonWhiteLeftArrow16.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhiteLeftArrow16 > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteLeftArrow16.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteLeftArrow16.css
new file mode 100644
index 0000000..70268e2
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteLeftArrow16.css
@@ -0,0 +1,23 @@
+/* === WhiteLeftArrow16 ==*/
+.mblDomButtonWhiteLeftArrow16 {
+  position: relative;
+  width: 16px;
+  height: 16px;
+}
+.mblDomButtonWhiteLeftArrow16 > div {
+  position: absolute;
+  left: 0px;
+  clip: rect(0px 12px 16px 4px);
+}
+.mblDomButtonWhiteLeftArrow16 > div > div {
+  position: absolute;
+  top: 3px;
+  left: 6px;
+  width: 10px;
+  height: 10px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
+  -webkit-transform: scaleY(0.5) rotate(45deg);
+  transform: scaleY(0.5) rotate(45deg);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteLeftArrow16.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteLeftArrow16.less
new file mode 100644
index 0000000..ce24c06
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteLeftArrow16.less
@@ -0,0 +1,23 @@
+ at import "../css3.less";
+/* === WhiteLeftArrow16 ==*/
+.mblDomButtonWhiteLeftArrow16 {
+	position: relative;
+	width: 16px;
+	height: 16px;
+}
+.mblDomButtonWhiteLeftArrow16 > div {
+	position: absolute;
+	left: 0px;
+	clip: rect(0px 12px 16px 4px);
+}
+.mblDomButtonWhiteLeftArrow16 > div > div {
+	position: absolute;
+	top: 3px;
+	left: 6px;
+	width: 10px;
+	height: 10px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+	.transform(scaleY(0.5) rotate(45deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteMinus-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteMinus-compat.css
new file mode 100644
index 0000000..7173447
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteMinus-compat.css
@@ -0,0 +1,8 @@
+/* === Minus Button ==*/
+.mblDomButtonWhiteMinus {
+	background-image: url(compat/mblDomButtonWhiteMinus.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhiteMinus div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteMinus.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteMinus.css
new file mode 100644
index 0000000..943712e
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteMinus.css
@@ -0,0 +1,19 @@
+/* === Minus Button ==*/
+.mblDomButtonWhiteMinus {
+  position: relative;
+  width: 29px;
+  height: 29px;
+}
+.mblDomButtonWhiteMinus > div {
+  /* horiz line */
+
+  position: absolute;
+  top: 12px;
+  left: 8px;
+  width: 13px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
+  border-top: 1px solid #4a5a71;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteMinus.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteMinus.less
new file mode 100644
index 0000000..459d30e
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteMinus.less
@@ -0,0 +1,18 @@
+ at import "../css3.less";
+/* === Minus Button ==*/
+.mblDomButtonWhiteMinus {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonWhiteMinus > div { /* horiz line */
+	position: absolute;
+	top: 12px;
+	left: 8px;
+	width: 13px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+	border-top: 1px solid #4a5a71;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus.css b/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus.css
index 4de8a89..dec2e37 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus.css
@@ -1,28 +1,32 @@
 /* === Plus Button ==*/
 .mblDomButtonWhitePlus {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
-.mblDomButtonWhitePlus > div { /* horiz line */
-	position: absolute;
-	top: 11px;
-	left: 8px;
-	width: 13px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-	border-top: 1px solid #4A5A71;
+.mblDomButtonWhitePlus > div {
+  /* horiz line */
+
+  position: absolute;
+  top: 12px;
+  left: 8px;
+  width: 13px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
+  border-top: 1px solid #4a5a71;
 }
-.mblDomButtonWhitePlus > div > div { /* vert line */
-	position: absolute;
-	top: -6px;
-	left: 5px;
-	width: 3px;
-	height: 13px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-	border-top: 1px solid #4A5A71;
+.mblDomButtonWhitePlus > div > div {
+  /* vert line */
+
+  position: absolute;
+  top: -6px;
+  left: 5px;
+  width: 3px;
+  height: 13px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
+  border-top: 1px solid #4a5a71;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus.less b/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus.less
new file mode 100644
index 0000000..f75f280
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhitePlus.less
@@ -0,0 +1,29 @@
+ at import "../css3.less";
+/* === Plus Button ==*/
+.mblDomButtonWhitePlus {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonWhitePlus > div { /* horiz line */
+	position: absolute;
+	top: 12px;
+	left: 8px;
+	width: 13px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+	border-top: 1px solid #4a5a71;
+}
+.mblDomButtonWhitePlus > div > div { /* vert line */
+	position: absolute;
+	top: -6px;
+	left: 5px;
+	width: 3px;
+	height: 13px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+	border-top: 1px solid #4a5a71;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteRightArrow16-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteRightArrow16-compat.css
new file mode 100644
index 0000000..d3e5972
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteRightArrow16-compat.css
@@ -0,0 +1,8 @@
+/* === WhiteRightArrow16 ==*/
+.mblDomButtonWhiteRightArrow16 {
+	background-image: url(compat/mblDomButtonWhiteRightArrow16.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhiteRightArrow16 > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteRightArrow16.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteRightArrow16.css
new file mode 100644
index 0000000..3b76700
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteRightArrow16.css
@@ -0,0 +1,23 @@
+/* === WhiteRightArrow16 ==*/
+.mblDomButtonWhiteRightArrow16 {
+  position: relative;
+  width: 16px;
+  height: 16px;
+}
+.mblDomButtonWhiteRightArrow16 > div {
+  position: absolute;
+  left: 0px;
+  clip: rect(0px 16px 16px 4px);
+}
+.mblDomButtonWhiteRightArrow16 > div > div {
+  position: absolute;
+  top: 3px;
+  left: 0px;
+  width: 10px;
+  height: 10px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
+  -webkit-transform: scaleY(0.5) rotate(45deg);
+  transform: scaleY(0.5) rotate(45deg);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteRightArrow16.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteRightArrow16.less
new file mode 100644
index 0000000..016acb7
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteRightArrow16.less
@@ -0,0 +1,23 @@
+ at import "../css3.less";
+/* === WhiteRightArrow16 ==*/
+.mblDomButtonWhiteRightArrow16 {
+	position: relative;
+	width: 16px;
+	height: 16px;
+}
+.mblDomButtonWhiteRightArrow16 > div {
+	position: absolute;
+	left: 0px;
+	clip: rect(0px 16px 16px 4px);
+}
+.mblDomButtonWhiteRightArrow16 > div > div {
+	position: absolute;
+	top: 3px;
+	left: 0px;
+	width: 10px;
+	height: 10px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+	.transform(scaleY(0.5) rotate(45deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch.css
index d8efeeb..eb9e363 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch.css
@@ -1,30 +1,31 @@
 /* === Search Button ==*/
 .mblDomButtonWhiteSearch {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
 .mblDomButtonWhiteSearch > div {
-	position: absolute;
-	top: 5px;
-	left: 6px;
-	width: 10px;
-	height: 10px;
-	margin: 0px;
-	font-size: 1px;
-	border: 2px solid white;
-	-webkit-border-radius: 6px;
+  position: absolute;
+  top: 5px;
+  left: 6px;
+  width: 10px;
+  height: 10px;
+  margin: 0px;
+  font-size: 1px;
+  border: 2px solid white;
+  border-radius: 6px;
 }
 .mblDomButtonWhiteSearch > div > div {
-	position: absolute;
-	top: 10px;
-	left: 7px;
-	width: 8px;
-	height: 3px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-	border: none;
-	-webkit-transform: rotate(45deg);
-	-webkit-border-radius: 0px;
+  position: absolute;
+  top: 10px;
+  left: 7px;
+  width: 8px;
+  height: 3px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
+  border: none;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  border-radius: 0px;
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch.less
new file mode 100644
index 0000000..e422113
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteSearch.less
@@ -0,0 +1,31 @@
+ at import "../css3.less";
+/* === Search Button ==*/
+.mblDomButtonWhiteSearch {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonWhiteSearch > div {
+	position: absolute;
+	top: 5px;
+	left: 6px;
+	width: 10px;
+	height: 10px;
+	margin: 0px;
+	font-size: 1px;
+	border: 2px solid white;
+	border-radius: 6px;
+}
+.mblDomButtonWhiteSearch > div > div {
+	position: absolute;
+	top: 10px;
+	left: 7px;
+	width: 8px;
+	height: 3px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+	border: none;
+	.transform(rotate(45deg));
+	border-radius: 0px;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow.css
index 7c7d0da..df966d7 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow.css
@@ -1,22 +1,23 @@
 /* === Up Arrow Button ==*/
 .mblDomButtonWhiteUpArrow {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
 .mblDomButtonWhiteUpArrow div {
-	position: absolute;
-	left: 0px;
-	clip: rect(0px 30px 20px 0px);
+  position: absolute;
+  left: 0px;
+  clip: rect(0px 30px 20px 0px);
 }
 .mblDomButtonWhiteUpArrow > div > div {
-	top: 9px;
-	left: 4px;
-	width: 20px;
-	height: 20px;
-	margin: 0px;
-	font-size: 1px;
-	background-color: white;
-	border-top: 1px solid #4A5A71;
-	-webkit-transform: scaleX(0.6) rotate(45deg);
+  top: 9px;
+  left: 4px;
+  width: 20px;
+  height: 20px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
+  border-top: 1px solid #4a5a71;
+  -webkit-transform: scaleX(0.6) rotate(45deg);
+  transform: scaleX(0.6) rotate(45deg);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow.less
new file mode 100644
index 0000000..b2ed027
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow.less
@@ -0,0 +1,23 @@
+ at import "../css3.less";
+/* === Up Arrow Button ==*/
+.mblDomButtonWhiteUpArrow {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonWhiteUpArrow div {
+	position: absolute;
+	left: 0px;
+	clip: rect(0px 30px 20px 0px);
+}
+.mblDomButtonWhiteUpArrow > div > div {
+	top: 9px;
+	left: 4px;
+	width: 20px;
+	height: 20px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+	border-top: 1px solid #4a5a71;
+	.transform(scaleX(0.6) rotate(45deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow16-compat.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow16-compat.css
new file mode 100644
index 0000000..0e35d7e
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow16-compat.css
@@ -0,0 +1,8 @@
+/* === WhiteUpArrow16 ==*/
+.mblDomButtonWhiteUpArrow16 {
+	background-image: url(compat/mblDomButtonWhiteUpArrow16.png);
+	background-repeat: no-repeat;
+}
+.mblDomButtonWhiteUpArrow16 > div {
+	display: none;
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow16.css b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow16.css
new file mode 100644
index 0000000..e5a464b
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow16.css
@@ -0,0 +1,23 @@
+/* === WhiteUpArrow16 ==*/
+.mblDomButtonWhiteUpArrow16 {
+  position: relative;
+  width: 16px;
+  height: 16px;
+}
+.mblDomButtonWhiteUpArrow16 > div {
+  position: absolute;
+  left: 0px;
+  clip: rect(0px 16px 12px 0px);
+}
+.mblDomButtonWhiteUpArrow16 > div > div {
+  position: absolute;
+  top: 6px;
+  left: 3px;
+  width: 10px;
+  height: 10px;
+  margin: 0px;
+  font-size: 1px;
+  background-color: white;
+  -webkit-transform: scaleX(0.5) rotate(45deg);
+  transform: scaleX(0.5) rotate(45deg);
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow16.less b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow16.less
new file mode 100644
index 0000000..933c068
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonWhiteUpArrow16.less
@@ -0,0 +1,23 @@
+ at import "../css3.less";
+/* === WhiteUpArrow16 ==*/
+.mblDomButtonWhiteUpArrow16 {
+	position: relative;
+	width: 16px;
+	height: 16px;
+}
+.mblDomButtonWhiteUpArrow16 > div {
+	position: absolute;
+	left: 0px;
+	clip: rect(0px 16px 12px 0px);
+}
+.mblDomButtonWhiteUpArrow16 > div > div {
+	position: absolute;
+	top: 6px;
+	left: 3px;
+	width: 10px;
+	height: 10px;
+	margin: 0px;
+	font-size: 1px;
+	background-color: white;
+	.transform(scaleX(0.5) rotate(45deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonYellowStar.css b/dojox/mobile/themes/common/domButtons/DomButtonYellowStar.css
index 96c07ce..1b980e9 100644
--- a/dojox/mobile/themes/common/domButtons/DomButtonYellowStar.css
+++ b/dojox/mobile/themes/common/domButtons/DomButtonYellowStar.css
@@ -1,49 +1,52 @@
 /* === Yellow Star ==*/
 .mblDomButtonYellowStar {
-	position: relative;
-	width: 29px;
-	height: 29px;
+  position: relative;
+  width: 29px;
+  height: 29px;
 }
 .mblDomButtonYellowStar > div {
-	position: absolute;
-	width: 0px;
-	height: 0px;
-	border-style: solid;
-	border-color: #FFFF00 transparent transparent transparent;
-	top: 12px;
-	left: 3px;
-	border-width: 9px 12px 0px 12px;
-	-webkit-transform: rotate(0deg);
+  position: absolute;
+  width: 0px;
+  height: 0px;
+  border-style: solid;
+  border-color: #ffff00 transparent transparent transparent;
+  top: 12px;
+  left: 3px;
+  border-width: 9px 12px 0px 12px;
+  -webkit-transform: rotate(0deg);
+  transform: rotate(0deg);
 }
 .mblDomButtonYellowStar > div > div {
-	position: absolute;
-	width: 24px;
-	height: 0px;
-	border-style: solid;
-	border-color: #CD853F;
-	border-width: 1px 0px 0px 0px;
-	top: -10px;
-	left: -12px;
+  position: absolute;
+  width: 24px;
+  height: 0px;
+  border-style: solid;
+  border-color: #cd853f;
+  border-width: 1px 0px 0px 0px;
+  top: -10px;
+  left: -12px;
 }
 .mblDomButtonYellowStar > div > div > div {
-	position: absolute;
-	width: 0px;
-	height: 0px;
-	border-style: solid;
-	border-color: #FFFF00 transparent transparent transparent;
-	top: 0px;
-	left: 0px;
-	border-width: 9px 12px 0px 12px;
-	-webkit-transform: rotate(72deg);
+  position: absolute;
+  width: 0px;
+  height: 0px;
+  border-style: solid;
+  border-color: #ffff00 transparent transparent transparent;
+  top: 0px;
+  left: 0px;
+  border-width: 9px 12px 0px 12px;
+  -webkit-transform: rotate(72deg);
+  transform: rotate(72deg);
 }
 .mblDomButtonYellowStar > div > div > div > div {
-	position: absolute;
-	width: 0px;
-	height: 0px;
-	border-style: solid;
-	border-color: #FFFF00 transparent transparent transparent;
-	top: -10px;
-	left: -12px;
-	border-width: 9px 12px 0px 12px;
-	-webkit-transform: rotate(216deg);
+  position: absolute;
+  width: 0px;
+  height: 0px;
+  border-style: solid;
+  border-color: #ffff00 transparent transparent transparent;
+  top: -10px;
+  left: -12px;
+  border-width: 9px 12px 0px 12px;
+  -webkit-transform: rotate(216deg);
+  transform: rotate(216deg);
 }
diff --git a/dojox/mobile/themes/common/domButtons/DomButtonYellowStar.less b/dojox/mobile/themes/common/domButtons/DomButtonYellowStar.less
new file mode 100644
index 0000000..d44f774
--- /dev/null
+++ b/dojox/mobile/themes/common/domButtons/DomButtonYellowStar.less
@@ -0,0 +1,50 @@
+ at import "../css3.less";
+/* === Yellow Star ==*/
+.mblDomButtonYellowStar {
+	position: relative;
+	width: 29px;
+	height: 29px;
+}
+.mblDomButtonYellowStar > div {
+	position: absolute;
+	width: 0px;
+	height: 0px;
+	border-style: solid;
+	border-color: #ffff00 transparent transparent transparent;
+	top: 12px;
+	left: 3px;
+	border-width: 9px 12px 0px 12px;
+	.transform(rotate(0deg));
+}
+.mblDomButtonYellowStar > div > div {
+	position: absolute;
+	width: 24px;
+	height: 0px;
+	border-style: solid;
+	border-color: #cd853f;
+	border-width: 1px 0px 0px 0px;
+	top: -10px;
+	left: -12px;
+}
+.mblDomButtonYellowStar > div > div > div {
+	position: absolute;
+	width: 0px;
+	height: 0px;
+	border-style: solid;
+	border-color: #ffff00 transparent transparent transparent;
+	top: 0px;
+	left: 0px;
+	border-width: 9px 12px 0px 12px;
+	.transform(rotate(72deg));
+}
+.mblDomButtonYellowStar > div > div > div > div {
+	position: absolute;
+	width: 0px;
+	height: 0px;
+	border-style: solid;
+	border-color: #ffff00 transparent transparent transparent;
+	top: -10px;
+	left: -12px;
+	border-width: 9px 12px 0px 12px;
+	.transform(rotate(216deg));
+}
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackDownArrow16.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackDownArrow16.png
new file mode 100644
index 0000000..6bd2119
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackDownArrow16.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackLeftArrow16.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackLeftArrow16.png
new file mode 100644
index 0000000..e903602
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackLeftArrow16.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackRightArrow16.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackRightArrow16.png
new file mode 100644
index 0000000..a505d7b
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackRightArrow16.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackUpArrow16.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackUpArrow16.png
new file mode 100644
index 0000000..4e3f0f3
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonBlackUpArrow16.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayArrow_rtl.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayArrow_rtl.png
new file mode 100644
index 0000000..7305cab
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayArrow_rtl.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayCross.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayCross.png
new file mode 100644
index 0000000..ae546a5
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayCross.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayKnob.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayKnob.png
new file mode 100644
index 0000000..2d9765a
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayKnob.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayMinus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayMinus.png
new file mode 100644
index 0000000..306c182
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayMinus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayPlus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayPlus.png
new file mode 100644
index 0000000..2f6798a
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonGrayPlus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCross.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCross.png
new file mode 100644
index 0000000..571288b
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonRedCross.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteCross.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteCross.png
new file mode 100644
index 0000000..bb14743
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteCross.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteDownArrow16.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteDownArrow16.png
new file mode 100644
index 0000000..9dfb2c5
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteDownArrow16.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteLeftArrow16.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteLeftArrow16.png
new file mode 100644
index 0000000..fbe1ca1
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteLeftArrow16.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteMinus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteMinus.png
new file mode 100644
index 0000000..ed0f448
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteMinus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhitePlus.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhitePlus.png
index 4b2a010..d4cdeed 100644
Binary files a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhitePlus.png and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhitePlus.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteRightArrow16.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteRightArrow16.png
new file mode 100644
index 0000000..ee84063
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteRightArrow16.png differ
diff --git a/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteUpArrow16.png b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteUpArrow16.png
new file mode 100644
index 0000000..06acd29
Binary files /dev/null and b/dojox/mobile/themes/common/domButtons/compat/mblDomButtonWhiteUpArrow16.png differ
diff --git a/dojox/mobile/themes/common/transitions.css b/dojox/mobile/themes/common/transitions.css
index e3d7a33..7be765f 100644
--- a/dojox/mobile/themes/common/transitions.css
+++ b/dojox/mobile/themes/common/transitions.css
@@ -1,5 +1,6 @@
 @import url("transitions/dissolve.css");
 @import url("transitions/cover.css");
+ at import url("transitions/cube.css");
 @import url("transitions/reveal.css");
 @import url("transitions/slidev.css");
 @import url("transitions/coverv.css");
@@ -7,5 +8,6 @@
 @import url("transitions/swirl.css");
 @import url("transitions/scaleOut.css");
 @import url("transitions/scaleIn.css");
+ at import url("transitions/swap.css");
 @import url("transitions/zoomOut.css");
 @import url("transitions/zoomIn.css");
diff --git a/dojox/mobile/themes/common/transitions/cover.css b/dojox/mobile/themes/common/transitions/cover.css
index 5794f02..9db60bf 100644
--- a/dojox/mobile/themes/common/transitions/cover.css
+++ b/dojox/mobile/themes/common/transitions/cover.css
@@ -1,34 +1,36 @@
-.mblCover.mblOut {
-	z-index: -100;
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(0%,0px,-1px) !important;
+.mblCover {
+  -webkit-transition-property: none;
+  transition-property: none;
+  -webkit-transition-duration: 0s;
+  transition-duration: 0s;
 }
-.mblCover.mblOut.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .4s;
-	-webkit-transform: translate3d(0%,0px,0px) !important;
+.mblCover.mblTransition {
+  -webkit-transition-property: -webkit-transform;
+  transition-property: transform;
+  -webkit-transition-duration: 0.4s;
+  transition-duration: 0.4s;
 }
-.mblCover.mblIn {
-	z-index: 0;
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(100%,0px,0px) !important;
+.mblCover.mblOut {
+  z-index: -100;
+  -webkit-transform: translate3d(0%, 0px, -1px) !important;
+  transform: translate3d(0%, 0px, -1px) !important;
 }
-.mblCover.mblIn.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .4s;
-	-webkit-transform: translate3d(0%,0px,0px) !important;
+.mblCover.mblIn {
+  -webkit-transform: translate3d(100%, 0px, 0px) !important;
+  transform: translate3d(100%, 0px, 0px) !important;
 }
 .mblCover.mblIn.mblReverse {
-	-webkit-transform: translate3d(-100%,0px,0px) !important;
+  -webkit-transform: translate3d(-100%, 0px, 0px) !important;
+  transform: translate3d(-100%, 0px, 0px) !important;
 }
-.mblCover.mblIn.mblReverse.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transform: translate3d(0%,0px,0px) !important;
+.mblCover.mblOut.mblTransition,
+.mblCover.mblIn.mblTransition {
+  -webkit-transform: translate3d(0%, 0px, 0px) !important;
+  transform: translate3d(0%, 0px, 0px) !important;
 }
-.dj_android.dj_tablet .mblCover.mblOut.mblTransition,
-.dj_android.dj_tablet .mblCover.mblIn.mblTransition {
-	-webkit-transition-duration: .6s;
-	-webkit-transition-timing-function: linear;
+.dj_android.dj_tablet .mblCover.mblTransition {
+  -webkit-transition-duration: 0.6s;
+  transition-duration: 0.6s;
+  -webkit-transition-timing-function: linear;
+  transition-timing-function: linear;
 }
diff --git a/dojox/mobile/themes/common/transitions/cover.less b/dojox/mobile/themes/common/transitions/cover.less
new file mode 100644
index 0000000..4dcd124
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/cover.less
@@ -0,0 +1,27 @@
+ at import "../css3.less";
+.mblCover {
+	.transition-property(none);
+	.transition-duration(0s);
+}
+.mblCover.mblTransition {
+	.transition-property-transform();
+	.transition-duration(.4s);
+}
+.mblCover.mblOut {
+	z-index: -100;
+	.transform(translate3d(0%,0px,-1px) ) !important;
+}
+.mblCover.mblIn {
+	.transform(translate3d(100%,0px,0px) ) !important;
+}
+.mblCover.mblIn.mblReverse {
+	.transform(translate3d(-100%,0px,0px) ) !important;
+}
+.mblCover.mblOut.mblTransition,
+.mblCover.mblIn.mblTransition {
+	.transform(translate3d(0%,0px,0px) ) !important;
+}
+.dj_android.dj_tablet .mblCover.mblTransition {
+	.transition-duration(.6s);
+	.transition-timing-function(linear);
+}
diff --git a/dojox/mobile/themes/common/transitions/coverv.css b/dojox/mobile/themes/common/transitions/coverv.css
index 2c80e16..e3ce6d6 100644
--- a/dojox/mobile/themes/common/transitions/coverv.css
+++ b/dojox/mobile/themes/common/transitions/coverv.css
@@ -1,35 +1,36 @@
-.mblCoverv.mblOut {
-	z-index: -100;
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(0px,0%,-1px) !important;
+.mblCoverv {
+  -webkit-transition-property: none;
+  transition-property: none;
+  -webkit-transition-duration: 0s;
+  transition-duration: 0s;
 }
-.mblCoverv.mblOut.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .4s;
-	-webkit-transform: translate3d(0px,0%,0px) !important;
+.mblCoverv.mblTransition {
+  -webkit-transition-property: -webkit-transform;
+  transition-property: transform;
+  -webkit-transition-duration: 0.4s;
+  transition-duration: 0.4s;
 }
-.mblCoverv.mblIn {
-	z-index: 0;
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(0px,100%,0px) !important;
+.mblCoverv.mblOut {
+  z-index: -100;
+  -webkit-transform: translate3d(0px, 0%, -1px) !important;
+  transform: translate3d(0px, 0%, -1px) !important;
 }
-.mblCoverv.mblIn.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .4s;
-	-webkit-transform: translate3d(0px,0%,0px) !important;
+.mblCoverv.mblIn {
+  -webkit-transform: translate3d(0px, 100%, 0px) !important;
+  transform: translate3d(0px, 100%, 0px) !important;
 }
 .mblCoverv.mblIn.mblReverse {
-	-webkit-transition-property: none;
-	-webkit-transform: translate3d(0px,-100%,0px) !important;
+  -webkit-transform: translate3d(0px, -100%, 0px) !important;
+  transform: translate3d(0px, -100%, 0px) !important;
 }
-.mblCoverv.mblIn.mblReverse.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transform: translate3d(0px,0%,0px) !important;
+.mblCoverv.mblOut.mblTransition,
+.mblCoverv.mblIn.mblTransition {
+  -webkit-transform: translate3d(0px, 0%, 0px) !important;
+  transform: translate3d(0px, 0%, 0px) !important;
 }
-.dj_android.dj_tablet .mblCoverv.mblOut.mblTransition,
-.dj_android.dj_tablet .mblCoverv.mblIn.mblTransition {
-	-webkit-transition-duration: .6s;
-	-webkit-transition-timing-function: linear;
+.dj_android.dj_tablet .mblCoverv.mblTransition {
+  -webkit-transition-duration: 0.6s;
+  transition-duration: 0.6s;
+  -webkit-transition-timing-function: linear;
+  transition-timing-function: linear;
 }
diff --git a/dojox/mobile/themes/common/transitions/coverv.less b/dojox/mobile/themes/common/transitions/coverv.less
new file mode 100644
index 0000000..f817485
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/coverv.less
@@ -0,0 +1,27 @@
+ at import "../css3.less";
+.mblCoverv {
+	.transition-property(none);
+	.transition-duration(0s);
+}
+.mblCoverv.mblTransition {
+	.transition-property-transform();
+	.transition-duration(.4s);
+}
+.mblCoverv.mblOut {
+	z-index: -100;
+	.transform(translate3d(0px,0%,-1px) ) !important;
+}
+.mblCoverv.mblIn {
+	.transform(translate3d(0px,100%,0px) ) !important;
+}
+.mblCoverv.mblIn.mblReverse {
+	.transform(translate3d(0px,-100%,0px) ) !important;
+}
+.mblCoverv.mblOut.mblTransition,
+.mblCoverv.mblIn.mblTransition {
+	.transform(translate3d(0px,0%,0px) ) !important;
+}
+.dj_android.dj_tablet .mblCoverv.mblTransition {
+	.transition-duration(.6s);
+	.transition-timing-function(linear);
+}
diff --git a/dojox/mobile/themes/common/transitions/cube.css b/dojox/mobile/themes/common/transitions/cube.css
new file mode 100644
index 0000000..1072681
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/cube.css
@@ -0,0 +1,473 @@
+.mblCube {
+  -webkit-animation-duration: 0.8s;
+  animation-duration: 0.8s;
+  -webkit-animation-timing-function: linear;
+  animation-timing-function: linear;
+}
+.mblCube.mblOut {
+  -webkit-animation-name: mblCubeOut;
+  animation-name: mblCubeOut;
+  -webkit-transform-origin: 0% 50% !important;
+  transform-origin: 0% 50% !important;
+}
+.mblCube.mblIn {
+  -webkit-animation-name: mblCubeIn;
+  animation-name: mblCubeIn;
+  -webkit-transform-origin: 100% 50% !important;
+  transform-origin: 100% 50% !important;
+}
+ at -webkit-keyframes mblCubeOut {
+  0% {
+    -webkit-transform: scale(1, 1) skew(0deg, 0deg);
+  }
+  50% {
+    -webkit-transform: scale(0.5, 1) skew(0deg, 3deg);
+  }
+  100% {
+    -webkit-transform: scale(0, 1) skew(0deg, 0deg);
+  }
+}
+ at keyframes mblCubeOut {
+  0% {
+    transform: scale(1, 1) skew(0deg, 0deg);
+  }
+  50% {
+    transform: scale(0.5, 1) skew(0deg, 3deg);
+  }
+  100% {
+    transform: scale(0, 1) skew(0deg, 0deg);
+  }
+}
+ at -webkit-keyframes mblCubeIn {
+  0% {
+    -webkit-transform: scale(0, 1) skew(0deg, 0deg);
+  }
+  50% {
+    -webkit-transform: scale(0.5, 1) skew(0deg, -3deg);
+  }
+  100% {
+    -webkit-transform: scale(1, 1) skew(0deg, 0deg);
+  }
+}
+ at keyframes mblCubeIn {
+  0% {
+    transform: scale(0, 1) skew(0deg, 0deg);
+  }
+  50% {
+    transform: scale(0.5, 1) skew(0deg, -3deg);
+  }
+  100% {
+    transform: scale(1, 1) skew(0deg, 0deg);
+  }
+}
+.mblCube.mblOut.mblReverse {
+  -webkit-animation-name: mblCubeOutReverse;
+  animation-name: mblCubeOutReverse;
+  -webkit-transform-origin: 100% 50% !important;
+  transform-origin: 100% 50% !important;
+}
+.mblCube.mblIn.mblReverse {
+  -webkit-animation-name: mblCubeInReverse;
+  animation-name: mblCubeInReverse;
+  -webkit-transform-origin: 0% 50% !important;
+  transform-origin: 0% 50% !important;
+}
+ at -webkit-keyframes mblCubeOutReverse {
+  0% {
+    -webkit-transform: scale(1, 1) skew(0deg, 0deg);
+  }
+  50% {
+    -webkit-transform: scale(0.5, 1) skew(0deg, -3deg);
+  }
+  100% {
+    -webkit-transform: scale(0, 1) skew(0deg, 0deg);
+  }
+}
+ at keyframes mblCubeOutReverse {
+  0% {
+    transform: scale(1, 1) skew(0deg, 0deg);
+  }
+  50% {
+    transform: scale(0.5, 1) skew(0deg, -3deg);
+  }
+  100% {
+    transform: scale(0, 1) skew(0deg, 0deg);
+  }
+}
+ at -webkit-keyframes mblCubeInReverse {
+  0% {
+    -webkit-transform: scale(0, 1) skew(0deg, 0deg);
+  }
+  50% {
+    -webkit-transform: scale(0.5, 1) skew(0deg, 3deg);
+  }
+  100% {
+    -webkit-transform: scale(1, 1) skew(0deg, 0deg);
+  }
+}
+ at keyframes mblCubeInReverse {
+  0% {
+    transform: scale(0, 1) skew(0deg, 0deg);
+  }
+  50% {
+    transform: scale(0.5, 1) skew(0deg, 3deg);
+  }
+  100% {
+    transform: scale(1, 1) skew(0deg, 0deg);
+  }
+}
+.dj_ios .mblCube {
+  -webkit-transform-style: preserve-3d !important;
+}
+.dj_ios .mblCube.mblOut {
+  -webkit-animation-name: mblCubeOut_iphone;
+  animation-name: mblCubeOut_iphone;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+.dj_ios .mblCube.mblIn {
+  -webkit-animation-name: mblCubeIn_iphone;
+  animation-name: mblCubeIn_iphone;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+ at -webkit-keyframes mblCubeOut_iphone {
+  from {
+    -webkit-transform: scale3d(0.835, 0.835, 0.835) rotateY(0deg) translateZ(160px);
+  }
+  to {
+    -webkit-transform: scale3d(0.835, 0.835, 0.835) rotateY(-90deg) translateZ(160px);
+  }
+}
+ at keyframes mblCubeOut_iphone {
+  from {
+    transform: scale3d(0.835, 0.835, 0.835) rotateY(0deg) translateZ(160px);
+  }
+  to {
+    transform: scale3d(0.835, 0.835, 0.835) rotateY(-90deg) translateZ(160px);
+  }
+}
+ at -webkit-keyframes mblCubeIn_iphone {
+  from {
+    -webkit-transform: scale3d(0.835, 0.835, 0.835) rotateY(90deg) translateZ(160px);
+  }
+  to {
+    -webkit-transform: scale3d(0.835, 0.835, 0.835) rotateY(0deg) translateZ(160px);
+  }
+}
+ at keyframes mblCubeIn_iphone {
+  from {
+    transform: scale3d(0.835, 0.835, 0.835) rotateY(90deg) translateZ(160px);
+  }
+  to {
+    transform: scale3d(0.835, 0.835, 0.835) rotateY(0deg) translateZ(160px);
+  }
+}
+.dj_ios.dj_landscape .mblCube.mblOut {
+  -webkit-animation-name: mblCubeOut_iphone_l;
+  animation-name: mblCubeOut_iphone_l;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+.dj_ios.dj_landscape .mblCube.mblIn {
+  -webkit-animation-name: mblCubeIn_iphone_l;
+  animation-name: mblCubeIn_iphone_l;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+ at -webkit-keyframes mblCubeOut_iphone_l {
+  from {
+    -webkit-transform: scale3d(0.77, 0.77, 0.77) rotateY(0deg) translateZ(240px);
+  }
+  to {
+    -webkit-transform: scale3d(0.77, 0.77, 0.77) rotateY(-90deg) translateZ(240px);
+  }
+}
+ at keyframes mblCubeOut_iphone_l {
+  from {
+    transform: scale3d(0.77, 0.77, 0.77) rotateY(0deg) translateZ(240px);
+  }
+  to {
+    transform: scale3d(0.77, 0.77, 0.77) rotateY(-90deg) translateZ(240px);
+  }
+}
+ at -webkit-keyframes mblCubeIn_iphone_l {
+  from {
+    -webkit-transform: scale3d(0.77, 0.77, 0.77) rotateY(90deg) translateZ(240px);
+  }
+  to {
+    -webkit-transform: scale3d(0.77, 0.77, 0.77) rotateY(0deg) translateZ(240px);
+  }
+}
+ at keyframes mblCubeIn_iphone_l {
+  from {
+    transform: scale3d(0.77, 0.77, 0.77) rotateY(90deg) translateZ(240px);
+  }
+  to {
+    transform: scale3d(0.77, 0.77, 0.77) rotateY(0deg) translateZ(240px);
+  }
+}
+.dj_ios .mblCube.mblOut.mblReverse {
+  -webkit-animation-name: mblCubeOutReverse_iphone;
+  animation-name: mblCubeOutReverse_iphone;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+.dj_ios .mblCube.mblIn.mblReverse {
+  -webkit-animation-name: mblCubeInReverse_iphone;
+  animation-name: mblCubeInReverse_iphone;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+ at -webkit-keyframes mblCubeOutReverse_iphone {
+  from {
+    -webkit-transform: scale3d(0.835, 0.835, 0.835) rotateY(0deg) translateZ(160px);
+  }
+  to {
+    -webkit-transform: scale3d(0.835, 0.835, 0.835) rotateY(90deg) translateZ(160px);
+  }
+}
+ at keyframes mblCubeOutReverse_iphone {
+  from {
+    transform: scale3d(0.835, 0.835, 0.835) rotateY(0deg) translateZ(160px);
+  }
+  to {
+    transform: scale3d(0.835, 0.835, 0.835) rotateY(90deg) translateZ(160px);
+  }
+}
+ at -webkit-keyframes mblCubeInReverse_iphone {
+  from {
+    -webkit-transform: scale3d(0.835, 0.835, 0.835) rotateY(-90deg) translateZ(160px);
+  }
+  to {
+    -webkit-transform: scale3d(0.835, 0.835, 0.835) rotateY(0deg) translateZ(160px);
+  }
+}
+ at keyframes mblCubeInReverse_iphone {
+  from {
+    transform: scale3d(0.835, 0.835, 0.835) rotateY(-90deg) translateZ(160px);
+  }
+  to {
+    transform: scale3d(0.835, 0.835, 0.835) rotateY(0deg) translateZ(160px);
+  }
+}
+.dj_ios.dj_landscape .mblCube.mblOut.mblReverse {
+  -webkit-animation-name: mblCubeOutReverse_iphone_l;
+  animation-name: mblCubeOutReverse_iphone_l;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+.dj_ios.dj_landscape .mblCube.mblIn.mblReverse {
+  -webkit-animation-name: mblCubeInReverse_iphone_l;
+  animation-name: mblCubeInReverse_iphone_l;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+ at -webkit-keyframes mblCubeOutReverse_iphone_l {
+  from {
+    -webkit-transform: scale3d(0.77, 0.77, 0.77) rotateY(0deg) translateZ(240px);
+  }
+  to {
+    -webkit-transform: scale3d(0.77, 0.77, 0.77) rotateY(90deg) translateZ(240px);
+  }
+}
+ at keyframes mblCubeOutReverse_iphone_l {
+  from {
+    transform: scale3d(0.77, 0.77, 0.77) rotateY(0deg) translateZ(240px);
+  }
+  to {
+    transform: scale3d(0.77, 0.77, 0.77) rotateY(90deg) translateZ(240px);
+  }
+}
+ at -webkit-keyframes mblCubeInReverse_iphone_l {
+  from {
+    -webkit-transform: scale3d(0.77, 0.77, 0.77) rotateY(-90deg) translateZ(240px);
+  }
+  to {
+    -webkit-transform: scale3d(0.77, 0.77, 0.77) rotateY(0deg) translateZ(240px);
+  }
+}
+ at keyframes mblCubeInReverse_iphone_l {
+  from {
+    transform: scale3d(0.77, 0.77, 0.77) rotateY(-90deg) translateZ(240px);
+  }
+  to {
+    transform: scale3d(0.77, 0.77, 0.77) rotateY(0deg) translateZ(240px);
+  }
+}
+.dj_ipad.dj_ios .mblCube.mblOut {
+  -webkit-animation-name: mblCubeOut_ipad;
+  animation-name: mblCubeOut_ipad;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+.dj_ipad.dj_ios .mblCube.mblIn {
+  -webkit-animation-name: mblCubeIn_ipad;
+  animation-name: mblCubeIn_ipad;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+ at -webkit-keyframes mblCubeOut_ipad {
+  from {
+    -webkit-transform: scale3d(0.806, 0.806, 0.806) rotateY(0deg) translateZ(384px);
+  }
+  to {
+    -webkit-transform: scale3d(0.806, 0.806, 0.806) rotateY(-90deg) translateZ(384px);
+  }
+}
+ at keyframes mblCubeOut_ipad {
+  from {
+    transform: scale3d(0.806, 0.806, 0.806) rotateY(0deg) translateZ(384px);
+  }
+  to {
+    transform: scale3d(0.806, 0.806, 0.806) rotateY(-90deg) translateZ(384px);
+  }
+}
+ at -webkit-keyframes mblCubeIn_ipad {
+  from {
+    -webkit-transform: scale3d(0.806, 0.806, 0.806) rotateY(90deg) translateZ(384px);
+  }
+  to {
+    -webkit-transform: scale3d(0.806, 0.806, 0.806) rotateY(0deg) translateZ(384px);
+  }
+}
+ at keyframes mblCubeIn_ipad {
+  from {
+    transform: scale3d(0.806, 0.806, 0.806) rotateY(90deg) translateZ(384px);
+  }
+  to {
+    transform: scale3d(0.806, 0.806, 0.806) rotateY(0deg) translateZ(384px);
+  }
+}
+.dj_ipad.dj_ios.dj_landscape .mblCube.mblOut {
+  -webkit-animation-name: mblCubeOut_ipad_l;
+  animation-name: mblCubeOut_ipad_l;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+.dj_ipad.dj_ios.dj_landscape .mblCube.mblIn {
+  -webkit-animation-name: mblCubeIn_ipad_l;
+  animation-name: mblCubeIn_ipad_l;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+ at -webkit-keyframes mblCubeOut_ipad_l {
+  from {
+    -webkit-transform: scale3d(0.758, 0.758, 0.758) rotateY(0deg) translateZ(512px);
+  }
+  to {
+    -webkit-transform: scale3d(0.758, 0.758, 0.758) rotateY(-90deg) translateZ(512px);
+  }
+}
+ at keyframes mblCubeOut_ipad_l {
+  from {
+    transform: scale3d(0.758, 0.758, 0.758) rotateY(0deg) translateZ(512px);
+  }
+  to {
+    transform: scale3d(0.758, 0.758, 0.758) rotateY(-90deg) translateZ(512px);
+  }
+}
+ at -webkit-keyframes mblCubeIn_ipad_l {
+  from {
+    -webkit-transform: scale3d(0.758, 0.758, 0.758) rotateY(90deg) translateZ(512px);
+  }
+  to {
+    -webkit-transform: scale3d(0.758, 0.758, 0.758) rotateY(0deg) translateZ(512px);
+  }
+}
+ at keyframes mblCubeIn_ipad_l {
+  from {
+    transform: scale3d(0.758, 0.758, 0.758) rotateY(90deg) translateZ(512px);
+  }
+  to {
+    transform: scale3d(0.758, 0.758, 0.758) rotateY(0deg) translateZ(512px);
+  }
+}
+.dj_ipad.dj_ios .mblCube.mblOut.mblReverse {
+  -webkit-animation-name: mblCubeOutReverse_ipad;
+  animation-name: mblCubeOutReverse_ipad;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+.dj_ipad.dj_ios .mblCube.mblIn.mblReverse {
+  -webkit-animation-name: mblCubeInReverse_ipad;
+  animation-name: mblCubeInReverse_ipad;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+ at -webkit-keyframes mblCubeOutReverse_ipad {
+  from {
+    -webkit-transform: scale3d(0.806, 0.806, 0.806) rotateY(0deg) translateZ(384px);
+  }
+  to {
+    -webkit-transform: scale3d(0.806, 0.806, 0.806) rotateY(90deg) translateZ(384px);
+  }
+}
+ at keyframes mblCubeOutReverse_ipad {
+  from {
+    transform: scale3d(0.806, 0.806, 0.806) rotateY(0deg) translateZ(384px);
+  }
+  to {
+    transform: scale3d(0.806, 0.806, 0.806) rotateY(90deg) translateZ(384px);
+  }
+}
+ at -webkit-keyframes mblCubeInReverse_ipad {
+  from {
+    -webkit-transform: scale3d(0.806, 0.806, 0.806) rotateY(-90deg) translateZ(384px);
+  }
+  to {
+    -webkit-transform: scale3d(0.806, 0.806, 0.806) rotateY(0deg) translateZ(384px);
+  }
+}
+ at keyframes mblCubeInReverse_ipad {
+  from {
+    transform: scale3d(0.806, 0.806, 0.806) rotateY(-90deg) translateZ(384px);
+  }
+  to {
+    transform: scale3d(0.806, 0.806, 0.806) rotateY(0deg) translateZ(384px);
+  }
+}
+.dj_ipad.dj_ios.dj_landscape .mblCube.mblOut.mblReverse {
+  -webkit-animation-name: mblCubeOutReverse_ipad_l;
+  animation-name: mblCubeOutReverse_ipad_l;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+.dj_ipad.dj_ios.dj_landscape .mblCube.mblIn.mblReverse {
+  -webkit-animation-name: mblCubeInReverse_ipad_l;
+  animation-name: mblCubeInReverse_ipad_l;
+  -webkit-transform-origin: 50% 50% !important;
+  transform-origin: 50% 50% !important;
+}
+ at -webkit-keyframes mblCubeOutReverse_ipad_l {
+  from {
+    -webkit-transform: scale3d(0.758, 0.758, 0.758) rotateY(0deg) translateZ(512px);
+  }
+  to {
+    -webkit-transform: scale3d(0.758, 0.758, 0.758) rotateY(90deg) translateZ(512px);
+  }
+}
+ at keyframes mblCubeOutReverse_ipad_l {
+  from {
+    transform: scale3d(0.758, 0.758, 0.758) rotateY(0deg) translateZ(512px);
+  }
+  to {
+    transform: scale3d(0.758, 0.758, 0.758) rotateY(90deg) translateZ(512px);
+  }
+}
+ at -webkit-keyframes mblCubeInReverse_ipad_l {
+  from {
+    -webkit-transform: scale3d(0.758, 0.758, 0.758) rotateY(-90deg) translateZ(512px);
+  }
+  to {
+    -webkit-transform: scale3d(0.758, 0.758, 0.758) rotateY(0deg) translateZ(512px);
+  }
+}
+ at keyframes mblCubeInReverse_ipad_l {
+  from {
+    transform: scale3d(0.758, 0.758, 0.758) rotateY(-90deg) translateZ(512px);
+  }
+  to {
+    transform: scale3d(0.758, 0.758, 0.758) rotateY(0deg) translateZ(512px);
+  }
+}
diff --git a/dojox/mobile/themes/common/transitions/cube.less b/dojox/mobile/themes/common/transitions/cube.less
new file mode 100644
index 0000000..1fa3b1c
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/cube.less
@@ -0,0 +1,130 @@
+ at import "../css3.less";
+.mblCube {
+	.animation-duration(.8s);
+	.animation-timing-function(linear);
+}
+.mblCube.mblOut {
+	.animation-name(mblCubeOut);
+	.transform-origin(0% 50% ) !important;
+}
+.mblCube.mblIn {
+	.animation-name(mblCubeIn);
+	.transform-origin(100% 50% ) !important;
+}
+ at -webkit-keyframes mblCubeOut { .keyframes-transform-0-50-100-webkit(scale(1,1) skew(0deg,0deg), scale(.5,1) skew(0deg,3deg), scale(0,1) skew(0deg,0deg)); }
+ at keyframes         mblCubeOut { .keyframes-transform-0-50-100       (scale(1,1) skew(0deg,0deg), scale(.5,1) skew(0deg,3deg), scale(0,1) skew(0deg,0deg)); }
+ at -webkit-keyframes mblCubeIn { .keyframes-transform-0-50-100-webkit(scale(0,1) skew(0deg,0deg), scale(.5,1) skew(0deg,-3deg), scale(1,1) skew(0deg,0deg)); }
+ at keyframes         mblCubeIn { .keyframes-transform-0-50-100       (scale(0,1) skew(0deg,0deg), scale(.5,1) skew(0deg,-3deg), scale(1,1) skew(0deg,0deg)); }
+.mblCube.mblOut.mblReverse {
+	.animation-name(mblCubeOutReverse);
+	.transform-origin(100% 50% ) !important;
+}
+.mblCube.mblIn.mblReverse {
+	.animation-name(mblCubeInReverse);
+	.transform-origin(0% 50% ) !important;
+}
+ at -webkit-keyframes mblCubeOutReverse { .keyframes-transform-0-50-100-webkit(scale(1,1) skew(0deg,0deg), scale(.5,1) skew(0deg,-3deg), scale(0,1) skew(0deg,0deg)); }
+ at keyframes         mblCubeOutReverse { .keyframes-transform-0-50-100       (scale(1,1) skew(0deg,0deg), scale(.5,1) skew(0deg,-3deg), scale(0,1) skew(0deg,0deg)); }
+ at -webkit-keyframes mblCubeInReverse { .keyframes-transform-0-50-100-webkit(scale(0,1) skew(0deg,0deg), scale(.5,1) skew(0deg,3deg), scale(1,1) skew(0deg,0deg)); }
+ at keyframes         mblCubeInReverse { .keyframes-transform-0-50-100       (scale(0,1) skew(0deg,0deg), scale(.5,1) skew(0deg,3deg), scale(1,1) skew(0deg,0deg)); }
+
+.dj_ios .mblCube {
+	.transform-style(preserve-3d) !important;
+}
+.dj_ios .mblCube.mblOut {
+	.animation-name(mblCubeOut_iphone);
+	.transform-origin(50% 50% ) !important;
+}
+.dj_ios .mblCube.mblIn {
+	.animation-name(mblCubeIn_iphone);
+	.transform-origin(50% 50% ) !important;
+}
+ at -webkit-keyframes mblCubeOut_iphone { .keyframes-transform-from-to-webkit(scale3d(0.835,0.835,0.835) rotateY(0deg) translateZ(160px), scale3d(0.835,0.835,0.835) rotateY(-90deg) translateZ(160px)); }
+ at keyframes         mblCubeOut_iphone { .keyframes-transform-from-to       (scale3d(0.835,0.835,0.835) rotateY(0deg) translateZ(160px), scale3d(0.835,0.835,0.835) rotateY(-90deg) translateZ(160px)); }
+ at -webkit-keyframes mblCubeIn_iphone { .keyframes-transform-from-to-webkit(scale3d(0.835,0.835,0.835) rotateY(90deg) translateZ(160px), scale3d(0.835,0.835,0.835) rotateY(0deg) translateZ(160px)); }
+ at keyframes         mblCubeIn_iphone { .keyframes-transform-from-to       (scale3d(0.835,0.835,0.835) rotateY(90deg) translateZ(160px), scale3d(0.835,0.835,0.835) rotateY(0deg) translateZ(160px)); }
+.dj_ios.dj_landscape .mblCube.mblOut {
+	.animation-name(mblCubeOut_iphone_l);
+	.transform-origin(50% 50% ) !important;
+}
+.dj_ios.dj_landscape .mblCube.mblIn {
+	.animation-name(mblCubeIn_iphone_l);
+	.transform-origin(50% 50% ) !important;
+}
+ at -webkit-keyframes mblCubeOut_iphone_l { .keyframes-transform-from-to-webkit(scale3d(0.77,0.77,0.77) rotateY(0deg) translateZ(240px), scale3d(0.77,0.77,0.77) rotateY(-90deg) translateZ(240px)); }
+ at keyframes         mblCubeOut_iphone_l { .keyframes-transform-from-to       (scale3d(0.77,0.77,0.77) rotateY(0deg) translateZ(240px), scale3d(0.77,0.77,0.77) rotateY(-90deg) translateZ(240px)); }
+ at -webkit-keyframes mblCubeIn_iphone_l { .keyframes-transform-from-to-webkit(scale3d(0.77,0.77,0.77) rotateY(90deg) translateZ(240px), scale3d(0.77,0.77,0.77) rotateY(0deg) translateZ(240px)); }
+ at keyframes         mblCubeIn_iphone_l { .keyframes-transform-from-to       (scale3d(0.77,0.77,0.77) rotateY(90deg) translateZ(240px), scale3d(0.77,0.77,0.77) rotateY(0deg) translateZ(240px)); }
+.dj_ios .mblCube.mblOut.mblReverse {
+	.animation-name(mblCubeOutReverse_iphone);
+	.transform-origin(50% 50% ) !important;
+}
+.dj_ios .mblCube.mblIn.mblReverse {
+	.animation-name(mblCubeInReverse_iphone);
+	.transform-origin(50% 50% ) !important;
+}
+ at -webkit-keyframes mblCubeOutReverse_iphone { .keyframes-transform-from-to-webkit(scale3d(0.835,0.835,0.835) rotateY(0deg) translateZ(160px), scale3d(0.835,0.835,0.835) rotateY(90deg) translateZ(160px)); }
+ at keyframes         mblCubeOutReverse_iphone { .keyframes-transform-from-to       (scale3d(0.835,0.835,0.835) rotateY(0deg) translateZ(160px), scale3d(0.835,0.835,0.835) rotateY(90deg) translateZ(160px)); }
+ at -webkit-keyframes mblCubeInReverse_iphone { .keyframes-transform-from-to-webkit(scale3d(0.835,0.835,0.835) rotateY(-90deg) translateZ(160px), scale3d(0.835,0.835,0.835) rotateY(0deg) translateZ(160px)); }
+ at keyframes         mblCubeInReverse_iphone { .keyframes-transform-from-to       (scale3d(0.835,0.835,0.835) rotateY(-90deg) translateZ(160px), scale3d(0.835,0.835,0.835) rotateY(0deg) translateZ(160px)); }
+.dj_ios.dj_landscape .mblCube.mblOut.mblReverse {
+	.animation-name(mblCubeOutReverse_iphone_l);
+	.transform-origin(50% 50% ) !important;
+}
+.dj_ios.dj_landscape .mblCube.mblIn.mblReverse {
+	.animation-name(mblCubeInReverse_iphone_l);
+	.transform-origin(50% 50% ) !important;
+}
+ at -webkit-keyframes mblCubeOutReverse_iphone_l { .keyframes-transform-from-to-webkit(scale3d(0.77,0.77,0.77) rotateY(0deg) translateZ(240px), scale3d(0.77,0.77,0.77) rotateY(90deg) translateZ(240px)); }
+ at keyframes         mblCubeOutReverse_iphone_l { .keyframes-transform-from-to       (scale3d(0.77,0.77,0.77) rotateY(0deg) translateZ(240px), scale3d(0.77,0.77,0.77) rotateY(90deg) translateZ(240px)); }
+ at -webkit-keyframes mblCubeInReverse_iphone_l { .keyframes-transform-from-to-webkit(scale3d(0.77,0.77,0.77) rotateY(-90deg) translateZ(240px), scale3d(0.77,0.77,0.77) rotateY(0deg) translateZ(240px)); }
+ at keyframes         mblCubeInReverse_iphone_l { .keyframes-transform-from-to       (scale3d(0.77,0.77,0.77) rotateY(-90deg) translateZ(240px), scale3d(0.77,0.77,0.77) rotateY(0deg) translateZ(240px)); }
+
+.dj_ipad.dj_ios .mblCube.mblOut {
+	.animation-name(mblCubeOut_ipad);
+	.transform-origin(50% 50% ) !important;
+}
+.dj_ipad.dj_ios .mblCube.mblIn {
+	.animation-name(mblCubeIn_ipad);
+	.transform-origin(50% 50% ) !important;
+}
+ at -webkit-keyframes mblCubeOut_ipad { .keyframes-transform-from-to-webkit(scale3d(0.806,0.806,0.806) rotateY(0deg) translateZ(384px), scale3d(0.806,0.806,0.806) rotateY(-90deg) translateZ(384px)); }
+ at keyframes         mblCubeOut_ipad { .keyframes-transform-from-to       (scale3d(0.806,0.806,0.806) rotateY(0deg) translateZ(384px), scale3d(0.806,0.806,0.806) rotateY(-90deg) translateZ(384px)); }
+ at -webkit-keyframes mblCubeIn_ipad { .keyframes-transform-from-to-webkit(scale3d(0.806,0.806,0.806) rotateY(90deg) translateZ(384px), scale3d(0.806,0.806,0.806) rotateY(0deg) translateZ(384px)); }
+ at keyframes         mblCubeIn_ipad { .keyframes-transform-from-to       (scale3d(0.806,0.806,0.806) rotateY(90deg) translateZ(384px), scale3d(0.806,0.806,0.806) rotateY(0deg) translateZ(384px)); }
+.dj_ipad.dj_ios.dj_landscape .mblCube.mblOut {
+	.animation-name(mblCubeOut_ipad_l);
+	.transform-origin(50% 50% ) !important;
+}
+.dj_ipad.dj_ios.dj_landscape .mblCube.mblIn {
+	.animation-name(mblCubeIn_ipad_l);
+	.transform-origin(50% 50% ) !important;
+}
+ at -webkit-keyframes mblCubeOut_ipad_l { .keyframes-transform-from-to-webkit(scale3d(0.758,0.758,0.758) rotateY(0deg) translateZ(512px), scale3d(0.758,0.758,0.758) rotateY(-90deg) translateZ(512px)); }
+ at keyframes         mblCubeOut_ipad_l { .keyframes-transform-from-to       (scale3d(0.758,0.758,0.758) rotateY(0deg) translateZ(512px), scale3d(0.758,0.758,0.758) rotateY(-90deg) translateZ(512px)); }
+ at -webkit-keyframes mblCubeIn_ipad_l { .keyframes-transform-from-to-webkit(scale3d(0.758,0.758,0.758) rotateY(90deg) translateZ(512px), scale3d(0.758,0.758,0.758) rotateY(0deg) translateZ(512px)); }
+ at keyframes         mblCubeIn_ipad_l { .keyframes-transform-from-to       (scale3d(0.758,0.758,0.758) rotateY(90deg) translateZ(512px), scale3d(0.758,0.758,0.758) rotateY(0deg) translateZ(512px)); }
+.dj_ipad.dj_ios .mblCube.mblOut.mblReverse {
+	.animation-name(mblCubeOutReverse_ipad);
+	.transform-origin(50% 50% ) !important;
+}
+.dj_ipad.dj_ios .mblCube.mblIn.mblReverse {
+	.animation-name(mblCubeInReverse_ipad);
+	.transform-origin(50% 50% ) !important;
+}
+ at -webkit-keyframes mblCubeOutReverse_ipad { .keyframes-transform-from-to-webkit(scale3d(0.806,0.806,0.806) rotateY(0deg) translateZ(384px), scale3d(0.806,0.806,0.806) rotateY(90deg) translateZ(384px)); }
+ at keyframes         mblCubeOutReverse_ipad { .keyframes-transform-from-to       (scale3d(0.806,0.806,0.806) rotateY(0deg) translateZ(384px), scale3d(0.806,0.806,0.806) rotateY(90deg) translateZ(384px)); }
+ at -webkit-keyframes mblCubeInReverse_ipad { .keyframes-transform-from-to-webkit(scale3d(0.806,0.806,0.806) rotateY(-90deg) translateZ(384px), scale3d(0.806,0.806,0.806) rotateY(0deg) translateZ(384px)); }
+ at keyframes         mblCubeInReverse_ipad { .keyframes-transform-from-to       (scale3d(0.806,0.806,0.806) rotateY(-90deg) translateZ(384px), scale3d(0.806,0.806,0.806) rotateY(0deg) translateZ(384px)); }
+.dj_ipad.dj_ios.dj_landscape .mblCube.mblOut.mblReverse {
+	.animation-name(mblCubeOutReverse_ipad_l);
+	.transform-origin(50% 50% ) !important;
+}
+.dj_ipad.dj_ios.dj_landscape .mblCube.mblIn.mblReverse {
+	.animation-name(mblCubeInReverse_ipad_l);
+	.transform-origin(50% 50% ) !important;
+}
+ at -webkit-keyframes mblCubeOutReverse_ipad_l { .keyframes-transform-from-to-webkit(scale3d(0.758,0.758,0.758) rotateY(0deg) translateZ(512px), scale3d(0.758,0.758,0.758) rotateY(90deg) translateZ(512px)); }
+ at keyframes         mblCubeOutReverse_ipad_l { .keyframes-transform-from-to       (scale3d(0.758,0.758,0.758) rotateY(0deg) translateZ(512px), scale3d(0.758,0.758,0.758) rotateY(90deg) translateZ(512px)); }
+ at -webkit-keyframes mblCubeInReverse_ipad_l { .keyframes-transform-from-to-webkit(scale3d(0.758,0.758,0.758) rotateY(-90deg) translateZ(512px), scale3d(0.758,0.758,0.758) rotateY(0deg) translateZ(512px)); }
+ at keyframes         mblCubeInReverse_ipad_l { .keyframes-transform-from-to       (scale3d(0.758,0.758,0.758) rotateY(-90deg) translateZ(512px), scale3d(0.758,0.758,0.758) rotateY(0deg) translateZ(512px)); }
diff --git a/dojox/mobile/themes/common/transitions/dissolve.css b/dojox/mobile/themes/common/transitions/dissolve.css
index 4cedc51..01d5739 100644
--- a/dojox/mobile/themes/common/transitions/dissolve.css
+++ b/dojox/mobile/themes/common/transitions/dissolve.css
@@ -1,18 +1,48 @@
 .mblDissolve.mblOut {
-	-webkit-animation-duration: 1s;
-	-webkit-animation-name: mblDissolveOut;
-	-webkit-animation-timing-function: cubic-bezier(.25,1,.75,0);
+  -webkit-animation-duration: 1s;
+  animation-duration: 1s;
+  -webkit-animation-name: mblDissolveOut;
+  animation-name: mblDissolveOut;
+  -webkit-animation-timing-function: cubic-bezier(0.25, 1, 0.75, 0);
+  animation-timing-function: cubic-bezier(0.25, 1, 0.75, 0);
 }
 .mblDissolve.mblIn {
-	-webkit-animation-duration: 1s;
-	-webkit-animation-name: mblDissolveIn;
-	-webkit-animation-timing-function: cubic-bezier(.25,1,.75,0);
+  -webkit-animation-duration: 1s;
+  animation-duration: 1s;
+  -webkit-animation-name: mblDissolveIn;
+  animation-name: mblDissolveIn;
+  -webkit-animation-timing-function: cubic-bezier(0.25, 1, 0.75, 0);
+  animation-timing-function: cubic-bezier(0.25, 1, 0.75, 0);
 }
 @-webkit-keyframes mblDissolveOut {
-	from { opacity: 1; }
-	to { opacity: 0; }
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
+}
+ at keyframes mblDissolveOut {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+  }
 }
 @-webkit-keyframes mblDissolveIn {
-	from { opacity: 0; }
-	to { opacity: 1; }
-}
\ No newline at end of file
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
+ at keyframes mblDissolveIn {
+  from {
+    opacity: 0;
+  }
+  to {
+    opacity: 1;
+  }
+}
diff --git a/dojox/mobile/themes/common/transitions/dissolve.less b/dojox/mobile/themes/common/transitions/dissolve.less
new file mode 100644
index 0000000..6c94db9
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/dissolve.less
@@ -0,0 +1,15 @@
+ at import "../css3.less";
+.mblDissolve.mblOut {
+	.animation-duration(1s);
+	.animation-name(mblDissolveOut);
+	.animation-timing-function(cubic-bezier(.25,1,.75,0));
+}
+.mblDissolve.mblIn {
+	.animation-duration(1s);
+	.animation-name(mblDissolveIn);
+	.animation-timing-function(cubic-bezier(.25,1,.75,0));
+}
+ at -webkit-keyframes mblDissolveOut { .keyframes-opacity-from-to(1, 0); }
+ at keyframes         mblDissolveOut { .keyframes-opacity-from-to(1, 0); }
+ at -webkit-keyframes mblDissolveIn { .keyframes-opacity-from-to(0, 1); }
+ at keyframes         mblDissolveIn { .keyframes-opacity-from-to(0, 1); }
diff --git a/dojox/mobile/themes/common/transitions/fade.css b/dojox/mobile/themes/common/transitions/fade.css
index 889231d..b54e709 100644
--- a/dojox/mobile/themes/common/transitions/fade.css
+++ b/dojox/mobile/themes/common/transitions/fade.css
@@ -1,22 +1,28 @@
+.mblFade {
+  -webkit-transition-property: none;
+  transition-property: none;
+  -webkit-transition-duration: 0s;
+  transition-duration: 0s;
+}
+.mblFade.mblTransition {
+  -webkit-transition-property: opacity;
+  transition-property: opacity;
+  -webkit-transition-duration: 0.6s;
+  transition-duration: 0.6s;
+}
 .mblFade.mblOut {
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	opacity: 1;
+  opacity: 1;
 }
 .mblFade.mblOut.mblTransition {
-	-webkit-transition-property: opacity;
-	-webkit-transition-duration: .6s;
-	-webkit-transition-timing-function: ease-out;
-	opacity: 0;
+  -webkit-transition-timing-function: ease-out;
+  transition-timing-function: ease-out;
+  opacity: 0;
 }
 .mblFade.mblIn {
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	opacity: 0;
+  opacity: 0;
 }
 .mblFade.mblIn.mblTransition {
-	-webkit-transition-property: opacity;
-	-webkit-transition-duration: .6s;
-	-webkit-transition-timing-function: ease-in;
-	opacity: 1;
-}
\ No newline at end of file
+  -webkit-transition-timing-function: ease-in;
+  transition-timing-function: ease-in;
+  opacity: 1;
+}
diff --git a/dojox/mobile/themes/common/transitions/fade.less b/dojox/mobile/themes/common/transitions/fade.less
new file mode 100644
index 0000000..4ac2f4a
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/fade.less
@@ -0,0 +1,23 @@
+ at import "../css3.less";
+.mblFade {
+	.transition-property(none);
+	.transition-duration(0s);
+}
+.mblFade.mblTransition {
+	.transition-property(opacity);
+	.transition-duration(.6s);
+}
+.mblFade.mblOut {
+	opacity: 1;
+}
+.mblFade.mblOut.mblTransition {
+	.transition-timing-function(ease-out);
+	opacity: 0;
+}
+.mblFade.mblIn {
+	opacity: 0;
+}
+.mblFade.mblIn.mblTransition {
+	.transition-timing-function(ease-in);
+	opacity: 1;
+}
diff --git a/dojox/mobile/themes/common/transitions/flip.css b/dojox/mobile/themes/common/transitions/flip.css
index 0617361..72767e6 100644
--- a/dojox/mobile/themes/common/transitions/flip.css
+++ b/dojox/mobile/themes/common/transitions/flip.css
@@ -1,35 +1,44 @@
+.mblFlip {
+  -webkit-transition-property: none;
+  transition-property: none;
+  -webkit-transition-duration: 0s;
+  transition-duration: 0s;
+}
+.mblFlip.mblTransition {
+  -webkit-transition-property: all;
+  transition-property: all;
+  -webkit-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  -webkit-transition-timing-function: linear;
+  transition-timing-function: linear;
+}
 .mblFlip.mblOut {
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	opacity: 1;
-	-webkit-transform: scale(1,1) skew(0,0) !important;
+  opacity: 1;
+  -webkit-transform: scale(1, 1) skew(0, 0) !important;
+  transform: scale(1, 1) skew(0, 0) !important;
 }
 .mblFlip.mblOut.mblTransition {
-	-webkit-transition-property: all;
-	-webkit-transition-duration: .2s;
-	-webkit-transition-timing-function: linear;
-	opacity: 0;
-	-webkit-transform: scale(0,0.8) skew(0,30deg) !important;
+  opacity: 0;
+  -webkit-transform: scale(0, 0.8) skew(0, 30deg) !important;
+  transform: scale(0, 0.8) skew(0, 30deg) !important;
 }
 .mblFlip.mblIn {
-	position: absolute;
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	opacity: 0;
-	-webkit-transform: scale(0,0.8) skew(0,-30deg) !important;
+  opacity: 0;
+  -webkit-transform: scale(0, 0.8) skew(0, -30deg) !important;
+  transform: scale(0, 0.8) skew(0, -30deg) !important;
 }
 .mblFlip.mblIn.mblTransition {
-	-webkit-transition-property: all;
-	-webkit-transition-delay: .2s;
-	-webkit-transition-duration: .2s;
-	-webkit-transition-timing-function: linear;
-	opacity: 1;
-	-webkit-transform: scale(1,1) skew(0,0) !important;
+  -webkit-transition-delay: 0.2s;
+  transition-delay: 0.2s;
+  opacity: 1;
+  -webkit-transform: scale(1, 1) skew(0, 0) !important;
+  transform: scale(1, 1) skew(0, 0) !important;
 }
-.dj_android.dj_tablet .mblFlip.mblOut.mblTransition {
-	-webkit-transition-duration: .4s;
+.dj_android.dj_tablet .mblFlip.mblTransition {
+  -webkit-transition-duration: 0.4s;
+  transition-duration: 0.4s;
 }
 .dj_android.dj_tablet .mblFlip.mblIn.mblTransition {
-	-webkit-transition-delay: .4s;
-	-webkit-transition-duration: .4s;
+  -webkit-transition-delay: 0.4s;
+  transition-delay: 0.4s;
 }
diff --git a/dojox/mobile/themes/common/transitions/flip.less b/dojox/mobile/themes/common/transitions/flip.less
new file mode 100644
index 0000000..431f506
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/flip.less
@@ -0,0 +1,33 @@
+ at import "../css3.less";
+.mblFlip {
+	.transition-property(none);
+	.transition-duration(0s);
+}
+.mblFlip.mblTransition {
+	.transition-property(all);
+	.transition-duration(.2s);
+	.transition-timing-function(linear);
+}
+.mblFlip.mblOut {
+	opacity: 1;
+	.transform(scale(1,1) skew(0,0) ) !important;
+}
+.mblFlip.mblOut.mblTransition {
+	opacity: 0;
+	.transform(scale(0,0.8) skew(0,30deg) ) !important;
+}
+.mblFlip.mblIn {
+	opacity: 0;
+	.transform(scale(0,0.8) skew(0,-30deg) ) !important;
+}
+.mblFlip.mblIn.mblTransition {
+	.transition-delay(.2s);
+	opacity: 1;
+	.transform(scale(1,1) skew(0,0) ) !important;
+}
+.dj_android.dj_tablet .mblFlip.mblTransition {
+	.transition-duration(.4s);
+}
+.dj_android.dj_tablet .mblFlip.mblIn.mblTransition {
+	.transition-delay(.4s);
+}
diff --git a/dojox/mobile/themes/common/transitions/reveal.css b/dojox/mobile/themes/common/transitions/reveal.css
index b711984..89cadbe 100644
--- a/dojox/mobile/themes/common/transitions/reveal.css
+++ b/dojox/mobile/themes/common/transitions/reveal.css
@@ -1,35 +1,39 @@
+.mblReveal {
+  -webkit-transition-property: none;
+  transition-property: none;
+  -webkit-transition-duration: 0s;
+  transition-duration: 0s;
+}
+.mblReveal.mblTransition {
+  -webkit-transition-property: -webkit-transform;
+  transition-property: transform;
+  -webkit-transition-duration: 0.4s;
+  transition-duration: 0.4s;
+}
 .mblReveal.mblOut {
-	z-index: 0;
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(0%,0px,0px) !important;
+  -webkit-transform: translate3d(0%, 0px, 0px) !important;
+  transform: translate3d(0%, 0px, 0px) !important;
 }
 .mblReveal.mblOut.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .4s;
-	-webkit-transform: translate3d(-100%,0px,0px) !important;
+  -webkit-transform: translate3d(-100%, 0px, 0px) !important;
+  transform: translate3d(-100%, 0px, 0px) !important;
+}
+.mblReveal.mblOut.mblReverse.mblTransition {
+  -webkit-transform: translate3d(100%, 0px, 0px) !important;
+  transform: translate3d(100%, 0px, 0px) !important;
 }
 .mblReveal.mblIn {
-	z-index: -100;
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(0%,0px,-1px) !important;
+  z-index: -100;
+  -webkit-transform: translate3d(0%, 0px, -1px) !important;
+  transform: translate3d(0%, 0px, -1px) !important;
 }
 .mblReveal.mblIn.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .4s;
-	-webkit-transform: translate3d(0%,0px,0px) !important;
-}
-.mblReveal.mblOut.mblReverse {
-	-webkit-transition-property: none;
-	-webkit-transform: translate3d(0%,0px,0px) !important;
-}
-.mblReveal.mblOut.mblReverse.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transform: translate3d(100%,0px,0px) !important;
+  -webkit-transform: translate3d(0%, 0px, 0px) !important;
+  transform: translate3d(0%, 0px, 0px) !important;
 }
-.dj_android.dj_tablet .mblReveal.mblOut.mblTransition,
-.dj_android.dj_tablet .mblReveal.mblIn.mblTransition {
-	-webkit-transition-duration: .6s;
-	-webkit-transition-timing-function: linear;
+.dj_android.dj_tablet .mblReveal.mblTransition {
+  -webkit-transition-duration: 0.6s;
+  transition-duration: 0.6s;
+  -webkit-transition-timing-function: linear;
+  transition-timing-function: linear;
 }
diff --git a/dojox/mobile/themes/common/transitions/reveal.less b/dojox/mobile/themes/common/transitions/reveal.less
new file mode 100644
index 0000000..31f8ab9
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/reveal.less
@@ -0,0 +1,29 @@
+ at import "../css3.less";
+.mblReveal {
+	.transition-property(none);
+	.transition-duration(0s);
+}
+.mblReveal.mblTransition {
+	.transition-property-transform();
+	.transition-duration(.4s);
+}
+.mblReveal.mblOut {
+	.transform(translate3d(0%,0px,0px) ) !important;
+}
+.mblReveal.mblOut.mblTransition {
+	.transform(translate3d(-100%,0px,0px) ) !important;
+}
+.mblReveal.mblOut.mblReverse.mblTransition {
+	.transform(translate3d(100%,0px,0px) ) !important;
+}
+.mblReveal.mblIn {
+	z-index: -100;
+	.transform(translate3d(0%,0px,-1px) ) !important;
+}
+.mblReveal.mblIn.mblTransition {
+	.transform(translate3d(0%,0px,0px) ) !important;
+}
+.dj_android.dj_tablet .mblReveal.mblTransition {
+	.transition-duration(.6s);
+	.transition-timing-function(linear);
+}
diff --git a/dojox/mobile/themes/common/transitions/revealv.css b/dojox/mobile/themes/common/transitions/revealv.css
index 3c74d46..d0967a3 100644
--- a/dojox/mobile/themes/common/transitions/revealv.css
+++ b/dojox/mobile/themes/common/transitions/revealv.css
@@ -1,31 +1,39 @@
+.mblRevealv {
+  -webkit-transition-property: none;
+  transition-property: none;
+  -webkit-transition-duration: 0s;
+  transition-duration: 0s;
+}
+.mblRevealv.mblTransition {
+  -webkit-transition-property: -webkit-transform;
+  transition-property: transform;
+  -webkit-transition-duration: 0.4s;
+  transition-duration: 0.4s;
+}
 .mblRevealv.mblOut {
-	z-index: 0;
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(0px,0%,0px) !important;
+  -webkit-transform: translate3d(0px, 0%, 0px) !important;
+  transform: translate3d(0px, 0%, 0px) !important;
 }
 .mblRevealv.mblOut.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .4s;
-	-webkit-transform: translate3d(0px,-100%,0px) !important;
+  -webkit-transform: translate3d(0px, -100%, 0px) !important;
+  transform: translate3d(0px, -100%, 0px) !important;
+}
+.mblRevealv.mblOut.mblReverse.mblTransition {
+  -webkit-transform: translate3d(0px, 100%, 0px) !important;
+  transform: translate3d(0px, 100%, 0px) !important;
 }
 .mblRevealv.mblIn {
-	z-index: -100;
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(0px,0%,-1px) !important;
+  z-index: -100;
+  -webkit-transform: translate3d(0px, 0%, -1px) !important;
+  transform: translate3d(0px, 0%, -1px) !important;
 }
 .mblRevealv.mblIn.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .4s;
-	-webkit-transform: translate3d(0px,0%,0px) !important;
-}
-.mblRevealv.mblOut.mblReverse.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transform: translate3d(0px,100%,0px) !important;
+  -webkit-transform: translate3d(0px, 0%, 0px) !important;
+  transform: translate3d(0px, 0%, 0px) !important;
 }
-.dj_android.dj_tablet .mblRevealv.mblOut.mblTransition,
-.dj_android.dj_tablet .mblRevealv.mblIn.mblTransition {
-	-webkit-transition-duration: .6s;
-	-webkit-transition-timing-function: linear;
+.dj_android.dj_tablet .mblRevealv.mblTransition {
+  -webkit-transition-duration: 0.6s;
+  transition-duration: 0.6s;
+  -webkit-transition-timing-function: linear;
+  transition-timing-function: linear;
 }
diff --git a/dojox/mobile/themes/common/transitions/revealv.less b/dojox/mobile/themes/common/transitions/revealv.less
new file mode 100644
index 0000000..1ccbbb1
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/revealv.less
@@ -0,0 +1,29 @@
+ at import "../css3.less";
+.mblRevealv {
+	.transition-property(none);
+	.transition-duration(0s);
+}
+.mblRevealv.mblTransition {
+	.transition-property-transform();
+	.transition-duration(.4s);
+}
+.mblRevealv.mblOut {
+	.transform(translate3d(0px,0%,0px) ) !important;
+}
+.mblRevealv.mblOut.mblTransition {
+	.transform(translate3d(0px,-100%,0px) ) !important;
+}
+.mblRevealv.mblOut.mblReverse.mblTransition {
+	.transform(translate3d(0px,100%,0px) ) !important;
+}
+.mblRevealv.mblIn {
+	z-index: -100;
+	.transform(translate3d(0px,0%,-1px) ) !important;
+}
+.mblRevealv.mblIn.mblTransition {
+	.transform(translate3d(0px,0%,0px) ) !important;
+}
+.dj_android.dj_tablet .mblRevealv.mblTransition {
+	.transition-duration(.6s);
+	.transition-timing-function(linear);
+}
diff --git a/dojox/mobile/themes/common/transitions/scaleIn.css b/dojox/mobile/themes/common/transitions/scaleIn.css
index 64e136c..59eeb56 100644
--- a/dojox/mobile/themes/common/transitions/scaleIn.css
+++ b/dojox/mobile/themes/common/transitions/scaleIn.css
@@ -1,33 +1,73 @@
 .mblScaleIn.mblOut {
-	z-index: -100;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-name: mblScaleInOut;
-	-webkit-animation-timing-function: ease-out;
+  z-index: -100;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-name: mblScaleInOut;
+  animation-name: mblScaleInOut;
+  -webkit-animation-timing-function: ease-out;
+  animation-timing-function: ease-out;
 }
 .mblScaleIn.mblIn {
-	z-index: 0;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-name: mblScaleInIn;
-	-webkit-animation-timing-function: ease-out;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-name: mblScaleInIn;
+  animation-name: mblScaleInIn;
+  -webkit-animation-timing-function: ease-out;
+  animation-timing-function: ease-out;
 }
 .dj_android .mblScaleIn.mblIn {
-	-webkit-animation-name: mblScaleInInAndroid;
+  -webkit-animation-name: mblScaleInInAndroid;
+  animation-name: mblScaleInInAndroid;
 }
 @-webkit-keyframes mblScaleInOut {
-	from { -webkit-transform: scale(1.0); }
-	to { -webkit-transform: scale(1.0); }
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(1);
+  }
+}
+ at keyframes mblScaleInOut {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(1);
+  }
 }
 @-webkit-keyframes mblScaleInIn {
-	from {
-		-webkit-transform: scale(0.0);
-		opacity: 0;
-	}
-	to {
-		-webkit-transform: scale(1.0);
-		opacity: 1;
-	}
+  from {
+    -webkit-transform: scale(0);
+    opacity: 0;
+  }
+  to {
+    -webkit-transform: scale(1);
+    opacity: 1;
+  }
+}
+ at keyframes mblScaleInIn {
+  from {
+    transform: scale(0);
+    opacity: 0;
+  }
+  to {
+    transform: scale(1);
+    opacity: 1;
+  }
 }
 @-webkit-keyframes mblScaleInInAndroid {
-	from { -webkit-transform: scale(0.0); }
-	to { -webkit-transform: scale(1.0); }
+  from {
+    -webkit-transform: scale(0);
+  }
+  to {
+    -webkit-transform: scale(1);
+  }
+}
+ at keyframes mblScaleInInAndroid {
+  from {
+    transform: scale(0);
+  }
+  to {
+    transform: scale(1);
+  }
 }
diff --git a/dojox/mobile/themes/common/transitions/scaleIn.less b/dojox/mobile/themes/common/transitions/scaleIn.less
new file mode 100644
index 0000000..c1105c8
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/scaleIn.less
@@ -0,0 +1,21 @@
+ at import "../css3.less";
+.mblScaleIn.mblOut {
+	z-index: -100;
+	.animation-duration(.5s);
+	.animation-name(mblScaleInOut);
+	.animation-timing-function(ease-out);
+}
+.mblScaleIn.mblIn {
+	.animation-duration(.5s);
+	.animation-name(mblScaleInIn);
+	.animation-timing-function(ease-out);
+}
+.dj_android .mblScaleIn.mblIn {
+	.animation-name(mblScaleInInAndroid);
+}
+ at -webkit-keyframes mblScaleInOut { .keyframes-transform-from-to-webkit(scale(1.0), scale(1.0)); }
+ at keyframes         mblScaleInOut { .keyframes-transform-from-to       (scale(1.0), scale(1.0)); }
+ at -webkit-keyframes mblScaleInIn { .keyframes-transform-opacity-from-to-webkit(scale(0.0), 0, scale(1.0), 1); }
+ at keyframes         mblScaleInIn { .keyframes-transform-opacity-from-to       (scale(0.0), 0, scale(1.0), 1); }
+ at -webkit-keyframes mblScaleInInAndroid { .keyframes-transform-from-to-webkit(scale(0.0), scale(1.0)); }
+ at keyframes         mblScaleInInAndroid { .keyframes-transform-from-to       (scale(0.0), scale(1.0)); }
diff --git a/dojox/mobile/themes/common/transitions/scaleOut.css b/dojox/mobile/themes/common/transitions/scaleOut.css
index d2f16e8..7d9c75f 100644
--- a/dojox/mobile/themes/common/transitions/scaleOut.css
+++ b/dojox/mobile/themes/common/transitions/scaleOut.css
@@ -1,33 +1,73 @@
 .mblScaleOut.mblOut {
-	z-index: 0;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-name: mblScaleOutOut;
-	-webkit-animation-timing-function: ease-in;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-name: mblScaleOutOut;
+  animation-name: mblScaleOutOut;
+  -webkit-animation-timing-function: ease-in;
+  animation-timing-function: ease-in;
 }
 .dj_android .mblScaleOut.mblOut {
-	-webkit-animation-name: mblScaleOutOutAndroid;
+  -webkit-animation-name: mblScaleOutOutAndroid;
+  animation-name: mblScaleOutOutAndroid;
 }
 .mblScaleOut.mblIn {
-	z-index: -100;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-name: mblScaleOutIn;
-	-webkit-animation-timing-function: ease-in;
+  z-index: -100;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-name: mblScaleOutIn;
+  animation-name: mblScaleOutIn;
+  -webkit-animation-timing-function: ease-in;
+  animation-timing-function: ease-in;
 }
 @-webkit-keyframes mblScaleOutOut {
-	from {
-		-webkit-transform: scale(1.0);
-		opacity: 1;
-	}
-	to {
-		-webkit-transform: scale(0.0);
-		opacity: 0;
-	}
+  from {
+    -webkit-transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(0);
+    opacity: 0;
+  }
+}
+ at keyframes mblScaleOutOut {
+  from {
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    transform: scale(0);
+    opacity: 0;
+  }
 }
 @-webkit-keyframes mblScaleOutOutAndroid {
-	from { -webkit-transform: scale(1.0); }
-	to { -webkit-transform: scale(0.0); }
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(0);
+  }
+}
+ at keyframes mblScaleOutOutAndroid {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(0);
+  }
 }
 @-webkit-keyframes mblScaleOutIn {
-	from { -webkit-transform: scale(1.0); }
-	to { -webkit-transform: scale(1.0); }
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(1);
+  }
+}
+ at keyframes mblScaleOutIn {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(1);
+  }
 }
diff --git a/dojox/mobile/themes/common/transitions/scaleOut.less b/dojox/mobile/themes/common/transitions/scaleOut.less
new file mode 100644
index 0000000..ca105b0
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/scaleOut.less
@@ -0,0 +1,21 @@
+ at import "../css3.less";
+.mblScaleOut.mblOut {
+	.animation-duration(.5s);
+	.animation-name(mblScaleOutOut);
+	.animation-timing-function(ease-in);
+}
+.dj_android .mblScaleOut.mblOut {
+	.animation-name(mblScaleOutOutAndroid);
+}
+.mblScaleOut.mblIn {
+	z-index: -100;
+	.animation-duration(.5s);
+	.animation-name(mblScaleOutIn);
+	.animation-timing-function(ease-in);
+}
+ at -webkit-keyframes mblScaleOutOut { .keyframes-transform-opacity-from-to-webkit(scale(1.0), 1, scale(0.0), 0); }
+ at keyframes         mblScaleOutOut { .keyframes-transform-opacity-from-to       (scale(1.0), 1, scale(0.0), 0); }
+ at -webkit-keyframes mblScaleOutOutAndroid { .keyframes-transform-from-to-webkit(scale(1.0), scale(0.0)); }
+ at keyframes         mblScaleOutOutAndroid { .keyframes-transform-from-to       (scale(1.0), scale(0.0)); }
+ at -webkit-keyframes mblScaleOutIn { .keyframes-transform-from-to-webkit(scale(1.0), scale(1.0)); }
+ at keyframes         mblScaleOutIn { .keyframes-transform-from-to       (scale(1.0), scale(1.0)); }
diff --git a/dojox/mobile/themes/common/transitions/slide.css b/dojox/mobile/themes/common/transitions/slide.css
index cd6b02e..0dd89c5 100644
--- a/dojox/mobile/themes/common/transitions/slide.css
+++ b/dojox/mobile/themes/common/transitions/slide.css
@@ -1,41 +1,33 @@
-.mblSlide.mblOut {
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(0%,0px,0px) !important;
-}
-.mblSlide.mblOut.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .3s;
-	-webkit-transform: translate3d(-100%,0px,0px) !important;
-}
+.mblSlide {
+  -webkit-transition-property: none;
+  transition-property: none;
+  -webkit-transition-duration: 0s;
+  transition-duration: 0s;
+}
+.mblSlide.mblTransition {
+  -webkit-transition-property: -webkit-transform;
+  transition-property: transform;
+  -webkit-transition-duration: 0.3s;
+  transition-duration: 0.3s;
+}
+.mblSlide.mblOut.mblReverse.mblTransition,
 .mblSlide.mblIn {
-	position: absolute !important;
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(100%,0px,0px) !important;
-}
-.mblSlide.mblIn.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .3s;
-	-webkit-transform: translate3d(0%,0px,0px) !important;
-}
-.mblSlide.mblOut.mblReverse {
-	-webkit-transition-property: none;
-	-webkit-transform: translate3d(0%,0px,0px) !important;
-}
-.mblSlide.mblOut.mblReverse.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transform: translate3d(100%,0px,0px) !important;
+  -webkit-transform: translate3d(100%, 0px, 0px) !important;
+  transform: translate3d(100%, 0px, 0px) !important;
 }
+.mblSlide.mblOut.mblTransition,
 .mblSlide.mblIn.mblReverse {
-	-webkit-transform: translate3d(-100%,0px,0px) !important;
+  -webkit-transform: translate3d(-100%, 0px, 0px) !important;
+  transform: translate3d(-100%, 0px, 0px) !important;
 }
-.mblSlide.mblIn.mblReverse.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transform: translate3d(0%,0px,0px) !important;
-}
-.dj_android.dj_tablet .mblSlide.mblOut.mblTransition,
-.dj_android.dj_tablet .mblSlide.mblIn.mblTransition {
-	-webkit-transition-duration: .6s;
-	-webkit-transition-timing-function: linear;
+.mblSlide.mblOut,
+.mblSlide.mblIn.mblTransition {
+  -webkit-transform: translate3d(0%, 0px, 0px) !important;
+  transform: translate3d(0%, 0px, 0px) !important;
+}
+.dj_android.dj_tablet .mblSlide.mblTransition {
+  -webkit-transition-duration: 0.6s;
+  transition-duration: 0.6s;
+  -webkit-transition-timing-function: linear;
+  transition-timing-function: linear;
 }
diff --git a/dojox/mobile/themes/common/transitions/slide.less b/dojox/mobile/themes/common/transitions/slide.less
new file mode 100644
index 0000000..06d77d2
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/slide.less
@@ -0,0 +1,25 @@
+ at import "../css3.less";
+.mblSlide {
+	.transition-property(none);
+	.transition-duration(0s);
+}
+.mblSlide.mblTransition {
+	.transition-property-transform();
+	.transition-duration(.3s);
+}
+.mblSlide.mblOut.mblReverse.mblTransition,
+.mblSlide.mblIn {
+	.transform(translate3d(100%,0px,0px) ) !important;
+}
+.mblSlide.mblOut.mblTransition,
+.mblSlide.mblIn.mblReverse {
+	.transform(translate3d(-100%,0px,0px) ) !important;
+}
+.mblSlide.mblOut,
+.mblSlide.mblIn.mblTransition {
+	.transform(translate3d(0%,0px,0px) ) !important;
+}
+.dj_android.dj_tablet .mblSlide.mblTransition {
+	.transition-duration(.6s);
+	.transition-timing-function(linear);
+}
diff --git a/dojox/mobile/themes/common/transitions/slidev.css b/dojox/mobile/themes/common/transitions/slidev.css
index 0f6a816..9debb0a 100644
--- a/dojox/mobile/themes/common/transitions/slidev.css
+++ b/dojox/mobile/themes/common/transitions/slidev.css
@@ -1,42 +1,33 @@
-.mblSlidev.mblOut {
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(0px,0%,0px) !important;
-}
-.mblSlidev.mblOut.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .3s;
-	-webkit-transform: translate3d(0px,-100%,0px) !important;
-}
+.mblSlidev {
+  -webkit-transition-property: none;
+  transition-property: none;
+  -webkit-transition-duration: 0s;
+  transition-duration: 0s;
+}
+.mblSlidev.mblTransition {
+  -webkit-transition-property: -webkit-transform;
+  transition-property: transform;
+  -webkit-transition-duration: 0.3s;
+  transition-duration: 0.3s;
+}
+.mblSlidev.mblOut.mblReverse.mblTransition,
 .mblSlidev.mblIn {
-	position: absolute !important;
-	-webkit-transition-property: none;
-	-webkit-transition-duration: 0s;
-	-webkit-transform: translate3d(0px,100%,0px) !important;
-}
-.mblSlidev.mblIn.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transition-duration: .3s;
-	-webkit-transform: translate3d(0px,0%,0px) !important;
-}
-.mblSlidev.mblOut.mblReverse {
-	-webkit-transition-property: none;
-	-webkit-transform: translate3d(0px,0%,0px) !important;
-}
-.mblSlidev.mblOut.mblReverse.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transform: translate3d(0px,100%,0px) !important;
+  -webkit-transform: translate3d(0px, 100%, 0px) !important;
+  transform: translate3d(0px, 100%, 0px) !important;
 }
+.mblSlidev.mblOut.mblTransition,
 .mblSlidev.mblIn.mblReverse {
-	-webkit-transform: translate3d(0px,-100%,0px) !important;
+  -webkit-transform: translate3d(0px, -100%, 0px) !important;
+  transform: translate3d(0px, -100%, 0px) !important;
 }
-.mblSlidev.mblIn.mblReverse.mblTransition {
-	-webkit-transition-property: -webkit-transform;
-	-webkit-transform: translate3d(0px,0%,0px) !important;
+.mblSlidev.mblOut,
+.mblSlidev.mblIn.mblTransition {
+  -webkit-transform: translate3d(0px, 0%, 0px) !important;
+  transform: translate3d(0px, 0%, 0px) !important;
 }
-.dj_android.dj_tablet .mblSlidev.mblOut.mblTransition,
-.dj_android.dj_tablet .mblSlidev.mblIn.mblTransition {
-	-webkit-transition-duration: .6s;
-	-webkit-transition-timing-function: linear;
+.dj_android.dj_tablet .mblSlidev.mblTransition {
+  -webkit-transition-duration: 0.6s;
+  transition-duration: 0.6s;
+  -webkit-transition-timing-function: linear;
+  transition-timing-function: linear;
 }
-
diff --git a/dojox/mobile/themes/common/transitions/slidev.less b/dojox/mobile/themes/common/transitions/slidev.less
new file mode 100644
index 0000000..5fd979f
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/slidev.less
@@ -0,0 +1,26 @@
+ at import "../css3.less";
+.mblSlidev {
+	.transition-property(none);
+	.transition-duration(0s);
+}
+.mblSlidev.mblTransition {
+	.transition-property-transform();
+	.transition-duration(.3s);
+}
+.mblSlidev.mblOut.mblReverse.mblTransition,
+.mblSlidev.mblIn {
+	.transform(translate3d(0px,100%,0px) ) !important;
+}
+.mblSlidev.mblOut.mblTransition,
+.mblSlidev.mblIn.mblReverse {
+	.transform(translate3d(0px,-100%,0px) ) !important;
+}
+.mblSlidev.mblOut,
+.mblSlidev.mblIn.mblTransition {
+	.transform(translate3d(0px,0%,0px) ) !important;
+}
+.dj_android.dj_tablet .mblSlidev.mblTransition {
+	.transition-duration(.6s);
+	.transition-timing-function(linear);
+}
+
diff --git a/dojox/mobile/themes/common/transitions/swap.css b/dojox/mobile/themes/common/transitions/swap.css
new file mode 100644
index 0000000..6118b4c
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/swap.css
@@ -0,0 +1,158 @@
+.mblSwap {
+  -webkit-animation-duration: 0.6s;
+  animation-duration: 0.6s;
+  -webkit-animation-timing-function: linear;
+  animation-timing-function: linear;
+}
+.mblSwap.mblOut {
+  -webkit-animation-name: mblSwapOut;
+  animation-name: mblSwapOut;
+}
+.mblSwap.mblIn {
+  -webkit-animation-name: mblSwapIn;
+  animation-name: mblSwapIn;
+}
+.mblSwap.mblOut.mblReverse {
+  -webkit-animation-name: mblSwapOutReverse;
+  animation-name: mblSwapOutReverse;
+}
+.mblSwap.mblIn.mblReverse {
+  -webkit-animation-name: mblSwapInReverse;
+  animation-name: mblSwapInReverse;
+}
+ at -webkit-keyframes mblSwapOut {
+  0% {
+    z-index: auto;
+    -webkit-transform: translate3d(0%, 0%, 0px) scale(1);
+    opacity: 1;
+  }
+  50% {
+    z-index: -60;
+    -webkit-transform: translate3d(-45%, 5%, 0px) scale(0.6);
+    opacity: 0.4;
+  }
+  100% {
+    z-index: -100;
+    -webkit-transform: translate3d(-20%, 10%, 0px) scale(0.4);
+    opacity: 0;
+  }
+}
+ at keyframes mblSwapOut {
+  0% {
+    z-index: auto;
+    transform: translate3d(0%, 0%, 0px) scale(1);
+    opacity: 1;
+  }
+  50% {
+    z-index: -60;
+    transform: translate3d(-45%, 5%, 0px) scale(0.6);
+    opacity: 0.4;
+  }
+  100% {
+    z-index: -100;
+    transform: translate3d(-20%, 10%, 0px) scale(0.4);
+    opacity: 0;
+  }
+}
+ at -webkit-keyframes mblSwapIn {
+  0% {
+    z-index: -100;
+    -webkit-transform: translate3d(-20%, 0%, 0px) scale(0.5);
+    opacity: 0.4;
+  }
+  50% {
+    z-index: -40;
+    -webkit-transform: translate3d(45%, 0%, 0px) scale(0.7);
+    opacity: 1;
+  }
+  100% {
+    z-index: auto;
+    -webkit-transform: translate3d(0%, 0%, 0px) scale(1);
+    opacity: 1;
+  }
+}
+ at keyframes mblSwapIn {
+  0% {
+    z-index: -100;
+    transform: translate3d(-20%, 0%, 0px) scale(0.5);
+    opacity: 0.4;
+  }
+  50% {
+    z-index: -40;
+    transform: translate3d(45%, 0%, 0px) scale(0.7);
+    opacity: 1;
+  }
+  100% {
+    z-index: auto;
+    transform: translate3d(0%, 0%, 0px) scale(1);
+    opacity: 1;
+  }
+}
+ at -webkit-keyframes mblSwapOutReverse {
+  0% {
+    z-index: auto;
+    -webkit-transform: translate3d(0%, 0%, 0px) scale(1);
+    opacity: 1;
+  }
+  50% {
+    z-index: -60;
+    -webkit-transform: translate3d(45%, 5%, 0px) scale(0.6);
+    opacity: 0.4;
+  }
+  100% {
+    z-index: -100;
+    -webkit-transform: translate3d(20%, 10%, 0px) scale(0.4);
+    opacity: 0;
+  }
+}
+ at keyframes mblSwapOutReverse {
+  0% {
+    z-index: auto;
+    transform: translate3d(0%, 0%, 0px) scale(1);
+    opacity: 1;
+  }
+  50% {
+    z-index: -60;
+    transform: translate3d(45%, 5%, 0px) scale(0.6);
+    opacity: 0.4;
+  }
+  100% {
+    z-index: -100;
+    transform: translate3d(20%, 10%, 0px) scale(0.4);
+    opacity: 0;
+  }
+}
+ at -webkit-keyframes mblSwapInReverse {
+  0% {
+    z-index: -100;
+    -webkit-transform: translate3d(20%, 0%, 0px) scale(0.5);
+    opacity: 0.4;
+  }
+  50% {
+    z-index: -40;
+    -webkit-transform: translate3d(-45%, 0%, 0px) scale(0.7);
+    opacity: 1;
+  }
+  100% {
+    z-index: auto;
+    -webkit-transform: translate3d(0%, 0%, 0px) scale(1);
+    opacity: 1;
+  }
+}
+ at keyframes mblSwapInReverse {
+  0% {
+    z-index: -100;
+    transform: translate3d(20%, 0%, 0px) scale(0.5);
+    opacity: 0.4;
+  }
+  50% {
+    z-index: -40;
+    transform: translate3d(-45%, 0%, 0px) scale(0.7);
+    opacity: 1;
+  }
+  100% {
+    z-index: auto;
+    transform: translate3d(0%, 0%, 0px) scale(1);
+    opacity: 1;
+  }
+}
diff --git a/dojox/mobile/themes/common/transitions/swap.less b/dojox/mobile/themes/common/transitions/swap.less
new file mode 100644
index 0000000..45ae5ff
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/swap.less
@@ -0,0 +1,25 @@
+ at import "../css3.less";
+.mblSwap {
+	.animation-duration(.6s);
+	.animation-timing-function(linear);
+}
+.mblSwap.mblOut {
+	.animation-name(mblSwapOut);
+}
+.mblSwap.mblIn {
+	.animation-name(mblSwapIn);
+}
+.mblSwap.mblOut.mblReverse {
+	.animation-name(mblSwapOutReverse);
+}
+.mblSwap.mblIn.mblReverse {
+	.animation-name(mblSwapInReverse);
+}
+ at -webkit-keyframes mblSwapOut { .keyframes-z-index-transform-opacity-0-50-100-webkit(auto, translate3d(0%,0%,0px) scale(1.0), 1, -60, translate3d(-45%,5%,0px) scale(.6), .4, -100, translate3d(-20%,10%,0px) scale(.4), 0); }
+ at keyframes         mblSwapOut { .keyframes-z-index-transform-opacity-0-50-100       (auto, translate3d(0%,0%,0px) scale(1.0), 1, -60, translate3d(-45%,5%,0px) scale(.6), .4, -100, translate3d(-20%,10%,0px) scale(.4), 0); }
+ at -webkit-keyframes mblSwapIn { .keyframes-z-index-transform-opacity-0-50-100-webkit(-100, translate3d(-20%,0%,0px) scale(.5), .4, -40, translate3d(45%,0%,0px) scale(.7), 1, auto, translate3d(0%,0%,0px) scale(1.0), 1); }
+ at keyframes         mblSwapIn { .keyframes-z-index-transform-opacity-0-50-100       (-100, translate3d(-20%,0%,0px) scale(.5), .4, -40, translate3d(45%,0%,0px) scale(.7), 1, auto, translate3d(0%,0%,0px) scale(1.0), 1); }
+ at -webkit-keyframes mblSwapOutReverse { .keyframes-z-index-transform-opacity-0-50-100-webkit(auto, translate3d(0%,0%,0px) scale(1.0), 1, -60, translate3d(45%,5%,0px) scale(.6), .4, -100, translate3d(20%,10%,0px) scale(.4), 0); }
+ at keyframes         mblSwapOutReverse { .keyframes-z-index-transform-opacity-0-50-100       (auto, translate3d(0%,0%,0px) scale(1.0), 1, -60, translate3d(45%,5%,0px) scale(.6), .4, -100, translate3d(20%,10%,0px) scale(.4), 0); }
+ at -webkit-keyframes mblSwapInReverse { .keyframes-z-index-transform-opacity-0-50-100-webkit(-100, translate3d(20%,0%,0px) scale(.5), .4, -40, translate3d(-45%,0%,0px) scale(.7), 1, auto, translate3d(0%,0%,0px) scale(1.0), 1); }
+ at keyframes         mblSwapInReverse { .keyframes-z-index-transform-opacity-0-50-100       (-100, translate3d(20%,0%,0px) scale(.5), .4, -40, translate3d(-45%,0%,0px) scale(.7), 1, auto, translate3d(0%,0%,0px) scale(1.0), 1); }
diff --git a/dojox/mobile/themes/common/transitions/swirl.css b/dojox/mobile/themes/common/transitions/swirl.css
index 529a931..ea58c85 100644
--- a/dojox/mobile/themes/common/transitions/swirl.css
+++ b/dojox/mobile/themes/common/transitions/swirl.css
@@ -1,27 +1,69 @@
 .mblSwirl.mblOut {
-	z-index: 0;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-name: mblSwirlOut;
-	-webkit-animation-timing-function: ease-in;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-name: mblSwirlOut;
+  animation-name: mblSwirlOut;
+  -webkit-animation-timing-function: ease-in;
+  animation-timing-function: ease-in;
 }
 .mblSwirl.mblIn {
-	z-index: -100;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-name: mblSwirlIn;
-	-webkit-animation-timing-function: ease-in;
+  z-index: -100;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-name: mblSwirlIn;
+  animation-name: mblSwirlIn;
+  -webkit-animation-timing-function: ease-in;
+  animation-timing-function: ease-in;
 }
 .mblSwirl.mblOut.mblReverse {
-	-webkit-animation-name: mblSwirlOutReverse;
+  -webkit-animation-name: mblSwirlOutReverse;
+  animation-name: mblSwirlOutReverse;
 }
 @-webkit-keyframes mblSwirlOut {
-	from { -webkit-transform: rotate(0deg) scale(1.0); }
-	to { -webkit-transform: rotate(-360deg) scale(0.0); }
+  from {
+    -webkit-transform: rotate(0deg) scale(1);
+  }
+  to {
+    -webkit-transform: rotate(-360deg) scale(0);
+  }
+}
+ at keyframes mblSwirlOut {
+  from {
+    transform: rotate(0deg) scale(1);
+  }
+  to {
+    transform: rotate(-360deg) scale(0);
+  }
 }
 @-webkit-keyframes mblSwirlOutReverse {
-	from { -webkit-transform: rotate(0deg) scale(1.0); }
-	to { -webkit-transform: rotate(360deg) scale(0.0); }
+  from {
+    -webkit-transform: rotate(0deg) scale(1);
+  }
+  to {
+    -webkit-transform: rotate(360deg) scale(0);
+  }
+}
+ at keyframes mblSwirlOutReverse {
+  from {
+    transform: rotate(0deg) scale(1);
+  }
+  to {
+    transform: rotate(360deg) scale(0);
+  }
 }
 @-webkit-keyframes mblSwirlIn {
-	from { -webkit-transform: scale(1.0); }
-	to { -webkit-transform: scale(1.0); }
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(1);
+  }
+}
+ at keyframes mblSwirlIn {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(1);
+  }
 }
diff --git a/dojox/mobile/themes/common/transitions/swirl.less b/dojox/mobile/themes/common/transitions/swirl.less
new file mode 100644
index 0000000..8c5cae7
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/swirl.less
@@ -0,0 +1,21 @@
+ at import "../css3.less";
+.mblSwirl.mblOut {
+	.animation-duration(.5s);
+	.animation-name(mblSwirlOut);
+	.animation-timing-function(ease-in);
+}
+.mblSwirl.mblIn {
+	z-index: -100;
+	.animation-duration(.5s);
+	.animation-name(mblSwirlIn);
+	.animation-timing-function(ease-in);
+}
+.mblSwirl.mblOut.mblReverse {
+	.animation-name(mblSwirlOutReverse);
+}
+ at -webkit-keyframes mblSwirlOut { .keyframes-transform-from-to-webkit(rotate(0deg) scale(1.0), rotate(-360deg) scale(0.0)); }
+ at keyframes         mblSwirlOut { .keyframes-transform-from-to       (rotate(0deg) scale(1.0), rotate(-360deg) scale(0.0)); }
+ at -webkit-keyframes mblSwirlOutReverse { .keyframes-transform-from-to-webkit(rotate(0deg) scale(1.0), rotate(360deg) scale(0.0)); }
+ at keyframes         mblSwirlOutReverse { .keyframes-transform-from-to       (rotate(0deg) scale(1.0), rotate(360deg) scale(0.0)); }
+ at -webkit-keyframes mblSwirlIn { .keyframes-transform-from-to-webkit(scale(1.0), scale(1.0)); }
+ at keyframes         mblSwirlIn { .keyframes-transform-from-to       (scale(1.0), scale(1.0)); }
diff --git a/dojox/mobile/themes/common/transitions/zoomIn.css b/dojox/mobile/themes/common/transitions/zoomIn.css
index 4ed7eca..2e5b3c2 100644
--- a/dojox/mobile/themes/common/transitions/zoomIn.css
+++ b/dojox/mobile/themes/common/transitions/zoomIn.css
@@ -1,33 +1,73 @@
 .mblZoomIn.mblOut {
-	z-index: -100;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-name: mblZoomInOut;
-	-webkit-animation-timing-function: ease-out;
+  z-index: -100;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-name: mblZoomInOut;
+  animation-name: mblZoomInOut;
+  -webkit-animation-timing-function: ease-out;
+  animation-timing-function: ease-out;
 }
 .mblZoomIn.mblIn {
-	z-index: 0;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-name: mblZoomInIn;
-	-webkit-animation-timing-function: ease-out;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-name: mblZoomInIn;
+  animation-name: mblZoomInIn;
+  -webkit-animation-timing-function: ease-out;
+  animation-timing-function: ease-out;
 }
 .dj_android .mblZoomIn.mblIn {
-	-webkit-animation-name: mblZoomInInAndroid;
+  -webkit-animation-name: mblZoomInInAndroid;
+  animation-name: mblZoomInInAndroid;
 }
 @-webkit-keyframes mblZoomInOut {
-	from { -webkit-transform: scale(1.0); }
-	to { -webkit-transform: scale(1.0); }
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(1);
+  }
+}
+ at keyframes mblZoomInOut {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(1);
+  }
 }
 @-webkit-keyframes mblZoomInIn {
-	from {
-		-webkit-transform: scale(0.0);
-		opacity: 0;
-	}
-	to {
-		-webkit-transform: scale(1.0);
-		opacity: 1;
-	}
+  from {
+    -webkit-transform: scale(0);
+    opacity: 0;
+  }
+  to {
+    -webkit-transform: scale(1);
+    opacity: 1;
+  }
+}
+ at keyframes mblZoomInIn {
+  from {
+    transform: scale(0);
+    opacity: 0;
+  }
+  to {
+    transform: scale(1);
+    opacity: 1;
+  }
 }
 @-webkit-keyframes mblZoomInInAndroid {
-	from { -webkit-transform: scale(0.0); }
-	to { -webkit-transform: scale(1.0); }
+  from {
+    -webkit-transform: scale(0);
+  }
+  to {
+    -webkit-transform: scale(1);
+  }
+}
+ at keyframes mblZoomInInAndroid {
+  from {
+    transform: scale(0);
+  }
+  to {
+    transform: scale(1);
+  }
 }
diff --git a/dojox/mobile/themes/common/transitions/zoomIn.less b/dojox/mobile/themes/common/transitions/zoomIn.less
new file mode 100644
index 0000000..8d90902
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/zoomIn.less
@@ -0,0 +1,21 @@
+ at import "../css3.less";
+.mblZoomIn.mblOut {
+	z-index: -100;
+	.animation-duration(.5s);
+	.animation-name(mblZoomInOut);
+	.animation-timing-function(ease-out);
+}
+.mblZoomIn.mblIn {
+	.animation-duration(.5s);
+	.animation-name(mblZoomInIn);
+	.animation-timing-function(ease-out);
+}
+.dj_android .mblZoomIn.mblIn {
+	.animation-name(mblZoomInInAndroid);
+}
+ at -webkit-keyframes mblZoomInOut { .keyframes-transform-from-to-webkit(scale(1.0), scale(1.0)); }
+ at keyframes         mblZoomInOut { .keyframes-transform-from-to       (scale(1.0), scale(1.0)); }
+ at -webkit-keyframes mblZoomInIn { .keyframes-transform-opacity-from-to-webkit(scale(0.0), 0, scale(1.0), 1); }
+ at keyframes         mblZoomInIn { .keyframes-transform-opacity-from-to       (scale(0.0), 0, scale(1.0), 1); }
+ at -webkit-keyframes mblZoomInInAndroid { .keyframes-transform-from-to-webkit(scale(0.0), scale(1.0)); }
+ at keyframes         mblZoomInInAndroid { .keyframes-transform-from-to       (scale(0.0), scale(1.0)); }
diff --git a/dojox/mobile/themes/common/transitions/zoomOut.css b/dojox/mobile/themes/common/transitions/zoomOut.css
index 8a292d4..cb52091 100644
--- a/dojox/mobile/themes/common/transitions/zoomOut.css
+++ b/dojox/mobile/themes/common/transitions/zoomOut.css
@@ -1,33 +1,73 @@
 .mblZoomOut.mblOut {
-	z-index: 0;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-name: mblZoomOutOut;
-	-webkit-animation-timing-function: ease-in;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-name: mblZoomOutOut;
+  animation-name: mblZoomOutOut;
+  -webkit-animation-timing-function: ease-in;
+  animation-timing-function: ease-in;
 }
 .dj_android .mblZoomOut.mblOut {
-	-webkit-animation-name: mblZoomOutOutAndroid;
+  -webkit-animation-name: mblZoomOutOutAndroid;
+  animation-name: mblZoomOutOutAndroid;
 }
 .mblZoomOut.mblIn {
-	z-index: -100;
-	-webkit-animation-duration: .5s;
-	-webkit-animation-name: mblZoomOutIn;
-	-webkit-animation-timing-function: ease-in;
+  z-index: -100;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-name: mblZoomOutIn;
+  animation-name: mblZoomOutIn;
+  -webkit-animation-timing-function: ease-in;
+  animation-timing-function: ease-in;
 }
 @-webkit-keyframes mblZoomOutOut {
-	from {
-		-webkit-transform: scale(1.0);
-		opacity: 1;
-	}
-	to {
-		-webkit-transform: scale(0.0);
-		opacity: 0;
-	}
+  from {
+    -webkit-transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    -webkit-transform: scale(0);
+    opacity: 0;
+  }
+}
+ at keyframes mblZoomOutOut {
+  from {
+    transform: scale(1);
+    opacity: 1;
+  }
+  to {
+    transform: scale(0);
+    opacity: 0;
+  }
 }
 @-webkit-keyframes mblZoomOutOutAndroid {
-	from { -webkit-transform: scale(1.0); }
-	to { -webkit-transform: scale(0.0); }
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(0);
+  }
+}
+ at keyframes mblZoomOutOutAndroid {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(0);
+  }
 }
 @-webkit-keyframes mblZoomOutIn {
-	from { -webkit-transform: scale(1.0); }
-	to { -webkit-transform: scale(1.0); }
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(1);
+  }
+}
+ at keyframes mblZoomOutIn {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(1);
+  }
 }
diff --git a/dojox/mobile/themes/common/transitions/zoomOut.less b/dojox/mobile/themes/common/transitions/zoomOut.less
new file mode 100644
index 0000000..d595be1
--- /dev/null
+++ b/dojox/mobile/themes/common/transitions/zoomOut.less
@@ -0,0 +1,21 @@
+ at import "../css3.less";
+.mblZoomOut.mblOut {
+	.animation-duration(.5s);
+	.animation-name(mblZoomOutOut);
+	.animation-timing-function(ease-in);
+}
+.dj_android .mblZoomOut.mblOut {
+	.animation-name(mblZoomOutOutAndroid);
+}
+.mblZoomOut.mblIn {
+	z-index: -100;
+	.animation-duration(.5s);
+	.animation-name(mblZoomOutIn);
+	.animation-timing-function(ease-in);
+}
+ at -webkit-keyframes mblZoomOutOut { .keyframes-transform-opacity-from-to-webkit(scale(1.0), 1, scale(0.0), 0); }
+ at keyframes         mblZoomOutOut { .keyframes-transform-opacity-from-to       (scale(1.0), 1, scale(0.0), 0); }
+ at -webkit-keyframes mblZoomOutOutAndroid { .keyframes-transform-from-to-webkit(scale(1.0), scale(0.0)); }
+ at keyframes         mblZoomOutOutAndroid { .keyframes-transform-from-to       (scale(1.0), scale(0.0)); }
+ at -webkit-keyframes mblZoomOutIn { .keyframes-transform-from-to-webkit(scale(1.0), scale(1.0)); }
+ at keyframes         mblZoomOutIn { .keyframes-transform-from-to       (scale(1.0), scale(1.0)); }
diff --git a/dojox/mobile/themes/custom/Accordion-compat.css b/dojox/mobile/themes/custom/Accordion-compat.css
new file mode 100644
index 0000000..2e53bb9
--- /dev/null
+++ b/dojox/mobile/themes/custom/Accordion-compat.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.Accordion */
+.mblAccordionTitleSelected {
+  background-color: #e2e2e2;
+}
+.dj_gecko .mblAccordionTitleSelected {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+}
+.dj_ff3 .mblAccordionRoundRect {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitle:first-child {
+  -moz-border-radius-topleft: 8px;
+  -moz-border-radius-topright: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitleLast,
+.dj_ff3 .mblAccordionRoundRect .mblAccordionPane:last-child {
+  -moz-border-radius-bottomleft: 8px;
+  -moz-border-radius-bottomright: 8px;
+}
diff --git a/dojox/mobile/themes/custom/Accordion.css b/dojox/mobile/themes/custom/Accordion.css
new file mode 100644
index 0000000..c8e768f
--- /dev/null
+++ b/dojox/mobile/themes/custom/Accordion.css
@@ -0,0 +1,71 @@
+/* dojox.mobile.Accordion */
+.mblAccordion {
+  border-style: outset;
+  border-width: 1px;
+  border-color: #9b9b9b;
+}
+.mblAccordionRoundRect {
+  margin: 7px 9px 16px 9px;
+  padding: 0;
+  border: 1px solid #c0c0c0;
+  border-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitle:first-child {
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitleLast,
+.mblAccordionRoundRect .mblAccordionPane:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
+}
+.mblAccordionTitle {
+  position: relative;
+  height: 30px;
+  width: 100%;
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  line-height: 30px;
+  vertical-align: middle;
+  white-space: nowrap;
+  border-top: 1px solid #9b9b9b;
+  background-color: #c0c0c0;
+  background-image: none;
+  font-weight: normal;
+}
+.mblAccordionTitle:first-child {
+  border-top: none;
+}
+.mblAccordionTitleAnchor {
+  display: block;
+  height: 100%;
+  text-decoration: none;
+  white-space: nowrap;
+  color: #000000;
+  cursor: pointer;
+}
+.mblAccordionIconParent {
+  float: left;
+  margin: 6px 4px 0 6px;
+  line-height: normal;
+}
+.mblAccordionIconParent1 {
+  display: block;
+}
+.mblAccordionIconParent2 {
+  display: none;
+}
+.mblAccordionTitleSelected {
+  border-bottom: 1px solid #c0c0c0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
+  font-weight: bold;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent1 {
+  display: none;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent2 {
+  display: block;
+}
diff --git a/dojox/mobile/themes/custom/Button-compat.css b/dojox/mobile/themes/custom/Button-compat.css
index 32cc119..6970bd1 100644
--- a/dojox/mobile/themes/custom/Button-compat.css
+++ b/dojox/mobile/themes/custom/Button-compat.css
@@ -1,8 +1,41 @@
 /* dojox.mobile.Button */
 .mblButton {
-	background-image: url(compat/ui-widget-bg.png);
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
+  background-image: url(compat/button-bg.png);
+  background-repeat: repeat-x;
+}
+.mblButtonSelected {
+  background-image: url(compat/button-sel-bg.png);
+}
+.mblBlueButton {
+  background-image: url(compat/blue-button-bg.png);
+}
+.mblBlueButtonSelected {
+  background-image: url(compat/blue-button-sel-bg.png);
+}
+.mblRedButton {
+  background-image: url(compat/red-button-bg.png);
+}
+.mblRedButtonSelected {
+  background-image: url(compat/red-button-sel-bg.png);
+}
+.dj_gecko .mblButton {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+}
+.dj_gecko .mblButtonSelected {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_gecko .mblBlueButton {
+  background-image: -moz-linear-gradient(top, #48adfc 0%, #048bf4 100%);
+}
+.dj_gecko .mblBlueButtonSelected {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_gecko .mblRedButton {
+  background-image: -moz-linear-gradient(top, #fa9d58 0%, #ee4115 100%);
+}
+.dj_gecko .mblRedButtonSelected {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_ff3 .mblButton {
+  -moz-border-radius: 0;
 }
diff --git a/dojox/mobile/themes/custom/Button.css b/dojox/mobile/themes/custom/Button.css
index 92d7b63..53c54c5 100644
--- a/dojox/mobile/themes/custom/Button.css
+++ b/dojox/mobile/themes/custom/Button.css
@@ -1,48 +1,48 @@
 /* dojox.mobile.Button */
 .mblButton {
+  padding: 0 10px;
+  height: 29px;
+  border-style: outset;
+  border-width: 1px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
+  font-family: Helvetica;
+  line-height: 29px;
   cursor: pointer;
-  outline: none;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  padding: 0 8px;
-  height: 30px;
-  border: 1px outset #b5bcc7;
-  color: #131313;
-  font-size: 14px;
-  font-family: Helvetica;
-  font-weight: normal;
-  line-height: 30px;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-  -webkit-border-radius: 2px;
+  border: 1px solid #c0c0c0;
+  border-bottom-color: #9b9b9b;
+  border-radius: 0;
+  color: #000000;
+  font-size: 13px;
 }
-.mblButton.mblBlueButton {
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  color: #131313;
-  background-color: #0000FF;
+.mblButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
+  color: #ffffff;
 }
-.mblButton.mblBlueButtonSelected {
-  color: #000000;
-  border-color: #769dc0;
-  background-color: #000066;
+.mblButtonDisabled,
+.mblButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
 }
-.mblButton.mblRedButton {
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  color: #131313;
-  background-color: #FF0000;
+.mblBlueButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#48adfc), to(#048bf4));
+  background-image: linear-gradient(to bottom, #48adfc 0%, #048bf4 100%);
+  color: #ffffff;
 }
-.mblButton.mblRedButtonSelected {
-  color: #000000;
-  border-color: #769dc0;
-  background-color: #660000;
+.mblBlueButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
 }
-.mblButtonSelected {
-  color: #000000;
-  border-color: #769dc0;
-  background-color: #0064c2;
+.mblRedButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fa9d58), to(#ee4115));
+  background-image: linear-gradient(to bottom, #fa9d58 0%, #ee4115 100%);
+  color: #ffffff;
 }
-.mblButtonDisabled, .mblButton:disabled {
-  cursor: default;
-  color: grey;
-  border-color: grey;
-  background-color: #8fc9ff;
+.mblRedButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
 }
diff --git a/dojox/mobile/themes/custom/Button.less b/dojox/mobile/themes/custom/Button.less
deleted file mode 100644
index ab3a96c..0000000
--- a/dojox/mobile/themes/custom/Button.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Button.less";
diff --git a/dojox/mobile/themes/custom/Carousel.css b/dojox/mobile/themes/custom/Carousel.css
index a415950..4439d46 100644
--- a/dojox/mobile/themes/custom/Carousel.css
+++ b/dojox/mobile/themes/custom/Carousel.css
@@ -1,30 +1,17 @@
 /* dojox.mobile.Carousel */
 .mblCarousel {
   overflow: hidden;
+  height: 300px;
 }
-.mblCarouselBox {
+.mblCarouselSlot {
   position: relative;
   float: left;
-}
-.mblCarouselImg {
-  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
-  vertical-align: bottom;
-}
-.mblCarouselImgSelected {
-  border: 1px dashed #C0C0C0;
-  -webkit-box-shadow: none;
-}
-.mblCarouselImgHeaderText {
-  color: white;
-  font: 14px arial, helvetica, clean, sans-serif;
-}
-.mblCarouselImgFooterText {
-  color: white;
-  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: left;
+  box-sizing: border-box;
 }
 .mblCarouselHeaderBar {
-  background-color: #3A3A3B;
-  color: #B1B1B1;
+  background-color: #3a3a3b;
+  color: #b1b1b1;
   font: bold 16px arial, helvetica, clean, sans-serif;
   padding: 1px;
 }
@@ -58,3 +45,35 @@
   position: relative;
   text-align: center;
 }
+/* dojox.mobile._CarouselItem */
+.mblCarouselItem {
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblCarouselItemHeaderText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 8px;
+  margin-bottom: 5px;
+}
+.mblCarouselItemFooterText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 5px;
+  margin-bottom: 8px;
+}
+.mblCarouselItemImage {
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  vertical-align: bottom;
+}
+.mblCarouselItemBlank {
+  display: none;
+}
+.mblCarouselSlotSelected .mblCarouselItemImage {
+  opacity: 0.6;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
diff --git a/dojox/mobile/themes/custom/Carousel.less b/dojox/mobile/themes/custom/Carousel.less
deleted file mode 100644
index d717397..0000000
--- a/dojox/mobile/themes/custom/Carousel.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Carousel.less";
diff --git a/dojox/mobile/themes/custom/Carousel_rtl.css b/dojox/mobile/themes/custom/Carousel_rtl.css
new file mode 100644
index 0000000..6c8bc7a
--- /dev/null
+++ b/dojox/mobile/themes/custom/Carousel_rtl.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.Carousel Rtl */
+.mblCarouselItemRtl.mblCarouselSlot {
+  float: right;
+}
+.mblCarouselRtl .mblCarouselBtnContainer {
+  float: left;
+}
+.mblCarouselRtl .mblCarouselTitle {
+  margin: 2px 4px 2px 0px;
+}
+.mblCarouselRtl .mblCarouselHeaderBar .mblPageIndicator {
+  float: left;
+}
diff --git a/dojox/mobile/themes/custom/CheckBox-compat.css b/dojox/mobile/themes/custom/CheckBox-compat.css
index 7545638..60a31a0 100644
--- a/dojox/mobile/themes/custom/CheckBox-compat.css
+++ b/dojox/mobile/themes/custom/CheckBox-compat.css
@@ -1,26 +1,38 @@
 /* dojox.mobile.CheckBox */
 .mblCheckBox {
-	background-image: url(compat/ui-widget-bg.png);
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
-	-moz-appearance: none;
-	-o-appearance: none;
-	-ms-appearance: none;
-	appearance: none;
-	-o-transform: translateY(0.45em);
-	-ms-transform: translateY(0.45em);
-	transform: translateY(0.45em);
-}
-.mblCheckBoxChecked::after,
-.mblCheckBox:checked::after {
-	-moz-transform: rotate(45deg);
-	-o-transform: rotate(45deg);
-	-ms-transform: rotate(45deg);
-	transform: rotate(45deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
+  background-image: url(compat/button-bg.png);
+}
+.mblCheckBoxSelected {
+  background-image: url(compat/button-sel-bg.png);
+}
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblCheckBox {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+  -moz-appearance: none;
+}
+.dj_gecko .mblCheckBoxSelected {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_gecko .mblCheckBoxChecked,
+.dj_gecko .mblCheckBox:checked {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+}
+.dj_gecko .mblCheckBoxChecked::after,
+.dj_gecko .mblCheckBox:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblCheckBoxChecked.mblCheckBoxSelected,
+.dj_gecko .mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_ff3 .mblCheckBox {
+  -moz-border-radius: 0;
 }
diff --git a/dojox/mobile/themes/custom/CheckBox.css b/dojox/mobile/themes/custom/CheckBox.css
index 1891ba5..4618b3d 100644
--- a/dojox/mobile/themes/custom/CheckBox.css
+++ b/dojox/mobile/themes/custom/CheckBox.css
@@ -1,45 +1,54 @@
 /* dojox.mobile.CheckBox */
 .mblCheckBox {
   position: relative;
-  cursor: pointer;
-  outline: none;
-  -webkit-appearance: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
   margin: -0.5em 3px 0.3em 4px;
   width: 1em;
   height: 1em;
-  font-size: 18px;
-  border: 1px outset #b5bcc7;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-  -webkit-border-radius: 2px;
-  -webkit-transform: translatey(0.45em);
+  border-style: outset;
+  border-width: 1px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
+  font: inherit;
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  border: 1px solid #c0c0c0;
+  border-bottom-color: #9b9b9b;
+  border-radius: 0;
 }
 .mblCheckBoxSelected {
-  border-color: #769dc0;
-  background-color: #0064c2;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
 }
-.mblCheckBoxChecked, .mblCheckBox:checked {
-  border-color: #769dc0;
-  background-color: #007ef5;
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
 }
-.mblCheckBoxChecked::after, .mblCheckBox:checked::after {
+.mblCheckBoxChecked::after,
+.mblCheckBox:checked::after {
+  position: absolute;
   content: "";
   width: 0.3em;
   height: 0.6em;
-  position: absolute;
   top: 0;
   left: 0.3em;
-  border-color: #000000;
   border-width: 0.15em;
   border-style: none solid solid none;
   -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
   -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: #000000;
 }
-.mblCheckBoxChecked.mblCheckBoxSelected, .mblCheckBox:checked.mblCheckBoxSelected {
-  border-color: #769dc0;
-  background-color: #0064c2;
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
 }
-.mblCheckBoxChecked.mblCheckBoxSelected::after, .mblCheckBox:checked.mblCheckBoxSelected::after {
-  border-color: #000000;
+.mblCheckBoxChecked.mblCheckBoxSelected::after,
+.mblCheckBox:checked.mblCheckBoxSelected::after {
+  border-color: #ffffff;
 }
diff --git a/dojox/mobile/themes/custom/CheckBox.less b/dojox/mobile/themes/custom/CheckBox.less
deleted file mode 100644
index 09f93b2..0000000
--- a/dojox/mobile/themes/custom/CheckBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/CheckBox.less";
diff --git a/dojox/mobile/themes/custom/ComboBox-compat.css b/dojox/mobile/themes/custom/ComboBox-compat.css
index 09c7b38..c3297e3 100644
--- a/dojox/mobile/themes/custom/ComboBox-compat.css
+++ b/dojox/mobile/themes/custom/ComboBox-compat.css
@@ -1,7 +1,7 @@
 /* dojox.mobile.ComboBox */
-.dijitPopup {
-	-moz-box-shadow: 0px 0px 50px black;
-	-o-box-shadow: 0px 0px 50px black;
-	-ms-box-shadow: 0px 0px 50px black;
-	box-shadow: 0px 0px 50px black;
-}
\ No newline at end of file
+.dj_gecko .dijitPopup {
+  -moz-box-shadow: none;
+}
+.dj_gecko .mblComboBoxMenuItemSelected {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
diff --git a/dojox/mobile/themes/custom/ComboBox.css b/dojox/mobile/themes/custom/ComboBox.css
index 4247da7..8cdf200 100644
--- a/dojox/mobile/themes/custom/ComboBox.css
+++ b/dojox/mobile/themes/custom/ComboBox.css
@@ -5,8 +5,9 @@
   position: absolute;
   border: 0;
   background-color: transparent;
-  -webkit-box-shadow: 0px 0px 50px black;
-  -webkit-border-radius: 5px;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+  border-radius: 0;
 }
 .mblReset {
   margin: 0;
@@ -17,28 +18,31 @@
   color: inherit;
 }
 .mblComboBoxMenu {
-  overflow-y: hidden !important;
   position: relative;
+  overflow-y: hidden !important;
   overflow: hidden;
   border: 1px solid black;
-  background-color: #eff1f3;
-  -webkit-border-radius: 5px;
+  border-color: #000000;
+  border-radius: 0;
+  background-color: #ffffff;
+  color: #000000;
 }
 .mblComboBoxMenuItem {
-  white-space: nowrap;
-  text-align: left;
   padding: .1em .2em;
-  color: #131313;
   border-width: 1px 0 1px 0;
   border-style: solid;
-  border-color: #eff1f3;
+  text-align: left;
+  white-space: nowrap;
+  border-color: #ffffff;
+  color: inherit;
 }
 .mblComboBoxMenuItemSelected {
-  color: #000000;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
+  color: #ffffff;
 }
-.mblComboBoxMenuPreviousButton, .mblComboBoxMenuNextButton {
+.mblComboBoxMenuPreviousButton,
+.mblComboBoxMenuNextButton {
   font-style: italic;
   overflow: hidden;
 }
diff --git a/dojox/mobile/themes/custom/ComboBox.less b/dojox/mobile/themes/custom/ComboBox.less
deleted file mode 100644
index ab9458c..0000000
--- a/dojox/mobile/themes/custom/ComboBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ComboBox.less";
diff --git a/dojox/mobile/themes/custom/ComboBox_rtl.css b/dojox/mobile/themes/custom/ComboBox_rtl.css
new file mode 100644
index 0000000..01b9527
--- /dev/null
+++ b/dojox/mobile/themes/custom/ComboBox_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.ComboBox Rtl*/
+.mblComboBoxMenuItemRtl {
+  text-align: right;
+}
diff --git a/dojox/mobile/themes/custom/DatePicker.css b/dojox/mobile/themes/custom/DatePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/custom/DatePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/custom/EdgeToEdgeCategory-compat.css b/dojox/mobile/themes/custom/EdgeToEdgeCategory-compat.css
deleted file mode 100644
index f62bc07..0000000
--- a/dojox/mobile/themes/custom/EdgeToEdgeCategory-compat.css
+++ /dev/null
@@ -1,4 +0,0 @@
-/* dojox.mobile.EdgeToEdgeCategory */
-.mblEdgeToEdgeCategory {
-	background-image: url(compat/heading-bg.png);
-}
diff --git a/dojox/mobile/themes/custom/EdgeToEdgeCategory.css b/dojox/mobile/themes/custom/EdgeToEdgeCategory.css
index 289511f..a238610 100644
--- a/dojox/mobile/themes/custom/EdgeToEdgeCategory.css
+++ b/dojox/mobile/themes/custom/EdgeToEdgeCategory.css
@@ -1,19 +1,20 @@
 /* dojox.mobile.EdgeToEdgeCategory */
 .mblEdgeToEdgeCategory {
   position: relative;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
   margin: 0;
-  padding: 0 8px;
-  height: 30px;
-  border-bottom: 1px solid #b5bcc7;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(2.5%, #ffffff), color-stop(2.5%, rgba(255, 255, 255, 0.14)), color-stop(5%, rgba(255, 255, 255, 0.14)), color-stop(5%, rgba(255, 255, 255, 0.52)), color-stop(7.5%, rgba(255, 255, 255, 0.52)), color-stop(7.5%, rgba(255, 255, 255, 0.68)), color-stop(10%, rgba(255, 255, 255, 0.68)), color-stop(1, rgba(255, 255, 255, 0)));
-  font-size: 18px;
+  padding: 0 10px;
+  overflow: hidden;
   font-family: Helvetica;
-  font-weight: normal;
-  text-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px;
+  font-size: 16px;
+  font-weight: bold;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  height: 22px;
+  background-color: #dedede;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#dedede));
+  background-image: linear-gradient(to bottom, #f6f6f6 0%, #dedede 100%);
+  border-bottom: 1px solid #c0c0c0;
   color: #000000;
-  line-height: 32px;
+  text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
+  line-height: 22px;
 }
diff --git a/dojox/mobile/themes/custom/EdgeToEdgeCategory.less b/dojox/mobile/themes/custom/EdgeToEdgeCategory.less
deleted file mode 100644
index 3bb63da..0000000
--- a/dojox/mobile/themes/custom/EdgeToEdgeCategory.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/EdgeToEdgeCategory.less";
diff --git a/dojox/mobile/themes/custom/EdgeToEdgeList.css b/dojox/mobile/themes/custom/EdgeToEdgeList.css
index 9ea0ea4..b8a3fe9 100644
--- a/dojox/mobile/themes/custom/EdgeToEdgeList.css
+++ b/dojox/mobile/themes/custom/EdgeToEdgeList.css
@@ -1,12 +1,9 @@
 /* dojox.mobile.EdgeToEdgeList */
 .mblEdgeToEdgeList {
-  position: relative;
-  /* IE needs this */
-
   margin: 0;
   padding: 0;
-  background-color: #ffffff;
+  background-color: #000000;
 }
 .mblEdgeToEdgeList .mblListItem:last-child {
-  border-bottom-color: #b5bcc7;
+  border-bottom-color: #c0c0c0;
 }
diff --git a/dojox/mobile/themes/custom/EdgeToEdgeList.less b/dojox/mobile/themes/custom/EdgeToEdgeList.less
deleted file mode 100644
index 227627c..0000000
--- a/dojox/mobile/themes/custom/EdgeToEdgeList.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/EdgeToEdgeList.less";
diff --git a/dojox/mobile/themes/custom/FixedSplitter.css b/dojox/mobile/themes/custom/FixedSplitter.css
new file mode 100644
index 0000000..f53833d
--- /dev/null
+++ b/dojox/mobile/themes/custom/FixedSplitter.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.FixedSplitter */
+.mblFixedSplitter {
+  width: 100%;
+  height: 100%;
+}
+/* For FixedSplitter's child panes */
+.mblFixedSplitter > * {
+  position: absolute;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.mblFixedSplitterH > * {
+  height: 100%;
+  top: 0px;
+}
+.mblFixedSplitterV > * {
+  width: 100%;
+  left: 0px;
+}
diff --git a/dojox/mobile/themes/custom/FormLayout.css b/dojox/mobile/themes/custom/FormLayout.css
new file mode 100644
index 0000000..bb00da1
--- /dev/null
+++ b/dojox/mobile/themes/custom/FormLayout.css
@@ -0,0 +1,190 @@
+/* Single Column Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (max-width: 500px) {
+  .mblFormLayout.mblFormLayoutAuto fieldset {
+    padding-left: 0;
+    padding-right: 0;
+  }
+  /* A gap between rows */
+  .mblFormLayout.mblFormLayoutAuto > * + * {
+    margin-top: 0.6em;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 100%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'single' ***/
+.mblFormLayout.mblFormLayoutSingleCol fieldset {
+  padding-left: 0;
+  padding-right: 0;
+}
+/* A gap between rows */
+.mblFormLayout.mblFormLayoutSingleCol > * + * {
+  margin-top: 0.6em;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 100%;
+  box-sizing: border-box;
+}
+/* Two Columns Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (min-width: 500px) {
+  /* Form layout selector*/
+  .mblFormLayout.mblFormLayoutAuto {
+    display: table;
+    width: 100%;
+  }
+  /* Form rows */
+  .mblFormLayout.mblFormLayoutAuto > * {
+    display: table-row;
+  }
+  /* Form cells */
+  .mblFormLayout.mblFormLayoutAuto > * > * {
+    display: table-cell;
+    vertical-align: top;
+    padding: 0.5em 0;
+  }
+  /* Left cells */
+  .mblFormLayout.mblFormLayoutAuto > * > *:first-child {
+    width: 20%;
+    padding-right: 0.5em;
+  }
+  /* mblFormLayoutRightAlign optional selector definition */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child {
+    text-align: right;
+  }
+  /* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+    margin-right: 0;
+  }
+  /* The Slider sticks to its bounds when margin=10px */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+    display: inline-block;
+    margin-right: 10px;
+    margin-top: 0px;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 50%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'two' ***/
+/* Form layout selector*/
+.mblFormLayout.mblFormLayoutTwoCol {
+  display: table;
+  width: 100%;
+}
+/* Form rows */
+.mblFormLayout.mblFormLayoutTwoCol > * {
+  display: table-row;
+}
+/* Form cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > * {
+  display: table-cell;
+  vertical-align: top;
+  padding: 0.5em 0;
+}
+/* Left cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > *:first-child {
+  width: 20%;
+  padding-right: 0.5em;
+}
+/* mblFormLayoutRightAlign optional selector definition */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child {
+  text-align: right;
+}
+/* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+  margin-right: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+  display: inline-block;
+  margin-right: 10px;
+  margin-top: 0px;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 50%;
+  box-sizing: border-box;
+}
+/* Common Rules*/
+/**********************************************************************************************************************/
+.mblFormLayout fieldset {
+  border: none;
+  margin: 0;
+}
+/* Bold widget labels */
+.mblFormLayout > * > *:first-child {
+  font-weight: bold;
+}
+/* Whatever the screen width, force left margin of first elements and elements following a <br> */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Button"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ToggleButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.CheckBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Switch"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.RadioButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.SearchBox"] {
+  margin-left: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > .mblSlider:first-child {
+  display: inline-block;
+  margin-left: 10px;
+  margin-top: 0;
+  margin-bottom: 0;
+}
diff --git a/dojox/mobile/themes/custom/GridLayout.css b/dojox/mobile/themes/custom/GridLayout.css
new file mode 100644
index 0000000..628fd9f
--- /dev/null
+++ b/dojox/mobile/themes/custom/GridLayout.css
@@ -0,0 +1,24 @@
+/* dojox.mobile.GridLayout */
+.mblGridLayout {
+  width: 100%;
+  height: 100%;
+  padding: 0;
+}
+.mblGridLayout > div {
+  margin: 0;
+  border: 0;
+  padding: 0;
+  float: left;
+  min-height: 1px;
+}
+.mblGridItemFirstColumn {
+  clear: left;
+}
+.mblGridItemTerminator {
+  clear: both;
+}
+.mblGridItemLastItem:after {
+  content: "";
+  display: block;
+  clear: both;
+}
diff --git a/dojox/mobile/themes/custom/Heading-compat.css b/dojox/mobile/themes/custom/Heading-compat.css
index 74befb9..d704ff8 100644
--- a/dojox/mobile/themes/custom/Heading-compat.css
+++ b/dojox/mobile/themes/custom/Heading-compat.css
@@ -1,47 +1,10 @@
-/* mbl.widget.Heading */
+/* dojox.mobile.Heading */
 .mblHeading {
-	background-image: url(compat/heading-bg.png);
+  background-image: url(compat/heading-bg.png);
 }
 .mblHeadingSpanTitle {
-	white-space: normal;
+  white-space: normal;
 }
-
-/* Heading Arrow Button */
-.mblArrowButtonHead {
-	background-image: url(compat/ui-widget-bg.png);
-	-moz-transform-origin: left top;
-	-o-transform-origin: left top;
-	-ms-transform-origin: left top;
-	transform-origin: left top;
-	-moz-transform: scale(0.9, 0.99) rotate(45deg);
-	-o-transform: scale(0.9, 0.99) rotate(45deg);
-	-ms-transform: scale(0.9, 0.99) rotate(45deg);
-	transform: scale(0.9, 0.99) rotate(45deg);
-	left: 1px\9; /* IE7/8 hack */
-	_left: 9px; /* IE6 hack */
-	height: 32px\9; /* IE6/7/8 hack */
-	border-width: 0\9; /* IE6/7/8 hack */
-	background-image: url(compat/arrow-button-head.png)\9; /* IE6/7/8 hack */
-}
-.mblArrowButtonHead:not(:target) { /* IE9 hack */
-	background-image: url(compat/ui-widget-bg.png)\9;
-	left: 17px\9;
-	height: 21px\9;
-	border-width: 1px\9;
-}
-.mblArrowButtonBody {
-	-moz-border-radius-topright: 2px;
-	-moz-border-radius-bottomright: 2px;
-	-o-border-top-right-radius: 2px;
-	-o-border-bottom-right-radius: 2px;
-	-ms-border-top-right-radius: 2px;
-	-ms-border-bottom-right-radius: 2px;
-	border-top-right-radius: 2px;
-	border-bottom-right-radius: 2px;
-	background-image: url(compat/ui-widget-bg.png);
-}
-*html .mblArrowButtonBody { /* IE6 hack */
-	padding: 0px 10px 0px 3px;
-	top: 0px;
-	left: 17px;
+.dj_gecko .mblHeading {
+  background-image: -moz-linear-gradient(top, #f6f6f6 0%, #dedede 100%);
 }
diff --git a/dojox/mobile/themes/custom/Heading.css b/dojox/mobile/themes/custom/Heading.css
index 86bd3b4..06251c1 100644
--- a/dojox/mobile/themes/custom/Heading.css
+++ b/dojox/mobile/themes/custom/Heading.css
@@ -1,24 +1,25 @@
 /* dojox.mobile.Heading */
 .mblHeading {
   position: relative;
-  margin: 0px;
+  margin: 0;
   width: 100%;
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
   z-index: 1;
   padding: 0;
-  height: 40px;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(2.5%, #ffffff), color-stop(2.5%, rgba(255, 255, 255, 0.14)), color-stop(5%, rgba(255, 255, 255, 0.14)), color-stop(5%, rgba(255, 255, 255, 0.52)), color-stop(7.5%, rgba(255, 255, 255, 0.52)), color-stop(7.5%, rgba(255, 255, 255, 0.68)), color-stop(10%, rgba(255, 255, 255, 0.68)), color-stop(1, rgba(255, 255, 255, 0)));
-  border-bottom: 1px solid #769dc0;
-  color: #131313;
-  font-size: 18px;
+  height: 42px;
   font-family: Helvetica;
-  font-weight: normal;
-  text-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px;
+  font-size: 20px;
+  font-weight: bold;
   text-align: center;
-  line-height: 42px;
+  line-height: 44px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#dedede));
+  background-image: linear-gradient(to bottom, #f6f6f6 0%, #dedede 100%);
+  border-top: 1px solid #c0c0c0;
+  border-bottom: 1px solid #c0c0c0;
+  color: #000000;
+  text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
 }
 .mblHeading * {
   z-index: 2;
@@ -27,7 +28,7 @@
   position: absolute;
   width: 100%;
   display: none;
-  left: 0px;
+  left: 0;
   z-index: 1;
 }
 .mblHeadingCenterTitle .mblHeadingDivTitle {
@@ -36,50 +37,3 @@
 .mblHeadingCenterTitle .mblHeadingSpanTitle {
   display: none;
 }
-/* Heading Arrow Button */
-.mblArrowButton {
-  position: relative;
-  float: left;
-  height: 30px;
-  margin: 0px 8px;
-}
-.mblArrowButtonHead {
-  position: absolute;
-  top: 5px;
-  left: 17px;
-  width: 21px;
-  height: 21px;
-  border: 1px solid #b5bcc7;
-  -webkit-transform-origin: left top;
-  -webkit-transform: scale(0.9, 0.99) rotate(45deg);
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, right bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-}
-.dj_chrome .mblArrowButtonHead {
-  border-style: inset;
-}
-.mblArrowButtonBody {
-  position: absolute;
-  cursor: pointer;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  top: 5px;
-  left: 17px;
-  padding: 0px 10px 0px 3px;
-  height: 30px;
-  border-width: 1px 1px 1px 0px;
-  border-style: inset;
-  border-color: #b5bcc7;
-  font-size: 14px;
-  font-family: Helvetica;
-  font-weight: normal;
-  text-shadow: none;
-  color: #131313;
-  line-height: 30px;
-  -webkit-border-top-right-radius: 2px;
-  -webkit-border-bottom-right-radius: 2px;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-}
-.mblArrowButtonSelected .mblArrowButtonHead, .mblArrowButtonSelected .mblArrowButtonBody {
-  background-color: #0064c2;
-}
diff --git a/dojox/mobile/themes/custom/Heading.less b/dojox/mobile/themes/custom/Heading.less
deleted file mode 100644
index cfc8580..0000000
--- a/dojox/mobile/themes/custom/Heading.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Heading.less";
diff --git a/dojox/mobile/themes/custom/IconContainer-compat.css b/dojox/mobile/themes/custom/IconContainer-compat.css
index 78efb95..bafb264 100644
--- a/dojox/mobile/themes/custom/IconContainer-compat.css
+++ b/dojox/mobile/themes/custom/IconContainer-compat.css
@@ -1,11 +1,13 @@
 @import url("../common/domButtons/DomButtonColorButtons-compat.css");
 
-/* dojox.mobile.IconItem */
-.mblIconArea div {
-	*font-size: 60px; /* IE 7 quirks */
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+/* dojox.mobile.IconContainer */
+.mblIconItemPaneHeading {
+  background-image: url(compat/icon-content-heading-bg.png);
 }
-
-/* Icon Content Heading */
-.mblIconContentHeading {
-	background-image: url(compat/heading-bg.png);
+.dj_gecko .mblIconItemPaneHeading {
+  background-image: -moz-linear-gradient(top, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
+}
+.dj_ie7 .mblIconAreaInner {
+  font-size: 60px;
 }
diff --git a/dojox/mobile/themes/custom/IconContainer-compat.less b/dojox/mobile/themes/custom/IconContainer-compat.less
new file mode 100644
index 0000000..e2df985
--- /dev/null
+++ b/dojox/mobile/themes/custom/IconContainer-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer-compat.less";
diff --git a/dojox/mobile/themes/custom/IconContainer.css b/dojox/mobile/themes/custom/IconContainer.css
index 457a86a..7c1e9f9 100644
--- a/dojox/mobile/themes/custom/IconContainer.css
+++ b/dojox/mobile/themes/custom/IconContainer.css
@@ -1,14 +1,17 @@
 @import url("../common/domButtons/DomButtonColorButtons.css");
 
- at import url("../common/IconContainer_keyframes.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
 /* dojox.mobile.IconContainer */
 .mblIconContainer {
-  margin: 8px 0 8px 8px;
-  padding: 8px 0 8px;
-  background-color: #eff1f3;
+  margin: 20px 10px;
+  padding: 0;
 }
 /* dojox.mobile.IconItem */
 .mblIconItem {
+  position: relative;
+  overflow: hidden;
+  /* for focus frame */
+
   list-style-type: none;
   float: left;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
@@ -16,37 +19,43 @@
 .mblIconItemTerminator {
   list-style-type: none;
   clear: both;
-  height: 8px;
 }
-.mblIconItemSub {
+.mblIconItemPane {
   list-style-type: none;
-  margin-left: -8px;
-  background-color: white;
-  color: #131313;
+  background-color: #ffffff;
+  color: #000000;
 }
 .mblIconArea {
-  height: 87px;
-  width: 73px;
-  text-align: center;
+  position: relative;
+  height: 78px;
   font-family: Helvetica;
-  font-weight: normal;
-  font-size: 14px;
+  font-size: 12px;
+  text-align: center;
+  margin-top: 5px;
+  margin-bottom: 5px;
+  width: 74px;
+  color: #000000;
 }
-.mblIconArea div {
+.mblIconArea img {
+  vertical-align: middle;
+}
+.mblIconAreaInner {
   position: relative;
   height: 65px;
   line-height: 65px;
   text-align: center;
 }
-.mblIconArea img {
-  vertical-align: middle;
+.mblIconItemDeleteIcon {
+  position: absolute;
+  top: -4px;
+  left: -2px;
 }
 .mblIconItemSpriteIcon {
   position: absolute;
 }
 .mblContent {
   clear: both;
-  padding-bottom: 8px;
+  padding-bottom: 20px;
 }
 table.mblClose {
   clear: both;
@@ -54,48 +63,199 @@ table.mblClose {
 }
 .mblVibrate {
   position: relative;
-  -webkit-animation-duration: .5s;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
   -webkit-animation-timing-function: ease-in-out;
-  -webkit-animation-iteration-count: 20;
+  animation-timing-function: ease-in-out;
+  -webkit-animation-iteration-count: infinite;
+  animation-iteration-count: infinite;
   -webkit-animation-name: mblVibrate;
+  animation-name: mblVibrate;
   -webkit-transform: rotate(0deg);
+  transform: rotate(0deg);
 }
 .mblCloseContent {
-  -webkit-animation-duration: .3s;
+  -webkit-animation-duration: 0.3s;
+  animation-duration: 0.3s;
   -webkit-animation-timing-function: ease-in-out;
+  animation-timing-function: ease-in-out;
   -webkit-animation-name: mblShrink;
+  animation-name: mblShrink;
   -webkit-transform: scale(0.01);
+  transform: scale(0.01);
 }
 .mblCloseContent.mblShrink0 {
   -webkit-animation-name: mblShrink0;
+  animation-name: mblShrink0;
 }
 .mblCloseContent.mblShrink1 {
   -webkit-animation-name: mblShrink1;
+  animation-name: mblShrink1;
 }
 .mblCloseContent.mblShrink2 {
   -webkit-animation-name: mblShrink2;
+  animation-name: mblShrink2;
 }
 .mblCloseContent.mblShrink3 {
   -webkit-animation-name: mblShrink3;
+  animation-name: mblShrink3;
 }
-/* Icon Content Heading */
-.mblIconContentHeading {
+/* dojox.mobile._IconItemPane */
+.mblIconItemPaneHeading {
   position: relative;
   clear: both;
   overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
   margin-top: 0px;
-  padding-left: 37px;
+  padding-left: 40px;
   height: 25px;
-  border-top: 1px solid #dfe8f0;
-  border-bottom: 1px solid #769dc0;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(2.5%, #ffffff), color-stop(2.5%, rgba(255, 255, 255, 0.14)), color-stop(5%, rgba(255, 255, 255, 0.14)), color-stop(5%, rgba(255, 255, 255, 0.52)), color-stop(7.5%, rgba(255, 255, 255, 0.52)), color-stop(7.5%, rgba(255, 255, 255, 0.68)), color-stop(10%, rgba(255, 255, 255, 0.68)), color-stop(1, rgba(255, 255, 255, 0)));
-  color: #131313;
-  font-size: 14px;
+  border-top: 1px solid #f1f3f4;
+  border-bottom: 1px solid #717d85;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e0e4e7), to(#b4bec6), color-stop(0.5, #c4ccd2), color-stop(0.5, #bfc8ce));
+  background-image: linear-gradient(to bottom, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
   font-family: Helvetica;
-  font-weight: normal;
-  text-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px;
+  font-size: 14px;
+  color: white;
   line-height: 26px;
+  text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.mblIconItemPaneIcon {
+  position: absolute;
+  top: -2px;
+  left: 1px;
+}
+ at -webkit-keyframes mblVibrate {
+  0% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    -webkit-transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    -webkit-transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    -webkit-transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at keyframes mblVibrate {
+  0% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at -webkit-keyframes mblShrink {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(0.01);
+  }
+}
+ at keyframes mblShrink {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink0 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink0 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink1 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink1 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink2 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink2 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink3 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink3 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(40%, -70%) scale(0.01);
+  }
 }
diff --git a/dojox/mobile/themes/custom/IconContainer.less b/dojox/mobile/themes/custom/IconContainer.less
index 963eae6..729745a 100644
--- a/dojox/mobile/themes/custom/IconContainer.less
+++ b/dojox/mobile/themes/custom/IconContainer.less
@@ -1,5 +1,5 @@
 @import url("../common/domButtons/DomButtonColorButtons.css");
- at import url("../common/IconContainer_keyframes.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
 
 @import "variables.less";
 @import "../common/IconContainer.less";
diff --git a/dojox/mobile/themes/custom/IconContainer_rtl.css b/dojox/mobile/themes/custom/IconContainer_rtl.css
new file mode 100644
index 0000000..f5b8c10
--- /dev/null
+++ b/dojox/mobile/themes/custom/IconContainer_rtl.css
@@ -0,0 +1,14 @@
+/* dojox.mobile.IconItem Rtl */
+.mblIconItemRtl {
+  float: right;
+}
+.mblIconItemRtl .mblIconItemDeleteIcon {
+  right: -2px;
+}
+/* dojox.mobile._IconItemPane Rtl*/
+.mblIconItemPaneRtl .mblIconItemPaneHeading {
+  padding-right: 40px;
+}
+.mblIconItemPaneRtl .mblIconItemPaneIcon {
+  right: 1px;
+}
diff --git a/dojox/mobile/themes/custom/IconMenu-compat.css b/dojox/mobile/themes/custom/IconMenu-compat.css
new file mode 100644
index 0000000..5389e87
--- /dev/null
+++ b/dojox/mobile/themes/custom/IconMenu-compat.css
@@ -0,0 +1,34 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+  background-color: #9b9b9b;
+}
+.mblIconMenuItemSel {
+  background-color: #999999;
+}
+.dj_gecko .mblIconMenu {
+  background-color: rgba(160, 160, 160, 0.85);
+}
+.dj_gecko .mblIconMenuItem {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblIconMenuItemSel {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_ff3 .mblIconMenu {
+  -moz-border-radius: 3px;
+}
+.dj_ff3 .mblIconMenuItemIcon img {
+  border: 1px solid red;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-left-radius: 3px;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-right-radius: 3px;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-left-radius: 3px;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-right-radius: 3px;
+}
diff --git a/dojox/mobile/themes/custom/IconMenu.css b/dojox/mobile/themes/custom/IconMenu.css
new file mode 100644
index 0000000..fe3c4f6
--- /dev/null
+++ b/dojox/mobile/themes/custom/IconMenu.css
@@ -0,0 +1,63 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+  width: 100%;
+  height: 100%;
+  border-radius: 3px;
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  padding: 0;
+  background-color: rgba(160, 160, 160, 0.85);
+  border: 1px solid #000000;
+}
+/* dojox.mobile.IconMenuItem */
+.mblIconMenuItem {
+  float: left;
+  list-style-type: none;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border-left: 1px solid rgba(192, 192, 192, 0.85);
+  border-bottom: 1px solid rgba(192, 192, 192, 0.85);
+}
+.mblIconMenuItemIcon {
+  position: relative;
+  margin-left: auto;
+  margin-right: auto;
+}
+.mblIconMenuItemFirstColumn {
+  border-left: none;
+}
+.mblIconMenuItemLastRow {
+  border-bottom: none;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  border-top-left-radius: 3px;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  border-top-right-radius: 3px;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  border-bottom-left-radius: 3px;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  border-bottom-right-radius: 3px;
+}
+.mblIconMenuItemAnchor {
+  display: block;
+  height: 100%;
+  font-family: Helvetica;
+  text-decoration: none;
+  font-size: 13px;
+  color: #ffffff;
+  cursor: pointer;
+}
+.mblIconMenuItemTable {
+  width: 100%;
+  height: 100%;
+}
+.mblIconMenuItemTable img {
+  border: none;
+}
+.mblIconMenuItemSel {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
+}
diff --git a/dojox/mobile/themes/custom/IconMenu_rtl-compat.css b/dojox/mobile/themes/custom/IconMenu_rtl-compat.css
new file mode 100644
index 0000000..21b3041
--- /dev/null
+++ b/dojox/mobile/themes/custom/IconMenu_rtl-compat.css
@@ -0,0 +1,17 @@
+/* dojox.mobile.IconMenu Rtl */
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-right-radius: 3px;
+  -moz-border-top-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-left-radius: 3px;
+  -moz-border-top-right-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-right-radius: 3px;
+  -moz-border-bottom-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-left-radius: 3px;
+  -moz-border-bottom-right-radius: 0px;
+}
diff --git a/dojox/mobile/themes/custom/IconMenu_rtl.css b/dojox/mobile/themes/custom/IconMenu_rtl.css
new file mode 100644
index 0000000..52791b5
--- /dev/null
+++ b/dojox/mobile/themes/custom/IconMenu_rtl.css
@@ -0,0 +1,23 @@
+.mblIconMenuItemRtl {
+  float: right;
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstColumn {
+  border-right: none;
+  border-left: 1px solid rgba(192, 192, 192, 0.85);
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  border-top-right-radius: 3px;
+  border-top-left-radius: 0px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  border-top-right-radius: 0px;
+  border-top-left-radius: 3px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 0px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  border-bottom-right-radius: 0px;
+  border-bottom-left-radius: 3px;
+}
diff --git a/dojox/mobile/themes/custom/ListItem-compat.css b/dojox/mobile/themes/custom/ListItem-compat.css
index 1192cdf..1807f73 100644
--- a/dojox/mobile/themes/custom/ListItem-compat.css
+++ b/dojox/mobile/themes/custom/ListItem-compat.css
@@ -1,16 +1,13 @@
 @import url("../common/domButtons/DomButtonGrayArrow-compat.css");
- at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
 
-/* mbl.widget.ListItem */
-*html li.mblListItem.mblVariableHeight { /* IE6 hack */
-	height: 0;
-}
-.mblItemSelected {
-	background-image: url(compat/ui-widget-bg.png);
+ at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
+/* dojox.mobile.ListItem */
+.mblListItemSelected {
+  background-color: #999999;
 }
-*html .mblListItemTextBox { /* IE6 hack */
-	height: 100%;
+.dj_gecko .mblListItemSelected {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
 }
-*html li.mblListItem.mblVariableHeight .mblListItemTextBox { /* IE6 hack */
-	height: auto;
+.dj_ie6 .mblListItem {
+  vertical-align: bottom;
 }
diff --git a/dojox/mobile/themes/custom/ListItem-compat.less b/dojox/mobile/themes/custom/ListItem-compat.less
new file mode 100644
index 0000000..332107e
--- /dev/null
+++ b/dojox/mobile/themes/custom/ListItem-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayArrow-compat.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
+
+ at import "variables.less";
+ at import "../common/ListItem-compat.less";
diff --git a/dojox/mobile/themes/custom/ListItem.css b/dojox/mobile/themes/custom/ListItem.css
index 8d3cb7c..40428dd 100644
--- a/dojox/mobile/themes/custom/ListItem.css
+++ b/dojox/mobile/themes/custom/ListItem.css
@@ -4,81 +4,119 @@
 /* dojox.mobile.ListItem */
 .mblListItem {
   position: relative;
-  list-style-type: none;
-  vertical-align: bottom;
-  /* To avoid IE6 LI bug */
+  overflow: hidden;
+  /* for focus frame */
 
-  padding: 0 0 0 8px;
-  height: 50px;
-  border-bottom: 1px solid #b5bcc7;
-  font-size: 18px;
-  font-family: Helvetica;
-  font-weight: normal;
-  text-shadow: none;
-  color: #131313;
-  line-height: 50px;
+  padding: 0 8px;
+  height: 43px;
+  list-style-type: none;
+  line-height: 43px;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  border-bottom: 1px solid #c0c0c0;
+  background-color: #ffffff;
+  color: #000000;
+  font-weight: bold;
 }
 .mblListItem.mblVariableHeight {
+  padding: 11px 8px;
   height: auto;
-  padding: 11px 0px 10px 6px;
   line-height: normal;
 }
-.mblListItem .mblListItemAnchor {
-  display: block;
-  height: 100%;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  background-position: 9px 7px;
-  text-decoration: none;
-  padding-right: 7px;
+.mblListItemSelected {
+  color: #ffffff;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#dedede));
+  background-image: linear-gradient(to bottom, #f6f6f6 0%, #dedede 100%);
 }
-.mblListItem .mblListItemAnchor * {
-  -webkit-tap-highlight-color: rgba(0, 0, 0, 0.2);
+.mblListItemSelected .mblDomButton div {
+  border-color: white;
 }
-.mblItemSelected {
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
+.mblListItemLabelSelected {
+  background-color: #ffffff;
 }
-.mblItemSelected .mblListItemAnchor {
-  color: #000000;
+.mblListItemChecked {
+  color: #404040;
 }
-.mblItemSelected .mblDomButton div {
-  border-color: white;
+.mblListItemChecked .mblListItemRightIcon {
+  visibility: visible;
 }
-.mblListItemTextBoxSelected {
-  background-color: #5cb0ff;
+.mblListItemChecked .mblListItemUncheckIcon {
+  position: absolute;
+  visibility: hidden;
 }
-.mblListItemChecked {
-  color: #000000;
+.mblListItemUnchecked .mblListItemRightIcon {
+  visibility: hidden;
 }
-.mblListItemIcon {
+.mblListItemUnchecked .mblListItemUncheckIcon {
+  visibility: visible;
+}
+.mblListItemDeleteIcon {
+  position: relative;
   float: left;
   line-height: normal;
-  margin-top: 10.5px;
+  margin-top: 7px;
+  margin-bottom: -7px;
   margin-right: 11px;
 }
-.mblListItemSpriteIcon {
-  position: absolute;
-  margin-top: 10.5px;
-  margin-left: 8px;
+.mblListItemIcon {
+  position: relative;
+  float: left;
+  line-height: normal;
+  margin-top: 7px;
+  margin-bottom: -7px;
+  margin-right: 11px;
 }
-.mblListItemRightIcon, .mblListItemRightIcon2 {
+.mblListItemRightIcon,
+.mblListItemRightIcon2,
+.mblListItemUncheckIcon {
   position: relative;
   float: right;
   line-height: normal;
-  margin-top: 10.5px;
+  margin-top: 7px;
+  margin-bottom: -7px;
 }
 .mblListItemRightText {
   position: relative;
   float: right;
   line-height: normal;
-  color: #131313;
-  margin: 14px 4px 0 0;
+  margin-right: 4px;
+  color: #000000;
+  margin-top: 12px;
 }
-.mblListItemTextBox {
+.mblListItemLabel {
+  position: relative;
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
+  height: 100%;
 }
-.mblVariableHeight .mblListItemTextBox {
+.mblVariableHeight .mblListItemLabel {
   white-space: normal;
 }
+.mblListItemSubText {
+  font-size: 14px;
+  color: #2d2d2d;
+}
+.mblListItemLayoutLeft {
+  position: relative;
+  float: left;
+  margin-right: 11px;
+}
+.mblListItemLayoutCenter {
+  position: absolute;
+  width: 100%;
+  text-align: center;
+}
+.mblListItemLayoutRight {
+  position: relative;
+  float: right;
+}
+/* dojox.mobile._EditableListMixin */
+.mblListItemFloat {
+  position: absolute;
+  border: 1px solid gray;
+  opacity: 0.5;
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  border-radius: 0px !important;
+  -moz-border-radius: 0px !important;
+}
diff --git a/dojox/mobile/themes/custom/ListItem_rtl-compat.css b/dojox/mobile/themes/custom/ListItem_rtl-compat.css
new file mode 100644
index 0000000..f7deb99
--- /dev/null
+++ b/dojox/mobile/themes/custom/ListItem_rtl-compat.css
@@ -0,0 +1 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl-compat.css");
diff --git a/dojox/mobile/themes/custom/ListItem_rtl.css b/dojox/mobile/themes/custom/ListItem_rtl.css
new file mode 100644
index 0000000..2987450
--- /dev/null
+++ b/dojox/mobile/themes/custom/ListItem_rtl.css
@@ -0,0 +1,29 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl.css");
+
+ at import url("../common/domButtons/DomButtonDarkBlueCheck_rtl.css");
+/* dojox.mobile.ListItem Rtl*/
+.mblListItemRtl .mblListItemDeleteIcon {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemIcon {
+  float: right;
+  margin-left: 11px;
+  margin-right: 0px;
+}
+.mblListItemRtl .mblListItemRightIcon,
+.mblListItemRtl .mblListItemRightIcon2,
+.mblListItemRtl .mblListItemUncheckIcon {
+  float: left;
+}
+.mblListItemRtl .mblListItemRightText {
+  float: left;
+  margin-left: 4px;
+}
+.mblListItemRtl .mblListItemLayoutLeft {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemLayoutRight {
+  float: left;
+}
diff --git a/dojox/mobile/themes/custom/ListItem_rtl.less b/dojox/mobile/themes/custom/ListItem_rtl.less
new file mode 100644
index 0000000..3d3e9eb
--- /dev/null
+++ b/dojox/mobile/themes/custom/ListItem_rtl.less
@@ -0,0 +1,4 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck_rtl.css");
+
+ at import "../common/ListItem_rtl.less";
diff --git a/dojox/mobile/themes/custom/Opener.css b/dojox/mobile/themes/custom/Opener.css
index 141c72e..8f2d4c8 100644
--- a/dojox/mobile/themes/custom/Opener.css
+++ b/dojox/mobile/themes/custom/Opener.css
@@ -1,3 +1,7 @@
 /* dojox.mobile.Opener */
 @import url("Overlay.css");
 @import url("Tooltip.css");
+
+.mblOpenerUnderlay {
+	-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
diff --git a/dojox/mobile/themes/custom/Overlay-compat.css b/dojox/mobile/themes/custom/Overlay-compat.css
index 3bc72a3..4d4216c 100644
--- a/dojox/mobile/themes/custom/Overlay-compat.css
+++ b/dojox/mobile/themes/custom/Overlay-compat.css
@@ -1,13 +1,14 @@
 /* dojox.mobile.Overlay */
 .mblOverlay {
-	_position: absolute;
-	text-align: center;
+  text-align: center;
 }
 .dj_gecko .mblOverlay {
-	text-align: -moz-center;
+  text-align: -moz-center;
 }
 .dj_ie9 .mblOverlay > *,
-.dj_ie8 .mblOverlay > *
-{
-	margin: 0 auto;
+.dj_ie8 .mblOverlay > * {
+  margin: 0 auto;
+}
+.dj_ie6 .mblOverlay {
+  *position: absolute;
 }
diff --git a/dojox/mobile/themes/custom/Overlay.css b/dojox/mobile/themes/custom/Overlay.css
index c2b7731..ad0b745 100644
--- a/dojox/mobile/themes/custom/Overlay.css
+++ b/dojox/mobile/themes/custom/Overlay.css
@@ -10,9 +10,10 @@
   margin: 0;
   width: 100%;
   text-align: -webkit-center;
-  background-color: #eff1f3;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
+  background-color: #f6f6f6;
+  background-image: none;
 }
-.mblOverlayHidden *, .mblOverlayHidden {
+.mblOverlayHidden *,
+.mblOverlayHidden {
   visibility: hidden !important;
 }
diff --git a/dojox/mobile/themes/custom/PageIndicator-compat.css b/dojox/mobile/themes/custom/PageIndicator-compat.css
new file mode 100644
index 0000000..50412f7
--- /dev/null
+++ b/dojox/mobile/themes/custom/PageIndicator-compat.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.PageIndicator */
+.mblPageIndicatorDot {
+	-moz-border-radius: 3px;
+}
diff --git a/dojox/mobile/themes/custom/PageIndicator.css b/dojox/mobile/themes/custom/PageIndicator.css
index a175ad6..c4384f3 100644
--- a/dojox/mobile/themes/custom/PageIndicator.css
+++ b/dojox/mobile/themes/custom/PageIndicator.css
@@ -16,8 +16,7 @@
   height: 6px;
   font-size: 1px;
   background-color: #949294;
-  -webkit-border-radius: 3px;
-  -moz-border-radius: 3px;
+  border-radius: 3px;
 }
 .mblPageIndicatorDotSelected {
   background-color: white;
diff --git a/dojox/mobile/themes/custom/PageIndicator.less b/dojox/mobile/themes/custom/PageIndicator.less
deleted file mode 100644
index 9bb6c49..0000000
--- a/dojox/mobile/themes/custom/PageIndicator.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/PageIndicator.less";
diff --git a/dojox/mobile/themes/custom/ProgressBar-compat.css b/dojox/mobile/themes/custom/ProgressBar-compat.css
new file mode 100644
index 0000000..5554687
--- /dev/null
+++ b/dojox/mobile/themes/custom/ProgressBar-compat.css
@@ -0,0 +1,9 @@
+/* Progress Bar */
+.mblProgressBarProgress {
+  background-color: #048bf4;
+}
+.dj_gecko .mblProgressBarProgress {
+  -moz-transition-property: width;
+  -moz-transition-duration: 0.25s;
+  background-image: -moz-linear-gradient(top, #048bf4 0%, #048bf4 50%, #48adfc 100%);
+}
diff --git a/dojox/mobile/themes/custom/ProgressBar.css b/dojox/mobile/themes/custom/ProgressBar.css
new file mode 100644
index 0000000..1298053
--- /dev/null
+++ b/dojox/mobile/themes/custom/ProgressBar.css
@@ -0,0 +1,30 @@
+/* dojox.mobile.ProgressBar */
+.mblProgressBar {
+  position: relative;
+  height: 13px;
+  background-color: #ffffff;
+  border: 1px solid #048bf4;
+}
+.mblProgressBarProgress {
+  -webkit-transition-property: width;
+  transition-property: width;
+  -webkit-transition-duration: 0.25s;
+  transition-duration: 0.25s;
+  height: 13px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#048bf4), to(#48adfc), color-stop(0.5, #048bf4));
+  background-image: linear-gradient(to bottom, #048bf4 0%, #048bf4 50%, #48adfc 100%);
+  border-right: 1px solid #048bf4;
+}
+.mblProgressBarNotStarted {
+  border-left: none;
+  border-right: none;
+}
+.mblProgressBarMsg {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  text-align: center;
+  font-size: 12px;
+  top: -1px;
+}
diff --git a/dojox/mobile/themes/custom/ProgressIndicator-compat.css b/dojox/mobile/themes/custom/ProgressIndicator-compat.css
index 4ee0810..cbabad7 100644
--- a/dojox/mobile/themes/custom/ProgressIndicator-compat.css
+++ b/dojox/mobile/themes/custom/ProgressIndicator-compat.css
@@ -1,46 +1,83 @@
 /* Progress Indicator */
-.mblProg {
-	position: absolute;
-	top: 0px;
-	width: 4px;
-	font-size: 1px;
-	height: 36px;
-	overflow: hidden;
-	background-color: #C0C0C0;
+.dj_ie .mblProg {
+  width: 4px;
+  height: 36px;
 }
-.mblProg0 {
-	left: 0px;
+.dj_ie .mblProg0 {
+  left: 0px;
 }
-.mblProg1 {
-	left: 8px;
+.dj_ie .mblProg1 {
+  left: 8px;
 }
-.mblProg2 {
-	left: 16px;
+.dj_ie .mblProg2 {
+  left: 16px;
 }
-.mblProg3 {
-	left: 24px;
+.dj_ie .mblProg3 {
+  left: 24px;
 }
-.mblProg4 {
-	left: 32px;
+.dj_ie .mblProg4 {
+  left: 32px;
 }
-.mblProg5 {
-	left: 40px;
+.dj_ie .mblProg5 {
+  left: 40px;
 }
-.mblProg6 {
-	left: 48px;
+.dj_ie .mblProg6 {
+  left: 48px;
 }
-.mblProg7 {
-	left: 56px;
+.dj_ie .mblProg7 {
+  left: 56px;
 }
-.mblProg8 {
-	left: 64px;
+.dj_ie .mblProg8 {
+  left: 64px;
 }
-.mblProg9 {
-	left: 72px;
+.dj_ie .mblProg9 {
+  left: 72px;
 }
-.mblProg10 {
-	left: 80px;
+.dj_ie .mblProg10 {
+  left: 80px;
 }
-.mblProg11 {
-	left: 80px;
+.dj_ie .mblProg11 {
+  left: 80px;
+}
+.dj_gecko .mblProgressIndicatorCenter .mblProgContainer {
+  -moz-transform-origin: 50% 0;
+}
+.dj_gecko .mblProg {
+  -moz-transform-origin: 0 2px;
+}
+.dj_gecko .mblProg0 {
+  -moz-transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.dj_gecko .mblProg1 {
+  -moz-transform: translate(22px, 11px) rotate(-60deg);
+}
+.dj_gecko .mblProg2 {
+  -moz-transform: translate(25px, 14px) rotate(-30deg);
+}
+.dj_gecko .mblProg3 {
+  -moz-transform: translate(26px, 18px) rotate(0deg);
+}
+.dj_gecko .mblProg4 {
+  -moz-transform: translate(25px, 22px) rotate(30deg);
+}
+.dj_gecko .mblProg5 {
+  -moz-transform: translate(22px, 25px) rotate(60deg);
+}
+.dj_gecko .mblProg6 {
+  -moz-transform: translate(18px, 26px) rotate(90.1deg);
+}
+.dj_gecko .mblProg7 {
+  -moz-transform: translate(14px, 25px) rotate(120deg);
+}
+.dj_gecko .mblProg8 {
+  -moz-transform: translate(11px, 22px) rotate(150deg);
+}
+.dj_gecko .mblProg9 {
+  -moz-transform: translate(10px, 18px) rotate(180deg);
+}
+.dj_gecko .mblProg10 {
+  -moz-transform: translate(11px, 14px) rotate(210deg);
+}
+.dj_gecko .mblProg11 {
+  -moz-transform: translate(14px, 11px) rotate(240deg);
 }
diff --git a/dojox/mobile/themes/custom/ProgressIndicator.css b/dojox/mobile/themes/custom/ProgressIndicator.css
index 2340637..17a8bda 100644
--- a/dojox/mobile/themes/custom/ProgressIndicator.css
+++ b/dojox/mobile/themes/custom/ProgressIndicator.css
@@ -1,11 +1,26 @@
 /* Progress Indicator */
+.mblProgressIndicator {
+  position: relative;
+  top: 0px;
+}
+.mblHeading .mblProgressIndicator {
+  margin: 5px;
+  float: left;
+}
 .mblProgContainer {
   position: absolute;
-  width: 40px;
-  height: 40px;
+  width: 100%;
+  height: 100%;
+}
+.mblProgressIndicatorCenter {
+  position: absolute;
   top: 180px;
   left: 50%;
-  margin: -18px 0px 0px -18px;
+}
+.mblProgressIndicatorCenter .mblProgContainer {
+  left: -50%;
+  -webkit-transform-origin: 50% 0;
+  transform-origin: 50% 0;
 }
 .mblProg {
   position: absolute;
@@ -16,43 +31,127 @@
   height: 4px;
   overflow: hidden;
   -webkit-transform-origin: 0 2px;
-  background-color: #C0C0C0;
-  -webkit-border-radius: 2px;
-  -moz-border-radius: 2px;
+  transform-origin: 0 2px;
+  background-color: #c0c0c0;
+  border-radius: 2px;
 }
 .mblProg0 {
   -webkit-transform: translate(18px, 10px) rotate(-90.1deg);
+  transform: translate(18px, 10px) rotate(-90.1deg);
 }
 .mblProg1 {
   -webkit-transform: translate(22px, 11px) rotate(-60deg);
+  transform: translate(22px, 11px) rotate(-60deg);
 }
 .mblProg2 {
   -webkit-transform: translate(25px, 14px) rotate(-30deg);
+  transform: translate(25px, 14px) rotate(-30deg);
 }
 .mblProg3 {
   -webkit-transform: translate(26px, 18px) rotate(0deg);
+  transform: translate(26px, 18px) rotate(0deg);
 }
 .mblProg4 {
   -webkit-transform: translate(25px, 22px) rotate(30deg);
+  transform: translate(25px, 22px) rotate(30deg);
 }
 .mblProg5 {
   -webkit-transform: translate(22px, 25px) rotate(60deg);
+  transform: translate(22px, 25px) rotate(60deg);
 }
 .mblProg6 {
   -webkit-transform: translate(18px, 26px) rotate(90.1deg);
+  transform: translate(18px, 26px) rotate(90.1deg);
 }
 .mblProg7 {
   -webkit-transform: translate(14px, 25px) rotate(120deg);
+  transform: translate(14px, 25px) rotate(120deg);
 }
 .mblProg8 {
   -webkit-transform: translate(11px, 22px) rotate(150deg);
+  transform: translate(11px, 22px) rotate(150deg);
 }
 .mblProg9 {
   -webkit-transform: translate(10px, 18px) rotate(180deg);
+  transform: translate(10px, 18px) rotate(180deg);
 }
 .mblProg10 {
   -webkit-transform: translate(11px, 14px) rotate(210deg);
+  transform: translate(11px, 14px) rotate(210deg);
 }
 .mblProg11 {
   -webkit-transform: translate(14px, 11px) rotate(240deg);
+  transform: translate(14px, 11px) rotate(240deg);
+}
+.mblProg0Color {
+  background-color: #c0c0c0;
+}
+.mblProg1Color {
+  background-color: #c0c0c0;
+}
+.mblProg2Color {
+  background-color: #c0c0c0;
+}
+.mblProg3Color {
+  background-color: #c0c0c0;
+}
+.mblProg4Color {
+  background-color: #c0c0c0;
+}
+.mblProg5Color {
+  background-color: #c0c0c0;
+}
+.mblProg6Color {
+  background-color: #b8b9b8;
+}
+.mblProg7Color {
+  background-color: #aeafae;
+}
+.mblProg8Color {
+  background-color: #a4a5a4;
+}
+.mblProg9Color {
+  background-color: #9a9a9a;
+}
+.mblProg10Color {
+  background-color: #8e8e8e;
+}
+.mblProg11Color {
+  background-color: #838383;
+}
+.mblProgWhite .mblProg0Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg1Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg2Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg3Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg4Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg5Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg6Color {
+  background-color: #acb9cb;
+}
+.mblProgWhite .mblProg7Color {
+  background-color: #b7c2d2;
+}
+.mblProgWhite .mblProg8Color {
+  background-color: #c4cdda;
+}
+.mblProgWhite .mblProg9Color {
+  background-color: #d1d8e2;
+}
+.mblProgWhite .mblProg10Color {
+  background-color: #dee3ea;
+}
+.mblProgWhite .mblProg11Color {
+  background-color: #eceff3;
 }
diff --git a/dojox/mobile/themes/custom/ProgressIndicator.less b/dojox/mobile/themes/custom/ProgressIndicator.less
deleted file mode 100644
index 2ab2a2d..0000000
--- a/dojox/mobile/themes/custom/ProgressIndicator.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ProgressIndicator.less";
diff --git a/dojox/mobile/themes/custom/RadioButton-compat.css b/dojox/mobile/themes/custom/RadioButton-compat.css
index 9fd4ead..049b248 100644
--- a/dojox/mobile/themes/custom/RadioButton-compat.css
+++ b/dojox/mobile/themes/custom/RadioButton-compat.css
@@ -1,26 +1,32 @@
 /* dojox.mobile.RadioButton */
 .mblRadioButton {
-	background-image: url(compat/ui-widget-bg.png);
-	-moz-border-radius: 0.5em;
-	-o-border-radius: 0.5em;
-	-ms-border-radius: 0.5em;
-	border-radius: 0.5em;
-	-moz-appearance: none;
-	-o-appearance: none;
-	-ms-appearance: none;
-	appearance: none;
-	-o-transform: translateY(0.45em);
-	-ms-transform: translateY(0.45em);
-	transform: translateY(0.45em);
-}
-.mblRadioButtonChecked::after,
-.mblRadioButton:checked::after {
-	-moz-transform: rotate(45deg);
-	-o-transform: rotate(45deg);
-	-ms-transform: rotate(45deg);
-	transform: rotate(45deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
+  background-image: url(compat/button-bg.png);
+}
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: url(compat/blue-button-sel-bg.png);
+}
+.dj_gecko .mblRadioButton {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+  -moz-appearance: none;
+}
+.dj_gecko .mblRadioButtonChecked,
+.dj_gecko .mblRadioButton:checked {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+}
+.dj_gecko .mblRadioButtonChecked::after,
+.dj_gecko .mblRadioButton:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblRadioButtonChecked.mblRadioButtonSelected,
+.dj_gecko .mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_ff3 .mblRadioButton {
+  -moz-border-radius: 0.5em;
 }
diff --git a/dojox/mobile/themes/custom/RadioButton.css b/dojox/mobile/themes/custom/RadioButton.css
index 32b1ebb..e5c535d 100644
--- a/dojox/mobile/themes/custom/RadioButton.css
+++ b/dojox/mobile/themes/custom/RadioButton.css
@@ -1,41 +1,50 @@
 /* dojox.mobile.RadioButton */
 .mblRadioButton {
   position: relative;
-  cursor: pointer;
-  outline: none;
-  -webkit-appearance: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
   margin: -0.5em 3px 0.3em 4px;
   width: 1em;
   height: 1em;
-  font-size: 18px;
-  border: 1px outset #b5bcc7;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-  -webkit-border-radius: 0.5em;
-  -webkit-transform: translatey(0.45em);
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 0.5em;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
+  font: inherit;
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  border-style: solid;
+  border-color: #c0c0c0;
 }
-.mblRadioButtonChecked, .mblRadioButton:checked {
-  border-color: #769dc0;
-  background-color: #007ef5;
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
 }
-.mblRadioButtonChecked::after, .mblRadioButton:checked::after {
+.mblRadioButtonChecked::after,
+.mblRadioButton:checked::after {
   position: absolute;
   content: "";
   width: 0.3em;
   height: 0.6em;
   top: 0;
   left: 0.25em;
-  border-color: #000000;
   border-width: 0.15em;
   border-style: none solid solid none;
   -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
   -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: #000000;
 }
-.mblRadioButtonChecked.mblRadioButtonSelected, .mblRadioButton:checked.mblRadioButtonSelected {
-  border-color: #769dc0;
-  background-color: #0064c2;
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
 }
-.mblRadioButtonChecked.mblRadioButtonSelected::after, .mblRadioButton:checked.mblRadioButtonSelected::after {
-  border-color: #000000;
+.mblRadioButtonChecked.mblRadioButtonSelected::after,
+.mblRadioButton:checked.mblRadioButtonSelected::after {
+  border-color: #ffffff;
 }
diff --git a/dojox/mobile/themes/custom/RadioButton.less b/dojox/mobile/themes/custom/RadioButton.less
deleted file mode 100644
index 0793ca6..0000000
--- a/dojox/mobile/themes/custom/RadioButton.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RadioButton.less";
diff --git a/dojox/mobile/themes/custom/RoundRect-compat.css b/dojox/mobile/themes/custom/RoundRect-compat.css
index 104ef49..19da8f3 100644
--- a/dojox/mobile/themes/custom/RoundRect-compat.css
+++ b/dojox/mobile/themes/custom/RoundRect-compat.css
@@ -1,71 +1,73 @@
 /* dojox.mobile.RoundRect */
-.mblRoundRect {
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
+.mblRoundRect.mblShadow {
+  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.2);
+}
+.dj_ff3 .mblRoundRect {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblRoundRect.mblShadow {
+  -moz-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.2);
 }
 /* Round Corner */
-.mblRoundCorner {
-	background-color: white;
-	height: 1px;
-	font-size: 1px;
-	overflow: hidden;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRectContainer {
-	margin: 0px;
-	padding: 0px;
-	background-color: white;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRect .mblRoundRectContainer {
-	padding: 3px 8px;
-}
-.mblRoundCorner0T {
-	height: 0px;
-}
-.mblRoundCorner1T {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
-}
-.mblRoundCorner2T {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner3T {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4T {
-	margin: 0px 1px;
-}
-.mblRoundCorner5T {
-	margin: 0px 1px;
-}
-
-.mblRoundCorner0B {
-	height: 0px;
-}
-.mblRoundCorner1B {
-	margin: 0px 1px;
-}
-.mblRoundCorner2B {
-	margin: 0px 1px;
-}
-.mblRoundCorner3B {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4B {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner5B {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
+.dj_ie .mblRoundCorner {
+  background-color: #ffffff;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #c0c0c0;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: #ffffff;
+  border-style: solid;
+  border-color: #c0c0c0;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #c0c0c0;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #c0c0c0;
+  margin: 0 5px;
 }
diff --git a/dojox/mobile/themes/custom/RoundRect.css b/dojox/mobile/themes/custom/RoundRect.css
index 86caed0..173ace2 100644
--- a/dojox/mobile/themes/custom/RoundRect.css
+++ b/dojox/mobile/themes/custom/RoundRect.css
@@ -1,15 +1,13 @@
 /* dojox.mobile.RoundRect */
 .mblRoundRect {
-  margin: 8px 8px 12px;
+  margin: 7px 9px 16px;
   padding: 8px;
-  border: 1px solid #b5bcc7;
-  -webkit-border-radius: 5px;
+  border: 1px solid #c0c0c0;
+  border-radius: 8px;
   background-color: #ffffff;
-  font-size: 18px;
-  font-family: Helvetica;
-  font-weight: normal;
-  text-shadow: none;
+  color: #000000;
 }
 .mblRoundRect.mblShadow {
-  -webkit-box-shadow: 5px 5px 5px #b5bcc7;
+  -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.2);
+  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.2);
 }
diff --git a/dojox/mobile/themes/custom/RoundRect.less b/dojox/mobile/themes/custom/RoundRect.less
deleted file mode 100644
index efec816..0000000
--- a/dojox/mobile/themes/custom/RoundRect.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRect.less";
diff --git a/dojox/mobile/themes/custom/RoundRectCategory.css b/dojox/mobile/themes/custom/RoundRectCategory.css
index 12485a8..de866e8 100644
--- a/dojox/mobile/themes/custom/RoundRectCategory.css
+++ b/dojox/mobile/themes/custom/RoundRectCategory.css
@@ -1,14 +1,11 @@
 /* dojox.mobile.RoundRectCategory */
 .mblRoundRectCategory {
+  margin: 18px 0 0 20px;
+  padding: 0;
+  font-family: Helvetica;
+  font-size: 16px;
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
-  margin: 0;
-  padding: 8px 8px 0;
-  font-size: 18px;
-  font-family: Helvetica;
-  font-weight: normal;
-  text-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px;
   color: #000000;
-  line-height: 30px;
 }
diff --git a/dojox/mobile/themes/custom/RoundRectCategory.less b/dojox/mobile/themes/custom/RoundRectCategory.less
deleted file mode 100644
index e9148cc..0000000
--- a/dojox/mobile/themes/custom/RoundRectCategory.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRectCategory.less";
diff --git a/dojox/mobile/themes/custom/RoundRectCategory_rtl.css b/dojox/mobile/themes/custom/RoundRectCategory_rtl.css
new file mode 100644
index 0000000..2a7ffc3
--- /dev/null
+++ b/dojox/mobile/themes/custom/RoundRectCategory_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.RoundRectCategory Rtl */
+.mblRoundRectCategoryRtl {
+  margin: 18px 20px 0px 0px;
+}
diff --git a/dojox/mobile/themes/custom/RoundRectList-compat.css b/dojox/mobile/themes/custom/RoundRectList-compat.css
index d16eb00..a428851 100644
--- a/dojox/mobile/themes/custom/RoundRectList-compat.css
+++ b/dojox/mobile/themes/custom/RoundRectList-compat.css
@@ -1,91 +1,78 @@
 /* dojox.mobile.RoundRectList */
-.mblRoundRectList {
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
-}
-.mblRoundRectList .mblListItem:first-child {
-	-moz-border-radius-topleft: 5px;
-	-moz-border-radius-topright: 5px;
-	-o-border-top-left-radius: 5px;
-	-o-border-top-right-radius: 5px;
-	-ms-border-top-left-radius: 5px;
-	-ms-border-top-right-radius: 5px;
-	border-top-left-radius: 5px;
-	border-top-right-radius: 5px;
-}
-.mblRoundRectList .mblListItem:last-child {
-	-moz-border-radius-bottomleft: 5px;
-	-moz-border-radius-bottomright: 5px;
-	-o-border-bottom-left-radius: 5px;
-	-o-border-bottom-right-radius: 5px;
-	-ms-border-bottom-left-radius: 5px;
-	-ms-border-bottom-right-radius: 5px;
-	border-bottom-left-radius: 5px;
-	border-bottom-right-radius: 5px;
+.dj_ff3 .mblRoundRectList {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:first-child {
+  -moz-border-radius-topleft: 8px;
+  -moz-border-radius-topright: 8px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:last-child {
+  -moz-border-radius-bottomleft: 8px;
+  -moz-border-radius-bottomright: 8px;
 }
 /* Round Corner */
-.mblRoundCorner {
-	background-color: white;
-	height: 1px;
-	font-size: 1px;
-	overflow: hidden;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRectContainer {
-	margin: 0px;
-	padding: 0px;
-	background-color: white;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRect .mblRoundRectContainer {
-	padding: 3px 8px;
-}
-.mblRoundCorner0T {
-	height: 0px;
-}
-.mblRoundCorner1T {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
-}
-.mblRoundCorner2T {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner3T {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4T {
-	margin: 0px 1px;
-}
-.mblRoundCorner5T {
-	margin: 0px 1px;
-}
-
-.mblRoundCorner0B {
-	height: 0px;
-}
-.mblRoundCorner1B {
-	margin: 0px 1px;
-}
-.mblRoundCorner2B {
-	margin: 0px 1px;
-}
-.mblRoundCorner3B {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4B {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner5B {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
+.dj_ie .mblRoundRectList {
+  position: relative;
+}
+.dj_ie .mblRoundCorner {
+  background-color: #ffffff;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #c0c0c0;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: #ffffff;
+  border-style: solid;
+  border-color: #c0c0c0;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #c0c0c0;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #c0c0c0;
+  margin: 0 5px;
 }
diff --git a/dojox/mobile/themes/custom/RoundRectList.css b/dojox/mobile/themes/custom/RoundRectList.css
index 3399016..683343c 100644
--- a/dojox/mobile/themes/custom/RoundRectList.css
+++ b/dojox/mobile/themes/custom/RoundRectList.css
@@ -1,21 +1,19 @@
 /* dojox.mobile.RoundRectList */
 .mblRoundRectList {
-  position: relative;
-  /* IE needs this */
-
-  margin: 8px 8px 12px;
+  margin: 7px 9px 16px;
   padding: 0;
-  border: 1px solid #b5bcc7;
-  -webkit-border-radius: 5px;
+  border: 1px solid #c0c0c0;
+  border-radius: 8px;
   background-color: #ffffff;
-  -webkit-box-shadow: 5px 5px 5px #b5bcc7;
 }
-.mblRoundRectList .mblListItem:first-child {
-  -webkit-border-top-left-radius: 5px;
-  -webkit-border-top-right-radius: 5px;
+.mblRoundRectList .mblListItem:first-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:first-child {
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
 }
-.mblRoundRectList .mblListItem:last-child {
-  border-bottom-width: 0px;
-  -webkit-border-bottom-left-radius: 5px;
-  -webkit-border-bottom-right-radius: 5px;
+.mblRoundRectList .mblListItem:last-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
 }
diff --git a/dojox/mobile/themes/custom/RoundRectList.less b/dojox/mobile/themes/custom/RoundRectList.less
deleted file mode 100644
index 52e1164..0000000
--- a/dojox/mobile/themes/custom/RoundRectList.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRectList.less";
diff --git a/dojox/mobile/themes/custom/ScrollablePane.css b/dojox/mobile/themes/custom/ScrollablePane.css
new file mode 100644
index 0000000..573d58f
--- /dev/null
+++ b/dojox/mobile/themes/custom/ScrollablePane.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.mblScrollablePane */
+.mblScrollablePane {
+  position: relative;
+  overflow: hidden;
+}
+.mblScrollableViewContainer {
+  position: absolute;
+  top: 0px;
+}
+.mblScrollablePaneMask {
+  position: relative;
+}
diff --git a/dojox/mobile/themes/custom/SearchBox-compat.css b/dojox/mobile/themes/custom/SearchBox-compat.css
new file mode 100644
index 0000000..913c704
--- /dev/null
+++ b/dojox/mobile/themes/custom/SearchBox-compat.css
@@ -0,0 +1,26 @@
+ at import url("TextBox-compat.css");
+/* dojox.mobile.SearchBox */
+.mblSearchBox {
+  height: auto;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  -moz-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/custom/SearchBox.css b/dojox/mobile/themes/custom/SearchBox.css
new file mode 100644
index 0000000..26c7470
--- /dev/null
+++ b/dojox/mobile/themes/custom/SearchBox.css
@@ -0,0 +1,61 @@
+ at import url("TextBox.css");
+/* dojox.mobile.SearchBox */
+.mblSearchBox.iphone4:focus::-webkit-search-cancel-button {
+  background: none !important;
+  border-color: transparent !important;
+}
+.mblSearchBox::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+  background-color: #c0c0c0;
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-size: 15px 15px;
+  background-image: -webkit-gradient(linear, left top, right bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #ffffff), color-stop(0.54, #ffffff), color-stop(0.54, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #ffffff), color-stop(0.54, #ffffff), color-stop(0.54, transparent), to(transparent)) !important;
+  border: 2px solid #c0c0c0;
+  box-sizing: border-box;
+  height: 15px;
+  width: 15px;
+  display: inline-block;
+  vertical-align: middle;
+  margin-left: 0.5em;
+  border-radius: 1em;
+}
+.mblSearchBox::-webkit-search-results-decoration {
+  -webkit-appearance: none;
+  background-repeat: no-repeat;
+  background-size: 13px 13px, 9px 9px;
+  background-position: 0px 0px, 10px 10px;
+  background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 6, from(transparent), color-stop(0.65, transparent), color-stop(0.8, #c0c0c0), color-stop(0.95, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.425, transparent), color-stop(0.5, #c0c0c0), color-stop(0.575, transparent), to(transparent)) !important;
+  width: 15px;
+  height: 15px;
+  display: inline-block;
+  vertical-align: middle;
+}
+.mblSearchBox {
+  height: auto;
+}
+.dj_chrome .mblSearchBox {
+  border-radius: 0;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/custom/SimpleDialog-compat.css b/dojox/mobile/themes/custom/SimpleDialog-compat.css
new file mode 100644
index 0000000..605235e
--- /dev/null
+++ b/dojox/mobile/themes/custom/SimpleDialog-compat.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.SimpleDialog */
+.dj_ff3 .mblSimpleDialogDecoration {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/custom/SimpleDialog.css b/dojox/mobile/themes/custom/SimpleDialog.css
new file mode 100644
index 0000000..ce137fb
--- /dev/null
+++ b/dojox/mobile/themes/custom/SimpleDialog.css
@@ -0,0 +1,48 @@
+/* dojox.mobile.SimpleDialog */
+.mblSimpleDialog {
+  position: absolute;
+  z-index: 100;
+  margin: 0;
+  text-align: center;
+  outline: none;
+  padding: 5px;
+  width: 262px;
+}
+.mblSimpleDialogDecoration {
+  border-radius: 0;
+  background-color: #ffffff;
+  border: 1px solid #000000;
+  color: #000000;
+}
+.mblSimpleDialogContainer {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.mblSimpleDialogCover {
+  background-color: #000000;
+  opacity: 0.5;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 99;
+}
+.mblSimpleDialogCloseBtn {
+  position: absolute !important;
+}
+.mblSimpleDialogTitle {
+  margin: 7px 0 7px -5px;
+  padding: 0 14px 7px;
+  width: 244px;
+  border-bottom: 1px solid #c0c0c0;
+  font-size: 20px;
+  font-weight: bold;
+  text-align: left;
+}
+.mblSimpleDialogText {
+  margin: 14px 9px;
+  width: 244px;
+  text-align: left;
+}
diff --git a/dojox/mobile/themes/custom/Slider-compat.css b/dojox/mobile/themes/custom/Slider-compat.css
index 936dcd6..0086b40 100644
--- a/dojox/mobile/themes/custom/Slider-compat.css
+++ b/dojox/mobile/themes/custom/Slider-compat.css
@@ -1,42 +1,40 @@
 /* dojox.mobile.Slider */
 .mblSlider {
-	background-image: url(compat/ui-widget-bg.png);
-	-moz-border-radius: 8px;
-	-o-border-radius: 8px;
-	-ms-border-radius: 8px; 
-	border-radius: 8px;
-	-moz-user-select: none; /* prevent selection */
-	-o-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-	-moz-box-sizing: content-box; /* make width and height consistent with a DIV */
-	-o-box-sizing: content-box;
-	-ms-box-sizing: content-box;
-	box-sizing: content-box;
-}
-.mblSlider.mblSliderV {
-	background: #ABABAB;
+  background-image: url(compat/slider-h-bg.png);
+  background-repeat: repeat-x;
 }
 .mblSliderProgressBar {
-	background-image: url(compat/ui-widget-bg.png);
-	background-repeat: repeat-x;
-	-moz-border-radius: 8px;
-	-o-border-radius: 8px;
-	-ms-border-radius: 8px; 
-	border-radius: 8px;
-	_background-image: url(compat/slider-h-bar-bg.png); /* IE6 hack */
-	_background-color: transparent; /* IE6 hack */
+  background-image: url(compat/slider-h-bar-bg.png);
+  background-repeat: repeat-x;
+}
+.mblSliderHandle {
+  background-image: url(compat/slider-handle-bg.png);
+}
+.mblSliderV {
+  background-color: #e2e2e2;
+  background-image: none;
 }
 .mblSliderV .mblSliderProgressBar {
-	background: #0D48A8;
+  background-color: #c0c0c0;
+  background-image: none;
 }
-.mblSliderHandle {
-	background-image: url(compat/ui-widget-bg.png);
-	-moz-border-radius: 10px;
-	-o-border-radius: 10px;
-	-ms-border-radius: 10px; 
-	border-radius: 10px;
-}
-.mblSliderTransition {
-	transition-duration: 400ms;
+.dj_gecko .mblSlider {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+  -moz-user-select: none;
+  -moz-box-sizing: content-box;
+}
+.dj_gecko .mblSliderProgressBar {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_gecko .mblSliderHandle {
+  background-image: -moz-linear-gradient(top, #e2e2e2 0%, #a4a4a4 100%);
+}
+.dj_ff3 .mblSlider {
+  -moz-border-radius: 0;
+}
+.dj_ff3 .mblSliderProgressBar {
+  -moz-border-radius: 0;
+}
+.dj_ff3 .mblSliderHandle {
+  -moz-border-radius: 0;
 }
diff --git a/dojox/mobile/themes/custom/Slider.css b/dojox/mobile/themes/custom/Slider.css
index 888f96a..b4628df 100644
--- a/dojox/mobile/themes/custom/Slider.css
+++ b/dojox/mobile/themes/custom/Slider.css
@@ -1,19 +1,17 @@
 /* dojox.mobile.Slider */
 .mblSlider {
-  outline: none;
+  margin: 15px;
+  border-style: inset;
+  border-width: 1px;
+  border-radius: 0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
   -webkit-user-select: none;
-  /* prevent selection */
-
+  -ms-user-select: none;
   -webkit-box-sizing: content-box;
-  /* make width and height consistent with a DIV */
-
-  margin: 15px;
-  /* 1/2 handle width for hanging off the ends of the bar */
-
-  border: 1px outset #b5bcc7;
-  background-color: #8fc9ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-  -webkit-border-radius: 2px;
+  box-sizing: content-box;
+  border: 1px solid #c0c0c0;
+  border-bottom-color: #9b9b9b;
 }
 .mblSliderH {
   width: 200px;
@@ -36,21 +34,25 @@
   left: 50%;
 }
 .mblSliderProgressBar {
-  -webkit-border-radius: 2px;
-  background-color: #0064c2;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
+  border-radius: 0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
 }
 .mblSliderHandle {
   margin: -10px 0 0 -10px;
   width: 18px;
   height: 18px;
-  border: 1px outset #b5bcc7;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-  -webkit-border-radius: 2px;
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e2e2e2), to(#a4a4a4));
+  background-image: linear-gradient(to bottom, #e2e2e2 0%, #a4a4a4 100%);
+  border: 1px solid #9b9b9b;
+  border-bottom-color: #767676;
 }
 .mblSliderTransition {
   -webkit-transition-duration: 400ms;
+  transition-duration: 400ms;
 }
 .mblSliderTouchBox {
   margin: 0;
diff --git a/dojox/mobile/themes/custom/Slider.less b/dojox/mobile/themes/custom/Slider.less
deleted file mode 100644
index 928972f..0000000
--- a/dojox/mobile/themes/custom/Slider.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Slider.less";
diff --git a/dojox/mobile/themes/custom/SpinWheel-compat.css b/dojox/mobile/themes/custom/SpinWheel-compat.css
new file mode 100644
index 0000000..4d605d5
--- /dev/null
+++ b/dojox/mobile/themes/custom/SpinWheel-compat.css
@@ -0,0 +1,36 @@
+.mblSpinWheel {
+  background-image: url(../common/compat/spinwheel-bg.png);
+}
+.mblSpinWheelBar {
+  background-image: url(../common/compat/spinwheel-bar.png);
+}
+.mblSpinWheelSlotTouch,
+.mblSpinWheelSlotPanel {
+  left: 0;
+}
+.dj_gecko .mblSpinWheel {
+  background-image: -moz-linear-gradient(top, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+}
+.dj_gecko .mblSpinWheelBar {
+  background-image: -moz-linear-gradient(top, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 1%);
+}
+.dj_ff3 .mblSpinWheel {
+  -moz-border-radius: 3px;
+}
+.dj_ie .mblSpinWheelBar {
+  filter: progid:DXImageTransform.Microsoft.alpha(opacity=60);
+}
+.dj_ie6 .mblSpinWheelBar,
+.dj_ie7 .mblSpinWheelBar {
+  z-index: -1;
+}
+.dj_ie7 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
+.dj_ie6 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
diff --git a/dojox/mobile/themes/custom/SpinWheel.css b/dojox/mobile/themes/custom/SpinWheel.css
new file mode 100644
index 0000000..8764541
--- /dev/null
+++ b/dojox/mobile/themes/custom/SpinWheel.css
@@ -0,0 +1,77 @@
+/* dojox.mobile.SpinWheel */
+.mblSpinWheel {
+  position: relative;
+  overflow: hidden;
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #313137), color-stop(0.05, #73747d), color-stop(0.07, #92939b), color-stop(0.09, #ababb5), color-stop(0.12, #c5c6ce), color-stop(0.16, #dfe0e4), color-stop(0.22, #f4f5f6), color-stop(0.35, #fbfcfc), color-stop(0.5, #fbfcfc), color-stop(0.61, #fbfcfc), color-stop(0.61, #b4c1c7), color-stop(0.65, #fbfcfc), color-stop(0.78, #f4f5f6), color-stop(0.84, #dfe0e4), color-stop(0.88, #c5c6ce), color-stop(0.91, #ababb5), co [...]
+  background: linear-gradient(to bottom, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+  height: 200px;
+  border-left: solid 3px #000000;
+  border-right: solid 3px #000000;
+  color: #000000;
+  border-radius: 3px;
+}
+.mblSpinWheelBar {
+  position: absolute;
+  top: 79px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#edeef2), to(#a7adca), color-stop(0, #edeef2), color-stop(0.25, #c8cadd), color-stop(0.49, #bbbfd4), color-stop(0.51, #9fa8c6), color-stop(0.81, #a2a9c7), color-stop(0.82, #a6abc9), color-stop(1, #a7adca));
+  background: linear-gradient(to bottom, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 100%);
+  border: solid 1px #7b8497;
+  height: 42px;
+  width: 100%;
+  clear: both;
+  opacity: 0.6;
+}
+.mblSpinWheelDatePicker {
+  width: 312px;
+}
+.mblSpinWheelTimePicker {
+  width: 98px;
+}
+.mblSpinWheelSlot {
+  position: relative;
+  top: 0px;
+  float: left;
+  width: 100px;
+  height: 100%;
+  border-left: solid 2px #000000;
+  border-right: solid 2px #000000;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblSpinWheelSlotLabel {
+  padding: 0 8px;
+  height: 44px;
+  overflow: hidden;
+  font: bold 24px/44px Helvetica, sans-serif;
+}
+.mblSpinWheelSlotLabel img {
+  vertical-align: middle;
+  opacity: 0.7;
+}
+.mblSpinWheelSlotLabelGray {
+  color: #cccccc;
+}
+.mblSpinWheelSlotLabelBlue {
+  color: #0959d2;
+}
+.mblSpinWheelSlotContainer {
+  position: relative;
+}
+.mblSpinWheelSlotPanel {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+}
+.mblSpinWheelSlotTouch {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  z-index: 1;
+}
+.dj_ie .mblSpinWheelSlotTouch {
+  background-color: rgba(255, 255, 255, 0.01);
+}
+.dj_ie8 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+}
diff --git a/dojox/mobile/themes/custom/SpinWheel_rtl-compat.css b/dojox/mobile/themes/custom/SpinWheel_rtl-compat.css
new file mode 100644
index 0000000..98aab55
--- /dev/null
+++ b/dojox/mobile/themes/custom/SpinWheel_rtl-compat.css
@@ -0,0 +1,4 @@
+.mblSpinWheelSlotRtl .mblSpinWheelSlotTouch,
+.mblSpinWheelSlotRtl .mblSpinWheelSlotPanel {
+  right: 0;
+}
diff --git a/dojox/mobile/themes/custom/SpinWheel_rtl.css b/dojox/mobile/themes/custom/SpinWheel_rtl.css
new file mode 100644
index 0000000..c3efc85
--- /dev/null
+++ b/dojox/mobile/themes/custom/SpinWheel_rtl.css
@@ -0,0 +1,5 @@
+/* dojox.mobile.SpinWheel Rtl */
+.mblSpinWheelSlotRtl,
+.mblSpinWheelRtl .mblSpinWheelSlot {
+  float: right;
+}
diff --git a/dojox/mobile/themes/custom/Switch-compat.css b/dojox/mobile/themes/custom/Switch-compat.css
index 7730ebb..01c37b6 100644
--- a/dojox/mobile/themes/custom/Switch-compat.css
+++ b/dojox/mobile/themes/custom/Switch-compat.css
@@ -1,59 +1,116 @@
-/* Switch - default */
-.mblSwitchBg {
-	-moz-border-radius: 2px;
-	-o-border-radius: 2px;
-	-ms-border-radius: 2px;
-	border-radius: 2px;
-	-moz-box-sizing: border-box;
-	-o-box-sizing: border-box;
-	-ms-box-sizing: border-box;
-	box-sizing: border-box;
-}
-.mblSwitchBgLeft {
-	background-image: url(compat/ui-widget-bg.png);
-}
-.mblSwitchBgRight {
-	background-image: url(compat/ui-widget-bg.png);
-}
-.mblSwitchKnob {
-	background-image: url(compat/ui-widget-bg.png);
-	-moz-border-radius: 2px;
-	-o-border-radius: 2px;
-	-ms-border-radius: 2px;
-	border-radius: 2px;
-	-moz-box-sizing: border-box;
-	-o-box-sizing: border-box;
-	-ms-box-sizing: border-box;
-	box-sizing: border-box;
-}
-
-/* Round Shape */
-.mblSwRoundShape1 .mblSwitchBg,
+/* dojox.mobile.Switch */
+/* Switch - common */
+.dj_gecko .mblSwitchBg {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitchKnob {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitch .mblSwitchBgLeft {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_gecko .mblSwitch .mblSwitchBgRight {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+}
+.dj_gecko .mblSwitch .mblSwitchKnob {
+  background-image: -moz-linear-gradient(top, #e2e2e2 0%, #a4a4a4 100%);
+}
+.dj_ie .mblSwitchBg {
+  border: none;
+  background: none;
+}
+.dj_ie .mblSwitchBgLeft {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchBgRight {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchKnob {
+  background: none;
+  background-repeat: no-repeat;
+  border: none;
+}
+/* Square Shape */
+.mblSwSquareShape .mblSwitchBg {
+  -moz-border-radius: 2px;
+}
+.mblSwSquareShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-square-l.gif);
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchKnob {
+  -moz-border-radius: 2px;
+  background-image: url(compat/switch-square-k.gif);
+}
+/* Round Shape1 */
+.mblSwRoundShape1 .mblSwitchBg {
+  -moz-border-radius: 14px;
+}
+.mblSwRoundShape1 .mblSwitchBgLeft {
+  background-image: url(compat/switch-round1-l.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round1-k.gif);
+}
+/* Round Shape2 */
 .mblSwRoundShape2 .mblSwitchBg {
-	-moz-border-radius: 14px;
-	-o-border-radius: 14px;
-	-ms-border-radius: 14px;
-	border-radius: 14px;
+  -moz-border-radius: 14px;
+}
+.mblSwRoundShape2 .mblSwitchBgLeft {
+  background-image: url(compat/switch-round2-l.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+  background-image: url(compat/switch-round2-r.gif);
 }
-.mblSwRoundShape1 .mblSwitchKnob,
 .mblSwRoundShape2 .mblSwitchKnob {
-	-moz-border-radius: 13px;
-	-o-border-radius: 13px;
-	-ms-border-radius: 13px;
-	border-radius: 13px;
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round2-k.gif);
+}
+/* Arc Shape1 */
+.mblSwArcShape1 .mblSwitchBg {
+  -moz-border-radius: 5px/14px;
+}
+.mblSwArcShape1 .mblSwitchBgLeft {
+  background-image: url(compat/switch-arc1-l.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+  background-image: url(compat/switch-arc1-r.gif);
 }
-/* Arc Shape */
-.mblSwArcShape1 .mblSwitchBg,
+.mblSwArcShape1 .mblSwitchKnob {
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc1-k.gif);
+}
+/* Switch - Arc Shape2 */
 .mblSwArcShape2 .mblSwitchBg {
-	-moz-border-radius: 6px/14px;
-	-o-border-radius: 6px/14px;
-	-ms-border-radius: 6px/14px;
-	border-radius: 6px/14px;
+  -moz-border-radius: 5px/14px;
+}
+.mblSwArcShape2 .mblSwitchBgLeft {
+  background-image: url(compat/switch-arc2-l.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+  background-image: url(compat/switch-arc2-r.gif);
 }
-.mblSwArcShape1 .mblSwitchKnob,
 .mblSwArcShape2 .mblSwitchKnob {
-	-moz-border-radius: 5px/13px;
-	-o-border-radius: 5px/13px;
-	-ms-border-radius: 5px/13px;
-	border-radius: 5px/13px;
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc2-k.gif);
+}
+/* Default Shape */
+.mblSwDefaultShape .mblSwitchBg {
+  -moz-border-radius: 2px;
+}
+.mblSwDefaultShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-square-l.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  -moz-border-radius: 2px;
+  background-image: url(compat/switch-square-k.gif);
 }
diff --git a/dojox/mobile/themes/custom/Switch-compat.less b/dojox/mobile/themes/custom/Switch-compat.less
new file mode 100644
index 0000000..f15894c
--- /dev/null
+++ b/dojox/mobile/themes/custom/Switch-compat.less
@@ -0,0 +1,7 @@
+ at import "variables.less";
+ at import "../common/Switch-compat.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwSquareShape-styles;
+}
diff --git a/dojox/mobile/themes/custom/Switch.css b/dojox/mobile/themes/custom/Switch.css
index fa50ef9..d7ca1fb 100644
--- a/dojox/mobile/themes/custom/Switch.css
+++ b/dojox/mobile/themes/custom/Switch.css
@@ -1,23 +1,230 @@
- at import url("../common/Switch.css");
 /* dojox.mobile.Switch */
-.mblItemSwitch {
-  top: 12px;
+/* Switch - common */
+.mblSwitch {
+  margin: 0;
+  position: relative;
+  display: inline-block;
+  height: 27px;
+  line-height: 29px;
+  overflow: hidden;
+  text-align: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblListItem .mblSwitch {
+  position: absolute;
+  right: 12px;
+  top: 8px;
+}
+.mblSwitchInner {
+  position: absolute;
+  top: 0;
+  height: 27px;
+}
+.mblSwitchAnimation .mblSwitchInner {
+  -webkit-transition-property: left;
+  transition-property: left;
+  -webkit-transition-duration: 0.1s;
+  transition-duration: 0.1s;
+}
+.mblSwitchOn .mblSwitchInner {
+  left: 0;
 }
 .mblSwitchBg {
-  border-color: #b5bcc7;
-  -webkit-border-radius: 2px;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
+  position: absolute;
+  top: 0;
+  width: 94px;
+  height: 27px;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+  line-height: 29px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border: 1px solid #c0c0c0;
+  border-bottom-color: #9b9b9b;
 }
 .mblSwitchBgLeft {
-  background-color: #007ef5;
-  color: #131313;
+  left: 0;
+  color: white;
+  background-color: #3f84eb;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
 }
 .mblSwitchBgRight {
-  background-color: #8fc9ff;
+  color: #7f7f7f;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
 }
 .mblSwitchKnob {
-  border-color: #7b879b;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-  -webkit-border-radius: 2px;
+  position: absolute;
+  top: 0;
+  height: 27px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e2e2e2), to(#a4a4a4));
+  background-image: linear-gradient(to bottom, #e2e2e2 0%, #a4a4a4 100%);
+  font-size: 1px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border: 1px solid #9b9b9b;
+  border-bottom-color: #767676;
+}
+.mblSwitchText {
+  position: relative;
+  top: 0;
+  width: 53px;
+  height: 27px;
+  padding: 0;
+  line-height: 28px;
+  text-align: center;
+}
+.mblSwitchTextLeft {
+  left: 0;
+}
+.mblSwitchTextRight {
+  left: 40px;
+}
+/* Square Shape */
+.mblSwSquareShape {
+  width: 94px;
+}
+.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBg {
+  border-radius: 2px;
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+  width: 41px;
+  border-radius: 2px;
+}
+.mblSwSquareShape .mblSwitchText {
+  width: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRight {
+  left: 40px;
+}
+/* Round Shape1 */
+.mblSwRoundShape1 {
+  width: 77px;
+}
+.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwRoundShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 14px;
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 13px;
+}
+.mblSwRoundShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Round Shape2 */
+.mblSwRoundShape2 {
+  width: 94px;
+}
+.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBg {
+  border-radius: 14px;
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 13px;
+}
+.mblSwRoundShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Arc Shape1 */
+.mblSwArcShape1 {
+  width: 77px;
+}
+.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwArcShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 5px/14px;
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Arc Shape2 */
+.mblSwArcShape2 {
+  width: 94px;
+}
+.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBg {
+  border-radius: 5px/14px;
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Default Shape */
+.mblSwDefaultShape {
+  width: 94px;
+}
+.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: -53px;
+}
+.mblSwDefaultShape .mblSwitchBg {
+  border-radius: 2px;
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  left: 53px;
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  left: 53px;
+  width: 41px;
+  border-radius: 2px;
+}
+.mblSwDefaultShape .mblSwitchText {
+  width: 53px;
+}
+.mblSwDefaultShape .mblSwitchTextRight {
+  left: 40px;
 }
diff --git a/dojox/mobile/themes/custom/Switch.less b/dojox/mobile/themes/custom/Switch.less
index 84a1146..51d10ad 100644
--- a/dojox/mobile/themes/custom/Switch.less
+++ b/dojox/mobile/themes/custom/Switch.less
@@ -1,4 +1,7 @@
- at import url("../common/Switch.css");
-
 @import "variables.less";
 @import "../common/Switch.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwSquareShape-styles;
+}
diff --git a/dojox/mobile/themes/custom/Switch_rtl-compat.css b/dojox/mobile/themes/custom/Switch_rtl-compat.css
new file mode 100644
index 0000000..5293453
--- /dev/null
+++ b/dojox/mobile/themes/custom/Switch_rtl-compat.css
@@ -0,0 +1,43 @@
+/* dojox.mobile.Switch Rtl */
+/* Square Shape Rtl */
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
+/* Round Shape1 Rtl */
+.mblSwRoundShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round1-l.gif);
+}
+/* Round Shape2 Rtl */
+.mblSwRoundShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round2-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round2-l.gif);
+}
+/* Arc Shape1 Rtl */
+.mblSwArcShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc1-r.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc1-l.gif);
+}
+/* Switch - Arc Shape2 Rtl */
+.mblSwArcShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc2-r.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc2-l.gif);
+}
+/* Default Shape Rtl */
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
diff --git a/dojox/mobile/themes/custom/Switch_rtl.css b/dojox/mobile/themes/custom/Switch_rtl.css
new file mode 100644
index 0000000..5bb0935
--- /dev/null
+++ b/dojox/mobile/themes/custom/Switch_rtl.css
@@ -0,0 +1,117 @@
+/* dojox.mobile.Switch Rtl */
+/* Switch - common Rtl */
+.mblSwitchRtl {
+  text-align: right;
+}
+.mblListItemRtl .mblSwitch {
+  left: 12px;
+  right: auto;
+}
+.mblSwitchRtl.mblSwitchOn .mblSwitchInner {
+  left: -50px;
+}
+.mblSwitchBgLeftRtl {
+  left: 51px;
+}
+.mblSwitchTextLeftRtl {
+  left: 0px;
+}
+.mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Square Shape Rtl*/
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Round Shape1 Rtl */
+.mblSwitchRtl.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Round Shape2 Rtl */
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Arc Shape1 Rtl */
+.mblSwitchRtl.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Arc Shape2 Rtl */
+.mblSwitchRtl.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Default Shape Rtl */
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwDefaultShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwDefaultShape .mblSwitchTextRightRtl {
+  left: -40px;
+}
diff --git a/dojox/mobile/themes/custom/TabBar-compat.css b/dojox/mobile/themes/custom/TabBar-compat.css
index fb2a1b2..c39354a 100644
--- a/dojox/mobile/themes/custom/TabBar-compat.css
+++ b/dojox/mobile/themes/custom/TabBar-compat.css
@@ -1,55 +1,59 @@
-/* dojox.mobile.TabBarButton */
-.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
-	left: auto;
-}
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
+/* dojox.mobile.TabBar */
 .dj_ie6 .mblTabBar .mblTabBarButton {
-  display: inline; /* IE bug*/
-}
-.mblTabPanelHeader {
-	background-image: url(compat/heading-bg.png);
-}
-.mblTabBar {
-	background-image: url(compat/ui-widget-bg.png);
-}
-.mblTabBarButton, .mblTabButton {
-	background-image: url(compat/ui-widget-bg.png);
-	_background-image: none; /* IE6 */
-}
-.mblTabBar .mblTabBarButton.mblTabButtonSelected {
-	-moz-border-radius: 2px;
-	-o-border-radius: 2px;
-	-ms-border-radius: 2px;
-	border-radius: 2px;
-}
-.mblTabButton:first-child {
-	-moz-border-radius-topleft: 2px;
-	-moz-border-radius-bottomleft: 2px;
-	-o-border-top-left-radius: 2px;
-	-o-border-bottom-left-radius: 2px;
-	-ms-border-top-left-radius: 2px;
-	-ms-border-bottom-left-radius: 2px;
-	border-top-left-radius: 2px;
-	border-bottom-left-radius: 2px;
-}
-.mblTabButton:last-child {
-	-moz-border-radius-topright: 2px;
-	-moz-border-radius-bottomright: 2px;
-	-o-border-top-right-radius: 2px;
-	-o-border-bottom-right-radius: 2px;
-	-ms-border-top-right-radius: 2px;
-	-ms-border-bottom-right-radius: 2px;
-	border-top-right-radius: 2px;
-	border-bottom-right-radius: 2px;
-}
-*html .mblTabButton { /* IE6 hack */
-	behavior: expression(
-		(function(el){
-			if(!el.previousSibling)
-				el.style.borderWidth = "1px";
-			el.style.behavior = "none";
-		})(this)
-	);
-}
-.dj_ie6 .mblTabPanelHeader .mblDomButton {
-	left: 0px;
+  display: inline;
+}
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  background-image: none;
+  background-color: #000000;
+}
+.dj_ff3 .mblTabBarTabBar .mblTabBarButtonSelected {
+  -moz-border-radius: 3px;
+}
+/* barType="segmentedControl" | "standardTab" */
+.mblTabBarSegmentedControl,
+.mblTabBarStandardTab {
+  background-image: url(compat/heading-bg.png);
+}
+.mblTabBarSegmentedControl .mblTabBarButton,
+.mblTabBarStandardTab .mblTabBarButton {
+  background-image: url(compat/tab-seg-button-bg.png);
+}
+.mblTabBarSegmentedControl .mblTabBarButtonSelected,
+.mblTabBarStandardTab .mblTabBarButtonSelected {
+  background-image: url(compat/tab-seg-sel-button-bg.png);
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:first-child {
+  -moz-border-radius-topleft: 5px;
+  -moz-border-radius-bottomleft: 5px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:last-child {
+  -moz-border-radius-topright: 5px;
+  -moz-border-radius-bottomright: 5px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButton {
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 4px;
+}
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  background-image: url(compat/tab-slim-bar-bg.png);
+}
+.dj_gecko .mblTabBarSlimTab {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.dj_gecko .mblTabBarSlimTab .mblTabBarButton {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.dj_gecko .mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-image: -moz-linear-gradient(top, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
+}
+/* barType="flatTab" */
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  background-image: url(compat/tab-tall-bar-bg.png);
+}
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-color: #8c8e8c;
 }
diff --git a/dojox/mobile/themes/custom/TabBar-compat.less b/dojox/mobile/themes/custom/TabBar-compat.less
new file mode 100644
index 0000000..c0476f3
--- /dev/null
+++ b/dojox/mobile/themes/custom/TabBar-compat.less
@@ -0,0 +1,3 @@
+ at import "variables.less";
+ at import "../common/TabBar-compat.less";
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
diff --git a/dojox/mobile/themes/custom/TabBar.css b/dojox/mobile/themes/custom/TabBar.css
index 3362235..60f6408 100644
--- a/dojox/mobile/themes/custom/TabBar.css
+++ b/dojox/mobile/themes/custom/TabBar.css
@@ -1,161 +1,254 @@
+ at import "../common/domButtons/DomButtonWhiteCross.css";
 /* dojox.mobile.TabBar */
 .mblTabBar {
   position: relative;
+  margin: 0px;
   overflow: hidden;
   white-space: nowrap;
-  margin: 0;
-  padding: 0;
-  height: 50px;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-  border-bottom: 1px solid #769dc0;
-  color: #131313;
+  text-overflow: ellipsis;
+  padding: 0px 6px;
+  height: 42px;
   text-align: center;
-}
-.mblTabBarNoIcons {
-  height: 34px;
-}
-.mblTabBarNoText {
-  height: 34px;
+  color: white;
+  border-top: 1px solid #c0c0c0;
+  border-bottom: 1px solid #c0c0c0;
+  text-shadow: none;
 }
 /* dojox.mobile.TabBarButton */
+.mblTabBarFill .mblTabBarButton {
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
 .mblTabBarButton {
+  overflow: hidden;
   cursor: pointer;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-}
-.mblTabBar .mblTabBarButton {
   position: relative;
   list-style-type: none;
   float: left;
-  padding: 5px 0;
 }
-.mblTabBar .mblTabBarButton.mblTabButtonSelected {
-  border-color: #769dc0;
-  background-color: #0064c2;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-  -webkit-border-radius: 2px;
+.mblTabBarButtonIconArea {
+  margin: 0 auto;
+  width: 29px;
 }
-.mblTabBarButtonAnchor {
+.mblTabBarButtonIconParent1 {
   display: block;
-  text-decoration: none;
 }
-.mblTabBarButtonDiv {
-  position: relative;
-  margin-left: auto;
-  margin-right: auto;
-  height: 29px;
-  width: 29px;
+.mblTabBarButtonIconParent2 {
+  display: none;
 }
-.mblTabBarButtonIcon {
-  position: absolute;
-  left: 0;
-  top: 0;
+.mblTabBarButtonSelected .mblTabBarButtonIconParent1 {
+  display: none;
 }
-.mblTabBarButtonSpriteIcon {
-  position: absolute;
+.mblTabBarButtonSelected .mblTabBarButtonIconParent2 {
+  display: block;
 }
-.mblTabBarButtonTextBox {
-  color: #131313;
-  font-family: Helvetica;
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  height: 48px;
+  border-top: 1px solid #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #000000 100%);
+}
+.mblTabBarTabBar .mblTabBarButtonIconArea {
+  padding-top: 4px;
+}
+.mblTabBarTabBar .mblTabBarButtonLabel {
+  font-family: "Helvetica Neue", Helvetica;
   font-size: 11px;
-  font-weight: normal;
+  color: #ffffff;
 }
-.mblTabBarNoIcons .mblTabBarButtonDiv {
-  display: none;
+.mblTabBarTabBar .mblTabBarButtonSelected {
+  border-radius: 3px;
+  background-color: #404040;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424));
+  background-image: linear-gradient(to bottom, #484848 0%, #242424 100%);
 }
-.mblTabBarNoIcons .mblTabBarButtonTextBox {
-  line-height: 39px;
-  font-size: 17px;
+.mblTabBarTabBar .mblTabBarButtonSelected .mblTabBarButtonLabel {
+  color: #ffffff;
 }
-.mblTabBarTop .mblTabButton .mblTabBarButtonDiv {
-  display: none;
+/* barType="segmentedControl" */
+.mblTabBarSegmentedControl {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#dedede));
+  background-image: linear-gradient(to bottom, #f6f6f6 0%, #dedede 100%);
+}
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButton {
+  width: auto;
+  padding: 0 3px;
 }
-.mblTabButton {
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconArea {
   position: relative;
-  float: left;
-  list-style-type: none;
-  cursor: pointer;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  width: 90px;
-  height: 30px;
+}
+.mblTabBarSegmentedControl .mblTabBarButton {
+  margin: 6px 0;
+  width: 100px;
+  height: 29px;
   border-width: 1px 1px 1px 0px;
-  border-style: inset;
-  border-color: #b5bcc7;
-  border-right-color: #b5bcc7;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
   font-family: Helvetica;
-  font-size: 14px;
-  font-weight: normal;
-  color: #131313;
+  font-size: 13px;
+  font-weight: bold;
   text-align: center;
-  line-height: 30px;
-}
-.mblTabButton .mblTabBarButtonAnchor, .mblTabButton .mblTabBarButtonDiv {
-  height: 30px;
+  line-height: 29px;
+  border-style: solid;
+  border-color: #9b9b9b #9b9b9b #9b9b9b #9b9b9b;
+  color: #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
+  text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
 }
-.mblTabButton:first-child {
-  -webkit-border-top-left-radius: 2px;
-  -webkit-border-bottom-left-radius: 2px;
+.mblTabBarSegmentedControl .mblTabBarButton:first-child {
   border-left-width: 1px;
+  border-top-left-radius: 5px;
+  border-bottom-left-radius: 5px;
 }
-.mblTabButton:last-child {
-  -webkit-border-top-right-radius: 2px;
-  -webkit-border-bottom-right-radius: 2px;
-  border-right-color: #b5bcc7;
+.mblTabBarSegmentedControl .mblTabBarButton:last-child {
+  border-top-right-radius: 5px;
+  border-bottom-right-radius: 5px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
 }
-.mblTabButtonSelected .mblTabBarButtonTextBox {
+.mblTabBarSegmentedControl .mblTabBarButtonSelected {
   color: #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e2e2e2), to(#a4a4a4));
+  background-image: linear-gradient(to bottom, #e2e2e2 0%, #a4a4a4 100%);
+  text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
 }
-.mblTabButtonSelected.mblTabButton {
-  background-color: #0064c2;
+.mblHeading .mblTabBarSegmentedControl {
+  display: inline;
+  float: left;
+  height: auto;
+  border: none;
+}
+/* barType="standardTab" */
+.mblTabBarStandardTab {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#dedede));
+  background-image: linear-gradient(to bottom, #f6f6f6 0%, #dedede 100%);
+  border-top: none;
+  border-bottom: none;
+}
+.mblTabBarStandardTab .mblTabBarButton {
+  margin-top: 9px;
+  padding: 9px;
+  border: 1px solid #62676d;
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  color: #000000;
+  border-color: #9b9b9b;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#dedede));
+  background-image: linear-gradient(to bottom, #f6f6f6 0%, #dedede 100%);
 }
-.mblTabButtonHighlighted.mblTabButton {
-  background-color: #007ef5;
+.mblTabBarStandardTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 3px;
+  left: 0px;
 }
-.mblTabButtonImgDiv {
-  display: none;
+.mblTabBarStandardTab .mblTabBarButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e2e2e2), to(#a4a4a4));
+  background-image: linear-gradient(to bottom, #e2e2e2 0%, #a4a4a4 100%);
 }
-.mblTabPanelHeader {
-  position: relative;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  margin: 0;
-  padding: 0;
-  height: 40px;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(2.5%, #ffffff), color-stop(2.5%, rgba(255, 255, 255, 0.14)), color-stop(5%, rgba(255, 255, 255, 0.14)), color-stop(5%, rgba(255, 255, 255, 0.52)), color-stop(7.5%, rgba(255, 255, 255, 0.52)), color-stop(7.5%, rgba(255, 255, 255, 0.68)), color-stop(10%, rgba(255, 255, 255, 0.68)), color-stop(1, rgba(255, 255, 255, 0)));
-  border-bottom: 1px solid #769dc0;
-  color: #131313;
-  font-size: 18px;
+.mblTabBarStandardTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  height: 30px;
+  padding: 0px;
+  border: 1px solid #c0c0c0;
+  background-color: #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.mblTabBarSlimTab .mblTabBarButton {
+  padding: 7px;
+  border-right: 1px solid #4e4e4e;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
   font-family: Helvetica;
-  font-weight: normal;
-  text-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px;
+  font-size: 14px;
+  font-weight: bold;
+  color: white;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
   text-align: center;
-  line-height: 42px;
 }
-.mblTabPanelHeader .mblTabButton {
-  margin-top: 4px;
+.mblTabBarSlimTab .mblTabBarButton:first-child {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
 }
-.mblTabPanelHeader .mblTabButton.mblTabButtonSelected {
-  background-color: #0064c2;
+.mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-color: #404040;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#313031), to(#959595), color-stop(0.5, #5a555a), color-stop(0.5, #616161));
+  background-image: linear-gradient(to bottom, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
 }
-.mblTabPanelHeader .mblTabButtonDomButton {
-  width: 43px;
+.mblTabBarSlimTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="flatTab" */
+.mblTabBarFlatTab {
+  height: 30px;
+  padding: 0px;
+  border-style: none;
+  background-color: transparent;
+  background-image: none;
+}
+.mblTabBarFlatTab .mblTabBarButton {
+  padding: 7px;
+  background-image: none;
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
+  text-align: center;
 }
-.mblTabPanelHeader .mblTabButtonDomButtonClass {
-  left: 8px;
+.mblTabBarFlatTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+}
+.mblTabBarFlatTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  height: 64px;
+  border-top: 1px solid #cdd5df;
+  border-bottom: 2px solid #949694;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #000000 100%);
+}
+.mblTabBarTallTab .mblTabBarButton {
+  margin-top: 3px;
+  margin-right: 2px;
+  width: 78px;
+  height: 61px;
+  border-width: 0px 1px 0px 1px;
+  border-style: solid;
+  border-color: black #182018 black #393c39;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100c10), color-stop(0.1, #313031));
+  background-image: linear-gradient(to bottom, #181818 0%, #313031 10%, #100c10 100%);
+  font-family: Helvetica;
+  font-size: 13px;
+  color: white;
+  text-align: center;
 }
-.mblHeading .mblTabPanelHeader .mblTabButton {
-  margin-top: 5px;
+.mblTabBarTallTab .mblTabBarButtonIconArea {
+  margin-top: 8px;
 }
-.mblHeading .mblTabPanelHeader .mblTabButton:first-child {
-  -webkit-border-top-left-radius: 2px;
-  -webkit-border-bottom-left-radius: 2px;
-  border-left-width: 1px;
+.mblTabBarTallTab .mblTabBarButtonLabel {
+  font-family: "Helvetica Neue", Helvetica;
+  font-size: 11px;
 }
-.mblHeading .mblTabPanelHeader .mblTabButton:last-child {
-  -webkit-border-top-right-radius: 2px;
-  -webkit-border-bottom-right-radius: 2px;
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#a59ea5), to(#848284));
+  background-image: linear-gradient(to bottom, #a59ea5 0%, #848284 100%);
 }
diff --git a/dojox/mobile/themes/custom/TabBar.less b/dojox/mobile/themes/custom/TabBar.less
index 4875c40..4066ecc 100644
--- a/dojox/mobile/themes/custom/TabBar.less
+++ b/dojox/mobile/themes/custom/TabBar.less
@@ -1,2 +1,3 @@
 @import "variables.less";
 @import "../common/TabBar.less";
+ at import "../common/domButtons/DomButtonWhiteCross.css";
diff --git a/dojox/mobile/themes/custom/TabBar_rtl-compat.css b/dojox/mobile/themes/custom/TabBar_rtl-compat.css
new file mode 100644
index 0000000..848279c
--- /dev/null
+++ b/dojox/mobile/themes/custom/TabBar_rtl-compat.css
@@ -0,0 +1,19 @@
+/* barType="segmentedControl" | "standardTab" Rtl */
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  -moz-border-radius-topright: 5px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-bottomright: 5px;
+  -moz-border-radius-bottomleft: 0px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  -moz-border-radius-topleft: 5px;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomleft: 5px;
+  -moz-border-radius-bottomright: 0px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButtonRtl {
+  -moz-border-radius-topright: 4px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 0px;
+}
diff --git a/dojox/mobile/themes/custom/TabBar_rtl.css b/dojox/mobile/themes/custom/TabBar_rtl.css
new file mode 100644
index 0000000..5553209
--- /dev/null
+++ b/dojox/mobile/themes/custom/TabBar_rtl.css
@@ -0,0 +1,89 @@
+/* dojox.mobile.TabBarButton Rtl */
+.mblTabBarButtonRtl {
+  float: right;
+}
+.mblTabBarButtonIconAreaRtl {
+  margin: 0 auto;
+  width: 29px;
+}
+/* barType="tabBar" Rtl */
+.mblTabBarTabBar .mblTabBarButtonIconAreaRtl {
+  padding-top: 4px;
+}
+/* barType="segmentedControl" Rtl */
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconAreaRtl {
+  position: relative;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl {
+  border-width: 1px 0px 1px 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  border-right-width: 1px !important;
+  border-left-width: 0px;
+  border-top-right-radius: 5px;
+  border-top-left-radius: 0px;
+  border-bottom-right-radius: 5px;
+  border-bottom-left-radius: 0px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  border-top-left-radius: 5px;
+  border-top-right-radius: 0px;
+  border-bottom-left-radius: 5px;
+  border-bottom-right-radius: 0px;
+  border-left-width: 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblHeading .mblTabBarSegmentedControl.mblTabBarRtl {
+  float: right;
+}
+/* barType="standardTab" Rtl */
+.mblTabBarStandardTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 3px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarStandardTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="slimTab" Rtl */
+.mblTabBarSlimTab .mblTabBarButtonRtl {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl:first-child {
+  border-right: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="flatTab" Rtl*/
+.mblTabBarFlatTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarFlatTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab .mblTabBarButtonRtl {
+  margin-left: 2px;
+}
+.mblTabBarTallTab .mblTabBarButtonIconAreaRtl {
+  margin-top: 8px;
+}
diff --git a/dojox/mobile/themes/custom/TextArea-compat.css b/dojox/mobile/themes/custom/TextArea-compat.css
index af7e363..7dde72e 100644
--- a/dojox/mobile/themes/custom/TextArea-compat.css
+++ b/dojox/mobile/themes/custom/TextArea-compat.css
@@ -1,7 +1,7 @@
 /* dojox.mobile.TextArea */
 .mblTextArea {
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
+  overflow: auto;
+}
+.dj_ff3 .mblTextArea {
+  -moz-border-radius: 0;
 }
diff --git a/dojox/mobile/themes/custom/TextArea.css b/dojox/mobile/themes/custom/TextArea.css
index d56f3f4..fb3cf29 100644
--- a/dojox/mobile/themes/custom/TextArea.css
+++ b/dojox/mobile/themes/custom/TextArea.css
@@ -1,10 +1,13 @@
 /* dojox.mobile.TextArea */
 .mblTextArea {
   padding: 4px 1px;
-  border: #b5bcc7 1px inset;
+  border-width: 1px;
+  border-style: inset;
   font-family: Helvetica;
-  font-size: 14px;
-  -webkit-border-radius: 5px;
+  font-size: 13px;
+  border: 1px solid #c0c0c0;
+  border-bottom-color: #9b9b9b;
+  border-radius: 0;
 }
 /* dojox.mobile.ExpandingTextArea */
 .mblExpandingTextArea {
diff --git a/dojox/mobile/themes/custom/TextArea.less b/dojox/mobile/themes/custom/TextArea.less
deleted file mode 100644
index c16ffe0..0000000
--- a/dojox/mobile/themes/custom/TextArea.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/TextArea.less";
diff --git a/dojox/mobile/themes/custom/TextBox-compat.css b/dojox/mobile/themes/custom/TextBox-compat.css
index 32dcf46..d804aa1 100644
--- a/dojox/mobile/themes/custom/TextBox-compat.css
+++ b/dojox/mobile/themes/custom/TextBox-compat.css
@@ -1,7 +1,4 @@
 /* dojox.mobile.TextBox */
-.mblTextBox {
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
+.dj_ff3 .mblTextBox {
+  -moz-border-radius: 0;
 }
diff --git a/dojox/mobile/themes/custom/TextBox.css b/dojox/mobile/themes/custom/TextBox.css
index 65a63bf..a01a5f3 100644
--- a/dojox/mobile/themes/custom/TextBox.css
+++ b/dojox/mobile/themes/custom/TextBox.css
@@ -1,8 +1,11 @@
 /* dojox.mobile.TextBox */
 .mblTextBox {
-  height: 30px;
-  border: #b5bcc7 1px inset;
+  height: 22px;
+  border-width: 1px;
+  border-style: inset;
   font-family: Helvetica;
-  font-size: 14px;
-  -webkit-border-radius: 5px;
+  font-size: 13px;
+  border: 1px solid #c0c0c0;
+  border-bottom-color: #9b9b9b;
+  border-radius: 0;
 }
diff --git a/dojox/mobile/themes/custom/TextBox.less b/dojox/mobile/themes/custom/TextBox.less
deleted file mode 100644
index c83890a..0000000
--- a/dojox/mobile/themes/custom/TextBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/TextBox.less";
diff --git a/dojox/mobile/themes/custom/TimePicker.css b/dojox/mobile/themes/custom/TimePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/custom/TimePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/custom/ToggleButton-compat.css b/dojox/mobile/themes/custom/ToggleButton-compat.css
index c1333a9..2086dd8 100644
--- a/dojox/mobile/themes/custom/ToggleButton-compat.css
+++ b/dojox/mobile/themes/custom/ToggleButton-compat.css
@@ -1,21 +1,42 @@
 /* dojox.mobile.ToggleButton */
 .mblToggleButton {
-	background-image: url(compat/ui-widget-bg.png);
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
-}
-.mblToggleButton.mblToggleButtonChecked::after {
-	-moz-transform: translate(-25px,0px) rotate(45deg) skew(10deg);
-	-o-transform: rotate(45deg) skew(10deg);
-	-ms-transform: rotate(45deg) skew(10deg);
-	transform: rotate(45deg) skew(10deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
+  background-image: url(compat/button-bg.png);
+}
+.mblToggleButtonSelected {
+  background-image: url(compat/button-sel-bg.png);
+}
+.mblToggleButtonChecked {
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblToggleButton {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+}
+.dj_gecko .mblToggleButtonSelected {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_gecko .mblToggleButtonChecked {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+}
+.dj_gecko .mblToggleButtonChecked:after {
+  -moz-transform: rotate(45deg) skew(10deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_ff3 .mblToggleButton {
+  -moz-border-radius: 0;
 }
 .dj_ff3 .mblToggleButton.mblToggleButtonChecked::after {
-	-moz-transform: translate(-25px,-6px) rotate(45deg) skew(10deg);
+  -moz-transform: translate(-25px, -6px) rotate(45deg) skew(10deg);
+}
+.dj_ie .mblToggleButtonChecked:after {
+  top: 9px;
+  left: 5px;
+  width: 12px;
+  border: none;
+  background-image: url(compat/togglebutton-chk-mark-bg.png);
 }
diff --git a/dojox/mobile/themes/custom/ToggleButton.css b/dojox/mobile/themes/custom/ToggleButton.css
index 9932572..c129325 100644
--- a/dojox/mobile/themes/custom/ToggleButton.css
+++ b/dojox/mobile/themes/custom/ToggleButton.css
@@ -1,52 +1,58 @@
 /* dojox.mobile.ToggleButton */
 .mblToggleButton {
   position: relative;
+  padding: 0 10px 0 25px;
+  height: 29px;
+  border-width: 1px 1px 1px 1px;
+  border-style: outset;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
+  font-family: Helvetica;
+  line-height: 29px;
   cursor: pointer;
-  outline: none;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  padding: 0 8px 0 23px;
-  height: 30px;
-  border: 1px outset #b5bcc7;
-  -webkit-border-radius: 2px;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-  font-family: Helvetica;
-  font-weight: normal;
-  line-height: 30px;
-  color: #131313;
-  line-height: 30px;
+  border: 1px solid #c0c0c0;
+  border-bottom-color: #9b9b9b;
+  border-radius: 0;
+  font-size: 13px;
+  color: #000000;
+}
+.mblToggleButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
 }
-.mblToggleButton.mblToggleButtonSelected {
-  border-color: #769dc0;
-  background-color: #0064c2;
+.mblToggleButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
+  color: #ffffff;
 }
-.mblToggleButton.mblToggleButtonChecked {
-  border-color: #769dc0;
-  background-color: #007ef5;
+.mblToggleButtonChecked {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
+  color: #000000;
 }
-.mblToggleButton.mblToggleButtonChecked::after {
+.mblToggleButtonChecked:after {
   position: absolute;
   content: "";
-  top: 7.5px;
+  top: 6px;
   left: 7px;
   width: 5px;
   height: 10px;
-  border-color: #000000;
-  border-width: 0.15em;
+  border-width: 2px;
   border-style: none solid solid none;
   -webkit-transform: rotate(45deg) skew(10deg);
+  transform: rotate(45deg) skew(10deg);
   -webkit-transform-origin: 50% 50%;
-}
-.mblToggleButton.mblToggleButtonChecked.mblToggleButtonSelected {
-  border-color: #769dc0;
-  background-color: #0064c2;
-}
-.mblToggleButton.mblToggleButtonChecked.mblToggleButtonSelected::after {
+  transform-origin: 50% 50%;
   border-color: #000000;
 }
-.mblToggleButton:disabled {
-  cursor: default;
-  color: grey;
-  border-color: grey;
-  background-color: #8fc9ff;
+.mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
+  color: #ffffff;
+}
+.mblToggleButtonChecked.mblToggleButtonSelected:after {
+  border-color: #ffffff;
 }
diff --git a/dojox/mobile/themes/custom/ToggleButton.less b/dojox/mobile/themes/custom/ToggleButton.less
deleted file mode 100644
index bdce40f..0000000
--- a/dojox/mobile/themes/custom/ToggleButton.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ToggleButton.less";
diff --git a/dojox/mobile/themes/custom/ToggleButton_rtl.css b/dojox/mobile/themes/custom/ToggleButton_rtl.css
new file mode 100644
index 0000000..16d136f
--- /dev/null
+++ b/dojox/mobile/themes/custom/ToggleButton_rtl.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.ToggleButton Rtl */
+.mblToggleButtonRtl {
+  padding: 0 25px 0 10px!important;
+}
+.mblToggleButtonRtl.mblToggleButtonChecked:after {
+  right: 7px;
+}
diff --git a/dojox/mobile/themes/custom/ToolBarButton-compat.css b/dojox/mobile/themes/custom/ToolBarButton-compat.css
new file mode 100644
index 0000000..5363133
--- /dev/null
+++ b/dojox/mobile/themes/custom/ToolBarButton-compat.css
@@ -0,0 +1,63 @@
+/* dojox.mobile.ToolBarButton */
+.dj_gecko .mblToolBarButtonArrow {
+  -moz-transform: scale(0.77, 1.05) rotate(45deg);
+}
+.dj_ff3 .mblToolBarButtonArrow {
+  -moz-border-radius: 1px;
+}
+.dj_ff3 .mblToolBarButtonBody {
+  -moz-border-radius: 0;
+}
+.dj_ff3 .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  -moz-border-radius-topleft: 0;
+  -moz-border-radius-bottomleft: 0;
+}
+.dj_ff3 .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 0;
+}
+.dj_ie .mblToolBarButtonLeftArrow {
+  top: 0;
+  left: -2px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonLeftArrow {
+  background-image: url(compat/arrow-button-head-sel.png);
+}
+.dj_ie .mblToolBarButtonRightArrow {
+  top: 0;
+  right: -3px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-right-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonRightArrow {
+  background-image: url(compat/arrow-button-right-head-sel.png);
+}
+.dj_ie .mblToolBarButtonBody {
+  background-image: url(compat/arrow-button-bg.png);
+  background-position: left bottom;
+}
+.dj_ie .mblToolBarButtonBodySelected {
+  background-image: url(compat/arrow-button-bg-sel.png);
+}
+.dj_ie .mblToolBarButtonBody table {
+  margin: 0;
+}
+.dj_ie .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.dj_ie .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.dj_ie6 .mblToolBarButton .mblToolBarButtonBody {
+  background-position: left top;
+}
diff --git a/dojox/mobile/themes/custom/ToolBarButton.css b/dojox/mobile/themes/custom/ToolBarButton.css
index c02a12e..d779b41 100644
--- a/dojox/mobile/themes/custom/ToolBarButton.css
+++ b/dojox/mobile/themes/custom/ToolBarButton.css
@@ -1,32 +1,94 @@
 /* dojox.mobile.ToolBarButton */
 .mblToolBarButton {
-  float: left;
+  display: inline-block;
   position: relative;
-  overflow: hidden;
   cursor: pointer;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  margin: 8px;
-  height: 30px;
-  border: 1px inset #b5bcc7;
-  -webkit-border-radius: 2px;
-  font-size: 14px;
+  margin: 6px;
+  padding: 0 10px;
+  height: 29px;
+  line-height: 29px;
+  text-align: center;
   font-family: Helvetica;
-  font-weight: normal;
+  font-size: 13px;
+  font-weight: bold;
+  vertical-align: middle;
   text-shadow: none;
-  color: #131313;
-  line-height: 30px;
-  text-align: center;
 }
-.mblToolBarButton.mblArrowButtonText {
-  margin: 6px 8px;
+.mblToolBarButtonHasIcon,
+.mblToolBarButtonLightIcon {
+  padding: 0;
 }
-.mblToolBarButtonIcon {
-  position: relative;
-  top: 2px;
+.mblHeading .mblToolBarButton {
+  float: left;
 }
-.mblToolBarButtonSpriteIcon {
+.mblHeading span.mblToolBarButtonLightIcon {
+  padding: 0;
+}
+.mblToolBarButtonHasLeftArrow {
+  padding-right: 0;
+  padding-left: 10px;
+}
+.mblToolBarButtonHasRightArrow {
+  padding-left: 0;
+  padding-right: 10px;
+}
+.mblToolBarButtonArrow {
   position: absolute;
+  top: 5px;
+  width: 20px;
+  height: 19px;
+  border-radius: 1px;
+  -webkit-transform: scale(0.7, 1.05) rotate(45deg);
+  transform: scale(0.7, 1.05) rotate(45deg);
+  border: 1px solid #9b9b9b;
+  border-right-color: #767676;
+  border-bottom-color: #767676;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: -1px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: -1px;
+}
+.mblToolBarButtonBody {
+  display: inline-block;
+  position: relative;
+  overflow: hidden;
+  border-radius: 0;
+  border: 1px solid #9b9b9b;
+  border-bottom-color: #767676;
+  text-shadow: rgba(255, 255, 255, 0.5) 0 1px 0;
+}
+.mblToolBarButton .mblToolBarButtonBody {
+  width: 100%;
+}
+.mblToolBarButtonBody table {
+  margin: 0 auto;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-left-width: 0;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-right-width: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.mblToolBarButtonText .mblToolBarButtonIcon {
+  padding-left: 10px;
+}
+.mblToolBarButtonText .mblToolBarButtonLabel {
+  padding-right: 10px;
+  height: 29px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonIcon {
+  padding-left: 4px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonLabel {
+  padding-right: 4px;
 }
-.mblToolBarButtonText {
-  padding: 0px 10px;
+.mblToolBarButtonIcon > div {
+  height: 29px;
 }
diff --git a/dojox/mobile/themes/custom/ToolBarButton.less b/dojox/mobile/themes/custom/ToolBarButton.less
deleted file mode 100644
index 3b67bdc..0000000
--- a/dojox/mobile/themes/custom/ToolBarButton.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ToolBarButton.less";
diff --git a/dojox/mobile/themes/custom/ToolBarButton_rtl.css b/dojox/mobile/themes/custom/ToolBarButton_rtl.css
new file mode 100644
index 0000000..4c54f0d
--- /dev/null
+++ b/dojox/mobile/themes/custom/ToolBarButton_rtl.css
@@ -0,0 +1,18 @@
+/* dojox.mobile.ToolBarButton Rtl */
+.mblHeading .mblToolBarButtonRtl {
+  float: right;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonIcon {
+  padding-right: 10px;
+  padding-left: 0px;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonLabel {
+  padding-left: 10px;
+  padding-right: 0px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: 1px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: 0px;
+}
diff --git a/dojox/mobile/themes/custom/Tooltip-compat.css b/dojox/mobile/themes/custom/Tooltip-compat.css
index a028ad7..0362580 100644
--- a/dojox/mobile/themes/custom/Tooltip-compat.css
+++ b/dojox/mobile/themes/custom/Tooltip-compat.css
@@ -1,47 +1,40 @@
 /* dojox.mobile.Tooltip */
 .mblTooltip {
-	-moz-border-radius: 8px;
-	-o-border-radius: 8px;
-	-ms-border-radius: 8px;
-	border-radius: 8px;
-	background-image: none;
+  background-image: none;
 }
-.mblTooltipBefore .mblTooltipArrow {
-	*right: 0; /* IE 7 quirks */
-}
-.mblTooltipAbove .mblTooltipArrow {
-	*bottom: 0px; /* IE 7 quirks */
-}
-.mblTooltipBefore .mblTooltipInnerArrow {
-	*right: -1px; /* IE 7 quirks */
-}
-.mblTooltipAbove .mblTooltipInnerArrow {
-	*bottom: -1px;  /* IE 7 quirks */
-}
-.mblTooltipBefore .mblTooltipInnerArrow {
-	border-right-color: #5cb0ff;
-}
-.mblTooltipAfter .mblTooltipInnerArrow {
-	border-left-color: #5cb0ff;
-}
-.mblTooltipAbove .mblTooltipInnerArrow {
-	border-bottom-color: #5cb0ff;
-}
-.mblTooltipBelow .mblTooltipInnerArrow {
-	border-top-color: #5cb0ff;
-}
-.mblTooltip .mblHeading {
-	*padding: 0 9px 15px;
-	*border-top: 1px solid #5cb0ff;
-	*border-bottom: 1px solid #5cb0ff;
-	*width: auto;
-	*height: auto;
-	*overflow: visible;
-	*line-height: normal;
+.dj_ff3 .mblTooltip {
+  -moz-border-radius: 3px;
 }
 .dj_ie9 .mblTooltip .mblHeading {
-	width: auto;
-}
-.mblTooltip .mblHeading .mblToolBarButton {
-	*margin: auto 6px;
+  width: auto;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipArrow {
+  right: 0;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipArrow {
+  bottom: 0;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipInnerArrow {
+  right: -1px;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipInnerArrow {
+  bottom: -1px;
+}
+.dj_ie6 .mblTooltip .mblHeading,
+.dj_ie7 .mblTooltip .mblHeading {
+  padding: 0 9px 12px;
+  border-top: 1px solid #dedede;
+  border-bottom: 1px solid #dedede;
+  width: auto;
+  height: auto;
+  overflow: visible;
+  line-height: normal;
+}
+.dj_ie6 .mblTooltip .mblHeading .mblToolBarButton,
+.dj_ie7 .mblTooltip .mblHeading .mblToolBarButton {
+  margin: auto 6px;
 }
diff --git a/dojox/mobile/themes/custom/Tooltip.css b/dojox/mobile/themes/custom/Tooltip.css
index 2269de4..daf87e6 100644
--- a/dojox/mobile/themes/custom/Tooltip.css
+++ b/dojox/mobile/themes/custom/Tooltip.css
@@ -4,30 +4,33 @@
   z-index: 2000;
   display: block;
   margin: 0;
-  padding: 8px;
-  border: #769dc0 1px solid;
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-  -webkit-border-radius: 5px;
+  padding: 5px;
+  border-width: 1px;
+  border-style: solid;
   opacity: .97;
+  border-color: #000000;
+  border-radius: 3px;
+  background-color: #dedede;
+  background-image: none;
 }
 .mblTooltipBubble {
   overflow: visible;
   padding: 3px;
-  background-color: #5cb0ff;
+  background-color: #f6f6f6;
   background-image: none;
+  color: #000000;
 }
 .mblTooltipBubble.mblTooltipAbove .mblTooltipInnerArrow {
-  border-bottom-color: #5cb0ff;
+  border-bottom-color: #f6f6f6;
 }
 .mblTooltipBubble.mblTooltipBelow .mblTooltipInnerArrow {
-  border-top-color: #5cb0ff;
+  border-top-color: #f6f6f6;
 }
 .mblTooltipBubble.mblTooltipAfter .mblTooltipInnerArrow {
-  border-left-color: #5cb0ff;
+  border-left-color: #f6f6f6;
 }
 .mblTooltipBubble.mblTooltipBefore .mblTooltipInnerArrow {
-  border-right-color: #5cb0ff;
+  border-right-color: #f6f6f6;
 }
 .mblTooltip.mblTooltipAfter {
   margin-left: -11px;
@@ -74,7 +77,7 @@
   top: 0;
   bottom: auto;
   border-left-width: 0;
-  border-right-color: #769dc0;
+  border-right-color: #9b9b9b;
 }
 .mblTooltipAfter .mblTooltipArrow {
   left: 1px;
@@ -82,7 +85,7 @@
   top: 0;
   bottom: auto;
   border-right-width: 0;
-  border-left-color: #769dc0;
+  border-left-color: #9b9b9b;
 }
 .mblTooltipAbove .mblTooltipArrow {
   top: auto;
@@ -90,7 +93,7 @@
   left: auto;
   right: auto;
   border-top-width: 0;
-  border-bottom-color: #769dc0;
+  border-bottom-color: #9b9b9b;
 }
 .mblTooltipBelow .mblTooltipArrow {
   top: 1px;
@@ -98,7 +101,7 @@
   left: auto;
   right: auto;
   border-bottom-width: 0;
-  border-top-color: #769dc0;
+  border-top-color: #9b9b9b;
 }
 .mblTooltipInnerArrow {
   position: absolute;
@@ -111,30 +114,36 @@
   right: 0;
   top: 0;
   border-left-width: 0;
-  border-right-color: #deefff;
+  border-right-color: #dedede;
 }
 .mblTooltipAfter .mblTooltipInnerArrow {
   left: 0;
   top: 0;
   border-right-width: 0;
-  border-left-color: #deefff;
+  border-left-color: #dedede;
 }
 .mblTooltipAbove .mblTooltipInnerArrow {
   bottom: 0;
   left: 0;
   border-top-width: 0;
-  border-bottom-color: #ffffff;
+  border-bottom-color: #dedede;
 }
 .mblTooltipBelow .mblTooltipInnerArrow {
   top: 0;
   left: 0;
   border-bottom-width: 0;
-  border-top-color: #aed8ff;
+  border-top-color: #dedede;
 }
-.mblTooltipHidden, .mblTooltipHidden * {
+.mblTooltipHidden,
+.mblTooltipHidden * {
   visibility: hidden !important;
 }
+.mblTooltipHidden {
+  top: -99999px !important;
+  left: -99999px !important;
+}
 .mblTooltip .mblHeading {
+  padding-bottom: 3px;
   border-top: 1px solid transparent;
   border-bottom: 1px solid transparent;
   background-color: transparent;
diff --git a/dojox/mobile/themes/custom/Tooltip.less b/dojox/mobile/themes/custom/Tooltip.less
deleted file mode 100644
index 60af6d1..0000000
--- a/dojox/mobile/themes/custom/Tooltip.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Tooltip.less";
diff --git a/dojox/mobile/themes/custom/ValuePicker-compat.css b/dojox/mobile/themes/custom/ValuePicker-compat.css
new file mode 100644
index 0000000..34be307
--- /dev/null
+++ b/dojox/mobile/themes/custom/ValuePicker-compat.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.ValuePicker */
+.mblValuePickerSlotButton {
+  background-image: url(compat/valuepicker-button-bg.png);
+}
+.mblValuePickerSlotButtonSelected {
+  background-color: #999999;
+}
+.mblValuePickerSlotInputArea {
+  background-color: #f7f7f7;
+}
+.dj_gecko .mblValuePickerSlotButton {
+  background-image: -moz-linear-gradient(top, #f7f7f7 0%, #d6d6d6 50%, #bdbdbd 90%, #d6d6d6 100%);
+}
+.dj_gecko .mblValuePickerSlotButtonSelected {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_gecko .mblValuePickerSlotInputArea {
+  background-image: -moz-linear-gradient(top, #fafafa 10%, #fafafa 20%, #ffffff 50%, #ffffff 90%);
+}
diff --git a/dojox/mobile/themes/custom/ValuePicker.css b/dojox/mobile/themes/custom/ValuePicker.css
new file mode 100644
index 0000000..91abcf9
--- /dev/null
+++ b/dojox/mobile/themes/custom/ValuePicker.css
@@ -0,0 +1,57 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+/* dojox.mobile.ValuePicker */
+.mblValuePicker {
+  height: 126px;
+}
+/* dojox.mobile.ValuePickerSlot */
+.mblValuePicker > .mblValuePickerSlot {
+  float: left;
+  margin: 0 5px;
+}
+.mblValuePickerSlotButton {
+  position: relative;
+  height: 38px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f7f7f7), to(#d6d6d6), color-stop(0.5, #d6d6d6), color-stop(0.9, #bdbdbd));
+  background-image: linear-gradient(to bottom, #f7f7f7 0%, #d6d6d6 50%, #bdbdbd 90%, #d6d6d6 100%);
+}
+.mblValuePickerSlotPlusButton {
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+}
+.mblValuePickerSlotMinusButton {
+  border-bottom-left-radius: 5px;
+  border-bottom-right-radius: 5px;
+}
+.mblValuePickerSlotButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
+}
+.mblValuePickerSlotIcon {
+  top: 5px;
+  margin: 0 auto;
+}
+.mblValuePickerSlotInputArea {
+  position: relative;
+  height: 48px;
+  border-top: 1px solid #7b797b;
+  border-bottom: 1px solid #c6c3c6;
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.1, #fafafa), color-stop(0.2, #fafafa), color-stop(0.5, #ffffff), color-stop(0.9, #ffffff));
+  background-image: linear-gradient(to bottom, #fafafa 10%, #fafafa 20%, #ffffff 50%, #ffffff 90%);
+}
+.mblValuePickerSlotInput {
+  display: block;
+  width: 90%;
+  height: 90%;
+  margin: 5% auto;
+  padding: 0;
+  text-align: center;
+  border-style: none;
+  background-color: transparent;
+  font-size: 28px;
+}
+/* dojox.mobile.ValuePickerTimePicker */
+.mblValuePickerTimePicker > .mblToolBarButton {
+  top: 45px;
+}
diff --git a/dojox/mobile/themes/custom/ValuePicker.less b/dojox/mobile/themes/custom/ValuePicker.less
new file mode 100644
index 0000000..1561b85
--- /dev/null
+++ b/dojox/mobile/themes/custom/ValuePicker.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+
+ at import "variables.less";
+ at import "../common/ValuePicker.less";
diff --git a/dojox/mobile/themes/custom/View.css b/dojox/mobile/themes/custom/View.css
index 1600cde..e60b686 100644
--- a/dojox/mobile/themes/custom/View.css
+++ b/dojox/mobile/themes/custom/View.css
@@ -9,7 +9,7 @@
   top: 0px;
   left: 0px;
   width: 100%;
-  color: #131313;
+  color: #000000;
 }
 .mblView.mblIn {
   position: absolute;
diff --git a/dojox/mobile/themes/custom/base-compat.css b/dojox/mobile/themes/custom/base-compat.css
index 9c9c207..6689f7c 100644
--- a/dojox/mobile/themes/custom/base-compat.css
+++ b/dojox/mobile/themes/custom/base-compat.css
@@ -1,8 +1,8 @@
 @import url("common-compat.css");
 @import url("Heading-compat.css");
+ at import url("ToolBarButton-compat.css");
 @import url("RoundRect-compat.css");
 @import url("RoundRectList-compat.css");
- at import url("EdgeToEdgeCategory-compat.css");
 @import url("ListItem-compat.css");
 @import url("Switch-compat.css");
 @import url("ProgressIndicator-compat.css");
diff --git a/dojox/mobile/themes/custom/base_rtl-compat.css b/dojox/mobile/themes/custom/base_rtl-compat.css
new file mode 100644
index 0000000..71390e0
--- /dev/null
+++ b/dojox/mobile/themes/custom/base_rtl-compat.css
@@ -0,0 +1,3 @@
+ at import url("ListItem_rtl-compat.css");
+
+ at import url("Switch_rtl-compat.css");
diff --git a/dojox/mobile/themes/custom/base_rtl.css b/dojox/mobile/themes/custom/base_rtl.css
new file mode 100644
index 0000000..16f6b6c
--- /dev/null
+++ b/dojox/mobile/themes/custom/base_rtl.css
@@ -0,0 +1,7 @@
+ at import url("ToolBarButton_rtl.css");
+
+ at import url("RoundRectCategory_rtl.css");
+
+ at import url("ListItem_rtl.css");
+
+ at import url("Switch_rtl.css");
diff --git a/dojox/mobile/themes/custom/common-compat.css b/dojox/mobile/themes/custom/common-compat.css
index 963af00..66f1930 100644
--- a/dojox/mobile/themes/custom/common-compat.css
+++ b/dojox/mobile/themes/custom/common-compat.css
@@ -1,8 +1,18 @@
-/* Button Colors */
-.mblColorBlue {
-  background-image: url(compat/ui-widget-bg.png);
+.dj_gecko .mblColorBlue {
+  background-image: -moz-linear-gradient(top, #48adfc 0%, #048bf4 100%);
 }
-/* Default Button Colors */
-.mblColorDefault {
-  background-image: url(compat/ui-widget-bg.png);
+.dj_gecko .mblColorBlue45 {
+  background-image: -moz-linear-gradient(top left, #048bf4 0%, #48adfc 100%);
+}
+.dj_gecko .mblColorDefault {
+  background-image: -moz-linear-gradient(top, #e2e2e2 0%, #a4a4a4 100%);
+}
+.dj_gecko .mblColorDefault45 {
+  background-image: -moz-linear-gradient(top left, #e2e2e2 0%, #a4a4a4 100%);
+}
+.dj_gecko .mblColorDefaultSel {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_gecko .mblColorDefaultSel45 {
+  background-image: -moz-linear-gradient(top left, #bbbbbb 0%, #999999 100%);
 }
diff --git a/dojox/mobile/themes/custom/common.css b/dojox/mobile/themes/custom/common.css
index 8c097ff..acd3e0f 100644
--- a/dojox/mobile/themes/custom/common.css
+++ b/dojox/mobile/themes/custom/common.css
@@ -1,31 +1,58 @@
-html.mobile, .mobile body {
+html.mobile,
+.mobile body {
   width: 100%;
-  margin: 0px;
-  padding: 0px;
+  margin: 0;
+  padding: 0;
 }
 .mobile body {
   overflow-x: hidden;
   -webkit-text-size-adjust: none;
-  background-color: #eff1f3;
   font-family: Helvetica;
-  font-size: 14px;
+  font-size: 17px;
+  color: #000000;
+}
+.mblBackground {
+  background-color: #c0c0c0;
 }
 /* Button Colors */
 .mblColorBlue {
-  background-color: #366EDF;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
+  color: #ffffff;
+  background-color: #048bf4;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#48adfc), to(#048bf4));
+  background-image: linear-gradient(to bottom, #48adfc 0%, #048bf4 100%);
+}
+.mblColorBlue45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#048bf4), to(#48adfc));
+  background-image: linear-gradient(to right bottom, #048bf4 0%, #48adfc 100%);
 }
 /* Default Button Colors */
 .mblColorDefault {
-  background-color: #5cb0ff;
-  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ffffff), color-stop(3.3333333333333335%, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
+  color: #000000;
+  background-color: #a4a4a4;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e2e2e2), to(#a4a4a4));
+  background-image: linear-gradient(to bottom, #e2e2e2 0%, #a4a4a4 100%);
 }
-.mblColorDefault.mblDomButton {
-  background-color: #5cb0ff;
+.mblColorDefault45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#e2e2e2), to(#a4a4a4));
+  background-image: linear-gradient(to right bottom, #e2e2e2 0%, #a4a4a4 100%);
 }
 .mblColorDefaultSel {
-  background-color: #0064c2;
+  color: #ffffff;
+  background-color: #999999;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
+}
+.mblColorDefaultSel45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to right bottom, #bbbbbb 0%, #999999 100%);
+}
+.mblSpriteIcon {
+  position: absolute;
+}
+.mblSpriteIconParent {
+  position: relative;
+  font-size: 1px;
 }
-.mblColorDefaultSel.mblDomButton {
-  background-color: #0064c2;
+.mblImageIcon {
+  vertical-align: top;
 }
diff --git a/dojox/mobile/themes/custom/compat/arrow-button-bg-sel.png b/dojox/mobile/themes/custom/compat/arrow-button-bg-sel.png
new file mode 100644
index 0000000..961e214
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/arrow-button-bg-sel.png differ
diff --git a/dojox/mobile/themes/custom/compat/arrow-button-bg.png b/dojox/mobile/themes/custom/compat/arrow-button-bg.png
new file mode 100644
index 0000000..36ea74e
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/arrow-button-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/arrow-button-head-sel.png b/dojox/mobile/themes/custom/compat/arrow-button-head-sel.png
new file mode 100644
index 0000000..fe96456
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/arrow-button-head-sel.png differ
diff --git a/dojox/mobile/themes/custom/compat/arrow-button-head.png b/dojox/mobile/themes/custom/compat/arrow-button-head.png
index 12dad4e..24d52ee 100644
Binary files a/dojox/mobile/themes/custom/compat/arrow-button-head.png and b/dojox/mobile/themes/custom/compat/arrow-button-head.png differ
diff --git a/dojox/mobile/themes/custom/compat/arrow-button-right-head-sel.png b/dojox/mobile/themes/custom/compat/arrow-button-right-head-sel.png
new file mode 100644
index 0000000..96fd99e
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/arrow-button-right-head-sel.png differ
diff --git a/dojox/mobile/themes/custom/compat/arrow-button-right-head.png b/dojox/mobile/themes/custom/compat/arrow-button-right-head.png
new file mode 100644
index 0000000..17a72f0
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/arrow-button-right-head.png differ
diff --git a/dojox/mobile/themes/custom/compat/blue-button-bg.png b/dojox/mobile/themes/custom/compat/blue-button-bg.png
new file mode 100644
index 0000000..11e6fd3
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/blue-button-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/blue-button-sel-bg.png b/dojox/mobile/themes/custom/compat/blue-button-sel-bg.png
new file mode 100644
index 0000000..7857833
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/blue-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/button-arrow-head-bg.gif b/dojox/mobile/themes/custom/compat/button-arrow-head-bg.gif
new file mode 100644
index 0000000..5d01ac0
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/button-arrow-head-bg.gif differ
diff --git a/dojox/mobile/themes/custom/compat/button-bg.png b/dojox/mobile/themes/custom/compat/button-bg.png
new file mode 100644
index 0000000..d1582e1
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/button-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/button-chk-bg.png b/dojox/mobile/themes/custom/compat/button-chk-bg.png
new file mode 100644
index 0000000..d1582e1
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/button-chk-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/button-sel-bg.png b/dojox/mobile/themes/custom/compat/button-sel-bg.png
new file mode 100644
index 0000000..7857833
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/button-sel-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/button-unsel-bg.png b/dojox/mobile/themes/custom/compat/button-unsel-bg.png
new file mode 100644
index 0000000..7857833
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/button-unsel-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/heading-bg.png b/dojox/mobile/themes/custom/compat/heading-bg.png
index 22328a7..4fbdb69 100644
Binary files a/dojox/mobile/themes/custom/compat/heading-bg.png and b/dojox/mobile/themes/custom/compat/heading-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/icon-content-heading-bg.png b/dojox/mobile/themes/custom/compat/icon-content-heading-bg.png
new file mode 100644
index 0000000..3daa1a8
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/icon-content-heading-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/red-button-bg.png b/dojox/mobile/themes/custom/compat/red-button-bg.png
new file mode 100644
index 0000000..82efb14
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/red-button-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/red-button-sel-bg.png b/dojox/mobile/themes/custom/compat/red-button-sel-bg.png
new file mode 100644
index 0000000..7857833
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/red-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/slider-h-bar-bg.png b/dojox/mobile/themes/custom/compat/slider-h-bar-bg.png
index 65510ba..977cbbe 100644
Binary files a/dojox/mobile/themes/custom/compat/slider-h-bar-bg.png and b/dojox/mobile/themes/custom/compat/slider-h-bar-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/slider-h-bg.png b/dojox/mobile/themes/custom/compat/slider-h-bg.png
new file mode 100644
index 0000000..79eea5c
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/slider-h-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/slider-handle-bg.png b/dojox/mobile/themes/custom/compat/slider-handle-bg.png
new file mode 100644
index 0000000..637f2e6
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/slider-handle-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/switch-arc1-k.gif b/dojox/mobile/themes/custom/compat/switch-arc1-k.gif
new file mode 100644
index 0000000..c2b1720
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-arc1-k.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-arc1-l.gif b/dojox/mobile/themes/custom/compat/switch-arc1-l.gif
new file mode 100644
index 0000000..c361472
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-arc1-l.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-arc1-r.gif b/dojox/mobile/themes/custom/compat/switch-arc1-r.gif
new file mode 100644
index 0000000..a3e6a3e
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-arc1-r.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-arc2-k.gif b/dojox/mobile/themes/custom/compat/switch-arc2-k.gif
new file mode 100644
index 0000000..3c69045
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-arc2-k.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-arc2-l.gif b/dojox/mobile/themes/custom/compat/switch-arc2-l.gif
new file mode 100644
index 0000000..da6f880
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-arc2-l.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-arc2-r.gif b/dojox/mobile/themes/custom/compat/switch-arc2-r.gif
new file mode 100644
index 0000000..2be33c4
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-arc2-r.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-round1-k.gif b/dojox/mobile/themes/custom/compat/switch-round1-k.gif
new file mode 100644
index 0000000..008f509
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-round1-k.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-round1-l.gif b/dojox/mobile/themes/custom/compat/switch-round1-l.gif
new file mode 100644
index 0000000..af5e4a7
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-round1-l.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-round1-r.gif b/dojox/mobile/themes/custom/compat/switch-round1-r.gif
new file mode 100644
index 0000000..5938bb4
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-round1-r.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-round2-k.gif b/dojox/mobile/themes/custom/compat/switch-round2-k.gif
new file mode 100644
index 0000000..94d1616
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-round2-k.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-round2-l.gif b/dojox/mobile/themes/custom/compat/switch-round2-l.gif
new file mode 100644
index 0000000..880d713
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-round2-l.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-round2-r.gif b/dojox/mobile/themes/custom/compat/switch-round2-r.gif
new file mode 100644
index 0000000..c630135
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-round2-r.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-square-k.gif b/dojox/mobile/themes/custom/compat/switch-square-k.gif
new file mode 100644
index 0000000..8c678e4
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-square-k.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-square-l.gif b/dojox/mobile/themes/custom/compat/switch-square-l.gif
new file mode 100644
index 0000000..ec0890c
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-square-l.gif differ
diff --git a/dojox/mobile/themes/custom/compat/switch-square-r.gif b/dojox/mobile/themes/custom/compat/switch-square-r.gif
new file mode 100644
index 0000000..0fd937a
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/switch-square-r.gif differ
diff --git a/dojox/mobile/themes/custom/compat/tab-seg-button-bg.png b/dojox/mobile/themes/custom/compat/tab-seg-button-bg.png
new file mode 100644
index 0000000..98905bb
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/tab-seg-button-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/tab-seg-sel-button-bg.png b/dojox/mobile/themes/custom/compat/tab-seg-sel-button-bg.png
new file mode 100644
index 0000000..d6ad2ec
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/tab-seg-sel-button-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/tab-slim-bar-bg.png b/dojox/mobile/themes/custom/compat/tab-slim-bar-bg.png
new file mode 100644
index 0000000..f982afb
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/tab-slim-bar-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/tab-tall-bar-bg.png b/dojox/mobile/themes/custom/compat/tab-tall-bar-bg.png
new file mode 100644
index 0000000..50a2371
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/tab-tall-bar-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/togglebutton-chk-mark-bg.png b/dojox/mobile/themes/custom/compat/togglebutton-chk-mark-bg.png
new file mode 100644
index 0000000..853bbaf
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/togglebutton-chk-mark-bg.png differ
diff --git a/dojox/mobile/themes/custom/compat/ui-widget-bg.png b/dojox/mobile/themes/custom/compat/ui-widget-bg.png
deleted file mode 100644
index cb787cb..0000000
Binary files a/dojox/mobile/themes/custom/compat/ui-widget-bg.png and /dev/null differ
diff --git a/dojox/mobile/themes/custom/compat/valuepicker-button-bg.png b/dojox/mobile/themes/custom/compat/valuepicker-button-bg.png
new file mode 100644
index 0000000..5d85828
Binary files /dev/null and b/dojox/mobile/themes/custom/compat/valuepicker-button-bg.png differ
diff --git a/dojox/mobile/themes/custom/custom-compat.css b/dojox/mobile/themes/custom/custom-compat.css
index f5a0140..7fcf52b 100644
--- a/dojox/mobile/themes/custom/custom-compat.css
+++ b/dojox/mobile/themes/custom/custom-compat.css
@@ -2,17 +2,22 @@
 
 /* common styles */
 @import url("../common/domButtons-compat.css");
- at import url("../common/SpinWheel-compat.css");
 
 /* widget styles */
+ at import url("Accordion-compat.css");
 @import url("Button-compat.css");
 @import url("CheckBox-compat.css");
 @import url("ComboBox-compat.css");
 @import url("IconContainer-compat.css");
+ at import url("IconMenu-compat.css");
 @import url("Opener-compat.css");
+ at import url("PageIndicator-compat.css");
 @import url("RadioButton-compat.css");
+ at import url("SimpleDialog-compat.css");
 @import url("Slider-compat.css");
+ at import url("SpinWheel-compat.css");
 @import url("TabBar-compat.css");
 @import url("TextArea-compat.css");
 @import url("TextBox-compat.css");
 @import url("ToggleButton-compat.css");
+ at import url("ValuePicker-compat.css");
diff --git a/dojox/mobile/themes/custom/custom.css b/dojox/mobile/themes/custom/custom.css
index a50e0ce..06caeb8 100644
--- a/dojox/mobile/themes/custom/custom.css
+++ b/dojox/mobile/themes/custom/custom.css
@@ -2,21 +2,29 @@
 
 /* common styles */
 @import url("../common/domButtons.css");
- at import url("../common/FixedSplitter.css");
- at import url("../common/SpinWheel.css");
 @import url("../common/transitions.css");
 
 /* widget styles */
+ at import url("Accordion.css");
 @import url("Button.css");
 @import url("Carousel.css");
 @import url("CheckBox.css");
 @import url("ComboBox.css");
+ at import url("FixedSplitter.css");
+ at import url("GridLayout.css");
 @import url("IconContainer.css");
+ at import url("IconMenu.css");
 @import url("Opener.css");
 @import url("PageIndicator.css");
+ at import url("ProgressBar.css");
 @import url("RadioButton.css");
+ at import url("ScrollablePane.css");
+ at import url("SimpleDialog.css");
 @import url("Slider.css");
+ at import url("SpinWheel.css");
 @import url("TabBar.css");
 @import url("TextArea.css");
- at import url("TextBox.css");
+ at import url("SearchBox.css");
 @import url("ToggleButton.css");
+ at import url("ValuePicker.css");
+ at import url("FormLayout.css");
diff --git a/dojox/mobile/themes/custom/custom_rtl-compat.css b/dojox/mobile/themes/custom/custom_rtl-compat.css
new file mode 100644
index 0000000..0143aa0
--- /dev/null
+++ b/dojox/mobile/themes/custom/custom_rtl-compat.css
@@ -0,0 +1,7 @@
+ at import url("base_rtl-compat.css");
+
+ at import url("IconMenu_rtl-compat.css");
+
+ at import url("SpinWheel_rtl-compat.css");
+
+ at import url("TabBar_rtl-compat.css");
diff --git a/dojox/mobile/themes/custom/custom_rtl.css b/dojox/mobile/themes/custom/custom_rtl.css
new file mode 100644
index 0000000..f61e915
--- /dev/null
+++ b/dojox/mobile/themes/custom/custom_rtl.css
@@ -0,0 +1,15 @@
+ at import url("base_rtl.css");
+
+ at import url("Carousel_rtl.css");
+
+ at import url("ComboBox_rtl.css");
+
+ at import url("IconContainer_rtl.css");
+
+ at import url("IconMenu_rtl.css");
+
+ at import url("SpinWheel_rtl.css");
+
+ at import url("TabBar_rtl.css");
+
+ at import url("ToggleButton_rtl.css");
diff --git a/dojox/mobile/themes/custom/dijit/Calendar-compat.css b/dojox/mobile/themes/custom/dijit/Calendar-compat.css
new file mode 100644
index 0000000..194e643
--- /dev/null
+++ b/dojox/mobile/themes/custom/dijit/Calendar-compat.css
@@ -0,0 +1,35 @@
+/* dijit.Calendar */
+.dijitCalendar thead {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-month-bg.png);
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-datelabel-sel-bg.png);
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-datelabel-act-bg.png);
+}
+.dijitCalendarYearLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-year-bg.png);
+}
+.dj_gecko .dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  -moz-box-shadow: 0 0 0 transparent;
+}
+.dj_gecko .dijitCalendar thead {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+}
+.dj_gecko .dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-image: -moz-linear-gradient(top, #e2e2e2 0%, #a4a4a4 100%);
+}
+.dj_gecko .dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-image: -moz-linear-gradient(top, #bbbbbb 0%, #999999 100%);
+}
+.dj_gecko .dijitCalendarYearLabel {
+  background-image: -moz-linear-gradient(top, #ffffff 0%, #e2e2e2 100%);
+}
+.dj_ff3 .dijitCalendar {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/custom/dijit/Calendar-compat.less b/dojox/mobile/themes/custom/dijit/Calendar-compat.less
new file mode 100644
index 0000000..88cd6f0
--- /dev/null
+++ b/dojox/mobile/themes/custom/dijit/Calendar-compat.less
@@ -0,0 +1,2 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar-compat.less";
diff --git a/dojox/mobile/themes/custom/dijit/Calendar.css b/dojox/mobile/themes/custom/dijit/Calendar.css
new file mode 100644
index 0000000..574da3e
--- /dev/null
+++ b/dojox/mobile/themes/custom/dijit/Calendar.css
@@ -0,0 +1,119 @@
+/* if you link this style sheet, dijit/themes/dijit.css must be imported. */
+/* dijit.Calendar */
+.dijitCalendar {
+  padding: 0;
+  width: 320px;
+  border-radius: 0;
+  text-align: center;
+  border: 1px solid #c0c0c0;
+}
+.dijitCalendar thead {
+  border-color: inherit;
+  vertical-align: middle;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
+}
+.dijitCalendarMonthLabel {
+  padding: 0 4px;
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0 1px 0px;
+  color: #000000;
+  font-size: 16px;
+}
+.dijitCalendarMonthMenu .dijitCalendarMonthLabel {
+  background-color: #f2f2f2;
+  color: #000000;
+}
+.dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  padding: 0 3px 0 2px;
+  border: none;
+  background-color: transparent;
+  background-image: none;
+  -webkit-box-shadow: 0 0 0 transparent;
+  box-shadow: 0 0 0 transparent;
+}
+.dijitArrowButtonInner {
+  display: none;
+}
+.dijitCalendarMonthContainer th {
+  border-right: 1px solid transparent;
+}
+.dijitCalendarIncrementControl {
+  width: 0;
+  height: 0;
+  border: 6px solid transparent !important;
+}
+.dijitCalendarDecrease {
+  border-left-width: 0 !important;
+  border-right: 6px solid #9b9b9b !important;
+}
+.dijitCalendarIncrease {
+  border-right-width: 0 !important;
+  border-left: 6px solid #9b9b9b !important;
+}
+.dijitA11ySideArrow {
+  display: none;
+}
+.dijitCalendarDayLabelTemplate {
+  border-right: 1px solid transparent;
+  text-align: center;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  background-color: #f6f6f6;
+  font-size: 12px;
+  color: #000000;
+}
+.dijitCalendarDateTemplate {
+  border-bottom: 1px solid lightGrey;
+  font-family: Helvetica;
+  font-size: 22px;
+  font-weight: normal;
+  text-align: center;
+  border: none;
+  background-color: #ffffff;
+  color: #000000;
+}
+.dijitCalendarDateTemplate:last-child {
+  border-right: none;
+}
+.dijitCalendarDateTemplate .dijitCalendarDateLabel {
+  padding: 3px 5px 3px 4px;
+  display: block;
+  text-decoration: none;
+  border: none;
+}
+.dijitCalendarPreviousMonth .dijitCalendarDateLabel,
+.dijitCalendarNextMonth .dijitCalendarDateLabel {
+  color: lightGrey;
+}
+.dijitCalendarHoveredDate .dijitCalendarDateLabel {
+  color: grey;
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e2e2e2), to(#a4a4a4));
+  background-image: linear-gradient(to bottom, #e2e2e2 0%, #a4a4a4 100%);
+  color: #000000;
+  text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0;
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bbbbbb), to(#999999));
+  background-image: linear-gradient(to bottom, #bbbbbb 0%, #999999 100%);
+}
+.dijitCalendarYearLabel {
+  margin: 0;
+  padding: 0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #e2e2e2 100%);
+}
+.dijitCalendarSelectedYear {
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  color: #000000;
+  font-size: 16px;
+}
+.dijitCalendarNextYear,
+.dijitCalendarPreviousYear {
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  padding: 1px 6px 3px 6px;
+  color: #000000;
+  font-size: 12px;
+}
diff --git a/dojox/mobile/themes/custom/dijit/Calendar.less b/dojox/mobile/themes/custom/dijit/Calendar.less
new file mode 100644
index 0000000..a590903
--- /dev/null
+++ b/dojox/mobile/themes/custom/dijit/Calendar.less
@@ -0,0 +1,2 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar.less";
diff --git a/dojox/mobile/themes/custom/dijit/compat/calendar-datelabel-act-bg.png b/dojox/mobile/themes/custom/dijit/compat/calendar-datelabel-act-bg.png
new file mode 100644
index 0000000..d4d8640
Binary files /dev/null and b/dojox/mobile/themes/custom/dijit/compat/calendar-datelabel-act-bg.png differ
diff --git a/dojox/mobile/themes/custom/dijit/compat/calendar-datelabel-sel-bg.png b/dojox/mobile/themes/custom/dijit/compat/calendar-datelabel-sel-bg.png
new file mode 100644
index 0000000..7743892
Binary files /dev/null and b/dojox/mobile/themes/custom/dijit/compat/calendar-datelabel-sel-bg.png differ
diff --git a/dojox/mobile/themes/custom/dijit/compat/calendar-month-bg.png b/dojox/mobile/themes/custom/dijit/compat/calendar-month-bg.png
new file mode 100644
index 0000000..9bbba0a
Binary files /dev/null and b/dojox/mobile/themes/custom/dijit/compat/calendar-month-bg.png differ
diff --git a/dojox/mobile/themes/custom/dijit/compat/calendar-year-bg.png b/dojox/mobile/themes/custom/dijit/compat/calendar-year-bg.png
new file mode 100644
index 0000000..9bbba0a
Binary files /dev/null and b/dojox/mobile/themes/custom/dijit/compat/calendar-year-bg.png differ
diff --git a/dojox/mobile/themes/custom/variables.less b/dojox/mobile/themes/custom/variables.less
index 9c22efc..aa0ed17 100644
--- a/dojox/mobile/themes/custom/variables.less
+++ b/dojox/mobile/themes/custom/variables.less
@@ -1,921 +1,827 @@
-//----------------------------------------------------------------
-// 1. Variables for quick setting
-//----------------------------------------------------------------
-
-// Default state variables
- at theme-default-margin: 8px;
- at theme-default-padding: 8px;
- at theme-default-font-size: 14px;
- at theme-default-font-family: Helvetica;
- at theme-default-font-weight: normal;
- at theme-default-text-shadow: none;
- at theme-default-color: #131313;	// numerical color value
- at theme-default-border-color: #B5BCC7;	// numerical color value
- at theme-default-border-radius: 5px;
- at theme-default-background-color: lighten(@theme-default-border-color, 20%);
-
-// Highlighting state variables
- at theme-highlight-font-size: 18px;
- at theme-highlight-font-family: @theme-default-font-family;
- at theme-highlight-font-weight: bold;
- at theme-highlight-text-shadow: rgba(0,0,0,0.2) 0px 1px 2px;
- at theme-highlight-color: #000000;	// numerical color value
- at theme-highlight-border-color: #769DC0;	// numerical color value
- at theme-highlight-background-color: #5CB0FF;	// numerical color value
-
-//----------------------------------------------------------------
-// 2. Variables for typical style setting
-//----------------------------------------------------------------
-
-// Color
- at theme-heading-color: @theme-default-color;
- at theme-heading-border-color: @theme-highlight-border-color;
- at theme-heading-background-color: @theme-highlight-background-color;
- at theme-dom-button-background-color: @theme-highlight-background-color;
- at theme-tabbar-color: @theme-default-color;
- at theme-round-rect-border-color: @theme-default-border-color;
- at theme-round-rect-background-color: #FFFFFF;
- at theme-round-rect-box-shadow: 5px 5px 5px @theme-round-rect-border-color;
- at theme-category-color: @theme-highlight-color;
- at theme-list-item-color: @theme-default-color;
- at theme-list-item-border-color: @theme-default-border-color;
- at theme-list-item-background-color: #FFFFFF;
- at theme-ui-widget-color: @theme-default-color;
- at theme-ui-widget-selected-color: @theme-highlight-color;
- at theme-ui-widget-border-color: @theme-default-border-color;
- at theme-ui-widget-selected-border-color: @theme-highlight-border-color;
- at theme-ui-widget-background-color: @theme-highlight-background-color;
- at theme-ui-widget-selected-background-color: darken(@theme-ui-widget-background-color, 30%);
- at theme-ui-widget-checked-background-color: darken(@theme-ui-widget-background-color, 20%);
- at theme-ui-widget-disabled-background-color: lighten(@theme-ui-widget-background-color, 10%);
-
-// Font
- at theme-heading-font-size: @theme-highlight-font-size;
- at theme-heading-font-family: @theme-highlight-font-family;
- at theme-heading-font-weight: @theme-default-font-weight;
- at theme-heading-text-shadow: @theme-highlight-text-shadow;
- at theme-tabbar-font-size: @theme-default-font-size - 3;
- at theme-tabbar-font-family: @theme-default-font-family;
- at theme-tabbar-font-weight: @theme-default-font-weight;
- at theme-category-font-size: @theme-highlight-font-size;
- at theme-category-font-family: @theme-highlight-font-family;
- at theme-category-font-weight: @theme-default-font-weight;
- at theme-category-text-shadow: @theme-highlight-text-shadow;
- at theme-list-item-font-size: @theme-highlight-font-size;
- at theme-list-item-font-family: @theme-default-font-family;
- at theme-list-item-font-weight: @theme-default-font-weight;
- at theme-list-item-text-shadow: none;
- at theme-ui-widget-font-size: @theme-default-font-size;
- at theme-ui-widget-font-family: @theme-default-font-family;
- at theme-ui-widget-font-weight: @theme-default-font-weight;
- at theme-ui-widget-text-shadow: none;
-
-// Size
- at theme-heading-height: 40px;
- at theme-tabbar-height: 50px;
- at theme-category-height: 30px;
- at theme-list-item-height: 50px;
- at theme-icon-item-height: 65px;
- at theme-icon-item-width: 65px;
- at theme-ui-widget-height: 30px;
- at theme-ui-widget-width: 90px;
-
- at theme-ui-widget-border-radius: 2px;	// square style
-//@theme-ui-widget-border-radius: @theme-default-border-radius;	// round style
-//@theme-ui-widget-border-radius: @theme-ui-widget-height * 0.5;	// oval style
-
-// background-image gradation
-._background-image-gradient-mask-heading () {
-	@delta: 1% / @theme-heading-height * 100;
-	// claro gradation
-	background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(255, 255, 255, 1)), color-stop(@delta * 1, rgba(255, 255, 255, 1)), color-stop(@delta * 1, rgba(255, 255, 255, 0.14)), color-stop(@delta * 2, rgba(255, 255, 255, 0.14)), color-stop(@delta * 2, rgba(255, 255, 255, 0.52)), color-stop(@delta * 3, rgba(255, 255, 255, 0.52)), color-stop(@delta * 3, rgba(255, 255, 255, 0.68)), color-stop(@delta * 4, rgba(255, 255, 255, 0.68)), color-stop(1, rgba(255, 255, 255, 0)));
-}
-._background-image-gradient-mask-ui-widget () {
-	@delta: 1% / @theme-ui-widget-height * 100;
-	// claro gradation
-	background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, rgba(255, 255, 255, 1)), color-stop(@delta * 1, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-}
-._background-image-gradient-mask-ui-widget-r () { // for .mblArrowButtonHead-styles
-	@delta: 1% / @theme-ui-widget-height * 100;
-	// claro gradation
-	background-image: -webkit-gradient(linear, left top, right bottom, color-stop(0, rgba(255, 255, 255, 1)), color-stop(@delta * 1, rgba(255, 255, 255, 0.1)), color-stop(0.5, rgba(255, 255, 255, 0.6)), color-stop(1, rgba(255, 255, 255, 0.3)));
-}
-
-// dojox.mobile fixed variables
- at mbl-dom-button-size: 29px;
- at mbl-switch-height: 27px;
-
-// Application's customizable variables
- at appl-list-item-icon-size: 29px; // size of ListItemIcon
-
-//----------------------------------------------------------------
-// 3. Variables for dojox.mobile Widgets
-//----------------------------------------------------------------
-
-//----------------------------------------------------------------
+// You can customize this theme by changing lightColor/darkColor and run the 'compile' script in ../utils.
+// See ../utils/README for more informations on compiling themes.
+
+ at lightColor: #FFFFFF; // The base color of the theme
+ at darkColor: #000000;  // Mainly used for text and some borders
+
+// Selected button gradient colors
+ at lightColor02: darken(@lightColor, 40%);
+ at lightColor03: darken(@lightColor, 26.5%);
+
+// Background color of form controls, TabBar(segmented), dijit Calendar thread and year label
+ at lightColor04: darken(@lightColor, 11.5%);
+
+// Button background color
+ at lightColor05: darken(@lightColor, 35.5%);
+
+// Background color of Heading, Overlay, bubble Tooltip and Calendar day label
+ at lightColor06: darken(@lightColor, 3.5%);
+
+// Background color of Heading and bubble Tooltip
+ at lightColor07: darken(@lightColor, 13%);
+
+// Background colors of ValuePicker slot
+ at lightColor08: darken(@lightColor, 26%);
+ at lightColor09: darken(@lightColor, 3%);
+ at lightColor10: darken(@lightColor, 16%);
+
+// Background colors of ValuePicker input area
+ at lightColor11: darken(@lightColor, 2%);
+
+// Border color of Button (bottom), Toolbar button (top left right), Toolbar button arrow, Switch, Slider handle,
+// standard and segmented TabBar buttons, Tooltip arrow, Accordion, IconMenu (compat), dijit Calendar increase/decrease buttons
+ at lightColor12: darken(@lightColor, 39.2%);
+
+// Background color of View, Switch (left part), Accordion's title, SearchBox's cancel button,
+// Border color of Button (top, left, right), Heading (top, bottom), RoundRect, ListItem, RadioButton, Slider,
+// Accordion's selected title (bottom), SimpleDialog's title (bottom), dijit Calendar.
+ at lightColor13: darken(@lightColor, 24.8%);
+
+// Background color of dijit Calendar month menu label.
+ at lightColor14: darken(@lightColor, 5%);
+
+// Color of ListItem subtext, TabBar background gradient (barType=tabBar, tallBar)
+ at darkColor02: lighten(@darkColor, 17.5%);
+
+// Background color of TabBar's button (barType=tabBar).
+ at darkColor03: lighten(@darkColor, 28.2%);
+
+// Background color of TabBar's selected button (barType=tabBar).
+ at darkColor04: lighten(@darkColor, 14%);
+
+// Text color of checked ListItem. Background color of TabBar's button (barType=tabBar).
+ at darkColor05: lighten(@darkColor, 25%);
+
+// Border color of ToolBar's body (bottom), ToolBar's button arrow (right and bottom), Switch knob (bottom).
+ at darkColor06: lighten(@darkColor, 46.2%);
+
+// Blue and red colors
+ at blueColor: #048bf4;
+ at blueColor02: lighten(@blueColor, 15%);
+ at redColor: #ee4115;
+ at redColor02: #fa9d58;
+
+
+
+ at import "../common/css3.less";
+
+ at default-blue-button-color: @lightColor;
+ at default-blue-button-background-color: @blueColor;
+.default-blue-button-background-image () { .background-image-linear-gradient-top-bottom(@blueColor02, @blueColor); }
+ at default-blue-button-background-image-gecko: -moz-linear-gradient(top, @blueColor02 0%, @blueColor 100%);
+
+.mbl-color-blue-45 () { .background-image-linear-gradient-top-left-bottom-right(@blueColor, @blueColor02); }
+.mbl-color-default-45 () { .background-image-linear-gradient-top-left-bottom-right(@lightColor04, @lightColor05); }
+.mbl-color-default-sel-45 () { .background-image-linear-gradient-top-left-bottom-right(@lightColor03, @lightColor02); }
+
+ at mbl-color-blue-45-gecko: -moz-linear-gradient(top left, @blueColor 0%, @blueColor02 100%);
+ at mbl-color-default-45-gecko: -moz-linear-gradient(top left, @lightColor04 0%, @lightColor05 100%);
+ at mbl-color-default-sel-45-gecko: -moz-linear-gradient(top left, @lightColor03 0%, @lightColor02 100%);
+
+ at default-button-color: @darkColor;
+ at default-button-background-color: @lightColor05;
+.default-button-background-image () { .background-image-linear-gradient-top-bottom(@lightColor04, @lightColor05); }
+ at default-button-background-image-gecko: -moz-linear-gradient(top, @lightColor04 0%, @lightColor05 100%);
+ at default-button-border-radius: 0;
+
+ at default-button-selected-color: @lightColor;
+ at default-button-selected-background-color: @lightColor02;
+.default-button-selected-background-image () { .background-image-linear-gradient-top-bottom(@lightColor03, @lightColor02); }
+ at default-button-selected-background-image-gecko: -moz-linear-gradient(top, @lightColor03 0%, @lightColor02 100%);
+
+ at default-selected-color: @lightColor;
+ at default-selected-background-color: @default-button-selected-background-color;
+.default-selected-background-image () { .default-button-selected-background-image(); }
+ at default-selected-background-image-gecko: @default-button-selected-background-image-gecko;
+
+ at heading-background-color: @lightColor07;
+.heading-background-image () { .background-image-linear-gradient-top-bottom(@lightColor06, @lightColor07); }
+ at heading-background-image-gecko: -moz-linear-gradient(top, @lightColor06 0%, @lightColor07 100%);
+ at heading-border-top-color: @lightColor13;
+ at heading-border-bottom-color: @lightColor13;
+
+.default-button-border-styles () {
+	border: 1px solid @lightColor13;
+	border-bottom-color: @lightColor12;
+	border-radius: @default-button-border-radius;
+}
+
+.mblToolBarButtonBodyInLeftArrow-styles () {
+  border-left-width: 0;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+.mblToolBarButtonBodyInRightArrow-styles () {
+  border-right-width: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+// background styles of form controls
+.mbl-button-background-image () { .background-image-linear-gradient-top-bottom(@lightColor, @lightColor04); }
+.mbl-button-selected-background-image () { .default-selected-background-image(); }
+.mbl-blue-button-background-image () { .default-blue-button-background-image(); }
+.mbl-blue-button-selected-background-image () { .default-selected-background-image(); }
+.mbl-red-button-background-image () { .background-image-linear-gradient-top-bottom(@redColor02, @redColor); }
+.mbl-red-button-selected-background-image () { .default-selected-background-image(); }
+.mbl-button-checked-background-image () { .mbl-button-background-image(); }
+
+// background styles of form controls (for gecko)
+ at mbl-button-background-image-gecko: -moz-linear-gradient(top, @lightColor 0%, @lightColor04 100%);
+ at mbl-button-selected-background-image-gecko: @default-selected-background-image-gecko;
+ at mbl-blue-button-background-image-gecko: @default-blue-button-background-image-gecko;
+ at mbl-blue-button-selected-background-image-gecko: @default-selected-background-image-gecko;
+ at mbl-red-button-background-image-gecko: -moz-linear-gradient(top, @redColor02 0%, @redColor 100%);
+ at mbl-red-button-selected-background-image-gecko: @default-selected-background-image-gecko;
+ at mbl-button-checked-background-image-gecko: @mbl-button-background-image-gecko;
+
 // common.less
-//----------------------------------------------------------------
-// .mobile body
 .mobile-body-styles () {
-	background-color: @theme-default-background-color;
-	font-family: @theme-default-font-family;
-	font-size: @theme-default-font-size;
+	font-family: Helvetica;
+	font-size: 17px;
+	color: @darkColor;
 }
-// .mblView
+
+.mblBackground-styles () {
+	background-color: @lightColor13;
+}
+
 .mblView-styles () {
-	color: @theme-default-color;
+	color: @darkColor;
 }
-// .mblColorBlue
+
 .mblColorBlue-styles () {
-	background-color: #366EDF;
-	._background-image-gradient-mask-ui-widget;
+	color: @default-blue-button-color;
+	background-color: @default-blue-button-background-color;
+	.default-blue-button-background-image();
 }
-// .mblColorDefault
 .mblColorDefault-styles () {
-	background-color: @theme-ui-widget-background-color;
-	._background-image-gradient-mask-ui-widget;
-	&.mblDomButton {
-		background-color: @theme-dom-button-background-color;
-	}
+	color: @default-button-color;
+	background-color: @default-button-background-color;
+	.default-button-background-image();
 }
-// .mblColorDefaultSel
 .mblColorDefaultSel-styles () {
-	background-color: @theme-ui-widget-selected-background-color;
-	&.mblDomButton {
-		background-color: @theme-ui-widget-selected-background-color;
-	}
+	color: @default-button-selected-color;
+	background-color: @default-button-selected-background-color;
+	.default-button-selected-background-image();
 }
 
-//----------------------------------------------------------------
 // Heading.less
-//----------------------------------------------------------------
- at _heading-inner-margin: (@theme-heading-height - @theme-ui-widget-height) * 0.5;
 .mblHeading-styles () {
-	padding: 0;
-	height: @theme-heading-height;
-	background-color: @theme-heading-background-color;
-	._background-image-gradient-mask-heading();
-	border-bottom: 1px solid @theme-heading-border-color;
-	color: @theme-heading-color;
-	font-size: @theme-heading-font-size;
-	font-family: @theme-heading-font-family;
-	font-weight: @theme-heading-font-weight;
-	text-shadow: @theme-heading-text-shadow;
-	text-align: center;
-	line-height: @theme-heading-height + 2;
-}
-.mblArrowButton-styles () {
-	height: @theme-ui-widget-height;
-	margin: 0px @theme-default-margin;
-}
-.mblArrowButtonHead-styles () {
-	top: @_heading-inner-margin;
-	left: @_heading-inner-margin + @theme-ui-widget-height * 0.4; // = 0.5 * 0.9 
-	width: @theme-ui-widget-height * 0.7;
-	height: @theme-ui-widget-height * 0.7;
-	border: 1px solid @theme-ui-widget-border-color;
-	-webkit-transform-origin: left top;
-	-webkit-transform: scale(0.9,0.99) rotate(45deg);
-	background-color: @theme-ui-widget-background-color;
-	._background-image-gradient-mask-ui-widget-r;
-}
-.mblArrowButtonHeadChrome-styles () {
-	border-style: inset;
-}
-.mblArrowButtonBody-styles () {
-	top: @_heading-inner-margin;
-	left: @_heading-inner-margin + @theme-ui-widget-height * 0.4;
-	padding: 0px 10px 0px 3px;
-	height: @theme-ui-widget-height;
-	border-width: 1px 1px 1px 0px;
-	border-style: inset;
-	border-color: @theme-ui-widget-border-color;
-	font-size: @theme-ui-widget-font-size;
-	font-family: @theme-ui-widget-font-family;
-	font-weight: @theme-ui-widget-font-weight;
-	text-shadow: @theme-ui-widget-text-shadow;
-	color: @theme-ui-widget-color;
-	line-height: @theme-ui-widget-height;
-	-webkit-border-top-right-radius: @theme-ui-widget-border-radius;
-	-webkit-border-bottom-right-radius: @theme-ui-widget-border-radius;
-	background-color: @theme-ui-widget-background-color;
-	._background-image-gradient-mask-ui-widget;
-}
-.mblArrowButtonSelected-styles () {
-	background-color: @theme-ui-widget-selected-background-color;
-}
-.mblArrowButtonHeadSelected-styles () {
-}
-.mblArrowButtonBodySelected-styles () {
-}
-
-//----------------------------------------------------------------
+	.heading-background-image();
+	border-top: 1px solid @heading-border-top-color;
+	border-bottom: 1px solid @heading-border-bottom-color;
+	color: @darkColor;
+	text-shadow: rgba(255,255,255,0.5) 0 1px 0;
+}
+
 // ToolBarButton.less
-//----------------------------------------------------------------
+ at mbl-tool-bar-button-body-border-radius: 0;
+//
 .mblToolBarButton-styles () {
-	margin: @theme-default-margin;
-	height: @theme-ui-widget-height;
-	border: 1px inset @theme-ui-widget-border-color;
-	-webkit-border-radius: @theme-ui-widget-border-radius;
-	font-size: @theme-ui-widget-font-size;
-	font-family: @theme-ui-widget-font-family;
-	font-weight: @theme-ui-widget-font-weight;
-	text-shadow: @theme-ui-widget-text-shadow;
-	color: @theme-ui-widget-color;
-	line-height: @theme-ui-widget-height;
-	text-align: center;
-	&.mblArrowButtonText {
-		margin: ((@theme-heading-height + 2 - @theme-ui-widget-height) * 0.5) @theme-default-margin;
-	}
-}
-.mblToolBarButtonDomButton-styles () {
-}
-.mblToolBarButtonIcon-styles () {
-	top: 2px;
-}
-
-//----------------------------------------------------------------
-// RoundRect.less
-//----------------------------------------------------------------
-.mblRoundRect-styles () {
-	margin: @theme-default-margin @theme-default-margin (@theme-default-margin * 1.5);
-	padding: @theme-default-padding;
-	border: 1px solid @theme-round-rect-border-color;
-	-webkit-border-radius: @theme-default-border-radius;
-	background-color: @theme-round-rect-background-color;
-	font-size: @theme-list-item-font-size;
-	font-family: @theme-list-item-font-family;
-	font-weight: @theme-list-item-font-weight;
-	text-shadow: @theme-list-item-text-shadow;
+	text-shadow: none;
+}
+.mblToolBarButtonArrow-styles () {
+	border-radius: 1px;
+  .transform(scale(0.7, 1.05) rotate(45deg));
+	border: 1px solid @lightColor12;
+	border-right-color: @darkColor06;
+	border-bottom-color: @darkColor06;
+}
+.mblToolBarButtonArrowInHeading-styles () {
+}
+.mblToolBarButtonHasLeftArrowInHeading-styles () {
+}
+.mblToolBarButtonHasLeftArrowInHeading-compat-gecko () {
+}
+.mblToolBarButtonHasRightArrowInHeading-styles () {
+}
+.mblToolBarButtonHasRightArrowInHeading-compat-gecko () {
+}
+.mblToolBarButtonArrowInLeftArrow-styles () {
+  left: -1px;
+}
+.mblToolBarButtonArrowInRightArrow-styles () {
+  right: -1px;
 }
-.mblRoundRectShadowBox-styles () {
-	-webkit-box-shadow: @theme-round-rect-box-shadow;
+.mblToolBarButtonBody-styles () {
+	border: 1px solid @lightColor12;
+	border-bottom-color: @darkColor06;
+	text-shadow: rgba(255,255,255,0.5) 0 1px 0;
+}
+.mblToolBarButtonBodyInHeading-styles () {
+}
+.mblToolBarButtonBodyInHeading-compat-gecko () {
+}
+
+// RoundRect.less & RoundRectList.less
+ at mbl-round-rect-border-color: @lightColor13;
+ at mbl-round-rect-border-radius: 8px;
+ at mbl-round-rect-background-color: @lightColor;
+ at mbl-round-rect-box-shadow: 2px 2px 2px rgba(0,0,0,0.2);
+//
+.mblRoundRect-styles () {
+	color: @darkColor;
 }
 
-//----------------------------------------------------------------
 // EdgeToEdgeCategory.less
-//----------------------------------------------------------------
 .mblEdgeToEdgeCategory-styles () {
-	margin: 0;
-	padding: 0 @theme-default-padding;
-	height: @theme-category-height;
-	border-bottom: 1px solid @theme-default-border-color;
-	background-color: @theme-highlight-background-color;
-	._background-image-gradient-mask-heading();
-	font-size: @theme-category-font-size;
-	font-family: @theme-category-font-family;
-	font-weight: @theme-category-font-weight;
-	text-shadow: @theme-category-text-shadow;
-	color: @theme-category-color;
-	line-height: @theme-category-height + 2;
-}
-
-//----------------------------------------------------------------
+	height: 22px;
+	background-color: @heading-background-color;
+	.heading-background-image();
+	border-bottom: 1px solid @heading-border-bottom-color;
+	color: @darkColor;
+	text-shadow: rgba(255,255,255,0.5) 0 1px 0;
+	line-height: 22px;
+}
+
 // RoundRectCategory.less
-//----------------------------------------------------------------
 .mblRoundRectCategory-styles () {
-	margin: 0;
-	padding: @theme-default-margin @theme-default-margin 0;
-	font-size: @theme-category-font-size;
-	font-family: @theme-category-font-family;
-	font-weight: @theme-category-font-weight;
-	text-shadow: @theme-category-text-shadow;
-	color: @theme-category-color;
-	line-height: @theme-category-height;
-}
-
-//----------------------------------------------------------------
-// RoundRectList.less
-//----------------------------------------------------------------
-.mblRoundRectList-styles () {
-	margin: @theme-default-margin @theme-default-margin (@theme-default-margin * 1.5);
-	padding: 0;
-	border: 1px solid @theme-default-border-color;
-	-webkit-border-radius: @theme-default-border-radius;
-	background-color: @theme-list-item-background-color;
-	-webkit-box-shadow: @theme-round-rect-box-shadow;
-}
-.mblRoundRectList-withCategory-styles () {
-}	
-.mblRoundRectList-FirstListItem-styles () {
-	-webkit-border-top-left-radius: @theme-default-border-radius;
-	-webkit-border-top-right-radius: @theme-default-border-radius;
-}
-.mblRoundRectList-withCategory-FirstListItem-styles () {
-}
-.mblRoundRectList-LastListItem-styles () {
-	border-bottom-width: 0px;
-	-webkit-border-bottom-left-radius: @theme-default-border-radius;
-	-webkit-border-bottom-right-radius: @theme-default-border-radius;
+	color: @darkColor;
 }
 
-//----------------------------------------------------------------
 // EdgeToEdgeList.less
-//----------------------------------------------------------------
 .mblEdgeToEdgeList-styles () {
-	margin: 0;
-	padding: 0;
-	background-color: @theme-list-item-background-color;
+	background-color: @darkColor;
 }
 .mblEdgeToEdgeList-LastListItem-styles () {
-	border-bottom-color: @theme-list-item-border-color;
+	border-bottom-color: @lightColor13;
 }
 
-//----------------------------------------------------------------
 // ListItem.less
-//----------------------------------------------------------------
+ at mbl-list-item-height: 43px;
+//
 .mblListItem-styles () {
-	padding: 0 0 0 @theme-default-margin;
-	height: @theme-list-item-height;
-	border-bottom: 1px solid @theme-list-item-border-color;
-	font-size: @theme-list-item-font-size;
-	font-family: @theme-list-item-font-family;
-	font-weight: @theme-list-item-font-weight;
-	text-shadow: @theme-list-item-text-shadow;
-	color: @theme-list-item-color;
-	line-height: @theme-list-item-height;
-}
-.mblListItem-mblVariableHeight-styles () {
-	padding: 11px 0px 10px 6px;
-	line-height: normal;
+	border-bottom: 1px solid @lightColor13;
+	background-color: @lightColor;
+	color: @darkColor;
+	font-weight: bold;
 }
-.mblListItem-mblListItemAnchor-styles () {
-	background-position: 9px 7px;
-	text-decoration: none;
-	padding-right: 7px;
+.mblListItemSelected-styles () {
+	color: @default-selected-color;
+	.heading-background-image();
 }
-.mblItemSelected-styles () {
-	background-color: @theme-highlight-background-color;
-	._background-image-gradient-mask-ui-widget;
-}
-.mblItemSelected-mblListItemAnchor-styles () {
-	color: @theme-highlight-color;
-}
-.mblItemSelected-mblDomButton-Div-styles () {
-	border-color: white;
-}
-.mblItemSelected-mblListItemSubText-styles () {
-}
-.mblListItemTextBoxSelected-styles () {
-	background-color: @theme-highlight-background-color;
+.mblListItemLabelSelected-styles () {
+	background-color: @lightColor;
 }
 .mblListItemChecked-styles () {
-	color: @theme-highlight-color;
-}
-.mblListItemIcon-styles () {
-	margin-top: (@theme-list-item-height - @appl-list-item-icon-size) * 0.5;
-	margin-right: 11px;
-}
-.mblListItemSpriteIcon-styles () {
-	margin-top: (@theme-list-item-height - @appl-list-item-icon-size) * 0.5;
-	margin-left: 8px;
-}
-.mblListItemRightIcon-styles () {
-	margin-top: (@theme-list-item-height - @appl-list-item-icon-size) * 0.5;
+	color: @darkColor05;
 }
 .mblListItemRightText-styles () {
-	color: @theme-default-color;
-	margin: ((@theme-list-item-height - (@theme-list-item-font-size + 4)) * 0.5) 4px 0 0;
-}
-.mblListItemTextBox-styles () {
-}
-.mblListItemAnchorNoIcon-mblListItemTextBox-styles () {
+	color: @darkColor;
+	margin-top: 12px;
 }
 .mblListItemSubText-styles () {
+	font-size: 14px;
+	color: @darkColor02;
 }
 
-//----------------------------------------------------------------
 // Switch.less
-//----------------------------------------------------------------
-.mblItemSwitch-styles () {
-	top: (@theme-list-item-height - @mbl-switch-height + 1) * 0.5;
-}
+ at mbl-switch-bg-left-background-color: @lightColor13;
+.mbl-switch-bg-left-background-image () { .default-button-selected-background-image(); }
+ at mbl-switch-bg-right-background-color: @lightColor04;
+.mbl-switch-bg-right-background-image () { .mbl-button-background-image(); }
+.mbl-switch-knob-background-image () { .default-button-background-image(); }
+//
+ at mbl-switch-bg-left-background-image-gecko: @default-button-selected-background-image-gecko;
+ at mbl-switch-bg-right-background-image-gecko: @mbl-button-background-image-gecko;
+ at mbl-switch-knob-background-image-gecko: @default-button-background-image-gecko;
+ at mbl-switch-square-border-radius: 2px;
+//
 .mblSwitchBg-styles () {
-	border-color: @theme-ui-widget-border-color;
-	-webkit-border-radius: @theme-ui-widget-border-radius;
-	._background-image-gradient-mask-ui-widget;
-}
-.mblSwitchBgLeft-styles () {
-	background-color: @theme-ui-widget-checked-background-color;
-	color: @theme-ui-widget-color;
-}
-.mblSwitchBgRight-styles () {
-	background-color: @theme-ui-widget-disabled-background-color;
+	border: 1px solid @lightColor13;
+	border-bottom-color: @lightColor12;
 }
 .mblSwitchKnob-styles () {
-	border-color: darken(@theme-ui-widget-border-color, 20%);
-	background-color: @theme-ui-widget-background-color;
-	._background-image-gradient-mask-ui-widget;
-	-webkit-border-radius: @theme-ui-widget-border-radius;
+	border: 1px solid @lightColor12;
+	border-bottom-color: @darkColor06;
 }
 
-//----------------------------------------------------------------
 // Button.less
-//----------------------------------------------------------------
 .mblButton-styles () {
-	padding: 0 @theme-default-padding;
-	height: @theme-ui-widget-height;
-	border: 1px outset @theme-ui-widget-border-color;
-	color: @theme-ui-widget-color;
-	font-size: @theme-ui-widget-font-size;
-	font-family: @theme-ui-widget-font-family;
-	font-weight: @theme-ui-widget-font-weight;
-	line-height: @theme-ui-widget-height;
-	background-color: @theme-ui-widget-background-color;
-	._background-image-gradient-mask-ui-widget;
-	-webkit-border-radius: @theme-ui-widget-border-radius;
+	.default-button-border-styles;
+	color: @darkColor;
+	font-size: 13px;
 }
-.mblButton-mblBlueButton-styles () {
-	color: @theme-ui-widget-color;
-	background-color: #0000FF;
+.mblButtonSelected-styles () {
+	color: @lightColor;
 }
-.mblButton-mblBlueButtonSelected-styles () {
-	color: @theme-ui-widget-selected-color;
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: darken(#0000FF, 30%);
+.mblButton-mblBlueButton-styles () {
+	color: @lightColor;
 }
 .mblButton-mblRedButton-styles () {
-	color: @theme-ui-widget-color;
-	background-color: #FF0000;
-}
-.mblButton-mblRedButtonSelected-styles () {
-	color: @theme-ui-widget-selected-color;
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: darken(#FF0000, 30%);
-}
-.mblButtonSelected-styles () {
-	color: @theme-ui-widget-selected-color;
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: @theme-ui-widget-selected-background-color;
-}
-.mblButtonDisabled-styles () {
-	color: grey;
-	border-color: grey;
-	background-color: @theme-ui-widget-disabled-background-color;
+	color: @lightColor;
 }
 
-//----------------------------------------------------------------
 // CheckBox.less
-//----------------------------------------------------------------
 .mblCheckBox-styles () {
-	margin: -0.5em 3px 0.3em 4px;
-	width: 1em;
-	height: 1em;
-	font-size: @theme-highlight-font-size;
-	border: 1px outset @theme-ui-widget-border-color;
-	background-color: @theme-ui-widget-background-color;
-	._background-image-gradient-mask-ui-widget;
-	-webkit-border-radius: @theme-ui-widget-border-radius;
-	-webkit-transform: translateY(0.45em);
-}
-.mblCheckBoxSelected-styles () {
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: @theme-ui-widget-selected-background-color;
-}
-.mblCheckBoxChecked-styles () {
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: @theme-ui-widget-checked-background-color;
+	.default-button-border-styles;
 }
 .mblCheckBoxChecked-after-styles () {
-	content: "";
-	width: 0.3em;
-	height: 0.6em;
-	position: absolute;
-	top: 0;
-	left: 0.3em;
-	border-color: @theme-ui-widget-selected-color;
-	border-width: 0.15em;
-	border-style: none solid solid none;
-	-webkit-transform: rotate(45deg);
-	-webkit-transform-origin: 50% 50%;
-}
-.mblCheckBoxChecked-mblCheckBoxSelected-styles () {
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: @theme-ui-widget-selected-background-color;
+	border-color: @darkColor;
 }
 .mblCheckBoxChecked-mblCheckBoxSelected-after-styles () {
-	border-color: @theme-ui-widget-selected-color;
+	border-color: @lightColor;
 }
 
-//----------------------------------------------------------------
 // ComboBox.less
-//----------------------------------------------------------------
+ at mbl-combo-box-popup-box-shadow: none;
+//
 .dijitPopup-styles () {
-	-webkit-box-shadow: 0px 0px 50px black;
-	-webkit-border-radius: @theme-default-border-radius;
+	border-radius: 0;
 }
 .mblComboBoxMenu-styles () {
-	border: 1px solid black;
-	background-color: @theme-default-background-color;
-	-webkit-border-radius: @theme-default-border-radius;
+	border-color: @darkColor;
+	border-radius: 0;
+	background-color: @lightColor;
+	color: @darkColor;
 }
 .mblComboBoxMenuItem-styles () {
-	text-align: left;
-	padding: .1em .2em;
-	color: @theme-default-color;
-	border-width: 1px 0 1px 0;
-	border-style: solid;
-	border-color: @theme-default-background-color;
+	border-color: @lightColor;
+	color: inherit;
 }
 .mblComboBoxMenuItemSelected-styles () {
-	color: @theme-highlight-color;
-	background-color: @theme-highlight-background-color;
-	._background-image-gradient-mask-ui-widget;
-}
-.mblComboBoxMenuPreviousButton-styles () {
-	font-style: italic;
-	overflow: hidden;
+	.default-selected-background-image();
+	color: @lightColor;
 }
 
-//----------------------------------------------------------------
 // IconContainer.less
-//----------------------------------------------------------------
-.mblIconContainer-styles () {
-	margin: @theme-default-margin 0 @theme-default-margin @theme-default-margin;
-	padding: @theme-default-padding 0 @theme-default-padding;
-	background-color: @theme-default-background-color;
-}
-
-//----------------------------------------------------------------
-// IconItem.less
-//----------------------------------------------------------------
-.mblIconItemTerminator-styles () {
-	height: @theme-default-margin;
-}
 .mblIconItemSub-styles () {
-	margin-left: - at theme-default-margin;
-	background-color: white;
-	color: @theme-default-color;
+	background-color: @lightColor;
+	color: @darkColor;
 }
 .mblIconArea-styles () {
-	height: @theme-icon-item-height + @theme-default-font-size + @theme-default-margin;
-	width: @theme-icon-item-width + @theme-default-margin;
-	text-align: center;
-	font-family: @theme-default-font-family;
-	font-weight: @theme-default-font-weight;
-	font-size: @theme-default-font-size;
-}
-.mblContent-styles () {
-	padding-bottom: @theme-default-margin;
-}
-.mblIconContentHeading-styles () {
-	margin-top: 0px;
-	padding-left: @mbl-dom-button-size + @theme-default-margin;
-	height: @mbl-dom-button-size - 4;
-	border-top: 1px solid lighten(@theme-heading-border-color, 30%);
-	border-bottom: 1px solid @theme-heading-border-color;
-	background-color: @theme-heading-background-color;
-	._background-image-gradient-mask-heading();
-	color: @theme-heading-color;
-	font-size: @theme-default-font-size;
-	font-family: @theme-heading-font-family;
-	font-weight: @theme-heading-font-weight;
-	text-shadow: @theme-heading-text-shadow;
-	line-height: @mbl-dom-button-size - 3;
-}
-
-//----------------------------------------------------------------
+	margin-top: 5px;
+	margin-bottom: 5px;
+	width: 74px;
+	color: @darkColor;
+}
+.mblIconItemDeleteIcon-styles () {
+	top: -4px;
+	left: -2px;
+}
+
 // RadioButton.less
-//----------------------------------------------------------------
 .mblRadioButton-styles () {
-	margin: -0.5em 3px 0.3em 4px;
-	width: 1em;
-	height: 1em;
-	font-size: @theme-highlight-font-size;
-	border: 1px outset @theme-ui-widget-border-color;
-	background-color: @theme-ui-widget-background-color;
-	._background-image-gradient-mask-ui-widget;
-	-webkit-border-radius: 0.5em;
-	-webkit-transform: translateY(0.45em);
-}
-.mblRadioButtonChecked-styles () {
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: @theme-ui-widget-checked-background-color;
+	border-style: solid;
+	border-color: @lightColor13;
 }
 .mblRadioButtonChecked-after-styles () {
-	content: "";
-	width: 0.3em;
-	height: 0.6em;
-	top: 0;
-	left: 0.25em;
-	border-color: @theme-ui-widget-selected-color;
-	border-width: 0.15em;
-	border-style: none solid solid none;
-	-webkit-transform: rotate(45deg);
-	-webkit-transform-origin: 50% 50%;
-}
-.mblRadioButtonChecked-Selected-styles () {
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: @theme-ui-widget-selected-background-color;
+	border-color: @darkColor;
 }
 .mblRadioButtonChecked-Selected-after-styles () {
-	border-color: @theme-ui-widget-selected-color;
+	border-color: @lightColor;
 }
 
-//----------------------------------------------------------------
 // Slider.less
-//----------------------------------------------------------------
+ at mbl-slider-bar-border-radius: 0;
+ at mbl-slider-knob-border-radius: 0;
+//
 .mblSlider-styles () {
-	margin: 15px; /* 1/2 handle width for hanging off the ends of the bar */
-	border: 1px outset @theme-ui-widget-border-color;
-	background-color: @theme-ui-widget-disabled-background-color;
-	._background-image-gradient-mask-ui-widget;
-	-webkit-border-radius: @theme-ui-widget-border-radius;
-}
-.mblSliderProgressBar-styles () {
-	-webkit-border-radius: @theme-ui-widget-border-radius;
-	background-color: @theme-ui-widget-selected-background-color;
-	._background-image-gradient-mask-ui-widget;
+	border: 1px solid @lightColor13;
+	border-bottom-color: @lightColor12;
 }
 .mblSliderHandle-styles () {
-	margin: -10px 0 0 -10px;
-	width: 18px;
-	height: 18px;
-	border: 1px outset @theme-ui-widget-border-color;
-	background-color: @theme-ui-widget-background-color;
-	._background-image-gradient-mask-ui-widget;
-	-webkit-border-radius: @theme-ui-widget-border-radius;
+	border: 1px solid @lightColor12;
+	border-bottom-color: @darkColor06;
 }
 
-//----------------------------------------------------------------
 // TabBar.less
-//----------------------------------------------------------------
 .mblTabBar-styles () {
-	margin: 0;
-	padding: 0;
-	height: @theme-tabbar-height;
-	background-color: @theme-heading-background-color;
-	._background-image-gradient-mask-ui-widget;
-	border-bottom: 1px solid @theme-heading-border-color;
-	color: @theme-heading-color;
-	text-align: center;
-}
-.mblTabBar-TabBarButton-styles () {
-	padding: ((@theme-tabbar-height - @mbl-dom-button-size - @theme-tabbar-font-size) * 0.5) 0;
-}
-.mblTabBar-TabBarButton-Selected-styles () {
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: @theme-ui-widget-selected-background-color;
-	._background-image-gradient-mask-ui-widget;
-	-webkit-border-radius: @theme-ui-widget-border-radius;
-}
-.mblTabBarButtonDiv-styles () {
-	height: @mbl-dom-button-size;
-	width: @mbl-dom-button-size;
-}
-.mblTabBarButtonIcon-styles () {
-	left: 0;
-	top: 0;
-}
-.mblTabBarButtonTextBox-styles () {
-	color: @theme-tabbar-color;
-	font-family: @theme-tabbar-font-family;
-	font-size: @theme-tabbar-font-size;
-	font-weight: @theme-tabbar-font-weight;
-}
-.mblTabBarNoIcons-TabBarButtonTextBox-styles () {
-	line-height: @theme-tabbar-height - @theme-tabbar-font-size;
-	font-size: @theme-tabbar-font-size + 6;
-}
-.mblTabButton-styles () {
-	width: @theme-ui-widget-width;
-	height: @theme-ui-widget-height;
-	border-width: 1px 1px 1px 0px;
-	border-style: inset;
-	border-color: @theme-default-border-color;
-	border-right-color: @theme-ui-widget-border-color;
-	background-color: @theme-ui-widget-background-color;
-	._background-image-gradient-mask-ui-widget;
-	font-family: @theme-default-font-family;
-	font-size: @theme-default-font-size;
-	font-weight: @theme-default-font-weight;
-	color: @theme-default-color;
-	text-align: center;
-	line-height: @theme-ui-widget-height;
-}
-.mblTabButton-TabBarButtonAnchor-styles () {
-	height: @theme-ui-widget-height;
-}
-.mblTabBarTop-TabButton-TabBarButtonDiv-styles () {
-	display: none;
-}
-.mblTabBarHead-TabButton-TabBarButtonDiv-styles () {
-}
-.mblTabButton-FirstTabButtom-styles () {
-	-webkit-border-top-left-radius: @theme-ui-widget-border-radius;
-	-webkit-border-bottom-left-radius: @theme-ui-widget-border-radius;
-	border-left-width: 1px;
-}
-.mblTabButton-LastTabButton-styles () {
-	-webkit-border-top-right-radius: @theme-ui-widget-border-radius;
-	-webkit-border-bottom-right-radius: @theme-ui-widget-border-radius;
-	border-right-color: @theme-ui-widget-border-color;
-}
-.mblTabButton-img-styles () {
-}
-.mblTabBarButtonTextBoxSelected-styles () {
-	color: @theme-ui-widget-selected-color;
-}
-.mblTabButtonSelected-styles () {
-	background-color: @theme-ui-widget-selected-background-color;
-}
-.mblTabButtonHighlighted-styles () {
-	background-color: @theme-ui-widget-checked-background-color;
-}
-.mblTabButtonImgDiv-styles () {
-	display: none;
-}
-.mblTabPanelHeader-styles () {
-	margin: 0;
-	padding: 0;
-	height: @theme-heading-height;
-	background-color: @theme-heading-background-color;
-	._background-image-gradient-mask-heading();
-	border-bottom: 1px solid @theme-heading-border-color;
-	color: @theme-heading-color;
-	font-size: @theme-heading-font-size;
-	font-family: @theme-heading-font-family;
-	font-weight: @theme-heading-font-weight;
-	text-shadow: @theme-heading-text-shadow;
-	text-align: center;
-	line-height: @theme-heading-height + 2;
+	text-shadow: none;
+}
+
+// barType="tabBar"
+.mblTabBarTabBar-styles () {
+	.background-image-linear-gradient-top-bottom(@darkColor02, @darkColor);
 }
-.mblTabPanelHeader-TabButton-styles () {
-	margin-top: (@theme-heading-height - @theme-ui-widget-height - 2) * 0.5;
+.mblTabBarTabBar-compat () {
+	background-color: @darkColor;
 }
-.mblTabPanelHeader-TabButtonSelected-styles () {
-	background-color: @theme-ui-widget-selected-background-color;
+.mblTabBarTabBarButton-styles () {
+
 }
-.mblTabPanelHeader-TabButtonDomButton-styles () {
-	width: 43px;
+.mblTabBarTabBarButtonIconArea-styles () {
 }
-.mblTabPanelHeader-TabButtonDomButtonClass-styles () {
-	left: 8px;
+.mblTabBarTabBarButtonLabel-styles () {
+	color: @lightColor;
 }
-.mblTabPanelHeader-DomButton-styles () {
+.mblTabBarTabBarButtonSelected-styles () {
+	background-color: @darkColor05;
+	.background-image-linear-gradient-top-bottom(@darkColor03, @darkColor04);
 }
-.mblTabPanelHeader-inHeading-styles () {
+.mblTabBarTabBarButtonLabelSelected-styles () {
+	color: @lightColor;
 }
-.mblTabPanelHeader-TabButton-inHeading-styles () {
-	margin-top: (@theme-heading-height - @theme-ui-widget-height) * 0.5;
+
+// barType="segmentedControl"
+ at mbl-tab-bar-segmented-control-border-radius: 5px;
+//
+.mblTabBarSegmentedControl-styles () {
 }
-.mblTabPanelHeader-TabButton-FirstTabButtom-inHeading-styles () {
-	-webkit-border-top-left-radius: @theme-ui-widget-border-radius;
-	-webkit-border-bottom-left-radius: @theme-ui-widget-border-radius;
-	border-left-width: 1px;
+.mblTabBarSegmentedControlButton-styles () {
+	border-style: solid;
+	border-color: @lightColor12 @lightColor12 @lightColor12 @lightColor12;
+	color: @darkColor;
+	.mbl-button-background-image();
+	text-shadow: rgba(255,255,255,0.5) 0 1px 0;
 }
-.mblTabPanelHeader-TabButton-LastTabButtom-inHeading-styles () {
-	-webkit-border-top-right-radius: @theme-ui-widget-border-radius;
-	-webkit-border-bottom-right-radius: @theme-ui-widget-border-radius;
+.mblTabBarSegmentedControlButton-compat-gecko () {
+}
+.mblTabBarSegmentedControlButtonSelected-styles () {
+	color: @default-button-color;
+	.default-button-background-image();
+	text-shadow: rgba(255,255,255,0.5) 0 1px 0;
+}
+
+// barType="standardTab"
+.mblTabBarStandardTab-styles () {
+	border-top: none;
+	border-bottom: none;
+}
+.mblTabBarStandardTabButton-styles () {
+	color: @darkColor;
+	border-color: @lightColor12;
+	.heading-background-image();
+}
+.mblTabBarStandardTabButtonIconArea-styles () {
+}
+.mblTabBarStandardTabButtonLabel-styles () {
+}
+.mblTabBarStandardTabButtonSelected-styles () {
+	.default-button-background-image();
+}
+.mblTabBarStandardTabButtonLabelSelected-styles () {
+}
+
+// barType="tallTab"
+.mblTabBarTallTab-styles () {
+	.background-image-linear-gradient-top-bottom(@darkColor02, @darkColor);
+}
+.mblTabBarTallTabButton-styles () {
+}
+.mblTabBarTallTabButton-FirstChild-styles () {
+}
+.mblTabBarTallTabButton-LastChild-styles () {
+}
+.mblTabBarTallTabButtonIconArea-styles () {
+}
+.mblTabBarTallTabButtonLabel-styles () {
+}
+.mblTabBarTallTabButtonSelected-styles () {
+}
+.mblTabBarTallTabButtonLabelSelected-styles () {
 }
-.mblTabPanelHeader-TabButtonSelected-inHeading-styles () {
-}	
 
-//----------------------------------------------------------------
 // TextArea.less
-//----------------------------------------------------------------
 .mblTextArea-styles () {
-	padding: 4px 1px;
-	border: @theme-default-border-color 1px inset;
-	font-family: @theme-default-font-family;
-	font-size: @theme-default-font-size;
-	-webkit-border-radius: @theme-default-border-radius;
-}
-.mblExpandingTextArea-styles () {
-	margin: 2px;
+	.default-button-border-styles;
 }
 
-//----------------------------------------------------------------
 // TextBox.less
-//----------------------------------------------------------------
 .mblTextBox-styles () {
-	height: @theme-ui-widget-height;
-	border: @theme-default-border-color 1px inset;
-	font-family: @theme-default-font-family;
-	font-size: @theme-default-font-size;
-	-webkit-border-radius: @theme-default-border-radius;
+	.default-button-border-styles;
 }
 
-//----------------------------------------------------------------
 // ToggleButton.less
-//----------------------------------------------------------------
 .mblToggleButton-styles () {
-	padding: 0 @theme-default-padding 0 (@theme-default-padding + 15px);
-	height: @theme-ui-widget-height;
-	border: 1px outset @theme-ui-widget-border-color;
-	-webkit-border-radius: @theme-ui-widget-border-radius;
-	background-color: @theme-ui-widget-background-color;
-	._background-image-gradient-mask-ui-widget;
-	font-family: @theme-ui-widget-font-family;
-	font-weight: @theme-ui-widget-font-weight;
-	line-height: @theme-ui-widget-height;
-	color: @theme-ui-widget-color;
-	line-height: @theme-ui-widget-height;
+	.default-button-border-styles;
+	font-size: 13px;
+	color: @darkColor;
 }
 .mblToggleButtonSelected-styles () {
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: @theme-ui-widget-selected-background-color;
+	color: @lightColor;
 }
 .mblToggleButtonChecked-styles () {
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: @theme-ui-widget-checked-background-color;
+	color: @darkColor;
 }
 .mblToggleButtonChecked-after-styles () {
-	content: "";
-	top: (@theme-ui-widget-height - 15) * 0.5;
-	left: 7px;
-	width: 5px;
-	height: 10px;
-	border-color: @theme-ui-widget-selected-color;
-	border-width: 0.15em;
-	border-style: none solid solid none;
-	-webkit-transform: rotate(45deg) skew(10deg);
-	-webkit-transform-origin: 50% 50%;
+	border-color: @darkColor;
 }
 .mblToggleButtonCheckedSelected-styles () {
-	border-color: @theme-ui-widget-selected-border-color;
-	background-color: @theme-ui-widget-selected-background-color;
+	color: @lightColor;
 }
 .mblToggleButtonCheckedSelected-after-styles () {
-	border-color: @theme-ui-widget-selected-color;
-}
-.mblToggleButtonDisabled-styles () {
-	color: grey;
-	border-color: grey;
-	background-color: @theme-ui-widget-disabled-background-color;
+	border-color: @lightColor;
 }
 
 // Overlay.less
 .mblOverlay-styles () {
-	background-color: @theme-default-background-color;
-	._background-image-gradient-mask-ui-widget;
+	background-color: @lightColor06;
+	background-image: none;
+}
+.mblOverlay-compat () {
+}
+.mblOverlay-compat-gecko () {
 }
 
 // Tooltip.less
+ at mbl-tooltip-border-radius: 3px;
+//
 .mblTooltip-styles () {
-	padding: @theme-default-padding;
-	border: @theme-heading-border-color 1px solid;
-	background-color: @theme-heading-background-color;
-	._background-image-gradient-mask-ui-widget;
-	-webkit-border-radius: @theme-default-border-radius;
-	opacity: .97;
+	border-color: @darkColor;
+	border-radius: @mbl-tooltip-border-radius;
+	background-color: @lightColor07;
+	background-image: none;
 }
 .mblTooltipBubble-styles () {
-	background-color: @theme-heading-background-color;
+	background-color: @lightColor06;
 	background-image: none;
+	color: @darkColor;
 }
 .mblTooltipInnerArrow-Bubble-Above-styles () {
-	border-bottom-color: @theme-heading-background-color;
+	border-bottom-color: @lightColor06;
 }
 .mblTooltipInnerArrow-Bubble-Below-styles () {
-	border-top-color: @theme-heading-background-color;
+	border-top-color: @lightColor06;
 }
 .mblTooltipInnerArrow-Bubble-After-styles () {
-	border-left-color: @theme-heading-background-color;
+	border-left-color: @lightColor06;
 }
 .mblTooltipInnerArrow-Bubble-Before-styles () {
-	border-right-color: @theme-heading-background-color;
-}
-.mblTooltipArrow-styles () {
-	border: 11px solid transparent;
+	border-right-color: @lightColor06;
 }
 .mblTooltipArrow-Before-styles () {
 	border-left-width: 0;
-	border-right-color: @theme-heading-border-color;
+	border-right-color: @lightColor12;
 }
 .mblTooltipArrow-After-styles () {
 	border-right-width: 0;
-	border-left-color: @theme-heading-border-color;
+	border-left-color: @lightColor12;
 }
 .mblTooltipArrow-Above-styles () {
 	border-top-width: 0;
-	border-bottom-color: @theme-heading-border-color;
+	border-bottom-color: @lightColor12;
 }
 .mblTooltipArrow-Below-styles () {
 	border-bottom-width: 0;
-	border-top-color: @theme-heading-border-color;
+	border-top-color: @lightColor12;
 }
 .mblTooltipInnerArrow-Before-styles () {
 	border-left-width: 0;
-	border-right-color: @theme-heading-background-color * 0.2 + #ffffff * 0.8;
+	border-right-color: @lightColor07;
 }
 .mblTooltipInnerArrow-After-styles () {
 	border-right-width: 0;
-	border-left-color: @theme-heading-background-color * 0.2 + #ffffff * 0.8;
+	border-left-color: @lightColor07;
 }
 .mblTooltipInnerArrow-Above-styles () {
 	border-top-width: 0;
-	border-bottom-color: @theme-heading-background-color * 0.0 + #ffffff * 1.0;
+	border-bottom-color: @lightColor07;
 }
 .mblTooltipInnerArrow-Below-styles () {
 	border-bottom-width: 0;
-	border-top-color: @theme-heading-background-color * 0.5 + #ffffff * 0.5;
+	border-top-color: @lightColor07;
 }
 .mblTooltip-Heading-styles () {
+	padding-bottom: 3px;
 	border-top: 1px solid transparent;
 	border-bottom: 1px solid transparent;
 	background-color: transparent;
 	background-image: none;
 }
+.mblTooltip-Heading-compat () {
+}
 .mblTooltip-Heading-ToolbarButton-styles () {
 }
+.mblTooltip-Heading-ToolbarButton-compat () {
+}
+
+// Accordion.less
+.mblAccordion-styles () {
+	border-color: @lightColor12;
+}
+.mblAccordionTitle-styles () {
+	border-top: 1px solid @lightColor12;
+	background-color: @lightColor13;
+	background-image: none;
+	font-weight: normal;
+}
+.mblAccordionTitle-compat () {
+}
+.mblAccordionTitle-compat-gecko () {
+}
+.mblAccordionTitleSelected-styles () {
+	border-bottom: 1px solid @lightColor13;
+	.mbl-button-checked-background-image();
+	font-weight: bold;
+}
+.mblAccordionTitleSelected-compat () {
+	background-color: @lightColor04;
+}
+.mblAccordionTitleSelected-compat-gecko () {
+	background-image: @mbl-button-checked-background-image-gecko;
+}
+.mblAccordionTitleAnchor-styles () {
+	color: @darkColor;
+}
+.mblAccordionTitleAnchorSelected-styles () {
+}
+
+// SimpleDialog.less
+ at mbl-simple-dialog-border-radius: 0;
+//
+.mblSimpleDialog-styles () {
+	padding: 5px;
+	width: 262px;
+}
+.mblSimpleDialogDecoration-styles () {
+	background-color: @lightColor;
+	border: 1px solid @darkColor;
+	color: @darkColor;
+}
+.mblSimpleDialogDecoration-compat () {
+}
+.mblSimpleDialogDecoration-compat-gecko () {
+}
+.mblSimpleDialogTitle-styles () {
+	margin: 7px 0 7px -5px;
+	padding: 0 14px 7px;
+	width: 244px;
+	border-bottom: 1px solid @lightColor13;
+	font-size: 20px;
+	font-weight: bold;
+	text-align: left;
+}
+.mblSimpleDialogText-styles () {
+	margin: 14px 9px;
+	width: 244px;
+	text-align: left;
+}
+
+// IconMenu.less
+ at mbl-icon-menu-border-radius: 3px;
+ at mbl-icon-menu-item-border-radius: 3px;
+//
+.mblIconMenu-styles () {
+	padding: 0;
+	background-color: rgba(160, 160, 160, 0.85);
+	border: 1px solid @darkColor;
+}
+.mblIconMenu-compat () {
+	background-color: @lightColor12;
+}
+.mblIconMenu-compat-gecko () {
+	background-color: rgba(160, 160, 160, 0.85);
+}
+.mblIconMenuItem-styles () {
+	border-left: 1px solid rgba(192, 192, 192, 0.85);
+	border-bottom: 1px solid rgba(192, 192, 192, 0.85);
+}
+.mblIconMenuItemAnchor-styles () {
+	font-size: 13px;
+	color: @lightColor;
+}
+.mblIconMenuItemSel-styles () {
+	.default-selected-background-image();
+}
+.mblIconMenuItemSel-compat () {
+	background-color: @default-selected-background-color;
+}
+.mblIconMenuItemSel-compat-gecko () {
+	background-image: @default-selected-background-image-gecko;
+}
+
+// dijit.Calendar
+.dijitCalendar-styles () {
+	border: 1px solid @lightColor13;
+}
+.dijitCalendar-thead-styles () {
+	.mbl-button-background-image();
+}
+.dijitCalendar-thead-compat () {
+	background-image: url(compat/calendar-month-bg.png);
+}
+.dijitCalendar-thead-compat-gecko () {
+	background-image: @mbl-button-background-image-gecko;
+}
+.dijitCalendarMonthLabel-styles () {
+	color: @darkColor;
+	font-size: 16px;
+}
+.dijitCalendarMonthMenu-styles () {
+}
+.dijitCalendarMonthMenu-compat-ff3 () {
+}
+.dijitCalendarMonthMenu-Label-styles () {
+	background-color: @lightColor14;
+	color: @darkColor;
+}
+.dijitCalendarDecrease-styles () {
+	border-right: 6px solid @lightColor12 !important;
+}
+.dijitCalendarIncrease-styles () {
+	border-left: 6px solid @lightColor12 !important;
+}
+.dijitCalendarDayLabelTemplate-styles () {
+	background-color: @lightColor06;
+	font-size: 12px;
+	color: @darkColor;
+}
+.dijitCalendarDateTemplate-styles () {
+	border: none;
+	background-color: @lightColor;
+	color: @darkColor;
+}
+.dijitCalendarDateTemplate-LastChild-styles () {
+	border-right: none;
+}
+.dijitCalendarDateLabel-DateTemplate-styles () {
+	border: none;
+}
+.dijitCalendarDateLabel-PrevMonth-styles () {
+	color: lightGrey;
+}
+.dijitCalendarDateLabel-Hovered-styles () {
+	color: grey;
+}
+.dijitCalendarDateLabel-Selected-styles () {
+	.default-button-background-image();
+	color: @darkColor;
+	text-shadow: rgba(0,0,0,0.4) 0 1px 0;
+}
+.dijitCalendarDateLabel-Selected-compat () {
+	background-image: url(compat/calendar-datelabel-sel-bg.png);
+}
+.dijitCalendarDateLabel-Selected-compat-gecko () {
+	background-image: @default-button-background-image-gecko;
+}
+.dijitCalendarDateLabel-Active-styles () {
+	.default-selected-background-image();
+}
+.dijitCalendarDateLabel-Active-compat () {
+	background-image: url(compat/calendar-datelabel-act-bg.png);
+}
+.dijitCalendarDateLabel-Active-compat-gecko () {
+	background-image: @default-selected-background-image-gecko;
+}
+.dijitCalendarYearLabel-styles () {
+	padding: 0;
+	.mbl-button-background-image();
+}
+.dijitCalendarYearLabel-compat () {
+	background-image: url(compat/calendar-year-bg.png);
+}
+.dijitCalendarYearLabel-compat-gecko () {
+	background-image: @mbl-button-background-image-gecko;
+}
+.dijitCalendarSelectedYear-styles () {
+	color: @darkColor;
+	font-size: 16px;
+}
+.dijitCalendarNextYear-styles () {
+	padding: 1px 6px 3px 6px;
+	color: @darkColor;
+	font-size: 12px;
+}
+
+// SearchBox.less
+ at mbl-searchbox-cancel-button-color: @lightColor;
+ at mbl-searchbox-cancel-button-bg-color: @lightColor13;
+.mblSearchBox-Cancel-Button-styles () {
+	border-radius: 1em;
+}
+ at mbl-searchbox-results-decoration-color: @lightColor13;
+
+// ProgressBar.less
+.mblProgressBar-styles () {
+	height: 13px;
+	background-color: @lightColor;
+	border: 1px solid @blueColor;
+}
+.mblProgressBarProgress-styles () {
+	height: 13px;
+	.background-image-linear-gradient-top-bottom-1-stop(@blueColor, @blueColor02, 0.5, @blueColor);
+	border-right: 1px solid @blueColor;
+}
+.mblProgressBarComplete-styles () {
+}
+.mblProgressBarNotStarted-styles () {
+}
+.mblProgressBarMsg-styles () {
+	top: -1px;
+}
+.mblProgressBar-compat () {
+}
+.mblProgressBarProgress-compat () {
+	background-color: @blueColor;
+}
+.mblProgressBar-compat-gecko () {
+}
+.mblProgressBarProgress-compat-gecko () {
+	background-image: -moz-linear-gradient(top, @blueColor 0%, @blueColor 50%, @blueColor02 100%);
+}
+
+// ValuePicker.less
+.mbl-value-picker-slot-button-background-image () { .background-image-linear-gradient-top-bottom-2-stops(@lightColor09, @lightColor10, 0.5, @lightColor10, 0.9, @lightColor08); }
+ at mbl-value-picker-slot-button-background-image-gecko: -moz-linear-gradient(top, @lightColor09 0%, @lightColor10 50%, @lightColor08 90%, @lightColor10 100%);
+ at mbl-value-picker-slot-button-radius: 5px;
+.mbl-value-picker-slot-input-area-background-image () { .background-image-linear-gradient-top-bottom-4-stops-no-from-to(0.1, @lightColor11, 0.2, @lightColor11, 0.5, @lightColor, 0.9, @lightColor); }
+ at mbl-value-picker-slot-input-area-background-image-gecko: -moz-linear-gradient(top, @lightColor11 10%, @lightColor11 20%, @lightColor 50%, @lightColor 90%);
+.mblValuePickerSlot-style () {
+  margin:  0 5px;
+}
+.mblValuePickerSlot-input-style () {
+	font-size: 28px;
+}
diff --git a/dojox/mobile/themes/custom/variables_rtl.less b/dojox/mobile/themes/custom/variables_rtl.less
new file mode 100644
index 0000000..df5f14b
--- /dev/null
+++ b/dojox/mobile/themes/custom/variables_rtl.less
@@ -0,0 +1,32 @@
+// Carousel_rtl
+ at mbl-carousel-margin-rtl: ~"2px 4px 2px 0px";
+
+// IconContainer_rtl
+ at mbl-icon-container-right-rtl: -2px;
+
+// IconMenu_rtl-compat
+ at mbl-border-radius-rtl: 3px;
+
+// TabBar_rtl-compat
+ at mbl-moz-border-radius-rtl: 5px;
+
+// TabBar_rtl
+ at mbl-border-width-rtl: ~"1px 0px 1px 1px !important";
+ at mbl-tb-border-radius-rtl: 5px;
+
+// ThemeID
+ at theme-id: custom;
+
+// Switch_rtl-compat
+ at mbl-bg-image-r-rtl: ~"url(compat/switch-square-r.gif)";
+ at mbl-bg-image-l-rtl: ~"url(compat/switch-square-l.gif)";
+
+// Switch_rtl
+ at mbl-switchOn-left-rtl: -53px;
+ at mbl-switchBg-left-rtl: 53px;
+ at mbl-switch-knob-rtl: 53px;
+ at mbl-switch-text-right-rtl: -40px;
+
+// ToolBarButton_rtl
+ at mbl-toolbar-right-arrow-rtl: 1px;
+ at mbl-toolbar-left-arrow-rtl: 0px;
diff --git a/dojox/mobile/themes/holodark/Accordion-compat.css b/dojox/mobile/themes/holodark/Accordion-compat.css
new file mode 100644
index 0000000..cd3b26d
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Accordion-compat.css
@@ -0,0 +1,28 @@
+/* dojox.mobile.Accordion */
+.mblAccordionTitleSelected {
+  background-color: #33b5e5;
+}
+.dj_gecko .mblAccordionTitle {
+  background-image: none;
+  background-color: #333333;
+  border-style: none;
+  border-top-style: solid;
+  border-top-color: rgba(85, 85, 85, 0.9);
+  border-top-width: 1px;
+  border-radius: 2px;
+}
+.dj_gecko .mblAccordionTitleSelected {
+  background-color: #33b5e5;
+}
+.dj_ff3 .mblAccordionRoundRect {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitle:first-child {
+  -moz-border-radius-topleft: 8px;
+  -moz-border-radius-topright: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitleLast,
+.dj_ff3 .mblAccordionRoundRect .mblAccordionPane:last-child {
+  -moz-border-radius-bottomleft: 8px;
+  -moz-border-radius-bottomright: 8px;
+}
diff --git a/dojox/mobile/themes/holodark/Accordion.css b/dojox/mobile/themes/holodark/Accordion.css
new file mode 100644
index 0000000..a6ca7b9
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Accordion.css
@@ -0,0 +1,74 @@
+/* dojox.mobile.Accordion */
+.mblAccordion {
+  border-style: outset;
+  border-width: 1px;
+  border-style: none;
+}
+.mblAccordionRoundRect {
+  margin: 7px 9px 16px 9px;
+  padding: 0;
+  border: 1px solid #222222;
+  border-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitle:first-child {
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitleLast,
+.mblAccordionRoundRect .mblAccordionPane:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
+}
+.mblAccordionTitle {
+  position: relative;
+  height: 30px;
+  width: 100%;
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  line-height: 30px;
+  vertical-align: middle;
+  white-space: nowrap;
+  background-image: none;
+  background-color: #333333;
+  border-style: none;
+  border-top-style: solid;
+  border-top-color: rgba(85, 85, 85, 0.9);
+  border-top-width: 1px;
+  border-radius: 2px;
+}
+.mblAccordionTitle:first-child {
+  border-top: none;
+}
+.mblAccordionTitleAnchor {
+  display: block;
+  height: 100%;
+  text-decoration: none;
+  white-space: nowrap;
+  color: #ffffff;
+  cursor: pointer;
+}
+.mblAccordionIconParent {
+  float: left;
+  margin: 6px 4px 0 6px;
+  line-height: normal;
+}
+.mblAccordionIconParent1 {
+  display: block;
+}
+.mblAccordionIconParent2 {
+  display: none;
+}
+.mblAccordionTitleSelected {
+  background-color: #33b5e5;
+}
+.mblAccordionTitleSelected .mblAccordionTitleAnchor {
+  color: #ffffff;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent1 {
+  display: none;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent2 {
+  display: block;
+}
diff --git a/dojox/mobile/themes/holodark/Button-compat.css b/dojox/mobile/themes/holodark/Button-compat.css
new file mode 100644
index 0000000..affbf88
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Button-compat.css
@@ -0,0 +1,59 @@
+/* dojox.mobile.Button */
+.mblButton {
+  background-image: url(compat/button-bg.png);
+  background-repeat: repeat-x;
+}
+.mblButtonSelected {
+  background-image: url(compat/button-sel-bg.png);
+}
+.mblBlueButton {
+  background-image: url(compat/blue-button-bg.png);
+}
+.mblBlueButtonSelected {
+  background-image: url(compat/blue-button-sel-bg.png);
+}
+.mblRedButton {
+  background-image: url(compat/red-button-bg.png);
+}
+.mblRedButtonSelected {
+  background-image: url(compat/red-button-sel-bg.png);
+}
+.dj_gecko .mblButton {
+  background-image: none;
+}
+.dj_gecko .mblButtonSelected {
+  background-image: none;
+}
+.dj_gecko .mblBlueButton {
+  background-image: none;
+}
+.dj_gecko .mblBlueButtonSelected {
+  background-image: none;
+}
+.dj_gecko .mblRedButton {
+  background-image: none;
+}
+.dj_gecko .mblRedButtonSelected {
+  background-image: none;
+}
+.dj_ff3 .mblButton {
+  -moz-border-radius: 2px;
+}
+.mblButton {
+  background-image: none;
+}
+.mblButtonSelected {
+  background-image: none;
+}
+.mblBlueButton {
+  background-image: none;
+}
+.mblBlueButtonSelected {
+  background-image: none;
+}
+.mblRedButton {
+  background-image: none;
+}
+.mblRedButtonSelected {
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/holodark/Button-compat.less b/dojox/mobile/themes/holodark/Button-compat.less
new file mode 100644
index 0000000..70c0a96
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Button-compat.less
@@ -0,0 +1,21 @@
+ at import "variables.less";
+ at import "../common/Button-compat.less";
+
+.mblButton {
+  background-image: none;
+}
+.mblButtonSelected {
+  background-image: none;
+}
+.mblBlueButton {
+  background-image: none;
+}
+.mblBlueButtonSelected {
+  background-image: none;
+}
+.mblRedButton {
+  background-image: none;
+}
+.mblRedButtonSelected {
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/holodark/Button.css b/dojox/mobile/themes/holodark/Button.css
new file mode 100644
index 0000000..5e322e4
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Button.css
@@ -0,0 +1,86 @@
+/* dojox.mobile.Button */
+.mblButton {
+  padding: 0 10px;
+  height: 29px;
+  border-style: outset;
+  border-width: 1px;
+  font-family: Helvetica;
+  line-height: 29px;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  background-image: none;
+  background-color: #333333;
+  border-style: none;
+  border-top-style: solid;
+  border-top-color: rgba(85, 85, 85, 0.9);
+  border-top-width: 1px;
+  border-radius: 2px;
+  height: 40px;
+  color: #ffffff;
+}
+.mblButtonSelected {
+  color: #ffffff;
+  border-color: transparent;
+  background-image: none;
+  background-color: #2C94BB;
+  box-shadow: 0px 0px 1px 4px #1F5366;
+}
+.mblButtonDisabled,
+.mblButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
+}
+.mblBlueButton {
+  color: #ffffff;
+  background-image: none;
+  background-color: #333333;
+  border-style: none;
+  border-top-style: solid;
+  border-top-color: rgba(85, 85, 85, 0.9);
+  border-top-width: 1px;
+  border-radius: 2px;
+  background-color: #0099CC;
+}
+.mblBlueButtonSelected {
+  background-image: none;
+}
+.mblRedButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fa9d58), to(#ee4115), color-stop(0.5, #ff4d25), color-stop(0.5, #ed4d15));
+  background-image: linear-gradient(to bottom, #fa9d58 0%, #ff4d25 50%, #ed4d15 50%, #ee4115 100%);
+  color: #ffffff;
+  background-image: none;
+  background-color: #333333;
+  border-style: none;
+  border-top-style: solid;
+  border-top-color: rgba(85, 85, 85, 0.9);
+  border-top-width: 1px;
+  border-radius: 2px;
+  background-color: #CC0000;
+}
+.mblRedButtonSelected {
+  background-image: none;
+}
+.mblButtonDisabled,
+.mblButton:disabled {
+  color: #646464;
+  background-image: none;
+  background-color: #333333;
+  border-style: none;
+  border-top-style: solid;
+  border-top-color: rgba(85, 85, 85, 0.9);
+  border-top-width: 1px;
+  border-radius: 2px;
+  background-color: #212121;
+}
+.mblBlueButtonSelected {
+  border-color: transparent;
+  background-image: none;
+  box-shadow: 0px 0px 1px 4px #33B5E5;
+}
+.mblRedButtonSelected {
+  border-color: transparent;
+  background-image: none;
+  box-shadow: 0px 0px 1px 4px #FF4444;
+}
diff --git a/dojox/mobile/themes/holodark/Button.less b/dojox/mobile/themes/holodark/Button.less
new file mode 100644
index 0000000..8982a2c
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Button.less
@@ -0,0 +1,20 @@
+ at import "variables.less";
+ at import "../common/Button.less";
+
+.mblButtonDisabled,
+.mblButton:disabled {
+  color: #646464;
+  .default-button-border-styles;
+  background-color: #212121;
+}
+
+.mblBlueButtonSelected {
+  border-color: transparent;
+  background-image: none;
+  box-shadow: 0px 0px 1px 4px #33B5E5;
+}
+.mblRedButtonSelected {
+  border-color: transparent;
+  background-image: none;
+  box-shadow: 0px 0px 1px 4px #FF4444;
+}
diff --git a/dojox/mobile/themes/holodark/Carousel.css b/dojox/mobile/themes/holodark/Carousel.css
new file mode 100644
index 0000000..4439d46
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Carousel.css
@@ -0,0 +1,79 @@
+/* dojox.mobile.Carousel */
+.mblCarousel {
+  overflow: hidden;
+  height: 300px;
+}
+.mblCarouselSlot {
+  position: relative;
+  float: left;
+  text-align: left;
+  box-sizing: border-box;
+}
+.mblCarouselHeaderBar {
+  background-color: #3a3a3b;
+  color: #b1b1b1;
+  font: bold 16px arial, helvetica, clean, sans-serif;
+  padding: 1px;
+}
+.mblCarouselBtnContainer {
+  float: right;
+}
+.mblCarouselBtn {
+  height: 18px;
+  width: 46px;
+  font: bold 14px arial, helvetica, clean, sans-serif;
+  color: gray;
+  padding-top: 0px;
+  margin: 0px 2px;
+  border-width: 1px;
+  /* workaround for android problem */
+
+}
+.mblCarouselTitle {
+  margin: 2px 0px 2px 4px;
+}
+.mblCarouselHeaderBar .mblPageIndicator {
+  float: right;
+  width: auto;
+  padding: 0px 20px;
+}
+.mblCarouselHeaderBar .mblPageIndicatorContainer {
+  margin-left: 0px;
+  margin-right: 0px;
+}
+.mblCarouselPages {
+  position: relative;
+  text-align: center;
+}
+/* dojox.mobile._CarouselItem */
+.mblCarouselItem {
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblCarouselItemHeaderText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 8px;
+  margin-bottom: 5px;
+}
+.mblCarouselItemFooterText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 5px;
+  margin-bottom: 8px;
+}
+.mblCarouselItemImage {
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  vertical-align: bottom;
+}
+.mblCarouselItemBlank {
+  display: none;
+}
+.mblCarouselSlotSelected .mblCarouselItemImage {
+  opacity: 0.6;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
diff --git a/dojox/mobile/themes/holodark/Carousel_rtl.css b/dojox/mobile/themes/holodark/Carousel_rtl.css
new file mode 100644
index 0000000..45abf85
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Carousel_rtl.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.Carousel Rtl */
+.mblCarouselItemRtl.mblCarouselSlot {
+  float: right;
+}
+.mblCarouselRtl .mblCarouselBtnContainer {
+  float: left;
+}
+.mblCarouselRtl .mblCarouselTitle {
+  margin: 2px 0px 2px 4px;
+}
+.mblCarouselRtl .mblCarouselHeaderBar .mblPageIndicator {
+  float: left;
+}
diff --git a/dojox/mobile/themes/holodark/CheckBox-compat.css b/dojox/mobile/themes/holodark/CheckBox-compat.css
new file mode 100644
index 0000000..98e7e9d
--- /dev/null
+++ b/dojox/mobile/themes/holodark/CheckBox-compat.css
@@ -0,0 +1,38 @@
+/* dojox.mobile.CheckBox */
+.mblCheckBox {
+  background-image: url(compat/button-bg.png);
+}
+.mblCheckBoxSelected {
+  background-image: url(compat/button-sel-bg.png);
+}
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblCheckBox {
+  background-image: none;
+  -moz-appearance: none;
+}
+.dj_gecko .mblCheckBoxSelected {
+  background-image: none;
+}
+.dj_gecko .mblCheckBoxChecked,
+.dj_gecko .mblCheckBox:checked {
+  background-image: none;
+}
+.dj_gecko .mblCheckBoxChecked::after,
+.dj_gecko .mblCheckBox:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblCheckBoxChecked.mblCheckBoxSelected,
+.dj_gecko .mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: none;
+}
+.dj_ff3 .mblCheckBox {
+  -moz-border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/holodark/CheckBox.css b/dojox/mobile/themes/holodark/CheckBox.css
new file mode 100644
index 0000000..2f8993a
--- /dev/null
+++ b/dojox/mobile/themes/holodark/CheckBox.css
@@ -0,0 +1,85 @@
+/* dojox.mobile.CheckBox */
+.mblCheckBox {
+  position: relative;
+  margin: -0.5em 3px 0.3em 4px;
+  width: 1em;
+  height: 1em;
+  border-style: outset;
+  background-color: #333333;
+  border-style: none;
+  border-top-style: solid;
+  border-top-color: rgba(85, 85, 85, 0.9);
+  border-top-width: 1px;
+  border-radius: 2px;
+  font: inherit;
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  border-color: #5c5c5c;
+  border-width: 1px;
+  background-color: transparent;
+  background-image: none;
+  border-style: solid;
+}
+.mblCheckBoxSelected {
+  background-image: none;
+}
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
+  background-color: transparent;
+}
+.mblCheckBoxChecked::after,
+.mblCheckBox:checked::after {
+  position: absolute;
+  content: "";
+  width: 0.3em;
+  height: 0.6em;
+  top: 0;
+  left: 0.3em;
+  border-width: 0.15em;
+  border-style: none solid solid none;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: white;
+  background-color: transparent;
+  background-image: none;
+}
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: none;
+}
+.mblCheckBoxChecked.mblCheckBoxSelected::after,
+.mblCheckBox:checked.mblCheckBoxSelected::after {
+  background-color: transparent;
+  background-image: none;
+}
+.mblCheckBox:disabled {
+  border-color: #333333;
+}
+.mblCheckBoxSelected {
+  background-image: none;
+  border-color: #99bbca;
+  box-shadow: 0px 0px 1px 4px #1f5366;
+  background-color: #1f5366;
+}
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
+  background-image: none;
+}
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: none;
+  border-color: #99bbca;
+  box-shadow: 0px 0px 3px 4px #1f5366;
+  background-color: #1f5366;
+}
+.mblCheckBox:checked::after {
+  border-color: #61c6eb;
+}
+.mblCheckBox:disabled::after {
+  border-color: #333333;
+}
diff --git a/dojox/mobile/themes/holodark/CheckBox.less b/dojox/mobile/themes/holodark/CheckBox.less
new file mode 100644
index 0000000..a008a71
--- /dev/null
+++ b/dojox/mobile/themes/holodark/CheckBox.less
@@ -0,0 +1,32 @@
+ at import "variables.less";
+ at import "../common/CheckBox.less";
+
+.mblCheckBox:disabled{
+  border-color: @holo-grey2;
+}
+.mblCheckBoxSelected {
+  background-image: none;
+  border-color: @holo-checkbox-selected-color;
+  box-shadow: 0px 0px 1px 4px @holo-checkbox-checked-color;
+  background-color: @holo-checkbox-checked-color;
+  
+}
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
+  background-image: none;
+  
+  &.mblCheckBoxSelected {
+    background-image: none;
+    border-color: @holo-checkbox-selected-color;
+    box-shadow: 0px 0px 3px 4px @holo-checkbox-checked-color;
+    background-color: @holo-checkbox-checked-color;
+  }
+}
+
+.mblCheckBox:checked::after{
+  border-color: @holo-checkbox-tick-color;
+}
+
+.mblCheckBox:disabled::after{
+  border-color: @holo-grey2;
+}
diff --git a/dojox/mobile/themes/holodark/ComboBox-compat.css b/dojox/mobile/themes/holodark/ComboBox-compat.css
new file mode 100644
index 0000000..b2d6e94
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ComboBox-compat.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.ComboBox */
+.dj_gecko .dijitPopup {
+  -moz-box-shadow: 0 0 50px #000000;
+}
+.dj_gecko .mblComboBoxMenuItemSelected {
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/holodark/ComboBox.css b/dojox/mobile/themes/holodark/ComboBox.css
new file mode 100644
index 0000000..319fd1e
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ComboBox.css
@@ -0,0 +1,48 @@
+/* dojox.mobile.ComboBox */
+.dijitPopup {
+  margin: 0;
+  padding: 0;
+  position: absolute;
+  border: 0;
+  background-color: transparent;
+  -webkit-box-shadow: 0 0 50px #000000;
+  box-shadow: 0 0 50px #000000;
+  border-radius: 0;
+}
+.mblReset {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  line-height: normal;
+  font: inherit;
+  color: inherit;
+}
+.mblComboBoxMenu {
+  position: relative;
+  overflow-y: hidden !important;
+  overflow: hidden;
+  border: 1px solid black;
+  border-radius: 0;
+  background-color: #333333;
+  color: #ffffff;
+}
+.mblComboBoxMenuItem {
+  padding: .1em .2em;
+  border-width: 1px 0 1px 0;
+  border-style: solid;
+  text-align: left;
+  white-space: nowrap;
+  border-color: #4f4f4f;
+  border-top: none;
+  height: 35px;
+  padding-top: 17px;
+}
+.mblComboBoxMenuItemSelected {
+  background-color: #3578b1;
+  color: white;
+}
+.mblComboBoxMenuPreviousButton,
+.mblComboBoxMenuNextButton {
+  font-style: italic;
+  overflow: hidden;
+}
diff --git a/dojox/mobile/themes/holodark/ComboBox_rtl.css b/dojox/mobile/themes/holodark/ComboBox_rtl.css
new file mode 100644
index 0000000..01b9527
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ComboBox_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.ComboBox Rtl*/
+.mblComboBoxMenuItemRtl {
+  text-align: right;
+}
diff --git a/dojox/mobile/themes/holodark/DatePicker.css b/dojox/mobile/themes/holodark/DatePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/holodark/DatePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/holodark/EdgeToEdgeCategory.css b/dojox/mobile/themes/holodark/EdgeToEdgeCategory.css
new file mode 100644
index 0000000..7309ac6
--- /dev/null
+++ b/dojox/mobile/themes/holodark/EdgeToEdgeCategory.css
@@ -0,0 +1,21 @@
+/* dojox.mobile.EdgeToEdgeCategory */
+.mblEdgeToEdgeCategory {
+  position: relative;
+  margin: 0;
+  padding: 0 10px;
+  overflow: hidden;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  height: 35px;
+  border-bottom: 3px solid #39393A;
+  background-color: rgba(0, 0, 0, 0);
+  color: white;
+  line-height: 35px;
+  margin-right: 7px;
+  margin-left: 7px;
+  margin-top: 10px;
+  text-transform: uppercase;
+}
diff --git a/dojox/mobile/themes/holodark/EdgeToEdgeList.css b/dojox/mobile/themes/holodark/EdgeToEdgeList.css
new file mode 100644
index 0000000..635ba0b
--- /dev/null
+++ b/dojox/mobile/themes/holodark/EdgeToEdgeList.css
@@ -0,0 +1,10 @@
+/* dojox.mobile.EdgeToEdgeList */
+.mblEdgeToEdgeList {
+  margin: 0;
+  padding: 0;
+}
+.mblEdgeToEdgeList .mblListItem:last-child {
+  border-bottom-color: #333538;
+  margin-right: 7px;
+  margin-left: 7px;
+}
diff --git a/dojox/mobile/themes/holodark/FixedSplitter.css b/dojox/mobile/themes/holodark/FixedSplitter.css
new file mode 100644
index 0000000..f53833d
--- /dev/null
+++ b/dojox/mobile/themes/holodark/FixedSplitter.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.FixedSplitter */
+.mblFixedSplitter {
+  width: 100%;
+  height: 100%;
+}
+/* For FixedSplitter's child panes */
+.mblFixedSplitter > * {
+  position: absolute;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.mblFixedSplitterH > * {
+  height: 100%;
+  top: 0px;
+}
+.mblFixedSplitterV > * {
+  width: 100%;
+  left: 0px;
+}
diff --git a/dojox/mobile/themes/holodark/FormLayout.css b/dojox/mobile/themes/holodark/FormLayout.css
new file mode 100644
index 0000000..bb00da1
--- /dev/null
+++ b/dojox/mobile/themes/holodark/FormLayout.css
@@ -0,0 +1,190 @@
+/* Single Column Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (max-width: 500px) {
+  .mblFormLayout.mblFormLayoutAuto fieldset {
+    padding-left: 0;
+    padding-right: 0;
+  }
+  /* A gap between rows */
+  .mblFormLayout.mblFormLayoutAuto > * + * {
+    margin-top: 0.6em;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 100%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'single' ***/
+.mblFormLayout.mblFormLayoutSingleCol fieldset {
+  padding-left: 0;
+  padding-right: 0;
+}
+/* A gap between rows */
+.mblFormLayout.mblFormLayoutSingleCol > * + * {
+  margin-top: 0.6em;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 100%;
+  box-sizing: border-box;
+}
+/* Two Columns Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (min-width: 500px) {
+  /* Form layout selector*/
+  .mblFormLayout.mblFormLayoutAuto {
+    display: table;
+    width: 100%;
+  }
+  /* Form rows */
+  .mblFormLayout.mblFormLayoutAuto > * {
+    display: table-row;
+  }
+  /* Form cells */
+  .mblFormLayout.mblFormLayoutAuto > * > * {
+    display: table-cell;
+    vertical-align: top;
+    padding: 0.5em 0;
+  }
+  /* Left cells */
+  .mblFormLayout.mblFormLayoutAuto > * > *:first-child {
+    width: 20%;
+    padding-right: 0.5em;
+  }
+  /* mblFormLayoutRightAlign optional selector definition */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child {
+    text-align: right;
+  }
+  /* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+    margin-right: 0;
+  }
+  /* The Slider sticks to its bounds when margin=10px */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+    display: inline-block;
+    margin-right: 10px;
+    margin-top: 0px;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 50%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'two' ***/
+/* Form layout selector*/
+.mblFormLayout.mblFormLayoutTwoCol {
+  display: table;
+  width: 100%;
+}
+/* Form rows */
+.mblFormLayout.mblFormLayoutTwoCol > * {
+  display: table-row;
+}
+/* Form cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > * {
+  display: table-cell;
+  vertical-align: top;
+  padding: 0.5em 0;
+}
+/* Left cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > *:first-child {
+  width: 20%;
+  padding-right: 0.5em;
+}
+/* mblFormLayoutRightAlign optional selector definition */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child {
+  text-align: right;
+}
+/* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+  margin-right: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+  display: inline-block;
+  margin-right: 10px;
+  margin-top: 0px;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 50%;
+  box-sizing: border-box;
+}
+/* Common Rules*/
+/**********************************************************************************************************************/
+.mblFormLayout fieldset {
+  border: none;
+  margin: 0;
+}
+/* Bold widget labels */
+.mblFormLayout > * > *:first-child {
+  font-weight: bold;
+}
+/* Whatever the screen width, force left margin of first elements and elements following a <br> */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Button"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ToggleButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.CheckBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Switch"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.RadioButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.SearchBox"] {
+  margin-left: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > .mblSlider:first-child {
+  display: inline-block;
+  margin-left: 10px;
+  margin-top: 0;
+  margin-bottom: 0;
+}
diff --git a/dojox/mobile/themes/holodark/GridLayout.css b/dojox/mobile/themes/holodark/GridLayout.css
new file mode 100644
index 0000000..628fd9f
--- /dev/null
+++ b/dojox/mobile/themes/holodark/GridLayout.css
@@ -0,0 +1,24 @@
+/* dojox.mobile.GridLayout */
+.mblGridLayout {
+  width: 100%;
+  height: 100%;
+  padding: 0;
+}
+.mblGridLayout > div {
+  margin: 0;
+  border: 0;
+  padding: 0;
+  float: left;
+  min-height: 1px;
+}
+.mblGridItemFirstColumn {
+  clear: left;
+}
+.mblGridItemTerminator {
+  clear: both;
+}
+.mblGridItemLastItem:after {
+  content: "";
+  display: block;
+  clear: both;
+}
diff --git a/dojox/mobile/themes/holodark/Heading-compat.css b/dojox/mobile/themes/holodark/Heading-compat.css
new file mode 100644
index 0000000..884a97b
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Heading-compat.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.Heading */
+.mblHeading {
+  background-image: url(compat/heading-bg.png);
+}
+.mblHeadingSpanTitle {
+  white-space: normal;
+}
+.dj_gecko .mblHeading {
+  background-image: none;
+}
+.mblHeading {
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/holodark/Heading-compat.less b/dojox/mobile/themes/holodark/Heading-compat.less
new file mode 100644
index 0000000..85a3b88
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Heading-compat.less
@@ -0,0 +1,6 @@
+ at import "variables.less";
+ at import "../common/Heading-compat.less";
+
+.mblHeading {
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/holodark/Heading.css b/dojox/mobile/themes/holodark/Heading.css
new file mode 100644
index 0000000..a4bb97f
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Heading.css
@@ -0,0 +1,40 @@
+/* dojox.mobile.Heading */
+.mblHeading {
+  position: relative;
+  margin: 0;
+  width: 100%;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  z-index: 1;
+  padding: 0;
+  height: 42px;
+  font-family: Helvetica;
+  font-size: 20px;
+  font-weight: bold;
+  text-align: center;
+  line-height: 44px;
+  color: #ffffff;
+  background-color: #000000;
+  border-bottom-color: #33b5e5;
+  border-bottom-width: 2px;
+  border-bottom-style: solid;
+  font-size: 18px;
+  font-weight: normal;
+}
+.mblHeading * {
+  z-index: 2;
+}
+.mblHeadingDivTitle {
+  position: absolute;
+  width: 100%;
+  display: none;
+  left: 0;
+  z-index: 1;
+}
+.mblHeadingCenterTitle .mblHeadingDivTitle {
+  display: block;
+}
+.mblHeadingCenterTitle .mblHeadingSpanTitle {
+  display: none;
+}
diff --git a/dojox/mobile/themes/holodark/IconContainer-compat.css b/dojox/mobile/themes/holodark/IconContainer-compat.css
new file mode 100644
index 0000000..bafb264
--- /dev/null
+++ b/dojox/mobile/themes/holodark/IconContainer-compat.css
@@ -0,0 +1,13 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+/* dojox.mobile.IconContainer */
+.mblIconItemPaneHeading {
+  background-image: url(compat/icon-content-heading-bg.png);
+}
+.dj_gecko .mblIconItemPaneHeading {
+  background-image: -moz-linear-gradient(top, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
+}
+.dj_ie7 .mblIconAreaInner {
+  font-size: 60px;
+}
diff --git a/dojox/mobile/themes/holodark/IconContainer-compat.less b/dojox/mobile/themes/holodark/IconContainer-compat.less
new file mode 100644
index 0000000..e2df985
--- /dev/null
+++ b/dojox/mobile/themes/holodark/IconContainer-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer-compat.less";
diff --git a/dojox/mobile/themes/holodark/IconContainer.css b/dojox/mobile/themes/holodark/IconContainer.css
new file mode 100644
index 0000000..b80d49d
--- /dev/null
+++ b/dojox/mobile/themes/holodark/IconContainer.css
@@ -0,0 +1,261 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
+/* dojox.mobile.IconContainer */
+.mblIconContainer {
+  margin: 20px 10px;
+  padding: 0;
+}
+/* dojox.mobile.IconItem */
+.mblIconItem {
+  position: relative;
+  overflow: hidden;
+  /* for focus frame */
+
+  list-style-type: none;
+  float: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblIconItemTerminator {
+  list-style-type: none;
+  clear: both;
+}
+.mblIconItemPane {
+  list-style-type: none;
+  background-color: white;
+  color: black;
+}
+.mblIconArea {
+  position: relative;
+  height: 78px;
+  font-family: Helvetica;
+  font-size: 12px;
+  text-align: center;
+  margin-top: 5px;
+  margin-bottom: 5px;
+  width: 74px;
+  color: white;
+}
+.mblIconArea img {
+  vertical-align: middle;
+}
+.mblIconAreaInner {
+  position: relative;
+  height: 65px;
+  line-height: 65px;
+  text-align: center;
+}
+.mblIconItemDeleteIcon {
+  position: absolute;
+  top: -4px;
+  left: -2px;
+}
+.mblIconItemSpriteIcon {
+  position: absolute;
+}
+.mblContent {
+  clear: both;
+  padding-bottom: 20px;
+}
+table.mblClose {
+  clear: both;
+  cursor: pointer;
+}
+.mblVibrate {
+  position: relative;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-timing-function: ease-in-out;
+  animation-timing-function: ease-in-out;
+  -webkit-animation-iteration-count: infinite;
+  animation-iteration-count: infinite;
+  -webkit-animation-name: mblVibrate;
+  animation-name: mblVibrate;
+  -webkit-transform: rotate(0deg);
+  transform: rotate(0deg);
+}
+.mblCloseContent {
+  -webkit-animation-duration: 0.3s;
+  animation-duration: 0.3s;
+  -webkit-animation-timing-function: ease-in-out;
+  animation-timing-function: ease-in-out;
+  -webkit-animation-name: mblShrink;
+  animation-name: mblShrink;
+  -webkit-transform: scale(0.01);
+  transform: scale(0.01);
+}
+.mblCloseContent.mblShrink0 {
+  -webkit-animation-name: mblShrink0;
+  animation-name: mblShrink0;
+}
+.mblCloseContent.mblShrink1 {
+  -webkit-animation-name: mblShrink1;
+  animation-name: mblShrink1;
+}
+.mblCloseContent.mblShrink2 {
+  -webkit-animation-name: mblShrink2;
+  animation-name: mblShrink2;
+}
+.mblCloseContent.mblShrink3 {
+  -webkit-animation-name: mblShrink3;
+  animation-name: mblShrink3;
+}
+/* dojox.mobile._IconItemPane */
+.mblIconItemPaneHeading {
+  position: relative;
+  clear: both;
+  overflow: hidden;
+  margin-top: 0px;
+  padding-left: 40px;
+  height: 25px;
+  border-top: 1px solid #f1f3f4;
+  border-bottom: 1px solid #717d85;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e0e4e7), to(#b4bec6), color-stop(0.5, #c4ccd2), color-stop(0.5, #bfc8ce));
+  background-image: linear-gradient(to bottom, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
+  font-family: Helvetica;
+  font-size: 14px;
+  color: white;
+  line-height: 26px;
+  text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.mblIconItemPaneIcon {
+  position: absolute;
+  top: -2px;
+  left: 1px;
+}
+ at -webkit-keyframes mblVibrate {
+  0% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    -webkit-transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    -webkit-transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    -webkit-transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at keyframes mblVibrate {
+  0% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at -webkit-keyframes mblShrink {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(0.01);
+  }
+}
+ at keyframes mblShrink {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink0 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink0 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink1 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink1 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink2 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink2 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink3 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink3 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(40%, -70%) scale(0.01);
+  }
+}
diff --git a/dojox/mobile/themes/holodark/IconContainer.less b/dojox/mobile/themes/holodark/IconContainer.less
new file mode 100644
index 0000000..729745a
--- /dev/null
+++ b/dojox/mobile/themes/holodark/IconContainer.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer.less";
diff --git a/dojox/mobile/themes/holodark/IconContainer_rtl.css b/dojox/mobile/themes/holodark/IconContainer_rtl.css
new file mode 100644
index 0000000..f5b8c10
--- /dev/null
+++ b/dojox/mobile/themes/holodark/IconContainer_rtl.css
@@ -0,0 +1,14 @@
+/* dojox.mobile.IconItem Rtl */
+.mblIconItemRtl {
+  float: right;
+}
+.mblIconItemRtl .mblIconItemDeleteIcon {
+  right: -2px;
+}
+/* dojox.mobile._IconItemPane Rtl*/
+.mblIconItemPaneRtl .mblIconItemPaneHeading {
+  padding-right: 40px;
+}
+.mblIconItemPaneRtl .mblIconItemPaneIcon {
+  right: 1px;
+}
diff --git a/dojox/mobile/themes/holodark/IconMenu-compat.css b/dojox/mobile/themes/holodark/IconMenu-compat.css
new file mode 100644
index 0000000..b9aa9a5
--- /dev/null
+++ b/dojox/mobile/themes/holodark/IconMenu-compat.css
@@ -0,0 +1,34 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+  background-color: #404040;
+}
+.mblIconMenuItemSel {
+  background-color: #3578b1;
+}
+.dj_gecko .mblIconMenu {
+  background-color: rgba(64, 64, 64, 0.85);
+}
+.dj_gecko .mblIconMenuItem {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblIconMenuItemSel {
+  background-color: #3578b1;
+}
+.dj_ff3 .mblIconMenu {
+  -moz-border-radius: 6px;
+}
+.dj_ff3 .mblIconMenuItemIcon img {
+  border: 1px solid red;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-left-radius: 6px;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-right-radius: 6px;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-left-radius: 6px;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-right-radius: 6px;
+}
diff --git a/dojox/mobile/themes/holodark/IconMenu.css b/dojox/mobile/themes/holodark/IconMenu.css
new file mode 100644
index 0000000..ee983e7
--- /dev/null
+++ b/dojox/mobile/themes/holodark/IconMenu.css
@@ -0,0 +1,63 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+  width: 100%;
+  height: 100%;
+  border-radius: 6px;
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  padding: 0;
+  background-color: rgba(64, 64, 64, 0.85);
+  border: 2px solid #eeeeee;
+}
+/* dojox.mobile.IconMenuItem */
+.mblIconMenuItem {
+  float: left;
+  list-style-type: none;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border-left: 1px solid rgba(96, 96, 96, 0.85);
+  border-bottom: 1px solid rgba(96, 96, 96, 0.85);
+}
+.mblIconMenuItemIcon {
+  position: relative;
+  margin-left: auto;
+  margin-right: auto;
+}
+.mblIconMenuItemFirstColumn {
+  border-left: none;
+}
+.mblIconMenuItemLastRow {
+  border-bottom: none;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  border-top-left-radius: 6px;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  border-top-right-radius: 6px;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  border-bottom-left-radius: 6px;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  border-bottom-right-radius: 6px;
+}
+.mblIconMenuItemAnchor {
+  display: block;
+  height: 100%;
+  font-family: Helvetica;
+  text-decoration: none;
+  font-size: 13px;
+  color: white;
+  cursor: pointer;
+}
+.mblIconMenuItemTable {
+  width: 100%;
+  height: 100%;
+}
+.mblIconMenuItemTable img {
+  border: none;
+}
+.mblIconMenuItemSel {
+  background-color: #3578b1;
+  color: white;
+}
diff --git a/dojox/mobile/themes/holodark/IconMenu_rtl-compat.css b/dojox/mobile/themes/holodark/IconMenu_rtl-compat.css
new file mode 100644
index 0000000..67d04b0
--- /dev/null
+++ b/dojox/mobile/themes/holodark/IconMenu_rtl-compat.css
@@ -0,0 +1,17 @@
+/* dojox.mobile.IconMenu Rtl */
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-right-radius: 6px;
+  -moz-border-top-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-left-radius: 6px;
+  -moz-border-top-right-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-right-radius: 6px;
+  -moz-border-bottom-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-left-radius: 6px;
+  -moz-border-bottom-right-radius: 0px;
+}
diff --git a/dojox/mobile/themes/holodark/IconMenu_rtl.css b/dojox/mobile/themes/holodark/IconMenu_rtl.css
new file mode 100644
index 0000000..0675ffc
--- /dev/null
+++ b/dojox/mobile/themes/holodark/IconMenu_rtl.css
@@ -0,0 +1,23 @@
+.mblIconMenuItemRtl {
+  float: right;
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstColumn {
+  border-right: none;
+  border-left: 1px solid rgba(96, 96, 96, 0.85);
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  border-top-right-radius: 6px;
+  border-top-left-radius: 0px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  border-top-right-radius: 0px;
+  border-top-left-radius: 6px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  border-bottom-right-radius: 6px;
+  border-bottom-left-radius: 0px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  border-bottom-right-radius: 0px;
+  border-bottom-left-radius: 6px;
+}
diff --git a/dojox/mobile/themes/holodark/ListItem-compat.css b/dojox/mobile/themes/holodark/ListItem-compat.css
new file mode 100644
index 0000000..7845049
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ListItem-compat.css
@@ -0,0 +1,13 @@
+ at import url("../common/domButtons/DomButtonGrayArrow-compat.css");
+
+ at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
+/* dojox.mobile.ListItem */
+.mblListItemSelected {
+  background-color: #3578b1;
+}
+.dj_gecko .mblListItemSelected {
+  background-image: none;
+}
+.dj_ie6 .mblListItem {
+  vertical-align: bottom;
+}
diff --git a/dojox/mobile/themes/holodark/ListItem-compat.less b/dojox/mobile/themes/holodark/ListItem-compat.less
new file mode 100644
index 0000000..332107e
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ListItem-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayArrow-compat.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
+
+ at import "variables.less";
+ at import "../common/ListItem-compat.less";
diff --git a/dojox/mobile/themes/holodark/ListItem.css b/dojox/mobile/themes/holodark/ListItem.css
new file mode 100644
index 0000000..cc09b62
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ListItem.css
@@ -0,0 +1,119 @@
+ at import url("../common/domButtons/DomButtonGrayArrow.css");
+
+ at import url("../common/domButtons/DomButtonWhiteCheck.css");
+/* dojox.mobile.ListItem */
+.mblListItem {
+  position: relative;
+  overflow: hidden;
+  /* for focus frame */
+
+  padding: 0 8px;
+  height: 50px;
+  list-style-type: none;
+  line-height: 50px;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  border-bottom: 1px solid #333538;
+  margin-right: 7px;
+  margin-left: 7px;
+  font-size: 18px;
+  color: #ffffff;
+}
+.mblListItem.mblVariableHeight {
+  padding: 11px 8px;
+  height: auto;
+  line-height: normal;
+}
+.mblListItemSelected {
+  color: #ffffff;
+  background-color: #3578b1;
+}
+.mblListItemSelected .mblDomButton div {
+  border-color: white;
+}
+.mblListItemLabelSelected {
+  background-color: #048bf4;
+}
+.mblListItemChecked .mblListItemRightIcon {
+  visibility: visible;
+}
+.mblListItemChecked .mblListItemUncheckIcon {
+  position: absolute;
+  visibility: hidden;
+}
+.mblListItemUnchecked .mblListItemRightIcon {
+  visibility: hidden;
+}
+.mblListItemUnchecked .mblListItemUncheckIcon {
+  visibility: visible;
+}
+.mblListItemDeleteIcon {
+  position: relative;
+  float: left;
+  line-height: normal;
+  margin-top: 10.5px;
+  margin-bottom: -10.5px;
+  margin-right: 11px;
+}
+.mblListItemIcon {
+  position: relative;
+  float: left;
+  line-height: normal;
+  margin-top: 10.5px;
+  margin-bottom: -10.5px;
+  margin-right: 11px;
+}
+.mblListItemRightIcon,
+.mblListItemRightIcon2,
+.mblListItemUncheckIcon {
+  position: relative;
+  float: right;
+  line-height: normal;
+  margin-top: 10.5px;
+  margin-bottom: -10.5px;
+}
+.mblListItemRightText {
+  position: relative;
+  float: right;
+  line-height: normal;
+  margin-right: 4px;
+  color: white;
+  margin-top: 14px;
+}
+.mblListItemLabel {
+  position: relative;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  height: 100%;
+}
+.mblVariableHeight .mblListItemLabel {
+  white-space: normal;
+}
+.mblListItemSubText {
+  font-size: 14px;
+  color: gray;
+}
+.mblListItemLayoutLeft {
+  position: relative;
+  float: left;
+  margin-right: 11px;
+}
+.mblListItemLayoutCenter {
+  position: absolute;
+  width: 100%;
+  text-align: center;
+}
+.mblListItemLayoutRight {
+  position: relative;
+  float: right;
+}
+/* dojox.mobile._EditableListMixin */
+.mblListItemFloat {
+  position: absolute;
+  border: 1px solid gray;
+  opacity: 0.5;
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  border-radius: 0px !important;
+  -moz-border-radius: 0px !important;
+}
diff --git a/dojox/mobile/themes/holodark/ListItem.less b/dojox/mobile/themes/holodark/ListItem.less
new file mode 100644
index 0000000..45d4386
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ListItem.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayArrow.css");
+ at import url("../common/domButtons/DomButtonWhiteCheck.css");
+
+ at import "variables.less";
+ at import "../common/ListItem.less";
diff --git a/dojox/mobile/themes/holodark/ListItem_rtl-compat.css b/dojox/mobile/themes/holodark/ListItem_rtl-compat.css
new file mode 100644
index 0000000..f7deb99
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ListItem_rtl-compat.css
@@ -0,0 +1 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl-compat.css");
diff --git a/dojox/mobile/themes/holodark/ListItem_rtl.css b/dojox/mobile/themes/holodark/ListItem_rtl.css
new file mode 100644
index 0000000..30e340f
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ListItem_rtl.css
@@ -0,0 +1,29 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl.css");
+
+ at import url("../common/domButtons/DomButtonWhiteCheck_rtl.css");
+/* dojox.mobile.ListItem Rtl*/
+.mblListItemRtl .mblListItemDeleteIcon {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemIcon {
+  float: right;
+  margin-left: 11px;
+  margin-right: 0px;
+}
+.mblListItemRtl .mblListItemRightIcon,
+.mblListItemRtl .mblListItemRightIcon2,
+.mblListItemRtl .mblListItemUncheckIcon {
+  float: left;
+}
+.mblListItemRtl .mblListItemRightText {
+  float: left;
+  margin-left: 4px;
+}
+.mblListItemRtl .mblListItemLayoutLeft {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemLayoutRight {
+  float: left;
+}
diff --git a/dojox/mobile/themes/holodark/ListItem_rtl.less b/dojox/mobile/themes/holodark/ListItem_rtl.less
new file mode 100644
index 0000000..c21ef27
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ListItem_rtl.less
@@ -0,0 +1,4 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl.css");
+ at import url("../common/domButtons/DomButtonWhiteCheck_rtl.css");
+
+ at import "../common/ListItem_rtl.less";
diff --git a/dojox/mobile/themes/holodark/Opener-compat.css b/dojox/mobile/themes/holodark/Opener-compat.css
new file mode 100644
index 0000000..68cb1a8
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Opener-compat.css
@@ -0,0 +1,3 @@
+/* dojox.mobile.Opener */
+ at import url("Overlay-compat.css");
+ at import url("Tooltip-compat.css");
diff --git a/dojox/mobile/themes/holodark/Opener.css b/dojox/mobile/themes/holodark/Opener.css
new file mode 100644
index 0000000..8f2d4c8
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Opener.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.Opener */
+ at import url("Overlay.css");
+ at import url("Tooltip.css");
+
+.mblOpenerUnderlay {
+	-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
diff --git a/dojox/mobile/themes/holodark/Overlay-compat.css b/dojox/mobile/themes/holodark/Overlay-compat.css
new file mode 100644
index 0000000..4d4216c
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Overlay-compat.css
@@ -0,0 +1,14 @@
+/* dojox.mobile.Overlay */
+.mblOverlay {
+  text-align: center;
+}
+.dj_gecko .mblOverlay {
+  text-align: -moz-center;
+}
+.dj_ie9 .mblOverlay > *,
+.dj_ie8 .mblOverlay > * {
+  margin: 0 auto;
+}
+.dj_ie6 .mblOverlay {
+  *position: absolute;
+}
diff --git a/dojox/mobile/themes/holodark/Overlay.css b/dojox/mobile/themes/holodark/Overlay.css
new file mode 100644
index 0000000..a11259a
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Overlay.css
@@ -0,0 +1,19 @@
+ at import url("../common/transitions/coverv.css");
+
+ at import url("../common/transitions/revealv.css");
+/* dojox.mobile.Overlay */
+.mblOverlay {
+  position: fixed;
+  z-index: 2000;
+  left: 0;
+  bottom: 0;
+  margin: 0;
+  width: 100%;
+  text-align: -webkit-center;
+  background-color: #333333;
+  background-image: none;
+}
+.mblOverlayHidden *,
+.mblOverlayHidden {
+  visibility: hidden !important;
+}
diff --git a/dojox/mobile/themes/holodark/Overlay.less b/dojox/mobile/themes/holodark/Overlay.less
new file mode 100644
index 0000000..e49ea9e
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Overlay.less
@@ -0,0 +1,5 @@
+ at import url("../common/transitions/coverv.css");
+ at import url("../common/transitions/revealv.css");
+
+ at import "variables.less";
+ at import "../common/Overlay.less";
diff --git a/dojox/mobile/themes/holodark/PageIndicator-compat.css b/dojox/mobile/themes/holodark/PageIndicator-compat.css
new file mode 100644
index 0000000..50412f7
--- /dev/null
+++ b/dojox/mobile/themes/holodark/PageIndicator-compat.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.PageIndicator */
+.mblPageIndicatorDot {
+	-moz-border-radius: 3px;
+}
diff --git a/dojox/mobile/themes/holodark/PageIndicator.css b/dojox/mobile/themes/holodark/PageIndicator.css
new file mode 100644
index 0000000..c4384f3
--- /dev/null
+++ b/dojox/mobile/themes/holodark/PageIndicator.css
@@ -0,0 +1,23 @@
+/* dojox.mobile.PageIndicator */
+.mblPageIndicator {
+  position: relative;
+  width: 100%;
+  height: 20px;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblPageIndicatorContainer {
+  margin-top: 4px;
+  margin-left: auto;
+  margin-right: auto;
+}
+.mblPageIndicatorDot {
+  margin: 0px 3px;
+  width: 6px;
+  height: 6px;
+  font-size: 1px;
+  background-color: #949294;
+  border-radius: 3px;
+}
+.mblPageIndicatorDotSelected {
+  background-color: white;
+}
diff --git a/dojox/mobile/themes/holodark/ProgressBar-compat.css b/dojox/mobile/themes/holodark/ProgressBar-compat.css
new file mode 100644
index 0000000..c3d8833
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ProgressBar-compat.css
@@ -0,0 +1,17 @@
+/* Progress Bar */
+.mblProgressBar {
+  background-color: #333333;
+}
+.mblProgressBarProgress {
+  background-color: #33b5e5;
+}
+.dj_gecko .mblProgressBar {
+  background-image: none;
+  background-color: #333333;
+}
+.dj_gecko .mblProgressBarProgress {
+  -moz-transition-property: width;
+  -moz-transition-duration: 0.25s;
+  background-image: none;
+  background-color: #33b5e5;
+}
diff --git a/dojox/mobile/themes/holodark/ProgressBar.css b/dojox/mobile/themes/holodark/ProgressBar.css
new file mode 100644
index 0000000..fd9ba93
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ProgressBar.css
@@ -0,0 +1,35 @@
+/* dojox.mobile.ProgressBar */
+.mblProgressBar {
+  position: relative;
+  border-radius: 0px;
+  height: 2px;
+  background-image: none;
+  background-color: #333333;
+}
+.mblProgressBarProgress {
+  -webkit-transition-property: width;
+  transition-property: width;
+  -webkit-transition-duration: 0.25s;
+  transition-duration: 0.25s;
+  border-top-left-radius: 6px;
+  border-bottom-left-radius: 6px;
+  background-image: none;
+  background-color: #33b5e5;
+  height: 2px;
+}
+.mblProgressBarComplete {
+  border-radius: 0px;
+}
+.mblProgressBarNotStarted {
+  border-left: none;
+  border-right: none;
+}
+.mblProgressBarMsg {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  text-align: center;
+  font-size: 12px;
+  top: 3px;
+}
diff --git a/dojox/mobile/themes/holodark/ProgressBar.less b/dojox/mobile/themes/holodark/ProgressBar.less
new file mode 100644
index 0000000..e2afc0b
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ProgressBar.less
@@ -0,0 +1,6 @@
+ at import "variables.less";
+ at import "../common/ProgressBar.less";
+
+.mblProgressBarMsg {
+  //display:none;
+}
diff --git a/dojox/mobile/themes/holodark/ProgressIndicator-compat.css b/dojox/mobile/themes/holodark/ProgressIndicator-compat.css
new file mode 100644
index 0000000..cbabad7
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ProgressIndicator-compat.css
@@ -0,0 +1,83 @@
+/* Progress Indicator */
+.dj_ie .mblProg {
+  width: 4px;
+  height: 36px;
+}
+.dj_ie .mblProg0 {
+  left: 0px;
+}
+.dj_ie .mblProg1 {
+  left: 8px;
+}
+.dj_ie .mblProg2 {
+  left: 16px;
+}
+.dj_ie .mblProg3 {
+  left: 24px;
+}
+.dj_ie .mblProg4 {
+  left: 32px;
+}
+.dj_ie .mblProg5 {
+  left: 40px;
+}
+.dj_ie .mblProg6 {
+  left: 48px;
+}
+.dj_ie .mblProg7 {
+  left: 56px;
+}
+.dj_ie .mblProg8 {
+  left: 64px;
+}
+.dj_ie .mblProg9 {
+  left: 72px;
+}
+.dj_ie .mblProg10 {
+  left: 80px;
+}
+.dj_ie .mblProg11 {
+  left: 80px;
+}
+.dj_gecko .mblProgressIndicatorCenter .mblProgContainer {
+  -moz-transform-origin: 50% 0;
+}
+.dj_gecko .mblProg {
+  -moz-transform-origin: 0 2px;
+}
+.dj_gecko .mblProg0 {
+  -moz-transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.dj_gecko .mblProg1 {
+  -moz-transform: translate(22px, 11px) rotate(-60deg);
+}
+.dj_gecko .mblProg2 {
+  -moz-transform: translate(25px, 14px) rotate(-30deg);
+}
+.dj_gecko .mblProg3 {
+  -moz-transform: translate(26px, 18px) rotate(0deg);
+}
+.dj_gecko .mblProg4 {
+  -moz-transform: translate(25px, 22px) rotate(30deg);
+}
+.dj_gecko .mblProg5 {
+  -moz-transform: translate(22px, 25px) rotate(60deg);
+}
+.dj_gecko .mblProg6 {
+  -moz-transform: translate(18px, 26px) rotate(90.1deg);
+}
+.dj_gecko .mblProg7 {
+  -moz-transform: translate(14px, 25px) rotate(120deg);
+}
+.dj_gecko .mblProg8 {
+  -moz-transform: translate(11px, 22px) rotate(150deg);
+}
+.dj_gecko .mblProg9 {
+  -moz-transform: translate(10px, 18px) rotate(180deg);
+}
+.dj_gecko .mblProg10 {
+  -moz-transform: translate(11px, 14px) rotate(210deg);
+}
+.dj_gecko .mblProg11 {
+  -moz-transform: translate(14px, 11px) rotate(240deg);
+}
diff --git a/dojox/mobile/themes/holodark/ProgressIndicator.css b/dojox/mobile/themes/holodark/ProgressIndicator.css
new file mode 100644
index 0000000..17a8bda
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ProgressIndicator.css
@@ -0,0 +1,157 @@
+/* Progress Indicator */
+.mblProgressIndicator {
+  position: relative;
+  top: 0px;
+}
+.mblHeading .mblProgressIndicator {
+  margin: 5px;
+  float: left;
+}
+.mblProgContainer {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+}
+.mblProgressIndicatorCenter {
+  position: absolute;
+  top: 180px;
+  left: 50%;
+}
+.mblProgressIndicatorCenter .mblProgContainer {
+  left: -50%;
+  -webkit-transform-origin: 50% 0;
+  transform-origin: 50% 0;
+}
+.mblProg {
+  position: absolute;
+  left: 2px;
+  top: 0px;
+  width: 11px;
+  font-size: 1px;
+  height: 4px;
+  overflow: hidden;
+  -webkit-transform-origin: 0 2px;
+  transform-origin: 0 2px;
+  background-color: #c0c0c0;
+  border-radius: 2px;
+}
+.mblProg0 {
+  -webkit-transform: translate(18px, 10px) rotate(-90.1deg);
+  transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.mblProg1 {
+  -webkit-transform: translate(22px, 11px) rotate(-60deg);
+  transform: translate(22px, 11px) rotate(-60deg);
+}
+.mblProg2 {
+  -webkit-transform: translate(25px, 14px) rotate(-30deg);
+  transform: translate(25px, 14px) rotate(-30deg);
+}
+.mblProg3 {
+  -webkit-transform: translate(26px, 18px) rotate(0deg);
+  transform: translate(26px, 18px) rotate(0deg);
+}
+.mblProg4 {
+  -webkit-transform: translate(25px, 22px) rotate(30deg);
+  transform: translate(25px, 22px) rotate(30deg);
+}
+.mblProg5 {
+  -webkit-transform: translate(22px, 25px) rotate(60deg);
+  transform: translate(22px, 25px) rotate(60deg);
+}
+.mblProg6 {
+  -webkit-transform: translate(18px, 26px) rotate(90.1deg);
+  transform: translate(18px, 26px) rotate(90.1deg);
+}
+.mblProg7 {
+  -webkit-transform: translate(14px, 25px) rotate(120deg);
+  transform: translate(14px, 25px) rotate(120deg);
+}
+.mblProg8 {
+  -webkit-transform: translate(11px, 22px) rotate(150deg);
+  transform: translate(11px, 22px) rotate(150deg);
+}
+.mblProg9 {
+  -webkit-transform: translate(10px, 18px) rotate(180deg);
+  transform: translate(10px, 18px) rotate(180deg);
+}
+.mblProg10 {
+  -webkit-transform: translate(11px, 14px) rotate(210deg);
+  transform: translate(11px, 14px) rotate(210deg);
+}
+.mblProg11 {
+  -webkit-transform: translate(14px, 11px) rotate(240deg);
+  transform: translate(14px, 11px) rotate(240deg);
+}
+.mblProg0Color {
+  background-color: #c0c0c0;
+}
+.mblProg1Color {
+  background-color: #c0c0c0;
+}
+.mblProg2Color {
+  background-color: #c0c0c0;
+}
+.mblProg3Color {
+  background-color: #c0c0c0;
+}
+.mblProg4Color {
+  background-color: #c0c0c0;
+}
+.mblProg5Color {
+  background-color: #c0c0c0;
+}
+.mblProg6Color {
+  background-color: #b8b9b8;
+}
+.mblProg7Color {
+  background-color: #aeafae;
+}
+.mblProg8Color {
+  background-color: #a4a5a4;
+}
+.mblProg9Color {
+  background-color: #9a9a9a;
+}
+.mblProg10Color {
+  background-color: #8e8e8e;
+}
+.mblProg11Color {
+  background-color: #838383;
+}
+.mblProgWhite .mblProg0Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg1Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg2Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg3Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg4Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg5Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg6Color {
+  background-color: #acb9cb;
+}
+.mblProgWhite .mblProg7Color {
+  background-color: #b7c2d2;
+}
+.mblProgWhite .mblProg8Color {
+  background-color: #c4cdda;
+}
+.mblProgWhite .mblProg9Color {
+  background-color: #d1d8e2;
+}
+.mblProgWhite .mblProg10Color {
+  background-color: #dee3ea;
+}
+.mblProgWhite .mblProg11Color {
+  background-color: #eceff3;
+}
diff --git a/dojox/mobile/themes/holodark/RadioButton-compat.css b/dojox/mobile/themes/holodark/RadioButton-compat.css
new file mode 100644
index 0000000..4247b25
--- /dev/null
+++ b/dojox/mobile/themes/holodark/RadioButton-compat.css
@@ -0,0 +1,32 @@
+/* dojox.mobile.RadioButton */
+.mblRadioButton {
+  background-image: url(compat/button-bg.png);
+}
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: url(compat/blue-button-sel-bg.png);
+}
+.dj_gecko .mblRadioButton {
+  background-image: none;
+  -moz-appearance: none;
+}
+.dj_gecko .mblRadioButtonChecked,
+.dj_gecko .mblRadioButton:checked {
+  background-image: none;
+}
+.dj_gecko .mblRadioButtonChecked::after,
+.dj_gecko .mblRadioButton:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblRadioButtonChecked.mblRadioButtonSelected,
+.dj_gecko .mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: none;
+}
+.dj_ff3 .mblRadioButton {
+  -moz-border-radius: 0.5em;
+}
diff --git a/dojox/mobile/themes/holodark/RadioButton.css b/dojox/mobile/themes/holodark/RadioButton.css
new file mode 100644
index 0000000..683c956
--- /dev/null
+++ b/dojox/mobile/themes/holodark/RadioButton.css
@@ -0,0 +1,87 @@
+/* dojox.mobile.RadioButton */
+.mblRadioButton {
+  position: relative;
+  margin: -0.5em 3px 0.3em 4px;
+  width: 1em;
+  height: 1em;
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 0.5em;
+  background-image: none;
+  background-color: #333333;
+  border-style: none;
+  border-top-style: solid;
+  border-top-color: rgba(85, 85, 85, 0.9);
+  border-top-width: 1px;
+  border-radius: 2px;
+  font: inherit;
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  border-color: #5c5c5c;
+}
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
+  background-color: transparent;
+}
+.mblRadioButtonChecked::after,
+.mblRadioButton:checked::after {
+  position: absolute;
+  content: "";
+  width: 0.3em;
+  height: 0.6em;
+  top: 0;
+  left: 0.25em;
+  border-width: 0.15em;
+  border-style: none solid solid none;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: #61c6eb;
+}
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: none;
+}
+.mblRadioButtonChecked.mblRadioButtonSelected::after,
+.mblRadioButton:checked.mblRadioButtonSelected::after {
+  border-color: #61c6eb;
+}
+.mblRadioButton {
+  border-style: solid;
+  border-width: 1px;
+  border-radius: 999px;
+  background-image: none;
+  background-color: transparent;
+  -webkit-tap-highlight-color: none;
+  border-color: #5c5c5c;
+}
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
+  background-image: none;
+}
+.mblRadioButtonChecked::after,
+.mblRadioButton:checked::after {
+  position: absolute;
+  content: "";
+  width: 0.65em;
+  height: 0.65em;
+  top: 0.17em;
+  left: 0.17em;
+  border-style: none;
+  background-color: #61c6eb;
+  border-radius: 1em;
+  border-color: #61c6eb;
+}
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: none;
+  box-shadow: 0px 0px 1px 4px #1f5366 inset;
+}
+.mblRadioButtonChecked.mblRadioButtonSelected::after,
+.mblRadioButton:checked.mblRadioButtonSelected::after {
+  border-color: #61c6eb;
+}
diff --git a/dojox/mobile/themes/holodark/RadioButton.less b/dojox/mobile/themes/holodark/RadioButton.less
new file mode 100644
index 0000000..4b51534
--- /dev/null
+++ b/dojox/mobile/themes/holodark/RadioButton.less
@@ -0,0 +1,37 @@
+ at import "variables.less";
+ at import "../common/RadioButton.less";
+.mblRadioButton {
+  border-style: solid;
+  border-width: 1px;
+  border-radius: 999px;
+  background-image: none;
+  background-color: transparent;
+  -webkit-tap-highlight-color: none;
+  .mblRadioButton-styles;
+}
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
+  background-image: none;
+  &::after {
+    position: absolute;
+    content: "";
+    width: 0.65em;
+    height: 0.65em;
+    top: 0.17em;
+    left: 0.17em;
+    
+    border-style: none;
+    background-color: @holo-checkbox-tick-color;
+    border-radius: 1em;
+
+    .mblRadioButtonChecked-after-styles;
+  }
+  &.mblRadioButtonSelected {
+    background-image: none;
+    box-shadow: 0px 0px 1px 4px @holo-checkbox-checked-color inset;
+    &::after {
+      .mblRadioButtonChecked-Selected-after-styles;
+      
+    }
+  } 
+}
diff --git a/dojox/mobile/themes/holodark/RoundRect-compat.css b/dojox/mobile/themes/holodark/RoundRect-compat.css
new file mode 100644
index 0000000..22c6f0b
--- /dev/null
+++ b/dojox/mobile/themes/holodark/RoundRect-compat.css
@@ -0,0 +1,73 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect.mblShadow {
+  box-shadow: none;
+}
+.dj_ff3 .mblRoundRect {
+  -moz-border-radius: 14px;
+}
+.dj_ff3 .mblRoundRect.mblShadow {
+  -moz-box-shadow: none;
+}
+/* Round Corner */
+.dj_ie .mblRoundCorner {
+  background-color: transparent;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #222222;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: transparent;
+  border-style: solid;
+  border-color: #222222;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #222222;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #222222;
+  margin: 0 5px;
+}
diff --git a/dojox/mobile/themes/holodark/RoundRect.css b/dojox/mobile/themes/holodark/RoundRect.css
new file mode 100644
index 0000000..76266be
--- /dev/null
+++ b/dojox/mobile/themes/holodark/RoundRect.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect {
+  margin: 7px 9px 16px;
+  padding: 8px;
+  border: 1px solid #222222;
+  border-radius: 14px;
+  background-color: transparent;
+  color: white;
+}
+.mblRoundRect.mblShadow {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
diff --git a/dojox/mobile/themes/holodark/RoundRectCategory.css b/dojox/mobile/themes/holodark/RoundRectCategory.css
new file mode 100644
index 0000000..ea9158b
--- /dev/null
+++ b/dojox/mobile/themes/holodark/RoundRectCategory.css
@@ -0,0 +1,10 @@
+/* dojox.mobile.RoundRectCategory */
+.mblRoundRectCategory {
+  margin: 18px 0 0 20px;
+  padding: 0;
+  font-family: Helvetica;
+  font-size: 16px;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+}
diff --git a/dojox/mobile/themes/holodark/RoundRectCategory_rtl.css b/dojox/mobile/themes/holodark/RoundRectCategory_rtl.css
new file mode 100644
index 0000000..2a7ffc3
--- /dev/null
+++ b/dojox/mobile/themes/holodark/RoundRectCategory_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.RoundRectCategory Rtl */
+.mblRoundRectCategoryRtl {
+  margin: 18px 20px 0px 0px;
+}
diff --git a/dojox/mobile/themes/holodark/RoundRectList-compat.css b/dojox/mobile/themes/holodark/RoundRectList-compat.css
new file mode 100644
index 0000000..797b76c
--- /dev/null
+++ b/dojox/mobile/themes/holodark/RoundRectList-compat.css
@@ -0,0 +1,78 @@
+/* dojox.mobile.RoundRectList */
+.dj_ff3 .mblRoundRectList {
+  -moz-border-radius: 14px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:first-child {
+  -moz-border-radius-topleft: 14px;
+  -moz-border-radius-topright: 14px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:last-child {
+  -moz-border-radius-bottomleft: 14px;
+  -moz-border-radius-bottomright: 14px;
+}
+/* Round Corner */
+.dj_ie .mblRoundRectList {
+  position: relative;
+}
+.dj_ie .mblRoundCorner {
+  background-color: transparent;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #222222;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: transparent;
+  border-style: solid;
+  border-color: #222222;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #222222;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #222222;
+  margin: 0 5px;
+}
diff --git a/dojox/mobile/themes/holodark/RoundRectList.css b/dojox/mobile/themes/holodark/RoundRectList.css
new file mode 100644
index 0000000..9625a3e
--- /dev/null
+++ b/dojox/mobile/themes/holodark/RoundRectList.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.RoundRectList */
+.mblRoundRectList {
+  margin: 7px 9px 16px;
+  padding: 0;
+  border: 1px solid #222222;
+  border-radius: 14px;
+  background-color: transparent;
+}
+.mblRoundRectList .mblListItem:first-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:first-child {
+  border-top-left-radius: 14px;
+  border-top-right-radius: 14px;
+}
+.mblRoundRectList .mblListItem:last-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 14px;
+  border-bottom-right-radius: 14px;
+}
diff --git a/dojox/mobile/themes/holodark/ScrollablePane.css b/dojox/mobile/themes/holodark/ScrollablePane.css
new file mode 100644
index 0000000..573d58f
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ScrollablePane.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.mblScrollablePane */
+.mblScrollablePane {
+  position: relative;
+  overflow: hidden;
+}
+.mblScrollableViewContainer {
+  position: absolute;
+  top: 0px;
+}
+.mblScrollablePaneMask {
+  position: relative;
+}
diff --git a/dojox/mobile/themes/holodark/SearchBox-compat.css b/dojox/mobile/themes/holodark/SearchBox-compat.css
new file mode 100644
index 0000000..913c704
--- /dev/null
+++ b/dojox/mobile/themes/holodark/SearchBox-compat.css
@@ -0,0 +1,26 @@
+ at import url("TextBox-compat.css");
+/* dojox.mobile.SearchBox */
+.mblSearchBox {
+  height: auto;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  -moz-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/holodark/SearchBox.css b/dojox/mobile/themes/holodark/SearchBox.css
new file mode 100644
index 0000000..eb3511d
--- /dev/null
+++ b/dojox/mobile/themes/holodark/SearchBox.css
@@ -0,0 +1,61 @@
+ at import url("TextBox.css");
+/* dojox.mobile.SearchBox */
+.mblSearchBox.iphone4:focus::-webkit-search-cancel-button {
+  background: none !important;
+  border-color: transparent !important;
+}
+.mblSearchBox::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+  background-color: transparent;
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-size: 15px 15px;
+  background-image: -webkit-gradient(linear, left top, right bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #000000), color-stop(0.54, #000000), color-stop(0.54, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #000000), color-stop(0.54, #000000), color-stop(0.54, transparent), to(transparent)) !important;
+  border: 2px solid transparent;
+  box-sizing: border-box;
+  height: 15px;
+  width: 15px;
+  display: inline-block;
+  vertical-align: middle;
+  margin-left: 0.5em;
+  border-radius: 0;
+}
+.mblSearchBox::-webkit-search-results-decoration {
+  -webkit-appearance: none;
+  background-repeat: no-repeat;
+  background-size: 13px 13px, 9px 9px;
+  background-position: 0px 0px, 10px 10px;
+  background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 6, from(transparent), color-stop(0.65, transparent), color-stop(0.8, #000000), color-stop(0.95, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.425, transparent), color-stop(0.5, #000000), color-stop(0.575, transparent), to(transparent)) !important;
+  width: 15px;
+  height: 15px;
+  display: inline-block;
+  vertical-align: middle;
+}
+.mblSearchBox {
+  height: auto;
+}
+.dj_chrome .mblSearchBox {
+  border-radius: 0;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/holodark/SimpleDialog-compat.css b/dojox/mobile/themes/holodark/SimpleDialog-compat.css
new file mode 100644
index 0000000..3baedf8
--- /dev/null
+++ b/dojox/mobile/themes/holodark/SimpleDialog-compat.css
@@ -0,0 +1,10 @@
+/* dojox.mobile.SimpleDialog */
+.mblSimpleDialogDecoration {
+  background-color: #404040;
+}
+.dj_gecko .mblSimpleDialogDecoration {
+  background-color: rgba(64, 64, 64, 0.85);
+}
+.dj_ff3 .mblSimpleDialogDecoration {
+  -moz-border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/holodark/SimpleDialog.css b/dojox/mobile/themes/holodark/SimpleDialog.css
new file mode 100644
index 0000000..b950027
--- /dev/null
+++ b/dojox/mobile/themes/holodark/SimpleDialog.css
@@ -0,0 +1,54 @@
+/* dojox.mobile.SimpleDialog */
+.mblSimpleDialog {
+  position: absolute;
+  z-index: 100;
+  margin: 0;
+  text-align: center;
+  outline: none;
+  padding: 5px;
+  width: 262px;
+}
+.mblSimpleDialogDecoration {
+  background-color: rgba(64, 64, 64, 0.85);
+  border: 2px solid #eeeeee;
+  color: white;
+  background-image: none;
+  background-color: #222222;
+  border-style: none;
+  border-top-style: solid;
+  border-top-width: 1px;
+  border-top-color: rgba(255, 255, 255, 0.6);
+  border-radius: 2px;
+}
+.mblSimpleDialogContainer {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.mblSimpleDialogCover {
+  background-color: #000000;
+  opacity: 0.5;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 99;
+}
+.mblSimpleDialogCloseBtn {
+  position: absolute !important;
+}
+.mblSimpleDialogTitle {
+  margin: 14px 0 7px -5px;
+  padding: 0 14px 14px;
+  width: 244px;
+  border-bottom: 1px solid #33b5e5;
+  font-size: 17px;
+  text-align: left;
+}
+.mblSimpleDialogText {
+  margin: 14px 9px;
+  width: 244px;
+  font-size: 17px;
+  text-align: left;
+}
diff --git a/dojox/mobile/themes/holodark/Slider-compat.css b/dojox/mobile/themes/holodark/Slider-compat.css
new file mode 100644
index 0000000..3c554e9
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Slider-compat.css
@@ -0,0 +1,40 @@
+/* dojox.mobile.Slider */
+.mblSlider {
+  background-image: url(compat/slider-h-bg.png);
+  background-repeat: repeat-x;
+}
+.mblSliderProgressBar {
+  background-image: url(compat/slider-h-bar-bg.png);
+  background-repeat: repeat-x;
+}
+.mblSliderHandle {
+  background-image: url(compat/slider-handle-bg.png);
+}
+.mblSliderV {
+  background-color: #bdbebd;
+  background-image: none;
+}
+.mblSliderV .mblSliderProgressBar {
+  background-color: #00a200;
+  background-image: none;
+}
+.dj_gecko .mblSlider {
+  background-image: -none;
+  -moz-user-select: none;
+  -moz-box-sizing: content-box;
+}
+.dj_gecko .mblSliderProgressBar {
+  background-image: none;
+}
+.dj_gecko .mblSliderHandle {
+  background-image: none;
+}
+.dj_ff3 .mblSlider {
+  -moz-border-radius: 10em;
+}
+.dj_ff3 .mblSliderProgressBar {
+  -moz-border-radius: 10em;
+}
+.dj_ff3 .mblSliderHandle {
+  -moz-border-radius: 10em;
+}
diff --git a/dojox/mobile/themes/holodark/Slider.css b/dojox/mobile/themes/holodark/Slider.css
new file mode 100644
index 0000000..d3eced8
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Slider.css
@@ -0,0 +1,98 @@
+/* dojox.mobile.Slider */
+.mblSlider {
+  margin: 15px;
+  border-style: inset;
+  border-width: 1px;
+  border-radius: 10em;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bdbebd), to(#f7f3f7));
+  background-image: linear-gradient(to bottom, #bdbebd 0%, #f7f3f7 100%);
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -webkit-box-sizing: content-box;
+  box-sizing: content-box;
+  border-color: #b0b0b0;
+}
+.mblSliderH {
+  width: 200px;
+  height: 8px;
+}
+.mblSliderH .mblSliderProgressBar {
+  height: 100%;
+}
+.mblSliderH .mblSliderHandle {
+  top: 50%;
+}
+.mblSliderV {
+  height: 200px;
+  width: 8px;
+}
+.mblSliderV .mblSliderProgressBar {
+  width: 100%;
+}
+.mblSliderV .mblSliderHandle {
+  left: 50%;
+}
+.mblSliderProgressBar {
+  border-radius: 10em;
+  background-image: none;
+}
+.mblSliderHandle {
+  margin: -10px 0 0 -10px;
+  width: 18px;
+  height: 18px;
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 10em;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9a9c), to(#848284));
+  background-image: linear-gradient(to bottom, #9c9a9c 0%, #848284 100%);
+  border-color: transparent;
+}
+.mblSliderTransition {
+  -webkit-transition-duration: 400ms;
+  transition-duration: 400ms;
+}
+.mblSliderTouchBox {
+  margin: 0;
+  padding: 12pt;
+  left: -12pt;
+  top: -12pt;
+  border: none;
+  width: 100%;
+  height: 100%;
+  background-color: transparent;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblSlider {
+  border-style: none;
+  border-radius: 0;
+  background-image: none;
+  background-color: transparent;
+  border-color: #b0b0b0;
+}
+.mblSliderH {
+  width: 200px;
+  height: 3px;
+  background-color: #292929;
+  border-style: none;
+}
+.mblSliderV {
+  height: 200px;
+  width: 3px;
+  background-color: #292929;
+  border-style: none;
+}
+.mblSliderProgressBar {
+  border: radius: 0;
+  background-image: none;
+  background-color: #33b5e5;
+}
+.mblSliderHandle {
+  background: -webkit-gradient(radial, 9 9, 3, 9 9, 9, from(#33b5e5), color-stop(0, #33b5e5), color-stop(0.01, rgba(31, 83, 102, 0.8)), to(rgba(31, 83, 102, 0.8)));
+  background-image: radial-gradient(circle closest-side at center, #ffffff 0%, #a435c5 50%, #251ae7 75%, #00a3ef 100%);
+  border-color: transparent;
+}
+.mblSliderHandle:after {
+  border-style: solid;
+  background-image: none;
+  border-color: transparent;
+}
diff --git a/dojox/mobile/themes/holodark/Slider.less b/dojox/mobile/themes/holodark/Slider.less
new file mode 100644
index 0000000..eb56152
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Slider.less
@@ -0,0 +1,45 @@
+ at import "variables.less";
+ at import "../common/Slider.less";
+
+.mblSlider {
+  border-style: none;
+  border-radius: 0;
+  background-image: none;
+  background-color: transparent;
+  .mblSlider-styles;
+}
+.mblSliderH {
+  width: 200px;
+
+  height: 3px;
+  background-color: @holo-slider-track-color;
+  border-style: none;
+}
+
+.mblSliderV {
+  height: 200px;
+  width: 3px;
+  background-color: @holo-slider-track-color;
+  border-style: none;
+  
+}
+
+.mblSliderProgressBar {
+  border:radius: 0;
+  background-image: none;
+  background-color: @holo-color1;
+  
+  
+}
+.mblSliderHandle {
+  .holo-slider-background-image();
+  .mblSliderHandle-styles;
+}
+
+.mblSliderHandle:after {
+  border-style: solid;
+  background-image: none;
+  .mblSliderHandle-styles;
+}
+
+
diff --git a/dojox/mobile/themes/holodark/SpinWheel-compat.css b/dojox/mobile/themes/holodark/SpinWheel-compat.css
new file mode 100644
index 0000000..4d605d5
--- /dev/null
+++ b/dojox/mobile/themes/holodark/SpinWheel-compat.css
@@ -0,0 +1,36 @@
+.mblSpinWheel {
+  background-image: url(../common/compat/spinwheel-bg.png);
+}
+.mblSpinWheelBar {
+  background-image: url(../common/compat/spinwheel-bar.png);
+}
+.mblSpinWheelSlotTouch,
+.mblSpinWheelSlotPanel {
+  left: 0;
+}
+.dj_gecko .mblSpinWheel {
+  background-image: -moz-linear-gradient(top, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+}
+.dj_gecko .mblSpinWheelBar {
+  background-image: -moz-linear-gradient(top, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 1%);
+}
+.dj_ff3 .mblSpinWheel {
+  -moz-border-radius: 3px;
+}
+.dj_ie .mblSpinWheelBar {
+  filter: progid:DXImageTransform.Microsoft.alpha(opacity=60);
+}
+.dj_ie6 .mblSpinWheelBar,
+.dj_ie7 .mblSpinWheelBar {
+  z-index: -1;
+}
+.dj_ie7 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
+.dj_ie6 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
diff --git a/dojox/mobile/themes/holodark/SpinWheel.css b/dojox/mobile/themes/holodark/SpinWheel.css
new file mode 100644
index 0000000..8764541
--- /dev/null
+++ b/dojox/mobile/themes/holodark/SpinWheel.css
@@ -0,0 +1,77 @@
+/* dojox.mobile.SpinWheel */
+.mblSpinWheel {
+  position: relative;
+  overflow: hidden;
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #313137), color-stop(0.05, #73747d), color-stop(0.07, #92939b), color-stop(0.09, #ababb5), color-stop(0.12, #c5c6ce), color-stop(0.16, #dfe0e4), color-stop(0.22, #f4f5f6), color-stop(0.35, #fbfcfc), color-stop(0.5, #fbfcfc), color-stop(0.61, #fbfcfc), color-stop(0.61, #b4c1c7), color-stop(0.65, #fbfcfc), color-stop(0.78, #f4f5f6), color-stop(0.84, #dfe0e4), color-stop(0.88, #c5c6ce), color-stop(0.91, #ababb5), co [...]
+  background: linear-gradient(to bottom, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+  height: 200px;
+  border-left: solid 3px #000000;
+  border-right: solid 3px #000000;
+  color: #000000;
+  border-radius: 3px;
+}
+.mblSpinWheelBar {
+  position: absolute;
+  top: 79px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#edeef2), to(#a7adca), color-stop(0, #edeef2), color-stop(0.25, #c8cadd), color-stop(0.49, #bbbfd4), color-stop(0.51, #9fa8c6), color-stop(0.81, #a2a9c7), color-stop(0.82, #a6abc9), color-stop(1, #a7adca));
+  background: linear-gradient(to bottom, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 100%);
+  border: solid 1px #7b8497;
+  height: 42px;
+  width: 100%;
+  clear: both;
+  opacity: 0.6;
+}
+.mblSpinWheelDatePicker {
+  width: 312px;
+}
+.mblSpinWheelTimePicker {
+  width: 98px;
+}
+.mblSpinWheelSlot {
+  position: relative;
+  top: 0px;
+  float: left;
+  width: 100px;
+  height: 100%;
+  border-left: solid 2px #000000;
+  border-right: solid 2px #000000;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblSpinWheelSlotLabel {
+  padding: 0 8px;
+  height: 44px;
+  overflow: hidden;
+  font: bold 24px/44px Helvetica, sans-serif;
+}
+.mblSpinWheelSlotLabel img {
+  vertical-align: middle;
+  opacity: 0.7;
+}
+.mblSpinWheelSlotLabelGray {
+  color: #cccccc;
+}
+.mblSpinWheelSlotLabelBlue {
+  color: #0959d2;
+}
+.mblSpinWheelSlotContainer {
+  position: relative;
+}
+.mblSpinWheelSlotPanel {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+}
+.mblSpinWheelSlotTouch {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  z-index: 1;
+}
+.dj_ie .mblSpinWheelSlotTouch {
+  background-color: rgba(255, 255, 255, 0.01);
+}
+.dj_ie8 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+}
diff --git a/dojox/mobile/themes/holodark/SpinWheel_rtl-compat.css b/dojox/mobile/themes/holodark/SpinWheel_rtl-compat.css
new file mode 100644
index 0000000..98aab55
--- /dev/null
+++ b/dojox/mobile/themes/holodark/SpinWheel_rtl-compat.css
@@ -0,0 +1,4 @@
+.mblSpinWheelSlotRtl .mblSpinWheelSlotTouch,
+.mblSpinWheelSlotRtl .mblSpinWheelSlotPanel {
+  right: 0;
+}
diff --git a/dojox/mobile/themes/holodark/SpinWheel_rtl.css b/dojox/mobile/themes/holodark/SpinWheel_rtl.css
new file mode 100644
index 0000000..c3efc85
--- /dev/null
+++ b/dojox/mobile/themes/holodark/SpinWheel_rtl.css
@@ -0,0 +1,5 @@
+/* dojox.mobile.SpinWheel Rtl */
+.mblSpinWheelSlotRtl,
+.mblSpinWheelRtl .mblSpinWheelSlot {
+  float: right;
+}
diff --git a/dojox/mobile/themes/holodark/Switch-compat.css b/dojox/mobile/themes/holodark/Switch-compat.css
new file mode 100644
index 0000000..905c97e
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Switch-compat.css
@@ -0,0 +1,116 @@
+/* dojox.mobile.Switch */
+/* Switch - common */
+.dj_gecko .mblSwitchBg {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitchKnob {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitch .mblSwitchBgLeft {
+  background-image: none;
+}
+.dj_gecko .mblSwitch .mblSwitchBgRight {
+  background-image: -none;
+}
+.dj_gecko .mblSwitch .mblSwitchKnob {
+  background-image: none;
+}
+.dj_ie .mblSwitchBg {
+  border: none;
+  background: none;
+}
+.dj_ie .mblSwitchBgLeft {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchBgRight {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchKnob {
+  background: none;
+  background-repeat: no-repeat;
+  border: none;
+}
+/* Square Shape */
+.mblSwSquareShape .mblSwitchBg {
+  -moz-border-radius: 0px;
+}
+.mblSwSquareShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-square-l.gif);
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchKnob {
+  -moz-border-radius: 0px;
+  background-image: url(compat/switch-square-k.gif);
+}
+/* Round Shape1 */
+.mblSwRoundShape1 .mblSwitchBg {
+  -moz-border-radius: 14px;
+}
+.mblSwRoundShape1 .mblSwitchBgLeft {
+  background-image: url(compat/switch-round1-l.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round1-k.gif);
+}
+/* Round Shape2 */
+.mblSwRoundShape2 .mblSwitchBg {
+  -moz-border-radius: 14px;
+}
+.mblSwRoundShape2 .mblSwitchBgLeft {
+  background-image: url(compat/switch-round2-l.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+  background-image: url(compat/switch-round2-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchKnob {
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round2-k.gif);
+}
+/* Arc Shape1 */
+.mblSwArcShape1 .mblSwitchBg {
+  -moz-border-radius: 5px/14px;
+}
+.mblSwArcShape1 .mblSwitchBgLeft {
+  background-image: url(compat/switch-arc1-l.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+  background-image: url(compat/switch-arc1-r.gif);
+}
+.mblSwArcShape1 .mblSwitchKnob {
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc1-k.gif);
+}
+/* Switch - Arc Shape2 */
+.mblSwArcShape2 .mblSwitchBg {
+  -moz-border-radius: 5px/14px;
+}
+.mblSwArcShape2 .mblSwitchBgLeft {
+  background-image: url(compat/switch-arc2-l.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+  background-image: url(compat/switch-arc2-r.gif);
+}
+.mblSwArcShape2 .mblSwitchKnob {
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc2-k.gif);
+}
+/* Default Shape */
+.mblSwDefaultShape .mblSwitchBg {
+  -moz-border-radius: 0px;
+}
+.mblSwDefaultShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-square-l.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  -moz-border-radius: 0px;
+  background-image: url(compat/switch-square-k.gif);
+}
diff --git a/dojox/mobile/themes/holodark/Switch-compat.less b/dojox/mobile/themes/holodark/Switch-compat.less
new file mode 100644
index 0000000..f15894c
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Switch-compat.less
@@ -0,0 +1,7 @@
+ at import "variables.less";
+ at import "../common/Switch-compat.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwSquareShape-styles;
+}
diff --git a/dojox/mobile/themes/holodark/Switch.css b/dojox/mobile/themes/holodark/Switch.css
new file mode 100644
index 0000000..f1451a2
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Switch.css
@@ -0,0 +1,240 @@
+/* dojox.mobile.Switch */
+/* Switch - common */
+.mblSwitch {
+  margin: 0;
+  position: relative;
+  display: inline-block;
+  height: 27px;
+  line-height: 29px;
+  overflow: hidden;
+  text-align: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblListItem .mblSwitch {
+  position: absolute;
+  right: 12px;
+  top: 11.5px;
+}
+.mblSwitchInner {
+  position: absolute;
+  top: 0;
+  height: 27px;
+}
+.mblSwitchAnimation .mblSwitchInner {
+  -webkit-transition-property: left;
+  transition-property: left;
+  -webkit-transition-duration: 0.1s;
+  transition-duration: 0.1s;
+}
+.mblSwitchOn .mblSwitchInner {
+  left: 0;
+}
+.mblSwitchBg {
+  position: absolute;
+  top: 0;
+  width: 94px;
+  height: 27px;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+  line-height: 29px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border: rgba(176, 176, 176, 0.5) 1px inset;
+}
+.mblSwitchBgLeft {
+  left: 0;
+  color: white;
+  background-color: #3f84eb;
+  background-image: none;
+}
+.mblSwitchBgRight {
+  color: #7f7f7f;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#bdbebd), to(#f7f3f7));
+  background-image: linear-gradient(to bottom, #bdbebd 0%, #f7f3f7 100%);
+}
+.mblSwitchKnob {
+  position: absolute;
+  top: 0;
+  height: 27px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9a9c), to(#848284));
+  background-image: linear-gradient(to bottom, #9c9a9c 0%, #848284 100%);
+  font-size: 1px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border: rgba(157, 157, 157, 0.5) 1px outset;
+}
+.mblSwitchText {
+  position: relative;
+  top: 0;
+  width: 53px;
+  height: 27px;
+  padding: 0;
+  line-height: 28px;
+  text-align: center;
+}
+.mblSwitchTextLeft {
+  left: 0;
+}
+.mblSwitchTextRight {
+  left: 40px;
+}
+/* Square Shape */
+.mblSwSquareShape {
+  width: 94px;
+}
+.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBg {
+  border-radius: 0px;
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+  width: 41px;
+  border-radius: 0px;
+}
+.mblSwSquareShape .mblSwitchText {
+  width: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRight {
+  left: 40px;
+}
+/* Round Shape1 */
+.mblSwRoundShape1 {
+  width: 77px;
+}
+.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwRoundShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 14px;
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 13px;
+}
+.mblSwRoundShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Round Shape2 */
+.mblSwRoundShape2 {
+  width: 94px;
+}
+.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBg {
+  border-radius: 14px;
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 13px;
+}
+.mblSwRoundShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Arc Shape1 */
+.mblSwArcShape1 {
+  width: 77px;
+}
+.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwArcShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 5px/14px;
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Arc Shape2 */
+.mblSwArcShape2 {
+  width: 94px;
+}
+.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBg {
+  border-radius: 5px/14px;
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Default Shape */
+.mblSwDefaultShape {
+  width: 94px;
+}
+.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: -53px;
+}
+.mblSwDefaultShape .mblSwitchBg {
+  border-radius: 0px;
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  left: 53px;
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  left: 53px;
+  width: 41px;
+  border-radius: 0px;
+}
+.mblSwDefaultShape .mblSwitchText {
+  width: 53px;
+}
+.mblSwDefaultShape .mblSwitchTextRight {
+  left: 40px;
+}
+.mblSwitchBgLeft {
+  background-color: #0c86af;
+  background-image: none;
+}
+.mblSwitchBgRight {
+  background-color: #333333;
+  background-image: none;
+  color: #ffffff;
+}
+.mblSwitchKnob {
+  background-color: #606060;
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/holodark/Switch.less b/dojox/mobile/themes/holodark/Switch.less
new file mode 100644
index 0000000..525689c
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Switch.less
@@ -0,0 +1,23 @@
+ at import "variables.less";
+ at import "../common/Switch.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwSquareShape-styles;
+}
+
+.mblSwitchBgLeft {
+  background-color: @holo-switch-on-color;
+  background-image: none;
+}
+.mblSwitchBgRight {
+  background-color: @holo-switch-off-color;
+  background-image: none;
+  color: @holo-color;
+}
+
+.mblSwitchKnob{
+  background-color: @holo-switch-knob-color;
+  background-image: none;
+  
+}
diff --git a/dojox/mobile/themes/holodark/Switch_rtl-compat.css b/dojox/mobile/themes/holodark/Switch_rtl-compat.css
new file mode 100644
index 0000000..5293453
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Switch_rtl-compat.css
@@ -0,0 +1,43 @@
+/* dojox.mobile.Switch Rtl */
+/* Square Shape Rtl */
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
+/* Round Shape1 Rtl */
+.mblSwRoundShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round1-l.gif);
+}
+/* Round Shape2 Rtl */
+.mblSwRoundShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round2-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round2-l.gif);
+}
+/* Arc Shape1 Rtl */
+.mblSwArcShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc1-r.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc1-l.gif);
+}
+/* Switch - Arc Shape2 Rtl */
+.mblSwArcShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc2-r.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc2-l.gif);
+}
+/* Default Shape Rtl */
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
diff --git a/dojox/mobile/themes/holodark/Switch_rtl.css b/dojox/mobile/themes/holodark/Switch_rtl.css
new file mode 100644
index 0000000..5bb0935
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Switch_rtl.css
@@ -0,0 +1,117 @@
+/* dojox.mobile.Switch Rtl */
+/* Switch - common Rtl */
+.mblSwitchRtl {
+  text-align: right;
+}
+.mblListItemRtl .mblSwitch {
+  left: 12px;
+  right: auto;
+}
+.mblSwitchRtl.mblSwitchOn .mblSwitchInner {
+  left: -50px;
+}
+.mblSwitchBgLeftRtl {
+  left: 51px;
+}
+.mblSwitchTextLeftRtl {
+  left: 0px;
+}
+.mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Square Shape Rtl*/
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Round Shape1 Rtl */
+.mblSwitchRtl.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Round Shape2 Rtl */
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Arc Shape1 Rtl */
+.mblSwitchRtl.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Arc Shape2 Rtl */
+.mblSwitchRtl.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Default Shape Rtl */
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwDefaultShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwDefaultShape .mblSwitchTextRightRtl {
+  left: -40px;
+}
diff --git a/dojox/mobile/themes/holodark/TabBar-compat.css b/dojox/mobile/themes/holodark/TabBar-compat.css
new file mode 100644
index 0000000..665577d
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TabBar-compat.css
@@ -0,0 +1,80 @@
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
+/* dojox.mobile.TabBar */
+.dj_ie6 .mblTabBar .mblTabBarButton {
+  display: inline;
+}
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  background-color: rgba(0, 0, 0, 0);
+  background-image: none;
+  border-style: none;
+  line-height: 0.5em;
+}
+.dj_ff3 .mblTabBarTabBar .mblTabBarButtonSelected {
+  -moz-border-radius: 3px;
+}
+/* barType="segmentedControl" | "standardTab" */
+.mblTabBarSegmentedControl,
+.mblTabBarStandardTab {
+  background-image: url(compat/heading-bg.png);
+}
+.mblTabBarSegmentedControl .mblTabBarButton,
+.mblTabBarStandardTab .mblTabBarButton {
+  background-image: url(compat/tab-seg-button-bg.png);
+}
+.mblTabBarSegmentedControl .mblTabBarButtonSelected,
+.mblTabBarStandardTab .mblTabBarButtonSelected {
+  background-image: url(compat/tab-seg-sel-button-bg.png);
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:first-child {
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-bottomleft: 0px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:last-child {
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomright: 0px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButton {
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 4px;
+}
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  background-image: url(compat/tab-slim-bar-bg.png);
+}
+.dj_gecko .mblTabBarSlimTab {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.dj_gecko .mblTabBarSlimTab .mblTabBarButton {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.dj_gecko .mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-image: -moz-linear-gradient(top, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
+}
+/* barType="flatTab" */
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  background-image: url(compat/tab-tall-bar-bg.png);
+}
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-color: #8c8e8c;
+}
+.mblTabBarSegmentedControl,
+.mblTabBarStandardTab {
+  background-image: none;
+}
+.mblTabBarSegmentedControl .mblTabBarButton,
+.mblTabBarStandardTab .mblTabBarButton {
+  background-image: none;
+}
+/*
+.mblTabBarSegmentedControl, .mblTabBarStandardTab {
+  background-image: url(compat/heading-bg.png);
+  .mblTabBarButton {
+    background-image: none;
+  }
+  .mblTabBarButtonSelected {
+    background-image: none;
+  }
+}
+*/
diff --git a/dojox/mobile/themes/holodark/TabBar-compat.less b/dojox/mobile/themes/holodark/TabBar-compat.less
new file mode 100644
index 0000000..f3b6f56
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TabBar-compat.less
@@ -0,0 +1,22 @@
+ at import "variables.less";
+ at import "../common/TabBar-compat.less";
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
+
+.mblTabBarSegmentedControl, .mblTabBarStandardTab {
+    background-image: none;
+}
+
+.mblTabBarSegmentedControl .mblTabBarButton, .mblTabBarStandardTab .mblTabBarButton {
+    background-image: none;
+}
+/*
+.mblTabBarSegmentedControl, .mblTabBarStandardTab {
+  background-image: url(compat/heading-bg.png);
+  .mblTabBarButton {
+    background-image: none;
+  }
+  .mblTabBarButtonSelected {
+    background-image: none;
+  }
+}
+*/
diff --git a/dojox/mobile/themes/holodark/TabBar.css b/dojox/mobile/themes/holodark/TabBar.css
new file mode 100644
index 0000000..e0d77eb
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TabBar.css
@@ -0,0 +1,318 @@
+ at import "../common/domButtons/DomButtonWhiteCross.css";
+/* dojox.mobile.TabBar */
+.mblTabBar {
+  position: relative;
+  margin: 0px;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  padding: 0px 6px;
+  height: 42px;
+  text-align: center;
+  color: white;
+  border-top: 1px solid #cdd5df;
+  border-bottom: 1px solid #2d3642;
+  text-shadow: none;
+  color: #ffffff;
+}
+/* dojox.mobile.TabBarButton */
+.mblTabBarFill .mblTabBarButton {
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
+.mblTabBarButton {
+  overflow: hidden;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  position: relative;
+  list-style-type: none;
+  float: left;
+}
+.mblTabBarButtonIconArea {
+  margin: 0 auto;
+  width: 29px;
+}
+.mblTabBarButtonIconParent1 {
+  display: block;
+}
+.mblTabBarButtonIconParent2 {
+  display: none;
+}
+.mblTabBarButtonSelected .mblTabBarButtonIconParent1 {
+  display: none;
+}
+.mblTabBarButtonSelected .mblTabBarButtonIconParent2 {
+  display: block;
+}
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  height: 48px;
+  border-top: 1px solid #000000;
+  background-color: rgba(0, 0, 0, 0);
+  background-image: none;
+  border-style: none;
+  line-height: 0.5em;
+}
+.mblTabBarTabBar .mblTabBarButton {
+  border-radius: 0px;
+  height: 47px;
+  border-bottom-color: #33b5e5;
+  border-bottom-width: 1px;
+  border-bottom-style: solid;
+}
+.mblTabBarTabBar .mblTabBarButtonIconArea {
+  padding-top: 4px;
+  padding-top: 0px;
+}
+.mblTabBarTabBar .mblTabBarButtonLabel {
+  font-family: "Helvetica Neue", Helvetica;
+  font-size: 11px;
+  display: inline;
+  text-transform: uppercase;
+  color: #ffffff;
+  font-weight: bold;
+}
+.mblTabBarTabBar .mblTabBarButtonSelected {
+  border-radius: 3px;
+  border-radius: 0px;
+  height: 42px;
+  border-bottom-color: #33b5e5;
+  border-bottom-width: 6px;
+  border-bottom-style: solid;
+}
+/* barType="segmentedControl" */
+.mblTabBarSegmentedControl {
+  background-color: rgba(0, 0, 0, 0);
+  background-image: none;
+  border-style: none;
+  line-height: 0.5em;
+}
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButton {
+  width: auto;
+  padding: 0 3px;
+}
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconArea {
+  position: relative;
+}
+.mblTabBarSegmentedControl .mblTabBarButton {
+  margin: 6px 0;
+  width: 100px;
+  height: 29px;
+  border-width: 1px 1px 1px 0px;
+  font-family: Helvetica;
+  font-size: 13px;
+  font-weight: bold;
+  text-align: center;
+  line-height: 29px;
+  border-radius: 0px;
+  height: 28px;
+  border-bottom-color: #33b5e5;
+  border-bottom-width: 1px;
+  border-bottom-style: solid;
+}
+.mblTabBarSegmentedControl .mblTabBarButton:first-child {
+  border-left-width: 1px;
+  border-top-left-radius: 0px;
+  border-bottom-left-radius: 0px;
+}
+.mblTabBarSegmentedControl .mblTabBarButton:last-child {
+  border-top-right-radius: 0px;
+  border-bottom-right-radius: 0px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonSelected {
+  border-radius: 0px;
+  height: 23px;
+  border-bottom-color: #33b5e5;
+  border-bottom-width: 6px;
+  border-bottom-style: solid;
+}
+.mblHeading .mblTabBarSegmentedControl {
+  display: inline;
+  float: left;
+  height: auto;
+  border: none;
+}
+/* barType="standardTab" */
+.mblTabBarStandardTab {
+  background-color: rgba(0, 0, 0, 0);
+  background-image: none;
+  border-style: none;
+}
+.mblTabBarStandardTab .mblTabBarButton {
+  margin-top: 9px;
+  padding: 9px;
+  border: 1px solid #62676d;
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  color: #ffffff;
+  background-color: #333333;
+  /* TODO: to compat */
+
+  background-image: none;
+}
+.mblTabBarStandardTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 3px;
+  left: 0px;
+}
+.mblTabBarStandardTab .mblTabBarButtonLabel {
+  display: inline;
+  text-transform: uppercase;
+  color: #ffffff;
+  font-weight: bold;
+}
+.mblTabBarStandardTab .mblTabBarButtonSelected {
+  color: #ffffff;
+  background-color: #33b5e5;
+  /* TODO: to compat */
+
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#313031), to(#959595), color-stop(0.5, #5a555a), color-stop(0.5, #616161));
+  background-image: linear-gradient(to bottom, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
+}
+.mblTabBarStandardTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  height: 30px;
+  padding: 0px;
+  border: 1px solid #2d3642;
+  background-color: #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.mblTabBarSlimTab .mblTabBarButton {
+  padding: 7px;
+  border-right: 1px solid #4e4e4e;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  color: white;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
+  text-align: center;
+}
+.mblTabBarSlimTab .mblTabBarButton:first-child {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+}
+.mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-color: #404040;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#313031), to(#959595), color-stop(0.5, #5a555a), color-stop(0.5, #616161));
+  background-image: linear-gradient(to bottom, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
+}
+.mblTabBarSlimTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="flatTab" */
+.mblTabBarFlatTab {
+  height: 30px;
+  padding: 0px;
+  border-style: none;
+  background-color: transparent;
+  background-image: none;
+}
+.mblTabBarFlatTab .mblTabBarButton {
+  padding: 7px;
+  background-image: none;
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
+  text-align: center;
+}
+.mblTabBarFlatTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+}
+.mblTabBarFlatTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  height: 64px;
+  border-top: 1px solid #cdd5df;
+  border-bottom: 2px solid #949694;
+  background-color: rgba(0, 0, 0, 0);
+  background-image: none;
+  border-style: none;
+}
+.mblTabBarTallTab .mblTabBarButton {
+  margin-top: 3px;
+  margin-right: 2px;
+  width: 78px;
+  height: 61px;
+  border-width: 0px 1px 0px 1px;
+  border-style: solid;
+  border-color: black #182018 black #393c39;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100c10), color-stop(0.1, #313031));
+  background-image: linear-gradient(to bottom, #181818 0%, #313031 10%, #100c10 100%);
+  font-family: Helvetica;
+  font-size: 13px;
+  color: white;
+  text-align: center;
+  background-color: rgba(0, 0, 0, 0);
+  background-image: none;
+  border-radius: 0px;
+  height: 58px;
+  border-style: none;
+  border-bottom-color: #33b5e5;
+  border-bottom-width: 1px;
+  border-bottom-style: solid;
+}
+.mblTabBarTallTab .mblTabBarButtonIconArea {
+  margin-top: 8px;
+}
+.mblTabBarTallTab .mblTabBarButtonLabel {
+  font-family: "Helvetica Neue", Helvetica;
+  font-size: 11px;
+}
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#a59ea5), to(#848284));
+  background-image: linear-gradient(to bottom, #a59ea5 0%, #848284 100%);
+  background-color: rgba(0, 0, 0, 0);
+  background-image: none;
+  border-radius: 0px;
+  height: 53px;
+  border-style: none;
+  border-bottom-color: #33b5e5;
+  border-bottom-width: 6px;
+  border-bottom-style: solid;
+}
+ at media (max-width: 500px) {
+  .mblTabBarTabBar {
+    /* Tab separator only for width < 500 (because TabBar._largeScreenWidth == 500)*/
+  
+  }
+  .mblTabBarTabBar .mblTabBarButton + .mblTabBarButton:before {
+    content: url('images/vseparator.png');
+    position: absolute;
+    top: 12px;
+    left: 0px;
+  }
+}
+/* when fill is activated, box-sizing is border-box */
+.mblTabBarTabBar.mblTabBarFill .mblTabBarButton {
+  height: 48px;
+}
+.mblTabBarSegmentedControl.mblTabBarFill .mblTabBarButton {
+  height: 29px;
+}
+.mblTabBarTallTab.mblTabBarFill .mblTabBarButton {
+  height: 62px;
+}
diff --git a/dojox/mobile/themes/holodark/TabBar.less b/dojox/mobile/themes/holodark/TabBar.less
new file mode 100644
index 0000000..f7de067
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TabBar.less
@@ -0,0 +1,37 @@
+ at import "variables.less";
+ at import "../common/TabBar.less";
+ at import "../common/domButtons/DomButtonWhiteCross.css";
+
+ at media (max-width:500px) {
+  .mblTabBarTabBar {
+  	/* Tab separator only for width < 500 (because TabBar._largeScreenWidth == 500)*/
+  		.mblTabBarButton+.mblTabBarButton:before{
+  			content:url('images/vseparator.png');
+  			position:absolute;
+  			top: 12px;
+  			left:0px;
+  		}
+  }
+}
+/* when fill is activated, box-sizing is border-box */
+.mblTabBarTabBar {
+	&.mblTabBarFill {
+		.mblTabBarButton {
+			height: 48px;
+		}
+	}
+}
+.mblTabBarSegmentedControl {
+	&.mblTabBarFill {
+		.mblTabBarButton {
+			height: 29px;
+		}
+	}	
+}
+.mblTabBarTallTab {
+	&.mblTabBarFill {
+		.mblTabBarButton {
+			height: 62px;
+		}
+	}
+}
diff --git a/dojox/mobile/themes/holodark/TabBar_rtl-compat.css b/dojox/mobile/themes/holodark/TabBar_rtl-compat.css
new file mode 100644
index 0000000..848279c
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TabBar_rtl-compat.css
@@ -0,0 +1,19 @@
+/* barType="segmentedControl" | "standardTab" Rtl */
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  -moz-border-radius-topright: 5px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-bottomright: 5px;
+  -moz-border-radius-bottomleft: 0px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  -moz-border-radius-topleft: 5px;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomleft: 5px;
+  -moz-border-radius-bottomright: 0px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButtonRtl {
+  -moz-border-radius-topright: 4px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 0px;
+}
diff --git a/dojox/mobile/themes/holodark/TabBar_rtl.css b/dojox/mobile/themes/holodark/TabBar_rtl.css
new file mode 100644
index 0000000..5553209
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TabBar_rtl.css
@@ -0,0 +1,89 @@
+/* dojox.mobile.TabBarButton Rtl */
+.mblTabBarButtonRtl {
+  float: right;
+}
+.mblTabBarButtonIconAreaRtl {
+  margin: 0 auto;
+  width: 29px;
+}
+/* barType="tabBar" Rtl */
+.mblTabBarTabBar .mblTabBarButtonIconAreaRtl {
+  padding-top: 4px;
+}
+/* barType="segmentedControl" Rtl */
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconAreaRtl {
+  position: relative;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl {
+  border-width: 1px 0px 1px 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  border-right-width: 1px !important;
+  border-left-width: 0px;
+  border-top-right-radius: 5px;
+  border-top-left-radius: 0px;
+  border-bottom-right-radius: 5px;
+  border-bottom-left-radius: 0px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  border-top-left-radius: 5px;
+  border-top-right-radius: 0px;
+  border-bottom-left-radius: 5px;
+  border-bottom-right-radius: 0px;
+  border-left-width: 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblHeading .mblTabBarSegmentedControl.mblTabBarRtl {
+  float: right;
+}
+/* barType="standardTab" Rtl */
+.mblTabBarStandardTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 3px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarStandardTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="slimTab" Rtl */
+.mblTabBarSlimTab .mblTabBarButtonRtl {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl:first-child {
+  border-right: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="flatTab" Rtl*/
+.mblTabBarFlatTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarFlatTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab .mblTabBarButtonRtl {
+  margin-left: 2px;
+}
+.mblTabBarTallTab .mblTabBarButtonIconAreaRtl {
+  margin-top: 8px;
+}
diff --git a/dojox/mobile/themes/holodark/TextArea-compat.css b/dojox/mobile/themes/holodark/TextArea-compat.css
new file mode 100644
index 0000000..9ff3c64
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TextArea-compat.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  overflow: auto;
+}
+.dj_ff3 .mblTextArea {
+  -moz-border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/holodark/TextArea.css b/dojox/mobile/themes/holodark/TextArea.css
new file mode 100644
index 0000000..1a315fb
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TextArea.css
@@ -0,0 +1,23 @@
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  padding: 4px 1px;
+  border-width: 1px;
+  border-style: inset;
+  font-family: Helvetica;
+  font-size: 13px;
+  background-image: none;
+  background-color: #333333;
+  border-style: none;
+  border-top-style: solid;
+  border-top-color: rgba(85, 85, 85, 0.9);
+  border-top-width: 1px;
+  border-radius: 2px;
+  color: #ffffff;
+  border-radius: 0;
+  border-top-color: transparent;
+  font-size: 17px;
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 2px;
+}
diff --git a/dojox/mobile/themes/holodark/TextBox-compat.css b/dojox/mobile/themes/holodark/TextBox-compat.css
new file mode 100644
index 0000000..e9542a7
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TextBox-compat.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.TextBox */
+.dj_ff3 .mblTextBox {
+  -moz-border-radius: 2px;
+}
diff --git a/dojox/mobile/themes/holodark/TextBox.css b/dojox/mobile/themes/holodark/TextBox.css
new file mode 100644
index 0000000..03eaf5e
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TextBox.css
@@ -0,0 +1,27 @@
+/* dojox.mobile.TextBox */
+.mblTextBox {
+  height: 22px;
+  border-width: 1px;
+  border-style: inset;
+  font-family: Helvetica;
+  font-size: 13px;
+  background-color: transparent;
+  border-top-color: transparent;
+  border-left-color: transparent;
+  border-right-color: transparent;
+  border-bottom-color: #33b5e5;
+  border-width: 2px;
+  font-size: 17px;
+  border-style: solid;
+  color: #ffffff;
+}
+.mblTextBox:disabled {
+  background-color: transparent;
+  border-top-color: transparent;
+  border-left-color: transparent;
+  border-right-color: transparent;
+  border-bottom-color: #333333;
+  border-width: 1px;
+  font-size: 17px;
+  border-style: solid;
+}
diff --git a/dojox/mobile/themes/holodark/TextBox.less b/dojox/mobile/themes/holodark/TextBox.less
new file mode 100644
index 0000000..368e6c4
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TextBox.less
@@ -0,0 +1,13 @@
+ at import "variables.less";
+ at import "../common/TextBox.less";
+
+.mblTextBox:disabled {
+  background-color: transparent;
+  border-top-color: transparent;
+  border-left-color: transparent;
+  border-right-color: transparent;
+  border-bottom-color: @holo-grey2;
+  border-width: 1px;
+  font-size: 17px;
+  border-style: solid;  
+}
diff --git a/dojox/mobile/themes/holodark/TimePicker.css b/dojox/mobile/themes/holodark/TimePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/holodark/TimePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/holodark/ToggleButton-compat.css b/dojox/mobile/themes/holodark/ToggleButton-compat.css
new file mode 100644
index 0000000..66c3f6f
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ToggleButton-compat.css
@@ -0,0 +1,42 @@
+/* dojox.mobile.ToggleButton */
+.mblToggleButton {
+  background-image: url(compat/button-bg.png);
+}
+.mblToggleButtonSelected {
+  background-image: url(compat/button-sel-bg.png);
+}
+.mblToggleButtonChecked {
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblToggleButton {
+  background-image: none;
+}
+.dj_gecko .mblToggleButtonSelected {
+  background-image: none;
+}
+.dj_gecko .mblToggleButtonChecked {
+  background-image: none;
+}
+.dj_gecko .mblToggleButtonChecked:after {
+  -moz-transform: rotate(45deg) skew(10deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: none;
+}
+.dj_ff3 .mblToggleButton {
+  -moz-border-radius: 2px;
+}
+.dj_ff3 .mblToggleButton.mblToggleButtonChecked::after {
+  -moz-transform: translate(-25px, -6px) rotate(45deg) skew(10deg);
+}
+.dj_ie .mblToggleButtonChecked:after {
+  top: 9px;
+  left: 5px;
+  width: 12px;
+  border: none;
+  background-image: url(compat/togglebutton-chk-mark-bg.png);
+}
diff --git a/dojox/mobile/themes/holodark/ToggleButton.css b/dojox/mobile/themes/holodark/ToggleButton.css
new file mode 100644
index 0000000..043b6c1
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ToggleButton.css
@@ -0,0 +1,54 @@
+/* dojox.mobile.ToggleButton */
+.mblToggleButton {
+  position: relative;
+  padding: 0 10px 0 25px;
+  height: 29px;
+  border-width: 1px 1px 1px 1px;
+  border-style: outset;
+  font-family: Helvetica;
+  line-height: 29px;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  background-image: none;
+  background-color: #333333;
+  border-style: none;
+  border-top-style: solid;
+  border-top-color: rgba(85, 85, 85, 0.9);
+  border-top-width: 1px;
+  border-radius: 2px;
+  font-size: 13px;
+  color: black;
+}
+.mblToggleButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
+}
+.mblToggleButtonSelected {
+  background-image: none;
+  color: white;
+}
+.mblToggleButtonChecked {
+  background-color: transparent;
+  color: white;
+}
+.mblToggleButtonChecked:after {
+  position: absolute;
+  content: "";
+  top: 6px;
+  left: 7px;
+  width: 5px;
+  height: 10px;
+  border-width: 2px;
+  border-style: none solid solid none;
+  -webkit-transform: rotate(45deg) skew(10deg);
+  transform: rotate(45deg) skew(10deg);
+  -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: white;
+}
+.mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: none;
+  color: white;
+}
diff --git a/dojox/mobile/themes/holodark/ToggleButton_rtl.css b/dojox/mobile/themes/holodark/ToggleButton_rtl.css
new file mode 100644
index 0000000..16d136f
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ToggleButton_rtl.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.ToggleButton Rtl */
+.mblToggleButtonRtl {
+  padding: 0 25px 0 10px!important;
+}
+.mblToggleButtonRtl.mblToggleButtonChecked:after {
+  right: 7px;
+}
diff --git a/dojox/mobile/themes/holodark/ToolBarButton-compat.css b/dojox/mobile/themes/holodark/ToolBarButton-compat.css
new file mode 100644
index 0000000..5363133
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ToolBarButton-compat.css
@@ -0,0 +1,63 @@
+/* dojox.mobile.ToolBarButton */
+.dj_gecko .mblToolBarButtonArrow {
+  -moz-transform: scale(0.77, 1.05) rotate(45deg);
+}
+.dj_ff3 .mblToolBarButtonArrow {
+  -moz-border-radius: 1px;
+}
+.dj_ff3 .mblToolBarButtonBody {
+  -moz-border-radius: 0;
+}
+.dj_ff3 .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  -moz-border-radius-topleft: 0;
+  -moz-border-radius-bottomleft: 0;
+}
+.dj_ff3 .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 0;
+}
+.dj_ie .mblToolBarButtonLeftArrow {
+  top: 0;
+  left: -2px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonLeftArrow {
+  background-image: url(compat/arrow-button-head-sel.png);
+}
+.dj_ie .mblToolBarButtonRightArrow {
+  top: 0;
+  right: -3px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-right-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonRightArrow {
+  background-image: url(compat/arrow-button-right-head-sel.png);
+}
+.dj_ie .mblToolBarButtonBody {
+  background-image: url(compat/arrow-button-bg.png);
+  background-position: left bottom;
+}
+.dj_ie .mblToolBarButtonBodySelected {
+  background-image: url(compat/arrow-button-bg-sel.png);
+}
+.dj_ie .mblToolBarButtonBody table {
+  margin: 0;
+}
+.dj_ie .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.dj_ie .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.dj_ie6 .mblToolBarButton .mblToolBarButtonBody {
+  background-position: left top;
+}
diff --git a/dojox/mobile/themes/holodark/ToolBarButton.css b/dojox/mobile/themes/holodark/ToolBarButton.css
new file mode 100644
index 0000000..8450e66
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ToolBarButton.css
@@ -0,0 +1,90 @@
+/* dojox.mobile.ToolBarButton */
+.mblToolBarButton {
+  display: inline-block;
+  position: relative;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  margin: 6px;
+  padding: 0 10px;
+  height: 29px;
+  line-height: 29px;
+  text-align: center;
+  font-family: Helvetica;
+  font-size: 13px;
+  font-weight: bold;
+  vertical-align: middle;
+  text-shadow: none;
+}
+.mblToolBarButtonHasIcon,
+.mblToolBarButtonLightIcon {
+  padding: 0;
+}
+.mblHeading .mblToolBarButton {
+  float: left;
+}
+.mblHeading span.mblToolBarButtonLightIcon {
+  padding: 0;
+}
+.mblToolBarButtonHasLeftArrow {
+  padding-right: 0;
+  padding-left: 10px;
+}
+.mblToolBarButtonHasRightArrow {
+  padding-left: 0;
+  padding-right: 10px;
+}
+.mblToolBarButtonArrow {
+  position: absolute;
+  top: 5px;
+  width: 20px;
+  height: 19px;
+  border-radius: 1px;
+  -webkit-transform: scale(0.7, 1.05) rotate(45deg);
+  transform: scale(0.7, 1.05) rotate(45deg);
+  border: 1px solid #3a4655;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: -1px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: -1px;
+}
+.mblToolBarButtonBody {
+  display: inline-block;
+  position: relative;
+  overflow: hidden;
+  border-radius: 0;
+  border: 1px solid #555555;
+}
+.mblToolBarButton .mblToolBarButtonBody {
+  width: 100%;
+}
+.mblToolBarButtonBody table {
+  margin: 0 auto;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-left-width: 0;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-right-width: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.mblToolBarButtonText .mblToolBarButtonIcon {
+  padding-left: 10px;
+}
+.mblToolBarButtonText .mblToolBarButtonLabel {
+  padding-right: 10px;
+  height: 29px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonIcon {
+  padding-left: 4px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonLabel {
+  padding-right: 4px;
+}
+.mblToolBarButtonIcon > div {
+  height: 29px;
+}
diff --git a/dojox/mobile/themes/holodark/ToolBarButton_rtl.css b/dojox/mobile/themes/holodark/ToolBarButton_rtl.css
new file mode 100644
index 0000000..9abae68
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ToolBarButton_rtl.css
@@ -0,0 +1,18 @@
+/* dojox.mobile.ToolBarButton Rtl */
+.mblHeading .mblToolBarButtonRtl {
+  float: right;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonIcon {
+  padding-right: 10px;
+  padding-left: 0px;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonLabel {
+  padding-left: 10px;
+  padding-right: 0px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: -1px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: -2px;
+}
diff --git a/dojox/mobile/themes/holodark/Tooltip-compat.css b/dojox/mobile/themes/holodark/Tooltip-compat.css
new file mode 100644
index 0000000..9415367
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Tooltip-compat.css
@@ -0,0 +1,40 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+  background-image: none;
+}
+.dj_ff3 .mblTooltip {
+  -moz-border-radius: 3px;
+}
+.dj_ie9 .mblTooltip .mblHeading {
+  width: auto;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipArrow {
+  right: 0;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipArrow {
+  bottom: 0;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipInnerArrow {
+  right: -1px;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipInnerArrow {
+  bottom: -1px;
+}
+.dj_ie6 .mblTooltip .mblHeading,
+.dj_ie7 .mblTooltip .mblHeading {
+  padding: 0 9px 12px;
+  border-top: 1px solid #8c8a8c;
+  border-bottom: 1px solid #8c8a8c;
+  width: auto;
+  height: auto;
+  overflow: visible;
+  line-height: normal;
+}
+.dj_ie6 .mblTooltip .mblHeading .mblToolBarButton,
+.dj_ie7 .mblTooltip .mblHeading .mblToolBarButton {
+  margin: auto 6px;
+}
diff --git a/dojox/mobile/themes/holodark/Tooltip.css b/dojox/mobile/themes/holodark/Tooltip.css
new file mode 100644
index 0000000..2f82d6c
--- /dev/null
+++ b/dojox/mobile/themes/holodark/Tooltip.css
@@ -0,0 +1,152 @@
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+  position: absolute;
+  z-index: 2000;
+  display: block;
+  margin: 0;
+  padding: 5px;
+  border-width: 1px;
+  border-style: solid;
+  opacity: .97;
+  border-color: #adaaad;
+  border-radius: 3px;
+  background-color: #8c8a8c;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#9c9e9c), to(#848284));
+  background-image: linear-gradient(to bottom, #9c9e9c 0%, #848284 100%);
+}
+.mblTooltipBubble {
+  overflow: visible;
+  padding: 3px;
+  background-color: #306ea1;
+  background-image: none;
+  color: white;
+}
+.mblTooltipBubble.mblTooltipAbove .mblTooltipInnerArrow {
+  border-bottom-color: #306ea1;
+}
+.mblTooltipBubble.mblTooltipBelow .mblTooltipInnerArrow {
+  border-top-color: #306ea1;
+}
+.mblTooltipBubble.mblTooltipAfter .mblTooltipInnerArrow {
+  border-left-color: #306ea1;
+}
+.mblTooltipBubble.mblTooltipBefore .mblTooltipInnerArrow {
+  border-right-color: #306ea1;
+}
+.mblTooltip.mblTooltipAfter {
+  margin-left: -11px;
+}
+.mblTooltip.mblTooltipBefore {
+  margin-left: 11px;
+}
+.mblTooltip.mblTooltipAbove {
+  margin-top: 11px;
+}
+.mblTooltip.mblTooltipBelow {
+  margin-top: -11px;
+}
+.mblTooltipAnchor {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  background-color: transparent;
+  line-height: 0;
+  font-size: 0;
+}
+.mblTooltipBefore .mblTooltipAnchor {
+  left: -1px;
+}
+.mblTooltipAfter .mblTooltipAnchor {
+  right: -1px;
+}
+.mblTooltipAbove .mblTooltipAnchor {
+  top: -1px;
+}
+.mblTooltipBelow .mblTooltipAnchor {
+  bottom: -1px;
+}
+.mblTooltipArrow {
+  position: absolute;
+  width: 0;
+  height: 0;
+  line-height: 0;
+  border: 11px solid transparent;
+}
+.mblTooltipBefore .mblTooltipArrow {
+  left: auto;
+  right: 1px;
+  top: 0;
+  bottom: auto;
+  border-left-width: 0;
+  border-right-color: #adaaad;
+}
+.mblTooltipAfter .mblTooltipArrow {
+  left: 1px;
+  right: auto;
+  top: 0;
+  bottom: auto;
+  border-right-width: 0;
+  border-left-color: #adaaad;
+}
+.mblTooltipAbove .mblTooltipArrow {
+  top: auto;
+  bottom: 1px;
+  left: auto;
+  right: auto;
+  border-top-width: 0;
+  border-bottom-color: #adaaad;
+}
+.mblTooltipBelow .mblTooltipArrow {
+  top: 1px;
+  bottom: auto;
+  left: auto;
+  right: auto;
+  border-bottom-width: 0;
+  border-top-color: #adaaad;
+}
+.mblTooltipInnerArrow {
+  position: absolute;
+  width: 0;
+  height: 0;
+  line-height: 0;
+  border: 10px solid transparent;
+}
+.mblTooltipBefore .mblTooltipInnerArrow {
+  right: 0;
+  top: 0;
+  border-left-width: 0;
+  border-right-color: #848284;
+}
+.mblTooltipAfter .mblTooltipInnerArrow {
+  left: 0;
+  top: 0;
+  border-right-width: 0;
+  border-left-color: #848284;
+}
+.mblTooltipAbove .mblTooltipInnerArrow {
+  bottom: 0;
+  left: 0;
+  border-top-width: 0;
+  border-bottom-color: #9c9e9c;
+}
+.mblTooltipBelow .mblTooltipInnerArrow {
+  top: 0;
+  left: 0;
+  border-bottom-width: 0;
+  border-top-color: #848284;
+}
+.mblTooltipHidden,
+.mblTooltipHidden * {
+  visibility: hidden !important;
+}
+.mblTooltipHidden {
+  top: -99999px !important;
+  left: -99999px !important;
+}
+.mblTooltip .mblHeading {
+  padding-bottom: 3px;
+  border-top: 1px solid transparent;
+  border-bottom: 1px solid transparent;
+  background-color: transparent;
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/holodark/ValuePicker-compat.css b/dojox/mobile/themes/holodark/ValuePicker-compat.css
new file mode 100644
index 0000000..16cd1ea
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ValuePicker-compat.css
@@ -0,0 +1,22 @@
+/* dojox.mobile.ValuePicker */
+.mblValuePickerSlotButton {
+  background-image: url(compat/valuepicker-button-bg.png);
+}
+.mblValuePickerSlotButtonSelected {
+  background-color: #33b5e5;
+}
+.mblValuePickerSlotInputArea {
+  background-color: #f7f7f7;
+}
+.dj_gecko .mblValuePickerSlotButton {
+  background-image: none;
+}
+.dj_gecko .mblValuePickerSlotButtonSelected {
+  background-image: none;
+}
+.dj_gecko .mblValuePickerSlotInputArea {
+  background-image: none;
+}
+.mblValuePickerSlotInputArea {
+  background-color: transparent;
+}
diff --git a/dojox/mobile/themes/holodark/ValuePicker-compat.less b/dojox/mobile/themes/holodark/ValuePicker-compat.less
new file mode 100644
index 0000000..04256ba
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ValuePicker-compat.less
@@ -0,0 +1,6 @@
+ at import "variables.less";
+ at import "../common/ValuePicker-compat.less";
+
+.mblValuePickerSlotInputArea {
+  background-color: transparent;
+}
diff --git a/dojox/mobile/themes/holodark/ValuePicker.css b/dojox/mobile/themes/holodark/ValuePicker.css
new file mode 100644
index 0000000..09d3529
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ValuePicker.css
@@ -0,0 +1,60 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+/* dojox.mobile.ValuePicker */
+.mblValuePicker {
+  height: 126px;
+}
+/* dojox.mobile.ValuePickerSlot */
+.mblValuePicker > .mblValuePickerSlot {
+  float: left;
+  margin: 0 5px;
+}
+.mblValuePickerSlotButton {
+  position: relative;
+  height: 38px;
+  background-image: none;
+}
+.mblValuePickerSlotPlusButton {
+  border-top-left-radius: 0px;
+  border-top-right-radius: 0px;
+}
+.mblValuePickerSlotMinusButton {
+  border-bottom-left-radius: 0px;
+  border-bottom-right-radius: 0px;
+}
+.mblValuePickerSlotButtonSelected {
+  background-image: none;
+}
+.mblValuePickerSlotIcon {
+  top: 5px;
+  margin: 0 auto;
+}
+.mblValuePickerSlotInputArea {
+  position: relative;
+  height: 48px;
+  border-top: 1px solid #7b797b;
+  border-bottom: 1px solid #c6c3c6;
+  background-image: none;
+}
+.mblValuePickerSlotInput {
+  display: block;
+  width: 90%;
+  height: 90%;
+  margin: 5% auto;
+  padding: 0;
+  text-align: center;
+  border-style: none;
+  background-color: transparent;
+  font-size: 28px;
+  color: #ffffff;
+}
+/* dojox.mobile.ValuePickerTimePicker */
+.mblValuePickerTimePicker > .mblToolBarButton {
+  top: 45px;
+}
+.mblValuePickerSlotInputArea {
+  border-top: 2px solid #33b5e5;
+  border-bottom: 2px solid #33b5e5;
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/holodark/ValuePicker.less b/dojox/mobile/themes/holodark/ValuePicker.less
new file mode 100644
index 0000000..1b760f9
--- /dev/null
+++ b/dojox/mobile/themes/holodark/ValuePicker.less
@@ -0,0 +1,11 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+
+ at import "variables.less";
+ at import "../common/ValuePicker.less";
+
+.mblValuePickerSlotInputArea {
+  border-top: 2px solid @holo-color1;
+  border-bottom: 2px solid @holo-color1;
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/holodark/View.css b/dojox/mobile/themes/holodark/View.css
new file mode 100644
index 0000000..fe86a8c
--- /dev/null
+++ b/dojox/mobile/themes/holodark/View.css
@@ -0,0 +1,24 @@
+ at import url("../common/transitions/slide.css");
+
+ at import url("../common/transitions/flip.css");
+
+ at import url("../common/transitions/fade.css");
+/* dojox.mobile.View */
+.mblView {
+  position: relative;
+  top: 0px;
+  left: 0px;
+  width: 100%;
+  color: white;
+}
+.mblView.mblIn {
+  position: absolute;
+}
+.mblFixedHeaderBar {
+  z-index: 1;
+}
+.mblFixedBottomBar {
+  position: absolute !important;
+  width: 100%;
+  z-index: 1;
+}
diff --git a/dojox/mobile/themes/holodark/View.less b/dojox/mobile/themes/holodark/View.less
new file mode 100644
index 0000000..910651f
--- /dev/null
+++ b/dojox/mobile/themes/holodark/View.less
@@ -0,0 +1,6 @@
+ at import url("../common/transitions/slide.css");
+ at import url("../common/transitions/flip.css");
+ at import url("../common/transitions/fade.css");
+
+ at import "variables.less";
+ at import "../common/View.less";
diff --git a/dojox/mobile/themes/holodark/android-compat.css b/dojox/mobile/themes/holodark/android-compat.css
new file mode 100644
index 0000000..7fcf52b
--- /dev/null
+++ b/dojox/mobile/themes/holodark/android-compat.css
@@ -0,0 +1,23 @@
+ at import url("base-compat.css");
+
+/* common styles */
+ at import url("../common/domButtons-compat.css");
+
+/* widget styles */
+ at import url("Accordion-compat.css");
+ at import url("Button-compat.css");
+ at import url("CheckBox-compat.css");
+ at import url("ComboBox-compat.css");
+ at import url("IconContainer-compat.css");
+ at import url("IconMenu-compat.css");
+ at import url("Opener-compat.css");
+ at import url("PageIndicator-compat.css");
+ at import url("RadioButton-compat.css");
+ at import url("SimpleDialog-compat.css");
+ at import url("Slider-compat.css");
+ at import url("SpinWheel-compat.css");
+ at import url("TabBar-compat.css");
+ at import url("TextArea-compat.css");
+ at import url("TextBox-compat.css");
+ at import url("ToggleButton-compat.css");
+ at import url("ValuePicker-compat.css");
diff --git a/dojox/mobile/themes/holodark/android_rtl-compat.css b/dojox/mobile/themes/holodark/android_rtl-compat.css
new file mode 100644
index 0000000..0143aa0
--- /dev/null
+++ b/dojox/mobile/themes/holodark/android_rtl-compat.css
@@ -0,0 +1,7 @@
+ at import url("base_rtl-compat.css");
+
+ at import url("IconMenu_rtl-compat.css");
+
+ at import url("SpinWheel_rtl-compat.css");
+
+ at import url("TabBar_rtl-compat.css");
diff --git a/dojox/mobile/themes/holodark/base-compat.css b/dojox/mobile/themes/holodark/base-compat.css
new file mode 100644
index 0000000..6689f7c
--- /dev/null
+++ b/dojox/mobile/themes/holodark/base-compat.css
@@ -0,0 +1,8 @@
+ at import url("common-compat.css");
+ at import url("Heading-compat.css");
+ at import url("ToolBarButton-compat.css");
+ at import url("RoundRect-compat.css");
+ at import url("RoundRectList-compat.css");
+ at import url("ListItem-compat.css");
+ at import url("Switch-compat.css");
+ at import url("ProgressIndicator-compat.css");
diff --git a/dojox/mobile/themes/holodark/base.css b/dojox/mobile/themes/holodark/base.css
new file mode 100644
index 0000000..2409467
--- /dev/null
+++ b/dojox/mobile/themes/holodark/base.css
@@ -0,0 +1,12 @@
+ at import url("common.css");
+ at import url("Heading.css");
+ at import url("View.css");
+ at import url("ToolBarButton.css");
+ at import url("RoundRect.css");
+ at import url("EdgeToEdgeCategory.css");
+ at import url("RoundRectCategory.css");
+ at import url("RoundRectList.css");
+ at import url("EdgeToEdgeList.css");
+ at import url("ListItem.css");
+ at import url("Switch.css");
+ at import url("ProgressIndicator.css");
diff --git a/dojox/mobile/themes/holodark/base_rtl-compat.css b/dojox/mobile/themes/holodark/base_rtl-compat.css
new file mode 100644
index 0000000..71390e0
--- /dev/null
+++ b/dojox/mobile/themes/holodark/base_rtl-compat.css
@@ -0,0 +1,3 @@
+ at import url("ListItem_rtl-compat.css");
+
+ at import url("Switch_rtl-compat.css");
diff --git a/dojox/mobile/themes/holodark/base_rtl.css b/dojox/mobile/themes/holodark/base_rtl.css
new file mode 100644
index 0000000..16f6b6c
--- /dev/null
+++ b/dojox/mobile/themes/holodark/base_rtl.css
@@ -0,0 +1,7 @@
+ at import url("ToolBarButton_rtl.css");
+
+ at import url("RoundRectCategory_rtl.css");
+
+ at import url("ListItem_rtl.css");
+
+ at import url("Switch_rtl.css");
diff --git a/dojox/mobile/themes/holodark/common-compat.css b/dojox/mobile/themes/holodark/common-compat.css
new file mode 100644
index 0000000..bec0d06
--- /dev/null
+++ b/dojox/mobile/themes/holodark/common-compat.css
@@ -0,0 +1,18 @@
+.dj_gecko .mblColorBlue {
+  background-image: none;
+}
+.dj_gecko .mblColorBlue45 {
+  background-image: none;
+}
+.dj_gecko .mblColorDefault {
+  background-image: none;
+}
+.dj_gecko .mblColorDefault45 {
+  background-image: #333333;
+}
+.dj_gecko .mblColorDefaultSel {
+  background-image: none;
+}
+.dj_gecko .mblColorDefaultSel45 {
+  background-image: #33b5e5;
+}
diff --git a/dojox/mobile/themes/holodark/common.css b/dojox/mobile/themes/holodark/common.css
new file mode 100644
index 0000000..c2d2152
--- /dev/null
+++ b/dojox/mobile/themes/holodark/common.css
@@ -0,0 +1,52 @@
+html.mobile,
+.mobile body {
+  width: 100%;
+  margin: 0;
+  padding: 0;
+}
+.mobile body {
+  overflow-x: hidden;
+  -webkit-text-size-adjust: none;
+  font-family: Helvetica;
+  font-size: 17px;
+  color: #ffffff;
+}
+.mblBackground {
+  background-color: #000000;
+}
+/* Button Colors */
+.mblColorBlue {
+  color: #ffffff;
+  background-color: #366edf;
+  background-image: none;
+}
+.mblColorBlue45 {
+  background-image: none;
+}
+/* Default Button Colors */
+.mblColorDefault {
+  color: #ffffff;
+  background-color: #333333;
+  background-image: none;
+}
+.mblColorDefault45 {
+  background-color: #333333;
+}
+.mblColorDefaultSel {
+  color: #ffffff;
+  background-color: #33b5e5;
+  background-image: none;
+}
+.mblColorDefaultSel45 {
+  background-color: #33b5e5;
+}
+.mblSpriteIcon {
+  position: absolute;
+}
+.mblSpriteIconParent {
+  position: relative;
+  font-size: 1px;
+}
+.mblImageIcon {
+  vertical-align: top;
+}
diff --git a/dojox/mobile/themes/holodark/compat/arrow-button-bg-sel.png b/dojox/mobile/themes/holodark/compat/arrow-button-bg-sel.png
new file mode 100644
index 0000000..5b85b72
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/arrow-button-bg-sel.png differ
diff --git a/dojox/mobile/themes/holodark/compat/arrow-button-bg.png b/dojox/mobile/themes/holodark/compat/arrow-button-bg.png
new file mode 100644
index 0000000..7871ed1
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/arrow-button-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/arrow-button-head-sel.png b/dojox/mobile/themes/holodark/compat/arrow-button-head-sel.png
new file mode 100644
index 0000000..f10e271
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/arrow-button-head-sel.png differ
diff --git a/dojox/mobile/themes/holodark/compat/arrow-button-head.png b/dojox/mobile/themes/holodark/compat/arrow-button-head.png
new file mode 100644
index 0000000..ac78b9e
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/arrow-button-head.png differ
diff --git a/dojox/mobile/themes/holodark/compat/arrow-button-right-head-sel.png b/dojox/mobile/themes/holodark/compat/arrow-button-right-head-sel.png
new file mode 100644
index 0000000..068c601
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/arrow-button-right-head-sel.png differ
diff --git a/dojox/mobile/themes/holodark/compat/arrow-button-right-head.png b/dojox/mobile/themes/holodark/compat/arrow-button-right-head.png
new file mode 100644
index 0000000..cc92700
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/arrow-button-right-head.png differ
diff --git a/dojox/mobile/themes/holodark/compat/blue-button-bg.png b/dojox/mobile/themes/holodark/compat/blue-button-bg.png
new file mode 100644
index 0000000..3bd558b
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/blue-button-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/blue-button-sel-bg.png b/dojox/mobile/themes/holodark/compat/blue-button-sel-bg.png
new file mode 100644
index 0000000..d371d89
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/blue-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/button-arrow-head-bg.gif b/dojox/mobile/themes/holodark/compat/button-arrow-head-bg.gif
new file mode 100644
index 0000000..77b6e9e
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/button-arrow-head-bg.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/button-bg.png b/dojox/mobile/themes/holodark/compat/button-bg.png
new file mode 100644
index 0000000..0d378fa
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/button-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/button-chk-bg.png b/dojox/mobile/themes/holodark/compat/button-chk-bg.png
new file mode 100644
index 0000000..4bfad06
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/button-chk-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/button-sel-bg.png b/dojox/mobile/themes/holodark/compat/button-sel-bg.png
new file mode 100644
index 0000000..d371d89
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/button-sel-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/button-unsel-bg.png b/dojox/mobile/themes/holodark/compat/button-unsel-bg.png
new file mode 100644
index 0000000..d371d89
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/button-unsel-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/gray-arrow.png b/dojox/mobile/themes/holodark/compat/gray-arrow.png
new file mode 100644
index 0000000..c93d17f
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/gray-arrow.png differ
diff --git a/dojox/mobile/themes/holodark/compat/heading-bg.png b/dojox/mobile/themes/holodark/compat/heading-bg.png
new file mode 100644
index 0000000..8c3999b
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/heading-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/icon-content-heading-bg.png b/dojox/mobile/themes/holodark/compat/icon-content-heading-bg.png
new file mode 100644
index 0000000..3daa1a8
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/icon-content-heading-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/red-button-bg.png b/dojox/mobile/themes/holodark/compat/red-button-bg.png
new file mode 100644
index 0000000..799870f
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/red-button-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/red-button-sel-bg.png b/dojox/mobile/themes/holodark/compat/red-button-sel-bg.png
new file mode 100644
index 0000000..d371d89
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/red-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/slider-h-bar-bg.png b/dojox/mobile/themes/holodark/compat/slider-h-bar-bg.png
new file mode 100644
index 0000000..970c7ff
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/slider-h-bar-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/slider-h-bg.png b/dojox/mobile/themes/holodark/compat/slider-h-bg.png
new file mode 100644
index 0000000..0a08c57
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/slider-h-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/slider-handle-bg.png b/dojox/mobile/themes/holodark/compat/slider-handle-bg.png
new file mode 100644
index 0000000..1988f04
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/slider-handle-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-arc1-k.gif b/dojox/mobile/themes/holodark/compat/switch-arc1-k.gif
new file mode 100644
index 0000000..b706766
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-arc1-k.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-arc1-l.gif b/dojox/mobile/themes/holodark/compat/switch-arc1-l.gif
new file mode 100644
index 0000000..873b9a7
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-arc1-l.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-arc1-r.gif b/dojox/mobile/themes/holodark/compat/switch-arc1-r.gif
new file mode 100644
index 0000000..2e70891
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-arc1-r.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-arc2-k.gif b/dojox/mobile/themes/holodark/compat/switch-arc2-k.gif
new file mode 100644
index 0000000..7c74289
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-arc2-k.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-arc2-l.gif b/dojox/mobile/themes/holodark/compat/switch-arc2-l.gif
new file mode 100644
index 0000000..b9e9ea6
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-arc2-l.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-arc2-r.gif b/dojox/mobile/themes/holodark/compat/switch-arc2-r.gif
new file mode 100644
index 0000000..d92e181
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-arc2-r.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-round1-k.gif b/dojox/mobile/themes/holodark/compat/switch-round1-k.gif
new file mode 100644
index 0000000..1bc8a14
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-round1-k.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-round1-l.gif b/dojox/mobile/themes/holodark/compat/switch-round1-l.gif
new file mode 100644
index 0000000..f015cc2
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-round1-l.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-round1-r.gif b/dojox/mobile/themes/holodark/compat/switch-round1-r.gif
new file mode 100644
index 0000000..f62342a
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-round1-r.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-round2-k.gif b/dojox/mobile/themes/holodark/compat/switch-round2-k.gif
new file mode 100644
index 0000000..7885243
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-round2-k.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-round2-l.gif b/dojox/mobile/themes/holodark/compat/switch-round2-l.gif
new file mode 100644
index 0000000..0417737
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-round2-l.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-round2-r.gif b/dojox/mobile/themes/holodark/compat/switch-round2-r.gif
new file mode 100644
index 0000000..2cf1260
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-round2-r.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-square-k.gif b/dojox/mobile/themes/holodark/compat/switch-square-k.gif
new file mode 100644
index 0000000..cdab63e
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-square-k.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-square-l.gif b/dojox/mobile/themes/holodark/compat/switch-square-l.gif
new file mode 100644
index 0000000..e32a3dd
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-square-l.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/switch-square-r.gif b/dojox/mobile/themes/holodark/compat/switch-square-r.gif
new file mode 100644
index 0000000..0c67709
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/switch-square-r.gif differ
diff --git a/dojox/mobile/themes/holodark/compat/tab-button-bg.png b/dojox/mobile/themes/holodark/compat/tab-button-bg.png
new file mode 100644
index 0000000..548ef73
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/tab-button-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/tab-orange-button-bg.png b/dojox/mobile/themes/holodark/compat/tab-orange-button-bg.png
new file mode 100644
index 0000000..56f555b
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/tab-orange-button-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/tab-seg-button-bg.png b/dojox/mobile/themes/holodark/compat/tab-seg-button-bg.png
new file mode 100644
index 0000000..7871ed1
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/tab-seg-button-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/tab-seg-sel-button-bg.png b/dojox/mobile/themes/holodark/compat/tab-seg-sel-button-bg.png
new file mode 100644
index 0000000..7afa879
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/tab-seg-sel-button-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/tab-sel-button-bg.png b/dojox/mobile/themes/holodark/compat/tab-sel-button-bg.png
new file mode 100644
index 0000000..c454088
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/tab-sel-button-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/tab-slim-bar-bg.png b/dojox/mobile/themes/holodark/compat/tab-slim-bar-bg.png
new file mode 100644
index 0000000..f982afb
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/tab-slim-bar-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/tab-tall-bar-bg.png b/dojox/mobile/themes/holodark/compat/tab-tall-bar-bg.png
new file mode 100644
index 0000000..50a2371
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/tab-tall-bar-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/togglebutton-chk-bg.png b/dojox/mobile/themes/holodark/compat/togglebutton-chk-bg.png
new file mode 100644
index 0000000..4bfad06
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/togglebutton-chk-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/togglebutton-chk-mark-bg.png b/dojox/mobile/themes/holodark/compat/togglebutton-chk-mark-bg.png
new file mode 100644
index 0000000..2262424
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/togglebutton-chk-mark-bg.png differ
diff --git a/dojox/mobile/themes/holodark/compat/valuepicker-button-bg.png b/dojox/mobile/themes/holodark/compat/valuepicker-button-bg.png
new file mode 100644
index 0000000..965db4b
Binary files /dev/null and b/dojox/mobile/themes/holodark/compat/valuepicker-button-bg.png differ
diff --git a/dojox/mobile/themes/holodark/dijit/Calendar-compat.css b/dojox/mobile/themes/holodark/dijit/Calendar-compat.css
new file mode 100644
index 0000000..8423e34
--- /dev/null
+++ b/dojox/mobile/themes/holodark/dijit/Calendar-compat.css
@@ -0,0 +1,31 @@
+/* dijit.Calendar */
+.dijitCalendar thead {
+  background-repeat: repeat-x;
+  background-color: #333333;
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+  color: #33b5e5;
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+}
+.dijitCalendarYearLabel {
+  background-repeat: repeat-x;
+  background-color: #333333;
+}
+.dj_gecko .dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  -moz-box-shadow: 0 0 0 transparent;
+}
+.dj_gecko .dijitCalendar thead {
+  background-color: #333333;
+}
+.dj_gecko .dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  color: #33b5e5;
+}
+.dj_gecko .dijitCalendarYearLabel {
+  background-color: #333333;
+}
+.dj_ff3 .dijitCalendar {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/holodark/dijit/Calendar-compat.less b/dojox/mobile/themes/holodark/dijit/Calendar-compat.less
new file mode 100644
index 0000000..88cd6f0
--- /dev/null
+++ b/dojox/mobile/themes/holodark/dijit/Calendar-compat.less
@@ -0,0 +1,2 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar-compat.less";
diff --git a/dojox/mobile/themes/holodark/dijit/Calendar.css b/dojox/mobile/themes/holodark/dijit/Calendar.css
new file mode 100644
index 0000000..c3ff454
--- /dev/null
+++ b/dojox/mobile/themes/holodark/dijit/Calendar.css
@@ -0,0 +1,113 @@
+/* if you link this style sheet, dijit/themes/dijit.css must be imported. */
+/* dijit.Calendar */
+.dijitCalendar {
+  padding: 0;
+  width: 320px;
+  border-radius: 0;
+  text-align: center;
+  border: none 0 transparent;
+  background-color: white;
+}
+.dijitCalendar thead {
+  border-color: inherit;
+  vertical-align: middle;
+  background-color: #333333;
+}
+.dijitCalendarMonthLabel {
+  padding: 0 4px;
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0 1px 0px;
+  color: white;
+  font-size: 16px;
+}
+.dijitCalendarMonthMenu .dijitCalendarMonthLabel {
+  color: black;
+}
+.dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  padding: 0 3px 0 2px;
+  border: none;
+  background-color: transparent;
+  background-image: none;
+  -webkit-box-shadow: 0 0 0 transparent;
+  box-shadow: 0 0 0 transparent;
+}
+.dijitArrowButtonInner {
+  display: none;
+}
+.dijitCalendarMonthContainer th {
+  border-right: 1px solid transparent;
+}
+.dijitCalendarIncrementControl {
+  width: 0;
+  height: 0;
+  border: 6px solid transparent !important;
+}
+.dijitCalendarDecrease {
+  border-left-width: 0 !important;
+  border-right: 6px solid white !important;
+}
+.dijitCalendarIncrease {
+  border-right-width: 0 !important;
+  border-left: 6px solid white !important;
+}
+.dijitA11ySideArrow {
+  display: none;
+}
+.dijitCalendarDayLabelTemplate {
+  border-right: 1px solid transparent;
+  text-align: center;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  background-color: #292c31;
+  font-size: 12px;
+  color: white;
+}
+.dijitCalendarDateTemplate {
+  border-bottom: 1px solid lightGrey;
+  font-family: Helvetica;
+  font-size: 22px;
+  font-weight: normal;
+  text-align: center;
+  border-right: 1px solid lightGrey;
+  background-color: white;
+  color: black;
+}
+.dijitCalendarDateTemplate:last-child {
+  border-right: none;
+}
+.dijitCalendarDateTemplate .dijitCalendarDateLabel {
+  padding: 3px 5px 3px 4px;
+  display: block;
+  text-decoration: none;
+  border: none;
+}
+.dijitCalendarPreviousMonth .dijitCalendarDateLabel,
+.dijitCalendarNextMonth .dijitCalendarDateLabel {
+  color: lightGrey;
+}
+.dijitCalendarHoveredDate .dijitCalendarDateLabel {
+  color: #33b5e5;
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  color: #33b5e5;
+}
+.dijitCalendarYearLabel {
+  margin: 0;
+  padding: 0;
+  background-color: #333333;
+}
+.dijitCalendarSelectedYear {
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  color: white;
+  font-size: 16px;
+}
+.dijitCalendarNextYear,
+.dijitCalendarPreviousYear {
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  padding: 1px 6px 3px 6px;
+  color: white;
+  font-size: 12px;
+}
+.mblIconItemPane .dijitCalendarDayLabel {
+  color: white;
+}
diff --git a/dojox/mobile/themes/holodark/dijit/Calendar.less b/dojox/mobile/themes/holodark/dijit/Calendar.less
new file mode 100644
index 0000000..2abfc07
--- /dev/null
+++ b/dojox/mobile/themes/holodark/dijit/Calendar.less
@@ -0,0 +1,9 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar.less";
+
+// Fix for ticket #16920
+.mblIconItemPane {
+	.dijitCalendarDayLabel {
+		color: white;
+	}
+}
diff --git a/dojox/mobile/themes/holodark/dijit/compat/calendar-datelabel-act-bg.png b/dojox/mobile/themes/holodark/dijit/compat/calendar-datelabel-act-bg.png
new file mode 100644
index 0000000..688b46c
Binary files /dev/null and b/dojox/mobile/themes/holodark/dijit/compat/calendar-datelabel-act-bg.png differ
diff --git a/dojox/mobile/themes/holodark/dijit/compat/calendar-datelabel-sel-bg.png b/dojox/mobile/themes/holodark/dijit/compat/calendar-datelabel-sel-bg.png
new file mode 100644
index 0000000..bd89c1d
Binary files /dev/null and b/dojox/mobile/themes/holodark/dijit/compat/calendar-datelabel-sel-bg.png differ
diff --git a/dojox/mobile/themes/holodark/dijit/compat/calendar-month-bg.png b/dojox/mobile/themes/holodark/dijit/compat/calendar-month-bg.png
new file mode 100644
index 0000000..cfc5a64
Binary files /dev/null and b/dojox/mobile/themes/holodark/dijit/compat/calendar-month-bg.png differ
diff --git a/dojox/mobile/themes/holodark/dijit/compat/calendar-year-bg.png b/dojox/mobile/themes/holodark/dijit/compat/calendar-year-bg.png
new file mode 100644
index 0000000..3e27901
Binary files /dev/null and b/dojox/mobile/themes/holodark/dijit/compat/calendar-year-bg.png differ
diff --git a/dojox/mobile/themes/holodark/holodark.css b/dojox/mobile/themes/holodark/holodark.css
new file mode 100644
index 0000000..90c19b0
--- /dev/null
+++ b/dojox/mobile/themes/holodark/holodark.css
@@ -0,0 +1,31 @@
+ at import url("base.css");
+
+/* common styles */
+ at import url("../common/domButtons.css");
+ at import url("../common/transitions.css");
+
+
+/* widget styles */
+ at import url("Accordion.css");
+ at import url("Button.css");
+ at import url("Carousel.css");
+ at import url("CheckBox.css");
+ at import url("ComboBox.css");
+ at import url("FixedSplitter.css");
+ at import url("GridLayout.css");
+ at import url("IconContainer.css");
+ at import url("IconMenu.css");
+ at import url("Opener.css");
+ at import url("PageIndicator.css");
+ at import url("ProgressBar.css");
+ at import url("RadioButton.css");
+ at import url("ScrollablePane.css");
+ at import url("SimpleDialog.css");
+ at import url("Slider.css");
+ at import url("SpinWheel.css");
+ at import url("TabBar.css");
+ at import url("TextArea.css");
+ at import url("SearchBox.css");
+ at import url("ToggleButton.css");
+ at import url("ValuePicker.css");
+ at import url("FormLayout.css");
diff --git a/dojox/mobile/themes/holodark/holodark_rtl.css b/dojox/mobile/themes/holodark/holodark_rtl.css
new file mode 100644
index 0000000..f61e915
--- /dev/null
+++ b/dojox/mobile/themes/holodark/holodark_rtl.css
@@ -0,0 +1,15 @@
+ at import url("base_rtl.css");
+
+ at import url("Carousel_rtl.css");
+
+ at import url("ComboBox_rtl.css");
+
+ at import url("IconContainer_rtl.css");
+
+ at import url("IconMenu_rtl.css");
+
+ at import url("SpinWheel_rtl.css");
+
+ at import url("TabBar_rtl.css");
+
+ at import url("ToggleButton_rtl.css");
diff --git a/dojox/mobile/themes/holodark/images/thumb-overlay-large.png b/dojox/mobile/themes/holodark/images/thumb-overlay-large.png
new file mode 100644
index 0000000..dfac370
Binary files /dev/null and b/dojox/mobile/themes/holodark/images/thumb-overlay-large.png differ
diff --git a/dojox/mobile/themes/holodark/images/thumb-overlay-small.png b/dojox/mobile/themes/holodark/images/thumb-overlay-small.png
new file mode 100644
index 0000000..b6836d9
Binary files /dev/null and b/dojox/mobile/themes/holodark/images/thumb-overlay-small.png differ
diff --git a/dojox/mobile/themes/holodark/images/thumb-overlay.png b/dojox/mobile/themes/holodark/images/thumb-overlay.png
new file mode 100644
index 0000000..b16efec
Binary files /dev/null and b/dojox/mobile/themes/holodark/images/thumb-overlay.png differ
diff --git a/dojox/mobile/themes/holodark/images/vseparator.png b/dojox/mobile/themes/holodark/images/vseparator.png
new file mode 100644
index 0000000..c6f4f8c
Binary files /dev/null and b/dojox/mobile/themes/holodark/images/vseparator.png differ
diff --git a/dojox/mobile/themes/holodark/variables.less b/dojox/mobile/themes/holodark/variables.less
new file mode 100644
index 0000000..8aba3b1
--- /dev/null
+++ b/dojox/mobile/themes/holodark/variables.less
@@ -0,0 +1,914 @@
+ at import "../common/css3.less";
+
+ at holo-color: white;
+ at holo-base-color: black;
+ at holo-grey1: #222222;
+ at holo-grey2: #333333;
+ at holo-grey3: #4F4F4F;
+
+ at holo-color1: #33B5E5;
+
+ at holo-checkbox-border-color: #5C5C5C;
+ at holo-checkbox-selected-color: #99BBCA;
+ at holo-checkbox-tick-color: #61C6EB;
+ at holo-checkbox-checked-color: #1F5366;
+
+ at holo-switch-on-color: #0C86AF;
+ at holo-switch-off-color: @holo-grey2;
+ at holo-switch-knob-color: #606060;
+
+ at holo-slider-thumb-color: rgba(31, 83, 102, 0.8);
+
+ at holo-slider-background-image-gecko: -moz-linear-gradient(top, @holo-color1 0%, @holo-slider-thumb-color 100%);
+ at holo-slider-track-color: #292929;
+
+ at default-blue-button-color: white;
+ at default-blue-button-background-color: #366edf;
+.default-blue-button-background-image () { 
+  background-image: none;
+}
+
+ at default-blue-button-background-image-gecko: none;
+
+.mbl-color-blue-45 () { 
+  background-image: none;  
+}
+
+
+.mbl-color-default-45 () { background-color: @holo-grey2; }
+.mbl-color-default-sel-45 () {background-color: @holo-color1; }
+
+ at mbl-color-blue-45-gecko: none;
+ at mbl-color-default-45-gecko: @holo-grey2;
+ at mbl-color-default-sel-45-gecko: @holo-color1;
+
+ at default-button-color: @holo-color;
+ at default-button-background-color: @holo-grey2;
+.default-button-background-image() {background-image: none};
+ at default-button-background-image-gecko: none;
+ at default-button-border-radius: 2px;
+
+ at default-button-selected-color: white;
+ at default-button-selected-background-color: @holo-color1;
+.default-button-selected-background-image () {background-image: none;}
+ at default-button-selected-background-image-gecko: none;
+
+ at default-selected-color: white;
+ at default-selected-background-color: #3578b1;
+ at default-selected-background-image: none;
+ at default-selected-background-image-gecko: none;
+
+ at heading-background-color: #8c8a8c;
+.heading-background-image () { background-image: none; }
+ at heading-background-image-gecko: none;
+ at heading-border-top-color: #cdd5df;
+ at heading-border-bottom-color: #2d3642;
+
+.default-button-border-styles () {
+	background-image: none;
+	background-color: #333333;
+	border-style: none;
+	border-top-style: solid;
+	border-top-color: rgba(85,85,85,0.9);
+	border-top-width: 1px;
+	border-radius: 2px;
+}
+
+.mblToolBarButtonBodyInLeftArrow-styles () {
+  border-left-width: 0;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+.mblToolBarButtonBodyInRightArrow-styles () {
+  border-right-width: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+
+
+// background styles of form controls
+.mbl-button-background-image () { .default-button-border-styles; }
+
+.mbl-button-selected-background-image () { .default-button-selected-background-image(); }
+.mbl-blue-button-background-image () { .default-blue-button-background-image(); }
+.mbl-blue-button-selected-background-image () { .default-button-selected-background-image(); }
+.mbl-red-button-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#fa9d58, #ee4115, 0.5, #ff4d25, 0.5, #ed4d15);}
+
+.mbl-red-button-selected-background-image () { .default-button-selected-background-image(); }
+.mbl-button-checked-background-image () { background-color: transparent; }
+
+// background styles of form controls (for gecko)
+ at mbl-button-background-image-gecko: none;
+ at mbl-button-selected-background-image-gecko: @default-button-selected-background-image-gecko;
+ at mbl-blue-button-background-image-gecko: @default-blue-button-background-image-gecko;
+ at mbl-blue-button-selected-background-image-gecko: @default-button-selected-background-image-gecko;
+ at mbl-red-button-background-image-gecko: none;
+ at mbl-red-button-selected-background-image-gecko: none;
+ at mbl-button-checked-background-image-gecko: none;
+
+// common.less
+.mobile-body-styles () {
+	font-family: Helvetica;
+	font-size: 17px;
+	color: @holo-color;
+}
+
+.mblBackground-styles () {
+	background-color: @holo-base-color;
+}
+
+.mblView-styles () {
+	color: white;
+}
+
+.mblColorBlue-styles () {
+	color: @default-blue-button-color;
+	background-color: @default-blue-button-background-color;
+	.default-blue-button-background-image();
+}
+.mblColorDefault-styles () {
+	color: @holo-color;
+	background-color: @default-button-background-color;
+	.default-button-background-image();
+}
+.mblColorDefaultSel-styles () {
+	color: @default-button-selected-color;
+	background-color: @default-button-selected-background-color;
+	.default-button-selected-background-image();
+}
+
+// Heading.less
+.mblHeading-styles () {
+	color: @holo-color;
+	background-color: @holo-base-color;
+	border-bottom-color: @holo-color1;
+	border-bottom-width: 2px;
+	border-bottom-style: solid;
+	font-size: 18px;
+	font-weight: normal;
+}
+
+
+// ToolBarButton.less
+ at mbl-tool-bar-button-body-border-radius: 0;
+//
+.mblToolBarButton-styles () {
+	text-shadow: none;
+}
+
+.mblToolBarButtonArrow-styles () {
+	border-radius: 1px;
+  .transform(scale(0.7, 1.05) rotate(45deg));
+	border: 1px solid #3a4655;
+}
+.mblToolBarButtonArrowInHeading-styles () {
+}
+.mblToolBarButtonHasLeftArrowInHeading-styles () {
+}
+.mblToolBarButtonHasLeftArrowInHeading-compat-gecko () {
+}
+.mblToolBarButtonHasRightArrowInHeading-styles () {
+}
+.mblToolBarButtonHasRightArrowInHeading-compat-gecko () {
+}
+.mblToolBarButtonArrowInLeftArrow-styles () {
+  left: -1px;
+}
+.mblToolBarButtonArrowInRightArrow-styles () {
+  right: -1px;
+}
+.mblToolBarButtonBody-styles () {
+	border: 1px solid #555555;
+}
+.mblToolBarButtonBodyInHeading-styles () {
+}
+.mblToolBarButtonBodyInHeading-compat-gecko () {
+
+}
+
+// RoundRect.less & RoundRectList.less
+ at mbl-round-rect-border-color: @holo-grey1;
+ at mbl-round-rect-border-radius: 14px;
+ at mbl-round-rect-background-color: transparent;
+ at mbl-round-rect-box-shadow: none;
+//
+.mblRoundRect-styles () {
+	color: white;
+}
+
+// EdgeToEdgeCategory.less
+.mblEdgeToEdgeCategory-styles () {
+	height: 35px;
+	border-bottom: 3px solid #39393A;
+	background-color: rgba(0,0,0,0);
+	color: white;
+	line-height: 35px;
+	margin-right:7px;
+	margin-left:7px;
+	margin-top: 10px;
+	text-transform: uppercase;
+}
+
+// RoundRectCategory.less
+ at mbl-value-picker-slot-margin: 0 5px;
+.mblRoundRectCategory-styles () {
+
+}
+
+// EdgeToEdgeList.less
+.mblEdgeToEdgeList-styles () {
+	
+}
+.mblEdgeToEdgeList-LastListItem-styles () {
+	border-bottom-color: #333538;
+	margin-right:7px;
+  margin-left:7px;
+}
+
+// ListItem.less
+ at mbl-list-item-height: 50px;
+//
+.mblListItem-styles () {
+	border-bottom: 1px solid #333538;
+  margin-right:7px;
+  margin-left:7px;
+	
+	font-size: 18px;
+	color: @holo-color;
+}
+.mblListItemSelected-styles () {
+	color: @default-selected-color;
+	background-color: @default-selected-background-color;
+}
+.mblListItemLabelSelected-styles () {
+	background-color: #048bf4;
+}
+.mblListItemChecked-styles () {
+}
+.mblListItemRightText-styles () {
+	color: white;
+	margin-top: 14px;
+}
+.mblListItemSubText-styles () {
+	font-size: 14px;
+	color: gray;
+}
+
+// Switch.less
+ at mbl-switch-bg-left-background-color: #00a200;
+.mbl-switch-bg-left-background-image () {background-image: none; }
+ at mbl-switch-bg-right-background-color: #bdbebd;
+.mbl-switch-bg-right-background-image () { .background-image-linear-gradient-top-bottom(#bdbebd, #f7f3f7); }
+.mbl-switch-knob-background-image () {  .background-image-linear-gradient-top-bottom(#9c9a9c, #848284); }
+
+//
+ at mbl-switch-bg-left-background-image-gecko: none;
+ at mbl-switch-bg-right-background-image-gecko: -none;
+ at mbl-switch-knob-background-image-gecko: none;
+ at mbl-switch-square-border-radius: 0px;
+//
+.mblSwitchBg-styles () {
+	border: rgba(176,176,176,0.5) 1px inset;
+}
+.mblSwitchKnob-styles () {
+	border: rgba(157,157,157,0.5) 1px outset;
+}
+
+// Button.less
+.mblButton-styles () {
+	.default-button-border-styles;
+	height: 40px;
+	color: @holo-color;
+	
+}
+.mblButtonSelected-styles () {
+  
+  color: @holo-color;
+  border-color: transparent;
+  background-image: none;
+  background-color: #2C94BB;
+  box-shadow: 0px 0px 1px 4px #1F5366;
+  
+}
+.mblButton-mblBlueButton-styles () {
+  color: @holo-color;
+  .default-button-border-styles;
+  background-color: #0099CC;
+}
+.mblButton-mblRedButton-styles () {
+  color: @holo-color;
+  .default-button-border-styles;
+  background-color: #CC0000;
+}
+
+// CheckBox.less
+.mblCheckBox-styles () {
+	border-color: @holo-checkbox-border-color;
+  border-width: 1px;
+	background-color: transparent;
+	background-image: none;
+  border-style: solid;
+}
+.mblCheckBoxChecked-after-styles () {
+	border-color: white;
+  background-color: transparent;
+  background-image: none;
+
+}
+.mblCheckBoxChecked-mblCheckBoxSelected-after-styles () {
+  background-color: transparent;
+  background-image: none;
+}
+
+// ComboBox.less
+ at mbl-combo-box-popup-box-shadow: 0 0 50px black;
+//
+.dijitPopup-styles () {
+	border-radius: 0;
+}
+
+.mblComboBoxMenu-styles () {
+	border-radius: 0;
+	background-color: @holo-grey2;
+	color: @holo-color;
+}
+
+.mblComboBoxMenuItem-styles () {
+	border-color: @holo-grey3;
+	border-top: none;
+	height: 35px;
+	padding-top: 17px;
+}
+
+.mblComboBoxMenuItemSelected-styles () {
+	background-color: @default-selected-background-color;
+	color: white;
+}
+
+// IconContainer.less
+.mblIconItemSub-styles () {
+	background-color: white;
+	color: black;
+}
+.mblIconArea-styles () {
+	margin-top: 5px;
+	margin-bottom: 5px;
+	width: 74px;
+	color: white;
+}
+.mblIconItemDeleteIcon-styles () {
+	top: -4px;
+	left: -2px;
+}
+
+// RadioButton.less
+.mblRadioButton-styles () {
+	border-color: @holo-checkbox-border-color;
+}
+.mblRadioButtonChecked-after-styles () {
+	border-color: @holo-checkbox-tick-color;
+}
+.mblRadioButtonChecked-Selected-after-styles () {
+	border-color: @holo-checkbox-tick-color;
+}
+
+// Slider.less
+ at mbl-slider-bar-border-radius: 10em;
+ at mbl-slider-knob-border-radius: 10em;
+
+//
+.mblSlider-styles () {
+	border-color: #b0b0b0;
+}
+.mblSliderHandle-styles () {
+	border-color: transparent;
+}
+
+// TabBar.less
+
+.holoTabBarBackground-styles () {
+  background-color: rgba(0,0,0,0);
+  background-image: none;
+  border-style:none;
+}
+
+
+.mblTabBar-styles () {
+	text-shadow: none;
+	color: @holo-color;
+}
+
+
+// barType="tabBar"
+.mblTabBarTabBar-styles () {
+	.holoTabBarBackground-styles;
+	line-height: 0.5em;
+	
+}
+.mblTabBarTabBar-compat () {
+  .holoTabBarBackground-styles;
+  line-height: 0.5em;
+}
+
+.mblTabBarTabBarButton-styles () {
+	border-radius: 0px;
+	height:47px;
+	border-bottom-color: @holo-color1;
+	border-bottom-width: 1px;
+	border-bottom-style: solid;
+}
+
+.mblTabBarTabBarButtonIconArea-styles () {
+	padding-top: 0px;
+}
+
+.mblTabBarTabBarButtonLabel-styles () {
+	display: inline;
+	text-transform: uppercase;
+	color: @holo-color;
+	font-weight: bold;
+}
+
+.mblTabBarTabBarButtonSelected-styles () {
+	border-radius: 0px;
+	height:42px;
+	border-bottom-color: @holo-color1;
+	border-bottom-width: 6px;
+	border-bottom-style: solid;
+}
+.mblTabBarTabBarButtonLabelSelected-styles () {
+}
+
+// barType="segmentedControl"
+ at mbl-tab-bar-segmented-control-border-radius: 0px;
+//
+.mblTabBarSegmentedControl-styles () {
+	.holoTabBarBackground-styles;
+  line-height: 0.5em;	
+}
+.mblTabBarSegmentedControlButton-styles () {
+  border-radius: 0px;
+  height:28px;
+  border-bottom-color: @holo-color1;
+  border-bottom-width: 1px;
+  border-bottom-style: solid;
+}
+.mblTabBarSegmentedControlButton-compat-gecko () {
+
+}
+
+.mblTabBarSegmentedControlButtonSelected-styles () {
+  border-radius: 0px;
+  height:23px;
+  border-bottom-color: @holo-color1;
+  border-bottom-width: 6px;
+  border-bottom-style: solid;
+}
+
+// barType="standardTab"
+.mblTabBarStandardTab-styles () {
+	.holoTabBarBackground-styles;
+}
+.mblTabBarStandardTabButton-styles () {
+	color: @default-button-color;
+	background-color: @default-button-background-color; /* TODO: to compat */
+	.default-button-background-image();
+}
+.mblTabBarStandardTabButtonIconArea-styles () {
+}
+.mblTabBarStandardTabButtonLabel-styles () {
+  display: inline;
+  text-transform: uppercase;
+  color: @holo-color;
+  font-weight: bold;  
+}
+.mblTabBarStandardTabButtonSelected-styles () {
+	color: @default-button-selected-color;
+	background-color: @default-button-selected-background-color; /* TODO: to compat */
+	.background-image-linear-gradient-top-bottom-2-stops(#313031, #959595, 0.5, #5a555a, 0.5, #616161)
+	
+}
+.mblTabBarStandardTabButtonLabelSelected-styles () {
+}
+
+// barType="tallTab"
+.mblTabBarTallTab-styles () {
+	.holoTabBarBackground-styles;
+}
+.mblTabBarTallTabButton-styles () {
+  background-color: rgba(0,0,0,0);
+  background-image: none;
+  border-radius: 0px;
+  height: 58px;
+  border-style: none;
+  border-bottom-color: @holo-color1;
+  border-bottom-width: 1px;
+  border-bottom-style: solid;  
+}
+.mblTabBarTallTabButton-FirstChild-styles () {
+}
+.mblTabBarTallTabButton-LastChild-styles () {
+}
+.mblTabBarTallTabButtonIconArea-styles () {
+}
+.mblTabBarTallTabButtonLabel-styles () {
+}
+.mblTabBarTallTabButtonSelected-styles () {
+  background-color: rgba(0,0,0,0);
+  background-image: none;
+  border-radius: 0px;
+  height:53px;
+  border-style: none;
+  border-bottom-color: @holo-color1;
+  border-bottom-width: 6px;
+  border-bottom-style: solid;  
+}
+.mblTabBarTallTabButtonLabelSelected-styles () {
+}
+
+// TextArea.less
+.mblTextArea-styles () {
+	.default-button-border-styles;
+	color: @holo-color;
+	border-radius: 0;
+	border-top-color: transparent;
+	font-size: 17px;
+}
+
+// TextBox.less
+
+.mblTextBox-styles () {
+	background-color: transparent;
+	border-top-color: transparent;
+	border-left-color: transparent;
+	border-right-color: transparent;
+	border-bottom-color: @holo-color1;
+	border-width: 2px;
+	font-size: 17px;
+	border-style: solid;
+	color: @holo-color;
+}
+
+// ToggleButton.less
+.mblToggleButton-styles () {
+	.default-button-border-styles;
+	font-size: 13px;
+	color: black;
+}
+.mblToggleButtonSelected-styles () {
+	color: white;
+}
+.mblToggleButtonChecked-styles () {
+	color: white;
+}
+.mblToggleButtonChecked-after-styles () {
+	border-color: white;
+}
+.mblToggleButtonCheckedSelected-styles () {
+	color: white;
+}
+.mblToggleButtonCheckedSelected-after-styles () {
+}
+
+// Overlay.less
+.mblOverlay-styles () {
+	background-color: #333333;
+	background-image: none;
+}
+.mblOverlay-compat () {
+}
+.mblOverlay-compat-gecko () {
+}
+
+// Tooltip.less
+ at mbl-tooltip-border-radius: 3px;
+//
+.mblTooltip-styles () {
+	border-color: #adaaad;
+	border-radius: @mbl-tooltip-border-radius;
+	background-color: #8c8a8c;
+	.background-image-linear-gradient-top-bottom(#9c9e9c, #848284);
+
+}
+.mblTooltipBubble-styles () {
+	background-color: #306ea1;
+	background-image: none;
+	color: white;
+}
+.mblTooltipInnerArrow-Bubble-Above-styles () {
+	border-bottom-color: #306ea1;
+}
+.mblTooltipInnerArrow-Bubble-Below-styles () {
+	border-top-color: #306ea1;
+}
+.mblTooltipInnerArrow-Bubble-After-styles () {
+	border-left-color: #306ea1;
+}
+.mblTooltipInnerArrow-Bubble-Before-styles () {
+	border-right-color: #306ea1;
+}
+.mblTooltipArrow-Before-styles () {
+	border-left-width: 0;
+	border-right-color: #adaaad;
+}
+.mblTooltipArrow-After-styles () {
+	border-right-width: 0;
+	border-left-color: #adaaad;
+}
+.mblTooltipArrow-Above-styles () {
+	border-top-width: 0;
+	border-bottom-color: #adaaad;
+}
+.mblTooltipArrow-Below-styles () {
+	border-bottom-width: 0;
+	border-top-color: #adaaad;
+}
+.mblTooltipInnerArrow-Before-styles () {
+	border-left-width: 0;
+	border-right-color: #848284;
+}
+.mblTooltipInnerArrow-After-styles () {
+	border-right-width: 0;
+	border-left-color: #848284;
+}
+.mblTooltipInnerArrow-Above-styles () {
+	border-top-width: 0;
+	border-bottom-color: #9c9e9c;
+}
+.mblTooltipInnerArrow-Below-styles () {
+	border-bottom-width: 0;
+	border-top-color: #848284;
+}
+.mblTooltip-Heading-styles () {
+	padding-bottom: 3px;
+	border-top: 1px solid transparent;
+	border-bottom: 1px solid transparent;
+	background-color: transparent;
+	background-image: none;
+}
+.mblTooltip-Heading-compat () {
+}
+.mblTooltip-Heading-ToolbarButton-styles () {
+}
+.mblTooltip-Heading-ToolbarButton-compat () {
+}
+
+// Accordion.less
+.mblAccordion-styles () {
+	border-style:none;
+}
+.mblAccordionTitle-styles () {
+	.mbl-button-background-image();
+}
+.mblAccordionTitle-compat () {
+}
+
+.mblAccordionTitle-compat-gecko () {
+  .mbl-button-background-image();
+}
+.mblAccordionTitleSelected-styles () {
+	background-color: @holo-color1;
+}
+.mblAccordionTitleSelected-compat () {
+  background-color: @holo-color1;
+}
+.mblAccordionTitleSelected-compat-gecko () {
+  background-color: @holo-color1;
+}
+.mblAccordionTitleAnchor-styles () {
+	color: @holo-color;
+}
+.mblAccordionTitleAnchorSelected-styles () {
+	color: @holo-color;
+}
+
+// SimpleDialog.less
+ at mbl-simple-dialog-border-radius: 2px;
+//
+.mblSimpleDialog-styles () {
+	padding: 5px;
+	width: 262px;
+}
+.mblSimpleDialogDecoration-styles () {
+	background-color: rgba(64,64,64,0.85);
+	border: 2px solid #eeeeee;
+	color: white;
+
+  background-image: none;
+  background-color: @holo-grey1;
+  border-style: none;
+  border-top-style: solid;
+  border-top-width: 1px;
+  border-top-color: rgba(255,255,255,0.6);
+  border-radius: 2px; 
+}
+.mblSimpleDialogDecoration-compat () {
+	background-color: #404040;
+}
+.mblSimpleDialogDecoration-compat-gecko () {
+	background-color: rgba(64,64,64,0.85);
+}
+.mblSimpleDialogTitle-styles () {
+	margin: 14px 0 7px -5px;
+	padding: 0 14px 14px;
+	width: 244px;
+	border-bottom: 1px solid @holo-color1;
+	font-size: 17px;
+	text-align: left;
+}
+.mblSimpleDialogText-styles () {
+	margin: 14px 9px;
+	width: 244px;
+	font-size: 17px;
+	text-align: left;
+}
+
+// IconMenu.less
+ at mbl-icon-menu-border-radius: 6px;
+ at mbl-icon-menu-item-border-radius: 6px;
+//
+.mblIconMenu-styles () {
+	padding: 0;
+	background-color: rgba(64, 64, 64, 0.85);
+	border: 2px solid #eeeeee;
+}
+.mblIconMenu-compat () {
+	background-color: #404040;
+}
+.mblIconMenu-compat-gecko () {
+	background-color: rgba(64, 64, 64, 0.85);
+}
+.mblIconMenuItem-styles () {
+	border-left: 1px solid rgba(96, 96, 96, 0.85);
+	border-bottom: 1px solid rgba(96, 96, 96, 0.85);
+}
+.mblIconMenuItemAnchor-styles () {
+	font-size: 13px;
+	color: white;
+}
+.mblIconMenuItemSel-styles () {
+	background-color: @default-selected-background-color;
+	color: white;
+}
+.mblIconMenuItemSel-compat () {
+	background-color: @default-selected-background-color;
+}
+.mblIconMenuItemSel-compat-gecko () {
+	background-color: @default-selected-background-color;
+}
+
+// dijit.Calendar
+.dijitCalendar-styles () {
+	border: none 0 transparent;
+	background-color: white;
+}
+.dijitCalendar-thead-styles () {
+	background-color: @holo-grey2;
+	
+}
+.dijitCalendar-thead-compat () {
+	background-color: @holo-grey2;
+}
+.dijitCalendar-thead-compat-gecko () {
+	background-color: @holo-grey2;
+}
+.dijitCalendarMonthLabel-styles () {
+	color: white;
+	font-size: 16px;
+}
+.dijitCalendarMonthMenu-styles () {
+}
+.dijitCalendarMonthMenu-compat-ff3 () {
+}
+.dijitCalendarMonthMenu-Label-styles () {
+	color: black;
+}
+.dijitCalendarDecrease-styles () {
+	border-right: 6px solid white !important;
+}
+.dijitCalendarIncrease-styles () {
+	border-left: 6px solid white !important;
+}
+.dijitCalendarDayLabelTemplate-styles () {
+	background-color: #292c31;
+	font-size: 12px;
+	color: white;
+}
+.dijitCalendarDateTemplate-styles () {
+	border-right: 1px solid lightGrey;
+	background-color: white;
+	color: black;
+}
+.dijitCalendarDateTemplate-LastChild-styles () {
+	border-right: none;
+}
+.dijitCalendarDateLabel-DateTemplate-styles () {
+	border: none;
+}
+.dijitCalendarDateLabel-PrevMonth-styles () {
+	color: lightGrey;
+}
+.dijitCalendarDateLabel-Hovered-styles () {
+	color: @holo-color1;
+}
+.dijitCalendarDateLabel-Selected-styles () {
+	color: @holo-color1;
+	
+}
+.dijitCalendarDateLabel-Selected-compat () {
+	color: @holo-color1;
+}
+.dijitCalendarDateLabel-Selected-compat-gecko () {
+	color: @holo-color1;
+}
+.dijitCalendarDateLabel-Active-styles () {
+	
+}
+.dijitCalendarDateLabel-Active-compat () {
+	
+}
+.dijitCalendarDateLabel-Active-compat-gecko () {
+	
+}
+.dijitCalendarYearLabel-styles () {
+	padding: 0;
+	background-color: @holo-grey2;
+}
+.dijitCalendarYearLabel-compat () {
+  background-color: @holo-grey2;
+}
+.dijitCalendarYearLabel-compat-gecko () {
+  background-color: @holo-grey2;
+}
+.dijitCalendarSelectedYear-styles () {
+	color: white;
+	font-size: 16px;
+}
+.dijitCalendarNextYear-styles () {
+	padding: 1px 6px 3px 6px;
+	color: white;
+	font-size: 12px;
+}
+
+// SearchBox.less
+ at mbl-searchbox-cancel-button-color: black;
+ at mbl-searchbox-cancel-button-bg-color: transparent;
+.mblSearchBox-Cancel-Button-styles () {
+	border-radius: 0;
+}
+ at mbl-searchbox-results-decoration-color: black;
+
+// ProgressBar.less
+.mblProgressBar-styles () {
+	border-radius: 0px;
+	height: 2px;
+	background-image: none;
+	background-color: @holo-grey2;
+}
+.mblProgressBarProgress-styles () {
+	border-top-left-radius: 6px;
+	border-bottom-left-radius: 6px;
+	background-image: none;
+	background-color: @holo-color1;
+	height: 2px;
+}
+.mblProgressBarComplete-styles () {
+	border-radius: 0px;
+}
+.mblProgressBarNotStarted-styles () {
+}
+.mblProgressBarMsg-styles () {
+	top: 3px;
+}
+.mblProgressBar-compat () {
+	background-color: @holo-grey2;
+}
+.mblProgressBarProgress-compat () {
+	background-color: @holo-color1;
+}
+.mblProgressBar-compat-gecko () {
+	background-image: none;
+	background-color: @holo-grey2;
+}
+.mblProgressBarProgress-compat-gecko () {
+  background-image: none;
+  background-color: @holo-color1;
+
+}
+
+// ValuePicker.less
+.mbl-value-picker-slot-button-background-image () {background-image: none;}
+ at mbl-value-picker-slot-button-background-image-gecko: none;
+ at mbl-value-picker-slot-button-radius: 0px;
+.mbl-value-picker-slot-input-area-background-image () {background-image: none;}
+ at mbl-value-picker-slot-input-area-background-image-gecko: none;
+.mblValuePickerSlot-style () {
+  margin:  0 5px;
+}
+.mblValuePickerSlot-input-style () {
+  font-size: 28px;  
+  color: @holo-color;
+}
+
diff --git a/dojox/mobile/themes/holodark/variables_rtl.less b/dojox/mobile/themes/holodark/variables_rtl.less
new file mode 100644
index 0000000..1c065d1
--- /dev/null
+++ b/dojox/mobile/themes/holodark/variables_rtl.less
@@ -0,0 +1,32 @@
+// Carousel_rtl
+ at mbl-carousel-margin-rtl: ~"2px 0px 2px 4px";
+
+// IconContainer_rtl
+ at mbl-icon-container-right-rtl: -2px;
+
+// IconMenu_rtl-compat
+ at mbl-border-radius-rtl: 6px;
+
+// TabBar_rtl-compat
+ at mbl-moz-border-radius-rtl: 5px;
+
+// TabBar_rtl
+ at mbl-border-width-rtl: ~"1px 0px 1px 1px !important";
+ at mbl-tb-border-radius-rtl: 5px;
+
+// ThemeID
+ at theme-id: holoDark;
+
+// Switch_rtl-compat
+ at mbl-bg-image-r-rtl: ~"url(compat/switch-square-r.gif)";
+ at mbl-bg-image-l-rtl: ~"url(compat/switch-square-l.gif)";
+
+// Switch_rtl
+ at mbl-switchOn-left-rtl: -53px;
+ at mbl-switchBg-left-rtl: 53px;
+ at mbl-switch-knob-rtl: 53px;
+ at mbl-switch-text-right-rtl: -40px;
+
+// ToolBarButton_rtl
+ at mbl-toolbar-right-arrow-rtl: -1px;
+ at mbl-toolbar-left-arrow-rtl: -2px;
diff --git a/dojox/mobile/themes/iphone/Accordion-compat.css b/dojox/mobile/themes/iphone/Accordion-compat.css
new file mode 100644
index 0000000..37f6f7c
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Accordion-compat.css
@@ -0,0 +1,25 @@
+/* dojox.mobile.Accordion */
+.mblAccordionTitle {
+  background-color: #f0f2f3;
+}
+.mblAccordionTitleSelected {
+  background-color: #7796ac;
+}
+.dj_gecko .mblAccordionTitle {
+  background-image: -moz-linear-gradient(top, #fcfcfc 0%, #f0f2f3 20%, #e1e5e8 100%);
+}
+.dj_gecko .mblAccordionTitleSelected {
+  background-image: -moz-linear-gradient(top, #97afc0 0%, #7796ac 20%, #46708e 100%);
+}
+.dj_ff3 .mblAccordionRoundRect {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitle:first-child {
+  -moz-border-radius-topleft: 8px;
+  -moz-border-radius-topright: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitleLast,
+.dj_ff3 .mblAccordionRoundRect .mblAccordionPane:last-child {
+  -moz-border-radius-bottomleft: 8px;
+  -moz-border-radius-bottomright: 8px;
+}
diff --git a/dojox/mobile/themes/iphone/Accordion.css b/dojox/mobile/themes/iphone/Accordion.css
new file mode 100644
index 0000000..f2b05a6
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Accordion.css
@@ -0,0 +1,73 @@
+/* dojox.mobile.Accordion */
+.mblAccordion {
+  border-style: outset;
+  border-width: 1px;
+  border-color: #8c8f91;
+}
+.mblAccordionRoundRect {
+  margin: 7px 9px 16px 9px;
+  padding: 0;
+  border: 1px solid #adaaad;
+  border-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitle:first-child {
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitleLast,
+.mblAccordionRoundRect .mblAccordionPane:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
+}
+.mblAccordionTitle {
+  position: relative;
+  height: 30px;
+  width: 100%;
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  line-height: 30px;
+  vertical-align: middle;
+  white-space: nowrap;
+  border-top: 1px solid #8c8f91;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcfcfc), to(#e1e5e8), color-stop(0.2, #f0f2f3));
+  background-image: linear-gradient(to bottom, #fcfcfc 0%, #f0f2f3 20%, #e1e5e8 100%);
+}
+.mblAccordionTitle:first-child {
+  border-top: none;
+}
+.mblAccordionTitleAnchor {
+  display: block;
+  height: 100%;
+  text-decoration: none;
+  white-space: nowrap;
+  color: black;
+  cursor: pointer;
+}
+.mblAccordionIconParent {
+  float: left;
+  margin: 6px 4px 0 6px;
+  line-height: normal;
+}
+.mblAccordionIconParent1 {
+  display: block;
+}
+.mblAccordionIconParent2 {
+  display: none;
+}
+.mblAccordionTitleSelected {
+  border-bottom: 1px solid #8c8f91;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#97afc0), to(#46708e), color-stop(0.2, #7796ac));
+  background-image: linear-gradient(to bottom, #97afc0 0%, #7796ac 20%, #46708e 100%);
+  color: white;
+}
+.mblAccordionTitleSelected .mblAccordionTitleAnchor {
+  color: white;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent1 {
+  display: none;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent2 {
+  display: block;
+}
diff --git a/dojox/mobile/themes/iphone/Button-compat.css b/dojox/mobile/themes/iphone/Button-compat.css
index dccf89b..100b48d 100644
--- a/dojox/mobile/themes/iphone/Button-compat.css
+++ b/dojox/mobile/themes/iphone/Button-compat.css
@@ -1,33 +1,41 @@
 /* dojox.mobile.Button */
 .mblButton {
-	background-color: #cfcfcf;
-	background-image: url(compat/button-bg.png);
-	background-repeat: repeat-x;
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
+  background-image: url(compat/button-bg.png);
+  background-repeat: repeat-x;
 }
 .mblButtonSelected {
-	background-color: #c0c0c0;
-	background-image: url(compat/button-sel-bg.png);
-}
-.mblButtonDisabled {
-	background-image: none;
+  background-image: url(compat/button-sel-bg.png);
 }
 .mblBlueButton {
-	background-color: #2261dd;
-	background-image: url(compat/blue-button-bg.png);
+  background-image: url(compat/blue-button-bg.png);
 }
 .mblBlueButtonSelected {
-	background-color: #4a6c9b;
-	background-image: url(compat/blue-button-sel-bg.png);
+  background-image: url(compat/blue-button-sel-bg.png);
 }
 .mblRedButton {
-	background-color: #ee4115;
-	background-image: url(compat/red-button-bg.png);
+  background-image: url(compat/red-button-bg.png);
 }
 .mblRedButtonSelected {
-	background-color: #9b6c4a;
-	background-image: url(compat/red-button-sel-bg.png);
+  background-image: url(compat/red-button-sel-bg.png);
+}
+.dj_gecko .mblButton {
+  background-image: -moz-linear-gradient(top, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+}
+.dj_gecko .mblButtonSelected {
+  background-image: -moz-linear-gradient(top, #f0f0f0 0%, #ebebeb 50%, #dedede 50%, #bfbfbf 100%);
+}
+.dj_gecko .mblBlueButton {
+  background-image: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblBlueButtonSelected {
+  background-image: -moz-linear-gradient(top, #8ea4c1 0%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
+}
+.dj_gecko .mblRedButton {
+  background-image: -moz-linear-gradient(top, #fa9d58 0%, #ff4d25 50%, #ed4d15 50%, #ee4115 100%);
+}
+.dj_gecko .mblRedButtonSelected {
+  background-image: -moz-linear-gradient(top, #c1a48e 0%, #a27758 50%, #996947 50%, #9b6c4a 100%);
+}
+.dj_ff3 .mblButton {
+  -moz-border-radius: 5px;
 }
diff --git a/dojox/mobile/themes/iphone/Button.css b/dojox/mobile/themes/iphone/Button.css
index 9ed5a9d..f17bdde 100644
--- a/dojox/mobile/themes/iphone/Button.css
+++ b/dojox/mobile/themes/iphone/Button.css
@@ -1,45 +1,47 @@
 /* dojox.mobile.Button */
 .mblButton {
-  cursor: pointer;
-  outline: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  padding: 0px 10px;
+  padding: 0 10px;
   height: 29px;
-  border: #9CACC0 1px outset;
-  -webkit-border-radius: 5px;
+  border-style: outset;
+  border-width: 1px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#cecece), color-stop(0.5, #f8f8f8), color-stop(0.5, #eeeeee));
-  color: black;
+  background-image: linear-gradient(to bottom, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
   font-family: Helvetica;
-  font-size: 13px;
   line-height: 29px;
-}
-.mblButton.mblBlueButton {
+  cursor: pointer;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  border-color: #9CACC0;
+  border-color: #9cacc0;
+  border-radius: 5px;
+  color: black;
+  font-size: 13px;
+}
+.mblButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0), to(#bfbfbf), color-stop(0.5, #ebebeb), color-stop(0.5, #dedede));
+  background-image: linear-gradient(to bottom, #f0f0f0 0%, #ebebeb 50%, #dedede 50%, #bfbfbf 100%);
+  color: black;
+}
+.mblButtonDisabled,
+.mblButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
+}
+.mblBlueButton {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
   color: white;
 }
-.mblButton.mblBlueButtonSelected {
+.mblBlueButtonSelected {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#8ea4c1), to(#4a6c9b), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
-  color: white;
+  background-image: linear-gradient(to bottom, #8ea4c1 0%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
 }
-.mblButton.mblRedButton {
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  border-color: #9CACC0;
+.mblRedButton {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fa9d58), to(#ee4115), color-stop(0.5, #ff4d25), color-stop(0.5, #ed4d15));
+  background-image: linear-gradient(to bottom, #fa9d58 0%, #ff4d25 50%, #ed4d15 50%, #ee4115 100%);
   color: white;
 }
-.mblButton.mblRedButtonSelected {
+.mblRedButtonSelected {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#c1a48e), to(#9b6c4a), color-stop(0.5, #a27758), color-stop(0.5, #996947));
-  color: white;
-}
-.mblButtonSelected {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0), to(#bfbfbf), color-stop(0.5, #ebebeb), color-stop(0.5, #dedede));
-  color: black;
-}
-.mblButtonDisabled, .mblButton:disabled {
-  cursor: default;
-  border-color: grey;
-  background-image: none;
-  color: grey;
+  background-image: linear-gradient(to bottom, #c1a48e 0%, #a27758 50%, #996947 50%, #9b6c4a 100%);
 }
diff --git a/dojox/mobile/themes/iphone/Button.less b/dojox/mobile/themes/iphone/Button.less
deleted file mode 100644
index ab3a96c..0000000
--- a/dojox/mobile/themes/iphone/Button.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Button.less";
diff --git a/dojox/mobile/themes/iphone/Carousel.css b/dojox/mobile/themes/iphone/Carousel.css
index a415950..4439d46 100644
--- a/dojox/mobile/themes/iphone/Carousel.css
+++ b/dojox/mobile/themes/iphone/Carousel.css
@@ -1,30 +1,17 @@
 /* dojox.mobile.Carousel */
 .mblCarousel {
   overflow: hidden;
+  height: 300px;
 }
-.mblCarouselBox {
+.mblCarouselSlot {
   position: relative;
   float: left;
-}
-.mblCarouselImg {
-  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
-  vertical-align: bottom;
-}
-.mblCarouselImgSelected {
-  border: 1px dashed #C0C0C0;
-  -webkit-box-shadow: none;
-}
-.mblCarouselImgHeaderText {
-  color: white;
-  font: 14px arial, helvetica, clean, sans-serif;
-}
-.mblCarouselImgFooterText {
-  color: white;
-  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: left;
+  box-sizing: border-box;
 }
 .mblCarouselHeaderBar {
-  background-color: #3A3A3B;
-  color: #B1B1B1;
+  background-color: #3a3a3b;
+  color: #b1b1b1;
   font: bold 16px arial, helvetica, clean, sans-serif;
   padding: 1px;
 }
@@ -58,3 +45,35 @@
   position: relative;
   text-align: center;
 }
+/* dojox.mobile._CarouselItem */
+.mblCarouselItem {
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblCarouselItemHeaderText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 8px;
+  margin-bottom: 5px;
+}
+.mblCarouselItemFooterText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 5px;
+  margin-bottom: 8px;
+}
+.mblCarouselItemImage {
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  vertical-align: bottom;
+}
+.mblCarouselItemBlank {
+  display: none;
+}
+.mblCarouselSlotSelected .mblCarouselItemImage {
+  opacity: 0.6;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
diff --git a/dojox/mobile/themes/iphone/Carousel.less b/dojox/mobile/themes/iphone/Carousel.less
deleted file mode 100644
index d717397..0000000
--- a/dojox/mobile/themes/iphone/Carousel.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Carousel.less";
diff --git a/dojox/mobile/themes/iphone/Carousel_rtl.css b/dojox/mobile/themes/iphone/Carousel_rtl.css
new file mode 100644
index 0000000..6c8bc7a
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Carousel_rtl.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.Carousel Rtl */
+.mblCarouselItemRtl.mblCarouselSlot {
+  float: right;
+}
+.mblCarouselRtl .mblCarouselBtnContainer {
+  float: left;
+}
+.mblCarouselRtl .mblCarouselTitle {
+  margin: 2px 4px 2px 0px;
+}
+.mblCarouselRtl .mblCarouselHeaderBar .mblPageIndicator {
+  float: left;
+}
diff --git a/dojox/mobile/themes/iphone/CheckBox-compat.css b/dojox/mobile/themes/iphone/CheckBox-compat.css
index 99aade2..14e16ca 100644
--- a/dojox/mobile/themes/iphone/CheckBox-compat.css
+++ b/dojox/mobile/themes/iphone/CheckBox-compat.css
@@ -1,36 +1,38 @@
 /* dojox.mobile.CheckBox */
 .mblCheckBox {
-	background-image: url(compat/button-bg.png);
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
-	-moz-appearance: none;
-	-o-appearance: none;
-	-ms-appearance: none;
-	appearance: none;
-	-o-transform: translateY(0.45em);
-	-ms-transform: translateY(0.45em);
-	transform: translateY(0.45em);
+  background-image: url(compat/button-bg.png);
 }
 .mblCheckBoxSelected {
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/button-sel-bg.png);
 }
 .mblCheckBoxChecked,
 .mblCheckBox:checked {
-	background-image: url(compat/blue-button-bg.png);
-}
-.mblCheckBoxChecked::after,
-.mblCheckBox:checked::after {
-	-moz-transform: rotate(45deg);
-	-o-transform: rotate(45deg);
-	-ms-transform: rotate(45deg);
-	transform: rotate(45deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
-}
-.mblCheckBoxChecked.mblCheckBoxSelected {
-	background-image: url(compat/blue-button-sel-bg.png);
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblCheckBox {
+  background-image: -moz-linear-gradient(top, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+  -moz-appearance: none;
+}
+.dj_gecko .mblCheckBoxSelected {
+  background-image: -moz-linear-gradient(top, #f0f0f0 0%, #ebebeb 50%, #dedede 50%, #bfbfbf 100%);
+}
+.dj_gecko .mblCheckBoxChecked,
+.dj_gecko .mblCheckBox:checked {
+  background-image: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblCheckBoxChecked::after,
+.dj_gecko .mblCheckBox:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblCheckBoxChecked.mblCheckBoxSelected,
+.dj_gecko .mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: -moz-linear-gradient(top, #8ea4c1 0%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
+}
+.dj_ff3 .mblCheckBox {
+  -moz-border-radius: 5px;
 }
diff --git a/dojox/mobile/themes/iphone/CheckBox.css b/dojox/mobile/themes/iphone/CheckBox.css
index eb9069c..2cc090b 100644
--- a/dojox/mobile/themes/iphone/CheckBox.css
+++ b/dojox/mobile/themes/iphone/CheckBox.css
@@ -1,44 +1,49 @@
 /* dojox.mobile.CheckBox */
 .mblCheckBox {
   position: relative;
-  cursor: pointer;
-  outline: none;
-  -webkit-appearance: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
   margin: -0.5em 3px 0.3em 4px;
   width: 1em;
   height: 1em;
-  border: #9CACC0 1px outset;
-  -webkit-border-radius: 5px;
+  border-style: outset;
+  border-width: 1px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#cecece), color-stop(0.5, #f8f8f8), color-stop(0.5, #eeeeee));
+  background-image: linear-gradient(to bottom, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
   font: inherit;
-  -webkit-transform: translatey(0.45em);
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  border-color: #9cacc0;
+  border-radius: 5px;
 }
 .mblCheckBoxSelected {
-  border-color: #9CACC0;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0), to(#bfbfbf), color-stop(0.5, #ebebeb), color-stop(0.5, #dedede));
+  background-image: linear-gradient(to bottom, #f0f0f0 0%, #ebebeb 50%, #dedede 50%, #bfbfbf 100%);
 }
-.mblCheckBoxChecked, .mblCheckBox:checked {
-  border-color: #9CACC0;
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
 }
-.mblCheckBoxChecked::after, .mblCheckBox:checked::after {
+.mblCheckBoxChecked::after,
+.mblCheckBox:checked::after {
   position: absolute;
   content: "";
   width: 0.3em;
   height: 0.6em;
   top: 0;
   left: 0.3em;
-  border-color: white;
   border-width: 0.15em;
   border-style: none solid solid none;
   -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
   -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: white;
 }
-.mblCheckBoxChecked.mblCheckBoxSelected, .mblCheckBox:checked.mblCheckBoxSelected {
-  border-color: #9CACC0;
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#8ea4c1), to(#4a6c9b), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
-}
-.mblCheckBoxChecked.mblCheckBoxSelected::after, .mblCheckBox:checked.mblCheckBoxSelected::after {
-  border-color: #9CACC0;
+  background-image: linear-gradient(to bottom, #8ea4c1 0%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
 }
diff --git a/dojox/mobile/themes/iphone/CheckBox.less b/dojox/mobile/themes/iphone/CheckBox.less
deleted file mode 100644
index 09f93b2..0000000
--- a/dojox/mobile/themes/iphone/CheckBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/CheckBox.less";
diff --git a/dojox/mobile/themes/iphone/ComboBox-compat.css b/dojox/mobile/themes/iphone/ComboBox-compat.css
index 09c7b38..0146cbe 100644
--- a/dojox/mobile/themes/iphone/ComboBox-compat.css
+++ b/dojox/mobile/themes/iphone/ComboBox-compat.css
@@ -1,7 +1,7 @@
 /* dojox.mobile.ComboBox */
-.dijitPopup {
-	-moz-box-shadow: 0px 0px 50px black;
-	-o-box-shadow: 0px 0px 50px black;
-	-ms-box-shadow: 0px 0px 50px black;
-	box-shadow: 0px 0px 50px black;
-}
\ No newline at end of file
+.dj_gecko .dijitPopup {
+  -moz-box-shadow: 0 0 50px #000000;
+}
+.dj_gecko .mblComboBoxMenuItemSelected {
+  background-image: -moz-linear-gradient(top, #048bf4 0%, #005ce5 100%);
+}
diff --git a/dojox/mobile/themes/iphone/ComboBox.css b/dojox/mobile/themes/iphone/ComboBox.css
index 259629d..fc3aa40 100644
--- a/dojox/mobile/themes/iphone/ComboBox.css
+++ b/dojox/mobile/themes/iphone/ComboBox.css
@@ -5,8 +5,9 @@
   position: absolute;
   border: 0;
   background-color: transparent;
-  -webkit-box-shadow: 0px 0px 50px black;
-  -webkit-border-radius: 0px;
+  -webkit-box-shadow: 0 0 50px #000000;
+  box-shadow: 0 0 50px #000000;
+  border-radius: 0;
 }
 .mblReset {
   margin: 0;
@@ -17,28 +18,29 @@
   color: inherit;
 }
 .mblComboBoxMenu {
-  overflow-y: hidden !important;
   position: relative;
+  overflow-y: hidden !important;
   overflow: hidden;
   border: 1px solid black;
-  -webkit-border-radius: 0px;
+  border-radius: 0;
   background-color: white;
 }
 .mblComboBoxMenuItem {
-  white-space: nowrap;
   padding: .1em .2em;
   border-width: 1px 0 1px 0;
   border-style: solid;
+  text-align: left;
+  white-space: nowrap;
   border-color: #ffffff;
   color: inherit;
-  text-align: left;
 }
 .mblComboBoxMenuItemSelected {
-  background-color: black;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#048bf4), to(#005ce5));
+  background-image: linear-gradient(to bottom, #048bf4 0%, #005ce5 100%);
   color: white;
 }
-.mblComboBoxMenuPreviousButton, .mblComboBoxMenuNextButton {
+.mblComboBoxMenuPreviousButton,
+.mblComboBoxMenuNextButton {
   font-style: italic;
   overflow: hidden;
 }
diff --git a/dojox/mobile/themes/iphone/ComboBox.less b/dojox/mobile/themes/iphone/ComboBox.less
deleted file mode 100644
index ab9458c..0000000
--- a/dojox/mobile/themes/iphone/ComboBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ComboBox.less";
diff --git a/dojox/mobile/themes/iphone/ComboBox_rtl.css b/dojox/mobile/themes/iphone/ComboBox_rtl.css
new file mode 100644
index 0000000..01b9527
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ComboBox_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.ComboBox Rtl*/
+.mblComboBoxMenuItemRtl {
+  text-align: right;
+}
diff --git a/dojox/mobile/themes/iphone/DatePicker.css b/dojox/mobile/themes/iphone/DatePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/iphone/DatePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/iphone/EdgeToEdgeCategory-compat.css b/dojox/mobile/themes/iphone/EdgeToEdgeCategory-compat.css
index f6d50e2..685f524 100644
--- a/dojox/mobile/themes/iphone/EdgeToEdgeCategory-compat.css
+++ b/dojox/mobile/themes/iphone/EdgeToEdgeCategory-compat.css
@@ -2,3 +2,7 @@
 .mblEdgeToEdgeCategory {
 	background-image: url(compat/edge-categ-bg.png);
 }
+
+.dj_gecko .mblEdgeToEdgeCategory {
+	background-image: -moz-linear-gradient(top, #8f9ea9 0%, #b7c0c7 100%);
+}
diff --git a/dojox/mobile/themes/iphone/EdgeToEdgeCategory.css b/dojox/mobile/themes/iphone/EdgeToEdgeCategory.css
index fc21dd8..48efa0e 100644
--- a/dojox/mobile/themes/iphone/EdgeToEdgeCategory.css
+++ b/dojox/mobile/themes/iphone/EdgeToEdgeCategory.css
@@ -1,19 +1,20 @@
 /* dojox.mobile.EdgeToEdgeCategory */
 .mblEdgeToEdgeCategory {
   position: relative;
+  margin: 0;
+  padding: 0 10px;
   overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  margin: 0px;
-  padding: 0px 10px;
-  height: 22px;
-  border-top: 1px solid #A4B0B9;
-  border-bottom: 1px solid #979DA3;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#8f9ea9), to(#b7c0c7));
   font-family: Helvetica;
   font-size: 16px;
   font-weight: bold;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  height: 22px;
+  border-top: 1px solid #a4b0b9;
+  border-bottom: 1px solid #979da3;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#8f9ea9), to(#b7c0c7));
+  background-image: linear-gradient(to bottom, #8f9ea9 0%, #b7c0c7 100%);
   color: white;
   line-height: 22px;
-  text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+  text-shadow: rgba(0, 0, 0, 0.6) 0 -1px 0;
 }
diff --git a/dojox/mobile/themes/iphone/EdgeToEdgeCategory.less b/dojox/mobile/themes/iphone/EdgeToEdgeCategory.less
deleted file mode 100644
index 3bb63da..0000000
--- a/dojox/mobile/themes/iphone/EdgeToEdgeCategory.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/EdgeToEdgeCategory.less";
diff --git a/dojox/mobile/themes/iphone/EdgeToEdgeList.css b/dojox/mobile/themes/iphone/EdgeToEdgeList.css
index 9864276..74f88ba 100644
--- a/dojox/mobile/themes/iphone/EdgeToEdgeList.css
+++ b/dojox/mobile/themes/iphone/EdgeToEdgeList.css
@@ -1,12 +1,9 @@
 /* dojox.mobile.EdgeToEdgeList */
 .mblEdgeToEdgeList {
-  position: relative;
-  /* IE needs this */
-
-  margin: 0px;
-  padding: 0px;
+  margin: 0;
+  padding: 0;
   background-color: white;
 }
 .mblEdgeToEdgeList .mblListItem:last-child {
-  border-bottom-color: #707C84;
+  border-bottom-color: #707c84;
 }
diff --git a/dojox/mobile/themes/iphone/EdgeToEdgeList.less b/dojox/mobile/themes/iphone/EdgeToEdgeList.less
deleted file mode 100644
index 227627c..0000000
--- a/dojox/mobile/themes/iphone/EdgeToEdgeList.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/EdgeToEdgeList.less";
diff --git a/dojox/mobile/themes/iphone/FixedSplitter.css b/dojox/mobile/themes/iphone/FixedSplitter.css
new file mode 100644
index 0000000..f53833d
--- /dev/null
+++ b/dojox/mobile/themes/iphone/FixedSplitter.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.FixedSplitter */
+.mblFixedSplitter {
+  width: 100%;
+  height: 100%;
+}
+/* For FixedSplitter's child panes */
+.mblFixedSplitter > * {
+  position: absolute;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.mblFixedSplitterH > * {
+  height: 100%;
+  top: 0px;
+}
+.mblFixedSplitterV > * {
+  width: 100%;
+  left: 0px;
+}
diff --git a/dojox/mobile/themes/iphone/FormLayout.css b/dojox/mobile/themes/iphone/FormLayout.css
new file mode 100644
index 0000000..bb00da1
--- /dev/null
+++ b/dojox/mobile/themes/iphone/FormLayout.css
@@ -0,0 +1,190 @@
+/* Single Column Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (max-width: 500px) {
+  .mblFormLayout.mblFormLayoutAuto fieldset {
+    padding-left: 0;
+    padding-right: 0;
+  }
+  /* A gap between rows */
+  .mblFormLayout.mblFormLayoutAuto > * + * {
+    margin-top: 0.6em;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 100%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'single' ***/
+.mblFormLayout.mblFormLayoutSingleCol fieldset {
+  padding-left: 0;
+  padding-right: 0;
+}
+/* A gap between rows */
+.mblFormLayout.mblFormLayoutSingleCol > * + * {
+  margin-top: 0.6em;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 100%;
+  box-sizing: border-box;
+}
+/* Two Columns Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (min-width: 500px) {
+  /* Form layout selector*/
+  .mblFormLayout.mblFormLayoutAuto {
+    display: table;
+    width: 100%;
+  }
+  /* Form rows */
+  .mblFormLayout.mblFormLayoutAuto > * {
+    display: table-row;
+  }
+  /* Form cells */
+  .mblFormLayout.mblFormLayoutAuto > * > * {
+    display: table-cell;
+    vertical-align: top;
+    padding: 0.5em 0;
+  }
+  /* Left cells */
+  .mblFormLayout.mblFormLayoutAuto > * > *:first-child {
+    width: 20%;
+    padding-right: 0.5em;
+  }
+  /* mblFormLayoutRightAlign optional selector definition */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child {
+    text-align: right;
+  }
+  /* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+    margin-right: 0;
+  }
+  /* The Slider sticks to its bounds when margin=10px */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+    display: inline-block;
+    margin-right: 10px;
+    margin-top: 0px;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 50%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'two' ***/
+/* Form layout selector*/
+.mblFormLayout.mblFormLayoutTwoCol {
+  display: table;
+  width: 100%;
+}
+/* Form rows */
+.mblFormLayout.mblFormLayoutTwoCol > * {
+  display: table-row;
+}
+/* Form cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > * {
+  display: table-cell;
+  vertical-align: top;
+  padding: 0.5em 0;
+}
+/* Left cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > *:first-child {
+  width: 20%;
+  padding-right: 0.5em;
+}
+/* mblFormLayoutRightAlign optional selector definition */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child {
+  text-align: right;
+}
+/* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+  margin-right: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+  display: inline-block;
+  margin-right: 10px;
+  margin-top: 0px;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 50%;
+  box-sizing: border-box;
+}
+/* Common Rules*/
+/**********************************************************************************************************************/
+.mblFormLayout fieldset {
+  border: none;
+  margin: 0;
+}
+/* Bold widget labels */
+.mblFormLayout > * > *:first-child {
+  font-weight: bold;
+}
+/* Whatever the screen width, force left margin of first elements and elements following a <br> */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Button"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ToggleButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.CheckBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Switch"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.RadioButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.SearchBox"] {
+  margin-left: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > .mblSlider:first-child {
+  display: inline-block;
+  margin-left: 10px;
+  margin-top: 0;
+  margin-bottom: 0;
+}
diff --git a/dojox/mobile/themes/iphone/GridLayout.css b/dojox/mobile/themes/iphone/GridLayout.css
new file mode 100644
index 0000000..628fd9f
--- /dev/null
+++ b/dojox/mobile/themes/iphone/GridLayout.css
@@ -0,0 +1,24 @@
+/* dojox.mobile.GridLayout */
+.mblGridLayout {
+  width: 100%;
+  height: 100%;
+  padding: 0;
+}
+.mblGridLayout > div {
+  margin: 0;
+  border: 0;
+  padding: 0;
+  float: left;
+  min-height: 1px;
+}
+.mblGridItemFirstColumn {
+  clear: left;
+}
+.mblGridItemTerminator {
+  clear: both;
+}
+.mblGridItemLastItem:after {
+  content: "";
+  display: block;
+  clear: both;
+}
diff --git a/dojox/mobile/themes/iphone/Heading-compat.css b/dojox/mobile/themes/iphone/Heading-compat.css
index bc02fa1..b684fd4 100644
--- a/dojox/mobile/themes/iphone/Heading-compat.css
+++ b/dojox/mobile/themes/iphone/Heading-compat.css
@@ -1,24 +1,10 @@
-/* mbl.widget.Heading */
+/* dojox.mobile.Heading */
 .mblHeading {
-	background-image: url(compat/heading-bg.png);
+  background-image: url(compat/heading-bg.png);
 }
 .mblHeadingSpanTitle {
-	white-space: normal;
+  white-space: normal;
 }
-
-/* Heading Arrow Button */
-.mblArrowButtonHead {
-	position: absolute;
-	top: 6px;
-	left: 3px;
-	width: 19px;
-	height: 29px;
-	border-style: none;
-	background-image: url(compat/arrow-button-head.png);
-}
-.mblArrowButtonBody {
-	padding: 0px 10px 0px 4px;
-	-moz-border-radius-topright: 5px;
-	-moz-border-radius-bottomright: 5px;
-	background-image: url(compat/arrow-button-bg.png);
+.dj_gecko .mblHeading {
+  background-image: -moz-linear-gradient(top, #b0bccd 0%, #889bb3 50%, #8195af 50%, #6d84a2 100%);
 }
diff --git a/dojox/mobile/themes/iphone/Heading.css b/dojox/mobile/themes/iphone/Heading.css
index 613cf72..94b558c 100644
--- a/dojox/mobile/themes/iphone/Heading.css
+++ b/dojox/mobile/themes/iphone/Heading.css
@@ -1,25 +1,25 @@
 /* dojox.mobile.Heading */
 .mblHeading {
   position: relative;
-  margin: 0px;
+  margin: 0;
   width: 100%;
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
   z-index: 1;
-  padding: 0px;
+  padding: 0;
   height: 42px;
-  background-color: #889BB3;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), to(#6d84a2), color-stop(0.5, #889bb3), color-stop(0.5, #8195af));
-  border-top: 1px solid #CDD5DF;
-  border-bottom: 1px solid #2D3642;
-  color: white;
   font-family: Helvetica;
   font-size: 20px;
   font-weight: bold;
   text-align: center;
   line-height: 44px;
-  text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), to(#6d84a2), color-stop(0.5, #889bb3), color-stop(0.5, #8195af));
+  background-image: linear-gradient(to bottom, #b0bccd 0%, #889bb3 50%, #8195af 50%, #6d84a2 100%);
+  border-top: 1px solid #cdd5df;
+  border-bottom: 1px solid #2d3642;
+  color: white;
+  text-shadow: rgba(0, 0, 0, 0.6) 0 -1px 0;
 }
 .mblHeading * {
   z-index: 2;
@@ -28,7 +28,7 @@
   position: absolute;
   width: 100%;
   display: none;
-  left: 0px;
+  left: 0;
   z-index: 1;
 }
 .mblHeadingCenterTitle .mblHeadingDivTitle {
@@ -37,48 +37,16 @@
 .mblHeadingCenterTitle .mblHeadingSpanTitle {
   display: none;
 }
-/* Heading Arrow Button */
-.mblArrowButton {
-  position: relative;
-  float: left;
-  height: 42px;
-}
-.mblArrowButtonHead {
-  position: absolute;
-  top: 11px;
-  left: 5px;
-  width: 20px;
-  height: 19px;
-  border: 1px solid #3A4655;
-  -webkit-transform: scale(0.7, 1) rotate(45deg);
-  background-image: -webkit-gradient(linear, left top, right bottom, from(#8ea4c1), to(#4a6c9b), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
-}
-.dj_chrome .mblArrowButtonHead {
-  border: 1px inset #3A4655;
-}
-.mblArrowButtonBody {
-  position: absolute;
-  cursor: pointer;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  top: 6px;
-  left: 16px;
-  padding: 0px 10px 0px 4px;
-  height: 29px;
-  border-width: 1px 1px 1px 0px;
-  border-style: inset;
-  border-color: #9CACC0;
-  font-family: Helvetica;
-  font-size: 13px;
-  color: white;
-  line-height: 29px;
-  -webkit-border-top-right-radius: 5px;
-  -webkit-border-bottom-right-radius: 5px;
-  background-color: #5877A2;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#8ea4c1), to(#4a6c9b), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
-}
-.mblArrowButtonSelected .mblArrowButtonHead {
-  background-image: -webkit-gradient(linear, left top, right bottom, from(#7c87a4), to(#263e6c), color-stop(0.5, #394d77), color-stop(0.5, #243b69));
-}
-.mblArrowButtonSelected .mblArrowButtonBody {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#7c87a4), to(#263e6c), color-stop(0.5, #394d77), color-stop(0.5, #243b69));
+/* iOS 6 specific */
+.dj_ios6.dj_phone .mblHeading {
+  border-top: 1px solid #eff2f7;
+  border-bottom: 1px solid #3f5c80;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d0d9e6), to(#587397), color-stop(0.025, #d0d9e6), color-stop(0.025, #beccdd));
+  background-image: linear-gradient(to bottom, #d0d9e6 0%, #d0d9e6 2.5%, #beccdd 2.5%, #587397 100%);
+}
+.dj_ios6.dj_phone .mblHeading.mblFixedBottomBar {
+  border-top: 1px solid #5e748c;
+  border-bottom: 1px solid #577296;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dee4ec), to(#577296), color-stop(0.025, #dee4ec), color-stop(0.025, #c1cddd), color-stop(0.05, #c1cddd), color-stop(0.05, #b0bfd3));
+  background-image: linear-gradient(to bottom, #dee4ec 0%, #dee4ec 2.5%, #c1cddd 2.5%, #c1cddd 5%, #b0bfd3 5%, #577296 100%);
 }
diff --git a/dojox/mobile/themes/iphone/Heading.less b/dojox/mobile/themes/iphone/Heading.less
index cfc8580..c04e447 100644
--- a/dojox/mobile/themes/iphone/Heading.less
+++ b/dojox/mobile/themes/iphone/Heading.less
@@ -1,2 +1,15 @@
 @import "variables.less";
 @import "../common/Heading.less";
+/* iOS 6 specific */
+.dj_ios6.dj_phone {
+	.mblHeading {
+		border-top: 1px solid #eff2f7;
+		border-bottom: 1px solid #3f5c80;
+		.background-image-linear-gradient-top-bottom-2-stops(#d0d9e6, #587397, 0.025, #d0d9e6, 0.025, #beccdd);
+	}
+	.mblHeading.mblFixedBottomBar {
+		border-top: 1px solid #5e748c;
+		border-bottom: 1px solid #577296;
+		.background-image-linear-gradient-top-bottom-4-stops(#dee4ec, #577296, 0.025, #dee4ec, 0.025, #c1cddd, 0.05, #c1cddd, 0.05, #b0bfd3);
+	}
+}
diff --git a/dojox/mobile/themes/iphone/IconContainer-compat.css b/dojox/mobile/themes/iphone/IconContainer-compat.css
index adf6d49..bafb264 100644
--- a/dojox/mobile/themes/iphone/IconContainer-compat.css
+++ b/dojox/mobile/themes/iphone/IconContainer-compat.css
@@ -1,11 +1,13 @@
 @import url("../common/domButtons/DomButtonColorButtons-compat.css");
 
-/* dojox.mobile.IconItem */
-.mblIconArea div {
-	*font-size: 60px; /* IE 7 quirks */
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+/* dojox.mobile.IconContainer */
+.mblIconItemPaneHeading {
+  background-image: url(compat/icon-content-heading-bg.png);
 }
-
-/* Icon Content Heading */
-.mblIconContentHeading {
-	background-image: url(compat/icon-content-heading-bg.png);
+.dj_gecko .mblIconItemPaneHeading {
+  background-image: -moz-linear-gradient(top, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
+}
+.dj_ie7 .mblIconAreaInner {
+  font-size: 60px;
 }
diff --git a/dojox/mobile/themes/iphone/IconContainer-compat.less b/dojox/mobile/themes/iphone/IconContainer-compat.less
new file mode 100644
index 0000000..e2df985
--- /dev/null
+++ b/dojox/mobile/themes/iphone/IconContainer-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer-compat.less";
diff --git a/dojox/mobile/themes/iphone/IconContainer.css b/dojox/mobile/themes/iphone/IconContainer.css
index bb33f89..6ab7612 100644
--- a/dojox/mobile/themes/iphone/IconContainer.css
+++ b/dojox/mobile/themes/iphone/IconContainer.css
@@ -1,13 +1,17 @@
 @import url("../common/domButtons/DomButtonColorButtons.css");
 
- at import url("../common/IconContainer_keyframes.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
 /* dojox.mobile.IconContainer */
 .mblIconContainer {
-  margin: 20px 0px 0px 10px;
-  padding: 0px 0px 40px 0px;
+  margin: 20px 10px;
+  padding: 0;
 }
 /* dojox.mobile.IconItem */
 .mblIconItem {
+  position: relative;
+  overflow: hidden;
+  /* for focus frame */
+
   list-style-type: none;
   float: left;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
@@ -15,29 +19,34 @@
 .mblIconItemTerminator {
   list-style-type: none;
   clear: both;
-  height: 20px;
 }
-.mblIconItemSub {
+.mblIconItemPane {
   list-style-type: none;
-  margin-left: -10px;
   background-color: white;
 }
 .mblIconArea {
-  margin-bottom: 10px;
+  position: relative;
   height: 78px;
-  width: 74px;
   font-family: Helvetica;
   font-size: 12px;
   text-align: center;
+  margin-top: 5px;
+  margin-bottom: 5px;
+  width: 74px;
 }
-.mblIconArea div {
+.mblIconArea img {
+  vertical-align: middle;
+}
+.mblIconAreaInner {
   position: relative;
   height: 65px;
   line-height: 65px;
   text-align: center;
 }
-.mblIconArea img {
-  vertical-align: middle;
+.mblIconItemDeleteIcon {
+  position: absolute;
+  top: -4px;
+  left: -2px;
 }
 .mblIconItemSpriteIcon {
   position: absolute;
@@ -52,46 +61,199 @@ table.mblClose {
 }
 .mblVibrate {
   position: relative;
-  -webkit-animation-duration: .5s;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
   -webkit-animation-timing-function: ease-in-out;
-  -webkit-animation-iteration-count: 20;
+  animation-timing-function: ease-in-out;
+  -webkit-animation-iteration-count: infinite;
+  animation-iteration-count: infinite;
   -webkit-animation-name: mblVibrate;
+  animation-name: mblVibrate;
   -webkit-transform: rotate(0deg);
+  transform: rotate(0deg);
 }
 .mblCloseContent {
-  -webkit-animation-duration: .3s;
+  -webkit-animation-duration: 0.3s;
+  animation-duration: 0.3s;
   -webkit-animation-timing-function: ease-in-out;
+  animation-timing-function: ease-in-out;
   -webkit-animation-name: mblShrink;
+  animation-name: mblShrink;
   -webkit-transform: scale(0.01);
+  transform: scale(0.01);
 }
 .mblCloseContent.mblShrink0 {
   -webkit-animation-name: mblShrink0;
+  animation-name: mblShrink0;
 }
 .mblCloseContent.mblShrink1 {
   -webkit-animation-name: mblShrink1;
+  animation-name: mblShrink1;
 }
 .mblCloseContent.mblShrink2 {
   -webkit-animation-name: mblShrink2;
+  animation-name: mblShrink2;
 }
 .mblCloseContent.mblShrink3 {
   -webkit-animation-name: mblShrink3;
+  animation-name: mblShrink3;
 }
-/* Icon Content Heading */
-.mblIconContentHeading {
+/* dojox.mobile._IconItemPane */
+.mblIconItemPaneHeading {
   position: relative;
   clear: both;
   overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
   margin-top: 0px;
   padding-left: 40px;
   height: 25px;
-  border-top: 1px solid #F1F3F4;
-  border-bottom: 1px solid #717D85;
+  border-top: 1px solid #f1f3f4;
+  border-bottom: 1px solid #717d85;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#e0e4e7), to(#b4bec6), color-stop(0.5, #c4ccd2), color-stop(0.5, #bfc8ce));
+  background-image: linear-gradient(to bottom, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
   font-family: Helvetica;
   font-size: 14px;
   color: white;
   line-height: 26px;
   text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.mblIconItemPaneIcon {
+  position: absolute;
+  top: -2px;
+  left: 1px;
+}
+ at -webkit-keyframes mblVibrate {
+  0% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    -webkit-transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    -webkit-transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    -webkit-transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at keyframes mblVibrate {
+  0% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at -webkit-keyframes mblShrink {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(0.01);
+  }
+}
+ at keyframes mblShrink {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink0 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink0 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink1 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink1 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink2 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink2 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink3 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink3 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(40%, -70%) scale(0.01);
+  }
 }
diff --git a/dojox/mobile/themes/iphone/IconContainer.less b/dojox/mobile/themes/iphone/IconContainer.less
index 963eae6..729745a 100644
--- a/dojox/mobile/themes/iphone/IconContainer.less
+++ b/dojox/mobile/themes/iphone/IconContainer.less
@@ -1,5 +1,5 @@
 @import url("../common/domButtons/DomButtonColorButtons.css");
- at import url("../common/IconContainer_keyframes.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
 
 @import "variables.less";
 @import "../common/IconContainer.less";
diff --git a/dojox/mobile/themes/iphone/IconContainer_rtl.css b/dojox/mobile/themes/iphone/IconContainer_rtl.css
new file mode 100644
index 0000000..f5b8c10
--- /dev/null
+++ b/dojox/mobile/themes/iphone/IconContainer_rtl.css
@@ -0,0 +1,14 @@
+/* dojox.mobile.IconItem Rtl */
+.mblIconItemRtl {
+  float: right;
+}
+.mblIconItemRtl .mblIconItemDeleteIcon {
+  right: -2px;
+}
+/* dojox.mobile._IconItemPane Rtl*/
+.mblIconItemPaneRtl .mblIconItemPaneHeading {
+  padding-right: 40px;
+}
+.mblIconItemPaneRtl .mblIconItemPaneIcon {
+  right: 1px;
+}
diff --git a/dojox/mobile/themes/iphone/IconMenu-compat.css b/dojox/mobile/themes/iphone/IconMenu-compat.css
new file mode 100644
index 0000000..fb8c058
--- /dev/null
+++ b/dojox/mobile/themes/iphone/IconMenu-compat.css
@@ -0,0 +1,37 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+  background-color: #040404;
+}
+.mblIconMenuItemSel {
+  background-color: #0a36e9;
+}
+.dj_gecko .mblIconMenu {
+  background-color: transparent;
+  background-image: -moz-linear-gradient(top, rgba(102, 102, 119, 0.85) 0%, rgba(22, 22, 30, 0.85) 35%, rgba(4, 4, 4, 0.85) 100%);
+  -moz-box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.5);
+}
+.dj_gecko .mblIconMenuItem {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblIconMenuItemSel {
+  background-color: transparent;
+  background-image: -moz-linear-gradient(top, rgba(139, 157, 229, 0.6) 0%, rgba(10, 54, 233, 0.8) 60%, rgba(10, 54, 233, 0.8) 100%);
+}
+.dj_ff3 .mblIconMenu {
+  -moz-border-radius: 10px;
+}
+.dj_ff3 .mblIconMenuItemIcon img {
+  border: 1px solid red;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-left-radius: 10px;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-right-radius: 10px;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-left-radius: 10px;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-right-radius: 10px;
+}
diff --git a/dojox/mobile/themes/iphone/IconMenu.css b/dojox/mobile/themes/iphone/IconMenu.css
new file mode 100644
index 0000000..f4241cd
--- /dev/null
+++ b/dojox/mobile/themes/iphone/IconMenu.css
@@ -0,0 +1,67 @@
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+  width: 100%;
+  height: 100%;
+  border-radius: 10px;
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  padding: 0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(102, 102, 119, 0.85)), to(rgba(4, 4, 4, 0.85)), color-stop(0.35, rgba(22, 22, 30, 0.85)));
+  background-image: linear-gradient(to bottom, rgba(102, 102, 119, 0.85) 0%, rgba(22, 22, 30, 0.85) 35%, rgba(4, 4, 4, 0.85) 100%);
+  border: 2px solid #9a9a9e;
+  border-top-color: #f2f2f3;
+  -webkit-box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.5);
+}
+/* dojox.mobile.IconMenuItem */
+.mblIconMenuItem {
+  float: left;
+  list-style-type: none;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border-left: 1px solid #6b6c6f;
+  border-bottom: 1px solid #6b6c6f;
+}
+.mblIconMenuItemIcon {
+  position: relative;
+  margin-left: auto;
+  margin-right: auto;
+}
+.mblIconMenuItemFirstColumn {
+  border-left: none;
+}
+.mblIconMenuItemLastRow {
+  border-bottom: none;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  border-top-left-radius: 10px;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  border-top-right-radius: 10px;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  border-bottom-left-radius: 10px;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  border-bottom-right-radius: 10px;
+}
+.mblIconMenuItemAnchor {
+  display: block;
+  height: 100%;
+  font-family: Helvetica;
+  text-decoration: none;
+  font-size: 11px;
+  color: #b8bbc0;
+  cursor: pointer;
+}
+.mblIconMenuItemTable {
+  width: 100%;
+  height: 100%;
+}
+.mblIconMenuItemTable img {
+  border: none;
+}
+.mblIconMenuItemSel {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(139, 157, 229, 0.6)), to(rgba(10, 54, 233, 0.8)), color-stop(0.6, rgba(10, 54, 233, 0.8)));
+  background-image: linear-gradient(to bottom, rgba(139, 157, 229, 0.6) 0%, rgba(10, 54, 233, 0.8) 60%, rgba(10, 54, 233, 0.8) 100%);
+}
diff --git a/dojox/mobile/themes/iphone/IconMenu_rtl-compat.css b/dojox/mobile/themes/iphone/IconMenu_rtl-compat.css
new file mode 100644
index 0000000..b67857d
--- /dev/null
+++ b/dojox/mobile/themes/iphone/IconMenu_rtl-compat.css
@@ -0,0 +1,17 @@
+/* dojox.mobile.IconMenu Rtl */
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-right-radius: 10px;
+  -moz-border-top-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-left-radius: 10px;
+  -moz-border-top-right-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-right-radius: 10px;
+  -moz-border-bottom-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-left-radius: 10px;
+  -moz-border-bottom-right-radius: 0px;
+}
diff --git a/dojox/mobile/themes/iphone/IconMenu_rtl.css b/dojox/mobile/themes/iphone/IconMenu_rtl.css
new file mode 100644
index 0000000..776c11b
--- /dev/null
+++ b/dojox/mobile/themes/iphone/IconMenu_rtl.css
@@ -0,0 +1,23 @@
+.mblIconMenuItemRtl {
+  float: right;
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstColumn {
+  border-right: none;
+  border-left: 1px solid #6b6c6f;
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  border-top-right-radius: 10px;
+  border-top-left-radius: 0px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  border-top-right-radius: 0px;
+  border-top-left-radius: 10px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  border-bottom-right-radius: 10px;
+  border-bottom-left-radius: 0px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  border-bottom-right-radius: 0px;
+  border-bottom-left-radius: 10px;
+}
diff --git a/dojox/mobile/themes/iphone/ListItem-compat.css b/dojox/mobile/themes/iphone/ListItem-compat.css
index d153c4b..9b3d402 100644
--- a/dojox/mobile/themes/iphone/ListItem-compat.css
+++ b/dojox/mobile/themes/iphone/ListItem-compat.css
@@ -1,7 +1,13 @@
 @import url("../common/domButtons/DomButtonGrayArrow-compat.css");
- at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
 
-/* mbl.widget.ListItem */
-*html li.mblListItem.mblVariableHeight { /* IE6 hack */
-	height: 0;
+ at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
+/* dojox.mobile.ListItem */
+.mblListItemSelected {
+  background-color: #048bf4;
+}
+.dj_gecko .mblListItemSelected {
+  background-image: -moz-linear-gradient(top, #048bf4 0%, #005ce5 100%);
+}
+.dj_ie6 .mblListItem {
+  vertical-align: bottom;
 }
diff --git a/dojox/mobile/themes/iphone/ListItem-compat.less b/dojox/mobile/themes/iphone/ListItem-compat.less
new file mode 100644
index 0000000..332107e
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ListItem-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayArrow-compat.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
+
+ at import "variables.less";
+ at import "../common/ListItem-compat.less";
diff --git a/dojox/mobile/themes/iphone/ListItem.css b/dojox/mobile/themes/iphone/ListItem.css
index 77d88d9..a963393 100644
--- a/dojox/mobile/themes/iphone/ListItem.css
+++ b/dojox/mobile/themes/iphone/ListItem.css
@@ -4,61 +4,69 @@
 /* dojox.mobile.ListItem */
 .mblListItem {
   position: relative;
-  list-style-type: none;
-  vertical-align: bottom;
-  /* To avoid IE6 LI bug */
+  overflow: hidden;
+  /* for focus frame */
 
-  padding: 0px 0px 0px 8px;
+  padding: 0 8px;
   height: 43px;
-  border-bottom: 1px solid #ADAAAD;
+  list-style-type: none;
+  line-height: 43px;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  border-bottom: 1px solid #adaaad;
   font-weight: bold;
   color: black;
-  line-height: 43px;
 }
 .mblListItem.mblVariableHeight {
+  padding: 11px 8px;
   height: auto;
-  padding: 11px 0px 10px 6px;
   line-height: normal;
 }
-.mblListItem .mblListItemAnchor {
-  display: block;
-  height: 100%;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  background-position: 9px 7px;
-  text-decoration: none;
-  padding-right: 7px;
-}
-.mblListItem .mblListItemAnchor * {
-  -webkit-tap-highlight-color: rgba(0, 0, 0, 0.2);
-}
-.mblItemSelected {
-  background-color: #048BF4;
+.mblListItemSelected {
+  color: #ffffff;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#048bf4), to(#005ce5));
+  background-image: linear-gradient(to bottom, #048bf4 0%, #005ce5 100%);
 }
-.mblItemSelected .mblListItemAnchor {
-  color: white;
-}
-.mblItemSelected .mblDomButton div {
+.mblListItemSelected .mblDomButton div {
   border-color: white;
 }
-.mblListItemTextBoxSelected {
-  background-color: #048BF4;
+.mblListItemLabelSelected {
+  background-color: #048bf4;
 }
 .mblListItemChecked {
-  color: #314E84;
+  color: #314e84;
 }
-.mblListItemIcon {
+.mblListItemChecked .mblListItemRightIcon {
+  visibility: visible;
+}
+.mblListItemChecked .mblListItemUncheckIcon {
+  position: absolute;
+  visibility: hidden;
+}
+.mblListItemUnchecked .mblListItemRightIcon {
+  visibility: hidden;
+}
+.mblListItemUnchecked .mblListItemUncheckIcon {
+  visibility: visible;
+}
+.mblListItemDeleteIcon {
+  position: relative;
   float: left;
   line-height: normal;
   margin-top: 7px;
+  margin-bottom: -7px;
   margin-right: 11px;
 }
-.mblListItemSpriteIcon {
-  position: absolute;
+.mblListItemIcon {
+  position: relative;
+  float: left;
+  line-height: normal;
   margin-top: 7px;
-  margin-left: 8px;
+  margin-bottom: -7px;
+  margin-right: 11px;
 }
-.mblListItemRightIcon, .mblListItemRightIcon2 {
+.mblListItemRightIcon,
+.mblListItemRightIcon2,
+.mblListItemUncheckIcon {
   position: relative;
   float: right;
   line-height: normal;
@@ -69,14 +77,51 @@
   position: relative;
   float: right;
   line-height: normal;
-  color: #324F85;
-  margin: 11px 4px 0 0;
+  margin-right: 4px;
+  color: #324f85;
+  margin-top: 12px;
 }
-.mblListItemTextBox {
+.mblListItemLabel {
+  position: relative;
   overflow: hidden;
   white-space: nowrap;
   text-overflow: ellipsis;
+  height: 100%;
 }
-.mblVariableHeight .mblListItemTextBox {
+.mblVariableHeight .mblListItemLabel {
   white-space: normal;
 }
+.mblListItemLayoutLeft {
+  position: relative;
+  float: left;
+  margin-right: 11px;
+}
+.mblListItemLayoutCenter {
+  position: absolute;
+  width: 100%;
+  text-align: center;
+}
+.mblListItemLayoutRight {
+  position: relative;
+  float: right;
+}
+/* dojox.mobile._EditableListMixin */
+.mblListItemFloat {
+  position: absolute;
+  border: 1px solid gray;
+  opacity: 0.5;
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  border-radius: 0px !important;
+  -moz-border-radius: 0px !important;
+}
+/* iOS 6 specific */
+.dj_ios6 .mblListItemRightText {
+  color: #385487;
+  font-weight: normal;
+}
+.dj_ios6 .mblListItem {
+  /* enables hardware acc. to avoid flickering issues - see #16956 */
+
+  -webkit-perspective: 1000;
+}
diff --git a/dojox/mobile/themes/iphone/ListItem.less b/dojox/mobile/themes/iphone/ListItem.less
index f9f9d21..fefce26 100644
--- a/dojox/mobile/themes/iphone/ListItem.less
+++ b/dojox/mobile/themes/iphone/ListItem.less
@@ -3,3 +3,15 @@
 
 @import "variables.less";
 @import "../common/ListItem.less";
+/* iOS 6 specific */
+.dj_ios6 {
+	.mblListItemRightText {
+		color: #385487;
+		font-weight: normal;
+	}
+	
+	.mblListItem {
+		/* enables hardware acc. to avoid flickering issues - see #16956 */
+		-webkit-perspective: 1000;
+	}
+}
diff --git a/dojox/mobile/themes/iphone/ListItem_rtl-compat.css b/dojox/mobile/themes/iphone/ListItem_rtl-compat.css
new file mode 100644
index 0000000..f7deb99
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ListItem_rtl-compat.css
@@ -0,0 +1 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl-compat.css");
diff --git a/dojox/mobile/themes/iphone/ListItem_rtl.css b/dojox/mobile/themes/iphone/ListItem_rtl.css
new file mode 100644
index 0000000..2987450
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ListItem_rtl.css
@@ -0,0 +1,29 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl.css");
+
+ at import url("../common/domButtons/DomButtonDarkBlueCheck_rtl.css");
+/* dojox.mobile.ListItem Rtl*/
+.mblListItemRtl .mblListItemDeleteIcon {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemIcon {
+  float: right;
+  margin-left: 11px;
+  margin-right: 0px;
+}
+.mblListItemRtl .mblListItemRightIcon,
+.mblListItemRtl .mblListItemRightIcon2,
+.mblListItemRtl .mblListItemUncheckIcon {
+  float: left;
+}
+.mblListItemRtl .mblListItemRightText {
+  float: left;
+  margin-left: 4px;
+}
+.mblListItemRtl .mblListItemLayoutLeft {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemLayoutRight {
+  float: left;
+}
diff --git a/dojox/mobile/themes/iphone/ListItem_rtl.less b/dojox/mobile/themes/iphone/ListItem_rtl.less
new file mode 100644
index 0000000..3d3e9eb
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ListItem_rtl.less
@@ -0,0 +1,4 @@
+ at import url("../common/domButtons/DomButtonGrayArrow_rtl.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck_rtl.css");
+
+ at import "../common/ListItem_rtl.less";
diff --git a/dojox/mobile/themes/iphone/Overlay-compat.css b/dojox/mobile/themes/iphone/Overlay-compat.css
index bf8a160..8fef1c0 100644
--- a/dojox/mobile/themes/iphone/Overlay-compat.css
+++ b/dojox/mobile/themes/iphone/Overlay-compat.css
@@ -1,15 +1,17 @@
 /* dojox.mobile.Overlay */
 .mblOverlay {
-	*position: absolute;
-	background-color: #CECECE;
-	background-image: none;
-	text-align: center;
+  text-align: center;
+  background-color: #cecece;
+  background-image: none;
 }
 .dj_gecko .mblOverlay {
-	text-align: -moz-center;
+  text-align: -moz-center;
+  background-image: -moz-linear-gradient(top, #fdfdfd 0%, #cecece 100%);
 }
 .dj_ie9 .mblOverlay > *,
-.dj_ie8 .mblOverlay > *
-{
-	margin: 0 auto;
+.dj_ie8 .mblOverlay > * {
+  margin: 0 auto;
+}
+.dj_ie6 .mblOverlay {
+  *position: absolute;
 }
diff --git a/dojox/mobile/themes/iphone/Overlay.css b/dojox/mobile/themes/iphone/Overlay.css
index 56c3778..c53730a 100644
--- a/dojox/mobile/themes/iphone/Overlay.css
+++ b/dojox/mobile/themes/iphone/Overlay.css
@@ -11,7 +11,9 @@
   width: 100%;
   text-align: -webkit-center;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#cecece));
+  background-image: linear-gradient(to bottom, #fdfdfd 0%, #cecece 100%);
 }
-.mblOverlayHidden *, .mblOverlayHidden {
+.mblOverlayHidden *,
+.mblOverlayHidden {
   visibility: hidden !important;
 }
diff --git a/dojox/mobile/themes/iphone/PageIndicator-compat.css b/dojox/mobile/themes/iphone/PageIndicator-compat.css
new file mode 100644
index 0000000..50412f7
--- /dev/null
+++ b/dojox/mobile/themes/iphone/PageIndicator-compat.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.PageIndicator */
+.mblPageIndicatorDot {
+	-moz-border-radius: 3px;
+}
diff --git a/dojox/mobile/themes/iphone/PageIndicator.css b/dojox/mobile/themes/iphone/PageIndicator.css
index a175ad6..c4384f3 100644
--- a/dojox/mobile/themes/iphone/PageIndicator.css
+++ b/dojox/mobile/themes/iphone/PageIndicator.css
@@ -16,8 +16,7 @@
   height: 6px;
   font-size: 1px;
   background-color: #949294;
-  -webkit-border-radius: 3px;
-  -moz-border-radius: 3px;
+  border-radius: 3px;
 }
 .mblPageIndicatorDotSelected {
   background-color: white;
diff --git a/dojox/mobile/themes/iphone/PageIndicator.less b/dojox/mobile/themes/iphone/PageIndicator.less
deleted file mode 100644
index 9bb6c49..0000000
--- a/dojox/mobile/themes/iphone/PageIndicator.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/PageIndicator.less";
diff --git a/dojox/mobile/themes/iphone/ProgressBar-compat.css b/dojox/mobile/themes/iphone/ProgressBar-compat.css
new file mode 100644
index 0000000..2122232
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ProgressBar-compat.css
@@ -0,0 +1,15 @@
+/* Progress Bar */
+.mblProgressBar {
+  background-color: white;
+}
+.mblProgressBarProgress {
+  background-color: #3186e7;
+}
+.dj_gecko .mblProgressBar {
+  background-image: -moz-linear-gradient(top, #a5a6a5 0%, #d6d7d6 50%, #ffffff 50%, #ffffff 90%, #b5b6b5 100%);
+}
+.dj_gecko .mblProgressBarProgress {
+  -moz-transition-property: width;
+  -moz-transition-duration: 0.25s;
+  background-image: -moz-linear-gradient(top, #b0c0ff 0%, #70b2ff 60%, #3470b6 60%, #2f83e1 100%);
+}
diff --git a/dojox/mobile/themes/iphone/ProgressBar.css b/dojox/mobile/themes/iphone/ProgressBar.css
new file mode 100644
index 0000000..08c0341
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ProgressBar.css
@@ -0,0 +1,33 @@
+/* dojox.mobile.ProgressBar */
+.mblProgressBar {
+  position: relative;
+  border-radius: 6px;
+  height: 9px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#a5a6a5), to(#b5b6b5), color-stop(0.5, #d6d7d6), color-stop(0.5, #ffffff), color-stop(0.9, #ffffff));
+  background-image: linear-gradient(to bottom, #a5a6a5 0%, #d6d7d6 50%, #ffffff 50%, #ffffff 90%, #b5b6b5 100%);
+}
+.mblProgressBarProgress {
+  -webkit-transition-property: width;
+  transition-property: width;
+  -webkit-transition-duration: 0.25s;
+  transition-duration: 0.25s;
+  height: 7px;
+  border: 1px solid #5e6fa3;
+  border-radius: 6px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#b0c0ff), to(#2f83e1), color-stop(0.6, #70b2ff), color-stop(0.6, #3470b6));
+  background-image: linear-gradient(to bottom, #b0c0ff 0%, #70b2ff 60%, #3470b6 60%, #2f83e1 100%);
+}
+.mblProgressBarNotStarted {
+  border-left: none;
+  border-right: none;
+}
+.mblProgressBarMsg {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  text-align: center;
+  font-size: 12px;
+  top: -1px;
+  font-size: 10px;
+}
diff --git a/dojox/mobile/themes/iphone/ProgressIndicator-compat.css b/dojox/mobile/themes/iphone/ProgressIndicator-compat.css
index 4ee0810..cbabad7 100644
--- a/dojox/mobile/themes/iphone/ProgressIndicator-compat.css
+++ b/dojox/mobile/themes/iphone/ProgressIndicator-compat.css
@@ -1,46 +1,83 @@
 /* Progress Indicator */
-.mblProg {
-	position: absolute;
-	top: 0px;
-	width: 4px;
-	font-size: 1px;
-	height: 36px;
-	overflow: hidden;
-	background-color: #C0C0C0;
+.dj_ie .mblProg {
+  width: 4px;
+  height: 36px;
 }
-.mblProg0 {
-	left: 0px;
+.dj_ie .mblProg0 {
+  left: 0px;
 }
-.mblProg1 {
-	left: 8px;
+.dj_ie .mblProg1 {
+  left: 8px;
 }
-.mblProg2 {
-	left: 16px;
+.dj_ie .mblProg2 {
+  left: 16px;
 }
-.mblProg3 {
-	left: 24px;
+.dj_ie .mblProg3 {
+  left: 24px;
 }
-.mblProg4 {
-	left: 32px;
+.dj_ie .mblProg4 {
+  left: 32px;
 }
-.mblProg5 {
-	left: 40px;
+.dj_ie .mblProg5 {
+  left: 40px;
 }
-.mblProg6 {
-	left: 48px;
+.dj_ie .mblProg6 {
+  left: 48px;
 }
-.mblProg7 {
-	left: 56px;
+.dj_ie .mblProg7 {
+  left: 56px;
 }
-.mblProg8 {
-	left: 64px;
+.dj_ie .mblProg8 {
+  left: 64px;
 }
-.mblProg9 {
-	left: 72px;
+.dj_ie .mblProg9 {
+  left: 72px;
 }
-.mblProg10 {
-	left: 80px;
+.dj_ie .mblProg10 {
+  left: 80px;
 }
-.mblProg11 {
-	left: 80px;
+.dj_ie .mblProg11 {
+  left: 80px;
+}
+.dj_gecko .mblProgressIndicatorCenter .mblProgContainer {
+  -moz-transform-origin: 50% 0;
+}
+.dj_gecko .mblProg {
+  -moz-transform-origin: 0 2px;
+}
+.dj_gecko .mblProg0 {
+  -moz-transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.dj_gecko .mblProg1 {
+  -moz-transform: translate(22px, 11px) rotate(-60deg);
+}
+.dj_gecko .mblProg2 {
+  -moz-transform: translate(25px, 14px) rotate(-30deg);
+}
+.dj_gecko .mblProg3 {
+  -moz-transform: translate(26px, 18px) rotate(0deg);
+}
+.dj_gecko .mblProg4 {
+  -moz-transform: translate(25px, 22px) rotate(30deg);
+}
+.dj_gecko .mblProg5 {
+  -moz-transform: translate(22px, 25px) rotate(60deg);
+}
+.dj_gecko .mblProg6 {
+  -moz-transform: translate(18px, 26px) rotate(90.1deg);
+}
+.dj_gecko .mblProg7 {
+  -moz-transform: translate(14px, 25px) rotate(120deg);
+}
+.dj_gecko .mblProg8 {
+  -moz-transform: translate(11px, 22px) rotate(150deg);
+}
+.dj_gecko .mblProg9 {
+  -moz-transform: translate(10px, 18px) rotate(180deg);
+}
+.dj_gecko .mblProg10 {
+  -moz-transform: translate(11px, 14px) rotate(210deg);
+}
+.dj_gecko .mblProg11 {
+  -moz-transform: translate(14px, 11px) rotate(240deg);
 }
diff --git a/dojox/mobile/themes/iphone/ProgressIndicator.css b/dojox/mobile/themes/iphone/ProgressIndicator.css
index 2340637..17a8bda 100644
--- a/dojox/mobile/themes/iphone/ProgressIndicator.css
+++ b/dojox/mobile/themes/iphone/ProgressIndicator.css
@@ -1,11 +1,26 @@
 /* Progress Indicator */
+.mblProgressIndicator {
+  position: relative;
+  top: 0px;
+}
+.mblHeading .mblProgressIndicator {
+  margin: 5px;
+  float: left;
+}
 .mblProgContainer {
   position: absolute;
-  width: 40px;
-  height: 40px;
+  width: 100%;
+  height: 100%;
+}
+.mblProgressIndicatorCenter {
+  position: absolute;
   top: 180px;
   left: 50%;
-  margin: -18px 0px 0px -18px;
+}
+.mblProgressIndicatorCenter .mblProgContainer {
+  left: -50%;
+  -webkit-transform-origin: 50% 0;
+  transform-origin: 50% 0;
 }
 .mblProg {
   position: absolute;
@@ -16,43 +31,127 @@
   height: 4px;
   overflow: hidden;
   -webkit-transform-origin: 0 2px;
-  background-color: #C0C0C0;
-  -webkit-border-radius: 2px;
-  -moz-border-radius: 2px;
+  transform-origin: 0 2px;
+  background-color: #c0c0c0;
+  border-radius: 2px;
 }
 .mblProg0 {
   -webkit-transform: translate(18px, 10px) rotate(-90.1deg);
+  transform: translate(18px, 10px) rotate(-90.1deg);
 }
 .mblProg1 {
   -webkit-transform: translate(22px, 11px) rotate(-60deg);
+  transform: translate(22px, 11px) rotate(-60deg);
 }
 .mblProg2 {
   -webkit-transform: translate(25px, 14px) rotate(-30deg);
+  transform: translate(25px, 14px) rotate(-30deg);
 }
 .mblProg3 {
   -webkit-transform: translate(26px, 18px) rotate(0deg);
+  transform: translate(26px, 18px) rotate(0deg);
 }
 .mblProg4 {
   -webkit-transform: translate(25px, 22px) rotate(30deg);
+  transform: translate(25px, 22px) rotate(30deg);
 }
 .mblProg5 {
   -webkit-transform: translate(22px, 25px) rotate(60deg);
+  transform: translate(22px, 25px) rotate(60deg);
 }
 .mblProg6 {
   -webkit-transform: translate(18px, 26px) rotate(90.1deg);
+  transform: translate(18px, 26px) rotate(90.1deg);
 }
 .mblProg7 {
   -webkit-transform: translate(14px, 25px) rotate(120deg);
+  transform: translate(14px, 25px) rotate(120deg);
 }
 .mblProg8 {
   -webkit-transform: translate(11px, 22px) rotate(150deg);
+  transform: translate(11px, 22px) rotate(150deg);
 }
 .mblProg9 {
   -webkit-transform: translate(10px, 18px) rotate(180deg);
+  transform: translate(10px, 18px) rotate(180deg);
 }
 .mblProg10 {
   -webkit-transform: translate(11px, 14px) rotate(210deg);
+  transform: translate(11px, 14px) rotate(210deg);
 }
 .mblProg11 {
   -webkit-transform: translate(14px, 11px) rotate(240deg);
+  transform: translate(14px, 11px) rotate(240deg);
+}
+.mblProg0Color {
+  background-color: #c0c0c0;
+}
+.mblProg1Color {
+  background-color: #c0c0c0;
+}
+.mblProg2Color {
+  background-color: #c0c0c0;
+}
+.mblProg3Color {
+  background-color: #c0c0c0;
+}
+.mblProg4Color {
+  background-color: #c0c0c0;
+}
+.mblProg5Color {
+  background-color: #c0c0c0;
+}
+.mblProg6Color {
+  background-color: #b8b9b8;
+}
+.mblProg7Color {
+  background-color: #aeafae;
+}
+.mblProg8Color {
+  background-color: #a4a5a4;
+}
+.mblProg9Color {
+  background-color: #9a9a9a;
+}
+.mblProg10Color {
+  background-color: #8e8e8e;
+}
+.mblProg11Color {
+  background-color: #838383;
+}
+.mblProgWhite .mblProg0Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg1Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg2Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg3Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg4Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg5Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg6Color {
+  background-color: #acb9cb;
+}
+.mblProgWhite .mblProg7Color {
+  background-color: #b7c2d2;
+}
+.mblProgWhite .mblProg8Color {
+  background-color: #c4cdda;
+}
+.mblProgWhite .mblProg9Color {
+  background-color: #d1d8e2;
+}
+.mblProgWhite .mblProg10Color {
+  background-color: #dee3ea;
+}
+.mblProgWhite .mblProg11Color {
+  background-color: #eceff3;
 }
diff --git a/dojox/mobile/themes/iphone/ProgressIndicator.less b/dojox/mobile/themes/iphone/ProgressIndicator.less
deleted file mode 100644
index 2ab2a2d..0000000
--- a/dojox/mobile/themes/iphone/ProgressIndicator.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ProgressIndicator.less";
diff --git a/dojox/mobile/themes/iphone/RadioButton-compat.css b/dojox/mobile/themes/iphone/RadioButton-compat.css
index 6566cc1..95e9623 100644
--- a/dojox/mobile/themes/iphone/RadioButton-compat.css
+++ b/dojox/mobile/themes/iphone/RadioButton-compat.css
@@ -1,33 +1,32 @@
 /* dojox.mobile.RadioButton */
 .mblRadioButton {
-	background-image: url(compat/button-bg.png);
-	-moz-border-radius: 0.5em;
-	-o-border-radius: 0.5em;
-	-ms-border-radius: 0.5em;
-	border-radius: 0.5em;
-	-moz-appearance: none;
-	-o-appearance: none;
-	-ms-appearance: none;
-	appearance: none;
-	-o-transform: translateY(0.45em);
-	-ms-transform: translateY(0.45em);
-	transform: translateY(0.45em);
+  background-image: url(compat/button-bg.png);
 }
 .mblRadioButtonChecked,
 .mblRadioButton:checked {
-	background-image: url(compat/blue-button-bg.png);
-}
-.mblRadioButtonChecked::after,
-.mblRadioButton:checked::after {
-	-moz-transform: rotate(45deg);
-	-o-transform: rotate(45deg);
-	-ms-transform: rotate(45deg);
-	transform: rotate(45deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
-}
-.mblRadioButtonChecked.mblRadioButtonSelected {
-	background-image: url(compat/blue-button-sel-bg.png);
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: url(compat/blue-button-sel-bg.png);
+}
+.dj_gecko .mblRadioButton {
+  background-image: -moz-linear-gradient(top, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+  -moz-appearance: none;
+}
+.dj_gecko .mblRadioButtonChecked,
+.dj_gecko .mblRadioButton:checked {
+  background-image: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblRadioButtonChecked::after,
+.dj_gecko .mblRadioButton:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblRadioButtonChecked.mblRadioButtonSelected,
+.dj_gecko .mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: -moz-linear-gradient(top, #8ea4c1 0%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
+}
+.dj_ff3 .mblRadioButton {
+  -moz-border-radius: 0.5em;
 }
diff --git a/dojox/mobile/themes/iphone/RadioButton.css b/dojox/mobile/themes/iphone/RadioButton.css
index 799f485..bb411d4 100644
--- a/dojox/mobile/themes/iphone/RadioButton.css
+++ b/dojox/mobile/themes/iphone/RadioButton.css
@@ -1,41 +1,49 @@
 /* dojox.mobile.RadioButton */
 .mblRadioButton {
   position: relative;
-  cursor: pointer;
-  outline: none;
-  -webkit-appearance: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
   margin: -0.5em 3px 0.3em 4px;
   width: 1em;
   height: 1em;
-  border: #9CACC0 1px outset;
-  -webkit-border-radius: 0.5em;
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 0.5em;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#cecece), color-stop(0.5, #f8f8f8), color-stop(0.5, #eeeeee));
+  background-image: linear-gradient(to bottom, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
   font: inherit;
-  -webkit-transform: translatey(0.45em);
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  border-color: #9cacc0;
 }
-.mblRadioButtonChecked, .mblRadioButton:checked {
-  border-color: #9CACC0;
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
 }
-.mblRadioButtonChecked::after, .mblRadioButton:checked::after {
+.mblRadioButtonChecked::after,
+.mblRadioButton:checked::after {
   position: absolute;
   content: "";
   width: 0.3em;
   height: 0.6em;
   top: 0;
   left: 0.25em;
-  border-color: white;
   border-width: 0.15em;
   border-style: none solid solid none;
-  border-color: white;
   -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
   -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: white;
 }
-.mblRadioButtonChecked.mblRadioButtonSelected, .mblRadioButton:checked.mblRadioButtonSelected {
-  border-color: #9CACC0;
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#8ea4c1), to(#4a6c9b), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
+  background-image: linear-gradient(to bottom, #8ea4c1 0%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
 }
-.mblRadioButtonChecked.mblRadioButtonSelected::after, .mblRadioButton:checked.mblRadioButtonSelected::after {
+.mblRadioButtonChecked.mblRadioButtonSelected::after,
+.mblRadioButton:checked.mblRadioButtonSelected::after {
   border-color: white;
 }
diff --git a/dojox/mobile/themes/iphone/RadioButton.less b/dojox/mobile/themes/iphone/RadioButton.less
deleted file mode 100644
index 0793ca6..0000000
--- a/dojox/mobile/themes/iphone/RadioButton.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RadioButton.less";
diff --git a/dojox/mobile/themes/iphone/RoundRect-compat.css b/dojox/mobile/themes/iphone/RoundRect-compat.css
index 4f16c44..fa1be56 100644
--- a/dojox/mobile/themes/iphone/RoundRect-compat.css
+++ b/dojox/mobile/themes/iphone/RoundRect-compat.css
@@ -1,64 +1,73 @@
+/* dojox.mobile.RoundRect */
+.mblRoundRect.mblShadow {
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+}
+.dj_ff3 .mblRoundRect {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblRoundRect.mblShadow {
+  -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+}
 /* Round Corner */
-.mblRoundCorner {
-	background-color: white;
-	height: 1px;
-	font-size: 1px;
-	overflow: hidden;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRectContainer {
-	margin: 0px;
-	padding: 0px;
-	background-color: white;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRect .mblRoundRectContainer {
-	padding: 3px 8px;
-}
-.mblRoundCorner0T {
-	height: 0px;
-}
-.mblRoundCorner1T {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
-}
-.mblRoundCorner2T {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner3T {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4T {
-	margin: 0px 1px;
-}
-.mblRoundCorner5T {
-	margin: 0px 1px;
-}
-
-.mblRoundCorner0B {
-	height: 0px;
-}
-.mblRoundCorner1B {
-	margin: 0px 1px;
-}
-.mblRoundCorner2B {
-	margin: 0px 1px;
-}
-.mblRoundCorner3B {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4B {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner5B {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
+.dj_ie .mblRoundCorner {
+  background-color: #ffffff;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #adaaad;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: #ffffff;
+  border-style: solid;
+  border-color: #adaaad;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #adaaad;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #adaaad;
+  margin: 0 5px;
 }
diff --git a/dojox/mobile/themes/iphone/RoundRect.css b/dojox/mobile/themes/iphone/RoundRect.css
index 071a9da..2727252 100644
--- a/dojox/mobile/themes/iphone/RoundRect.css
+++ b/dojox/mobile/themes/iphone/RoundRect.css
@@ -1,12 +1,12 @@
 /* dojox.mobile.RoundRect */
 .mblRoundRect {
-  margin: 7px 9px 16px 9px;
+  margin: 7px 9px 16px;
   padding: 8px;
-  border: 1px solid #ADAAAD;
-  -webkit-border-radius: 8px;
-  -moz-border-radius: 8px;
-  background-color: white;
+  border: 1px solid #adaaad;
+  border-radius: 8px;
+  background-color: #ffffff;
 }
 .mblRoundRect.mblShadow {
   -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
 }
diff --git a/dojox/mobile/themes/iphone/RoundRect.less b/dojox/mobile/themes/iphone/RoundRect.less
deleted file mode 100644
index efec816..0000000
--- a/dojox/mobile/themes/iphone/RoundRect.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRect.less";
diff --git a/dojox/mobile/themes/iphone/RoundRectCategory.css b/dojox/mobile/themes/iphone/RoundRectCategory.css
index 0a9b90b..b22247b 100644
--- a/dojox/mobile/themes/iphone/RoundRectCategory.css
+++ b/dojox/mobile/themes/iphone/RoundRectCategory.css
@@ -1,12 +1,12 @@
 /* dojox.mobile.RoundRectCategory */
 .mblRoundRectCategory {
+  margin: 18px 0 0 20px;
+  padding: 0;
+  font-family: Helvetica;
+  font-size: 16px;
   white-space: nowrap;
   text-overflow: ellipsis;
   overflow: hidden;
-  padding: 18px 0px 0px 20px;
-  margin: 0px;
-  font-family: Helvetica;
-  font-size: 16px;
-  color: #4C566C;
-  text-shadow: #ffffff 0px 1px 0px;
+  color: #4c566c;
+  text-shadow: #ffffff 0 1px 0;
 }
diff --git a/dojox/mobile/themes/iphone/RoundRectCategory.less b/dojox/mobile/themes/iphone/RoundRectCategory.less
deleted file mode 100644
index e9148cc..0000000
--- a/dojox/mobile/themes/iphone/RoundRectCategory.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRectCategory.less";
diff --git a/dojox/mobile/themes/iphone/RoundRectCategory_rtl.css b/dojox/mobile/themes/iphone/RoundRectCategory_rtl.css
new file mode 100644
index 0000000..2a7ffc3
--- /dev/null
+++ b/dojox/mobile/themes/iphone/RoundRectCategory_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.RoundRectCategory Rtl */
+.mblRoundRectCategoryRtl {
+  margin: 18px 20px 0px 0px;
+}
diff --git a/dojox/mobile/themes/iphone/RoundRectList-compat.css b/dojox/mobile/themes/iphone/RoundRectList-compat.css
index 4f16c44..92b4ac3 100644
--- a/dojox/mobile/themes/iphone/RoundRectList-compat.css
+++ b/dojox/mobile/themes/iphone/RoundRectList-compat.css
@@ -1,64 +1,78 @@
+/* dojox.mobile.RoundRectList */
+.dj_ff3 .mblRoundRectList {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:first-child {
+  -moz-border-radius-topleft: 8px;
+  -moz-border-radius-topright: 8px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:last-child {
+  -moz-border-radius-bottomleft: 8px;
+  -moz-border-radius-bottomright: 8px;
+}
 /* Round Corner */
-.mblRoundCorner {
-	background-color: white;
-	height: 1px;
-	font-size: 1px;
-	overflow: hidden;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRectContainer {
-	margin: 0px;
-	padding: 0px;
-	background-color: white;
-	border-style: solid;
-	border-color: #ADAAAD;
-	border-width: 0px 1px;
-}
-.mblRoundRect .mblRoundRectContainer {
-	padding: 3px 8px;
-}
-.mblRoundCorner0T {
-	height: 0px;
-}
-.mblRoundCorner1T {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
-}
-.mblRoundCorner2T {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner3T {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4T {
-	margin: 0px 1px;
-}
-.mblRoundCorner5T {
-	margin: 0px 1px;
-}
-
-.mblRoundCorner0B {
-	height: 0px;
-}
-.mblRoundCorner1B {
-	margin: 0px 1px;
-}
-.mblRoundCorner2B {
-	margin: 0px 1px;
-}
-.mblRoundCorner3B {
-	margin: 0px 1px;
-	border-width: 0px 2px;
-}
-.mblRoundCorner4B {
-	margin: 0px 2px;
-	border-width: 0px 3px;
-}
-.mblRoundCorner5B {
-	background-color: #ADAAAD;
-	margin: 0px 5px;
+.dj_ie .mblRoundRectList {
+  position: relative;
+}
+.dj_ie .mblRoundCorner {
+  background-color: #ffffff;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #adaaad;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: #ffffff;
+  border-style: solid;
+  border-color: #adaaad;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #adaaad;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #adaaad;
+  margin: 0 5px;
 }
diff --git a/dojox/mobile/themes/iphone/RoundRectList.css b/dojox/mobile/themes/iphone/RoundRectList.css
index cf0bea0..d801407 100644
--- a/dojox/mobile/themes/iphone/RoundRectList.css
+++ b/dojox/mobile/themes/iphone/RoundRectList.css
@@ -1,25 +1,19 @@
 /* dojox.mobile.RoundRectList */
 .mblRoundRectList {
-  position: relative;
-  /* IE needs this */
-
-  margin: 7px 9px 16px 9px;
-  padding: 0px;
-  border: 1px solid #ADAAAD;
-  -webkit-border-radius: 8px;
-  -moz-border-radius: 8px;
-  background-color: white;
+  margin: 7px 9px 16px;
+  padding: 0;
+  border: 1px solid #adaaad;
+  border-radius: 8px;
+  background-color: #ffffff;
 }
-.mblRoundRectList .mblListItem:first-child {
-  -webkit-border-top-left-radius: 8px;
-  -webkit-border-top-right-radius: 8px;
-  -moz-border-radius-topleft: 8px;
-  -moz-border-radius-topright: 8px;
+.mblRoundRectList .mblListItem:first-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:first-child {
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
 }
-.mblRoundRectList .mblListItem:last-child {
-  border-bottom-width: 0px;
-  -webkit-border-bottom-left-radius: 8px;
-  -webkit-border-bottom-right-radius: 8px;
-  -moz-border-radius-bottomleft: 8px;
-  -moz-border-radius-bottomright: 8px;
+.mblRoundRectList .mblListItem:last-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
 }
diff --git a/dojox/mobile/themes/iphone/RoundRectList.less b/dojox/mobile/themes/iphone/RoundRectList.less
deleted file mode 100644
index 52e1164..0000000
--- a/dojox/mobile/themes/iphone/RoundRectList.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/RoundRectList.less";
diff --git a/dojox/mobile/themes/iphone/ScrollablePane.css b/dojox/mobile/themes/iphone/ScrollablePane.css
new file mode 100644
index 0000000..573d58f
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ScrollablePane.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.mblScrollablePane */
+.mblScrollablePane {
+  position: relative;
+  overflow: hidden;
+}
+.mblScrollableViewContainer {
+  position: absolute;
+  top: 0px;
+}
+.mblScrollablePaneMask {
+  position: relative;
+}
diff --git a/dojox/mobile/themes/iphone/SearchBox-compat.css b/dojox/mobile/themes/iphone/SearchBox-compat.css
new file mode 100644
index 0000000..913c704
--- /dev/null
+++ b/dojox/mobile/themes/iphone/SearchBox-compat.css
@@ -0,0 +1,26 @@
+ at import url("TextBox-compat.css");
+/* dojox.mobile.SearchBox */
+.mblSearchBox {
+  height: auto;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  -moz-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/iphone/SearchBox.css b/dojox/mobile/themes/iphone/SearchBox.css
new file mode 100644
index 0000000..c1ecc9a
--- /dev/null
+++ b/dojox/mobile/themes/iphone/SearchBox.css
@@ -0,0 +1,61 @@
+ at import url("TextBox.css");
+/* dojox.mobile.SearchBox */
+.mblSearchBox.iphone4:focus::-webkit-search-cancel-button {
+  background: none !important;
+  border-color: transparent !important;
+}
+.mblSearchBox::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+  background-color: #b2b2b2;
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-size: 15px 15px;
+  background-image: -webkit-gradient(linear, left top, right bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #ffffff), color-stop(0.54, #ffffff), color-stop(0.54, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #ffffff), color-stop(0.54, #ffffff), color-stop(0.54, transparent), to(transparent)) !important;
+  border: 2px solid #b2b2b2;
+  box-sizing: border-box;
+  height: 15px;
+  width: 15px;
+  display: inline-block;
+  vertical-align: middle;
+  margin-left: 0.5em;
+  border-radius: 1em;
+}
+.mblSearchBox::-webkit-search-results-decoration {
+  -webkit-appearance: none;
+  background-repeat: no-repeat;
+  background-size: 13px 13px, 9px 9px;
+  background-position: 0px 0px, 10px 10px;
+  background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 6, from(transparent), color-stop(0.65, transparent), color-stop(0.8, #93989c), color-stop(0.95, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.425, transparent), color-stop(0.5, #93989c), color-stop(0.575, transparent), to(transparent)) !important;
+  width: 15px;
+  height: 15px;
+  display: inline-block;
+  vertical-align: middle;
+}
+.mblSearchBox {
+  height: auto;
+}
+.dj_chrome .mblSearchBox {
+  border-radius: 0;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/iphone/SimpleDialog-compat.css b/dojox/mobile/themes/iphone/SimpleDialog-compat.css
new file mode 100644
index 0000000..4b30945
--- /dev/null
+++ b/dojox/mobile/themes/iphone/SimpleDialog-compat.css
@@ -0,0 +1,12 @@
+/* dojox.mobile.SimpleDialog */
+.mblSimpleDialogDecoration {
+  background-color: #233260;
+}
+.dj_gecko .mblSimpleDialogDecoration {
+  background-color: rgba(35, 50, 96, 0.85);
+  background-image: -moz-linear-gradient(top, rgba(150, 150, 170, 0.85) 0%, rgba(77, 85, 119, 0.85) 15%, rgba(35, 50, 96, 0.85) 15%, rgba(18, 29, 68, 0.85) 100%);
+  -moz-box-shadow: 0 3px 2px #000000;
+}
+.dj_ff3 .mblSimpleDialogDecoration {
+  -moz-border-radius: 10px;
+}
diff --git a/dojox/mobile/themes/iphone/SimpleDialog.css b/dojox/mobile/themes/iphone/SimpleDialog.css
new file mode 100644
index 0000000..04e0e3d
--- /dev/null
+++ b/dojox/mobile/themes/iphone/SimpleDialog.css
@@ -0,0 +1,70 @@
+/* dojox.mobile.SimpleDialog */
+.mblSimpleDialog {
+  position: absolute;
+  z-index: 100;
+  margin: 0;
+  text-align: center;
+  outline: none;
+  padding: 5px;
+  width: 262px;
+}
+.mblSimpleDialogDecoration {
+  border-radius: 10px;
+  background-color: rgba(35, 50, 96, 0.85);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(150, 150, 170, 0.85)), to(rgba(18, 29, 68, 0.85)), color-stop(0.15, rgba(77, 85, 119, 0.85)), color-stop(0.15, rgba(35, 50, 96, 0.85)));
+  background-image: linear-gradient(to bottom, rgba(150, 150, 170, 0.85) 0%, rgba(77, 85, 119, 0.85) 15%, rgba(35, 50, 96, 0.85) 15%, rgba(18, 29, 68, 0.85) 100%);
+  border: 2px solid #bac1d3;
+  border-top-color: #eaeaf2;
+  -webkit-box-shadow: 0 3px 2px #000000;
+  box-shadow: 0 3px 2px #000000;
+  color: white;
+}
+.mblSimpleDialogContainer {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.mblSimpleDialogCover {
+  background-color: #000000;
+  opacity: 0.5;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 99;
+}
+.mblSimpleDialogCloseBtn {
+  position: absolute !important;
+}
+.mblSimpleDialogTitle {
+  margin: 14px 0 7px;
+  width: 262px;
+  font-weight: bold;
+}
+.mblSimpleDialogText {
+  margin: 7px 0 14px;
+  width: 262px;
+}
+/* iOS 6 specific */
+.dj_ios6 .mblSimpleDialogDecoration {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(179, 184, 199, 0.85)), to(rgba(35, 50, 90, 0.85)), color-stop(0.2, rgba(109, 120, 148, 0.85)), color-stop(0.2, rgba(33, 48, 88, 0.85)));
+  background-image: linear-gradient(to bottom, rgba(179, 184, 199, 0.85) 0%, rgba(109, 120, 148, 0.85) 20%, rgba(33, 48, 88, 0.85) 20%, rgba(35, 50, 90, 0.85) 100%);
+  text-shadow: rgba(0, 0, 0, 0.6) 0 -1px 0;
+}
+.dj_ios6 .mblSimpleDialogButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#b3b8c7), to(#6c7692), color-stop(0.5, #6d7894), color-stop(0.5, #586484));
+  background-image: linear-gradient(to bottom, #b3b8c7 0%, #6d7894 50%, #586484 50%, #6c7692 100%);
+  border-color: #273a52;
+  font-weight: bold;
+  color: white;
+  text-shadow: rgba(0, 0, 0, 0.6) 0 -1px 0;
+}
+.dj_ios6 .mblSimpleDialogButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#4f5157), to(#4f5157), color-stop(0.5, #6d6f74), color-stop(0.5, #61656f));
+  background-image: linear-gradient(to bottom, #4f5157 0%, #6d6f74 50%, #61656f 50%, #4f5157 100%);
+  border-color: #273a52;
+  font-weight: bold;
+  color: white;
+  text-shadow: rgba(0, 0, 0, 0.6) 0 -1px 0;
+}
diff --git a/dojox/mobile/themes/iphone/SimpleDialog.less b/dojox/mobile/themes/iphone/SimpleDialog.less
new file mode 100644
index 0000000..478459f
--- /dev/null
+++ b/dojox/mobile/themes/iphone/SimpleDialog.less
@@ -0,0 +1,23 @@
+ at import "variables.less";
+ at import "../common/SimpleDialog.less";
+/* iOS 6 specific */
+.dj_ios6 {
+	.mblSimpleDialogDecoration {
+		.background-image-linear-gradient-top-bottom-2-stops(rgba(179,184,199,0.85), rgba(35,50,90,0.85), 0.2, rgba(109,120,148,0.85), 0.2, rgba(33,48,88,0.85));
+		text-shadow: rgba(0,0,0,0.6) 0 -1px 0;
+	}
+	.mblSimpleDialogButton {
+		.background-image-linear-gradient-top-bottom-2-stops(#b3b8c7, #6c7692, 0.5, #6d7894, 0.5, #586484);
+		border-color: rgb(39, 58, 82);
+		font-weight: bold;
+		color: white;
+		text-shadow: rgba(0,0,0,0.6) 0 -1px 0;
+	}
+	.mblSimpleDialogButtonSelected {
+		.background-image-linear-gradient-top-bottom-2-stops(#4f5157, #4f5157, 0.5, #6d6f74, 0.5, #61656f);
+		border-color: rgb(39, 58, 82);
+		font-weight: bold;
+		color: white;
+		text-shadow: rgba(0,0,0,0.6) 0 -1px 0;
+	}
+}
diff --git a/dojox/mobile/themes/iphone/Slider-compat.css b/dojox/mobile/themes/iphone/Slider-compat.css
index f6987bd..a018713 100644
--- a/dojox/mobile/themes/iphone/Slider-compat.css
+++ b/dojox/mobile/themes/iphone/Slider-compat.css
@@ -1,43 +1,40 @@
 /* dojox.mobile.Slider */
 .mblSlider {
-	background-image: url(compat/slider-h-bg.png);
-	-moz-border-radius: 8px;
-	-o-border-radius: 8px;
-	-ms-border-radius: 8px; 
-	border-radius: 8px;
-	-moz-user-select: none; /* prevent selection */
-	-o-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-	-moz-box-sizing: content-box; /* make width and height consistent with a DIV */
-	-o-box-sizing: content-box;
-	-ms-box-sizing: content-box;
-	box-sizing: content-box;
-}
-.mblSlider.mblSliderV {
-	background: #ABABAB;
+  background-image: url(compat/slider-h-bg.png);
+  background-repeat: repeat-x;
 }
 .mblSliderProgressBar {
-	background-image: url(compat/slider-h-bar-bg.png);
-	background-repeat: repeat-x;
-	-moz-border-radius: 8px;
-	-o-border-radius: 8px;
-	-ms-border-radius: 8px; 
-	border-radius: 8px;
+  background-image: url(compat/slider-h-bar-bg.png);
+  background-repeat: repeat-x;
+}
+.mblSliderHandle {
+  background-image: url(compat/slider-handle-bg.png);
+}
+.mblSliderV {
+  background-color: #cecece;
+  background-image: none;
 }
 .mblSliderV .mblSliderProgressBar {
-	background: #0D48A8;
+  background-color: #2859b1;
+  background-image: none;
 }
-.mblSliderHandle {
-	background-image: url(compat/slider-handle-bg.png);
-	-moz-border-radius: 10px;
-	-o-border-radius: 10px;
-	-ms-border-radius: 10px; 
-	border-radius: 10px;
-}
-.mblSliderTransition {
-	-moz-transition-duration: 400ms;
-	-o-transition-duration: 400ms;
-	-ms-transition-duration: 400ms;
-	transition-duration: 400ms;
+.dj_gecko .mblSlider {
+  background-image: -moz-linear-gradient(top, #cecece 0%, #eeeeee 50%, #f8f8f8 50%, #fdfdfd 100%);
+  -moz-user-select: none;
+  -moz-box-sizing: content-box;
+}
+.dj_gecko .mblSliderProgressBar {
+  background-image: -moz-linear-gradient(top, #2859b1 0%, #3f84eb 50%, #4c8eee 50%, #75acfb 100%);
+}
+.dj_gecko .mblSliderHandle {
+  background-image: -moz-linear-gradient(top, #cccccc 0%, #fafafa 100%);
+}
+.dj_ff3 .mblSlider {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblSliderProgressBar {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblSliderHandle {
+  -moz-border-radius: 10px;
 }
diff --git a/dojox/mobile/themes/iphone/Slider.css b/dojox/mobile/themes/iphone/Slider.css
index 6866098..3d66533 100644
--- a/dojox/mobile/themes/iphone/Slider.css
+++ b/dojox/mobile/themes/iphone/Slider.css
@@ -1,18 +1,16 @@
 /* dojox.mobile.Slider */
 .mblSlider {
-  outline: none;
+  margin: 15px;
+  border-style: inset;
+  border-width: 1px;
+  border-radius: 8px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#cecece), to(#fdfdfd), color-stop(0.5, #eeeeee), color-stop(0.5, #f8f8f8));
+  background-image: linear-gradient(to bottom, #cecece 0%, #eeeeee 50%, #f8f8f8 50%, #fdfdfd 100%);
   -webkit-user-select: none;
-  /* prevent selection */
-
+  -ms-user-select: none;
   -webkit-box-sizing: content-box;
-  /* make width and height consistent with a DIV */
-
-  margin: 15px;
-  /* 1/2 handle width for hanging off the ends of the bar */
-
-  border: #B0B0B0 1px inset;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#ababab), to(#fefefe));
-  -webkit-border-radius: 8px;
+  box-sizing: content-box;
+  border-color: #b0b0b0;
 }
 .mblSliderH {
   width: 200px;
@@ -35,19 +33,24 @@
   left: 50%;
 }
 .mblSliderProgressBar {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#0d48a8), to(#68a6f8));
-  -webkit-border-radius: 8px;
+  border-radius: 8px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2859b1), to(#75acfb), color-stop(0.5, #3f84eb), color-stop(0.5, #4c8eee));
+  background-image: linear-gradient(to bottom, #2859b1 0%, #3f84eb 50%, #4c8eee 50%, #75acfb 100%);
 }
 .mblSliderHandle {
   margin: -10px 0 0 -10px;
   width: 18px;
   height: 18px;
-  border: #9D9D9D 1px outset;
-  -webkit-border-radius: 10px;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#a6a6a6), to(#fcfcfc));
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 10px;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#cccccc), to(#fafafa));
+  background-image: linear-gradient(to bottom, #cccccc 0%, #fafafa 100%);
+  border-color: #9d9d9d;
 }
 .mblSliderTransition {
   -webkit-transition-duration: 400ms;
+  transition-duration: 400ms;
 }
 .mblSliderTouchBox {
   margin: 0;
diff --git a/dojox/mobile/themes/iphone/Slider.less b/dojox/mobile/themes/iphone/Slider.less
deleted file mode 100644
index 928972f..0000000
--- a/dojox/mobile/themes/iphone/Slider.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Slider.less";
diff --git a/dojox/mobile/themes/iphone/SpinWheel-compat.css b/dojox/mobile/themes/iphone/SpinWheel-compat.css
new file mode 100644
index 0000000..4d605d5
--- /dev/null
+++ b/dojox/mobile/themes/iphone/SpinWheel-compat.css
@@ -0,0 +1,36 @@
+.mblSpinWheel {
+  background-image: url(../common/compat/spinwheel-bg.png);
+}
+.mblSpinWheelBar {
+  background-image: url(../common/compat/spinwheel-bar.png);
+}
+.mblSpinWheelSlotTouch,
+.mblSpinWheelSlotPanel {
+  left: 0;
+}
+.dj_gecko .mblSpinWheel {
+  background-image: -moz-linear-gradient(top, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+}
+.dj_gecko .mblSpinWheelBar {
+  background-image: -moz-linear-gradient(top, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 1%);
+}
+.dj_ff3 .mblSpinWheel {
+  -moz-border-radius: 3px;
+}
+.dj_ie .mblSpinWheelBar {
+  filter: progid:DXImageTransform.Microsoft.alpha(opacity=60);
+}
+.dj_ie6 .mblSpinWheelBar,
+.dj_ie7 .mblSpinWheelBar {
+  z-index: -1;
+}
+.dj_ie7 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
+.dj_ie6 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
diff --git a/dojox/mobile/themes/iphone/SpinWheel.css b/dojox/mobile/themes/iphone/SpinWheel.css
new file mode 100644
index 0000000..28c4ba6
--- /dev/null
+++ b/dojox/mobile/themes/iphone/SpinWheel.css
@@ -0,0 +1,81 @@
+/* dojox.mobile.SpinWheel */
+.mblSpinWheel {
+  position: relative;
+  overflow: hidden;
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #313137), color-stop(0.05, #73747d), color-stop(0.07, #92939b), color-stop(0.09, #ababb5), color-stop(0.12, #c5c6ce), color-stop(0.16, #dfe0e4), color-stop(0.22, #f4f5f6), color-stop(0.35, #fbfcfc), color-stop(0.5, #fbfcfc), color-stop(0.61, #fbfcfc), color-stop(0.61, #b4c1c7), color-stop(0.65, #fbfcfc), color-stop(0.78, #f4f5f6), color-stop(0.84, #dfe0e4), color-stop(0.88, #c5c6ce), color-stop(0.91, #ababb5), co [...]
+  background: linear-gradient(to bottom, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+  height: 200px;
+  border-left: solid 3px #000000;
+  border-right: solid 3px #000000;
+  color: #000000;
+  border-radius: 3px;
+}
+.mblSpinWheelBar {
+  position: absolute;
+  top: 79px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#edeef2), to(#a7adca), color-stop(0, #edeef2), color-stop(0.25, #c8cadd), color-stop(0.49, #bbbfd4), color-stop(0.51, #9fa8c6), color-stop(0.81, #a2a9c7), color-stop(0.82, #a6abc9), color-stop(1, #a7adca));
+  background: linear-gradient(to bottom, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 100%);
+  border: solid 1px #7b8497;
+  height: 42px;
+  width: 100%;
+  clear: both;
+  opacity: 0.6;
+}
+.mblSpinWheelDatePicker {
+  width: 312px;
+}
+.mblSpinWheelTimePicker {
+  width: 98px;
+}
+.mblSpinWheelSlot {
+  position: relative;
+  top: 0px;
+  float: left;
+  width: 100px;
+  height: 100%;
+  border-left: solid 2px #000000;
+  border-right: solid 2px #000000;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblSpinWheelSlotLabel {
+  padding: 0 8px;
+  height: 44px;
+  overflow: hidden;
+  font: bold 24px/44px Helvetica, sans-serif;
+}
+.mblSpinWheelSlotLabel img {
+  vertical-align: middle;
+  opacity: 0.7;
+}
+.mblSpinWheelSlotLabelGray {
+  color: #cccccc;
+}
+.mblSpinWheelSlotLabelBlue {
+  color: #0959d2;
+}
+.mblSpinWheelSlotContainer {
+  position: relative;
+}
+.mblSpinWheelSlotPanel {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+}
+.mblSpinWheelSlotTouch {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  z-index: 1;
+}
+.dj_ie .mblSpinWheelSlotTouch {
+  background-color: rgba(255, 255, 255, 0.01);
+}
+.dj_ie8 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+}
+/* iOS6 specific */
+.dj_ios6 .mblSpinWheelSlotLabelBlue {
+  color: #0160f2;
+}
diff --git a/dojox/mobile/themes/iphone/SpinWheel.less b/dojox/mobile/themes/iphone/SpinWheel.less
new file mode 100644
index 0000000..fe794be
--- /dev/null
+++ b/dojox/mobile/themes/iphone/SpinWheel.less
@@ -0,0 +1,8 @@
+ at import "variables.less";
+ at import "../common/SpinWheel.less";
+/* iOS6 specific */
+.dj_ios6 {
+	.mblSpinWheelSlotLabelBlue {
+		color: #0160f2;
+	}
+}
diff --git a/dojox/mobile/themes/iphone/SpinWheel_rtl-compat.css b/dojox/mobile/themes/iphone/SpinWheel_rtl-compat.css
new file mode 100644
index 0000000..98aab55
--- /dev/null
+++ b/dojox/mobile/themes/iphone/SpinWheel_rtl-compat.css
@@ -0,0 +1,4 @@
+.mblSpinWheelSlotRtl .mblSpinWheelSlotTouch,
+.mblSpinWheelSlotRtl .mblSpinWheelSlotPanel {
+  right: 0;
+}
diff --git a/dojox/mobile/themes/iphone/SpinWheel_rtl.css b/dojox/mobile/themes/iphone/SpinWheel_rtl.css
new file mode 100644
index 0000000..c3efc85
--- /dev/null
+++ b/dojox/mobile/themes/iphone/SpinWheel_rtl.css
@@ -0,0 +1,5 @@
+/* dojox.mobile.SpinWheel Rtl */
+.mblSpinWheelSlotRtl,
+.mblSpinWheelRtl .mblSpinWheelSlot {
+  float: right;
+}
diff --git a/dojox/mobile/themes/iphone/Switch-compat.css b/dojox/mobile/themes/iphone/Switch-compat.css
index 3756d95..e2b714b 100644
--- a/dojox/mobile/themes/iphone/Switch-compat.css
+++ b/dojox/mobile/themes/iphone/Switch-compat.css
@@ -1,70 +1,116 @@
-/* Switch - default */
-.mblSwitchBg {
-	border: none;
-}
-.mblSwitchBgLeft {
-	background: none;
-	background-image: url(compat/switch-default-l.gif);
-	background-repeat: no-repeat;
-}
-.mblSwitchBgRight {
-	background: none;
-	background-image: url(compat/switch-default-r.gif);
-	background-repeat: no-repeat;
-}
-.mblSwitchKnob {
-	top: 0px;
-	height: 27px;
-	background: none;
-	background-image: url(compat/switch-default-k.gif);
-	background-repeat: no-repeat;
-	border: none;
-}
-/* Switch - Round Shape1 */
+/* dojox.mobile.Switch */
+/* Switch - common */
+.dj_gecko .mblSwitchBg {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitchKnob {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitch .mblSwitchBgLeft {
+  background-image: -moz-linear-gradient(top, #2859b1 0%, #3f84eb 50%, #4c8eee 50%, #75acfb 100%);
+}
+.dj_gecko .mblSwitch .mblSwitchBgRight {
+  background-image: -moz-linear-gradient(top, #cecece 0%, #eeeeee 50%, #f8f8f8 50%, #fdfdfd 100%);
+}
+.dj_gecko .mblSwitch .mblSwitchKnob {
+  background-image: -moz-linear-gradient(top, #cccccc 0%, #fafafa 100%);
+}
+.dj_ie .mblSwitchBg {
+  border: none;
+  background: none;
+}
+.dj_ie .mblSwitchBgLeft {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchBgRight {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchKnob {
+  background: none;
+  background-repeat: no-repeat;
+  border: none;
+}
+/* Square Shape */
+.mblSwSquareShape .mblSwitchBg {
+  -moz-border-radius: 5px;
+}
+.mblSwSquareShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-square-l.gif);
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchKnob {
+  -moz-border-radius: 5px;
+  background-image: url(compat/switch-square-k.gif);
+}
+/* Round Shape1 */
+.mblSwRoundShape1 .mblSwitchBg {
+  -moz-border-radius: 14px;
+}
 .mblSwRoundShape1 .mblSwitchBgLeft {
-	background-image: url(compat/switch-round-l.gif);
+  background-image: url(compat/switch-round1-l.gif);
 }
 .mblSwRoundShape1 .mblSwitchBgRight {
-	background-image: url(compat/switch-round-r.gif);
+  background-image: url(compat/switch-round1-r.gif);
 }
 .mblSwRoundShape1 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-round1-k.gif);
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round1-k.gif);
+}
+/* Round Shape2 */
+.mblSwRoundShape2 .mblSwitchBg {
+  -moz-border-radius: 14px;
 }
-/* Switch - Round Shape2 */
 .mblSwRoundShape2 .mblSwitchBgLeft {
-	background-image: url(compat/switch-round-l.gif);
+  background-image: url(compat/switch-round2-l.gif);
 }
 .mblSwRoundShape2 .mblSwitchBgRight {
-	background-image: url(compat/switch-round-r.gif);
+  background-image: url(compat/switch-round2-r.gif);
 }
 .mblSwRoundShape2 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-round2-k.gif);
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round2-k.gif);
+}
+/* Arc Shape1 */
+.mblSwArcShape1 .mblSwitchBg {
+  -moz-border-radius: 5px/14px;
 }
-/* Switch - Arc Shape1 */
 .mblSwArcShape1 .mblSwitchBgLeft {
-	background-image: url(compat/switch-arc-l.gif);
+  background-image: url(compat/switch-arc1-l.gif);
 }
 .mblSwArcShape1 .mblSwitchBgRight {
-	background-image: url(compat/switch-arc-r.gif);
+  background-image: url(compat/switch-arc1-r.gif);
 }
 .mblSwArcShape1 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-arc1-k.gif);
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc1-k.gif);
 }
 /* Switch - Arc Shape2 */
+.mblSwArcShape2 .mblSwitchBg {
+  -moz-border-radius: 5px/14px;
+}
 .mblSwArcShape2 .mblSwitchBgLeft {
-	background-image: url(compat/switch-arc-l.gif);
+  background-image: url(compat/switch-arc2-l.gif);
 }
 .mblSwArcShape2 .mblSwitchBgRight {
-	background-image: url(compat/switch-arc-r.gif);
+  background-image: url(compat/switch-arc2-r.gif);
 }
 .mblSwArcShape2 .mblSwitchKnob {
-	top: 1px;
-	height: 26px;
-	background-image: url(compat/switch-arc2-k.gif);
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc2-k.gif);
+}
+/* Default Shape */
+.mblSwDefaultShape .mblSwitchBg {
+  -moz-border-radius: 14px;
+}
+.mblSwDefaultShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-round1-l.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round1-k.gif);
 }
diff --git a/dojox/mobile/themes/iphone/Switch-compat.less b/dojox/mobile/themes/iphone/Switch-compat.less
new file mode 100644
index 0000000..7fe42fd
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Switch-compat.less
@@ -0,0 +1,7 @@
+ at import "variables.less";
+ at import "../common/Switch-compat.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwRoundShape1-styles;
+}
diff --git a/dojox/mobile/themes/iphone/Switch.css b/dojox/mobile/themes/iphone/Switch.css
index 84597f9..2fd8651 100644
--- a/dojox/mobile/themes/iphone/Switch.css
+++ b/dojox/mobile/themes/iphone/Switch.css
@@ -1,18 +1,239 @@
- at import url("../common/Switch.css");
 /* dojox.mobile.Switch */
-.mblItemSwitch {
+/* Switch - common */
+.mblSwitch {
+  margin: 0;
+  position: relative;
+  display: inline-block;
+  height: 27px;
+  line-height: 29px;
+  overflow: hidden;
+  text-align: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblListItem .mblSwitch {
+  position: absolute;
+  right: 12px;
   top: 8px;
 }
+.mblSwitchInner {
+  position: absolute;
+  top: 0;
+  height: 27px;
+}
+.mblSwitchAnimation .mblSwitchInner {
+  -webkit-transition-property: left;
+  transition-property: left;
+  -webkit-transition-duration: 0.1s;
+  transition-duration: 0.1s;
+}
+.mblSwitchOn .mblSwitchInner {
+  left: 0;
+}
 .mblSwitchBg {
-  -webkit-border-radius: 5px;
+  position: absolute;
+  top: 0;
+  width: 94px;
+  height: 27px;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+  line-height: 29px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border-width: 1px;
+  border-style: solid;
+  border-color: #939393 #aaaaaa #cbcbcb #767676;
 }
 .mblSwitchBgLeft {
+  left: 0;
+  color: white;
+  background-color: #3f84eb;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#2859b1), to(#75acfb), color-stop(0.5, #3f84eb), color-stop(0.5, #4c8eee));
+  background-image: linear-gradient(to bottom, #2859b1 0%, #3f84eb 50%, #4c8eee 50%, #75acfb 100%);
 }
 .mblSwitchBgRight {
+  color: #7f7f7f;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#cecece), to(#fdfdfd), color-stop(0.5, #eeeeee), color-stop(0.5, #f8f8f8));
+  background-image: linear-gradient(to bottom, #cecece 0%, #eeeeee 50%, #f8f8f8 50%, #fdfdfd 100%);
 }
 .mblSwitchKnob {
+  position: absolute;
+  top: 0;
+  height: 27px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#cccccc), to(#fafafa));
-  -webkit-border-radius: 5px;
+  background-image: linear-gradient(to bottom, #cccccc 0%, #fafafa 100%);
+  font-size: 1px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border-width: 1px;
+  border-style: solid;
+  border-color: #5e5e5e #9e9e9e #828282 #797979;
+}
+.mblSwitchText {
+  position: relative;
+  top: 0;
+  width: 53px;
+  height: 27px;
+  padding: 0;
+  line-height: 28px;
+  text-align: center;
+}
+.mblSwitchTextLeft {
+  left: 0;
+}
+.mblSwitchTextRight {
+  left: 40px;
+}
+/* Square Shape */
+.mblSwSquareShape {
+  width: 94px;
+}
+.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBg {
+  border-radius: 5px;
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+  width: 41px;
+  border-radius: 5px;
+}
+.mblSwSquareShape .mblSwitchText {
+  width: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRight {
+  left: 40px;
+}
+/* Round Shape1 */
+.mblSwRoundShape1 {
+  width: 77px;
+}
+.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwRoundShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 14px;
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 13px;
+}
+.mblSwRoundShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Round Shape2 */
+.mblSwRoundShape2 {
+  width: 94px;
+}
+.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBg {
+  border-radius: 14px;
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 13px;
+}
+.mblSwRoundShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Arc Shape1 */
+.mblSwArcShape1 {
+  width: 77px;
+}
+.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwArcShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 5px/14px;
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Arc Shape2 */
+.mblSwArcShape2 {
+  width: 94px;
+}
+.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBg {
+  border-radius: 5px/14px;
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Default Shape */
+.mblSwDefaultShape {
+  width: 77px;
+}
+.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwDefaultShape .mblSwitchBg {
+  width: 77px;
+  border-radius: 14px;
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 13px;
+}
+.mblSwDefaultShape .mblSwitchText {
+  width: 50px;
+}
+.mblSwDefaultShape .mblSwitchTextRight {
+  left: 26px;
+}
+/* i0S 6 specific */
+.dj_ios6 .mblSwitchBgLeft {
+  background-color: #007fea;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#0060b1), to(#73b3ea), color-stop(0.5, #007fea), color-stop(0.5, #218fec));
+  background-image: linear-gradient(to bottom, #0060b1 0%, #007fea 50%, #218fec 50%, #73b3ea 100%);
 }
diff --git a/dojox/mobile/themes/iphone/Switch.less b/dojox/mobile/themes/iphone/Switch.less
index 84a1146..003bba5 100644
--- a/dojox/mobile/themes/iphone/Switch.less
+++ b/dojox/mobile/themes/iphone/Switch.less
@@ -1,4 +1,15 @@
- at import url("../common/Switch.css");
-
 @import "variables.less";
 @import "../common/Switch.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwRoundShape1-styles;
+}
+/* i0S 6 specific */
+.dj_ios6 {
+	.mblSwitchBgLeft {
+		background-color: #007fea;
+		.background-image-linear-gradient-top-bottom-2-stops(#0060b1, #73b3ea, 0.5, #007fea, 0.5, #218fec);
+	}
+}
+
diff --git a/dojox/mobile/themes/iphone/Switch_rtl-compat.css b/dojox/mobile/themes/iphone/Switch_rtl-compat.css
new file mode 100644
index 0000000..83956ee
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Switch_rtl-compat.css
@@ -0,0 +1,43 @@
+/* dojox.mobile.Switch Rtl */
+/* Square Shape Rtl */
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
+/* Round Shape1 Rtl */
+.mblSwRoundShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round1-l.gif);
+}
+/* Round Shape2 Rtl */
+.mblSwRoundShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round2-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round2-l.gif);
+}
+/* Arc Shape1 Rtl */
+.mblSwArcShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc1-r.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc1-l.gif);
+}
+/* Switch - Arc Shape2 Rtl */
+.mblSwArcShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc2-r.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc2-l.gif);
+}
+/* Default Shape Rtl */
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round1-l.gif);
+}
diff --git a/dojox/mobile/themes/iphone/Switch_rtl.css b/dojox/mobile/themes/iphone/Switch_rtl.css
new file mode 100644
index 0000000..aa98bfa
--- /dev/null
+++ b/dojox/mobile/themes/iphone/Switch_rtl.css
@@ -0,0 +1,117 @@
+/* dojox.mobile.Switch Rtl */
+/* Switch - common Rtl */
+.mblSwitchRtl {
+  text-align: right;
+}
+.mblListItemRtl .mblSwitch {
+  left: 12px;
+  right: auto;
+}
+.mblSwitchRtl.mblSwitchOn .mblSwitchInner {
+  left: -50px;
+}
+.mblSwitchBgLeftRtl {
+  left: 51px;
+}
+.mblSwitchTextLeftRtl {
+  left: 0px;
+}
+.mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Square Shape Rtl*/
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Round Shape1 Rtl */
+.mblSwitchRtl.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Round Shape2 Rtl */
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Arc Shape1 Rtl */
+.mblSwitchRtl.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Arc Shape2 Rtl */
+.mblSwitchRtl.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Default Shape Rtl */
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOn .mblSwitchInner {
+  left: -50px;
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  left: 50px;
+}
+.mblSwitchRtl.mblSwDefaultShape .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwDefaultShape .mblSwitchTextRightRtl {
+  left: -26px;
+}
diff --git a/dojox/mobile/themes/iphone/TabBar-compat.css b/dojox/mobile/themes/iphone/TabBar-compat.css
index 2e12529..ace7ac2 100644
--- a/dojox/mobile/themes/iphone/TabBar-compat.css
+++ b/dojox/mobile/themes/iphone/TabBar-compat.css
@@ -1,36 +1,62 @@
-/* dojox.mobile.TabBarButton */
-.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
-	left: auto;
-}
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
+/* dojox.mobile.TabBar */
 .dj_ie6 .mblTabBar .mblTabBarButton {
-  display: inline; /* IE bug*/
+  display: inline;
+}
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  background-image: none;
+  background-color: #000000;
 }
-.mblTabPanelHeader {
-	background-image: url(compat/heading-bg.png);
+.dj_ff3 .mblTabBarTabBar .mblTabBarButtonSelected {
+  -moz-border-radius: 3px;
 }
-.mblTabContainer .mblTabButton {
-	background-image: url(compat/tab-button-bg.png);
+/* barType="segmentedControl" | "standardTab" */
+.mblTabBarSegmentedControl,
+.mblTabBarStandardTab {
+  background-image: url(compat/heading-bg.png);
 }
-.mblTabContainer .mblTabButtonSelected {
-	background-image: url(compat/tab-sel-button-bg.png);
+.mblTabBarSegmentedControl .mblTabBarButton,
+.mblTabBarStandardTab .mblTabBarButton {
+  background-image: url(compat/tab-seg-button-bg.png);
 }
-*html .mblTabButton { /* IE6 hack */
-	behavior: expression(
-		(function(el){
-			if(!el.previousSibling)
-				el.style.borderWidth = "1px";
-			el.style.behavior = "none";
-		})(this)
-	);
+.mblTabBarSegmentedControl .mblTabBarButtonSelected,
+.mblTabBarStandardTab .mblTabBarButtonSelected {
+  background-image: url(compat/tab-seg-sel-button-bg.png);
 }
-.dj_ie6 .mblTabPanelHeader .mblDomButton {
-	left: 0px;
+.dj_gecko .mblTabBarSegmentedControl .mblTabBarButton {
+  -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.305);
 }
-.mblTabButton:first-child {
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:first-child {
   -moz-border-radius-topleft: 5px;
   -moz-border-radius-bottomleft: 5px;
 }
-.mblTabButton:last-child {
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:last-child {
   -moz-border-radius-topright: 5px;
   -moz-border-radius-bottomright: 5px;
 }
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButton {
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 4px;
+}
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  background-image: url(compat/tab-slim-bar-bg.png);
+}
+.dj_gecko .mblTabBarSlimTab {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.dj_gecko .mblTabBarSlimTab .mblTabBarButton {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.dj_gecko .mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-image: -moz-linear-gradient(top, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
+}
+/* barType="flatTab" */
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  background-image: url(compat/tab-tall-bar-bg.png);
+}
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-color: #8c8e8c;
+}
diff --git a/dojox/mobile/themes/iphone/TabBar-compat.less b/dojox/mobile/themes/iphone/TabBar-compat.less
new file mode 100644
index 0000000..c0476f3
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TabBar-compat.less
@@ -0,0 +1,3 @@
+ at import "variables.less";
+ at import "../common/TabBar-compat.less";
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
diff --git a/dojox/mobile/themes/iphone/TabBar.css b/dojox/mobile/themes/iphone/TabBar.css
index becc58a..d4f0d72 100644
--- a/dojox/mobile/themes/iphone/TabBar.css
+++ b/dojox/mobile/themes/iphone/TabBar.css
@@ -1,142 +1,280 @@
+ at import "../common/domButtons/DomButtonWhiteCross.css";
 /* dojox.mobile.TabBar */
 .mblTabBar {
   position: relative;
+  margin: 0px;
   overflow: hidden;
   white-space: nowrap;
-  margin: 0px;
-  padding: 0px;
-  height: 48px;
-  border-top: 1px solid #000000;
-  background-color: #000000;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
-  color: white;
+  text-overflow: ellipsis;
+  padding: 0px 6px;
+  height: 42px;
   text-align: center;
-}
-.mblTabBarNoIcons {
-  height: 34px;
-}
-.mblTabBarNoText {
-  height: 34px;
+  color: white;
+  border-top: 1px solid #cdd5df;
+  border-bottom: 1px solid #2d3642;
+  text-shadow: rgba(0, 0, 0, 0.6) 0 -1px 0;
 }
 /* dojox.mobile.TabBarButton */
+.mblTabBarFill .mblTabBarButton {
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
 .mblTabBarButton {
+  overflow: hidden;
   cursor: pointer;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-}
-.mblTabBar .mblTabBarButton {
   position: relative;
   list-style-type: none;
   float: left;
 }
-.mblTabBar .mblTabBarButton.mblTabButtonSelected {
-  -webkit-border-radius: 3px;
-  background-color: #404040;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424), color-stop(0.5, #353535), color-stop(0.5, #242424));
+.mblTabBarButtonIconArea {
+  margin: 0 auto;
+  width: 29px;
 }
-.mblTabBarButtonAnchor {
+.mblTabBarButtonIconParent1 {
   display: block;
-  text-decoration: none;
 }
-.mblTabBarButtonDiv {
-  position: relative;
-  margin-left: auto;
-  margin-right: auto;
-  height: 34px;
-  width: 29px;
+.mblTabBarButtonIconParent2 {
+  display: none;
 }
-.mblTabBarButtonIcon {
-  position: absolute;
-  left: 0px;
-  top: 2px;
+.mblTabBarButtonSelected .mblTabBarButtonIconParent1 {
+  display: none;
 }
-.mblTabBarButtonSpriteIcon {
-  position: absolute;
+.mblTabBarButtonSelected .mblTabBarButtonIconParent2 {
+  display: block;
 }
-.mblTabBarButtonTextBox {
-  color: #979797;
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  height: 48px;
+  border-top: 1px solid #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.mblTabBarTabBar .mblTabBarButtonIconArea {
+  padding-top: 4px;
+}
+.mblTabBarTabBar .mblTabBarButtonLabel {
   font-family: "Helvetica Neue", Helvetica;
   font-size: 11px;
+  color: #979797;
 }
-.mblTabBarNoIcons .mblTabBarButtonDiv {
-  display: none;
+.mblTabBarTabBar .mblTabBarButtonSelected {
+  border-radius: 3px;
+  background-color: #404040;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424), color-stop(0.5, #353535), color-stop(0.5, #242424));
+  background-image: linear-gradient(to bottom, #484848 0%, #353535 50%, #242424 50%, #242424 100%);
 }
-.mblTabBarNoIcons .mblTabBarButtonTextBox {
-  line-height: 34px;
-  font-size: 20px;
+.mblTabBarTabBar .mblTabBarButtonSelected .mblTabBarButtonLabel {
+  color: white;
 }
-.mblTabBarTop .mblTabButton .mblTabBarButtonDiv {
-  display: none;
+/* barType="segmentedControl" */
+.mblTabBarSegmentedControl {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), to(#6d84a2), color-stop(0.5, #889bb3), color-stop(0.5, #8195af));
+  background-image: linear-gradient(to bottom, #b0bccd 0%, #889bb3 50%, #8195af 50%, #6d84a2 100%);
 }
-.mblTabButton {
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButton {
+  width: auto;
+  padding: 0 3px;
+}
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconArea {
   position: relative;
-  float: left;
-  list-style-type: none;
-  cursor: pointer;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblTabBarSegmentedControl .mblTabBarButton {
+  margin: 6px 0;
   width: 100px;
-  height: 28px;
+  height: 29px;
   border-width: 1px 1px 1px 0px;
-  border-style: inset;
-  border-color: #9CACC0;
-  border-right-color: #5E708A;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#abb9ca), to(#788da9), color-stop(0.5, #8297af), color-stop(0.5, #768ba7));
   font-family: Helvetica;
   font-size: 13px;
-  color: white;
+  font-weight: bold;
   text-align: center;
   line-height: 29px;
+  border-style: solid;
+  border-color: #2f3740 #405a7e #375073 #3a4755;
+  color: #ffffff;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), to(#6d84a2), color-stop(0.5, #889bb3), color-stop(0.5, #8195af));
+  background-image: linear-gradient(to bottom, #b0bccd 0%, #889bb3 50%, #8195af 50%, #6d84a2 100%);
+  -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.305);
+  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.305);
 }
-.mblTabButton .mblTabBarButtonAnchor, .mblTabButton .mblTabBarButtonDiv {
-  height: 29px;
-}
-.mblTabButton:first-child {
-  -webkit-border-top-left-radius: 5px;
-  -webkit-border-bottom-left-radius: 5px;
+.mblTabBarSegmentedControl .mblTabBarButton:first-child {
   border-left-width: 1px;
+  border-top-left-radius: 5px;
+  border-bottom-left-radius: 5px;
 }
-.mblTabButton:last-child {
-  -webkit-border-top-right-radius: 5px;
-  -webkit-border-bottom-right-radius: 5px;
-  border-right-color: #9CACC0;
+.mblTabBarSegmentedControl .mblTabBarButton:last-child {
+  border-top-right-radius: 5px;
+  border-bottom-right-radius: 5px;
 }
-.mblTabButtonSelected .mblTabBarButtonTextBox {
-  color: white;
+.mblTabBarSegmentedControl .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
 }
-.mblTabButtonImgDiv {
-  display: none;
+.mblTabBarSegmentedControl .mblTabBarButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#222222), to(#4a6c9b), color-stop(0.02, #8ea4c1), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
+  background-image: linear-gradient(to bottom, #222222 0%, #8ea4c1 2%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
 }
-.mblTabPanelHeader {
-  position: relative;
-  overflow: hidden;
-  white-space: nowrap;
-  text-overflow: ellipsis;
-  margin: 0px;
-  padding: 3px 0px 0px 0px;
-  height: 39px;
-  border-top: 1px solid #CDD5DF;
-  border-bottom: 1px solid #2D3642;
-  background-color: #889BB3;
+.mblHeading .mblTabBarSegmentedControl {
+  display: inline;
+  float: left;
+  height: auto;
+  border: none;
+}
+/* barType="standardTab" */
+.mblTabBarStandardTab {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), to(#6d84a2), color-stop(0.5, #889bb3), color-stop(0.5, #8195af));
+  background-image: linear-gradient(to bottom, #b0bccd 0%, #889bb3 50%, #8195af 50%, #6d84a2 100%);
+}
+.mblTabBarStandardTab .mblTabBarButton {
+  margin-top: 9px;
+  padding: 9px;
+  border: 1px solid #62676d;
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  color: #ffffff;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), to(#6d84a2), color-stop(0.5, #889bb3), color-stop(0.5, #8195af));
+  background-image: linear-gradient(to bottom, #b0bccd 0%, #889bb3 50%, #8195af 50%, #6d84a2 100%);
+}
+.mblTabBarStandardTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 3px;
+  left: 0px;
+}
+.mblTabBarStandardTab .mblTabBarButtonSelected {
+  background-color: #5877a2;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#222222), to(#4a6c9b), color-stop(0.02, #8ea4c1), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
+  background-image: linear-gradient(to bottom, #222222 0%, #8ea4c1 2%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
+}
+.mblTabBarStandardTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  height: 30px;
+  padding: 0px;
+  border: 1px solid #2d3642;
+  background-color: #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.mblTabBarSlimTab .mblTabBarButton {
+  padding: 7px;
+  border-right: 1px solid #4e4e4e;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
   font-family: Helvetica;
-  font-size: 20px;
+  font-size: 14px;
+  font-weight: bold;
   color: white;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
+  text-align: center;
+}
+.mblTabBarSlimTab .mblTabBarButton:first-child {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+}
+.mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-color: #404040;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#313031), to(#959595), color-stop(0.5, #5a555a), color-stop(0.5, #616161));
+  background-image: linear-gradient(to bottom, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
+}
+.mblTabBarSlimTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="flatTab" */
+.mblTabBarFlatTab {
+  height: 30px;
+  padding: 0px;
+  border-style: none;
+  background-color: transparent;
+  background-image: none;
+}
+.mblTabBarFlatTab .mblTabBarButton {
+  padding: 7px;
+  background-image: none;
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
   text-align: center;
-  line-height: 44px;
-  text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
 }
-.mblTabPanelHeader .mblTabButton {
+.mblTabBarFlatTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+}
+.mblTabBarFlatTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  height: 64px;
+  border-top: 1px solid #cdd5df;
+  border-bottom: 2px solid #949694;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.mblTabBarTallTab .mblTabBarButton {
   margin-top: 3px;
+  margin-right: 2px;
+  width: 78px;
+  height: 61px;
+  border-width: 0px 1px 0px 1px;
+  border-style: solid;
+  border-color: black #182018 black #393c39;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100c10), color-stop(0.1, #313031));
+  background-image: linear-gradient(to bottom, #181818 0%, #313031 10%, #100c10 100%);
+  font-family: Helvetica;
+  font-size: 13px;
+  color: white;
+  text-align: center;
+  background-color: #212421;
+  background-image: none;
+}
+.mblTabBarTallTab .mblTabBarButtonIconArea {
+  margin-top: 8px;
+}
+.mblTabBarTallTab .mblTabBarButtonLabel {
+  font-family: "Helvetica Neue", Helvetica;
+  font-size: 11px;
+}
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#a59ea5), to(#848284));
+  background-image: linear-gradient(to bottom, #a59ea5 0%, #848284 100%);
+  background-color: #636363;
+  background-image: none;
+}
+/* iOS 6 specific */
+.dj_ios6.dj_phone .mblTabBarSegmentedControl {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d0d9e6), to(#587397), color-stop(0.025, #d0d9e6), color-stop(0.025, #beccdd));
+  background-image: linear-gradient(to bottom, #d0d9e6 0%, #d0d9e6 2.5%, #beccdd 2.5%, #587397 100%);
+}
+.dj_ios6.dj_phone .mblTabBarSegmentedControl .mblTabBarButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), to(#6d84a2));
+  background-image: linear-gradient(to bottom, #b0bccd 0%, #6d84a2 100%);
 }
-.mblTabPanelHeader .mblTabButton.mblTabButtonSelected {
-  background-color: #5877A2;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#8ea4c1), to(#4a6c9b), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
+.dj_ios6.dj_phone .mblTabBarSegmentedControl .mblTabBarButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#8ea4c1), to(#4a6c9b));
+  background-image: linear-gradient(to bottom, #8ea4c1 0%, #4a6c9b 100%);
 }
-.mblTabPanelHeader .mblTabButtonDomButton {
-  width: 43px;
+.dj_ios6.dj_phone .mblTabBarStandardTab {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d0d9e6), to(#587397), color-stop(0.025, #d0d9e6), color-stop(0.025, #beccdd));
+  background-image: linear-gradient(to bottom, #d0d9e6 0%, #d0d9e6 2.5%, #beccdd 2.5%, #587397 100%);
 }
-.mblTabPanelHeader .mblTabButtonDomButtonClass {
-  left: 8px;
+.dj_ios6.dj_phone .mblTabBarStandardTab .mblTabBarButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), to(#6d84a2));
+  background-image: linear-gradient(to bottom, #b0bccd 0%, #6d84a2 100%);
 }
-.mblHeading .mblTabPanelHeader .mblTabButton {
-  margin-top: 6px;
+.dj_ios6.dj_phone .mblTabBarStandardTab .mblTabBarButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#8ea4c1), to(#4a6c9b));
+  background-image: linear-gradient(to bottom, #8ea4c1 0%, #4a6c9b 100%);
 }
diff --git a/dojox/mobile/themes/iphone/TabBar.less b/dojox/mobile/themes/iphone/TabBar.less
index 4875c40..f8ff1b2 100644
--- a/dojox/mobile/themes/iphone/TabBar.less
+++ b/dojox/mobile/themes/iphone/TabBar.less
@@ -1,2 +1,24 @@
 @import "variables.less";
 @import "../common/TabBar.less";
+ at import "../common/domButtons/DomButtonWhiteCross.css";
+/* iOS 6 specific */
+.dj_ios6.dj_phone {
+	.mblTabBarSegmentedControl {
+		.background-image-linear-gradient-top-bottom-2-stops(#d0d9e6, #587397, 0.025, #d0d9e6, 0.025, #beccdd);
+		.mblTabBarButton {
+			.background-image-linear-gradient-top-bottom(#b0bccd, #6d84a2);
+		}
+		.mblTabBarButtonSelected {
+			.background-image-linear-gradient-top-bottom(#8ea4c1, #4a6c9b);
+		}
+	}
+	.mblTabBarStandardTab {
+		.background-image-linear-gradient-top-bottom-2-stops(#d0d9e6, #587397, 0.025, #d0d9e6, 0.025, #beccdd);
+		.mblTabBarButton {
+			.background-image-linear-gradient-top-bottom(#b0bccd, #6d84a2);
+		}
+		.mblTabBarButtonSelected {
+			.background-image-linear-gradient-top-bottom(#8ea4c1, #4a6c9b);
+		}
+	}
+}
diff --git a/dojox/mobile/themes/iphone/TabBar_rtl-compat.css b/dojox/mobile/themes/iphone/TabBar_rtl-compat.css
new file mode 100644
index 0000000..848279c
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TabBar_rtl-compat.css
@@ -0,0 +1,19 @@
+/* barType="segmentedControl" | "standardTab" Rtl */
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  -moz-border-radius-topright: 5px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-bottomright: 5px;
+  -moz-border-radius-bottomleft: 0px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  -moz-border-radius-topleft: 5px;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomleft: 5px;
+  -moz-border-radius-bottomright: 0px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButtonRtl {
+  -moz-border-radius-topright: 4px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 0px;
+}
diff --git a/dojox/mobile/themes/iphone/TabBar_rtl.css b/dojox/mobile/themes/iphone/TabBar_rtl.css
new file mode 100644
index 0000000..5553209
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TabBar_rtl.css
@@ -0,0 +1,89 @@
+/* dojox.mobile.TabBarButton Rtl */
+.mblTabBarButtonRtl {
+  float: right;
+}
+.mblTabBarButtonIconAreaRtl {
+  margin: 0 auto;
+  width: 29px;
+}
+/* barType="tabBar" Rtl */
+.mblTabBarTabBar .mblTabBarButtonIconAreaRtl {
+  padding-top: 4px;
+}
+/* barType="segmentedControl" Rtl */
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconAreaRtl {
+  position: relative;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl {
+  border-width: 1px 0px 1px 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  border-right-width: 1px !important;
+  border-left-width: 0px;
+  border-top-right-radius: 5px;
+  border-top-left-radius: 0px;
+  border-bottom-right-radius: 5px;
+  border-bottom-left-radius: 0px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  border-top-left-radius: 5px;
+  border-top-right-radius: 0px;
+  border-bottom-left-radius: 5px;
+  border-bottom-right-radius: 0px;
+  border-left-width: 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblHeading .mblTabBarSegmentedControl.mblTabBarRtl {
+  float: right;
+}
+/* barType="standardTab" Rtl */
+.mblTabBarStandardTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 3px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarStandardTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="slimTab" Rtl */
+.mblTabBarSlimTab .mblTabBarButtonRtl {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl:first-child {
+  border-right: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="flatTab" Rtl*/
+.mblTabBarFlatTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarFlatTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab .mblTabBarButtonRtl {
+  margin-left: 2px;
+}
+.mblTabBarTallTab .mblTabBarButtonIconAreaRtl {
+  margin-top: 8px;
+}
diff --git a/dojox/mobile/themes/iphone/TextArea-compat.css b/dojox/mobile/themes/iphone/TextArea-compat.css
index af7e363..78b7029 100644
--- a/dojox/mobile/themes/iphone/TextArea-compat.css
+++ b/dojox/mobile/themes/iphone/TextArea-compat.css
@@ -1,7 +1,7 @@
 /* dojox.mobile.TextArea */
 .mblTextArea {
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
+  overflow: auto;
+}
+.dj_ff3 .mblTextArea {
+  -moz-border-radius: 5px;
 }
diff --git a/dojox/mobile/themes/iphone/TextArea.css b/dojox/mobile/themes/iphone/TextArea.css
index 0768622..295337d 100644
--- a/dojox/mobile/themes/iphone/TextArea.css
+++ b/dojox/mobile/themes/iphone/TextArea.css
@@ -1,12 +1,12 @@
 /* dojox.mobile.TextArea */
 .mblTextArea {
   padding: 4px 1px;
-  border-color: #9CACC0;
   border-width: 1px;
   border-style: inset;
-  -webkit-border-radius: 5px;
   font-family: Helvetica;
   font-size: 13px;
+  border-color: #9cacc0;
+  border-radius: 5px;
 }
 /* dojox.mobile.ExpandingTextArea */
 .mblExpandingTextArea {
diff --git a/dojox/mobile/themes/iphone/TextArea.less b/dojox/mobile/themes/iphone/TextArea.less
deleted file mode 100644
index c16ffe0..0000000
--- a/dojox/mobile/themes/iphone/TextArea.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/TextArea.less";
diff --git a/dojox/mobile/themes/iphone/TextBox-compat.css b/dojox/mobile/themes/iphone/TextBox-compat.css
index 32dcf46..c8d4c48 100644
--- a/dojox/mobile/themes/iphone/TextBox-compat.css
+++ b/dojox/mobile/themes/iphone/TextBox-compat.css
@@ -1,7 +1,4 @@
 /* dojox.mobile.TextBox */
-.mblTextBox {
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
+.dj_ff3 .mblTextBox {
+  -moz-border-radius: 5px;
 }
diff --git a/dojox/mobile/themes/iphone/TextBox.css b/dojox/mobile/themes/iphone/TextBox.css
index d87404e..fb6a2aa 100644
--- a/dojox/mobile/themes/iphone/TextBox.css
+++ b/dojox/mobile/themes/iphone/TextBox.css
@@ -1,8 +1,10 @@
 /* dojox.mobile.TextBox */
 .mblTextBox {
   height: 22px;
-  border: #9CACC0 1px inset;
-  -webkit-border-radius: 5px;
+  border-width: 1px;
+  border-style: inset;
   font-family: Helvetica;
   font-size: 13px;
+  border-color: #9cacc0;
+  border-radius: 5px;
 }
diff --git a/dojox/mobile/themes/iphone/TextBox.less b/dojox/mobile/themes/iphone/TextBox.less
deleted file mode 100644
index c83890a..0000000
--- a/dojox/mobile/themes/iphone/TextBox.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/TextBox.less";
diff --git a/dojox/mobile/themes/iphone/TimePicker.css b/dojox/mobile/themes/iphone/TimePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/iphone/TimePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/iphone/ToggleButton-compat.css b/dojox/mobile/themes/iphone/ToggleButton-compat.css
index 75bfb32..4febb1b 100644
--- a/dojox/mobile/themes/iphone/ToggleButton-compat.css
+++ b/dojox/mobile/themes/iphone/ToggleButton-compat.css
@@ -1,30 +1,42 @@
 /* dojox.mobile.ToggleButton */
 .mblToggleButton {
-	background-image: url(compat/button-bg.png);
-	-moz-border-radius: 5px;
-	-o-border-radius: 5px;
-	-ms-border-radius: 5px;
-	border-radius: 5px;
+  background-image: url(compat/button-bg.png);
 }
 .mblToggleButtonSelected {
-	background-image: url(compat/button-sel-bg.png);
+  background-image: url(compat/button-sel-bg.png);
 }
 .mblToggleButtonChecked {
-	background-image: url(compat/blue-button-bg.png);
-}
-.mblToggleButton.mblToggleButtonChecked::after {
-	-moz-transform: translate(-25px,0px) rotate(45deg) skew(10deg);
-	-o-transform: rotate(45deg) skew(10deg);
-	-ms-transform: rotate(45deg) skew(10deg);
-	transform: rotate(45deg) skew(10deg);
-	-moz-transform-origin: 50% 50%;
-	-o-transform-origin: 50% 50%;
-	-ms-transform-origin: 50% 50%;
-	transform-origin: 50% 50%;
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblToggleButton {
+  background-image: -moz-linear-gradient(top, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+}
+.dj_gecko .mblToggleButtonSelected {
+  background-image: -moz-linear-gradient(top, #f0f0f0 0%, #ebebeb 50%, #dedede 50%, #bfbfbf 100%);
+}
+.dj_gecko .mblToggleButtonChecked {
+  background-image: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblToggleButtonChecked:after {
+  -moz-transform: rotate(45deg) skew(10deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: -moz-linear-gradient(top, #8ea4c1 0%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
+}
+.dj_ff3 .mblToggleButton {
+  -moz-border-radius: 5px;
 }
 .dj_ff3 .mblToggleButton.mblToggleButtonChecked::after {
-	-moz-transform: translate(-25px,-6px) rotate(45deg) skew(10deg);
+  -moz-transform: translate(-25px, -6px) rotate(45deg) skew(10deg);
 }
-.mblToggleButtonChecked.mblToggleButtonSelected {
-	background-image: url(compat/blue-button-sel-bg.png);
+.dj_ie .mblToggleButtonChecked:after {
+  top: 9px;
+  left: 5px;
+  width: 12px;
+  border: none;
+  background-image: url(compat/togglebutton-chk-mark-bg.png);
 }
diff --git a/dojox/mobile/themes/iphone/ToggleButton.css b/dojox/mobile/themes/iphone/ToggleButton.css
index 17e7295..0309bc3 100644
--- a/dojox/mobile/themes/iphone/ToggleButton.css
+++ b/dojox/mobile/themes/iphone/ToggleButton.css
@@ -1,52 +1,52 @@
 /* dojox.mobile.ToggleButton */
 .mblToggleButton {
   position: relative;
-  cursor: pointer;
-  outline: none;
-  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-  padding: 0px 10px 0px 25px;
+  padding: 0 10px 0 25px;
   height: 29px;
   border-width: 1px 1px 1px 1px;
   border-style: outset;
-  border-color: #9CACC0;
-  -webkit-border-radius: 5px;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#cecece), color-stop(0.5, #f8f8f8), color-stop(0.5, #eeeeee));
+  background-image: linear-gradient(to bottom, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
   font-family: Helvetica;
+  line-height: 29px;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  border-color: #9cacc0;
+  border-radius: 5px;
   font-size: 13px;
   color: black;
-  line-height: 29px;
 }
-.mblToggleButton.mblToggleButtonSelected {
+.mblToggleButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
+}
+.mblToggleButtonSelected {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0), to(#bfbfbf), color-stop(0.5, #ebebeb), color-stop(0.5, #dedede));
-  color: black;
+  background-image: linear-gradient(to bottom, #f0f0f0 0%, #ebebeb 50%, #dedede 50%, #bfbfbf 100%);
 }
-.mblToggleButton.mblToggleButtonChecked {
+.mblToggleButtonChecked {
   background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
   color: white;
 }
-.mblToggleButton.mblToggleButtonChecked::after {
+.mblToggleButtonChecked:after {
   position: absolute;
   content: "";
   top: 6px;
   left: 7px;
   width: 5px;
   height: 10px;
-  border-color: white;
   border-width: 2px;
   border-style: none solid solid none;
   -webkit-transform: rotate(45deg) skew(10deg);
+  transform: rotate(45deg) skew(10deg);
   -webkit-transform-origin: 50% 50%;
-}
-.mblToggleButton.mblToggleButtonChecked.mblToggleButtonSelected {
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#8ea4c1), to(#4a6c9b), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
-  color: white;
-}
-.mblToggleButton.mblToggleButtonChecked.mblToggleButtonSelected::after {
+  transform-origin: 50% 50%;
   border-color: white;
 }
-.mblToggleButton:disabled {
-  cursor: default;
-  border-color: grey;
-  background-image: none;
-  color: grey;
+.mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#8ea4c1), to(#4a6c9b), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
+  background-image: linear-gradient(to bottom, #8ea4c1 0%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
 }
diff --git a/dojox/mobile/themes/iphone/ToggleButton.less b/dojox/mobile/themes/iphone/ToggleButton.less
deleted file mode 100644
index bdce40f..0000000
--- a/dojox/mobile/themes/iphone/ToggleButton.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/ToggleButton.less";
diff --git a/dojox/mobile/themes/iphone/ToggleButton_rtl.css b/dojox/mobile/themes/iphone/ToggleButton_rtl.css
new file mode 100644
index 0000000..16d136f
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ToggleButton_rtl.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.ToggleButton Rtl */
+.mblToggleButtonRtl {
+  padding: 0 25px 0 10px!important;
+}
+.mblToggleButtonRtl.mblToggleButtonChecked:after {
+  right: 7px;
+}
diff --git a/dojox/mobile/themes/iphone/ToolBarButton-compat.css b/dojox/mobile/themes/iphone/ToolBarButton-compat.css
new file mode 100644
index 0000000..b3515c7
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ToolBarButton-compat.css
@@ -0,0 +1,72 @@
+/* dojox.mobile.ToolBarButton */
+.dj_gecko .mblToolBarButtonArrow {
+  -moz-transform: scale(0.77, 1.05) rotate(45deg);
+}
+.dj_gecko .mblHeading .mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.305);
+}
+.dj_gecko .mblHeading .mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  -moz-box-shadow: 1px 0 0 rgba(255, 255, 255, 0.305);
+}
+.dj_gecko .mblHeading .mblToolBarButtonBody {
+  -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.305);
+}
+.dj_ff3 .mblToolBarButtonArrow {
+  -moz-border-radius: 1px;
+}
+.dj_ff3 .mblToolBarButtonBody {
+  -moz-border-radius: 5px;
+}
+.dj_ff3 .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  -moz-border-radius-topleft: 0;
+  -moz-border-radius-bottomleft: 0;
+}
+.dj_ff3 .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 0;
+}
+.dj_ie .mblToolBarButtonLeftArrow {
+  top: 0;
+  left: -2px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonLeftArrow {
+  background-image: url(compat/arrow-button-head-sel.png);
+}
+.dj_ie .mblToolBarButtonRightArrow {
+  top: 0;
+  right: -3px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-right-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonRightArrow {
+  background-image: url(compat/arrow-button-right-head-sel.png);
+}
+.dj_ie .mblToolBarButtonBody {
+  background-image: url(compat/arrow-button-bg.png);
+  background-position: left bottom;
+}
+.dj_ie .mblToolBarButtonBodySelected {
+  background-image: url(compat/arrow-button-bg-sel.png);
+}
+.dj_ie .mblToolBarButtonBody table {
+  margin: 0;
+}
+.dj_ie .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.dj_ie .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.dj_ie6 .mblToolBarButton .mblToolBarButtonBody {
+  background-position: left top;
+}
diff --git a/dojox/mobile/themes/iphone/ToolBarButton.css b/dojox/mobile/themes/iphone/ToolBarButton.css
index 7299e04..c1ca1da 100644
--- a/dojox/mobile/themes/iphone/ToolBarButton.css
+++ b/dojox/mobile/themes/iphone/ToolBarButton.css
@@ -1,28 +1,110 @@
 /* dojox.mobile.ToolBarButton */
 .mblToolBarButton {
-  float: left;
+  display: inline-block;
   position: relative;
-  overflow: hidden;
   cursor: pointer;
   -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
   margin: 6px;
+  padding: 0 10px;
   height: 29px;
-  border: 1px inset #9CACC0;
+  line-height: 29px;
+  text-align: center;
   font-family: Helvetica;
   font-size: 13px;
   font-weight: bold;
-  color: white;
-  line-height: 29px;
-  text-align: center;
-  -webkit-border-radius: 5px;
-  -moz-border-radius: 5px;
+  vertical-align: middle;
 }
-.mblToolBarButtonIcon {
-  position: relative;
+.mblToolBarButtonHasIcon,
+.mblToolBarButtonLightIcon {
+  padding: 0;
+}
+.mblHeading .mblToolBarButton {
+  float: left;
+}
+.mblHeading span.mblToolBarButtonLightIcon {
+  padding: 0;
+}
+.mblToolBarButtonHasLeftArrow {
+  padding-right: 0;
+  padding-left: 10px;
+}
+.mblToolBarButtonHasRightArrow {
+  padding-left: 0;
+  padding-right: 10px;
 }
-.mblToolBarButtonSpriteIcon {
+.mblToolBarButtonArrow {
   position: absolute;
+  top: 5px;
+  width: 20px;
+  height: 19px;
+  -webkit-transform: scale(0.75, 1) rotate(45deg);
+  transform: scale(0.75, 1) rotate(45deg);
+  border: 1px solid #9cacc0;
+  border-top-left-radius: 1px;
+  border-bottom-right-radius: 1px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: 1px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: 0px;
+}
+.mblHeading .mblToolBarButtonArrow {
+  border-width: 1px;
+  border-style: solid;
+  border-color: #405a7e #405a7e #3a4755 #3a4755;
+}
+.mblHeading .mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.305);
+  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.305);
+}
+.mblHeading .mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  -webkit-box-shadow: 1px 0 0 rgba(255, 255, 255, 0.305);
+  box-shadow: 1px 0 0 rgba(255, 255, 255, 0.305);
+}
+.mblToolBarButtonBody {
+  display: inline-block;
+  position: relative;
+  overflow: hidden;
+  border-radius: 5px;
+  border: 1px outset #9cacc0;
+}
+.mblToolBarButton .mblToolBarButtonBody {
+  width: 100%;
+}
+.mblHeading .mblToolBarButtonBody {
+  border-width: 1px;
+  border-style: solid;
+  border-color: #2f3740 #405a7e #375073 #3a4755;
+  -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.305);
+  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.305);
+}
+.mblToolBarButtonBody table {
+  margin: 0 auto;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-left-width: 0;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-right-width: 0;
+}
+.mblToolBarButtonText .mblToolBarButtonIcon {
+  padding-left: 10px;
+}
+.mblToolBarButtonText .mblToolBarButtonLabel {
+  padding-right: 10px;
+  height: 29px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonIcon {
+  padding-left: 4px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonLabel {
+  padding-right: 4px;
+}
+.mblToolBarButtonIcon > div {
+  height: 29px;
 }
-.mblToolBarButtonText {
-  padding: 0px 10px;
+/* iOS 6 specific */
+.dj_ios6.dj_phone .mblHeading .mblToolBarButtonBody {
+  border-color: #343a42 #425167 #2f4769 #415066;
 }
diff --git a/dojox/mobile/themes/iphone/ToolBarButton.less b/dojox/mobile/themes/iphone/ToolBarButton.less
index 3b67bdc..cdb87c2 100644
--- a/dojox/mobile/themes/iphone/ToolBarButton.less
+++ b/dojox/mobile/themes/iphone/ToolBarButton.less
@@ -1,2 +1,10 @@
 @import "variables.less";
 @import "../common/ToolBarButton.less";
+/* iOS 6 specific */
+.dj_ios6.dj_phone {
+	.mblHeading {
+		.mblToolBarButtonBody {
+			border-color: #343a42 #425167 #2f4769 #415066;
+		}
+	}
+}
diff --git a/dojox/mobile/themes/iphone/ToolBarButton_rtl.css b/dojox/mobile/themes/iphone/ToolBarButton_rtl.css
new file mode 100644
index 0000000..4c54f0d
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ToolBarButton_rtl.css
@@ -0,0 +1,18 @@
+/* dojox.mobile.ToolBarButton Rtl */
+.mblHeading .mblToolBarButtonRtl {
+  float: right;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonIcon {
+  padding-right: 10px;
+  padding-left: 0px;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonLabel {
+  padding-left: 10px;
+  padding-right: 0px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: 1px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: 0px;
+}
diff --git a/dojox/mobile/themes/iphone/Tooltip-compat.css b/dojox/mobile/themes/iphone/Tooltip-compat.css
index 18b2623..66a468e 100644
--- a/dojox/mobile/themes/iphone/Tooltip-compat.css
+++ b/dojox/mobile/themes/iphone/Tooltip-compat.css
@@ -1,41 +1,47 @@
 /* dojox.mobile.Tooltip */
 .mblTooltip {
-	-moz-border-radius: 8px;
-	-o-border-radius: 8px;
-	-ms-border-radius: 8px;
-	border-radius: 8px;
-	background-image: none;
+  background-image: none;
 }
-.mblTooltipBefore .mblTooltipArrow {
-	*right: 0; /* IE 7 quirks */
-}
-.mblTooltipAbove .mblTooltipArrow {
-	*bottom: 0px; /* IE 7 quirks */
-}
-.mblTooltipBefore .mblTooltipInnerArrow {
-	*right: -1px; /* IE 7 quirks */
-}
-.mblTooltipAbove .mblTooltipInnerArrow {
-	*bottom: -1px;  /* IE 7 quirks */
+.mblTooltip .mblHeading {
+  background-image: url(compat/tooltip-heading-bg.png);
 }
-.mblTooltipAbove .mblTooltipInnerArrow {
-	border-bottom-color: #172035;
+.mblTooltip .mblHeading .mblToolBarButton {
+  background-color: #000924;
+  background-image: url(compat/tooltip-button-bg.png);
 }
-.mblTooltip .mblHeading {
-	background-image: url(compat/tooltip-heading-bg.png);
-	*padding: 0 9px 9px;
-	*border-top: 1px solid #4F5055;
-	*border-bottom: 1px solid #2D3642;
-	*width: auto;
-	*height: auto;
-	*overflow: visible;
-	*line-height: normal;
+.dj_ff3 .mblTooltip {
+  -moz-border-radius: 8px;
 }
 .dj_ie9 .mblTooltip .mblHeading {
-	width: auto;
-}
-.mblTooltip .mblHeading .mblToolBarButton {
-	background-color: #000924;
-	background-image: url(compat/tooltip-button-bg.png);
-	*margin: auto 6px;
+  width: auto;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipArrow {
+  right: 0;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipArrow {
+  bottom: 0;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipInnerArrow {
+  right: -1px;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipInnerArrow {
+  bottom: -1px;
+}
+.dj_ie6 .mblTooltip .mblHeading,
+.dj_ie7 .mblTooltip .mblHeading {
+  padding: 0 9px 12px;
+  border-top: 1px solid #889bb3;
+  border-bottom: 1px solid #889bb3;
+  width: auto;
+  height: auto;
+  overflow: visible;
+  line-height: normal;
+}
+.dj_ie6 .mblTooltip .mblHeading .mblToolBarButton,
+.dj_ie7 .mblTooltip .mblHeading .mblToolBarButton {
+  margin: auto 6px;
 }
diff --git a/dojox/mobile/themes/iphone/Tooltip.css b/dojox/mobile/themes/iphone/Tooltip.css
index cfe2db4..4e220cf 100644
--- a/dojox/mobile/themes/iphone/Tooltip.css
+++ b/dojox/mobile/themes/iphone/Tooltip.css
@@ -5,11 +5,14 @@
   display: block;
   margin: 0;
   padding: 5px;
-  border: #5A5A5A 1px solid;
-  background-color: #121B2F;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#656872), to(#121b2f), color-stop(0.1, #2c3345), color-stop(0.1, #161f32));
-  -webkit-border-radius: 8px;
+  border-width: 1px;
+  border-style: solid;
   opacity: .97;
+  border-color: #5a5a5a;
+  border-radius: 8px;
+  background-color: #121b2f;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#656872), to(#121b2f), color-stop(0.1, #2c3345), color-stop(0.1, #161f32));
+  background-image: linear-gradient(to bottom, #656872 0%, #2c3345 10%, #161f32 10%, #121b2f 100%);
 }
 .mblTooltipBubble {
   overflow: visible;
@@ -74,7 +77,7 @@
   top: 0;
   bottom: auto;
   border-left-width: 0;
-  border-right-color: #5A5A5A;
+  border-right-color: #5a5a5a;
 }
 .mblTooltipAfter .mblTooltipArrow {
   left: 1px;
@@ -82,7 +85,7 @@
   top: 0;
   bottom: auto;
   border-right-width: 0;
-  border-left-color: #5A5A5A;
+  border-left-color: #5a5a5a;
 }
 .mblTooltipAbove .mblTooltipArrow {
   top: auto;
@@ -90,7 +93,7 @@
   left: auto;
   right: auto;
   border-top-width: 0;
-  border-bottom-color: #5A5A5A;
+  border-bottom-color: #5a5a5a;
 }
 .mblTooltipBelow .mblTooltipArrow {
   top: 1px;
@@ -98,7 +101,7 @@
   left: auto;
   right: auto;
   border-bottom-width: 0;
-  border-top-color: #5A5A5A;
+  border-top-color: #5a5a5a;
 }
 .mblTooltipInnerArrow {
   position: absolute;
@@ -131,20 +134,27 @@
   border-bottom-width: 0;
   border-top-color: #172035;
 }
-.mblTooltipHidden, .mblTooltipHidden * {
+.mblTooltipHidden,
+.mblTooltipHidden * {
   visibility: hidden !important;
 }
+.mblTooltipHidden {
+  top: -99999px !important;
+  left: -99999px !important;
+}
 .mblTooltip .mblHeading {
-  border-top: 3px solid #4F5055;
-  border-bottom: 1px solid #2D3642;
-  border-left: 1px solid #2A2D47;
-  -webkit-border-radius: 3px 3px 0 0;
-  background-color: #889BB3;
+  border-top: 3px solid #4f5055;
+  border-bottom: 1px solid #2d3642;
+  border-left: 1px solid #2a2d47;
+  border-radius: 3px 3px 0 0;
+  background-color: #889bb3;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#5e6167), to(#1a1d24), color-stop(0.5, #2e322b));
+  background-image: linear-gradient(to bottom, #5e6167 0%, #2e322b 50%, #1a1d24 100%);
   font-weight: normal;
 }
 .mblTooltip .mblHeading .mblToolBarButton {
   border: 1px inset #434450;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#686f80), to(#000924), color-stop(0.5, #000b29));
+  background-image: linear-gradient(to bottom, #686f80 0%, #000b29 50%, #000924 100%);
   font-weight: normal;
 }
diff --git a/dojox/mobile/themes/iphone/Tooltip.less b/dojox/mobile/themes/iphone/Tooltip.less
deleted file mode 100644
index 60af6d1..0000000
--- a/dojox/mobile/themes/iphone/Tooltip.less
+++ /dev/null
@@ -1,2 +0,0 @@
- at import "variables.less";
- at import "../common/Tooltip.less";
diff --git a/dojox/mobile/themes/iphone/ValuePicker-compat.css b/dojox/mobile/themes/iphone/ValuePicker-compat.css
new file mode 100644
index 0000000..9eb8f76
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ValuePicker-compat.css
@@ -0,0 +1,19 @@
+/* dojox.mobile.ValuePicker */
+.mblValuePickerSlotButton {
+  background-image: url(compat/valuepicker-button-bg.png);
+}
+.mblValuePickerSlotButtonSelected {
+  background-color: #394d77;
+}
+.mblValuePickerSlotInputArea {
+  background-color: #f7f7f7;
+}
+.dj_gecko .mblValuePickerSlotButton {
+  background-image: -moz-linear-gradient(top, #9cb1c9 10%, #f0f1f5 35%, #f0f1f5 65%, #9cb1c9 90%);
+}
+.dj_gecko .mblValuePickerSlotButtonSelected {
+  background-image: -moz-linear-gradient(top, #7c87a4 0%, #394d77 50%, #243b69 50%, #263e6c 100%);
+}
+.dj_gecko .mblValuePickerSlotInputArea {
+  background-image: -moz-linear-gradient(top, #eaeaea 10%, #fafafa 20%, #ffffff 50%, #efefef 90%);
+}
diff --git a/dojox/mobile/themes/iphone/ValuePicker.css b/dojox/mobile/themes/iphone/ValuePicker.css
new file mode 100644
index 0000000..39aa4d7
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ValuePicker.css
@@ -0,0 +1,60 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+/* dojox.mobile.ValuePicker */
+.mblValuePicker {
+  height: 126px;
+}
+/* dojox.mobile.ValuePickerSlot */
+.mblValuePicker > .mblValuePickerSlot {
+  float: left;
+  margin: 0 3px;
+  border-left: solid 2px #000000;
+  border-right: solid 2px #000000;
+  border-radius: 3px;
+}
+.mblValuePickerSlotButton {
+  position: relative;
+  height: 38px;
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.1, #9cb1c9), color-stop(0.35, #f0f1f5), color-stop(0.65, #f0f1f5), color-stop(0.9, #9cb1c9));
+  background-image: linear-gradient(to bottom, #9cb1c9 10%, #f0f1f5 35%, #f0f1f5 65%, #9cb1c9 90%);
+}
+.mblValuePickerSlotPlusButton {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+}
+.mblValuePickerSlotMinusButton {
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.mblValuePickerSlotButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#7c87a4), to(#263e6c), color-stop(0.5, #394d77), color-stop(0.5, #243b69));
+  background-image: linear-gradient(to bottom, #7c87a4 0%, #394d77 50%, #243b69 50%, #263e6c 100%);
+}
+.mblValuePickerSlotIcon {
+  top: 5px;
+  margin: 0 auto;
+}
+.mblValuePickerSlotInputArea {
+  position: relative;
+  height: 48px;
+  border-top: 1px solid #7b797b;
+  border-bottom: 1px solid #c6c3c6;
+  background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0.1, #eaeaea), color-stop(0.2, #fafafa), color-stop(0.5, #ffffff), color-stop(0.9, #efefef));
+  background-image: linear-gradient(to bottom, #eaeaea 10%, #fafafa 20%, #ffffff 50%, #efefef 90%);
+}
+.mblValuePickerSlotInput {
+  display: block;
+  width: 90%;
+  height: 90%;
+  margin: 5% auto;
+  padding: 0;
+  text-align: center;
+  border-style: none;
+  background-color: transparent;
+  font: bold 24px/44px Helvetica, sans-serif;
+}
+/* dojox.mobile.ValuePickerTimePicker */
+.mblValuePickerTimePicker > .mblToolBarButton {
+  top: 45px;
+}
diff --git a/dojox/mobile/themes/iphone/ValuePicker.less b/dojox/mobile/themes/iphone/ValuePicker.less
new file mode 100644
index 0000000..1561b85
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ValuePicker.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+
+ at import "variables.less";
+ at import "../common/ValuePicker.less";
diff --git a/dojox/mobile/themes/iphone/base-compat.css b/dojox/mobile/themes/iphone/base-compat.css
index d12cf2b..da51ed5 100644
--- a/dojox/mobile/themes/iphone/base-compat.css
+++ b/dojox/mobile/themes/iphone/base-compat.css
@@ -1,4 +1,6 @@
+ at import url("common-compat.css");
 @import url("Heading-compat.css");
+ at import url("ToolBarButton-compat.css");
 @import url("RoundRect-compat.css");
 @import url("RoundRectList-compat.css");
 @import url("EdgeToEdgeCategory-compat.css");
diff --git a/dojox/mobile/themes/iphone/base_rtl-compat.css b/dojox/mobile/themes/iphone/base_rtl-compat.css
new file mode 100644
index 0000000..71390e0
--- /dev/null
+++ b/dojox/mobile/themes/iphone/base_rtl-compat.css
@@ -0,0 +1,3 @@
+ at import url("ListItem_rtl-compat.css");
+
+ at import url("Switch_rtl-compat.css");
diff --git a/dojox/mobile/themes/iphone/base_rtl.css b/dojox/mobile/themes/iphone/base_rtl.css
new file mode 100644
index 0000000..16f6b6c
--- /dev/null
+++ b/dojox/mobile/themes/iphone/base_rtl.css
@@ -0,0 +1,7 @@
+ at import url("ToolBarButton_rtl.css");
+
+ at import url("RoundRectCategory_rtl.css");
+
+ at import url("ListItem_rtl.css");
+
+ at import url("Switch_rtl.css");
diff --git a/dojox/mobile/themes/iphone/common-compat.css b/dojox/mobile/themes/iphone/common-compat.css
new file mode 100644
index 0000000..124ffa4
--- /dev/null
+++ b/dojox/mobile/themes/iphone/common-compat.css
@@ -0,0 +1,18 @@
+.dj_gecko .mblColorBlue {
+  background-image: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblColorBlue45 {
+  background-image: -moz-linear-gradient(top left, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.dj_gecko .mblColorDefault {
+  background-image: -moz-linear-gradient(top, #222222 0%, #8ea4c1 2%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
+}
+.dj_gecko .mblColorDefault45 {
+  background-image: -moz-linear-gradient(top left, #222222 0%, #8ea4c1 2%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
+}
+.dj_gecko .mblColorDefaultSel {
+  background-image: -moz-linear-gradient(top, #7c87a4 0%, #394d77 50%, #243b69 50%, #263e6c 100%);
+}
+.dj_gecko .mblColorDefaultSel45 {
+  background-image: -moz-linear-gradient(top left, #7c87a4 0%, #394d77 50%, #243b69 50%, #263e6c 100%);
+}
diff --git a/dojox/mobile/themes/iphone/common.css b/dojox/mobile/themes/iphone/common.css
index f2859e0..9ede24b 100644
--- a/dojox/mobile/themes/iphone/common.css
+++ b/dojox/mobile/themes/iphone/common.css
@@ -1,26 +1,103 @@
-html.mobile, .mobile body {
+html.mobile,
+.mobile body {
   width: 100%;
-  margin: 0px;
-  padding: 0px;
+  margin: 0;
+  padding: 0;
 }
 .mobile body {
   overflow-x: hidden;
   -webkit-text-size-adjust: none;
-  background-color: #c5ccd3;
   font-family: Helvetica;
   font-size: 17px;
 }
+.mblBackground {
+  background-color: #c5ccd3;
+}
 /* Button Colors */
 .mblColorBlue {
-  background-color: #366EDF;
+  color: #ffffff;
+  background-color: #366edf;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+}
+.mblColorBlue45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#7a9de9), to(#2362dd), color-stop(0.5, #366edf), color-stop(0.5, #215fdc));
+  background-image: linear-gradient(to right bottom, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
 }
 /* Default Button Colors */
 .mblColorDefault {
-  background-color: #5877A2;
-  background-image: -webkit-gradient(linear, left top, left bottom, from(#8ea4c1), to(#4a6c9b), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
+  color: #ffffff;
+  background-color: #5877a2;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#222222), to(#4a6c9b), color-stop(0.02, #8ea4c1), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
+  background-image: linear-gradient(to bottom, #222222 0%, #8ea4c1 2%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
+}
+.mblColorDefault45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#222222), to(#4a6c9b), color-stop(0.02, #8ea4c1), color-stop(0.5, #5877a2), color-stop(0.5, #476999));
+  background-image: linear-gradient(to right bottom, #222222 0%, #8ea4c1 2%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
 }
 .mblColorDefaultSel {
-  background-color: #394D77;
+  color: #ffffff;
+  background-color: #394d77;
   background-image: -webkit-gradient(linear, left top, left bottom, from(#7c87a4), to(#263e6c), color-stop(0.5, #394d77), color-stop(0.5, #243b69));
+  background-image: linear-gradient(to bottom, #7c87a4 0%, #394d77 50%, #243b69 50%, #263e6c 100%);
+}
+.mblColorDefaultSel45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#7c87a4), to(#263e6c), color-stop(0.5, #394d77), color-stop(0.5, #243b69));
+  background-image: linear-gradient(to right bottom, #7c87a4 0%, #394d77 50%, #243b69 50%, #263e6c 100%);
+}
+.mblSpriteIcon {
+  position: absolute;
+}
+.mblSpriteIconParent {
+  position: relative;
+  font-size: 1px;
+}
+.mblImageIcon {
+  vertical-align: top;
+}
+/* iOS 6 specific */
+.dj_ios6 .mblColorBlue {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#89abec), to(#2057c1));
+  background-image: linear-gradient(to bottom, #89abec 0%, #2057c1 100%);
+}
+.dj_ios6 .mblColorBlue45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#89abec), to(#2057c1));
+  background-image: linear-gradient(to right bottom, #89abec 0%, #2057c1 100%);
+}
+.dj_ios6.dj_phone {
+  /* mblColorBlue also defined here to correctly show up in openers */
+
+}
+.dj_ios6.dj_phone body {
+  background-color: #d7dce5;
+}
+.dj_ios6.dj_phone body.mblIOS6Stripes {
+  /* Vertical stripes on webkit */
+
+  background-image: -webkit-gradient(linear, left top, right top, from(transparent), to(#d4d9e3), color-stop(0.7, transparent), color-stop(0.7, #d4d9e3));
+  background-size: 8px 8px;
+}
+.dj_ios6.dj_phone .mblColorDefault {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#99aac2), to(#41618d));
+  background-image: linear-gradient(to bottom, #99aac2 0%, #41618d 100%);
+}
+.dj_ios6.dj_phone .mblColorDefault45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#99aac2), to(#41618d));
+  background-image: linear-gradient(to right bottom, #99aac2 0%, #41618d 100%);
+}
+.dj_ios6.dj_phone .mblColorDefaultSel {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#8b97af), to(#273e6b));
+  background-image: linear-gradient(to bottom, #8b97af 0%, #273e6b 100%);
+}
+.dj_ios6.dj_phone .mblColorDefaultSel45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#8b97af), to(#273e6b));
+  background-image: linear-gradient(to right bottom, #8b97af 0%, #273e6b 100%);
+}
+.dj_ios6.dj_phone .mblColorBlue {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#89abec), to(#2057c1));
+  background-image: linear-gradient(to bottom, #89abec 0%, #2057c1 100%);
+}
+.dj_ios6.dj_phone .mblColorBlue45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#89abec), to(#2057c1));
+  background-image: linear-gradient(to right bottom, #89abec 0%, #2057c1 100%);
 }
diff --git a/dojox/mobile/themes/iphone/common.less b/dojox/mobile/themes/iphone/common.less
index 4e57a5c..f6de45f 100644
--- a/dojox/mobile/themes/iphone/common.less
+++ b/dojox/mobile/themes/iphone/common.less
@@ -1,2 +1,42 @@
 @import "variables.less";
 @import "../common/common.less";
+/* iOS 6 specific */
+.dj_ios6 {
+	.mblColorBlue {
+		.background-image-linear-gradient-top-bottom(#89abec, #2057c1);
+	}
+	.mblColorBlue45 {
+		.background-image-linear-gradient-top-left-bottom-right(#89abec, #2057c1);
+	}
+}
+.dj_ios6.dj_phone {
+
+	body {
+		background-color: #d7dce5;
+		&.mblIOS6Stripes {
+			/* Vertical stripes on webkit */
+			background-image: -webkit-gradient(linear, left top, right top, from(transparent), to(#d4d9e3), color-stop(0.70, transparent), color-stop(0.70, #d4d9e3));
+			background-size: 8px 8px;
+		}
+	}
+	
+	.mblColorDefault {
+		.background-image-linear-gradient-top-bottom(#99aac2, #41618d);
+	}
+	.mblColorDefault45 {
+		.background-image-linear-gradient-top-left-bottom-right(#99aac2, #41618d);
+	}
+	.mblColorDefaultSel {
+		.background-image-linear-gradient-top-bottom(#8b97af, #273e6b);
+	}
+	.mblColorDefaultSel45 {
+		.background-image-linear-gradient-top-left-bottom-right(#8b97af, #273e6b);
+	}
+	/* mblColorBlue also defined here to correctly show up in openers */
+	.mblColorBlue {
+		.background-image-linear-gradient-top-bottom(#89abec, #2057c1);
+	}
+	.mblColorBlue45 {
+		.background-image-linear-gradient-top-left-bottom-right(#89abec, #2057c1);
+	}
+}
diff --git a/dojox/mobile/themes/iphone/compat/arrow-button-bg-sel.png b/dojox/mobile/themes/iphone/compat/arrow-button-bg-sel.png
new file mode 100644
index 0000000..33112b1
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/arrow-button-bg-sel.png differ
diff --git a/dojox/mobile/themes/iphone/compat/arrow-button-bg.png b/dojox/mobile/themes/iphone/compat/arrow-button-bg.png
index 5efaa9e..39ff2f0 100755
Binary files a/dojox/mobile/themes/iphone/compat/arrow-button-bg.png and b/dojox/mobile/themes/iphone/compat/arrow-button-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/arrow-button-head-sel.png b/dojox/mobile/themes/iphone/compat/arrow-button-head-sel.png
new file mode 100644
index 0000000..d9389d7
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/arrow-button-head-sel.png differ
diff --git a/dojox/mobile/themes/iphone/compat/arrow-button-head.png b/dojox/mobile/themes/iphone/compat/arrow-button-head.png
index 85beb43..5b63fc8 100755
Binary files a/dojox/mobile/themes/iphone/compat/arrow-button-head.png and b/dojox/mobile/themes/iphone/compat/arrow-button-head.png differ
diff --git a/dojox/mobile/themes/iphone/compat/arrow-button-right-head-sel.png b/dojox/mobile/themes/iphone/compat/arrow-button-right-head-sel.png
new file mode 100644
index 0000000..f97347c
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/arrow-button-right-head-sel.png differ
diff --git a/dojox/mobile/themes/iphone/compat/arrow-button-right-head.png b/dojox/mobile/themes/iphone/compat/arrow-button-right-head.png
new file mode 100644
index 0000000..cefa100
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/arrow-button-right-head.png differ
diff --git a/dojox/mobile/themes/iphone/compat/button-arrow-head-bg.gif b/dojox/mobile/themes/iphone/compat/button-arrow-head-bg.gif
new file mode 100644
index 0000000..77b6e9e
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/button-arrow-head-bg.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/button-chk-bg.png b/dojox/mobile/themes/iphone/compat/button-chk-bg.png
new file mode 100644
index 0000000..3bd558b
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/button-chk-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/button-unsel-bg.png b/dojox/mobile/themes/iphone/compat/button-unsel-bg.png
new file mode 100644
index 0000000..6968458
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/button-unsel-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/ipad-arrow-button-bg.png b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-bg.png
index b2afca9..bdf1ee4 100644
Binary files a/dojox/mobile/themes/iphone/compat/ipad-arrow-button-bg.png and b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/ipad-arrow-button-head-sel.png b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-head-sel.png
new file mode 100644
index 0000000..0408042
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-head-sel.png differ
diff --git a/dojox/mobile/themes/iphone/compat/ipad-arrow-button-head.png b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-head.png
index 503c685..970c47c 100644
Binary files a/dojox/mobile/themes/iphone/compat/ipad-arrow-button-head.png and b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-head.png differ
diff --git a/dojox/mobile/themes/iphone/compat/ipad-arrow-button-right-head-sel.png b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-right-head-sel.png
new file mode 100644
index 0000000..64d1be6
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-right-head-sel.png differ
diff --git a/dojox/mobile/themes/iphone/compat/ipad-arrow-button-right-head.png b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-right-head.png
new file mode 100644
index 0000000..890126c
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-right-head.png differ
diff --git a/dojox/mobile/themes/iphone/compat/ipad-arrow-button-sel-bg.png b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-sel-bg.png
new file mode 100644
index 0000000..831de06
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-arc1-k.gif b/dojox/mobile/themes/iphone/compat/switch-arc1-k.gif
index 6596e32..e51c1e4 100644
Binary files a/dojox/mobile/themes/iphone/compat/switch-arc1-k.gif and b/dojox/mobile/themes/iphone/compat/switch-arc1-k.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-arc1-l.gif b/dojox/mobile/themes/iphone/compat/switch-arc1-l.gif
new file mode 100644
index 0000000..6bfb2d4
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-arc1-l.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-arc1-r.gif b/dojox/mobile/themes/iphone/compat/switch-arc1-r.gif
new file mode 100644
index 0000000..5ab1242
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-arc1-r.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-arc2-k.gif b/dojox/mobile/themes/iphone/compat/switch-arc2-k.gif
index bf307b1..9619926 100644
Binary files a/dojox/mobile/themes/iphone/compat/switch-arc2-k.gif and b/dojox/mobile/themes/iphone/compat/switch-arc2-k.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-arc2-l.gif b/dojox/mobile/themes/iphone/compat/switch-arc2-l.gif
new file mode 100644
index 0000000..0af2e44
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-arc2-l.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-arc2-r.gif b/dojox/mobile/themes/iphone/compat/switch-arc2-r.gif
new file mode 100644
index 0000000..b054a06
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-arc2-r.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-round1-k.gif b/dojox/mobile/themes/iphone/compat/switch-round1-k.gif
index 6b9fe0a..634e5e5 100644
Binary files a/dojox/mobile/themes/iphone/compat/switch-round1-k.gif and b/dojox/mobile/themes/iphone/compat/switch-round1-k.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-round1-l.gif b/dojox/mobile/themes/iphone/compat/switch-round1-l.gif
new file mode 100644
index 0000000..da7792b
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-round1-l.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-round1-r.gif b/dojox/mobile/themes/iphone/compat/switch-round1-r.gif
new file mode 100644
index 0000000..3937ff9
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-round1-r.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-round2-k.gif b/dojox/mobile/themes/iphone/compat/switch-round2-k.gif
index dfa763e..b8d42a0 100644
Binary files a/dojox/mobile/themes/iphone/compat/switch-round2-k.gif and b/dojox/mobile/themes/iphone/compat/switch-round2-k.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-round2-l.gif b/dojox/mobile/themes/iphone/compat/switch-round2-l.gif
new file mode 100644
index 0000000..38b9669
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-round2-l.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-round2-r.gif b/dojox/mobile/themes/iphone/compat/switch-round2-r.gif
new file mode 100644
index 0000000..7a2ee13
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-round2-r.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-square-k.gif b/dojox/mobile/themes/iphone/compat/switch-square-k.gif
new file mode 100644
index 0000000..f745933
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-square-k.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-square-l.gif b/dojox/mobile/themes/iphone/compat/switch-square-l.gif
new file mode 100644
index 0000000..ca8d970
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-square-l.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/switch-square-r.gif b/dojox/mobile/themes/iphone/compat/switch-square-r.gif
new file mode 100644
index 0000000..1d4be9d
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/switch-square-r.gif differ
diff --git a/dojox/mobile/themes/iphone/compat/tab-seg-button-bg.png b/dojox/mobile/themes/iphone/compat/tab-seg-button-bg.png
new file mode 100644
index 0000000..f8bb99e
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/tab-seg-button-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/tab-seg-sel-button-bg.png b/dojox/mobile/themes/iphone/compat/tab-seg-sel-button-bg.png
new file mode 100644
index 0000000..5e593f6
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/tab-seg-sel-button-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/tab-slim-bar-bg.png b/dojox/mobile/themes/iphone/compat/tab-slim-bar-bg.png
new file mode 100644
index 0000000..f982afb
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/tab-slim-bar-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/tab-tall-bar-bg.png b/dojox/mobile/themes/iphone/compat/tab-tall-bar-bg.png
new file mode 100644
index 0000000..4131342
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/tab-tall-bar-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/togglebutton-chk-mark-bg.png b/dojox/mobile/themes/iphone/compat/togglebutton-chk-mark-bg.png
new file mode 100644
index 0000000..2262424
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/togglebutton-chk-mark-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/valuepicker-button-bg.png b/dojox/mobile/themes/iphone/compat/valuepicker-button-bg.png
new file mode 100644
index 0000000..5d85828
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/valuepicker-button-bg.png differ
diff --git a/dojox/mobile/themes/iphone/dijit/Calendar-compat.css b/dojox/mobile/themes/iphone/dijit/Calendar-compat.css
new file mode 100644
index 0000000..e9b7689
--- /dev/null
+++ b/dojox/mobile/themes/iphone/dijit/Calendar-compat.css
@@ -0,0 +1,27 @@
+/* dijit.Calendar */
+.dijitCalendar thead {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-month-bg.png);
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+}
+.dijitCalendarYearLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-year-bg.png);
+}
+.dj_gecko .dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  -moz-box-shadow: 0 0 0 transparent;
+}
+.dj_gecko .dijitCalendar thead {
+  background-image: -moz-linear-gradient(top, #f6f6f6 0%, #ccccd1 100%);
+}
+.dj_gecko .dijitCalendarYearLabel {
+  background-image: -moz-linear-gradient(top, #f6f6f6 0%, #ccccd1 100%);
+}
+.dj_ff3 .dijitCalendar {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/iphone/dijit/Calendar-compat.less b/dojox/mobile/themes/iphone/dijit/Calendar-compat.less
new file mode 100644
index 0000000..88cd6f0
--- /dev/null
+++ b/dojox/mobile/themes/iphone/dijit/Calendar-compat.less
@@ -0,0 +1,2 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar-compat.less";
diff --git a/dojox/mobile/themes/iphone/dijit/Calendar.css b/dojox/mobile/themes/iphone/dijit/Calendar.css
new file mode 100644
index 0000000..b0f8b65
--- /dev/null
+++ b/dojox/mobile/themes/iphone/dijit/Calendar.css
@@ -0,0 +1,123 @@
+/* if you link this style sheet, dijit/themes/dijit.css must be imported. */
+/* dijit.Calendar */
+.dijitCalendar {
+  padding: 0;
+  width: 320px;
+  border-radius: 0;
+  text-align: center;
+  border: solid 1px #b5bcc7;
+  background-color: #dddde0;
+}
+.dijitCalendar thead {
+  border-color: inherit;
+  vertical-align: middle;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#ccccd1));
+  background-image: linear-gradient(to bottom, #f6f6f6 0%, #ccccd1 100%);
+}
+.dijitCalendarMonthLabel {
+  padding: 0 4px;
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0 1px 0px;
+  color: #545454;
+  font-size: 22px;
+}
+.dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  padding: 0 3px 0 2px;
+  border: none;
+  background-color: transparent;
+  background-image: none;
+  -webkit-box-shadow: 0 0 0 transparent;
+  box-shadow: 0 0 0 transparent;
+}
+.dijitArrowButtonInner {
+  display: none;
+}
+.dijitCalendarMonthContainer th {
+  border-right: 1px solid transparent;
+}
+.dijitCalendarIncrementControl {
+  width: 0;
+  height: 0;
+  border: 6px solid transparent !important;
+}
+.dijitCalendarDecrease {
+  border-left-width: 0 !important;
+  border-right: 6px solid #545454 !important;
+}
+.dijitCalendarIncrease {
+  border-right-width: 0 !important;
+  border-left: 6px solid #545454 !important;
+}
+.dijitA11ySideArrow {
+  display: none;
+}
+.dijitCalendarDayLabelTemplate {
+  border-right: 1px solid transparent;
+  text-align: center;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  font-size: 9px;
+  color: #545454;
+}
+.dijitCalendarDateTemplate {
+  border-bottom: 1px solid lightGrey;
+  font-family: Helvetica;
+  font-size: 22px;
+  font-weight: normal;
+  text-align: center;
+  background-color: #dddde0;
+  color: #4a5b6e;
+  text-shadow: #e7e7e9 0 1px 0;
+}
+.dijitCalendarDateTemplate .dijitCalendarDateLabel {
+  padding: 3px 5px 3px 4px;
+  display: block;
+  text-decoration: none;
+  border-top: solid 1px #eceeef;
+  border-bottom: solid 1px #a6aab3;
+  border-left: solid 1px #a0a4ad;
+  border-right: solid 1px #ececed;
+  background-color: rgba(171, 212, 251, 0);
+  -webkit-transition-property: background-color, border;
+  transition-property: background-color, border;
+  -webkit-transition-duration: 0.35s;
+  transition-duration: 0.35s;
+}
+.dijitCalendarPreviousMonth .dijitCalendarDateLabel,
+.dijitCalendarNextMonth .dijitCalendarDateLabel {
+  color: #9099a4;
+}
+.dijitCalendarHoveredDate .dijitCalendarDateLabel {
+  border: solid 1px #769dc0;
+  color: black;
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  border: solid 1px #1037b3;
+  background-color: #1a80e5;
+  color: white;
+  text-shadow: rgba(0, 0, 0, 0.4) 0 1px 0;
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+  border: solid 1px white;
+  background-color: #1a80e5;
+  -webkit-transition-duration: 0.1s;
+  transition-duration: 0.1s;
+}
+.dijitCalendarYearLabel {
+  margin: 0;
+  padding: 2px 0 0 0;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f6f6f6), to(#ccccd1));
+  background-image: linear-gradient(to bottom, #f6f6f6 0%, #ccccd1 100%);
+}
+.dijitCalendarSelectedYear {
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  color: #545454;
+  font-size: 1.091em;
+}
+.dijitCalendarNextYear,
+.dijitCalendarPreviousYear {
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  padding: 1px 6px 1px 6px;
+  color: #545454;
+  font-size: 0.909em;
+}
diff --git a/dojox/mobile/themes/iphone/dijit/Calendar.less b/dojox/mobile/themes/iphone/dijit/Calendar.less
new file mode 100644
index 0000000..a590903
--- /dev/null
+++ b/dojox/mobile/themes/iphone/dijit/Calendar.less
@@ -0,0 +1,2 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar.less";
diff --git a/dojox/mobile/themes/common/dijit/compat/calendar-daylabel-bg.png b/dojox/mobile/themes/iphone/dijit/compat/calendar-daylabel-bg.png
similarity index 100%
rename from dojox/mobile/themes/common/dijit/compat/calendar-daylabel-bg.png
rename to dojox/mobile/themes/iphone/dijit/compat/calendar-daylabel-bg.png
diff --git a/dojox/mobile/themes/common/dijit/compat/calendar-month-bg.png b/dojox/mobile/themes/iphone/dijit/compat/calendar-month-bg.png
similarity index 100%
rename from dojox/mobile/themes/common/dijit/compat/calendar-month-bg.png
rename to dojox/mobile/themes/iphone/dijit/compat/calendar-month-bg.png
diff --git a/dojox/mobile/themes/common/dijit/compat/calendar-year-bg.png b/dojox/mobile/themes/iphone/dijit/compat/calendar-year-bg.png
similarity index 100%
rename from dojox/mobile/themes/common/dijit/compat/calendar-year-bg.png
rename to dojox/mobile/themes/iphone/dijit/compat/calendar-year-bg.png
diff --git a/dojox/mobile/themes/iphone/ipad-compat.css b/dojox/mobile/themes/iphone/ipad-compat.css
index d48170e..08ae1d6 100644
--- a/dojox/mobile/themes/iphone/ipad-compat.css
+++ b/dojox/mobile/themes/iphone/ipad-compat.css
@@ -2,16 +2,77 @@
 .dj_tablet .mblHeading {
 	background-image: url(compat/ipad-heading-bg.png);
 }
+.dj_gecko.dj_tablet .mblHeading {
+	background-image: -moz-linear-gradient(top, #f3f4f6 0%, #a7abb8 100%);
+}
 
-/* Heading Arrow Button */
-.dj_tablet .mblArrowButtonHead {
+/* dojox.mobile.ToolBarButton */
+.dj_ie.dj_tablet .mblToolBarButtonHasLeftArrow .mblToolBarButtonLeftArrow {
 	background-image: url(compat/ipad-arrow-button-head.png);
 }
-.dj_tablet .mblArrowButtonBody {
+.dj_ie.dj_tablet .mblToolBarButtonHasRightArrow .mblToolBarButtonRightArrow {
+	background-image: url(compat/ipad-arrow-button-right-head.png);
+}
+.dj_ie.dj_tablet .mblToolBarButtonBody {
 	background-image: url(compat/ipad-arrow-button-bg.png);
 }
+.dj_ie.dj_tablet .mblToolBarButtonSelected .mblToolBarButtonLeftArrow {
+	background-image: url(compat/ipad-arrow-button-head-sel.png);
+}
+.dj_ie.dj_tablet .mblToolBarButtonSelected .mblToolBarButtonRightArrow {
+	background-image: url(compat/ipad-arrow-button-right-head-sel.png);
+}
+.dj_ie.dj_tablet .mblToolBarButtonSelected .mblToolBarButtonBody {
+	background-image: url(compat/ipad-arrow-button-sel-bg.png);
+}
 
-/* mbl.widget.TabBar */
-.dj_tablet .mblTabPanelHeader {
+/* dojox.mobile.TabBar */
+.dj_tablet .mblTabBarSegmentedControl,
+.dj_tablet .mblTabBarStandardTab,
+.dj_tablet .mblTabBarSegmentedControl .mblTabBarButton {
 	background-image: url(compat/ipad-heading-bg.png);
 }
+.dj_tablet .mblTabBarSegmentedControl .mblTabBarButtonSelected {
+	background-image: url(compat/ipad-arrow-button-bg.png);
+}
+.dj_tablet .mblTabBarStandardTab .mblTabBarButtonSelected {
+	background-color: #f3f4f6;
+	background-image: none;
+}
+.dj_gecko.dj_tablet .mblTabBarSegmentedControl,
+.dj_gecko.dj_tablet .mblTabBarStandardTab,
+.dj_gecko.dj_tablet .mblTabBarSegmentedControl .mblTabBarButton {
+	background-image: -moz-linear-gradient(top, #f3f4f6 0%, #a7abb8 100%);
+}
+.dj_gecko.dj_tablet .mblTabBarSegmentedControl .mblTabBarButtonSelected {
+	background-image: -moz-linear-gradient(top, #b1b5bb 0%, #6a727d 100%);
+}
+.dj_gecko.dj_tablet .mblTabBarStandardTab .mblTabBarButton {
+	background-image: -moz-linear-gradient(top, #f0f0f2 0%, #959da0 100%);
+}
+.dj_gecko.dj_tablet .mblTabBarStandardTab .mblTabBarButtonSelected {
+	background-image: -moz-linear-gradient(top, #f3f4f6 0%, #f2f3f7 100%);
+}
+
+
+/* Default Button Colors */
+.dj_tablet .mblColorDefault {
+	background-color: #8b919a;
+}
+.dj_gecko.dj_tablet .mblColorDefault {
+	background-image: -moz-linear-gradient(top, #b1b5bb 0%, #6a727d 100%);
+}
+
+.dj_gecko.dj_tablet .mblColorDefault45 {
+	background-image: -moz-linear-gradient(top left, #b1b5bb 0%, #6a727d 100%);
+}
+.dj_tablet .mblColorDefaultSel {
+	background-color: #515761;
+}
+.dj_gecko.dj_tablet .mblColorDefaultSel {
+	background-image: -moz-linear-gradient(top, #7a7e85 0%, #303845 100%);
+}
+
+.dj_gecko.dj_tablet .mblColorDefaultSel45 {
+	background-image: -moz-linear-gradient(top left, #7a7e85 0%, #303845 100%);
+}
\ No newline at end of file
diff --git a/dojox/mobile/themes/iphone/ipad.css b/dojox/mobile/themes/iphone/ipad.css
index b17502d..243516f 100644
--- a/dojox/mobile/themes/iphone/ipad.css
+++ b/dojox/mobile/themes/iphone/ipad.css
@@ -2,76 +2,28 @@
 
 /* dojox.mobile.Heading */
 .dj_tablet .mblHeading {
-	background-color: #889BB3;
-	background: -webkit-gradient(linear, left top, left bottom, from(#F3F4F6), to(#A7ABB8));
-	border-top: 1px solid #FEFEFE;
-	border-bottom: 1px solid #787E8F;
-	color: #70777F;
+	background: -webkit-gradient(linear, left top, left bottom, from(#f3f4f6), to(#a7abb8));
+	border-top: 1px solid #fefefe;
+	border-bottom: 1px solid #787e8f;
+	color: #70777f;
 	text-shadow: rgba(256,256,256,0.6) 0px 1px 0px;
 }
 
-/*Headings and Button styles are overridden in Tooltips*/
-.dj_tablet .mblTooltip .mblHeading { 
-	position: relative;
-	margin: 0px;
-	width: 100%;
-	overflow: hidden;
-	white-space: nowrap;
-	text-overflow: ellipsis;
-	padding: 0px;
-	height: 42px;
-	background-color: #889BB3;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#5E6167), to(#1A1D24), color-stop(0.5, #2E322B));
-	border-top: 3px solid #4F5055;
-	border-bottom: 1px solid #2D3642;
-	color: white;
-	font-family: Helvetica;
-	font-size: 20px;
-	font-weight: normal;
-	text-align: center;
-	line-height: 44px;
+/* dojox.mobile.ToolBarButton */
+.dj_tablet .mblToolBarButton {
 	text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
-	z-index: 1;
-	border-left: 1px solid #2A2D47;
-	-webkit-border-radius: 3px 3px 0 0;
-}
-.dj_tablet .mblTooltip .mblHeading .mblToolBarButton {
-	float: left;
-	position: relative;
-	cursor: pointer;
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
-	margin: 6px;
-	padding: 0px 10px;
-	height: 29px;
-	border: 1px inset #434450;
-	font-family: Helvetica;
-	font-size: 13px;
-	font-weight: normal;
-	color: white;
-	line-height: 29px;
-	text-align: center;
-	-webkit-border-radius: 5px;
-	-moz-border-radius: 5px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#686F80), to(#000924), color-stop(0.5, #000B29));
-}
-
-/* Heading Arrow Button */
-.dj_tablet .mblArrowButtonHead {
-	border-color: #4D4E50;
-	background: -webkit-gradient(linear, left top, right bottom, from(#B1B5BB), to(#6A727D));
 }
-.dj_tablet .mblArrowButtonBody {
-	border-color: #C0C0C0;
-	background-color: #8B919A;
-	background: -webkit-gradient(linear, left top, left bottom, from(#B1B5BB), to(#6A727D));
-	-webkit-tap-highlight-color: rgba(255,255,255,0);
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
+.dj_tablet .mblHeading .mblToolBarButtonArrow {
+	border-color: #60656f #60656f #5a5c5f #5a5c5f;
 }
-.dj_tablet .mblArrowButtonSelected .mblArrowButtonHead {
-	background: -webkit-gradient(linear, left top, right bottom, from(#9DA0A3), to(#43484F));
+.dj_tablet .mblHeading .mblToolBarButtonBody {
+	border-color: #4e4f51 #60656f #565b64 #5a5c5f;
 }
-.dj_tablet .mblArrowButtonSelected .mblArrowButtonBody {
-	background: -webkit-gradient(linear, left top, left bottom, from(#9DA0A3), to(#43484F));
+
+/*Headings and Button styles are overridden in Tooltips*/
+.dj_tablet .mblTooltip .mblHeading { 
+	color: white;
+	text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
 }
 
 /* dojox.mobile.RoundRect */
@@ -99,6 +51,12 @@
 	margin-top: 30px;
 }
 
+/* dojox.mobile.SearchBox */
+.dj_tablet .mblFilteredRoundRectListSearchBox {
+  padding-left: 30px;
+  padding-right: 30px;
+}
+
 /* dojox.mobile.EdgeToEdgeList */
 /* dojox.mobile.ListItem */
 /* Switch */
@@ -109,44 +67,66 @@
 /* Progress Indicator */
 
 /* dojox.mobile.TabBar */
-.dj_tablet .mblTabPanelHeader {
-	background-color: #889BB3;
-	background: -webkit-gradient(linear, left top, left bottom, from(#F3F4F6), to(#A7ABB8));
-	border-top: 1px solid #FEFEFE;
-	border-bottom: 1px solid #787E8F;
-	color: #70777F;
-	text-shadow: rgba(256,256,256,0.6) 0px 1px 0px;
-}
-
-/* dojox.mobile.TabBarButton */
-.dj_tablet .mblTabButton {
-	font-weight: bold;
-	color: #70777F;
+.dj_tablet .mblTabBar {
+	color: #70777f;
+	text-shadow: rgba(255,255,255,0.6) 0px 1px 0px;
+}
+/* barType=tabBar */
+.dj_tablet .mblTabBarTabBar {
+	border-top: 1px solid #000000;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+}
+/* barType=segmentedControl */
+.dj_tablet .mblTabBarSegmentedControl,
+.dj_tablet .mblTabBarStandardTab {
+	border-top: 1px solid #fefefe;
+	border-bottom: 1px solid #787e8f;
+	background: -webkit-gradient(linear, left top, left bottom, from(#f3f4f6), to(#a7abb8));
+}
+.dj_tablet .mblTabBarSegmentedControl .mblTabBarButton {
+	background-color: #889bb3;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#f3f4f6), to(#a7abb8));
+	border-color: #4e4f51 #60656f #565b64 #5a5c5f;
+	color: #70777f;
 	text-shadow: none;
-	border-color: silver;
-	background-color: #CCCED6;
-	background: -webkit-gradient(linear, left top, left bottom, from(#F3F4F6), to(#A7ABB8));
 }
-.dj_tablet .mblTabPanelHeader .mblTabButton.mblTabButtonSelected {
+
+.dj_tablet .mblTabBarSegmentedControl .mblTabBarButtonSelected {
 	color: white;
 	text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
-	background-color: #8B919A;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#B1B5BB), to(#6A727D));
+	background-color: #8b919a;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#b1b5bb), to(#6a727d));
 }
-
-/* dojox.mobile.ToolBarButton */
-.dj_tablet .mblToolBarButton {
-	text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
-	border: 1px inset silver;
+.dj_tablet .mblHeading .mblTabBarSegmentedControl {
+ 	border: none;
+}
+/* barType=standardTab */
+.dj_tablet .mblTabBarStandardTab .mblTabBarButton {
+	color: #000000;
+	text-shadow: rgba(255, 255, 255, 0.6) 0px 1px 0px;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#f0f0f2), to(#959da0));
+}
+.dj_tablet .mblTabBarStandardTab .mblTabBarButtonSelected {
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#f3f4f6), to(#f2f3f7));
+}
+/* barType=flatTab */
+.dj_tablet .mblTabBarFlatTab .mblTabBarButton {
+	color: white;
 }
 
 /* Default Button Colors */
 .dj_tablet .mblColorDefault {
-	background-color: #8B919A;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#B1B5BB), to(#6A727D));
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#b1b5bb), to(#6a727d));
+}
 
+.dj_tablet .mblColorDefault45 {
+	background-image: -webkit-gradient(linear, left top, right bottom, from(#b1b5bb), to(#6a727d));
 }
+
 .dj_tablet .mblColorDefaultSel {
-	background-color: #515761;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7A7E85), to(#303845));
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#7a7e85), to(#303845));
+}
+
+.dj_tablet .mblColorDefaultSel45 {
+	background-image: -webkit-gradient(linear, left top, right bottom, from(#7a7e85), to(#303845));
 }
diff --git a/dojox/mobile/themes/iphone/iphone-app-compat.css b/dojox/mobile/themes/iphone/iphone-app-compat.css
index dc0a814..5e95cad 100755
--- a/dojox/mobile/themes/iphone/iphone-app-compat.css
+++ b/dojox/mobile/themes/iphone/iphone-app-compat.css
@@ -1,6 +1,10 @@
 /* mbl.widget.Heading */
 @import url("iphone-compat.css");
 
+.alertDialogBody { /* 1.8 */
+	-moz-border-radius: 10px;
+}
+
 .alertTitle {
 	background-image: url(compat/heading-bg.png);
 }
diff --git a/dojox/mobile/themes/iphone/iphone-app.css b/dojox/mobile/themes/iphone/iphone-app.css
index d91d2f4..31fc3e9 100644
--- a/dojox/mobile/themes/iphone/iphone-app.css
+++ b/dojox/mobile/themes/iphone/iphone-app.css
@@ -8,9 +8,9 @@
 }
 
 .alertDialogBody {
-	border: 1px solid #ADAAAD;
-	-webkit-border-radius: 10px;
-	-moz-border-radius: 10px;
+	border: 1px solid #adaaad;
+	border-radius: 10px;
+	/* 1.8 removed */
 	background-color: white;
 	margin-left: 2px;
 	margin-right: 4px;
@@ -20,10 +20,10 @@
 	height: 42px;
 	margin: 0px;
 	padding: 0px;
-	background-color: #889BB3;
-	background: -webkit-gradient(linear, left top, left bottom, from(#B0BCCD), to(#6D84A2), color-stop(0.5, #889BB3), color-stop(0.5, #8195AF));
-	border-top: 1px solid #CDD5DF;
-	border-bottom: 1px solid #2D3642;
+	background-color: #889bb3;
+	background: -webkit-gradient(linear, left top, left bottom, from(#b0bccd), to(#6d84a2), color-stop(0.5, #889bb3), color-stop(0.5, #8195af));
+	border-top: 1px solid #cdd5df;
+	border-bottom: 1px solid #2d3642;
 	font-family: Helvetica;
 	font-size: 20px;
 	color: white;
@@ -154,7 +154,7 @@
 
 .listSelector {
 	position: absolute;
-	-webkit-border-radius: 10px;
+	border-radius: 10px;
 	-moz-border-radius: 10px;
 	border: 1px solid #666;
 	background-color: #ccc;
@@ -257,7 +257,7 @@ input {
 	overflow: hidden;
 	position: absolute;
 	-webkit-background-size: 100% 100%;
-	-webkit-border-radius: 5px;
+	border-radius: 5px;
 	width: 90px;
 	height: 90px;
 	z-index: 5;
diff --git a/dojox/mobile/themes/iphone/iphone-compat.css b/dojox/mobile/themes/iphone/iphone-compat.css
index f5a0140..3d25bdd 100755
--- a/dojox/mobile/themes/iphone/iphone-compat.css
+++ b/dojox/mobile/themes/iphone/iphone-compat.css
@@ -2,17 +2,23 @@
 
 /* common styles */
 @import url("../common/domButtons-compat.css");
- at import url("../common/SpinWheel-compat.css");
 
 /* widget styles */
+ at import url("Accordion-compat.css");
 @import url("Button-compat.css");
 @import url("CheckBox-compat.css");
 @import url("ComboBox-compat.css");
 @import url("IconContainer-compat.css");
+ at import url("IconMenu-compat.css");
 @import url("Opener-compat.css");
+ at import url("PageIndicator-compat.css");
 @import url("RadioButton-compat.css");
+ at import url("SearchBox-compat.css");
+ at import url("SimpleDialog-compat.css");
 @import url("Slider-compat.css");
+ at import url("SpinWheel-compat.css");
 @import url("TabBar-compat.css");
 @import url("TextArea-compat.css");
 @import url("TextBox-compat.css");
 @import url("ToggleButton-compat.css");
+ at import url("ValuePicker-compat.css");
diff --git a/dojox/mobile/themes/iphone/iphone.css b/dojox/mobile/themes/iphone/iphone.css
index a50e0ce..0a3b95f 100755
--- a/dojox/mobile/themes/iphone/iphone.css
+++ b/dojox/mobile/themes/iphone/iphone.css
@@ -2,21 +2,29 @@
 
 /* common styles */
 @import url("../common/domButtons.css");
- at import url("../common/FixedSplitter.css");
- at import url("../common/SpinWheel.css");
 @import url("../common/transitions.css");
 
 /* widget styles */
+ at import url("Accordion.css");
 @import url("Button.css");
 @import url("Carousel.css");
 @import url("CheckBox.css");
 @import url("ComboBox.css");
+ at import url("FixedSplitter.css");
+ at import url("GridLayout.css");
 @import url("IconContainer.css");
+ at import url("IconMenu.css");
 @import url("Opener.css");
 @import url("PageIndicator.css");
+ at import url("ProgressBar.css");
 @import url("RadioButton.css");
+ at import url("ScrollablePane.css");
+ at import url("SearchBox.css");
+ at import url("SimpleDialog.css");
 @import url("Slider.css");
+ at import url("SpinWheel.css");
 @import url("TabBar.css");
 @import url("TextArea.css");
- at import url("TextBox.css");
 @import url("ToggleButton.css");
+ at import url("ValuePicker.css");
+ at import url("FormLayout.css");
diff --git a/dojox/mobile/themes/iphone/iphone_rtl-compat.css b/dojox/mobile/themes/iphone/iphone_rtl-compat.css
new file mode 100644
index 0000000..0143aa0
--- /dev/null
+++ b/dojox/mobile/themes/iphone/iphone_rtl-compat.css
@@ -0,0 +1,7 @@
+ at import url("base_rtl-compat.css");
+
+ at import url("IconMenu_rtl-compat.css");
+
+ at import url("SpinWheel_rtl-compat.css");
+
+ at import url("TabBar_rtl-compat.css");
diff --git a/dojox/mobile/themes/iphone/iphone_rtl.css b/dojox/mobile/themes/iphone/iphone_rtl.css
new file mode 100644
index 0000000..f61e915
--- /dev/null
+++ b/dojox/mobile/themes/iphone/iphone_rtl.css
@@ -0,0 +1,15 @@
+ at import url("base_rtl.css");
+
+ at import url("Carousel_rtl.css");
+
+ at import url("ComboBox_rtl.css");
+
+ at import url("IconContainer_rtl.css");
+
+ at import url("IconMenu_rtl.css");
+
+ at import url("SpinWheel_rtl.css");
+
+ at import url("TabBar_rtl.css");
+
+ at import url("ToggleButton_rtl.css");
diff --git a/dojox/mobile/themes/iphone/variables.less b/dojox/mobile/themes/iphone/variables.less
index 007cab4..5103a2f 100644
--- a/dojox/mobile/themes/iphone/variables.less
+++ b/dojox/mobile/themes/iphone/variables.less
@@ -1,662 +1,456 @@
+ at import "../common/css3.less";
+
+ at default-blue-button-color: white;
+ at default-blue-button-background-color: #366edf;
+.default-blue-button-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#7a9de9, #2362dd, 0.5, #366edf, 0.5, #215fdc); }
+ at default-blue-button-background-image-gecko: -moz-linear-gradient(top, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+
+.mbl-color-blue-45 () { .background-image-linear-gradient-top-left-bottom-right-2-stops(#7a9de9, #2362dd, 0.5, #366edf, 0.5, #215fdc); }
+.mbl-color-default-45 () { .background-image-linear-gradient-top-left-bottom-right-3-stops(#222222, #4a6c9b, 0.02, #8ea4c1, 0.5, #5877a2, 0.5, #476999); }
+.mbl-color-default-sel-45 () { .background-image-linear-gradient-top-left-bottom-right-2-stops(#7c87a4, #263e6c, 0.5, #394d77, 0.5, #243b69); }
+
+ at mbl-color-blue-45-gecko: -moz-linear-gradient(top left, #7a9de9 0%, #366edf 50%, #215fdc 50%, #2362dd 100%);
+ at mbl-color-default-45-gecko: -moz-linear-gradient(top left, #222222 0%, #8ea4c1 2%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
+ at mbl-color-default-sel-45-gecko: -moz-linear-gradient(top left, #7c87a4 0%, #394d77 50%, #243b69 50%, #263e6c 100%);
+
+ at default-button-color: white;
+ at default-button-background-color: #5877a2;
+.default-button-background-image () { .background-image-linear-gradient-top-bottom-3-stops(#222, #4a6c9b, .02, #8ea4c1, 0.5, #5877a2, 0.5, #476999); }
+ at default-button-background-image-gecko: -moz-linear-gradient(top, #222 0%, #8ea4c1 2%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
+ at default-button-border-radius: 5px;
+
+ at default-button-selected-color: white;
+ at default-button-selected-background-color: #394d77;
+.default-button-selected-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#7c87a4, #263e6c, 0.5, #394d77, 0.5, #243b69); }
+ at default-button-selected-background-image-gecko: -moz-linear-gradient(top, #7c87a4 0%, #394d77 50%, #243b69 50%, #263e6c 100%);
+
+ at default-selected-color: white;
+ at default-selected-background-color: #048bf4;
+.default-selected-background-image () { .background-image-linear-gradient-top-bottom(#048bf4, #005ce5); }
+ at default-selected-background-image-gecko: -moz-linear-gradient(top, #048bf4 0%, #005ce5 100%);
+
+ at heading-background-color: #889bb3;
+.heading-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#b0bccd, #6d84a2, 0.5, #889bb3, 0.5, #8195af); }
+ at heading-background-image-gecko: -moz-linear-gradient(top, #b0bccd 0%, #889bb3 50%, #8195af 50%, #6d84a2 100%);
+ at heading-border-top-color: #cdd5df;
+ at heading-border-bottom-color: #2d3642;
+
+.default-button-border-styles () {
+	border-color: #9cacc0;
+	border-radius: @default-button-border-radius;
+}
+
+.mblToolBarButtonBodyInLeftArrow-styles () {
+  border-left-width: 0;
+}
+
+.mblToolBarButtonBodyInRightArrow-styles () {
+  border-right-width: 0;
+}
+
+// background styles of form controls
+.mbl-button-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#fdfdfd, #cecece, 0.5, #f8f8f8, 0.5, #eeeeee); }
+.mbl-button-selected-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#f0f0f0, #bfbfbf, 0.5, #ebebeb, 0.5, #dedede); }
+.mbl-blue-button-background-image () { .default-blue-button-background-image(); }
+.mbl-blue-button-selected-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#8ea4c1, #4a6c9b, 0.5, #5877a2, 0.5, #476999); }
+.mbl-red-button-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#fa9d58, #ee4115, 0.5, #ff4d25, 0.5, #ed4d15); }
+.mbl-red-button-selected-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#c1a48e, #9b6c4a, 0.5, #a27758, 0.5, #996947); }
+.mbl-button-checked-background-image () { .default-blue-button-background-image(); }
+
+// background styles of form controls (for gecko)
+ at mbl-button-background-image-gecko: -moz-linear-gradient(top, #fdfdfd 0%, #f8f8f8 50%, #eeeeee 50%, #cecece 100%);
+ at mbl-button-selected-background-image-gecko: -moz-linear-gradient(top, #f0f0f0 0%, #ebebeb 50%, #dedede 50%, #bfbfbf 100%);
+ at mbl-blue-button-background-image-gecko: @default-blue-button-background-image-gecko;
+ at mbl-blue-button-selected-background-image-gecko: -moz-linear-gradient(top, #8ea4c1 0%, #5877a2 50%, #476999 50%, #4a6c9b 100%);
+ at mbl-red-button-background-image-gecko: -moz-linear-gradient(top, #fa9d58 0%, #ff4d25 50%, #ed4d15 50%, #ee4115 100%);
+ at mbl-red-button-selected-background-image-gecko: -moz-linear-gradient(top, #c1a48e 0%, #a27758 50%, #996947 50%, #9b6c4a 100%);
+ at mbl-button-checked-background-image-gecko: @default-blue-button-background-image-gecko;
+
 // common.less
 .mobile-body-styles () {
-	background-color: rgb(197,204,211);
 	font-family: Helvetica;
 	font-size: 17px;
 }
 
+.mblBackground-styles () {
+	background-color: #c5ccd3;
+}
+
 .mblView-styles () {
 }
 
 .mblColorBlue-styles () {
-	background-color: #366EDF;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7A9DE9), to(#2362DD), color-stop(0.5, #366EDF), color-stop(0.5, #215FDC));
+	color: @default-blue-button-color;
+	background-color: @default-blue-button-background-color;
+	.default-blue-button-background-image();
 }
 .mblColorDefault-styles () {
-	background-color: #5877A2;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
+	color: @default-button-color;
+	background-color: @default-button-background-color;
+	.default-button-background-image();
 }
 .mblColorDefaultSel-styles () {
-	background-color: #394D77;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7C87A4), to(#263E6C), color-stop(0.5, #394D77), color-stop(0.5, #243B69));
+	color: @default-button-selected-color;
+	background-color: @default-button-selected-background-color;
+	.default-button-selected-background-image();
 }
 
 // Heading.less
 .mblHeading-styles () {
-	padding: 0px;
-	height: 42px;
-	background-color: #889BB3;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#B0BCCD), to(#6D84A2), color-stop(0.5, #889BB3), color-stop(0.5, #8195AF));
-	border-top: 1px solid #CDD5DF;
-	border-bottom: 1px solid #2D3642;
+	.heading-background-image();
+	border-top: 1px solid @heading-border-top-color;
+	border-bottom: 1px solid @heading-border-bottom-color;
 	color: white;
-	font-family: Helvetica;
-	font-size: 20px;
-	font-weight: bold;
-	text-align: center;
-	line-height: 44px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
-}
-.mblArrowButton-styles () {
-	height: 42px;
-}
-.mblArrowButtonHead-styles () {
-	top: 11px;
-	left: 5px;
-	width: 20px;
-	height: 19px;
-	border: 1px solid #3A4655;
-	-webkit-transform: scale(0.7, 1) rotate(45deg);
-	background-image: -webkit-gradient(linear, left top, right bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
-}
-.mblArrowButtonHeadChrome-styles () {
-	border: 1px inset #3A4655;
-}
-.mblArrowButtonBody-styles () {
-	top: 6px;
-	left: 16px;
-	padding: 0px 10px 0px 4px;
-	height: 29px;
-	border-width: 1px 1px 1px 0px;
-	border-style: inset;
-	border-color: #9CACC0;
-	font-family: Helvetica;
-	font-size: 13px;
-	color: white;
-	line-height: 29px;
-	-webkit-border-top-right-radius: 5px;
-	-webkit-border-bottom-right-radius: 5px;
-	background-color: #5877A2;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
-}
-.mblArrowButtonSelected-styles () {
-}
-.mblArrowButtonHeadSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, right bottom, from(#7C87A4), to(#263E6C), color-stop(0.5, #394D77), color-stop(0.5, #243B69));
-}
-.mblArrowButtonBodySelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7C87A4), to(#263E6C), color-stop(0.5, #394D77), color-stop(0.5, #243B69));
+	text-shadow: rgba(0,0,0,0.6) 0 -1px 0;
 }
 
 // ToolBarButton.less
+ at mbl-tool-bar-button-body-border-radius: 5px;
+//
 .mblToolBarButton-styles () {
-	margin: 6px;
-	height: 29px;
-	border: 1px inset #9CACC0;
-	font-family: Helvetica;
-	font-size: 13px;
-	font-weight: bold;
-	color: white;
-	line-height: 29px;
-	text-align: center;
-	-webkit-border-radius: 5px;
-	-moz-border-radius: 5px;
 }
-.mblToolBarButtonDomButton-styles () {
+.mblToolBarButtonArrow-styles () {
+  .transform(scale(0.75, 1.0) rotate(45deg));
+	border: 1px solid #9cacc0;
+	border-top-left-radius: 1px;
+  border-bottom-right-radius: 1px;
+}
+.mblToolBarButtonArrowInHeading-styles () {
+	border-width: 1px;
+	border-style: solid;
+	border-color: #405a7e #405a7e #3a4755 #3a4755;
+}
+.mblToolBarButtonHasLeftArrowInHeading-styles () {
+	.box-shadow(0 1px 0 rgba(255, 255, 255, 0.305));
 }
-.mblToolBarButtonIcon-styles () {
+.mblToolBarButtonHasLeftArrowInHeading-compat-gecko () {
+	-moz-box-shadow: 0 1px 0 rgba(255,255,255,0.305);
+}
+.mblToolBarButtonHasRightArrowInHeading-styles () {
+	.box-shadow(1px 0 0 rgba(255, 255, 255, 0.305));
+}
+.mblToolBarButtonHasRightArrowInHeading-compat-gecko () {
+	-moz-box-shadow: 1px 0 0 rgba(255,255,255,0.305);
+}
+.mblToolBarButtonArrowInLeftArrow-styles () {
+  left: 1px;
+}
+.mblToolBarButtonArrowInRightArrow-styles () {
+  right: 0px;
+}
+.mblToolBarButtonBody-styles () {
+	border: 1px outset #9cacc0;
+}
+.mblToolBarButtonBodyInHeading-styles () {
+	border-width: 1px;
+	border-style: solid;
+	border-color: #2f3740 #405a7e #375073 #3a4755;
+	.box-shadow(0 1px 0 rgba(255,255,255,0.305));
+}
+.mblToolBarButtonBodyInHeading-compat-gecko () {
+	-moz-box-shadow: 0 1px 0 rgba(255,255,255,0.305);
 }
 
-// RoundRect.less
+// RoundRect.less & RoundRectList.less
+ at mbl-round-rect-border-color: #adaaad;
+ at mbl-round-rect-border-radius: 8px;
+ at mbl-round-rect-background-color: white;
+ at mbl-round-rect-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+//
 .mblRoundRect-styles () {
-	margin: 7px 9px 16px 9px;
-	padding: 8px;
-	border: 1px solid #ADAAAD;
-	-webkit-border-radius: 8px;
-	-moz-border-radius: 8px;
-	background-color: white;
-}
-.mblRoundRectShadowBox-styles () {
-	-webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
 }
 
 // EdgeToEdgeCategory.less
 .mblEdgeToEdgeCategory-styles () {
-	margin: 0px;
-	padding: 0px 10px;
 	height: 22px;
-	border-top: 1px solid #A4B0B9;
-	border-bottom: 1px solid #979DA3;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#8F9EA9), to(#B7C0C7));
-	font-family: Helvetica;
-	font-size: 16px;
-	font-weight: bold;
+	border-top: 1px solid #a4b0b9;
+	border-bottom: 1px solid #979da3;
+	.background-image-linear-gradient-top-bottom(#8f9ea9, #b7c0c7);
 	color: white;
 	line-height: 22px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
+	text-shadow: rgba(0,0,0,0.6) 0 -1px 0;
 }
 
 // RoundRectCategory.less
 .mblRoundRectCategory-styles () {
-	padding: 18px 0px 0px 20px;
-	margin: 0px;
-	font-family: Helvetica;
-	font-size: 16px;
-	color: #4C566C;
-	text-shadow: rgba(255, 255, 255, 1) 0px 1px 0px;
-}
-
-// RoundRectList.less
-.mblRoundRectList-styles () {
-	margin: 7px 9px 16px 9px;
-	padding: 0px;
-	border: 1px solid #ADAAAD;
-	-webkit-border-radius: 8px;
-	-moz-border-radius: 8px;
-	background-color: white;
-}
-.mblRoundRectList-withCategory-styles () {
-}	
-.mblRoundRectList-FirstListItem-styles () {
-	-webkit-border-top-left-radius: 8px;
-	-webkit-border-top-right-radius: 8px;
-	-moz-border-radius-topleft: 8px;
-	-moz-border-radius-topright: 8px;
-}
-.mblRoundRectList-withCategory-FirstListItem-styles () {
-}
-.mblRoundRectList-LastListItem-styles () {
-	border-bottom-width: 0px;
-	-webkit-border-bottom-left-radius: 8px;
-	-webkit-border-bottom-right-radius: 8px;
-	-moz-border-radius-bottomleft: 8px;
-	-moz-border-radius-bottomright: 8px;
+	color: #4c566c;
+	text-shadow: rgba(255, 255, 255, 1) 0 1px 0;
 }
 
 // EdgeToEdgeList.less
 .mblEdgeToEdgeList-styles () {
-	margin: 0px;
-	padding: 0px;
 	background-color: white;
 }
 .mblEdgeToEdgeList-LastListItem-styles () {
-	border-bottom-color: #707C84;
+	border-bottom-color: #707c84;
 }
 
 // ListItem.less
+ at mbl-list-item-height: 43px;
+//
 .mblListItem-styles () {
-	padding: 0px 0px 0px 8px;
-	height: 43px;
-	border-bottom: 1px solid #ADAAAD;
+	border-bottom: 1px solid #adaaad;
 	font-weight: bold;
 	color: black;
-	line-height: 43px;
-}
-.mblListItem-mblVariableHeight-styles () {
-	padding: 11px 0px 10px 6px;
-	line-height: normal;
 }
-.mblListItem-mblListItemAnchor-styles () {
-	background-position: 9px 7px;
-	text-decoration: none;
-	padding-right: 7px;
+.mblListItemSelected-styles () {
+	color: @default-selected-color;
+	.default-selected-background-image();
 }
-.mblItemSelected-styles () {
-	background-color: #048BF4;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#048BF4), to(#005CE5));
-}
-.mblItemSelected-mblListItemAnchor-styles () {
-	color: white;
-}
-.mblItemSelected-mblDomButton-Div-styles () {
-	border-color: white;
-}
-.mblItemSelected-mblListItemSubText-styles () {
-}
-.mblListItemTextBoxSelected-styles () {
-	background-color: #048BF4;
+.mblListItemLabelSelected-styles () {
+	background-color: #048bf4;
 }
 .mblListItemChecked-styles () {
-	color: #314E84;
-}
-.mblListItemIcon-styles () {
-	margin-top: 7px;
-	margin-right: 11px;
-}
-.mblListItemSpriteIcon-styles () {
-	margin-top: 7px;
-	margin-left: 8px;
-}
-.mblListItemRightIcon-styles () {
-	margin-top: 7px;
-	margin-bottom: -7px;
+	color: #314e84;
 }
 .mblListItemRightText-styles () {
-	color: #324F85;
-	margin: 11px 4px 0 0;
-}
-.mblListItemTextBox-styles () {
-}
-.mblListItemAnchorNoIcon-mblListItemTextBox-styles () {
+	color: #324f85;
+	margin-top: 12px;
 }
 .mblListItemSubText-styles () {
 }
 
 // Switch.less
-.mblItemSwitch-styles () {
-	top: 8px;
-}
+ at mbl-switch-bg-left-background-color: #2859b1;
+.mbl-switch-bg-left-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#2859b1, #75acfb, 0.5, #3f84eb, 0.5, #4c8eee); }
+ at mbl-switch-bg-right-background-color: #cecece;
+.mbl-switch-bg-right-background-image () { .background-image-linear-gradient-top-bottom-2-stops(#cecece, #fdfdfd, 0.5, #eeeeee, 0.5, #f8f8f8); }
+.mbl-switch-knob-background-image () { .background-image-linear-gradient-top-bottom(#cccccc, #fafafa); }
+//
+ at mbl-switch-bg-left-background-image-gecko: -moz-linear-gradient(top, #2859b1 0%, #3f84eb 50%, #4c8eee 50%, #75acfb 100%);
+ at mbl-switch-bg-right-background-image-gecko: -moz-linear-gradient(top, #cecece 0%, #eeeeee 50%, #f8f8f8 50%, #fdfdfd 100%);
+ at mbl-switch-knob-background-image-gecko: -moz-linear-gradient(top, #cccccc 0%, #fafafa 100%);
+//
+ at mbl-switch-square-border-radius: 5px;
+//
 .mblSwitchBg-styles () {
-	-webkit-border-radius: 5px;
-}
-.mblSwitchBgLeft-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#2859B1), to(#75ACFB), color-stop(0.5, #3F84EB), color-stop(0.5, #4C8EEE));
-}
-.mblSwitchBgRight-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#CECECE), to(#FDFDFD), color-stop(0.5, #EEEEEE), color-stop(0.5, #F8F8F8));
+	border-width: 1px;
+	border-style: solid;
+	border-color: #939393 #aaaaaa #cbcbcb #767676;
 }
 .mblSwitchKnob-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#CCCCCC), to(#FAFAFA));
-	-webkit-border-radius: 5px;
+	border-width: 1px;
+	border-style: solid;
+	border-color: #5e5e5e #9e9e9e #828282 #797979;
 }
 
 // Button.less
 .mblButton-styles () {
-	padding: 0px 10px;
-	height: 29px;
-	border: #9CACC0 1px outset;
-	-webkit-border-radius: 5px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FDFDFD), to(#CECECE), color-stop(0.5, #F8F8F8), color-stop(0.5, #EEEEEE));
+	.default-button-border-styles;
 	color: black;
-	font-family: Helvetica;
 	font-size: 13px;
-	line-height: 29px;
 }
-.mblButton-mblBlueButton-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7A9DE9), to(#2362DD), color-stop(0.5, #366EDF), color-stop(0.5, #215FDC));
-	color: white;
+.mblButtonSelected-styles () {
+	color: black;
 }
-.mblButton-mblBlueButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
+.mblButton-mblBlueButton-styles () {
 	color: white;
 }
 .mblButton-mblRedButton-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FA9D58), to(#EE4115), color-stop(0.5, #FF4D25), color-stop(0.5, #ED4D15));
-	color: white;
-}
-.mblButton-mblRedButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#C1A48E), to(#9B6C4A), color-stop(0.5, #A27758), color-stop(0.5, #996947));
 	color: white;
 }
-.mblButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F0F0F0), to(#BFBFBF), color-stop(0.5, #EBEBEB), color-stop(0.5, #DEDEDE));
-	color: black;
-}
-.mblButtonDisabled-styles () {
-	border-color: grey;
-	background-image: none;
-	color: grey;
-}
 
 // CheckBox.less
 .mblCheckBox-styles () {
-	margin: -0.5em 3px 0.3em 4px;
-	width: 1em;
-	height: 1em;
-	border: #9CACC0 1px outset;
-	-webkit-border-radius: 5px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FDFDFD), to(#CECECE), color-stop(0.5, #F8F8F8), color-stop(0.5, #EEEEEE));
-	font: inherit;
-	-webkit-transform: translateY(0.45em);
-}
-.mblCheckBoxSelected-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F0F0F0), to(#BFBFBF), color-stop(0.5, #EBEBEB), color-stop(0.5, #DEDEDE));
-}
-.mblCheckBoxChecked-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7A9DE9), to(#2362DD), color-stop(0.5, #366EDF), color-stop(0.5, #215FDC));
+	.default-button-border-styles;
 }
 .mblCheckBoxChecked-after-styles () {
-	position: absolute;
-	content: "";
-	width: 0.3em;
-	height: 0.6em;
-	top: 0;
-	left: 0.3em;
 	border-color: white;
-	border-width: 0.15em;
-	border-style: none solid solid none;
-	-webkit-transform: rotate(45deg);
-	-webkit-transform-origin: 50% 50%;
-}
-.mblCheckBoxChecked-mblCheckBoxSelected-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
 }
 .mblCheckBoxChecked-mblCheckBoxSelected-after-styles () {
-	border-color: #9CACC0;
 }
 
 // ComboBox.less
+ at mbl-combo-box-popup-box-shadow: 0 0 50px black;
+//
 .dijitPopup-styles () {
-	-webkit-box-shadow: 0px 0px 50px black;
-	-webkit-border-radius: 0px;
+	border-radius: 0;
 }
 .mblComboBoxMenu-styles () {
-	border: 1px solid black;
-	-webkit-border-radius: 0px;
+	border-radius: 0;
 	background-color: white;
 }
-.mblComboBoxMenuItemSelected-styles () {
-	background-color: black;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#048BF4), to(#005CE5));
-	color: white;
-}
 .mblComboBoxMenuItem-styles () {
-	padding: .1em .2em;
-	border-width: 1px 0 1px 0;
-	border-style: solid;
 	border-color: #ffffff;
 	color: inherit;
-	text-align: left;
 }
-.mblComboBoxMenuPreviousButton-styles () {
-	font-style: italic;
-	overflow: hidden;
+.mblComboBoxMenuItemSelected-styles () {
+	.default-selected-background-image();
+	color: white;
 }
 
 // IconContainer.less
-.mblIconContainer-styles () {
-	margin: 20px 0px 0px 10px;
-	padding: 0px 0px 40px 0px;
-}
-
-// IconItem.less
-.mblIconItemTerminator-styles () {
-	height: 20px;
-}
 .mblIconItemSub-styles () {
-	margin-left: -10px;
 	background-color: white;
 }
 .mblIconArea-styles () {
-	margin-bottom: 10px;
-	height: 78px;
+	margin-top: 5px;
+	margin-bottom: 5px;
 	width: 74px;
-	font-family: Helvetica;
-	font-size: 12px;
-	text-align: center;
-}
-.mblContent-styles () {
-	padding-bottom: 20px;
-}
-.mblIconContentHeading-styles () {
-	margin-top: 0px;
-	padding-left: 40px;
-	height: 25px;
-	border-top: 1px solid #F1F3F4;
-	border-bottom: 1px solid #717D85;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#E0E4E7), to(#B4BEC6), color-stop(0.5, #C4CCD2), color-stop(0.5, #BFC8CE));
-	font-family: Helvetica;
-	font-size: 14px;
-	color: white;
-	line-height: 26px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
+}
+.mblIconItemDeleteIcon-styles () {
+	top: -4px;
+	left: -2px;
 }
 
 // RadioButton.less
 .mblRadioButton-styles () {
-	margin: -0.5em 3px 0.3em 4px;
-	width: 1em;
-	height: 1em;
-	border: #9CACC0 1px outset;
-	-webkit-border-radius: 0.5em;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FDFDFD), to(#CECECE), color-stop(0.5, #F8F8F8), color-stop(0.5, #EEEEEE));
-	font: inherit;
-	-webkit-transform: translateY(0.45em);
-}
-.mblRadioButtonChecked-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7A9DE9), to(#2362DD), color-stop(0.5, #366EDF), color-stop(0.5, #215FDC));
+	border-color: #9cacc0;
 }
 .mblRadioButtonChecked-after-styles () {
-	content: "";
-	width: 0.3em;
-	height: 0.6em;
-	top: 0;
-	left: 0.25em;
 	border-color: white;
-	border-width: 0.15em;
-	border-style: none solid solid none;
-	border-color: white;
-	-webkit-transform: rotate(45deg);
-	-webkit-transform-origin: 50% 50%;
-}
-.mblRadioButtonChecked-Selected-styles () {
-	border-color: #9CACC0;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
 }
 .mblRadioButtonChecked-Selected-after-styles () {
 	border-color: white;
 }
 
 // Slider.less
+ at mbl-slider-bar-border-radius: 8px;
+ at mbl-slider-knob-border-radius: 10px;
+//
 .mblSlider-styles () {
-	margin: 15px; /* 1/2 handle width for hanging off the ends of the bar */
-	border: #B0B0B0 1px inset;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#ABABAB), to(#FEFEFE));
-	-webkit-border-radius: 8px;
-}
-.mblSliderProgressBar-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#0D48A8), to(#68A6F8));
-	-webkit-border-radius: 8px;
+	border-color: #b0b0b0;
 }
 .mblSliderHandle-styles () {
-	margin: -10px 0 0 -10px;
-	width: 18px;
-	height: 18px;
-	border: #9D9D9D 1px outset;
-	-webkit-border-radius: 10px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#A6A6A6), to(#FCFCFC));
+	border-color: #9d9d9d;
 }
 
 // TabBar.less
 .mblTabBar-styles () {
-	margin: 0px;
-	padding: 0px;
-	height: 48px;
-	border-top: 1px solid #000000;
-	background-color: #000000;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#2D2D2D), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
-	color: white;
-	text-align: center;
+	text-shadow: rgba(0,0,0,0.6) 0 -1px 0;
 }
-.mblTabBar-TabBarButton-styles () {
+
+// barType="tabBar"
+.mblTabBarTabBar-styles () {
+	.background-image-linear-gradient-top-bottom-2-stops(#2d2d2d, #000000, 0.5, #141414, 0.5, #000000);
 }
-.mblTabBar-TabBarButton-Selected-styles () {
-	-webkit-border-radius: 3px;
-	background-color: #404040;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#484848), to(#242424), color-stop(0.5, #353535), color-stop(0.5, #242424));
+.mblTabBarTabBar-compat () {
+	background-color: #000000;
 }
-.mblTabBarButtonDiv-styles () {
-	height: 34px;
-	width: 29px;
+.mblTabBarTabBarButton-styles () {
 }
-.mblTabBarButtonIcon-styles () {
-	left: 0px;
-	top: 2px;
+.mblTabBarTabBarButtonIconArea-styles () {
 }
-.mblTabBarButtonTextBox-styles () {
+.mblTabBarTabBarButtonLabel-styles () {
 	color: #979797;
-	font-family: "Helvetica Neue", Helvetica;
-	font-size: 11px;
 }
-.mblTabBarNoIcons-TabBarButtonTextBox-styles () {
-	line-height: 34px;
-	font-size: 20px;
-}
-.mblTabButton-styles () {
-	width: 100px;
-	height: 28px;
-	border-width: 1px 1px 1px 0px;
-	border-style: inset;
-	border-color: #9CACC0;
-	border-right-color: #5E708A;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#ABB9CA), to(#788DA9), color-stop(0.5, #8297AF), color-stop(0.5, #768BA7));
-	font-family: Helvetica;
-	font-size: 13px;
-	color: white;
-	text-align: center;
-	line-height: 29px;
+.mblTabBarTabBarButtonSelected-styles () {
+	background-color: #404040;
+	.background-image-linear-gradient-top-bottom-2-stops(#484848, #242424, 0.5, #353535, 0.5, #242424);
 }
-.mblTabButton-TabBarButtonAnchor-styles () {
-	height: 29px;
+.mblTabBarTabBarButtonLabelSelected-styles () {
+	color: white;
 }
-.mblTabBarTop-TabButton-TabBarButtonDiv-styles () {
-	display: none;
+
+// barType="segmentedControl"
+ at mbl-tab-bar-segmented-control-border-radius: 5px;
+//
+.mblTabBarSegmentedControl-styles () {
 }
-.mblTabBarHead-TabButton-TabBarButtonDiv-styles () {
+.mblTabBarSegmentedControlButton-styles () {
+	border-style: solid;
+	border-color: #2f3740 #405a7e #375073 #3a4755;
+	color: @default-button-color;
+	.heading-background-image();
+	.box-shadow(0 1px 0 rgba(255, 255, 255, 0.305));
 }
-.mblTabButton-FirstTabButtom-styles () {
-	-webkit-border-top-left-radius: 5px;
-	-webkit-border-bottom-left-radius: 5px;
-	border-left-width: 1px;
+.mblTabBarSegmentedControlButton-compat-gecko () {
+	-moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.305);
 }
-.mblTabButton-LastTabButton-styles () {
-	-webkit-border-top-right-radius: 5px;
-	-webkit-border-bottom-right-radius: 5px;
-	border-right-color: #9CACC0;
+.mblTabBarSegmentedControlButtonSelected-styles () {
+	.default-button-background-image();
 }
-.mblTabButton-img-styles () {
+
+// barType="standardTab"
+.mblTabBarStandardTab-styles () {
 }
-.mblTabBarButtonTextBoxSelected-styles () {
-	color: white;
+.mblTabBarStandardTabButton-styles () {
+	color: @default-button-color;
+	.heading-background-image();
 }
-.mblTabButtonSelected-styles () {
+.mblTabBarStandardTabButtonIconArea-styles () {
 }
-.mblTabButtonHighlighted-styles () {
+.mblTabBarStandardTabButtonLabel-styles () {
 }
-.mblTabButtonImgDiv-styles () {
-	display: none;
+.mblTabBarStandardTabButtonSelected-styles () {
+	background-color: @default-button-background-color;
+	.default-button-background-image();
 }
-.mblTabPanelHeader-styles () {
-	margin: 0px;
-	padding: 3px 0px 0px 0px;
-	height: 39px;
-	border-top: 1px solid #CDD5DF;
-	border-bottom: 1px solid #2D3642;
-	background-color: #889BB3;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#B0BCCD), to(#6D84A2), color-stop(0.5, #889BB3), color-stop(0.5, #8195AF));
-	font-family: Helvetica;
-	font-size: 20px;
-	color: white;
-	text-align: center;
-	line-height: 44px;
-	text-shadow: rgba(0,0,0,0.6) 0px -1px 0px;
+.mblTabBarStandardTabButtonLabelSelected-styles () {
 }
-.mblTabPanelHeader-TabButton-styles () {
-	margin-top: 3px;
+
+// barType="tallTab"
+.mblTabBarTallTab-styles () {
+	.background-image-linear-gradient-top-bottom-2-stops(#2d2d2d, #000000, 0.5, #141414, 0.5, #000000);
 }
-.mblTabPanelHeader-TabButtonSelected-styles () {
-	background-color: #5877A2;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
-}	
-.mblTabPanelHeader-TabButtonDomButton-styles () {
-	width: 43px;
+.mblTabBarTallTabButton-styles () {
+	background-color: #212421;
+	background-image: none;
 }
-.mblTabPanelHeader-TabButtonDomButtonClass-styles () {
-	left: 8px;
+.mblTabBarTallTabButton-FirstChild-styles () {
 }
-.mblTabPanelHeader-DomButton-styles () {
+.mblTabBarTallTabButton-LastChild-styles () {
 }
-.mblTabPanelHeader-inHeading-styles () {
+.mblTabBarTallTabButtonIconArea-styles () {
 }
-.mblTabPanelHeader-TabButton-inHeading-styles () {
-	margin-top: 6px;
+.mblTabBarTallTabButtonLabel-styles () {
 }
-.mblTabPanelHeader-TabButton-FirstTabButtom-inHeading-styles () {
+.mblTabBarTallTabButtonSelected-styles () {
+	background-color: #636363;
+	background-image: none;
 }
-.mblTabPanelHeader-TabButton-LastTabButtom-inHeading-styles () {
+.mblTabBarTallTabButtonLabelSelected-styles () {
 }
-.mblTabPanelHeader-TabButtonSelected-inHeading-styles () {
-}	
 
 // TextArea.less
 .mblTextArea-styles () {
-	padding: 4px 1px;
-	border-color: #9CACC0;
-	border-width: 1px;
-	border-style: inset;
-	-webkit-border-radius: 5px;
-	font-family: Helvetica;
-	font-size: 13px;
-}
-.mblExpandingTextArea-styles () {
-	margin: 2px;
+	.default-button-border-styles;
 }
 
 // TextBox.less
 .mblTextBox-styles () {
-	height: 22px;
-	border: #9CACC0 1px inset;
-	-webkit-border-radius: 5px;
-	font-family: Helvetica;
-	font-size: 13px;
+	.default-button-border-styles;
 }
 
 // ToggleButton.less
 .mblToggleButton-styles () {
-	padding: 0px 10px 0px 25px;
-	height: 29px;
-	border-width: 1px 1px 1px 1px;
-	border-style: outset;
-	border-color: #9CACC0;
-	-webkit-border-radius: 5px;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FDFDFD), to(#CECECE), color-stop(0.5, #F8F8F8), color-stop(0.5, #EEEEEE));
-	font-family: Helvetica;
+	.default-button-border-styles;
 	font-size: 13px;
 	color: black;
-	line-height: 29px;
 }
 .mblToggleButtonSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#F0F0F0), to(#BFBFBF), color-stop(0.5, #EBEBEB), color-stop(0.5, #DEDEDE));
-	color: black;
 }
 .mblToggleButtonChecked-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#7A9DE9), to(#2362DD), color-stop(0.5, #366EDF), color-stop(0.5, #215FDC));
 	color: white;
 }
 .mblToggleButtonChecked-after-styles () {
-	content: "";
-	top: 6px;
-	left: 7px;
-	width: 5px;
-	height: 10px;
 	border-color: white;
-	border-width: 2px;
-	border-style: none solid solid none;
-	-webkit-transform: rotate(45deg) skew(10deg);
-	-webkit-transform-origin: 50% 50%;
 }
 .mblToggleButtonCheckedSelected-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#8EA4C1), to(#4A6C9B), color-stop(0.5, #5877A2), color-stop(0.5, #476999));
-	color: white;
 }
 .mblToggleButtonCheckedSelected-after-styles () {
-	border-color: white;
-}
-.mblToggleButtonDisabled-styles () {
-	border-color: grey;
-	background-image: none;
-	color: grey;
 }
 
 // Overlay.less
 .mblOverlay-styles () {
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#FDFDFD), to(#CECECE));
+	.background-image-linear-gradient-top-bottom(#fdfdfd, #cecece);
+}
+.mblOverlay-compat () {
+	background-color: #cecece;
+	background-image: none;
+}
+.mblOverlay-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #fdfdfd 0%, #cecece 100%);
 }
 
 // Tooltip.less
+ at mbl-tooltip-border-radius: 8px;
+//
 .mblTooltip-styles () {
-	padding: 5px;
-	border: #5A5A5A 1px solid;
-	background-color: #121B2F;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#656872), to(#121B2F), color-stop(0.1,#2C3345),color-stop(0.1,#161F32));
-	-webkit-border-radius: 8px;
-	opacity: .97;
+	border-color: #5a5a5a;
+	border-radius: @mbl-tooltip-border-radius;
+	background-color: #121b2f;
+	.background-image-linear-gradient-top-bottom-2-stops(#656872, #121b2f, 0.1, #2c3345, 0.1, #161f32);
 }
 .mblTooltipBubble-styles () {
 	background-color: #f9f7ba;
@@ -674,24 +468,21 @@
 .mblTooltipInnerArrow-Bubble-Before-styles () {
 	border-right-color: #f9f7ba;
 }
-.mblTooltipArrow-styles () {
-	border: 11px solid transparent;
-}
 .mblTooltipArrow-Before-styles () {
 	border-left-width: 0;
-	border-right-color: #5A5A5A;
+	border-right-color: #5a5a5a;
 }
 .mblTooltipArrow-After-styles () {
 	border-right-width: 0;
-	border-left-color: #5A5A5A;
+	border-left-color: #5a5a5a;
 }
 .mblTooltipArrow-Above-styles () {
 	border-top-width: 0;
-	border-bottom-color: #5A5A5A;
+	border-bottom-color: #5a5a5a;
 }
 .mblTooltipArrow-Below-styles () {
 	border-bottom-width: 0;
-	border-top-color: #5A5A5A;
+	border-top-color: #5a5a5a;
 }
 .mblTooltipInnerArrow-Before-styles () {
 	border-left-width: 0;
@@ -710,17 +501,279 @@
 	border-top-color: #172035;
 }
 .mblTooltip-Heading-styles () {
-	border-top: 3px solid #4F5055;
-	border-bottom: 1px solid #2D3642;
-	border-left: 1px solid #2A2D47;
-	-webkit-border-radius: 3px 3px 0 0;
-	background-color: #889BB3;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#5E6167), to(#1A1D24), color-stop(0.5, #2E322B));
+	border-top: 3px solid #4f5055;
+	border-bottom: 1px solid #2d3642;
+	border-left: 1px solid #2a2d47;
+	border-radius: 3px 3px 0 0;
+	background-color: #889bb3;
+	.background-image-linear-gradient-top-bottom-1-stop(#5e6167, #1a1d24, 0.5, #2e322b);
 	font-weight: normal;
 }
+.mblTooltip-Heading-compat () {
+	background-image: url(compat/tooltip-heading-bg.png);
+}
 .mblTooltip-Heading-ToolbarButton-styles () {
 	border: 1px inset #434450;
-	background-image: -webkit-gradient(linear, left top, left bottom, from(#686F80), to(#000924), color-stop(0.5, #000B29));
+	.background-image-linear-gradient-top-bottom-1-stop(#686f80, #000924, 0.5, #000b29);
 	font-weight: normal;
 }
+.mblTooltip-Heading-ToolbarButton-compat () {
+	background-color: #000924;
+	background-image: url(compat/tooltip-button-bg.png);
+}
+
+// Accordion.less
+.mblAccordion-styles () {
+	border-color: #8c8f91;
+}
+.mblAccordionTitle-styles () {
+	border-top: 1px solid #8c8f91;
+	.background-image-linear-gradient-top-bottom-1-stop(#fcfcfc, #e1e5e8, 0.2, #f0f2f3);
+}
+.mblAccordionTitle-compat () {
+	background-color: #f0f2f3;
+}
+.mblAccordionTitle-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #fcfcfc 0%, #f0f2f3 20%, #e1e5e8 100%);
+}
+.mblAccordionTitleSelected-styles () {
+	border-bottom: 1px solid #8c8f91;
+	.background-image-linear-gradient-top-bottom-1-stop(#97afc0, #46708e, 0.2, #7796ac);
+	color: white;
+}
+.mblAccordionTitleSelected-compat () {
+	background-color: #7796ac;
+}
+.mblAccordionTitleSelected-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #97afc0 0%, #7796ac 20%, #46708e 100%);
+}
+.mblAccordionTitleAnchor-styles () {
+	color: black;
+}
+.mblAccordionTitleAnchorSelected-styles () {
+	color: white;
+}
+
+// SimpleDialog.less
+ at mbl-simple-dialog-border-radius: 10px;
+//
+.mblSimpleDialog-styles () {
+	padding: 5px;
+	width: 262px;
+}
+.mblSimpleDialogDecoration-styles () {
+	background-color: rgba(35,50,96,0.85);
+	.background-image-linear-gradient-top-bottom-2-stops(rgba(150,150,170,0.85), rgba(18,29,68,0.85), 0.15, rgba(77,85,119,0.85), 0.15, rgba(35,50,96,0.85));
+	border: 2px solid #bac1d3;
+	border-top-color: #eaeaf2;
+	.box-shadow(0 3px 2px #000000);
+	color: white;
+}
+.mblSimpleDialogDecoration-compat () {
+	background-color: #233260;
+}
+.mblSimpleDialogDecoration-compat-gecko () {
+	background-color: rgba(35,50,96,0.85);
+	background-image: -moz-linear-gradient(top, rgba(150,150,170,0.85) 0%, rgba(77,85,119,0.85) 15%, rgba(35,50,96,0.85) 15%, rgba(18,29,68,0.85) 100%);
+	-moz-box-shadow: 0 3px 2px #000000;
+}
+.mblSimpleDialogTitle-styles () {
+	margin: 14px 0 7px;
+	width: 262px;
+	font-weight: bold;
+}
+.mblSimpleDialogText-styles () {
+	margin: 7px 0 14px;
+	width: 262px;
+}
+
+// IconMenu.less
+ at mbl-icon-menu-border-radius: 10px;
+ at mbl-icon-menu-item-border-radius: 10px;
+//
+.mblIconMenu-styles () {
+	padding: 0;
+	.background-image-linear-gradient-top-bottom-1-stop(rgba(102,102,119,0.85), rgba(4,4,4,0.85), 0.35, rgba(22,22,30,0.85));
+	border: 2px solid #9a9a9e;
+	border-top-color: #f2f2f3;
+	.box-shadow(1px 3px 5px rgba(0,0,0,0.5));
+}
+.mblIconMenu-compat () {
+	background-color: #040404;
+}
+.mblIconMenu-compat-gecko () {
+	background-color: transparent;
+	background-image: -moz-linear-gradient(top, rgba(102,102,119,0.85) 0%, rgba(22,22,30,0.85) 35%, rgba(4,4,4,0.85) 100%);
+	-moz-box-shadow: 1px 3px 5px rgba(0,0,0,0.5);
+}
+.mblIconMenuItem-styles () {
+	border-left: 1px solid #6b6c6f;
+	border-bottom: 1px solid #6b6c6f;
+}
+.mblIconMenuItemAnchor-styles () {
+	font-size: 11px;
+	color: #b8bbc0;
+}
+.mblIconMenuItemSel-styles () {
+  .background-image-linear-gradient-top-bottom-1-stop(rgba(139,157,229,0.6), rgba(10,54,233,0.8), 0.6, rgba(10,54,233,0.8));
+}
+.mblIconMenuItemSel-compat () {
+	background-color: #0a36e9;
+}
+.mblIconMenuItemSel-compat-gecko () {
+	background-color: transparent;
+	background-image: -moz-linear-gradient(top, rgba(139,157,229,0.6) 0%, rgba(10,54,233,0.8) 60%, rgba(10,54,233,0.8) 100%);
+}
 
+// dijit.Calendar
+.dijitCalendar-styles () {
+	border: solid 1px #b5bcc7;
+	background-color: #dddde0;
+}
+.dijitCalendar-thead-styles () {
+	.background-image-linear-gradient-top-bottom(#f6f6f6, #ccccd1);
+}
+.dijitCalendar-thead-compat () {
+	background-image: url(compat/calendar-month-bg.png);
+}
+.dijitCalendar-thead-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #f6f6f6 0%, #ccccd1 100%);
+}
+.dijitCalendarMonthLabel-styles () {
+	color: #545454;
+	font-size: 22px;
+}
+.dijitCalendarMonthMenu-styles () {
+}
+.dijitCalendarMonthMenu-compat-ff3 () {
+}
+.dijitCalendarMonthMenu-Label-styles () {
+}
+.dijitCalendarDecrease-styles () {
+	border-right: 6px solid #545454 !important;
+}
+.dijitCalendarIncrease-styles () {
+	border-left: 6px solid #545454 !important;
+}
+.dijitCalendarDayLabelTemplate-styles () {
+	font-size: 9px;
+	color: #545454;
+}
+.dijitCalendarDateTemplate-styles () {
+	background-color: #dddde0;
+	color: #4a5b6e;
+	text-shadow: rgba(231,231,233,1.0) 0 1px 0;
+}
+.dijitCalendarDateTemplate-LastChild-styles () {
+}
+.dijitCalendarDateLabel-DateTemplate-styles () {
+	border-top: solid 1px #eceeef; 
+	border-bottom: solid 1px #a6aab3; 
+	border-left: solid 1px #a0a4ad; 
+	border-right: solid 1px #ececed; 
+	background-color: rgba(171, 212, 251, 0);
+	.transition-property-2(background-color, border);
+	.transition-duration(0.35s);
+}
+.dijitCalendarDateLabel-PrevMonth-styles () {
+	color: #9099a4;
+}
+.dijitCalendarDateLabel-Hovered-styles () {
+	border: solid 1px #769dc0;
+	color: black;
+}
+.dijitCalendarDateLabel-Selected-styles () {
+	border: solid 1px #1037b3; 
+	background-color: #1a80e5;
+	color: white;
+	text-shadow: rgba(0,0,0,0.4) 0 1px 0;
+}
+.dijitCalendarDateLabel-Selected-compat () {
+}
+.dijitCalendarDateLabel-Selected-compat-gecko () {
+}
+.dijitCalendarDateLabel-Active-styles () {
+	border: solid 1px white;
+	background-color: #1a80e5;
+	.transition-duration(0.1s);
+}
+.dijitCalendarDateLabel-Active-compat () {
+}
+.dijitCalendarDateLabel-Active-compat-gecko () {
+}
+.dijitCalendarYearLabel-styles () {
+	padding: 2px 0 0 0;
+	.background-image-linear-gradient-top-bottom(#f6f6f6, #ccccd1);
+}
+.dijitCalendarYearLabel-compat () {
+	background-image: url(compat/calendar-year-bg.png);
+}
+.dijitCalendarYearLabel-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #f6f6f6 0%, #ccccd1 100%);
+}
+.dijitCalendarSelectedYear-styles () {
+	color: #545454;
+	font-size: 1.091em;
+}
+.dijitCalendarNextYear-styles () {
+	padding: 1px 6px 1px 6px;
+	color: #545454;
+	font-size: 0.909em;
+}
+
+// SearchBox.less
+ at mbl-searchbox-cancel-button-color: white;
+ at mbl-searchbox-cancel-button-bg-color: #b2b2b2;
+.mblSearchBox-Cancel-Button-styles () {
+	border-radius: 1em;
+}
+ at mbl-searchbox-results-decoration-color: #93989c;
+
+// ProgressBar.less
+.mblProgressBar-styles () {
+	border-radius: 6px;
+	height: 9px;
+	.background-image-linear-gradient-top-bottom-3-stops(#a5a6a5, #b5b6b5, 0.5, #d6d7d6, 0.5, #ffffff, 0.9, #ffffff);
+}
+.mblProgressBarProgress-styles () {
+	height: 7px;
+	border:1px solid #5e6fa3;
+	border-radius: 6px;
+	.background-image-linear-gradient-top-bottom-2-stops(#b0c0ff, #2f83e1, 0.6, #70b2ff, 0.6, #3470b6);
+}
+.mblProgressBarComplete-styles () {
+}
+.mblProgressBarNotStarted-styles () {
+}
+.mblProgressBarMsg-styles () {
+	top: -1px;
+	font-size: 10px;
+}
+.mblProgressBar-compat () {
+	background-color: white;
+}
+.mblProgressBarProgress-compat () {
+	background-color: #3186e7;
+}
+.mblProgressBar-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #a5a6a5 0%, #d6d7d6 50%, #ffffff 50%, #ffffff 90%, #b5b6b5 100%);
+}
+.mblProgressBarProgress-compat-gecko () {
+	background-image: -moz-linear-gradient(top, #b0c0ff 0%, #70b2ff 60%, #3470b6 60%, #2f83e1 100%);
+}
+
+// ValuePicker.less
+.mbl-value-picker-slot-button-background-image () { .background-image-linear-gradient-top-bottom-4-stops-no-from-to(0.1, #9cb1c9, 0.35, #f0f1f5, 0.65, #f0f1f5, 0.9, #9cb1c9); }
+ at mbl-value-picker-slot-button-background-image-gecko: -moz-linear-gradient(top, #9cb1c9 10%, #f0f1f5 35%, #f0f1f5 65%, #9cb1c9 90%);
+ at mbl-value-picker-slot-button-radius: 0;
+.mbl-value-picker-slot-input-area-background-image () { .background-image-linear-gradient-top-bottom-4-stops-no-from-to(0.1, #eaeaea, 0.2, #fafafa, 0.5, #ffffff, 0.9, #efefef); }
+ at mbl-value-picker-slot-input-area-background-image-gecko: -moz-linear-gradient(top, #eaeaea 10%, #fafafa 20%, #ffffff 50%, #efefef 90%);
+.mblValuePickerSlot-style () {
+  margin: 0 3px;
+  border-left: solid 2px #000000;
+  border-right: solid 2px #000000;
+  border-radius: 3px;
+}
+.mblValuePickerSlot-input-style () {
+  font: bold 24px/44px Helvetica, sans-serif;
+}
diff --git a/dojox/mobile/themes/iphone/variables_rtl.less b/dojox/mobile/themes/iphone/variables_rtl.less
new file mode 100644
index 0000000..cc4ceaf
--- /dev/null
+++ b/dojox/mobile/themes/iphone/variables_rtl.less
@@ -0,0 +1,32 @@
+// Carousel_rtl
+ at mbl-carousel-margin-rtl: ~"2px 4px 2px 0px";
+
+// IconContainer_rtl
+ at mbl-icon-container-right-rtl: -2px;
+
+// IconMenu_rtl-compat
+ at mbl-border-radius-rtl: 10px;
+
+// TabBar_rtl-compat
+ at mbl-moz-border-radius-rtl: 5px;
+
+// TabBar_rtl
+ at mbl-border-width-rtl: ~"1px 0px 1px 1px !important";
+ at mbl-tb-border-radius-rtl: 5px;
+
+// ThemeID
+ at theme-id: iphone;
+
+// Switch_rtl-compat
+ at mbl-bg-image-r-rtl: ~"url(compat/switch-round1-r.gif)";
+ at mbl-bg-image-l-rtl: ~"url(compat/switch-round1-l.gif)";
+
+// Switch_rtl
+ at mbl-switchOn-left-rtl: -50px;
+ at mbl-switchBg-left-rtl: 50px;
+ at mbl-switch-knob-rtl: 50px;
+ at mbl-switch-text-right-rtl: -26px;
+
+// ToolBarButton_rtl
+ at mbl-toolbar-right-arrow-rtl: 1px;
+ at mbl-toolbar-left-arrow-rtl: 0px;
diff --git a/dojox/mobile/themes/utils/README b/dojox/mobile/themes/utils/README
new file mode 100644
index 0000000..a3c44df
--- /dev/null
+++ b/dojox/mobile/themes/utils/README
@@ -0,0 +1,26 @@
+-------------------------------------------------------------------------------
+Dojo Mobile Themes
+-------------------------------------------------------------------------------
+
+Dojo provides platform-specific themes for Android 2, Android 3/4, iOS and Blackberry. There is also a generic theme named "custom".  
+
+All themes are generated using the Less CSS library (http://lesscss.org/).
+
+Building mobile themes
+----------------------
+
+1. Install Node.js (http://nodejs.org/). 
+
+2. Run compile.bat or compile.sh to generate all themes.
+
+You can also run cleanup.bat or cleanup.sh to remove all the generated css files.  
+
+
+Creating a new theme from the Custom theme
+------------------------------------------     
+
+The 'custom' theme (i.e. mobile/themes/custom folder) is a generic grey theme. It is a good starting point for creating a new theme. All colors of this theme are derived from 2 colors defined at the beginning of themes/custom/variables.less.
+
+To create a new theme, you can change these colors (i.e. @lightColor and @darkColor) as well as other part of variables.less and then run the compile script.
+
+   
diff --git a/dojox/mobile/themes/utils/cleanup.bat b/dojox/mobile/themes/utils/cleanup.bat
new file mode 100644
index 0000000..1032ff3
--- /dev/null
+++ b/dojox/mobile/themes/utils/cleanup.bat
@@ -0,0 +1,2 @@
+node cleanup.js
+pause
diff --git a/dojox/mobile/themes/utils/cleanup.js b/dojox/mobile/themes/utils/cleanup.js
new file mode 100644
index 0000000..eb89f1a
--- /dev/null
+++ b/dojox/mobile/themes/utils/cleanup.js
@@ -0,0 +1,46 @@
+var fs = require("fs");
+
+clean("../android");
+clean("../android/dijit");
+clean("../iphone");
+clean("../iphone/dijit");
+clean("../blackberry");
+clean("../blackberry/dijit");
+clean("../holodark");
+clean("../holodark/dijit");
+clean("../windows");
+clean("../windows/dijit");
+clean("../custom");
+clean("../custom/dijit");
+
+clean("../common/transitions");
+clean("../common/domButtons");
+
+// Remove css files that have a matching less file in the same folder or in common folder
+function clean(folder){ 	
+	var cssFiles = [];
+	getFiles(folder, /.*.css$/, cssFiles);
+	var lessFiles = {};
+	getFiles("../common/", /.*.less$/, lessFiles);
+	getFiles(folder, /.*.less$/, lessFiles);
+	
+	for(var i=0; i < cssFiles.length; i++){
+		if(lessFiles[cssFiles[i].replace(".css", ".less")]){ 
+			console.log("deleting", folder + "/" + cssFiles[i]);
+			fs.unlink(folder + "/" + cssFiles[i], function(err){if(err){console.log(err);}});			
+		}
+	}
+	
+}
+
+function getFiles(folder, pattern, dest){
+	fs.readdirSync(folder).map(function(file){
+		if(pattern.test(file)){
+			if(dest instanceof Array){
+				dest.push(file);
+			}else{
+				dest[file] = true;
+			}
+		}
+	});
+}
diff --git a/dojox/mobile/themes/utils/cleanup.sh b/dojox/mobile/themes/utils/cleanup.sh
new file mode 100755
index 0000000..e4060cb
--- /dev/null
+++ b/dojox/mobile/themes/utils/cleanup.sh
@@ -0,0 +1 @@
+node cleanup.js
diff --git a/dojox/mobile/themes/utils/compile.bat b/dojox/mobile/themes/utils/compile.bat
new file mode 100644
index 0000000..fddf360
--- /dev/null
+++ b/dojox/mobile/themes/utils/compile.bat
@@ -0,0 +1,3 @@
+ at set NODE_PATH=../../../../util/less/lib
+node compile.js
+pause
diff --git a/dojox/mobile/themes/utils/compile.js b/dojox/mobile/themes/utils/compile.js
new file mode 100644
index 0000000..3614aeb
--- /dev/null
+++ b/dojox/mobile/themes/utils/compile.js
@@ -0,0 +1,118 @@
+var fs = require("fs");
+var path = require("path");
+var less = require("less");
+
+var themeFolders = ["../android", "../iphone", "../blackberry", "../holodark", "../windows", "../custom"];
+
+var commonFolders = ["../common/domButtons", "../common/transitions"];
+
+var batchQueue = [];
+var batchIndex = 0;
+var processProgress = 0; 
+
+themeFolders.forEach(function(folder){ 
+	batchQueue.push(function(){
+		processFolder(folder, true);
+		processFolder(folder + "/dijit", false);
+	});
+});
+
+commonFolders.forEach(function(folder){ 
+	batchQueue.push(function(){
+		processFolder(folder, false);
+	});
+});
+
+batch();
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+function batch(){
+	if(batchIndex < batchQueue.length){
+		batchQueue[batchIndex]();
+		batchIndex++;
+	}
+}
+
+function beginProcess(){
+	processProgress++;
+}
+function endProcess(){
+	processProgress--;
+	if (processProgress == 0){
+		batch();
+	}
+}
+
+function processFolder(folder, usingCommonSubstitution){
+	var folderFiles = getLessFiles(folder);
+	
+	if(usingCommonSubstitution){
+		var commonFiles = getLessFiles("../common");
+		var outputFile;
+		commonFiles.array.forEach(function(commonFile){
+			var themeFile = folderFiles.dic[commonFiles.dic[commonFile]];
+			if(themeFile){
+				// If there is a .less file in the theme folder, use it. 
+				outputFile = themeFile.replace(".less", ".css");
+				applyLess(themeFile, null, outputFile);
+			}else{
+				// Otherwise, fall back to the .less file which is in 'common'.
+				var fileName = commonFiles.dic[commonFile];
+				outputFile = folder + "/" + fileName.replace(".less", ".css");
+				// dojox.mobile mirroring support
+				if(fileName.indexOf("_rtl") == -1){ 
+					applyLess(commonFile, '@import "' + folder + '/variables.less";', outputFile);
+				}else{
+					applyLess(commonFile, '@import "' + folder + '/variables_rtl.less";', outputFile);
+				}
+			}
+		});
+	}else{
+		folderFiles.array.forEach(function(file){
+			applyLess(file, null, file.replace(".less", ".css"));
+		});
+	}
+}
+
+function applyLess(file, prependText, outputFile){ 
+	beginProcess();
+	console.log("compiling:", file);
+	
+	var parser = new(less.Parser)({paths: [path.dirname(file)], filename: file, optimization: 1});
+	var lessContent = fs.readFileSync(file, "utf-8");
+	
+	if(prependText){
+		lessContent = prependText + lessContent;
+	}
+	parser.parse(lessContent, function(error, tree){
+		if(error){
+			less.writeError(error);
+			process.exit(1);
+		}
+		var fd = fs.openSync(outputFile, "w");
+		
+		fs.write(fd, tree.toCSS({compress: false}).replace(/\n/g, "\r\n"), 0, "utf-8", function(f){
+			fs.close(fd);
+			console.log("writing:", outputFile);
+			endProcess();
+		});
+	});
+}
+
+function getLessFiles(folder){ 
+	var filesMap = {};
+	var filesArray = fs.readdirSync(folder);
+	filesArray = filesArray.filter(function(file){
+		return file && /\.less$/.test(file) && !/variables\.less$/.test(file) && !/css3\.less$/.test(file) 
+		&& !/variables_rtl\.less$/.test(file);
+	});
+	
+	filesArray = filesArray.map(function(file){
+			filesMap[file] = folder + "/" + file;
+			filesMap[folder + "/" + file] = file;
+			return filesMap[file]; 
+	});
+	
+	return {array: filesArray, dic: filesMap};
+}
diff --git a/dojox/mobile/themes/utils/compile.sh b/dojox/mobile/themes/utils/compile.sh
new file mode 100755
index 0000000..c13822d
--- /dev/null
+++ b/dojox/mobile/themes/utils/compile.sh
@@ -0,0 +1,2 @@
+export NODE_PATH=../../../../util/less/lib
+node compile.js
diff --git a/dojox/mobile/themes/windows/Accordion-compat.css b/dojox/mobile/themes/windows/Accordion-compat.css
new file mode 100644
index 0000000..7df5d82
--- /dev/null
+++ b/dojox/mobile/themes/windows/Accordion-compat.css
@@ -0,0 +1,30 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Accordion */
+.mblAccordionTitleSelected {
+  background-color: #e2e2e2;
+}
+.dj_ff3 .mblAccordionRoundRect {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitle:first-child {
+  -moz-border-radius-topleft: 8px;
+  -moz-border-radius-topright: 8px;
+}
+.dj_ff3 .mblAccordionRoundRect .mblAccordionTitleLast,
+.dj_ff3 .mblAccordionRoundRect .mblAccordionPane:last-child {
+  -moz-border-radius-bottomleft: 8px;
+  -moz-border-radius-bottomright: 8px;
+}
diff --git a/dojox/mobile/themes/windows/Accordion.css b/dojox/mobile/themes/windows/Accordion.css
new file mode 100644
index 0000000..5bafd3c
--- /dev/null
+++ b/dojox/mobile/themes/windows/Accordion.css
@@ -0,0 +1,111 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Accordion */
+.mblAccordion {
+  border-style: outset;
+  border-width: 1px;
+  border: none;
+}
+.mblAccordionRoundRect {
+  margin: 7px 9px 16px 9px;
+  padding: 0;
+  border: 1px solid #cccccc;
+  border-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitle:first-child {
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
+}
+.mblAccordionRoundRect .mblAccordionTitleLast,
+.mblAccordionRoundRect .mblAccordionPane:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
+}
+.mblAccordionTitle {
+  position: relative;
+  height: 30px;
+  width: 100%;
+  font-family: Helvetica;
+  font-size: 17px;
+  font-weight: bold;
+  line-height: 30px;
+  vertical-align: middle;
+  white-space: nowrap;
+  border: none;
+  background-color: transparent;
+  background-image: none;
+  font-weight: normal;
+  color: #ffffff;
+  font-size: 15pt;
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+.mblAccordionTitle:first-child {
+  border-top: none;
+}
+.mblAccordionTitleAnchor {
+  display: block;
+  height: 100%;
+  text-decoration: none;
+  white-space: nowrap;
+  color: #ffffff;
+  cursor: pointer;
+}
+.mblAccordionIconParent {
+  float: left;
+  margin: 6px 4px 0 6px;
+  line-height: normal;
+}
+.mblAccordionIconParent1 {
+  display: block;
+}
+.mblAccordionIconParent2 {
+  display: none;
+}
+.mblAccordionTitleSelected {
+  border: none;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent1 {
+  display: none;
+}
+.mblAccordionTitleSelected .mblAccordionIconParent2 {
+  display: block;
+}
+.mblAccordionPane {
+  margin-top: -5px;
+  padding-left: 50px;
+  background-color: transparent;
+  overflow: hidden;
+  position: relative;
+}
+.mblAccordionPane:before {
+  content: '';
+  position: absolute;
+  height: 100%;
+  width: 2px;
+  border-left: 2px solid #ffffff;
+  left: 40px;
+  z-index: -1;
+}
+.mblAccordionTitleLabel:active {
+  color: Highlight;
+}
+.mblAccordionIconParent {
+  margin-left: 0px;
+}
+.mblAccordionRoundRect {
+  border: none;
+}
diff --git a/dojox/mobile/themes/windows/Accordion.less b/dojox/mobile/themes/windows/Accordion.less
new file mode 100644
index 0000000..5d2d714
--- /dev/null
+++ b/dojox/mobile/themes/windows/Accordion.less
@@ -0,0 +1,31 @@
+ at import "variables.less";
+ at import "../common/Accordion.less";
+
+.mblAccordionPane {
+	margin-top: -5px;
+	padding-left: 50px;
+	background-color: @win-control-bg-color;
+	overflow: hidden;
+	position: relative;
+	&:before {
+		content: '';
+		position: absolute;
+		height: 100%;
+		width: 2px;
+		border-left: 2px solid @win-foreground-color;
+		left: 40px;
+		z-index: -1;
+	}
+}
+
+.mblAccordionTitleLabel:active {
+	color: @win-accent-color;
+}
+
+.mblAccordionIconParent {
+	margin-left: 0px;
+}
+
+.mblAccordionRoundRect {
+	border: none;
+}
diff --git a/dojox/mobile/themes/windows/Button-compat.css b/dojox/mobile/themes/windows/Button-compat.css
new file mode 100644
index 0000000..7e79bb0
--- /dev/null
+++ b/dojox/mobile/themes/windows/Button-compat.css
@@ -0,0 +1,55 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Button */
+.mblButton {
+  background-image: url(compat/button-bg.png);
+  background-repeat: repeat-x;
+}
+.mblButtonSelected {
+  background-image: url(compat/button-sel-bg.png);
+}
+.mblBlueButton {
+  background-image: url(compat/blue-button-bg.png);
+}
+.mblBlueButtonSelected {
+  background-image: url(compat/blue-button-sel-bg.png);
+}
+.mblRedButton {
+  background-image: url(compat/red-button-bg.png);
+}
+.mblRedButtonSelected {
+  background-image: url(compat/red-button-sel-bg.png);
+}
+.dj_gecko .mblButton {
+  background-image: none;
+}
+.dj_gecko .mblButtonSelected {
+  background-image: '';
+}
+.dj_gecko .mblBlueButton {
+  background-image: -moz-linear-gradient(top, #7a9de9 0%, #2362dd 100%);
+}
+.dj_gecko .mblBlueButtonSelected {
+  background-image: '';
+}
+.dj_gecko .mblRedButton {
+  background-image: none;
+}
+.dj_gecko .mblRedButtonSelected {
+  background-image: '';
+}
+.dj_ff3 .mblButton {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/windows/Button.css b/dojox/mobile/themes/windows/Button.css
new file mode 100644
index 0000000..9b60d04
--- /dev/null
+++ b/dojox/mobile/themes/windows/Button.css
@@ -0,0 +1,64 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Button */
+.mblButton {
+  padding: 0 10px;
+  height: 29px;
+  border-style: outset;
+  border-width: 1px;
+  font-family: Helvetica;
+  line-height: 29px;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  border: 2px solid #ffffff;
+  border-radius: 0;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  color: #ffffff;
+  background-color: transparent;
+  font-size: 9pt;
+  font-family: "Segoe WP", "Segoe UI", "HelveticaNeue", "Helvetica-Neue", "Helvetica", "BBAlpha Sans", "sans-serif";
+  background-image: none;
+  line-height: 0;
+  text-transform: lowercase;
+  -ms-user-select: none;
+  height: 32px;
+  padding-bottom: 3px;
+  text-decoration: none;
+}
+.mblButtonSelected {
+  color: #ffffff;
+  background-color: Highlight;
+}
+.mblButtonDisabled,
+.mblButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
+}
+.mblBlueButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd));
+  background-image: linear-gradient(to bottom, #7a9de9 0%, #2362dd 100%);
+  color: white;
+}
+.mblRedButton {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fa9d58), to(#ee4115));
+  background-image: linear-gradient(to bottom, #fa9d58 0%, #ee4115 100%);
+  color: white;
+}
+.mblButton:not([disabled]):active {
+  background-color: Highlight;
+}
diff --git a/dojox/mobile/themes/windows/Button.less b/dojox/mobile/themes/windows/Button.less
new file mode 100644
index 0000000..bdfcc92
--- /dev/null
+++ b/dojox/mobile/themes/windows/Button.less
@@ -0,0 +1,6 @@
+ at import "variables.less";
+ at import "../common/Button.less";
+
+.mblButton:not([disabled]):active {
+	background-color: @win-accent-color;
+}
diff --git a/dojox/mobile/themes/windows/Carousel.css b/dojox/mobile/themes/windows/Carousel.css
new file mode 100644
index 0000000..cfbbd92
--- /dev/null
+++ b/dojox/mobile/themes/windows/Carousel.css
@@ -0,0 +1,93 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Carousel */
+.mblCarousel {
+  overflow: hidden;
+  height: 300px;
+}
+.mblCarouselSlot {
+  position: relative;
+  float: left;
+  text-align: left;
+  box-sizing: border-box;
+}
+.mblCarouselHeaderBar {
+  background-color: #3a3a3b;
+  color: #b1b1b1;
+  font: bold 16px arial, helvetica, clean, sans-serif;
+  padding: 1px;
+}
+.mblCarouselBtnContainer {
+  float: right;
+}
+.mblCarouselBtn {
+  height: 18px;
+  width: 46px;
+  font: bold 14px arial, helvetica, clean, sans-serif;
+  color: gray;
+  padding-top: 0px;
+  margin: 0px 2px;
+  border-width: 1px;
+  /* workaround for android problem */
+
+}
+.mblCarouselTitle {
+  margin: 2px 0px 2px 4px;
+}
+.mblCarouselHeaderBar .mblPageIndicator {
+  float: right;
+  width: auto;
+  padding: 0px 20px;
+}
+.mblCarouselHeaderBar .mblPageIndicatorContainer {
+  margin-left: 0px;
+  margin-right: 0px;
+}
+.mblCarouselPages {
+  position: relative;
+  text-align: center;
+}
+/* dojox.mobile._CarouselItem */
+.mblCarouselItem {
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblCarouselItemHeaderText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 8px;
+  margin-bottom: 5px;
+}
+.mblCarouselItemFooterText {
+  color: white;
+  font: 14px arial, helvetica, clean, sans-serif;
+  text-align: center;
+  margin-top: 5px;
+  margin-bottom: 8px;
+}
+.mblCarouselItemImage {
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  vertical-align: bottom;
+}
+.mblCarouselItemBlank {
+  display: none;
+}
+.mblCarouselSlotSelected .mblCarouselItemImage {
+  opacity: 0.6;
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
diff --git a/dojox/mobile/themes/windows/Carousel_rtl.css b/dojox/mobile/themes/windows/Carousel_rtl.css
new file mode 100644
index 0000000..6c8bc7a
--- /dev/null
+++ b/dojox/mobile/themes/windows/Carousel_rtl.css
@@ -0,0 +1,13 @@
+/* dojox.mobile.Carousel Rtl */
+.mblCarouselItemRtl.mblCarouselSlot {
+  float: right;
+}
+.mblCarouselRtl .mblCarouselBtnContainer {
+  float: left;
+}
+.mblCarouselRtl .mblCarouselTitle {
+  margin: 2px 4px 2px 0px;
+}
+.mblCarouselRtl .mblCarouselHeaderBar .mblPageIndicator {
+  float: left;
+}
diff --git a/dojox/mobile/themes/windows/CheckBox-compat.css b/dojox/mobile/themes/windows/CheckBox-compat.css
new file mode 100644
index 0000000..55b3e82
--- /dev/null
+++ b/dojox/mobile/themes/windows/CheckBox-compat.css
@@ -0,0 +1,52 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.CheckBox */
+.mblCheckBox {
+  background-image: url(compat/button-bg.png);
+}
+.mblCheckBoxSelected {
+  background-image: url(compat/button-sel-bg.png);
+}
+.mblCheckBoxChecked,
+.mblCheckBox:checked {
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblCheckBoxChecked.mblCheckBoxSelected,
+.mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblCheckBox {
+  background-image: none;
+  -moz-appearance: none;
+}
+.dj_gecko .mblCheckBoxSelected {
+  background-image: '';
+}
+.dj_gecko .mblCheckBoxChecked,
+.dj_gecko .mblCheckBox:checked {
+  background-image: none;
+}
+.dj_gecko .mblCheckBoxChecked::after,
+.dj_gecko .mblCheckBox:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblCheckBoxChecked.mblCheckBoxSelected,
+.dj_gecko .mblCheckBox:checked.mblCheckBoxSelected {
+  background-image: '';
+}
+.dj_ff3 .mblCheckBox {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/windows/CheckBox.css b/dojox/mobile/themes/windows/CheckBox.css
new file mode 100644
index 0000000..1797379
--- /dev/null
+++ b/dojox/mobile/themes/windows/CheckBox.css
@@ -0,0 +1,97 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.CheckBox */
+.mblCheckBox {
+  position: relative;
+  margin: -0.5em 3px 0.3em 4px;
+  width: 1em;
+  height: 1em;
+  border-style: outset;
+  border-width: 1px;
+  font: inherit;
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  border: 2px solid #ffffff;
+  border-radius: 0;
+  opacity: 0;
+  margin: 0;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  transform: none;
+  z-index: 1;
+}
+.mblCheckBoxChecked::after,
+.mblCheckBox:checked::after {
+  position: absolute;
+  content: "";
+  width: 0.3em;
+  height: 0.6em;
+  top: 0;
+  left: 0.3em;
+  border-width: 0.15em;
+  border-style: none solid solid none;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: black;
+}
+.mblCheckBoxChecked.mblCheckBoxSelected::after,
+.mblCheckBox:checked.mblCheckBoxSelected::after {
+  border-color: white;
+}
+.mblCheckBox + .mblCheckableInputDecorator:before {
+  content: '';
+  width: 20px;
+  height: 20px;
+  position: absolute;
+  border: 2px solid #ffffff;
+  background-color: transparent;
+  margin-left: -25px;
+  z-index: 0;
+  border-radius: 0;
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+.mblCheckBox:not([disabled]):active + .mblCheckableInputDecorator:before,
+.mblCheckBox:not([disabled]) + .mblCheckableInputDecorator:active:before {
+  background-color: Highlight;
+}
+.mblCheckBoxChecked + .mblCheckableInputDecorator:before {
+  background-image: url("images/dark/check.png");
+  background-position: 50% 50%;
+  background-size: 32px 32px;
+  background-repeat: no-repeat;
+}
+.mblCheckBox[disabled] + .mblCheckableInputDecorator:before {
+  border-color: #808080;
+}
+.mblCheckBox[disabled].mblCheckBoxChecked + .mblCheckableInputDecorator:before {
+  background-image: url("images/check-disabled.png");
+  background-position: 50% 50%;
+  background-size: 32px 32px;
+  background-repeat: no-repeat;
+}
+.mblCheckableInputContainer + label {
+  color: #ffffff;
+  margin: 0 5px 0 5px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  -ms-user-select: none;
+  display: inline-block;
+}
diff --git a/dojox/mobile/themes/windows/CheckBox.less b/dojox/mobile/themes/windows/CheckBox.less
new file mode 100644
index 0000000..4bcbcc5
--- /dev/null
+++ b/dojox/mobile/themes/windows/CheckBox.less
@@ -0,0 +1,37 @@
+ at import "variables.less";
+ at import "../common/CheckBox.less";
+
+.mblCheckBox + .mblCheckableInputDecorator {
+	&:before {
+		.mblCheckRadioBorder;
+	}
+}
+
+.mblCheckBox:not([disabled]) {
+	&:active + .mblCheckableInputDecorator:before,
+	& + .mblCheckableInputDecorator:active:before {
+		background-color: @win-accent-color;
+	}
+}
+
+.mblCheckBoxChecked + .mblCheckableInputDecorator {
+	&:before {
+		.mblImage(@imgCheckUrl);
+	}
+}
+
+.mblCheckBox[disabled] {
+	& + .mblCheckableInputDecorator {
+		&:before {
+			border-color: @win-disabled-color;
+		}
+	}
+
+	&.mblCheckBoxChecked + .mblCheckableInputDecorator:before {
+		.mblImage("images/check-disabled.png");
+	}
+}
+
+.mblCheckableInputContainer + label {
+   .mblCheckRadioLabel;
+}
diff --git a/dojox/mobile/themes/windows/ComboBox-compat.css b/dojox/mobile/themes/windows/ComboBox-compat.css
new file mode 100644
index 0000000..95af72f
--- /dev/null
+++ b/dojox/mobile/themes/windows/ComboBox-compat.css
@@ -0,0 +1,21 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.ComboBox */
+.dj_gecko .dijitPopup {
+  -moz-box-shadow: none;
+}
+.dj_gecko .mblComboBoxMenuItemSelected {
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/windows/ComboBox.css b/dojox/mobile/themes/windows/ComboBox.css
new file mode 100644
index 0000000..b0b9951
--- /dev/null
+++ b/dojox/mobile/themes/windows/ComboBox.css
@@ -0,0 +1,90 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.ComboBox */
+.dijitPopup {
+  margin: 0;
+  padding: 0;
+  position: absolute;
+  border: 0;
+  background-color: transparent;
+  -webkit-box-shadow: none;
+  border-radius: 0;
+  box-shadow: none;
+}
+.mblReset {
+  margin: 0;
+  padding: 0;
+  border: 0;
+  line-height: normal;
+  font: inherit;
+  color: inherit;
+}
+.mblComboBoxMenu {
+  position: relative;
+  overflow-y: hidden !important;
+  overflow: hidden;
+  border: 1px solid black;
+  border: none;
+  border-radius: 0;
+  background-color: #1f1f1f;
+  color: #ffffff;
+  width: 100% !important;
+  height: calc(100% - 20px) !important;
+}
+.mblComboBoxMenuItem {
+  padding: .1em .2em;
+  border-width: 1px 0 1px 0;
+  border-style: solid;
+  text-align: left;
+  border: none;
+  color: inherit;
+  font-size: 15pt;
+  line-height: 1.4;
+  padding-left: 15px;
+  -ms-user-select: none;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  white-space: nowrap;
+}
+.mblComboBoxMenuItemSelected {
+  color: Highlight;
+}
+.mblComboBoxMenuPreviousButton,
+.mblComboBoxMenuNextButton {
+  font-style: italic;
+  overflow: hidden;
+}
+.mblComboBoxMenuPopup {
+  background-color: #1f1f1f;
+  color: #ffffff;
+  width: 100%;
+  height: calc(100% - 50px) !important;
+  padding: 50px 0 0 0;
+  left: 0px !important;
+  -ms-touch-action: none;
+}
+.mblComboBoxMenuPopup:before {
+  content: 'CHOOSE AN ITEM';
+  position: absolute;
+  top: 20px;
+  left: 15px;
+  font-weight: 600;
+}
+.mblComboBoxMenu > div {
+  width: 100%;
+}
+.mblComboBoxMenuItem:active {
+  color: Highlight;
+}
diff --git a/dojox/mobile/themes/windows/ComboBox.less b/dojox/mobile/themes/windows/ComboBox.less
new file mode 100644
index 0000000..081ca2f
--- /dev/null
+++ b/dojox/mobile/themes/windows/ComboBox.less
@@ -0,0 +1,28 @@
+ at import "variables.less";
+ at import "../common/ComboBox.less";
+
+.mblComboBoxMenuPopup {
+	background-color: @win-dialog-color;
+	color: @win-foreground-color;
+	width: 100%;
+	height: calc(~'100% - @{mbl-combo-box-padding-top}') !important;
+	padding: @mbl-combo-box-padding-top 0 0 0;
+	left: 0px !important;
+	-ms-touch-action: none;
+
+  &:before {
+		content: 'CHOOSE AN ITEM';
+		position: absolute;
+		top: @mbl-combo-box-title-top;
+		left: @default-padding-left;
+		font-weight: 600;
+	}
+}
+
+.mblComboBoxMenu > div {
+	width: 100%;
+}
+
+.mblComboBoxMenuItem:active {
+	color: @win-accent-color;
+}
diff --git a/dojox/mobile/themes/windows/ComboBox_rtl.css b/dojox/mobile/themes/windows/ComboBox_rtl.css
new file mode 100644
index 0000000..01b9527
--- /dev/null
+++ b/dojox/mobile/themes/windows/ComboBox_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.ComboBox Rtl*/
+.mblComboBoxMenuItemRtl {
+  text-align: right;
+}
diff --git a/dojox/mobile/themes/windows/DatePicker.css b/dojox/mobile/themes/windows/DatePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/windows/DatePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/windows/EdgeToEdgeCategory.css b/dojox/mobile/themes/windows/EdgeToEdgeCategory.css
new file mode 100644
index 0000000..33a9269
--- /dev/null
+++ b/dojox/mobile/themes/windows/EdgeToEdgeCategory.css
@@ -0,0 +1,45 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.EdgeToEdgeCategory */
+.mblEdgeToEdgeCategory {
+  position: relative;
+  margin: 0;
+  padding: 0 10px;
+  overflow: hidden;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  display: inline-block;
+  padding: 0 0 0 5px;
+  font-size: 15pt;
+  font-family: "Segoe WP", "Segoe UI", "HelveticaNeue", "Helvetica-Neue", "Helvetica", "BBAlpha Sans", "sans-serif";
+  font-weight: 200;
+  line-height: 2;
+  height: 43px;
+  width: 38px;
+  background-color: Highlight;
+  border: none;
+  color: #ffffff;
+  text-transform: lowercase;
+  overflow: visible;
+}
+.mblEdgeToEdgeCategoryLong {
+  width: 100%;
+}
+.mblEdgeToEdgeCategory:first-of-type {
+  margin-top: 8px;
+}
diff --git a/dojox/mobile/themes/windows/EdgeToEdgeCategory.less b/dojox/mobile/themes/windows/EdgeToEdgeCategory.less
new file mode 100644
index 0000000..db5701c
--- /dev/null
+++ b/dojox/mobile/themes/windows/EdgeToEdgeCategory.less
@@ -0,0 +1,10 @@
+ at import "variables.less";
+ at import "../common/EdgeToEdgeCategory.less";
+
+.mblEdgeToEdgeCategoryLong {
+	width: 100%;
+}
+
+.mblEdgeToEdgeCategory:first-of-type {
+	margin-top: 8px;
+}
diff --git a/dojox/mobile/themes/windows/EdgeToEdgeList.css b/dojox/mobile/themes/windows/EdgeToEdgeList.css
new file mode 100644
index 0000000..2693f71
--- /dev/null
+++ b/dojox/mobile/themes/windows/EdgeToEdgeList.css
@@ -0,0 +1,24 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.EdgeToEdgeList */
+.mblEdgeToEdgeList {
+  margin: 0;
+  padding: 0;
+  background-color: transparent;
+  padding: 0px;
+}
+.mblEdgeToEdgeList .mblListItem:last-child {
+  border-bottom-color: #bfbfbf;
+}
diff --git a/dojox/mobile/themes/android/EdgeToEdgeList.less b/dojox/mobile/themes/windows/EdgeToEdgeList.less
similarity index 100%
rename from dojox/mobile/themes/android/EdgeToEdgeList.less
rename to dojox/mobile/themes/windows/EdgeToEdgeList.less
diff --git a/dojox/mobile/themes/windows/FixedSplitter.css b/dojox/mobile/themes/windows/FixedSplitter.css
new file mode 100644
index 0000000..85160cd
--- /dev/null
+++ b/dojox/mobile/themes/windows/FixedSplitter.css
@@ -0,0 +1,33 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.FixedSplitter */
+.mblFixedSplitter {
+  width: 100%;
+  height: 100%;
+}
+/* For FixedSplitter's child panes */
+.mblFixedSplitter > * {
+  position: absolute;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+.mblFixedSplitterH > * {
+  height: 100%;
+  top: 0px;
+}
+.mblFixedSplitterV > * {
+  width: 100%;
+  left: 0px;
+}
diff --git a/dojox/mobile/themes/windows/FormLayout.css b/dojox/mobile/themes/windows/FormLayout.css
new file mode 100644
index 0000000..9ed801a
--- /dev/null
+++ b/dojox/mobile/themes/windows/FormLayout.css
@@ -0,0 +1,204 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* Single Column Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (max-width: 500px) {
+  .mblFormLayout.mblFormLayoutAuto fieldset {
+    padding-left: 0;
+    padding-right: 0;
+  }
+  /* A gap between rows */
+  .mblFormLayout.mblFormLayoutAuto > * + * {
+    margin-top: 0.6em;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 100%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'single' ***/
+.mblFormLayout.mblFormLayoutSingleCol fieldset {
+  padding-left: 0;
+  padding-right: 0;
+}
+/* A gap between rows */
+.mblFormLayout.mblFormLayoutSingleCol > * + * {
+  margin-top: 0.6em;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutSingleCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 100%;
+  box-sizing: border-box;
+}
+/* Two Columns Layout */
+/**********************************************************************************************************************/
+/*** columns == 'auto' ***/
+ at media all and (min-width: 500px) {
+  /* Form layout selector*/
+  .mblFormLayout.mblFormLayoutAuto {
+    display: table;
+    width: 100%;
+  }
+  /* Form rows */
+  .mblFormLayout.mblFormLayoutAuto > * {
+    display: table-row;
+  }
+  /* Form cells */
+  .mblFormLayout.mblFormLayoutAuto > * > * {
+    display: table-cell;
+    vertical-align: top;
+    padding: 0.5em 0;
+  }
+  /* Left cells */
+  .mblFormLayout.mblFormLayoutAuto > * > *:first-child {
+    width: 20%;
+    padding-right: 0.5em;
+  }
+  /* mblFormLayoutRightAlign optional selector definition */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child {
+    text-align: right;
+  }
+  /* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+    margin-right: 0;
+  }
+  /* The Slider sticks to its bounds when margin=10px */
+  .mblFormLayout.mblFormLayoutAuto.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+    display: inline-block;
+    margin-right: 10px;
+    margin-top: 0px;
+  }
+  /* Text widgets */
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.TextBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.ComboBox"],
+  .mblFormLayout.mblFormLayoutAuto *[data-dojo-type="dojox.mobile.SearchBox"] {
+    width: 50%;
+    box-sizing: border-box;
+  }
+}
+/*** columns == 'two' ***/
+/* Form layout selector*/
+.mblFormLayout.mblFormLayoutTwoCol {
+  display: table;
+  width: 100%;
+}
+/* Form rows */
+.mblFormLayout.mblFormLayoutTwoCol > * {
+  display: table-row;
+}
+/* Form cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > * {
+  display: table-cell;
+  vertical-align: top;
+  padding: 0.5em 0;
+}
+/* Left cells */
+.mblFormLayout.mblFormLayoutTwoCol > * > *:first-child {
+  width: 20%;
+  padding-right: 0.5em;
+}
+/* mblFormLayoutRightAlign optional selector definition */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child {
+  text-align: right;
+}
+/* Force right margin of last elements of the right column, no way to select elements followed by a <br> */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:last-child,
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:last-child {
+  margin-right: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout.mblFormLayoutTwoCol.mblFormLayoutRightAlign > * > *:last-child > .mblSlider:last-child {
+  display: inline-block;
+  margin-right: 10px;
+  margin-top: 0px;
+}
+/* Text widgets */
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout.mblFormLayoutTwoCol *[data-dojo-type="dojox.mobile.SearchBox"] {
+  width: 50%;
+  box-sizing: border-box;
+}
+/* Common Rules*/
+/**********************************************************************************************************************/
+.mblFormLayout fieldset {
+  border: none;
+  margin: 0;
+}
+/* Bold widget labels */
+.mblFormLayout > * > *:first-child {
+  font-weight: bold;
+}
+/* Whatever the screen width, force left margin of first elements and elements following a <br> */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Button"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ToggleButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.CheckBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.Switch"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.RadioButton"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ComboBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.ExpandingTextArea"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.TextBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > *[data-dojo-type="dojox.mobile.SearchBox"]:first-child,
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Button"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ToggleButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.CheckBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.Switch"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.RadioButton"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ComboBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.ExpandingTextArea"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.TextBox"],
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > br + *[data-dojo-type="dojox.mobile.SearchBox"] {
+  margin-left: 0;
+}
+/* The Slider sticks to its bounds when margin=10px */
+.mblFormLayout:not(.mblFormLayoutRightAlign) > * > *:last-child > .mblSlider:first-child {
+  display: inline-block;
+  margin-left: 10px;
+  margin-top: 0;
+  margin-bottom: 0;
+}
diff --git a/dojox/mobile/themes/windows/GridLayout.css b/dojox/mobile/themes/windows/GridLayout.css
new file mode 100644
index 0000000..5f989d0
--- /dev/null
+++ b/dojox/mobile/themes/windows/GridLayout.css
@@ -0,0 +1,38 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.GridLayout */
+.mblGridLayout {
+  width: 100%;
+  height: 100%;
+  padding: 0;
+}
+.mblGridLayout > div {
+  margin: 0;
+  border: 0;
+  padding: 0;
+  float: left;
+  min-height: 1px;
+}
+.mblGridItemFirstColumn {
+  clear: left;
+}
+.mblGridItemTerminator {
+  clear: both;
+}
+.mblGridItemLastItem:after {
+  content: "";
+  display: block;
+  clear: both;
+}
diff --git a/dojox/mobile/themes/windows/Heading-compat.css b/dojox/mobile/themes/windows/Heading-compat.css
new file mode 100644
index 0000000..e489df3
--- /dev/null
+++ b/dojox/mobile/themes/windows/Heading-compat.css
@@ -0,0 +1,24 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Heading */
+.mblHeading {
+  background-image: url(compat/heading-bg.png);
+}
+.mblHeadingSpanTitle {
+  white-space: normal;
+}
+.dj_gecko .mblHeading {
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/windows/Heading.css b/dojox/mobile/themes/windows/Heading.css
new file mode 100644
index 0000000..1afc401
--- /dev/null
+++ b/dojox/mobile/themes/windows/Heading.css
@@ -0,0 +1,88 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Heading */
+.mblHeading {
+  position: relative;
+  margin: 0;
+  width: 100%;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  z-index: 1;
+  padding: 0;
+  height: 42px;
+  font-family: Helvetica;
+  font-size: 20px;
+  font-weight: bold;
+  text-align: center;
+  line-height: 44px;
+  border: none;
+  color: #ffffff;
+  font-family: "Segoe WP", "Segoe UI", "HelveticaNeue", "Helvetica-Neue", "Helvetica", "BBAlpha Sans", "sans-serif";
+  font-weight: 400;
+  text-align: left;
+  font-size: 17pt;
+  overflow: visible;
+}
+.mblHeading * {
+  z-index: 2;
+}
+.mblHeadingDivTitle {
+  position: absolute;
+  width: 100%;
+  display: none;
+  left: 0;
+  z-index: 1;
+}
+.mblHeadingCenterTitle .mblHeadingDivTitle {
+  display: block;
+}
+.mblHeadingCenterTitle .mblHeadingSpanTitle {
+  display: none;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  line-height: normal;
+  font-weight: 400;
+  margin: 0;
+}
+h1.mblHeading {
+  font-size: 19pt;
+}
+h2.mblHeading {
+  font-size: 17pt;
+}
+h3.mblHeading {
+  font-size: 15pt;
+}
+h4.mblHeading {
+  font-size: 11pt;
+}
+h5.mblHeading {
+  font-size: 10pt;
+}
+h6.mblHeading {
+  font-size: 9pt;
+}
+.mblHeading .mblToolBarButton ~ .mblHeadingDivTitle {
+  text-align: center;
+}
+.mblHeading .mblToolBarButton.mblToolBarButtonHasRightArrow {
+  float: right;
+}
diff --git a/dojox/mobile/themes/windows/Heading.less b/dojox/mobile/themes/windows/Heading.less
new file mode 100644
index 0000000..15c00f0
--- /dev/null
+++ b/dojox/mobile/themes/windows/Heading.less
@@ -0,0 +1,42 @@
+ at import "variables.less";
+ at import "../common/Heading.less";
+
+h1, h2, h3, h4, h5, h6 {
+	line-height: normal;
+	font-weight: 400;
+	margin: 0;
+}
+
+h1.mblHeading {
+	font-size: @win-font-size-huge;
+}
+
+h2.mblHeading {
+	font-size: @win-font-size-extra-large;
+}
+
+h3.mblHeading {
+	font-size: @win-font-size-large;
+}
+
+h4.mblHeading {
+	font-size: @win-font-size-medium-large;
+}
+
+h5.mblHeading {
+	font-size: @win-font-size-medium;
+}
+
+h6.mblHeading {
+	font-size: @win-font-size-normal;
+}
+
+.mblHeading {
+	& .mblToolBarButton ~ .mblHeadingDivTitle {
+		text-align: center;
+	}
+
+	& .mblToolBarButton.mblToolBarButtonHasRightArrow {
+		float: right;
+	}
+}
diff --git a/dojox/mobile/themes/windows/IconContainer-compat.css b/dojox/mobile/themes/windows/IconContainer-compat.css
new file mode 100644
index 0000000..0dfd958
--- /dev/null
+++ b/dojox/mobile/themes/windows/IconContainer-compat.css
@@ -0,0 +1,27 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.IconContainer */
+.mblIconItemPaneHeading {
+  background-image: url(compat/icon-content-heading-bg.png);
+}
+.dj_gecko .mblIconItemPaneHeading {
+  background-image: -moz-linear-gradient(top, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
+}
+.dj_ie7 .mblIconAreaInner {
+  font-size: 60px;
+}
diff --git a/dojox/mobile/themes/windows/IconContainer-compat.less b/dojox/mobile/themes/windows/IconContainer-compat.less
new file mode 100644
index 0000000..e2df985
--- /dev/null
+++ b/dojox/mobile/themes/windows/IconContainer-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonColorButtons-compat.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross-compat.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer-compat.less";
diff --git a/dojox/mobile/themes/windows/IconContainer.css b/dojox/mobile/themes/windows/IconContainer.css
new file mode 100644
index 0000000..c6b3094
--- /dev/null
+++ b/dojox/mobile/themes/windows/IconContainer.css
@@ -0,0 +1,317 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
+
+ at import url("../common/IconContainer_keyframes.css");
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.IconContainer */
+.mblIconContainer {
+  margin: 20px 10px;
+  padding: 0;
+}
+/* dojox.mobile.IconItem */
+.mblIconItem {
+  position: relative;
+  overflow: hidden;
+  /* for focus frame */
+
+  list-style-type: none;
+  float: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblIconItemTerminator {
+  list-style-type: none;
+  clear: both;
+}
+.mblIconItemPane {
+  list-style-type: none;
+  background-color: white;
+  color: black;
+}
+.mblIconArea {
+  position: relative;
+  height: 78px;
+  font-family: Helvetica;
+  font-size: 12px;
+  text-align: center;
+  margin-top: 5px;
+  margin-bottom: 5px;
+  width: 74px;
+  color: #ffffff;
+}
+.mblIconArea img {
+  vertical-align: middle;
+}
+.mblIconAreaInner {
+  position: relative;
+  height: 65px;
+  line-height: 65px;
+  text-align: center;
+}
+.mblIconItemDeleteIcon {
+  position: absolute;
+  top: -4px;
+  left: -2px;
+}
+.mblIconItemSpriteIcon {
+  position: absolute;
+}
+.mblContent {
+  clear: both;
+  padding-bottom: 20px;
+}
+table.mblClose {
+  clear: both;
+  cursor: pointer;
+}
+.mblVibrate {
+  position: relative;
+  -webkit-animation-duration: 0.5s;
+  animation-duration: 0.5s;
+  -webkit-animation-timing-function: ease-in-out;
+  animation-timing-function: ease-in-out;
+  -webkit-animation-iteration-count: infinite;
+  animation-iteration-count: infinite;
+  -webkit-animation-name: mblVibrate;
+  animation-name: mblVibrate;
+  -webkit-transform: rotate(0deg);
+  transform: rotate(0deg);
+}
+.mblCloseContent {
+  -webkit-animation-duration: 0.3s;
+  animation-duration: 0.3s;
+  -webkit-animation-timing-function: ease-in-out;
+  animation-timing-function: ease-in-out;
+  -webkit-animation-name: mblShrink;
+  animation-name: mblShrink;
+  -webkit-transform: scale(0.01);
+  transform: scale(0.01);
+}
+.mblCloseContent.mblShrink0 {
+  -webkit-animation-name: mblShrink0;
+  animation-name: mblShrink0;
+}
+.mblCloseContent.mblShrink1 {
+  -webkit-animation-name: mblShrink1;
+  animation-name: mblShrink1;
+}
+.mblCloseContent.mblShrink2 {
+  -webkit-animation-name: mblShrink2;
+  animation-name: mblShrink2;
+}
+.mblCloseContent.mblShrink3 {
+  -webkit-animation-name: mblShrink3;
+  animation-name: mblShrink3;
+}
+/* dojox.mobile._IconItemPane */
+.mblIconItemPaneHeading {
+  position: relative;
+  clear: both;
+  overflow: hidden;
+  margin-top: 0px;
+  padding-left: 40px;
+  height: 25px;
+  border-top: 1px solid #f1f3f4;
+  border-bottom: 1px solid #717d85;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e0e4e7), to(#b4bec6), color-stop(0.5, #c4ccd2), color-stop(0.5, #bfc8ce));
+  background-image: linear-gradient(to bottom, #e0e4e7 0%, #c4ccd2 50%, #bfc8ce 50%, #b4bec6 100%);
+  font-family: Helvetica;
+  font-size: 14px;
+  color: white;
+  line-height: 26px;
+  text-shadow: rgba(0, 0, 0, 0.6) 0px -1px 0px;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+.mblIconItemPaneIcon {
+  position: absolute;
+  top: -2px;
+  left: 1px;
+}
+ at -webkit-keyframes mblVibrate {
+  0% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    -webkit-transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    -webkit-transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    -webkit-transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    -webkit-transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at keyframes mblVibrate {
+  0% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+  25% {
+    transform: rotate(1deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  50% {
+    transform: rotate(-1deg);
+    bottom: -2px;
+    left: -1px;
+  }
+  75% {
+    transform: rotate(2deg);
+    bottom: 2px;
+    left: 1px;
+  }
+  100% {
+    transform: rotate(-2deg);
+    bottom: -1px;
+    left: -1px;
+  }
+}
+ at -webkit-keyframes mblShrink {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: scale(0.01);
+  }
+}
+ at keyframes mblShrink {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink0 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink0 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-40%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink1 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink1 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(-14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink2 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink2 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(14%, -70%) scale(0.01);
+  }
+}
+ at -webkit-keyframes mblShrink3 {
+  from {
+    -webkit-transform: scale(1);
+  }
+  to {
+    -webkit-transform: translate(40%, -70%) scale(0.01);
+  }
+}
+ at keyframes mblShrink3 {
+  from {
+    transform: scale(1);
+  }
+  to {
+    transform: translate(40%, -70%) scale(0.01);
+  }
+}
+.mblIconItemPaneHeading {
+  display: -ms-flexbox;
+  -ms-flex-direction: column-reverse;
+  text-shadow: none;
+  background-image: none;
+  border: none;
+  position: relative;
+  height: auto;
+  padding: 0px;
+}
+.mblIconContainer {
+  margin: 0px;
+}
+.mblIconItemPane {
+  background-color: #1f1f1f;
+  color: white !important;
+  position: fixed;
+  width: 100%;
+  top: 0px;
+  z-index: 100;
+  padding-left: 15px;
+  padding-right: 10px;
+  margin-left: -15px;
+  display: -ms-flexbox;
+  -ms-flex-direction: column-reverse;
+}
+.mblContent {
+  padding: 8px 0px;
+}
+.mblIconItemPaneIcon {
+  position: relative;
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+.mblIconItemPaneIcon:not([title='']) .mblDomButton {
+  display: none;
+}
+.mblCloseButton {
+  display: inline !important;
+}
diff --git a/dojox/mobile/themes/windows/IconContainer.less b/dojox/mobile/themes/windows/IconContainer.less
new file mode 100644
index 0000000..204eb35
--- /dev/null
+++ b/dojox/mobile/themes/windows/IconContainer.less
@@ -0,0 +1,51 @@
+ at import url("../common/domButtons/DomButtonColorButtons.css");
+ at import url("../common/domButtons/DomButtonBlackCircleCross.css");
+ at import url("../common/IconContainer_keyframes.css");
+
+ at import "variables.less";
+ at import "../common/IconContainer.less";
+
+.mblIconItemPaneHeading {
+	display: -ms-flexbox;
+	-ms-flex-direction: column-reverse;
+	text-shadow: none;
+	background-image: none;
+	border: none;
+	position: relative;
+	height: auto;
+	padding: 0px;
+}
+
+.mblIconContainer {
+	margin: 0px;
+}
+
+.mblIconItemPane {
+	background-color: @win-dialog-color;
+	color: white !important;
+	position: fixed;
+	width: 100%;
+	top: 0px;
+	z-index: 100;
+	padding-left: @default-padding-left;
+	padding-right: @default-padding-right;
+	margin-left: - at default-padding-left;
+	display: -ms-flexbox;
+	-ms-flex-direction: column-reverse;
+}
+
+.mblContent {
+	padding: 8px 0px;
+}
+
+.mblIconItemPaneIcon {
+	position: relative;
+	.default-vertical-margin;
+	&:not([title='']) .mblDomButton {
+		display: none;
+	}
+}
+
+.mblCloseButton {
+	display: inline !important;
+}
diff --git a/dojox/mobile/themes/windows/IconContainer_rtl.css b/dojox/mobile/themes/windows/IconContainer_rtl.css
new file mode 100644
index 0000000..f5b8c10
--- /dev/null
+++ b/dojox/mobile/themes/windows/IconContainer_rtl.css
@@ -0,0 +1,14 @@
+/* dojox.mobile.IconItem Rtl */
+.mblIconItemRtl {
+  float: right;
+}
+.mblIconItemRtl .mblIconItemDeleteIcon {
+  right: -2px;
+}
+/* dojox.mobile._IconItemPane Rtl*/
+.mblIconItemPaneRtl .mblIconItemPaneHeading {
+  padding-right: 40px;
+}
+.mblIconItemPaneRtl .mblIconItemPaneIcon {
+  right: 1px;
+}
diff --git a/dojox/mobile/themes/windows/IconMenu-compat.css b/dojox/mobile/themes/windows/IconMenu-compat.css
new file mode 100644
index 0000000..4064b2a
--- /dev/null
+++ b/dojox/mobile/themes/windows/IconMenu-compat.css
@@ -0,0 +1,45 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+  background-color: #a0a0a0;
+}
+.mblIconMenuItemSel {
+  background-color: Highlight;
+}
+.dj_gecko .mblIconMenu {
+  background-color: rgba(160, 160, 160, 0.85);
+}
+.dj_gecko .mblIconMenuItem {
+  -moz-box-sizing: border-box;
+}
+.dj_ff3 .mblIconMenu {
+  -moz-border-radius: 3px;
+}
+.dj_ff3 .mblIconMenuItemIcon img {
+  border: 1px solid red;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-left-radius: 3px;
+}
+.dj_ff3 .mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-right-radius: 3px;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-left-radius: 3px;
+}
+.dj_ff3 .mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-right-radius: 3px;
+}
diff --git a/dojox/mobile/themes/windows/IconMenu.css b/dojox/mobile/themes/windows/IconMenu.css
new file mode 100644
index 0000000..e014461
--- /dev/null
+++ b/dojox/mobile/themes/windows/IconMenu.css
@@ -0,0 +1,77 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.IconMenu */
+.mblIconMenu {
+  width: 100%;
+  height: 100%;
+  border-radius: 3px;
+  text-align: center;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  padding: 0;
+  background-color: rgba(160, 160, 160, 0.85);
+  border: 1px solid #869cbf;
+  margin: 0px;
+}
+/* dojox.mobile.IconMenuItem */
+.mblIconMenuItem {
+  float: left;
+  list-style-type: none;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border-left: 1px solid rgba(192, 192, 192, 0.85);
+  border-bottom: 1px solid rgba(192, 192, 192, 0.85);
+}
+.mblIconMenuItemIcon {
+  position: relative;
+  margin-left: auto;
+  margin-right: auto;
+}
+.mblIconMenuItemFirstColumn {
+  border-left: none;
+}
+.mblIconMenuItemLastRow {
+  border-bottom: none;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  border-top-left-radius: 3px;
+}
+.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  border-top-right-radius: 3px;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  border-bottom-left-radius: 3px;
+}
+.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  border-bottom-right-radius: 3px;
+}
+.mblIconMenuItemAnchor {
+  display: block;
+  height: 100%;
+  font-family: Helvetica;
+  text-decoration: none;
+  font-size: 10pt;
+  color: #ffffff;
+  cursor: pointer;
+}
+.mblIconMenuItemTable {
+  width: 100%;
+  height: 100%;
+}
+.mblIconMenuItemTable img {
+  border: none;
+}
+.mblIconMenuItemSel {
+  background-color: Highlight;
+}
diff --git a/dojox/mobile/themes/windows/IconMenu_rtl-compat.css b/dojox/mobile/themes/windows/IconMenu_rtl-compat.css
new file mode 100644
index 0000000..21b3041
--- /dev/null
+++ b/dojox/mobile/themes/windows/IconMenu_rtl-compat.css
@@ -0,0 +1,17 @@
+/* dojox.mobile.IconMenu Rtl */
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  -moz-border-top-right-radius: 3px;
+  -moz-border-top-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  -moz-border-top-left-radius: 3px;
+  -moz-border-top-right-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  -moz-border-bottom-right-radius: 3px;
+  -moz-border-bottom-left-radius: 0px;
+}
+.dj_ff3 .mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  -moz-border-bottom-left-radius: 3px;
+  -moz-border-bottom-right-radius: 0px;
+}
diff --git a/dojox/mobile/themes/windows/IconMenu_rtl.css b/dojox/mobile/themes/windows/IconMenu_rtl.css
new file mode 100644
index 0000000..52791b5
--- /dev/null
+++ b/dojox/mobile/themes/windows/IconMenu_rtl.css
@@ -0,0 +1,23 @@
+.mblIconMenuItemRtl {
+  float: right;
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstColumn {
+  border-right: none;
+  border-left: 1px solid rgba(192, 192, 192, 0.85);
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemFirstColumn {
+  border-top-right-radius: 3px;
+  border-top-left-radius: 0px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemFirstRow.mblIconMenuItemLastColumn {
+  border-top-right-radius: 0px;
+  border-top-left-radius: 3px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemFirstColumn {
+  border-bottom-right-radius: 3px;
+  border-bottom-left-radius: 0px;
+}
+.mblIconMenuItemRtl.mblIconMenuItemLastRow.mblIconMenuItemLastColumn {
+  border-bottom-right-radius: 0px;
+  border-bottom-left-radius: 3px;
+}
diff --git a/dojox/mobile/themes/windows/ListItem-compat.css b/dojox/mobile/themes/windows/ListItem-compat.css
new file mode 100644
index 0000000..cbeb26f
--- /dev/null
+++ b/dojox/mobile/themes/windows/ListItem-compat.css
@@ -0,0 +1,27 @@
+ at import url("../common/domButtons/DomButtonGrayArrow-compat.css");
+
+ at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.ListItem */
+.mblListItemSelected {
+  background-color: Highlight;
+}
+.dj_gecko .mblListItemSelected {
+  background-image: none;
+}
+.dj_ie6 .mblListItem {
+  vertical-align: bottom;
+}
diff --git a/dojox/mobile/themes/windows/ListItem-compat.less b/dojox/mobile/themes/windows/ListItem-compat.less
new file mode 100644
index 0000000..332107e
--- /dev/null
+++ b/dojox/mobile/themes/windows/ListItem-compat.less
@@ -0,0 +1,5 @@
+ at import url("../common/domButtons/DomButtonGrayArrow-compat.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck-compat.css");
+
+ at import "variables.less";
+ at import "../common/ListItem-compat.less";
diff --git a/dojox/mobile/themes/windows/ListItem.css b/dojox/mobile/themes/windows/ListItem.css
new file mode 100644
index 0000000..8f460c2
--- /dev/null
+++ b/dojox/mobile/themes/windows/ListItem.css
@@ -0,0 +1,163 @@
+ at import url("../common/domButtons/DomButtonGrayArrow.css");
+
+ at import url("../common/domButtons/DomButtonDarkBlueCheck.css");
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.ListItem */
+.mblListItem {
+  position: relative;
+  overflow: hidden;
+  /* for focus frame */
+
+  padding: 0 8px;
+  height: 43px;
+  list-style-type: none;
+  line-height: 43px;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  border: none;
+  background-color: transparent;
+  color: #ffffff;
+  font-size: 15pt;
+  padding: 0;
+}
+.mblListItem.mblVariableHeight {
+  padding: 11px 8px;
+  height: auto;
+  line-height: normal;
+}
+.mblListItemSelected {
+  color: Highlight;
+}
+.mblListItemSelected .mblDomButton div {
+  border-color: white;
+}
+.mblListItemLabelSelected {
+  background-color: #048bf4;
+}
+.mblListItemChecked {
+  color: #314e84;
+}
+.mblListItemChecked .mblListItemRightIcon {
+  visibility: visible;
+}
+.mblListItemChecked .mblListItemUncheckIcon {
+  position: absolute;
+  visibility: hidden;
+}
+.mblListItemUnchecked .mblListItemRightIcon {
+  visibility: hidden;
+}
+.mblListItemUnchecked .mblListItemUncheckIcon {
+  visibility: visible;
+}
+.mblListItemDeleteIcon {
+  position: relative;
+  float: left;
+  line-height: normal;
+  margin-top: 7px;
+  margin-bottom: -7px;
+  margin-right: 11px;
+}
+.mblListItemIcon {
+  position: relative;
+  float: left;
+  line-height: normal;
+  margin-top: 7px;
+  margin-bottom: -7px;
+  margin-right: 11px;
+}
+.mblListItemRightIcon,
+.mblListItemRightIcon2,
+.mblListItemUncheckIcon {
+  position: relative;
+  float: right;
+  line-height: normal;
+  margin-top: 7px;
+  margin-bottom: -7px;
+}
+.mblListItemRightText {
+  position: relative;
+  float: right;
+  line-height: normal;
+  margin-right: 4px;
+  color: black;
+  margin-top: 12px;
+}
+.mblListItemLabel {
+  position: relative;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  height: 100%;
+}
+.mblVariableHeight .mblListItemLabel {
+  white-space: normal;
+}
+.mblListItemSubText {
+  font-size: 14px;
+  color: gray;
+}
+.mblListItemLayoutLeft {
+  position: relative;
+  float: left;
+  margin-right: 11px;
+}
+.mblListItemLayoutCenter {
+  position: absolute;
+  width: 100%;
+  text-align: center;
+}
+.mblListItemLayoutRight {
+  position: relative;
+  float: right;
+}
+/* dojox.mobile._EditableListMixin */
+.mblListItemFloat {
+  position: absolute;
+  border: 1px solid gray;
+  opacity: 0.5;
+  -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.5);
+  border-radius: 0px !important;
+  -moz-border-radius: 0px !important;
+}
+.mblListItem {
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+.mblListItem .mblListItemLabel:active {
+  color: Highlight;
+}
+.mblListItem .mblListItemLabel:first-child {
+  margin-left: 53px;
+  overflow: visible;
+}
+.mblListItem .mblListItemLabel:first-child:before {
+  content: '';
+  width: 43px;
+  height: 43px;
+  background-color: #1f1f1f;
+  position: absolute;
+  margin-left: -53px;
+}
+.mblListItem .mblListItemIcon {
+  height: 43px;
+  width: 43px;
+  margin: 0 10px 0 0;
+}
+.mblListItem .mblListItemEmptyIcon {
+  padding-top: 43px;
+  background-color: #1f1f1f;
+}
diff --git a/dojox/mobile/themes/windows/ListItem.less b/dojox/mobile/themes/windows/ListItem.less
new file mode 100644
index 0000000..1a168b4
--- /dev/null
+++ b/dojox/mobile/themes/windows/ListItem.less
@@ -0,0 +1,40 @@
+ at import url("../common/domButtons/DomButtonGrayArrow.css");
+ at import url("../common/domButtons/DomButtonDarkBlueCheck.css");
+
+ at import "variables.less";
+ at import "../common/ListItem.less";
+
+.mblListItem {
+	.default-vertical-margin;
+
+	& .mblListItemLabel {
+		&:active {
+			color: @win-accent-color;
+		}
+
+		&:first-child {
+			margin-left: @mbl-list-item-height + 10px;
+			overflow: visible;
+
+			&:before {
+				content: '';
+				width: @mbl-list-item-height;
+				height: @mbl-list-item-height;
+				background-color: @win-app-bar-color;
+				position: absolute;
+				margin-left: - at mbl-list-item-height - 10px;
+		  }
+		}
+	}
+
+	& .mblListItemIcon {
+		height: @mbl-list-item-height;
+		width: @mbl-list-item-height;
+		margin: 0 10px 0 0;
+	}
+
+	& .mblListItemEmptyIcon {
+		padding-top: @mbl-list-item-height;
+		background-color: @win-app-bar-color;
+	}
+}
diff --git a/dojox/mobile/themes/windows/ListItem_rtl.css b/dojox/mobile/themes/windows/ListItem_rtl.css
new file mode 100644
index 0000000..f34eb94
--- /dev/null
+++ b/dojox/mobile/themes/windows/ListItem_rtl.css
@@ -0,0 +1,26 @@
+/* dojox.mobile.ListItem Rtl*/
+.mblListItemRtl .mblListItemDeleteIcon {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemIcon {
+  float: right;
+  margin-left: 11px;
+  margin-right: 0px;
+}
+.mblListItemRtl .mblListItemRightIcon,
+.mblListItemRtl .mblListItemRightIcon2,
+.mblListItemRtl .mblListItemUncheckIcon {
+  float: left;
+}
+.mblListItemRtl .mblListItemRightText {
+  float: left;
+  margin-left: 4px;
+}
+.mblListItemRtl .mblListItemLayoutLeft {
+  float: right;
+  margin-left: 11px;
+}
+.mblListItemRtl .mblListItemLayoutRight {
+  float: left;
+}
diff --git a/dojox/mobile/themes/windows/Opener-compat.css b/dojox/mobile/themes/windows/Opener-compat.css
new file mode 100644
index 0000000..68cb1a8
--- /dev/null
+++ b/dojox/mobile/themes/windows/Opener-compat.css
@@ -0,0 +1,3 @@
+/* dojox.mobile.Opener */
+ at import url("Overlay-compat.css");
+ at import url("Tooltip-compat.css");
diff --git a/dojox/mobile/themes/windows/Opener.css b/dojox/mobile/themes/windows/Opener.css
new file mode 100644
index 0000000..8f2d4c8
--- /dev/null
+++ b/dojox/mobile/themes/windows/Opener.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.Opener */
+ at import url("Overlay.css");
+ at import url("Tooltip.css");
+
+.mblOpenerUnderlay {
+	-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
diff --git a/dojox/mobile/themes/windows/Overlay-compat.css b/dojox/mobile/themes/windows/Overlay-compat.css
new file mode 100644
index 0000000..c75192b
--- /dev/null
+++ b/dojox/mobile/themes/windows/Overlay-compat.css
@@ -0,0 +1,28 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Overlay */
+.mblOverlay {
+  text-align: center;
+}
+.dj_gecko .mblOverlay {
+  text-align: -moz-center;
+}
+.dj_ie9 .mblOverlay > *,
+.dj_ie8 .mblOverlay > * {
+  margin: 0 auto;
+}
+.dj_ie6 .mblOverlay {
+  *position: absolute;
+}
diff --git a/dojox/mobile/themes/windows/Overlay.css b/dojox/mobile/themes/windows/Overlay.css
new file mode 100644
index 0000000..86c4bf8
--- /dev/null
+++ b/dojox/mobile/themes/windows/Overlay.css
@@ -0,0 +1,37 @@
+ at import url("../common/transitions/coverv.css");
+
+ at import url("../common/transitions/revealv.css");
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Overlay */
+.mblOverlay {
+  position: fixed;
+  z-index: 2000;
+  left: 0;
+  bottom: 0;
+  margin: 0;
+  width: 100%;
+  text-align: -webkit-center;
+  position: fixed !important;
+  top: 0px !important;
+  background-color: #1f1f1f;
+  background-image: none;
+  padding: 12px 10px 12px 15px;
+  width: calc(100% - 15px);
+}
+.mblOverlayHidden *,
+.mblOverlayHidden {
+  visibility: hidden !important;
+}
diff --git a/dojox/mobile/themes/windows/Overlay.less b/dojox/mobile/themes/windows/Overlay.less
new file mode 100644
index 0000000..e49ea9e
--- /dev/null
+++ b/dojox/mobile/themes/windows/Overlay.less
@@ -0,0 +1,5 @@
+ at import url("../common/transitions/coverv.css");
+ at import url("../common/transitions/revealv.css");
+
+ at import "variables.less";
+ at import "../common/Overlay.less";
diff --git a/dojox/mobile/themes/windows/PageIndicator-compat.css b/dojox/mobile/themes/windows/PageIndicator-compat.css
new file mode 100644
index 0000000..50412f7
--- /dev/null
+++ b/dojox/mobile/themes/windows/PageIndicator-compat.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.PageIndicator */
+.mblPageIndicatorDot {
+	-moz-border-radius: 3px;
+}
diff --git a/dojox/mobile/themes/windows/PageIndicator.css b/dojox/mobile/themes/windows/PageIndicator.css
new file mode 100644
index 0000000..28e3f89
--- /dev/null
+++ b/dojox/mobile/themes/windows/PageIndicator.css
@@ -0,0 +1,37 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.PageIndicator */
+.mblPageIndicator {
+  position: relative;
+  width: 100%;
+  height: 20px;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblPageIndicatorContainer {
+  margin-top: 4px;
+  margin-left: auto;
+  margin-right: auto;
+}
+.mblPageIndicatorDot {
+  margin: 0px 3px;
+  width: 6px;
+  height: 6px;
+  font-size: 1px;
+  background-color: #949294;
+  border-radius: 3px;
+}
+.mblPageIndicatorDotSelected {
+  background-color: white;
+}
diff --git a/dojox/mobile/themes/windows/ProgressBar-compat.css b/dojox/mobile/themes/windows/ProgressBar-compat.css
new file mode 100644
index 0000000..e0ebd66
--- /dev/null
+++ b/dojox/mobile/themes/windows/ProgressBar-compat.css
@@ -0,0 +1,23 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* Progress Bar */
+.mblProgressBarProgress {
+  background-color: Highlight;
+}
+.dj_gecko .mblProgressBarProgress {
+  -moz-transition-property: width;
+  -moz-transition-duration: 0.25s;
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/windows/ProgressBar.css b/dojox/mobile/themes/windows/ProgressBar.css
new file mode 100644
index 0000000..b6adce8
--- /dev/null
+++ b/dojox/mobile/themes/windows/ProgressBar.css
@@ -0,0 +1,62 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.ProgressBar */
+.mblProgressBar {
+  position: relative;
+  height: 3px;
+  background-color: transparent;
+  border: none;
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+.mblProgressBarProgress {
+  -webkit-transition-property: width;
+  transition-property: width;
+  -webkit-transition-duration: 0.25s;
+  transition-duration: 0.25s;
+  height: 3px;
+  border: none;
+  background-color: Highlight;
+}
+.mblProgressBarNotStarted {
+  border-left: none;
+  border-right: none;
+}
+.mblProgressBarMsg {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  text-align: center;
+  font-size: 12px;
+  top: 3px;
+}
+.mblProgressBar:before {
+  content: '';
+  position: absolute;
+  height: 3px;
+  width: 100%;
+  background-color: Highlight;
+  opacity: 0.2;
+}
+.mblProgressBar[disabled]:before {
+  background-color: #808080;
+}
+.mblProgressBar[disabled] .mblProgressBarProgress {
+  background-color: #808080;
+}
+.mblProgressBar[disabled] .mblProgressBarMsg {
+  color: #808080;
+}
diff --git a/dojox/mobile/themes/windows/ProgressBar.less b/dojox/mobile/themes/windows/ProgressBar.less
new file mode 100644
index 0000000..cec8c5d
--- /dev/null
+++ b/dojox/mobile/themes/windows/ProgressBar.less
@@ -0,0 +1,27 @@
+ at import "variables.less";
+ at import "../common/ProgressBar.less";
+
+.mblProgressBar {
+	&:before {
+		content: '';
+		position: absolute;
+		height: @mbl-progressBar-height;
+		width: 100%;
+		background-color: @win-accent-color;
+		opacity: 0.2;
+	}
+}
+
+.mblProgressBar[disabled] {
+	&:before{
+		background-color: @win-disabled-color;
+	}
+
+	.mblProgressBarProgress {
+		background-color: @win-disabled-color;
+	}
+
+	.mblProgressBarMsg {
+		color: @win-disabled-color;
+	}
+}
diff --git a/dojox/mobile/themes/windows/ProgressIndicator-compat.css b/dojox/mobile/themes/windows/ProgressIndicator-compat.css
new file mode 100644
index 0000000..c12b868
--- /dev/null
+++ b/dojox/mobile/themes/windows/ProgressIndicator-compat.css
@@ -0,0 +1,97 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* Progress Indicator */
+.dj_ie .mblProg {
+  width: 4px;
+  height: 36px;
+}
+.dj_ie .mblProg0 {
+  left: 0px;
+}
+.dj_ie .mblProg1 {
+  left: 8px;
+}
+.dj_ie .mblProg2 {
+  left: 16px;
+}
+.dj_ie .mblProg3 {
+  left: 24px;
+}
+.dj_ie .mblProg4 {
+  left: 32px;
+}
+.dj_ie .mblProg5 {
+  left: 40px;
+}
+.dj_ie .mblProg6 {
+  left: 48px;
+}
+.dj_ie .mblProg7 {
+  left: 56px;
+}
+.dj_ie .mblProg8 {
+  left: 64px;
+}
+.dj_ie .mblProg9 {
+  left: 72px;
+}
+.dj_ie .mblProg10 {
+  left: 80px;
+}
+.dj_ie .mblProg11 {
+  left: 80px;
+}
+.dj_gecko .mblProgressIndicatorCenter .mblProgContainer {
+  -moz-transform-origin: 50% 0;
+}
+.dj_gecko .mblProg {
+  -moz-transform-origin: 0 2px;
+}
+.dj_gecko .mblProg0 {
+  -moz-transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.dj_gecko .mblProg1 {
+  -moz-transform: translate(22px, 11px) rotate(-60deg);
+}
+.dj_gecko .mblProg2 {
+  -moz-transform: translate(25px, 14px) rotate(-30deg);
+}
+.dj_gecko .mblProg3 {
+  -moz-transform: translate(26px, 18px) rotate(0deg);
+}
+.dj_gecko .mblProg4 {
+  -moz-transform: translate(25px, 22px) rotate(30deg);
+}
+.dj_gecko .mblProg5 {
+  -moz-transform: translate(22px, 25px) rotate(60deg);
+}
+.dj_gecko .mblProg6 {
+  -moz-transform: translate(18px, 26px) rotate(90.1deg);
+}
+.dj_gecko .mblProg7 {
+  -moz-transform: translate(14px, 25px) rotate(120deg);
+}
+.dj_gecko .mblProg8 {
+  -moz-transform: translate(11px, 22px) rotate(150deg);
+}
+.dj_gecko .mblProg9 {
+  -moz-transform: translate(10px, 18px) rotate(180deg);
+}
+.dj_gecko .mblProg10 {
+  -moz-transform: translate(11px, 14px) rotate(210deg);
+}
+.dj_gecko .mblProg11 {
+  -moz-transform: translate(14px, 11px) rotate(240deg);
+}
diff --git a/dojox/mobile/themes/windows/ProgressIndicator.css b/dojox/mobile/themes/windows/ProgressIndicator.css
new file mode 100644
index 0000000..14a435f
--- /dev/null
+++ b/dojox/mobile/themes/windows/ProgressIndicator.css
@@ -0,0 +1,174 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* Progress Indicator */
+.mblProgressIndicator {
+  position: relative;
+  top: 0px;
+}
+.mblHeading .mblProgressIndicator {
+  margin: 5px;
+  float: left;
+}
+.mblProgContainer {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+}
+.mblProgressIndicatorCenter {
+  position: absolute;
+  top: 180px;
+  left: 50%;
+}
+.mblProgressIndicatorCenter .mblProgContainer {
+  left: -50%;
+  -webkit-transform-origin: 50% 0;
+  transform-origin: 50% 0;
+}
+.mblProg {
+  position: absolute;
+  left: 2px;
+  top: 0px;
+  width: 11px;
+  font-size: 1px;
+  height: 4px;
+  overflow: hidden;
+  -webkit-transform-origin: 0 2px;
+  transform-origin: 0 2px;
+  background-color: #c0c0c0;
+  border-radius: 2px;
+}
+.mblProg0 {
+  -webkit-transform: translate(18px, 10px) rotate(-90.1deg);
+  transform: translate(18px, 10px) rotate(-90.1deg);
+}
+.mblProg1 {
+  -webkit-transform: translate(22px, 11px) rotate(-60deg);
+  transform: translate(22px, 11px) rotate(-60deg);
+}
+.mblProg2 {
+  -webkit-transform: translate(25px, 14px) rotate(-30deg);
+  transform: translate(25px, 14px) rotate(-30deg);
+}
+.mblProg3 {
+  -webkit-transform: translate(26px, 18px) rotate(0deg);
+  transform: translate(26px, 18px) rotate(0deg);
+}
+.mblProg4 {
+  -webkit-transform: translate(25px, 22px) rotate(30deg);
+  transform: translate(25px, 22px) rotate(30deg);
+}
+.mblProg5 {
+  -webkit-transform: translate(22px, 25px) rotate(60deg);
+  transform: translate(22px, 25px) rotate(60deg);
+}
+.mblProg6 {
+  -webkit-transform: translate(18px, 26px) rotate(90.1deg);
+  transform: translate(18px, 26px) rotate(90.1deg);
+}
+.mblProg7 {
+  -webkit-transform: translate(14px, 25px) rotate(120deg);
+  transform: translate(14px, 25px) rotate(120deg);
+}
+.mblProg8 {
+  -webkit-transform: translate(11px, 22px) rotate(150deg);
+  transform: translate(11px, 22px) rotate(150deg);
+}
+.mblProg9 {
+  -webkit-transform: translate(10px, 18px) rotate(180deg);
+  transform: translate(10px, 18px) rotate(180deg);
+}
+.mblProg10 {
+  -webkit-transform: translate(11px, 14px) rotate(210deg);
+  transform: translate(11px, 14px) rotate(210deg);
+}
+.mblProg11 {
+  -webkit-transform: translate(14px, 11px) rotate(240deg);
+  transform: translate(14px, 11px) rotate(240deg);
+}
+.mblProg0Color {
+  background-color: #c0c0c0;
+}
+.mblProg1Color {
+  background-color: #c0c0c0;
+}
+.mblProg2Color {
+  background-color: #c0c0c0;
+}
+.mblProg3Color {
+  background-color: #c0c0c0;
+}
+.mblProg4Color {
+  background-color: #c0c0c0;
+}
+.mblProg5Color {
+  background-color: #c0c0c0;
+}
+.mblProg6Color {
+  background-color: #b8b9b8;
+}
+.mblProg7Color {
+  background-color: #aeafae;
+}
+.mblProg8Color {
+  background-color: #a4a5a4;
+}
+.mblProg9Color {
+  background-color: #9a9a9a;
+}
+.mblProg10Color {
+  background-color: #8e8e8e;
+}
+.mblProg11Color {
+  background-color: #838383;
+}
+.mblProgWhite .mblProg0Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg1Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg2Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg3Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg4Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg5Color {
+  background-color: #adb9c9;
+}
+.mblProgWhite .mblProg6Color {
+  background-color: #acb9cb;
+}
+.mblProgWhite .mblProg7Color {
+  background-color: #b7c2d2;
+}
+.mblProgWhite .mblProg8Color {
+  background-color: #c4cdda;
+}
+.mblProgWhite .mblProg9Color {
+  background-color: #d1d8e2;
+}
+.mblProgWhite .mblProg10Color {
+  background-color: #dee3ea;
+}
+.mblProgWhite .mblProg11Color {
+  background-color: #eceff3;
+}
+.mblHeading .mblProgressIndicator {
+  right: 0px;
+}
diff --git a/dojox/mobile/themes/windows/ProgressIndicator.less b/dojox/mobile/themes/windows/ProgressIndicator.less
new file mode 100644
index 0000000..92a13da
--- /dev/null
+++ b/dojox/mobile/themes/windows/ProgressIndicator.less
@@ -0,0 +1,6 @@
+ at import "variables.less";
+ at import "../common/ProgressIndicator.less";
+
+.mblHeading .mblProgressIndicator {
+    right: 0px;
+}
diff --git a/dojox/mobile/themes/windows/RadioButton-compat.css b/dojox/mobile/themes/windows/RadioButton-compat.css
new file mode 100644
index 0000000..931a602
--- /dev/null
+++ b/dojox/mobile/themes/windows/RadioButton-compat.css
@@ -0,0 +1,46 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.RadioButton */
+.mblRadioButton {
+  background-image: url(compat/button-bg.png);
+}
+.mblRadioButtonChecked,
+.mblRadioButton:checked {
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblRadioButtonChecked.mblRadioButtonSelected,
+.mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: url(compat/blue-button-sel-bg.png);
+}
+.dj_gecko .mblRadioButton {
+  background-image: none;
+  -moz-appearance: none;
+}
+.dj_gecko .mblRadioButtonChecked,
+.dj_gecko .mblRadioButton:checked {
+  background-image: none;
+}
+.dj_gecko .mblRadioButtonChecked::after,
+.dj_gecko .mblRadioButton:checked::after {
+  -moz-transform: rotate(45deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblRadioButtonChecked.mblRadioButtonSelected,
+.dj_gecko .mblRadioButton:checked.mblRadioButtonSelected {
+  background-image: '';
+}
+.dj_ff3 .mblRadioButton {
+  -moz-border-radius: 0.5em;
+}
diff --git a/dojox/mobile/themes/windows/RadioButton.css b/dojox/mobile/themes/windows/RadioButton.css
new file mode 100644
index 0000000..75f1add
--- /dev/null
+++ b/dojox/mobile/themes/windows/RadioButton.css
@@ -0,0 +1,88 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.RadioButton */
+.mblRadioButton {
+  position: relative;
+  margin: -0.5em 3px 0.3em 4px;
+  width: 1em;
+  height: 1em;
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 0.5em;
+  font: inherit;
+  cursor: pointer;
+  -webkit-appearance: none;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  -webkit-transform: translateY(0.45em);
+  transform: translateY(0.45em);
+  opacity: 0;
+  margin: 0;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  transform: none;
+  z-index: 1;
+}
+.mblRadioButtonChecked::after,
+.mblRadioButton:checked::after {
+  position: absolute;
+  content: "";
+  width: 0.3em;
+  height: 0.6em;
+  top: 0;
+  left: 0.25em;
+  border-width: 0.15em;
+  border-style: none solid solid none;
+  -webkit-transform: rotate(45deg);
+  transform: rotate(45deg);
+  -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: black;
+}
+.mblRadioButtonChecked.mblRadioButtonSelected::after,
+.mblRadioButton:checked.mblRadioButtonSelected::after {
+  border-color: white;
+}
+.mblRadioButton + .mblCheckableInputDecorator:before {
+  content: '';
+  width: 20px;
+  height: 20px;
+  position: absolute;
+  border: 2px solid #ffffff;
+  background-color: transparent;
+  margin-left: -25px;
+  z-index: 0;
+  border-radius: 15px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+.mblRadioButton:not([disabled]):active + .mblCheckableInputDecorator:before,
+.mblRadioButton:not([disabled]) + .mblCheckableInputDecorator:active:before {
+  background-color: Highlight;
+}
+.mblRadioButtonChecked + .mblCheckableInputDecorator:before {
+  background-image: url("images/dark/radiobtn.png");
+  background-position: 50% 50%;
+  background-size: 13px 13px;
+  background-repeat: no-repeat;
+}
+.mblRadioButton[disabled] + .mblCheckableInputDecorator:before {
+  border-color: #808080;
+}
+.mblRadioButton[disabled].mblRadioButtonChecked + .mblCheckableInputDecorator:before {
+  background-image: url("images/radiobtn-disabled.png");
+  background-position: 50% 50%;
+  background-size: 13px 13px;
+  background-repeat: no-repeat;
+}
diff --git a/dojox/mobile/themes/windows/RadioButton.less b/dojox/mobile/themes/windows/RadioButton.less
new file mode 100644
index 0000000..f2b7077
--- /dev/null
+++ b/dojox/mobile/themes/windows/RadioButton.less
@@ -0,0 +1,33 @@
+ at import "variables.less";
+ at import "../common/RadioButton.less";
+
+.mblRadioButton + .mblCheckableInputDecorator {
+	&:before {
+		.mblCheckRadioBorder(15px);
+	}
+}
+
+.mblRadioButton:not([disabled]) {
+	&:active + .mblCheckableInputDecorator:before,
+	& + .mblCheckableInputDecorator:active:before {
+		background-color: @win-accent-color;
+	}
+}
+
+.mblRadioButtonChecked + .mblCheckableInputDecorator {
+	&:before {
+		.mblImage(@imgRadioBtnUrl, 13px 13px);
+	}
+}
+
+.mblRadioButton[disabled] {
+	& + .mblCheckableInputDecorator {
+		&:before {
+			border-color: @win-disabled-color;
+		}
+	}
+
+	&.mblRadioButtonChecked + .mblCheckableInputDecorator:before {
+		.mblImage("images/radiobtn-disabled.png", 13px 13px);
+	}
+}
diff --git a/dojox/mobile/themes/windows/RoundRect-compat.css b/dojox/mobile/themes/windows/RoundRect-compat.css
new file mode 100644
index 0000000..6e66946
--- /dev/null
+++ b/dojox/mobile/themes/windows/RoundRect-compat.css
@@ -0,0 +1,87 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.RoundRect */
+.mblRoundRect.mblShadow {
+  box-shadow: none;
+}
+.dj_ff3 .mblRoundRect {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblRoundRect.mblShadow {
+  -moz-box-shadow: none;
+}
+/* Round Corner */
+.dj_ie .mblRoundCorner {
+  background-color: #ffffff;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #cccccc;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: #ffffff;
+  border-style: solid;
+  border-color: #cccccc;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #cccccc;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #cccccc;
+  margin: 0 5px;
+}
diff --git a/dojox/mobile/themes/windows/RoundRect.css b/dojox/mobile/themes/windows/RoundRect.css
new file mode 100644
index 0000000..a43836b
--- /dev/null
+++ b/dojox/mobile/themes/windows/RoundRect.css
@@ -0,0 +1,31 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.RoundRect */
+.mblRoundRect {
+  margin: 7px 9px 16px;
+  padding: 8px;
+  border: 1px solid #cccccc;
+  border-radius: 8px;
+  background-color: #ffffff;
+  border: none;
+  background-color: transparent;
+  border-radius: 0px;
+  margin: 0px;
+  padding: 0px;
+}
+.mblRoundRect.mblShadow {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
diff --git a/dojox/mobile/themes/windows/RoundRectCategory.css b/dojox/mobile/themes/windows/RoundRectCategory.css
new file mode 100644
index 0000000..1ce624b
--- /dev/null
+++ b/dojox/mobile/themes/windows/RoundRectCategory.css
@@ -0,0 +1,26 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.RoundRectCategory */
+.mblRoundRectCategory {
+  margin: 18px 0 0 20px;
+  padding: 0;
+  font-family: Helvetica;
+  font-size: 16px;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  overflow: hidden;
+  color: #ffffff;
+  margin: 0px;
+}
diff --git a/dojox/mobile/themes/windows/RoundRectCategory_rtl.css b/dojox/mobile/themes/windows/RoundRectCategory_rtl.css
new file mode 100644
index 0000000..2a7ffc3
--- /dev/null
+++ b/dojox/mobile/themes/windows/RoundRectCategory_rtl.css
@@ -0,0 +1,4 @@
+/* dojox.mobile.RoundRectCategory Rtl */
+.mblRoundRectCategoryRtl {
+  margin: 18px 20px 0px 0px;
+}
diff --git a/dojox/mobile/themes/windows/RoundRectList-compat.css b/dojox/mobile/themes/windows/RoundRectList-compat.css
new file mode 100644
index 0000000..bb3249a
--- /dev/null
+++ b/dojox/mobile/themes/windows/RoundRectList-compat.css
@@ -0,0 +1,92 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.RoundRectList */
+.dj_ff3 .mblRoundRectList {
+  -moz-border-radius: 8px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:first-child {
+  -moz-border-radius-topleft: 8px;
+  -moz-border-radius-topright: 8px;
+}
+.dj_ff3 .mblRoundRectList .mblListItem:last-child {
+  -moz-border-radius-bottomleft: 8px;
+  -moz-border-radius-bottomright: 8px;
+}
+/* Round Corner */
+.dj_ie .mblRoundRectList {
+  position: relative;
+}
+.dj_ie .mblRoundCorner {
+  background-color: #ffffff;
+  height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: #cccccc;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectContainer {
+  padding: 3px 8px;
+  background-color: #ffffff;
+  border-style: solid;
+  border-color: #cccccc;
+  border-width: 0 1px;
+}
+.dj_ie .mblRoundRectList .mblRoundRectContainer {
+  margin: 0;
+  padding: 0;
+}
+.dj_ie .mblRoundCorner0T {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1T {
+  background-color: #cccccc;
+  margin: 0 5px;
+}
+.dj_ie .mblRoundCorner2T {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner3T {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner5T {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner0B {
+  height: 0;
+}
+.dj_ie .mblRoundCorner1B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner2B {
+  margin: 0 1px;
+}
+.dj_ie .mblRoundCorner3B {
+  margin: 0 1px;
+  border-width: 0 2px;
+}
+.dj_ie .mblRoundCorner4B {
+  margin: 0 2px;
+  border-width: 0 3px;
+}
+.dj_ie .mblRoundCorner5B {
+  background-color: #cccccc;
+  margin: 0 5px;
+}
diff --git a/dojox/mobile/themes/windows/RoundRectList.css b/dojox/mobile/themes/windows/RoundRectList.css
new file mode 100644
index 0000000..fc4f99c
--- /dev/null
+++ b/dojox/mobile/themes/windows/RoundRectList.css
@@ -0,0 +1,42 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.RoundRectList */
+.mblRoundRectList {
+  margin: 7px 9px 16px;
+  padding: 0;
+  border: 1px solid #cccccc;
+  border-radius: 8px;
+  background-color: #ffffff;
+}
+.mblRoundRectList .mblListItem:first-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:first-child {
+  border-top-left-radius: 8px;
+  border-top-right-radius: 8px;
+}
+.mblRoundRectList .mblListItem:last-child,
+.mblRoundRectList .mblEdgeToEdgeCategory:last-child {
+  border-bottom-width: 0;
+  border-bottom-left-radius: 8px;
+  border-bottom-right-radius: 8px;
+}
+.mblRoundRectList {
+  padding: 0;
+  border: none;
+  background-color: transparent;
+  margin: 0px;
+}
+.mblRoundRectList .mblListItem {
+  border-radius: 0px !important;
+}
diff --git a/dojox/mobile/themes/windows/RoundRectList.less b/dojox/mobile/themes/windows/RoundRectList.less
new file mode 100644
index 0000000..b7e5b1e
--- /dev/null
+++ b/dojox/mobile/themes/windows/RoundRectList.less
@@ -0,0 +1,13 @@
+ at import "variables.less";
+ at import "../common/RoundRectList.less";
+
+.mblRoundRectList {
+	padding: 0;
+	border: none;
+	background-color: transparent;
+	margin: 0px;
+
+	& .mblListItem {
+		border-radius: 0px !important;
+	}
+}
diff --git a/dojox/mobile/themes/windows/ScrollablePane.css b/dojox/mobile/themes/windows/ScrollablePane.css
new file mode 100644
index 0000000..f1aa3a9
--- /dev/null
+++ b/dojox/mobile/themes/windows/ScrollablePane.css
@@ -0,0 +1,33 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.mblScrollablePane */
+.mblScrollablePane {
+  position: relative;
+  overflow: hidden;
+}
+.mblScrollableViewContainer {
+  position: absolute;
+  top: 0px;
+}
+.mblScrollablePaneMask {
+  position: relative;
+}
+.mblScrollableView:not(.mblView) {
+  padding: 0px;
+}
+.mblView.mblScrollableView .mblScrollableViewContainer {
+  min-width: calc(100% - 15px - 10px) !important;
+  width: auto !important;
+}
diff --git a/dojox/mobile/themes/windows/ScrollablePane.less b/dojox/mobile/themes/windows/ScrollablePane.less
new file mode 100644
index 0000000..f8f4962
--- /dev/null
+++ b/dojox/mobile/themes/windows/ScrollablePane.less
@@ -0,0 +1,11 @@
+ at import "variables.less";
+ at import "../common/ScrollablePane.less";
+
+.mblScrollableView:not(.mblView) {
+	padding: 0px;
+}
+
+.mblView.mblScrollableView .mblScrollableViewContainer {
+	min-width: calc(~'100% - @{default-padding-left} - @{default-padding-right}') !important;
+	width: auto !important;
+}
\ No newline at end of file
diff --git a/dojox/mobile/themes/windows/SearchBox-compat.css b/dojox/mobile/themes/windows/SearchBox-compat.css
new file mode 100644
index 0000000..d0a8cf6
--- /dev/null
+++ b/dojox/mobile/themes/windows/SearchBox-compat.css
@@ -0,0 +1,40 @@
+ at import url("TextBox-compat.css");
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.SearchBox */
+.mblSearchBox {
+  height: auto;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  -moz-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
diff --git a/dojox/mobile/themes/windows/SearchBox.css b/dojox/mobile/themes/windows/SearchBox.css
new file mode 100644
index 0000000..b646816
--- /dev/null
+++ b/dojox/mobile/themes/windows/SearchBox.css
@@ -0,0 +1,82 @@
+ at import url("TextBox.css");
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.SearchBox */
+.mblSearchBox.iphone4:focus::-webkit-search-cancel-button {
+  background: none !important;
+  border-color: transparent !important;
+}
+.mblSearchBox::-webkit-search-cancel-button {
+  -webkit-appearance: none;
+  background-color: #bbc4d0;
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-size: 15px 15px;
+  background-image: -webkit-gradient(linear, left top, right bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #ffffff), color-stop(0.54, #ffffff), color-stop(0.54, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.46, transparent), color-stop(0.46, #ffffff), color-stop(0.54, #ffffff), color-stop(0.54, transparent), to(transparent)) !important;
+  border: 2px solid #bbc4d0;
+  box-sizing: border-box;
+  height: 15px;
+  width: 15px;
+  display: inline-block;
+  vertical-align: middle;
+  margin-left: 0.5em;
+  border-radius: 1em;
+}
+.mblSearchBox::-webkit-search-results-decoration {
+  -webkit-appearance: none;
+  background-repeat: no-repeat;
+  background-size: 13px 13px, 9px 9px;
+  background-position: 0px 0px, 10px 10px;
+  background-image: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 6, from(transparent), color-stop(0.65, transparent), color-stop(0.8, #bbc4d0), color-stop(0.95, transparent), to(transparent)), -webkit-gradient(linear, right top, left bottom, from(transparent), color-stop(0.425, transparent), color-stop(0.5, #bbc4d0), color-stop(0.575, transparent), to(transparent)) !important;
+  width: 15px;
+  height: 15px;
+  display: inline-block;
+  vertical-align: middle;
+}
+.mblSearchBox {
+  height: auto;
+}
+.dj_chrome .mblSearchBox {
+  border-radius: 0;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/RoundRectList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredRoundRectListSearchBox {
+  width: 100%;
+  padding-left: 9px;
+  padding-right: 9px;
+  box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
+.mblFilteredRoundRectListSearchBox > input {
+  width: 100%;
+}
+/* CSS class for the parent DIV of the dojox/mobile/SearchBox used for filtering a 
+  dojox/mobile/EdgeToEdgeList or subclass. This class is set by dojox/mobile/FilteredListMixin 
+  only if the mixin creates the SearchBox by itself. */
+.mblFilteredEdgeToEdgeListSearchBox {
+  width: 100%;
+}
+.mblFilteredEdgeToEdgeListSearchBox > input {
+  width: 100%;
+}
+.mblSearchBox {
+  height: 2em;
+}
+.mblFilteredRoundRectListSearchBox,
+.mblFilteredEdgeToEdgeListSearchBox {
+  padding: 0px;
+}
diff --git a/dojox/mobile/themes/windows/SearchBox.less b/dojox/mobile/themes/windows/SearchBox.less
new file mode 100644
index 0000000..82c5595
--- /dev/null
+++ b/dojox/mobile/themes/windows/SearchBox.less
@@ -0,0 +1,11 @@
+ at import "variables.less";
+ at import "../common/SearchBox.less";
+
+.mblSearchBox {
+	height: @win-text-input-height;
+}
+
+.mblFilteredRoundRectListSearchBox,
+.mblFilteredEdgeToEdgeListSearchBox {
+	padding: 0px;
+}
diff --git a/dojox/mobile/themes/windows/SimpleDialog-compat.css b/dojox/mobile/themes/windows/SimpleDialog-compat.css
new file mode 100644
index 0000000..23ff756
--- /dev/null
+++ b/dojox/mobile/themes/windows/SimpleDialog-compat.css
@@ -0,0 +1,18 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.SimpleDialog */
+.dj_ff3 .mblSimpleDialogDecoration {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/windows/SimpleDialog.css b/dojox/mobile/themes/windows/SimpleDialog.css
new file mode 100644
index 0000000..947c82e
--- /dev/null
+++ b/dojox/mobile/themes/windows/SimpleDialog.css
@@ -0,0 +1,83 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.SimpleDialog */
+.mblSimpleDialog {
+  position: absolute;
+  z-index: 100;
+  text-align: center;
+  outline: none;
+  background-color: #1f1f1f;
+  padding: 0 10px 12px 15px;
+  width: calc(100% - 15px - 10px);
+  margin: 0;
+  text-align: left;
+  left: 0px !important;
+}
+.mblSimpleDialogDecoration {
+  border-radius: 0;
+  background-color: #1f1f1f;
+  color: #ffffff;
+}
+.mblSimpleDialogContainer {
+  position: relative;
+  width: 100%;
+  height: 100%;
+}
+.mblSimpleDialogCover {
+  background-color: #000000;
+  opacity: 0.5;
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  z-index: 99;
+}
+.mblSimpleDialogCloseBtn {
+  position: absolute !important;
+}
+.mblSimpleDialogTitle {
+  margin: 12px 0;
+  padding: 0;
+  width: auto;
+  font-size: 11pt;
+  font-weight: 400;
+  text-align: left;
+}
+.mblSimpleDialogText {
+  margin: 12px 0;
+  width: auto;
+  text-align: left;
+}
+.mblSimpleDialog {
+  position: fixed;
+  top: 0px !important;
+  -ms-touch-action: none;
+}
+.mblSimpleDialog .mblButton {
+  width: 100%;
+  max-width: 46%;
+}
+.mblSimpleDialog .mblButton:nth-of-type(odd) {
+  float: left;
+}
+.mblSimpleDialog .mblButton:nth-of-type(even) {
+  float: right;
+}
+.mblSimpleDialogCover {
+  position: fixed;
+  top: 0px !important;
+  -ms-touch-action: none;
+}
diff --git a/dojox/mobile/themes/windows/SimpleDialog.less b/dojox/mobile/themes/windows/SimpleDialog.less
new file mode 100644
index 0000000..98bc0a2
--- /dev/null
+++ b/dojox/mobile/themes/windows/SimpleDialog.less
@@ -0,0 +1,27 @@
+ at import "variables.less";
+ at import "../common/SimpleDialog.less";
+
+.mblSimpleDialog {
+	position: fixed;
+	top: 0px !important;
+	-ms-touch-action: none;
+
+	& .mblButton {
+		width: 100%;
+		max-width: 46%;
+
+		&:nth-of-type(odd) {
+			float: left;
+		}
+
+		&:nth-of-type(even) {
+			float: right;
+		}
+	}
+}
+
+.mblSimpleDialogCover {
+	position: fixed;
+	top: 0px !important;
+	-ms-touch-action: none;
+}
diff --git a/dojox/mobile/themes/windows/Slider-compat.css b/dojox/mobile/themes/windows/Slider-compat.css
new file mode 100644
index 0000000..1da6c0a
--- /dev/null
+++ b/dojox/mobile/themes/windows/Slider-compat.css
@@ -0,0 +1,54 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Slider */
+.mblSlider {
+  background-image: url(compat/slider-h-bg.png);
+  background-repeat: repeat-x;
+}
+.mblSliderProgressBar {
+  background-image: url(compat/slider-h-bar-bg.png);
+  background-repeat: repeat-x;
+}
+.mblSliderHandle {
+  background-image: url(compat/slider-handle-bg.png);
+}
+.mblSliderV {
+  background-color: #e2e2e2;
+  background-image: none;
+}
+.mblSliderV .mblSliderProgressBar {
+  background-color: Highlight;
+  background-image: none;
+}
+.dj_gecko .mblSlider {
+  background-image: none;
+  -moz-user-select: none;
+  -moz-box-sizing: content-box;
+}
+.dj_gecko .mblSliderProgressBar {
+  background-image: none;
+}
+.dj_gecko .mblSliderHandle {
+  background-image: none;
+}
+.dj_ff3 .mblSlider {
+  -moz-border-radius: 0;
+}
+.dj_ff3 .mblSliderProgressBar {
+  -moz-border-radius: 0;
+}
+.dj_ff3 .mblSliderHandle {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/windows/Slider.css b/dojox/mobile/themes/windows/Slider.css
new file mode 100644
index 0000000..51158dc
--- /dev/null
+++ b/dojox/mobile/themes/windows/Slider.css
@@ -0,0 +1,123 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Slider */
+.mblSlider {
+  margin: 15px;
+  border-style: inset;
+  border-width: 1px;
+  border-radius: 0;
+  -webkit-user-select: none;
+  -ms-user-select: none;
+  -webkit-box-sizing: content-box;
+  box-sizing: content-box;
+  border: none;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  margin-left: 0px;
+  margin-right: 0px;
+}
+.mblSliderH {
+  width: 200px;
+  height: 8px;
+}
+.mblSliderH .mblSliderProgressBar {
+  height: 100%;
+}
+.mblSliderH .mblSliderHandle {
+  top: 50%;
+}
+.mblSliderV {
+  height: 200px;
+  width: 8px;
+}
+.mblSliderV .mblSliderProgressBar {
+  width: 100%;
+}
+.mblSliderV .mblSliderHandle {
+  left: 50%;
+}
+.mblSliderProgressBar {
+  border-radius: 0;
+}
+.mblSliderHandle {
+  margin: -10px 0 0 -10px;
+  width: 18px;
+  height: 18px;
+  border-style: outset;
+  border-width: 1px;
+  border-radius: 0;
+  border: none;
+  background-color: #ffffff;
+}
+.mblSliderTransition {
+  -webkit-transition-duration: 400ms;
+  transition-duration: 400ms;
+}
+.mblSliderTouchBox {
+  margin: 0;
+  padding: 12pt;
+  left: -12pt;
+  top: -12pt;
+  border: none;
+  width: 100%;
+  height: 100%;
+  background-color: transparent;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblSlider > div:before {
+  content: '';
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  background-color: #1f1f1f;
+}
+.mblSlider .mblSliderProgressBar {
+  background-color: Highlight;
+}
+.mblSlider .mblSliderTouchBox {
+  left: 0px;
+  top: -4px;
+  padding: 4px 0px;
+}
+.mblSlider[disabled] > div:before {
+  opacity: 0.5;
+}
+.mblSlider[disabled] .mblSliderProgressBar {
+  background-color: #808080;
+}
+.mblSliderV {
+  width: 0.5em !important;
+  height: 100% !important;
+}
+.mblSliderV > div {
+  min-height: 100px;
+}
+.mblSliderV .mblSliderHandle {
+  height: 0.5em;
+  width: 1.1em;
+  margin-top: -4px;
+  margin-left: -8px;
+}
+.mblSliderH {
+  min-width: 100px;
+  width: 100% !important;
+  height: 0.5em !important;
+}
+.mblSliderH .mblSliderHandle {
+  height: 1.1em;
+  width: 0.5em;
+  margin-top: -8px;
+  margin-left: -4px;
+}
diff --git a/dojox/mobile/themes/windows/Slider.less b/dojox/mobile/themes/windows/Slider.less
new file mode 100644
index 0000000..05c74c9
--- /dev/null
+++ b/dojox/mobile/themes/windows/Slider.less
@@ -0,0 +1,52 @@
+ at import "variables.less";
+ at import "../common/Slider.less";
+
+.mblSlider {
+	> div:before {
+		content: '';
+		position: absolute;
+		width: 100%;
+		height: 100%;
+		background-color: @win-app-bar-color;
+	}
+
+	.mblSliderProgressBar {
+		background-color: @win-accent-color;
+	}
+
+	& .mblSliderTouchBox {
+		left: 0px;
+		top: -4px;
+		padding: 4px 0px;
+	}
+}
+
+.mblSlider[disabled] {
+	> div:before {
+		opacity: 0.5;
+	}
+
+	.mblSliderProgressBar {
+		background-color: @win-disabled-color;
+	}
+}
+
+.mblSliderV {
+	> div {
+		min-height: 100px;
+	};
+	.mblSlider-size(@mbl-slider-height, 100%);
+
+	& .mblSliderHandle {
+		.mblSliderHandle-markup("V");
+	}
+}
+
+.mblSliderH {
+	min-width: 100px;
+	.mblSlider-size(100%, @mbl-slider-height);
+
+	& .mblSliderHandle {
+		.mblSliderHandle-markup("H");
+	}
+}
diff --git a/dojox/mobile/themes/windows/SpinWheel-compat.css b/dojox/mobile/themes/windows/SpinWheel-compat.css
new file mode 100644
index 0000000..67835f6
--- /dev/null
+++ b/dojox/mobile/themes/windows/SpinWheel-compat.css
@@ -0,0 +1,50 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+.mblSpinWheel {
+  background-image: url(../common/compat/spinwheel-bg.png);
+}
+.mblSpinWheelBar {
+  background-image: url(../common/compat/spinwheel-bar.png);
+}
+.mblSpinWheelSlotTouch,
+.mblSpinWheelSlotPanel {
+  left: 0;
+}
+.dj_gecko .mblSpinWheel {
+  background-image: -moz-linear-gradient(top, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+}
+.dj_gecko .mblSpinWheelBar {
+  background-image: -moz-linear-gradient(top, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 1%);
+}
+.dj_ff3 .mblSpinWheel {
+  -moz-border-radius: 3px;
+}
+.dj_ie .mblSpinWheelBar {
+  filter: progid:DXImageTransform.Microsoft.alpha(opacity=60);
+}
+.dj_ie6 .mblSpinWheelBar,
+.dj_ie7 .mblSpinWheelBar {
+  z-index: -1;
+}
+.dj_ie7 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
+.dj_ie6 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+  height: 200px;
+}
diff --git a/dojox/mobile/themes/windows/SpinWheel.css b/dojox/mobile/themes/windows/SpinWheel.css
new file mode 100644
index 0000000..24f88cf
--- /dev/null
+++ b/dojox/mobile/themes/windows/SpinWheel.css
@@ -0,0 +1,180 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.SpinWheel */
+.mblSpinWheel {
+  position: relative;
+  overflow: hidden;
+  background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #313137), color-stop(0.05, #73747d), color-stop(0.07, #92939b), color-stop(0.09, #ababb5), color-stop(0.12, #c5c6ce), color-stop(0.16, #dfe0e4), color-stop(0.22, #f4f5f6), color-stop(0.35, #fbfcfc), color-stop(0.5, #fbfcfc), color-stop(0.61, #fbfcfc), color-stop(0.61, #b4c1c7), color-stop(0.65, #fbfcfc), color-stop(0.78, #f4f5f6), color-stop(0.84, #dfe0e4), color-stop(0.88, #c5c6ce), color-stop(0.91, #ababb5), co [...]
+  background: linear-gradient(to bottom, #313137 0%, #73747d 5%, #92939b 7%, #ababb5 9%, #c5c6ce 12%, #dfe0e4 16%, #f4f5f6 22%, #fbfcfc 35%, #fbfcfc 50%, #fbfcfc 61%, #b4c1c7 61%, #fbfcfc 65%, #f4f5f6 78%, #dfe0e4 84%, #c5c6ce 88%, #ababb5 91%, #92939b 93%, #73747d 95%, #313137 100%);
+  height: 200px;
+  border-left: solid 3px #000000;
+  border-right: solid 3px #000000;
+  color: #000000;
+  border-radius: 3px;
+}
+.mblSpinWheelBar {
+  position: absolute;
+  top: 79px;
+  background: -webkit-gradient(linear, left top, left bottom, from(#edeef2), to(#a7adca), color-stop(0, #edeef2), color-stop(0.25, #c8cadd), color-stop(0.49, #bbbfd4), color-stop(0.51, #9fa8c6), color-stop(0.81, #a2a9c7), color-stop(0.82, #a6abc9), color-stop(1, #a7adca));
+  background: linear-gradient(to bottom, #edeef2 0%, #c8cadd 25%, #bbbfd4 49%, #9fa8c6 51%, #a2a9c7 81%, #a6abc9 82%, #a7adca 100%);
+  border: solid 1px #7b8497;
+  height: 42px;
+  width: 100%;
+  clear: both;
+  opacity: 0.6;
+}
+.mblSpinWheelDatePicker {
+  width: 312px;
+}
+.mblSpinWheelTimePicker {
+  width: 98px;
+}
+.mblSpinWheelSlot {
+  position: relative;
+  top: 0px;
+  float: left;
+  width: 100px;
+  height: 100%;
+  border-left: solid 2px #000000;
+  border-right: solid 2px #000000;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblSpinWheelSlotLabel {
+  padding: 0 8px;
+  height: 44px;
+  overflow: hidden;
+  font: bold 24px/44px Helvetica, sans-serif;
+}
+.mblSpinWheelSlotLabel img {
+  vertical-align: middle;
+  opacity: 0.7;
+}
+.mblSpinWheelSlotLabelGray {
+  color: #cccccc;
+}
+.mblSpinWheelSlotLabelBlue {
+  color: #0959d2;
+}
+.mblSpinWheelSlotContainer {
+  position: relative;
+}
+.mblSpinWheelSlotPanel {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+}
+.mblSpinWheelSlotTouch {
+  position: absolute;
+  top: 0px;
+  width: 100%;
+  height: 100%;
+  z-index: 1;
+}
+.dj_ie .mblSpinWheelSlotTouch {
+  background-color: rgba(255, 255, 255, 0.01);
+}
+.dj_ie8 .mblSpinWheelSlotTouch {
+  background: white;
+  filter: alpha(opacity=0);
+}
+.mblSpinWheel {
+  background-image: none !important;
+  border: none !important;
+  margin: auto 0;
+  height: 400px !important;
+  width: auto !important;
+  display: -ms-flexbox;
+  color: #ffffff;
+}
+.mblSpinWheel .mblSpinWheelSlot {
+  -ms-flex-preferred-size: auto;
+  border: none;
+  -ms-user-select: none;
+  text-align: left !important;
+  overflow: hidden;
+  margin: 0px !important;
+  width: 100px !important;
+}
+.mblSpinWheel .mblSpinWheelSlot:empty {
+  display: none !important;
+}
+.mblSpinWheel .mblSpinWheelSlot:not([widgetId]) {
+  top: 150px;
+  height: 94px !important;
+  width: 86px !important;
+  padding: 0 0 0 8px !important;
+  margin-right: 6px !important;
+  background-color: #666666;
+  line-height: 4.5;
+}
+.mblSpinWheel .mblSpinWheelSlotContainer:not(.mblSelectedSlot) .mblSpinWheelSlotLabel:not(.mblSelectedSlotItem) {
+  opacity: 0;
+  -ms-transition: opacity 0.4s ease-out;
+}
+.mblSpinWheel .mblSpinWheelSlotContainer:not(.mblSelectedSlot) .mblSpinWheelSlotLabel:not(.mblSelectedSlotItem):before {
+  opacity: 0;
+  transition: opacity 0.4s ease-out;
+}
+.mblSpinWheel .mblSpinWheelSlotLabel:not(.mblSelectedSlotItem) {
+  opacity: 1;
+  -ms-transition: opacity 0.4s ease-out;
+}
+.mblSpinWheel .mblSpinWheelSlotLabel:not(.mblSelectedSlotItem):before {
+  opacity: 1;
+  transition: opacity 0.4s ease-out;
+}
+.mblSpinWheel .mblSpinWheelSlotLabel {
+  border: none;
+  margin: 0px;
+  color: #808080;
+  height: 100px;
+  line-height: 3.5;
+  font-size: 17pt;
+}
+.mblSpinWheel .mblSpinWheelSlotLabel.mblSelectedSlotItem {
+  color: #ffffff;
+}
+.mblSpinWheel .mblSpinWheelSlotLabel.mblSelectedSlotItem:before {
+  background-color: #808080;
+  z-index: -1;
+}
+.mblSpinWheel .mblSpinWheelSlotLabel:before {
+  content: '';
+  position: absolute;
+  width: 90px;
+  height: 90px;
+  border: 2px solid #808080;
+  left: 0px;
+}
+.mblSpinWheel .mblSpinWheelSlotLabel.mblSpinWheelSlotLabelGray {
+  opacity: 0.3;
+}
+.mblSpinWheel .mblSpinWheelSlotLabel.mblSpinWheelSlotLabelGray:before {
+  opacity: 0.3;
+}
+.mblSpinWheel .mblSpinWheelBar {
+  display: none;
+}
+.mblSpinWheel .mblSpinWheelSlotTouch {
+  background-color: #000000;
+  opacity: 0.01;
+}
+.mblTooltip.mblOpener .mblSpinWheelDatePicker {
+  left: calc(50% - 150px);
+  position: absolute !important;
+  top: 50%;
+  bottom: 50%;
+  width: 300px !important;
+}
diff --git a/dojox/mobile/themes/windows/SpinWheel.less b/dojox/mobile/themes/windows/SpinWheel.less
new file mode 100644
index 0000000..8ebb20c
--- /dev/null
+++ b/dojox/mobile/themes/windows/SpinWheel.less
@@ -0,0 +1,112 @@
+ at import "variables.less";
+ at import "../common/SpinWheel.less";
+
+ at mbl-PickerItemHeight: 100px;
+ at mbl-PickerItemWidth: 100px;
+
+.mblSpinWheel {
+	background-image: none !important;
+	border: none !important;
+	margin: auto 0;
+	height: 400px !important;
+	width: auto !important;
+	display: -ms-flexbox;
+	color: @win-foreground-color;
+
+	& .mblSpinWheelSlot {
+		-ms-flex-preferred-size: auto;
+		border: none;
+		-ms-user-select: none;
+		text-align: left !important;
+		overflow: hidden;
+		margin: 0px !important;
+		width: @mbl-PickerItemWidth !important;
+
+		&:empty {
+			display: none !important;
+		}
+
+		&:not([widgetId]) {
+			top: 150px;
+			height: 94px !important;
+			width: 86px !important;
+			padding: 0 0 0 8px !important;
+			margin-right: 6px !important;
+			background-color: @win-inactive-color;
+			line-height: 4.5;
+		}
+	}
+
+	& .mblSpinWheelSlotContainer:not(.mblSelectedSlot) {
+		& .mblSpinWheelSlotLabel:not(.mblSelectedSlotItem) {
+		  opacity: 0;
+		  -ms-transition: opacity 0.4s ease-out;
+		  &:before {
+			  opacity: 0;
+			  transition: opacity 0.4s ease-out;
+		  }
+		}
+	}
+
+	& .mblSpinWheelSlotLabel:not(.mblSelectedSlotItem) {
+		opacity: 1;
+		-ms-transition: opacity 0.4s ease-out;
+		&:before {
+			opacity: 1;
+			transition: opacity 0.4s ease-out;
+		}
+	}
+
+	& .mblSpinWheelSlotLabel {
+		border: none;
+		margin: 0px;
+		color: @win-disabled-color;
+		height: @mbl-PickerItemHeight;
+		line-height: 3.5;
+		font-size: @win-font-size-extra-large;
+
+		&.mblSelectedSlotItem {
+			color: @win-foreground-color;
+			&:before {
+				background-color: @win-disabled-color;
+				z-index: -1;
+			}
+		}
+
+		&:before {
+			content: '';
+			position: absolute;
+			width: 90px;
+			height: 90px;
+			border: 2px solid @win-disabled-color;
+			left: 0px;
+		}
+
+		&.mblSpinWheelSlotLabelGray {
+			opacity: 0.3;
+
+			&:before{
+				opacity: 0.3;
+			}
+		}
+	}
+
+	& .mblSpinWheelBar {
+		display: none;
+	}
+
+	& .mblSpinWheelSlotTouch {
+		background-color: @win-bg-color;
+		opacity: 0.01;
+	}
+}
+
+.mblTooltip.mblOpener  {
+	& .mblSpinWheelDatePicker {
+		left: calc(~"50% - 150px");
+		position: absolute !important;
+		top: 50%;
+		bottom: 50%;
+		width: 300px !important;
+	}
+}
diff --git a/dojox/mobile/themes/windows/SpinWheel_rtl-compat.css b/dojox/mobile/themes/windows/SpinWheel_rtl-compat.css
new file mode 100644
index 0000000..98aab55
--- /dev/null
+++ b/dojox/mobile/themes/windows/SpinWheel_rtl-compat.css
@@ -0,0 +1,4 @@
+.mblSpinWheelSlotRtl .mblSpinWheelSlotTouch,
+.mblSpinWheelSlotRtl .mblSpinWheelSlotPanel {
+  right: 0;
+}
diff --git a/dojox/mobile/themes/windows/SpinWheel_rtl.css b/dojox/mobile/themes/windows/SpinWheel_rtl.css
new file mode 100644
index 0000000..c3efc85
--- /dev/null
+++ b/dojox/mobile/themes/windows/SpinWheel_rtl.css
@@ -0,0 +1,5 @@
+/* dojox.mobile.SpinWheel Rtl */
+.mblSpinWheelSlotRtl,
+.mblSpinWheelRtl .mblSpinWheelSlot {
+  float: right;
+}
diff --git a/dojox/mobile/themes/windows/Switch-compat.css b/dojox/mobile/themes/windows/Switch-compat.css
new file mode 100644
index 0000000..d8c456f
--- /dev/null
+++ b/dojox/mobile/themes/windows/Switch-compat.css
@@ -0,0 +1,130 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Switch */
+/* Switch - common */
+.dj_gecko .mblSwitchBg {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitchKnob {
+  -moz-box-sizing: border-box;
+}
+.dj_gecko .mblSwitch .mblSwitchBgLeft {
+  background-image: none;
+}
+.dj_gecko .mblSwitch .mblSwitchBgRight {
+  background-image: none;
+}
+.dj_gecko .mblSwitch .mblSwitchKnob {
+  background-image: none;
+}
+.dj_ie .mblSwitchBg {
+  border: none;
+  background: none;
+}
+.dj_ie .mblSwitchBgLeft {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchBgRight {
+  background-repeat: no-repeat;
+}
+.dj_ie .mblSwitchKnob {
+  background: none;
+  background-repeat: no-repeat;
+  border: none;
+}
+/* Square Shape */
+.mblSwSquareShape .mblSwitchBg {
+  -moz-border-radius: 2px;
+}
+.mblSwSquareShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-square-l.gif);
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchKnob {
+  -moz-border-radius: 2px;
+  background-image: url(compat/switch-square-k.gif);
+}
+/* Round Shape1 */
+.mblSwRoundShape1 .mblSwitchBg {
+  -moz-border-radius: 14px;
+}
+.mblSwRoundShape1 .mblSwitchBgLeft {
+  background-image: url(compat/switch-round1-l.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round1-k.gif);
+}
+/* Round Shape2 */
+.mblSwRoundShape2 .mblSwitchBg {
+  -moz-border-radius: 14px;
+}
+.mblSwRoundShape2 .mblSwitchBgLeft {
+  background-image: url(compat/switch-round2-l.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+  background-image: url(compat/switch-round2-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchKnob {
+  -moz-border-radius: 13px;
+  background-image: url(compat/switch-round2-k.gif);
+}
+/* Arc Shape1 */
+.mblSwArcShape1 .mblSwitchBg {
+  -moz-border-radius: 5px/14px;
+}
+.mblSwArcShape1 .mblSwitchBgLeft {
+  background-image: url(compat/switch-arc1-l.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+  background-image: url(compat/switch-arc1-r.gif);
+}
+.mblSwArcShape1 .mblSwitchKnob {
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc1-k.gif);
+}
+/* Switch - Arc Shape2 */
+.mblSwArcShape2 .mblSwitchBg {
+  -moz-border-radius: 5px/14px;
+}
+.mblSwArcShape2 .mblSwitchBgLeft {
+  background-image: url(compat/switch-arc2-l.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+  background-image: url(compat/switch-arc2-r.gif);
+}
+.mblSwArcShape2 .mblSwitchKnob {
+  -moz-border-radius: 5px/13px;
+  background-image: url(compat/switch-arc2-k.gif);
+}
+/* Default Shape */
+.mblSwDefaultShape .mblSwitchBg {
+  -moz-border-radius: 2px;
+}
+.mblSwDefaultShape .mblSwitchBgLeft {
+  background-image: url(compat/switch-square-l.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  -moz-border-radius: 2px;
+  background-image: url(compat/switch-square-k.gif);
+}
diff --git a/dojox/mobile/themes/windows/Switch-compat.less b/dojox/mobile/themes/windows/Switch-compat.less
new file mode 100644
index 0000000..f15894c
--- /dev/null
+++ b/dojox/mobile/themes/windows/Switch-compat.less
@@ -0,0 +1,7 @@
+ at import "variables.less";
+ at import "../common/Switch-compat.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwSquareShape-styles;
+}
diff --git a/dojox/mobile/themes/windows/Switch.css b/dojox/mobile/themes/windows/Switch.css
new file mode 100644
index 0000000..85aaa56
--- /dev/null
+++ b/dojox/mobile/themes/windows/Switch.css
@@ -0,0 +1,296 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Switch */
+/* Switch - common */
+.mblSwitch {
+  margin: 0;
+  position: relative;
+  display: inline-block;
+  height: 27px;
+  line-height: 29px;
+  overflow: hidden;
+  text-align: left;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+}
+.mblListItem .mblSwitch {
+  position: absolute;
+  right: 12px;
+  top: 8px;
+}
+.mblSwitchInner {
+  position: absolute;
+  top: 0;
+  height: 27px;
+}
+.mblSwitchAnimation .mblSwitchInner {
+  -webkit-transition-property: left;
+  transition-property: left;
+  -webkit-transition-duration: 0.1s;
+  transition-duration: 0.1s;
+}
+.mblSwitchOn .mblSwitchInner {
+  left: 0;
+}
+.mblSwitchBg {
+  position: absolute;
+  top: 0;
+  width: 94px;
+  height: 27px;
+  font-family: Helvetica;
+  font-size: 16px;
+  font-weight: bold;
+  line-height: 29px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border: none;
+}
+.mblSwitchBgLeft {
+  left: 0;
+  color: white;
+  background-color: #3f84eb;
+}
+.mblSwitchBgRight {
+  color: #7f7f7f;
+}
+.mblSwitchKnob {
+  position: absolute;
+  top: 0;
+  height: 27px;
+  font-size: 1px;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  border: 2px solid #000000;
+  background-color: #ffffff;
+  width: 18px !important;
+  z-index: 3;
+  border-radius: 0 !important;
+}
+.mblSwitchText {
+  position: relative;
+  top: 0;
+  width: 53px;
+  height: 27px;
+  padding: 0;
+  line-height: 28px;
+  text-align: center;
+}
+.mblSwitchTextLeft {
+  left: 0;
+}
+.mblSwitchTextRight {
+  left: 40px;
+}
+/* Square Shape */
+.mblSwSquareShape {
+  width: 94px;
+}
+.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBg {
+  border-radius: 2px;
+}
+.mblSwSquareShape .mblSwitchBgRight {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+  width: 41px;
+  border-radius: 2px;
+}
+.mblSwSquareShape .mblSwitchText {
+  width: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRight {
+  left: 40px;
+}
+/* Round Shape1 */
+.mblSwRoundShape1 {
+  width: 77px;
+}
+.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwRoundShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 14px;
+}
+.mblSwRoundShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 13px;
+}
+.mblSwRoundShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Round Shape2 */
+.mblSwRoundShape2 {
+  width: 94px;
+}
+.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBg {
+  border-radius: 14px;
+}
+.mblSwRoundShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 13px;
+}
+.mblSwRoundShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Arc Shape1 */
+.mblSwArcShape1 {
+  width: 77px;
+}
+.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: -50px;
+}
+.mblSwArcShape1 .mblSwitchBg {
+  width: 77px;
+  border-radius: 5px/14px;
+}
+.mblSwArcShape1 .mblSwitchBgRight {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+  width: 27px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape1 .mblSwitchText {
+  width: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRight {
+  left: 26px;
+}
+/* Arc Shape2 */
+.mblSwArcShape2 {
+  width: 94px;
+}
+.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBg {
+  border-radius: 5px/14px;
+}
+.mblSwArcShape2 .mblSwitchBgRight {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+  width: 43px;
+  border-radius: 5px/13px;
+}
+.mblSwArcShape2 .mblSwitchText {
+  width: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRight {
+  left: 42px;
+}
+/* Default Shape */
+.mblSwDefaultShape {
+  width: 94px;
+}
+.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: -53px;
+}
+.mblSwDefaultShape .mblSwitchBg {
+  border-radius: 2px;
+}
+.mblSwDefaultShape .mblSwitchBgRight {
+  left: 53px;
+}
+.mblSwDefaultShape .mblSwitchKnob {
+  left: 53px;
+  width: 41px;
+  border-radius: 2px;
+}
+.mblSwDefaultShape .mblSwitchText {
+  width: 53px;
+}
+.mblSwDefaultShape .mblSwitchTextRight {
+  left: 40px;
+}
+.mblSwitchBgLeft {
+  background-color: Highlight;
+  height: 14px;
+  margin: auto 4px;
+  top: 50%;
+  bottom: 50%;
+  border-radius: 0 !important;
+  width: 45px !important;
+  z-index: 1;
+}
+.mblSwitch {
+  width: 65px;
+  float: right;
+  display: block;
+  clear: right;
+}
+.mblSwitch:before {
+  content: '';
+  width: 85%;
+  height: 65%;
+  position: absolute;
+  border: 2px solid #ffffff;
+  margin: auto 0;
+  top: 50%;
+  bottom: 50%;
+  z-index: 2;
+}
+.mblSwitch.mblSwitchOn .mblSwitchKnob {
+  left: 45px !important;
+}
+.mblSwitch .mblSwitchInner {
+  width: 100%;
+}
+.mblSwitch[disabled] .mblSwitchKnob,
+.mblSwitch[disabled] .mblSwitchBgLeft {
+  background-color: #808080;
+}
+.mblSwitch[disabled]:before {
+  border-color: #808080;
+}
+.mblSwitchText {
+  display: none !important;
+}
+.mblSwitchLabel {
+  color: #ffffff;
+  position: relative;
+  float: left;
+  clear: both;
+  margin: 3px 0;
+}
+.mblSwitchContainer {
+  width: 100%;
+  min-height: 27px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
diff --git a/dojox/mobile/themes/windows/Switch.less b/dojox/mobile/themes/windows/Switch.less
new file mode 100644
index 0000000..a531b76
--- /dev/null
+++ b/dojox/mobile/themes/windows/Switch.less
@@ -0,0 +1,73 @@
+ at import "variables.less";
+ at import "../common/Switch.less";
+
+/* Default Shape */
+.mblSwDefaultShape {
+	.mblSwSquareShape-styles;
+}
+
+.mblSwitchBgLeft {
+	background-color: @mbl-switch-bg-left-background-color;
+	height: 14px;
+	margin: auto 4px;
+	top: 50%;
+	bottom: 50%;
+	border-radius: 0 !important;
+	width: 45px !important;
+	z-index: 1;
+}
+
+.mblSwitch {
+	width: 65px;
+	float: right;
+	display: block;
+	clear: right;
+
+	&:before {
+		content: '';
+		width: 85%;
+		height: 65%;
+		position: absolute;
+		border: 2px solid @win-contrast-bg-color;
+		margin: auto 0;
+		top: 50%;
+		bottom: 50%;
+		z-index: 2;
+	}
+
+	&.mblSwitchOn .mblSwitchKnob {
+	  left: 45px !important;
+	}
+
+	& .mblSwitchInner{
+		width: 100%;
+	}
+}
+
+.mblSwitch[disabled] {
+	& .mblSwitchKnob,
+	& .mblSwitchBgLeft {
+		background-color: @win-disabled-color;
+	}
+	&:before {
+		border-color: @win-disabled-color;
+	}
+}
+
+.mblSwitchText {
+	display: none !important;
+}
+
+.mblSwitchLabel {
+	color: @win-foreground-color;
+	position: relative;
+	float: left;
+	clear: both;
+	margin: 3px 0;
+}
+
+.mblSwitchContainer {
+	width: 100%;
+	min-height: 27px;
+	.default-vertical-margin;
+}
diff --git a/dojox/mobile/themes/windows/Switch_rtl-compat.css b/dojox/mobile/themes/windows/Switch_rtl-compat.css
new file mode 100644
index 0000000..5293453
--- /dev/null
+++ b/dojox/mobile/themes/windows/Switch_rtl-compat.css
@@ -0,0 +1,43 @@
+/* dojox.mobile.Switch Rtl */
+/* Square Shape Rtl */
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
+/* Round Shape1 Rtl */
+.mblSwRoundShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round1-r.gif);
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round1-l.gif);
+}
+/* Round Shape2 Rtl */
+.mblSwRoundShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-round2-r.gif);
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-round2-l.gif);
+}
+/* Arc Shape1 Rtl */
+.mblSwArcShape1 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc1-r.gif);
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc1-l.gif);
+}
+/* Switch - Arc Shape2 Rtl */
+.mblSwArcShape2 .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-arc2-r.gif);
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-arc2-l.gif);
+}
+/* Default Shape Rtl */
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  background-image: url(compat/switch-square-r.gif);
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  background-image: url(compat/switch-square-l.gif);
+}
diff --git a/dojox/mobile/themes/windows/Switch_rtl.css b/dojox/mobile/themes/windows/Switch_rtl.css
new file mode 100644
index 0000000..a119019
--- /dev/null
+++ b/dojox/mobile/themes/windows/Switch_rtl.css
@@ -0,0 +1,117 @@
+/* dojox.mobile.Switch Rtl */
+/* Switch - common Rtl */
+.mblSwitchRtl {
+  text-align: right;
+}
+.mblListItemRtl .mblSwitch {
+  left: 12px;
+  right: auto;
+}
+.mblSwitchRtl.mblSwitchOn .mblSwitchInner {
+  left: -50px;
+}
+.mblSwitchBgLeftRtl {
+  left: 51px;
+}
+.mblSwitchTextLeftRtl {
+  left: 0px;
+}
+.mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Square Shape Rtl*/
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwSquareShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwSquareShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwSquareShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwSquareShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwSquareShape .mblSwitchTextRightRtl {
+  left: -40px;
+}
+/* Round Shape1 Rtl */
+.mblSwitchRtl.mblSwRoundShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwRoundShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwRoundShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Round Shape2 Rtl */
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwRoundShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwRoundShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwRoundShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Arc Shape1 Rtl */
+.mblSwitchRtl.mblSwArcShape1.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape1 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape1 .mblSwitchKnob {
+  left: 50px;
+}
+.mblSwArcShape1 .mblSwitchTextRightRtl {
+  left: -26px;
+}
+/* Arc Shape2 Rtl */
+.mblSwitchRtl.mblSwArcShape2.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwArcShape2.mblSwitchOn .mblSwitchInner {
+  left: -51px;
+}
+.mblSwArcShape2 .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwArcShape2 .mblSwitchKnob {
+  left: 51px;
+}
+.mblSwArcShape2 .mblSwitchTextRightRtl {
+  left: -42px;
+}
+/* Default Shape Rtl */
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOff .mblSwitchInner {
+  left: 0px;
+}
+.mblSwitchRtl.mblSwDefaultShape.mblSwitchOn .mblSwitchInner {
+  left: -53px;
+}
+.mblSwDefaultShape .mblSwitchBgRightRtl {
+  left: 0px;
+}
+.mblSwDefaultShape .mblSwitchBgLeftRtl {
+  left: 53px;
+}
+.mblSwitchRtl.mblSwDefaultShape .mblSwitchKnob {
+  left: 53px;
+}
+.mblSwDefaultShape .mblSwitchTextRightRtl {
+  left: 40px;
+}
diff --git a/dojox/mobile/themes/windows/TabBar-compat.css b/dojox/mobile/themes/windows/TabBar-compat.css
new file mode 100644
index 0000000..4c7405e
--- /dev/null
+++ b/dojox/mobile/themes/windows/TabBar-compat.css
@@ -0,0 +1,73 @@
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.TabBar */
+.dj_ie6 .mblTabBar .mblTabBarButton {
+  display: inline;
+}
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  background-image: none;
+  background-color: #000000;
+}
+.dj_ff3 .mblTabBarTabBar .mblTabBarButtonSelected {
+  -moz-border-radius: 3px;
+}
+/* barType="segmentedControl" | "standardTab" */
+.mblTabBarSegmentedControl,
+.mblTabBarStandardTab {
+  background-image: url(compat/heading-bg.png);
+}
+.mblTabBarSegmentedControl .mblTabBarButton,
+.mblTabBarStandardTab .mblTabBarButton {
+  background-image: url(compat/tab-seg-button-bg.png);
+}
+.mblTabBarSegmentedControl .mblTabBarButtonSelected,
+.mblTabBarStandardTab .mblTabBarButtonSelected {
+  background-image: url(compat/tab-seg-sel-button-bg.png);
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:first-child {
+  -moz-border-radius-topleft: 5px;
+  -moz-border-radius-bottomleft: 5px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButton:last-child {
+  -moz-border-radius-topright: 5px;
+  -moz-border-radius-bottomright: 5px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButton {
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 4px;
+}
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  background-image: url(compat/tab-slim-bar-bg.png);
+}
+.dj_gecko .mblTabBarSlimTab {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.dj_gecko .mblTabBarSlimTab .mblTabBarButton {
+  background-image: -moz-linear-gradient(top, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.dj_gecko .mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-image: -moz-linear-gradient(top, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
+}
+/* barType="flatTab" */
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  background-image: url(compat/tab-tall-bar-bg.png);
+}
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-color: #8c8e8c;
+}
diff --git a/dojox/mobile/themes/windows/TabBar-compat.less b/dojox/mobile/themes/windows/TabBar-compat.less
new file mode 100644
index 0000000..c0476f3
--- /dev/null
+++ b/dojox/mobile/themes/windows/TabBar-compat.less
@@ -0,0 +1,3 @@
+ at import "variables.less";
+ at import "../common/TabBar-compat.less";
+ at import "../common/domButtons/DomButtonWhiteCross-compat.css";
diff --git a/dojox/mobile/themes/windows/TabBar.css b/dojox/mobile/themes/windows/TabBar.css
new file mode 100644
index 0000000..0a8ac65
--- /dev/null
+++ b/dojox/mobile/themes/windows/TabBar.css
@@ -0,0 +1,277 @@
+ at import "../common/domButtons/DomButtonWhiteCross.css";
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.TabBar */
+.mblTabBar {
+  position: relative;
+  margin: 0px;
+  overflow: hidden;
+  white-space: nowrap;
+  text-overflow: ellipsis;
+  padding: 0px 6px;
+  height: 42px;
+  text-align: center;
+  color: white;
+  border-top: 1px solid transparent;
+  border-bottom: 1px solid transparent;
+  padding: 0px;
+}
+/* dojox.mobile.TabBarButton */
+.mblTabBarFill .mblTabBarButton {
+  box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+}
+.mblTabBarButton {
+  overflow: hidden;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  position: relative;
+  list-style-type: none;
+  float: left;
+}
+.mblTabBarButtonIconArea {
+  margin: 0 auto;
+  width: 29px;
+}
+.mblTabBarButtonIconParent1 {
+  display: block;
+}
+.mblTabBarButtonIconParent2 {
+  display: none;
+}
+.mblTabBarButtonSelected .mblTabBarButtonIconParent1 {
+  display: none;
+}
+.mblTabBarButtonSelected .mblTabBarButtonIconParent2 {
+  display: block;
+}
+/* barType="tabBar" */
+.mblTabBarTabBar {
+  height: 48px;
+  border-top: 1px solid #000000;
+}
+.mblTabBarTabBar .mblTabBarButton {
+  font-family: "Segoe WP", "Segoe UI", "HelveticaNeue", "Helvetica-Neue", "Helvetica", "BBAlpha Sans", "sans-serif";
+}
+.mblTabBarTabBar .mblTabBarButtonIconArea {
+  padding-top: 4px;
+}
+.mblTabBarTabBar .mblTabBarButtonLabel {
+  font-family: "Helvetica Neue", Helvetica;
+  font-size: 11px;
+  color: white;
+  font-family: "Segoe WP", "Segoe UI", "HelveticaNeue", "Helvetica-Neue", "Helvetica", "BBAlpha Sans", "sans-serif";
+}
+.mblTabBarTabBar .mblTabBarButtonSelected {
+  border-radius: 3px;
+  background-color: #404040;
+}
+.mblTabBarTabBar .mblTabBarButtonSelected .mblTabBarButtonLabel {
+  color: white;
+}
+/* barType="segmentedControl" */
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButton {
+  width: auto;
+  padding: 0 3px;
+}
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconArea {
+  position: relative;
+}
+.mblTabBarSegmentedControl .mblTabBarButton {
+  margin: 6px 0;
+  width: 100px;
+  height: 29px;
+  border-width: 1px 1px 1px 0px;
+  font-family: Helvetica;
+  font-size: 13px;
+  font-weight: bold;
+  text-align: center;
+  line-height: 29px;
+  border-style: solid;
+  border-color: #9b9b9b #9b9b9b #767676 #9b9b9b;
+  color: black;
+}
+.mblTabBarSegmentedControl .mblTabBarButton:first-child {
+  border-left-width: 1px;
+  border-top-left-radius: 5px;
+  border-bottom-left-radius: 5px;
+}
+.mblTabBarSegmentedControl .mblTabBarButton:last-child {
+  border-top-right-radius: 5px;
+  border-bottom-right-radius: 5px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonSelected {
+  color: #ffffff;
+}
+.mblHeading .mblTabBarSegmentedControl {
+  display: inline;
+  float: left;
+  height: auto;
+  border: none;
+}
+/* barType="standardTab" */
+.mblTabBarStandardTab {
+  border-top: none;
+  border-bottom: none;
+}
+.mblTabBarStandardTab .mblTabBarButton {
+  margin-top: 9px;
+  padding: 9px;
+  border: 1px solid #62676d;
+  border-top-left-radius: 4px;
+  border-top-right-radius: 4px;
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  color: black;
+  border-color: #9b9b9b;
+}
+.mblTabBarStandardTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 3px;
+  left: 0px;
+}
+.mblTabBarStandardTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="slimTab" */
+.mblTabBarSlimTab {
+  height: 30px;
+  padding: 0px;
+  border: 1px solid transparent;
+  background-color: #000000;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+}
+.mblTabBarSlimTab .mblTabBarButton {
+  padding: 7px;
+  border-right: 1px solid #4e4e4e;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#2d2d2d), to(#000000), color-stop(0.5, #141414), color-stop(0.5, #000000));
+  background-image: linear-gradient(to bottom, #2d2d2d 0%, #141414 50%, #000000 50%, #000000 100%);
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  color: white;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
+  text-align: center;
+}
+.mblTabBarSlimTab .mblTabBarButton:first-child {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+}
+.mblTabBarSlimTab .mblTabBarButtonSelected {
+  background-color: #404040;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#313031), to(#959595), color-stop(0.5, #5a555a), color-stop(0.5, #616161));
+  background-image: linear-gradient(to bottom, #313031 0%, #5a555a 50%, #616161 50%, #959595 100%);
+}
+.mblTabBarSlimTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="flatTab" */
+.mblTabBarFlatTab {
+  height: 30px;
+  padding: 0px;
+  border-style: none;
+  background-color: transparent;
+  background-image: none;
+}
+.mblTabBarFlatTab .mblTabBarButton {
+  padding: 7px;
+  background-image: none;
+  font-family: Helvetica;
+  font-size: 14px;
+  font-weight: bold;
+  text-shadow: rgba(100, 100, 100, 0.6) 0px -1px 0px;
+  text-align: center;
+}
+.mblTabBarFlatTab .mblTabBarButtonIconArea {
+  position: absolute;
+  top: 0px;
+  left: 0px;
+}
+.mblTabBarFlatTab .mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-left: 20px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab {
+  height: 64px;
+  border-top: 1px solid #cdd5df;
+  border-bottom: 2px solid #949694;
+}
+.mblTabBarTallTab .mblTabBarButton {
+  margin-top: 3px;
+  margin-right: 2px;
+  width: 78px;
+  height: 61px;
+  border-width: 0px 1px 0px 1px;
+  border-style: solid;
+  border-color: black #182018 black #393c39;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#181818), to(#100c10), color-stop(0.1, #313031));
+  background-image: linear-gradient(to bottom, #181818 0%, #313031 10%, #100c10 100%);
+  font-family: Helvetica;
+  font-size: 13px;
+  color: white;
+  text-align: center;
+}
+.mblTabBarTallTab .mblTabBarButtonIconArea {
+  margin-top: 8px;
+}
+.mblTabBarTallTab .mblTabBarButtonLabel {
+  font-family: "Helvetica Neue", Helvetica;
+  font-size: 11px;
+}
+.mblTabBarTallTab .mblTabBarButtonSelected {
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#a59ea5), to(#848284));
+  background-image: linear-gradient(to bottom, #a59ea5 0%, #848284 100%);
+}
+.mblTabBar {
+  border: none;
+  background-image: none;
+}
+.mblTabBar .mblTabBarButton {
+  text-shadow: none;
+  background-image: none;
+  border: none;
+  font-family: "Segoe WP", "Segoe UI", "HelveticaNeue", "Helvetica-Neue", "Helvetica", "BBAlpha Sans", "sans-serif";
+}
+.mblTabBarSegmentedControl {
+  min-width: 480px;
+  padding: 0px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButton {
+  color: #808080;
+  border: none;
+  font-size: 17pt;
+  font-weight: 400;
+  width: auto;
+  margin: 0 8px 0 0;
+  height: auto;
+  line-height: normal;
+  display: inline;
+  float: left;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonSelected {
+  color: #ffffff;
+}
diff --git a/dojox/mobile/themes/windows/TabBar.less b/dojox/mobile/themes/windows/TabBar.less
new file mode 100644
index 0000000..e0fda80
--- /dev/null
+++ b/dojox/mobile/themes/windows/TabBar.less
@@ -0,0 +1,37 @@
+ at import "variables.less";
+ at import "../common/TabBar.less";
+ at import "../common/domButtons/DomButtonWhiteCross.css";
+
+.mblTabBar {
+	border: none;
+	background-image: none;
+
+	.mblTabBarButton {
+		text-shadow: none;
+		background-image: none;
+		border: none;
+		font-family: @win-font-family;
+	}
+}
+
+.mblTabBarSegmentedControl {
+	min-width: 480px;
+	padding: 0px !important;
+
+	.mblTabBarButton {
+		color: @win-disabled-color;
+		border: none;
+		font-size: @win-font-size-extra-large;
+		font-weight: 400;
+		width: auto;
+		margin: 0 8px 0 0;
+		height: auto;
+		line-height: normal;
+		display: inline;
+		float: left;
+	}
+
+	.mblTabBarButtonSelected {
+		color: @win-foreground-color;
+	}
+}
diff --git a/dojox/mobile/themes/windows/TabBar_rtl-compat.css b/dojox/mobile/themes/windows/TabBar_rtl-compat.css
new file mode 100644
index 0000000..848279c
--- /dev/null
+++ b/dojox/mobile/themes/windows/TabBar_rtl-compat.css
@@ -0,0 +1,19 @@
+/* barType="segmentedControl" | "standardTab" Rtl */
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  -moz-border-radius-topright: 5px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-bottomright: 5px;
+  -moz-border-radius-bottomleft: 0px;
+}
+.dj_ff3 .mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  -moz-border-radius-topleft: 5px;
+  -moz-border-radius-topright: 0px;
+  -moz-border-radius-bottomleft: 5px;
+  -moz-border-radius-bottomright: 0px;
+}
+.dj_ff3 .mblTabBarStandardTab .mblTabBarButtonRtl {
+  -moz-border-radius-topright: 4px;
+  -moz-border-radius-topleft: 0px;
+  -moz-border-radius-topleft: 4px;
+  -moz-border-radius-topright: 0px;
+}
diff --git a/dojox/mobile/themes/windows/TabBar_rtl.css b/dojox/mobile/themes/windows/TabBar_rtl.css
new file mode 100644
index 0000000..5553209
--- /dev/null
+++ b/dojox/mobile/themes/windows/TabBar_rtl.css
@@ -0,0 +1,89 @@
+/* dojox.mobile.TabBarButton Rtl */
+.mblTabBarButtonRtl {
+  float: right;
+}
+.mblTabBarButtonIconAreaRtl {
+  margin: 0 auto;
+  width: 29px;
+}
+/* barType="tabBar" Rtl */
+.mblTabBarTabBar .mblTabBarButtonIconAreaRtl {
+  padding-top: 4px;
+}
+/* barType="segmentedControl" Rtl */
+.mblTabBarSegmentedControl.mblTabBarNoText .mblTabBarButtonIconAreaRtl {
+  position: relative;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl {
+  border-width: 1px 0px 1px 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:first-child {
+  border-right-width: 1px !important;
+  border-left-width: 0px;
+  border-top-right-radius: 5px;
+  border-top-left-radius: 0px;
+  border-bottom-right-radius: 5px;
+  border-bottom-left-radius: 0px;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonRtl:last-child {
+  border-top-left-radius: 5px;
+  border-top-right-radius: 0px;
+  border-bottom-left-radius: 5px;
+  border-bottom-right-radius: 0px;
+  border-left-width: 1px !important;
+}
+.mblTabBarSegmentedControl .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblHeading .mblTabBarSegmentedControl.mblTabBarRtl {
+  float: right;
+}
+/* barType="standardTab" Rtl */
+.mblTabBarStandardTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 3px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarStandardTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="slimTab" Rtl */
+.mblTabBarSlimTab .mblTabBarButtonRtl {
+  border-left: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl:first-child {
+  border-right: 1px solid #4e4e4e;
+}
+.mblTabBarSlimTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarSlimTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="flatTab" Rtl*/
+.mblTabBarFlatTab .mblTabBarButtonIconAreaRtl {
+  position: absolute;
+  top: 0px;
+  right: 0px;
+  left: auto;
+}
+.mblTabBarFlatTab .mblTabBarButtonRtl.mblTabBarButtonHasIcon .mblTabBarButtonLabel {
+  margin-right: 20px;
+  margin-left: 0px;
+}
+/* barType="tallTab" */
+.mblTabBarTallTab .mblTabBarButtonRtl {
+  margin-left: 2px;
+}
+.mblTabBarTallTab .mblTabBarButtonIconAreaRtl {
+  margin-top: 8px;
+}
diff --git a/dojox/mobile/themes/windows/TextArea-compat.css b/dojox/mobile/themes/windows/TextArea-compat.css
new file mode 100644
index 0000000..1c49845
--- /dev/null
+++ b/dojox/mobile/themes/windows/TextArea-compat.css
@@ -0,0 +1,21 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  overflow: auto;
+}
+.dj_ff3 .mblTextArea {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/windows/TextArea.css b/dojox/mobile/themes/windows/TextArea.css
new file mode 100644
index 0000000..9a0b3aa
--- /dev/null
+++ b/dojox/mobile/themes/windows/TextArea.css
@@ -0,0 +1,48 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.TextArea */
+.mblTextArea {
+  padding: 4px 1px;
+  border-width: 1px;
+  border-style: inset;
+  font-family: Helvetica;
+  font-size: 13px;
+  display: block;
+  background-color: #bfbfbf;
+  border: 2px solid #ffffff;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  border-radius: 0;
+  font-family: "Segoe WP", "Segoe UI", "HelveticaNeue", "Helvetica-Neue", "Helvetica", "BBAlpha Sans", "sans-serif";
+  border-color: #bfbfbf;
+  padding: 0 0 0 3px;
+  font-size: 9pt;
+  width: calc(100% - 10px);
+}
+/* dojox.mobile.ExpandingTextArea */
+.mblExpandingTextArea {
+  margin: 2px;
+}
+.mblTextArea:active,
+.mblTextArea:focus {
+  border-color: Highlight;
+  background-color: white;
+  color: black;
+}
+.mblTextArea[disabled] {
+  border-color: #808080;
+  background-color: transparent;
+  color: #808080;
+}
diff --git a/dojox/mobile/themes/windows/TextArea.less b/dojox/mobile/themes/windows/TextArea.less
new file mode 100644
index 0000000..a958fb2
--- /dev/null
+++ b/dojox/mobile/themes/windows/TextArea.less
@@ -0,0 +1,12 @@
+ at import "variables.less";
+ at import "../common/TextArea.less";
+
+.mblTextArea {
+    &:active, &:focus {
+      .mblTextInputFocused-styles;
+    }
+
+    &[disabled] {
+      .mblTextInputDisabled-styles
+    }
+}
diff --git a/dojox/mobile/themes/windows/TextBox-compat.css b/dojox/mobile/themes/windows/TextBox-compat.css
new file mode 100644
index 0000000..2a7c3bd
--- /dev/null
+++ b/dojox/mobile/themes/windows/TextBox-compat.css
@@ -0,0 +1,18 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.TextBox */
+.dj_ff3 .mblTextBox {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/windows/TextBox.css b/dojox/mobile/themes/windows/TextBox.css
new file mode 100644
index 0000000..d6b7fdb
--- /dev/null
+++ b/dojox/mobile/themes/windows/TextBox.css
@@ -0,0 +1,48 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.TextBox */
+.mblTextBox {
+  height: 22px;
+  border-width: 1px;
+  border-style: inset;
+  font-family: Helvetica;
+  font-size: 13px;
+  display: block;
+  background-color: #bfbfbf;
+  border: 2px solid #ffffff;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  border-radius: 0;
+  font-family: "Segoe WP", "Segoe UI", "HelveticaNeue", "Helvetica-Neue", "Helvetica", "BBAlpha Sans", "sans-serif";
+  border-color: #bfbfbf;
+  padding: 0 0 0 3px;
+  font-size: 9pt;
+  width: calc(100% - 10px);
+  height: 2em;
+}
+.mblTextBox:active,
+.mblTextBox:focus {
+  border-color: Highlight;
+  background-color: white;
+  color: black;
+}
+.mblTextBox[disabled] {
+  border-color: #808080;
+  background-color: transparent;
+  color: #808080;
+}
+.mblTextBox::-ms-clear {
+  display: none;
+}
diff --git a/dojox/mobile/themes/windows/TextBox.less b/dojox/mobile/themes/windows/TextBox.less
new file mode 100644
index 0000000..001cb7e
--- /dev/null
+++ b/dojox/mobile/themes/windows/TextBox.less
@@ -0,0 +1,16 @@
+ at import "variables.less";
+ at import "../common/TextBox.less";
+
+.mblTextBox {
+	&:active, &:focus {
+	  .mblTextInputFocused-styles;
+	}
+
+	&[disabled] {
+	  .mblTextInputDisabled-styles;
+	}
+
+	&::-ms-clear {
+	  display: none;
+	}
+}
diff --git a/dojox/mobile/themes/windows/TimePicker.css b/dojox/mobile/themes/windows/TimePicker.css
new file mode 100644
index 0000000..10bc87e
--- /dev/null
+++ b/dojox/mobile/themes/windows/TimePicker.css
@@ -0,0 +1,2 @@
+ at import url("SpinWheel.css");
+ at import url("ValuePicker.css");
diff --git a/dojox/mobile/themes/windows/ToggleButton-compat.css b/dojox/mobile/themes/windows/ToggleButton-compat.css
new file mode 100644
index 0000000..367a68a
--- /dev/null
+++ b/dojox/mobile/themes/windows/ToggleButton-compat.css
@@ -0,0 +1,56 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.ToggleButton */
+.mblToggleButton {
+  background-image: url(compat/button-bg.png);
+}
+.mblToggleButtonSelected {
+  background-image: url(compat/button-sel-bg.png);
+}
+.mblToggleButtonChecked {
+  background-image: url(compat/button-chk-bg.png);
+}
+.mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: url(compat/button-unsel-bg.png);
+}
+.dj_gecko .mblToggleButton {
+  background-image: none;
+}
+.dj_gecko .mblToggleButtonSelected {
+  background-image: '';
+}
+.dj_gecko .mblToggleButtonChecked {
+  background-image: none;
+}
+.dj_gecko .mblToggleButtonChecked:after {
+  -moz-transform: rotate(45deg) skew(10deg);
+  -moz-transform-origin: 50% 50%;
+}
+.dj_gecko .mblToggleButtonChecked.mblToggleButtonSelected {
+  background-image: '';
+}
+.dj_ff3 .mblToggleButton {
+  -moz-border-radius: 0;
+}
+.dj_ff3 .mblToggleButton.mblToggleButtonChecked::after {
+  -moz-transform: translate(-25px, -6px) rotate(45deg) skew(10deg);
+}
+.dj_ie .mblToggleButtonChecked:after {
+  top: 9px;
+  left: 5px;
+  width: 12px;
+  border: none;
+  background-image: url(compat/togglebutton-chk-mark-bg.png);
+}
diff --git a/dojox/mobile/themes/windows/ToggleButton.css b/dojox/mobile/themes/windows/ToggleButton.css
new file mode 100644
index 0000000..7eae6ab
--- /dev/null
+++ b/dojox/mobile/themes/windows/ToggleButton.css
@@ -0,0 +1,117 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.ToggleButton */
+.mblToggleButton {
+  position: relative;
+  padding: 0 10px 0 25px;
+  height: 29px;
+  border-width: 1px 1px 1px 1px;
+  border-style: outset;
+  font-family: Helvetica;
+  line-height: 29px;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  margin-top: 8px;
+  margin-bottom: 8px;
+  margin-left: 0px!important;
+  font-size: 8pt;
+  color: #ffffff;
+  background-color: transparent;
+  border: none;
+  overflow: visible;
+  padding: 40px 0 0 0;
+  text-align: center;
+  width: 35px;
+  height: auto;
+  line-height: normal;
+}
+.mblToggleButton:disabled {
+  border-color: grey;
+  background-image: none;
+  color: grey;
+  cursor: default;
+}
+.mblToggleButtonSelected {
+  color: white;
+}
+.mblToggleButtonChecked {
+  color: #ffffff;
+}
+.mblToggleButtonChecked:after {
+  position: absolute;
+  content: "";
+  top: 6px;
+  left: 7px;
+  width: 5px;
+  height: 10px;
+  border-width: 2px;
+  border-style: none solid solid none;
+  -webkit-transform: rotate(45deg) skew(10deg);
+  transform: rotate(45deg) skew(10deg);
+  -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+  border-color: #000000;
+  width: 6px;
+  height: 12px;
+  left: 13px;
+  top: 7px;
+  border-width: 3.5px;
+}
+.mblToggleButtonChecked.mblToggleButtonSelected {
+  color: white;
+}
+.mblToggleButtonChecked.mblToggleButtonSelected:after {
+  border-color: white;
+}
+.mblToggleButton:before {
+  content: '';
+  position: absolute;
+  width: 30px;
+  height: 30px;
+  top: 0px;
+  border: 2px solid #ffffff;
+}
+.mblToggleButton:active:not([disabled]):before {
+  background-color: Highlight;
+}
+.mblToggleButton:after {
+  position: absolute;
+  content: "";
+  border-color: #000000;
+  width: 6px;
+  height: 12px;
+  left: 13px;
+  top: 7px;
+  border-width: 3.5px;
+  border-style: none solid solid none;
+  -webkit-transform: rotate(45deg) skew(10deg);
+  transform: rotate(45deg) skew(10deg);
+  -webkit-transform-origin: 50% 50%;
+  transform-origin: 50% 50%;
+}
+.mblToggleButtonChecked:before,
+.mblToggleButtonSelected[aria-pressed='true']:before {
+  background-color: #ffffff;
+}
+.mblToggleButtonChecked:after,
+.mblToggleButtonSelected[aria-pressed='true']:after {
+  border-color: #000000 !important;
+}
+.mblToggleButton[disabled]:before {
+  border-color: #808080;
+}
+.mblToggleButton[disabled].mblToggleButtonChecked:before {
+  background-color: #808080;
+}
diff --git a/dojox/mobile/themes/windows/ToggleButton.less b/dojox/mobile/themes/windows/ToggleButton.less
new file mode 100644
index 0000000..89f8be6
--- /dev/null
+++ b/dojox/mobile/themes/windows/ToggleButton.less
@@ -0,0 +1,49 @@
+ at import "variables.less";
+ at import "../common/ToggleButton.less";
+
+.mblToggleButton {
+	&:before {
+		content: '';
+		position: absolute;
+		width: 30px;
+		height: 30px;
+		top: 0px;
+		border: 2px solid @win-foreground-color;
+	}
+
+	&:active:not([disabled]):before {
+		background-color: @win-accent-color;
+	}
+
+	&:after {
+		position: absolute;
+		content: "";
+		.mblToggleButtonChecked-after-styles;
+		border-style: none solid solid none;
+		.transform(rotate(45deg) skew(10deg));
+		.transform-origin(50% 50%);
+	}
+}
+
+.mblToggleButtonChecked,
+.mblToggleButtonSelected[aria-pressed='true'] {
+	&:before {
+		background-color: @win-foreground-color;
+	}
+
+	&:after {
+		border-color: @win-bg-color !important;
+	}
+}
+
+.mblToggleButton[disabled] {
+	&:before {
+		border-color: @win-disabled-color;
+	}
+
+	&.mblToggleButtonChecked{
+		&:before {
+			background-color: @win-disabled-color;
+		}
+	}
+}
diff --git a/dojox/mobile/themes/windows/ToggleButton_rtl.css b/dojox/mobile/themes/windows/ToggleButton_rtl.css
new file mode 100644
index 0000000..16d136f
--- /dev/null
+++ b/dojox/mobile/themes/windows/ToggleButton_rtl.css
@@ -0,0 +1,7 @@
+/* dojox.mobile.ToggleButton Rtl */
+.mblToggleButtonRtl {
+  padding: 0 25px 0 10px!important;
+}
+.mblToggleButtonRtl.mblToggleButtonChecked:after {
+  right: 7px;
+}
diff --git a/dojox/mobile/themes/windows/ToolBarButton-compat.css b/dojox/mobile/themes/windows/ToolBarButton-compat.css
new file mode 100644
index 0000000..ccee23f
--- /dev/null
+++ b/dojox/mobile/themes/windows/ToolBarButton-compat.css
@@ -0,0 +1,77 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.ToolBarButton */
+.dj_gecko .mblToolBarButtonArrow {
+  -moz-transform: scale(0.77, 1.05) rotate(45deg);
+}
+.dj_ff3 .mblToolBarButtonArrow {
+  -moz-border-radius: 1px;
+}
+.dj_ff3 .mblToolBarButtonBody {
+  -moz-border-radius: 0;
+}
+.dj_ff3 .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  -moz-border-radius-topleft: 0;
+  -moz-border-radius-bottomleft: 0;
+}
+.dj_ff3 .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 0;
+}
+.dj_ie .mblToolBarButtonLeftArrow {
+  top: 0;
+  left: -2px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonLeftArrow {
+  background-image: url(compat/arrow-button-head-sel.png);
+}
+.dj_ie .mblToolBarButtonRightArrow {
+  top: 0;
+  right: -3px;
+  width: 13px;
+  height: 31px;
+  border-style: none;
+  border-radius: 0;
+  background-image: url(compat/arrow-button-right-head.png);
+}
+.dj_ie .mblToolBarButtonSelected .mblToolBarButtonRightArrow {
+  background-image: url(compat/arrow-button-right-head-sel.png);
+}
+.dj_ie .mblToolBarButtonBody {
+  background-image: url(compat/arrow-button-bg.png);
+  background-position: left bottom;
+}
+.dj_ie .mblToolBarButtonBodySelected {
+  background-image: url(compat/arrow-button-bg-sel.png);
+}
+.dj_ie .mblToolBarButtonBody table {
+  margin: 0;
+}
+.dj_ie .mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.dj_ie .mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.dj_ie6 .mblToolBarButton .mblToolBarButtonBody {
+  background-position: left top;
+}
diff --git a/dojox/mobile/themes/windows/ToolBarButton.css b/dojox/mobile/themes/windows/ToolBarButton.css
new file mode 100644
index 0000000..56cec53
--- /dev/null
+++ b/dojox/mobile/themes/windows/ToolBarButton.css
@@ -0,0 +1,135 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.ToolBarButton */
+.mblToolBarButton {
+  display: inline-block;
+  position: relative;
+  cursor: pointer;
+  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+  margin: 6px;
+  padding: 0 10px;
+  height: 29px;
+  line-height: 29px;
+  text-align: center;
+  font-family: Helvetica;
+  font-size: 13px;
+  font-weight: bold;
+  vertical-align: middle;
+  font-family: "Segoe WP", "Segoe UI", "HelveticaNeue", "Helvetica-Neue", "Helvetica", "BBAlpha Sans", "sans-serif";
+}
+.mblToolBarButtonHasIcon,
+.mblToolBarButtonLightIcon {
+  padding: 0;
+}
+.mblHeading .mblToolBarButton {
+  float: left;
+}
+.mblHeading span.mblToolBarButtonLightIcon {
+  padding: 0;
+}
+.mblToolBarButtonHasLeftArrow {
+  padding-right: 0;
+  padding-left: 10px;
+}
+.mblToolBarButtonHasRightArrow {
+  padding-left: 0;
+  padding-right: 10px;
+}
+.mblToolBarButtonArrow {
+  position: absolute;
+  top: 5px;
+  width: 20px;
+  height: 19px;
+  border-radius: 1px;
+  -webkit-transform: scale(0.7, 1.05) rotate(45deg);
+  transform: scale(0.7, 1.05) rotate(45deg);
+  border: 1px solid #9b9b9b;
+  border-right-color: #767676;
+  border-bottom-color: #767676;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: -1px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: -1px;
+}
+.mblToolBarButtonBody {
+  display: inline-block;
+  position: relative;
+  overflow: hidden;
+  border-radius: 0;
+  border: none;
+}
+.mblToolBarButton .mblToolBarButtonBody {
+  width: 100%;
+}
+.mblToolBarButtonBody table {
+  margin: 0 auto;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonBody {
+  border-left-width: 0;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonBody {
+  border-right-width: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+.mblToolBarButtonText .mblToolBarButtonIcon {
+  padding-left: 10px;
+}
+.mblToolBarButtonText .mblToolBarButtonLabel {
+  padding-right: 10px;
+  height: 29px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonIcon {
+  padding-left: 4px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonLabel {
+  padding-right: 4px;
+}
+.mblToolBarButtonIcon > div {
+  height: 29px;
+}
+.mblToolBarButton {
+  border: 2px solid #ffffff;
+}
+.mblToolBarButtonHasLeftArrow,
+.mblToolBarButtonHasRightArrow {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+.mblToolBarButtonHasLeftArrow *,
+.mblToolBarButtonHasRightArrow * {
+  display: none;
+}
+.mblToolBarButtonHasLeftArrow:active,
+.mblToolBarButtonHasRightArrow:active {
+  background-color: Highlight;
+}
+.mblToolBarButtonHasRightArrow {
+  transform: rotate(180deg);
+}
diff --git a/dojox/mobile/themes/windows/ToolBarButton.less b/dojox/mobile/themes/windows/ToolBarButton.less
new file mode 100644
index 0000000..1e276a6
--- /dev/null
+++ b/dojox/mobile/themes/windows/ToolBarButton.less
@@ -0,0 +1,22 @@
+ at import "variables.less";
+ at import "../common/ToolBarButton.less";
+
+.mblToolBarButton{
+	border: @default-border-width solid @win-foreground-color;
+}
+
+.mblToolBarButtonHasLeftArrow,
+.mblToolBarButtonHasRightArrow {
+  .mblToolBarButtonHasArrow-styles;
+	  & * {
+		  display: none;
+	  }
+
+	  &:active {
+		  background-color: @win-accent-color;
+	  }
+}
+
+.mblToolBarButtonHasRightArrow {
+	transform:rotate(180deg);
+}
diff --git a/dojox/mobile/themes/windows/ToolBarButton_rtl.css b/dojox/mobile/themes/windows/ToolBarButton_rtl.css
new file mode 100644
index 0000000..4c54f0d
--- /dev/null
+++ b/dojox/mobile/themes/windows/ToolBarButton_rtl.css
@@ -0,0 +1,18 @@
+/* dojox.mobile.ToolBarButton Rtl */
+.mblHeading .mblToolBarButtonRtl {
+  float: right;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonIcon {
+  padding-right: 10px;
+  padding-left: 0px;
+}
+.mblToolBarButtonTextRtl .mblToolBarButtonLabel {
+  padding-left: 10px;
+  padding-right: 0px;
+}
+.mblToolBarButtonHasRightArrow .mblToolBarButtonArrow {
+  right: 1px;
+}
+.mblToolBarButtonHasLeftArrow .mblToolBarButtonArrow {
+  left: 0px;
+}
diff --git a/dojox/mobile/themes/windows/Tooltip-compat.css b/dojox/mobile/themes/windows/Tooltip-compat.css
new file mode 100644
index 0000000..8ac5550
--- /dev/null
+++ b/dojox/mobile/themes/windows/Tooltip-compat.css
@@ -0,0 +1,54 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+  background-image: none;
+}
+.dj_ff3 .mblTooltip {
+  -moz-border-radius: 3px;
+}
+.dj_ie9 .mblTooltip .mblHeading {
+  width: auto;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipArrow {
+  right: 0;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipArrow {
+  bottom: 0;
+}
+.dj_ie6 .mblTooltipBefore .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipBefore .mblTooltipInnerArrow {
+  right: -1px;
+}
+.dj_ie6 .mblTooltipAbove .mblTooltipInnerArrow,
+.dj_ie7 .mblTooltipAbove .mblTooltipInnerArrow {
+  bottom: -1px;
+}
+.dj_ie6 .mblTooltip .mblHeading,
+.dj_ie7 .mblTooltip .mblHeading {
+  padding: 0 9px 12px;
+  border-top: 1px solid transparent;
+  border-bottom: 1px solid transparent;
+  width: auto;
+  height: auto;
+  overflow: visible;
+  line-height: normal;
+}
+.dj_ie6 .mblTooltip .mblHeading .mblToolBarButton,
+.dj_ie7 .mblTooltip .mblHeading .mblToolBarButton {
+  margin: auto 6px;
+}
diff --git a/dojox/mobile/themes/windows/Tooltip.css b/dojox/mobile/themes/windows/Tooltip.css
new file mode 100644
index 0000000..0678951
--- /dev/null
+++ b/dojox/mobile/themes/windows/Tooltip.css
@@ -0,0 +1,275 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.Tooltip */
+.mblTooltip {
+  position: absolute;
+  z-index: 2000;
+  display: block;
+  margin: 0;
+  padding: 5px;
+  border-width: 1px;
+  border-style: solid;
+  opacity: .97;
+  border-color: #869cbf;
+  border-radius: 3px;
+  background-color: #dedede;
+  background-image: none;
+}
+.mblTooltipBubble {
+  overflow: visible;
+  padding: 3px;
+  background-color: #f6f6f6;
+  background-image: none;
+  color: black;
+}
+.mblTooltipBubble.mblTooltipAbove .mblTooltipInnerArrow {
+  border-bottom-color: #f6f6f6;
+}
+.mblTooltipBubble.mblTooltipBelow .mblTooltipInnerArrow {
+  border-top-color: #f6f6f6;
+}
+.mblTooltipBubble.mblTooltipAfter .mblTooltipInnerArrow {
+  border-left-color: #f6f6f6;
+}
+.mblTooltipBubble.mblTooltipBefore .mblTooltipInnerArrow {
+  border-right-color: #f6f6f6;
+}
+.mblTooltip.mblTooltipAfter {
+  margin-left: -11px;
+}
+.mblTooltip.mblTooltipBefore {
+  margin-left: 11px;
+}
+.mblTooltip.mblTooltipAbove {
+  margin-top: 11px;
+}
+.mblTooltip.mblTooltipBelow {
+  margin-top: -11px;
+}
+.mblTooltipAnchor {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  background-color: transparent;
+  line-height: 0;
+  font-size: 0;
+}
+.mblTooltipBefore .mblTooltipAnchor {
+  left: -1px;
+}
+.mblTooltipAfter .mblTooltipAnchor {
+  right: -1px;
+}
+.mblTooltipAbove .mblTooltipAnchor {
+  top: -1px;
+}
+.mblTooltipBelow .mblTooltipAnchor {
+  bottom: -1px;
+}
+.mblTooltipArrow {
+  position: absolute;
+  width: 0;
+  height: 0;
+  line-height: 0;
+  border: 11px solid transparent;
+}
+.mblTooltipBefore .mblTooltipArrow {
+  left: auto;
+  right: 1px;
+  top: 0;
+  bottom: auto;
+  border-left-width: 0;
+  border-right-color: #adadad;
+}
+.mblTooltipAfter .mblTooltipArrow {
+  left: 1px;
+  right: auto;
+  top: 0;
+  bottom: auto;
+  border-right-width: 0;
+  border-left-color: #adadad;
+}
+.mblTooltipAbove .mblTooltipArrow {
+  top: auto;
+  bottom: 1px;
+  left: auto;
+  right: auto;
+  border-top-width: 0;
+  border-bottom-color: #adadad;
+}
+.mblTooltipBelow .mblTooltipArrow {
+  top: 1px;
+  bottom: auto;
+  left: auto;
+  right: auto;
+  border-bottom-width: 0;
+  border-top-color: #adadad;
+}
+.mblTooltipInnerArrow {
+  position: absolute;
+  width: 0;
+  height: 0;
+  line-height: 0;
+  border: 10px solid transparent;
+}
+.mblTooltipBefore .mblTooltipInnerArrow {
+  right: 0;
+  top: 0;
+  border-left-width: 0;
+  border-right-color: #dedede;
+}
+.mblTooltipAfter .mblTooltipInnerArrow {
+  left: 0;
+  top: 0;
+  border-right-width: 0;
+  border-left-color: #dedede;
+}
+.mblTooltipAbove .mblTooltipInnerArrow {
+  bottom: 0;
+  left: 0;
+  border-top-width: 0;
+  border-bottom-color: #dedede;
+}
+.mblTooltipBelow .mblTooltipInnerArrow {
+  top: 0;
+  left: 0;
+  border-bottom-width: 0;
+  border-top-color: #dedede;
+}
+.mblTooltipHidden,
+.mblTooltipHidden * {
+  visibility: hidden !important;
+}
+.mblTooltipHidden {
+  top: -99999px !important;
+  left: -99999px !important;
+}
+.mblTooltip .mblHeading {
+  padding-bottom: 3px;
+  border-top: 1px solid transparent;
+  border-bottom: 1px solid transparent;
+  background-color: transparent;
+  background-image: none;
+}
+.mblOpener {
+  background-color: #1f1f1f;
+  width: calc(100% - 10px - 15px);
+  height: calc(100% - 50px);
+  border: none;
+  top: 0px !important;
+  left: 0 !important;
+  margin: 0 !important;
+  position: fixed;
+  padding: 50px 10px 0 15px;
+  opacity: 1;
+  -ms-touch-action: none;
+}
+.mblOpener .mblTooltipAnchor,
+.mblOpener .mblOpenerUnderlay {
+  display: none;
+}
+.mblOpener .mblHeading {
+  min-height: 50px;
+  position: absolute;
+  bottom: 0px;
+  text-transform: uppercase;
+  font-size: 9pt;
+  width: calc(100% - 10px - 15px);
+  z-index: 3;
+}
+.mblOpener .mblHeading .mblHeadingDivTitle {
+  text-align: left;
+  position: fixed;
+  top: 0px;
+  width: auto;
+  padding-left: 15px;
+}
+.mblOpener .mblHeading ~ .mblScrollableView {
+  height: calc(100% - 60px) !important;
+}
+.mblOpener .mblHeading .mblButton,
+.mblOpener .mblHeading .mblToolBarButton {
+  bottom: 10px;
+  border: 2px solid #ffffff;
+  position: absolute;
+  width: 100%;
+  max-width: 45%;
+  padding: 0px;
+}
+.mblOpener .mblHeading .mblButton:nth-of-type(odd),
+.mblOpener .mblHeading .mblToolBarButton:nth-of-type(odd) {
+  left: 0px;
+}
+.mblOpener .mblHeading .mblButton:nth-of-type(even),
+.mblOpener .mblHeading .mblToolBarButton:nth-of-type(even) {
+  left: auto !important;
+  right: 0px;
+}
+.mblOpener .dijitColorPalette {
+  width: calc(100% - 10px - 15px);
+  height: calc(100% - 50px);
+}
+.mblOpener .dijitColorPalette table {
+  width: 100%;
+  height: 100%;
+  padding: 0px !important;
+}
+.mblOpener .dijitColorPalette tbody {
+  width: 100%;
+  height: 100%;
+  position: absolute;
+}
+.mblOpener .dijitColorPalette tr {
+  display: -ms-flexbox;
+  -ms-flex: 1;
+  -ms-flex-align: center;
+}
+.mblOpener .dijitColorPalette td {
+  -ms-flex: 1;
+  display: inline-block;
+}
+.mblOpener .dijitColorPalette .dijitPaletteImg {
+  border: none !important;
+  padding: 2px !important;
+}
+.mblOpener .dijitColorPalette .dijitColorPaletteSwatch {
+  border-radius: 0px!important;
+  border: 2px solid transparent;
+}
+.mblOpener .dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg {
+  margin: 2px 0px !important;
+}
+.mblOpener .dijitColorPalette .dijitPaletteCellSelected .dijitColorPaletteSwatch {
+  border: 2px solid Highlight !important;
+}
+ at media screen and (orientation: landscape) {
+  .dijitColorPalette tbody {
+    display: -ms-flexbox;
+    -ms-flex-direction: column;
+  }
+}
+.mblTooltip:not(.mblOpener).mblTooltipAbove .mblSpinWheel {
+  bottom: auto;
+}
+.mblTooltip:not(.mblOpener).mblTooltipBelow .mblSpinWheel {
+  top: auto;
+}
+.mblTooltip:not(.mblOpener).mblTooltipBefore .mblSpinWheel {
+  left: 0px;
+}
+.mblTooltip:not(.mblOpener).mblTooltipAfter .mblSpinWheel {
+  left: auto;
+  right: 0px;
+}
diff --git a/dojox/mobile/themes/windows/Tooltip.less b/dojox/mobile/themes/windows/Tooltip.less
new file mode 100644
index 0000000..97fed1d
--- /dev/null
+++ b/dojox/mobile/themes/windows/Tooltip.less
@@ -0,0 +1,146 @@
+ at import "variables.less";
+ at import "../common/Tooltip.less";
+
+.mblOpener {
+	background-color: @win-dialog-color;
+	width: calc(~"100% - @{default-padding-right} - @{default-padding-left}");
+	height: calc(~'100% - 50px');
+	border: none;
+	top: 0px !important;
+	left: 0 !important;
+	margin: 0 !important;
+	position: fixed;
+	padding: 50px @default-padding-right 0 @default-padding-left;
+	opacity: 1;
+	-ms-touch-action: none;
+
+	& .mblTooltipAnchor,
+	& .mblOpenerUnderlay {
+		display: none;
+	}
+
+	& .mblHeading {
+		min-height: 50px;
+		position: absolute;
+		bottom: 0px;
+		text-transform: uppercase;
+		font-size: @win-font-size-normal;
+		width: calc(~"100% - @{default-padding-right} - @{default-padding-left}");
+		z-index:3;
+
+		& .mblHeadingDivTitle {
+			text-align: left;
+			position: fixed;
+			top: 0px;
+			width: auto;
+			padding-left: @default-padding-left;
+		}
+
+		& ~ .mblScrollableView {
+			height: calc(~"100% - 60px") !important;
+		}
+
+		& .mblButton,
+		& .mblToolBarButton {
+			bottom: 10px;
+			border: 2px solid @win-foreground-color;
+			position: absolute;
+			width: 100%;
+			max-width: 45%;
+			padding: 0px;
+			&:nth-of-type(odd) {
+				left: 0px;
+			}
+
+			&:nth-of-type(even) {
+				left: auto !important;
+				right: 0px;
+			}
+		}
+
+	}
+
+}
+
+.mblOpener .dijitColorPalette {
+	width: calc(~"100% - @{default-padding-right} - @{default-padding-left}");
+	height: calc(~'100% - 50px');
+
+	table {
+		width: 100%;
+		height: 100%;
+		padding: 0px !important;
+	}
+
+	tbody {
+		width: 100%;
+
+		height: 100%;
+		position: absolute;
+	}
+
+	tr {
+		display: -ms-flexbox;
+		-ms-flex: 1;
+		-ms-flex-align: center;
+	}
+
+	td {
+		-ms-flex:1;
+		display: inline-block;
+	}
+
+	.dijitPaletteImg {
+		border: none !important;
+		padding: 2px !important;
+	}
+
+	.dijitColorPaletteSwatch {
+		border-radius: 0px!important;
+		border: 2px solid transparent;
+	}
+
+	.dijitPaletteCellSelected {
+		.dijitPaletteImg {
+			margin: 2px 0px !important;
+		}
+		.dijitColorPaletteSwatch {
+			border: 2px solid @win-accent-color !important;
+		}
+	}
+}
+
+ at media screen and (orientation: landscape) {
+  .dijitColorPalette tbody {
+	  display: -ms-flexbox;
+	  -ms-flex-direction: column;
+  }
+
+}
+
+.mblTooltip:not(.mblOpener) {
+	&.mblTooltipAbove {
+		& .mblSpinWheel {
+			bottom: auto;
+		}
+	}
+
+	&.mblTooltipBelow {
+		& .mblSpinWheel {
+			top: auto;
+		}
+	}
+
+	&.mblTooltipBefore {
+		& .mblSpinWheel {
+			left: 0px;
+		}
+	}
+
+	&.mblTooltipAfter {
+		& .mblSpinWheel {
+			left: auto;
+			right: 0px;
+		}
+	}
+}
diff --git a/dojox/mobile/themes/windows/ValuePicker-compat.css b/dojox/mobile/themes/windows/ValuePicker-compat.css
new file mode 100644
index 0000000..02ec97e
--- /dev/null
+++ b/dojox/mobile/themes/windows/ValuePicker-compat.css
@@ -0,0 +1,33 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.ValuePicker */
+.mblValuePickerSlotButton {
+  background-image: url(compat/valuepicker-button-bg.png);
+}
+.mblValuePickerSlotButtonSelected {
+  background-color: Highlight;
+}
+.mblValuePickerSlotInputArea {
+  background-color: #f7f7f7;
+}
+.dj_gecko .mblValuePickerSlotButton {
+  background-image: none;
+}
+.dj_gecko .mblValuePickerSlotButtonSelected {
+  background-image: none;
+}
+.dj_gecko .mblValuePickerSlotInputArea {
+  background-image: none;
+}
diff --git a/dojox/mobile/themes/windows/ValuePicker.css b/dojox/mobile/themes/windows/ValuePicker.css
new file mode 100644
index 0000000..1c5baa2
--- /dev/null
+++ b/dojox/mobile/themes/windows/ValuePicker.css
@@ -0,0 +1,104 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.ValuePicker */
+.mblValuePicker {
+  height: 126px;
+}
+/* dojox.mobile.ValuePickerSlot */
+.mblValuePicker > .mblValuePickerSlot {
+  float: left;
+  margin: 0 5px;
+}
+.mblValuePickerSlotButton {
+  position: relative;
+  height: 38px;
+}
+.mblValuePickerSlotPlusButton {
+  border-top-left-radius: 5px;
+  border-top-right-radius: 5px;
+}
+.mblValuePickerSlotMinusButton {
+  border-bottom-left-radius: 5px;
+  border-bottom-right-radius: 5px;
+}
+.mblValuePickerSlotIcon {
+  top: 5px;
+  margin: 0 auto;
+}
+.mblValuePickerSlotInputArea {
+  position: relative;
+  height: 48px;
+  border-top: 1px solid #7b797b;
+  border-bottom: 1px solid #c6c3c6;
+}
+.mblValuePickerSlotInput {
+  display: block;
+  width: 90%;
+  height: 90%;
+  margin: 5% auto;
+  padding: 0;
+  text-align: center;
+  border-style: none;
+  background-color: transparent;
+  font-size: 17pt;
+}
+/* dojox.mobile.ValuePickerTimePicker */
+.mblValuePickerTimePicker > .mblToolBarButton {
+  top: 45px;
+}
+.mblValuePicker {
+  margin-top: 8px;
+  margin-bottom: 8px;
+}
+.mblValuePickerSlot {
+  border: 2px solid #ffffff;
+}
+.mblValuePickerSlot:first-child {
+  margin-left: 0px !important;
+}
+.mblValuePickerSlotInputArea {
+  border-top: 2px solid #ffffff;
+  border-bottom: 2px solid #ffffff;
+}
+.mblValuePickerSlotInput {
+  color: #ffffff;
+}
+.mblValuePickerSlotButton {
+  color: #ffffff;
+  border-radius: 0px;
+}
+.mblValuePickerSlotButton .mblValuePickerSlotIcon {
+  width: 100%;
+  height: 100%;
+  top: 0px;
+  display: -ms-flexbox;
+  -ms-flex-pack: center;
+  -ms-flex-align: center;
+}
+.mblValuePickerSlotButton .mblValuePickerSlotIcon:active {
+  background-color: Highlight;
+}
+.mblValuePickerSlotButton > div > div {
+  position: relative;
+  background-color: #ffffff;
+  left: 0px;
+  top: 0px;
+}
+.mblValuePickerSlotButton > div > div > div {
+  background-color: #ffffff;
+}
diff --git a/dojox/mobile/themes/windows/ValuePicker.less b/dojox/mobile/themes/windows/ValuePicker.less
new file mode 100644
index 0000000..c893421
--- /dev/null
+++ b/dojox/mobile/themes/windows/ValuePicker.less
@@ -0,0 +1,55 @@
+ at import url("../common/domButtons/DomButtonGrayPlus.css");
+ at import url("../common/domButtons/DomButtonGrayMinus.css");
+
+ at import "variables.less";
+ at import "../common/ValuePicker.less";
+
+.mblValuePicker {
+	.default-vertical-margin;
+}
+
+.mblValuePickerSlot {
+	border: 2px solid @win-foreground-color;
+
+	&:first-child {
+		margin-left: 0px !important;
+	}
+}
+
+.mblValuePickerSlotInputArea {
+	border-top: 2px solid @win-foreground-color;
+	border-bottom: 2px solid @win-foreground-color;
+}
+
+.mblValuePickerSlotInput {
+	color: @win-foreground-color;
+}
+
+.mblValuePickerSlotButton {
+	color: @win-foreground-color;
+	border-radius: 0px;
+
+	& .mblValuePickerSlotIcon {
+		width: 100%;
+		height: 100%;
+		top: 0px;
+		display: -ms-flexbox;
+		-ms-flex-pack: center;
+		-ms-flex-align: center;
+
+		&:active {
+			background-color: @win-accent-color;
+		}
+	}
+
+	& > div > div {
+		position: relative;
+		background-color: @win-foreground-color;
+		left: 0px;
+		top: 0px;
+
+		& > div {
+			background-color: @win-foreground-color;
+		}
+	}
+}
diff --git a/dojox/mobile/themes/windows/View.css b/dojox/mobile/themes/windows/View.css
new file mode 100644
index 0000000..08f3127
--- /dev/null
+++ b/dojox/mobile/themes/windows/View.css
@@ -0,0 +1,40 @@
+ at import url("../common/transitions/slide.css");
+
+ at import url("../common/transitions/flip.css");
+
+ at import url("../common/transitions/fade.css");
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dojox.mobile.View */
+.mblView {
+  position: relative;
+  top: 0px;
+  left: 0px;
+  width: 100%;
+  color: #ffffff;
+  padding: 0 10px 0 15px;
+  width: auto;
+}
+.mblView.mblIn {
+  position: absolute;
+}
+.mblFixedHeaderBar {
+  z-index: 1;
+}
+.mblFixedBottomBar {
+  position: absolute !important;
+  width: 100%;
+  z-index: 1;
+}
diff --git a/dojox/mobile/themes/windows/View.less b/dojox/mobile/themes/windows/View.less
new file mode 100644
index 0000000..910651f
--- /dev/null
+++ b/dojox/mobile/themes/windows/View.less
@@ -0,0 +1,6 @@
+ at import url("../common/transitions/slide.css");
+ at import url("../common/transitions/flip.css");
+ at import url("../common/transitions/fade.css");
+
+ at import "variables.less";
+ at import "../common/View.less";
diff --git a/dojox/mobile/themes/windows/base-compat.css b/dojox/mobile/themes/windows/base-compat.css
new file mode 100644
index 0000000..6689f7c
--- /dev/null
+++ b/dojox/mobile/themes/windows/base-compat.css
@@ -0,0 +1,8 @@
+ at import url("common-compat.css");
+ at import url("Heading-compat.css");
+ at import url("ToolBarButton-compat.css");
+ at import url("RoundRect-compat.css");
+ at import url("RoundRectList-compat.css");
+ at import url("ListItem-compat.css");
+ at import url("Switch-compat.css");
+ at import url("ProgressIndicator-compat.css");
diff --git a/dojox/mobile/themes/windows/base.css b/dojox/mobile/themes/windows/base.css
new file mode 100644
index 0000000..793de4a
--- /dev/null
+++ b/dojox/mobile/themes/windows/base.css
@@ -0,0 +1,13 @@
+ at import url("common.css");
+ at import url("Heading.css");
+ at import url("View.css");
+ at import url("ToolBarButton.css");
+ at import url("RoundRect.css");
+ at import url("EdgeToEdgeCategory.css");
+ at import url("RoundRectCategory.css");
+ at import url("RoundRectList.css");
+ at import url("EdgeToEdgeList.css");
+ at import url("ListItem.css");
+ at import url("ScrollablePane.css");
+ at import url("Switch.css");
+ at import url("ProgressIndicator.css");
\ No newline at end of file
diff --git a/dojox/mobile/themes/windows/common-compat.css b/dojox/mobile/themes/windows/common-compat.css
new file mode 100644
index 0000000..2465076
--- /dev/null
+++ b/dojox/mobile/themes/windows/common-compat.css
@@ -0,0 +1,32 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+.dj_gecko .mblColorBlue {
+  background-image: -moz-linear-gradient(top, #7a9de9 0%, #2362dd 100%);
+}
+.dj_gecko .mblColorBlue45 {
+  background-image: -moz-linear-gradient(top left, #7a9de9 0%, #2362dd 100%);
+}
+.dj_gecko .mblColorDefault {
+  background-image: none;
+}
+.dj_gecko .mblColorDefault45 {
+  background-image: -moz-linear-gradient(top left, #e2e2e2 0%, #a4a4a4 100%);
+}
+.dj_gecko .mblColorDefaultSel {
+  background-image: none;
+}
+.dj_gecko .mblColorDefaultSel45 {
+  background-image: -moz-linear-gradient(top left, #bbbbbb 0%, #666666 100%);
+}
diff --git a/dojox/mobile/themes/windows/common.css b/dojox/mobile/themes/windows/common.css
new file mode 100644
index 0000000..f53773d
--- /dev/null
+++ b/dojox/mobile/themes/windows/common.css
@@ -0,0 +1,93 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+html.mobile,
+.mobile body {
+  width: 100%;
+  margin: 0;
+  padding: 0;
+}
+.mobile body {
+  overflow-x: hidden;
+  -webkit-text-size-adjust: none;
+  background-color: #000000;
+  font-family: "Segoe WP", "Segoe UI", "HelveticaNeue", "Helvetica-Neue", "Helvetica", "BBAlpha Sans", "sans-serif";
+  font-size: 9pt;
+  color: #ffffff;
+  padding: 8px 0 8px 0;
+}
+.mblBackground {
+  background-color: #000000;
+}
+/* Button Colors */
+.mblColorBlue {
+  color: #ffffff;
+  background-color: #2362dd;
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#7a9de9), to(#2362dd));
+  background-image: linear-gradient(to bottom, #7a9de9 0%, #2362dd 100%);
+}
+.mblColorBlue45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#7a9de9), to(#2362dd));
+  background-image: linear-gradient(to right bottom, #7a9de9 0%, #2362dd 100%);
+}
+/* Default Button Colors */
+.mblColorDefault {
+  color: #ffffff;
+  background-color: transparent;
+  background-image: none;
+}
+.mblColorDefault45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#e2e2e2), to(#a4a4a4));
+  background-image: linear-gradient(to right bottom, #e2e2e2 0%, #a4a4a4 100%);
+}
+.mblColorDefaultSel {
+  color: #ffffff;
+  background-color: Highlight;
+}
+.mblColorDefaultSel45 {
+  background-image: -webkit-gradient(linear, left top, right bottom, from(#bbbbbb), to(#666666));
+  background-image: linear-gradient(to right bottom, #bbbbbb 0%, #666666 100%);
+}
+.mblSpriteIcon {
+  position: absolute;
+}
+.mblSpriteIconParent {
+  position: relative;
+  font-size: 1px;
+}
+.mblImageIcon {
+  vertical-align: top;
+}
+body {
+  -ms-touch-action: pan-y;
+}
+label {
+  margin-right: 5px;
+}
+ at -ms-viewport {
+  user-zoom: fixed;
+  max-zoom: 1;
+  min-zoom: 1;
+  zoom: 1;
+}
+ at media screen and (orientation: portrait) and (min-device-width: 768px) {
+  @-ms-viewport {
+    width: device-width;
+  }
+}
+ at media screen and (orientation: landscape) and (min-device-width: 1366px) {
+  @-ms-viewport {
+    width: device-width;
+  }
+}
diff --git a/dojox/mobile/themes/windows/common.less b/dojox/mobile/themes/windows/common.less
new file mode 100644
index 0000000..6409403
--- /dev/null
+++ b/dojox/mobile/themes/windows/common.less
@@ -0,0 +1,29 @@
+ at import "variables.less";
+ at import "../common/common.less";
+
+body {
+	-ms-touch-action: pan-y;
+}
+
+label {
+	margin-right: 5px;
+}
+
+ at -ms-viewport {
+	user-zoom: fixed;
+	max-zoom: 1;
+	min-zoom: 1;
+	zoom: 1;
+}
+
+ at media screen and (orientation: portrait) and (min-device-width: 768px) {
+	@-ms-viewport {
+		width: device-width;
+	}
+}
+
+ at media screen and (orientation: landscape) and (min-device-width: 1366px) {
+	@-ms-viewport {
+		width: device-width;
+	}
+}
diff --git a/dojox/mobile/themes/windows/compat/arrow-button-bg-sel.png b/dojox/mobile/themes/windows/compat/arrow-button-bg-sel.png
new file mode 100644
index 0000000..5b85b72
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/arrow-button-bg-sel.png differ
diff --git a/dojox/mobile/themes/windows/compat/arrow-button-bg.png b/dojox/mobile/themes/windows/compat/arrow-button-bg.png
new file mode 100644
index 0000000..7871ed1
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/arrow-button-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/arrow-button-head-sel.png b/dojox/mobile/themes/windows/compat/arrow-button-head-sel.png
new file mode 100644
index 0000000..f10e271
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/arrow-button-head-sel.png differ
diff --git a/dojox/mobile/themes/windows/compat/arrow-button-head.png b/dojox/mobile/themes/windows/compat/arrow-button-head.png
new file mode 100644
index 0000000..ac78b9e
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/arrow-button-head.png differ
diff --git a/dojox/mobile/themes/windows/compat/arrow-button-right-head-sel.png b/dojox/mobile/themes/windows/compat/arrow-button-right-head-sel.png
new file mode 100644
index 0000000..068c601
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/arrow-button-right-head-sel.png differ
diff --git a/dojox/mobile/themes/windows/compat/arrow-button-right-head.png b/dojox/mobile/themes/windows/compat/arrow-button-right-head.png
new file mode 100644
index 0000000..cc92700
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/arrow-button-right-head.png differ
diff --git a/dojox/mobile/themes/windows/compat/blue-button-bg.png b/dojox/mobile/themes/windows/compat/blue-button-bg.png
new file mode 100644
index 0000000..3bd558b
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/blue-button-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/blue-button-sel-bg.png b/dojox/mobile/themes/windows/compat/blue-button-sel-bg.png
new file mode 100644
index 0000000..d371d89
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/blue-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/button-arrow-head-bg.gif b/dojox/mobile/themes/windows/compat/button-arrow-head-bg.gif
new file mode 100644
index 0000000..77b6e9e
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/button-arrow-head-bg.gif differ
diff --git a/dojox/mobile/themes/windows/compat/button-bg.png b/dojox/mobile/themes/windows/compat/button-bg.png
new file mode 100644
index 0000000..0d378fa
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/button-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/button-chk-bg.png b/dojox/mobile/themes/windows/compat/button-chk-bg.png
new file mode 100644
index 0000000..4bfad06
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/button-chk-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/button-sel-bg.png b/dojox/mobile/themes/windows/compat/button-sel-bg.png
new file mode 100644
index 0000000..d371d89
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/button-sel-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/button-unsel-bg.png b/dojox/mobile/themes/windows/compat/button-unsel-bg.png
new file mode 100644
index 0000000..d371d89
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/button-unsel-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/gray-arrow.png b/dojox/mobile/themes/windows/compat/gray-arrow.png
new file mode 100644
index 0000000..c93d17f
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/gray-arrow.png differ
diff --git a/dojox/mobile/themes/windows/compat/heading-bg.png b/dojox/mobile/themes/windows/compat/heading-bg.png
new file mode 100644
index 0000000..8c3999b
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/heading-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/icon-content-heading-bg.png b/dojox/mobile/themes/windows/compat/icon-content-heading-bg.png
new file mode 100644
index 0000000..3daa1a8
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/icon-content-heading-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/red-button-bg.png b/dojox/mobile/themes/windows/compat/red-button-bg.png
new file mode 100644
index 0000000..799870f
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/red-button-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/red-button-sel-bg.png b/dojox/mobile/themes/windows/compat/red-button-sel-bg.png
new file mode 100644
index 0000000..d371d89
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/red-button-sel-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/slider-h-bar-bg.png b/dojox/mobile/themes/windows/compat/slider-h-bar-bg.png
new file mode 100644
index 0000000..970c7ff
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/slider-h-bar-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/slider-h-bg.png b/dojox/mobile/themes/windows/compat/slider-h-bg.png
new file mode 100644
index 0000000..0a08c57
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/slider-h-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/slider-handle-bg.png b/dojox/mobile/themes/windows/compat/slider-handle-bg.png
new file mode 100644
index 0000000..1988f04
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/slider-handle-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/switch-arc1-k.gif b/dojox/mobile/themes/windows/compat/switch-arc1-k.gif
new file mode 100644
index 0000000..b706766
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-arc1-k.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-arc1-l.gif b/dojox/mobile/themes/windows/compat/switch-arc1-l.gif
new file mode 100644
index 0000000..873b9a7
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-arc1-l.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-arc1-r.gif b/dojox/mobile/themes/windows/compat/switch-arc1-r.gif
new file mode 100644
index 0000000..2e70891
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-arc1-r.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-arc2-k.gif b/dojox/mobile/themes/windows/compat/switch-arc2-k.gif
new file mode 100644
index 0000000..7c74289
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-arc2-k.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-arc2-l.gif b/dojox/mobile/themes/windows/compat/switch-arc2-l.gif
new file mode 100644
index 0000000..b9e9ea6
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-arc2-l.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-arc2-r.gif b/dojox/mobile/themes/windows/compat/switch-arc2-r.gif
new file mode 100644
index 0000000..d92e181
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-arc2-r.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-round1-k.gif b/dojox/mobile/themes/windows/compat/switch-round1-k.gif
new file mode 100644
index 0000000..1bc8a14
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-round1-k.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-round1-l.gif b/dojox/mobile/themes/windows/compat/switch-round1-l.gif
new file mode 100644
index 0000000..f015cc2
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-round1-l.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-round1-r.gif b/dojox/mobile/themes/windows/compat/switch-round1-r.gif
new file mode 100644
index 0000000..f62342a
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-round1-r.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-round2-k.gif b/dojox/mobile/themes/windows/compat/switch-round2-k.gif
new file mode 100644
index 0000000..7885243
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-round2-k.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-round2-l.gif b/dojox/mobile/themes/windows/compat/switch-round2-l.gif
new file mode 100644
index 0000000..0417737
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-round2-l.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-round2-r.gif b/dojox/mobile/themes/windows/compat/switch-round2-r.gif
new file mode 100644
index 0000000..2cf1260
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-round2-r.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-square-k.gif b/dojox/mobile/themes/windows/compat/switch-square-k.gif
new file mode 100644
index 0000000..cdab63e
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-square-k.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-square-l.gif b/dojox/mobile/themes/windows/compat/switch-square-l.gif
new file mode 100644
index 0000000..e32a3dd
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-square-l.gif differ
diff --git a/dojox/mobile/themes/windows/compat/switch-square-r.gif b/dojox/mobile/themes/windows/compat/switch-square-r.gif
new file mode 100644
index 0000000..0c67709
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/switch-square-r.gif differ
diff --git a/dojox/mobile/themes/windows/compat/tab-button-bg.png b/dojox/mobile/themes/windows/compat/tab-button-bg.png
new file mode 100644
index 0000000..548ef73
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/tab-button-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/tab-orange-button-bg.png b/dojox/mobile/themes/windows/compat/tab-orange-button-bg.png
new file mode 100644
index 0000000..56f555b
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/tab-orange-button-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/tab-seg-button-bg.png b/dojox/mobile/themes/windows/compat/tab-seg-button-bg.png
new file mode 100644
index 0000000..7871ed1
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/tab-seg-button-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/tab-seg-sel-button-bg.png b/dojox/mobile/themes/windows/compat/tab-seg-sel-button-bg.png
new file mode 100644
index 0000000..7afa879
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/tab-seg-sel-button-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/tab-sel-button-bg.png b/dojox/mobile/themes/windows/compat/tab-sel-button-bg.png
new file mode 100644
index 0000000..c454088
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/tab-sel-button-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/tab-slim-bar-bg.png b/dojox/mobile/themes/windows/compat/tab-slim-bar-bg.png
new file mode 100644
index 0000000..f982afb
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/tab-slim-bar-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/tab-tall-bar-bg.png b/dojox/mobile/themes/windows/compat/tab-tall-bar-bg.png
new file mode 100644
index 0000000..50a2371
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/tab-tall-bar-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/togglebutton-chk-bg.png b/dojox/mobile/themes/windows/compat/togglebutton-chk-bg.png
new file mode 100644
index 0000000..4bfad06
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/togglebutton-chk-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/togglebutton-chk-mark-bg.png b/dojox/mobile/themes/windows/compat/togglebutton-chk-mark-bg.png
new file mode 100644
index 0000000..2262424
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/togglebutton-chk-mark-bg.png differ
diff --git a/dojox/mobile/themes/windows/compat/valuepicker-button-bg.png b/dojox/mobile/themes/windows/compat/valuepicker-button-bg.png
new file mode 100644
index 0000000..965db4b
Binary files /dev/null and b/dojox/mobile/themes/windows/compat/valuepicker-button-bg.png differ
diff --git a/dojox/mobile/themes/windows/dijit/Calendar-compat.css b/dojox/mobile/themes/windows/dijit/Calendar-compat.css
new file mode 100644
index 0000000..842264c
--- /dev/null
+++ b/dojox/mobile/themes/windows/dijit/Calendar-compat.css
@@ -0,0 +1,37 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* dijit.Calendar */
+.dijitCalendar thead {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-month-bg.png);
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-datelabel-sel-bg.png);
+}
+.dijitCalendarActiveDate .dijitCalendarDateLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-datelabel-act-bg.png);
+}
+.dijitCalendarYearLabel {
+  background-repeat: repeat-x;
+  background-image: url(compat/calendar-year-bg.png);
+}
+.dj_gecko .dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  -moz-box-shadow: 0 0 0 transparent;
+}
+.dj_ff3 .dijitCalendar {
+  -moz-border-radius: 0;
+}
diff --git a/dojox/mobile/themes/windows/dijit/Calendar-compat.less b/dojox/mobile/themes/windows/dijit/Calendar-compat.less
new file mode 100644
index 0000000..88cd6f0
--- /dev/null
+++ b/dojox/mobile/themes/windows/dijit/Calendar-compat.less
@@ -0,0 +1,2 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar-compat.less";
diff --git a/dojox/mobile/themes/windows/dijit/Calendar.css b/dojox/mobile/themes/windows/dijit/Calendar.css
new file mode 100644
index 0000000..1483467
--- /dev/null
+++ b/dojox/mobile/themes/windows/dijit/Calendar.css
@@ -0,0 +1,123 @@
+.mblToolBarButtonHasArrow-styles {
+  width: 27px;
+  height: 27px;
+  border-radius: 20px;
+  border: 2px solid #ffffff;
+  padding: 0px;
+  margin: 0px;
+  margin-top: 8px;
+  margin-bottom: 8px;
+  background-image: url("images/dark/back.png");
+  background-position: 50% 50%;
+  background-size: 27px 27px;
+  background-repeat: no-repeat;
+}
+/* if you link this style sheet, dijit/themes/dijit.css must be imported. */
+/* dijit.Calendar */
+.dijitCalendar {
+  padding: 0;
+  width: 320px;
+  border-radius: 0;
+  text-align: center;
+  border: 1px solid #c0c0c0;
+}
+.dijitCalendar thead {
+  border-color: inherit;
+  vertical-align: middle;
+}
+.dijitCalendarMonthLabel {
+  padding: 0 4px;
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0 1px 0px;
+  color: #ffffff;
+  font-size: 16px;
+}
+.dijitCalendarMonthMenu .dijitCalendarMonthLabel {
+  background-color: #f2f2f2;
+  color: black;
+}
+.dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  padding: 0 3px 0 2px;
+  border: none;
+  background-color: transparent;
+  background-image: none;
+  -webkit-box-shadow: 0 0 0 transparent;
+  box-shadow: 0 0 0 transparent;
+}
+.dijitArrowButtonInner {
+  display: none;
+}
+.dijitCalendarMonthContainer th {
+  border-right: 1px solid transparent;
+}
+.dijitCalendarIncrementControl {
+  width: 0;
+  height: 0;
+  border: 6px solid transparent !important;
+}
+.dijitCalendarDecrease {
+  border-left-width: 0 !important;
+  border-right: 6px solid #9b9b9b !important;
+}
+.dijitCalendarIncrease {
+  border-right-width: 0 !important;
+  border-left: 6px solid #9b9b9b !important;
+}
+.dijitA11ySideArrow {
+  display: none;
+}
+.dijitCalendarDayLabelTemplate {
+  border-right: 1px solid transparent;
+  text-align: center;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  background-color: #f6f6f6;
+  font-size: 12px;
+  color: #000000 !important;
+}
+.dijitCalendarDateTemplate {
+  border-bottom: 1px solid lightGrey;
+  font-family: Helvetica;
+  font-size: 22px;
+  font-weight: normal;
+  text-align: center;
+  border: none;
+  background-color: white;
+  color: black;
+}
+.dijitCalendarDateTemplate:last-child {
+  border-right: none;
+}
+.dijitCalendarDateTemplate .dijitCalendarDateLabel {
+  padding: 3px 5px 3px 4px;
+  display: block;
+  text-decoration: none;
+  border: none;
+}
+.dijitCalendarPreviousMonth .dijitCalendarDateLabel,
+.dijitCalendarNextMonth .dijitCalendarDateLabel {
+  color: lightGrey;
+}
+.dijitCalendarHoveredDate .dijitCalendarDateLabel {
+  color: grey;
+}
+.dijitCalendarSelectedDate .dijitCalendarDateLabel {
+  color: black;
+  background-color: Highlight;
+}
+.dijitCalendarYearLabel {
+  margin: 0;
+  padding: 0;
+}
+.dijitCalendarSelectedYear {
+  font-family: Helvetica;
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  color: #ffffff;
+  font-size: 16px;
+}
+.dijitCalendarNextYear,
+.dijitCalendarPreviousYear {
+  text-shadow: rgba(247, 247, 247, 0.6) 0px 1px 0px;
+  padding: 1px 6px 3px 6px;
+  color: #ffffff;
+  font-size: 12px;
+}
diff --git a/dojox/mobile/themes/windows/dijit/Calendar.less b/dojox/mobile/themes/windows/dijit/Calendar.less
new file mode 100644
index 0000000..a590903
--- /dev/null
+++ b/dojox/mobile/themes/windows/dijit/Calendar.less
@@ -0,0 +1,2 @@
+ at import "../variables.less";
+ at import "../../common/dijit/Calendar.less";
diff --git a/dojox/mobile/themes/windows/images/check-disabled.png b/dojox/mobile/themes/windows/images/check-disabled.png
new file mode 100644
index 0000000..25a538d
Binary files /dev/null and b/dojox/mobile/themes/windows/images/check-disabled.png differ
diff --git a/dojox/mobile/themes/windows/images/dark/back.png b/dojox/mobile/themes/windows/images/dark/back.png
new file mode 100644
index 0000000..a861d6f
Binary files /dev/null and b/dojox/mobile/themes/windows/images/dark/back.png differ
diff --git a/dojox/mobile/themes/windows/images/dark/check.png b/dojox/mobile/themes/windows/images/dark/check.png
new file mode 100644
index 0000000..e358a20
Binary files /dev/null and b/dojox/mobile/themes/windows/images/dark/check.png differ
diff --git a/dojox/mobile/themes/windows/images/dark/radiobtn.png b/dojox/mobile/themes/windows/images/dark/radiobtn.png
new file mode 100644
index 0000000..aa26195
Binary files /dev/null and b/dojox/mobile/themes/windows/images/dark/radiobtn.png differ
diff --git a/dojox/mobile/themes/windows/images/light/back.png b/dojox/mobile/themes/windows/images/light/back.png
new file mode 100644
index 0000000..4d8d2e9
Binary files /dev/null and b/dojox/mobile/themes/windows/images/light/back.png differ
diff --git a/dojox/mobile/themes/windows/images/light/check.png b/dojox/mobile/themes/windows/images/light/check.png
new file mode 100644
index 0000000..b4974c2
Binary files /dev/null and b/dojox/mobile/themes/windows/images/light/check.png differ
diff --git a/dojox/mobile/themes/windows/images/light/radiobtn.png b/dojox/mobile/themes/windows/images/light/radiobtn.png
new file mode 100644
index 0000000..f5bd7e5
Binary files /dev/null and b/dojox/mobile/themes/windows/images/light/radiobtn.png differ
diff --git a/dojox/mobile/themes/windows/images/radiobtn-disabled.png b/dojox/mobile/themes/windows/images/radiobtn-disabled.png
new file mode 100644
index 0000000..8c35947
Binary files /dev/null and b/dojox/mobile/themes/windows/images/radiobtn-disabled.png differ
diff --git a/dojox/mobile/themes/windows/variables.less b/dojox/mobile/themes/windows/variables.less
new file mode 100644
index 0000000..1581f0d
--- /dev/null
+++ b/dojox/mobile/themes/windows/variables.less
@@ -0,0 +1,995 @@
+ at import "../common/css3.less";
+
+ at win-theme: "dark";
+ at win-dark-theme: "dark";
+ at win-light-theme: "light";
+
+ at win-font-family: "Segoe WP", "Segoe UI", "HelveticaNeue", "Helvetica-Neue", "Helvetica", "BBAlpha Sans", "sans-serif";
+
+ at win-bg-color: black;
+ at win-contrast-bg-color: #FFFFFF;
+ at win-foreground-color: white;
+ at win-contrast-foreground-color: black;
+
+ at win-accent-color: Highlight;
+ at win-control-bg-color: transparent;
+ at win-app-bar-color: #1F1F1F;
+ at win-dialog-color: #1F1F1F;
+ at win-inactive-color: #666666;
+ at win-disabled-color: #808080;
+ at win-subtle-color: #999999;
+ at win-text-box-color: #BFBFBF;
+ at win-border-color: #CCCCCC;
+ at win-text-selection-color: black;
+ at win-focused-background-color: #FFFFFF;
+
+// Original WP font sizes
+//@win-font-size-small: 10pt;
+//@win-font-size-normal: 11pt;
+//@win-font-size-medium: 15pt;
+//@win-font-size-medium-large: 17pt;
+//@win-font-size-large: 19pt;
+//@win-font-size-extra-large: 24pt;
+//@win-font-size-huge: 29pt;
+
+// Reduced font-sizes
+ at win-font-size-small: 8pt;
+ at win-font-size-normal: 9pt;
+ at win-font-size-medium: 10pt;
+ at win-font-size-medium-large: 11pt;
+ at win-font-size-large: 15pt;
+ at win-font-size-extra-large: 17pt;
+ at win-font-size-huge: 19pt;
+
+ at imgDir: "images/@{win-theme}/";
+
+ at default-blue-button-color: white;
+ at default-blue-button-background-color: #2362dd;
+.default-blue-button-background-image () { .background-image-linear-gradient-top-bottom(#7a9de9, #2362dd); }
+ at default-blue-button-background-image-gecko: -moz-linear-gradient(top, #7a9de9 0%, #2362dd 100%);
+
+.mbl-color-blue-45 () { .background-image-linear-gradient-top-left-bottom-right(#7a9de9, #2362dd); }
+.mbl-color-default-45 () { .background-image-linear-gradient-top-left-bottom-right(#e2e2e2, #a4a4a4); }
+.mbl-color-default-sel-45 () { .background-image-linear-gradient-top-left-bottom-right(#bbbbbb, #666666); }
+
+ at mbl-color-blue-45-gecko: -moz-linear-gradient(top left, #7a9de9 0%, #2362dd 100%);
+ at mbl-color-default-45-gecko: -moz-linear-gradient(top left, #e2e2e2 0%, #a4a4a4 100%);
+ at mbl-color-default-sel-45-gecko: -moz-linear-gradient(top left, #bbbbbb 0%, #666666 100%);
+
+ at default-button-color: @win-foreground-color;
+ at default-button-background-color: @win-control-bg-color;
+.default-button-background-image () {
+  background-image: none;
+}
+ at default-button-background-image-gecko: none;
+ at default-button-border-radius: 0;
+
+ at default-button-selected-color: @win-foreground-color;
+ at default-button-selected-background-color: @win-accent-color;
+.default-button-selected-background-image () {
+}
+ at default-button-selected-background-image-gecko: none;
+
+ at default-selected-color: white;
+ at default-selected-background-color: @default-button-selected-background-color;
+.default-selected-background-image () {
+}
+ at default-selected-background-image-gecko: @default-button-selected-background-image-gecko;
+
+ at default-border-width: 2px;
+ at default-padding-left: 15px;
+ at default-padding-right: 10px;
+
+ at heading-background-color: @win-control-bg-color;
+.heading-background-image () {
+}
+ at heading-background-image-gecko: none;
+ at heading-border-top-color: transparent;
+ at heading-border-bottom-color: transparent;
+
+.default-vertical-margin (){
+	margin-top: 8px;
+	margin-bottom: 8px;
+}
+
+.mblImage(@imgUrl, @size: 32px 32px) {
+	background-image: url(@imgUrl);
+	background-position: 50% 50%;
+	background-size: @size;
+	background-repeat: no-repeat;
+}
+
+.default-button-border-styles () {
+	border: @default-border-width solid @win-foreground-color;
+	border-radius: @default-button-border-radius;
+}
+
+.mblToolBarButtonBodyInLeftArrow-styles () {
+  border-left-width: 0;
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+.mblToolBarButtonBodyInRightArrow-styles () {
+  border-right-width: 0;
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+// background styles of form controls
+.mbl-button-background-image () {
+}
+.mbl-button-selected-background-image () { .default-selected-background-image(); }
+.mbl-blue-button-background-image () { .default-blue-button-background-image(); }
+.mbl-blue-button-selected-background-image () { .default-selected-background-image(); }
+.mbl-red-button-background-image () { .background-image-linear-gradient-top-bottom(#fa9d58, #ee4115); }
+.mbl-red-button-selected-background-image () { .default-selected-background-image(); }
+.mbl-button-checked-background-image () { .mbl-button-background-image(); }
+
+// background styles of form controls (for gecko)
+ at mbl-button-background-image-gecko: none;
+ at default-selected-background-image: '';
+ at mbl-button-selected-background-image-gecko: @default-selected-background-image;
+ at mbl-blue-button-background-image-gecko: @default-blue-button-background-image-gecko;
+ at mbl-blue-button-selected-background-image-gecko: @default-selected-background-image;
+ at mbl-red-button-background-image-gecko: none;
+ at mbl-red-button-selected-background-image-gecko: @default-selected-background-image;
+ at mbl-button-checked-background-image-gecko: @mbl-button-background-image-gecko;
+
+// common.less
+.mobile-body-styles () {
+	background-color: @win-bg-color;
+	font-family: @win-font-family;
+	font-size: @win-font-size-normal;
+	color: @win-foreground-color;
+	padding: 8px 0 8px 0;
+}
+
+.mblView-styles () {
+	color: @win-foreground-color;
+	padding: 0 @default-padding-right 0 @default-padding-left;
+	width: auto;
+}
+
+.mblBackground-styles () {
+  background-color: @win-bg-color;
+}
+
+.mblColorBlue-styles () {
+	color: @default-blue-button-color;
+	background-color: @default-blue-button-background-color;
+	.default-blue-button-background-image();
+}
+.mblColorDefault-styles () {
+	color: @default-button-color;
+	background-color: @default-button-background-color;
+	.default-button-background-image();
+}
+.mblColorDefaultSel-styles () {
+	color: @default-button-selected-color;
+	background-color: @default-button-selected-background-color;
+}
+
+// Heading.less
+.mblHeading-styles () {
+	border: none;
+	color: @win-foreground-color;
+	font-family: @win-font-family;
+	font-weight: 400;
+	text-align: left;
+	font-size: @win-font-size-extra-large;
+	overflow: visible;
+}
+
+// ToolBarButton.less
+
+ at mbl-tool-bar-button-size: 27px;
+
+ at imgBackBtnUrl: "@{imgDir}back.png";
+
+ at mbl-tool-bar-button-body-border-radius: 0;
+//
+.mblToolBarButton-styles () {
+  font-family: @win-font-family;
+}
+.mblToolBarButtonArrow-styles () {
+	border-radius: 1px;
+	.transform(scale(0.7, 1.05) rotate(45deg));
+	border: 1px solid #9b9b9b;
+	border-right-color: #767676;
+	border-bottom-color: #767676;
+}
+
+.mblToolBarButtonHasArrow-styles{
+	width: @mbl-tool-bar-button-size;
+	height: @mbl-tool-bar-button-size;
+	border-radius: 20px;
+	border: @default-border-width solid @win-foreground-color;
+	padding: 0px;
+	margin: 0px;
+	.default-vertical-margin;
+	.mblImage(@imgBackBtnUrl, @mbl-tool-bar-button-size @mbl-tool-bar-button-size);
+}
+
+.mblToolBarButtonArrowInHeading-styles () {
+}
+.mblToolBarButtonHasLeftArrowInHeading-styles () {
+}
+.mblToolBarButtonHasLeftArrowInHeading-compat-gecko () {
+}
+.mblToolBarButtonHasRightArrowInHeading-styles () {
+}
+.mblToolBarButtonHasRightArrowInHeading-compat-gecko () {
+}
+.mblToolBarButtonArrowInLeftArrow-styles () {
+  left: -1px;
+}
+.mblToolBarButtonArrowInRightArrow-styles () {
+  right: -1px;
+}
+.mblToolBarButtonBody-styles () {
+	border: none;
+}
+.mblToolBarButtonBodyInHeading-styles () {
+}
+.mblToolBarButtonBodyInHeading-compat-gecko () {
+}
+
+// RoundRect.less & RoundRectList.less
+ at mbl-round-rect-border-color: #cccccc;
+ at mbl-round-rect-border-radius: 8px;
+ at mbl-round-rect-background-color: #ffffff;
+ at mbl-round-rect-box-shadow: none;
+//
+.mblRoundRect-styles () {
+	border: none;
+	background-color: @win-control-bg-color;
+	border-radius: 0px;
+	margin: 0px;
+	padding: 0px;
+}
+
+// EdgeToEdgeCategory.less
+
+ at mbl-list-item-height: 43px;
+
+ at mblEdgeToEdgeCategoryPadding: 5px;
+
+ at mbl-list-item-width: @mbl-list-item-height - @mblEdgeToEdgeCategoryPadding;
+
+.mblEdgeToEdgeCategory-styles () {
+	display: inline-block;
+	padding: 0 0 0 @mblEdgeToEdgeCategoryPadding;
+	font-size: @win-font-size-large;
+	font-family: @win-font-family;
+	font-weight: 200;
+	line-height: 2;
+	height: @mbl-list-item-height;
+	width: @mbl-list-item-width;
+	background-color: @win-accent-color;
+	border: none;
+	color: @win-foreground-color;
+	text-transform: lowercase;
+	overflow: visible;
+}
+
+// RoundRectCategory.less
+.mblRoundRectCategory-styles () {
+	color: @win-foreground-color;
+	margin: 0px;
+}
+
+// EdgeToEdgeList.less
+.mblEdgeToEdgeList-styles () {
+	background-color: @win-control-bg-color;
+	padding: 0px;
+}
+.mblEdgeToEdgeList-LastListItem-styles () {
+	border-bottom-color: #bfbfbf;
+}
+
+// ListItem.less
+
+.mblListItem-styles () {
+	border: none;
+	background-color: @win-control-bg-color;
+	color: @win-foreground-color;
+	font-size: @win-font-size-large;
+	padding: 0;
+}
+.mblListItemSelected-styles () {
+	color: @win-accent-color;
+}
+.mblListItemLabelSelected-styles () {
+	background-color: #048bf4;
+}
+.mblListItemChecked-styles () {
+	color: #314e84;
+}
+.mblListItemRightText-styles () {
+	color: black;
+	margin-top: 12px;
+}
+.mblListItemSubText-styles () {
+	font-size: 14px;
+	color: gray;
+}
+
+// Switch.less
+ at mbl-switch-bg-left-background-color: @win-accent-color;
+.mbl-switch-bg-left-background-image () {
+}
+ at mbl-switch-bg-right-background-color: #e2e2e2;
+.mbl-switch-bg-right-background-image () { .mbl-button-background-image(); }
+.mbl-switch-knob-background-image () {  }
+//
+ at mbl-switch-bg-left-background-image-gecko: @default-button-selected-background-image-gecko;
+ at mbl-switch-bg-right-background-image-gecko: @mbl-button-background-image-gecko;
+ at mbl-switch-knob-background-image-gecko: @default-button-background-image-gecko;
+ at mbl-switch-square-border-radius: 2px;
+//
+.mblSwitchBg-styles () {
+	border: none;
+}
+.mblSwitchKnob-styles () {
+	border: @default-border-width solid @win-bg-color;
+	background-color: @win-contrast-bg-color;
+	width: 18px !important;
+	z-index: 3;
+	border-radius: 0 !important;
+}
+
+// Button.less
+.mblButton-styles () {
+	.default-button-border-styles;
+	.default-vertical-margin;
+	color: @default-button-color;
+	background-color: @default-button-background-color;
+	font-size: @win-font-size-normal;
+	font-family: @win-font-family;
+	.default-button-background-image();
+	line-height: 0;
+	text-transform: lowercase;
+	-ms-user-select: none;
+	height: 32px;
+	padding-bottom: 3px;
+	text-decoration: none;
+}
+.mblButtonSelected-styles () {
+	color: @win-foreground-color;
+	background-color: @default-button-selected-background-color;
+}
+.mblButton-mblBlueButton-styles () {
+	color: white;
+}
+.mblButton-mblRedButton-styles () {
+	color: white;
+}
+
+// CheckBox.less
+ at imgCheckUrl: "@{imgDir}check.png";
+ at imgRadioBtnUrl: "@{imgDir}radiobtn.png";
+
+.mblCheckBox-styles () {
+	.default-button-border-styles;
+	.mblCheckboxRadio-styles;
+}
+
+.mblCheckboxRadio-styles () {
+	opacity: 0;
+	margin: 0;
+	.default-vertical-margin;
+	transform: none;
+	z-index: 1;
+}
+
+.mblCheckBoxChecked-after-styles () {
+	border-color: black;
+}
+
+.mblCheckBoxChecked-mblCheckBoxSelected-after-styles () {
+	border-color: white;
+}
+
+.mblCheckRadioLabel () {
+	color: @win-foreground-color;
+	margin: 0 5px 0 5px;
+	.default-vertical-margin;
+	-ms-user-select: none;
+	display: inline-block;
+}
+
+.mblCheckRadioBorder (@radius : 0) {
+	content: '';
+	width: 20px;
+	height: 20px;
+	position: absolute;
+	border: @default-border-width solid @win-contrast-bg-color;
+	background-color: transparent;
+	margin-left: -25px;
+	z-index: 0;
+	border-radius: @radius;
+	.default-vertical-margin;
+}
+
+// ComboBox.less
+ at mbl-combo-box-popup-box-shadow: none;
+ at mbl-combo-box-padding-top: 50px;
+ at mbl-combo-box-title-top: 20px;
+//
+.dijitPopup-styles () {
+	border-radius: 0;
+	box-shadow: none;
+}
+
+.mblComboBoxMenu-styles () {
+	border: none;
+	border-radius: 0;
+	background-color: @win-dialog-color;
+	color: @win-foreground-color;
+	width: 100% !important;
+	height: calc(~'100% - @{mbl-combo-box-title-top}') !important;
+}
+
+.mblComboBoxMenuItem-styles () {
+	border: none;
+	color: inherit;
+	font-size: @win-font-size-large;
+	line-height: 1.4;
+	padding-left: @default-padding-left;
+	-ms-user-select: none;
+	text-overflow: ellipsis;
+	overflow: hidden;
+	white-space: nowrap;
+}
+
+.mblComboBoxMenuItemSelected-styles () {
+	color: @win-accent-color;
+}
+
+// IconContainer.less
+.mblIconItemSub-styles () {
+	background-color: white;
+	color: black;
+}
+.mblIconArea-styles () {
+	margin-top: 5px;
+	margin-bottom: 5px;
+	width: 74px;
+	color: @win-foreground-color;
+}
+.mblIconItemDeleteIcon-styles () {
+	top: -4px;
+	left: -2px;
+}
+
+// RadioButton.less
+.mblRadioButton-styles () {
+	.mblCheckboxRadio-styles;
+}
+.mblRadioButtonChecked-after-styles () {
+	border-color: black;
+}
+.mblRadioButtonChecked-Selected-after-styles () {
+	border-color: white;
+}
+
+// Slider.less
+ at mbl-slider-bar-border-radius: 0;
+ at mbl-slider-knob-border-radius: 0;
+
+ at mbl-slider-handle-height: 1.1em;
+ at mbl-slider-handle-width: 0.5em;
+ at mbl-slider-height: 0.5em;
+
+.mblSlider-size(@width, @height) {
+	width: @width !important;
+	height: @height !important;
+}
+
+.mblSlider-styles () {
+	border: none;
+	.default-vertical-margin;
+	margin-left: 0px;
+	margin-right: 0px;
+}
+
+.mblSliderHandle-markup (@orientation) when (@orientation = "V"){
+	.mbl-markup(-4px, -8px, @mbl-slider-handle-width, @mbl-slider-handle-height);
+}
+
+.mblSliderHandle-markup (@orientation) when (@orientation = "H"){
+	.mbl-markup(-8px, -4px, @mbl-slider-handle-height, @mbl-slider-handle-width);
+}
+
+.mbl-markup (@mtop, @mleft, @heigth, @width) {
+	height: @heigth;
+	width: @width;
+	margin-top: @mtop;
+	margin-left: @mleft;
+}
+
+.mblSliderHandle-styles () {
+	border: none;
+	background-color: @win-foreground-color;
+}
+
+// TabBar.less
+.mblTabBar-styles () {
+	padding: 0px;
+}
+
+// barType="tabBar"
+.mblTabBarTabBar-styles () {
+}
+.mblTabBarTabBar-compat () {
+	background-color: #000000;
+}
+.mblTabBarTabBarButton-styles () {
+  font-family: @win-font-family;
+}
+.mblTabBarTabBarButtonIconArea-styles () {
+}
+.mblTabBarTabBarButtonLabel-styles () {
+	color: white;
+	font-family: @win-font-family;
+}
+.mblTabBarTabBarButtonSelected-styles () {
+	background-color: #404040;
+}
+.mblTabBarTabBarButtonLabelSelected-styles () {
+	color: white;
+}
+
+// barType="segmentedControl"
+ at mbl-tab-bar-segmented-control-border-radius: 5px;
+//
+.mblTabBarSegmentedControl-styles () {
+}
+.mblTabBarSegmentedControlButton-styles () {
+	border-style: solid;
+	border-color: #9b9b9b #9b9b9b #767676 #9b9b9b;
+	color: black;
+}
+.mblTabBarSegmentedControlButton-compat-gecko () {
+}
+.mblTabBarSegmentedControlButtonSelected-styles () {
+	color: @default-button-color;
+}
+
+// barType="standardTab"
+.mblTabBarStandardTab-styles () {
+	border-top: none;
+	border-bottom: none;
+}
+.mblTabBarStandardTabButton-styles () {
+	color: black;
+	border-color: #9b9b9b;
+}
+.mblTabBarStandardTabButtonIconArea-styles () {
+}
+.mblTabBarStandardTabButtonLabel-styles () {
+}
+.mblTabBarStandardTabButtonSelected-styles () {
+}
+.mblTabBarStandardTabButtonLabelSelected-styles () {
+}
+
+// barType="tallTab"
+.mblTabBarTallTab-styles () {
+}
+.mblTabBarTallTabButton-styles () {
+}
+.mblTabBarTallTabButton-FirstChild-styles () {
+}
+.mblTabBarTallTabButton-LastChild-styles () {
+}
+.mblTabBarTallTabButtonIconArea-styles () {
+}
+.mblTabBarTallTabButtonLabel-styles () {
+}
+.mblTabBarTallTabButtonSelected-styles () {
+}
+.mblTabBarTallTabButtonLabelSelected-styles () {
+}
+
+// Text input
+
+ at win-text-input-height: 2em;
+
+.mblTextInput-styles() {
+	display: block;
+	background-color: @win-text-box-color;
+	.default-button-border-styles;
+	.default-vertical-margin;
+	border-radius: 0;
+	font-family: @win-font-family;
+	border-color: @win-text-box-color;
+	padding: 0 0 0 3px;
+	font-size: @win-font-size-normal;
+	width: calc(~"100% - @{default-padding-right}");
+}
+
+.mblTextInputFocused-styles() {
+	border-color: @win-accent-color;
+	background-color: white;
+	color: black;
+}
+
+.mblTextInputDisabled-styles() {
+	border-color: @win-disabled-color;
+	background-color: transparent;
+	color: @win-disabled-color;
+}
+
+// TextArea.less
+.mblTextArea-styles () {
+	.mblTextInput-styles;
+}
+
+// TextBox.less
+.mblTextBox-styles () {
+	.mblTextInput-styles;
+	height: @win-text-input-height;
+}
+
+// ToggleButton.less
+.mblToggleButton-styles () {
+	.default-vertical-margin;
+	margin-left: 0px!important;
+	font-size: 8pt;
+	color: @win-foreground-color;
+	background-color: @win-control-bg-color;
+	border: none;
+	overflow: visible;
+	padding: 40px 0 0 0;
+	text-align: center;
+	width: 35px;
+	height: auto;
+	line-height: normal;
+}
+.mblToggleButtonSelected-styles () {
+	color: white;
+}
+.mblToggleButtonChecked-styles () {
+	color: @win-foreground-color;
+}
+.mblToggleButtonChecked-after-styles () {
+	border-color: @win-bg-color;
+	width: 6px;
+	height: 12px;
+	left: 13px;
+	top: 7px;
+	border-width: 3.5px;
+}
+.mblToggleButtonCheckedSelected-styles () {
+	color: white;
+}
+.mblToggleButtonCheckedSelected-after-styles () {
+	border-color: white;
+}
+
+// Overlay.less
+.mblOverlay-styles () {
+	position: fixed !important;
+	top: 0px !important;
+	background-color: @win-dialog-color;
+	background-image: none;
+	padding: 12px @default-padding-right 12px @default-padding-left;
+	width: calc(~"100% - @{default-padding-left}") ;
+}
+.mblOverlay-compat () {
+}
+.mblOverlay-compat-gecko () {
+}
+
+// Tooltip.less
+ at mbl-tooltip-border-radius: 3px;
+//
+.mblTooltip-styles () {
+	border-color: #869cbf;
+	border-radius: @mbl-tooltip-border-radius;
+	background-color: #dedede;
+	background-image: none;
+}
+.mblTooltipBubble-styles () {
+	background-color: #f6f6f6;
+	background-image: none;
+	color: black;
+}
+.mblTooltipInnerArrow-Bubble-Above-styles () {
+	border-bottom-color: #f6f6f6;
+}
+.mblTooltipInnerArrow-Bubble-Below-styles () {
+	border-top-color: #f6f6f6;
+}
+.mblTooltipInnerArrow-Bubble-After-styles () {
+	border-left-color: #f6f6f6;
+}
+.mblTooltipInnerArrow-Bubble-Before-styles () {
+	border-right-color: #f6f6f6;
+}
+.mblTooltipArrow-Before-styles () {
+	border-left-width: 0;
+	border-right-color: #adadad;
+}
+.mblTooltipArrow-After-styles () {
+	border-right-width: 0;
+	border-left-color: #adadad;
+}
+.mblTooltipArrow-Above-styles () {
+	border-top-width: 0;
+	border-bottom-color: #adadad;
+}
+.mblTooltipArrow-Below-styles () {
+	border-bottom-width: 0;
+	border-top-color: #adadad;
+}
+.mblTooltipInnerArrow-Before-styles () {
+	border-left-width: 0;
+	border-right-color: #dedede;
+}
+.mblTooltipInnerArrow-After-styles () {
+	border-right-width: 0;
+	border-left-color: #dedede;
+}
+.mblTooltipInnerArrow-Above-styles () {
+	border-top-width: 0;
+	border-bottom-color: #dedede;
+}
+.mblTooltipInnerArrow-Below-styles () {
+	border-bottom-width: 0;
+	border-top-color: #dedede;
+}
+.mblTooltip-Heading-styles () {
+	padding-bottom: 3px;
+	border-top: 1px solid transparent;
+	border-bottom: 1px solid transparent;
+	background-color: transparent;
+	background-image: none;
+}
+.mblTooltip-Heading-compat () {
+}
+.mblTooltip-Heading-ToolbarButton-styles () {
+}
+.mblTooltip-Heading-ToolbarButton-compat () {
+}
+
+// Accordion.less
+.mblAccordion-styles () {
+	border: none;
+}
+.mblAccordionTitle-styles () {
+	border: none;
+	background-color: @win-control-bg-color;
+	background-image: none;
+	font-weight: normal;
+	color: @win-foreground-color;
+	font-size: @win-font-size-large;
+	.default-vertical-margin;
+}
+.mblAccordionTitle-compat () {
+}
+.mblAccordionTitle-compat-gecko () {
+}
+.mblAccordionTitleSelected-styles () {
+	border: none;
+}
+.mblAccordionTitleSelected-compat () {
+	background-color: #e2e2e2;
+}
+.mblAccordionTitleSelected-compat-gecko () {
+}
+.mblAccordionTitleAnchor-styles () {
+	color: @win-foreground-color;
+}
+.mblAccordionTitleAnchorSelected-styles () {
+}
+
+// SimpleDialog.less
+ at mbl-simple-dialog-border-radius: 0;
+//
+.mblSimpleDialog-styles () {
+	background-color: @win-dialog-color;
+	padding: 0 @default-padding-right 12px @default-padding-left;
+	width: calc(~"100% - @{default-padding-left} - @{default-padding-right}");
+	margin: 0;
+	text-align: left;
+	left: 0px !important;
+
+}
+.mblSimpleDialogDecoration-styles () {
+	background-color: @win-dialog-color;
+	color: @win-foreground-color;
+}
+.mblSimpleDialogDecoration-compat () {
+}
+.mblSimpleDialogDecoration-compat-gecko () {
+}
+.mblSimpleDialogTitle-styles () {
+	margin: 12px 0;
+	padding: 0;
+	width: auto;
+	font-size: @win-font-size-medium-large;
+	font-weight: 400;
+	text-align: left;
+}
+.mblSimpleDialogText-styles () {
+	margin: 12px 0;
+	width: auto;
+	text-align: left;
+}
+
+// IconMenu.less
+ at mbl-icon-menu-border-radius: 3px;
+ at mbl-icon-menu-item-border-radius: 3px;
+//
+.mblIconMenu-styles () {
+	padding: 0;
+	background-color: rgba(160, 160, 160, 0.85);
+	border: 1px solid #869cbf;
+	margin: 0px;
+}
+.mblIconMenu-compat () {
+	background-color: #a0a0a0;
+}
+.mblIconMenu-compat-gecko () {
+	background-color: rgba(160, 160, 160, 0.85);
+}
+.mblIconMenuItem-styles () {
+	border-left: 1px solid rgba(192, 192, 192, 0.85);
+	border-bottom: 1px solid rgba(192, 192, 192, 0.85);
+}
+.mblIconMenuItemAnchor-styles () {
+	font-size: @win-font-size-medium;
+	color: @win-foreground-color;
+}
+.mblIconMenuItemSel-styles () {
+	background-color: @win-accent-color;
+}
+.mblIconMenuItemSel-compat () {
+	background-color: @default-selected-background-color;
+}
+.mblIconMenuItemSel-compat-gecko () {
+}
+
+// dijit.Calendar
+.dijitCalendar-styles () {
+	border: 1px solid #c0c0c0;
+}
+.dijitCalendar-thead-styles () {
+}
+.dijitCalendar-thead-compat () {
+	background-image: url(compat/calendar-month-bg.png);
+}
+.dijitCalendar-thead-compat-gecko () {
+}
+.dijitCalendarMonthLabel-styles () {
+	color: @win-foreground-color;
+	font-size: 16px;
+}
+.dijitCalendarMonthMenu-styles () {
+}
+.dijitCalendarMonthMenu-compat-ff3 () {
+}
+.dijitCalendarMonthMenu-Label-styles () {
+	background-color: #f2f2f2;
+	color: black;
+}
+.dijitCalendarDecrease-styles () {
+	border-right: 6px solid #9b9b9b !important;
+}
+.dijitCalendarIncrease-styles () {
+	border-left: 6px solid #9b9b9b !important;
+}
+.dijitCalendarDayLabelTemplate-styles () {
+	background-color: #f6f6f6;
+	font-size: 12px;
+	color: @win-bg-color !important;
+}
+.dijitCalendarDateTemplate-styles () {
+	border: none;
+	background-color: white;
+	color: black;
+}
+.dijitCalendarDateTemplate-LastChild-styles () {
+	border-right: none;
+}
+.dijitCalendarDateLabel-DateTemplate-styles () {
+	border: none;
+}
+.dijitCalendarDateLabel-PrevMonth-styles () {
+	color: lightGrey;
+}
+.dijitCalendarDateLabel-Hovered-styles () {
+	color: grey;
+}
+.dijitCalendarDateLabel-Selected-styles () {
+	color: black;
+	background-color: @win-accent-color;
+}
+.dijitCalendarDateLabel-Selected-compat () {
+	background-image: url(compat/calendar-datelabel-sel-bg.png);
+}
+.dijitCalendarDateLabel-Selected-compat-gecko () {
+}
+.dijitCalendarDateLabel-Active-styles () {
+}
+.dijitCalendarDateLabel-Active-compat () {
+	background-image: url(compat/calendar-datelabel-act-bg.png);
+}
+.dijitCalendarDateLabel-Active-compat-gecko () {
+}
+.dijitCalendarYearLabel-styles () {
+	padding: 0;
+}
+.dijitCalendarYearLabel-compat () {
+	background-image: url(compat/calendar-year-bg.png);
+}
+.dijitCalendarYearLabel-compat-gecko () {
+}
+.dijitCalendarSelectedYear-styles () {
+	color: @win-foreground-color;
+	font-size: 16px;
+}
+.dijitCalendarNextYear-styles () {
+	padding: 1px 6px 3px 6px;
+	color: @win-foreground-color;
+	font-size: 12px;
+}
+
+// SearchBox.less
+ at mbl-searchbox-cancel-button-color: white;
+ at mbl-searchbox-cancel-button-bg-color: #bbc4d0;
+.mblSearchBox-Cancel-Button-styles () {
+	border-radius: 1em;
+}
+ at mbl-searchbox-results-decoration-color: #bbc4d0;
+
+// ProgressBar.less
+
+ at mbl-progressBar-height : 3px;
+
+.mblProgressBar-styles () {
+	height: @mbl-progressBar-height;
+	background-color: @win-control-bg-color;
+	border: none;
+	.default-vertical-margin;
+}
+.mblProgressBarProgress-styles () {
+	height: @mbl-progressBar-height;
+	border: none;
+	background-color: @win-accent-color;
+}
+.mblProgressBarComplete-styles () {
+}
+.mblProgressBarNotStarted-styles () {
+}
+.mblProgressBarMsg-styles () {
+	top: 3px;
+}
+.mblProgressBar-compat () {
+}
+.mblProgressBarProgress-compat () {
+	background-color: @win-accent-color;
+}
+.mblProgressBar-compat-gecko () {
+}
+.mblProgressBarProgress-compat-gecko () {
+	background-image: none;
+}
+
+// ValuePicker.less
+.mbl-value-picker-slot-button-background-image () {
+}
+ at mbl-value-picker-slot-button-background-image-gecko: none;
+ at mbl-value-picker-slot-button-radius: 5px;
+.mbl-value-picker-slot-input-area-background-image () {
+}
+ at mbl-value-picker-slot-input-area-background-image-gecko: none;
+.mblValuePickerSlot-style () {
+  margin:  0 5px;
+}
+.mblValuePickerSlot-input-style () {
+  font-size: @win-font-size-extra-large;
+}
diff --git a/dojox/mobile/themes/windows/variables_rtl.less b/dojox/mobile/themes/windows/variables_rtl.less
new file mode 100644
index 0000000..e58a4ae
--- /dev/null
+++ b/dojox/mobile/themes/windows/variables_rtl.less
@@ -0,0 +1,33 @@
+
+// Carousel_rtl
+ at mbl-carousel-margin-rtl: ~"2px 4px 2px 0px";
+
+// IconContainer_rtl
+ at mbl-icon-container-right-rtl: -2px;
+
+// IconMenu_rtl-compat
+ at mbl-border-radius-rtl: 3px;
+
+// TabBar_rtl-compat
+ at mbl-moz-border-radius-rtl: 5px;
+
+// TabBar_rtl
+ at mbl-border-width-rtl: ~"1px 0px 1px 1px !important";
+ at mbl-tb-border-radius-rtl: 5px;
+
+// ThemeID
+ at theme-id: custom;
+
+// Switch_rtl-compat
+ at mbl-bg-image-r-rtl: ~"url(compat/switch-square-r.gif)";
+ at mbl-bg-image-l-rtl: ~"url(compat/switch-square-l.gif)";
+
+// Switch_rtl
+ at mbl-switchOn-left-rtl: -53px;
+ at mbl-switchBg-left-rtl: 53px;
+ at mbl-switch-knob-rtl: 53px;
+ at mbl-switch-text-right-rtl: 40px;
+
+// ToolBarButton_rtl
+ at mbl-toolbar-right-arrow-rtl: 1px;
+ at mbl-toolbar-left-arrow-rtl: 0px;
diff --git a/dojox/mobile/themes/windows/windows-compat.css b/dojox/mobile/themes/windows/windows-compat.css
new file mode 100644
index 0000000..7fcf52b
--- /dev/null
+++ b/dojox/mobile/themes/windows/windows-compat.css
@@ -0,0 +1,23 @@
+ at import url("base-compat.css");
+
+/* common styles */
+ at import url("../common/domButtons-compat.css");
+
+/* widget styles */
+ at import url("Accordion-compat.css");
+ at import url("Button-compat.css");
+ at import url("CheckBox-compat.css");
+ at import url("ComboBox-compat.css");
+ at import url("IconContainer-compat.css");
+ at import url("IconMenu-compat.css");
+ at import url("Opener-compat.css");
+ at import url("PageIndicator-compat.css");
+ at import url("RadioButton-compat.css");
+ at import url("SimpleDialog-compat.css");
+ at import url("Slider-compat.css");
+ at import url("SpinWheel-compat.css");
+ at import url("TabBar-compat.css");
+ at import url("TextArea-compat.css");
+ at import url("TextBox-compat.css");
+ at import url("ToggleButton-compat.css");
+ at import url("ValuePicker-compat.css");
diff --git a/dojox/mobile/themes/windows/windows.css b/dojox/mobile/themes/windows/windows.css
new file mode 100644
index 0000000..5993599
--- /dev/null
+++ b/dojox/mobile/themes/windows/windows.css
@@ -0,0 +1,31 @@
+ at import url("base.css");
+
+/* common styles */
+ at import url("../common/domButtons.css");
+ at import url("../common/transitions.css");
+
+/* widget styles */
+ at import url("Accordion.css");
+ at import url("Button.css");
+ at import url("Carousel.css");
+ at import url("CheckBox.css");
+ at import url("ComboBox.css");
+ at import url("FixedSplitter.css");
+ at import url("GridLayout.css");
+ at import url("IconContainer.css");
+ at import url("IconMenu.css");
+ at import url("Opener.css");
+ at import url("PageIndicator.css");
+ at import url("ProgressBar.css");
+ at import url("ProgressIndicator.css");
+ at import url("RadioButton.css");
+ at import url("ScrollablePane.css");
+ at import url("SimpleDialog.css");
+ at import url("Slider.css");
+ at import url("SpinWheel.css");
+ at import url("TabBar.css");
+ at import url("TextArea.css");
+ at import url("SearchBox.css");
+ at import url("ToggleButton.css");
+ at import url("ValuePicker.css");
+ at import url("FormLayout.css");
diff --git a/dojox/mobile/transition.js b/dojox/mobile/transition.js
index aed509d..b6d308c 100644
--- a/dojox/mobile/transition.js
+++ b/dojox/mobile/transition.js
@@ -2,11 +2,15 @@ define([
 	"dojo/_base/Deferred",
 	"dojo/_base/config"
 ], function(Deferred, config){
-	/* summary: this is the wrapper module which load
-	 * dojox/css3/transit conditionally. If mblCSS3Transition
-	 * is set to 'dojox/css3/transit', it will be loaded as
-	 * the module to conduct the view transition.
-	 */
+	/*=====
+	return {
+		// summary:
+		//		This is the wrapper module which loads
+		//		dojox/css3/transit conditionally. If mblCSS3Transition
+		//		is set to 'dojox/css3/transit', it will be loaded as
+		//		the module to conduct view transitions, otherwise this module returns null.
+	};
+	=====*/
 	if(config['mblCSS3Transition']){
 		//require dojox/css3/transit and resolve it as the result of transitDeferred.
 		var transitDeferred = new Deferred();
diff --git a/dojox/mobile/uacss.js b/dojox/mobile/uacss.js
index d5d3b01..1b662a7 100644
--- a/dojox/mobile/uacss.js
+++ b/dojox/mobile/uacss.js
@@ -2,14 +2,32 @@ define([
 	"dojo/_base/kernel",
 	"dojo/_base/lang",
 	"dojo/_base/window",
-	"dojox/mobile/sniff"
+	"./sniff"
 ], function(dojo, lang, win, has){
-	win.doc.documentElement.className += lang.trim([
+	var html = win.doc.documentElement;
+	html.className = lang.trim(html.className + " " + [
 		has('bb') ? "dj_bb" : "",
 		has('android') ? "dj_android" : "",
-		has('iphone') ? "dj_iphone" : "",
+		has("ios") ? "dj_ios" : "",
+		has("ios") >= 6 ? "dj_ios6" : "",
+		has("ios") ? "dj_iphone" : "",	// TODO: remove for 2.0
 		has('ipod') ? "dj_ipod" : "",
-		has('ipad') ? "dj_ipad" : ""
+		has('ipad') ? "dj_ipad" : "",
+		has('ie') ? "dj_ie": ""
 	].join(" ").replace(/ +/g," "));
+	
+	/*=====
+	return {
+		// summary:
+		//		Requiring this module adds CSS classes to your document's `<html`> tag:
+		//
+		//		- "dj_android" when running on Android;
+		//		- "dj_bb" when running on BlackBerry;
+		//		- "dj_ios" when running on iPhone, iPad or iPod;
+		//		- "dj_iphone" when running on iPhone, iPad or iPod (Note: will be changed in future versions to be set only on iPhone);
+		//		- "dj_ipod" when running on iPod;
+		//		- "dj_ipad" when running on iPad.
+	};
+	=====*/
 	return dojo;
 });
diff --git a/dojox/mobile/viewRegistry.js b/dojox/mobile/viewRegistry.js
new file mode 100644
index 0000000..384bf46
--- /dev/null
+++ b/dojox/mobile/viewRegistry.js
@@ -0,0 +1,94 @@
+define([
+	"dojo/_base/array",
+	"dojo/dom-class",
+	"dijit/registry"
+], function(array, domClass, registry){
+
+	// module:
+	//		dojox/mobile/viewRegistry
+
+	var viewRegistry = {
+		// summary:
+		//		A registry of existing views.
+
+		// length: Number
+		//		The number of registered views.
+		length: 0,
+		
+		// hash: [private] Object
+		//		The object used to register views.
+		hash: {},
+		
+		// initialView: [private] dojox/mobile/View
+		//		The initial view.
+		initialView: null,
+
+		add: function(/*dojox/mobile/View*/ view){
+			// summary:
+			//		Adds a view to the registry.
+			this.hash[view.id] = view;
+			this.length++;
+		},
+
+		remove: function(/*String*/ id){
+			// summary:
+			//		Removes a view from the registry.
+			if(this.hash[id]){
+				delete this.hash[id];
+				this.length--;
+			}
+		},
+
+		getViews: function(){
+			// summary:
+			//		Gets all registered views.
+			// returns: Array
+			var arr = [];
+			for(var i in this.hash){
+				arr.push(this.hash[i]);
+			}
+			return arr;
+		},
+
+		getParentView: function(/*dojox/mobile/View*/ view){
+			// summary:
+			//		Gets the parent view of the specified view.
+			// returns: dojox/mobile/View
+			for(var v = view.getParent(); v; v = v.getParent()){
+				if(domClass.contains(v.domNode, "mblView")){ return v; }
+			}
+			return null;
+		},
+
+		getChildViews: function(/*dojox/mobile/View*/ parent){
+			// summary:
+			//		Gets the children views of the specified view.
+			// returns: Array
+			return array.filter(this.getViews(), function(v){ return this.getParentView(v) === parent; }, this);
+		},
+
+		getEnclosingView: function(/*DomNode*/ node){
+			// summary:
+			//		Gets the view containing the specified DOM node.
+			// returns: dojox/mobile/View
+			for(var n = node; n && n.tagName !== "BODY"; n = n.parentNode){
+				if(n.nodeType === 1 && domClass.contains(n, "mblView")){
+					return registry.byNode(n);
+				}
+			}
+			return null;
+		},
+
+		getEnclosingScrollable: function(/*DomNode*/ node){
+			// summary:
+			//		Gets the dojox/mobile/scrollable object containing the specified DOM node.
+			// returns: dojox/mobile/scrollable
+			for(var w = registry.getEnclosingWidget(node); w; w = w.getParent()){
+				if(w.scrollableParams && w._v){ return w; }
+			}
+			return null;
+		}
+	};
+
+	return viewRegistry;
+});
diff --git a/dojox/mvc.js b/dojox/mvc.js
index cf48514..09c83d2 100755
--- a/dojox/mvc.js
+++ b/dojox/mvc.js
@@ -1,8 +1,14 @@
 define(["./mvc/_base"], function(dxmvc){
 	// module:
 	//		dojox/mvc
-	// summary:
-	//		Adds elements of MVC support to Dojo.
+
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/mvc modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
 
 	return dxmvc;
 });
diff --git a/dojox/mvc/Bind.js b/dojox/mvc/Bind.js
old mode 100755
new mode 100644
index d7a6207..e24649c
--- a/dojox/mvc/Bind.js
+++ b/dojox/mvc/Bind.js
@@ -3,31 +3,28 @@ define([
 	"dojo/_base/array"
 ], function(lang, array){
 	var mvc = lang.getObject("dojox.mvc", true);
-	/*=====
-		mvc = dojox.mvc;
-	=====*/
 
 	return lang.mixin(mvc, {
-		bind: function(/*dojo.Stateful*/ source, /*String*/ sourceProp,
-					/*dojo.Stateful*/ target, /*String*/ targetProp,
+		bind: function(/*dojo/Stateful*/ source, /*String*/ sourceProp,
+					/*dojo/Stateful*/ target, /*String*/ targetProp,
 					/*Function?*/ func, /*Boolean?*/ bindOnlyIfUnequal){
 			// summary:
 			//		Bind the specified property of the target to the specified
 			//		property of the source with the supplied transformation.
-			//	source:
-			//		The source dojo.Stateful object for the bind.
-			//	sourceProp:
+			// source:
+			//		The source dojo/Stateful object for the bind.
+			// sourceProp:
 			//		The name of the source's property whose change triggers the bind.
-			//	target:
-			//		The target dojo.Stateful object for the bind whose
+			// target:
+			//		The target dojo/Stateful object for the bind whose
 			//		property will be updated with the result of the function.
-			//	targetProp:
+			// targetProp:
 			//		The name of the target's property to be updated with the
 			//		result of the function.
-			//	func:
+			// func:
 			//		The optional calculation to be performed to obtain the target
 			//		property value.
-			//	bindOnlyIfUnequal:
+			// bindOnlyIfUnequal:
 			//		Whether the bind notification should happen only if the old and
 			//		new values are unequal (optional, defaults to false).
 			var convertedValue;
@@ -39,14 +36,14 @@ define([
 			});
 		},
 
-		bindInputs: function(/*dojo.Stateful[]*/ sourceBindArray, /*Function*/ func){
+		bindInputs: function(/*dojo/Stateful[]*/ sourceBindArray, /*Function*/ func){
 			// summary:
 			//		Bind the values at the sources specified in the first argument
 			//		array such that a composing function in the second argument is
 			//		called when any of the values changes.
-			//	sourceBindArray:
-			//		The array of dojo.Stateful objects to watch values changes on.
-			//	func:
+			// sourceBindArray:
+			//		The array of dojo/Stateful objects to watch values changes on.
+			// func:
 			//		The composing function that is called when any of the source
 			//		values changes.
 			// tags:
diff --git a/dojox/mvc/EditModelRefController.js b/dojox/mvc/EditModelRefController.js
new file mode 100644
index 0000000..4702d2e
--- /dev/null
+++ b/dojox/mvc/EditModelRefController.js
@@ -0,0 +1,204 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"./getPlainValue",
+	"./getStateful",
+	"./ModelRefController"
+], function(declare, lang, getPlainValue, getStateful, ModelRefController){
+	// module:
+	//		dojox/mvc/EditModelRefController
+
+	function setRefSourceModel(/*dojox/mvc/EditModelRefController*/ ctrl, /*Anything*/ old, /*Anything*/ current){
+		// summary:
+		//		A function called when this controller gets newer value as the data source.
+		// ctrl: dojox/mvc/EditModelRefController
+		//		The controller.
+		// old: Anything
+		//		The older value.
+		// current: Anything
+		//		The newer value.
+
+		if(old !== current){
+			ctrl.set(ctrl._refOriginalModelProp, ctrl.holdModelUntilCommit ? current : ctrl.cloneModel(current));
+			ctrl.set(ctrl._refEditModelProp, ctrl.holdModelUntilCommit ? ctrl.cloneModel(current) : current);
+		}
+	}
+
+	return declare("dojox.mvc.EditModelRefController", ModelRefController, {
+		// summary:
+		//		A child class of dojox/mvc/ModelRefController.
+		//		Keeps a copy (originalModel) of given data model (sourceModel) so that it can manage the data model of before/after the edit.
+		// description:
+		//		Has two modes:
+		//
+		//		- Directly reflect the edits to sourceModel (holdModelUntilCommit=false)
+		//		- Don't reflect the edits to sourceModel, until commit() is called (holdModelUntilCommit=true)
+		//
+		//		For the 1st case, dojo/Stateful get()/set()/watch() interfaces will work with sourceModel.
+		//		For the 2nd case, dojo/Stateful get()/set()/watch() interfaces will work with a copy of sourceModel, and sourceModel will be replaced with such copy when commit() is called.
+		//
+		//		NOTE - If this class is used with a widget by data-dojo-mixins, make sure putting the widget in data-dojo-type and putting this class to data-dojo-mixins.
+		// example:
+		//		The check box refers to "value" property in the controller (with "ctrl" ID).
+		//		The controller provides the "value" property on behalf of the model ("model" property in the controller, which comes from "sourceModel" property).
+		//		Two seconds later, the check box changes from unchecked to checked, and the controller saves the state.
+		//		Two seconds later then, the check box changes from checked to unchecked.
+		//		Two seconds later then, the controller goes back to the last saved state, and the check box changes from unchecked to checked as the result.
+		// |		<html>
+		// |			<head>
+		// |				<script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script>
+		// |				<script type="text/javascript">
+		// |					require([
+		// |						"dojo/dom", "dojo/parser", "dojo/Stateful", "dijit/registry", "dijit/form/CheckBox", "dojox/mvc/EditModelRefController", "dojo/domReady!"
+		// |					], function(ddom, parser, Stateful, registry){
+		// |						model = new Stateful({value: false});
+		// |						setTimeout(function(){
+		// |							ddom.byId("check").click();
+		// |							registry.byId("ctrl").commit();
+		// |							setTimeout(function(){
+		// |								ddom.byId("check").click();
+		// |								setTimeout(function(){
+		// |									registry.byId("ctrl").reset();
+		// |								}, 2000);
+		// |							}, 2000);
+		// |						}, 2000);
+		// |						parser.parse();
+		// |					});
+		// |				</script>
+		// |			</head>
+		// |			<body>
+		// |				<script type="dojo/require">at: "dojox/mvc/at"</script>
+		// |				<span id="ctrl" data-dojo-type="dojox/mvc/EditModelRefController" data-dojo-props="sourceModel: model"></span>
+		// |				<input id="check" type="checkbox" data-dojo-type="dijit/form/CheckBox" data-dojo-props="checked: at('widget:ctrl', 'value')">
+		// |			</body>
+		// |		</html>
+		// example:
+		//		The controller with "ctrlSource" ID specifies holding changes until commit() is called (by setting true to holdModelUntilCommit).
+		//		As the change in the second check box is committed two seconds later from the change, the first check box is checked at then (when the change is committed).
+		// |		<html>
+		// |			<head>
+		// |				<script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script>
+		// |				<script type="text/javascript">
+		// |					require([
+		// |						"dojo/dom", "dojo/parser", "dojo/Stateful", "dijit/registry",
+		// |						"dijit/form/CheckBox", "dojox/mvc/ModelRefController", "dojox/mvc/EditModelRefController", "dojo/domReady!"
+		// |					], function(ddom, parser, Stateful, registry){
+		// |						model = new Stateful({value: false});
+		// |						setTimeout(function(){
+		// |							ddom.byId("checkEdit").click();
+		// |							setTimeout(function(){
+		// |								registry.byId("ctrlEdit").commit();
+		// |							}, 2000);
+		// |						}, 2000);
+		// |						parser.parse();
+		// |					});
+		// |				</script>
+		// |			</head>
+		// |			<body>
+		// |				<script type="dojo/require">at: "dojox/mvc/at"</script>
+		// |				<span id="ctrlSource" data-dojo-type="dojox/mvc/ModelRefController" data-dojo-props="model: model"></span>
+		// |				<span id="ctrlEdit" data-dojo-type="dojox/mvc/EditModelRefController"
+		// |				 data-dojo-props="sourceModel: at('widget:ctrlSource', 'model'), holdModelUntilCommit: true"></span>
+		// |				Source:
+		// |				<input id="checkSource" type="checkbox" data-dojo-type="dijit/form/CheckBox"
+		// |				 data-dojo-props="checked: at('widget:ctrlSource', 'value')">
+		// |				Edit:
+		// |				<input id="checkEdit" type="checkbox" data-dojo-type="dijit/form/CheckBox"
+		// |				 data-dojo-props="checked: at('widget:ctrlEdit', 'value')">
+		// |			</body>
+		// |		</html>
+
+		// getStatefulOptions: dojox/mvc/getStatefulOptions
+		//		The options to get stateful object from plain value.
+		getStatefulOptions: null,
+
+		// getPlainValueOptions: dojox/mvc/getPlainValueOptions
+		//		The options to get plain value from stateful object.
+		getPlainValueOptions: null,
+
+		// holdModelUntilCommit: Boolean
+		//		True not to send the change in model back to sourceModel until commit() is called.
+		holdModelUntilCommit: false,
+
+		// originalModel: dojo/Stateful
+		//		The data model, that serves as the original data.
+		originalModel: null,
+
+		// originalModel: dojo/Stateful
+		//		The data model, that serves as the data source.
+		sourceModel: null,
+
+		// _refOriginalModelProp: String
+		//		The property name for the data model, that serves as the original data.
+		_refOriginalModelProp: "originalModel",
+
+		// _refSourceModelProp: String
+		//		The property name for the data model, that serves as the data source.
+		_refSourceModelProp: "sourceModel",
+
+		// _refEditModelProp: String
+		//		The property name for the data model, that is being edited.
+		_refEditModelProp: "model",
+
+		postscript: function(/*Object?*/ params, /*DomNode|String?*/ srcNodeRef){
+			// summary:
+			//		Sets certain properties before setting models.
+
+			for(var s in {getStatefulOptions: 1, getPlainValueOptions: 1, holdModelUntilCommit: 1}){
+				var value = (params || {})[s];
+				if(typeof value != "undefined"){
+					this[s] = value;
+				}
+			}
+			this.inherited(arguments);
+		},
+
+		set: function(/*String*/ name, /*Anything*/ value){
+			// summary:
+			//		Set a property to this.
+			// name: String
+			//		The property to set.
+			// value: Anything
+			//		The value to set in the property.
+
+			if(name == this._refSourceModelProp){
+				setRefSourceModel(this, this[this._refSourceModelProp], value);
+			}
+			this.inherited(arguments);
+		},
+
+		cloneModel: function(/*Anything*/ value){
+			// summary:
+			//		Create a clone object of the data source.
+			//		Child classes of this controller can override it to achieve its specific needs.
+			// value: Anything
+			//		The data serving as the data source.
+
+			var plain = lang.isFunction((value || {}).set) && lang.isFunction((value || {}).watch) ? getPlainValue(value, this.getPlainValueOptions) : value;
+			return getStateful(plain, this.getStatefulOptions);
+		},
+
+		commit: function(){
+			// summary:
+			//		Send the change back to the data source.
+
+			this.set(this.holdModelUntilCommit ? this._refSourceModelProp : this._refOriginalModelProp, this.cloneModel(this.get(this._refEditModelProp)));
+		},
+
+		reset: function(){
+			// summary:
+			//		Change the model back to its original state.
+
+			this.set(this.holdModelUntilCommit ? this._refEditModelProp : this._refSourceModelProp, this.cloneModel(this.get(this._refOriginalModelProp)));
+		},
+
+		hasControllerProperty: function(/*String*/ name){
+			// summary:
+			//		Returns true if this controller itself owns the given property.
+			// name: String
+			//		The property name.
+
+			return this.inherited(arguments) || name == this._refOriginalModelProp || name == this._refSourceModelProp;
+		}
+	});
+});
diff --git a/dojox/mvc/EditStoreRefController.js b/dojox/mvc/EditStoreRefController.js
new file mode 100644
index 0000000..d6e48d0
--- /dev/null
+++ b/dojox/mvc/EditStoreRefController.js
@@ -0,0 +1,153 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/when",
+	"./getPlainValue",
+	"./EditModelRefController",
+	"./StoreRefController"
+], function(declare, lang, when, getPlainValue, EditModelRefController, StoreRefController){
+	return declare("dojox.mvc.EditStoreRefController", [StoreRefController, EditModelRefController], {
+		// summary:
+		//		A child class of dojox/mvc/StoreRefController, managing edits.
+		// description:
+		//		In addition to what dojox/mvc/StoreRefController does, the commit() method sends the data model as well as the removed entries in array to the data store.
+		//		NOTE - If this class is used with a widget by data-dojo-mixins, make sure putting the widget in data-dojo-type and putting this class to data-dojo-mixins.
+		// example:
+		//		The check box refers to "value" property in the controller (with "ctrl" ID).
+		//		The controller provides the "value" property, from the data coming from data store ("store" property in the controller), using the first one in array.
+		//		Two seconds later, the check box changes from unchecked to checked.
+		//		The change is committed to the data store, which is reflected to dojo/store/Observable callback. 
+		// |		<html>
+		// |			<head>
+		// |				<script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script>
+		// |				<script type="text/javascript">
+		// |					require([
+		// |						"dojo/dom", "dojo/parser", "dojo/when", "dojo/store/Observable", "dojo/store/Memory", "dijit/registry", "dojo/domReady!"
+		// |					], function(ddom, parser, when, Observable, Memory, registry){
+		// |						store = Observable(new Memory({data: [{id: "Foo", value: false}]}));
+		// |						when(parser.parse(), function(){
+		// |							registry.byId("ctrl").queryStore().observe(function(object, previousIndex, newIndex){
+		// |								alert("ID: " + object.id + ", value: " + object.value);
+		// |							}, true);
+		// |							var count = 0;
+		// |							var h = setInterval(function(){
+		// |								ddom.byId("check").click();
+		// |								registry.byId("ctrl").commit();
+		// |								if(++count >= 2){ clearInterval(h); }
+		// |							}, 2000);
+		// |						});
+		// |					});
+		// |				</script>
+		// |			</head>
+		// |			<body>
+		// |				<script type="dojo/require">at: "dojox/mvc/at"</script>
+		// |				<span id="ctrl" data-dojo-type="dojox/mvc/EditStoreRefController" data-dojo-mixins="dojox/mvc/ListController"
+		// |				 data-dojo-props="store: store, cursorIndex: 0"></span>
+		// |				<input id="check" type="checkbox" data-dojo-type="dijit/form/CheckBox" data-dojo-props="checked: at('widget:ctrl', 'value')">
+		// |			</body>
+		// |		</html>
+
+		// getPlainValueOptions: dojox/mvc/getPlainValueOptions
+		//		The options to get plain value from stateful object.
+		getPlainValueOptions: null,
+
+		// _removals: Object[]
+		//		The list of removed elements.
+		_removals: [],
+
+		// _resultsWatchHandle: dojox/mvc/StatefulArray.watchElements.handle
+		//		The watch handle for model array elements.
+		_resultsWatchHandle: null,
+
+		// _refSourceModelProp: String
+		//		The property name for the data model, that serves as the data source.
+		_refSourceModelProp: "sourceModel",
+
+		queryStore: function(/*Object*/ query, /*dojo/store/api/Store.QueryOptions?*/ options){
+			// summary:
+			//		Queries the store for objects.
+			// query: Object
+			//		The query to use for retrieving objects from the store.
+			// options: dojo/store/api/Store.QueryOptions?
+			//		The optional arguments to apply to the resultset.
+			// returns: dojo/store/api/Store.QueryResults
+			//		The results of the query, extended with iterative methods.
+
+			if(!(this.store || {}).query){ return; }
+			if(this._resultsWatchHandle){ this._resultsWatchHandle.unwatch(); }
+			this._removals = [];
+			var _self = this,
+			 queryResult = this.inherited(arguments),
+			 result = when(queryResult, function(results){
+				if(_self._beingDestroyed){ return; }
+				if(lang.isArray(results)){
+					_self._resultsWatchHandle = results.watchElements(function(idx, removals, adds){
+						[].push.apply(_self._removals, removals);
+					});
+				}
+				return results;
+			});
+			if(result.then){
+				result = lang.delegate(result);
+			}
+			// For dojo/store/Observable, which adds a function to query result
+			for(var s in queryResult){
+				if(isNaN(s) && queryResult.hasOwnProperty(s) && lang.isFunction(queryResult[s])){
+					result[s] = queryResult[s];
+				}
+			}
+			return result;
+		},
+
+		getStore: function(/*Number*/ id, /*Object*/ options){
+			// summary:
+			//		Retrieves an object by its identity.
+			// id: Number
+			//		The identity to use to lookup the object.
+			// options: Object
+			//		The options for dojo/store/*/get().
+			// returns: Object
+			//		The object in the store that matches the given id.
+
+			if(this._resultsWatchHandle){ this._resultsWatchHandle.unwatch(); }
+			return this.inherited(arguments);
+		},
+
+		commit: function(){
+			// summary:
+			//		Send the change back to the data source.
+
+			if(this._removals){
+				for(var i = 0; i < this._removals.length; i++){
+					this.store.remove(this.store.getIdentity(this._removals[i]));
+				}
+				this._removals = [];
+			}
+			var data = getPlainValue(this.get(this._refEditModelProp), this.getPlainValueOptions);
+			if(lang.isArray(data)){
+				for(var i = 0; i < data.length; i++){
+					this.store.put(data[i]);
+				}
+			}else{
+				this.store.put(data);
+			}
+			this.inherited(arguments);
+		},
+
+		reset: function(){
+			// summary:
+			//		Change the model back to its original state.
+
+			this.inherited(arguments);
+			this._removals = [];
+		},
+
+		destroy: function(){
+			// summary:
+			//		Clean up model watch handle as this object is destroyed.
+
+			if(this._resultsWatchHandle){ this._resultsWatchHandle.unwatch(); }
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dojox/mvc/EditStoreRefListController.js b/dojox/mvc/EditStoreRefListController.js
new file mode 100644
index 0000000..ae98083
--- /dev/null
+++ b/dojox/mvc/EditStoreRefListController.js
@@ -0,0 +1,64 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"./getPlainValue",
+	"./EditStoreRefController",
+	"./ListController"
+], function(declare, lang, getPlainValue, EditStoreRefController, ListController){
+	return declare("dojox.mvc.EditStoreRefListController", [EditStoreRefController, ListController], {
+		// summary:
+		//		A child class of dojox/mvc/EditStoreRefController, mixed with ListController.
+		// description:
+		//		It supports Lists in addition to what dojox/mvc/EditStoreRefController does.
+		//		NOTE - If this class is used with a widget by data-dojo-mixins, make sure putting the widget in data-dojo-type and putting this class to data-dojo-mixins.
+		// example:
+		//		The check box refers to "value" property in the controller (with "ctrl" ID).
+		//		The controller provides the "value" property, from the data coming from data store ("store" property in the controller), using the first one in array.
+		//		Two seconds later, the check box changes from unchecked to checked.
+		//		The change is committed to the data store, which is reflected to dojo/store/Observable callback. 
+		// |		<html>
+		// |			<head>
+		// |				<script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script>
+		// |				<script type="text/javascript">
+		// |					require([
+		// |						"dojo/dom", "dojo/parser", "dojo/store/Observable", "dojo/store/Memory", "dijit/registry",
+		// |						"dijit/form/CheckBox", "dojox/mvc/EditStoreRefListController", "dojox/mvc/ListController", "dojo/domReady!"
+		// |					], function(ddom, parser, Observable, Memory, registry){
+		// |						store = Observable(new Memory({data: [{id: "Foo", value: false}]}));
+		// |						parser.parse();
+		// |						registry.byId("ctrl").queryStore().observe(function(object, previousIndex, newIndex){
+		// |							alert("ID: " + object.id + ", value: " + object.value);
+		// |						}, true);
+		// |						var count = 0;
+		// |						var h = setInterval(function(){
+		// |							ddom.byId("check").click();
+		// |							registry.byId("ctrl").commit();
+		// |							if(++count >= 2){ clearInterval(h); }
+		// |						}, 2000);
+		// |					});
+		// |				</script>
+		// |			</head>
+		// |			<body>
+		// |				<script type="dojo/require">at: "dojox/mvc/at"</script>
+		// |				<span id="ctrl" data-dojo-type="dojox/mvc/EditStoreRefListController" 
+		// |				 data-dojo-props="store: store, cursorIndex: 0"></span>
+		// |				<input id="check" type="checkbox" data-dojo-type="dijit/form/CheckBox" data-dojo-props="checked: at('widget:ctrl', 'value')">
+		// |			</body>
+		// |		</html>
+
+		commitCurrent: function(){
+		// summary:
+		//		Send the change back to the data source for the current index.
+
+			var id = this.cursor[this.idProperty];
+			for(var i = 0; i < this.originalModel.length; i++){
+				if(this.originalModel[i][this.idProperty] == id){
+					this.originalModel.set(i, this.cloneModel(this.cursor));
+					break;
+				}
+			}
+			this.store.put(this.cursor);
+		}
+
+	});
+});
diff --git a/dojox/mvc/Element.js b/dojox/mvc/Element.js
new file mode 100644
index 0000000..f81f82b
--- /dev/null
+++ b/dojox/mvc/Element.js
@@ -0,0 +1,31 @@
+define([
+	"dojo/_base/declare",
+	"dijit/_WidgetBase"
+], function(declare, _WidgetBase){
+	return declare("dojox.mvc.Element", _WidgetBase, {
+		// summary:
+		//		A widget implicitly created by dojox/mvc/parserExtension.
+		//		Maps "value" attribute to form element value, innerText/innerHTML to element's innerText/innerHTML, and other attributes to DOM attributes.
+		//		Also, for form element, updates value (or checked for check box) as user edits.
+
+		_setInnerTextAttr: {node: "domNode", type: "innerText"},
+		_setInnerHTMLAttr: {node: "domNode", type: "innerHTML"},
+
+		buildRendering: function(){
+			// summary:
+			//		Set onchange event handler for form elements.
+
+			this.inherited(arguments);
+			if(/select|input|textarea/i.test(this.domNode.tagName)){
+				var _self = this, node = this.focusNode = this.domNode;
+				this.on("change", function(e){
+					var attr = /^checkbox$/i.test(node.getAttribute("type")) ? "checked" : "value";
+					_self._set(attr, _self.get(attr));
+				});
+			}
+		},
+
+		_getCheckedAttr: function(){ return this.domNode.checked; },
+		_getValueAttr: function(){ return this.domNode.value; }
+	});
+});
diff --git a/dojox/mvc/Generate.js b/dojox/mvc/Generate.js
old mode 100755
new mode 100644
index 884f125..84d862d
--- a/dojox/mvc/Generate.js
+++ b/dojox/mvc/Generate.js
@@ -1,14 +1,12 @@
 define([
+	"dojo/_base/array",
 	"dojo/_base/lang",
 	"dojo/_base/declare",
 	"./_Container",
+	"./at",
 	"./Group",
 	"dijit/form/TextBox"
-], function(lang, declare, Container){
-	/*=====
-		Container = dojox.mvc._Container;
-		declare = dojo.declare;
-	=====*/
+], function(array, lang, declare, Container, at){
 
 	return declare("dojox.mvc.Generate", [Container], {
 		// summary:
@@ -27,7 +25,7 @@ define([
 		// defaultWidgetMapping: Object
 		//		The mapping of types to a widget class. Set widgetMapping to override this. 
 		//	
-		_defaultWidgetMapping: {"String" : "dijit.form.TextBox"},
+		_defaultWidgetMapping: {"String" : "dijit/form/TextBox"},
 	
 		// defaultClassMapping: Object
 		//		The mapping of class to use. Set classMapping to override this. 
@@ -39,115 +37,163 @@ define([
 		//		The mapping of id and name to use. Set idNameMapping to override this. A count will be added to the id and name
 		//	
 		_defaultIdNameMapping: {"String" : "textbox_t"},
-		
+
+		// children: dojo/Stateful
+		//		The array of data model that is used to render child nodes.
+		children: null,
+
+		// _relTargetProp: String
+		//		The name of the property that is used by child widgets for relative data binding.
+		_relTargetProp : "children",
+
+		startup: function(){
+			this.inherited(arguments);
+			this._setChildrenAttr(this.children);
+		},
+
 		////////////////////// PRIVATE METHODS ////////////////////////
-	
-		_updateBinding: function(){
+
+		_setChildrenAttr: function(/*dojo/Stateful*/ value){
 			// summary:
-			//		Regenerate if the binding changes.
-			this.inherited(arguments);
-			this._buildContained();
+			//		Handler for calls to set("children", val).
+			// description:
+			//		Sets "ref" property so that child widgets can refer to, and then rebuilds the children.
+
+			var children = this.children;
+			this._set("children", value);
+			// this.binding is the resolved ref, so not matching with the new value means change in repeat target.
+			if(this.binding != value){
+				this.set("ref", value);
+			}
+			if(this._started && (!this._builtOnce || children != value)){
+				this._builtOnce = true;
+				this._buildContained(value);
+			}
 		},
 	
-		_buildContained: function(){
+		_buildContained: function(/*dojo/Stateful*/ children){
 			// summary:
 			//		Destroy any existing generated view, recreate it from scratch
 			//		parse the new contents.
+			// children: dojo/Stateful
+			//		The array of child widgets.
 			// tags:
 			//		private
+
+			if(!children){ return; }
+
 			this._destroyBody();
 	
 			this._counter = 0;
-			this.srcNodeRef.innerHTML = this._generateBody(this.get("binding"));
+			this.srcNodeRef.innerHTML = this._generateBody(children);
 	
 			this._createBody();
 		},
 	
-		_generateBody: function(binding, hideHeading){
+		_generateBody: function(/*dojo/Stateful*/ children, /*Boolean*/ hideHeading){
 			// summary:
 			//		Generate the markup for the view associated with this generate
 			//		container.
-			//	binding:
-			//		The associated data binding to generate a view for.
-			//	hideHeading:
+			// children: dojo/Stateful
+			//		The associated data to generate a view for.
+			// hideHeading: Boolean
 			//		Whether the property name should be displayed as a heading.
 			// tags:
 			//		private
-			var body = "";
-			for(var prop in binding){
-				if(binding[prop] && lang.isFunction(binding[prop].toPlainObject)){
-					if(binding[prop].get(0)){
-						body += this._generateRepeat(binding[prop], prop);
-					}else if(binding[prop].value){
+
+			if(children === void 0){ return ""; }
+
+			var body = [];
+			var isStatefulModel = lang.isFunction(children.toPlainObject);
+
+			function generateElement(value, prop){
+				if(isStatefulModel ? (value && lang.isFunction(value.toPlainObject)) : !lang.isFunction(value)){
+					if(lang.isArray(value)){
+						body.push(this._generateRepeat(value, prop));
+					}else if(isStatefulModel ? value.value : ((value == null || {}.toString.call(value) != "[object Object]") && (!(value || {}).set || !(value || {}).watch))){
 						// TODO: Data types based widgets
-						body += this._generateTextBox(prop);
+						body.push(this._generateTextBox(prop, isStatefulModel));
 					}else{
-						body += this._generateGroup(binding[prop], prop, hideHeading);
+						body.push(this._generateGroup(value, prop, hideHeading));
 					}
 				}
 			}
-			return body;
+
+			if(lang.isArray(children)){
+				array.forEach(children, generateElement, this);
+			}else{
+				for(var s in children){
+					if(children.hasOwnProperty(s)){
+						generateElement.call(this, children[s], s);
+					}
+				}
+			}
+
+			return body.join("");
 		},
 	
-		_generateRepeat: function(binding, repeatHeading){
+		_generateRepeat: function(/*dojox/mvc/StatefulArray*/ children, /*String*/ repeatHeading){
 			// summary:
 			//		Generate a repeating model-bound view.
-			//	binding:
+			// children: dojox/mvc/StatefulArray
 			//		The bound node (a collection/array node) to generate a
 			//		repeating UI/view for.
-			//	repeatHeading:
+			// repeatHeading: String
 			//		The heading to be used for this portion.
 			// tags:
 			//		private
+
 			var headingClass = (this.classMapping && this.classMapping["Heading"]) ? this.classMapping["Heading"] : this._defaultClassMapping["Heading"];
-			var repeat = '<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: \'' + repeatHeading + '\'" + id="' + this.id + '_r' + this._counter++ + '">' +
-						 '<div class="' + headingClass + '\">' + repeatHeading + '</div>';
-			repeat += this._generateBody(binding, true);
-			repeat += '</div>';
-			return repeat;
+			return '<div data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(\'rel:\', \'' + repeatHeading + '\')" + id="' + this.id + '_r' + this._counter++ + '">'
+			 + '<div class="' + headingClass + '\">' + repeatHeading + '</div>'
+			 + this._generateBody(children, true)
+			 + '</div>';
 		},
 		
-		_generateGroup: function(binding, groupHeading, hideHeading){
+		_generateGroup: function(/*dojo/Stateful*/ model, /*String*/ groupHeading, /*Boolean*/ hideHeading){
 			// summary:
 			//		Generate a hierarchical model-bound view.
-			//	binding:
-			//		The bound (intermediate) node to generate a hierarchical
-			//		view portion for.
-			//	groupHeading:
+			// model: dojo/Stateful
+			//		The bound (intermediate) model to generate a hierarchical view portion for.
+			// groupHeading: String
 			//		The heading to be used for this portion.
-			//	hideHeading:
+			// hideHeading: Boolean
 			//		Whether the heading should be hidden for this portion.
 			// tags:
 			//		private
-			var group = '<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: \'' + groupHeading + '\'" + id="' + this.id + '_g' + this._counter++ + '">';
+
+			var html = ['<div data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(\'rel:\', \'' + groupHeading + '\')" + id="' + this.id + '_g' + this._counter++ + '">'];
 			if(!hideHeading){
 				var headingClass = (this.classMapping && this.classMapping["Heading"]) ? this.classMapping["Heading"] : this._defaultClassMapping["Heading"];
-				group += '<div class="' + headingClass + '\">' + groupHeading + '</div>';
+				html.push('<div class="' + headingClass + '\">' + groupHeading + '</div>');
 			}
-			group += this._generateBody(binding);
-			group += '</div>';
-			return group;
+			html.push(this._generateBody(model) + '</div>');
+			return html.join("");
 		},
 	
-		_generateTextBox: function(prop){
+		_generateTextBox: function(/*String*/ prop, /*Boolean*/ referToValue){
 			// summary:
 			//		Produce a widget for a simple value.
-			//	prop:
+			// prop: String
 			//		The data model property name.
+			// referToValue: Boolean
+			//		True if the property is dojox/mvc/StatefulModel with "value" attribute.
 			// tags:
 			//		private
 			// TODO: Data type based widget generation / enhanced meta-data
+
 			var idname = this.idNameMapping ? this.idNameMapping["String"] : this._defaultIdNameMapping["String"];
 			idname = idname + this._counter++; 
 			var widClass = this.widgetMapping ? this.widgetMapping["String"] : this._defaultWidgetMapping["String"];
 			var labelClass = (this.classMapping && this.classMapping["Label"]) ? this.classMapping["Label"] : this._defaultClassMapping["Label"];
 			var stringClass = (this.classMapping && this.classMapping["String"]) ? this.classMapping["String"] : this._defaultClassMapping["String"];
 			var rowClass = (this.classMapping && this.classMapping["Row"]) ? this.classMapping["Row"] : this._defaultClassMapping["Row"];
-			
+			var bindingSyntax = 'value: at(\'rel:' + (referToValue && prop || '') + '\', \'' + (referToValue ? 'value' : prop) + '\')'; 
+
 			return '<div class="' + rowClass + '\">' +
 					'<label class="' + labelClass + '\">' + prop + ':</label>' +
-					'<input class="' + stringClass + '\" data-dojo-type="' + widClass + '\" data-dojo-props="name: \'' + idname + "', ref: '" + prop + '\'" id="' +
-					idname + '\"></input>' +
+					'<input class="' + stringClass + '\" data-dojo-type="' + widClass + '\"' +
+					' data-dojo-props="name: \'' + idname + '\', ' + bindingSyntax + '" id="' + idname + '\"></input>' +
 					'</div>';
 		}
 	});
diff --git a/dojox/mvc/Group.js b/dojox/mvc/Group.js
old mode 100755
new mode 100644
index a343f3b..04ed7a2
--- a/dojox/mvc/Group.js
+++ b/dojox/mvc/Group.js
@@ -1,16 +1,43 @@
-define(["dojo/_base/declare", "dijit/_WidgetBase"], function(declare, WidgetBase){
-	/*=====
-		WidgetBase = dijit._WidgetBase;
-		declare = dojo.declare;
-	=====*/
+define(["dojo/_base/declare", "dijit/_WidgetBase", 	"dojo/_base/lang"], function(declare, _WidgetBase, lang){
 
-	return declare("dojox.mvc.Group", [WidgetBase], {
+	return declare("dojox.mvc.Group", _WidgetBase, {
 		// summary:
 		//		A simple model-bound container widget with single-node binding to a data model.
 		//
 		// description:
-		//		A group is usually bound to an intermediate dojo.Stateful node in the data model.
+		//		A group is usually bound to an intermediate dojo/Stateful node in the data model.
 		//		Child dijits or custom view components inside a group inherit their parent
 		//		data binding context from it.
+
+		// target: dojo/Stateful
+		//		The data model used for relative data binding.
+		target: null,
+
+		startup: function(){
+			// This code needed for ticket 14423 is using removeRepeatNode on a repeat to work with mobile.lists
+			// this.select and this.onCheckStateChanged are called by ListItem so they need to be set
+			// but it seems like a bit of a hack.
+			var parent = null;
+			if(lang.isFunction(this.getParent)){
+				if(this.getParent() && this.getParent().removeRepeatNode){
+					this.select = this.getParent().select;
+					this.onCheckStateChanged = this.getParent().onCheckStateChanged;
+				}
+			}			
+			this.inherited(arguments);
+		},
+
+		_setTargetAttr: function(/*dojo/Stateful*/ value){
+			// summary:
+			//		Handler for calls to set("target", val).
+			// description:
+			//		Sets target and "ref" property so that child widgets can refer to.
+
+			this._set("target", value);
+			if(this.binding != value){
+				// The new value not matching to this.binding means that the change is not initiated by ref change.
+				this.set("ref", value);
+			}
+		}
 	});
 });
diff --git a/dojox/mvc/ListController.js b/dojox/mvc/ListController.js
new file mode 100644
index 0000000..02df468
--- /dev/null
+++ b/dojox/mvc/ListController.js
@@ -0,0 +1,229 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"./ModelRefController"
+], function(array, lang, declare, ModelRefController){
+	function unwatchHandles(/*dojox/mvc/ListController*/ c){
+		// summary:
+		//		Unwatch model watch handles.
+
+		for(var s in {"_listModelWatchHandle": 1, "_tableModelWatchHandle": 1}){
+			if(c[s]){
+				c[s].unwatch();
+				c[s] = null;
+			}
+		}
+	}
+
+	function setRefInModel(/*dojox/mvc/ListController*/ ctrl, /*dojo/Stateful*/ old, /*dojo/Stateful*/ current){
+		// summary:
+		//		A function called when this controller gets newer value as the list data.
+
+		unwatchHandles(ctrl);
+		if(current && old !== current){
+			if(current.watchElements){
+				ctrl._listModelWatchHandle = current.watchElements(function(idx, removals, adds){
+					if(removals && adds){
+						var curIdx = ctrl.get("cursorIndex");
+						// If selected element is removed, make "no selection" state
+						if(removals && curIdx >= idx && curIdx < idx + removals.length){
+							ctrl.set("cursorIndex", -1);
+							return;
+						}
+						// If selected element is equal to or larger than the removals/adds point, update the selected index
+						if((removals.length || adds.length) && curIdx >= idx){
+							ctrl.set(ctrl._refCursorProp, ctrl.get("cursor"));
+						}
+					}else{
+						// If there is a update to the whole array, update the selected index 
+						ctrl.set(ctrl._refCursorProp, ctrl.get(ctrl._refCursorProp));
+					}
+				});
+			}else if(current.set && current.watch){
+				if(ctrl.get("cursorIndex") < 0){ ctrl._set("cursorIndex", ""); }
+				ctrl._tableModelWatchHandle = current.watch(function(name, old, current){
+					if(old !== current && name == ctrl.get("cursorIndex")){
+						ctrl.set(ctrl._refCursorProp, current);
+					}
+				});
+			}
+		}
+		ctrl._setCursorIndexAttr(ctrl.cursorIndex);
+	}
+
+	function setRefCursor(/*dojox/mvc/ListController*/ ctrl, /*dojo/Stateful*/ old, /*dojo/Stateful*/ current){
+		// summary:
+		//		A function called when this controller gets newer value as the data of current selection.
+		// description:
+		//		Finds the index associated with the given element, and updates cursorIndex property.
+
+		var model = ctrl[ctrl._refInModelProp];
+		if(!model){ return; }
+		if(old !== current){
+			if(lang.isArray(model)){
+				var foundIdx = array.indexOf(model, current);
+				if(foundIdx < 0){
+					var targetIdx = ctrl.get("cursorIndex");
+					if(targetIdx >= 0 && targetIdx < model.length){
+						model.set(targetIdx, current);
+					}
+				}else{
+					ctrl.set("cursorIndex", foundIdx);
+				}
+			}else{
+				for(var s in model){
+					if(model[s] == current){
+						ctrl.set("cursorIndex", s);
+						return;
+					}
+				}
+				var targetIdx = ctrl.get("cursorIndex");
+				if(targetIdx){
+					model.set(targetIdx, current);
+				}
+			}
+		}
+	}
+
+	return declare("dojox.mvc.ListController", ModelRefController, {
+		// summary:
+		//		A controller working with array model, managing its cursor.
+		//		NOTE - If this class is used with a widget by data-dojo-mixins, make sure putting the widget in data-dojo-type and putting this class to data-dojo-mixins.
+		// example:
+		//		The text box changes its value every two seconds.
+		// |		<html>
+		// |			<head>
+		// |				<script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script>
+		// |				<script type="text/javascript">
+		// |					require([
+		// |						"dojo/parser", "dijit/registry", "dojox/mvc/StatefulArray",
+		// |						"dijit/form/TextBox", "dojox/mvc/ListController", "dojo/domReady!"
+		// |					], function(parser, registry, StatefulArray){
+		// |						var count = 0;
+		// |						model = new StatefulArray([{value: "First"}, {value: "Second"}, {value: "Third"}, {value: "Fourth"}, {value: "Fifth"}]);
+		// |						setInterval(function(){ registry.byId("ctrl").set("cursorIndex", ++count % 5); }, 2000);
+		// |						parser.parse();
+		// |					});
+		// |				</script>
+		// |			</head>
+		// |			<body>
+		// |				<script type="dojo/require">at: "dojox/mvc/at"</script>
+		// |				<span id="ctrl" data-dojo-type="dojox/mvc/ListController" data-dojo-props="model: model"></span>
+		// |				<input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-props="value: at('widget:ctrl', 'value')">
+		// |			</body>
+		// |		</html>
+
+		// idProperty: String
+		//		The property name in element in the model array, that works as its identifier.
+		idProperty: "uniqueId",
+
+		// cursorId: String
+		//		The ID of the selected element in the model array.
+		cursorId: null,
+
+		// cursorIndex: Number|String
+		//		The index of the selected element in the model.
+		cursorIndex: -1,
+
+		// cursor: dojo/Stateful
+		//		The selected element in the model array.
+		cursor: null,
+
+		// model: dojox/mvc/StatefulArray
+		//		The data model working as an array.
+		model: null,
+
+		// _listModelWatchHandle: Object
+		//		The watch handle of model, watching for array elements.
+		_listModelWatchHandle: null,
+
+		// _tableModelWatchHandle: Object
+		//		The watch handle of model.
+		_tableModelWatchHandle: null,
+
+		// _refCursorProp: String
+		//		The property name for the data model of the current selection.
+		_refCursorProp: "cursor",
+
+		// _refModelProp: String
+		//		The property name for the data model.
+		_refModelProp: "cursor",
+
+		destroy: function(){
+			unwatchHandles(this);
+			this.inherited(arguments);
+		},
+
+		set: function(/*String*/ name, /*Anything*/ value){
+			// summary:
+			//		Set a property to this.
+			// name: String
+			//		The property to set.
+			// value: Anything
+			//		The value to set in the property.
+
+			var oldRefInCursor = this[this._refCursorProp];
+			var oldRefInModel = this[this._refInModelProp];
+			this.inherited(arguments);
+			if(name == this._refCursorProp){
+				setRefCursor(this, oldRefInCursor, value);
+			}
+			if(name == this._refInModelProp){
+				setRefInModel(this, oldRefInModel, value);
+			}
+		},
+
+		_setCursorIdAttr: function(/*String*/ value){
+			// summary:
+			//		Handler for calls to set("cursorId", val).
+			// description:
+			//		Finds the index associated with the given cursor ID, and updates cursorIndex property.
+
+			var old = this.cursorId;
+			this._set("cursorId", value);
+			var model = this[this._refInModelProp];
+			if(!model){ return; }
+			if(old !== value){
+				if(lang.isArray(model)){
+					for(var i = 0; i < model.length; i++){
+						if(model[i][this.idProperty] == value){
+							this.set("cursorIndex", i);
+							return;
+						}
+					}
+					this._set("cursorIndex", -1);
+				}else{
+					for(var s in model){
+						if(model[s][this.idProperty] == value){
+							this.set("cursorIndex", s);
+							return;
+						}
+					}
+					this._set("cursorIndex", "");
+				}
+			}
+		},
+
+		_setCursorIndexAttr: function(/*Number*/ value){
+			// summary:
+			//		Handler for calls to set("cursorIndex", val).
+			// description:
+			//		Updates cursor, cursorId, cursorIndex properties internally and call watch callbacks for them.
+
+			this._set("cursorIndex", value);
+			if(!this[this._refInModelProp]){ return; }
+			this.set(this._refCursorProp, this[this._refInModelProp][value]);
+			this.set("cursorId", this[this._refInModelProp][value] && this[this._refInModelProp][value][this.idProperty]);
+		},
+
+		hasControllerProperty: function(/*String*/ name){
+			// summary:
+			//		Returns true if this controller itself owns the given property.
+			// name: String
+			//		The property name.
+
+			return this.inherited(arguments) || name == this._refCursorProp;
+		}
+	});
+});
diff --git a/dojox/mvc/ModelRefController.js b/dojox/mvc/ModelRefController.js
new file mode 100644
index 0000000..0cc725b
--- /dev/null
+++ b/dojox/mvc/ModelRefController.js
@@ -0,0 +1,198 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/Stateful",
+	"./_Controller"
+], function(array, declare, lang, Stateful, _Controller){
+	return declare("dojox.mvc.ModelRefController", _Controller, {
+		// summary:
+		//		A controller that keeps a reference to dojo/Stateful-based data model.
+		// description:
+		//		Does the following on behalf of such model:
+		//
+		//		- Provides data from model via dojo/Stateful get() interface
+		//		- Stores data to model via dojo/Stateful set() interface
+		//		- Watches for change in model via dojo/Stateful watch() interface (The callback is called when there is a change in data model, as well as when the data model itself is replaced with different one)
+		//
+		//		Can also be used to do some application-specific stuffs upon change in properties in model, by defining setter functions. 
+		//		Doing so will help keep models and widgets free from application-specific logic, and will help keep application logic free from specifics of models and widgets.
+		//		Such kind of setter functions can be defined in the same manner as widgets (_setXXXAttr()).
+		//
+		//		NOTE - If this class is used with a widget by data-dojo-mixins, make sure putting the widget in data-dojo-type and putting this class to data-dojo-mixins.
+		// example:
+		//		The text box refers to "value" property in the controller (with "ctrl" ID).
+		//		The controller provides the "value" property on behalf of the model ("model" property in the controller).
+		//		Two seconds later, the text box changes from "Foo" to "Bar" as the controller changes the data model it refers to.
+		// |		<html>
+		// |			<head>
+		// |				<script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script>
+		// |				<script type="text/javascript">
+		// |					require([
+		// |						"dojo/parser", "dojo/Stateful", "dijit/registry",
+		// |						"dijit/form/TextBox", "dojox/mvc/ModelRefController", "dojo/domReady!"
+		// |					], function(parser, Stateful, registry){
+		// |						modelFoo = new Stateful({value: "Foo"});
+		// |						modelBar = new Stateful({value: "Bar"});
+		// |						setTimeout(function(){ registry.byId("ctrl").set("model", modelBar); }, 2000);
+		// |						parser.parse();
+		// |					});
+		// |				</script>
+		// |			</head>
+		// |			<body>
+		// |				<script type="dojo/require">at: "dojox/mvc/at"</script>
+		// |				<span id="ctrl" data-dojo-type="dojox/mvc/ModelRefController" data-dojo-props="model: modelFoo"></span>
+		// |				<input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-props="value: at('widget:ctrl', 'value')">
+		// |			</body>
+		// |		</html>
+
+		// ownProps: Object
+		//		List of property names owned by this controller, instead of the data model.
+		ownProps: null,
+
+		// _refModelProp: String
+		//		The property name for the data model.
+		_refModelProp: "model",
+
+		// _refInModelProp: String
+		//		The property name for the data model, used as the input.
+		//		Used when this controller needs data model (as input) that is different from the data model this controller provides.
+		_refInModelProp: "model",
+
+		// model: dojo/Stateful
+		//		The data model.
+		model: null,
+
+		postscript: function(/*Object?*/ params, /*DomNode|String?*/ srcNodeRef){
+			// summary:
+			//		Sets _relTargetProp so that the property specified by _refModelProp is used for relative data binding.
+
+			this._relTargetProp = (params || {})._refModelProp || this._refModelProp;
+			this.inherited(arguments);
+		},
+
+		get: function(/*String*/ name){
+			// summary:
+			//		If getter function is there, use it. Otherwise, get the data from data model of this object.
+			// name: String
+			//		The property name.
+
+			if(!this.hasControllerProperty(name)){
+				var model = this[this._refModelProp];
+				return !model ? void 0 : model.get ? model.get(name) : model[name];
+			}
+			return this.inherited(arguments);
+		},
+
+		_set: function(/*String*/ name, /*Anything*/ value){
+			// summary:
+			//		Set the value to the data model or to this object.
+			// name: String
+			//		The property name.
+			// value: Anything
+			//		The property value.
+
+			if(!this.hasControllerProperty(name)){
+				var model = this[this._refModelProp];
+				model && (model.set ? model.set(name, value) : (model[name] = value));
+				return this;
+			}
+			return this.inherited(arguments);
+		},
+
+		watch: function(/*String?*/ name, /*Function*/ callback){
+			// summary:
+			//		Watch a property in the data model or in this object.
+			// name: String?
+			//		The property name.
+			// callback: Function
+			//		The callback function.
+
+			if(this.hasControllerProperty(name)){
+				return this.inherited(arguments);
+			}
+
+			if(!callback){
+				callback = name;
+				name = null;
+			}
+
+			var hm = null, hp = null, _self = this;
+
+			function watchPropertiesInModel(/*dojo/Stateful*/ model){
+				// summary:
+				//		Watch properties in referred model.
+				// model: dojo/Stateful
+				//		The model to watch for.
+
+				// Unwatch properties of older model.
+				if(hp){ hp.unwatch(); }
+				// Watch properties of newer model.
+				if(model && lang.isFunction(model.set) && lang.isFunction(model.watch)){
+					hp = model.watch.apply(model, (name ? [name] : []).concat([function(name, old, current){ callback.call(_self, name, old, current); }]));
+				}
+			}
+
+			function reflectChangeInModel(/*dojo/Stateful*/ old, /*dojo/Stateful*/ current){
+				// summary:
+				//		Upon change in model, detect change in properties, and call watch callbacks.
+				// old: dojo/Stateful
+				//		The older model.
+				// current: dojo/Stateful
+				//		The newer model.
+
+				// Gather list of properties to notify change in value as model changes.
+				var props = {};
+				if(!name){
+					// If all properties are being watched, find out all properties from older model as well as from newer model.
+					array.forEach([old, current], function(model){
+						var list = model && model.get("properties");
+						if(list){
+							// If the model explicitly specifies the list of properties, use it.
+							array.forEach(list, function(item){
+								if(!_self.hasControllerProperty(item)){ props[item] = 1; }
+							});
+						}else{
+							// Otherwise, iterate through own properties.
+							for(var s in model){
+								if(model.hasOwnProperty(s) && !_self.hasControllerProperty(s)){ props[s] = 1; }
+							}
+						}
+					});
+				}else{
+					props[name] = 1;
+				}
+
+				// Call watch callbacks for properties.
+				for(var s in props){
+					callback.call(_self, s, !old ? void 0 : old.get ? old.get(s) : old[s], !current ? void 0 : current.get ? current.get(s) : current[s]);
+				}
+			}
+
+			// Watch for change in model.
+			hm = Stateful.prototype.watch.call(this, this._refModelProp, function(name, old, current){
+				if(old === current){ return; }
+				reflectChangeInModel(old, current);
+				watchPropertiesInModel(current);
+			});
+
+			// Watch for properties in model.
+			watchPropertiesInModel(this.get(this._refModelProp));
+
+			var h = {};
+			h.unwatch = h.remove = function(){
+				if(hp){ hp.unwatch(); hp = null; } if(hm){ hm.unwatch(); hm = null; }
+			};
+			return h; // dojo/handle
+		},
+
+		hasControllerProperty: function(/*String*/ name){
+			// summary:
+			//		Returns true if this controller itself owns the given property.
+			// name: String
+			//		The property name.
+
+			return name == "_watchCallbacks" || name == this._refModelProp || name == this._refInModelProp || (name in (this.ownProps || {})) || (name in this.constructor.prototype) || /^dojoAttach(Point|Event)$/i.test(name); // Let dojoAttachPoint/dojoAttachEvent be this controller's property to support <span data-dojo-type="dojox/mvc/ModelRefController" data-dojo-attach-point="controllerNode"> in widgets-in-template
+		}
+	});
+});
diff --git a/dojox/mvc/Output.js b/dojox/mvc/Output.js
old mode 100755
new mode 100644
index 1ba6ec2..a279c0c
--- a/dojox/mvc/Output.js
+++ b/dojox/mvc/Output.js
@@ -2,15 +2,11 @@ define([
 	"dojo/_base/declare",
 	"dojo/_base/lang",
 	"dojo/dom",
-	"dijit/_WidgetBase"
-], function(declare, lang, dom, _WidgetBase){
-	/*=====
-		declare = dojo.declare;
-		dom = dojo.dom;
-		_WidgetBase = dijit._WidgetBase;
-	=====*/
+	"dijit/_WidgetBase",
+	"dojo/regexp"
+], function(declare, lang, dom, _WidgetBase, regexp){
 
-	return declare("dojox.mvc.Output", [_WidgetBase], {
+	return declare("dojox.mvc.Output", _WidgetBase, {
 		// summary:
 		//		A simple widget that displays templated output, parts of which may
 		//		be data-bound.
@@ -18,13 +14,23 @@ define([
 		// description:
 		//		Simple output example:
 		//
-		//		|  <span dojoType="dojox.mvc.Output" ref="model.balance">
+		//		|  <span data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(model, 'balance')"></span>
+		//
+		//		Another simple output example:
+		//
+		//		|  <span data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(model, 'balance')">
 		//		|    Your balance is: ${this.value}
 		//		|  </span>
 		//
+		//
 		//		The output widget being data-bound, if the balance changes in the
-		//		dojox.mvc.StatefulModel, the content within the <span> will be
+		//		model, the content within the `<span>` will be
 		//		updated accordingly.
+
+		// exprchar:  Character
+		//		Character to use for a substitution expression, for a substitution string like ${this.value}
+		//		If this class is declared in a template HTML and exprchar is used in in-line template of this class, something other than `$` should be specified to avoid conflict with exprchar of outer-template.
+		exprchar: '$',
 	
 		// templateString: [private] String
 		//		The template or data-bound output content.
@@ -44,6 +50,10 @@ define([
 		set: function(name, value){
 			// summary:
 			//		Override and refresh output on value change.
+			// name:
+			//		The property to set.
+			// value:
+			//		The value to set in the property.
 			this.inherited(arguments);
 			if(name === "value"){
 				this._output();
@@ -79,10 +89,13 @@ define([
 				if(!value){return "";}
 				var exp = value.substr(2);
 				exp = exp.substr(0, exp.length - 1);
-				with(pThis){return eval(exp) || "";}
+				with(pThis){
+					var val = eval(exp);
+					return (val || val == 0 ? val : "");
+				}
 			};
 			transform = lang.hitch(this, transform);
-			return tmpl.replace(/\$\{.*?\}/g,
+			return tmpl.replace(new RegExp(regexp.escapeString(this.exprchar)+"(\{.*?\})","g"),
 				function(match, key, format){
 					return transform(match, key).toString();
 				});
diff --git a/dojox/mvc/README b/dojox/mvc/README
old mode 100755
new mode 100644
index f4b34a4..8f9d703
--- a/dojox/mvc/README
+++ b/dojox/mvc/README
@@ -9,6 +9,7 @@ Project state: experimental (code and API subject to change in future releases)
 Credits:
        Rahul Akolkar (original author)
        Ed Chatelain
+       Akira Sudoh
        Charlie Wiecha
 
 -------------------------------------------------------------------------------
@@ -26,7 +27,7 @@ This project is useful across form factors. For example, it may be used with
 dijit as well as dojox.mobile.
 
 We begin by introducing a first-class client-side data model based on
-dojo.Stateful and extending Dojo Form widgets with support for the
+dojo/Stateful and extending Dojo Form widgets with support for the
 Model-View-Control (MVC) pattern key to separating data from presentation in
 user interface design. This basic MVC pattern allows for the flexible reuse of
 each of the Model, View, and Control artifacts by application authors in
@@ -41,8 +42,8 @@ such as:
 
 For more, see descriptive class documentation at the top of the following
 files:
-dojox/mvc/StatefulModel.js
-dojox/mvc/_DataBindingMixin.js
+dojox/mvc/at.js
+dojox/mvc/sync.js
 
 For an introductory page on the included samples, see:
 dojox/mvc/tests/mvc_index.html
@@ -53,8 +54,8 @@ dojox/mvc/tests/mobile/demo/demo.html
 -------------------------------------------------------------------------------
 Dependencies:
 
-    Dojo Core (base, dojo.Stateful)
-    Dijit (dijit._WidgetBase, dijit.form.*)
+    Dojo Core (base, dojo/Stateful)
+    Dijit (dijit/_WidgetBase, dijit/form.*)
 
 -------------------------------------------------------------------------------
 Documentation:
@@ -75,7 +76,7 @@ Install into the following directory structure:
 
 ...which should be at the same level as your Dojo checkout.
 
-then dojo.require("dojox.mvc") in your application to load basic support for
+then add the requires for the "dojox/mvc/at" or one of the other "dojox/mvc/xxx" classes in your application to load support for
 data bindings. Other components (such as MVC containers i.e. Group, Repeat)
 should be required as per application need.
 
diff --git a/dojox/mvc/Repeat.js b/dojox/mvc/Repeat.js
old mode 100755
new mode 100644
index 607ed89..ad8c23c
--- a/dojox/mvc/Repeat.js
+++ b/dojox/mvc/Repeat.js
@@ -1,22 +1,25 @@
 define([
 	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/sniff",
+	"dojo/_base/window",
 	"dojo/dom",
+	"dojo/dom-construct",
+	"dojo/_base/array",
+	"dojo/query",
+	"dojo/when",
+	"dijit/registry",
 	"./_Container"
-], function(declare, dom, _Container){
-	/*=====
-		declare = dojo.declare;
-		dom = dojo.dom;
-		_Container = dojox.mvc._Container;
-	=====*/
-
-	return declare("dojox.mvc.Repeat", [_Container], {
+], function(declare, lang, has, win, dom, domconstruct, array, query, when, registry, _Container){
+
+	return declare("dojox.mvc.Repeat", _Container, {
 		// summary:
 		//		A model-bound container which binds to a collection within a data model
 		//		and produces a repeating user-interface from a template for each
 		//		iteration within the collection.
 		//
 		// description:
-		//		A repeat is bound to an intermediate dojo.Stateful node corresponding
+		//		A repeat is bound to an intermediate dojo/Stateful node corresponding
 		//		to an array in the data model. Child dijits or custom view components
 		//		inside it inherit their parent data binding context from it.
 
@@ -30,77 +33,184 @@ define([
 		//		model. Then, the following CRUD-style UI displays all the names in
 		//		the search results in text boxes where they may be updated or such.
 		//
-		//		|	<div dojoType="dojox.mvc.Repeat" ref="Results">
-		//		|		<div class="row" dojoType="dojox.mvc.Group" ref="${this.index}">
+		//		|	<div dojoType="dojox/mvc/Repeat" ref="Results">
+		//		|		<div class="row" dojoType="dojox/mvc/Group" ref="${this.index}">
 		//		|			<label for="nameInput${this.index}">Name:</label>
-		//		|			<input dojoType="dijit.form.TextBox" id="nameInput${this.index}" ref="'Name'"></input>
+		//		|			<input dojoType="dijit/form/TextBox" id="nameInput${this.index}" ref="'Name'"></input>
 		//		|		</div>
 		//		|	</div>
 		index : 0,
 
+		// useParent: String
+		//		id of the DOM node to use as the parent for the repeating items, similar to useParentId processed a little differently 
+		useParent : "",
+		
+		// removeRepeatNode: boolean
+		//		When true the dom node for the Repeat and Groups within the Repeat
+		//		will be removed, their children will be placed into the parent node 
+		//		of the Repeat node.  This should be set to true when working with 
+		//		a Repeat inside of a dojox.mobile list.		
+		removeRepeatNode : false,
+
+		// children: dojox/mvc/StatefulArray
+		//		The array of data model that is used to render child nodes.
+		children: null,
+
+		// _relTargetProp: String
+		//		The name of the property that is used by child widgets for relative data binding.
+		_relTargetProp : "children",
+
+		startup: function(){
+			// This code needed for ticket 14423 is using removeRepeatNode to work with mobile.lists
+			// this.select and this.onCheckStateChanged are called by ListItem so they need to be set
+			// but it seems like a bit of a hack.
+			if(this.removeRepeatNode){				
+				var parent = null;
+				if(lang.isFunction(this.getParent)){
+					if(this.getParent()){
+						this.select = this.getParent().select;
+						this.onCheckStateChanged = this.getParent().onCheckStateChanged;
+					}
+				}			
+			}
+
+			this.inherited(arguments);
+			this._setChildrenAttr(this.children);
+		},
+
 		// summary:
 		//		Override and save template from body.
 		postscript: function(params, srcNodeRef){
-			this.srcNodeRef = dom.byId(srcNodeRef);
+			//this.srcNodeRef = dom.byId(srcNodeRef);
+			if(this.useParent && dom.byId(this.useParent)){
+				this.srcNodeRef = dom.byId(this.useParent);				
+			} else{
+				this.srcNodeRef = dom.byId(srcNodeRef);
+			}
 			if(this.srcNodeRef){
-				if(this.templateString == ""){ // only overwrite templateString if it has not been set
-					this.templateString = this.srcNodeRef.innerHTML;
+				var prop = this._attachTemplateNodes ? "inlineTemplateString" : "templateString";
+				if(this[prop] == ""){ // only overwrite templateString if it has not been set
+					this[prop] = this.srcNodeRef.innerHTML;
 				}
-				this.srcNodeRef.innerHTML = "";
+				try{
+					this.srcNodeRef.innerHTML = "";
+				}catch(e){
+					while(this.srcNodeRef.firstChild){ this.srcNodeRef.removeChild(this.srcNodeRef.firstChild); }
+				}
+
 			}
 			this.inherited(arguments);
 		},
 
 		////////////////////// PRIVATE METHODS ////////////////////////
 
-		_updateBinding: function(name, old, current){
+		_setChildrenAttr: function(/*dojo/Stateful*/ value){
 			// summary:
-			//		Rebuild repeating UI if data binding changes.
-			// tags:
-			//		private
-			this.inherited(arguments);
-			this._buildContained();
+			//		Handler for calls to set("children", val).
+			// description:
+			//		Sets "ref" property so that child widgets can refer to, and then rebuilds the children.
+
+			var children = this.children;
+			this._set("children", value);
+			// this.binding is the resolved ref, so not matching with the new value means change in repeat target.
+			if(this.binding != value){
+				this.set("ref", value);
+			}
+			if(this._started && (!this._builtOnce || children != value)){
+				this._builtOnce = true;
+				this._buildContained(value);
+			}
 		},
 
-		_buildContained: function(){
+		_buildContained: function(/*dojox/mvc/StatefulArray*/ children){
 			// summary:
 			//		Destroy any existing contained view, recreate the repeating UI
 			//		markup and parse the new contents.
+			// children: dojox/mvc/StatefulArray
+			//		The array of child widgets.
 			// tags:
 			//		private
 
+			if(!children){ return; }
+
 			// TODO: Potential optimization: only create new widgets for insert, only destroy for delete.
+			if(this.useParent && dom.byId(this.useParent)){
+				this.srcNodeRef = dom.byId(this.useParent);				
+			}
+
 			this._destroyBody();
-			this._updateAddRemoveWatch();
+			this._updateAddRemoveWatch(children);
+
+			var insert = [], prop = this._attachTemplateNodes ? "inlineTemplateString" : "templateString";
+			for(this.index = 0; lang.isFunction(children.get) ? children.get(this.index) : children[this.index]; this.index++){
+				insert.push(this._exprRepl(this[prop]));
+			}
 
-			var insert = "";
-			for(this.index = 0; this.get("binding").get(this.index); this.index++){
-				insert += this._exprRepl(this.templateString);
+			var repeatNode = this.containerNode || this.srcNodeRef || this.domNode;
+			if(has("ie") && /^(table|tbody)$/i.test(repeatNode.tagName)){
+				var div = win.doc.createElement("div");
+				div.innerHTML = "<table><tbody>" + insert.join("") + "</tbody></table>";
+				for(var tbody = div.getElementsByTagName("tbody")[0]; tbody.firstChild;){
+					repeatNode.appendChild(tbody.firstChild);
+				}
+			}else if(has("ie") && /^td$/i.test(repeatNode.tagName)){
+				var div = win.doc.createElement("div");
+				div.innerHTML = "<table><tbody><tr>" + insert.join("") + "</tr></tbody></table>";
+				for(var tr = div.getElementsByTagName("tr")[0]; tr.firstChild;){
+					repeatNode.appendChild(tr.firstChild);
+				}
+			}else{
+				repeatNode.innerHTML = insert.join("");
 			}
-			var repeatNode = this.srcNodeRef || this.domNode;
-			repeatNode.innerHTML = insert;
 
 			// srcNodeRef is used in _createBody, so in the programmatic create case where repeatNode was set  
 			// from this.domNode we need to set srcNodeRef from repeatNode
 			this.srcNodeRef = repeatNode;
 
-			this._createBody();
+			var _self = this;
+
+			when(this._createBody(), function(){
+				if(!_self.removeRepeatNode){ return; }
+				
+				var repeatnode = _self.domNode;
+				if(!_self.savedParentId && _self.domNode.parentNode && _self.domNode.parentNode.id){
+					_self.savedParentId = _self.domNode.parentNode.id;
+				}
+				var repeatParent = dom.byId(_self.savedParentId);			
+				if(repeatnode && repeatnode.children){
+					var t3 = registry.findWidgets(repeatnode);
+					var parentcnt = t3.length;
+					for(var j = parentcnt;j > 0;j--){
+						if(t3[j-1].declaredClass == "dojox.mvc.Group"){
+							var cnt = repeatnode.children[j-1].children.length;
+							var selForList = registry.byId(repeatParent.id).select;
+							for(var i = cnt;i > 0;i--){
+								registry.byId(repeatnode.children[j-1].id).select = selForList;
+								domconstruct.place(repeatnode.children[j-1].removeChild(repeatnode.children[j-1].children[i-1]), repeatParent, "first");
+							}							
+						}else{
+							domconstruct.place(repeatnode.removeChild(repeatnode.children[j-1]), repeatParent, "first");							
+						}
+					}
+					domconstruct.destroy(repeatnode);
+				}
+			});
 		},
 
-		_updateAddRemoveWatch: function(){
+		_updateAddRemoveWatch: function(/*dojo/Stateful*/ children){
 			// summary:
 			//		Updates the watch handle when binding changes.
+			// children: dojo/Stateful
+			//		The array of child widgets.
 			// tags:
 			//		private
 			if(this._addRemoveWatch){
 				this._addRemoveWatch.unwatch();
 			}
 			var pThis = this;
-			this._addRemoveWatch = this.get("binding").watch(function(name,old,current){
-				if(/^[0-9]+$/.test(name.toString())){
-					if(!old || !current){
-						pThis._buildContained();
-					} // else not an insert or delete, will get updated in above
+			this._addRemoveWatch = lang.isFunction(children.watchElements) && children.watchElements(function(idx, removals, adds){
+				if(!removals || !adds || removals.length || adds.length){
+					pThis._buildContained(pThis.children);
 				}
 			});
 		}
diff --git a/dojox/mvc/StatefulArray.js b/dojox/mvc/StatefulArray.js
new file mode 100644
index 0000000..0eb0a30
--- /dev/null
+++ b/dojox/mvc/StatefulArray.js
@@ -0,0 +1,203 @@
+define([
+	"dojo/_base/lang",
+	"dojo/Stateful"
+], function(lang, Stateful){
+	function update(/*dojox/mvc/StatefulArray*/ a){
+		// summary:
+		//		Set all array elements as stateful so that watch function runs.
+		// a: dojox/mvc/StatefulArray
+		//		The array.
+
+		// Notify change of elements.
+		if(a._watchElementCallbacks){
+			a._watchElementCallbacks();
+		}
+
+		return a; // dojox/mvc/StatefulArray
+	}
+
+	var StatefulArray = function(/*Anything[]*/ a){
+		// summary:
+		//		An inheritance of native JavaScript array, that adds dojo/Stateful capability.
+		// description:
+		//		Supported methods are:
+		//
+		//		- pop() - watchElements() notification is done for the removed elements. watch() notification is done for the length.
+		//		- push() - watchElements() notification is done for the added elements. watch() notification is done for the length.
+		//		- reverse() - watchElements() notification is done, indicating that the change affects all elements.
+		//		- shift() - watchElements() notification is done for the removed elements. watch() notification is done for the length.
+		//		- sort() - watchElements() notification is done, indicating that the change affects all elements.
+		//		- splice() - watchElements() notification is done for the removed/added elements. watch() notification is done for the length. Returns an instance of StatefulArray instead of the native array.
+		//		- unshift() - watchElements() notification is done for the added elements. watch() notification is done for the length.
+		//		- concat() - Returns an instance of StatefulArray instead of the native Array.
+		//		- join() - The length as well as the elements are obtained via stateful getters, instead of direct access.
+		//		- slice() - The length as well as the elements are obtained via stateful getters, instead of direct access.
+		//		- Setting an element to this array via set() - watch() notification is done for the new element as well as the new length.
+		//		- Setting a length to this array via set() - watchElements() notification is done for the removed/added elements. watch() notification is done for the new length.
+
+		var array = lang._toArray(a || []);
+		var ctor = StatefulArray;
+		array.constructor = ctor;
+		return lang.mixin(array, {
+			pop: function(){
+				return this.splice(this.get("length") - 1, 1)[0];
+			},
+			push: function(){
+				this.splice.apply(this, [this.get("length"), 0].concat(lang._toArray(arguments)));
+				return this.get("length");
+			},
+			reverse: function(){
+				return update([].reverse.apply(this, lang._toArray(arguments)));
+			},
+			shift: function(){
+				return this.splice(0, 1)[0];
+			},
+			sort: function(){
+				return update([].sort.apply(this, lang._toArray(arguments)));
+			},
+			splice: function(/*Number*/ idx, /*Number*/ n){
+				// summary:
+				//		Removes and then adds some elements to an array.
+				//		watchElements() notification is done for the removed/added elements.
+				//		watch() notification is done for the length.
+				//		Returns an instance of StatefulArray instead of the native array.
+				// idx: Number
+				//		The index where removal/addition should be done.
+				// n: Number
+				//		How many elements to be removed at idx.
+				// varargs: Anything[]
+				//		The elements to be added to idx.
+				// returns: dojox/mvc/StatefulArray
+				//		The removed elements.
+
+				var l = this.get("length");
+
+				idx += idx < 0 ? l : 0;
+
+				var p = Math.min(idx, l),
+				 removals = this.slice(idx, idx + n),
+				 adds = lang._toArray(arguments).slice(2);
+
+				// Do the modification in a native manner except for setting additions
+				[].splice.apply(this, [idx, n].concat(new Array(adds.length)));
+
+				// Set additions in a stateful manner
+				for(var i = 0; i < adds.length; i++){
+					this.set(p + i, adds[i]);
+				}
+
+				// Notify change of elements.
+				if(this._watchElementCallbacks){
+					this._watchElementCallbacks(idx, removals, adds);
+				}
+
+				// Notify change of length.
+				// Not calling the setter for "length" though, given removal/addition of array automatically changes the length.
+				if(this._watchCallbacks){
+					this._watchCallbacks("length", l, l - removals.length + adds.length);
+				}
+
+				return removals; // dojox/mvc/StatefulArray
+			},
+			unshift: function(){
+				this.splice.apply(this, [0, 0].concat(lang._toArray(arguments)));
+				return this.get("length");
+			},
+			concat: function(/*Array*/ a){
+				return new StatefulArray([].concat.apply(this, arguments));
+			},
+			join: function(/*String*/ sep){
+				// summary:
+				//		Returns a string joining string elements in a, with a separator.
+				// sep: String
+				//		The separator.
+
+				var list = [];
+				for(var l = this.get("length"), i = 0; i < l; i++){
+					list.push(this.get(i));
+				}
+				return list.join(sep); // String
+			},
+			slice: function(/*Number*/ start, /*Number*/ end){
+				// summary:
+				//		Returns partial elements of an array.
+				// start: Number
+				//		The index to begin with.
+				// end: Number
+				//		The index to end at. (a[end] won't be picked up)
+
+				var l = this.get("length");
+
+				start += start < 0 ? l : 0;
+				end = (end === void 0 ? l : end) + (end < 0 ? l : 0);
+
+				var slice = [];
+				for(var i = start || 0; i < Math.min(end, this.get("length")); i++){
+					slice.push(this.get(i));
+				}
+				return new StatefulArray(slice); // dojox/mvc/StatefulArray
+			},
+			watchElements: function(/*Function*/ callback){
+				// summary:
+				//		Watch for change in array elements.
+				// callback: Function
+				//		The callback function, which should take: The array index, the removed elements, and the added elements.
+
+				var callbacks = this._watchElementCallbacks, _self = this;
+				if(!callbacks){
+					callbacks = this._watchElementCallbacks = function(idx, removals, adds){
+						for(var list = [].concat(callbacks.list), i = 0; i < list.length; i++){
+							list[i].call(_self, idx, removals, adds);
+						}
+					};
+					callbacks.list = [];
+				}
+
+				callbacks.list.push(callback);
+
+				var h = {};
+				h.unwatch = h.remove = function(){
+					for(var list = callbacks.list, i = 0; i < list.length; i++){
+						if(list[i] == callback){
+							list.splice(i, 1);
+							break;
+						}
+					}
+				};
+				return h; // dojo/handle
+			}
+		}, Stateful.prototype, {
+			set: function(/*Number|String*/ name, /*Anything*/ value){
+				// summary:
+				//		Sets a new value to an array.
+				// name: Number|String
+				//		The property name.
+				// value: Anything
+				//		The new value.
+
+				if(name == "length"){
+					var old = this.get("length");
+					if(old < value){
+						this.splice.apply(this, [old, 0].concat(new Array(value - old)));
+					}else if(value > old){
+						this.splice.apply(this, [value, old - value]);
+					}
+					return this;
+				}else{
+					var oldLength = this.length;
+					Stateful.prototype.set.call(this, name, value);
+					if(oldLength != this.length){
+						Stateful.prototype.set.call(this, "length", this.length);
+					}
+					return this;
+				}
+			},
+			isInstanceOf: function(cls){
+				return Stateful.prototype.isInstanceOf.apply(this, arguments) || cls == StatefulArray;
+			}
+		});
+	};
+
+	StatefulArray._meta = {bases: [Stateful]}; // For isInstanceOf()
+	return lang.setObject("dojox.mvc.StatefulArray", StatefulArray);
+});
diff --git a/dojox/mvc/StatefulModel.js b/dojox/mvc/StatefulModel.js
old mode 100755
new mode 100644
index aab1535..4845726
--- a/dojox/mvc/StatefulModel.js
+++ b/dojox/mvc/StatefulModel.js
@@ -1,21 +1,24 @@
 define([
+	"dojo/_base/kernel",
 	"dojo/_base/lang",
 	"dojo/_base/array",
 	"dojo/_base/declare",
-	"dojo/Stateful"
-], function(lang, array, declare, Stateful){
-	/*=====
-		declare = dojo.declare;
-		Stateful = dojo.Stateful;
-	=====*/
+	"dojo/Stateful",
+	"./getStateful",
+	"./getPlainValue",
+	"./StatefulArray"
+], function(kernel, lang, array, declare, Stateful, getStateful, getPlainValue, StatefulArray){
+
+	kernel.deprecated("dojox/mvc/StatefulModel", "Use dojox/mvc/getStateful, dojox/mvc/getPlainValue, dojox/mvc/StatefulArray or one of the dojox/mvc/*RefControllers instead");
 
 	var StatefulModel = declare("dojox.mvc.StatefulModel", [Stateful], {
 		// summary:
-		//		The first-class native JavaScript data model based on dojo.Stateful
+		//		Deprecated.  Use dojox/mvc/getStateful, dojox/mvc/getPlainValue, dojox/mvc/StatefulArray or one of the dojox/mvc/*RefControllers instead.
+		//		The first-class native JavaScript data model based on dojo/Stateful
 		//		that wraps any data structure(s) that may be relevant for a view,
 		//		a view portion, a dijit or any custom view layer component.
 		//
-		//  description:
+		// description:
 		//		A data model is effectively instantiated with a plain JavaScript
 		//		object which specifies the initial data structure for the model.
 		//
@@ -31,43 +34,45 @@ define([
 		//		|		]
 		//		|	};
 		//		|
-		//		|	var model = dojox.mvc.newStatefulModel({ data : struct });
+		//		|	var model = dojox/mvc.newStatefulModel({ data : struct });
 		//
 		//		The simple example above shows an inline plain JavaScript object
 		//		illustrating the data structure to prime the model with, however
 		//		the underlying data may be made available by other means, such as
-		//		from the results of a dojo.store or dojo.data query.
+		//		from the results of a dojo/store or dojo/data query.
 		//
 		//		To deal with stores providing immediate values or Promises, a
 		//		factory method for model instantiation is provided. This method
 		//		will either return an immediate model or a model Promise depending
 		//		on the nature of the store.
 		//
-		//		|	var model = dojox.mvc.newStatefulModel({ store: someStore });
+		//		|	var model = mvc.newStatefulModel({ store: someStore });
 		//
 		//		The created data model has the following properties:
 		//
 		//		- It enables dijits or custom components in the view to "bind" to
 		//		  data within the model. A bind creates a bi-directional update
 		//		  mechanism between the bound view and the underlying data:
-		//			- The data model is "live" data i.e. it maintains any updates
-		//			  driven by the view on the underlying data.
-		//			- The data model issues updates to portions of the view if the
-		//			  data they bind to is updated in the model. For example, if two
-		//			  dijits are bound to the same part of a data model, updating the
-		//			  value of one in the view will cause the data model to issue an
-		//			  update to the other containing the new value.
 		//
-		//		- The data model internally creates a tree of dojo.Stateful
+		//		a) The data model is "live" data i.e. it maintains any updates
+		//		driven by the view on the underlying data.
+		//
+		//		b) The data model issues updates to portions of the view if the
+		//		data they bind to is updated in the model. For example, if two
+		//		dijits are bound to the same part of a data model, updating the
+		//		value of one in the view will cause the data model to issue an
+		//		update to the other containing the new value.
+		//
+		//		- The data model internally creates a tree of dojo/Stateful
 		//		  objects that matches the input, which is effectively a plain
 		//		  JavaScript object i.e. "pure data". This tree allows dijits or
 		//		  other view components to bind to any node within the data model.
 		//		  Typically, dijits with simple values bind to leaf nodes of the
 		//		  datamodel, whereas containers bind to internal nodes of the
 		//		  datamodel. For example, a datamodel created using the object below
-		//		  will generate the dojo.Stateful tree as shown:
+		//		  will generate the dojo/Stateful tree as shown:
 		//
-		//		|	var model = dojox.mvc.newStatefulModel({ data : {
+		//		|	var model = dojox/mvc/newStatefulModel({ data : {
 		//		|		prop1	: "foo",
 		//		|		prop2	: {
 		//		|			leaf1	: "bar",
@@ -75,19 +80,19 @@ define([
 		//		|		}
 		//		|	}});
 		//		|
-		//		|	// The created dojo.Stateful tree is illustrated below (all nodes are dojo.Stateful objects)
+		//		|	// The created dojo/Stateful tree is illustrated below (all nodes are dojo/Stateful objects)
 		//		|	//
-		//		|	//	                o  (root node)
-		//		|	//	               / \
+		//		|	//		            o  (root node)
+		//		|	//		           / \
 		//		|	//	 (prop1 node) o   o (prop2 node)
-		//		|	//	                 / \
+		//		|	//		             / \
 		//		|	//	   (leaf1 node)	o   o (leaf2 node)
 		//		|	//
 		//		|	// The root node is accessed using the expression "model" (the var name above). The prop1
 		//		|	// node is accessed using the expression "model.prop1", the leaf2 node is accessed using
 		//		|	// the expression "model.prop2.leaf2" and so on.
 		//
-		//		- Each of the dojo.Stateful nodes in the model may store data as well
+		//		- Each of the dojo/Stateful nodes in the model may store data as well
 		//		  as associated "meta-data", which includes things such as whether
 		//		  the data is required or readOnly etc. This meta-data differs from
 		//		  that maintained by, for example, an individual dijit in that this
@@ -95,7 +100,7 @@ define([
 		//		  datamodel-level constraints that span multiple dijits or even
 		//		  additional criteria such as server-side computations.
 		//
-		//		- When the model is backed by a dojo.store or dojo.data query, the
+		//		- When the model is backed by a dojo/store or dojo/data query, the
 		//		  client-side updates can be persisted once the client is ready to
 		//		  "submit" the changes (which may include both value changes or
 		//		  structural changes - adds/deletes). The datamodel allows control
@@ -116,45 +121,32 @@ define([
 		//		To illustrate, the following is the "Hello World" of such data-bound
 		//		widget examples:
 		//
-		//		|	<script>
-		//		|		dojo.require("dojox.mvc");
-		//		|		dojo.require("dojo.parser");
-		//		|		var model;
-		//		|		dojo.addOnLoad(function(){
-		//		|			model = dojox.mvc.newStatefulModel({ data : {
-		//		|				hello : "Hello World"
-		//		|			}});
-		//		|			dojo.parser.parse();
-		//		|		}
-		//		|	</script>
-		//		|
-		//		|	<input id="helloInput" dojoType="dijit.form.TextBox"
-		//		|		ref="model.hello">
-		//
-		//		or
 		//
 		//		|	<script>
 		//		|		var model;
-		//		|		require(["dojox/mvc", "dojo/parser"], function(dxmvc, parser){
-		//		|			model = dojox.mvc.newStatefulModel({ data : {
+		//		|		require(["dojox/mvc", "dojo/parser"], function(mvc, parser){
+		//		|			model = mvc.newStatefulModel({ data : {
 		//		|				hello : "Hello World"
 		//		|			}});
 		//		|			parser.parse();
 		//		|		});
 		//		|	</script>
 		//		|
-		//		|	<input id="helloInput" data-dojo-type="dijit.form.TextBox"
+		//		|	<input id="helloInput" data-dojo-type="dijit/form/TextBox"
 		//		|		data-dojo-props="ref: 'model.hello'">
 		//
 		//		Such data binding awareness for dijits is added by extending the
-		//		dijit._WidgetBase class to include data binding capabilities
-		//		provided by dojox.mvc._DataBindingMixin, and this class declares a
-		//		dependency on dojox.mvc._DataBindingMixin.
+		//		dijit/_WidgetBase class to include data binding capabilities
+		//		provided by dojox/mvc/_DataBindingMixin, and this class declares a
+		//		dependency on dojox/mvc/_DataBindingMixin.
 		//
 		//		The presence of a data model and the data-binding capabilities
 		//		outlined above support the flexible development of a number of MVC
 		//		patterns on the client. As an example, CRUD operations can be
 		//		supported with minimal application code.
+		//
+		// tags:
+		//		deprecated
 	
 		// data: Object
 		//		The plain JavaScript object / data structure used to initialize
@@ -163,7 +155,7 @@ define([
 		//		Either data or store property must be provided.
 		data: null,
 
-		// store: dojo.store.DataStore
+		// store: dojo/store/DataStore
 		//		The data store from where to retrieve initial data for this model.
 		//		An optional query may also be provided along with this store.
 		//		Either data or store property must be provided.
@@ -196,16 +188,17 @@ define([
 			}
 		},
 
-		commit: function(/*"dojo.store.DataStore?"*/ store){
+		commit: function(/*"dojo/store/DataStore?"*/ store){
 			// summary:
 			//		Commits this data model:
+			//
 			//		- Saves the current state such that a subsequent reset will not
 			//		  undo any prior changes.
 			//		- Persists client-side changes to the data store, if a store
 			//		  has been supplied as a parameter or at instantiation.
-			//	store:
-			//		dojo.store.DataStore
-			//		Optional dojo.store.DataStore to use for this commit, if none
+			// store:
+			//		dojo/store/DataStore
+			//		Optional dojo/store/DataStore to use for this commit, if none
 			//		provided but one was provided at instantiation time, that store
 			//		will be used instead.
 			this._commit();
@@ -223,71 +216,48 @@ define([
 			//		Object
 			//		The plain JavaScript object representation of the data in this
 			//		model.
-			var ret = {};
-			var nested = false;
-			for(var p in this){
-				if(this[p] && lang.isFunction(this[p].toPlainObject)){
-					if(!nested && typeof this.get("length") === "number"){
-						ret = [];
-					}
-					nested = true;
-					ret[p] = this[p].toPlainObject();
-				}
-			}
-			if(!nested){
-				if(this.get("length") === 0){
-					ret = [];
-				}else{				
-					ret = this.value;
-				}
+			return getPlainValue(this, StatefulModel.getPlainValueOptions);
+		},
+
+		splice: function(/*Number*/ idx, /*Number*/ n){
+			// summary:
+			//		Removes and then adds some elements to this array.
+			//		Updates the removed/added elements, as well as the length, as stateful.
+			// idx: Number
+			//		The index where removal/addition should be done.
+			// n: Number
+			//		How many elements to be removed at idx.
+			// varargs: Anything[]
+			//		The elements to be added to idx.
+			// returns: dojox/mvc/StatefulArray
+			//		The removed elements.
+
+			var a = (new StatefulArray([])).splice.apply(this, lang._toArray(arguments));
+			for(var i = 0; i < a.length; i++){
+				(this._removals = this._removals || []).push(a[i].toPlainObject());
 			}
-			return ret;
+			return a;
 		},
 
-		add: function(/*String*/ name, /*dojo.Stateful*/ stateful){
+		add: function(/*String*/ name, /*dojo/Stateful*/ stateful){
 			// summary:
-			//		Adds a dojo.Stateful tree represented by the given
-			//		dojox.mvc.StatefulModel at the given property name.
-			//	name:
+			//		Adds a dojo/Stateful tree represented by the given
+			//		dojox/mvc/StatefulModel at the given property name.
+			// name:
 			//		The property name to use whose value will become the given
-			//		dijit.Stateful tree.
-			//	stateful:
-			//		The dojox.mvc.StatefulModel to insert.
+			//		dijit/Stateful tree.
+			// stateful:
+			//		The dojox/mvc/StatefulModel to insert.
 			// description:
 			//		In case of arrays, the property names are indices passed
-			//		as Strings. An addition of such a dojo.Stateful node
+			//		as Strings. An addition of such a dojo/Stateful node
 			//		results in right-shifting any trailing sibling nodes.
-			var n, n1, elem, elem1, save = new StatefulModel({ data : "" });
+
 			if(typeof this.get("length") === "number" && /^[0-9]+$/.test(name.toString())){
-				n = name;
-				if(!this.get(n)){
-					if(this.get("length") == 0 && n == 0){ // handle the empty array case
-						this.set(n, stateful);
-					} else {
-						n1 = n-1;
-						if(!this.get(n1)){
-							throw new Error("Out of bounds insert attempted, must be contiguous.");
-						}
-						this.set(n, stateful);
-					}
-				}else{
-					n1 = n-0+1;
-					elem = stateful;
-					elem1 = this.get(n1);
-					if(!elem1){
-						this.set(n1, elem);
-					}else{
-						do{
-							this._copyStatefulProperties(elem1, save);
-							this._copyStatefulProperties(elem, elem1);
-							this._copyStatefulProperties(save, elem);
-							this.set(n1, elem1); // for watchers
-							elem1 = this.get(++n1);
-						}while(elem1);
-						this.set(n1, elem);
-					}
+				if(this.get("length") < (name - 0)){
+					throw new Error("Out of bounds insert attempted, must be contiguous.");
 				}
-				this.set("length", this.get("length") + 1);
+				this.splice(name - 0, 0, stateful);
 			}else{
 				this.set(name, stateful);
 			}
@@ -295,40 +265,21 @@ define([
 
 		remove: function(/*String*/ name){
 			// summary:
-			//		Removes the dojo.Stateful tree at the given property name.
-			//	name:
+			//		Removes the dojo/Stateful tree at the given property name.
+			// name:
 			//		The property name from where the tree will be removed.
 			// description:
 			//		In case of arrays, the property names are indices passed
-			//		as Strings. A removal of such a dojo.Stateful node
+			//		as Strings. A removal of such a dojo/Stateful node
 			//		results in left-shifting any trailing sibling nodes.
-			var n, elem, elem1;
 			if(typeof this.get("length") === "number" && /^[0-9]+$/.test(name.toString())){
-				n = name;
-				elem = this.get(n);
-				if(!elem){
+				if(!this.get(name)){
 					throw new Error("Out of bounds delete attempted - no such index: " + n);
 				}else{
-					this._removals = this._removals || [];
-					this._removals.push(elem.toPlainObject());
-					n1 = n-0+1;
-					elem1 = this.get(n1);
-					if(!elem1){
-						this.set(n, undefined);
-						delete this[n];
-					}else{
-						while(elem1){
-							this._copyStatefulProperties(elem1, elem);
-							elem = this.get(n1++);
-							elem1 = this.get(n1);
-						}
-						this.set(n1-1, undefined);
-						delete this[n1-1];
-					}
-					this.set("length", this.get("length") - 1);
+					this.splice(name - 0, 1);
 				}
 			}else{
-				elem = this.get(name);
+				var elem = this.get(name);
 				if(!elem){
 					throw new Error("Illegal delete attempted - no such property: " + name);
 				}else{
@@ -364,39 +315,46 @@ define([
 			// summary:
 			//		Instantiates a new data model that view components may bind to.
 			//		This is a private constructor, use the factory method
-			//		instead: dojox.mvc.newStatefulModel(args)
-			//	args:
+			//		instead: dojox/mvc/newStatefulModel(args)
+			// args:
 			//		The mixin properties.
 			// description:
-			//		Creates a tree of dojo.Stateful objects matching the initial
+			//		Creates a tree of dojo/Stateful objects matching the initial
 			//		data structure passed as input. The mixin property "data" is
 			//		used to provide a plain JavaScript object directly representing
 			//		the data structure.
 			// tags:
 			//		private
-			var data = (args && "data" in args) ? args.data : this.data; 
+			var data = (args && "data" in args) ? args.data : this.data;
 			this._createModel(data);
 		},
 
 		//////////////////////// PRIVATE METHODS ////////////////////////
 
-		_createModel: function(/*Object*/ obj){
+		_createModel: function(/*Object*/ data){
 			// summary:
 			//		Create this data model from provided input data.
 			//	obj:
 			//		The input for the model, as a plain JavaScript object.
 			// tags:
 			//		private
-			if(lang.isObject(obj) && !(obj instanceof Date) && !(obj instanceof RegExp) && obj !== null){
-				for(var x in obj){
-					var newProp = new StatefulModel({ data : obj[x] });
-					this.set(x, newProp);
-				}
-				if(lang.isArray(obj)){
-					this.set("length", obj.length);
+
+			if(data != null){
+				data = getStateful(data, StatefulModel.getStatefulOptions);
+				if(lang.isArray(data)){
+					// Some consumers of dojox/mvc/StatefulModel inherits it via dojo/declare(), where we cannot use array inheritance technique
+					// (dojo/declare() does not support return value in constructor)
+					this.length = 0;
+					[].splice.apply(this, data);
+				}else if(lang.isObject(data)){
+					for(var s in data){
+						if(data.hasOwnProperty(s)){
+							this[s] = data[s];
+						}
+					}
+				}else{
+					this.set("value", data);
 				}
-			}else{
-				this.set("value", obj);
 			}
 		},
 
@@ -414,13 +372,14 @@ define([
 			this.data = this.toPlainObject();
 		},
 
-		_saveToStore: function(/*"dojo.store.DataStore"*/ store){
+		_saveToStore: function(/*"dojo/store/DataStore"*/ store){
 			// summary:
 			//		Commit the current values to the data store:
+			//
 			//		- remove() any deleted entries
 			//		- put() any new or updated entries
-			//	store:
-			//		dojo.store.DataStore to use for this commit.
+			// store:
+			//		dojo/store/DataStore to use for this commit.
 			// tags:
 			//		private
 			if(this._removals){
@@ -437,23 +396,100 @@ define([
 			}else{
 				store.put(dataToCommit);
 			}
+		}
+	});
+
+	lang.mixin(StatefulModel, {
+		getStatefulOptions: {
+			// summary:
+			//		An object that defines how model object should be created from plain object hierarchy.
+
+			getType: function(/*Anything*/ v){
+				// summary:
+				//		Returns the type of the given value.
+				// v: Anything
+				//		The value.
+
+				return lang.isArray(v) ? "array" : v != null && {}.toString.call(v) == "[object Object]" ? "object" : "value"; // String
+			},
+
+			getStatefulArray: function(/*Anything[]*/ a){
+				// summary:
+				//		Create a stateful array from a plain array.
+				// a: Anything[]
+				//		The plain array.
+
+				var _self = this, statefularray = lang.mixin(new StatefulArray(array.map(a, function(item){ return getStateful(item, _self); })));
+				for(var s in StatefulModel.prototype){
+					if(s != "set"){ statefularray[s] = StatefulModel.prototype[s]; }
+				}
+				statefularray.data = a;
+				return statefularray;
+			},
+
+			getStatefulObject: function(/*Object*/ o){
+				// summary:
+				//		Create a stateful object from a plain object.
+				// o: Object
+				//		The plain object.
+
+				var object = new StatefulModel();
+				object.data = o;
+				for(var s in o){
+					object.set(s, getStateful(o[s], this));
+				}
+				return object; // dojox/mvc/StatefulModel
+			},
+
+			getStatefulValue: function(/*Anything*/ v){
+				// summary:
+				//		Create a stateful value from a plain value.
+				// v: Anything
+				//		The plain value.
+
+				var value = new StatefulModel();
+				value.data = v;
+				value.set("value", v);
+				return value;
+			}
 		},
 
-		_copyStatefulProperties: function(/*dojo.Stateful*/ src, /*dojo.Stateful*/ dest){
+		getPlainValueOptions: {
 			// summary:
-			//		Copy only the dojo.Stateful properties from src to dest (uses
-			//		duck typing).
-			//	src:
-			//		The source object for the copy.
-			//	dest:
-			//		The target object of the copy.
-			// tags:
-			//		private
-			for(var x in src){
-				var o = src.get(x);
-				if(o && lang.isObject(o) && lang.isFunction(o.get)){
-					dest.set(x, o);
+			//		An object that defines how plain value should be created from model object.
+
+			getType: function(/*Anything*/ v){
+				// summary:
+				//		Returns the type of the given value.
+				// v: Anything
+				//		The value.
+
+				if(lang.isArray(v)){ return "array"; }
+				if(lang.isObject(v)){ // Primitive values may have their own properties
+					for(var s in v){
+						if(v.hasOwnProperty(s) && s != "value" && (v[s] || {}).get && (v[s] || {}).watch){
+							return "object";
+						}
+					}
 				}
+				return "value";
+			},
+
+			getPlainArray: function(/*dojox/mvc/StatefulArray*/ a){
+				return array.map(a, function(item){ return getPlainValue(item, this); }, this);
+			},
+
+			getPlainObject: function(/*dojox/mvc/StatefulModel*/ o){
+				var plain = {};
+				for(var s in o){
+					if(s == "_watchCallbacks" || (s in StatefulModel.prototype)){ continue; }
+					plain[s] = getPlainValue(o[s], this);
+				}
+				return plain;
+			},
+
+			getPlainValue: function(/*Anything*/ v){
+				return (v || {}).set && (v || {}).watch ? getPlainValue(v.value, this) : v;
 			}
 		}
 	});
diff --git a/dojox/mvc/StatefulSeries.js b/dojox/mvc/StatefulSeries.js
new file mode 100644
index 0000000..b4ee5a7
--- /dev/null
+++ b/dojox/mvc/StatefulSeries.js
@@ -0,0 +1,79 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojox/mvc/at"
+], function(darray, declare, lang, at){
+	return declare("dojox.mvc.StatefulSeries", null, {
+		// summary:
+		//		Chart data plugin ("series") that watches for properties specified in dojox/mvc/at handles in the given data.
+		//		At initialization, and when the properties are updated, creates the data from data given and updates the chart.
+		// example:
+		//		Two seconds later, the chart changes from 25%/25%/50% to 10%/10%/80%, as the data model changes:
+		// |		<html>
+		// |			<head>
+		// |				<script type="text/javascript" src="/path/to/dojo/dojo.js"></script>
+		// |				<script>
+		// |					require([
+		// |						"dojo/Stateful", "dojox/mvc/at", "dojox/mvc/StatefulSeries",
+		// |						"dojox/charting/Chart", "dojox/charting/themes/PlotKit/blue", "dojox/charting/plot2d/Pie",
+		// |						"dojo/domReady!"
+		// |					], function(Stateful, at, StatefulSeries, Chart, blue){
+		// |						var model = new Stateful({First: 25, Second: 25, Third: 50});
+		// |						new Chart("chart")
+		// |						 .setTheme(blue)
+		// |						 .addPlot("default", {type: "Pie"})
+		// |						 .addSeries("default", new StatefulSeries([at(model, "First"), at(model, "Second"), at(model, "Third")])).render();
+		// |						setTimeout(function(){ model.set("First", 10); model.set("Second", 10); model.set("Third", 80); }, 2000);
+		// |					});
+		// |				</script>
+		// |			</head>
+		// |			<body>
+		// |				<div id="chart"></div>
+		// |			</body>
+		// |		</html>
+
+		constructor: function(/*Anything[]*/ items){
+			var _self = this;
+			function pushDataChanges(){
+				if(_self.series){
+					_self.series.chart.updateSeries(_self.series.name, _self);
+					_self.series.chart.delayedRender();
+				}
+			}
+			this._handles = [];
+			this.data = darray.map(items, function(item, idx){
+				if((item || {}).atsignature == "dojox.mvc.at"){
+					var target = item.target, targetProp = item.targetProp;
+					if(lang.isString(target)){
+						throw new Error("Literal-based dojox/mvc/at is not supported in dojox/mvc/StatefulSeries.");
+					}
+					if(item.bindDirection && !(item.bindDirection & at.from)){
+						console.warn("Data binding bindDirection option is ignored in dojox/mvc/StatefulSeries.");
+					}
+					if(targetProp && lang.isFunction(target.set) && lang.isFunction(target.watch)){
+						var converter = item.converter, formatFunc = (converter || {}).format && lang.hitch({target: target, source: this}, converter.format);
+						this._handles.push(target.watch(targetProp, function(name, old, current){
+							_self.data[idx] = formatFunc ? formatFunc(current) : current;
+							pushDataChanges();
+						}));
+					}
+					return !targetProp ? target : lang.isFunction(target.get) ? target.get(targetProp) : target[targetProp];
+				}else{
+					return item;
+				}
+			}, this);
+			pushDataChanges();
+		},
+
+		destroy: function(){
+			for(var h = null; h = this._handles.pop();){
+				h.unwatch();
+			}
+		},
+
+		setSeriesObject: function(series){
+			this.series = series;
+		}
+	});
+});
diff --git a/dojox/mvc/StoreRefController.js b/dojox/mvc/StoreRefController.js
new file mode 100644
index 0000000..6adad0f
--- /dev/null
+++ b/dojox/mvc/StoreRefController.js
@@ -0,0 +1,156 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/when",
+	"./getStateful",
+	"./ModelRefController"
+], function(declare, lang, when, getStateful, ModelRefController){
+	return declare("dojox.mvc.StoreRefController", ModelRefController, {
+		// summary:
+		//		A child class of dojox.mvc.ModelRefController, which keeps a reference to Dojo Object Store (in store property).
+		// description:
+		//		Has several methods to work with the store:
+		//
+		//		- queryStore(): Runs query() against the store, and creates a data model from retrieved data
+		//		- getStore(): Runs get() against the store, and creates a data model from retrieved data
+		//		- putStore(): Runs put() against the store
+		//		- addStore(): Runs add() against the store
+		//		- removeStore(): Runs remove() against the store
+		//
+		//		dojo.Stateful get()/set()/watch() interfaces in dojox.mvc.StoreRefController will work with the data model from queryStore() or getStore().
+		//
+		//		NOTE - If this class is used with a widget by data-dojo-mixins, make sure putting the widget in data-dojo-type and putting this class to data-dojo-mixins.
+		// example:
+		//		The text box refers to "value" property in the controller (with "ctrl" ID).
+		//		The controller provides the "value" property, from the data coming from data store ("store" property in the controller).
+		//		Two seconds later, the text box changes from "Foo" to "Bar" as the controller gets new data from data store.
+		// |		<html>
+		// |			<head>
+		// |				<script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script>
+		// |				<script type="text/javascript">
+		// |					require([
+		// |						"dojo/parser", "dojo/when", "dojo/store/Memory", "dijit/registry", "dojo/domReady!"
+		// |					], function(parser, when, Memory, registry){
+		// |						store = new Memory({data: [{id: "Foo", value: "Foo"}, {id: "Bar", value: "Bar"}]});
+		// |						when(parser.parse(), function(){
+		// |							registry.byId("ctrl").getStore("Foo");
+		// |							setTimeout(function(){ registry.byId("ctrl").getStore("Bar"); }, 2000);
+		// |						});
+		// |					});
+		// |				</script>
+		// |			</head>
+		// |			<body>
+		// |				<script type="dojo/require">at: "dojox/mvc/at"</script>
+		// |				<span id="ctrl" data-dojo-type="dojox.mvc.StoreRefController" data-dojo-props="store: store"></span>
+		// |				<input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-props="value: at('widget:ctrl', 'value')">
+		// |			</body>
+		// |		</html>
+
+		// store: dojo/store/*
+		//		The Dojo Object Store in use.
+		store: null,
+
+		// getStatefulOptions: dojox.mvc.getStatefulOptions
+		//		The options to get stateful object from plain value.
+		getStatefulOptions: null,
+
+		// _refSourceModelProp: String
+		//		The property name for the data model, that serves as the data source.
+		_refSourceModelProp: "model",
+
+		queryStore: function(/*Object*/ query, /*dojo/store/api/Store.QueryOptions?*/ options){
+			// summary:
+			//		Queries the store for objects.
+			// query: Object
+			//		The query to use for retrieving objects from the store.
+			// options: dojo/store/api/Store.QueryOptions?
+			//		The optional arguments to apply to the resultset.
+			// returns: dojo/store/api/Store.QueryResults
+			//		The results of the query, extended with iterative methods.
+
+			if(!(this.store || {}).query){ return; }
+			if(this._queryObserveHandle){ this._queryObserveHandle.cancel(); }
+
+			var _self = this,
+			 queryResult = this.store.query(query, options),
+			 result = when(queryResult, function(results){
+				if(_self._beingDestroyed){ return; }
+				results = getStateful(results, _self.getStatefulOptions);
+				_self.set(_self._refSourceModelProp, results);
+				return results;
+			});
+			if(result.then){
+				result = lang.delegate(result);
+			}
+			// For dojo/store/Observable, which adds a function to query result
+			for(var s in queryResult){
+				if(isNaN(s) && queryResult.hasOwnProperty(s) && lang.isFunction(queryResult[s])){
+					result[s] = queryResult[s];
+				}
+			}
+			return result;
+		},
+
+		getStore: function(/*Number*/ id, /*Object*/ options){
+			// summary:
+			//		Retrieves an object by its identity.
+			// id: Number
+			//		The identity to use to lookup the object.
+			// options: Object
+			//		The options for dojo/store.*.get().
+			// returns: Object
+			//		The object in the store that matches the given id.
+
+			if(!(this.store || {}).get){ return; }
+			if(this._queryObserveHandle){ this._queryObserveHandle.cancel(); }
+			var _self = this;
+			result = when(this.store.get(id, options), function(result){
+				if(_self._beingDestroyed){ return; }
+				result = getStateful(result, _self.getStatefulOptions);
+				_self.set(_self._refSourceModelProp, result);
+				return result;
+			});
+			return result;
+		},
+
+		putStore: function(/*Object*/ object, /*dojo/store/api/Store.PutDirectives?*/ options){
+			// summary:
+			//		Stores an object.
+			// object: Object
+			//		The object to store.
+			// options: dojo/store/api/Store.PutDirectives?
+			//		Additional metadata for storing the data.  Includes an "id" property if a specific id is to be used.
+			// returns: Number
+
+			if(!(this.store || {}).put){ return; }
+			return this.store.put(object, options);
+		},
+
+		addStore: function(object, options){
+			// summary:
+			//		Creates an object, throws an error if the object already exists.
+			// object: Object
+			//		The object to store.
+			// options: dojo/store/api/Store.PutDirectives?
+			//		Additional metadata for storing the data.  Includes an "id" property if a specific id is to be used.
+			// returns: Number
+
+			if(!(this.store || {}).add){ return; }
+			return this.store.add(object, options);
+		},
+
+		removeStore: function(/*Number*/ id, /*Object*/ options){
+			// summary:
+			//		Deletes an object by its identity
+			// id: Number
+			//		The identity to use to delete the object
+			// options: Object
+			//		The options for dojo/store/*.remove().
+			// returns: Boolean
+			//		Returns true if an object was removed, falsy (undefined) if no object matched the id.
+
+			if(!(this.store || {}).remove){ return; }
+			return this.store.remove(id, options);
+		}
+	});
+});
diff --git a/dojox/mvc/Templated.js b/dojox/mvc/Templated.js
new file mode 100644
index 0000000..09d5b02
--- /dev/null
+++ b/dojox/mvc/Templated.js
@@ -0,0 +1,34 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dijit/_WidgetBase",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"./at"
+], function(declare, lang, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin){
+	return declare("dojox.mvc.Templated", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+		// summary:
+		//		A templated widget, mostly the same as dijit/_Templated, but without deprecated features in it.
+
+		// bindings: Object|Function
+		//		The data binding declaration (or simple parameters) for child widgets.
+		bindings: null,
+
+		startup: function(){
+			// Code to support childBindings property in dojox/mvc/WidgetList, etc.
+			// This implementation makes sure childBindings is set before this widget starts up, as dijit/_WidgetsInTemplatedMixin starts up child widgets before it starts itself up.
+			var bindings = lang.isFunction(this.bindings) && this.bindings.call(this) || this.bindings;
+			for(var s in bindings){
+				var w = this[s], props = bindings[s];
+				if(w){
+					for(var prop in props){
+						w.set(prop, props[prop]);
+					}
+				}else{
+					console.warn("Widget with the following attach point was not found: " + s);
+				}
+			}
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dojox/mvc/WidgetList.js b/dojox/mvc/WidgetList.js
new file mode 100644
index 0000000..d57c689
--- /dev/null
+++ b/dojox/mvc/WidgetList.js
@@ -0,0 +1,286 @@
+define([
+	"require",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dijit/_Container",
+	"dijit/_WidgetBase",
+	"./Templated"
+], function(require, array, lang, declare, _Container, _WidgetBase, Templated){
+	var childTypeAttr = "data-mvc-child-type",
+	 childMixinsAttr = "data-mvc-child-mixins",
+	 childParamsAttr = "data-mvc-child-props",
+	 childBindingsAttr = "data-mvc-child-bindings",
+	 undef;
+
+	function evalParams(params){
+		return eval("({" + params + "})");
+	}
+
+	function unwatchElements(/*dojox/mvc/WidgetList*/ w){
+		for(var h = null; h = (w._handles || []).pop();){
+			h.unwatch();
+		}
+	}
+
+	function flatten(/*String[][]*/ a){
+		var flattened = [];
+		array.forEach(a, function(item){
+			[].push.apply(flattened, item);
+		});
+		return flattened;
+	}
+
+	function loadModules(/*dojo/Stateful[]*/ items, /*Function*/ callback){
+		// summary:
+		//		Load modules associated with an array of data.
+		// items: dojo/Stateful[]
+		//		The array of data.
+		// callback: Function
+		//		Then callback called when the modules have been loaded.
+
+		if(this.childClz){
+			callback(this.childClz);
+		}else if(this.childType){
+			var typesForItems = !lang.isFunction(this.childType) && !lang.isFunction(this.childMixins) ? [[this.childType].concat(this.childMixins && this.childMixins.split(",") || [])] :
+			 array.map(items, function(item){
+				var type = lang.isFunction(this.childType) ? this.childType.call(item, this) : this.childType,
+				 mixins = lang.isFunction(this.childMixins) ? this.childMixins.call(item, this) : this.childMixins;
+				return type ? [type].concat(lang.isArray(mixins) ? mixins : mixins ? mixins.split(",") : []) : ["dojox/mvc/Templated"];
+			}, this);
+			require(array.filter(array.map(flatten(typesForItems), function(type){ return lang.getObject(type) ? undef : type; }), function(type){ return type !== undef; }), function(){
+				callback.apply(this, array.map(typesForItems, function(types){
+					var clzList = array.map(types, function(type){ return lang.getObject(type) || require(type); });
+					return clzList.length > 1 ? declare(clzList, {}) : clzList[0];
+				}));
+			});
+		}else{
+			callback(Templated);
+		}
+	}
+
+	var WidgetList = declare("dojox.mvc.WidgetList", [_WidgetBase, _Container], {
+		// summary:
+		//		A widget that creates child widgets repeatedly based on the children attribute (the repeated data) and childType/childMixins/childParams attributes (determines how to create each child widget).
+		// example:
+		//		Create multiple instances of dijit/TextBox based on the data in array.
+		//		The text box refers to First property in the array item.
+		// |		<div data-dojo-type="dojox/mvc/WidgetList"
+		// |		 data-dojo-props="children: array"
+		// |		 data-mvc-child-type="dijit/form/TextBox"
+		// |		 data-mvc-child-props="value: at(this.target, 'First')"></div>
+		// example:
+		//		Create multiple instances of widgets-in-template based on the HTML written in `<script type="dojox/mvc/InlineTemplate">`.
+		//		The label refers to Serial property in the array item, and the text box refers to First property in the array item.
+		// |		<div data-dojo-type="dojox/mvc/WidgetList"
+		// |		 data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+		// |		 data-dojo-props="children: array">
+		// |			<script type="dojox/mvc/InlineTemplate">
+		// |				<div>
+		// |					<span data-dojo-type="dijit/_WidgetBase"
+		// |					 data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at('rel:', 'Serial')"></span>: 
+		// |					<span data-dojo-type="dijit/form/TextBox"
+		// |					 data-dojo-props="value: at('rel:', 'First')"></span>
+		// |				</div>
+		// |			</script>
+		// |		</div>
+		// example:
+		//		Programmatically create multiple instances of widgets-in-template based on the HTML stored in childTemplate.
+		//		(childTemplate may come from dojo/text)
+		//		Also programmatically establish data binding at child widget's startup phase.
+		//		The label refers to Serial property in the array item, and the text box refers to First property in the array item.
+		// |		var childTemplate = '<div>'
+		// |		 + '<span data-dojo-type="dijit/_WidgetBase"'
+		// |		 + ' data-dojo-attach-point="labelNode"'
+		// |		 + ' data-dojo-props="_setValueAttr: {node: \'domNode\', type: \'innerText\'}"></span>'
+		// |		 + '<span data-dojo-type="dijit/form/TextBox"'
+		// |		 + ' data-dojo-attach-point="inputNode"></span>'
+		// |		 + '</div>';
+		// |		(new WidgetList({
+		// |			children: array,
+		// |			childParams: {
+		// |				startup: function(){
+		// |					this.labelNode.set("value", at("rel:", "Serial"));
+		// |					this.inputNode.set("value", at("rel:", "First"));
+		// |					this.inherited("startup", arguments);
+		// |				}
+		// |			},
+		// |			templateString: childTemplate
+		// |		}, dom.byId("programmaticRepeat"))).startup();
+		// example:
+		//		Using the same childTemplate above, establish data binding for child widgets based on the declaration in childBindings.
+		//		(childBindings may come from dojo/text, by eval()'ing the text)
+		// |		var childBindings = {
+		// |			labelNode: {value: at("rel:", "Serial")},
+		// |			inputNode: {value: at("rel:", "First")}
+		// |		};
+		// |		(new WidgetList({
+		// |			children: array,
+		// |			templateString: childTemplate,
+		// |			childBindings: childBindings
+		// |		}, dom.byId("programmaticRepeatWithSeparateBindingDeclaration"))).startup();
+
+		// childClz: Function
+		//		The class of the child widget. Takes precedence over childType/childMixins.
+		childClz: null,
+
+		// childType: String|Function
+		//		The module ID of child widget, or a function that takes child data as the argument and returns the module ID of child widget. childClz takes precedence over this/childMixins.
+		//		Can be specified via data-mvc-child-type attribute of widget declaration.
+		childType: "",
+
+		// childMixins: String|String[]|Function
+		//		The list of module IDs (separated by comma), or a functinon that takes child data as the argument and returns it, of the classes that will be mixed into child widget. childClz takes precedence over childType/this.
+		//		Can be specified via data-mvc-child-mixins attribute of widget declaration.
+		childMixins: "",
+
+		// childParams: Object|Function
+		//		The mixin properties for child widget.
+		//		Can be specified via data-mvc-child-props attribute of widget declaration.
+		//		"this" in data-mvc-child-props will have the following properties:
+		//
+		//		- parent - This widget's instance.
+		//		- target - The data item in children.
+		childParams: null,
+
+		// childBindings: Object|Function
+		//		Data bindings for child widget.
+		childBindings: null,
+
+		// children: dojox/mvc/StatefulArray
+		//		The array of data model that is used to render child nodes.
+		children: null,
+
+		/*=====
+		// templateString: String
+		//		The template string for each child items. templateString in child widgets take precedence over this.
+		templateString: "",
+		=====*/
+
+		// partialRebuild: Boolean
+		//		If true, only rebuild repeat items for changed elements. Otherwise, rebuild everything if there is a change in children.
+		partialRebuild: false,
+
+		// _relTargetProp: String
+		//		The name of the property that is used by child widgets for relative data binding.
+		_relTargetProp : "children",
+
+		postMixInProperties: function(){
+			this.inherited(arguments);
+			if(this[childTypeAttr]){
+				this.childType = this[childTypeAttr];
+			}
+			if(this[childMixinsAttr]){
+				this.childMixins = this[childMixinsAttr];
+			}
+		},
+
+		startup: function(){
+			this.inherited(arguments);
+			this._setChildrenAttr(this.children);
+		},
+
+		_setChildrenAttr: function(/*dojo/Stateful*/ value){
+			// summary:
+			//		Handler for calls to set("children", val).
+
+			var children = this.children;
+			this._set("children", value);
+			if(this._started && (!this._builtOnce || children != value)){
+				this._builtOnce = true;
+				this._buildChildren(value);
+				if(lang.isArray(value)){
+					var _self = this;
+					value.watch !== {}.watch && (this._handles = this._handles || []).push(value.watch(function(name, old, current){
+						if(!isNaN(name)){
+							var w = _self.getChildren()[name - 0];
+							w && w.set(w._relTargetProp || "target", current);
+						}
+					}));
+				}
+			}
+		},
+
+		_buildChildren: function(/*dojox/mvc/StatefulArray*/ children){
+			// summary:
+			//		Create child widgets upon children and inserts them into the container node.
+
+			unwatchElements(this);
+			for(var cw = this.getChildren(), w = null; w = cw.pop();){ this.removeChild(w); w.destroy(); }
+			if(!lang.isArray(children)){ return; }
+
+			var _self = this,
+			 seq = this._buildChildrenSeq = (this._buildChildrenSeq || 0) + 1,
+			 initial = {idx: 0, removals: [], adds: [].concat(children)},
+			 changes = [initial];
+
+			function loadedModule(/*Object*/ change){
+				// summary:
+				//		The callback function called when modules associated with an array splice have been loaded.
+				// description:
+				//		Looks through the queued array splices and process queue entries whose modules have been loaded, by removing/adding child widgets upon the array splice.
+
+				if(this._beingDestroyed || this._buildChildrenSeq > seq){ return; } // If this _WidgetList is being destroyed, or newer _buildChildren call comes during lazy loading, bail
+
+				// Associate an object associated with an array splice with the module loaded
+				var list = [].slice.call(arguments, 1);
+				change.clz = lang.isFunction(this.childType) || lang.isFunction(this.childMixins) ? list : list[0];
+
+				// Looks through the queued array splices
+				for(var item = null; item = changes.shift();){
+					// The modules for the array splice have not been loaded, bail
+					if(!item.clz){
+						changes.unshift(item);
+						break;
+					}
+
+					// Remove child widgets upon the array removals
+					for(var i = 0, l = (item.removals || []).length; i < l; ++i){
+						this.removeChild(item.idx);
+					}
+
+					// Create/add child widgets upon the array adds
+					array.forEach(array.map(item.adds, function(child, idx){
+						var params = {
+							ownerDocument: this.ownerDocument,
+							parent: this,
+							indexAtStartup: item.idx + idx // Won't be updated even if there are removals/adds of repeat items after startup
+						}, childClz = lang.isArray(item.clz) ? item.clz[idx] : item.clz;
+						params[(lang.isFunction(this.childParams) && this.childParams.call(params, this) || this.childParams || this[childParamsAttr] && evalParams.call(params, this[childParamsAttr]) || {})._relTargetProp || childClz.prototype._relTargetProp || "target"] = child;
+
+						var childParams = this.childParams || this[childParamsAttr] && evalParams.call(params, this[childParamsAttr]),
+						 childBindings = this.childBindings || this[childBindingsAttr] && evalParams.call(params, this[childBindingsAttr]);
+						if(this.templateString && !params.templateString && !childClz.prototype.templateString){ params.templateString = this.templateString; }
+						if(childBindings && !params.bindings && !childClz.prototype.bindings){ params.bindings = childBindings; }
+						return new childClz(lang.delegate(lang.isFunction(childParams) ? childParams.call(params, this) : childParams, params));
+					}, this), function(child, idx){
+						this.addChild(child, item.idx + idx);
+					}, this);
+				}
+			}
+
+			lang.isFunction(children.watchElements) && (this._handles = this._handles || []).push(children.watchElements(function(idx, removals, adds){
+				if(!removals || !adds || !_self.partialRebuild){
+					// If the entire array is changed, or this WidgetList should rebuild the whole child widgets with every change in array, rebuild the whole
+					_self._buildChildren(children);
+				}else{
+					// Otherwise queue the array splice and load modules associated with the additions
+					var change = {idx: idx, removals: removals, adds: adds};
+					changes.push(change);
+					loadModules.call(_self, adds, lang.hitch(_self, loadedModule, change));
+				}
+			}));
+
+			// Load modules associated with the initial data
+			loadModules.call(this, children, lang.hitch(this, loadedModule, initial));
+		},
+
+		destroy: function(){
+			unwatchElements(this);
+			this.inherited(arguments);
+		}
+	});
+
+	WidgetList.prototype[childTypeAttr] = WidgetList.prototype[childMixinsAttr] = WidgetList.prototype[childParamsAttr] = WidgetList.prototype[childBindingsAttr] = ""; // Let parser treat these attributes as string
+	return WidgetList;
+});
diff --git a/dojox/mvc/_Container.js b/dojox/mvc/_Container.js
old mode 100755
new mode 100644
index 6c475f2..b5a0167
--- a/dojox/mvc/_Container.js
+++ b/dojox/mvc/_Container.js
@@ -1,15 +1,12 @@
 define([
 	"dojo/_base/declare",
 	"dojo/_base/lang",
+	"dojo/when",
 	"dijit/_WidgetBase",
 	"dojo/regexp"
-], function(declare, lang, _WidgetBase, regexp){
-	/*=====
-		declare = dojo.declare;
-		_WidgetBase = dijit._WidgetBase;
-	=====*/
+], function(declare, lang, when, _WidgetBase, regexp){
 
-	return declare("dojox.mvc._Container", [_WidgetBase], {
+	return declare("dojox.mvc._Container", _WidgetBase, {
 	
 		// stopParser: [private] Boolean
 		//		Flag to parser to not try and parse widgets declared inside the container.
@@ -17,6 +14,7 @@ define([
 
 		// exprchar:  Character
 		//		Character to use for a substitution expression, for a substitution string like ${this.index}
+		//		If this class is declared in a template HTML and exprchar is used in in-line template of this class, something other than `$` should be specified to avoid conflict with exprchar of outer-template.
 		exprchar: '$',
 	
 		// templateString: [private] String
@@ -26,7 +24,11 @@ define([
 		//		attributes are not supported in the template.
 		templateString : "",
 	
-		// _containedWidgets: [protected] dijit._Widget[]
+		// inlineTemplateString: [private] String
+		//		Same as templateString. Used when this widget is mixed with a regular templated widget.
+		inlineTemplateString : "",
+
+		// _containedWidgets: [protected] dijit/_Widget[]
 		//		The array of contained widgets at any given point in time within this container.
 		_containedWidgets : [],
 	
@@ -58,12 +60,17 @@ define([
 					}
 				}
 			}
+
+			var _self = this;
+
 			if(this._parser){
-				this._containedWidgets = this._parser.parse(this.srcNodeRef,{
+				return when(this._parser.parse(this.srcNodeRef,{
 					template: true,
 					inherited: {dir: this.dir, lang: this.lang},
 					propsThis: this,
 					scope: "dojo"
+				}), function(widgets){
+					_self._containedWidgets = widgets;
 				});
 			}
 		},
diff --git a/dojox/mvc/_Controller.js b/dojox/mvc/_Controller.js
new file mode 100644
index 0000000..3f5a62b
--- /dev/null
+++ b/dojox/mvc/_Controller.js
@@ -0,0 +1,131 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/Stateful",
+	"./_atBindingMixin"
+], function(declare, lang, Stateful, _atBindingMixin){
+	return declare("dojox.mvc._Controller", [Stateful, _atBindingMixin], {
+		postscript: function(/*Object?*/ params, /*DomNode|String?*/ srcNodeRef){
+			// summary:
+			//		If this object is not called from Dojo parser, starts this up right away.
+			//		Also, if widget registry is available, register this object.
+
+			// If there is dijit/_WidgetBase in upper class hierarchy (happens when this descendant is mixed into a widget), let _WidgetBase do all work
+			if(this._applyAttributes){
+				this.inherited(arguments);
+			}
+			// Look for dojox/mvc/at handles in the parameters
+			this._dbpostscript(params, srcNodeRef);
+			// Merge the parameters to this
+			if(params){
+				this.params = params;
+				for(var s in params){
+					this.set(s, params[s]);
+				}
+			}
+			// Add this instance to dijit/registry, if it's available
+			var registry;
+			try{
+				// Usage of dijit/registry module is optional. Do not use it if it's not already loaded.
+				registry = require("dijit/registry");
+				this.id = this.id || (srcNodeRef || {}).id || registry.getUniqueId(this.declaredClass.replace(/\./g, "_"));
+				registry.add(this);
+			}catch(e){}
+			if(!srcNodeRef){
+				// If this instance is not created via Dojo parser, start this up right away
+				this.startup();
+			}else{
+				// If this is created via Dojo parser, set widgetId attribute so that destroyDescendants() of parent widget works
+				srcNodeRef.setAttribute("widgetId", this.id); 
+			}
+		},
+
+		startup: function(){
+			// summary:
+			//		Starts up data binding as this object starts up.
+
+			if(!this._applyAttributes){
+				this._startAtWatchHandles();
+			}
+			// If there is dijit/_WidgetBase in upper class hierarchy (happens when this descendant is mixed into a widget), let _WidgetBase do all work
+			this.inherited(arguments);
+		},
+
+		destroy: function(){
+			// summary:
+			//		Stops data binding as this object is destroyed.
+
+			this._beingDestroyed = true;
+			if(!this._applyAttributes){
+				this._stopAtWatchHandles();
+			}
+			// If there is dijit/_WidgetBase in upper class hierarchy (happens when this descendant is mixed into a widget), let _WidgetBase do all work
+			this.inherited(arguments);
+			if(!this._applyAttributes){
+				try{
+					// Remove this instance from dijit/registry
+					// Usage of dijit/registry module is optional. Do not use it if it's not already loaded.
+					require("dijit/registry").remove(this.id);
+				}catch(e){}
+			}
+			this._destroyed = true;
+		},
+
+		set: function(/*String*/ name, /*Anything*/ value){
+			// summary:
+			//		If the value given is dojox/mvc/at handle, use it for data binding.
+			//		Otherwise, if setter function is there, use it.
+			//		Otherwise, set the value to the data model or to this object.
+			// name: String
+			//		The property name.
+			// value: Anything
+			//		The property value.
+
+			// If an object is used, iterate through object
+			if(typeof name === "object"){
+				for(var x in name){
+					if(name.hasOwnProperty(x)){
+						this.set(x, name[x]);
+					}
+				}
+				return this;
+			}
+
+			if(!this._applyAttributes){
+				if((value || {}).atsignature == "dojox.mvc.at"){
+					// If dojox/mvc/at handle is given, use it for data binding
+					return this._setAtWatchHandle(name, value);
+				}else{
+					// Otherwise align the setter interface to _WidgetBase
+					var setterName = "_set" + name.replace(/^[a-z]/, function(c){ return c.toUpperCase(); }) + "Attr";
+					if(this[setterName]){
+						this[setterName](value);
+					}else{
+						this._set(name, value);
+					}
+					return this;
+				}
+			}
+
+			// If there is dijit/_WidgetBase in upper class hierarchy (happens when this descendant is mixed into a widget), let _WidgetBase do all work
+			return this.inherited(arguments);
+		},
+
+		_set: function(/*String*/ name, /*Anything*/ value){
+			// summary:
+			//		Implement _set() interface so that _set() behavior is consistent whether the instance inherits _WidgetBase or not.
+			//		If the instance does not inherit _WidgetBase, use dojo/Stateful/_changeAttrValue() that's equivalent to dijit/_WidgetBase._set().
+			// name: String
+			//		The property name.
+			// value: Anything
+			//		The property value.
+
+			if(!this._applyAttributes){
+				// Call dojo/Stateful/_changeAttrValue() that's equivalent to dijit/_WidgetBase/_set()
+				return this._changeAttrValue(name, value);
+			}
+			// If there is dijit/_WidgetBase in upper class hierarchy (happens when this descendant is mixed into a widget), let _WidgetBase do all work
+			return this.inherited(arguments);
+		}
+	});
+});
diff --git a/dojox/mvc/_DataBindingExtension.js b/dojox/mvc/_DataBindingExtension.js
new file mode 100644
index 0000000..61d414d
--- /dev/null
+++ b/dojox/mvc/_DataBindingExtension.js
@@ -0,0 +1,26 @@
+define([
+	"dojo/_base/array",
+	"dojo/aspect",
+	"dojo/_base/lang",
+	"dijit/_WidgetBase",
+	"./_DataBindingMixin"
+], function(array, aspect, lang, WidgetBase, DataBindingMixin){
+
+	//Apply the data binding mixin to all dijits, see mixin class description for details
+	lang.extend(WidgetBase, /*===== {} || =====*/ new DataBindingMixin());
+
+	// monkey patch dijit/_WidgetBase.startup to get data binds set up
+	aspect.before(WidgetBase.prototype, "startup", function(){
+		this._dbstartup();
+	});
+
+	// monkey patch dijit/_WidgetBase.destroy to remove watches setup in _DataBindingMixin
+	aspect.before(WidgetBase.prototype, "destroy", function(){
+		if(this._modelWatchHandles){
+			array.forEach(this._modelWatchHandles, function(h){ h.unwatch(); });
+		}
+		if(this._viewWatchHandles){
+			array.forEach(this._viewWatchHandles, function(h){ h.unwatch(); });
+		}
+	});
+});
diff --git a/dojox/mvc/_DataBindingMixin.js b/dojox/mvc/_DataBindingMixin.js
old mode 100755
new mode 100644
index 5a97a0f..d649b38
--- a/dojox/mvc/_DataBindingMixin.js
+++ b/dojox/mvc/_DataBindingMixin.js
@@ -1,23 +1,26 @@
 define([
+	"dojo/_base/kernel",
 	"dojo/_base/lang",
 	"dojo/_base/array",
 	"dojo/_base/declare",
 	"dojo/Stateful",
 	"dijit/registry"
-], function(lang, array, declare, Stateful, registry){
-	/*=====
-	registry = dijit.registry;
-	=====*/
+], function(kernel, lang, array, declare, Stateful, registry){
 
+	kernel.deprecated("dojox.mvc._DataBindingMixin", "Use dojox/mvc/at for data binding.");
+
+	// Note: This should be a plain Object, not a Class.
+	// But no need to change it since it's deprecated.
 	return declare("dojox.mvc._DataBindingMixin", null, {
 		// summary:
+		//		Deprecated.  Use dojox/mvc/at for data binding.
 		//		Provides the ability for dijits or custom view components to become
 		//		data binding aware.
 		//
 		// description:
 		//		Data binding awareness enables dijits or other view layer
 		//		components to bind to locations within a client-side data model,
-		//		which is commonly an instance of the dojox.mvc.StatefulModel class. A
+		//		which is commonly an instance of the dojox/mvc/StatefulModel class. A
 		//		bind is a bi-directional update mechanism which is capable of
 		//		synchronizing value changes between the bound dijit or other view
 		//		component and the specified location within the data model, as well
@@ -39,13 +42,13 @@ define([
 		//		|		});
 		//		|	</script>
 		//		|
-		//		|	<input id="hello1" data-dojo-type="dijit.form.TextBox"
+		//		|	<input id="hello1" data-dojo-type="dijit/form/TextBox"
 		//		|		data-dojo-props="ref: model.hello"></input>
 		//		|
-		//		|	<input id="hello2" data-dojo-type="dijit.form.TextBox"
+		//		|	<input id="hello2" data-dojo-type="dijit/form/TextBox"
 		//		|		data-dojo-props="ref: model.hello"></input>
 		//
-		//		In the above example, both dijit.form.TextBox instances (with IDs
+		//		In the above example, both dijit/form/TextBox instances (with IDs
 		//		"hello1" and "hello2" respectively) are bound to the same reference
 		//		location in the data model i.e. "hello" via the "ref" expression
 		//		"model.hello". Both will have an initial value of "Hello World".
@@ -53,8 +56,10 @@ define([
 		//		will cause an update of the value in the data model at location
 		//		"hello" which will in turn cause a matching update of the value in
 		//		the other textbox.
+		// tags:
+		//		deprecated
 	
-		// ref: String||dojox.mvc.StatefulModel
+		// ref: [deprecated] String||dojox/mvc/StatefulModel
 		//		The value of the data binding expression passed declaratively by
 		//		the developer. This usually references a location within an
 		//		existing datamodel and may be a relative reference based on the
@@ -62,7 +67,7 @@ define([
 		ref: null,
 
 /*=====
-		// binding: [readOnly] dojox.mvc.StatefulModel
+		// binding: [readOnly] dojox/mvc/StatefulModel
 		//		The read only value of the resolved data binding for this widget.
 		//		This may be a result of resolving various relative refs along
 		//		the parent axis.
@@ -80,16 +85,19 @@ define([
 			// description:
 			//		This function is meant to provide an API bridge to the dijit API.
 			//		Validity of data-bound dijits is a function of multiple concerns:
+			//
 			//		- The validity of the value as ascertained by the data binding
 			//		  and constraints specified in the data model (usually semantic).
 			//		- The validity of the value as ascertained by the widget itself
 			//		  based on widget constraints (usually syntactic).
+			//
 			//		In order for dijits to function correctly in data-bound
 			//		environments, it is imperative that their isValid() functions
 			//		assess the model validity of the data binding via the
 			//		this.inherited(arguments) hierarchy and declare any values
 			//		failing the test as invalid.
-			return this.get("binding") ? this.get("binding").get("valid") : true;
+			var valid = this.get("valid");
+			return typeof valid != "undefined" ? valid : this.get("binding") ? this.get("binding").get("valid") : true;
 		},
 
 		//////////////////////// LIFECYCLE METHODS ////////////////////////
@@ -108,7 +116,7 @@ define([
 			this._viewWatchHandles = [
 				// 1. data binding refs
 				this.watch("ref", function(name, old, current){
-					if(this._databound){
+					if(this._databound && old !== current){
 						this._setupBinding();
 					}
 				}),
@@ -135,28 +143,31 @@ define([
 
 		_setupBinding: function(parentBinding){
 			// summary:
-			//		Calculate and set the dojo.Stateful data binding for the
+			//		Calculate and set the dojo/Stateful data binding for the
 			//		associated dijit or custom view component.
-			//	parentBinding:
+			// parentBinding:
 			//		The binding of this widget/view component's data-bound parent,
 			//		if available.
 			// description:
 			//		The declarative data binding reference may be specified in two
 			//		ways via markup:
+			//
 			//		- For older style documents (non validating), controls may use
 			//		  the "ref" attribute to specify the data binding reference
 			//		  (String).
 			//		- For validating documents using the new Dojo parser, controls
 			//		  may specify the data binding reference (String) as the "ref"
 			//		  property specified in the data-dojo-props attribute.
+			//
 			//		Once the ref value is obtained using either of the above means,
 			//		the binding is set up for this control and its required, readOnly
 			//		etc. properties are refreshed.
 			//		The data binding may be specified as a direct reference to the
-			//		dojo.Stateful model node or as a string relative to its DOM
+			//		dojo/Stateful model node or as a string relative to its DOM
 			//		parent or another widget.
 			//		There are three ways in which the data binding node reference is
 			//		calculated when specified as a string:
+			//
 			//		- If an explicit parent widget is specified, the binding is
 			//		  calculated relative to the parent widget's data binding.
 			//		- For any dijits that specify a data binding reference,
@@ -166,14 +177,17 @@ define([
 			//		- If no such parent is found i.e. for the outermost container
 			//		  dijits that specify a data binding reference, the binding is
 			//		  calculated by treating the reference String as an expression and
-			//		  evaluating it to obtain the dojo.Stateful node in the datamodel.
-			//		This method throws an Error in these two conditions:
+			//		  evaluating it to obtain the dojo/Stateful node in the datamodel.
+			//
+			//		This method calls console.warn in these two conditions:
+			//
 			//		- The ref is an expression i.e. outermost bound dijit, but the
 			//		  expression evaluation fails.
 			//		- The calculated binding turns out to not be an instance of a
-			//		  dojo.Stateful node.
+			//		  dojo/Stateful node.
 			// tags:
 			//		private
+
 			if(!this.ref){
 				return; // nothing to do here
 			}
@@ -205,13 +219,14 @@ define([
 					binding = lang.getObject("" + ref, false, parentBinding);
 				}else{
 					try{
-						if(lang.getObject(ref) instanceof Stateful){
-							binding = lang.getObject(ref);
+						var b = lang.getObject("" + ref) || {};
+						if(lang.isFunction(b.set) && lang.isFunction(b.watch)){
+							binding = b;
 						}						
 					}catch(err){
 						if(ref.indexOf("${") == -1){ // Ignore templated refs such as in repeat body
-							throw new Error("dojox.mvc._DataBindingMixin: '" + this.domNode +
-								"' widget with illegal ref expression: '" + ref + "'");
+							console.warn("dojox/mvc/_DataBindingMixin: '" + this.domNode +
+								"' widget with illegal ref not evaluating to a dojo/Stateful node: '" + ref + "'");
 						}
 					}
 				}
@@ -219,16 +234,19 @@ define([
 			if(binding){
 				if(lang.isFunction(binding.toPlainObject)){
 					this.binding = binding;
+					if(this[this._relTargetProp || "target"] !== binding){
+						this.set(this._relTargetProp || "target", binding);
+					}
 					this._updateBinding("binding", null, binding);
 				}else{
-					throw new Error("dojox.mvc._DataBindingMixin: '" + this.domNode +
-						"' widget with illegal ref not evaluating to a dojo.Stateful node: '" + ref + "'");
+					console.warn("dojox/mvc/_DataBindingMixin: '" + this.domNode +
+						"' widget with illegal ref not evaluating to a dojo/Stateful node: '" + ref + "'");
 				}
 			}
 		},
 
 		_isEqual: function(one, other){
-        	// test for equality
+			// test for equality
 			return one === other ||
 				// test for NaN === NaN
 				isNaN(one) && typeof one === 'number' &&
@@ -238,13 +256,13 @@ define([
 		_updateBinding: function(name, old, current){
 			// summary:
 			//		Set the data binding to the supplied value, which must be a
-			//		dojo.Stateful node of a data model.
-			//	name:
+			//		dojo/Stateful node of a data model.
+			// name:
 			//		The name of the binding property (always "binding").
-			//	old:
-			//		The old dojo.Stateful binding node of the data model.
-			//	current:
-			//		The new dojo.Stateful binding node of the data model.
+			// old:
+			//		The old dojo/Stateful binding node of the data model.
+			// current:
+			//		The new dojo/Stateful binding node of the data model.
 			// description:
 			//		Applies the specified data binding to the attached widget.
 			//		Loses any prior watch registrations on the previously active
@@ -300,19 +318,19 @@ define([
 		_updateProperty: function(name, old, current, defaultValue, setPropName, setPropValue){
 			// summary:
 			//		Update a binding property of the bound widget.
-			//	name:
+			// name:
 			//		The binding property name.
-			//	old:
+			// old:
 			//		The old value of the binding property.
-			//	current:
+			// current:
 			//		The new or current value of the binding property.
-			//	defaultValue:
+			// defaultValue:
 			//		The optional value to be applied as the current value of the
 			//		binding property if the current value is null.
-			//	setPropName:
+			// setPropName:
 			//		The optional name of a stateful property to set on the bound
 			//		widget.
-			//	setPropValue:
+			// setPropValue:
 			//		The value, if an optional name is provided, for the stateful
 			//		property of the bound widget.
 			// tags:
@@ -330,14 +348,15 @@ define([
 				this.set(setPropName, setPropValue);
 			}
 		},
+
 		_updateChildBindings: function(parentBind){
 			// summary:
 			//		Update this widget's value based on the current binding and
 			//		set up the bindings of all contained widgets so as to refresh
 			//		any relative binding references. 
-			// 		findWidgets does not return children of widgets so need to also
+			//		findWidgets does not return children of widgets so need to also
 			//		update children of widgets which are not bound but may hold widgets which are.
-			//	parentBind:
+			// parentBind:
 			//		The binding on the parent of a widget whose children may have bindings 
 			//		which need to be updated.
 			// tags:
@@ -379,7 +398,7 @@ define([
 		_unwatchArray: function(watchHandles){
 			// summary:
 			//		Given an array of watch handles, unwatch all.
-			//	watchHandles:
+			// watchHandles:
 			//		The array of watch handles.
 			// tags:
 			//		private
diff --git a/dojox/mvc/_InlineTemplateMixin.js b/dojox/mvc/_InlineTemplateMixin.js
new file mode 100644
index 0000000..483dcfd
--- /dev/null
+++ b/dojox/mvc/_InlineTemplateMixin.js
@@ -0,0 +1,30 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/has"
+], function(declare, lang, has){
+	has.add("dom-qsa", !!document.createElement("div").querySelectorAll);
+
+	return declare("dojox.mvc._InlineTemplateMixin", null, {
+		// summary:
+		//		A mixin for template widget, which will look for `<script type="dojox/mvc/InlineTemplate">`
+		//		and treat the HTML in there as the template string.
+
+		buildRendering: function(){
+			var root = this.srcNodeRef;
+			if(root){
+				var nodes = has("dom-qsa") ? root.querySelectorAll("script[type='dojox/mvc/InlineTemplate']") : root.getElementsByTagName("script"),
+				 templates = [];
+				for(var i = 0, l = nodes.length; i < l; ++i){
+					if(!has("dom-qsa") && nodes[i].getAttribute("type") != "dojox/mvc/InlineTemplate"){ continue; }
+					templates.push(nodes[i].innerHTML);
+				}
+				var templateString = lang.trim(templates.join(""));
+				if(templateString){
+					this.templateString = templateString;
+				}
+			}
+			this.inherited(arguments);
+		}
+	});
+});
diff --git a/dojox/mvc/_TextBoxExtensions.js b/dojox/mvc/_TextBoxExtensions.js
new file mode 100644
index 0000000..8d38dd4
--- /dev/null
+++ b/dojox/mvc/_TextBoxExtensions.js
@@ -0,0 +1,33 @@
+define([
+	"dojo/_base/lang",
+	"dijit/_WidgetBase",
+	"dijit/form/ValidationTextBox",
+	"dijit/form/NumberTextBox"
+], function(lang, WidgetBase, ValidationTextBox, NumberTextBox){
+
+	// monkey patch dijit/form/ValidationTextBox.isValid to check this.inherited for isValid.
+	// hide patch from doc parser though because we want it to display the original definition of isValid.
+	var oldValidationTextBoxIsValid = ValidationTextBox.prototype.isValid;
+	ValidationTextBox.prototype.isValid = /*===== oldValidationTextBoxIsValid || =====*/ function(/*Boolean*/ isFocused){
+		return (this.inherited("isValid", arguments) !== false && oldValidationTextBoxIsValid.apply(this, [isFocused]));
+	};
+
+	// monkey patch dijit/form/NumberTextBox.isValid to check this.inherited for isValid.
+	// hide patch from doc parser though because we want it to display the original definition of isValid.
+	var oldNumberTextBoxIsValid = NumberTextBox.prototype.isValid;
+	NumberTextBox.prototype.isValid = /*===== oldNumberTextBoxIsValid || =====*/ function(/*Boolean*/ isFocused){
+		return (this.inherited("isValid", arguments) !== false && oldNumberTextBoxIsValid.apply(this, [isFocused]));
+	};
+
+	if(!lang.isFunction(WidgetBase.prototype.isValid)){
+		WidgetBase.prototype.isValid = function(){
+			var valid = this.get("valid");
+			return typeof valid == "undefined" ? true : valid;
+		};
+	}
+
+	WidgetBase.prototype._setValidAttr = function(value){
+		this._set("valid", value);
+		this.validate();
+	};
+});
diff --git a/dojox/mvc/_atBindingExtension.js b/dojox/mvc/_atBindingExtension.js
new file mode 100644
index 0000000..ba3787b
--- /dev/null
+++ b/dojox/mvc/_atBindingExtension.js
@@ -0,0 +1,11 @@
+define([
+	"dojo/_base/config",
+	"dojo/has",
+	"dijit/_WidgetBase",
+	"./atBindingExtension"
+], function(config, has, _WidgetBase, atBindingExtension){
+	has.add("mvc-extension-per-widget", (config["mvc"] || {}).extensionPerWidget);
+	if(!has("mvc-extension-per-widget")){
+		atBindingExtension(_WidgetBase.prototype);
+	}
+});
diff --git a/dojox/mvc/_atBindingMixin.js b/dojox/mvc/_atBindingMixin.js
new file mode 100644
index 0000000..9d05185
--- /dev/null
+++ b/dojox/mvc/_atBindingMixin.js
@@ -0,0 +1,268 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dojo/has",
+	"dojo/Stateful",
+	"./resolve",
+	"./sync"
+], function(array, lang, declare, has, Stateful, resolve, sync){
+	if(has("mvc-bindings-log-api")){
+		function getLogContent(/*dojo/Stateful*/ target, /*String*/ targetProp){
+			return [target._setIdAttr || !target.declaredClass ? target : target.declaredClass, targetProp].join(":");
+		}
+
+		function logResolveFailure(target, targetProp){
+			console.warn(targetProp + " could not be resolved" + (typeof target == "string" ? (" with " + target) : "") + ".");
+		}
+	}
+
+	function getParent(/*dijit/_WidgetBase*/ w){
+		// summary:
+		//		Returns parent widget having data binding target for relative data binding.
+		// w: dijit/_WidgetBase
+		//		The widget.
+
+		// Usage of dijit/registry module is optional. Return null if it's not already loaded.
+		var registry;
+		try{
+			registry = require("dijit/registry");
+		}catch(e){
+			return;
+		}
+		var pn = w.domNode && w.domNode.parentNode, pw, pb;
+		while(pn){
+			pw = registry.getEnclosingWidget(pn);
+			if(pw){
+				var relTargetProp = pw._relTargetProp || "target", pt = lang.isFunction(pw.get) ? pw.get(relTargetProp) : pw[relTargetProp];
+				if(pt || relTargetProp in pw.constructor.prototype){
+					return pw; // dijit/_WidgetBase
+				}
+			}
+			pn = pw && pw.domNode.parentNode;
+		}
+	}
+
+	function bind(/*dojo/Stateful|String*/ source, /*String*/ sourceProp, /*dijit/_WidgetBase*/ target, /*String*/ targetProp, /*dojox/mvc/sync.options*/ options){
+		// summary:
+		//		Resolves the data binding literal, and starts data binding.
+		// source: dojo/Stateful|String
+		//		Source data binding literal or dojo/Stateful to be synchronized.
+		// sourceProp: String
+		//		The property name in source to be synchronized.
+		// target: dijit/_WidgetBase
+		//		Target dojo/Stateful to be synchronized.
+		// targetProp: String
+		//		The property name in target to be synchronized.
+		// options: dojox/mvc/sync.options
+		//		Data binding options.
+
+		var _handles = {}, parent = getParent(target), relTargetProp = parent && parent._relTargetProp || "target";
+
+		function resolveAndBind(){
+			_handles["Two"] && _handles["Two"].unwatch();
+			delete _handles["Two"];
+
+			var relTarget = parent && (lang.isFunction(parent.get) ? parent.get(relTargetProp) : parent[relTargetProp]),
+			 resolvedSource = resolve(source, relTarget),
+			 resolvedTarget = resolve(target, relTarget);
+
+			if(has("mvc-bindings-log-api") && (!resolvedSource || /^rel:/.test(source) && !parent)){ logResolveFailure(source, sourceProp); }
+			if(has("mvc-bindings-log-api") && (!resolvedTarget || /^rel:/.test(target) && !parent)){ logResolveFailure(target, targetProp); }
+			if(!resolvedSource || !resolvedTarget || (/^rel:/.test(source) || /^rel:/.test(target)) && !parent){ return; }
+			if((!resolvedSource.set || !resolvedSource.watch) && sourceProp == "*"){
+				if(has("mvc-bindings-log-api")){ logResolveFailure(source, sourceProp); }
+				return;
+			}
+
+			if(sourceProp == null){
+				// If source property is not specified, it means this handle is just for resolving data binding target.
+				// (For dojox/mvc/Group and dojox/mvc/Repeat)
+				// Do not perform data binding synchronization in such case.
+				lang.isFunction(resolvedTarget.set) ? resolvedTarget.set(targetProp, resolvedSource) : (resolvedTarget[targetProp] = resolvedSource);
+				if(has("mvc-bindings-log-api")){
+					console.log("dojox/mvc/_atBindingMixin set " + resolvedSource + " to: " + getLogContent(resolvedTarget, targetProp));
+				}
+			}else{
+				// Start data binding
+				_handles["Two"] = sync(resolvedSource, sourceProp, resolvedTarget, targetProp, options); // dojox/mvc/sync.handle
+			}
+		}
+
+		resolveAndBind();
+		if(parent && /^rel:/.test(source) || /^rel:/.test(target) && lang.isFunction(parent.set) && lang.isFunction(parent.watch)){
+			_handles["rel"] = parent.watch(relTargetProp, function(name, old, current){
+				if(old !== current){
+					if(has("mvc-bindings-log-api")){ console.log("Change in relative data binding target: " + parent); }
+					resolveAndBind();
+				}
+			});
+		}
+		var h = {};
+		h.unwatch = h.remove = function(){
+			for(var s in _handles){
+				_handles[s] && _handles[s].unwatch();
+				delete _handles[s];
+			}
+		};
+		return h;
+	}
+
+	var mixin = {
+		// summary:
+		//		The mixin for dijit/_WidgetBase to support data binding.
+
+		// dataBindAttr: String
+		//		The attribute name for data binding.
+		dataBindAttr: "data-mvc-bindings",
+
+		_dbpostscript: function(/*Object?*/ params, /*DomNode|String*/ srcNodeRef){
+			// summary:
+			//		See if any parameters for this widget are dojox/mvc/at handles.
+			//		If so, move them under this._refs to prevent widget implementations from referring them.
+
+			var refs = this._refs = (params || {}).refs || {};
+			for(var prop in params){
+				if((params[prop] || {}).atsignature == "dojox.mvc.at"){
+					var h = params[prop];
+					delete params[prop];
+					refs[prop] = h;
+				}
+			}
+
+			var dbParams = new Stateful(),
+			 _self = this;
+			dbParams.toString = function(){ return '[Mixin value of widget ' + _self.declaredClass + ', ' + (_self.id || 'NO ID') + ']'; };
+			dbParams.canConvertToLoggable = true;
+			this._startAtWatchHandles(dbParams);
+			for(var prop in refs){
+				if(dbParams[prop] !== void 0){
+					(params = params || {})[prop] = dbParams[prop];
+				}
+			}
+			this._stopAtWatchHandles();
+		},
+
+		_startAtWatchHandles: function(/*dojo/Stateful*/ bindWith){
+			// summary:
+			//		Establish data bindings based on dojox/mvc/at handles.
+			// bindWith: dojo/Stateful
+			//		The dojo/Stateful to bind properties with.
+
+			this.canConvertToLoggable = true;
+
+			var refs = this._refs;
+			if(refs){
+				var atWatchHandles = this._atWatchHandles = this._atWatchHandles || {};
+
+				// Clear the cache of properties that data binding is established with
+				this._excludes = null;
+
+				// First, establish non-wildcard data bindings
+				for(var prop in refs){
+					if(!refs[prop] || prop == "*"){ continue; }
+					atWatchHandles[prop] = bind(refs[prop].target, refs[prop].targetProp, bindWith || this, prop, {bindDirection: refs[prop].bindDirection, converter: refs[prop].converter, equals: refs[prop].equalsCallback});
+				}
+
+				// Then establish wildcard data bindings
+				if((refs["*"] || {}).atsignature == "dojox.mvc.at"){
+					atWatchHandles["*"] = bind(refs["*"].target, refs["*"].targetProp, bindWith || this, "*", {bindDirection: refs["*"].bindDirection, converter: refs["*"].converter, equals: refs["*"].equalsCallback});
+				}
+			}
+		},
+
+		_stopAtWatchHandles: function(){
+			// summary:
+			//		Stops data binding synchronization handles as widget is destroyed.
+
+			for(var s in this._atWatchHandles){
+				this._atWatchHandles[s].unwatch();
+				delete this._atWatchHandles[s];
+			}
+		},
+
+		_setAtWatchHandle: function(/*String*/ name, /*Anything*/ value){
+			// summary:
+			//		Called if the value is a dojox/mvc/at handle.
+			//		If this widget has started, start data binding with the new dojox/mvc/at handle.
+			//		Otherwise, queue it up to this._refs so that _dbstartup() can pick it up.
+
+			if(name == "ref"){
+				throw new Error(this + ": 1.7 ref syntax used in conjuction with 1.8 dojox/mvc/at syntax, which is not supported.");
+			}
+
+			// Claen up older data binding
+			var atWatchHandles = this._atWatchHandles = this._atWatchHandles || {};
+			if(atWatchHandles[name]){
+				atWatchHandles[name].unwatch();
+				delete atWatchHandles[name];
+			}
+
+			// Claar the value
+			this[name] = null;
+
+			// Clear the cache of properties that data binding is established with
+			this._excludes = null;
+
+			if(this._started){
+				// If this widget has been started already, establish data binding immediately.
+				atWatchHandles[name] = bind(value.target, value.targetProp, this, name, {bindDirection: value.bindDirection, converter: value.converter, equals: value.equalsCallback});
+			}else{
+				// Otherwise, queue it up to this._refs so that _dbstartup() can pick it up.
+				this._refs[name] = value;
+			}
+		},
+
+		_setBind: function(/*Object*/ value){
+			// summary:
+			//		Sets data binding described in data-mvc-bindings.
+
+			var list = eval("({" + value + "})");
+			for(var prop in list){
+				var h = list[prop];
+				if((h || {}).atsignature != "dojox.mvc.at"){
+					console.warn(prop + " in " + dataBindAttr + " is not a data binding handle.");
+				}else{
+					this._setAtWatchHandle(prop, h);
+				}
+			}
+		},
+
+		_getExcludesAttr: function(){
+			// summary:
+			//		Returns list of all properties that data binding is established with.
+
+			if(this._excludes){ 
+				return this._excludes;  // String[] 
+			}
+			var list = [];
+			for(var s in this._atWatchHandles){
+				if(s != "*"){ list.push(s); }
+			}
+			return list; // String[]
+		},
+
+		_getPropertiesAttr: function(){
+			// summary:
+			//		Returns list of all properties in this widget, except "id".
+			// returns: String[]
+			//		 The list of all properties in this widget, except "id"..
+
+			if(this.constructor._attribs){
+				return this.constructor._attribs; // String[]
+			}
+			var list = ["onClick"].concat(this.constructor._setterAttrs);
+			array.forEach(["id", "excludes", "properties", "ref", "binding"], function(s){
+				var index = array.indexOf(list, s);
+				if(index >= 0){ list.splice(index, 1); }
+			});
+			return this.constructor._attribs = list; // String[]
+		}
+	};
+
+	mixin[mixin.dataBindAttr] = ""; // Let parser treat the attribute as string
+
+	var _atBindingMixin = declare("dojox/mvc/_atBindingMixin", null, mixin);
+	_atBindingMixin.mixin = mixin; // Keep the plain object version
+	return _atBindingMixin;
+});
diff --git a/dojox/mvc/_base.js b/dojox/mvc/_base.js
old mode 100755
new mode 100644
index fee784d..4fd4c15
--- a/dojox/mvc/_base.js
+++ b/dojox/mvc/_base.js
@@ -1,11 +1,12 @@
 define([
 	"dojo/_base/kernel",
 	"dojo/_base/lang",
+	"./getStateful",
 	"./StatefulModel",
 	"./Bind",
 	"./_DataBindingMixin",
 	"./_patches"
-], function(kernel, lang, StatefulModel){
+], function(kernel, lang, getStateful, StatefulModel){
 	// module:
 	//		dojox/mvc/_base
 	// summary:
@@ -23,37 +24,39 @@ define([
 		// summary:
 		//		Factory method that instantiates a new data model that view
 		//		components may bind to.
-		//	args:
+		// args:
 		//		The mixin properties.
 		// description:
 		//		Factory method that returns a client-side data model, which is a
-		//		tree of dojo.Stateful objects matching the initial data structure
+		//		tree of dojo/Stateful objects matching the initial data structure
 		//		passed as input:
+		//
 		//		- The mixin property "data" is used to provide a plain JavaScript
 		//		  object directly representing the data structure.
 		//		- The mixin property "store", along with an optional mixin property
 		//		  "query", is used to provide a data store to query to obtain the
 		//		  initial data.
+		//
 		//		This function returns an immediate dojox.mvc.StatefulModel instance or
 		//		a Promise for such an instance as follows:
-		//		- if args.data: returns immediate
-		//		- if args.store:
-		//			- if store returns immediate: this function returns immediate
-		//			- if store returns a Promise: this function returns a model
-		//			  Promise
+		//
+		//		- if args.data: returns immediately
+		//		- if args.store: if store returns immediately, this function returns immediately;
+		//			if store returns a Promise, this function returns a model Promise
+
 		if(args.data){
-			return new StatefulModel({ data : args.data });
+			return getStateful(args.data, StatefulModel.getStatefulOptions);
 		}else if(args.store && lang.isFunction(args.store.query)){
 			var model;
 			var result = args.store.query(args.query);
 			if(result.then){
 				return (result.then(function(data){
-					model = new StatefulModel({ data : data });
+					model = getStateful(data, StatefulModel.getStatefulOptions);
 					model.store = args.store;
 					return model;
 				}));
 			}else{
-				model = new StatefulModel({ data : result });
+				model = getStateful(result, StatefulModel.getStatefulOptions);
 				model.store = args.store;
 				return model;
 			}
diff --git a/dojox/mvc/_patches.js b/dojox/mvc/_patches.js
old mode 100755
new mode 100644
index 61fc563..6a17ac5
--- a/dojox/mvc/_patches.js
+++ b/dojox/mvc/_patches.js
@@ -1,49 +1,5 @@
 define([
-	"dojo/_base/lang",
-	"dojo/_base/array",
-	"dijit/_WidgetBase",
-	"./_DataBindingMixin",
-	"dijit/form/ValidationTextBox",
-	"dijit/form/NumberTextBox"
-], function(lang, array, wb, dbm, vtb, ntb){
-	/*=====
-		vtb = dijit.form.ValidationTextBox;
-		ntb = dijit.form.NumberTextBox;
-		dbm = dojox.mvc._DataBindingMixin;
-		wb = dijit._WidgetBase;
-	=====*/
-
-	//Apply the data binding mixin to all dijits, see mixin class description for details
-	lang.extend(wb, new dbm());
-
-	// monkey patch dijit._WidgetBase.startup to get data binds set up
-	var oldWidgetBaseStartup = wb.prototype.startup;
-	wb.prototype.startup = function(){
-		this._dbstartup();
-		oldWidgetBaseStartup.apply(this);
-	};
-
-	// monkey patch dijit._WidgetBase.destroy to remove watches setup in _DataBindingMixin
-	var oldWidgetBaseDestroy = wb.prototype.destroy;
-	wb.prototype.destroy = function(/*Boolean*/ preserveDom){
-		if(this._modelWatchHandles){
-			array.forEach(this._modelWatchHandles, function(h){ h.unwatch(); });
-		}
-		if(this._viewWatchHandles){
-			array.forEach(this._viewWatchHandles, function(h){ h.unwatch(); });
-		}
-		oldWidgetBaseDestroy.apply(this, [preserveDom]);		
-	};
-
-	// monkey patch dijit.form.ValidationTextBox.isValid to check this.inherited for isValid
-	var oldValidationTextBoxIsValid = vtb.prototype.isValid;
-	vtb.prototype.isValid = function(/*Boolean*/ isFocused){
-		return (this.inherited("isValid", arguments) !== false && oldValidationTextBoxIsValid.apply(this, [isFocused]));
-	};
-
-	// monkey patch dijit.form.NumberTextBox.isValid to check this.inherited for isValid
-	var oldNumberTextBoxIsValid = ntb.prototype.isValid;
-	ntb.prototype.isValid = function(/*Boolean*/ isFocused){
-		return (this.inherited("isValid", arguments) !== false && oldNumberTextBoxIsValid.apply(this, [isFocused]));
-	};
-});
+	"./_atBindingExtension",
+	"./_DataBindingExtension",
+	"./_TextBoxExtensions"
+], function(){});
diff --git a/dojox/mvc/at.js b/dojox/mvc/at.js
new file mode 100644
index 0000000..30a87cb
--- /dev/null
+++ b/dojox/mvc/at.js
@@ -0,0 +1,134 @@
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"./sync",
+	"./_atBindingExtension"
+], function(kernel, lang, sync){
+
+	kernel.experimental("dojox.mvc");
+
+	var at = function(/*dojo/Stateful|String*/ target, /*String*/ targetProp){
+		// summary:
+		//		Returns a pointer to data binding target (a dojo/Stateful property), called at handle, which is used for start synchronization with data binding source (another dojo/Stateful property).
+		// description:
+		//		Typically used in data-dojo-props so that a widget can synchronize its attribute with another dojo/Stateful, like shown in the example.
+		// target: dojo/Stateful|String
+		//		dojo/Stateful to be synchronized.
+		// targetProp: String
+		//		The property name in target to be synchronized.
+		// returns:
+		//		A pointer to data binding target (a dojo/Stateful property), called at handle, which is used for start synchronization with data binding source (another dojo/Stateful property).
+		// example:
+		//		Two seconds later, the text box changes from "Foo" to "Bar" as the "value" property in model changes.
+		// |		<html>
+		// |			<head>
+		// |				<script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script>
+		// |				<script type="text/javascript">
+		// |					require([
+		// |						"dojo/parser", "dojo/Stateful", "dijit/form/TextBox", "dojo/domReady!"
+		// |					], function(parser, Stateful){
+		// |						model = new Stateful({value: "Foo"});
+		// |						setTimeout(function(){ model.set("value", "Bar"); }, 2000);
+		// |						parser.parse();
+		// |					});
+		// |				</script>
+		// |			</head>
+		// |			<body>
+		// |				<script type="dojo/require">at: "dojox/mvc/at"</script>
+		// |				<input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-props="value: at(model, 'value')">
+		// |			</body>
+		// |		</html>
+		// example:
+		//		Edit in text box is reflected to the text next to it.
+		// |		<html>
+		// |			<head>
+		// |				<script src="/path/to/dojo-toolkit/dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0"></script>
+		// |				<script type="text/javascript">
+		// |					require([
+		// |						"dojo/parser", "dojo/Stateful", "dojo/domReady!"
+		// |					], function(parser, Stateful){
+		// |						model = new Stateful({value: "Foo"});
+		// |						parser.parse();
+		// |					});
+		// |				</script>
+		// |			</head>
+		// |			<body>
+		// |				<script type="dojo/require">at: "dojox/mvc/at"</script>
+		// |				<input type="text" data-dojo-type="dijit/form/TextBox" data-dojo-props="value: at(model, 'value')">
+		// |				<span data-dojo-type="dijit/_WidgetBase" data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at(model, 'value')"></span>
+		// |			</body>
+		// |		</html>
+
+		return { // dojox/mvc/at.handle
+			atsignature: "dojox.mvc.at",
+			target: target,
+			targetProp: targetProp,
+			bindDirection: sync.both,
+			direction: function(/*Number*/ bindDirection){
+				this.bindDirection = bindDirection;
+				return this;
+			},
+			transform: function(/*dojox/mvc/sync.converter*/ converter){
+				this.converter = converter;
+				return this;
+			},
+			equals: function(/*Function*/ equals){
+				this.equalsCallback = equals;
+				return this;
+			}
+		};
+	};
+
+	/*=====
+	at.handle = {
+		// summary:
+		//		A handle of data binding target (a dojo/Stateful property), which is used for start synchronization with data binding source (another dojo/Stateful property).
+
+		// target: dojo/Stateful|String
+		//		The data binding literal or dojo/Stateful to be synchronized.
+		target: new dojo/Stateful(),
+
+		// targetProp: String
+		//		The property name in target to be synchronized.
+		targetProp: "",
+
+		// bindDirection: Number
+		//		The data binding bindDirection, choose from: dojox/mvc/sync.from, dojox/mvc/sync.to or dojox/mvc/sync.both.
+		bindDirection: dojox/mvc/sync.both,
+
+		// converter: dojox/mvc/sync.converter
+		//		Class/object containing the converter functions used when the data goes between data binding target (e.g. data model or controller) to data binding origin (e.g. widget).
+		converter: null,
+
+		direction: function(bindDirection){
+			// summary:
+			//		Sets data binding bindDirection.
+			// bindDirection: Number
+			//		The data binding bindDirection, choose from: dojox/mvc/sync.from, dojox/mvc/sync.to or dojox/mvc/sync.both.
+		},
+
+		transform: function(converter){
+			// summary:
+			//		Attach a data converter.
+			// converter: dojox/mvc/sync.converter
+			//		Class/object containing the converter functions used when the data goes between data binding target (e.g. data model or controller) to data binding origin (e.g. widget).
+		},
+
+		equals: function(equals){
+			// summary:
+			//		Sets a function to check if a value has really been changed when source/target dojo/Stateful changes.
+			// equals: Function
+			//		The function to check for the change.
+			//		Should take two arguments, and should return true when those two are considered equal.
+		}
+	};
+	=====*/
+
+	// Data binding bindDirections
+	at.from = sync.from;
+	at.to = sync.to;
+	at.both = sync.both;
+
+	// lang.setObject() thing is for back-compat, remove it in 2.0
+	return lang.setObject("dojox.mvc.at", at);
+});
diff --git a/dojox/mvc/atBindingExtension.js b/dojox/mvc/atBindingExtension.js
new file mode 100644
index 0000000..2936efe
--- /dev/null
+++ b/dojox/mvc/atBindingExtension.js
@@ -0,0 +1,54 @@
+define([
+	"dojo/aspect",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dijit/_WidgetBase",
+	"./_atBindingMixin",
+	"dijit/registry"
+], function(aspect, array, lang, _WidgetBase, _atBindingMixin){
+	return function(/*dijit/_WidgetBase...*/ w){
+		// summary:
+		//		Monkey-patch the given widget so that they looks at dojox/mvc/at set in them and start data binding specified there.
+		// w: dijit/_WidgetBase...
+		//		The widget.
+
+		array.forEach(arguments, function(w){
+			if(w.dataBindAttr){
+				console.warn("Detected a widget or a widget class that has already been applied data binding extension. Skipping...");
+				return;
+			}
+
+			// Apply the at binding mixin
+			lang._mixin(w, _atBindingMixin.mixin);
+
+			// Monkey patch widget.postscript to get the list of dojox/mvc/at handles before startup
+			aspect.before(w, "postscript", function(/*Object?*/ params, /*DomNode|String*/ srcNodeRef){
+				this._dbpostscript(params, srcNodeRef);
+			});
+
+			// Monkey patch widget.startup to get data binds set up
+			aspect.before(w, "startup", function(){
+				this._startAtWatchHandles();
+			});
+
+			// Monkey patch widget.destroy to remove watches setup in _DataBindingMixin
+			aspect.before(w, "destroy", function(){
+				this._stopAtWatchHandles();
+			});
+
+			// Monkey patch widget.set to establish data binding if a dojox/mvc/at handle comes
+			aspect.around(w, "set", function(oldWidgetBaseSet){
+				return function(/*String*/ name, /*Anything*/ value){
+					if(name == _atBindingMixin.prototype.dataBindAttr){
+						return this._setBind(value);
+					}else if((value || {}).atsignature == "dojox.mvc.at"){
+						return this._setAtWatchHandle(name, value);
+					}
+					return oldWidgetBaseSet.apply(this, lang._toArray(arguments));
+				};
+			});
+		});
+
+		return arguments; // dijit/_WidgetBase...
+	};
+});
diff --git a/dojox/mvc/equals.js b/dojox/mvc/equals.js
new file mode 100644
index 0000000..f8f8ebb
--- /dev/null
+++ b/dojox/mvc/equals.js
@@ -0,0 +1,81 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/Stateful",
+	"./StatefulArray"
+], function(array, lang, Stateful, StatefulArray){
+	var equalsOptions = {
+		// summary:
+		//		Options used for dojox/mvc/equals().
+
+		getType: function(/*Anything*/ v){
+			// summary:
+			//		Returns the type of the given value.
+			// v: Anything
+			//		The value.
+
+			return lang.isArray(v) ? "array" : lang.isFunction((v || {}).getTime) ? "date" : v != null && ({}.toString.call(v) == "[object Object]" || lang.isFunction((v || {}).set) && lang.isFunction((v || {}).watch)) ? "object" : "value";
+		},
+
+		equalsArray: function(/*Anything[]*/ dst, /*Anything[]*/ src){
+			// summary:
+			//		Returns if the given two stateful arrays are equal.
+			// dst: Anything[]
+			//		The array to compare with.
+			// src: Anything[]
+			//		The array to compare with.
+
+			for(var i = 0, l = Math.max(dst.length, src.length); i < l; i++){
+				if(!equals(dst[i], src[i])){ return false; }
+			}
+			return true;
+		},
+
+		equalsDate: function(/*Date*/ dst, /*Date*/ src){
+			return dst.getTime() == src.getTime();
+		},
+
+		equalsObject: function(/*Object*/ dst, /*Object*/ src){
+			// summary:
+			//		Returns if the given two stateful objects are equal.
+			// dst: Object
+			//		The object to compare with.
+			// src: Object
+			//		The object to compare with.
+
+			var list = lang.mixin({}, dst, src);
+			for(var s in list){
+				if(!(s in Stateful.prototype) && s != "_watchCallbacks" && !equals(dst[s], src[s])){ return false; }
+			}
+			return true;
+		},
+
+		equalsValue: function(/*Anything*/ dst, /*Anything*/ src){
+			// summary:
+			//		Returns if the given two values are equal.
+
+			return dst === src; // Boolean
+		}
+	};
+
+	var equals = function(/*Anything*/ dst, /*Anything*/ src, /*dojox/mvc/equalsOptions*/ options){
+		// summary:
+		//		Compares two dojo/Stateful objects, by diving into the leaves.
+		// description:
+		//		Recursively iterates and compares stateful values.
+		// dst: Anything
+		//		The stateful value to compare with.
+		// src: Anything
+		//		The stateful value to compare with.
+		// options: dojox/mvc/equalsOptions
+		//		The object that defines how two stateful values are compared.
+		// returns: Boolean
+		//		True if dst equals to src, false otherwise.
+
+		var opts = options || equals, types = [opts.getType(dst), opts.getType(src)];
+		return types[0] != types[1] ? false : opts["equals" + types[0].replace(/^[a-z]/, function(c){ return c.toUpperCase(); })](dst, src); // Boolean
+	};
+
+	// lang.setObject() thing is for back-compat, remove it in 2.0
+	return lang.setObject("dojox.mvc.equals", lang.mixin(equals, equalsOptions));
+});
diff --git a/dojox/mvc/getPlainValue.js b/dojox/mvc/getPlainValue.js
new file mode 100644
index 0000000..8dcdae3
--- /dev/null
+++ b/dojox/mvc/getPlainValue.js
@@ -0,0 +1,72 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/Stateful"
+], function(array, lang, Stateful){
+	var getPlainValueOptions = {
+		// summary:
+		//		Options used for dojox/mvc/getPlainValue().
+
+		getType: function(/*Anything*/ v){
+			// summary:
+			//		Returns the type of the given value.
+			// v: Anything
+			//		The value.
+			// returns:
+			//		 The type of the given value.
+
+			return lang.isArray(v) ? "array" : v != null && {}.toString.call(v) == "[object Object]" ? "object" : "value";
+		},
+
+		getPlainArray: function(/*Anything[]*/ a){
+			// summary:
+			//		Returns the stateful version of the given array.
+			// a: Anything[]
+			//		The array.
+			// returns:
+			//		 The converted array.
+
+			return array.map(a, function(item){ return getPlainValue(item, this); }, this); // Anything[]
+		},
+
+		getPlainObject: function(/*Object*/ o){
+			// summary:
+			//		Returns the stateful version of the given object.
+			// o: Object
+			//		The object.
+
+			var plain = {};
+			for(var s in o){
+				if(!(s in Stateful.prototype) && s != "_watchCallbacks"){
+					plain[s] = getPlainValue(o[s], this);
+				}
+			}
+			return plain; // Object
+		},
+
+		getPlainValue: function(/*Anything*/ v){
+			// summary:
+			//		Just returns the given value.
+
+			return v; // Anything
+		}
+	};
+
+	var getPlainValue = function(/*Anything*/ value, /*dojox/mvc/getPlainValueOptions*/ options){
+		// summary:
+		//		Create a raw value from a dojo/Stateful object.
+		// description:
+		//		Recursively iterates the stateful value given, and convert them to raw ones.
+		// value: Anything
+		//		The stateful value.
+		// options: dojox/mvc/getPlainValueOptions
+		//		The object that defines how plain value should be created from stateful value.
+		// returns:
+		//		 The converted value.
+
+		return (options || getPlainValue)["getPlain" + (options || getPlainValue).getType(value).replace(/^[a-z]/, function(c){ return c.toUpperCase(); })](value); // Anything
+	};
+
+	// lang.setObject() thing is for back-compat, remove it in 2.0
+	return lang.setObject("dojox.mvc.getPlainValue", lang.mixin(getPlainValue, getPlainValueOptions));
+});
diff --git a/dojox/mvc/getStateful.js b/dojox/mvc/getStateful.js
new file mode 100644
index 0000000..231d335
--- /dev/null
+++ b/dojox/mvc/getStateful.js
@@ -0,0 +1,67 @@
+define([
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/Stateful",
+	"./StatefulArray"
+], function(array, lang, Stateful, StatefulArray){
+	var getStatefulOptions = {
+		// summary:
+		//		Options used for dojox/mvc/getStateful().
+
+		getType: function(/*Anything*/ v){
+			// summary:
+			//		Returns the type of the given value.
+			// v: Anything
+			//		The value.
+
+			return lang.isArray(v) ? "array" : v != null && {}.toString.call(v) == "[object Object]" ? "object" : "value";
+		},
+
+		getStatefulArray: function(/*Anything[]*/ a){
+			// summary:
+			//		Returns the stateful version of the given array.
+			// a: Anything[]
+			//		The array.
+
+			return new StatefulArray(array.map(a, function(item){ return getStateful(item, this); }, this)); // dojox/mvc/StatefulArray
+		},
+
+		getStatefulObject: function(/*Object*/ o){
+			// summary:
+			//		Returns the stateful version of the given object.
+			// o: Object
+			//		The object.
+
+			var stateful = new Stateful();
+			for(var s in o){
+				stateful[s] = getStateful(o[s], this);
+			}
+			return stateful; // dojo/Stateful
+		},
+
+		getStatefulValue: function(/*Anything*/ v){
+			// summary:
+			//		Just returns the given value.
+
+			return v; // Anything
+		}
+	};
+
+	var getStateful = function(/*Anything*/ value, /*dojox/mvc/getStatefulOptions*/ options){
+		// summary:
+		//		Create a dojo/Stateful object from a raw value.
+		// description:
+		//		Recursively iterates the raw value given, and convert them to stateful ones.
+		// value: Anything
+		//		The raw value.
+		// options: dojox/mvc/getStatefulOptions
+		//		The object that defines how model object should be created from plain object hierarchy.
+		// returns: Anything
+		//		 The converted value.
+
+		return (options || getStateful)["getStateful" + (options || getStateful).getType(value).replace(/^[a-z]/, function(c){ return c.toUpperCase(); })](value); // Anything
+	};
+
+	// lang.setObject() thing is for back-compat, remove it in 2.0
+	return lang.setObject("dojox.mvc.getStateful", lang.mixin(getStateful, getStatefulOptions));
+});
diff --git a/dojox/mvc/parserExtension.js b/dojox/mvc/parserExtension.js
new file mode 100644
index 0000000..53c2961
--- /dev/null
+++ b/dojox/mvc/parserExtension.js
@@ -0,0 +1,75 @@
+define([
+	"require",
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/has!dojo-parser?:dojo/_base/window",
+	"dojo/has",
+	"dojo/has!dojo-mobile-parser?:dojo/parser",
+	"dojo/has!dojo-parser?:dojox/mobile/parser",
+	"dojox/mvc/_atBindingMixin",
+	"dojox/mvc/Element"
+], function(require, kernel, lang, win, has, parser, mobileParser, _atBindingMixin){
+
+	// module:
+	//		dojox/mvc/parserExtension
+	// summary:
+	//		A extension of Dojo parser that allows data binding without specifying data-dojo-type.
+
+	has.add("dom-qsa", !!document.createElement("div").querySelectorAll);
+	try{ has.add("dojo-parser", !!require("dojo/parser"));  }catch(e){}
+	try{ has.add("dojo-mobile-parser", !!require("dojox/mobile/parser")); }catch(e){}
+
+	if(has("dojo-parser")){
+		var oldScan = parser.scan;
+
+		parser.scan = function(/*DOMNode?*/ root, /*Object*/ options){
+			// summary:
+			//		Find list of DOM nodes that has data-dojo-bind, but not data-dojo-type.
+			//		And add them to list of DOM nodes to instantiate widget (dojox/mvc/Element).
+
+			return oldScan.apply(this, lang._toArray(arguments)).then(function(list){
+				var dojoType = (options.scope || kernel._scopeName) + "Type",			// typically "dojoType"
+				 attrData = "data-" + (options.scope || kernel._scopeName) + "-",	// typically "data-dojo-"
+				 dataDojoType = attrData + "type";									// typically "data-dojo-type"
+
+				for(var nodes = has("dom-qsa") ? root.querySelectorAll("[" + _atBindingMixin.prototype.dataBindAttr + "]") : root.getElementsByTagName("*"), i = 0, l = nodes.length; i < l; i++){
+					var node = nodes[i], foundBindingInAttribs = false;
+					if(!node.getAttribute(dataDojoType) && !node.getAttribute(dojoType) && node.getAttribute(_atBindingMixin.prototype.dataBindAttr)){
+						list.push({
+							types: ["dojox/mvc/Element"],
+							node: node
+						});
+					}
+				}
+
+				return list;
+			});
+		};
+	}
+
+	if(has("dojo-mobile-parser")){
+		var oldParse = mobileParser.parse;
+
+		mobileParser.parse = function(/*DOMNode?*/ root, /*Object*/ options){
+			// summary:
+			//		Find list of DOM nodes that has data-dojo-bind, but not data-dojo-type.
+			//		Set dojox/mvc/Element to their data-dojo-type.
+
+			var dojoType = ((options || {}).scope || kernel._scopeName) + "Type",		// typically "dojoType"
+			 attrData = "data-" + ((options || {}).scope || kernel._scopeName) + "-",	// typically "data-dojo-"
+			 dataDojoType = attrData + "type";											// typically "data-dojo-type"
+			 nodes = has("dom-qsa") ? (root || win.body()).querySelectorAll("[" + _atBindingMixin.prototype.dataBindAttr + "]") : (root || win.body()).getElementsByTagName("*");
+
+			for(var i = 0, l = nodes.length; i < l; i++){
+				var node = nodes[i], foundBindingInAttribs = false, bindingsInAttribs = [];
+				if(!node.getAttribute(dataDojoType) && !node.getAttribute(dojoType) && node.getAttribute(_atBindingMixin.prototype.dataBindAttr)){
+					node.setAttribute(dataDojoType, "dojox/mvc/Element");
+				}
+			}
+
+			return oldParse.apply(this, lang._toArray(arguments));
+		};
+	}
+
+	return parser || mobileParser;
+});
diff --git a/dojox/mvc/resolve.js b/dojox/mvc/resolve.js
new file mode 100644
index 0000000..ecea4e1
--- /dev/null
+++ b/dojox/mvc/resolve.js
@@ -0,0 +1,36 @@
+define([
+	"dojo/_base/lang",
+	"dijit/registry",
+	"dojo/Stateful"
+], function(lang, registry){
+	var resolve = function(/*dojo/Stateful|String*/ target, /*dojo/Stateful?*/ parent){
+		// summary:
+		//		Find a dojo/Stateful for the target.
+		// description:
+		//		If target is not a string, return target itself.
+		//		If target is "widget:widgetid", returns the widget whose ID is widgetid.
+		//		If target is "rel:object.path", or target is other string, returns an object under parent (if specified) or under global scope.
+		// target: dojo/Stateful|String
+		//		The data binding to resolve.
+		// parent: dojo/Stateful?
+		//		The parent data binding. Used when the data binding is defined inside repeat.
+
+		if(typeof target == "string"){
+			var tokens = target.match(/^(expr|rel|widget):(.*)$/) || [];
+			try{
+				if(tokens[1] == "rel"){
+					target = lang.getObject(tokens[2] || "", false, parent);
+				}else if(tokens[1] == "widget"){
+					target = registry.byId(tokens[2]);
+				}else{
+					target = lang.getObject(tokens[2] || target, false, parent);
+				}
+			}catch(e){}
+		}
+
+		return target; // dojo/Stateful
+	};
+
+	// lang.setObject() thing is for back-compat, remove it in 2.0
+	return lang.setObject("dojox.mvc.resolve", resolve);
+});
diff --git a/dojox/mvc/sync.js b/dojox/mvc/sync.js
new file mode 100644
index 0000000..cfb73af
--- /dev/null
+++ b/dojox/mvc/sync.js
@@ -0,0 +1,260 @@
+define([
+	"dojo/_base/lang",
+	"dojo/_base/config",
+	"dojo/_base/array",
+	"dojo/has"
+], function(lang, config, array, has){
+	var mvc = lang.getObject("dojox.mvc", true);
+	/*=====
+	mvc = {};
+	=====*/
+	
+	/*=====
+	dojox.mvc.sync.converter = {
+		// summary:
+		//		Class/object containing the converter functions used when the data goes between data binding source (e.g. data model or controller) to data binding origin (e.g. widget).
+
+		format: function(value, constraints){
+			// summary:
+			//		The converter function used when the data comes from data binding source (e.g. data model or controller) to data binding origin (e.g. widget).
+			// value: Anything
+			//		The data.
+			// constraints: Object
+			//		The options for data conversion, which is: mixin({}, dataBindingTarget.constraints, dataBindingOrigin.constraints).
+		},
+
+		parse: function(value, constraints){
+			// summary:
+			//		The converter function used when the data comes from data binding origin (e.g. widget) to data binding source (e.g. data model or controller).
+			// value: Anything
+			//		The data.
+			// constraints: Object
+			//		The options for data conversion, which is: mixin({}, dataBindingTarget.constraints, dataBindingOrigin.constraints).
+		}
+	};
+
+	dojox.mvc.sync.options = {
+		// summary:
+		//		Data binding options.
+
+		// bindDirection: Number
+		//		The data binding bindDirection, choose from: dojox.mvc.Bind.from, dojox.mvc.Bind.to or dojox.mvc.Bind.both.
+		bindDirection: dojox/mvc.both,
+
+		// converter: dojox/mvc/sync.converter
+		//		Class/object containing the converter functions used when the data goes between data binding source (e.g. data model or controller) to data binding origin (e.g. widget).
+		converter: null,
+
+		// equals: Function
+		//		The function to check if there really was a change when source/target dojo/Stateful indicates so.
+		//		Should take two arguments, and should return true when those two are considered equal.
+		equals: null
+	};
+	=====*/
+
+	has.add("mvc-bindings-log-api", (config["mvc"] || {}).debugBindings);
+
+	var sync;
+
+	if(has("mvc-bindings-log-api")){
+		function getLogContent(/*dojo/Stateful*/ source, /*String*/ sourceProp, /*dojo/Stateful*/ target, /*String*/ targetProp){
+			return [
+				[target.canConvertToLoggable || !target.declaredClass ? target : target.declaredClass, targetProp].join(":"),
+				[source.canConvertToLoggable || !source.declaredClass ? source : source.declaredClass, sourceProp].join(":")
+			];
+		}
+	}
+
+	function equals(/*Anything*/ dst, /*Anything*/ src){
+		// summary:
+		//		Returns if the given two values are equal.
+
+		return dst === src
+		 || typeof dst == "number" && isNaN(dst) && typeof src == "number" && isNaN(src)
+		 || lang.isFunction((dst || {}).getTime) && lang.isFunction((src || {}).getTime) && dst.getTime() == src.getTime()
+		 || (lang.isFunction((dst || {}).equals) ? dst.equals(src) : lang.isFunction((src || {}).equals) ? src.equals(dst) : false);
+	}
+
+	function copy(/*Function*/ convertFunc, /*Object?*/ constraints, /*Function*/ equals, /*dojo/Stateful*/ source, /*String*/ sourceProp, /*dojo/Stateful*/ target, /*String*/ targetProp, /*Anything*/ old, /*Anything*/ current, /*Object?*/ excludes){
+		// summary:
+		//		Watch for change in property in dojo/Stateful object.
+		// description:
+		//		Called when targetProp property in target is changed. (This is mainly used as a callback function of dojo/Stateful.watch())
+		//		When older value and newer value are different, copies the newer value to sourceProp property in source.
+		// convertFunc: Function
+		//		The data converter function.
+		// constraints: Object?
+		//		The data converter options.
+		// equals: Function
+		//		The function to check if there really was a change when source/target dojo/Stateful indicates so.
+		//		Should take two arguments, and should return true when those two are considered equal.
+		// source: dojo/Stateful
+		//		The dojo/Stateful of copy source.
+		// sourceProp: String
+		//		The property of copy source, specified in data binding. May be wildcarded.
+		// target: dojo/Stateful
+		//		The dojo/Stateful of copy target.
+		// targetProp: String
+		//		The property of copy target, being changed. For wildcard-based data binding, this is used as the property to be copied.
+		// old: Anything
+		//		The older property value.
+		// current: Anything
+		//		The newer property value.
+		// excludes: Object?
+		//		The list of properties that should be excluded from wildcarded data binding.
+
+		// Bail if there is no change in value,
+		// or property name is wildcarded and the property to be copied is not in source property list (and source property list is defined),
+		// or property name is wildcarded and the property to be copied is in explicit "excludes" list
+		if(equals(current, old)
+		 || sourceProp == "*" && array.indexOf(source.get("properties") || [targetProp], targetProp) < 0
+		 || sourceProp == "*" && targetProp in (excludes || {})){ return; }
+
+		var prop = sourceProp == "*" ? targetProp : sourceProp;
+		if(has("mvc-bindings-log-api")){
+			var logContent = getLogContent(source, prop, target, targetProp);
+		}
+
+		try{
+			current = convertFunc ? convertFunc(current, constraints) : current;
+		}catch(e){
+			if(has("mvc-bindings-log-api")){
+				console.log("Copy from" + logContent.join(" to ") + " was not done as an error is thrown in the converter.");
+			}
+			return;
+		}
+
+		if(has("mvc-bindings-log-api")){
+			console.log(logContent.reverse().join(" is being copied from: ") + " (Value: " + current + " from " + old + ")");
+		}
+
+		// Copy the new value to source
+		lang.isFunction(source.set) ? source.set(prop, current) : (source[prop] = current);
+	}
+
+	var directions = {
+		// from: Number
+		//		Data binding goes from the source to the target
+		from: 1,
+
+		// to: Number
+		//		Data binding goes from the target to the source
+		to: 2,
+
+		// both: Number
+		//		Data binding goes in both directions (dojox/mvc/Bind.from | dojox/mvc/Bind.to)
+		both: 3
+	}, undef;
+
+	sync = function(/*dojo/Stateful*/ source, /*String*/ sourceProp, /*dojo/Stateful*/ target, /*String*/ targetProp, /*dojox/mvc/sync.options*/ options){
+		// summary:
+		//		Synchronize two dojo/Stateful properties.
+		// description:
+		//		Synchronize two dojo/Stateful properties.
+		// source: dojo/Stateful
+		//		Source dojo/Stateful to be synchronized.
+		// sourceProp: String
+		//		The property name in source to be synchronized.
+		// target: dojo/Stateful
+		//		Target dojo/Stateful to be synchronized.
+		// targetProp: String
+		//		The property name in target to be synchronized.
+		// options: dojox/mvc/sync.options
+		//		Data binding options.
+		// returns:
+		//		The handle of data binding synchronization.
+
+		var converter = (options || {}).converter, converterInstance, formatFunc, parseFunc;
+		if(converter){
+			converterInstance = {source: source, target: target};
+			formatFunc = converter.format && lang.hitch(converterInstance, converter.format);
+			parseFunc = converter.parse && lang.hitch(converterInstance, converter.parse);
+		}
+
+		var _watchHandles = [],
+		 excludes = [],
+		 list,
+		 constraints = lang.mixin({}, source.constraints, target.constraints),
+		 bindDirection = (options || {}).bindDirection || mvc.both,
+		 equals = (options || {}).equals || sync.equals;
+
+		if(has("mvc-bindings-log-api")){
+			var logContent = getLogContent(source, sourceProp, target, targetProp);
+		}
+
+		if(targetProp == "*"){
+			if(sourceProp != "*"){ throw new Error("Unmatched wildcard is specified between source and target."); }
+			list = target.get("properties");
+			if(!list){
+				list = [];
+				for(var s in target){ if(target.hasOwnProperty(s) && s != "_watchCallbacks"){ list.push(s); } }
+			}
+			excludes = target.get("excludes");
+		}else{
+			list = [sourceProp];
+		}
+
+		if(bindDirection & mvc.from){
+			// Start synchronization from source to target (e.g. from model to widget). For wildcard mode (sourceProp == targetProp == "*"), the 1st argument of watch() is omitted
+			if(lang.isFunction(source.set) && lang.isFunction(source.watch)){
+				_watchHandles.push(source.watch.apply(source, ((sourceProp != "*") ? [sourceProp] : []).concat([function(name, old, current){
+					copy(formatFunc, constraints, equals, target, targetProp, source, name, old, current, excludes);
+				}])));
+			}else if(has("mvc-bindings-log-api")){
+				console.log(logContent.reverse().join(" is not a stateful property. Its change is not reflected to ") + ".");
+			}
+
+			// Initial copy from source to target (e.g. from model to widget)
+			array.forEach(list, function(prop){
+				// In "all properties synchronization" case, copy is not done for properties in "exclude" list
+				if(targetProp != "*" || !(prop in (excludes || {}))){
+					var value = lang.isFunction(source.get) ? source.get(prop) : source[prop];
+					copy(formatFunc, constraints, equals, target, targetProp == "*" ? prop : targetProp, source, prop, undef, value);
+				}
+			});
+		}
+
+		if(bindDirection & mvc.to){
+			if(!(bindDirection & mvc.from)){
+				// Initial copy from source to target (e.g. from model to widget)
+				array.forEach(list, function(prop){
+					// In "all properties synchronization" case, copy is not done for properties in "exclude" list
+					if(targetProp != "*" || !(prop in (excludes || {}))){
+						// Initial copy from target to source (e.g. from widget to model), only done for one-way binding from widget to model
+						var value = lang.isFunction(target.get) ? target.get(targetProp) : target[targetProp];
+						copy(parseFunc, constraints, equals, source, prop, target, targetProp == "*" ? prop : targetProp, undef, value);
+					}
+				});
+			}
+
+			// Start synchronization from target to source (e.g. from widget to model). For wildcard mode (sourceProp == targetProp == "*"), the 1st argument of watch() is omitted
+			if(lang.isFunction(target.set) && lang.isFunction(target.watch)){
+				_watchHandles.push(target.watch.apply(target, ((targetProp != "*") ? [targetProp] : []).concat([function(name, old, current){
+					copy(parseFunc, constraints, equals, source, sourceProp, target, name, old, current, excludes);
+				}])));
+			}else if(has("mvc-bindings-log-api")){
+				console.log(logContent.join(" is not a stateful property. Its change is not reflected to ") + ".");
+			}
+		}
+
+		if(has("mvc-bindings-log-api")){
+			console.log(logContent.join(" is bound to: "));
+		}
+
+		var handle = {};
+		handle.unwatch = handle.remove = function(){
+			for(var h = null; h = _watchHandles.pop();){
+				h.unwatch();
+			}
+			if(has("mvc-bindings-log-api")){
+				console.log(logContent.join(" is unbound from: "));
+			}
+		};
+		return handle; // dojo/handle
+	};
+
+	lang.mixin(mvc, directions);
+
+	// lang.setObject() thing is for back-compat, remove it in 2.0
+	return lang.setObject("dojox.mvc.sync", lang.mixin(sync, {equals: equals}, directions));
+});
diff --git a/dojox/mvc/tests/css/android-format.css b/dojox/mvc/tests/1.7/css/android-format.css
similarity index 100%
copy from dojox/mvc/tests/css/android-format.css
copy to dojox/mvc/tests/1.7/css/android-format.css
diff --git a/dojox/mvc/tests/css/app-format.css b/dojox/mvc/tests/1.7/css/app-format.css
similarity index 100%
copy from dojox/mvc/tests/css/app-format.css
copy to dojox/mvc/tests/1.7/css/app-format.css
diff --git a/dojox/mvc/tests/css/index-format.css b/dojox/mvc/tests/1.7/css/index-format.css
similarity index 100%
copy from dojox/mvc/tests/css/index-format.css
copy to dojox/mvc/tests/1.7/css/index-format.css
diff --git a/dojox/mvc/tests/css/iphone-format.css b/dojox/mvc/tests/1.7/css/iphone-format.css
similarity index 100%
copy from dojox/mvc/tests/css/iphone-format.css
copy to dojox/mvc/tests/1.7/css/iphone-format.css
diff --git a/dojox/mvc/tests/1.7/doh/doh_async_mvc_14491-input-output.html b/dojox/mvc/tests/1.7/doh/doh_async_mvc_14491-input-output.html
new file mode 100644
index 0000000..ec609ff
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_async_mvc_14491-input-output.html
@@ -0,0 +1,161 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH Async Simple Input - Output Group example</title>
+		<style type="text/css">
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../../../dijit/themes/claro/claro.css";
+		</style>
+<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+ 		var model;
+ 
+		require([
+		'dojo/parser',
+        'dojox/mvc',
+		'dojox/mvc/Group',
+		'dojox/mvc/Output',
+		'dojo/parser',
+		'dijit/form/TextBox',
+		'dijit/form/Button'], function(){
+
+			// The dojox.mvc.StatefulModel class creates a data model instance
+			// where each leaf within the data model is decorated with dojo.Stateful
+			// properties that widgets can bind to and watch for their changes.
+			model = dojox.mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
+				require([
+					'doh/runner', 'dijit/dijit'
+				], function(){
+				require([
+					'dojo/domReady!'
+					], function(){
+						doh.register("parse", function() {
+							dojo.parser.parse();
+
+							var detailsGroup = dijit.byId('detailsGroup');
+							detailsGroup.set('ref', model);
+
+						});
+						// should be able to verify all of the inputs 
+						doh.register("check initial values and bindings", [{
+							name : "initial",
+							runTest : function() {
+								doh.is("John", dijit.byId("First").get('value'),"First should be John");
+								doh.is("John",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
+
+								doh.is("Doe", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe");
+								doh.is("Doe",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe");
+
+								doh.is("jdoe at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe at example.com");
+								doh.is("jdoe at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe at example.com");
+							}
+						}]);
+
+						doh.register("update first name", [{
+							name : "Update-First-Name",
+							runTest : function() {
+								var first1, bind1, addr1;
+								//test first relevant false
+								first1 = dijit.byId("First");
+								first1.set("value","John-update");
+								if (first1) {
+									doh.is("John-update", dijit.byId("First").get('value'),"First should be John");
+									doh.is("John-update",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
+								}
+							}
+						}]);
+						doh.register("update last name", [{
+							name : "Update-Last-Name",
+							runTest : function() {
+								var last;
+								//test first relevant false
+								last = dijit.byId("lastnameInput");
+								last.set("value","Doe-update");
+								if (last) {
+									doh.is("Doe-update", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe-update");
+									doh.is("Doe-update",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe-update");
+								}
+							}
+						}]);
+						doh.register("update last name", [{
+							name : "Update-Last-Name",
+							runTest : function() {
+								var last;
+								//test first relevant false
+								email = dijit.byId("emailInput");
+								email.set("value","jdoe-update at example.com");
+								if (email) {
+									doh.is("jdoe-update at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe-update at example.com");
+									doh.is("jdoe-update at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe-update at example.com");
+								}
+							}
+						}]);
+						doh.register("reset back to initial values and bindings", [{
+							name : "reset_test",
+							runTest : function() {
+								model.reset();
+								doh.is("John", dijit.byId("First").get('value'),"First should be John");
+								doh.is("John",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
+
+								doh.is("Doe", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe");
+								doh.is("Doe",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe");
+
+								doh.is("jdoe at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe at example.com");
+								doh.is("jdoe at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe at example.com");
+							}
+						}]);
+
+						doh.run();
+
+					});
+				});	
+		}); 
+		</script>
+</head>
+	<body class="claro">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Async Input Ouput Test</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="detailsGroup" dojoType="dojox.mvc.Group">
+					<div class="row">
+						<label class="cell" for="First">First:</label>
+						<input class="cell" id="First" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.First"></input>
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'First'">
+						(first name is: ${this.value})
+						</span>
+					</div>
+				<div class="row">
+					<label class="cell" for="lastnameInput">Last:</label>
+					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Last"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Last'">
+						(last name is: ${this.value})
+					</span>
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Email"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Email'">
+					(email is: ${this.value})
+					</span>
+				</div>
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+				</div>
+			</div>
+		</div>
+	</body>
+
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_async_mvc_input-output-simple.html b/dojox/mvc/tests/1.7/doh/doh_async_mvc_input-output-simple.html
new file mode 100644
index 0000000..3d319d2
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_async_mvc_input-output-simple.html
@@ -0,0 +1,158 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH Async Simple Input - Output Group example</title>
+		<style type="text/css">
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+			@import "../../../../../dijit/themes/claro/claro.css";
+		</style>
+<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+ 		var model;
+ 
+		require([
+		'dojo/parser',
+        'dojox/mvc',
+		'dojox/mvc/Group',
+		'dojox/mvc/Output',
+		'dojo/parser',
+		'dijit/form/TextBox',
+		'dijit/form/Button'], function(){
+
+			// The dojox.mvc.StatefulModel class creates a data model instance
+			// where each leaf within the data model is decorated with dojo.Stateful
+			// properties that widgets can bind to and watch for their changes.
+			model = dojox.mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
+				require([
+					'doh/runner', 'dijit/dijit'
+				], function(){
+				require([
+					'dojo/domReady!'
+					], function(){
+						doh.register("parse", function() {
+							dojo.parser.parse();
+						});
+						// should be able to verify all of the inputs 
+						doh.register("check initial values and bindings", [{
+							name : "initial",
+							runTest : function() {
+								doh.is("John", dijit.byId("firstnameInput").get('value'),"firstnameInput should be John");
+								doh.is("John",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
+
+								doh.is("Doe", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe");
+								doh.is("Doe",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe");
+
+								doh.is("jdoe at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe at example.com");
+								doh.is("jdoe at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe at example.com");
+							}
+						}]);
+
+						doh.register("update first name", [{
+							name : "Update-First-Name",
+							runTest : function() {
+								var first1, bind1, addr1;
+								//test first relevant false
+								first1 = dijit.byId("firstnameInput");
+								first1.set("value","John-update");
+								if (first1) {
+									doh.is("John-update", dijit.byId("firstnameInput").get('value'),"firstnameInput should be John");
+									doh.is("John-update",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
+								}
+							}
+						}]);
+						doh.register("update last name", [{
+							name : "Update-Last-Name",
+							runTest : function() {
+								var last;
+								//test first relevant false
+								last = dijit.byId("lastnameInput");
+								last.set("value","Doe-update");
+								if (last) {
+									doh.is("Doe-update", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe-update");
+									doh.is("Doe-update",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe-update");
+								}
+							}
+						}]);
+						doh.register("update last name", [{
+							name : "Update-Last-Name",
+							runTest : function() {
+								var last;
+								//test first relevant false
+								email = dijit.byId("emailInput");
+								email.set("value","jdoe-update at example.com");
+								if (email) {
+									doh.is("jdoe-update at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe-update at example.com");
+									doh.is("jdoe-update at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe-update at example.com");
+								}
+							}
+						}]);
+						doh.register("reset back to initial values and bindings", [{
+							name : "reset_test",
+							runTest : function() {
+								model.reset();
+								doh.is("John", dijit.byId("firstnameInput").get('value'),"firstnameInput should be John");
+								doh.is("John",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
+
+								doh.is("Doe", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe");
+								doh.is("Doe",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe");
+
+								doh.is("jdoe at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe at example.com");
+								doh.is("jdoe at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe at example.com");
+							}
+						}]);
+
+						doh.run();
+
+					});
+				});	
+		}); 
+		</script>
+</head>
+	<body class="claro">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Async Input Ouput Test</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent" dojoType="dojox.mvc.Group" data-dojo-props="ref: 'expr:model'">
+					<div class="row">
+						<label class="cell" for="firstnameInput">First:</label>
+						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.First"></input>
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'First'">
+						(first name is: ${this.value})
+						</span>
+					</div>
+				<div class="row">
+					<label class="cell" for="lastnameInput">Last:</label>
+					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Last"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Last'">
+						(last name is: ${this.value})
+					</span>
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Email"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Email'">
+					(email is: ${this.value})
+					</span>
+				</div>
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+				</div>
+			</div>
+		</div>
+	</body>
+
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_async_mvc_mobile-demo.html b/dojox/mvc/tests/1.7/doh/doh_async_mvc_mobile-demo.html
new file mode 100644
index 0000000..b3803eb
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_async_mvc_mobile-demo.html
@@ -0,0 +1,342 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH Async MVC Mobile Demo Test</title>
+		<link rel="stylesheet" type="text/css" href="./mobile/demo/demo.css"/>		
+		<style>
+		
+		html, body{
+			height: 100%;
+			overflow: hidden;
+			position: relative;
+		}
+		.mblEdgeToEdgeList {
+			background-color: #DBDDE2;
+		}
+		</style>
+<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../dojo/dojo.js"></script>
+
+<script type="text/javascript">
+var repeatModel, setRef, nextIndexToAdd, selectedIndex;
+var setRef, setDetailsContext, insertResult, updateView, updateModel;
+
+require([
+	'dojox/mobile/parser',
+	'dojox/mvc',
+	'dojox/mobile',
+	'dojox/mobile/ScrollableView',
+	'dojox/mobile/Button',
+	'dojox/mobile/TextArea',
+	'dojox/mvc/Group',
+	'dojox/mvc/Generate',
+	'dojox/mvc/Repeat',
+	'dojox/mobile/TextBox',
+	'dojox/mobile/ViewController',
+	'dojox/mobile/FixedSplitter',
+	'dojox/mobile/EdgeToEdgeList',
+	'dojox/mobile/EdgeToEdgeCategory',
+	'dojox/mobile/deviceTheme',
+	'dojox/mobile/RoundRectCategory',
+	'dojox/mobile/Heading',
+	'dojo/data/ItemFileWriteStore',
+	'dojo/store/DataStore'	
+], function(){
+	require([
+	         "dojox/mobile/compat"
+	]);
+
+	var names = {
+	"Serial" : "360324",
+	"First"  : "John",
+	"Last"   : "Doe",
+	"Email"  : "jdoe at us.ibm.com",
+	"ShipTo" : {
+		"Street" : "123 Valley Rd",
+		"City"   : "Katonah",
+		"State"  : "NY",
+		"Zip"    : "10536"
+	},
+	"BillTo" : {
+		"Street" : "17 Skyline Dr",
+		"City"   : "Hawthorne",
+		"State"  : "NY",
+		"Zip"    : "10532"
+	}
+};
+
+selectedIndex = 0;
+
+model = dojox.mvc.newStatefulModel({ data : names });
+repeatmodel = null;  // use store for repeat data 
+nextIndexToAdd = -1;
+
+ // used in the Ship to - Bill to demo
+setRef = function(id, addrRef) {
+	var widget = dijit.byId(id);
+	widget.set("ref", addrRef);
+}
+
+// used in the Repeat Data binding demo
+setDetailsContext = function(index){
+	selectedIndex = index;
+	var groupRoot = dijit.byId("detailsGroup");
+	groupRoot.set("ref", index);
+}
+
+// used in the Repeat Data binding demo
+insertResult = function(index){
+	if (repeatmodel[index-1].First.value !== ""){ // TODO: figure out why we are getting called twice for each click
+		var insert = dojox.mvc.newStatefulModel({ "data" : {
+			"First"   : "",
+			"Last"    : "",
+			"Location": "CA",
+			"Office"  : "",
+			"Email"   : "",
+			"Tel"     : "",
+			"Fax"     : ""} 
+		});
+		repeatmodel.add(index, insert);
+		setDetailsContext(index);
+		nextIndexToAdd++;
+	}else{
+		setDetailsContext(index-1);                 
+	}
+};
+
+// used in the Generate View demo
+var genmodel;
+updateView = function() {
+	try {
+		var modeldata = dojo.fromJson(dojo.byId("modelArea").value);
+		genmodel = dojox.mvc.newStatefulModel({ data : modeldata });
+		dijit.byId("view").set("ref", genmodel);
+		dojo.byId("outerModelArea").style.display = "none";
+		dojo.byId("viewArea").style.display = "";              		
+	}catch(err){
+		console.error("Error parsing json from model: "+err);
+	}
+};
+
+// used in the Generate View demo
+updateModel = function() {
+	dojo.byId("outerModelArea").style.display = "";
+	try {
+		dojo.byId("modelArea").focus(); // hack: do this to force focus off of the textbox, bug on mobile?
+		dojo.byId("viewArea").style.display = "none";
+		dijit.byId("modelArea").set("value",(dojo.toJson(genmodel.toPlainObject(), true)));
+	} catch(e) {
+		console.log(e);
+	};
+};
+
+
+// The dojox.mvc.StatefulModel class creates a data model instance
+// where each leaf within the data model is decorated with dojo.Stateful
+// properties that widgets can bind to and watch for their changes.
+var writeStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests.1.7/_data", "mvcRepeatData.json")});
+var modelPromise = dojox.mvc.newStatefulModel({store: new dojo.store.DataStore({store: writeStore}), query:{"Location" : "CA"}}); // example of using a query parm for Location 
+
+				require([
+					'doh/runner', 'dijit/dijit'
+				], function(){
+				require([
+					'dojo/domReady!'
+					], function(){
+				modelPromise.then(function(results){ 
+					repeatmodel = results;
+					nextIndexToAdd = repeatmodel.data.length;
+					console.log("before call to parser.parse");
+					dojox.mobile.parser.parse();
+					console.log("before call to set the wholepage style for display");	
+					dojo.byId("wholepage").style.display = "";
+					console.log("after call to set the wholepage style for display");	
+						doh.register("check initial display", [{
+							name : "initial",
+							runTest : function() {
+								var x = dojo.query(".mblListItemLabel");
+								var y0 = dojo.query(".mblListItemLabel", dijit.byId("sdb").domNode)[0].innerHTML;
+								var y1 = dojo.query(".mblListItemLabel", dijit.byId("rdb").domNode)[0];
+								var y2 = dojo.query(".mblListItemLabel", dijit.byId("sfg").domNode)[0];
+								console.debug("dijit.byId(sdb).domNode)[0].innerHTML is ["+y0+"]");
+								doh.is("Simple Data Binding", dojo.trim(dojo.query(".mblListItemLabel", dijit.byId("sdb").domNode)[0].innerHTML),"first one should be Simple Data Binding");
+								doh.is("Repeat Data Binding", dojo.trim(dojo.query(".mblListItemLabel", dijit.byId("rdb").domNode)[0].innerHTML),"first one should be Simple Data Binding");
+								doh.is("Simple Form Generate", dojo.trim(dojo.query(".mblListItemLabel", dijit.byId("sfg").domNode)[0].innerHTML),"first one should be Simple Data Binding");
+							}
+						}]);
+						doh.run();
+				});
+			});
+		});
+
+dojo.addOnLoad(function() {
+});
+
+}); // end function
+		</script>
+</head>
+	<body>
+	<div id="wholepage" style="display:none">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Mobile MVC Views</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="sdb" dojoType="dojox.mobile.ListItem" icon="mobile/demo/images/i-icon-1.png" transition="slide" moveTo="settings">
+					Simple Data Binding
+				</li>
+				<li id="rdb" dojoType="dojox.mobile.ListItem" icon="mobile/demo/images/i-icon-2.png" transition="slide" moveTo="repeat">
+					Repeat Data Binding
+				</li>
+				<li id="sfg" dojoType="dojox.mobile.ListItem" icon="mobile/demo/images/i-icon-3.png" transition="slide" moveTo="generate">
+					Simple Form Generate
+				</li>
+			</ul>
+		</div>
+
+	<div id="settings" dojoType="dojox.mobile.ScrollableView">
+		<h1 id="home" dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Data Binding Example</h1>
+		<form name="testForm" id="testForm">	
+		<div class="field-title">Ship to - Bill to Address</div>
+			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
+				<div class="field-row">
+					<span>Order #</span>
+					<input id="lastnameInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Order #" ref="'rel:Serial'"/>
+				</div>
+				<div class="field-row">
+					<span>Last</span>
+					<input  id="serialInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Last'"/>
+				</div>
+				<div class="field-row">
+					<span>Email</span>
+					<input  id="emailInput1" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Email'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
+			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
+				<div class="field-row">
+					<span>Street</span>
+					<input  id="streetInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Street" ref="'rel:Street'"/>
+				</div>
+				<div class="field-row">
+					<span>City</span>
+					<input  id="cityInput" dojoType="dojox.mobile.TextBox"
+						placeholder="City" ref="'rel:City'"/>
+				</div>
+				<div class="field-row">
+					<span>State</span>
+					<input  id="stateInput" dojoType="dojox.mobile.TextBox"
+						placeholder="State" ref="'rel:State'"/>
+				</div>
+				<div class="field-row">
+					<span>ZIP Code</span>
+					<input  id="zipInput" dojoType="dojox.mobile.TextBox"
+						placeholder="ZIP Code" ref="'rel:Zip'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
+		</form>
+	</div>
+
+	<div id="repeat" dojoType="dojox.mobile.ScrollableView">
+		<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Repeat Data Binding Example</h1>
+		<form name="repeatTestForm" id="repeatTestForm">	
+		<div class="field-title">Search Results</div>
+			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
+				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
+					<div class="row">			 
+						<input dojoType="dojox.mobile.TextBox"
+							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
+						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
+					</div>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
+				<div id="detailsBanner">Details for selected index:</div>
+					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
+						<div class="field-row">
+							<span>First Name</span>
+							<input  id="firstInput" dojoType="dojox.mobile.TextBox"
+								placeholder="First Name" ref="'rel:First'"/>
+						</div>
+						<div class="field-row">
+							<span>Last Name</span>
+							<input id="lastInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Last Name" ref="'rel:Last'"/>
+						</div>
+						<div class="field-row">
+							<span>Email</span>
+							<input  id="emailInput2" dojoType="dojox.mobile.TextBox"
+								placeholder="Email" ref="'rel:Email'"/>
+						</div>
+						<div class="field-row">
+							<span>Telephone</span>
+							<input  id="telInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Telephone" ref="'rel:Tel'"/>
+						</div>
+					</div>
+				</div>
+			<div class="spacer"></div>
+			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
+			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
+			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
+		</form>
+
+	</div>
+
+	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" back="Home" moveTo="foo">Simple Form Generate Example</h1>
+		<div class="field-title"></div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent" class="generate-maincontent">
+					<div id="outerModelArea">
+						<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Model</h3>
+						<div class="generate-textarea-row">
+							<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+							</textarea>
+						</div>
+						<div class="fieldset">
+							<div class="spacer"></div>
+							<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
+						</div>
+					</div>
+					<div id="viewArea" style="display:none">
+						<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Generated View</h3>
+							<div class="fieldset">
+							<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
+						</div>
+						<div class="fieldset">
+							<div class="spacer"></div>
+							<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+	</body>
+
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_async_mvc_zero-value-test.html b/dojox/mvc/tests/1.7/doh/doh_async_mvc_zero-value-test.html
new file mode 100644
index 0000000..ac5bf85
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_async_mvc_zero-value-test.html
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH Async Simple Input - Output Group example</title>
+		<style type="text/css">
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../../../dijit/themes/claro/claro.css";
+		</style>
+<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+ 		var model;
+ 
+		require([
+		'dojo/parser',
+        'dojox/mvc',
+        'dojo/dom',
+        'dojo/ready',
+		'dojox/mvc/Group',
+		'dojox/mvc/Output',
+		'dojo/parser',
+		'dijit/form/Form',
+		'dijit/form/TextBox',
+		'dijit/form/Button'], function(parser, mvc, dom, ready){
+
+			var order = {"First" : 0};
+			model = mvc.newStatefulModel({data : order});
+
+			var zip = {"First" : 0};
+			zipmodel = mvc.newStatefulModel({data : zip});
+
+			require([
+						'doh/runner', 'dijit/dijit'
+					], function(){
+					require([
+						'dojo/domReady!'
+						], function(){
+							parser.parse();
+							var detailsGroup = dijit.byId('detailsGroup');
+							detailsGroup.set('ref', model);
+
+						// should be able to verify all of the inputs 
+						doh.register("check initial values and bindings", [{
+							name : "initial",
+							runTest : function() {
+								doh.is("Priority: 0", dom.byId("one").innerHTML,"One should be set to Priority: 0");
+								doh.is("0", dom.byId("two").innerHTML,"One should be set to Priority: 0");
+								doh.is("Priority: 0", dom.byId("three").innerHTML,"One should be set to Priority: 0");
+								doh.is("0", dom.byId("four").innerHTML,"One should be set to Priority: 0");
+								doh.is("0",  dijit.byId("FirstWork").get('value'),"FirstWork should be 0");
+								doh.is("0",  dijit.byId("First").get('value'),"FirstWork should be 0");
+							}
+						}]);
+
+						doh.register("update first name", [{
+							name : "Update-First-Name",
+							runTest : function() {
+								var first1, bind1, addr1;
+								//test first relevant false
+								first1 = dijit.byId("First");
+								first1.set("value",2);
+								if (first1) {
+									doh.is("Priority: 0", dom.byId("one").innerHTML,"One should be set to Priority: 0");
+									doh.is("0", dom.byId("two").innerHTML,"One should be set to Priority: 0");
+									doh.is("Priority: 2", dom.byId("three").innerHTML,"One should be set to Priority: 0");
+									doh.is("2", dom.byId("four").innerHTML,"One should be set to Priority: 0");
+									doh.is("2",  dijit.byId("FirstWork").get('value'),"FirstWork should be 0");
+									doh.is("2",  dijit.byId("First").get('value'),"FirstWork should be 0");
+								}
+							}
+						}]);
+
+						doh.register("test ref set 0", [{
+							name : "test-ref-set-0",
+							runTest : function() {
+								var first1, bind1, addr1;
+								//test first relevant false
+								first1 = dijit.byId("First");
+								first1.set("value",0);
+								if (first1) {
+									doh.is("Priority: 0", dom.byId("one").innerHTML,"One should be set to Priority: 0");
+									doh.is("0", dom.byId("two").innerHTML,"One should be set to Priority: 0");
+									doh.is("Priority: 0", dom.byId("three").innerHTML,"One should be set to Priority: 0");
+									doh.is("0", dom.byId("four").innerHTML,"One should be set to Priority: 0");
+									doh.is("0",  dijit.byId("FirstWork").get('value'),"FirstWork should be 0");
+									doh.is("0",  dijit.byId("First").get('value'),"FirstWork should be 0");
+								}
+							}
+						}]);
+						doh.run();
+
+
+					});
+				});	
+		}); 
+		</script>
+</head>
+<body>
+	<br>
+	<span> There should be "Priority : zero" here ===></span>
+	<span id="one" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: zipmodel.First, exprchar:'#'">Priority: #{this.value}</span>
+	<span><== there should be "Priority : zero" here.</span>
+	<br>
+	<span> There should be a zero here ===></span>
+	<span id="two" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: zipmodel.First, exprchar:'#'"></span>
+	<span><== there should be a zero here.</span>
+	<br>
+
+	<div data-dojo-type="dijit.form.Form">
+			<div id="detailsGroup" data-dojo-type="dojox.mvc.Group">
+				Working sample
+				<span> There should be "Priority : zero" here ===></span>
+				<span id="three" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'First'">Priority: ${this.value}</span>
+				<span><== there should be "Priority : zero" here.</span>
+				<br>
+				Working sample 2
+				<span> There should be a zero here ===></span>
+				<span id="four" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'First'"></span>
+				<span><== there should be a zero here.</span>
+				<br>
+				<br>
+				<ul>
+					<li>
+					<label for="FirstWork">Working</label> 				
+					<input name="FirstWork" id="FirstWork" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'" /></li>
+				</ul>
+				Here, id is the same as ref, this was not working before the fix for 14491
+				<ul>
+					<li>
+					<label for="First">Not working</label>
+					<input name="First" id="First" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'" /></li>
+					<!--	<input name="First" id="First" data-dojo-type="dijit.form.TextBox" /></li> -->
+				</ul>
+			</div>
+		</div>
+	</body>
+
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_mvc_binding-simple.html b/dojox/mvc/tests/1.7/doh/doh_mvc_binding-simple.html
new file mode 100644
index 0000000..3cc26cb
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_mvc_binding-simple.html
@@ -0,0 +1,429 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>MVC DOH Test</title>
+
+	<style>
+		@import "../../../../../dojo/resources/dojo.css";
+		@import "../../../../../dijit/tests/css/dijitTests.css";
+		@import "../css/app-format.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script src="../../../../../dojo/dojo.js" type="text/javascript"
+		djConfig="isDebug: true">
+	</script>
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("dojox.mvc");
+		dojo.require("dojox.mvc.Output");
+		dojo.require("dijit.form.TextBox");
+		dojo.require("dijit.form.NumberTextBox");
+		dojo.require("dijit.form.ValidationTextBox");
+		dojo.require("dijit.form.Button");
+		dojo.require("dojo.parser");
+
+		// The dojox.mvc.StatefulModel class creates a data model instance
+		// where each leaf within the data model is decorated with dojo.Stateful
+		// properties that widgets can bind to and watch for their changes.
+		var model = dojox.mvc.newStatefulModel({ data : 
+			{	"First" : "John", 
+				"Last" : "Doe", 
+				"Email" : "jdoe at example.com", 
+				"Num" : 3 
+			}
+		});
+
+		function testFirstRelevance(newValue) {
+			//newValue = model.First.value;
+			if ( newValue !== "0" ) return true;
+			else return false;
+		}
+
+		function testFirstReadOnly(newValue) {
+			if ( newValue !== "2" && newValue !== "3"  ) return false;
+			else return true;
+		}
+
+		function testNumValid(newValue) {
+			if ( newValue !== 1 && newValue !== "1"	 && newValue !== "3") return true;
+			else return false;
+		}
+
+		function testRequired(newValue) {
+			if ( newValue !== 4 && newValue !== "4") return false;
+			else return true;
+		}
+
+		function testLastRelevance(newValue) {
+			//newValue = model.First.value;
+			if ( newValue !== "0" ) return true;
+			else return false;
+		}
+
+		function testLastValid(newValue) {
+			if ( newValue !== "1" ) return true;
+			else return false;
+		}
+		
+		  
+		function init(){
+			// bindSelfProperties tests
+			//"readOnly"
+		}
+		  
+	</script>
+
+	<script type="text/javascript">
+		dojo.require('doh.runner');
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
+
+		dojo.addOnLoad(function() {
+
+		doh.register("parse", function() {
+			dojo.parser.parse();
+		});
+
+		// Setup Bindings
+		dojox.mvc.bind(model.First, "value", model.First, "readOnly", testFirstReadOnly, true);
+		dojox.mvc.bind(model.First, "value", model.First, "relevant", testFirstRelevance, true);
+		dojox.mvc.bind(model.First, "value", model.First, "valid", testNumValid, true);
+		dojox.mvc.bind(model.Num, "value", model.Num, "valid", testNumValid, true);
+
+		// bind tests bind Last value to Email relevant and valid
+		dojox.mvc.bind(model.Last, "value", model.Email, "relevant", testFirstRelevance, true);
+		dojox.mvc.bind(model.Last, "value", model.Email, "valid", testNumValid, true);
+		dojox.mvc.bind(model.Last, "value", model.Email, "readOnly", testFirstReadOnly, true);
+		dojox.mvc.bind(model.Last, "value", model.Email, "required", testRequired, true);
+		dojox.mvc.bind(model.Last, "value", model.Email, "value");
+
+		// should be able to verify all of the inputs 
+		doh.register("check initial values and bindings", [{
+			name : "initial",
+			runTest : function() {
+				// First test an empty array
+				var m = new dojox.mvc.newStatefulModel({ data: {arr: []} });
+				doh.is([],m.arr.toPlainObject(),"m.arr.toPlainObject()should be [].");
+				doh.is("object",typeof m.arr.toPlainObject(),"m.arr.toPlainObject() should be an object (array)");
+				doh.is(0,m.arr.toPlainObject().length,"m.arr.toPlainObject().length should be 0 for [].");
+
+				var m2 = new dojox.mvc.newStatefulModel({ data: {str: ""} });
+				doh.is("",m2.str.toPlainObject(),"m2.str.toPlainObject()should be [].");
+				doh.is("string",typeof m2.str.toPlainObject(),"m2.str.toPlainObject() should be a string.");
+				doh.is(0,m2.str.toPlainObject().length,"m2.str.toPlainObject().length should be 0 for an empty string.");
+
+
+				var first1, bind1, addr1;
+				//test serialInput
+				first1 = dijit.byId("firstnameInput");
+				if (first1) {
+					bind1 = first1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false");
+						//doh.t(bind1.relevant,"bind1.relevant should be true");
+						doh.f(bind1.required,"bind1.required should be false");
+						//doh.t(bind1.valid,"bind1.valid should be true");
+					}
+				}
+				//test emailInput
+				addr1 = dijit.byId("emailInput");
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false");
+						//doh.t(bind1.relevant,"bind1.relevant should be true");
+						doh.f(bind1.required,"bind1.required should be false");
+						//doh.t(bind1.valid,"bind1.valid should be true");
+					}
+				}
+			}
+		}]);
+
+		doh.register("check FirstUpdate", [{
+			name : "testFirstUpdate",
+			runTest : function() {
+				//setRef("addrGroup", masterRecord.BillTo);
+				var first1, bind1, addr1;
+				//test first relevant false
+				first1 = dijit.byId("firstnameInput");
+				first1.set("value","0");
+				if (first1) {
+					bind1 = first1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false");
+						doh.f(bind1.relevant,"bind1.relevant should be false");
+						doh.f(bind1.required,"bind1.required should be false");
+						doh.t(bind1.valid,"bind1.valid should be true");
+					}
+				}
+				//test first valid false
+				first1.set("value","1");
+				if (first1) {
+					bind1 = first1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false for value = 1");
+						doh.t(bind1.relevant,"bind1.relevant should be true for value = 1");
+						doh.f(bind1.required,"bind1.required should be false for value = 1");
+						doh.f(bind1.valid,"bind1.valid should be false for value = 1");
+					}
+				}
+				//test first readOnly true
+				first1.set("value","2");
+				if (first1) {
+					bind1 = first1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.t(bind1.relevant,"bind1.relevant should be true for value = 2");
+						doh.f(bind1.required,"bind1.required should be false for value = 2");
+						doh.t(bind1.valid,"bind1.valid should be true for value = 2");
+						doh.t(bind1.readOnly,"bind1.readOnly should be true for value = 2");
+					}
+				}
+				//test first readOnly true and valid false
+				first1.set("value","3");
+				if (first1) {
+					bind1 = first1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.t(bind1.readOnly,"bind1.readOnly should be true for value = 3");
+						doh.t(bind1.relevant,"bind1.relevant should be true for value = 3");
+						doh.f(bind1.required,"bind1.required should be false for value = 3");
+						doh.f(bind1.valid,"bind1.valid should be false for value = 3");
+					}
+				}
+				//test first back to original
+				first1.set("value","5");
+				if (first1) {
+					bind1 = first1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false for value = 5");
+						doh.t(bind1.relevant,"bind1.relevant should be true for value = 5");
+						doh.f(bind1.required,"bind1.required should be false for value = 5");
+						doh.t(bind1.valid,"bind1.valid should be ture for value = 5");
+					}
+				}
+			}
+		}]);
+
+
+		doh.register("check NumUpdate", [{
+			name : "testNumUpdate",
+			runTest : function() {
+				var first1, bind1, addr1;
+				//test first valid false
+				num1 = dijit.byId("numInput");
+				num1.set("value",1);
+				if (num1) {
+					bind1 = num1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false for value = 1");
+						//doh.t(bind1.relevant,"bind1.relevant should be true for value = 1");
+						doh.f(bind1.required,"bind1.required should be false for value = 1");
+						doh.f(bind1.valid,"bind1.valid should be false for value = 1");
+					}
+				}				
+				num1.set("value",5);
+				if (num1) {
+					bind1 = num1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false for value = 5");
+						//doh.t(bind1.relevant,"bind1.relevant should be true for value = 5");
+						doh.f(bind1.required,"bind1.required should be false for value = 5");
+						doh.t(bind1.valid,"bind1.valid should be true for value = 5");
+					}
+				}				
+			}
+		}]);
+
+		doh.register("check emailUpdate", [{
+			name : "testNumUpdate",
+			runTest : function() {
+				var last1, email1, bind1, addr1;
+				//test first valid false
+				last1 = dijit.byId("lastnameInput");
+				email1 = dijit.byId("emailInput");
+				
+				//test last = 5 for original
+				last1.set("value","5");
+				if (email1) {
+					bind1 = email1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false for email value = 5");
+						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 5");
+						doh.f(bind1.required,"bind1.required should be false for email value = 5");
+						doh.t(bind1.valid,"bind1.valid should be true for email value = 5");
+					}
+				}				
+				//test last = 0 for email relevant = false
+				last1.set("value","0");
+				if (email1) {
+					bind1 = email1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false for email value = 0");
+						doh.f(bind1.relevant,"bind1.relevant should be false for email value = 0");
+						doh.f(bind1.required,"bind1.required should be false for email value = 0");
+						doh.t(bind1.valid,"bind1.valid should be true for email value = 0");
+					}
+				}				
+				//test last = 1 for email valid = false
+				last1.set("value","1");
+				if (email1) {
+					bind1 = email1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false for email value = 1");
+						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 1");
+						doh.f(bind1.required,"bind1.required should be false for email value = 1");
+						doh.f(bind1.valid,"bind1.valid should be false for email value = 1");
+					}
+				}				
+				//test last = 2 for email readOnly true
+				last1.set("value","2");
+				if (email1) {
+					bind1 = email1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.t(bind1.readOnly,"bind1.readOnly should be true for email value = 2");
+						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 2");
+						doh.f(bind1.required,"bind1.required should be false for email value = 2");
+						doh.t(bind1.valid,"bind1.valid should be true for email value = 2");
+					}
+				}				
+				//test last = 3 for email readOnly true and email valid = false
+				last1.set("value","3");
+				if (email1) {
+					bind1 = email1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.t(bind1.readOnly,"bind1.readOnly should be true for email value = 3");
+						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 3");
+						doh.f(bind1.required,"bind1.required should be false for email value = 3");
+						doh.f(bind1.valid,"bind1.valid should be false for email value = 3");
+					}
+				}				
+				//test last = 4 for email required true 
+				last1.set("value","4");
+				if (email1) {
+					bind1 = email1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false for email value = 4");
+						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 4");
+						doh.t(bind1.required,"bind1.required should be true for email value = 4");
+						doh.t(bind1.valid,"bind1.valid should be true for email value = 4");
+					}
+				}				
+
+				//test last = 5 for back to original
+				last1.set("value","5");
+				if (email1) {
+					bind1 = email1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.f(bind1.readOnly,"bind1.readOnly should be false for email value = 5");
+						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 5");
+						doh.f(bind1.required,"bind1.required should be false for email value = 5");
+						doh.t(bind1.valid,"bind1.valid should be true for email value = 5");
+					}
+				}				
+			
+			}
+		}]);
+
+		doh.run();
+
+		});
+	</script>
+</head>
+
+	<body class="claro">
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Binding Tests</h1>
+		  </div>
+		</div>
+		<div id="main">
+		  <div id="leftNav">
+		  </div>
+		  <div id="mainContent">
+			<h2>Bind Self Tests</h2>
+			<div class="row">
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 0 to test for Relevant false (use Reset to re-enable)</label>
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 1 to test for Valid false.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 2 to test for ReadOnly false (use Reset to re-enable)</label>
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 3 to test for ReadOnly false and Valid false (use Reset to re-enable)</label>
+			</div>			
+			<div class="row">
+				<label class="cell" for="firstnameInput">First:</label>
+				<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.ValidationTextBox"
+									data-dojo-props="ref: model.First"/>
+				<!-- Content in output below will always be in sync with value of textbox above -->
+				<span id="tout" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
+					(first name is: ${this.value})
+				</span>
+				
+			</div>
+		   <div class="row">
+				<label class="cell" for="firstnameInput"></label>
+				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
+					Relevant is:  ${this.ref.relevant}, Valid is: ${this.ref.valid}, ReadOnly is: ${this.ref.readOnly})
+				</span>			   
+			</div>
+			<div class="row">
+				<label style="display:inline-block; width:100%; text-align:left;">Num: Enter 1 for Valid false</label>
+			</div>
+			<div class="row">
+				<label class="cell" for="numInput">Num:</label>
+				<input class="cell" id="numInput" data-dojo-type="dijit.form.NumberTextBox"
+									data-dojo-props="ref: model.Num"/>
+				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Num">
+					(num is: ${this.value})
+				</span>
+			</div>
+			<h2>Bind Tests</h2>
+			<div class="row">
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 0 to test for Relevant false for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 1 to test for Valid false for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 2 to test for ReadOnly true for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 3 to test for ReadOnly true and Valid false for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 4 to test for Required true for Email.</label>
+			</div>			
+			
+			<div class="row">
+				<label class="cell" for="lastnameInput">Last:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Last"/>
+				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Last">
+					(last name is: ${this.value})
+				</span>
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.ValidationTextBox"
+									data-dojo-props="ref: model.Email"/>
+				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
+					(email is: ${this.value})
+				</span>
+			</div>
+		   <div class="row">
+				<label class="cell" for="emailInput"></label>
+				<span id="emailOut" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
+					Relevant is:  ${dijit.byId("emailInput").ref.relevant}, Valid is: ${this.ref.valid}, ReadOnly is: ${this.ref.readOnly}, Required is: ${this.ref.required})
+				</span>
+		   </div>
+			
+			<br/>Model:
+			<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){doReset()}">Reset</button>
+		  </div>
+		</div></div>
+		<script type="text/javascript">
+			function doReset() {
+				model.reset();
+			}
+		</script>
+		
+	</body>
+
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_mvc_date_test.html b/dojox/mvc/tests/1.7/doh/doh_mvc_date_test.html
new file mode 100644
index 0000000..fe30456
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_mvc_date_test.html
@@ -0,0 +1,697 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH MVC Date Binding Test</title>
+		<style type="text/css">
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../../../../dijit/themes/claro/claro.css";
+		</style>
+<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:0" src="../../../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+ 		var model;
+ 
+		require([
+			'dijit/form/DateTextBox',
+			'dijit/CalendarLite',
+			'dojox/mvc/StatefulModel',
+			'dijit/form/Button',
+			'dojox/mvc/Output',
+			'dijit/form/TextBox',
+			'dojo/date/stamp',
+			'dojox/mvc',
+			'dojo/on',
+			'dojo/domReady!'
+		], function (DateTextBox, Calendar, StatefulModel, Button, Output, TextBox, dateStamp) {
+
+			// *** Test1 setup begin: ***
+			var test1_init = dateStamp.fromISOString("1987-08-01"); // 8/1/1987
+			test1_model = new StatefulModel({
+				data: {
+					date: test1_init
+				}
+			});
+			var test1_cal = new Calendar({
+				ref: test1_model.date // bind to model.date
+			}, document.getElementById('test1_cal'));
+			test1_cal.startup();
+
+			var test1_cal2 = new Calendar({
+				ref: test1_model.date // bind to model.date
+			}, document.getElementById('test1_cal2'));
+			test1_cal2.startup();
+
+			var test1_txt2 = new TextBox({
+				ref: test1_model.date
+			}, document.getElementById('test1_txt2'));
+			dojo.style(test1_txt2.domNode, "width", "368px");
+			test1_txt2.startup();
+
+			var test1_out2 = new Output({
+				ref: test1_model.date // bind to model.date
+			}, document.getElementById('test1_output2'));
+			test1_out2.startup();
+
+			var test1_setday2 = new Button({
+				label: 'Set Calendar to dateStamp.fromISOString("1989-09-07") (Sep 7 1989)', 
+				onClick: function() {
+							//console.log("test1_setday2 called");
+							//var day2 = new Date(1989,9,7);  // 9/7/1989
+							//var day2 = new Date("1989-09-07");  // 9/7/1989
+							var day2 = dateStamp.fromISOString("1989-09-07"); // 9/7/1989
+							test1_cal2.set("value", day2);
+						} 
+			}, document.getElementById('test1_setdate1'));
+			test1_setday2.startup();
+
+			var test1_settext2 = new Button({
+				label: 'Set TextBox to dateStamp.fromISOString("1991-05-05") (May 5, 1991)', 
+				onClick: function() {
+							//test1_txt2.set("value", new Date("1993-05-05")); // ISO date format  
+							test1_txt2.set("value", dateStamp.fromISOString("1991-05-05")); // 5/5/1993
+							//test1_cal2.set("value", "1991-05-05"); 
+							//test1_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
+						} 
+			}, document.getElementById('test1_setdate2'));
+			test1_settext2.startup();
+
+			var test1_settext3 = new Button({
+				label: 'Set TextBox to ISO String("2011-11-06") (Nov 6, 2011) fails on IE', 
+				onClick: function() {
+							//test1_txt2.set("value", new Date("2011-11-07")); // ISO date format  
+							test1_txt2.set("value", "2011-11-07"); // 11/6/2011
+							//test1_cal2.set("value", "2011-11-07"); 
+							//test1_txt2.set("value", "Sun Nov 06 2011 01:00:00 GMT-0500 (Eastern Standard Time)");  
+						} 
+			}, document.getElementById('test1_setdate3'));
+			test1_settext3.startup();
+
+			var test1_reset2 = new Button({
+				label: "Reset Calendar back to (Aug 1 1987)",
+				onClick: function() {
+							test1_model.date.reset();
+						} 
+			}, document.getElementById('test1_reset2'));
+			test1_reset2.startup();
+			// *** Test1 setup end: ***
+
+			// *** Test2 setup begin: ***
+			var test2_init = dateStamp.fromISOString("2011-11-06"); // Nov 6, 2011
+			//var test2_init = dateStamp.fromISOString("1987-08-01"); // 8/1/1987
+			test2_model = new StatefulModel({
+				data: {
+					date: test2_init
+				}
+			});
+			var test2_cal = new DateTextBox({
+				ref: test2_model.date // bind to model.date
+			}, document.getElementById('test2_cal'));
+			test2_cal.startup();
+
+			var test2_cal2 = new DateTextBox({
+				ref: test2_model.date // bind to model.date
+			}, document.getElementById('test2_cal2'));
+			test2_cal2.startup();
+
+			var test2_txt2 = new TextBox({
+				ref: test2_model.date
+			}, document.getElementById('test2_txt2'));
+			dojo.style(test2_txt2.domNode, "width", "368px");
+			test2_txt2.startup();
+
+			var test2_out2 = new Output({
+				ref: test2_model.date // bind to model.date
+			}, document.getElementById('test2_output2'));
+			test2_out2.startup();
+
+			var test2_setday2 = new Button({
+				label: 'Set DateTextBox to new Date(1993,9,28) (Oct 28, 1993)', 
+				onClick: function() {
+							var day2 = new Date(1993,9,28);  // 10/28/1993
+							//var day2 = new Date("1993-10-28");  // 10/28/1993
+							//var day2 = dateStamp.fromISOString("1993-09-28"); // 10/28/1997
+							//test2_cal2.set("value", day2);
+							test2_txt2.set("value", day2);
+						} 
+			}, document.getElementById('test2_setdate1'));
+			test2_setday2.startup();
+
+			var test2_settext2 = new Button({
+				label: 'Set DateTextBox to dateStamp.fromISOString("1997-10-14") (Oct 14 1997)', 
+				onClick: function() {
+							//test2_txt2.set("value", new Date("1997-10-14")); // ISO date format  
+							test2_txt2.set("value", dateStamp.fromISOString("1997-10-14")); // Oct 14 1997
+							//test2_cal2.set("value", "1997-10-14"); 
+							//test2_txt2.set("value", "Tue Oct 14 1997 00:00:00 GMT-0400 (Eastern Daylight Time)");  
+						} 
+			}, document.getElementById('test2_setdate2'));
+			test2_settext2.startup();
+
+			var test2_reset2 = new Button({
+				label: "Reset DateTextBox back to (Nov 6 2011)",
+				onClick: function() {
+							test2_model.date.reset();
+						} 
+			}, document.getElementById('test2_reset2'));
+
+			var test2_settext3 = new Button({
+				label: 'Set TextBox to ISO String("1991-05-05") (May 5, 1991)', 
+				onClick: function() {
+							//test2_txt2.set("value", new Date("1991-05-05")); // ISO date format  
+							test2_txt2.set("value", "1991-05-05"); // 5/5/1993
+							//test2_cal2.set("value", "1991-05-05"); 
+							//test2_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
+						} 
+			}, document.getElementById('test2_setdate3'));
+			test2_settext3.startup();
+
+			test2_reset2.startup();
+			// *** Test2 setup end: ***
+
+
+			// *** Test3 setup begin: ***
+			// *** Test3 setup begin: ***
+			var test3_init = dateStamp.fromISOString("2011-08-27"); // 8/27/2011
+			test3_model = new StatefulModel({
+				data: {
+					date: test3_init,
+					date2: test3_init
+				}
+			});
+			var test3_cal = new Calendar({
+				ref: test3_model.date // bind to model.date
+			}, document.getElementById('test3_cal'));
+			test3_cal.startup();
+
+			var test3_cal2 = new DateTextBox({
+				ref: test3_model.date // bind to model.date
+			}, document.getElementById('test3_cal2'));
+			test3_cal2.startup();
+
+			var test3_txt2 = new TextBox({
+				ref: test3_model.date,
+				disabled: true
+			}, document.getElementById('test3_txt2'));
+			dojo.style(test3_txt2.domNode, "width", "368px");
+			test3_txt2.startup();
+
+			var test3_out2 = new Output({
+				ref: test3_model.date // bind to model.date
+			}, document.getElementById('test3_output2'));
+			test3_out2.startup();
+
+			var test3_setday2 = new Button({
+				label: 'Set Calendar to dateStamp.fromISOString("1997-10-14") (Oct 14 1997)', 
+				onClick: function() {
+							//console.log("test3_setday2 called");
+							//var day2 = new Date(1997,10,14);  // 10/14/1997
+							//var day2 = new Date("1997-10-14");  // 10/14/1997
+							var day2 = dateStamp.fromISOString("1997-10-14"); // 10/14/1997
+							test3_cal2.set("value", day2);
+						} 
+			}, document.getElementById('test3_setdate1'));
+			test3_setday2.startup();
+
+			var test3_settext2 = new Button({
+				label: 'Set TextBox to dateStamp.fromISOString("2011-11-06") (Nov 6, 2011)', 
+				onClick: function() {
+							//test3_txt2.set("value", new Date("2011-11-06")); // ISO date format  
+							test3_txt2.set("value", dateStamp.fromISOString("2011-11-06")); // 11/6/2011
+							//test3_cal2.set("value", "2011-11-06"); 
+							//test3_txt2.set("value", "2011-11-06"); // FAILS
+							//test3_txt2.set("value", "1991-05-06"); // 5/5/1991
+							//test3_txt2.set("value", "Sun Nov 06 2011 00:00:00 GMT-0400 (Eastern Daylight Time)");  
+						} 
+			}, document.getElementById('test3_setdate2'));
+			test3_settext2.startup();
+
+			var test3_settext3 = new Button({
+				label: 'Set TextBox to ISO String("1991-05-06") via new Date (May 5, 1991)', 
+				onClick: function() {
+							//test3_txt2.set("value", new Date("1991-05-05")); // ISO date format
+							//var d = new Date("1991-05-06T01:00:00");  
+							var d = new Date("1991-05-06");  
+							test3_txt2.set("value", d); // 5/5/1991 YYYY-MM-DDThh:mm:ss via new Date
+							//test3_txt2.set("value", "1991-05-06T01:00:00"); // 5/5/1991 YYYY-MM-DDThh:mm:ss FAILS
+							//test3_cal2.set("value", "1991-05-05"); 
+							//test3_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
+						} 
+			}, document.getElementById('test3_setdate3'));
+			test3_settext3.startup();
+			if(dojo.isIE){ // new Date("1991-05-06") will not work on IE
+				test3_settext3.set('disabled',true);
+			}
+
+			var test3_reset2 = new Button({
+				label: "Reset Calendar back to (Aug 27 2011)",
+				onClick: function() {
+							//console.log("test3_callreset2 called");
+							test3_model.date.reset();
+						} 
+			}, document.getElementById('test3_reset2'));
+			test3_reset2.startup();
+			// *** Test3 setup end: ***
+
+
+
+			// *** Test4 setup begin: RegExp Test***
+			// *** Test4 setup begin: RegExp Test***
+			var regx = new RegExp("abc","i");			
+			test4_model = new StatefulModel({
+				data: {
+					//regex: /abc/i // should be regex: /abc/
+					regex: regx // should be regex: /abc/
+				}
+			});
+
+			/*
+			console.log('test4_model.regex', test4_model.regex.get('value'));
+			var str = "ABCDEFGHIJKLMNOP abcdefghi";
+			var patt1 = test4_model.regex.get('value');
+			console.log("str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
+			console.log('str.match(patt1)',str.match(patt1));
+			test4_model.regex.set('value',/def/);
+			console.log("set to def str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
+			test4_model.regex.reset();
+			console.log("after reset str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
+			*/
+			// *** Test4 setup end: ***
+
+			// *** Test5 setup begin: Falsy Test***
+			var d = {
+				u: undefined,
+				z: 0,
+				n: null,
+				f: false,
+				s: ""
+			};
+			test5_model = new StatefulModel({data: d});
+			//console.log(test5_model.toPlainObject());
+			// *** Test5 setup end: ***
+
+	
+
+				require([
+					'doh/runner', 'dijit/dijit'
+				], function(){
+				require([
+					'dojo/domReady!'
+					], function(){
+						doh.register("parse", function() {
+							dojo.parser.parse();
+						});
+						// should be able to verify all of the inputs 
+						doh.register("check initial values and bindings - test1", [{
+							name : "initial-test1",
+							runTest : function() {
+								doh.is("1987", dijit.byId("test1_cal").get('value').getFullYear(),"test1_cal getFullYear should be 1987");
+								doh.is("7", dijit.byId("test1_cal").get('value').getMonth(),"test1_cal getMonth should be 7");
+								doh.is("1", dijit.byId("test1_cal").get('value').getDate(),"test1_cal getDate should be 1");
+								doh.is("1987", dijit.byId("test1_cal2").get('value').getFullYear(),"test1_cal2 getFullYear should be 1987");
+								doh.is("7", dijit.byId("test1_cal2").get('value').getMonth(),"test1_cal2 getMonth should be 7");
+								doh.is("1", dijit.byId("test1_cal2").get('value').getDate(),"test1_cal2 getDate should be 1");
+								var date = new Date(1987, 7, 1, 0, 0, 0, 0);
+								doh.t(date.getTime() == dijit.byId("test1_txt2").get("binding").get("value").getTime(), "test1_txt2 should be 8/1/87 0:00 AM");
+								doh.t(date.getTime() == dijit.byId("test1_output2").get("binding").get("value").getTime(), "test1_output2 should be 8/1/87 0:00 AM");
+							}
+						}]);
+
+						doh.register("check initial values and bindings - test2", [{
+							name : "initial-test2",
+							runTest : function() {
+								doh.is("2011", dijit.byId("test2_cal").get('value').getFullYear(),"test2_cal getFullYear should be 1987");
+								doh.is("10", dijit.byId("test2_cal").get('value').getMonth(),"test2_cal getMonth should be 10");
+								doh.is("6", dijit.byId("test2_cal").get('value').getDate(),"test2_cal getDate should be 6");
+								doh.is("2011", dijit.byId("test2_cal2").get('value').getFullYear(),"test2_cal2 getFullYear should be 1987");
+								doh.is("10", dijit.byId("test2_cal2").get('value').getMonth(),"test2_cal2 getMonth should be 10");
+								doh.is("6", dijit.byId("test2_cal2").get('value').getDate(),"test2_cal2 getDate should be 6");
+								var date = new Date(2011, 10, 6, 0, 0, 0, 0);
+								doh.t(date.getTime() == dijit.byId("test2_txt2").get("binding").get("value").getTime(), "test2_txt2 should be 11/6/11 0:00 AM");
+								doh.t(date.getTime() == dijit.byId("test2_output2").get("binding").get("value").getTime(), "test2_output2 should be 11/6/11 0:00 AM");
+							}
+						}]);
+
+						doh.register("check initial values and bindings - test3", [{
+							name : "initial-test3",
+							runTest : function() {
+								doh.is("2011", dijit.byId("test3_cal").get('value').getFullYear(),"test3_cal getFullYear should be 1987");
+								doh.is("7", dijit.byId("test3_cal").get('value').getMonth(),"test3_cal getMonth should be 7");
+								doh.is("27", dijit.byId("test3_cal").get('value').getDate(),"test3_cal getDate should be 27");
+								doh.is("2011", dijit.byId("test3_cal2").get('value').getFullYear(),"test3_cal2 getFullYear should be 1987");
+								doh.is("7", dijit.byId("test3_cal2").get('value').getMonth(),"test3_cal2 getMonth should be 7");
+								doh.is("27", dijit.byId("test3_cal2").get('value').getDate(),"test3_cal2 getDate should be 27");
+								var date = new Date(2011, 7, 27, 0, 0, 0, 0);
+								doh.t(date.getTime() == dijit.byId("test3_txt2").get("binding").get("value").getTime(), "test3_txt2 should be 8/27/11 0:00 AM");
+								doh.t(date.getTime() == dijit.byId("test3_output2").get("binding").get("value").getTime(), "test3_output2 should be 8/27/11 0:00 AM");
+							}
+						}]);
+
+						doh.register("update first cal - test1", [{
+							name : "Update-First-Cal-test1",
+							runTest : function() {
+								var day2 = dateStamp.fromISOString("1989-09-07"); // 9/7/1989
+								dijit.byId(test1_cal).set("value", day2);
+								doh.is("1989", dijit.byId("test1_cal").get('value').getFullYear(),"test1_cal getFullYear should be 1989");
+								doh.is("8", dijit.byId("test1_cal").get('value').getMonth(),"test1_cal getMonth should be 8");
+								doh.is("7", dijit.byId("test1_cal").get('value').getDate(),"test1_cal getDate should be 7");
+								doh.is("1989", dijit.byId("test1_cal2").get('value').getFullYear(),"test1_cal2 getFullYear should be 1989");
+								doh.is("8", dijit.byId("test1_cal2").get('value').getMonth(),"test1_cal2 getMonth should be 8");
+								doh.is("7", dijit.byId("test1_cal2").get('value').getDate(),"test1_cal2 getDate should be 7");
+								var date = new Date(1989, 8, 7, 1, 0, 0, 0); // Setting a date to dijit.CalendarLite-based widget will cause the value to become 1am (See dijit.CalenarLite._patchDate())
+								doh.t(date.getTime() == dijit.byId("test1_txt2").get("binding").get("value").getTime(), "test1_txt2 should be 9/7/89 1:00 AM");
+								doh.t(date.getTime() == dijit.byId("test1_output2").get("binding").get("value").getTime(), "test1_output2 should be 9/7/89 1:00 AM");
+							}
+						}]);
+
+						doh.register("update first cal - test2", [{
+							name : "Update-First-Cal-test2",
+							runTest : function() {
+								var day2 = dateStamp.fromISOString("1989-09-07"); // 9/7/1989
+								dijit.byId(test2_cal).set("value", day2);
+								doh.is("1989", dijit.byId("test2_cal").get('value').getFullYear(),"test2_cal getFullYear should be 1989");
+								doh.is("8", dijit.byId("test2_cal").get('value').getMonth(),"test2_cal getMonth should be 8");
+								doh.is("7", dijit.byId("test2_cal").get('value').getDate(),"test2_cal getDate should be 7");
+								doh.is("1989", dijit.byId("test2_cal2").get('value').getFullYear(),"test2_cal2 getFullYear should be 1989");
+								doh.is("8", dijit.byId("test2_cal2").get('value').getMonth(),"test2_cal2 getMonth should be 8");
+								doh.is("7", dijit.byId("test2_cal2").get('value').getDate(),"test2_cal2 getDate should be 7");
+								var date = new Date(1989, 8, 7, 0, 0, 0, 0);
+								doh.t(date.getTime() == dijit.byId("test2_txt2").get("binding").get("value").getTime(), "test2_txt2 should be 9/7/89 0:00 AM");
+								doh.t(date.getTime() == dijit.byId("test2_output2").get("binding").get("value").getTime(), "test2_output2 should be 9/7/89 0:00 AM");
+							}
+						}]);
+
+						doh.register("update first cal - test3", [{
+							name : "Update-First-Cal-test3",
+							runTest : function() {
+								var day2 = dateStamp.fromISOString("1989-09-07"); // 9/7/1989
+								dijit.byId(test3_cal).set("value", day2);
+								doh.is("1989", dijit.byId("test3_cal").get('value').getFullYear(),"test3_cal getFullYear should be 1989");
+								doh.is("8", dijit.byId("test3_cal").get('value').getMonth(),"test3_cal getMonth should be 8");
+								doh.is("7", dijit.byId("test3_cal").get('value').getDate(),"test3_cal getDate should be 7");
+								doh.is("1989", dijit.byId("test3_cal2").get('value').getFullYear(),"test3_cal2 getFullYear should be 1989");
+								doh.is("8", dijit.byId("test3_cal2").get('value').getMonth(),"test3_cal2 getMonth should be 8");
+								doh.is("7", dijit.byId("test3_cal2").get('value').getDate(),"test3_cal2 getDate should be 7");
+								var date = new Date(1989, 8, 7, 1, 0, 0, 0); // Setting a date to dijit.CalendarLite-based widget will cause the value to become 1am (See dijit.CalenarLite._patchDate())
+								doh.t(date.getTime() == dijit.byId("test3_txt2").get("binding").get("value").getTime(), "test3_txt2 should be 9/7/89 1:00 AM");
+								doh.t(date.getTime() == dijit.byId("test3_output2").get("binding").get("value").getTime(), "test3_output2 should be 9/7/89 1:00 AM");
+							}
+						}]);
+
+						doh.register("update textbox - test1", [{
+							name : "Update-TextBox-test1",
+							runTest : function() {
+								dijit.byId(test1_txt2).set("value", dateStamp.fromISOString("1991-05-05"));
+								doh.is("1991", dijit.byId("test1_cal").get('value').getFullYear(),"test1_cal getFullYear should be 1991");
+								doh.is("4", dijit.byId("test1_cal").get('value').getMonth(),"test1_cal getMonth should be 4");
+								doh.is("5", dijit.byId("test1_cal").get('value').getDate(),"test1_cal getDate should be 4");
+								doh.is("1991", dijit.byId("test1_cal2").get('value').getFullYear(),"test1_cal2 getFullYear should be 1991");
+								doh.is("4", dijit.byId("test1_cal2").get('value').getMonth(),"test1_cal2 getMonth should be 4");
+								doh.is("5", dijit.byId("test1_cal2").get('value').getDate(),"test1_cal2 getDate should be 5");
+								var date = new Date(1991, 4, 5, 0, 0, 0, 0);
+								doh.t(date.getTime() == dijit.byId("test1_txt2").get("binding").get("value").getTime(), "test1_txt2 should be 5/5/91 0:00 AM");
+								doh.t(date.getTime() == dijit.byId("test1_output2").get("binding").get("value").getTime(), "test1_output2 should be 5/5/91 0:00 AM");
+							}
+						}]);
+
+						doh.register("update textbox - test2", [{
+							name : "Update-TextBox-test2",
+							runTest : function() {
+								dijit.byId(test2_txt2).set("value", dateStamp.fromISOString("1991-05-05"));
+								doh.is("1991", dijit.byId("test2_cal").get('value').getFullYear(),"test2_cal getFullYear should be 1991");
+								doh.is("4", dijit.byId("test2_cal").get('value').getMonth(),"test2_cal getMonth should be 4");
+								doh.is("5", dijit.byId("test2_cal").get('value').getDate(),"test2_cal getDate should be 4");
+								doh.is("1991", dijit.byId("test2_cal2").get('value').getFullYear(),"test2_cal2 getFullYear should be 1991");
+								doh.is("4", dijit.byId("test2_cal2").get('value').getMonth(),"test2_cal2 getMonth should be 4");
+								doh.is("5", dijit.byId("test2_cal2").get('value').getDate(),"test2_cal2 getDate should be 5");
+								var date = new Date(1991, 4, 5, 0, 0, 0, 0);
+								doh.t(date.getTime() == dijit.byId("test2_txt2").get("binding").get("value").getTime(), "test2_txt2 should be 5/5/91 0:00 AM");
+								doh.t(date.getTime() == dijit.byId("test2_output2").get("binding").get("value").getTime(), "test2_output2 should be 5/5/91 0:00 AM");
+							}
+						}]);
+
+						doh.register("update textbox - test3", [{
+							name : "Update-TextBox-test3",
+							runTest : function() {
+								dijit.byId(test3_txt2).set("value", dateStamp.fromISOString("1991-05-05"));
+								doh.is("1991", dijit.byId("test3_cal").get('value').getFullYear(),"test3_cal getFullYear should be 1991");
+								doh.is("4", dijit.byId("test3_cal").get('value').getMonth(),"test3_cal getMonth should be 4");
+								doh.is("5", dijit.byId("test3_cal").get('value').getDate(),"test3_cal getDate should be 4");
+								doh.is("1991", dijit.byId("test3_cal2").get('value').getFullYear(),"test3_cal2 getFullYear should be 1991");
+								doh.is("4", dijit.byId("test3_cal2").get('value').getMonth(),"test3_cal2 getMonth should be 4");
+								doh.is("5", dijit.byId("test3_cal2").get('value').getDate(),"test3_cal2 getDate should be 5");
+								var date = new Date(1991, 4, 5, 0, 0, 0, 0);
+								doh.t(date.getTime() == dijit.byId("test3_txt2").get("binding").get("value").getTime(), "test3_txt2 should be 5/5/91 0:00 AM");
+								doh.t(date.getTime() == dijit.byId("test3_output2").get("binding").get("value").getTime(), "test3_output2 should be 5/5/91 0:00 AM");
+							}
+						}]);
+
+						doh.register("update cal with new date - test1", [{
+							name : "Update-withNewDate-test1",
+							runTest : function() {
+								var day2 = new Date(1993,9,28);  // 10/28/1993							
+								dijit.byId(test1_cal).set("value", day2);
+								doh.is("1993", dijit.byId("test1_cal").get('value').getFullYear(),"test1_cal getFullYear should be 1993");
+								doh.is("9", dijit.byId("test1_cal").get('value').getMonth(),"test1_cal getMonth should be 9");
+								doh.is("28", dijit.byId("test1_cal").get('value').getDate(),"test1_cal getDate should be 28");
+								doh.is("1993", dijit.byId("test1_cal2").get('value').getFullYear(),"test1_cal2 getFullYear should be 1993");
+								doh.is("9", dijit.byId("test1_cal2").get('value').getMonth(),"test1_cal2 getMonth should be 9");
+								doh.is("28", dijit.byId("test1_cal2").get('value').getDate(),"test1_cal2 getDate should be 28");
+								var date = new Date(1993, 9, 28, 1, 0, 0, 0); // Setting a date to dijit.CalendarLite-based widget will cause the value to become 1am (See dijit.CalenarLite._patchDate())
+								doh.t(date.getTime() == dijit.byId("test1_txt2").get("binding").get("value").getTime(), "test1_txt2 should be 10/28/93 1:00 AM");
+								doh.t(date.getTime() == dijit.byId("test1_output2").get("binding").get("value").getTime(), "test1_output2 should be 10/28/93 1:00 AM");
+							}
+						}]);
+
+						doh.register("update cal with new date - test2", [{
+							name : "Update-withNewDate-test2",
+							runTest : function() {
+								var day2 = new Date(1993,9,28);  // 10/28/1993							
+								dijit.byId(test2_cal).set("value", day2);
+								doh.is("1993", dijit.byId("test2_cal").get('value').getFullYear(),"test2_cal getFullYear should be 1993");
+								doh.is("9", dijit.byId("test2_cal").get('value').getMonth(),"test2_cal getMonth should be 9");
+								doh.is("28", dijit.byId("test2_cal").get('value').getDate(),"test2_cal getDate should be 28");
+								doh.is("1993", dijit.byId("test2_cal2").get('value').getFullYear(),"test2_cal2 getFullYear should be 1993");
+								doh.is("9", dijit.byId("test2_cal2").get('value').getMonth(),"test2_cal2 getMonth should be 9");
+								doh.is("28", dijit.byId("test2_cal2").get('value').getDate(),"test2_cal2 getDate should be 28");
+								var date = new Date(1993, 9, 28, 0, 0, 0, 0);
+								doh.t(date.getTime() == dijit.byId("test2_txt2").get("binding").get("value").getTime(), "test2_txt2 should be 10/28/93 0:00 AM");
+								doh.t(date.getTime() == dijit.byId("test2_output2").get("binding").get("value").getTime(), "test2_output2 should be 10/28/93 0:00 AM");
+							}
+						}]);
+
+						doh.register("update cal with new date - test3", [{
+							name : "Update-withNewDate-test3",
+							runTest : function() {
+								var day2 = new Date(1993,9,28);  // 10/28/1993							
+								dijit.byId(test3_cal).set("value", day2);
+								doh.is("1993", dijit.byId("test3_cal").get('value').getFullYear(),"test3_cal getFullYear should be 1993");
+								doh.is("9", dijit.byId("test3_cal").get('value').getMonth(),"test3_cal getMonth should be 9");
+								doh.is("28", dijit.byId("test3_cal").get('value').getDate(),"test3_cal getDate should be 28");
+								doh.is("1993", dijit.byId("test3_cal2").get('value').getFullYear(),"test3_cal2 getFullYear should be 1993");
+								doh.is("9", dijit.byId("test3_cal2").get('value').getMonth(),"test3_cal2 getMonth should be 9");
+								doh.is("28", dijit.byId("test3_cal2").get('value').getDate(),"test3_cal2 getDate should be 28");
+								var date = new Date(1993, 9, 28, 1, 0, 0, 0); // Setting a date to dijit.CalendarLite-based widget will cause the value to become 1am (See dijit.CalenarLite._patchDate())
+								doh.t(date.getTime() == dijit.byId("test3_txt2").get("binding").get("value").getTime(), "test3_txt2 should be 10/28/93 1:00 AM");
+								doh.t(date.getTime() == dijit.byId("test3_output2").get("binding").get("value").getTime(), "test3_output2 should be 10/28/93 1:00 AM");
+							}
+						}]);
+
+						doh.register("check model reset - test1", [{
+							name : "reset-test1",
+							runTest : function() {
+								test1_model.date.reset();
+								doh.is("1987", dijit.byId("test1_cal").get('value').getFullYear(),"test1_cal getFullYear should be 1987");
+								doh.is("7", dijit.byId("test1_cal").get('value').getMonth(),"test1_cal getMonth should be 7");
+								doh.is("1", dijit.byId("test1_cal").get('value').getDate(),"test1_cal getDate should be 1");
+								doh.is("1987", dijit.byId("test1_cal2").get('value').getFullYear(),"test1_cal2 getFullYear should be 1987");
+								doh.is("7", dijit.byId("test1_cal2").get('value').getMonth(),"test1_cal2 getMonth should be 7");
+								doh.is("1", dijit.byId("test1_cal2").get('value').getDate(),"test1_cal2 getDate should be 1");
+								var date = new Date(1987, 7, 1, 0, 0, 0, 0);
+								doh.t(date.getTime() == dijit.byId("test1_txt2").get("binding").get("value").getTime(), "test1_txt2 should be 8/1/87 0:00 AM");
+								doh.t(date.getTime() == dijit.byId("test1_output2").get("binding").get("value").getTime(), "test1_output2 should be 8/1/87 0:00 AM");
+							}
+						}]);
+
+						doh.register("check model reset - test2", [{
+							name : "reset-test2",
+							runTest : function() {
+								test2_model.date.reset();
+								doh.is("2011", dijit.byId("test2_cal").get('value').getFullYear(),"test2_cal getFullYear should be 1987");
+								doh.is("10", dijit.byId("test2_cal").get('value').getMonth(),"test2_cal getMonth should be 10");
+								doh.is("6", dijit.byId("test2_cal").get('value').getDate(),"test2_cal getDate should be 6");
+								doh.is("2011", dijit.byId("test2_cal2").get('value').getFullYear(),"test2_cal2 getFullYear should be 1987");
+								doh.is("10", dijit.byId("test2_cal2").get('value').getMonth(),"test2_cal2 getMonth should be 10");
+								doh.is("6", dijit.byId("test2_cal2").get('value').getDate(),"test2_cal2 getDate should be 6");
+								var date = new Date(2011, 10, 6, 0, 0, 0, 0);
+								doh.t(date.getTime() == dijit.byId("test2_txt2").get("binding").get("value").getTime(), "test2_txt2 should be 11/6/11 0:00 AM");
+								doh.t(date.getTime() == dijit.byId("test2_output2").get("binding").get("value").getTime(), "test2_output2 should be 11/6/11 0:00 AM");
+							}
+						}]);
+
+						doh.register("check model reset - test3", [{
+							name : "reset-test3",
+							runTest : function() {
+								test3_model.date.reset();
+								doh.is("2011", dijit.byId("test3_cal").get('value').getFullYear(),"test3_cal getFullYear should be 1987");
+								doh.is("7", dijit.byId("test3_cal").get('value').getMonth(),"test3_cal getMonth should be 7");
+								doh.is("27", dijit.byId("test3_cal").get('value').getDate(),"test3_cal getDate should be 27");
+								doh.is("2011", dijit.byId("test3_cal2").get('value').getFullYear(),"test3_cal2 getFullYear should be 1987");
+								doh.is("7", dijit.byId("test3_cal2").get('value').getMonth(),"test3_cal2 getMonth should be 7");
+								doh.is("27", dijit.byId("test3_cal2").get('value').getDate(),"test3_cal2 getDate should be 27");
+								var date = new Date(2011, 7, 27, 0, 0, 0, 0);
+								doh.t(date.getTime() == dijit.byId("test3_txt2").get("binding").get("value").getTime(), "test3_txt2 should be 8/27/11 0:00 AM");
+								doh.t(date.getTime() == dijit.byId("test3_output2").get("binding").get("value").getTime(), "test3_output2 should be 8/27/11 0:00 AM");
+							}
+						}]);
+
+						doh.register("test regexp in model", [{
+							name : "regexp-test4",
+							runTest : function() {
+								doh.is("/abc/i", test4_model.regex.get('value'),"test4_model.regex.get(value) should be /abc/i");
+								var str = "ABCDEFGHIJKLMNOP abcdefghi";
+								var patt1 = test4_model.regex.get('value');
+								doh.is("ABC", str.match(test4_model.regex.get('value')),"str.match(test4_model.regex.get('value')) should be ABC");
+								doh.is("ABC", str.match(patt1),"str.match(patt1) should be ABC");
+								test4_model.regex.set('value',/def/);
+								doh.is("def", str.match(test4_model.regex.get('value')),"str.match(test4_model.regex.get('value')) after set /def/ should be def");
+								test4_model.regex.reset();
+								doh.is("ABC", str.match(test4_model.regex.get('value')),"str.match(test4_model.regex.get('value')) after reset should be ABC");
+							}
+						}]);
+
+
+						doh.register("test falsy in model", [{
+							name : "falsy-test5",
+							runTest : function() {
+								doh.t(null === test5_model.n.get('value'),"test5_model.n.get(value) should be null");
+								doh.t(0 === test5_model.z.get('value'),"test5_model.z.get(value) should be 0");
+								doh.t(undefined === test5_model.u.get('value'),"test5_model.u.get(value) should be undefined");
+								doh.t(false === test5_model.f.get('value'),"test5_model.f.get(value) should be false");
+								doh.t("" === test5_model.s.get('value'),"test5_model.s.get(value) should be an empty string");
+							}
+						}]);
+
+						doh.run();
+
+					});
+				});	
+		}); 
+		</script>
+</head>
+<body class="claro">
+			<h2>Test 1: Two Calendars bound to each other, a TextBox and an mvc Output field.</h2>
+				<div  style="border-style: solid; border-width: 2px; width: 827px;">
+					<table>
+						<tbody>
+							<tr>
+								<td><div id="test1_cal"></div></td>
+								<td><div id="test1_cal2"></div></td>
+								<td>
+					<table><tbody>
+								<tr><td><label for="test1_txt2">TextBox bound to date:</label></td></tr>
+								<tr><td><div id="test1_txt2"></div></td></tr>
+								<tr><td><label for="test1_txt2">MVC Output bound to date:</label></td></tr>
+								<tr><td><div id="test1_output2"></div></td></tr>
+					</tbody></table>
+					<table><tbody><tr>
+								<td><div id="test1_setdate1"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test1_setdate2"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test1_setdate3"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test1_reset2"></div></td>
+					</tr></tbody></table>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+
+			<h2>Test 2: Two DateTextBoxes bound to each other, a TextBox and an mvc Output field.</h2>
+				<div  style="border-style: solid; border-width: 2px; width: 827px;">
+					<table>
+						<tbody>
+							<tr>
+								<td style="vertical-align: top;"><div id="test2_cal"></div></td>
+								<td style="vertical-align: top;"><div id="test2_cal2"></div></td>
+								<td>
+					<table><tbody>
+								<tr><td><label for="test2_txt2">TextBox bound to date:</label></td></tr>
+								<tr><td><div id="test2_txt2"></div></td></tr>
+								<tr><td><label for="test2_txt2">MVC Output bound to date:</label></td></tr>
+								<tr><td><div id="test2_output2"></div></td></tr>
+					</tbody></table>
+					<table><tbody><tr>
+								<td><div id="test2_setdate1"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test2_setdate2"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test2_setdate3"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test2_reset2"></div></td>
+					</tr></tbody></table>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+
+
+			<h2>Test 3: One Calendar bound to a DateTextbox, a TextBox and an mvc Output field.</h2>
+				<div  style="border-style: solid; border-width: 2px; width: 827px;">
+					<table>
+						<tbody>
+							<tr>
+								<td style="vertical-align: top;"><div id="test3_cal"></div></td>
+								<td style="vertical-align: top;"><div id="test3_cal2"></div></td>
+								<td>
+					<table><tbody>
+								<tr><td><label for="test3_txt2">TextBox bound to date: (disabled to avoid error)</label></td></tr>
+								<tr><td><div id="test3_txt2"></div></td></tr>
+								<tr><td><label for="test3_txt2">MVC Output bound to date:</label></td></tr>
+								<tr><td><div id="test3_output2"></div></td></tr>
+					</tbody></table>
+					<table><tbody><tr>
+								<td><div id="test3_setdate1"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test3_setdate2"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test3_setdate3"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test3_reset2"></div></td>
+					</tr></tbody></table>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+	<!--  	  
+			<h2>I see these problems Binding a TextBox to DateTextBox and Calendar:</h2>
+				<div  style="border-style: solid; border-width: 2px; width: 827px;">
+				<span>There is also a problem when trying to set a date string in this format:</span><br>
+				<span>"Wed May 05 2010 01:00:00 GMT-0400 (Eastern Daylight Time)" into a  into a TextBox bound to a dijit.form.DateTextbox, but that works in a Calendar.</span><br>
+				<span>It is ending up with the DateTextBox set to null.  : </span><br>
+				<span></span><br>
+				<span>There is also a problem when trying to set a date ISO format date string like "1991-05-05":</span><br>
+				<span>"into a  into a TextBox bound to a Calendar, but that works for a dijit.form.DateTextbox.</span><br>
+				<span>It is loops for a while and gets range errors in the console.  : </span><br>
+				<span></span><br>
+				<span>Another thing I have found was that on a calendar I would get a different value from dijit.byId("cal").get('value') and dijit.byId("cal").value.</span><br>
+				<span>dijit.byId("cal").value:        Wed May 05 2010 <b>01:00:00</b> GMT-0400 (Eastern Daylight Time)</span><br>
+				<span>dijit.byId("cal").get('value'): Wed May 05 2010 <b>00:00:00</b> GMT-0400 (Eastern Daylight Time)</span><br>
+				<span>dijit.byId("cal").get('value') is getting 00:00:00 when it seems like it should be 01:00:00</span><br>
+				</div>
+	-->
+</body>
+
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_mvc_form-kitchensink.html b/dojox/mvc/tests/1.7/doh/doh_mvc_form-kitchensink.html
new file mode 100644
index 0000000..afa76e4
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_mvc_form-kitchensink.html
@@ -0,0 +1,1408 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>MVC DOH Test</title>
+
+	<style>
+		@import "../../../../../dojo/resources/dojo.css";
+		@import "../../../../../dijit/tests/css/dijitTests.css";
+		@import "../css/app-format.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script src="../../../../../dojo/dojo.js" type="text/javascript"
+		djConfig="isDebug: true">
+	</script>
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<script type="text/javascript" >
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Output");
+			dojo.require("dijit.form.TextBox");
+			dojo.require("dijit.form.Button");
+			dojo.require("dijit.form.Select");
+			dojo.require("dijit.form.FilteringSelect");
+			dojo.require("dijit.form.ComboBox");
+			dojo.require("dijit.form.DateTextBox");
+			dojo.require("dijit.form.HorizontalSlider");
+			dojo.require("dijit.form.NumberSpinner");
+			dojo.require("dijit.form.NumberTextBox");
+			dojo.require("dijit.form.SimpleTextarea");		
+			dojo.require("dijit.form.Textarea");
+			dojo.require("dojo.data.ItemFileReadStore");
+			dojo.require("dijit.Calendar");
+			dojo.require("dijit.ColorPalette");
+			dojo.require("dojo.date.locale");
+			dojo.require("dojo.parser");
+			// The dojox.mvc.StatefulModel class creates a data model instance
+			// where each leaf within the data model is decorated with dojo.Stateful
+			// properties that widgets can bind to and watch for their changes.
+
+			var alreadyset = false;	
+			var data = [
+				{id: '1',name:"one"},
+				{id: '2',name:"two"},
+				{id: '3',name:"three"},
+				{id: '4',name:"four"},
+				{id: '5',name:"five"},
+				{id: '6',name:"six"},
+				{id: '7',name:"seven"},
+				{id: '8',name:"eight"},
+				{id: '9',name:"nine"},
+				{id: '10',name:"ten"},
+				{id: '11',name:"eleven"},
+				{id: '12',name:"twelve"},
+				{id: '13',name:"thirteen"}
+			  ];
+			var store = new dojo.data.ItemFileReadStore({
+				data: {
+					identifier: 'id',
+					label: 'name',
+					items: data
+				}
+			});
+
+			var data2 = {
+				identifier: "value",
+				label: "label",
+				items: [
+					{value: "1", label: "one"},
+					{value: "2", label: "two"},
+					{value: "3", label: "three"},
+					{value: "4", label: "four"},
+					{value: "5", label: "five"},
+					{value: "6", label: "six"},
+					{value: "7", label: "seven"},
+					{value: "8", label: "eigth"},
+					{value: "9", label: "nine"},
+					{value: "10", label: "ten"},
+					{value: "11", label: "eleven"},
+					{value: "12", label: "twelve"},
+					{value: "13", label: "thirteen"},
+					{value: "14", label: "fourteen"}
+				]
+			};
+			var store2 = new dojo.data.ItemFileReadStore({data:dojo.clone(data2)});
+
+			// create models for selects
+			var selmodel = new dojox.mvc.newStatefulModel({data: {number: '1'}});
+			var decselmodel = new dojox.mvc.newStatefulModel({data: {number: '1'}});
+
+			// create models for filtering selects
+			var filmodel = new dojox.mvc.newStatefulModel({data: {number: '2'}});
+			var decfilmodel = new dojox.mvc.newStatefulModel({data: {number: '2'}});
+
+			// create models for ComboBoxes
+			var combomodel = new dojox.mvc.newStatefulModel({data: {number: 'three'}});
+			var deccombomodel = new dojox.mvc.newStatefulModel({data: {number: 'three'}});
+
+			// create a model for DateTextBox
+			var datemodel = new dojox.mvc.newStatefulModel({data: {number: new Date(2011, 3, 4)}});
+			var decdatemodel = new dojox.mvc.newStatefulModel({data: {number: new Date(2011, 3, 4)}});
+
+			// create a model for Slider
+			var slidermodel = new dojox.mvc.newStatefulModel({data: {number: '5'}});
+			var decslidermodel = new dojox.mvc.newStatefulModel({data: {number: '5'}});
+
+			// create a model for NumberSpinner
+			var numspinmodel = new dojox.mvc.newStatefulModel({data: {number: '6'}});
+			var decnumspinmodel = new dojox.mvc.newStatefulModel({data: {number: '6'}});
+
+			// create a model for SimpleTextArea
+			var simpTAmodel = new dojox.mvc.newStatefulModel({data: {number: '7'}});
+			var decsimpTAmodel = new dojox.mvc.newStatefulModel({data: {number: '7'}});
+
+			// create a model for TextArea
+			var textareamodel = new dojox.mvc.newStatefulModel({data: {number: '8'}});
+			var dectextareamodel = new dojox.mvc.newStatefulModel({data: {number: '8'}});
+
+			// create a model for dijit.Calendar
+			var deccalmodel = new dojox.mvc.newStatefulModel({data: {date: new Date(2011,4,4)}});
+
+			// create a model for dijit.ColorPalette
+			var deccolormodel = new dojox.mvc.newStatefulModel({data: {code: "#000000"}});
+
+			var nanmodel = new dojox.mvc.newStatefulModel({data: {num: null}});
+
+	</script>
+
+	<script type="text/javascript">
+		dojo.require('doh.runner');
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+
+		dojo.addOnLoad(function(){
+
+			doh.register("parse", function(){
+				dummyDateWid = new dijit.form.DateTextBox({constraints:{datePattern:"MM-dd-yyyy", strict:true}});
+
+				dojo.parser.parse();
+
+			// Handle the programmatic creation of widgets here:
+			
+			// create the select, textbox, output and button			
+			var sel = new dijit.form.Select({
+				store: store,
+				loadChildrenOnOpen: true,
+				ref: selmodel.number // bind to model.number
+			}, document.getElementById('sel'));
+			
+			var text = new dijit.form.TextBox({
+				//id: "seltext",
+				ref: selmodel.number
+			}, document.getElementById('seltext'));			
+			text.startup();
+			
+			var selOutput = new dojox.mvc.Output({
+				ref: selmodel.number
+			}, document.getElementById('selOutput'));
+			selOutput.startup();
+
+			var reset1 = new dijit.form.Button({
+				onClick: function(){selmodel.reset();},
+				id: "selReset",
+				label: "Reset"
+			}, document.getElementById('reset1'));
+			reset1.startup();
+
+
+			sel.watch('value', function () {
+				//console.log('sel value changed', arguments);
+			});
+
+			text.watch('value', function () {
+				//console.log('text value changed', arguments);
+			});
+			
+			sel.startup();
+			
+
+			// create the filtering select, textbox, output and button			
+			var filsel = new dijit.form.FilteringSelect({
+				store: store,
+				ref: filmodel.number // bind to model.number
+			}, document.getElementById('filsel'));
+			
+			var filtext = new dijit.form.TextBox({
+				ref: filmodel.number
+			}, document.getElementById('filtext'));
+			
+			var filoutput = new dojox.mvc.Output({
+				ref: filmodel.number
+			}, document.getElementById('filoutput'));			
+			filoutput.startup();
+
+			var filreset = new dijit.form.Button({
+				onClick: function(){filmodel.reset();},
+				id: "filReset",
+				label: "Reset"
+			}, document.getElementById('filreset'));
+			filreset.startup();
+			
+			filtext.startup();
+			filsel.startup();
+			
+			// create the comboBox, textbox, output and button			
+			var combo = new dijit.form.ComboBox({
+				store: store,
+				ref: combomodel.number // bind to model.number
+			}, document.getElementById('combosel'));
+			
+			var combotext = new dijit.form.TextBox({
+				ref: combomodel.number
+			}, document.getElementById('combotext'));
+			
+			var combooutput = new dojox.mvc.Output({
+				ref: combomodel.number
+			}, document.getElementById('combooutput'));			
+			combooutput.startup();
+
+			var comboreset = new dijit.form.Button({
+				onClick: function(){combomodel.reset();},
+				id: "comboReset",
+				label: "Reset"
+			}, document.getElementById('comboreset'));
+			comboreset.startup();
+			
+			combotext.startup();
+			combo.startup();
+			
+			var dateWid = new dijit.form.DateTextBox({
+				ref: datemodel.number // bind to model.number
+			}, document.getElementById('datesel'));
+			dateWid.constraints = dummyDateWid.constraints;
+			dateWid.dateLocaleModule = dummyDateWid.dateLocaleModule;
+			dateWid.format = dummyDateWid.format;
+			dateWid.startup();
+			
+			var datetext = new dijit.form.TextBox({				
+				disabled : true,
+				ref: datemodel.number
+			}, document.getElementById('datetext'));
+			datetext.constraints = dummyDateWid.constraints;
+			datetext.dateLocaleModule = dummyDateWid.dateLocaleModule;
+			datetext.format = dummyDateWid.format;
+			datetext.startup();
+			
+			var dateoutput = new dojox.mvc.Output({
+				ref: datemodel.number
+			}, document.getElementById('dateoutput'));			
+			dateoutput.startup();
+
+			var datereset = new dijit.form.Button({
+				onClick: function(){datemodel.reset();},
+				id: "dateReset",
+				label: "Reset"
+			}, document.getElementById('datereset'));
+			datereset.startup();
+			
+			
+			// create the dijit.form.HorizontalSlider, textbox, output and button			
+			var sliderWid = new dijit.form.HorizontalSlider({
+						style:{width:"190px"},
+						minimum:0,
+						maximum:100,
+						discreteValues:21,
+				ref: slidermodel.number // bind to model.number
+			}, document.getElementById('slidersel'));
+			
+			var slidertext = new dijit.form.TextBox({
+				ref: slidermodel.number
+			}, document.getElementById('slidertext'));
+			
+			var slideroutput = new dojox.mvc.Output({
+				ref: slidermodel.number
+			}, document.getElementById('slideroutput'));			
+			slideroutput.startup();
+
+			var sliderreset = new dijit.form.Button({
+				onClick: function(){slidermodel.reset();},
+				id: "sliderReset",
+				label: "Reset"
+			}, document.getElementById('sliderreset'));
+			sliderreset.startup();
+			
+			slidertext.startup();
+			sliderWid.startup();
+			
+			// create the dijit.form.NumberSpinner, textbox, output and button			
+			var numspinWid = new dijit.form.NumberSpinner({
+			//	constraints:{max:100,places:0},
+				ref: numspinmodel.number // bind to model.number
+			}, document.getElementById('numspinsel'));
+			
+			var numspintext = new dijit.form.TextBox({
+				ref: numspinmodel.number
+			}, document.getElementById('numspintext'));
+			
+			var numspinoutput = new dojox.mvc.Output({
+				ref: numspinmodel.number
+			}, document.getElementById('numspinoutput'));			
+			numspinoutput.startup();
+
+			var numspinreset = new dijit.form.Button({
+				onClick: function(){numspinmodel.reset();},
+				id: "numspinReset",
+				label: "Reset"
+			}, document.getElementById('numspinreset'));
+			numspinreset.startup();
+			
+			numspintext.startup();
+			numspinWid.startup();
+			
+			// create the dijit.form.SimpleTextarea, textbox, output and button 			
+			var simpTAWid = new dijit.form.SimpleTextarea({
+				style:{height:"20px", width:"180px"},
+				ref: simpTAmodel.number // bind to model.number
+			}, document.getElementById('simpTAsel'));
+			
+			var simpTAtext = new dijit.form.TextBox({
+				ref: simpTAmodel.number
+			}, document.getElementById('simpTAtext'));
+			
+			var simpTAoutput = new dojox.mvc.Output({
+				ref: simpTAmodel.number
+			}, document.getElementById('simpTAoutput'));			
+			simpTAoutput.startup();
+
+			var simpTAreset = new dijit.form.Button({
+				onClick: function(){simpTAmodel.reset();},
+				id: "simpTAReset",
+				label: "Reset"
+			}, document.getElementById('simpTAreset'));
+			simpTAreset.startup();
+			
+			simpTAtext.startup();
+			simpTAWid.startup();
+
+			// create the dijit.form.Textarea, textbox, output and button 
+			var textareaWid = new dijit.form.Textarea({
+			//	constraints:{max:100,places:0},
+				ref: textareamodel.number // bind to model.number
+			}, document.getElementById('textareasel'));
+			
+			var textareatext = new dijit.form.TextBox({
+				ref: textareamodel.number
+			}, document.getElementById('textareatext'));
+			
+			var textareaoutput = new dojox.mvc.Output({
+				ref: textareamodel.number
+			}, document.getElementById('textareaoutput'));			
+			textareaoutput.startup();
+
+			var textareareset = new dijit.form.Button({
+				onClick: function(){textareamodel.reset();},
+				id: "textareaReset",
+				label: "Reset"
+			}, document.getElementById('textareareset'));
+			textareareset.startup();
+			
+			textareatext.startup();
+			textareaWid.startup();
+
+			var numBox = new dijit.form.NumberTextBox({
+				ref: nanmodel.num // bind to model.num
+			}, document.getElementById('nannb'));
+
+			numBox.startup();
+
+			
+		});
+
+			// should be able to verify all of the inputs
+			//console.log("This test is commented out because it will fail if _FromSelectWidget is not updated to setup the store in postCreate instead of startup, see ticket 13372 for details."); 
+			
+			doh.register("Check initial programatic values and bindings for select widget only", [
+				{
+					name: "initialSelectOnly",
+					runTest: function(){
+						var wid, textboxval, outputval; 
+						// Test Select
+						wid = dijit.byId("sel");
+						textboxval = dijit.byId("seltext").value;
+						outputval = dijit.byId("selOutput").value;
+						if (wid) {
+								doh.is("1",wid.get('value'),"This test will fail if _FromSelectWidget is not updated to setup the store in postCreate instead of startup, see ticket 13372 for details.");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+					}
+				}
+			]);
+			
+			doh.register("Check initial programatic values and bindings widgets other than select", [
+				{
+					name: "initialOtherThanSelect",
+					runTest: function(){
+						var wid, textboxval, outputval; 
+						// Test FilteringSelect
+						wid = dijit.byId("filsel");
+						textboxval = dijit.byId("filtext").value;
+						outputval = dijit.byId("filoutput").value;
+						if (wid) {
+								doh.is("2",wid.get('value'),"wid.get('value') should be set");
+								doh.is("two",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.ComboBox
+						wid = dijit.byId("combosel");
+						textboxval = dijit.byId("combotext").value;
+						outputval = dijit.byId("combooutput").value;
+						if (wid) {
+								doh.is("three",wid.get('value'),"wid.get('value') should be set");
+								doh.is("three",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.DateTextBox
+						wid = dijit.byId("datesel");
+						textboxval = dijit.byId("datetext").displayedValue;
+						outputval = dijit.byId("dateoutput").value;
+						if (wid) {
+								var date = new Date(2011, 3, 4, 0, 0, 0, 0);
+								doh.is(date.getTime(), wid.get("value").getTime(), "wid.get(\"value\") should be set it is:" + wid.get("value"));
+								doh.is("04-04-2011", wid.displayedValue, "wid.displayedValue should be set it is:" + wid.displayedValue);
+								doh.is("04-04-2011", textboxval, "textboxval should be set it is:" + textboxval);
+								doh.is(date.getTime(), outputval.getTime(), "outputval should be set to match date:" + date);
+						}
+						// Test dijit.form.HorizontalSlider
+						wid = dijit.byId("slidersel");
+						textboxval = dijit.byId("slidertext").value;
+						outputval = dijit.byId("slideroutput").value;
+						if (wid) {
+								doh.is("5",wid.get('value'),"wid.get('value') should be set");
+								//doh.is("five",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.NumberSpinner
+						wid = dijit.byId("numspinsel");
+						textboxval = dijit.byId("numspintext").value;
+						outputval = dijit.byId("numspinoutput").value;
+						if (wid) {
+								//doh.is("6",wid.get('value'),"wid.get('value') should be set");
+								doh.is("6",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
+								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
+						}
+						// Test dijit.form.SimpleTextarea
+						wid = dijit.byId("simpTAsel");
+						textboxval = dijit.byId("simpTAtext").value;
+						outputval = dijit.byId("simpTAoutput").value;
+						if (wid) {
+								doh.is("7",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.Textarea
+						wid = dijit.byId("textareasel");
+						textboxval = dijit.byId("textareatext").value;
+						outputval = dijit.byId("textareaoutput").value;
+						if (wid) {
+								doh.is("8",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+
+
+					}
+				}
+			]);
+
+			// should be able to verify all of the inputs 
+			doh.register("Check initial declarative values and bindings", [
+				{
+					name: "initial-declarative",
+					runTest: function(){
+						var wid, textboxval, outputval; 
+						// Test Select
+						wid = dijit.byId("decsel");
+						textboxval = dijit.byId("decseltext").value;
+						outputval = dijit.byId("decselOutput").value;
+						if (wid) {
+								doh.is("1",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test FilteringSelect
+						wid = dijit.byId("decfilsel");
+						textboxval = dijit.byId("decfiltext").value;
+						outputval = dijit.byId("decfilOutput").value;
+						if (wid) {
+								doh.is("2",wid.get('value'),"wid.get('value') should be set");
+								doh.is("two",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.ComboBox
+						wid = dijit.byId("deccombosel");
+						textboxval = dijit.byId("deccombotext").value;
+						outputval = dijit.byId("deccomboOutput").value;
+						if (wid) {
+								doh.is("three",wid.get('value'),"wid.get('value') should be set");
+								doh.is("three",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.DateTextBox
+						wid = dijit.byId("decdatesel");
+						textboxval = dijit.byId("decdatetext").displayedValue;
+						outputval = dijit.byId("decdateOutput").value;
+						if (wid) {
+								var date = new Date(2011, 3, 4, 0, 0, 0, 0);
+								doh.t(wid.get("value").getTime() == date.getTime(), "wid.get(\"value\") should be set to:" + date);
+								doh.is("04-04-2011",wid.displayedValue,"wid.displayedValue should be set it is:"+wid.displayedValue);
+								doh.is("04-04-2011",textboxval,"textboxval should be set it is:"+textboxval);
+								doh.t(outputval.getTime() == date.getTime(), "outputval should be set to:" + date);
+						}
+						// Test dijit.form.HorizontalSlider
+						wid = dijit.byId("decslidersel");
+						textboxval = dijit.byId("decslidertext").value;
+						outputval = dijit.byId("decsliderOutput").value;
+						if (wid) {
+								doh.is("5",wid.get('value'),"wid.get('value') should be set");
+								//doh.is("five",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.NumberSpinner
+						wid = dijit.byId("decnumspinsel");
+						textboxval = dijit.byId("decnumspintext").value;
+						outputval = dijit.byId("decnumspinOutput").value;
+						if (wid) {
+								//doh.is("6",wid.get('value'),"wid.get('value') should be set");
+								doh.is("6",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
+								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
+						}
+						// Test dijit.form.SimpleTextarea
+						wid = dijit.byId("decsimpTAsel");
+						textboxval = dijit.byId("decsimpTAtext").value;
+						outputval = dijit.byId("decsimpTAOutput").value;
+						if (wid) {
+								doh.is("7",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.Textarea
+						wid = dijit.byId("dectextareasel");
+						textboxval = dijit.byId("dectextareatext").value;
+						outputval = dijit.byId("dectextareaOutput").value;
+						if (wid) {
+								doh.is("8",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+
+
+					}
+				}
+			]);
+
+			// should be able to verify all of the inputs 
+			doh.register("Check initial calendar and colorpalette values", [
+				{
+					name: "test-calendar-and-color",
+					runTest: function(){
+						var wid, textboxval, outputval; 
+						// Test Calendar
+						wid = dijit.byId("deccal");
+						textboxval = dijit.byId("deccaltext").value;
+						outputval = dijit.byId("deccalOutput").value;
+						if (wid) {
+							var date = new Date(2011, 4, 4, 0, 0, 0, 0);
+							doh.t(wid.get("value").getTime() == date.getTime(), "wid.get(\"value\") should be set to:" + date);
+							doh.t(textboxval.getTime() == date.getTime(), "1-textboxval should be set to:" + date);
+							doh.t(outputval.getTime() == date.getTime(), "1-outputval should be set to:" + date);
+						}
+						// Test dijit.ColorPalette
+						wid = dijit.byId("deccolor");
+						textboxval = dijit.byId("deccolortext").value;
+						outputval = dijit.byId("deccolorOutput").value;
+						if (wid) {
+								doh.is("#000000",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}						
+					}
+				}
+			]);
+
+			doh.register("Check update and reset calendar and colorpalette values", [
+				{
+					name: "test-calendar-and-color",
+					runTest: function(){
+						var wid, textboxval, outputval; 
+						// Test Update calendar
+						var d = new Date(2011,10,10);
+						wid = dijit.byId("deccal");
+						//wid.set('value', d.toDateString()); 						
+						wid.set('value', d); 						
+						textboxval = dijit.byId("deccaltext").value;
+						outputval = dijit.byId("deccalOutput").value;
+						if (wid && wid.get('value')) {
+							var date1 = new Date(2011, 10, 10, 0, 0, 0, 0);
+							var date2 = new Date(2011, 10, 10, 1, 0, 0, 0);
+							doh.t(wid.get("value").getTime() == date1.getTime(), "wid.get(\"value\") should be set to:" + date1);
+							doh.t(textboxval.getTime() == date2.getTime(), "2-textboxval should be set to:" + date2);
+							doh.t(outputval.getTime() == date2.getTime(), "2-outputval should be set to:" + date2);
+						}
+
+						// Test dijit.ColorPalette
+						// update the text field
+						dijit.byId('deccolortext').set('value',"#ffffff");						
+						wid = dijit.byId("deccolor");
+						textboxval = dijit.byId("deccolortext").value;
+						outputval = dijit.byId("deccolorOutput").value;
+						if (wid) {
+								doh.is("#ffffff",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+
+						// Test Reset Calendar
+						button = dijit.byId("deccalReset"); // reset the model
+						button.onClick();
+						wid = dijit.byId("deccal");
+						textboxval = dijit.byId("deccaltext").value;
+						outputval = dijit.byId("deccalOutput").value;
+						if (wid) {
+							var date = new Date(2011, 4, 4, 0, 0, 0, 0);
+							doh.t(wid.get("value").getTime() == date.getTime(), "wid.get(\"value\") should be set to:" + date);
+							doh.t(textboxval.getTime() == date.getTime(), "3-textboxval should be set to:" + date);
+							doh.t(outputval.getTime() == date.getTime(), "3-outputval should be set to:" + date);
+						}
+						// Test reset the dijit.ColorPalette
+						button = dijit.byId("deccolorReset"); // reset the model
+						button.onClick();
+						wid = dijit.byId("deccolor");
+						textboxval = dijit.byId("deccolortext").value;
+						outputval = dijit.byId("deccolorOutput").value;
+						if (wid) {
+								doh.is("#000000",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						
+						
+						
+					}
+				}
+			]);
+
+
+			// Update and Test all fields 
+			doh.register("Test update for all programatic values and bindings", [
+				{
+					name: "update-programatic",
+					runTest: function(){
+						// update the text field
+						dijit.byId('seltext').set('value',"10");						
+						var wid, textboxval, outputval; 
+						// Test Select
+						wid = dijit.byId("sel");
+						textboxval = dijit.byId("seltext").value;
+						outputval = dijit.byId("selOutput").value;
+						if (wid) {
+								doh.is("10",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test FilteringSelect
+						// update the text field
+						dijit.byId('filtext').set('value',"10");						
+						wid = dijit.byId("filsel");
+						textboxval = dijit.byId("filtext").value;
+						outputval = dijit.byId("filoutput").value;
+						if (wid) {
+								doh.is("10",wid.get('value'),"wid.get('value') should be set");
+								doh.is("ten",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.ComboBox
+						dijit.byId('combotext').set('value',"ten");						
+						wid = dijit.byId("combosel");
+						textboxval = dijit.byId("combotext").value;
+						outputval = dijit.byId("combooutput").value;
+						if (wid) {
+								doh.is("ten",wid.get('value'),"wid.get('value') should be set");
+								doh.is("ten",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.DateTextBox
+						// update the text field
+						var d = new Date(2011, 9, 10, 0, 0, 0, 0);
+						//wid.set('value', d.toDateString()); //"2011-09-09");						
+						//dijit.byId('datetext').set('value',d.toDateString());						
+						dijit.byId('datetext').set('value',d);						
+						wid = dijit.byId("datesel");
+						textboxval = dijit.byId("datetext").value;
+						outputval = dijit.byId("dateoutput").value;
+						if (wid) {
+							var date = new Date(2011, 9, 10, 0, 0, 0, 0);
+							doh.t(wid.get("value").getTime() == date.getTime(), "wid.get(\"value\") should be set to:" + date);
+							doh.t(textboxval.getTime() == date.getTime(), "2-textboxval should be set to:" + date);
+							doh.t(outputval.getTime() == date.getTime(), "2-outputval should be set to:" + date);
+						}
+						// Test dijit.form.HorizontalSlider
+						// update the text field
+						dijit.byId('slidertext').set('value',"10");						
+						wid = dijit.byId("slidersel");
+						textboxval = dijit.byId("slidertext").value;
+						outputval = dijit.byId("slideroutput").value;
+						if (wid) {
+								doh.is("10",wid.get('value'),"wid.get(value) should be set");
+								//doh.is("five",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.NumberSpinner
+						dijit.byId('numspintext').set('value',"10");						
+						wid = dijit.byId("numspinsel");
+						textboxval = dijit.byId("numspintext").value;
+						outputval = dijit.byId("numspinoutput").value;
+						if (wid) {
+								doh.is("10",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
+								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
+						}
+						// Test dijit.form.SimpleTextarea
+						dijit.byId('simpTAtext').set('value',"10");						
+						wid = dijit.byId("simpTAsel");
+						textboxval = dijit.byId("simpTAtext").value;
+						outputval = dijit.byId("simpTAoutput").value;
+						if (wid) {
+								doh.is("10",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.Textarea
+						dijit.byId('textareatext').set('value',"10");						
+						wid = dijit.byId("textareasel");
+						textboxval = dijit.byId("textareatext").value;
+						outputval = dijit.byId("textareaoutput").value;
+						if (wid) {
+								doh.is("10",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+
+
+					}
+				}
+			]);
+
+			// Update and Test all fields 
+			doh.register("Test update for all declarative values and bindings", [
+				{
+					name: "update-declarative",
+					runTest: function(){
+						dijit.byId("decsel").set('value',"4");   // update widget value						
+						var wid, textboxval, outputval; 
+						// Test Select
+						wid = dijit.byId("decsel");
+						textboxval = dijit.byId("decseltext").value;
+						outputval = dijit.byId("decselOutput").value;
+						if (wid) {
+								doh.is("4",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test FilteringSelect
+						wid = dijit.byId("decfilsel");
+						wid.set('value','4');   // update widget value
+						textboxval = dijit.byId("decfiltext").value;
+						outputval = dijit.byId("decfilOutput").value;
+						if (wid) {
+								doh.is("4",wid.get('value'),"wid.get('value') should be set");
+								doh.is("four",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.ComboBox
+						wid = dijit.byId("deccombosel");
+						wid.set('value',"four");   // update widget value
+						textboxval = dijit.byId("deccombotext").value;
+						outputval = dijit.byId("deccomboOutput").value;
+						if (wid) {
+								doh.is("four",wid.get('value'),"wid.get('value') should be set");
+								doh.is("four",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.DateTextBox
+						wid = dijit.byId("decdatesel");
+						//var d = new Date(2011,09,09);
+						//wid.set('value', d.toDateString()); //"2011-09-09");						
+						wid.set('value', "2011-09-09");						
+						textboxval = dijit.byId("decdatetext").value;
+						outputval = dijit.byId("decdateOutput").value;
+						if (wid) {
+								var date = new Date(2011, 8, 9, 0, 0, 0, 0);
+								doh.t(wid.get("value").getTime() == date.getTime(), "wid.get(\"value\") should be set to:" + date);
+								doh.t(textboxval.getTime() == date.getTime(), "2-textboxval should be set to:" + date);
+								doh.t(outputval.getTime() == date.getTime(), "2-outputval should be set to:" + date);
+								doh.is("09-09-2011",wid.displayedValue,"wid.displayedValue should be set");
+						}
+						// Test dijit.form.HorizontalSlider
+						wid = dijit.byId("decslidersel");
+						wid.set('value',"4");   // update widget value
+						textboxval = dijit.byId("decslidertext").value;
+						outputval = dijit.byId("decsliderOutput").value;
+						if (wid) {
+								doh.is("4",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.NumberSpinner
+						wid = dijit.byId("decnumspinsel");
+						wid.set('displayedValue',"4");   // update widget value
+						textboxval = dijit.byId("decnumspintext").value;
+						outputval = dijit.byId("decnumspinOutput").value;
+						if (wid) {
+								doh.is("4",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
+								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
+						}
+						// Test dijit.form.SimpleTextarea
+						wid = dijit.byId("decsimpTAsel");
+						wid.set('value',"4");   // update widget value
+						textboxval = dijit.byId("decsimpTAtext").value;
+						outputval = dijit.byId("decsimpTAOutput").value;
+						if (wid) {
+								doh.is("4",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.Textarea
+						wid = dijit.byId("dectextareasel");
+						wid.set('value',"4");   // update widget value
+						textboxval = dijit.byId("dectextareatext").value;
+						outputval = dijit.byId("dectextareaOutput").value;
+						if (wid) {
+								doh.is("4",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+
+
+					}
+				}
+			]);
+
+
+
+
+			// Test RESET for all fields 
+			doh.register("Test reset for all programatic values and bindings", [
+				{
+					name: "reset-programatic",
+					runTest: function(){
+						// reset the model
+						var button = dijit.byId("selReset"); 
+						button.onClick();
+						var wid, textboxval, outputval; 
+						// Test Select
+						wid = dijit.byId("sel");
+						textboxval = dijit.byId("seltext").value;
+						outputval = dijit.byId("selOutput").value;
+						if (wid) {
+								doh.is("1",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test FilteringSelect
+						button = dijit.byId("filReset"); 
+						button.onClick();
+						wid = dijit.byId("filsel");
+						textboxval = dijit.byId("filtext").value;
+						outputval = dijit.byId("filoutput").value;
+						if (wid) {
+								doh.is("2",wid.get('value'),"wid.get('value') should be set");
+								doh.is("two",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.ComboBox
+						button = dijit.byId("comboReset"); 
+						button.onClick();
+						wid = dijit.byId("combosel");
+						textboxval = dijit.byId("combotext").value;
+						outputval = dijit.byId("combooutput").value;
+						if (wid) {
+								doh.is("three",wid.get('value'),"wid.get('value') should be set");
+								doh.is("three",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.DateTextBox
+						button = dijit.byId("dateReset"); 
+						button.onClick();
+						wid = dijit.byId("datesel");
+						textboxval = dijit.byId("datetext").value;
+						outputval = dijit.byId("dateoutput").value;
+						if (wid) {
+							var date = new Date(2011, 3, 4, 0, 0, 0, 0);
+							doh.t(textboxval.getTime() == date.getTime(), "textboxval should be set to:" + date);
+							doh.t(outputval.getTime() == date.getTime(), "outputval should be set to:" + date);
+						}
+						// test a second reset...
+						button.onClick();
+						if (wid) {
+								var date = new Date(2011, 3, 4, 0, 0, 0, 0);
+								doh.t(wid.get("value").getTime() == date.getTime(), "wid.get(\"value\") should be set to:" + date);
+								doh.t(textboxval.getTime() == date.getTime(), "2-textboxval should be set to:" + date);
+								doh.t(outputval.getTime() == date.getTime(), "2-outputval should be set to:" + date);
+								doh.is("04-04-2011",wid.displayedValue,"wid.displayedValue should be set");
+						}
+						// Test dijit.form.HorizontalSlider
+						button = dijit.byId("sliderReset"); 
+						button.onClick();
+						wid = dijit.byId("slidersel");
+						textboxval = dijit.byId("slidertext").value;
+						outputval = dijit.byId("slideroutput").value;
+						if (wid) {
+								doh.is("5",wid.get('value'),"wid.get('value') should be set");
+								//doh.is("five",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.NumberSpinner
+						button = dijit.byId("numspinReset"); 
+						button.onClick();
+						wid = dijit.byId("numspinsel");
+						textboxval = dijit.byId("numspintext").value;
+						outputval = dijit.byId("numspinoutput").value;
+						if (wid) {
+								doh.is("6",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
+								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
+						}
+						// Test dijit.form.SimpleTextarea
+						button = dijit.byId("simpTAReset"); 
+						button.onClick();
+						wid = dijit.byId("simpTAsel");
+						textboxval = dijit.byId("simpTAtext").value;
+						outputval = dijit.byId("simpTAoutput").value;
+						if (wid) {
+								doh.is("7",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.Textarea
+						button = dijit.byId("textareaReset"); 
+						button.onClick();
+						wid = dijit.byId("textareasel");
+						textboxval = dijit.byId("textareatext").value;
+						outputval = dijit.byId("textareaoutput").value;
+						if (wid) {
+								doh.is("8",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+
+
+					}
+				}
+			]);
+
+			// Test reset all declarative 
+			doh.register("Test Reset all declarative values and bindings", [
+				{
+					name: "reset-declarative",
+					runTest: function(){
+						var button = dijit.byId("decselReset"); // reset the model
+						button.onClick();
+						var wid, textboxval, outputval; 
+						// Test Select
+						wid = dijit.byId("decsel");
+						textboxval = dijit.byId("decseltext").value;
+						outputval = dijit.byId("decselOutput").value;
+						if (wid) {
+								doh.is("1",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test FilteringSelect
+						button = dijit.byId("decfilReset"); // reset the model
+						button.onClick();
+						wid = dijit.byId("decfilsel");
+						textboxval = dijit.byId("decfiltext").value;
+						outputval = dijit.byId("decfilOutput").value;
+						if (wid) {
+								doh.is("2",wid.get('value'),"wid.get('value') should be set");
+								doh.is("two",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.ComboBox
+						button = dijit.byId("deccomboReset"); // reset the model
+						button.onClick();
+						wid = dijit.byId("deccombosel");
+						textboxval = dijit.byId("deccombotext").value;
+						outputval = dijit.byId("deccomboOutput").value;
+						if (wid) {
+								doh.is("three",wid.get('value'),"wid.get('value') should be set");
+								doh.is("three",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.DateTextBox
+						button = dijit.byId("decdateReset"); // reset the model
+						button.onClick();
+						wid = dijit.byId("decdatesel");
+						textboxval = dijit.byId("decdatetext").displayedValue;
+						outputval = dijit.byId("decdateOutput").value;
+						if (wid) {
+								var date = new Date(2011, 3, 4, 0, 0, 0, 0);
+								doh.t(wid.get("value").getTime() == date.getTime(), "wid.get(\"value\") should be set to:" + date);
+								doh.is("04-04-2011",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is("04-04-2011",textboxval,"textboxval should be set");
+								outputval = dijit.byId("decdateOutput").value;
+								doh.t(outputval.getTime() == date.getTime(), "outputval should be set to:" + date);
+						}
+						// Test dijit.form.HorizontalSlider
+						button = dijit.byId("decsliderReset"); // reset the model
+						button.onClick();
+						wid = dijit.byId("decslidersel");
+						textboxval = dijit.byId("decslidertext").value;
+						outputval = dijit.byId("decsliderOutput").value;
+						if (wid) {
+								doh.is("5",wid.get('value'),"wid.get('value') should be set");
+								//doh.is("five",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.NumberSpinner
+						button = dijit.byId("decnumspinReset"); // reset the model
+						button.onClick();
+						wid = dijit.byId("decnumspinsel");
+						textboxval = dijit.byId("decnumspintext").value;
+						outputval = dijit.byId("decnumspinOutput").value;
+						if (wid) {
+								//doh.is("6",wid.get('value'),"wid.get('value') should be set");
+								doh.is("6",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
+								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
+						}
+						// Test dijit.form.SimpleTextarea
+						button = dijit.byId("decsimpTAReset"); // reset the model
+						button.onClick();
+						wid = dijit.byId("decsimpTAsel");
+						textboxval = dijit.byId("decsimpTAtext").value;
+						outputval = dijit.byId("decsimpTAOutput").value;
+						if (wid) {
+								doh.is("7",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+						// Test dijit.form.Textarea
+						button = dijit.byId("dectextareaReset"); // reset the model
+						button.onClick();
+						wid = dijit.byId("dectextareasel");
+						textboxval = dijit.byId("dectextareatext").value;
+						outputval = dijit.byId("dectextareaOutput").value;
+						if (wid) {
+								doh.is("8",wid.get('value'),"wid.get('value') should be set");
+								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
+								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
+						}
+
+					}
+				}
+			]);
+
+
+			// Test reset all declarative 
+			doh.register("Test NaN values and bindings", [
+				{
+					name: "NaN-test",
+					runTest: function(){
+						var button = dijit.byId("decselReset"); // reset the model
+						button.onClick();
+						var wid, wid2; 
+
+						// test for NaN stuff here, uses nanmodel, without fix for ticket 14190 FF crashes
+						wid = dijit.byId("nannb");
+						wid.focus();
+						wid2 = dijit.byId("textareatext");
+						wid2.focus();
+						wid = dijit.byId("nannb");
+						wid.focus();
+						wid2.focus();
+						if (wid) {
+								doh.t(isNaN(wid.get('value')),"isNaN(wid.get('value') should be true");
+						}
+
+					}
+				}
+			]);
+
+			doh.run();
+
+		});
+	</script>
+</head>
+	<body class="claro">
+		<div id="wrapper">
+			<div id="header" style="margin-top: 0px;">
+				<div id="navigation"  style="margin-top: 0px;"></div>
+				<div id="headerInsert"  style="margin-top: 0px;">
+					<h2>Data-bound Form Element Kitchen Sink MVC test</h2>
+				</div>
+			</div>
+			<div id="main" style="margin-top: 0px;">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+	
+					<h2 style="margin-top: 0px;">Programmatic creation of Form elements:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+								<td><label for="sel">Select:</label></td>
+								<td><div id="sel"></div></td>
+								<td><div id="seltext"></div></td>
+								<td><div id="selOutput"></div></td>
+								<td><div id="reset1" ></div></td>
+							</tr>
+							<tr>
+								<td><label for="filsel">FilteringSelect:</label></td>
+								<td><div id="filsel"></div></td>
+								<td><div id="filtext"></div></td>
+								<td><div id="filoutput"></div></td>
+								<td><div id="filreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="combosel">ComboBox:</label></td>
+								<td><div id="combosel"></div></td>
+								<td><div id="combotext"></div></td>
+								<td><div id="combooutput"></div></td>
+								<td><div id="comboreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="datesel">DateTextBox:</label></td>
+								<td><div id="datesel"></div></td>
+								<td><div id="datetext"></div></td>
+								<td><div id="dateoutput"></div></td>
+								<td><div id="datereset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="slidersel">Slider:</label></td>
+								<td><div id="slidersel"></div></td>
+								<td><div id="slidertext"></div></td>
+								<td><div id="slideroutput"></div></td>
+								<td><div id="sliderreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="numspinsel">NumberSpinner:</label></td>
+								<td><div id="numspinsel"></div></td>
+								<td><div id="numspintext"></div></td>
+								<td><div id="numspinoutput"></div></td>
+								<td><div id="numspinreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="simpTAsel">SimpleTextArea:</label></td>
+								<td><div id="simpTAsel"></div></td>
+								<td><div id="simpTAtext"></div></td>
+								<td><div id="simpTAoutput"></div></td>
+								<td><div id="simpTAreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="textareasel">TextArea:</label></td>
+								<td><div id="textareasel"></div></td>
+								<td><div id="textareatext"></div></td>
+								<td><div id="textareaoutput"></div></td>
+								<td><div id="textareareset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="nannb">TextBox nan test:</label></td>
+								<td><div id="nannb"></div></td>
+							</tr>							
+						</tbody>
+					</table>
+	  
+					<h2>Declarative creation of Form elements:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+								<td><label for="decsel">Select:</label></td>
+								<td>
+									<select id="decsel" style="width: 188px;" 
+													data-dojo-id="decsel" data-dojo-type="dijit.form.Select" 
+													data-dojo-props='name:"decsel", ref: decselmodel.number '>
+										<option value="1">one</option>
+										<option value="2">two</option>
+										<option value="3">three</option>
+										<option value="4">four</option>
+									</select>
+								</td>
+								<td>
+									<input class="cell" id="decseltext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decselmodel.number"></input>
+								</td>
+								<td><span   id="decselOutput" data-dojo-type="dojox.mvc.Output"
+											data-dojo-props="ref: decselmodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="decselReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decselmodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decfilsel">FilteringSelect:</label></td>
+								<td>
+									<input id="decfilsel" data-dojo-type="dijit.form.FilteringSelect"
+										data-dojo-props='store:store, ref: decfilmodel.number'/>
+								</td>
+								<td>
+									<input id="decfiltext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decfilmodel.number"></input>
+								</td>
+								<td><span id="decfilOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: decfilmodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="decfilReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decfilmodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="deccombosel">ComboBox:</label></td>
+								<td>
+									<input id="deccombosel" data-dojo-type="dijit.form.ComboBox"
+										data-dojo-props='store:store, ref: deccombomodel.number'/>
+								</td>
+								<td>
+									<input id="deccombotext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: deccombomodel.number"></input>
+								</td>
+								<td><span id="deccomboOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: deccombomodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="deccomboReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){deccombomodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="datesel">DateTextBox:</label></td>
+								<td>
+									<input id="decdatesel" data-dojo-type="dijit.form.DateTextBox"
+										data-dojo-props='store:store, ref: decdatemodel.number, constraints: dummyDateWid.constraints'/>
+								</td>
+								<td>
+									<input id="decdatetext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decdatemodel.number, 
+									disabled: true,
+									constraints: dummyDateWid.constraints,
+									dateLocaleModule : dummyDateWid.dateLocaleModule,
+									format : dummyDateWid.format"></input>
+								</td>
+								<td><span id="decdateOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: decdatemodel.number, constraints: dummyDateWid.constraints">
+						 			${this.value}
+								</span></td>
+								<td><button id="decdateReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decdatemodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decslidersel">Slider:</label></td>
+								<td>
+									<input id="decslidersel" data-dojo-type="dijit.form.HorizontalSlider"
+										data-dojo-props='store:store, ref: decslidermodel.number,
+														style:{width:"190px"}, minimum:0, maximum:100, discreteValues:21'/>
+								</td>
+								<td>
+									<input id="decslidertext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decslidermodel.number"></input>
+								</td>
+								<td><span id="decsliderOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: decslidermodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="decsliderReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decslidermodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decnumspinsel">NumberSpinner:</label></td>
+								<td>
+									<input id="decnumspinsel" data-dojo-type="dijit.form.NumberSpinner"
+										data-dojo-props='store:store, ref: decnumspinmodel.number'/>
+								</td>
+								<td>
+									<input id="decnumspintext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decnumspinmodel.number"></input>
+								</td>
+								<td><span id="decnumspinOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: decnumspinmodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="decnumspinReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decnumspinmodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decsimpTAsel">SimpleTextArea:</label></td>
+								<td>
+									<input id="decsimpTAsel" data-dojo-type="dijit.form.Textarea"
+										data-dojo-props='store:store, ref: decsimpTAmodel.number'/>
+								</td>
+								<td>
+									<input id="decsimpTAtext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decsimpTAmodel.number"/>
+								</td>
+								<td><span id="decsimpTAOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: decsimpTAmodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="decsimpTAReset" type="button" data-dojo-type="dijit.form.Button" 
+										data-dojo-props="onClick: function(){decsimpTAmodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="dectextareasel">TextArea:</label></td>
+								<td>
+									<input id="dectextareasel" data-dojo-type="dijit.form.Textarea"
+										data-dojo-props='store:store, ref: dectextareamodel.number'/>
+								</td>
+								<td>
+									<input id="dectextareatext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: dectextareamodel.number"/>
+								</td>
+								<td><span id="dectextareaOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: dectextareamodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="dectextareaReset" type="button" data-dojo-type="dijit.form.Button" 
+										data-dojo-props="onClick: function(){dectextareamodel.reset();}">Reset</button></td>
+							</tr>
+						</tbody>
+					</table>
+	  
+					<h2>Test data-bound dijit.Calendar:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+								<td><label for="deccal">Calendar:</label></td>
+								<td>
+									<input class="cell"  id="deccal" data-dojo-id="deccal"  data-dojo-type="dijit.Calendar" 
+											data-dojo-props='ref: deccalmodel.date '/>
+								</td>
+								<td>
+									<input class="cell" id="deccaltext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: deccalmodel.date"></input>
+								</td>
+								<td><span   id="deccalOutput" data-dojo-type="dojox.mvc.Output"
+											data-dojo-props="ref: deccalmodel.date">
+						 			${this.value}
+								</span></td>
+								<td><button id="deccalReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){deccalmodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="deccolor">ColorPalette:</label></td>
+								<td>
+									<div id="deccolor" data-dojo-type="dijit.ColorPalette" 
+											data-dojo-props='palette:"3x4", ref: deccolormodel.code'></div>								
+								</td>
+								<td>
+									<input class="cell" id="deccolortext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: deccolormodel.code"></input>
+								</td>
+								<td><span   id="deccolorOutput" data-dojo-type="dojox.mvc.Output"
+											data-dojo-props="ref: deccolormodel.code">
+						 			${this.value}
+								</span></td>
+								<td><button id="deccolorReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){deccolormodel.reset();}">Reset</button></td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_mvc_programmatic-repeat-store.html b/dojox/mvc/tests/1.7/doh/doh_mvc_programmatic-repeat-store.html
new file mode 100644
index 0000000..0cf6895
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_mvc_programmatic-repeat-store.html
@@ -0,0 +1,348 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>MVC DOH Test</title>
+
+	<style>
+		@import "../../../../../dojo/resources/dojo.css";
+		@import "../../../../../dijit/tests/css/dijitTests.css";
+		@import "../css/app-format.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script src="../../../../../dojo/dojo.js" type="text/javascript"
+		djConfig="parseOnLoad: false, isDebug: true">
+	</script>
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<script type="text/javascript" >
+		dojo.require("dojox.mvc");
+		dojo.require("dojox.mvc.Group");
+		dojo.require("dojox.mvc.Repeat");
+		dojo.require("dijit.form.TextBox");
+		dojo.require("dijit.form.Button");
+		dojo.require("dojo.data.ItemFileWriteStore");
+		dojo.require("dojo.store.DataStore");
+		dojo.require("dojo.parser");
+		
+			var results, selectedIndex = 0;
+				// declared here for convenience
+			templateString = '<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: \'${this.index}\'">' +
+							'<label class="cell">Name:</label>' + 
+							'<input class="cell" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: \'First\'"></input>' +
+							'<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext(\'${this.index}\');}">Details</button>' +
+						'</div>';
+
+			function setup() {
+				var writeStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests._data", "mvcRepeatData.json")});
+				var modelPromise = dojox.mvc.newStatefulModel({store: new dojo.store.DataStore({store: writeStore})}); 
+				modelPromise.then(function(model){ 
+					results = model;
+					dojo.parser.parse();
+
+					// Can test with either the dojox.mvc.Repeat or my.Repeat
+					var repeat = new my.Repeat({
+					//var repeat = new dojox.mvc.Repeat({
+					//	templateString: templateString, // not needed with my.Repeat since it is set there.
+						ref: model
+					}).placeAt('repeat2');
+					repeat.startup();
+					startTests();
+				});
+			};
+
+			dojo.declare('my.Repeat', [dojox.mvc.Repeat], {
+				templateString : templateString
+			});
+			dojo.addOnLoad(setup);
+	</script>
+
+	<script type="text/javascript">
+		dojo.require('doh.runner');
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		function startTests(){
+			 // should be able to verify all of the inputs 
+			doh.register("Check initial values and bindings", [
+				{
+					name: "initial",
+					runTest: function(){
+						var name1, bind1, firstInput; 
+						name1 = dijit.byId("dijit_form_TextBox_10");
+						if (name1) {
+							console.log("testing dijit_form_TextBox_10");
+							bind1 = name1.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Anne",bind1.data,"bind1.data should be set");
+								doh.is("Anne",bind1.value,"bind1.value should be set");
+							}
+						}
+
+						name1 = dijit.byId("dijit_form_TextBox_0");
+						if (name1) {
+							console.log("testing dijit_form_TextBox_0");
+							bind1 = name1.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Anne",bind1.data,"bind1.data should be set");
+								doh.is("Anne",bind1.value,"bind1.value should be set");
+							}
+						}
+
+						firstInput = dijit.byId("firstInput");
+						if (firstInput) {
+							bind1 = firstInput.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Anne",bind1.data,"bind1.data should be set");
+								doh.is("Anne",bind1.value,"bind1.value should be set");
+							}
+						}
+					}
+				}
+			]);
+
+			doh.register("select Ben", [
+				{
+					name: "testBen",
+					runTest: function(){
+						setDetailsContext(1);
+						var name1, bind1, firstInput; 
+						name1 = dijit.byId("dijit_form_TextBox_11");
+						if (name1) {
+							bind1 = name1.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Ben",bind1.data,"bind1.data is wrong");
+								doh.is("Ben",bind1.value,"bind1.value is wrong");
+							}
+						}
+						name1 = dijit.byId("dijit_form_TextBox_1");
+						if (name1) {
+							bind1 = name1.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Ben",bind1.data,"bind1.data is wrong");
+								doh.is("Ben",bind1.value,"bind1.value is wrong");
+							}
+						}
+
+						firstInput = dijit.byId("firstInput");
+						if (firstInput) {
+							bind1 = firstInput.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								console.debug("firstInput.value="+firstInput.value);
+								doh.is("Ben",bind1.data,"firstInput bind1.data is wrong");
+								doh.is("Ben",bind1.value,"firstInput bind1.value is wrong");
+							}
+						}
+					}
+				}
+			]);
+
+
+			doh.register("select John and update John to Johnny test valueOf and toString", [
+				{
+					name: "testJohn",
+					runTest: function(){
+						setDetailsContext(9); //select John 
+						var name9, bind9, firstInput; 
+						name9 = dijit.byId("dijit_form_TextBox_19");
+						if (name9) {
+							bind9 = name9.get("binding");
+							if (bind9 && bind9.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("John",bind9.data,"bind9.data is wrong");
+								doh.is("John",bind9.value,"bind9.value is wrong");
+								doh.is("John",bind9.valueOf(),"bind9.valueOf() is wrong");
+								doh.is("John",bind9.toString(),"bind9.toString() is wrong");
+							}
+						}
+						name9 = dijit.byId("dijit_form_TextBox_9");
+						if (name9) {
+							bind9 = name9.get("binding");
+							if (bind9 && bind9.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("John",bind9.data,"bind9.data is wrong");
+								doh.is("John",bind9.value,"bind9.value is wrong");
+								doh.is("John",bind9.valueOf(),"bind9.valueOf() is wrong");
+								doh.is("John",bind9.toString(),"bind9.toString() is wrong");
+							}
+						}
+
+						firstInput = dijit.byId("firstInput");
+						dojo.byId("firstInput").focus();
+						firstInput.set('value',"Johnny");
+						dojo.byId("lastInput").focus();
+						
+						if (firstInput) {
+							bind9 = firstInput.get("binding");
+							if (bind9 && bind9.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Johnny",bind9.value,"firstInput bind9.value is wrong");
+								doh.is("Johnny",firstInput.value,"firstInput firstInput.value is wrong");
+								doh.is("Johnny",bind9.valueOf(),"firstInput bind9.valueOf() is wrong");
+								doh.is("Johnny",bind9.toString(),"firstInput bind9.toString() is wrong");
+							}
+						}
+
+						// Test the value of and toString
+						valueOfTest = new dojox.mvc.StatefulModel({ data: 42 });
+						doh.is(42,valueOfTest.data,"valueOfTest.data is wrong");
+						doh.is(42,valueOfTest.value,"valueOfTest.value is wrong");
+						doh.is(42,+valueOfTest,"valueOfTest.valueOf() is wrong");
+						doh.is("42",'' + valueOfTest,"valueOfTest.toString() is wrong");
+
+						toStringTest = new dojox.mvc.StatefulModel({ data: 'abc' });
+						doh.is('abc',toStringTest.data,"toStringTest.data is wrong");
+						doh.is('abc',toStringTest.value,"toStringTest.value is wrong");
+						doh.is(NaN,+toStringTest,"toStringTest.valueOf() is wrong");
+						doh.is('abc','' + toStringTest,"toStringTest.toString() is wrong")
+
+						
+					}					
+				}
+			]);
+
+			doh.register("test Commit and Reset", [
+				{
+					name: "testC&R",
+					runTest: function(){
+						setDetailsContext(8); //select Irene 
+						var name8, bind8, firstInput, lastInput; 
+						name8 = dijit.byId("dijit_form_TextBox_18");
+						if (name8) {
+							bind8 = name8.get("binding");
+							if (bind8 && bind8.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Irene",bind8.data,"bind8.data is wrong");
+								doh.is("Irene",bind8.value,"bind8.value is wrong");
+							}
+						}
+						name8 = dijit.byId("dijit_form_TextBox_8");
+						if (name8) {
+							bind8 = name8.get("binding");
+							if (bind8 && bind8.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Irene",bind8.data,"bind8.data is wrong");
+								doh.is("Irene",bind8.value,"bind8.value is wrong");
+							}
+						}
+
+						//update Irene to IreneThisUpdateShouldBeSaved and commit
+						firstInput = dijit.byId("firstInput");
+						dojo.byId("firstInput").focus();
+						firstInput.set("value","IreneThisUpdateShouldBeSaved");
+						dojo.byId("lastInput").focus();
+						results.commit();
+
+						lastInput = dijit.byId("lastInput");
+						dojo.byId("lastInput").focus();
+						lastInput.set("value", "IraThisUpdateShouldBeReset");
+						dojo.byId("firstInput").focus();
+						results.reset();
+						
+						if (firstInput) {
+							bind8 = firstInput.get("binding");
+							if (bind8 && bind8.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("IreneThisUpdateShouldBeSaved",bind8.value,"firstInput bind8.value is wrong");
+								doh.is("IreneThisUpdateShouldBeSaved",firstInput.value,"firstInput firstInput.value is wrong");
+								doh.is("Ira",lastInput.value,"lastInput lastInput.value is wrong");
+							}
+						}
+					}
+				}
+			]);
+			
+			doh.run();
+		};
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">doh_mvc_programmatic-repeat-store.html automated tests (non-robot)</h1>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation">
+				</div>
+				<div id="headerInsert">
+				<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav">
+				</div>
+				<div id="mainContent">
+					<div id="searchBanner">Search Results for term: </div>         
+					<!--
+						The repeat container denotes a templated UI that operates over a collection
+						of data records.
+						The UI can be customized for each iteration using properties such as
+						${this.index} for the iteration index.
+					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results', templateString: templateString"></div>
+					<div id="repeatId" data-dojo-type="my.Repeat" data-dojo-props="ref: 'results'"></div>
+					-->
+					<table><tbody><tr>
+								<td>
+									<div>
+										<div>Programatic Repeat using my.Repeat and its templateString: </div>         
+										<div id="repeat2"></div>
+									</div>
+								</td>
+								<td>
+									<div>
+										<div>Declarative Repeat using my.Repeat does not pass templateString: </div>         
+										<div id="repeatId2" data-dojo-type="my.Repeat" data-dojo-props="ref: 'results'"></div>
+									</div>
+								</td>
+					</tr></tbody></table>
+					
+					<div class="spacer"></div>
+
+					<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results'">
+						<div id="detailsBanner">Details for selected index:</div>
+
+						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
+							<div class="row">
+								<label class="cell" for="firstInput">First Name:</label>
+								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="lastInput">Last Name:</label>
+								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="locationInput">Location:</label>
+								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="officeInput">Office:</label>
+								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="emailInput">Email:</label>
+								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="telInput">Telephone:</label>
+								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="faxInput">Fax:</label>
+								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
+							</div>
+							<div class="row">
+							<div class="spacer"></div>
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results[selectedIndex].toPlainObject());results[selectedIndex].commit();}">Save Item</button>        
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.toPlainObject());results.commit();;}">Commit All</button>        
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.reset();}">Reset to last saved</button>        
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+        </div>
+        <script type="text/javascript">
+			// called to change the selected item
+			function setDetailsContext(index) {
+				selectedIndex = index;
+				var widget = dijit.byId("detailsGroup");
+				widget.set("ref", index);
+			}
+        </script>
+    </body>
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_mvc_ref-set-repeat.html b/dojox/mvc/tests/1.7/doh/doh_mvc_ref-set-repeat.html
new file mode 100644
index 0000000..abacff0
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_mvc_ref-set-repeat.html
@@ -0,0 +1,247 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>MVC DOH Test</title>
+	<style>
+		@import "../../../../../dojo/resources/dojo.css";
+		@import "../../../../../dijit/tests/css/dijitTests.css";
+		@import "../css/app-format.css";
+	</style>
+	<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+	<script src="../../../../../dojo/dojo.js" type="text/javascript" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../helpers.js"></script>
+	<script type="text/javascript">
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Output");
+			dojo.require("dojox.mvc.Group");
+			dojo.require("dojox.mvc.Repeat");
+			dojo.require("dijit.form.TextBox");
+			dojo.require("dijit.form.Button");
+			dojo.require("dojo.store.Memory");
+			dojo.require("dojo.parser");
+
+			var search_results_init1 =
+			[{
+				"Query" : "Engineers1",
+				"Results" : [
+					{
+						"First"	  : "Anne1",
+						"Last"	  : "Ackerman1"
+					},
+					{
+						"First"	  : "Ben1",
+						"Last"	  : "Beckham1"
+					},
+					{
+						"First"	  : "Chad1",
+						"Last"	  : "Chapman1"
+					}
+				]
+			}];
+			var search_results_init2 =
+			[{
+				"Query" : "Engineers2",
+				"Results" : [
+					{
+						"First"	  : "Anne2",
+						"Last"	  : "Ackerman2"
+					},
+					{
+						"First"	  : "Ben2",
+						"Last"	  : "Beckham2"
+					}
+				]
+			}];
+			var search_results_init3 =
+			[{
+				"Query" : "Engineers3",
+				"Results" : [
+					{
+						"First"	  : "",
+						"Last"	  : ""
+					}
+				]
+			}];
+
+			var memStore1 = new dojo.store.Memory({data : search_results_init1});
+			var model1 = dojox.mvc.newStatefulModel({ store : memStore1 })[0];
+			var memStore2 = new dojo.store.Memory({data : search_results_init2});
+			var model2 = dojox.mvc.newStatefulModel({ store : memStore2 })[0];
+			var memStore3 = new dojo.store.Memory({data : search_results_init3});
+			var model3 = dojox.mvc.newStatefulModel({ store : memStore3 })[0];
+	</script>
+
+	<script type="text/javascript">
+		dojo.require('doh.runner');
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
+
+		dojo.addOnLoad(function() {
+
+		doh.register("parse", function() {
+			dojo.parser.parse();
+		});
+
+		// should be able to verify all of the inputs 
+		doh.register("check initial values and bindings", [{
+			name : "initial",
+			runTest : function() {
+				doh.is("Anne1", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne1");
+				doh.is("Ben1",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben1 ");
+				doh.is("Chad1", dijit.byId("nameInput2").get('value'),"nameInput2 should be Chad1");
+
+				doh.is("Anne1", dijit.byId("firstnameOutput10").get('value'),"firstnameOutput10 should be Anne1");
+				doh.is("Ben1",  dijit.byId("firstnameOutput11").get('value'),"firstnameOutput11 should be Ben1 ");
+				doh.is("Chad1", dijit.byId("firstnameOutput12").get('value'),"firstnameOutput12 should be Chad1");
+
+				doh.is("Anne2", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2");
+				doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
+
+				doh.is("", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be blank");
+			}
+		}]);
+
+		doh.register("SelectModel2", [{
+			name : "SelectModel2",
+			runTest : function() {
+							//doh.robot.mouseMoveAt("dijit_form_Button_1", 500, 0);
+							//doh.robot.mouseClick({left:true}, 500);
+				dijit.byId('outergroupId').set('ref',model2);			
+							
+				doh.is("Anne2", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne2");
+				doh.is("Ben2",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben2 ");				
+			}
+		}]);
+
+		doh.register("ChangeModel2", [{
+			name : "ChangeModel2",
+			runTest : function() {
+				dijit.byId('nameInput0').set('value',"Anne2-Update");			
+							
+				doh.is("Anne2-Update", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne2-Update");
+				doh.is("Ben2",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben2 ");
+
+				doh.is("Anne2-Update", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2-Update");
+				doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
+			}
+		}]);
+
+		doh.register("SelectModel3", [{
+			name : "SelectModel3",
+			runTest : function() {
+				dijit.byId('outergroupId').set('ref',model3);			
+							
+				doh.is("", dijit.byId("nameInput0").get('value'),"nameInput0 should be blank");
+			}
+		}]);
+
+		doh.register("ChangeModel3", [{
+			name : "ChangeModel3",
+			runTest : function() {
+				dijit.byId('nameInput0').set('value',"Anne3-Update");			
+							
+				doh.is("Anne3-Update", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne3-Update");
+
+				doh.is("Anne3-Update", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be Anne3-Update");
+			}
+		}]);
+
+		doh.register("ResetAll", [{
+			name : "ResetAll",
+			runTest : function() {
+				dijit.byId('outergroupId').set('ref',model1);			
+				model1.reset();
+				model2.reset();
+				model3.reset();			
+							
+				doh.is("Anne1", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne1");
+				doh.is("Ben1",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben1 ");
+				doh.is("Chad1", dijit.byId("nameInput2").get('value'),"nameInput2 should be Chad1");
+
+				doh.is("Anne1", dijit.byId("firstnameOutput10").get('value'),"firstnameOutput10 should be Anne1");
+				doh.is("Ben1",  dijit.byId("firstnameOutput11").get('value'),"firstnameOutput11 should be Ben1 ");
+				doh.is("Chad1", dijit.byId("firstnameOutput12").get('value'),"firstnameOutput12 should be Chad1");
+
+				doh.is("Anne2", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2");
+				doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
+
+				doh.is("", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be blank");
+			}
+		}]);
+
+		doh.run();
+
+		});
+	</script>
+</head>
+
+
+	<body class="claro">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="row">
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model1);}">Swap Model1</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model2);}">Swap Model2</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model3);}">Swap Model3</button>
+					</div>
+					<div id="outergroupId"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model1'">
+						<div id="innergroupId"	 data-dojo-type="dojox.mvc.Group">
+							<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
+								<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+									<label class="cell" for="nameInput${this.index}">Name:</label>
+									<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
+								</div>
+							</div>
+						</div>
+					</div>
+					<div class="row">
+							<span>
+								Model1 Output is ==>  
+							</span>
+							<span id="firstnameOutput10" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[0].First">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput11" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[1].First">
+								Name2 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput12" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[2].First">
+								Name3 is "${this.value}"  
+							</span>
+					</div>
+					<div class="row">
+							<span>
+								Model2 Output is ==>  
+							</span>
+							<span id="firstnameOutput20" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[0].First">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput21" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[1].First">
+								Name2 is "${this.value}"  
+							</span>
+					</div>
+					<div class="row">
+							<span>
+								Model3 Output is ==>  
+							</span>
+							<span id="firstnameOutput30" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model3.Results[0].First">
+								Name1 is "${this.value}"  
+							</span>
+					</div>					
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model1.reset();model2.reset();model3.reset();}">Reset all</button>
+				</div>
+			</div>
+		</div>
+	</body>
+
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_mvc_search-results-repeat-store.html b/dojox/mvc/tests/1.7/doh/doh_mvc_search-results-repeat-store.html
new file mode 100644
index 0000000..03e2f16
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_mvc_search-results-repeat-store.html
@@ -0,0 +1,278 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>MVC DOH Test</title>
+
+	<style>
+		@import "../../../../../dojo/resources/dojo.css";
+		@import "../../../../../dijit/tests/css/dijitTests.css";
+		@import "../css/app-format.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script src="../../../../../dojo/dojo.js" type="text/javascript"
+		djConfig="parseOnLoad: false, isDebug: true">
+	</script>
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<script type="text/javascript" >
+		dojo.require("dojox.mvc");
+		dojo.require("dojox.mvc.Group");
+		dojo.require("dojox.mvc.Repeat");
+		dojo.require("dijit.form.TextBox");
+		dojo.require("dijit.form.Button");
+		dojo.require("dojo.data.ItemFileWriteStore");
+		dojo.require("dojo.store.DataStore");
+		dojo.require("dojo.parser");
+		
+		var results, selectedIndex = 0;
+
+		function setup() {
+			var writeStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests._data", "mvcRepeatData.json")});
+			var modelPromise = dojox.mvc.newStatefulModel({store: new dojo.store.DataStore({store: writeStore})}); 
+			modelPromise.then(function(model){ 
+				results = model;
+				dojo.parser.parse();
+				startTests();
+			});
+		};
+
+		dojo.addOnLoad(setup);
+	</script>
+
+	<script type="text/javascript">
+		dojo.require('doh.runner');
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		function startTests(){
+			 // should be able to verify all of the inputs 
+			doh.register("Check initial values and bindings", [
+				{
+					name: "initial",
+					runTest: function(){
+						var name1, bind1, firstInput; 
+						name1 = dijit.byId("nameInput0");
+						if (name1) {
+							bind1 = name1.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Anne",bind1.data,"bind1.data should be set");
+								doh.is("Anne",bind1.value,"bind1.value should be set");
+							}
+						}
+
+						firstInput = dijit.byId("firstInput");
+						if (firstInput) {
+							bind1 = firstInput.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Anne",bind1.data,"bind1.data should be set");
+								doh.is("Anne",bind1.value,"bind1.value should be set");
+							}
+						}
+					}
+				}
+			]);
+
+			doh.register("select Ben", [
+				{
+					name: "testBen",
+					runTest: function(){
+						setDetailsContext(1);
+						var name1, bind1, firstInput; 
+						name1 = dijit.byId("nameInput1");
+						if (name1) {
+							bind1 = name1.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Ben",bind1.data,"bind1.data is wrong");
+								doh.is("Ben",bind1.value,"bind1.value is wrong");
+							}
+						}
+
+						firstInput = dijit.byId("firstInput");
+						if (firstInput) {
+							bind1 = firstInput.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								console.debug("firstInput.value="+firstInput.value);
+								doh.is("Ben",bind1.data,"firstInput bind1.data is wrong");
+								doh.is("Ben",bind1.value,"firstInput bind1.value is wrong");
+							}
+						}
+					}
+				}
+			]);
+
+
+			doh.register("select John and update John to Johnny test valueOf and toString", [
+				{
+					name: "testJohn",
+					runTest: function(){
+						setDetailsContext(9); //select John 
+						var name9, bind9, firstInput; 
+						name9 = dijit.byId("nameInput9");
+						if (name9) {
+							bind9 = name9.get("binding");
+							if (bind9 && bind9.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("John",bind9.data,"bind9.data is wrong");
+								doh.is("John",bind9.value,"bind9.value is wrong");
+								doh.is("John",bind9.valueOf(),"bind9.valueOf() is wrong");
+								doh.is("John",bind9.toString(),"bind9.toString() is wrong");
+							}
+						}
+
+						firstInput = dijit.byId("firstInput");
+						dojo.byId("firstInput").focus();
+						firstInput.set('value',"Johnny");
+						dojo.byId("lastInput").focus();
+						
+						if (firstInput) {
+							bind9 = firstInput.get("binding");
+							if (bind9 && bind9.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Johnny",bind9.value,"firstInput bind9.value is wrong");
+								doh.is("Johnny",firstInput.value,"firstInput firstInput.value is wrong");
+								doh.is("Johnny",bind9.valueOf(),"firstInput bind9.valueOf() is wrong");
+								doh.is("Johnny",bind9.toString(),"firstInput bind9.toString() is wrong");
+							}
+						}
+
+						// Test the value of and toString
+						valueOfTest = new dojox.mvc.StatefulModel({ data: 42 });
+						doh.is(42,valueOfTest.data,"valueOfTest.data is wrong");
+						doh.is(42,valueOfTest.value,"valueOfTest.value is wrong");
+						doh.is(42,+valueOfTest,"valueOfTest.valueOf() is wrong");
+						doh.is("42",'' + valueOfTest,"valueOfTest.toString() is wrong");
+
+						toStringTest = new dojox.mvc.StatefulModel({ data: 'abc' });
+						doh.is('abc',toStringTest.data,"toStringTest.data is wrong");
+						doh.is('abc',toStringTest.value,"toStringTest.value is wrong");
+						doh.is(NaN,+toStringTest,"toStringTest.valueOf() is wrong");
+						doh.is('abc','' + toStringTest,"toStringTest.toString() is wrong")
+
+						
+					}					
+				}
+			]);
+
+			doh.register("test Commit and Reset", [
+				{
+					name: "testC&R",
+					runTest: function(){
+						setDetailsContext(8); //select Irene 
+						var name8, bind8, firstInput, lastInput; 
+						name8 = dijit.byId("nameInput8");
+						if (name8) {
+							bind8 = name8.get("binding");
+							if (bind8 && bind8.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Irene",bind8.data,"bind8.data is wrong");
+								doh.is("Irene",bind8.value,"bind8.value is wrong");
+							}
+						}
+
+						//update Irene to IreneThisUpdateShouldBeSaved and commit
+						firstInput = dijit.byId("firstInput");
+						dojo.byId("firstInput").focus();
+						firstInput.set("value","IreneThisUpdateShouldBeSaved");
+						dojo.byId("lastInput").focus();
+						results.commit();
+
+						lastInput = dijit.byId("lastInput");
+						dojo.byId("lastInput").focus();
+						lastInput.set("value", "IraThisUpdateShouldBeReset");
+						dojo.byId("firstInput").focus();
+						results.reset();
+						
+						if (firstInput) {
+							bind8 = firstInput.get("binding");
+							if (bind8 && bind8.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("IreneThisUpdateShouldBeSaved",bind8.value,"firstInput bind8.value is wrong");
+								doh.is("IreneThisUpdateShouldBeSaved",firstInput.value,"firstInput firstInput.value is wrong");
+								doh.is("Ira",lastInput.value,"lastInput lastInput.value is wrong");
+							}
+						}
+					}
+				}
+			]);
+			
+			doh.run();
+		};
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">doh_mvc_search-results-repeat-store.html automated tests (non-robot)</h1>
+		<div id="wrapper">
+		<div id="header">
+			<div id="navigation"></div>
+			<div id="headerInsert">
+				<h1>Employee Search</h1>
+				<h2>Master Detail Example - With repeat container.</h2>
+			</div>
+		</div>
+		<div id="main">
+			<div id="leftNav"></div>
+			<div id="mainContent">
+			<!--
+				The repeat container denotes a templated UI that operates over a collection
+				of data records.
+				The UI can be customized for each iteration using properties such as
+				${this.index} for the iteration index.
+			-->
+			<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results'">
+				<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+					<label class="cell" for="nameInput${this.index}">Name:</label>
+					<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results'">
+				<div id="detailsBanner">Details for selected index:</div>
+				<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
+					<div class="row">
+						<label class="cell" for="firstInput">First Name:</label>
+						<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="lastInput">Last Name:</label>
+						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="locationInput">Location:</label>
+						<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="officeInput">Office:</label>
+						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label>
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="telInput">Telephone:</label>
+						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="faxInput">Fax:</label>
+						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"/>
+					</div>
+					<div class="row">
+						<div class="spacer"></div>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.commit();}">Commit</button>		 
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.reset();}">Reset</button>		   
+					</div>
+				</div>
+			</div>
+		</div>
+		</div>
+	</div>
+	<script type="text/javascript">
+	function setDetailsContext(index) {
+				selectedIndex = index;
+				var widget = dijit.byId("detailsGroup");
+				widget.set("ref", index);
+	}
+	</script>
+</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_mvc_search-results-repeat.html b/dojox/mvc/tests/1.7/doh/doh_mvc_search-results-repeat.html
new file mode 100644
index 0000000..915d8f1
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_mvc_search-results-repeat.html
@@ -0,0 +1,301 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>MVC DOH Test</title>
+
+	<style>
+		@import "../../../../../dojo/resources/dojo.css";
+		@import "../../../../../dijit/tests/css/dijitTests.css";
+		@import "../css/app-format.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script src="../../../../../dojo/dojo.js" type="text/javascript"
+		djConfig="isDebug: true">
+	</script>
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<script type="text/javascript" >
+		dojo.require("dojox.mvc");
+		dojo.require("dojox.mvc.Group");
+		dojo.require("dojox.mvc.Repeat");
+		dojo.require("dijit.form.TextBox");
+		dojo.require("dijit.form.Button");
+		dojo.require("dojo.parser");
+
+		// Raw records for the master detail
+		var search_results_init =
+		{
+		  "Query" : "Engineers",
+		  "Results" : [
+			  {
+				  "First"	: "Anne",
+				  "Last"	: "Ackerman",
+				  "Location": "NY",
+				  "Office"	: "1S76",
+				  "Email"	: "a.a at test.com",
+				  "Tel"		: "123-764-8237",
+				  "Fax"		: "123-764-8228"
+			  },
+			  {
+				  "First"	: "Ben",
+				  "Last"	: "Beckham",
+				  "Location": "NY",
+				  "Office"	: "5N47",
+				  "Email"	: "b.b at test.com",
+				  "Tel"		: "123-764-8599",
+				  "Fax"		: "123-764-8600"
+			  },
+			  {
+				  "First"	: "Chad",
+				  "Last"	: "Chapman",
+				  "Location": "CA",
+				  "Office"	: "1278",
+				  "Email"	: "c.c at test.com",
+				  "Tel"		: "408-764-8237",
+				  "Fax"		: "408-764-8228"
+			  },
+			  {
+				  "First"	: "David",
+				  "Last"	: "Durham",
+				  "Location": "NJ",
+				  "Office"	: "C12",
+				  "Email"	: "d.d at test.com",
+				  "Tel"		: "514-764-8237",
+				  "Fax"		: "514-764-8228"
+			  },
+			  {
+				  "First"	: "Emma",
+				  "Last"	: "Eklof",
+				  "Location": "NY",
+				  "Office"	: "4N76",
+				  "Email"	: "e.e at test.com",
+				  "Tel"		: "123-764-1234",
+				  "Fax"		: "123-764-4321"
+			  },
+			  {
+				  "First"	: "Fred",
+				  "Last"	: "Fisher",
+				  "Location": "NJ",
+				  "Office"	: "V89",
+				  "Email"	: "f.f at test.com",
+				  "Tel"		: "514-764-8567",
+				  "Fax"		: "514-764-8000"
+			  },
+			  {
+				  "First"	: "George",
+				  "Last"	: "Garnett",
+				  "Location": "NY",
+				  "Office"	: "7S11",
+				  "Email"	: "gig at test.com",
+				  "Tel"		: "123-999-8599",
+				  "Fax"		: "123-999-8600"
+			  },
+			  {
+				  "First"	: "Hunter",
+				  "Last"	: "Huffman",
+				  "Location": "CA",
+				  "Office"	: "6532",
+				  "Email"	: "h.h at test.com",
+				  "Tel"		: "408-874-8237",
+				  "Fax"		: "408-874-8228"
+			  },
+			  {
+				  "First"	: "Irene",
+				  "Last"	: "Ira",
+				  "Location": "NJ",
+				  "Office"	: "F09",
+				  "Email"	: "i.i at test.com",
+				  "Tel"		: "514-764-6532",
+				  "Fax"		: "514-764-7300"
+			  },
+			  {
+				  "First"	: "John",
+				  "Last"	: "Jacklin",
+				  "Location": "CA",
+				  "Office"	: "6701",
+				  "Email"	: "j.j at test.com",
+				  "Tel"		: "408-764-1234",
+				  "Fax"		: "408-764-4321"
+			  }
+		  ]
+	  };
+
+	  // The dojox.mvc.StatefulModel class creates a data model instance
+	  // where each leaf within the data model is decorated with dojo.Stateful
+	  // properties that widgets can bind to and watch for their changes.
+	  var searchRecords = dojox.mvc.newStatefulModel({ data : search_results_init });
+	</script>
+
+	<script type="text/javascript">
+		dojo.require('doh.runner');
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+
+		dojo.addOnLoad(function(){
+
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+			// should be able to verify all of the inputs 
+			doh.register("Check initial values and bindings", [
+				{
+					name: "initial",
+					runTest: function(){
+						var name1, bind1, firstInput; 
+						name1 = dijit.byId("nameInput0");
+						if (name1) {
+							bind1 = name1.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Anne",bind1.data,"bind1.data should be set");
+								doh.is("Anne",bind1.value,"bind1.value should be set");
+							}
+						}
+
+						firstInput = dijit.byId("firstInput");
+						if (firstInput) {
+							bind1 = firstInput.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Anne",bind1.data,"bind1.data should be set");
+								doh.is("Anne",bind1.value,"bind1.value should be set");
+							}
+						}
+					}
+				}
+			]);
+
+			doh.register("select Ben", [
+				{
+					name: "testBen",
+					runTest: function(){
+						setDetailsContext(1);
+						var name1, bind1, firstInput; 
+						name1 = dijit.byId("nameInput1");
+						if (name1) {
+							bind1 = name1.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								doh.is("Ben",bind1.data,"bind1.data is wrong");
+								doh.is("Ben",bind1.value,"bind1.value is wrong");
+							}
+						}
+
+						firstInput = dijit.byId("firstInput");
+						if (firstInput) {
+							bind1 = firstInput.get("binding");
+							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+								console.debug("firstInput.value="+firstInput.value);
+								doh.is("Ben",bind1.data,"firstInput bind1.data is wrong");
+								doh.is("Ben",bind1.value,"firstInput bind1.value is wrong");
+							}
+						}
+					}					
+				}
+			]);
+
+			doh.run();
+
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">doh_mvc_search-results-repeat.html automated tests (non-robot)</h1>
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - With repeat container.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		 <div id="leftNav">
+		 </div>
+		 <div id="mainContent">
+		 <!--
+			 The group container denotes some logical grouping of widgets and also serves
+			 to establish a parent data binding context for its children.
+			 The ref attribute for the outermost container obtains the binding from the
+			 "page scope" itself.
+		 -->
+		 <div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'searchRecords'">
+			<div class="row">
+				<label class="cell" for="queryInput">Search for:</label>
+				<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Query'"/>
+				<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setSearchBanner();}">Search</button>
+			</div>
+			<div class="spacer"></div>
+
+			<div id="searchBanner">Search Results for term: Engineers</div>
+
+			<!--
+				The repeat container denotes a templated UI that operates over a collection
+				of data records.
+				The UI can be customized for each iteration using properties such as
+				${this.index} for the iteration index.
+			-->
+			<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
+				<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+					<label class="cell" for="nameInput${this.index}">Name:</label>
+					<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+				</div>
+			</div>
+			<div class="spacer"></div>
+
+			<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Results'">
+				<div id="detailsBanner">Details for result index: 0</div>
+
+				<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
+					<div class="row">
+						<label class="cell" for="firstInput">First Name:</label>
+						<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="lastInput">Last Name:</label>
+						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="locationInput">Location:</label>
+						<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="officeInput">Office:</label>
+						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label>
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="telInput">Telephone:</label>
+						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="faxInput">Fax:</label>
+						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"/>
+					</div>
+				</div>
+			</div>
+		</div>
+		</div>
+	</div>
+	<script type="text/javascript">
+	function setDetailsContext(index) {
+		var widget = dijit.byId("detailsGroup");
+		widget.set("ref", index);
+		var detailsBanner = dojo.byId("detailsBanner");
+		detailsBanner.innerHTML = "Details for result index: " + index;
+	}
+	function setSearchBanner() {
+		var searchBanner = dojo.byId("searchBanner");
+		searchBanner.innerHTML = "Search Results for term: " + searchRecords.Query.get("value");
+	}
+	</script>
+</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_mvc_shipto-billto-hierarchical.html b/dojox/mvc/tests/1.7/doh/doh_mvc_shipto-billto-hierarchical.html
new file mode 100644
index 0000000..5c30950
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_mvc_shipto-billto-hierarchical.html
@@ -0,0 +1,377 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>MVC DOH Test</title>
+	<style>
+		@import "../../../../../dojo/resources/dojo.css";
+		@import "../../../../../dijit/tests/css/dijitTests.css";
+		@import "../css/app-format.css";
+	</style>
+	<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+	<script src="../../../../../dojo/dojo.js" type="text/javascript" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../helpers.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.mvc");
+		dojo.require("dojox.mvc.Group");
+		dojo.require("dijit.form.TextBox");
+		dojo.require("dijit.form.Button");
+		dojo.require("dojo.parser");
+
+		  // Initial data with a noticeable hierarchy
+		  var order = {
+			  "Serial" : "360324",
+			  "First"  : "John",
+			  "Last"   : "Doe",
+			  "Email"  : "jdoe at example.com",
+			  "ShipTo" : {
+				  "Type" : "Home",
+				  "Address" : {
+					  "Street" : "123 Valley Rd",
+					  "City"   : "Katonah",
+					  "State"  : "NY",
+					  "Zip"	   : "10536"
+				  },
+				  "Telephone" : {
+					  "AreaCode" : "123",
+					  "Landline" : {
+						  "Number"	  : "456-7890",
+						  "Extension" : "42"
+					  },
+					  "Cell" : {
+						  "Number"	  : "765-4321"
+					  }
+				  }
+			  },
+			  "BillTo" : {
+				  "Type" : "Office",
+				  "Address" : {
+					  "Street" : "17 Skyline Dr",
+					  "City"   : "Hawthorne",
+					  "State"  : "NY",
+					  "Zip"	   : "10532"
+				  },
+				  "Telephone" : {
+					  "AreaCode" : "098",
+					  "Landline" : {
+						  "Number"	  : "765-4321",
+						  "Extension" : "24"
+					  },
+					  "Cell" : {
+						  "Number"	  : "123-4567"
+					  }
+				  }
+			  }
+		  };
+
+		  // The dojox.mvc.StatefulModel class creates a data model instance
+		  // where each leaf within the data model is decorated with dojo.Stateful
+		  // properties that widgets can bind to and watch for their changes.
+		  var model = dojox.mvc.newStatefulModel({ data : order });
+		  var selectedAddr = dojox.mvc.newStatefulModel({ data : "ShipTo" });
+	</script>
+
+	<script type="text/javascript">
+		dojo.require('doh.runner');
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
+
+		dojo.addOnLoad(function() {
+
+		doh.register("parse", function() {
+			dojo.parser.parse();
+		});
+
+		// should be able to verify all of the inputs 
+		doh.register("check initial values and bindings", [{
+			name : "initial",
+			runTest : function() {
+				var serial1, bind1, addr1;
+				//test serialInput
+				serial1 = dijit.byId("serialInput");
+				if (serial1) {
+					bind1 = serial1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("360324", bind1.data,"bind1.data should be set");
+						doh.is("360324", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test addrLabel
+				addr1 = dijit.byId("addrLabel");
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("ShipTo", bind1.data,"bind1.data should be set");
+						doh.is("ShipTo", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test streetInput
+				addr1 = dijit.byId("streetInput");
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("123 Valley Rd", bind1.data,"bind1.data should be set");
+						doh.is("123 Valley Rd", bind1.value,"bind1.value should be set");
+					}
+				}
+			}
+		}]);
+
+		doh.register("check BillTo", [{
+			name : "testBillTo",
+			runTest : function() {
+				setRef('addrGroup', 'model.BillTo');
+				
+				var serial1, bind1, addr1;
+				//test serialInput
+				serial1 = dijit.byId("serialInput");
+				if (serial1) {
+					bind1 = serial1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("360324", bind1.data,"bind1.data should be set");
+						doh.is("360324", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test addrLabel
+				addr1 = dijit.byId("addrLabel");
+
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("ShipTo", bind1.data,"bind1.data should be set");
+						doh.is("BillTo", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test streetInput
+				addr1 = dijit.byId("streetInput");
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("17 Skyline Dr", bind1.data,"bind1.data should be set");
+						doh.is("17 Skyline Dr", bind1.value,"bind1.value should be set");
+					}
+				}
+			}
+		}]);
+
+		doh.register("check ShipTo", [{
+			name : "testShipTo",
+			runTest : function() {
+				setRef('addrGroup', 'model.ShipTo');
+				
+				var serial1, bind1, addr1;
+				//test serialInput
+				serial1 = dijit.byId("serialInput");
+				if (serial1) {
+					bind1 = serial1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("360324", bind1.data,"bind1.data should be set");
+						doh.is("360324", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test addrLabel
+				addr1 = dijit.byId("addrLabel");
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("ShipTo", bind1.data,"bind1.data should be set");
+						doh.is("ShipTo", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test streetInput
+				addr1 = dijit.byId("streetInput");
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("123 Valley Rd", bind1.data,"bind1.data should be set");
+						doh.is("123 Valley Rd", bind1.value,"bind1.value should be set");
+					}
+				}
+			}
+		}]);
+
+		doh.register("change ShipTo", [{
+			name : "testShipTo",
+			runTest : function() {
+				setRef('addrGroup', 'model.ShipTo');
+				//set streetInput
+				addr1 = dijit.byId("streetInput");
+				if (addr1) {
+					addr1.set("value","456 Mountain Rd");
+				}
+				setRef('addrGroup', 'model.BillTo');
+				setRef('addrGroup', 'model.ShipTo');
+				
+				var serial1, bind1, addr1;
+				//test serialInput
+				serial1 = dijit.byId("serialInput");
+				if (serial1) {
+					bind1 = serial1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("360324", bind1.data,"bind1.data should be set");
+						doh.is("360324", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test addrLabel
+				addr1 = dijit.byId("addrLabel");
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("ShipTo", bind1.data,"bind1.data should be set");
+						doh.is("ShipTo", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test streetInput
+				var addr1s = dijit.byId("streetInput");
+				if (addr1s) {
+					bind1s = addr1s.get("binding");
+					if (bind1s && bind1s.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("456 Mountain Rd", bind1s.value,"bind1s.value should be set");
+						bind1s.commit();
+						doh.is("456 Mountain Rd", bind1s.data,"bind1s.value should be set after commit");
+					}
+				}
+				//test streetInput
+				var addr1c = dijit.byId("cityInput");
+				if (addr1c) {
+					bind1c = addr1c.get("binding");
+					if (bind1c && bind1c.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("Katonah", bind1c.value,"bind1c.value should be set");
+						doh.is("Katonah", bind1c.data,"bind1c.data should be set");
+					}
+				}
+			}
+		}]);
+
+		doh.run();
+
+		});
+	</script>
+</head>
+
+
+	<body class="claro">
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Order Shipping Details</h1>
+			<h2>Data Binding Example - Hierarchical data.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		  <div id="leftNav">
+		  </div>
+		  <div id="mainContent">
+		<!--
+			The group container denotes some logical grouping of widgets and also serves
+			to establish a parent data binding context for its children.
+			The ref attribute for the outermost container obtains the binding from the
+			"page scope" itself.
+		-->
+		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model'">
+			<div class="row">
+				<label class="cell" for="serialInput">Order #:</label>
+				<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Serial'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="lastnameInput">Last name:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Last'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Email'"/>
+			</div>
+		</div>
+		<br/>
+		Choose:
+		<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.ShipTo');}">Ship To</button>
+		<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.BillTo');}">Bill To</button>
+		<br/>
+		<div class="row">
+			<label class="cell" for="addrLabel">Selected Address:</label>
+			<input class="cell" data-dojo-type="dijit.form.TextBox" id="addrLabel"
+								data-dojo-props="ref: 'selectedAddr'"/>
+		</div>
+		<br/>
+		<!--
+			For convenience, the widget hierarchy matches the data hierarchy
+			(see JSON literal above).
+			In this implementation, the child ref attributes are simple property names
+			of the parent binding context.
+			The ref attribute may support more advanced constructs, such as queries
+			over the parent widget's or other application specified binding context.
+		-->
+		  <div id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model.ShipTo'">
+			<div class="row">
+			  <label class="cell" for="typeInput">Type:</label>
+			  <input class="cell" id="typeInput" data-dojo-type="dijit.form.TextBox"
+								  data-dojo-props="ref: 'Type'"/>
+			</div>
+			<div id="postalGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Address'">
+			  <div class="row">
+				  <label class="cell" for="streetInput">Street:</label>
+				  <input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'Street'"/>
+			  </div>
+			  <div class="row">
+				  <label class="cell" for="cityInput">City:</label>
+				  <input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'City'"/>
+			  </div>
+			  <div class="row">
+				  <label class="cell" for="stateInput">State:</label>
+				  <input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'State'"/>
+			  </div>
+			  <div class="row">
+				  <label class="cell" for="zipInput">Zipcode:</label>
+				  <input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'Zip'"/>
+			  </div>
+			</div>
+			<div id="telGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Telephone'">
+			  <div class="row">
+				  <label class="cell" for="areacodeInput">Area code:</label>
+				  <input class="cell" id="areacodeInput" data-dojo-type="dijit.form.TextBox"
+										 data-dojo-props="ref: 'AreaCode'"/>
+			  </div>
+			  <div id="llGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Landline'">
+				<div class="row">
+				  <label class="cell" for="numberInput">Landline Number:</label>
+				  <input class="cell" id="numberInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'Number'"/>
+				</div>
+				<div class="row">
+				  <label class="cell" for="extInput">Extension:</label>
+				  <input class="cell" id="extInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'Extension'"/>
+				</div>
+			  </div>
+			  <div class="row" id="cellGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Cell'">
+				  <label class="cell" for="cellInput">Cell Number:</label>
+				  <input class="cell" id="cellInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'Number'"/>
+			  </div>
+			</div>
+			<br/>
+			Model:
+			<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+		</div></div></div>
+		<script type="text/javascript">
+			function setRef(id, addrRef) {
+				var widget = dijit.byId(id);
+				widget.set("ref", addrRef);
+				if(addrRef == "model.ShipTo")
+					selectedAddr.set("value", "ShipTo");
+				else
+					selectedAddr.set("value", "BillTo");
+			}
+		</script>
+	</body>
+
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_mvc_shipto-billto-simple.html b/dojox/mvc/tests/1.7/doh/doh_mvc_shipto-billto-simple.html
new file mode 100644
index 0000000..4cbfd74
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_mvc_shipto-billto-simple.html
@@ -0,0 +1,215 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>MVC DOH Test</title>
+	<style>
+		@import "../../../../../dojo/resources/dojo.css";
+		@import "../../../../../dijit/tests/css/dijitTests.css";
+		@import "../css/app-format.css";
+	</style>
+	<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+	<script src="../../../../../dojo/dojo.js" type="text/javascript" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../helpers.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.mvc");
+		dojo.require("dojox.mvc.Group");
+		dojo.require("dijit.form.TextBox");
+		dojo.require("dijit.form.Button");
+		dojo.require("dojo.parser");
+
+		// Initial data
+		var master_init = {
+			"Serial" : "360324",
+			"First" : "John",
+			"Last" : "Doe",
+			"Email" : "jdoe at example.com",
+			"ShipTo" : {
+				"Street" : "123 Valley Rd",
+				"City" : "Katonah",
+				"State" : "NY",
+				"Zip" : "10536"
+			},
+			"BillTo" : {
+				"Street" : "17 Skyline Dr",
+				"City" : "Hawthorne",
+				"State" : "NY",
+				"Zip" : "10532"
+			}
+		};
+
+		// The dojox.mvc.StatefulModel class creates a data model instance
+		// where each leaf within the data model is decorated with dojo.Stateful
+		// properties that widgets can bind to and watch for their changes.
+		var masterRecord = dojox.mvc.newStatefulModel({ data : master_init });
+		var selectedAddr = dojox.mvc.newStatefulModel({ data : "ShipTo" });
+	</script>
+
+	<script type="text/javascript">
+		dojo.require('doh.runner');
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
+
+		dojo.addOnLoad(function() {
+
+		doh.register("parse", function() {
+			dojo.parser.parse();
+		});
+
+		// should be able to verify all of the inputs 
+		doh.register("check initial values and bindings", [{
+			name : "initial",
+			runTest : function() {
+				var serial1, bind1, addr1;
+				//test serialInput
+				serial1 = dijit.byId("serialInput");
+				if (serial1) {
+					bind1 = serial1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("360324", bind1.data,"bind1.data should be set");
+						doh.is("360324", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test addrLabel
+				addr1 = dijit.byId("addrLabel");
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("ShipTo", bind1.data,"bind1.data should be set");
+						doh.is("ShipTo", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test streetInput
+				addr1 = dijit.byId("streetInput");
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("123 Valley Rd", bind1.data,"bind1.data should be set");
+						doh.is("123 Valley Rd", bind1.value,"bind1.value should be set");
+					}
+				}
+			}
+		}]);
+
+		doh.register("check BillTo", [{
+			name : "testBillTo",
+			runTest : function() {
+				setRef("addrGroup", masterRecord.BillTo);
+				var serial1, bind1, addr1;
+				//test serialInput
+				serial1 = dijit.byId("serialInput");
+				if (serial1) {
+					bind1 = serial1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("360324", bind1.data,"bind1.data should be set");
+						doh.is("360324", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test addrLabel
+				addr1 = dijit.byId("addrLabel");
+
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("ShipTo", bind1.data,"bind1.data should be set");
+						doh.is("BillTo", bind1.value,"bind1.value should be set");
+					}
+				}
+				//test streetInput
+				addr1 = dijit.byId("streetInput");
+				if (addr1) {
+					bind1 = addr1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("17 Skyline Dr", bind1.data,"bind1.data should be set");
+						doh.is("17 Skyline Dr", bind1.value,"bind1.value should be set");
+					}
+				}
+			}
+		}]);
+
+		doh.run();
+
+		});
+	</script>
+</head>
+
+
+<body class="claro">
+	<h1 class="testTitle">doh_mvc__shipto-billto-simple.html automated tests (non-robot)</h1>
+	<div id="wrapper">
+		<div id="header">
+			<div id="navigation"></div>
+			<div id="headerInsert">
+				<h1>Order Shipping Details</h1>
+				<h2>Data Binding Example - Group Container.</h2>
+			</div>
+		</div>
+		<div id="main">
+			<div id="leftNav"></div>
+			<div id="mainContent"><!--
+			The group container denotes some logical grouping of widgets and also serves
+			to establish a parent data binding context for its children.
+			The ref attribute for the outermost container obtains the binding from the
+			"page scope" itself.
+			-->
+			<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'masterRecord'">
+				<div class="row"><label class="cell" for="serialInput">Serial:</label>
+					<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Serial'"/>
+				</div>
+				<div class="row"><label class="cell" for="lastnameInput">Last:</label>
+					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
+				</div>
+				<div class="row"><label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
+				</div>
+			</div>
+			<br />
+			Choose:
+			<button id="shipto1" type="button" data-dojo-type="dijit.form.Button"
+				data-dojo-props="onClick: function(){setRef('addrGroup', masterRecord.ShipTo);}">Ship To</button>
+			<button id="billto1" type="button" data-dojo-type="dijit.form.Button"
+				data-dojo-props="onClick: function(){setRef('addrGroup', masterRecord.BillTo);}">Bill To</button>
+			<br />
+			<div class="row"><label class="cell" for="addrLabel">Selected
+			Address:</label> <input class="cell" data-dojo-type="dijit.form.TextBox"
+				id="addrLabel" data-dojo-props="ref: 'selectedAddr'"/></div>
+			<br />
+			<!--
+				For convenience, the widget hierarchy matches the data hierarchy
+				(see JSON literal above).
+				In this implementation, the child ref attributes are simple property names
+				of the parent binding context.
+				The ref attribute may support more advanced constructs, such as queries
+				over the parent widget's or other application specified binding context.
+			-->
+			<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group"
+				data-dojo-props="ref: 'masterRecord.ShipTo'">
+				<div class="row"><label class="cell" for="streetInput">Street:</label>
+					<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Street'"/>
+				</div>
+				<div class="row"><label class="cell" for="cityInput">City:</label>
+					<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'City'"/>
+				</div>
+				<div class="row"><label class="cell" for="stateInput">State:</label>
+					<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'State'"/>
+				</div>
+				<div class="row"><label class="cell" for="zipInput">Zipcode:</label>
+					<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Zip'"/>
+				</div>
+			</div>
+		</div>
+		</div>
+	</div>
+	<script type="text/javascript">
+	function setRef(id, addrRef){
+		var widget = dijit.byId(id);
+		widget.set("ref", addrRef);
+		if(addrRef == "masterRecord.ShipTo"){
+			selectedAddr.set("value", "ShipTo");
+		}else{
+			selectedAddr.set("value", "BillTo");
+		}
+	}
+	</script>
+</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_mvc_template_repeat_exprchar.html b/dojox/mvc/tests/1.7/doh/doh_mvc_template_repeat_exprchar.html
new file mode 100644
index 0000000..edc90d5
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_mvc_template_repeat_exprchar.html
@@ -0,0 +1,237 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>MVC DOH Test</title>
+
+	<style>
+		@import "../../../../../dojo/resources/dojo.css";
+		@import "../../../../../dijit/tests/css/dijitTests.css";
+		@import "../css/app-format.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script src="../../../../../dojo/dojo.js" type="text/javascript"
+		djConfig="isDebug: true">
+	</script>
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<script type="text/javascript">
+            dojo.require("dojox.mvc");
+            dojo.require("dojox.mvc.Group");
+            dojo.require("dojox.mvc.Repeat");
+            dojo.require("dijit.form.TextBox");
+            dojo.require("dijit.form.Button");
+            dojo.require("dojo.parser");
+            dojo.registerModulePath("17", "../dojox/mvc/tests/1.7");
+            dojo.require("17.test_templatedWidget.myMvcTemplated");
+            
+            // Raw records for the master detail
+            var search_results_init = {
+                "Query": "Engineers",
+                "Results": [{
+                    "First": "Anne",
+                    "Last": "Ackerman",
+                    "Location": "NY",
+                    "Office": "1S76",
+                    "Email": "a.a at test.com",
+                    "Tel": "123-764-8237",
+                    "Fax": "123-764-8228"
+                }, {
+                    "First": "Ben",
+                    "Last": "Beckham",
+                    "Location": "NY",
+                    "Office": "5N47",
+                    "Email": "b.b at test.com",
+                    "Tel": "123-764-8599",
+                    "Fax": "123-764-8600"
+                }, {
+                    "First": "John",
+                    "Last": "Jacklin",
+                    "Location": "CA",
+                    "Office": "6701",
+                    "Email": "j.j at test.com",
+                    "Tel": "408-764-1234",
+                    "Fax": "408-764-4321"
+                }]
+            };
+            
+            // The dojox.mvc.StatefulModel class creates a data model instance
+            // where each leaf within the data model is decorated with dojo.Stateful
+            // properties that widgets can bind to and watch for their changes.
+            var searchRecords = dojox.mvc.newStatefulModel({
+                data: search_results_init
+            });
+            
+            dojo.ready(function(){
+                dojo.parser.parse();
+            });
+	</script>
+
+	<script type="text/javascript">
+		dojo.require('doh.runner');
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
+
+		dojo.addOnLoad(function() {
+
+		doh.register("parse", function() {
+			dojo.parser.parse();
+		});
+
+		// should be able to verify all of the inputs 
+		doh.register("check initial values for Input0s", [{
+			name : "initial",
+			runTest : function() {
+				var name1, bind1;
+				//test nameInput0 
+				name1 = dijit.byId("nameInput0");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("Anne",bind1.data,"bind1.data should be set");
+						doh.is("Anne",bind1.value,"bind1.value should be set");
+					}
+				}
+				//test anameInput0 
+				name1 = dijit.byId("anameInput0");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("Anne",bind1.data,"bind1.data should be set");
+						doh.is("Anne",bind1.value,"bind1.value should be set");
+					}
+				}
+				//test bnameInput0 
+				name1 = dijit.byId("bnameInput0");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("Anne",bind1.data,"bind1.data should be set");
+						doh.is("Anne",bind1.value,"bind1.value should be set");
+					}
+				}
+				//test 9nameInput0 
+				name1 = dijit.byId("9nameInput0");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("Anne",bind1.data,"bind1.data should be set");
+						doh.is("Anne",bind1.value,"bind1.value should be set");
+					}
+				}
+			}
+		}]);
+
+		doh.register("check initial values for Input1s", [{
+			name : "initial",
+			runTest : function() {
+				var name1, bind1;
+				//test nameInput1 
+				name1 = dijit.byId("nameInput1");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("Ben",bind1.data,"bind1.data should be set");
+						doh.is("Ben",bind1.value,"bind1.value should be set");
+					}
+				}
+				//test anameInput1 
+				name1 = dijit.byId("anameInput1");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("Ben",bind1.data,"bind1.data should be set");
+						doh.is("Ben",bind1.value,"bind1.value should be set");
+					}
+				}
+				//test bnameInput1 
+				name1 = dijit.byId("bnameInput1");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("Ben",bind1.data,"bind1.data should be set");
+						doh.is("Ben",bind1.value,"bind1.value should be set");
+					}
+				}
+				//test 9nameInput1 
+				name1 = dijit.byId("9nameInput1");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("Ben",bind1.data,"bind1.data should be set");
+						doh.is("Ben",bind1.value,"bind1.value should be set");
+					}
+				}
+			}
+		}]);
+
+		doh.register("check initial values for Input2s", [{
+			name : "initial",
+			runTest : function() {
+				var name1, bind1;
+				//test nameInput1 
+				name1 = dijit.byId("nameInput2");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("John",bind1.data,"bind1.data should be set");
+						doh.is("John",bind1.value,"bind1.value should be set");
+					}
+				}
+				//test anameInput2 
+				name1 = dijit.byId("anameInput2");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("John",bind1.data,"bind1.data should be set");
+						doh.is("John",bind1.value,"bind1.value should be set");
+					}
+				}
+				//test bnameInput2 
+				name1 = dijit.byId("bnameInput2");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("John",bind1.data,"bind1.data should be set");
+						doh.is("John",bind1.value,"bind1.value should be set");
+					}
+				}
+				//test 9nameInput2 
+				name1 = dijit.byId("9nameInput2");
+				if (name1) {
+					bind1 = name1.get("binding");
+					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
+						doh.is("John",bind1.data,"bind1.data should be set");
+						doh.is("John",bind1.value,"bind1.value should be set");
+					}
+				}
+			}
+		}]);
+
+		doh.run();
+
+		});
+	</script>
+</head>
+
+	<body class="claro" style="background-image: url(../images/master_detail.png)">
+		<div id="wrapper">
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div>
+						Test exprchar. Widget template test uses exprchar of # and others for template:#{this.index} etc. 
+					</div>
+					<br/>
+					<div id="container2"  data-dojo-type="dojox.mvc.tests.test_templatedWidget.myMvcTemplated">    
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+
+</html>
diff --git a/dojox/mvc/tests/1.7/doh/doh_mvc_validation-test-simple.html b/dojox/mvc/tests/1.7/doh/doh_mvc_validation-test-simple.html
new file mode 100644
index 0000000..b15508c
--- /dev/null
+++ b/dojox/mvc/tests/1.7/doh/doh_mvc_validation-test-simple.html
@@ -0,0 +1,134 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH Validation Relevant Test</title>
+		<link rel='stylesheet' href='../../../../../dojo/resources/dojo.css'>
+		<link rel='stylesheet' href='../../../../../dijit/themes/dijit.css'>
+		<link rel='stylesheet' href='../../../../../dijit/themes/claro/claro.css'>
+<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+			var model;
+			require([
+					'dojo/_base/declare',
+					'dojo/parser',
+					'dojox/mvc',
+					'dojox/mvc/StatefulModel',
+					'dojo/_base/lang',
+					"dojo/_base/html",
+					'dijit/form/Button'
+				], function (declare, parser, mvc, StatefulModel, lang, html) {
+					var Model = declare([StatefulModel], {
+						constructor: function (args) {
+							mvc.bindInputs([this.num1, this.num2], lang.hitch(this, '_checkNums'));
+						},
+
+						_checkNums: function () {
+							var num1Val = this.num1.get('value'),
+								num2Val = this.num2.get('value');
+
+							this.num1.set({
+								relevant: num1Val !== num2Val,
+								valid: num1Val <= num2Val
+							});
+
+							this.num2.set({
+								relevant: num1Val !== num2Val,
+								valid: num1Val <= num2Val
+							});
+						}
+					});
+
+					model = new Model({
+						data: {
+							num1: 10,
+							num2: 20
+						}
+					});
+				require([
+					'doh/runner', 'dijit/dijit'
+				], function(){
+				require([
+					'dojo/domReady!'
+					], function(){
+						doh.register("parse", function() {
+							dojo.parser.parse();
+						});
+						// should be able to verify all of the inputs
+						doh.register("check initial values and bindings", [{
+							name : "initial",
+							runTest : function() {
+								num1 = dijit.byId("num1");
+								num2 = dijit.byId("num2");
+								doh.is("10", num1.get('value'),"num1 should be 10");
+								doh.is("20", num2.get('value'),"num2 should be 20");
+								doh.t(num1.isValid(),"num1.isValid() should be true");
+								doh.t(num2.isValid(),"num2.isValid() should be true");
+								doh.f(num2.disabled,"num2.disabled should be false");
+								doh.f(num1.disabled,"num1.disabled should be false");
+							}
+						}]);
+
+						doh.register("update num1 invalid", [{
+							name : "Update-Num1-invalid",
+							runTest : function() {
+								num1 = dijit.byId("num1");
+								num2 = dijit.byId("num2");
+								num1.set("value","30");
+								doh.is("30", num1.get('value'),"num1 should be 30");
+								doh.f(num1.disabled,"num1.disabled should be false");
+								doh.is("20", num2.get('value'),"num2 should be 20");
+								doh.f(num2.isValid(),"num2.isValid() should be false");
+								doh.f(num2.disabled,"num2.disabled should be false");
+								doh.t(dojo.hasClass('widget_num1','dijitNumberTextBoxError'),"num1 should have the dijitNumberTextBoxError class");
+								doh.t(dojo.hasClass('widget_num2','dijitNumberTextBoxError'),"num2 should have the dijitNumberTextBoxError class");
+							}
+						}]);
+
+						doh.register("update num1 disabled2", [{
+							name : "Update-Num1-disabled2",
+							runTest : function() {
+								num1 = dijit.byId("num1");
+								num2 = dijit.byId("num2");
+								num1.set("value","21");
+								num2.set("value","21");
+								doh.is("21", num1.get('value'),"num1 should be 30");
+								doh.is("21", num2.get('value'),"num2 should be 20");
+								doh.t(dijit.byId("num2").disabled,"num2.disabled should be true");
+								doh.t(dijit.byId("num1").disabled,"num1.disabled should be true");
+
+								model.reset();
+							}
+						}]);
+
+						doh.run();
+
+					});
+				});
+		});
+
+		</script>
+</head>
+	<body class="claro">
+		<form method="post">
+			<div>
+				<label for="num1">Number 1</label>
+				<input data-dojo-props="ref:model.num1" data-dojo-type="dijit.form.NumberTextBox" id="num1">
+			</div>
+			<div>
+				<label for="num2">Number 2</label>
+				<input data-dojo-props="ref:model.num2" data-dojo-type="dijit.form.NumberTextBox" id="num2">
+			</div>
+		</form>
+		<br/>Model:
+		<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){doReset()}">Reset</button>
+
+		<script type="text/javascript">
+			function doReset() {
+				model.reset();
+			}
+		</script>
+
+	</body>
+
+</html>
diff --git a/dojox/mvc/tests/helpers.js b/dojox/mvc/tests/1.7/helpers.js
similarity index 100%
copy from dojox/mvc/tests/helpers.js
copy to dojox/mvc/tests/1.7/helpers.js
diff --git a/dojox/mvc/tests/1.7/images/MVC_patterns_in_Dojo.png b/dojox/mvc/tests/1.7/images/MVC_patterns_in_Dojo.png
new file mode 100755
index 0000000..9577e1e
Binary files /dev/null and b/dojox/mvc/tests/1.7/images/MVC_patterns_in_Dojo.png differ
diff --git a/dojox/mvc/tests/1.7/images/background.jpg b/dojox/mvc/tests/1.7/images/background.jpg
new file mode 100755
index 0000000..eee0997
Binary files /dev/null and b/dojox/mvc/tests/1.7/images/background.jpg differ
diff --git a/dojox/mvc/tests/1.7/images/master_detail.png b/dojox/mvc/tests/1.7/images/master_detail.png
new file mode 100755
index 0000000..a680d6e
Binary files /dev/null and b/dojox/mvc/tests/1.7/images/master_detail.png differ
diff --git a/dojox/mvc/tests/1.7/images/validating_form_pattern.png b/dojox/mvc/tests/1.7/images/validating_form_pattern.png
new file mode 100755
index 0000000..7356f87
Binary files /dev/null and b/dojox/mvc/tests/1.7/images/validating_form_pattern.png differ
diff --git a/dojox/mvc/tests/1.7/mobile/demo/demo-async-store.html b/dojox/mvc/tests/1.7/mobile/demo/demo-async-store.html
new file mode 100644
index 0000000..b04c138
--- /dev/null
+++ b/dojox/mvc/tests/1.7/mobile/demo/demo-async-store.html
@@ -0,0 +1,186 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<title>Async Mobile MVC</title>
+		<link rel="stylesheet" type="text/css" href="demo.css"/>		
+		<style>
+		
+		html, body{
+			height: 100%;
+			overflow: hidden;
+			position: relative;
+		}
+		.mblEdgeToEdgeList {
+			background-color: #DBDDE2;
+		}
+		</style>
+
+		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../../dojo/dojo.js"></script>
+		<script type="text/javascript" src="src-async-store.js" charset="utf-8"></script>
+
+	</head>
+	<body>
+	<div id="wholepage" style="display:none">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Mobile MVC Views</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="sdb" dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" transition="slide" moveTo="settings">
+					Simple Data Binding
+				</li>
+				<li id="rdb" dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" transition="slide" moveTo="repeat">
+					Repeat Data Binding
+				</li>
+				<li id="sfg" dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" transition="slide" moveTo="generate">
+					Simple Form Generate
+				</li>
+			</ul>
+		</div>
+
+	<div id="settings" dojoType="dojox.mobile.ScrollableView">
+		<h1 id="home" dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Data Binding Example</h1>
+		<form name="testForm" id="testForm">	
+		<div class="field-title">Ship to - Bill to Address</div>
+			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
+				<div class="field-row">
+					<span>Order #</span>
+					<input id="lastnameInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Order #" ref="'rel:Serial'"/>
+				</div>
+				<div class="field-row">
+					<span>Last</span>
+					<input  id="serialInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Last'"/>
+				</div>
+				<div class="field-row">
+					<span>Email</span>
+					<input  id="emailInput1" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Email'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
+			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
+				<div class="field-row">
+					<span>Street</span>
+					<input  id="streetInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Street" ref="'rel:Street'"/>
+				</div>
+				<div class="field-row">
+					<span>City</span>
+					<input  id="cityInput" dojoType="dojox.mobile.TextBox"
+						placeholder="City" ref="'rel:City'"/>
+				</div>
+				<div class="field-row">
+					<span>State</span>
+					<input  id="stateInput" dojoType="dojox.mobile.TextBox"
+						placeholder="State" ref="'rel:State'"/>
+				</div>
+				<div class="field-row">
+					<span>ZIP Code</span>
+					<input  id="zipInput" dojoType="dojox.mobile.TextBox"
+						placeholder="ZIP Code" ref="'rel:Zip'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
+		</form>
+	</div>
+
+	<div id="repeat" dojoType="dojox.mobile.ScrollableView">
+		<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Repeat Data Binding Example</h1>
+		<form name="repeatTestForm" id="repeatTestForm">	
+		<div class="field-title">Search Results</div>
+			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
+				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
+					<div class="row">			 
+						<input dojoType="dojox.mobile.TextBox"
+							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
+						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
+					</div>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
+				<div id="detailsBanner">Details for selected index:</div>
+					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
+						<div class="field-row">
+							<span>First Name</span>
+							<input  id="firstInput" dojoType="dojox.mobile.TextBox"
+								placeholder="First Name" ref="'rel:First'"/>
+						</div>
+						<div class="field-row">
+							<span>Last Name</span>
+							<input id="lastInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Last Name" ref="'rel:Last'"/>
+						</div>
+						<div class="field-row">
+							<span>Email</span>
+							<input  id="emailInput2" dojoType="dojox.mobile.TextBox"
+								placeholder="Email" ref="'rel:Email'"/>
+						</div>
+						<div class="field-row">
+							<span>Telephone</span>
+							<input  id="telInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Telephone" ref="'rel:Tel'"/>
+						</div>
+					</div>
+				</div>
+			<div class="spacer"></div>
+			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
+			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
+			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
+		</form>
+
+	</div>
+
+	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" back="Home" moveTo="foo">Simple Form Generate Example</h1>
+		<div class="field-title"></div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent" class="generate-maincontent">
+					<div id="outerModelArea">
+						<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Model</h3>
+						<div class="generate-textarea-row">
+							<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+							</textarea>
+						</div>
+						<div class="fieldset">
+							<div class="spacer"></div>
+							<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
+						</div>
+					</div>
+					<div id="viewArea" style="display:none">
+						<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Generated View</h3>
+							<div class="fieldset">
+							<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
+						</div>
+						<div class="fieldset">
+							<div class="spacer"></div>
+							<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/mobile/demo/demo-async.html b/dojox/mvc/tests/1.7/mobile/demo/demo-async.html
new file mode 100644
index 0000000..caa13e0
--- /dev/null
+++ b/dojox/mvc/tests/1.7/mobile/demo/demo-async.html
@@ -0,0 +1,203 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Mobile MVC</title>
+		<link rel="stylesheet" type="text/css" href="demo.css"/>
+		<style>
+		html, body{
+			height: 100%;
+			overflow: hidden;
+		}
+		.mblEdgeToEdgeList {
+			background-color: #DBDDE2;
+		}
+		</style>
+
+	<!--<script type="text/javascript" src="../../../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script> -->
+		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../../dojo/dojo.js"></script>
+		<script type="text/javascript" src="src-async.js" charset="utf-8"></script>
+
+	</head>
+	<body>
+	<div id="wholepage" style="display:none">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo</h1>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="sdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="settings">
+					Simple Data Binding
+				</li>
+				<li id="rdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="repeat">
+					Repeat Data Binding
+				</li>
+				<li id="sfg" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="generate">
+					Generate Simple Form
+				</li>
+			</ul>
+		</div>
+
+	<div id="settings" dojoType="dojox.mobile.ScrollableView">
+		<h1 id="home" dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Data Binding Example</h1>
+		<form name="testForm" id="testForm">	
+		<div class="field-title">Ship to - Bill to Address</div>
+			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
+				<div class="field-row">
+					<span>Order #</span>
+					<input id="lastnameInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Order #" ref="'rel:Serial'"/>
+				</div>
+				<div class="field-row">
+					<span>Last</span>
+					<input  id="serialInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Last'"/>
+				</div>
+				<div class="field-row">
+					<span>Email</span>
+					<input  id="emailInput1" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Email'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
+			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
+				<div class="field-row">
+					<span>Street</span>
+					<input  id="streetInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Street" ref="'rel:Street'"/>
+				</div>
+				<div class="field-row">
+					<span>City</span>
+					<input  id="cityInput" dojoType="dojox.mobile.TextBox"
+						placeholder="City" ref="'rel:City'"/>
+				</div>
+				<div class="field-row">
+					<span>State</span>
+					<input  id="stateInput" dojoType="dojox.mobile.TextBox"
+						placeholder="State" ref="'rel:State'"/>
+				</div>
+				<div class="field-row">
+					<span>ZIP Code</span>
+					<input  id="zipInput" dojoType="dojox.mobile.TextBox"
+						placeholder="ZIP Code" ref="'rel:Zip'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
+		</form>
+	</div>
+
+	<div id="repeat" dojoType="dojox.mobile.ScrollableView">
+		<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Repeat Data Binding Example</h1>
+		<form name="repeatTestForm" id="repeatTestForm">	
+		<div class="field-title">Search Results</div>
+			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
+				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
+					<div class="row">			 
+						<input dojoType="dojox.mobile.TextBox"
+							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
+						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
+					</div>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
+				<div id="detailsBanner">Details for selected index:</div>
+					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
+						<div class="field-row">
+							<span>First Name</span>
+							<input  id="firstInput" dojoType="dojox.mobile.TextBox"
+								placeholder="First Name" ref="'rel:First'"/>
+						</div>
+						<div class="field-row">
+							<span>Last Name</span>
+							<input id="lastInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Last Name" ref="'rel:Last'"/>
+						</div>
+						<div class="field-row">
+							<span>Email</span>
+							<input  id="emailInput2" dojoType="dojox.mobile.TextBox"
+								placeholder="Email" ref="'rel:Email'"/>
+						</div>
+						<div class="field-row">
+							<span>Telephone</span>
+							<input  id="telInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Telephone" ref="'rel:Tel'"/>
+						</div>
+					</div>
+				</div>
+			<div class="spacer"></div>
+			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
+			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
+			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
+		</form>
+
+	</div>
+
+	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="foo">Simple Form Generate Example</h1>
+		<div class="field-title"></div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent" class="generate-maincontent">
+					<div id="outerModelArea">
+						<div id="generateModel">Model</div>
+						<div class="generate-textarea-row">
+							<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+							</textarea>
+						</div>
+						<div class="fieldset">
+							<div class="spacer"></div>
+							<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
+						</div>
+					</div>
+					<div id="viewArea" style="display:none">
+						<div id="generateView">Generated View</div>
+							<div class="fieldset">
+							<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
+						</div>
+						<div class="fieldset">
+							<div class="spacer"></div>
+							<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
+						</div>
+					</div>
+				</div>
+			</div>
+					<textarea style="display:none" data-dojo-type="dojox.mobile.TextArea" id="modelArea2">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Middle": "J",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+					</textarea>
+			
+		</div>
+	</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/mobile/demo/demo-sync.html b/dojox/mvc/tests/1.7/mobile/demo/demo-sync.html
new file mode 100644
index 0000000..5c80e74
--- /dev/null
+++ b/dojox/mvc/tests/1.7/mobile/demo/demo-sync.html
@@ -0,0 +1,201 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Mobile MVC</title>
+		<link rel="stylesheet" type="text/css" href="demo.css"/>
+		<style>
+		html, body{
+			height: 100%;
+			overflow: hidden;
+		}
+		.mblEdgeToEdgeList {
+			background-color: #DBDDE2;
+		}		
+		</style>
+
+		<script type="text/javascript" src="../../../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
+		<!-- <script type="text/javascript" src="../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>	 -->	 
+		<script type="text/javascript" src="src-sync.js" charset="utf-8"></script>
+	</head>
+	<body>
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo</h1>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="sdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="settings">
+					Simple Data Binding
+				</li>
+				<li id="rdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="repeat">
+					Repeat Data Binding
+				</li>
+				<li id="sfg" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="generate">
+					Generate Simple Form
+				</li>
+			</ul>
+		</div>
+
+	<div id="settings" dojoType="dojox.mobile.ScrollableView">
+		<h1 id="home" dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Data Binding Example</h1>
+		<form name="testForm" id="testForm">	
+		<div class="field-title">Ship to - Bill to Address</div>
+			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
+				<div class="field-row">
+					<span>Order #</span>
+					<input id="lastnameInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Order #" ref="'rel:Serial'"/>
+				</div>
+				<div class="field-row">
+					<span>Last</span>
+					<input  id="serialInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Last'"/>
+				</div>
+				<div class="field-row">
+					<span>Email</span>
+					<input  id="emailInput1" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Email'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
+			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
+				<div class="field-row">
+					<span>Street</span>
+					<input  id="streetInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Street" ref="'rel:Street'"/>
+				</div>
+				<div class="field-row">
+					<span>City</span>
+					<input  id="cityInput" dojoType="dojox.mobile.TextBox"
+						placeholder="City" ref="'rel:City'"/>
+				</div>
+				<div class="field-row">
+					<span>State</span>
+					<input  id="stateInput" dojoType="dojox.mobile.TextBox"
+						placeholder="State" ref="'rel:State'"/>
+				</div>
+				<div class="field-row">
+					<span>ZIP Code</span>
+					<input  id="zipInput" dojoType="dojox.mobile.TextBox"
+						placeholder="ZIP Code" ref="'rel:Zip'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
+		</form>
+	</div>
+
+	<div id="repeat" dojoType="dojox.mobile.ScrollableView">
+		<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Repeat Data Binding Example</h1>
+		<form name="repeatTestForm" id="repeatTestForm">	
+		<div class="field-title">Search Results</div>
+			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
+				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
+					<div class="row">			 
+						<input dojoType="dojox.mobile.TextBox"
+							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
+						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
+					</div>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
+				<div id="detailsBanner">Details for selected index:</div>
+					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
+						<div class="field-row">
+							<span>First Name</span>
+							<input  id="firstInput" dojoType="dojox.mobile.TextBox"
+								placeholder="First Name" ref="'rel:First'"/>
+						</div>
+						<div class="field-row">
+							<span>Last Name</span>
+							<input id="lastInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Last Name" ref="'rel:Last'"/>
+						</div>
+						<div class="field-row">
+							<span>Email</span>
+							<input  id="emailInput2" dojoType="dojox.mobile.TextBox"
+								placeholder="Email" ref="'rel:Email'"/>
+						</div>
+						<div class="field-row">
+							<span>Telephone</span>
+							<input  id="telInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Telephone" ref="'rel:Tel'"/>
+						</div>
+					</div>
+				</div>
+			<div class="spacer"></div>
+			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
+			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
+			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
+		</form>
+	
+	</div>
+
+	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="foo">Simple Form Generate Example</h1>
+		<div class="field-title"></div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent" class="generate-maincontent">
+					<div id="outerModelArea">
+						<div id="generateModel">Model</div>
+						<div class="generate-textarea-row">
+							<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+							</textarea>
+						</div>
+						<div class="fieldset">
+							<div class="spacer"></div>
+							<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
+						</div>
+					</div>
+					<div id="viewArea" style="display:none">
+						<div id="generateView">Generated View</div>
+							<div class="fieldset">
+							<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
+						</div>
+						<div class="fieldset">
+							<div class="spacer"></div>
+							<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
+						</div>
+					</div>
+				</div>
+			</div>
+					<textarea style="display:none" data-dojo-type="dojox.mobile.TextArea" id="modelArea2">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Middle": "J",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+					</textarea>
+			
+		  </div>
+		
+	</body>
+</html>
diff --git a/dojox/mvc/tests/mobile/demo/demo.css b/dojox/mvc/tests/1.7/mobile/demo/demo.css
similarity index 100%
copy from dojox/mvc/tests/mobile/demo/demo.css
copy to dojox/mvc/tests/1.7/mobile/demo/demo.css
diff --git a/dojox/mvc/tests/1.7/mobile/demo/demo.html b/dojox/mvc/tests/1.7/mobile/demo/demo.html
new file mode 100755
index 0000000..bbee70c
--- /dev/null
+++ b/dojox/mvc/tests/1.7/mobile/demo/demo.html
@@ -0,0 +1,203 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Mobile MVC</title>
+		<link rel="stylesheet" type="text/css" href="demo.css"/>
+		<style>
+		html, body{
+			height: 100%;
+			overflow: hidden;
+		}
+		.mblEdgeToEdgeList {
+			background-color: #DBDDE2;
+		}
+		</style>
+
+	<!--<script type="text/javascript" src="../../../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script> -->
+		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../../dojo/dojo.js"></script>
+		<script type="text/javascript" src="src.js" charset="utf-8"></script>
+
+	</head>
+	<body>
+	<div id="wholepage" style="display:none">
+		<div id="foo" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo</h1>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="sdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="settings">
+					Simple Data Binding
+				</li>
+				<li id="rdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="repeat">
+					Repeat Data Binding
+				</li>
+				<li id="sfg" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="generate">
+					Generate Simple Form
+				</li>
+			</ul>
+		</div>
+
+	<div id="settings" dojoType="dojox.mobile.ScrollableView">
+		<h1 id="home" dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Data Binding Example</h1>
+		<form name="testForm" id="testForm">	
+		<div class="field-title">Ship to - Bill to Address</div>
+			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
+				<div class="field-row">
+					<span>Order #</span>
+					<input id="lastnameInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Order #" ref="'rel:Serial'"/>
+				</div>
+				<div class="field-row">
+					<span>Last</span>
+					<input  id="serialInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Last'"/>
+				</div>
+				<div class="field-row">
+					<span>Email</span>
+					<input  id="emailInput1" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Email'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
+			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
+				<div class="field-row">
+					<span>Street</span>
+					<input  id="streetInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Street" ref="'rel:Street'"/>
+				</div>
+				<div class="field-row">
+					<span>City</span>
+					<input  id="cityInput" dojoType="dojox.mobile.TextBox"
+						placeholder="City" ref="'rel:City'"/>
+				</div>
+				<div class="field-row">
+					<span>State</span>
+					<input  id="stateInput" dojoType="dojox.mobile.TextBox"
+						placeholder="State" ref="'rel:State'"/>
+				</div>
+				<div class="field-row">
+					<span>ZIP Code</span>
+					<input  id="zipInput" dojoType="dojox.mobile.TextBox"
+						placeholder="ZIP Code" ref="'rel:Zip'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
+		</form>
+	</div>
+
+	<div id="repeat" dojoType="dojox.mobile.ScrollableView">
+		<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Repeat Data Binding Example</h1>
+		<form name="repeatTestForm" id="repeatTestForm">	
+		<div class="field-title">Search Results</div>
+			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
+				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
+					<div class="row">			 
+						<input dojoType="dojox.mobile.TextBox"
+							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
+						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
+					</div>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
+				<div id="detailsBanner">Details for selected index:</div>
+					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
+						<div class="field-row">
+							<span>First Name</span>
+							<input  id="firstInput" dojoType="dojox.mobile.TextBox"
+								placeholder="First Name" ref="'rel:First'"/>
+						</div>
+						<div class="field-row">
+							<span>Last Name</span>
+							<input id="lastInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Last Name" ref="'rel:Last'"/>
+						</div>
+						<div class="field-row">
+							<span>Email</span>
+							<input  id="emailInput2" dojoType="dojox.mobile.TextBox"
+								placeholder="Email" ref="'rel:Email'"/>
+						</div>
+						<div class="field-row">
+							<span>Telephone</span>
+							<input  id="telInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Telephone" ref="'rel:Tel'"/>
+						</div>
+					</div>
+				</div>
+			<div class="spacer"></div>
+			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
+			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
+			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
+		</form>
+
+	</div>
+
+	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="foo">Simple Form Generate Example</h1>
+		<div class="field-title"></div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent" class="generate-maincontent">
+					<div id="outerModelArea">
+						<div id="generateModel">Model</div>
+						<div class="generate-textarea-row">
+							<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+							</textarea>
+						</div>
+						<div class="fieldset">
+							<div class="spacer"></div>
+							<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
+						</div>
+					</div>
+					<div id="viewArea" style="display:none">
+						<div id="generateView">Generated View</div>
+							<div class="fieldset">
+							<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
+						</div>
+						<div class="fieldset">
+							<div class="spacer"></div>
+							<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
+						</div>
+					</div>
+				</div>
+			</div>
+					<textarea style="display:none" data-dojo-type="dojox.mobile.TextArea" id="modelArea2">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Middle": "J",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+					</textarea>
+			
+		</div>
+	</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/mobile/demo/demo.profile.js b/dojox/mvc/tests/1.7/mobile/demo/demo.profile.js
similarity index 100%
rename from dojox/mvc/tests/mobile/demo/demo.profile.js
rename to dojox/mvc/tests/1.7/mobile/demo/demo.profile.js
diff --git a/dojox/mvc/tests/mobile/demo/generateView.html b/dojox/mvc/tests/1.7/mobile/demo/generateView.html
similarity index 100%
rename from dojox/mvc/tests/mobile/demo/generateView.html
rename to dojox/mvc/tests/1.7/mobile/demo/generateView.html
diff --git a/dojox/mvc/tests/1.7/mobile/demo/iPad-Demo.html b/dojox/mvc/tests/1.7/mobile/demo/iPad-Demo.html
new file mode 100644
index 0000000..299ce2f
--- /dev/null
+++ b/dojox/mvc/tests/1.7/mobile/demo/iPad-Demo.html
@@ -0,0 +1,213 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Mobile MVC on iPad</title>
+		<link rel="stylesheet" type="text/css" href="demo.css"/>		
+		<style>
+		@import "../../../../mobile/themes/iphone/base.css";
+		@import "../../../../mobile/themes/iphone/ipad.css";
+		@import "../../../../mobile/themes/common/FixedSplitter.css";
+		html, body{
+			height: 100%;
+			overflow: hidden;
+			position: relative;
+		}
+		.mblEdgeToEdgeList {
+			background-color: #DBDDE2;
+		}
+		</style>
+	<!--<script type="text/javascript" src="../../../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script> -->
+		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../../dojo/dojo.js"></script>
+		<script type="text/javascript" src="src-async-store.js" charset="utf-8"></script>
+
+	</head>
+	<body>
+	<div id="wholepage" style="display:none">	
+		<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
+			<div dojoType="dojox.mobile.FixedSplitterPane" style="width:300px;border-right:1px solid black;">
+				<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
+					<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo for iPad</h1>
+					<ul dojoType="dojox.mobile.EdgeToEdgeList" transition="flip" stateful="true">
+					<li id="sdb" dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" transition="slide" moveTo="settings"  selected="true">
+						Simple Data Binding
+					</li>
+					<li id="rdb" dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" transition="slide" moveTo="repeat">
+						Repeat Data Binding
+					</li>
+					<li id="sfg" dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" transition="slide" moveTo="generate">
+						Simple Form Generate
+					</li>
+				</ul>
+			</div>
+			</div>
+
+			<div dojoType="dojox.mobile.FixedSplitterPane">
+
+
+	<div id="settings" dojoType="dojox.mobile.ScrollableView"  selected="true">
+		<h1 id="home" dojoType="dojox.mobile.Heading" fixed="top">Data Binding Example</h1>
+		<form name="testForm" id="testForm">	
+		<div class="field-title">Ship to - Bill to Address</div>
+			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
+				<div class="field-row">
+					<span>Order #</span>
+					<input type=text id="lastnameInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Order #" ref="'rel:Serial'"/>
+				</div>
+				<div class="field-row">
+					<span>Last</span>
+					<input type=text id="serialInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Last'"/>
+				</div>
+				<div class="field-row">
+					<span>Email</span>
+					<input type=text id="emailInput1" dojoType="dojox.mobile.TextBox"
+						placeholder="Last" ref="'rel:Email'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
+			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
+			<br/>
+			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
+				<div class="field-row">
+					<span>Street</span>
+					<input type=text id="streetInput" dojoType="dojox.mobile.TextBox"
+						placeholder="Street" ref="'rel:Street'"/>
+				</div>
+				<div class="field-row">
+					<span>City</span>
+					<input type=text id="cityInput" dojoType="dojox.mobile.TextBox"
+						placeholder="City" ref="'rel:City'"/>
+				</div>
+				<div class="field-row">
+					<span>State</span>
+					<input type=text id="stateInput" dojoType="dojox.mobile.TextBox"
+						placeholder="State" ref="'rel:State'"/>
+				</div>
+				<div class="field-row">
+					<span>ZIP Code</span>
+					<input type=text id="zipInput" dojoType="dojox.mobile.TextBox"
+						placeholder="ZIP Code" ref="'rel:Zip'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
+		</form>
+	</div>
+
+
+				<div id="repeat" dojoType="dojox.mobile.ScrollableView">
+		<h1 dojoType="dojox.mobile.Heading" fixed="top">Repeat Data Binding Example</h1>
+		<form name="repeatTestForm" id="repeatTestForm">	
+		<div class="field-title">Search Results</div>
+			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
+				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
+					<div class="row">			 
+						<input dojoType="dojox.mobile.TextBox"
+							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
+						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
+					</div>
+				</div>
+			</div>
+			<div class="spacer"></div>
+			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
+				<div id="detailsBanner">Details for selected index:</div>
+					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
+						<div class="field-row">
+							<span>First Name</span>
+							<input type=text id="firstInput" dojoType="dojox.mobile.TextBox"
+								placeholder="First Name" ref="'rel:First'"/>
+						</div>
+						<div class="field-row">
+							<span>Last Name</span>
+							<input type=text id="lastInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Last Name" ref="'rel:Last'"/>
+						</div>
+						<div class="field-row">
+							<span>Email</span>
+							<input type=text id="emailInput2" dojoType="dojox.mobile.TextBox"
+								placeholder="Email" ref="'rel:Email'"/>
+						</div>
+						<div class="field-row">
+							<span>Telephone</span>
+							<input type=text id="telInput" dojoType="dojox.mobile.TextBox"
+								placeholder="Telephone" ref="'rel:Tel'"/>
+						</div>
+					</div>
+				</div>		   
+			<div class="spacer"></div>
+			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
+			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
+			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
+			
+	</div>
+
+	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView"	 style="width: 100%;">
+	<h1 data-dojo-type="dojox.mobile.Heading" fixed="top">Simple Form Generate Example</h1>
+	<div class="field-title"></div>
+		<div id="main">
+		  <div id="leftNav">
+		  </div>
+		  <div id="mainContent" class="generate-maincontent">
+			<div id="outerModelArea">
+				<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Model</h3>
+				<div class="generate-textarea-row">
+					<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+					</textarea>
+				</div>
+				<div class="fieldset">
+					<div class="spacer"></div>
+					<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
+				</div>
+			</div>
+			<div id="viewArea" style="display:none">
+				<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Generated View</h3>
+				<div class="fieldset">
+					<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
+				</div>
+				<div class="fieldset">
+					<div class="spacer"></div>
+					<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
+				</div>
+			</div>
+					<textarea style="display:none" data-dojo-type="dojox.mobile.TextArea" id="modelArea2">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Middle": "J",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+					</textarea>
+			
+		  			</div>
+				</div>
+			</div>
+		</div></div></div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/mobile/demo/images/i-icon-1.png b/dojox/mvc/tests/1.7/mobile/demo/images/i-icon-1.png
similarity index 100%
rename from dojox/mvc/tests/mobile/demo/images/i-icon-1.png
rename to dojox/mvc/tests/1.7/mobile/demo/images/i-icon-1.png
diff --git a/dojox/mvc/tests/mobile/demo/images/i-icon-2.png b/dojox/mvc/tests/1.7/mobile/demo/images/i-icon-2.png
similarity index 100%
rename from dojox/mvc/tests/mobile/demo/images/i-icon-2.png
rename to dojox/mvc/tests/1.7/mobile/demo/images/i-icon-2.png
diff --git a/dojox/mvc/tests/mobile/demo/images/i-icon-3.png b/dojox/mvc/tests/1.7/mobile/demo/images/i-icon-3.png
similarity index 100%
rename from dojox/mvc/tests/mobile/demo/images/i-icon-3.png
rename to dojox/mvc/tests/1.7/mobile/demo/images/i-icon-3.png
diff --git a/dojox/mvc/tests/mobile/demo/images/mvc.png b/dojox/mvc/tests/1.7/mobile/demo/images/mvc.png
similarity index 100%
rename from dojox/mvc/tests/mobile/demo/images/mvc.png
rename to dojox/mvc/tests/1.7/mobile/demo/images/mvc.png
diff --git a/dojox/mvc/tests/mobile/demo/repeatDataBinding.html b/dojox/mvc/tests/1.7/mobile/demo/repeatDataBinding.html
similarity index 100%
rename from dojox/mvc/tests/mobile/demo/repeatDataBinding.html
rename to dojox/mvc/tests/1.7/mobile/demo/repeatDataBinding.html
diff --git a/dojox/mvc/tests/mobile/demo/shipToBillTo.html b/dojox/mvc/tests/1.7/mobile/demo/shipToBillTo.html
similarity index 100%
rename from dojox/mvc/tests/mobile/demo/shipToBillTo.html
rename to dojox/mvc/tests/1.7/mobile/demo/shipToBillTo.html
diff --git a/dojox/mvc/tests/mobile/demo/src-async-store.js b/dojox/mvc/tests/1.7/mobile/demo/src-async-store.js
similarity index 100%
rename from dojox/mvc/tests/mobile/demo/src-async-store.js
rename to dojox/mvc/tests/1.7/mobile/demo/src-async-store.js
diff --git a/dojox/mvc/tests/mobile/demo/src-async.js b/dojox/mvc/tests/1.7/mobile/demo/src-async.js
similarity index 100%
rename from dojox/mvc/tests/mobile/demo/src-async.js
rename to dojox/mvc/tests/1.7/mobile/demo/src-async.js
diff --git a/dojox/mvc/tests/mobile/demo/src-sync.js b/dojox/mvc/tests/1.7/mobile/demo/src-sync.js
similarity index 100%
rename from dojox/mvc/tests/mobile/demo/src-sync.js
rename to dojox/mvc/tests/1.7/mobile/demo/src-sync.js
diff --git a/dojox/mvc/tests/mobile/demo/src.js b/dojox/mvc/tests/1.7/mobile/demo/src.js
similarity index 100%
copy from dojox/mvc/tests/mobile/demo/src.js
copy to dojox/mvc/tests/1.7/mobile/demo/src.js
diff --git a/dojox/mvc/tests/1.7/mobile/test_Android-repeat-data-store.html b/dojox/mvc/tests/1.7/mobile/test_Android-repeat-data-store.html
new file mode 100644
index 0000000..0a93ba0
--- /dev/null
+++ b/dojox/mvc/tests/1.7/mobile/test_Android-repeat-data-store.html
@@ -0,0 +1,104 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Android Repeat Data Example</title>
+		<link href="../../../../../dojox/mobile/themes/android/android.css" rel="stylesheet"/>
+		<link href="../css/android-format.css" rel="stylesheet"/>
+
+	<!--  use below for iPhone theme  
+		<link href="../../../../../dojox/mobile/themes/iphone/iphone.css" rel="stylesheet"></link>
+		<link href="../css/iphone-format.css" rel="stylesheet"></link>
+	-->
+
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: false, isDebug: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); 
+			dojo.require("dojox.mobile.parser"); // dojox.mobile.parser did not work
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.TextBox");
+			dojo.require("dojox.mobile.Button");
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Group");
+			dojo.require("dojox.mvc.Repeat");
+			dojo.require("dojo.data.ItemFileWriteStore");
+			dojo.require("dojo.store.DataStore");
+			
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+			var model, selectedIndex = 0, nextIndexToAdd, theModelPromise;
+
+			function setup() {
+				var writeStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests._data", "mvcRepeatData.json")});
+				var modelPromise = dojox.mvc.newStatefulModel({store: new dojo.store.DataStore({store: writeStore}), query:{"Location" : "CA"}}); // example of using a query parm for Location 
+				modelPromise.then(function(results){ 
+					model = results;
+					nextIndexToAdd = model.data.length;
+					//dojo.parser.parse();
+					dojox.mobile.parser.parse();
+				});
+			};
+
+			dojo.ready(setup);
+		</script>
+	</head>
+	<body>
+<h1 dojoType="dojox.mobile.Heading">Android Repeat Data Binding Example.</h1>
+		<div >Search Results:</div>
+		<div dojoType="dojox.mvc.Repeat" class="row" ref="model">
+			<div class="row" dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
+				<input dojoType="dojox.mobile.TextBox"
+					id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
+				<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
+			</div>
+		</div>
+		<div class="spacer"></div>
+		<div dojoType="dojox.mvc.Group" ref="model">
+			<div id="detailsBanner">Details for selected index:</div>
+				<div id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
+					<div><label for="firstInput">First Name:</label></div>
+					<div><input id="firstInput" dojoType="dojox.mobile.TextBox" ref="'rel:First'" placeHolder="First Name"/></div>
+					<div><label for="lastInput">Last Name:</label></div>
+					<div><input id="lastInput" dojoType="dojox.mobile.TextBox" ref="'rel:Last'" placeHolder="Last Name"/></div>
+					<div><label for="emailInput">Email:</label></div>
+					<div><input id="emailInput" dojoType="dojox.mobile.TextBox" ref="'rel:Email'" placeHolder="Email"/></div>
+					<div><label for="telInput">Telephone:</label></div>
+					<div><input id="telInput" dojoType="dojox.mobile.TextBox" ref="'rel:Tel'" placeHolder="Telephone"/></div>
+					<div><label for="faxInput">Fax:</label></div>
+					<div><input id="faxInput" dojoType="dojox.mobile.TextBox" ref="'rel:Fax'" placeHolder="Fax"/></div>
+				</div>
+			</div>		   
+		<div class="spacer"></div>
+		<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
+		<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(model[selectedIndex].toPlainObject());model[selectedIndex].commit()">Save</button>
+		<button id="reset" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
+		<script type="text/javascript">
+			function setDetailsContext(index){
+				selectedIndex = index;
+				var groupRoot = dijit.byId("detailsGroup");
+				groupRoot.set("ref", index);
+			}
+
+			function insertResult(index){
+				if (model[index-1].First.value !== ""){ // TODO: figure out why we are getting called twice for each click
+					var insert = dojox.mvc.newStatefulModel({ "data" : {
+						"First"	  : "",
+						"Last"	  : "",
+						"Location": "CA",
+						"Office"  : "",
+						"Email"	  : "",
+						"Tel"	  : "",
+						"Fax"	  : ""} 
+					});
+					model.add(index, insert);
+					setDetailsContext(index);
+					nextIndexToAdd++;
+				}else{
+					setDetailsContext(index-1);					
+				}
+			}
+		</script>				 
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/mobile/test_iPhone-shipto-billto.html b/dojox/mvc/tests/1.7/mobile/test_iPhone-shipto-billto.html
new file mode 100755
index 0000000..6abddbe
--- /dev/null
+++ b/dojox/mvc/tests/1.7/mobile/test_iPhone-shipto-billto.html
@@ -0,0 +1,121 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>iPhone Shipto-Billto</title>
+		<link href="../../../../../dojox/mobile/themes/iphone/iphone.css" rel="stylesheet"/>
+		<link href="../css/iphone-format.css" rel="stylesheet"/>
+
+	<!-- use links below for android theme		  
+		<link href="../../../../../dojox/mobile/themes/android/android.css" rel="stylesheet">
+		<link href="../css/android-format.css" rel="stylesheet">
+	-->
+	
+		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); 
+			dojo.require("dojox.mobile.parser"); 
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.TextBox");
+			dojo.require("dojox.mobile.Button");
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Group");
+			dojo.require("dojox.mvc.Repeat");
+			
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+			// Initial data
+			var names = {
+				"Serial" : "360324",
+				"First"	 : "John",
+				"Last"	 : "Doe",
+				"Email"	 : "jdoe at us.ibm.com",
+				"ShipTo" : {
+					"Street" : "123 Valley Rd",
+					"City"	 : "Katonah",
+					"State"	 : "NY",
+					"Zip"	 : "10536"
+				},
+				"BillTo" : {
+					"Street" : "17 Skyline Dr",
+					"City"	 : "Hawthorne",
+					"State"	 : "NY",
+					"Zip"	 : "10532"
+				}
+			};
+
+			var model = dojox.mvc.newStatefulModel({ data : names });
+			
+		</script>
+	</head>
+	<body>
+		<h1 data-dojo-type="dojox.mobile.Heading">iPhone Data Binding Ex.</h1>
+		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref:'model'">
+			<div>
+				<label for="serialInput">Order #:</label>
+			</div>
+			<div>
+				<input	class="cell" id="serialInput" data-dojo-type="dojox.mobile.TextBox"
+						data-dojo-props="ref:'rel:Serial'"/>
+			</div>
+			<div>
+				<label for="lastnameInput">Last:</label>
+			</div>
+			<div>
+				<input id="lastnameInput" data-dojo-type="dojox.mobile.TextBox"
+					   data-dojo-props="ref:'rel:Last'"/>
+			</div>
+			<div>
+				<label for="emailInput">Email:</label>
+			</div>
+			<div>
+				<input id="emailInput" data-dojo-type="dojox.mobile.TextBox"
+					   data-dojo-props="ref:'rel:Email'"/>
+			</div>
+		</div>
+		<div class="spacer"></div>
+		<button id="shipto" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
+		<button id="billto" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
+		<br/>
+		<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref:model.ShipTo">
+			<div>
+				<label for="streetInput">Street:</label>
+			</div>
+			<div>
+				<input	id="streetInput" data-dojo-type="dojox.mobile.TextBox"
+						placeHolder="Street" data-dojo-props="ref:'rel:Street'"/>
+			</div>
+			<div>
+				<label for="cityInput">City:</label>
+			</div>
+			<div>
+				<input id="cityInput" data-dojo-type="dojox.mobile.TextBox"
+					   placeHolder="City" data-dojo-props="ref:'rel:City'"/>
+			</div>
+			<div>
+				<label for="stateInput">State:</label>
+			</div>
+			<div>
+				<input id="stateInput" data-dojo-type="dojox.mobile.TextBox"
+					   placeHolder="State" data-dojo-props="ref:'rel:State'"/>
+			</div>
+			<div>
+				<label for="zipInput">ZIP Code:</label>
+			</div>
+			<div>
+				<input id="zipInput" data-dojo-type="dojox.mobile.TextBox"
+					   placeHolder="ZIP Code" data-dojo-props="ref:'rel:Zip'"/>
+			</div>
+		</div>
+		<div class="spacer"></div>
+		<button id="reset" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
+		<script type="text/javascript">
+			function setRef(id, addrRef) {
+				var widget = dijit.byId(id);
+				widget.set("ref", addrRef);
+			}
+		</script>				 
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/mobile/test_mobile-list-multiple-sel-mvc.html b/dojox/mvc/tests/1.7/mobile/test_mobile-list-multiple-sel-mvc.html
new file mode 100644
index 0000000..f200933
--- /dev/null
+++ b/dojox/mvc/tests/1.7/mobile/test_mobile-list-multiple-sel-mvc.html
@@ -0,0 +1,210 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>MVC Repeat with Selectable RoundRectDataList - Multiple Select</title>
+
+	<script type="text/javascript" src="./../../../dojox/mobile/deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true, parseOnLoad: false"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox",
+			"dojox/mvc",
+			//"dojox/mobile/parser",
+			"dojo/parser",
+			"dojo/store/Memory",
+			"dojo/ready",
+			"dojox/mvc/_patches",
+			"dojox/mvc/at",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat",
+			"dojox/mvc/Output",
+			"dojox/mobile",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/Button",
+			"dojox/mobile/TextArea",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/CheckBox",
+			"dojox/mobile/ViewController",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/EdgeToEdgeList",
+			"dojox/mobile/EdgeToEdgeCategory",
+			"dojox/mobile/deviceTheme",
+			"dojox/mobile/RoundRectCategory",
+			"dojox/mobile/Heading"
+		], function(dojox, mvc, parser, MemoryStore, ready){
+
+			var search_results_init1 =
+			[{
+				"Query" : "Engineers1",
+				"Results" : [
+					{
+						"First"	  : "Anne1",
+						"Last"	  : "Ackerman1",
+						"Checked" : true
+					},
+					{
+						"First"	  : "Ben1",
+						"Last"	  : "Beckham1",
+						"Checked" : false
+					},
+					{
+						"First"	  : "Chad1",
+						"Last"	  : "Chapman1",
+						"Checked" : false
+					}
+				]
+			}];
+
+			var search_results_init2 =
+				[{
+					"Query" : "Engineers1",
+					"Results" : [
+						{
+							"First"	  : "Anne2",
+							"Last"	  : "Ackerman2",
+							"Checked" : false
+						},
+						{
+							"First"	  : "Ben2",
+							"Last"	  : "Beckham2",
+							"Checked" : true
+						},
+						{
+							"First"	  : "Chad2",
+							"Last"	  : "Chapman2",
+							"Checked" : false
+						}
+					]
+				}];
+			var memStore1 = new MemoryStore({data : search_results_init1});
+			model1 = mvc.newStatefulModel({ store : memStore1 })[0];
+
+			var memStore2 = new MemoryStore({data : search_results_init2});
+			model2 = mvc.newStatefulModel({ store : memStore2 })[0];
+			
+			// when "dojo/ready" is ready call parser.parse (if not doing parseOnLoad)
+			ready(function(){
+				parser.parse();
+			});
+
+
+
+		});
+
+		// called to reset the model for each of the repeats
+		function swapToModel1() {
+			dijit.byId('repeatId1').set('ref',model1.Results); 
+			dijit.byId('repeatId2').set('ref',model1.Results); 
+			dijit.byId('repeatid2arem').set('ref',model1.Results);
+			dijit.byId('repeatid2aremg').set('ref',model1.Results);
+			dijit.byId('repeatid2a').set('ref',model1.Results);			
+		};
+
+		function swapToModel2() {
+			dijit.byId('repeatId1').set('ref',model2.Results); 
+			dijit.byId('repeatId2').set('ref',model2.Results); 
+			dijit.byId('repeatid2arem').set('ref',model2.Results);
+			dijit.byId('repeatid2aremg').set('ref',model2.Results);
+			dijit.byId('repeatid2a').set('ref',model2.Results);			
+		};
+		
+		
+	</script>
+</head>
+<body style="visibility:hidden;">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h2>MVC Repeat with Selectable RoundRectList - Multiple Select</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+				<h4>Here is one using dojox.mvc.Repeat as a mixin with no Group and dojo.parser instead of dojox.mobile.parser it is all good using mixin.</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatId1" select="multiple" 
+					data-dojo-mixins="dojox.mvc.Repeat" data-dojo-props="exprchar:'#', ref:'model1.Results'">
+							<li id="configure_itemmix1#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at('rel:#{this.index}.First', 'value'),
+												checked: dojox.mvc.at('rel:#{this.index}.Checked', 'value')">
+							</li>
+				</ul>
+
+				<h4>Here is one using MVC using Repeat no Group, with removeRepeatNode set true it is all good if Repeat sets select and onCheckStateChanged.</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatparentidrem" select="multiple">
+					<div data-dojo-type="dojox.mvc.Repeat" id="repeatid2arem" data-dojo-props="exprchar:'#', ref:'model1.Results', removeRepeatNode:true">
+							<li id="configure_itemrem#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at('rel:#{this.index}.First', 'value'),
+												checked: dojox.mvc.at('rel:#{this.index}.Checked', 'value')">
+							</li>
+					</div>
+				</ul>
+
+				<h4>Here is one using MVC using Repeat with a Group, with removeRepeatNode set true it is all good if Repeat sets select and onCheckStateChanged.</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatparentidremg" select="multiple">
+					<div data-dojo-type="dojox.mvc.Repeat" id="repeatid2aremg" data-dojo-props="exprchar:'#', ref:'model1.Results', removeRepeatNode:true">
+						<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '#{this.index}'">
+							<li id="configure_itemremg#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at('rel:First', 'value'),
+												checked: dojox.mvc.at('rel:Checked', 'value')">
+							</li>
+						</div>
+					</div>
+				</ul>
+  
+				<h4>You can update the label or checked from here to update the model.</h4>
+				   <div id="repeatparentid2">
+						<div id="repeatId2" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref:'model1.Results'">
+								<input class="cell" data-dojo-type="dojox.mobile.TextBox" id="nameInput2${this.index}" 
+										data-dojo-props="value: dojox.mvc.at('rel:${this.index}.First', 'value')"/>
+		  						<label data-dojo-type="dojox.mvc.Output" for="CBInput${this.index}" 
+										data-dojo-props="value: dojox.mvc.at('rel:${this.index}.First', 'value')"/></label>
+								<input class="cell" type="checkbox" data-dojo-type="dojox.mobile.CheckBox" id="CBInput${this.index}" 
+										data-dojo-props="checked: dojox.mvc.at('rel:${this.index}.Checked', 'value')"/>
+						</div>
+					</div>
+
+					<br/>Model:
+					<button type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){swapToModel2();}">Swap Model2</button> 
+					<button type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){swapToModel1();}">Swap Model1</button> 					
+					<button id="reset" type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){model1.reset();model2.reset();}">Reset all</button>
+				
+				<h4>Here is one using MVC using Repeat no Group, using useParent it has style and 
+				selection problems because of the Group nodes, updates to the model are reflected here, looks good, but has selection problems...
+				Also the Swap model buttons do not work with this one.
+				</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatparentid" select="multiple">
+					<div data-dojo-type="dojox.mvc.Repeat" id="repeatid2a" data-dojo-props="exprchar:'#', ref:'model1.Results', useParent:'repeatparentid'">
+							<li id="configure_item#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at('model1.Results.#{this.index}.First', 'value'),
+												checked: dojox.mvc.at('model1.Results.#{this.index}.Checked', 'value')">
+							</li>
+					</div>
+				</ul>
+
+		<!--
+					<h4>Here is a normal RoundRectList for comparison Item one should be selected</h4>
+					<ul id="list1a" data-dojo-type="dojox.mobile.RoundRectList" select="multiple" >
+							<li id="configure_itemXX0" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at(model1.Results[0].First, 'value'),
+												checked: dojox.mvc.at(model1.Results[0].Checked, 'value')">
+							</li>
+							<li id="configure_itemXX1" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at(model1.Results[1].First, 'value'),
+												checked: dojox.mvc.at(model1.Results[1].Checked, 'value')">
+							</li>
+					</ul>	
+		-->	
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/mobile/test_mobile-list-single-sel-mvc.html b/dojox/mvc/tests/1.7/mobile/test_mobile-list-single-sel-mvc.html
new file mode 100644
index 0000000..2cba302
--- /dev/null
+++ b/dojox/mvc/tests/1.7/mobile/test_mobile-list-single-sel-mvc.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>MVC Repeat with Selectable RoundRectList - Single Select</title>
+
+	<script type="text/javascript" src="../../../../../dojox/mobile/deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true, parseOnLoad: false"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox",
+			"dojox/mvc",
+			//"dojox/mobile/parser",
+			"dojo/parser",
+			"dojo/store/Memory",
+			"dojo/ready",
+			"dojox/mvc/_patches",
+			"dojox/mvc/at",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat",
+			"dojox/mvc/Output",
+			"dojox/mobile",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/Button",
+			"dojox/mobile/TextArea",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/CheckBox",
+			"dojox/mobile/ViewController",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/EdgeToEdgeList",
+			"dojox/mobile/EdgeToEdgeCategory",
+			"dojox/mobile/deviceTheme",
+			"dojox/mobile/RoundRectCategory",
+			"dojox/mobile/Heading"
+		], function(dojox, mvc, parser, MemoryStore, ready){
+
+
+			var search_results_init1 =
+			[{
+				"Query" : "Engineers1",
+				"Results" : [
+					{
+						"First"	  : "Anne1",
+						"Last"	  : "Ackerman1",
+						"Checked" : true
+					},
+					{
+						"First"	  : "Ben1",
+						"Last"	  : "Beckham1",
+						"Checked" : false
+					},
+					{
+						"First"	  : "Chad1",
+						"Last"	  : "Chapman1",
+						"Checked" : false
+					}
+				]
+			}];
+
+			var search_results_init2 =
+				[{
+					"Query" : "Engineers1",
+					"Results" : [
+						{
+							"First"	  : "Anne2",
+							"Last"	  : "Ackerman2",
+							"Checked" : false
+						},
+						{
+							"First"	  : "Ben2",
+							"Last"	  : "Beckham2",
+							"Checked" : true
+						},
+						{
+							"First"	  : "Chad2",
+							"Last"	  : "Chapman2",
+							"Checked" : false
+						}
+					]
+				}];
+			var memStore1 = new MemoryStore({data : search_results_init1});
+			model1 = mvc.newStatefulModel({ store : memStore1 })[0];
+
+			var memStore2 = new MemoryStore({data : search_results_init2});
+			model2 = mvc.newStatefulModel({ store : memStore2 })[0];
+			
+			// when "dojo/ready" is ready call parser.parse (if not doing parseOnLoad)
+			ready(function(){
+				parser.parse();
+			});
+
+
+
+		});
+
+		// called to reset the model for each of the repeats
+		function swapToModel1() {
+			dijit.byId('repeatId1').set('ref',model1.Results); 
+			dijit.byId('repeatId2').set('ref',model1.Results); 
+			dijit.byId('repeatid2arem').set('ref',model1.Results);
+			dijit.byId('repeatid2aremg').set('ref',model1.Results);
+			dijit.byId('repeatid2a').set('ref',model1.Results);			
+		};
+
+		function swapToModel2() {
+			dijit.byId('repeatId1').set('ref',model2.Results); 
+			dijit.byId('repeatId2').set('ref',model2.Results); 
+			dijit.byId('repeatid2arem').set('ref',model2.Results);
+			dijit.byId('repeatid2aremg').set('ref',model2.Results);
+			dijit.byId('repeatid2a').set('ref',model2.Results);			
+		};
+		
+		
+	</script>
+</head>
+<body style="visibility:hidden;">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h2>MVC Repeat with Selectable RoundRectDataList - Single Select</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+				<h4>Here is one using dojox.mvc.Repeat as a mixin with no Group and dojo.parser instead of dojox.mobile.parser it is all good using mixin.</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatId1" select="single" 
+					data-dojo-mixins="dojox.mvc.Repeat" data-dojo-props="exprchar:'#', ref:'model1.Results'">
+							<li id="configure_itemmix1#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at('rel:#{this.index}.First', 'value'),
+												checked: dojox.mvc.at('rel:#{this.index}.Checked', 'value')">
+							</li>
+				</ul>
+				
+				<h4>Here is one using MVC using Repeat no Group, with removeRepeatNode set true it is all good if Repeat sets select and onCheckStateChanged.</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatparentidrem" select="single">
+					<div data-dojo-type="dojox.mvc.Repeat" id="repeatid2arem" data-dojo-props="exprchar:'#', ref:'model1.Results', removeRepeatNode:true">
+							<li id="configure_itemrem#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at('rel:#{this.index}.First', 'value'),
+												checked: dojox.mvc.at('rel:#{this.index}.Checked', 'value')">
+							</li>
+					</div>
+				</ul>
+
+				<h4>Here is one using MVC using Repeat with a Group, with removeRepeatNode set true it is all good if Repeat sets select and onCheckStateChanged.</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatparentidremg" select="single">
+					<div data-dojo-type="dojox.mvc.Repeat" id="repeatid2aremg" data-dojo-props="exprchar:'#', ref:'model1.Results', removeRepeatNode:true">
+						<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '#{this.index}'">
+							<li id="configure_itemremg#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at('rel:First', 'value'),
+												checked: dojox.mvc.at('rel:Checked', 'value')">
+							</li>
+						</div>
+					</div>
+				</ul>
+  
+				<h4>You can update the label or checked from here to update the model.</h4>
+				   <div id="repeatparentid2">
+						<div id="repeatId2" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref:'model1.Results'">
+								<input class="cell" data-dojo-type="dojox.mobile.TextBox" id="nameInput2${this.index}" 
+										data-dojo-props="value: dojox.mvc.at('rel:${this.index}.First', 'value')"/>
+		  						<label data-dojo-type="dojox.mvc.Output" for="CBInput${this.index}" 
+										data-dojo-props="value: dojox.mvc.at('rel:${this.index}.First', 'value')"/></label>
+								<input class="cell" type="checkbox" data-dojo-type="dojox.mobile.CheckBox" id="CBInput${this.index}" 
+										data-dojo-props="checked: dojox.mvc.at('rel:${this.index}.Checked', 'value')"/>
+						</div>
+					</div>
+
+					<br/>Model:
+					<button type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){swapToModel2();}">Swap Model2</button> 
+					<button type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){swapToModel1();}">Swap Model1</button> 					
+					<button id="reset" type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){model1.reset();model2.reset();}">Reset all</button>
+				
+				<h4>Here is one using MVC using Repeat no Group, using useParent it has style and 
+				selection problems because of the Group nodes, updates to the model are reflected here, looks good, but has selection problems...
+				Also the Swap model buttons do not work with this one.
+				</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatparentid" select="single">
+					<div data-dojo-type="dojox.mvc.Repeat" id="repeatid2a" data-dojo-props="exprchar:'#', ref:'model1.Results', useParent:'repeatparentid'">
+							<li id="configure_item#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at('model1.Results.#{this.index}.First', 'value'),
+												checked: dojox.mvc.at('model1.Results.#{this.index}.Checked', 'value')">
+							</li>
+					</div>
+				</ul>
+
+
+		<!--
+					<h4>Here is a normal RoundRectList for comparison Item one should be selected</h4>
+					<ul id="list1a" data-dojo-type="dojox.mobile.RoundRectList" select="single" >
+							<li id="configure_itemXX0" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at(model1.Results[0].First, 'value'),
+												checked: dojox.mvc.at(model1.Results[0].Checked, 'value')">
+							</li>
+							<li id="configure_itemXX1" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: dojox.mvc.at(model1.Results[1].First, 'value'),
+												checked: dojox.mvc.at(model1.Results[1].Checked, 'value')">
+							</li>
+					</ul>	
+		-->	
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/models/LoanWizardModel.js b/dojox/mvc/tests/1.7/models/LoanWizardModel.js
new file mode 100644
index 0000000..954d4fd
--- /dev/null
+++ b/dojox/mvc/tests/1.7/models/LoanWizardModel.js
@@ -0,0 +1,105 @@
+define([
+	"dojo/_base/declare",
+	"dojox/mvc",
+	"dojox/mvc/StatefulModel",
+	"dojo/data/ItemFileWriteStore"
+], function(declare, mvc, StatefulModel, ItemFileWriteStore){
+
+	return declare("dojox.mvc.tests.models.LoanWizardModel", [StatefulModel], {
+
+		// data store for pie chart
+		chartStore: new ItemFileWriteStore({ data: {
+			"hierarchical" : false,
+			"identifier"   : "id",
+			"items" : [
+			           { "id" : "mortgage", "x"  : 1, "y"	: 0 },
+			           { "id" : "taxes", "x"  : 2, "y"	 : 0 },
+			           { "id" : "otherhousing", "x"  : 3, "y"	: 0 }
+			           ]
+		}}),
+
+		constructor: function (args) {
+			// try to precompute address fields from the zipcode and country...	 
+			mvc.bindInputs([this.Zip, this.Country], dojo.hitch(this, this._lookupAddrs));
+			// simple dependence of percentages on input values and total
+			mvc.bindInputs([this.Mortgage, this.Taxes, this.OtherHousing, this.BaseIncome, this.BonusIncome], dojo.hitch(this, this._recomputeTotalAndPercentages));
+
+			mvc.bind(this.HousingPercent, "value", this.HousingPercent, "valid", dojo.hitch(this, this._isHousingLessThanOrEqualToThirtyThreePercent), true);
+
+			mvc.bind(this.HousingPercent, "value", this.HousingPercent, "relevant", dojo.hitch(this, this._nonZeroRelevance), true);
+			mvc.bind(this.TotalHousing, "value", this.TotalHousing, "relevant", dojo.hitch(this, this._nonZeroRelevance), true);
+
+			this._recomputeTotalAndPercentages();  // get things going first time...
+		},
+
+		_lookupItem: function( dataSource, identity ) {
+			var found_item;
+			dataSource.fetchItemByIdentity( { "identity": identity, 
+				"onItem": function (item) { found_item = item; } } );
+			return found_item;
+		},
+
+		_lookupAddrs: function() {
+			if ( this.Zip.get("value") == null || isNaN(this.Zip.get("value"))) return;
+			var pThis = this;
+			var query = { "postalcode": this.Zip.get("value"), "country": this.Country.get("value") };		
+			var xhrArgs = {
+					url: "zips/"+this.Zip.get("value")+".json",
+					sync: true,
+					content: query,
+					preventCache: true,
+					handleAs: "json",
+					load: function(data, io) {
+						pThis.City.set("value", data.postalcodes[0].placeName );
+						pThis.County.set("value", data.postalcodes[0].adminName2 );
+						pThis.State.set("value", data.postalcodes[0].adminCode1 );
+						pThis.Zip.set("valid", true ); 
+					},
+					error: function (data) {
+						// we couldn't find this country/zip combination...clear the fields and set validity=false
+						pThis.City.set("value", "" );
+						pThis.County.set("value", "" );
+						pThis.State.set("value", "" );
+						pThis.Zip.set("valid", false );
+					}
+			};
+			//Call the synchronous xhrGet
+			var deferred = dojo.xhrGet(xhrArgs);	
+		},
+
+		_recomputeTotalAndPercentages: function() {
+			var mortgage = parseInt(this.Mortgage.get("value"));
+			var taxes = parseInt(this.Taxes.get("value"));
+			var otherHousing = parseInt(this.OtherHousing.get("value"));
+			var totalHousing = mortgage + taxes + otherHousing;
+
+			var baseIncome = parseInt(this.BaseIncome.get("value"));
+			var bonusIncome = parseInt(this.BonusIncome.get("value"));
+			var totalIncome = baseIncome + bonusIncome;
+
+			var housingPercentage = Math.round(totalHousing / totalIncome * 100);
+
+			this.HousingPercent.set("value", housingPercentage);
+			this.TotalHousing.set("value", totalHousing);
+			this.TotalIncome.set("value", totalIncome);
+
+			// map the values into the data source structure required for chart display as well...
+			var mortgageItem = this._lookupItem(this.chartStore, "mortgage");
+			var taxesItem = this._lookupItem(this.chartStore, "taxes");
+			var otherItem = this._lookupItem(this.chartStore, "otherhousing");
+			this.chartStore.setValue(mortgageItem, "y", mortgage);
+			this.chartStore.setValue(taxesItem, "y", taxes);
+			this.chartStore.setValue(otherItem, "y", otherHousing);
+		},
+
+		_isHousingLessThanOrEqualToThirtyThreePercent: function(newValue) {
+			return newValue <= 33;
+		},
+
+		_nonZeroRelevance: function(newValue) {
+			if ( newValue > 0 ) return true;
+			else return false;
+		}
+
+	});
+});
diff --git a/dojox/mvc/tests/1.7/module.js b/dojox/mvc/tests/1.7/module.js
new file mode 100644
index 0000000..30f0b92
--- /dev/null
+++ b/dojox/mvc/tests/1.7/module.js
@@ -0,0 +1,33 @@
+dojo.provide("dojox.mvc.tests.module");
+
+try{
+	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
+	// DOH
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_shipto-billto-simple", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_mvc_shipto-billto-simple.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_search-results-repeat", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_mvc_search-results-repeat.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_search-results-repeat-store", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_mvc_search-results-repeat-store.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_programmatic-repeat-store", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_mvc_programmatic-repeat-store.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_binding-simple", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_mvc_binding-simple.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_ref-set-repeat", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_mvc_ref-set-repeat.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_billto-hierarchical", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_mvc_shipto-billto-hierarchical.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_async_mvc_input-output-simple", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_async_mvc_input-output-simple.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_async_mvc_zero-value-test", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_async_mvc_zero-value-test.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_template_repeat_exprchar", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_mvc_template_repeat_exprchar.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_form-kitchensink", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_mvc_form-kitchensink.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_date_test", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_mvc_date_test.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_validation-test-simple", dojo.moduleUrl("dojox.mvc","tests/1.7/doh/doh_mvc_validation-test-simple.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.doh_new-mvc_input-output-simple.html", dojo.moduleUrl("dojox.mvc","tests/doh_new-mvc_input-output-simple.html"+userArgs), 999999);
+	// Robot
+	doh.registerUrl("dojox.mvc.tests.1.7.robot.mobile-demo-test", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mobile-demo-test.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_shipto-billto-simple", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_shipto-billto-simple.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_generate-view", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_generate-view.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_loan-stateful", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_loan-stateful.html"+userArgs), 999999);
+	//doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_ref-set-repeat", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_ref-set-repeat.html"+userArgs), 999999);
+	//doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_search-results-repeat", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_search-results-repeat.html"+userArgs), 999999);
+	doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_search-results-ins-del", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_search-results-ins-del.html"+userArgs), 999999);
+	//doh.registerUrl("dojox.mvc.tests.1.7.robot.iphone_shipto-billto", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/iphone_shipto-billto.html"+userArgs), 999999);
+	//doh.registerUrl("dojox.mvc.tests.1.7.robot.android_repeat-ins", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/android_repeat-ins.html"+userArgs), 999999);
+	//doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_shipto-billto-hierarchical", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_shipto-billto-hierarchical.html"+userArgs), 999999);
+}catch(e){
+	doh.debug(e);
+}
diff --git a/dojox/mvc/tests/mvc_index.html b/dojox/mvc/tests/1.7/mvc_index.html
old mode 100755
new mode 100644
similarity index 100%
copy from dojox/mvc/tests/mvc_index.html
copy to dojox/mvc/tests/1.7/mvc_index.html
diff --git a/dojox/mvc/tests/1.7/robot/android_repeat-ins.html b/dojox/mvc/tests/1.7/robot/android_repeat-ins.html
new file mode 100644
index 0000000..602bc4b
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/android_repeat-ins.html
@@ -0,0 +1,171 @@
+<!DOCTYPE html>
+<html>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>doh.robot MVC search-results-ins-del Test</title>
+
+		<style>
+			@import "../../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"
+			djConfig="isDebug: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript" src="../helpers.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../mobile/test_Android-repeat-data-store.html');
+
+				doh.register("on_test_MVC_Search_Results_Repeat", [
+					 {
+						name: "initial conditions",
+						timeout: 9000,
+						runTest: function(){
+						var d = new doh.Deferred();
+						console.debug("dojo.version() is "+dojo.version);
+						
+						doh.robot.sequence(d.getTestCallback(function(){
+							doh.is("Chad", dijit.byId("nameInput0").get('value'),"nameInput0 should be Chad");
+							doh.is("Hunter", dijit.byId("nameInput1").get('value'),"nameInput1 should be Hunter");
+							doh.is("John", dijit.byId("nameInput2").get('value'),"nameInput2 should be John");
+							doh.is("Chad", dijit.byId("firstInput").get('value'),"firstInput should be Chad");
+							doh.is("Chapman", dijit.byId("lastInput").get('value'),"lastInput should be Chapman");
+							doh.is("c.c at test.com", dijit.byId("emailInput").get('value'),"emailInput should be c.c at test.com");
+						}), 1000);
+						return d;
+						}
+					 },
+					{
+						name: "selectHunter",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("details1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Hunter", dijit.byId("firstInput").get('value'),"firstInput should be Hunter");
+								doh.is("Huffman", dijit.byId("lastInput").get('value'),"lastInput should be Huffman");
+								doh.is("h.h at test.com", dijit.byId("emailInput").get('value'),"emailInput should be h.h at test.com");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "selectJohn",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("details2", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("John", dijit.byId("firstInput").get('value'),"firstInput should be John");
+								doh.is("Jacklin", dijit.byId("lastInput").get('value'),"lastInput should be Jacklin");
+								doh.is("j.j at test.com", dijit.byId("emailInput").get('value'),"emailInput should be j.j at test.com");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "changeJohn",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("firstInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.typeKeys("Johnny", 1000, 2000);													  
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Johnny", dijit.byId("firstInput").get('value'),"firstInput should be Johnny");
+								doh.is("Johnny", dijit.byId("nameInput2").get('value'),"nameInput2 should be Johnny");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "changeHunter",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("details1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("nameInput1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.typeKeys("Howard", 500, 1000);													 
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Howard", dijit.byId("firstInput").get('value'),"check for firstInput set to Howard");
+								doh.is("Howard", dijit.byId("nameInput1").get('value'),"check for nameInput1 set to Howard");
+							}), 1500);
+							return d;
+						}
+					},
+					{
+						name: "AddKen",
+						timeout: 20000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							//doh.robot.mouseMoveAt("dijit_form_Button_29", 500, 0);
+							//doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("add", 2000, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("firstInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.typeKeys("Ken", 500, 1000);													  
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("Kelly", 500, 1000);														
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							//doh.robot.typeKeys("CA", 500, 1000);													   
+							//doh.robot.keyPress(dojo.keys.TAB, 500, {});  
+							//doh.robot.typeKeys("5623", 500, 1000);													 
+							//doh.robot.keyPress(dojo.keys.TAB, 500, {});  
+							doh.robot.typeKeys("k.k at test.com", 500, 1000);													   
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("408-764-3454", 500, 1000);													   
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("408-764-6000", 500, 1000);													   
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Ken", dijit.byId("firstInput").get('value'),"firstInput should be Ken");
+								doh.is("Ken", dijit.byId("nameInput3").get('value'),"nameInput4 should be Ken");
+								doh.is("Kelly", dijit.byId("lastInput").get('value'),"lastInput should be set");
+								//doh.is("CA", dijit.byId("locationInput").get('value'),"locationInput should be set");
+								//doh.is("5623", dijit.byId("officeInput").get('value'),"officeInput should be set");
+								doh.is("k.k at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
+								doh.is("408-764-3454", dijit.byId("telInput").get('value'),"telInput should be set");
+								doh.is("408-764-6000", dijit.byId("faxInput").get('value'),"faxInput should be set");
+							}), 1000);
+							return d;
+						}
+					}				]);
+				doh.run();
+			});
+		</script>
+</html>
diff --git a/dojox/mvc/tests/1.7/robot/iphone_shipto-billto.html b/dojox/mvc/tests/1.7/robot/iphone_shipto-billto.html
new file mode 100755
index 0000000..51e9b0d
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/iphone_shipto-billto.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<html>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>doh.robot MVC demo-shipto-billto-simple Declarative Test</title>
+
+		<style>
+			@import "../../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"
+			djConfig="isDebug: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript" src="../helpers.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../mobile/test_iPhone-shipto-billto.html');
+
+				doh.register("test_iPhone_SimpleDataBoundField", [															   
+					{
+						name: "initial conditions",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							console.debug("dojo.version() is "+dojo.version);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								//"ShipTo" selected 
+								doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					 },
+					 {						
+						name: "billto",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("billto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								//"BillTo" selected 
+								doh.is("17 Skyline Dr", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "shipto",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("shipto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								//"ShipTo" selected 
+								doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					},					
+					{
+						name: "changeShipToAddress",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("cityInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});							
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
+							
+							doh.robot.typeKeys("456 Mountain Rd", 500, 1000);							
+							
+							doh.robot.mouseMoveAt("billto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("shipto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("streetInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+</html>
diff --git a/dojox/mvc/tests/1.7/robot/mobile-demo-test.html b/dojox/mvc/tests/1.7/robot/mobile-demo-test.html
new file mode 100644
index 0000000..de38feb
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/mobile-demo-test.html
@@ -0,0 +1,404 @@
+<!DOCTYPE html>
+<html>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>doh.robot MVC demo-shipto-billto-simple Declarative Test</title>
+
+		<style>
+			@import "../../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"
+			djConfig="isDebug: true, parseOnLoad: true"></script>
+
+		<!-- <script type="text/javascript" src="../helpers.js"></script>  -->
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../mobile/demo/demo.html');
+
+				doh.register("test_Mobile-Demo", [															   
+					{
+						name: "initial conditions",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							console.debug("dojo.version() is "+dojo.version);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								//"ShipTo" selected 
+								//doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					 },
+					 {						
+						name: "testSimpleDataBinding",
+						timeout: 18000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("sdb", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("cityInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});							
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
+							
+							doh.robot.typeKeys("456 Mountain Rd", 300, 800);							
+							doh.robot.keyPress(dojo.keys.TAB, 300, {shift:true});							
+							
+							doh.robot.mouseMoveAt("billto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("shipto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("streetInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var w = dijit.byId("streetInput");
+								var v  = w.get('value');
+								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							
+						//	doh.robot.sequence(d.getTestCallback(function(){
+								//"SendTo" selected 
+								//"BillTo" selected 
+						//		doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+								//doh.is("17 Skyline Dr", dijit.byId("streetInput").get('value'),"streetInput should be set");
+						//	}), 1000);
+							return d;
+						}
+					},
+					 {						
+						name: "testSimpleDataBinding - billTo",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("billto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								//"BillTo" selected 
+								doh.is("17 Skyline Dr", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "shipto",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("shipto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								//"ShipTo" selected 
+								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					},					
+/*					{
+						name: "changeShipToAddress",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("cityInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});							
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
+							
+							doh.robot.typeKeys("456 Mountain Rd", 500, 1000);							
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});							
+							
+							doh.robot.mouseMoveAt("billto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("shipto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("streetInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var w = dijit.byId("streetInput");
+								var v  = w.get('value');
+								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					 },
+				*/ 
+					 {						
+						name: "testRepeatDataBinding",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							//doh.robot.mouseMoveAt("home", 500, 0);
+							var t1 = dojo.query('.mblToolBarButtonLeftArrow')[0];
+							doh.robot.mouseMoveAt(dojo.query('.mblToolBarButtonLeftArrow')[0], 500);							
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("rdb", 1500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+							doh.is("Chad", dijit.byId("nameInput0").get('value'),"nameInput0 should be Chad");
+							doh.is("Irene", dijit.byId("nameInput1").get('value'),"nameInput1 should be Irene");
+							doh.is("John", dijit.byId("nameInput2").get('value'),"nameInput2 should be John");
+							doh.is("Chad", dijit.byId("firstInput").get('value'),"firstInput should be Chad");
+							doh.is("Chapman", dijit.byId("lastInput").get('value'),"lastInput should be Chapman");
+							doh.is("c.c at test.com", dijit.byId("emailInput2").get('value'),"emailInput2 should be c.c at test.com");
+							}), 1000);
+							
+							return d;
+						}
+					},
+			/*		{
+						name: "selectIrene",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("details1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Irene", dijit.byId("firstInput").get('value'),"firstInput should be Irene");
+								doh.is("Ira", dijit.byId("lastInput").get('value'),"lastInput should be Ira");
+								doh.is("i.i at test.com", dijit.byId("emailInput2").get('value'),"emailInput2 should be h.h at test.com");
+							}), 1000);
+							return d;
+						}
+					},
+			*/		
+					{
+						name: "selectJohn",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("details2", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("John", dijit.byId("firstInput").get('value'),"firstInput should be John");
+								doh.is("Jacklin", dijit.byId("lastInput").get('value'),"lastInput should be Jacklin");
+								doh.is("j.j at test.com", dijit.byId("emailInput2").get('value'),"emailInput2 should be j.j at test.com");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "changeJohn",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("firstInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.typeKeys("Johnny", 1000, 2000);													  
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Johnny", dijit.byId("firstInput").get('value'),"firstInput should be Johnny");
+								doh.is("Johnny", dijit.byId("nameInput2").get('value'),"nameInput2 should be Johnny");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "changeIrene",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("details1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("nameInput1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.typeKeys("Howard", 300, 800);													 
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Howard", dijit.byId("firstInput").get('value'),"check for firstInput set to Howard");
+								doh.is("Howard", dijit.byId("nameInput1").get('value'),"check for nameInput1 set to Howard");
+							}), 1500);
+							return d;
+						}
+					},
+					{
+						name: "AddKen",
+						timeout: 20000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							//doh.robot.mouseMoveAt("dijit_form_Button_29", 500, 0);
+							//doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("add", 1000, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("firstInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.typeKeys("Ken", 300, 600);													  
+							doh.robot.keyPress(dojo.keys.TAB, 300, {});	 
+							doh.robot.typeKeys("Kelly", 300, 600);														
+							doh.robot.keyPress(dojo.keys.TAB, 300, {});	 
+							doh.robot.typeKeys("k.k at test.com", 300, 600);													   
+							doh.robot.keyPress(dojo.keys.TAB, 300, {});	 
+							doh.robot.typeKeys("408-764-3454", 300, 600);													   
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Ken", dijit.byId("firstInput").get('value'),"firstInput should be Ken");
+								doh.is("Ken", dijit.byId("nameInput3").get('value'),"nameInput4 should be Ken");
+								doh.is("Kelly", dijit.byId("lastInput").get('value'),"lastInput should be set");
+								doh.is("k.k at test.com", dijit.byId("emailInput2").get('value'),"emailInput2 should be set");
+								doh.is("408-764-3454", dijit.byId("telInput").get('value'),"telInput should be set");
+							}), 1000);
+							return d;
+						}
+				
+					 },
+				
+					 {						
+						name: "testGenerateDataBinding",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// move back to Home
+							doh.robot.mouseMoveAt(dojo.query('.mblToolBarButtonLeftArrow')[1], 500);							
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("sfg", 1000, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("generate1", 1000, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("11111", dijit.byId("TB0").get('value'),"TB0 should be set");
+								doh.is("John", dijit.byId("TB1").get('value'),"TB1 should be set");
+								doh.is("Doe", dijit.byId("TB2").get('value'),"TB2 should be set");
+								doh.is("jdoe at example.com", dijit.byId("TB3").get('value'),"TB3 should be set");			
+							}), 1000);
+							
+							return d;
+						}
+					},
+					{
+						name: "changeJohnGenerate", 
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("TB1", 500, 0); //updateModel
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
+							doh.robot.typeKeys("Johnny", 200, 800);													  
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Johnny", dijit.byId("TB1").get('value'),"TB1 should be Johnny");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "updateModelGenerate", 
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("updateModel", 500, 0); 
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var ttt = dijit.byId("modelArea").get('value');
+								var txa = ttt.substring(33,39);
+								if (txa !== "Johnny"){ //IE has a diff offset
+									txa = ttt.substring(35,41);
+								}
+								doh.is("Johnny", txa,"textarea should have Johnny");
+							}), 2000);
+							return d;
+						}
+					},
+					{
+						name: "updateFormGenerate", 
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var ttt2 = dijit.byId("modelArea2").get('value');
+							dijit.byId("modelArea").set('value',ttt2);
+							
+							doh.robot.mouseMoveAt("generate1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("11111", dijit.byId("TB0").get('value'),"TB0 should be set");
+								doh.is("John", dijit.byId("TB1").get('value'),"TB1 should be set");
+								doh.is("J", dijit.byId("TB2").get('value'),"TB2 should be set");
+								doh.is("Doe", dijit.byId("TB3").get('value'),"TB3 should be set");
+								doh.is("jdoe at example.com", dijit.byId("TB4").get('value'),"TB4 should be set");			
+							}), 1000);
+							return d;
+						}
+					},
+					 {						
+						name: "testBackToHome",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// move back to Home
+							var t = dojo.query('.mblToolBarButtonLeftArrow');
+							doh.robot.mouseMoveAt(dojo.query('.mblToolBarButtonLeftArrow')[2], 500);							
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("11111", dijit.byId("TB0").get('value'),"TB0 should be set");
+							}), 1000);
+							
+							return d;
+						}
+					}
+					
+				]);
+				doh.run();
+			});
+		</script>
+</html>
diff --git a/dojox/mvc/tests/1.7/robot/moduleFullSet.js b/dojox/mvc/tests/1.7/robot/moduleFullSet.js
new file mode 100644
index 0000000..65623ec
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/moduleFullSet.js
@@ -0,0 +1,27 @@
+define([
+	"doh/runner",
+	"dojo/_base/sniff",
+	"../../../equals",
+	"../../StatefulModelOptions"
+], function(doh, has){
+	try{
+		var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g, "").replace(/^&/, "?");
+
+		// only run the 1.7 Robot tests
+		if(!has("ie")){
+			// Hit an error with the mobile parser with IE, need to investigate more
+			doh.registerUrl("dojox.mvc.tests.1.7.robot.mobile-demo-test", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mobile-demo-test.html"+userArgs), 999999);
+			doh.registerUrl("dojox.mvc.tests.1.7.robot.android_repeat-ins", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/android_repeat-ins.html"+userArgs), 999999);
+		}
+		doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_shipto-billto-simple", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_shipto-billto-simple.html"+userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_generate-view", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_generate-view.html"+userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_loan-stateful", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_loan-stateful.html"+userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_ref-set-repeat", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_ref-set-repeat.html"+userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_search-results-repeat", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_search-results-repeat.html"+userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_search-results-ins-del", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_search-results-ins-del.html"+userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.robot.iphone_shipto-billto", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/iphone_shipto-billto.html"+userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.robot.mvc_shipto-billto-hierarchical", dojo.moduleUrl("dojox.mvc","tests/1.7/robot/mvc_shipto-billto-hierarchical.html"+userArgs), 999999);
+	}catch(e){
+		doh.debug(e);
+	}
+});
diff --git a/dojox/mvc/tests/1.7/robot/mvc_generate-view.html b/dojox/mvc/tests/1.7/robot/mvc_generate-view.html
new file mode 100755
index 0000000..1bed451
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/mvc_generate-view.html
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<html>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>doh.robot MVC Generate View Test</title>
+
+		<style>
+			@import "../../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"
+			djConfig="isDebug: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript" src="../helpers.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_mvc_generate-view.html');
+
+				doh.register("on_test_MVC_Search_Results_Repeat", [
+					 {
+						name: "initial conditions",
+						timeout: 9000,
+						runTest: function(){
+						var d = new doh.Deferred();
+						console.debug("dojo.version() is "+dojo.version);
+						
+						doh.robot.sequence(d.getTestCallback(function(){
+							doh.is("360324", dijit.byId("view_t0").get('value'),"view_t0 should be set");
+							doh.is("John", dijit.byId("view_t1").get('value'),"view_t1 should be set");
+							doh.is("Doe", dijit.byId("view_t2").get('value'),"view_t2 should be set");
+							doh.is("jdoe at example.com", dijit.byId("view_t3").get('value'),"view_t3 should be set");
+						}), 1000);
+						return d;
+						}
+					 },
+					{
+						name: "changeJohn",
+						timeout: 18000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("view_t0", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
+
+							// ensure we've reached top left of text area x-browser
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});
+
+							// navigate to end of first name in JSON in textarea
+
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});						   
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});						   
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});						   
+
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});						   
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});						   
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});						   
+
+							doh.robot.typeKeys("ny", 500, 1000);													 
+							doh.robot.mouseMoveAt("view_t0", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("360324", dijit.byId("view_t0").get('value'),"view_t0 should be set");
+								doh.is("Johnny", dijit.byId("view_t1").get('value'),"view_t1 should be set");
+								doh.is("Doe", dijit.byId("view_t2").get('value'),"view_t2 should be set");
+								doh.is("jdoe at example.com", dijit.byId("view_t3").get('value'),"view_t3 should be set");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "addMiddle",
+						timeout: 18000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("view_t0", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
+
+							// ensure we've reached top left of text area x-browser
+
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
+
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});
+
+							// navigate to end of first name in JSON in textarea
+
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});						   
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});						   
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});
+
+							doh.robot.typeKeys('    "Middle" : "J.",', 500, 1000);													 
+							doh.robot.keyPress(dojo.keys.ENTER, 100, {});						  
+							doh.robot.mouseMoveAt("view_t0", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("360324", dijit.byId("view_t0").get('value'),"view_t0 should be set");
+								doh.is("Johnny", dijit.byId("view_t1").get('value'),"view_t1 should be set");
+								doh.is("J.", dijit.byId("view_t2").get('value'),"view_t2 should be set");
+								doh.is("Doe", dijit.byId("view_t3").get('value'),"view_t3 should be set");
+								doh.is("jdoe at example.com", dijit.byId("view_t4").get('value'),"view_t4 should be set");
+
+								doh.is("2010", dijit.byId("view_t18").get('value'),"view_t18 should be set");
+								doh.is("Gold", dijit.byId("view_t19").get('value'),"view_t19 should be set");
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+</html>
diff --git a/dojox/mvc/tests/1.7/robot/mvc_loan-stateful.html b/dojox/mvc/tests/1.7/robot/mvc_loan-stateful.html
new file mode 100755
index 0000000..764c869
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/mvc_loan-stateful.html
@@ -0,0 +1,160 @@
+<!DOCTYPE html>
+<html>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>doh.robot MVC loan stateful Test</title>
+
+		<style>
+			@import "../../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"
+			djConfig="isDebug: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript" src="../helpers.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_mvc_loan-stateful.html');
+
+				doh.register("on_test_MVC_LoanStateful", [
+					 {
+						name: "initial conditions",
+						timeout: 9000,
+						runTest: function(){
+						var d = new doh.Deferred();
+						console.debug("dojo.version() is "+dojo.version);
+						
+						doh.robot.sequence(d.getTestCallback(function(){
+							doh.is("5", dijit.byId("percentHousing").get('value'),"percentHousing should be 5");
+							doh.is(true, dijit.byId("percentHousing").isValid(), "isValid()","percentHousing should be valid");
+							doh.is("1000", dijit.byId("housing").get('value'),"housing should be 1000");
+							doh.is("2700", dijit.byId("totalHousing").get('value'),"totalHousing should be 2700");
+						}), 1000);
+						return d;
+						}
+					 },
+					{
+						name: "setzipgood1",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("zipInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.typeKeys("10706", 800, 1000);														
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Hastings On Hudson", dijit.byId("cityInput").get('value'),"good zip 10706 should display the city");
+							}), 1500);
+							return d;
+						}
+					},
+					{
+						name: "setzipbad1",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("borrowerInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});		
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});														
+							doh.robot.typeKeys("11111", 500, 1000);														
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							
+							// should also check for invalid zip indicator
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("", dijit.byId("cityInput").get('value'),"cityInput should be blank");
+								doh.is(false, dijit.byId("zipInput").isValid(), "zipInput should be invalid");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "setzipgood2",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("borrowerInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});			
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});														
+							doh.robot.typeKeys("10024", 500, 1000);														
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("New York", dijit.byId("cityInput").get('value'),"check for cityInput set to New York");
+							}), 1500);
+							return d;
+						}
+					},
+					{
+						name: "changeMortgageAmt1",
+						timeout: 19000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("stateInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
+							
+							doh.robot.typeKeys("10000", 500, 1000);							
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+
+							doh.robot.mouseMoveAt("total", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("10000", dijit.byId("housing").get('value'),"housing should be 10000");
+								doh.is("11700", dijit.byId("totalHousing").get('value'),"totalHousing should be 11700");								
+								doh.is("20", dijit.byId("percentHousing").get('value'),"percentHousing should be 20");
+								doh.is(true, dijit.byId("percentHousing").isValid(),"percentHousing should be valid");
+								
+							}), 1500);
+							return d;
+						}
+					},
+					{
+						name: "changeMortgageAmt2",
+						timeout: 19000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("stateInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
+							
+							doh.robot.typeKeys("20000", 500, 1000);							
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+
+							doh.robot.mouseMoveAt("total", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("20000", dijit.byId("housing").get('value'),"housing should be 20000");
+								doh.is("21700", dijit.byId("totalHousing").get('value'),"totalHousing should be 21700");								
+								doh.is("36", dijit.byId("percentHousing").get('value'),"percentHousing should be 36");
+								doh.is(false, dijit.byId("percentHousing").isValid(),"percentHousing should be invalid");
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+</html>
diff --git a/dojox/mvc/tests/1.7/robot/mvc_ref-set-repeat.html b/dojox/mvc/tests/1.7/robot/mvc_ref-set-repeat.html
new file mode 100644
index 0000000..ecb4af0
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/mvc_ref-set-repeat.html
@@ -0,0 +1,156 @@
+<!DOCTYPE html>
+<html>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>doh.robot MVC Ref set repeat test</title>
+
+		<style>
+			@import "../../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"
+			djConfig="isDebug: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript" src="../helpers.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_mvc_ref-set-repeat-simple.html');
+
+				doh.register("test_MVC_SimpleDataBoundField", [				                                               
+					{
+						name: "initial conditions",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							console.debug("dojo.version() is "+dojo.version);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Anne1", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne1");
+								doh.is("Ben1",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben1 ");
+								doh.is("Chad1", dijit.byId("nameInput2").get('value'),"nameInput2 should be Chad1");
+
+								doh.is("Anne1", dijit.byId("firstnameOutput10").get('value'),"firstnameOutput10 should be Anne1");
+								doh.is("Ben1",  dijit.byId("firstnameOutput11").get('value'),"firstnameOutput11 should be Ben1 ");
+								doh.is("Chad1", dijit.byId("firstnameOutput12").get('value'),"firstnameOutput12 should be Chad1");
+
+								doh.is("Anne2", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2");
+								doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
+
+								doh.is("", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be blank");
+							}), 1000);
+							return d;
+						}
+					 },
+                     {						
+						name: "SelectModel2",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Anne2", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne2");
+								doh.is("Ben2",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben2 ");
+							}), 1000);
+							return d;
+						}
+					 },
+                     {						
+						name: "ChangeModel2",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+                            doh.robot.keyPress(dojo.keys.TAB, 500, {});                         
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
+							
+							doh.robot.typeKeys("Anne2-Update", 500, 1000);							
+                            doh.robot.keyPress(dojo.keys.TAB, 500, {});                         
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Anne2-Update", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne2-Update");
+								doh.is("Ben2",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben2 ");
+
+								doh.is("Anne2-Update", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2-Update");
+								doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
+							}), 1000);
+							return d;
+						}
+					 },
+                     {						
+						name: "SelectModel3",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_2", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("", dijit.byId("nameInput0").get('value'),"nameInput0 should be blank");
+							}), 1000);
+							return d;
+						}
+					 },
+                     {						
+						name: "ChangeModel3",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("nameInput0", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});
+							
+							doh.robot.typeKeys("Anne3-Update", 500, 1000);							
+                            doh.robot.keyPress(dojo.keys.TAB, 500, {});                         
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Anne3-Update", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne3-Update");
+
+								doh.is("Anne3-Update", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be Anne3-Update");
+							}), 1000);
+							return d;
+						}
+					 },
+                     {						
+						name: "ResetAll",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("dijit_form_Button_0", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("reset", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Anne1", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne1");
+								doh.is("Ben1",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben1 ");
+								doh.is("Chad1", dijit.byId("nameInput2").get('value'),"nameInput2 should be Chad1");
+
+								doh.is("Anne1", dijit.byId("firstnameOutput10").get('value'),"firstnameOutput10 should be Anne1");
+								doh.is("Ben1",  dijit.byId("firstnameOutput11").get('value'),"firstnameOutput11 should be Ben1 ");
+								doh.is("Chad1", dijit.byId("firstnameOutput12").get('value'),"firstnameOutput12 should be Chad1");
+
+								doh.is("Anne2", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2");
+								doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
+
+								doh.is("", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be blank");
+							
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+</html>
diff --git a/dojox/mvc/tests/1.7/robot/mvc_search-results-ins-del.html b/dojox/mvc/tests/1.7/robot/mvc_search-results-ins-del.html
new file mode 100755
index 0000000..66d5a89
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/mvc_search-results-ins-del.html
@@ -0,0 +1,276 @@
+<!DOCTYPE html>
+<html>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>doh.robot MVC search-results-ins-del Test</title>
+
+		<style>
+			@import "../../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"
+			djConfig="isDebug: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript" src="../helpers.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_mvc_search-results-ins-del.html');
+
+				doh.register("on_test_MVC_Search_Results_Repeat", [
+					 {
+						name: "initial conditions",
+						timeout: 9000,
+						runTest: function(){
+						var d = new doh.Deferred();
+						console.debug("dojo.version() is "+dojo.version);
+						doh.robot.mouseMoveAt("firstInput", 500, 0);
+						doh.robot.mouseClick({left:true}, 500);
+						
+						doh.robot.sequence(d.getTestCallback(function(){
+							doh.is("Anne", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne");
+							doh.is("Ben", dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben");
+							doh.is("John", dijit.byId("nameInput9").get('value'),"nameInput9 should be John");
+							doh.is("Anne", dijit.byId("firstInput").get('value'),"firstInput should be Anne");
+							doh.is("Ackerman", dijit.byId("lastInput").get('value'),"lastInput should be Ackerman");
+							doh.is("a.a at test.com", dijit.byId("emailInput").get('value'),"emailInput should be a.a at test.com");
+						}), 1000);
+						return d;
+						}
+					 },
+			/*		{
+						name: "selectBen",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_4", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Ben", dijit.byId("firstInput").get('value'),"firstInput should be Ben");
+								doh.is("Beckham", dijit.byId("lastInput").get('value'),"lastInput should be Beckham");
+								doh.is("b.b at test.com", dijit.byId("emailInput").get('value'),"emailInput should be b.b at test.com");
+							}), 1000);
+							return d;
+						}
+					},
+			*/		
+					{
+						name: "selectJohn",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_30", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("John", dijit.byId("firstInput").get('value'),"firstInput should be John");
+								doh.is("Jacklin", dijit.byId("lastInput").get('value'),"lastInput should be Jacklin");
+								doh.is("j.j at test.com", dijit.byId("emailInput").get('value'),"emailInput should be j.j at test.com");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "changeJohn",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("firstInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.typeKeys("Johnny", 300, 600);													  
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Johnny", dijit.byId("firstInput").get('value'),"firstInput should be Johnny");
+								doh.is("Johnny", dijit.byId("nameInput9").get('value'),"nameInput9 should be Johnny");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "changeBen",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_6", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("nameInput1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.typeKeys("jamin", 300, 600);														
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Benjamin", dijit.byId("firstInput").get('value'),"check for firstInput set to Benjamin");
+								doh.is("Benjamin", dijit.byId("nameInput1").get('value'),"check for nameInput1 set to Benjamin");
+							}), 1500);
+							return d;
+						}
+					},
+					{
+						name: "AddKen",
+						timeout: 20000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_31", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("dijit_form_Button_63", 2000, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("firstInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.typeKeys("Ken", 300, 600);													  
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("Kelly", 300, 600);														
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("CA", 300, 600);													 
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("5623", 300, 600);													   
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("k.k at test.com", 300, 600);													   
+							doh.robot.keyPress(dojo.keys.TAB, 300, {});	 
+							doh.robot.typeKeys("408-764-3454", 300, 600);													   
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("408-764-6000", 300, 600);													   
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Ken", dijit.byId("firstInput").get('value'),"firstInput should be Ken");
+								doh.is("Ken", dijit.byId("nameInput10").get('value'),"nameInput10 should be Ken");
+								doh.is("Kelly", dijit.byId("lastInput").get('value'),"lastInput should be set");
+								doh.is("CA", dijit.byId("locationInput").get('value'),"locationInput should be set");
+								doh.is("5623", dijit.byId("officeInput").get('value'),"officeInput should be set");
+								doh.is("k.k at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
+								doh.is("408-764-3454", dijit.byId("telInput").get('value'),"telInput should be set");
+								doh.is("408-764-6000", dijit.byId("faxInput").get('value'),"faxInput should be set");
+							}), 1000);
+							return d;
+						}
+					},
+			/*		{
+						name: "AddBetty",
+						timeout: 20000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_37", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("dijit_form_Button_72", 2000, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("nameInput2", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.typeKeys("Betty", 500, 1000);														
+							doh.robot.mouseMoveAt("lastInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.typeKeys("Baker", 500, 1000);														
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("CA", 500, 1000);													 
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("5624", 500, 1000);													   
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("b2.b2 at test.com", 500, 1000);													 
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("408-764-3455", 500, 1000);													   
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
+							doh.robot.typeKeys("408-764-6000", 500, 1000);													   
+							//doh.robot.keyPress(dojo.keys.TAB, 500, {});  
+							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Betty", dijit.byId("firstInput").get('value'),"firstInput should be set");
+								doh.is("Betty", dijit.byId("nameInput2").get('value'),"faxInput should be set");
+								doh.is("Baker", dijit.byId("lastInput").get('value'),"nameInput2 should be set");
+								doh.is("CA", dijit.byId("locationInput").get('value'),"locationInput should be set");
+								doh.is("5624", dijit.byId("officeInput").get('value'),"officeInput should be set");
+								doh.is("b2.b2 at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
+								doh.is("408-764-3455", dijit.byId("telInput").get('value'),"telInput should be set");
+								doh.is("408-764-6000", dijit.byId("faxInput").get('value'),"faxInput should be set");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "RemoveBetty",
+						timeout: 20000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_74", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("dijit_form_Button_114", 2000, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("dijit_form_Button_108", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("nameInput2", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Chad", dijit.byId("firstInput").get('value'),"firstInput should be set");
+								doh.is("Chad", dijit.byId("nameInput2").get('value'),"nameInput2 should be set");
+							}), 1000);
+							return d;
+						}
+					},					
+					{
+						name: "RemoveKen",
+						timeout: 20000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_134", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Chad", dijit.byId("firstInput").get('value'),"firstInput should be set");
+								doh.is(undefined, dijit.byId("nameInput10"),"nameInput10 should be set");
+							}), 1000);
+							return d;
+						}
+					}
+		*/			
+					{
+						name: "RemoveKen",
+						timeout: 20000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_39", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("dijit_form_Button_65", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Chad", dijit.byId("firstInput").get('value'),"firstInput should be set");
+								doh.is(undefined, dijit.byId("nameInput10"),"nameInput10 should be set");
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+</html>
diff --git a/dojox/mvc/tests/1.7/robot/mvc_search-results-repeat.html b/dojox/mvc/tests/1.7/robot/mvc_search-results-repeat.html
new file mode 100755
index 0000000..52be1d7
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/mvc_search-results-repeat.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>doh.robot MVC search-results-repeat Test</title>
+
+		<style>
+			@import "../../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"
+			djConfig="isDebug: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript" src="../helpers.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_mvc_search-results-repeat.html');
+
+				doh.register("on_test_MVC_Search_Results_Repeat", [
+					 {
+						name: "initial conditions",
+						timeout: 9000,
+						runTest: function(){
+						var d = new doh.Deferred();
+						console.debug("dojo.version() is "+dojo.version);
+						
+						doh.robot.sequence(d.getTestCallback(function(){
+							doh.is("Anne", dijit.byId("nameInput0").get('value'),"nameInput0 should be set");
+							doh.is("Ben", dijit.byId("nameInput1").get('value'),"nameInput1 should be set");
+							doh.is("John", dijit.byId("nameInput9").get('value'),"nameInput9 should be set");
+							doh.is("Anne", dijit.byId("firstInput").get('value'),"firstInput should be set");
+							doh.is("Ackerman", dijit.byId("lastInput").get('value'),"lastInput should be set");
+							doh.is("a.a at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
+						}), 1000);
+						return d;
+						}
+					 },
+					{
+						name: "selectBen",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_2", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Ben", dijit.byId("firstInput").get('value'),"firstInput should be set");
+								doh.is("Beckham", dijit.byId("lastInput").get('value'),"lastInput should be set");
+								doh.is("b.b at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "selectJohn",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_10", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("John", dijit.byId("firstInput").get('value'),"firstInput should be set");
+								doh.is("Jacklin", dijit.byId("lastInput").get('value'),"lastInput should be set");
+								doh.is("j.j at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
+							}), 1500);
+							return d;
+						}
+					},
+					{
+						name: "changeJohn",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("firstInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
+							doh.robot.typeKeys("Johnny", 1000, 2000);													  
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Johnny", dijit.byId("firstInput").get('value'),"firstInput should be set");
+								doh.is("Johnny", dijit.byId("nameInput9").get('value'),"nameInput9 should be set");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "changeBen",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_2", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("nameInput1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.typeKeys("jamin", 500, 1000);														
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Benjamin", dijit.byId("firstInput").get('value'),"firstInput should be set");
+								doh.is("Benjamin", dijit.byId("nameInput1").get('value'),"nameInput1 should be set");
+							}), 1000);
+							return d;
+						}
+					}				]);
+				doh.run();
+			});
+		</script>
+</html>
diff --git a/dojox/mvc/tests/1.7/robot/mvc_shipto-billto-hierarchical.html b/dojox/mvc/tests/1.7/robot/mvc_shipto-billto-hierarchical.html
new file mode 100755
index 0000000..e9762bb
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/mvc_shipto-billto-hierarchical.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>doh.robot MVC shipto-billto-hierarchical Test</title>
+
+		<style>
+			@import "../../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"
+			djConfig="isDebug: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript" src="../helpers.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_mvc_shipto-billto-hierarchical.html');
+
+				doh.register("test_MVC_SimpleDataBoundField", [
+				{
+						name: "initial conditions",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							console.debug("dojo.version() is "+dojo.version);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("ShipTo", dijit.byId("addrLabel").get('value'));
+								doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					 },
+					 {
+						name: "billto",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("BillTo", dijit.byId("addrLabel").get('value'),"addrLabel should be set");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "shipto",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							doh.robot.mouseMoveAt("dijit_form_Button_0", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("ShipTo", dijit.byId("addrLabel").get('value'),"addrLabel should be set");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "changeShipToAddress",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							//reset the streetInput textbox
+							//dijit.byId("streetInput").set('value',"");
+							
+							doh.robot.mouseMoveAt("addrLabel", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});
+							
+							doh.robot.typeKeys("456 Mountain Rd", 500, 1000);
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_1_label", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("dijit_form_Button_0_label", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("streetInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+</html>
diff --git a/dojox/mvc/tests/1.7/robot/mvc_shipto-billto-simple.html b/dojox/mvc/tests/1.7/robot/mvc_shipto-billto-simple.html
new file mode 100755
index 0000000..c2d6eb0
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/mvc_shipto-billto-simple.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<html>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>doh.robot MVC demo-shipto-billto-simple Declarative Test</title>
+
+		<style>
+			@import "../../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../../dojo/dojo.js"
+			djConfig="isDebug: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript" src="../helpers.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_mvc_shipto-billto-simple-declarative.html');
+
+				doh.register("test_MVC_SimpleDataBoundField", [				                                               
+					{
+						name: "initial conditions",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							console.debug("dojo.version() is "+dojo.version);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								//"ShipTo" selected 
+								doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					 },
+                     {						
+						name: "billto",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("billto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								//"BillTo" selected 
+								doh.is("17 Skyline Dr", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "shipto",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("shipto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								//"ShipTo" selected 
+								doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					},					
+					{
+						name: "changeShipToAddress",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
+                            doh.robot.keyPress(dojo.keys.TAB, 500, {});                         
+							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
+							
+							doh.robot.typeKeys("456 Mountain Rd", 500, 1000);							
+							
+							doh.robot.mouseMoveAt("billto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("shipto", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt("streetInput", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								console.debug("check data "+dijit.byId("streetInput").get('binding').data);
+								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+</html>
diff --git a/dojox/mvc/tests/1.7/robot/runTestsFullSet.html b/dojox/mvc/tests/1.7/robot/runTestsFullSet.html
new file mode 100644
index 0000000..fc5fd7d
--- /dev/null
+++ b/dojox/mvc/tests/1.7/robot/runTestsFullSet.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>Dijit Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../../util/doh/runner.html?testModule=dojox.mvc.tests.1.7.robot.moduleFullSet"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mvc/tests/1.7/test_async-mvc_group-simple.html b/dojox/mvc/tests/1.7/test_async-mvc_group-simple.html
new file mode 100644
index 0000000..eee77de
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_async-mvc_group-simple.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Async Simple Input - Output Group example</title>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+
+<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+ 		var model;
+ 
+		require([
+		'dojo/parser',
+        'dojox/mvc',
+		'dojox/mvc/Group',
+		'dojox/mvc/Output',
+		'dojo/parser',
+		'dijit/form/TextBox',
+		'dijit/form/Button'], function(){
+
+			// The dojox.mvc.StatefulModel class creates a data model instance
+			// where each leaf within the data model is decorated with dojo.Stateful
+			// properties that widgets can bind to and watch for their changes.
+			model = dojox.mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
+				require([
+					'dojo/domReady!'
+				], function(){
+				   dojo.parser.parse();
+				});
+				
+		}); // end onload
+
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent" dojoType="dojox.mvc.Group" data-dojo-props="ref: 'expr:model'">
+					<div class="row">
+						<label class="cell" for="firstnameInput">First:</label>
+						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.First"></input>
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'First'">
+						(first name is: ${this.value})
+						</span>
+					</div>
+				<div class="row">
+					<label class="cell" for="lastnameInput">Last:</label>
+					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Last"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Last'">
+						(last name is: ${this.value})
+					</span>
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Email"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Email'">
+					(email is: ${this.value})
+					</span>
+				</div>
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_async-mvc_input-output-simple.html b/dojox/mvc/tests/1.7/test_async-mvc_input-output-simple.html
new file mode 100644
index 0000000..3ad7979
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_async-mvc_input-output-simple.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Simple Input-Output Data Binding Example</title>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+
+		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var model;
+ 
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(parser, ready, mvc){
+
+				// The dojox.mvc.StatefulModel class creates a data model instance
+				// where each leaf within the data model is decorated with dojo.Stateful
+				// properties that widgets can bind to and watch for their changes.
+				model = mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
+				// the StatefulModel created above is initialized with 
+				// model.First set to "John", model.Last set to "Doe" and model.Email set to "jdoe at example.com"
+				
+				// when "dojo/ready" is ready call parser.parse
+				ready(function(){
+					parser.parse();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="row">
+						<label class="cell" for="firstnameInput">First:</label>
+						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.First"></input>
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
+						(first name is: ${this.value})
+						</span>
+					</div>
+				<div class="row">
+					<label class="cell" for="lastnameInput">Last:</label>
+					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Last"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Last">
+						(last name is: ${this.value})
+					</span>
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Email"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
+					(email is: ${this.value})
+					</span>
+				</div>
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_async-mvc_repeat-simple.html b/dojox/mvc/tests/1.7/test_async-mvc_repeat-simple.html
new file mode 100644
index 0000000..105ab11
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_async-mvc_repeat-simple.html
@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+
+<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+ /*
+			
+ */
+		var model;
+ 		var searchRecords;
+ 
+		require([
+		'dojo/parser',  // has to be first?         
+        'dojox/mvc',
+		'dojox/mvc/Group',
+		'dojox/mvc/Repeat',
+		'dijit/form/TextBox',
+		'dijit/form/Button'], function(){
+
+		  // Raw records for the master detail
+		  var search_results_init =
+			{
+				"Query" : "Engineers",
+				"Results" : [
+					{
+						"First"	  : "Anne",
+						"Last"	  : "Ackerman",
+						"Location": "NY",
+						"Office"  : "1S76",
+						"Email"	  : "a.a at test.com",
+						"Tel"	  : "123-764-8237",
+						"Fax"	  : "123-764-8228"
+					},
+					{
+						"First"	  : "Ben",
+						"Last"	  : "Beckham",
+						"Location": "NY",
+						"Office"  : "5N47",
+						"Email"	  : "b.b at test.com",
+						"Tel"	  : "123-764-8599",
+						"Fax"	  : "123-764-8600"
+					},
+					{
+						"First"	  : "Chad",
+						"Last"	  : "Chapman",
+						"Location": "CA",
+						"Office"  : "1278",
+						"Email"	  : "c.c at test.com",
+						"Tel"	  : "408-764-8237",
+						"Fax"	  : "408-764-8228"
+					},
+					{
+						"First"	  : "Irene",
+						"Last"	  : "Ira",
+						"Location": "NJ",
+						"Office"  : "F09",
+						"Email"	  : "i.i at test.com",
+						"Tel"	  : "514-764-6532",
+						"Fax"	  : "514-764-7300"
+					},
+					{
+						"First"	  : "John",
+						"Last"	  : "Jacklin",
+						"Location": "CA",
+						"Office"  : "6701",
+						"Email"	  : "j.j at test.com",
+						"Tel"	  : "408-764-1234",
+						"Fax"	  : "408-764-4321"
+					}
+				]
+			};
+
+		   // The dojox.mvc.StatefulModel class creates a data model instance
+		   // where each leaf within the data model is decorated with dojo.Stateful
+		   // properties that widgets can bind to and watch for their changes.
+		   searchRecords = dojox.mvc.newStatefulModel({ data : search_results_init });
+				require([
+					'dojo/domReady!'
+				], function(){
+				   dojo.parser.parse();
+				});
+				
+			
+		
+
+		}); // end onload
+
+		</script>
+	</head>
+	<body class="claro" style="background-image: url(images/master_detail.png)">
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - With repeat container.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		 <div id="leftNav">
+		 </div>
+		 <div id="mainContent">
+		 <!--
+			 The group container denotes some logical grouping of widgets and also serves
+			 to establish a parent data binding context for its children.
+			 The ref attribute for the outermost container obtains the binding from the
+			 "page scope" itself.
+		 -->
+		 <div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'searchRecords'">
+			<div class="row">
+				<label class="cell" for="queryInput">Search for:</label>
+				<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Query'"></input>
+				<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setSearchBanner();}">Search</button>
+			</div>
+			<div class="spacer"></div>
+
+			<div id="searchBanner">Search Results for term: Engineers</div>
+
+			<!--
+				The repeat container denotes a templated UI that operates over a collection
+				of data records.
+				The UI can be customized for each iteration using properties such as
+				${this.index} for the iteration index.
+			-->
+			<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
+				<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+					<label class="cell" for="nameInput${this.index}">Name:</label>
+					<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"></input>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+				</div>
+			</div>
+			<div class="spacer"></div>
+
+			<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Results'">
+				<div id="detailsBanner">Details for result index: 0</div>
+
+				<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
+					<div class="row">
+						<label class="cell" for="firstInput">First Name:</label>
+						<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
+					</div>
+					<div class="row">
+						<label class="cell" for="lastInput">Last Name:</label>
+						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
+					</div>
+<!--  				<div class="row">
+						<label class="cell" for="locationInput">Location:</label>
+						<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
+					</div>
+	-->							
+					<div class="row">
+						<label class="cell" for="officeInput">Office:</label>
+						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label>
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
+					</div>
+					<div class="row">
+						<label class="cell" for="telInput">Telephone:</label>
+						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
+					</div>
+					<div class="row">
+						<label class="cell" for="faxInput">Fax:</label>
+						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
+					</div>
+				</div>
+			</div>
+		   </div>
+		 </div>
+		</div>
+		<script type="text/javascript">
+			function setDetailsContext(index) {
+				var widget = dijit.byId("detailsGroup");
+				widget.set("ref", index);
+				var detailsBanner = dojo.byId("detailsBanner");
+				detailsBanner.innerHTML = "Details for result index: " + index;
+			}
+			function setSearchBanner() {
+				var searchBanner = dojo.byId("searchBanner");
+				searchBanner.innerHTML = "Search Results for term: " + searchRecords.Query.get("value");
+			}
+		</script>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_bindings-simple.html b/dojox/mvc/tests/1.7/test_mvc_bindings-simple.html
new file mode 100644
index 0000000..050091b
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_bindings-simple.html
@@ -0,0 +1,182 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Binding Test</title>
+
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:1" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+
+		var model; 
+
+		require([
+			'dojo/_base/kernel',
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dijit/form/ValidationTextBox',
+			'dijit/form/NumberTextBox',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(dojo, parser, ready, mvc){
+		  // The dojox.mvc.StatefulModel class creates a data model instance
+		  // where each leaf within the data model is decorated with dojo.Stateful
+		  // properties that widgets can bind to and watch for their changes.
+		  model = mvc.newStatefulModel({ data : 
+				{	"First" : "John", 
+					"Last" : "Doe", 
+					"Email" : "jdoe at example.com", 
+					"Num" : 3 
+				}
+			});
+		  console.log("model is ");
+		  console.log(model);
+
+			function testFirstRelevance(newValue) {
+			  //newValue = model.First.value;
+				if ( newValue !== "0" ) return true;
+				else return false;
+			}
+
+			function testFirstReadOnly(newValue) {
+				if ( newValue !== "2" && newValue !== "3"	 ) return false;
+				else return true;
+			}
+
+			function testNumValid(newValue) {
+				if ( newValue !== 1 && newValue !== "1"  && newValue !== "3") return true;
+				else return false;
+			}
+
+			function testRequired(newValue) {
+				if ( newValue !== 4 && newValue !== "4") return false;
+				else return true;
+			}
+
+			function testLastRelevance(newValue) {
+				//newValue = model.First.value;
+				if ( newValue !== "0" ) return true;
+				else return false;
+			}
+
+			function testLastValid(newValue) {
+				if ( newValue !== "1" ) return true;
+				else return false;
+			}
+		
+			function init(){
+				// bind tests, "read-only" etc.
+				mvc.bind(model.First, "value", model.First, "readOnly", testFirstReadOnly, true);
+				mvc.bind(model.First, "value", model.First, "relevant", testFirstRelevance, true);
+				mvc.bind(model.First, "value", model.First, "valid", testNumValid, true);
+				mvc.bind(model.Num, "value", model.Num, "valid", testNumValid, true);
+
+				// bind tests bind Last value to Email relevant and valid
+				mvc.bind(model.Last, "value", model.Email, "relevant", testFirstRelevance, true);
+				mvc.bind(model.Last, "value", model.Email, "valid", testNumValid, true);
+				mvc.bind(model.Last, "value", model.Email, "readOnly", testFirstReadOnly, true);
+				mvc.bind(model.Last, "value", model.Email, "required", testRequired, true);
+				mvc.bind(model.Last, "value", model.Email, "value");
+			}
+			ready(init);
+		});
+		
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Binding Tests</h1>
+		  </div>
+		</div>
+		<div id="main">
+		  <div id="leftNav">
+		  </div>
+		  <div id="mainContent">
+			<h2>Bind Self Tests</h2>
+			<div class="row">
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 0 to test for Relevant false (disabled) (use Reset to re-enable)</label>
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 1 to test for Valid false.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 2 to test for Read-only false (use Reset to re-enable)</label>
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 3 to test for Read-only false and Valid false (use Reset to re-enable)</label>
+			</div>
+			<div class="row">
+				<label class="cell" for="firstnameInput">First:</label>
+				<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.ValidationTextBox"
+									data-dojo-props="ref: model.First"></input>
+				<!-- Content in output below will always be in sync with value of textbox above -->
+				<span id="tout" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
+					(first name is: ${this.value})
+				</span>
+				
+			</div>
+		   <div class="row">
+				<label class="cell" for="firstnameInput"></label>
+				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
+					Relevant is:  ${this.ref.relevant}, Valid is: ${this.ref.valid}, Read-only is: ${this.ref.readOnly})
+				</span>			   
+			</div>
+			<div class="row">
+				<label style="display:inline-block; width:100%; text-align:left;">Num: Enter 1 for Valid false</label>
+			</div>
+			<div class="row">
+				<label class="cell" for="numInput">Num:</label>
+				<input class="cell" id="numInput" data-dojo-type="dijit.form.NumberTextBox"
+									data-dojo-props="ref: model.Num"></input>
+				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Num">
+					(num is: ${this.value})
+				</span>
+			</div>
+			<h2>Bind Tests</h2>
+			<div class="row">
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 0 to test for Relevant false (disabled) for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 1 to test for Valid false for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 2 to test for Read-only true for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 3 to test for Read-only true and Valid false for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 4 to test for Required true for Email.</label>
+			</div>			
+			
+			<div class="row">
+				<label class="cell" for="lastnameInput">Last:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Last"></input>
+				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Last">
+					(last name is: ${this.value})
+				</span>
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.ValidationTextBox"
+									data-dojo-props="ref: model.Email"></input>
+				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
+					(email is: ${this.value})
+				</span>
+			</div>
+		   <div class="row">
+				<label class="cell" for="emailInput"></label>
+				<span id="emailOut" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
+					Relevant is:  ${this.ref.relevant}, Valid is: ${this.ref.valid}, Read-only is: ${this.ref.readOnly}, Required is: ${this.ref.required})
+				</span>
+		   </div>
+			
+			<br/>Model:
+			<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){doReset()}">Reset</button>
+		  </div>
+		</div></div>
+		<script type="text/javascript">
+			function doReset() {
+				model.reset();
+			}
+		</script>
+		
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_dates.html b/dojox/mvc/tests/1.7/test_mvc_dates.html
new file mode 100644
index 0000000..5923be6
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_dates.html
@@ -0,0 +1,407 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>13899 mvc Stateful Dates</title>
+
+	<style>
+		@import "../../../../dijit/themes/claro/document.css";
+		@import "../../../../util/doh/robot/robot.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, parseOnLoad: false"></script>
+
+	<!-- only needed for alternate theme testing: -->
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+
+	<script type="text/javascript">
+	var model;
+			
+		require([
+			'dijit/form/DateTextBox',
+			'dijit/CalendarLite',
+			'dojox/mvc/StatefulModel',
+			'dijit/form/Button',
+			'dojox/mvc/Output',
+			'dijit/form/TextBox',
+			'dojo/date/stamp',
+			'dojox/mvc',
+			'dojo/on',
+			'dojo/domReady!'
+		], function (DateTextBox, Calendar, StatefulModel, Button, Output, TextBox, dateStamp) {
+
+			// *** Test1 setup begin: ***
+			var test1_init = dateStamp.fromISOString("1987-08-01"); // 8/1/1987
+			test1_model = new StatefulModel({
+				data: {
+					date: test1_init
+				}
+			});
+			var test1_cal = new Calendar({
+				ref: test1_model.date // bind to model.date
+			}, document.getElementById('test1_cal'));
+			test1_cal.startup();
+
+			var test1_cal2 = new Calendar({
+				ref: test1_model.date // bind to model.date
+			}, document.getElementById('test1_cal2'));
+			test1_cal2.startup();
+
+			var test1_txt2 = new TextBox({
+				ref: test1_model.date
+			}, document.getElementById('test1_txt2'));
+			dojo.style(test1_txt2.domNode, "width", "368px");
+			test1_txt2.startup();
+
+			var test1_out2 = new Output({
+				ref: test1_model.date // bind to model.date
+			}, document.getElementById('test1_output2'));
+			test1_out2.startup();
+
+			var test1_setday2 = new Button({
+				label: 'Set Calendar to dateStamp.fromISOString("1991-09-07") (Sep 7 1991)', 
+				onClick: function() {
+							//console.log("test1_setday2 called");
+							//var day2 = new Date(1991,9,7);  // 9/7/1991
+							//var day2 = new Date("1991-09-07");  // 9/7/1991
+							var day2 = dateStamp.fromISOString("1991-09-07"); // 9/7/1991
+							test1_cal2.set("value", day2);
+						} 
+			}, document.getElementById('test1_setdate1'));
+			test1_setday2.startup();
+
+			var test1_settext2 = new Button({
+				label: 'Set TextBox to dateStamp.fromISOString("1991-05-05") (May 5, 1991)', 
+				onClick: function() {
+							//test1_txt2.set("value", new Date("1993-05-05")); // ISO date format  
+							test1_txt2.set("value", dateStamp.fromISOString("1991-05-05")); // 5/5/1993
+							//test1_cal2.set("value", "1991-05-05"); 
+							//test1_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
+						} 
+			}, document.getElementById('test1_setdate2'));
+			test1_settext2.startup();
+
+			var test1_settext3 = new Button({
+				label: 'Set TextBox to ISO String("2011-11-06") (Nov 6, 2011) fails on IE', 
+				onClick: function() {
+							//test1_txt2.set("value", new Date("2011-11-07")); // ISO date format  
+							test1_txt2.set("value", "2011-11-07"); // 11/6/2011
+							//test1_cal2.set("value", "2011-11-07"); 
+							//test1_txt2.set("value", "Sun Nov 06 2011 01:00:00 GMT-0500 (Eastern Standard Time)");  
+						} 
+			}, document.getElementById('test1_setdate3'));
+			test1_settext3.startup();
+
+			var test1_reset2 = new Button({
+				label: "Reset Calendar back to (Aug 1 1987)",
+				onClick: function() {
+							test1_model.date.reset();
+						} 
+			}, document.getElementById('test1_reset2'));
+			test1_reset2.startup();
+			// *** Test1 setup end: ***
+
+			// *** Test2 setup begin: ***
+			var test2_init = dateStamp.fromISOString("2011-11-06"); // Nov 6, 2011
+			test2_model = new StatefulModel({
+				data: {
+					date: test2_init
+				}
+			});
+			var test2_cal = new DateTextBox({
+				ref: test2_model.date // bind to model.date
+			}, document.getElementById('test2_cal'));
+			test2_cal.startup();
+
+			var test2_cal2 = new DateTextBox({
+				ref: test2_model.date // bind to model.date
+			}, document.getElementById('test2_cal2'));
+			test2_cal2.startup();
+
+			var test2_txt2 = new TextBox({
+				ref: test2_model.date
+			}, document.getElementById('test2_txt2'));
+			dojo.style(test2_txt2.domNode, "width", "368px");
+			test2_txt2.startup();
+
+			var test2_out2 = new Output({
+				ref: test2_model.date // bind to model.date
+			}, document.getElementById('test2_output2'));
+			test2_out2.startup();
+
+			var test2_setday2 = new Button({
+				label: 'Set DateTextBox to new Date(1993,9,28) (Oct 28, 1993)', 
+				onClick: function() {
+							var day2 = new Date(1993,9,28);  // 10/28/1993
+							//var day2 = new Date("1993-10-28");  // 10/28/1993
+							//var day2 = dateStamp.fromISOString("1993-09-28"); // 10/28/1997
+							//test2_cal2.set("value", day2);
+							test2_txt2.set("value", day2);
+						} 
+			}, document.getElementById('test2_setdate1'));
+			test2_setday2.startup();
+
+			var test2_settext2 = new Button({
+				label: 'Set DateTextBox to dateStamp.fromISOString("1997-10-14") (Oct 14 1997)', 
+				onClick: function() {
+							//test2_txt2.set("value", new Date("1997-10-14")); // ISO date format  
+							test2_txt2.set("value", dateStamp.fromISOString("1997-10-14")); // Oct 14 1997
+							//test2_cal2.set("value", "1997-10-14"); 
+							//test2_txt2.set("value", "Tue Oct 14 1997 00:00:00 GMT-0400 (Eastern Daylight Time)");  
+						} 
+			}, document.getElementById('test2_setdate2'));
+			test2_settext2.startup();
+
+			var test2_reset2 = new Button({
+				label: "Reset DateTextBox back to (Nov 6 2011)",
+				onClick: function() {
+							test2_model.date.reset();
+						} 
+			}, document.getElementById('test2_reset2'));
+
+			var test2_settext3 = new Button({
+				label: 'Set TextBox to ISO String("1991-05-05") (May 5, 1991)', 
+				onClick: function() {
+							//test2_txt2.set("value", new Date("1991-05-05")); // ISO date format  
+							test2_txt2.set("value", "1991-05-05"); // 5/5/1993
+							//test2_cal2.set("value", "1991-05-05"); 
+							//test2_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
+						} 
+			}, document.getElementById('test2_setdate3'));
+			test2_settext3.startup();
+
+			test2_reset2.startup();
+			// *** Test2 setup end: ***
+
+
+			// *** Test3 setup begin: ***
+			// *** Test3 setup begin: ***
+			var test3_init = dateStamp.fromISOString("2011-08-27"); // 8/27/2011
+			test3_model = new StatefulModel({
+				data: {
+					date: test3_init,
+					date2: test3_init
+				}
+			});
+			var test3_cal = new Calendar({
+				ref: test3_model.date // bind to model.date
+			}, document.getElementById('test3_cal'));
+			test3_cal.startup();
+
+			var test3_cal2 = new DateTextBox({
+				ref: test3_model.date // bind to model.date
+			}, document.getElementById('test3_cal2'));
+			test3_cal2.startup();
+
+			var test3_txt2 = new TextBox({
+				ref: test3_model.date,
+				disabled: true
+			}, document.getElementById('test3_txt2'));
+			dojo.style(test3_txt2.domNode, "width", "368px");
+			test3_txt2.startup();
+
+			var test3_out2 = new Output({
+				ref: test3_model.date // bind to model.date
+			}, document.getElementById('test3_output2'));
+			test3_out2.startup();
+
+			var test3_setday2 = new Button({
+				label: 'Set Calendar to dateStamp.fromISOString("1997-10-14") (Oct 14 1997)', 
+				onClick: function() {
+							//console.log("test3_setday2 called");
+							//var day2 = new Date(1997,10,14);  // 10/14/1997
+							//var day2 = new Date("1997-10-14");  // 10/14/1997
+							var day2 = dateStamp.fromISOString("1997-10-14"); // 10/14/1997
+							test3_cal2.set("value", day2);
+						} 
+			}, document.getElementById('test3_setdate1'));
+			test3_setday2.startup();
+
+			var test3_settext2 = new Button({
+				label: 'Set TextBox to dateStamp.fromISOString("2011-11-06") (Nov 6, 2011)', 
+				onClick: function() {
+							//test3_txt2.set("value", new Date("2011-11-06")); // ISO date format  
+							test3_txt2.set("value", dateStamp.fromISOString("2011-11-06")); // 11/6/2011
+							//test3_cal2.set("value", "2011-11-06"); 
+							//test3_txt2.set("value", "2011-11-06"); // FAILS
+							//test3_txt2.set("value", "1991-05-06"); // 5/5/1991
+							//test3_txt2.set("value", "Sun Nov 06 2011 00:00:00 GMT-0400 (Eastern Daylight Time)");  
+						} 
+			}, document.getElementById('test3_setdate2'));
+			test3_settext2.startup();
+
+			var test3_settext3 = new Button({
+				label: 'Set TextBox to ISO String("1991-05-06T01:00:00") via new Date (May 5, 1991)', 
+				onClick: function() {
+							//test3_txt2.set("value", new Date("1991-05-05")); // ISO date format
+							var d = new Date("1991-05-06T01:00:00");  
+							test3_txt2.set("value", d); // 5/5/1991 YYYY-MM-DDThh:mm:ss via new Date
+							//test3_txt2.set("value", "1991-05-06T01:00:00"); // 5/5/1991 YYYY-MM-DDThh:mm:ss FAILS
+							//test3_cal2.set("value", "1991-05-05"); 
+							//test3_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
+						} 
+			}, document.getElementById('test3_setdate3'));
+			test3_settext3.startup();
+			if(dojo.isIE){ // new Date("1991-05-06") will not work on IE
+				test3_settext3.set('disabled',true);
+			}
+
+			var test3_reset2 = new Button({
+				label: "Reset Calendar back to (Aug 27 2011)",
+				onClick: function() {
+							//console.log("test3_callreset2 called");
+							test3_model.date.reset();
+						} 
+			}, document.getElementById('test3_reset2'));
+			test3_reset2.startup();
+			// *** Test3 setup end: ***
+
+
+
+			// *** Test4 setup begin: RegExp Test***
+			// *** Test4 setup begin: RegExp Test***
+			var regx = new RegExp("abc","i");			
+			test4_model = new StatefulModel({
+				data: {
+					//regex: /abc/i // should be regex: /abc/
+					regex: regx // should be regex: /abc/
+				}
+			});
+
+			console.log('test4_model.regex', test4_model.regex.get('value'));
+			var str = "ABCDEFGHIJKLMNOP abcdefghi";
+			var patt1 = test4_model.regex.get('value');
+			console.log("str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
+			console.log('str.match(patt1)',str.match(patt1));
+			test4_model.regex.set('value',/def/);
+			console.log("set to def str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
+			test4_model.regex.reset();
+			console.log("after reset str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
+			// *** Test4 setup end: ***
+	
+		});
+	</script>
+</head>
+
+<body class="claro">
+			<h2>Test 1: Two Calendars bound to each other, a TextBox and an mvc Output field.</h2>
+				<div  style="border-style: solid; border-width: 2px; width: 827px;">
+					<table>
+						<tbody>
+							<tr>
+								<td><div id="test1_cal"></div></td>
+								<td><div id="test1_cal2"></div></td>
+								<td>
+					<table><tbody>
+								<tr><td><label for="test1_txt2">TextBox bound to date:</label></td></tr>
+								<tr><td><div id="test1_txt2"></div></td></tr>
+								<tr><td><label for="test1_txt2">MVC Output bound to date:</label></td></tr>
+								<tr><td><div id="test1_output2"></div></td></tr>
+					</tbody></table>
+					<table><tbody><tr>
+								<td><div id="test1_setdate1"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test1_setdate2"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test1_setdate3"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test1_reset2"></div></td>
+					</tr></tbody></table>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+
+			<h2>Test 2: Two DateTextBoxes bound to each other, a TextBox and an mvc Output field.</h2>
+				<div  style="border-style: solid; border-width: 2px; width: 827px;">
+					<table>
+						<tbody>
+							<tr>
+								<td style="vertical-align: top;"><div id="test2_cal"></div></td>
+								<td style="vertical-align: top;"><div id="test2_cal2"></div></td>
+								<td>
+					<table><tbody>
+								<tr><td><label for="test2_txt2">TextBox bound to date:</label></td></tr>
+								<tr><td><div id="test2_txt2"></div></td></tr>
+								<tr><td><label for="test2_txt2">MVC Output bound to date:</label></td></tr>
+								<tr><td><div id="test2_output2"></div></td></tr>
+					</tbody></table>
+					<table><tbody><tr>
+								<td><div id="test2_setdate1"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test2_setdate2"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test2_setdate3"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test2_reset2"></div></td>
+					</tr></tbody></table>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+
+
+			<h2>Test 3: One Calendar bound to a DateTextbox, a TextBox and an mvc Output field.</h2>
+				<div  style="border-style: solid; border-width: 2px; width: 827px;">
+					<table>
+						<tbody>
+							<tr>
+								<td style="vertical-align: top;"><div id="test3_cal"></div></td>
+								<td style="vertical-align: top;"><div id="test3_cal2"></div></td>
+								<td>
+					<table><tbody>
+								<tr><td><label for="test3_txt2">TextBox bound to date: (disabled to avoid error)</label></td></tr>
+								<tr><td><div id="test3_txt2"></div></td></tr>
+								<tr><td><label for="test3_txt2">MVC Output bound to date:</label></td></tr>
+								<tr><td><div id="test3_output2"></div></td></tr>
+					</tbody></table>
+					<table><tbody><tr>
+								<td><div id="test3_setdate1"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test3_setdate2"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test3_setdate3"></div></td>
+					</tr></tbody></table>
+					<table><tbody><tr>
+								<td><div id="test3_reset2"></div></td>
+					</tr></tbody></table>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+	<!--  	  
+			<h2>I see these problems Binding a TextBox to DateTextBox and Calendar:</h2>
+				<div  style="border-style: solid; border-width: 2px; width: 827px;">
+				<span>There is also a problem when trying to set a date string in this format:</span><br>
+				<span>"Wed May 05 2010 01:00:00 GMT-0400 (Eastern Daylight Time)" into a  into a TextBox bound to a dijit.form.DateTextbox, but that works in a Calendar.</span><br>
+				<span>It is ending up with the DateTextBox set to null.  : </span><br>
+				<span></span><br>
+				<span>There is also a problem when trying to set a date ISO format date string like "1991-05-05":</span><br>
+				<span>"into a  into a TextBox bound to a Calendar, but that works for a dijit.form.DateTextbox.</span><br>
+				<span>It is loops for a while and gets range errors in the console.  : </span><br>
+				<span></span><br>
+				<span>Another thing I have found was that on a calendar I would get a different value from dijit.byId("cal").get('value') and dijit.byId("cal").value.</span><br>
+				<span>dijit.byId("cal").value:        Wed May 05 2010 <b>01:00:00</b> GMT-0400 (Eastern Daylight Time)</span><br>
+				<span>dijit.byId("cal").get('value'): Wed May 05 2010 <b>00:00:00</b> GMT-0400 (Eastern Daylight Time)</span><br>
+				<span>dijit.byId("cal").get('value') is getting 00:00:00 when it seems like it should be 01:00:00</span><br>
+				</div>
+	-->
+</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_form-kitchensink.html b/dojox/mvc/tests/1.7/test_mvc_form-kitchensink.html
new file mode 100644
index 0000000..3a8f385
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_form-kitchensink.html
@@ -0,0 +1,651 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Data-bound Form element Kitchen Sink test</title>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+			label {
+				text-align: left;
+				width: 100%;
+			}
+		</style>
+		<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:1" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+
+		var store, selmodel, decselmodel, numspinmodel; 
+		var store2, filmodel, decfilmodel;
+		var combomodel, deccombomodel;
+		var datemodel, decdatemodel; 
+		var slidermodel, decslidermodel;
+		var numspinmodel, decnumspinmodel;
+		var simpTAmodel, decsimpTAmodel;
+		var textareamodel, dectextareamodel;
+		var deccalmodel, deccolormodel;
+
+		require([
+			'dojo/_base/kernel',
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dijit/form/Select',
+			'dijit/form/FilteringSelect',
+			'dijit/form/ComboBox',
+			'dijit/form/DateTextBox',
+			'dijit/form/HorizontalSlider',
+			'dijit/form/NumberSpinner',
+			'dijit/form/SimpleTextarea',
+			'dijit/form/Textarea',
+			'dojo/data/ItemFileReadStore',
+			'dijit/Calendar',
+			'dijit/ColorPalette',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output',
+			'dojo/date/locale'
+			], function(dojo, parser, ready, mvc, TextBox, Button, Select, FilteringSelect, ComboBox, DateTextBox, HorizontalSlider, NumberSpinner,
+						SimpleTextarea, Textarea, ItemFileReadStore, Calendar, ColorPalette){
+
+			var alreadyset = false;	
+			var data = [
+				{id: '1',name:"one"},
+				{id: '2',name:"two"},
+				{id: '3',name:"three"},
+				{id: '4',name:"four"},
+				{id: '5',name:"five"},
+				{id: '6',name:"six"},
+				{id: '7',name:"seven"},
+				{id: '8',name:"eight"},
+				{id: '9',name:"nine"},
+				{id: '10',name:"ten"},
+				{id: '11',name:"eleven"},
+				{id: '12',name:"twelve"},
+				{id: '13',name:"thirteen"}
+			  ];
+			store = new ItemFileReadStore({
+				data: {
+					identifier: 'id',
+					label: 'name',
+					items: data
+				}
+			});
+
+			var data2 = {
+				identifier: "value",
+				label: "label",
+				items: [
+					{value: "1", label: "one"},
+					{value: "2", label: "two"},
+					{value: "3", label: "three"},
+					{value: "4", label: "four"},
+					{value: "5", label: "five"},
+					{value: "6", label: "six"},
+					{value: "7", label: "seven"},
+					{value: "8", label: "eigth"},
+					{value: "9", label: "nine"},
+					{value: "10", label: "ten"},
+					{value: "11", label: "eleven"},
+					{value: "12", label: "twelve"},
+					{value: "13", label: "thirteen"},
+					{value: "14", label: "fourteen"}
+				]
+			};
+			store2 = new ItemFileReadStore({data:dojo.clone(data2)});
+
+			// create models for selects
+			selmodel = new mvc.newStatefulModel({data: {number: '1'}});
+			decselmodel = new mvc.newStatefulModel({data: {number: '1'}});
+
+			// create models for filtering selects
+			filmodel = new mvc.newStatefulModel({data: {number: '2'}});
+			decfilmodel = new mvc.newStatefulModel({data: {number: '2'}});
+
+			// create models for ComboBoxes
+			combomodel = new mvc.newStatefulModel({data: {number: 'three'}});
+			deccombomodel = new mvc.newStatefulModel({data: {number: 'three'}});
+
+			// create a model for DateTextBox
+			datemodel = new mvc.newStatefulModel({data: {number: "2011-04-04"}});
+			decdatemodel = new mvc.newStatefulModel({data: {number: "2011-04-04"}});
+
+			// create a model for Slider
+			slidermodel = new mvc.newStatefulModel({data: {number: '5'}});
+			decslidermodel = new mvc.newStatefulModel({data: {number: '5'}});
+
+			// create a model for NumberSpinner
+			numspinmodel = new mvc.newStatefulModel({data: {number: '6'}});
+			decnumspinmodel = new mvc.newStatefulModel({data: {number: '6'}});
+
+			// create a model for SimpleTextArea
+			simpTAmodel = new mvc.newStatefulModel({data: {number: '7'}});
+			decsimpTAmodel = new mvc.newStatefulModel({data: {number: '7'}});
+
+			// create a model for TextArea
+			textareamodel = new mvc.newStatefulModel({data: {number: '8'}});
+			dectextareamodel = new mvc.newStatefulModel({data: {number: '8'}});
+
+			// create a model for dijit.Calendar
+			deccalmodel = new mvc.newStatefulModel({data: {date: "Mon Apr 04 2011 01:00:00 GMT-0400 (Eastern Daylight Time)"}});
+
+			// create a model for dijit.ColorPalette
+			deccolormodel = new mvc.newStatefulModel({data: {code: "#000000"}});
+
+			// Handle the programmatic creation of widgets here:
+			
+			// create the select, textbox, output and button			
+			var sel = new Select({
+				store: store,
+				loadChildrenOnOpen: true,
+			//	value: 1,	
+				ref: selmodel.number // bind to model.number
+			}, document.getElementById('sel'));
+			
+			var text = new TextBox({
+				//id: "seltext",
+				ref: selmodel.number
+			}, document.getElementById('seltext'));			
+			text.startup();
+			
+			var selOutput = new mvc.Output({
+				ref: selmodel.number
+			}, document.getElementById('selOutput'));
+			selOutput.startup();
+
+			var reset1 = new Button({
+				onClick: function(){selmodel.reset();},
+				id: "selReset",
+				label: "Reset"
+			}, document.getElementById('reset1'));
+			reset1.startup();
+
+
+			sel.watch('value', function () {
+				//console.log('sel value changed', arguments);
+			});
+
+			text.watch('value', function () {
+				//console.log('text value changed', arguments);
+			});
+			
+			sel.startup();
+			
+
+			// create the filtering select, textbox, output and button			
+			var filsel = new FilteringSelect({
+				store: store,
+				ref: filmodel.number // bind to model.number
+			}, document.getElementById('filsel'));
+			
+			var filtext = new TextBox({
+				ref: filmodel.number
+			}, document.getElementById('filtext'));
+			
+			var filoutput = new mvc.Output({
+				ref: filmodel.number
+			}, document.getElementById('filoutput'));			
+			filoutput.startup();
+
+			var filreset = new Button({
+				onClick: function(){filmodel.reset();},
+				id: "filReset",
+				label: "Reset"
+			}, document.getElementById('filreset'));
+			filreset.startup();
+			
+			filtext.startup();
+			filsel.startup();
+			
+			// create the comboBox, textbox, output and button			
+			var combo = new ComboBox({
+				store: store,
+				ref: combomodel.number // bind to model.number
+			}, document.getElementById('combosel'));
+			
+			var combotext = new TextBox({
+				ref: combomodel.number
+			}, document.getElementById('combotext'));
+			
+			var combooutput = new mvc.Output({
+				ref: combomodel.number
+			}, document.getElementById('combooutput'));			
+			combooutput.startup();
+
+			var comboreset = new Button({
+				onClick: function(){combomodel.reset();},
+				id: "comboReset",
+				label: "Reset"
+			}, document.getElementById('comboreset'));
+			comboreset.startup();
+			
+			combotext.startup();
+			combo.startup();
+			
+			// create the dijit.form.DateTextBox, textbox, output and button			
+			var dateWid = new DateTextBox({
+				ref: datemodel.number // bind to model.number
+			}, document.getElementById('datesel'));
+			
+			var datetext = new TextBox({
+				ref: datemodel.number
+			}, document.getElementById('datetext'));
+			
+			var dateoutput = new mvc.Output({
+				ref: datemodel.number
+			}, document.getElementById('dateoutput'));			
+			dateoutput.startup();
+
+			var datereset = new Button({
+				onClick: function(){datemodel.reset();},
+				id: "dateReset",
+				label: "Reset"
+			}, document.getElementById('datereset'));
+			datereset.startup();
+			
+			datetext.startup();
+			dateWid.startup();
+			
+			// create the dijit.form.HorizontalSlider, textbox, output and button			
+			var sliderWid = new HorizontalSlider({
+						style:{width:"190px"},
+						minimum:0,
+						maximum:100,
+						discreteValues:21,
+				ref: slidermodel.number // bind to model.number
+			}, document.getElementById('slidersel'));
+			
+			var slidertext = new TextBox({
+				ref: slidermodel.number
+			}, document.getElementById('slidertext'));
+			
+			var slideroutput = new mvc.Output({
+				ref: slidermodel.number
+			}, document.getElementById('slideroutput'));			
+			slideroutput.startup();
+
+			var sliderreset = new Button({
+				onClick: function(){slidermodel.reset();},
+				id: "sliderReset",
+				label: "Reset"
+			}, document.getElementById('sliderreset'));
+			sliderreset.startup();
+			
+			slidertext.startup();
+			sliderWid.startup();
+			
+			// create the dijit.form.NumberSpinner, textbox, output and button			
+			var numspinWid = new NumberSpinner({
+			//	constraints:{max:100,places:0},
+				ref: numspinmodel.number // bind to model.number
+			}, document.getElementById('numspinsel'));
+			
+			var numspintext = new TextBox({
+				ref: numspinmodel.number
+			}, document.getElementById('numspintext'));
+			
+			var numspinoutput = new mvc.Output({
+				ref: numspinmodel.number
+			}, document.getElementById('numspinoutput'));			
+			numspinoutput.startup();
+
+			var numspinreset = new Button({
+				onClick: function(){numspinmodel.reset();},
+				id: "numspinReset",
+				label: "Reset"
+			}, document.getElementById('numspinreset'));
+			numspinreset.startup();
+			
+			numspintext.startup();
+			numspinWid.startup();
+			
+			// create the dijit.form.SimpleTextarea, textbox, output and button 			
+			var simpTAWid = new SimpleTextarea({
+				style:{height:"20px", width:"180px"},
+				ref: simpTAmodel.number // bind to model.number
+			}, document.getElementById('simpTAsel'));
+			
+			var simpTAtext = new TextBox({
+				ref: simpTAmodel.number
+			}, document.getElementById('simpTAtext'));
+			
+			var simpTAoutput = new mvc.Output({
+				ref: simpTAmodel.number
+			}, document.getElementById('simpTAoutput'));			
+			simpTAoutput.startup();
+
+			var simpTAreset = new Button({
+				onClick: function(){simpTAmodel.reset();},
+				id: "simpTAReset",
+				label: "Reset"
+			}, document.getElementById('simpTAreset'));
+			simpTAreset.startup();
+			
+			simpTAtext.startup();
+			simpTAWid.startup();
+
+			// create the dijit.form.Textarea, textbox, output and button 
+			var textareaWid = new Textarea({
+			//	constraints:{max:100,places:0},
+				ref: textareamodel.number // bind to model.number
+			}, document.getElementById('textareasel'));
+			
+			var textareatext = new TextBox({
+				ref: textareamodel.number
+			}, document.getElementById('textareatext'));
+			
+			var textareaoutput = new mvc.Output({
+				ref: textareamodel.number
+			}, document.getElementById('textareaoutput'));			
+			textareaoutput.startup();
+
+			var textareareset = new Button({
+				onClick: function(){textareamodel.reset();},
+				id: "textareaReset",
+				label: "Reset"
+			}, document.getElementById('textareareset'));
+			textareareset.startup();
+			
+			textareatext.startup();
+			textareaWid.startup();
+
+			});
+
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+			<div id="header" style="margin-top: 0px;">
+				<div id="navigation"  style="margin-top: 0px;"></div>
+				<div id="headerInsert"  style="margin-top: 0px;">
+					<h2>Data-bound Form Element Kitchen Sink MVC test</h2>
+				</div>
+			</div>
+			<div id="main" style="margin-top: 0px;">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+	
+					<h2 style="margin-top: 0px;">Programmatic creation of Form elements:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+								<td><label for="sel">Select:</label></td>
+								<td><div id="sel"></div></td>
+								<td><div id="seltext"></div></td>
+								<td><div id="selOutput"></div></td>
+								<td><div id="reset1" ></div></td>
+							</tr>
+							<tr>
+								<td><label for="filsel">FilteringSelect:</label></td>
+								<td><div id="filsel"></div></td>
+								<td><div id="filtext"></div></td>
+								<td><div id="filoutput"></div></td>
+								<td><div id="filreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="combosel">ComboBox:</label></td>
+								<td><div id="combosel"></div></td>
+								<td><div id="combotext"></div></td>
+								<td><div id="combooutput"></div></td>
+								<td><div id="comboreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="datesel">DateTextBox:</label></td>
+								<td><div id="datesel"></div></td>
+								<td><div id="datetext"></div></td>
+								<td><div id="dateoutput"></div></td>
+								<td><div id="datereset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="slidersel">Slider:</label></td>
+								<td><div id="slidersel"></div></td>
+								<td><div id="slidertext"></div></td>
+								<td><div id="slideroutput"></div></td>
+								<td><div id="sliderreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="numspinsel">NumberSpinner:</label></td>
+								<td><div id="numspinsel"></div></td>
+								<td><div id="numspintext"></div></td>
+								<td><div id="numspinoutput"></div></td>
+								<td><div id="numspinreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="simpTAsel">SimpleTextArea:</label></td>
+								<td><div id="simpTAsel"></div></td>
+								<td><div id="simpTAtext"></div></td>
+								<td><div id="simpTAoutput"></div></td>
+								<td><div id="simpTAreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="textareasel">TextArea:</label></td>
+								<td><div id="textareasel"></div></td>
+								<td><div id="textareatext"></div></td>
+								<td><div id="textareaoutput"></div></td>
+								<td><div id="textareareset"></div></td>
+							</tr>
+						</tbody>
+					</table>
+	  
+					<h2>Declarative creation of Form elements:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+							<!--  <td><label for="decsel">Select:</label></td>
+								<td>
+									<select id="decsel" style="width: 188px;" 
+													data-dojo-id="decsel" data-dojo-type="dijit.form.Select" 
+													data-dojo-props='name:"decsel",loadChildrenOnOpen: true, ref: decselmodel.number '>
+										<option value="1">one</option>
+										<option value="2">two</option>
+										<option value="3">three</option>
+										<option value="4">four</option>
+									</select>
+								</td>
+							-->	
+								<td><label for="decsel">Select:</label></td>
+								<td>
+									<select id="decsel" style="width: 188px;" 
+													data-dojo-id="decsel" data-dojo-type="dijit.form.Select" 
+													data-dojo-props='store:store, name:"decsel",loadChildrenOnOpen: true, ref: decselmodel.number '>
+									</select>
+								</td>
+								<td>
+									<input class="cell" id="decseltext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decselmodel.number"></input>
+								</td>
+								<td><span   id="decselOutput" data-dojo-type="dojox.mvc.Output"
+											data-dojo-props="ref: decselmodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="decselReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decselmodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decfilsel">FilteringSelect:</label></td>
+								<td>
+									<input id="decfilsel" data-dojo-type="dijit.form.FilteringSelect"
+										data-dojo-props='store:store, ref: decfilmodel.number'/>
+								</td>
+								<td>
+									<input id="decfiltext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decfilmodel.number"></input>
+								</td>
+								<td><span id="decfilOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: decfilmodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="decfilReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decfilmodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="deccombosel">ComboBox:</label></td>
+								<td>
+									<input id="deccombosel" data-dojo-type="dijit.form.ComboBox"
+										data-dojo-props='store:store, ref: deccombomodel.number'/>
+								</td>
+								<td>
+									<input id="deccombotext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: deccombomodel.number"></input>
+								</td>
+								<td><span id="deccomboOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: deccombomodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="deccomboReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){deccombomodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="datesel">DateTextBox:</label></td>
+								<td>
+									<input id="decdatesel" data-dojo-type="dijit.form.DateTextBox"
+										data-dojo-props='store:store, ref: decdatemodel.number'/>
+								</td>
+								<td>
+									<input id="decdatetext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decdatemodel.number"></input>
+								</td>
+								<td><span id="decdateOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: decdatemodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="decdateReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decdatemodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decslidersel">Slider:</label></td>
+								<td>
+									<input id="decslidersel" data-dojo-type="dijit.form.HorizontalSlider"
+										data-dojo-props='store:store, ref: decslidermodel.number,
+														style:{width:"190px"}, minimum:0, maximum:100, discreteValues:21'/>
+								</td>
+								<td>
+									<input id="decslidertext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decslidermodel.number"></input>
+								</td>
+								<td><span id="decsliderOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: decslidermodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="decsliderReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decslidermodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decnumspinsel">NumberSpinner:</label></td>
+								<td>
+									<input id="decnumspinsel" data-dojo-type="dijit.form.NumberSpinner"
+										data-dojo-props='store:store, ref: decnumspinmodel.number'/>
+								</td>
+								<td>
+									<input id="decnumspintext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decnumspinmodel.number"></input>
+								</td>
+								<td><span id="decnumspinOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: decnumspinmodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="decnumspinReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decnumspinmodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decsimpTAsel">SimpleTextArea:</label></td>
+								<td>
+									<input id="decsimpTAsel" data-dojo-type="dijit.form.Textarea"
+										data-dojo-props='store:store, ref: decsimpTAmodel.number'/>
+								</td>
+								<td>
+									<input id="decsimpTAtext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: decsimpTAmodel.number"/>
+								</td>
+								<td><span id="decsimpTAOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: decsimpTAmodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="decsimpTAReset" type="button" data-dojo-type="dijit.form.Button" 
+										data-dojo-props="onClick: function(){decsimpTAmodel.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="dectextareasel">TextArea:</label></td>
+								<td>
+									<input id="dectextareasel" data-dojo-type="dijit.form.Textarea"
+										data-dojo-props='store:store, ref: dectextareamodel.number'/>
+								</td>
+								<td>
+									<input id="dectextareatext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: dectextareamodel.number"/>
+								</td>
+								<td><span id="dectextareaOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="ref: dectextareamodel.number">
+						 			${this.value}
+								</span></td>
+								<td><button id="dectextareaReset" type="button" data-dojo-type="dijit.form.Button" 
+										data-dojo-props="onClick: function(){dectextareamodel.reset();}">Reset</button></td>
+							</tr>
+						</tbody>
+					</table>
+	  
+					<h2>Test data-bound dijit.Calendar:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+								<td><label for="deccal">Calendar:</label></td>
+								<td>
+									<input class="cell"  id="deccal" data-dojo-id="deccal"  data-dojo-type="dijit.Calendar" 
+											data-dojo-props='ref: deccalmodel.date '/>
+								</td>
+								<td>
+									<input class="cell" id="deccaltext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: deccalmodel.date"></input>
+								</td>
+								<td><span   id="deccalOutput" data-dojo-type="dojox.mvc.Output"
+											data-dojo-props="ref: deccalmodel.date">
+						 			${this.value}
+								</span></td>
+								<td><button id="deccalReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){deccalmodel.date.set('value', 'Mon Apr 04 2011 01:00:00 GMT-0400 (Eastern Daylight Time)')/*deccalmodel.reset();*/}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="deccolor">ColorPalette:</label></td>
+								<td>
+									<div id="deccolor" data-dojo-type="dijit.ColorPalette" 
+											data-dojo-props='palette:"3x4", ref: deccolormodel.code'></div>								
+								</td>
+								<td>
+									<input class="cell" id="deccolortext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: deccolormodel.code"></input>
+								</td>
+								<td><span   id="deccolorOutput" data-dojo-type="dojox.mvc.Output"
+											data-dojo-props="ref: deccolormodel.code">
+						 			${this.value}
+								</span></td>
+								<td><button id="deccolorReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){deccolormodel.reset();}">Reset</button></td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_generate-view-store.html b/dojox/mvc/tests/1.7/test_mvc_generate-view-store.html
new file mode 100644
index 0000000..051a590
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_generate-view-store.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>View generation -- Model-bound generation example with a store, commit and reset</title>
+
+		<script src="../../../../dojo/dojo.js"
+				type="text/javascript"
+				djConfig="isDebug: true, parseOnLoad: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";			
+		</style>
+		<script type="text/javascript" >
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Generate");
+			dojo.require("dijit.form.Textarea");
+			dojo.require("dijit.form.Button");
+			dojo.require("dojo.data.ItemFileReadStore");
+			dojo.require("dojo.data.ItemFileWriteStore");
+			dojo.require("dojo.store.DataStore");
+			dojo.require("dojo.parser");
+
+			var model;
+
+			function setup(){
+				var theWriteStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests._data", "mvcGenerateData.json")});
+				// this is used to see what would have been written out if we were using a real service
+				theWriteStore._saveEverything = function(c, e, n){
+					console.log(n);
+					c.call();
+				};
+				var theDataStore = new dojo.store.DataStore({store: theWriteStore});
+				var theModelPromise = dojox.mvc.newStatefulModel({store: theDataStore});  // query() returns a deferred.promise
+				theModelPromise.then(function(theStatefulModel){
+					model = theStatefulModel;
+					dijit.byId("view").set("ref", "model");
+				});
+			};
+
+			dojo.addOnLoad(setup);
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>View generation example</h1>
+			<h2>Data Binding - Generate Container, with a store, commit and reset.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		  <div id="leftNav">
+		  </div>
+			<div id="mainContent">
+				<h3>Generated View</h3>
+				<div id="view" data-dojo-type="dojox.mvc.Generate">
+				</div>
+				<div class="row">
+					<div class="spacer"></div>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.commit();}">Commit</button>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+				</div>
+			</div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_generate-view.html b/dojox/mvc/tests/1.7/test_mvc_generate-view.html
new file mode 100644
index 0000000..ebf36a2
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_generate-view.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>View generation -- Model-bound generation example</title>
+	
+		<script src="../../../../dojo/dojo.js"
+				type="text/javascript"
+				djConfig="isDebug: true, parseOnLoad: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";			
+		</style>
+		<script type="text/javascript" >
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Generate");
+			dojo.require("dijit.form.Textarea");
+			dojo.require("dojo.parser");
+	
+			function updateView() {
+				var modeldata = dojo.fromJson(dijit.byId("modelArea").value);
+				var model = dojox.mvc.newStatefulModel({ data : modeldata });
+				dijit.byId("view").set("ref", model);
+			};
+		dojo.addOnLoad(updateView);
+	   </script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+				<h1>View generation example</h1>
+				<h2>Data Binding - Generate Container.</h2>
+			</div>
+		</div>
+		<div id="main">
+			<div id="leftNav"></div>
+			<div id="mainContent">
+				<h3>Model</h3>
+				<div class="row">
+					<textarea class="cell" data-dojo-type="dijit.form.Textarea" id="modelArea" data-dojo-props="onBlur: updateView">
+{
+    "Serial" : "360324",
+    "First"  : "John",
+    "Last"   : "Doe",
+    "Email"  : "jdoe at example.com",
+    "Address": {
+        "Street" : "123 Valley Rd",
+        "City"   : "Katonah",
+        "State"	 : "NY",
+        "Zip"    : "10536"
+    },
+    "Phones" : [{
+        "Areacode" : "111",
+        "Local"	   : "111-1111"
+    },{
+        "Areacode" : "222",
+        "Local"	   : "222-2222"
+    }],
+    "Member" : {
+        "Since"	 : "2010",
+        "Type"   : "Gold"
+    }
+}
+					</textarea>
+					</div>
+					<h3>Generated View</h3>
+					<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="idNameMapping:{'String' : 'view_t'}"></div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_input-output-simple.html b/dojox/mvc/tests/1.7/test_mvc_input-output-simple.html
new file mode 100644
index 0000000..b48bbee
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_input-output-simple.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+			.row { width: 500px; display: inline-block; margin: 5px; }
+			.cell { width: 20%;  display:inline-block; }
+			.textcell { width: 30%;  display:inline-block; }
+		</style>
+		<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:1" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			var model;
+ 
+			require([
+				'dojo/parser',
+				'dojox/mvc',
+				'dijit/form/TextBox',
+				'dijit/form/Button',
+				'dojox/mvc/Group',
+				'dojox/mvc/Output'
+			], function(parser, mvc){
+				// The dojox.mvc.StatefulModel class creates a data model instance
+				// where each leaf within the data model is decorated with dojo.Stateful
+				// properties that widgets can bind to and watch for their changes.
+				model = mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
+				// the StatefulModel created above is initialized with 
+				// model.First set to "John", model.Last set to "Doe" and model.Email set to "jdoe at example.com"				
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="row">
+						<label class="cell" for="firstId">First:</label>
+						<input class="textcell" id="firstId" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.First"></input>
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
+						(first name is: ${this.value})
+						</span>
+					</div>
+				<div class="row">
+					<label class="cell" for="lastnameInput">Last:</label>
+					<input class="textcell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Last"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Last">
+						(last name is: ${this.value})
+					</span>
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="textcell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: model.Email"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
+					(email is: ${this.value})
+					</span>
+				</div>
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" 
+							data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+					<button id="fromModel" type="button" data-dojo-type="dijit.form.Button" 
+							data-dojo-props="onClick: 
+							function(){model.First.set('value','Updated in Model');}">Update First from Model</button>
+					<button id="fromWidget" type="button" data-dojo-type="dijit.form.Button" 
+							data-dojo-props="onClick: 
+							function(){dijit.byId('firstId').set('value','Updated Widget');}">Update First from Widget</button>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_loan-stateful.html b/dojox/mvc/tests/1.7/test_mvc_loan-stateful.html
new file mode 100644
index 0000000..6cfb1fb
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_loan-stateful.html
@@ -0,0 +1,187 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Loan Form (Using DOJO within MVC Support)</title>
+	
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:1" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+
+		var loanModel; 
+
+		require([
+			'dojo/_base/kernel',
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc',
+			'dojox/mvc/tests/1.7/models/LoanWizardModel',			
+			'dojox/charting/DataChart',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dijit/form/ValidationTextBox',
+			'dijit/form/NumberTextBox',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(dojo, parser, ready, mvc, LoanWizardModel, DataChart){
+	
+			var loan_init = {
+				"Name"            : "John Doe",
+				"Street"          :  "",
+				"City"            :  "",
+				"County"          :  "",
+				"State"           :  "",
+				"Zip"             :  "",
+				"Country"         :  "US",
+				"TotalIncome"     :  "0",
+				"BaseIncome"      :  "50000",
+				"BonusIncome"     :  "10000",
+				"TotalHousing"    :  "0",
+				"HousingPercent"  :  "0",
+				"Mortgage"        :  "1000",
+				"Taxes"           :  "500",
+				"OtherHousing"    :  "1200"
+			};
+			loanModel = new LoanWizardModel({ data: loan_init });
+	
+			function createChart() {
+				var chart = new DataChart("expenseChart", {
+					store: loanModel.chartStore,
+					comparative: true,
+					type: dojox.charting.plot2d.Pie,
+					query: { "x":"*" },
+					fieldName:"y"
+				});
+			};
+			ready(createChart);
+		});
+			
+		</script>    
+	</head>
+	<body class="claro" style="background-image: url(images/validating_form_pattern.png)">
+	<div id="wrapper">
+	<div id="header">
+		<div id="navigation">
+		</div>
+		<div id="headerInsert">
+			<h1>Big Red Loan</h1>
+			<h2>The one to choose when you're in the red...</h2>
+		</div>
+	</div>		 
+	<div id="main">
+		<div id="leftNav"></div>
+		<div id="mainContent">
+			<h3>Borrower information</h3>
+			<hr size="6" class="rule"/>
+			<div class="spacer"></div>
+			<div class="row">
+			<div class="cell"><label for="borrowerInput">Name:</label></div>
+				<div class="cell">
+					<input id="borrowerInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'loanModel.Name'"/>
+				</div>
+			</div>
+			<div class="row">
+			<div class="cell"><label for="zipInput">Zipcode (try 10706):</label></div>
+				<div class="cell">
+				    <input id="zipInput" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.Zip'"
+		               constraints="{pattern:'#'}" regExp="\d{5}" required="true" invalidMessage="Invalid Zip Code."/>
+				</div>
+			</div>
+			<div class="row">
+			<div class="cell"><label for="cityInput">City:</label></div>
+				<div class="cell">
+					<input id="cityInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'loanModel.City'"/>
+				</div>
+			</div>
+			<div class="row">
+			<div class="cell"><label for="countyInput">County:</label></div>
+				<div class="cell">
+					<input id="countyInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'loanModel.County'"/>
+				</div>
+			</div>
+			<div class="row">
+			<div class="cell"><label for="stateInput">State:</label></div>
+				<div class="cell">
+					<input id="stateInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'loanModel.State'"/>
+				</div>
+			</div>
+			<div class="spacer"></div>
+
+			<h3>Expenses</h3>
+			<hr size="6" class="rule"/>
+			<div class="spacer"></div>
+			<table style="width:900px;">
+			<tr style="width:900px;">
+			<td style="width:400px;">
+			<div class="row">
+			<div class="cell"><label for="housing">Mortgage:</label></div>
+				<div class="cell">
+					<input id="housing" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.Mortgage'"/>
+			</div>
+			</div>
+			<div class="row">
+				<div class="cell">
+					<label>Real Estate Taxes:</label>
+				</div>
+				<div class="cell">
+					<input id="taxes" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.Taxes'"/>
+				</div>
+			</div>
+			<div class="row">
+			<div class="cell"><label>Other Housing:</label></div>
+				<div class="cell">
+					<input id="otherHousing" type="text" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.OtherHousing'"/>
+				</div>
+			</div>
+			<div class="row">
+			<div class="cell"><label for="transportation">Total Housing:</label></div>
+				<div class="cell">
+					<input id="totalHousing" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.TotalHousing'"/>
+			</div>
+			</div>
+			</td>
+			<td style="width:200px;">
+				<div id="expenseChart" width="150" height="150" style="display:block; width: 150px; height: 150px;"></div>
+			</td>
+			</tr>
+			</table>
+			
+			<h3>Income</h3>
+			<hr size="6" class="rule"/>
+			<div class="spacer"></div>
+			<div class="row">
+			<div class="cell"><label for="baseIncome">Base Income:</label></div>
+				<div class="cell">
+					<input id="baseIncome" type="text" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.BaseIncome'"/>
+				</div>
+			</div>
+			<div class="row">
+			<div class="cell"><label>Bonus Income:</label></div>
+				<div class="cell">
+					<input id="bonusIncome" type="text" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.BonusIncome'"/>
+				</div>
+			</div>
+			<div class="row">
+			<div class="cell"><label for="total">Total Income:</label></div>
+				<div class="cell">
+					<input id="total" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.TotalIncome'"/>
+				</div>
+			</div>
+			<h3>Analysis</h3>
+			<hr size="6" class="rule"/>
+			<div class="spacer"></div>
+			<div class="row">
+			<div class="cell"><label for="percentHousing">Percent housing (under 33%):</label></div>
+				<div class="cell">
+					<input id="percentHousing" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.HousingPercent'"
+					    invalidMessage="Housing should be less than 1/3 total expenses!"/>
+				</div>
+			</div>
+		</div>
+	</div>
+	</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_prog_repeat.html b/dojox/mvc/tests/1.7/test_mvc_prog_repeat.html
new file mode 100644
index 0000000..368e3be
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_prog_repeat.html
@@ -0,0 +1,219 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>13899 mvc Stateful Dates</title>
+
+	<style>
+		@import "../../../../dijit/themes/claro/document.css";
+		@import "../../../util/doh/robot/robot.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+		.cell { display:inline-block; }	
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, parseOnLoad: false"></script>
+
+	<!-- only needed for alternate theme testing: -->
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+
+	<script type="text/javascript">
+	var model;
+			
+		require([
+			'dojo/parser',
+			'dojox/mvc',
+			'dojo/store/Memory',
+			'dijit/form/DateTextBox',
+			'dijit/CalendarLite',
+			'dojox/mvc/StatefulModel',
+			'dojox/mvc/Repeat',
+			'dojox/mvc/Group',
+			'dojox/mvc/at',
+			'dijit/registry',
+			'dijit/form/Button',
+			'dojox/mvc/Output',
+			'dijit/form/TextBox',
+			'dojo/date/stamp',
+			'dojo/dom',
+			'dojo/dom-construct',			
+			'dojo/on',
+			'dojo/domReady!'
+		], function (parser, mvc, Memory, DateTextBox, Calendar, StatefulModel, Repeat, Group, 
+					at, registry, Button, Output, TextBox, dateStamp, dom, domconstruct) {
+			window.at = at;
+
+			// *** Test1 setup begin: ***
+			var search_results_init1 =
+				[{
+					"Query" : "Engineers1",
+					"Results" : [
+						{
+							"First"	  : "Anne1",
+							"Last"	  : "Ackerman1"
+						},
+						{
+							"First"	  : "Ben1",
+							"Last"	  : "Beckham1"
+						},
+						{
+							"First"	  : "Chad1",
+							"Last"	  : "Chapman1"
+						}
+					]
+				}];
+				var search_results_init2 =
+				[{
+					"Query" : "Engineers2",
+					"Results" : [
+						{
+							"First"	  : "Anne2",
+							"Last"	  : "Ackerman2"
+						},
+						{
+							"First"	  : "Ben2",
+							"Last"	  : "Beckham2"
+						}
+					]
+				}];
+				var search_results_init3 =
+				[{
+					"Query" : "Engineers3",
+					"Results" : [
+						{
+							"First"	  : "Chad3",
+							"Last"	  : "Chapman3"
+						}
+					]
+				}];
+
+				var memStore1 = new Memory({data : search_results_init1});
+				model1 = mvc.newStatefulModel({ store : memStore1 })[0];
+				var memStore2 = new Memory({data : search_results_init2});
+				model2 = mvc.newStatefulModel({ store : memStore2 })[0];
+				var memStore3 = new Memory({data : search_results_init3});
+				model3 = mvc.newStatefulModel({ store : memStore3 })[0];
+
+			templateString = '<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: \'${this.index}\'">' +
+				'<label class="cell">Name:</label>' + 
+				'<input class="cell" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: \'First\'"></input>' +
+				'<div  class="cell"  data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: \'Last\'"></div>' +
+				'</div>';
+
+			// I would like to be able to programmatically create the widgets
+			// which would go into the repeat, but that is not possible now given the way the
+			// repeat parses it's content when it is built
+			
+			// need to parse the declarative swap buttons 
+			parser.parse("swapbuttons2");
+
+			var swapb1 = new Button({
+				onClick: function(){swapToModel(model1);},
+				id: "swapbutton1",
+				label: "Swap Model1"
+			}, document.getElementById('swapbutton1'));
+			swapb1.startup();
+
+			var swapb2 = new Button({
+				onClick: function(){swapToModel(model2);},
+				id: "swapbutton2",
+				label: "Swap Model2"
+			}, document.getElementById('swapbutton2'));
+			swapb2.startup();
+			
+			var swapb3 = new Button({
+				onClick: function(){swapToModel(model3);},
+				id: "swapbutton3",
+				label: "Swap Model3"
+			}, document.getElementById('swapbutton3'));
+			swapb3.startup();
+			
+			var test2_repeat = new Repeat({
+					ref: model1.Results
+			}, document.getElementById('test2_repeat'));
+			test2_repeat.startup();
+			
+			var test3_repeat = new Repeat({
+					children: at(model1, 'Results')
+			}, document.getElementById('test3_repeat'));
+			test3_repeat.startup();
+			
+			var test1_repeat = new Repeat({
+					templateString: templateString, // not needed with my.Repeat since it is set there.
+					ref: model1.Results
+			}, document.getElementById('test1_repeat'));
+			test1_repeat.startup();
+
+		});
+
+		// called to reset the model for each of the repeats
+		//function swapToModel(model) {
+		//	console.log("called with "+model);
+		//}
+	</script>
+</head>
+
+<body class="claro">
+	<h2>Test 1: A programmatic repeat using a Template with a textbox and an mvc output field.</h2>
+	<div  style="border-style: solid; border-width: 2px; width: 827px;">
+		<div id="test1_repeat">
+		</div>
+	</div>
+
+	<h2>Test 2: A programmatic repeat with the html inline with an mvc output field and a textbox.</h2>
+	<div  style="border-style: solid; border-width: 2px; width: 827px;">
+		<div id="test2_repeat">
+			<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+				<label class="cell">Name:</label> 
+				<div class="cell" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'First'"></div>
+				<input  class="cell"  data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
+			</div>	
+		</div>
+	</div>
+
+	<h2>Test 3: A programmatic repeat with the html inline using mvc.at.</h2>
+	<div  style="border-style: solid; border-width: 2px; width: 827px;">
+		<div id="test3_repeat">
+			<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:${this.index}')">
+				<label class="cell">Name:</label> 
+				<input  class="cell"  data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:First', 'value')"></input>
+				<input  class="cell"  data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:Last', 'value')"></input>
+			</div>	
+		</div>
+	</div>
+
+	<h2>Test 4: Programmatic Swap models, this one is done by swapping between different models, I would like to be able to update the model data without replacing the model.</h2>
+	<div id="swapbuttons" class="row">
+		<div id="swapbutton1" ></div>
+		<div id="swapbutton2" ></div>
+		<div id="swapbutton3" ></div>
+	</div>
+
+	<h2>Test 5: Swap models, (these are declarative buttons) this one is done by swapping between different models, I would like to be able to update the model data without replacing the model.</h2>
+	<div id="swapbuttons2" class="row">
+		<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){swapToModel(model1);}">Swap Model1</button>
+		<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){swapToModel(model2);}">Swap Model2</button>
+		<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){swapToModel(model3);}">Swap Model3</button>		
+	</div>
+
+	
+	<script type="text/javascript">
+	function swapToModel(model) {
+		require([
+			"dijit/registry",
+			"dojox/mvc/at"
+		], function(registry, at){
+			var widget = registry.byId("test1_repeat");
+			widget.set("ref", model.Results);
+			registry.byId("test2_repeat").set("ref", model.Results);
+			registry.byId("test3_repeat").set("children", at(model, 'Results'));
+		});
+	}
+</script>
+	
+</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_programmatic-repeat-store.html b/dojox/mvc/tests/1.7/test_mvc_programmatic-repeat-store.html
new file mode 100644
index 0000000..76e0b13
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_programmatic-repeat-store.html
@@ -0,0 +1,147 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Programmatic Repeat example, using a store with save, commit and reset</title>
+
+		<script src="../../../../dojo/dojo.js"
+			type="text/javascript"
+			djConfig="parseOnLoad: false, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Group");
+			dojo.require("dojox.mvc.Repeat");
+			dojo.require("dijit.form.TextBox");
+			dojo.require("dijit.form.Button");
+			dojo.require("dojo.data.ItemFileWriteStore");
+			dojo.require("dojo.store.DataStore");
+			dojo.require("dojo.parser");
+
+			var results, selectedIndex = 0;
+				// declared here for convenience
+			templateString = '<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: \'${this.index}\'">' +
+							'<label class="cell">Name:</label>' + 
+							'<input class="cell" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: \'First\'"></input>' +
+							'<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext(\'${this.index}\');}">Details</button>' +
+						'</div>';
+
+			function setup() {
+				var writeStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests._data", "mvcRepeatData.json")});
+				var modelPromise = dojox.mvc.newStatefulModel({store: new dojo.store.DataStore({store: writeStore})}); 
+				modelPromise.then(function(model){ 
+					results = model;
+					dojo.parser.parse();
+
+					// Can test with either the dojox.mvc.Repeat or my.Repeat
+					var repeat = new my.Repeat({
+					//var repeat = new dojox.mvc.Repeat({
+					//	templateString: templateString, // not needed with my.Repeat since it is set there.
+						ref: model
+					}).placeAt('repeat2');
+					repeat.startup();
+				});
+			};
+
+			dojo.declare('my.Repeat', [dojox.mvc.Repeat], {
+				templateString : templateString
+			});
+			dojo.addOnLoad(setup);
+		</script>
+	</head>
+	<body class="claro" style="background-image: url(images/master_detail.png)">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation">
+				</div>
+				<div id="headerInsert">
+				<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav">
+				</div>
+				<div id="mainContent">
+					<div id="searchBanner">Search Results for term: </div>         
+					<!--
+						The repeat container denotes a templated UI that operates over a collection
+						of data records.
+						The UI can be customized for each iteration using properties such as
+						${this.index} for the iteration index.
+					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results', templateString: templateString"></div>
+					<div id="repeatId" data-dojo-type="my.Repeat" data-dojo-props="ref: 'results'"></div>
+					-->
+					<table><tbody><tr>
+								<td>
+									<div>
+										<div>Programatic Repeat using my.Repeat and its templateString: </div>         
+										<div id="repeat2"></div>
+									</div>
+								</td>
+								<td>
+									<div>
+										<div>Declarative Repeat using my.Repeat does not pass templateString: </div>         
+										<div id="repeatId2" data-dojo-type="my.Repeat" data-dojo-props="ref: 'results'"></div>
+									</div>
+								</td>
+					</tr></tbody></table>
+					
+					<div class="spacer"></div>
+
+					<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results'">
+						<div id="detailsBanner">Details for selected index:</div>
+
+						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
+							<div class="row">
+								<label class="cell" for="firstInput">First Name:</label>
+								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="lastInput">Last Name:</label>
+								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="locationInput">Location:</label>
+								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="officeInput">Office:</label>
+								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="emailInput">Email:</label>
+								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="telInput">Telephone:</label>
+								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="faxInput">Fax:</label>
+								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
+							</div>
+							<div class="row">
+							<div class="spacer"></div>
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results[selectedIndex].toPlainObject());results[selectedIndex].commit();}">Save Item</button>        
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.toPlainObject());results.commit();;}">Commit All</button>        
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.reset();}">Reset to last saved</button>        
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+        </div>
+        <script type="text/javascript">
+			// called to change the selected item
+			function setDetailsContext(index) {
+				selectedIndex = index;
+				var widget = dijit.byId("detailsGroup");
+				widget.set("ref", index);
+			};
+        </script>
+    </body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_ref-kitchensink.html b/dojox/mvc/tests/1.7/test_mvc_ref-kitchensink.html
new file mode 100644
index 0000000..6093850
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_ref-kitchensink.html
@@ -0,0 +1,160 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Data binding -- Ref kitchen sink example</title>
+
+		<script src="../../../../dojo/dojo.js"
+				type="text/javascript"
+				djConfig="parseOnLoad: true, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+		  dojo.require("dojox.mvc");
+		  dojo.require("dojox.mvc.Group");
+		  dojo.require("dijit.form.TextBox");
+		  dojo.require("dijit.form.Button");
+		  dojo.require("dojo.parser");
+
+		  // Initial data
+		  var order = {
+			  "Serial" : "360324",
+			  "First"  : "John",
+			  "Last"   : "Doe",
+			  "Email"  : "jdoe at example.com",
+			  "ShipTo" : {
+				  "Street" : "123 Valley Rd",
+				  "City"   : "Katonah",
+				  "State"  : "NY",
+				  "Zip"	   : "10536"
+			  },
+			  "BillTo" : {
+				  "Street" : "17 Skyline Dr",
+				  "City"   : "Hawthorne",
+				  "State"  : "NY",
+				  "Zip"	   : "10532"
+			  }
+		  };
+
+		  // This example is an odd mix of everything, being the kitchen sink example :-)
+
+		  // The dojox.mvc.StatefulModel class creates a data model instance, which will be
+		  // shared by widgets being instantiated programmatically as well as
+		  // declaratively
+		  var model = dojox.mvc.newStatefulModel({ data : order });
+
+		  // Here is programmatic data bound widget instantiation
+		  function addBoundDijits(){
+			  // Absolute ref, passed as object
+			  var serial = new dijit.form.TextBox({id: "serialInput", ref: model.Serial});
+			  serial.placeAt(dojo.byId("serialDiv"));
+			  serial.startup();
+
+			  // Relative refs, passed as strings
+			  var fn = new dijit.form.TextBox({id: "firstnameInput", ref: "First"});
+			  fn.placeAt(dojo.byId("firstnameDiv"));
+			  fn.startup();
+			  var ln = new dijit.form.TextBox({id: "lastnameInput", ref: "Last"});
+			  ln.placeAt(dojo.byId("lastnameDiv"));
+			  ln.startup();
+		  }
+
+		  dojo.addOnLoad(addBoundDijits);
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Data Binding</h1>
+			<h2>Ref kitchen sink example - all ways to specify refs, mixed bag on purpose.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		  <div id="leftNav">
+		  </div>
+		  <div id="mainContent">
+		<!--
+			Following group shows first example of declarative usage. Its child
+			dijits are added programmatically.
+			Here, the ref points to the application space "model" variable (can
+			be any dot-separated expression).
+		-->
+		<div class="row" id="infoGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model'">
+			<!-- The serial text box gets placed in div below programmatically -->
+			<div class="row" id="serialDiv">
+				<label class="cell" for="serialInput">Order #:</label>
+			</div>
+			<!-- The first and last name text boxes gets placed in corresponding
+				 divs below, with a relative ref to data-bound parent (group) -->
+			<div class="row" id="firstnameDiv">
+				<label class="cell" for="firstnameInput">First:</label>
+			</div>
+			<div class="row" id="lastnameDiv">
+				<label class="cell" for="lastnameInput">Last:</label>
+			</div>
+			<!-- Here, we break out of any parent data binding association
+				 by declaratively specifying a direct ref expression.
+				 There is no necessity for DOM to match data structure even in
+				 declarative ref specifications. -->
+			<div class="row" id="emailDiv">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'expr:model.Email'"></input>
+			</div>
+		</div>
+		<br/>
+		Choose:
+		<button id="shipto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', model.ShipTo);}">Ship To</button>
+		<button id="billto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', model.BillTo);}">Bill To</button>
+		<br/>
+		<!--
+			Following group shows a declarative example of a ref thats relative
+			to another widget's ref. This is useful, for example, if the widget
+			may move its DOM location at some point.
+			Here, we're saying group's ref is relative to "infoGroup" widget's
+			ref and is located at the property "ShipTo" therein.
+		-->
+		<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'widget:infoGroup.ShipTo'">
+			<!-- This is a relative ref, passed as a string -->
+			<div class="row">
+				<label class="cell" for="streetInput">Street:</label>
+				<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Street'"></input>
+			</div>
+			<!-- Here, we are explicit that the string is a relative ref, which
+				is slightly more performant. -->
+			<div class="row">
+				<label class="cell" for="cityInput">City:</label>
+				<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'rel:City'"></input>
+			</div>
+			<!-- Just goofing with whitespace in refs below, for robustness -->
+			<div class="row">
+				<label class="cell" for="stateInput">State:</label>
+				<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: '	 rel:	State'	"></input>
+			</div>
+			<div class="row">
+				<label class="cell" for="zipInput">Zipcode:</label>
+				<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Zip' "></input>
+			</div>
+		</div>
+		<br/>
+		Model:
+		<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+		</div></div></div>
+		<script type="text/javascript">
+			function setRef(id, addrRef) {
+				var widget = dijit.byId(id);
+				widget.set("ref", addrRef);
+			}
+		</script>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_ref-set-repeat-simple.html b/dojox/mvc/tests/1.7/test_mvc_ref-set-repeat-simple.html
new file mode 100644
index 0000000..9bf8f6e
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_ref-set-repeat-simple.html
@@ -0,0 +1,140 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+
+		<script src="../../../../dojo/dojo.js"
+				type="text/javascript"
+				djConfig="parseOnLoad: true, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Output");
+			dojo.require("dojox.mvc.Group");
+			dojo.require("dojox.mvc.Repeat");
+			dojo.require("dijit.form.TextBox");
+			dojo.require("dijit.form.Button");
+			dojo.require("dojo.store.Memory");
+			dojo.require("dojo.parser");
+
+			var search_results_init1 =
+			[{
+				"Query" : "Engineers1",
+				"Results" : [
+					{
+						"First"	  : "Anne1",
+						"Last"	  : "Ackerman1"
+					},
+					{
+						"First"	  : "Ben1",
+						"Last"	  : "Beckham1"
+					},
+					{
+						"First"	  : "Chad1",
+						"Last"	  : "Chapman1"
+					}
+				]
+			}];
+			var search_results_init2 =
+			[{
+				"Query" : "Engineers2",
+				"Results" : [
+					{
+						"First"	  : "Anne2",
+						"Last"	  : "Ackerman2"
+					},
+					{
+						"First"	  : "Ben2",
+						"Last"	  : "Beckham2"
+					}
+				]
+			}];
+			var search_results_init3 =
+			[{
+				"Query" : "Engineers3",
+				"Results" : [
+					{
+						"First"	  : "",
+						"Last"	  : ""
+					}
+				]
+			}];
+
+			var memStore1 = new dojo.store.Memory({data : search_results_init1});
+			var model1 = dojox.mvc.newStatefulModel({ store : memStore1 })[0];
+			var memStore2 = new dojo.store.Memory({data : search_results_init2});
+			var model2 = dojox.mvc.newStatefulModel({ store : memStore2 })[0];
+			var memStore3 = new dojo.store.Memory({data : search_results_init3});
+			var model3 = dojox.mvc.newStatefulModel({ store : memStore3 })[0];
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="row">
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model1);}">Swap Model1</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model2);}">Swap Model2</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model3);}">Swap Model3</button>
+					</div>
+					<div id="outergroupId"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model1'">
+						<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
+							<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+								<label class="cell" for="nameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
+							</div>
+						</div>
+					</div>
+					<div class="row">
+							<span>
+								Model1 Output is ==>  
+							</span>
+							<span id="firstnameOutput10" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[0].First">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput11" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[1].First">
+								Name2 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput12" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[2].First">
+								Name3 is "${this.value}"  
+							</span>
+					</div>
+					<div class="row">
+							<span>
+								Model2 Output is ==>  
+							</span>
+							<span id="firstnameOutput20" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[0].First">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput21" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[1].First">
+								Name2 is "${this.value}"  
+							</span>
+					</div>
+					<div class="row">
+							<span>
+								Model3 Output is ==>  
+							</span>
+							<span id="firstnameOutput30" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model3.Results[0].First">
+								Name1 is "${this.value}"  
+							</span>
+					</div>					
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model1.reset();model2.reset();model3.reset();}">Reset all</button>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_ref-template-13263.html b/dojox/mvc/tests/1.7/test_mvc_ref-template-13263.html
new file mode 100644
index 0000000..236673f
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_ref-template-13263.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>latebinding</title>
+		<link type="text/css" href="../../../../dojo/resources/dojo.css" />
+		<link type="text/css" href="../../../../dijit/themes/claro/claro.css" />
+		<script src="../../../../dojo/dojo.js"></script>
+		<script>
+			var model;
+			require([
+				'dojo/_base/declare',
+				'dojox/mvc',
+				'dojox/mvc/Group',
+				'dijit/_TemplatedMixin',
+				'dijit/_WidgetsInTemplateMixin',
+				'dojox/mvc/StatefulModel',
+				'dojo/ready',
+				'dojo/parser',
+				'dijit/form/TextBox'
+			], function (declare, mvc, Group, _TemplatedMixin, _WidgetsInTemplateMixin, StatefulModel, ready, parser, TextBox) {
+				declare('test.TextBox', [TextBox], {
+					startup: function () {
+						console.log('starting...', this.id, this.binding);
+						this.inherited(arguments);
+						console.log('started', this.id, this.binding);
+					}
+				});
+				var testGroup = declare('test.Group', [Group], {
+					startup: function () {
+						console.log('starting...', this.id, this.binding);
+						this.inherited(arguments);
+						console.log('started', this.id, this.binding);
+					}
+				});
+				declare('test.Templated', [testGroup, _TemplatedMixin, _WidgetsInTemplateMixin], {
+					templateString: '<div><input data-dojo-type="test.TextBox" data-dojo-props="ref: \'rel:fn\'"></div>'
+				});
+
+				model = new StatefulModel({ data: {fn: 'first', ln: 'last'}});
+				ready(function () {
+					parser.parse();
+					console.log('setting ref after parsing...');
+					dijit.byId('late').set('ref', model);
+					var prog = new test.Templated({
+						ref: model
+					}, 'prog');
+					prog.startup();
+				});
+			});
+		</script>
+	</head>
+
+	<body class="claro">
+		<h1>latebinding</h1>
+		<p>no template</p>
+		<div id="parsedGroup" data-dojo-type="test.Group" data-dojo-props="ref:model">
+			<input data-dojo-type="test.TextBox" data-dojo-props="ref: 'rel:fn'" id="parsedInput">
+		</div>
+		<p>Early parsed</p><div id="early" data-dojo-type="test.Templated" ref="model"></div>
+		<p>Late parsed</p><div id="late" data-dojo-type="test.Templated"></div>
+		<p>programmatic</p><div id="prog"></div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_repeat-declarative-sync.html b/dojox/mvc/tests/1.7/test_mvc_repeat-declarative-sync.html
new file mode 100644
index 0000000..4678968
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_repeat-declarative-sync.html
@@ -0,0 +1,205 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Search Results example, declarative with save, commit and reset</title>
+
+		<script src="../../../../dojo/dojo.js"
+			type="text/javascript"
+			djConfig="parseOnLoad: true, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Group");
+			dojo.require("dojox.mvc.Repeat");
+			dojo.require("dijit.form.TextBox");
+			dojo.require("dijit.form.Button");
+			dojo.require("dojo.parser");
+			
+		  // Raw records for the master detail
+		  var search_results_init =
+			{
+				"Results" : [
+					{
+						"First"	  : "Anne",
+						"Last"	  : "Ackerman",
+						"Location": "NY",
+						"Office"  : "1S76",
+						"Email"	  : "a.a at test.com",
+						"Tel"	  : "123-764-8237",
+						"Fax"	  : "123-764-8228"
+					},
+					{
+						"First"	  : "Ben",
+						"Last"	  : "Beckham",
+						"Location": "NY",
+						"Office"  : "5N47",
+						"Email"	  : "b.b at test.com",
+						"Tel"	  : "123-764-8599",
+						"Fax"	  : "123-764-8600"
+					},
+					{
+						"First"	  : "Chad",
+						"Last"	  : "Chapman",
+						"Location": "CA",
+						"Office"  : "1278",
+						"Email"	  : "c.c at test.com",
+						"Tel"	  : "408-764-8237",
+						"Fax"	  : "408-764-8228"
+					},
+					{
+						"First"	  : "David",
+						"Last"	  : "Durham",
+						"Location": "NJ",
+						"Office"  : "C12",
+						"Email"	  : "d.d at test.com",
+						"Tel"	  : "514-764-8237",
+						"Fax"	  : "514-764-8228"
+					},
+					{
+						"First"	  : "Emma",
+						"Last"	  : "Eklof",
+						"Location": "NY",
+						"Office"  : "4N76",
+						"Email"	  : "e.e at test.com",
+						"Tel"	  : "123-764-1234",
+						"Fax"	  : "123-764-4321"
+					},
+					{
+						"First"	  : "Fred",
+						"Last"	  : "Fisher",
+						"Location": "NJ",
+						"Office"  : "V89",
+						"Email"	  : "f.f at test.com",
+						"Tel"	  : "514-764-8567",
+						"Fax"	  : "514-764-8000"
+					},
+					{
+						"First"	  : "George",
+						"Last"	  : "Garnett",
+						"Location": "NY",
+						"Office"  : "7S11",
+						"Email"	  : "gig at test.com",
+						"Tel"	  : "123-999-8599",
+						"Fax"	  : "123-999-8600"
+					},
+					{
+						"First"	  : "Hunter",
+						"Last"	  : "Huffman",
+						"Location": "CA",
+						"Office"  : "6532",
+						"Email"	  : "h.h at test.com",
+						"Tel"	  : "408-874-8237",
+						"Fax"	  : "408-874-8228"
+					},
+					{
+						"First"	  : "Irene",
+						"Last"	  : "Ira",
+						"Location": "NJ",
+						"Office"  : "F09",
+						"Email"	  : "i.i at test.com",
+						"Tel"	  : "514-764-6532",
+						"Fax"	  : "514-764-7300"
+					},
+					{
+						"First"	  : "John",
+						"Last"	  : "Jacklin",
+						"Location": "CA",
+						"Office"  : "6701",
+						"Email"	  : "j.j at test.com",
+						"Tel"	  : "408-764-1234",
+						"Fax"	  : "408-764-4321"
+					}
+				]
+			};
+
+			var selectedIndex = 0;
+		</script>
+	</head>
+	<body class="claro" style="background-image: url(images/master_detail.png)">
+		<div data-dojo-id="results" data-dojo-type="dojox.mvc.StatefulModel" data="search_results_init" ></div>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation">
+				</div>
+				<div id="headerInsert">
+				<h2>Master Detail Example - Declarative with repeat container, with save, commit and reset.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav">
+				</div>
+				<div id="mainContent">
+					<div id="searchBanner">Search Results for term: </div>		   
+					<!--
+						The repeat container denotes a templated UI that operates over a collection
+						of data records.
+						The UI can be customized for each iteration using properties such as
+						${this.index} for the iteration index.
+					-->
+					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results.Results'">
+						<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+							<label class="cell" for="nameInput${this.index}">Name:</label>
+							<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"></input>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+						</div>
+					</div>
+					<div class="spacer"></div>
+
+					<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results.Results'">
+						<div id="detailsBanner">Details for selected index:</div>
+
+						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
+							<div class="row">
+								<label class="cell" for="firstInput">First Name:</label>
+								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="lastInput">Last Name:</label>
+								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="locationInput">Location:</label>
+								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="officeInput">Office:</label>
+								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="emailInput">Email:</label>
+								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="telInput">Telephone:</label>
+								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="faxInput">Fax:</label>
+								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
+							</div>
+							<div class="row">
+							<div class="spacer"></div>
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.Results[selectedIndex].toPlainObject());results.Results[selectedIndex].commit();}">Save Item</button>		   
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.Results.toPlainObject());results.Results.commit();;}">Commit All</button>		   
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.Results.reset();}">Reset to last saved</button>		 
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+		<script type="text/javascript">
+			// called to change the selected item
+			function setDetailsContext(index) {
+				selectedIndex = index;
+				var widget = dijit.byId("detailsGroup");
+				widget.set("ref", index);
+			};
+		</script>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_repeat-store-declarative-async.html b/dojox/mvc/tests/1.7/test_mvc_repeat-store-declarative-async.html
new file mode 100644
index 0000000..62a67b4
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_repeat-store-declarative-async.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Search Results example, using a store with save, commit and reset</title>
+
+		<script src="../../../../dojo/dojo.js"
+			type="text/javascript"
+			djConfig="parseOnLoad: false, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Group");
+			dojo.require("dojox.mvc.Repeat");
+			dojo.require("dijit.form.TextBox");
+			dojo.require("dijit.form.Button");
+			dojo.require("dojo.data.ItemFileWriteStore");
+			dojo.require("dojo.store.DataStore");
+			dojo.require("dojo.parser");
+			
+			var results, selectedIndex = 0;
+
+			function setup() {				
+				var storeNodes = dojo.byId("storeNodes");
+				// this is necessary to parse the declarative stores without parsing the rest of the html with the refs.				
+				dojo.parser.parse(storeNodes);
+				// writeStore and dataStore are created declaratively in the html below.
+				var modelPromise = dojox.mvc.newStatefulModel({store: theDataStore}); 
+				modelPromise.then(function(model){ 
+					results = model;
+					var wrapperNodes = dojo.byId("wrapper");
+					dojo.parser.parse(wrapperNodes); // parse the part of the html with the refs
+				});
+			};
+
+			dojo.addOnLoad(setup);
+		</script>
+	</head>
+	<body class="claro" style="background-image: url(images/master_detail.png)">
+        <div id="storeNodes">
+			<div data-dojo-id="theWriteStore" data-dojo-type="dojo.data.ItemFileWriteStore" data-dojo-props="url: '../../../../dojox/mvc/tests/_data/mvcRepeatData.json'"></div>	
+			<div data-dojo-id="theDataStore" data-dojo-type="dojo.store.DataStore" data-dojo-props="store: theWriteStore"></div>
+        </div>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation">
+				</div>
+				<div id="headerInsert">
+				<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav">
+				</div>
+				<div id="mainContent">
+					<div id="searchBanner">Search Results for term: </div>         
+					<!--
+						The repeat container denotes a templated UI that operates over a collection
+						of data records.
+						The UI can be customized for each iteration using properties such as
+						${this.index} for the iteration index.
+					-->
+					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results'">
+						<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+							<label class="cell" for="nameInput${this.index}">Name:</label>
+							<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"></input>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+						</div>
+					</div>
+					<div class="spacer"></div>
+
+					<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results'">
+						<div id="detailsBanner">Details for selected index:</div>
+
+						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
+							<div class="row">
+								<label class="cell" for="firstInput">First Name:</label>
+								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="lastInput">Last Name:</label>
+								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="locationInput">Location:</label>
+								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="officeInput">Office:</label>
+								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="emailInput">Email:</label>
+								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="telInput">Telephone:</label>
+								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="faxInput">Fax:</label>
+								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
+							</div>
+							<div class="row">
+							<div class="spacer"></div>
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results[selectedIndex].toPlainObject());results[selectedIndex].commit();}">Save Item</button>        
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.toPlainObject());results.commit();;}">Commit All</button>        
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.reset();}">Reset to last saved</button>        
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+        </div>
+        <script type="text/javascript">
+			// called to change the selected item
+			function setDetailsContext(index) {
+				selectedIndex = index;
+				var widget = dijit.byId("detailsGroup");
+				widget.set("ref", index);
+			};
+        </script>
+    </body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_search-results-ins-del.html b/dojox/mvc/tests/1.7/test_mvc_search-results-ins-del.html
new file mode 100644
index 0000000..a38a28f
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_search-results-ins-del.html
@@ -0,0 +1,244 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Search Results example</title>
+
+		<script src="../../../../dojo/dojo.js"
+				type="text/javascript"
+				djConfig="parseOnLoad: true, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript">
+		  dojo.require("dojox.mvc");
+		  dojo.require("dojox.mvc.Group");
+		  dojo.require("dojox.mvc.Repeat");
+		  dojo.require("dijit.form.TextBox");
+		  dojo.require("dijit.form.Button");
+		  dojo.require("dojo.parser");
+
+		  // Initial raw records for the master detail
+		  var search_results_init =
+			{
+				"Query" : "Engineers",
+				"Results" : [
+					{
+						"First"	  : "Anne",
+						"Last"	  : "Ackerman",
+						"Location": "NY",
+						"Office"  : "1S76",
+						"Email"	  : "a.a at test.com",
+						"Tel"	  : "123-764-8237",
+						"Fax"	  : "123-764-8228"
+					},
+					{
+						"First"	  : "Ben",
+						"Last"	  : "Beckham",
+						"Location": "NY",
+						"Office"  : "5N47",
+						"Email"	  : "b.b at test.com",
+						"Tel"	  : "123-764-8599",
+						"Fax"	  : "123-764-8600"
+					},
+					{
+						"First"	  : "Chad",
+						"Last"	  : "Chapman",
+						"Location": "CA",
+						"Office"  : "1278",
+						"Email"	  : "c.c at test.com",
+						"Tel"	  : "408-764-8237",
+						"Fax"	  : "408-764-8228"
+					},
+					{
+						"First"	  : "David",
+						"Last"	  : "Durham",
+						"Location": "NJ",
+						"Office"  : "C12",
+						"Email"	  : "d.d at test.com",
+						"Tel"	  : "514-764-8237",
+						"Fax"	  : "514-764-8228"
+					},
+					{
+						"First"	  : "Emma",
+						"Last"	  : "Eklof",
+						"Location": "NY",
+						"Office"  : "4N76",
+						"Email"	  : "e.e at test.com",
+						"Tel"	  : "123-764-1234",
+						"Fax"	  : "123-764-4321"
+					},
+					{
+						"First"	  : "Fred",
+						"Last"	  : "Fisher",
+						"Location": "NJ",
+						"Office"  : "V89",
+						"Email"	  : "f.f at test.com",
+						"Tel"	  : "514-764-8567",
+						"Fax"	  : "514-764-8000"
+					},
+					{
+						"First"	  : "George",
+						"Last"	  : "Garnett",
+						"Location": "NY",
+						"Office"  : "7S11",
+						"Email"	  : "gig at test.com",
+						"Tel"	  : "123-999-8599",
+						"Fax"	  : "123-999-8600"
+					},
+					{
+						"First"	  : "Hunter",
+						"Last"	  : "Huffman",
+						"Location": "CA",
+						"Office"  : "6532",
+						"Email"	  : "h.h at test.com",
+						"Tel"	  : "408-874-8237",
+						"Fax"	  : "408-874-8228"
+					},
+					{
+						"First"	  : "Irene",
+						"Last"	  : "Ira",
+						"Location": "NJ",
+						"Office"  : "F09",
+						"Email"	  : "i.i at test.com",
+						"Tel"	  : "514-764-6532",
+						"Fax"	  : "514-764-7300"
+					},
+					{
+						"First"	  : "John",
+						"Last"	  : "Jacklin",
+						"Location": "CA",
+						"Office"  : "6701",
+						"Email"	  : "j.j at test.com",
+						"Tel"	  : "408-764-1234",
+						"Fax"	  : "408-764-4321"
+					}
+				]
+			};
+
+		   // The dojox.mvc.StatefulModel class creates a data model instance
+		   // where each leaf within the data model is decorated with dojo.Stateful
+		   // properties that widgets can bind to and watch for their changes.
+		   var searchRecords = dojox.mvc.newStatefulModel({ data : search_results_init });
+		 </script>
+	</head>
+	<body class="claro" style="background-image: url(images/master_detail.png)">
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - Repeat with insert and delete.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		 <div id="leftNav">
+		 </div>
+		 <div id="mainContent">
+			<div class="row">
+			<div class="spacer"></div>
+				<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(searchRecords.Results.toPlainObject());searchRecords.Results.commit();;}">Commit All</button>        
+				<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){searchRecords.Results.reset();}">Reset to last saved</button>        
+			</div>
+		 <!--
+			 The group container denotes some logical grouping of widgets and also serves
+			 to establish a parent data binding context for its children.
+			 The ref attribute for the outermost container obtains the binding from the
+			 "page scope" itself.
+		 -->
+		 <div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'searchRecords'">
+			<div class="row">
+				<label class="cell" for="queryInput">Search for:</label>
+				<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Query'"/>
+				<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setSearchBanner();}">Search</button>
+			</div>
+			<div class="spacer"></div>
+
+			<div id="searchBanner">Search Results for term: Engineers</div>
+
+			<!--
+				The repeat container denotes a templated UI that operates over a collection
+				of data records.
+				The UI can be customized for each iteration using properties such as
+				${this.index} for the iteration index.
+			-->
+			<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
+				<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+					<label class="cell" for="nameInput${this.index}">Name:</label>
+					<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){insertResult('${this.index}');}">+</button>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){deleteResult('${this.index}');}">-</button>
+				</div>
+			</div>
+			<div class="spacer"></div>
+
+			<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Results'">
+				<div id="detailsBanner">Details for result index: 0</div>
+
+				<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
+					<div class="row">
+						<label class="cell" for="firstInput">First Name:</label>
+						<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="lastInput">Last Name:</label>
+						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="locationInput">Location:</label>
+						<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="officeInput">Office:</label>
+						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label>
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="telInput">Telephone:</label>
+						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="faxInput">Fax:</label>
+						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"/>
+					</div>
+				</div>
+			</div>
+		   </div>
+		 </div>
+		</div>
+		<script type="text/javascript">
+			function setDetailsContext(index) {
+				var widget = dijit.byId("detailsGroup");
+				widget.set("ref", index);
+				var detailsBanner = dojo.byId("detailsBanner");
+				detailsBanner.innerHTML = "Details for result index: " + index;
+			}
+			function insertResult(index) {
+				var insert = dojox.mvc.newStatefulModel({ "data" : {
+					"First"	  : "",
+					"Last"	  : "",
+					"Location": "",
+					"Office"  : "",
+					"Email"	  : "",
+					"Tel"	  : "",
+					"Fax"	  : ""
+				} });
+				searchRecords.Results.add(parseInt(index)+1, insert);
+			}
+			function deleteResult(index) {
+				searchRecords.Results.remove(index);
+			}
+			function setSearchBanner() {
+				var searchBanner = dojo.byId("searchBanner");
+				searchBanner.innerHTML = "Search Results for term: " + searchRecords.Query.get("value");
+			}
+		</script>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_search-results-repeat-store.html b/dojox/mvc/tests/1.7/test_mvc_search-results-repeat-store.html
new file mode 100644
index 0000000..7fdbdd2
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_search-results-repeat-store.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Search Results example, using a store with save, commit and reset</title>
+
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var results, selectedIndex = 0;
+ 
+		require([
+			'dojo/_base/kernel',
+			'dojo/parser',
+			'dojox/mvc',
+			'dojo/data/ItemFileWriteStore',
+			'dojo/store/DataStore',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Repeat',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(kernel, parser, mvc, ItemFileWriteStore, DataStore){
+				var writeStore = new ItemFileWriteStore({url: kernel.moduleUrl("dojox.mvc.tests._data", "mvcRepeatData.json")});
+				var modelPromise = mvc.newStatefulModel({store: new DataStore({store: writeStore})}); 
+				modelPromise.then(function(model){ 
+					results = model;
+					parser.parse();
+				});
+			});
+
+			// called to change the selected item
+			function setDetailsContext(index) {
+				selectedIndex = index;
+				var widget = dijit.byId("detailsGroup");
+				widget.set("ref", index);
+			};
+        </script>
+	</head>
+	<body class="claro" style="background-image: url(images/master_detail.png)">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation">
+				</div>
+				<div id="headerInsert">
+				<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav">
+				</div>
+				<div id="mainContent">
+					<div id="searchBanner">Search Results for term: </div>         
+					<!--
+						The repeat container denotes a templated UI that operates over a collection
+						of data records.
+						The UI can be customized for each iteration using properties such as
+						${this.index} for the iteration index.
+					-->
+					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results'">
+						<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+							<label class="cell" for="nameInput${this.index}">Name:</label>
+							<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"></input>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+						</div>
+					</div>
+					<div class="spacer"></div>
+
+					<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results'">
+						<div id="detailsBanner">Details for selected index:</div>
+
+						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
+							<div class="row">
+								<label class="cell" for="firstInput">First Name:</label>
+								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="lastInput">Last Name:</label>
+								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="locationInput">Location:</label>
+								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="officeInput">Office:</label>
+								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="emailInput">Email:</label>
+								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="telInput">Telephone:</label>
+								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
+							</div>
+							<div class="row">
+								<label class="cell" for="faxInput">Fax:</label>
+								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
+							</div>
+							<div class="row">
+							<div class="spacer"></div>
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results[selectedIndex].toPlainObject());results[selectedIndex].commit();}">Save Item</button>        
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.toPlainObject());results.commit();;}">Commit All</button>        
+								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.reset();}">Reset to last saved</button>        
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+        </div>
+    </body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_search-results-repeat.html b/dojox/mvc/tests/1.7/test_mvc_search-results-repeat.html
new file mode 100644
index 0000000..4bf7368
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_search-results-repeat.html
@@ -0,0 +1,222 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Search Results example</title>
+
+		<script src="../../../../dojo/dojo.js"
+				type="text/javascript"
+				djConfig="parseOnLoad: true, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+		  dojo.require("dojox.mvc");
+		  dojo.require("dojox.mvc.Group");
+		  dojo.require("dojox.mvc.Repeat");
+		  dojo.require("dijit.form.TextBox");
+		  dojo.require("dijit.form.Button");
+		  dojo.require("dojo.parser");
+
+		  // Raw records for the master detail
+		  var search_results_init =
+			{
+				"Query" : "Engineers",
+				"Results" : [
+					{
+						"First"	  : "Anne",
+						"Last"	  : "Ackerman",
+						"Location": "NY",
+						"Office"  : "1S76",
+						"Email"	  : "a.a at test.com",
+						"Tel"	  : "123-764-8237",
+						"Fax"	  : "123-764-8228"
+					},
+					{
+						"First"	  : "Ben",
+						"Last"	  : "Beckham",
+						"Location": "NY",
+						"Office"  : "5N47",
+						"Email"	  : "b.b at test.com",
+						"Tel"	  : "123-764-8599",
+						"Fax"	  : "123-764-8600"
+					},
+					{
+						"First"	  : "Chad",
+						"Last"	  : "Chapman",
+						"Location": "CA",
+						"Office"  : "1278",
+						"Email"	  : "c.c at test.com",
+						"Tel"	  : "408-764-8237",
+						"Fax"	  : "408-764-8228"
+					},
+					{
+						"First"	  : "David",
+						"Last"	  : "Durham",
+						"Location": "NJ",
+						"Office"  : "C12",
+						"Email"	  : "d.d at test.com",
+						"Tel"	  : "514-764-8237",
+						"Fax"	  : "514-764-8228"
+					},
+					{
+						"First"	  : "Emma",
+						"Last"	  : "Eklof",
+						"Location": "NY",
+						"Office"  : "4N76",
+						"Email"	  : "e.e at test.com",
+						"Tel"	  : "123-764-1234",
+						"Fax"	  : "123-764-4321"
+					},
+					{
+						"First"	  : "Fred",
+						"Last"	  : "Fisher",
+						"Location": "NJ",
+						"Office"  : "V89",
+						"Email"	  : "f.f at test.com",
+						"Tel"	  : "514-764-8567",
+						"Fax"	  : "514-764-8000"
+					},
+					{
+						"First"	  : "George",
+						"Last"	  : "Garnett",
+						"Location": "NY",
+						"Office"  : "7S11",
+						"Email"	  : "gig at test.com",
+						"Tel"	  : "123-999-8599",
+						"Fax"	  : "123-999-8600"
+					},
+					{
+						"First"	  : "Hunter",
+						"Last"	  : "Huffman",
+						"Location": "CA",
+						"Office"  : "6532",
+						"Email"	  : "h.h at test.com",
+						"Tel"	  : "408-874-8237",
+						"Fax"	  : "408-874-8228"
+					},
+					{
+						"First"	  : "Irene",
+						"Last"	  : "Ira",
+						"Location": "NJ",
+						"Office"  : "F09",
+						"Email"	  : "i.i at test.com",
+						"Tel"	  : "514-764-6532",
+						"Fax"	  : "514-764-7300"
+					},
+					{
+						"First"	  : "John",
+						"Last"	  : "Jacklin",
+						"Location": "CA",
+						"Office"  : "6701",
+						"Email"	  : "j.j at test.com",
+						"Tel"	  : "408-764-1234",
+						"Fax"	  : "408-764-4321"
+					}
+				]
+			};
+
+		   // The dojox.mvc.StatefulModel class creates a data model instance
+		   // where each leaf within the data model is decorated with dojo.Stateful
+		   // properties that widgets can bind to and watch for their changes.
+		   var searchRecords = dojox.mvc.newStatefulModel({ data : search_results_init });
+		 </script>
+	</head>
+	<body class="claro" style="background-image: url(images/master_detail.png)">
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - With repeat container.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		 <div id="leftNav">
+		 </div>
+		 <div id="mainContent">
+		 <!--
+			 The group container denotes some logical grouping of widgets and also serves
+			 to establish a parent data binding context for its children.
+			 The ref attribute for the outermost container obtains the binding from the
+			 "page scope" itself.
+		 -->
+		 <div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'searchRecords'">
+			<div class="row">
+				<label class="cell" for="queryInput">Search for:</label>
+				<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Query'"/>
+				<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setSearchBanner();}">Search</button>
+			</div>
+			<div class="spacer"></div>
+
+			<div id="searchBanner">Search Results for term: Engineers</div>
+
+			<!--
+				The repeat container denotes a templated UI that operates over a collection
+				of data records.
+				The UI can be customized for each iteration using properties such as
+				${this.index} for the iteration index.
+			-->
+			<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
+				<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+					<label class="cell" for="nameInput${this.index}">Name:</label>
+					<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+				</div>
+			</div>
+			<div class="spacer"></div>
+
+			<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Results'">
+				<div id="detailsBanner">Details for result index: 0</div>
+
+				<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
+					<div class="row">
+						<label class="cell" for="firstInput">First Name:</label>
+						<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="lastInput">Last Name:</label>
+						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="locationInput">Location:</label>
+						<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="officeInput">Office:</label>
+						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label>
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="telInput">Telephone:</label>
+						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"/>
+					</div>
+					<div class="row">
+						<label class="cell" for="faxInput">Fax:</label>
+						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"/>
+					</div>
+				</div>
+			</div>
+		   </div>
+		 </div>
+		</div>
+		<script type="text/javascript">
+			function setDetailsContext(index) {
+				var widget = dijit.byId("detailsGroup");
+				widget.set("ref", index);
+				var detailsBanner = dojo.byId("detailsBanner");
+				detailsBanner.innerHTML = "Details for result index: " + index;
+			}
+			function setSearchBanner() {
+				var searchBanner = dojo.byId("searchBanner");
+				searchBanner.innerHTML = "Search Results for term: " + searchRecords.Query.get("value");
+			}
+		</script>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_shipto-billto-hierarchical.html b/dojox/mvc/tests/1.7/test_mvc_shipto-billto-hierarchical.html
new file mode 100644
index 0000000..916e43d
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_shipto-billto-hierarchical.html
@@ -0,0 +1,198 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+
+		<script src="../../../../dojo/dojo.js"
+				type="text/javascript"
+				djConfig="parseOnLoad: true, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+		  dojo.require("dojox.mvc");
+		  dojo.require("dojox.mvc.Group");
+		  dojo.require("dijit.form.TextBox");
+		  dojo.require("dijit.form.Button");
+		  dojo.require("dojo.parser");
+
+		  // Initial data with a noticeable hierarchy
+		  var order = {
+			  "Serial" : "360324",
+			  "First"  : "John",
+			  "Last"   : "Doe",
+			  "Email"  : "jdoe at example.com",
+			  "ShipTo" : {
+				  "Type" : "Home",
+				  "Address" : {
+					  "Street" : "123 Valley Rd",
+					  "City"   : "Katonah",
+					  "State"  : "NY",
+					  "Zip"	   : "10536"
+				  },
+				  "Telephone" : {
+					  "AreaCode" : "123",
+					  "Landline" : {
+						  "Number"	  : "456-7890",
+						  "Extension" : "42"
+					  },
+					  "Cell" : {
+						  "Number"	  : "765-4321"
+					  }
+				  }
+			  },
+			  "BillTo" : {
+				  "Type" : "Office",
+				  "Address" : {
+					  "Street" : "17 Skyline Dr",
+					  "City"   : "Hawthorne",
+					  "State"  : "NY",
+					  "Zip"	   : "10532"
+				  },
+				  "Telephone" : {
+					  "AreaCode" : "098",
+					  "Landline" : {
+						  "Number"	  : "765-4321",
+						  "Extension" : "24"
+					  },
+					  "Cell" : {
+						  "Number"	  : "123-4567"
+					  }
+				  }
+			  }
+		  };
+
+		  // The dojox.mvc.StatefulModel class creates a data model instance
+		  // where each leaf within the data model is decorated with dojo.Stateful
+		  // properties that widgets can bind to and watch for their changes.
+		  var model = dojox.mvc.newStatefulModel({ data : order });
+		  var selectedAddr = dojox.mvc.newStatefulModel({ data : "ShipTo" });
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Order Shipping Details</h1>
+			<h2>Data Binding Example - Hierarchical data.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		  <div id="leftNav">
+		  </div>
+		  <div id="mainContent">
+		<!--
+			The group container denotes some logical grouping of widgets and also serves
+			to establish a parent data binding context for its children.
+			The ref attribute for the outermost container obtains the binding from the
+			"page scope" itself.
+		-->
+		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model'">
+			<div class="row">
+				<label class="cell" for="serialInput">Order #:</label>
+				<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Serial'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="lastnameInput">Last name:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Last'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Email'"/>
+			</div>
+		</div>
+		<br/>
+		Choose:
+		<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.ShipTo');}">Ship To</button>
+		<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.BillTo');}">Bill To</button>
+		<br/>
+		<div class="row">
+			<label class="cell" for="addrLabel">Selected Address:</label>
+			<input class="cell" data-dojo-type="dijit.form.TextBox" id="addrLabel"
+								data-dojo-props="ref: 'selectedAddr'"/>
+		</div>
+		<br/>
+		<!--
+			For convenience, the widget hierarchy matches the data hierarchy
+			(see JSON literal above).
+			In this implementation, the child ref attributes are simple property names
+			of the parent binding context.
+			The ref attribute may support more advanced constructs, such as queries
+			over the parent widget's or other application specified binding context.
+		-->
+		  <div id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model.ShipTo'">
+			<div class="row">
+			  <label class="cell" for="typeInput">Type:</label>
+			  <input class="cell" id="typeInput" data-dojo-type="dijit.form.TextBox"
+								  data-dojo-props="ref: 'Type'"/>
+			</div>
+			<div id="postalGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Address'">
+			  <div class="row">
+				  <label class="cell" for="streetInput">Street:</label>
+				  <input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'Street'"/>
+			  </div>
+			  <div class="row">
+				  <label class="cell" for="cityInput">City:</label>
+				  <input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'City'"/>
+			  </div>
+			  <div class="row">
+				  <label class="cell" for="stateInput">State:</label>
+				  <input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'State'"/>
+			  </div>
+			  <div class="row">
+				  <label class="cell" for="zipInput">Zipcode:</label>
+				  <input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'Zip'"/>
+			  </div>
+			</div>
+			<div id="telGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Telephone'">
+			  <div class="row">
+				  <label class="cell" for="areacodeInput">Area code:</label>
+				  <input class="cell" id="areacodeInput" data-dojo-type="dijit.form.TextBox"
+										 data-dojo-props="ref: 'AreaCode'"/>
+			  </div>
+			  <div id="llGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Landline'">
+				<div class="row">
+				  <label class="cell" for="numberInput">Landline Number:</label>
+				  <input class="cell" id="numberInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'Number'"/>
+				</div>
+				<div class="row">
+				  <label class="cell" for="extInput">Extension:</label>
+				  <input class="cell" id="extInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'Extension'"/>
+				</div>
+			  </div>
+			  <div class="row" id="cellGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Cell'">
+				  <label class="cell" for="cellInput">Cell Number:</label>
+				  <input class="cell" id="cellInput" data-dojo-type="dijit.form.TextBox"
+									  data-dojo-props="ref: 'Number'"/>
+			  </div>
+			</div>
+			<br/>
+			Model:
+			<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+		</div></div></div>
+		<script type="text/javascript">
+			function setRef(id, addrRef) {
+				var widget = dijit.byId(id);
+				widget.set("ref", addrRef);
+				if(addrRef == "model.ShipTo")
+					selectedAddr.set("value", "ShipTo");
+				else
+					selectedAddr.set("value", "BillTo");
+			}
+		</script>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_shipto-billto-simple-declarative.html b/dojox/mvc/tests/1.7/test_mvc_shipto-billto-simple-declarative.html
new file mode 100644
index 0000000..10a2f69
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_shipto-billto-simple-declarative.html
@@ -0,0 +1,132 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Declarative Multiple Address Detail example</title>
+
+		<script src="../../../../dojo/dojo.js"
+				type="text/javascript"
+				djConfig="parseOnLoad: true, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+		  dojo.require("dojox.mvc");
+		  dojo.require("dojox.mvc.Group");
+		  dojo.require("dijit.form.TextBox");
+		  dojo.require("dijit.form.Button");
+		  dojo.require("dojo.parser");
+
+		  // Initial data
+		  var order = {
+			  "Serial" : "360324",
+			  "First"  : "John",
+			  "Last"   : "Doe",
+			  "Email"  : "jdoe at example.com",
+			  "ShipTo" : {
+				  "Street" : "123 Valley Rd",
+				  "City"   : "Katonah",
+				  "State"  : "NY",
+				  "Zip"	   : "10536"
+			  },
+			  "BillTo" : {
+				  "Street" : "17 Skyline Dr",
+				  "City"   : "Hawthorne",
+				  "State"  : "NY",
+				  "Zip"	   : "10532"
+			  }
+		  };
+		</script>
+	</head>
+	<body class="claro">
+		<!--
+			The following dojox.mvc.StatefulModel creates a data model instance
+			where each leaf within the data model is decorated with dojo.Stateful
+			properties that widgets can bind to and watch for their changes.
+		-->
+		<div data-dojo-type="dojox.mvc.StatefulModel" data-dojo-props="data: order" data-dojo-id="model"></div>	   
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Order Shipping Details</h1>
+			<h2>Declarative Data Binding Example - Group Container.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		  <div id="leftNav">
+		  </div>
+		  <div id="mainContent">
+		<!--
+			The group container denotes some logical grouping of widgets and also serves
+			to establish a parent data binding context for its children.
+			The ref attribute for the outermost container obtains the binding from the
+			"page scope" itself.
+		-->
+		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'expr:model'">
+			<div class="row">
+				<label class="cell" for="serialInput">Order #:</label>
+				<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Serial'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="lastnameInput">Last:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Last'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Email'"/>
+			</div>
+		</div>
+		<br/>
+		Choose:
+		<button id="shipto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.ShipTo');}">Ship To</button>
+		<button id="billto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.BillTo');}">Bill To</button>
+		<br/>
+		<!--
+			For convenience, the widget hierarchy matches the data hierarchy
+			(see JSON literal above).
+			In this implementation, the child ref attributes are simple property names
+			of the parent binding context.
+			The ref attribute may support more advanced constructs, such as queries
+			over the parent widget's or other application specified binding context.
+		-->
+		<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model.ShipTo'">
+			<div class="row">
+				<label class="cell" for="streetInput">Street:</label>
+				<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Street'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="cityInput">City:</label>
+				<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'City'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="stateInput">State:</label>
+				<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'State'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="zipInput">Zipcode:</label>
+				<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="ref: 'Zip'"/>
+			</div>
+		</div>
+		<br/>
+		Model:
+		<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+		</div></div></div>
+		<script type="text/javascript">
+			function setRef(id, addrRef) {
+				var widget = dijit.byId(id);
+				widget.set("ref", addrRef);
+			}
+		</script>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_shipto-billto-simple-oldparser.html b/dojox/mvc/tests/1.7/test_mvc_shipto-billto-simple-oldparser.html
new file mode 100755
index 0000000..a8e47b3
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_shipto-billto-simple-oldparser.html
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+
+		<script src="../../../../dojo/dojo.js"
+				type="text/javascript"
+				djConfig="parseOnLoad: true, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+		  dojo.require("dojox.mvc");
+		  dojo.require("dojox.mvc.Group");
+		  dojo.require("dijit.form.TextBox");
+		  dojo.require("dijit.form.Button");
+		  dojo.require("dojo.parser");
+
+		  // Initial data
+		  var order = {
+			  "Serial" : "360324",
+			  "First"  : "John",
+			  "Last"   : "Doe",
+			  "Email"  : "jdoe at example.com",
+			  "ShipTo" : {
+				  "Street" : "123 Valley Rd",
+				  "City"   : "Katonah",
+				  "State"  : "NY",
+				  "Zip"	   : "10536"
+			  },
+			  "BillTo" : {
+				  "Street" : "17 Skyline Dr",
+				  "City"   : "Hawthorne",
+				  "State"  : "NY",
+				  "Zip"	   : "10532"
+			  }
+		  };
+
+		  // The dojox.mvc.StatefulModel class creates a data model instance
+		  // where each leaf within the data model is decorated with dojo.Stateful
+		  // properties that widgets can bind to and watch for their changes.
+		  var model = dojox.mvc.newStatefulModel({ data : order });
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Order Shipping Details</h1>
+			<h2>Data Binding Example - Group Container.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		  <div id="leftNav">
+		  </div>
+		  <div id="mainContent">
+		<!--
+			The group container denotes some logical grouping of widgets and also serves
+			to establish a parent data binding context for its children.
+			The ref value for the outermost container obtains the binding from the
+			"page scope" itself.
+		-->
+		<div class="row" dojoType="dojox.mvc.Group" ref="model">
+			<div class="row">
+				<label class="cell" for="serialInput">Order #:</label>
+				<input class="cell" id="serialInput" dojoType="dijit.form.TextBox"
+									ref="'Serial'"></input>
+			</div>
+			<div class="row">
+				<label class="cell" for="lastnameInput">Last:</label>
+				<input class="cell" id="lastnameInput" dojoType="dijit.form.TextBox"
+									ref="'Last'"></input>
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput" dojoType="dijit.form.TextBox"
+									ref="'Email'"></input>
+			</div>
+		</div>
+		<br/>
+		Choose:
+		<button id="shipto" type="button" dojoType="dijit.form.Button" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
+		<button id="billto" type="button" dojoType="dijit.form.Button" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>
+		<br/>
+		<!--
+			For convenience, the widget hierarchy matches the data hierarchy
+			(see JavaScript object literal above).
+			In this implementation, the child ref values are simple property names
+			of the parent binding context.
+			The ref value may support more advanced constructs, such as queries
+			over the parent widget's or other application specified binding context.
+		-->
+		<div class="row" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
+			<div class="row">
+				<label class="cell" for="streetInput">Street:</label>
+				<input class="cell" id="streetInput" dojoType="dijit.form.TextBox"
+									ref="'Street'"></input>
+			</div>
+			<div class="row">
+				<label class="cell" for="cityInput">City:</label>
+				<input class="cell" id="cityInput" dojoType="dijit.form.TextBox"
+									ref="'City'"></input>
+			</div>
+			<div class="row">
+				<label class="cell" for="stateInput">State:</label>
+				<input class="cell" id="stateInput" dojoType="dijit.form.TextBox"
+									ref="'State'"></input>
+			</div>
+			<div class="row">
+				<label class="cell" for="zipInput">Zipcode:</label>
+				<input class="cell" id="zipInput" dojoType="dijit.form.TextBox"
+									ref="'Zip'"></input>
+			</div>
+		</div>
+		<br/>
+		Model:
+		<button id="reset" type="button" dojoType="dijit.form.Button" onclick="model.reset()">Reset</button>
+		</div></div></div>
+		<script type="text/javascript">
+			function setRef(id, addrRef) {
+				var widget = dijit.byId(id);
+				widget.set("ref", addrRef);
+			}
+		</script>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_shipto-billto-simple.html b/dojox/mvc/tests/1.7/test_mvc_shipto-billto-simple.html
new file mode 100644
index 0000000..20371c5
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_shipto-billto-simple.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:1" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var model;
+ 
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(parser, ready, mvc){
+
+			// Initial data
+			var order = {
+				"Serial" : "360324",
+				"First" : "John",
+				"Last" : "Doe",
+				"Email" : "jdoe at example.com",
+				"ShipTo" : {
+					"Street" : "123 Valley Rd",
+					"City" : "Katonah",
+					"State" : "NY",
+					"Zip" : "10536"
+				},
+				"BillTo" : {
+					"Street" : "17 Skyline Dr",
+					"City" : "Hawthorne",
+					"State" : "NY",
+					"Zip" : "10532"
+				}
+			};
+				// The dojox.mvc.StatefulModel class creates a data model instance
+				// where each leaf within the data model is decorated with dojo.Stateful
+				// properties that widgets can bind to and watch for their changes.
+				model = mvc.newStatefulModel({ data : order });
+				// the StatefulModel created above is initialized with 
+				// model.First set to "John", model.Last set to "Doe" and model.Email set to "jdoe at example.com"
+
+			});
+
+			// setRef is call when the "Ship To" or "Bill To" button is pressed.
+			function setRef(id, addrRef) {
+				var widget = dijit.byId(id);
+				widget.set("ref", addrRef);
+			}
+		</script>
+		
+		
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+		<div id="header">
+			<div id="navigation">
+			</div>
+			<div id="headerInsert">
+				<h1>Order Shipping Details</h1>
+				<h2>Data Binding Example - Group Container.</h2>
+			</div>
+		</div>
+		<div id="main">
+		<div id="leftNav"></div>
+		<div id="mainContent">
+		<!--
+			The group container denotes some logical grouping of widgets and also serves
+			to establish a parent data binding context for its children.
+			The ref attribute for the outermost container obtains the binding from the
+			"page scope" itself.
+		-->
+		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model'">
+			<div class="row">
+				<label class="cell" for="serialInput">Order #:</label>
+				<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Serial'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="lastnameInput">Last:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
+			</div>
+		</div>
+		<br/>
+		Choose:
+		<button id="shipto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', model.ShipTo);}">Ship To</button>
+		<button id="billto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', model.BillTo);}">Bill To</button>
+		<br/>
+		<!--
+			For convenience, the widget hierarchy matches the data hierarchy
+			(see JSON literal above).
+			In this implementation, the child ref attributes are simple property names
+			of the parent binding context.
+			The ref attribute may support more advanced constructs, such as queries
+			over the parent widget's or other application specified binding context.
+		-->
+		<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model.ShipTo'">
+			<div class="row">
+				<label class="cell" for="streetInput">Street:</label>
+				<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Street'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="cityInput">City:</label>
+				<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'City'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="stateInput">State:</label>
+				<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'State'"/>
+			</div>
+			<div class="row">
+				<label class="cell" for="zipInput">Zipcode:</label>
+				<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Zip'"/>
+			</div>
+		</div>
+		<br/>
+		Model:
+		<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+		</div></div></div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_simple-programmatic.html b/dojox/mvc/tests/1.7/test_mvc_simple-programmatic.html
new file mode 100644
index 0000000..fd4d56e
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_simple-programmatic.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Simple programmatic data binding - Toggle example</title>
+
+		<script src="../../../../dojo/dojo.js"
+				type="text/javascript"
+				djConfig="parseOnLoad: true, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+		  dojo.require("dojox.mvc");
+		  dojo.require("dijit.form.TextBox");
+		  dojo.require("dijit.form.Button");
+		  dojo.require("dojo.parser");
+
+		  // Function below shows programmatic creation of data-bound dijits
+		  function addBoundDijits(){
+			  var model = dojox.mvc.newStatefulModel({ data: { first: "John", last: "Doe" }});
+
+			  var fn = new dijit.form.TextBox({id: "fn", ref: model.first});
+			  fn.placeAt(dojo.byId("mainContent"));
+			  fn.startup();
+
+			  var ln = new dijit.form.TextBox({id: "ln", ref: model.last});
+			  ln.placeAt(dojo.byId("mainContent"));
+			  ln.startup();
+		  }
+
+		  // Function below shows programmatic update of data-bound dijit refs
+		  function toggleRefs(){
+			  var fn = dijit.byId("fn"), ln = dijit.byId("ln");
+			  var ref = fn.get("ref");
+			  fn.set("ref", ln.get("ref"));
+			  ln.set("ref", ref);
+		  }
+
+		  dojo.addOnLoad(addBoundDijits);
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Toggle</h1>
+			<h2>Simple Example - Programmatic data binding.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		  <div id="leftNav">
+		  </div>
+		  <div id="mainContent">
+			<button id="toggle" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: toggleRefs">Toggle Refs</button>
+		  </div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/1.7/test_mvc_updateData-hack-support.html b/dojox/mvc/tests/1.7/test_mvc_updateData-hack-support.html
new file mode 100644
index 0000000..7f95fa6
--- /dev/null
+++ b/dojox/mvc/tests/1.7/test_mvc_updateData-hack-support.html
@@ -0,0 +1,221 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+
+		<script src="../../../../dojo/dojo.js"
+				type="text/javascript"
+				djConfig="parseOnLoad: true, isDebug: true">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Output");
+			dojo.require("dojox.mvc.Group");
+			dojo.require("dojox.mvc.Repeat");
+			dojo.require("dijit.form.TextBox");
+			dojo.require("dijit.form.Button");
+			dojo.require("dojo.store.Memory");
+			dojo.require("dojo.parser");
+			dojo.require("dojo._base.lang");
+
+			var search_results_init1 =
+			[{
+				"Query" : "Engineers1",
+				"Results" : [
+					{
+						"First"	  : "Anne1",
+						"Last"	  : "Ackerman1"
+					},
+					{
+						"First"	  : "Ben1",
+						"Last"	  : "Beckham1"
+					},
+					{
+						"First"	  : "Chad1",
+						"Last"	  : "Chapman1"
+					}
+				]
+			}];
+			var search_results_init2 =
+			[{
+				"Query" : "Engineers2",
+				"Results" : [
+					{
+						"First"	  : "Anne2",
+						"Last"	  : "Ackerman2"
+					},
+					{
+						"First"	  : "Ben2",
+						"Last"	  : "Beckham2"
+					}
+				]
+			}];
+			var search_results_init3 =
+			[{
+				"Query" : "Engineers3",
+				"Results" : [
+					{
+						"First"	  : "",
+						"Last"	  : ""
+					}
+				]
+			}];
+
+			var memStore1 = new dojo.store.Memory({data : search_results_init1});
+			var model1 = dojox.mvc.newStatefulModel({ store : memStore1 })[0];
+			var memStore2 = new dojo.store.Memory({data : search_results_init2});
+			var model2 = dojox.mvc.newStatefulModel({ store : memStore2 })[0];
+			var memStore3 = new dojo.store.Memory({data : search_results_init3});
+			var model3 = dojox.mvc.newStatefulModel({ store : memStore3 })[0];
+		</script>
+	</head>
+	<body class="claro">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="row">
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model1);}">Swap Model1</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model2);}">Swap Model2</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model3);}">Swap Model3</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){swapData();}">Test Swap Data</button>
+					</div>
+					<div id="outergroupId"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model1'">
+						<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
+							<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+								<label class="cell" for="nameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
+							</div>
+						</div>
+					</div>
+					<div class="row">
+							<span>
+								Model1 Output is ==>  
+							</span>
+					<div id="outergroupIdOutput"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model1'">
+						<div id="repeatIdOutput" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
+							<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInputOut${this.index}" data-dojo-props="ref: 'First'"/>
+								<span  class="cell"> Name${this.index} is 
+								</span>
+								<span  class="cell" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'First'"></span>
+							</div>
+						</div>
+					</div>
+
+					<!--<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model1.Results[0]'">
+							<span id="firstnameOutput10" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'First'">
+								Name1 is "${this.value}" : 
+							</span>
+							</div>
+							<span id="firstnameOutput11" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[1].First">
+								Name2 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput12" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[2].First">
+								Name3 is "${this.value}"  
+							</span>
+					</div>
+					-->
+					<div class="row">
+							<span>
+								Model2 Output is ==>  
+							</span>
+							
+							<span id="firstnameOutput20" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[0].First">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput21" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[1].First">
+								Name2 is "${this.value}"  
+							</span>
+					</div>
+					<div class="row">
+							<span>
+								Model3 Output is ==>  
+							</span>
+							<span id="firstnameOutput30" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model3.Results[0].First">
+								Name1 is "${this.value}"  
+							</span>
+					</div>					
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model1.reset();model2.reset();model3.reset();}">Reset all</button>
+				</div>
+			</div>
+		</div>
+		<script type="text/javascript">
+			function swapData(index) {
+				//model1 = model2;
+				//model1.Results = model2.Results;
+				
+				//for(var x in src){
+				//	var o = src.get(x);
+				//	if(o && dojo._base.lang.isObject(o) && dojo._base.lang.isFunction(o.get)){
+				//		dest[x].set('value', o);
+				//	}
+				//}
+				//for(var n = this._containedWidgets.length - 1; n > -1; n--){
+		/*	this will remove all and add the new ones, it works and updates...	
+				var dest = model1.Results;
+				var src = dojo._base.lang.clone(model2.Results);
+				for(var i=dest.length-1; i>-1; i--){
+					dest.remove(i);
+				}
+				for(var i=0; i<src.length; i++){
+					dest.add(i,src[i]);
+				}
+		*/		
+
+		//	this will try to set the index for each item, it should update too
+		/*
+				var dest = model1.Results;
+				var src = dojo._base.lang.clone(model2.Results);
+				src.forceBuild = true;	
+				for(var i=dest.length-1; i>-1; i--){
+					if(src.length > i){
+						src[i].forceBuild = true;	
+						dest.set(i,src[i]);
+					}else{
+						dest.remove(i);
+					}
+				}
+		*/
+				//var dest = searchRecords.Results;
+				//var src = searchRecords2.Results.toPlainObject();
+				var dest = model1.Results;
+				var src = dojo._base.lang.clone(model2.Results);
+				if(dest){
+				for(var x in dest){
+					if(dest && dest[x].First){
+					src[x].First.forceBuild = true;	
+					dest[x].First.set('value',src[x].First);
+					src[x].Last.forceBuild = true;	
+					dest[x].Last.set('value',src[x].Last);
+					}
+				}
+				}
+		
+				//model1.Results.add("3",model2.Results[0]);
+				//model1.Results._copyStatefulProperties(model2.Results,model1.Results);
+				//model1.Results[0].First.set('value', model2.Results[0].First);
+				//model1.Results[1].First.set('value', model2.Results[1].First);
+				//model.First.set('value', 'Jane'); 
+				//dijit.byId('outergroupId').set('ref',model1);
+				//var widget = dijit.byId("detailsGroup");
+				//widget.set("ref", index);
+				//var detailsBanner = dojo.byId("detailsBanner");
+				//detailsBanner.innerHTML = "Details for result index: " + index;
+			}
+		</script>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_templatedWidget/myMvcTemplated.js b/dojox/mvc/tests/1.7/test_templatedWidget/myMvcTemplated.js
similarity index 100%
copy from dojox/mvc/tests/test_templatedWidget/myMvcTemplated.js
copy to dojox/mvc/tests/1.7/test_templatedWidget/myMvcTemplated.js
diff --git a/dojox/mvc/tests/test_templatedWidget/readme.txt b/dojox/mvc/tests/1.7/test_templatedWidget/readme.txt
similarity index 100%
copy from dojox/mvc/tests/test_templatedWidget/readme.txt
copy to dojox/mvc/tests/1.7/test_templatedWidget/readme.txt
diff --git a/dojox/mvc/tests/test_templatedWidget/test_mvc_widget.html b/dojox/mvc/tests/1.7/test_templatedWidget/test_mvc_widget.html
similarity index 100%
copy from dojox/mvc/tests/test_templatedWidget/test_mvc_widget.html
copy to dojox/mvc/tests/1.7/test_templatedWidget/test_mvc_widget.html
diff --git a/dojox/mvc/tests/test_templatedWidget/test_mvc_widget_template.html b/dojox/mvc/tests/1.7/test_templatedWidget/test_mvc_widget_template.html
similarity index 100%
copy from dojox/mvc/tests/test_templatedWidget/test_mvc_widget_template.html
copy to dojox/mvc/tests/1.7/test_templatedWidget/test_mvc_widget_template.html
diff --git a/dojox/mvc/tests/zips/10024.json b/dojox/mvc/tests/1.7/zips/10024.json
old mode 100755
new mode 100644
similarity index 100%
copy from dojox/mvc/tests/zips/10024.json
copy to dojox/mvc/tests/1.7/zips/10024.json
diff --git a/dojox/mvc/tests/zips/10706.json b/dojox/mvc/tests/1.7/zips/10706.json
old mode 100755
new mode 100644
similarity index 100%
copy from dojox/mvc/tests/zips/10706.json
copy to dojox/mvc/tests/1.7/zips/10706.json
diff --git a/dojox/mvc/tests/WidgetList_tests/module.js b/dojox/mvc/tests/WidgetList_tests/module.js
new file mode 100644
index 0000000..7229830
--- /dev/null
+++ b/dojox/mvc/tests/WidgetList_tests/module.js
@@ -0,0 +1,18 @@
+define(["doh/runner"], function(doh){
+	try{
+		var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g, "").replace(/^&/, "?");
+		doh.registerUrl("dojox.mvc.tests.WidgetList_tests.doh_mvc_DOMNode-search-results-repeat", require.toUrl("dojox/mvc/tests/WidgetList_tests/doh_mvc_DOMNode-search-results-repeat.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.WidgetList_tests.doh_mvc_mobile-demo", require.toUrl("dojox/mvc/tests/WidgetList_tests/doh_mvc_mobile-demo.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.WidgetList_tests.doh_mvc_new_ref-set-repeat", require.toUrl("dojox/mvc/tests/WidgetList_tests/doh_mvc_new_ref-set-repeat.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.WidgetList_tests.doh_mvc_performance_search-results-repeat", require.toUrl("dojox/mvc/tests/WidgetList_tests/doh_mvc_performance_search-results-repeat.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.WidgetList_tests.doh_mvc_programmatic-repeat-store", require.toUrl("dojox/mvc/tests/WidgetList_tests/doh_mvc_programmatic-repeat-store.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.WidgetList_tests.doh_mvc_repeat_select_cancel", require.toUrl("dojox/mvc/tests/WidgetList_tests/doh_mvc_repeat_select_cancel.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.WidgetList_tests.doh_mvc_repeat_select_manualsave", require.toUrl("dojox/mvc/tests/WidgetList_tests/doh_mvc_repeat_select_manualsave.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.WidgetList_tests.doh_mvc_search-results-repeat", require.toUrl("dojox/mvc/tests/WidgetList_tests/doh_mvc_search-results-repeat.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.WidgetList_tests.doh_mvc_search-results-repeat-store", require.toUrl("dojox/mvc/tests/WidgetList_tests/doh_mvc_search-results-repeat-store.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.WidgetList_tests.doh_new-mvc_label_and_totals", require.toUrl("dojox/mvc/tests/WidgetList_tests/doh_new-mvc_label_and_totals.html" + userArgs), 999999);
+	}catch(e){
+		doh.debug(e);
+	}
+});
+
diff --git a/dojox/mvc/tests/WidgetList_tests/runTests.html b/dojox/mvc/tests/WidgetList_tests/runTests.html
new file mode 100644
index 0000000..6754e82
--- /dev/null
+++ b/dojox/mvc/tests/WidgetList_tests/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+	<head>
+	<title>Dijit Unit Test Runner</title>
+	<meta http-equiv="REFRESH" content="0;url=../../../../util/doh/runner.html?test=dojox/mvc/tests/WidgetList_tests/module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dojox/mvc/tests/WidgetList_tests/test_mobile-checkbox-list-mvc.html b/dojox/mvc/tests/WidgetList_tests/test_mobile-checkbox-list-mvc.html
new file mode 100644
index 0000000..ce097b4
--- /dev/null
+++ b/dojox/mvc/tests/WidgetList_tests/test_mobile-checkbox-list-mvc.html
@@ -0,0 +1,474 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>MVC Repeat with Selectable RoundRectList - Multiple Select</title>
+
+	<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true, parseOnLoad: false, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dojo/_base/declare",
+			"dojo/_base/connect",
+			"dijit/registry",
+			"dojo/dom",
+			"dojox/mobile/parser",
+			"dojo/store/Memory",
+			"dojo/ready",
+			"dojo/when",
+			"dojo/Stateful",
+			"dojox/mvc/getStateful",
+			"dojo/data/ItemFileWriteStore",
+			"dojo/store/Memory",
+			"dojox/mvc/EditStoreRefController",
+			"dojox/mvc/ListController",
+			"dojox/mvc/at",
+			"dojox/mvc/Group",
+			"dojox/mvc/WidgetList",
+			"dojox/mvc/Templated",
+			"dojox/mvc/_InlineTemplateMixin",
+			"dojox/mvc/Output",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Container",
+			"dojox/mobile/ListItem",
+			"dojox/mobile/Button",
+			"dojox/mobile/ToolBarButton",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/CheckBox",
+			"dojox/mobile/EdgeToEdgeDataList",
+			"dojox/mobile/View",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/SimpleDialog",
+			"dojox/mobile/Heading",
+			"dojox/mobile/deviceTheme"
+		], function(lang, declare, connect, registry, dom, parser, MemoryStore, ready, when, Stateful, getStateful, ItemFileWriteStore, Memory, EditStoreRefController, ListController, at){
+			window.at = at;
+
+			function _addNewItem(e){
+				console.log("_addNewItem called");
+
+				var datamodel = currentctrl;
+				var parentId;
+				try{
+					parentId = datamodel.model[0].parentId;
+				}catch (e){
+					console.log("Warning: itemlistmodel is empty, get parentId from listsmodel");
+					parentId = app.loadedModels.listsmodel[window.selected_configuration_item].id;
+				}
+
+				var index = datamodel.model.length;
+				var insert = new Stateful({
+					"id": (new Date().getTime()),
+					"parentId": parentId,
+					"title": "",
+					"notes": "To do",
+					"due": "2010-10-15T11:03:47.681Z",
+					"completionDate": "",
+					"reminder": "2010-10-15T11:03:47.681Z",
+					"repeat": 0,
+					"priority": 0,
+					"hidden": false,
+					"completed": false,
+					"deleted": false
+				});
+				datamodel.model.push(insert);
+				datamodel.commit(); //need to commit after delete. TODO: need to enhance the performance
+				var r = registry.byId("todomain");
+				r.performTransition("details", 1, "none");
+				movedTo(index);
+				//update cache
+				//app.loadedModels.itemlistsmodel[parentId] = datamodel.model;
+				//refresh view
+				//window.showData(datamodel.model);
+			}
+
+			completeConverter = {
+				format: function(value){
+					console.log("****in completeConverter format value = "+value);
+					//return "dijitMenuItemLabel" + (value ? " complete" : "");
+					//ctrl.set("completed", false);
+					//ctrlComplete.set("completed", true);
+					//for(var a = this.source.inModel, i = 0; i < a.length; i++){
+					//	if(a[i].id == this.target.id){
+							console.log("****in completeConverter format this.source.id = "+this.source.id);
+							console.log(this.source);
+							//return a[i];
+					//	}
+					//}
+					return value;
+				},
+				parse: function(value){
+					console.log("****in completeConverter parse value = "+value);
+					console.log("****in completeConverter parse this.source.id = "+this.source.id);
+					console.log(this.source);
+					var model = ctrlComplete.model;
+					if(value){
+						model = currentctrl.model;
+					}
+					for(var a = model, i = 0; i < a.length; i++){
+						if(a[i].id == this.source.id){
+							if(value){ // remove from list and move to completed
+								window.setTimeout(lang.hitch(window, moveToComplete, currentctrl.model, ctrlComplete.model, i, value), 500);
+							}else{
+								window.setTimeout(lang.hitch(window, moveFromComplete, ctrlComplete.model, currentctrl.model, i, value), 500);
+							}
+						}
+					}
+					//throw new Error(); // Stop copying the new value for unchecked case
+					if(!value){ throw new Error(); } // Stop copying the new value for unchecked case
+					return value;
+				}
+			};
+
+			var listData = {
+				"identifier": "id",
+				"items": [
+					{
+						"id": 100,
+						"parentId":1,
+						"title": "item 1 to do for 1",
+						"notes": "To do",
+						"due": "2010-10-15T11:03:47.681Z",
+						"completionDate": "",
+						"reminder": "2010-10-15T11:03:47.681Z",
+						"repeat": 0,
+						"priority": 0,
+						"hidden": false,
+						"completed": false,
+						"deleted": false
+					},
+					{
+						"id": 103,
+						"parentId":1,
+						"title": "item 3 to do for 1",
+						"notes": "To do",
+						"due": "2010-10-15T11:03:47.681Z",
+						"completionDate": "",
+						"reminder": "2010-10-15T11:03:47.681Z",
+						"repeat": 2,
+						"priority": 2,
+						"hidden": false,
+						"completed": false,
+						"deleted": false
+					}
+				]
+			};
+
+			var listData1 = {
+				"identifier": "id",
+				"items": [
+					{
+						"id": 101,
+						"parentId":2,
+						"title": "item 1 to do for 2",
+						"notes": "To do",
+						"priority": 0,
+						"due": "2010-10-15T11:03:47.681Z",
+						"completionDate": "",
+						"reminder": "2010-10-15T11:03:47.681Z",
+						"repeat": 0,
+						"hidden": false,
+						"completed": false,
+						"deleted": false
+					},
+					{
+						"id": 103,
+						"parentId":2,
+						"title": "item 3 else to do for 2",
+						"notes": "To do",
+						"priority": 0,
+						"due": "2010-10-15T11:03:47.681Z",
+						"completionDate": "",
+						"reminder": "2010-10-15T11:03:47.681Z",
+						"repeat": 0,
+						"hidden": false,
+						"completed": false,
+						"deleted": false
+					}
+				]
+			};
+
+			var completedListData = {
+				"identifier": "id",
+				"items": [
+					{
+						"id": 102,
+						"parentId":2,
+						"title": "item 2 to do for 0",
+						"notes": "To do",
+						"due": "2010-10-15T11:03:47.681Z",
+						"completionDate": "",
+						"reminder": "2010-10-15T11:03:47.681Z",
+						"repeat": 0,
+						"priority": 1,
+						"hidden": false,
+						"completed": true,
+						"deleted": false
+					}
+				]
+			};
+
+			var allListsData = {
+				"identifier": "id",
+				"items": [
+					{
+						"title":"Reminders",
+						"id":0,
+						"parentId":null,
+						"itemsurl":"../resources/data/items-for-0.json"
+					},
+					{
+						"title":"Work Items",
+						"id":1,
+						"parentId":null,
+						"itemsurl":"../resources/data/items-for-1.json"
+					}
+				]
+			};
+
+			var inited,
+			ctrlClass = declare([EditStoreRefController, ListController], {
+				cursorIndex: 0,
+				completed: "",
+				completedTyped: "",
+				_refModelProp: "model",
+
+				addEmpty: function(){
+					this.model.push(new Stateful({First: "", Last: "", Location: "", Office: "", Email: "", Tel: "", Fax: ""}));
+					this.set("cursorIndex", this.get("length") - 1);
+				},
+
+				remove: function(idx){
+					this.model.splice(idx, 1);
+					if(this.get("cursorIndex") < 0){
+						this.set("cursorIndex", this.get("length") - 1);
+					}
+				},
+
+				_setCompletedAttr: function(value){
+					this.set("completedTyped", value);
+					console.log("_setCompletedAttr called for completedTyped="+this.completedTyped +" with value="+value);
+
+					when(this.queryStore(), function(){
+						if(inited){
+							parser.parse();
+							//inited = true;
+							var d = registry.byId("addbutton");
+							connect.connect(d, "onClick", this, _addNewItem);
+						}
+					});
+					this._set("completed", value);
+				}
+			});
+			ctrlListsClass = declare([EditStoreRefController, ListController], {
+				cursorIndex: 0,
+				_refModelProp: "model"
+			});
+
+			listsCtrls = [];
+			ctrlComplete = new ctrlClass({store: new Memory({data: completedListData})});
+			listsCtrls.push(ctrlComplete);
+			currentctrl = new ctrlClass({store: new Memory({data: listData})});
+			listsCtrls.push(currentctrl);
+			ctrl1 = new ctrlClass({store: new Memory({data: listData1})});
+			listsCtrls.push(ctrl1);
+
+			listsCtrl = new ctrlListsClass({store: new Memory({data: allListsData})});
+			when(listsCtrl.queryStore(), function(){
+				listsCtrls[0].set("completed", true);
+				//currentctrl.set("completed", false);
+				listsCtrls[1].set("completed", false);
+				inited = true;
+				listsCtrls[2].set("completed", false);
+			});
+
+			// called when showing item details
+			movedTo = function(index) {
+				console.log("movedTo called with index"+index);
+				currentctrl.set('cursorIndex', index);
+				var g = registry.byId("detailsGroup");
+				g.set("target", at(currentctrl, 'cursor'));
+				var h = registry.byId("detailsHeading");
+				h.set("label","To-Do Details");
+				var h2 = dom.byId("detailsHeading2");
+				h2.innerHTML="To Do Item";
+			};
+
+			// called when showing item details for a completed item
+			movedToCompleted = function(index) {
+				console.log("movedToCompleted called with index"+index);
+				ctrlComplete.set('cursorIndex', index);
+				var g = registry.byId("detailsGroup");
+				g.set("target", at(ctrlComplete, 'cursor'));
+				var h = registry.byId("detailsHeading");
+				h.set("label","Completed To-Do");
+				var h2 = dom.byId("detailsHeading2");
+				h2.innerHTML="Completed Item";
+			};
+
+			// called when an item is completed
+			moveToComplete = function(fromModel, toModel, i, value) {
+				console.log("****in moveToComplete value = "+value);
+				var t = fromModel.splice(i, 1);
+				t[0].set("completed", value);
+				toModel.push(t[0]);
+			};
+
+			// called when a completed items is unchecked
+			moveFromComplete = function(fromModel, toModel, i, value) {
+				console.log("****in moveFromComplete value = "+value);
+				var t = fromModel.splice(i, 1);
+				t[0].set("completed", value);
+				toModel = listsCtrls[t[0].get('parentId')].model;
+				toModel.push(t[0]);
+			};
+
+			// called when a different list is selected
+			selectList = function(index) {
+				if(index != -1){
+					index = parseInt(index)+1;
+				}else{
+					index = '0';
+				}
+				console.log("selectList called with index"+index);
+				listsCtrl.set('cursorIndex', index);
+				//listsCtrl.set('cursorIndex', index);//listItems
+				var r = registry.byId("listItems");
+				currentctrl = listsCtrls[index];
+				r.set("children", at(currentctrl, 'model'));
+			};
+
+			// called to delete the selected item
+			deleteSelected = function() {
+				console.log("deleteSelected called with currentctrl.cursorIndex="+currentctrl.cursorIndex);
+				console.log("deleteSelected called with currentctrl.cursor.title="+currentctrl.cursor.title);
+				currentctrl.model.splice(currentctrl.cursorIndex, 1);
+				var r = registry.byId("details");
+				r.performTransition("todomain", 1, "none");
+			};
+
+			showDlg = function(dlg){
+				registry.byId(dlg).show();
+			};
+
+			hideDlg = function(dlg){
+				registry.byId(dlg).hide();
+			};
+
+			resetAll = function() {
+				console.log("resetAll called");
+			};
+		});
+
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Container" style="width:300px;border-right:1px solid black;">
+			<div id="settings" data-dojo-type="dojox.mobile.ScrollableView">
+			<!--  <h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Configure</h1> -->
+			<h2 data-dojo-type="dojox.mobile.Heading" region="top">
+				Configure
+				<img style="position: absolute; display: block; width: 32px; height: 32px; right: 0; top: 0" onClick="editConfiguration();" src="../images/settings.png">
+			</h2>
+ 			<ul data-dojo-type="dojox.mobile.RoundRectList">
+				<li data-dojo-type="dojox.mobile.ListItem"  clickable="true"
+				data-dojo-props="onClick: function(){console.log('selected list ', '-1'); selectList('-1');}">
+					Completed
+				</li>
+			</ul>
+			<ul data-dojo-type="dojox/mobile/RoundRectList"
+				data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+				data-dojo-props="children: at(listsCtrl, 'model')"
+				data-mvc-child-type="dojox/mvc/Templated"
+				data-mvc-child-mixins="dojox/mobile/ListItem"
+				data-mvc-child-props="clickable: true,
+				                      onClick: function(){ console.log('Selected list: ' + this.indexAtStartup); selectList(this.indexAtStartup); }">
+				<script type="dojox/mvc/InlineTemplate">
+					<li class="mblVariableHeight">
+						<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'title')"></div>
+					</li>
+				</script>
+			</ul>
+		</div>
+	</div>
+	<div data-dojo-type="dojox.mobile.Container">
+		<div id="main">
+			<div id="leftNav"></div>
+			<div id="mainContent">
+				<div id="todomain" data-dojo-type="dojox.mobile.View" selected="true">
+					<div data-dojo-type="dojox.mvc.Group"
+						data-dojo-props="target: at(listsCtrl, 'cursor')">
+						<div data-dojo-type="dojox.mobile.Heading" region="top"
+							data-dojo-props="label: at('rel:','title')">
+							<span id="addbutton"  data-dojo-type="dojox.mobile.ToolBarButton"
+									data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;"
+									onclick="console.log('+ was clicked')"></span>
+						</div>
+					</div>
+					<ul id="listItems"
+						data-dojo-type="dojox/mobile/RoundRectList"
+						data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+						data-dojo-props="children: at(currentctrl, 'model')"
+						data-mvc-child-type="dojox/mvc/Templated"
+						data-mvc-child-mixins="dojox/mobile/ListItem"
+						data-mvc-child-props="moveTo: 'details',
+						                      clickable: true,
+						                      transitionOptions: {title: 'Detail', target: 'details,detail'},
+						                      callback: function(){ movedTo(this.indexAtStartup); },
+						                      onClick: function(){ console.log('Select item : ' + this.indexAtStartup); window.selected_item = this.indexAtStartup; }">
+						<script type="dojox/mvc/InlineTemplate">
+							<li class="mblVariableHeight">
+								<table>
+									<tr>
+										<td>
+											<input preventTouch='true' type='checkbox'
+												data-dojo-type="dojox.mobile.CheckBox"
+												data-dojo-props="checked: at('rel:', 'completed').transform(completeConverter)"/></td>
+										<td data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:', 'title')"></td>
+									</tr>
+								</table>
+							</li>
+						</script>
+					</ul>
+				</div>
+				<div id="details" data-dojo-type="dojox.mobile.ScrollableView">
+					<h1 id="detailsHeading" data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="todomain">To-Do Details</h1>
+					<div id="detailsGroup" class="fieldset" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(currentctrl, 'cursor')">
+						<h2 id="detailsHeading2">Completed Items</h2>
+						<div class="field-row">
+							<span>To Do</span>
+							<input id="todo" data-dojo-type="dojox.mobile.TextBox"
+								placeholder="To do placeholder"
+								data-dojo-props="value: at('rel:', 'title')"/>
+						</div>
+						<ul data-dojo-type="dojox.mobile.RoundRectList">
+							<li data-dojo-type="dojox.mobile.ListItem"
+								data-dojo-props="clickable: true,
+								                 noArrow: true,
+								                 onClick: function(){ console.log('delete item'); showDlg('dlg_confirm'); }">
+								Delete
+							</li>
+						</ul>
+					</div>
+				</div>
+			</div>
+		</div>
+		<div id="dlg_confirm" data-dojo-type="dojox.mobile.SimpleDialog">
+			<div class="mblSimpleDialogTitle">Delete Confirmation</div>
+			<div class="mblSimpleDialogText">Are you sure you want to delete this item?</div>
+			<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton" onclick="hideDlg('dlg_confirm')">No</button>
+			<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton mblBlueButton" onclick="hideDlg('dlg_confirm'); deleteSelected();">Yes</button>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/WidgetList_tests/test_mobile-list-single-sel-mvc.html b/dojox/mvc/tests/WidgetList_tests/test_mobile-list-single-sel-mvc.html
new file mode 100644
index 0000000..a0856fc
--- /dev/null
+++ b/dojox/mvc/tests/WidgetList_tests/test_mobile-list-single-sel-mvc.html
@@ -0,0 +1,171 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>MVC Repeat with Selectable RoundRectList - Single Select</title>
+
+	<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true, parseOnLoad: false, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dijit/registry",
+			//"dojox/mobile/parser",
+			"dojo/parser",
+			"dojo/store/Memory",
+			"dojo/ready",
+			"dojo/when",
+			"dojox/mvc/getStateful",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat",
+			"dojox/mvc/Templated",
+			"dojox/mvc/WidgetList",
+			"dojox/mvc/Output",
+			"dojox/mobile",
+			"dojox/mobile/Button",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/CheckBox",
+			"dojox/mobile/deviceTheme"
+		], function(lang, registry, parser, MemoryStore, ready, when, getStateful){
+			var search_results_init1 =
+			[{
+				"Query" : "Engineers1",
+				"Results" : [
+					{
+						"First"	  : "Anne1",
+						"Last"	  : "Ackerman1",
+						"Checked" : true
+					},
+					{
+						"First"	  : "Ben1",
+						"Last"	  : "Beckham1",
+						"Checked" : false
+					},
+					{
+						"First"	  : "Chad1",
+						"Last"	  : "Chapman1",
+						"Checked" : false
+					}
+				]
+			}];
+
+			var search_results_init2 =
+				[{
+					"Query" : "Engineers1",
+					"Results" : [
+						{
+							"First"	  : "Anne2",
+							"Last"	  : "Ackerman2",
+							"Checked" : false
+						},
+						{
+							"First"	  : "Ben2",
+							"Last"	  : "Beckham2",
+							"Checked" : true
+						},
+						{
+							"First"	  : "Chad2",
+							"Last"	  : "Chapman2",
+							"Checked" : false
+						}
+					]
+				}];
+			var memStore1 = new MemoryStore({data : search_results_init1});
+			//model1 = mvc.newStatefulModel({ store : memStore1 })[0];
+
+				when(memStore1.query(), function(data){
+					model1 = getStateful(data)[0];
+					model1Orig = lang.clone(model1);
+					//if(model1 && model2 && model3){ runTests(); }
+				});
+
+
+		var memStore2 = new MemoryStore({data : search_results_init2});
+		//model2 = mvc.newStatefulModel({ store : memStore2 })[0];
+				when(memStore2.query(), function(data){
+					model2 = getStateful(data)[0];
+					model2Orig = lang.clone(model2);
+					//if(model1 && model2 && model3){ runTests(); }
+				});
+			
+			// when "dojo/ready" is ready call parser.parse (if not doing parseOnLoad)
+			ready(function(){
+				parser.parse();
+			});
+
+
+			// called to reset the model for each of the repeats
+			swapToModel1 = function() {
+				registry.byId('repeatId1').set('children',model1.Results); 
+				registry.byId('repeatId2').set('children',model1.Results); 
+			};
+
+			swapToModel2 = function() {
+				registry.byId('repeatId1').set('children',model2.Results); 
+				registry.byId('repeatId2').set('children',model2.Results); 
+			};
+
+			resetAll = function() {
+				model1 = lang.clone(model1Orig);
+				model2 = lang.clone(model2Orig);
+				registry.byId('repeatId1').set('children',model1.Results); 
+				registry.byId('repeatId2').set('children',model1.Results); 
+			};
+			
+
+		});
+		
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h2>MVC Repeat with Selectable RoundRectDataList - Single Select</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<h4>Here is one using dojox.mvc.Repeat as a mixin with no Group and dojo.parser instead of dojox.mobile.parser it is all good using mixin.</h4>
+					<ul data-dojo-type="dojox.mobile.RoundRectList" id="repeatId1" select="single"
+						data-dojo-mixins="dojox/mvc/WidgetList"
+						data-mvc-child-type="dojox/mobile/ListItem"
+						data-mvc-child-props="label: at(this.target, 'First'), checked: at(this.target, 'Checked'), variableHeight: true"
+						data-dojo-props="children: model1.Results">
+					</ul>
+					<h4>You can update the label or checked from here to update the model.</h4>
+					<div id="repeatId2" data-dojo-type="dojox/mvc/WidgetList"
+					 data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+					 data-dojo-props="children: model1.Results">
+						<script type="dojox/mvc/InlineTemplate">
+							<div>
+								<input class="cell"
+									data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'First')">
+								<label for="CBInput${indexAtStartup}"
+									data-dojo-type="dijit/_WidgetBase"
+									data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at('rel:', 'First')"></label>
+								<input class="cell" type="checkbox" id="CBInput${indexAtStartup}"
+									data-dojo-type="dojox/mobile/CheckBox"
+									data-dojo-props="checked: at('rel:', 'Checked')">
+							</div>
+						</script>
+					</div>
+					<br/>Model:
+					<button type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){swapToModel2();}">Swap Model2</button> 
+					<button type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){swapToModel1();}">Swap Model1</button> 					
+				 	<button id="reset" type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){resetAll();}">Reset all</button> 	
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/WidgetList_tests/test_mobile-listItem-with-icon-and-sub-lables.html b/dojox/mvc/tests/WidgetList_tests/test_mobile-listItem-with-icon-and-sub-lables.html
new file mode 100644
index 0000000..74563e7
--- /dev/null
+++ b/dojox/mvc/tests/WidgetList_tests/test_mobile-listItem-with-icon-and-sub-lables.html
@@ -0,0 +1,188 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<style>
+		.adminlistitem {
+			font-size:12px;
+			margin-right: 10px;
+			padding-right: 10px;
+			line-height: 59px; /* 20px; */
+			height: 59px;  
+		}	
+		.admin2LineListItem1 {
+			height: 16px; 
+			color: #222222;
+			font-weight: bold;
+			margin: -8px 0px 10px 8px;
+		}
+		.admin2LineListItem2 {
+			height: 16px; 
+			color: #464646;
+			font-weight: normal;
+			margin: -13px 0 10px 8px;
+		}
+		
+	</style>
+
+	<title>MVC WidgetList with EdgeToEdgeList with icons and sub-label</title>
+
+	<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true, parseOnLoad: false, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dijit/registry",
+			"dojo/parser",
+			"dojo/store/Memory",
+			"dojo/ready",
+			"dojo/when",
+			"dojox/mvc/EditStoreRefListController",
+			"dojox/mvc/at",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat",
+			"dojox/mvc/Templated",
+			"dojox/mvc/WidgetList",
+			"dojox/mvc/Output",
+			"dojox/mobile",
+			"dojox/mobile/Button",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/CheckBox",
+			"dojox/mobile/EdgeToEdgeList",
+			"dojox/mvc/WidgetList",
+			"dojox/mvc/_InlineTemplateMixin",
+			"dojox/mobile/deviceTheme"
+		], function(lang, registry, parser, MemoryStore, ready, when, EditStoreRefListController){
+			var projects_init1 = {
+  				"identifier": "id",
+   				"items": [ 
+                    {
+                        "id"  : "ID1001",
+                        "label"   : "Project 01",
+                        "displayName"   : "Project 01",
+                        "shortDesc"    : "Short Description for project 01",
+                        "longDesc"    : "Long Description for project 01",
+                        "checked" : true,
+                        "icon" : "../images/directory_45.png"
+                    },
+                    {
+                        "id"  : "ID1002",
+                        "label"   : "Project 02",
+                        "displayName"   : "Project 02",
+                        "shortDesc"    : "Short Description for project 02",
+                        "longDesc"    : "Long Description for project 02",
+                        "checked" : true,
+                        "icon" : "../images/directory_45.png"
+                    },
+                    {
+                        "id"  : "ID1003",
+                        "label"   : "Project 03",
+                        "displayName"   : "Project 03",
+                        "shortDesc"    : "Short Description for project 03",
+                        "longDesc"    : "Long Description for project 03",
+                        "checked" : false,
+                        "icon" : "../images/directory_45.png"
+                    }
+                ]
+};
+
+			var memStore1 = new MemoryStore({data : projects_init1});
+
+			ctrl = new EditStoreRefListController({store: memStore1});
+			when(ctrl.queryStore(), function(data){
+				model1 = ctrl.model;
+			});
+
+			
+			// when "dojo/ready" is ready call parser.parse (if not doing parseOnLoad)
+			ready(function(){
+				parser.parse();
+			});
+			
+		});
+		
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<script type="dojo/require">registry: "dijit/registry"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h4>MVC WidgetList with EdgeToEdgeList with icons and sub-label</h4>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<h5>EdgeToEdgeList with a WidgetList with child type of ListItem, sets label, icon and checked and multiple select.</h5>
+					<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" id="repeatId1B" select="multiple"
+						data-dojo-mixins="dojox/mvc/WidgetList"
+						data-mvc-child-type="dojox/mobile/ListItem"
+						data-mvc-child-props="label: at(this.target, 'displayName'), 
+											icon:  at(this.target, 'icon'),
+											checked: at(this.target, 'checked'), 
+											variableHeight: true"
+						data-dojo-props="children: model1">
+					</ul>
+
+					<h5>EdgeToEdgeList with a WidgetList with child type of mvc/Templated with ListItem mixin, sets label, icon and checked and multiple select.</h5>					
+					<ul data-dojo-type="dojox.mobile.EdgeToEdgeList" id="repeatId1"
+						data-dojo-props='select:"multiple", children: model1'
+						data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+						data-mvc-child-type="dojox/mvc/Templated"
+						data-mvc-child-mixins="dojox/mobile/ListItem"
+						data-mvc-child-props="clickable: true, 
+												_relTargetProp: 'childTarget',  // avoid using target for a ListItem since it uses that
+	   	                          				icon:  at(this.childTarget, 'icon'), // setting icon:  '../images/directory_45.png' works
+                              					noArrow: true,
+                              					indexAtStartup: this.indexAtStartup,
+												checked: at(this.childTarget, 'checked'),
+                              					onClick: function(e){                              						
+                              						console.log(this.id);
+                              						console.log(e);
+                              						console.log(registry.byId(this.id));
+                              						console.log(this.indexAtStartup); return true;}">
+						<script type="dojox/mvc/InlineTemplate">
+							<li class="adminlistitem">
+                   			  <div class="mblListItemLabel">
+    					    		<div class="admin2LineListItem1" data-dojo-type="dojox/mvc/Output" 
+    					    			data-dojo-props="value: at('rel:','displayName')"></div> 
+	    				    		<div class="admin2LineListItem2" data-dojo-type="dojox/mvc/Output" 
+	    				    			data-dojo-props="value: at('rel:','shortDesc')"></div> 
+			                  </div>
+		            		</li>
+						</script>
+					</ul>
+					
+					<h5>WidgetList with an mvc/InlineTemplate, you can change the label, or checked here.</h5>					
+					<div id="repeatId2" data-dojo-type="dojox/mvc/WidgetList"
+					 data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+					 data-dojo-props="children: model1">
+						<script type="dojox/mvc/InlineTemplate">
+							<div>
+								<input class="cell"
+									data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'displayName')">
+								<label for="CBInput${indexAtStartup}"
+									data-dojo-type="dijit/_WidgetBase"
+									data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at('rel:', 'displayName')"></label>
+								<input class="cell" type="checkbox" id="CBInput${indexAtStartup}"
+									data-dojo-type="dojox/mobile/CheckBox"
+									data-dojo-props="checked: at('rel:', 'checked')">
+							</div>
+						</script>
+					</div>					
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/WidgetList_tests/test_mvc_Menu.html b/dojox/mvc/tests/WidgetList_tests/test_mvc_Menu.html
new file mode 100644
index 0000000..3e1432b
--- /dev/null
+++ b/dojox/mvc/tests/WidgetList_tests/test_mvc_Menu.html
@@ -0,0 +1,466 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
+	<title>Menu System Test</title>
+
+	<style type="text/css">
+		@import "../../../../dijit/themes/claro/document.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+
+		body { padding: 0; }
+
+		/* styling for left-hand-side navigation menu to become a column equal to length of page */
+		#formattingTable {
+			border: 0;
+			border-spacing: 0;
+		}
+		#contentContainer { padding: 2em; }
+
+		#navMenu {
+			/* make the sidebar menu blend in with the whole sidebar */
+			border: none;
+		}
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad: 0, isDebug: 1, async: 1, mvc: {debugBindings: 1}"></script>
+
+	<!-- not needed, for testing alternate themes -->
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/declare",
+			"dojo/_base/lang",
+			"dojo/aspect",
+			"dojo/dom",
+			"dojo/parser",	// scan page for widgets and instantiate them
+			"dojo/when",
+			"dojox/mvc/at",
+			"dijit/Menu",
+			"dijit/MenuItem",
+			"dijit/PopupMenuItem",
+			"dijit/PopupMenuBarItem",
+			"dijit/CheckedMenuItem",
+			"dijit/MenuSeparator",
+			"dojox/mvc/getStateful",
+			"dojox/mvc/WidgetList",
+			"dijit/MenuBar",
+			"dijit/MenuBarItem",
+			"dijit/ColorPalette",
+			"dijit/form/TextBox",
+			"dijit/dijit", // optimize: load dijit layer
+			"dojo/domReady!"
+		], function(declare, lang, aspect, dom, parser, when, at, Menu, MenuItem, PopupMenuItem, PopupMenuBarItem, CheckedMenuItem, MenuSeparator, getStateful, WidgetList){
+			var mixin = declare(null, {
+				_getPropertiesAttr: function(){
+					var list = this.inherited(arguments);
+					return ["children", "popupType"].concat(list);
+				},
+
+				startup: function(){
+					this.popup = new Menu(); // Stop PopupMenuItem.startup() from attempting to find popup from DOM
+					this.inherited(arguments);
+					this.popup.destroy();
+					this.popup = null;
+					if(this.popupType){
+						this.popup = new (lang.getObject(this.popupType) || require(this.popupType))(this.params);
+					}else if(this.children){
+						this.popup = new (declare([Menu, WidgetList], {childType: getChildMenuType, childParams: getChildMenuParams}))(this.params);
+					}
+					if(this.popupType || this.children){
+						this.ownerDocumentBody.appendChild(this.popup.domNode);
+						this.popup.startup();
+						this.popup.domNode.style.display = "none";
+					}
+				}
+			});
+
+			declare("dojox.mvc.tests.PopupMenuItem", [PopupMenuItem, mixin]);
+			declare("dojox.mvc.tests.PopupMenuBarItem", [PopupMenuBarItem, mixin]);
+
+			getChildMenuType = function(parent){
+				return this.children || this.popupType ? (parent._isMenuBar ? "dojox.mvc.tests.PopupMenuBarItem" : "dojox.mvc.tests.PopupMenuItem") :
+				 this.isSeparator ? "dijit/MenuSeparator" :
+				 this.checked !== void 0 ? "dijit/CheckedMenuItem" :
+				 parent._isMenuBar ? "dijit/MenuBarItem" :
+				 "dijit/MenuItem";
+			};
+
+			getChildMenuParams = function(){
+				return {"*": at(this.target, "*")};
+			};
+
+			updateButtons = function(created){
+				dom.byId("prog_menu").innerHTML = created ? "This div has a programmatic context menu on it that's different to the page menu." : "No programmatic menu on this div, should get page level menu.";
+				dom.byId("createButton").disabled = created;
+				dom.byId("destroyButton").disabled = !created;
+			};
+
+			var separatorItem = {isSeparator: true},
+			 disabledItem = {label: "Disabled Item", disabled: true, onClick: function(){ alert("this should NOT appear"); }},
+			 differentPopupItem = {label: "Different popup", popupType: "dijit/ColorPalette"},
+			 enabledSubmenuItem = {
+			 	label: "{E}nabled Submenu",
+			 	children: [
+					{label: "Submenu Item One", onClick: function(){ console.log("Submenu 1!") }},
+					{label: "Submenu Item Two", onClick: function(){ console.log("Submenu 2!") }},
+					{label: "Deeper Submenu", children: [
+						{label: "Sub-sub-menu Item One", onClick: function(){ console.log("Sub-submenu 1!") }},
+						{label: "Sub-sub-menu Item Two", onClick: function(){ console.log("Sub-submenu 2!") }}
+					]}
+				]
+			}, disabledSubmenuItem = {
+				label: "Disabled Submenu",
+				disabled: true,
+				children: [
+					{label: "Submenu Item One", onClick: function(){ console.log("Submenu 1!") }},
+					{label: "Submenu Item Two", onClick: function(){ console.log("Submenu 2!") }}
+				]
+			}, checkedMenuItems = [
+				{label: "Checked", checked: true, onChange: function(val){ console.log("Now set to " + val); }},
+				{label: "Not Checked", checked: false},
+				{label: "Checked Disabled", checked: true, disabled: true}
+			], editMenuItems = [
+				{label: "C{u}t", iconClass: "dijitEditorIcon dijitEditorIconCut", onClick: function(){ console.log("not actually cutting anything, just a test!") }, accelKey: "Ctrl+X"},
+				{label: "{C}opy", iconClass: "dijitEditorIcon dijitEditorIconCopy", onClick: function(){ console.log("not actually copying anything, just a test!") }, accelKey: "Ctrl+C"},
+				{label: "{P}aste", iconClass: "dijitEditorIcon dijitEditorIconPaste", onClick: function(){ console.log("not actually pasting anything, just a test!") }, accelKey: "Ctrl+V"}
+			];
+
+			menubarData = getStateful([
+				{
+					label: "{F}ile",
+					accessKey: "F",
+					children: [
+						{label: "{N}ew"},
+						{label: "{O}pen"},
+						separatorItem,
+						{label: "{S}ave", iconClass:"dijitEditorIconSave"},
+						{label: "Save {A}s..."}
+					]
+				},
+				{
+					label: "{E}dit",
+					accessKey: "E",
+					children: editMenuItems
+				},
+				{
+					label: "{V}iew",
+					accessKey: "V",
+					children: [
+						{label: "Normal"},
+						{label: "Outline"},
+						{
+							label: "{Z}oom",
+							children: [
+								{label: "50%"},
+								{label: "75%"},
+								{label: "100%"},
+								{label: "150%"},
+								{label: "200%"}
+							]
+						}
+					]
+				},
+				{
+					label: "{H}elp",
+					accessKey: "H",
+					children: [
+						{label: "Help Topics"},
+						{label: "About dojox/mvc"}
+					]
+				},
+				{label: "{D}isabled", accessKey: "D", disabled: true, children: [{label: "You should not see this"}]},
+				{label: "E{m}pty", accessKey: "M", children: []},
+				{label: "Click me! ({Z})", accessKey: "Z", onClick: function(){ console.log("no submenu, just a clickable MenuItem"); }}
+			]);
+
+			windowContextMenuData = getStateful([
+				{label: "Context Menu", onClick: function(){ console.log("Hello world"); }},
+				separatorItem,
+				disabledItem
+			].concat(editMenuItems).concat([
+				separatorItem,
+				enabledSubmenuItem,
+				disabledSubmenuItem,
+				differentPopupItem,
+				separatorItem
+			]).concat(checkedMenuItems).concat([
+				separatorItem,
+				{label: "Bigger Submenu", children: [
+					{label: "Item One"},
+					{label: "Item Two"},
+					{label: "Item Three"},
+					{label: "Item Four"},
+					{label: "Item Five"},
+					{label: "Item Six"},
+					{label: "Item Seven"},
+					{label: "Item Eight"},
+					{label: "Item Nine"},
+					{label: "Item Ten"}
+				]}
+			]));
+
+			leftClickContextMenuData = getStateful([
+				{label: "Left Click Menu", disabled: true},
+				{label: "Enabled Item", onClick: function(){ console.log("Hello world"); }},
+				disabledItem,
+				separatorItem
+			].concat(editMenuItems).concat([
+				separatorItem,
+				enabledSubmenuItem,
+				disabledSubmenuItem,
+				differentPopupItem
+			]));
+
+			navMenuData = getStateful([
+				{label: "Drama", iconClass: "dijitEditorIcon dijitEditorIconPaste", onClick: function(){ console.log("drama!"); }},
+				{label: "Cut", iconClass: "dijitEditorIcon dijitEditorIconCut", onClick: function(){ console.log("not actually cutting anything, just a test!") }},
+				{label: "Copy", iconClass: "dijitEditorIcon dijitEditorIconCopy", onClick: function(){ console.log("not actually copying anything, just a test!") }},
+				{label: "Paste", iconClass: "dijitEditorIcon dijitEditorIconPaste", onClick: function(){ console.log("not actually pasting anything, just a test!") }},
+				separatorItem,
+				enabledSubmenuItem,
+				disabledSubmenuItem,
+				differentPopupItem,
+				separatorItem
+			].concat(checkedMenuItems));
+
+			createMenu = function(){
+				// create a menu programmatically
+				function fClick(){console.log("clicked!")}
+
+				pMenu = new (declare([Menu, WidgetList], {
+					childType: getChildMenuType,
+					childParams: getChildMenuParams
+				}))({
+					targetNodeIds: ["prog_menu"],
+					id: "progMenu",
+					children: getStateful([
+						{label: "Programmatic Context Menu", disabled: true},
+						separatorItem,
+						{label: "Simple menu item", onClick: fClick, accelKey: "Shift+S"},
+						{label: "Another menu item", onClick: fClick, accelKey: "Ctrl+A"},
+						{label: "With an icon", iconClass: "dijitEditorIcon dijitEditorIconCut", onClick: fClick},
+						{label: "dojo/aspect clicking", accelKey: "Alt+D"},
+						{label: "checkable menu item", checked: false},
+						enabledSubmenuItem
+					])
+				});
+				pMenu.startup();
+
+				aspect.after(pMenu.getChildren()[5], "onClick", function(){ console.log("click! handler created via dojo/aspect" )});
+
+				updateButtons(true);
+
+				dom.byId("prog_menu").innerHTML="This div has a programmatic context menu on it that's different to the page menu.";
+
+				dom.byId("createButton").disabled = true;
+				dom.byId("destroyButton").disabled = false;
+			};
+
+			destroyMenu = function(){
+				pMenu.destroyRecursive();
+				updateButtons(false);
+			};
+
+			when(parser.parse(), function(){
+				// need to explicitly update our buttons states, otherwise the
+				// browser will remember the last states of them before reloading
+				// (so a programmatic menu is created, reload, and "the create
+				// programmatic menu" button is still in disabled state)
+				updateButtons(false);
+			});
+		});
+	</script>
+</head>
+<body class="claro" role="main">
+	<div id="windowContextMenu"
+	 data-dojo-type="dijit/Menu"
+	 data-dojo-mixins="dojox/mvc/WidgetList"
+	 data-dojo-props='contextMenuForWindow: true, style: "display: none;", children: windowContextMenuData, childType: getChildMenuType, childParams: getChildMenuParams'>
+	</div>
+
+	<div id="leftClickContextMenu"
+	 data-dojo-type="dijit/Menu"
+	 data-dojo-mixins="dojox/mvc/WidgetList"
+	 data-dojo-props='leftClickToOpen: true, targetNodeIds: ["input2"], style: "display: none;", children: leftClickContextMenuData, childType: getChildMenuType, childParams: getChildMenuParams'>
+	</div>
+
+	<table id="formattingTable" role="presentation">
+		<tr>
+			<td style="width:0;">
+				<!-- This is here for tabIndex testing.
+					 Use textarea since Chrome 1.0 likes it better for TABing and
+					 because it has innerText property and because it doesn't mess
+					 with the URL when clicked -->
+				<textarea aria-label="random link" id="link" tabIndex="0" readOnly class="dijitReset" style="font-family:monospace;font-size:12px;width:84px;text-decoration:underline;overflow:hidden;background-color:transparent;" rows=1>random link</textarea>
+			</td>
+			<td id="menuBarContainer" style="width:100%;">
+				<div id="menubar"
+				 data-dojo-type="dijit/MenuBar"
+				 data-dojo-mixins="dojox/mvc/WidgetList"
+				 data-dojo-props="children: menubarData, childType: getChildMenuType, childParams: getChildMenuParams">
+				</div>
+			</td>
+		</tr>
+		<tr>
+			<td id="navMenuContainer" class="dijitMenu" style="vertical-align:top; width:0;">
+				<h3 style="margin-bottom: 2em;">Navigation menu:</h3>
+				<div id="navMenu" aria-label="navigation"
+				 data-dojo-type="dijit/Menu"
+				 data-dojo-mixins="dojox/mvc/WidgetList"
+				 data-dojo-props="children: navMenuData, childType: getChildMenuType, childParams: getChildMenuParams">
+				</div>
+			</td>
+
+			<td style="padding: 1em" id="contentContainer">
+
+				<h1 class="testTitle">Dijit Menu System Test</h1>
+
+				<p>This page contains:</p>
+				<ul>
+					<li>"Navigation bar" Menu widget on left, a.k.a vertical MenuBar
+					<li>MenuBar on top
+					<li>page level context menu (right-click anywhere on page)
+					<li>form widget context menu (right-click on textbox widget)</li>
+					<li>left click context menu (left click on input on far right)
+					<li>Example of programatically created menu
+					<li>Note: while some accelerator (shortcut) keys are displayed in the context menu, they are not actually hooked up to the corresponding actions (if any), they need to be setup explicitly by the user
+				</ul>
+
+				<h3>Form</h3>
+
+				<form>
+					<p style="float:right; text-align: right;">
+						left click to open the menu for this input:<br/>
+						Note: because of the window contextMenu, make sure you get<br/>
+						the right menu by verifying the left<br/>
+						click one starts with "Left Click Menu"<br/>
+						at the very top.
+						<input aria-label="input2" id=input2 value="top-right"/>
+					</p>
+					<input aria-label="input1" id=input1 value="top-left"/>
+					<textarea aria-label="textara" id=textarea>hello there!</textarea><br>
+					<select aria-label="select">
+						<option>check if i</option>
+						<option>bleed through</option>
+						<option>on IE6</option>
+					</select>
+					<button id=button>push me</button><br>
+					<input data-dojo-type="dijit/form/TextBox" aria-label="focus test" id="formwidget" data-dojo-props='style:"width:25em;", value:"dijit.form._FormWidget focus test"'/>
+				</form>
+
+				<div id="prog_menu" style="clear: both; border:1px solid blue; padding:10px; margin:20px 0;">
+					Click button below to create special menu on this div.
+				</div>
+				<button id="createButton" onclick="createMenu();">create programmatic menu</button>
+				<button id="destroyButton" onclick="destroyMenu();" disabled>destroy programmatic menu</button>
+
+				<div style="height:500px"></div>
+				<p>(this space intentionally left blank to aid testing with controls
+				at the bottom of the browser window)</p>
+				<div style="height:500px"></div>
+				<input id=input3 aria-label="input3" value="bottom-left"/>
+				<p style="text-align:right"><input aria-label="input4" id=input4 value="bottom-right"/></p>
+
+				<p>See also: <a href="form/test_Button.html">form/test_Button</a>
+				(PopupMenu is used with DropDownButton and ComboButton)</p>
+
+				<h3>Mouse opening tests</h3>
+
+				<ul>
+					<li>Right click on the client area of the page (ctrl-click for Macintosh). Menu should open.</li>
+					<li>Right click on each of the form controls above. Menu should open.</li>
+					<li>Right click near the right hand window border. Menu should open to the left of the pointer.</li>
+					<li>Right click near the bottom window border. Menu should open above the pointer.</li>
+				</ul>
+
+
+				<h3>Mouse hover tests</h3>
+
+				<ul>
+					<li>Hover over the first item with the pointer. Item should highlight and get focus.</li>
+					<li>Hover over the second (disabled) item. Item should highlight and get focus.</li>
+					<li>Separator items should not highlight on hover - no items should highlight in this case.</li>
+				</ul>
+
+
+				<h3>Mouse click tests</h3>
+
+				<ul>
+					<li>Click on the first menu item. console.log should log the message "Hello world". The menu should dissapear.</li>
+					<li>Click on the second menu item (disabled). Should not do anything - focus should remain on the disabled item.</li>
+					<li>Click anywhere outside the menu. Menu should close. Focus will be set by the browser based on where the user clicks.</li>
+				</ul>
+
+
+				<h3>Mouse submenu tests</h3>
+
+				<ul>
+					<li>Hover over the "Enabled Submenu" item. Item should highlight and then pop open a submenu after a short (500ms) delay.</li>
+					<li>Hover over any of the other menu items. Submenu should close immediately and deselect the submenu parent item. The newly hovered item should become selected.</li>
+					<li>Hover over the "Disabled Submenu" item. Item should highlight, but no submenu should appear.</li>
+					<li>Clicking on the "Enabled Submenu" item before the submenu has opened (you'll have to be quick!) should immediatley open the submenu.</li>
+					<li>Clicking on the "Enabled Submenu" item <i>after</i> the submenu has opened should have no effect - the item is still selected and the submenu still open.</li>
+					<li>Hover over submenu item 1. Should select it - the parent menu item should stay selected also.</li>
+					<li>Hover over submenu item 2. Should select it - the parent menu item should stay selected also.</li>
+				</ul>
+
+
+				<h3>Keyboard opening tests</h3>
+
+				<ul>
+					<li>On Windows: press shift-f10 with focus on any of the form controls. Should open the menu.</li>
+					<li>On Windows: press the context menu key (located on the right of the space bar on North American keyboards) with focus on any of the form controls. Should open the menu.</li>
+					<li>On Firefox on the Mac: press ctrl-space with focus on any of the form controls. Should open the menu.</li>
+				</ul>
+
+
+				<h3>Keyboard closing tests</h3>
+
+				<ul>
+					<li>Open the menu.</li>
+					<li>Press tab. Should close the menu and return focus to where it was before the menu was opened.</li>
+					<li>Open the menu.</li>
+					<li>Press escape. Should close the menu and return focus to where it was before the menu was opened.</li>
+				</ul>
+
+
+				<h3>Keyboard navigation tests</h3>
+
+				<ul>
+					<li>Open the menu.</li>
+					<li>Pressing up or down arrow should cycle focus through the items in that menu.</li>
+					<li>Pressing enter or space should invoke the menu item.</li>
+					<li>Disabled items receive focus but no action is taken upon pressing enter or space.</li>
+				</ul>
+
+
+				<h3>Keyboard submenu tests</h3>
+
+				<ul>
+					<li>Open the menu.</li>
+					<li>The first item should become selected.</li>
+					<li>Press the right arrow key. Nothing should happen.</li>
+					<li>Press the left arrow key. Nothing should happen.</li>
+					<li>Press the down arrow until "Enabled Submenu" is selected. The submenu should not appear.</li>
+					<li>Press enter. The submenu should appear with the first item selected.</li>
+					<li>Press escape. The submenu should vanish - "Enabled Submenu" should remain selected.</li>
+					<li>Press the right arrow key. The submenu should appear with the first item selected.</li>
+					<li>Press the right arrow key. Nothing should happen.</li>
+					<li>Press the left arrow key. The submenu should close - "Enabled Submenu" should remain selected.</li>
+					<li>Press the left arrow key. The menu should <i>not</i> close and "Enabled Submenu" should remain selected.</li>
+					<li>Press escape. The menu should close and focus should be returned to where it was before the menu was opened.</li>
+				</ul>
+			</td>
+		</tr>
+	</table>
+</body>
+</html>
diff --git a/dojox/mvc/tests/WidgetList_tests/test_mvc_observable-search-results-ins-del.html b/dojox/mvc/tests/WidgetList_tests/test_mvc_observable-search-results-ins-del.html
new file mode 100644
index 0000000..371d65a
--- /dev/null
+++ b/dojox/mvc/tests/WidgetList_tests/test_mvc_observable-search-results-ins-del.html
@@ -0,0 +1,370 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Search Results example</title>
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: true, mvc: {debugBindings: true}">
+		</script>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript">
+			var data = [
+				{
+					id: "1",
+					Group: "Engineer",
+					First: "Anne",
+					Last: "Ackerman",
+					Location: "NY",
+					Office: "1S76",
+					Email: "a.a at test.com",
+					Tel: "123-764-8237",
+					Fax: "123-764-8228"
+				},
+				{
+					id: "2",
+					Group: "Engineer",
+					First: "Ben",
+					Last : "Beckham",
+					Location: "NY",
+					Office: "5N47",
+					Email: "b.b at test.com",
+					Tel: "123-764-8599",
+					Fax: "123-764-8600"
+				},
+				{
+					id: "3",
+					Group: "Engineer",
+					First: "Chad",
+					Last: "Chapman",
+					Location: "CA",
+					Office: "1278",
+					Email: "c.c at test.com",
+					Tel: "408-764-8237",
+					Fax: "408-764-8228"
+				},
+				{
+					id: "4",
+					Group: "Engineer",
+					First: "David",
+					Last: "Durham",
+					Location: "NJ",
+					Office: "C12",
+					Email: "d.d at test.com",
+					Tel: "514-764-8237",
+					Fax: "514-764-8228"
+				},
+				{
+					id: "5",
+					Group: "Engineer",
+					First: "Emma",
+					Last: "Eklof",
+					Location: "NY",
+					Office: "4N76",
+					Email: "e.e at test.com",
+					Tel: "123-764-1234",
+					Fax: "123-764-4321"
+				},
+				{
+					id: "6",
+					Group: "Manager",
+					First: "Fred",
+					Last: "Fisher",
+					Location: "NJ",
+					Office: "V89",
+					Email: "f.f at test.com",
+					Tel: "514-764-8567",
+					Fax: "514-764-8000"
+				},
+				{
+					id: "7",
+					Group: "Manager",
+					First: "George",
+					Last: "Garnett",
+					Location: "NY",
+					Office: "7S11",
+					Email: "gig at test.com",
+					Tel: "123-999-8599",
+					Fax: "123-999-8600"
+				},
+				{
+					id: "8",
+					Group: "Accountant",
+					First: "Hunter",
+					Last: "Huffman",
+					Location: "CA",
+					Office: "6532",
+					Email: "h.h at test.com",
+					Tel: "408-874-8237",
+					Fax: "408-874-8228"
+				},
+				{
+					id: "9",
+					Group: "Accountant",
+					First: "Irene",
+					Last: "Ira",
+					Location: "NJ",
+					Office: "F09",
+					Email: "i.i at test.com",
+					Tel: "514-764-6532",
+					Fax: "514-764-7300"
+				},
+				{
+					id: "10",
+					Group: "Accountant",
+					First: "John",
+					Last: "Jacklin",
+					Location: "CA",
+					Office: "6701",
+					Email: "j.j at test.com",
+					Tel: "408-764-1234",
+					Fax: "408-764-4321"
+				}
+			], ctrl;
+
+			require([
+				"dojo/_base/declare",
+				"dojo/when",
+				"dojo/parser",
+				"dijit/registry",
+				"dojo/Stateful",
+				"dojo/store/Memory",
+				"dojo/store/Observable",
+				"dojox/mvc/EditStoreRefListController",
+				"dojox/mvc/equals",
+				"dijit/form/Button",
+				"dijit/form/RadioButton",
+				"dijit/form/TextBox",
+				"dijit/form/ComboBox",
+				"dijit/Dialog",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Templated",
+				"dojox/mvc/WidgetList",
+				"dojo/domReady!"
+			], function(declare, when, parser, registry, Stateful, Memory, Observable, 
+						EditStoreRefListController, equals){
+
+				var inited,
+				 ctrlClass = declare([EditStoreRefListController], {
+					cursorIndex: 0,
+					idProperty: "id",
+					group: "",
+					groupTyped: "",
+					_refModelProp: "model",
+
+					addEmpty: function(idx){
+						//this.model.push(new Stateful({id:Math.random(), Group: this.groupTyped, First: "", Last: "", Location: "", Office: "", Email: "", Tel: "", Fax: ""}));
+						this.model.splice(idx+1, 0, new Stateful({id:Math.random(), Group: this.groupTyped, First: "", Last: "", Location: "", Office: "", Email: "", Tel: "", Fax: ""}));
+						this.set("cursorIndex", idx+1);
+						//this.set("cursorIndex", this.get("length") - 1);
+					},
+
+					remove: function(idx){
+						this.model.splice(idx, 1);
+						if(this.get("cursorIndex") < 0){
+							this.set("cursorIndex", this.get("length") - 1);
+						}
+					},
+
+					// called when set("group",..) is called, this will query the store
+					_setGroupAttr: function(value){
+						this.set("groupTyped", value);
+						var old = this.group;
+						if(old === value){ return; }
+						when(this.queryStore({Group: value}), function(){
+							if(!inited){
+								parser.parse();
+								inited = true;
+							}
+						});
+						this._set("group", value);
+
+						this.sourceModel.observe(function(object, removedFrom, insertedInto){
+							console.log("observeHandle hit");
+							// need to check to see if the model has been updated, use mvc.equals.
+							var clean = equals(ctrl.originalModel, ctrl.model);
+							console.log("store updated, model is clean?  "+clean);
+							if(!clean){
+								//  use a simple confirm dialog for this one
+								if(confirm("The store has been updated, do you want to save your changes? Select 'OK' to save your changes, select 'Cancel' to discard your changes")){
+									ctrl.commit(); 
+								}
+							}
+							var grp = ctrl.get("group");
+							ctrl.queryStore({Group: grp});			
+						});				
+						
+					}
+				});
+
+				// called to show items for a different group
+				search = function() { 					
+					// need to check to see if the model has been updated, use mvc.equals.
+					var clean = equals(ctrl.originalModel, ctrl.model);
+					console.log("the seach is changing, model is clean?  "+clean);
+					if(!clean && (ctrl.get('groupTyped') !== ctrl.get('group'))){
+						//  use a dijit.dialog for this one
+						registry.byId("myFormDialog").show();
+					}else{
+						ctrl.set('group', ctrl.get('groupTyped'));
+					}
+				};
+
+				commitAndUpdate = function(){
+			        registry.byId("myFormDialog").hide();
+					ctrl.commit(); 
+					ctrl.set('group', ctrl.get('groupTyped'));
+			   };
+
+			    justUpdate = function(){
+			        registry.byId("myFormDialog").hide();
+					ctrl.set('group', ctrl.get('groupTyped'));			        
+			    };
+			    
+				storeAddIndex = 0;
+				// Add an item to the store, to see the Observable fire
+				testStoreAdd = function(){
+					storeAddIndex++;				
+					var store = ctrl.store;
+					var grp = ctrl.get("group");
+					var newdata = {Group: grp, First: "NEWfirst"+storeAddIndex, 
+												Last: "NEWlast"+storeAddIndex, Location: "NEWlocation"+storeAddIndex, 
+												Office: "NEWoffice"+storeAddIndex, Email: "NEWEmail"+storeAddIndex, 
+												Tel: "NEWtel"+storeAddIndex, Fax: "NEWfax"+storeAddIndex};
+					
+					store.put(newdata);
+				};
+				
+				// using Observable allows us to listen for any changes to the store
+				ctrl = new ctrlClass({store: Observable(new dojo.store.Memory({data: data}))});
+				ctrl.set("group", "Engineer");
+			});
+		 </script>
+	</head>
+	<body class="claro" style="background-image: url(../images/master_detail.png)">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Employee Search</h1>
+					<h2>Master Detail Example - Observable Repeat with insert and delete.</h2>
+					<h4>Press the "Add New Item to Store" button to update the store with a new item, the Observable will fire and update the model if no updates are in progress.  If an uncommitted change has been made an alert will ask if you want to save your change.</h4>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+					<div id="mainContent">
+						<div class="row">
+						<div class="spacer"></div>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ testStoreAdd(); }">Add New Item to Store</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commit(); }">Commit All</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset to last saved</button>
+						</div>
+						<div class="spacer"></div>
+						<div>
+							Try "Engineer", "Manager", or "Accountant":
+						</div>
+						<div class="row">
+							<label class="cell" for="queryInput">Search for:</label>
+							<select id="setvaluetest" data-dojo-type="dijit.form.ComboBox" data-dojo-props="value: at(ctrl, 'groupTyped')">
+								<option value="Engineer">Engineer</option>
+								<option value="Manager">Manager</option>
+								<option value="Accountant">Accountant</option>
+							</select>							
+							<button type="button" data-dojo-type="dijit.form.Button"
+							 data-dojo-props="onClick: function(){ search(); }">Search</button>
+						</div>
+						<div class="spacer"></div>
+						<div id="searchBanner">
+							Search Results for group: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(ctrl, 'group')"></span>
+						</div>
+			<!--			
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at(ctrl, 'model')">
+							<div class="row" data-dojo-type="dijit._WidgetBase" data-dojo-props="target: at('rel:', ${this.index})">
+								<label class="cell" for="nameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}"
+								 data-dojo-props="value: at('rel:', 'First')">
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${this.index}); }">Details</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.addEmpty(${index}); }">+</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.remove(${index}); }">-</button>
+							</div>
+						</div>
+			-->
+
+				<div data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				 data-dojo-props="children: at(ctrl, 'model')">
+					<script type="dojox/mvc/InlineTemplate">
+						<div>
+								<label class="cell" for="nameInput${indexAtStartup}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${indexAtStartup}"
+								 data-dojo-props="value: at('rel:', 'First')">
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${indexAtStartup}); }">Details</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.addEmpty(${indexAtStartup}); }">+</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.remove(${indexAtStartup}); }">-</button>
+						</div>
+					</script>
+				</div>
+
+						
+						<div class="spacer"></div>
+						<div id="detailsBanner">
+							Details for result index:
+							<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(ctrl, 'cursorIndex')"></span>
+						</div>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commitCurrent(); }">Save Item</button>
+						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'cursor')">
+							<div class="row">
+								<label class="cell" for="firstInput">First Name:</label>
+								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')">
+							</div>
+							<div class="row">
+								<label class="cell" for="lastInput">Last Name:</label>
+								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')">
+							</div>
+							<div class="row">
+								<label class="cell" for="locationInput">Location:</label>
+								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Location')">
+							</div>
+							<div class="row">
+								<label class="cell" for="officeInput">Office:</label>
+								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Office')">
+							</div>
+							<div class="row">
+								<label class="cell" for="emailInput">Email:</label>
+								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')">
+							</div>
+							<div class="row">
+								<label class="cell" for="telInput">Telephone:</label>
+								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Tel')">
+							</div>
+							<div class="row">
+								<label class="cell" for="faxInput">Fax:</label>
+								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Fax')">
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		<div data-dojo-type="dijit/Dialog" id="myFormDialog" title="Changing the search will cause you to lose your updates, do you want to save your changes?">
+    		<h3>Save Updates?</h3>
+    		<h5>
+        		"Changing the search will cause you to lose your updates, do you want to save your changes? 
+				<br />
+        		Select 'Yes' to save your changes, select 'No' to discard your changes"
+    		</h5>
+    		<br />
+			<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick:commitAndUpdate">Yes</button>
+			<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick:justUpdate">No</button>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/WidgetList_tests/test_mvc_search-results-ins-del.html b/dojox/mvc/tests/WidgetList_tests/test_mvc_search-results-ins-del.html
new file mode 100644
index 0000000..fc875a9
--- /dev/null
+++ b/dojox/mvc/tests/WidgetList_tests/test_mvc_search-results-ins-del.html
@@ -0,0 +1,299 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Search Results example</title>
+		<script src="../../../../dojo/dojo.js" type="text/javascript" 
+				data-dojo-config="parseOnLoad: 0, isDebug: true, mvc: {debugBindings: true}">
+		</script>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript">
+			var data = [
+				{
+					id: "1",
+					Group: "Engineer",
+					First: "Anne",
+					Last: "Ackerman",
+					Location: "NY",
+					Office: "1S76",
+					Email: "a.a at test.com",
+					Tel: "123-764-8237",
+					Fax: "123-764-8228"
+				},
+				{
+					id: "2",
+					Group: "Engineer",
+					First: "Ben",
+					Last : "Beckham",
+					Location: "NY",
+					Office: "5N47",
+					Email: "b.b at test.com",
+					Tel: "123-764-8599",
+					Fax: "123-764-8600"
+				},
+				{
+					id: "3",
+					Group: "Engineer",
+					First: "Chad",
+					Last: "Chapman",
+					Location: "CA",
+					Office: "1278",
+					Email: "c.c at test.com",
+					Tel: "408-764-8237",
+					Fax: "408-764-8228"
+				},
+				{
+					id: "4",
+					Group: "Engineer",
+					First: "David",
+					Last: "Durham",
+					Location: "NJ",
+					Office: "C12",
+					Email: "d.d at test.com",
+					Tel: "514-764-8237",
+					Fax: "514-764-8228"
+				},
+				{
+					id: "5",
+					Group: "Engineer",
+					First: "Emma",
+					Last: "Eklof",
+					Location: "NY",
+					Office: "4N76",
+					Email: "e.e at test.com",
+					Tel: "123-764-1234",
+					Fax: "123-764-4321"
+				},
+				{
+					id: "6",
+					Group: "Manager",
+					First: "Fred",
+					Last: "Fisher",
+					Location: "NJ",
+					Office: "V89",
+					Email: "f.f at test.com",
+					Tel: "514-764-8567",
+					Fax: "514-764-8000"
+				},
+				{
+					id: "7",
+					Group: "Manager",
+					First: "George",
+					Last: "Garnett",
+					Location: "NY",
+					Office: "7S11",
+					Email: "gig at test.com",
+					Tel: "123-999-8599",
+					Fax: "123-999-8600"
+				},
+				{
+					id: "8",
+					Group: "Accountant",
+					First: "Hunter",
+					Last: "Huffman",
+					Location: "CA",
+					Office: "6532",
+					Email: "h.h at test.com",
+					Tel: "408-874-8237",
+					Fax: "408-874-8228"
+				},
+				{
+					id: "9",
+					Group: "Accountant",
+					First: "Irene",
+					Last: "Ira",
+					Location: "NJ",
+					Office: "F09",
+					Email: "i.i at test.com",
+					Tel: "514-764-6532",
+					Fax: "514-764-7300"
+				},
+				{
+					id: "10",
+					Group: "Accountant",
+					First: "John",
+					Last: "Jacklin",
+					Location: "CA",
+					Office: "6701",
+					Email: "j.j at test.com",
+					Tel: "408-764-1234",
+					Fax: "408-764-4321"
+				}
+			], ctrl;
+
+			require([
+				"dojo/_base/declare",
+				"dojo/when",
+				"dojo/parser",
+				"dojo/Stateful",
+				"dojo/store/Memory",
+				"dojox/mvc/EditStoreRefListController",
+				"dijit/form/Button",
+				"dijit/form/TextBox",
+				"dijit/form/ComboBox",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Templated",
+				"dojox/mvc/WidgetList",
+				"dojo/domReady!"
+			], function(declare, when, parser, Stateful, Memory, EditStoreRefListController){
+
+				var inited,
+				 ctrlClass = declare([EditStoreRefListController], {
+					cursorIndex: 0,
+					group: "",
+					groupTyped: "",
+					_refModelProp: "model",
+
+					addEmpty: function(){
+						this.model.push(new Stateful({id:Math.random(), Group: this.groupTyped, First: "", Last: "", Location: "", Office: "", Email: "", Tel: "", Fax: ""}));
+						this.set("cursorIndex", this.get("length") - 1);
+					},
+
+					remove: function(idx){
+						this.model.splice(idx, 1);
+						if(this.get("cursorIndex") < 0){
+							this.set("cursorIndex", this.get("length") - 1);
+						}
+					},
+
+					_setGroupAttr: function(value){
+						this.set("groupTyped", value);
+						var old = this.group;
+						if(old === value){ return; }
+						when(this.queryStore({Group: value}), function(){
+							if(!inited){
+								parser.parse();
+								inited = true;
+							}
+						});
+						this._set("group", value);
+					}
+				});
+
+				ctrl = new ctrlClass({store: new Memory({data: data})});
+				ctrl.set("group", "Engineer");
+			});
+		 </script>
+	</head>
+	<body class="claro" style="background-image: url(../images/master_detail.png)">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Employee Search</h1>
+					<h2>Master Detail Example - Repeat with insert and delete.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+					<div id="mainContent">
+						<div class="row">
+						<div class="spacer"></div>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commit(); }">Commit All</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset to last saved</button>
+						</div>
+						<div class="spacer"></div>
+						<div>
+							Try "Engineer", "Manager", or "Accountant":
+						</div>
+						<div class="row">
+							<label class="cell" for="queryInput">Search for:</label>
+				<!--		<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at(ctrl, 'groupTyped')"> -->
+							<select id="setvaluetest" data-dojo-type="dijit.form.ComboBox" data-dojo-props="value: at(ctrl, 'groupTyped')">
+								<option value="Engineer">Engineer</option>
+								<option value="Manager">Manager</option>
+								<option value="Accountant">Accountant</option>
+							</select>							
+							<button type="button" data-dojo-type="dijit.form.Button"
+							 data-dojo-props="onClick: function(){ ctrl.set('group', ctrl.get('groupTyped')); }">Search</button>
+						</div>
+						<div class="spacer"></div>
+						<div id="searchBanner">
+							Search Results for group: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(ctrl, 'group')"></span>
+						</div>
+			<!--			
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at(ctrl, 'model')">
+							<div class="row" data-dojo-type="dijit._WidgetBase" data-dojo-props="target: at('rel:', ${this.index})">
+								<label class="cell" for="nameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}"
+								 data-dojo-props="value: at('rel:', 'First')">
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${this.index}); }">Details</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.addEmpty(); }">+</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.remove(${index}); }">-</button>
+							</div>
+						</div>
+
+
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.addEmpty(); }">+</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.remove(${index}); }">-</button>
+
+			-->			
+
+				<div data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				 data-dojo-props="children: at(ctrl, 'model')">
+					<script type="dojox/mvc/InlineTemplate">
+						<div>
+								<label class="cell" for="nameInput${indexAtStartup}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${indexAtStartup}"
+								 data-dojo-props="value: at('rel:', 'First')">
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${indexAtStartup}); }">Details</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.addEmpty(); }">+</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.remove(${indexAtStartup}); }">-</button>
+						</div>
+					</script>
+				</div>
+
+						<div class="spacer"></div>
+						<div id="detailsBanner">
+							Details for result index:
+							<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(ctrl, 'cursorIndex')"></span>
+						</div>
+						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'cursor')">
+							<div class="row">
+								<label class="cell" for="firstInput">First Name:</label>
+								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')">
+							</div>
+							<div class="row">
+								<label class="cell" for="lastInput">Last Name:</label>
+								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')">
+							</div>
+							<div class="row">
+								<label class="cell" for="locationInput">Location:</label>
+								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Location')">
+							</div>
+							<div class="row">
+								<label class="cell" for="officeInput">Office:</label>
+								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Office')">
+							</div>
+							<div class="row">
+								<label class="cell" for="emailInput">Email:</label>
+								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')">
+							</div>
+							<div class="row">
+								<label class="cell" for="telInput">Telephone:</label>
+								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Tel')">
+							</div>
+							<div class="row">
+								<label class="cell" for="faxInput">Fax:</label>
+								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Fax')">
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/WidgetList_tests/test_mvc_search-results-repeat.html b/dojox/mvc/tests/WidgetList_tests/test_mvc_search-results-repeat.html
new file mode 100644
index 0000000..f5155df
--- /dev/null
+++ b/dojox/mvc/tests/WidgetList_tests/test_mvc_search-results-repeat.html
@@ -0,0 +1,270 @@
+<!DOCTYPE html>
+<html style="width: 100%; height: 100%;">
+<head>
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+<title>Dojo Repeat Selection Test</title>
+
+<style type="text/css">
+ at import "../../../../dijit/themes/dijit.css";
+ at import "../../../../dijit/themes/claro/document.css";
+ at import "../../../../dijit/tests/css/dijitTests.css";
+ at import "../css/app-format.css";
+</style>
+
+<!-- required: a default dijit theme: -->
+<link id="themeStyles" rel="stylesheet"
+	href="../../../../dijit/themes/claro/claro.css" />
+
+
+<!-- required: dojo.js -->
+<script type="text/javascript" src="../../../../dojo/dojo.js"
+	data-dojo-config="isDebug: true, async: true, mvc: {debugBindings: true}"></script>
+
+<script type="text/javascript">
+	require([
+			"dojo/parser", 
+			"dijit/registry", 
+			"dojox/mvc/getStateful", 
+			"dojox/mvc/_atBindingExtension", 
+			"dojox/mvc/ListController", 
+			"dojox/mvc/StatefulArray",
+			"dojox/mvc/Group", 
+			"dojox/mvc/Output", 
+			"dojox/mvc/Templated",
+			"dojox/mvc/WidgetList",
+			"dojox/mvc/Repeat",
+			"dijit/form/Button", 
+			"dijit/form/TextBox"
+			],
+			function(parser, registry, getStateful){
+
+				setDetailsContext=function(index){
+					var ctl=registry.byId("listCtl");
+					ctl.set("cursorIndex", index);
+				};
+
+				searchRecords=getStateful({
+					"Query" : "Engineers",
+					"Results" : [{
+						"First" : "Anne",
+						"Last" : "Ackerman",
+						"Location" : "NY",
+						"Office" : "1S76",
+						"Email" : "a.a at test.com",
+						"Tel" : "123-764-8237",
+						"Fax" : "123-764-8228"
+					}, {
+						"First" : "Ben",
+						"Last" : "Beckham",
+						"Location" : "NY",
+						"Office" : "5N47",
+						"Email" : "b.b at test.com",
+						"Tel" : "123-764-8599",
+						"Fax" : "123-764-8600"
+					}, {
+						"First" : "Chad",
+						"Last" : "Chapman",
+						"Location" : "CA",
+						"Office" : "1278",
+						"Email" : "c.c at test.com",
+						"Tel" : "408-764-8237",
+						"Fax" : "408-764-8228"
+					}, {
+						"First" : "David",
+						"Last" : "Durham",
+						"Location" : "NJ",
+						"Office" : "C12",
+						"Email" : "d.d at test.com",
+						"Tel" : "514-764-8237",
+						"Fax" : "514-764-8228"
+					}, {
+						"First" : "Emma",
+						"Last" : "Eklof",
+						"Location" : "NY",
+						"Office" : "4N76",
+						"Email" : "e.e at test.com",
+						"Tel" : "123-764-1234",
+						"Fax" : "123-764-4321"
+					}, {
+						"First" : "Fred",
+						"Last" : "Fisher",
+						"Location" : "NJ",
+						"Office" : "V89",
+						"Email" : "f.f at test.com",
+						"Tel" : "514-764-8567",
+						"Fax" : "514-764-8000"
+					}, {
+						"First" : "George",
+						"Last" : "Garnett",
+						"Location" : "NY",
+						"Office" : "7S11",
+						"Email" : "gig at test.com",
+						"Tel" : "123-999-8599",
+						"Fax" : "123-999-8600"
+					}, {
+						"First" : "Hunter",
+						"Last" : "Huffman",
+						"Location" : "CA",
+						"Office" : "6532",
+						"Email" : "h.h at test.com",
+						"Tel" : "408-874-8237",
+						"Fax" : "408-874-8228"
+					}, {
+						"First" : "Irene",
+						"Last" : "Ira",
+						"Location" : "NJ",
+						"Office" : "F09",
+						"Email" : "i.i at test.com",
+						"Tel" : "514-764-6532",
+						"Fax" : "514-764-7300"
+					}, {
+						"First" : "John",
+						"Last" : "Jacklin",
+						"Location" : "CA",
+						"Office" : "6701",
+						"Email" : "j.j at test.com",
+						"Tel" : "408-764-1234",
+						"Fax" : "408-764-4321"
+					}]
+				});
+
+				parser.parse();
+			});
+</script>
+</head>
+<body class="claro"
+	style="width: 100%; height: 100%; margin: 0; padding: 0;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<span id="listCtl" data-dojo-type="dojox.mvc.ListController"
+		data-dojo-props="model: searchRecords.Results, cursorIndex: 0"></span>
+	<div id="header">
+		<div id="navigation"></div>
+		<div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - With repeat container.</h2>
+		</div>
+	</div>
+	<div id="main">
+		<div id="leftNav"></div>
+		<div id="mainContent">
+			<!--
+			 The group container denotes some logical grouping of widgets and also serves
+			 to establish a parent data binding context for its children.
+			 The target attribute for the outermost container obtains the binding from the
+			 "page scope" itself.
+				
+			<div>
+				<h1>Repeating simple text box and label</h2>
+				<div data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-props="children: searchRecords.Results"
+				 data-mvc-child-type="dijit/form/TextBox"
+				 data-mvc-child-props="value: at(this.target, 'First')"></div>
+				<span data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-props="children: searchRecords.Results"
+				 data-mvc-child-type="dijit/_WidgetBase"
+				 data-mvc-child-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at(this.target, 'First')"></span>
+			</div>
+		 	-->
+				
+			<div data-dojo-type="dojox.mvc.Group"
+				data-dojo-props="target: searchRecords">
+				<div class="row">
+					<label class="cell" for="queryInput">Search for:</label> 
+					<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox"
+						data-dojo-props="value: at('rel:', 'Query')" />
+					<button type="button" data-dojo-type="dijit.form.Button"
+						data-dojo-props="onClick: function(){setSearchBanner();}">Search</button>
+				</div>
+				<div class="spacer"></div>
+
+				<div id="searchBanner">Search Results for term: Engineers</div>
+
+				<div data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				 data-dojo-props="children: at('rel:', 'Results')">
+					<script type="dojox/mvc/InlineTemplate">
+						<div>
+							<label class="cell">Name:</label>
+							<span data-dojo-type="dijit/_WidgetBase"
+							 data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: ${indexAtStartup}"></span>: 
+							<span data-dojo-type="dijit/form/TextBox"
+							 data-dojo-props="value: at('rel:', 'First')"></span>
+							<button type="button" data-dojo-type="dijit/form/Button"
+								data-dojo-props="onClick: function(){setDetailsContext('${indexAtStartup}');}">Details</button>
+						</div>
+					</script>
+				</div>
+
+
+				<!--
+				The repeat container denotes a templated UI that operates over a collection
+				of data records.
+				The UI can be customized for each iteration using properties such as
+				listCtl cursor or cursorIndex for the iteration.
+
+				<div data-dojo-type="dojox.mvc.Repeat"
+					data-dojo-props="children: at('rel:', 'Results')">
+					<div class="row" data-dojo-type="dojox.mvc.Group"
+						data-dojo-props="target: at('rel:${this.index}')">
+						<label class="cell" for="nameInput${this.index}">Name:</label> 
+						<input class="cell" data-dojo-type="dijit.form.TextBox"
+							id="nameInput${this.index}"
+							data-dojo-props="value: at('rel:', 'First')">
+						<button type="button" data-dojo-type="dijit.form.Button"
+							data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+					</div>
+				</div>
+				-->
+				
+				<div class="spacer"></div>
+
+				<div data-dojo-type="dojox.mvc.Group"
+					data-dojo-props="target: at('widget:listCtl', 'cursor')">
+					<div class="row">
+						<div style="display: inline-block;" id="detailsBanner">Details for result index:</div>
+						<span class="cell" id="indexOutput"
+							data-dojo-type="dojox.mvc.Output"
+							data-dojo-props="value: at('widget:listCtl', 'cursorIndex')"></span>
+					</div>
+					<div class="row">
+						<label class="cell" for="firstInput">First Name:</label> 
+							<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'First')">
+					</div>
+					<div class="row">
+						<label class="cell" for="lastInput">Last Name:</label> 
+						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Last')">
+					</div>
+					<div class="row">
+						<label class="cell" for="locationInput">Location:</label> 
+						<input class="cell" id="locationInput"
+							data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Location')">
+					</div>
+					<div class="row">
+						<label class="cell" for="officeInput">Office:</label> 
+						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Office')">
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label> 
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Email')">
+					</div>
+					<div class="row">
+						<label class="cell" for="telInput">Telephone:</label> 
+						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Tel')">
+					</div>
+					<div class="row">
+						<label class="cell" for="faxInput">Fax:</label> 
+						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Fax')">
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/WidgetList_tests/test_nested_widgetLists-jsonRest-ins-del.html b/dojox/mvc/tests/WidgetList_tests/test_nested_widgetLists-jsonRest-ins-del.html
new file mode 100644
index 0000000..7d6db83
--- /dev/null
+++ b/dojox/mvc/tests/WidgetList_tests/test_nested_widgetLists-jsonRest-ins-del.html
@@ -0,0 +1,213 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Nested WidgetList example</title>
+		<script src="../../../../dojo/dojo.js" type="text/javascript"
+		data-dojo-config="parseOnLoad: 0, isDebug: true, mvc: {debugBindings: true}"></script>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript">
+			var ctrl;
+
+			require(["dojo/_base/declare", "dojo/when", "dojo/parser", "dojo/Stateful", "dojo/store/JsonRest", "dojo/_base/kernel", 
+			"dijit/registry", "dojox/mvc/EditStoreRefListController", "dijit/form/Button", "dijit/form/TextBox", "dijit/form/ComboBox", 
+			"dojox/mvc/Group", "dojox/mvc/Output", "dojox/mvc/Templated", "dojox/mvc/WidgetList", "dojo/domReady!"], 
+			function(declare, when, parser, Stateful, JsonRest, kernel, registry, EditStoreRefListController) {
+
+				var inited, ctrlClass = declare([EditStoreRefListController], {
+					cursorIndex : 0,
+					group : "",
+					groupTyped : "",
+					_refModelProp : "model",
+
+					addEmpty : function() {
+						this.model.push(new Stateful({
+							id : Math.random(),
+							Group : this.groupTyped,
+							First : "",
+							Last : "",
+							Location : "",
+							Office : "",
+							Email : "",
+							Tel : [{
+								"name" : "Home",
+								"number" : ""
+							}]
+						}));
+						this.set("cursorIndex", this.get("length") - 1);
+					},
+
+					remove : function(idx) {
+						this.model.splice(idx, 1);
+						if (this.get("cursorIndex") < 0) {
+							this.set("cursorIndex", this.get("length") - 1);
+						}
+					},
+
+					phoneAddEmpty : function() {
+						this.cursor.Tel.push(new Stateful({
+							"name" : "Home",
+							"number" : ""
+						}));
+						// this is needed for when a new person is added, those phones would not be added correctly without this
+						registry.byId("telRepeat").set("children", at('rel:', 'Tel'));
+						registry.byId("emailInput").focus();
+						// this is done to force it to scroll to the bottom so you can see that it was added.
+					},
+
+					phoneRemove : function(idx) {
+						this.cursor.Tel.splice(idx, 1);
+						registry.byId("telRepeat").set("children", at('rel:', 'Tel'));
+					},
+
+					_setGroupAttr : function(value) {
+						this.set("groupTyped", value);
+						var old = this.group;
+						if (old === value) {
+							return;
+						}
+						when(this.queryStore({
+							Group : value
+						}), function() {
+							if (!inited) {
+								parser.parse();
+								inited = true;
+							}
+						});
+						this._set("group", value);
+					}
+				});
+
+				ctrl = new ctrlClass({
+					store : new JsonRest({
+						target : kernel.moduleUrl("dojox.mvc.tests._data", "jsonRestRepeatData.json")
+					})
+				});
+				ctrl.set("group", "Engineer");
+			});
+		</script>
+	</head>
+	<body class="claro" style="background-image: url(../images/master_detail.png)">
+		<script type="dojo/require">
+			at: "dojox/mvc/at"
+		</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Nested WidgetLists</h1>
+					<h2>Nested WidgetLists one for the people and one for their phones, select person and use Details to add or remove a phone.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="fullrow">
+						<div class="spacer"></div>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commit(); }">
+							Commit All
+						</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">
+							Reset to last saved
+						</button>
+					</div>
+					<div class="spacer"></div>
+					<div id="searchBanner">
+						People with multiple phone numbers:
+					</div>
+
+					<div data-dojo-type="dojox/mvc/WidgetList"
+					data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: at(ctrl, 'model')">
+						<script type="dojox/mvc/InlineTemplate">
+							<div>
+							<label class="fixedcell" for="nameInput${indexAtStartup}">Name:</label>
+							<input class="fixedcell" data-dojo-type="dijit.form.TextBox" id="nameInput${indexAtStartup}"
+							data-dojo-props="value: at('rel:', 'First')">
+							<button type="button" data-dojo-type="dijit.form.Button"
+							data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${indexAtStartup}); }">Details</button>
+							<button type="button" data-dojo-type="dijit.form.Button"
+							data-dojo-props="onClick: function(){ ctrl.addEmpty(); }">+</button>
+							<button type="button" data-dojo-type="dijit.form.Button"
+							data-dojo-props="onClick: function(){ ctrl.remove(${indexAtStartup}); }">-</button>
+
+							<!-- try to add nested widgetList here -->
+							<div data-dojo-type="dojox/mvc/WidgetList"
+							data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+							data-dojo-props="children: at('rel:', 'Tel')">
+							<script type="dojox/mvc/InlineTemplate">
+							<div>
+							<div class="fullrow">
+							<div class="fixedcell"></div>
+							<label class="fixedcell" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:', 'name')"></label>
+							<input class="fixedcell" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'number')">
+							</div>
+						</script>
+					</div>
+
+				</div>
+				</script>
+
+				<div class="spacer"></div>
+				<div class="fullrow">
+					<div id="detailsBanner" class="fullrow">
+						<div class="fixedcell"></div>
+						<div class="fixedcell">
+							Details for result index:
+						</div>
+						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(ctrl, 'cursorIndex')"></span>
+					</div>
+				</div>
+				<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'cursor')">
+					<div class="fullrow">
+						<label class="fixedcell" for="firstInput">First Name:</label>
+						<input class="fixedcell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')">
+					</div>
+					<div class="fullrow">
+						<label class="fixedcell" for="lastInput">Last Name:</label>
+						<input class="fixedcell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')">
+					</div>
+					<div class="fullrow">
+						<label class="fixedcell" for="locationInput">Location:</label>
+						<input class="fixedcell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Location')">
+					</div>
+					<div class="fullrow">
+						<label class="fixedcell" for="officeInput">Office:</label>
+						<input class="fixedcell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Office')">
+					</div>
+					<div class="fullrow">
+						<label class="fixedcell">Phones:</label>
+						<button type="button" data-dojo-type="dijit.form.Button"
+						data-dojo-props="onClick: function(){ ctrl.phoneAddEmpty(); }">
+							+
+						</button>
+					</div>
+					<div data-dojo-type="dojox/mvc/WidgetList" id="telRepeat"
+					data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: at('rel:', 'Tel')">
+						<script type="dojox/mvc/InlineTemplate">
+							<div>
+							<div class="fullrow">
+							<div class="fixedcell"></div>
+							<input class="fixedcell" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'name')">
+							<input class="fixedcell" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'number')">
+							<button type="button" data-dojo-type="dijit.form.Button"
+							data-dojo-props="onClick: function(){ ctrl.phoneRemove(${indexAtStartup}); }">-</button>
+							</div>
+							</div>
+						</script>
+					</div>
+					<div class="fullrow">
+						<label class="fixedcell" for="emailInput">Email:</label>
+						<input class="fixedcell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')">
+					</div>
+				</div>
+			</div>
+		</div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/_data/jsonRestRepeatData.json b/dojox/mvc/tests/_data/jsonRestRepeatData.json
new file mode 100644
index 0000000..7c71f3b
--- /dev/null
+++ b/dojox/mvc/tests/_data/jsonRestRepeatData.json
@@ -0,0 +1,29 @@
+[ 
+                    {
+                        "Serial"  : "A111",
+                        "First"   : "Anne",
+                        "Last"    : "Ackerman",
+                        "Location": "NY",
+                        "Office"  : "1S76",
+                        "Email"   : "a.a at test.com",
+                        "Tel"     : [{"name":"Home", "number" : "123-764-8227"}, {"name":"Fax", "number" : "123-764-8228"}]
+                    },
+                    {
+                        "Serial"  : "H111",
+                        "First"   : "Hunter",
+                        "Last"    : "Huffman",
+                        "Location": "CA",
+                        "Office"  : "6532",
+                        "Email"   : "h.h at test.com",
+                        "Tel"     : [{"name":"Home", "number" : "408-874-8228"}, {"name":"Fax", "number" : "408-874-8229"}]
+                    },
+                    {
+                        "Serial"  : "J111",
+                        "First"   : "John",
+                        "Last"    : "Jacklin",
+                        "Location": "CA",
+                        "Office"  : "6701",
+                        "Email"   : "j.j at test.com",
+                        "Tel"     : [{"name":"Home", "number" : "408-764-4321"}, {"name":"Fax", "number" : "408-764-4322"}]
+                    }
+]
diff --git a/dojox/mvc/tests/controllers/readme.txt b/dojox/mvc/tests/controllers/readme.txt
new file mode 100644
index 0000000..aa8256f
--- /dev/null
+++ b/dojox/mvc/tests/controllers/readme.txt
@@ -0,0 +1,113 @@
+This directory in dojox/mvc/tests/controllers is used to show the differences when using different types of MVC Controllers.
+
+step1_test_mvc.html 
+	Just uses getStateful(), it does not use a controller.
+	The getStateful call will take json data and make it Stateful.
+	In this example a transform (transformAddress2Class) is used to hide the row for AddressLine2 if it is blank.
+	'dojox/mvc/parserExtension' is required for this since the row being hidden is not a widget.
+	The class attribute is bound to AddressLine2 with a direction and a transform.
+
+
+step2_test_mvc.html 
+	Step 2 of tests for Controllers, uses a ModelRefController.
+	To move from getStateful to ModelRefController, the only change other than the call to require and call new ModelRefController, 
+	is to change the binding on the groups to use ctrl instead of model.
+	
+	This example also uses the transform (transformAddress2Class) to hide the row for AddressLine2 if it is blank.
+
+	The ModelRefController constructor sets model to the results of the getStateful call which will take json data and make it Stateful
+
+
+step3_test_mvc.html 
+	Step 3 of test for Controllers, uses an EditModelRefController with holdModelUntilCommit: true.
+	To move from ModelRefController to use EditModelRefController, need to require EditModelRefController. 
+	and on the new call use sourceModel instead of model.
+ 
+	EditModelRefController adds support for reset() and commit(), so buttons were added to show Reset and Save (commit).
+
+	With holdModelUntilCommit set to true, you will want to bind the output address for the group to 
+	"target: at(ctrl,'sourceModel')", if holdModelUntilCommit is false you can stay with model, sourceModel will also work.
+	You can change holdModelUntilCommit to false to see how that works, updates will be reflected into the Verify section 
+	immediately upon focus changes, and Reset will revert back to the last saved model.
+	The EditModelRefController constructor sets sourceModel to the results of the getStateful call which will take json data and create make it Stateful
+
+
+step4_test_mvc.html 
+	Step 4 of test for Controllers, uses a StoreRefController.
+	To move from ModelRefController to use StoreRefController, need to require StoreRefController, Memory (store), and when 
+	Also needed to change the data to be valid for a store query. 
+	Setup StoreRefController and use ctrl.queryStore() to setup the models.
+
+	Because of the queryStore call had to move the call to parser.parse inside the when to wait for it. 
+	The change in the data for queryStore required changes to the bindings, shad to add a group with target: at('rel:','0')
+	for the bindings of fields. 
+	
+	An exprchar:'%' was used for an mvc/Output just to show how it is used. 
+
+
+step5_test_mvc.html
+	Step 5 of test for Controllers, uses an EditStoreRefController with holdModelUntilCommit: true.
+	To move from an EditModelRefController to use an EditStoreRefController, need to require EditStoreRefController, 
+	Memory, and when.  Also needed to change the data to be valid for a store query. 
+
+	Because of the queryStore call had to move the call to parser.parse inside the when to wait for it. 
+	The change in the data for queryStore required changes to the bindings. had to add a group with target: at('rel:','0') 
+	for the bindings of fields.  
+
+	With holdModelUntilCommit set to true, you will want to bind the output address for the group to 
+	"target: at(ctrl,'sourceModel')", if holdModelUntilCommit is false you can stay with model, sourceModel will also work.
+	You can change holdModelUntilCommit to false to see how that works, updates will be reflected into the Verify section
+	immediately upon focus changes, and Reset will revert back to the last saved model.
+	The EditStoreRefController constructor sets store to the memory store and uses queryStore() to setup the models.
+
+
+step6_test_mvc.html
+	Step 6 of test for Controllers, uses a ListController.
+	To move from ModelRefController to also use ListController, 
+	Need to require declare, and ListController, I also needed WidgetList and _InlineTemplateMixin.  
+	mvc/parserExtension is still needed to bind to class with data-mvc-bindings for 'AddressLine2'  
+	Decided to setup a ctrlclz with ListController to have the functions as part of the controller. 
+	The data had to be changed to be array data. 
+	The html was updated to use a WidgetList to show a radio button group with the choices, and to use a 
+	"cursor" binding for the selected address.  
+	Added a transform (transformRadioChecked) to change the cursorIndex when a different AddressName radio button is 
+	selected.  Also added an addEmpty function to add a New Address to the list.
+
+
+step7_test_mvc.html
+	Step 7 of test for Controllers, uses an EditModelRefController and ListController.
+	To move from ModelRefController to also use EditModelRefController and a ListController, 
+	Need to require declare, and EditModelRefController, ListController, 
+	I also needed WidgetList and _InlineTemplateMixin.  
+
+	Needed to setup ctrlclz with EditModelRefController and ListController, and the data needs to be array data and the 
+	call to new ctrlclz uses sourceModel instead of model, and sets holdModelUntilCommit
+	The html was updated to use a WidgetList to show a radio button group with the choices, and to use a 
+	"cursor" binding for the selected address.  
+	Added a transform (transformRadioChecked) to change the cursorIndex when a different AddressName radio button is 
+	selected.  Also added an addEmpty function to add a New Address to the list.
+
+
+step8_test_mvc.html
+	Step 8 of test for Controllers, uses an EditStoreRefListController with holdModelUntilCommit: false
+	To move from ModelRefController with EditModelRefController and a ListController to a EditStoreRefListController
+	Need to require the EditStoreRefListController, when, and Memory 
+	I also needed to change the data to be valid for a store query.   
+	Needed to setup ctrlclz with EditStoreRefListController, and use when and ctrl.queryStore() to setup the models. 
+
+	This test uses holdModelUntilCommit: false on the WidgetList, so updates to the address will immediately show-up in 
+	the verify section and in the select an address section, but changes can be "Reset" back to their last saved state.
+
+
+step9_test_mvc.html
+	Step 9 of test for Controllers, uses an EditStoreRefListController with holdModelUntilCommit: true
+	To move from EditStoreRefListController with holdModelUntilCommit: false to use holdModelUntilCommit: true 
+	I had to add the require for dojox/mvc/at and ListController 
+
+	This test uses holdModelUntilCommit: true on the WidgetList, so updates to the address will not show-up in 
+	the "Verify" section and in the "Select an address" section until "Save" is pressed.
+	But using holdModelUntilCommit: true requires use of a second controller (ctrlSource) which is a ListController 
+	and is bound to the sourceModel and cursorIndex of the first controller (ctrl).
+
+	The "Verify" section and the "Select an address" section are bound to at(ctrlSource,'cursor') and at(ctrlSource, 'model') respectively.
+	To set the Radio buttons correctly, "Checked" has to be updated in ctrl.model inside the transformRadioChecked. 
diff --git a/dojox/mvc/tests/controllers/step1_test_mvc.html b/dojox/mvc/tests/controllers/step1_test_mvc.html
new file mode 100644
index 0000000..6b145c8
--- /dev/null
+++ b/dojox/mvc/tests/controllers/step1_test_mvc.html
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Step 1 of test for Controllers, use getStateful() only.</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var model;
+
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc/getStateful',
+			'dojox/mvc/parserExtension', // required for data-mvc-bindings to bind to non-widgets
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(parser, ready, getStateful){
+
+				// Initial data
+				var data = {
+					"id" : "360324",
+					"FullName" : "Mr. John Doe",
+					"Email" : "jdoe at example.com",
+					"AddressLine1" : "123 Valley Rd.",
+					"AddressLine2" : "",
+					"City" : "Cary",
+					"State" : "NC",
+					"Zip" : "27513"
+				};
+
+				transformAddress2Class = {
+						format: function(value){
+							if(value && value.trim().length > 0){ 
+								return "row" // if AddressLine2 is set return row for class
+							}
+							return "hiderow"; // if AddressLine2 is not set return hiderow for class
+						}
+
+				};
+
+				// The getStateful call will take json data and make it Stateful
+				//
+				// In this example a transform (transformAddress2Class) is used to hide the row for AddressLine2 if it is blank.
+				// 'dojox/mvc/parserExtension' is required for this since the row being hidden is not a widget.  
+				// The class attribute is bound to AddressLine2 with a direction and a transform.
+				//
+				model = getStateful(data);
+
+				parser.parse();
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="main">
+			<div>
+				<h2>Step 1 of test for Controllers, use getStateful() only.</h2>
+				<h2>Enter Shipping Address</h2>
+			</div>
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(model)">
+				<div class="fullrow">
+					<label class="cell" for="nameInput">Full Name:</label>
+					<input class="cell" id="nameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'FullName')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine1Input">Address Line1:</label>
+					<input class="cell" id="AddressLine1Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine1')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine2Input">Address Line2:</label>
+					<input class="cell" id="AddressLine2Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine2')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="cityInput">City:</label>
+					<input class="cell" id="cityInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'City')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="stateInput">State:</label>
+					<input class="cell" id="stateInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'State')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="zipInput">Zipcode:</label>
+					<input class="cell" id="zipInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'Zip')">
+				</div>
+			</div>
+			<br/>
+			<div>
+				<h2>Verify the shipping address</h2>
+			</div>
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(model)">
+				<div class="fullrow">
+					<div class="boldnamecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'FullName')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine1')"></div>
+				</div>
+				<div class="hiderow" data-mvc-bindings="class: at('rel:', 'AddressLine2').direction(at.from).transform(transformAddress2Class)">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine2')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'City')">${this.value},</div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'State')"></div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'Zip')"></div>
+				</div>
+			</div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/controllers/step2_test_mvc.html b/dojox/mvc/tests/controllers/step2_test_mvc.html
new file mode 100644
index 0000000..9276974
--- /dev/null
+++ b/dojox/mvc/tests/controllers/step2_test_mvc.html
@@ -0,0 +1,131 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Step 2 of tests for Controllers, uses a ModelRefController.</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var ctrl;
+
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc/getStateful',
+			'dojox/mvc/ModelRefController',
+			'dojox/mvc/parserExtension',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(parser, ready, getStateful, ModelRefController){
+
+				// Initial data
+				var data = {
+					"id" : "360324",
+					"FullName" : "Mr. John Doe",
+					"Email" : "jdoe at example.com",
+					"AddressLine1" : "123 Valley Rd.",
+					"AddressLine2" : "",
+					"City" : "Cary",
+					"State" : "NC",
+					"Zip" : "27513"
+				};
+
+				transformAddress2Class = {
+						format: function(value){
+							if(value && value.trim().length > 0){ 
+								return "row" // if AddressLine2 is set return row for class
+							}
+							return "hiderow"; // if AddressLine2 is not set return hiderow for class
+						}
+
+				};
+
+				// To move from getStateful to ModelRefController, the only change other than the call to require and call new ModelRefController, 
+				// is to change the binding on the groups to use ctrl instead of model.
+				//
+				// In this example a transform (transformAddress2Class) is used to hide the row for AddressLine2 if it is blank.
+				// 'dojox/mvc/parserExtension' is required for this since the row being hidden is not a widget.  
+				// The class attribute is bound to AddressLine2 with a direction and a transform.
+				//
+				// The ModelRefController constructor sets model to the results of the getStateful call which will take json data and make it Stateful
+				ctrl = new ModelRefController({model: getStateful(data)});
+
+				parser.parse();
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="main">
+			<div>
+				<h2>Step 2 of test for Controllers, uses a ModelRefController.</h2>
+				<h2>Enter Shipping Address</h2>
+			</div>
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'model')">
+				<div class="fullrow">
+					<label class="cell" for="nameInput">Full Name:</label>
+					<input class="cell" id="nameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'FullName')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine1Input">Address Line1:</label>
+					<input class="cell" id="AddressLine1Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine1')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine2Input">Address Line2:</label>
+					<input class="cell" id="AddressLine2Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine2')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="cityInput">City:</label>
+					<input class="cell" id="cityInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'City')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="stateInput">State:</label>
+					<input class="cell" id="stateInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'State')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="zipInput">Zipcode:</label>
+					<input class="cell" id="zipInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'Zip')">
+				</div>
+			</div>
+			<br/>
+			<div>
+				<h2>Verify the shipping address</h2>
+			</div>
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'model')">
+				<div class="fullrow">
+					<div class="boldnamecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'FullName')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine1')"></div>
+				</div>
+				<div class="hiderow" data-mvc-bindings="class: at('rel:', 'AddressLine2').direction(at.from).transform(transformAddress2Class)">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine2')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'City')">${this.value},</div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'State')"></div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'Zip')"></div>
+				</div>
+			</div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/controllers/step3_test_mvc.html b/dojox/mvc/tests/controllers/step3_test_mvc.html
new file mode 100644
index 0000000..a29c03c
--- /dev/null
+++ b/dojox/mvc/tests/controllers/step3_test_mvc.html
@@ -0,0 +1,142 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Step 3 of test for Controllers, uses an EditModelRefController.</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var ctrl;
+ 
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc/getStateful',
+			'dojox/mvc/EditModelRefController',
+			'dojox/mvc/parserExtension',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(parser, ready, getStateful, EditModelRefController){
+
+				// Initial data
+				var data = {
+					"id" : "360324",
+					"FullName" : "Mr. John Doe",
+					"Email" : "jdoe at example.com",
+					"AddressLine1" : "123 Valley Rd.",
+					"AddressLine2" : "",
+					"City" : "Cary",
+					"State" : "NC",
+					"Zip" : "27513"
+				};
+
+				// To move from ModelRefController to use EditModelRefController, need to require EditModelRefController. 
+				// and on the new call use sourceModel instead of model.
+				// 
+				// EditModelRefController adds support for reset() and commit(), so buttons were added to show Reset and Save (commit).
+				//
+				// With holdModelUntilCommit set to true, you will want to bind the output address for the group to 
+				// "target: at(ctrl,'sourceModel')", if holdModelUntilCommit is false you can stay with model, sourceModel will also work.
+				//
+				// You can change holdModelUntilCommit to false to see how that works, updates will be reflected into the Verify section
+				// immediately upon focus changes, and Reset will revert back to the last saved model.
+				// The EditModelRefController constructor sets sourceModel to the results of the getStateful call which will take json data and make it Stateful
+
+
+				transformAddress2Class = {
+						format: function(value){
+							if(value && value.trim().length > 0){ 
+								return "row" // if AddressLine2 is set return row for class
+							}
+							return "hiderow"; // if AddressLine2 is not set return hiderow for class
+						}
+
+				};
+
+				ctrl = new EditModelRefController({sourceModel: getStateful(data), holdModelUntilCommit: true});
+
+				parser.parse();
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="main">
+			<div>
+				<h2>Step 3 of test for Controllers, uses an EditModelRefController with holdModelUntilCommit: true.</h2>
+				<h2>Enter Shipping Address</h2>
+			</div>
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'model')">
+				<div class="fullrow">
+					<label class="cell" for="nameInput">Full Name:</label>
+					<input class="cell" id="nameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'FullName')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine1Input">Address Line1:</label>
+					<input class="cell" id="AddressLine1Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine1')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine2Input">Address Line2:</label>
+					<input class="cell" id="AddressLine2Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine2')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="cityInput">City:</label>
+					<input class="cell" id="cityInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'City')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="stateInput">State:</label>
+					<input class="cell" id="stateInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'State')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="zipInput">Zipcode:</label>
+					<input class="cell" id="zipInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'Zip')">
+				</div>
+			</div>
+			<br/>
+			<div class="row">
+				<button  class="buttoncell" id="reset" type="button" data-dojo-type="dijit/form/Button"  data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset</button>
+				<button  class="buttoncell" id="commit" type="button" data-dojo-type="dijit/form/Button"  data-dojo-props="onClick: function(){ ctrl.commit(); }">Save</button>
+			</div>
+
+			<br/>
+			<div>
+				<h2>Verify the shipping address, will not update until saved with holdModelUntilCommit true.</h2>
+			</div>
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'sourceModel')">
+				<div class="fullrow">
+					<div class="boldnamecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'FullName')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine1')"></div>
+				</div>
+				<div class="hiderow" data-mvc-bindings="class: at('rel:', 'AddressLine2').direction(at.from).transform(transformAddress2Class)">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine2')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'City')">${this.value},</div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'State')"></div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'Zip')"></div>
+				</div>
+			</div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/controllers/step4_test_mvc.html b/dojox/mvc/tests/controllers/step4_test_mvc.html
new file mode 100644
index 0000000..95bb948
--- /dev/null
+++ b/dojox/mvc/tests/controllers/step4_test_mvc.html
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Step 4 of test for Controllers, uses a StoreRefController.</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var ctrl;
+ 
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			'dojo/when',
+			'dojo/store/Memory',
+			'dojox/mvc/getStateful',
+			'dojox/mvc/StoreRefController',
+			'dojox/mvc/parserExtension',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(parser, ready, when, Memory, getStateful, StoreRefController){
+
+				// Initial data
+			var storeData = {
+				"identifier": "id",
+				"items": [
+					{
+						"id" : "360324",
+						"FullName" : "Mr. John Doe",
+						"Email" : "jdoe at example.com",
+						"AddressLine1" : "123 Valley Rd.",
+						"AddressLine2" : "",
+						"City" : "Cary",
+						"State" : "NC",
+						"Zip" : "27513"
+					}
+				]
+			};
+
+				// To move from ModelRefController to use StoreRefController, need to require StoreRefController, Memory, and when 
+				// also needed to change the data to be valid for a store query. 
+				// Setup StoreRefController and use ctrl.queryStore() to setup the models.
+				//
+				// Because of the queryStore call had to move the call to parser.parse inside the when to wait for it. 
+				// The change in the data for queryStore required changes to the bindings. had to add a group with target: at('rel:','0')
+				// for the bindings of fields.
+				//
+				// An exprchar:'%' was used for an mvc/Output just to show how it is used.  
+				//
+
+				transformAddress2Class = {
+						format: function(value){
+							if(value && value.trim().length > 0){ 
+								return "row" // if AddressLine2 is set return row for class
+							}
+							return "hiderow"; // if AddressLine2 is not set return hiderow for class
+						}
+
+				};
+
+				ctrl = new StoreRefController({store: new Memory({data:storeData})});
+				when(ctrl.queryStore(), function(){
+							parser.parse();
+				});
+
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="main">
+			<div>
+				<h2>Step 4 of test for Controllers, uses a StoreRefController.</h2>
+				<h2>Enter Shipping Address</h2>
+			</div>
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'model')">
+				<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:','0')">
+				<div class="fullrow">
+					<label class="cell" for="nameInput">Full Name:</label>
+						<input class="cell" id="nameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'FullName')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine1Input">Address Line1:</label>
+					<input class="cell" id="AddressLine1Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine1')">
+					</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine2Input">Address Line2:</label>
+					<input class="cell" id="AddressLine2Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine2')">
+					</div>
+				<div class="fullrow">
+						<label class="cell" for="cityInput">City:</label>
+						<input class="cell" id="cityInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'City')">
+					</div>
+				<div class="fullrow">
+						<label class="cell" for="stateInput">State:</label>
+						<input class="cell" id="stateInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'State')">
+					</div>
+				<div class="fullrow">
+						<label class="cell" for="zipInput">Zipcode:</label>
+						<input class="cell" id="zipInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'Zip')">
+					</div>
+				</div>
+			</div>
+
+			<br/>
+			<div>
+				<h2>Verify the shipping address</h2>
+			</div>
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'model')">
+				<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:','0')">
+					<div class="fullrow">
+						<div class="boldnamecell" id="nameOutput" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'FullName')"></div>
+					</div>
+					<div class="fullrow">
+						<div class="namecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'AddressLine1')"></div>
+					</div>
+					<div class="hiderow" data-mvc-bindings="class: at('rel:', 'AddressLine2').direction(at.from).transform(transformAddress2Class)">
+						<div class="namecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'AddressLine2')"></div>
+					</div>
+					<div class="fullrow">
+						<div class="namecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="exprchar:'%', value: at('rel:', 'City')">%{this.value},</div>
+						<div class="namecell" data-dojo-type="dojox/mvc/Output"
+								data-dojo-props="value: at('rel:', 'State')"></div>
+						<div class="namecell" data-dojo-type="dojox/mvc/Output"
+								data-dojo-props="value: at('rel:', 'Zip')"></div>
+					</div>
+				</div>
+			</div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/controllers/step5_test_mvc.html b/dojox/mvc/tests/controllers/step5_test_mvc.html
new file mode 100644
index 0000000..1f34b43
--- /dev/null
+++ b/dojox/mvc/tests/controllers/step5_test_mvc.html
@@ -0,0 +1,158 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Step 5 of test for Controllers, uses an EditControllerMixin with a StoreControllerMixin.</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var ctrl;
+ 
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			'dojo/when',
+			'dojo/store/Memory',
+			'dojox/mvc/getStateful',
+			'dojox/mvc/EditStoreRefController',
+			'dojox/mvc/parserExtension',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(parser, ready, when, Memory, getStateful, EditStoreRefController){
+
+				// Initial data
+			var storeData = {
+				"identifier": "id",
+				"items": [
+					{
+						"id" : "360324",
+						"FullName" : "Mr. John Doe",
+						"Email" : "jdoe at example.com",
+						"AddressLine1" : "123 Valley Rd.",
+						"AddressLine2" : "",
+						"City" : "Cary",
+						"State" : "NC",
+						"Zip" : "27513"
+					}
+				]
+			};
+
+				// To move from an EditModelRefController to use an EditStoreRefController, need to require EditStoreRefController, 
+				// Memory, and when.  Also needed to change the data to be valid for a store query. 
+				// 
+				// Because of the queryStore call had to move the call to parser.parse inside the when to wait for it. 
+				// The change in the data for queryStore required changes to the bindings. had to add a group with target: at('rel:','0') 
+				// for the bindings of fields.  
+				//
+				// With holdModelUntilCommit set to true, you will want to bind the output address for the group to 
+				// "target: at(ctrl,'sourceModel')", if holdModelUntilCommit is false you can stay with model, sourceModel will also work.
+				// You can change holdModelUntilCommit to false to see how that works, updates will be reflected into the Verify section
+				// immediately upon focus changes, and Reset will revert back to the last saved model.
+				// The EditStoreRefController constructor sets store to the memory store and uses queryStore() to setup the models.
+				//
+
+				transformAddress2Class = {
+						format: function(value){
+							if(value && value.trim().length > 0){ 
+								return "row" // if AddressLine2 is set return row for class
+							}
+							return "hiderow"; // if AddressLine2 is not set return hiderow for class
+						}
+
+				};
+
+				ctrl = new EditStoreRefController({store: new Memory({data:storeData}), holdModelUntilCommit: true});
+				when(ctrl.queryStore(), function(){
+							parser.parse();
+				});
+
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="main">
+			<div>
+				<h2>Step 5 of test for Controllers, uses an EditStoreRefController with holdModelUntilCommit: true.</h2>
+				<h2>Enter Shipping Address</h2>
+			</div>
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'model')">
+				<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:','0')">
+					<div class="fullrow">
+						<label class="cell" for="nameInput">Full Name:</label>
+						<input class="cell" id="nameInput" data-dojo-type="dijit/form/TextBox"
+								data-dojo-props="value: at('rel:', 'FullName')">
+					</div>
+					<div class="fullrow">
+						<label class="cell" for="AddressLine1Input">Address Line1:</label>
+						<input class="cell" id="AddressLine1Input" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'AddressLine1')">
+					</div>
+					<div class="fullrow">
+						<label class="cell" for="AddressLine2Input">Address Line2:</label>
+						<input class="cell" id="AddressLine2Input" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'AddressLine2')">
+					</div>
+					<div class="fullrow">
+						<label class="cell" for="cityInput">City:</label>
+						<input class="cell" id="cityInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'City')">
+					</div>
+					<div class="fullrow">
+						<label class="cell" for="stateInput">State:</label>
+						<input class="cell" id="stateInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'State')">
+					</div>
+					<div class="fullrow">
+						<label class="cell" for="zipInput">Zipcode:</label>
+						<input class="cell" id="zipInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'Zip')">
+					</div>
+				</div>
+			</div>
+			<br/>
+
+			<div class="fullrow">
+				<button  class="buttoncell" id="reset" type="button" data-dojo-type="dijit/form/Button"  data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset</button>
+				<button  class="buttoncell" id="commit" type="button" data-dojo-type="dijit/form/Button"  data-dojo-props="onClick: function(){ ctrl.commit(); }">Save</button>
+			</div>
+
+			<br/>
+
+			<div>
+				<h2>Verify the shipping address, will not update until saved.</h2>
+			</div>
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'sourceModel')">
+				<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:','0')">
+					<div class="fullrow">
+						<div class="boldnamecell" id="nameOutput" data-dojo-type="dojox/mvc/Output"
+								data-dojo-props="value: at('rel:', 'FullName')"></div>
+					</div>
+					<div class="fullrow">
+						<div class="namecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'AddressLine1')"></div>
+					</div>
+					<div class="hiderow" data-mvc-bindings="class: at('rel:', 'AddressLine2').direction(at.from).transform(transformAddress2Class)">
+						<div class="namecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'AddressLine2')"></div>
+					</div>
+					<div class="fullrow">
+						<div class="namecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="exprchar:'%', value: at('rel:', 'City')">%{this.value},</div>
+						<div class="namecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'State')"></div>
+						<div class="namecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'Zip')"></div>
+					</div>
+				</div>
+			</div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/controllers/step6_test_mvc.html b/dojox/mvc/tests/controllers/step6_test_mvc.html
new file mode 100644
index 0000000..e9fd17c
--- /dev/null
+++ b/dojox/mvc/tests/controllers/step6_test_mvc.html
@@ -0,0 +1,236 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Step 6 of test for Controllers, uses a ListController.</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var ctrl;
+
+		require([
+			'dojo/parser',
+			'dojo/_base/declare',
+			'dojo/ready',
+			'dojox/mvc/getStateful',
+			'dojox/mvc/ListController',
+			'dojox/mvc/parserExtension',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dijit/form/RadioButton',
+			'dojox/mvc/Group',
+			'dojox/mvc/WidgetList',
+			'dojox/mvc/_InlineTemplateMixin',
+			'dojox/mvc/Output'
+			], function(parser, declare, ready, getStateful, ListController){
+
+				// Initial data
+				var listData = [
+					{
+						"id" : "360324",
+						"AddressName" : "Home",
+						"Checked" : true,
+						"FullName" : "Mr. John Doe",
+						"Email" : "jdoe at example.com",
+						"AddressLine1" : "123 Valley Rd.",
+						"AddressLine2" : "",
+						"City" : "Cary",
+						"State" : "NC",
+						"Zip" : "27513"
+					},
+					{
+						"id" : "360325",
+						"AddressName" : "Work",
+						"Checked" : false,
+						"FullName" : "Mr. John Doe",
+						"Email" : "jdoe at example.com",
+						"AddressLine1" : "4567 S Miami Blvd",
+						"AddressLine2" : "Bldg:502, Office:M120",
+						"City" : "Durham",
+						"State" : "NC",
+						"Zip" : "27703"
+					}
+				];
+
+				// To move from ModelRefController to also use ListController, I had to add the following
+				// Need to require declare, and ListController, I also needed WidgetList and _InlineTemplateMixin.  
+				// mvc/parserExtension is still needed to bind to class with data-mvc-bindings for 'AddressLine2'  
+				// Decided to setup a ctrlclz with ListController to have the functions as part of the controller. 
+				// The data had to be changed to be array data. 
+				// The html was updated to use a WidgetList to show a radio button group with the choices, and to use a 
+				// "cursor" binding for the selected address.  
+				// Added a transform (transformRadioChecked) to change the cursorIndex when a different AddressName radio button is 
+				// selected.  Also added an addEmpty function to add a New Address to the list.
+				//
+
+				var ctrlclz = declare([ListController], {
+
+					transformRadioChecked : {
+						format: function(checked){
+							if(checked){
+								ctrl.set('cursorIndex', this.target.index);
+								console.log("in transformRadioChecked setting cursorIndex to "+this.target.index);
+							}
+							return checked;
+						},
+						parse: function(checked){
+							return checked;
+						}
+					},
+
+					transformAddress2Class : {
+						format: function(value){
+							if(value && value.trim().length > 0){ 
+								return "row" // if AddressLine2 is set return row for class
+							}
+							return "hiderow"; // if AddressLine2 is not set return hiderow for class
+						}
+					},
+
+					addEmpty : function(empty){
+						var idx = this.model.length;
+						var data = {
+							"id" : Math.random(),
+							"AddressName" : "New Address",
+							"Checked" : true,
+							"FullName" : "",
+							"Email" : "",
+							"AddressLine1" : "",
+							"AddressLine2" : "",
+							"City" : "",
+							"State" : "",
+							"Zip" : ""
+						};
+						if(!empty){
+							data = {
+								"id" : Math.random(),
+								"AddressName" : "Copy of "+this.cursor.AddressName,
+								"Checked" : true,
+								"FullName" : "" || this.cursor.Name,
+								"Email" : this.cursor.Email,
+								"AddressLine1" : this.cursor.AddressLine1,
+								"AddressLine2" : this.cursor.AddressLine2,
+								"City" : this.cursor.City,
+								"State" : this.cursor.State,
+								"Zip" : this.cursor.Zip
+							};
+						}
+						this.model.splice(idx, 0, getStateful(data));
+					}
+
+				});
+				ctrl = new ctrlclz({model: getStateful(listData)});
+
+				parser.parse();
+				ctrl.model[0].set("Checked", true); // called to init the radio button selection.
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="main">
+			<div>
+				<h2>Step 6 of test for Controllers, uses a ListController.</h2>
+				<h2>Select the Shipping Address to use.</h2>
+			</div>
+
+			<div data-dojo-type="dojox/mvc/WidgetList"
+				data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				data-dojo-props="children: at(ctrl, 'model'), partialRebuild:true">
+					<script type="dojox/mvc/InlineTemplate">
+						<div>
+							<input type="radio" data-dojo-type="dijit/form/RadioButton" name="AddressName" id="radio${indexAtStartup}"
+								data-dojo-props="index: ${indexAtStartup},
+											//	value: at('rel:', 'AddressName'), // do not set value on the radio button or it will also set checked.
+												checked: at('rel:', 'Checked').transform(ctrl.transformRadioChecked)"/>
+							<label class="radioLabel" for="radio${indexAtStartup}" data-dojo-type="dojox/mvc/Output"
+									data-dojo-props="value: at('rel:', 'AddressName')"></label>
+							<br />
+						</div>
+					</script>
+			</div>
+			<div class="fullrow">
+				<button class="buttoncell" id="add" type="button" data-dojo-type="dijit/form/Button"  
+						data-dojo-props="onClick: function(){ ctrl.addEmpty(true); }">New Address</button>
+				<button class="buttoncell" id="addcopy" type="button" data-dojo-type="dijit/form/Button"  
+						data-dojo-props="onClick: function(){ ctrl.addEmpty(false); }">New copy of selected.</button>
+			</div>
+
+			<div class="spacer"></div>
+			<h2>Enter the Shipping Address</h2>
+
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'cursor')">
+				<div class="fullrow">
+					<label class="cell" for="AddressNameInput">Address Name:</label>
+					<input class="cell" id="AddressNameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'AddressName')">
+				</div>
+				<br/>
+				<div class="fullrow">
+					<label class="cell" for="nameInput">Full Name:</label>
+					<input class="cell" id="nameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'FullName')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine1Input">Address Line1:</label>
+					<input class="cell" id="AddressLine1Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine1')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine2Input">Address Line2:</label>
+					<input class="cell" id="AddressLine2Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine2')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="cityInput">City:</label>
+					<input class="cell" id="cityInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'City')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="stateInput">State:</label>
+					<input class="cell" id="stateInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'State')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="zipInput">Zipcode:</label>
+					<input class="cell" id="zipInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'Zip')">
+				</div>
+			</div>
+			<br/>
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'cursor')">
+				<div>
+					<h2>Verify the shipping address for:
+						<div class="namecell" id="AddressNameOutput" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'AddressName')"></div>
+					</h2>
+				</div>
+				<div class="fullrow">
+					<div class="boldnamecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'FullName')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine1')"></div>
+				</div>
+				<div class="hiderow" data-mvc-bindings="class: at('rel:', 'AddressLine2').direction(at.from).transform(ctrl.transformAddress2Class)">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine2')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="exprchar:'%', value: at('rel:', 'City')">%{this.value},</div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'State')"></div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'Zip')"></div>
+				</div>
+			</div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/controllers/step7_test_mvc.html b/dojox/mvc/tests/controllers/step7_test_mvc.html
new file mode 100644
index 0000000..326328e
--- /dev/null
+++ b/dojox/mvc/tests/controllers/step7_test_mvc.html
@@ -0,0 +1,245 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Step 7 of test for Controllers, uses an EditControllerMixin and ListControllerMixin.</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var ctrl;
+
+		require([
+			'dojo/parser',
+			'dojo/_base/declare',
+			'dojo/ready',
+			'dojox/mvc/getStateful',
+			'dojox/mvc/EditModelRefController',
+			'dojox/mvc/ListController',
+			'dojox/mvc/parserExtension',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dijit/form/RadioButton',
+			'dojox/mvc/Group',
+			'dojox/mvc/WidgetList',
+			'dojox/mvc/_InlineTemplateMixin',
+			'dojox/mvc/Output'
+			], function(parser, declare, ready, getStateful, EditModelRefController, ListController){
+				// Initial data
+				var listData = [
+					{
+						"id" : "360324",
+						"AddressName" : "Home",
+						"Checked" : true,
+						"FullName" : "Mr. John Doe",
+						"Email" : "jdoe at example.com",
+						"AddressLine1" : "123 Valley Rd.",
+						"AddressLine2" : "",
+						"City" : "Cary",
+						"State" : "NC",
+						"Zip" : "27513"
+					},
+					{
+						"id" : "360325",
+						"AddressName" : "Work",
+						"Checked" : false,
+						"FullName" : "Mr. John Doe",
+						"Email" : "jdoe at example.com",
+						"AddressLine1" : "4567 S Miami Blvd",
+						"AddressLine2" : "Bldg:502, Office:M120",
+						"City" : "Durham",
+						"State" : "NC",
+						"Zip" : "27703"
+					}
+				];
+
+				// To move from ModelRefController to also use EditModelRefController and a ListController, 
+				// Need to require declare, and EditModelRefController, ListController, 
+				// I also needed WidgetList and _InlineTemplateMixin.  
+				//
+				// Needed to setup ctrlclz with EditModelRefController and ListController, and the data needs to be array data and the 
+				// call to new ctrlclz uses sourceModel instead of model, and sets holdModelUntilCommit
+				// The html was updated to use a WidgetList to show a radio button group with the choices, and to use a 
+				// "cursor" binding for the selected address.  
+				// Added a transform (transformRadioChecked) to change the cursorIndex when a different AddressName radio button is 
+				// selected.  Also added an addEmpty function to add a New Address to the list.
+				//
+
+				var ctrlclz = declare([EditModelRefController, ListController], {
+
+					transformRadioChecked : {
+						format: function(checked){
+							if(checked){
+								ctrl.set('cursorIndex', this.target.index);
+								console.log("in transformRadioChecked setting cursorIndex to "+this.target.index);
+							}
+							return checked;
+						},
+						parse: function(checked){
+							return checked;
+						}
+					},
+
+					transformAddress2Class : {
+						format: function(value){
+							if(value && value.trim().length > 0){ 
+								return "row" // if AddressLine2 is set return row for class
+							}
+							return "hiderow"; // if AddressLine2 is not set return hiderow for class
+						}
+					},
+
+					addEmpty : function(empty){
+						var idx = this.model.length;
+						var data = {
+							"id" : Math.random(), 
+							"AddressName" : "New Address",
+							"Checked" : true,
+							"FullName" : "",
+							"Email" : "",
+							"AddressLine1" : "",
+							"AddressLine2" : "",
+							"City" : "",
+							"State" : "",
+							"Zip" : ""
+						};
+						if(!empty){
+							data = {
+								"id" : Math.random(), 
+								"AddressName" : "Copy of "+this.cursor.AddressName,
+								"Checked" : true,
+								"FullName" : "" || this.cursor.Name,
+								"Email" : this.cursor.Email,
+								"AddressLine1" : this.cursor.AddressLine1,
+								"AddressLine2" : this.cursor.AddressLine2,
+								"City" : this.cursor.City,
+								"State" : this.cursor.State,
+								"Zip" : this.cursor.Zip
+							};
+						}
+						this.model.splice(idx, 0, getStateful(data));
+					}
+
+				});
+				ctrl = new ctrlclz({sourceModel: getStateful(listData), holdModelUntilCommit: false});
+
+				parser.parse();
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="main">
+			<div>
+				<h2>Step 7 of test for Controllers, uses an EditModelRefController and ListController</h2>
+				<h2>Select the Shipping Address to use.</h2>
+			</div>
+
+			<div data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				 data-dojo-props="children: at(ctrl, 'model'), partialRebuild:true">
+					<script type="dojox/mvc/InlineTemplate">
+						<div>
+							<input type="radio" data-dojo-type="dijit/form/RadioButton" name="AddressName" id="radio${indexAtStartup}"
+								data-dojo-props="index: ${indexAtStartup},
+											//	value: at('rel:', 'AddressName'), // do not set value on the radio button or it will also set checked.
+												checked: at('rel:', 'Checked').transform(ctrl.transformRadioChecked)"/> 
+							<label class="radioLabel" for="radio${indexAtStartup}" data-dojo-type="dojox/mvc/Output" 
+									data-dojo-props="value: at('rel:', 'AddressName')"></label>
+							<br />
+						</div>
+					</script>
+			</div>
+			<div class="fullrow">
+				<button  class="buttoncell" id="add" type="button" data-dojo-type="dijit/form/Button"  
+						data-dojo-props="onClick: function(){ ctrl.addEmpty(true); }">New Address</button>
+				<button class="buttoncell" id="addcopy" type="button" data-dojo-type="dijit/form/Button"
+						data-dojo-props="onClick: function(){ ctrl.addEmpty(false); }">New copy of selected.</button>
+			</div>
+
+			<div class="spacer"></div>
+			<h2>Enter the Shipping Address</h2>
+
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'cursor')">
+				<div class="fullrow">
+					<label class="cell" for="AddressNameInput">Address Name:</label>
+					<input class="cell" id="AddressNameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'AddressName')">
+				</div>
+				<br/>
+				<div class="fullrow">
+					<label class="cell" for="nameInput">Full Name:</label>
+					<input class="cell" id="nameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'FullName')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine1Input">Address Line1:</label>
+					<input class="cell" id="AddressLine1Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine1')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine2Input">Address Line2:</label>
+					<input class="cell" id="AddressLine2Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine2')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="cityInput">City:</label>
+					<input class="cell" id="cityInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'City')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="stateInput">State:</label>
+					<input class="cell" id="stateInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'State')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="zipInput">Zipcode:</label>
+					<input class="cell" id="zipInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'Zip')">
+				</div>
+			</div>
+			<br/>
+
+			<div class="fullrow">
+				<button  class="buttoncell" id="reset" type="button" data-dojo-type="dijit/form/Button"  data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset</button>
+				<button  class="buttoncell" id="commit" type="button" data-dojo-type="dijit/form/Button"  data-dojo-props="onClick: function(){ ctrl.commit(); }">Save</button>
+			</div>
+
+			<br/>
+
+			<!-- I guess I can not use cursor here if I want to use sourceModel so holdModelUntilCommit: true does not work well with ListControllerMixin -->
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'cursor')"> 
+				<div>
+					<h2>Verify the shipping address for:
+						<div class="namecell" id="AddressNameOutput" data-dojo-type="dojox/mvc/Output"
+								data-dojo-props="value: at('rel:', 'AddressName')"></div>
+					</h2>
+				</div>
+				<div class="fullrow">
+					<div class="boldnamecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'FullName')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine1')"></div>
+				</div>
+				<div class="hiderow" data-mvc-bindings="class: at('rel:', 'AddressLine2').direction(at.from).transform(ctrl.transformAddress2Class)">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine2')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="exprchar:'%', value: at('rel:', 'City')">%{this.value},</div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'State')"></div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'Zip')"></div>
+				</div>
+			</div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/controllers/step8_test_mvc.html b/dojox/mvc/tests/controllers/step8_test_mvc.html
new file mode 100644
index 0000000..98c4df6
--- /dev/null
+++ b/dojox/mvc/tests/controllers/step8_test_mvc.html
@@ -0,0 +1,247 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Step 8 of test for Controllers, uses an EditStoreRefListController.</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var ctrl;
+
+		require([
+			'dojo/parser',
+			'dojo/_base/declare',
+			'dojo/ready',
+			'dojo/when',
+			'dojo/store/Memory',
+			'dojox/mvc/getStateful',
+			'dojox/mvc/EditStoreRefListController',
+			'dojox/mvc/parserExtension',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dijit/form/RadioButton',
+			'dojox/mvc/Group',
+			'dojox/mvc/WidgetList',
+			'dojox/mvc/_InlineTemplateMixin',
+			'dojox/mvc/Output'
+			], function(parser, declare, ready, when, Memory, getStateful, EditStoreRefListController){
+				// Initial data
+				var storeData = {
+					"identifier": "id",
+					"items": [
+						{
+							"id" : "360324",
+							"AddressName" : "Home",
+							"Checked" : true,
+							"FullName" : "Mr. John Doe",
+							"Email" : "jdoe at example.com",
+							"AddressLine1" : "123 Valley Rd.",
+							"AddressLine2" : "",
+							"City" : "Cary",
+							"State" : "NC",
+							"Zip" : "27513"
+						},
+						{
+							"id" : "360325",
+							"AddressName" : "Work",
+							"Checked" : false,
+							"FullName" : "Mr. John Doe",
+							"Email" : "jdoe at example.com",
+							"AddressLine1" : "4567 S Miami Blvd",
+							"AddressLine2" : "Bldg:502, Office:M120",
+							"City" : "Durham",
+							"State" : "NC",
+							"Zip" : "27703"
+						}
+					]
+				};
+
+
+				// To move from ModelRefController with EditModelRefController and a ListController to a EditStoreRefListController
+				// Need to require the EditStoreRefListController, when, and Memory 
+				// I also needed to change the data to be valid for a store query.   
+				// Needed to setup ctrlclz with EditStoreRefListController, and use when and ctrl.queryStore() to setup the models. 
+				//
+				// This test uses holdModelUntilCommit: false on the WidgetList, so updates to the address will immediately show-up in 
+				// the verify section and in the select an address section, but changes can be "Reset" back to their last saved state.
+				//
+
+				var ctrlclz = declare([EditStoreRefListController], {
+
+					transformRadioChecked : {
+						format: function(checked){
+							if(checked){
+								ctrl.set('cursorIndex', this.target.index);
+								console.log("in transformRadioChecked setting cursorIndex to "+this.target.index);
+							}
+							return checked;
+						},
+						parse: function(checked){
+							return checked;
+						}
+					},
+
+					transformAddress2Class : {
+						format: function(value){
+							if(value && value.trim().length > 0){ 
+								return "row" // if AddressLine2 is set return row for class
+							}
+							return "hiderow"; // if AddressLine2 is not set return hiderow for class
+						}
+					},
+
+					addEmpty : function(empty){
+						var idx = this.model.length;
+						var data = {
+							"id" : Math.random(), 
+							"AddressName" : "New Address",
+							"Checked" : true,
+							"FullName" : "",
+							"Email" : "",
+							"AddressLine1" : "",
+							"AddressLine2" : "",
+							"City" : "",
+							"State" : "",
+							"Zip" : ""
+						};
+						if(!empty){
+							data = {
+								"id" : Math.random(), 
+								"AddressName" : "Copy of "+this.cursor.AddressName,
+								"Checked" : true,
+								"FullName" : "" || this.cursor.Name,
+								"Email" : this.cursor.Email,
+								"AddressLine1" : this.cursor.AddressLine1,
+								"AddressLine2" : this.cursor.AddressLine2,
+								"City" : this.cursor.City,
+								"State" : this.cursor.State,
+								"Zip" : this.cursor.Zip
+							};
+						}
+						this.model.splice(idx, 0, getStateful(data));
+					}
+
+				});
+				ctrl = new ctrlclz({store: new Memory({data:storeData}), holdModelUntilCommit: false});
+				when(ctrl.queryStore(), function(){
+							parser.parse();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="main">
+			<div>
+				<h2>Step 8 of test for Controllers, uses an EditStoreRefListController with holdModelUntilCommit: false</h2>
+				<h2>Select the Shipping Address to use.</h2>
+			</div>
+
+			<div data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				 data-dojo-props="children: at(ctrl, 'model'), partialRebuild:true">
+					<script type="dojox/mvc/InlineTemplate">
+						<div>
+							<input type="radio" data-dojo-type="dijit/form/RadioButton" name="AddressName" id="radio${indexAtStartup}" 
+								data-dojo-props="index: ${indexAtStartup},
+											//	value: at('rel:', 'AddressName'), // do not set value on the radio button or it will also set checked.
+												checked: at('rel:', 'Checked').transform(ctrl.transformRadioChecked)"/> 
+							<label class="radioLabel" for="radio${indexAtStartup}" data-dojo-type="dojox/mvc/Output" 
+									data-dojo-props="value: at('rel:', 'AddressName')"></label> <br />
+						</div>
+					</script>
+			</div>
+			<div class="fullrow">
+				<button  class="buttoncell" id="add" type="button" data-dojo-type="dijit/form/Button"  
+						data-dojo-props="onClick: function(){ ctrl.addEmpty(true); }">New Address</button>
+				<button  class="buttoncell" id="addcopy" type="button" data-dojo-type="dijit/form/Button"  
+						data-dojo-props="onClick: function(){ ctrl.addEmpty(false); }">New copy of selected.</button>
+			</div>
+
+			<div class="spacer"></div>
+			<h2>Enter the Shipping Address</h2>
+
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'cursor')">
+				<div class="fullrow">
+					<label class="cell" for="AddressNameInput">Address Name:</label>
+					<input class="cell" id="AddressNameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'AddressName')">
+				</div>
+				<br/>
+				<div class="fullrow">
+					<label class="cell" for="nameInput">Full Name:</label>
+					<input class="cell" id="nameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'FullName')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine1Input">Address Line1:</label>
+					<input class="cell" id="AddressLine1Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine1')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine2Input">Address Line2:</label>
+					<input class="cell" id="AddressLine2Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine2')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="cityInput">City:</label>
+					<input class="cell" id="cityInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'City')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="stateInput">State:</label>
+					<input class="cell" id="stateInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'State')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="zipInput">Zipcode:</label>
+					<input class="cell" id="zipInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'Zip')">
+				</div>
+			</div>
+			<br/>
+
+			<div class="fullrow">
+				<button  class="buttoncell" id="reset" type="button" data-dojo-type="dijit/form/Button"  data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset</button>
+				<button  class="buttoncell" id="commit" type="button" data-dojo-type="dijit/form/Button"  data-dojo-props="onClick: function(){ ctrl.commit(); }">Save</button>
+			</div>
+
+			<br/>
+
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'cursor')"> 
+			<div>
+				<h2>Verify the shipping address for:
+					<div class="namecell" id="AddressNameOutput" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'AddressName')"></div>
+
+				</h2>
+			</div>
+				<div class="fullrow">
+					<div class="boldnamecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'FullName')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine1')"></div>
+				</div>
+				<div class="hiderow" data-mvc-bindings="class: at('rel:', 'AddressLine2').direction(at.from).transform(ctrl.transformAddress2Class)">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine2')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="exprchar:'%', value: at('rel:', 'City')">%{this.value},</div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'State')"></div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'Zip')"></div>
+				</div>
+			</div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/controllers/step9_test_mvc.html b/dojox/mvc/tests/controllers/step9_test_mvc.html
new file mode 100644
index 0000000..f252445
--- /dev/null
+++ b/dojox/mvc/tests/controllers/step9_test_mvc.html
@@ -0,0 +1,257 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Step 9 of test for Controllers, uses an EditStoreRefListController with holdModelUntilCommit: true.</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var ctrl;
+
+		require([
+			'dojo/parser',
+			'dojo/_base/declare',
+			'dojo/ready',
+			'dojo/when',
+			'dojo/store/Memory',
+			'dojox/mvc/at',
+			'dojox/mvc/getStateful',
+			'dojox/mvc/EditStoreRefListController',
+			'dojox/mvc/ListController',
+			'dojox/mvc/parserExtension',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dijit/form/RadioButton',
+			'dojox/mvc/Group',
+			'dojox/mvc/WidgetList',
+			'dojox/mvc/_InlineTemplateMixin',
+			'dojox/mvc/Output'
+			], function(parser, declare, ready, when, Memory, at, getStateful, 
+						EditStoreRefListController, ListController){
+				// Initial data
+				var storeData = {
+					"identifier": "id",
+					"items": [
+						{
+							"id" : "360324",
+							"AddressName" : "Home",
+							"Checked" : true,
+							"FullName" : "Mr. John Doe",
+							"Email" : "jdoe at example.com",
+							"AddressLine1" : "123 Valley Rd.",
+							"AddressLine2" : "",
+							"City" : "Cary",
+							"State" : "NC",
+							"Zip" : "27513"
+						},
+						{
+							"id" : "360325",
+							"AddressName" : "Work",
+							"Checked" : false,
+							"FullName" : "Mr. John Doe",
+							"Email" : "jdoe at example.com",
+							"AddressLine1" : "4567 S Miami Blvd",
+							"AddressLine2" : "Bldg:502, Office:M120",
+							"City" : "Durham",
+							"State" : "NC",
+							"Zip" : "27703"
+						}
+					]
+				};
+
+
+				// To move from EditStoreRefListController with holdModelUntilCommit: false to use holdModelUntilCommit: true 
+				// I had to add the require for dojox/mvc/at and ListController 
+				//
+				// This test uses holdModelUntilCommit: true on the WidgetList, so updates to the address will not show-up in 
+				// the "Verify" section and in the "Select an address" section until "Save" is pressed.
+				// But using holdModelUntilCommit: true requires use of a second controller (ctrlSource) which is a ListController 
+				// and is bound to the sourceModel and cursorIndex of the first controller (ctrl).
+				//
+				// The "Verify" section and the "Select an address" section are bound to at(ctrlSource,'cursor') and at(ctrlSource, 'model') respectively.
+				// To set the Radio buttons correctly, "Checked" has to be updated in ctrl.model inside the transformRadioChecked. 
+				//
+
+				var ctrlclz = declare([EditStoreRefListController], {
+
+					transformRadioChecked : {
+						format: function(checked){
+							if(checked){
+								ctrl.set('cursorIndex', this.target.index);
+								console.log("in transformRadioChecked setting cursorIndex to "+this.target.index);
+							}
+							ctrl.model[this.target.index].set("Checked", checked);  // had to do this here to update the ctrl.model too.
+							return checked;
+						},
+						parse: function(checked){
+							return checked;
+						}
+					},
+
+					transformAddress2Class : {
+						format: function(value){
+							if(value && value.trim().length > 0){ 
+								return "row" // if AddressLine2 is set return row for class
+							}
+							return "hiderow"; // if AddressLine2 is not set return hiderow for class
+						}
+					},
+
+					addEmpty : function(empty){
+						var idx = this.model.length;
+						var data = {
+							"id" : Math.random(), 
+							"AddressName" : "New Address",
+							"Checked" : true,
+							"FullName" : "",
+							"Email" : "",
+							"AddressLine1" : "",
+							"AddressLine2" : "",
+							"City" : "",
+							"State" : "",
+							"Zip" : ""
+						};
+						if(!empty){
+							data = {
+								"id" : Math.random(), 
+								"AddressName" : "Copy of "+this.cursor.AddressName,
+								"Checked" : true,
+								"FullName" : "" || this.cursor.Name,
+								"Email" : this.cursor.Email,
+								"AddressLine1" : this.cursor.AddressLine1,
+								"AddressLine2" : this.cursor.AddressLine2,
+								"City" : this.cursor.City,
+								"State" : this.cursor.State,
+								"Zip" : this.cursor.Zip
+							};
+						}
+						var statefulData = getStateful(data);
+						this.model.splice(idx, 0, statefulData);
+						ctrlSource.model.splice(idx, 0, statefulData);
+					}
+
+				});
+				ctrl = new ctrlclz({store: new Memory({data:storeData}), holdModelUntilCommit: true});
+				ctrlSource = new (declare([ListController], {}))({model: at(ctrl, "sourceModel"), cursorIndex: at(ctrl, "cursorIndex")});
+				when(ctrl.queryStore(), function(){
+							parser.parse();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="main">
+			<div>
+				<h2>Step 9 of test for Controllers, uses an EditStoreRefListController with holdModelUntilCommit: true</h2>
+				<h2>Select the Shipping Address to use.</h2>
+			</div>
+
+			<div data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				 data-dojo-props="children: at(ctrlSource, 'model'), partialRebuild:true">
+					<script type="dojox/mvc/InlineTemplate">
+						<div>
+							<input type="radio" data-dojo-type="dijit/form/RadioButton" name="AddressName" id="radio${indexAtStartup}" 
+								data-dojo-props="index: ${indexAtStartup},
+											//	value: at('rel:', 'AddressName'), // do not set value on the radio button or it will also set checked.
+												checked: at('rel:', 'Checked').transform(ctrl.transformRadioChecked)"/> 
+							<label class="radioLabel" for="radio${indexAtStartup}" data-dojo-type="dojox/mvc/Output" 
+									data-dojo-props="value: at('rel:', 'AddressName')"></label> <br />
+						</div>
+					</script>
+			</div>
+			<div class="fullrow">
+				<button  class="buttoncell" id="add" type="button" data-dojo-type="dijit/form/Button"  
+						data-dojo-props="onClick: function(){ ctrl.addEmpty(true); }">New Address</button>
+				<button  class="buttoncell" id="addcopy" type="button" data-dojo-type="dijit/form/Button"  
+						data-dojo-props="onClick: function(){ ctrl.addEmpty(false); }">New copy of selected.</button>
+			</div>
+
+			<div class="spacer"></div>
+			<h2>Enter the Shipping Address</h2>
+
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrl,'cursor')">
+				<div class="fullrow">
+					<label class="cell" for="AddressNameInput">Address Name:</label>
+					<input class="cell" id="AddressNameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'AddressName')">
+				</div>
+				<br/>
+				<div class="fullrow">
+					<label class="cell" for="nameInput">Full Name:</label>
+					<input class="cell" id="nameInput" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'FullName')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine1Input">Address Line1:</label>
+					<input class="cell" id="AddressLine1Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine1')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="AddressLine2Input">Address Line2:</label>
+					<input class="cell" id="AddressLine2Input" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'AddressLine2')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="cityInput">City:</label>
+					<input class="cell" id="cityInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'City')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="stateInput">State:</label>
+					<input class="cell" id="stateInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'State')">
+				</div>
+				<div class="fullrow">
+					<label class="cell" for="zipInput">Zipcode:</label>
+					<input class="cell" id="zipInput" data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'Zip')">
+				</div>
+			</div>
+			<br/>
+
+			<div class="fullrow">
+				<button  class="buttoncell" id="reset" type="button" data-dojo-type="dijit/form/Button"  data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset</button>
+				<button  class="buttoncell" id="commit" type="button" data-dojo-type="dijit/form/Button"  data-dojo-props="onClick: function(){ ctrl.commit(); }">Save</button>
+			</div>
+
+			<br/>
+
+			<div class="fullrow" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at(ctrlSource,'cursor')"> 
+			<div>
+				<h2>Verify the shipping address for:
+					<div class="namecell" id="AddressNameOutput" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'AddressName')"></div>
+
+				</h2>
+			</div>
+				<div class="fullrow">
+					<div class="boldnamecell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at('rel:', 'FullName')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine1')"></div>
+				</div>
+				<div class="hiderow" data-mvc-bindings="class: at('rel:', 'AddressLine2').direction(at.from).transform(ctrl.transformAddress2Class)">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'AddressLine2')"></div>
+				</div>
+				<div class="fullrow">
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="exprchar:'%', value: at('rel:', 'City')">%{this.value},</div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'State')"></div>
+					<div class="namecell" data-dojo-type="dojox/mvc/Output"
+						data-dojo-props="value: at('rel:', 'Zip')"></div>
+				</div>
+			</div>
+		</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/css/android-format.css b/dojox/mvc/tests/css/android-format.css
old mode 100755
new mode 100644
diff --git a/dojox/mvc/tests/css/app-format.css b/dojox/mvc/tests/css/app-format.css
old mode 100755
new mode 100644
index 3f3fdc0..3b3ba04
--- a/dojox/mvc/tests/css/app-format.css
+++ b/dojox/mvc/tests/css/app-format.css
@@ -19,8 +19,18 @@ body {
 tbody { display: inline-block; width: 100%; }
 .row { width: 500px; display: inline-block; margin: 5px; }
 .cell { width: 20%;  display:inline-block; }
+.fullrow { width: 100%; display: inline-block; margin: 5px; }
+.fixedcell { width: 170px;  display:inline-block; }
+.buttoncell { display:inline-block; }
 .widerow { width: 900px; display: inline-block; margin: 5px; }
 .narrowcell { width: 5%;  display:inline-block; }
+.namecell { margin-right: 2px;  display:inline-block; }
+.radioLabel {text-align: left; display:inline-block;  width: 20%; }
+.boldnamecell { font-weight: bold; margin-right: 2px;  display:inline-block; }
+
+.hiderow {  width: 100%; display: none; margin: 5px;  }
+
+
 label { text-align: right; width: 98%; display: inline-block; font-weight: bold; }
 
 .generate-heading { font-size:1.2em; font-weight:bold; }
diff --git a/dojox/mvc/tests/css/dijitTests.css b/dojox/mvc/tests/css/dijitTests.css
deleted file mode 100644
index 33efb89..0000000
--- a/dojox/mvc/tests/css/dijitTests.css
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Test file styles for Dijit widgets */
-
-body {
-	background:#fff url("../images/testsBodyBg.gif") repeat-x top left;
-	padding:2em 2em 2em 2em;
-}
-
-h1.testTitle {
-	font-size:2em;
-	margin:0 0 1em 0;
-}
-
-/* Icons used in the tests */
-
-.plusIcon, .plusBlockIcon {
-	background-image: url(../images/plus.gif);
-	background-repeat: no-repeat;
-	background-position: center center;
-	width: 18px;
-	height: 18px;
-}
-.plusBlockIcon {
-	display: block !important;
-}
-.noteIcon {
-	background-image: url(../images/note.gif);
-	background-repeat: no-repeat;
-	background-position: center center;
-	width: 18px;
-	height: 18px;
-}
-.flatScreenIcon {
-	background-image: url(../images/flatScreen.gif);
-	background-repeat: no-repeat;
-	width: 32px;
-	height: 32px;
-}
-.dijitTestNodeDialog {
-	position:absolute;
-	top:5px;
-	right:5px;
-	display:block;
-	width:200px;
-	visibility:hidden;
-	background-color:#fff !important;
-	color:#000 !important;
-	border:1px solid #000;
-	padding:5px;
-}
-.dijitTestNodeDialog table {
-	background-color:#fff !important;
-}
-.dijitTestNodeDialog td {
-	padding:3px;
-}
-.dijitTestNodeShowing {
-	visibility:visible;
-}
-
-body .customFolderOpenedIcon, body .customFolderClosedIcon {
-	background-image: url('../images/folderIcons.png'); /* mail icons sprite image */
-	background-repeat: no-repeat;
-	width: 18px;
-	height: 18px;
-    background-position: -44px;
-}
-
-.dj_ie6 .customFolderOpenedIcon, .dj_ie6 .customFolderClosedIcon {
-	background-image: url('../images/folderIcons.gif');
-}
-
-.customFolderClosedIcon {
-    background-position: -154px;
-}
-
-#testMatrix {
-	width:100%;
-	text-align:center;
-}
-#testMatrix tr > td {
-	text-align:left;
-}
-#testMatrix tr.top {
-	background:blue;
-	color:#fff;
-}
-#testMatrix tr.top th {
-	padding:6px;
-}
-#testMatrix tr.tests {
-	background:#666;
-	padding:3px;
-	padding-left:6px;
-	padding-right:6px;
-	color:#fff;
-}
-#testMatrix tr.tests th {
-	text-align:center;
-}
-#testMatrix tr.spacer {
-	background:#dedede;
-	color:#666;
-}
-#testMatrix tr.spacer td {
-	padding:6px;
-}
-#testMatrix tr.testRow td {
-	text-align:center;
-}
-#testMatrix tr.testRow td.label {
-	text-align:left;
-	padding-left:15px;
-}
-#testMatrix tr.alt {
-	background:#ededed;
-}
diff --git a/dojox/mvc/tests/css/index-format.css b/dojox/mvc/tests/css/index-format.css
old mode 100755
new mode 100644
diff --git a/dojox/mvc/tests/css/iphone-format.css b/dojox/mvc/tests/css/iphone-format.css
old mode 100755
new mode 100644
diff --git a/dojox/mvc/tests/docExamples/generateDeclarativeExample1.html b/dojox/mvc/tests/docExamples/generateDeclarativeExample1.html
new file mode 100644
index 0000000..58fc697
--- /dev/null
+++ b/dojox/mvc/tests/docExamples/generateDeclarativeExample1.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html >
+<head>
+
+		<style type="text/css">
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+<script src="../../../../dojo/dojo.js" data-dojo-config='parseOnLoad: true, mvc: {debugBindings: true}'></script><script>var searchRecords;
+	
+	
+</script>
+<script>
+/* BEGIN .. js :: Things in this section have to be two tabs in */
+
+			require([
+				"dojo/parser",
+				"dojo/_base/json",
+				"dijit/form/Textarea",
+				"dojox/mvc/Generate"
+			], function(parser){
+				parser.parse();
+			});
+
+/* END .. js :: */
+</script>
+</head>
+<body class="claro">
+<!--  BEGIN .. html :: THINGS IN HERE START TWO TABS IN -->	
+
+
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+				<h1>View generation example</h1>
+				<h2>Data Binding - Generate Container.</h2>
+			</div>
+		</div>
+		<div id="main">
+			<div id="leftNav"></div>
+			<div id="mainContent">
+				<h3>Model</h3>
+				<div class="row">
+					<textarea id="textarea" class="cell" data-dojo-type="dijit/form/Textarea">
+		{
+			Serial: "360324",
+			First: "John",
+			Last: "Doe",
+			Email: "jdoe at example.com",
+			Address: {
+				Street: "123 Valley Rd",
+				City: "Katonah",
+				State: "NY",
+				Zip: "10536"
+			},
+			Phones: [
+				{
+					Areacode: "111",
+					Local: "111-1111"
+				},{
+					Areacode: "222",
+					Local: "222-2222"
+				}
+			],
+			Member: {
+				Since: "2010",
+				Type: "Gold"
+			}
+		}
+					</textarea>
+				</div>
+				<h3>Generated View</h3>
+				<div data-dojo-type="dojox/mvc/Generate"
+				 data-dojo-props="children: at('widget:textarea', 'value').direction(at.from).transform({format: dojo.fromJson}), idNameMapping: {String: 'view_t'}"></div>
+			</div>
+		</div>
+		</div>
+
+		<p>In the above example, the Generate will create a view with a label and TextBox for each of the fields listed in the textarea, and any updates to the textarea will be cause the view to be updated when you tab out of the text area.</p>
+
+<!--  END .. html :: THINGS IN HERE START TWO TABS IN -->	
+</body>
+</html>
diff --git a/dojox/mvc/tests/docExamples/groupDeclarativeExample1.html b/dojox/mvc/tests/docExamples/groupDeclarativeExample1.html
new file mode 100644
index 0000000..9d33ccc
--- /dev/null
+++ b/dojox/mvc/tests/docExamples/groupDeclarativeExample1.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html >
+<head>
+
+		<style type="text/css">
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+	<style type="text/css">.row { width: 500px; display: inline-block; margin: 5px; }
+.cell { width: 20%;  display:inline-block; }</style>
+<script src="../../../../dojo/dojo.js" data-dojo-config='parseOnLoad: true, mvc: {debugBindings: true}'></script><script>var searchRecords;
+
+require([
+        'dojo/parser',
+        'dojo/ready',
+        'dojox/mvc/getStateful',
+        'dijit/form/TextBox',
+        'dijit/form/Button',
+        'dojox/mvc/Group',
+        'dojox/mvc/Output'
+        ], function(parser, ready, getStateful){
+
+        // Initial data
+        var order = {
+                "Serial" : "360324",
+                "First" : "John",
+                "Last" : "Doe",
+                "Email" : "jdoe at example.com",
+                "ShipTo" : {
+                        "Street" : "123 Valley Rd",
+                        "City" : "Katonah",
+                        "State" : "NY",
+                        "Zip" : "10536"
+                },
+                "BillTo" : {
+                        "Street" : "17 Skyline Dr",
+                        "City" : "Hawthorne",
+                        "State" : "NY",
+                        "Zip" : "10532"
+                }
+        };
+                // The getStateful call will take json data and create make it Stateful
+                model = getStateful(order);
+                // the model created above is initialized with
+                // model.First set to "John", model.Last set to "Doe" and model.Email set to "jdoe at example.com"
+
+        });
+
+        function setRef(id, model, attr) {
+                require([
+                         "dijit/registry",
+                         "dojox/mvc/at"
+                         ], function(registry, at){
+                                                var widget = registry.byId(id);
+                                                widget.set("target", model[attr]);
+                                        });
+        };</script>
+</head>
+<body class="claro">
+    <script type="dojo/require">at: "dojox/mvc/at"</script>
+<div id="main">
+<div id="leftNav"></div>
+<div id="mainContent">
+<!--
+        The group container denotes some logical grouping of widgets and also serves
+        to establish a parent data binding context for its children.
+        The target attribute for the outermost container obtains the binding from the
+        "page scope" itself.
+-->
+<!--
+        For convenience, the widget hierarchy matches the data hierarchy
+        (see JSON literal above).
+        In this implementation, the child attributes are simple property names
+        of the parent binding context.
+-->
+<div class="row" id="addrGroup" data-dojo-type="dojox/mvc/Group"
+                                        data-dojo-props="target: model.ShipTo">
+        <div class="row">
+                <label class="cell" for="streetInput">Street:</label>
+                <input class="cell" id="streetInput" data-dojo-type="dijit/form/TextBox"
+                        data-dojo-props="value: at('rel:', 'Street')">
+        </div>
+        <div class="row">
+                <label class="cell" for="cityInput">City:</label>
+                <input class="cell" id="cityInput" data-dojo-type="dijit/form/TextBox"
+                        data-dojo-props="value: at('rel:', 'City')">
+        </div>
+        <div class="row">
+                <label class="cell" for="stateInput">State:</label>
+                <input class="cell" id="stateInput" data-dojo-type="dijit/form/TextBox"
+                        data-dojo-props="value: at('rel:', 'State')">
+        </div>
+        <div class="row">
+                <label class="cell" for="zipInput">Zipcode:</label>
+                <input class="cell" id="zipInput" data-dojo-type="dijit/form/TextBox"
+                        data-dojo-props="value: at('rel:', 'Zip')">
+        </div>
+</div>
+<br/>
+Choose:
+<button id="shipto" type="button" data-dojo-type="dijit/form/Button"
+                data-dojo-props="onClick: function(){setRef('addrGroup', model, 'ShipTo');}">Ship To</button>
+<button id="billto" type="button" data-dojo-type="dijit/form/Button"
+                data-dojo-props="onClick: function(){setRef('addrGroup', model, 'BillTo');}">Bill To</button>
+<br/>
+<br/>
+</div></div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/docExamples/repeatDeclarativeExample1.html b/dojox/mvc/tests/docExamples/repeatDeclarativeExample1.html
new file mode 100644
index 0000000..eb50ee0
--- /dev/null
+++ b/dojox/mvc/tests/docExamples/repeatDeclarativeExample1.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html>
+<html >
+<head>
+
+		<style type="text/css">
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+	<style type="text/css">
+/* BEGIN .. css :: Things in this section have to be two tabs in */
+	
+        .row { width: 500px; display: inline-block; margin: 5px; }
+        .cell { width: 20%;  display:inline-block; }
+
+/* END .. css :: Things in this section have to be two tabs in */
+</style>
+<script src="../../../../dojo/dojo.js" data-dojo-config='parseOnLoad: true, mvc: {debugBindings: true}'></script>
+<script>
+/* BEGIN .. js :: Things in this section have to be two tabs in */
+
+		var searchRecords; 
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc/getStateful',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Repeat',
+			'dojox/mvc/Output'
+			], function(parser, ready, getStateful){
+
+			// Initial data
+			var search_results_init = {
+  			"identifier": "Serial",
+   			"items": [ 
+                    {
+                        "Serial"  : "A111",
+                        "First"   : "Anne",
+                        "Last"    : "Ackerman",
+                        "Email"   : "a.a at test.com"
+                    },
+                    {
+                        "Serial"  : "B111",
+                        "First"   : "Ben",
+                        "Last"    : "Beckham",
+                        "Email"   : "b.b at test.com"
+                    },
+                    {
+                        "Serial"  : "I111",
+                        "First"   : "Irene",
+                        "Last"    : "Ira",
+                        "Email"   : "i.i at test.com"
+                    },
+                    {
+                        "Serial"  : "J111",
+                        "First"   : "John",
+                        "Last"    : "Jacklin",
+                        "Email"   : "j.j at test.com"
+                    }
+                ]
+			};
+				// The getStateful call will take json data and create make it Stateful
+				searchRecords = getStateful(search_results_init);
+			});
+
+/* END .. js :: */
+</script>
+</head>
+<body class="claro">
+<!--  BEGIN .. html :: THINGS IN HERE START TWO TABS IN -->	
+
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="main">
+		<div data-dojo-type="dojox/mvc/Group" data-dojo-props="target: searchRecords">
+        <!--
+            The repeat container denotes a templated UI that operates over a collection
+            of data records.
+            The UI can be customized for each iteration using properties such as
+            ${this.index} for the iteration index.
+        -->
+        	<h4>Repeat with TextBox for First and Last properties: </h4>        
+        	<div id="repeatId" data-dojo-type="dojox/mvc/Repeat" data-dojo-props="children: at('rel:', 'items')">
+            <div class="row" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:', ${this.index})">
+                <label class="cell" for="nameInput${this.index}">Name:</label>
+                <input class="cell" data-dojo-type="dijit/form/TextBox" id="nameInput${this.index}"
+                                    data-dojo-props="value: at('rel:', 'First')"></input>
+                <input class="cell" data-dojo-type="dijit/form/TextBox"
+                                    data-dojo-props="value: at('rel:', 'Last')"></input>
+            </div>
+        </div>
+        <h4>Repeat with mvc/Output for First and Last properties, will be updated when the TextBox is updated: </h4>        
+        <div id="repeatIdOutput" data-dojo-type="dojox/mvc/Repeat" data-dojo-props="children: at('rel:', 'items')">
+            <div class="row" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:', ${this.index})">
+                <label class="cell" for="nameOutput${this.index}">Name:</label>
+                <div class="cell" data-dojo-type="dojox/mvc/Output" id="nameOutput${this.index}"
+                                    data-dojo-props="value: at('rel:', 'First')"></div>
+                <div class="cell" data-dojo-type="dojox/mvc/Output"
+                                    data-dojo-props="value: at('rel:', 'Last')"></div>
+            </div>
+        </div>
+		</div>
+        <p>In the above example, the TextBoxes inside the repeat will display the firstname of each of the entries in the model.
+		</div>
+
+<!--  END .. html :: THINGS IN HERE START TWO TABS IN -->	
+</body>
+</html>
diff --git a/dojox/mvc/tests/docExamples/widgetListDeclarativeExample1.html b/dojox/mvc/tests/docExamples/widgetListDeclarativeExample1.html
new file mode 100644
index 0000000..6d0353e
--- /dev/null
+++ b/dojox/mvc/tests/docExamples/widgetListDeclarativeExample1.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html >
+<head>
+
+		<style type="text/css">
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+	<style type="text/css">
+/* BEGIN .. css :: Things in this section have to be two tabs in */
+	
+        .row { width: 500px; display: inline-block; margin: 5px; }
+        .cell { width: 20%;  display:inline-block; }
+
+/* END .. css :: Things in this section have to be two tabs in */
+</style>
+<script src="../../../../dojo/dojo.js" data-dojo-config='parseOnLoad: true, mvc: {debugBindings: true}'></script><script>var searchRecords;
+
+/* BEGIN .. js :: Things in this section have to be two tabs in */
+ 
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc/getStateful',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/WidgetList',
+			'dojox/mvc/Output'
+        ], function(parser, ready, getStateful){
+
+        // Initial data
+		var data = {
+  			"identifier": "Serial",
+   			"items": [ 
+                    {
+                        "Serial"  : "A111",
+                        "First"   : "Anne",
+                        "Last"    : "Ackerman",
+                        "Email"   : "a.a at test.com"
+                    },
+                    {
+                        "Serial"  : "B111",
+                        "First"   : "Ben",
+                        "Last"    : "Beckham",
+                        "Email"   : "b.b at test.com"
+                    },
+                    {
+                        "Serial"  : "I111",
+                        "First"   : "Irene",
+                        "Last"    : "Ira",
+                        "Email"   : "i.i at test.com"
+                    },
+                    {
+                        "Serial"  : "J111",
+                        "First"   : "John",
+                        "Last"    : "Jacklin",
+                        "Email"   : "j.j at test.com"
+                    }
+                ]
+			};
+
+                // The getStateful call will take json data and create make it Stateful
+                searchRecords = getStateful(data);
+        });
+        
+/* END .. js :: */
+        
+        </script>
+</head>
+<body class="claro">
+<!--  BEGIN .. html :: THINGS IN HERE START TWO TABS IN -->	
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="main">
+			<div data-dojo-type="dojox/mvc/Group"
+				data-dojo-props="target: searchRecords">
+        	<!--
+                The WidgetList container denotes a templated UI that operates over
+                a collection of data records.
+        	-->
+        	<h4>Declarative WidgetList using data-mvc-child-type to create TextBox with data bound to the First name from the items: </h4>
+        	<div data-dojo-type="dojox/mvc/WidgetList"
+                 data-dojo-props="children: at('rel:', 'items')"
+                 data-mvc-child-type="dijit/form/TextBox"
+                 data-mvc-child-props="value: at(this.target, 'First'),
+                                                class: 'row'">
+        	</div>
+		</div>
+		<h4>Declarative WidgetList using a dojox/mvc/InlineTemplate to create label with the Serial and a TextBox with data bound to the First name from the items: </h4>
+		<div data-dojo-type="dojox/mvc/WidgetList"
+			data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+			data-dojo-props="children: at(searchRecords, 'items')">
+			<script type="dojox/mvc/InlineTemplate">
+			<div>
+				<span data-dojo-type="dijit/_WidgetBase"
+						data-dojo-props="value: at('rel:', 'Serial'),
+							_setValueAttr: {node: 'domNode',
+									type: 'innerText'}">
+					</span>:
+					<span data-dojo-type="dijit/form/TextBox"
+						data-dojo-props="value: at('rel:', 'First')"></span>
+				</div>
+			</script>
+		</div>
+		<p>Updates to either set of TextBoxes will be reflected in the other set when tabbing out of the field, since they are bound to the same model properties.
+	</div>
+<!--  END .. html :: THINGS IN HERE START TWO TABS IN -->	
+</body>
+</html>
diff --git a/dojox/mvc/tests/docExamples/widgetListProgrammaticExample1.html b/dojox/mvc/tests/docExamples/widgetListProgrammaticExample1.html
new file mode 100644
index 0000000..49af20b
--- /dev/null
+++ b/dojox/mvc/tests/docExamples/widgetListProgrammaticExample1.html
@@ -0,0 +1,121 @@
+<!DOCTYPE html>
+<html >
+<head>
+
+		<style type="text/css">
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+	<style type="text/css">
+/* BEGIN .. css :: Things in this section have to be two tabs in */
+	
+        .row { width: 500px; display: inline-block; margin: 5px; }
+        .cell { width: 20%;  display:inline-block; }
+
+/* END .. css :: Things in this section have to be two tabs in */
+</style>
+<script src="../../../../dojo/dojo.js" data-dojo-config='parseOnLoad: false, mvc: {debugBindings: true}'></script><script>var searchRecords;
+
+/* BEGIN .. js :: Things in this section have to be two tabs in */
+
+		var templateString2 = '<div class="row">'
+		+ '<script type="dojo/require">at: "dojox/mvc/at"<\/script>'
+		+ '<label class="cell">Name:</label>'
+		+ '<input id="${parent.id}_textbox${indexAtStartup}" class="cell" data-dojo-type="dijit/form/TextBox" data-dojo-attach-point="firstNode"></input>'
+		+ '<input class="cell" data-dojo-type="dijit/form/TextBox" data-dojo-attach-point="lastNode"></input>'
+		+ '</div>';
+
+
+		require([
+			"dojo/_base/declare",
+			"dojo/when",
+			"dojo/dom",
+			"dojo/parser",
+			"dojo/promise/all",
+			"dojo/store/Memory",
+			"dojox/mvc/at",
+			"dijit/registry",
+			"dijit/_WidgetBase",
+			"dojox/mvc/EditStoreRefListController",
+			"dojox/mvc/WidgetList",
+			"dijit/form/TextBox",
+			"dojox/mvc/Group",
+			"dojo/domReady!"
+		], function(declare, when, ddom, parser, all, Memory, at, registry, _WidgetBase, EditStoreRefListController, WidgetList){
+
+        // Initial data
+		var data = {
+  			"identifier": "Serial",
+   			"items": [ 
+                    {
+                        "Serial"  : "A111",
+                        "First"   : "Anne",
+                        "Last"    : "Ackerman",
+                        "Email"   : "a.a at test.com"
+                    },
+                    {
+                        "Serial"  : "B111",
+                        "First"   : "Ben",
+                        "Last"    : "Beckham",
+                        "Email"   : "b.b at test.com"
+                    },
+                    {
+                        "Serial"  : "I111",
+                        "First"   : "Irene",
+                        "Last"    : "Ira",
+                        "Email"   : "i.i at test.com"
+                    },
+                    {
+                        "Serial"  : "J111",
+                        "First"   : "John",
+                        "Last"    : "Jacklin",
+                        "Email"   : "j.j at test.com"
+                    }
+                ]
+			};
+
+			ctrl = new EditStoreRefListController({store: new Memory({data: data})});
+
+			// Programmatic WidgetList using childBindings and a templateString using attach-points
+			(new WidgetList({templateString: templateString2, 
+							children: at(ctrl, "model"),
+							childBindings: {
+								firstNode: {value: at("rel:", "First")},
+								lastNode: {value: at("rel:", "Last")}
+							}},
+							ddom.byId("programmaticRepeat1"))).startup();
+							
+			// Programatic WidgetList using childParams and startup function to setup bindings with templateString using attach-points
+			(new WidgetList({templateString: templateString2, 
+							children: at(ctrl, "model"),
+							childParams: {
+								startup: function(){
+									this.firstNode.set("value", at("rel:", "First"));
+									this.lastNode.set("value", at("rel:", "Last"));
+									this.inherited("startup", arguments);
+							}}},
+							ddom.byId("programmaticRepeat2"))).startup();
+							
+			when(all([parser.parse(), ctrl.queryStore()]), function(a){
+				console.log("parser.parse and queryStore are complete ctrl.model is set to from the query",a[1]);
+			});
+
+        });
+
+/* END .. js :: */
+
+        </script>
+</head>
+<body class="claro">
+
+<!--  BEGIN .. html :: THINGS IN HERE START TWO TABS IN -->	
+		<div id="main">
+        	<h4>Programatic WidgetList using childBindings to setup the bindings with a templateString using attach-points: </h4>
+        	<div id="programmaticRepeat1"></div>
+        	<h4>Programatic WidgetList using childParams and startup function to setup bindings with templateString using attach-points: </h4>
+        	<div id="programmaticRepeat2"></div>
+			<p>In the above example, the TextBoxes inside the WidgetList are bound to the same model, so updates in one list will be reflected in the other.        
+		</div>
+
+<!--  END .. html :: THINGS IN HERE START TWO TABS IN -->	
+</body>
+</html>
diff --git a/dojox/mvc/tests/doh/ModelRefController.js b/dojox/mvc/tests/doh/ModelRefController.js
new file mode 100644
index 0000000..aa827f6
--- /dev/null
+++ b/dojox/mvc/tests/doh/ModelRefController.js
@@ -0,0 +1,28 @@
+define([
+	"doh",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/Stateful",
+	"dijit/_WidgetBase",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"../doh/ModelRefController",
+	"dojo/text!../templates/ModelRefControllerInTemplate.html"
+], function(doh, declare, lang, Stateful, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, ModelRefController, template){
+	doh.register("dojox.mvc.tests.doh.ModelRefController", [
+		{
+			name: "attachPoint",
+			runTest: function(){
+				lang.setObject("model", new Stateful());
+				var w = new (declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+					templateString: template
+				}))();
+				w.startup();
+				doh.t(w.controllerNode, "The controllerNode exists in the template widget");
+			},
+			tearDown: function(){
+				lang.setObject("model", void 0);
+			}
+		}
+	]);
+});
\ No newline at end of file
diff --git a/dojox/mvc/tests/doh/StatefulArray.js b/dojox/mvc/tests/doh/StatefulArray.js
new file mode 100644
index 0000000..f964f3e
--- /dev/null
+++ b/dojox/mvc/tests/doh/StatefulArray.js
@@ -0,0 +1,51 @@
+define([
+	"doh",
+	"dojo/Stateful",
+	"dojox/mvc/StatefulArray"
+], function(doh, Stateful, StatefulArray){
+	doh.register("dojox.mvc.tests.doh.StatefulArray", [
+		{
+			name: "splice",
+			runTest: function(){
+				var dfd = new doh.Deferred(),
+				 a = new StatefulArray([0, 1, 2, 3]);
+
+				this.h = a.watchElements(function(idx, removals, adds){
+					try{
+						doh.is(1, idx, "The removal starts with index 1");
+						doh.is([1, 2], removals, "Index 1 and index 2 should be removed");
+						doh.is([100, 101], adds, "100 and 101 should be added");
+					}catch(e){
+						dfd.errback(e);
+					}
+				});
+
+				a.splice(-3, 2, 100, 101);
+
+				doh.is([0, 100, 101, 3], a, "The array should end up with 0, 100, 101, 3");
+				dfd.callback(1);
+
+				return dfd;
+			},
+			tearDown: function(){
+				this.h && this.h.remove();
+			}
+		},
+		function slice(){
+			var a = new StatefulArray([0, 1, 2, 3]);
+			doh.is([1, 2], a.slice(-3, 3), "Index 1 and index 2 should be returned");
+			doh.is([1], a.slice(-3, -2), "Index 1 should be returned");
+		},
+		function concat(){
+			var a = new StatefulArray([0, 1, 2, 3]);
+			doh.is([0, 1, 2, 3], a.concat(), "concat() with empty args should end up with the same array");
+			doh.is([0, 1, 2, 3, 4, 5, 6, 7, 8], a.concat([4, 5], [6, 7, 8]), "concat() should support multiple args");
+			doh.is([0, 1, 2, 3, 4, 5, 6, 7, 8], a.concat(4, 5, [6, 7, 8]), "concat() should non-array values");
+		},
+		function isInstanceOf(){
+			var a = new StatefulArray();
+			doh.t(a.isInstanceOf(Stateful), "StatefulArray should be a subclass of Stateful");
+			doh.t(a.isInstanceOf(StatefulArray), "StatefulArray's instance should work with isInstanceOf() call");
+		}
+	]);
+});
diff --git a/dojox/mvc/tests/doh/StatefulModelOptions.js b/dojox/mvc/tests/doh/StatefulModelOptions.js
new file mode 100644
index 0000000..4b1b052
--- /dev/null
+++ b/dojox/mvc/tests/doh/StatefulModelOptions.js
@@ -0,0 +1,23 @@
+define([
+	"doh",
+	"dojox/mvc/StatefulModel"
+], function(doh, StatefulModel){
+	// Refers to:
+	//		http://bugs.dojotoolkit.org/ticket/15009
+	//		http://bugs.dojotoolkit.org/ticket/15012
+
+	doh.register("dojox.mvc.tests.doh.StatefulModelOptions", [
+		function createStatefulModel(){
+			var model = new StatefulModel({data: {
+				prop1 : "String",
+				prop2 : 10,
+				prop3 : void 0,
+				prop4 : null
+			}});
+			doh.is("String", model.prop1.get("value"), "prop1 should be String");
+			doh.is(10, model.prop2.get("value"), "prop2 should be 10");
+			doh.is(void 0, model.prop3.get("value"), "prop3 should be undefined");
+			doh.is(null, model.prop4.get("value"), "prop4 should be null");
+		}
+	]);
+});
diff --git a/dojox/mvc/tests/doh/StoreRefControllerTest.js b/dojox/mvc/tests/doh/StoreRefControllerTest.js
new file mode 100644
index 0000000..71e2e78
--- /dev/null
+++ b/dojox/mvc/tests/doh/StoreRefControllerTest.js
@@ -0,0 +1,221 @@
+define([
+	"doh",
+	"dojo/_base/array",
+	"dojo/_base/config",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/Deferred",
+	"dojo/store/util/QueryResults",
+	"dijit/_WidgetBase",
+	"dojox/mvc/at",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/_Container",
+	"dijit/form/TextBox",
+	"dojox/mvc/getStateful",
+    "dojox/mvc/StoreRefController",
+    "dojox/mvc/EditStoreRefListController",	
+    "dojo/store/JsonRest",
+    "dojo/store/Memory",
+    "dojo/store/Observable",
+    "dojo/when",
+	"dojox/mvc/WidgetList",
+	"dojo/text!dojox/mvc/tests/test_WidgetList_WidgetListInTemplate.html",
+	"dojo/text!dojox/mvc/tests/test_WidgetList_childTemplate.html",
+	"dojo/text!dojox/mvc/tests/test_WidgetList_childBindings.json"
+], function(doh, array, config, declare, lang, Deferred, QueryResults, _WidgetBase, at, _TemplatedMixin, _WidgetsInTemplateMixin, _Container,
+	_TextBox, getStateful, StoreRefController, EditStoreRefListController, JsonRest, Memory, Observable, when, WidgetList, template, childTemplate, childBindings){7
+    var data = {
+        "identifier": "Serial",
+        "items": [
+            {
+                "Serial"  : "A111",
+                "First"   : "Anne",
+                "Last"    : "Ackerman",
+                "Email"   : "a.a at test.com"
+            },
+            {
+                "Serial"  : "B111",
+                "First"   : "Ben",
+                "Last"    : "Beckham",
+                "Email"   : "b.b at test.com"
+            },
+            {
+                "Serial"  : "I111",
+                "First"   : "Irene",
+                "Last"    : "Ira",
+                "Email"   : "i.i at test.com"
+            },
+            {
+                "Serial"  : "J111",
+                "First"   : "John",
+                "Last"    : "Jacklin",
+                "Email"   : "j.j at test.com"
+            }
+        ]
+    };
+
+
+	ctrl = new EditStoreRefListController({
+		store : new Memory({
+			data : data
+		})
+	});
+	when(ctrl.getStore("A111"), function(value) {
+		doh.register("dojox.mvc.tests.doh.StoreRefControllerTest", [
+			function getStore(){
+				doh.is(value.Serial, "A111", "Serial should be set");
+				doh.is(value.First, "Anne", "First should be set");
+				doh.is(value.Last, "Ackerman", "Last should be set");
+				doh.is(value.Email, "a.a at test.com", "Email should be set");
+			},
+			function queryStore(){
+				when(ctrl.queryStore(), function(results) {
+					doh.is(results[0].Serial, "A111", "Serial should be set");
+					doh.is(results[0].First, "Anne", "First should be set");
+					doh.is(results[0].Last, "Ackerman", "Last should be set");
+					doh.is(results[0].Email, "a.a at test.com", "Email should be set");
+				});
+			},
+			function addStore(){
+				var newId2 = "newObj222-" + Math.random();
+				var newObj2 = {
+					"Serial" : newId2,
+					"First" : "newObj2",
+					"Last" : "newObj2 Last",
+					"Email" : "new.obj2 at test.com"
+				};
+				when(ctrl.addStore(newObj2), function(results) {
+					doh.is(results, newId2, "id should be returned");
+					when(ctrl.getStore(newId2), function(value) {
+						doh.is(value.Serial, newId2, "Serial should be set");
+						doh.is(value.First, "newObj2", "First should be set");
+						doh.is(value.Last, "newObj2 Last", "Last should be set");
+						doh.is(value.Email, "new.obj2 at test.com", "Email should be set");
+					});
+				});
+			},
+			function putStore(){
+				var newId1 = "newObj111-" + Math.random();
+				var newObj = {
+					"Serial" : newId1,
+					"First" : "newObj",
+					"Last" : "newObj Last",
+					"Email" : "new.obj at test.com"
+				};
+				when(ctrl.putStore(newObj), function(results) {
+					doh.is(results, newId1, "id should be returned");
+					when(ctrl.getStore(results), function(value) {
+						doh.is(value.Serial, newId1, "Serial should be set");
+						doh.is(value.First, "newObj", "First should be set");
+						doh.is(value.Last, "newObj Last", "Last should be set");
+						doh.is(value.Email, "new.obj at test.com", "Email should be set");
+					});
+				});
+			},
+			function removeStore(){
+				when(ctrl.queryStore(), function(results) {
+					var remObjId = results[1].Serial;
+					when(ctrl.removeStore(remObjId), function(results) {
+						doh.is(results, true, "should return true from removeStore");
+					});
+				});
+			},
+			function observableAsyncStore(){
+				var AsyncMemoryStore = declare(Memory, {});
+				for(var s in {put: 1, remove: 1, query: 1}){
+					(function(s){
+						AsyncMemoryStore.prototype[s] = function(){
+							var args = arguments,
+							 dfd = new Deferred(),
+							 _self = this;
+							setTimeout(function(){
+								dfd.resolve(Memory.prototype[s].apply(_self, args));
+							}, 500);
+							return QueryResults(dfd.promise);
+						};
+					})(s);
+				}
+				var ctrl = new EditStoreRefListController({store: Observable(new AsyncMemoryStore({idProperty: "Serial", data: data}))}),
+				 updates = [],
+				 dfd = new doh.Deferred();
+				ctrl.queryStore({Last: "Ackerman"}).observe(dfd.getTestErrback(function(object, previousIndex, newIndex){
+					updates.push(lang.delegate(object, {
+						previousIndex: previousIndex,
+						newIndex: newIndex
+					}));
+					if(updates.length == 2){
+						doh.is({
+							Serial: "D111",
+							First: "David",
+							Last: "Ackerman",
+							Email: "d.a at test.com",
+							previousIndex: -1,
+							newIndex: 1
+						}, updates[0], "The observable callback should catch the addition");
+						doh.is({
+							Serial: "A111",
+							First: "Anne",
+							Last: "Ackerman",
+							Email: "a.a at test.com",
+							previousIndex: 0,
+							newIndex: -1
+						}, updates[1], "The observable callback should catch the removal");
+						dfd.callback(1);
+					}
+				}));
+				ctrl.addStore({
+					Serial: "D111",
+					First: "David",
+					Last: "Ackerman",
+					Email: "d.a at test.com"
+				});
+				ctrl.removeStore("A111");
+				return dfd;
+			},
+			function observeJsonRest(){
+				// Test we can observe results from a store that DOES defer results.
+				var store = new JsonRest({
+					target: require.toUrl("dojo/tests/store/"),
+					put: function(o){ var dfd = new Deferred(); setTimeout(function(){ dfd.resolve(o.id); }, 500); return dfd.promise; }, // Intead of making REST call, just return the ID asynchronously
+					remove: function(){ var dfd = new Deferred(); setTimeout(function(){ dfd.resolve(true); }, 500); return dfd.promise; } // Intead of making REST call, just return true asynchronously
+				});
+
+				var ctrl = new StoreRefController({store : new Observable(store)}),
+				 dfd = new doh.Deferred(),
+				 updates = [];
+
+				ctrl.queryStore("treeTestRoot").observe(dfd.getTestErrback(function(object, previousIndex, newIndex){
+					updates.push(lang.delegate(object, {
+						previousIndex: previousIndex,
+						newIndex: newIndex
+					}));
+					if(updates.length == 2){
+						doh.is({
+							id: "node6",
+							name: "node6",
+							someProperty: "somePropertyA",
+							previousIndex: -1,
+							newIndex: 0
+						}, updates[0], "The observable callback should catch the addition");
+						doh.is({
+							id: "node4",
+							name: "node4",
+							someProperty: "somePropertyA",
+							previousIndex: 4,
+							newIndex: -1
+						}, updates[1], "The observable callback should catch the removal");
+						dfd.callback(1);
+					}
+				}));
+				ctrl.addStore({
+					id: "node6",
+					name: "node6",
+					someProperty: "somePropertyA"
+				});
+				ctrl.removeStore("node4");
+				return dfd;
+			}
+		]);
+	}); 
+});
diff --git a/dojox/mvc/tests/doh/WidgetList.js b/dojox/mvc/tests/doh/WidgetList.js
new file mode 100644
index 0000000..fe91921
--- /dev/null
+++ b/dojox/mvc/tests/doh/WidgetList.js
@@ -0,0 +1,199 @@
+define([
+	"doh",
+	"dojo/_base/array",
+	"dojo/_base/config",
+	"dojo/_base/declare",
+	"dijit/_WidgetBase",
+	"dojox/mvc/at",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/_Container",
+	"dijit/form/TextBox",
+	"dojox/mvc/getStateful",
+	"dojox/mvc/WidgetList",
+	"dojo/text!dojox/mvc/tests/test_WidgetList_WidgetListInTemplate.html",
+	"dojo/text!dojox/mvc/tests/test_WidgetList_childTemplate.html",
+	"dojo/text!dojox/mvc/tests/test_WidgetList_childBindings.json"
+], function(doh, array, config, declare, _WidgetBase, at, _TemplatedMixin, _WidgetsInTemplateMixin, _Container, _TextBox, getStateful, WidgetList, template, childTemplate, childBindings){
+	var a = getStateful([
+		{
+			Serial: "A111",
+			First: "Anne",
+			Last: "Ackerman",
+			Location: "NY",
+			Office: "1S76",
+			Email: "a.a at test.com",
+			Tel: "123-764-8237",
+			Fax: "123-764-8228"
+		},
+		{
+			Serial: "B111",
+			First: "Ben",
+			Last: "Beckham",
+			Location: "NY",
+			Office: "5N47",
+			Email: "b.b at test.com",
+			Tel: "123-764-8599",
+			Fax: "123-764-8600"
+		},
+		{
+			Serial: "C111",
+			First: "Chad",
+			Last: "Chapman",
+			Location: "CA",
+			Office: "1278",
+			Email: "c.c at test.com",
+			Tel: "408-764-8237",
+			Fax: "408-764-8228"
+		}
+	]), b = getStateful([
+		{
+			Serial: "D111",
+			First: "David",
+			Last: "Durham",
+			Location: "NJ",
+			Office: "C12",
+			Email: "d.d at test.com",
+			Tel: "514-764-8237",
+			Fax: "514-764-8228"
+		},
+		{
+			Serial: "E111",
+			First: "Emma",
+			Last: "Eklof",
+			Location: "NY",
+			Office: "4N76",
+			Email: "e.e at test.com",
+			Tel: "123-764-1234",
+			Fax: "123-764-4321"
+		}
+	]);
+
+	var wl0 = new WidgetList({
+		children: getStateful(a),
+		childParams: {
+			startup: function(){
+				this.labelNode.set("value", at("rel:", "Serial"));
+				this.inputNode.set("value", at("rel:", "First"));
+				this.inherited("startup", arguments);
+			}
+		},
+		templateString: childTemplate
+	});
+	wl0.startup();
+
+	var wl1 = new WidgetList({
+		children: getStateful(a),
+		childBindings: eval("(" + childBindings + ")"),
+		templateString: childTemplate
+	});
+	wl1.startup();
+
+	doh.register("dojox.mvc.tests.doh.WidgetList", [
+		function programmaticBinding(){
+			var children = wl0.getChildren();
+			doh.is("A111", children[0].labelNode.value, "The label of index #0 should be: A111");
+			doh.is("Anne", children[0].inputNode.value, "The input of index #0 should be: Anne");
+			doh.is("B111", children[1].labelNode.value, "The label of index #1 should be: B111");
+			doh.is("Ben", children[1].inputNode.value, "The input of index #1 should be: Ben");
+			doh.is("C111", children[2].labelNode.value, "The label of index #2 should be: C111");
+			doh.is("Chad", children[2].inputNode.value, "The input of index #2 should be: Chad");
+
+			wl0.set("children", b);
+			children = wl0.getChildren();
+			doh.is("D111", children[0].labelNode.value, "The label of index #0 should be: D111");
+			doh.is("David", children[0].inputNode.value, "The input of index #0 should be: David");
+			doh.is("E111", children[1].labelNode.value, "The label of index #1 should be: E111");
+			doh.is("Emma", children[1].inputNode.value, "The input of index #1 should be: Emma");
+
+		},
+		function declarativeBinding(){
+			var children = wl1.getChildren();
+			doh.is("A111", children[0].labelNode.value, "The label of index #0 should be: A111");
+			doh.is("Anne", children[0].inputNode.value, "The input of index #0 should be: Anne");
+			doh.is("B111", children[1].labelNode.value, "The label of index #1 should be: B111");
+			doh.is("Ben", children[1].inputNode.value, "The input of index #1 should be: Ben");
+			doh.is("C111", children[2].labelNode.value, "The label of index #2 should be: C111");
+			doh.is("Chad", children[2].inputNode.value, "The input of index #2 should be: Chad");
+
+			wl1.set("children", b);
+			children = wl1.getChildren();
+			doh.is("D111", children[0].labelNode.value, "The label of index #0 should be: D111");
+			doh.is("David", children[0].inputNode.value, "The input of index #0 should be: David");
+			doh.is("E111", children[1].labelNode.value, "The label of index #1 should be: E111");
+			doh.is("Emma", children[1].inputNode.value, "The input of index #1 should be: Emma");
+		},
+		function removeAddElement(){
+			var c = getStateful(a.slice(0));
+			wl0.set("children", c);
+			wl1.set("children", c);
+
+			c.splice(1, 1);
+			var children = wl0.getChildren();
+			doh.is("C111", children[1].labelNode.value, "The label of index #1 should be: C111");
+			doh.is("Chad", children[1].inputNode.value, "The input of index #1 should be: Chad");
+			children = wl1.getChildren();
+			doh.is("C111", children[1].labelNode.value, "The label of index #1 should be: C111");
+			doh.is("Chad", children[1].inputNode.value, "The input of index #1 should be: Chad");
+
+			c.splice(1, 0, b[0], b[1]);
+			children = wl0.getChildren();
+			doh.is("D111", children[1].labelNode.value, "The label of index #1 should be: D111");
+			doh.is("David", children[1].inputNode.value, "The input of index #1 should be: David");
+			doh.is("E111", children[2].labelNode.value, "The label of index #2 should be: E111");
+			doh.is("Emma", children[2].inputNode.value, "The input of index #2 should be: Emma");
+			children = wl1.getChildren();
+			doh.is("D111", children[1].labelNode.value, "The label of index #1 should be: D111");
+			doh.is("David", children[1].inputNode.value, "The input of index #1 should be: David");
+			doh.is("E111", children[2].labelNode.value, "The label of index #2 should be: E111");
+			doh.is("Emma", children[2].inputNode.value, "The input of index #2 should be: Emma");
+		},
+		function replaceElement(){
+			wl0.set("children", a);
+			wl1.set("children", a);
+			a.set(1, b[1]);
+
+			var children = wl0.getChildren();
+			doh.is("E111", children[1].labelNode.value, "The label of index #1 should be: E111");
+			doh.is("Emma", children[1].inputNode.value, "The input of index #1 should be: Emma");
+			children = wl1.getChildren();
+			doh.is("E111", children[1].labelNode.value, "The label of index #1 should be: E111");
+			doh.is("Emma", children[1].inputNode.value, "The input of index #1 should be: Emma");
+		},
+		function wrongChildren(){
+			wl0.set("children", null);
+			var children = wl0.getChildren();
+			doh.is(0, children.length, "The widget list should be empty");
+			wl0.set("children", true);
+			children = wl0.getChildren();
+			doh.is(0, children.length, "The widget list should be empty");
+			wl0.set("children", 1);
+			children = wl0.getChildren();
+			doh.is(0, children.length, "The widget list should be empty");
+			wl0.set("children", "foo");
+			children = wl0.getChildren();
+			doh.is(0, children.length, "The widget list should be empty");
+		},
+		function objectInChildType(){
+			var data = [{idx: 0}, {idx: 1}, {idx: 2}, {idx: 3}];
+
+			declare("My.Widget", _WidgetBase, {
+				isMyWidget: true
+			});
+			declare("My.Mixin", null, {
+				isMyMixin: true
+			});
+
+			var w = new (declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {templateString: template}))({childData: data});
+			w.startup();
+
+			var simpleChildren = w.simpleWidgetList.getChildren(),
+			 simpleChildrenWithRegularDijit = w.simpleWidgetListWithRegularDijit.getChildren(),
+			 simpleChildrenWithRegularDijitInMixin = w.simpleWidgetListWithRegularDijitInMixin.getChildren()
+
+			doh.t(array.every(simpleChildren, function(child){ return child.isMyWidget && child.isMyMixin && !child.addChild && !child._setValueAttr; }), "simpleChildren should be created by My.Widget and My.Mixin");
+			doh.t(array.every(simpleChildrenWithRegularDijit, function(child){ return !child.isMyWidget && child.isMyMixin && !child.addChild && child._setValueAttr; }), "simpleChildrenWithRegularDijit should be created by dijit/form/TextBox and My.Mixin");
+			doh.t(array.every(simpleChildrenWithRegularDijitInMixin, function(child){ return child.isMyWidget && child.isMyMixin && child.addChild && !child._setValueAttr; }), "simpleChildrenWithRegularDijitInMixin should be created by My.Widget, My.Mixin and dijit/_Container");
+		}
+	]);
+});
diff --git a/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_DOMNode-search-results-repeat.html b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_DOMNode-search-results-repeat.html
new file mode 100644
index 0000000..070ab3e
--- /dev/null
+++ b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_DOMNode-search-results-repeat.html
@@ -0,0 +1,280 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Search Results Repeat Test</title>
+		<style>
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../css/app-format.css";
+		</style>
+		<script src="../../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: true, mvc: {debugBindings: true}"></script>
+		<script type="text/javascript" src="../helpers.js"></script>
+		<script type="text/javascript">
+
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dijit/registry",
+				"dojo/dom",
+				"dojo/when",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/_atBindingExtension",
+				"dojox/mvc/ListController",
+				"dojox/mvc/StatefulArray",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Repeat",
+				"dojox/mvc/parserExtension",
+				"dojo/domReady!"
+			], function(doh, parser, registry, dom, when, getStateful){
+				function runTests(){
+					// should be able to verify all of the inputs 
+				}
+
+				setDetailsContext = function(index){
+					var ctl = registry.byId("listCtl");
+					ctl.set("cursorIndex", index);
+				};
+
+				searchRecords = getStateful(
+					{
+						"Query" : "Engineers",
+						"Results" : [
+							{
+								"First"	  : "Anne",
+								"Last"	  : "Ackerman",
+								"Location": "NY",
+								"Office"  : "1S76",
+								"Email"	  : "a.a at test.com",
+								"Tel"	  : "123-764-8237",
+								"Fax"	  : "123-764-8228"
+							},
+							{
+								"First"	  : "Ben",
+								"Last"	  : "Beckham",
+								"Location": "NY",
+								"Office"  : "5N47",
+								"Email"	  : "b.b at test.com",
+								"Tel"	  : "123-764-8599",
+								"Fax"	  : "123-764-8600"
+							},
+							{
+								"First"	  : "Chad",
+								"Last"	  : "Chapman",
+								"Location": "CA",
+								"Office"  : "1278",
+								"Email"	  : "c.c at test.com",
+								"Tel"	  : "408-764-8237",
+								"Fax"	  : "408-764-8228"
+							},
+							{
+								"First"	  : "David",
+								"Last"	  : "Durham",
+								"Location": "NJ",
+								"Office"  : "C12",
+								"Email"	  : "d.d at test.com",
+								"Tel"	  : "514-764-8237",
+								"Fax"	  : "514-764-8228"
+							},
+							{
+								"First"	  : "Emma",
+								"Last"	  : "Eklof",
+								"Location": "NY",
+								"Office"  : "4N76",
+								"Email"	  : "e.e at test.com",
+								"Tel"	  : "123-764-1234",
+								"Fax"	  : "123-764-4321"
+							},
+							{
+								"First"	  : "Fred",
+								"Last"	  : "Fisher",
+								"Location": "NJ",
+								"Office"  : "V89",
+								"Email"	  : "f.f at test.com",
+								"Tel"	  : "514-764-8567",
+								"Fax"	  : "514-764-8000"
+							},
+							{
+								"First"	  : "George",
+								"Last"	  : "Garnett",
+								"Location": "NY",
+								"Office"  : "7S11",
+								"Email"	  : "gig at test.com",
+								"Tel"	  : "123-999-8599",
+								"Fax"	  : "123-999-8600"
+							},
+							{
+								"First"	  : "Hunter",
+								"Last"	  : "Huffman",
+								"Location": "CA",
+								"Office"  : "6532",
+								"Email"	  : "h.h at test.com",
+								"Tel"	  : "408-874-8237",
+								"Fax"	  : "408-874-8228"
+							},
+							{
+								"First"	  : "Irene",
+								"Last"	  : "Ira",
+								"Location": "NJ",
+								"Office"  : "F09",
+								"Email"	  : "i.i at test.com",
+								"Tel"	  : "514-764-6532",
+								"Fax"	  : "514-764-7300"
+							},
+							{
+								"First"	  : "John",
+								"Last"	  : "Jacklin",
+								"Location": "CA",
+								"Office"  : "6701",
+								"Email"	  : "j.j at test.com",
+								"Tel"	  : "408-764-1234",
+								"Fax"	  : "408-764-4321"
+							}
+						]
+					});
+
+				when(parser.parse(), function(){
+					registry.byId("listCtl").set("model", searchRecords.Results);
+					//runTests();
+					doh.register("Test values and bindings", [
+						{
+							name: "Initial",
+							runTest: function(){
+								var dfd = new doh.Deferred();
+						
+								var name1, bind1, firstInput; 
+								name1 = dom.byId("nameInput0");
+								if (name1) {
+										doh.is("Anne",name1.value,"name1.value should be set");
+								}
+
+								firstInput = dom.byId("firstInput");
+								if (firstInput) {
+										doh.is("Anne",firstInput.value,"firstInput.value should be set");
+								}
+								return dfd.callback(true);
+							}
+						},
+						{
+							name: "testBen",
+							runTest: function(){
+								var dfd = new doh.Deferred();
+								setDetailsContext(1);
+								var name1, bind1, firstInput; 
+								name1 = dom.byId("nameInput1");
+								if (name1) {
+										doh.is("Ben",name1.value,"name1.value is wrong");
+								}
+
+								firstInput = registry.byId("firstInput");
+								if (firstInput) {
+										doh.is("Ben",firstInput.value,"firstInput value is wrong");
+										firstInput.set("value","Benjamin");
+										doh.is("Benjamin",firstInput.value,"firstInput value is wrong after update");
+										doh.is("Benjamin",name1.value,"name1.get(value) is wrong after update");
+								}
+								return dfd.callback(true);
+							}
+										
+						}
+					]);
+
+					doh.run();
+					
+				});
+			});
+		</script>
+	</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<span id="listCtl"  data-dojo-type="dojox.mvc.ListController" 
+							data-dojo-props="cursorIndex: 0"></span>
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - With repeat container.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		 <div id="leftNav">
+		 </div>
+		 <div id="mainContent">
+		 <!--
+			 The group container denotes some logical grouping of widgets and also serves
+			 to establish a parent data binding context for its children.
+			 The target attribute for the outermost container obtains the binding from the
+			 "page scope" itself.
+		 -->
+	   <div> 	
+			<div id="searchBanner">Search Results for term: Engineers</div>
+
+			<!--
+				The repeat container denotes a templated UI that operates over a collection
+				of data records.
+				The UI can be customized for each iteration using properties such as
+				${this.index} for the iteration index.
+			-->
+			<div data-dojo-type="dojox/mvc/WidgetList"
+				data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				data-dojo-props="children: at('widget:listCtl', 'model')">
+				<script type="dojox/mvc/InlineTemplate">
+					<div>
+						<label class="cell" for="nameInput${indexAtStartup}">Name:</label>
+						<input class="cell" id="nameInput${indexAtStartup}" 
+							data-mvc-bindings="value: at('rel:', 'First')">
+						<button type="button" onclick="setDetailsContext('${indexAtStartup}')">Details</button>
+					</div>
+				</script>
+			</div>
+			<div class="spacer"></div>
+
+			<div data-dojo-type="dojox.mvc.Group" 
+								data-dojo-props="target: at('widget:listCtl', 'cursor')">
+				<div class="row">
+					<div style="display: inline-block;" id="detailsBanner">Details for result index: </div>
+					<span class="cell" id="indexOutput"  
+							data-mvc-bindings="innerText: at('widget:listCtl', 'cursorIndex')"></span>
+				</div>
+				<div class="row">
+					<label class="cell" for="firstInput">First Name:</label>
+					<input class="cell" id="firstInput"  
+										data-mvc-bindings="value: at('rel:', 'First')">
+				</div>
+				<div class="row">
+					<label class="cell" for="lastInput">Last Name:</label>
+					<input class="cell" id="lastInput"  
+									data-mvc-bindings="value: at('rel:', 'Last')">
+				</div>
+				<div class="row">
+					<label class="cell" for="locationInput">Location:</label>
+					<input class="cell" id="locationInput"  
+									data-mvc-bindings="value: at('rel:', 'Location')">
+				</div>
+				<div class="row">
+					<label class="cell" for="officeInput">Office:</label>
+					<input class="cell" id="officeInput"  
+									data-mvc-bindings="value: at('rel:', 'Office')">
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput"  
+									data-mvc-bindings="value: at('rel:', 'Email')">
+				</div>
+				<div class="row">
+					<label class="cell" for="telInput">Telephone:</label>
+					<input class="cell" id="telInput"  
+									data-mvc-bindings="value: at('rel:', 'Tel')">
+				</div>
+				<div class="row">
+					<label class="cell" for="faxInput">Fax:</label>
+					<input class="cell" id="faxInput"  
+								data-mvc-bindings="value: at('rel:', 'Fax')">
+				</div>
+			</div>
+		   </div>
+		 </div>
+		</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_mobile-demo.html b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_mobile-demo.html
new file mode 100644
index 0000000..49aac70
--- /dev/null
+++ b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_mobile-demo.html
@@ -0,0 +1,348 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH MVC Mobile Demo Test</title>
+		<link rel="stylesheet" type="text/css" href="../../1.7/mobile/demo/demo.css"/>
+		<style>
+			html, body{
+				height: 100%;
+				overflow: hidden;
+				position: relative;
+			}
+			.mblEdgeToEdgeList {
+				background-color: #DBDDE2;
+			}
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1, mvc: {debugBindings: 1}" src="../../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			var ctrl, listCtrl;
+			var updateView, updateModel;
+
+			require([
+				"doh/runner",
+				"dojo/_base/declare",
+				"dojo/_base/json",
+				"dojo/when",
+				"dojo/dom",
+				"dojo/store/JsonRest",
+				"dojo/store/Memory",
+				"dojox/mvc/at",
+				"dijit/registry",
+				"dojox/mobile/parser",
+				"dojox/mvc/getPlainValue",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/EditModelRefController",
+				"dojox/mvc/ListController",
+				"dojox/mvc/StoreRefController",
+				"dojox/mobile",
+				"dojox/mobile/compat",
+				"dojox/mobile/ScrollableView",
+				"dojox/mobile/Button",
+				"dojox/mobile/TextArea",
+				"dojox/mobile/TextBox",
+				"dojox/mobile/ViewController",
+				"dojox/mobile/FixedSplitter",
+				"dojox/mobile/EdgeToEdgeList",
+				"dojox/mobile/EdgeToEdgeCategory",
+				"dojox/mobile/deviceTheme",
+				"dojox/mobile/RoundRectCategory",
+				"dojox/mobile/Heading",
+				"dojox/mvc/Group",
+				"dojox/mvc/Generate",
+				"dojox/mvc/WidgetList",
+				"dojox/mvc/_InlineTemplateMixin",
+				"dojo/domReady!"
+			], function(doh, declare, djson, when, ddom, JsonRest, Memory, at, registry, parser, getPlainValue, getStateful, EditModelRefController, ListController, StoreRefController){
+				window.at = at;
+
+				ctrlClass = declare([EditModelRefController, ListController], {});
+				ctrl = new ctrlClass({sourceModel: getStateful({
+					Serial: "360324",
+					First: "John",
+					Last: "Doe",
+					Email: "jdoe at us.ibm.com",
+					ShipTo: {
+						Street: "123 Valley Rd",
+						City: "Katonah",
+						State: "NY",
+						Zip: "10536"
+					},
+					BillTo: {
+						Street: "17 Skyline Dr",
+						City: "Hawthorne",
+						State: "NY",
+						Zip: "10532"
+					}
+				})});
+				ctrl.set("cursorIndex", "ShipTo");
+
+				// used in the Generate View demo
+				var genmodel;
+				updateView = function() {
+					try {
+						genmodel = getStateful(djson.fromJson(ddom.byId("modelArea").value));
+						registry.byId("view").set("children", genmodel);
+						ddom.byId("outerModelArea").style.display = "none";
+						ddom.byId("viewArea").style.display = "";
+					}catch(err){
+						console.error("Error parsing json from model: "+err);
+					}
+				};
+
+				// used in the Generate View demo
+				updateModel = function() {
+					ddom.byId("outerModelArea").style.display = "";
+					try {
+						ddom.byId("modelArea").focus(); // hack: do this to force focus off of the textbox, bug on mobile?
+						ddom.byId("viewArea").style.display = "none";
+						registry.byId("modelArea").set("value", djson.toJson(getPlainValue(genmodel), true));
+					} catch(e) {
+						console.log(e);
+					};
+				};
+
+				var listCtrlClass = declare([StoreRefController, EditModelRefController, ListController], {
+					addEmpty: function(){
+						var modelToInsert = getStateful({
+							First: "",
+							Last: "",
+							Location: "CA",
+							Office: "",
+							Email: "",
+							Tel: "",
+							Fax: ""
+						});
+						this.model.push(modelToInsert);
+						this.set("cursor", modelToInsert);
+					}
+				});
+
+				listCtrl = new listCtrlClass({cursorIndex: 0});
+
+				parser.parse();
+				ddom.byId("wholepage").style.display = "";
+
+				when((new JsonRest({target: require.toUrl("dojox/mvc/tests/_data/mvcRepeatData.json")})).query({}), function(results){
+					listCtrl.set("store", new Memory({data: results.items}));
+					when(listCtrl.queryStore({Location: "CA"}), function(results){
+						doh.register("Ship to - Bill to Address page", [{
+							name: "Initial",
+							runTest: function(){
+								registry.byId("settings").show();
+								doh.is("360324", registry.byId("serialInput").get("value"), "Order# should be set");
+								doh.is("123 Valley Rd", registry.byId("streetInput").get("value"), "Street should be set of Ship To");
+							}
+						}, {
+							name: "TestBillTo",
+							runTest : function(){
+								ctrl.set("cursorIndex", "BillTo");
+								doh.is("17 Skyline Dr", registry.byId("streetInput").get("value"), "Street should be set of Bill To");
+							}
+						}, {
+							name: "TestReset",
+							runTest: function(){
+								var addr1 = registry.byId("streetInput");
+								addr1.set("value", "Foo");
+								doh.is("Foo", ctrl.get("Street"), "Street should be Foo");
+								ctrl.reset();
+								doh.is("17 Skyline Dr", addr1.get("value"), "Street should be set back to of Bill To");
+							}
+						}]);
+
+						doh.register("Repeat Data Binding Example page", [{
+							name: "Initial",
+							runTest: function(){
+								registry.byId("repeat").show();
+								doh.is("Chad", registry.byId("nameInput0").get("value"), "nameInput0 should be Chad");
+								doh.is("Hunter", registry.byId("nameInput1").get("value"), "nameInput1 should be Hunter");
+								doh.is("John", registry.byId("nameInput2").get("value"), "nameInput2 should be John");
+							}
+						}, {
+							name: "ChangeCursor",
+							runTest: function(){
+								listCtrl.set("cursorIndex", 1);
+								doh.is("Hunter", registry.byId("firstnameInputDetail").get("value"), "firstnameInputDetail should be Hunter");
+							}
+						}, {
+							name : "ResetAll",
+							runTest : function(){
+								var first = registry.byId("firstnameInputDetail");
+								first.set("value", "Foo");
+								doh.is("Foo", listCtrl.get("First"), "First should be Foo");
+								listCtrl.reset();
+								doh.is("Hunter", registry.byId("firstnameInputDetail").get("value"), "firstnameInputDetail should be Hunter");
+							}
+						}]);
+
+						doh.register("Simple Form Generate Example page", [{
+							name: "Initial",
+							runTest: function(){
+								registry.byId("generate").show();
+								updateView();
+								var tb0 = registry.byId("TB0");
+								doh.is("11111", tb0 && tb0.get("value"), "Serial should be 11111");
+								var tb6 = registry.byId("TB6");
+								doh.is("111-111-1111", tb6 && tb6.get("value"), "Office should be 111-111-1111");
+								tb6.set("value", "333-333-3333");
+								updateModel();
+								doh.t(ddom.byId("modelArea").value.indexOf("\"Office\": \"333-333-3333\""), "Model should be updated with newer Office phone number");
+							}
+						}]);
+
+						doh.run();
+					});
+				});
+			}); // end function
+		</script>
+	</head>
+	<body>
+		<div id="wholepage" style="display:none">
+			<div id="foo" data-dojo-type="dojox.mobile.View" selected="true">
+				<h1 data-dojo-type="dojox.mobile.Heading">Mobile MVC Demo</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Mobile MVC Views</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li id="sdb" data-dojo-type="dojox.mobile.ListItem" icon="../../1.7/mobile/demo/images/i-icon-1.png" transition="slide" moveTo="settings">
+						Simple Data Binding
+					</li>
+					<li id="rdb" data-dojo-type="dojox.mobile.ListItem" icon="../../1.7/mobile/demo/images/i-icon-2.png" transition="slide" moveTo="repeat">
+						Repeat Data Binding
+					</li>
+					<li id="sfg" data-dojo-type="dojox.mobile.ListItem" icon="../../1.7/mobile/demo/images/i-icon-3.png" transition="slide" moveTo="generate">
+						Simple Form Generate
+					</li>
+				</ul>
+			</div>
+			<div id="settings" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 id="home" data-dojo-type="dojox.mobile.Heading" back="Home" moveTo="foo">Data Binding Example</h1>
+				<form name="testForm" id="testForm">
+				<div class="field-title">Ship to - Bill to Address</div>
+					<div class="fieldset" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model')">
+						<div class="field-row">
+							<span>Order #</span>
+							<input id="serialInput" placeholder="Order #" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Serial')" />
+						</div>
+						<div class="field-row">
+							<span>Last</span>
+							<input placeholder="Last" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Last')" />
+						</div>
+						<div class="field-row">
+							<span>Email</span>
+							<input placeholder="Last" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Email')" />
+						</div>
+					</div>
+					<div class="spacer"></div>
+					<button id="shipto" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="ctrl.set('cursorIndex', 'ShipTo');">Ship To</button>
+					<button id="billto" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="ctrl.set('cursorIndex', 'BillTo');">Bill To</button>
+					<br/>
+					<div class="fieldset" id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'cursor')">
+						<div class="field-row">
+							<span>Street</span>
+							<input id="streetInput" placeholder="Street" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Street')" />
+						</div>
+						<div class="field-row">
+							<span>City</span>
+							<input placeholder="City" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'City')" />
+						</div>
+						<div class="field-row">
+							<span>State</span>
+							<input placeholder="State" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'State')" />
+						</div>
+						<div class="field-row">
+							<span>ZIP Code</span>
+							<input placeholder="ZIP Code" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Zip')" />
+						</div>
+					</div>
+					<div class="spacer"></div>
+					<button id="reset1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="ctrl.reset()">Reset</button>
+				</form>
+			</div>
+			<div id="repeat" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" back="Home" moveTo="foo">Repeat Data Binding Example</h1>
+				<form name="repeatTestForm" id="repeatTestForm">
+					<div class="field-title">Search Results</div>
+					<div class="fieldset" class="row"
+						data-dojo-type="dojox/mvc/WidgetList"
+						data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+						data-dojo-props="children: at(listCtrl, 'model')">
+						<script type="dojox/mvc/InlineTemplate">
+							<div class="row">
+								<input id="nameInput${indexAtStartup}" placeHolder="First Name" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'First')" />
+								<button id="details${indexAtStartup}" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="listCtrl.set('cursorIndex', '${indexAtStartup}')">Details</button>
+							</div>
+						</script>
+					</div>
+					<div class="spacer"></div>
+					<div id="detailsBanner">Details for selected index:</div>
+					<div class="fieldset" id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(listCtrl, 'cursor')">
+						<div class="field-row">
+							<span>First Name</span>
+							<input id="firstnameInputDetail" placeholder="First Name" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'First')" />
+						</div>
+						<div class="field-row">
+							<span>Last Name</span>
+							<input placeholder="Last Name" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Last') "/>
+						</div>
+						<div class="field-row">
+							<span>Email</span>
+							<input placeholder="Email" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Email')" />
+						</div>
+						<div class="field-row">
+							<span>Telephone</span>
+							<input placeholder="Telephone" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Tel')" />
+						</div>
+					</div>
+					<div class="spacer"></div>
+					<button id="add" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="listCtrl.addEmpty();">Add</button>
+					<button id="save" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="listCtrl.commit();">Save</button>
+					<button id="reset2" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="listCtrl.reset();">Reset</button>
+				</form>
+			</div>
+			<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" back="Home" moveTo="foo">Simple Form Generate Example</h1>
+				<div class="field-title"></div>
+					<div id="main">
+						<div id="leftNav"></div>
+						<div id="mainContent" class="generate-maincontent">
+							<div id="outerModelArea">
+								<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Model</h3>
+								<div class="generate-textarea-row">
+									<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+									</textarea>
+								</div>
+								<div class="fieldset">
+									<div class="spacer"></div>
+									<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
+								</div>
+							</div>
+							<div id="viewArea" style="display:none">
+								<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Generated View</h3>
+									<div class="fieldset">
+									<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping: {'String': 'dojox.mobile.TextBox'}, idNameMapping: {'String' : 'TB'}"></div>
+								</div>
+								<div class="fieldset">
+									<div class="spacer"></div>
+									<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_new_ref-set-repeat.html b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_new_ref-set-repeat.html
new file mode 100644
index 0000000..fd3e554
--- /dev/null
+++ b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_new_ref-set-repeat.html
@@ -0,0 +1,234 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+		<style>
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../../../../dijit/tests/css/dijitTests.css";
+			@import "../../css/app-format.css";
+		</style>
+		<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+		<script src="../../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: true, mvc: {debugBindings: true}"></script>
+		<script type="text/javascript" src="../helpers.js"></script>
+		<script type="text/javascript">
+			var ctrl, data1, data2, data3;
+
+			require([
+				"doh/runner",
+				"dojo/_base/array",
+				"dojo/_base/lang",
+				"dojo/when",
+				"dojo/parser",
+				"dojo/store/Memory",
+				"dijit/registry",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/ModelRefController",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Repeat",
+				"dojo/domReady!"
+			], function(doh, array, lang, when, parser, MemoryStore, registry, getStateful, ModelRefController){
+
+				function runTests(){
+					doh.register("Tests", [
+						{
+							name : "initial",
+							runTest : function() {
+								ctrl.set("model", ctrl.get("model1"));
+								doh.is("Anne1", registry.byId("nameInput0").get("value"), "nameInput0 should be Anne1");
+								doh.is("Ben1", registry.byId("nameInput1").get("value"), "nameInput1 should be Ben1 ");
+								doh.is("Chad1", registry.byId("nameInput2").get("value"), "nameInput2 should be Chad1");
+								doh.is("Anne1", registry.byId("firstnameOutput10").get("value"), "firstnameOutput10 should be Anne1");
+								doh.is("Ben1", registry.byId("firstnameOutput11").get("value"), "firstnameOutput11 should be Ben1 ");
+								doh.is("Chad1", registry.byId("firstnameOutput12").get("value"), "firstnameOutput12 should be Chad1");
+								doh.is("Anne2", registry.byId("firstnameOutput20").get("value"), "firstnameOutput20 should be Anne2");
+								doh.is("Ben2", registry.byId("firstnameOutput21").get("value"), "firstnameOutput21 should be Ben2 ");
+								doh.is("", registry.byId("firstnameOutput30").get("value"), "firstnameOutput30 should be blank");
+							}
+						}, {
+							name : "SelectModel2",
+							runTest : function() {
+								ctrl.set("model", ctrl.get("model2"));
+								doh.is("Anne2", registry.byId("nameInput0").get("value"), "nameInput0 should be Anne2");
+								doh.is("Ben2", registry.byId("nameInput1").get("value"), "nameInput1 should be Ben2 ");
+							}
+						}, {
+							name : "ChangeModel2",
+							runTest : function() {
+								registry.byId("nameInput0").set("value", "Anne2-Update");
+								doh.is("Anne2-Update", registry.byId("nameInput0").get("value"), "nameInput0 should be Anne2-Update");
+								doh.is("Ben2", registry.byId("nameInput1").get("value"), "nameInput1 should be Ben2 ");
+								doh.is("Anne2-Update", registry.byId("firstnameOutput20").get("value"), "firstnameOutput20 should be Anne2-Update");
+								doh.is("Ben2",  registry.byId("firstnameOutput21").get("value"), "firstnameOutput21 should be Ben2 ");
+							}
+						}, {
+							name : "SelectModel3",
+							runTest : function() {
+								ctrl.set("model", ctrl.get("model3"));
+								doh.is("", registry.byId("nameInput0").get("value"), "nameInput0 should be blank");
+							}
+						}, {
+							name : "ChangeModel3",
+							runTest : function() {
+								registry.byId("nameInput0").set("value", "Anne3-Update");
+								doh.is("Anne3-Update", registry.byId("nameInput0").get("value"), "nameInput0 should be Anne3-Update");
+								doh.is("Anne3-Update", registry.byId("firstnameOutput30").get("value"), "firstnameOutput30 should be Anne3-Update");
+							}
+						}, {
+							name : "UpdateData1",
+							runTest : function() {
+								var newdata = {
+									"Results": [
+										{
+											"First": "Anne1x",
+											"Last": "Ackerman1x"
+										},
+										{
+											"First": "Ben1x",
+											"Last": "Beckham1x"
+										}
+									]
+								};
+								ctrl.set("model", newdata);
+								doh.is("Anne1x", registry.byId("nameInput0").get("value"), "nameInput0 should be Anne1X");
+							}
+						}
+					]);
+
+					doh.run();
+				}
+
+				ctrl = new ModelRefController({ownProps: {model1: 1, model2: 1, model3: 1}});
+
+				when(parser.parse(), function(){
+					when((new MemoryStore({data: data1 = [
+						{
+							"Query": "Engineers1",
+							"Results": [
+								{
+									"First": "Anne1",
+									"Last": "Ackerman1"
+								},
+								{
+									"First": "Ben1",
+									"Last": "Beckham1"
+								},
+								{
+									"First": "Chad1",
+									"Last": "Chapman1"
+								}
+							]
+						}
+					]})).query(), function(data){
+						ctrl.set("model1", getStateful(data)[0]);
+						if(ctrl.get("model1") && ctrl.get("model2") && ctrl.get("model3")){ runTests(); }
+					});
+
+					when((new MemoryStore({data: data2 = [
+						{
+							"Query": "Engineers2",
+							"Results": [
+								{
+									"First": "Anne2",
+									"Last": "Ackerman2"
+								},
+								{
+									"First": "Ben2",
+									"Last": "Beckham2"
+								}
+							]
+						}
+					]}).query()), function(data){
+						ctrl.set("model2", getStateful(data)[0]);
+						if(ctrl.get("model1") && ctrl.get("model2") && ctrl.get("model3")){ runTests(); }
+					});
+
+					when((new MemoryStore({data: data3 = [
+						{
+							"Query": "Engineers3",
+							"Results": [
+								{
+									"First": "",
+									"Last": ""
+								}
+							]
+						}
+					]}).query()), function(data){
+						ctrl.set("model3", getStateful(data)[0]);
+						if(ctrl.get("model1") && ctrl.get("model2") && ctrl.get("model3")){ runTests(); }
+					});
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div id="repeatId"
+						data-dojo-type="dojox/mvc/WidgetList"
+						data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+						data-dojo-props="children: at(ctrl, 'Results')">
+						<script type="dojox/mvc/InlineTemplate">
+							<div>
+								<label class="cell" for="nameInput${indexAtStartup}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${indexAtStartup}" data-dojo-props="value: at('rel:', 'First')"/>
+							</div>
+						</script>
+					</div>
+					<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model1')">
+						<div data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Results')">
+							<span>
+								Model1 Output is ==> 
+							</span>
+							<span id="firstnameOutput10" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:0', 'First')">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput11" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:1', 'First')">
+								Name2 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput12" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:2', 'First')">
+								Name3 is "${this.value}"
+							</span>
+						</div>
+					</div>
+					<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model2')">
+						<div data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Results')">
+							<span>
+								Model2 Output is ==>
+							</span>
+							<span id="firstnameOutput20" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:0', 'First')">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput21" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:1', 'First')">
+								Name2 is "${this.value}"
+							</span>
+						</div>
+					</div>
+					<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model3')">
+						<div data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Results')">
+							<span>
+								Model3 Output is ==>
+							</span>
+							<span id="firstnameOutput30" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:0', 'First')">
+								Name1 is "${this.value}"
+							</span>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_performance_search-results-repeat.html b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_performance_search-results-repeat.html
new file mode 100644
index 0000000..fe52b83
--- /dev/null
+++ b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_performance_search-results-repeat.html
@@ -0,0 +1,324 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Search Results Repeat Test</title>
+		<style>
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../../../../dijit/tests/css/dijitTests.css";
+			@import "../../css/app-format.css";
+		</style>
+		<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+<!--  <script src="../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: true"></script> -->		
+	<script type="text/javascript">
+		require = {
+			isDebug: 1,
+			async: 1
+		};
+	</script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
+
+		<script type="text/javascript" src="../helpers.js"></script>
+		<script type="text/javascript">
+
+			require([
+				"doh/runner",
+				"dojo/parser",
+			//	"dojox/mobile/parser",
+				"dijit/registry",
+				"dojox/mvc/at",
+				"dojox/mvc/getStateful",
+				"dojo/store/Memory",
+				"dojox/mvc/EditStoreRefListController",
+				"dojo/dom",
+				"dojo/store/Observable",
+				"dijit/form/Button",
+				"dijit/form/TextBox",
+				"dojox/mvc/_atBindingExtension",
+				"dojox/mvc/ListController",
+				"dojox/mvc/StatefulArray",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/WidgetList",
+				"dojox/mvc/_InlineTemplateMixin",
+				"dojo/domReady!"
+			], function(doh, parser, registry, at, getStateful, Memory, EditStoreRefListController, dom){
+				function runTests(){
+					// should be able to verify all of the inputs 
+					doh.register("parse", [
+						{
+							name: "parse",
+							runTest: function(){
+								console.log("in parse test with maxentries ="+maxentries);
+								parser.parse(dom.byId("stateful"));
+							}
+						}
+					]);
+					doh.register("parse2", [
+											{
+												name: "parse",
+												runTest: function(){
+													ctrl = new EditStoreRefListController({store: new Memory({data: data2})});
+													ctrl.queryStore();
+													
+													console.log("in ctrl parse test with maxentries ="+maxentries);
+													parser.parse(dom.byId("ctrl"));
+												}
+											}
+										]);
+
+
+					doh.run();
+				}
+
+				window.at = at;
+
+				//parser.parse();
+
+				setDetailsContext = function(index){
+					var ctl = registry.byId("listCtl");
+					ctl.set("cursorIndex", index);
+				};
+
+				var data = [
+							{
+								id: "1",
+								Group: "Engineer",
+								First: "Anne",
+								Last: "Ackerman",
+								Location: "NY",
+								Office: "1S76",
+								Email: "a.a at test.com",
+								Tel: "123-764-8237",
+								Fax: "123-764-8228"
+							},
+							{
+								id: "2",
+								Group: "Engineer",
+								First: "Ben",
+								Last : "Beckham",
+								Location: "NY",
+								Office: "5N47",
+								Email: "b.b at test.com",
+								Tel: "123-764-8599",
+								Fax: "123-764-8600"
+							},
+							{
+								id: "3",
+								Group: "Engineer",
+								First: "Chad",
+								Last: "Chapman",
+								Location: "CA",
+								Office: "1278",
+								Email: "c.c at test.com",
+								Tel: "408-764-8237",
+								Fax: "408-764-8228"
+							},
+							{
+								id: "4",
+								Group: "Engineer",
+								First: "David",
+								Last: "Durham",
+								Location: "NJ",
+								Office: "C12",
+								Email: "d.d at test.com",
+								Tel: "514-764-8237",
+								Fax: "514-764-8228"
+							},
+							{
+								id: "5",
+								Group: "Engineer",
+								First: "Emma",
+								Last: "Eklof",
+								Location: "NY",
+								Office: "4N76",
+								Email: "e.e at test.com",
+								Tel: "123-764-1234",
+								Fax: "123-764-4321"
+							},
+							{
+								id: "6",
+								Group: "Manager",
+								First: "Fred",
+								Last: "Fisher",
+								Location: "NJ",
+								Office: "V89",
+								Email: "f.f at test.com",
+								Tel: "514-764-8567",
+								Fax: "514-764-8000"
+							},
+							{
+								id: "7",
+								Group: "Manager",
+								First: "George",
+								Last: "Garnett",
+								Location: "NY",
+								Office: "7S11",
+								Email: "gig at test.com",
+								Tel: "123-999-8599",
+								Fax: "123-999-8600"
+							},
+							{
+								id: "8",
+								Group: "Accountant",
+								First: "Hunter",
+								Last: "Huffman",
+								Location: "CA",
+								Office: "6532",
+								Email: "h.h at test.com",
+								Tel: "408-874-8237",
+								Fax: "408-874-8228"
+							},
+							{
+								id: "9",
+								Group: "Accountant",
+								First: "Irene",
+								Last: "Ira",
+								Location: "NJ",
+								Office: "F09",
+								Email: "i.i at test.com",
+								Tel: "514-764-6532",
+								Fax: "514-764-7300"
+							},
+							{
+								id: "10",
+								Group: "Accountant",
+								First: "John",
+								Last: "Jacklin",
+								Location: "CA",
+								Office: "6701",
+								Email: "j.j at test.com",
+								Tel: "408-764-1234",
+								Fax: "408-764-4321"
+							}
+						];
+						window.ctrl = null;
+						var data2 = data;
+						var currentId = 10;
+						maxentries = 100;
+						for(var a = data2, i = 0; i < maxentries; i++){
+							var d = 				{
+									id: currentId++,
+									Group: "Engineer",
+									First: "First"+currentId,
+									Last: "Last"+currentId,
+									Location: "CA",
+									Office: "6701",
+									Email: "j.j at test.com"+currentId,
+									Tel: "408-764-1234",
+									Fax: "408-764-4321"
+								};
+							data2.push(d);				
+						}
+				searchRecords = {};
+				searchRecords.Results = getStateful(data2);
+
+				runTests();
+
+			});
+		</script>
+	</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - With repeat container.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		 <div id="leftNav"></div>
+		 <div id="mainContent">
+	   	 <div  id="ctrl"> 	
+			<div id="repeat1"
+				data-dojo-type="dojox/mvc/WidgetList"
+				data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				data-dojo-props="children: at(ctrl, 'model')">
+				<script type="dojox/mvc/InlineTemplate">
+					<div class="row">
+						<label class="cell" for="xnameInput${indexAtStartup}">Name:</label>
+						<input class="cell" data-dojo-type="dijit.form.TextBox" id="xnameInput${indexAtStartup}"
+						 data-dojo-props="value: at('rel:', 'First')">
+						<button type="button" data-dojo-type="dijit.form.Button"
+						 data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${indexAtStartup}); }">Details</button>
+						<button type="button" data-dojo-type="dijit.form.Button"
+						 data-dojo-props="onClick: function(){ ctrl.addEmpty(); }">+</button>
+						<button type="button" data-dojo-type="dijit.form.Button"
+						 data-dojo-props="onClick: function(){ ctrl.remove(${indexAtStartup}); }">-</button>
+					</div>
+				</script>
+			</div>
+		</div>
+		 
+	   	 <div  id="stateful"> 	
+			<div id="searchBanner">Search Results for term: Engineers</div>
+			<div data-dojo-type="dojox/mvc/WidgetList"
+				data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				data-dojo-props="children: at('searchRecords', 'Results')">
+				<script type="dojox/mvc/InlineTemplate">
+					<div class="row">
+						<label class="cell" for="ynameInput${indexAtStartup}">Name:</label>
+						<input class="cell" data-dojo-type="dijit.form.TextBox" id="ynameInput${indexAtStartup}"
+						 data-dojo-props="value: at('rel:', 'First')">
+						<button type="button" data-dojo-type="dijit.form.Button"
+						 data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${indexAtStartup}); }">Details</button>
+						<button type="button" data-dojo-type="dijit.form.Button"
+						 data-dojo-props="onClick: function(){ ctrl.addEmpty(); }">+</button>
+						<button type="button" data-dojo-type="dijit.form.Button"
+						 data-dojo-props="onClick: function(){ ctrl.remove(${indexAtStartup}); }">-</button>
+					</div>
+				</script>
+			</div>
+			<div class="spacer"></div>
+
+			<div data-dojo-type="dojox.mvc.Group" 
+								data-dojo-props="target: at('widget:listCtl', 'cursor')">
+				<div class="row">
+					<div style="display: inline-block;" id="detailsBanner">Details for result index: </div>
+					<span class="cell" id="indexOutput" data-dojo-type="dojox.mvc.Output" 
+							data-dojo-props="value: at('widget:listCtl', 'cursorIndex')"></span>
+				</div>
+				<div class="row">
+					<label class="cell" for="firstInput">First Name:</label>
+					<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" 
+										data-dojo-props="value: at('rel:', 'First')">
+				</div>
+				<div class="row">
+					<label class="cell" for="lastInput">Last Name:</label>
+					<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Last')">
+				</div>
+				<div class="row">
+					<label class="cell" for="locationInput">Location:</label>
+					<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Location')">
+				</div>
+				<div class="row">
+					<label class="cell" for="officeInput">Office:</label>
+					<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Office')">
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Email')">
+				</div>
+				<div class="row">
+					<label class="cell" for="telInput">Telephone:</label>
+					<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Tel')">
+				</div>
+				<div class="row">
+					<label class="cell" for="faxInput">Fax:</label>
+					<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" 
+								data-dojo-props="value: at('rel:', 'Fax')">
+				</div>
+			</div>
+		   </div>
+		 </div>
+		</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_programmatic-repeat-store.html b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_programmatic-repeat-store.html
new file mode 100644
index 0000000..5410f2f
--- /dev/null
+++ b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_programmatic-repeat-store.html
@@ -0,0 +1,191 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+
+		<style>
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../../../../dijit/tests/css/dijitTests.css";
+			@import "../../css/app-format.css";
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+
+		<!-- required: dojo.js -->
+		<script src="../../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: 1, mvc: {debugBindings: 1}"></script>
+		<script type="text/javascript" src="../helpers.js"></script>
+
+		<script type="text/javascript">
+			var templateString = '<div class="row">'
+			 + '<script type="dojo/require">at: "dojox/mvc/at"<\/script>'
+			 + '<label class="cell">Name:</label>'
+			 + '<input id="${parent.id}_textbox${indexAtStartup}" class="cell" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at(\'rel:\', \'First\')"></input>'
+			 + '<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.set(\'cursorIndex\', \'${indexAtStartup}\'); }">Details</button>'
+			 + '</div>';
+
+			require([
+				"doh/runner",
+				"dojo/_base/declare",
+				"dojo/when",
+				"dojo/dom",
+				"dojo/parser",
+				"dojo/promise/all",
+				"dojo/store/JsonRest",
+				"dijit/registry",
+				"dijit/_WidgetBase",
+				"dojox/mvc/at",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/EditModelRefController",
+				"dojox/mvc/ListController",
+				"dojox/mvc/WidgetList",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojo/domReady!"
+			], function(doh, declare, when, ddom, parser, all, JsonRest, registry, _WidgetBase, at, getStateful, EditModelRefController, ListController, WidgetList){
+
+				var ctrlClass = declare([_WidgetBase, EditModelRefController, ListController], {});
+				(ctrl = (new ctrlClass({srcNodeRef: ddom.byId("detailsGroup"), cursorIndex: 0}))).startup();
+
+				(new WidgetList({templateString: templateString, children: at(ctrl, "model")}, ddom.byId("repeat2"))).startup();
+
+				when(all([parser.parse(), new JsonRest({target: require.toUrl("dojox/mvc/tests/_data/mvcRepeatData.json")}).query({})]), function(a){
+	//				ctrl.set("sourceModel", getStateful(a[1].items));
+
+					 // should be able to verify all of the inputs
+					doh.register("Check values and bindings", [
+						{
+							name: "setup",
+							runTest: function(){
+								ctrl.set("sourceModel", getStateful(a[1].items));
+							}
+						}, {
+							name: "Initial",
+							runTest: function(){
+								doh.is("Anne", registry.byId("repeat2_textbox0").value, "textbox0 should be Anne");
+								doh.is("Anne", registry.byId("firstInput").value, "firstInput should be Anne");
+							}
+						}, {
+							name: "TestBen",
+							runTest: function(){
+								ctrl.set("cursorIndex", 1);
+								doh.is("Ben", registry.byId("repeat2_textbox1").value, "textbox1 should be Ben");
+								doh.is("Ben", registry.byId("firstInput").value, "firstInput should be Ben");
+							}
+						}, {
+							name: "TestJohn",
+							runTest: function(){
+								ctrl.set("cursorIndex", 9);
+								doh.is("John", registry.byId("repeat2_textbox9").value, "textbox9 should be John");
+								doh.is("John", registry.byId("firstInput").value, "firstInput should be John");
+
+								registry.byId("firstInput").set("value", "Johnny");
+
+								doh.is("Johnny", ctrl.get("model").get(9).get("First"), "First name of the 10th entry should be changed to Johnny");
+							}
+						}, {
+							name: "TestCommitReset",
+							runTest: function(){
+								ctrl.set("cursorIndex", 8);
+
+								doh.is("Irene", registry.byId("repeat2_textbox8").value, "textbox8 should be Irene");
+								doh.is("Irene", registry.byId("firstInput").value, "firstInput should be Irene");
+
+								registry.byId("firstInput").set("value", "IreneThisUpdateShouldBeSaved");
+
+								ctrl.commit();
+
+								registry.byId("lastInput").set("value", "IraThisUpdateShouldBeReset");
+
+								ctrl.reset();
+
+								doh.is("IreneThisUpdateShouldBeSaved", registry.byId("repeat2_textbox8").value, "textbox8 should be IreneThisUpdateShouldBeSaved");
+								doh.is("IreneThisUpdateShouldBeSaved", registry.byId("firstInput").value, "firstInput should be IreneThisUpdateShouldBeSaved");
+								doh.is("Ira", registry.byId("lastInput").value, "lastInput should be Ira");
+							}
+						}
+					]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<h1 class="testTitle">doh_mvc_programmatic-repeat-store.html automated tests (non-robot)</h1>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div id="searchBanner">Search Results for term: </div>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<div>
+										<div>Programatic Repeat using my.Repeat and its templateString: </div>
+										<div id="repeat2"></div>
+									</div>
+								</td>
+								<td>
+									<div>
+										<div>Declarative Repeat using my.Repeat does not pass templateString: </div>
+										<div id="repeatId2"
+											data-dojo-type="dojox/mvc/WidgetList"
+											data-dojo-props="templateString: templateString, children: at(ctrl, 'model')"></div>
+									</div>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+					<div class="spacer"></div>
+					<div id="detailsBanner">Details for selected index:</div>
+					<div id="detailsGroup">
+						<div class="row">
+							<label class="cell" for="firstInput">First Name:</label>
+							<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="lastInput">Last Name:</label>
+							<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="locationInput">Location:</label>
+							<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Location')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="officeInput">Office:</label>
+							<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Office')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="emailInput">Email:</label>
+							<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="telInput">Telephone:</label>
+							<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Tel')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="faxInput">Fax:</label>
+							<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Fax')"></input>
+						</div>
+						<div class="row">
+						<div class="spacer"></div>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commit();}">Commit All</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset to last saved</button>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_repeat_select_cancel.html b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_repeat_select_cancel.html
new file mode 100644
index 0000000..b958c17
--- /dev/null
+++ b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_repeat_select_cancel.html
@@ -0,0 +1,379 @@
+<!DOCTYPE html>
+<html style="width:100%;height:100%;overflow:hidden;">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo Repeat Selection Test</title>
+
+	<style type="text/css">
+		@import "../../../../../dijit/themes/dijit.css";
+		@import "../../../../../dijit/themes/claro/document.css";
+		@import "../../../../../dijit/tests/css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+
+	<style>
+		.bordercontainer-nopadding .dijitContentPane, .bordercontainer-nopadding .dijitSplitContainer-dijitContentPane, .bordercontainer-nopadding .dijitBorderContainer-dijitContentPane {
+			padding: 0;
+		}
+
+		.bordercontainer-nopadding .dijitMenuBar {
+			border-width: 0 0 1px 0;
+		}
+
+		.view .dijitMenu {
+			border-width: 0;
+		}
+
+		.view .dijitMenuItemHover {
+			background-color: inherit;
+			background-image: none;
+		}
+
+		.view .dijitMenuItemSelected {
+			background-color: #abd6ff;
+			background-image: url("images/standardGradient.png");
+			background-repeat: repeat-x;
+			background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			_background-image: none;
+		}
+
+		.view td.dijitMenuItemLabel {
+			width: 100%;
+			padding: 6px;
+		}
+
+		.view td.dijitMenuItemIconCell {
+			padding: 6px;
+		}
+
+		.dijitBorderContainerNoGutter > .form {
+			padding: 6px;
+		}
+
+		.row {
+			width: 100%;
+			display: inline-block;
+			padding: 6px;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.cell {
+			width: 100%;
+			display:inline-block;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.complete {
+			text-decoration: line-through;
+		}
+	</style>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		var ViewMenuBarData, DetailMenuBarData, initialRows;
+		var selectionStatusConverter = {
+			format: function(value){
+				return this.target.uniqueId == (value || {}).uniqueId;
+			},
+			parse: function(value){
+				if(!value){ throw new Error(); } // Stop copying the new value for unchecked case
+				for(var a = this.source.inModel, i = 0; i < a.length; i++){
+					if(a[i].uniqueId == this.target.uniqueId){
+						return a[i];
+					}
+				}
+			}
+		}, priorityConverter = {
+			format: function(value){
+				return "dijitIcon dijitMenuItemIconCell " + (value <= 1 ? "dijitIconError" : "");
+			}
+		}, completeConverter = {
+			format: function(value){
+				return "dijitMenuItemLabel" + (value ? " complete" : "");
+			}
+		},subjectConverter = {
+			format: function(value){
+				return value || "(No subject)";
+			}
+		};
+
+		require([
+			"doh/runner",
+			"dojox",
+			"dojo/_base/declare",
+			"dojo/_base/lang",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/query",
+			"dojo/parser",
+			"dojo/Stateful",
+			"dojox/mvc/at",
+			"dijit/registry",
+			"dijit/Menu",
+			"dojox/mvc/getStateful",
+			"dijit/form/CheckBox",
+			"dijit/form/DateTextBox",
+			"dijit/form/Select",
+			"dijit/form/TextBox",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/Editor",
+			"dijit/MenuBar",
+			"dijit/MenuBarItem",
+			"dijit/MenuItem",
+			"dojox/mvc/_atBindingExtension",
+			"dojox/mvc/EditModelRefController",
+			"dojox/mvc/ListController",
+			"dojox/mvc/StatefulArray",
+			"dojox/mvc/Group",
+			"dojox/mvc/WidgetList",
+			"dojox/mvc/_InlineTemplateMixin"
+		], function(doh, dojox, declare, lang, ddom, domClass, query, parser, Stateful, at, registry, Menu, getStateful){
+			//window.at = at;
+
+			var uniqueIdSeq = 3;
+
+			initialRows = getStateful([
+				{
+					uniqueId: 0,
+					Completed: false,
+					Subject: "Pick up my kids",
+					Due: new Date((new Date()).getTime() + 48 * 3600000),
+					Priority: 1,
+					Description: "At the kindergarden"
+				},
+				{
+					uniqueId: 1,
+					Completed: true,
+					Subject: "Take dojox.mvc learning course",
+					Due: new Date((new Date()).getTime() + 72 * 3600000),
+					Priority: 2,
+					Description: "Need to find course material at http://dojotoolkit.org/"
+				},
+				{
+					uniqueId: 2,
+					Completed: false,
+					Subject: "Wash my car",
+					Due: new Date((new Date()).getTime() + 120 * 3600000),
+					Priority: 3,
+					Description: "Need to buy a cleaner before that"
+				}
+			]);
+
+			ViewMenuBarData = getStateful([
+				{
+					label: "New",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						var payload = getStateful({
+							uniqueId: uniqueIdSeq++,
+							Completed: false,
+							Subject: "",
+							Due: new Date(""),
+							Priority: 2,
+							Description: ""
+						});
+						ctl.inModel.unshift(payload);
+						ctl.set("cursor", payload);
+					}
+				},
+				{
+					label: "Delete",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						var idx = ctl.get("cursorIndex");
+						if(idx >= 0){
+							ctl.inModel.splice(idx, 1);
+						}
+						if(idx < ctl.inModel.get("length")){
+							ctl.set("cursorIndex", idx);
+						}
+					}
+				}
+			]);
+
+			DetailMenuBarData = getStateful([
+				{
+					label: "Cancel",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						ctl.reset();
+					}
+				}
+			]);
+
+			domClass.add(ddom.byId("loading"), "dijitDisplayNone");
+			domClass.remove(ddom.byId("main"), "dijitDisplayNone");
+			parser.parse();
+
+			doh.register("Test values and bindings", [
+				{
+					name: "Initial",
+					runTest: function(){
+						doh.t(ddom.byId("viewcheckbox0").checked, "First view row should be checked");
+						doh.t(domClass.contains(ddom.byId("viewiconimg0"), "dijitIconError"), "First view row should contain explanation mark");
+						doh.t(domClass.contains(ddom.byId("viewtext1"), "complete"), "Second view row should be marked as complete");
+						doh.is("Wash my car", ddom.byId("viewtext2").innerHTML, "Third view row should exist");
+						doh.f(ddom.byId("viewtext3"), "Fourth row shouldn't exist");
+						doh.is("Pick up my kids", ddom.byId("subject").value, "The subject field should be of the first row");
+					}
+				},
+				{
+					name: "Navigate",
+					runTest: function(){
+						ddom.byId("viewcheckbox1").click();
+						doh.is("Take dojox.mvc learning course", ddom.byId("subject").value, "The subject field should be of the second row");
+						ddom.byId("viewcheckbox2").click();
+						doh.is("3", ((query("#priority input[data-dojo-attach-point='valueNode']") || [])[0] || {}).value, "The priority field should be of the third row");
+					}
+				},
+				{
+					name: "EditToCancel",
+					runTest: function(){
+						ddom.byId("viewcheckbox0").click();
+						var completed = ddom.byId("completed");
+						completed.click();
+						var subject = registry.byId("subject");
+						subject.set("displayedValue", "Pick up my wife");
+						doh.t(domClass.contains(ddom.byId("viewtext0"), "complete"), "First view row should be marked as complete");
+						doh.is("Pick up my wife", ddom.byId("viewtext0").innerHTML, "First view row's subject should be updated");
+						registry.byId("dijit_MenuBarItem_2").onClick();
+						doh.is("Pick up my kids", subject.get("displayedValue"), "Subject should be set back to the original one");
+						doh.f(completed.checked, "Completed checkbox should be set back to unchecked");
+					}
+				},
+				{
+					name: "Delete",
+					runTest: function(){
+						registry.byId("dijit_MenuBarItem_1").onClick();
+						doh.is("Take dojox.mvc learning course", ddom.byId("subject").value, "The subject field should be of the (formerly) second row");
+						doh.f(ddom.byId("viewtext2"), "Third row shouldn't exist");
+					}
+				},
+				{
+					name: "Create",
+					runTest: function(){
+						registry.byId("dijit_MenuBarItem_0").onClick();
+						var viewtext = ddom.byId("viewtext0");
+						doh.is("(No subject)", viewtext.innerHTML, "First row's subject shouldn't be set yet");
+						var subject = registry.byId("subject");
+						subject.set("displayedValue", "Complete dojox.mvc test case");
+						doh.is("Complete dojox.mvc test case", viewtext.innerHTML, "First row's subject should be updated");
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;overflow:hidden;">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<table id="loading" style="width:100%;height:100%;" border="0" cellpadding="0" cellspacing="0">
+		<tbody>
+			<tr>
+				<td align="center">Loading...</td>
+			</tr>
+		</tbody>
+	</table>
+	<div id="main" class="dijitDisplayNone" style="width:100%;height:100%;">
+		<span id="listCtl" data-dojo-type="dojox.mvc.ListController" data-dojo-mixins="dojox.mvc.EditModelRefController"
+		 data-dojo-props="_refInModelProp: 'inModel', _refSourceModelProp: 'cursor', _refModelProp: 'model', inModel: initialRows, cursorIndex: 0"></span>
+		<div class="bordercontainer-nopadding" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: true, style: 'height: 100%; width: 100%;'">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'left', style: 'background-color: white; width: 48ex', splitter: true">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox/mvc/WidgetList"
+							data-dojo-mixins="dijit/MenuBar"
+							data-dojo-props="children: ViewMenuBarData"
+							data-mvc-child-type="dijit/MenuBarItem"
+							data-mvc-child-props="'*': at(this.target, '*')"></div>
+					</div>
+					<div class="view" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center'">
+						<table border="0" cellspacing="0" cellpadding="0">
+							<tbody data-dojo-type="dojox/mvc/WidgetList"
+								data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+								data-dojo-props="children: at('widget:listCtl', 'inModel')">
+								<script type="dojox/mvc/InlineTemplate">
+									<tr>
+										<td class="dijitMenuItemIconCell">
+											<input id="viewcheckbox${indexAtStartup}" data-dojo-type="dijit.form.CheckBox"
+											 data-dojo-props="uniqueId: at('rel:', 'uniqueId'),
+											                  checked: at('widget:listCtl', 'cursor').transform(selectionStatusConverter)">
+										</td>
+										<td class="dijitMenuItemIconCell">
+											<img id="viewiconimg${indexAtStartup}" src="../../../../../dojo/resources/blank.gif" data-dojo-type="dijit._WidgetBase"
+											 data-dojo-props="_setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Priority').direction(at.from).transform(priorityConverter)">
+										</td>
+										<td id="viewtext${indexAtStartup}" data-dojo-type="dijit._WidgetBase"
+										 data-dojo-props="Subject: at('rel:', 'Subject').direction(at.from).transform(subjectConverter),
+										                  _setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Completed').direction(at.from).transform(completeConverter),
+										                  _setSubjectAttr: {node: 'domNode', type: 'innerText'}">
+										</td>
+									</tr>
+								</script>
+							</tbody>
+						</table>
+					</div>
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', style: 'background-color: white;'">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox/mvc/WidgetList"
+							data-dojo-mixins="dijit/MenuBar"
+							data-dojo-props="children: DetailMenuBarData"
+							data-mvc-child-type="dijit/MenuBarItem"
+							data-mvc-child-props="'*': at(this.target, '*')"></div>
+					</div>
+					<div class="form" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', target: at('widget:listCtl', 'model')">
+						<div class="row">
+							<span class="cell">
+								<label for="completed">Completed:</label>
+								<input id="completed" data-dojo-type="dijit.form.CheckBox" data-dojo-props="checked: at('rel:', 'Completed')">
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="subject">Subject:</label>
+							<input class="cell" id="subject" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Subject')">
+						</div>
+						<div class="row">
+							<label class="cell" for="priority">Priority:</label>
+							<span class="cell">
+								<select id="priority" data-dojo-type="dijit.form.Select" data-dojo-props="value: at('rel:', 'Priority')">
+									<option value="1">1</option>
+									<option value="2">2</option>
+									<option value="3">3</option>
+								</select>
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="due">Due:</label>
+							<span class="cell">
+								<input id="due" data-dojo-type="dijit.form.DateTextBox"
+								 data-dojo-props="required: false, constraints: {datePattern: 'MMMM dd yyyy'}, value: at('rel:', 'Due')">
+							</span>
+						</div>
+						<div class="row">
+							<span class="cell">Description:</span>
+							<div class="cell" data-dojo-type="dijit.Editor"
+							 data-dojo-props="plugins: ['bold', 'italic', 'underline'], height: '200', value: at('rel:', 'Description')"></div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_repeat_select_manualsave.html b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_repeat_select_manualsave.html
new file mode 100644
index 0000000..fdaa09e
--- /dev/null
+++ b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_repeat_select_manualsave.html
@@ -0,0 +1,398 @@
+<!DOCTYPE html>
+<html style="width:100%;height:100%;overflow:hidden;">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo Repeat Selection Test</title>
+
+	<style type="text/css">
+		@import "../../../../../dijit/themes/dijit.css";
+		@import "../../../../../dijit/themes/claro/document.css";
+		@import "../../../../../dijit/tests/css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+
+	<style>
+		.bordercontainer-nopadding .dijitContentPane, .bordercontainer-nopadding .dijitSplitContainer-dijitContentPane, .bordercontainer-nopadding .dijitBorderContainer-dijitContentPane {
+			padding: 0;
+		}
+
+		.bordercontainer-nopadding .dijitMenuBar {
+			border-width: 0 0 1px 0;
+		}
+
+		.view .dijitMenu {
+			border-width: 0;
+		}
+
+		.view .dijitMenuItemHover {
+			background-color: inherit;
+			background-image: none;
+		}
+
+		.view .dijitMenuItemSelected {
+			background-color: #abd6ff;
+			background-image: url("images/standardGradient.png");
+			background-repeat: repeat-x;
+			background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			_background-image: none;
+		}
+
+		.view td.dijitMenuItemLabel {
+			width: 100%;
+			padding: 6px;
+		}
+
+		.view td.dijitMenuItemIconCell {
+			padding: 6px;
+		}
+
+		.dijitBorderContainerNoGutter > .form {
+			padding: 6px;
+		}
+
+		.row {
+			width: 100%;
+			display: inline-block;
+			padding: 6px;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.cell {
+			width: 100%;
+			display:inline-block;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.complete {
+			text-decoration: line-through;
+		}
+	</style>
+
+	<script type="text/javascript">
+		dojoConfig = {async: 1, isDebug: 1, mvc: {debugBindings: 1}};
+	</script>
+	<script type="text/javascript" src="../../../../../dojo/dojo.js"></script>
+
+	<script type="text/javascript">
+		var ViewMenuBarData, DetailMenuBarData, initialRows;
+		var selectionStatusConverter = {
+			format: function(value){
+				return this.target.uniqueId == (value || {}).uniqueId;
+			},
+			parse: function(value){
+				if(!value){ throw new Error(); } // Stop copying the new value for unchecked case
+				for(var a = this.source.inModel, i = 0; i < a.length; i++){
+					if(a[i].uniqueId == this.target.uniqueId){
+						return a[i];
+					}
+				}
+			}
+		}, priorityConverter = {
+			format: function(value){
+				return "dijitIcon dijitMenuItemIconCell " + (value <= 1 ? "dijitIconError" : "");
+			}
+		}, completeConverter = {
+			format: function(value){
+				return "dijitMenuItemLabel" + (value ? " complete" : "");
+			}
+		},subjectConverter = {
+			format: function(value){
+				return value || "(No subject)";
+			}
+		};
+
+		require([
+			"doh/runner",
+			"dojox",
+			"dojo/_base/declare",
+			"dojo/_base/lang",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/query",
+			"dojo/parser",
+			"dojo/Stateful",
+			"dojox/mvc/at",
+			"dijit/registry",
+			"dijit/Menu",
+			"dojox/mvc/getStateful",
+			"dijit/form/CheckBox",
+			"dijit/form/DateTextBox",
+			"dijit/form/Select",
+			"dijit/form/TextBox",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/Editor",
+			"dijit/MenuBar",
+			"dijit/MenuBarItem",
+			"dijit/MenuItem",
+			"dojox/mvc/_atBindingExtension",
+			"dojox/mvc/EditModelRefController",
+			"dojox/mvc/ListController",
+			"dojox/mvc/StatefulArray",
+			"dojox/mvc/Group",
+			"dojox/mvc/WidgetList",
+			"dojox/mvc/_InlineTemplateMixin"
+		], function(doh, dojox, declare, lang, ddom, domClass, query, parser, Stateful, at, registry, Menu, getStateful){
+
+			var uniqueIdSeq = 3;
+
+			initialRows = getStateful([
+				{
+					uniqueId: 0,
+					Completed: false,
+					Subject: "Pick up my kids",
+					Due: new Date((new Date()).getTime() + 48 * 3600000),
+					Priority: 1,
+					Description: "At the kindergarden"
+				},
+				{
+					uniqueId: 1,
+					Completed: true,
+					Subject: "Take dojox.mvc learning course",
+					Due: new Date((new Date()).getTime() + 72 * 3600000),
+					Priority: 2,
+					Description: "Need to find course material at http://dojotoolkit.org/"
+				},
+				{
+					uniqueId: 2,
+					Completed: false,
+					Subject: "Wash my car",
+					Due: new Date((new Date()).getTime() + 120 * 3600000),
+					Priority: 3,
+					Description: "Need to buy a cleaner before that"
+				}
+			]);
+
+			ViewMenuBarData = getStateful([
+				{
+					label: "New",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						var payload = getStateful({
+							uniqueId: uniqueIdSeq++,
+							Completed: false,
+							Subject: "",
+							Due: new Date(""),
+							Priority: 2,
+							Description: ""
+						});
+						ctl.inModel.unshift(payload);
+						ctl.set("cursor", payload);
+					}
+				},
+				{
+					label: "Delete",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						var idx = ctl.get("cursorIndex");
+						if(idx >= 0){
+							ctl.inModel.splice(idx, 1);
+						}
+						if(idx < ctl.inModel.get("length")){
+							ctl.set("cursorIndex", idx);
+						}
+					}
+				}
+			]);
+
+			DetailMenuBarData = getStateful([
+				{
+					label: "Save",
+					onClick: function(){
+						registry.byId("listCtl").commit();
+					}
+				},
+				{
+					label: "Cancel",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						ctl.reset();
+					}
+				}
+			]);
+
+			domClass.add(ddom.byId("loading"), "dijitDisplayNone");
+			domClass.remove(ddom.byId("main"), "dijitDisplayNone");
+			parser.parse();
+
+			doh.register("Test values and bindings", [
+				{
+					name: "Initial",
+					runTest: function(){
+						doh.t(ddom.byId("viewcheckbox0").checked, "First view row should be checked");
+						doh.t(domClass.contains(ddom.byId("viewiconimg0"), "dijitIconError"), "First view row should contain explanation mark");
+						doh.t(domClass.contains(ddom.byId("viewtext1"), "complete"), "Second view row should be marked as complete");
+						doh.is("Wash my car", ddom.byId("viewtext2").innerHTML, "Third view row should exist");
+						doh.f(ddom.byId("viewtext3"), "Fourth row shouldn't exist");
+						doh.is("Pick up my kids", ddom.byId("subject").value, "The subject field should be of the first row");
+					}
+				},
+				{
+					name: "Navigate",
+					runTest: function(){
+						ddom.byId("viewcheckbox1").click();
+						doh.is("Take dojox.mvc learning course", ddom.byId("subject").value, "The subject field should be of the second row");
+						ddom.byId("viewcheckbox2").click();
+						doh.is("3", ((query("#priority input[data-dojo-attach-point='valueNode']") || [])[0] || {}).value, "The due field should be of the third row");
+					}
+				},
+				{
+					name: "EditToCancel",
+					runTest: function(){
+						ddom.byId("viewcheckbox0").click();
+						var completed = ddom.byId("completed");
+						completed.click();
+						var subject = registry.byId("subject");
+						subject.set("displayedValue", "Pick up my wife");
+						doh.f(domClass.contains(ddom.byId("viewtext0"), "complete"), "First view row shouldn't be marked as complete yet");
+						doh.is("Pick up my kids", ddom.byId("viewtext0").innerHTML, "First view row's subject shouldn't be updated yet");
+						registry.byId("dijit_MenuBarItem_3").onClick();
+						doh.is("Pick up my kids", subject.get("displayedValue"), "Subject should be set back to the original one");
+						doh.f(completed.checked, "Completed checkbox should be set back to unchecked");
+					}
+				},
+				{
+					name: "EditToSave",
+					runTest: function(){
+						ddom.byId("viewcheckbox0").click();
+						var completed = ddom.byId("completed");
+						completed.click();
+						var subject = registry.byId("subject");
+						subject.set("displayedValue", "Pick up my wife");
+						doh.f(domClass.contains(ddom.byId("viewtext0"), "complete"), "First view row shouldn't be marked as complete yet");
+						doh.is("Pick up my kids", ddom.byId("viewtext0").innerHTML, "First view row's subject shouldn't be updated yet");
+						registry.byId("dijit_MenuBarItem_2").onClick();
+						doh.t(domClass.contains(ddom.byId("viewtext0"), "complete"), "First view row should be marked as complete");
+						doh.is("Pick up my wife", ddom.byId("viewtext0").innerHTML, "First view row's subject should be updated");
+					}
+				},
+				{
+					name: "Delete",
+					runTest: function(){
+						registry.byId("dijit_MenuBarItem_1").onClick();
+						doh.is("Take dojox.mvc learning course", ddom.byId("subject").value, "The subject field should be of the (formerly) second row");
+						doh.f(ddom.byId("viewtext2"), "Third row shouldn't exist");
+					}
+				},
+				{
+					name: "Create",
+					runTest: function(){
+						registry.byId("dijit_MenuBarItem_0").onClick();
+						var viewtext = ddom.byId("viewtext0");
+						doh.is("(No subject)", viewtext.innerHTML, "First row's subject shouldn't be set yet");
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;overflow:hidden;">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<table id="loading" style="width:100%;height:100%;" border="0" cellpadding="0" cellspacing="0">
+		<tbody>
+			<tr>
+				<td align="center">Loading...</td>
+			</tr>
+		</tbody>
+	</table>
+	<div id="main" class="dijitDisplayNone" style="width:100%;height:100%;">
+		<span id="listCtl" data-dojo-type="dojox.mvc.ListController" data-dojo-mixins="dojox.mvc.EditModelRefController"
+		 data-dojo-props="_refInModelProp: 'inModel', _refSourceModelProp: 'cursor', _refModelProp: 'model', inModel: initialRows, cursorIndex: 0, holdModelUntilCommit: true"></span>
+		<div class="bordercontainer-nopadding" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: true, style: 'height: 100%; width: 100%;'">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'left', style: 'background-color: white; width: 48ex', splitter: true">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox/mvc/WidgetList"
+							data-dojo-mixins="dijit/MenuBar"
+							data-dojo-props="children: ViewMenuBarData"
+							data-mvc-child-type="dijit/MenuBarItem"
+							data-mvc-child-props="'*': at(this.target, '*')"></div>
+					</div>
+					<div class="view" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center'">
+						<table border="0" cellspacing="0" cellpadding="0">
+							<tbody data-dojo-type="dojox/mvc/WidgetList"
+								data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+								data-dojo-props="children: at('widget:listCtl', 'inModel')">
+								<script type="dojox/mvc/InlineTemplate">
+									<tr>
+										<td class="dijitMenuItemIconCell">
+											<input id="viewcheckbox${indexAtStartup}" data-dojo-type="dijit.form.CheckBox"
+											 data-dojo-props="uniqueId: at('rel:', 'uniqueId'),
+											                  checked: at('widget:listCtl', 'cursor').transform(selectionStatusConverter)">
+										</td>
+										<td class="dijitMenuItemIconCell">
+											<img id="viewiconimg${indexAtStartup}" src="../../../../../dojo/resources/blank.gif" data-dojo-type="dijit._WidgetBase"
+											 data-dojo-props="_setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Priority').direction(at.from).transform(priorityConverter)">
+										</td>
+										<td id="viewtext${indexAtStartup}" data-dojo-type="dijit._WidgetBase"
+										 data-dojo-props="Subject: at('rel:', 'Subject').direction(at.from).transform(subjectConverter),
+										                  _setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Completed').direction(at.from).transform(completeConverter),
+										                  _setSubjectAttr: {node: 'domNode', type: 'innerText'}">
+										</td>
+									</tr>
+								</script>
+							</tbody>
+						</table>
+					</div>
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', style: 'background-color: white;'">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox/mvc/WidgetList"
+							data-dojo-mixins="dijit/MenuBar"
+							data-dojo-props="children: DetailMenuBarData"
+							data-mvc-child-type="dijit/MenuBarItem"
+							data-mvc-child-props="'*': at(this.target, '*')"></div>
+					</div>
+					<div class="form" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', target: at('widget:listCtl', 'model')">
+						<div class="row">
+							<span class="cell">
+								<label for="completed">Completed:</label>
+								<input id="completed" data-dojo-type="dijit.form.CheckBox" data-dojo-props="checked: at('rel:', 'Completed')">
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="subject">Subject:</label>
+							<input class="cell" id="subject" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Subject')">
+						</div>
+						<div class="row">
+							<label class="cell" for="priority">Priority:</label>
+							<span class="cell">
+								<select id="priority" data-dojo-type="dijit.form.Select" data-dojo-props="value: at('rel:', 'Priority')">
+									<option value="1">1</option>
+									<option value="2">2</option>
+									<option value="3">3</option>
+								</select>
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="due">Due:</label>
+							<span class="cell">
+								<input id="due" data-dojo-type="dijit.form.DateTextBox"
+								 data-dojo-props="required: false, constraints: {datePattern: 'MMMM dd yyyy'}, value: at('rel:', 'Due')">
+							</span>
+						</div>
+						<div class="row">
+							<span class="cell">Description:</span>
+							<div class="cell" data-dojo-type="dijit.Editor"
+							 data-dojo-props="plugins: ['bold', 'italic', 'underline'], height: '200', value: at('rel:', 'Description')"></div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_search-results-repeat-store.html b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_search-results-repeat-store.html
new file mode 100644
index 0000000..7e31538
--- /dev/null
+++ b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_search-results-repeat-store.html
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+
+		<style>
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../../../../dijit/tests/css/dijitTests.css";
+			@import "../../css/app-format.css";
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css">
+
+		<!-- required: dojo.js -->
+		<script src="../../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: 1, mvc: {debugBindings: 1}"></script>
+		<script type="text/javascript" src="../helpers.js"></script>
+
+		<script type="text/javascript" >
+			require([
+				"doh/runner",
+				"dojo/_base/declare",
+				"dojo/when",
+				"dojo/dom",
+				"dojo/parser",
+				"dojo/promise/all",
+				"dojo/store/JsonRest",
+				"dijit/registry",
+				"dijit/_WidgetBase",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/EditModelRefController",
+				"dojox/mvc/ListController",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojox/mvc/WidgetList",
+				"dojo/domReady!"
+			], function(doh, declare, when, ddom, parser, all, JsonRest, registry, _WidgetBase, getStateful, EditModelRefController, ListController){
+
+				var ctrlClass = declare([_WidgetBase, EditModelRefController, ListController], {});
+				(ctrl = (new ctrlClass({srcNodeRef: ddom.byId("detailsGroup"), cursorIndex: 0}))).startup();
+
+				when(all([parser.parse(), new JsonRest({target: require.toUrl("dojox/mvc/tests/_data/mvcRepeatData.json")}).query({})]), function(a){
+					ctrl.set("sourceModel", getStateful(a[1].items));
+
+					 // should be able to verify all of the inputs
+					doh.register("Check values and bindings", [
+						{
+							name: "Initial",
+							runTest: function(){
+								doh.is("Anne", registry.byId("nameInput0").value, "nameInput0 should be Anne");
+								doh.is("Anne", registry.byId("firstInput").value, "firstInput should be Anne");
+							}
+						}, {
+							name: "TestBen",
+							runTest: function(){
+								ctrl.set("cursorIndex", 1);
+								doh.is("Ben", registry.byId("nameInput1").value, "nameInput1 should be Ben");
+								doh.is("Ben", registry.byId("firstInput").value, "firstInput should be Ben");
+							}
+						}, {
+							name: "TestJohn",
+							runTest: function(){
+								ctrl.set("cursorIndex", 9);
+								doh.is("John", registry.byId("nameInput9").value, "nameInput9 should be John");
+								doh.is("John", registry.byId("firstInput").value, "firstInput should be John");
+
+								registry.byId("firstInput").set("value", "Johnny");
+
+								doh.is("Johnny", ctrl.get("model").get(9).get("First"), "First name of the 10th entry should be changed to Johnny");
+							}
+						}, {
+							name: "TestCommitReset",
+							runTest: function(){
+								ctrl.set("cursorIndex", 8);
+
+								doh.is("Irene", registry.byId("nameInput8").value, "nameInput8 should be Irene");
+								doh.is("Irene", registry.byId("firstInput").value, "firstInput should be Irene");
+
+								registry.byId("firstInput").set("value", "IreneThisUpdateShouldBeSaved");
+
+								ctrl.commit();
+
+								registry.byId("lastInput").set("value", "IraThisUpdateShouldBeReset");
+
+								ctrl.reset();
+
+								doh.is("IreneThisUpdateShouldBeSaved", registry.byId("nameInput8").value, "nameInput8 should be IreneThisUpdateShouldBeSaved");
+								doh.is("IreneThisUpdateShouldBeSaved", registry.byId("firstInput").value, "firstInput should be IreneThisUpdateShouldBeSaved");
+								doh.is("Ira", registry.byId("lastInput").value, "lastInput should be Ira");
+							}
+						}
+					]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<h1 class="testTitle">doh_mvc_programmatic-repeat-store.html automated tests (non-robot)</h1>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div id="searchBanner">Search Results for term: </div>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<div>
+										<div>Declarative Repeat using my.Repeat does not pass templateString: </div>
+										<div id="repeatId"
+											data-dojo-type="dojox/mvc/WidgetList"
+											data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+											data-dojo-props="children: at(ctrl, 'model')">
+											<script type="dojox/mvc/InlineTemplate">
+												<div class="row">
+													<label class="cell" for="nameInput${indexAtStartup}">Name:</label>
+													<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${indexAtStartup}" data-dojo-props="value: at('rel:', 'First')"/>
+													<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', '${indexAtStartup}'); }">Details</button>
+												</div>
+											</script>
+										</div>
+									</div>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+					<div class="spacer"></div>
+					<div id="detailsBanner">Details for selected index:</div>
+					<div id="detailsGroup">
+						<div class="row">
+							<label class="cell" for="firstInput">First Name:</label>
+							<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')">
+						</div>
+						<div class="row">
+							<label class="cell" for="lastInput">Last Name:</label>
+							<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')">
+						</div>
+						<div class="row">
+							<label class="cell" for="locationInput">Location:</label>
+							<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Location')">
+						</div>
+						<div class="row">
+							<label class="cell" for="officeInput">Office:</label>
+							<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Office')">
+						</div>
+						<div class="row">
+							<label class="cell" for="emailInput">Email:</label>
+							<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')">
+						</div>
+						<div class="row">
+							<label class="cell" for="telInput">Telephone:</label>
+							<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Tel')">
+						</div>
+						<div class="row">
+							<label class="cell" for="faxInput">Fax:</label>
+							<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Fax')">
+						</div>
+						<div class="row">
+						<div class="spacer"></div>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commit();}">Commit All</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset to last saved</button>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_search-results-repeat.html b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_search-results-repeat.html
new file mode 100644
index 0000000..2ff2397
--- /dev/null
+++ b/dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_search-results-repeat.html
@@ -0,0 +1,281 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Search Results Repeat Test</title>
+		<style>
+			@import "../../../../../dojo/resources/dojo.css";
+			@import "../../../../../dijit/tests/css/dijitTests.css";
+			@import "../../css/app-format.css";
+		</style>
+		<link id="themeStyles" rel="stylesheet" href="../../../../../dijit/themes/claro/claro.css"/>
+		<script src="../../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="async: true, isDebug: true, mvc: {debugBindings: true}"></script>
+		<script type="text/javascript" src="../helpers.js"></script>
+		<script type="text/javascript">
+
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dojo/when",
+				"dijit/registry",
+				"dojox/mvc/getStateful",
+				"dijit/form/Button",
+				"dijit/form/TextBox",
+				"dojox/mvc/_atBindingExtension",
+				"dojox/mvc/ListController",
+				"dojox/mvc/StatefulArray",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Templated",
+				"dojox/mvc/WidgetList",
+				"dojo/domReady!"
+			], function(doh, parser, when, registry, getStateful){
+				function runTests(){
+					// should be able to verify all of the inputs 
+					doh.register("Check initial values and bindings", [
+						{
+							name: "initial",
+							runTest: function(){
+								var name1, bind1, firstInput; 
+								name1 = registry.byId("nameInput0");
+								if (name1) {
+										doh.is("Anne",name1.value,"name1.value should be set");
+								}
+
+								firstInput = registry.byId("firstInput");
+								if (firstInput) {
+										doh.is("Anne",firstInput.value,"firstInput.value should be set");
+								}
+							}
+						}
+					]);
+
+					doh.register("select Ben", [
+						{
+							name: "testBen",
+							runTest: function(){
+								setDetailsContext(1);
+								var name1, bind1, firstInput; 
+								name1 = registry.byId("nameInput1");
+								if (name1) {
+										doh.is("Ben",name1.get("value"),"name1.get(value) is wrong");
+								}
+
+								firstInput = registry.byId("firstInput");
+								if (firstInput) {
+										doh.is("Ben",firstInput.get("value"),"firstInput value is wrong");
+										firstInput.set("value","Benjamin");
+										doh.is("Benjamin",firstInput.get("value"),"firstInput value is wrong after update");
+										doh.is("Benjamin",name1.get("value"),"name1.get(value) is wrong after update");
+								}
+							}					
+						}
+					]);
+
+					doh.run();
+				}
+
+					searchRecords = getStateful(
+						{
+							"Query" : "Engineers",
+							"Results" : [
+								{
+									"First"	  : "Anne",
+									"Last"	  : "Ackerman",
+									"Location": "NY",
+									"Office"  : "1S76",
+									"Email"	  : "a.a at test.com",
+									"Tel"	  : "123-764-8237",
+									"Fax"	  : "123-764-8228"
+								},
+								{
+									"First"	  : "Ben",
+									"Last"	  : "Beckham",
+									"Location": "NY",
+									"Office"  : "5N47",
+									"Email"	  : "b.b at test.com",
+									"Tel"	  : "123-764-8599",
+									"Fax"	  : "123-764-8600"
+								},
+								{
+									"First"	  : "Chad",
+									"Last"	  : "Chapman",
+									"Location": "CA",
+									"Office"  : "1278",
+									"Email"	  : "c.c at test.com",
+									"Tel"	  : "408-764-8237",
+									"Fax"	  : "408-764-8228"
+								},
+								{
+									"First"	  : "David",
+									"Last"	  : "Durham",
+									"Location": "NJ",
+									"Office"  : "C12",
+									"Email"	  : "d.d at test.com",
+									"Tel"	  : "514-764-8237",
+									"Fax"	  : "514-764-8228"
+								},
+								{
+									"First"	  : "Emma",
+									"Last"	  : "Eklof",
+									"Location": "NY",
+									"Office"  : "4N76",
+									"Email"	  : "e.e at test.com",
+									"Tel"	  : "123-764-1234",
+									"Fax"	  : "123-764-4321"
+								},
+								{
+									"First"	  : "Fred",
+									"Last"	  : "Fisher",
+									"Location": "NJ",
+									"Office"  : "V89",
+									"Email"	  : "f.f at test.com",
+									"Tel"	  : "514-764-8567",
+									"Fax"	  : "514-764-8000"
+								},
+								{
+									"First"	  : "George",
+									"Last"	  : "Garnett",
+									"Location": "NY",
+									"Office"  : "7S11",
+									"Email"	  : "gig at test.com",
+									"Tel"	  : "123-999-8599",
+									"Fax"	  : "123-999-8600"
+								},
+								{
+									"First"	  : "Hunter",
+									"Last"	  : "Huffman",
+									"Location": "CA",
+									"Office"  : "6532",
+									"Email"	  : "h.h at test.com",
+									"Tel"	  : "408-874-8237",
+									"Fax"	  : "408-874-8228"
+								},
+								{
+									"First"	  : "Irene",
+									"Last"	  : "Ira",
+									"Location": "NJ",
+									"Office"  : "F09",
+									"Email"	  : "i.i at test.com",
+									"Tel"	  : "514-764-6532",
+									"Fax"	  : "514-764-7300"
+								},
+								{
+									"First"	  : "John",
+									"Last"	  : "Jacklin",
+									"Location": "CA",
+									"Office"  : "6701",
+									"Email"	  : "j.j at test.com",
+									"Tel"	  : "408-764-1234",
+									"Fax"	  : "408-764-4321"
+								}
+							]
+						});
+
+				when(parser.parse(), function(){
+					setDetailsContext = function(index){
+						var ctl = registry.byId("listCtl");
+						ctl.set("cursorIndex", index);
+					};
+
+					registry.byId("listCtl").set("model", searchRecords.Results);
+					runTests();
+				});
+			});
+		</script>
+	</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<span id="listCtl"  data-dojo-type="dojox/mvc/ListController" 
+							data-dojo-props="cursorIndex: 0"></span>
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - With repeat container.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		 <div id="leftNav">
+		 </div>
+		 <div id="mainContent">
+		 <!--
+			 The group container denotes some logical grouping of widgets and also serves
+			 to establish a parent data binding context for its children.
+			 The target attribute for the outermost container obtains the binding from the
+			 "page scope" itself.
+		 -->
+	   <div> 	
+			<div id="searchBanner">Search Results for term: Engineers</div>
+
+			<!--
+				The repeat container denotes a templated UI that operates over a collection
+				of data records.
+				The UI can be customized for each iteration using properties such as
+				${this.index} for the iteration index.
+			-->
+				<div data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				 data-dojo-props="children: at('widget:listCtl', 'model')">
+					<script type="dojox/mvc/InlineTemplate">
+						<div>
+								<label class="cell" >Name:</label>
+								<input class="cell" data-dojo-type="dijit/form/TextBox" id="nameInput${indexAtStartup}" 
+										data-dojo-props="value: at('rel:', 'First')">
+								<button type="button" data-dojo-type="dijit/form/Button" 
+										data-dojo-props="onClick: function(){setDetailsContext('${indexAtStartup}');}">Details</button>
+						</div>
+					</script>
+				</div>
+
+			<div class="spacer"></div>
+
+			<div data-dojo-type="dojox.mvc.Group" 
+								data-dojo-props="target: at('widget:listCtl', 'cursor')">
+				<div class="row">
+					<div style="display: inline-block;" id="detailsBanner">Details for result index: </div>
+					<span class="cell" id="indexOutput" data-dojo-type="dojox.mvc.Output" 
+							data-dojo-props="value: at('widget:listCtl', 'cursorIndex')"></span>
+				</div>
+				<div class="row">
+					<label class="cell" for="firstInput">First Name:</label>
+					<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" 
+										data-dojo-props="value: at('rel:', 'First')">
+				</div>
+				<div class="row">
+					<label class="cell" for="lastInput">Last Name:</label>
+					<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Last')">
+				</div>
+				<div class="row">
+					<label class="cell" for="locationInput">Location:</label>
+					<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Location')">
+				</div>
+				<div class="row">
+					<label class="cell" for="officeInput">Office:</label>
+					<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Office')">
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Email')">
+				</div>
+				<div class="row">
+					<label class="cell" for="telInput">Telephone:</label>
+					<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Tel')">
+				</div>
+				<div class="row">
+					<label class="cell" for="faxInput">Fax:</label>
+					<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" 
+								data-dojo-props="value: at('rel:', 'Fax')">
+				</div>
+			</div>
+		   </div>
+		 </div>
+		</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/doh/WidgetList_tests/doh_new-mvc_label_and_totals.html b/dojox/mvc/tests/doh/WidgetList_tests/doh_new-mvc_label_and_totals.html
new file mode 100644
index 0000000..25dfc3c
--- /dev/null
+++ b/dojox/mvc/tests/doh/WidgetList_tests/doh_new-mvc_label_and_totals.html
@@ -0,0 +1,306 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC Test for dynamic label and calculating totals</title>
+		<style type="text/css">
+			@import "../../css/app-format.css";
+			@import "../../../../../dijit/themes/claro/claro.css";
+			.cell { width: 30%;  display:inline-block; }
+		</style>
+
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			var model;
+
+			require([
+				"doh/runner",
+				"dojo/dom",
+				"dojo/parser",
+				"dojo/when",
+				"dijit/registry",
+				"dojox/mvc/getStateful",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojox/mvc/WidgetList",
+				"dojox/mvc/_InlineTemplateMixin",
+				"dojox/mvc/Output"
+			], function(doh, ddom, parser, when, registry, getStateful){
+
+				// Order data
+				orderData = {
+					"Serial" : "111",
+					"First" : "",
+					"Lab" : "TEST",
+					"Last" : "last",
+					"Email" : "email",
+					"Age" : "33"
+				};
+
+				// Initial sum data
+				sumData = {
+					"one" : 1,
+					"two" : 2,
+					"three" : 3,
+					"four" : 4,
+					"total" : 10
+				};
+
+				// Initial repeat sum data
+				sumRepeatData = {
+					"list" : [
+					          {"item" : 1},
+					          {"item" : 2},
+					          {"item" : 3},
+					          {"item" : 4}
+					          ],	
+					"total" : 10
+				};
+
+				sumValuesConverter = {
+						format: function(value){
+							console.log("in sumValuesConverter format value ="+value);
+							value = value || 0;
+							return value;
+						},
+						parse: function(value){
+							console.log("in sumValuesConverter parse value ="+value);
+							recomputeTotal();
+							return value;
+						}
+				};
+
+				ageLabelConverter = {
+						format: function(value){
+							console.log("in ageLabelConverter format value ="+value);
+							if(!value){
+								return "Enter Age";
+							}else{
+								return "Enter "+value+"'s age";
+							}
+						},
+						parse: function(value){
+							console.log("in ageLabelConverter parse value ="+value);
+							return value;
+						}
+				};
+
+
+				sumRepeatValuesConverter = {
+						format: function(value){
+							console.log("in sumRepeatValuesConverter format value ="+value);
+							value = value || 0;
+							return value;
+	//						recomputeRepeatTotal();
+	//						return value;
+						},
+						parse: function(value){
+							console.log("in sumRepeatValuesConverter parse value ="+value);
+							recomputeRepeatTotal();
+							return value;
+						}
+				};
+
+				//summodel = mvc.newStatefulModel({ data : sumData });
+				summodel = getStateful(sumData );
+
+				//sumrepeatmodel = mvc.newStatefulModel({ data : sumRepeatData });
+				sumrepeatmodel = getStateful(sumRepeatData);
+
+				//model = mvc.newStatefulModel({ data : order });
+				model = getStateful(orderData);
+				
+				function recomputeTotal() {
+					require([
+					         "dijit/registry",
+					         "dojox/mvc/at"
+					         ], function(registry, at){
+									var total = 0;			
+									var wone = parseInt(registry.byId("oneInput").get("value")) || 0;
+				   					var wtwo = parseInt(registry.byId("twoInput").get("value")) || 0;
+									var wthree = parseInt(registry.byId("threeInput").get("value")) || 0;
+				   					var wfour = parseInt(registry.byId("fourInput").get("value")) || 0;
+				   					total = wone + wtwo + wthree + wfour;
+				   					var wtotal = registry.byId("totalOutput");
+				   					wtotal.set("value", total);			   					
+								});
+				}
+
+				function recomputeRepeatTotal() {
+					require([
+					         "dijit/registry",
+					         "dojox/mvc/at"
+					         ], function(registry, at){
+									var total = 0;
+									for(var i=0;i<sumrepeatmodel.list.length;i++){
+										var item = parseInt(registry.byId("input"+i).get("value")) || 0;
+										console.log("sumrepeatmodel item = "+item);
+										total = total + item;
+									}
+				   					var wtotal = registry.byId("totalrepeatOutput");
+				   					wtotal.set("value", total);			   					
+								});
+				}
+
+				when(parser.parse(), function(){
+					recomputeTotal();
+
+					doh.register("Synchronize text box and label", [{
+						name: "Check first value",
+						runTest: function(){
+							doh.is("", registry.byId("firstInput").get("value"), "First should reflect initial data");
+							doh.is("last", registry.byId("lastnameInput").get("value"), "Last should reflect initial data");
+							doh.is("email", registry.byId("emailInput").get("value"), "Email should reflect initial data");
+							doh.t(/\s*\(Enter Age\)\s*/, registry.byId("ageOutput").innerHTML, "First should reflect initial data");
+							doh.is("10", registry.byId("totalOutput").get("value"), "totalOutput should reflect initial data");
+							doh.is("10", registry.byId("totalrepeatOutput").get("value"), "totalrepeatOutput should reflect initial data");						
+						}
+					}, {
+						name: "Change first and check age label",
+						runTest: function(){
+							model.set("First", "John");
+							doh.is("John", registry.byId("firstInput").get("value"), "First should reflect initial data");
+							doh.t(/\s*\(Enter John's Age\)\s*/, registry.byId("ageOutput").innerHTML, "First should reflect initial data");
+						}
+					}, {
+						name: "Change oneInput and item 0 and check totalOutput and totalrepeatOutput",
+						runTest: function(){
+							summodel.set("one", 11);
+							doh.is("20", registry.byId("totalOutput").get("value"), "totalOutput should reflect updated value");
+							sumrepeatmodel.list[0].set("item", 211);
+							doh.is("220", registry.byId("totalrepeatOutput").get("value"), "totalrepeatOutput should reflect updated value");
+						}
+					}, {
+						name: "blank oneInput and item 0 and check totalOutput and totalrepeatOutput",
+						runTest: function(){
+							summodel.set("one", "");
+							doh.is("9", registry.byId("totalOutput").get("value"), "totalOutput should reflect updated value");
+							doh.is("0", registry.byId("oneInput").get("value"), "oneInput should reflect updated value");
+							sumrepeatmodel.list[0].set("item", "");
+							doh.is("9", registry.byId("totalrepeatOutput").get("value"), "totalrepeatOutput should reflect updated value");
+							doh.is("0", registry.byId("input0").get("value"), "input0 should reflect updated value");
+						}
+					}, {
+						name: "Check model reset",
+						setUp: function(){
+							//model.reset();
+							//summodel.reset();
+							//sumrepeatmodel.reset();
+							summodel.set(sumData);
+							sumrepeatmodel.set(sumRepeatData);
+							model.set(orderData);
+						},
+						runTest: function(){
+							doh.is("", registry.byId("firstInput").get("value"), "First should reflect initial data");
+							doh.is("last", registry.byId("lastnameInput").get("value"), "Last should reflect initial data");
+							doh.is("email", registry.byId("emailInput").get("value"), "Email should reflect initial data");
+							doh.t(/\s*\(Enter Age\)\s*/, registry.byId("ageOutput").innerHTML, "First should reflect initial data");
+							doh.is("10", registry.byId("totalOutput").get("value"), "totalOutput should reflect initial data");
+							doh.is("10", registry.byId("totalrepeatOutput").get("value"), "totalrepeatOutput should reflect initial data");						
+						}
+						
+					}]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<div id="wrapper">
+	<div id="header">
+		<div id="navigation">
+		</div>
+		<div id="headerInsert">
+			<h2>MVC Test for dynamic label and calculating totals</h2>
+		</div>
+	</div>
+	<div id="main">
+		<div id="leftNav"></div>
+		<div id="mainContent">
+		<h4>Update Age label with first name when it is set.</h4>
+		<div data-dojo-type="dojox.mvc.Group"
+			data-dojo-props="target: model">		
+			<div class="row">
+				<label class="cell" for="firstInput">Enter first name:</label>
+				<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'First')">
+				</div>
+			<div class="row">
+				<label class="cell" for="lastnameInput">Enter last name:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Last')">
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Enter email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Email')">
+			</div>
+			<div class="row">
+				<label data-dojo-type="dojox.mvc.Output" class="cell" for="ageInput" id="ageOutput"
+					data-dojo-props="value: at('rel:', 'First').direction(at.from).transform(ageLabelConverter)"></label>
+				<input class="cell" id="ageInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Age')">
+			</div>
+		</div>
+		<br/>
+		<h4>Update total when any of the fields are changed.</h4>
+		<div data-dojo-type="dojox.mvc.Group"
+			data-dojo-props="target: summodel">
+			<div class="row">
+				<label class="cell" for="oneInput">Item one:</label>
+				<input class="cell" id="oneInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'one').transform(sumValuesConverter)">
+			</div>
+			<div class="row">
+				<label class="cell" for="twoInput">Item two:</label>
+				<input class="cell" id="twoInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'two').transform(sumValuesConverter)">
+			</div>
+			<div class="row">
+				<label class="cell" for="threeInput">Item three:</label>
+				<input class="cell" id="threeInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'three').transform(sumValuesConverter)">
+			</div>
+			<div class="row">
+				<label class="cell" for="fourInput">Item four:</label>
+				<input class="cell" id="fourInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'four').transform(sumValuesConverter)">
+			</div>
+			<div class="row">
+			<label class="cell" for="totalOutput">Total:</label>
+			<div class="cell" id="totalOutput" data-dojo-type="dojox.mvc.Output" 
+				data-dojo-props="value: at('rel:', 'total')"></div>
+		</div>
+		<br/>
+		<h4>Update total when any of the fields are changed - Using a Repeat.</h4>
+		<div id="outergroupId" data-dojo-type="dojox.mvc.Group" 
+								data-dojo-props="target: sumrepeatmodel">
+			<div id="repeatId"
+				data-dojo-type="dojox/mvc/WidgetList"
+				data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				data-dojo-props="children: at('rel:', 'list')">
+				<script type="dojox/mvc/InlineTemplate">
+					<div class="row">
+						<label class="cell" for="input${indexAtStartup}">Item ${indexAtStartup}:</label>
+						<input class="cell" id="input${indexAtStartup}" data-dojo-type="dijit.form.TextBox" 
+							data-dojo-props="value: at('rel:', 'item').transform(sumRepeatValuesConverter)">
+					</div>
+				</script>
+			</div>
+			<div class="row">
+				<label class="cell" for="totalrepeatOutput">Total:</label>
+				<div class="cell" id="totalrepeatOutput" data-dojo-type="dojox.mvc.Output" 
+					data-dojo-props="value: at('rel:', 'total')"></div>
+		</div>
+	</div>
+	<br/>
+	<br/>
+	Model:
+	<button id="reset" type="button" data-dojo-type="dijit.form.Button" 
+			data-dojo-props="onClick: function(){model.set(orderData);summodel.set(sumData);sumrepeatmodel.set(sumRepeatData);}">Reset</button>
+	</div></div></div></div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/_Controller.js b/dojox/mvc/tests/doh/_Controller.js
new file mode 100644
index 0000000..42d29f2
--- /dev/null
+++ b/dojox/mvc/tests/doh/_Controller.js
@@ -0,0 +1,24 @@
+define([
+	"doh",
+	"dojo/_base/declare",
+	"dijit/registry",
+	"dijit/_WidgetBase",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"../doh/_Controller",
+	"dojo/text!../templates/_ControllerInTemplate.html"
+], function(doh, declare, registry, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _Controller, template){
+	doh.register("dojox.mvc.tests.doh._Controller", [
+		function destroyFromWidgetsInTemplate(){
+			var w = new (declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+				templateString: template
+			}))({}, document.createElement("div"));
+			w.startup();
+			var ctrl = w.controllerNode,
+			 id = ctrl.id;
+			w.destroy();
+			doh.f(registry.byId(id), "The controller should have been removed from registry along with the template widget");
+			doh.t(ctrl._destroyed, "The controller should have been marked as destroyed along with the template widget");
+		}
+	]);
+});
\ No newline at end of file
diff --git a/dojox/mvc/tests/doh/atEquals.js b/dojox/mvc/tests/doh/atEquals.js
new file mode 100644
index 0000000..6a59a9b
--- /dev/null
+++ b/dojox/mvc/tests/doh/atEquals.js
@@ -0,0 +1,34 @@
+define([
+	"doh",
+	"dojo/Stateful",
+	"dijit/_WidgetBase",
+	"dojox/mvc/at",
+	"dojox/mvc/equals"
+], function(doh, Stateful, _WidgetBase, at, equals){
+	doh.register("dojox.mvc.tests.doh.atEquals", [
+		function single(){
+			var a = [0, 1, 2],
+			 model = new Stateful({value: a}),
+			 w = new _WidgetBase({value: at(model, "value").equals(equals)});
+			w.startup();
+			model.set("value", a.slice());
+			doh.is(a, w.value, "The widget should keep the original value");
+			w.set("value", at(model, "value"));
+			var copy = a.slice();
+			model.set("value", copy);
+			doh.is(copy, w.value, "The widget should be updated with the new value");
+		},
+		function wildcard(){
+			var a = [0, 1, 2],
+			 model = new Stateful({value: a}),
+			 w = new _WidgetBase({_getPropertiesAttr: function(){ return ["value"]; }, "*": at(model, "*").equals(equals)});
+			w.startup();
+			model.set("value", a.slice());
+			doh.is(a, w.value, "The widget should keep the original value");
+			w.set("value", at(model, "value"));
+			var copy = a.slice();
+			model.set("value", copy);
+			doh.is(copy, w.value, "The widget should be updated with the new value");
+		}
+	]);
+});
diff --git a/dojox/mvc/tests/doh/doh_async_mvc_14491-input-output.html b/dojox/mvc/tests/doh/doh_async_mvc_14491-input-output.html
new file mode 100644
index 0000000..14b8512
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_async_mvc_14491-input-output.html
@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH Async Simple Input - Output Group example</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+ 		var model;
+ 
+		require([
+		'dojo/parser',
+		'dojo/when',
+       	'dojox/mvc/EditModelRefController',
+		'dojo/Stateful',
+ 		'dojox/mvc/Group',
+		'dojox/mvc/Output',
+		'dojo/parser',
+		'dijit/form/TextBox',
+		'dijit/form/Button'], function(parser, when, EditModelRefController, Stateful){
+
+			// The dojox.mvc.StatefulModel class creates a data model instance
+			// where each leaf within the data model is decorated with dojo.Stateful
+			// properties that widgets can bind to and watch for their changes.
+			//model = dojox.mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
+			model = new EditModelRefController({sourceModel: new Stateful({ "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" })});
+
+				require([
+					'doh/runner', 'dijit/dijit'
+				], function(){
+				require([
+					'dojo/domReady!'
+					], function(){
+						doh.register("parse", function() {
+							var dfd = new doh.Deferred();
+							when(dojo.parser.parse(), function(){
+								var detailsGroup = dijit.byId('detailsGroup');
+								detailsGroup.set('target', model);
+								dfd.callback(true);
+							});
+							return dfd;
+						});
+						// should be able to verify all of the inputs 
+						doh.register("check initial values and bindings", [{
+							name : "initial",
+							runTest : function() {
+								doh.is("John", dijit.byId("First").get('value'),"First should be John");
+								doh.is("John",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
+
+								doh.is("Doe", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe");
+								doh.is("Doe",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe");
+
+								doh.is("jdoe at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe at example.com");
+								doh.is("jdoe at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe at example.com");
+							}
+						}]);
+
+						doh.register("update first name", [{
+							name : "Update-First-Name",
+							runTest : function() {
+								var first1, bind1, addr1;
+								//test first relevant false
+								first1 = dijit.byId("First");
+								first1.set("value","John-update");
+								if (first1) {
+									doh.is("John-update", dijit.byId("First").get('value'),"First should be John");
+									doh.is("John-update",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
+								}
+							}
+						}]);
+						doh.register("update last name", [{
+							name : "Update-Last-Name",
+							runTest : function() {
+								var last;
+								//test first relevant false
+								last = dijit.byId("lastnameInput");
+								last.set("value","Doe-update");
+								if (last) {
+									doh.is("Doe-update", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe-update");
+									doh.is("Doe-update",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe-update");
+								}
+							}
+						}]);
+						doh.register("update last name", [{
+							name : "Update-Last-Name",
+							runTest : function() {
+								var last;
+								//test first relevant false
+								email = dijit.byId("emailInput");
+								email.set("value","jdoe-update at example.com");
+								if (email) {
+									doh.is("jdoe-update at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe-update at example.com");
+									doh.is("jdoe-update at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe-update at example.com");
+								}
+							}
+						}]);
+						doh.register("reset back to initial values and bindings", [{
+							name : "reset_test",
+							runTest : function() {
+								model.reset();
+								doh.is("John", dijit.byId("First").get('value'),"First should be John");
+								doh.is("John",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
+
+								doh.is("Doe", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe");
+								doh.is("Doe",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe");
+
+								doh.is("jdoe at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe at example.com");
+								doh.is("jdoe at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe at example.com");
+							}
+						}]);
+
+						doh.run();
+
+					});
+				});	
+		}); 
+		</script>
+</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Async Input Ouput Test</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="detailsGroup" dojoType="dojox.mvc.Group">
+					<div class="row">
+						<label class="cell" for="First">First:</label>
+						<input class="cell" id="First" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at('rel:', 'First')"></input>
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						<span data-dojo-type="dojox.mvc.Output" 
+								data-dojo-props="value: at('rel:', 'First')">
+						(first name is: ${this.value})
+						</span>
+					</div>
+				<div class="row">
+					<label class="cell" for="lastnameInput">Last:</label>
+					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at('rel:', 'Last')"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:', 'Last')">
+						(last name is: ${this.value})
+					</span>
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at('rel:', 'Email')"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:', 'Email')">
+					(email is: ${this.value})
+					</span>
+				</div>
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+				</div>
+			</div>
+		</div>
+	</body>
+
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_DOMNode-search-results-repeat.html b/dojox/mvc/tests/doh/doh_mvc_DOMNode-search-results-repeat.html
new file mode 100644
index 0000000..fb70413
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_DOMNode-search-results-repeat.html
@@ -0,0 +1,274 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Search Results Repeat Test</title>
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../css/app-format.css";
+		</style>
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: true, mvc: {debugBindings: true}"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+		<script type="text/javascript">
+
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dijit/registry",
+				"dojo/dom",
+				"dojo/when",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/_atBindingExtension",
+				"dojox/mvc/ListController",
+				"dojox/mvc/StatefulArray",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Repeat",
+				"dojox/mvc/parserExtension",
+				"dojo/domReady!"
+			], function(doh, parser, registry, dom, when, getStateful){
+				function runTests(){
+					// should be able to verify all of the inputs 
+					doh.register("Check initial values and bindings", [
+						{
+							name: "initial",
+							runTest: function(){
+								var name1, bind1, firstInput; 
+								name1 = dom.byId("nameInput0");
+								if (name1) {
+										doh.is("Anne",name1.value,"name1.value should be set");
+								}
+
+								firstInput = dom.byId("firstInput");
+								if (firstInput) {
+										doh.is("Anne",firstInput.value,"firstInput.value should be set");
+								}
+							}
+						}
+					]);
+
+					doh.register("select Ben", [
+						{
+							name: "testBen",
+							runTest: function(){
+								setDetailsContext(1);
+								var name1, bind1, firstInput; 
+								name1 = dom.byId("nameInput1");
+								if (name1) {
+										doh.is("Ben",name1.value,"name1.value is wrong");
+								}
+
+								firstInput = registry.byId("firstInput");
+								if (firstInput) {
+										doh.is("Ben",firstInput.value,"firstInput value is wrong");
+										firstInput.set("value","Benjamin");
+										doh.is("Benjamin",firstInput.value,"firstInput value is wrong after update");
+										doh.is("Benjamin",name1.value,"name1.get(value) is wrong after update");
+								}
+							}					
+						}
+					]);
+
+					doh.run();
+				}
+
+				setDetailsContext = function(index){
+					var ctl = registry.byId("listCtl");
+					ctl.set("cursorIndex", index);
+				};
+
+				searchRecords = getStateful(
+					{
+						"Query" : "Engineers",
+						"Results" : [
+							{
+								"First"	  : "Anne",
+								"Last"	  : "Ackerman",
+								"Location": "NY",
+								"Office"  : "1S76",
+								"Email"	  : "a.a at test.com",
+								"Tel"	  : "123-764-8237",
+								"Fax"	  : "123-764-8228"
+							},
+							{
+								"First"	  : "Ben",
+								"Last"	  : "Beckham",
+								"Location": "NY",
+								"Office"  : "5N47",
+								"Email"	  : "b.b at test.com",
+								"Tel"	  : "123-764-8599",
+								"Fax"	  : "123-764-8600"
+							},
+							{
+								"First"	  : "Chad",
+								"Last"	  : "Chapman",
+								"Location": "CA",
+								"Office"  : "1278",
+								"Email"	  : "c.c at test.com",
+								"Tel"	  : "408-764-8237",
+								"Fax"	  : "408-764-8228"
+							},
+							{
+								"First"	  : "David",
+								"Last"	  : "Durham",
+								"Location": "NJ",
+								"Office"  : "C12",
+								"Email"	  : "d.d at test.com",
+								"Tel"	  : "514-764-8237",
+								"Fax"	  : "514-764-8228"
+							},
+							{
+								"First"	  : "Emma",
+								"Last"	  : "Eklof",
+								"Location": "NY",
+								"Office"  : "4N76",
+								"Email"	  : "e.e at test.com",
+								"Tel"	  : "123-764-1234",
+								"Fax"	  : "123-764-4321"
+							},
+							{
+								"First"	  : "Fred",
+								"Last"	  : "Fisher",
+								"Location": "NJ",
+								"Office"  : "V89",
+								"Email"	  : "f.f at test.com",
+								"Tel"	  : "514-764-8567",
+								"Fax"	  : "514-764-8000"
+							},
+							{
+								"First"	  : "George",
+								"Last"	  : "Garnett",
+								"Location": "NY",
+								"Office"  : "7S11",
+								"Email"	  : "gig at test.com",
+								"Tel"	  : "123-999-8599",
+								"Fax"	  : "123-999-8600"
+							},
+							{
+								"First"	  : "Hunter",
+								"Last"	  : "Huffman",
+								"Location": "CA",
+								"Office"  : "6532",
+								"Email"	  : "h.h at test.com",
+								"Tel"	  : "408-874-8237",
+								"Fax"	  : "408-874-8228"
+							},
+							{
+								"First"	  : "Irene",
+								"Last"	  : "Ira",
+								"Location": "NJ",
+								"Office"  : "F09",
+								"Email"	  : "i.i at test.com",
+								"Tel"	  : "514-764-6532",
+								"Fax"	  : "514-764-7300"
+							},
+							{
+								"First"	  : "John",
+								"Last"	  : "Jacklin",
+								"Location": "CA",
+								"Office"  : "6701",
+								"Email"	  : "j.j at test.com",
+								"Tel"	  : "408-764-1234",
+								"Fax"	  : "408-764-4321"
+							}
+						]
+					});
+
+				when(parser.parse(), function(){
+					registry.byId("listCtl").set("model", searchRecords.Results);
+					runTests();
+				});
+			});
+		</script>
+	</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<span id="listCtl"  data-dojo-type="dojox.mvc.ListController" 
+							data-dojo-props="cursorIndex: 0"></span>
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - With repeat container.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		 <div id="leftNav">
+		 </div>
+		 <div id="mainContent">
+		 <!--
+			 The group container denotes some logical grouping of widgets and also serves
+			 to establish a parent data binding context for its children.
+			 The target attribute for the outermost container obtains the binding from the
+			 "page scope" itself.
+		 -->
+	   <div> 	
+			<div id="searchBanner">Search Results for term: Engineers</div>
+
+			<!--
+				The repeat container denotes a templated UI that operates over a collection
+				of data records.
+				The UI can be customized for each iteration using properties such as
+				${this.index} for the iteration index.
+			-->
+			<div data-dojo-type="dojox.mvc.Repeat" 
+						data-dojo-props="children: at('widget:listCtl', 'model')">
+				<div class="row" data-dojo-type="dojox.mvc.Group" 
+								data-dojo-props="target: at('rel:${this.index}')">
+					<label class="cell" for="nameInput${this.index}">Name:</label>
+					<input class="cell" id="nameInput${this.index}" 
+										data-mvc-bindings="value: at('rel:', 'First')">
+					<button type="button" onclick="setDetailsContext('${this.index}')">Details</button>
+				</div>
+			</div>
+			<div class="spacer"></div>
+
+			<div data-dojo-type="dojox.mvc.Group" 
+								data-dojo-props="target: at('widget:listCtl', 'cursor')">
+				<div class="row">
+					<div style="display: inline-block;" id="detailsBanner">Details for result index: </div>
+					<span class="cell" id="indexOutput"  
+							data-mvc-bindings="innerText: at('widget:listCtl', 'cursorIndex')"></span>
+				</div>
+				<div class="row">
+					<label class="cell" for="firstInput">First Name:</label>
+					<input class="cell" id="firstInput"  
+										data-mvc-bindings="value: at('rel:', 'First')">
+				</div>
+				<div class="row">
+					<label class="cell" for="lastInput">Last Name:</label>
+					<input class="cell" id="lastInput"  
+									data-mvc-bindings="value: at('rel:', 'Last')">
+				</div>
+				<div class="row">
+					<label class="cell" for="locationInput">Location:</label>
+					<input class="cell" id="locationInput"  
+									data-mvc-bindings="value: at('rel:', 'Location')">
+				</div>
+				<div class="row">
+					<label class="cell" for="officeInput">Office:</label>
+					<input class="cell" id="officeInput"  
+									data-mvc-bindings="value: at('rel:', 'Office')">
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput"  
+									data-mvc-bindings="value: at('rel:', 'Email')">
+				</div>
+				<div class="row">
+					<label class="cell" for="telInput">Telephone:</label>
+					<input class="cell" id="telInput"  
+									data-mvc-bindings="value: at('rel:', 'Tel')">
+				</div>
+				<div class="row">
+					<label class="cell" for="faxInput">Fax:</label>
+					<input class="cell" id="faxInput"  
+								data-mvc-bindings="value: at('rel:', 'Fax')">
+				</div>
+			</div>
+		   </div>
+		 </div>
+		</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_DOMNode_shipto-billto-simple.html b/dojox/mvc/tests/doh/doh_mvc_DOMNode_shipto-billto-simple.html
new file mode 100644
index 0000000..81df671
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_DOMNode_shipto-billto-simple.html
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			var ctrl, ctrlDetail, model, data;
+
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dojo/Stateful",
+				"dojo/dom",
+				"dojo/when",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/ModelRefController",
+				"dojox/mvc/Group",
+				"dojox/mvc/parserExtension",
+				"dojo/domReady!"
+			], function(doh, parser, Stateful, dom, when, getStateful, ModelRefController){
+
+				ctrl = new ModelRefController();
+				ctrlDetail = new ModelRefController();
+
+				when(parser.parse(), function(){
+					data = {
+						"Serial": "360324",
+						"First": "John",
+						"Last": "Doe",
+						"Email": "jdoe at example.com",
+						"ShipTo": {
+							"Street": "123 Valley Rd-ShipTo",
+							"City": "Katonah",
+							"State": "NY",
+							"Zip": "10536"
+						},
+						"BillTo": {
+							"Street": "17 Skyline Dr-BillTo",
+							"City": "Hawthorne",
+							"State": "NY",
+							"Zip": "10532"
+						}
+					};
+
+					ctrl.set("model", getStateful(data));
+					ctrlDetail.set("model", ctrl.model.get("ShipTo"));
+
+					doh.register("Switch between ShipTo and BillTo", [{
+						name: "Switch-to-BillTo",
+						runTest: function(){
+							ctrlDetail.set("model", ctrl.model.get("BillTo"));
+							doh.is("17 Skyline Dr-BillTo", dom.byId("streetInput").value, "Street should be of BillTo");
+							doh.is("Hawthorne", dom.byId("cityInput").value, "City should be of BillTo");
+						}
+					}, {
+						name: "Switch-to-ShipTo",
+						runTest: function(){
+							ctrlDetail.set("model", ctrl.model.get("ShipTo"));
+							doh.is("123 Valley Rd-ShipTo", dom.byId("streetInput").value, "Street should be of ShipTo");
+							doh.is("Katonah", dom.byId("cityInput").value, "City should be of ShipTo");
+						}
+					}]);
+
+					doh.run();
+				});
+			});	
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="header">
+			<div id="navigation">
+			</div>
+			<div id="headerInsert">
+				<h1>Order Shipping Details</h1>
+				<h2>Data Binding Example - Group Container.</h2>
+			</div>
+		</div>
+		<div id="main">
+		<div id="leftNav"></div>
+		<div id="mainContent">
+		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model')">
+			<div class="row">
+				<label class="cell" for="serialInput">Order #:</label>
+				<input class="cell" id="serialInput"  
+							data-mvc-bindings="value: at('rel:', 'Serial')">
+			</div>
+			<div class="row">
+				<label class="cell" for="lastnameInput">Last:</label>
+				<input class="cell" id="lastnameInput"  
+					data-mvc-bindings="value: at('rel:', 'Last')">
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput"  
+					data-mvc-bindings="value: at('rel:', 'Email')">
+			</div>
+		</div>
+		<br/>
+		<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrlDetail, 'model')">
+			<div class="row">
+				<label class="cell" for="streetInput">Street:</label>
+				<input class="cell" id="streetInput"  
+					data-mvc-bindings="value: at('rel:', 'Street')">
+			</div>
+			<div class="row">
+				<label class="cell" for="cityInput">City:</label>
+				<input class="cell" id="cityInput"  
+					data-mvc-bindings="value: at('rel:', 'City')">
+			</div>
+			<div class="row">
+				<label class="cell" for="stateInput">State:</label>
+				<input class="cell" id="stateInput"  
+					data-mvc-bindings="value: at('rel:', 'State')">
+			</div>
+			<div class="row">
+				<label class="cell" for="zipInput">Zipcode:</label>
+				<input class="cell" id="zipInput"  
+					data-mvc-bindings="value: at('rel:', 'Zip')">
+			</div>
+		</div>
+		</div></div></div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_binding-simple.html b/dojox/mvc/tests/doh/doh_mvc_binding-simple.html
new file mode 100644
index 0000000..5cdb0a2
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_binding-simple.html
@@ -0,0 +1,265 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css">
+
+		<!-- required: dojo.js -->
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: 1, parseOnLoad: 0, async: 1"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dojo/when",
+				"dojo/Stateful",
+				"dijit/registry",
+				"dijit/form/TextBox",
+				"dijit/form/NumberTextBox",
+				"dijit/form/ValidationTextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Output"
+			], function(doh, parser, when, Stateful, registry){
+				model = new Stateful({
+					First: "John",
+					Last: "Doe",
+					Email: "jdoe at example.com",
+					Num: 3
+				});
+
+				function noParse(){
+					throw new Error();
+				}
+
+				readOnlyConverter = {
+					format: function(value){
+						return value === "2" || value === "3";
+					},
+					parse: noParse
+				};
+
+				relevanceConverter = {
+					format: function(value){
+						return value !== "0";
+					},
+					parse: noParse
+				};
+
+				numValidConverter = {
+					format: function(value){
+						return value !== "3" && !(value - 0 === 1);
+					},
+					parse: noParse
+				};
+
+				requiredConverter = {
+					format: function(value){
+						return value - 0 === 4;
+					},
+					parse: noParse
+				};
+
+				lastValidConverter = {
+					format: function(value){
+						return value !== "1";
+					},
+					parse: noParse
+				};
+
+				when(parser.parse(), function(){
+					doh.register("Check values and bindings", [{
+						name: "Initial",
+						runTest: function(){
+							var first1 = registry.byId("firstnameInput");
+							doh.f(first1.get("readOnly"), "readOnly should be false");
+							doh.t(first1.get("relevant"), "relevant should be true");
+							doh.t(first1.get("valid"), "valid should be true");
+							var addr1 = registry.byId("emailInput");
+							doh.f(addr1.get("readOnly"), "readOnly should be false");
+							doh.t(addr1.get("relevant"), "relevant should be true");
+							doh.f(addr1.get("required"), "required should be false");
+							doh.t(addr1.get("valid"), "valid should be true");
+						}
+					}, {
+						name: "TestFirstUpdate",
+						runTest: function(){
+							var first1 = registry.byId("firstnameInput");
+							first1.set("value", "0");
+							doh.f(first1.get("readOnly"), "readOnly should be false");
+							doh.f(first1.get("relevant"), "relevant should be false");
+							doh.f(first1.get("required"), "required should be false");
+							doh.t(first1.get("valid"), "valid should be true");
+							first1.set("value", "1");
+							doh.f(first1.get("readOnly"), "readOnly should be false for value = 1");
+							doh.t(first1.get("relevant"), "relevant should be true for value = 1");
+							doh.f(first1.get("required"), "required should be false for value = 1");
+							doh.f(first1.get("valid"), "valid should be false for value = 1");
+							first1.set("value", "2");
+							doh.t(first1.get("relevant"), "relevant should be true for value = 2");
+							doh.f(first1.get("required"), "required should be false for value = 2");
+							doh.t(first1.get("valid"), "valid should be true for value = 2");
+							doh.t(first1.get("readOnly"), "readOnly should be true for value = 2");
+							first1.set("value", "3");
+							doh.t(first1.get("readOnly"), "readOnly should be true for value = 3");
+							doh.t(first1.get("relevant"), "relevant should be true for value = 3");
+							doh.f(first1.get("required"), "required should be false for value = 3");
+							doh.f(first1.get("valid"), "valid should be false for value = 3");
+							first1.set("value", "5");
+							doh.f(first1.get("readOnly"), "readOnly should be false for value = 5");
+							doh.t(first1.get("relevant"), "relevant should be true for value = 5");
+							doh.f(first1.get("required"), "required should be false for value = 5");
+							doh.t(first1.get("valid"), "valid should be ture for value = 5");
+						}
+					}, {
+						name: "TestNumUpdate",
+						runTest: function(){
+							var num1 = registry.byId("numInput");
+							num1.set("value", 1);
+							doh.f(num1.get("readOnly"), "readOnly should be false for value = 1");
+							doh.f(num1.get("required"), "required should be false for value = 1");
+							doh.f(num1.get("valid"), "valid should be false for value = 1");
+							num1.set("value",5);
+							doh.f(num1.get("readOnly"), "readOnly should be false for value = 5");
+							doh.f(num1.get("required"), "required should be false for value = 5");
+							doh.t(num1.get("valid"), "valid should be true for value = 5");
+						}
+					}, {
+						name: "TestNumUpdate",
+						runTest: function(){
+							var last1 = registry.byId("lastnameInput");
+							var email1 = registry.byId("emailInput");
+							last1.set("value", "5");
+							doh.f(email1.get("readOnly"), "readOnly should be false for email value = 5");
+							doh.t(email1.get("relevant"), "relevant should be true for email value = 5");
+							doh.f(email1.get("required"), "required should be false for email value = 5");
+							doh.t(email1.get("valid"), "valid should be true for email value = 5");
+							last1.set("value", "0");
+							doh.f(email1.get("readOnly"), "readOnly should be false for email value = 0");
+							doh.f(email1.get("relevant"), "relevant should be false for email value = 0");
+							doh.f(email1.get("required"), "required should be false for email value = 0");
+							doh.t(email1.get("valid"), "valid should be true for email value = 0");
+							last1.set("value", "1");
+							doh.f(email1.get("readOnly"), "readOnly should be false for email value = 1");
+							doh.t(email1.get("relevant"), "relevant should be true for email value = 1");
+							doh.f(email1.get("required"), "required should be false for email value = 1");
+							doh.f(email1.get("valid"), "valid should be false for email value = 1");
+							last1.set("value", "2");
+							doh.t(email1.get("readOnly"), "readOnly should be true for email value = 2");
+							doh.t(email1.get("relevant"), "relevant should be true for email value = 2");
+							doh.f(email1.get("required"), "required should be false for email value = 2");
+							doh.t(email1.get("valid"), "valid should be true for email value = 2");
+							last1.set("value", "3");
+							doh.t(email1.get("readOnly"), "readOnly should be true for email value = 3");
+							doh.t(email1.get("relevant"), "relevant should be true for email value = 3");
+							doh.f(email1.get("required"), "required should be false for email value = 3");
+							doh.f(email1.get("valid"), "valid should be false for email value = 3");
+							last1.set("value", "4");
+							doh.f(email1.get("readOnly"), "readOnly should be false for email value = 4");
+							doh.t(email1.get("relevant"), "relevant should be true for email value = 4");
+							doh.t(email1.get("required"), "required should be true for email value = 4");
+							doh.t(email1.get("valid"), "valid should be true for email value = 4");
+							last1.set("value","5");
+							doh.f(email1.get("readOnly"), "readOnly should be false for email value = 5");
+							doh.t(email1.get("relevant"), "relevant should be true for email value = 5");
+							doh.f(email1.get("required"), "required should be false for email value = 5");
+							doh.t(email1.get("valid"), "valid should be true for email value = 5");
+						}
+					}]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Binding Tests</h1>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav">
+				</div>
+				<div id="mainContent">
+					<h2>Bind Self Tests</h2>
+					<div class="row">
+						<label style="display:inline-block; width:100%; text-align:left;">First: Enter 0 to test for Relevant false (use Reset to re-enable)</label>
+						<label style="display:inline-block; width:100%; text-align:left;">First: Enter 1 to test for Valid false.</label>
+						<label style="display:inline-block; width:100%; text-align:left;">First: Enter 2 to test for ReadOnly false (use Reset to re-enable)</label>
+						<label style="display:inline-block; width:100%; text-align:left;">First: Enter 3 to test for ReadOnly false and Valid false (use Reset to re-enable)</label>
+					</div>
+					<div class="row">
+						<label class="cell" for="firstnameInput">First:</label>
+						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.ValidationTextBox"
+						 data-dojo-props="value: at(model, 'First'),
+										  readOnly: at(model, 'First').transform(readOnlyConverter),
+										  relevant: at(model, 'First').transform(relevanceConverter),
+										  valid: at(model, 'First').transform(numValidConverter)">
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						First name is: <span id="tout" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'First')"></span>
+					</div>
+					<div class="row">
+						<label class="cell" for="firstnameInput"></label>
+						ReadOnly is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'First').transform(readOnlyConverter)"></span>
+						Relevant is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'First').transform(relevanceConverter)"></span>
+						Valid is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'First').transform(numValidConverter)"></span>
+					</div>
+					<div class="row">
+						<label style="display:inline-block; width:100%; text-align:left;">Num: Enter 1 for Valid false</label>
+					</div>
+					<div class="row">
+						<label class="cell" for="numInput">Num:</label>
+						<input class="cell" id="numInput" data-dojo-type="dijit.form.NumberTextBox"
+						 data-dojo-props="value: at(model, 'Num'),
+										  valid: at(model, 'Num').transform(numValidConverter)">
+						Num is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'Num')"></span>
+					</div>
+					<h2>Bind Tests</h2>
+					<div class="row">
+						<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 0 to test for Relevant false for Email.</label>
+						<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 1 to test for Valid false for Email.</label>
+						<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 2 to test for ReadOnly true for Email.</label>
+						<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 3 to test for ReadOnly true and Valid false for Email.</label>
+						<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 4 to test for Required true for Email.</label>
+					</div>
+
+					<div class="row">
+						<label class="cell" for="lastnameInput">Last:</label>
+						<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at(model, 'Last')">
+						Last name is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'Last')"></span>
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label>
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.ValidationTextBox"
+						 data-dojo-props="value: at(model, 'Email'),
+										  readOnly: at(model, 'Last').transform(readOnlyConverter),
+										  relevant: at(model, 'Last').transform(relevanceConverter),
+										  required: at(model, 'Last').transform(requiredConverter),
+										  valid: at(model, 'Last').transform(numValidConverter)">
+						Email is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'Email')"></span>
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput"></label>
+						ReadOnly is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'Last').transform(readOnlyConverter)"></span>
+						Relevant is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'Last').transform(relevanceConverter)"></span>
+						Required is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'Last').transform(requiredConverter)"></span>
+						Valid is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'Last').transform(numValidConverter)"></span>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_date_test.html b/dojox/mvc/tests/doh/doh_mvc_date_test.html
new file mode 100644
index 0000000..effc72d
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_date_test.html
@@ -0,0 +1,596 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH MVC Date Binding Test</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/dom",
+				"dojo/dom-style",
+				"dojo/parser",
+				"dojo/Stateful",
+				"dojo/date/stamp",
+				"dojo/date/locale",
+				"dojox/mvc/at",
+				"dijit/registry",
+				"dijit/CalendarLite",
+				"dijit/form/Button",
+				"dijit/form/DateTextBox",
+				"dijit/form/TextBox",
+				"dojox/mvc/EditModelRefController",
+				"dojox/mvc/Output",
+				"dojo/domReady!"
+			], function(doh, ddom, domStyle, parser, Stateful, dateStamp, dateLocale, at, registry, Calendar, Button, DateTextBox, TextBox, EditModelRefController, Output){
+
+				parser.parse();
+
+				var dummyDateWid = new DateTextBox({constraints:{datePattern:"MM-dd-yyyy h:mm a", strict:true}});
+
+				// *** Test1 setup begin: ***
+				test1_ctrl = new EditModelRefController({sourceModel: new Stateful({date: new Date(1987, 7, 1, 1, 0, 0, 0)})}); // Sets the time to 1am, see dijit._CalendarList._patchDate()
+
+				var test1_cal = new Calendar({value: at(test1_ctrl, "date")}, ddom.byId("test1_cal"));
+				test1_cal.startup();
+
+				var test1_cal2 = new Calendar({value: at(test1_ctrl, "date")}, ddom.byId("test1_cal2"));
+				test1_cal2.startup();
+
+				var test1_txt2 = new TextBox({value: at(test1_ctrl, "date").transform(dummyDateWid.dateLocaleModule), constraints: dummyDateWid.constraints}, ddom.byId("test1_txt2"));
+				domStyle.set(test1_txt2.domNode, "width", "368px");
+				test1_txt2.startup();
+
+				var test1_out2 = new Output({value: at(test1_ctrl, "date").transform(dummyDateWid.dateLocaleModule), 
+					constraints: dummyDateWid.constraints}, ddom.byId("test1_output2"));
+				test1_out2.startup();
+
+				var test1_setday2 = new Button({
+					label: "Set Calendar to Sep 7 1989",
+					onClick: function() {
+						var day2 = new Date(1989, 8, 7, 1, 0, 0, 0); // Sets the time to 1am, see dijit._CalendarList._patchDate()
+						test1_cal2.set("value", day2);
+					}
+				}, ddom.byId("test1_setdate1"));
+				test1_setday2.startup();
+
+				var test1_settext2 = new Button({
+					label: "Set TextBox to May 5, 1991",
+					onClick: function() {
+						test1_txt2.set("value", dateLocale.format(new Date(1991, 4, 5, 1, 0, 0, 0), {datePattern: "MM-dd-yyyy h:mm a", selector: "date"})); // Sets the time to 1am, see dijit._CalendarList._patchDate()
+					}
+				}, ddom.byId("test1_setdate2"));
+				test1_settext2.startup();
+
+				var test1_settext3 = new Button({
+					label: "Set TextBox to Nov 6, 2011",
+					onClick: function() {
+						test1_txt2.set("value", dateLocale.format(new Date(2011, 10, 7, 1, 0, 0, 0), {datePattern: "MM-dd-yyyy h:mm a", selector: "date"}));						
+					}
+				}, ddom.byId("test1_setdate3"));
+				test1_settext3.startup();
+
+				var test1_reset2 = new Button({
+					label: "Reset Calendar back to Aug 1 1987",
+					onClick: function() {
+						test1_ctrl.reset();
+					}
+				}, ddom.byId("test1_reset2"));
+				test1_reset2.startup();
+				// *** Test1 setup end: ***
+
+				// *** Test2 setup begin: ***
+				test2_ctrl = new EditModelRefController({sourceModel: new Stateful({date: new Date(2011, 10, 6, 1, 0, 0, 0)})}); // Sets the time to 1am, see dijit._CalendarList._patchDate()
+				var test2_cal = new DateTextBox({value: at(test2_ctrl, "date")}, ddom.byId("test2_cal"));
+				test2_cal.startup();
+
+				var test2_cal2 = new DateTextBox({value: at(test2_ctrl, "date")}, ddom.byId("test2_cal2"));
+				test2_cal2.startup();
+
+				var test2_txt2 = new TextBox({value: at(test2_ctrl, "date").transform(dummyDateWid.dateLocaleModule), constraints: dummyDateWid.constraints}, ddom.byId("test2_txt2"));
+				domStyle.set(test2_txt2.domNode, "width", "368px");
+				test2_txt2.startup();
+
+				var test2_out2 = new Output({value: at(test2_ctrl, "date").transform(dummyDateWid.dateLocaleModule), 
+					constraints: dummyDateWid.constraints}, ddom.byId("test2_output2"));
+				test2_out2.startup();
+
+				var test2_setday2 = new Button({
+					label: "Set DateTextBox to Oct 28, 1993",
+					onClick: function() {
+						var day2 = dateLocale.format(new Date(1993, 9, 28, 1, 0, 0, 0), {datePattern: "MM-dd-yyyy h:mm a", selector: "date"}); // Sets the time to 1am, see dijit._CalendarList._patchDate()
+						test2_txt2.set("value", day2);
+					}
+				}, ddom.byId("test2_setdate1"));
+				test2_setday2.startup();
+
+				var test2_settext2 = new Button({
+					label: "Set DateTextBox to Oct 14 1997",
+					onClick: function() {
+						test2_txt2.set("value", dateLocale.format(new Date(1997, 9, 14, 1, 0, 0, 0), {datePattern: "MM-dd-yyyy h:mm a", selector: "date"}));						
+					}
+				}, ddom.byId("test2_setdate2"));
+				test2_settext2.startup();
+
+				var test2_reset2 = new Button({
+					label: "Reset DateTextBox back to Nov 6 2011",
+					onClick: function() {
+						test2_ctrl.reset();
+					}
+				}, ddom.byId("test2_reset2"));
+
+				var test2_settext3 = new Button({
+					label: "Set TextBox to May 5, 1991",
+					onClick: function() {
+						test2_txt2.set("value", dateLocale.format(new Date(1991, 4, 5, 1, 0, 0, 0), {datePattern: "MM-dd-yyyy h:mm a", selector: "date"}));						
+					}
+				}, ddom.byId("test2_setdate3"));
+				test2_settext3.startup();
+
+				test2_reset2.startup();
+				// *** Test2 setup end: ***
+
+				// *** Test3 setup begin: ***
+				var test3_init = new Date(2011, 7, 27, 1, 0, 0, 0); // Sets the time to 1am, see dijit._CalendarList._patchDate()
+				test3_ctrl = new EditModelRefController({sourceModel: new Stateful({date: test3_init})});
+
+				var test3_cal = new Calendar({value: at(test3_ctrl, "date")}, ddom.byId("test3_cal"));
+				test3_cal.startup();
+
+				var test3_cal2 = new DateTextBox({value: at(test3_ctrl, "date")}, ddom.byId("test3_cal2"));
+				test3_cal2.startup();
+
+				var test3_txt2 = new TextBox({
+					value: at(test3_ctrl, "date").transform(dummyDateWid.dateLocaleModule),
+					constraints: dummyDateWid.constraints,
+					disabled: true
+				}, ddom.byId("test3_txt2"));
+				domStyle.set(test3_txt2.domNode, "width", "368px");
+				test3_txt2.startup();
+
+				var test3_out2 = new Output({value: at(test3_ctrl, "date").transform(dummyDateWid.dateLocaleModule), 
+					constraints: dummyDateWid.constraints}, ddom.byId("test3_output2"));
+				test3_out2.startup();
+
+				var test3_setday2 = new Button({
+					label: "Set Calendar to Oct 14 1997",
+					onClick: function() {
+						var day2 = new Date(1997, 9, 14, 1, 0, 0, 0); // Sets the time to 1am, see dijit._CalendarList._patchDate()
+						test3_cal2.set("value", day2);
+					}
+				}, ddom.byId("test3_setdate1"));
+				test3_setday2.startup();
+
+				var test3_settext2 = new Button({
+					label: "Set TextBox to Nov 6, 2011",
+					onClick: function() {
+						test3_txt2.set("value", dateLocale.format(new Date(2011, 10, 6, 1, 0, 0, 0), {datePattern: "MM-dd-yyyy h:mm a", selector: "date"})); // Sets the time to 1am, see dijit._CalendarList._patchDate()
+					}
+				}, ddom.byId("test3_setdate2"));
+				test3_settext2.startup();
+
+				var test3_settext3 = new Button({
+					label: "Set TextBox to May 5, 1991",
+					onClick: function() {
+						var d = dateLocale.format(new Date(1991, 4, 5, 1, 0, 0, 0), {datePattern: "MM-dd-yyyy h:mm a", selector: "date"}); // Sets the time to 1am, see dijit._CalendarList._patchDate()
+						test3_txt2.set("value", d); // 5/5/1991 YYYY-MM-DDThh:mm:ss via new Date
+					}
+				}, ddom.byId("test3_setdate3"));
+				test3_settext3.startup();
+
+				var test3_reset2 = new Button({
+					label: "Reset Calendar back to Aug 27 2011",
+					onClick: function() {
+						test3_ctrl.reset();
+					}
+				}, ddom.byId("test3_reset2"));
+				test3_reset2.startup();
+				// *** Test3 setup end: ***
+
+				// *** Test4 setup begin: RegExp Test***
+				test4_ctrl = new EditModelRefController({sourceModel: new Stateful({regex: /abc/i})});
+				// *** Test4 setup end: ***
+
+				// *** Test5 setup begin: Falsy Test***
+				test5_model = new Stateful({
+					u: void 0,
+					z: 0,
+					n: null,
+					f: false,
+					s: ""
+				});
+				// *** Test5 setup end: ***
+
+				doh.register("Check initial values and bindings", [{
+					name: "Initial-test1",
+					runTest: function(){
+						doh.is("1987", registry.byId("test1_cal").get("value").getFullYear(),"test1_cal getFullYear should be 1987");
+						doh.is("7", registry.byId("test1_cal").get("value").getMonth(),"test1_cal getMonth should be 7");
+						doh.is("1", registry.byId("test1_cal").get("value").getDate(),"test1_cal getDate should be 1");
+						doh.is("1987", registry.byId("test1_cal2").get("value").getFullYear(),"test1_cal2 getFullYear should be 1987");
+						doh.is("7", registry.byId("test1_cal2").get("value").getMonth(),"test1_cal2 getMonth should be 7");
+						doh.is("1", registry.byId("test1_cal2").get("value").getDate(),"test1_cal2 getDate should be 1");
+						doh.is("08-01-1987 1:00 AM", registry.byId("test1_txt2").get("value"), "test1_txt2 should be 08-01-1987 1:00 AM");
+						doh.is("08-01-1987 1:00 AM", registry.byId("test1_output2").get("value"), "test1_output2 should be 08-01-1987 1:00 AM");
+					}
+				}, {
+					name: "Initial-test2",
+					runTest: function(){
+						doh.is("2011", registry.byId("test2_cal").get("value").getFullYear(),"test2_cal getFullYear should be 1987");
+						doh.is("10", registry.byId("test2_cal").get("value").getMonth(),"test2_cal getMonth should be 10");
+						doh.is("6", registry.byId("test2_cal").get("value").getDate(),"test2_cal getDate should be 6");
+						doh.is("2011", registry.byId("test2_cal2").get("value").getFullYear(),"test2_cal2 getFullYear should be 1987");
+						doh.is("10", registry.byId("test2_cal2").get("value").getMonth(),"test2_cal2 getMonth should be 10");
+						doh.is("6", registry.byId("test2_cal2").get("value").getDate(),"test2_cal2 getDate should be 6");
+						doh.is("11-06-2011 1:00 AM", registry.byId("test2_txt2").get("value"), "test2_txt2 should be 11-06-2011 1:00 AM");
+						doh.is("11-06-2011 1:00 AM", registry.byId("test2_output2").get("value"), "test2_output2 should be 11-06-2011 1:00 AM");
+					}
+				}, {
+					name: "Initial-test3",
+					runTest: function(){
+						doh.is("2011", registry.byId("test3_cal").get("value").getFullYear(),"test3_cal getFullYear should be 1987");
+						doh.is("7", registry.byId("test3_cal").get("value").getMonth(),"test3_cal getMonth should be 7");
+						doh.is("27", registry.byId("test3_cal").get("value").getDate(),"test3_cal getDate should be 27");
+						doh.is("2011", registry.byId("test3_cal2").get("value").getFullYear(),"test3_cal2 getFullYear should be 1987");
+						doh.is("7", registry.byId("test3_cal2").get("value").getMonth(),"test3_cal2 getMonth should be 7");
+						doh.is("27", registry.byId("test3_cal2").get("value").getDate(),"test3_cal2 getDate should be 27");
+						doh.is("08-27-2011 1:00 AM", registry.byId("test3_txt2").get("value"), "test3_txt2 should be 08-27-2011 1:00 AM");
+						doh.is("08-27-2011 1:00 AM", registry.byId("test3_output2").get("value"), "test3_output2 should be 08-27-2011 1:00 AM");
+					}
+				}]);
+
+				doh.register("Update first cal", [{
+					name: "Update-First-Cal-test1",
+					runTest: function(){
+						var day2 = new Date(1989, 8, 7, 1, 0, 0, 0); // 9/7/1989 (Sets the time to 1am, see dijit._CalendarList._patchDate())
+						registry.byId(test1_cal).set("value", day2);
+						doh.is("1989", registry.byId("test1_cal").get("value").getFullYear(),"test1_cal getFullYear should be 1989");
+						doh.is("8", registry.byId("test1_cal").get("value").getMonth(),"test1_cal getMonth should be 8");
+						doh.is("7", registry.byId("test1_cal").get("value").getDate(),"test1_cal getDate should be 7");
+						doh.is("1989", registry.byId("test1_cal2").get("value").getFullYear(),"test1_cal2 getFullYear should be 1989");
+						doh.is("8", registry.byId("test1_cal2").get("value").getMonth(),"test1_cal2 getMonth should be 8");
+						doh.is("7", registry.byId("test1_cal2").get("value").getDate(),"test1_cal2 getDate should be 7");
+						doh.is("09-07-1989 1:00 AM", registry.byId("test1_txt2").get("value"), "test1_txt2 should be 09-07-1989 1:00 AM");
+						doh.is("09-07-1989 1:00 AM", registry.byId("test1_output2").get("value"), "test1_output2 should be 09-07-1989 1:00 AM");
+					}
+				}, {
+					name: "Update-First-Cal-test2",
+					runTest: function(){
+						var day2 = new Date(1989, 8, 7, 1, 0, 0, 0); // 9/7/1989 (Sets the time to 1am, see dijit._CalendarList._patchDate())
+						registry.byId(test2_cal).set("value", day2);
+						doh.is("1989", registry.byId("test2_cal").get("value").getFullYear(),"test2_cal getFullYear should be 1989");
+						doh.is("8", registry.byId("test2_cal").get("value").getMonth(),"test2_cal getMonth should be 8");
+						doh.is("7", registry.byId("test2_cal").get("value").getDate(),"test2_cal getDate should be 7");
+						doh.is("1989", registry.byId("test2_cal2").get("value").getFullYear(),"test2_cal2 getFullYear should be 1989");
+						doh.is("8", registry.byId("test2_cal2").get("value").getMonth(),"test2_cal2 getMonth should be 8");
+						doh.is("7", registry.byId("test2_cal2").get("value").getDate(),"test2_cal2 getDate should be 7");
+						doh.is("09-07-1989 1:00 AM", registry.byId("test2_txt2").get("value"), "test2_txt2 should be 09-07-1989 1:00 AM");
+						doh.is("09-07-1989 1:00 AM", registry.byId("test2_output2").get("value"), "test2_output2 should be 09-07-1989 1:00 AM");
+					}
+				}, {
+					name: "Update-First-Cal-test3",
+					runTest: function(){
+						var day2 = new Date(1989, 8, 7, 1, 0, 0, 0); // 9/7/1989 (Sets the time to 1am, see dijit._CalendarList._patchDate())
+						registry.byId(test3_cal).set("value", day2);
+						doh.is("1989", registry.byId("test3_cal").get("value").getFullYear(),"test3_cal getFullYear should be 1989");
+						doh.is("8", registry.byId("test3_cal").get("value").getMonth(),"test3_cal getMonth should be 8");
+						doh.is("7", registry.byId("test3_cal").get("value").getDate(),"test3_cal getDate should be 7");
+						doh.is("1989", registry.byId("test3_cal2").get("value").getFullYear(),"test3_cal2 getFullYear should be 1989");
+						doh.is("8", registry.byId("test3_cal2").get("value").getMonth(),"test3_cal2 getMonth should be 8");
+						doh.is("7", registry.byId("test3_cal2").get("value").getDate(),"test3_cal2 getDate should be 7");
+						doh.is("09-07-1989 1:00 AM", registry.byId("test3_txt2").get("value"), "test3_txt2 should be 09-07-1989 1:00 AM");
+						doh.is("09-07-1989 1:00 AM", registry.byId("test3_output2").get("value"), "test3_output2 should be 09-07-1989 1:00 AM");
+					}
+				}]);
+
+				doh.register("Update textbox", [{
+					name: "Update-TextBox-test1",
+					runTest: function(){
+						registry.byId(test1_txt2).set("value", "05-05-1991 1:00 AM");
+						doh.is("1991", registry.byId("test1_cal").get("value").getFullYear(),"test1_cal getFullYear should be 1991");
+						doh.is("4", registry.byId("test1_cal").get("value").getMonth(),"test1_cal getMonth should be 4");
+						doh.is("5", registry.byId("test1_cal").get("value").getDate(),"test1_cal getDate should be 4");
+						doh.is("1991", registry.byId("test1_cal2").get("value").getFullYear(),"test1_cal2 getFullYear should be 1991");
+						doh.is("4", registry.byId("test1_cal2").get("value").getMonth(),"test1_cal2 getMonth should be 4");
+						doh.is("5", registry.byId("test1_cal2").get("value").getDate(),"test1_cal2 getDate should be 5");
+						doh.is("05-05-1991 1:00 AM", registry.byId("test1_txt2").get("value"), "test1_txt2 should be 05-05-1991 1:00 AM");
+						doh.is("05-05-1991 1:00 AM", registry.byId("test1_output2").get("value"), "test1_output2 should be 05-05-1991 1:00 AM");
+					}
+				}, {
+					name: "Update-TextBox-test2",
+					runTest: function(){
+						registry.byId(test2_txt2).set("value", "05-05-1991 1:00 AM");
+						doh.is("1991", registry.byId("test2_cal").get("value").getFullYear(),"test2_cal getFullYear should be 1991");
+						doh.is("4", registry.byId("test2_cal").get("value").getMonth(),"test2_cal getMonth should be 4");
+						doh.is("5", registry.byId("test2_cal").get("value").getDate(),"test2_cal getDate should be 4");
+						doh.is("1991", registry.byId("test2_cal2").get("value").getFullYear(),"test2_cal2 getFullYear should be 1991");
+						doh.is("4", registry.byId("test2_cal2").get("value").getMonth(),"test2_cal2 getMonth should be 4");
+						doh.is("5", registry.byId("test2_cal2").get("value").getDate(),"test2_cal2 getDate should be 5");
+						doh.is("05-05-1991 1:00 AM", registry.byId("test2_txt2").get("value"), "test2_txt2 should be 05-05-1991 1:00 AM");
+						doh.is("05-05-1991 1:00 AM", registry.byId("test2_output2").get("value"), "test2_output2 should be 05-05-1991 1:00 AM");
+					}
+				}, {
+					name: "Update-TextBox-test3",
+					runTest: function(){
+						registry.byId(test3_txt2).set("value", "05-05-1991 1:00 AM");
+						doh.is("1991", registry.byId("test3_cal").get("value").getFullYear(),"test3_cal getFullYear should be 1991");
+						doh.is("4", registry.byId("test3_cal").get("value").getMonth(),"test3_cal getMonth should be 4");
+						doh.is("5", registry.byId("test3_cal").get("value").getDate(),"test3_cal getDate should be 4");
+						doh.is("1991", registry.byId("test3_cal2").get("value").getFullYear(),"test3_cal2 getFullYear should be 1991");
+						doh.is("4", registry.byId("test3_cal2").get("value").getMonth(),"test3_cal2 getMonth should be 4");
+						doh.is("5", registry.byId("test3_cal2").get("value").getDate(),"test3_cal2 getDate should be 5");
+						doh.is("05-05-1991 1:00 AM", registry.byId("test3_txt2").get("value"), "test3_txt2 should be 05-05-1991 1:00 AM");
+						doh.is("05-05-1991 1:00 AM", registry.byId("test3_output2").get("value"), "test3_output2 should be 05-05-1991 1:00 AM");
+					}
+				}]);
+
+				doh.register("Update cal with new date", [{
+					name: "Update-withNewDate-test1",
+					runTest: function(){
+						var day2 = new Date(1993, 9, 28, 1, 0, 0, 0);  // 10/28/1993
+						var test = day2.toDateString();
+						var startTime3 = (new Date()).getTime();
+						registry.byId(test1_cal).set("value", day2);
+						doh.is("1993", registry.byId("test1_cal").get("value").getFullYear(),"test1_cal getFullYear should be 1993");
+						doh.is("9", registry.byId("test1_cal").get("value").getMonth(),"test1_cal getMonth should be 9");
+						doh.is("28", registry.byId("test1_cal").get("value").getDate(),"test1_cal getDate should be 28");
+						doh.is("1993", registry.byId("test1_cal2").get("value").getFullYear(),"test1_cal2 getFullYear should be 1993");
+						doh.is("9", registry.byId("test1_cal2").get("value").getMonth(),"test1_cal2 getMonth should be 9");
+						doh.is("28", registry.byId("test1_cal2").get("value").getDate(),"test1_cal2 getDate should be 28");
+						doh.is("10-28-1993 1:00 AM", registry.byId("test1_txt2").get("value"), "test1_txt2 should be 10-28-1993 1:00 AM");
+						doh.is("10-28-1993 1:00 AM", registry.byId("test1_output2").get("value"), "test1_output2 should be 10-28-1993 1:00 AM");
+					}
+				}, {
+					name: "Update-withNewDate-test2",
+					runTest: function(){
+						var day2 = new Date(1993, 9, 28, 1, 0, 0, 0);  // 10/28/1993
+						registry.byId(test2_cal).set("value", day2);
+						doh.is("1993", registry.byId("test2_cal").get("value").getFullYear(),"test2_cal getFullYear should be 1993");
+						doh.is("9", registry.byId("test2_cal").get("value").getMonth(),"test2_cal getMonth should be 9");
+						doh.is("28", registry.byId("test2_cal").get("value").getDate(),"test2_cal getDate should be 28");
+						doh.is("1993", registry.byId("test2_cal2").get("value").getFullYear(),"test2_cal2 getFullYear should be 1993");
+						doh.is("9", registry.byId("test2_cal2").get("value").getMonth(),"test2_cal2 getMonth should be 9");
+						doh.is("28", registry.byId("test2_cal2").get("value").getDate(),"test2_cal2 getDate should be 28");
+						doh.is("10-28-1993 1:00 AM", registry.byId("test2_txt2").get("value"), "test2_txt2 should be 10-28-1993 1:00 AM");
+						doh.is("10-28-1993 1:00 AM", registry.byId("test2_output2").get("value"), "test2_output2 should be 10-28-1993 1:00 AM");
+					}
+				}, {
+					name: "Update-withNewDate-test3",
+					runTest: function(){
+						var day2 = new Date(1993, 9, 28, 1, 0, 0, 0);  // 10/28/1993
+						registry.byId(test3_cal).set("value", day2);
+						doh.is("1993", registry.byId("test3_cal").get("value").getFullYear(),"test3_cal getFullYear should be 1993");
+						doh.is("9", registry.byId("test3_cal").get("value").getMonth(),"test3_cal getMonth should be 9");
+						doh.is("28", registry.byId("test3_cal").get("value").getDate(),"test3_cal getDate should be 28");
+						doh.is("1993", registry.byId("test3_cal2").get("value").getFullYear(),"test3_cal2 getFullYear should be 1993");
+						doh.is("9", registry.byId("test3_cal2").get("value").getMonth(),"test3_cal2 getMonth should be 9");
+						doh.is("28", registry.byId("test3_cal2").get("value").getDate(),"test3_cal2 getDate should be 28");
+						doh.is("10-28-1993 1:00 AM", registry.byId("test3_txt2").get("value"), "test3_txt2 should be 10-28-1993 1:00 AM");
+						doh.is("10-28-1993 1:00 AM", registry.byId("test3_output2").get("value"), "test3_output2 should be 10-28-1993 1:00 AM");
+					}
+				}]);
+
+				doh.register("Check model reset", [{
+					name: "Reset-test1",
+					runTest: function(){
+						test1_ctrl.reset();
+						doh.is("1987", registry.byId("test1_cal").get("value").getFullYear(),"test1_cal getFullYear should be 1987");
+						doh.is("7", registry.byId("test1_cal").get("value").getMonth(),"test1_cal getMonth should be 7");
+						doh.is("1", registry.byId("test1_cal").get("value").getDate(),"test1_cal getDate should be 1");
+						doh.is("1987", registry.byId("test1_cal2").get("value").getFullYear(),"test1_cal2 getFullYear should be 1987");
+						doh.is("7", registry.byId("test1_cal2").get("value").getMonth(),"test1_cal2 getMonth should be 7");
+						doh.is("1", registry.byId("test1_cal2").get("value").getDate(),"test1_cal2 getDate should be 1");
+						doh.is("08-01-1987 1:00 AM", registry.byId("test1_txt2").get("value"), "test1_txt2 should be 08-01-1987 1:00 AM");
+						doh.is("08-01-1987 1:00 AM", registry.byId("test1_output2").get("value"), "test1_output2 should be 08-01-1987 1:00 AM");
+					}
+				}, {
+					name: "Reset-test2",
+					runTest: function(){
+						test2_ctrl.reset();
+						doh.is("2011", registry.byId("test2_cal").get("value").getFullYear(),"test2_cal getFullYear should be 1987");
+						doh.is("10", registry.byId("test2_cal").get("value").getMonth(),"test2_cal getMonth should be 10");
+						doh.is("6", registry.byId("test2_cal").get("value").getDate(),"test2_cal getDate should be 6");
+						doh.is("2011", registry.byId("test2_cal2").get("value").getFullYear(),"test2_cal2 getFullYear should be 1987");
+						doh.is("10", registry.byId("test2_cal2").get("value").getMonth(),"test2_cal2 getMonth should be 10");
+						doh.is("6", registry.byId("test2_cal2").get("value").getDate(),"test2_cal2 getDate should be 6");
+						doh.is("11-06-2011 1:00 AM", registry.byId("test2_txt2").get("value"), "test2_txt2 should be 11-06-2011 1:00 AM");
+						doh.is("11-06-2011 1:00 AM", registry.byId("test2_output2").get("value"), "test2_output2 should be 11-06-2011 1:00 AM");
+					}
+				}, {
+					name: "Reset-test3",
+					runTest: function(){
+						test3_ctrl.reset();
+						doh.is("2011", registry.byId("test3_cal").get("value").getFullYear(),"test3_cal getFullYear should be 1987");
+						doh.is("7", registry.byId("test3_cal").get("value").getMonth(),"test3_cal getMonth should be 7");
+						doh.is("27", registry.byId("test3_cal").get("value").getDate(),"test3_cal getDate should be 27");
+						doh.is("2011", registry.byId("test3_cal2").get("value").getFullYear(),"test3_cal2 getFullYear should be 1987");
+						doh.is("7", registry.byId("test3_cal2").get("value").getMonth(),"test3_cal2 getMonth should be 7");
+						doh.is("27", registry.byId("test3_cal2").get("value").getDate(),"test3_cal2 getDate should be 27");
+						doh.is("08-27-2011 1:00 AM", registry.byId("test3_txt2").get("value"), "test3_txt2 should be 08-27-2011 1:00 AM");
+						doh.is("08-27-2011 1:00 AM", registry.byId("test3_output2").get("value"), "test3_output2 should be 08-27-2011 1:00 AM");
+					}
+				}]);
+
+				doh.register("Test misc in model", [{
+					name: "Regexp-test4",
+					runTest: function(){
+						doh.is("/abc/i", test4_ctrl.get("regex"),"test4_ctrl.get(\"regex\") should be /abc/i");
+						var str = "ABCDEFGHIJKLMNOP abcdefghi";
+						var patt1 = test4_ctrl.get("regex");
+						doh.is("ABC", str.match(test4_ctrl.get("regex")),"str.match(test4_ctrl.get(\"regex\")) should be ABC");
+						doh.is("ABC", str.match(patt1),"str.match(patt1) should be ABC");
+						test4_ctrl.set("regex",/def/);
+						doh.is("def", str.match(test4_ctrl.get("regex")),"str.match(test4_ctrl.get(\"regex\")) after set /def/ should be def");
+						test4_ctrl.reset();
+						doh.is("ABC", str.match(test4_ctrl.get("regex")),"str.match(test4_ctrl.get(\"regex\")) after reset should be ABC");
+					}
+				}, {
+					name: "Falsy-test5",
+					runTest: function(){
+						doh.t(null === test5_model.get("n"),"test5_model.get(\"n\") should be null");
+						doh.t(0 === test5_model.get("z"),"test5_model.get(\"z\") should be 0");
+						doh.t(undefined === test5_model.get("u"),"test5_model.get(\"u\") should be undefined");
+						doh.t(false === test5_model.get("f"),"test5_model.f.get(\"f\") should be false");
+						doh.t("" === test5_model.get("s"),"test5_model.s.get(\"s\") should be an empty string");
+					}
+				}]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<h2>Test 1: Two Calendars bound to each other, a TextBox and an mvc Output field.</h2>
+			<div  style="border-style: solid; border-width: 2px; width: 827px;">
+				<table>
+					<tbody>
+						<tr>
+							<td><div id="test1_cal"></div></td>
+							<td><div id="test1_cal2"></div></td>
+							<td>
+								<table>
+									<tbody>
+										<tr><td><label for="test1_txt2">TextBox bound to date:</label></td></tr>
+										<tr><td><div id="test1_txt2"></div></td></tr>
+										<tr><td><label for="test1_txt2">MVC Output bound to date:</label></td></tr>
+										<tr><td><div id="test1_output2"></div></td></tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test1_setdate1"></div></td>
+										</tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test1_setdate2"></div></td>
+										</tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test1_setdate3"></div></td>
+										</tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test1_reset2"></div></td>
+										</tr>
+									</tbody>
+								</table>
+							</td>
+						</tr>
+					</tbody>
+				</table>
+			</div>
+
+		<h2>Test 2: Two DateTextBoxes bound to each other, a TextBox and an mvc Output field.</h2>
+			<div  style="border-style: solid; border-width: 2px; width: 827px;">
+				<table>
+					<tbody>
+						<tr>
+							<td style="vertical-align: top;"><div id="test2_cal"></div></td>
+							<td style="vertical-align: top;"><div id="test2_cal2"></div></td>
+							<td>
+								<table>
+									<tbody>
+										<tr><td><label for="test2_txt2">TextBox bound to date:</label></td></tr>
+										<tr><td><div id="test2_txt2"></div></td></tr>
+										<tr><td><label for="test2_txt2">MVC Output bound to date:</label></td></tr>
+										<tr><td><div id="test2_output2"></div></td></tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test2_setdate1"></div></td>
+										</tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test2_setdate2"></div></td>
+										</tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test2_setdate3"></div></td>
+										</tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test2_reset2"></div></td>
+										</tr>
+									</tbody>
+								</table>
+							</td>
+						</tr>
+					</tbody>
+				</table>
+			</div>
+		<h2>Test 3: One Calendar bound to a DateTextbox, a TextBox and an mvc Output field.</h2>
+			<div  style="border-style: solid; border-width: 2px; width: 827px;">
+				<table>
+					<tbody>
+						<tr>
+							<td style="vertical-align: top;"><div id="test3_cal"></div></td>
+							<td style="vertical-align: top;"><div id="test3_cal2"></div></td>
+							<td>
+								<table>
+									<tbody>
+										<tr><td><label for="test3_txt2">TextBox bound to date: (disabled to avoid error)</label></td></tr>
+										<tr><td><div id="test3_txt2"></div></td></tr>
+										<tr><td><label for="test3_txt2">MVC Output bound to date:</label></td></tr>
+										<tr><td><div id="test3_output2"></div></td></tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test3_setdate1"></div></td>
+										</tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test3_setdate2"></div></td>
+										</tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test3_setdate3"></div></td>
+										</tr>
+									</tbody>
+								</table>
+								<table>
+									<tbody>
+										<tr>
+											<td><div id="test3_reset2"></div></td>
+										</tr>
+									</tbody>
+								</table>
+							</td>
+						</tr>
+					</tbody>
+				</table>
+			</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_extension-per-widget.html b/dojox/mvc/tests/doh/doh_mvc_extension-per-widget.html
new file mode 100644
index 0000000..0c412ec
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_extension-per-widget.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+		</style>
+		<!-- required: dojo.js -->
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: 1, parseOnLoad: 0, async: 1, mvc: {debugBindings: true, extensionPerWidget: true}"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/dom",
+				"dojo/Stateful",
+				"dijit/_WidgetBase",
+				"dijit/form/TextBox",
+				"dojox/mvc/at",
+				"dojox/mvc/atBindingExtension"
+			], function(doh, dom, Stateful, _WidgetBase, TextBox, at, atBindingExtension){
+				doh.register("doh_mvc_extension-per-widget", [
+					function widgetNotExtended(){
+						var model = new Stateful({value: "Foo"}),
+						 w = new TextBox({value: at(model, "value")}, dom.byId("tb0"));
+						w.startup();
+						doh.f(w.value == "Foo", "Widget should not have been looked at at()");
+					},
+					function extendInstance(){
+						var model = new Stateful({value: "Foo"}),
+						 w = atBindingExtension(new TextBox({}, dom.byId("tb1")))[0];
+						w.startup();
+						w.set("value", at(model, "value"));
+						doh.is("Foo", w.value, "Extended widget should have been initialized with the model value");
+						model.set("value", "Bar");
+						doh.is("Bar", w.value, "Extended widget should have been updated with the model value");
+						w = new TextBox({value: at(model, "value")}, dom.byId("tb2"));
+						w.startup();
+						doh.f(w.value == "Bar", "Non-extended widget should not have been looked at at()");
+					},
+					function extendClass(){
+						atBindingExtension(TextBox.prototype);
+						var model = new Stateful({value: "Foo"}),
+						 w = new TextBox({value: at(model, "value")}, dom.byId("tb3"));
+						w.startup();
+						doh.is("Foo", w.value, "Extended widget should have been looked at at()");
+						w = new _WidgetBase({value: at(model, "value")}, dom.byId("w0"));
+						w.startup();
+						doh.f(w.value == "Foo", "Non-extended widget should not have been looked at at()");
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+	<body>
+		<input id="tb0" type="text">
+		<input id="tb1" type="text">
+		<input id="tb2" type="text">
+		<input id="tb3" type="text">
+		<span id="w0"></span>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_form-kitchensink.html b/dojox/mvc/tests/doh/doh_mvc_form-kitchensink.html
new file mode 100644
index 0000000..525277d
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_form-kitchensink.html
@@ -0,0 +1,1176 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css">
+
+		<!-- required: dojo.js -->
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: 1, async: 1, mvc: {debugBindings: 1, extensionPerWidget: true}"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+		<script type="text/javascript" >
+			require([
+				"doh/runner",
+				"dojo/dom",
+				"dojo/number",
+				"dojo/parser",
+				"dojo/when",
+				"dojo/Stateful",
+				"dojo/data/ItemFileReadStore",
+				"dojo/date/locale",
+				"dijit/registry",
+				"dijit/form/Button",
+				"dijit/form/ComboBox",
+				"dijit/form/DateTextBox",
+				"dijit/form/FilteringSelect",
+				"dijit/form/HorizontalSlider",
+				"dijit/form/NumberSpinner",
+				"dijit/form/NumberTextBox",
+				"dijit/form/TextBox",
+				"dijit/form/Select",
+				"dijit/form/SimpleTextarea",
+				"dijit/form/Textarea",
+				"dijit/Calendar",
+				"dijit/ColorPalette",
+				"dojox/mvc/at",
+				"dojox/mvc/atBindingExtension",
+				"dojox/mvc/EditModelRefController",
+				"dojox/mvc/Output"
+			], function(doh, ddom, number, parser, when, Stateful, ItemFileReadStore, locale, registry, Button, 
+					ComboBox, DateTextBox, FilteringSelect, HorizontalSlider, NumberSpinner, NumberTextBox, 
+					TextBox, Select, SimpleTextarea, Textarea, Calendar, ColorPalette, 
+					at, atBindingExtension, EditModelRefController, Output){
+
+				for(var i = 0, l = arguments.length; i < l; ++i){
+					var proto = arguments[i].prototype;
+					if((proto || {})._blankGif){
+						atBindingExtension(proto);
+					}
+				}
+
+				store = new ItemFileReadStore({
+					data: {
+						identifier: "id",
+						label: "name",
+						items: [
+							{id: "1", name: "one"},
+							{id: "2", name:  "two"},
+							{id: "3", name: "three"},
+							{id: "4", name: "four"},
+							{id: "5", name: "five"},
+							{id: "6", name: "six"},
+							{id: "7", name: "seven"},
+							{id: "8", name: "eight"},
+							{id: "9", name: "nine"},
+							{id: "10", name: "ten"},
+							{id: "11", name: "eleven"},
+							{id: "12", name: "twelve"},
+							{id: "13", name: "thirteen"}
+						]
+					}
+				});
+
+				store2 = new ItemFileReadStore({data: {
+					identifier: "value",
+					label: "label",
+					items: [
+						{value: "1", label: "one"},
+						{value: "2", label: "two"},
+						{value: "3", label: "three"},
+						{value: "4", label: "four"},
+						{value: "5", label: "five"},
+						{value: "6", label: "six"},
+						{value: "7", label: "seven"},
+						{value: "8", label: "eigth"},
+						{value: "9", label: "nine"},
+						{value: "10", label: "ten"},
+						{value: "11", label: "eleven"},
+						{value: "12", label: "twelve"},
+						{value: "13", label: "thirteen"},
+						{value: "14", label: "fourteen"}
+					]
+				}});
+
+				// create models for selects
+				selctrl = new EditModelRefController({sourceModel: new Stateful({number: "1"})});
+				decselctrl = new EditModelRefController({sourceModel: new Stateful({number: "1"})});
+
+				// create models for filtering selects
+				filctrl = new EditModelRefController({sourceModel: new Stateful({number: "2"})});
+				decfilctrl = new EditModelRefController({sourceModel: new Stateful({number: "2"})});
+
+				// create models for ComboBoxes
+				comboctrl = new EditModelRefController({sourceModel: new Stateful({number: "three"})});
+				deccomboctrl = new EditModelRefController({sourceModel: new Stateful({number: "three"})});
+
+				// create a model for DateTextBox
+				datectrl = new EditModelRefController({sourceModel: new Stateful({number: new Date(2011, 3, 4)})});
+				decdatectrl = new EditModelRefController({sourceModel: new Stateful({number: new Date(2011, 3, 4)})});
+
+				// create a model for Slider
+				sliderctrl = new EditModelRefController({sourceModel: new Stateful({number: "5"})});
+				decsliderctrl = new EditModelRefController({sourceModel: new Stateful({number: "5"})});
+
+				// create a model for NumberSpinner
+				numspinctrl = new EditModelRefController({sourceModel: new Stateful({number: 6})});
+				decnumspinctrl = new EditModelRefController({sourceModel: new Stateful({number: 6})});
+
+				// create a model for SimpleTextArea
+				simpTActrl = new EditModelRefController({sourceModel: new Stateful({number: "7"})});
+				decsimpTActrl = new EditModelRefController({sourceModel: new Stateful({number: "7"})});
+
+				// create a model for TextArea
+				textareactrl = new EditModelRefController({sourceModel: new Stateful({number: "8"})});
+				dectextareactrl = new EditModelRefController({sourceModel: new Stateful({number: "8"})});
+
+				// create a model for dijit.Calendar
+				deccalctrl = new EditModelRefController({sourceModel: new Stateful({date: new Date(2011, 3, 4)})});
+
+				// create a model for dijit.ColorPalette
+				deccolorctrl = new EditModelRefController({sourceModel: new Stateful({code: "#000000"})});
+
+				nanmodel = new Stateful({num: null});
+
+				dummyDateWid = new DateTextBox({constraints:{datePattern:"MM-dd-yyyy", strict:true}});
+
+				when(parser.parse(), function(){
+					// Handle the programmatic creation of widgets here:
+
+					// create the select, textbox, output and button
+					var sel = new Select({
+						store: store,
+						loadChildrenOnOpen: true,
+						value: at(selctrl, "number")
+					}, ddom.byId("sel"));
+
+					(new TextBox({value: at(selctrl, "number")}, ddom.byId("seltext"))).startup();
+
+					var selOutput = new Output({value: at(selctrl, "number")}, ddom.byId("selOutput"));
+					selOutput.startup();
+
+					var reset1 = new Button({
+						onClick: function(){ selctrl.reset(); },
+						id: "selReset",
+						label: "Reset"
+					}, ddom.byId("reset1"));
+					reset1.startup();
+
+					sel.startup();
+
+					// create the filtering select, textbox, output and button
+					var filsel = new FilteringSelect({
+						store: store,
+						value: at(filctrl, "number")
+					}, ddom.byId("filsel"));
+
+					var filtext = new TextBox({value: at(filctrl, "number")}, ddom.byId("filtext"));
+
+					var filoutput = new Output({value: at(filctrl, "number")}, ddom.byId("filoutput"));
+					filoutput.startup();
+
+					var filreset = new Button({
+						onClick: function(){ filctrl.reset(); },
+						id: "filReset",
+						label: "Reset"
+					}, ddom.byId("filreset"));
+					filreset.startup();
+
+					filtext.startup();
+					filsel.startup();
+
+					// create the comboBox, textbox, output and button
+					var combo = new ComboBox({
+						store: store,
+						value: at(comboctrl, "number")
+					}, ddom.byId("combosel"));
+
+					var combotext = new TextBox({value: at(comboctrl, "number")}, ddom.byId("combotext"));
+
+					var combooutput = new Output({value: at(comboctrl, "number")}, ddom.byId("combooutput"));
+					combooutput.startup();
+
+					var comboreset = new Button({
+						onClick: function(){ comboctrl.reset(); },
+						id: "comboReset",
+						label: "Reset"
+					}, ddom.byId("comboreset"));
+					comboreset.startup();
+
+					combotext.startup();
+					combo.startup();
+
+					// create the dijit.form.DateTextBox, textbox, output and button
+					var dateWid = new DateTextBox({
+						value: at(datectrl, "number"),
+						constraints: dummyDateWid.constraints
+					}, ddom.byId("datesel"));
+
+					var datetext = new TextBox({
+						value: at(datectrl, "number").transform(dummyDateWid.dateLocaleModule),
+						constraints: dummyDateWid.constraints
+					}, ddom.byId("datetext"));
+
+					var dateoutput = new Output({
+						value: at(datectrl, "number").transform(dummyDateWid.dateLocaleModule),
+						constraints: dummyDateWid.constraints
+					}, ddom.byId("dateoutput"));
+					dateoutput.startup();
+
+					var datereset = new Button({
+						onClick: function(){ datectrl.reset(); },
+						id: "dateReset",
+						label: "Reset"
+					}, ddom.byId("datereset"));
+					datereset.startup();
+
+					datetext.startup();
+					dateWid.startup();
+
+					// create the dijit.form.HorizontalSlider, textbox, output and button
+					var sliderWid = new HorizontalSlider({
+						style: {width: "190px"},
+						minimum: 0,
+						maximum: 100,
+						discreteValues: 21,
+						value: at(sliderctrl, "number") // bind to model.number
+					}, ddom.byId("slidersel"));
+
+					var slidertext = new TextBox({value: at(sliderctrl, "number").transform(number)}, ddom.byId("slidertext"));
+
+					var slideroutput = new Output({	value: at(sliderctrl, "number").transform(number)}, ddom.byId("slideroutput"));
+					slideroutput.startup();
+
+					var sliderreset = new Button({
+						onClick: function(){ sliderctrl.reset(); },
+						id: "sliderReset",
+						label: "Reset"
+					}, ddom.byId("sliderreset"));
+					sliderreset.startup();
+
+					slidertext.startup();
+					sliderWid.startup();
+
+					// create the dijit.form.NumberSpinner, textbox, output and button
+					var numspinWid = new NumberSpinner({value: at(numspinctrl, "number")}, ddom.byId("numspinsel"));
+
+					var numspintext = new TextBox({value: at(numspinctrl, "number").transform(number)}, ddom.byId("numspintext"));
+
+					var numspinoutput = new Output({value: at(numspinctrl, "number").transform(number)}, ddom.byId("numspinoutput"));
+					numspinoutput.startup();
+
+					var numspinreset = new Button({
+						onClick: function(){ numspinctrl.reset(); },
+						id: "numspinReset",
+						label: "Reset"
+					}, ddom.byId("numspinreset"));
+					numspinreset.startup();
+
+					numspintext.startup();
+					numspinWid.startup();
+
+					// create the dijit.form.SimpleTextarea, textbox, output and button
+					var simpTAWid = new SimpleTextarea({
+						style: {height: "20px", width: "180px"},
+						value: at(simpTActrl, "number")
+					}, ddom.byId("simpTAsel"));
+
+					var simpTAtext = new TextBox({value: at(simpTActrl, "number")}, ddom.byId("simpTAtext"));
+
+					var simpTAoutput = new Output({value: at(simpTActrl, "number")}, ddom.byId("simpTAoutput"));
+					simpTAoutput.startup();
+
+					var simpTAreset = new Button({
+						onClick: function(){ simpTActrl.reset(); },
+						id: "simpTAReset",
+						label: "Reset"
+					}, ddom.byId("simpTAreset"));
+					simpTAreset.startup();
+
+					simpTAtext.startup();
+					simpTAWid.startup();
+
+					// create the dijit.form.Textarea, textbox, output and button
+					var textareaWid = new Textarea({value: at(textareactrl, "number")}, ddom.byId("textareasel"));
+
+					var textareatext = new TextBox({value: at(textareactrl, "number")}, ddom.byId("textareatext"));
+
+					var textareaoutput = new Output({value: at(textareactrl, "number")}, ddom.byId("textareaoutput"));
+					textareaoutput.startup();
+
+					var textareareset = new Button({
+						onClick: function(){ textareactrl.reset(); },
+						id: "textareaReset",
+						label: "Reset"
+					}, ddom.byId("textareareset"));
+					textareareset.startup();
+
+					textareatext.startup();
+					textareaWid.startup();
+
+					var numBox = new dijit.form.NumberTextBox({value: at(nanmodel, "num")}, ddom.byId("nannb"));
+
+					numBox.startup();
+
+	/*
+					doh.register("Check initial programatic values and bindings for select widget only", [
+						{
+							name: "InitialSelectOnly",
+							runTest: function(){
+								console.log("This test is commented out because it will fail if _FromSelectWidget is not updated to setup the store in postCreate instead of startup, see ticket 13372 for details.");
+								// Test Select
+								doh.is("1",wid.get("value"),"This test will fail if _FromSelectWidget is not updated to setup the store in postCreate instead of startup, see ticket 13372 for details.");
+								doh.is(registry.byId("seltext").value,registry.byId("sel").get("value"),"wid.get(\"value\") should be set same as textboxval");
+								doh.is(registry.byId("selOutput").value,registry.byId("sel").get("value"),"wid.get(\"value\") should be set same as outputval");
+							}
+						}
+					]);
+	*/
+
+					doh.register("Check initial values and bindings widgets other than select", [
+						{
+							name: "InitialOtherThanSelect",
+							runTest: function(){
+								// Test FilteringSelect
+								var wid, textboxval, outputval;
+								wid = registry.byId("filsel");
+								textboxval = registry.byId("filtext").value;
+								outputval = registry.byId("filoutput").value;
+								doh.is("2", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is("two", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.ComboBox
+								wid = registry.byId("combosel");
+								textboxval = registry.byId("combotext").value;
+								outputval = registry.byId("combooutput").value;
+								doh.is("three", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is("three", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.DateTextBox
+								wid = registry.byId("datesel");
+								textboxval = registry.byId("datetext").value;
+								outputval = registry.byId("dateoutput").value;
+								doh.is((new Date(2011, 3, 4)).getTime(), wid.get("value").getTime(), "wid.get(\"value\") should be set it is:" + wid.get("value"));
+								doh.is("04-04-2011", wid.displayedValue, "wid.displayedValue should be set it is:" + wid.displayedValue);
+								doh.is("04-04-2011", textboxval, "textboxval should be set it is:" + textboxval);
+								doh.is("04-04-2011", outputval, "outputval should be set it is:" + outputval);
+								// Test dijit.form.HorizontalSlider
+								wid = registry.byId("slidersel");
+								textboxval = registry.byId("slidertext").value;
+								outputval = registry.byId("slideroutput").value;
+								doh.is("5", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.NumberSpinner
+								wid = registry.byId("numspinsel");
+								textboxval = registry.byId("numspintext").value;
+								outputval = registry.byId("numspinoutput").value;
+								doh.is("6", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.displayedValue, "wid.displayedValue should be set same as textboxval");
+								doh.is(outputval, wid.displayedValue, "wid.displayedValue should be set same as outputval");
+								// Test dijit.form.SimpleTextarea
+								wid = registry.byId("simpTAsel");
+								textboxval = registry.byId("simpTAtext").value;
+								outputval = registry.byId("simpTAoutput").value;
+								doh.is("7", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.Textarea
+								wid = registry.byId("textareasel");
+								textboxval = registry.byId("textareatext").value;
+								outputval = registry.byId("textareaoutput").value;
+								doh.is("8", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+							}
+						}, {
+							name: "Initial-declarative",
+							runTest: function(){
+								var wid, textboxval, outputval;
+								// Test Select
+								wid = registry.byId("decsel");
+								textboxval = registry.byId("decseltext").value;
+								outputval = registry.byId("decselOutput").value;
+								doh.is("1", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test FilteringSelect
+								wid = registry.byId("decfilsel");
+								textboxval = registry.byId("decfiltext").value;
+								outputval = registry.byId("decfilOutput").value;
+								doh.is("2", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is("two", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.ComboBox
+								wid = registry.byId("deccombosel");
+								textboxval = registry.byId("deccombotext").value;
+								outputval = registry.byId("deccomboOutput").value;
+								doh.is("three",wid.get("value"),"wid.get(\"value\") should be set");
+								doh.is("three",wid.displayedValue,"wid.displayedValue should be set");
+								doh.is(textboxval,wid.get("value"),"wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval,wid.get("value"),"wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.DateTextBox
+								wid = registry.byId("decdatesel");
+								textboxval = registry.byId("decdatetext").value;
+								outputval = registry.byId("decdateOutput").value;
+								doh.is((new Date(2011, 3, 4)).getTime(), wid.get("value").getTime(), "wid.get(\"value\") should be set it is:" + wid.get("value"));
+								doh.is("04-04-2011", wid.displayedValue, "wid.displayedValue should be set it is:" + wid.displayedValue);
+								doh.is("04-04-2011", textboxval, "textboxval should be set it is:" + textboxval);
+								doh.is("04-04-2011", outputval, "outputval should be set it is:" + outputval);
+								// Test dijit.form.HorizontalSlider
+								wid = registry.byId("decslidersel");
+								textboxval = registry.byId("decslidertext").value;
+								outputval = registry.byId("decsliderOutput").value;
+								doh.is("5", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.NumberSpinner
+								wid = registry.byId("decnumspinsel");
+								textboxval = registry.byId("decnumspintext").value;
+								outputval = registry.byId("decnumspinOutput").value;
+								doh.is("6", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.displayedValue, "wid.displayedValue should be set same as textboxval");
+								doh.is(outputval, wid.displayedValue, "wid.displayedValue should be set same as outputval");
+								// Test dijit.form.SimpleTextarea
+								wid = registry.byId("decsimpTAsel");
+								textboxval = registry.byId("decsimpTAtext").value;
+								outputval = registry.byId("decsimpTAOutput").value;
+								doh.is("7", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.Textarea
+								wid = registry.byId("dectextareasel");
+								textboxval = registry.byId("dectextareatext").value;
+								outputval = registry.byId("dectextareaOutput").value;
+								doh.is("8", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+							}
+						}
+					]);
+
+					doh.register("Check initial/updated calendar and colorpalette values", [
+						{
+							name: "Initial-calendar-and-color",
+							runTest: function(){
+								var wid, textboxval, outputval;
+								// Test Calendar
+								wid = registry.byId("deccal");
+								textboxval = registry.byId("deccaltext").value;
+								outputval = registry.byId("deccalOutput").value;
+								doh.is((new Date(2011, 3, 4)).getTime(), wid.get("value").getTime(), "wid.get(\"value\") should be set it is:" + wid.get("value"));
+								doh.is("04-04-2011", textboxval, "1-textboxval should be set");
+								doh.is("04-04-2011", outputval, "1-textboxval should be set");
+								// Test dijit.ColorPalette
+								wid = registry.byId("deccolor");
+								textboxval = registry.byId("deccolortext").value;
+								outputval = registry.byId("deccolorOutput").value;
+								doh.is("#000000", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+							}
+						}, {
+							name: "Updated-test-calendar-and-color",
+							runTest: function(){
+								var wid, textboxval, outputval;
+								// Test Update calendar
+								var d = new Date(2011, 10, 10);
+								wid = registry.byId("deccal");
+								wid.set("value", d);
+								textboxval = registry.byId("deccaltext").value;
+								outputval = registry.byId("deccalOutput").value;
+								doh.is(d.getTime(), wid.get("value").getTime(), "2-wid.get(\"value\") should be set " + wid.get("value"));
+								doh.is("11-10-2011", textboxval, "2-textboxval should be set" + textboxval);
+								doh.is("11-10-2011", outputval, "2-textboxval should be set" + outputval);
+								// Test dijit.ColorPalette
+								// update the text field
+								registry.byId("deccolortext").set("value", "#ffffff");
+								wid = registry.byId("deccolor");
+								textboxval = registry.byId("deccolortext").value;
+								outputval = registry.byId("deccolorOutput").value;
+								doh.is("#ffffff", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+
+								// Test Reset Calendar
+								button = registry.byId("deccalReset"); // reset the model
+								button.onClick();
+								wid = registry.byId("deccal");
+								textboxval = registry.byId("deccaltext").value;
+								outputval = registry.byId("deccalOutput").value;
+								doh.is((new Date(2011, 3, 4)).getTime(), wid.get("value").getTime(), "3-wid.get(\"value\") should be set " + wid.get("value"));
+								doh.is("04-04-2011", textboxval, "3-textboxval should be set" + textboxval);
+								doh.is("04-04-2011", outputval, "3-textboxval should be set" + outputval);
+								// Test reset the dijit.ColorPalette
+								button = registry.byId("deccolorReset"); // reset the model
+								button.onClick();
+								wid = registry.byId("deccolor");
+								textboxval = registry.byId("deccolortext").value;
+								outputval = registry.byId("deccolorOutput").value;
+								doh.is("#000000", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+							}
+						}
+					]);
+
+					// Update and Test all fields
+					doh.register("Test update for all values and bindings", [
+						{
+							name: "Update-programatic",
+							runTest: function(){
+								// update the text field
+								registry.byId("seltext").set("value", "10");
+								var wid, textboxval, outputval;
+								// Test Select
+								wid = registry.byId("sel");
+								textboxval = registry.byId("seltext").value;
+								outputval = registry.byId("selOutput").value;
+								doh.is("10", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test FilteringSelect
+								// update the text field
+								registry.byId("filtext").set("value", "10");
+								wid = registry.byId("filsel");
+								textboxval = registry.byId("filtext").value;
+								outputval = registry.byId("filoutput").value;
+								doh.is("10", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is("ten", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.ComboBox
+								registry.byId("combotext").set("value", "ten");
+								wid = registry.byId("combosel");
+								textboxval = registry.byId("combotext").value;
+								outputval = registry.byId("combooutput").value;
+								doh.is("ten", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is("ten", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.DateTextBox
+								// update the text field
+								registry.byId("datetext").set("value", "10-10-2011");
+								wid = registry.byId("datesel");
+								textboxval = registry.byId("datetext").value;
+								outputval = registry.byId("dateoutput").value;
+								doh.is((new Date(2011, 9, 10)).getTime(), wid.get("value").getTime(), "wid.get(value) should be set " + wid.get("value"));
+								doh.is("10-10-2011", textboxval, "2-textboxval should be set" + textboxval);
+								doh.is("10-10-2011", outputval, "2-textboxval should be set" + outputval);
+								// Test dijit.form.HorizontalSlider
+								// update the text field
+								registry.byId("slidertext").set("value", "10");
+								wid = registry.byId("slidersel");
+								textboxval = registry.byId("slidertext").value;
+								outputval = registry.byId("slideroutput").value;
+								doh.is("10", wid.get("value"), "wid.get(value) should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.NumberSpinner
+								registry.byId("numspintext").set("value", "10");
+								wid = registry.byId("numspinsel");
+								textboxval = registry.byId("numspintext").value;
+								outputval = registry.byId("numspinoutput").value;
+								doh.is("10", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.displayedValue, "wid.displayedValue should be set same as textboxval");
+								doh.is(outputval, wid.displayedValue, "wid.displayedValue should be set same as outputval");
+								// Test dijit.form.SimpleTextarea
+								registry.byId("simpTAtext").set("value", "10");
+								wid = registry.byId("simpTAsel");
+								textboxval = registry.byId("simpTAtext").value;
+								outputval = registry.byId("simpTAoutput").value;
+								doh.is("10", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.Textarea
+								registry.byId("textareatext").set("value", "10");
+								wid = registry.byId("textareasel");
+								textboxval = registry.byId("textareatext").value;
+								outputval = registry.byId("textareaoutput").value;
+								doh.is("10", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+							}
+						}, {
+							name: "Update-declarative",
+							runTest: function(){
+								registry.byId("decsel").set("value", "4");
+								var wid, textboxval, outputval;
+								// Test Select
+								wid = registry.byId("decsel");
+								textboxval = registry.byId("decseltext").value;
+								outputval = registry.byId("decselOutput").value;
+								doh.is("4", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test FilteringSelect
+								wid = registry.byId("decfilsel");
+								wid.set("value", "4");
+								textboxval = registry.byId("decfiltext").value;
+								outputval = registry.byId("decfilOutput").value;
+								doh.is("4", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is("four", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.ComboBox
+								wid = registry.byId("deccombosel");
+								wid.set("value", "four");
+								textboxval = registry.byId("deccombotext").value;
+								outputval = registry.byId("deccomboOutput").value;
+								doh.is("four", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is("four", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.DateTextBox
+								wid = registry.byId("decdatesel");
+								wid.set("value", new Date(2011, 8, 9));
+								textboxval = registry.byId("decdatetext").value;
+								outputval = registry.byId("decdateOutput").value;
+								doh.is((new Date(2011, 8, 9)).getTime(), wid.get("value").getTime(), "wid.get(\"value\") should be set " + wid.get("value"));
+								doh.is("09-09-2011", textboxval, "textboxval should be set" + textboxval);
+								doh.is("09-09-2011", outputval, "textboxval should be set" + outputval);
+								// Test dijit.form.HorizontalSlider
+								wid = registry.byId("decslidersel");
+								wid.set("value", "4");
+								textboxval = registry.byId("decslidertext").value;
+								outputval = registry.byId("decsliderOutput").value;
+								doh.is("4", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.NumberSpinner
+								wid = registry.byId("decnumspinsel");
+								wid.set("displayedValue", "4");
+								textboxval = registry.byId("decnumspintext").value;
+								outputval = registry.byId("decnumspinOutput").value;
+								doh.is("4", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.displayedValue, "wid.displayedValue should be set same as textboxval");
+								doh.is(outputval, wid.displayedValue, "wid.displayedValue should be set same as outputval");
+								// Test dijit.form.SimpleTextarea
+								wid = registry.byId("decsimpTAsel");
+								wid.set("value", "4");
+								textboxval = registry.byId("decsimpTAtext").value;
+								outputval = registry.byId("decsimpTAOutput").value;
+								doh.is("4", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.Textarea
+								wid = registry.byId("dectextareasel");
+								wid.set("value","4");   // update widget value
+								textboxval = registry.byId("dectextareatext").value;
+								outputval = registry.byId("dectextareaOutput").value;
+								doh.is("4", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+							}
+						}
+					]);
+
+					// Test RESET for all fields
+					doh.register("Test reset for all values and bindings", [
+						{
+							name: "Reset-programatic",
+							runTest: function(){
+								// reset the model
+								var button = registry.byId("selReset");
+								button.onClick();
+								var wid, textboxval, outputval;
+								// Test Select
+								wid = registry.byId("sel");
+								textboxval = registry.byId("seltext").value;
+								outputval = registry.byId("selOutput").value;
+								doh.is("1", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test FilteringSelect
+								button = registry.byId("filReset");
+								button.onClick();
+								wid = registry.byId("filsel");
+								textboxval = registry.byId("filtext").value;
+								outputval = registry.byId("filoutput").value;
+								doh.is("2", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is("two", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.ComboBox
+								button = registry.byId("comboReset");
+								button.onClick();
+								wid = registry.byId("combosel");
+								textboxval = registry.byId("combotext").value;
+								outputval = registry.byId("combooutput").value;
+								doh.is("three", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is("three", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.DateTextBox
+								button = registry.byId("dateReset");
+								button.onClick();
+								wid = registry.byId("datesel");
+								textboxval = registry.byId("datetext").value;
+								outputval = registry.byId("dateoutput").value;
+								doh.is((new Date(2011, 3, 4)).getTime(), wid.get("value").getTime(), "wid.get(\"value\") should be set " + wid.get("value"));
+								doh.is("04-04-2011", textboxval, "textboxval should be set" + textboxval);
+								doh.is("04-04-2011", outputval, "textboxval should be set" + outputval);
+								// test a second reset...
+								button.onClick();
+								doh.is((new Date(2011, 3, 4)).getTime(), wid.get("value").getTime(), "wid.get(\"value\") should be set " + wid.get("value"));
+								doh.is("04-04-2011", textboxval, "textboxval should be set" + textboxval);
+								doh.is("04-04-2011", outputval, "textboxval should be set" + outputval);
+								// Test dijit.form.HorizontalSlider
+								button = registry.byId("sliderReset");
+								button.onClick();
+								wid = registry.byId("slidersel");
+								textboxval = registry.byId("slidertext").value;
+								outputval = registry.byId("slideroutput").value;
+								doh.is("5", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.NumberSpinner
+								button = registry.byId("numspinReset");
+								button.onClick();
+								wid = registry.byId("numspinsel");
+								textboxval = registry.byId("numspintext").value;
+								outputval = registry.byId("numspinoutput").value;
+								doh.is("6", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.displayedValue, "wid.displayedValue should be set same as textboxval");
+								doh.is(outputval, wid.displayedValue, "wid.displayedValue should be set same as outputval");
+								// Test dijit.form.SimpleTextarea
+								button = registry.byId("simpTAReset");
+								button.onClick();
+								wid = registry.byId("simpTAsel");
+								textboxval = registry.byId("simpTAtext").value;
+								outputval = registry.byId("simpTAoutput").value;
+								doh.is("7", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.Textarea
+								button = registry.byId("textareaReset");
+								button.onClick();
+								wid = registry.byId("textareasel");
+								textboxval = registry.byId("textareatext").value;
+								outputval = registry.byId("textareaoutput").value;
+								doh.is("8", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+							}
+						}, {
+							name: "Reset-declarative",
+							runTest: function(){
+								var button = registry.byId("decselReset"); // reset the model
+								button.onClick();
+								var wid, textboxval, outputval;
+								// Test Select
+								wid = registry.byId("decsel");
+								textboxval = registry.byId("decseltext").value;
+								outputval = registry.byId("decselOutput").value;
+								doh.is("1", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test FilteringSelect
+								button = registry.byId("decfilReset"); // reset the model
+								button.onClick();
+								wid = registry.byId("decfilsel");
+								textboxval = registry.byId("decfiltext").value;
+								outputval = registry.byId("decfilOutput").value;
+								doh.is("2", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is("two", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.ComboBox
+								button = registry.byId("deccomboReset"); // reset the model
+								button.onClick();
+								wid = registry.byId("deccombosel");
+								textboxval = registry.byId("deccombotext").value;
+								outputval = registry.byId("deccomboOutput").value;
+								doh.is("three", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is("three", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.DateTextBox
+								button = registry.byId("decdateReset"); // reset the model
+								button.onClick();
+								wid = registry.byId("decdatesel");
+								textboxval = registry.byId("decdatetext").value;
+								outputval = registry.byId("decdateOutput").value;
+								doh.is((new Date(2011, 3, 4)).getTime(), wid.get("value").getTime(), "wid.get(\"value\") should be set " + wid.get("value"));
+								doh.is("04-04-2011", textboxval, "textboxval should be set" + textboxval);
+								doh.is("04-04-2011", outputval, "textboxval should be set" + outputval);
+								// Test dijit.form.HorizontalSlider
+								button = registry.byId("decsliderReset"); // reset the model
+								button.onClick();
+								wid = registry.byId("decslidersel");
+								textboxval = registry.byId("decslidertext").value;
+								outputval = registry.byId("decsliderOutput").value;
+								doh.is("5", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.NumberSpinner
+								button = registry.byId("decnumspinReset"); // reset the model
+								button.onClick();
+								wid = registry.byId("decnumspinsel");
+								textboxval = registry.byId("decnumspintext").value;
+								outputval = registry.byId("decnumspinOutput").value;
+								doh.is("6", wid.displayedValue, "wid.displayedValue should be set");
+								doh.is(textboxval, wid.displayedValue, "wid.displayedValue should be set same as textboxval");
+								doh.is(outputval, wid.displayedValue, "wid.displayedValue should be set same as outputval");
+								// Test dijit.form.SimpleTextarea
+								button = registry.byId("decsimpTAReset"); // reset the model
+								button.onClick();
+								wid = registry.byId("decsimpTAsel");
+								textboxval = registry.byId("decsimpTAtext").value;
+								outputval = registry.byId("decsimpTAOutput").value;
+								doh.is("7", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+								// Test dijit.form.Textarea
+								button = registry.byId("dectextareaReset"); // reset the model
+								button.onClick();
+								wid = registry.byId("dectextareasel");
+								textboxval = registry.byId("dectextareatext").value;
+								outputval = registry.byId("dectextareaOutput").value;
+								doh.is("8", wid.get("value"), "wid.get(\"value\") should be set");
+								doh.is(textboxval, wid.get("value"), "wid.get(\"value\") should be set same as textboxval");
+								doh.is(outputval, wid.get("value"), "wid.get(\"value\") should be set same as outputval");
+							}
+						}
+					]);
+
+					// Test reset all declarative
+					doh.register("Test NaN values and bindings", [
+						{
+							name: "NaN-test",
+							runTest: function(){
+								var button = registry.byId("decselReset"); // reset the model
+								button.onClick();
+								var wid, wid2;
+
+								// test for NaN stuff here, uses nanmodel, without fix for ticket 14190 FF crashes
+								wid = registry.byId("nannb");
+								wid.focus();
+								wid2 = registry.byId("textareatext");
+								wid2.focus();
+								wid = registry.byId("nannb");
+								wid.focus();
+								wid2.focus();
+								doh.t(isNaN(wid.get("value")), "isNaN(wid.get(\"value\") should be true");
+							}
+						}
+					]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header" style="margin-top: 0px;">
+				<div id="navigation"  style="margin-top: 0px;"></div>
+				<div id="headerInsert"  style="margin-top: 0px;">
+					<h2>Data-bound Form Element Kitchen Sink MVC test</h2>
+				</div>
+			</div>
+			<div id="main" style="margin-top: 0px;">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+
+					<h2 style="margin-top: 0px;">Programmatic creation of Form elements:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+								<td><label for="sel">Select:</label></td>
+								<td><div id="sel"></div></td>
+								<td><div id="seltext"></div></td>
+								<td><div id="selOutput"></div></td>
+								<td><div id="reset1" ></div></td>
+							</tr>
+							<tr>
+								<td><label for="filsel">FilteringSelect:</label></td>
+								<td><div id="filsel"></div></td>
+								<td><div id="filtext"></div></td>
+								<td><div id="filoutput"></div></td>
+								<td><div id="filreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="combosel">ComboBox:</label></td>
+								<td><div id="combosel"></div></td>
+								<td><div id="combotext"></div></td>
+								<td><div id="combooutput"></div></td>
+								<td><div id="comboreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="datesel">DateTextBox:</label></td>
+								<td><div id="datesel"></div></td>
+								<td><div id="datetext"></div></td>
+								<td><div id="dateoutput"></div></td>
+								<td><div id="datereset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="slidersel">Slider:</label></td>
+								<td><div id="slidersel"></div></td>
+								<td><div id="slidertext"></div></td>
+								<td><div id="slideroutput"></div></td>
+								<td><div id="sliderreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="numspinsel">NumberSpinner:</label></td>
+								<td><div id="numspinsel"></div></td>
+								<td><div id="numspintext"></div></td>
+								<td><div id="numspinoutput"></div></td>
+								<td><div id="numspinreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="simpTAsel">SimpleTextArea:</label></td>
+								<td><div id="simpTAsel"></div></td>
+								<td><div id="simpTAtext"></div></td>
+								<td><div id="simpTAoutput"></div></td>
+								<td><div id="simpTAreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="textareasel">TextArea:</label></td>
+								<td><div id="textareasel"></div></td>
+								<td><div id="textareatext"></div></td>
+								<td><div id="textareaoutput"></div></td>
+								<td><div id="textareareset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="nannb">TextBox nan test:</label></td>
+								<td><div id="nannb"></div></td>
+							</tr>
+						</tbody>
+					</table>
+
+					<h2>Declarative creation of Form elements:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+								<td><label for="decsel">Select:</label></td>
+								<td>
+									<select id="decsel" style="width: 188px;"
+									 data-dojo-id="decsel" data-dojo-type="dijit/form/Select"
+									 data-dojo-props="name: 'decsel', value: at(decselctrl, 'number')">
+										<option value="1">one</option>
+										<option value="2">two</option>
+										<option value="3">three</option>
+										<option value="4">four</option>
+									</select>
+								</td>
+								<td>
+									<input class="cell" id="decseltext" data-dojo-type="dijit/form/TextBox"
+									 data-dojo-props="value: at(decselctrl, 'number')"></input>
+								</td>
+								<td><span id="decselOutput" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(decselctrl, 'number')"></span></td>
+								<td>
+									<button id="decselReset" type="button" data-dojo-type="dijit/form/Button"
+									 data-dojo-props="onClick: function(){decselctrl.reset();}">Reset</button>
+								</td>
+							</tr>
+							<tr>
+								<td><label for="decfilsel">FilteringSelect:</label></td>
+								<td>
+									<input id="decfilsel" data-dojo-type="dijit/form/FilteringSelect"
+									 data-dojo-props="store: store, value: at(decfilctrl, 'number')">
+								</td>
+								<td>
+									<input id="decfiltext" data-dojo-type="dijit/form/TextBox"
+									 data-dojo-props="value: at(decfilctrl, 'number')"></input>
+								</td>
+								<td><span id="decfilOutput" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(decfilctrl, 'number')"></span></td>
+								<td>
+									<button id="decfilReset" type="button" data-dojo-type="dijit/form/Button"
+									 data-dojo-props="onClick: function(){decfilctrl.reset();}">Reset</button>
+								</td>
+							</tr>
+							<tr>
+								<td><label for="deccombosel">ComboBox:</label></td>
+								<td>
+									<input id="deccombosel" data-dojo-type="dijit/form/ComboBox"
+									 data-dojo-props="store: store, value: at(deccomboctrl, 'number')">
+								</td>
+								<td>
+									<input id="deccombotext" data-dojo-type="dijit/form/TextBox"
+									 data-dojo-props="value: at(deccomboctrl, 'number')"></input>
+								</td>
+								<td><span id="deccomboOutput" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(deccomboctrl, 'number')"></span></td>
+								<td>
+									<button id="deccomboReset" type="button" data-dojo-type="dijit/form/Button"
+									 data-dojo-props="onClick: function(){deccomboctrl.reset();}">Reset</button>
+								</td>
+							</tr>
+							<tr>
+								<td><label for="datesel">DateTextBox:</label></td>
+								<td>
+									<input id="decdatesel" data-dojo-type="dijit/form/DateTextBox"
+									 data-dojo-props="store: store, value: at(decdatectrl, 'number'), constraints: dummyDateWid.constraints">
+								</td>
+								<td>
+									<input id="decdatetext" data-dojo-type="dijit/form/TextBox"
+									 data-dojo-props="value: at(decdatectrl, 'number').transform(dummyDateWid.dateLocaleModule),
+									                  constraints: dummyDateWid.constraints"></input>
+								</td>
+								<td>
+									<span id="decdateOutput" data-dojo-type="dojox/mvc/Output"
+									 data-dojo-props="value: at(decdatectrl, 'number').transform(dummyDateWid.dateLocaleModule),
+									                  constraints: dummyDateWid.constraints"></span><!--
+									--></td>
+								<td>
+									<button id="decdateReset" type="button" data-dojo-type="dijit/form/Button"
+									 data-dojo-props="onClick: function(){decdatectrl.reset();}">Reset</button>
+								</td>
+							</tr>
+							<tr>
+								<td><label for="decslidersel">Slider:</label></td>
+								<td>
+									<input id="decslidersel" data-dojo-type="dijit/form/HorizontalSlider"
+									 data-dojo-props="store: store, value: at(decsliderctrl, 'number'),
+									                  style: {width: '190px'},
+									                  minimum: 0,
+									                  maximum: 100,
+									                  discreteValues: 21">
+								</td>
+								<td>
+									<input id="decslidertext" data-dojo-type="dijit/form/TextBox"
+									 data-dojo-props="value: at(decsliderctrl, 'number').transform(dojo.number)">
+								</td>
+								<td>
+									<span id="decsliderOutput" data-dojo-type="dojox/mvc/Output"
+									 data-dojo-props="value: at(decsliderctrl, 'number').transform(dojo.number)"></span><!--
+								--></td>
+								<td>
+									<button id="decsliderReset" type="button" data-dojo-type="dijit/form/Button"
+									 data-dojo-props="onClick: function(){decsliderctrl.reset();}">Reset</button>
+								</td>
+							</tr>
+							<tr>
+								<td><label for="decnumspinsel">NumberSpinner:</label></td>
+								<td>
+									<input id="decnumspinsel" data-dojo-type="dijit/form/NumberSpinner"
+									 data-dojo-props="store:store, value: at(decnumspinctrl, 'number')">
+								</td>
+								<td>
+									<input id="decnumspintext" data-dojo-type="dijit/form/TextBox"
+									 data-dojo-props="value: at(decnumspinctrl, 'number').transform(dojo.number)">
+								</td>
+								<td>
+									<span id="decnumspinOutput" data-dojo-type="dojox/mvc/Output"
+									 data-dojo-props="value: at(decnumspinctrl, 'number').transform(dojo.number)"></span><!--
+								--></td>
+								<td>
+									<button id="decnumspinReset" type="button" data-dojo-type="dijit/form/Button"
+									 data-dojo-props="onClick: function(){decnumspinctrl.reset();}">Reset</button>
+								</td>
+							</tr>
+							<tr>
+								<td><label for="decsimpTAsel">SimpleTextArea:</label></td>
+								<td>
+									<input id="decsimpTAsel" data-dojo-type="dijit/form/Textarea"
+									 data-dojo-props="store:store, value: at(decsimpTActrl, 'number')">
+								</td>
+								<td>
+									<input id="decsimpTAtext" data-dojo-type="dijit/form/TextBox"
+									 data-dojo-props="value: at(decsimpTActrl, 'number')">
+								</td>
+								<td><span id="decsimpTAOutput" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(decsimpTActrl, 'number')"></span></td>
+								<td>
+									<button id="decsimpTAReset" type="button" data-dojo-type="dijit/form/Button"
+									 data-dojo-props="onClick: function(){decsimpTActrl.reset();}">Reset</button>
+								</td>
+							</tr>
+							<tr>
+								<td><label for="dectextareasel">TextArea:</label></td>
+								<td>
+									<input id="dectextareasel" data-dojo-type="dijit/form/Textarea"
+									 data-dojo-props="store:store, value: at(dectextareactrl, 'number')">
+								</td>
+								<td>
+									<input id="dectextareatext" data-dojo-type="dijit/form/TextBox"
+									 data-dojo-props="value: at(dectextareactrl, 'number')">
+								</td>
+								<td><span id="dectextareaOutput" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(dectextareactrl, 'number')"></span></td>
+								<td>
+									<button id="dectextareaReset" type="button" data-dojo-type="dijit/form/Button"
+									 data-dojo-props="onClick: function(){dectextareactrl.reset();}">Reset</button>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+
+					<h2>Test data-bound dijit.Calendar:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+								<td><label for="deccal">Calendar:</label></td>
+								<td>
+									<input class="cell"  id="deccal" data-dojo-id="deccal" data-dojo-type="dijit/Calendar"
+									 data-dojo-props="value: at(deccalctrl, 'date')">
+								</td>
+								<td>
+									<input class="cell" id="deccaltext" data-dojo-type="dijit/form/TextBox"
+									 data-dojo-props="value: at(deccalctrl, 'date').transform(dummyDateWid.dateLocaleModule),
+									                  constraints: dummyDateWid.constraints">
+								</td>
+								<td>
+									<span id="deccalOutput" data-dojo-type="dojox/mvc/Output"
+									 data-dojo-props="value: at(deccalctrl, 'date').transform(dummyDateWid.dateLocaleModule),
+									                  constraints: dummyDateWid.constraints"></span><!--
+								--></td>
+								<td>
+									<button id="deccalReset" type="button" data-dojo-type="dijit/form/Button"
+									 data-dojo-props="onClick: function(){deccalctrl.reset();}">Reset</button>
+								</td>
+							</tr>
+							<tr>
+								<td><label for="deccolor">ColorPalette:</label></td>
+								<td>
+									<div id="deccolor" data-dojo-type="dijit/ColorPalette"
+									 data-dojo-props="palette: '3x4', value: at(deccolorctrl, 'code')">
+									</div>
+								</td>
+								<td>
+									<input class="cell" id="deccolortext" data-dojo-type="dijit/form/TextBox"
+									 data-dojo-props="value: at(deccolorctrl, 'code')"></input>
+								</td>
+								<td><span id="deccolorOutput" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(deccolorctrl, 'code')"></span></td>
+								<td>
+									<button id="deccolorReset" type="button" data-dojo-type="dijit/form/Button"
+									 data-dojo-props="onClick: function(){deccolorctrl.reset();}">Reset</button>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_loan-stateful.html b/dojox/mvc/tests/doh/doh_mvc_loan-stateful.html
new file mode 100644
index 0000000..23dacba
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_loan-stateful.html
@@ -0,0 +1,436 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css">
+
+		<!-- required: dojo.js -->
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: 1, mvc: {debugBindings: 1}"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+
+		<script type="text/javascript" >
+		var lookup, loanModel, validHousingPercentConverter = {
+				format: function(value){
+					return value <= 33;
+				}
+			}, nonZeroRelevanceConverter = {
+				format: function(value){
+					return value <= 0;
+				}
+			};
+
+		require([
+				"doh/runner",
+				"dojo/_base/declare",
+				"dojo/dom",
+				"dojo/_base/array",
+				"dojo/_base/lang",
+				"dojo/request/xhr",
+				"dojo/parser",
+				"dojo/when",
+				"dijit/registry",				
+				"dojox/charting/Chart",
+				"dojox/charting/themes/PlotKit/blue",
+				"dojox/mvc/at",
+				"dojo/Stateful",
+				"dojox/mvc/StatefulSeries",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dijit/form/ValidationTextBox",
+				"dijit/form/NumberTextBox",
+				"dojox/charting/plot2d/Pie",
+				"dojox/mvc/_TextBoxExtensions",
+				"dojox/mvc/Group",
+				"dojox/mvc/ModelRefController",
+				"dojox/mvc/Output",
+				"dojo/domReady!"
+			], function(doh, declare, ddom, array, lang, dxhr, parser, when, registry, Chart, blue, at, Stateful, StatefulSeries){
+
+				lookup = function(model){
+					if(isNaN(model.get("Zip"))){ return; }
+					dxhr.get("../zips/" + model.get("Zip") + ".json", {
+						content: {postalcode: model.get("Zip"), country: model.get("County")},
+						preventCache: true,
+						handleAs: "json"
+					}).then(function(data){
+						model.set("City", data.postalcodes[0].placeName);
+						model.set("County", data.postalcodes[0].adminName2);
+						model.set("State", data.postalcodes[0].adminCode1);
+						model.set("isZipValid", true);
+					}, function(e){
+						model.set("City", "");
+						model.set("County", "");
+						model.set("State", "");
+						model.set("isZipValid", false);
+					});	
+				};
+
+				function getNewValue(model, prop, name, value){
+					return prop == name ? value : model.get(prop);
+				}
+
+				function recomputeTotalAndPercentages(model, name, value){
+					var mortgage = getNewValue(model, "Mortgage", name, value);
+					var taxes = getNewValue(model, "Taxes", name, value);
+					var otherHousing = getNewValue(model, "OtherHousing", name, value);
+					var totalHousing = mortgage + taxes + otherHousing;
+			
+					var baseIncome = getNewValue(model, "BaseIncome", name, value);
+					var bonusIncome = getNewValue(model, "BonusIncome", name, value);
+					var totalIncome = baseIncome + bonusIncome;
+			
+					var housingPercentage = Math.round(totalHousing / totalIncome * 100);
+			
+					model.set("HousingPercent", housingPercentage);
+					model.set("TotalHousing", totalHousing);
+					model.set("TotalIncome", totalIncome);
+			
+					model[name] = value;
+				}
+
+				loanModel = new Stateful({
+					Name: "John Doe",
+					Street: "",
+					City: "",
+					County: "",
+					State: "",
+					Zip: "",
+					Country: "US",
+					TotalIncome: 0,
+					BaseIncome: 50000,
+					BonusIncome: 10000,
+					TotalHousing: 2700,
+					HousingPercent: 5,
+					Mortgage: 1000,
+					Taxes: 500,
+					OtherHousing: 1200,
+					_MortgageSetter: function(value){
+						recomputeTotalAndPercentages(this, "Mortgage", value);
+					},
+					_TaxesSetter: function(value){
+						recomputeTotalAndPercentages(this, "Taxes", value);
+					},
+					_OtherHousingSetter: function(value){
+						recomputeTotalAndPercentages(this, "OtherHousing", value);
+					},
+					_BaseIncomeSetter: function(value){
+						recomputeTotalAndPercentages(this, "BaseIncome", value);
+					},
+					_BonusIncomeSetter: function(value){
+						recomputeTotalAndPercentages(this, "BonusIncome", value);
+					}
+				});
+
+				when(parser.parse(), function(){
+					new Chart("expenseChart")
+					 .setTheme(blue)
+					 .addPlot("default", {type: "Pie"})
+					 .addSeries("default", new StatefulSeries([at(loanModel, "Mortgage"), at(loanModel, "Taxes"), at(loanModel, "OtherHousing")])).render();
+
+					 // should be able to verify all of the inputs
+					doh.register("Check values and bindings", [
+						{
+							name: "Initial",
+							runTest: function(){
+								doh.is("5", registry.byId("percentHousing").get('value'),"percentHousing should be 5");
+								doh.is(true, registry.byId("percentHousing").isValid(), "isValid()","percentHousing should be valid");
+								doh.is("1000", registry.byId("housing").get('value'),"housing should be 1000");
+								doh.is("2700", registry.byId("totalHousing").get('value'),"totalHousing should be 2700");
+							}
+						}, {
+							name: "setZipTest",
+							runTest: function(){
+								registry.byId("zipInput").focus();
+								registry.byId("zipInput").set('value', "11111");
+								var dfd = new doh.Deferred();
+								setTimeout(function(){
+									try{
+										registry.byId("cityInput").focus();
+									}catch(e){
+										return dfd.errback(e);
+									}
+									setTimeout(function(){
+										try{
+											doh.t(/^\s*$/.test(registry.byId("cityInput").get('value')), "bad zip should not display the city");
+											doh.is(false, registry.byId("zipInput").isValid(), "zipInput should be invalid");
+											// now try a good one
+											registry.byId("zipInput").focus();
+											registry.byId("zipInput").set('value', "10706");
+											registry.byId("cityInput").focus();
+										}catch(e){
+											return dfd.errback(e);
+										}
+										setTimeout(function(){
+											try{
+												doh.is("Hastings On Hudson", registry.byId("cityInput").get('value'),"good zip 10706 should display the city");
+												return dfd.callback(true);
+											}catch(e){
+												return dfd.errback(e);
+											}
+										}, 2000);							
+									}, 2000);
+								}, 1000);
+								return dfd;							
+							},
+							timeout: 10000
+						}, {
+							name: "setMortgageTest",
+							runTest: function(){
+								registry.byId("housing").focus();
+								registry.byId("housing").set('value', "10000");
+								registry.byId("totalHousing").focus();
+								var dfd = new doh.Deferred();
+								setTimeout(function(){
+									try{
+										doh.is("20", registry.byId("percentHousing").get('value'),"percentHousing should be 5");
+										doh.is(true, registry.byId("percentHousing").isValid(), "isValid()","percentHousing should be valid");
+										doh.is("10000", registry.byId("housing").get('value'),"housing should be 10000");
+										doh.is("11700", registry.byId("totalHousing").get('value'),"totalHousing should be 11700");
+										dfd.callback(true);
+									}catch(e){
+										dfd.errback(e);
+									}
+								}, 500);
+								return dfd;
+							}
+						}, {
+							name: "setMortgageTest2",
+							runTest: function(){
+								registry.byId("housing").focus();
+								registry.byId("housing").set('value', "20000");
+								registry.byId("totalHousing").focus();
+								var dfd = new doh.Deferred();
+								setTimeout(function(){
+									try{
+										doh.is("36", registry.byId("percentHousing").get('value'),"percentHousing should be 5");
+										doh.is(false, registry.byId("percentHousing").isValid(), "isValid()","percentHousing should not be valid");
+										doh.is("20000", registry.byId("housing").get('value'),"housing should be 10000");
+										doh.is("21700", registry.byId("totalHousing").get('value'),"totalHousing should be 11700");
+										return dfd.callback(true);
+									}catch(e){
+										return dfd.errback(e);
+									}
+								}, 500);
+								return dfd;
+							}
+						}, {
+							name: "setHousingZero",
+							runTest: function(){
+								registry.byId("housing").focus();
+								registry.byId("housing").set('value', "0");
+								registry.byId("taxes").focus();
+								registry.byId("taxes").set('value', "0");
+								registry.byId("otherHousing").focus();
+								registry.byId("otherHousing").set('value', "0");
+								registry.byId("totalHousing").focus();
+								var dfd = new doh.Deferred();
+								setTimeout(function(){
+									try{
+										doh.is("0", registry.byId("housing").get('value'),"housing should be 0");
+										doh.is("0", registry.byId("taxes").get('value'),"taxes should be 0");
+										doh.is("0", registry.byId("otherHousing").get('value'),"otherHousing should be 0");
+										doh.is("0", registry.byId("totalHousing").get('value'),"totalHousing should be 0");
+										doh.is(true, registry.byId("totalHousing").get("disabled"), "disabled()","totalHousing should be disabled");
+										doh.is(true, registry.byId("percentHousing").get("disabled"), "disabled()","percentHousing should disabled");
+										doh.is("0", registry.byId("percentHousing").get('value'),"percentHousing should be 5");
+										doh.is(true, registry.byId("percentHousing").isValid(), "isValid()","percentHousing should be valid");
+										return dfd.callback(true);
+									}catch(e){
+										return dfd.errback(e);
+									}
+								}, 500);
+								return dfd;
+							}
+						}, {
+							name: "setHousingBack",
+							runTest: function(){
+								registry.byId("housing").focus();
+								registry.byId("housing").set('value', "1000");
+								registry.byId("taxes").focus();
+								registry.byId("taxes").set('value', "500");
+								registry.byId("otherHousing").focus();
+								registry.byId("otherHousing").set('value', "1200");
+								registry.byId("totalHousing").focus();
+								var dfd = new doh.Deferred();
+								setTimeout(function(){
+									try{
+										doh.is("5", registry.byId("percentHousing").get('value'),"percentHousing should be 5");
+										doh.is(true, registry.byId("percentHousing").isValid(), "isValid()","percentHousing should be valid");
+										doh.is("1000", registry.byId("housing").get('value'),"housing should be 1000");
+										doh.is("2700", registry.byId("totalHousing").get('value'),"totalHousing should be 2700");
+										doh.is(false, registry.byId("totalHousing").get("disabled"), "disabled()","totalHousing should be disabled");
+										doh.is(false, registry.byId("percentHousing").get("disabled"), "disabled()","percentHousing should disabled");
+										doh.is(true, registry.byId("percentHousing").isValid(), "isValid()","percentHousing should be valid");
+										return dfd.callback(true);
+									}catch(e){
+										return dfd.errback(e);
+									}
+								}, 500);
+								return dfd;
+							}
+						}
+					]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro" style="background-image: url(../images/validating_form_pattern.png)">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<h1 class="testTitle">doh_mvc_loan-stateful.html automated tests (non-robot)</h1>
+		<div id="wrapper">
+			<div id="addressLookupController" class="dijitDisplayNone" data-dojo-type="dojox.mvc.ModelRefController"
+			 data-dojo-props="model: loanModel, ownProps: {_setZipAttr: 1, _setCountyAttr: 1}">
+				<script type="dojo/method" event="_setZipAttr" args="value">
+					var changed = this.model.Zip != value;
+					this.model._changeAttrValue("Zip", value);
+					if(changed){
+						lookup(this.model);
+					}
+					return this;
+				</script>
+				<script type="dojo/method" event="_setCountyAttr" args="value">
+					var changed = this.model.County != value;
+					this.model._changeAttrValue("County", value);
+					if(changed){
+						lookup(this.model);
+					}
+					return this;
+				</script>
+			</div>
+			<div id="header">
+				<div id="navigation">
+				</div>
+				<div id="headerInsert">
+					<h1>Big Red Loan</h1>
+					<h2>The one to choose when you're in the red...</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('widget:addressLookupController')">
+					<h3>Borrower information</h3>
+					<hr size="6" class="rule"/>
+					<div class="spacer"></div>
+					<div class="row">
+						<div class="cell"><label for="borrowerInput">Name:</label></div>
+						<div class="cell">
+							<input id="borrowerInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Name')"/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label for="zipInput">Zipcode (try 10706):</label></div>
+						<div class="cell">
+							<input id="zipInput" data-dojo-type="dijit.form.NumberTextBox"
+							 data-dojo-props="value: at('rel:', 'Zip'), valid: at('rel:', 'isZipValid')"
+							 constraints="{pattern:'#'}" regExp="\d{5}" required="true" invalidMessage="Invalid Zip Code."/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label for="cityInput">City:</label></div>
+						<div class="cell">
+							<input id="cityInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'City')"/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label for="countyInput">County:</label></div>
+						<div class="cell">
+							<input id="countyInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'County')"/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label for="stateInput">State:</label></div>
+						<div class="cell">
+							<input id="stateInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'State')"/>
+						</div>
+					</div>
+					<div class="spacer"></div>
+					<h3>Expenses</h3>
+					<hr size="6" class="rule"/>
+					<div class="spacer"></div>
+					<table style="width:900px;">
+						<tr style="width:900px;">
+							<td style="width:400px;">
+								<div class="row">
+									<div class="cell"><label for="housing">Mortgage:</label></div>
+									<div class="cell">
+										<input id="housing" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="value: at('rel:', 'Mortgage')"/>
+									</div>
+								</div>
+								<div class="row">
+									<div class="cell">
+										<label>Real Estate Taxes:</label>
+									</div>
+									<div class="cell">
+										<input id="taxes" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="value: at('rel:', 'Taxes')"/>
+									</div>
+								</div>
+								<div class="row">
+									<div class="cell"><label>Other Housing:</label></div>
+									<div class="cell">
+										<input id="otherHousing" type="text" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="value: at('rel:', 'OtherHousing')"/>
+									</div>
+								</div>
+								<div class="row">
+									<div class="cell"><label for="transportation">Total Housing:</label></div>
+									<div class="cell">
+										<input id="totalHousing" data-dojo-type="dijit.form.NumberTextBox"
+										 data-dojo-props="value: at('rel:', 'TotalHousing'),
+										                  disabled: at('rel:', 'TotalHousing').direction(at.from).transform(nonZeroRelevanceConverter)"/>
+									</div>
+								</div>
+							</td>
+							<td style="width:200px;">
+								<div id="expenseChart" width="150" height="150" style="display:block; width: 150px; height: 150px;"></div>
+							</td>
+						</tr>
+					</table>
+					<h3>Income</h3>
+					<hr size="6" class="rule"/>
+					<div class="spacer"></div>
+					<div class="row">
+						<div class="cell"><label for="baseIncome">Base Income:</label></div>
+						<div class="cell">
+							<input id="baseIncome" type="text" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="value: at('rel:', 'BaseIncome')"/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label>Bonus Income:</label></div>
+						<div class="cell">
+							<input id="bonusIncome" type="text" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="value: at('rel:', 'BonusIncome')"/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label for="total">Total Income:</label></div>
+						<div class="cell">
+							<input id="total" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="value: at('rel:', 'TotalIncome')"/>
+						</div>
+					</div>
+					<h3>Analysis</h3>
+					<hr size="6" class="rule"/>
+					<div class="spacer"></div>
+					<div class="row">
+						<div class="cell"><label for="percentHousing">Percent housing (under 33%):</label></div>
+						<div class="cell">
+							<input id="percentHousing" data-dojo-type="dijit.form.NumberTextBox"
+							 data-dojo-props="value: at('rel:', 'HousingPercent'),
+							                  valid: at('rel:', 'HousingPercent').direction(at.from).transform(validHousingPercentConverter),
+							                  disabled: at('rel:', 'HousingPercent').direction(at.from).transform(nonZeroRelevanceConverter)"
+							 invalidMessage="Housing should be less than 1/3 total expenses!"/>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_mobile-demo.html b/dojox/mvc/tests/doh/doh_mvc_mobile-demo.html
new file mode 100644
index 0000000..4624262
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_mobile-demo.html
@@ -0,0 +1,344 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH MVC Mobile Demo Test</title>
+		<link rel="stylesheet" type="text/css" href="../1.7/mobile/demo/demo.css"/>
+		<style>
+			html, body{
+				height: 100%;
+				overflow: hidden;
+				position: relative;
+			}
+			.mblEdgeToEdgeList {
+				background-color: #DBDDE2;
+			}
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1, mvc: {debugBindings: 1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			var ctrl, listCtrl;
+			var updateView, updateModel;
+
+			require([
+				"doh/runner",
+				"dojo/_base/declare",
+				"dojo/_base/json",
+				"dojo/when",
+				"dojo/dom",
+				"dojo/store/JsonRest",
+				"dojo/store/Memory",
+				"dijit/registry",
+				"dojox/mobile/parser",
+				"dojox/mvc/getPlainValue",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/EditModelRefController",
+				"dojox/mvc/ListController",
+				"dojox/mvc/StoreRefController",
+				"dojox/mvc/at",
+				"dojox/mobile",
+				"dojox/mobile/compat",
+				"dojox/mobile/ScrollableView",
+				"dojox/mobile/Button",
+				"dojox/mobile/TextArea",
+				"dojox/mobile/TextBox",
+				"dojox/mobile/ViewController",
+				"dojox/mobile/FixedSplitter",
+				"dojox/mobile/EdgeToEdgeList",
+				"dojox/mobile/EdgeToEdgeCategory",
+				"dojox/mobile/deviceTheme",
+				"dojox/mobile/RoundRectCategory",
+				"dojox/mobile/Heading",
+				"dojox/mvc/Group",
+				"dojox/mvc/Generate",
+				"dojox/mvc/Repeat",
+				"dojo/domReady!"
+			], function(doh, declare, djson, when, ddom, JsonRest, Memory, registry, parser, getPlainValue, getStateful, EditModelRefController, ListController, StoreRefController, at){
+				window.at = at;
+
+				ctrlClass = declare([EditModelRefController, ListController], {});
+				ctrl = new ctrlClass({sourceModel: getStateful({
+					Serial: "360324",
+					First: "John",
+					Last: "Doe",
+					Email: "jdoe at us.ibm.com",
+					ShipTo: {
+						Street: "123 Valley Rd",
+						City: "Katonah",
+						State: "NY",
+						Zip: "10536"
+					},
+					BillTo: {
+						Street: "17 Skyline Dr",
+						City: "Hawthorne",
+						State: "NY",
+						Zip: "10532"
+					}
+				})});
+				ctrl.set("cursorIndex", "ShipTo");
+
+				// used in the Generate View demo
+				var genmodel;
+				updateView = function() {
+					try {
+						genmodel = getStateful(djson.fromJson(ddom.byId("modelArea").value));
+						registry.byId("view").set("children", genmodel);
+						ddom.byId("outerModelArea").style.display = "none";
+						ddom.byId("viewArea").style.display = "";
+					}catch(err){
+						console.error("Error parsing json from model: "+err);
+					}
+				};
+
+				// used in the Generate View demo
+				updateModel = function() {
+					ddom.byId("outerModelArea").style.display = "";
+					try {
+						ddom.byId("modelArea").focus(); // hack: do this to force focus off of the textbox, bug on mobile?
+						ddom.byId("viewArea").style.display = "none";
+						registry.byId("modelArea").set("value", djson.toJson(getPlainValue(genmodel), true));
+					} catch(e) {
+						console.log(e);
+					};
+				};
+
+				var listCtrlClass = declare([StoreRefController, EditModelRefController, ListController], {
+					addEmpty: function(){
+						var modelToInsert = getStateful({
+							First: "",
+							Last: "",
+							Location: "CA",
+							Office: "",
+							Email: "",
+							Tel: "",
+							Fax: ""
+						});
+						this.model.push(modelToInsert);
+						this.set("cursor", modelToInsert);
+					}
+				});
+
+				listCtrl = new listCtrlClass({cursorIndex: 0});
+
+				parser.parse();
+				ddom.byId("wholepage").style.display = "";
+
+				when((new JsonRest({target: require.toUrl("dojox/mvc/tests/_data/mvcRepeatData.json")})).query({}), function(results){
+					listCtrl.set("store", new Memory({data: results.items}));
+					when(listCtrl.queryStore({Location: "CA"}), function(results){
+						doh.register("Ship to - Bill to Address page", [{
+							name: "Initial",
+							runTest: function(){
+								registry.byId("settings").show();
+								doh.is("360324", registry.byId("serialInput").get("value"), "Order# should be set");
+								doh.is("123 Valley Rd", registry.byId("streetInput").get("value"), "Street should be set of Ship To");
+							}
+						}, {
+							name: "TestBillTo",
+							runTest : function(){
+								ctrl.set("cursorIndex", "BillTo");
+								doh.is("17 Skyline Dr", registry.byId("streetInput").get("value"), "Street should be set of Bill To");
+							}
+						}, {
+							name: "TestReset",
+							runTest: function(){
+								var addr1 = registry.byId("streetInput");
+								addr1.set("value", "Foo");
+								doh.is("Foo", ctrl.get("Street"), "Street should be Foo");
+								ctrl.reset();
+								doh.is("17 Skyline Dr", addr1.get("value"), "Street should be set back to of Bill To");
+							}
+						}]);
+
+						doh.register("Repeat Data Binding Example page", [{
+							name: "Initial",
+							runTest: function(){
+								registry.byId("repeat").show();
+								doh.is("Chad", registry.byId("nameInput0").get("value"), "nameInput0 should be Chad");
+								doh.is("Hunter", registry.byId("nameInput1").get("value"), "nameInput1 should be Hunter");
+								doh.is("John", registry.byId("nameInput2").get("value"), "nameInput2 should be John");
+							}
+						}, {
+							name: "ChangeCursor",
+							runTest: function(){
+								listCtrl.set("cursorIndex", 1);
+								doh.is("Hunter", registry.byId("firstnameInputDetail").get("value"), "firstnameInputDetail should be Hunter");
+							}
+						}, {
+							name : "ResetAll",
+							runTest : function(){
+								var first = registry.byId("firstnameInputDetail");
+								first.set("value", "Foo");
+								doh.is("Foo", listCtrl.get("First"), "First should be Foo");
+								listCtrl.reset();
+								doh.is("Hunter", registry.byId("firstnameInputDetail").get("value"), "firstnameInputDetail should be Hunter");
+							}
+						}]);
+
+						doh.register("Simple Form Generate Example page", [{
+							name: "Initial",
+							runTest: function(){
+								registry.byId("generate").show();
+								updateView();
+								var tb0 = registry.byId("TB0");
+								doh.is("11111", tb0 && tb0.get("value"), "Serial should be 11111");
+								var tb6 = registry.byId("TB6");
+								doh.is("111-111-1111", tb6 && tb6.get("value"), "Office should be 111-111-1111");
+								tb6.set("value", "333-333-3333");
+								updateModel();
+								doh.t(ddom.byId("modelArea").value.indexOf("\"Office\": \"333-333-3333\""), "Model should be updated with newer Office phone number");
+							}
+						}]);
+
+						doh.run();
+					});
+				});
+			}); // end function
+		</script>
+	</head>
+	<body>
+		<div id="wholepage" style="display:none">
+			<div id="foo" data-dojo-type="dojox.mobile.View" selected="true">
+				<h1 data-dojo-type="dojox.mobile.Heading">Mobile MVC Demo</h1>
+				<h2 data-dojo-type="dojox.mobile.RoundRectCategory">Mobile MVC Views</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li id="sdb" data-dojo-type="dojox.mobile.ListItem" icon="../1.7/mobile/demo/images/i-icon-1.png" transition="slide" moveTo="settings">
+						Simple Data Binding
+					</li>
+					<li id="rdb" data-dojo-type="dojox.mobile.ListItem" icon="../1.7/mobile/demo/images/i-icon-2.png" transition="slide" moveTo="repeat">
+						Repeat Data Binding
+					</li>
+					<li id="sfg" data-dojo-type="dojox.mobile.ListItem" icon="../1.7/mobile/demo/images/i-icon-3.png" transition="slide" moveTo="generate">
+						Simple Form Generate
+					</li>
+				</ul>
+			</div>
+			<div id="settings" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 id="home" data-dojo-type="dojox.mobile.Heading" back="Home" moveTo="foo">Data Binding Example</h1>
+				<form name="testForm" id="testForm">
+				<div class="field-title">Ship to - Bill to Address</div>
+					<div class="fieldset" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model')">
+						<div class="field-row">
+							<span>Order #</span>
+							<input id="serialInput" placeholder="Order #" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Serial')" />
+						</div>
+						<div class="field-row">
+							<span>Last</span>
+							<input placeholder="Last" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Last')" />
+						</div>
+						<div class="field-row">
+							<span>Email</span>
+							<input placeholder="Last" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Email')" />
+						</div>
+					</div>
+					<div class="spacer"></div>
+					<button id="shipto" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="ctrl.set('cursorIndex', 'ShipTo');">Ship To</button>
+					<button id="billto" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="ctrl.set('cursorIndex', 'BillTo');">Bill To</button>
+					<br/>
+					<div class="fieldset" id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'cursor')">
+						<div class="field-row">
+							<span>Street</span>
+							<input id="streetInput" placeholder="Street" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Street')" />
+						</div>
+						<div class="field-row">
+							<span>City</span>
+							<input placeholder="City" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'City')" />
+						</div>
+						<div class="field-row">
+							<span>State</span>
+							<input placeholder="State" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'State')" />
+						</div>
+						<div class="field-row">
+							<span>ZIP Code</span>
+							<input placeholder="ZIP Code" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Zip')" />
+						</div>
+					</div>
+					<div class="spacer"></div>
+					<button id="reset1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="ctrl.reset()">Reset</button>
+				</form>
+			</div>
+			<div id="repeat" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" back="Home" moveTo="foo">Repeat Data Binding Example</h1>
+				<form name="repeatTestForm" id="repeatTestForm">
+					<div class="field-title">Search Results</div>
+					<div class="fieldset" class="row" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at(listCtrl, 'model')">
+						<div data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', '${this.index}')">
+							<div class="row">
+								<input id="nameInput${this.index}" placeHolder="First Name" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'First')" />
+								<button id="details${this.index}" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="listCtrl.set('cursorIndex', '${this.index}')">Details</button>
+							</div>
+						</div>
+					</div>
+					<div class="spacer"></div>
+					<div id="detailsBanner">Details for selected index:</div>
+					<div class="fieldset" id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(listCtrl, 'cursor')">
+						<div class="field-row">
+							<span>First Name</span>
+							<input id="firstnameInputDetail" placeholder="First Name" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'First')" />
+						</div>
+						<div class="field-row">
+							<span>Last Name</span>
+							<input placeholder="Last Name" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Last') "/>
+						</div>
+						<div class="field-row">
+							<span>Email</span>
+							<input placeholder="Email" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Email')" />
+						</div>
+						<div class="field-row">
+							<span>Telephone</span>
+							<input placeholder="Telephone" data-dojo-type="dojox.mobile.TextBox" data-dojo-props="value: at('rel:', 'Tel')" />
+						</div>
+					</div>
+					<div class="spacer"></div>
+					<button id="add" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="listCtrl.addEmpty();">Add</button>
+					<button id="save" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="listCtrl.commit();">Save</button>
+					<button id="reset2" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="listCtrl.reset();">Reset</button>
+				</form>
+			</div>
+			<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
+				<h1 data-dojo-type="dojox.mobile.Heading" back="Home" moveTo="foo">Simple Form Generate Example</h1>
+				<div class="field-title"></div>
+					<div id="main">
+						<div id="leftNav"></div>
+						<div id="mainContent" class="generate-maincontent">
+							<div id="outerModelArea">
+								<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Model</h3>
+								<div class="generate-textarea-row">
+									<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
+{
+	"Serial": "11111",
+	"First": "John",
+	"Last": "Doe",
+	"Email": "jdoe at example.com",
+	"Phones": [
+		{
+			"Office": "111-111-1111"
+		},
+		{
+			"Mobile": "222-222-2222"
+		}
+	]
+}
+									</textarea>
+								</div>
+								<div class="fieldset">
+									<div class="spacer"></div>
+									<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
+								</div>
+							</div>
+							<div id="viewArea" style="display:none">
+								<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Generated View</h3>
+									<div class="fieldset">
+									<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping: {'String': 'dojox.mobile.TextBox'}, idNameMapping: {'String' : 'TB'}"></div>
+								</div>
+								<div class="fieldset">
+									<div class="spacer"></div>
+									<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_new_ref-set-repeat.html b/dojox/mvc/tests/doh/doh_mvc_new_ref-set-repeat.html
new file mode 100644
index 0000000..277107a
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_new_ref-set-repeat.html
@@ -0,0 +1,229 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+		</style>
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: true, mvc: {debugBindings: true}"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+		<script type="text/javascript">
+			var ctrl, data1, data2, data3;
+
+			require([
+				"doh/runner",
+				"dojo/_base/array",
+				"dojo/_base/lang",
+				"dojo/when",
+				"dojo/parser",
+				"dojo/store/Memory",
+				"dijit/registry",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/ModelRefController",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Repeat",
+				"dojo/domReady!"
+			], function(doh, array, lang, when, parser, MemoryStore, registry, getStateful, ModelRefController){
+
+				function runTests(){
+					doh.register("Tests", [
+						{
+							name : "initial",
+							runTest : function() {
+								ctrl.set("model", ctrl.get("model1"));
+								doh.is("Anne1", registry.byId("nameInput0").get("value"), "nameInput0 should be Anne1");
+								doh.is("Ben1", registry.byId("nameInput1").get("value"), "nameInput1 should be Ben1 ");
+								doh.is("Chad1", registry.byId("nameInput2").get("value"), "nameInput2 should be Chad1");
+								doh.is("Anne1", registry.byId("firstnameOutput10").get("value"), "firstnameOutput10 should be Anne1");
+								doh.is("Ben1", registry.byId("firstnameOutput11").get("value"), "firstnameOutput11 should be Ben1 ");
+								doh.is("Chad1", registry.byId("firstnameOutput12").get("value"), "firstnameOutput12 should be Chad1");
+								doh.is("Anne2", registry.byId("firstnameOutput20").get("value"), "firstnameOutput20 should be Anne2");
+								doh.is("Ben2", registry.byId("firstnameOutput21").get("value"), "firstnameOutput21 should be Ben2 ");
+								doh.is("", registry.byId("firstnameOutput30").get("value"), "firstnameOutput30 should be blank");
+							}
+						}, {
+							name : "SelectModel2",
+							runTest : function() {
+								ctrl.set("model", ctrl.get("model2"));
+								doh.is("Anne2", registry.byId("nameInput0").get("value"), "nameInput0 should be Anne2");
+								doh.is("Ben2", registry.byId("nameInput1").get("value"), "nameInput1 should be Ben2 ");
+							}
+						}, {
+							name : "ChangeModel2",
+							runTest : function() {
+								registry.byId("nameInput0").set("value", "Anne2-Update");
+								doh.is("Anne2-Update", registry.byId("nameInput0").get("value"), "nameInput0 should be Anne2-Update");
+								doh.is("Ben2", registry.byId("nameInput1").get("value"), "nameInput1 should be Ben2 ");
+								doh.is("Anne2-Update", registry.byId("firstnameOutput20").get("value"), "firstnameOutput20 should be Anne2-Update");
+								doh.is("Ben2",  registry.byId("firstnameOutput21").get("value"), "firstnameOutput21 should be Ben2 ");
+							}
+						}, {
+							name : "SelectModel3",
+							runTest : function() {
+								ctrl.set("model", ctrl.get("model3"));
+								doh.is("", registry.byId("nameInput0").get("value"), "nameInput0 should be blank");
+							}
+						}, {
+							name : "ChangeModel3",
+							runTest : function() {
+								registry.byId("nameInput0").set("value", "Anne3-Update");
+								doh.is("Anne3-Update", registry.byId("nameInput0").get("value"), "nameInput0 should be Anne3-Update");
+								doh.is("Anne3-Update", registry.byId("firstnameOutput30").get("value"), "firstnameOutput30 should be Anne3-Update");
+							}
+						}, {
+							name : "UpdateData1",
+							runTest : function() {
+								var newdata = {
+									"Results": [
+										{
+											"First": "Anne1x",
+											"Last": "Ackerman1x"
+										},
+										{
+											"First": "Ben1x",
+											"Last": "Beckham1x"
+										}
+									]
+								};
+								ctrl.set("model", newdata);
+								doh.is("Anne1x", registry.byId("nameInput0").get("value"), "nameInput0 should be Anne1X");
+							}
+						}
+					]);
+
+					doh.run();
+				}
+
+				ctrl = new ModelRefController({ownProps: {model1: 1, model2: 1, model3: 1}});
+
+				when(parser.parse(), function(){
+					when((new MemoryStore({data: data1 = [
+						{
+							"Query": "Engineers1",
+							"Results": [
+								{
+									"First": "Anne1",
+									"Last": "Ackerman1"
+								},
+								{
+									"First": "Ben1",
+									"Last": "Beckham1"
+								},
+								{
+									"First": "Chad1",
+									"Last": "Chapman1"
+								}
+							]
+						}
+					]})).query(), function(data){
+						ctrl.set("model1", getStateful(data)[0]);
+						if(ctrl.get("model1") && ctrl.get("model2") && ctrl.get("model3")){ runTests(); }
+					});
+
+					when((new MemoryStore({data: data2 = [
+						{
+							"Query": "Engineers2",
+							"Results": [
+								{
+									"First": "Anne2",
+									"Last": "Ackerman2"
+								},
+								{
+									"First": "Ben2",
+									"Last": "Beckham2"
+								}
+							]
+						}
+					]}).query()), function(data){
+						ctrl.set("model2", getStateful(data)[0]);
+						if(ctrl.get("model1") && ctrl.get("model2") && ctrl.get("model3")){ runTests(); }
+					});
+
+					when((new MemoryStore({data: data3 = [
+						{
+							"Query": "Engineers3",
+							"Results": [
+								{
+									"First": "",
+									"Last": ""
+								}
+							]
+						}
+					]}).query()), function(data){
+						ctrl.set("model3", getStateful(data)[0]);
+						if(ctrl.get("model1") && ctrl.get("model2") && ctrl.get("model3")){ runTests(); }
+					});
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at(ctrl, 'Results')">
+						<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:${this.index}')">
+							<label class="cell" for="nameInput${this.index}">Name:</label>
+							<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="value: at('rel:', 'First')"/>
+						</div>
+					</div>
+					<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model1')">
+						<div data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Results')">
+							<span>
+								Model1 Output is ==> 
+							</span>
+							<span id="firstnameOutput10" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:0', 'First')">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput11" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:1', 'First')">
+								Name2 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput12" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:2', 'First')">
+								Name3 is "${this.value}"
+							</span>
+						</div>
+					</div>
+					<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model2')">
+						<div data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Results')">
+							<span>
+								Model2 Output is ==>
+							</span>
+							<span id="firstnameOutput20" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:0', 'First')">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput21" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:1', 'First')">
+								Name2 is "${this.value}"
+							</span>
+						</div>
+					</div>
+					<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model3')">
+						<div data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Results')">
+							<span>
+								Model3 Output is ==>
+							</span>
+							<span id="firstnameOutput30" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:0', 'First')">
+								Name1 is "${this.value}"
+							</span>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_new_shipto-billto-simple.html b/dojox/mvc/tests/doh/doh_mvc_new_shipto-billto-simple.html
new file mode 100644
index 0000000..7238393
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_new_shipto-billto-simple.html
@@ -0,0 +1,173 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1, mvc: {debugBindings: 1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			var ctrl, ctrlDetail, model, data;
+
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dojo/when",
+				"dojo/Stateful",
+				"dijit/registry",
+				"dojox/mvc/at",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/ModelRefController",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output"
+			], function(doh, parser, when, Stateful, registry, at, getStateful, ModelRefController){
+
+				ctrl = new ModelRefController();
+				ctrlDetail = new ModelRefController();
+
+				when(parser.parse(), function(){
+					data = {
+						"Serial": "360324",
+						"First": "John",
+						"Last": "Doe",
+						"Email": "jdoe at example.com",
+						"ShipTo": {
+							"Street": "123 Valley Rd-ShipTo",
+							"City": "Katonah",
+							"State": "NY",
+							"Zip": "10536"
+						},
+						"BillTo": {
+							"Street": "17 Skyline Dr-BillTo",
+							"City": "Hawthorne",
+							"State": "NY",
+							"Zip": "10532"
+						}
+					};
+
+					ctrl.set("model", getStateful(data));
+					ctrlDetail.set("model", ctrl.model.get("ShipTo"));
+
+					doh.register("Switch between ShipTo and BillTo", [{
+						name: "Switch-to-BillTo",
+						runTest: function(){
+							ctrlDetail.set("model", ctrl.model.get("BillTo"));
+							doh.is("17 Skyline Dr-BillTo", registry.byId("streetInput").get("value"), "Street should be of BillTo");
+							doh.is("Hawthorne", registry.byId("cityInput").get("value"), "City should be of BillTo");
+						}
+					}, {
+						name: "Switch-to-ShipTo",
+						runTest: function(){
+							ctrlDetail.set("model", ctrl.model.get("ShipTo"));
+							doh.is("123 Valley Rd-ShipTo", registry.byId("streetInput").get("value"), "Street should be of ShipTo");
+							doh.is("Katonah", registry.byId("cityInput").get("value"), "City should be of ShipTo");
+						}
+					}]);
+
+					doh.register("Setting a plain object to group", [{
+						name: "Switch-to-BillTo",
+						setUp: function(){
+							registry.byId("streetInput").set("value", at("rel:", "Street"));
+							registry.byId("cityInput").set("value", at("rel:", "City"));
+							registry.byId("stateInput").set("value", at("rel:", "State"));
+							registry.byId("zipInput").set("value", at("rel:", "Zip"));
+						},
+						runTest: function(){
+							ctrlDetail.set("model", data.BillTo);
+							doh.is("17 Skyline Dr-BillTo", registry.byId("streetInput").get("value"), "Street should be of BillTo");
+							doh.is("Hawthorne", registry.byId("cityInput").get("value"), "City should be of BillTo");
+						}
+					}, {
+						name: "Switch-to-ShipTo",
+						runTest: function(){
+							ctrlDetail.set("model", data.ShipTo);
+							doh.is("123 Valley Rd-ShipTo", registry.byId("streetInput").get("value"), "Street should be of ShipTo");
+							doh.is("Katonah", registry.byId("cityInput").get("value"), "City should be of ShipTo");
+						}
+					}]);
+
+					doh.run();
+				});
+			});	
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="header">
+			<div id="navigation">
+			</div>
+			<div id="headerInsert">
+				<h1>Order Shipping Details</h1>
+				<h2>Data Binding Example - Group Container.</h2>
+			</div>
+		</div>
+		<div id="main">
+		<div id="leftNav"></div>
+		<div id="mainContent">
+		<!--
+			The group container denotes some logical grouping of widgets and also serves
+			to establish a parent data binding context for its children.
+			The ref attribute for the outermost container obtains the binding from the
+			"page scope" itself.
+		-->
+		<!--				data-dojo-props="ref: 'model'"> -->
+		<!--				data-dojo-props="ref: 'Serial'"/> -->
+		<!--		data-dojo-props="ref: 'Last'"/> -->
+		<!--		data-dojo-props="ref: 'Email'"/>  -->
+		<!-- 		data-dojo-props="value: at('rel:Serial', 'value')"> -->
+		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model')">
+			<div class="row">
+				<label class="cell" for="serialInput">Order #:</label>
+				<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox" 
+							data-dojo-props="value: at('rel:', 'Serial')">
+			</div>
+			<div class="row">
+				<label class="cell" for="lastnameInput">Last:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Last')">
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Email')">
+			</div>
+		</div>
+		<br/>
+		<!--
+			For convenience, the widget hierarchy matches the data hierarchy
+			(see JSON literal above).
+			In this implementation, the child ref attributes are simple property names
+			of the parent binding context.
+			The ref attribute may support more advanced constructs, such as queries
+			over the parent widget's or other application specified binding context.
+		-->
+		<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrlDetail, 'model')">
+			<div class="row">
+				<label class="cell" for="streetInput">Street:</label>
+				<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Street')">
+			</div>
+			<div class="row">
+				<label class="cell" for="cityInput">City:</label>
+				<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'City')">
+			</div>
+			<div class="row">
+				<label class="cell" for="stateInput">State:</label>
+				<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'State')">
+			</div>
+			<div class="row">
+				<label class="cell" for="zipInput">Zipcode:</label>
+				<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Zip')">
+			</div>
+		</div>
+		</div></div></div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_performance_search-results-repeat.html b/dojox/mvc/tests/doh/doh_mvc_performance_search-results-repeat.html
new file mode 100644
index 0000000..8ca9034
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_performance_search-results-repeat.html
@@ -0,0 +1,317 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Search Results Repeat Test</title>
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+		</style>
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+<!--  <script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: true"></script> -->		
+	<script type="text/javascript">
+		require = {
+			isDebug: 1,
+			async: 1
+		};
+	</script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+		<script type="text/javascript" src="./helpers.js"></script>
+		<script type="text/javascript">
+
+			require([
+				"doh/runner",
+				"dojo/parser",
+			//	"dojox/mobile/parser",
+				"dijit/registry",
+				"dojox/mvc/at",
+				"dojox/mvc/getStateful",
+				"dojo/store/Memory",
+				"dojox/mvc/EditStoreRefListController",
+				"dojo/dom",
+				"dojo/store/Observable",
+				"dijit/form/Button",
+				"dijit/form/TextBox",
+				"dojox/mvc/_atBindingExtension",
+				"dojox/mvc/ListController",
+				"dojox/mvc/StatefulArray",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Repeat",
+		//		"dojox/mvc/parserExtension",
+				"dojo/domReady!"
+			], function(doh, parser, registry, at, getStateful, Memory, EditStoreRefListController, dom){
+				function runTests(){
+					// should be able to verify all of the inputs 
+					doh.register("parse", [
+						{
+							name: "parse",
+							runTest: function(){
+								console.log("in parse test with maxentries ="+maxentries);
+								parser.parse(dom.byId("stateful"));
+							}
+						}
+					]);
+					doh.register("parse2", [
+											{
+												name: "parse",
+												runTest: function(){
+													ctrl = new EditStoreRefListController({store: new Memory({data: data2})});
+													ctrl.queryStore();
+													
+													console.log("in ctrl parse test with maxentries ="+maxentries);
+													parser.parse(dom.byId("ctrl"));
+												}
+											}
+										]);
+
+
+					doh.run();
+				}
+
+				window.at = at;
+
+				//parser.parse();
+
+				setDetailsContext = function(index){
+					var ctl = registry.byId("listCtl");
+					ctl.set("cursorIndex", index);
+				};
+
+				var data = [
+							{
+								id: "1",
+								Group: "Engineer",
+								First: "Anne",
+								Last: "Ackerman",
+								Location: "NY",
+								Office: "1S76",
+								Email: "a.a at test.com",
+								Tel: "123-764-8237",
+								Fax: "123-764-8228"
+							},
+							{
+								id: "2",
+								Group: "Engineer",
+								First: "Ben",
+								Last : "Beckham",
+								Location: "NY",
+								Office: "5N47",
+								Email: "b.b at test.com",
+								Tel: "123-764-8599",
+								Fax: "123-764-8600"
+							},
+							{
+								id: "3",
+								Group: "Engineer",
+								First: "Chad",
+								Last: "Chapman",
+								Location: "CA",
+								Office: "1278",
+								Email: "c.c at test.com",
+								Tel: "408-764-8237",
+								Fax: "408-764-8228"
+							},
+							{
+								id: "4",
+								Group: "Engineer",
+								First: "David",
+								Last: "Durham",
+								Location: "NJ",
+								Office: "C12",
+								Email: "d.d at test.com",
+								Tel: "514-764-8237",
+								Fax: "514-764-8228"
+							},
+							{
+								id: "5",
+								Group: "Engineer",
+								First: "Emma",
+								Last: "Eklof",
+								Location: "NY",
+								Office: "4N76",
+								Email: "e.e at test.com",
+								Tel: "123-764-1234",
+								Fax: "123-764-4321"
+							},
+							{
+								id: "6",
+								Group: "Manager",
+								First: "Fred",
+								Last: "Fisher",
+								Location: "NJ",
+								Office: "V89",
+								Email: "f.f at test.com",
+								Tel: "514-764-8567",
+								Fax: "514-764-8000"
+							},
+							{
+								id: "7",
+								Group: "Manager",
+								First: "George",
+								Last: "Garnett",
+								Location: "NY",
+								Office: "7S11",
+								Email: "gig at test.com",
+								Tel: "123-999-8599",
+								Fax: "123-999-8600"
+							},
+							{
+								id: "8",
+								Group: "Accountant",
+								First: "Hunter",
+								Last: "Huffman",
+								Location: "CA",
+								Office: "6532",
+								Email: "h.h at test.com",
+								Tel: "408-874-8237",
+								Fax: "408-874-8228"
+							},
+							{
+								id: "9",
+								Group: "Accountant",
+								First: "Irene",
+								Last: "Ira",
+								Location: "NJ",
+								Office: "F09",
+								Email: "i.i at test.com",
+								Tel: "514-764-6532",
+								Fax: "514-764-7300"
+							},
+							{
+								id: "10",
+								Group: "Accountant",
+								First: "John",
+								Last: "Jacklin",
+								Location: "CA",
+								Office: "6701",
+								Email: "j.j at test.com",
+								Tel: "408-764-1234",
+								Fax: "408-764-4321"
+							}
+						];
+						window.ctrl = null;
+						var data2 = data;
+						var currentId = 10;
+						maxentries = 100;
+						for(var a = data2, i = 0; i < maxentries; i++){
+							var d = 				{
+									id: currentId++,
+									Group: "Engineer",
+									First: "First"+currentId,
+									Last: "Last"+currentId,
+									Location: "CA",
+									Office: "6701",
+									Email: "j.j at test.com"+currentId,
+									Tel: "408-764-1234",
+									Fax: "408-764-4321"
+								};
+							data2.push(d);				
+						}
+				searchRecords = {};
+				searchRecords.Results = getStateful(data2);
+
+				runTests();
+
+			});
+		</script>
+	</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - With repeat container.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		 <div id="leftNav"></div>
+		 <div id="mainContent">
+	   	 <div  id="ctrl"> 	
+		 
+						<div data-dojo-type="dojox.mvc.Repeat" id="repeat1" data-dojo-props="children: at(ctrl, 'model')">
+							<div class="row" data-dojo-type="dijit._WidgetBase" data-dojo-props="target: at('rel:', ${this.index})">
+								<label class="cell" for="xnameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="xnameInput${this.index}"
+								 data-dojo-props="value: at('rel:', 'First')">
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${this.index}); }">Details</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.addEmpty(); }">+</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.remove(${index}); }">-</button>
+							</div>
+						</div>
+		</div>
+		 
+	   	 <div  id="stateful"> 	
+			<div id="searchBanner">Search Results for term: Engineers</div>
+			<div data-dojo-type="dojox.mvc.Repeat"
+						data-dojo-props="children: at('searchRecords', 'Results')">
+							<div class="row" data-dojo-type="dijit._WidgetBase" data-dojo-props="target: at('rel:', ${this.index})">
+								<label class="cell" for="ynameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="ynameInput${this.index}"
+								 data-dojo-props="value: at('rel:', 'First')">
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${this.index}); }">Details</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.addEmpty(); }">+</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.remove(${index}); }">-</button>
+							</div>
+						</div>
+			</div>
+			<div class="spacer"></div>
+
+			<div data-dojo-type="dojox.mvc.Group" 
+								data-dojo-props="target: at('widget:listCtl', 'cursor')">
+				<div class="row">
+					<div style="display: inline-block;" id="detailsBanner">Details for result index: </div>
+					<span class="cell" id="indexOutput" data-dojo-type="dojox.mvc.Output" 
+							data-dojo-props="value: at('widget:listCtl', 'cursorIndex')"></span>
+				</div>
+				<div class="row">
+					<label class="cell" for="firstInput">First Name:</label>
+					<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" 
+										data-dojo-props="value: at('rel:', 'First')">
+				</div>
+				<div class="row">
+					<label class="cell" for="lastInput">Last Name:</label>
+					<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Last')">
+				</div>
+				<div class="row">
+					<label class="cell" for="locationInput">Location:</label>
+					<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Location')">
+				</div>
+				<div class="row">
+					<label class="cell" for="officeInput">Office:</label>
+					<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Office')">
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Email')">
+				</div>
+				<div class="row">
+					<label class="cell" for="telInput">Telephone:</label>
+					<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Tel')">
+				</div>
+				<div class="row">
+					<label class="cell" for="faxInput">Fax:</label>
+					<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" 
+								data-dojo-props="value: at('rel:', 'Fax')">
+				</div>
+			</div>
+		   </div>
+		 </div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_programmatic-repeat-store.html b/dojox/mvc/tests/doh/doh_mvc_programmatic-repeat-store.html
new file mode 100644
index 0000000..8c7304b
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_programmatic-repeat-store.html
@@ -0,0 +1,191 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+		<!-- required: dojo.js -->
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: 1, mvc: {debugBindings: 1}"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/_base/declare",
+				"dojo/when",
+				"dojo/dom",
+				"dojo/parser",
+				"dojo/promise/all",
+				"dojo/store/JsonRest",
+				"dijit/registry",
+				"dijit/_WidgetBase",
+				"dojox/mvc/at",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/EditModelRefController",
+				"dojox/mvc/ListController",
+				"dojox/mvc/Repeat",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojo/domReady!"
+			], function(doh, declare, when, ddom, parser, all, JsonRest, registry, _WidgetBase, at, getStateful, EditModelRefController, ListController, Repeat){
+
+				var ctrlClass = declare([_WidgetBase, EditModelRefController, ListController], {});
+				(ctrl = (new ctrlClass({srcNodeRef: ddom.byId("detailsGroup"), cursorIndex: 0}))).startup();
+
+				var repeatClass = declare("my.Repeat", Repeat, {
+					templateString: '<script type="dojo/require">at: "dojox/mvc/at"<\/script>'
+					 + '<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(\'rel:\', \'${this.index}\')">'
+					 + '<label class="cell">Name:</label>'
+					 + '<input id="${id}_textbox${index}" class="cell" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at(\'rel:\', \'First\')"></input>'
+					 + '<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.set(\'cursorIndex\', \'${this.index}\'); }">Details</button>'
+					 + '</div>'
+				});
+
+				(new repeatClass({children: at(ctrl, "model")}).placeAt('repeat2')).startup();
+
+				when(all([parser.parse(), new JsonRest({target: require.toUrl("dojox/mvc/tests/_data/mvcRepeatData.json")}).query({})]), function(a){
+	//				ctrl.set("sourceModel", getStateful(a[1].items));
+
+					 // should be able to verify all of the inputs
+					doh.register("Check values and bindings", [
+						{
+							name: "setup",
+							runTest: function(){
+								ctrl.set("sourceModel", getStateful(a[1].items));
+							}
+						}, {
+							name: "Initial",
+							runTest: function(){
+								doh.is("Anne", registry.byId("my_Repeat_0_textbox0").value, "textbox0 should be Anne");
+								doh.is("Anne", registry.byId("firstInput").value, "firstInput should be Anne");
+							}
+						}, {
+							name: "TestBen",
+							runTest: function(){
+								ctrl.set("cursorIndex", 1);
+								doh.is("Ben", registry.byId("my_Repeat_0_textbox1").value, "textbox1 should be Ben");
+								doh.is("Ben", registry.byId("firstInput").value, "firstInput should be Ben");
+							}
+						}, {
+							name: "TestJohn",
+							runTest: function(){
+								ctrl.set("cursorIndex", 9);
+								doh.is("John", registry.byId("my_Repeat_0_textbox9").value, "textbox9 should be John");
+								doh.is("John", registry.byId("firstInput").value, "firstInput should be John");
+
+								registry.byId("firstInput").set("value", "Johnny");
+
+								doh.is("Johnny", ctrl.get("model").get(9).get("First"), "First name of the 10th entry should be changed to Johnny");
+							}
+						}, {
+							name: "TestCommitReset",
+							runTest: function(){
+								ctrl.set("cursorIndex", 8);
+
+								doh.is("Irene", registry.byId("my_Repeat_0_textbox8").value, "textbox8 should be Irene");
+								doh.is("Irene", registry.byId("firstInput").value, "firstInput should be Irene");
+
+								registry.byId("firstInput").set("value", "IreneThisUpdateShouldBeSaved");
+
+								ctrl.commit();
+
+								registry.byId("lastInput").set("value", "IraThisUpdateShouldBeReset");
+
+								ctrl.reset();
+
+								doh.is("IreneThisUpdateShouldBeSaved", registry.byId("my_Repeat_0_textbox8").value, "textbox8 should be IreneThisUpdateShouldBeSaved");
+								doh.is("IreneThisUpdateShouldBeSaved", registry.byId("firstInput").value, "firstInput should be IreneThisUpdateShouldBeSaved");
+								doh.is("Ira", registry.byId("lastInput").value, "lastInput should be Ira");
+							}
+						}
+					]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<h1 class="testTitle">doh_mvc_programmatic-repeat-store.html automated tests (non-robot)</h1>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div id="searchBanner">Search Results for term: </div>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<div>
+										<div>Programatic Repeat using my.Repeat and its templateString: </div>
+										<div id="repeat2"></div>
+									</div>
+								</td>
+								<td>
+									<div>
+										<div>Declarative Repeat using my.Repeat does not pass templateString: </div>
+										<div id="repeatId2" data-dojo-type="my.Repeat" data-dojo-props="children: at(ctrl, 'model')"></div>
+									</div>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+					<div class="spacer"></div>
+					<div id="detailsBanner">Details for selected index:</div>
+					<div id="detailsGroup">
+						<div class="row">
+							<label class="cell" for="firstInput">First Name:</label>
+							<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="lastInput">Last Name:</label>
+							<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="locationInput">Location:</label>
+							<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Location')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="officeInput">Office:</label>
+							<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Office')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="emailInput">Email:</label>
+							<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="telInput">Telephone:</label>
+							<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Tel')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="faxInput">Fax:</label>
+							<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Fax')"></input>
+						</div>
+						<div class="row">
+						<div class="spacer"></div>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commit();}">Commit All</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset to last saved</button>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_ref-template-13263.html b/dojox/mvc/tests/doh/doh_mvc_ref-template-13263.html
new file mode 100644
index 0000000..bc20c3d
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_ref-template-13263.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH Async Late Binding Template Input - Output Group example</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1, mvc: {debugBindings: 1}" src="../../../../dojo/dojo.js"></script>
+<script type="text/javascript">
+ 		var model;
+ 
+		require([
+				'dojo/_base/declare',
+				'dojox/mvc/at',
+				'dojox/mvc/EditModelRefController',
+				'dojox/mvc/ModelRefController',
+				'dojo/Stateful',
+				'dojox/mvc/Group',
+				'dijit/_TemplatedMixin',
+				'dijit/_WidgetsInTemplateMixin',
+				'dojox/mvc/StatefulModel',
+				'dojo/ready',
+				'dojo/parser',
+				'dijit/form/TextBox'
+				], function (declare, at, EditModelRefController, ModelRefController, Stateful, Group, _TemplatedMixin, 
+						_WidgetsInTemplateMixin, StatefulModel, ready, parser, TextBox) {
+
+				declare('test.TextBox', [TextBox], {
+					startup: function () {
+						console.log('starting...', this.id, this._refs.value.targetProp);
+						this.inherited(arguments);
+						console.log('started', this.id, this._refs.value.targetProp);
+					}
+				});
+				var testGroup = declare('test.Group', [Group], {
+					startup: function () {
+						console.log('starting...', this.id);
+						this.inherited(arguments);
+						console.log('started', this.id);
+					}
+				});
+				declare('test.Templated', [testGroup, _TemplatedMixin, _WidgetsInTemplateMixin], {
+					templateString: '<div><input data-dojo-type="test.TextBox" data-dojo-props="value: at(\'rel:\', \'fn\')"></div>'
+				});
+				
+				// All 3 of these models work
+				//model = new EditModelRefController({sourceModel: new Stateful({fn: 'first', ln: 'last'})});
+				//model = new Stateful({fn: 'first', ln: 'last'});
+				model = new ModelRefController({model: new Stateful({fn: 'first', ln: 'last'})});
+
+
+				require([
+					'doh/runner', 'dijit/dijit'
+				], function(){
+				require([
+					'dojo/domReady!'
+					], function(){
+						doh.register("parse", function() {
+						parser.parse();
+						console.log('setting ref after parsing...');
+						dijit.byId('late').set('target', model);
+						var prog = new test.Templated({
+							target: model
+						}, 'prog');
+						prog.startup();
+
+						});
+						// should be able to verify all of the inputs 
+						doh.register("check initial values", [{
+							name : "initial",
+							runTest : function() {
+								doh.is("first", dijit.byId("parsedInput").get('value'),"parsedInput should be first");
+								doh.is("first", dijit.byId("test_TextBox_0").get('value'),"test_TextBox_0 should be first");
+								doh.is("first", dijit.byId("test_TextBox_1").get('value'),"test_TextBox_1 should be first");
+								doh.is("first", dijit.byId("test_TextBox_2").get('value'),"test_TextBox_2 should be first");
+							}
+						}]);
+
+						doh.register("update first", [{
+							name : "Update-first",
+							runTest : function() {
+								var first1;
+								first1 = dijit.byId("parsedInput");
+								first1.set("value","first-update");
+								if (first1) {
+								doh.is("first-update", dijit.byId("parsedInput").get('value'),"parsedInput should be first-update");
+								doh.is("first-update", dijit.byId("test_TextBox_0").get('value'),"test_TextBox_0 should be first-update");
+								doh.is("first-update", dijit.byId("test_TextBox_1").get('value'),"test_TextBox_1 should be first-update");
+								doh.is("first-update", dijit.byId("test_TextBox_2").get('value'),"test_TextBox_2 should be first-update");
+								}
+							}
+						}]);
+						doh.run();
+
+					});
+				});	
+		}); 
+		</script>
+</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<h1>late binding</h1>
+		<p>no template</p>
+		<div id="parsedGroup" data-dojo-type="test.Group" data-dojo-props="target : model">
+			<input data-dojo-type="test.TextBox" data-dojo-props="value: at('rel:', 'fn')" id="parsedInput">
+		</div>
+		<p>Early parsed</p><div id="early" data-dojo-type="test.Templated" data-dojo-props="target : model"></div>
+		<p>Late parsed</p><div id="late" data-dojo-type="test.Templated"></div>
+		<p>programmatic</p><div id="prog"></div>
+	</body>
+
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_repeat_select_cancel.html b/dojox/mvc/tests/doh/doh_mvc_repeat_select_cancel.html
new file mode 100644
index 0000000..52814cf
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_repeat_select_cancel.html
@@ -0,0 +1,370 @@
+<!DOCTYPE html>
+<html style="width:100%;height:100%;overflow:hidden;">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo Repeat Selection Test</title>
+
+	<style type="text/css">
+		@import "../../../../dijit/themes/dijit.css";
+		@import "../../../../dijit/themes/claro/document.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<style>
+		.bordercontainer-nopadding .dijitContentPane, .bordercontainer-nopadding .dijitSplitContainer-dijitContentPane, .bordercontainer-nopadding .dijitBorderContainer-dijitContentPane {
+			padding: 0;
+		}
+
+		.bordercontainer-nopadding .dijitMenuBar {
+			border-width: 0 0 1px 0;
+		}
+
+		.view .dijitMenu {
+			border-width: 0;
+		}
+
+		.view .dijitMenuItemHover {
+			background-color: inherit;
+			background-image: none;
+		}
+
+		.view .dijitMenuItemSelected {
+			background-color: #abd6ff;
+			background-image: url("images/standardGradient.png");
+			background-repeat: repeat-x;
+			background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			_background-image: none;
+		}
+
+		.view td.dijitMenuItemLabel {
+			width: 100%;
+			padding: 6px;
+		}
+
+		.view td.dijitMenuItemIconCell {
+			padding: 6px;
+		}
+
+		.dijitBorderContainerNoGutter > .form {
+			padding: 6px;
+		}
+
+		.row {
+			width: 100%;
+			display: inline-block;
+			padding: 6px;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.cell {
+			width: 100%;
+			display:inline-block;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.complete {
+			text-decoration: line-through;
+		}
+	</style>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		var ViewMenuBarData, DetailMenuBarData, initialRows;
+		var selectionStatusConverter = {
+			format: function(value){
+				return this.target.uniqueId == (value || {}).uniqueId;
+			},
+			parse: function(value){
+				if(!value){ throw new Error(); } // Stop copying the new value for unchecked case
+				for(var a = this.source.inModel, i = 0; i < a.length; i++){
+					if(a[i].uniqueId == this.target.uniqueId){
+						return a[i];
+					}
+				}
+			}
+		}, priorityConverter = {
+			format: function(value){
+				return "dijitIcon dijitMenuItemIconCell " + (value <= 1 ? "dijitIconError" : "");
+			}
+		}, completeConverter = {
+			format: function(value){
+				return "dijitMenuItemLabel" + (value ? " complete" : "");
+			}
+		},subjectConverter = {
+			format: function(value){
+				return value || "(No subject)";
+			}
+		};
+
+		require([
+			"doh/runner",
+			"dojox",
+			"dojo/_base/declare",
+			"dojo/_base/lang",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/query",
+			"dojo/parser",
+			"dojo/Stateful",
+			"dojox/mvc/at",
+			"dijit/registry",
+			"dijit/Menu",
+			"dojox/mvc/getStateful",
+			"dijit/form/CheckBox",
+			"dijit/form/DateTextBox",
+			"dijit/form/Select",
+			"dijit/form/TextBox",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/Editor",
+			"dijit/MenuBar",
+			"dijit/MenuBarItem",
+			"dijit/MenuItem",
+			"dojox/mvc/_atBindingExtension",
+			"dojox/mvc/EditModelRefController",
+			"dojox/mvc/ListController",
+			"dojox/mvc/StatefulArray",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat"
+		], function(doh, dojox, declare, lang, ddom, domClass, query, parser, Stateful, at, registry, Menu, getStateful){
+			//window.at = at;
+
+			var uniqueIdSeq = 3;
+
+			initialRows = getStateful([
+				{
+					uniqueId: 0,
+					Completed: false,
+					Subject: "Pick up my kids",
+					Due: new Date((new Date()).getTime() + 48 * 3600000),
+					Priority: 1,
+					Description: "At the kindergarden"
+				},
+				{
+					uniqueId: 1,
+					Completed: true,
+					Subject: "Take dojox.mvc learning course",
+					Due: new Date((new Date()).getTime() + 72 * 3600000),
+					Priority: 2,
+					Description: "Need to find course material at http://dojotoolkit.org/"
+				},
+				{
+					uniqueId: 2,
+					Completed: false,
+					Subject: "Wash my car",
+					Due: new Date((new Date()).getTime() + 120 * 3600000),
+					Priority: 3,
+					Description: "Need to buy a cleaner before that"
+				}
+			]);
+
+			ViewMenuBarData = getStateful([
+				{
+					label: "New",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						var payload = getStateful({
+							uniqueId: uniqueIdSeq++,
+							Completed: false,
+							Subject: "",
+							Due: new Date(""),
+							Priority: 2,
+							Description: ""
+						});
+						ctl.inModel.unshift(payload);
+						ctl.set("cursor", payload);
+					}
+				},
+				{
+					label: "Delete",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						var idx = ctl.get("cursorIndex");
+						if(idx >= 0){
+							ctl.inModel.splice(idx, 1);
+						}
+						if(idx < ctl.inModel.get("length")){
+							ctl.set("cursorIndex", idx);
+						}
+					}
+				}
+			]);
+
+			DetailMenuBarData = getStateful([
+				{
+					label: "Cancel",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						ctl.reset();
+					}
+				}
+			]);
+
+			domClass.add(ddom.byId("loading"), "dijitDisplayNone");
+			domClass.remove(ddom.byId("main"), "dijitDisplayNone");
+			parser.parse();
+
+			doh.register("Test values and bindings", [
+				{
+					name: "Initial",
+					runTest: function(){
+						doh.t(ddom.byId("viewcheckbox0").checked, "First view row should be checked");
+						doh.t(domClass.contains(ddom.byId("viewiconimg0"), "dijitIconError"), "First view row should contain explanation mark");
+						doh.t(domClass.contains(ddom.byId("viewtext1"), "complete"), "Second view row should be marked as complete");
+						doh.is("Wash my car", ddom.byId("viewtext2").innerHTML, "Third view row should exist");
+						doh.f(ddom.byId("viewtext3"), "Fourth row shouldn't exist");
+						doh.is("Pick up my kids", ddom.byId("subject").value, "The subject field should be of the first row");
+					}
+				},
+				{
+					name: "Navigate",
+					runTest: function(){
+						ddom.byId("viewcheckbox1").click();
+						doh.is("Take dojox.mvc learning course", ddom.byId("subject").value, "The subject field should be of the second row");
+						ddom.byId("viewcheckbox2").click();
+						doh.is("3", ((query("#priority input[data-dojo-attach-point='valueNode']") || [])[0] || {}).value, "The priority field should be of the third row");
+					}
+				},
+				{
+					name: "EditToCancel",
+					runTest: function(){
+						ddom.byId("viewcheckbox0").click();
+						var completed = ddom.byId("completed");
+						completed.click();
+						var subject = registry.byId("subject");
+						subject.set("displayedValue", "Pick up my wife");
+						doh.t(domClass.contains(ddom.byId("viewtext0"), "complete"), "First view row should be marked as complete");
+						doh.is("Pick up my wife", ddom.byId("viewtext0").innerHTML, "First view row's subject should be updated");
+						registry.byId("menubaritem1_0").onClick();
+						doh.is("Pick up my kids", subject.get("displayedValue"), "Subject should be set back to the original one");
+						doh.f(completed.checked, "Completed checkbox should be set back to unchecked");
+					}
+				},
+				{
+					name: "Delete",
+					runTest: function(){
+						registry.byId("menubaritem0_1").onClick();
+						doh.is("Take dojox.mvc learning course", ddom.byId("subject").value, "The subject field should be of the (formerly) second row");
+						doh.f(ddom.byId("viewtext2"), "Third row shouldn't exist");
+					}
+				},
+				{
+					name: "Create",
+					runTest: function(){
+						registry.byId("menubaritem0_0").onClick();
+						var viewtext = ddom.byId("viewtext0");
+						doh.is("(No subject)", viewtext.innerHTML, "First row's subject shouldn't be set yet");
+						var subject = registry.byId("subject");
+						subject.set("displayedValue", "Complete dojox.mvc test case");
+						doh.is("Complete dojox.mvc test case", viewtext.innerHTML, "First row's subject should be updated");
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;overflow:hidden;">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<table id="loading" style="width:100%;height:100%;" border="0" cellpadding="0" cellspacing="0">
+		<tbody>
+			<tr>
+				<td align="center">Loading...</td>
+			</tr>
+		</tbody>
+	</table>
+	<div id="main" class="dijitDisplayNone" style="width:100%;height:100%;">
+		<span id="listCtl" data-dojo-type="dojox.mvc.ListController" data-dojo-mixins="dojox.mvc.EditModelRefController"
+		 data-dojo-props="_refInModelProp: 'inModel', _refSourceModelProp: 'cursor', _refModelProp: 'model', inModel: initialRows, cursorIndex: 0"></span>
+		<div class="bordercontainer-nopadding" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: true, style: 'height: 100%; width: 100%;'">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'left', style: 'background-color: white; width: 48ex', splitter: true">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-mixins="dijit.MenuBar" data-dojo-props="children: ViewMenuBarData">
+							<div id="menubaritem0_${index}" data-dojo-type="dijit.MenuBarItem" data-dojo-props="'*': at('rel:${index}', '*')"></div>
+						</div>
+					</div>
+					<div class="view" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center'">
+						<table border="0" cellspacing="0" cellpadding="0">
+							<tbody data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at('widget:listCtl', 'inModel')">
+								<tr data-dojo-type="dijit._WidgetBase" data-dojo-props="target: at('rel:', '${index}')">
+									<td class="dijitMenuItemIconCell">
+										<input id="viewcheckbox${index}" data-dojo-type="dijit.form.CheckBox"
+										 data-dojo-props="uniqueId: at('rel:', 'uniqueId'),
+										                  checked: at('widget:listCtl', 'cursor').transform(selectionStatusConverter)">
+									</td>
+									<td class="dijitMenuItemIconCell">
+										<img id="viewiconimg${index}" src="../../../../dojo/resources/blank.gif" data-dojo-type="dijit._WidgetBase"
+										 data-dojo-props="_setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Priority').direction(at.from).transform(priorityConverter)">
+									</td>
+									<td id="viewtext${index}" data-dojo-type="dijit._WidgetBase"
+									 data-dojo-props="Subject: at('rel:', 'Subject').direction(at.from).transform(subjectConverter),
+									                  _setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Completed').direction(at.from).transform(completeConverter),
+									                  _setSubjectAttr: {node: 'domNode', type: 'innerText'}">
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</div>
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', style: 'background-color: white;'">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-mixins="dijit.MenuBar" data-dojo-props="children: DetailMenuBarData">
+							<div id="menubaritem1_${index}" data-dojo-type="dijit.MenuBarItem" data-dojo-props="'*': at('rel:${index}', '*')"></div>
+						</div>
+					</div>
+					<div class="form" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', target: at('widget:listCtl', 'model')">
+						<div class="row">
+							<span class="cell">
+								<label for="completed">Completed:</label>
+								<input id="completed" data-dojo-type="dijit.form.CheckBox" data-dojo-props="checked: at('rel:', 'Completed')">
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="subject">Subject:</label>
+							<input class="cell" id="subject" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Subject')">
+						</div>
+						<div class="row">
+							<label class="cell" for="priority">Priority:</label>
+							<span class="cell">
+								<select id="priority" data-dojo-type="dijit.form.Select" data-dojo-props="value: at('rel:', 'Priority')">
+									<option value="1">1</option>
+									<option value="2">2</option>
+									<option value="3">3</option>
+								</select>
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="due">Due:</label>
+							<span class="cell">
+								<input id="due" data-dojo-type="dijit.form.DateTextBox"
+								 data-dojo-props="required: false, constraints: {datePattern: 'MMMM dd yyyy'}, value: at('rel:', 'Due')">
+							</span>
+						</div>
+						<div class="row">
+							<span class="cell">Description:</span>
+							<div class="cell" data-dojo-type="dijit.Editor"
+							 data-dojo-props="plugins: ['bold', 'italic', 'underline'], height: '200', value: at('rel:', 'Description')"></div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_repeat_select_manualsave.html b/dojox/mvc/tests/doh/doh_mvc_repeat_select_manualsave.html
new file mode 100644
index 0000000..74875ab
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_repeat_select_manualsave.html
@@ -0,0 +1,394 @@
+<!DOCTYPE html>
+<html style="width:100%;height:100%;overflow:hidden;">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo Repeat Selection Test</title>
+
+	<style type="text/css">
+		@import "../../../../dijit/themes/dijit.css";
+		@import "../../../../dijit/themes/claro/document.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<style>
+		.bordercontainer-nopadding .dijitContentPane, .bordercontainer-nopadding .dijitSplitContainer-dijitContentPane, .bordercontainer-nopadding .dijitBorderContainer-dijitContentPane {
+			padding: 0;
+		}
+
+		.bordercontainer-nopadding .dijitMenuBar {
+			border-width: 0 0 1px 0;
+		}
+
+		.view .dijitMenu {
+			border-width: 0;
+		}
+
+		.view .dijitMenuItemHover {
+			background-color: inherit;
+			background-image: none;
+		}
+
+		.view .dijitMenuItemSelected {
+			background-color: #abd6ff;
+			background-image: url("images/standardGradient.png");
+			background-repeat: repeat-x;
+			background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			_background-image: none;
+		}
+
+		.view td.dijitMenuItemLabel {
+			width: 100%;
+			padding: 6px;
+		}
+
+		.view td.dijitMenuItemIconCell {
+			padding: 6px;
+		}
+
+		.dijitBorderContainerNoGutter > .form {
+			padding: 6px;
+		}
+
+		.row {
+			width: 100%;
+			display: inline-block;
+			padding: 6px;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.cell {
+			width: 100%;
+			display:inline-block;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.complete {
+			text-decoration: line-through;
+		}
+	</style>
+
+	<script type="text/javascript">
+		dojoConfig = {async: 1, isDebug: 1, mvc: {debugBindings: 1}};
+	</script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js"></script>
+
+	<script type="text/javascript">
+		var ViewMenuBarData, DetailMenuBarData, initialRows;
+		var selectionStatusConverter = {
+			format: function(value){
+				return this.target.uniqueId == (value || {}).uniqueId;
+			},
+			parse: function(value){
+				if(!value){ throw new Error(); } // Stop copying the new value for unchecked case
+				for(var a = this.source.inModel, i = 0; i < a.length; i++){
+					if(a[i].uniqueId == this.target.uniqueId){
+						return a[i];
+					}
+				}
+			}
+		}, priorityConverter = {
+			format: function(value){
+				return "dijitIcon dijitMenuItemIconCell " + (value <= 1 ? "dijitIconError" : "");
+			}
+		}, completeConverter = {
+			format: function(value){
+				return "dijitMenuItemLabel" + (value ? " complete" : "");
+			}
+		},subjectConverter = {
+			format: function(value){
+				return value || "(No subject)";
+			}
+		};
+
+		require([
+			"doh/runner",
+			"dojox",
+			"dojo/_base/declare",
+			"dojo/_base/lang",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/query",
+			"dojo/parser",
+			"dojo/Stateful",
+			"dijit/registry",
+			"dijit/Menu",
+			"dojox/mvc/at",
+			"dojox/mvc/getStateful",
+			"dijit/form/CheckBox",
+			"dijit/form/DateTextBox",
+			"dijit/form/Select",
+			"dijit/form/TextBox",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/Editor",
+			"dijit/MenuBar",
+			"dijit/MenuBarItem",
+			"dijit/MenuItem",
+			"dojox/mvc/_atBindingExtension",
+			"dojox/mvc/EditModelRefController",
+			"dojox/mvc/ListController",
+			"dojox/mvc/StatefulArray",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat"
+		], function(doh, dojox, declare, lang, ddom, domClass, query, parser, Stateful, registry, Menu, at, getStateful){
+
+			var uniqueIdSeq = 3;
+
+			initialRows = getStateful([
+				{
+					uniqueId: 0,
+					Completed: false,
+					Subject: "Pick up my kids",
+					Due: new Date((new Date()).getTime() + 48 * 3600000),
+					Priority: 1,
+					Description: "At the kindergarden"
+				},
+				{
+					uniqueId: 1,
+					Completed: true,
+					Subject: "Take dojox.mvc learning course",
+					Due: new Date((new Date()).getTime() + 72 * 3600000),
+					Priority: 2,
+					Description: "Need to find course material at http://dojotoolkit.org/"
+				},
+				{
+					uniqueId: 2,
+					Completed: false,
+					Subject: "Wash my car",
+					Due: new Date((new Date()).getTime() + 120 * 3600000),
+					Priority: 3,
+					Description: "Need to buy a cleaner before that"
+				}
+			]);
+
+			ViewMenuBarData = getStateful([
+				{
+					label: "New",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						var payload = getStateful({
+							uniqueId: uniqueIdSeq++,
+							Completed: false,
+							Subject: "",
+							Due: new Date(""),
+							Priority: 2,
+							Description: ""
+						});
+						ctl.inModel.unshift(payload);
+						ctl.set("cursor", payload);
+					}
+				},
+				{
+					label: "Delete",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						var idx = ctl.get("cursorIndex");
+						if(idx >= 0){
+							ctl.inModel.splice(idx, 1);
+						}
+						if(idx < ctl.inModel.get("length")){
+							ctl.set("cursorIndex", idx);
+						}
+					}
+				}
+			]);
+
+			DetailMenuBarData = getStateful([
+				{
+					label: "Save",
+					onClick: function(){
+						registry.byId("listCtl").commit();
+					}
+				},
+				{
+					label: "Cancel",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						ctl.reset();
+					}
+				}
+			]);
+
+			domClass.add(ddom.byId("loading"), "dijitDisplayNone");
+			domClass.remove(ddom.byId("main"), "dijitDisplayNone");
+			parser.parse();
+
+			doh.register("Test values and bindings", [
+				{
+					name: "Initial",
+					runTest: function(){
+						doh.t(ddom.byId("viewcheckbox0").checked, "First view row should be checked");
+						doh.t(domClass.contains(ddom.byId("viewiconimg0"), "dijitIconError"), "First view row should contain explanation mark");
+						doh.t(domClass.contains(ddom.byId("viewtext1"), "complete"), "Second view row should be marked as complete");
+						doh.is("Wash my car", ddom.byId("viewtext2").innerHTML, "Third view row should exist");
+						doh.f(ddom.byId("viewtext3"), "Fourth row shouldn't exist");
+						doh.is("Pick up my kids", ddom.byId("subject").value, "The subject field should be of the first row");
+					}
+				},
+				{
+					name: "Navigate",
+					runTest: function(){
+						ddom.byId("viewcheckbox1").click();
+						doh.is("Take dojox.mvc learning course", ddom.byId("subject").value, "The subject field should be of the second row");
+						ddom.byId("viewcheckbox2").click();
+						doh.is("3", ((query("#priority input[data-dojo-attach-point='valueNode']") || [])[0] || {}).value, "The priority field should be of the third row");
+					}
+				},
+				{
+					name: "EditToCancel",
+					runTest: function(){
+						ddom.byId("viewcheckbox0").click();
+						var completed = ddom.byId("completed");
+						completed.click();
+						var subject = registry.byId("subject");
+						subject.set("displayedValue", "Pick up my wife");
+						doh.f(domClass.contains(ddom.byId("viewtext0"), "complete"), "First view row shouldn't be marked as complete yet");
+						doh.is("Pick up my kids", ddom.byId("viewtext0").innerHTML, "First view row's subject shouldn't be updated yet");
+						registry.byId("menubaritem1_1").onClick();
+						doh.is("Pick up my kids", subject.get("displayedValue"), "Subject should be set back to the original one");
+						doh.f(completed.checked, "Completed checkbox should be set back to unchecked");
+					}
+				},
+				{
+					name: "EditToSave",
+					runTest: function(){
+						ddom.byId("viewcheckbox0").click();
+						var completed = ddom.byId("completed");
+						completed.click();
+						var subject = registry.byId("subject");
+						subject.set("displayedValue", "Pick up my wife");
+						doh.f(domClass.contains(ddom.byId("viewtext0"), "complete"), "First view row shouldn't be marked as complete yet");
+						doh.is("Pick up my kids", ddom.byId("viewtext0").innerHTML, "First view row's subject shouldn't be updated yet");
+						registry.byId("menubaritem1_0").onClick();
+						doh.t(domClass.contains(ddom.byId("viewtext0"), "complete"), "First view row should be marked as complete");
+						doh.is("Pick up my wife", ddom.byId("viewtext0").innerHTML, "First view row's subject should be updated");
+					}
+				},
+				{
+					name: "Delete",
+					runTest: function(){
+						registry.byId("menubaritem0_1").onClick();
+						doh.is("Take dojox.mvc learning course", ddom.byId("subject").value, "The subject field should be of the (formerly) second row");
+						doh.f(ddom.byId("viewtext2"), "Third row shouldn't exist");
+					}
+				},
+				{
+					name: "Create",
+					runTest: function(){
+						registry.byId("menubaritem0_0").onClick();
+						var viewtext = ddom.byId("viewtext0");
+						doh.is("(No subject)", viewtext.innerHTML, "First row's subject shouldn't be set yet");
+						var subject = registry.byId("subject");
+						subject.set("displayedValue", "Complete dojox.mvc test case");
+						doh.is("(No subject)", viewtext.innerHTML, "First row's subject shouldn't be updated yet");
+						registry.byId("menubaritem1_0").onClick();
+						doh.is("Complete dojox.mvc test case", viewtext.innerHTML, "Subject should be updated");
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;overflow:hidden;">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<table id="loading" style="width:100%;height:100%;" border="0" cellpadding="0" cellspacing="0">
+		<tbody>
+			<tr>
+				<td align="center">Loading...</td>
+			</tr>
+		</tbody>
+	</table>
+	<div id="main" class="dijitDisplayNone" style="width:100%;height:100%;">
+		<span id="listCtl" data-dojo-type="dojox.mvc.ListController" data-dojo-mixins="dojox.mvc.EditModelRefController"
+		 data-dojo-props="_refInModelProp: 'inModel', _refSourceModelProp: 'cursor', _refModelProp: 'model', inModel: initialRows, cursorIndex: 0, holdModelUntilCommit: true"></span>
+		<div class="bordercontainer-nopadding" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: true, style: 'height: 100%; width: 100%;'">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'left', style: 'background-color: white; width: 48ex', splitter: true">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-mixins="dijit.MenuBar" data-dojo-props="children: ViewMenuBarData">
+							<div id="menubaritem0_${index}" data-dojo-type="dijit.MenuBarItem" data-dojo-props="'*': at('rel:${index}', '*')"></div>
+						</div>
+					</div>
+					<div class="view" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center'">
+						<table border="0" cellspacing="0" cellpadding="0">
+							<tbody data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at('widget:listCtl', 'inModel')">
+								<tr data-dojo-type="dijit._WidgetBase" data-dojo-props="target: at('rel:', '${index}')">
+									<td class="dijitMenuItemIconCell">
+										<input id="viewcheckbox${index}" data-dojo-type="dijit.form.CheckBox"
+										 data-dojo-props="uniqueId: at('rel:', 'uniqueId'),
+										                  checked: at('widget:listCtl', 'cursor').transform(selectionStatusConverter)">
+									</td>
+									<td class="dijitMenuItemIconCell">
+										<img id="viewiconimg${index}" src="../../../../dojo/resources/blank.gif" data-dojo-type="dijit._WidgetBase"
+										 data-dojo-props="_setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Priority').direction(at.from).transform(priorityConverter)">
+									</td>
+									<td id="viewtext${index}" data-dojo-type="dijit._WidgetBase"
+									 data-dojo-props="Subject: at('rel:', 'Subject').direction(at.from).transform(subjectConverter),
+									                  _setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Completed').direction(at.from).transform(completeConverter),
+									                  _setSubjectAttr: {node: 'domNode', type: 'innerText'}">
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</div>
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', style: 'background-color: white;'">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-mixins="dijit.MenuBar" data-dojo-props="children: DetailMenuBarData">
+							<div id="menubaritem1_${index}" data-dojo-type="dijit.MenuBarItem" data-dojo-props="'*': at('rel:${index}', '*')"></div>
+						</div>
+					</div>
+					<div class="form" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', target: at('widget:listCtl', 'model')">
+						<div class="row">
+							<span class="cell">
+								<label for="completed">Completed:</label>
+								<input id="completed" data-dojo-type="dijit.form.CheckBox" data-dojo-props="checked: at('rel:', 'Completed')">
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="subject">Subject:</label>
+							<input class="cell" id="subject" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Subject')">
+						</div>
+						<div class="row">
+							<label class="cell" for="priority">Priority:</label>
+							<span class="cell">
+								<select id="priority" data-dojo-type="dijit.form.Select" data-dojo-props="value: at('rel:', 'Priority')">
+									<option value="1">1</option>
+									<option value="2">2</option>
+									<option value="3">3</option>
+								</select>
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="due">Due:</label>
+							<span class="cell">
+								<input id="due" data-dojo-type="dijit.form.DateTextBox"
+								 data-dojo-props="required: false, constraints: {datePattern: 'MMMM dd yyyy'}, value: at('rel:', 'Due')">
+							</span>
+						</div>
+						<div class="row">
+							<span class="cell">Description:</span>
+							<div class="cell" data-dojo-type="dijit.Editor"
+							 data-dojo-props="plugins: ['bold', 'italic', 'underline'], height: '200', value: at('rel:', 'Description')"></div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_search-results-repeat-store.html b/dojox/mvc/tests/doh/doh_mvc_search-results-repeat-store.html
new file mode 100644
index 0000000..602afd3
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_search-results-repeat-store.html
@@ -0,0 +1,174 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css">
+
+		<!-- required: dojo.js -->
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: 1, mvc: {debugBindings: 1}"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+
+		<script type="text/javascript" >
+			require([
+				"doh/runner",
+				"dojo/_base/declare",
+				"dojo/when",
+				"dojo/dom",
+				"dojo/parser",
+				"dojo/promise/all",
+				"dojo/store/JsonRest",
+				"dijit/registry",
+				"dijit/_WidgetBase",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/EditModelRefController",
+				"dojox/mvc/ListController",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojox/mvc/Repeat",
+				"dojo/domReady!"
+			], function(doh, declare, when, ddom, parser, all, JsonRest, registry, _WidgetBase, getStateful, EditModelRefController, ListController){
+
+				var ctrlClass = declare([_WidgetBase, EditModelRefController, ListController], {});
+				(ctrl = (new ctrlClass({srcNodeRef: ddom.byId("detailsGroup"), cursorIndex: 0}))).startup();
+
+				when(all([parser.parse(), new JsonRest({target: require.toUrl("dojox/mvc/tests/_data/mvcRepeatData.json")}).query({})]), function(a){
+					ctrl.set("sourceModel", getStateful(a[1].items));
+
+					 // should be able to verify all of the inputs
+					doh.register("Check values and bindings", [
+						{
+							name: "Initial",
+							runTest: function(){
+								doh.is("Anne", registry.byId("nameInput0").value, "nameInput0 should be Anne");
+								doh.is("Anne", registry.byId("firstInput").value, "firstInput should be Anne");
+							}
+						}, {
+							name: "TestBen",
+							runTest: function(){
+								ctrl.set("cursorIndex", 1);
+								doh.is("Ben", registry.byId("nameInput1").value, "nameInput1 should be Ben");
+								doh.is("Ben", registry.byId("firstInput").value, "firstInput should be Ben");
+							}
+						}, {
+							name: "TestJohn",
+							runTest: function(){
+								ctrl.set("cursorIndex", 9);
+								doh.is("John", registry.byId("nameInput9").value, "nameInput9 should be John");
+								doh.is("John", registry.byId("firstInput").value, "firstInput should be John");
+
+								registry.byId("firstInput").set("value", "Johnny");
+
+								doh.is("Johnny", ctrl.get("model").get(9).get("First"), "First name of the 10th entry should be changed to Johnny");
+							}
+						}, {
+							name: "TestCommitReset",
+							runTest: function(){
+								ctrl.set("cursorIndex", 8);
+
+								doh.is("Irene", registry.byId("nameInput8").value, "nameInput8 should be Irene");
+								doh.is("Irene", registry.byId("firstInput").value, "firstInput should be Irene");
+
+								registry.byId("firstInput").set("value", "IreneThisUpdateShouldBeSaved");
+
+								ctrl.commit();
+
+								registry.byId("lastInput").set("value", "IraThisUpdateShouldBeReset");
+
+								ctrl.reset();
+
+								doh.is("IreneThisUpdateShouldBeSaved", registry.byId("nameInput8").value, "nameInput8 should be IreneThisUpdateShouldBeSaved");
+								doh.is("IreneThisUpdateShouldBeSaved", registry.byId("firstInput").value, "firstInput should be IreneThisUpdateShouldBeSaved");
+								doh.is("Ira", registry.byId("lastInput").value, "lastInput should be Ira");
+							}
+						}
+					]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<h1 class="testTitle">doh_mvc_programmatic-repeat-store.html automated tests (non-robot)</h1>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div id="searchBanner">Search Results for term: </div>
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<div>
+										<div>Declarative Repeat using my.Repeat does not pass templateString: </div>
+										<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at(ctrl, 'model')">
+											<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', '${this.index}')">
+												<label class="cell" for="nameInput${this.index}">Name:</label>
+												<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="value: at('rel:', 'First')"/>
+												<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', '${this.index}'); }">Details</button>
+											</div>
+										</div>
+									</div>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+					<div class="spacer"></div>
+					<div id="detailsBanner">Details for selected index:</div>
+					<div id="detailsGroup">
+						<div class="row">
+							<label class="cell" for="firstInput">First Name:</label>
+							<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')">
+						</div>
+						<div class="row">
+							<label class="cell" for="lastInput">Last Name:</label>
+							<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')">
+						</div>
+						<div class="row">
+							<label class="cell" for="locationInput">Location:</label>
+							<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Location')">
+						</div>
+						<div class="row">
+							<label class="cell" for="officeInput">Office:</label>
+							<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Office')">
+						</div>
+						<div class="row">
+							<label class="cell" for="emailInput">Email:</label>
+							<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')">
+						</div>
+						<div class="row">
+							<label class="cell" for="telInput">Telephone:</label>
+							<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Tel')">
+						</div>
+						<div class="row">
+							<label class="cell" for="faxInput">Fax:</label>
+							<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Fax')">
+						</div>
+						<div class="row">
+						<div class="spacer"></div>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commit();}">Commit All</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset to last saved</button>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_search-results-repeat.html b/dojox/mvc/tests/doh/doh_mvc_search-results-repeat.html
new file mode 100644
index 0000000..fd8906f
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_search-results-repeat.html
@@ -0,0 +1,277 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Search Results Repeat Test</title>
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+		</style>
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: true, mvc: {debugBindings: true}"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+		<script type="text/javascript">
+
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dojo/when",
+				"dijit/registry",
+				"dojox/mvc/getStateful",
+				"dijit/form/Button",
+				"dijit/form/TextBox",
+				"dojox/mvc/_atBindingExtension",
+				"dojox/mvc/ListController",
+				"dojox/mvc/StatefulArray",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Repeat",
+				"dojo/domReady!"
+			], function(doh, parser, when, registry, getStateful){
+				function runTests(){
+					// should be able to verify all of the inputs 
+					doh.register("Check initial values and bindings", [
+						{
+							name: "initial",
+							runTest: function(){
+								var name1, bind1, firstInput; 
+								name1 = registry.byId("nameInput0");
+								if (name1) {
+										doh.is("Anne",name1.value,"name1.value should be set");
+								}
+
+								firstInput = registry.byId("firstInput");
+								if (firstInput) {
+										doh.is("Anne",firstInput.value,"firstInput.value should be set");
+								}
+							}
+						}
+					]);
+
+					doh.register("select Ben", [
+						{
+							name: "testBen",
+							runTest: function(){
+								setDetailsContext(1);
+								var name1, bind1, firstInput; 
+								name1 = registry.byId("nameInput1");
+								if (name1) {
+										doh.is("Ben",name1.get("value"),"name1.get(value) is wrong");
+								}
+
+								firstInput = registry.byId("firstInput");
+								if (firstInput) {
+										doh.is("Ben",firstInput.get("value"),"firstInput value is wrong");
+										firstInput.set("value","Benjamin");
+										doh.is("Benjamin",firstInput.get("value"),"firstInput value is wrong after update");
+										doh.is("Benjamin",name1.get("value"),"name1.get(value) is wrong after update");
+								}
+							}					
+						}
+					]);
+
+					doh.run();
+				}
+
+				when(parser.parse(), function(){
+					setDetailsContext = function(index){
+						var ctl = registry.byId("listCtl");
+						ctl.set("cursorIndex", index);
+					};
+
+					searchRecords = getStateful(
+						{
+							"Query" : "Engineers",
+							"Results" : [
+								{
+									"First"	  : "Anne",
+									"Last"	  : "Ackerman",
+									"Location": "NY",
+									"Office"  : "1S76",
+									"Email"	  : "a.a at test.com",
+									"Tel"	  : "123-764-8237",
+									"Fax"	  : "123-764-8228"
+								},
+								{
+									"First"	  : "Ben",
+									"Last"	  : "Beckham",
+									"Location": "NY",
+									"Office"  : "5N47",
+									"Email"	  : "b.b at test.com",
+									"Tel"	  : "123-764-8599",
+									"Fax"	  : "123-764-8600"
+								},
+								{
+									"First"	  : "Chad",
+									"Last"	  : "Chapman",
+									"Location": "CA",
+									"Office"  : "1278",
+									"Email"	  : "c.c at test.com",
+									"Tel"	  : "408-764-8237",
+									"Fax"	  : "408-764-8228"
+								},
+								{
+									"First"	  : "David",
+									"Last"	  : "Durham",
+									"Location": "NJ",
+									"Office"  : "C12",
+									"Email"	  : "d.d at test.com",
+									"Tel"	  : "514-764-8237",
+									"Fax"	  : "514-764-8228"
+								},
+								{
+									"First"	  : "Emma",
+									"Last"	  : "Eklof",
+									"Location": "NY",
+									"Office"  : "4N76",
+									"Email"	  : "e.e at test.com",
+									"Tel"	  : "123-764-1234",
+									"Fax"	  : "123-764-4321"
+								},
+								{
+									"First"	  : "Fred",
+									"Last"	  : "Fisher",
+									"Location": "NJ",
+									"Office"  : "V89",
+									"Email"	  : "f.f at test.com",
+									"Tel"	  : "514-764-8567",
+									"Fax"	  : "514-764-8000"
+								},
+								{
+									"First"	  : "George",
+									"Last"	  : "Garnett",
+									"Location": "NY",
+									"Office"  : "7S11",
+									"Email"	  : "gig at test.com",
+									"Tel"	  : "123-999-8599",
+									"Fax"	  : "123-999-8600"
+								},
+								{
+									"First"	  : "Hunter",
+									"Last"	  : "Huffman",
+									"Location": "CA",
+									"Office"  : "6532",
+									"Email"	  : "h.h at test.com",
+									"Tel"	  : "408-874-8237",
+									"Fax"	  : "408-874-8228"
+								},
+								{
+									"First"	  : "Irene",
+									"Last"	  : "Ira",
+									"Location": "NJ",
+									"Office"  : "F09",
+									"Email"	  : "i.i at test.com",
+									"Tel"	  : "514-764-6532",
+									"Fax"	  : "514-764-7300"
+								},
+								{
+									"First"	  : "John",
+									"Last"	  : "Jacklin",
+									"Location": "CA",
+									"Office"  : "6701",
+									"Email"	  : "j.j at test.com",
+									"Tel"	  : "408-764-1234",
+									"Fax"	  : "408-764-4321"
+								}
+							]
+						});
+
+					registry.byId("listCtl").set("model", searchRecords.Results);
+					runTests();
+				});
+			});
+		</script>
+	</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<span id="listCtl"  data-dojo-type="dojox.mvc.ListController" 
+							data-dojo-props="cursorIndex: 0"></span>
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - With repeat container.</h2>
+		  </div>
+		</div>
+		<div id="main">
+		 <div id="leftNav">
+		 </div>
+		 <div id="mainContent">
+		 <!--
+			 The group container denotes some logical grouping of widgets and also serves
+			 to establish a parent data binding context for its children.
+			 The target attribute for the outermost container obtains the binding from the
+			 "page scope" itself.
+		 -->
+	   <div> 	
+			<div id="searchBanner">Search Results for term: Engineers</div>
+
+			<!--
+				The repeat container denotes a templated UI that operates over a collection
+				of data records.
+				The UI can be customized for each iteration using properties such as
+				${this.index} for the iteration index.
+			-->
+			<div data-dojo-type="dojox.mvc.Repeat" 
+						data-dojo-props="children: at('widget:listCtl', 'model')">
+				<div class="row" data-dojo-type="dojox.mvc.Group" 
+								data-dojo-props="target: at('rel:${this.index}')">
+					<label class="cell" for="nameInput${this.index}">Name:</label>
+					<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" 
+										data-dojo-props="value: at('rel:', 'First')">
+					<button type="button" data-dojo-type="dijit.form.Button" 
+										data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+				</div>
+			</div>
+			<div class="spacer"></div>
+
+			<div data-dojo-type="dojox.mvc.Group" 
+								data-dojo-props="target: at('widget:listCtl', 'cursor')">
+				<div class="row">
+					<div style="display: inline-block;" id="detailsBanner">Details for result index: </div>
+					<span class="cell" id="indexOutput" data-dojo-type="dojox.mvc.Output" 
+							data-dojo-props="value: at('widget:listCtl', 'cursorIndex')"></span>
+				</div>
+				<div class="row">
+					<label class="cell" for="firstInput">First Name:</label>
+					<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" 
+										data-dojo-props="value: at('rel:', 'First')">
+				</div>
+				<div class="row">
+					<label class="cell" for="lastInput">Last Name:</label>
+					<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Last')">
+				</div>
+				<div class="row">
+					<label class="cell" for="locationInput">Location:</label>
+					<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Location')">
+				</div>
+				<div class="row">
+					<label class="cell" for="officeInput">Office:</label>
+					<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Office')">
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Email')">
+				</div>
+				<div class="row">
+					<label class="cell" for="telInput">Telephone:</label>
+					<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Tel')">
+				</div>
+				<div class="row">
+					<label class="cell" for="faxInput">Fax:</label>
+					<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" 
+								data-dojo-props="value: at('rel:', 'Fax')">
+				</div>
+			</div>
+		   </div>
+		 </div>
+		</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_shipto-billto-hierarchical.html b/dojox/mvc/tests/doh/doh_mvc_shipto-billto-hierarchical.html
new file mode 100644
index 0000000..5613b7e
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_shipto-billto-hierarchical.html
@@ -0,0 +1,218 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+		</style>
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: 1, mvc: {debugBindings: 1}"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dojo/when",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/ListController",
+				"dijit/registry",
+				"dijit/form/Button",
+				"dijit/form/TextBox",
+				"dojox/mvc/Group",
+				"dojo/domReady!"
+			], function(doh, parser, when, getStateful, ListController, registry){
+
+				ctrl = new ListController({model: getStateful({
+					Serial: "360324",
+					First: "John",
+					Last: "Doe",
+					Email: "jdoe at example.com",
+					ShipTo: {
+						Type: "Home",
+						Address: {
+							Street: "123 Valley Rd",
+							City: "Katonah",
+							State: "NY",
+							Zip: "10536"
+						},
+						Telephone: {
+							AreaCode: "123",
+							Landline: {
+								Number: "456-7890",
+								Extension: "42"
+							},
+							Cell: {
+								Number: "765-4321"
+							}
+						}
+					},
+					BillTo: {
+						Type: "Office",
+						Address: {
+							Street: "17 Skyline Dr",
+							City: "Hawthorne",
+							State: "NY",
+							Zip: "10532"
+						},
+						Telephone: {
+							AreaCode: "098",
+							Landline: {
+								Number: "765-4321",
+								Extension: "24"
+							},
+							Cell: {
+								Number: "123-4567"
+							}
+						}
+					}
+
+				}), cursorIndex: "ShipTo"});
+
+				when(parser.parse(), function(){
+					// should be able to verify all of the inputs
+					doh.register("Check values and bindings", [{
+						name: "Initial",
+						runTest: function(){
+							doh.is("360324", registry.byId("serialInput").get("value"), "serial1 should be set");
+							doh.is("ShipTo", registry.byId("addrLabel").get("value"), "addr1 should be set");
+							doh.is("123 Valley Rd", registry.byId("streetInput").get("value"), "street1 should be set");
+						}
+					}, {
+						name: "TestBillTo",
+						runTest: function(){
+							ctrl.set("cursorIndex", "BillTo");
+							doh.is("360324", registry.byId("serialInput").get("value"), "serial1 should be set");
+							doh.is("BillTo", registry.byId("addrLabel").get("value"), "addr1 should be set");
+							doh.is("17 Skyline Dr", registry.byId("streetInput").get("value"), "street1 should be set");
+						}
+					}, {
+						name: "TestShipTo",
+						runTest: function(){
+							ctrl.set("cursorIndex", "ShipTo");
+							doh.is("360324", registry.byId("serialInput").get("value"), "serial1 should be set");
+							doh.is("ShipTo", registry.byId("addrLabel").get("value"), "addr1 should be set");
+							doh.is("123 Valley Rd", registry.byId("streetInput").get("value"), "street1 should be set");
+						}
+					}, {
+						name: "ChangeShipTo",
+						runTest: function(){
+							ctrl.set("cursorIndex", "ShipTo");
+							registry.byId("streetInput").set("value","456 Mountain Rd");
+							ctrl.set("cursorIndex", "BillTo");
+							ctrl.set("cursorIndex", "ShipTo");
+							doh.is("360324", registry.byId("serialInput").get("value"), "serial1 should be set");
+							doh.is("ShipTo", registry.byId("addrLabel").get("value"), "addr1 should be set");
+							doh.is("456 Mountain Rd", registry.byId("streetInput").get("value"), "street1 should be set");
+							doh.is("Katonah", registry.byId("cityInput").get("value"), "city1 should be set");
+						}
+					}]);
+
+					doh.run();
+				});
+			});
+
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Order Shipping Details</h1>
+					<h2>Data Binding Example - Hierarchical data.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<!--
+						The group container denotes some logical grouping of widgets and also serves
+						to establish a parent data binding context for its children.
+						The ref attribute for the outermost container obtains the binding from the
+						"page scope" itself.
+					-->
+					<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model')">
+						<div class="row">
+							<label class="cell" for="serialInput">Order #:</label>
+							<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Serial')"/>
+						</div>
+						<div class="row">
+							<label class="cell" for="lastnameInput">Last name:</label>
+							<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')"/>
+						</div>
+						<div class="row">
+							<label class="cell" for="emailInput">Email:</label>
+							<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')"/>
+						</div>
+					</div>
+					<br/>
+					Choose:
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', 'ShipTo'); }">Ship To</button>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', 'BillTo'); }">Bill To</button>
+					<br/>
+					<div class="row">
+						<label class="cell" for="addrLabel">Selected Address:</label>
+						<input class="cell" id="addrLabel" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at(ctrl, 'cursorIndex')"/>
+					</div>
+					<br/>
+					<!--
+						For convenience, the widget hierarchy matches the data hierarchy
+						(see JSON literal above).
+						In this implementation, the child ref attributes are simple property names
+						of the parent binding context.
+						The ref attribute may support more advanced constructs, such as queries
+						over the parent widget's or other application specified binding context.
+					-->
+					<div id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'cursor')">
+						<div class="row">
+							<label class="cell" for="typeInput">Type:</label>
+							<input class="cell" id="typeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Type')"/>
+						</div>
+						<div id="postalGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Address')">
+							<div class="row">
+								<label class="cell" for="streetInput">Street:</label>
+								<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Street')"/>
+							</div>
+							<div class="row">
+								<label class="cell" for="cityInput">City:</label>
+								<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'City')"/>
+							</div>
+							<div class="row">
+								<label class="cell" for="stateInput">State:</label>
+								<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'State')"/>
+							</div>
+							<div class="row">
+								<label class="cell" for="zipInput">Zipcode:</label>
+								<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Zip')"/>
+							</div>
+						</div>
+						<div id="telGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Telephone')">
+							<div class="row">
+								<label class="cell" for="areacodeInput">Area code:</label>
+								<input class="cell" id="areacodeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'AreaCode')"/>
+							</div>
+							<div id="llGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Landline')">
+								<div class="row">
+									<label class="cell" for="numberInput">Landline Number:</label>
+									<input class="cell" id="numberInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Number')"/>
+								</div>
+								<div class="row">
+									<label class="cell" for="extInput">Extension:</label>
+									<input class="cell" id="extInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Extension')"/>
+								</div>
+							</div>
+							<div class="row" id="cellGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Cell')">
+								<label class="cell" for="cellInput">Cell Number:</label>
+								<input class="cell" id="cellInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Number')"/>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_sync-test.html b/dojox/mvc/tests/doh/doh_mvc_sync-test.html
new file mode 100644
index 0000000..5467909
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_sync-test.html
@@ -0,0 +1,218 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css">
+
+		<!-- required: dojo.js -->
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: 1, parseOnLoad: 0, async: 1"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dojo/when",
+				"dojo/Stateful",
+				"dijit/registry",
+				"dojox/mvc/sync",
+				"dijit/form/TextBox",
+				"dijit/form/NumberTextBox",
+				"dijit/form/ValidationTextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Output"
+			], function(doh, parser, when, Stateful, registry, sync){
+				model = new Stateful({
+					First: "John",
+					Last: "Doe",
+					Email: "jdoe at example.com",
+					Num: 3
+				});
+				model2 = new Stateful({
+					First: "John2",
+					Last: "Doe2",
+					Email: "jdoe2 at example.com",
+					Num: 2
+				});
+				model3 = new Stateful({
+					First: "",
+					Last: "",
+					Email: "",
+					Num: 3
+				});
+				model4 = new Stateful({
+					First: "John4",
+					Last: "Doe4",
+					Email: "jdoe4 at example.com",
+					Num: 4
+				});
+				model5 = new Stateful({
+					First: "",
+					Last: "",
+					Email: "",
+					Num: 5
+				});
+
+				function noParse(){
+					throw new Error();
+				}
+
+				readOnlyConverter = {
+					format: function(value){
+						return value === "2" || value === "3";
+					},
+					parse: noParse
+				};
+
+				relevanceConverter = {
+					format: function(value){
+						return value !== "0";
+					},
+					parse: noParse
+				};
+
+				numValidConverter = {
+					format: function(value){
+						return value !== "3" && !(value - 0 === 1);
+					},
+					parse: noParse
+				};
+
+				emailConverter = {
+					format: function(value){
+						return value + "formatted";
+					},
+					parse: noParse
+				};
+
+				requiredConverter = {
+					format: function(value){
+						return value - 0 === 4;
+					},
+					parse: noParse
+				};
+
+				lastValidConverter = {
+					format: function(value){
+						return value !== "1";
+					},
+					parse: noParse
+				};
+
+				when(parser.parse(), function(){
+					doh.register("Check sync values from 2 to 3", [{
+						name: "Initial",
+						runTest: function(){
+							// sync test
+							var firstx2 = "";
+							sync(model2, "First", model3, "First");							
+							doh.is("John2", model3.get("First"), "model3.First should be John2");
+							// set model3.First should update model2.First
+							model3.set("First", "Billy3");
+							doh.is("Billy3", model2.get("First"), "model2.First should now be Billy3");
+
+							sync(model2, "Last", model3, "Last", {bindDirection:sync.from});							
+					//		sync(model2, "Last", model3, "Last", {bindDirection:sync.to});							
+							doh.is("Doe2", model3.get("Last"), "model3.Last should be Doe2");
+							// set model3.Last should NOT update model2.Last
+							model3.set("Last", "Billy3");
+							doh.is("Doe2", model2.get("Last"), "model2.Last should still be Doe2");
+
+							sync(model2, "Num", model3, "Num", {bindDirection:sync.to});							
+							doh.is(3, model2.get("Num"), "model2.Num should be 3");
+							doh.is(3, model3.get("Num"), "model3.Num should be 3");
+						}
+					}, {
+						name: "TestSyncWildCard",
+						runTest: function(){
+							sync(model4, "*", model5, "*");							
+							doh.is("John4", model5.get("First"), "model5.First should be John4");
+							doh.is("Doe4", model5.get("Last"), "model5.Last should now be Doe4");
+							// set model5.Last should update model4.Last
+							model5.set("Last", "Upate5");
+							doh.is("Upate5", model4.get("Last"), "model4.Last should be Upate5");
+						}
+					}, {
+						name: "TestSyncConverter",
+						runTest: function(){
+							sync(model2, "Email", model3, "Email", {converter : emailConverter});							
+							doh.is("jdoe2 at example.comformatted", model3.get("Email"), "model3.Email should be jdoe2 at example.comformatted");
+							model2.set("Email", "Em2");
+							doh.is("Em2formatted", model3.get("Email"), "model3.Email should be Em2formatted");
+						//	doh.is("Doe4", model5.get("Last"), "model5.Last should now be Doe4");
+						}
+					}]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Binding Tests</h1>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav">
+				</div>
+				<div id="mainContent">
+					<h2>Bind Self Tests</h2>
+					<div class="row">
+						<label class="cell" for="firstnameInput">Model2 First:</label>
+						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.ValidationTextBox"
+						 data-dojo-props="value: at(model2, 'First')">
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						First name is: <span id="tout" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model2, 'First')"></span>
+					</div>
+					<div class="row">
+						<label class="cell" for="firstnameInput3">Model3 First:</label>
+						<input class="cell" id="firstnameInput3" data-dojo-type="dijit.form.ValidationTextBox"
+						 data-dojo-props="value: at(model3, 'First')">
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						First name is: <span id="tout3" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model3, 'First')"></span>
+					</div>
+					<div class="row">
+						<label class="cell" for="lastnameInput">Model2 Last:</label>
+						<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.ValidationTextBox"
+						 data-dojo-props="value: at(model2, 'Last')">
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						Last name is: <span id="lasttout" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model2, 'Last')"></span>
+					</div>
+					<div class="row">
+						<label class="cell" for="lastnameInput3">Model3 Last:</label>
+						<input class="cell" id="lastnameInput3" data-dojo-type="dijit.form.ValidationTextBox"
+						 data-dojo-props="value: at(model3, 'Last')">
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						Last name is: <span id="lasttout3" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model3, 'Last')"></span>
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput2">Email:</label>
+						<input class="cell" id="emailInput2" data-dojo-type="dijit.form.ValidationTextBox"
+						 data-dojo-props="value: at(model2, 'Email')">
+						Model2 Email is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model2, 'Email')"></span>
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput3">Email:</label>
+						<input class="cell" id="emailInput3" data-dojo-type="dijit.form.ValidationTextBox"
+						 data-dojo-props="value: at(model3, 'Email')">
+						Model3 Email is: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model3, 'Email')"></span>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_template_repeat_exprchar.html b/dojox/mvc/tests/doh/doh_mvc_template_repeat_exprchar.html
new file mode 100644
index 0000000..8eb03f3
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_template_repeat_exprchar.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Test</title>
+
+		<style>
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../css/app-format.css";
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+		<!-- required: dojo.js -->
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="isDebug: 1, parseOnLoad: 0"></script>
+		<script type="text/javascript" src="./helpers.js"></script>
+
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dojo/when",
+				"dijit/registry",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/ModelRefController",
+				"dojox/mvc/tests/test_templatedWidget/myMvcTemplated",
+				"dojo/domReady!"
+			], function(doh, parser, when, registry, getStateful, ModelRefController, myMvcTemplated){
+				ctrl = new ModelRefController({model: getStateful([
+					{
+						First: "Anne",
+						Last: "Ackerman",
+						Location: "NY",
+						Office: "1S76",
+						Email: "a.a at test.com",
+						Tel: "123-764-8237",
+						Fax: "123-764-8228"
+					}, {
+						First: "Ben",
+						Last: "Beckham",
+						Location: "NY",
+						Office: "5N47",
+						Email: "b.b at test.com",
+						Tel: "123-764-8599",
+						Fax: "123-764-8600"
+					}, {
+						First: "John",
+						Last: "Jacklin",
+						Location: "CA",
+						Office: "6701",
+						Email: "j.j at test.com",
+						Tel: "408-764-1234",
+						Fax: "408-764-4321"
+					}
+				])});
+
+				when(parser.parse(), function(){
+					// should be able to verify all of the inputs
+					doh.register("Check values", [
+						{
+							name : "Input0",
+							runTest: function(){
+								doh.is("Anne", registry.byId("nameInput0").value, "nameInput0 should be Anne");
+								doh.is("Anne", registry.byId("anameInput0").value, "anameInput0 should be Anne");
+								doh.is("Anne", registry.byId("bnameInput0").value, "bnameInput0 should be Anne");
+								doh.is("Anne", registry.byId("9nameInput0").value, "9nameInput0 should be Anne");
+							}
+						}, {
+							name : "Input1",
+							runTest: function(){
+								doh.is("Ben", registry.byId("nameInput1").value, "nameInput1 should be Ben");
+								doh.is("Ben", registry.byId("anameInput1").value, "anameInput1 should be Ben");
+								doh.is("Ben", registry.byId("bnameInput1").value, "bnameInput1 should be Ben");
+								doh.is("Ben", registry.byId("9nameInput1").value, "9nameInput1 should be Ben");
+							}
+						}, {
+							name : "Input2",
+							runTest: function(){
+								doh.is("John", registry.byId("nameInput2").value, "nameInput2 should be John");
+								doh.is("John", registry.byId("anameInput2").value, "anameInput2 should be John");
+								doh.is("John", registry.byId("bnameInput2").value, "bnameInput2 should be John");
+								doh.is("John", registry.byId("9nameInput2").value, "9nameInput2 should be John");
+							}
+						}
+					]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro" style="background-image: url(./images/master_detail.png)">
+		<div id="wrapper">
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div>
+						Test exprchar. Widget template test uses exprchar of # and others for template:#{this.index} etc.
+					</div>
+					<br/>
+					<div id="container2" data-dojo-type="dojox.mvc.tests.test_templatedWidget.myMvcTemplated" data-dojo-props="ctrl: ctrl"></div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_validation-test-simple.html b/dojox/mvc/tests/doh/doh_mvc_validation-test-simple.html
new file mode 100644
index 0000000..b750634
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_validation-test-simple.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH Validation Relevant Test</title>
+		<link rel="stylesheet" href="../../../../dojo/resources/dojo.css">
+		<link rel="stylesheet" href="../../../../dijit/themes/dijit.css">
+		<link rel="stylesheet" href="../../../../dijit/themes/claro/claro.css">
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1, mvc: {debugBindings: 1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/dom-class",
+				"dojo/parser",
+				"dojo/when",
+				"dojo/Stateful",
+				"dijit/registry",
+				"dojox/mvc/ModelRefController",
+				"dijit/form/NumberTextBox",
+				"dojox/mvc/_TextBoxExtensions"
+			], function(doh, domClass, parser, when, Stateful, registry, ModelRefController){
+
+				ctrl = new ModelRefController({
+					ownProps: {relation: 1, _setNum1Attr: 1, _setNum2Attr: 1},
+					relation: null,
+					model: new Stateful({num1: 10, num2: 20}),
+					_setNum1Attr: function(value){
+						this.set("relation", [value, this.get("num2")]);
+						this._set("num1", value);
+					},
+					_setNum2Attr: function(value){
+						this.set("relation", [this.get("num1"), value]);
+						this._set("num2", value);
+					}
+				});
+
+				disabledConverter = {
+					format: function(value){
+						return value && value[0] === value[1];
+					},
+					parse: function(value){
+						throw new Error();
+					}
+				};
+
+				validConverter = {
+					format: function(value){
+						return !value || value[0] < value[1];
+					},
+					parse: function(value){
+						throw new Error();
+					}
+				};
+
+				when(parser.parse(), function(){
+					// should be able to verify all of the inputs
+					doh.register("Check values and bindings", [
+						{
+							name: "initial",
+							runTest: function(){
+								var num1 = registry.byId("num1");
+								var num2 = registry.byId("num2");
+								doh.is(10, num1.get("value"), "num1 should be 10");
+								doh.is(20, num2.get("value"), "num2 should be 20");
+								doh.t(num1.isValid(), "num1.isValid() should be true");
+								doh.t(num2.isValid(), "num2.isValid() should be true");
+								doh.f(num2.disabled, "num2.disabled should be false");
+								doh.f(num1.disabled, "num1.disabled should be false");
+							}
+						}, {
+							name: "Update-Num1-invalid",
+							runTest: function(){
+								var num1 = registry.byId("num1");
+								var num2 = registry.byId("num2");
+								num1.set("displayedValue", "30");
+								doh.is(30, num1.get("value"), "num1 should be 30");
+								doh.f(num1.disabled, "num1.disabled should be false");
+								doh.is(20, num2.get("value"), "num2 should be 20");
+								doh.f(num2.isValid(), "num2.isValid() should be false");
+								doh.f(num2.disabled, "num2.disabled should be false");
+								doh.t(domClass.contains(num1.domNode, "dijitNumberTextBoxError"), "num1 should have the dijitNumberTextBoxError class");
+								doh.t(domClass.contains(num2.domNode, "dijitNumberTextBoxError"), "num2 should have the dijitNumberTextBoxError class");
+							}
+						}, {
+							name: "Update-Num1-disabled2",
+							runTest: function(){
+								var num1 = registry.byId("num1");
+								var num2 = registry.byId("num2");
+								num1.set("displayedValue", "21");
+								num2.set("displayedValue", "21");
+								doh.is(21, num1.get("value"), "num1 should be 21");
+								doh.is(21, num2.get("value"), "num2 should be 21");
+								doh.t(registry.byId("num2").disabled, "num2.disabled should be true");
+								doh.t(registry.byId("num1").disabled, "num1.disabled should be true");
+							}
+						}
+					]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<form method="post">
+			<div>
+				<label for="num1">Number 1</label>
+				<input id="num1" data-dojo-type="dijit.form.NumberTextBox"
+				 data-dojo-props="value: at(ctrl, 'num1'),
+				                  disabled: at(ctrl, 'relation').transform(disabledConverter),
+				                  valid: at(ctrl, 'relation').transform(validConverter)">
+			</div>
+			<div>
+				<label for="num2">Number 2</label>
+				<input id="num2" data-dojo-type="dijit.form.NumberTextBox"
+				 data-dojo-props="value: at(ctrl, 'num2'),
+				                  disabled: at(ctrl, 'relation').transform(disabledConverter),
+				                  valid: at(ctrl, 'relation').transform(validConverter)">
+			</div>
+		</form>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_mvc_zero-value-test.html b/dojox/mvc/tests/doh/doh_mvc_zero-value-test.html
new file mode 100644
index 0000000..82497ea
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_mvc_zero-value-test.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>DOH Async Simple Input - Output Group example</title>
+		<style type="text/css">
+			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			require([
+				"doh/runner",
+				"dojo/dom",
+				"dojo/parser",
+				"dojo/when",
+				"dojo/Stateful",
+				"dijit/registry",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojo/parser",
+				"dijit/form/Form",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojo/domReady!"
+			], function(doh, ddom, parser, when, Stateful, registry){
+				models = new Stateful;
+
+				when(parser.parse(), function(){
+					models.set("model", new Stateful({First: 0}));
+
+					doh.register("Check values and bindings", [{
+						name: "Initial",
+						runTest: function(){
+							doh.is("Priority: 0", ddom.byId("one").innerHTML, "One should be set to Priority: 0");
+							doh.is("0", ddom.byId("two").innerHTML, "One should be set to Priority: 0");
+							doh.is("0", registry.byId("FirstWork").get("value"), "FirstWork should be 0");
+							doh.is("0", registry.byId("First").get("value"), "First should be 0");
+						}
+					}, {
+						name: "Update-First-Name",
+						runTest: function(){
+							var first1;
+							first1 = registry.byId("First");
+							first1.set("value", 2);
+							if (first1) {
+								doh.is("Priority: 2", ddom.byId("one").innerHTML, "One should be set to Priority: 2");
+								doh.is("2", ddom.byId("two").innerHTML, "One should be set to Priority: 2");
+								doh.is("2",  registry.byId("FirstWork").get("value"), "FirstWork should be 2");
+								doh.is("2",  registry.byId("First").get("value"), "First should be 2");
+							}
+						}
+					}, {
+						name: "Test-ref-set-0",
+						runTest: function(){
+							var first1;
+							//test first relevant false
+							first1 = registry.byId("First");
+							first1.set("value", 0);
+							if (first1) {
+								doh.is("Priority: 0", ddom.byId("one").innerHTML, "One should be set to Priority: 0");
+								doh.is("0", ddom.byId("two").innerHTML, "One should be set to Priority: 0");
+								doh.is("0", registry.byId("FirstWork").get("value"), "FirstWork should be 0");
+								doh.is("0", registry.byId("First").get("value"), "First should be 0");
+							}
+						}
+					}]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body>
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div data-dojo-type="dijit.form.Form" data-dojo-mixins="dojox.mvc.Group" data-dojo-props="target: at(models, 'model')">
+			Working sample
+			<span> There should be "Priority : zero" here ===></span>
+			<span id="one" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:', 'First')">Priority: ${this.value}</span>
+			<span><== there should be "Priority : zero" here.</span>
+			<br>
+			Working sample 2
+			<span> There should be a zero here ===></span>
+			<span id="two" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:', 'First')"></span>
+			<span><== there should be a zero here.</span>
+			<br>
+			<br>
+			<ul>
+				<li>
+				<label for="FirstWork">Working</label>
+				<input name="FirstWork" id="FirstWork" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')" /></li>
+			</ul>
+			Here, id is the same as ref, this was not working before the fix for 14491
+			<ul>
+				<li>
+				<label for="First">Not working</label>
+				<input name="First" id="First" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')" /></li>
+				<!--	<input name="First" id="First" data-dojo-type="dijit.form.TextBox" /></li> -->
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_new-mvc_input-output-simple.html b/dojox/mvc/tests/doh/doh_new-mvc_input-output-simple.html
new file mode 100644
index 0000000..de06cc4
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_new-mvc_input-output-simple.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Simple Input-Output Data Binding Example</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1, mvc: {debugBindings: 1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			var model;
+
+			require([
+				"doh/runner",
+				"dojo/dom",
+				"dojo/parser",
+				"dojo/when",
+				"dijit/registry",
+				"dojox/mvc/getStateful",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output"
+			], function(doh, ddom, parser, when, registry, getStateful){
+				// The dojox.mvc.StatefulModel class creates a data model instance
+				// where each leaf within the data model is decorated with dojo.Stateful
+				// properties that widgets can bind to and watch for their changes.
+				//model = mvc.newStatefulModel({data :{"First": "John", "Last": "Doe", "Email": "jdoe at example.com"}});
+				model = getStateful({"First": "John", "Last": "Doe", "Email": "jdoe at example.com"});
+				// the StatefulModel created above is initialized with 
+				// model.First set to "John", model.Last set to "Doe" and model.Email set to "jdoe at example.com"
+				when(parser.parse(), function(){
+					doh.register("Synchronize text box and label", [{
+						name: "Check first value",
+						runTest: function(){
+							doh.is("John", registry.byId("firstnameInput").get("value"), "First should reflect initial data");
+							doh.is("Doe", registry.byId("lastnameInput").get("value"), "Last should reflect initial data");
+							doh.is("jdoe at example.com", registry.byId("emailInput").get("value"), "Email should reflect initial data");
+							doh.t(/\s*\(first name is: John\)\s*/, registry.byId("firstnameOut").innerHTML, "First should reflect initial data");
+							doh.t(/\s*\(last name is: Doe\)\s*/, registry.byId("lastnameOut").innerHTML, "Last should reflect initial data");
+							doh.t(/\s*\(email is: Doe\)\s*/, registry.byId("emailOut").innerHTML, "Email should reflect initial data");
+						}
+					}, {
+						name: "Check value sync",
+						runTest: function(){
+							model.set("First", "JohnJohn");
+							doh.t(/\s*\(first name is: JohnJohn\)\s*/, registry.byId("firstnameOut").innerHTML, "First should reflect the change");
+						}
+					}, {
+						name: "Check model reset",
+						setUp: function(){
+							model.set({"First": "John", "Last": "Doe", "Email": "jdoe at example.com"});
+							
+							//model.reset();
+						},
+						runTest: function(){
+							doh.is("John", registry.byId("firstnameInput").get("value"), "First should reflect initial data");
+							doh.is("Doe", registry.byId("lastnameInput").get("value"), "Last should reflect initial data");
+							doh.is("jdoe at example.com", registry.byId("emailInput").get("value"), "Email should reflect initial data");
+							doh.t(/\s*\(first name is: John\)\s*/, registry.byId("firstnameOut").innerHTML, "First should reflect initial data");
+							doh.t(/\s*\(last name is: Doe\)\s*/, registry.byId("lastnameOut").innerHTML, "Last should reflect initial data");
+							doh.t(/\s*\(email is: Doe\)\s*/, registry.byId("emailOut").innerHTML, "Email should reflect initial data");
+						}
+					}]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="row">
+						<label class="cell" for="firstnameInput">First:</label>
+						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at(model, 'First')"></input>
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						<span id="firstnameOut" data-dojo-type="dojox.mvc.Output" 
+												data-dojo-props="value: at(model, 'First')">
+							(first name is: ${this.value})
+						</span>
+					</div>
+					<div class="row">
+						<label class="cell" for="lastnameInput">Last:</label>
+						<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+										data-dojo-props="value: at(model, 'Last')"></input>
+						<span id="lastnameOut" data-dojo-type="dojox.mvc.Output" 
+												data-dojo-props="value: at(model, 'Last')">
+							(last name is: ${this.value})
+						</span>
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label>
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+										data-dojo-props="value: at(model, 'Email')"></input>
+						<span id="emailOut" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="value: at(model, 'Email')">
+							(email is: ${this.value})
+						</span>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/doh_new-mvc_label_and_totals.html b/dojox/mvc/tests/doh/doh_new-mvc_label_and_totals.html
new file mode 100644
index 0000000..aee9cde
--- /dev/null
+++ b/dojox/mvc/tests/doh/doh_new-mvc_label_and_totals.html
@@ -0,0 +1,304 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC Test for dynamic label and calculating totals</title>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+			.cell { width: 30%;  display:inline-block; }
+		</style>
+
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			var model;
+
+			require([
+				"doh/runner",
+				"dojo/dom",
+				"dojo/parser",
+				"dojo/when",
+				"dijit/registry",
+				"dojox/mvc/getStateful",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojox/mvc/Repeat",
+				"dojox/mvc/Output"
+			], function(doh, ddom, parser, when, registry, getStateful){
+
+				// Order data
+				orderData = {
+					"Serial" : "111",
+					"First" : "",
+					"Lab" : "TEST",
+					"Last" : "last",
+					"Email" : "email",
+					"Age" : "33"
+				};
+
+				// Initial sum data
+				sumData = {
+					"one" : 1,
+					"two" : 2,
+					"three" : 3,
+					"four" : 4,
+					"total" : 10
+				};
+
+				// Initial repeat sum data
+				sumRepeatData = {
+					"list" : [
+					          {"item" : 1},
+					          {"item" : 2},
+					          {"item" : 3},
+					          {"item" : 4}
+					          ],	
+					"total" : 10
+				};
+
+				sumValuesConverter = {
+						format: function(value){
+							console.log("in sumValuesConverter format value ="+value);
+							value = value || 0;
+							return value;
+						},
+						parse: function(value){
+							console.log("in sumValuesConverter parse value ="+value);
+							recomputeTotal();
+							return value;
+						}
+				};
+
+				ageLabelConverter = {
+						format: function(value){
+							console.log("in ageLabelConverter format value ="+value);
+							if(!value){
+								return "Enter Age";
+							}else{
+								return "Enter "+value+"'s age";
+							}
+						},
+						parse: function(value){
+							console.log("in ageLabelConverter parse value ="+value);
+							return value;
+						}
+				};
+
+
+				sumRepeatValuesConverter = {
+						format: function(value){
+							console.log("in sumRepeatValuesConverter format value ="+value);
+							value = value || 0;
+							return value;
+	//						recomputeRepeatTotal();
+	//						return value;
+						},
+						parse: function(value){
+							console.log("in sumRepeatValuesConverter parse value ="+value);
+							recomputeRepeatTotal();
+							return value;
+						}
+				};
+
+				//summodel = mvc.newStatefulModel({ data : sumData });
+				summodel = getStateful(sumData );
+
+				//sumrepeatmodel = mvc.newStatefulModel({ data : sumRepeatData });
+				sumrepeatmodel = getStateful(sumRepeatData);
+
+				//model = mvc.newStatefulModel({ data : order });
+				model = getStateful(orderData);
+				
+				function recomputeTotal() {
+					require([
+					         "dijit/registry",
+					         "dojox/mvc/at"
+					         ], function(registry, at){
+									var total = 0;			
+									var wone = parseInt(registry.byId("oneInput").get("value")) || 0;
+				   					var wtwo = parseInt(registry.byId("twoInput").get("value")) || 0;
+									var wthree = parseInt(registry.byId("threeInput").get("value")) || 0;
+				   					var wfour = parseInt(registry.byId("fourInput").get("value")) || 0;
+				   					total = wone + wtwo + wthree + wfour;
+				   					var wtotal = registry.byId("totalOutput");
+				   					wtotal.set("value", total);			   					
+								});
+				}
+
+				function recomputeRepeatTotal() {
+					require([
+					         "dijit/registry",
+					         "dojox/mvc/at"
+					         ], function(registry, at){
+									var total = 0;
+									for(var i=0;i<sumrepeatmodel.list.length;i++){
+										var item = parseInt(registry.byId("input"+i).get("value")) || 0;
+										console.log("sumrepeatmodel item = "+item);
+										total = total + item;
+									}
+				   					var wtotal = registry.byId("totalrepeatOutput");
+				   					wtotal.set("value", total);			   					
+								});
+				}
+
+				when(parser.parse(), function(){
+					recomputeTotal();
+
+					doh.register("Synchronize text box and label", [{
+						name: "Check first value",
+						runTest: function(){
+							doh.is("", registry.byId("firstInput").get("value"), "First should reflect initial data");
+							doh.is("last", registry.byId("lastnameInput").get("value"), "Last should reflect initial data");
+							doh.is("email", registry.byId("emailInput").get("value"), "Email should reflect initial data");
+							doh.t(/\s*\(Enter Age\)\s*/, registry.byId("ageOutput").innerHTML, "First should reflect initial data");
+							doh.is("10", registry.byId("totalOutput").get("value"), "totalOutput should reflect initial data");
+							doh.is("10", registry.byId("totalrepeatOutput").get("value"), "totalrepeatOutput should reflect initial data");						
+						}
+					}, {
+						name: "Change first and check age label",
+						runTest: function(){
+							model.set("First", "John");
+							doh.is("John", registry.byId("firstInput").get("value"), "First should reflect initial data");
+							doh.t(/\s*\(Enter John's Age\)\s*/, registry.byId("ageOutput").innerHTML, "First should reflect initial data");
+						}
+					}, {
+						name: "Change oneInput and item 0 and check totalOutput and totalrepeatOutput",
+						runTest: function(){
+							summodel.set("one", 11);
+							doh.is("20", registry.byId("totalOutput").get("value"), "totalOutput should reflect updated value");
+							sumrepeatmodel.list[0].set("item", 211);
+							doh.is("220", registry.byId("totalrepeatOutput").get("value"), "totalrepeatOutput should reflect updated value");
+						}
+					}, {
+						name: "blank oneInput and item 0 and check totalOutput and totalrepeatOutput",
+						runTest: function(){
+							summodel.set("one", "");
+							doh.is("9", registry.byId("totalOutput").get("value"), "totalOutput should reflect updated value");
+							doh.is("0", registry.byId("oneInput").get("value"), "oneInput should reflect updated value");
+							sumrepeatmodel.list[0].set("item", "");
+							doh.is("9", registry.byId("totalrepeatOutput").get("value"), "totalrepeatOutput should reflect updated value");
+							doh.is("0", registry.byId("input0").get("value"), "input0 should reflect updated value");
+						}
+					}, {
+						name: "Check model reset",
+						setUp: function(){
+							//model.reset();
+							//summodel.reset();
+							//sumrepeatmodel.reset();
+							summodel.set(sumData);
+							sumrepeatmodel.set(sumRepeatData);
+							model.set(orderData);
+						},
+						runTest: function(){
+							doh.is("", registry.byId("firstInput").get("value"), "First should reflect initial data");
+							doh.is("last", registry.byId("lastnameInput").get("value"), "Last should reflect initial data");
+							doh.is("email", registry.byId("emailInput").get("value"), "Email should reflect initial data");
+							doh.t(/\s*\(Enter Age\)\s*/, registry.byId("ageOutput").innerHTML, "First should reflect initial data");
+							doh.is("10", registry.byId("totalOutput").get("value"), "totalOutput should reflect initial data");
+							doh.is("10", registry.byId("totalrepeatOutput").get("value"), "totalrepeatOutput should reflect initial data");						
+						}
+						
+					}]);
+
+					doh.run();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<div id="wrapper">
+	<div id="header">
+		<div id="navigation">
+		</div>
+		<div id="headerInsert">
+			<h2>MVC Test for dynamic label and calculating totals</h2>
+		</div>
+	</div>
+	<div id="main">
+		<div id="leftNav"></div>
+		<div id="mainContent">
+		<h4>Update Age label with first name when it is set.</h4>
+		<div data-dojo-type="dojox.mvc.Group"
+			data-dojo-props="target: model">		
+			<div class="row">
+				<label class="cell" for="firstInput">Enter first name:</label>
+				<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'First')">
+				</div>
+			<div class="row">
+				<label class="cell" for="lastnameInput">Enter last name:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Last')">
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Enter email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Email')">
+			</div>
+			<div class="row">
+				<label data-dojo-type="dojox.mvc.Output" class="cell" for="ageInput" id="ageOutput"
+					data-dojo-props="value: at('rel:', 'First').direction(at.from).transform(ageLabelConverter)"></label>
+				<input class="cell" id="ageInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Age')">
+			</div>
+		</div>
+		<br/>
+		<h4>Update total when any of the fields are changed.</h4>
+		<div data-dojo-type="dojox.mvc.Group"
+			data-dojo-props="target: summodel">
+			<div class="row">
+				<label class="cell" for="oneInput">Item one:</label>
+				<input class="cell" id="oneInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'one').transform(sumValuesConverter)">
+			</div>
+			<div class="row">
+				<label class="cell" for="twoInput">Item two:</label>
+				<input class="cell" id="twoInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'two').transform(sumValuesConverter)">
+			</div>
+			<div class="row">
+				<label class="cell" for="threeInput">Item three:</label>
+				<input class="cell" id="threeInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'three').transform(sumValuesConverter)">
+			</div>
+			<div class="row">
+				<label class="cell" for="fourInput">Item four:</label>
+				<input class="cell" id="fourInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'four').transform(sumValuesConverter)">
+			</div>
+			<div class="row">
+			<label class="cell" for="totalOutput">Total:</label>
+			<div class="cell" id="totalOutput" data-dojo-type="dojox.mvc.Output" 
+				data-dojo-props="value: at('rel:', 'total')"></div>
+		</div>
+		<br/>
+		<h4>Update total when any of the fields are changed - Using a Repeat.</h4>
+		<div id="outergroupId" data-dojo-type="dojox.mvc.Group" 
+								data-dojo-props="target: sumrepeatmodel">
+			<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" 
+				data-dojo-props="children: at('rel:', 'list')">
+			<div data-dojo-type="dojox.mvc.Group"
+				data-dojo-props="target: at('rel:${this.index}')">
+				<div class="row">
+					<label class="cell" for="input${this.index}">Item ${this.index}:</label>
+					<input class="cell" id="input${this.index}" data-dojo-type="dijit.form.TextBox" 
+						data-dojo-props="value: at('rel:', 'item').transform(sumRepeatValuesConverter)">
+					</div>
+				</div>
+			</div>
+			<div class="row">
+				<label class="cell" for="totalrepeatOutput">Total:</label>
+				<div class="cell" id="totalrepeatOutput" data-dojo-type="dojox.mvc.Output" 
+					data-dojo-props="value: at('rel:', 'total')"></div>
+		</div>
+	</div>
+	<br/>
+	<br/>
+	Model:
+	<button id="reset" type="button" data-dojo-type="dijit.form.Button" 
+			data-dojo-props="onClick: function(){model.set(orderData);summodel.set(sumData);sumrepeatmodel.set(sumRepeatData);}">Reset</button>
+	</div></div></div></div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/doh/equals.js b/dojox/mvc/tests/doh/equals.js
new file mode 100644
index 0000000..63ce48f
--- /dev/null
+++ b/dojox/mvc/tests/doh/equals.js
@@ -0,0 +1,54 @@
+define([
+	"doh",
+	"dojox/mvc/getStateful",
+	"dojox/mvc/equals"
+], function(doh, getStateful, equals){
+	var a = [
+		{
+			uniqueId: 0,
+			Completed: false,
+			Subject: "Pick up my kids",
+			Due: new Date((new Date()).getTime() + 48 * 3600000),
+			Priority: 1,
+			Description: "At the kindergarden"
+		},
+		{
+			uniqueId: 1,
+			Completed: true,
+			Subject: "Take dojox.mvc learning course",
+			Due: new Date((new Date()).getTime() + 72 * 3600000),
+			Priority: 2,
+			Description: "Need to find course material at http://dojotoolkit.org/"
+		},
+		{
+			uniqueId: 2,
+			Completed: false,
+			Subject: "Wash my car",
+			Due: new Date((new Date()).getTime() + 120 * 3600000),
+			Priority: 3,
+			Description: "Need to buy a cleaner before that"
+		}
+	];
+
+	doh.register("dojox.mvc.tests.doh.equals", [
+		function equalsSimple(){
+			doh.t(equals(getStateful(a), getStateful(a)), "Two stateful object from the same data source should be equal");
+		},
+		function changeValue(){
+			var dst = getStateful(a), src = getStateful(a);
+			src[1].set("Priority", 3);
+			doh.f(equals(dst, src), "equals() should catch the change");
+			src[1].set("Priority", 2);
+			doh.t(equals(dst, src), "equals() should catch the change in src back to original");
+		},
+		function changeDate(){
+			var dst = getStateful(a), src = getStateful(a), d;
+			(d = new Date()).setTime(src[1].get("Due").getTime() + 72 * 3600000);
+			src[1].set("Due", d);
+			doh.f(equals(dst, src), "equals() should catch the change");
+			(d = new Date()).setTime(src[1].get("Due").getTime() - 72 * 3600000);
+			src[1].set("Due", d);
+			doh.t(equals(dst, src), "equals() should catch the change in src back to original");
+		}
+	]);
+});
diff --git a/dojox/mvc/tests/helpers.js b/dojox/mvc/tests/doh/helpers.js
similarity index 100%
rename from dojox/mvc/tests/helpers.js
rename to dojox/mvc/tests/doh/helpers.js
diff --git a/dojox/mvc/tests/doh/wildcard.js b/dojox/mvc/tests/doh/wildcard.js
new file mode 100644
index 0000000..99959b6
--- /dev/null
+++ b/dojox/mvc/tests/doh/wildcard.js
@@ -0,0 +1,21 @@
+define([
+	"doh",
+	"dojo/Stateful",
+	"dojox/mvc/at",
+	"dijit/form/TextBox"
+], function(doh, Stateful, at, TextBox){
+	doh.register("dojox.mvc.tests.doh.wildcard", [
+		function wildcard(){
+			var m0 = new Stateful({"placeHolder": "placeHolder0", "value": "Value0"}),
+			 m1 = new Stateful({"placeHolder": "placeHolder1", "value": "Value1"}),
+			 w = new TextBox({
+				"*": at(m1, "*"),
+				"placeHolder": at(m0, "placeHolder")
+			}, document.createElement("div"));
+
+			w.startup();
+
+			doh.is("Value1", w.textbox.value, "Widget's value should come from m1");
+		}
+	]);
+});
diff --git a/dojox/mvc/tests/doh_async_mvc_14491-input-output.html b/dojox/mvc/tests/doh_async_mvc_14491-input-output.html
deleted file mode 100644
index 82bbbad..0000000
--- a/dojox/mvc/tests/doh_async_mvc_14491-input-output.html
+++ /dev/null
@@ -1,162 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>DOH Async Simple Input - Output Group example</title>
-		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
-			@import "./css/dijitTests.css";
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
-<script type="text/javascript">
- 		var model;
- 
-		require([
-		'dojo/parser',
-        'dojox/mvc',
-		'dojox/mvc/Group',
-		'dojox/mvc/Output',
-		'dojo/parser',
-		'dijit/form/TextBox',
-		'dijit/form/Button'], function(){
-
-			// The dojox.mvc.StatefulModel class creates a data model instance
-			// where each leaf within the data model is decorated with dojo.Stateful
-			// properties that widgets can bind to and watch for their changes.
-			model = dojox.mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
-				require([
-					'doh/runner', 'dijit/dijit'
-				], function(){
-				require([
-					'dojo/domReady!'
-					], function(){
-						doh.register("parse", function() {
-							dojo.parser.parse();
-
-							var detailsGroup = dijit.byId('detailsGroup');
-							detailsGroup.set('ref', model);
-
-						});
-						// should be able to verify all of the inputs 
-						doh.register("check initial values and bindings", [{
-							name : "initial",
-							runTest : function() {
-								doh.is("John", dijit.byId("First").get('value'),"First should be John");
-								doh.is("John",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
-
-								doh.is("Doe", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe");
-								doh.is("Doe",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe");
-
-								doh.is("jdoe at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe at example.com");
-								doh.is("jdoe at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe at example.com");
-							}
-						}]);
-
-						doh.register("update first name", [{
-							name : "Update-First-Name",
-							runTest : function() {
-								var first1, bind1, addr1;
-								//test first relevant false
-								first1 = dijit.byId("First");
-								first1.set("value","John-update");
-								if (first1) {
-									doh.is("John-update", dijit.byId("First").get('value'),"First should be John");
-									doh.is("John-update",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
-								}
-							}
-						}]);
-						doh.register("update last name", [{
-							name : "Update-Last-Name",
-							runTest : function() {
-								var last;
-								//test first relevant false
-								last = dijit.byId("lastnameInput");
-								last.set("value","Doe-update");
-								if (last) {
-									doh.is("Doe-update", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe-update");
-									doh.is("Doe-update",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe-update");
-								}
-							}
-						}]);
-						doh.register("update last name", [{
-							name : "Update-Last-Name",
-							runTest : function() {
-								var last;
-								//test first relevant false
-								email = dijit.byId("emailInput");
-								email.set("value","jdoe-update at example.com");
-								if (email) {
-									doh.is("jdoe-update at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe-update at example.com");
-									doh.is("jdoe-update at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe-update at example.com");
-								}
-							}
-						}]);
-						doh.register("reset back to initial values and bindings", [{
-							name : "reset_test",
-							runTest : function() {
-								model.reset();
-								doh.is("John", dijit.byId("First").get('value'),"First should be John");
-								doh.is("John",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
-
-								doh.is("Doe", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe");
-								doh.is("Doe",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe");
-
-								doh.is("jdoe at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe at example.com");
-								doh.is("jdoe at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe at example.com");
-							}
-						}]);
-
-						doh.run();
-
-					});
-				});	
-		}); 
-		</script>
-</head>
-	<body class="claro">
-		<div id="wrapper">
-			<div id="header">
-				<div id="navigation"></div>
-				<div id="headerInsert">
-					<h1>Async Input Ouput Test</h1>
-					<h2>Data Binding Example</h2>
-				</div>
-			</div>
-			<div id="main">
-				<div id="leftNav"></div>
-				<div id="detailsGroup" dojoType="dojox.mvc.Group">
-					<div class="row">
-						<label class="cell" for="First">First:</label>
-						<input class="cell" id="First" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.First"></input>
-						<!-- Content in output below will always be in sync with value of textbox above -->
-						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'First'">
-						(first name is: ${this.value})
-						</span>
-					</div>
-				<div class="row">
-					<label class="cell" for="lastnameInput">Last:</label>
-					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Last"></input>
-					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Last'">
-						(last name is: ${this.value})
-					</span>
-				</div>
-				<div class="row">
-					<label class="cell" for="emailInput">Email:</label>
-					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Email"></input>
-					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Email'">
-					(email is: ${this.value})
-					</span>
-				</div>
-					<br/>Model:
-					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
-				</div>
-			</div>
-		</div>
-	</body>
-
-</html>
diff --git a/dojox/mvc/tests/doh_async_mvc_input-output-simple.html b/dojox/mvc/tests/doh_async_mvc_input-output-simple.html
deleted file mode 100644
index 2328349..0000000
--- a/dojox/mvc/tests/doh_async_mvc_input-output-simple.html
+++ /dev/null
@@ -1,158 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>DOH Async Simple Input - Output Group example</title>
-		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
-			@import "./css/dijitTests.css";
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
-<script type="text/javascript">
- 		var model;
- 
-		require([
-		'dojo/parser',
-        'dojox/mvc',
-		'dojox/mvc/Group',
-		'dojox/mvc/Output',
-		'dojo/parser',
-		'dijit/form/TextBox',
-		'dijit/form/Button'], function(){
-
-			// The dojox.mvc.StatefulModel class creates a data model instance
-			// where each leaf within the data model is decorated with dojo.Stateful
-			// properties that widgets can bind to and watch for their changes.
-			model = dojox.mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
-				require([
-					'doh/runner', 'dijit/dijit'
-				], function(){
-				require([
-					'dojo/domReady!'
-					], function(){
-						doh.register("parse", function() {
-							dojo.parser.parse();
-						});
-						// should be able to verify all of the inputs 
-						doh.register("check initial values and bindings", [{
-							name : "initial",
-							runTest : function() {
-								doh.is("John", dijit.byId("firstnameInput").get('value'),"firstnameInput should be John");
-								doh.is("John",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
-
-								doh.is("Doe", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe");
-								doh.is("Doe",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe");
-
-								doh.is("jdoe at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe at example.com");
-								doh.is("jdoe at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe at example.com");
-							}
-						}]);
-
-						doh.register("update first name", [{
-							name : "Update-First-Name",
-							runTest : function() {
-								var first1, bind1, addr1;
-								//test first relevant false
-								first1 = dijit.byId("firstnameInput");
-								first1.set("value","John-update");
-								if (first1) {
-									doh.is("John-update", dijit.byId("firstnameInput").get('value'),"firstnameInput should be John");
-									doh.is("John-update",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
-								}
-							}
-						}]);
-						doh.register("update last name", [{
-							name : "Update-Last-Name",
-							runTest : function() {
-								var last;
-								//test first relevant false
-								last = dijit.byId("lastnameInput");
-								last.set("value","Doe-update");
-								if (last) {
-									doh.is("Doe-update", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe-update");
-									doh.is("Doe-update",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe-update");
-								}
-							}
-						}]);
-						doh.register("update last name", [{
-							name : "Update-Last-Name",
-							runTest : function() {
-								var last;
-								//test first relevant false
-								email = dijit.byId("emailInput");
-								email.set("value","jdoe-update at example.com");
-								if (email) {
-									doh.is("jdoe-update at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe-update at example.com");
-									doh.is("jdoe-update at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe-update at example.com");
-								}
-							}
-						}]);
-						doh.register("reset back to initial values and bindings", [{
-							name : "reset_test",
-							runTest : function() {
-								model.reset();
-								doh.is("John", dijit.byId("firstnameInput").get('value'),"firstnameInput should be John");
-								doh.is("John",  dijit.byId("dojox_mvc_Output_0").get('value'),"dojox_mvc_Output_0 should be John");
-
-								doh.is("Doe", dijit.byId("lastnameInput").get('value'),"lastnameInput should be Doe");
-								doh.is("Doe",  dijit.byId("dojox_mvc_Output_1").get('value'),"dojox_mvc_Output_1 should be Doe");
-
-								doh.is("jdoe at example.com", dijit.byId("emailInput").get('value'),"emailInput should be jdoe at example.com");
-								doh.is("jdoe at example.com",  dijit.byId("dojox_mvc_Output_2").get('value'),"dojox_mvc_Output_2 should be jdoe at example.com");
-							}
-						}]);
-
-						doh.run();
-
-					});
-				});	
-		}); 
-		</script>
-</head>
-	<body class="claro">
-		<div id="wrapper">
-			<div id="header">
-				<div id="navigation"></div>
-				<div id="headerInsert">
-					<h1>Async Input Ouput Test</h1>
-					<h2>Data Binding Example</h2>
-				</div>
-			</div>
-			<div id="main">
-				<div id="leftNav"></div>
-				<div id="mainContent" dojoType="dojox.mvc.Group" data-dojo-props="ref: 'expr:model'">
-					<div class="row">
-						<label class="cell" for="firstnameInput">First:</label>
-						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.First"></input>
-						<!-- Content in output below will always be in sync with value of textbox above -->
-						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'First'">
-						(first name is: ${this.value})
-						</span>
-					</div>
-				<div class="row">
-					<label class="cell" for="lastnameInput">Last:</label>
-					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Last"></input>
-					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Last'">
-						(last name is: ${this.value})
-					</span>
-				</div>
-				<div class="row">
-					<label class="cell" for="emailInput">Email:</label>
-					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Email"></input>
-					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Email'">
-					(email is: ${this.value})
-					</span>
-				</div>
-					<br/>Model:
-					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
-				</div>
-			</div>
-		</div>
-	</body>
-
-</html>
diff --git a/dojox/mvc/tests/doh_async_mvc_mobile-demo.html b/dojox/mvc/tests/doh_async_mvc_mobile-demo.html
deleted file mode 100644
index e07e1ef..0000000
--- a/dojox/mvc/tests/doh_async_mvc_mobile-demo.html
+++ /dev/null
@@ -1,342 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>DOH Async MVC Mobile Demo Test</title>
-		<link rel="stylesheet" type="text/css" href="./mobile/demo/demo.css"/>		
-		<style>
-		
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			position: relative;
-		}
-		.mblEdgeToEdgeList {
-			background-color: #DBDDE2;
-		}
-		</style>
-<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
-
-<script type="text/javascript">
-var repeatModel, setRef, nextIndexToAdd, selectedIndex;
-var setRef, setDetailsContext, insertResult, updateView, updateModel;
-
-require([
-	'dojox/mobile/parser',
-	'dojox/mvc',
-	'dojox/mobile',
-	'dojox/mobile/ScrollableView',
-	'dojox/mobile/Button',
-	'dojox/mobile/TextArea',
-	'dojox/mvc/Group',
-	'dojox/mvc/Generate',
-	'dojox/mvc/Repeat',
-	'dojox/mobile/TextBox',
-	'dojox/mobile/ViewController',
-	'dojox/mobile/FixedSplitter',
-	'dojox/mobile/EdgeToEdgeList',
-	'dojox/mobile/EdgeToEdgeCategory',
-	'dojox/mobile/deviceTheme',
-	'dojox/mobile/RoundRectCategory',
-	'dojox/mobile/Heading',
-	'dojo/data/ItemFileWriteStore',
-	'dojo/store/DataStore'	
-], function(){
-	require([
-	         "dojox/mobile/compat"
-	]);
-
-	var names = {
-	"Serial" : "360324",
-	"First"  : "John",
-	"Last"   : "Doe",
-	"Email"  : "jdoe at us.ibm.com",
-	"ShipTo" : {
-		"Street" : "123 Valley Rd",
-		"City"   : "Katonah",
-		"State"  : "NY",
-		"Zip"    : "10536"
-	},
-	"BillTo" : {
-		"Street" : "17 Skyline Dr",
-		"City"   : "Hawthorne",
-		"State"  : "NY",
-		"Zip"    : "10532"
-	}
-};
-
-selectedIndex = 0;
-
-model = dojox.mvc.newStatefulModel({ data : names });
-repeatmodel = null;  // use store for repeat data 
-nextIndexToAdd = -1;
-
- // used in the Ship to - Bill to demo
-setRef = function(id, addrRef) {
-	var widget = dijit.byId(id);
-	widget.set("ref", addrRef);
-}
-
-// used in the Repeat Data binding demo
-setDetailsContext = function(index){
-	selectedIndex = index;
-	var groupRoot = dijit.byId("detailsGroup");
-	groupRoot.set("ref", index);
-}
-
-// used in the Repeat Data binding demo
-insertResult = function(index){
-	if (repeatmodel[index-1].First.value !== ""){ // TODO: figure out why we are getting called twice for each click
-		var insert = dojox.mvc.newStatefulModel({ "data" : {
-			"First"   : "",
-			"Last"    : "",
-			"Location": "CA",
-			"Office"  : "",
-			"Email"   : "",
-			"Tel"     : "",
-			"Fax"     : ""} 
-		});
-		repeatmodel.add(index, insert);
-		setDetailsContext(index);
-		nextIndexToAdd++;
-	}else{
-		setDetailsContext(index-1);                 
-	}
-};
-
-// used in the Generate View demo
-var genmodel;
-updateView = function() {
-	try {
-		var modeldata = dojo.fromJson(dojo.byId("modelArea").value);
-		genmodel = dojox.mvc.newStatefulModel({ data : modeldata });
-		dijit.byId("view").set("ref", genmodel);
-		dojo.byId("outerModelArea").style.display = "none";
-		dojo.byId("viewArea").style.display = "";              		
-	}catch(err){
-		console.error("Error parsing json from model: "+err);
-	}
-};
-
-// used in the Generate View demo
-updateModel = function() {
-	dojo.byId("outerModelArea").style.display = "";
-	try {
-		dojo.byId("modelArea").focus(); // hack: do this to force focus off of the textbox, bug on mobile?
-		dojo.byId("viewArea").style.display = "none";
-		dijit.byId("modelArea").set("value",(dojo.toJson(genmodel.toPlainObject(), true)));
-	} catch(e) {
-		console.log(e);
-	};
-};
-
-
-// The dojox.mvc.StatefulModel class creates a data model instance
-// where each leaf within the data model is decorated with dojo.Stateful
-// properties that widgets can bind to and watch for their changes.
-var writeStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests._data", "mvcRepeatData.json")});
-var modelPromise = dojox.mvc.newStatefulModel({store: new dojo.store.DataStore({store: writeStore}), query:{"Location" : "CA"}}); // example of using a query parm for Location 
-
-				require([
-					'doh/runner', 'dijit/dijit'
-				], function(){
-				require([
-					'dojo/domReady!'
-					], function(){
-				modelPromise.then(function(results){ 
-					repeatmodel = results;
-					nextIndexToAdd = repeatmodel.data.length;
-					console.log("before call to parser.parse");
-					dojox.mobile.parser.parse();
-					console.log("before call to set the wholepage style for display");	
-					dojo.byId("wholepage").style.display = "";
-					console.log("after call to set the wholepage style for display");	
-						doh.register("check initial display", [{
-							name : "initial",
-							runTest : function() {
-								var x = dojo.query(".mblListItemLabel");
-								var y0 = dojo.query(".mblListItemLabel", dijit.byId("sdb").domNode)[0].innerHTML;
-								var y1 = dojo.query(".mblListItemLabel", dijit.byId("rdb").domNode)[0];
-								var y2 = dojo.query(".mblListItemLabel", dijit.byId("sfg").domNode)[0];
-								console.debug("dijit.byId(sdb).domNode)[0].innerHTML is ["+y0+"]");
-								doh.is("Simple Data Binding", dojo.trim(dojo.query(".mblListItemLabel", dijit.byId("sdb").domNode)[0].innerHTML),"first one should be Simple Data Binding");
-								doh.is("Repeat Data Binding", dojo.trim(dojo.query(".mblListItemLabel", dijit.byId("rdb").domNode)[0].innerHTML),"first one should be Simple Data Binding");
-								doh.is("Simple Form Generate", dojo.trim(dojo.query(".mblListItemLabel", dijit.byId("sfg").domNode)[0].innerHTML),"first one should be Simple Data Binding");
-							}
-						}]);
-						doh.run();
-				});
-			});
-		});
-
-dojo.addOnLoad(function() {
-});
-
-}); // end function
-		</script>
-</head>
-	<body>
-	<div id="wholepage" style="display:none">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Mobile MVC Views</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="sdb" dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" transition="slide" moveTo="settings">
-					Simple Data Binding
-				</li>
-				<li id="rdb" dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" transition="slide" moveTo="repeat">
-					Repeat Data Binding
-				</li>
-				<li id="sfg" dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" transition="slide" moveTo="generate">
-					Simple Form Generate
-				</li>
-			</ul>
-		</div>
-
-	<div id="settings" dojoType="dojox.mobile.ScrollableView">
-		<h1 id="home" dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Data Binding Example</h1>
-		<form name="testForm" id="testForm">	
-		<div class="field-title">Ship to - Bill to Address</div>
-			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
-				<div class="field-row">
-					<span>Order #</span>
-					<input id="lastnameInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Order #" ref="'rel:Serial'"/>
-				</div>
-				<div class="field-row">
-					<span>Last</span>
-					<input  id="serialInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Last'"/>
-				</div>
-				<div class="field-row">
-					<span>Email</span>
-					<input  id="emailInput1" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Email'"/>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
-			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
-			<br/>
-			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
-				<div class="field-row">
-					<span>Street</span>
-					<input  id="streetInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Street" ref="'rel:Street'"/>
-				</div>
-				<div class="field-row">
-					<span>City</span>
-					<input  id="cityInput" dojoType="dojox.mobile.TextBox"
-						placeholder="City" ref="'rel:City'"/>
-				</div>
-				<div class="field-row">
-					<span>State</span>
-					<input  id="stateInput" dojoType="dojox.mobile.TextBox"
-						placeholder="State" ref="'rel:State'"/>
-				</div>
-				<div class="field-row">
-					<span>ZIP Code</span>
-					<input  id="zipInput" dojoType="dojox.mobile.TextBox"
-						placeholder="ZIP Code" ref="'rel:Zip'"/>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
-		</form>
-	</div>
-
-	<div id="repeat" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Repeat Data Binding Example</h1>
-		<form name="repeatTestForm" id="repeatTestForm">	
-		<div class="field-title">Search Results</div>
-			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
-				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
-					<div class="row">			 
-						<input dojoType="dojox.mobile.TextBox"
-							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
-						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
-					</div>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
-				<div id="detailsBanner">Details for selected index:</div>
-					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
-						<div class="field-row">
-							<span>First Name</span>
-							<input  id="firstInput" dojoType="dojox.mobile.TextBox"
-								placeholder="First Name" ref="'rel:First'"/>
-						</div>
-						<div class="field-row">
-							<span>Last Name</span>
-							<input id="lastInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Last Name" ref="'rel:Last'"/>
-						</div>
-						<div class="field-row">
-							<span>Email</span>
-							<input  id="emailInput2" dojoType="dojox.mobile.TextBox"
-								placeholder="Email" ref="'rel:Email'"/>
-						</div>
-						<div class="field-row">
-							<span>Telephone</span>
-							<input  id="telInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Telephone" ref="'rel:Tel'"/>
-						</div>
-					</div>
-				</div>
-			<div class="spacer"></div>
-			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
-			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
-			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
-		</form>
-
-	</div>
-
-	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
-		<h1 data-dojo-type="dojox.mobile.Heading" back="Home" moveTo="foo">Simple Form Generate Example</h1>
-		<div class="field-title"></div>
-			<div id="main">
-				<div id="leftNav"></div>
-				<div id="mainContent" class="generate-maincontent">
-					<div id="outerModelArea">
-						<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Model</h3>
-						<div class="generate-textarea-row">
-							<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
-{
-	"Serial": "11111",
-	"First": "John",
-	"Last": "Doe",
-	"Email": "jdoe at example.com",
-	"Phones": [
-		{
-			"Office": "111-111-1111"
-		},
-		{
-			"Mobile": "222-222-2222"
-		}
-	]
-}
-							</textarea>
-						</div>
-						<div class="fieldset">
-							<div class="spacer"></div>
-							<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
-						</div>
-					</div>
-					<div id="viewArea" style="display:none">
-						<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Generated View</h3>
-							<div class="fieldset">
-							<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
-						</div>
-						<div class="fieldset">
-							<div class="spacer"></div>
-							<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
-						</div>
-					</div>
-				</div>
-			</div>
-		</div>
-	</div>
-	</body>
-
-</html>
diff --git a/dojox/mvc/tests/doh_mvc_binding-simple.html b/dojox/mvc/tests/doh_mvc_binding-simple.html
deleted file mode 100755
index 7a24741..0000000
--- a/dojox/mvc/tests/doh_mvc_binding-simple.html
+++ /dev/null
@@ -1,429 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>MVC DOH Test</title>
-
-	<style>
-		@import "../../../dojo/resources/dojo.css";
-		@import "./css/dijitTests.css";
-		@import "css/app-format.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script src="../../../dojo/dojo.js" type="text/javascript"
-		djConfig="isDebug: true">
-	</script>
-	<script type="text/javascript" src="./helpers.js"></script>
-
-	<script type="text/javascript">
-		dojo.require("dojox.mvc");
-		dojo.require("dojox.mvc.Output");
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dijit.form.NumberTextBox");
-		dojo.require("dijit.form.ValidationTextBox");
-		dojo.require("dijit.form.Button");
-		dojo.require("dojo.parser");
-
-		// The dojox.mvc.StatefulModel class creates a data model instance
-		// where each leaf within the data model is decorated with dojo.Stateful
-		// properties that widgets can bind to and watch for their changes.
-		var model = dojox.mvc.newStatefulModel({ data : 
-			{	"First" : "John", 
-				"Last" : "Doe", 
-				"Email" : "jdoe at example.com", 
-				"Num" : 3 
-			}
-		});
-
-		function testFirstRelevance(newValue) {
-			//newValue = model.First.value;
-			if ( newValue !== "0" ) return true;
-			else return false;
-		}
-
-		function testFirstReadOnly(newValue) {
-			if ( newValue !== "2" && newValue !== "3"  ) return false;
-			else return true;
-		}
-
-		function testNumValid(newValue) {
-			if ( newValue !== 1 && newValue !== "1"	 && newValue !== "3") return true;
-			else return false;
-		}
-
-		function testRequired(newValue) {
-			if ( newValue !== 4 && newValue !== "4") return false;
-			else return true;
-		}
-
-		function testLastRelevance(newValue) {
-			//newValue = model.First.value;
-			if ( newValue !== "0" ) return true;
-			else return false;
-		}
-
-		function testLastValid(newValue) {
-			if ( newValue !== "1" ) return true;
-			else return false;
-		}
-		
-		  
-		function init(){
-			// bindSelfProperties tests
-			//"readOnly"
-		}
-		  
-	</script>
-
-	<script type="text/javascript">
-		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
-
-		dojo.addOnLoad(function() {
-
-		doh.register("parse", function() {
-			dojo.parser.parse();
-		});
-
-		// Setup Bindings
-		dojox.mvc.bind(model.First, "value", model.First, "readOnly", testFirstReadOnly, true);
-		dojox.mvc.bind(model.First, "value", model.First, "relevant", testFirstRelevance, true);
-		dojox.mvc.bind(model.First, "value", model.First, "valid", testNumValid, true);
-		dojox.mvc.bind(model.Num, "value", model.Num, "valid", testNumValid, true);
-
-		// bind tests bind Last value to Email relevant and valid
-		dojox.mvc.bind(model.Last, "value", model.Email, "relevant", testFirstRelevance, true);
-		dojox.mvc.bind(model.Last, "value", model.Email, "valid", testNumValid, true);
-		dojox.mvc.bind(model.Last, "value", model.Email, "readOnly", testFirstReadOnly, true);
-		dojox.mvc.bind(model.Last, "value", model.Email, "required", testRequired, true);
-		dojox.mvc.bind(model.Last, "value", model.Email, "value");
-
-		// should be able to verify all of the inputs 
-		doh.register("check initial values and bindings", [{
-			name : "initial",
-			runTest : function() {
-				// First test an empty array
-				var m = new dojox.mvc.newStatefulModel({ data: {arr: []} });
-				doh.is([],m.arr.toPlainObject(),"m.arr.toPlainObject()should be [].");
-				doh.is("object",typeof m.arr.toPlainObject(),"m.arr.toPlainObject() should be an object (array)");
-				doh.is(0,m.arr.toPlainObject().length,"m.arr.toPlainObject().length should be 0 for [].");
-
-				var m2 = new dojox.mvc.newStatefulModel({ data: {str: ""} });
-				doh.is("",m2.str.toPlainObject(),"m2.str.toPlainObject()should be [].");
-				doh.is("string",typeof m2.str.toPlainObject(),"m2.str.toPlainObject() should be a string.");
-				doh.is(0,m2.str.toPlainObject().length,"m2.str.toPlainObject().length should be 0 for an empty string.");
-
-
-				var first1, bind1, addr1;
-				//test serialInput
-				first1 = dijit.byId("firstnameInput");
-				if (first1) {
-					bind1 = first1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false");
-						//doh.t(bind1.relevant,"bind1.relevant should be true");
-						doh.f(bind1.required,"bind1.required should be false");
-						//doh.t(bind1.valid,"bind1.valid should be true");
-					}
-				}
-				//test emailInput
-				addr1 = dijit.byId("emailInput");
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false");
-						//doh.t(bind1.relevant,"bind1.relevant should be true");
-						doh.f(bind1.required,"bind1.required should be false");
-						//doh.t(bind1.valid,"bind1.valid should be true");
-					}
-				}
-			}
-		}]);
-
-		doh.register("check FirstUpdate", [{
-			name : "testFirstUpdate",
-			runTest : function() {
-				//setRef("addrGroup", masterRecord.BillTo);
-				var first1, bind1, addr1;
-				//test first relevant false
-				first1 = dijit.byId("firstnameInput");
-				first1.set("value","0");
-				if (first1) {
-					bind1 = first1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false");
-						doh.f(bind1.relevant,"bind1.relevant should be false");
-						doh.f(bind1.required,"bind1.required should be false");
-						doh.t(bind1.valid,"bind1.valid should be true");
-					}
-				}
-				//test first valid false
-				first1.set("value","1");
-				if (first1) {
-					bind1 = first1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false for value = 1");
-						doh.t(bind1.relevant,"bind1.relevant should be true for value = 1");
-						doh.f(bind1.required,"bind1.required should be false for value = 1");
-						doh.f(bind1.valid,"bind1.valid should be false for value = 1");
-					}
-				}
-				//test first readOnly true
-				first1.set("value","2");
-				if (first1) {
-					bind1 = first1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.t(bind1.relevant,"bind1.relevant should be true for value = 2");
-						doh.f(bind1.required,"bind1.required should be false for value = 2");
-						doh.t(bind1.valid,"bind1.valid should be true for value = 2");
-						doh.t(bind1.readOnly,"bind1.readOnly should be true for value = 2");
-					}
-				}
-				//test first readOnly true and valid false
-				first1.set("value","3");
-				if (first1) {
-					bind1 = first1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.t(bind1.readOnly,"bind1.readOnly should be true for value = 3");
-						doh.t(bind1.relevant,"bind1.relevant should be true for value = 3");
-						doh.f(bind1.required,"bind1.required should be false for value = 3");
-						doh.f(bind1.valid,"bind1.valid should be false for value = 3");
-					}
-				}
-				//test first back to original
-				first1.set("value","5");
-				if (first1) {
-					bind1 = first1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false for value = 5");
-						doh.t(bind1.relevant,"bind1.relevant should be true for value = 5");
-						doh.f(bind1.required,"bind1.required should be false for value = 5");
-						doh.t(bind1.valid,"bind1.valid should be ture for value = 5");
-					}
-				}
-			}
-		}]);
-
-
-		doh.register("check NumUpdate", [{
-			name : "testNumUpdate",
-			runTest : function() {
-				var first1, bind1, addr1;
-				//test first valid false
-				num1 = dijit.byId("numInput");
-				num1.set("value",1);
-				if (num1) {
-					bind1 = num1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false for value = 1");
-						//doh.t(bind1.relevant,"bind1.relevant should be true for value = 1");
-						doh.f(bind1.required,"bind1.required should be false for value = 1");
-						doh.f(bind1.valid,"bind1.valid should be false for value = 1");
-					}
-				}				
-				num1.set("value",5);
-				if (num1) {
-					bind1 = num1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false for value = 5");
-						//doh.t(bind1.relevant,"bind1.relevant should be true for value = 5");
-						doh.f(bind1.required,"bind1.required should be false for value = 5");
-						doh.t(bind1.valid,"bind1.valid should be true for value = 5");
-					}
-				}				
-			}
-		}]);
-
-		doh.register("check emailUpdate", [{
-			name : "testNumUpdate",
-			runTest : function() {
-				var last1, email1, bind1, addr1;
-				//test first valid false
-				last1 = dijit.byId("lastnameInput");
-				email1 = dijit.byId("emailInput");
-				
-				//test last = 5 for original
-				last1.set("value","5");
-				if (email1) {
-					bind1 = email1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false for email value = 5");
-						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 5");
-						doh.f(bind1.required,"bind1.required should be false for email value = 5");
-						doh.t(bind1.valid,"bind1.valid should be true for email value = 5");
-					}
-				}				
-				//test last = 0 for email relevant = false
-				last1.set("value","0");
-				if (email1) {
-					bind1 = email1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false for email value = 0");
-						doh.f(bind1.relevant,"bind1.relevant should be false for email value = 0");
-						doh.f(bind1.required,"bind1.required should be false for email value = 0");
-						doh.t(bind1.valid,"bind1.valid should be true for email value = 0");
-					}
-				}				
-				//test last = 1 for email valid = false
-				last1.set("value","1");
-				if (email1) {
-					bind1 = email1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false for email value = 1");
-						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 1");
-						doh.f(bind1.required,"bind1.required should be false for email value = 1");
-						doh.f(bind1.valid,"bind1.valid should be false for email value = 1");
-					}
-				}				
-				//test last = 2 for email readOnly true
-				last1.set("value","2");
-				if (email1) {
-					bind1 = email1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.t(bind1.readOnly,"bind1.readOnly should be true for email value = 2");
-						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 2");
-						doh.f(bind1.required,"bind1.required should be false for email value = 2");
-						doh.t(bind1.valid,"bind1.valid should be true for email value = 2");
-					}
-				}				
-				//test last = 3 for email readOnly true and email valid = false
-				last1.set("value","3");
-				if (email1) {
-					bind1 = email1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.t(bind1.readOnly,"bind1.readOnly should be true for email value = 3");
-						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 3");
-						doh.f(bind1.required,"bind1.required should be false for email value = 3");
-						doh.f(bind1.valid,"bind1.valid should be false for email value = 3");
-					}
-				}				
-				//test last = 4 for email required true 
-				last1.set("value","4");
-				if (email1) {
-					bind1 = email1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false for email value = 4");
-						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 4");
-						doh.t(bind1.required,"bind1.required should be true for email value = 4");
-						doh.t(bind1.valid,"bind1.valid should be true for email value = 4");
-					}
-				}				
-
-				//test last = 5 for back to original
-				last1.set("value","5");
-				if (email1) {
-					bind1 = email1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.f(bind1.readOnly,"bind1.readOnly should be false for email value = 5");
-						//doh.t(bind1.relevant,"bind1.relevant should be true for email value = 5");
-						doh.f(bind1.required,"bind1.required should be false for email value = 5");
-						doh.t(bind1.valid,"bind1.valid should be true for email value = 5");
-					}
-				}				
-			
-			}
-		}]);
-
-		doh.run();
-
-		});
-	</script>
-</head>
-
-	<body class="claro">
-		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>Binding Tests</h1>
-		  </div>
-		</div>
-		<div id="main">
-		  <div id="leftNav">
-		  </div>
-		  <div id="mainContent">
-			<h2>Bind Self Tests</h2>
-			<div class="row">
-				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 0 to test for Relevant false (use Reset to re-enable)</label>
-				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 1 to test for Valid false.</label>
-				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 2 to test for ReadOnly false (use Reset to re-enable)</label>
-				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 3 to test for ReadOnly false and Valid false (use Reset to re-enable)</label>
-			</div>			
-			<div class="row">
-				<label class="cell" for="firstnameInput">First:</label>
-				<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.ValidationTextBox"
-									data-dojo-props="ref: model.First"/>
-				<!-- Content in output below will always be in sync with value of textbox above -->
-				<span id="tout" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
-					(first name is: ${this.value})
-				</span>
-				
-			</div>
-		   <div class="row">
-				<label class="cell" for="firstnameInput"></label>
-				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
-					Relevant is:  ${this.ref.relevant}, Valid is: ${this.ref.valid}, ReadOnly is: ${this.ref.readOnly})
-				</span>			   
-			</div>
-			<div class="row">
-				<label style="display:inline-block; width:100%; text-align:left;">Num: Enter 1 for Valid false</label>
-			</div>
-			<div class="row">
-				<label class="cell" for="numInput">Num:</label>
-				<input class="cell" id="numInput" data-dojo-type="dijit.form.NumberTextBox"
-									data-dojo-props="ref: model.Num"/>
-				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Num">
-					(num is: ${this.value})
-				</span>
-			</div>
-			<h2>Bind Tests</h2>
-			<div class="row">
-				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 0 to test for Relevant false for Email.</label>
-				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 1 to test for Valid false for Email.</label>
-				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 2 to test for ReadOnly true for Email.</label>
-				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 3 to test for ReadOnly true and Valid false for Email.</label>
-				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 4 to test for Required true for Email.</label>
-			</div>			
-			
-			<div class="row">
-				<label class="cell" for="lastnameInput">Last:</label>
-				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Last"/>
-				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Last">
-					(last name is: ${this.value})
-				</span>
-			</div>
-			<div class="row">
-				<label class="cell" for="emailInput">Email:</label>
-				<input class="cell" id="emailInput" data-dojo-type="dijit.form.ValidationTextBox"
-									data-dojo-props="ref: model.Email"/>
-				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
-					(email is: ${this.value})
-				</span>
-			</div>
-		   <div class="row">
-				<label class="cell" for="emailInput"></label>
-				<span id="emailOut" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
-					Relevant is:  ${dijit.byId("emailInput").ref.relevant}, Valid is: ${this.ref.valid}, ReadOnly is: ${this.ref.readOnly}, Required is: ${this.ref.required})
-				</span>
-		   </div>
-			
-			<br/>Model:
-			<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){doReset()}">Reset</button>
-		  </div>
-		</div></div>
-		<script type="text/javascript">
-			function doReset() {
-				model.reset();
-			}
-		</script>
-		
-	</body>
-
-</html>
diff --git a/dojox/mvc/tests/doh_mvc_date_test.html b/dojox/mvc/tests/doh_mvc_date_test.html
deleted file mode 100644
index 5923e86..0000000
--- a/dojox/mvc/tests/doh_mvc_date_test.html
+++ /dev/null
@@ -1,711 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>DOH MVC Date Binding Test</title>
-		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:0" src="../../../dojo/dojo.js"></script>
-<script type="text/javascript">
- 		var model;
- 
-		require([
-			'dijit/form/DateTextBox',
-			'dijit/CalendarLite',
-			'dojox/mvc/StatefulModel',
-			'dijit/form/Button',
-			'dojox/mvc/Output',
-			'dijit/form/TextBox',
-			'dojo/date/stamp',
-			'dojox/mvc',
-			'dojo/on',
-			'dojo/domReady!'
-		], function (DateTextBox, Calendar, StatefulModel, Button, Output, TextBox, dateStamp) {
-
-			// *** Test1 setup begin: ***
-			var test1_init = dateStamp.fromISOString("1987-08-01"); // 8/1/1987
-			test1_model = new StatefulModel({
-				data: {
-					date: test1_init
-				}
-			});
-			var test1_cal = new Calendar({
-				ref: test1_model.date // bind to model.date
-			}, document.getElementById('test1_cal'));
-			test1_cal.startup();
-
-			var test1_cal2 = new Calendar({
-				ref: test1_model.date // bind to model.date
-			}, document.getElementById('test1_cal2'));
-			test1_cal2.startup();
-
-			var test1_txt2 = new TextBox({
-				ref: test1_model.date
-			}, document.getElementById('test1_txt2'));
-			dojo.style(test1_txt2.domNode, "width", "368px");
-			test1_txt2.startup();
-
-			var test1_out2 = new Output({
-				ref: test1_model.date // bind to model.date
-			}, document.getElementById('test1_output2'));
-			test1_out2.startup();
-
-			var test1_setday2 = new Button({
-				label: 'Set Calendar to dateStamp.fromISOString("1989-09-07") (Sep 7 1989)', 
-				onClick: function() {
-							//console.log("test1_setday2 called");
-							//var day2 = new Date(1989,9,7);  // 9/7/1989
-							//var day2 = new Date("1989-09-07");  // 9/7/1989
-							var day2 = dateStamp.fromISOString("1989-09-07"); // 9/7/1989
-							test1_cal2.set("value", day2);
-						} 
-			}, document.getElementById('test1_setdate1'));
-			test1_setday2.startup();
-
-			var test1_settext2 = new Button({
-				label: 'Set TextBox to dateStamp.fromISOString("1991-05-05") (May 5, 1991)', 
-				onClick: function() {
-							//test1_txt2.set("value", new Date("1993-05-05")); // ISO date format  
-							test1_txt2.set("value", dateStamp.fromISOString("1991-05-05")); // 5/5/1993
-							//test1_cal2.set("value", "1991-05-05"); 
-							//test1_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
-						} 
-			}, document.getElementById('test1_setdate2'));
-			test1_settext2.startup();
-
-			var test1_settext3 = new Button({
-				label: 'Set TextBox to ISO String("2011-11-06") (Nov 6, 2011) fails on IE', 
-				onClick: function() {
-							//test1_txt2.set("value", new Date("2011-11-07")); // ISO date format  
-							test1_txt2.set("value", "2011-11-07"); // 11/6/2011
-							//test1_cal2.set("value", "2011-11-07"); 
-							//test1_txt2.set("value", "Sun Nov 06 2011 01:00:00 GMT-0500 (Eastern Standard Time)");  
-						} 
-			}, document.getElementById('test1_setdate3'));
-			test1_settext3.startup();
-
-			var test1_reset2 = new Button({
-				label: "Reset Calendar back to (Aug 1 1987)",
-				onClick: function() {
-							test1_model.date.reset();
-						} 
-			}, document.getElementById('test1_reset2'));
-			test1_reset2.startup();
-			// *** Test1 setup end: ***
-
-			// *** Test2 setup begin: ***
-			var test2_init = dateStamp.fromISOString("2011-11-06"); // Nov 6, 2011
-			test2_model = new StatefulModel({
-				data: {
-					date: test2_init
-				}
-			});
-			var test2_cal = new DateTextBox({
-				ref: test2_model.date // bind to model.date
-			}, document.getElementById('test2_cal'));
-			test2_cal.startup();
-
-			var test2_cal2 = new DateTextBox({
-				ref: test2_model.date // bind to model.date
-			}, document.getElementById('test2_cal2'));
-			test2_cal2.startup();
-
-			var test2_txt2 = new TextBox({
-				ref: test2_model.date
-			}, document.getElementById('test2_txt2'));
-			dojo.style(test2_txt2.domNode, "width", "368px");
-			test2_txt2.startup();
-
-			var test2_out2 = new Output({
-				ref: test2_model.date // bind to model.date
-			}, document.getElementById('test2_output2'));
-			test2_out2.startup();
-
-			var test2_setday2 = new Button({
-				label: 'Set DateTextBox to new Date(1993,9,28) (Oct 28, 1993)', 
-				onClick: function() {
-							var day2 = new Date(1993,9,28);  // 10/28/1993
-							//var day2 = new Date("1993-10-28");  // 10/28/1993
-							//var day2 = dateStamp.fromISOString("1993-09-28"); // 10/28/1997
-							//test2_cal2.set("value", day2);
-							test2_txt2.set("value", day2);
-						} 
-			}, document.getElementById('test2_setdate1'));
-			test2_setday2.startup();
-
-			var test2_settext2 = new Button({
-				label: 'Set DateTextBox to dateStamp.fromISOString("1997-10-14") (Oct 14 1997)', 
-				onClick: function() {
-							//test2_txt2.set("value", new Date("1997-10-14")); // ISO date format  
-							test2_txt2.set("value", dateStamp.fromISOString("1997-10-14")); // Oct 14 1997
-							//test2_cal2.set("value", "1997-10-14"); 
-							//test2_txt2.set("value", "Tue Oct 14 1997 00:00:00 GMT-0400 (Eastern Daylight Time)");  
-						} 
-			}, document.getElementById('test2_setdate2'));
-			test2_settext2.startup();
-
-			var test2_reset2 = new Button({
-				label: "Reset DateTextBox back to (Nov 6 2011)",
-				onClick: function() {
-							test2_model.date.reset();
-						} 
-			}, document.getElementById('test2_reset2'));
-
-			var test2_settext3 = new Button({
-				label: 'Set TextBox to ISO String("1991-05-05") (May 5, 1991)', 
-				onClick: function() {
-							//test2_txt2.set("value", new Date("1991-05-05")); // ISO date format  
-							test2_txt2.set("value", "1991-05-05"); // 5/5/1993
-							//test2_cal2.set("value", "1991-05-05"); 
-							//test2_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
-						} 
-			}, document.getElementById('test2_setdate3'));
-			test2_settext3.startup();
-
-			test2_reset2.startup();
-			// *** Test2 setup end: ***
-
-
-			// *** Test3 setup begin: ***
-			// *** Test3 setup begin: ***
-			var test3_init = dateStamp.fromISOString("2011-08-27"); // 8/27/2011
-			test3_model = new StatefulModel({
-				data: {
-					date: test3_init,
-					date2: test3_init
-				}
-			});
-			var test3_cal = new Calendar({
-				ref: test3_model.date // bind to model.date
-			}, document.getElementById('test3_cal'));
-			test3_cal.startup();
-
-			var test3_cal2 = new DateTextBox({
-				ref: test3_model.date // bind to model.date
-			}, document.getElementById('test3_cal2'));
-			test3_cal2.startup();
-
-			var test3_txt2 = new TextBox({
-				ref: test3_model.date,
-				disabled: true
-			}, document.getElementById('test3_txt2'));
-			dojo.style(test3_txt2.domNode, "width", "368px");
-			test3_txt2.startup();
-
-			var test3_out2 = new Output({
-				ref: test3_model.date // bind to model.date
-			}, document.getElementById('test3_output2'));
-			test3_out2.startup();
-
-			var test3_setday2 = new Button({
-				label: 'Set Calendar to dateStamp.fromISOString("1997-10-14") (Oct 14 1997)', 
-				onClick: function() {
-							//console.log("test3_setday2 called");
-							//var day2 = new Date(1997,10,14);  // 10/14/1997
-							//var day2 = new Date("1997-10-14");  // 10/14/1997
-							var day2 = dateStamp.fromISOString("1997-10-14"); // 10/14/1997
-							test3_cal2.set("value", day2);
-						} 
-			}, document.getElementById('test3_setdate1'));
-			test3_setday2.startup();
-
-			var test3_settext2 = new Button({
-				label: 'Set TextBox to dateStamp.fromISOString("2011-11-06") (Nov 6, 2011)', 
-				onClick: function() {
-							//test3_txt2.set("value", new Date("2011-11-06")); // ISO date format  
-							test3_txt2.set("value", dateStamp.fromISOString("2011-11-06")); // 11/6/2011
-							//test3_cal2.set("value", "2011-11-06"); 
-							//test3_txt2.set("value", "2011-11-06"); // FAILS
-							//test3_txt2.set("value", "1991-05-06"); // 5/5/1991
-							//test3_txt2.set("value", "Sun Nov 06 2011 00:00:00 GMT-0400 (Eastern Daylight Time)");  
-						} 
-			}, document.getElementById('test3_setdate2'));
-			test3_settext2.startup();
-
-			var test3_settext3 = new Button({
-				label: 'Set TextBox to ISO String("1991-05-06") via new Date (May 5, 1991)', 
-				onClick: function() {
-							//test3_txt2.set("value", new Date("1991-05-05")); // ISO date format
-							//var d = new Date("1991-05-06T01:00:00");  
-							var d = new Date("1991-05-06");  
-							test3_txt2.set("value", d); // 5/5/1991 YYYY-MM-DDThh:mm:ss via new Date
-							//test3_txt2.set("value", "1991-05-06T01:00:00"); // 5/5/1991 YYYY-MM-DDThh:mm:ss FAILS
-							//test3_cal2.set("value", "1991-05-05"); 
-							//test3_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
-						} 
-			}, document.getElementById('test3_setdate3'));
-			test3_settext3.startup();
-			if(dojo.isIE){ // new Date("1991-05-06") will not work on IE
-				test3_settext3.set('disabled',true);
-			}
-
-			var test3_reset2 = new Button({
-				label: "Reset Calendar back to (Aug 27 2011)",
-				onClick: function() {
-							//console.log("test3_callreset2 called");
-							test3_model.date.reset();
-						} 
-			}, document.getElementById('test3_reset2'));
-			test3_reset2.startup();
-			// *** Test3 setup end: ***
-
-
-
-			// *** Test4 setup begin: RegExp Test***
-			// *** Test4 setup begin: RegExp Test***
-			var regx = new RegExp("abc","i");			
-			test4_model = new StatefulModel({
-				data: {
-					//regex: /abc/i // should be regex: /abc/
-					regex: regx // should be regex: /abc/
-				}
-			});
-
-			/*
-			console.log('test4_model.regex', test4_model.regex.get('value'));
-			var str = "ABCDEFGHIJKLMNOP abcdefghi";
-			var patt1 = test4_model.regex.get('value');
-			console.log("str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
-			console.log('str.match(patt1)',str.match(patt1));
-			test4_model.regex.set('value',/def/);
-			console.log("set to def str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
-			test4_model.regex.reset();
-			console.log("after reset str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
-			*/
-			// *** Test4 setup end: ***
-
-			// *** Test5 setup begin: Falsy Test***
-			var d = {
-				u: undefined,
-				z: 0,
-				n: null,
-				f: false,
-				s: ""
-			};
-			test5_model = new StatefulModel({data: d});
-			//console.log(test5_model.toPlainObject());
-			// *** Test5 setup end: ***
-
-	
-
-				require([
-					'doh/runner', 'dijit/dijit'
-				], function(){
-				require([
-					'dojo/domReady!'
-					], function(){
-						doh.register("parse", function() {
-							dojo.parser.parse();
-						});
-						// should be able to verify all of the inputs 
-						doh.register("check initial values and bindings - test1", [{
-							name : "initial-test1",
-							runTest : function() {
-								doh.is("1987", dijit.byId("test1_cal").get('value').getFullYear(),"test1_cal getFullYear should be 1987");
-								doh.is("7", dijit.byId("test1_cal").get('value').getMonth(),"test1_cal getMonth should be 7");
-								doh.is("1", dijit.byId("test1_cal").get('value').getDate(),"test1_cal getDate should be 1");
-								doh.is("1987", dijit.byId("test1_cal2").get('value').getFullYear(),"test1_cal2 getFullYear should be 1987");
-								doh.is("7", dijit.byId("test1_cal2").get('value').getMonth(),"test1_cal2 getMonth should be 7");
-								doh.is("1", dijit.byId("test1_cal2").get('value').getDate(),"test1_cal2 getDate should be 1");
-								var date1 = "Sat Aug 01 1987 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Sat Aug 1 00:00:00 EDT 1987"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test1_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test1_txt2").get('value'))),"test1_txt2 should be set");
-								doh.t((date1.substring(0,15)==(dijit.byId("test1_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test1_output2").get('value'))),"test1_output2 should be set");
-							}
-						}]);
-
-						doh.register("check initial values and bindings - test2", [{
-							name : "initial-test2",
-							runTest : function() {
-								doh.is("2011", dijit.byId("test2_cal").get('value').getFullYear(),"test2_cal getFullYear should be 1987");
-								doh.is("10", dijit.byId("test2_cal").get('value').getMonth(),"test2_cal getMonth should be 10");
-								doh.is("6", dijit.byId("test2_cal").get('value').getDate(),"test2_cal getDate should be 6");
-								doh.is("2011", dijit.byId("test2_cal2").get('value').getFullYear(),"test2_cal2 getFullYear should be 1987");
-								doh.is("10", dijit.byId("test2_cal2").get('value').getMonth(),"test2_cal2 getMonth should be 10");
-								doh.is("6", dijit.byId("test2_cal2").get('value').getDate(),"test2_cal2 getDate should be 6");
-								var date1 = "Sun Nov 06 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Sun Nov 6 00:00:00 EDT 2011"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test2_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test2_txt2").get('value'))),"test2_txt2 should be set");
-								doh.t((date1.substring(0,15)==(dijit.byId("test2_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test2_output2").get('value'))),"test2_output2 should be set");
-							}
-						}]);
-
-						doh.register("check initial values and bindings - test3", [{
-							name : "initial-test3",
-							runTest : function() {
-								doh.is("2011", dijit.byId("test3_cal").get('value').getFullYear(),"test3_cal getFullYear should be 1987");
-								doh.is("7", dijit.byId("test3_cal").get('value').getMonth(),"test3_cal getMonth should be 7");
-								doh.is("27", dijit.byId("test3_cal").get('value').getDate(),"test3_cal getDate should be 27");
-								doh.is("2011", dijit.byId("test3_cal2").get('value').getFullYear(),"test3_cal2 getFullYear should be 1987");
-								doh.is("7", dijit.byId("test3_cal2").get('value').getMonth(),"test3_cal2 getMonth should be 7");
-								doh.is("27", dijit.byId("test3_cal2").get('value').getDate(),"test3_cal2 getDate should be 27");
-								var date1 = "Sat Aug 27 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Sat Aug 27 00:00:00 EDT 2011"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test3_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test3_txt2").get('value'))),"test3_txt2 should be set-"+dijit.byId("test3_txt2").get('value'));
-								doh.t((date1.substring(0,15)==(dijit.byId("test3_output2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test3_output2").get('value'))),"test3_output2 should be set");
-							}
-						}]);
-
-						doh.register("update first cal - test1", [{
-							name : "Update-First-Cal-test1",
-							runTest : function() {
-								var day2 = dateStamp.fromISOString("1989-09-07"); // 9/7/1989
-								dijit.byId(test1_cal).set("value", day2);
-								doh.is("1989", dijit.byId("test1_cal").get('value').getFullYear(),"test1_cal getFullYear should be 1989");
-								doh.is("8", dijit.byId("test1_cal").get('value').getMonth(),"test1_cal getMonth should be 8");
-								doh.is("7", dijit.byId("test1_cal").get('value').getDate(),"test1_cal getDate should be 7");
-								doh.is("1989", dijit.byId("test1_cal2").get('value').getFullYear(),"test1_cal2 getFullYear should be 1989");
-								doh.is("8", dijit.byId("test1_cal2").get('value').getMonth(),"test1_cal2 getMonth should be 8");
-								doh.is("7", dijit.byId("test1_cal2").get('value').getDate(),"test1_cal2 getDate should be 7");
-								var date1 = "Thu Sep 07 1989 01:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Thu Sep 7 01:00:00 EDT 1989"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test1_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test1_txt2").get('value'))),"test1_txt2 should be set-"+dijit.byId("test3_txt2").get('value'));
-								doh.t((date1.substring(0,15)==(dijit.byId("test1_output2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test1_output2").get('value'))),"test1_output2 should be set");
-							}
-						}]);
-
-						doh.register("update first cal - test2", [{
-							name : "Update-First-Cal-test2",
-							runTest : function() {
-								var day2 = dateStamp.fromISOString("1989-09-07"); // 9/7/1989
-								dijit.byId(test2_cal).set("value", day2);
-								doh.is("1989", dijit.byId("test2_cal").get('value').getFullYear(),"test2_cal getFullYear should be 1989");
-								doh.is("8", dijit.byId("test2_cal").get('value').getMonth(),"test2_cal getMonth should be 8");
-								doh.is("7", dijit.byId("test2_cal").get('value').getDate(),"test2_cal getDate should be 7");
-								doh.is("1989", dijit.byId("test2_cal2").get('value').getFullYear(),"test2_cal2 getFullYear should be 1989");
-								doh.is("8", dijit.byId("test2_cal2").get('value').getMonth(),"test2_cal2 getMonth should be 8");
-								doh.is("7", dijit.byId("test2_cal2").get('value').getDate(),"test2_cal2 getDate should be 7");
-								var date1 = "Thu Sep 07 1989 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Thu Sep 7 00:00:00 EDT 1989"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test2_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test2_txt2").get('value'))),"test2_txt2 should be set");
-								doh.t((date1.substring(0,15)==(dijit.byId("test2_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test2_output2").get('value'))),"test2_output2 should be set");
-							}
-						}]);
-
-						doh.register("update first cal - test3", [{
-							name : "Update-First-Cal-test3",
-							runTest : function() {
-								var day2 = dateStamp.fromISOString("1989-09-07"); // 9/7/1989
-								dijit.byId(test3_cal).set("value", day2);
-								doh.is("1989", dijit.byId("test3_cal").get('value').getFullYear(),"test3_cal getFullYear should be 1989");
-								doh.is("8", dijit.byId("test3_cal").get('value').getMonth(),"test3_cal getMonth should be 8");
-								doh.is("7", dijit.byId("test3_cal").get('value').getDate(),"test3_cal getDate should be 7");
-								doh.is("1989", dijit.byId("test3_cal2").get('value').getFullYear(),"test3_cal2 getFullYear should be 1989");
-								doh.is("8", dijit.byId("test3_cal2").get('value').getMonth(),"test3_cal2 getMonth should be 8");
-								doh.is("7", dijit.byId("test3_cal2").get('value').getDate(),"test3_cal2 getDate should be 7");
-								var date1 = "Thu Sep 07 1989 01:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Thu Sep 7 01:00:00 EDT 1989"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test3_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test3_txt2").get('value'))),"test3_txt2 should be set - got "+dijit.byId("test3_txt2").get('value'));
-								doh.t((date1.substring(0,15)==(dijit.byId("test3_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test3_output2").get('value'))),"test3_output2 should be set");
-							}
-						}]);
-
-						doh.register("update textbox - test1", [{
-							name : "Update-TextBox-test1",
-							runTest : function() {
-								dijit.byId(test1_txt2).set("value", dateStamp.fromISOString("1991-05-05"));
-								doh.is("1991", dijit.byId("test1_cal").get('value').getFullYear(),"test1_cal getFullYear should be 1991");
-								doh.is("4", dijit.byId("test1_cal").get('value').getMonth(),"test1_cal getMonth should be 4");
-								doh.is("5", dijit.byId("test1_cal").get('value').getDate(),"test1_cal getDate should be 4");
-								doh.is("1991", dijit.byId("test1_cal2").get('value').getFullYear(),"test1_cal2 getFullYear should be 1991");
-								doh.is("4", dijit.byId("test1_cal2").get('value').getMonth(),"test1_cal2 getMonth should be 4");
-								doh.is("5", dijit.byId("test1_cal2").get('value').getDate(),"test1_cal2 getDate should be 5");
-								var date1 = "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Sun May 5 00:00:00 EDT 1991"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test1_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test1_txt2").get('value'))),"test1_txt2 should be set-"+dijit.byId("test1_txt2").get('value'));
-								doh.t((date1.substring(0,15)==(dijit.byId("test1_output2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test1_output2").get('value'))),"test1_output2 should be set");
-							}
-						}]);
-
-						doh.register("update textbox - test2", [{
-							name : "Update-TextBox-test2",
-							runTest : function() {
-								dijit.byId(test2_txt2).set("value", dateStamp.fromISOString("1991-05-05"));
-								doh.is("1991", dijit.byId("test2_cal").get('value').getFullYear(),"test2_cal getFullYear should be 1991");
-								doh.is("4", dijit.byId("test2_cal").get('value').getMonth(),"test2_cal getMonth should be 4");
-								doh.is("5", dijit.byId("test2_cal").get('value').getDate(),"test2_cal getDate should be 4");
-								doh.is("1991", dijit.byId("test2_cal2").get('value').getFullYear(),"test2_cal2 getFullYear should be 1991");
-								doh.is("4", dijit.byId("test2_cal2").get('value').getMonth(),"test2_cal2 getMonth should be 4");
-								doh.is("5", dijit.byId("test2_cal2").get('value').getDate(),"test2_cal2 getDate should be 5");
-								var date1 = "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Sun May 5 00:00:00 EDT 1991"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test2_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test2_txt2").get('value'))),"test2_txt2 should be set-"+dijit.byId("test2_txt2").get('value'));
-								doh.t((date1.substring(0,15)==(dijit.byId("test2_output2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test2_output2").get('value'))),"test2_output2 should be set");
-							}
-						}]);
-
-						doh.register("update textbox - test3", [{
-							name : "Update-TextBox-test3",
-							runTest : function() {
-								dijit.byId(test3_txt2).set("value", dateStamp.fromISOString("1991-05-05"));
-								doh.is("1991", dijit.byId("test3_cal").get('value').getFullYear(),"test3_cal getFullYear should be 1991");
-								doh.is("4", dijit.byId("test3_cal").get('value').getMonth(),"test3_cal getMonth should be 4");
-								doh.is("5", dijit.byId("test3_cal").get('value').getDate(),"test3_cal getDate should be 4");
-								doh.is("1991", dijit.byId("test3_cal2").get('value').getFullYear(),"test3_cal2 getFullYear should be 1991");
-								doh.is("4", dijit.byId("test3_cal2").get('value').getMonth(),"test3_cal2 getMonth should be 4");
-								doh.is("5", dijit.byId("test3_cal2").get('value').getDate(),"test3_cal2 getDate should be 5");
-								var date1 = "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Sun May 5 00:00:00 EDT 1991"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test3_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test3_txt2").get('value'))),"test3_txt2 should be set-"+dijit.byId("test3_txt2").get('value'));
-								doh.t((date1.substring(0,15)==(dijit.byId("test3_output2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test3_output2").get('value'))),"test3_output2 should be set");
-							}
-						}]);
-
-						doh.register("update cal with new date - test1", [{
-							name : "Update-withNewDate-test1",
-							runTest : function() {
-								var day2 = new Date(1993,9,28);  // 10/28/1993							
-								dijit.byId(test1_cal).set("value", day2);
-								doh.is("1993", dijit.byId("test1_cal").get('value').getFullYear(),"test1_cal getFullYear should be 1993");
-								doh.is("9", dijit.byId("test1_cal").get('value').getMonth(),"test1_cal getMonth should be 9");
-								doh.is("28", dijit.byId("test1_cal").get('value').getDate(),"test1_cal getDate should be 28");
-								doh.is("1993", dijit.byId("test1_cal2").get('value').getFullYear(),"test1_cal2 getFullYear should be 1993");
-								doh.is("9", dijit.byId("test1_cal2").get('value').getMonth(),"test1_cal2 getMonth should be 9");
-								doh.is("28", dijit.byId("test1_cal2").get('value').getDate(),"test1_cal2 getDate should be 28");
-								var date1 = "Thu Oct 28 1993 01:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Thu Oct 28 01:00:00 EDT 1993"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test1_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test1_txt2").get('value'))),"test1_txt2 should be set-"+dijit.byId("test1_txt2").get('value'));
-								doh.t((date1.substring(0,15)==(dijit.byId("test1_output2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test1_output2").get('value'))),"test1_output2 should be set");
-							}
-						}]);
-
-						doh.register("update cal with new date - test2", [{
-							name : "Update-withNewDate-test2",
-							runTest : function() {
-								var day2 = new Date(1993,9,28);  // 10/28/1993							
-								dijit.byId(test2_cal).set("value", day2);
-								doh.is("1993", dijit.byId("test2_cal").get('value').getFullYear(),"test2_cal getFullYear should be 1993");
-								doh.is("9", dijit.byId("test2_cal").get('value').getMonth(),"test2_cal getMonth should be 9");
-								doh.is("28", dijit.byId("test2_cal").get('value').getDate(),"test2_cal getDate should be 28");
-								doh.is("1993", dijit.byId("test2_cal2").get('value').getFullYear(),"test2_cal2 getFullYear should be 1993");
-								doh.is("9", dijit.byId("test2_cal2").get('value').getMonth(),"test2_cal2 getMonth should be 9");
-								doh.is("28", dijit.byId("test2_cal2").get('value').getDate(),"test2_cal2 getDate should be 28");
-								var date1 = "Thu Oct 28 1993 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Thu Oct 28 00:00:00 EDT 1993"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test2_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test2_txt2").get('value'))),"test2_txt2 should be set-"+dijit.byId("test2_txt2").get('value'));
-								doh.t((date1.substring(0,15)==(dijit.byId("test2_output2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test2_output2").get('value'))),"test2_output2 should be set");
-							}
-						}]);
-
-						doh.register("update cal with new date - test3", [{
-							name : "Update-withNewDate-test3",
-							runTest : function() {
-								var day2 = new Date(1993,9,28);  // 10/28/1993							
-								dijit.byId(test3_cal).set("value", day2);
-								doh.is("1993", dijit.byId("test3_cal").get('value').getFullYear(),"test3_cal getFullYear should be 1993");
-								doh.is("9", dijit.byId("test3_cal").get('value').getMonth(),"test3_cal getMonth should be 9");
-								doh.is("28", dijit.byId("test3_cal").get('value').getDate(),"test3_cal getDate should be 28");
-								doh.is("1993", dijit.byId("test3_cal2").get('value').getFullYear(),"test3_cal2 getFullYear should be 1993");
-								doh.is("9", dijit.byId("test3_cal2").get('value').getMonth(),"test3_cal2 getMonth should be 9");
-								doh.is("28", dijit.byId("test3_cal2").get('value').getDate(),"test3_cal2 getDate should be 28");
-								var date1 = "Thu Oct 28 1993 01:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Thu Oct 28 01:00:00 EDT 1993"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test3_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test3_txt2").get('value'))),"test3_txt2 should be set-"+dijit.byId("test3_txt2").get('value'));
-								doh.t((date1.substring(0,15)==(dijit.byId("test3_output2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test3_output2").get('value'))),"test3_output2 should be set");
-							}
-						}]);
-
-						doh.register("check model reset - test1", [{
-							name : "reset-test1",
-							runTest : function() {
-								test1_model.date.reset();
-								doh.is("1987", dijit.byId("test1_cal").get('value').getFullYear(),"test1_cal getFullYear should be 1987");
-								doh.is("7", dijit.byId("test1_cal").get('value').getMonth(),"test1_cal getMonth should be 7");
-								doh.is("1", dijit.byId("test1_cal").get('value').getDate(),"test1_cal getDate should be 1");
-								doh.is("1987", dijit.byId("test1_cal2").get('value').getFullYear(),"test1_cal2 getFullYear should be 1987");
-								doh.is("7", dijit.byId("test1_cal2").get('value').getMonth(),"test1_cal2 getMonth should be 7");
-								doh.is("1", dijit.byId("test1_cal2").get('value').getDate(),"test1_cal2 getDate should be 1");
-								var date1 = "Sat Aug 01 1987 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Sat Aug 1 00:00:00 EDT 1987"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test1_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test1_txt2").get('value'))),"test1_txt2 should be set");
-								doh.t((date1.substring(0,15)==(dijit.byId("test1_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test1_output2").get('value'))),"test1_output2 should be set");
-							}
-						}]);
-
-						doh.register("check model reset - test2", [{
-							name : "reset-test2",
-							runTest : function() {
-								test2_model.date.reset();
-								doh.is("2011", dijit.byId("test2_cal").get('value').getFullYear(),"test2_cal getFullYear should be 1987");
-								doh.is("10", dijit.byId("test2_cal").get('value').getMonth(),"test2_cal getMonth should be 10");
-								doh.is("6", dijit.byId("test2_cal").get('value').getDate(),"test2_cal getDate should be 6");
-								doh.is("2011", dijit.byId("test2_cal2").get('value').getFullYear(),"test2_cal2 getFullYear should be 1987");
-								doh.is("10", dijit.byId("test2_cal2").get('value').getMonth(),"test2_cal2 getMonth should be 10");
-								doh.is("6", dijit.byId("test2_cal2").get('value').getDate(),"test2_cal2 getDate should be 6");
-								var date1 = "Sun Nov 06 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Sun Nov 6 00:00:00 EDT 2011"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test2_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test2_txt2").get('value'))),"test2_txt2 should be set");
-								doh.t((date1.substring(0,15)==(dijit.byId("test2_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test2_output2").get('value'))),"test2_output2 should be set");
-							}
-						}]);
-
-						doh.register("check model reset - test3", [{
-							name : "reset-test3",
-							runTest : function() {
-								test3_model.date.reset();
-								doh.is("2011", dijit.byId("test3_cal").get('value').getFullYear(),"test3_cal getFullYear should be 1987");
-								doh.is("7", dijit.byId("test3_cal").get('value').getMonth(),"test3_cal getMonth should be 7");
-								doh.is("27", dijit.byId("test3_cal").get('value').getDate(),"test3_cal getDate should be 27");
-								doh.is("2011", dijit.byId("test3_cal2").get('value').getFullYear(),"test3_cal2 getFullYear should be 1987");
-								doh.is("7", dijit.byId("test3_cal2").get('value').getMonth(),"test3_cal2 getMonth should be 7");
-								doh.is("27", dijit.byId("test3_cal2").get('value').getDate(),"test3_cal2 getDate should be 27");
-								var date1 = "Sat Aug 27 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Sat Aug 27 00:00:00 EDT 2011"; // IE
-								doh.t((date1.substring(0,15)==(dijit.byId("test3_txt2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test3_txt2").get('value'))),"test3_txt2 should be set-"+dijit.byId("test3_txt2").get('value'));
-								doh.t((date1.substring(0,15)==(dijit.byId("test3_output2").get('value').toString().substring(0,15)) || date2==(dijit.byId("test3_output2").get('value'))),"test3_output2 should be set");
-							}
-						}]);
-
-						doh.register("test regexp in model", [{
-							name : "regexp-test4",
-							runTest : function() {
-								doh.is("/abc/i", test4_model.regex.get('value'),"test4_model.regex.get(value) should be /abc/i");
-								var str = "ABCDEFGHIJKLMNOP abcdefghi";
-								var patt1 = test4_model.regex.get('value');
-								doh.is("ABC", str.match(test4_model.regex.get('value')),"str.match(test4_model.regex.get('value')) should be ABC");
-								doh.is("ABC", str.match(patt1),"str.match(patt1) should be ABC");
-								test4_model.regex.set('value',/def/);
-								doh.is("def", str.match(test4_model.regex.get('value')),"str.match(test4_model.regex.get('value')) after set /def/ should be def");
-								test4_model.regex.reset();
-								doh.is("ABC", str.match(test4_model.regex.get('value')),"str.match(test4_model.regex.get('value')) after reset should be ABC");
-							}
-						}]);
-
-
-						doh.register("test falsy in model", [{
-							name : "falsy-test5",
-							runTest : function() {
-								doh.t(null === test5_model.n.get('value'),"test5_model.n.get(value) should be null");
-								doh.t(0 === test5_model.z.get('value'),"test5_model.z.get(value) should be 0");
-								doh.t(undefined === test5_model.u.get('value'),"test5_model.u.get(value) should be undefined");
-								doh.t(false === test5_model.f.get('value'),"test5_model.f.get(value) should be false");
-								doh.t("" === test5_model.s.get('value'),"test5_model.s.get(value) should be an empty string");
-							}
-						}]);
-
-						doh.run();
-
-					});
-				});	
-		}); 
-		</script>
-</head>
-<body class="claro">
-			<h2>Test 1: Two Calendars bound to each other, a TextBox and an mvc Output field.</h2>
-				<div  style="border-style: solid; border-width: 2px; width: 827px;">
-					<table>
-						<tbody>
-							<tr>
-								<td><div id="test1_cal"></div></td>
-								<td><div id="test1_cal2"></div></td>
-								<td>
-					<table><tbody>
-								<tr><td><label for="test1_txt2">TextBox bound to date:</label></td></tr>
-								<tr><td><div id="test1_txt2"></div></td></tr>
-								<tr><td><label for="test1_txt2">MVC Output bound to date:</label></td></tr>
-								<tr><td><div id="test1_output2"></div></td></tr>
-					</tbody></table>
-					<table><tbody><tr>
-								<td><div id="test1_setdate1"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test1_setdate2"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test1_setdate3"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test1_reset2"></div></td>
-					</tr></tbody></table>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</div>
-
-			<h2>Test 2: Two DateTextBoxes bound to each other, a TextBox and an mvc Output field.</h2>
-				<div  style="border-style: solid; border-width: 2px; width: 827px;">
-					<table>
-						<tbody>
-							<tr>
-								<td style="vertical-align: top;"><div id="test2_cal"></div></td>
-								<td style="vertical-align: top;"><div id="test2_cal2"></div></td>
-								<td>
-					<table><tbody>
-								<tr><td><label for="test2_txt2">TextBox bound to date:</label></td></tr>
-								<tr><td><div id="test2_txt2"></div></td></tr>
-								<tr><td><label for="test2_txt2">MVC Output bound to date:</label></td></tr>
-								<tr><td><div id="test2_output2"></div></td></tr>
-					</tbody></table>
-					<table><tbody><tr>
-								<td><div id="test2_setdate1"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test2_setdate2"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test2_setdate3"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test2_reset2"></div></td>
-					</tr></tbody></table>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</div>
-
-
-			<h2>Test 3: One Calendar bound to a DateTextbox, a TextBox and an mvc Output field.</h2>
-				<div  style="border-style: solid; border-width: 2px; width: 827px;">
-					<table>
-						<tbody>
-							<tr>
-								<td style="vertical-align: top;"><div id="test3_cal"></div></td>
-								<td style="vertical-align: top;"><div id="test3_cal2"></div></td>
-								<td>
-					<table><tbody>
-								<tr><td><label for="test3_txt2">TextBox bound to date: (disabled to avoid error)</label></td></tr>
-								<tr><td><div id="test3_txt2"></div></td></tr>
-								<tr><td><label for="test3_txt2">MVC Output bound to date:</label></td></tr>
-								<tr><td><div id="test3_output2"></div></td></tr>
-					</tbody></table>
-					<table><tbody><tr>
-								<td><div id="test3_setdate1"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test3_setdate2"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test3_setdate3"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test3_reset2"></div></td>
-					</tr></tbody></table>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</div>
-	<!--  	  
-			<h2>I see these problems Binding a TextBox to DateTextBox and Calendar:</h2>
-				<div  style="border-style: solid; border-width: 2px; width: 827px;">
-				<span>There is also a problem when trying to set a date string in this format:</span><br>
-				<span>"Wed May 05 2010 01:00:00 GMT-0400 (Eastern Daylight Time)" into a  into a TextBox bound to a dijit.form.DateTextbox, but that works in a Calendar.</span><br>
-				<span>It is ending up with the DateTextBox set to null.  : </span><br>
-				<span></span><br>
-				<span>There is also a problem when trying to set a date ISO format date string like "1991-05-05":</span><br>
-				<span>"into a  into a TextBox bound to a Calendar, but that works for a dijit.form.DateTextbox.</span><br>
-				<span>It is loops for a while and gets range errors in the console.  : </span><br>
-				<span></span><br>
-				<span>Another thing I have found was that on a calendar I would get a different value from dijit.byId("cal").get('value') and dijit.byId("cal").value.</span><br>
-				<span>dijit.byId("cal").value:        Wed May 05 2010 <b>01:00:00</b> GMT-0400 (Eastern Daylight Time)</span><br>
-				<span>dijit.byId("cal").get('value'): Wed May 05 2010 <b>00:00:00</b> GMT-0400 (Eastern Daylight Time)</span><br>
-				<span>dijit.byId("cal").get('value') is getting 00:00:00 when it seems like it should be 01:00:00</span><br>
-				</div>
-	-->
-</body>
-
-</html>
diff --git a/dojox/mvc/tests/doh_mvc_form-kitchensink.html b/dojox/mvc/tests/doh_mvc_form-kitchensink.html
deleted file mode 100644
index 2c52b3a..0000000
--- a/dojox/mvc/tests/doh_mvc_form-kitchensink.html
+++ /dev/null
@@ -1,1417 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>MVC DOH Test</title>
-
-	<style>
-		@import "../../../dojo/resources/dojo.css";
-		@import "./css/dijitTests.css";
-		@import "css/app-format.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script src="../../../dojo/dojo.js" type="text/javascript"
-		djConfig="isDebug: true">
-	</script>
-	<script type="text/javascript" src="./helpers.js"></script>
-
-	<script type="text/javascript" >
-			dojo.require("dojox.mvc");
-			dojo.require("dojox.mvc.Output");
-			dojo.require("dijit.form.TextBox");
-			dojo.require("dijit.form.Button");
-			dojo.require("dijit.form.Select");
-			dojo.require("dijit.form.FilteringSelect");
-			dojo.require("dijit.form.ComboBox");
-			dojo.require("dijit.form.DateTextBox");
-			dojo.require("dijit.form.HorizontalSlider");
-			dojo.require("dijit.form.NumberSpinner");
-			dojo.require("dijit.form.NumberTextBox");
-			dojo.require("dijit.form.SimpleTextarea");		
-			dojo.require("dijit.form.Textarea");
-			dojo.require("dojo.data.ItemFileReadStore");
-			dojo.require("dijit.Calendar");
-			dojo.require("dijit.ColorPalette");
-			dojo.require("dojo.date.locale");
-			dojo.require("dojo.parser");
-			// The dojox.mvc.StatefulModel class creates a data model instance
-			// where each leaf within the data model is decorated with dojo.Stateful
-			// properties that widgets can bind to and watch for their changes.
-
-			var alreadyset = false;	
-			var data = [
-				{id: '1',name:"one"},
-				{id: '2',name:"two"},
-				{id: '3',name:"three"},
-				{id: '4',name:"four"},
-				{id: '5',name:"five"},
-				{id: '6',name:"six"},
-				{id: '7',name:"seven"},
-				{id: '8',name:"eight"},
-				{id: '9',name:"nine"},
-				{id: '10',name:"ten"},
-				{id: '11',name:"eleven"},
-				{id: '12',name:"twelve"},
-				{id: '13',name:"thirteen"}
-			  ];
-			var store = new dojo.data.ItemFileReadStore({
-				data: {
-					identifier: 'id',
-					label: 'name',
-					items: data
-				}
-			});
-
-			var data2 = {
-				identifier: "value",
-				label: "label",
-				items: [
-					{value: "1", label: "one"},
-					{value: "2", label: "two"},
-					{value: "3", label: "three"},
-					{value: "4", label: "four"},
-					{value: "5", label: "five"},
-					{value: "6", label: "six"},
-					{value: "7", label: "seven"},
-					{value: "8", label: "eigth"},
-					{value: "9", label: "nine"},
-					{value: "10", label: "ten"},
-					{value: "11", label: "eleven"},
-					{value: "12", label: "twelve"},
-					{value: "13", label: "thirteen"},
-					{value: "14", label: "fourteen"}
-				]
-			};
-			var store2 = new dojo.data.ItemFileReadStore({data:dojo.clone(data2)});
-
-			// create models for selects
-			var selmodel = new dojox.mvc.newStatefulModel({data: {number: '1'}});
-			var decselmodel = new dojox.mvc.newStatefulModel({data: {number: '1'}});
-
-			// create models for filtering selects
-			var filmodel = new dojox.mvc.newStatefulModel({data: {number: '2'}});
-			var decfilmodel = new dojox.mvc.newStatefulModel({data: {number: '2'}});
-
-			// create models for ComboBoxes
-			var combomodel = new dojox.mvc.newStatefulModel({data: {number: 'three'}});
-			var deccombomodel = new dojox.mvc.newStatefulModel({data: {number: 'three'}});
-
-			// create a model for DateTextBox
-			var datemodel = new dojox.mvc.newStatefulModel({data: {number: "2011-04-04"}});
-			var decdatemodel = new dojox.mvc.newStatefulModel({data: {number: "2011-04-04"}});
-
-			// create a model for Slider
-			var slidermodel = new dojox.mvc.newStatefulModel({data: {number: '5'}});
-			var decslidermodel = new dojox.mvc.newStatefulModel({data: {number: '5'}});
-
-			// create a model for NumberSpinner
-			var numspinmodel = new dojox.mvc.newStatefulModel({data: {number: '6'}});
-			var decnumspinmodel = new dojox.mvc.newStatefulModel({data: {number: '6'}});
-
-			// create a model for SimpleTextArea
-			var simpTAmodel = new dojox.mvc.newStatefulModel({data: {number: '7'}});
-			var decsimpTAmodel = new dojox.mvc.newStatefulModel({data: {number: '7'}});
-
-			// create a model for TextArea
-			var textareamodel = new dojox.mvc.newStatefulModel({data: {number: '8'}});
-			var dectextareamodel = new dojox.mvc.newStatefulModel({data: {number: '8'}});
-
-			// create a model for dijit.Calendar
-			var deccalmodel = new dojox.mvc.newStatefulModel({data: {date: new Date(2011,4,4)}});
-
-			// create a model for dijit.ColorPalette
-			var deccolormodel = new dojox.mvc.newStatefulModel({data: {code: "#000000"}});
-
-			var nanmodel = new dojox.mvc.newStatefulModel({data: {num: null}});
-
-	</script>
-
-	<script type="text/javascript">
-		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-		dojo.addOnLoad(function(){
-
-			doh.register("parse", function(){
-				dojo.parser.parse();
-
-			// Handle the programmatic creation of widgets here:
-			
-			// create the select, textbox, output and button			
-			var sel = new dijit.form.Select({
-				store: store,
-				loadChildrenOnOpen: true,
-				ref: selmodel.number // bind to model.number
-			}, document.getElementById('sel'));
-			
-			var text = new dijit.form.TextBox({
-				//id: "seltext",
-				ref: selmodel.number
-			}, document.getElementById('seltext'));			
-			text.startup();
-			
-			var selOutput = new dojox.mvc.Output({
-				ref: selmodel.number
-			}, document.getElementById('selOutput'));
-			selOutput.startup();
-
-			var reset1 = new dijit.form.Button({
-				onClick: function(){selmodel.reset();},
-				id: "selReset",
-				label: "Reset"
-			}, document.getElementById('reset1'));
-			reset1.startup();
-
-
-			sel.watch('value', function () {
-				//console.log('sel value changed', arguments);
-			});
-
-			text.watch('value', function () {
-				//console.log('text value changed', arguments);
-			});
-			
-			sel.startup();
-			
-
-			// create the filtering select, textbox, output and button			
-			var filsel = new dijit.form.FilteringSelect({
-				store: store,
-				ref: filmodel.number // bind to model.number
-			}, document.getElementById('filsel'));
-			
-			var filtext = new dijit.form.TextBox({
-				ref: filmodel.number
-			}, document.getElementById('filtext'));
-			
-			var filoutput = new dojox.mvc.Output({
-				ref: filmodel.number
-			}, document.getElementById('filoutput'));			
-			filoutput.startup();
-
-			var filreset = new dijit.form.Button({
-				onClick: function(){filmodel.reset();},
-				id: "filReset",
-				label: "Reset"
-			}, document.getElementById('filreset'));
-			filreset.startup();
-			
-			filtext.startup();
-			filsel.startup();
-			
-			// create the comboBox, textbox, output and button			
-			var combo = new dijit.form.ComboBox({
-				store: store,
-				ref: combomodel.number // bind to model.number
-			}, document.getElementById('combosel'));
-			
-			var combotext = new dijit.form.TextBox({
-				ref: combomodel.number
-			}, document.getElementById('combotext'));
-			
-			var combooutput = new dojox.mvc.Output({
-				ref: combomodel.number
-			}, document.getElementById('combooutput'));			
-			combooutput.startup();
-
-			var comboreset = new dijit.form.Button({
-				onClick: function(){combomodel.reset();},
-				id: "comboReset",
-				label: "Reset"
-			}, document.getElementById('comboreset'));
-			comboreset.startup();
-			
-			combotext.startup();
-			combo.startup();
-			
-			// create the dijit.form.DateTextBox, textbox, output and button			
-			var dateWid = new dijit.form.DateTextBox({
-				ref: datemodel.number // bind to model.number
-			}, document.getElementById('datesel'));
-			
-			var datetext = new dijit.form.TextBox({
-				ref: datemodel.number
-			}, document.getElementById('datetext'));
-			
-			var dateoutput = new dojox.mvc.Output({
-				ref: datemodel.number
-			}, document.getElementById('dateoutput'));			
-			dateoutput.startup();
-
-			var datereset = new dijit.form.Button({
-				onClick: function(){datemodel.reset();},
-				id: "dateReset",
-				label: "Reset"
-			}, document.getElementById('datereset'));
-			datereset.startup();
-			
-			datetext.startup();
-			dateWid.startup();
-			
-			// create the dijit.form.HorizontalSlider, textbox, output and button			
-			var sliderWid = new dijit.form.HorizontalSlider({
-						style:{width:"190px"},
-						minimum:0,
-						maximum:100,
-						discreteValues:21,
-				ref: slidermodel.number // bind to model.number
-			}, document.getElementById('slidersel'));
-			
-			var slidertext = new dijit.form.TextBox({
-				ref: slidermodel.number
-			}, document.getElementById('slidertext'));
-			
-			var slideroutput = new dojox.mvc.Output({
-				ref: slidermodel.number
-			}, document.getElementById('slideroutput'));			
-			slideroutput.startup();
-
-			var sliderreset = new dijit.form.Button({
-				onClick: function(){slidermodel.reset();},
-				id: "sliderReset",
-				label: "Reset"
-			}, document.getElementById('sliderreset'));
-			sliderreset.startup();
-			
-			slidertext.startup();
-			sliderWid.startup();
-			
-			// create the dijit.form.NumberSpinner, textbox, output and button			
-			var numspinWid = new dijit.form.NumberSpinner({
-			//	constraints:{max:100,places:0},
-				ref: numspinmodel.number // bind to model.number
-			}, document.getElementById('numspinsel'));
-			
-			var numspintext = new dijit.form.TextBox({
-				ref: numspinmodel.number
-			}, document.getElementById('numspintext'));
-			
-			var numspinoutput = new dojox.mvc.Output({
-				ref: numspinmodel.number
-			}, document.getElementById('numspinoutput'));			
-			numspinoutput.startup();
-
-			var numspinreset = new dijit.form.Button({
-				onClick: function(){numspinmodel.reset();},
-				id: "numspinReset",
-				label: "Reset"
-			}, document.getElementById('numspinreset'));
-			numspinreset.startup();
-			
-			numspintext.startup();
-			numspinWid.startup();
-			
-			// create the dijit.form.SimpleTextarea, textbox, output and button 			
-			var simpTAWid = new dijit.form.SimpleTextarea({
-				style:{height:"20px", width:"180px"},
-				ref: simpTAmodel.number // bind to model.number
-			}, document.getElementById('simpTAsel'));
-			
-			var simpTAtext = new dijit.form.TextBox({
-				ref: simpTAmodel.number
-			}, document.getElementById('simpTAtext'));
-			
-			var simpTAoutput = new dojox.mvc.Output({
-				ref: simpTAmodel.number
-			}, document.getElementById('simpTAoutput'));			
-			simpTAoutput.startup();
-
-			var simpTAreset = new dijit.form.Button({
-				onClick: function(){simpTAmodel.reset();},
-				id: "simpTAReset",
-				label: "Reset"
-			}, document.getElementById('simpTAreset'));
-			simpTAreset.startup();
-			
-			simpTAtext.startup();
-			simpTAWid.startup();
-
-			// create the dijit.form.Textarea, textbox, output and button 
-			var textareaWid = new dijit.form.Textarea({
-			//	constraints:{max:100,places:0},
-				ref: textareamodel.number // bind to model.number
-			}, document.getElementById('textareasel'));
-			
-			var textareatext = new dijit.form.TextBox({
-				ref: textareamodel.number
-			}, document.getElementById('textareatext'));
-			
-			var textareaoutput = new dojox.mvc.Output({
-				ref: textareamodel.number
-			}, document.getElementById('textareaoutput'));			
-			textareaoutput.startup();
-
-			var textareareset = new dijit.form.Button({
-				onClick: function(){textareamodel.reset();},
-				id: "textareaReset",
-				label: "Reset"
-			}, document.getElementById('textareareset'));
-			textareareset.startup();
-			
-			textareatext.startup();
-			textareaWid.startup();
-
-			var numBox = new dijit.form.NumberTextBox({
-				ref: nanmodel.num // bind to model.num
-			}, document.getElementById('nannb'));
-
-			numBox.startup();
-
-			
-		});
-
-			// should be able to verify all of the inputs
-			console.log("This test is commented out because it will fail if _FromSelectWidget is not updated to setup the store in postCreate instead of startup, see ticket 13372 for details."); 
-		/*	
-			doh.register("Check initial programatic values and bindings for select widget only", [
-				{
-					name: "initialSelectOnly",
-					runTest: function(){
-						var wid, textboxval, outputval; 
-						// Test Select
-						wid = dijit.byId("sel");
-						textboxval = dijit.byId("seltext").value;
-						outputval = dijit.byId("selOutput").value;
-						if (wid) {
-								doh.is("1",wid.get('value'),"This test will fail if _FromSelectWidget is not updated to setup the store in postCreate instead of startup, see ticket 13372 for details.");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-					}
-				}
-			]);
-		*/	
-			doh.register("Check initial programatic values and bindings widgets other than select", [
-				{
-					name: "initialOtherThanSelect",
-					runTest: function(){
-
-						var wid, textboxval, outputval; 
-						// Test FilteringSelect
-						wid = dijit.byId("filsel");
-						textboxval = dijit.byId("filtext").value;
-						outputval = dijit.byId("filoutput").value;
-						if (wid) {
-								doh.is("2",wid.get('value'),"wid.get('value') should be set");
-								doh.is("two",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.ComboBox
-						wid = dijit.byId("combosel");
-						textboxval = dijit.byId("combotext").value;
-						outputval = dijit.byId("combooutput").value;
-						if (wid) {
-								doh.is("three",wid.get('value'),"wid.get('value') should be set");
-								doh.is("three",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.DateTextBox
-						wid = dijit.byId("datesel");
-						textboxval = dijit.byId("datetext").value;
-						outputval = dijit.byId("dateoutput").value;
-						if (wid) {
-								var date1 = "Mon Apr 04 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Mon Apr 4 00:00:00 EDT 2011";
-								doh.t((date1.substring(0,15)==(wid.get('value').toString().substring(0,15)) || 
-									date2==(wid.get('value'))),"wid.get('value') should be set it is:"+wid.get('value'));
-								doh.is("4/4/2011",wid.displayedValue,"wid.displayedValue should be set it is:"+wid.displayedValue);
-								doh.is("2011-04-04",textboxval,"textboxval should be set it is:"+textboxval);
-								doh.is("2011-04-04",outputval,"outputval should be set it is:"+outputval);
-						}
-						// Test dijit.form.HorizontalSlider
-						wid = dijit.byId("slidersel");
-						textboxval = dijit.byId("slidertext").value;
-						outputval = dijit.byId("slideroutput").value;
-						if (wid) {
-								doh.is("5",wid.get('value'),"wid.get('value') should be set");
-								//doh.is("five",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.NumberSpinner
-						wid = dijit.byId("numspinsel");
-						textboxval = dijit.byId("numspintext").value;
-						outputval = dijit.byId("numspinoutput").value;
-						if (wid) {
-								//doh.is("6",wid.get('value'),"wid.get('value') should be set");
-								doh.is("6",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
-								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
-						}
-						// Test dijit.form.SimpleTextarea
-						wid = dijit.byId("simpTAsel");
-						textboxval = dijit.byId("simpTAtext").value;
-						outputval = dijit.byId("simpTAoutput").value;
-						if (wid) {
-								doh.is("7",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.Textarea
-						wid = dijit.byId("textareasel");
-						textboxval = dijit.byId("textareatext").value;
-						outputval = dijit.byId("textareaoutput").value;
-						if (wid) {
-								doh.is("8",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-
-
-					}
-				}
-			]);
-
-			// should be able to verify all of the inputs 
-			doh.register("Check initial declarative values and bindings", [
-				{
-					name: "initial-declarative",
-					runTest: function(){
-						var wid, textboxval, outputval; 
-						// Test Select
-						wid = dijit.byId("decsel");
-						textboxval = dijit.byId("decseltext").value;
-						outputval = dijit.byId("decselOutput").value;
-						if (wid) {
-								doh.is("1",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test FilteringSelect
-						wid = dijit.byId("decfilsel");
-						textboxval = dijit.byId("decfiltext").value;
-						outputval = dijit.byId("decfilOutput").value;
-						if (wid) {
-								doh.is("2",wid.get('value'),"wid.get('value') should be set");
-								doh.is("two",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.ComboBox
-						wid = dijit.byId("deccombosel");
-						textboxval = dijit.byId("deccombotext").value;
-						outputval = dijit.byId("deccomboOutput").value;
-						if (wid) {
-								doh.is("three",wid.get('value'),"wid.get('value') should be set");
-								doh.is("three",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.DateTextBox
-						wid = dijit.byId("decdatesel");
-						textboxval = dijit.byId("decdatetext").value;
-						outputval = dijit.byId("decdateOutput").value;
-						if (wid) {
-								var date1 = "Mon Apr 04 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Mon Apr 4 00:00:00 EDT 2011";
-								doh.t((date1.substring(0,15)==(wid.get('value').toString().substring(0,15)) || 
-									date2==(wid.get('value'))),"wid.get('value') should be set it is:"+wid.get('value'));
-								doh.is("4/4/2011",wid.displayedValue,"wid.displayedValue should be set it is:"+wid.displayedValue);
-								doh.is("2011-04-04",textboxval,"textboxval should be set it is:"+textboxval);
-								doh.is("2011-04-04",outputval,"outputval should be set it is:"+outputval);
-						}
-						// Test dijit.form.HorizontalSlider
-						wid = dijit.byId("decslidersel");
-						textboxval = dijit.byId("decslidertext").value;
-						outputval = dijit.byId("decsliderOutput").value;
-						if (wid) {
-								doh.is("5",wid.get('value'),"wid.get('value') should be set");
-								//doh.is("five",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.NumberSpinner
-						wid = dijit.byId("decnumspinsel");
-						textboxval = dijit.byId("decnumspintext").value;
-						outputval = dijit.byId("decnumspinOutput").value;
-						if (wid) {
-								//doh.is("6",wid.get('value'),"wid.get('value') should be set");
-								doh.is("6",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
-								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
-						}
-						// Test dijit.form.SimpleTextarea
-						wid = dijit.byId("decsimpTAsel");
-						textboxval = dijit.byId("decsimpTAtext").value;
-						outputval = dijit.byId("decsimpTAOutput").value;
-						if (wid) {
-								doh.is("7",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.Textarea
-						wid = dijit.byId("dectextareasel");
-						textboxval = dijit.byId("dectextareatext").value;
-						outputval = dijit.byId("dectextareaOutput").value;
-						if (wid) {
-								doh.is("8",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-
-
-					}
-				}
-			]);
-
-			// should be able to verify all of the inputs 
-			doh.register("Check initial calendar and colorpalette values", [
-				{
-					name: "test-calendar-and-color",
-					runTest: function(){
-						var wid, textboxval, outputval; 
-						// Test Calendar
-						wid = dijit.byId("deccal");
-						textboxval = dijit.byId("deccaltext").value;
-						outputval = dijit.byId("deccalOutput").value;
-						if (wid) {
-							   var date1 = "Wed May 04 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-							   var date2 = "Wed May 4 00:00:00 EDT 2011";
-								doh.t((date1.substring(0,15)==(wid.get('value').toString().substring(0,15)) || 
-									date2==(wid.get('value'))),"1-wid.get('value') should be set value is: "+wid.get('value').toString().substring(0,15));
-								doh.t((date1.substring(0,15)==(textboxval.toString().substring(0,15)) || date2==(textboxval)),"1-textboxval should be set "+textboxval.toString().substring(0,15));
-								doh.t((date1.substring(0,15)==(outputval.toString().substring(0,15)) || date2==(outputval)),"1-outputval should be set "+outputval.toString().substring(0,15));
-						}
-						// Test dijit.ColorPalette
-						wid = dijit.byId("deccolor");
-						textboxval = dijit.byId("deccolortext").value;
-						outputval = dijit.byId("deccolorOutput").value;
-						if (wid) {
-								doh.is("#000000",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}						
-					}
-				}
-			]);
-
-			doh.register("Check update and reset calendar and colorpalette values", [
-				{
-					name: "test-calendar-and-color",
-					runTest: function(){
-						var wid, textboxval, outputval; 
-						// Test Update calendar
-						var d = new Date(2011,10,10);
-						wid = dijit.byId("deccal");
-						//wid.set('value', d.toDateString()); 						
-						wid.set('value', d); 						
-						textboxval = dijit.byId("deccaltext").value;
-						outputval = dijit.byId("deccalOutput").value;
-						if (wid && wid.get('value')) {
-							   var date1 = "Thu Nov 10 2011 00:00:00 GMT-0500 (Eastern Standard Time)";
-							   var date2 = "Thu Nov 10 00:00:00 EST 2011";
-							   var date1b = "Thu Nov 10 2011 01:00:00 GMT-0500 (Eastern Standard Time)";
-							   var date2b = "Thu Nov 10 01:00:00 EST 2011";
-								doh.t((date1.substring(0,15)==(wid.get('value').toString().substring(0,15)) || 
-									date2==(wid.get('value'))),"2-wid.get('value') should be set "+wid.get('value'));
-								doh.t((date1b.substring(0,15)==(textboxval.toString().substring(0,15)) || date2b==(textboxval)),"2-textboxval should be set"+textboxval);
-								doh.t((date1b.substring(0,15)==(outputval.toString().substring(0,15)) || date2b==(outputval)),"2-outputval should be set"+outputval);
-						}
-
-						// Test dijit.ColorPalette
-						// update the text field
-						dijit.byId('deccolortext').set('value',"#ffffff");						
-						wid = dijit.byId("deccolor");
-						textboxval = dijit.byId("deccolortext").value;
-						outputval = dijit.byId("deccolorOutput").value;
-						if (wid) {
-								doh.is("#ffffff",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-
-						// Test Reset Calendar
-						button = dijit.byId("deccalReset"); // reset the model
-						button.onClick();
-						wid = dijit.byId("deccal");
-						textboxval = dijit.byId("deccaltext").value;
-						outputval = dijit.byId("deccalOutput").value;
-						if (wid) {
-							   var date1 = "Wed May 04 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-							   var date2 = "Wed May 4 00:00:00 EDT 2011";
-								doh.t((date1.substring(0,15)==(wid.get('value').toString().substring(0,15)) || 
-									date2==(wid.get('value'))),"3-wid.get('value') should be set "+wid.get('value'));
-								doh.t((date1.substring(0,15)==(textboxval.toString().substring(0,15)) || date2==(textboxval)),"3-textboxval should be set"+textboxval);
-								doh.t((date1.substring(0,15)==(outputval.toString().substring(0,15)) || date2==(outputval)),"3-outputval should be set"+outputval);
-						}
-						// Test reset the dijit.ColorPalette
-						button = dijit.byId("deccolorReset"); // reset the model
-						button.onClick();
-						wid = dijit.byId("deccolor");
-						textboxval = dijit.byId("deccolortext").value;
-						outputval = dijit.byId("deccolorOutput").value;
-						if (wid) {
-								doh.is("#000000",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						
-						
-						
-					}
-				}
-			]);
-
-
-			// Update and Test all fields 
-			doh.register("Test update for all programatic values and bindings", [
-				{
-					name: "update-programatic",
-					runTest: function(){
-						// update the text field
-						dijit.byId('seltext').set('value',"10");						
-						var wid, textboxval, outputval; 
-						// Test Select
-						wid = dijit.byId("sel");
-						textboxval = dijit.byId("seltext").value;
-						outputval = dijit.byId("selOutput").value;
-						if (wid) {
-								doh.is("10",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test FilteringSelect
-						// update the text field
-						dijit.byId('filtext').set('value',"10");						
-						wid = dijit.byId("filsel");
-						textboxval = dijit.byId("filtext").value;
-						outputval = dijit.byId("filoutput").value;
-						if (wid) {
-								doh.is("10",wid.get('value'),"wid.get('value') should be set");
-								doh.is("ten",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.ComboBox
-						dijit.byId('combotext').set('value',"ten");						
-						wid = dijit.byId("combosel");
-						textboxval = dijit.byId("combotext").value;
-						outputval = dijit.byId("combooutput").value;
-						if (wid) {
-								doh.is("ten",wid.get('value'),"wid.get('value') should be set");
-								doh.is("ten",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.DateTextBox
-						// update the text field
-						//var d = new Date(2011,10,10);
-						//wid.set('value', d.toDateString()); //"2011-09-09");						
-						//dijit.byId('datetext').set('value',d.toDateString());						
-						dijit.byId('datetext').set('value',"2011-10-10");						
-						wid = dijit.byId("datesel");
-						textboxval = dijit.byId("datetext").value;
-						outputval = dijit.byId("dateoutput").value;
-						if (wid) {
-								var date1 = "Mon Oct 10 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Mon Oct 10 00:00:00 EDT 2011";
-								doh.t((date1.substring(0,15)==(wid.get('value').toString().substring(0,15)) || 
-									date2==(wid.get('value'))),"wid.get(value) should be set "+wid.get('value'));
-								doh.is("10/10/2011",wid.displayedValue,"wid.displayedValue should be set");
-								doh.t((date1.substring(0,15)==(textboxval.toString().substring(0,15)) || date2==(textboxval)),"2-textboxval should be set"+textboxval);
-								doh.t((date1.substring(0,15)==(outputval.toString().substring(0,15)) || date2==(outputval)),"2-outputval should be set"+outputval);
-						}
-						// Test dijit.form.HorizontalSlider
-						// update the text field
-						dijit.byId('slidertext').set('value',"10");						
-						wid = dijit.byId("slidersel");
-						textboxval = dijit.byId("slidertext").value;
-						outputval = dijit.byId("slideroutput").value;
-						if (wid) {
-								doh.is("10",wid.get('value'),"wid.get(value) should be set");
-								//doh.is("five",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.NumberSpinner
-						dijit.byId('numspintext').set('value',"10");						
-						wid = dijit.byId("numspinsel");
-						textboxval = dijit.byId("numspintext").value;
-						outputval = dijit.byId("numspinoutput").value;
-						if (wid) {
-								doh.is("10",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
-								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
-						}
-						// Test dijit.form.SimpleTextarea
-						dijit.byId('simpTAtext').set('value',"10");						
-						wid = dijit.byId("simpTAsel");
-						textboxval = dijit.byId("simpTAtext").value;
-						outputval = dijit.byId("simpTAoutput").value;
-						if (wid) {
-								doh.is("10",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.Textarea
-						dijit.byId('textareatext').set('value',"10");						
-						wid = dijit.byId("textareasel");
-						textboxval = dijit.byId("textareatext").value;
-						outputval = dijit.byId("textareaoutput").value;
-						if (wid) {
-								doh.is("10",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-
-
-					}
-				}
-			]);
-
-			// Update and Test all fields 
-			doh.register("Test update for all declarative values and bindings", [
-				{
-					name: "update-declarative",
-					runTest: function(){
-						dijit.byId("decsel").set('value',"4");   // update widget value						
-						var wid, textboxval, outputval; 
-						// Test Select
-						wid = dijit.byId("decsel");
-						textboxval = dijit.byId("decseltext").value;
-						outputval = dijit.byId("decselOutput").value;
-						if (wid) {
-								doh.is("4",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test FilteringSelect
-						wid = dijit.byId("decfilsel");
-						wid.set('value','4');   // update widget value
-						textboxval = dijit.byId("decfiltext").value;
-						outputval = dijit.byId("decfilOutput").value;
-						if (wid) {
-								doh.is("4",wid.get('value'),"wid.get('value') should be set");
-								doh.is("four",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.ComboBox
-						wid = dijit.byId("deccombosel");
-						wid.set('value',"four");   // update widget value
-						textboxval = dijit.byId("deccombotext").value;
-						outputval = dijit.byId("deccomboOutput").value;
-						if (wid) {
-								doh.is("four",wid.get('value'),"wid.get('value') should be set");
-								doh.is("four",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.DateTextBox
-						wid = dijit.byId("decdatesel");
-						//var d = new Date(2011,09,09);
-						//wid.set('value', d.toDateString()); //"2011-09-09");						
-						wid.set('value', "2011-09-09");						
-						textboxval = dijit.byId("decdatetext").value;
-						outputval = dijit.byId("decdateOutput").value;
-						if (wid) {
-								var date1 = "Fri Sep 09 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Fri Sep 9 00:00:00 EDT 2011";
-								doh.t((date1.substring(0,15)==(wid.get('value').toString().substring(0,15)) || 
-									date2==(wid.get('value'))),"wid.get('value') should be set "+wid.get('value'));
-								doh.t((date1.substring(0,15)==(textboxval.toString().substring(0,15)) || date2==(textboxval)),"textboxval should be set"+textboxval);
-								doh.t((date1.substring(0,15)==(outputval.toString().substring(0,15)) || date2==(outputval)),"outputval should be set"+outputval);
-								doh.is("9/9/2011",wid.displayedValue,"wid.displayedValue should be set");
-						}
-						// Test dijit.form.HorizontalSlider
-						wid = dijit.byId("decslidersel");
-						wid.set('value',"4");   // update widget value
-						textboxval = dijit.byId("decslidertext").value;
-						outputval = dijit.byId("decsliderOutput").value;
-						if (wid) {
-								doh.is("4",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.NumberSpinner
-						wid = dijit.byId("decnumspinsel");
-						wid.set('displayedValue',"4");   // update widget value
-						textboxval = dijit.byId("decnumspintext").value;
-						outputval = dijit.byId("decnumspinOutput").value;
-						if (wid) {
-								doh.is("4",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
-								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
-						}
-						// Test dijit.form.SimpleTextarea
-						wid = dijit.byId("decsimpTAsel");
-						wid.set('value',"4");   // update widget value
-						textboxval = dijit.byId("decsimpTAtext").value;
-						outputval = dijit.byId("decsimpTAOutput").value;
-						if (wid) {
-								doh.is("4",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.Textarea
-						wid = dijit.byId("dectextareasel");
-						wid.set('value',"4");   // update widget value
-						textboxval = dijit.byId("dectextareatext").value;
-						outputval = dijit.byId("dectextareaOutput").value;
-						if (wid) {
-								doh.is("4",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-
-
-					}
-				}
-			]);
-
-
-
-
-			// Test RESET for all fields 
-			doh.register("Test reset for all programatic values and bindings", [
-				{
-					name: "reset-programatic",
-					runTest: function(){
-						// reset the model
-						var button = dijit.byId("selReset"); 
-						button.onClick();
-						var wid, textboxval, outputval; 
-						// Test Select
-						wid = dijit.byId("sel");
-						textboxval = dijit.byId("seltext").value;
-						outputval = dijit.byId("selOutput").value;
-						if (wid) {
-								doh.is("1",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test FilteringSelect
-						button = dijit.byId("filReset"); 
-						button.onClick();
-						wid = dijit.byId("filsel");
-						textboxval = dijit.byId("filtext").value;
-						outputval = dijit.byId("filoutput").value;
-						if (wid) {
-								doh.is("2",wid.get('value'),"wid.get('value') should be set");
-								doh.is("two",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.ComboBox
-						button = dijit.byId("comboReset"); 
-						button.onClick();
-						wid = dijit.byId("combosel");
-						textboxval = dijit.byId("combotext").value;
-						outputval = dijit.byId("combooutput").value;
-						if (wid) {
-								doh.is("three",wid.get('value'),"wid.get('value') should be set");
-								doh.is("three",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.DateTextBox
-						button = dijit.byId("dateReset"); 
-						button.onClick();
-						wid = dijit.byId("datesel");
-						textboxval = dijit.byId("datetext").value;
-						outputval = dijit.byId("dateoutput").value;
-						if (wid) {
-								var date1 = "Mon Apr 04 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Mon Apr 4 00:00:00 EDT 2011";
-								doh.t((date1.substring(0,15)==(textboxval.toString().substring(0,15)) || date2==(textboxval)),"textboxval should be set"+textboxval);
-								doh.t((date1.substring(0,15)==(outputval.toString().substring(0,15)) || date2==(outputval)),"outputval should be set"+outputval);
-						}
-						// test a second reset...
-						button.onClick();
-						if (wid) {
-								var date1 = "Mon Apr 04 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Mon Apr 4 00:00:00 EDT 2011";
-								doh.t((date1.substring(0,15)==(wid.get('value').toString().substring(0,15)) || 
-									date2==(wid.get('value'))),"wid.get('value') should be set "+wid.get('value'));
-								doh.t((date1.substring(0,15)==(textboxval.toString().substring(0,15)) || date2==(textboxval)),"textboxval should be set"+textboxval);
-								doh.t((date1.substring(0,15)==(outputval.toString().substring(0,15)) || date2==(outputval)),"outputval should be set"+outputval);
-								doh.is("4/4/2011",wid.displayedValue,"wid.displayedValue should be set");
-						}
-						// Test dijit.form.HorizontalSlider
-						button = dijit.byId("sliderReset"); 
-						button.onClick();
-						wid = dijit.byId("slidersel");
-						textboxval = dijit.byId("slidertext").value;
-						outputval = dijit.byId("slideroutput").value;
-						if (wid) {
-								doh.is("5",wid.get('value'),"wid.get('value') should be set");
-								//doh.is("five",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.NumberSpinner
-						button = dijit.byId("numspinReset"); 
-						button.onClick();
-						wid = dijit.byId("numspinsel");
-						textboxval = dijit.byId("numspintext").value;
-						outputval = dijit.byId("numspinoutput").value;
-						if (wid) {
-								doh.is("6",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
-								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
-						}
-						// Test dijit.form.SimpleTextarea
-						button = dijit.byId("simpTAReset"); 
-						button.onClick();
-						wid = dijit.byId("simpTAsel");
-						textboxval = dijit.byId("simpTAtext").value;
-						outputval = dijit.byId("simpTAoutput").value;
-						if (wid) {
-								doh.is("7",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.Textarea
-						button = dijit.byId("textareaReset"); 
-						button.onClick();
-						wid = dijit.byId("textareasel");
-						textboxval = dijit.byId("textareatext").value;
-						outputval = dijit.byId("textareaoutput").value;
-						if (wid) {
-								doh.is("8",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-
-
-					}
-				}
-			]);
-
-			// Test reset all declarative 
-			doh.register("Test Reset all declarative values and bindings", [
-				{
-					name: "reset-declarative",
-					runTest: function(){
-						var button = dijit.byId("decselReset"); // reset the model
-						button.onClick();
-						var wid, textboxval, outputval; 
-						// Test Select
-						wid = dijit.byId("decsel");
-						textboxval = dijit.byId("decseltext").value;
-						outputval = dijit.byId("decselOutput").value;
-						if (wid) {
-								doh.is("1",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test FilteringSelect
-						button = dijit.byId("decfilReset"); // reset the model
-						button.onClick();
-						wid = dijit.byId("decfilsel");
-						textboxval = dijit.byId("decfiltext").value;
-						outputval = dijit.byId("decfilOutput").value;
-						if (wid) {
-								doh.is("2",wid.get('value'),"wid.get('value') should be set");
-								doh.is("two",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.ComboBox
-						button = dijit.byId("deccomboReset"); // reset the model
-						button.onClick();
-						wid = dijit.byId("deccombosel");
-						textboxval = dijit.byId("deccombotext").value;
-						outputval = dijit.byId("deccomboOutput").value;
-						if (wid) {
-								doh.is("three",wid.get('value'),"wid.get('value') should be set");
-								doh.is("three",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.DateTextBox
-						button = dijit.byId("decdateReset"); // reset the model
-						button.onClick();
-						wid = dijit.byId("decdatesel");
-						textboxval = dijit.byId("decdatetext").value;
-						outputval = dijit.byId("decdateOutput").value;
-						if (wid) {
-								var date1 = "Mon Apr 04 2011 00:00:00 GMT-0400 (Eastern Daylight Time)";
-								var date2 = "Mon Apr 4 00:00:00 EDT 2011";
-								doh.t((date1.substring(0,15)==(wid.get('value').toString().substring(0,15)) || 
-									date2==(wid.get('value'))),"wid.get('value') should be set "+wid.get('value'));
-								doh.is("4/4/2011",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is("2011-04-04",textboxval,"textboxval should be set");
-								doh.is("2011-04-04",outputval,"outputval should be set");
-						}
-						// Test dijit.form.HorizontalSlider
-						button = dijit.byId("decsliderReset"); // reset the model
-						button.onClick();
-						wid = dijit.byId("decslidersel");
-						textboxval = dijit.byId("decslidertext").value;
-						outputval = dijit.byId("decsliderOutput").value;
-						if (wid) {
-								doh.is("5",wid.get('value'),"wid.get('value') should be set");
-								//doh.is("five",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.NumberSpinner
-						button = dijit.byId("decnumspinReset"); // reset the model
-						button.onClick();
-						wid = dijit.byId("decnumspinsel");
-						textboxval = dijit.byId("decnumspintext").value;
-						outputval = dijit.byId("decnumspinOutput").value;
-						if (wid) {
-								//doh.is("6",wid.get('value'),"wid.get('value') should be set");
-								doh.is("6",wid.displayedValue,"wid.displayedValue should be set");
-								doh.is(textboxval,wid.displayedValue,"wid.displayedValue should be set same as textboxval");
-								doh.is(outputval,wid.displayedValue,"wid.displayedValue should be set same as outputval");
-						}
-						// Test dijit.form.SimpleTextarea
-						button = dijit.byId("decsimpTAReset"); // reset the model
-						button.onClick();
-						wid = dijit.byId("decsimpTAsel");
-						textboxval = dijit.byId("decsimpTAtext").value;
-						outputval = dijit.byId("decsimpTAOutput").value;
-						if (wid) {
-								doh.is("7",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-						// Test dijit.form.Textarea
-						button = dijit.byId("dectextareaReset"); // reset the model
-						button.onClick();
-						wid = dijit.byId("dectextareasel");
-						textboxval = dijit.byId("dectextareatext").value;
-						outputval = dijit.byId("dectextareaOutput").value;
-						if (wid) {
-								doh.is("8",wid.get('value'),"wid.get('value') should be set");
-								doh.is(textboxval,wid.get('value'),"wid.get('value') should be set same as textboxval");
-								doh.is(outputval,wid.get('value'),"wid.get('value') should be set same as outputval");
-						}
-
-					}
-				}
-			]);
-
-
-			// Test reset all declarative 
-			doh.register("Test NaN values and bindings", [
-				{
-					name: "NaN-test",
-					runTest: function(){
-						var button = dijit.byId("decselReset"); // reset the model
-						button.onClick();
-						var wid, wid2; 
-
-						// test for NaN stuff here, uses nanmodel, without fix for ticket 14190 FF crashes
-						wid = dijit.byId("nannb");
-						wid.focus();
-						wid2 = dijit.byId("textareatext");
-						wid2.focus();
-						wid = dijit.byId("nannb");
-						wid.focus();
-						wid2.focus();
-						if (wid) {
-								doh.t(isNaN(wid.get('value')),"isNaN(wid.get('value') should be true");
-						}
-
-					}
-				}
-			]);
-
-			doh.run();
-
-		});
-	</script>
-</head>
-	<body class="claro">
-		<div id="wrapper">
-			<div id="header" style="margin-top: 0px;">
-				<div id="navigation"  style="margin-top: 0px;"></div>
-				<div id="headerInsert"  style="margin-top: 0px;">
-					<h2>Data-bound Form Element Kitchen Sink MVC test</h2>
-				</div>
-			</div>
-			<div id="main" style="margin-top: 0px;">
-				<div id="leftNav"></div>
-				<div id="mainContent">
-	
-					<h2 style="margin-top: 0px;">Programmatic creation of Form elements:</h2>
-					<table>
-						<tbody>
-							<tr>
-								<td><label>Widget</label></td>
-								<td><label></label></td>
-								<td><label>Textbox</label></td>
-								<td><label>Output</label></td>
-								<td><label>Model Reset</label></td>
-							</tr>
-							<tr>
-								<td><label for="sel">Select:</label></td>
-								<td><div id="sel"></div></td>
-								<td><div id="seltext"></div></td>
-								<td><div id="selOutput"></div></td>
-								<td><div id="reset1" ></div></td>
-							</tr>
-							<tr>
-								<td><label for="filsel">FilteringSelect:</label></td>
-								<td><div id="filsel"></div></td>
-								<td><div id="filtext"></div></td>
-								<td><div id="filoutput"></div></td>
-								<td><div id="filreset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="combosel">ComboBox:</label></td>
-								<td><div id="combosel"></div></td>
-								<td><div id="combotext"></div></td>
-								<td><div id="combooutput"></div></td>
-								<td><div id="comboreset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="datesel">DateTextBox:</label></td>
-								<td><div id="datesel"></div></td>
-								<td><div id="datetext"></div></td>
-								<td><div id="dateoutput"></div></td>
-								<td><div id="datereset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="slidersel">Slider:</label></td>
-								<td><div id="slidersel"></div></td>
-								<td><div id="slidertext"></div></td>
-								<td><div id="slideroutput"></div></td>
-								<td><div id="sliderreset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="numspinsel">NumberSpinner:</label></td>
-								<td><div id="numspinsel"></div></td>
-								<td><div id="numspintext"></div></td>
-								<td><div id="numspinoutput"></div></td>
-								<td><div id="numspinreset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="simpTAsel">SimpleTextArea:</label></td>
-								<td><div id="simpTAsel"></div></td>
-								<td><div id="simpTAtext"></div></td>
-								<td><div id="simpTAoutput"></div></td>
-								<td><div id="simpTAreset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="textareasel">TextArea:</label></td>
-								<td><div id="textareasel"></div></td>
-								<td><div id="textareatext"></div></td>
-								<td><div id="textareaoutput"></div></td>
-								<td><div id="textareareset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="nannb">TextBox nan test:</label></td>
-								<td><div id="nannb"></div></td>
-							</tr>							
-						</tbody>
-					</table>
-	  
-					<h2>Declarative creation of Form elements:</h2>
-					<table>
-						<tbody>
-							<tr>
-								<td><label>Widget</label></td>
-								<td><label></label></td>
-								<td><label>Textbox</label></td>
-								<td><label>Output</label></td>
-								<td><label>Model Reset</label></td>
-							</tr>
-							<tr>
-								<td><label for="decsel">Select:</label></td>
-								<td>
-									<select id="decsel" style="width: 188px;" 
-													data-dojo-id="decsel" data-dojo-type="dijit.form.Select" 
-													data-dojo-props='name:"decsel", ref: decselmodel.number '>
-										<option value="1">one</option>
-										<option value="2">two</option>
-										<option value="3">three</option>
-										<option value="4">four</option>
-									</select>
-								</td>
-								<td>
-									<input class="cell" id="decseltext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decselmodel.number"></input>
-								</td>
-								<td><span   id="decselOutput" data-dojo-type="dojox.mvc.Output"
-											data-dojo-props="ref: decselmodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decselReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){decselmodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="decfilsel">FilteringSelect:</label></td>
-								<td>
-									<input id="decfilsel" data-dojo-type="dijit.form.FilteringSelect"
-										data-dojo-props='store:store, ref: decfilmodel.number'/>
-								</td>
-								<td>
-									<input id="decfiltext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decfilmodel.number"></input>
-								</td>
-								<td><span id="decfilOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: decfilmodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decfilReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){decfilmodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="deccombosel">ComboBox:</label></td>
-								<td>
-									<input id="deccombosel" data-dojo-type="dijit.form.ComboBox"
-										data-dojo-props='store:store, ref: deccombomodel.number'/>
-								</td>
-								<td>
-									<input id="deccombotext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: deccombomodel.number"></input>
-								</td>
-								<td><span id="deccomboOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: deccombomodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="deccomboReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){deccombomodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="datesel">DateTextBox:</label></td>
-								<td>
-									<input id="decdatesel" data-dojo-type="dijit.form.DateTextBox"
-										data-dojo-props='store:store, ref: decdatemodel.number'/>
-								</td>
-								<td>
-									<input id="decdatetext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decdatemodel.number"></input>
-								</td>
-								<td><span id="decdateOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: decdatemodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decdateReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){decdatemodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="decslidersel">Slider:</label></td>
-								<td>
-									<input id="decslidersel" data-dojo-type="dijit.form.HorizontalSlider"
-										data-dojo-props='store:store, ref: decslidermodel.number,
-														style:{width:"190px"}, minimum:0, maximum:100, discreteValues:21'/>
-								</td>
-								<td>
-									<input id="decslidertext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decslidermodel.number"></input>
-								</td>
-								<td><span id="decsliderOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: decslidermodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decsliderReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){decslidermodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="decnumspinsel">NumberSpinner:</label></td>
-								<td>
-									<input id="decnumspinsel" data-dojo-type="dijit.form.NumberSpinner"
-										data-dojo-props='store:store, ref: decnumspinmodel.number'/>
-								</td>
-								<td>
-									<input id="decnumspintext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decnumspinmodel.number"></input>
-								</td>
-								<td><span id="decnumspinOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: decnumspinmodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decnumspinReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){decnumspinmodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="decsimpTAsel">SimpleTextArea:</label></td>
-								<td>
-									<input id="decsimpTAsel" data-dojo-type="dijit.form.Textarea"
-										data-dojo-props='store:store, ref: decsimpTAmodel.number'/>
-								</td>
-								<td>
-									<input id="decsimpTAtext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decsimpTAmodel.number"/>
-								</td>
-								<td><span id="decsimpTAOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: decsimpTAmodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decsimpTAReset" type="button" data-dojo-type="dijit.form.Button" 
-										data-dojo-props="onClick: function(){decsimpTAmodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="dectextareasel">TextArea:</label></td>
-								<td>
-									<input id="dectextareasel" data-dojo-type="dijit.form.Textarea"
-										data-dojo-props='store:store, ref: dectextareamodel.number'/>
-								</td>
-								<td>
-									<input id="dectextareatext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: dectextareamodel.number"/>
-								</td>
-								<td><span id="dectextareaOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: dectextareamodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="dectextareaReset" type="button" data-dojo-type="dijit.form.Button" 
-										data-dojo-props="onClick: function(){dectextareamodel.reset();}">Reset</button></td>
-							</tr>
-						</tbody>
-					</table>
-	  
-					<h2>Test data-bound dijit.Calendar:</h2>
-					<table>
-						<tbody>
-							<tr>
-								<td><label>Widget</label></td>
-								<td><label></label></td>
-								<td><label>Textbox</label></td>
-								<td><label>Output</label></td>
-								<td><label>Model Reset</label></td>
-							</tr>
-							<tr>
-								<td><label for="deccal">Calendar:</label></td>
-								<td>
-									<input class="cell"  id="deccal" data-dojo-id="deccal"  data-dojo-type="dijit.Calendar" 
-											data-dojo-props='ref: deccalmodel.date '/>
-								</td>
-								<td>
-									<input class="cell" id="deccaltext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: deccalmodel.date"></input>
-								</td>
-								<td><span   id="deccalOutput" data-dojo-type="dojox.mvc.Output"
-											data-dojo-props="ref: deccalmodel.date">
-						 			${this.value}
-								</span></td>
-								<td><button id="deccalReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){deccalmodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="deccolor">ColorPalette:</label></td>
-								<td>
-									<div id="deccolor" data-dojo-type="dijit.ColorPalette" 
-											data-dojo-props='palette:"3x4", ref: deccolormodel.code'></div>								
-								</td>
-								<td>
-									<input class="cell" id="deccolortext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: deccolormodel.code"></input>
-								</td>
-								<td><span   id="deccolorOutput" data-dojo-type="dojox.mvc.Output"
-											data-dojo-props="ref: deccolormodel.code">
-						 			${this.value}
-								</span></td>
-								<td><button id="deccolorReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){deccolormodel.reset();}">Reset</button></td>
-							</tr>
-						</tbody>
-					</table>
-				</div>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/doh_mvc_programmatic-repeat-store.html b/dojox/mvc/tests/doh_mvc_programmatic-repeat-store.html
deleted file mode 100644
index dbc8e22..0000000
--- a/dojox/mvc/tests/doh_mvc_programmatic-repeat-store.html
+++ /dev/null
@@ -1,348 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>MVC DOH Test</title>
-
-	<style>
-		@import "../../../dojo/resources/dojo.css";
-		@import "./css/dijitTests.css";
-		@import "css/app-format.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script src="../../../dojo/dojo.js" type="text/javascript"
-		djConfig="parseOnLoad: false, isDebug: true">
-	</script>
-	<script type="text/javascript" src="./helpers.js"></script>
-
-	<script type="text/javascript" >
-		dojo.require("dojox.mvc");
-		dojo.require("dojox.mvc.Group");
-		dojo.require("dojox.mvc.Repeat");
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dijit.form.Button");
-		dojo.require("dojo.data.ItemFileWriteStore");
-		dojo.require("dojo.store.DataStore");
-		dojo.require("dojo.parser");
-		
-			var results, selectedIndex = 0;
-				// declared here for convenience
-			templateString = '<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: \'${this.index}\'">' +
-							'<label class="cell">Name:</label>' + 
-							'<input class="cell" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: \'First\'"></input>' +
-							'<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext(\'${this.index}\');}">Details</button>' +
-						'</div>';
-
-			function setup() {
-				var writeStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests._data", "mvcRepeatData.json")});
-				var modelPromise = dojox.mvc.newStatefulModel({store: new dojo.store.DataStore({store: writeStore})}); 
-				modelPromise.then(function(model){ 
-					results = model;
-					dojo.parser.parse();
-
-					// Can test with either the dojox.mvc.Repeat or my.Repeat
-					var repeat = new my.Repeat({
-					//var repeat = new dojox.mvc.Repeat({
-					//	templateString: templateString, // not needed with my.Repeat since it is set there.
-						ref: model
-					}).placeAt('repeat2');
-					repeat.startup();
-					startTests();
-				});
-			};
-
-			dojo.declare('my.Repeat', [dojox.mvc.Repeat], {
-				templateString : templateString
-			});
-			dojo.addOnLoad(setup);
-	</script>
-
-	<script type="text/javascript">
-		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		function startTests(){
-			 // should be able to verify all of the inputs 
-			doh.register("Check initial values and bindings", [
-				{
-					name: "initial",
-					runTest: function(){
-						var name1, bind1, firstInput; 
-						name1 = dijit.byId("dijit_form_TextBox_10");
-						if (name1) {
-							console.log("testing dijit_form_TextBox_10");
-							bind1 = name1.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Anne",bind1.data,"bind1.data should be set");
-								doh.is("Anne",bind1.value,"bind1.value should be set");
-							}
-						}
-
-						name1 = dijit.byId("dijit_form_TextBox_0");
-						if (name1) {
-							console.log("testing dijit_form_TextBox_0");
-							bind1 = name1.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Anne",bind1.data,"bind1.data should be set");
-								doh.is("Anne",bind1.value,"bind1.value should be set");
-							}
-						}
-
-						firstInput = dijit.byId("firstInput");
-						if (firstInput) {
-							bind1 = firstInput.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Anne",bind1.data,"bind1.data should be set");
-								doh.is("Anne",bind1.value,"bind1.value should be set");
-							}
-						}
-					}
-				}
-			]);
-
-			doh.register("select Ben", [
-				{
-					name: "testBen",
-					runTest: function(){
-						setDetailsContext(1);
-						var name1, bind1, firstInput; 
-						name1 = dijit.byId("dijit_form_TextBox_11");
-						if (name1) {
-							bind1 = name1.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Ben",bind1.data,"bind1.data is wrong");
-								doh.is("Ben",bind1.value,"bind1.value is wrong");
-							}
-						}
-						name1 = dijit.byId("dijit_form_TextBox_1");
-						if (name1) {
-							bind1 = name1.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Ben",bind1.data,"bind1.data is wrong");
-								doh.is("Ben",bind1.value,"bind1.value is wrong");
-							}
-						}
-
-						firstInput = dijit.byId("firstInput");
-						if (firstInput) {
-							bind1 = firstInput.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								console.debug("firstInput.value="+firstInput.value);
-								doh.is("Ben",bind1.data,"firstInput bind1.data is wrong");
-								doh.is("Ben",bind1.value,"firstInput bind1.value is wrong");
-							}
-						}
-					}
-				}
-			]);
-
-
-			doh.register("select John and update John to Johnny test valueOf and toString", [
-				{
-					name: "testJohn",
-					runTest: function(){
-						setDetailsContext(9); //select John 
-						var name9, bind9, firstInput; 
-						name9 = dijit.byId("dijit_form_TextBox_19");
-						if (name9) {
-							bind9 = name9.get("binding");
-							if (bind9 && bind9.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("John",bind9.data,"bind9.data is wrong");
-								doh.is("John",bind9.value,"bind9.value is wrong");
-								doh.is("John",bind9.valueOf(),"bind9.valueOf() is wrong");
-								doh.is("John",bind9.toString(),"bind9.toString() is wrong");
-							}
-						}
-						name9 = dijit.byId("dijit_form_TextBox_9");
-						if (name9) {
-							bind9 = name9.get("binding");
-							if (bind9 && bind9.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("John",bind9.data,"bind9.data is wrong");
-								doh.is("John",bind9.value,"bind9.value is wrong");
-								doh.is("John",bind9.valueOf(),"bind9.valueOf() is wrong");
-								doh.is("John",bind9.toString(),"bind9.toString() is wrong");
-							}
-						}
-
-						firstInput = dijit.byId("firstInput");
-						dojo.byId("firstInput").focus();
-						firstInput.set('value',"Johnny");
-						dojo.byId("lastInput").focus();
-						
-						if (firstInput) {
-							bind9 = firstInput.get("binding");
-							if (bind9 && bind9.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Johnny",bind9.value,"firstInput bind9.value is wrong");
-								doh.is("Johnny",firstInput.value,"firstInput firstInput.value is wrong");
-								doh.is("Johnny",bind9.valueOf(),"firstInput bind9.valueOf() is wrong");
-								doh.is("Johnny",bind9.toString(),"firstInput bind9.toString() is wrong");
-							}
-						}
-
-						// Test the value of and toString
-						valueOfTest = new dojox.mvc.StatefulModel({ data: 42 });
-						doh.is(42,valueOfTest.data,"valueOfTest.data is wrong");
-						doh.is(42,valueOfTest.value,"valueOfTest.value is wrong");
-						doh.is(42,+valueOfTest,"valueOfTest.valueOf() is wrong");
-						doh.is("42",'' + valueOfTest,"valueOfTest.toString() is wrong");
-
-						toStringTest = new dojox.mvc.StatefulModel({ data: 'abc' });
-						doh.is('abc',toStringTest.data,"toStringTest.data is wrong");
-						doh.is('abc',toStringTest.value,"toStringTest.value is wrong");
-						doh.is(NaN,+toStringTest,"toStringTest.valueOf() is wrong");
-						doh.is('abc','' + toStringTest,"toStringTest.toString() is wrong")
-
-						
-					}					
-				}
-			]);
-
-			doh.register("test Commit and Reset", [
-				{
-					name: "testC&R",
-					runTest: function(){
-						setDetailsContext(8); //select Irene 
-						var name8, bind8, firstInput, lastInput; 
-						name8 = dijit.byId("dijit_form_TextBox_18");
-						if (name8) {
-							bind8 = name8.get("binding");
-							if (bind8 && bind8.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Irene",bind8.data,"bind8.data is wrong");
-								doh.is("Irene",bind8.value,"bind8.value is wrong");
-							}
-						}
-						name8 = dijit.byId("dijit_form_TextBox_8");
-						if (name8) {
-							bind8 = name8.get("binding");
-							if (bind8 && bind8.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Irene",bind8.data,"bind8.data is wrong");
-								doh.is("Irene",bind8.value,"bind8.value is wrong");
-							}
-						}
-
-						//update Irene to IreneThisUpdateShouldBeSaved and commit
-						firstInput = dijit.byId("firstInput");
-						dojo.byId("firstInput").focus();
-						firstInput.set("value","IreneThisUpdateShouldBeSaved");
-						dojo.byId("lastInput").focus();
-						results.commit();
-
-						lastInput = dijit.byId("lastInput");
-						dojo.byId("lastInput").focus();
-						lastInput.set("value", "IraThisUpdateShouldBeReset");
-						dojo.byId("firstInput").focus();
-						results.reset();
-						
-						if (firstInput) {
-							bind8 = firstInput.get("binding");
-							if (bind8 && bind8.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("IreneThisUpdateShouldBeSaved",bind8.value,"firstInput bind8.value is wrong");
-								doh.is("IreneThisUpdateShouldBeSaved",firstInput.value,"firstInput firstInput.value is wrong");
-								doh.is("Ira",lastInput.value,"lastInput lastInput.value is wrong");
-							}
-						}
-					}
-				}
-			]);
-			
-			doh.run();
-		};
-	</script>
-</head>
-<body class="claro">
-	<h1 class="testTitle">doh_mvc_programmatic-repeat-store.html automated tests (non-robot)</h1>
-		<div id="wrapper">
-			<div id="header">
-				<div id="navigation">
-				</div>
-				<div id="headerInsert">
-				<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
-				</div>
-			</div>
-			<div id="main">
-				<div id="leftNav">
-				</div>
-				<div id="mainContent">
-					<div id="searchBanner">Search Results for term: </div>         
-					<!--
-						The repeat container denotes a templated UI that operates over a collection
-						of data records.
-						The UI can be customized for each iteration using properties such as
-						${this.index} for the iteration index.
-					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results', templateString: templateString"></div>
-					<div id="repeatId" data-dojo-type="my.Repeat" data-dojo-props="ref: 'results'"></div>
-					-->
-					<table><tbody><tr>
-								<td>
-									<div>
-										<div>Programatic Repeat using my.Repeat and its templateString: </div>         
-										<div id="repeat2"></div>
-									</div>
-								</td>
-								<td>
-									<div>
-										<div>Declarative Repeat using my.Repeat does not pass templateString: </div>         
-										<div id="repeatId2" data-dojo-type="my.Repeat" data-dojo-props="ref: 'results'"></div>
-									</div>
-								</td>
-					</tr></tbody></table>
-					
-					<div class="spacer"></div>
-
-					<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results'">
-						<div id="detailsBanner">Details for selected index:</div>
-
-						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
-							<div class="row">
-								<label class="cell" for="firstInput">First Name:</label>
-								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="lastInput">Last Name:</label>
-								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="locationInput">Location:</label>
-								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="officeInput">Office:</label>
-								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="emailInput">Email:</label>
-								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="telInput">Telephone:</label>
-								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="faxInput">Fax:</label>
-								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
-							</div>
-							<div class="row">
-							<div class="spacer"></div>
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results[selectedIndex].toPlainObject());results[selectedIndex].commit();}">Save Item</button>        
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.toPlainObject());results.commit();;}">Commit All</button>        
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.reset();}">Reset to last saved</button>        
-							</div>
-						</div>
-					</div>
-				</div>
-			</div>
-        </div>
-        <script type="text/javascript">
-			// called to change the selected item
-			function setDetailsContext(index) {
-				selectedIndex = index;
-				var widget = dijit.byId("detailsGroup");
-				widget.set("ref", index);
-			}
-        </script>
-    </body>
-</html>
diff --git a/dojox/mvc/tests/doh_mvc_ref-set-repeat.html b/dojox/mvc/tests/doh_mvc_ref-set-repeat.html
deleted file mode 100644
index c5187a5..0000000
--- a/dojox/mvc/tests/doh_mvc_ref-set-repeat.html
+++ /dev/null
@@ -1,247 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>MVC DOH Test</title>
-	<style>
-		@import "../../../dojo/resources/dojo.css";
-		@import "./css/dijitTests.css";
-		@import "css/app-format.css";
-	</style>
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-	<script src="../../../dojo/dojo.js" type="text/javascript" djConfig="isDebug: true"></script>
-	<script type="text/javascript" src="./helpers.js"></script>
-	<script type="text/javascript">
-			dojo.require("dojox.mvc");
-			dojo.require("dojox.mvc.Output");
-			dojo.require("dojox.mvc.Group");
-			dojo.require("dojox.mvc.Repeat");
-			dojo.require("dijit.form.TextBox");
-			dojo.require("dijit.form.Button");
-			dojo.require("dojo.store.Memory");
-			dojo.require("dojo.parser");
-
-			var search_results_init1 =
-			[{
-				"Query" : "Engineers1",
-				"Results" : [
-					{
-						"First"	  : "Anne1",
-						"Last"	  : "Ackerman1"
-					},
-					{
-						"First"	  : "Ben1",
-						"Last"	  : "Beckham1"
-					},
-					{
-						"First"	  : "Chad1",
-						"Last"	  : "Chapman1"
-					}
-				]
-			}];
-			var search_results_init2 =
-			[{
-				"Query" : "Engineers2",
-				"Results" : [
-					{
-						"First"	  : "Anne2",
-						"Last"	  : "Ackerman2"
-					},
-					{
-						"First"	  : "Ben2",
-						"Last"	  : "Beckham2"
-					}
-				]
-			}];
-			var search_results_init3 =
-			[{
-				"Query" : "Engineers3",
-				"Results" : [
-					{
-						"First"	  : "",
-						"Last"	  : ""
-					}
-				]
-			}];
-
-			var memStore1 = new dojo.store.Memory({data : search_results_init1});
-			var model1 = dojox.mvc.newStatefulModel({ store : memStore1 })[0];
-			var memStore2 = new dojo.store.Memory({data : search_results_init2});
-			var model2 = dojox.mvc.newStatefulModel({ store : memStore2 })[0];
-			var memStore3 = new dojo.store.Memory({data : search_results_init3});
-			var model3 = dojox.mvc.newStatefulModel({ store : memStore3 })[0];
-	</script>
-
-	<script type="text/javascript">
-		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
-
-		dojo.addOnLoad(function() {
-
-		doh.register("parse", function() {
-			dojo.parser.parse();
-		});
-
-		// should be able to verify all of the inputs 
-		doh.register("check initial values and bindings", [{
-			name : "initial",
-			runTest : function() {
-				doh.is("Anne1", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne1");
-				doh.is("Ben1",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben1 ");
-				doh.is("Chad1", dijit.byId("nameInput2").get('value'),"nameInput2 should be Chad1");
-
-				doh.is("Anne1", dijit.byId("firstnameOutput10").get('value'),"firstnameOutput10 should be Anne1");
-				doh.is("Ben1",  dijit.byId("firstnameOutput11").get('value'),"firstnameOutput11 should be Ben1 ");
-				doh.is("Chad1", dijit.byId("firstnameOutput12").get('value'),"firstnameOutput12 should be Chad1");
-
-				doh.is("Anne2", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2");
-				doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
-
-				doh.is("", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be blank");
-			}
-		}]);
-
-		doh.register("SelectModel2", [{
-			name : "SelectModel2",
-			runTest : function() {
-							//doh.robot.mouseMoveAt("dijit_form_Button_1", 500, 0);
-							//doh.robot.mouseClick({left:true}, 500);
-				dijit.byId('outergroupId').set('ref',model2);			
-							
-				doh.is("Anne2", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne2");
-				doh.is("Ben2",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben2 ");				
-			}
-		}]);
-
-		doh.register("ChangeModel2", [{
-			name : "ChangeModel2",
-			runTest : function() {
-				dijit.byId('nameInput0').set('value',"Anne2-Update");			
-							
-				doh.is("Anne2-Update", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne2-Update");
-				doh.is("Ben2",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben2 ");
-
-				doh.is("Anne2-Update", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2-Update");
-				doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
-			}
-		}]);
-
-		doh.register("SelectModel3", [{
-			name : "SelectModel3",
-			runTest : function() {
-				dijit.byId('outergroupId').set('ref',model3);			
-							
-				doh.is("", dijit.byId("nameInput0").get('value'),"nameInput0 should be blank");
-			}
-		}]);
-
-		doh.register("ChangeModel3", [{
-			name : "ChangeModel3",
-			runTest : function() {
-				dijit.byId('nameInput0').set('value',"Anne3-Update");			
-							
-				doh.is("Anne3-Update", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne3-Update");
-
-				doh.is("Anne3-Update", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be Anne3-Update");
-			}
-		}]);
-
-		doh.register("ResetAll", [{
-			name : "ResetAll",
-			runTest : function() {
-				dijit.byId('outergroupId').set('ref',model1);			
-				model1.reset();
-				model2.reset();
-				model3.reset();			
-							
-				doh.is("Anne1", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne1");
-				doh.is("Ben1",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben1 ");
-				doh.is("Chad1", dijit.byId("nameInput2").get('value'),"nameInput2 should be Chad1");
-
-				doh.is("Anne1", dijit.byId("firstnameOutput10").get('value'),"firstnameOutput10 should be Anne1");
-				doh.is("Ben1",  dijit.byId("firstnameOutput11").get('value'),"firstnameOutput11 should be Ben1 ");
-				doh.is("Chad1", dijit.byId("firstnameOutput12").get('value'),"firstnameOutput12 should be Chad1");
-
-				doh.is("Anne2", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2");
-				doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
-
-				doh.is("", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be blank");
-			}
-		}]);
-
-		doh.run();
-
-		});
-	</script>
-</head>
-
-
-	<body class="claro">
-		<div id="wrapper">
-			<div id="header">
-				<div id="navigation"></div>
-				<div id="headerInsert">
-					<h1>Input Ouput Sync</h1>
-					<h2>Data Binding Example</h2>
-				</div>
-			</div>
-			<div id="main">
-				<div id="leftNav"></div>
-				<div id="mainContent">
-					<div class="row">
-						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model1);}">Swap Model1</button>
-						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model2);}">Swap Model2</button>
-						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model3);}">Swap Model3</button>
-					</div>
-					<div id="outergroupId"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model1'">
-						<div id="innergroupId"	 data-dojo-type="dojox.mvc.Group">
-							<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
-								<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
-									<label class="cell" for="nameInput${this.index}">Name:</label>
-									<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
-								</div>
-							</div>
-						</div>
-					</div>
-					<div class="row">
-							<span>
-								Model1 Output is ==>  
-							</span>
-							<span id="firstnameOutput10" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[0].First">
-								Name1 is "${this.value}" : 
-							</span>
-							<span id="firstnameOutput11" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[1].First">
-								Name2 is "${this.value}" : 
-							</span>
-							<span id="firstnameOutput12" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[2].First">
-								Name3 is "${this.value}"  
-							</span>
-					</div>
-					<div class="row">
-							<span>
-								Model2 Output is ==>  
-							</span>
-							<span id="firstnameOutput20" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[0].First">
-								Name1 is "${this.value}" : 
-							</span>
-							<span id="firstnameOutput21" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[1].First">
-								Name2 is "${this.value}"  
-							</span>
-					</div>
-					<div class="row">
-							<span>
-								Model3 Output is ==>  
-							</span>
-							<span id="firstnameOutput30" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model3.Results[0].First">
-								Name1 is "${this.value}"  
-							</span>
-					</div>					
-					<br/>Model:
-					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model1.reset();model2.reset();model3.reset();}">Reset all</button>
-				</div>
-			</div>
-		</div>
-	</body>
-
-</html>
diff --git a/dojox/mvc/tests/doh_mvc_search-results-repeat-store.html b/dojox/mvc/tests/doh_mvc_search-results-repeat-store.html
deleted file mode 100755
index c5523a7..0000000
--- a/dojox/mvc/tests/doh_mvc_search-results-repeat-store.html
+++ /dev/null
@@ -1,278 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>MVC DOH Test</title>
-
-	<style>
-		@import "../../../dojo/resources/dojo.css";
-		@import "./css/dijitTests.css";
-		@import "css/app-format.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script src="../../../dojo/dojo.js" type="text/javascript"
-		djConfig="parseOnLoad: false, isDebug: true">
-	</script>
-	<script type="text/javascript" src="./helpers.js"></script>
-
-	<script type="text/javascript" >
-		dojo.require("dojox.mvc");
-		dojo.require("dojox.mvc.Group");
-		dojo.require("dojox.mvc.Repeat");
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dijit.form.Button");
-		dojo.require("dojo.data.ItemFileWriteStore");
-		dojo.require("dojo.store.DataStore");
-		dojo.require("dojo.parser");
-		
-		var results, selectedIndex = 0;
-
-		function setup() {
-			var writeStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests._data", "mvcRepeatData.json")});
-			var modelPromise = dojox.mvc.newStatefulModel({store: new dojo.store.DataStore({store: writeStore})}); 
-			modelPromise.then(function(model){ 
-				results = model;
-				dojo.parser.parse();
-				startTests();
-			});
-		};
-
-		dojo.addOnLoad(setup);
-	</script>
-
-	<script type="text/javascript">
-		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		function startTests(){
-			 // should be able to verify all of the inputs 
-			doh.register("Check initial values and bindings", [
-				{
-					name: "initial",
-					runTest: function(){
-						var name1, bind1, firstInput; 
-						name1 = dijit.byId("nameInput0");
-						if (name1) {
-							bind1 = name1.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Anne",bind1.data,"bind1.data should be set");
-								doh.is("Anne",bind1.value,"bind1.value should be set");
-							}
-						}
-
-						firstInput = dijit.byId("firstInput");
-						if (firstInput) {
-							bind1 = firstInput.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Anne",bind1.data,"bind1.data should be set");
-								doh.is("Anne",bind1.value,"bind1.value should be set");
-							}
-						}
-					}
-				}
-			]);
-
-			doh.register("select Ben", [
-				{
-					name: "testBen",
-					runTest: function(){
-						setDetailsContext(1);
-						var name1, bind1, firstInput; 
-						name1 = dijit.byId("nameInput1");
-						if (name1) {
-							bind1 = name1.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Ben",bind1.data,"bind1.data is wrong");
-								doh.is("Ben",bind1.value,"bind1.value is wrong");
-							}
-						}
-
-						firstInput = dijit.byId("firstInput");
-						if (firstInput) {
-							bind1 = firstInput.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								console.debug("firstInput.value="+firstInput.value);
-								doh.is("Ben",bind1.data,"firstInput bind1.data is wrong");
-								doh.is("Ben",bind1.value,"firstInput bind1.value is wrong");
-							}
-						}
-					}
-				}
-			]);
-
-
-			doh.register("select John and update John to Johnny test valueOf and toString", [
-				{
-					name: "testJohn",
-					runTest: function(){
-						setDetailsContext(9); //select John 
-						var name9, bind9, firstInput; 
-						name9 = dijit.byId("nameInput9");
-						if (name9) {
-							bind9 = name9.get("binding");
-							if (bind9 && bind9.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("John",bind9.data,"bind9.data is wrong");
-								doh.is("John",bind9.value,"bind9.value is wrong");
-								doh.is("John",bind9.valueOf(),"bind9.valueOf() is wrong");
-								doh.is("John",bind9.toString(),"bind9.toString() is wrong");
-							}
-						}
-
-						firstInput = dijit.byId("firstInput");
-						dojo.byId("firstInput").focus();
-						firstInput.set('value',"Johnny");
-						dojo.byId("lastInput").focus();
-						
-						if (firstInput) {
-							bind9 = firstInput.get("binding");
-							if (bind9 && bind9.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Johnny",bind9.value,"firstInput bind9.value is wrong");
-								doh.is("Johnny",firstInput.value,"firstInput firstInput.value is wrong");
-								doh.is("Johnny",bind9.valueOf(),"firstInput bind9.valueOf() is wrong");
-								doh.is("Johnny",bind9.toString(),"firstInput bind9.toString() is wrong");
-							}
-						}
-
-						// Test the value of and toString
-						valueOfTest = new dojox.mvc.StatefulModel({ data: 42 });
-						doh.is(42,valueOfTest.data,"valueOfTest.data is wrong");
-						doh.is(42,valueOfTest.value,"valueOfTest.value is wrong");
-						doh.is(42,+valueOfTest,"valueOfTest.valueOf() is wrong");
-						doh.is("42",'' + valueOfTest,"valueOfTest.toString() is wrong");
-
-						toStringTest = new dojox.mvc.StatefulModel({ data: 'abc' });
-						doh.is('abc',toStringTest.data,"toStringTest.data is wrong");
-						doh.is('abc',toStringTest.value,"toStringTest.value is wrong");
-						doh.is(NaN,+toStringTest,"toStringTest.valueOf() is wrong");
-						doh.is('abc','' + toStringTest,"toStringTest.toString() is wrong")
-
-						
-					}					
-				}
-			]);
-
-			doh.register("test Commit and Reset", [
-				{
-					name: "testC&R",
-					runTest: function(){
-						setDetailsContext(8); //select Irene 
-						var name8, bind8, firstInput, lastInput; 
-						name8 = dijit.byId("nameInput8");
-						if (name8) {
-							bind8 = name8.get("binding");
-							if (bind8 && bind8.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Irene",bind8.data,"bind8.data is wrong");
-								doh.is("Irene",bind8.value,"bind8.value is wrong");
-							}
-						}
-
-						//update Irene to IreneThisUpdateShouldBeSaved and commit
-						firstInput = dijit.byId("firstInput");
-						dojo.byId("firstInput").focus();
-						firstInput.set("value","IreneThisUpdateShouldBeSaved");
-						dojo.byId("lastInput").focus();
-						results.commit();
-
-						lastInput = dijit.byId("lastInput");
-						dojo.byId("lastInput").focus();
-						lastInput.set("value", "IraThisUpdateShouldBeReset");
-						dojo.byId("firstInput").focus();
-						results.reset();
-						
-						if (firstInput) {
-							bind8 = firstInput.get("binding");
-							if (bind8 && bind8.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("IreneThisUpdateShouldBeSaved",bind8.value,"firstInput bind8.value is wrong");
-								doh.is("IreneThisUpdateShouldBeSaved",firstInput.value,"firstInput firstInput.value is wrong");
-								doh.is("Ira",lastInput.value,"lastInput lastInput.value is wrong");
-							}
-						}
-					}
-				}
-			]);
-			
-			doh.run();
-		};
-	</script>
-</head>
-<body class="claro">
-	<h1 class="testTitle">doh_mvc_search-results-repeat-store.html automated tests (non-robot)</h1>
-		<div id="wrapper">
-		<div id="header">
-			<div id="navigation"></div>
-			<div id="headerInsert">
-				<h1>Employee Search</h1>
-				<h2>Master Detail Example - With repeat container.</h2>
-			</div>
-		</div>
-		<div id="main">
-			<div id="leftNav"></div>
-			<div id="mainContent">
-			<!--
-				The repeat container denotes a templated UI that operates over a collection
-				of data records.
-				The UI can be customized for each iteration using properties such as
-				${this.index} for the iteration index.
-			-->
-			<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results'">
-				<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
-					<label class="cell" for="nameInput${this.index}">Name:</label>
-					<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
-					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results'">
-				<div id="detailsBanner">Details for selected index:</div>
-				<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
-					<div class="row">
-						<label class="cell" for="firstInput">First Name:</label>
-						<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="lastInput">Last Name:</label>
-						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="locationInput">Location:</label>
-						<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="officeInput">Office:</label>
-						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="emailInput">Email:</label>
-						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="telInput">Telephone:</label>
-						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="faxInput">Fax:</label>
-						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"/>
-					</div>
-					<div class="row">
-						<div class="spacer"></div>
-						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.commit();}">Commit</button>		 
-						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.reset();}">Reset</button>		   
-					</div>
-				</div>
-			</div>
-		</div>
-		</div>
-	</div>
-	<script type="text/javascript">
-	function setDetailsContext(index) {
-				selectedIndex = index;
-				var widget = dijit.byId("detailsGroup");
-				widget.set("ref", index);
-	}
-	</script>
-</body>
-</html>
diff --git a/dojox/mvc/tests/doh_mvc_search-results-repeat.html b/dojox/mvc/tests/doh_mvc_search-results-repeat.html
deleted file mode 100755
index 69e7ac0..0000000
--- a/dojox/mvc/tests/doh_mvc_search-results-repeat.html
+++ /dev/null
@@ -1,301 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>MVC DOH Test</title>
-
-	<style>
-		@import "../../../dojo/resources/dojo.css";
-		@import "./css/dijitTests.css";
-		@import "css/app-format.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script src="../../../dojo/dojo.js" type="text/javascript"
-		djConfig="isDebug: true">
-	</script>
-	<script type="text/javascript" src="./helpers.js"></script>
-
-	<script type="text/javascript" >
-		dojo.require("dojox.mvc");
-		dojo.require("dojox.mvc.Group");
-		dojo.require("dojox.mvc.Repeat");
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dijit.form.Button");
-		dojo.require("dojo.parser");
-
-		// Raw records for the master detail
-		var search_results_init =
-		{
-		  "Query" : "Engineers",
-		  "Results" : [
-			  {
-				  "First"	: "Anne",
-				  "Last"	: "Ackerman",
-				  "Location": "NY",
-				  "Office"	: "1S76",
-				  "Email"	: "a.a at test.com",
-				  "Tel"		: "123-764-8237",
-				  "Fax"		: "123-764-8228"
-			  },
-			  {
-				  "First"	: "Ben",
-				  "Last"	: "Beckham",
-				  "Location": "NY",
-				  "Office"	: "5N47",
-				  "Email"	: "b.b at test.com",
-				  "Tel"		: "123-764-8599",
-				  "Fax"		: "123-764-8600"
-			  },
-			  {
-				  "First"	: "Chad",
-				  "Last"	: "Chapman",
-				  "Location": "CA",
-				  "Office"	: "1278",
-				  "Email"	: "c.c at test.com",
-				  "Tel"		: "408-764-8237",
-				  "Fax"		: "408-764-8228"
-			  },
-			  {
-				  "First"	: "David",
-				  "Last"	: "Durham",
-				  "Location": "NJ",
-				  "Office"	: "C12",
-				  "Email"	: "d.d at test.com",
-				  "Tel"		: "514-764-8237",
-				  "Fax"		: "514-764-8228"
-			  },
-			  {
-				  "First"	: "Emma",
-				  "Last"	: "Eklof",
-				  "Location": "NY",
-				  "Office"	: "4N76",
-				  "Email"	: "e.e at test.com",
-				  "Tel"		: "123-764-1234",
-				  "Fax"		: "123-764-4321"
-			  },
-			  {
-				  "First"	: "Fred",
-				  "Last"	: "Fisher",
-				  "Location": "NJ",
-				  "Office"	: "V89",
-				  "Email"	: "f.f at test.com",
-				  "Tel"		: "514-764-8567",
-				  "Fax"		: "514-764-8000"
-			  },
-			  {
-				  "First"	: "George",
-				  "Last"	: "Garnett",
-				  "Location": "NY",
-				  "Office"	: "7S11",
-				  "Email"	: "gig at test.com",
-				  "Tel"		: "123-999-8599",
-				  "Fax"		: "123-999-8600"
-			  },
-			  {
-				  "First"	: "Hunter",
-				  "Last"	: "Huffman",
-				  "Location": "CA",
-				  "Office"	: "6532",
-				  "Email"	: "h.h at test.com",
-				  "Tel"		: "408-874-8237",
-				  "Fax"		: "408-874-8228"
-			  },
-			  {
-				  "First"	: "Irene",
-				  "Last"	: "Ira",
-				  "Location": "NJ",
-				  "Office"	: "F09",
-				  "Email"	: "i.i at test.com",
-				  "Tel"		: "514-764-6532",
-				  "Fax"		: "514-764-7300"
-			  },
-			  {
-				  "First"	: "John",
-				  "Last"	: "Jacklin",
-				  "Location": "CA",
-				  "Office"	: "6701",
-				  "Email"	: "j.j at test.com",
-				  "Tel"		: "408-764-1234",
-				  "Fax"		: "408-764-4321"
-			  }
-		  ]
-	  };
-
-	  // The dojox.mvc.StatefulModel class creates a data model instance
-	  // where each leaf within the data model is decorated with dojo.Stateful
-	  // properties that widgets can bind to and watch for their changes.
-	  var searchRecords = dojox.mvc.newStatefulModel({ data : search_results_init });
-	</script>
-
-	<script type="text/javascript">
-		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-		dojo.addOnLoad(function(){
-
-			doh.register("parse", function(){
-				dojo.parser.parse();
-			});
-
-			// should be able to verify all of the inputs 
-			doh.register("Check initial values and bindings", [
-				{
-					name: "initial",
-					runTest: function(){
-						var name1, bind1, firstInput; 
-						name1 = dijit.byId("nameInput0");
-						if (name1) {
-							bind1 = name1.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Anne",bind1.data,"bind1.data should be set");
-								doh.is("Anne",bind1.value,"bind1.value should be set");
-							}
-						}
-
-						firstInput = dijit.byId("firstInput");
-						if (firstInput) {
-							bind1 = firstInput.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Anne",bind1.data,"bind1.data should be set");
-								doh.is("Anne",bind1.value,"bind1.value should be set");
-							}
-						}
-					}
-				}
-			]);
-
-			doh.register("select Ben", [
-				{
-					name: "testBen",
-					runTest: function(){
-						setDetailsContext(1);
-						var name1, bind1, firstInput; 
-						name1 = dijit.byId("nameInput1");
-						if (name1) {
-							bind1 = name1.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								doh.is("Ben",bind1.data,"bind1.data is wrong");
-								doh.is("Ben",bind1.value,"bind1.value is wrong");
-							}
-						}
-
-						firstInput = dijit.byId("firstInput");
-						if (firstInput) {
-							bind1 = firstInput.get("binding");
-							if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-								console.debug("firstInput.value="+firstInput.value);
-								doh.is("Ben",bind1.data,"firstInput bind1.data is wrong");
-								doh.is("Ben",bind1.value,"firstInput bind1.value is wrong");
-							}
-						}
-					}					
-				}
-			]);
-
-			doh.run();
-
-		});
-	</script>
-</head>
-<body class="claro">
-	<h1 class="testTitle">doh_mvc_search-results-repeat.html automated tests (non-robot)</h1>
-		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>Employee Search</h1>
-			<h2>Master Detail Example - With repeat container.</h2>
-		  </div>
-		</div>
-		<div id="main">
-		 <div id="leftNav">
-		 </div>
-		 <div id="mainContent">
-		 <!--
-			 The group container denotes some logical grouping of widgets and also serves
-			 to establish a parent data binding context for its children.
-			 The ref attribute for the outermost container obtains the binding from the
-			 "page scope" itself.
-		 -->
-		 <div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'searchRecords'">
-			<div class="row">
-				<label class="cell" for="queryInput">Search for:</label>
-				<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Query'"/>
-				<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setSearchBanner();}">Search</button>
-			</div>
-			<div class="spacer"></div>
-
-			<div id="searchBanner">Search Results for term: Engineers</div>
-
-			<!--
-				The repeat container denotes a templated UI that operates over a collection
-				of data records.
-				The UI can be customized for each iteration using properties such as
-				${this.index} for the iteration index.
-			-->
-			<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
-				<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
-					<label class="cell" for="nameInput${this.index}">Name:</label>
-					<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
-					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
-				</div>
-			</div>
-			<div class="spacer"></div>
-
-			<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Results'">
-				<div id="detailsBanner">Details for result index: 0</div>
-
-				<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
-					<div class="row">
-						<label class="cell" for="firstInput">First Name:</label>
-						<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="lastInput">Last Name:</label>
-						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="locationInput">Location:</label>
-						<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="officeInput">Office:</label>
-						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="emailInput">Email:</label>
-						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="telInput">Telephone:</label>
-						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="faxInput">Fax:</label>
-						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"/>
-					</div>
-				</div>
-			</div>
-		</div>
-		</div>
-	</div>
-	<script type="text/javascript">
-	function setDetailsContext(index) {
-		var widget = dijit.byId("detailsGroup");
-		widget.set("ref", index);
-		var detailsBanner = dojo.byId("detailsBanner");
-		detailsBanner.innerHTML = "Details for result index: " + index;
-	}
-	function setSearchBanner() {
-		var searchBanner = dojo.byId("searchBanner");
-		searchBanner.innerHTML = "Search Results for term: " + searchRecords.Query.get("value");
-	}
-	</script>
-</body>
-</html>
diff --git a/dojox/mvc/tests/doh_mvc_shipto-billto-hierarchical.html b/dojox/mvc/tests/doh_mvc_shipto-billto-hierarchical.html
deleted file mode 100644
index 9e4ccdb..0000000
--- a/dojox/mvc/tests/doh_mvc_shipto-billto-hierarchical.html
+++ /dev/null
@@ -1,377 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>MVC DOH Test</title>
-	<style>
-		@import "../../../dojo/resources/dojo.css";
-		@import "./css/dijitTests.css";
-		@import "css/app-format.css";
-	</style>
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-	<script src="../../../dojo/dojo.js" type="text/javascript" djConfig="isDebug: true"></script>
-	<script type="text/javascript" src="./helpers.js"></script>
-	<script type="text/javascript">
-		dojo.require("dojox.mvc");
-		dojo.require("dojox.mvc.Group");
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dijit.form.Button");
-		dojo.require("dojo.parser");
-
-		  // Initial data with a noticeable hierarchy
-		  var order = {
-			  "Serial" : "360324",
-			  "First"  : "John",
-			  "Last"   : "Doe",
-			  "Email"  : "jdoe at example.com",
-			  "ShipTo" : {
-				  "Type" : "Home",
-				  "Address" : {
-					  "Street" : "123 Valley Rd",
-					  "City"   : "Katonah",
-					  "State"  : "NY",
-					  "Zip"	   : "10536"
-				  },
-				  "Telephone" : {
-					  "AreaCode" : "123",
-					  "Landline" : {
-						  "Number"	  : "456-7890",
-						  "Extension" : "42"
-					  },
-					  "Cell" : {
-						  "Number"	  : "765-4321"
-					  }
-				  }
-			  },
-			  "BillTo" : {
-				  "Type" : "Office",
-				  "Address" : {
-					  "Street" : "17 Skyline Dr",
-					  "City"   : "Hawthorne",
-					  "State"  : "NY",
-					  "Zip"	   : "10532"
-				  },
-				  "Telephone" : {
-					  "AreaCode" : "098",
-					  "Landline" : {
-						  "Number"	  : "765-4321",
-						  "Extension" : "24"
-					  },
-					  "Cell" : {
-						  "Number"	  : "123-4567"
-					  }
-				  }
-			  }
-		  };
-
-		  // The dojox.mvc.StatefulModel class creates a data model instance
-		  // where each leaf within the data model is decorated with dojo.Stateful
-		  // properties that widgets can bind to and watch for their changes.
-		  var model = dojox.mvc.newStatefulModel({ data : order });
-		  var selectedAddr = dojox.mvc.newStatefulModel({ data : "ShipTo" });
-	</script>
-
-	<script type="text/javascript">
-		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
-
-		dojo.addOnLoad(function() {
-
-		doh.register("parse", function() {
-			dojo.parser.parse();
-		});
-
-		// should be able to verify all of the inputs 
-		doh.register("check initial values and bindings", [{
-			name : "initial",
-			runTest : function() {
-				var serial1, bind1, addr1;
-				//test serialInput
-				serial1 = dijit.byId("serialInput");
-				if (serial1) {
-					bind1 = serial1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("360324", bind1.data,"bind1.data should be set");
-						doh.is("360324", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test addrLabel
-				addr1 = dijit.byId("addrLabel");
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("ShipTo", bind1.data,"bind1.data should be set");
-						doh.is("ShipTo", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test streetInput
-				addr1 = dijit.byId("streetInput");
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("123 Valley Rd", bind1.data,"bind1.data should be set");
-						doh.is("123 Valley Rd", bind1.value,"bind1.value should be set");
-					}
-				}
-			}
-		}]);
-
-		doh.register("check BillTo", [{
-			name : "testBillTo",
-			runTest : function() {
-				setRef('addrGroup', 'model.BillTo');
-				
-				var serial1, bind1, addr1;
-				//test serialInput
-				serial1 = dijit.byId("serialInput");
-				if (serial1) {
-					bind1 = serial1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("360324", bind1.data,"bind1.data should be set");
-						doh.is("360324", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test addrLabel
-				addr1 = dijit.byId("addrLabel");
-
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("ShipTo", bind1.data,"bind1.data should be set");
-						doh.is("BillTo", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test streetInput
-				addr1 = dijit.byId("streetInput");
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("17 Skyline Dr", bind1.data,"bind1.data should be set");
-						doh.is("17 Skyline Dr", bind1.value,"bind1.value should be set");
-					}
-				}
-			}
-		}]);
-
-		doh.register("check ShipTo", [{
-			name : "testShipTo",
-			runTest : function() {
-				setRef('addrGroup', 'model.ShipTo');
-				
-				var serial1, bind1, addr1;
-				//test serialInput
-				serial1 = dijit.byId("serialInput");
-				if (serial1) {
-					bind1 = serial1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("360324", bind1.data,"bind1.data should be set");
-						doh.is("360324", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test addrLabel
-				addr1 = dijit.byId("addrLabel");
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("ShipTo", bind1.data,"bind1.data should be set");
-						doh.is("ShipTo", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test streetInput
-				addr1 = dijit.byId("streetInput");
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("123 Valley Rd", bind1.data,"bind1.data should be set");
-						doh.is("123 Valley Rd", bind1.value,"bind1.value should be set");
-					}
-				}
-			}
-		}]);
-
-		doh.register("change ShipTo", [{
-			name : "testShipTo",
-			runTest : function() {
-				setRef('addrGroup', 'model.ShipTo');
-				//set streetInput
-				addr1 = dijit.byId("streetInput");
-				if (addr1) {
-					addr1.set("value","456 Mountain Rd");
-				}
-				setRef('addrGroup', 'model.BillTo');
-				setRef('addrGroup', 'model.ShipTo');
-				
-				var serial1, bind1, addr1;
-				//test serialInput
-				serial1 = dijit.byId("serialInput");
-				if (serial1) {
-					bind1 = serial1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("360324", bind1.data,"bind1.data should be set");
-						doh.is("360324", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test addrLabel
-				addr1 = dijit.byId("addrLabel");
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("ShipTo", bind1.data,"bind1.data should be set");
-						doh.is("ShipTo", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test streetInput
-				var addr1s = dijit.byId("streetInput");
-				if (addr1s) {
-					bind1s = addr1s.get("binding");
-					if (bind1s && bind1s.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("456 Mountain Rd", bind1s.value,"bind1s.value should be set");
-						bind1s.commit();
-						doh.is("456 Mountain Rd", bind1s.data,"bind1s.value should be set after commit");
-					}
-				}
-				//test streetInput
-				var addr1c = dijit.byId("cityInput");
-				if (addr1c) {
-					bind1c = addr1c.get("binding");
-					if (bind1c && bind1c.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("Katonah", bind1c.value,"bind1c.value should be set");
-						doh.is("Katonah", bind1c.data,"bind1c.data should be set");
-					}
-				}
-			}
-		}]);
-
-		doh.run();
-
-		});
-	</script>
-</head>
-
-
-	<body class="claro">
-		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>Order Shipping Details</h1>
-			<h2>Data Binding Example - Hierarchical data.</h2>
-		  </div>
-		</div>
-		<div id="main">
-		  <div id="leftNav">
-		  </div>
-		  <div id="mainContent">
-		<!--
-			The group container denotes some logical grouping of widgets and also serves
-			to establish a parent data binding context for its children.
-			The ref attribute for the outermost container obtains the binding from the
-			"page scope" itself.
-		-->
-		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model'">
-			<div class="row">
-				<label class="cell" for="serialInput">Order #:</label>
-				<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Serial'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="lastnameInput">Last name:</label>
-				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Last'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="emailInput">Email:</label>
-				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Email'"/>
-			</div>
-		</div>
-		<br/>
-		Choose:
-		<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.ShipTo');}">Ship To</button>
-		<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.BillTo');}">Bill To</button>
-		<br/>
-		<div class="row">
-			<label class="cell" for="addrLabel">Selected Address:</label>
-			<input class="cell" data-dojo-type="dijit.form.TextBox" id="addrLabel"
-								data-dojo-props="ref: 'selectedAddr'"/>
-		</div>
-		<br/>
-		<!--
-			For convenience, the widget hierarchy matches the data hierarchy
-			(see JSON literal above).
-			In this implementation, the child ref attributes are simple property names
-			of the parent binding context.
-			The ref attribute may support more advanced constructs, such as queries
-			over the parent widget's or other application specified binding context.
-		-->
-		  <div id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model.ShipTo'">
-			<div class="row">
-			  <label class="cell" for="typeInput">Type:</label>
-			  <input class="cell" id="typeInput" data-dojo-type="dijit.form.TextBox"
-								  data-dojo-props="ref: 'Type'"/>
-			</div>
-			<div id="postalGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Address'">
-			  <div class="row">
-				  <label class="cell" for="streetInput">Street:</label>
-				  <input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'Street'"/>
-			  </div>
-			  <div class="row">
-				  <label class="cell" for="cityInput">City:</label>
-				  <input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'City'"/>
-			  </div>
-			  <div class="row">
-				  <label class="cell" for="stateInput">State:</label>
-				  <input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'State'"/>
-			  </div>
-			  <div class="row">
-				  <label class="cell" for="zipInput">Zipcode:</label>
-				  <input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'Zip'"/>
-			  </div>
-			</div>
-			<div id="telGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Telephone'">
-			  <div class="row">
-				  <label class="cell" for="areacodeInput">Area code:</label>
-				  <input class="cell" id="areacodeInput" data-dojo-type="dijit.form.TextBox"
-										 data-dojo-props="ref: 'AreaCode'"/>
-			  </div>
-			  <div id="llGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Landline'">
-				<div class="row">
-				  <label class="cell" for="numberInput">Landline Number:</label>
-				  <input class="cell" id="numberInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'Number'"/>
-				</div>
-				<div class="row">
-				  <label class="cell" for="extInput">Extension:</label>
-				  <input class="cell" id="extInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'Extension'"/>
-				</div>
-			  </div>
-			  <div class="row" id="cellGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Cell'">
-				  <label class="cell" for="cellInput">Cell Number:</label>
-				  <input class="cell" id="cellInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'Number'"/>
-			  </div>
-			</div>
-			<br/>
-			Model:
-			<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
-		</div></div></div>
-		<script type="text/javascript">
-			function setRef(id, addrRef) {
-				var widget = dijit.byId(id);
-				widget.set("ref", addrRef);
-				if(addrRef == "model.ShipTo")
-					selectedAddr.set("value", "ShipTo");
-				else
-					selectedAddr.set("value", "BillTo");
-			}
-		</script>
-	</body>
-
-</html>
diff --git a/dojox/mvc/tests/doh_mvc_shipto-billto-simple.html b/dojox/mvc/tests/doh_mvc_shipto-billto-simple.html
deleted file mode 100755
index 7c4408a..0000000
--- a/dojox/mvc/tests/doh_mvc_shipto-billto-simple.html
+++ /dev/null
@@ -1,215 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>MVC DOH Test</title>
-	<style>
-		@import "../../../dojo/resources/dojo.css";
-		@import "./css/dijitTests.css";
-		@import "css/app-format.css";
-	</style>
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-	<script src="../../../dojo/dojo.js" type="text/javascript" djConfig="isDebug: true"></script>
-	<script type="text/javascript" src="./helpers.js"></script>
-	<script type="text/javascript">
-		dojo.require("dojox.mvc");
-		dojo.require("dojox.mvc.Group");
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dijit.form.Button");
-		dojo.require("dojo.parser");
-
-		// Initial data
-		var master_init = {
-			"Serial" : "360324",
-			"First" : "John",
-			"Last" : "Doe",
-			"Email" : "jdoe at example.com",
-			"ShipTo" : {
-				"Street" : "123 Valley Rd",
-				"City" : "Katonah",
-				"State" : "NY",
-				"Zip" : "10536"
-			},
-			"BillTo" : {
-				"Street" : "17 Skyline Dr",
-				"City" : "Hawthorne",
-				"State" : "NY",
-				"Zip" : "10532"
-			}
-		};
-
-		// The dojox.mvc.StatefulModel class creates a data model instance
-		// where each leaf within the data model is decorated with dojo.Stateful
-		// properties that widgets can bind to and watch for their changes.
-		var masterRecord = dojox.mvc.newStatefulModel({ data : master_init });
-		var selectedAddr = dojox.mvc.newStatefulModel({ data : "ShipTo" });
-	</script>
-
-	<script type="text/javascript">
-		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
-
-		dojo.addOnLoad(function() {
-
-		doh.register("parse", function() {
-			dojo.parser.parse();
-		});
-
-		// should be able to verify all of the inputs 
-		doh.register("check initial values and bindings", [{
-			name : "initial",
-			runTest : function() {
-				var serial1, bind1, addr1;
-				//test serialInput
-				serial1 = dijit.byId("serialInput");
-				if (serial1) {
-					bind1 = serial1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("360324", bind1.data,"bind1.data should be set");
-						doh.is("360324", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test addrLabel
-				addr1 = dijit.byId("addrLabel");
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("ShipTo", bind1.data,"bind1.data should be set");
-						doh.is("ShipTo", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test streetInput
-				addr1 = dijit.byId("streetInput");
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("123 Valley Rd", bind1.data,"bind1.data should be set");
-						doh.is("123 Valley Rd", bind1.value,"bind1.value should be set");
-					}
-				}
-			}
-		}]);
-
-		doh.register("check BillTo", [{
-			name : "testBillTo",
-			runTest : function() {
-				setRef("addrGroup", masterRecord.BillTo);
-				var serial1, bind1, addr1;
-				//test serialInput
-				serial1 = dijit.byId("serialInput");
-				if (serial1) {
-					bind1 = serial1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("360324", bind1.data,"bind1.data should be set");
-						doh.is("360324", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test addrLabel
-				addr1 = dijit.byId("addrLabel");
-
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("ShipTo", bind1.data,"bind1.data should be set");
-						doh.is("BillTo", bind1.value,"bind1.value should be set");
-					}
-				}
-				//test streetInput
-				addr1 = dijit.byId("streetInput");
-				if (addr1) {
-					bind1 = addr1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("17 Skyline Dr", bind1.data,"bind1.data should be set");
-						doh.is("17 Skyline Dr", bind1.value,"bind1.value should be set");
-					}
-				}
-			}
-		}]);
-
-		doh.run();
-
-		});
-	</script>
-</head>
-
-
-<body class="claro">
-	<h1 class="testTitle">doh_mvc__shipto-billto-simple.html automated tests (non-robot)</h1>
-	<div id="wrapper">
-		<div id="header">
-			<div id="navigation"></div>
-			<div id="headerInsert">
-				<h1>Order Shipping Details</h1>
-				<h2>Data Binding Example - Group Container.</h2>
-			</div>
-		</div>
-		<div id="main">
-			<div id="leftNav"></div>
-			<div id="mainContent"><!--
-			The group container denotes some logical grouping of widgets and also serves
-			to establish a parent data binding context for its children.
-			The ref attribute for the outermost container obtains the binding from the
-			"page scope" itself.
-			-->
-			<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'masterRecord'">
-				<div class="row"><label class="cell" for="serialInput">Serial:</label>
-					<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Serial'"/>
-				</div>
-				<div class="row"><label class="cell" for="lastnameInput">Last:</label>
-					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
-				</div>
-				<div class="row"><label class="cell" for="emailInput">Email:</label>
-					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
-				</div>
-			</div>
-			<br />
-			Choose:
-			<button id="shipto1" type="button" data-dojo-type="dijit.form.Button"
-				data-dojo-props="onClick: function(){setRef('addrGroup', masterRecord.ShipTo);}">Ship To</button>
-			<button id="billto1" type="button" data-dojo-type="dijit.form.Button"
-				data-dojo-props="onClick: function(){setRef('addrGroup', masterRecord.BillTo);}">Bill To</button>
-			<br />
-			<div class="row"><label class="cell" for="addrLabel">Selected
-			Address:</label> <input class="cell" data-dojo-type="dijit.form.TextBox"
-				id="addrLabel" data-dojo-props="ref: 'selectedAddr'"/></div>
-			<br />
-			<!--
-				For convenience, the widget hierarchy matches the data hierarchy
-				(see JSON literal above).
-				In this implementation, the child ref attributes are simple property names
-				of the parent binding context.
-				The ref attribute may support more advanced constructs, such as queries
-				over the parent widget's or other application specified binding context.
-			-->
-			<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group"
-				data-dojo-props="ref: 'masterRecord.ShipTo'">
-				<div class="row"><label class="cell" for="streetInput">Street:</label>
-					<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Street'"/>
-				</div>
-				<div class="row"><label class="cell" for="cityInput">City:</label>
-					<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'City'"/>
-				</div>
-				<div class="row"><label class="cell" for="stateInput">State:</label>
-					<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'State'"/>
-				</div>
-				<div class="row"><label class="cell" for="zipInput">Zipcode:</label>
-					<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Zip'"/>
-				</div>
-			</div>
-		</div>
-		</div>
-	</div>
-	<script type="text/javascript">
-	function setRef(id, addrRef){
-		var widget = dijit.byId(id);
-		widget.set("ref", addrRef);
-		if(addrRef == "masterRecord.ShipTo"){
-			selectedAddr.set("value", "ShipTo");
-		}else{
-			selectedAddr.set("value", "BillTo");
-		}
-	}
-	</script>
-</body>
-</html>
diff --git a/dojox/mvc/tests/doh_mvc_template_repeat_exprchar.html b/dojox/mvc/tests/doh_mvc_template_repeat_exprchar.html
deleted file mode 100644
index 09c1a67..0000000
--- a/dojox/mvc/tests/doh_mvc_template_repeat_exprchar.html
+++ /dev/null
@@ -1,236 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>MVC DOH Test</title>
-
-	<style>
-		@import "../../../dojo/resources/dojo.css";
-		@import "./css/dijitTests.css";
-		@import "css/app-format.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script src="../../../dojo/dojo.js" type="text/javascript"
-		djConfig="isDebug: true">
-	</script>
-	<script type="text/javascript" src="./helpers.js"></script>
-
-	<script type="text/javascript">
-            dojo.require("dojox.mvc");
-            dojo.require("dojox.mvc.Group");
-            dojo.require("dojox.mvc.Repeat");
-            dojo.require("dijit.form.TextBox");
-            dojo.require("dijit.form.Button");
-            dojo.require("dojo.parser");
-            dojo.require("dojox.mvc.tests.test_templatedWidget.myMvcTemplated");
-            
-            // Raw records for the master detail
-            var search_results_init = {
-                "Query": "Engineers",
-                "Results": [{
-                    "First": "Anne",
-                    "Last": "Ackerman",
-                    "Location": "NY",
-                    "Office": "1S76",
-                    "Email": "a.a at test.com",
-                    "Tel": "123-764-8237",
-                    "Fax": "123-764-8228"
-                }, {
-                    "First": "Ben",
-                    "Last": "Beckham",
-                    "Location": "NY",
-                    "Office": "5N47",
-                    "Email": "b.b at test.com",
-                    "Tel": "123-764-8599",
-                    "Fax": "123-764-8600"
-                }, {
-                    "First": "John",
-                    "Last": "Jacklin",
-                    "Location": "CA",
-                    "Office": "6701",
-                    "Email": "j.j at test.com",
-                    "Tel": "408-764-1234",
-                    "Fax": "408-764-4321"
-                }]
-            };
-            
-            // The dojox.mvc.StatefulModel class creates a data model instance
-            // where each leaf within the data model is decorated with dojo.Stateful
-            // properties that widgets can bind to and watch for their changes.
-            var searchRecords = dojox.mvc.newStatefulModel({
-                data: search_results_init
-            });
-            
-            dojo.ready(function(){
-                dojo.parser.parse();
-            });
-	</script>
-
-	<script type="text/javascript">
-		dojo.require('doh.runner');
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.parser"); // scan page for widgets and instantiate them
-
-		dojo.addOnLoad(function() {
-
-		doh.register("parse", function() {
-			dojo.parser.parse();
-		});
-
-		// should be able to verify all of the inputs 
-		doh.register("check initial values for Input0s", [{
-			name : "initial",
-			runTest : function() {
-				var name1, bind1;
-				//test nameInput0 
-				name1 = dijit.byId("nameInput0");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("Anne",bind1.data,"bind1.data should be set");
-						doh.is("Anne",bind1.value,"bind1.value should be set");
-					}
-				}
-				//test anameInput0 
-				name1 = dijit.byId("anameInput0");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("Anne",bind1.data,"bind1.data should be set");
-						doh.is("Anne",bind1.value,"bind1.value should be set");
-					}
-				}
-				//test bnameInput0 
-				name1 = dijit.byId("bnameInput0");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("Anne",bind1.data,"bind1.data should be set");
-						doh.is("Anne",bind1.value,"bind1.value should be set");
-					}
-				}
-				//test 9nameInput0 
-				name1 = dijit.byId("9nameInput0");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("Anne",bind1.data,"bind1.data should be set");
-						doh.is("Anne",bind1.value,"bind1.value should be set");
-					}
-				}
-			}
-		}]);
-
-		doh.register("check initial values for Input1s", [{
-			name : "initial",
-			runTest : function() {
-				var name1, bind1;
-				//test nameInput1 
-				name1 = dijit.byId("nameInput1");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("Ben",bind1.data,"bind1.data should be set");
-						doh.is("Ben",bind1.value,"bind1.value should be set");
-					}
-				}
-				//test anameInput1 
-				name1 = dijit.byId("anameInput1");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("Ben",bind1.data,"bind1.data should be set");
-						doh.is("Ben",bind1.value,"bind1.value should be set");
-					}
-				}
-				//test bnameInput1 
-				name1 = dijit.byId("bnameInput1");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("Ben",bind1.data,"bind1.data should be set");
-						doh.is("Ben",bind1.value,"bind1.value should be set");
-					}
-				}
-				//test 9nameInput1 
-				name1 = dijit.byId("9nameInput1");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("Ben",bind1.data,"bind1.data should be set");
-						doh.is("Ben",bind1.value,"bind1.value should be set");
-					}
-				}
-			}
-		}]);
-
-		doh.register("check initial values for Input2s", [{
-			name : "initial",
-			runTest : function() {
-				var name1, bind1;
-				//test nameInput1 
-				name1 = dijit.byId("nameInput2");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("John",bind1.data,"bind1.data should be set");
-						doh.is("John",bind1.value,"bind1.value should be set");
-					}
-				}
-				//test anameInput2 
-				name1 = dijit.byId("anameInput2");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("John",bind1.data,"bind1.data should be set");
-						doh.is("John",bind1.value,"bind1.value should be set");
-					}
-				}
-				//test bnameInput2 
-				name1 = dijit.byId("bnameInput2");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("John",bind1.data,"bind1.data should be set");
-						doh.is("John",bind1.value,"bind1.value should be set");
-					}
-				}
-				//test 9nameInput2 
-				name1 = dijit.byId("9nameInput2");
-				if (name1) {
-					bind1 = name1.get("binding");
-					if (bind1 && bind1.isInstanceOf(dojox.mvc.StatefulModel)) {
-						doh.is("John",bind1.data,"bind1.data should be set");
-						doh.is("John",bind1.value,"bind1.value should be set");
-					}
-				}
-			}
-		}]);
-
-		doh.run();
-
-		});
-	</script>
-</head>
-
-	<body class="claro" style="background-image: url(../images/master_detail.png)">
-		<div id="wrapper">
-			<div id="main">
-				<div id="leftNav"></div>
-				<div id="mainContent">
-					<div>
-						Test exprchar. Widget template test uses exprchar of # and others for template:#{this.index} etc. 
-					</div>
-					<br/>
-					<div id="container2"  data-dojo-type="dojox.mvc.tests.test_templatedWidget.myMvcTemplated">    
-					</div>
-				</div>
-			</div>
-		</div>
-	</body>
-
-</html>
diff --git a/dojox/mvc/tests/doh_mvc_validation-test-simple.html b/dojox/mvc/tests/doh_mvc_validation-test-simple.html
deleted file mode 100644
index f1e9231..0000000
--- a/dojox/mvc/tests/doh_mvc_validation-test-simple.html
+++ /dev/null
@@ -1,133 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>DOH Validation Relevant Test</title>
-		<link rel='stylesheet' href='../../../dojo/resources/dojo.css'>
-		<link rel='stylesheet' href='../../../dijit/themes/dijit.css'>
-		<link rel='stylesheet' href='../../../dijit/themes/claro/claro.css'>
-<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
-<script type="text/javascript">
-			var model;
-			require([
-					'dojo/_base/declare',
-					'dojo/parser',
-					'dojox/mvc',
-					'dojox/mvc/StatefulModel',
-					'dojo/_base/lang',
-					'dijit/form/Button'
-				], function (declare, parser, mvc, StatefulModel, lang) {
-					var Model = declare([StatefulModel], {
-						constructor: function (args) {
-							mvc.bindInputs([this.num1, this.num2], lang.hitch(this, '_checkNums'));
-						},
-
-						_checkNums: function () {
-							var num1Val = this.num1.get('value'),
-								num2Val = this.num2.get('value');
-
-							this.num1.set({
-								relevant: num1Val !== num2Val,
-								valid: num1Val <= num2Val
-							});
-
-							this.num2.set({
-								relevant: num1Val !== num2Val,
-								valid: num1Val <= num2Val
-							});
-						}
-					});
-
-					model = new Model({
-						data: {
-							num1: 10,
-							num2: 20
-						}
-					});
-				require([
-					'doh/runner', 'dijit/dijit'
-				], function(){
-				require([
-					'dojo/domReady!'
-					], function(){
-						doh.register("parse", function() {
-							dojo.parser.parse();
-						});
-						// should be able to verify all of the inputs
-						doh.register("check initial values and bindings", [{
-							name : "initial",
-							runTest : function() {
-								num1 = dijit.byId("num1");
-								num2 = dijit.byId("num2");
-								doh.is("10", num1.get('value'),"num1 should be 10");
-								doh.is("20", num2.get('value'),"num2 should be 20");
-								doh.t(num1.isValid(),"num1.isValid() should be true");
-								doh.t(num2.isValid(),"num2.isValid() should be true");
-								doh.f(num2.disabled,"num2.disabled should be false");
-								doh.f(num1.disabled,"num1.disabled should be false");
-							}
-						}]);
-
-						doh.register("update num1 invalid", [{
-							name : "Update-Num1-invalid",
-							runTest : function() {
-								num1 = dijit.byId("num1");
-								num2 = dijit.byId("num2");
-								num1.set("value","30");
-								doh.is("30", num1.get('value'),"num1 should be 30");
-								doh.f(num1.disabled,"num1.disabled should be false");
-								doh.is("20", num2.get('value'),"num2 should be 20");
-								doh.f(num2.isValid(),"num2.isValid() should be false");
-								doh.f(num2.disabled,"num2.disabled should be false");
-								doh.t(dojo.hasClass('widget_num1','dijitNumberTextBoxError'),"num1 should have the dijitNumberTextBoxError class");
-								doh.t(dojo.hasClass('widget_num2','dijitNumberTextBoxError'),"num2 should have the dijitNumberTextBoxError class");
-							}
-						}]);
-
-						doh.register("update num1 disabled2", [{
-							name : "Update-Num1-disabled2",
-							runTest : function() {
-								num1 = dijit.byId("num1");
-								num2 = dijit.byId("num2");
-								num1.set("value","21");
-								num2.set("value","21");
-								doh.is("21", num1.get('value'),"num1 should be 30");
-								doh.is("21", num2.get('value'),"num2 should be 20");
-								doh.t(dijit.byId("num2").disabled,"num2.disabled should be true");
-								doh.t(dijit.byId("num1").disabled,"num1.disabled should be true");
-
-								model.reset();
-							}
-						}]);
-
-						doh.run();
-
-					});
-				});
-		});
-
-		</script>
-</head>
-	<body class="claro">
-		<form method="post">
-			<div>
-				<label for="num1">Number 1</label>
-				<input data-dojo-props="ref:model.num1" data-dojo-type="dijit.form.NumberTextBox" id="num1">
-			</div>
-			<div>
-				<label for="num2">Number 2</label>
-				<input data-dojo-props="ref:model.num2" data-dojo-type="dijit.form.NumberTextBox" id="num2">
-			</div>
-		</form>
-		<br/>Model:
-		<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){doReset()}">Reset</button>
-
-		<script type="text/javascript">
-			function doReset() {
-				model.reset();
-			}
-		</script>
-
-	</body>
-
-</html>
diff --git a/dojox/mvc/tests/images/directory_45.png b/dojox/mvc/tests/images/directory_45.png
new file mode 100755
index 0000000..dc3941f
Binary files /dev/null and b/dojox/mvc/tests/images/directory_45.png differ
diff --git a/dojox/mvc/tests/images/settings.png b/dojox/mvc/tests/images/settings.png
new file mode 100644
index 0000000..5de8548
Binary files /dev/null and b/dojox/mvc/tests/images/settings.png differ
diff --git a/dojox/mvc/tests/mobile/demo/MobileDemoContactController.js b/dojox/mvc/tests/mobile/demo/MobileDemoContactController.js
new file mode 100644
index 0000000..47f3286
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/MobileDemoContactController.js
@@ -0,0 +1,12 @@
+define([
+	"dojo/_base/declare",
+	"dojox/mvc/EditModelRefController",
+	"dojox/mvc/ListController"
+], function(declare, EditModelRefController, ListController){
+	// module:
+	//		dojox/mvc/tests/mobile/demo/ContactController
+	// summary:
+	//		The controller for contact info for this demo.
+
+	return declare([EditModelRefController, ListController]);
+});
diff --git a/dojox/mvc/tests/mobile/demo/MobileDemoContactListController.js b/dojox/mvc/tests/mobile/demo/MobileDemoContactListController.js
new file mode 100644
index 0000000..bed338c
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/MobileDemoContactListController.js
@@ -0,0 +1,71 @@
+define([
+	"dojo/_base/declare",
+	"dijit/registry",
+	"dojox/mvc/getStateful",
+	"dojox/mvc/ListController",
+	"dojox/mvc/StoreRefController"
+], function(declare, registry, getStateful, ListController, StoreRefController){
+	// module:
+	//		dojox/mvc/tests/mobile/demo/MobileDemoContactListController
+	// summary:
+	//		The controller for contact list info for this demo.
+
+	return declare([ListController, StoreRefController], {
+		// summaryScrollableViewId: String
+		//		The ID of the scrollable view representing summary (in list).
+		summaryScrollableViewId: "",
+
+		// detailScrollableViewId: String
+		//		The ID of the scrollable view representing detail (in form).
+		detailScrollableViewId: "",
+
+		// initialFocusElementId: String
+		//		The ID of the element that should get the focus when list selection switches, etc.
+		initialFocusElementId: "",
+
+		setDetailsContext: function(/*String*/ uniqueId){
+			// summary:
+			//		Called to move to the repeatdetails page when an item is selected on the WidgetList Data Binding page. 
+			// uniqueId: String
+			//		The ID of the row. 
+
+			this.set("cursorId", uniqueId);
+			registry.byId(this.initialFocusElementId).focus();
+		},
+
+		addEmpty: function(){
+			// summary:
+			//		Called to add an empty item when the white plus icon is pressed on the WidgetList Data Binding page. 
+
+			var payload = getStateful({
+				uniqueId: "" + Math.random(),
+				First: "",
+				Last: "",
+				Location: "CA",
+				Office: "",
+				Email: "",
+				Tel: "",
+				Fax: ""
+			});
+			this[this._refInModelProp].push(payload);
+			this.set("cursor", payload);
+			registry.byId(this.summaryScrollableViewId).performTransition(this.detailScrollableViewId, 1, "none");
+			registry.byId(this.initialFocusElementId).focus();
+		},
+
+		remove: function(/*String*/ uniqueId){
+			// summary:
+			//		Called to remove an item when the red circle minus icon is pressed on the WidgetList Data Binding page. 
+
+			for(var model = this[this._refInModelProp], i = 0; i < model.length; i++){
+				if(model[i][this.idProperty] == uniqueId){
+					model.splice(i, 1);
+					if(i < this[this._refInModelProp].get("length")){
+						this.set("cursorIndex", i);
+					}
+					return;
+				}
+			}
+		}
+	});
+});
diff --git a/dojox/mvc/tests/mobile/demo/MobileDemoContactListModel.js b/dojox/mvc/tests/mobile/demo/MobileDemoContactListModel.js
new file mode 100644
index 0000000..9a26413
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/MobileDemoContactListModel.js
@@ -0,0 +1,39 @@
+define(["dojox/mvc/getStateful"], function(getStateful){
+	// module:
+	//		dojox/mvc/tests/mobile/demo/MobileDemoContactListModel
+	// summary:
+	//		The data model of contact list info for this demo.
+
+	return getStateful([ 
+		{
+			uniqueId: "0",
+			First: "Chad",
+			Last: "Chapman",
+			Location: "CA",
+			Office: "1278",
+			Email: "c.c at test.com",
+			Tel: "408-764-8237",
+			Fax: "408-764-8228"
+		},
+		{
+			uniqueId: "1",
+			First: "Irene",
+			Last: "Ira",
+			Location: "NJ",
+			Office: "F09",
+			Email: "i.i at test.com",
+			Tel: "514-764-6532",
+			Fax: "514-764-7300"
+		},
+		{
+			uniqueId: "2",
+			First: "John",
+			Last: "Jacklin",
+			Location: "CA",
+			Office: "6701",
+			Email: "j.j at test.com",
+			Tel: "408-764-1234",
+			Fax: "408-764-4321"
+		}
+	]);
+});
diff --git a/dojox/mvc/tests/mobile/demo/MobileDemoContactModel.js b/dojox/mvc/tests/mobile/demo/MobileDemoContactModel.js
new file mode 100644
index 0000000..96151d8
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/MobileDemoContactModel.js
@@ -0,0 +1,25 @@
+define(["dojox/mvc/getStateful"], function(getStateful){
+	// module:
+	//		dojox/mvc/tests/mobile/demo/MobileDemoContactModel
+	// summary:
+	//		The data model of contact info for this demo.
+
+	return getStateful({
+		Serial: "360324",
+		First: "John",
+		Last: "Doe",
+		Email: "jdoe at us.ibm.com",
+		ShipTo: {
+			Street: "123 Valley Rd",
+			City: "Katonah",
+			State: "NY",
+			Zip: "10536"
+		},
+		BillTo: {
+			Street: "17 Skyline Dr",
+			City: "Hawthorne",
+			State: "NY",
+			Zip: "10532"
+		}
+	});
+});
diff --git a/dojox/mvc/tests/mobile/demo/MobileDemoGenerateActions.js b/dojox/mvc/tests/mobile/demo/MobileDemoGenerateActions.js
new file mode 100644
index 0000000..a3abf19
--- /dev/null
+++ b/dojox/mvc/tests/mobile/demo/MobileDemoGenerateActions.js
@@ -0,0 +1,35 @@
+define([
+	"dojo/dom",
+	"dojo/json",
+	"dijit/registry"
+], function(dom, json, registry){
+	// module:
+	//		dojox/mvc/tests/mobile/demo/MobileDemoGenerateActions
+	// summary:
+	//		The action handlers for Generate example of this demo.
+
+	return {
+		switchToData: function(){
+			// summary:
+			//		Called when the "Update Model" button is pressed on the Generate View page.
+
+			dom.byId("outerModelArea").style.display = "";
+			try {
+				dom.byId("modelArea").focus(); // hack: do this to force focus off of the textbox, bug on mobile?
+				dom.byId("viewArea").style.display = "none";
+				registry.byId("modelArea").set("value", json.stringify(registry.byId("view").get("children")));
+			} catch(e) {
+				console.log(e);
+			}
+		},
+		
+		switchToGenerated: function(){
+			// summary:
+			//		Called when the "Update View" button is pressed on the Generate Simple Form. 
+
+			dom.byId("outerModelArea").style.display = "none";
+			dom.byId("viewArea").style.display = "";
+		}
+	};
+});
+
diff --git a/dojox/mvc/tests/mobile/demo/demo-async-store.html b/dojox/mvc/tests/mobile/demo/demo-async-store.html
deleted file mode 100644
index 14aa506..0000000
--- a/dojox/mvc/tests/mobile/demo/demo-async-store.html
+++ /dev/null
@@ -1,186 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<title>Async Mobile MVC</title>
-		<link rel="stylesheet" type="text/css" href="demo.css"/>		
-		<style>
-		
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			position: relative;
-		}
-		.mblEdgeToEdgeList {
-			background-color: #DBDDE2;
-		}
-		</style>
-
-		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../dojo/dojo.js"></script>
-		<script type="text/javascript" src="src-async-store.js" charset="utf-8"></script>
-
-	</head>
-	<body>
-	<div id="wholepage" style="display:none">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo</h1>
-			<h2 dojoType="dojox.mobile.RoundRectCategory">Mobile MVC Views</h2>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="sdb" dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" transition="slide" moveTo="settings">
-					Simple Data Binding
-				</li>
-				<li id="rdb" dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" transition="slide" moveTo="repeat">
-					Repeat Data Binding
-				</li>
-				<li id="sfg" dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" transition="slide" moveTo="generate">
-					Simple Form Generate
-				</li>
-			</ul>
-		</div>
-
-	<div id="settings" dojoType="dojox.mobile.ScrollableView">
-		<h1 id="home" dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Data Binding Example</h1>
-		<form name="testForm" id="testForm">	
-		<div class="field-title">Ship to - Bill to Address</div>
-			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
-				<div class="field-row">
-					<span>Order #</span>
-					<input id="lastnameInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Order #" ref="'rel:Serial'"/>
-				</div>
-				<div class="field-row">
-					<span>Last</span>
-					<input  id="serialInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Last'"/>
-				</div>
-				<div class="field-row">
-					<span>Email</span>
-					<input  id="emailInput1" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Email'"/>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
-			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
-			<br/>
-			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
-				<div class="field-row">
-					<span>Street</span>
-					<input  id="streetInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Street" ref="'rel:Street'"/>
-				</div>
-				<div class="field-row">
-					<span>City</span>
-					<input  id="cityInput" dojoType="dojox.mobile.TextBox"
-						placeholder="City" ref="'rel:City'"/>
-				</div>
-				<div class="field-row">
-					<span>State</span>
-					<input  id="stateInput" dojoType="dojox.mobile.TextBox"
-						placeholder="State" ref="'rel:State'"/>
-				</div>
-				<div class="field-row">
-					<span>ZIP Code</span>
-					<input  id="zipInput" dojoType="dojox.mobile.TextBox"
-						placeholder="ZIP Code" ref="'rel:Zip'"/>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
-		</form>
-	</div>
-
-	<div id="repeat" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" back="Home" moveTo="foo">Repeat Data Binding Example</h1>
-		<form name="repeatTestForm" id="repeatTestForm">	
-		<div class="field-title">Search Results</div>
-			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
-				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
-					<div class="row">			 
-						<input dojoType="dojox.mobile.TextBox"
-							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
-						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
-					</div>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
-				<div id="detailsBanner">Details for selected index:</div>
-					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
-						<div class="field-row">
-							<span>First Name</span>
-							<input  id="firstInput" dojoType="dojox.mobile.TextBox"
-								placeholder="First Name" ref="'rel:First'"/>
-						</div>
-						<div class="field-row">
-							<span>Last Name</span>
-							<input id="lastInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Last Name" ref="'rel:Last'"/>
-						</div>
-						<div class="field-row">
-							<span>Email</span>
-							<input  id="emailInput2" dojoType="dojox.mobile.TextBox"
-								placeholder="Email" ref="'rel:Email'"/>
-						</div>
-						<div class="field-row">
-							<span>Telephone</span>
-							<input  id="telInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Telephone" ref="'rel:Tel'"/>
-						</div>
-					</div>
-				</div>
-			<div class="spacer"></div>
-			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
-			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
-			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
-		</form>
-
-	</div>
-
-	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
-		<h1 data-dojo-type="dojox.mobile.Heading" back="Home" moveTo="foo">Simple Form Generate Example</h1>
-		<div class="field-title"></div>
-			<div id="main">
-				<div id="leftNav"></div>
-				<div id="mainContent" class="generate-maincontent">
-					<div id="outerModelArea">
-						<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Model</h3>
-						<div class="generate-textarea-row">
-							<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
-{
-	"Serial": "11111",
-	"First": "John",
-	"Last": "Doe",
-	"Email": "jdoe at example.com",
-	"Phones": [
-		{
-			"Office": "111-111-1111"
-		},
-		{
-			"Mobile": "222-222-2222"
-		}
-	]
-}
-							</textarea>
-						</div>
-						<div class="fieldset">
-							<div class="spacer"></div>
-							<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
-						</div>
-					</div>
-					<div id="viewArea" style="display:none">
-						<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Generated View</h3>
-							<div class="fieldset">
-							<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
-						</div>
-						<div class="fieldset">
-							<div class="spacer"></div>
-							<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
-						</div>
-					</div>
-				</div>
-			</div>
-		</div>
-	</div>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/mobile/demo/demo-async.html b/dojox/mvc/tests/mobile/demo/demo-async.html
deleted file mode 100644
index 2fdc0c5..0000000
--- a/dojox/mvc/tests/mobile/demo/demo-async.html
+++ /dev/null
@@ -1,203 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Mobile MVC</title>
-		<link rel="stylesheet" type="text/css" href="demo.css"/>
-		<style>
-		html, body{
-			height: 100%;
-			overflow: hidden;
-		}
-		.mblEdgeToEdgeList {
-			background-color: #DBDDE2;
-		}
-		</style>
-
-	<!--<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script> -->
-		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../dojo/dojo.js"></script>
-		<script type="text/javascript" src="src-async.js" charset="utf-8"></script>
-
-	</head>
-	<body>
-	<div id="wholepage" style="display:none">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="sdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="settings">
-					Simple Data Binding
-				</li>
-				<li id="rdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="repeat">
-					Repeat Data Binding
-				</li>
-				<li id="sfg" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="generate">
-					Generate Simple Form
-				</li>
-			</ul>
-		</div>
-
-	<div id="settings" dojoType="dojox.mobile.ScrollableView">
-		<h1 id="home" dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Data Binding Example</h1>
-		<form name="testForm" id="testForm">	
-		<div class="field-title">Ship to - Bill to Address</div>
-			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
-				<div class="field-row">
-					<span>Order #</span>
-					<input id="lastnameInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Order #" ref="'rel:Serial'"/>
-				</div>
-				<div class="field-row">
-					<span>Last</span>
-					<input  id="serialInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Last'"/>
-				</div>
-				<div class="field-row">
-					<span>Email</span>
-					<input  id="emailInput1" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Email'"/>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
-			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
-			<br/>
-			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
-				<div class="field-row">
-					<span>Street</span>
-					<input  id="streetInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Street" ref="'rel:Street'"/>
-				</div>
-				<div class="field-row">
-					<span>City</span>
-					<input  id="cityInput" dojoType="dojox.mobile.TextBox"
-						placeholder="City" ref="'rel:City'"/>
-				</div>
-				<div class="field-row">
-					<span>State</span>
-					<input  id="stateInput" dojoType="dojox.mobile.TextBox"
-						placeholder="State" ref="'rel:State'"/>
-				</div>
-				<div class="field-row">
-					<span>ZIP Code</span>
-					<input  id="zipInput" dojoType="dojox.mobile.TextBox"
-						placeholder="ZIP Code" ref="'rel:Zip'"/>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
-		</form>
-	</div>
-
-	<div id="repeat" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Repeat Data Binding Example</h1>
-		<form name="repeatTestForm" id="repeatTestForm">	
-		<div class="field-title">Search Results</div>
-			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
-				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
-					<div class="row">			 
-						<input dojoType="dojox.mobile.TextBox"
-							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
-						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
-					</div>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
-				<div id="detailsBanner">Details for selected index:</div>
-					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
-						<div class="field-row">
-							<span>First Name</span>
-							<input  id="firstInput" dojoType="dojox.mobile.TextBox"
-								placeholder="First Name" ref="'rel:First'"/>
-						</div>
-						<div class="field-row">
-							<span>Last Name</span>
-							<input id="lastInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Last Name" ref="'rel:Last'"/>
-						</div>
-						<div class="field-row">
-							<span>Email</span>
-							<input  id="emailInput2" dojoType="dojox.mobile.TextBox"
-								placeholder="Email" ref="'rel:Email'"/>
-						</div>
-						<div class="field-row">
-							<span>Telephone</span>
-							<input  id="telInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Telephone" ref="'rel:Tel'"/>
-						</div>
-					</div>
-				</div>
-			<div class="spacer"></div>
-			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
-			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
-			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
-		</form>
-
-	</div>
-
-	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
-		<h1 data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="foo">Simple Form Generate Example</h1>
-		<div class="field-title"></div>
-			<div id="main">
-				<div id="leftNav"></div>
-				<div id="mainContent" class="generate-maincontent">
-					<div id="outerModelArea">
-						<div id="generateModel">Model</div>
-						<div class="generate-textarea-row">
-							<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
-{
-	"Serial": "11111",
-	"First": "John",
-	"Last": "Doe",
-	"Email": "jdoe at example.com",
-	"Phones": [
-		{
-			"Office": "111-111-1111"
-		},
-		{
-			"Mobile": "222-222-2222"
-		}
-	]
-}
-							</textarea>
-						</div>
-						<div class="fieldset">
-							<div class="spacer"></div>
-							<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
-						</div>
-					</div>
-					<div id="viewArea" style="display:none">
-						<div id="generateView">Generated View</div>
-							<div class="fieldset">
-							<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
-						</div>
-						<div class="fieldset">
-							<div class="spacer"></div>
-							<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
-						</div>
-					</div>
-				</div>
-			</div>
-					<textarea style="display:none" data-dojo-type="dojox.mobile.TextArea" id="modelArea2">
-{
-	"Serial": "11111",
-	"First": "John",
-	"Middle": "J",
-	"Last": "Doe",
-	"Email": "jdoe at example.com",
-	"Phones": [
-		{
-			"Office": "111-111-1111"
-		},
-		{
-			"Mobile": "222-222-2222"
-		}
-	]
-}
-					</textarea>
-			
-		</div>
-	</div>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/mobile/demo/demo-sync.html b/dojox/mvc/tests/mobile/demo/demo-sync.html
deleted file mode 100644
index accfd3e..0000000
--- a/dojox/mvc/tests/mobile/demo/demo-sync.html
+++ /dev/null
@@ -1,201 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Mobile MVC</title>
-		<link rel="stylesheet" type="text/css" href="demo.css"/>
-		<style>
-		html, body{
-			height: 100%;
-			overflow: hidden;
-		}
-		.mblEdgeToEdgeList {
-			background-color: #DBDDE2;
-		}		
-		</style>
-
-		<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>
-		<!-- <script type="text/javascript" src="../../dojo/dojo.js" djConfig="parseOnLoad: false"></script>	 -->	 
-		<script type="text/javascript" src="src-sync.js" charset="utf-8"></script>
-	</head>
-	<body>
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="sdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="settings">
-					Simple Data Binding
-				</li>
-				<li id="rdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="repeat">
-					Repeat Data Binding
-				</li>
-				<li id="sfg" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="generate">
-					Generate Simple Form
-				</li>
-			</ul>
-		</div>
-
-	<div id="settings" dojoType="dojox.mobile.ScrollableView">
-		<h1 id="home" dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Data Binding Example</h1>
-		<form name="testForm" id="testForm">	
-		<div class="field-title">Ship to - Bill to Address</div>
-			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
-				<div class="field-row">
-					<span>Order #</span>
-					<input id="lastnameInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Order #" ref="'rel:Serial'"/>
-				</div>
-				<div class="field-row">
-					<span>Last</span>
-					<input  id="serialInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Last'"/>
-				</div>
-				<div class="field-row">
-					<span>Email</span>
-					<input  id="emailInput1" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Email'"/>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
-			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
-			<br/>
-			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
-				<div class="field-row">
-					<span>Street</span>
-					<input  id="streetInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Street" ref="'rel:Street'"/>
-				</div>
-				<div class="field-row">
-					<span>City</span>
-					<input  id="cityInput" dojoType="dojox.mobile.TextBox"
-						placeholder="City" ref="'rel:City'"/>
-				</div>
-				<div class="field-row">
-					<span>State</span>
-					<input  id="stateInput" dojoType="dojox.mobile.TextBox"
-						placeholder="State" ref="'rel:State'"/>
-				</div>
-				<div class="field-row">
-					<span>ZIP Code</span>
-					<input  id="zipInput" dojoType="dojox.mobile.TextBox"
-						placeholder="ZIP Code" ref="'rel:Zip'"/>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
-		</form>
-	</div>
-
-	<div id="repeat" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Repeat Data Binding Example</h1>
-		<form name="repeatTestForm" id="repeatTestForm">	
-		<div class="field-title">Search Results</div>
-			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
-				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
-					<div class="row">			 
-						<input dojoType="dojox.mobile.TextBox"
-							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
-						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
-					</div>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
-				<div id="detailsBanner">Details for selected index:</div>
-					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
-						<div class="field-row">
-							<span>First Name</span>
-							<input  id="firstInput" dojoType="dojox.mobile.TextBox"
-								placeholder="First Name" ref="'rel:First'"/>
-						</div>
-						<div class="field-row">
-							<span>Last Name</span>
-							<input id="lastInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Last Name" ref="'rel:Last'"/>
-						</div>
-						<div class="field-row">
-							<span>Email</span>
-							<input  id="emailInput2" dojoType="dojox.mobile.TextBox"
-								placeholder="Email" ref="'rel:Email'"/>
-						</div>
-						<div class="field-row">
-							<span>Telephone</span>
-							<input  id="telInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Telephone" ref="'rel:Tel'"/>
-						</div>
-					</div>
-				</div>
-			<div class="spacer"></div>
-			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
-			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
-			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
-		</form>
-	
-	</div>
-
-	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
-		<h1 data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="foo">Simple Form Generate Example</h1>
-		<div class="field-title"></div>
-			<div id="main">
-				<div id="leftNav"></div>
-				<div id="mainContent" class="generate-maincontent">
-					<div id="outerModelArea">
-						<div id="generateModel">Model</div>
-						<div class="generate-textarea-row">
-							<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
-{
-	"Serial": "11111",
-	"First": "John",
-	"Last": "Doe",
-	"Email": "jdoe at example.com",
-	"Phones": [
-		{
-			"Office": "111-111-1111"
-		},
-		{
-			"Mobile": "222-222-2222"
-		}
-	]
-}
-							</textarea>
-						</div>
-						<div class="fieldset">
-							<div class="spacer"></div>
-							<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
-						</div>
-					</div>
-					<div id="viewArea" style="display:none">
-						<div id="generateView">Generated View</div>
-							<div class="fieldset">
-							<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
-						</div>
-						<div class="fieldset">
-							<div class="spacer"></div>
-							<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
-						</div>
-					</div>
-				</div>
-			</div>
-					<textarea style="display:none" data-dojo-type="dojox.mobile.TextArea" id="modelArea2">
-{
-	"Serial": "11111",
-	"First": "John",
-	"Middle": "J",
-	"Last": "Doe",
-	"Email": "jdoe at example.com",
-	"Phones": [
-		{
-			"Office": "111-111-1111"
-		},
-		{
-			"Mobile": "222-222-2222"
-		}
-	]
-}
-					</textarea>
-			
-		  </div>
-		
-	</body>
-</html>
diff --git a/dojox/mvc/tests/mobile/demo/demo.css b/dojox/mvc/tests/mobile/demo/demo.css
old mode 100755
new mode 100644
index 6f04d16..b5dbdbf
--- a/dojox/mvc/tests/mobile/demo/demo.css
+++ b/dojox/mvc/tests/mobile/demo/demo.css
@@ -46,7 +46,7 @@ div#view {
 	margin: 3px;
 	padding: 3px;
 	width: 100%;
-	background-color: #F7F7F7;
+	background-color: #F7F7F7; 
 	color: #333;
 }
 
@@ -174,7 +174,7 @@ form#testForm div.fieldset, form#repeatTestForm div.fieldset {
 	display: table;
 	border: 1px solid #ddd;
 	border-radius: 10px;
-	background-color: white;
+/*	background-color: white; */
 	margin: 3px;
 	padding: 3px;
 	width: 100%;
@@ -466,4 +466,4 @@ div#tContainer, div#tabPanel {
 	box-shadow: 10px 10px 5px #888;
 	margin-left: 5px;
 	margin-right: 5px;
-}
\ No newline at end of file
+}
diff --git a/dojox/mvc/tests/mobile/demo/demo.html b/dojox/mvc/tests/mobile/demo/demo.html
old mode 100755
new mode 100644
index 67e1465..1880ab1
--- a/dojox/mvc/tests/mobile/demo/demo.html
+++ b/dojox/mvc/tests/mobile/demo/demo.html
@@ -6,146 +6,217 @@
 		<title>Mobile MVC</title>
 		<link rel="stylesheet" type="text/css" href="demo.css"/>
 		<style>
-		html, body{
-			height: 100%;
-			overflow: hidden;
-		}
-		.mblEdgeToEdgeList {
-			background-color: #DBDDE2;
-		}
+			html, body{
+				height: 100%;
+				overflow: hidden;
+			}
+			.mblEdgeToEdgeList {
+				background-color: #DBDDE2;
+			}
 		</style>
-
-	<!--<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script> -->
-		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../dojo/dojo.js"></script>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1, mvc: {debugBindings: 1}" src="../../../../../dojo/dojo.js"></script>
 		<script type="text/javascript" src="src.js" charset="utf-8"></script>
-
 	</head>
 	<body>
-	<div id="wholepage" style="display:none">
-		<div id="foo" dojoType="dojox.mobile.View" selected="true">
-			<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo</h1>
-			<ul dojoType="dojox.mobile.RoundRectList">
-				<li id="sdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="settings">
-					Simple Data Binding
-				</li>
-				<li id="rdb" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="repeat">
-					Repeat Data Binding
-				</li>
-				<li id="sfg" dojoType="dojox.mobile.ListItem" transition="slide" moveTo="generate">
-					Generate Simple Form
-				</li>
-			</ul>
-		</div>
-
-	<div id="settings" dojoType="dojox.mobile.ScrollableView">
-		<h1 id="home" dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Data Binding Example</h1>
-		<form name="testForm" id="testForm">	
-		<div class="field-title">Ship to - Bill to Address</div>
-			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
-				<div class="field-row">
-					<span>Order #</span>
-					<input id="lastnameInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Order #" ref="'rel:Serial'"/>
-				</div>
-				<div class="field-row">
-					<span>Last</span>
-					<input  id="serialInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Last'"/>
-				</div>
-				<div class="field-row">
-					<span>Email</span>
-					<input  id="emailInput1" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Email'"/>
-				</div>
+		<div id="wholepage" style="display:none"> 
+			<div id="foo" data-dojo-type="dojox/mobile/View" data-dojo-props="selected:'true'">
+				<h1 data-dojo-type="dojox/mobile/Heading">Mobile MVC Demo</h1>
+				<ul data-dojo-type="dojox/mobile/RoundRectList">
+					<li id="sdb" data-dojo-type="dojox/mobile/ListItem" data-dojo-props="transition: 'slide', moveTo: 'settings'">
+						Simple Data Binding
+					</li>
+					<li id="rdb" data-dojo-type="dojox/mobile/ListItem" data-dojo-props="transition: 'slide', moveTo: 'repeat'">
+						WidgetList Data Binding
+					</li>
+					<li id="sfg" data-dojo-type="dojox/mobile/ListItem"  data-dojo-props="transition: 'slide', moveTo: 'generate'">
+						Generate Simple Form
+					</li>
+				</ul>
 			</div>
-			<div class="spacer"></div>
-			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
-			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
-			<br/>
-			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
-				<div class="field-row">
-					<span>Street</span>
-					<input  id="streetInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Street" ref="'rel:Street'"/>
-				</div>
-				<div class="field-row">
-					<span>City</span>
-					<input  id="cityInput" dojoType="dojox.mobile.TextBox"
-						placeholder="City" ref="'rel:City'"/>
-				</div>
-				<div class="field-row">
-					<span>State</span>
-					<input  id="stateInput" dojoType="dojox.mobile.TextBox"
-						placeholder="State" ref="'rel:State'"/>
-				</div>
-				<div class="field-row">
-					<span>ZIP Code</span>
-					<input  id="zipInput" dojoType="dojox.mobile.TextBox"
-						placeholder="ZIP Code" ref="'rel:Zip'"/>
-				</div>
+			<span data-dojo-id="nameCtl"
+				data-dojo-type="dojox/mvc/tests/mobile/demo/MobileDemoContactController"
+				data-dojo-props="sourceModel: require('dojox/mvc/tests/mobile/demo/MobileDemoContactModel'),
+				                 cursorIndex: 'ShipTo'"></span>
+			<div id="settings" data-dojo-type="dojox/mobile/ScrollableView">
+				<h1 id="home" data-dojo-type="dojox/mobile/Heading" data-dojo-props="back: 'Back', moveTo: 'foo'">Data Binding Example</h1>
+				<form name="testForm" id="testForm">	
+				<div class="field-title">Ship to - Bill to Address</div>
+					<div class="fieldset"
+						data-dojo-type="dojox/mvc/Group"
+						data-dojo-props="target: at(nameCtl, 'model')">
+						<table id="table" cellspacing="10"  style="width: 100%">
+							<tr>
+								<td style="width: 100px;" class="layout">First</td>
+								<td class="layout">							
+									<input  id="firstInput1" data-dojo-type="dojox/mobile/TextBox" 
+										data-dojo-props="value: at('rel:', 'First'), placeholder: 'First'">
+								</td>
+							</tr>
+							<tr>
+								<td style="width: 100px;" class="layout">Last Name</td>
+								<td class="layout">
+									<input id="lastInput1" data-dojo-type="dojox/mobile/TextBox"
+										 
+										data-dojo-props="placeholder: 'Last Name', value: at('rel:', 'Last')">
+								</td>
+							</tr>
+							<tr>
+								<td style="width: 100px;" class="layout">Email</td>
+								<td class="layout">
+									<input  id="emailInput1" data-dojo-type="dojox/mobile/TextBox"
+										data-dojo-props="value: at('rel:', 'Email'), placeholder: 'Email'">
+								</td>
+							</tr>
+						</table>
+						<div class="spacer"></div>
+						<button id="shipto" type="button" class="mblBlueButton"
+							data-dojo-type="dojox/mobile/Button"
+							onclick="nameCtl.set('cursorIndex', 'ShipTo');">Ship To</button>
+						<button id="billto" type="button" class="mblBlueButton"
+							data-dojo-type="dojox/mobile/Button"
+							onclick="nameCtl.set('cursorIndex', 'BillTo');">Bill To</button>		
+						<br/>
+						<div class="fieldset" id="addrGroup"
+							data-dojo-type="dojox/mvc/Group" 
+							data-dojo-props="target: at(nameCtl, 'cursor')">
+							<table id="table" cellspacing="10" style="width: 100%">
+								<tr>
+									<td style="width: 100px;" class="layout">Street</td>
+									<td class="layout">							
+										<input  id="streetInput" data-dojo-type="dojox/mobile/TextBox" 
+											data-dojo-props="value: at('rel:', 'Street'), placeholder: 'Street'">
+									</td>
+								</tr>
+								<tr>
+									<td style="width: 100px;" class="layout">City</td>
+									<td class="layout">
+										<input id="cityInput" data-dojo-type="dojox/mobile/TextBox"
+											 
+											data-dojo-props="placeholder: 'City', value: at('rel:', 'City')">
+									</td>
+								</tr>
+								<tr>
+									<td style="width: 100px;" class="layout">State</td>
+									<td class="layout">
+										<input  id="StateInput" data-dojo-type="dojox/mobile/TextBox"
+											data-dojo-props="value: at('rel:', 'State'), placeholder: 'State'">
+									</td>
+								</tr>
+								<tr>
+									<td style="width: 100px;" class="layout">State</td>
+									<td class="layout">
+										<input  id="ZipInput" data-dojo-type="dojox/mobile/TextBox"
+											data-dojo-props="value: at('rel:', 'Zip'), placeholder: 'Zip Code'">
+									</td>
+								</tr>
+							</table>
+						</div>
+					</div> <!--  end of outer group -->
+					<div class="spacer"></div>
+					<button id="reset1" type="button" data-dojo-type="dojox/mobile/Button" class="mblBlueButton" onclick="nameCtl.reset();">Reset</button>
+				</form>
 			</div>
-			<div class="spacer"></div>
-			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
-		</form>
-	</div>
-
-	<div id="repeat" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" back="Back" moveTo="foo">Repeat Data Binding Example</h1>
-		<form name="repeatTestForm" id="repeatTestForm">	
-		<div class="field-title">Search Results</div>
-			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
-				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
-					<div class="row">			 
-						<input dojoType="dojox.mobile.TextBox"
-							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
-						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
-					</div>
-				</div>
+			<span data-dojo-id="listCtl"
+				data-dojo-type="dojox/mvc/tests/mobile/demo/MobileDemoContactListController"
+				data-dojo-props="model: require('dojox/mvc/tests/mobile/demo/MobileDemoContactListModel'),
+				                 summaryScrollableViewId: 'repeat',
+				                 detailScrollableViewId: 'repeatdetails',
+				                 initialFocusElementId: 'firstInput'"></span>
+			<div id="repeat" data-dojo-type="dojox/mobile/ScrollableView">
+				<h1 data-dojo-type="dojox/mobile/Heading"
+					data-dojo-props="back: 'Back', moveTo: 'foo'">
+					WidgetList Data
+					<span id="addbutton"  data-dojo-type="dojox/mobile/ToolBarButton" 
+						data-dojo-props="icon: 'mblDomButtonWhitePlus',
+						                 onClick: function(){ listCtl.addEmpty(); }"
+						style="float:right;"></span>
+				</h1>
+				<ul id="listItems"
+					data-dojo-type="dojox/mobile/RoundRectList"
+					data-dojo-mixins="dojox/mvc/WidgetList,dojox/mvc/_InlineTemplateMixin"
+					data-dojo-props="children: at(listCtl, 'model')"
+					data-mvc-child-type="dojox/mvc/Templated"
+					data-mvc-child-mixins="dojox/mobile/ListItem"
+					data-mvc-child-props="moveTo: 'repeatdetails',
+					                      uniqueId: at(this.target, 'uniqueId'),
+					                      transitionOptions: {title: 'Detail', target: 'details,detail'},  
+					                      clickable: 'true',
+					                      callback: function(){ listCtl.setDetailsContext(this.uniqueId); }">
+					<script type="dojox/mvc/InlineTemplate">
+						<li data-dojo-type="dojox/mobile/ListItem" 
+							<table>
+								<tr>
+									<td>
+										<div data-dojo-type="dojox/mobile/ToolBarButton" 
+											data-dojo-props="icon: 'mblDomButtonRedCircleMinus', 
+											                 onClick: function(){ listCtl.remove(this.uniqueId); return false; },
+											                 uniqueId: at('rel:', 'uniqueId')" 
+											style="float: left; color: white; background-color: transparent; background-image: none; border: none; margin-top: 0px;"></div>
+									</td>
+								</tr>
+							</table>
+							<div class="mblListItemLabel" style="display: block;" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at('rel:', 'First')"></div>
+						</li>
+					</script>
+				</ul>
 			</div>
-			<div class="spacer"></div>
-			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
-				<div id="detailsBanner">Details for selected index:</div>
-					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
-						<div class="field-row">
-							<span>First Name</span>
-							<input  id="firstInput" dojoType="dojox.mobile.TextBox"
-								placeholder="First Name" ref="'rel:First'"/>
-						</div>
-						<div class="field-row">
-							<span>Last Name</span>
-							<input id="lastInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Last Name" ref="'rel:Last'"/>
-						</div>
-						<div class="field-row">
-							<span>Email</span>
-							<input  id="emailInput2" dojoType="dojox.mobile.TextBox"
-								placeholder="Email" ref="'rel:Email'"/>
-						</div>
-						<div class="field-row">
-							<span>Telephone</span>
-							<input  id="telInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Telephone" ref="'rel:Tel'"/>
-						</div>
+			<div id="repeatdetails" data-dojo-type="dojox/mobile/ScrollableView">
+		 		<h1 id="detailsHeading" data-dojo-type="dojox/mobile/Heading" data-dojo-props="label: 'Details'" data-app-region="top">
+					<div id="detail_back" data-dojo-type="dojox/mobile/ToolBarButton" 
+						data-dojo-props="onClick: function(e){ require('dijit/registry').byId('telInput').focus(); }, moveTo:'repeat', arrow: 'left', label: 'Back'" style="float:left"></div>
+				</h1>
+				<div id="detailsGroup" class="fieldset" data-dojo-type="dojox/mvc/Group" 
+					data-dojo-props="target: at(listCtl, 'cursor')">
+					<div class="row">
+						<div style="display: inline-block;" id="detailsBanner">Details for selected index:</div>
+						<span class="cell" id="indexOutput"
+							data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at(listCtl, 'cursorIndex')"></span>
 					</div>
+					<table id="table" cellspacing="10"  style="width: 100%">
+						<tr>
+							<td style="width: 100px;" class="layout">First Name</td>
+							<td class="layout">							
+								<input  id="firstInput" data-dojo-type="dojox/mobile/TextBox" 
+									data-dojo-props="value: at('rel:', 'First'), placeholder: 'First Name'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Last Name</td>
+							<td class="layout">
+								<input id="lastInput" data-dojo-type="dojox/mobile/TextBox"
+									 
+									data-dojo-props="placeholder: 'Last Name', value: at('rel:', 'Last')">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Email</td>
+							<td class="layout">
+								<input  id="emailInput2" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Email'), placeholder: 'Email'">
+							</td>
+						</tr>
+						<tr>
+							<td style="width: 100px;" class="layout">Telephone</td>
+							<td class="layout">
+								<input  id="telInput" data-dojo-type="dojox/mobile/TextBox"
+									data-dojo-props="value: at('rel:', 'Tel'), placeholder: 'Telephone'">
+							</td>
+						</tr>
+					</table>
 				</div>
-			<div class="spacer"></div>
-			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
-			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
-			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
-		</form>
-
-	</div>
-
-	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView">
-		<h1 data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="foo">Simple Form Generate Example</h1>
-		<div class="field-title"></div>
-			<div id="main">
-				<div id="leftNav"></div>
-				<div id="mainContent" class="generate-maincontent">
-					<div id="outerModelArea">
-						<div id="generateModel">Model</div>
-						<div class="generate-textarea-row">
-							<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
+			</div>
+			<div id="generate" data-dojo-type="dojox/mobile/ScrollableView">
+				<h1 data-dojo-type="dojox/mobile/Heading" data-dojo-props='back:"Back", moveTo:"foo"'>Simple Form Generate Example</h1>
+				<div class="field-title"></div>
+				<div id="main">
+					<div id="leftNav"></div>
+					<div id="mainContent" class="generate-maincontent">
+						<div id="outerModelArea">
+							<div id="generateModel">Model</div>
+							<div class="generate-textarea-row">
+								<textarea class="generate-textarea-cell" 
+										data-dojo-type="dojox/mobile/TextArea" id="modelArea">
 {
 	"Serial": "11111",
 	"First": "John",
@@ -160,44 +231,34 @@
 		}
 	]
 }
-							</textarea>
-						</div>
-						<div class="fieldset">
-							<div class="spacer"></div>
-							<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
-						</div>
-					</div>
-					<div id="viewArea" style="display:none">
-						<div id="generateView">Generated View</div>
+								</textarea>
+							</div>
 							<div class="fieldset">
-							<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
+								<div class="spacer"></div>
+								<button id="generate1" type="button" class="mblBlueButton"
+									data-dojo-type="dojox/mobile/Button"
+									onclick="require('dojox/mvc/tests/mobile/demo/MobileDemoGenerateActions').switchToGenerated()">Generate Form</button>
+							</div>
 						</div>
-						<div class="fieldset">
-							<div class="spacer"></div>
-							<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
+						<div id="viewArea" style="display:none">
+							<div id="generateView">Generated View</div>
+								<div class="fieldset">
+								<div id="view" data-dojo-type="dojox/mvc/Generate"
+					 				data-dojo-props="widgetMapping:{'String' : 'dojox/mobile/TextBox'},
+					 				                 idNameMapping: {String: 'TB'},
+					 				                 children: at('widget:modelArea', 'value').direction(at.from).transform({format: require('dojo/json').parse})">
+					 			</div>
+							</div>
+							<div class="fieldset">
+								<div class="spacer"></div>
+								<button id="updateModel" type="button" class="mblBlueButton"
+									data-dojo-type="dojox/mobile/Button"
+									onclick="require('dojox/mvc/tests/mobile/demo/MobileDemoGenerateActions').switchToData();">Update Model</button>
+							</div>
 						</div>
 					</div>
 				</div>
 			</div>
-					<textarea style="display:none" data-dojo-type="dojox.mobile.TextArea" id="modelArea2">
-{
-	"Serial": "11111",
-	"First": "John",
-	"Middle": "J",
-	"Last": "Doe",
-	"Email": "jdoe at example.com",
-	"Phones": [
-		{
-			"Office": "111-111-1111"
-		},
-		{
-			"Mobile": "222-222-2222"
-		}
-	]
-}
-					</textarea>
-			
 		</div>
-	</div>
 	</body>
 </html>
diff --git a/dojox/mvc/tests/mobile/demo/iPad-Demo.html b/dojox/mvc/tests/mobile/demo/iPad-Demo.html
deleted file mode 100644
index 24a0a63..0000000
--- a/dojox/mvc/tests/mobile/demo/iPad-Demo.html
+++ /dev/null
@@ -1,213 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Mobile MVC on iPad</title>
-		<link rel="stylesheet" type="text/css" href="demo.css"/>		
-		<style>
-		@import "../../../../mobile/themes/iphone/base.css";
-		@import "../../../../mobile/themes/iphone/ipad.css";
-		@import "../../../../mobile/themes/common/FixedSplitter.css";
-		html, body{
-			height: 100%;
-			overflow: hidden;
-			position: relative;
-		}
-		.mblEdgeToEdgeList {
-			background-color: #DBDDE2;
-		}
-		</style>
-	<!--<script type="text/javascript" src="../../../../../dojo/dojo.js" djConfig="parseOnLoad: false"></script> -->
-		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../../../dojo/dojo.js"></script>
-		<script type="text/javascript" src="src-async-store.js" charset="utf-8"></script>
-
-	</head>
-	<body>
-	<div id="wholepage" style="display:none">	
-		<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
-			<div dojoType="dojox.mobile.FixedSplitterPane" style="width:300px;border-right:1px solid black;">
-				<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
-					<h1 dojoType="dojox.mobile.Heading">Mobile MVC Demo for iPad</h1>
-					<ul dojoType="dojox.mobile.EdgeToEdgeList" transition="flip" stateful="true">
-					<li id="sdb" dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" transition="slide" moveTo="settings"  selected="true">
-						Simple Data Binding
-					</li>
-					<li id="rdb" dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" transition="slide" moveTo="repeat">
-						Repeat Data Binding
-					</li>
-					<li id="sfg" dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" transition="slide" moveTo="generate">
-						Simple Form Generate
-					</li>
-				</ul>
-			</div>
-			</div>
-
-			<div dojoType="dojox.mobile.FixedSplitterPane">
-
-
-	<div id="settings" dojoType="dojox.mobile.ScrollableView"  selected="true">
-		<h1 id="home" dojoType="dojox.mobile.Heading" fixed="top">Data Binding Example</h1>
-		<form name="testForm" id="testForm">	
-		<div class="field-title">Ship to - Bill to Address</div>
-			<div class="fieldset" dojoType="dojox.mvc.Group" ref="model">
-				<div class="field-row">
-					<span>Order #</span>
-					<input type=text id="lastnameInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Order #" ref="'rel:Serial'"/>
-				</div>
-				<div class="field-row">
-					<span>Last</span>
-					<input type=text id="serialInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Last'"/>
-				</div>
-				<div class="field-row">
-					<span>Email</span>
-					<input type=text id="emailInput1" dojoType="dojox.mobile.TextBox"
-						placeholder="Last" ref="'rel:Email'"/>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
-			<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
-			<br/>
-			<div class="fieldset" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
-				<div class="field-row">
-					<span>Street</span>
-					<input type=text id="streetInput" dojoType="dojox.mobile.TextBox"
-						placeholder="Street" ref="'rel:Street'"/>
-				</div>
-				<div class="field-row">
-					<span>City</span>
-					<input type=text id="cityInput" dojoType="dojox.mobile.TextBox"
-						placeholder="City" ref="'rel:City'"/>
-				</div>
-				<div class="field-row">
-					<span>State</span>
-					<input type=text id="stateInput" dojoType="dojox.mobile.TextBox"
-						placeholder="State" ref="'rel:State'"/>
-				</div>
-				<div class="field-row">
-					<span>ZIP Code</span>
-					<input type=text id="zipInput" dojoType="dojox.mobile.TextBox"
-						placeholder="ZIP Code" ref="'rel:Zip'"/>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<button id="reset1" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
-		</form>
-	</div>
-
-
-				<div id="repeat" dojoType="dojox.mobile.ScrollableView">
-		<h1 dojoType="dojox.mobile.Heading" fixed="top">Repeat Data Binding Example</h1>
-		<form name="repeatTestForm" id="repeatTestForm">	
-		<div class="field-title">Search Results</div>
-			<div class="fieldset" dojoType="dojox.mvc.Repeat" class="row" ref="repeatmodel">
-				<div dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
-					<div class="row">			 
-						<input dojoType="dojox.mobile.TextBox"
-							id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
-						<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
-					</div>
-				</div>
-			</div>
-			<div class="spacer"></div>
-			<div  dojoType="dojox.mvc.Group" ref="repeatmodel">
-				<div id="detailsBanner">Details for selected index:</div>
-					<div class="fieldset" id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
-						<div class="field-row">
-							<span>First Name</span>
-							<input type=text id="firstInput" dojoType="dojox.mobile.TextBox"
-								placeholder="First Name" ref="'rel:First'"/>
-						</div>
-						<div class="field-row">
-							<span>Last Name</span>
-							<input type=text id="lastInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Last Name" ref="'rel:Last'"/>
-						</div>
-						<div class="field-row">
-							<span>Email</span>
-							<input type=text id="emailInput2" dojoType="dojox.mobile.TextBox"
-								placeholder="Email" ref="'rel:Email'"/>
-						</div>
-						<div class="field-row">
-							<span>Telephone</span>
-							<input type=text id="telInput" dojoType="dojox.mobile.TextBox"
-								placeholder="Telephone" ref="'rel:Tel'"/>
-						</div>
-					</div>
-				</div>		   
-			<div class="spacer"></div>
-			<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
-			<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(repeatmodel[selectedIndex].toPlainObject());repeatmodel[selectedIndex].commit()">Save</button>
-			<button id="reset2" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="repeatmodel.reset()">Reset</button>
-			
-	</div>
-
-	<div id="generate" data-dojo-type="dojox.mobile.ScrollableView"	 style="width: 100%;">
-	<h1 data-dojo-type="dojox.mobile.Heading" fixed="top">Simple Form Generate Example</h1>
-	<div class="field-title"></div>
-		<div id="main">
-		  <div id="leftNav">
-		  </div>
-		  <div id="mainContent" class="generate-maincontent">
-			<div id="outerModelArea">
-				<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Model</h3>
-				<div class="generate-textarea-row">
-					<textarea class="generate-textarea-cell" data-dojo-type="dojox.mobile.TextArea" id="modelArea">
-{
-	"Serial": "11111",
-	"First": "John",
-	"Last": "Doe",
-	"Email": "jdoe at example.com",
-	"Phones": [
-		{
-			"Office": "111-111-1111"
-		},
-		{
-			"Mobile": "222-222-2222"
-		}
-	]
-}
-					</textarea>
-				</div>
-				<div class="fieldset">
-					<div class="spacer"></div>
-					<button id="generate1" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateView()">Generate Form</button>
-				</div>
-			</div>
-			<div id="viewArea" style="display:none">
-				<h3 data-dojo-type="dojox.mobile.RoundRectCategory">Generated View</h3>
-				<div class="fieldset">
-					<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="widgetMapping:{'String' : 'dojox.mobile.TextBox'}, idNameMapping:{'String' : 'TB'}"></div>
-				</div>
-				<div class="fieldset">
-					<div class="spacer"></div>
-					<button id="updateModel" type="button" data-dojo-type="dojox.mobile.Button" class="mblBlueButton" onclick="updateModel()">Update Model</button>
-				</div>
-			</div>
-					<textarea style="display:none" data-dojo-type="dojox.mobile.TextArea" id="modelArea2">
-{
-	"Serial": "11111",
-	"First": "John",
-	"Middle": "J",
-	"Last": "Doe",
-	"Email": "jdoe at example.com",
-	"Phones": [
-		{
-			"Office": "111-111-1111"
-		},
-		{
-			"Mobile": "222-222-2222"
-		}
-	]
-}
-					</textarea>
-			
-		  			</div>
-				</div>
-			</div>
-		</div></div></div>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/mobile/demo/src.js b/dojox/mvc/tests/mobile/demo/src.js
old mode 100755
new mode 100644
index 787cb6b..f02fad2
--- a/dojox/mvc/tests/mobile/demo/src.js
+++ b/dojox/mvc/tests/mobile/demo/src.js
@@ -1,167 +1,36 @@
-var repeatModel, setRef, nextIndexToAdd, selectedIndex;
-var setRef, setDetailsContext, insertResult, updateView, updateModel;
-
-require(['dojo/has',
-	'dojox/mobile/parser',
-	//'dojo/parser',
-	'dojo/ready',
-	'dojox/mvc',
-	'dojox/mobile',
-	'dojox/mobile/ScrollableView',
-	'dojox/mobile/Button',
-	'dojox/mobile/TextArea',
-	'dojox/mvc/Group',
-	'dojox/mvc/Generate',
-	'dojox/mvc/Repeat',
-	'dojox/mobile/TextBox',
-	'dojox/mobile/ViewController',
-	'dojox/mobile/FixedSplitter',
-	'dojox/mobile/EdgeToEdgeList',
-	'dojox/mobile/EdgeToEdgeCategory',
-	'dojox/mobile/deviceTheme',
-	'dojox/mobile/RoundRectCategory',
-	'dojox/mobile/Heading',
-	'dijit/registry',
-	'dojo/_base/json',
-	'dojo/dom'
-], function(has, parser, ready, mvc, mobile, ScrollableView, Button, TextArea, Group, Generate, Repeat, TextBox, ViewController,
-		FixedSplitter, EdgeToEdgeList, EdgeToEdgeCategory, deviceTheme, RoundRectCategory, Heading, WidgetRegistry,
-		json, dom){
-
+require([
+	"dojo/_base/lang",
+	"dojo/aspect",
+	"dojo/dom",
+	"dojo/has",
+	"dijit/registry",
+	"dojox/mobile/parser",
+	"dojox/mobile/ListItem",
+	"dojox/mvc/at",
+	"dojox/mvc/Generate",
+	"dojox/mvc/Group",
+	"dojox/mvc/Output",
+	"dojox/mvc/Templated",
+	"dojox/mvc/WidgetList",
+	"dojox/mvc/_InlineTemplateMixin",
+	"dojox/mvc/tests/mobile/demo/MobileDemoContactModel",
+	"dojox/mvc/tests/mobile/demo/MobileDemoContactListModel",
+	"dojox/mvc/tests/mobile/demo/MobileDemoContactController",
+	"dojox/mvc/tests/mobile/demo/MobileDemoContactListController",
+	"dojox/mvc/tests/mobile/demo/MobileDemoGenerateActions",
+	"dojox/mobile",
+	"dojox/mobile/deviceTheme",
+	"dojox/mobile/Button",
+	"dojox/mobile/Heading",
+	"dojox/mobile/ScrollableView",
+	"dojox/mobile/TextArea",
+	"dojox/mobile/TextBox",
+	"dojo/domReady!"
+], function(lang, aspect, dom, has, registry, parser, ListItem, at){
 	if(!has("webkit")){
 		require(["dojox/mobile/compat"]);
 	}
-
-	var names = {
-	"Serial" : "360324",
-	"First"  : "John",
-	"Last"   : "Doe",
-	"Email"  : "jdoe at us.ibm.com",
-	"ShipTo" : {
-		"Street" : "123 Valley Rd",
-		"City"   : "Katonah",
-		"State"  : "NY",
-		"Zip"    : "10536"
-	},
-	"BillTo" : {
-		"Street" : "17 Skyline Dr",
-		"City"   : "Hawthorne",
-		"State"  : "NY",
-		"Zip"    : "10532"
-	}
-};
-
-// Initial repeat data used in the Repeat Data binding demo
-var repeatData = [ 
-	{
-		"First"   : "Chad",
-		"Last"    : "Chapman",
-		"Location": "CA",
-		"Office"  : "1278",
-		"Email"   : "c.c at test.com",
-		"Tel"     : "408-764-8237",
-		"Fax"     : "408-764-8228"
-	},
-	{
-		"First"   : "Irene",
-		"Last"    : "Ira",
-		"Location": "NJ",
-		"Office"  : "F09",
-		"Email"   : "i.i at test.com",
-		"Tel"     : "514-764-6532",
-		"Fax"     : "514-764-7300"
-	},
-	{
-		"First"   : "John",
-		"Last"    : "Jacklin",
-		"Location": "CA",
-		"Office"  : "6701",
-		"Email"   : "j.j at test.com",
-		"Tel"     : "408-764-1234",
-		"Fax"     : "408-764-4321"
-	}
-];
-
-	selectedIndex = 0;
-
-	model = mvc.newStatefulModel({ data : names });
-	repeatmodel = mvc.newStatefulModel({ data : repeatData });
-	nextIndexToAdd = repeatmodel.data.length;
-
-	// used in the Ship to - Bill to demo
-	setRef = function(id, addrRef) {
-		var widget = WidgetRegistry.byId(id);
-		widget.set("ref", addrRef);
-	}
-
-	// used in the Repeat Data binding demo
-	setDetailsContext = function(index){
-		selectedIndex = index;
-		var groupRoot = WidgetRegistry.byId("detailsGroup");
-		groupRoot.set("ref", index);
-	}
-
-	// used in the Repeat Data binding demo
-	insertResult = function(index){
-		if (repeatmodel[index-1].First.value !== ""){ // TODO: figure out why we are getting called twice for each click
-			var insert = mvc.newStatefulModel({ "data" : {
-			"First"   : "",
-			"Last"    : "",
-			"Location": "CA",
-			"Office"  : "",
-			"Email"   : "",
-			"Tel"     : "",
-			"Fax"     : ""} 
-			});
-			repeatmodel.add(index, insert);
-			setDetailsContext(index);
-			nextIndexToAdd++;
-		}else{
-			setDetailsContext(index-1);                 
-		}
-	};
-
-	// used in the Generate View demo
-	var genmodel;
-	updateView = function() {
-		try {
-			var modeldata = json.fromJson(dom.byId("modelArea").value);
-			genmodel = mvc.newStatefulModel({ data : modeldata });
-			WidgetRegistry.byId("view").set("ref", genmodel);
-			dom.byId("outerModelArea").style.display = "none";
-			dom.byId("viewArea").style.display = "";              		
-		}catch(err){
-			console.error("Error parsing json from model: "+err);
-		}
-	};
-
-	// used in the Generate View demo
-	updateModel = function() {
-		dom.byId("outerModelArea").style.display = "";
-		try {
-			dom.byId("modelArea").focus(); // hack: do this to force focus off of the textbox, bug on mobile?
-			dom.byId("viewArea").style.display = "none";
-			WidgetRegistry.byId("modelArea").set("value",(json.toJson(genmodel.toPlainObject(), true)));
-		} catch(e) {
-			console.log(e);
-		};
-	};
-
-
-	// The dojox.mvc.StatefulModel class creates a data model instance
-	// where each leaf within the data model is decorated with dojo.Stateful
-	// properties that widgets can bind to and watch for their changes.
-
-
-	// when "dojo/ready" is ready call parse
-	ready(function(){
-		parser.parse();
-	});
-
-	// when domReady! is ready show the page 
-	require(['dojo/domReady!'], function(){
-		dom.byId("wholepage").style.display = "";
-	});
-
-}); // end function
-
+	window.at = at;
+	parser.parse();
+	dom.byId("wholepage").style.display = "";
+});
diff --git a/dojox/mvc/tests/mobile/test_Android-repeat-data-store.html b/dojox/mvc/tests/mobile/test_Android-repeat-data-store.html
deleted file mode 100755
index a0a736e..0000000
--- a/dojox/mvc/tests/mobile/test_Android-repeat-data-store.html
+++ /dev/null
@@ -1,104 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>Android Repeat Data Example</title>
-		<link href="../../../../dojox/mobile/themes/android/android.css" rel="stylesheet"/>
-		<link href="../css/android-format.css" rel="stylesheet"/>
-
-	<!--  use below for iPhone theme  
-		<link href="../../../../dojox/mobile/themes/iphone/iphone.css" rel="stylesheet"></link>
-		<link href="../css/iphone-format.css" rel="stylesheet"></link>
-	-->
-
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: false, isDebug: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); 
-			dojo.require("dojox.mobile.parser"); // dojox.mobile.parser did not work
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.TextBox");
-			dojo.require("dojox.mobile.Button");
-			dojo.require("dojox.mvc");
-			dojo.require("dojox.mvc.Group");
-			dojo.require("dojox.mvc.Repeat");
-			dojo.require("dojo.data.ItemFileWriteStore");
-			dojo.require("dojo.store.DataStore");
-			
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-			var model, selectedIndex = 0, nextIndexToAdd, theModelPromise;
-
-			function setup() {
-				var writeStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests._data", "mvcRepeatData.json")});
-				var modelPromise = dojox.mvc.newStatefulModel({store: new dojo.store.DataStore({store: writeStore}), query:{"Location" : "CA"}}); // example of using a query parm for Location 
-				modelPromise.then(function(results){ 
-					model = results;
-					nextIndexToAdd = model.data.length;
-					//dojo.parser.parse();
-					dojox.mobile.parser.parse();
-				});
-			};
-
-			dojo.ready(setup);
-		</script>
-	</head>
-	<body>
-<h1 dojoType="dojox.mobile.Heading">Android Repeat Data Binding Example.</h1>
-		<div >Search Results:</div>
-		<div dojoType="dojox.mvc.Repeat" class="row" ref="model">
-			<div class="row" dojoType="dojox.mvc.Group" ref="'rel:${this.index}'">
-				<input dojoType="dojox.mobile.TextBox"
-					id="nameInput${this.index}" ref="'rel:First'" placeHolder="First Name"/>
-				<button id="details${this.index}" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setDetailsContext('${this.index}')">Details</button>
-			</div>
-		</div>
-		<div class="spacer"></div>
-		<div dojoType="dojox.mvc.Group" ref="model">
-			<div id="detailsBanner">Details for selected index:</div>
-				<div id="detailsGroup" dojoType="dojox.mvc.Group" ref="'rel:0'">
-					<div><label for="firstInput">First Name:</label></div>
-					<div><input id="firstInput" dojoType="dojox.mobile.TextBox" ref="'rel:First'" placeHolder="First Name"/></div>
-					<div><label for="lastInput">Last Name:</label></div>
-					<div><input id="lastInput" dojoType="dojox.mobile.TextBox" ref="'rel:Last'" placeHolder="Last Name"/></div>
-					<div><label for="emailInput">Email:</label></div>
-					<div><input id="emailInput" dojoType="dojox.mobile.TextBox" ref="'rel:Email'" placeHolder="Email"/></div>
-					<div><label for="telInput">Telephone:</label></div>
-					<div><input id="telInput" dojoType="dojox.mobile.TextBox" ref="'rel:Tel'" placeHolder="Telephone"/></div>
-					<div><label for="faxInput">Fax:</label></div>
-					<div><input id="faxInput" dojoType="dojox.mobile.TextBox" ref="'rel:Fax'" placeHolder="Fax"/></div>
-				</div>
-			</div>		   
-		<div class="spacer"></div>
-		<button id="add" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="insertResult(nextIndexToAdd)">Add</button>
-		<button id="save" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="console.log(model[selectedIndex].toPlainObject());model[selectedIndex].commit()">Save</button>
-		<button id="reset" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
-		<script type="text/javascript">
-			function setDetailsContext(index){
-				selectedIndex = index;
-				var groupRoot = dijit.byId("detailsGroup");
-				groupRoot.set("ref", index);
-			}
-
-			function insertResult(index){
-				if (model[index-1].First.value !== ""){ // TODO: figure out why we are getting called twice for each click
-					var insert = dojox.mvc.newStatefulModel({ "data" : {
-						"First"	  : "",
-						"Last"	  : "",
-						"Location": "CA",
-						"Office"  : "",
-						"Email"	  : "",
-						"Tel"	  : "",
-						"Fax"	  : ""} 
-					});
-					model.add(index, insert);
-					setDetailsContext(index);
-					nextIndexToAdd++;
-				}else{
-					setDetailsContext(index-1);					
-				}
-			}
-		</script>				 
-	</body>
-</html>
diff --git a/dojox/mvc/tests/mobile/test_iPhone-shipto-billto.html b/dojox/mvc/tests/mobile/test_iPhone-shipto-billto.html
deleted file mode 100755
index 700caae..0000000
--- a/dojox/mvc/tests/mobile/test_iPhone-shipto-billto.html
+++ /dev/null
@@ -1,121 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
-		<meta name="apple-mobile-web-app-capable" content="yes" />
-		<title>iPhone Shipto-Billto</title>
-		<link href="../../../../dojox/mobile/themes/iphone/iphone.css" rel="stylesheet"/>
-		<link href="../css/iphone-format.css" rel="stylesheet"/>
-
-	<!-- use links below for android theme		  
-		<link href="../../../../dojox/mobile/themes/android/android.css" rel="stylesheet">
-		<link href="../css/android-format.css" rel="stylesheet">
-	-->
-	
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
-
-		<script language="JavaScript" type="text/javascript">
-			//dojo.require("dojo.parser"); 
-			dojo.require("dojox.mobile.parser"); 
-			dojo.require("dojox.mobile");
-			dojo.require("dojox.mobile.TextBox");
-			dojo.require("dojox.mobile.Button");
-			dojo.require("dojox.mvc");
-			dojo.require("dojox.mvc.Group");
-			dojo.require("dojox.mvc.Repeat");
-			
-			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
-
-			// Initial data
-			var names = {
-				"Serial" : "360324",
-				"First"	 : "John",
-				"Last"	 : "Doe",
-				"Email"	 : "jdoe at us.ibm.com",
-				"ShipTo" : {
-					"Street" : "123 Valley Rd",
-					"City"	 : "Katonah",
-					"State"	 : "NY",
-					"Zip"	 : "10536"
-				},
-				"BillTo" : {
-					"Street" : "17 Skyline Dr",
-					"City"	 : "Hawthorne",
-					"State"	 : "NY",
-					"Zip"	 : "10532"
-				}
-			};
-
-			var model = dojox.mvc.newStatefulModel({ data : names });
-			
-		</script>
-	</head>
-	<body>
-		<h1 dojoType="dojox.mobile.Heading">iPhone Data Binding Ex.</h1>
-		<div class="row" dojoType="dojox.mvc.Group" ref="model">
-			<div>
-				<label for="serialInput">Order #:</label>
-			</div>
-			<div>
-				<input	class="cell" id="serialInput" dojoType="dojox.mobile.TextBox"
-						ref="'rel:Serial'"/>
-			</div>
-			<div>
-				<label for="lastnameInput">Last:</label>
-			</div>
-			<div>
-				<input id="lastnameInput" dojoType="dojox.mobile.TextBox"
-					   ref="'rel:Last'"/>
-			</div>
-			<div>
-				<label for="emailInput">Email:</label>
-			</div>
-			<div>
-				<input id="emailInput" dojoType="dojox.mobile.TextBox"
-					   ref="'rel:Email'"/>
-			</div>
-		</div>
-		<div class="spacer"></div>
-		<button id="shipto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
-		<button id="billto" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>		
-		<br/>
-		<div class="row" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
-			<div>
-				<label for="streetInput">Street:</label>
-			</div>
-			<div>
-				<input	id="streetInput" dojoType="dojox.mobile.TextBox"
-						placeHolder="Street" ref="'rel:Street'"/>
-			</div>
-			<div>
-				<label for="cityInput">City:</label>
-			</div>
-			<div>
-				<input id="cityInput" dojoType="dojox.mobile.TextBox"
-					   placeHolder="City" ref="'rel:City'"/>
-			</div>
-			<div>
-				<label for="stateInput">State:</label>
-			</div>
-			<div>
-				<input id="stateInput" dojoType="dojox.mobile.TextBox"
-					   placeHolder="State" ref="'rel:State'"/>
-			</div>
-			<div>
-				<label for="zipInput">ZIP Code:</label>
-			</div>
-			<div>
-				<input id="zipInput" dojoType="dojox.mobile.TextBox"
-					   placeHolder="ZIP Code" ref="'rel:Zip'"/>
-			</div>
-		</div>
-		<div class="spacer"></div>
-		<button id="reset" type="button" dojoType="dojox.mobile.Button" class="mblBlueButton" onclick="model.reset()">Reset</button>
-		<script type="text/javascript">
-			function setRef(id, addrRef) {
-				var widget = dijit.byId(id);
-				widget.set("ref", addrRef);
-			}
-		</script>				 
-	</body>
-</html>
diff --git a/dojox/mvc/tests/mobile/test_mobile-checkbox-list-mvc.html b/dojox/mvc/tests/mobile/test_mobile-checkbox-list-mvc.html
new file mode 100644
index 0000000..d7896af
--- /dev/null
+++ b/dojox/mvc/tests/mobile/test_mobile-checkbox-list-mvc.html
@@ -0,0 +1,514 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>MVC Repeat with Selectable RoundRectList - Multiple Select</title>
+
+	<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true, parseOnLoad: false, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dojo/_base/declare",
+	        "dojo/_base/connect", 
+			"dijit/registry",
+			"dojo/dom",
+			"dojox/mobile/parser",
+			"dojo/store/Memory",
+			"dojo/ready",
+			"dojo/when",
+			"dojo/Stateful",
+			"dojox/mvc/getStateful",
+			"dojo/data/ItemFileWriteStore",
+			"dojo/store/Memory",
+			"dojox/mvc/EditStoreRefController",
+			"dojox/mvc/ListController",
+			"dojox/mvc/at",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat",
+			"dojox/mvc/Output",
+			"dojox/mobile",
+			"dojox/mobile/compat",
+			"dojox/mobile/FixedSplitter",
+			"dojox/mobile/Container",			
+			"dojox/mobile/ListItem",
+			"dojox/mobile/Button",
+			"dojox/mobile/ToolBarButton",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/CheckBox",
+			"dojox/mobile/EdgeToEdgeDataList",
+//			"dojox/mobile/TextArea",
+			"dojox/mobile/View",
+			"dojox/mobile/ScrollableView",
+			"dojox/mobile/SimpleDialog",
+//			"dojox/mobile/FixedSplitter",
+//			"dojox/mobile/EdgeToEdgeList",
+//			"dojox/mobile/EdgeToEdgeCategory",
+//			"dojox/mobile/RoundRectCategory",
+			"dojox/mobile/Heading",
+			"dojox/mobile/deviceTheme"
+		], function(lang, declare, connect, registry, dom, parser, MemoryStore, ready, when, Stateful, 
+					getStateful, ItemFileWriteStore, Memory, EditStoreRefController, ListController, at){
+			window.at = at;
+			
+			_addNewItem = function(e){
+				console.log("_addNewItem called");
+				//event.stop(e);
+				
+				//var datamodel = app.loadedModels.itemlistmodel;
+				//var datamodel = app.loadedModels.itemlistcontroller;
+				var datamodel = currentctrl;
+				var parentId;
+				try {
+					parentId = datamodel.model[0].parentId;
+				}
+				catch (e) {
+					console.log("Warning: itemlistmodel is empty, get parentId from listsmodel");
+					parentId = app.loadedModels.listsmodel[window.selected_configuration_item].id;
+				}
+				var index = datamodel.model.length;
+				var insert = new Stateful({
+						"id": (new Date().getTime()),
+						"parentId": parentId,
+						"title": "",
+						"notes": "To do",
+						"due": "2010-10-15T11:03:47.681Z",
+						"completionDate": "",
+						"reminder": "2010-10-15T11:03:47.681Z",
+						"repeat": 0,
+						"priority": 0,
+						"hidden": false,
+						"completed": false,
+						"deleted": false
+				});
+				datamodel.model.push(insert);
+				datamodel.commit(); //need to commit after delete. TODO: need to enhance the performance
+				var r = registry.byId("todomain");
+				r.performTransition("details", 1, "none");
+				movedTo(index);
+				//update cache
+				//app.loadedModels.itemlistsmodel[parentId] = datamodel.model;
+				//refresh view
+				//window.showData(datamodel.model);
+			};
+
+			completeConverter = {
+					format: function(value){
+						console.log("****in completeConverter format value = "+value);
+						//return "dijitMenuItemLabel" + (value ? " complete" : "");
+						//ctrl.set("completed", false);
+						//ctrlComplete.set("completed", true);
+						//for(var a = this.source.inModel, i = 0; i < a.length; i++){
+						//	if(a[i].id == this.target.id){
+								console.log("****in completeConverter format this.source.id = "+this.source.id);
+								console.log(this.source);							
+								//return a[i];
+						//	}
+						//}						
+						return value;
+					},
+					parse: function(value){
+						console.log("****in completeConverter parse value = "+value);
+						console.log("****in completeConverter parse this.source.id = "+this.source.id);						
+						console.log(this.source);
+						var model = ctrlComplete.model;
+						if(value){
+							model = currentctrl.model;
+						}
+						for(var a = model, i = 0; i < a.length; i++){
+							if(a[i].id == this.source.id){
+								if(value){ // remove from list and move to completed
+									window.setTimeout(moveToComplete(currentctrl.model, ctrlComplete.model, i, value), 500);						
+								}else{
+									window.setTimeout(moveFromComplete(ctrlComplete.model, currentctrl.model, i, value), 500);						
+								}
+							} 
+						}
+						//throw new Error(); // Stop copying the new value for unchecked case
+						if(!value){ throw new Error(); } // Stop copying the new value for unchecked case						
+						return value;
+					}					
+			};
+			
+			var listData =
+			{
+				  	"identifier": "id",
+					"items": [
+								{
+									"id": 100,
+									"parentId":1,  
+									"title": "item 1 to do for 1",
+									"notes": "To do",
+									"due": "2010-10-15T11:03:47.681Z",
+									"completionDate": "", 
+									"reminder": "2010-10-15T11:03:47.681Z",  
+									"repeat": 0,
+									"priority": 0,
+									"hidden": false,
+									"completed": false,
+									"deleted": false
+								},
+								{
+									"id": 103,
+									"parentId":1,
+									"title": "item 3 to do for 1",
+									"notes": "To do",
+									"due": "2010-10-15T11:03:47.681Z",
+									"completionDate": "",
+									"reminder": "2010-10-15T11:03:47.681Z",
+									"repeat": 2,
+									"priority": 2,
+									"hidden": false,
+									"completed": false,
+									"deleted": false
+								}
+							]
+			};
+
+			
+			var listData1 =
+			{
+				  	"identifier": "id",
+					"items": [
+								{
+									"id": 101,
+									"parentId":2,  
+									"title": "item 1 to do for 2",
+									"notes": "To do",
+									"priority": 0,
+									"due": "2010-10-15T11:03:47.681Z",
+									"completionDate": "", 
+									"reminder": "2010-10-15T11:03:47.681Z",  
+									"repeat": 0,
+									"hidden": false,
+									"completed": false,
+									"deleted": false
+								},
+								{
+									"id": 103,  
+									"parentId":2,  
+									"title": "item 3 else to do for 2",
+									"notes": "To do",
+									"priority": 0,
+									"due": "2010-10-15T11:03:47.681Z",
+									"completionDate": "", 
+									"reminder": "2010-10-15T11:03:47.681Z",  
+									"repeat": 0,
+									"hidden": false,
+									"completed": false,
+									"deleted": false
+								}
+							]
+			};
+
+			var completedListData =
+			{
+				  	"identifier": "id",
+					"items": [
+								{
+									"id": 102,  
+									"parentId":2,  
+									"title": "item 2 to do for 0",
+									"notes": "To do",
+									"due": "2010-10-15T11:03:47.681Z",
+									"completionDate": "", 
+									"reminder": "2010-10-15T11:03:47.681Z",  
+									"repeat": 0,
+									"priority": 1,
+									"hidden": false,
+									"completed": true,
+									"deleted": false
+								}							]
+			};
+
+			var allListsData =
+			{
+					  "identifier": "id",
+					  "items": [ 
+					                    {
+					                    	"title":"Reminders",
+											"id":0,
+											"parentId":null,
+											"itemsurl":"../resources/data/items-for-0.json"
+					                    },
+					                    {
+					                    	"title":"Work Items",
+											"id":1,
+											"parentId":null,
+											"itemsurl":"../resources/data/items-for-1.json"
+					                    }
+							]
+			};
+
+			
+			var inited,
+			ctrlClass = declare([EditStoreRefController, ListController], {
+				cursorIndex: 0,
+				completed: "",
+				completedTyped: "",
+				_refModelProp: "model",
+
+				addEmpty: function(){
+					this.model.push(new Stateful({First: "", Last: "", Location: "", Office: "", Email: "", Tel: "", Fax: ""}));
+					this.set("cursorIndex", this.get("length") - 1);
+				},
+
+				remove: function(idx){
+					this.model.splice(idx, 1);
+					if(this.get("cursorIndex") < 0){
+						this.set("cursorIndex", this.get("length") - 1);
+					}
+				},
+
+				_setCompletedAttr: function(value){
+					this.set("completedTyped", value);
+					console.log("_setCompletedAttr called for completedTyped="+this.completedTyped +" with value="+value);					
+				
+					when(this.queryStore(), function(){
+						if(inited){
+							parser.parse();
+							//inited = true;
+							var d = registry.byId("addbutton");
+							connect.connect(d, "onClick", this, _addNewItem);
+						}
+					});
+					this._set("completed", value);
+				}
+			});
+			ctrlListsClass = declare([EditStoreRefController, ListController], {
+				cursorIndex: 0,
+				_refModelProp: "model"
+			});
+
+			listsCtrls = [];
+			ctrlComplete = new ctrlClass({store: new Memory({data: completedListData})});
+			listsCtrls.push(ctrlComplete);
+			currentctrl = new ctrlClass({store: new Memory({data: listData})});
+			listsCtrls.push(currentctrl);
+			ctrl1 = new ctrlClass({store: new Memory({data: listData1})});
+			listsCtrls.push(ctrl1);
+
+			listsCtrl = new ctrlListsClass({store: new Memory({data: allListsData})});
+			when(listsCtrl.queryStore(), function(){
+					listsCtrls[0].set("completed", true);
+					//currentctrl.set("completed", false);
+					listsCtrls[1].set("completed", false);
+					inited = true;
+					listsCtrls[2].set("completed", false);
+			});
+
+
+
+			// called when showing item details
+			movedTo = function(index) {
+				console.log("movedTo called with index"+index);
+				currentctrl.set('cursorIndex', index);
+				var g = registry.byId("detailsGroup");
+				g.set("target", at(currentctrl, 'cursor'));
+				var h = registry.byId("detailsHeading");
+				h.set("label","To-Do Details");
+				var h2 = dom.byId("detailsHeading2");
+				h2.innerHTML="To Do Item";
+			};
+
+			// called when showing item details for a completed item
+			movedToCompleted = function(index) {
+				console.log("movedToCompleted called with index"+index);
+				ctrlComplete.set('cursorIndex', index);
+				var g = registry.byId("detailsGroup");
+				g.set("target", at(ctrlComplete, 'cursor'));
+				var h = registry.byId("detailsHeading");
+				h.set("label","Completed To-Do");
+				var h2 = dom.byId("detailsHeading2");
+				h2.innerHTML="Completed Item";
+			};
+			
+			// called when an item is completed
+			moveToComplete = function(fromModel, toModel, i, value) {
+				console.log("****in moveToComplete value = "+value);
+				var t = fromModel.splice(i, 1);
+				t[0].set("completed", value);
+				toModel.push(t[0]);
+			};
+
+			// called when a completed items is unchecked
+			moveFromComplete = function(fromModel, toModel, i, value) {
+				console.log("****in moveFromComplete value = "+value);
+				var t = fromModel.splice(i, 1);
+				t[0].set("completed", value);
+				toModel = listsCtrls[t[0].get('parentId')].model;
+				toModel.push(t[0]);
+			};
+
+			// called when a different list is selected
+			selectList = function(index) {
+				if(index != -1){
+					index = parseInt(index)+1;
+				}else{
+					index = '0';
+				}
+				console.log("selectList called with index"+index);
+				listsCtrl.set('cursorIndex', index);
+				//listsCtrl.set('cursorIndex', index);//listItems
+				var r = registry.byId("listItems");
+				currentctrl = listsCtrls[index];
+				r.set("children", at(currentctrl, 'model'));
+			};
+
+			// called to delete the selected item
+			deleteSelected = function() {
+				console.log("deleteSelected called with currentctrl.cursorIndex="+currentctrl.cursorIndex);
+				console.log("deleteSelected called with currentctrl.cursor.title="+currentctrl.cursor.title);				
+				currentctrl.model.splice(currentctrl.cursorIndex, 1);
+				var r = registry.byId("details");
+				r.performTransition("todomain", 1, "none");
+			};
+
+			showDlg = function(dlg){
+				registry.byId(dlg).show();
+			};
+			hideDlg = function(dlg){
+				registry.byId(dlg).hide();
+			};
+			
+			resetAll = function() {
+				console.log("resetAll called");
+			
+			};
+			
+
+		});
+		
+	</script>
+</head>
+<body style="visibility:hidden;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<div data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props='orientation:"H"'>
+		<div data-dojo-type="dojox.mobile.Container" style="width:300px;border-right:1px solid black;">
+			<div id="settings" data-dojo-type="dojox.mobile.ScrollableView">
+			<!--  <h1 data-dojo-type="dojox.mobile.Heading" data-dojo-props='fixed:"top"'>Configure</h1> -->
+				<h2 data-dojo-type="dojox.mobile.Heading" region="top">Configure
+			<img style="position: absolute; display: block; width: 32px; height: 32px; right: 0; top: 0" onClick="editConfiguration();"
+				src="../images/settings.png" />
+			</h2>
+   
+ 	 			<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem"  clickable="true" 
+					data-dojo-props="onClick: function(){console.log('selected list ', '-1'); selectList('-1');}">
+						Completed
+					</li>
+				</ul>
+
+				<ul data-dojo-type="dojox.mobile.RoundRectList"   
+					data-dojo-mixins="dojox.mvc.Repeat" 
+					data-dojo-props="exprchar:'#', children: at(listsCtrl, 'model')">
+							<li  class="mblVariableHeight" 
+								data-dojo-type="dojox.mobile.ListItem" clickable="true" 
+								data-dojo-props="label:at('rel:#{this.index}','title'), 
+									onClick: function(){console.log('selected list ', '#{this.index}'); selectList('#{this.index}');}">  
+							<!-- <table><tr>
+									<td data-dojo-type="dojox.mvc.Output" 
+										data-dojo-props="value: at('rel:#{this.index}','title')"></td>
+								</tr></table>
+							-->	
+							</li>
+				</ul>
+			
+			</div>
+		</div>
+
+		<div data-dojo-type="dojox.mobile.Container">
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+ 			<div id="todomain" data-dojo-type="dojox.mobile.View" selected="true">
+				<div data-dojo-type="dojox.mvc.Group" 
+					data-dojo-props="target: at(listsCtrl, 'cursor')">
+					<div data-dojo-type="dojox.mobile.Heading" region="top"
+						data-dojo-props="label: at('rel:','title')">
+					<span id="addbutton"  data-dojo-type="dojox.mobile.ToolBarButton" 
+							data-dojo-props='icon:"mblDomButtonWhitePlus"' style="float:right;" 
+							onclick="console.log('+ was clicked')"></span>
+					</div>	
+				</div>				
+				<ul data-dojo-type="dojox.mobile.RoundRectList" id="listItems"   
+					data-dojo-mixins="dojox.mvc.Repeat" 
+					data-dojo-props="exprchar:'#', children: at(currentctrl, 'model')">
+							<li  class="mblVariableHeight"  moveTo="details" callback="function(){movedTo('#{this.index}')}" 
+								data-dojo-type="dojox.mobile.ListItem" clickable="true" 
+								data-dojo-props="onClick: function(){console.log('select item ', '#{this.index}'); window.selected_item = this.index;}"
+								transitionOptions="{title: 'Detail', target: 'details,detail'}">  
+								<table><tr>
+									<td><input preventTouch='true' type='checkbox' 
+											data-dojo-type="dojox.mobile.CheckBox" 
+											data-dojo-props="checked: at('rel:#{this.index}','completed').transform(completeConverter)"/></td>
+									<td data-dojo-type="dojox.mvc.Output" 
+										data-dojo-props="value: at('rel:#{this.index}','title')"></td>
+								</tr></table>
+							</li>
+				</ul>
+<!--  
+	<h2 data-dojo-type="dojox.mobile.Heading" region="top">
+		<span>Completed Items</span>
+	</h2>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"   
+					data-dojo-mixins="dojox.mvc.Repeat" 
+					data-dojo-props="exprchar:'#', children: at(ctrlComplete, 'model')">
+							<li  class="mblVariableHeight"   moveTo="details" callback="function(){movedToCompleted('#{this.index}')}" 
+								data-dojo-type="dojox.mobile.ListItem" clickable="true" 
+								data-dojo-props="onClick: function(){console.log('select item ', '#{this.index}'); window.selected_item = this.index;}"
+								transitionOptions="{title: 'Detail', target: 'details,detail'}">  
+								<table><tr>
+									<td><input preventTouch='true' type='checkbox' 
+											data-dojo-type="dojox.mobile.CheckBox" 
+											data-dojo-props="checked: at('rel:#{this.index}','completed').transform(completeConverter)"/></td>
+									<td data-dojo-type="dojox.mvc.Output" 
+										data-dojo-props="value: at('rel:#{this.index}','title')"></td>
+								</tr></table>
+							</li>
+				</ul>
+-->
+
+			</div>
+	<div id="details" data-dojo-type="dojox.mobile.ScrollableView">
+		<h1 id="detailsHeading" data-dojo-type="dojox.mobile.Heading" back="Back" moveTo="todomain">To-Do Details</h1>
+			<div id="detailsGroup" class="fieldset" data-dojo-type="dojox.mvc.Group" 
+								data-dojo-props="target: at(currentctrl, 'cursor')">
+ 				<h2 id="detailsHeading2">Completed Items</h2>
+				<div class="field-row">
+					<span>To Do</span>
+					<input id="todo" data-dojo-type="dojox.mobile.TextBox"
+						placeholder="To do placeholder"  
+						data-dojo-props="value: at('rel:', 'title')"/>
+				</div>
+
+ 	 			<ul data-dojo-type="dojox.mobile.RoundRectList">
+					<li data-dojo-type="dojox.mobile.ListItem"  
+					data-dojo-props="clickable: true, noArrow: true, 
+						onClick: function(){console.log('delete item '); showDlg('dlg_confirm');}">
+						Delete
+					</li>
+				</ul>
+				
+			</div>
+
+
+	</div>
+			</div>
+		</div>
+
+	<div id="dlg_confirm" data-dojo-type="dojox.mobile.SimpleDialog">
+		<div class="mblSimpleDialogTitle">Delete Confirmation</div>
+		<div class="mblSimpleDialogText">Are you sure you want to delete this item?</div>
+		<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton" onclick="hideDlg('dlg_confirm')">No</button>
+		<button data-dojo-type="dojox.mobile.Button" class="mblSimpleDialogButton mblBlueButton" onclick="hideDlg('dlg_confirm');deleteSelected();">Yes</button>
+	</div>
+		
+	</body>
+</html>
diff --git a/dojox/mvc/tests/mobile/test_mobile-list-multiple-sel-mvc.html b/dojox/mvc/tests/mobile/test_mobile-list-multiple-sel-mvc.html
new file mode 100644
index 0000000..66b2c89
--- /dev/null
+++ b/dojox/mvc/tests/mobile/test_mobile-list-multiple-sel-mvc.html
@@ -0,0 +1,180 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>MVC Repeat with Selectable RoundRectList - Multiple Select</title>
+
+	<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true, parseOnLoad: false, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojo/store/Memory",
+			"dojo/ready",
+			"dojo/when",
+			"dojox/mvc/getStateful",
+			"dojox/mvc/at",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat",
+			"dojox/mvc/Output",
+			"dojox/mobile",
+			"dojox/mobile/Button",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/CheckBox",
+			"dojox/mobile/deviceTheme"
+		], function(lang, registry, parser, MemoryStore, ready, when, getStateful, at){
+			window.at = at;
+
+			var search_results_init1 =
+			[{
+				"Query" : "Engineers1",
+				"Results" : [
+					{
+						"First"	  : "Anne1",
+						"Last"	  : "Ackerman1",
+						"Checked" : true
+					},
+					{
+						"First"	  : "Ben1",
+						"Last"	  : "Beckham1",
+						"Checked" : false
+					},
+					{
+						"First"	  : "Chad1",
+						"Last"	  : "Chapman1",
+						"Checked" : false
+					}
+				]
+			}];
+
+			var search_results_init2 =
+				[{
+					"Query" : "Engineers1",
+					"Results" : [
+						{
+							"First"	  : "Anne2",
+							"Last"	  : "Ackerman2",
+							"Checked" : false
+						},
+						{
+							"First"	  : "Ben2",
+							"Last"	  : "Beckham2",
+							"Checked" : true
+						},
+						{
+							"First"	  : "Chad2",
+							"Last"	  : "Chapman2",
+							"Checked" : false
+						}
+					]
+				}];
+			var memStore1 = new MemoryStore({data : search_results_init1});
+			//model1 = mvc.newStatefulModel({ store : memStore1 })[0];
+
+				when(memStore1.query(), function(data){
+					model1 = getStateful(data)[0];
+					model1Orig = lang.clone(model1);
+					//if(model1 && model2 && model3){ runTests(); }
+				});
+
+
+		var memStore2 = new MemoryStore({data : search_results_init2});
+		//model2 = mvc.newStatefulModel({ store : memStore2 })[0];
+				when(memStore2.query(), function(data){
+					model2 = getStateful(data)[0];
+					model2Orig = lang.clone(model2);
+					//if(model1 && model2 && model3){ runTests(); }
+				});
+			
+			// when "dojo/ready" is ready call parser.parse (if not doing parseOnLoad)
+			ready(function(){
+				parser.parse();
+			});
+
+
+			// called to reset the model for each of the repeats
+			swapToModel1 = function() {
+				registry.byId('repeatId1').set('children',model1.Results); 
+				registry.byId('repeatId2').set('children',model1.Results); 
+				registry.byId('repeatid2arem').set('children',model1.Results);
+			};
+
+			swapToModel2 = function() {
+				registry.byId('repeatId1').set('children',model2.Results); 
+				registry.byId('repeatId2').set('children',model2.Results); 
+				registry.byId('repeatid2arem').set('children',model2.Results);
+			};
+
+			resetAll = function() {
+				model1 = lang.clone(model1Orig);
+				model2 = lang.clone(model2Orig);
+				registry.byId('repeatId1').set('children',model1.Results); 
+				registry.byId('repeatId2').set('children',model1.Results); 
+				registry.byId('repeatid2arem').set('children',model1.Results);
+			};
+			
+
+		});
+		
+	</script>
+</head>
+<body style="visibility:hidden;">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h2>MVC Repeat with Selectable RoundRectList - Multiple Select</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+				<h4>Here is one using dojox.mvc.Repeat as a mixin with no Group and dojo.parser instead of dojox.mobile.parser it is all good using mixin.</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatId1" select="multiple" 
+					data-dojo-mixins="dojox.mvc.Repeat" data-dojo-props="exprchar:'#', children: model1.Results">
+							<li id="configure_itemmix1#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: at('rel:#{this.index}', 'First'),
+												checked: at('rel:#{this.index}', 'Checked')">
+							</li>
+				</ul>
+
+				<h4>Here is one using MVC using Repeat no Group, with removeRepeatNode set true it is all good if Repeat sets select and onCheckStateChanged.</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatparentidrem" select="multiple">
+					<div data-dojo-type="dojox.mvc.Repeat" id="repeatid2arem" 
+						data-dojo-props="exprchar:'#', children:model1.Results, removeRepeatNode:true">
+							<li id="configure_itemrem#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: at('rel:#{this.index}','First'),
+												checked: at('rel:#{this.index}','Checked')">
+							</li>
+					</div>
+				</ul>
+				<h4>You can update the label or checked from here to update the model.</h4>
+				   <div id="repeatparentid2">
+						<div id="repeatId2" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children:model1.Results">
+								<input class="cell" data-dojo-type="dojox.mobile.TextBox" id="nameInput2${this.index}" 
+										data-dojo-props="value: at('rel:${this.index}', 'First')"/>
+		  						<label data-dojo-type="dojox.mvc.Output" for="CBInput${this.index}" 
+										data-dojo-props="value: at('rel:${this.index}','First')"/></label>
+								<input class="cell" type="checkbox" data-dojo-type="dojox.mobile.CheckBox" id="CBInput${this.index}" 
+										data-dojo-props="checked: at('rel:${this.index}','Checked')"/>
+						</div>
+					</div>
+
+					<br/>Model:
+					<button type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){swapToModel2();}">Swap Model2</button> 
+					<button type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){swapToModel1();}">Swap Model1</button> 					
+				 	<button id="reset" type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){resetAll();}">Reset all</button> 	
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/mobile/test_mobile-list-single-sel-mvc.html b/dojox/mvc/tests/mobile/test_mobile-list-single-sel-mvc.html
new file mode 100644
index 0000000..8d12df6
--- /dev/null
+++ b/dojox/mvc/tests/mobile/test_mobile-list-single-sel-mvc.html
@@ -0,0 +1,179 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
+	<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+	<meta name="apple-mobile-web-app-capable" content="yes"/>
+	<title>MVC Repeat with Selectable RoundRectList - Single Select</title>
+
+	<script type="text/javascript" src="../../../../dojox/mobile/deviceTheme.js" data-dojo-config="mblThemeFiles: ['base']"></script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true, parseOnLoad: false, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojo/_base/lang",
+			"dijit/registry",
+			"dojox/mobile/parser",
+			"dojo/store/Memory",
+			"dojo/ready",
+			"dojo/when",
+			"dojox/mvc/getStateful",
+			"dojox/mvc/at",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat",
+			"dojox/mvc/Output",
+			"dojox/mobile",
+			"dojox/mobile/Button",
+			"dojox/mobile/TextBox",
+			"dojox/mobile/CheckBox",
+			"dojox/mobile/deviceTheme"
+		], function(lang, registry, parser, MemoryStore, ready, when, getStateful, at){
+			window.at = at;
+
+			var search_results_init1 =
+			[{
+				"Query" : "Engineers1",
+				"Results" : [
+					{
+						"First"	  : "Anne1",
+						"Last"	  : "Ackerman1",
+						"Checked" : true
+					},
+					{
+						"First"	  : "Ben1",
+						"Last"	  : "Beckham1",
+						"Checked" : false
+					},
+					{
+						"First"	  : "Chad1",
+						"Last"	  : "Chapman1",
+						"Checked" : false
+					}
+				]
+			}];
+
+			var search_results_init2 =
+				[{
+					"Query" : "Engineers1",
+					"Results" : [
+						{
+							"First"	  : "Anne2",
+							"Last"	  : "Ackerman2",
+							"Checked" : false
+						},
+						{
+							"First"	  : "Ben2",
+							"Last"	  : "Beckham2",
+							"Checked" : true
+						},
+						{
+							"First"	  : "Chad2",
+							"Last"	  : "Chapman2",
+							"Checked" : false
+						}
+					]
+				}];
+			var memStore1 = new MemoryStore({data : search_results_init1});
+			//model1 = mvc.newStatefulModel({ store : memStore1 })[0];
+
+				when(memStore1.query(), function(data){
+					model1 = getStateful(data)[0];
+					model1Orig = lang.clone(model1);
+					//if(model1 && model2 && model3){ runTests(); }
+				});
+
+
+		var memStore2 = new MemoryStore({data : search_results_init2});
+		//model2 = mvc.newStatefulModel({ store : memStore2 })[0];
+				when(memStore2.query(), function(data){
+					model2 = getStateful(data)[0];
+					model2Orig = lang.clone(model2);
+					//if(model1 && model2 && model3){ runTests(); }
+				});
+			
+			// when "dojo/ready" is ready call parser.parse (if not doing parseOnLoad)
+			ready(function(){
+				parser.parse();
+			});
+
+
+			// called to reset the model for each of the repeats
+			swapToModel1 = function() {
+				registry.byId('repeatId1').set('children',model1.Results); 
+				registry.byId('repeatId2').set('children',model1.Results); 
+				registry.byId('repeatid2arem').set('children',model1.Results);
+			};
+
+			swapToModel2 = function() {
+				registry.byId('repeatId1').set('children',model2.Results); 
+				registry.byId('repeatId2').set('children',model2.Results); 
+				registry.byId('repeatid2arem').set('children',model2.Results);
+			};
+
+			resetAll = function() {
+				model1 = lang.clone(model1Orig);
+				model2 = lang.clone(model2Orig);
+				registry.byId('repeatId1').set('children',model1.Results); 
+				registry.byId('repeatId2').set('children',model1.Results); 
+				registry.byId('repeatid2arem').set('children',model1.Results);
+			};
+			
+
+		});
+		
+	</script>
+</head>
+<body style="visibility:hidden;">
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h2>MVC Repeat with Selectable RoundRectDataList - Single Select</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+				<h4>Here is one using dojox.mvc.Repeat as a mixin with no Group and dojo.parser instead of dojox.mobile.parser it is all good using mixin.</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatId1" select="single" 
+					data-dojo-mixins="dojox.mvc.Repeat" data-dojo-props="exprchar:'#', children: model1.Results">
+							<li id="configure_itemmix1#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: at('rel:#{this.index}', 'First'),
+												checked: at('rel:#{this.index}', 'Checked')">
+							</li>
+				</ul>
+
+				<h4>Here is one using MVC using Repeat no Group, with removeRepeatNode set true it is all good if Repeat sets select and onCheckStateChanged.</h4>
+				<ul data-dojo-type="dojox.mobile.RoundRectList"  id="repeatparentidrem" select="single">
+					<div data-dojo-type="dojox.mvc.Repeat" id="repeatid2arem" 
+						data-dojo-props="exprchar:'#', children:model1.Results, removeRepeatNode:true">
+							<li id="configure_itemrem#{this.index}" class="mblVariableHeight" data-dojo-type="dojox.mobile.ListItem"  
+								data-dojo-props="label: at('rel:#{this.index}','First'),
+												checked: at('rel:#{this.index}','Checked')">
+							</li>
+					</div>
+				</ul>
+				<h4>You can update the label or checked from here to update the model.</h4>
+				   <div id="repeatparentid2">
+						<div id="repeatId2" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children:model1.Results">
+								<input class="cell" data-dojo-type="dojox.mobile.TextBox" id="nameInput2${this.index}" 
+										data-dojo-props="value: at('rel:${this.index}', 'First')"/>
+		  						<label data-dojo-type="dojox.mvc.Output" for="CBInput${this.index}" 
+										data-dojo-props="value: at('rel:${this.index}','First')"/></label>
+								<input class="cell" type="checkbox" data-dojo-type="dojox.mobile.CheckBox" id="CBInput${this.index}" 
+										data-dojo-props="checked: at('rel:${this.index}','Checked')"/>
+						</div>
+					</div>
+
+					<br/>Model:
+					<button type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){swapToModel2();}">Swap Model2</button> 
+					<button type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){swapToModel1();}">Swap Model1</button> 					
+				 	<button id="reset" type="button" data-dojo-type="dojox.mobile.Button" data-dojo-props="onClick: function(){resetAll();}">Reset all</button> 	
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/models/LoanWizardModel.js b/dojox/mvc/tests/models/LoanWizardModel.js
deleted file mode 100755
index 62314ba..0000000
--- a/dojox/mvc/tests/models/LoanWizardModel.js
+++ /dev/null
@@ -1,113 +0,0 @@
-define([
-	"dojo/_base/declare",
-	"dojox/mvc",
-	"dojox/mvc/StatefulModel",
-	"dojo/data/ItemFileWriteStore"
-], function(declare, mvc, StatefulModel, ItemFileWriteStore){
-	/*=====
-		declare = dojo.declare;
-		mvc = dojox.mvc;
-		StatefulModel = dojox.mvc.StatefulModel;
-		ItemFileWriteStore = dojo.data.ItemFileWriteStore;
-	=====*/
-
-	return declare("dojox.mvc.tests.models.LoanWizardModel", [StatefulModel], {
-
-		// data store for pie chart
-		chartStore: new ItemFileWriteStore({ data: {
-			"hierarchical" : false,
-			"identifier"   : "id",
-			"items" : [
-			           { "id" : "mortgage", "x"  : 1, "y"	: 0 },
-			           { "id" : "taxes", "x"  : 2, "y"	 : 0 },
-			           { "id" : "otherhousing", "x"  : 3, "y"	: 0 }
-			           ]
-		}}),
-
-		constructor: function (args) {
-			this.inherited(arguments);
-
-			// try to precompute address fields from the zipcode and country...	 
-			mvc.bindInputs([this.Zip, this.Country], dojo.hitch(this, this._lookupAddrs));
-			// simple dependence of percentages on input values and total
-			mvc.bindInputs([this.Mortgage, this.Taxes, this.OtherHousing, this.BaseIncome, this.BonusIncome], dojo.hitch(this, this._recomputeTotalAndPercentages));
-
-			mvc.bind(this.HousingPercent, "value", this.HousingPercent, "valid", dojo.hitch(this, this._isHousingLessThanOrEqualToThirtyThreePercent), true);
-
-			mvc.bind(this.HousingPercent, "value", this.HousingPercent, "relevant", dojo.hitch(this, this._nonZeroRelevance), true);
-			mvc.bind(this.TotalHousing, "value", this.TotalHousing, "relevant", dojo.hitch(this, this._nonZeroRelevance), true);
-
-			this._recomputeTotalAndPercentages();  // get things going first time...
-		},
-
-		_lookupItem: function( dataSource, identity ) {
-			var found_item;
-			dataSource.fetchItemByIdentity( { "identity": identity, 
-				"onItem": function (item) { found_item = item; } } );
-			return found_item;
-		},
-
-		_lookupAddrs: function() {
-			if ( this.Zip.get("value") == null || isNaN(this.Zip.get("value"))) return;
-			var pThis = this;
-			var query = { "postalcode": this.Zip.get("value"), "country": this.Country.get("value") };		
-			var xhrArgs = {
-					url: "zips/"+this.Zip.get("value")+".json",
-					sync: true,
-					content: query,
-					preventCache: true,
-					handleAs: "json",
-					load: function(data, io) {
-						pThis.City.set("value", data.postalcodes[0].placeName );
-						pThis.County.set("value", data.postalcodes[0].adminName2 );
-						pThis.State.set("value", data.postalcodes[0].adminCode1 );
-						pThis.Zip.set("valid", true ); 
-					},
-					error: function (data) {
-						// we couldn't find this country/zip combination...clear the fields and set validity=false
-						pThis.City.set("value", "" );
-						pThis.County.set("value", "" );
-						pThis.State.set("value", "" );
-						pThis.Zip.set("valid", false );
-					}
-			};
-			//Call the synchronous xhrGet
-			var deferred = dojo.xhrGet(xhrArgs);	
-		},
-
-		_recomputeTotalAndPercentages: function() {
-			var mortgage = parseInt(this.Mortgage.get("value"));
-			var taxes = parseInt(this.Taxes.get("value"));
-			var otherHousing = parseInt(this.OtherHousing.get("value"));
-			var totalHousing = mortgage + taxes + otherHousing;
-
-			var baseIncome = parseInt(this.BaseIncome.get("value"));
-			var bonusIncome = parseInt(this.BonusIncome.get("value"));
-			var totalIncome = baseIncome + bonusIncome;
-
-			var housingPercentage = Math.round(totalHousing / totalIncome * 100);
-
-			this.HousingPercent.set("value", housingPercentage);
-			this.TotalHousing.set("value", totalHousing);
-			this.TotalIncome.set("value", totalIncome);
-
-			// map the values into the data source structure required for chart display as well...
-			var mortgageItem = this._lookupItem(this.chartStore, "mortgage");
-			var taxesItem = this._lookupItem(this.chartStore, "taxes");
-			var otherItem = this._lookupItem(this.chartStore, "otherhousing");
-			this.chartStore.setValue(mortgageItem, "y", mortgage);
-			this.chartStore.setValue(taxesItem, "y", taxes);
-			this.chartStore.setValue(otherItem, "y", otherHousing);
-		},
-
-		_isHousingLessThanOrEqualToThirtyThreePercent: function(newValue) {
-			return newValue <= 33;
-		},
-
-		_nonZeroRelevance: function(newValue) {
-			if ( newValue > 0 ) return true;
-			else return false;
-		}
-
-	});
-});
diff --git a/dojox/mvc/tests/module.js b/dojox/mvc/tests/module.js
old mode 100755
new mode 100644
index 56fb9e9..175a205
--- a/dojox/mvc/tests/module.js
+++ b/dojox/mvc/tests/module.js
@@ -1,31 +1,77 @@
-dojo.provide("dojox.mvc.tests.module");
+define([
+	"doh/runner",
+	"dojo/_base/sniff",
+	"./doh/atEquals",
+	"./doh/equals",
+	"./doh/wildcard",
+	"./doh/_Controller",
+	"./doh/ModelRefController",
+	"./doh/StoreRefControllerTest",
+	"./doh/WidgetList",
+	"./doh/StatefulArray",
+	"./doh/StatefulModelOptions"
+], function(doh, has){
+	try{
+		var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g, "").replace(/^&/, "?");
 
-try{
-	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
-	// DOH
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_shipto-billto-simple", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_shipto-billto-simple.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_search-results-repeat", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_search-results-repeat.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_search-results-repeat-store", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_search-results-repeat-store.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_programmatic-repeat-store", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_programmatic-repeat-store.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_binding-simple", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_binding-simple.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_ref-set-repeat", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_ref-set-repeat.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_billto-hierarchical", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_shipto-billto-hierarchical.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_async_mvc_input-output-simple", dojo.moduleUrl("dojox.mvc","tests/doh_async_mvc_input-output-simple.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_template_repeat_exprchar", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_template_repeat_exprchar.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_form-kitchensink", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_form-kitchensink.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_date_test", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_date_test.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_validation-test-simple", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_validation-test-simple.html"+userArgs), 999999);
-	// Robot
-	doh.registerUrl("dojox.mvc.tests.robot.mobile-demo-test", dojo.moduleUrl("dojox.mvc","tests/robot/mobile-demo-test.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.mvc_shipto-billto-simple", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_shipto-billto-simple.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.mvc_generate-view", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_generate-view.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.mvc_loan-stateful", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_loan-stateful.html"+userArgs), 999999);
-	//doh.registerUrl("dojox.mvc.tests.robot.mvc_ref-set-repeat", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_ref-set-repeat.html"+userArgs), 999999);
-	//doh.registerUrl("dojox.mvc.tests.robot.mvc_search-results-repeat", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_search-results-repeat.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.mvc_search-results-ins-del", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_search-results-ins-del.html"+userArgs), 999999);
-	//doh.registerUrl("dojox.mvc.tests.robot.iphone_shipto-billto", dojo.moduleUrl("dojox.mvc","tests/robot/iphone_shipto-billto.html"+userArgs), 999999);
-	//doh.registerUrl("dojox.mvc.tests.robot.android_repeat-ins", dojo.moduleUrl("dojox.mvc","tests/robot/android_repeat-ins.html"+userArgs), 999999);
-	//doh.registerUrl("dojox.mvc.tests.robot.mvc_shipto-billto-hierarchical", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_shipto-billto-hierarchical.html"+userArgs), 999999);
-}catch(e){
-	doh.debug(e);
-}
+		// DOH
+		doh.registerUrl("WidgetList_tests.doh_mvc_mobile-demo", require.toUrl("dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_mobile-demo.html" + userArgs), 999999);
+		doh.registerUrl("WidgetList_tests.doh_mvc_DOMNode-search-results-repeat", require.toUrl("dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_DOMNode-search-results-repeat.html" + userArgs), 999999);
+		doh.registerUrl("WidgetList_tests.doh_mvc_new_ref-set-repeat", require.toUrl("dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_new_ref-set-repeat.html" + userArgs), 999999);
+		doh.registerUrl("WidgetList_tests.doh_mvc_performance_search-results-repeat", require.toUrl("dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_performance_search-results-repeat.html" + userArgs), 999999);
+		doh.registerUrl("WidgetList_tests.doh_mvc_programmatic-repeat-store", require.toUrl("dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_programmatic-repeat-store.html" + userArgs), 999999);
+		doh.registerUrl("WidgetList_tests.doh_mvc_repeat_select_cancel", require.toUrl("dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_repeat_select_cancel.html" + userArgs), 999999);
+		doh.registerUrl("WidgetList_tests.doh_mvc_repeat_select_manualsave", require.toUrl("dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_repeat_select_manualsave.html" + userArgs), 999999);
+		doh.registerUrl("WidgetList_tests.doh_mvc_search-results-repeat", require.toUrl("dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_search-results-repeat.html" + userArgs), 999999);
+		doh.registerUrl("WidgetList_tests.doh_mvc_search-results-repeat-store", require.toUrl("dojox/mvc/tests/doh/WidgetList_tests/doh_mvc_search-results-repeat-store.html" + userArgs), 999999);
+		doh.registerUrl("WidgetList_tests.doh_new-mvc_label_and_totals", require.toUrl("dojox/mvc/tests/doh/WidgetList_tests/doh_new-mvc_label_and_totals.html" + userArgs), 999999);
+		
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_new_shipto-billto-simple", require.toUrl("dojox/mvc/tests/doh/doh_mvc_new_shipto-billto-simple.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_new_ref-set-repeat", require.toUrl("dojox/mvc/tests/doh/doh_mvc_new_ref-set-repeat.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.multiattrib.doh_mvc_test_Toolbar", require.toUrl("dojox/mvc/tests/multiattrib/doh_mvc_test_Toolbar.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.multiattrib.doh_mvc_test_Toolbar_withCtrl", require.toUrl("dojox/mvc/tests/multiattrib/doh_mvc_test_Toolbar_withCtrl.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_search-results-repeat", require.toUrl("dojox/mvc/tests/doh/doh_mvc_search-results-repeat.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_new-mvc_input-output-simple", require.toUrl("dojox/mvc/tests/doh/doh_new-mvc_input-output-simple.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_new-mvc_label_and_totals", require.toUrl("dojox/mvc/tests/doh/doh_new-mvc_label_and_totals.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_mobile-demo", require.toUrl("dojox/mvc/tests/doh/doh_mvc_mobile-demo.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_zero-value-test", require.toUrl("dojox/mvc/tests/doh/doh_mvc_zero-value-test.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_binding-simple", require.toUrl("dojox/mvc/tests/doh/doh_mvc_binding-simple.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_shipto-billto-hierarchical", require.toUrl("dojox/mvc/tests/doh/doh_mvc_shipto-billto-hierarchical.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_ref-template-13263", require.toUrl("dojox/mvc/tests/doh/doh_mvc_ref-template-13263.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_async_mvc_14491-input-output", require.toUrl("dojox/mvc/tests/doh/doh_async_mvc_14491-input-output.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_form-kitchensink", require.toUrl("dojox/mvc/tests/doh/doh_mvc_form-kitchensink.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_programmatic-repeat-store", require.toUrl("dojox/mvc/tests/doh/doh_mvc_programmatic-repeat-store.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_search-results-repeat-store", require.toUrl("dojox/mvc/tests/doh/doh_mvc_search-results-repeat-store.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_template_repeat_exprchar", require.toUrl("dojox/mvc/tests/doh/doh_mvc_template_repeat_exprchar.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_validation-test-simple", require.toUrl("dojox/mvc/tests/doh/doh_mvc_validation-test-simple.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_date_test", require.toUrl("dojox/mvc/tests/doh/doh_mvc_date_test.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_repeat_select_manualsave", require.toUrl("dojox/mvc/tests/doh/doh_mvc_repeat_select_manualsave.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_repeat_select_cancel", require.toUrl("dojox/mvc/tests/doh/doh_mvc_repeat_select_cancel.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_sync-test", require.toUrl("dojox/mvc/tests/doh/doh_mvc_sync-test.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.doh_mvc_extension-per-widget", require.toUrl("dojox/mvc/tests/doh/doh_mvc_extension-per-widget.html" + userArgs), 999999);
+		doh.registerUrl("doh_mvc_loan-stateful", require.toUrl("dojox/mvc/tests/doh/doh_mvc_loan-stateful.html" + userArgs), 999999);
+		doh.registerUrl("doh_mvc_DOMNode_shipto-billto-simple", require.toUrl("dojox/mvc/tests/doh/doh_mvc_DOMNode_shipto-billto-simple.html" + userArgs), 999999);
+		doh.registerUrl("doh_mvc_DOMNode-search-results-repeat", require.toUrl("dojox/mvc/tests/doh/doh_mvc_DOMNode-search-results-repeat.html" + userArgs), 999999);
+		doh.registerUrl("doh_mvc_performance_search-results-repeat", require.toUrl("dojox/mvc/tests/doh/doh_mvc_performance_search-results-repeat.html" + userArgs), 999999);
+		// DOH 1.7
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_shipto-billto-simple", require.toUrl("dojox/mvc/tests/1.7/doh/doh_mvc_shipto-billto-simple.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_search-results-repeat", require.toUrl("dojox/mvc/tests/1.7/doh/doh_mvc_search-results-repeat.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_search-results-repeat-store", require.toUrl("dojox/mvc/tests/1.7/doh/doh_mvc_search-results-repeat-store.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_programmatic-repeat-store", require.toUrl("dojox/mvc/tests/1.7/doh/doh_mvc_programmatic-repeat-store.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_binding-simple", require.toUrl("dojox/mvc/tests/1.7/doh/doh_mvc_binding-simple.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_ref-set-repeat", require.toUrl("dojox/mvc/tests/1.7/doh/doh_mvc_ref-set-repeat.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_billto-hierarchical", require.toUrl("dojox/mvc/tests/1.7/doh/doh_mvc_shipto-billto-hierarchical.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_async_mvc_input-output-simple", require.toUrl("dojox/mvc/tests/1.7/doh/doh_async_mvc_input-output-simple.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_async_mvc_zero-value-test", require.toUrl("dojox/mvc/tests/1.7/doh/doh_async_mvc_zero-value-test.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_template_repeat_exprchar", require.toUrl("dojox/mvc/tests/1.7/doh/doh_mvc_template_repeat_exprchar.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_form-kitchensink", require.toUrl("dojox/mvc/tests/1.7/doh/doh_mvc_form-kitchensink.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_date_test", require.toUrl("dojox/mvc/tests/1.7/doh/doh_mvc_date_test.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_mvc_validation-test-simple", require.toUrl("dojox/mvc/tests/1.7/doh/doh_mvc_validation-test-simple.html" + userArgs), 999999);
+		doh.registerUrl("dojox.mvc.tests.1.7.doh_new-mvc_input-output-simple.html", require.toUrl("dojox/mvc/tests/doh/doh_new-mvc_input-output-simple.html" + userArgs), 999999);
+		// Robot 1.7 tests have been removed, coverage is provided with the doh tests, and there 
+		// have been too many problems with the running of the robot tests.
+		// But the robot 1.7 tests are available with the dojox/mvc/tests/1.7/robot/runTestsFullSet.html
+	}catch(e){
+		doh.debug(e);
+	}
+});
diff --git a/dojox/mvc/tests/moduleFullSet.js b/dojox/mvc/tests/moduleFullSet.js
deleted file mode 100644
index a83a79a..0000000
--- a/dojox/mvc/tests/moduleFullSet.js
+++ /dev/null
@@ -1,31 +0,0 @@
-dojo.provide("dojox.mvc.tests.module");
-
-try{
-	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
-	// DOH
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_shipto-billto-simple", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_shipto-billto-simple.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_search-results-repeat", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_search-results-repeat.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_search-results-repeat-store", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_search-results-repeat-store.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_programmatic-repeat-store", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_programmatic-repeat-store.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_binding-simple", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_binding-simple.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_ref-set-repeat", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_ref-set-repeat.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_binding-hierarchical", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_shipto-billto-hierarchical.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_async_mvc_input-output-simple", dojo.moduleUrl("dojox.mvc","tests/doh_async_mvc_input-output-simple.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_template_repeat_exprchar", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_template_repeat_exprchar.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_form-kitchensink", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_form-kitchensink.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_date_test", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_date_test.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.doh_mvc_validation-test-simple", dojo.moduleUrl("dojox.mvc","tests/doh_mvc_validation-test-simple.html"+userArgs), 999999);
-	// Robot
-	doh.registerUrl("dojox.mvc.tests.robot.mobile-demo-test", dojo.moduleUrl("dojox.mvc","tests/robot/mobile-demo-test.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.mvc_shipto-billto-simple", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_shipto-billto-simple.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.mvc_generate-view", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_generate-view.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.mvc_loan-stateful", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_loan-stateful.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.mvc_ref-set-repeat", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_ref-set-repeat.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.mvc_search-results-repeat", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_search-results-repeat.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.mvc_search-results-ins-del", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_search-results-ins-del.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.iphone_shipto-billto", dojo.moduleUrl("dojox.mvc","tests/robot/iphone_shipto-billto.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.android_repeat-ins", dojo.moduleUrl("dojox.mvc","tests/robot/android_repeat-ins.html"+userArgs), 999999);
-	doh.registerUrl("dojox.mvc.tests.robot.mvc_shipto-billto-hierarchical", dojo.moduleUrl("dojox.mvc","tests/robot/mvc_shipto-billto-hierarchical.html"+userArgs), 999999);
-}catch(e){
-	doh.debug(e);
-}
diff --git a/dojox/mvc/tests/multiattrib/doh_mvc_test_Toolbar.html b/dojox/mvc/tests/multiattrib/doh_mvc_test_Toolbar.html
new file mode 100644
index 0000000..430b9d3
--- /dev/null
+++ b/dojox/mvc/tests/multiattrib/doh_mvc_test_Toolbar.html
@@ -0,0 +1,176 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>MVC DOH Toolbar Widget Test</title>
+	<style>
+		@import "../../../../dijit/themes/claro/document.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+
+		.flatScreen {
+			background-image: url(../../../../dijit/tests/images/flatScreen.gif); height: 32px; width: 32px;		
+	</style>
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+
+	<script type="text/javascript">
+		negativeConverter = {
+			format: function(value){ return !value; },
+			parse: function(value){ return !value; }
+		};
+
+		require([
+			"dojox/mvc",
+			"dojo/parser",
+			"dojo/when",
+			"dojox/mvc/_patches",
+			"dijit/Declaration",
+			"dijit/Toolbar",
+			"dijit/ToolbarSeparator",
+			"dijit/form/Button",
+			"dijit/form/DropDownButton",
+			"dijit/form/ComboButton",
+			"dijit/form/ToggleButton",
+			"dijit/ColorPalette",
+			"dijit/TooltipDialog",
+			"dijit/form/TextBox",
+			"dijit/Menu",
+			"dijit/MenuItem",
+			"dijit/form/TextBox",
+			"dijit/form/Select",
+			"dijit/form/CheckBox"
+		], function(mvc, parser, when){
+			(cutItemModel = new dojo.Stateful).set("iconClass", "dijitEditorIcon dijitEditorIconCut");
+			(copyItemModel = new dojo.Stateful).set("iconClass", "dijitEditorIcon dijitEditorIconCopy").set("label", "Copy");
+			boldItemModel = mvc.newStatefulModel({ data : { "checked" : false}});
+				require([
+					'doh/runner', 'dijit/dijit'
+				], function(){
+				require([
+					'dojo/domReady!'
+					], function(){
+
+						doh.register("parse", function() {
+							var dfd = new doh.Deferred();
+							when(dojo.parser.parse(), function(){
+								dfd.callback(true);
+							});
+							return dfd;
+						});
+						// should be able to verify all of the inputs 
+						doh.register("check initial values and bindings", [{
+							name : "initial",
+							runTest : function() {
+								doh.is("Copy", dijit.byId("selCopy").get('value'),"value should be Copy");
+								doh.is("Copy",  dijit.byId("toolbar1.copy").get('label'),"label should be Copy");
+								doh.t(dijit.byId("toolbar1.copy").get('showLabel'),"label should be shown");
+
+								doh.f(dijit.byId("checkBold").get('checked'),"bold checkbox should be false");
+								doh.f(dijit.byId("toolbar1.bold").get('checked'),"bold toolbar should be false");
+
+								doh.t(dijit.byId("checkItalic").get('checked'),"italic checkbox should be true");
+								doh.f(dijit.byId("toolbar1.italic").get('checked'),"italic toolbar should be false");
+							}
+						}]);
+
+						doh.register("update Copy Label", [{
+							name : "Update-First-Name",
+							runTest : function() {
+								var copyLabel, boldToolbar, bold, italic;
+								//test first relevant false
+								copyLabel = dijit.byId("selCopy");
+								if (copyLabel) {
+									copyItemModel.set("label","Copy to clipboard...");
+									doh.is("Copy to clipboard...", dijit.byId("selCopy").get('value'),"value should be Copy to clipboard...");
+									doh.is("Copy to clipboard...",  dijit.byId("toolbar1.copy").get('label'),"label should be Copy to clipboard...");
+								}
+								boldToolbar = dijit.byId("boldtoolbar1.copy");
+								if (boldToolbar) {
+									boldToolbar.set("checked", true);
+									doh.f(dijit.byId("checkBold").get('checked'),"bold checkbox should be false");
+									doh.t(dijit.byId("toolbar1.bold").get('checked'),"bold toolbar should be true");
+								}
+								bold = dijit.byId("checkBold");
+								if (bold) {
+									bold.set("checked",false);
+									doh.f(dijit.byId("checkBold").get('checked'),"bold checkbox should be false");
+									doh.f(dijit.byId("toolbar1.bold").get('checked'),"bold toolbar should be false");
+								}
+								italic = dijit.byId("checkItalic");
+								if (italic) {
+									italic.set("checked",true);
+									doh.t(dijit.byId("checkItalic").get('checked'),"italic checkbox should be false");
+									doh.f(dijit.byId("toolbar1.italic").get('checked'),"italic toolbar should be false");
+								}
+							}
+						}]);
+						doh.run();
+
+					});
+				});	
+		}); 
+		</script>
+</head>
+
+
+	<body class="claro">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1 class="testTitle">Toolbar test</h1>
+
+	<span data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"ToolbarSectionStart", defaults:{ label: "Label"}'>
+		<span data-dojo-type="dijit.ToolbarSeparator"></span><i>${label}:</i>
+	</span>
+
+	<h2>Toolbar from markup</h2>
+
+	<div id="toolbar1" data-dojo-type="dijit.Toolbar"
+			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Buttons"'></div
+			><div id="toolbar1.cut" data-dojo-type="dijit.form.Button" data-dojo-props='showLabel:false, iconClass: at(cutItemModel, "iconClass")'>Cut</div
+			><div id="toolbar1.copy" data-dojo-type="dijit.form.Button" data-dojo-props='showLabel:true, "*": at(copyItemModel, "*")'>Copy</div
+
+			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Toggles"'></div
+			><div id="toolbar1.bold" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBold", showLabel:false, checked: at(boldItemModel, "checked")'>Bold</div
+			><div id="toolbar1.italic" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconItalic", showLabel: true'>Italic</div
+
+></div>
+
+	<div style="margin-top:8px;">
+		Icon for "Cut":
+		<select data-dojo-type="dijit.form.Select" data-dojo-props="value: at(cutItemModel, 'iconClass')">
+			<option value="dijitEditorIcon dijitEditorIconCut">Cut</option>
+			<option value="dijitFolderClosed">Folder</option>
+			<option value="noteIcon">Note</option>
+			<option value="flatScreen">Flat Screen</option>
+		</select>
+	</div>
+
+	<div style="margin-top:8px;">
+		Icon for "Copy":
+		<select data-dojo-type="dijit.form.Select" data-dojo-props="value: at(copyItemModel, 'iconClass')">
+			<option value="dijitEditorIcon dijitEditorIconCopy">Copy</option>
+			<option value="dijitFolderClosed">Folder</option>
+			<option value="noteIcon">Note</option>
+			<option value="flatScreen">Flat Screen</option>
+		</select>
+	</div>
+
+	<div style="margin-top:8px;">
+		Label for "Copy":
+		<select id="selCopy" data-dojo-type="dijit.form.Select" data-dojo-props="value: at(copyItemModel, 'label')">
+			<option value="Copy">Copy</option>
+			<option value="Copy to clipboard...">Copy to clipboard...</option>
+		</select>
+	</div>
+
+	<div style="margin-top:8px;">
+		Change the state for "Bold" (but this check box is free from change in the tool bar):
+		<input id="checkBold" data-dojo-type="dijit.form.CheckBox" checked data-dojo-props="checked: at(boldItemModel, 'checked').direction(at.to)">
+	</div>
+
+	<div style="margin-top:8px;">
+		"Italic" should be unselected (directly bound to the tool bar item widget):
+		<input id="checkItalic" data-dojo-type="dijit.form.CheckBox" checked data-dojo-props="checked: at(dijit.byId('toolbar1.italic'), 'checked').transform(negativeConverter)">
+	</div>
+  </body>
+
+</html>
diff --git a/dojox/mvc/tests/multiattrib/doh_mvc_test_Toolbar_withCtrl.html b/dojox/mvc/tests/multiattrib/doh_mvc_test_Toolbar_withCtrl.html
new file mode 100644
index 0000000..0fc5fa9
--- /dev/null
+++ b/dojox/mvc/tests/multiattrib/doh_mvc_test_Toolbar_withCtrl.html
@@ -0,0 +1,170 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC DOH Toolbar Widget Test</title>
+		<style>
+			@import "../../../../dijit/themes/claro/document.css";
+			@import "../../../../dijit/tests/css/dijitTests.css";
+	
+			.flatScreen {
+				background-image: url(../../../../dijit/tests/images/flatScreen.gif); height: 32px; width: 32px;		
+		</style>
+		<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../../dojo/dojo.js"></script>
+	
+		<script type="text/javascript">
+			negativeConverter = {
+				format: function(value){ return !value; },
+				parse: function(value){ return !value; }
+			};
+	
+			require([
+				"doh/runner",
+				"dojo/parser",
+				"dojo/when",
+				"dojo/Stateful",
+				"dojox/mvc/ModelRefController",
+				"dojox/mvc/_patches",
+				"dijit/Declaration",
+				"dijit/Toolbar",
+				"dijit/ToolbarSeparator",
+				"dijit/form/Button",
+				"dijit/form/DropDownButton",
+				"dijit/form/ComboButton",
+				"dijit/form/ToggleButton",
+				"dijit/ColorPalette",
+				"dijit/TooltipDialog",
+				"dijit/form/TextBox",
+				"dijit/Menu",
+				"dijit/MenuItem",
+				"dijit/form/TextBox",
+				"dijit/form/Select",
+				"dijit/form/CheckBox",
+				"dojo/domReady!"
+			], function(doh, parser, when, Stateful, ModelRefController){
+	
+				cutItemCtrl = new ModelRefController();
+				copyItemCtrl = new ModelRefController();
+				boldItemCtrl = new ModelRefController();
+
+				when(parser.parse(), function(){
+					cutItemCtrl.set("model", new Stateful({iconClass: "dijitEditorIcon dijitEditorIconCut"}));
+					copyItemCtrl.set("model", new Stateful({iconClass: "dijitEditorIcon dijitEditorIconCopy", label: "Copy"}));
+					boldItemCtrl.set("model", new Stateful({checked: false}));
+		
+					// should be able to verify all of the inputs 
+					doh.register("check initial values and bindings", [{
+						name : "initial",
+						runTest : function() {
+							doh.is("Copy", dijit.byId("selCopy").get('value'),"value should be Copy");
+							doh.is("Copy",  dijit.byId("toolbar1.copy").get('label'),"label should be Copy");
+							doh.t(dijit.byId("toolbar1.copy").get('showLabel'),"label should be shown");
+
+							doh.f(dijit.byId("checkBold").get('checked'),"bold checkbox should be false");
+							doh.f(dijit.byId("toolbar1.bold").get('checked'),"bold toolbar should be false");
+
+							doh.t(dijit.byId("checkItalic").get('checked'),"italic checkbox should be true");
+							doh.f(dijit.byId("toolbar1.italic").get('checked'),"italic toolbar should be false");
+						}
+					}]);
+
+					doh.register("update Copy Label", [{
+						name : "Update-First-Name",
+						runTest : function() {
+							var copyLabel, boldToolbar, bold, italic;
+							//test first relevant false
+							copyLabel = dijit.byId("selCopy");
+							if (copyLabel) {
+								copyItemCtrl.set("label","Copy to clipboard...");
+								doh.is("Copy to clipboard...", dijit.byId("selCopy").get('value'),"value should be Copy to clipboard...");
+								doh.is("Copy to clipboard...",  dijit.byId("toolbar1.copy").get('label'),"label should be Copy to clipboard...");
+							}
+							boldToolbar = dijit.byId("boldtoolbar1.copy");
+							if (boldToolbar) {
+								boldToolbar.set("checked", true);
+								doh.f(dijit.byId("checkBold").get('checked'),"bold checkbox should be false");
+								doh.t(dijit.byId("toolbar1.bold").get('checked'),"bold toolbar should be true");
+							}
+							bold = dijit.byId("checkBold");
+							if (bold) {
+								bold.set("checked",false);
+								doh.f(dijit.byId("checkBold").get('checked'),"bold checkbox should be false");
+								doh.f(dijit.byId("toolbar1.bold").get('checked'),"bold toolbar should be false");
+							}
+							italic = dijit.byId("checkItalic");
+							if (italic) {
+								italic.set("checked",true);
+								doh.t(dijit.byId("checkItalic").get('checked'),"italic checkbox should be false");
+								doh.f(dijit.byId("toolbar1.italic").get('checked'),"italic toolbar should be false");
+							}
+						}
+					}]);
+
+					doh.run();
+				});
+			}); 
+		</script>
+	</head>
+
+	<body class="claro">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1 class="testTitle">Toolbar test</h1>
+
+	<span data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"ToolbarSectionStart", defaults:{ label: "Label"}'>
+		<span data-dojo-type="dijit.ToolbarSeparator"></span><i>${label}:</i>
+	</span>
+
+	<h2>Toolbar from markup</h2>
+
+	<div id="toolbar1" data-dojo-type="dijit.Toolbar"
+			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Buttons"'></div
+			><div id="toolbar1.cut" data-dojo-type="dijit.form.Button" data-dojo-props='showLabel:false, iconClass: at(cutItemCtrl, "iconClass")'>Cut</div
+			><div id="toolbar1.copy" data-dojo-type="dijit.form.Button" data-dojo-props='showLabel:true, "*": at(copyItemCtrl, "*")'>Copy</div
+
+			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Toggles"'></div
+			><div id="toolbar1.bold" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBold", showLabel:false, checked: at(boldItemCtrl, "checked")'>Bold</div
+			><div id="toolbar1.italic" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconItalic", showLabel: true'>Italic</div
+
+></div>
+
+	<div style="margin-top:8px;">
+		Icon for "Cut":
+		<select data-dojo-type="dijit.form.Select" data-dojo-props="value: at(cutItemCtrl, 'iconClass')">
+			<option value="dijitEditorIcon dijitEditorIconCut">Cut</option>
+			<option value="dijitFolderClosed">Folder</option>
+			<option value="noteIcon">Note</option>
+			<option value="flatScreen">Flat Screen</option>
+		</select>
+	</div>
+
+	<div style="margin-top:8px;">
+		Icon for "Copy":
+		<select data-dojo-type="dijit.form.Select" data-dojo-props="value: at(copyItemCtrl, 'iconClass')">
+			<option value="dijitEditorIcon dijitEditorIconCopy">Copy</option>
+			<option value="dijitFolderClosed">Folder</option>
+			<option value="noteIcon">Note</option>
+			<option value="flatScreen">Flat Screen</option>
+		</select>
+	</div>
+
+	<div style="margin-top:8px;">
+		Label for "Copy":
+		<select id="selCopy" data-dojo-type="dijit.form.Select" data-dojo-props="value: at(copyItemCtrl, 'label')">
+			<option value="Copy">Copy</option>
+			<option value="Copy to clipboard...">Copy to clipboard...</option>
+		</select>
+	</div>
+
+	<div style="margin-top:8px;">
+		Change the state for "Bold" (but this check box is free from change in the tool bar):
+		<input id="checkBold" data-dojo-type="dijit.form.CheckBox" checked data-dojo-props="checked: at(boldItemCtrl, 'checked').direction(at.to)">
+	</div>
+
+	<div style="margin-top:8px;">
+		"Italic" should be unselected (directly bound to the tool bar item widget):
+		<input id="checkItalic" data-dojo-type="dijit.form.CheckBox" checked data-dojo-props="checked: at(dijit.byId('toolbar1.italic'), 'checked').transform(negativeConverter)">
+	</div>
+  </body>
+
+</html>
diff --git a/dojox/mvc/tests/multiattrib/test_Toolbar.html b/dojox/mvc/tests/multiattrib/test_Toolbar.html
new file mode 100644
index 0000000..ce6de78
--- /dev/null
+++ b/dojox/mvc/tests/multiattrib/test_Toolbar.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo Toolbar Widget Test</title>
+
+	<style type="text/css">
+		@import "../../../../dijit/themes/claro/document.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+
+		.flatScreen {
+			background-image: url(../../../../dijit/tests/images/flatScreen.gif); height: 32px; width: 32px;
+		}
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		negativeConverter = {
+			format: function(value){ return !value },
+			parse: function(value){ return !value }
+		};
+
+		require([
+			"dojox",
+			"dojo/parser",
+			"dijit/Declaration",
+			"dijit/Toolbar",
+			"dijit/ToolbarSeparator",
+			"dijit/form/Button",
+			"dijit/form/DropDownButton",
+			"dijit/form/ComboButton",
+			"dijit/form/ToggleButton",
+			"dijit/ColorPalette",
+			"dijit/TooltipDialog",
+			"dijit/form/TextBox",
+			"dijit/Menu",
+			"dijit/MenuItem",
+			"dijit/form/TextBox",
+			"dijit/form/Select",
+			"dijit/form/CheckBox"
+		], function(dojox, parser){
+			(cutItemModel = new dojo.Stateful).set("iconClass", "dijitEditorIcon dijitEditorIconCut");
+			(copyItemModel = new dojo.Stateful).set("iconClass", "dijitEditorIcon dijitEditorIconCopy").set("label", "Copy");
+			(boldItemModel = new dojo.Stateful).set("checked", false);
+			parser.parse();
+		});
+	</script>
+</head>
+<body class="claro">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1 class="testTitle">Toolbar test</h1>
+
+	<span data-dojo-type="dijit.Declaration" 
+			data-dojo-props='widgetClass:"ToolbarSectionStart", defaults:{ label: "Label"}'>
+		<span data-dojo-type="dijit.ToolbarSeparator"></span><i>${label}:</i>
+	</span>
+
+	<h2>Toolbar from markup</h2>
+
+	<div id="toolbar1" data-dojo-type="dijit.Toolbar"
+			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Buttons"'></div
+			><div id="toolbar1.cut" data-dojo-type="dijit.form.Button" data-dojo-props='showLabel:false, iconClass: at(cutItemModel, "iconClass")'>Cut</div
+			><div id="toolbar1.copy" data-dojo-type="dijit.form.Button" 
+					data-dojo-props='showLabel:true, "*": at(copyItemModel, "*")'>Copy</div
+
+			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Toggles"'></div
+			><div id="toolbar1.bold" data-dojo-type="dijit.form.ToggleButton" 
+					data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBold", showLabel:false, checked: at(boldItemModel, "checked")'>Bold</div
+			><div id="toolbar1.italic" data-dojo-type="dijit.form.ToggleButton" 
+					data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconItalic", showLabel: true'>Italic</div
+
+></div>
+
+	<div style="margin-top:8px;">
+		Icon for "Cut":
+		<select data-dojo-type="dijit.form.Select" 
+				data-dojo-props="value: at(cutItemModel, 'iconClass')">
+			<option value="dijitEditorIcon dijitEditorIconCut">Cut</option>
+			<option value="dijitFolderClosed">Folder</option>
+			<option value="noteIcon">Note</option>
+			<option value="flatScreen">Flat Screen</option>
+		</select>
+	</div>
+
+	<div style="margin-top:8px;">
+		Icon for "Copy":
+		<select data-dojo-type="dijit.form.Select" 
+				data-dojo-props="value: at(copyItemModel, 'iconClass')">
+			<option value="dijitEditorIcon dijitEditorIconCopy">Copy</option>
+			<option value="dijitFolderClosed">Folder</option>
+			<option value="noteIcon">Note</option>
+			<option value="flatScreen">Flat Screen</option>
+		</select>
+	</div>
+
+	<div style="margin-top:8px;">
+		Label for "Copy":
+		<select data-dojo-type="dijit.form.Select" 
+				data-dojo-props="value: at(copyItemModel, 'label')">
+			<option value="Copy">Copy</option>
+			<option value="Copy to clipboard...">Copy to clipboard...</option>
+		</select>
+	</div>
+
+	<div style="margin-top:8px;">
+		Change the state for "Bold" (but this check box is free from change in the tool bar):
+		<input data-dojo-type="dijit.form.CheckBox" checked 
+				data-dojo-props="checked: at(boldItemModel, 'checked').direction(at.to)">
+	</div>
+
+	<div style="margin-top:8px;">
+		"Italic" should be unselected (directly bound to the tool bar item widget):
+		<input data-dojo-type="dijit.form.CheckBox" checked 
+				data-dojo-props="checked: at(dijit.byId('toolbar1.italic'), 'checked').transform(negativeConverter)">
+	</div>
+  </body>
+</html>
diff --git a/dojox/mvc/tests/multiattrib/test_mvc_ref-set-repeat-multiattrib.html b/dojox/mvc/tests/multiattrib/test_mvc_ref-set-repeat-multiattrib.html
new file mode 100644
index 0000000..39a2a02
--- /dev/null
+++ b/dojox/mvc/tests/multiattrib/test_mvc_ref-set-repeat-multiattrib.html
@@ -0,0 +1,212 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>MVC Repeat with Multiattribute Test</title>
+
+	<style type="text/css">
+		@import "../../../../dijit/themes/claro/document.css";
+		@import "../../../../dijit/tests/css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox",
+			"dojox/mvc",
+			"dojo/parser",
+			"dojo/store/Memory",
+			"dojox/mvc/at",
+			"dojox/mvc/_patches",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat",
+			"dojox/mvc/Output",
+			"dijit/form/Button",
+			"dijit/form/DropDownButton",
+			"dijit/form/ComboButton",
+			"dijit/form/ToggleButton",
+			"dijit/ColorPalette",
+			"dijit/TooltipDialog",
+			"dijit/form/TextBox",
+			"dijit/Menu",
+			"dijit/MenuItem",
+			"dijit/form/TextBox",
+			"dijit/form/Select",
+			"dijit/form/CheckBox"
+		], function(dojox, mvc, parser, MemoryStore, at){
+			//(cutItemModel = new dojo.Stateful).set("iconClass", "dijitEditorIcon dijitEditorIconCut");
+			//(copyItemModel = new dojo.Stateful).set("iconClass", "dijitEditorIcon dijitEditorIconCopy").set("label", "Copy");
+			//(boldItemModel = new dojo.Stateful).set("checked", false);
+//			window.at = at;
+
+			var search_results_init1 =
+			[{
+				"Query" : "Engineers1",
+				"Results" : [
+					{
+						"First"	  : "Anne1",
+						"Last"	  : "Ackerman1",
+						"Checked" : true
+					},
+					{
+						"First"	  : "Ben1",
+						"Last"	  : "Beckham1",
+						"Checked" : false
+					},
+					{
+						"First"	  : "Chad1",
+						"Last"	  : "Chapman1",
+						"Checked" : true
+					}
+				]
+			}];
+			var search_results_init2 =
+			[{
+				"Query" : "Engineers2",
+				"Results" : [
+					{
+						"First"	  : "Anne2",
+						"Last"	  : "Ackerman2",
+						"Checked" : true
+					},
+					{
+						"First"	  : "Ben2",
+						"Last"	  : "Beckham2",
+						"Checked" : false
+					}
+				]
+			}];
+			var search_results_init3 =
+			[{
+				"Query" : "Engineers3",
+				"Results" : [
+					{
+						"First"	  : "",
+						"Last"	  : "",
+						"Checked" : true
+					}
+				]
+			}];
+
+			var memStore1 = new MemoryStore({data : search_results_init1});
+			model1 = mvc.newStatefulModel({ store : memStore1 })[0];
+			var memStore2 = new MemoryStore({data : search_results_init2});
+			model2 = mvc.newStatefulModel({ store : memStore2 })[0];
+			var memStore3 = new MemoryStore({data : search_results_init3});
+			model3 = mvc.newStatefulModel({ store : memStore3 })[0];
+			
+			parser.parse();
+		});
+	</script>
+</head>
+<body class="claro">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="row">
+						<button type="button" data-dojo-type="dijit/form/Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model1);}">Swap Model1</button>
+						<button type="button" data-dojo-type="dijit/form/Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model2);}">Swap Model2</button>
+						<button type="button" data-dojo-type="dijit/form/Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('target',at(model3));}">Swap Model3</button>
+					</div>
+					<div id="outergroupId"	 data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('model1')">
+						<div id="repeatId" data-dojo-type="dojox/mvc/Repeat" data-dojo-props="children: at('rel:', 'Results')">
+							<div class="row" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:${this.index}')">
+								<input class="cell" data-dojo-type="dijit/form/CheckBox" id="CBInput${this.index}" data-dojo-props="checked: at('rel:Checked', 'value')"/>
+								<label data-dojo-type="dojox/mvc/Output" for="CBInput${this.index}" data-dojo-props="ref: 'First'"></label>
+					<!--  		<label for="CBInput${this.index}" data-dojo-props="ref: 'First'">LABEL(firstname)->${model1.Results[this.index].First}</label>-->	
+								<input class="cell" data-dojo-type="dijit/form/TextBox" id="nameInput${this.index}" data-dojo-props="value: at('rel:First', 'value')"/>
+								<input class="cell" data-dojo-type="dijit/form/TextBox" id="nameInputLast${this.index}" data-dojo-props="value: at('Last', 'value')"/>
+							</div>
+						</div>
+					</div>
+					<div class="row">
+							<span>
+								Model1 Output is ==>  
+							</span>
+							<span id="CBOutput10" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model1.Results[0].Checked">
+								Checked1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput10" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model1.Results[0].First">
+								First1 is "${this.value}" : 
+							</span>
+							<span id="lastnameOutput10" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model1.Results[0].Last">
+								Last1 is "${this.value}" : 
+							</span>
+							<span id="CBOutput11" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model1.Results[1].Checked">
+								Checked2 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput11" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model1.Results[1].First">
+								First2 is "${this.value}" : 
+							</span>
+							<span id="lastnameOutput11" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model1.Results[1].Last">
+								Last2 is "${this.value}" : 
+							</span>
+							<span id="CBOutput12" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model1.Results[2].Checked">
+								Checked3 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput12" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model1.Results[2].First">
+								First3 is "${this.value}" : 
+							</span>
+							<span id="lastnameOutput12" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model1.Results[2].Last">
+								Last3 is "${this.value}"
+							</span>
+					</div>
+					<div class="row">
+							<span>
+								Model2 Output is ==>  
+							</span>
+							<span id="CBOutput20" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model2.Results[0].Checked">
+								Checked1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput20" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model2.Results[0].First">
+								First1 is "${this.value}" : 
+							</span>
+							<span id="lastnameOutput20" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model2.Results[0].Last">
+								Last1 is "${this.value}" : 
+							</span>
+							<span id="CBOutput21" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model2.Results[1].Checked">
+								Checked2 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput21" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model2.Results[1].First">
+								First2 is "${this.value}" : 
+							</span>
+							<span id="lastnameOutput21" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model2.Results[1].Last">
+								Last2 is "${this.value}"
+							</span>
+					</div>
+					<div class="row">
+							<span>
+								Model3 Output is ==>  
+							</span>
+							<span id="CBOutput30" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model3.Results[0].Checked">
+								Checked1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput30" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model3.Results[0].First">
+								First1 is "${this.value}" :
+							</span>
+							<span id="lastnameOutput30" data-dojo-type="dojox/mvc/Output" data-dojo-props="ref: model3.Results[0].Last">
+								Last1 is "${this.value}"
+							</span>
+					</div>
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit/form/Button" data-dojo-props="onClick: function(){model1.reset();model2.reset();model3.reset();}">Reset all</button>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/mvc_index.html b/dojox/mvc/tests/mvc_index.html
old mode 100755
new mode 100644
index 66896c9..6f8dbf5
--- a/dojox/mvc/tests/mvc_index.html
+++ b/dojox/mvc/tests/mvc_index.html
@@ -9,13 +9,22 @@
 		<h2>Examples</h2>
 		<p>
 			<dl>
-				<dt><a href="test_mvc_shipto-billto-simple.html">Simple data-bound fields</a></dt>
+				<dt><a href="test_async-mvc_input-output-simple.html">Simple data-bound fields</a></dt>
+				<dd>Simple of data binding -- no hierarchical or repeating structure nor model validation...just data binding.</dd>
+
+				<dt><a href="test_async-mvc_group-simple.html">2nd Simple data-bound fields</a></dt>
+				<dd>"Another simple of data binding -- this one is using EditModelRefController for Reset support.</dd>
+
+				<dt><a href="test_mvc_shipto-billto-simple.html">Ship to Bill to example</a></dt>
 				<dd>"Hello world" of data binding -- no hierarchical or repeating structure nor model validation...just data binding.</dd>
 
-				<dt><a href="test_mvc_shipto-billto-hierarchical.html">Hierarchical data-bound fields</a></dt>
+				<dt><a href="test_mvc_new_shipto-billto-simple.html">Hierarchical data-bound fields</a></dt>
 				<dd>Widgets are nested hierarchically showing relative binding context.</dd>
 
-				<dt><a href="test_mvc_loan-stateful.html">Data-bound form fields</a></dt>
+				<dt><a href="multiattrib/test_Toolbar.html">Bindings using multiple attributes.</a></dt>
+				<dd>The icons and labels in the toolbar are bound to the widgets on the page, also uses single direction binding and a converter.</dd>
+
+				<dt><a href="test_mvc_new_loan-stateful.html">Data-bound form fields</a></dt>
 				<dd>Form widgets bind to model data and merge model and widget states (e.g. validity) to determine overall status.
 				Data is provided for zipcodes of 10024 or 10706 to see side-effects on completing related fields.  Try other 5-digit numeric values
 				to see the effect of model-flagged invalidity on the widget.  Non-numeric fields trigger widget validation
diff --git a/dojox/mvc/tests/robot/android_repeat-ins.html b/dojox/mvc/tests/robot/android_repeat-ins.html
deleted file mode 100755
index 34b04cb..0000000
--- a/dojox/mvc/tests/robot/android_repeat-ins.html
+++ /dev/null
@@ -1,171 +0,0 @@
-<!DOCTYPE html>
-<html>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>doh.robot MVC search-results-ins-del Test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<script type="text/javascript" src="../helpers.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../mobile/test_Android-repeat-data-store.html');
-
-				doh.register("on_test_MVC_Search_Results_Repeat", [
-					 {
-						name: "initial conditions",
-						timeout: 9000,
-						runTest: function(){
-						var d = new doh.Deferred();
-						console.debug("dojo.version() is "+dojo.version);
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is("Chad", dijit.byId("nameInput0").get('value'),"nameInput0 should be Chad");
-							doh.is("Hunter", dijit.byId("nameInput1").get('value'),"nameInput1 should be Hunter");
-							doh.is("John", dijit.byId("nameInput2").get('value'),"nameInput2 should be John");
-							doh.is("Chad", dijit.byId("firstInput").get('value'),"firstInput should be Chad");
-							doh.is("Chapman", dijit.byId("lastInput").get('value'),"lastInput should be Chapman");
-							doh.is("c.c at test.com", dijit.byId("emailInput").get('value'),"emailInput should be c.c at test.com");
-						}), 1000);
-						return d;
-						}
-					 },
-					{
-						name: "selectHunter",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("details1", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Hunter", dijit.byId("firstInput").get('value'),"firstInput should be Hunter");
-								doh.is("Huffman", dijit.byId("lastInput").get('value'),"lastInput should be Huffman");
-								doh.is("h.h at test.com", dijit.byId("emailInput").get('value'),"emailInput should be h.h at test.com");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "selectJohn",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("details2", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("John", dijit.byId("firstInput").get('value'),"firstInput should be John");
-								doh.is("Jacklin", dijit.byId("lastInput").get('value'),"lastInput should be Jacklin");
-								doh.is("j.j at test.com", dijit.byId("emailInput").get('value'),"emailInput should be j.j at test.com");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "changeJohn",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("firstInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.typeKeys("Johnny", 1000, 2000);													  
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Johnny", dijit.byId("firstInput").get('value'),"firstInput should be Johnny");
-								doh.is("Johnny", dijit.byId("nameInput2").get('value'),"nameInput2 should be Johnny");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "changeHunter",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("details1", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("nameInput1", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.typeKeys("Howard", 500, 1000);													 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Howard", dijit.byId("firstInput").get('value'),"check for firstInput set to Howard");
-								doh.is("Howard", dijit.byId("nameInput1").get('value'),"check for nameInput1 set to Howard");
-							}), 1500);
-							return d;
-						}
-					},
-					{
-						name: "AddKen",
-						timeout: 20000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							//doh.robot.mouseMoveAt("dijit_form_Button_29", 500, 0);
-							//doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("add", 2000, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("firstInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.typeKeys("Ken", 500, 1000);													  
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("Kelly", 500, 1000);														
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							//doh.robot.typeKeys("CA", 500, 1000);													   
-							//doh.robot.keyPress(dojo.keys.TAB, 500, {});  
-							//doh.robot.typeKeys("5623", 500, 1000);													 
-							//doh.robot.keyPress(dojo.keys.TAB, 500, {});  
-							doh.robot.typeKeys("k.k at test.com", 500, 1000);													   
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("408-764-3454", 500, 1000);													   
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("408-764-6000", 500, 1000);													   
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Ken", dijit.byId("firstInput").get('value'),"firstInput should be Ken");
-								doh.is("Ken", dijit.byId("nameInput3").get('value'),"nameInput4 should be Ken");
-								doh.is("Kelly", dijit.byId("lastInput").get('value'),"lastInput should be set");
-								//doh.is("CA", dijit.byId("locationInput").get('value'),"locationInput should be set");
-								//doh.is("5623", dijit.byId("officeInput").get('value'),"officeInput should be set");
-								doh.is("k.k at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
-								doh.is("408-764-3454", dijit.byId("telInput").get('value'),"telInput should be set");
-								doh.is("408-764-6000", dijit.byId("faxInput").get('value'),"faxInput should be set");
-							}), 1000);
-							return d;
-						}
-					}				]);
-				doh.run();
-			});
-		</script>
-</html>
diff --git a/dojox/mvc/tests/robot/iphone_shipto-billto.html b/dojox/mvc/tests/robot/iphone_shipto-billto.html
deleted file mode 100755
index a479fa4..0000000
--- a/dojox/mvc/tests/robot/iphone_shipto-billto.html
+++ /dev/null
@@ -1,102 +0,0 @@
-<!DOCTYPE html>
-<html>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>doh.robot MVC demo-shipto-billto-simple Declarative Test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<script type="text/javascript" src="../helpers.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../mobile/test_iPhone-shipto-billto.html');
-
-				doh.register("test_iPhone_SimpleDataBoundField", [															   
-					{
-						name: "initial conditions",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							console.debug("dojo.version() is "+dojo.version);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								//"ShipTo" selected 
-								doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					 },
-					 {						
-						name: "billto",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("billto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								//"BillTo" selected 
-								doh.is("17 Skyline Dr", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "shipto",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("shipto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								//"ShipTo" selected 
-								doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					},					
-					{
-						name: "changeShipToAddress",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("cityInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});							
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
-							
-							doh.robot.typeKeys("456 Mountain Rd", 500, 1000);							
-							
-							doh.robot.mouseMoveAt("billto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("shipto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("streetInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-</html>
diff --git a/dojox/mvc/tests/robot/mobile-demo-test.html b/dojox/mvc/tests/robot/mobile-demo-test.html
deleted file mode 100644
index 0289b85..0000000
--- a/dojox/mvc/tests/robot/mobile-demo-test.html
+++ /dev/null
@@ -1,404 +0,0 @@
-<!DOCTYPE html>
-<html>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>doh.robot MVC demo-shipto-billto-simple Declarative Test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<!-- <script type="text/javascript" src="../helpers.js"></script>  -->
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../mobile/demo/demo.html');
-
-				doh.register("test_Mobile-Demo", [															   
-					{
-						name: "initial conditions",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							console.debug("dojo.version() is "+dojo.version);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								//"ShipTo" selected 
-								//doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					 },
-					 {						
-						name: "testSimpleDataBinding",
-						timeout: 18000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("sdb", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseMoveAt("cityInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});							
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
-							
-							doh.robot.typeKeys("456 Mountain Rd", 300, 800);							
-							doh.robot.keyPress(dojo.keys.TAB, 300, {shift:true});							
-							
-							doh.robot.mouseMoveAt("billto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("shipto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("streetInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								var w = dijit.byId("streetInput");
-								var v  = w.get('value');
-								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							
-						//	doh.robot.sequence(d.getTestCallback(function(){
-								//"SendTo" selected 
-								//"BillTo" selected 
-						//		doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-								//doh.is("17 Skyline Dr", dijit.byId("streetInput").get('value'),"streetInput should be set");
-						//	}), 1000);
-							return d;
-						}
-					},
-					 {						
-						name: "testSimpleDataBinding - billTo",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("billto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								//"BillTo" selected 
-								doh.is("17 Skyline Dr", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "shipto",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("shipto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								//"ShipTo" selected 
-								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					},					
-/*					{
-						name: "changeShipToAddress",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("cityInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});							
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
-							
-							doh.robot.typeKeys("456 Mountain Rd", 500, 1000);							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});							
-							
-							doh.robot.mouseMoveAt("billto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("shipto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("streetInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								var w = dijit.byId("streetInput");
-								var v  = w.get('value');
-								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					 },
-				*/ 
-					 {						
-						name: "testRepeatDataBinding",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							//doh.robot.mouseMoveAt("home", 500, 0);
-							var t1 = dojo.query('.mblArrowButtonBody')[0];
-							doh.robot.mouseMoveAt(dojo.query('.mblArrowButtonBody')[0], 500);							
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("rdb", 1500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-							doh.is("Chad", dijit.byId("nameInput0").get('value'),"nameInput0 should be Chad");
-							doh.is("Irene", dijit.byId("nameInput1").get('value'),"nameInput1 should be Irene");
-							doh.is("John", dijit.byId("nameInput2").get('value'),"nameInput2 should be John");
-							doh.is("Chad", dijit.byId("firstInput").get('value'),"firstInput should be Chad");
-							doh.is("Chapman", dijit.byId("lastInput").get('value'),"lastInput should be Chapman");
-							doh.is("c.c at test.com", dijit.byId("emailInput2").get('value'),"emailInput2 should be c.c at test.com");
-							}), 1000);
-							
-							return d;
-						}
-					},
-			/*		{
-						name: "selectIrene",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("details1", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Irene", dijit.byId("firstInput").get('value'),"firstInput should be Irene");
-								doh.is("Ira", dijit.byId("lastInput").get('value'),"lastInput should be Ira");
-								doh.is("i.i at test.com", dijit.byId("emailInput2").get('value'),"emailInput2 should be h.h at test.com");
-							}), 1000);
-							return d;
-						}
-					},
-			*/		
-					{
-						name: "selectJohn",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("details2", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("John", dijit.byId("firstInput").get('value'),"firstInput should be John");
-								doh.is("Jacklin", dijit.byId("lastInput").get('value'),"lastInput should be Jacklin");
-								doh.is("j.j at test.com", dijit.byId("emailInput2").get('value'),"emailInput2 should be j.j at test.com");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "changeJohn",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("firstInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.typeKeys("Johnny", 1000, 2000);													  
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Johnny", dijit.byId("firstInput").get('value'),"firstInput should be Johnny");
-								doh.is("Johnny", dijit.byId("nameInput2").get('value'),"nameInput2 should be Johnny");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "changeIrene",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("details1", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("nameInput1", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.typeKeys("Howard", 300, 800);													 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Howard", dijit.byId("firstInput").get('value'),"check for firstInput set to Howard");
-								doh.is("Howard", dijit.byId("nameInput1").get('value'),"check for nameInput1 set to Howard");
-							}), 1500);
-							return d;
-						}
-					},
-					{
-						name: "AddKen",
-						timeout: 20000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							//doh.robot.mouseMoveAt("dijit_form_Button_29", 500, 0);
-							//doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("add", 1000, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("firstInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.typeKeys("Ken", 300, 600);													  
-							doh.robot.keyPress(dojo.keys.TAB, 300, {});	 
-							doh.robot.typeKeys("Kelly", 300, 600);														
-							doh.robot.keyPress(dojo.keys.TAB, 300, {});	 
-							doh.robot.typeKeys("k.k at test.com", 300, 600);													   
-							doh.robot.keyPress(dojo.keys.TAB, 300, {});	 
-							doh.robot.typeKeys("408-764-3454", 300, 600);													   
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Ken", dijit.byId("firstInput").get('value'),"firstInput should be Ken");
-								doh.is("Ken", dijit.byId("nameInput3").get('value'),"nameInput4 should be Ken");
-								doh.is("Kelly", dijit.byId("lastInput").get('value'),"lastInput should be set");
-								doh.is("k.k at test.com", dijit.byId("emailInput2").get('value'),"emailInput2 should be set");
-								doh.is("408-764-3454", dijit.byId("telInput").get('value'),"telInput should be set");
-							}), 1000);
-							return d;
-						}
-				
-					 },
-				
-					 {						
-						name: "testGenerateDataBinding",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							// move back to Home
-							doh.robot.mouseMoveAt(dojo.query('.mblArrowButtonBody')[1], 500);							
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("sfg", 1000, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("generate1", 1000, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("11111", dijit.byId("TB0").get('value'),"TB0 should be set");
-								doh.is("John", dijit.byId("TB1").get('value'),"TB1 should be set");
-								doh.is("Doe", dijit.byId("TB2").get('value'),"TB2 should be set");
-								doh.is("jdoe at example.com", dijit.byId("TB3").get('value'),"TB3 should be set");			
-							}), 1000);
-							
-							return d;
-						}
-					},
-					{
-						name: "changeJohnGenerate", 
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("TB1", 500, 0); //updateModel
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 100, {});						  
-							doh.robot.typeKeys("Johnny", 200, 800);													  
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Johnny", dijit.byId("TB1").get('value'),"TB1 should be Johnny");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "updateModelGenerate", 
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("updateModel", 500, 0); 
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.keyPress(dojo.keys.TAB, 1000, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								var ttt = dijit.byId("modelArea").get('value');
-								var txa = ttt.substring(33,39);
-								if (txa !== "Johnny"){ //IE has a diff offset
-									txa = ttt.substring(35,41);
-								}
-								doh.is("Johnny", txa,"textarea should have Johnny");
-							}), 2000);
-							return d;
-						}
-					},
-					{
-						name: "updateFormGenerate", 
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var ttt2 = dijit.byId("modelArea2").get('value');
-							dijit.byId("modelArea").set('value',ttt2);
-							
-							doh.robot.mouseMoveAt("generate1", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("11111", dijit.byId("TB0").get('value'),"TB0 should be set");
-								doh.is("John", dijit.byId("TB1").get('value'),"TB1 should be set");
-								doh.is("J", dijit.byId("TB2").get('value'),"TB2 should be set");
-								doh.is("Doe", dijit.byId("TB3").get('value'),"TB3 should be set");
-								doh.is("jdoe at example.com", dijit.byId("TB4").get('value'),"TB4 should be set");			
-							}), 1000);
-							return d;
-						}
-					},
-					 {						
-						name: "testBackToHome",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							// move back to Home
-							var t = dojo.query('.mblArrowButtonBody');
-							doh.robot.mouseMoveAt(dojo.query('.mblArrowButtonBody')[2], 500);							
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("11111", dijit.byId("TB0").get('value'),"TB0 should be set");
-							}), 1000);
-							
-							return d;
-						}
-					}
-					
-				]);
-				doh.run();
-			});
-		</script>
-</html>
diff --git a/dojox/mvc/tests/robot/mvc_generate-view.html b/dojox/mvc/tests/robot/mvc_generate-view.html
deleted file mode 100755
index 4d14245..0000000
--- a/dojox/mvc/tests/robot/mvc_generate-view.html
+++ /dev/null
@@ -1,179 +0,0 @@
-<!DOCTYPE html>
-<html>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>doh.robot MVC Generate View Test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<script type="text/javascript" src="../helpers.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../test_mvc_generate-view.html');
-
-				doh.register("on_test_MVC_Search_Results_Repeat", [
-					 {
-						name: "initial conditions",
-						timeout: 9000,
-						runTest: function(){
-						var d = new doh.Deferred();
-						console.debug("dojo.version() is "+dojo.version);
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is("360324", dijit.byId("view_t0").get('value'),"view_t0 should be set");
-							doh.is("John", dijit.byId("view_t1").get('value'),"view_t1 should be set");
-							doh.is("Doe", dijit.byId("view_t2").get('value'),"view_t2 should be set");
-							doh.is("jdoe at example.com", dijit.byId("view_t3").get('value'),"view_t3 should be set");
-						}), 1000);
-						return d;
-						}
-					 },
-					{
-						name: "changeJohn",
-						timeout: 18000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("view_t0", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
-
-							// ensure we've reached top left of text area x-browser
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});
-
-							// navigate to end of first name in JSON in textarea
-
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});						   
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});						   
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});						   
-
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});						   
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});						   
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});						   
-
-							doh.robot.typeKeys("ny", 500, 1000);													 
-							doh.robot.mouseMoveAt("view_t0", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("360324", dijit.byId("view_t0").get('value'),"view_t0 should be set");
-								doh.is("Johnny", dijit.byId("view_t1").get('value'),"view_t1 should be set");
-								doh.is("Doe", dijit.byId("view_t2").get('value'),"view_t2 should be set");
-								doh.is("jdoe at example.com", dijit.byId("view_t3").get('value'),"view_t3 should be set");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "addMiddle",
-						timeout: 18000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("view_t0", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
-
-							// ensure we've reached top left of text area x-browser
-
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200, {});						 
-
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});
-
-							// navigate to end of first name in JSON in textarea
-
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});						   
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});						   
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200, {});
-
-							doh.robot.typeKeys('    "Middle" : "J.",', 500, 1000);													 
-							doh.robot.keyPress(dojo.keys.ENTER, 100, {});						  
-							doh.robot.mouseMoveAt("view_t0", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("360324", dijit.byId("view_t0").get('value'),"view_t0 should be set");
-								doh.is("Johnny", dijit.byId("view_t1").get('value'),"view_t1 should be set");
-								doh.is("J.", dijit.byId("view_t2").get('value'),"view_t2 should be set");
-								doh.is("Doe", dijit.byId("view_t3").get('value'),"view_t3 should be set");
-								doh.is("jdoe at example.com", dijit.byId("view_t4").get('value'),"view_t4 should be set");
-
-								doh.is("2010", dijit.byId("view_t18").get('value'),"view_t18 should be set");
-								doh.is("Gold", dijit.byId("view_t19").get('value'),"view_t19 should be set");
-							}), 1000);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-</html>
diff --git a/dojox/mvc/tests/robot/mvc_loan-stateful.html b/dojox/mvc/tests/robot/mvc_loan-stateful.html
deleted file mode 100755
index 8855c1c..0000000
--- a/dojox/mvc/tests/robot/mvc_loan-stateful.html
+++ /dev/null
@@ -1,160 +0,0 @@
-<!DOCTYPE html>
-<html>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>doh.robot MVC loan stateful Test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<script type="text/javascript" src="../helpers.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../test_mvc_loan-stateful.html');
-
-				doh.register("on_test_MVC_LoanStateful", [
-					 {
-						name: "initial conditions",
-						timeout: 9000,
-						runTest: function(){
-						var d = new doh.Deferred();
-						console.debug("dojo.version() is "+dojo.version);
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is("5", dijit.byId("percentHousing").get('value'),"percentHousing should be 5");
-							doh.is(true, dijit.byId("percentHousing").isValid(), "isValid()","percentHousing should be valid");
-							doh.is("1000", dijit.byId("housing").get('value'),"housing should be 1000");
-							doh.is("2700", dijit.byId("totalHousing").get('value'),"totalHousing should be 2700");
-						}), 1000);
-						return d;
-						}
-					 },
-					{
-						name: "setzipgood1",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("zipInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.typeKeys("10706", 800, 1000);														
-							doh.robot.keyPress(dojo.keys.TAB, 1000, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Hastings On Hudson", dijit.byId("cityInput").get('value'),"good zip 10706 should display the city");
-							}), 1500);
-							return d;
-						}
-					},
-					{
-						name: "setzipbad1",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("borrowerInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});		
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});														
-							doh.robot.typeKeys("11111", 500, 1000);														
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							
-							// should also check for invalid zip indicator
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("", dijit.byId("cityInput").get('value'),"cityInput should be blank");
-								doh.is(false, dijit.byId("zipInput").isValid(), "zipInput should be invalid");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "setzipgood2",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("borrowerInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});			
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});														
-							doh.robot.typeKeys("10024", 500, 1000);														
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("New York", dijit.byId("cityInput").get('value'),"check for cityInput set to New York");
-							}), 1500);
-							return d;
-						}
-					},
-					{
-						name: "changeMortgageAmt1",
-						timeout: 19000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("stateInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
-							
-							doh.robot.typeKeys("10000", 500, 1000);							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-
-							doh.robot.mouseMoveAt("total", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("10000", dijit.byId("housing").get('value'),"housing should be 10000");
-								doh.is("11700", dijit.byId("totalHousing").get('value'),"totalHousing should be 11700");								
-								doh.is("20", dijit.byId("percentHousing").get('value'),"percentHousing should be 20");
-								doh.is(true, dijit.byId("percentHousing").isValid(),"percentHousing should be valid");
-								
-							}), 1500);
-							return d;
-						}
-					},
-					{
-						name: "changeMortgageAmt2",
-						timeout: 19000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("stateInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
-							
-							doh.robot.typeKeys("20000", 500, 1000);							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-
-							doh.robot.mouseMoveAt("total", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("20000", dijit.byId("housing").get('value'),"housing should be 20000");
-								doh.is("21700", dijit.byId("totalHousing").get('value'),"totalHousing should be 21700");								
-								doh.is("36", dijit.byId("percentHousing").get('value'),"percentHousing should be 36");
-								doh.is(false, dijit.byId("percentHousing").isValid(),"percentHousing should be invalid");
-							}), 1000);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-</html>
diff --git a/dojox/mvc/tests/robot/mvc_ref-set-repeat.html b/dojox/mvc/tests/robot/mvc_ref-set-repeat.html
deleted file mode 100644
index 4659394..0000000
--- a/dojox/mvc/tests/robot/mvc_ref-set-repeat.html
+++ /dev/null
@@ -1,156 +0,0 @@
-<!DOCTYPE html>
-<html>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>doh.robot MVC Ref set repeat test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<script type="text/javascript" src="../helpers.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../test_mvc_ref-set-repeat-simple.html');
-
-				doh.register("test_MVC_SimpleDataBoundField", [				                                               
-					{
-						name: "initial conditions",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							console.debug("dojo.version() is "+dojo.version);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Anne1", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne1");
-								doh.is("Ben1",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben1 ");
-								doh.is("Chad1", dijit.byId("nameInput2").get('value'),"nameInput2 should be Chad1");
-
-								doh.is("Anne1", dijit.byId("firstnameOutput10").get('value'),"firstnameOutput10 should be Anne1");
-								doh.is("Ben1",  dijit.byId("firstnameOutput11").get('value'),"firstnameOutput11 should be Ben1 ");
-								doh.is("Chad1", dijit.byId("firstnameOutput12").get('value'),"firstnameOutput12 should be Chad1");
-
-								doh.is("Anne2", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2");
-								doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
-
-								doh.is("", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be blank");
-							}), 1000);
-							return d;
-						}
-					 },
-                     {						
-						name: "SelectModel2",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_1", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Anne2", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne2");
-								doh.is("Ben2",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben2 ");
-							}), 1000);
-							return d;
-						}
-					 },
-                     {						
-						name: "ChangeModel2",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-                            doh.robot.keyPress(dojo.keys.TAB, 500, {});                         
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
-							
-							doh.robot.typeKeys("Anne2-Update", 500, 1000);							
-                            doh.robot.keyPress(dojo.keys.TAB, 500, {});                         
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Anne2-Update", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne2-Update");
-								doh.is("Ben2",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben2 ");
-
-								doh.is("Anne2-Update", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2-Update");
-								doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
-							}), 1000);
-							return d;
-						}
-					 },
-                     {						
-						name: "SelectModel3",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_2", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("", dijit.byId("nameInput0").get('value'),"nameInput0 should be blank");
-							}), 1000);
-							return d;
-						}
-					 },
-                     {						
-						name: "ChangeModel3",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("nameInput0", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});
-							
-							doh.robot.typeKeys("Anne3-Update", 500, 1000);							
-                            doh.robot.keyPress(dojo.keys.TAB, 500, {});                         
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Anne3-Update", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne3-Update");
-
-								doh.is("Anne3-Update", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be Anne3-Update");
-							}), 1000);
-							return d;
-						}
-					 },
-                     {						
-						name: "ResetAll",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("dijit_form_Button_0", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("reset", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Anne1", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne1");
-								doh.is("Ben1",  dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben1 ");
-								doh.is("Chad1", dijit.byId("nameInput2").get('value'),"nameInput2 should be Chad1");
-
-								doh.is("Anne1", dijit.byId("firstnameOutput10").get('value'),"firstnameOutput10 should be Anne1");
-								doh.is("Ben1",  dijit.byId("firstnameOutput11").get('value'),"firstnameOutput11 should be Ben1 ");
-								doh.is("Chad1", dijit.byId("firstnameOutput12").get('value'),"firstnameOutput12 should be Chad1");
-
-								doh.is("Anne2", dijit.byId("firstnameOutput20").get('value'),"firstnameOutput20 should be Anne2");
-								doh.is("Ben2",  dijit.byId("firstnameOutput21").get('value'),"firstnameOutput21 should be Ben2 ");
-
-								doh.is("", dijit.byId("firstnameOutput30").get('value'),"firstnameOutput30 should be blank");
-							
-							}), 1000);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-</html>
diff --git a/dojox/mvc/tests/robot/mvc_search-results-ins-del.html b/dojox/mvc/tests/robot/mvc_search-results-ins-del.html
deleted file mode 100755
index 6fdac2e..0000000
--- a/dojox/mvc/tests/robot/mvc_search-results-ins-del.html
+++ /dev/null
@@ -1,276 +0,0 @@
-<!DOCTYPE html>
-<html>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>doh.robot MVC search-results-ins-del Test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<script type="text/javascript" src="../helpers.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../test_mvc_search-results-ins-del.html');
-
-				doh.register("on_test_MVC_Search_Results_Repeat", [
-					 {
-						name: "initial conditions",
-						timeout: 9000,
-						runTest: function(){
-						var d = new doh.Deferred();
-						console.debug("dojo.version() is "+dojo.version);
-						doh.robot.mouseMoveAt("firstInput", 500, 0);
-						doh.robot.mouseClick({left:true}, 500);
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is("Anne", dijit.byId("nameInput0").get('value'),"nameInput0 should be Anne");
-							doh.is("Ben", dijit.byId("nameInput1").get('value'),"nameInput1 should be Ben");
-							doh.is("John", dijit.byId("nameInput9").get('value'),"nameInput9 should be John");
-							doh.is("Anne", dijit.byId("firstInput").get('value'),"firstInput should be Anne");
-							doh.is("Ackerman", dijit.byId("lastInput").get('value'),"lastInput should be Ackerman");
-							doh.is("a.a at test.com", dijit.byId("emailInput").get('value'),"emailInput should be a.a at test.com");
-						}), 1000);
-						return d;
-						}
-					 },
-			/*		{
-						name: "selectBen",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_4", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Ben", dijit.byId("firstInput").get('value'),"firstInput should be Ben");
-								doh.is("Beckham", dijit.byId("lastInput").get('value'),"lastInput should be Beckham");
-								doh.is("b.b at test.com", dijit.byId("emailInput").get('value'),"emailInput should be b.b at test.com");
-							}), 1000);
-							return d;
-						}
-					},
-			*/		
-					{
-						name: "selectJohn",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_28", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("John", dijit.byId("firstInput").get('value'),"firstInput should be John");
-								doh.is("Jacklin", dijit.byId("lastInput").get('value'),"lastInput should be Jacklin");
-								doh.is("j.j at test.com", dijit.byId("emailInput").get('value'),"emailInput should be j.j at test.com");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "changeJohn",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("firstInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.typeKeys("Johnny", 300, 600);													  
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Johnny", dijit.byId("firstInput").get('value'),"firstInput should be Johnny");
-								doh.is("Johnny", dijit.byId("nameInput9").get('value'),"nameInput9 should be Johnny");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "changeBen",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_4", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("nameInput1", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.typeKeys("jamin", 300, 600);														
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Benjamin", dijit.byId("firstInput").get('value'),"check for firstInput set to Benjamin");
-								doh.is("Benjamin", dijit.byId("nameInput1").get('value'),"check for nameInput1 set to Benjamin");
-							}), 1500);
-							return d;
-						}
-					},
-					{
-						name: "AddKen",
-						timeout: 20000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_29", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("dijit_form_Button_61", 2000, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("firstInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.typeKeys("Ken", 300, 600);													  
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("Kelly", 300, 600);														
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("CA", 300, 600);													 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("5623", 300, 600);													   
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("k.k at test.com", 300, 600);													   
-							doh.robot.keyPress(dojo.keys.TAB, 300, {});	 
-							doh.robot.typeKeys("408-764-3454", 300, 600);													   
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("408-764-6000", 300, 600);													   
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Ken", dijit.byId("firstInput").get('value'),"firstInput should be Ken");
-								doh.is("Ken", dijit.byId("nameInput10").get('value'),"nameInput10 should be Ken");
-								doh.is("Kelly", dijit.byId("lastInput").get('value'),"lastInput should be set");
-								doh.is("CA", dijit.byId("locationInput").get('value'),"locationInput should be set");
-								doh.is("5623", dijit.byId("officeInput").get('value'),"officeInput should be set");
-								doh.is("k.k at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
-								doh.is("408-764-3454", dijit.byId("telInput").get('value'),"telInput should be set");
-								doh.is("408-764-6000", dijit.byId("faxInput").get('value'),"faxInput should be set");
-							}), 1000);
-							return d;
-						}
-					},
-			/*		{
-						name: "AddBetty",
-						timeout: 20000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_35", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("dijit_form_Button_70", 2000, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("nameInput2", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.typeKeys("Betty", 500, 1000);														
-							doh.robot.mouseMoveAt("lastInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.typeKeys("Baker", 500, 1000);														
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("CA", 500, 1000);													 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("5624", 500, 1000);													   
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("b2.b2 at test.com", 500, 1000);													 
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("408-764-3455", 500, 1000);													   
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});	 
-							doh.robot.typeKeys("408-764-6000", 500, 1000);													   
-							//doh.robot.keyPress(dojo.keys.TAB, 500, {});  
-							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Betty", dijit.byId("firstInput").get('value'),"firstInput should be set");
-								doh.is("Betty", dijit.byId("nameInput2").get('value'),"faxInput should be set");
-								doh.is("Baker", dijit.byId("lastInput").get('value'),"nameInput2 should be set");
-								doh.is("CA", dijit.byId("locationInput").get('value'),"locationInput should be set");
-								doh.is("5624", dijit.byId("officeInput").get('value'),"officeInput should be set");
-								doh.is("b2.b2 at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
-								doh.is("408-764-3455", dijit.byId("telInput").get('value'),"telInput should be set");
-								doh.is("408-764-6000", dijit.byId("faxInput").get('value'),"faxInput should be set");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "RemoveBetty",
-						timeout: 20000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_72", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("dijit_form_Button_112", 2000, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("dijit_form_Button_106", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("nameInput2", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Chad", dijit.byId("firstInput").get('value'),"firstInput should be set");
-								doh.is("Chad", dijit.byId("nameInput2").get('value'),"nameInput2 should be set");
-							}), 1000);
-							return d;
-						}
-					},					
-					{
-						name: "RemoveKen",
-						timeout: 20000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_132", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Chad", dijit.byId("firstInput").get('value'),"firstInput should be set");
-								doh.is(undefined, dijit.byId("nameInput10"),"nameInput10 should be set");
-							}), 1000);
-							return d;
-						}
-					}
-		*/			
-					{
-						name: "RemoveKen",
-						timeout: 20000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_37", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("dijit_form_Button_63", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Chad", dijit.byId("firstInput").get('value'),"firstInput should be set");
-								doh.is(undefined, dijit.byId("nameInput10"),"nameInput10 should be set");
-							}), 1000);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-</html>
diff --git a/dojox/mvc/tests/robot/mvc_search-results-repeat.html b/dojox/mvc/tests/robot/mvc_search-results-repeat.html
deleted file mode 100755
index fbf92ea..0000000
--- a/dojox/mvc/tests/robot/mvc_search-results-repeat.html
+++ /dev/null
@@ -1,123 +0,0 @@
-<!DOCTYPE html>
-<html>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>doh.robot MVC search-results-repeat Test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<script type="text/javascript" src="../helpers.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../test_mvc_search-results-repeat.html');
-
-				doh.register("on_test_MVC_Search_Results_Repeat", [
-					 {
-						name: "initial conditions",
-						timeout: 9000,
-						runTest: function(){
-						var d = new doh.Deferred();
-						console.debug("dojo.version() is "+dojo.version);
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is("Anne", dijit.byId("nameInput0").get('value'),"nameInput0 should be set");
-							doh.is("Ben", dijit.byId("nameInput1").get('value'),"nameInput1 should be set");
-							doh.is("John", dijit.byId("nameInput9").get('value'),"nameInput9 should be set");
-							doh.is("Anne", dijit.byId("firstInput").get('value'),"firstInput should be set");
-							doh.is("Ackerman", dijit.byId("lastInput").get('value'),"lastInput should be set");
-							doh.is("a.a at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
-						}), 1000);
-						return d;
-						}
-					 },
-					{
-						name: "selectBen",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_2", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Ben", dijit.byId("firstInput").get('value'),"firstInput should be set");
-								doh.is("Beckham", dijit.byId("lastInput").get('value'),"lastInput should be set");
-								doh.is("b.b at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "selectJohn",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_10", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("John", dijit.byId("firstInput").get('value'),"firstInput should be set");
-								doh.is("Jacklin", dijit.byId("lastInput").get('value'),"lastInput should be set");
-								doh.is("j.j at test.com", dijit.byId("emailInput").get('value'),"emailInput should be set");
-							}), 1500);
-							return d;
-						}
-					},
-					{
-						name: "changeJohn",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("firstInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 200, {});						  
-							doh.robot.typeKeys("Johnny", 1000, 2000);													  
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Johnny", dijit.byId("firstInput").get('value'),"firstInput should be set");
-								doh.is("Johnny", dijit.byId("nameInput9").get('value'),"nameInput9 should be set");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "changeBen",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_2", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("nameInput1", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.typeKeys("jamin", 500, 1000);														
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Benjamin", dijit.byId("firstInput").get('value'),"firstInput should be set");
-								doh.is("Benjamin", dijit.byId("nameInput1").get('value'),"nameInput1 should be set");
-							}), 1000);
-							return d;
-						}
-					}				]);
-				doh.run();
-			});
-		</script>
-</html>
diff --git a/dojox/mvc/tests/robot/mvc_shipto-billto-hierarchical.html b/dojox/mvc/tests/robot/mvc_shipto-billto-hierarchical.html
deleted file mode 100755
index 46dd43f..0000000
--- a/dojox/mvc/tests/robot/mvc_shipto-billto-hierarchical.html
+++ /dev/null
@@ -1,103 +0,0 @@
-<!DOCTYPE html>
-<html>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>doh.robot MVC shipto-billto-hierarchical Test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<script type="text/javascript" src="../helpers.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../test_mvc_shipto-billto-hierarchical.html');
-
-				doh.register("test_MVC_SimpleDataBoundField", [
-				{
-						name: "initial conditions",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							console.debug("dojo.version() is "+dojo.version);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("ShipTo", dijit.byId("addrLabel").get('value'));
-								doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					 },
-					 {
-						name: "billto",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_1", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("BillTo", dijit.byId("addrLabel").get('value'),"addrLabel should be set");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "shipto",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							doh.robot.mouseMoveAt("dijit_form_Button_0", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("ShipTo", dijit.byId("addrLabel").get('value'),"addrLabel should be set");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "changeShipToAddress",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							//reset the streetInput textbox
-							//dijit.byId("streetInput").set('value',"");
-							
-							doh.robot.mouseMoveAt("addrLabel", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});
-							
-							doh.robot.typeKeys("456 Mountain Rd", 500, 1000);
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_1_label", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("dijit_form_Button_0_label", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("streetInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-</html>
diff --git a/dojox/mvc/tests/robot/mvc_shipto-billto-simple.html b/dojox/mvc/tests/robot/mvc_shipto-billto-simple.html
deleted file mode 100755
index 78018dc..0000000
--- a/dojox/mvc/tests/robot/mvc_shipto-billto-simple.html
+++ /dev/null
@@ -1,101 +0,0 @@
-<!DOCTYPE html>
-<html>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>doh.robot MVC demo-shipto-billto-simple Declarative Test</title>
-
-		<style>
-			@import "../../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<script type="text/javascript" src="../helpers.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../test_mvc_shipto-billto-simple-declarative.html');
-
-				doh.register("test_MVC_SimpleDataBoundField", [				                                               
-					{
-						name: "initial conditions",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							console.debug("dojo.version() is "+dojo.version);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								//"ShipTo" selected 
-								doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					 },
-                     {						
-						name: "billto",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.mouseMoveAt("billto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								//"BillTo" selected 
-								doh.is("17 Skyline Dr", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "shipto",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseMoveAt("shipto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								//"ShipTo" selected 
-								doh.is("123 Valley Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					},					
-					{
-						name: "changeShipToAddress",
-						timeout: 9000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});							
-                            doh.robot.keyPress(dojo.keys.TAB, 500, {});                         
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});							
-							
-							doh.robot.typeKeys("456 Mountain Rd", 500, 1000);							
-							
-							doh.robot.mouseMoveAt("billto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.mouseMoveAt("shipto", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-
-							doh.robot.mouseMoveAt("streetInput", 500, 0);
-							doh.robot.mouseClick({left:true}, 500);
-							
-							doh.robot.sequence(d.getTestCallback(function(){
-								console.debug("check data "+dijit.byId("streetInput").get('binding').data);
-								doh.is("456 Mountain Rd", dijit.byId("streetInput").get('value'),"streetInput should be set");
-							}), 1000);
-							return d;
-						}
-					}
-				]);
-				doh.run();
-			});
-		</script>
-</html>
diff --git a/dojox/mvc/tests/runTests.html b/dojox/mvc/tests/runTests.html
old mode 100755
new mode 100644
diff --git a/dojox/mvc/tests/runTestsFullSet.html b/dojox/mvc/tests/runTestsFullSet.html
deleted file mode 100644
index 305cfcb..0000000
--- a/dojox/mvc/tests/runTestsFullSet.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-	<head>
-	<title>Dijit Unit Test Runner</title>
-	<meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojox.mvc.tests.moduleFullSet"></HEAD>
-	<BODY>
-		Redirecting to D.O.H runner.
-	</BODY>
-</HTML>
diff --git a/dojox/mvc/tests/templates/ModelRefControllerInTemplate.html b/dojox/mvc/tests/templates/ModelRefControllerInTemplate.html
new file mode 100644
index 0000000..292345c
--- /dev/null
+++ b/dojox/mvc/tests/templates/ModelRefControllerInTemplate.html
@@ -0,0 +1,3 @@
+<div>
+	<span data-dojo-type="dojox/mvc/ModelRefController" data-dojo-attach-point="controllerNode" data-dojo-props="model: model"></span>
+</div>
\ No newline at end of file
diff --git a/dojox/mvc/tests/templates/_ControllerInTemplate.html b/dojox/mvc/tests/templates/_ControllerInTemplate.html
new file mode 100644
index 0000000..e6a7989
--- /dev/null
+++ b/dojox/mvc/tests/templates/_ControllerInTemplate.html
@@ -0,0 +1,3 @@
+<div>
+	<span data-dojo-type="dojox/mvc/_Controller" data-dojo-attach-point="controllerNode"></span>
+</div>
\ No newline at end of file
diff --git a/dojox/mvc/tests/test_WidgetList.html b/dojox/mvc/tests/test_WidgetList.html
new file mode 100644
index 0000000..e36bde9
--- /dev/null
+++ b/dojox/mvc/tests/test_WidgetList.html
@@ -0,0 +1,171 @@
+<!DOCTYPE html>
+<html style="width:100%;height:100%;overflow:hidden;">
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC repeated widget test</title>
+
+		<style type="text/css">
+			@import "../../../dijit/themes/dijit.css";
+			@import "../../../dijit/themes/claro/document.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
+		</style>
+
+		<!-- required: a default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript">
+			dojoConfig = {
+				isDebug: 1,
+				parseOnLoad: 0,
+				async: 1,
+				mvc: {debugBindings: 1}
+			};
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+
+		<script type="text/javascript">
+			require([
+				"dojo/dom",
+				"dojo/dom-class",
+				"dojo/parser",
+				"dijit/_WidgetBase",
+				"dojox/mvc/at",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/Templated",
+				"dojox/mvc/WidgetList",
+				"dojo/text!dojox/mvc/tests/test_WidgetList_childTemplate.html",
+				"dojo/text!dojox/mvc/tests/test_WidgetList_childBindings.json",
+				"dijit/form/TextBox" // dijit._WidgetsInTemplateMixin does not support auto-loading modules by parser
+			], function(dom, domClass, parser, _WidgetBase, at, getStateful, Templated, WidgetList, childTemplate, childBindings){
+				array = getStateful([
+					{
+						Serial: "A111",
+						First: "Anne",
+						Last: "Ackerman",
+						Location: "NY",
+						Office: "1S76",
+						Email: "a.a at test.com",
+						Tel: "123-764-8237",
+						Fax: "123-764-8228"
+					},
+					{
+						Serial: "B111",
+						First: "Ben",
+						Last: "Beckham",
+						Location: "NY",
+						Office: "5N47",
+						Email: "b.b at test.com",
+						Tel: "123-764-8599",
+						Fax: "123-764-8600"
+					},
+					{
+						Serial: "C111",
+						First: "Chad",
+						Last: "Chapman",
+						Location: "CA",
+						Office: "1278",
+						Email: "c.c at test.com",
+						Tel: "408-764-8237",
+						Fax: "408-764-8228"
+					}
+				]);
+
+				arrayAlt = getStateful([
+					{
+						Serial: "D111",
+						First: "David",
+						Last: "Durham",
+						Location: "NJ",
+						Office: "C12",
+						Email: "d.d at test.com",
+						Tel: "514-764-8237",
+						Fax: "514-764-8228"
+					},
+					{
+						Serial: "E111",
+						First: "Emma",
+						Last: "Eklof",
+						Location: "NY",
+						Office: "4N76",
+						Email: "e.e at test.com",
+						Tel: "123-764-1234",
+						Fax: "123-764-4321"
+					}
+				]);
+
+				domClass.add(dom.byId("loading"), "dijitDisplayNone");
+				domClass.remove(dom.byId("main"), "dijitDisplayNone");
+				parser.parse();
+
+				(new WidgetList({
+					children: array,
+					childParams: {
+						startup: function(){
+							this.labelNode.set("value", at("rel:", "Serial"));
+							this.inputNode.set("value", at("rel:", "First"));
+							this.inherited("startup", arguments);
+						}
+					},
+					templateString: childTemplate
+				}, dom.byId("programmaticRepeat"))).startup();
+
+				(new WidgetList({
+					children: array,
+					templateString: childTemplate,
+					childBindings: eval("(" + childBindings + ")")
+				}, dom.byId("programmaticRepeatWithSeparateBindingDeclaration"))).startup();
+			});
+		</script>
+	</head>
+	<body class="claro" style="width:100%;height:100%;margin:0;padding:8px;overflow:hidden;">
+		<script type="dojo/require">at: "dojox/mvc/at", Stateful: "dojo/Stateful"</script>
+		<table id="loading" style="width:100%;height:100%;" border="0" cellpadding="0" cellspacing="0">
+			<tbody>
+				<tr>
+					<td align="center">Loading...</td>
+				</tr>
+			</tbody>
+		</table>
+		<div id="main" class="dijitDisplayNone" style="width:100%;height:100%;">
+			<div>
+				<h1>Repeating simple text box and label</h1>
+				<div data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-props="children: array"
+				 data-mvc-child-type="dijit/form/TextBox"
+				 data-mvc-child-props="value: at(this.target, 'First')"></div>
+				<span data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-props="children: array"
+				 data-mvc-child-type="dijit/_WidgetBase"
+				 data-mvc-child-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at(this.target, 'First')"></span>
+			</div>
+			<div>
+				<h1>Repeating in-line template</h1>
+				<div data-dojo-type="dojox/mvc/WidgetList"
+				 data-dojo-mixins="dojox/mvc/_InlineTemplateMixin"
+				 data-dojo-props="children: array, partialRebuild: true">
+					<script type="dojox/mvc/InlineTemplate">
+						<div>
+							<span data-dojo-type="dijit/_WidgetBase"
+							 data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at('rel:', 'Serial')"></span>: 
+							<span data-dojo-type="dijit/form/TextBox"
+							 data-dojo-props="value: at('rel:', 'First')"></span>
+						</div>
+					</script>
+				</div>
+			</div>
+			<div>
+				<h1>Repeating programmatically created template widget</h1>
+				<div id="programmaticRepeat"></div>
+			</div>
+			<div>
+				<h1>Repeating programmatically created template widget, with separate data binding declaration from template</h1>
+				<div id="programmaticRepeatWithSeparateBindingDeclaration"></div>
+			</div>
+			<div>
+				<h1>Modifying array elements</h1>
+				<input type="button" value="Replace" onclick="array.splice.apply(array, [1, 1].concat(arrayAlt)); this.disabled = true;">
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_WidgetList_WidgetListInTemplate.html b/dojox/mvc/tests/test_WidgetList_WidgetListInTemplate.html
new file mode 100644
index 0000000..b241869
--- /dev/null
+++ b/dojox/mvc/tests/test_WidgetList_WidgetListInTemplate.html
@@ -0,0 +1,20 @@
+<div>
+	<div data-dojo-attach-point="simpleWidgetList"
+	 data-dojo-type="dojox/mvc/WidgetList"
+	 data-mvc-child-type="My.Widget"
+	 data-mvc-child-mixins="My.Mixin"
+	 data-dojo-props="children: this.childData">
+	</div>
+	<div data-dojo-attach-point="simpleWidgetListWithRegularDijit"
+	 data-dojo-type="dojox/mvc/WidgetList"
+	 data-mvc-child-type="dijit/form/TextBox"
+	 data-mvc-child-mixins="My.Mixin"
+	 data-dojo-props="children: this.childData">
+	</div>
+	<div data-dojo-attach-point="simpleWidgetListWithRegularDijitInMixin"
+	 data-dojo-type="dojox/mvc/WidgetList"
+	 data-mvc-child-type="My.Widget"
+	 data-mvc-child-mixins="My.Mixin,dijit/_Container"
+	 data-dojo-props="children: this.childData">
+	</div>
+</div>
\ No newline at end of file
diff --git a/dojox/mvc/tests/test_WidgetList_childBindings.json b/dojox/mvc/tests/test_WidgetList_childBindings.json
new file mode 100644
index 0000000..b2fb9e4
--- /dev/null
+++ b/dojox/mvc/tests/test_WidgetList_childBindings.json
@@ -0,0 +1,4 @@
+{
+	labelNode: {value: at("rel:", "Serial")},
+	inputNode: {value: at("rel:", "First")}
+}
diff --git a/dojox/mvc/tests/test_WidgetList_childTemplate.html b/dojox/mvc/tests/test_WidgetList_childTemplate.html
new file mode 100644
index 0000000..7c5fa7c
--- /dev/null
+++ b/dojox/mvc/tests/test_WidgetList_childTemplate.html
@@ -0,0 +1,7 @@
+<div>
+	<span data-dojo-type="dijit/_WidgetBase"
+	 data-dojo-attach-point="labelNode"
+	 data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}"></span>
+	<span data-dojo-type="dijit/form/TextBox"
+	 data-dojo-attach-point="inputNode"></span>
+</div>
diff --git a/dojox/mvc/tests/test_async-mvc_group-simple.html b/dojox/mvc/tests/test_async-mvc_group-simple.html
index b4d0279..a5f4a81 100644
--- a/dojox/mvc/tests/test_async-mvc_group-simple.html
+++ b/dojox/mvc/tests/test_async-mvc_group-simple.html
@@ -7,35 +7,50 @@
 			@import "css/app-format.css";
 			@import "../../../dijit/themes/claro/claro.css";
 		</style>
-
-<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
-<script type="text/javascript">
- 		var model;
- 
-		require([
-		'dojo/parser',
-        'dojox/mvc',
-		'dojox/mvc/Group',
-		'dojox/mvc/Output',
-		'dojo/parser',
-		'dijit/form/TextBox',
-		'dijit/form/Button'], function(){
-
-			// The dojox.mvc.StatefulModel class creates a data model instance
-			// where each leaf within the data model is decorated with dojo.Stateful
-			// properties that widgets can bind to and watch for their changes.
-			model = dojox.mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
-				require([
-					'dojo/domReady!'
-				], function(){
-				   dojo.parser.parse();
-				});
+		<script type="text/javascript">
+			require = {
+				async: 1,
+				parseOnLoad: 0,
+				isDebug: 1, 
+				mvc: {debugBindings: 1}
+			};
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			require([
+				"dojo/parser",
+				"dojo/Stateful",
+				"dojox/mvc/EditModelRefController",
+				"dojox/mvc/EditStoreRefController",
+				"dojo/store/Memory",
+				"dojox/mvc/getStateful",
+				"dijit/form/Button",
+				"dijit/form/TextBox",
+				"dojox/mvc/Group",
+				"dojox/mvc/parserExtension",
+				"dojo/domReady!"
+			], function(parser, Stateful, EditModelRefController, EditStoreRefController, Memory, getStateful){
+				var testmem = new Memory({data: {First: "John", Last: "Doe", Email: "jdoe at example.com"}});
+				var testdata = testmem.query();
+				console.log("testdata = ",testdata);
+				var testmem2 = new Memory({data: {identifier: "id", items: [{id: "emp0", First: "John", Last: "Doe", Email: "jdoe at example.com"}]}});
+				var testdata2 = testmem2.query();
+				console.log("testdata2 = ",testdata2);
 				
-		}); // end onload
-
+				ctrl1 = new EditStoreRefController({sourceModel: new Stateful({First: "John", Last: "Doe", Email: "jdoe at example.com"})});
+				ctrl2 = new EditStoreRefController({sourceModel: new Stateful(testdata)});
+				console.log("ctrl2 = ",ctrl2);
+				ctrl3 = new EditStoreRefController({store: new Memory({data: {items: [{id: "emp0", First: "John", Last: "Doe", Email: "jdoe at example.com"}]}})});
+				ctrl3.queryStore({});
+				ctrl = new EditStoreRefController({store: new Memory({data: {identifier: "id", items: [{id: "emp0", First: "John", Last: "Doe", Email: "jdoe at example.com"}]}})});
+				ctrl.getStore("emp0");				
+				console.log("ctrl = ",ctrl);
+				parser.parse();
+			});
 		</script>
 	</head>
 	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
 		<div id="wrapper">
 			<div id="header">
 				<div id="navigation"></div>
@@ -46,34 +61,29 @@
 			</div>
 			<div id="main">
 				<div id="leftNav"></div>
-				<div id="mainContent" dojoType="dojox.mvc.Group" data-dojo-props="ref: 'expr:model'">
+				<div id="mainContent" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model')">
 					<div class="row">
 						<label class="cell" for="firstnameInput">First:</label>
-						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.First"></input>
+						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox" 
+								data-dojo-props="value: at('rel:', 'First')">
 						<!-- Content in output below will always be in sync with value of textbox above -->
-						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'First'">
-						(first name is: ${this.value})
-						</span>
+						(first name is: <span data-mvc-bindings="innerText: at('rel:', 'First')"></span>)
+					</div>
+					<div class="row">
+						<label class="cell" for="lastnameInput">Last:</label>
+						<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" 
+								data-dojo-props="value: at('rel:', 'Last')">
+						(last name is: <span data-mvc-bindings="innerText: at('rel:', 'Last')"></span>)
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label>
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" 
+								data-dojo-props="value: at('rel:', 'Email')">
+						(email is: <span data-mvc-bindings="innerText: at('rel:', 'Email')"></span>)
 					</div>
-				<div class="row">
-					<label class="cell" for="lastnameInput">Last:</label>
-					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Last"></input>
-					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Last'">
-						(last name is: ${this.value})
-					</span>
-				</div>
-				<div class="row">
-					<label class="cell" for="emailInput">Email:</label>
-					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Email"></input>
-					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: 'Email'">
-					(email is: ${this.value})
-					</span>
-				</div>
 					<br/>Model:
-					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" 
+								data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset</button>
 				</div>
 			</div>
 		</div>
diff --git a/dojox/mvc/tests/test_async-mvc_input-output-simple.html b/dojox/mvc/tests/test_async-mvc_input-output-simple.html
index efe2b47..9e1ac6d 100644
--- a/dojox/mvc/tests/test_async-mvc_input-output-simple.html
+++ b/dojox/mvc/tests/test_async-mvc_input-output-simple.html
@@ -7,36 +7,30 @@
 			@import "css/app-format.css";
 			@import "../../../dijit/themes/claro/claro.css";
 		</style>
-
-		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
 		<script type="text/javascript">
-		var model;
- 
-		require([
-			'dojo/parser',
-			'dojo/ready',
-			'dojox/mvc',
-			'dijit/form/TextBox',
-			'dijit/form/Button',
-			'dojox/mvc/Group',
-			'dojox/mvc/Output'
-			], function(parser, ready, mvc){
-
-				// The dojox.mvc.StatefulModel class creates a data model instance
-				// where each leaf within the data model is decorated with dojo.Stateful
-				// properties that widgets can bind to and watch for their changes.
-				model = mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
-				// the StatefulModel created above is initialized with 
-				// model.First set to "John", model.Last set to "Doe" and model.Email set to "jdoe at example.com"
-				
-				// when "dojo/ready" is ready call parser.parse
-				ready(function(){
-					parser.parse();
-				});
+			require = {
+				parseOnLoad: 0,
+				isDebug: 1,
+				async: 1, 
+				mvc: {debugBindings: true}
+			};
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			require([
+				"dojo/parser",
+				"dojo/Stateful",
+				"dijit/form/Button",
+				"dijit/form/TextBox",
+				"dojo/domReady!"
+			], function(parser, Stateful){
+				model = new Stateful({First: "John", Last: "Doe", Email: "jdoe at example.com"});
+				parser.parse();
 			});
 		</script>
 	</head>
 	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
 		<div id="wrapper">
 			<div id="header">
 				<div id="navigation"></div>
@@ -50,31 +44,29 @@
 				<div id="mainContent">
 					<div class="row">
 						<label class="cell" for="firstnameInput">First:</label>
-						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.First"></input>
+						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox" 
+								data-dojo-props="value: at(model, 'First')">
 						<!-- Content in output below will always be in sync with value of textbox above -->
-						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
-						(first name is: ${this.value})
-						</span>
+						(first name is: <span data-dojo-type="dijit._WidgetBase" 
+								data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, 
+																value: at(model, 'First')"></span>)
+					</div>
+					<div class="row">
+						<label class="cell" for="lastnameInput">Last:</label>
+						<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" 
+								data-dojo-props="value: at(model, 'Last')">
+						(last name is: <span data-dojo-type="dijit._WidgetBase" 
+								data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, 
+																value: at(model, 'Last')"></span>)
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label>
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" 
+								data-dojo-props="value: at(model, 'Email')">
+						(email is: <span data-dojo-type="dijit._WidgetBase" 
+								data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, 
+														value: at(model, 'Email')"></span>)
 					</div>
-				<div class="row">
-					<label class="cell" for="lastnameInput">Last:</label>
-					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Last"></input>
-					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Last">
-						(last name is: ${this.value})
-					</span>
-				</div>
-				<div class="row">
-					<label class="cell" for="emailInput">Email:</label>
-					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Email"></input>
-					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
-					(email is: ${this.value})
-					</span>
-				</div>
-					<br/>Model:
-					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
 				</div>
 			</div>
 		</div>
diff --git a/dojox/mvc/tests/test_async-mvc_repeat-simple.html b/dojox/mvc/tests/test_async-mvc_repeat-simple.html
index e9055bd..5227bc3 100644
--- a/dojox/mvc/tests/test_async-mvc_repeat-simple.html
+++ b/dojox/mvc/tests/test_async-mvc_repeat-simple.html
@@ -7,187 +7,135 @@
 			@import "css/app-format.css";
 			@import "../../../dijit/themes/claro/claro.css";
 		</style>
-
-<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
-<script type="text/javascript">
- /*
-			
- */
-		var model;
- 		var searchRecords;
- 
-		require([
-		'dojo/parser',  // has to be first?         
-        'dojox/mvc',
-		'dojox/mvc/Group',
-		'dojox/mvc/Repeat',
-		'dijit/form/TextBox',
-		'dijit/form/Button'], function(){
-
-		  // Raw records for the master detail
-		  var search_results_init =
-			{
-				"Query" : "Engineers",
-				"Results" : [
-					{
-						"First"	  : "Anne",
-						"Last"	  : "Ackerman",
-						"Location": "NY",
-						"Office"  : "1S76",
-						"Email"	  : "a.a at test.com",
-						"Tel"	  : "123-764-8237",
-						"Fax"	  : "123-764-8228"
-					},
-					{
-						"First"	  : "Ben",
-						"Last"	  : "Beckham",
-						"Location": "NY",
-						"Office"  : "5N47",
-						"Email"	  : "b.b at test.com",
-						"Tel"	  : "123-764-8599",
-						"Fax"	  : "123-764-8600"
-					},
-					{
-						"First"	  : "Chad",
-						"Last"	  : "Chapman",
-						"Location": "CA",
-						"Office"  : "1278",
-						"Email"	  : "c.c at test.com",
-						"Tel"	  : "408-764-8237",
-						"Fax"	  : "408-764-8228"
-					},
-					{
-						"First"	  : "Irene",
-						"Last"	  : "Ira",
-						"Location": "NJ",
-						"Office"  : "F09",
-						"Email"	  : "i.i at test.com",
-						"Tel"	  : "514-764-6532",
-						"Fax"	  : "514-764-7300"
-					},
-					{
-						"First"	  : "John",
-						"Last"	  : "Jacklin",
-						"Location": "CA",
-						"Office"  : "6701",
-						"Email"	  : "j.j at test.com",
-						"Tel"	  : "408-764-1234",
-						"Fax"	  : "408-764-4321"
-					}
-				]
+		<script type="text/javascript">
+			require = {
+				parseOnLoad: 0,
+				isDebug: 1,
+				async: 1, 
+				mvc: {debugBindings: 1}
 			};
-
-		   // The dojox.mvc.StatefulModel class creates a data model instance
-		   // where each leaf within the data model is decorated with dojo.Stateful
-		   // properties that widgets can bind to and watch for their changes.
-		   searchRecords = dojox.mvc.newStatefulModel({ data : search_results_init });
-				require([
-					'dojo/domReady!'
-				], function(){
-				   dojo.parser.parse();
+		</script>
+		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			require([
+				"dojo/parser",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/ListController",
+				"dijit/form/Button",
+				"dijit/form/TextBox",
+				"dojox/mvc/Group",
+				"dojox/mvc/Repeat",
+				"dojo/domReady!"
+			], function(parser, getStateful, ListController){
+				ctrl = new ListController({
+					model: getStateful([
+						{
+							First: "Anne",
+							Last: "Ackerman",
+							Location: "NY",
+							Office: "1S76",
+							Email: "a.a at test.com",
+							Tel: "123-764-8237",
+							Fax: "123-764-8228"
+						},
+						{
+							First: "Ben",
+							Last: "Beckham",
+							Location: "NY",
+							Office: "5N47",
+							Email: "b.b at test.com",
+							Tel: "123-764-8599",
+							Fax: "123-764-8600"
+						},
+						{
+							First: "Chad",
+							Last: "Chapman",
+							Location: "CA",
+							Office: "1278",
+							Email: "c.c at test.com",
+							Tel: "408-764-8237",
+							Fax: "408-764-8228"
+						},
+						{
+							First: "Irene",
+							Last: "Ira",
+							Location: "NJ",
+							Office: "F09",
+							Email: "i.i at test.com",
+							Tel: "514-764-6532",
+							Fax: "514-764-7300"
+						},
+						{
+							First: "John",
+							Last: "Jacklin",
+							Location: "CA",
+							Office: "6701",
+							Email: "j.j at test.com",
+							Tel: "408-764-1234",
+							Fax: "408-764-4321"
+						}
+					]),
+					cursorIndex: 0
 				});
-				
-			
-		
-
-		}); // end onload
 
+				parser.parse();
+			});
 		</script>
 	</head>
 	<body class="claro" style="background-image: url(images/master_detail.png)">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
 		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>Employee Search</h1>
-			<h2>Master Detail Example - With repeat container.</h2>
-		  </div>
-		</div>
-		<div id="main">
-		 <div id="leftNav">
-		 </div>
-		 <div id="mainContent">
-		 <!--
-			 The group container denotes some logical grouping of widgets and also serves
-			 to establish a parent data binding context for its children.
-			 The ref attribute for the outermost container obtains the binding from the
-			 "page scope" itself.
-		 -->
-		 <div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'searchRecords'">
-			<div class="row">
-				<label class="cell" for="queryInput">Search for:</label>
-				<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Query'"></input>
-				<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setSearchBanner();}">Search</button>
-			</div>
-			<div class="spacer"></div>
-
-			<div id="searchBanner">Search Results for term: Engineers</div>
-
-			<!--
-				The repeat container denotes a templated UI that operates over a collection
-				of data records.
-				The UI can be customized for each iteration using properties such as
-				${this.index} for the iteration index.
-			-->
-			<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
-				<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
-					<label class="cell" for="nameInput${this.index}">Name:</label>
-					<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"></input>
-					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Master Detail Example - With repeat container</h1>
 				</div>
 			</div>
-			<div class="spacer"></div>
-
-			<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Results'">
-				<div id="detailsBanner">Details for result index: 0</div>
-
-				<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
-					<div class="row">
-						<label class="cell" for="firstInput">First Name:</label>
-						<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
-					</div>
-					<div class="row">
-						<label class="cell" for="lastInput">Last Name:</label>
-						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
-					</div>
-<!--  				<div class="row">
-						<label class="cell" for="locationInput">Location:</label>
-						<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at(ctrl, 'model')">
+						<div>
+							<label class="cell" for="nameInput${this.index}">Name:</label>
+							<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="value: at('rel:${index}', 'First')">
+							<button type="button" data-dojo-type="dijit.form.Button"
+							 data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${this.index}); }">Details</button>
+						</div>
 					</div>
-	-->							
-					<div class="row">
-						<label class="cell" for="officeInput">Office:</label>
-						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
+					<div class="spacer"></div>
+					<div id="detailsBanner">
+						Details for result index:
+						<span data-dojo-type="dijit._WidgetBase"
+						 data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at(ctrl, 'cursorIndex')"></span>
 					</div>
-					<div class="row">
-						<label class="cell" for="emailInput">Email:</label>
-						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
-					</div>
-					<div class="row">
-						<label class="cell" for="telInput">Telephone:</label>
-						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
-					</div>
-					<div class="row">
-						<label class="cell" for="faxInput">Fax:</label>
-						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
+					<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'cursor')">
+						<div class="row">
+							<label class="cell" for="firstInput">First Name:</label>
+							<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')">
+						</div>
+						<div class="row">
+							<label class="cell" for="lastInput">Last Name:</label>
+							<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')">
+						</div>
+						<div class="row">
+							<label class="cell" for="officeInput">Office:</label>
+							<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Office')">
+						</div>
+						<div class="row">
+							<label class="cell" for="emailInput">Email:</label>
+							<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')">
+						</div>
+						<div class="row">
+							<label class="cell" for="telInput">Telephone:</label>
+							<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Tel')">
+						</div>
+						<div class="row">
+							<label class="cell" for="faxInput">Fax:</label>
+							<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Fax')">
+						</div>
 					</div>
 				</div>
 			</div>
-		   </div>
-		 </div>
 		</div>
-		<script type="text/javascript">
-			function setDetailsContext(index) {
-				var widget = dijit.byId("detailsGroup");
-				widget.set("ref", index);
-				var detailsBanner = dojo.byId("detailsBanner");
-				detailsBanner.innerHTML = "Details for result index: " + index;
-			}
-			function setSearchBanner() {
-				var searchBanner = dojo.byId("searchBanner");
-				searchBanner.innerHTML = "Search Results for term: " + searchRecords.Query.get("value");
-			}
-		</script>
 	</body>
 </html>
diff --git a/dojox/mvc/tests/test_mvc_Element.html b/dojox/mvc/tests/test_mvc_Element.html
new file mode 100644
index 0000000..dee3b43
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_Element.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo MVC Node Widget Test</title>
+
+	<style type="text/css">
+		@import "../../../dijit/themes/claro/document.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+
+		.bgRed {
+			background-color: red;
+		}
+
+		.bgGreen {
+			background-color: green;
+		}
+
+		.bgBlue {
+			background-color: blue;
+		}
+
+		.boldText {
+			font-weight: Bold;
+		}
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<script type="text/javascript">
+		require = {
+			isDebug: 1,
+			async: 1,
+			mvc: {debugBindings: 1}
+		};
+	</script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox",
+			"dojo/Stateful",
+			"dojo/parser",
+			"dojox/mvc/parserExtension",
+			"dojo/domReady!"
+		], function(dojox, Stateful, parser){
+
+			titleModel = new Stateful({value: "Foo"});
+			colorModel = new Stateful({value: "bgRed"});
+			boldTextModel = new Stateful({checked: false});
+			parser.parse();
+		});
+	</script>
+</head>
+<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<div>
+		<div>
+			Text:
+			<span data-mvc-bindings="class: at(boldTextModel, 'checked').direction(at.from).transform({format: function(value){ return value ? 'boldText' : ''; }}),
+			                         innerText: at(titleModel, 'value')"></span>
+		</div>
+		<div>
+			Choose text from:
+			<select type="combo" data-mvc-bindings="value: at(titleModel, 'value')">
+				<option value="Foo">Foo</option>
+				<option value="Bar">Bar</option>
+			</select>
+		</div>
+	</div>
+
+	<div style="margin-top:8px;">
+		<div style="width:200px;height:200px;" data-mvc-bindings="class: at(colorModel, 'value')"></div>
+		<div>
+			Choose color from:
+			<select type="combo" data-mvc-bindings="value: at(colorModel, 'value')">
+				<option value="bgRed">Red</option>
+				<option value="bgGreen">Green</option>
+				<option value="bgBlue">Blue</option>
+			</select>
+		</div>
+	</div>
+
+	<div style="margin-top:8px;">
+		The text should be bold:
+		<input type="checkbox" data-mvc-bindings="checked: at(boldTextModel, 'checked')">
+	</div>
+  </body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_HTML5Element.html b/dojox/mvc/tests/test_mvc_HTML5Element.html
new file mode 100644
index 0000000..50e472f
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_HTML5Element.html
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo MVC Node Widget Test</title>
+
+	<style type="text/css">
+		@import "../../../dijit/themes/claro/document.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+
+		.bgRed {
+			background-color: red;
+		}
+
+		.bgGreen {
+			background-color: green;
+		}
+
+		.bgBlue {
+			background-color: blue;
+		}
+
+		.boldText {
+			font-weight: Bold;
+		}
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<script type="text/javascript">
+		require = {
+			isDebug: 1,
+			async: 1,
+			mvc: {debugBindings: 1}
+		};
+	</script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+
+	<script type="text/javascript">
+		require([
+			"dojox",
+			"dojo/Stateful",
+			"dojo/parser",
+			"dojo/date/stamp",
+			"dojo/date/locale",
+			"dojox/mvc/parserExtension",
+			"dojo/domReady!"
+		], function(dojox, Stateful, parser, stamp){
+
+			progressModel = new Stateful({value: 0});
+			datetimeModel = new Stateful({value: new Date});
+			colorModel = new Stateful({value: "#000000"});
+
+			utcISODateTimeConverter = {
+				format: function(value){
+					return stamp.toISOString(value, {zulu: 1});
+				},
+				parse: function(value){
+					return stamp.fromISOString(value);
+				}
+			};
+
+			localISODateTimeConverter = {
+				format: function(value){
+					return stamp.toISOString(value).replace(/[\+\-]\d{2}:\d{2}$/, "");
+				},
+				parse: function(value){
+					return stamp.fromISOString(value);
+				}
+			};
+
+			isoDateConverter = {
+				format: function(value){
+					return stamp.toISOString(value, {selector: "date"});
+				},
+				parse: function(value){
+					var utcDate = stamp.fromISOString(value + "T00:00:00Z"),
+					 current = this.source.value;
+					return new Date(utcDate.getUTCFullYear(), utcDate.getUTCMonth(), utcDate.getUTCDate(), current.getHours(), current.getMinutes(), current.getSeconds(), current.getMilliseconds());
+				}
+			};
+
+			isoTimeConverter = {
+				format: function(value){
+					return stamp.toISOString(value, {selector: "time"}).substr(1);
+				},
+				parse: function(value){
+					var utcTime = stamp.fromISOString("1970-01-01T" + value + "Z"),
+					 current = this.source.value;
+					return new Date(current.getFullYear(), current.getMonth(), current.getDate(), utcTime.getUTCHours(), utcTime.getUTCMinutes(), utcTime.getUTCSeconds(), utcTime.getUTCMilliseconds());
+				}
+			};
+
+			parser.parse();
+		});
+	</script>
+</head>
+<body class="claro">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1>Progress elements</h1>
+	<div>
+		Progress:
+		<progress max="100" data-mvc-bindings="value: at(progressModel, 'value')">Hoge</progress>
+	</div>
+	<div>
+		Meter:
+		<meter min="0" max="100" low="20" high="80" optimum="50" data-mvc-bindings="value: at(progressModel, 'value')"></meter>
+	</div>
+	<div>
+		Range:
+		<input type="range" data-mvc-bindings="value: at(progressModel, 'value')">
+	</div>
+	<h1>Date/time elements</h1>
+	<div>
+		Date/time (UTC):
+		<input type="datetime" data-mvc-bindings="value: at(datetimeModel, 'value').transform(utcISODateTimeConverter)">
+	</div>
+	<div>
+		Date:
+		<input type="date" data-mvc-bindings="value: at(datetimeModel, 'value').transform(isoDateConverter)">
+	</div>
+	<div>
+		Time:
+		<input type="time" data-mvc-bindings="value: at(datetimeModel, 'value').transform(isoTimeConverter)">
+	</div>
+	<div>
+		Date/time (Local):
+		<input type="datetime-local" data-mvc-bindings="value: at(datetimeModel, 'value').transform(localISODateTimeConverter)">
+	</div>
+	<h1>Others</h1>
+	<div>
+		Color:
+		<input type="color" data-mvc-bindings="value: at(colorModel, 'value')">
+		<output data-mvc-bindings="value: at(colorModel, 'value')"></output>
+	</div>
+	<div>
+		Output (for above progress):
+		<output data-mvc-bindings="value: at(progressModel, 'value')"></output>
+	</div>
+	<div>
+		Output (for above date):
+		<output data-mvc-bindings="value: at(datetimeModel, 'value').direction(at.from).transform(dojo.date.locale)"></output>
+	</div>
+  </body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_bindings-simple.html b/dojox/mvc/tests/test_mvc_bindings-simple.html
deleted file mode 100755
index 4535d78..0000000
--- a/dojox/mvc/tests/test_mvc_bindings-simple.html
+++ /dev/null
@@ -1,182 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Static Master/Detail Pattern -- Binding Test</title>
-
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
-		<script type="text/javascript">
-
-		var model; 
-
-		require([
-			'dojo/_base/kernel',
-			'dojo/parser',
-			'dojo/ready',
-			'dojox/mvc',
-			'dijit/form/TextBox',
-			'dijit/form/Button',
-			'dijit/form/ValidationTextBox',
-			'dijit/form/NumberTextBox',
-			'dojox/mvc/Group',
-			'dojox/mvc/Output'
-			], function(dojo, parser, ready, mvc){
-		  // The dojox.mvc.StatefulModel class creates a data model instance
-		  // where each leaf within the data model is decorated with dojo.Stateful
-		  // properties that widgets can bind to and watch for their changes.
-		  model = mvc.newStatefulModel({ data : 
-				{	"First" : "John", 
-					"Last" : "Doe", 
-					"Email" : "jdoe at example.com", 
-					"Num" : 3 
-				}
-			});
-		  console.log("model is ");
-		  console.log(model);
-
-			function testFirstRelevance(newValue) {
-			  //newValue = model.First.value;
-				if ( newValue !== "0" ) return true;
-				else return false;
-			}
-
-			function testFirstReadOnly(newValue) {
-				if ( newValue !== "2" && newValue !== "3"	 ) return false;
-				else return true;
-			}
-
-			function testNumValid(newValue) {
-				if ( newValue !== 1 && newValue !== "1"  && newValue !== "3") return true;
-				else return false;
-			}
-
-			function testRequired(newValue) {
-				if ( newValue !== 4 && newValue !== "4") return false;
-				else return true;
-			}
-
-			function testLastRelevance(newValue) {
-				//newValue = model.First.value;
-				if ( newValue !== "0" ) return true;
-				else return false;
-			}
-
-			function testLastValid(newValue) {
-				if ( newValue !== "1" ) return true;
-				else return false;
-			}
-		
-			function init(){
-				// bind tests, "read-only" etc.
-				mvc.bind(model.First, "value", model.First, "readOnly", testFirstReadOnly, true);
-				mvc.bind(model.First, "value", model.First, "relevant", testFirstRelevance, true);
-				mvc.bind(model.First, "value", model.First, "valid", testNumValid, true);
-				mvc.bind(model.Num, "value", model.Num, "valid", testNumValid, true);
-
-				// bind tests bind Last value to Email relevant and valid
-				mvc.bind(model.Last, "value", model.Email, "relevant", testFirstRelevance, true);
-				mvc.bind(model.Last, "value", model.Email, "valid", testNumValid, true);
-				mvc.bind(model.Last, "value", model.Email, "readOnly", testFirstReadOnly, true);
-				mvc.bind(model.Last, "value", model.Email, "required", testRequired, true);
-				mvc.bind(model.Last, "value", model.Email, "value");
-			}
-			ready(init);
-		});
-		
-		</script>
-	</head>
-	<body class="claro">
-		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>Binding Tests</h1>
-		  </div>
-		</div>
-		<div id="main">
-		  <div id="leftNav">
-		  </div>
-		  <div id="mainContent">
-			<h2>Bind Self Tests</h2>
-			<div class="row">
-				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 0 to test for Relevant false (disabled) (use Reset to re-enable)</label>
-				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 1 to test for Valid false.</label>
-				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 2 to test for Read-only false (use Reset to re-enable)</label>
-				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 3 to test for Read-only false and Valid false (use Reset to re-enable)</label>
-			</div>
-			<div class="row">
-				<label class="cell" for="firstnameInput">First:</label>
-				<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.ValidationTextBox"
-									data-dojo-props="ref: model.First"></input>
-				<!-- Content in output below will always be in sync with value of textbox above -->
-				<span id="tout" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
-					(first name is: ${this.value})
-				</span>
-				
-			</div>
-		   <div class="row">
-				<label class="cell" for="firstnameInput"></label>
-				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
-					Relevant is:  ${this.ref.relevant}, Valid is: ${this.ref.valid}, Read-only is: ${this.ref.readOnly})
-				</span>			   
-			</div>
-			<div class="row">
-				<label style="display:inline-block; width:100%; text-align:left;">Num: Enter 1 for Valid false</label>
-			</div>
-			<div class="row">
-				<label class="cell" for="numInput">Num:</label>
-				<input class="cell" id="numInput" data-dojo-type="dijit.form.NumberTextBox"
-									data-dojo-props="ref: model.Num"></input>
-				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Num">
-					(num is: ${this.value})
-				</span>
-			</div>
-			<h2>Bind Tests</h2>
-			<div class="row">
-				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 0 to test for Relevant false (disabled) for Email.</label>
-				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 1 to test for Valid false for Email.</label>
-				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 2 to test for Read-only true for Email.</label>
-				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 3 to test for Read-only true and Valid false for Email.</label>
-				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 4 to test for Required true for Email.</label>
-			</div>			
-			
-			<div class="row">
-				<label class="cell" for="lastnameInput">Last:</label>
-				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Last"></input>
-				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Last">
-					(last name is: ${this.value})
-				</span>
-			</div>
-			<div class="row">
-				<label class="cell" for="emailInput">Email:</label>
-				<input class="cell" id="emailInput" data-dojo-type="dijit.form.ValidationTextBox"
-									data-dojo-props="ref: model.Email"></input>
-				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
-					(email is: ${this.value})
-				</span>
-			</div>
-		   <div class="row">
-				<label class="cell" for="emailInput"></label>
-				<span id="emailOut" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
-					Relevant is:  ${this.ref.relevant}, Valid is: ${this.ref.valid}, Read-only is: ${this.ref.readOnly}, Required is: ${this.ref.required})
-				</span>
-		   </div>
-			
-			<br/>Model:
-			<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){doReset()}">Reset</button>
-		  </div>
-		</div></div>
-		<script type="text/javascript">
-			function doReset() {
-				model.reset();
-			}
-		</script>
-		
-	</body>
-</html>
diff --git a/dojox/mvc/tests/test_mvc_dates.html b/dojox/mvc/tests/test_mvc_dates.html
deleted file mode 100644
index e402908..0000000
--- a/dojox/mvc/tests/test_mvc_dates.html
+++ /dev/null
@@ -1,407 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-	<title>13899 mvc Stateful Dates</title>
-
-	<style>
-		@import "../../../dijit/themes/claro/document.css";
-		@import "../../../util/doh/robot/robot.css";
-		@import "../../../dijit/tests/css/dijitTests.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		data-dojo-config="isDebug: true, parseOnLoad: false"></script>
-
-	<!-- only needed for alternate theme testing: -->
-	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
-
-	<script type="text/javascript">
-	var model;
-			
-		require([
-			'dijit/form/DateTextBox',
-			'dijit/CalendarLite',
-			'dojox/mvc/StatefulModel',
-			'dijit/form/Button',
-			'dojox/mvc/Output',
-			'dijit/form/TextBox',
-			'dojo/date/stamp',
-			'dojox/mvc',
-			'dojo/on',
-			'dojo/domReady!'
-		], function (DateTextBox, Calendar, StatefulModel, Button, Output, TextBox, dateStamp) {
-
-			// *** Test1 setup begin: ***
-			var test1_init = dateStamp.fromISOString("1987-08-01"); // 8/1/1987
-			test1_model = new StatefulModel({
-				data: {
-					date: test1_init
-				}
-			});
-			var test1_cal = new Calendar({
-				ref: test1_model.date // bind to model.date
-			}, document.getElementById('test1_cal'));
-			test1_cal.startup();
-
-			var test1_cal2 = new Calendar({
-				ref: test1_model.date // bind to model.date
-			}, document.getElementById('test1_cal2'));
-			test1_cal2.startup();
-
-			var test1_txt2 = new TextBox({
-				ref: test1_model.date
-			}, document.getElementById('test1_txt2'));
-			dojo.style(test1_txt2.domNode, "width", "368px");
-			test1_txt2.startup();
-
-			var test1_out2 = new Output({
-				ref: test1_model.date // bind to model.date
-			}, document.getElementById('test1_output2'));
-			test1_out2.startup();
-
-			var test1_setday2 = new Button({
-				label: 'Set Calendar to dateStamp.fromISOString("1991-09-07") (Sep 7 1991)', 
-				onClick: function() {
-							//console.log("test1_setday2 called");
-							//var day2 = new Date(1991,9,7);  // 9/7/1991
-							//var day2 = new Date("1991-09-07");  // 9/7/1991
-							var day2 = dateStamp.fromISOString("1991-09-07"); // 9/7/1991
-							test1_cal2.set("value", day2);
-						} 
-			}, document.getElementById('test1_setdate1'));
-			test1_setday2.startup();
-
-			var test1_settext2 = new Button({
-				label: 'Set TextBox to dateStamp.fromISOString("1991-05-05") (May 5, 1991)', 
-				onClick: function() {
-							//test1_txt2.set("value", new Date("1993-05-05")); // ISO date format  
-							test1_txt2.set("value", dateStamp.fromISOString("1991-05-05")); // 5/5/1993
-							//test1_cal2.set("value", "1991-05-05"); 
-							//test1_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
-						} 
-			}, document.getElementById('test1_setdate2'));
-			test1_settext2.startup();
-
-			var test1_settext3 = new Button({
-				label: 'Set TextBox to ISO String("2011-11-06") (Nov 6, 2011) fails on IE', 
-				onClick: function() {
-							//test1_txt2.set("value", new Date("2011-11-07")); // ISO date format  
-							test1_txt2.set("value", "2011-11-07"); // 11/6/2011
-							//test1_cal2.set("value", "2011-11-07"); 
-							//test1_txt2.set("value", "Sun Nov 06 2011 01:00:00 GMT-0500 (Eastern Standard Time)");  
-						} 
-			}, document.getElementById('test1_setdate3'));
-			test1_settext3.startup();
-
-			var test1_reset2 = new Button({
-				label: "Reset Calendar back to (Aug 1 1987)",
-				onClick: function() {
-							test1_model.date.reset();
-						} 
-			}, document.getElementById('test1_reset2'));
-			test1_reset2.startup();
-			// *** Test1 setup end: ***
-
-			// *** Test2 setup begin: ***
-			var test2_init = dateStamp.fromISOString("2011-11-06"); // Nov 6, 2011
-			test2_model = new StatefulModel({
-				data: {
-					date: test2_init
-				}
-			});
-			var test2_cal = new DateTextBox({
-				ref: test2_model.date // bind to model.date
-			}, document.getElementById('test2_cal'));
-			test2_cal.startup();
-
-			var test2_cal2 = new DateTextBox({
-				ref: test2_model.date // bind to model.date
-			}, document.getElementById('test2_cal2'));
-			test2_cal2.startup();
-
-			var test2_txt2 = new TextBox({
-				ref: test2_model.date
-			}, document.getElementById('test2_txt2'));
-			dojo.style(test2_txt2.domNode, "width", "368px");
-			test2_txt2.startup();
-
-			var test2_out2 = new Output({
-				ref: test2_model.date // bind to model.date
-			}, document.getElementById('test2_output2'));
-			test2_out2.startup();
-
-			var test2_setday2 = new Button({
-				label: 'Set DateTextBox to new Date(1993,9,28) (Oct 28, 1993)', 
-				onClick: function() {
-							var day2 = new Date(1993,9,28);  // 10/28/1993
-							//var day2 = new Date("1993-10-28");  // 10/28/1993
-							//var day2 = dateStamp.fromISOString("1993-09-28"); // 10/28/1997
-							//test2_cal2.set("value", day2);
-							test2_txt2.set("value", day2);
-						} 
-			}, document.getElementById('test2_setdate1'));
-			test2_setday2.startup();
-
-			var test2_settext2 = new Button({
-				label: 'Set DateTextBox to dateStamp.fromISOString("1997-10-14") (Oct 14 1997)', 
-				onClick: function() {
-							//test2_txt2.set("value", new Date("1997-10-14")); // ISO date format  
-							test2_txt2.set("value", dateStamp.fromISOString("1997-10-14")); // Oct 14 1997
-							//test2_cal2.set("value", "1997-10-14"); 
-							//test2_txt2.set("value", "Tue Oct 14 1997 00:00:00 GMT-0400 (Eastern Daylight Time)");  
-						} 
-			}, document.getElementById('test2_setdate2'));
-			test2_settext2.startup();
-
-			var test2_reset2 = new Button({
-				label: "Reset DateTextBox back to (Nov 6 2011)",
-				onClick: function() {
-							test2_model.date.reset();
-						} 
-			}, document.getElementById('test2_reset2'));
-
-			var test2_settext3 = new Button({
-				label: 'Set TextBox to ISO String("1991-05-05") (May 5, 1991)', 
-				onClick: function() {
-							//test2_txt2.set("value", new Date("1991-05-05")); // ISO date format  
-							test2_txt2.set("value", "1991-05-05"); // 5/5/1993
-							//test2_cal2.set("value", "1991-05-05"); 
-							//test2_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
-						} 
-			}, document.getElementById('test2_setdate3'));
-			test2_settext3.startup();
-
-			test2_reset2.startup();
-			// *** Test2 setup end: ***
-
-
-			// *** Test3 setup begin: ***
-			// *** Test3 setup begin: ***
-			var test3_init = dateStamp.fromISOString("2011-08-27"); // 8/27/2011
-			test3_model = new StatefulModel({
-				data: {
-					date: test3_init,
-					date2: test3_init
-				}
-			});
-			var test3_cal = new Calendar({
-				ref: test3_model.date // bind to model.date
-			}, document.getElementById('test3_cal'));
-			test3_cal.startup();
-
-			var test3_cal2 = new DateTextBox({
-				ref: test3_model.date // bind to model.date
-			}, document.getElementById('test3_cal2'));
-			test3_cal2.startup();
-
-			var test3_txt2 = new TextBox({
-				ref: test3_model.date,
-				disabled: true
-			}, document.getElementById('test3_txt2'));
-			dojo.style(test3_txt2.domNode, "width", "368px");
-			test3_txt2.startup();
-
-			var test3_out2 = new Output({
-				ref: test3_model.date // bind to model.date
-			}, document.getElementById('test3_output2'));
-			test3_out2.startup();
-
-			var test3_setday2 = new Button({
-				label: 'Set Calendar to dateStamp.fromISOString("1997-10-14") (Oct 14 1997)', 
-				onClick: function() {
-							//console.log("test3_setday2 called");
-							//var day2 = new Date(1997,10,14);  // 10/14/1997
-							//var day2 = new Date("1997-10-14");  // 10/14/1997
-							var day2 = dateStamp.fromISOString("1997-10-14"); // 10/14/1997
-							test3_cal2.set("value", day2);
-						} 
-			}, document.getElementById('test3_setdate1'));
-			test3_setday2.startup();
-
-			var test3_settext2 = new Button({
-				label: 'Set TextBox to dateStamp.fromISOString("2011-11-06") (Nov 6, 2011)', 
-				onClick: function() {
-							//test3_txt2.set("value", new Date("2011-11-06")); // ISO date format  
-							test3_txt2.set("value", dateStamp.fromISOString("2011-11-06")); // 11/6/2011
-							//test3_cal2.set("value", "2011-11-06"); 
-							//test3_txt2.set("value", "2011-11-06"); // FAILS
-							//test3_txt2.set("value", "1991-05-06"); // 5/5/1991
-							//test3_txt2.set("value", "Sun Nov 06 2011 00:00:00 GMT-0400 (Eastern Daylight Time)");  
-						} 
-			}, document.getElementById('test3_setdate2'));
-			test3_settext2.startup();
-
-			var test3_settext3 = new Button({
-				label: 'Set TextBox to ISO String("1991-05-06T01:00:00") via new Date (May 5, 1991)', 
-				onClick: function() {
-							//test3_txt2.set("value", new Date("1991-05-05")); // ISO date format
-							var d = new Date("1991-05-06T01:00:00");  
-							test3_txt2.set("value", d); // 5/5/1991 YYYY-MM-DDThh:mm:ss via new Date
-							//test3_txt2.set("value", "1991-05-06T01:00:00"); // 5/5/1991 YYYY-MM-DDThh:mm:ss FAILS
-							//test3_cal2.set("value", "1991-05-05"); 
-							//test3_txt2.set("value", "Sun May 05 1991 00:00:00 GMT-0400 (Eastern Daylight Time)");  
-						} 
-			}, document.getElementById('test3_setdate3'));
-			test3_settext3.startup();
-			if(dojo.isIE){ // new Date("1991-05-06") will not work on IE
-				test3_settext3.set('disabled',true);
-			}
-
-			var test3_reset2 = new Button({
-				label: "Reset Calendar back to (Aug 27 2011)",
-				onClick: function() {
-							//console.log("test3_callreset2 called");
-							test3_model.date.reset();
-						} 
-			}, document.getElementById('test3_reset2'));
-			test3_reset2.startup();
-			// *** Test3 setup end: ***
-
-
-
-			// *** Test4 setup begin: RegExp Test***
-			// *** Test4 setup begin: RegExp Test***
-			var regx = new RegExp("abc","i");			
-			test4_model = new StatefulModel({
-				data: {
-					//regex: /abc/i // should be regex: /abc/
-					regex: regx // should be regex: /abc/
-				}
-			});
-
-			console.log('test4_model.regex', test4_model.regex.get('value'));
-			var str = "ABCDEFGHIJKLMNOP abcdefghi";
-			var patt1 = test4_model.regex.get('value');
-			console.log("str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
-			console.log('str.match(patt1)',str.match(patt1));
-			test4_model.regex.set('value',/def/);
-			console.log("set to def str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
-			test4_model.regex.reset();
-			console.log("after reset str.match(test4_model.regex.get('value')) is ",str.match(test4_model.regex.get('value')));
-			// *** Test4 setup end: ***
-	
-		});
-	</script>
-</head>
-
-<body class="claro">
-			<h2>Test 1: Two Calendars bound to each other, a TextBox and an mvc Output field.</h2>
-				<div  style="border-style: solid; border-width: 2px; width: 827px;">
-					<table>
-						<tbody>
-							<tr>
-								<td><div id="test1_cal"></div></td>
-								<td><div id="test1_cal2"></div></td>
-								<td>
-					<table><tbody>
-								<tr><td><label for="test1_txt2">TextBox bound to date:</label></td></tr>
-								<tr><td><div id="test1_txt2"></div></td></tr>
-								<tr><td><label for="test1_txt2">MVC Output bound to date:</label></td></tr>
-								<tr><td><div id="test1_output2"></div></td></tr>
-					</tbody></table>
-					<table><tbody><tr>
-								<td><div id="test1_setdate1"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test1_setdate2"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test1_setdate3"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test1_reset2"></div></td>
-					</tr></tbody></table>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</div>
-
-			<h2>Test 2: Two DateTextBoxes bound to each other, a TextBox and an mvc Output field.</h2>
-				<div  style="border-style: solid; border-width: 2px; width: 827px;">
-					<table>
-						<tbody>
-							<tr>
-								<td style="vertical-align: top;"><div id="test2_cal"></div></td>
-								<td style="vertical-align: top;"><div id="test2_cal2"></div></td>
-								<td>
-					<table><tbody>
-								<tr><td><label for="test2_txt2">TextBox bound to date:</label></td></tr>
-								<tr><td><div id="test2_txt2"></div></td></tr>
-								<tr><td><label for="test2_txt2">MVC Output bound to date:</label></td></tr>
-								<tr><td><div id="test2_output2"></div></td></tr>
-					</tbody></table>
-					<table><tbody><tr>
-								<td><div id="test2_setdate1"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test2_setdate2"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test2_setdate3"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test2_reset2"></div></td>
-					</tr></tbody></table>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</div>
-
-
-			<h2>Test 3: One Calendar bound to a DateTextbox, a TextBox and an mvc Output field.</h2>
-				<div  style="border-style: solid; border-width: 2px; width: 827px;">
-					<table>
-						<tbody>
-							<tr>
-								<td style="vertical-align: top;"><div id="test3_cal"></div></td>
-								<td style="vertical-align: top;"><div id="test3_cal2"></div></td>
-								<td>
-					<table><tbody>
-								<tr><td><label for="test3_txt2">TextBox bound to date: (disabled to avoid error)</label></td></tr>
-								<tr><td><div id="test3_txt2"></div></td></tr>
-								<tr><td><label for="test3_txt2">MVC Output bound to date:</label></td></tr>
-								<tr><td><div id="test3_output2"></div></td></tr>
-					</tbody></table>
-					<table><tbody><tr>
-								<td><div id="test3_setdate1"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test3_setdate2"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test3_setdate3"></div></td>
-					</tr></tbody></table>
-					<table><tbody><tr>
-								<td><div id="test3_reset2"></div></td>
-					</tr></tbody></table>
-								</td>
-							</tr>
-						</tbody>
-					</table>
-				</div>
-	<!--  	  
-			<h2>I see these problems Binding a TextBox to DateTextBox and Calendar:</h2>
-				<div  style="border-style: solid; border-width: 2px; width: 827px;">
-				<span>There is also a problem when trying to set a date string in this format:</span><br>
-				<span>"Wed May 05 2010 01:00:00 GMT-0400 (Eastern Daylight Time)" into a  into a TextBox bound to a dijit.form.DateTextbox, but that works in a Calendar.</span><br>
-				<span>It is ending up with the DateTextBox set to null.  : </span><br>
-				<span></span><br>
-				<span>There is also a problem when trying to set a date ISO format date string like "1991-05-05":</span><br>
-				<span>"into a  into a TextBox bound to a Calendar, but that works for a dijit.form.DateTextbox.</span><br>
-				<span>It is loops for a while and gets range errors in the console.  : </span><br>
-				<span></span><br>
-				<span>Another thing I have found was that on a calendar I would get a different value from dijit.byId("cal").get('value') and dijit.byId("cal").value.</span><br>
-				<span>dijit.byId("cal").value:        Wed May 05 2010 <b>01:00:00</b> GMT-0400 (Eastern Daylight Time)</span><br>
-				<span>dijit.byId("cal").get('value'): Wed May 05 2010 <b>00:00:00</b> GMT-0400 (Eastern Daylight Time)</span><br>
-				<span>dijit.byId("cal").get('value') is getting 00:00:00 when it seems like it should be 01:00:00</span><br>
-				</div>
-	-->
-</body>
-</html>
diff --git a/dojox/mvc/tests/test_mvc_form-kitchensink.html b/dojox/mvc/tests/test_mvc_form-kitchensink.html
deleted file mode 100644
index 1649366..0000000
--- a/dojox/mvc/tests/test_mvc_form-kitchensink.html
+++ /dev/null
@@ -1,651 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Data-bound Form element Kitchen Sink test</title>
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-			label {
-				text-align: left;
-				width: 100%;
-			}
-		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
-		<script type="text/javascript">
-
-		var store, selmodel, decselmodel, numspinmodel; 
-		var store2, filmodel, decfilmodel;
-		var combomodel, deccombomodel;
-		var datemodel, decdatemodel; 
-		var slidermodel, decslidermodel;
-		var numspinmodel, decnumspinmodel;
-		var simpTAmodel, decsimpTAmodel;
-		var textareamodel, dectextareamodel;
-		var deccalmodel, deccolormodel;
-
-		require([
-			'dojo/_base/kernel',
-			'dojo/parser',
-			'dojo/ready',
-			'dojox/mvc',
-			'dijit/form/TextBox',
-			'dijit/form/Button',
-			'dijit/form/Select',
-			'dijit/form/FilteringSelect',
-			'dijit/form/ComboBox',
-			'dijit/form/DateTextBox',
-			'dijit/form/HorizontalSlider',
-			'dijit/form/NumberSpinner',
-			'dijit/form/SimpleTextarea',
-			'dijit/form/Textarea',
-			'dojo/data/ItemFileReadStore',
-			'dijit/Calendar',
-			'dijit/ColorPalette',
-			'dojox/mvc/Group',
-			'dojox/mvc/Output',
-			'dojo/date/locale'
-			], function(dojo, parser, ready, mvc, TextBox, Button, Select, FilteringSelect, ComboBox, DateTextBox, HorizontalSlider, NumberSpinner,
-						SimpleTextarea, Textarea, ItemFileReadStore, Calendar, ColorPalette){
-
-			var alreadyset = false;	
-			var data = [
-				{id: '1',name:"one"},
-				{id: '2',name:"two"},
-				{id: '3',name:"three"},
-				{id: '4',name:"four"},
-				{id: '5',name:"five"},
-				{id: '6',name:"six"},
-				{id: '7',name:"seven"},
-				{id: '8',name:"eight"},
-				{id: '9',name:"nine"},
-				{id: '10',name:"ten"},
-				{id: '11',name:"eleven"},
-				{id: '12',name:"twelve"},
-				{id: '13',name:"thirteen"}
-			  ];
-			store = new ItemFileReadStore({
-				data: {
-					identifier: 'id',
-					label: 'name',
-					items: data
-				}
-			});
-
-			var data2 = {
-				identifier: "value",
-				label: "label",
-				items: [
-					{value: "1", label: "one"},
-					{value: "2", label: "two"},
-					{value: "3", label: "three"},
-					{value: "4", label: "four"},
-					{value: "5", label: "five"},
-					{value: "6", label: "six"},
-					{value: "7", label: "seven"},
-					{value: "8", label: "eigth"},
-					{value: "9", label: "nine"},
-					{value: "10", label: "ten"},
-					{value: "11", label: "eleven"},
-					{value: "12", label: "twelve"},
-					{value: "13", label: "thirteen"},
-					{value: "14", label: "fourteen"}
-				]
-			};
-			store2 = new ItemFileReadStore({data:dojo.clone(data2)});
-
-			// create models for selects
-			selmodel = new mvc.newStatefulModel({data: {number: '1'}});
-			decselmodel = new mvc.newStatefulModel({data: {number: '1'}});
-
-			// create models for filtering selects
-			filmodel = new mvc.newStatefulModel({data: {number: '2'}});
-			decfilmodel = new mvc.newStatefulModel({data: {number: '2'}});
-
-			// create models for ComboBoxes
-			combomodel = new mvc.newStatefulModel({data: {number: 'three'}});
-			deccombomodel = new mvc.newStatefulModel({data: {number: 'three'}});
-
-			// create a model for DateTextBox
-			datemodel = new mvc.newStatefulModel({data: {number: "2011-04-04"}});
-			decdatemodel = new mvc.newStatefulModel({data: {number: "2011-04-04"}});
-
-			// create a model for Slider
-			slidermodel = new mvc.newStatefulModel({data: {number: '5'}});
-			decslidermodel = new mvc.newStatefulModel({data: {number: '5'}});
-
-			// create a model for NumberSpinner
-			numspinmodel = new mvc.newStatefulModel({data: {number: '6'}});
-			decnumspinmodel = new mvc.newStatefulModel({data: {number: '6'}});
-
-			// create a model for SimpleTextArea
-			simpTAmodel = new mvc.newStatefulModel({data: {number: '7'}});
-			decsimpTAmodel = new mvc.newStatefulModel({data: {number: '7'}});
-
-			// create a model for TextArea
-			textareamodel = new mvc.newStatefulModel({data: {number: '8'}});
-			dectextareamodel = new mvc.newStatefulModel({data: {number: '8'}});
-
-			// create a model for dijit.Calendar
-			deccalmodel = new mvc.newStatefulModel({data: {date: "Mon Apr 04 2011 01:00:00 GMT-0400 (Eastern Daylight Time)"}});
-
-			// create a model for dijit.ColorPalette
-			deccolormodel = new mvc.newStatefulModel({data: {code: "#000000"}});
-
-			// Handle the programmatic creation of widgets here:
-			
-			// create the select, textbox, output and button			
-			var sel = new Select({
-				store: store,
-				loadChildrenOnOpen: true,
-			//	value: 1,	
-				ref: selmodel.number // bind to model.number
-			}, document.getElementById('sel'));
-			
-			var text = new TextBox({
-				//id: "seltext",
-				ref: selmodel.number
-			}, document.getElementById('seltext'));			
-			text.startup();
-			
-			var selOutput = new mvc.Output({
-				ref: selmodel.number
-			}, document.getElementById('selOutput'));
-			selOutput.startup();
-
-			var reset1 = new Button({
-				onClick: function(){selmodel.reset();},
-				id: "selReset",
-				label: "Reset"
-			}, document.getElementById('reset1'));
-			reset1.startup();
-
-
-			sel.watch('value', function () {
-				//console.log('sel value changed', arguments);
-			});
-
-			text.watch('value', function () {
-				//console.log('text value changed', arguments);
-			});
-			
-			sel.startup();
-			
-
-			// create the filtering select, textbox, output and button			
-			var filsel = new FilteringSelect({
-				store: store,
-				ref: filmodel.number // bind to model.number
-			}, document.getElementById('filsel'));
-			
-			var filtext = new TextBox({
-				ref: filmodel.number
-			}, document.getElementById('filtext'));
-			
-			var filoutput = new mvc.Output({
-				ref: filmodel.number
-			}, document.getElementById('filoutput'));			
-			filoutput.startup();
-
-			var filreset = new Button({
-				onClick: function(){filmodel.reset();},
-				id: "filReset",
-				label: "Reset"
-			}, document.getElementById('filreset'));
-			filreset.startup();
-			
-			filtext.startup();
-			filsel.startup();
-			
-			// create the comboBox, textbox, output and button			
-			var combo = new ComboBox({
-				store: store,
-				ref: combomodel.number // bind to model.number
-			}, document.getElementById('combosel'));
-			
-			var combotext = new TextBox({
-				ref: combomodel.number
-			}, document.getElementById('combotext'));
-			
-			var combooutput = new mvc.Output({
-				ref: combomodel.number
-			}, document.getElementById('combooutput'));			
-			combooutput.startup();
-
-			var comboreset = new Button({
-				onClick: function(){combomodel.reset();},
-				id: "comboReset",
-				label: "Reset"
-			}, document.getElementById('comboreset'));
-			comboreset.startup();
-			
-			combotext.startup();
-			combo.startup();
-			
-			// create the dijit.form.DateTextBox, textbox, output and button			
-			var dateWid = new DateTextBox({
-				ref: datemodel.number // bind to model.number
-			}, document.getElementById('datesel'));
-			
-			var datetext = new TextBox({
-				ref: datemodel.number
-			}, document.getElementById('datetext'));
-			
-			var dateoutput = new mvc.Output({
-				ref: datemodel.number
-			}, document.getElementById('dateoutput'));			
-			dateoutput.startup();
-
-			var datereset = new Button({
-				onClick: function(){datemodel.reset();},
-				id: "dateReset",
-				label: "Reset"
-			}, document.getElementById('datereset'));
-			datereset.startup();
-			
-			datetext.startup();
-			dateWid.startup();
-			
-			// create the dijit.form.HorizontalSlider, textbox, output and button			
-			var sliderWid = new HorizontalSlider({
-						style:{width:"190px"},
-						minimum:0,
-						maximum:100,
-						discreteValues:21,
-				ref: slidermodel.number // bind to model.number
-			}, document.getElementById('slidersel'));
-			
-			var slidertext = new TextBox({
-				ref: slidermodel.number
-			}, document.getElementById('slidertext'));
-			
-			var slideroutput = new mvc.Output({
-				ref: slidermodel.number
-			}, document.getElementById('slideroutput'));			
-			slideroutput.startup();
-
-			var sliderreset = new Button({
-				onClick: function(){slidermodel.reset();},
-				id: "sliderReset",
-				label: "Reset"
-			}, document.getElementById('sliderreset'));
-			sliderreset.startup();
-			
-			slidertext.startup();
-			sliderWid.startup();
-			
-			// create the dijit.form.NumberSpinner, textbox, output and button			
-			var numspinWid = new NumberSpinner({
-			//	constraints:{max:100,places:0},
-				ref: numspinmodel.number // bind to model.number
-			}, document.getElementById('numspinsel'));
-			
-			var numspintext = new TextBox({
-				ref: numspinmodel.number
-			}, document.getElementById('numspintext'));
-			
-			var numspinoutput = new mvc.Output({
-				ref: numspinmodel.number
-			}, document.getElementById('numspinoutput'));			
-			numspinoutput.startup();
-
-			var numspinreset = new Button({
-				onClick: function(){numspinmodel.reset();},
-				id: "numspinReset",
-				label: "Reset"
-			}, document.getElementById('numspinreset'));
-			numspinreset.startup();
-			
-			numspintext.startup();
-			numspinWid.startup();
-			
-			// create the dijit.form.SimpleTextarea, textbox, output and button 			
-			var simpTAWid = new SimpleTextarea({
-				style:{height:"20px", width:"180px"},
-				ref: simpTAmodel.number // bind to model.number
-			}, document.getElementById('simpTAsel'));
-			
-			var simpTAtext = new TextBox({
-				ref: simpTAmodel.number
-			}, document.getElementById('simpTAtext'));
-			
-			var simpTAoutput = new mvc.Output({
-				ref: simpTAmodel.number
-			}, document.getElementById('simpTAoutput'));			
-			simpTAoutput.startup();
-
-			var simpTAreset = new Button({
-				onClick: function(){simpTAmodel.reset();},
-				id: "simpTAReset",
-				label: "Reset"
-			}, document.getElementById('simpTAreset'));
-			simpTAreset.startup();
-			
-			simpTAtext.startup();
-			simpTAWid.startup();
-
-			// create the dijit.form.Textarea, textbox, output and button 
-			var textareaWid = new Textarea({
-			//	constraints:{max:100,places:0},
-				ref: textareamodel.number // bind to model.number
-			}, document.getElementById('textareasel'));
-			
-			var textareatext = new TextBox({
-				ref: textareamodel.number
-			}, document.getElementById('textareatext'));
-			
-			var textareaoutput = new mvc.Output({
-				ref: textareamodel.number
-			}, document.getElementById('textareaoutput'));			
-			textareaoutput.startup();
-
-			var textareareset = new Button({
-				onClick: function(){textareamodel.reset();},
-				id: "textareaReset",
-				label: "Reset"
-			}, document.getElementById('textareareset'));
-			textareareset.startup();
-			
-			textareatext.startup();
-			textareaWid.startup();
-
-			});
-
-		</script>
-	</head>
-	<body class="claro">
-		<div id="wrapper">
-			<div id="header" style="margin-top: 0px;">
-				<div id="navigation"  style="margin-top: 0px;"></div>
-				<div id="headerInsert"  style="margin-top: 0px;">
-					<h2>Data-bound Form Element Kitchen Sink MVC test</h2>
-				</div>
-			</div>
-			<div id="main" style="margin-top: 0px;">
-				<div id="leftNav"></div>
-				<div id="mainContent">
-	
-					<h2 style="margin-top: 0px;">Programmatic creation of Form elements:</h2>
-					<table>
-						<tbody>
-							<tr>
-								<td><label>Widget</label></td>
-								<td><label></label></td>
-								<td><label>Textbox</label></td>
-								<td><label>Output</label></td>
-								<td><label>Model Reset</label></td>
-							</tr>
-							<tr>
-								<td><label for="sel">Select:</label></td>
-								<td><div id="sel"></div></td>
-								<td><div id="seltext"></div></td>
-								<td><div id="selOutput"></div></td>
-								<td><div id="reset1" ></div></td>
-							</tr>
-							<tr>
-								<td><label for="filsel">FilteringSelect:</label></td>
-								<td><div id="filsel"></div></td>
-								<td><div id="filtext"></div></td>
-								<td><div id="filoutput"></div></td>
-								<td><div id="filreset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="combosel">ComboBox:</label></td>
-								<td><div id="combosel"></div></td>
-								<td><div id="combotext"></div></td>
-								<td><div id="combooutput"></div></td>
-								<td><div id="comboreset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="datesel">DateTextBox:</label></td>
-								<td><div id="datesel"></div></td>
-								<td><div id="datetext"></div></td>
-								<td><div id="dateoutput"></div></td>
-								<td><div id="datereset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="slidersel">Slider:</label></td>
-								<td><div id="slidersel"></div></td>
-								<td><div id="slidertext"></div></td>
-								<td><div id="slideroutput"></div></td>
-								<td><div id="sliderreset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="numspinsel">NumberSpinner:</label></td>
-								<td><div id="numspinsel"></div></td>
-								<td><div id="numspintext"></div></td>
-								<td><div id="numspinoutput"></div></td>
-								<td><div id="numspinreset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="simpTAsel">SimpleTextArea:</label></td>
-								<td><div id="simpTAsel"></div></td>
-								<td><div id="simpTAtext"></div></td>
-								<td><div id="simpTAoutput"></div></td>
-								<td><div id="simpTAreset"></div></td>
-							</tr>
-							<tr>
-								<td><label for="textareasel">TextArea:</label></td>
-								<td><div id="textareasel"></div></td>
-								<td><div id="textareatext"></div></td>
-								<td><div id="textareaoutput"></div></td>
-								<td><div id="textareareset"></div></td>
-							</tr>
-						</tbody>
-					</table>
-	  
-					<h2>Declarative creation of Form elements:</h2>
-					<table>
-						<tbody>
-							<tr>
-								<td><label>Widget</label></td>
-								<td><label></label></td>
-								<td><label>Textbox</label></td>
-								<td><label>Output</label></td>
-								<td><label>Model Reset</label></td>
-							</tr>
-							<tr>
-							<!--  <td><label for="decsel">Select:</label></td>
-								<td>
-									<select id="decsel" style="width: 188px;" 
-													data-dojo-id="decsel" data-dojo-type="dijit.form.Select" 
-													data-dojo-props='name:"decsel",loadChildrenOnOpen: true, ref: decselmodel.number '>
-										<option value="1">one</option>
-										<option value="2">two</option>
-										<option value="3">three</option>
-										<option value="4">four</option>
-									</select>
-								</td>
-							-->	
-								<td><label for="decsel">Select:</label></td>
-								<td>
-									<select id="decsel" style="width: 188px;" 
-													data-dojo-id="decsel" data-dojo-type="dijit.form.Select" 
-													data-dojo-props='store:store, name:"decsel",loadChildrenOnOpen: true, ref: decselmodel.number '>
-									</select>
-								</td>
-								<td>
-									<input class="cell" id="decseltext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decselmodel.number"></input>
-								</td>
-								<td><span   id="decselOutput" data-dojo-type="dojox.mvc.Output"
-											data-dojo-props="ref: decselmodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decselReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){decselmodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="decfilsel">FilteringSelect:</label></td>
-								<td>
-									<input id="decfilsel" data-dojo-type="dijit.form.FilteringSelect"
-										data-dojo-props='store:store, ref: decfilmodel.number'/>
-								</td>
-								<td>
-									<input id="decfiltext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decfilmodel.number"></input>
-								</td>
-								<td><span id="decfilOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: decfilmodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decfilReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){decfilmodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="deccombosel">ComboBox:</label></td>
-								<td>
-									<input id="deccombosel" data-dojo-type="dijit.form.ComboBox"
-										data-dojo-props='store:store, ref: deccombomodel.number'/>
-								</td>
-								<td>
-									<input id="deccombotext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: deccombomodel.number"></input>
-								</td>
-								<td><span id="deccomboOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: deccombomodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="deccomboReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){deccombomodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="datesel">DateTextBox:</label></td>
-								<td>
-									<input id="decdatesel" data-dojo-type="dijit.form.DateTextBox"
-										data-dojo-props='store:store, ref: decdatemodel.number'/>
-								</td>
-								<td>
-									<input id="decdatetext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decdatemodel.number"></input>
-								</td>
-								<td><span id="decdateOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: decdatemodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decdateReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){decdatemodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="decslidersel">Slider:</label></td>
-								<td>
-									<input id="decslidersel" data-dojo-type="dijit.form.HorizontalSlider"
-										data-dojo-props='store:store, ref: decslidermodel.number,
-														style:{width:"190px"}, minimum:0, maximum:100, discreteValues:21'/>
-								</td>
-								<td>
-									<input id="decslidertext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decslidermodel.number"></input>
-								</td>
-								<td><span id="decsliderOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: decslidermodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decsliderReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){decslidermodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="decnumspinsel">NumberSpinner:</label></td>
-								<td>
-									<input id="decnumspinsel" data-dojo-type="dijit.form.NumberSpinner"
-										data-dojo-props='store:store, ref: decnumspinmodel.number'/>
-								</td>
-								<td>
-									<input id="decnumspintext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decnumspinmodel.number"></input>
-								</td>
-								<td><span id="decnumspinOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: decnumspinmodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decnumspinReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){decnumspinmodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="decsimpTAsel">SimpleTextArea:</label></td>
-								<td>
-									<input id="decsimpTAsel" data-dojo-type="dijit.form.Textarea"
-										data-dojo-props='store:store, ref: decsimpTAmodel.number'/>
-								</td>
-								<td>
-									<input id="decsimpTAtext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: decsimpTAmodel.number"/>
-								</td>
-								<td><span id="decsimpTAOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: decsimpTAmodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="decsimpTAReset" type="button" data-dojo-type="dijit.form.Button" 
-										data-dojo-props="onClick: function(){decsimpTAmodel.reset();}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="dectextareasel">TextArea:</label></td>
-								<td>
-									<input id="dectextareasel" data-dojo-type="dijit.form.Textarea"
-										data-dojo-props='store:store, ref: dectextareamodel.number'/>
-								</td>
-								<td>
-									<input id="dectextareatext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: dectextareamodel.number"/>
-								</td>
-								<td><span id="dectextareaOutput" data-dojo-type="dojox.mvc.Output" 
-											data-dojo-props="ref: dectextareamodel.number">
-						 			${this.value}
-								</span></td>
-								<td><button id="dectextareaReset" type="button" data-dojo-type="dijit.form.Button" 
-										data-dojo-props="onClick: function(){dectextareamodel.reset();}">Reset</button></td>
-							</tr>
-						</tbody>
-					</table>
-	  
-					<h2>Test data-bound dijit.Calendar:</h2>
-					<table>
-						<tbody>
-							<tr>
-								<td><label>Widget</label></td>
-								<td><label></label></td>
-								<td><label>Textbox</label></td>
-								<td><label>Output</label></td>
-								<td><label>Model Reset</label></td>
-							</tr>
-							<tr>
-								<td><label for="deccal">Calendar:</label></td>
-								<td>
-									<input class="cell"  id="deccal" data-dojo-id="deccal"  data-dojo-type="dijit.Calendar" 
-											data-dojo-props='ref: deccalmodel.date '/>
-								</td>
-								<td>
-									<input class="cell" id="deccaltext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: deccalmodel.date"></input>
-								</td>
-								<td><span   id="deccalOutput" data-dojo-type="dojox.mvc.Output"
-											data-dojo-props="ref: deccalmodel.date">
-						 			${this.value}
-								</span></td>
-								<td><button id="deccalReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){deccalmodel.date.set('value', 'Mon Apr 04 2011 01:00:00 GMT-0400 (Eastern Daylight Time)')/*deccalmodel.reset();*/}">Reset</button></td>
-							</tr>
-							<tr>
-								<td><label for="deccolor">ColorPalette:</label></td>
-								<td>
-									<div id="deccolor" data-dojo-type="dijit.ColorPalette" 
-											data-dojo-props='palette:"3x4", ref: deccolormodel.code'></div>								
-								</td>
-								<td>
-									<input class="cell" id="deccolortext" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: deccolormodel.code"></input>
-								</td>
-								<td><span   id="deccolorOutput" data-dojo-type="dojox.mvc.Output"
-											data-dojo-props="ref: deccolormodel.code">
-						 			${this.value}
-								</span></td>
-								<td><button id="deccolorReset" type="button" data-dojo-type="dijit.form.Button" 
-											data-dojo-props="onClick: function(){deccolormodel.reset();}">Reset</button></td>
-							</tr>
-						</tbody>
-					</table>
-				</div>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/test_mvc_generate-view-store.html b/dojox/mvc/tests/test_mvc_generate-view-store.html
old mode 100755
new mode 100644
index d63d811..d90b8e7
--- a/dojox/mvc/tests/test_mvc_generate-view-store.html
+++ b/dojox/mvc/tests/test_mvc_generate-view-store.html
@@ -3,69 +3,56 @@
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>View generation -- Model-bound generation example with a store, commit and reset</title>
-
-		<script src="../../../dojo/dojo.js"
-				type="text/javascript"
-				djConfig="isDebug: true, parseOnLoad: true">
+		<script>
+			require = {
+				isDebug: 1,
+				parseOnLoad: 0,
+				async: 1, 
+				mvc: {debugBindings: 1}
+			};
 		</script>
+		<script src="../../../dojo/dojo.js" type="text/javascript"></script>
 		<style type="text/css">
 			@import "css/app-format.css";
 			@import "../../../dijit/themes/claro/claro.css";			
 		</style>
-		<script type="text/javascript" >
-			dojo.require("dojox.mvc");
-			dojo.require("dojox.mvc.Generate");
-			dojo.require("dijit.form.Textarea");
-			dojo.require("dijit.form.Button");
-			dojo.require("dojo.data.ItemFileReadStore");
-			dojo.require("dojo.data.ItemFileWriteStore");
-			dojo.require("dojo.store.DataStore");
-			dojo.require("dojo.parser");
-
-			var model;
-
-			function setup(){
-				var theWriteStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests._data", "mvcGenerateData.json")});
-				// this is used to see what would have been written out if we were using a real service
-				theWriteStore._saveEverything = function(c, e, n){
-					console.log(n);
-					c.call();
-				};
-				var theDataStore = new dojo.store.DataStore({store: theWriteStore});
-				var theModelPromise = dojox.mvc.newStatefulModel({store: theDataStore});  // query() returns a deferred.promise
-				theModelPromise.then(function(theStatefulModel){
-					model = theStatefulModel;
-					dijit.byId("view").set("ref", "model");
-				});
-			};
-
-			dojo.addOnLoad(setup);
+		<script type="text/javascript">
+			require([
+				"dojo/parser",
+				"dojo/store/JsonRest",
+				"dojox/mvc/EditStoreRefController",
+				"dijit/form/Button",
+				"dijit/form/TextArea",
+				"dojox/mvc/Generate"
+			], function(parser, JsonRest, EditStoreRefController){
+				ctrl = new EditStoreRefController({store: new JsonRest({target: require.toUrl("dojox/mvc/tests/_data/mvcGenerateData.json")})});
+				parser.parse();
+				ctrl.queryStore({});
+				console.log("test",ctrl);
+			});
 		</script>
 	</head>
 	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
 		<div id="wrapper">
 		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>View generation example</h1>
-			<h2>Data Binding - Generate Container, with a store, commit and reset.</h2>
-		  </div>
+			<div id="navigation"></div>
+			<div id="headerInsert">
+				<h1>View generation example</h1>
+				<h2>Data Binding - Generate Container, with a store, commit and reset.</h2>
+			</div>
 		</div>
 		<div id="main">
-		  <div id="leftNav">
-		  </div>
+			<div id="leftNav"></div>
 			<div id="mainContent">
 				<h3>Generated View</h3>
-				<div id="view" data-dojo-type="dojox.mvc.Generate">
-				</div>
+				<div data-dojo-type="dojox.mvc.Generate" data-dojo-props="children: at(ctrl, 'items')"></div>
 				<div class="row">
 					<div class="spacer"></div>
-					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.commit();}">Commit</button>
-					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commit(); }">Commit</button>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset</button>
 				</div>
 			</div>
 		</div>
-		</div>
 	</body>
 </html>
diff --git a/dojox/mvc/tests/test_mvc_generate-view.html b/dojox/mvc/tests/test_mvc_generate-view.html
old mode 100755
new mode 100644
index 95e0b77..ff3726a
--- a/dojox/mvc/tests/test_mvc_generate-view.html
+++ b/dojox/mvc/tests/test_mvc_generate-view.html
@@ -3,30 +3,32 @@
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>View generation -- Model-bound generation example</title>
-	
-		<script src="../../../dojo/dojo.js"
-				type="text/javascript"
-				djConfig="isDebug: true, parseOnLoad: true">
+		<script>
+			require = {
+				parseOnLoad: 0,
+				isDebug: 1,
+				async: 1, 
+				mvc: {debugBindings: 1}
+			};
 		</script>
+		<script src="../../../dojo/dojo.js" type="text/javascript"></script>
 		<style type="text/css">
 			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";			
+			@import "../../../dijit/themes/claro/claro.css";
 		</style>
-		<script type="text/javascript" >
-			dojo.require("dojox.mvc");
-			dojo.require("dojox.mvc.Generate");
-			dojo.require("dijit.form.Textarea");
-			dojo.require("dojo.parser");
-	
-			function updateView() {
-				var modeldata = dojo.fromJson(dijit.byId("modelArea").value);
-				var model = dojox.mvc.newStatefulModel({ data : modeldata });
-				dijit.byId("view").set("ref", model);
-			};
-		dojo.addOnLoad(updateView);
+		<script type="text/javascript">
+			require([
+				"dojo/parser",
+				"dojo/_base/json",
+				"dijit/form/Textarea",
+				"dojox/mvc/Generate"
+			], function(parser){
+				parser.parse();
+			});
 	   </script>
 	</head>
 	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
 		<div id="wrapper">
 			<div id="header">
 				<div id="navigation"></div>
@@ -40,36 +42,39 @@
 			<div id="mainContent">
 				<h3>Model</h3>
 				<div class="row">
-					<textarea class="cell" data-dojo-type="dijit.form.Textarea" id="modelArea" data-dojo-props="onBlur: updateView">
+					<textarea id="textarea" class="cell" data-dojo-type="dijit.form.Textarea">
 {
-    "Serial" : "360324",
-    "First"  : "John",
-    "Last"   : "Doe",
-    "Email"  : "jdoe at example.com",
-    "Address": {
-        "Street" : "123 Valley Rd",
-        "City"   : "Katonah",
-        "State"	 : "NY",
-        "Zip"    : "10536"
-    },
-    "Phones" : [{
-        "Areacode" : "111",
-        "Local"	   : "111-1111"
-    },{
-        "Areacode" : "222",
-        "Local"	   : "222-2222"
-    }],
-    "Member" : {
-        "Since"	 : "2010",
-        "Type"   : "Gold"
-    }
+	Serial: "360324",
+	First: "John",
+	Last: "Doe",
+	Email: "jdoe at example.com",
+	Address: {
+		Street: "123 Valley Rd",
+		City: "Katonah",
+		State: "NY",
+		Zip: "10536"
+	},
+	Phones: [
+		{
+			Areacode: "111",
+			Local: "111-1111"
+		},{
+			Areacode: "222",
+			Local: "222-2222"
+		}
+	],
+	Member: {
+		Since: "2010",
+		Type: "Gold"
+	}
 }
 					</textarea>
-					</div>
-					<h3>Generated View</h3>
-					<div id="view" data-dojo-type="dojox.mvc.Generate" data-dojo-props="idNameMapping:{'String' : 'view_t'}"></div>
 				</div>
+				<h3>Generated View</h3>
+				<div data-dojo-type="dojox.mvc.Generate"
+				 data-dojo-props="children: at('widget:textarea', 'value').direction(at.from).transform({format: dojo.fromJson}), idNameMapping: {String: 'view_t'}"></div>
 			</div>
 		</div>
+		</div>
 	</body>
 </html>
diff --git a/dojox/mvc/tests/test_mvc_input-output-simple.html b/dojox/mvc/tests/test_mvc_input-output-simple.html
old mode 100755
new mode 100644
index 2531b7a..dd13789
--- a/dojox/mvc/tests/test_mvc_input-output-simple.html
+++ b/dojox/mvc/tests/test_mvc_input-output-simple.html
@@ -6,29 +6,29 @@
 		<style type="text/css">
 			@import "css/app-format.css";
 			@import "../../../dijit/themes/claro/claro.css";
+			.row { width: 500px; display: inline-block; margin: 5px; }
+			.cell { width: 20%;  display:inline-block; }
+			.textcell { width: 30%;  display:inline-block; }
 		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../dojo/dojo.js"></script>
 		<script type="text/javascript">
-			var model;
- 
 			require([
-				'dojo/parser',
-				'dojox/mvc',
-				'dijit/form/TextBox',
-				'dijit/form/Button',
-				'dojox/mvc/Group',
-				'dojox/mvc/Output'
-			], function(parser, mvc){
-				// The dojox.mvc.StatefulModel class creates a data model instance
-				// where each leaf within the data model is decorated with dojo.Stateful
-				// properties that widgets can bind to and watch for their changes.
-				model = mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
-				// the StatefulModel created above is initialized with 
-				// model.First set to "John", model.Last set to "Doe" and model.Email set to "jdoe at example.com"				
+				"dojo/parser",
+				"dojo/Stateful",
+				"dojox/mvc/EditModelRefController",
+				"dijit/registry",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output"
+			], function(parser, Stateful, EditModelRefController){
+				ctrl = new EditModelRefController({sourceModel: new Stateful({First: "John", Last: "Doe", Email: "jdoe at example.com"})});
+				parser.parse();
 			});
 		</script>
 	</head>
 	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
 		<div id="wrapper">
 			<div id="header">
 				<div id="navigation"></div>
@@ -42,31 +42,26 @@
 				<div id="mainContent">
 					<div class="row">
 						<label class="cell" for="firstnameInput">First:</label>
-						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.First"></input>
+						<input id="firstId" class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at(ctrl, 'First')">
 						<!-- Content in output below will always be in sync with value of textbox above -->
-						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.First">
-						(first name is: ${this.value})
-						</span>
+						(first name is: <span data-dojo-type="dijit._WidgetBase" data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at(ctrl, 'First')"></span>)
+					</div>
+					<div class="row">
+						<label class="cell" for="lastnameInput">Last:</label>
+						<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at(ctrl, 'Last')">
+						(last name is: <span data-dojo-type="dijit._WidgetBase" data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at(ctrl, 'Last')"></span>)
+					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label>
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at(ctrl, 'Email')">
+						(email is: <span data-dojo-type="dijit._WidgetBase" data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}, value: at(ctrl, 'Email')"></span>)
 					</div>
-				<div class="row">
-					<label class="cell" for="lastnameInput">Last:</label>
-					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Last"></input>
-					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Last">
-						(last name is: ${this.value})
-					</span>
-				</div>
-				<div class="row">
-					<label class="cell" for="emailInput">Email:</label>
-					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: model.Email"></input>
-					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model.Email">
-					(email is: ${this.value})
-					</span>
-				</div>
 					<br/>Model:
-					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button"  data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset</button>
+					<button id="fromModel" type="button" data-dojo-type="dijit.form.Button" 
+					 data-dojo-props="onClick: function(){ ctrl.set('First','Updated in Model'); }">Update First from Model</button>
+					<button id="fromWidget" type="button" data-dojo-type="dijit.form.Button" 
+					 data-dojo-props="onClick: function(){ dijit.registry.byId('firstId').set('value', 'Updated Widget'); }">Update First from Widget</button>
 				</div>
 			</div>
 		</div>
diff --git a/dojox/mvc/tests/test_mvc_loan-stateful.html b/dojox/mvc/tests/test_mvc_loan-stateful.html
deleted file mode 100755
index 9eb9bc9..0000000
--- a/dojox/mvc/tests/test_mvc_loan-stateful.html
+++ /dev/null
@@ -1,187 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Loan Form (Using DOJO within MVC Support)</title>
-	
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
-		<script type="text/javascript">
-
-		var loanModel; 
-
-		require([
-			'dojo/_base/kernel',
-			'dojo/parser',
-			'dojo/ready',
-			'dojox/mvc',
-			'dojox/mvc/tests/models/LoanWizardModel',			
-			'dojox/charting/DataChart',
-			'dijit/form/TextBox',
-			'dijit/form/Button',
-			'dijit/form/ValidationTextBox',
-			'dijit/form/NumberTextBox',
-			'dojox/mvc/Group',
-			'dojox/mvc/Output'
-			], function(dojo, parser, ready, mvc, LoanWizardModel, DataChart){
-	
-			var loan_init = {
-				"Name"            : "John Doe",
-				"Street"          :  "",
-				"City"            :  "",
-				"County"          :  "",
-				"State"           :  "",
-				"Zip"             :  "",
-				"Country"         :  "US",
-				"TotalIncome"     :  "0",
-				"BaseIncome"      :  "50000",
-				"BonusIncome"     :  "10000",
-				"TotalHousing"    :  "0",
-				"HousingPercent"  :  "0",
-				"Mortgage"        :  "1000",
-				"Taxes"           :  "500",
-				"OtherHousing"    :  "1200"
-			};
-			loanModel = new LoanWizardModel({ data: loan_init });
-	
-			function createChart() {
-				var chart = new DataChart("expenseChart", {
-					store: loanModel.chartStore,
-					comparative: true,
-					type: dojox.charting.plot2d.Pie,
-					query: { "x":"*" },
-					fieldName:"y"
-				});
-			};
-			ready(createChart);
-		});
-			
-		</script>    
-	</head>
-	<body class="claro" style="background-image: url(images/validating_form_pattern.png)">
-	<div id="wrapper">
-	<div id="header">
-		<div id="navigation">
-		</div>
-		<div id="headerInsert">
-			<h1>Big Red Loan</h1>
-			<h2>The one to choose when you're in the red...</h2>
-		</div>
-	</div>		 
-	<div id="main">
-		<div id="leftNav"></div>
-		<div id="mainContent">
-			<h3>Borrower information</h3>
-			<hr size="6" class="rule"/>
-			<div class="spacer"></div>
-			<div class="row">
-			<div class="cell"><label for="borrowerInput">Name:</label></div>
-				<div class="cell">
-					<input id="borrowerInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'loanModel.Name'"/>
-				</div>
-			</div>
-			<div class="row">
-			<div class="cell"><label for="zipInput">Zipcode (try 10706):</label></div>
-				<div class="cell">
-				    <input id="zipInput" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.Zip'"
-		               constraints="{pattern:'#'}" regExp="\d{5}" required="true" invalidMessage="Invalid Zip Code."/>
-				</div>
-			</div>
-			<div class="row">
-			<div class="cell"><label for="cityInput">City:</label></div>
-				<div class="cell">
-					<input id="cityInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'loanModel.City'"/>
-				</div>
-			</div>
-			<div class="row">
-			<div class="cell"><label for="countyInput">County:</label></div>
-				<div class="cell">
-					<input id="countyInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'loanModel.County'"/>
-				</div>
-			</div>
-			<div class="row">
-			<div class="cell"><label for="stateInput">State:</label></div>
-				<div class="cell">
-					<input id="stateInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'loanModel.State'"/>
-				</div>
-			</div>
-			<div class="spacer"></div>
-
-			<h3>Expenses</h3>
-			<hr size="6" class="rule"/>
-			<div class="spacer"></div>
-			<table style="width:900px;">
-			<tr style="width:900px;">
-			<td style="width:400px;">
-			<div class="row">
-			<div class="cell"><label for="housing">Mortgage:</label></div>
-				<div class="cell">
-					<input id="housing" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.Mortgage'"/>
-			</div>
-			</div>
-			<div class="row">
-				<div class="cell">
-					<label>Real Estate Taxes:</label>
-				</div>
-				<div class="cell">
-					<input id="taxes" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.Taxes'"/>
-				</div>
-			</div>
-			<div class="row">
-			<div class="cell"><label>Other Housing:</label></div>
-				<div class="cell">
-					<input id="otherHousing" type="text" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.OtherHousing'"/>
-				</div>
-			</div>
-			<div class="row">
-			<div class="cell"><label for="transportation">Total Housing:</label></div>
-				<div class="cell">
-					<input id="totalHousing" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.TotalHousing'"/>
-			</div>
-			</div>
-			</td>
-			<td style="width:200px;">
-				<div id="expenseChart" width="150" height="150" style="display:block; width: 150px; height: 150px;"></div>
-			</td>
-			</tr>
-			</table>
-			
-			<h3>Income</h3>
-			<hr size="6" class="rule"/>
-			<div class="spacer"></div>
-			<div class="row">
-			<div class="cell"><label for="baseIncome">Base Income:</label></div>
-				<div class="cell">
-					<input id="baseIncome" type="text" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.BaseIncome'"/>
-				</div>
-			</div>
-			<div class="row">
-			<div class="cell"><label>Bonus Income:</label></div>
-				<div class="cell">
-					<input id="bonusIncome" type="text" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.BonusIncome'"/>
-				</div>
-			</div>
-			<div class="row">
-			<div class="cell"><label for="total">Total Income:</label></div>
-				<div class="cell">
-					<input id="total" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.TotalIncome'"/>
-				</div>
-			</div>
-			<h3>Analysis</h3>
-			<hr size="6" class="rule"/>
-			<div class="spacer"></div>
-			<div class="row">
-			<div class="cell"><label for="percentHousing">Percent housing (under 33%):</label></div>
-				<div class="cell">
-					<input id="percentHousing" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props="ref: 'loanModel.HousingPercent'"
-					    invalidMessage="Housing should be less than 1/3 total expenses!"/>
-				</div>
-			</div>
-		</div>
-	</div>
-	</div>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/test_mvc_new-data-replace-simple.html b/dojox/mvc/tests/test_mvc_new-data-replace-simple.html
new file mode 100644
index 0000000..660d68e
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_new-data-replace-simple.html
@@ -0,0 +1,151 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+
+		<script src="../../../dojo/dojo.js"
+				type="text/javascript"
+				data-dojo-config="parseOnLoad: false, isDebug: true, mvc: {debugBindings: true}">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+		var model1, model1Data, model2Data, model3Data;
+ 
+		require([
+			'dojo/parser',
+			"dojo/_base/lang",
+			'dojo/ready',
+			'dojo/when',
+			"dojo/Stateful",
+			"dojox/mvc/getStateful",
+			"dojox/mvc/getPlainValue",
+			"dojox/mvc/EditModelRefController",
+			"dojo/store/Memory",
+			'dijit/registry',			
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Repeat',
+			'dojox/mvc/Output'
+			], function(parser, lang, ready, when, Stateful, getStateful, getPlainValue, EditModelRefController, Memory, registry){
+			
+			model1Data =
+			[{
+				"Query" : "Engineers1",
+				"First"	  : "Anne1",
+				"Last"	  : "Ackerman1"
+			}];
+
+			model2Data =
+			[{
+				"Query" : "Engineers2",
+				"First"	  : "Anne2",
+				"Last"	  : "Ackerman2"
+			}];
+			model3Data =
+			[{
+				"Query" : "Engineers3",
+				"First"	  : "",
+				"Last"	  : ""
+			}];
+
+			//var memStore1 = new dojo.store.Memory({data : model1Data});
+			//var model1 = dojox.mvc.newStatefulModel({ store : memStore1 })[0];
+				var memStore1 = new Memory({data : model1Data});
+				when(memStore1.query(), function(data){
+					model1 = EditModelRefController({sourceModel : new Stateful({current: getStateful(data)[0]})});
+					vfaModel = new Stateful();
+					vfaModel.set('session', new Stateful());
+					vfaModel.session.set("user","FirstUser");
+				});
+			
+				replaceData = function(dest, src){
+					src = getPlainValue(src);
+					dest.set("current", getStateful(src));
+				};
+				
+					
+				// when "dojo/ready" is ready call parser.parse
+				ready(function(){
+					parser.parse();
+				});
+			});
+	</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<script type="dojo/require">Stateful: "dojo/Stateful"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+
+					<h4>Replace Model 1 data with original data from the models listed below, this should keep the bindings to the Model1 Output</h4>
+					<div class="row" style="width: 740px">
+	  					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){replaceData(model1, model1Data[0]);}">Replace with Orig. Model1 data</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){replaceData(model1, model2Data[0]);}">Replace with Orig. Model2 data</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){replaceData(model1, model3Data[0]);}">Replace with Orig. Model3 data</button>
+					</div>
+				
+					<div id="outergroupId1x"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(model1, 'current')">
+						<div class="row">
+								<label class="cell" for="nameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="fnameInput" 
+									data-dojo-props="value: at('rel:', 'First')">
+						</div>
+						<div class="row">
+								<label class="cell" for="nameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="lnameInput" 
+									data-dojo-props="value: at('rel:', 'Last')">
+						</div>
+						<div class="row">
+								<label class="cell" for="nameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="qnameInput" 
+									data-dojo-props="value: at('rel:', 'Query')">
+						</div>
+					</div>
+					<div class="row" id="outputgroupId"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(model1, 'current')">
+							<span>
+								Model1 Output is ==>  
+							</span>
+							<span id="firstnameOutput10" data-dojo-type="dojox.mvc.Output" 
+								data-dojo-props="value: at('rel:', 'First')">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput11" data-dojo-type="dojox.mvc.Output" 
+								data-dojo-props="value: at('rel:', 'Last')">
+								Name2 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput12" data-dojo-type="dojox.mvc.Output" 
+								data-dojo-props="value: at('rel:', 'Query')">
+								Name3 is "${this.value}"  
+							</span>
+					</div>
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model1.reset();}">Reset all</button>
+
+					<div id="outergroupId2x"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(vfaModel, 'session')">
+						<div class="row">
+								<label class="cell" for="configurationId">Session:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="configurationId" 
+									data-dojo-props="value: at('rel:', 'user')">
+						</div>
+					<button id="resetses" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){vfaModel.set('session', new Stateful());}">Reset session</button>
+					</div>
+
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_new-ref-set-repeat-nostateful.html b/dojox/mvc/tests/test_mvc_new-ref-set-repeat-nostateful.html
new file mode 100644
index 0000000..43a8c2b
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_new-ref-set-repeat-nostateful.html
@@ -0,0 +1,119 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: 0, isDebug: true, mvc: {debugBindings: true}">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+			var model1 = [
+				{
+					First: "Anne1",
+					Last: "Ackerman1"
+				},
+				{
+					First: "Ben1",
+					Last: "Beckham1"
+				},
+				{
+					First: "Chad1",
+					Last: "Chapman1"
+				}
+			], model2 = [
+				{
+					First: "Anne2",
+					Last: "Ackerman2"
+				},
+				{
+					First: "Ben2",
+					Last: "Beckham2"
+				}
+			], model3 = [
+				{
+					First: "",
+					Last: ""
+				}
+			], showOutput;
+
+			require([
+				"dojo/parser",
+				"dijit/registry",
+				"dijit/_Container",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Repeat",
+				"dojo/domReady!"
+			], function(parser, registry){
+
+				refreshOutput = function(){
+					registry.byId("out1").set("target", model1.slice());
+					registry.byId("out2").set("target", model2.slice());
+					registry.byId("out3").set("target", model3.slice());
+				}
+
+				parser.parse();
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="row">
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ dijit.byId('repeatId').set('children', model1); }">Swap Model1</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ dijit.byId('repeatId').set('children', model2); }">Swap Model2</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ dijit.byId('repeatId').set('children', model3); }">Swap Model3</button>
+					</div>
+					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: model1">
+						<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:${this.index}')">
+							<label class="cell" for="nameInput${this.index}">Name:</label>
+							<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" 
+							 data-dojo-props="value: at('rel:', 'First')">
+						</div>
+					</div>
+					<div class="row">
+						<div>Given the data models are not stateful objects, the change in models is not automatically notified to widgets.</div>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: refreshOutput">Refresh model outputs</button>
+					</div>
+					<div id="out1" class="row" data-dojo-type="dijit._WidgetBase" data-dojo-props="target: model1">
+						<span>
+							Model1 Output is ==>  
+						</span>
+						Name1 is "<span id="firstnameOutput10" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:0', 'First')"></span>" :
+						Name2 is "<span id="firstnameOutput11" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:1', 'First')"></span>" :
+						Name3 is "<span id="firstnameOutput12" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:2', 'First')"></span>"
+					</div>
+					<div id="out2" class="row" data-dojo-type="dijit._WidgetBase" data-dojo-props="target: model2">
+						<span>
+							Model2 Output is ==>  
+						</span>
+						Name1 is "<span id="firstnameOutput20" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:0', 'First')"></span>" :
+						Name2 is "<span id="firstnameOutput21" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:1', 'First')"></span>"
+					</div>
+					<div id="out3" class="row" data-dojo-type="dijit._WidgetBase" data-dojo-props="target: model3">
+						<span>
+							Model3 Output is ==>  
+						</span>
+						Name1 is "<span id="firstnameOutput30" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at('rel:0', 'First')"></span>"
+					</div>					
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_new-ref-set-repeat-simple.html b/dojox/mvc/tests/test_mvc_new-ref-set-repeat-simple.html
new file mode 100644
index 0000000..3984e9e
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_new-ref-set-repeat-simple.html
@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+
+		<script src="../../../dojo/dojo.js"
+				type="text/javascript"
+				data-dojo-config="parseOnLoad: true, isDebug: true, mvc: {debugBindings: true}">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" >
+			dojo.require("dojox.mvc");
+			dojo.require("dojox.mvc.Output");
+			dojo.require("dojox.mvc.Group");
+			dojo.require("dojox.mvc.Repeat");
+			dojo.require("dijit.form.TextBox");
+			dojo.require("dijit.form.Button");
+			dojo.require("dojo.store.Memory");
+			dojo.require("dojo.parser");
+
+			
+			var model1Data =
+			[{
+				"Query" : "Engineers1",
+				"Results" : [
+					{
+						"First"	  : "Anne1",
+						"Last"	  : "Ackerman1"
+					},
+					{
+						"First"	  : "Ben1",
+						"Last"	  : "Beckham1"
+					},
+					{
+						"First"	  : "Chad1",
+						"Last"	  : "Chapman1"
+					}
+				]
+			}];
+			var model2Data =
+			[{
+				"Query" : "Engineers2",
+				"Results" : [
+					{
+						"First"	  : "Anne2",
+						"Last"	  : "Ackerman2"
+					},
+					{
+						"First"	  : "Ben2",
+						"Last"	  : "Beckham2"
+					}
+				]
+			}];
+			var model3Data =
+			[{
+				"Query" : "Engineers3",
+				"Results" : [
+					{
+						"First"	  : "",
+						"Last"	  : ""
+					}
+				]
+			}];
+
+			var memStore1 = new dojo.store.Memory({data : model1Data});
+			var model1 = dojox.mvc.newStatefulModel({ store : memStore1 })[0];
+			var memStore2 = new dojo.store.Memory({data : model2Data});
+			var model2 = dojox.mvc.newStatefulModel({ store : memStore2 })[0];
+			var memStore3 = new dojo.store.Memory({data : model3Data});
+			var model3 = dojox.mvc.newStatefulModel({ store : memStore3 })[0];
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="row">
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model1);}">Swap Model1</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model2);}">Swap Model2</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model3);}">Swap Model3</button>
+					</div>
+					<div class="row">
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('target',model1Data);}">Swap Model1 data</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(model2Data);dijit.byId('outergroupId').set('target', model2Data);}">Swap Model2 data</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('target',model3Data);}">Swap Model3 data</button>						
+					</div>
+					<div id="outergroupId"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="target: model1">
+						<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" 
+											data-dojo-props="children: at('rel:', 'Results')">
+							<div class="row" data-dojo-type="dojox.mvc.Group" 
+											data-dojo-props="target: at('rel:${this.index}')">
+								<label class="cell" for="nameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" 
+									data-dojo-props="value: at('rel:First', 'value')">
+							</div>
+						</div>
+					</div>
+					<div class="row">
+							<span>
+								Model1 Output is ==>  
+							</span>
+							<span id="firstnameOutput10" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[0].First">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput11" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[1].First">
+								Name2 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput12" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[2].First">
+								Name3 is "${this.value}"  
+							</span>
+					</div>
+					<div class="row">
+							<span>
+								Model2 Output is ==>  
+							</span>
+							<span id="firstnameOutput20" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[0].First">
+								Name1 is "${this.value}" : 
+							</span>
+							<span id="firstnameOutput21" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[1].First">
+								Name2 is "${this.value}"  
+							</span>
+					</div>
+					<div class="row">
+							<span>
+								Model3 Output is ==>  
+							</span>
+							<span id="firstnameOutput30" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model3.Results[0].First">
+								Name1 is "${this.value}"  
+							</span>
+					</div>					
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model1.reset();model2.reset();model3.reset();}">Reset all</button>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_new-ref-set-replace-repeat.html b/dojox/mvc/tests/test_mvc_new-ref-set-replace-repeat.html
new file mode 100644
index 0000000..8ca1057
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_new-ref-set-replace-repeat.html
@@ -0,0 +1,198 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+
+		<script src="../../../dojo/dojo.js"
+				type="text/javascript"
+				data-dojo-config="parseOnLoad: false, isDebug: true, mvc: {debugBindings: true}">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript">
+		var model1, model2, model3;
+ 
+		require([
+			'dojo/parser',
+			"dojo/_base/lang",
+			'dojo/ready',
+			'dojo/when',
+			"dojo/Stateful",
+			"dojox/mvc/getStateful",
+			"dojox/mvc/getPlainValue",
+			"dojo/store/Memory",
+			'dijit/registry',			
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Repeat',
+			'dojox/mvc/Output'
+			], function(parser, lang, ready, when, Stateful, getStateful, getPlainValue, Memory, registry){
+				
+				model1Data =
+				[{
+					"Query" : "Engineers1",
+					"Results" : [
+						{
+							"First"	  : "Anne1",
+							"Last"	  : "Ackerman1"
+						},
+						{
+							"First"	  : "Ben1",
+							"Last"	  : "Beckham1"
+						},
+						{
+							"First"	  : "Chad1",
+							"Last"	  : "Chapman1"
+						}
+					]
+				}];
+				model2Data =
+				[{
+					"Query" : "Engineers2",
+					"Results" : [
+						{
+							"First"	  : "Anne2",
+							"Last"	  : "Ackerman2"
+						},
+						{
+							"First"	  : "Ben2",
+							"Last"	  : "Beckham2"
+						}
+					]
+				}];
+				model3Data =
+				[{
+					"Query" : "Engineers3",
+					"Results" : [
+						{
+							"First"	  : "",
+							"Last"	  : ""
+						}
+					]
+				}];
+
+				var memStore1 = new Memory({data : model1Data});
+				when(memStore1.query(), function(data){
+					model1 = new Stateful({current: getStateful(data)[0]});
+				});
+
+				var memStore2 = new Memory({data : model2Data});
+				//model2 = mvc.newStatefulModel({ store : memStore2 })[0];
+				when(memStore2.query(), function(data){
+					model2 = new Stateful({current: getStateful(data)[0]});
+				});
+				var memStore3 = new Memory({data : model3Data});
+				//model3 = mvc.newStatefulModel({ store : memStore3 })[0];
+				when(memStore3.query(), function(data){
+					//model3 = getStateful(data)[0];
+					model3 = new Stateful({current: getStateful(data)[0]});
+				});
+
+				replaceData = function(dest, src){
+					src = getPlainValue(src);
+					dest.set("current", getStateful(src));
+				};
+				
+					
+				// when "dojo/ready" is ready call parser.parse
+				ready(function(){
+					parser.parse();
+				});
+			});
+
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+  
+<h4>This will swap which model is used for the textboxes, so updates will effect the output for that model</h4>
+					<div class="row">
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('target',at(model1, 'current'));}">Swap Model1</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('target',at(model2, 'current'));}">Swap Model2</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('target',at(model3, 'current'));}">Swap Model3</button>
+					</div>
+
+					<h4>Replace Model 1 data with original data from the models listed below, this should keep the bindings to the Model1 Output</h4>
+					<div class="row" style="width: 740px">
+	  					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){replaceData(model1, model1Data[0]);}">Replace with Orig. Model1 data</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){replaceData(model1, model2Data[0]);}">Replace with Orig. Model2 data</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){replaceData(model1, model3Data[0]);}">Replace with Orig. Model3 data</button>
+					</div>
+					<h4>Replace Model 1 data with the current model data listed below, this should keep the bindings to the Model1 Output</h4>
+					<div class="row" style="width: 540px">						
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){replaceData(model1, model2.current);}">Replace with Model2 data</button>
+						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){replaceData(model1, model3.current);}">Replace with Model3 data</button>
+					</div>
+					<div id="outergroupId"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(model1, 'current')">
+						<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" 
+											data-dojo-props="children: at('rel:', 'Results')">
+							<div class="row" data-dojo-type="dojox.mvc.Group" 
+											data-dojo-props="target: at('rel:${this.index}')">
+								<label class="cell" for="nameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" 
+									data-dojo-props="value: at('rel:', 'First')">
+							</div>
+						</div>
+					</div>
+					<div class="row">
+						<span>Model1 Output is ==>  </span>
+						<div id="outergroupId12"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(model1, 'current')">
+							<div id="repeatId12" data-dojo-type="dojox.mvc.Repeat" 
+											data-dojo-props="children: at('rel:', 'Results')">
+								<div data-dojo-type="dojox.mvc.Group" 
+											data-dojo-props="target: at('rel:${this.index}')">
+									<span>Model1 Name${this.index} is</span>
+									<span id="firstnameOutput12${this.index}" data-dojo-type="dojox.mvc.Output"
+										data-dojo-props="value: at('rel:', 'First')"></span>
+								</div>
+							</div>
+						</div>
+					</div>
+					<div class="row">
+						<span>Model2 Output is ==>  </span>
+						<div id="outergroupId22"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(model2, 'current')">
+							<div id="repeatId22" data-dojo-type="dojox.mvc.Repeat" 
+											data-dojo-props="children: at('rel:', 'Results')">
+								<div data-dojo-type="dojox.mvc.Group" 
+											data-dojo-props="target: at('rel:${this.index}')">
+									<span>Model2 Name${this.index} is</span>
+									<span id="firstnameOutput22${this.index}" data-dojo-type="dojox.mvc.Output"
+										data-dojo-props="value: at('rel:', 'First')"></span>
+								</div>
+							</div>
+						</div>
+					</div>
+					<div class="row">
+						<span>Model3 Output is ==>  </span>
+						<div id="outergroupId23"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(model3, 'current')">
+							<div id="repeatId23" data-dojo-type="dojox.mvc.Repeat" 
+											data-dojo-props="children: at('rel:', 'Results')">
+								<div data-dojo-type="dojox.mvc.Group" 
+											data-dojo-props="target: at('rel:${this.index}')">
+									<span>Model3 Name${this.index} is</span>
+									<span id="firstnameOutput23${this.index}" data-dojo-type="dojox.mvc.Output"
+										data-dojo-props="value: at('rel:', 'First')"></span>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_new_bindings-simple.html b/dojox/mvc/tests/test_mvc_new_bindings-simple.html
new file mode 100644
index 0000000..d024b29
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_new_bindings-simple.html
@@ -0,0 +1,187 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Binding Test</title>
+
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:1,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+
+		var model; 
+
+		require([
+			'dojo/_base/kernel',
+			'dojo/parser',
+			'dojo/ready',
+			"dojox/mvc/getStateful", 
+			"dojox/mvc/EditModelRefController",
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dijit/form/ValidationTextBox',
+			'dijit/form/NumberTextBox',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(dojo, parser, ready, getStateful, EditModelRefController){
+
+			model = new EditModelRefController({sourceModel: getStateful({	"First" : "John", 
+					"Last" : "Doe", 
+					"Email" : "jdoe at example.com", 
+					"Num" : 3
+			})});
+	
+			console.log("model is ");
+			console.log(model);
+
+			function noParse(){
+				throw new Error();
+			}
+			nameReadOnlyConverter = {
+				format: function(value){
+					return value === "2" || value === "3";
+			},
+				parse: noParse
+			};
+			nameRelevanceConverter = {
+				format: function(value){
+					return value == "0";
+			},
+				parse: noParse
+			};
+			nameRequiredConverter = {
+				format: function(value){
+					return value === "4";
+				},
+				parse: noParse
+			};
+			numValidConverter = {
+				format: function(value){
+					return value - 0 !== 1 && value !== "3";
+				},
+				parse: noParse
+			};
+			disabledDisplayConverter = {
+				format: function(value){
+				//	if(value){
+						return "disabled is "+value;
+				//	}
+				//	return value - 0 !== 1 && value !== "3";
+				},
+				parse: function(value){
+				//	if(value){
+						return "disabled is "+value;
+				//	}
+				//	return value - 0 !== 1 && value !== "3";
+				}
+			};
+		});
+		
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="header">
+		  <div id="navigation">
+		  </div>
+		  <div id="headerInsert">
+			<h1>Binding Tests</h1>
+		  </div>
+		</div>
+		<div id="main">
+		  <div id="leftNav">
+		  </div>
+		  <div id="mainContent">
+			<h2>Bind Self Tests</h2>
+			<div class="row">
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 0 to test for disable false (disabled) (use Reset to re-enable)</label>
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 1 to test for Valid false.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 2 to test for Read-only false (use Reset to re-enable)</label>
+				<label style="display:inline-block; width:100%; text-align:left;">First: Enter 3 to test for Read-only false and Valid false (use Reset to re-enable)</label>
+			</div>
+			<div class="row">
+				<label class="cell" for="firstnameInput">First:</label>
+				<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.ValidationTextBox"
+									data-dojo-props="value: at(model, 'First'),
+													readOnly: at(model, 'First').transform(nameReadOnlyConverter),
+													disabled: at(model, 'First').transform(nameRelevanceConverter),
+													valid: at(model, 'First').transform(numValidConverter)"></input>
+				<!-- Content in output below will always be in sync with value of textbox above -->
+				<span id="tout" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'First')">
+					(first name is: ${this.value})
+				</span>
+				
+			</div>
+		   <div class="row">
+				<label class="cell" for="firstnameInput"></label>
+	<!--  	<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'First')">
+					disable is:  ${this.ref.disable}, Valid is: ${this.ref.valid}, Read-only is: ${this.ref.readOnly})
+				</span>
+	-->								   
+			</div>
+			<div class="row">
+				<label style="display:inline-block; width:100%; text-align:left;">Num: Enter 1 for Valid false</label>
+			</div>
+			<div class="row">
+				<label class="cell" for="numInput">Num:</label>
+				<input class="cell" id="numInput" data-dojo-type="dijit.form.NumberTextBox"
+												data-dojo-props="value: at(model, 'Num'),
+												valid: at(model, 'Num').transform(numValidConverter)"></input>
+				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'Num')">
+					(num is: ${this.value})
+				</span>
+			</div>
+			<h2>Bind Tests</h2>
+			<div class="row">
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 0 to test for disable false (disabled) for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 1 to test for Valid false for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 2 to test for Read-only true for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 3 to test for Read-only true and Valid false for Email.</label>
+				<label style="display:inline-block; width:100%; text-align:left;">Last: Enter 4 to test for Required true for Email.</label>
+			</div>			
+			
+			<div class="row">
+				<label class="cell" for="lastnameInput">Last:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(model, 'Last')"></input>
+				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'Last')">
+					(last name is: ${this.value})
+				</span>
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.ValidationTextBox"
+									data-dojo-props="value: at(model, 'Email'),
+													readOnly: at(model, 'Last').transform(nameReadOnlyConverter),
+													disabled: at(model, 'Last').transform(nameRelevanceConverter),
+													valid: at(model, 'Last').transform(numValidConverter),
+													required: at(model, 'Last').transform(nameRequiredConverter)"></input>
+				<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'Email')">
+					(email is: ${this.value})
+				</span>
+			</div>
+	<!--    <div class="row">
+				<label class="cell" for="emailInput"></label>
+				<span id="emailOut" data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model, 'Email'),
+													readOnly: at(model, 'Email'),
+													disabled: at(model, 'Email').transform(disabledDisplayConverter),
+													required: at(model, 'Email')">
+					disabled is:  ${this.disabled}, Valid is: ${this.valid}, Read-only is: ${this.readOnly}, Required is: ${this.required})
+				</span>
+		   </div>
+	 -->			
+			<br/>Model:
+			<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){doReset()}">Reset</button>
+		  </div>
+		</div></div>
+		<script type="text/javascript">
+			function doReset() {
+				model.reset();
+			}
+		</script>
+		
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_new_form-kitchensink.html b/dojox/mvc/tests/test_mvc_new_form-kitchensink.html
new file mode 100644
index 0000000..7f46fe5
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_new_form-kitchensink.html
@@ -0,0 +1,658 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Data-bound Form element Kitchen Sink test</title>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			label {
+				text-align: left;
+				width: 100%;
+			}
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:1,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+
+		var store, selctrl, decselctrl, numspinctrl; 
+		var filctrl, decfilctrl;
+		var comboctrl, deccomboctrl;
+		var datectrl, decdatectrl; 
+		var sliderctrl, decsliderctrl;
+		var numspinctrl, decnumspinctrl;
+		var simpTActrl, decsimpTActrl;
+		var textareactrl, dectextareactrl;
+		var deccalctrl, deccolorctrl;
+
+		require([
+			'dojo/_base/kernel',
+			"dojo/_base/declare",
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc',
+			'dojox/mvc/at',			
+			'dijit/_WidgetBase',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dijit/form/Select',
+			'dijit/form/FilteringSelect',
+			'dijit/form/ComboBox',
+			'dijit/form/DateTextBox',
+			'dijit/form/HorizontalSlider',
+			'dijit/form/NumberSpinner',
+			'dijit/form/SimpleTextarea',
+			'dijit/form/Textarea',
+			'dojo/data/ItemFileReadStore',
+			"dojo/Stateful",
+			"dojox/mvc/getStateful",
+			"dojox/mvc/EditModelRefController",
+			'dijit/Calendar',
+			'dijit/ColorPalette',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output',
+			'dojo/date/locale'
+			], function(kernel, declare, parser, ready, mvc, at, _WidgetBase, TextBox, Button, Select, FilteringSelect, ComboBox, DateTextBox, 
+						HorizontalSlider, NumberSpinner, SimpleTextarea, Textarea, ItemFileReadStore, Stateful, getStateful, EditModelRefController, 
+						Calendar, ColorPalette){
+			//window.at = at;
+
+			var alreadyset = false;	
+			var data = [
+				{id: '1',name:"one"},
+				{id: '2',name:"two"},
+				{id: '3',name:"three"},
+				{id: '4',name:"four"},
+				{id: '5',name:"five"},
+				{id: '6',name:"six"},
+				{id: '7',name:"seven"},
+				{id: '8',name:"eight"},
+				{id: '9',name:"nine"},
+				{id: '10',name:"ten"},
+				{id: '11',name:"eleven"},
+				{id: '12',name:"twelve"},
+				{id: '13',name:"thirteen"}
+			  ];
+			store = new ItemFileReadStore({
+				data: {
+					identifier: 'id',
+					label: 'name',
+					items: data
+				}
+			});
+
+			var data2 = {
+				identifier: "value",
+				label: "label",
+				items: [
+					{value: "1", label: "one"},
+					{value: "2", label: "two"},
+					{value: "3", label: "three"},
+					{value: "4", label: "four"},
+					{value: "5", label: "five"},
+					{value: "6", label: "six"},
+					{value: "7", label: "seven"},
+					{value: "8", label: "eigth"},
+					{value: "9", label: "nine"},
+					{value: "10", label: "ten"},
+					{value: "11", label: "eleven"},
+					{value: "12", label: "twelve"},
+					{value: "13", label: "thirteen"},
+					{value: "14", label: "fourteen"}
+				]
+			};
+
+			selctrl = new EditModelRefController({sourceModel: new Stateful({number: "1"})});
+			decselctrl = new EditModelRefController({sourceModel: new Stateful({number: "1"})});
+
+			// create models for filtering selects
+			filctrl = new EditModelRefController({sourceModel: new Stateful({number: "2"})});
+			decfilctrl = new EditModelRefController({sourceModel: new Stateful({number: "2"})});
+
+			// create models for ComboBoxes
+			comboctrl = new EditModelRefController({sourceModel: new Stateful({number: "three"})});
+			deccomboctrl = new EditModelRefController({sourceModel: new Stateful({number: "three"})});
+
+			// create a model for DateTextBox
+			datectrl = new EditModelRefController({sourceModel: new Stateful({number: "2011-04-04"})});
+			decdatectrl = new EditModelRefController({sourceModel: new Stateful({number: "2011-04-04"})});
+
+			// create a model for Slider
+			sliderctrl = new EditModelRefController({sourceModel: new Stateful({number: "5"})});
+			decsliderctrl = new EditModelRefController({sourceModel: new Stateful({number: "5"})});
+
+			// create a model for NumberSpinner
+			numspinctrl = new EditModelRefController({sourceModel: new Stateful({number: "6"})});
+			decnumspinctrl = new EditModelRefController({sourceModel: new Stateful({number: "6"})});
+
+			// create a model for SimpleTextArea
+			simpTActrl = new EditModelRefController({sourceModel: new Stateful({number: "7"})});
+			decsimpTActrl = new EditModelRefController({sourceModel: new Stateful({number: "7"})});
+
+			// create a model for TextArea
+			textareactrl = new EditModelRefController({sourceModel: new Stateful({number: "8"})});
+			dectextareactrl = new EditModelRefController({sourceModel: new Stateful({number: "8"})});
+
+			// create a model for dijit.Calendar
+			deccalctrl = new EditModelRefController({sourceModel: new Stateful({date: "Mon Apr 04 2011 01:00:00 GMT-0400 (Eastern Daylight Time)"})});
+
+			// create a model for dijit.ColorPalette
+			deccolorctrl = new EditModelRefController({sourceModel: new Stateful({code: "#000000"})});
+
+			// Handle the programmatic creation of widgets here:
+
+			// create the select, textbox, output and button			
+			var sel = new Select({
+				store: store,
+				loadChildrenOnOpen: true,
+			//	value: 1,	
+				value: at(selctrl, 'number') // bind to model.number
+			}, document.getElementById('sel'));
+			
+			var text = new TextBox({
+				//id: "seltext",
+				value: at(selctrl, 'number') // bind to model.number
+			}, document.getElementById('seltext'));			
+			text.startup();
+			
+			var selOutput = new mvc.Output({
+				value: at(selctrl, 'number') // bind to model.number
+			}, document.getElementById('selOutput'));
+			selOutput.startup();
+
+			var reset1 = new Button({
+				onClick: function(){ selctrl.reset(); },
+				id: "selReset",
+				label: "Reset"
+			}, document.getElementById('reset1'));
+			reset1.startup();
+
+
+			sel.watch('value', function () {
+				//console.log('sel value changed', arguments);
+			});
+
+			text.watch('value', function () {
+				//console.log('text value changed', arguments);
+			});
+			
+			sel.startup();
+			
+
+			// create the filtering select, textbox, output and button			
+			var filsel = new FilteringSelect({
+				store: store,
+				value: at(filctrl,'number') // bind to ctrl.number
+			}, document.getElementById('filsel'));
+			filsel.startup();
+			
+			var filtext = new TextBox({
+				value: at(filctrl,'number') // bind to ctrl.number
+			}, document.getElementById('filtext'));
+			filtext.startup();
+			
+			var filoutput = new mvc.Output({
+				value: at(filctrl,'number') // bind to ctrl.number
+			}, document.getElementById('filoutput'));			
+			filoutput.startup();
+
+			var filreset = new Button({
+				onClick: function(){filctrl.reset();},
+				id: "filReset",
+				label: "Reset"
+			}, document.getElementById('filreset'));
+			filreset.startup();
+			
+			
+			// create the comboBox, textbox, output and button			
+			var combo = new ComboBox({
+				store: store,
+				value: at(comboctrl, 'number') // bind to ctrl.number
+			}, document.getElementById('combosel'));
+			
+			var combotext = new TextBox({
+				value: at(comboctrl, 'number')
+			}, document.getElementById('combotext'));
+			
+			var combooutput = new mvc.Output({
+				value: at(comboctrl, 'number')
+			}, document.getElementById('combooutput'));			
+			combooutput.startup();
+
+			var comboreset = new Button({
+				onClick: function(){comboctrl.reset();},
+				id: "comboReset",
+				label: "Reset"
+			}, document.getElementById('comboreset'));
+			comboreset.startup();
+			
+			combotext.startup();
+			combo.startup();
+			
+			// create the dijit.form.DateTextBox, textbox, output and button			
+			var dateWid = new DateTextBox({
+				value: at(datectrl, 'number') // bind to ctrl.number
+			}, document.getElementById('datesel'));
+			
+			var datetext = new TextBox({
+				value: at(datectrl, 'number')
+			}, document.getElementById('datetext'));
+			
+			var dateoutput = new mvc.Output({
+				value: at(datectrl, 'number')
+			}, document.getElementById('dateoutput'));			
+			dateoutput.startup();
+
+			var datereset = new Button({
+				onClick: function(){datectrl.reset();},
+				id: "dateReset",
+				label: "Reset"
+			}, document.getElementById('datereset'));
+			datereset.startup();
+			
+			datetext.startup();
+			dateWid.startup();
+			
+			// create the dijit.form.HorizontalSlider, textbox, output and button			
+			var sliderWid = new HorizontalSlider({
+						style:{width:"190px"},
+						minimum:0,
+						maximum:100,
+						discreteValues:21,
+				value: at(sliderctrl, 'number') // bind to ctrl.number
+			}, document.getElementById('slidersel'));
+			
+			var slidertext = new TextBox({
+				value: at(sliderctrl, 'number')
+			}, document.getElementById('slidertext'));
+			
+			var slideroutput = new mvc.Output({
+				value: at(sliderctrl, 'number')
+			}, document.getElementById('slideroutput'));			
+			slideroutput.startup();
+
+			var sliderreset = new Button({
+				onClick: function(){sliderctrl.reset();},
+				id: "sliderReset",
+				label: "Reset"
+			}, document.getElementById('sliderreset'));
+			sliderreset.startup();
+			
+			slidertext.startup();
+			sliderWid.startup();
+			
+			// create the dijit.form.NumberSpinner, textbox, output and button			
+			var numspinWid = new NumberSpinner({
+			//	constraints:{max:100,places:0},
+				value: at(numspinctrl, 'number') // bind to ctrl.number
+			}, document.getElementById('numspinsel'));
+			
+			var numspintext = new TextBox({
+				value: at(numspinctrl, 'number')
+			}, document.getElementById('numspintext'));
+			
+			var numspinoutput = new mvc.Output({
+				value: at(numspinctrl, 'number')
+			}, document.getElementById('numspinoutput'));			
+			numspinoutput.startup();
+
+			var numspinreset = new Button({
+				onClick: function(){numspinctrl.reset();},
+				id: "numspinReset",
+				label: "Reset"
+			}, document.getElementById('numspinreset'));
+			numspinreset.startup();
+			
+			numspintext.startup();
+			numspinWid.startup();
+			
+			// create the dijit.form.SimpleTextarea, textbox, output and button 			
+			var simpTAWid = new SimpleTextarea({
+				style:{height:"20px", width:"180px"},
+				value: at(simpTActrl, 'number') // bind to ctrl.number
+			}, document.getElementById('simpTAsel'));
+			
+			var simpTAtext = new TextBox({
+				value: at(simpTActrl, 'number')
+			}, document.getElementById('simpTAtext'));
+			
+			var simpTAoutput = new mvc.Output({
+				value: at(simpTActrl, 'number')
+			}, document.getElementById('simpTAoutput'));			
+			simpTAoutput.startup();
+
+			var simpTAreset = new Button({
+				onClick: function(){simpTActrl.reset();},
+				id: "simpTAReset",
+				label: "Reset"
+			}, document.getElementById('simpTAreset'));
+			simpTAreset.startup();
+			
+			simpTAtext.startup();
+			simpTAWid.startup();
+
+			// create the dijit.form.Textarea, textbox, output and button 
+			var textareaWid = new Textarea({
+			//	constraints:{max:100,places:0},
+				value: at(textareactrl, 'number') // bind to ctrl.number
+			}, document.getElementById('textareasel'));
+			
+			var textareatext = new TextBox({
+				value: at(textareactrl, 'number')
+			}, document.getElementById('textareatext'));
+			
+			var textareaoutput = new mvc.Output({
+				value: at(textareactrl, 'number')
+			}, document.getElementById('textareaoutput'));			
+			textareaoutput.startup();
+
+			var textareareset = new Button({
+				onClick: function(){textareactrl.reset();},
+				id: "textareaReset",
+				label: "Reset"
+			}, document.getElementById('textareareset'));
+			textareareset.startup();
+			
+			textareatext.startup();
+			textareaWid.startup();
+
+			});
+
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header" style="margin-top: 0px;">
+				<div id="navigation"  style="margin-top: 0px;"></div>
+				<div id="headerInsert"  style="margin-top: 0px;">
+					<h2>Data-bound Form Element Kitchen Sink MVC test</h2>
+				</div>
+			</div>
+			<div id="main" style="margin-top: 0px;">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+	
+					<h2 style="margin-top: 0px;">Programmatic creation of Form elements:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+								<td><label for="sel">Select:</label></td>
+								<td><div id="sel"></div></td>
+								<td><div id="seltext"></div></td>
+								<td><div id="selOutput"></div></td>
+								<td><div id="reset1" ></div></td>
+							</tr>
+							<tr>
+								<td><label for="filsel">FilteringSelect:</label></td>
+								<td><div id="filsel"></div></td>
+								<td><div id="filtext"></div></td>
+								<td><div id="filoutput"></div></td>
+								<td><div id="filreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="combosel">ComboBox:</label></td>
+								<td><div id="combosel"></div></td>
+								<td><div id="combotext"></div></td>
+								<td><div id="combooutput"></div></td>
+								<td><div id="comboreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="datesel">DateTextBox:</label></td>
+								<td><div id="datesel"></div></td>
+								<td><div id="datetext"></div></td>
+								<td><div id="dateoutput"></div></td>
+								<td><div id="datereset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="slidersel">Slider:</label></td>
+								<td><div id="slidersel"></div></td>
+								<td><div id="slidertext"></div></td>
+								<td><div id="slideroutput"></div></td>
+								<td><div id="sliderreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="numspinsel">NumberSpinner:</label></td>
+								<td><div id="numspinsel"></div></td>
+								<td><div id="numspintext"></div></td>
+								<td><div id="numspinoutput"></div></td>
+								<td><div id="numspinreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="simpTAsel">SimpleTextArea:</label></td>
+								<td><div id="simpTAsel"></div></td>
+								<td><div id="simpTAtext"></div></td>
+								<td><div id="simpTAoutput"></div></td>
+								<td><div id="simpTAreset"></div></td>
+							</tr>
+							<tr>
+								<td><label for="textareasel">TextArea:</label></td>
+								<td><div id="textareasel"></div></td>
+								<td><div id="textareatext"></div></td>
+								<td><div id="textareaoutput"></div></td>
+								<td><div id="textareareset"></div></td>
+							</tr>
+						</tbody>
+					</table>
+	  
+					<h2>Declarative creation of Form elements:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+							<!--  <td><label for="decsel">Select:</label></td>
+								<td>
+									<select id="decsel" style="width: 188px;" 
+													data-dojo-id="decsel" data-dojo-type="dijit.form.Select" 
+													data-dojo-props='name:"decsel",loadChildrenOnOpen: true, value: at(decselctrl, 'number') '>
+										<option value="1">one</option>
+										<option value="2">two</option>
+										<option value="3">three</option>
+										<option value="4">four</option>
+									</select>
+								</td>
+							-->	
+								<td><label for="decsel">Select:</label></td>
+								<td>
+									<select id="decsel" style="width: 188px;" 
+													data-dojo-id="decsel" data-dojo-type="dijit.form.Select" 
+													data-dojo-props='store:store, name:"decsel",loadChildrenOnOpen: true, value: at(decselctrl, "number")'>
+									</select>
+								</td>
+								<td>
+									<input class="cell" id="decseltext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(decselctrl, 'number')"></input>
+								</td>
+								<td><span   id="decselOutput" data-dojo-type="dojox.mvc.Output"
+											data-dojo-props="value: at(decselctrl, 'number')">
+						 			${this.value}
+								</span></td>
+								<td><button id="decselReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decselctrl.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decfilsel">FilteringSelect:</label></td>
+								<td>
+									<input id="decfilsel" data-dojo-type="dijit.form.FilteringSelect"
+										data-dojo-props='store:store, value: at(decfilctrl, "number")'/>
+								</td>
+								<td>
+									<input id="decfiltext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(decfilctrl, 'number')"></input>
+								</td>
+								<td><span id="decfilOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="value: at(decfilctrl, 'number')">
+						 			${this.value}
+								</span></td>
+								<td><button id="decfilReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decfilctrl.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="deccombosel">ComboBox:</label></td>
+								<td>
+									<input id="deccombosel" data-dojo-type="dijit.form.ComboBox"
+										data-dojo-props='store:store, value: at(deccomboctrl, "number")'/>
+								</td>
+								<td>
+									<input id="deccombotext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(deccomboctrl, 'number')"></input>
+								</td>
+								<td><span id="deccomboOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="value: at(deccomboctrl, 'number')">
+						 			${this.value}
+								</span></td>
+								<td><button id="deccomboReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){deccomboctrl.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="datesel">DateTextBox:</label></td>
+								<td>
+									<input id="decdatesel" data-dojo-type="dijit.form.DateTextBox"
+										data-dojo-props='store:store, value: at(decdatectrl, "number")'/>
+								</td>
+								<td>
+									<input id="decdatetext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(decdatectrl, 'number')"></input>
+								</td>
+								<td><span id="decdateOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="value: at(decdatectrl, 'number')">
+						 			${this.value}
+								</span></td>
+								<td><button id="decdateReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decdatectrl.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decslidersel">Slider:</label></td>
+								<td>
+									<input id="decslidersel" data-dojo-type="dijit.form.HorizontalSlider"
+										data-dojo-props='store:store, value: at(decsliderctrl, "number"),
+														style:{width:"190px"}, minimum:0, maximum:100, discreteValues:21'/>
+								</td>
+								<td>
+									<input id="decslidertext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(decsliderctrl, 'number')"></input>
+								</td>
+								<td><span id="decsliderOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="value: at(decsliderctrl, 'number')">
+						 			${this.value}
+								</span></td>
+								<td><button id="decsliderReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decsliderctrl.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decnumspinsel">NumberSpinner:</label></td>
+								<td>
+									<input id="decnumspinsel" data-dojo-type="dijit.form.NumberSpinner"
+										data-dojo-props='store:store, value: at(decnumspinctrl, "number")'/>
+								</td>
+								<td>
+									<input id="decnumspintext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(decnumspinctrl, 'number')"></input>
+								</td>
+								<td><span id="decnumspinOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="value: at(decnumspinctrl, 'number')">
+						 			${this.value}
+								</span></td>
+								<td><button id="decnumspinReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){decnumspinctrl.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="decsimpTAsel">SimpleTextArea:</label></td>
+								<td>
+									<input id="decsimpTAsel" data-dojo-type="dijit.form.Textarea"
+										data-dojo-props='store:store, value: at(decsimpTActrl, "number")'/>
+								</td>
+								<td>
+									<input id="decsimpTAtext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(decsimpTActrl, 'number')"/>
+								</td>
+								<td><span id="decsimpTAOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="value: at(decsimpTActrl, 'number')">
+						 			${this.value}
+								</span></td>
+								<td><button id="decsimpTAReset" type="button" data-dojo-type="dijit.form.Button" 
+										data-dojo-props="onClick: function(){decsimpTActrl.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="dectextareasel">TextArea:</label></td>
+								<td>
+									<input id="dectextareasel" data-dojo-type="dijit.form.Textarea"
+										data-dojo-props='store:store, value: at(dectextareactrl, "number")'/>
+								</td>
+								<td>
+									<input id="dectextareatext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(dectextareactrl, 'number')"/>
+								</td>
+								<td><span id="dectextareaOutput" data-dojo-type="dojox.mvc.Output" 
+											data-dojo-props="value: at(dectextareactrl, 'number')">
+						 			${this.value}
+								</span></td>
+								<td><button id="dectextareaReset" type="button" data-dojo-type="dijit.form.Button" 
+										data-dojo-props="onClick: function(){dectextareactrl.reset();}">Reset</button></td>
+							</tr>
+						</tbody>
+					</table>
+	  
+					<h2>Test data-bound dijit.Calendar:</h2>
+					<table>
+						<tbody>
+							<tr>
+								<td><label>Widget</label></td>
+								<td><label></label></td>
+								<td><label>Textbox</label></td>
+								<td><label>Output</label></td>
+								<td><label>Model Reset</label></td>
+							</tr>
+							<tr>
+								<td><label for="deccal">Calendar:</label></td>
+								<td>
+									<input class="cell"  id="deccal" data-dojo-id="deccal"  data-dojo-type="dijit.Calendar" 
+											data-dojo-props='value: at(deccalctrl, "date") '/>
+								</td>
+								<td>
+									<input class="cell" id="deccaltext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(deccalctrl, 'date')"></input>
+								</td>
+								<td><span   id="deccalOutput" data-dojo-type="dojox.mvc.Output"
+											data-dojo-props="value: at(deccalctrl, 'date')">
+						 			${this.value}
+								</span></td>
+								<td><button id="deccalReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){deccalctrl.reset();}">Reset</button></td>
+							</tr>
+							<tr>
+								<td><label for="deccolor">ColorPalette:</label></td>
+								<td>
+									<div id="deccolor" data-dojo-type="dijit.ColorPalette" 
+											data-dojo-props='palette:"3x4", value: at(deccolorctrl, "code")'></div>								
+								</td>
+								<td>
+									<input class="cell" id="deccolortext" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(deccolorctrl, 'code')"></input>
+								</td>
+								<td><span   id="deccolorOutput" data-dojo-type="dojox.mvc.Output"
+											data-dojo-props="value: at(deccolorctrl, 'code')">
+						 			${this.value}
+								</span></td>
+								<td><button id="deccolorReset" type="button" data-dojo-type="dijit.form.Button" 
+											data-dojo-props="onClick: function(){deccolorctrl.reset();}">Reset</button></td>
+							</tr>
+						</tbody>
+					</table>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_new_label_and_totals.html b/dojox/mvc/tests/test_mvc_new_label_and_totals.html
new file mode 100644
index 0000000..05ac51b
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_new_label_and_totals.html
@@ -0,0 +1,247 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>MVC Test for dynamic label and calculating totals</title>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			.cell { width: 30%;  display:inline-block; }			
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var model;
+ 
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			"dojox/mvc/getStateful",
+			'dojox/mvc/at',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Repeat',
+			'dojox/mvc/Output'
+			], function(parser, ready, getStateful, at){
+
+			// Order data
+			orderData = {
+				"Serial" : "111",
+				"First" : "",
+				"Lab" : "TEST",
+				"Last" : "last",
+				"Email" : "email",
+				"Age" : "33"
+			};
+
+			// Initial sum data
+			sumData = {
+				"one" : 1,
+				"two" : 2,
+				"three" : 3,
+				"four" : 4,
+				"total" : 10
+			};
+
+			// Initial repeat sum data
+			sumRepeatData = {
+				"list" : [
+				          {"item" : 1},
+				          {"item" : 2},
+				          {"item" : 3},
+				          {"item" : 4}
+				          ],	
+				"total" : 10
+			};
+
+			sumValuesConverter = {
+					format: function(value){
+						console.log("in sumValuesConverter format value ="+value);
+						value = value || 0;
+						return value;
+					},
+					parse: function(value){
+						console.log("in sumValuesConverter parse value ="+value);
+						recomputeTotal();
+						return value;
+					}
+			};
+
+			ageLabelConverter = {
+					format: function(value){
+						console.log("in ageLabelConverter format value ="+value);
+						if(!value){
+							return "Enter Age";
+						}else{
+							return "Enter "+value+"'s age";
+						}
+					},
+					parse: function(value){
+						console.log("in ageLabelConverter parse value ="+value);
+						return value;
+					}
+			};
+
+
+			sumRepeatValuesConverter = {
+					format: function(value){
+						console.log("in sumRepeatValuesConverter format value ="+value);
+						value = value || 0;
+						recomputeRepeatTotal();
+						return value;
+					},
+					parse: function(value){
+						console.log("in sumRepeatValuesConverter parse value ="+value);
+						return value;
+					}
+			};
+			
+			ready(function(){
+				parser.parse();
+				recomputeTotal();
+			});
+
+			// Old api
+			//summodel = mvc.newStatefulModel({ data : sumData });
+			//sumrepeatmodel = mvc.newStatefulModel({ data : sumRepeatData });
+			//model = mvc.newStatefulModel({ data : order });
+			// new Api
+			summodel = getStateful(sumData );
+			sumrepeatmodel = getStateful(sumRepeatData);
+			model = getStateful(orderData);
+			
+
+		});
+
+		function recomputeTotal() {
+				require([
+				         "dijit/registry",
+				         "dojox/mvc/at"
+				         ], function(registry, at){
+								var total = 0;			
+								var wone = parseInt(registry.byId("oneInput").get("value")) || 0;
+			   					var wtwo = parseInt(registry.byId("twoInput").get("value")) || 0;
+								var wthree = parseInt(registry.byId("threeInput").get("value")) || 0;
+			   					var wfour = parseInt(registry.byId("fourInput").get("value")) || 0;
+			   					total = wone + wtwo + wthree + wfour;
+			   					var wtotal = registry.byId("totalOutput");
+			   					wtotal.set("value", total);			   					
+							});
+			};
+
+
+			function recomputeRepeatTotal() {
+				require([
+				         "dijit/registry",
+				         "dojox/mvc/at"
+				         ], function(registry, at){
+								var total = 0;
+								for(var i=0;i<sumrepeatmodel.list.length;i++){
+									console.log("sumrepeatmodel.list[i].item = "+sumrepeatmodel.list[i].item);
+									var item = parseInt(sumrepeatmodel.list[i].item) || 0;
+									total = total + item;
+								}
+			   					var wtotal = registry.byId("totalrepeatOutput");
+			   					wtotal.set("value", total);			   					
+							});
+			};
+			
+			
+		</script>
+				
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="header">
+			<div id="navigation">
+			</div>
+			<div id="headerInsert">
+				<h2>MVC Test for dynamic label and calculating totals</h2>
+			</div>
+		</div>
+		<div id="main">
+		<div id="leftNav"></div>
+		<div id="mainContent">
+		<h4>Update Age label with first name when it is set.</h4>
+		<div data-dojo-type="dojox.mvc.Group"
+				data-dojo-props="target: model">		
+			<div class="row">
+				<label class="cell" for="firstInput">Enter first name:</label>
+				<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'First')">
+			</div>
+			<div class="row">
+				<label class="cell" for="lastnameInput">Enter last name:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Last')">
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Enter email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Email')">
+			</div>
+			<div class="row">
+				<label data-dojo-type="dojox.mvc.Output" class="cell" for="ageInput"
+					data-dojo-props="value: at('rel:', 'First').direction(at.from).transform(ageLabelConverter)"></label>
+				<input class="cell" id="ageInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Age')">
+			</div>
+		</div>
+		<br/>
+		<h4>Update total when any of the fields are changed.</h4>
+		<div data-dojo-type="dojox.mvc.Group"
+			data-dojo-props="target: summodel">
+		<div class="row">
+			<label class="cell" for="oneInput">Item one:</label>
+			<input class="cell" id="oneInput" data-dojo-type="dijit.form.TextBox" 
+				data-dojo-props="value: at('rel:', 'one').transform(sumValuesConverter)">
+		</div>
+		<div class="row">
+			<label class="cell" for="twoInput">Item two:</label>
+			<input class="cell" id="twoInput" data-dojo-type="dijit.form.TextBox" 
+				data-dojo-props="value: at('rel:', 'two').transform(sumValuesConverter)">
+		</div>
+		<div class="row">
+		<label class="cell" for="threeInput">Item three:</label>
+		<input class="cell" id="threeInput" data-dojo-type="dijit.form.TextBox" 
+			data-dojo-props="value: at('rel:', 'three').transform(sumValuesConverter)">
+	</div>
+	<div class="row">
+		<label class="cell" for="fourInput">Item four:</label>
+		<input class="cell" id="fourInput" data-dojo-type="dijit.form.TextBox" 
+			data-dojo-props="value: at('rel:', 'four').transform(sumValuesConverter)">
+	</div>
+		<div class="row">
+			<label class="cell" for="totalOutput">Total:</label>
+			<div class="cell" id="totalOutput" data-dojo-type="dojox.mvc.Output" 
+				data-dojo-props="value: at('rel:', 'total')"></div>
+	</div>
+	<br/>
+	<h4>Update total when any of the fields are changed - Using a Repeat.</h4>
+	<div id="outergroupId" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: sumrepeatmodel">
+		<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" 
+				data-dojo-props="children: at('rel:', 'list')">
+			<div data-dojo-type="dojox.mvc.Group"
+				data-dojo-props="target: at('rel:${this.index}')">
+				<div class="row">
+					<label class="cell" for="input${this.index}">Item ${this.index}:</label>
+					<input class="cell" id="input${this.index}" data-dojo-type="dijit.form.TextBox" 
+						data-dojo-props="value: at('rel:', 'item').transform(sumRepeatValuesConverter)">
+				</div>
+			</div>
+		</div>
+		<div class="row">
+			<label class="cell" for="totalrepeatOutput">Total:</label>
+			<div class="cell" id="totalrepeatOutput" data-dojo-type="dojox.mvc.Output" 
+				data-dojo-props="value: at('rel:', 'total')"></div>
+		</div>
+	</div>
+	<br/>
+		<br/>
+		Model:
+		<button id="reset" type="button" data-dojo-type="dijit.form.Button" 
+				data-dojo-props="onClick: function(){model.set(orderData);summodel.set(sumData);sumrepeatmodel.set(sumRepeatData);}">Reset</button>
+		</div></div></div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_new_loan-stateful.html b/dojox/mvc/tests/test_mvc_new_loan-stateful.html
new file mode 100644
index 0000000..704431d
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_new_loan-stateful.html
@@ -0,0 +1,290 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Loan Form (Using DOJO within MVC Support)</title>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+			var lookup, loanModel, validHousingPercentConverter = {
+				format: function(value){
+					return value <= 33;
+				}
+			}, nonZeroRelevanceConverter = {
+				format: function(value){
+					return value <= 0;
+				}
+			};
+
+			require([
+				"dojo/_base/array",
+				"dojo/_base/declare",
+				"dojo/_base/lang",
+				"dojo/request/xhr",
+				"dojo/parser",
+				"dojox/charting/Chart",
+				"dojox/charting/themes/PlotKit/blue",
+				"dojox/mvc/at",
+				"dojo/Stateful",
+				"dojox/mvc/StatefulSeries",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dijit/form/ValidationTextBox",
+				"dijit/form/NumberTextBox",
+				"dojox/charting/plot2d/Pie",
+				"dojox/mvc/_TextBoxExtensions",
+				"dojox/mvc/Group",
+				"dojox/mvc/ModelRefController",
+				"dojox/mvc/Output",
+				"dojo/domReady!"
+			], function(array, declare, lang, dxhr, parser, Chart, blue, at, Stateful, StatefulSeries){
+
+				lookup = function(model){
+					if(isNaN(model.get("Zip"))){ return; }
+					dxhr.get("zips/" + model.get("Zip") + ".json", {
+						content: {postalcode: model.get("Zip"), country: model.get("County")},
+						preventCache: true,
+						handleAs: "json"
+					}).then(function(data){
+						model.set("City", data.postalcodes[0].placeName);
+						model.set("County", data.postalcodes[0].adminName2);
+						model.set("State", data.postalcodes[0].adminCode1);
+						model.set("isZipValid", true);
+					}, function(e){
+						model.set("City", "");
+						model.set("County", "");
+						model.set("State", "");
+						model.set("isZipValid", false);
+					});	
+				};
+
+				function getNewValue(model, prop, name, value){
+					return prop == name ? value : model.get(prop);
+				}
+
+				function recomputeTotalAndPercentages(model, name, value){
+					var mortgage = getNewValue(model, "Mortgage", name, value);
+					var taxes = getNewValue(model, "Taxes", name, value);
+					var otherHousing = getNewValue(model, "OtherHousing", name, value);
+					var totalHousing = mortgage + taxes + otherHousing;
+			
+					var baseIncome = getNewValue(model, "BaseIncome", name, value);
+					var bonusIncome = getNewValue(model, "BonusIncome", name, value);
+					var totalIncome = baseIncome + bonusIncome;
+			
+					var housingPercentage = Math.round(totalHousing / totalIncome * 100);
+			
+					model.set("HousingPercent", housingPercentage);
+					model.set("TotalHousing", totalHousing);
+					model.set("TotalIncome", totalIncome);
+			
+					model[name] = value;
+				}
+
+				loanModel = new Stateful({
+					Name: "John Doe",
+					Street: "",
+					City: "",
+					County: "",
+					State: "",
+					Zip: "",
+					Country: "US",
+					TotalIncome: 0,
+					BaseIncome: 50000,
+					BonusIncome: 10000,
+					TotalHousing: 2700,
+					HousingPercent: 5,
+					Mortgage: 1000,
+					Taxes: 500,
+					OtherHousing: 1200,
+					_MortgageSetter: function(value){
+						recomputeTotalAndPercentages(this, "Mortgage", value);
+					},
+					_TaxesSetter: function(value){
+						recomputeTotalAndPercentages(this, "Taxes", value);
+					},
+					_OtherHousingSetter: function(value){
+						recomputeTotalAndPercentages(this, "OtherHousing", value);
+					},
+					_BaseIncomeSetter: function(value){
+						recomputeTotalAndPercentages(this, "BaseIncome", value);
+					},
+					_BonusIncomeSetter: function(value){
+						recomputeTotalAndPercentages(this, "BonusIncome", value);
+					}
+				});
+
+				parser.parse();
+
+				new Chart("expenseChart")
+				 .setTheme(blue)
+				 .addPlot("default", {type: "Pie"})
+				 .addSeries("default", new StatefulSeries([at(loanModel, "Mortgage"), 
+				                       at(loanModel, "Taxes"), at(loanModel, "OtherHousing")])).render();
+			});
+		</script>
+	</head>
+	<body class="claro" style="background-image: url(images/validating_form_pattern.png)">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="addressLookupController" class="dijitDisplayNone" 
+				data-dojo-type="dojox.mvc.ModelRefController"
+			 	data-dojo-props="model: loanModel, ownProps: {_setZipAttr: 1, _setCountyAttr: 1}">
+				<script type="dojo/method" event="_setZipAttr" args="value">
+					var changed = this.model.Zip != value;
+					this.model._changeAttrValue("Zip", value);
+					if(changed){
+						lookup(this.model);
+					}
+					return this;
+				</script>
+				<script type="dojo/method" event="_setCountyAttr" args="value">
+					var changed = this.model.County != value;
+					this.model._changeAttrValue("County", value);
+					if(changed){
+						lookup(this.model);
+					}
+					return this;
+				</script>
+			</div>
+			<div id="header">
+				<div id="navigation">
+				</div>
+				<div id="headerInsert">
+					<h1>Big Red Loan</h1>
+					<h2>The one to choose when you're in the red...</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent" data-dojo-type="dojox.mvc.Group" 
+						data-dojo-props="target: at('widget:addressLookupController')">
+					<h3>Borrower information</h3>
+					<hr size="6" class="rule"/>
+					<div class="spacer"></div>
+					<div class="row">
+						<div class="cell"><label for="borrowerInput">Name:</label></div>
+						<div class="cell">
+							<input id="borrowerInput" data-dojo-type="dijit.form.TextBox" 
+									data-dojo-props="value: at('rel:', 'Name')"/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label for="zipInput">Zipcode (try 10706):</label></div>
+						<div class="cell">
+							<input id="zipInput" data-dojo-type="dijit.form.NumberTextBox"
+							 data-dojo-props="value: at('rel:', 'Zip'), 
+							 				valid: at('rel:', 'isZipValid')"
+							 constraints="{pattern:'#'}" regExp="\d{5}" required="true" invalidMessage="Invalid Zip Code."/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label for="cityInput">City:</label></div>
+						<div class="cell">
+							<input id="cityInput" data-dojo-type="dijit.form.TextBox" 
+								data-dojo-props="value: at('rel:', 'City')"/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label for="countyInput">County:</label></div>
+						<div class="cell">
+							<input id="countyInput" data-dojo-type="dijit.form.TextBox" 
+											data-dojo-props="value: at('rel:', 'County')"/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label for="stateInput">State:</label></div>
+						<div class="cell">
+							<input id="stateInput" data-dojo-type="dijit.form.TextBox" 
+										data-dojo-props="value: at('rel:', 'State')"/>
+						</div>
+					</div>
+					<div class="spacer"></div>
+					<h3>Expenses</h3>
+					<hr size="6" class="rule"/>
+					<div class="spacer"></div>
+					<table style="width:900px;">
+						<tr style="width:900px;">
+							<td style="width:400px;">
+								<div class="row">
+									<div class="cell"><label for="housing">Mortgage:</label></div>
+									<div class="cell">
+										<input id="housing" data-dojo-type="dijit.form.NumberTextBox" 
+												data-dojo-props="value: at('rel:', 'Mortgage')"/>
+									</div>
+								</div>
+								<div class="row">
+									<div class="cell">
+										<label>Real Estate Taxes:</label>
+									</div>
+									<div class="cell">
+										<input id="taxes" data-dojo-type="dijit.form.NumberTextBox" 
+												data-dojo-props="value: at('rel:', 'Taxes')"/>
+									</div>
+								</div>
+								<div class="row">
+									<div class="cell"><label>Other Housing:</label></div>
+									<div class="cell">
+										<input id="otherHousing" type="text" data-dojo-type="dijit.form.NumberTextBox" 
+												data-dojo-props="value: at('rel:', 'OtherHousing')"/>
+									</div>
+								</div>
+								<div class="row">
+									<div class="cell"><label for="transportation">Total Housing:</label></div>
+									<div class="cell">
+										<input id="totalHousing" data-dojo-type="dijit.form.NumberTextBox"
+										 data-dojo-props="value: at('rel:', 'TotalHousing'),
+										                  disabled: at('rel:', 'TotalHousing').direction(at.from).transform(nonZeroRelevanceConverter)"/>
+									</div>
+								</div>
+							</td>
+							<td style="width:200px;">
+								<div id="expenseChart" style="display:block; width: 150px; height: 150px;"></div>
+							</td>
+						</tr>
+					</table>
+					<h3>Income</h3>
+					<hr size="6" class="rule"/>
+					<div class="spacer"></div>
+					<div class="row">
+						<div class="cell"><label for="baseIncome">Base Income:</label></div>
+						<div class="cell">
+							<input id="baseIncome" type="text" data-dojo-type="dijit.form.NumberTextBox" 
+									data-dojo-props="value: at('rel:', 'BaseIncome')"/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label>Bonus Income:</label></div>
+						<div class="cell">
+							<input id="bonusIncome" type="text" data-dojo-type="dijit.form.NumberTextBox" 
+									data-dojo-props="value: at('rel:', 'BonusIncome')"/>
+						</div>
+					</div>
+					<div class="row">
+						<div class="cell"><label for="total">Total Income:</label></div>
+						<div class="cell">
+							<input id="total" data-dojo-type="dijit.form.NumberTextBox" 
+									data-dojo-props="value: at('rel:', 'TotalIncome')"/>
+						</div>
+					</div>
+					<h3>Analysis</h3>
+					<hr size="6" class="rule"/>
+					<div class="spacer"></div>
+					<div class="row">
+						<div class="cell"><label for="percentHousing">Percent housing (under 33%):</label></div>
+						<div class="cell">
+							<input id="percentHousing" data-dojo-type="dijit.form.NumberTextBox"
+							 data-dojo-props="value: at('rel:', 'HousingPercent'),
+							                  valid: at('rel:', 'HousingPercent').direction(at.from).transform(validHousingPercentConverter),
+							                  disabled: at('rel:', 'HousingPercent').direction(at.from).transform(nonZeroRelevanceConverter)"
+							 invalidMessage="Housing should be less than 1/3 total expenses!"/>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_new_shipto-billto-simple.html b/dojox/mvc/tests/test_mvc_new_shipto-billto-simple.html
new file mode 100644
index 0000000..bdb737d
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_new_shipto-billto-simple.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:1,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var model;
+ 
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			"dojox/mvc/getStateful",
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(parser, ready, getStateful){
+			
+			// Initial data
+			var order = {
+				"Serial" : "360324",
+				"First" : "John",
+				"Last" : "Doe",
+				"Email" : "jdoe at example.com",
+				"ShipTo" : {
+					"Street" : "123 Valley Rd-ShipTo",
+					"City" : "Katonah",
+					"State" : "NY",
+					"Zip" : "10536"
+				},
+				"BillTo" : {
+					"Street" : "17 Skyline Dr-BillTo",
+					"City" : "Hawthorne",
+					"State" : "NY",
+					"Zip" : "10532"
+				}
+			};
+				// The getStateful call will take json data and create make it Stateful
+				model = getStateful(order);
+				// the model created above is initialized with 
+				// model.First set to "John", model.Last set to "Doe" and model.Email set to "jdoe at example.com"
+
+			});
+
+			function setRef(id, model, attr) {
+				require([
+				         "dijit/registry",
+				         "dojox/mvc/at"
+				         ], function(registry, at){
+								var widget = registry.byId(id);
+								widget.set("target", model[attr]);
+							});
+			};
+		
+		</script>
+		
+		
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+		<div id="header">
+			<div id="navigation">
+			</div>
+			<div id="headerInsert">
+				<h1>Order Shipping Details</h1>
+				<h2>Data Binding Example - Group Container.</h2>
+			</div>
+		</div>
+		<div id="main">
+		<div id="leftNav"></div>
+		<div id="mainContent">
+		<!--
+			The group container denotes some logical grouping of widgets and also serves
+			to establish a parent data binding context for its children.
+			The target attribute for the outermost container obtains the binding from the
+			"page scope" itself.
+		-->
+		<div class="row" data-dojo-type="dojox.mvc.Group" 
+							data-dojo-props="target: model">
+			<div class="row">
+				<label class="cell" for="serialInput">Order #:</label>
+				<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox" 
+							data-dojo-props="value: at('rel:', 'Serial')">
+			</div>
+			<div class="row">
+				<label class="cell" for="lastnameInput">Last:</label>
+				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Last')">
+			</div>
+			<div class="row">
+				<label class="cell" for="emailInput">Email:</label>
+				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Email')">
+			</div>
+		</div>
+		<br/>
+		Choose:
+		<button id="shipto" type="button" data-dojo-type="dijit.form.Button" 
+				data-dojo-props="onClick: function(){setRef('addrGroup', model, 'ShipTo');}">Ship To</button>
+		<button id="billto" type="button" data-dojo-type="dijit.form.Button" 
+				data-dojo-props="onClick: function(){setRef('addrGroup', model, 'BillTo');}">Bill To</button>
+		<br/>
+		<!--
+			For convenience, the widget hierarchy matches the data hierarchy
+			(see JSON literal above).
+			In this implementation, the child attributes are simple property names
+			of the parent binding context.
+		-->
+		<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group" 
+							data-dojo-props="target: model.ShipTo">
+			<div class="row">
+				<label class="cell" for="streetInput">Street:</label>
+				<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Street')">
+			</div>
+			<div class="row">
+				<label class="cell" for="cityInput">City:</label>
+				<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'City')">
+			</div>
+			<div class="row">
+				<label class="cell" for="stateInput">State:</label>
+				<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'State')">
+			</div>
+			<div class="row">
+				<label class="cell" for="zipInput">Zipcode:</label>
+				<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox" 
+					data-dojo-props="value: at('rel:', 'Zip')">
+			</div>
+		</div>
+		<br/>
+		</div></div></div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_observable-search-results-ins-del.html b/dojox/mvc/tests/test_mvc_observable-search-results-ins-del.html
new file mode 100644
index 0000000..198d9ab
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_observable-search-results-ins-del.html
@@ -0,0 +1,347 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Static Master/Detail Pattern -- Search Results example</title>
+		<script src="../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: true, mvc: {debugBindings: true}">
+		</script>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript">
+			var data = [
+				{
+					id: "1",
+					Group: "Engineer",
+					First: "Anne",
+					Last: "Ackerman",
+					Location: "NY",
+					Office: "1S76",
+					Email: "a.a at test.com",
+					Tel: "123-764-8237",
+					Fax: "123-764-8228"
+				},
+				{
+					id: "2",
+					Group: "Engineer",
+					First: "Ben",
+					Last : "Beckham",
+					Location: "NY",
+					Office: "5N47",
+					Email: "b.b at test.com",
+					Tel: "123-764-8599",
+					Fax: "123-764-8600"
+				},
+				{
+					id: "3",
+					Group: "Engineer",
+					First: "Chad",
+					Last: "Chapman",
+					Location: "CA",
+					Office: "1278",
+					Email: "c.c at test.com",
+					Tel: "408-764-8237",
+					Fax: "408-764-8228"
+				},
+				{
+					id: "4",
+					Group: "Engineer",
+					First: "David",
+					Last: "Durham",
+					Location: "NJ",
+					Office: "C12",
+					Email: "d.d at test.com",
+					Tel: "514-764-8237",
+					Fax: "514-764-8228"
+				},
+				{
+					id: "5",
+					Group: "Engineer",
+					First: "Emma",
+					Last: "Eklof",
+					Location: "NY",
+					Office: "4N76",
+					Email: "e.e at test.com",
+					Tel: "123-764-1234",
+					Fax: "123-764-4321"
+				},
+				{
+					id: "6",
+					Group: "Manager",
+					First: "Fred",
+					Last: "Fisher",
+					Location: "NJ",
+					Office: "V89",
+					Email: "f.f at test.com",
+					Tel: "514-764-8567",
+					Fax: "514-764-8000"
+				},
+				{
+					id: "7",
+					Group: "Manager",
+					First: "George",
+					Last: "Garnett",
+					Location: "NY",
+					Office: "7S11",
+					Email: "gig at test.com",
+					Tel: "123-999-8599",
+					Fax: "123-999-8600"
+				},
+				{
+					id: "8",
+					Group: "Accountant",
+					First: "Hunter",
+					Last: "Huffman",
+					Location: "CA",
+					Office: "6532",
+					Email: "h.h at test.com",
+					Tel: "408-874-8237",
+					Fax: "408-874-8228"
+				},
+				{
+					id: "9",
+					Group: "Accountant",
+					First: "Irene",
+					Last: "Ira",
+					Location: "NJ",
+					Office: "F09",
+					Email: "i.i at test.com",
+					Tel: "514-764-6532",
+					Fax: "514-764-7300"
+				},
+				{
+					id: "10",
+					Group: "Accountant",
+					First: "John",
+					Last: "Jacklin",
+					Location: "CA",
+					Office: "6701",
+					Email: "j.j at test.com",
+					Tel: "408-764-1234",
+					Fax: "408-764-4321"
+				}
+			], ctrl;
+
+			require([
+				"dojo/_base/declare",
+				"dojo/when",
+				"dojo/parser",
+				"dijit/registry",
+				"dojo/Stateful",
+				"dojo/store/Memory",
+				"dojo/store/Observable",
+				"dojox/mvc/EditStoreRefListController",
+				"dojox/mvc/equals",
+				"dijit/form/Button",
+				"dijit/form/RadioButton",
+				"dijit/form/TextBox",
+				"dijit/form/ComboBox",
+				"dijit/Dialog",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Repeat",
+				"dojo/domReady!"
+			], function(declare, when, parser, registry, Stateful, Memory, Observable, 
+						EditStoreRefListController, equals){
+
+				var inited,
+				 ctrlClass = declare([EditStoreRefListController], {
+					cursorIndex: 0,
+					idProperty: "id",
+					group: "",
+					groupTyped: "",
+					_refModelProp: "model",
+
+					addEmpty: function(idx){
+						//this.model.push(new Stateful({id:Math.random(), Group: this.groupTyped, First: "", Last: "", Location: "", Office: "", Email: "", Tel: "", Fax: ""}));
+						this.model.splice(idx+1, 0, new Stateful({id:Math.random(), Group: this.groupTyped, First: "", Last: "", Location: "", Office: "", Email: "", Tel: "", Fax: ""}));
+						this.set("cursorIndex", idx+1);
+						//this.set("cursorIndex", this.get("length") - 1);
+					},
+
+					remove: function(idx){
+						this.model.splice(idx, 1);
+						if(this.get("cursorIndex") < 0){
+							this.set("cursorIndex", this.get("length") - 1);
+						}
+					},
+
+					// called when set("group",..) is called, this will query the store
+					_setGroupAttr: function(value){
+						this.set("groupTyped", value);
+						var old = this.group;
+						if(old === value){ return; }
+						when(this.queryStore({Group: value}), function(){
+							if(!inited){
+								parser.parse();
+								inited = true;
+							}
+						});
+						this._set("group", value);
+
+						this.sourceModel.observe(function(object, removedFrom, insertedInto){
+							console.log("observeHandle hit");
+							// need to check to see if the model has been updated, use mvc.equals.
+							var clean = equals(ctrl.originalModel, ctrl.model);
+							console.log("store updated, model is clean?  "+clean);
+							if(!clean){
+								//  use a simple confirm dialog for this one
+								if(confirm("The store has been updated, do you want to save your changes? Select 'OK' to save your changes, select 'Cancel' to discard your changes")){
+									ctrl.commit(); 
+								}
+							}
+							var grp = ctrl.get("group");
+							ctrl.queryStore({Group: grp});			
+						});				
+						
+					}
+				});
+
+				// called to show items for a different group
+				search = function() { 					
+					// need to check to see if the model has been updated, use mvc.equals.
+					var clean = equals(ctrl.originalModel, ctrl.model);
+					console.log("the seach is changing, model is clean?  "+clean);
+					if(!clean && (ctrl.get('groupTyped') !== ctrl.get('group'))){
+						//  use a dijit.dialog for this one
+						registry.byId("myFormDialog").show();
+					}else{
+						ctrl.set('group', ctrl.get('groupTyped'));
+					}
+				};
+
+				commitAndUpdate = function(){
+			        registry.byId("myFormDialog").hide();
+					ctrl.commit(); 
+					ctrl.set('group', ctrl.get('groupTyped'));
+			   };
+
+			    justUpdate = function(){
+			        registry.byId("myFormDialog").hide();
+					ctrl.set('group', ctrl.get('groupTyped'));			        
+			    };
+			    
+				storeAddIndex = 0;
+				// Add an item to the store, to see the Observable fire
+				testStoreAdd = function(){
+					storeAddIndex++;				
+					var store = ctrl.store;
+					var grp = ctrl.get("group");
+					var newdata = {Group: grp, First: "NEWfirst"+storeAddIndex, 
+												Last: "NEWlast"+storeAddIndex, Location: "NEWlocation"+storeAddIndex, 
+												Office: "NEWoffice"+storeAddIndex, Email: "NEWEmail"+storeAddIndex, 
+												Tel: "NEWtel"+storeAddIndex, Fax: "NEWfax"+storeAddIndex};
+					
+					store.put(newdata);
+				};
+				
+				// using Observable allows us to listen for any changes to the store
+				ctrl = new ctrlClass({store: Observable(new dojo.store.Memory({data: data}))});
+				ctrl.set("group", "Engineer");
+			});
+		 </script>
+	</head>
+	<body class="claro" style="background-image: url(images/master_detail.png)">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Employee Search</h1>
+					<h2>Master Detail Example - Observable Repeat with insert and delete.</h2>
+					<h4>Press the "Add New Item to Store" button to update the store with a new item, the Observable will fire and update the model if no updates are in progress.  If an uncommitted change has been made an alert will ask if you want to save your change.</h4>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+					<div id="mainContent">
+						<div class="row">
+						<div class="spacer"></div>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ testStoreAdd(); }">Add New Item to Store</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commit(); }">Commit All</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset to last saved</button>
+						</div>
+						<div class="spacer"></div>
+						<div>
+							Try "Engineer", "Manager", or "Accountant":
+						</div>
+						<div class="row">
+							<label class="cell" for="queryInput">Search for:</label>
+							<select id="setvaluetest" data-dojo-type="dijit.form.ComboBox" data-dojo-props="value: at(ctrl, 'groupTyped')">
+								<option value="Engineer">Engineer</option>
+								<option value="Manager">Manager</option>
+								<option value="Accountant">Accountant</option>
+							</select>							
+							<button type="button" data-dojo-type="dijit.form.Button"
+							 data-dojo-props="onClick: function(){ search(); }">Search</button>
+						</div>
+						<div class="spacer"></div>
+						<div id="searchBanner">
+							Search Results for group: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(ctrl, 'group')"></span>
+						</div>
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at(ctrl, 'model')">
+							<div class="row" data-dojo-type="dijit._WidgetBase" data-dojo-props="target: at('rel:', ${this.index})">
+								<label class="cell" for="nameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}"
+								 data-dojo-props="value: at('rel:', 'First')">
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${this.index}); }">Details</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.addEmpty(${index}); }">+</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.remove(${index}); }">-</button>
+							</div>
+						</div>
+						<div class="spacer"></div>
+						<div id="detailsBanner">
+							Details for result index:
+							<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(ctrl, 'cursorIndex')"></span>
+						</div>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commitCurrent(); }">Save Item</button>
+						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'cursor')">
+							<div class="row">
+								<label class="cell" for="firstInput">First Name:</label>
+								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')">
+							</div>
+							<div class="row">
+								<label class="cell" for="lastInput">Last Name:</label>
+								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')">
+							</div>
+							<div class="row">
+								<label class="cell" for="locationInput">Location:</label>
+								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Location')">
+							</div>
+							<div class="row">
+								<label class="cell" for="officeInput">Office:</label>
+								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Office')">
+							</div>
+							<div class="row">
+								<label class="cell" for="emailInput">Email:</label>
+								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')">
+							</div>
+							<div class="row">
+								<label class="cell" for="telInput">Telephone:</label>
+								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Tel')">
+							</div>
+							<div class="row">
+								<label class="cell" for="faxInput">Fax:</label>
+								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Fax')">
+							</div>
+						</div>
+					</div>
+				</div>
+			</div>
+		<div data-dojo-type="dijit/Dialog" id="myFormDialog" title="Changing the search will cause you to lose your updates, do you want to save your changes?">
+    		<h3>Save Updates?</h3>
+    		<h5>
+        		"Changing the search will cause you to lose your updates, do you want to save your changes? 
+				<br />
+        		Select 'Yes' to save your changes, select 'No' to discard your changes"
+    		</h5>
+    		<br />
+			<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick:commitAndUpdate">Yes</button>
+			<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick:justUpdate">No</button>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_programmatic-repeat-store.html b/dojox/mvc/tests/test_mvc_programmatic-repeat-store.html
index 3be7256..3935507 100644
--- a/dojox/mvc/tests/test_mvc_programmatic-repeat-store.html
+++ b/dojox/mvc/tests/test_mvc_programmatic-repeat-store.html
@@ -4,144 +4,166 @@
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Programmatic Repeat example, using a store with save, commit and reset</title>
 
-		<script src="../../../dojo/dojo.js"
-			type="text/javascript"
-			djConfig="parseOnLoad: false, isDebug: true">
-		</script>
-		<style type="text/css">
+		<style>
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/tests/css/dijitTests.css";
 			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
 		</style>
-		<script type="text/javascript" >
-			dojo.require("dojox.mvc");
-			dojo.require("dojox.mvc.Group");
-			dojo.require("dojox.mvc.Repeat");
-			dojo.require("dijit.form.TextBox");
-			dojo.require("dijit.form.Button");
-			dojo.require("dojo.data.ItemFileWriteStore");
-			dojo.require("dojo.store.DataStore");
-			dojo.require("dojo.parser");
 
-			var results, selectedIndex = 0;
-				// declared here for convenience
-			templateString = '<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: \'${this.index}\'">' +
-							'<label class="cell">Name:</label>' + 
-							'<input class="cell" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: \'First\'"></input>' +
-							'<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext(\'${this.index}\');}">Details</button>' +
-						'</div>';
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+		<!-- required: dojo.js -->
+		<script src="../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: 1, mvc:{debugBindings:1}"></script>
 
-			function setup() {
-				var writeStore = new dojo.data.ItemFileWriteStore({url: dojo.moduleUrl("dojox.mvc.tests._data", "mvcRepeatData.json")});
-				var modelPromise = dojox.mvc.newStatefulModel({store: new dojo.store.DataStore({store: writeStore})}); 
-				modelPromise.then(function(model){ 
-					results = model;
-					dojo.parser.parse();
+		<script type="text/javascript">
+			require([
+				"dojo/_base/array",
+				"dojo/_base/declare",
+				"dojo/_base/lang",
+				"dojo/dom",
+				"dojo/parser",
+				"dojo/Stateful",
+				"dojo/store/JsonRest",
+				"dijit/registry",
+				"dijit/_WidgetBase",
+				"dojox/mvc/at",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/EditStoreRefController",
+				"dojox/mvc/ListController",
+				"dojox/mvc/Repeat",
+				"dojox/mvc/StatefulArray",
+				"dijit/form/TextBox",
+				"dijit/form/Button",
+				"dojox/mvc/Group",
+				"dojo/domReady!"
+			], function(array, declare, lang, ddom, parser, Stateful, JsonRest, registry, _WidgetBase, at, getStateful, EditStoreRefController, ListController, Repeat, StatefulArray){
+
+				var ctrlClass = declare([_WidgetBase, EditStoreRefController, ListController], {
+					idProperty: "Serial",
+					store: new JsonRest({target: require.toUrl("dojox/mvc/tests/_data/mvcRepeatData.json")}),
+					getStatefulOptions: {
+						getType: function(v){
+							return (v || {}).identifier ? "root" : lang.isArray(v) ? "array" : v !== null && v !== void 0 && {}.toString.call(v) == "[object Object]" ? "object" : "value";
+						},
+						getStatefulRoot: function(root){
+							return this.getStatefulArray(root.items);
+						},
+						getStatefulArray: function(a){
+							return new StatefulArray(array.map(a, function(item){ return getStateful(item, this); }, this));
+						},
+						getStatefulObject: function(o){
+							var stateful = new Stateful();
+							for(var s in o){
+								stateful[s] = getStateful(o[s], this);
+							}
+							return stateful;
+						},
+						getStatefulValue: function(v){
+							return v;
+						}
+					},
+					commitCurrent: function(){
+						var id = this.cursor[this.idProperty];
+						for(var i = 0; i < this.originalModel.length; i++){
+							if(this.originalModel[i][this.idProperty] == id){
+								this.originalModel.set(i, this.cloneModel(this.cursor));
+								break;
+							}
+						}
+						this.store.put(this.cursor);
+					}
+				});
+				(ctrl = (new ctrlClass({srcNodeRef: ddom.byId("detailsGroup"), cursorIndex: 0}))).startup();
 
-					// Can test with either the dojox.mvc.Repeat or my.Repeat
-					var repeat = new my.Repeat({
-					//var repeat = new dojox.mvc.Repeat({
-					//	templateString: templateString, // not needed with my.Repeat since it is set there.
-						ref: model
-					}).placeAt('repeat2');
-					repeat.startup();
+				var repeatClass = declare("my.Repeat", Repeat, {
+					templateString: '<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(\'rel:\', \'${this.index}\')">'
+					 + '<label class="cell">Name:</label>'
+					 + '<input id="${id}_textbox${index}" class="cell" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at(\'rel:\', \'First\')"></input>'
+					 + '<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.set(\'cursorIndex\', \'${this.index}\'); }">Details</button>'
+					 + '</div>'
 				});
-			};
 
-			dojo.declare('my.Repeat', [dojox.mvc.Repeat], {
-				templateString : templateString
+				(new repeatClass({children: at(ctrl, "model")}).placeAt('repeat2')).startup();
+
+				parser.parse();
+
+				ctrl.queryStore({});
 			});
-			dojo.addOnLoad(setup);
 		</script>
 	</head>
-	<body class="claro" style="background-image: url(images/master_detail.png)">
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
 		<div id="wrapper">
 			<div id="header">
 				<div id="navigation">
 				</div>
 				<div id="headerInsert">
-				<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
+					<h1>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h1>
 				</div>
 			</div>
 			<div id="main">
-				<div id="leftNav">
-				</div>
+				<div id="leftNav"></div>
 				<div id="mainContent">
-					<div id="searchBanner">Search Results for term: </div>         
-					<!--
-						The repeat container denotes a templated UI that operates over a collection
-						of data records.
-						The UI can be customized for each iteration using properties such as
-						${this.index} for the iteration index.
-					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results', templateString: templateString"></div>
-					<div id="repeatId" data-dojo-type="my.Repeat" data-dojo-props="ref: 'results'"></div>
-					-->
-					<table><tbody><tr>
+					<div id="searchBanner">Search Results for term: </div>
+					<table>
+						<tbody>
+							<tr>
 								<td>
 									<div>
-										<div>Programatic Repeat using my.Repeat and its templateString: </div>         
+										<div>Programatic Repeat using my.Repeat and its templateString: </div>
 										<div id="repeat2"></div>
 									</div>
 								</td>
 								<td>
 									<div>
-										<div>Declarative Repeat using my.Repeat does not pass templateString: </div>         
-										<div id="repeatId2" data-dojo-type="my.Repeat" data-dojo-props="ref: 'results'"></div>
+										<div>Declarative Repeat using my.Repeat does not pass templateString: </div>
+										<div id="repeatId2" data-dojo-type="my.Repeat" data-dojo-props="children: at(ctrl, 'model')"></div>
 									</div>
 								</td>
-					</tr></tbody></table>
-					
+							</tr>
+						</tbody>
+					</table>
 					<div class="spacer"></div>
-
-					<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results'">
-						<div id="detailsBanner">Details for selected index:</div>
-
-						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
-							<div class="row">
-								<label class="cell" for="firstInput">First Name:</label>
-								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="lastInput">Last Name:</label>
-								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="locationInput">Location:</label>
-								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="officeInput">Office:</label>
-								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="emailInput">Email:</label>
-								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="telInput">Telephone:</label>
-								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="faxInput">Fax:</label>
-								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
-							</div>
-							<div class="row">
-							<div class="spacer"></div>
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results[selectedIndex].toPlainObject());results[selectedIndex].commit();}">Save Item</button>        
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.toPlainObject());results.commit();;}">Commit All</button>        
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.reset();}">Reset to last saved</button>        
-							</div>
+					<div id="detailsBanner">Details for selected index:</div>
+					<div id="detailsGroup">
+						<div class="row">
+							<label class="cell" for="firstInput">First Name:</label>
+							<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="lastInput">Last Name:</label>
+							<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="locationInput">Location:</label>
+							<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Location')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="officeInput">Office:</label>
+							<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Office')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="emailInput">Email:</label>
+							<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="telInput">Telephone:</label>
+							<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Tel')"></input>
+						</div>
+						<div class="row">
+							<label class="cell" for="faxInput">Fax:</label>
+							<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Fax')"></input>
+						</div>
+						<div class="row">
+						<div class="spacer"></div>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commitCurrent(); }">Save Item</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commit();}">Commit All</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset to last saved</button>
 						</div>
 					</div>
 				</div>
 			</div>
-        </div>
-        <script type="text/javascript">
-			// called to change the selected item
-			function setDetailsContext(index) {
-				selectedIndex = index;
-				var widget = dijit.byId("detailsGroup");
-				widget.set("ref", index);
-			};
-        </script>
-    </body>
+		</div>
+	</body>
 </html>
diff --git a/dojox/mvc/tests/test_mvc_radiobutton.html b/dojox/mvc/tests/test_mvc_radiobutton.html
new file mode 100644
index 0000000..919daae
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_radiobutton.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>RadioButton MVC test</title>
+		<style type="text/css">
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript" data-dojo-config="parseOnLoad:1,isDebug:1,async:1,mvc:{debugBindings:1}" src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+require([
+	
+    "dojo/ready",
+    "dojo/parser",
+    "dijit/registry",
+    'dojox/mvc/at',
+	"dojox/mvc/EditModelRefController",
+	"dojox/mvc/getStateful",
+	"dojo/Stateful",
+	"dojox/mvc/Output",
+    "dijit/form/RadioButton",
+    "dijit/form/Button" // used for example purpose
+], function(ready, parser, registry, at, EditModelRefController, getStateful, Stateful, RadioButton){
+    var data = { selectedValue: "",
+    		radio1Checked: false,
+    		radio1Value: "Tea",
+    		radio2Checked: false,
+    		radio2Value: "Coffee",
+    		radio3Checked: false,
+    		radio3Value: "Coke",
+    		radio4Checked: false,
+			radio4Value: "Pepsi"
+    };
+	
+	model = getStateful(data); 
+	
+	transformRadioChecked = {
+				format: function(checked){
+					return checked;
+				},
+				parse: function(checked){
+					if(checked){
+						model.set("selectedValue", this.target.value);
+						console.log("in transformRadioChecked setting selectedValue to "+this.target.value);
+					}
+					return checked;
+				}
+			};
+	
+    ready(function(){
+    	
+        registry.byId("radio3").set("value", at(model, "radio3Value"));
+        registry.byId("radio3").set("checked", at(model, "radio3Checked").transform(transformRadioChecked));
+        registry.byId("radio4").set("value", at(model, "radio4Value"));
+        registry.byId("radio4").set("checked", at(model, "radio4Checked").transform(transformRadioChecked));
+        registry.byId("radio1").set("checked", true);
+        
+    });
+});</script>
+</head>
+<body class="claro">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<h1>Bind MVC model to Radio buttons</h1>
+	<h2>Bind the value, label and checked, and set selectedValue in the model.</h2>
+	
+    <form id="myform">
+    <input type="radio" data-dojo-type="dijit/form/RadioButton" name="drink" id="radio1" 
+    	data-dojo-props="value: at(model, 'radio1Value'), checked: at(model, 'radio1Checked').transform(transformRadioChecked)"/> 
+    <label for="radio1" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(model, 'radio1Value')"></label> <br />
+    <input type="radio" data-dojo-type="dijit/form/RadioButton" name="drink" id="radio2" 
+    	data-dojo-props="value: at(model, 'radio2Value'), checked: at(model, 'radio2Checked').transform(transformRadioChecked)"/> 
+    <label for="radio2" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(model, 'radio2Value')"></label> <br />
+    <input type="radio" data-dojo-type="dijit/form/RadioButton" name="drink" id="radio3"/> 
+    <label for="radio3" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(model, 'radio3Value')"></label> <br />
+    <input type="radio" data-dojo-type="dijit/form/RadioButton" name="drink" id="radio4"/> 
+    <label for="radio4" data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(model, 'radio4Value')"></label> <br />
+
+</form>
+<br />
+    <label>Selected Value is:</label> <br />
+    <div data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(model, 'selectedValue')"></div> <br />
+
+</body>
+</html>
\ No newline at end of file
diff --git a/dojox/mvc/tests/test_mvc_ref-kitchensink.html b/dojox/mvc/tests/test_mvc_ref-kitchensink.html
deleted file mode 100755
index 2726a81..0000000
--- a/dojox/mvc/tests/test_mvc_ref-kitchensink.html
+++ /dev/null
@@ -1,160 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Data binding -- Ref kitchen sink example</title>
-
-		<script src="../../../dojo/dojo.js"
-				type="text/javascript"
-				djConfig="parseOnLoad: true, isDebug: true">
-		</script>
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-		<script type="text/javascript" >
-		  dojo.require("dojox.mvc");
-		  dojo.require("dojox.mvc.Group");
-		  dojo.require("dijit.form.TextBox");
-		  dojo.require("dijit.form.Button");
-		  dojo.require("dojo.parser");
-
-		  // Initial data
-		  var order = {
-			  "Serial" : "360324",
-			  "First"  : "John",
-			  "Last"   : "Doe",
-			  "Email"  : "jdoe at example.com",
-			  "ShipTo" : {
-				  "Street" : "123 Valley Rd",
-				  "City"   : "Katonah",
-				  "State"  : "NY",
-				  "Zip"	   : "10536"
-			  },
-			  "BillTo" : {
-				  "Street" : "17 Skyline Dr",
-				  "City"   : "Hawthorne",
-				  "State"  : "NY",
-				  "Zip"	   : "10532"
-			  }
-		  };
-
-		  // This example is an odd mix of everything, being the kitchen sink example :-)
-
-		  // The dojox.mvc.StatefulModel class creates a data model instance, which will be
-		  // shared by widgets being instantiated programmatically as well as
-		  // declaratively
-		  var model = dojox.mvc.newStatefulModel({ data : order });
-
-		  // Here is programmatic data bound widget instantiation
-		  function addBoundDijits(){
-			  // Absolute ref, passed as object
-			  var serial = new dijit.form.TextBox({id: "serialInput", ref: model.Serial});
-			  serial.placeAt(dojo.byId("serialDiv"));
-			  serial.startup();
-
-			  // Relative refs, passed as strings
-			  var fn = new dijit.form.TextBox({id: "firstnameInput", ref: "First"});
-			  fn.placeAt(dojo.byId("firstnameDiv"));
-			  fn.startup();
-			  var ln = new dijit.form.TextBox({id: "lastnameInput", ref: "Last"});
-			  ln.placeAt(dojo.byId("lastnameDiv"));
-			  ln.startup();
-		  }
-
-		  dojo.addOnLoad(addBoundDijits);
-		</script>
-	</head>
-	<body class="claro">
-		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>Data Binding</h1>
-			<h2>Ref kitchen sink example - all ways to specify refs, mixed bag on purpose.</h2>
-		  </div>
-		</div>
-		<div id="main">
-		  <div id="leftNav">
-		  </div>
-		  <div id="mainContent">
-		<!--
-			Following group shows first example of declarative usage. Its child
-			dijits are added programmatically.
-			Here, the ref points to the application space "model" variable (can
-			be any dot-separated expression).
-		-->
-		<div class="row" id="infoGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model'">
-			<!-- The serial text box gets placed in div below programmatically -->
-			<div class="row" id="serialDiv">
-				<label class="cell" for="serialInput">Order #:</label>
-			</div>
-			<!-- The first and last name text boxes gets placed in corresponding
-				 divs below, with a relative ref to data-bound parent (group) -->
-			<div class="row" id="firstnameDiv">
-				<label class="cell" for="firstnameInput">First:</label>
-			</div>
-			<div class="row" id="lastnameDiv">
-				<label class="cell" for="lastnameInput">Last:</label>
-			</div>
-			<!-- Here, we break out of any parent data binding association
-				 by declaratively specifying a direct ref expression.
-				 There is no necessity for DOM to match data structure even in
-				 declarative ref specifications. -->
-			<div class="row" id="emailDiv">
-				<label class="cell" for="emailInput">Email:</label>
-				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'expr:model.Email'"></input>
-			</div>
-		</div>
-		<br/>
-		Choose:
-		<button id="shipto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', model.ShipTo);}">Ship To</button>
-		<button id="billto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', model.BillTo);}">Bill To</button>
-		<br/>
-		<!--
-			Following group shows a declarative example of a ref thats relative
-			to another widget's ref. This is useful, for example, if the widget
-			may move its DOM location at some point.
-			Here, we're saying group's ref is relative to "infoGroup" widget's
-			ref and is located at the property "ShipTo" therein.
-		-->
-		<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'widget:infoGroup.ShipTo'">
-			<!-- This is a relative ref, passed as a string -->
-			<div class="row">
-				<label class="cell" for="streetInput">Street:</label>
-				<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Street'"></input>
-			</div>
-			<!-- Here, we are explicit that the string is a relative ref, which
-				is slightly more performant. -->
-			<div class="row">
-				<label class="cell" for="cityInput">City:</label>
-				<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'rel:City'"></input>
-			</div>
-			<!-- Just goofing with whitespace in refs below, for robustness -->
-			<div class="row">
-				<label class="cell" for="stateInput">State:</label>
-				<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: '	 rel:	State'	"></input>
-			</div>
-			<div class="row">
-				<label class="cell" for="zipInput">Zipcode:</label>
-				<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Zip' "></input>
-			</div>
-		</div>
-		<br/>
-		Model:
-		<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
-		</div></div></div>
-		<script type="text/javascript">
-			function setRef(id, addrRef) {
-				var widget = dijit.byId(id);
-				widget.set("ref", addrRef);
-			}
-		</script>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/test_mvc_ref-set-repeat-simple.html b/dojox/mvc/tests/test_mvc_ref-set-repeat-simple.html
deleted file mode 100644
index 7034d80..0000000
--- a/dojox/mvc/tests/test_mvc_ref-set-repeat-simple.html
+++ /dev/null
@@ -1,140 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
-
-		<script src="../../../dojo/dojo.js"
-				type="text/javascript"
-				djConfig="parseOnLoad: true, isDebug: true">
-		</script>
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-		<script type="text/javascript" >
-			dojo.require("dojox.mvc");
-			dojo.require("dojox.mvc.Output");
-			dojo.require("dojox.mvc.Group");
-			dojo.require("dojox.mvc.Repeat");
-			dojo.require("dijit.form.TextBox");
-			dojo.require("dijit.form.Button");
-			dojo.require("dojo.store.Memory");
-			dojo.require("dojo.parser");
-
-			var search_results_init1 =
-			[{
-				"Query" : "Engineers1",
-				"Results" : [
-					{
-						"First"	  : "Anne1",
-						"Last"	  : "Ackerman1"
-					},
-					{
-						"First"	  : "Ben1",
-						"Last"	  : "Beckham1"
-					},
-					{
-						"First"	  : "Chad1",
-						"Last"	  : "Chapman1"
-					}
-				]
-			}];
-			var search_results_init2 =
-			[{
-				"Query" : "Engineers2",
-				"Results" : [
-					{
-						"First"	  : "Anne2",
-						"Last"	  : "Ackerman2"
-					},
-					{
-						"First"	  : "Ben2",
-						"Last"	  : "Beckham2"
-					}
-				]
-			}];
-			var search_results_init3 =
-			[{
-				"Query" : "Engineers3",
-				"Results" : [
-					{
-						"First"	  : "",
-						"Last"	  : ""
-					}
-				]
-			}];
-
-			var memStore1 = new dojo.store.Memory({data : search_results_init1});
-			var model1 = dojox.mvc.newStatefulModel({ store : memStore1 })[0];
-			var memStore2 = new dojo.store.Memory({data : search_results_init2});
-			var model2 = dojox.mvc.newStatefulModel({ store : memStore2 })[0];
-			var memStore3 = new dojo.store.Memory({data : search_results_init3});
-			var model3 = dojox.mvc.newStatefulModel({ store : memStore3 })[0];
-		</script>
-	</head>
-	<body class="claro">
-		<div id="wrapper">
-			<div id="header">
-				<div id="navigation"></div>
-				<div id="headerInsert">
-					<h1>Input Ouput Sync</h1>
-					<h2>Data Binding Example</h2>
-				</div>
-			</div>
-			<div id="main">
-				<div id="leftNav"></div>
-				<div id="mainContent">
-					<div class="row">
-						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model1);}">Swap Model1</button>
-						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model2);}">Swap Model2</button>
-						<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){dijit.byId('outergroupId').set('ref',model3);}">Swap Model3</button>
-					</div>
-					<div id="outergroupId"	 data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model1'">
-						<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
-							<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
-								<label class="cell" for="nameInput${this.index}">Name:</label>
-								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
-							</div>
-						</div>
-					</div>
-					<div class="row">
-							<span>
-								Model1 Output is ==>  
-							</span>
-							<span id="firstnameOutput10" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[0].First">
-								Name1 is "${this.value}" : 
-							</span>
-							<span id="firstnameOutput11" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[1].First">
-								Name2 is "${this.value}" : 
-							</span>
-							<span id="firstnameOutput12" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model1.Results[2].First">
-								Name3 is "${this.value}"  
-							</span>
-					</div>
-					<div class="row">
-							<span>
-								Model2 Output is ==>  
-							</span>
-							<span id="firstnameOutput20" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[0].First">
-								Name1 is "${this.value}" : 
-							</span>
-							<span id="firstnameOutput21" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model2.Results[1].First">
-								Name2 is "${this.value}"  
-							</span>
-					</div>
-					<div class="row">
-							<span>
-								Model3 Output is ==>  
-							</span>
-							<span id="firstnameOutput30" data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: model3.Results[0].First">
-								Name1 is "${this.value}"  
-							</span>
-					</div>					
-					<br/>Model:
-					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model1.reset();model2.reset();model3.reset();}">Reset all</button>
-				</div>
-			</div>
-		</div>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/test_mvc_repeat-declarative-sync.html b/dojox/mvc/tests/test_mvc_repeat-declarative-sync.html
deleted file mode 100755
index 61e1818..0000000
--- a/dojox/mvc/tests/test_mvc_repeat-declarative-sync.html
+++ /dev/null
@@ -1,205 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Static Master/Detail Pattern -- Search Results example, declarative with save, commit and reset</title>
-
-		<script src="../../../dojo/dojo.js"
-			type="text/javascript"
-			djConfig="parseOnLoad: true, isDebug: true">
-		</script>
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-		<script type="text/javascript" >
-			dojo.require("dojox.mvc");
-			dojo.require("dojox.mvc.Group");
-			dojo.require("dojox.mvc.Repeat");
-			dojo.require("dijit.form.TextBox");
-			dojo.require("dijit.form.Button");
-			dojo.require("dojo.parser");
-			
-		  // Raw records for the master detail
-		  var search_results_init =
-			{
-				"Results" : [
-					{
-						"First"	  : "Anne",
-						"Last"	  : "Ackerman",
-						"Location": "NY",
-						"Office"  : "1S76",
-						"Email"	  : "a.a at test.com",
-						"Tel"	  : "123-764-8237",
-						"Fax"	  : "123-764-8228"
-					},
-					{
-						"First"	  : "Ben",
-						"Last"	  : "Beckham",
-						"Location": "NY",
-						"Office"  : "5N47",
-						"Email"	  : "b.b at test.com",
-						"Tel"	  : "123-764-8599",
-						"Fax"	  : "123-764-8600"
-					},
-					{
-						"First"	  : "Chad",
-						"Last"	  : "Chapman",
-						"Location": "CA",
-						"Office"  : "1278",
-						"Email"	  : "c.c at test.com",
-						"Tel"	  : "408-764-8237",
-						"Fax"	  : "408-764-8228"
-					},
-					{
-						"First"	  : "David",
-						"Last"	  : "Durham",
-						"Location": "NJ",
-						"Office"  : "C12",
-						"Email"	  : "d.d at test.com",
-						"Tel"	  : "514-764-8237",
-						"Fax"	  : "514-764-8228"
-					},
-					{
-						"First"	  : "Emma",
-						"Last"	  : "Eklof",
-						"Location": "NY",
-						"Office"  : "4N76",
-						"Email"	  : "e.e at test.com",
-						"Tel"	  : "123-764-1234",
-						"Fax"	  : "123-764-4321"
-					},
-					{
-						"First"	  : "Fred",
-						"Last"	  : "Fisher",
-						"Location": "NJ",
-						"Office"  : "V89",
-						"Email"	  : "f.f at test.com",
-						"Tel"	  : "514-764-8567",
-						"Fax"	  : "514-764-8000"
-					},
-					{
-						"First"	  : "George",
-						"Last"	  : "Garnett",
-						"Location": "NY",
-						"Office"  : "7S11",
-						"Email"	  : "gig at test.com",
-						"Tel"	  : "123-999-8599",
-						"Fax"	  : "123-999-8600"
-					},
-					{
-						"First"	  : "Hunter",
-						"Last"	  : "Huffman",
-						"Location": "CA",
-						"Office"  : "6532",
-						"Email"	  : "h.h at test.com",
-						"Tel"	  : "408-874-8237",
-						"Fax"	  : "408-874-8228"
-					},
-					{
-						"First"	  : "Irene",
-						"Last"	  : "Ira",
-						"Location": "NJ",
-						"Office"  : "F09",
-						"Email"	  : "i.i at test.com",
-						"Tel"	  : "514-764-6532",
-						"Fax"	  : "514-764-7300"
-					},
-					{
-						"First"	  : "John",
-						"Last"	  : "Jacklin",
-						"Location": "CA",
-						"Office"  : "6701",
-						"Email"	  : "j.j at test.com",
-						"Tel"	  : "408-764-1234",
-						"Fax"	  : "408-764-4321"
-					}
-				]
-			};
-
-			var selectedIndex = 0;
-		</script>
-	</head>
-	<body class="claro" style="background-image: url(images/master_detail.png)">
-		<div data-dojo-id="results" data-dojo-type="dojox.mvc.StatefulModel" data="search_results_init" ></div>
-		<div id="wrapper">
-			<div id="header">
-				<div id="navigation">
-				</div>
-				<div id="headerInsert">
-				<h2>Master Detail Example - Declarative with repeat container, with save, commit and reset.</h2>
-				</div>
-			</div>
-			<div id="main">
-				<div id="leftNav">
-				</div>
-				<div id="mainContent">
-					<div id="searchBanner">Search Results for term: </div>		   
-					<!--
-						The repeat container denotes a templated UI that operates over a collection
-						of data records.
-						The UI can be customized for each iteration using properties such as
-						${this.index} for the iteration index.
-					-->
-					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results.Results'">
-						<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
-							<label class="cell" for="nameInput${this.index}">Name:</label>
-							<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"></input>
-							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
-						</div>
-					</div>
-					<div class="spacer"></div>
-
-					<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results.Results'">
-						<div id="detailsBanner">Details for selected index:</div>
-
-						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
-							<div class="row">
-								<label class="cell" for="firstInput">First Name:</label>
-								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="lastInput">Last Name:</label>
-								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="locationInput">Location:</label>
-								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="officeInput">Office:</label>
-								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="emailInput">Email:</label>
-								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="telInput">Telephone:</label>
-								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="faxInput">Fax:</label>
-								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
-							</div>
-							<div class="row">
-							<div class="spacer"></div>
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.Results[selectedIndex].toPlainObject());results.Results[selectedIndex].commit();}">Save Item</button>		   
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.Results.toPlainObject());results.Results.commit();;}">Commit All</button>		   
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.Results.reset();}">Reset to last saved</button>		 
-							</div>
-						</div>
-					</div>
-				</div>
-			</div>
-		</div>
-		<script type="text/javascript">
-			// called to change the selected item
-			function setDetailsContext(index) {
-				selectedIndex = index;
-				var widget = dijit.byId("detailsGroup");
-				widget.set("ref", index);
-			};
-		</script>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/test_mvc_repeat-store-declarative-async.html b/dojox/mvc/tests/test_mvc_repeat-store-declarative-async.html
deleted file mode 100755
index 9f250c9..0000000
--- a/dojox/mvc/tests/test_mvc_repeat-store-declarative-async.html
+++ /dev/null
@@ -1,128 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Static Master/Detail Pattern -- Search Results example, using a store with save, commit and reset</title>
-
-		<script src="../../../dojo/dojo.js"
-			type="text/javascript"
-			djConfig="parseOnLoad: false, isDebug: true">
-		</script>
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-		<script type="text/javascript" >
-			dojo.require("dojox.mvc");
-			dojo.require("dojox.mvc.Group");
-			dojo.require("dojox.mvc.Repeat");
-			dojo.require("dijit.form.TextBox");
-			dojo.require("dijit.form.Button");
-			dojo.require("dojo.data.ItemFileWriteStore");
-			dojo.require("dojo.store.DataStore");
-			dojo.require("dojo.parser");
-			
-			var results, selectedIndex = 0;
-
-			function setup() {				
-				var storeNodes = dojo.byId("storeNodes");
-				// this is necessary to parse the declarative stores without parsing the rest of the html with the refs.				
-				dojo.parser.parse(storeNodes);
-				// writeStore and dataStore are created declaratively in the html below.
-				var modelPromise = dojox.mvc.newStatefulModel({store: theDataStore}); 
-				modelPromise.then(function(model){ 
-					results = model;
-					var wrapperNodes = dojo.byId("wrapper");
-					dojo.parser.parse(wrapperNodes); // parse the part of the html with the refs
-				});
-			};
-
-			dojo.addOnLoad(setup);
-		</script>
-	</head>
-	<body class="claro" style="background-image: url(images/master_detail.png)">
-        <div id="storeNodes">
-			<div data-dojo-id="theWriteStore" data-dojo-type="dojo.data.ItemFileWriteStore" data-dojo-props="url: '../../../dojox/mvc/tests/_data/mvcRepeatData.json'"></div>	
-			<div data-dojo-id="theDataStore" data-dojo-type="dojo.store.DataStore" data-dojo-props="store: writeStore"></div>
-        </div>
-		<div id="wrapper">
-			<div id="header">
-				<div id="navigation">
-				</div>
-				<div id="headerInsert">
-				<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
-				</div>
-			</div>
-			<div id="main">
-				<div id="leftNav">
-				</div>
-				<div id="mainContent">
-					<div id="searchBanner">Search Results for term: </div>         
-					<!--
-						The repeat container denotes a templated UI that operates over a collection
-						of data records.
-						The UI can be customized for each iteration using properties such as
-						${this.index} for the iteration index.
-					-->
-					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results'">
-						<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
-							<label class="cell" for="nameInput${this.index}">Name:</label>
-							<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"></input>
-							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
-						</div>
-					</div>
-					<div class="spacer"></div>
-
-					<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results'">
-						<div id="detailsBanner">Details for selected index:</div>
-
-						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
-							<div class="row">
-								<label class="cell" for="firstInput">First Name:</label>
-								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="lastInput">Last Name:</label>
-								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="locationInput">Location:</label>
-								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="officeInput">Office:</label>
-								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="emailInput">Email:</label>
-								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="telInput">Telephone:</label>
-								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="faxInput">Fax:</label>
-								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
-							</div>
-							<div class="row">
-							<div class="spacer"></div>
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results[selectedIndex].toPlainObject());results[selectedIndex].commit();}">Save Item</button>        
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.toPlainObject());results.commit();;}">Commit All</button>        
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.reset();}">Reset to last saved</button>        
-							</div>
-						</div>
-					</div>
-				</div>
-			</div>
-        </div>
-        <script type="text/javascript">
-			// called to change the selected item
-			function setDetailsContext(index) {
-				selectedIndex = index;
-				var widget = dijit.byId("detailsGroup");
-				widget.set("ref", index);
-			};
-        </script>
-    </body>
-</html>
diff --git a/dojox/mvc/tests/test_mvc_repeat_select.html b/dojox/mvc/tests/test_mvc_repeat_select.html
new file mode 100644
index 0000000..e1aeee7
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_repeat_select.html
@@ -0,0 +1,287 @@
+<!DOCTYPE html>
+<html style="width:100%;height:100%;overflow:hidden;">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo Repeat Selection Test</title>
+
+	<style type="text/css">
+		@import "../../../dijit/themes/dijit.css";
+		@import "../../../dijit/themes/claro/document.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<style>
+		.bordercontainer-nopadding .dijitContentPane, .bordercontainer-nopadding .dijitSplitContainer-dijitContentPane, .bordercontainer-nopadding .dijitBorderContainer-dijitContentPane {
+			padding: 0;
+		}
+
+		.bordercontainer-nopadding .dijitMenuBar {
+			border-width: 0 0 1px 0;
+		}
+
+		.view .dijitMenu {
+			border-width: 0;
+		}
+
+		.view .dijitMenuItemHover {
+			background-color: inherit;
+			background-image: none;
+		}
+
+		.view .dijitMenuItemSelected {
+			background-color: #abd6ff;
+			background-image: url("images/standardGradient.png");
+			background-repeat: repeat-x;
+			background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			_background-image: none;
+		}
+
+		.view td.dijitMenuItemLabel {
+			width: 100%;
+			padding: 6px;
+		}
+
+		.view td.dijitMenuItemIconCell {
+			padding: 6px;
+		}
+
+		.row {
+			width: 100%;
+			display: inline-block;
+			padding: 6px;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.cell {
+			width: 100%;
+			display:inline-block;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.complete {
+			text-decoration: line-through;
+		}
+	</style>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js" 
+			data-dojo-config="isDebug: true, async: true, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		var ViewMenuBarData, initialRows;
+		var selectionStatusConverter = {
+			format: function(value){
+				return this.target.uniqueId == (value || {}).uniqueId;
+			},
+			parse: function(value){
+				if(!value){ throw new Error(); } // Stop copying the new value for unchecked case
+				for(var a = this.source.model, i = 0; i < a.length; i++){
+					if(a[i].uniqueId == this.target.uniqueId){
+						return a[i];
+					}
+				}
+			}
+		}, priorityConverter = {
+			format: function(value){
+				return "dijitIcon dijitMenuItemIconCell " + (value <= 1 ? "dijitIconError" : "");
+			}
+		}, completeConverter = {
+			format: function(value){
+				return "dijitMenuItemLabel" + (value ? " complete" : "");
+			}
+		},subjectConverter = {
+			format: function(value){
+				return value || "(No subject)";
+			}
+		};
+
+		require([
+			"dojox",
+			"dojo/_base/declare",
+			"dojo/_base/lang",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/parser",
+			"dojo/Stateful",
+			"dijit/registry",
+			"dijit/Menu",
+			"dojox/mvc/at",
+			"dojox/mvc/getStateful",
+			"dijit/form/CheckBox",
+			"dijit/form/DateTextBox",
+			"dijit/form/Select",
+			"dijit/form/TextBox",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/Editor",
+			"dijit/MenuBar",
+			"dijit/MenuBarItem",
+			"dijit/MenuItem",
+			"dojox/mvc/_atBindingExtension",
+			"dojox/mvc/ListController",
+			"dojox/mvc/StatefulArray",
+			"dojox/mvc/Output",
+			"dojox/mvc/Repeat"
+		], function(dojox, declare, lang, ddom, domClass, parser, Stateful, registry, Menu, at, getStateful){
+
+			var uniqueIdSeq = 3;
+
+			initialRows = getStateful([
+				{
+					uniqueId: 0,
+					Completed: false,
+					Subject: "Pick up my kids",
+					Due: new Date((new Date()).getTime() + 48 * 3600000),
+					Priority: 1,
+					Description: "At the kindergarden"
+				},
+				{
+					uniqueId: 1,
+					Completed: true,
+					Subject: "Take dojox.mvc learning course",
+					Due: new Date((new Date()).getTime() + 72 * 3600000),
+					Priority: 2,
+					Description: "Need to find course material at http://dojotoolkit.org/"
+				},
+				{
+					uniqueId: 2,
+					Completed: false,
+					Subject: "Wash my car",
+					Due: new Date((new Date()).getTime() + 120 * 3600000),
+					Priority: 3,
+					Description: "Need to buy a cleaner before that"
+				}
+			]);
+
+			ViewMenuBarData = getStateful([
+				{
+					label: "New",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						var payload = getStateful({
+							uniqueId: uniqueIdSeq++,
+							Completed: false,
+							Subject: "",
+							Due: new Date(""),
+							Priority: 2,
+							Description: ""
+						});
+						ctl.model.unshift(payload);
+						ctl.set("cursor", payload);
+					}
+				},
+				{
+					label: "Delete",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						if(!confirm("Are you sure you want to delete \"" + ctl.get("cursor").get("Subject") + "\"?")){ return; }
+
+						var idx = ctl.get("cursorIndex");
+						if(idx >= 0){
+							ctl.model.splice(idx, 1);
+						}
+						if(idx < ctl.model.get("length")){
+							ctl.set("cursorIndex", idx);
+						}
+					}
+				}
+			]);
+
+			domClass.add(ddom.byId("loading"), "dijitDisplayNone");
+			domClass.remove(ddom.byId("main"), "dijitDisplayNone");
+			parser.parse();
+		});
+	</script>
+</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;overflow:hidden;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<table id="loading" style="width:100%;height:100%;" border="0" cellpadding="0" cellspacing="0">
+		<tbody>
+			<tr>
+				<td align="center">Loading...</td>
+			</tr>
+		</tbody>
+	</table>
+	<div id="main" class="dijitDisplayNone" style="width:100%;height:100%;">
+		<span id="listCtl" data-dojo-type="dojox.mvc.ListController" data-dojo-props="model: initialRows, cursorIndex: 0"></span>
+		<div class="bordercontainer-nopadding" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: true, style: 'height: 100%; width: 100%;'">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'left', style: 'background-color: white; width: 48ex', splitter: true">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-mixins="dijit.MenuBar" data-dojo-props="children: ViewMenuBarData">
+							<div data-dojo-type="dijit.MenuBarItem" data-dojo-props="'*': at('rel:${index}', '*')"></div>
+						</div>
+					</div>
+					<div class="view" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center'">
+						<table border="0" cellspacing="0" cellpadding="0">
+							<tbody data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at('widget:listCtl', 'model')">
+								<tr>
+									<td class="dijitMenuItemIconCell">
+										<input data-dojo-type="dijit.form.CheckBox"
+										 data-dojo-props="uniqueId: at('rel:${index}', 'uniqueId'),
+										                  checked: at('widget:listCtl', 'cursor').transform(selectionStatusConverter)">
+									</td>
+									<td class="dijitMenuItemIconCell">
+										<img src="../../../dojo/resources/blank.gif" data-dojo-type="dijit._WidgetBase"
+										 data-dojo-props="_setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:${index}', 'Priority').direction(at.from).transform(priorityConverter)">
+									</td>
+									<td data-dojo-type="dijit._WidgetBase"
+									 data-dojo-props="Subject: at('rel:${index}', 'Subject').direction(at.from).transform(subjectConverter),
+									                  _setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:${index}', 'Completed').direction(at.from).transform(completeConverter),
+									                  _setSubjectAttr: {node: 'domNode', type: 'innerText'}">
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</div>
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane"
+			 data-dojo-props="region: 'center', style: 'background-color: white; padding: 6px;', target: at('widget:listCtl', 'cursor')">
+				<div class="row">
+					<span class="cell">
+						<label for="completed">Completed:</label>
+						<input id="completed" data-dojo-type="dijit.form.CheckBox" data-dojo-props="checked: at('rel:', 'Completed')">
+					</span>
+				</div>
+				<div class="row">
+					<label class="cell" for="subject">Subject:</label>
+					<input class="cell" id="subject" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Subject')">
+				</div>
+				<div class="row">
+					<label class="cell" for="priority">Priority:</label>
+					<span class="cell">
+						<select id="priority" data-dojo-type="dijit.form.Select" data-dojo-props="value: at('rel:', 'Priority')">
+							<option value="1">1</option>
+							<option value="2">2</option>
+							<option value="3">3</option>
+						</select>
+					</span>
+				</div>
+				<div class="row">
+					<label class="cell" for="due">Due:</label>
+					<span class="cell">
+						<input id="due" data-dojo-type="dijit.form.DateTextBox"
+						 data-dojo-props="required: false, constraints: {datePattern: 'MMMM dd yyyy'}, value: at('rel:', 'Due')">
+					</span>
+				</div>
+				<div class="row">
+					<span class="cell">Description:</span>
+					<div class="cell" data-dojo-type="dijit.Editor"
+					 data-dojo-props="plugins: ['bold', 'italic', 'underline'], height: '200', value: at('rel:', 'Description')"></div>
+				</div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_repeat_select_cancel.html b/dojox/mvc/tests/test_mvc_repeat_select_cancel.html
new file mode 100644
index 0000000..20c0237
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_repeat_select_cancel.html
@@ -0,0 +1,311 @@
+<!DOCTYPE html>
+<html style="width:100%;height:100%;overflow:hidden;">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo Repeat Selection Test</title>
+
+	<style type="text/css">
+		@import "../../../dijit/themes/dijit.css";
+		@import "../../../dijit/themes/claro/document.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<style>
+		.bordercontainer-nopadding .dijitContentPane, .bordercontainer-nopadding .dijitSplitContainer-dijitContentPane, .bordercontainer-nopadding .dijitBorderContainer-dijitContentPane {
+			padding: 0;
+		}
+
+		.bordercontainer-nopadding .dijitMenuBar {
+			border-width: 0 0 1px 0;
+		}
+
+		.view .dijitMenu {
+			border-width: 0;
+		}
+
+		.view .dijitMenuItemHover {
+			background-color: inherit;
+			background-image: none;
+		}
+
+		.view .dijitMenuItemSelected {
+			background-color: #abd6ff;
+			background-image: url("images/standardGradient.png");
+			background-repeat: repeat-x;
+			background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			_background-image: none;
+		}
+
+		.view td.dijitMenuItemLabel {
+			width: 100%;
+			padding: 6px;
+		}
+
+		.view td.dijitMenuItemIconCell {
+			padding: 6px;
+		}
+
+		.dijitBorderContainerNoGutter > .form {
+			padding: 6px;
+		}
+
+		.row {
+			width: 100%;
+			display: inline-block;
+			padding: 6px;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.cell {
+			width: 100%;
+			display:inline-block;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.complete {
+			text-decoration: line-through;
+		}
+	</style>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		var ViewMenuBarData, DetailMenuBarData, initialRows;
+		var selectionStatusConverter = {
+			format: function(value){
+				return this.target.uniqueId == (value || {}).uniqueId;
+			},
+			parse: function(value){
+				if(!value){ throw new Error(); } // Stop copying the new value for unchecked case
+				for(var a = this.source.inModel, i = 0; i < a.length; i++){
+					if(a[i].uniqueId == this.target.uniqueId){
+						return a[i];
+					}
+				}
+			}
+		}, priorityConverter = {
+			format: function(value){
+				return "dijitIcon dijitMenuItemIconCell " + (value <= 1 ? "dijitIconError" : "");
+			}
+		}, completeConverter = {
+			format: function(value){
+				return "dijitMenuItemLabel" + (value ? " complete" : "");
+			}
+		},subjectConverter = {
+			format: function(value){
+				return value || "(No subject)";
+			}
+		};
+
+		require([
+			"dojox",
+			"dojo/_base/declare",
+			"dojo/_base/lang",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/parser",
+			"dojo/Stateful",
+			"dijit/registry",
+			"dijit/Menu",
+			"dojox/mvc/at",
+			"dojox/mvc/getStateful",
+			"dijit/form/CheckBox",
+			"dijit/form/DateTextBox",
+			"dijit/form/Select",
+			"dijit/form/TextBox",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/Editor",
+			"dijit/MenuBar",
+			"dijit/MenuBarItem",
+			"dijit/MenuItem",
+			"dojox/mvc/_atBindingExtension",
+			"dojox/mvc/EditModelRefController",
+			"dojox/mvc/ListController",
+			"dojox/mvc/StatefulArray",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat"
+		], function(dojox, declare, lang, ddom, domClass, parser, Stateful, registry, Menu, at, getStateful){
+
+			var uniqueIdSeq = 3;
+
+			initialRows = getStateful([
+				{
+					uniqueId: 0,
+					Completed: false,
+					Subject: "Pick up my kids",
+					Due: new Date((new Date()).getTime() + 48 * 3600000),
+					Priority: 1,
+					Description: "At the kindergarden"
+				},
+				{
+					uniqueId: 1,
+					Completed: true,
+					Subject: "Take dojox.mvc learning course",
+					Due: new Date((new Date()).getTime() + 72 * 3600000),
+					Priority: 2,
+					Description: "Need to find course material at http://dojotoolkit.org/"
+				},
+				{
+					uniqueId: 2,
+					Completed: false,
+					Subject: "Wash my car",
+					Due: new Date((new Date()).getTime() + 120 * 3600000),
+					Priority: 3,
+					Description: "Need to buy a cleaner before that"
+				}
+			]);
+
+			ViewMenuBarData = getStateful([
+				{
+					label: "New",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						var payload = getStateful({
+							uniqueId: uniqueIdSeq++,
+							Completed: false,
+							Subject: "",
+							Due: new Date(""),
+							Priority: 2,
+							Description: ""
+						});
+						ctl.inModel.unshift(payload);
+						ctl.set("cursor", payload);
+					}
+				},
+				{
+					label: "Delete",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						if(!confirm("Are you sure you want to delete \"" + ctl.get("Subject") + "\"?")){ return; }
+
+						var idx = ctl.get("cursorIndex");
+						if(idx >= 0){
+							ctl.inModel.splice(idx, 1);
+						}
+						if(idx < ctl.inModel.get("length")){
+							ctl.set("cursorIndex", idx);
+						}
+					}
+				}
+			]);
+
+			DetailMenuBarData = getStateful([
+				{
+					label: "Cancel",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						if(!confirm("Are you sure you want to cancel editing \"" + ctl.get("Subject") + "\"?")){ return; }
+						ctl.reset();
+					}
+				}
+			]);
+
+			domClass.add(ddom.byId("loading"), "dijitDisplayNone");
+			domClass.remove(ddom.byId("main"), "dijitDisplayNone");
+			parser.parse();
+		});
+	</script>
+</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;overflow:hidden;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<table id="loading" style="width:100%;height:100%;" border="0" cellpadding="0" cellspacing="0">
+		<tbody>
+			<tr>
+				<td align="center">Loading...</td>
+			</tr>
+		</tbody>
+	</table>
+	<div id="main" class="dijitDisplayNone" style="width:100%;height:100%;">
+		<span id="listCtl" data-dojo-type="dojox.mvc.ListController" data-dojo-mixins="dojox.mvc.EditModelRefController"
+		 data-dojo-props="_refInModelProp: 'inModel', _refSourceModelProp: 'cursor', _refModelProp: 'model', inModel: initialRows, cursorIndex: 0"></span>
+		<div class="bordercontainer-nopadding" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: true, style: 'height: 100%; width: 100%;'">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'left', style: 'background-color: white; width: 48ex', splitter: true">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-mixins="dijit.MenuBar" data-dojo-props="children: ViewMenuBarData">
+							<div data-dojo-type="dijit.MenuBarItem" data-dojo-props="'*': at('rel:${index}', '*')"></div>
+						</div>
+					</div>
+					<div class="view" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center'">
+						<table border="0" cellspacing="0" cellpadding="0">
+							<tbody data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at('widget:listCtl', 'inModel')">
+								<tr data-dojo-type="dijit._WidgetBase" data-dojo-props="target: at('rel:', '${index}')">
+									<td class="dijitMenuItemIconCell">
+										<input data-dojo-type="dijit.form.CheckBox"
+										 data-dojo-props="uniqueId: at('rel:', 'uniqueId'),
+										                  checked: at('widget:listCtl', 'cursor').transform(selectionStatusConverter)">
+									</td>
+									<td class="dijitMenuItemIconCell">
+										<img src="../../../dojo/resources/blank.gif" data-dojo-type="dijit._WidgetBase"
+										 data-dojo-props="_setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Priority').direction(at.from).transform(priorityConverter)">
+									</td>
+									<td data-dojo-type="dijit._WidgetBase"
+									 data-dojo-props="Subject: at('rel:', 'Subject').direction(at.from).transform(subjectConverter),
+									                  _setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Completed').direction(at.from).transform(completeConverter),
+									                  _setSubjectAttr: {node: 'domNode', type: 'innerText'}">
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</div>
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', style: 'background-color: white;'">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-mixins="dijit.MenuBar" data-dojo-props="children: DetailMenuBarData">
+							<div data-dojo-type="dijit.MenuBarItem" data-dojo-props="'*': at('rel:${index}', '*')"></div>
+						</div>
+					</div>
+					<div class="form" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', target: at('widget:listCtl', 'model')">
+						<div class="row">
+							<span class="cell">
+								<label for="completed">Completed:</label>
+								<input id="completed" data-dojo-type="dijit.form.CheckBox" data-dojo-props="checked: at('rel:', 'Completed')">
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="subject">Subject:</label>
+							<input class="cell" id="subject" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Subject')">
+						</div>
+						<div class="row">
+							<label class="cell" for="priority">Priority:</label>
+							<span class="cell">
+								<select id="priority" data-dojo-type="dijit.form.Select" data-dojo-props="value: at('rel:', 'Priority')">
+									<option value="1">1</option>
+									<option value="2">2</option>
+									<option value="3">3</option>
+								</select>
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="due">Due:</label>
+							<span class="cell">
+								<input id="due" data-dojo-type="dijit.form.DateTextBox"
+								 data-dojo-props="required: false, constraints: {datePattern: 'MMMM dd yyyy'}, value: at('rel:', 'Due')">
+							</span>
+						</div>
+						<div class="row">
+							<span class="cell">Description:</span>
+							<div class="cell" data-dojo-type="dijit.Editor"
+							 data-dojo-props="plugins: ['bold', 'italic', 'underline'], height: '200', value: at('rel:', 'Description')"></div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_repeat_select_manualsave.html b/dojox/mvc/tests/test_mvc_repeat_select_manualsave.html
new file mode 100644
index 0000000..29e2f5a
--- /dev/null
+++ b/dojox/mvc/tests/test_mvc_repeat_select_manualsave.html
@@ -0,0 +1,317 @@
+<!DOCTYPE html>
+<html style="width:100%;height:100%;overflow:hidden;">
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo Repeat Selection Test</title>
+
+	<style type="text/css">
+		@import "../../../dijit/themes/dijit.css";
+		@import "../../../dijit/themes/claro/document.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<style>
+		.bordercontainer-nopadding .dijitContentPane, .bordercontainer-nopadding .dijitSplitContainer-dijitContentPane, .bordercontainer-nopadding .dijitBorderContainer-dijitContentPane {
+			padding: 0;
+		}
+
+		.bordercontainer-nopadding .dijitMenuBar {
+			border-width: 0 0 1px 0;
+		}
+
+		.view .dijitMenu {
+			border-width: 0;
+		}
+
+		.view .dijitMenuItemHover {
+			background-color: inherit;
+			background-image: none;
+		}
+
+		.view .dijitMenuItemSelected {
+			background-color: #abd6ff;
+			background-image: url("images/standardGradient.png");
+			background-repeat: repeat-x;
+			background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -o-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			background-image: -ms-linear-gradient(rgba(255, 255, 255, 0.7) 0%, rgba(255, 255, 255, 0) 100%);
+			_background-image: none;
+		}
+
+		.view td.dijitMenuItemLabel {
+			width: 100%;
+			padding: 6px;
+		}
+
+		.view td.dijitMenuItemIconCell {
+			padding: 6px;
+		}
+
+		.dijitBorderContainerNoGutter > .form {
+			padding: 6px;
+		}
+
+		.row {
+			width: 100%;
+			display: inline-block;
+			padding: 6px;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.cell {
+			width: 100%;
+			display:inline-block;
+			-box-sizing: border-box;
+			-moz-box-sizing: border-box;
+			-webkit-box-sizing: border-box;
+		}
+
+		.complete {
+			text-decoration: line-through;
+		}
+	</style>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true, mvc: {debugBindings: true}"></script>
+
+	<script type="text/javascript">
+		var ViewMenuBarData, DetailMenuBarData, initialRows;
+		var selectionStatusConverter = {
+			format: function(value){
+				return this.target.uniqueId == (value || {}).uniqueId;
+			},
+			parse: function(value){
+				if(!value){ throw new Error(); } // Stop copying the new value for unchecked case
+				for(var a = this.source.inModel, i = 0; i < a.length; i++){
+					if(a[i].uniqueId == this.target.uniqueId){
+						return a[i];
+					}
+				}
+			}
+		}, priorityConverter = {
+			format: function(value){
+				return "dijitIcon dijitMenuItemIconCell " + (value <= 1 ? "dijitIconError" : "");
+			}
+		}, completeConverter = {
+			format: function(value){
+				return "dijitMenuItemLabel" + (value ? " complete" : "");
+			}
+		},subjectConverter = {
+			format: function(value){
+				return value || "(No subject)";
+			}
+		};
+
+		require([
+			"dojox",
+			"dojo/_base/declare",
+			"dojo/_base/lang",
+			"dojo/dom",
+			"dojo/dom-class",
+			"dojo/parser",
+			"dojo/Stateful",
+			"dijit/registry",
+			"dijit/Menu",
+			"dojox/mvc/at",
+			"dojox/mvc/getStateful",
+			"dijit/form/CheckBox",
+			"dijit/form/DateTextBox",
+			"dijit/form/Select",
+			"dijit/form/TextBox",
+			"dijit/layout/BorderContainer",
+			"dijit/layout/ContentPane",
+			"dijit/Editor",
+			"dijit/MenuBar",
+			"dijit/MenuBarItem",
+			"dijit/MenuItem",
+			"dojox/mvc/_atBindingExtension",
+			"dojox/mvc/EditModelRefController",
+			"dojox/mvc/ListController",
+			"dojox/mvc/StatefulArray",
+			"dojox/mvc/Group",
+			"dojox/mvc/Repeat"
+		], function(dojox, declare, lang, ddom, domClass, parser, Stateful, registry, Menu, at, getStateful){
+
+			var uniqueIdSeq = 3;
+
+			initialRows = getStateful([
+				{
+					uniqueId: 0,
+					Completed: false,
+					Subject: "Pick up my kids",
+					Due: new Date((new Date()).getTime() + 48 * 3600000),
+					Priority: 1,
+					Description: "At the kindergarden"
+				},
+				{
+					uniqueId: 1,
+					Completed: true,
+					Subject: "Take dojox.mvc learning course",
+					Due: new Date((new Date()).getTime() + 72 * 3600000),
+					Priority: 2,
+					Description: "Need to find course material at http://dojotoolkit.org/"
+				},
+				{
+					uniqueId: 2,
+					Completed: false,
+					Subject: "Wash my car",
+					Due: new Date((new Date()).getTime() + 120 * 3600000),
+					Priority: 3,
+					Description: "Need to buy a cleaner before that"
+				}
+			]);
+
+			ViewMenuBarData = getStateful([
+				{
+					label: "New",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						var payload = getStateful({
+							uniqueId: uniqueIdSeq++,
+							Completed: false,
+							Subject: "",
+							Due: new Date(""),
+							Priority: 2,
+							Description: ""
+						});
+						ctl.inModel.unshift(payload);
+						ctl.set("cursor", payload);
+					}
+				},
+				{
+					label: "Delete",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						if(!confirm("Are you sure you want to delete \"" + ctl.get("Subject") + "\"?")){ return; }
+
+						var idx = ctl.get("cursorIndex");
+						if(idx >= 0){
+							ctl.inModel.splice(idx, 1);
+						}
+						if(idx < ctl.inModel.get("length")){
+							ctl.set("cursorIndex", idx);
+						}
+					}
+				}
+			]);
+
+			DetailMenuBarData = getStateful([
+				{
+					label: "Save",
+					onClick: function(){
+						registry.byId("listCtl").commit();
+					}
+				},
+				{
+					label: "Cancel",
+					onClick: function(){
+						var ctl = registry.byId("listCtl");
+						if(!confirm("Are you sure you want to cancel editing \"" + ctl.get("Subject") + "\"?")){ return; }
+						ctl.reset();
+					}
+				}
+			]);
+
+			domClass.add(ddom.byId("loading"), "dijitDisplayNone");
+			domClass.remove(ddom.byId("main"), "dijitDisplayNone");
+			parser.parse();
+		});
+	</script>
+</head>
+<body class="claro" style="width:100%;height:100%;margin:0;padding:0;overflow:hidden;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<table id="loading" style="width:100%;height:100%;" border="0" cellpadding="0" cellspacing="0">
+		<tbody>
+			<tr>
+				<td align="center">Loading...</td>
+			</tr>
+		</tbody>
+	</table>
+	<div id="main" class="dijitDisplayNone" style="width:100%;height:100%;">
+		<span id="listCtl" data-dojo-type="dojox.mvc.ListController" data-dojo-mixins="dojox.mvc.EditModelRefController"
+		 data-dojo-props="_refInModelProp: 'inModel', _refSourceModelProp: 'cursor', _refModelProp: 'model', inModel: initialRows, cursorIndex: 0, holdModelUntilCommit: true"></span>
+		<div class="bordercontainer-nopadding" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: true, style: 'height: 100%; width: 100%;'">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'left', style: 'background-color: white; width: 48ex', splitter: true">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-mixins="dijit.MenuBar" data-dojo-props="children: ViewMenuBarData">
+							<div data-dojo-type="dijit.MenuBarItem" data-dojo-props="'*': at('rel:${index}', '*')"></div>
+						</div>
+					</div>
+					<div class="view" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center'">
+						<table border="0" cellspacing="0" cellpadding="0">
+							<tbody data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at('widget:listCtl', 'inModel')">
+								<tr data-dojo-type="dijit._WidgetBase" data-dojo-props="target: at('rel:', '${index}')">
+									<td class="dijitMenuItemIconCell">
+										<input data-dojo-type="dijit.form.CheckBox"
+										 data-dojo-props="uniqueId: at('rel:', 'uniqueId'),
+										                  checked: at('widget:listCtl', 'cursor').transform(selectionStatusConverter)">
+									</td>
+									<td class="dijitMenuItemIconCell">
+										<img src="../../../dojo/resources/blank.gif" data-dojo-type="dijit._WidgetBase"
+										 data-dojo-props="_setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Priority').direction(at.from).transform(priorityConverter)">
+									</td>
+									<td data-dojo-type="dijit._WidgetBase"
+									 data-dojo-props="Subject: at('rel:', 'Subject').direction(at.from).transform(subjectConverter),
+									                  _setDomClassAttr: {node: 'domNode', type: 'class'}, domClass: at('rel:', 'Completed').direction(at.from).transform(completeConverter),
+									                  _setSubjectAttr: {node: 'domNode', type: 'innerText'}">
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</div>
+				</div>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', style: 'background-color: white;'">
+				<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="persist: false, gutters: false">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'top'">
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-mixins="dijit.MenuBar" data-dojo-props="children: DetailMenuBarData">
+							<div data-dojo-type="dijit.MenuBarItem" data-dojo-props="'*': at('rel:${index}', '*')"></div>
+						</div>
+					</div>
+					<div class="form" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region: 'center', target: at('widget:listCtl', 'model')">
+						<div class="row">
+							<span class="cell">
+								<label for="completed">Completed:</label>
+								<input id="completed" data-dojo-type="dijit.form.CheckBox" data-dojo-props="checked: at('rel:', 'Completed')">
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="subject">Subject:</label>
+							<input class="cell" id="subject" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Subject')">
+						</div>
+						<div class="row">
+							<label class="cell" for="priority">Priority:</label>
+							<span class="cell">
+								<select id="priority" data-dojo-type="dijit.form.Select" data-dojo-props="value: at('rel:', 'Priority')">
+									<option value="1">1</option>
+									<option value="2">2</option>
+									<option value="3">3</option>
+								</select>
+							</span>
+						</div>
+						<div class="row">
+							<label class="cell" for="due">Due:</label>
+							<span class="cell">
+								<input id="due" data-dojo-type="dijit.form.DateTextBox"
+								 data-dojo-props="required: false, constraints: {datePattern: 'MMMM dd yyyy'}, value: at('rel:', 'Due')">
+							</span>
+						</div>
+						<div class="row">
+							<span class="cell">Description:</span>
+							<div class="cell" data-dojo-type="dijit.Editor"
+							 data-dojo-props="plugins: ['bold', 'italic', 'underline'], height: '200', value: at('rel:', 'Description')"></div>
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</body>
+</html>
diff --git a/dojox/mvc/tests/test_mvc_search-results-ins-del.html b/dojox/mvc/tests/test_mvc_search-results-ins-del.html
old mode 100755
new mode 100644
index 2b99dd5..6986cec
--- a/dojox/mvc/tests/test_mvc_search-results-ins-del.html
+++ b/dojox/mvc/tests/test_mvc_search-results-ins-del.html
@@ -3,237 +3,268 @@
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Static Master/Detail Pattern -- Search Results example</title>
-
-		<script src="../../../dojo/dojo.js"
-				type="text/javascript"
-				djConfig="parseOnLoad: true, isDebug: true">
+		<script src="../../../dojo/dojo.js" type="text/javascript" 
+				data-dojo-config="parseOnLoad: 0, isDebug: true, mvc: {debugBindings: true}">
 		</script>
 		<style type="text/css">
 			@import "css/app-format.css";
 			@import "../../../dijit/themes/claro/claro.css";
 		</style>
 		<script type="text/javascript">
-		  dojo.require("dojox.mvc");
-		  dojo.require("dojox.mvc.Group");
-		  dojo.require("dojox.mvc.Repeat");
-		  dojo.require("dijit.form.TextBox");
-		  dojo.require("dijit.form.Button");
-		  dojo.require("dojo.parser");
+			var data = [
+				{
+					id: "1",
+					Group: "Engineer",
+					First: "Anne",
+					Last: "Ackerman",
+					Location: "NY",
+					Office: "1S76",
+					Email: "a.a at test.com",
+					Tel: "123-764-8237",
+					Fax: "123-764-8228"
+				},
+				{
+					id: "2",
+					Group: "Engineer",
+					First: "Ben",
+					Last : "Beckham",
+					Location: "NY",
+					Office: "5N47",
+					Email: "b.b at test.com",
+					Tel: "123-764-8599",
+					Fax: "123-764-8600"
+				},
+				{
+					id: "3",
+					Group: "Engineer",
+					First: "Chad",
+					Last: "Chapman",
+					Location: "CA",
+					Office: "1278",
+					Email: "c.c at test.com",
+					Tel: "408-764-8237",
+					Fax: "408-764-8228"
+				},
+				{
+					id: "4",
+					Group: "Engineer",
+					First: "David",
+					Last: "Durham",
+					Location: "NJ",
+					Office: "C12",
+					Email: "d.d at test.com",
+					Tel: "514-764-8237",
+					Fax: "514-764-8228"
+				},
+				{
+					id: "5",
+					Group: "Engineer",
+					First: "Emma",
+					Last: "Eklof",
+					Location: "NY",
+					Office: "4N76",
+					Email: "e.e at test.com",
+					Tel: "123-764-1234",
+					Fax: "123-764-4321"
+				},
+				{
+					id: "6",
+					Group: "Manager",
+					First: "Fred",
+					Last: "Fisher",
+					Location: "NJ",
+					Office: "V89",
+					Email: "f.f at test.com",
+					Tel: "514-764-8567",
+					Fax: "514-764-8000"
+				},
+				{
+					id: "7",
+					Group: "Manager",
+					First: "George",
+					Last: "Garnett",
+					Location: "NY",
+					Office: "7S11",
+					Email: "gig at test.com",
+					Tel: "123-999-8599",
+					Fax: "123-999-8600"
+				},
+				{
+					id: "8",
+					Group: "Accountant",
+					First: "Hunter",
+					Last: "Huffman",
+					Location: "CA",
+					Office: "6532",
+					Email: "h.h at test.com",
+					Tel: "408-874-8237",
+					Fax: "408-874-8228"
+				},
+				{
+					id: "9",
+					Group: "Accountant",
+					First: "Irene",
+					Last: "Ira",
+					Location: "NJ",
+					Office: "F09",
+					Email: "i.i at test.com",
+					Tel: "514-764-6532",
+					Fax: "514-764-7300"
+				},
+				{
+					id: "10",
+					Group: "Accountant",
+					First: "John",
+					Last: "Jacklin",
+					Location: "CA",
+					Office: "6701",
+					Email: "j.j at test.com",
+					Tel: "408-764-1234",
+					Fax: "408-764-4321"
+				}
+			], ctrl;
 
-		  // Initial raw records for the master detail
-		  var search_results_init =
-			{
-				"Query" : "Engineers",
-				"Results" : [
-					{
-						"First"	  : "Anne",
-						"Last"	  : "Ackerman",
-						"Location": "NY",
-						"Office"  : "1S76",
-						"Email"	  : "a.a at test.com",
-						"Tel"	  : "123-764-8237",
-						"Fax"	  : "123-764-8228"
-					},
-					{
-						"First"	  : "Ben",
-						"Last"	  : "Beckham",
-						"Location": "NY",
-						"Office"  : "5N47",
-						"Email"	  : "b.b at test.com",
-						"Tel"	  : "123-764-8599",
-						"Fax"	  : "123-764-8600"
-					},
-					{
-						"First"	  : "Chad",
-						"Last"	  : "Chapman",
-						"Location": "CA",
-						"Office"  : "1278",
-						"Email"	  : "c.c at test.com",
-						"Tel"	  : "408-764-8237",
-						"Fax"	  : "408-764-8228"
-					},
-					{
-						"First"	  : "David",
-						"Last"	  : "Durham",
-						"Location": "NJ",
-						"Office"  : "C12",
-						"Email"	  : "d.d at test.com",
-						"Tel"	  : "514-764-8237",
-						"Fax"	  : "514-764-8228"
-					},
-					{
-						"First"	  : "Emma",
-						"Last"	  : "Eklof",
-						"Location": "NY",
-						"Office"  : "4N76",
-						"Email"	  : "e.e at test.com",
-						"Tel"	  : "123-764-1234",
-						"Fax"	  : "123-764-4321"
-					},
-					{
-						"First"	  : "Fred",
-						"Last"	  : "Fisher",
-						"Location": "NJ",
-						"Office"  : "V89",
-						"Email"	  : "f.f at test.com",
-						"Tel"	  : "514-764-8567",
-						"Fax"	  : "514-764-8000"
-					},
-					{
-						"First"	  : "George",
-						"Last"	  : "Garnett",
-						"Location": "NY",
-						"Office"  : "7S11",
-						"Email"	  : "gig at test.com",
-						"Tel"	  : "123-999-8599",
-						"Fax"	  : "123-999-8600"
-					},
-					{
-						"First"	  : "Hunter",
-						"Last"	  : "Huffman",
-						"Location": "CA",
-						"Office"  : "6532",
-						"Email"	  : "h.h at test.com",
-						"Tel"	  : "408-874-8237",
-						"Fax"	  : "408-874-8228"
+			require([
+				"dojo/_base/declare",
+				"dojo/when",
+				"dojo/parser",
+				"dojo/Stateful",
+				"dojo/store/Memory",
+				"dojox/mvc/EditStoreRefListController",
+				"dijit/form/Button",
+				"dijit/form/TextBox",
+				"dijit/form/ComboBox",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dojox/mvc/Repeat",
+				"dojo/domReady!"
+			], function(declare, when, parser, Stateful, Memory, EditStoreRefListController){
+
+				var inited,
+				 ctrlClass = declare([EditStoreRefListController], {
+					cursorIndex: 0,
+					group: "",
+					groupTyped: "",
+					_refModelProp: "model",
+
+					addEmpty: function(){
+						this.model.push(new Stateful({id:Math.random(), Group: this.groupTyped, First: "", Last: "", Location: "", Office: "", Email: "", Tel: "", Fax: ""}));
+						this.set("cursorIndex", this.get("length") - 1);
 					},
-					{
-						"First"	  : "Irene",
-						"Last"	  : "Ira",
-						"Location": "NJ",
-						"Office"  : "F09",
-						"Email"	  : "i.i at test.com",
-						"Tel"	  : "514-764-6532",
-						"Fax"	  : "514-764-7300"
+
+					remove: function(idx){
+						this.model.splice(idx, 1);
+						if(this.get("cursorIndex") < 0){
+							this.set("cursorIndex", this.get("length") - 1);
+						}
 					},
-					{
-						"First"	  : "John",
-						"Last"	  : "Jacklin",
-						"Location": "CA",
-						"Office"  : "6701",
-						"Email"	  : "j.j at test.com",
-						"Tel"	  : "408-764-1234",
-						"Fax"	  : "408-764-4321"
+
+					_setGroupAttr: function(value){
+						this.set("groupTyped", value);
+						var old = this.group;
+						if(old === value){ return; }
+						when(this.queryStore({Group: value}), function(){
+							if(!inited){
+								parser.parse();
+								inited = true;
+							}
+						});
+						this._set("group", value);
 					}
-				]
-			};
+				});
 
-		   // The dojox.mvc.StatefulModel class creates a data model instance
-		   // where each leaf within the data model is decorated with dojo.Stateful
-		   // properties that widgets can bind to and watch for their changes.
-		   var searchRecords = dojox.mvc.newStatefulModel({ data : search_results_init });
+				ctrl = new ctrlClass({store: new Memory({data: data})});
+				ctrl.set("group", "Engineer");
+			});
 		 </script>
 	</head>
 	<body class="claro" style="background-image: url(images/master_detail.png)">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
 		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>Employee Search</h1>
-			<h2>Master Detail Example - Repeat with insert and delete.</h2>
-		  </div>
-		</div>
-		<div id="main">
-		 <div id="leftNav">
-		 </div>
-		 <div id="mainContent">
-		 <!--
-			 The group container denotes some logical grouping of widgets and also serves
-			 to establish a parent data binding context for its children.
-			 The ref attribute for the outermost container obtains the binding from the
-			 "page scope" itself.
-		 -->
-		 <div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'searchRecords'">
-			<div class="row">
-				<label class="cell" for="queryInput">Search for:</label>
-				<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Query'"/>
-				<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setSearchBanner();}">Search</button>
-			</div>
-			<div class="spacer"></div>
-
-			<div id="searchBanner">Search Results for term: Engineers</div>
-
-			<!--
-				The repeat container denotes a templated UI that operates over a collection
-				of data records.
-				The UI can be customized for each iteration using properties such as
-				${this.index} for the iteration index.
-			-->
-			<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
-				<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
-					<label class="cell" for="nameInput${this.index}">Name:</label>
-					<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
-					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
-					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){insertResult('${this.index}');}">+</button>
-					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){deleteResult('${this.index}');}">-</button>
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Employee Search</h1>
+					<h2>Master Detail Example - Repeat with insert and delete.</h2>
 				</div>
 			</div>
-			<div class="spacer"></div>
-
-			<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Results'">
-				<div id="detailsBanner">Details for result index: 0</div>
-
-				<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
-					<div class="row">
-						<label class="cell" for="firstInput">First Name:</label>
-						<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="lastInput">Last Name:</label>
-						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="locationInput">Location:</label>
-						<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="officeInput">Office:</label>
-						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="emailInput">Email:</label>
-						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="telInput">Telephone:</label>
-						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"/>
-					</div>
-					<div class="row">
-						<label class="cell" for="faxInput">Fax:</label>
-						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"/>
+			<div id="main">
+				<div id="leftNav"></div>
+					<div id="mainContent">
+						<div class="row">
+						<div class="spacer"></div>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.commit(); }">Commit All</button>
+							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset to last saved</button>
+						</div>
+						<div class="spacer"></div>
+						<div>
+							Try "Engineer", "Manager", or "Accountant":
+						</div>
+						<div class="row">
+							<label class="cell" for="queryInput">Search for:</label>
+				<!--		<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at(ctrl, 'groupTyped')"> -->
+							<select id="setvaluetest" data-dojo-type="dijit.form.ComboBox" data-dojo-props="value: at(ctrl, 'groupTyped')">
+								<option value="Engineer">Engineer</option>
+								<option value="Manager">Manager</option>
+								<option value="Accountant">Accountant</option>
+							</select>							
+							<button type="button" data-dojo-type="dijit.form.Button"
+							 data-dojo-props="onClick: function(){ ctrl.set('group', ctrl.get('groupTyped')); }">Search</button>
+						</div>
+						<div class="spacer"></div>
+						<div id="searchBanner">
+							Search Results for group: <span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(ctrl, 'group')"></span>
+						</div>
+						<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="children: at(ctrl, 'model')">
+							<div class="row" data-dojo-type="dijit._WidgetBase" data-dojo-props="target: at('rel:', ${this.index})">
+								<label class="cell" for="nameInput${this.index}">Name:</label>
+								<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}"
+								 data-dojo-props="value: at('rel:', 'First')">
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', ${this.index}); }">Details</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.addEmpty(); }">+</button>
+								<button type="button" data-dojo-type="dijit.form.Button"
+								 data-dojo-props="onClick: function(){ ctrl.remove(${index}); }">-</button>
+							</div>
+						</div>
+						<div class="spacer"></div>
+						<div id="detailsBanner">
+							Details for result index:
+							<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(ctrl, 'cursorIndex')"></span>
+						</div>
+						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'cursor')">
+							<div class="row">
+								<label class="cell" for="firstInput">First Name:</label>
+								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'First')">
+							</div>
+							<div class="row">
+								<label class="cell" for="lastInput">Last Name:</label>
+								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')">
+							</div>
+							<div class="row">
+								<label class="cell" for="locationInput">Location:</label>
+								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Location')">
+							</div>
+							<div class="row">
+								<label class="cell" for="officeInput">Office:</label>
+								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Office')">
+							</div>
+							<div class="row">
+								<label class="cell" for="emailInput">Email:</label>
+								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')">
+							</div>
+							<div class="row">
+								<label class="cell" for="telInput">Telephone:</label>
+								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Tel')">
+							</div>
+							<div class="row">
+								<label class="cell" for="faxInput">Fax:</label>
+								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Fax')">
+							</div>
+						</div>
 					</div>
 				</div>
 			</div>
-		   </div>
-		 </div>
-		</div>
-		<script type="text/javascript">
-			function setDetailsContext(index) {
-				var widget = dijit.byId("detailsGroup");
-				widget.set("ref", index);
-				var detailsBanner = dojo.byId("detailsBanner");
-				detailsBanner.innerHTML = "Details for result index: " + index;
-			}
-			function insertResult(index) {
-				var insert = dojox.mvc.newStatefulModel({ "data" : {
-					"First"	  : "",
-					"Last"	  : "",
-					"Location": "",
-					"Office"  : "",
-					"Email"	  : "",
-					"Tel"	  : "",
-					"Fax"	  : ""
-				} });
-				searchRecords.Results.add(index, insert);
-			}
-			function deleteResult(index) {
-				searchRecords.Results.remove(index);
-			}
-			function setSearchBanner() {
-				var searchBanner = dojo.byId("searchBanner");
-				searchBanner.innerHTML = "Search Results for term: " + searchRecords.Query.get("value");
-			}
-		</script>
 	</body>
 </html>
diff --git a/dojox/mvc/tests/test_mvc_search-results-repeat-store.html b/dojox/mvc/tests/test_mvc_search-results-repeat-store.html
old mode 100755
new mode 100644
index f6191df..e7c5c0f
--- a/dojox/mvc/tests/test_mvc_search-results-repeat-store.html
+++ b/dojox/mvc/tests/test_mvc_search-results-repeat-store.html
@@ -1,116 +1,189 @@
 <!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Static Master/Detail Pattern -- Search Results example, using a store with save, commit and reset</title>
+<html style="width: 100%; height: 100%;">
+<head>
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+<title>Dojo Repeat Selection Test</title>
 
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:0,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
-		<script type="text/javascript">
-		var results, selectedIndex = 0;
- 
-		require([
-			'dojo/_base/kernel',
-			'dojo/parser',
-			'dojox/mvc',
-			'dojo/data/ItemFileWriteStore',
-			'dojo/store/DataStore',
-			'dijit/form/TextBox',
-			'dijit/form/Button',
-			'dojox/mvc/Repeat',
-			'dojox/mvc/Group',
-			'dojox/mvc/Output'
-			], function(kernel, parser, mvc, ItemFileWriteStore, DataStore){
+<style type="text/css">
+ at import "../../../dijit/themes/dijit.css";
+ at import "../../../dijit/themes/claro/document.css";
+ at import "../../../dijit/tests/css/dijitTests.css";
+ at import "css/app-format.css";
+</style>
+
+<!-- required: a default dijit theme: -->
+<link id="themeStyles" rel="stylesheet"
+	href="../../../dijit/themes/claro/claro.css" />
+
+
+<!-- required: dojo.js -->
+<script type="text/javascript" src="../../../dojo/dojo.js"
+	data-dojo-config="isDebug: true, async: true, parseOnLoad: false, mvc: {debugBindings: true}"></script>
+
+<script type="text/javascript">
+var results, savedData;
+	require([
+			"dojo/parser", 
+			"dijit/registry", 
+			"dojox/mvc/at",
+			"dojox/mvc/getStateful", 
+			"dojo/data/ItemFileWriteStore",
+			"dojo/store/DataStore",
+			"dojo/_base/kernel",
+			"dojox/mvc/_atBindingExtension", 
+			"dojox/mvc/ListController", 
+			"dojox/mvc/EditModelRefController", 
+			"dojox/mvc/StatefulArray",
+			"dojox/mvc/Group", 
+			"dojox/mvc/Output", 
+			"dojox/mvc/Repeat",
+			"dijit/form/Button", 
+			"dijit/layout/ContentPane",
+			"dijit/form/TextBox"
+			],
+			function(parser, registry, at, getStateful, ItemFileWriteStore, DataStore, kernel){
 				var writeStore = new ItemFileWriteStore({url: kernel.moduleUrl("dojox.mvc.tests._data", "mvcRepeatData.json")});
-				var modelPromise = mvc.newStatefulModel({store: new DataStore({store: writeStore})}); 
-				modelPromise.then(function(model){ 
-					results = model;
+				var modelPromise = new DataStore({store: writeStore}).query(); 
+				modelPromise.then(function(data){ 
+					savedData = data;
+					results = getStateful(data);
+
 					parser.parse();
 				});
+
+				setDetailsContext = function(index){
+					var ctl=registry.byId("listCtl");
+					ctl.set("cursorIndex", index);
+				};
+
+				saveData = function(){
+					//var ctl=registry.byId("listCtl");
+					var ctl=registry.byId("editCtl");
+					var ind = ctl.sourceModel.get('cursorIndex');
+					var ind2 = ctl.commitCurrent();
+					console.log(results[ind]);
+				};
+
+				saveAllData = function(){
+					var ctl=registry.byId("editCtl");
+					var ind = ctl.commit();
+					console.log(results);
+				};
+
+				resetData = function(){
+					var ctl=registry.byId("editCtl");
+					var ind = ctl.reset();
+					//results[ind].set(savedData[ind]);
+					//results.set(savedData);
+				};
+
 			});
+</script>
+</head>
+<body class="claro"
+	style="width: 100%; height: 100%; margin: 0; padding: 0;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<span id="listCtl" data-dojo-type="dojox.mvc.ListController"
+		data-dojo-props="model: results, cursorIndex: 0"></span>
+	<div id="header">
+		<div id="navigation"></div>
+		<div id="headerInsert">
+			<h1>Employee Search</h1>
+			<h2>Master Detail Example - With repeat container.</h2>
+		</div>
+	</div>
+	<div id="main">
+		<div id="leftNav"></div>
+		<div id="mainContent">
+			<!--
+			 The group container denotes some logical grouping of widgets and also serves
+			 to establish a parent data binding context for its children.
+			 The target attribute for the outermost container obtains the binding from the
+			 "page scope" itself.
+		 	-->
+				<div id="searchBanner">Search Results for term: Engineers</div>
 
-			// called to change the selected item
-			function setDetailsContext(index) {
-				selectedIndex = index;
-				var widget = dijit.byId("detailsGroup");
-				widget.set("ref", index);
-			};
-        </script>
-	</head>
-	<body class="claro" style="background-image: url(images/master_detail.png)">
-		<div id="wrapper">
-			<div id="header">
-				<div id="navigation">
-				</div>
-				<div id="headerInsert">
-				<h2>Master Detail Example - With repeat container, using a store, with save, commit and reset.</h2>
-				</div>
-			</div>
-			<div id="main">
-				<div id="leftNav">
+				<!--
+				The repeat container denotes a templated UI that operates over a collection
+				of data records.
+				The UI can be customized for each iteration using properties such as
+				listCtl cursor or cursorIndex for the iteration.
+				-->
+				<div data-dojo-type="dojox.mvc.Repeat"
+					data-dojo-props="children: results">
+					<div class="row" data-dojo-type="dojox.mvc.Group"
+						data-dojo-props="target: at('rel:${this.index}')">
+						<label class="cell" for="nameInput${this.index}">Name:</label> 
+						<div class="cell" data-dojo-type="dojox.mvc.Output"
+							id="nameInput${this.index}"
+							data-dojo-props="value: at('rel:', 'First')"></div>
+						<button type="button" data-dojo-type="dijit.form.Button"
+							data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+					</div>
 				</div>
-				<div id="mainContent">
-					<div id="searchBanner">Search Results for term: </div>         
-					<!--
-						The repeat container denotes a templated UI that operates over a collection
-						of data records.
-						The UI can be customized for each iteration using properties such as
-						${this.index} for the iteration index.
-					-->
-					<div id="repeatId" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'results'">
-						<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
-							<label class="cell" for="nameInput${this.index}">Name:</label>
-							<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"></input>
-							<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
-						</div>
+				<div class="spacer"></div>
+			<div id="editCtl" data-dojo-type="dijit.layout.ContentPane" data-dojo-mixins="dojox.mvc.EditModelRefController"
+			 data-dojo-props="region: 'center', style: 'background-color: white;', sourceModel: at('widget:listCtl', 'cursor')">
+			<!-- 
+			<div id="editCtl" data-dojo-type="dijit.layout.ContentPane" data-dojo-mixins="dojox.mvc.EditModelRefController"
+			 data-dojo-props="region: 'center', style: 'background-color: white;', sourceModel: at('widget:listCtl', 'cursor')">
+			<div data-dojo-type="dojox.mvc.Group" 
+					data-dojo-props="target: at('widget:listCtl', 'cursor')">
+			 -->			
+					<div class="row">
+						<div style="display: inline-block;" id="detailsBanner">Details for result index:</div>
+						<span class="cell" id="indexOutput"
+							data-dojo-type="dojox.mvc.Output"
+							data-dojo-props="value: at('widget:listCtl', 'cursorIndex')"></span>
+					</div>
+					<div class="row">
+						<label class="cell" for="firstInput">First Name:</label> 
+							<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'First')">
+					</div>
+					<div class="row">
+						<label class="cell" for="lastInput">Last Name:</label> 
+						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Last')">
+					</div>
+					<div class="row">
+						<label class="cell" for="locationInput">Location:</label> 
+						<input class="cell" id="locationInput"
+							data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Location')">
+					</div>
+					<div class="row">
+						<label class="cell" for="officeInput">Office:</label> 
+						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Office')">
 					</div>
+					<div class="row">
+						<label class="cell" for="emailInput">Email:</label> 
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Email')">
+					</div>
+					<div class="row">
+						<label class="cell" for="telInput">Telephone:</label> 
+						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Tel')">
+					</div>
+					<div class="row">
+						<label class="cell" for="faxInput">Fax:</label> 
+						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Fax')">
+					</div>
+					<div class="row">
 					<div class="spacer"></div>
-
-					<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'results'">
-						<div id="detailsBanner">Details for selected index:</div>
-
-						<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
-							<div class="row">
-								<label class="cell" for="firstInput">First Name:</label>
-								<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="lastInput">Last Name:</label>
-								<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="locationInput">Location:</label>
-								<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="officeInput">Office:</label>
-								<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="emailInput">Email:</label>
-								<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="telInput">Telephone:</label>
-								<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"></input>
-							</div>
-							<div class="row">
-								<label class="cell" for="faxInput">Fax:</label>
-								<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"></input>
-							</div>
-							<div class="row">
-							<div class="spacer"></div>
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results[selectedIndex].toPlainObject());results[selectedIndex].commit();}">Save Item</button>        
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){console.log(results.toPlainObject());results.commit();;}">Commit All</button>        
-								<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){results.reset();}">Reset to last saved</button>        
-							</div>
-						</div>
+						<button type="button" data-dojo-type="dijit.form.Button" 
+								data-dojo-props="onClick: function(){saveData();}">Save Item</button>        
+						<button type="button" data-dojo-type="dijit.form.Button" 
+								data-dojo-props="onClick: function(){saveAllData();}">Commit All</button>        
+						<button type="button" data-dojo-type="dijit.form.Button" 
+								data-dojo-props="onClick: function(){resetData();}">Reset to last saved</button>        
 					</div>
+					
 				</div>
 			</div>
-        </div>
-    </body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mvc/tests/test_mvc_search-results-repeat.html b/dojox/mvc/tests/test_mvc_search-results-repeat.html
old mode 100755
new mode 100644
index 6f2dc88..d21abb7
--- a/dojox/mvc/tests/test_mvc_search-results-repeat.html
+++ b/dojox/mvc/tests/test_mvc_search-results-repeat.html
@@ -1,222 +1,236 @@
 <!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Static Master/Detail Pattern -- Search Results example</title>
+<html style="width: 100%; height: 100%;">
+<head>
+<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+<title>Dojo Repeat Selection Test</title>
 
-		<script src="../../../dojo/dojo.js"
-				type="text/javascript"
-				djConfig="parseOnLoad: true, isDebug: true">
-		</script>
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-		<script type="text/javascript" >
-		  dojo.require("dojox.mvc");
-		  dojo.require("dojox.mvc.Group");
-		  dojo.require("dojox.mvc.Repeat");
-		  dojo.require("dijit.form.TextBox");
-		  dojo.require("dijit.form.Button");
-		  dojo.require("dojo.parser");
+<style type="text/css">
+ at import "../../../dijit/themes/dijit.css";
+ at import "../../../dijit/themes/claro/document.css";
+ at import "../../../dijit/tests/css/dijitTests.css";
+ at import "css/app-format.css";
+</style>
 
-		  // Raw records for the master detail
-		  var search_results_init =
-			{
-				"Query" : "Engineers",
-				"Results" : [
-					{
-						"First"	  : "Anne",
-						"Last"	  : "Ackerman",
-						"Location": "NY",
-						"Office"  : "1S76",
-						"Email"	  : "a.a at test.com",
-						"Tel"	  : "123-764-8237",
-						"Fax"	  : "123-764-8228"
-					},
-					{
-						"First"	  : "Ben",
-						"Last"	  : "Beckham",
-						"Location": "NY",
-						"Office"  : "5N47",
-						"Email"	  : "b.b at test.com",
-						"Tel"	  : "123-764-8599",
-						"Fax"	  : "123-764-8600"
-					},
-					{
-						"First"	  : "Chad",
-						"Last"	  : "Chapman",
-						"Location": "CA",
-						"Office"  : "1278",
-						"Email"	  : "c.c at test.com",
-						"Tel"	  : "408-764-8237",
-						"Fax"	  : "408-764-8228"
-					},
-					{
-						"First"	  : "David",
-						"Last"	  : "Durham",
-						"Location": "NJ",
-						"Office"  : "C12",
-						"Email"	  : "d.d at test.com",
-						"Tel"	  : "514-764-8237",
-						"Fax"	  : "514-764-8228"
-					},
-					{
-						"First"	  : "Emma",
-						"Last"	  : "Eklof",
-						"Location": "NY",
-						"Office"  : "4N76",
-						"Email"	  : "e.e at test.com",
-						"Tel"	  : "123-764-1234",
-						"Fax"	  : "123-764-4321"
-					},
-					{
-						"First"	  : "Fred",
-						"Last"	  : "Fisher",
-						"Location": "NJ",
-						"Office"  : "V89",
-						"Email"	  : "f.f at test.com",
-						"Tel"	  : "514-764-8567",
-						"Fax"	  : "514-764-8000"
-					},
-					{
-						"First"	  : "George",
-						"Last"	  : "Garnett",
-						"Location": "NY",
-						"Office"  : "7S11",
-						"Email"	  : "gig at test.com",
-						"Tel"	  : "123-999-8599",
-						"Fax"	  : "123-999-8600"
-					},
-					{
-						"First"	  : "Hunter",
-						"Last"	  : "Huffman",
-						"Location": "CA",
-						"Office"  : "6532",
-						"Email"	  : "h.h at test.com",
-						"Tel"	  : "408-874-8237",
-						"Fax"	  : "408-874-8228"
-					},
-					{
-						"First"	  : "Irene",
-						"Last"	  : "Ira",
-						"Location": "NJ",
-						"Office"  : "F09",
-						"Email"	  : "i.i at test.com",
-						"Tel"	  : "514-764-6532",
-						"Fax"	  : "514-764-7300"
-					},
-					{
-						"First"	  : "John",
-						"Last"	  : "Jacklin",
-						"Location": "CA",
-						"Office"  : "6701",
-						"Email"	  : "j.j at test.com",
-						"Tel"	  : "408-764-1234",
-						"Fax"	  : "408-764-4321"
-					}
-				]
-			};
+<!-- required: a default dijit theme: -->
+<link id="themeStyles" rel="stylesheet"
+	href="../../../dijit/themes/claro/claro.css" />
 
-		   // The dojox.mvc.StatefulModel class creates a data model instance
-		   // where each leaf within the data model is decorated with dojo.Stateful
-		   // properties that widgets can bind to and watch for their changes.
-		   var searchRecords = dojox.mvc.newStatefulModel({ data : search_results_init });
-		 </script>
-	</head>
-	<body class="claro" style="background-image: url(images/master_detail.png)">
-		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
+
+<!-- required: dojo.js -->
+<script type="text/javascript" src="../../../dojo/dojo.js"
+	data-dojo-config="isDebug: true, async: true, mvc: {debugBindings: true}"></script>
+
+<script type="text/javascript">
+	require([
+			"dojo/parser", 
+			"dijit/registry", 
+			"dojox/mvc/getStateful", 
+			"dojox/mvc/_atBindingExtension", 
+			"dojox/mvc/ListController", 
+			"dojox/mvc/StatefulArray",
+			"dojox/mvc/Group", 
+			"dojox/mvc/Output", 
+			"dojox/mvc/Repeat",
+			"dijit/form/Button", 
+			"dijit/form/TextBox"
+			],
+			function(parser, registry, getStateful){
+
+				setDetailsContext=function(index){
+					var ctl=registry.byId("listCtl");
+					ctl.set("cursorIndex", index);
+				};
+
+				searchRecords=getStateful({
+					"Query" : "Engineers",
+					"Results" : [{
+						"First" : "Anne",
+						"Last" : "Ackerman",
+						"Location" : "NY",
+						"Office" : "1S76",
+						"Email" : "a.a at test.com",
+						"Tel" : "123-764-8237",
+						"Fax" : "123-764-8228"
+					}, {
+						"First" : "Ben",
+						"Last" : "Beckham",
+						"Location" : "NY",
+						"Office" : "5N47",
+						"Email" : "b.b at test.com",
+						"Tel" : "123-764-8599",
+						"Fax" : "123-764-8600"
+					}, {
+						"First" : "Chad",
+						"Last" : "Chapman",
+						"Location" : "CA",
+						"Office" : "1278",
+						"Email" : "c.c at test.com",
+						"Tel" : "408-764-8237",
+						"Fax" : "408-764-8228"
+					}, {
+						"First" : "David",
+						"Last" : "Durham",
+						"Location" : "NJ",
+						"Office" : "C12",
+						"Email" : "d.d at test.com",
+						"Tel" : "514-764-8237",
+						"Fax" : "514-764-8228"
+					}, {
+						"First" : "Emma",
+						"Last" : "Eklof",
+						"Location" : "NY",
+						"Office" : "4N76",
+						"Email" : "e.e at test.com",
+						"Tel" : "123-764-1234",
+						"Fax" : "123-764-4321"
+					}, {
+						"First" : "Fred",
+						"Last" : "Fisher",
+						"Location" : "NJ",
+						"Office" : "V89",
+						"Email" : "f.f at test.com",
+						"Tel" : "514-764-8567",
+						"Fax" : "514-764-8000"
+					}, {
+						"First" : "George",
+						"Last" : "Garnett",
+						"Location" : "NY",
+						"Office" : "7S11",
+						"Email" : "gig at test.com",
+						"Tel" : "123-999-8599",
+						"Fax" : "123-999-8600"
+					}, {
+						"First" : "Hunter",
+						"Last" : "Huffman",
+						"Location" : "CA",
+						"Office" : "6532",
+						"Email" : "h.h at test.com",
+						"Tel" : "408-874-8237",
+						"Fax" : "408-874-8228"
+					}, {
+						"First" : "Irene",
+						"Last" : "Ira",
+						"Location" : "NJ",
+						"Office" : "F09",
+						"Email" : "i.i at test.com",
+						"Tel" : "514-764-6532",
+						"Fax" : "514-764-7300"
+					}, {
+						"First" : "John",
+						"Last" : "Jacklin",
+						"Location" : "CA",
+						"Office" : "6701",
+						"Email" : "j.j at test.com",
+						"Tel" : "408-764-1234",
+						"Fax" : "408-764-4321"
+					}]
+				});
+
+				parser.parse();
+			});
+</script>
+</head>
+<body class="claro"
+	style="width: 100%; height: 100%; margin: 0; padding: 0;">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+	<span id="listCtl" data-dojo-type="dojox.mvc.ListController"
+		data-dojo-props="model: searchRecords.Results, cursorIndex: 0"></span>
+	<div id="header">
+		<div id="navigation"></div>
+		<div id="headerInsert">
 			<h1>Employee Search</h1>
 			<h2>Master Detail Example - With repeat container.</h2>
-		  </div>
 		</div>
-		<div id="main">
-		 <div id="leftNav">
-		 </div>
-		 <div id="mainContent">
-		 <!--
+	</div>
+	<div id="main">
+		<div id="leftNav"></div>
+		<div id="mainContent">
+			<!--
 			 The group container denotes some logical grouping of widgets and also serves
 			 to establish a parent data binding context for its children.
-			 The ref attribute for the outermost container obtains the binding from the
+			 The target attribute for the outermost container obtains the binding from the
 			 "page scope" itself.
-		 -->
-		 <div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'searchRecords'">
-			<div class="row">
-				<label class="cell" for="queryInput">Search for:</label>
-				<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Query'"/>
-				<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setSearchBanner();}">Search</button>
-			</div>
-			<div class="spacer"></div>
+		 	-->
+			<div data-dojo-type="dojox.mvc.Group"
+				data-dojo-props="target: searchRecords">
+				<div class="row">
+					<label class="cell" for="queryInput">Search for:</label> 
+					<input class="cell" id="queryInput" data-dojo-type="dijit.form.TextBox"
+						data-dojo-props="value: at('rel:', 'Query')" />
+					<button type="button" data-dojo-type="dijit.form.Button"
+						data-dojo-props="onClick: function(){setSearchBanner();}">Search</button>
+				</div>
+				<div class="spacer"></div>
 
-			<div id="searchBanner">Search Results for term: Engineers</div>
+				<div id="searchBanner">Search Results for term: Engineers</div>
 
-			<!--
+				<!--
 				The repeat container denotes a templated UI that operates over a collection
 				of data records.
 				The UI can be customized for each iteration using properties such as
-				${this.index} for the iteration index.
-			-->
-			<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: 'Results'">
-				<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '${this.index}'">
-					<label class="cell" for="nameInput${this.index}">Name:</label>
-					<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput${this.index}" data-dojo-props="ref: 'First'"/>
-					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+				listCtl cursor or cursorIndex for the iteration.
+				-->
+				<div data-dojo-type="dojox.mvc.Repeat"
+					data-dojo-props="children: at('rel:', 'Results')">
+					<div class="row" data-dojo-type="dojox.mvc.Group"
+						data-dojo-props="target: at('rel:${this.index}')">
+						<label class="cell" for="nameInput${this.index}">Name:</label> 
+						<input class="cell" data-dojo-type="dijit.form.TextBox"
+							id="nameInput${this.index}"
+							data-dojo-props="value: at('rel:', 'First')">
+						<button type="button" data-dojo-type="dijit.form.Button"
+							data-dojo-props="onClick: function(){setDetailsContext('${this.index}');}">Details</button>
+					</div>
 				</div>
-			</div>
-			<div class="spacer"></div>
+				<div class="spacer"></div>
 
-			<div data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Results'">
-				<div id="detailsBanner">Details for result index: 0</div>
-
-				<div id="detailsGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '0'">
+				<div data-dojo-type="dojox.mvc.Group"
+					data-dojo-props="target: at('widget:listCtl', 'cursor')">
+					<div class="row">
+						<div style="display: inline-block;" id="detailsBanner">Details for result index:</div>
+						<span class="cell" id="indexOutput"
+							data-dojo-type="dojox.mvc.Output"
+							data-dojo-props="value: at('widget:listCtl', 'cursorIndex')"></span>
+					</div>
 					<div class="row">
-						<label class="cell" for="firstInput">First Name:</label>
-						<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'First'"/>
+						<label class="cell" for="firstInput">First Name:</label> 
+							<input class="cell" id="firstInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'First')">
 					</div>
 					<div class="row">
-						<label class="cell" for="lastInput">Last Name:</label>
-						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
+						<label class="cell" for="lastInput">Last Name:</label> 
+						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Last')">
 					</div>
 					<div class="row">
-						<label class="cell" for="locationInput">Location:</label>
-						<input class="cell" id="locationInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Location'"/>
+						<label class="cell" for="locationInput">Location:</label> 
+						<input class="cell" id="locationInput"
+							data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Location')">
 					</div>
 					<div class="row">
-						<label class="cell" for="officeInput">Office:</label>
-						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Office'"/>
+						<label class="cell" for="officeInput">Office:</label> 
+						<input class="cell" id="officeInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Office')">
 					</div>
 					<div class="row">
-						<label class="cell" for="emailInput">Email:</label>
-						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
+						<label class="cell" for="emailInput">Email:</label> 
+						<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Email')">
 					</div>
 					<div class="row">
-						<label class="cell" for="telInput">Telephone:</label>
-						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Tel'"/>
+						<label class="cell" for="telInput">Telephone:</label> 
+						<input class="cell" id="telInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Tel')">
 					</div>
 					<div class="row">
-						<label class="cell" for="faxInput">Fax:</label>
-						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Fax'"/>
+						<label class="cell" for="faxInput">Fax:</label> 
+						<input class="cell" id="faxInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Fax')">
 					</div>
 				</div>
 			</div>
-		   </div>
-		 </div>
 		</div>
-		<script type="text/javascript">
-			function setDetailsContext(index) {
-				var widget = dijit.byId("detailsGroup");
-				widget.set("ref", index);
-				var detailsBanner = dojo.byId("detailsBanner");
-				detailsBanner.innerHTML = "Details for result index: " + index;
-			}
-			function setSearchBanner() {
-				var searchBanner = dojo.byId("searchBanner");
-				searchBanner.innerHTML = "Search Results for term: " + searchRecords.Query.get("value");
-			}
-		</script>
-	</body>
+	</div>
+</body>
 </html>
diff --git a/dojox/mvc/tests/test_mvc_shipto-billto-hierarchical.html b/dojox/mvc/tests/test_mvc_shipto-billto-hierarchical.html
old mode 100755
new mode 100644
index e903644..ac80b6e
--- a/dojox/mvc/tests/test_mvc_shipto-billto-hierarchical.html
+++ b/dojox/mvc/tests/test_mvc_shipto-billto-hierarchical.html
@@ -3,196 +3,169 @@
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
-
-		<script src="../../../dojo/dojo.js"
-				type="text/javascript"
-				djConfig="parseOnLoad: true, isDebug: true">
+		<script>
+			require = {
+				parseOnLoad: 0,
+				isDebug: 1,
+				async: 1, 
+				mvc: {debugBindings: 1}
+			};
 		</script>
+		<script src="../../../dojo/dojo.js" type="text/javascript"></script>
 		<style type="text/css">
 			@import "css/app-format.css";
 			@import "../../../dijit/themes/claro/claro.css";
 		</style>
-		<script type="text/javascript" >
-		  dojo.require("dojox.mvc");
-		  dojo.require("dojox.mvc.Group");
-		  dojo.require("dijit.form.TextBox");
-		  dojo.require("dijit.form.Button");
-		  dojo.require("dojo.parser");
-
-		  // Initial data with a noticeable hierarchy
-		  var order = {
-			  "Serial" : "360324",
-			  "First"  : "John",
-			  "Last"   : "Doe",
-			  "Email"  : "jdoe at example.com",
-			  "ShipTo" : {
-				  "Type" : "Home",
-				  "Address" : {
-					  "Street" : "123 Valley Rd",
-					  "City"   : "Katonah",
-					  "State"  : "NY",
-					  "Zip"	   : "10536"
-				  },
-				  "Telephone" : {
-					  "AreaCode" : "123",
-					  "Landline" : {
-						  "Number"	  : "456-7890",
-						  "Extension" : "42"
-					  },
-					  "Cell" : {
-						  "Number"	  : "765-4321"
-					  }
-				  }
-			  },
-			  "BillTo" : {
-				  "Type" : "Office",
-				  "Address" : {
-					  "Street" : "17 Skyline Dr",
-					  "City"   : "Hawthorne",
-					  "State"  : "NY",
-					  "Zip"	   : "10532"
-				  },
-				  "Telephone" : {
-					  "AreaCode" : "098",
-					  "Landline" : {
-						  "Number"	  : "765-4321",
-						  "Extension" : "24"
-					  },
-					  "Cell" : {
-						  "Number"	  : "123-4567"
-					  }
-				  }
-			  }
-		  };
-
-		  // The dojox.mvc.StatefulModel class creates a data model instance
-		  // where each leaf within the data model is decorated with dojo.Stateful
-		  // properties that widgets can bind to and watch for their changes.
-		  var model = dojox.mvc.newStatefulModel({ data : order });
-		  var selectedAddr = dojox.mvc.newStatefulModel({ data : "ShipTo" });
+		<script type="text/javascript">
+			require([
+				"dojo/_base/declare",
+				"dojo/parser",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/EditModelRefController",
+				"dojox/mvc/ListController",
+				"dijit/form/Button",
+				"dijit/form/TextBox",
+				"dojox/mvc/Output",
+				"dojox/mvc/Group"
+			], function(declare, parser, getStateful, EditModelRefController, ListController){
+				var clz = declare([EditModelRefController, ListController], {});
+				ctrl = new clz({
+					sourceModel: getStateful({
+						Serial: "360324",
+						First: "John",
+						Last: "Doe",
+						Email: "jdoe at example.com",
+						ShipTo: {
+							Type: "Home",
+							Address: {
+								Street: "123 Valley Rd",
+								City: "Katonah",
+								State: "NY",
+								Zip: "10536"
+							},
+							Telephone: {
+								AreaCode: "123",
+								Landline: {
+									Number: "456-7890",
+									Extension: "42"
+								},
+								Cell: {
+									Number: "765-4321"
+								}
+							}
+						},
+						BillTo: {
+							Type: "Office",
+							Address: {
+								Street: "17 Skyline Dr",
+								City: "Hawthorne",
+								State: "NY",
+								Zip: "10532"
+							},
+							Telephone: {
+								AreaCode: "098",
+								Landline: {
+									Number: "765-4321",
+									Extension: "24"
+								},
+								Cell: {
+									Number: "123-4567"
+								}
+							}
+						}
+					}),
+					cursorIndex: 'ShipTo'
+				});
+				parser.parse();
+			});
 		</script>
 	</head>
 	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
 		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>Order Shipping Details</h1>
-			<h2>Data Binding Example - Hierarchical data.</h2>
-		  </div>
-		</div>
-		<div id="main">
-		  <div id="leftNav">
-		  </div>
-		  <div id="mainContent">
-		<!--
-			The group container denotes some logical grouping of widgets and also serves
-			to establish a parent data binding context for its children.
-			The ref attribute for the outermost container obtains the binding from the
-			"page scope" itself.
-		-->
-		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model'">
-			<div class="row">
-				<label class="cell" for="serialInput">Order #:</label>
-				<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Serial'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="lastnameInput">Last name:</label>
-				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Last'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="emailInput">Email:</label>
-				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Email'"/>
-			</div>
-		</div>
-		<br/>
-		Choose:
-		<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.ShipTo');}">Ship To</button>
-		<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.BillTo');}">Bill To</button>
-		<br/>
-		<div class="row">
-			<label class="cell" for="addrLabel">Selected Address:</label>
-			<input class="cell" data-dojo-type="dijit.form.TextBox" id="addrLabel"
-								data-dojo-props="ref: 'selectedAddr'"/>
-		</div>
-		<br/>
-		<!--
-			For convenience, the widget hierarchy matches the data hierarchy
-			(see JSON literal above).
-			In this implementation, the child ref attributes are simple property names
-			of the parent binding context.
-			The ref attribute may support more advanced constructs, such as queries
-			over the parent widget's or other application specified binding context.
-		-->
-		  <div id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model.ShipTo'">
-			<div class="row">
-			  <label class="cell" for="typeInput">Type:</label>
-			  <input class="cell" id="typeInput" data-dojo-type="dijit.form.TextBox"
-								  data-dojo-props="ref: 'Type'"/>
-			</div>
-			<div id="postalGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Address'">
-			  <div class="row">
-				  <label class="cell" for="streetInput">Street:</label>
-				  <input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'Street'"/>
-			  </div>
-			  <div class="row">
-				  <label class="cell" for="cityInput">City:</label>
-				  <input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'City'"/>
-			  </div>
-			  <div class="row">
-				  <label class="cell" for="stateInput">State:</label>
-				  <input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'State'"/>
-			  </div>
-			  <div class="row">
-				  <label class="cell" for="zipInput">Zipcode:</label>
-				  <input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'Zip'"/>
-			  </div>
-			</div>
-			<div id="telGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Telephone'">
-			  <div class="row">
-				  <label class="cell" for="areacodeInput">Area code:</label>
-				  <input class="cell" id="areacodeInput" data-dojo-type="dijit.form.TextBox"
-										 data-dojo-props="ref: 'AreaCode'"/>
-			  </div>
-			  <div id="llGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Landline'">
-				<div class="row">
-				  <label class="cell" for="numberInput">Landline Number:</label>
-				  <input class="cell" id="numberInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'Number'"/>
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Order Shipping Details</h1>
+					<h2>Data Binding Example - Hierarchical data.</h2>
 				</div>
-				<div class="row">
-				  <label class="cell" for="extInput">Extension:</label>
-				  <input class="cell" id="extInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'Extension'"/>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'model')">
+						<div class="row">
+							<label class="cell" for="serialInput">Order #:</label>
+							<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Serial')"/>
+						</div>
+						<div class="row">
+							<label class="cell" for="lastnameInput">Last name:</label>
+							<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Last')"/>
+						</div>
+						<div class="row">
+							<label class="cell" for="emailInput">Email:</label>
+							<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Email')"/>
+						</div>
+					</div>
+					<br/>
+					Choose:
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', 'ShipTo'); }">Ship To</button>
+					<button type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.set('cursorIndex', 'BillTo'); }">Bill To</button>
+					<br/>
+					<div class="row">
+						<label class="cell" for="addrLabel">Selected Address:</label>
+						<div class="cell" data-dojo-type="dojox.mvc.Output" id="addrLabel" data-dojo-props="value: at(ctrl, 'cursorIndex')"/></div>
+					</div>
+					<br/>
+					<div id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at(ctrl, 'cursor')">
+						<div class="row">
+							<label class="cell" for="typeInput">Type:</label>
+							<input class="cell" id="typeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Type')"/>
+						</div>
+						<div id="postalGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Address')">
+							<div class="row">
+								<label class="cell" for="streetInput">Street:</label>
+								<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Street')"/>
+							</div>
+							<div class="row">
+								<label class="cell" for="cityInput">City:</label>
+								<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'City')"/>
+							</div>
+							<div class="row">
+								<label class="cell" for="stateInput">State:</label>
+								<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'State')"/>
+							</div>
+							<div class="row">
+								<label class="cell" for="zipInput">Zipcode:</label>
+								<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Zip')"/>
+							</div>
+						</div>
+						<div id="telGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Telephone')">
+							<div class="row">
+								<label class="cell" for="areacodeInput">Area code:</label>
+								<input class="cell" id="areacodeInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'AreaCode')"/>
+							</div>
+							<div id="llGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Landline')">
+								<div class="row">
+									<label class="cell" for="numberInput">Landline Number:</label>
+									<input class="cell" id="numberInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Number')"/>
+								</div>
+								<div class="row">
+									<label class="cell" for="extInput">Extension:</label>
+									<input class="cell" id="extInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Extension')"/>
+								</div>
+							</div>
+							<div class="row" id="cellGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'Cell')">
+								<label class="cell" for="cellInput">Cell Number:</label>
+								<input class="cell" id="cellInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="value: at('rel:', 'Number')"/>
+							</div>
+						</div>
+						<br/>
+						Model:
+						<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){ ctrl.reset(); }">Reset</button>
+					</div>
 				</div>
-			  </div>
-			  <div class="row" id="cellGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'Cell'">
-				  <label class="cell" for="cellInput">Cell Number:</label>
-				  <input class="cell" id="cellInput" data-dojo-type="dijit.form.TextBox"
-									  data-dojo-props="ref: 'Number'"/>
-			  </div>
 			</div>
-			<br/>
-			Model:
-			<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
-		</div></div></div>
-		<script type="text/javascript">
-			function setRef(id, addrRef) {
-				var widget = dijit.byId(id);
-				widget.set("ref", addrRef);
-				if(addrRef == "model.ShipTo")
-					selectedAddr.set("value", "ShipTo");
-				else
-					selectedAddr.set("value", "BillTo");
-			}
-		</script>
+		</div>
 	</body>
 </html>
diff --git a/dojox/mvc/tests/test_mvc_shipto-billto-simple-declarative.html b/dojox/mvc/tests/test_mvc_shipto-billto-simple-declarative.html
deleted file mode 100755
index 723e680..0000000
--- a/dojox/mvc/tests/test_mvc_shipto-billto-simple-declarative.html
+++ /dev/null
@@ -1,132 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Static Master/Detail Pattern -- Declarative Multiple Address Detail example</title>
-
-		<script src="../../../dojo/dojo.js"
-				type="text/javascript"
-				djConfig="parseOnLoad: true, isDebug: true">
-		</script>
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-		<script type="text/javascript" >
-		  dojo.require("dojox.mvc");
-		  dojo.require("dojox.mvc.Group");
-		  dojo.require("dijit.form.TextBox");
-		  dojo.require("dijit.form.Button");
-		  dojo.require("dojo.parser");
-
-		  // Initial data
-		  var order = {
-			  "Serial" : "360324",
-			  "First"  : "John",
-			  "Last"   : "Doe",
-			  "Email"  : "jdoe at example.com",
-			  "ShipTo" : {
-				  "Street" : "123 Valley Rd",
-				  "City"   : "Katonah",
-				  "State"  : "NY",
-				  "Zip"	   : "10536"
-			  },
-			  "BillTo" : {
-				  "Street" : "17 Skyline Dr",
-				  "City"   : "Hawthorne",
-				  "State"  : "NY",
-				  "Zip"	   : "10532"
-			  }
-		  };
-		</script>
-	</head>
-	<body class="claro">
-		<!--
-			The following dojox.mvc.StatefulModel creates a data model instance
-			where each leaf within the data model is decorated with dojo.Stateful
-			properties that widgets can bind to and watch for their changes.
-		-->
-		<div data-dojo-type="dojox.mvc.StatefulModel" data-dojo-props="data: order" data-dojo-id="model"></div>	   
-		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>Order Shipping Details</h1>
-			<h2>Declarative Data Binding Example - Group Container.</h2>
-		  </div>
-		</div>
-		<div id="main">
-		  <div id="leftNav">
-		  </div>
-		  <div id="mainContent">
-		<!--
-			The group container denotes some logical grouping of widgets and also serves
-			to establish a parent data binding context for its children.
-			The ref attribute for the outermost container obtains the binding from the
-			"page scope" itself.
-		-->
-		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'expr:model'">
-			<div class="row">
-				<label class="cell" for="serialInput">Order #:</label>
-				<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Serial'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="lastnameInput">Last:</label>
-				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Last'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="emailInput">Email:</label>
-				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Email'"/>
-			</div>
-		</div>
-		<br/>
-		Choose:
-		<button id="shipto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.ShipTo');}">Ship To</button>
-		<button id="billto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', 'model.BillTo');}">Bill To</button>
-		<br/>
-		<!--
-			For convenience, the widget hierarchy matches the data hierarchy
-			(see JSON literal above).
-			In this implementation, the child ref attributes are simple property names
-			of the parent binding context.
-			The ref attribute may support more advanced constructs, such as queries
-			over the parent widget's or other application specified binding context.
-		-->
-		<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model.ShipTo'">
-			<div class="row">
-				<label class="cell" for="streetInput">Street:</label>
-				<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Street'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="cityInput">City:</label>
-				<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'City'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="stateInput">State:</label>
-				<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'State'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="zipInput">Zipcode:</label>
-				<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox"
-									data-dojo-props="ref: 'Zip'"/>
-			</div>
-		</div>
-		<br/>
-		Model:
-		<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
-		</div></div></div>
-		<script type="text/javascript">
-			function setRef(id, addrRef) {
-				var widget = dijit.byId(id);
-				widget.set("ref", addrRef);
-			}
-		</script>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/test_mvc_shipto-billto-simple-oldparser.html b/dojox/mvc/tests/test_mvc_shipto-billto-simple-oldparser.html
deleted file mode 100755
index d1653d0..0000000
--- a/dojox/mvc/tests/test_mvc_shipto-billto-simple-oldparser.html
+++ /dev/null
@@ -1,131 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
-
-		<script src="../../../dojo/dojo.js"
-				type="text/javascript"
-				djConfig="parseOnLoad: true, isDebug: true">
-		</script>
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-		<script type="text/javascript" >
-		  dojo.require("dojox.mvc");
-		  dojo.require("dojox.mvc.Group");
-		  dojo.require("dijit.form.TextBox");
-		  dojo.require("dijit.form.Button");
-		  dojo.require("dojo.parser");
-
-		  // Initial data
-		  var order = {
-			  "Serial" : "360324",
-			  "First"  : "John",
-			  "Last"   : "Doe",
-			  "Email"  : "jdoe at example.com",
-			  "ShipTo" : {
-				  "Street" : "123 Valley Rd",
-				  "City"   : "Katonah",
-				  "State"  : "NY",
-				  "Zip"	   : "10536"
-			  },
-			  "BillTo" : {
-				  "Street" : "17 Skyline Dr",
-				  "City"   : "Hawthorne",
-				  "State"  : "NY",
-				  "Zip"	   : "10532"
-			  }
-		  };
-
-		  // The dojox.mvc.StatefulModel class creates a data model instance
-		  // where each leaf within the data model is decorated with dojo.Stateful
-		  // properties that widgets can bind to and watch for their changes.
-		  var model = dojox.mvc.newStatefulModel({ data : order });
-		</script>
-	</head>
-	<body class="claro">
-		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>Order Shipping Details</h1>
-			<h2>Data Binding Example - Group Container.</h2>
-		  </div>
-		</div>
-		<div id="main">
-		  <div id="leftNav">
-		  </div>
-		  <div id="mainContent">
-		<!--
-			The group container denotes some logical grouping of widgets and also serves
-			to establish a parent data binding context for its children.
-			The ref value for the outermost container obtains the binding from the
-			"page scope" itself.
-		-->
-		<div class="row" dojoType="dojox.mvc.Group" ref="model">
-			<div class="row">
-				<label class="cell" for="serialInput">Order #:</label>
-				<input class="cell" id="serialInput" dojoType="dijit.form.TextBox"
-									ref="'Serial'"></input>
-			</div>
-			<div class="row">
-				<label class="cell" for="lastnameInput">Last:</label>
-				<input class="cell" id="lastnameInput" dojoType="dijit.form.TextBox"
-									ref="'Last'"></input>
-			</div>
-			<div class="row">
-				<label class="cell" for="emailInput">Email:</label>
-				<input class="cell" id="emailInput" dojoType="dijit.form.TextBox"
-									ref="'Email'"></input>
-			</div>
-		</div>
-		<br/>
-		Choose:
-		<button id="shipto" type="button" dojoType="dijit.form.Button" onclick="setRef('addrGroup', model.ShipTo)">Ship To</button>
-		<button id="billto" type="button" dojoType="dijit.form.Button" onclick="setRef('addrGroup', model.BillTo)">Bill To</button>
-		<br/>
-		<!--
-			For convenience, the widget hierarchy matches the data hierarchy
-			(see JavaScript object literal above).
-			In this implementation, the child ref values are simple property names
-			of the parent binding context.
-			The ref value may support more advanced constructs, such as queries
-			over the parent widget's or other application specified binding context.
-		-->
-		<div class="row" id="addrGroup" dojoType="dojox.mvc.Group" ref="model.ShipTo">
-			<div class="row">
-				<label class="cell" for="streetInput">Street:</label>
-				<input class="cell" id="streetInput" dojoType="dijit.form.TextBox"
-									ref="'Street'"></input>
-			</div>
-			<div class="row">
-				<label class="cell" for="cityInput">City:</label>
-				<input class="cell" id="cityInput" dojoType="dijit.form.TextBox"
-									ref="'City'"></input>
-			</div>
-			<div class="row">
-				<label class="cell" for="stateInput">State:</label>
-				<input class="cell" id="stateInput" dojoType="dijit.form.TextBox"
-									ref="'State'"></input>
-			</div>
-			<div class="row">
-				<label class="cell" for="zipInput">Zipcode:</label>
-				<input class="cell" id="zipInput" dojoType="dijit.form.TextBox"
-									ref="'Zip'"></input>
-			</div>
-		</div>
-		<br/>
-		Model:
-		<button id="reset" type="button" dojoType="dijit.form.Button" onclick="model.reset()">Reset</button>
-		</div></div></div>
-		<script type="text/javascript">
-			function setRef(id, addrRef) {
-				var widget = dijit.byId(id);
-				widget.set("ref", addrRef);
-			}
-		</script>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/test_mvc_shipto-billto-simple.html b/dojox/mvc/tests/test_mvc_shipto-billto-simple.html
deleted file mode 100755
index 23092ab..0000000
--- a/dojox/mvc/tests/test_mvc_shipto-billto-simple.html
+++ /dev/null
@@ -1,130 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
-		<title>Static Master/Detail Pattern -- Multiple Address Detail example</title>
-		<style type="text/css">
-			@import "css/app-format.css";
-			@import "../../../dijit/themes/claro/claro.css";
-		</style>
-		<script type="text/javascript" djConfig="parseOnLoad:1,isDebug:1,async:1" src="../../../dojo/dojo.js"></script>
-		<script type="text/javascript">
-		var model;
- 
-		require([
-			'dojo/parser',
-			'dojo/ready',
-			'dojox/mvc',
-			'dijit/form/TextBox',
-			'dijit/form/Button',
-			'dojox/mvc/Group',
-			'dojox/mvc/Output'
-			], function(parser, ready, mvc){
-
-			// Initial data
-			var order = {
-				"Serial" : "360324",
-				"First" : "John",
-				"Last" : "Doe",
-				"Email" : "jdoe at example.com",
-				"ShipTo" : {
-					"Street" : "123 Valley Rd",
-					"City" : "Katonah",
-					"State" : "NY",
-					"Zip" : "10536"
-				},
-				"BillTo" : {
-					"Street" : "17 Skyline Dr",
-					"City" : "Hawthorne",
-					"State" : "NY",
-					"Zip" : "10532"
-				}
-			};
-				// The dojox.mvc.StatefulModel class creates a data model instance
-				// where each leaf within the data model is decorated with dojo.Stateful
-				// properties that widgets can bind to and watch for their changes.
-				model = mvc.newStatefulModel({ data : order });
-				// the StatefulModel created above is initialized with 
-				// model.First set to "John", model.Last set to "Doe" and model.Email set to "jdoe at example.com"
-
-			});
-
-			// setRef is call when the "Ship To" or "Bill To" button is pressed.
-			function setRef(id, addrRef) {
-				var widget = dijit.byId(id);
-				widget.set("ref", addrRef);
-			}
-		</script>
-		
-		
-	</head>
-	<body class="claro">
-		<div id="wrapper">
-		<div id="header">
-			<div id="navigation">
-			</div>
-			<div id="headerInsert">
-				<h1>Order Shipping Details</h1>
-				<h2>Data Binding Example - Group Container.</h2>
-			</div>
-		</div>
-		<div id="main">
-		<div id="leftNav"></div>
-		<div id="mainContent">
-		<!--
-			The group container denotes some logical grouping of widgets and also serves
-			to establish a parent data binding context for its children.
-			The ref attribute for the outermost container obtains the binding from the
-			"page scope" itself.
-		-->
-		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model'">
-			<div class="row">
-				<label class="cell" for="serialInput">Order #:</label>
-				<input class="cell" id="serialInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Serial'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="lastnameInput">Last:</label>
-				<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Last'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="emailInput">Email:</label>
-				<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Email'"/>
-			</div>
-		</div>
-		<br/>
-		Choose:
-		<button id="shipto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', model.ShipTo);}">Ship To</button>
-		<button id="billto" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){setRef('addrGroup', model.BillTo);}">Bill To</button>
-		<br/>
-		<!--
-			For convenience, the widget hierarchy matches the data hierarchy
-			(see JSON literal above).
-			In this implementation, the child ref attributes are simple property names
-			of the parent binding context.
-			The ref attribute may support more advanced constructs, such as queries
-			over the parent widget's or other application specified binding context.
-		-->
-		<div class="row" id="addrGroup" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'model.ShipTo'">
-			<div class="row">
-				<label class="cell" for="streetInput">Street:</label>
-				<input class="cell" id="streetInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Street'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="cityInput">City:</label>
-				<input class="cell" id="cityInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'City'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="stateInput">State:</label>
-				<input class="cell" id="stateInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'State'"/>
-			</div>
-			<div class="row">
-				<label class="cell" for="zipInput">Zipcode:</label>
-				<input class="cell" id="zipInput" data-dojo-type="dijit.form.TextBox" data-dojo-props="ref: 'Zip'"/>
-			</div>
-		</div>
-		<br/>
-		Model:
-		<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
-		</div></div></div>
-	</body>
-</html>
diff --git a/dojox/mvc/tests/test_mvc_simple-programmatic.html b/dojox/mvc/tests/test_mvc_simple-programmatic.html
old mode 100755
new mode 100644
index 7d325b7..feedb3a
--- a/dojox/mvc/tests/test_mvc_simple-programmatic.html
+++ b/dojox/mvc/tests/test_mvc_simple-programmatic.html
@@ -3,62 +3,67 @@
 	<head>
 		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Simple programmatic data binding - Toggle example</title>
-
-		<script src="../../../dojo/dojo.js"
-				type="text/javascript"
-				djConfig="parseOnLoad: true, isDebug: true">
+		<script>
+			require = {
+				parseOnLoad: 0,
+				isDebug: 1,
+				async: 1
+			};
 		</script>
+		<script src="../../../dojo/dojo.js" type="text/javascript"></script>
 		<style type="text/css">
 			@import "css/app-format.css";
 			@import "../../../dijit/themes/claro/claro.css";
 		</style>
-		<script type="text/javascript" >
-		  dojo.require("dojox.mvc");
-		  dojo.require("dijit.form.TextBox");
-		  dojo.require("dijit.form.Button");
-		  dojo.require("dojo.parser");
+		<script type="text/javascript">
+			require([
+				"dojo/dom",
+				"dojo/parser",
+				"dojo/Stateful",
+				"dojox/mvc/at",
+				"dijit/registry",
+				"dijit/form/TextBox",
+				"dijit/form/Button"
+			], function(ddom, parser, Stateful, at, registry, TextBox){
+				var model = new Stateful({first: "John", last: "Doe"});
+
+				var fn = (new TextBox({id: "fn", value: at(model, 'first')})).placeAt(ddom.byId("mainContent"));
+				fn.startup();
 
-		  // Function below shows programmatic creation of data-bound dijits
-		  function addBoundDijits(){
-			  var model = dojox.mvc.newStatefulModel({ data: { first: "John", last: "Doe" }});
+				var ln = (new TextBox({id: "ln", value: at(model, 'last')})).placeAt(ddom.byId("mainContent"));
+				ln.startup();
 
-			  var fn = new dijit.form.TextBox({id: "fn", ref: model.first});
-			  fn.placeAt(dojo.byId("mainContent"));
-			  fn.startup();
+				var count = 0;
 
-			  var ln = new dijit.form.TextBox({id: "ln", ref: model.last});
-			  ln.placeAt(dojo.byId("mainContent"));
-			  ln.startup();
-		  }
+				// Function below shows programmatic update of data-bound dijit refs
+				toggleRefs = function(){
+					var fn = registry.byId("fn"),
+					 ln = registry.byId("ln"),
+					 state = ++count % 2;
+					fn.set("value", at(model, state == 0 ? 'first' : 'last'));
+					ln.set("value", at(model, state == 0 ? 'last' : 'first'));
+				};
 
-		  // Function below shows programmatic update of data-bound dijit refs
-		  function toggleRefs(){
-			  var fn = dijit.byId("fn"), ln = dijit.byId("ln");
-			  var ref = fn.get("ref");
-			  fn.set("ref", ln.get("ref"));
-			  ln.set("ref", ref);
-		  }
+				parser.parse();
+			});
 
-		  dojo.addOnLoad(addBoundDijits);
 		</script>
 	</head>
 	<body class="claro">
 		<div id="wrapper">
-		<div id="header">
-		  <div id="navigation">
-		  </div>
-		  <div id="headerInsert">
-			<h1>Toggle</h1>
-			<h2>Simple Example - Programmatic data binding.</h2>
-		  </div>
-		</div>
-		<div id="main">
-		  <div id="leftNav">
-		  </div>
-		  <div id="mainContent">
-			<button id="toggle" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: toggleRefs">Toggle Refs</button>
-		  </div>
-		</div>
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Toggle</h1>
+					<h2>Simple Example - Programmatic data binding.</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<button id="toggle" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: toggleRefs">Toggle Refs</button>
+				</div>
+			</div>
 		</div>
 	</body>
 </html>
diff --git a/dojox/mvc/tests/test_new-mvc_input-output-simple.html b/dojox/mvc/tests/test_new-mvc_input-output-simple.html
new file mode 100644
index 0000000..0261d9f
--- /dev/null
+++ b/dojox/mvc/tests/test_new-mvc_input-output-simple.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Simple Input-Output Data Binding Example</title>
+		<style type="text/css">
+			@import "css/app-format.css";
+			@import "../../../dijit/themes/claro/claro.css";
+		</style>
+
+		<script type="text/javascript" data-dojo-config="parseOnLoad:0,isDebug:1,async:1,mvc:{debugBindings:1}" 
+				src="../../../dojo/dojo.js"></script>
+		<script type="text/javascript">
+		var model;
+ 
+		require([
+			'dojo/parser',
+			'dojo/ready',
+			'dojox/mvc',
+			'dijit/form/TextBox',
+			'dijit/form/Button',
+			'dojox/mvc/Group',
+			'dojox/mvc/Output'
+			], function(parser, ready, mvc){
+
+				// The dojox.mvc.StatefulModel class creates a data model instance
+				// where each leaf within the data model is decorated with dojo.Stateful
+				// properties that widgets can bind to and watch for their changes.
+				model = mvc.newStatefulModel({ data : { "First" : "John", "Last" : "Doe", "Email" : "jdoe at example.com" }});
+				// the StatefulModel created above is initialized with 
+				// model.First set to "John", model.Last set to "Doe" and model.Email set to "jdoe at example.com"
+				
+				// when "dojo/ready" is ready call parser.parse
+				ready(function(){
+					parser.parse();
+				});
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="header">
+				<div id="navigation"></div>
+				<div id="headerInsert">
+					<h1>Input Ouput Sync</h1>
+					<h2>Data Binding Example</h2>
+				</div>
+			</div>
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div class="row">
+						<label class="cell" for="firstnameInput">First:</label>
+						<input class="cell" id="firstnameInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at(model.First, 'value')"></input>
+						<!-- Content in output below will always be in sync with value of textbox above -->
+						<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model.First, 'value')">
+						(first name is: ${this.value})
+						</span>
+					</div>
+				<div class="row">
+					<label class="cell" for="lastnameInput">Last:</label>
+					<input class="cell" id="lastnameInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(model.Last, 'value')"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model.Last, 'value')">
+						(last name is: ${this.value})
+					</span>
+				</div>
+				<div class="row">
+					<label class="cell" for="emailInput">Email:</label>
+					<input class="cell" id="emailInput" data-dojo-type="dijit.form.TextBox"
+									data-dojo-props="value: at(model.Email, 'value')"></input>
+					<span data-dojo-type="dojox.mvc.Output" data-dojo-props="value: at(model.Email, 'value')">
+					(email is: ${this.value})
+					</span>
+				</div>
+					<br/>Model:
+					<button id="reset" type="button" data-dojo-type="dijit.form.Button" data-dojo-props="onClick: function(){model.reset();}">Reset</button>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_templatedWidget/readme.txt b/dojox/mvc/tests/test_templatedWidget/README
similarity index 100%
rename from dojox/mvc/tests/test_templatedWidget/readme.txt
rename to dojox/mvc/tests/test_templatedWidget/README
diff --git a/dojox/mvc/tests/test_templatedWidget/myMvcTemplated.js b/dojox/mvc/tests/test_templatedWidget/myMvcTemplated.js
index 3ed5040..8c520d3 100644
--- a/dojox/mvc/tests/test_templatedWidget/myMvcTemplated.js
+++ b/dojox/mvc/tests/test_templatedWidget/myMvcTemplated.js
@@ -1,22 +1,38 @@
-/*
- * This template is used to show how to use exprchar to avoid instance of _TemplatedMixin error in dojo.mvc data binding.
- * If the templateString contains ${xxx}, it will throw an template error, use #{xxx} with exprchar :"#" instead.
- * See how it works in test_mvc_widget.html and test_mvc_widget_template.html
- */
-define(["dojo", "dijit", "dojox", "dijit/_Widget", "dijit/_TemplatedMixin", "dojo/text!./test_mvc_widget_template.html"], 
-		function(dojo, dijit, dojox, Widget, TemplatedMixin, template){
-    return dojo.declare("dojox.mvc.tests.test_templatedWidget.myMvcTemplated", [Widget, TemplatedMixin], {
-    	templateString: template,
-    	widgetsInTemplate: true,
-    	
-        buildRendering: function(){
+define([
+	"dojo/_base/declare",
+	"dijit/_WidgetBase",
+	"dijit/_TemplatedMixin",
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/registry",
+	"dojo/text!./test_mvc_widget_template.html",
+	"dojox/mvc/at",
+	"dijit/form/TextBox",
+	"dojox/mvc/Group",
+	"dojox/mvc/Repeat"
+], function(declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, registry, template, at){
+	return declare("dojox.mvc.tests.test_templatedWidget.myMvcTemplated", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
+		// summary:
+		//		A sample templated widget for dojox.mvc
+		// description:
+		//		This template is used to show how to use exprchar to avoid instance of _TemplatedMixin error in dojo.mvc data binding.
+		//		If the templateString contains ${xxx}, it will throw an template error, use #{xxx} with exprchar :"#" instead.
+		//		See how it works in test_mvc_widget.html and test_mvc_widget_template.html
+
+		// ctrl: dojox.mvc.ModelRefController
+		//		The controller that the form widgets in the template refer to.
+		ctrl: null,
+
+		templateString: template,
+
+		buildRendering: function(){
 			console.log("call myMvcTemplated buildRendering");
+			window.at = at;			
 			this.inherited(arguments);
 		},
-		
-        getParent: function(){
-            console.log("Call myMvcTemplated getParent");
-            return null;
-        }
-    });
+
+		getParent: function(){
+			console.log("Call myMvcTemplated getParent");
+			return null;
+		}
+	});
 });
diff --git a/dojox/mvc/tests/test_templatedWidget/test_mvc_widget.html b/dojox/mvc/tests/test_templatedWidget/test_mvc_widget.html
index 2691854..199d7df 100644
--- a/dojox/mvc/tests/test_templatedWidget/test_mvc_widget.html
+++ b/dojox/mvc/tests/test_templatedWidget/test_mvc_widget.html
@@ -1,78 +1,66 @@
 <!DOCTYPE html>
 <html>
-    <head>
-        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
-        <title>Test template with Repeat using different exprchars.</title>
-        <script src="../../../../dojo/dojo.js" type="text/javascript" djConfig="parseOnLoad: true, isDebug: true">
-        </script>
-        <style type="text/css">
-            @import "../css/app-format.css";
-            @import "../../../../dijit/themes/claro/claro.css";
-        </style>
-        <script type="text/javascript">
-            dojo.require("dojox.mvc");
-            dojo.require("dojox.mvc.Group");
-            dojo.require("dojox.mvc.Repeat");
-            dojo.require("dijit.form.TextBox");
-            dojo.require("dijit.form.Button");
-            dojo.require("dojo.parser");
-            dojo.require("dojox.mvc.tests.test_templatedWidget.myMvcTemplated");
-            
-            // Raw records for the master detail
-            var search_results_init = {
-                "Query": "Engineers",
-                "Results": [{
-                    "First": "Anne",
-                    "Last": "Ackerman",
-                    "Location": "NY",
-                    "Office": "1S76",
-                    "Email": "a.a at test.com",
-                    "Tel": "123-764-8237",
-                    "Fax": "123-764-8228"
-                }, {
-                    "First": "Ben",
-                    "Last": "Beckham",
-                    "Location": "NY",
-                    "Office": "5N47",
-                    "Email": "b.b at test.com",
-                    "Tel": "123-764-8599",
-                    "Fax": "123-764-8600"
-                }, {
-                    "First": "John",
-                    "Last": "Jacklin",
-                    "Location": "CA",
-                    "Office": "6701",
-                    "Email": "j.j at test.com",
-                    "Tel": "408-764-1234",
-                    "Fax": "408-764-4321"
-                }]
-            };
-            
-            // The dojox.mvc.StatefulModel class creates a data model instance
-            // where each leaf within the data model is decorated with dojo.Stateful
-            // properties that widgets can bind to and watch for their changes.
-            var searchRecords = dojox.mvc.newStatefulModel({
-                data: search_results_init
-            });
-            
-            dojo.ready(function(){
-                //dojo.parser.parse(dojo.byId('container'));
-                dojo.parser.parse();
-            });
-        </script>
-    </head>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Test template with Repeat using different exprchars.</title>
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: 1">
+		</script>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript">
+			require([
+				"dojo/parser",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/ModelRefController",
+				"dojox/mvc/tests/test_templatedWidget/myMvcTemplated",
+				"dojo/domReady!"
+			], function(parser, getStateful, ModelRefController, myMvcTemplated){
+				ctrl = new ModelRefController({model: getStateful([
+					{
+						First: "Anne",
+						Last: "Ackerman",
+						Location: "NY",
+						Office: "1S76",
+						Email: "a.a at test.com",
+						Tel: "123-764-8237",
+						Fax: "123-764-8228"
+					}, {
+						First: "Ben",
+						Last: "Beckham",
+						Location: "NY",
+						Office: "5N47",
+						Email: "b.b at test.com",
+						Tel: "123-764-8599",
+						Fax: "123-764-8600"
+					}, {
+						First: "John",
+						Last: "Jacklin",
+						Location: "CA",
+						Office: "6701",
+						Email: "j.j at test.com",
+						Tel: "408-764-1234",
+						Fax: "408-764-4321"
+					}
+				])});
+
+				parser.parse();
+			});
+		</script>
+	</head>
 	<body class="claro" style="background-image: url(../images/master_detail.png)">
 		<div id="wrapper">
 			<div id="main">
 				<div id="leftNav"></div>
 				<div id="mainContent">
 					<div>
-						Test exprchar. Widget template test uses exprchar of # and others for template:#{this.index} etc. 
+						Test exprchar. Widget template test uses exprchar of # and others for template:#{this.index} etc.
 					</div>
 					<br/>
-					<div id="container2"  data-dojo-type="dojox.mvc.tests.test_templatedWidget.myMvcTemplated">    
-					</div>
+					<div id="container2" data-dojo-type="dojox.mvc.tests.test_templatedWidget.myMvcTemplated" data-dojo-props="ctrl: ctrl"></div>
 				</div>
 			</div>
 		</div>
 	</body>
+</html>
diff --git a/dojox/mvc/tests/test_templatedWidget/test_mvc_widget_template.html b/dojox/mvc/tests/test_templatedWidget/test_mvc_widget_template.html
index 13b2244..782c667 100644
--- a/dojox/mvc/tests/test_templatedWidget/test_mvc_widget_template.html
+++ b/dojox/mvc/tests/test_templatedWidget/test_mvc_widget_template.html
@@ -1,39 +1,38 @@
-<div>     
-    <div>This repeat uses exprchar: #</div>              
-	<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="exprchar: '#', ref: 'searchRecords.Results'">
-                        <div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '#{this.index}'">
-                            <label class="cell" for="nameInput#{this.index}">
-                                Name-#:
-                            </label>
-                       <input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput#{this.index}" data-dojo-props="ref: 'First'"/>      
-                        </div>
-    </div>
-    <div>This repeat uses exprchar: a</div>              
-	<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="exprchar: 'a', ref: 'searchRecords.Results'">
-                        <div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'a{this.index}'">
-                            <label class="cell" for="anameInputa{this.index}">
-                                Name-a:
-                            </label>
-                       <input class="cell" data-dojo-type="dijit.form.TextBox" id="anameInputa{this.index}" data-dojo-props="ref: 'First'"/>      
-                        </div>
-    </div>
-    <div>This repeat uses exprchar: b</div>              
-	<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="exprchar: 'b', ref: 'searchRecords.Results'">
-                        <div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: 'b{this.index}'">
-                            <label class="cell" for="bnameInputb{this.index}">
-                                Name-b:
-                            </label>
-                       <input class="cell" data-dojo-type="dijit.form.TextBox" id="bnameInputb{this.index}" data-dojo-props="ref: 'First'"/>      
-                        </div>
-    </div>
-    <div>This repeat uses exprchar: 9</div>              
-	<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="exprchar: '9', ref: 'searchRecords.Results'">
-                        <div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '9{this.index}'">
-                            <label class="cell" for="9nameInput9{this.index}">
-                                Name-9:
-                            </label>
-                       <input class="cell" data-dojo-type="dijit.form.TextBox" id="9nameInput9{this.index}" data-dojo-props="ref: 'First'"/>      
-                        </div>
-    </div>
-    
+<div>
+	<div>This repeat uses exprchar: #</div>
+	<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="exprchar: '#', children: at(require('dijit/registry').byId('${id}').ctrl, 'model')">
+		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', '#{this.index}')">
+			<label class="cell" for="nameInput#{this.index}">
+				Name-#:
+			</label>
+			<input class="cell" data-dojo-type="dijit.form.TextBox" id="nameInput#{this.index}" data-dojo-props="value: at('rel:', 'First')">
+		</div>
+	</div>
+	<div>This repeat uses exprchar: a</div>
+	<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="exprchar: 'a', children: at(require('dijit/registry').byId('${id}').ctrl, 'model')">
+		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'a{this.index}')">
+			<label class="cell" for="anameInputa{this.index}">
+				Name-a:
+			</label>
+			<input class="cell" data-dojo-type="dijit.form.TextBox" id="anameInputa{this.index}" data-dojo-props="value: at('rel:', 'First')">
+		</div>
+	</div>
+	<div>This repeat uses exprchar: b</div>
+	<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="exprchar: 'b', children: at(require('dijit/registry').byId('${id}').ctrl, 'model')">
+		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', 'b{this.index}')">
+			<label class="cell" for="bnameInputb{this.index}">
+				Name-b:
+			</label>
+			<input class="cell" data-dojo-type="dijit.form.TextBox" id="bnameInputb{this.index}" data-dojo-props="value: at('rel:', 'First')">
+		</div>
+	</div>
+	<div>This repeat uses exprchar: 9</div>
+	<div data-dojo-type="dojox.mvc.Repeat" data-dojo-props="exprchar: '9', children: at(require('dijit/registry').byId('${id}').ctrl, 'model')">
+		<div class="row" data-dojo-type="dojox.mvc.Group" data-dojo-props="target: at('rel:', '9{this.index}')">
+			<label class="cell" for="9nameInput9{this.index}">
+				Name-9:
+			</label>
+			<input class="cell" data-dojo-type="dijit.form.TextBox" id="9nameInput9{this.index}" data-dojo-props="value: at('rel:', 'First')">
+		</div>
+	</div>
 </div>
\ No newline at end of file
diff --git a/dojox/mvc/tests/test_templatedWidgetList/README b/dojox/mvc/tests/test_templatedWidgetList/README
new file mode 100644
index 0000000..f100da9
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/README
@@ -0,0 +1,5 @@
+1. This directory in dojox/mvc/test/templatedWidgetList is used to test the WidgetList with a custom widget. 
+2. myMvcTemplated.js widget and test_mvc_widget_template.html shows how to use data-dojo-attach-point in the template and to setup bindings 
+3. Use test_mvc_widget.html to see the results.
+4. myMvcTemplated2.js widget and test_mvc_widget_template2.html shows how to use also use data-dojo-attach-event in the template. 
+5. Use test_mvc_widget2.html to see the results.
diff --git a/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated.js b/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated.js
new file mode 100644
index 0000000..c09486d
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated.js
@@ -0,0 +1,45 @@
+define([
+	"dojo/_base/declare",
+	"dojox/mvc/Templated",
+	"dijit/registry",
+	"dojo/text!./test_mvc_widget_template.html",
+	"dojox/mvc/at",
+	"dijit/form/TextBox",
+	"dojox/mvc/Group",
+	"dojox/mvc/Output",
+	"dojox/mvc/Repeat"
+], function(declare, Templated, registry, template, at){
+	return dojo.declare("dojox.mvc.tests.test_templatedWidgetList.myMvcTemplated", [Templated], {
+		// summary:
+		//		A sample templated widget for dojox.mvc
+		// description:
+		//		This template is used to show how to use exprchar to avoid instance of _TemplatedMixin error in dojo.mvc data binding.
+		//		If the templateString contains ${xxx}, it will throw an template error, use #{xxx} with exprchar :"#" instead.
+		//		See how it works in test_mvc_widget.html and test_mvc_widget_template.html
+
+		// ctrl: dojox.mvc.ModelRefController
+		//		The controller that the form widgets in the template refer to.
+		ctrl: null,
+
+		templateString: template,
+
+		startup: function(){
+			console.log("startup called  in myMvcTemplated!!! ");
+			this.labelNode.set("value", at("rel:", "Serial"));
+			this.inputNode.set("value", at("rel:", "First"));
+//			this.nameInputNode.set("value", at("rel:", "First"));
+			this.inherited("startup", arguments);
+		},
+
+		buildRendering: function(){
+			console.log("call myMvcTemplated buildRendering");
+			window.at = at;			
+			this.inherited(arguments);
+		},
+
+		getParent: function(){
+			console.log("Call myMvcTemplated getParent");
+			return null;
+		}
+	});
+});
diff --git a/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated2.js b/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated2.js
new file mode 100644
index 0000000..a257a11
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated2.js
@@ -0,0 +1,54 @@
+define([
+	"dojo/_base/declare",
+	"dojox/mvc/Templated",
+	"dijit/registry",
+	"dojo/text!./test_mvc_widget_template2.html",
+	"dojox/mvc/at",
+	"dijit/form/TextBox",
+	"dijit/form/Button",
+	"dojox/mvc/Group",
+	"dojox/mvc/Output",
+	"dojox/mvc/Repeat"
+], function(declare, Templated, registry, template, at){
+	return dojo.declare("dojox.mvc.tests.test_templatedWidgetList.myMvcTemplated", [Templated], {
+		// summary:
+		//		A sample templated widget for dojox.mvc
+		// description:
+		//		This template is used to show how to use exprchar to avoid instance of _TemplatedMixin error in dojo.mvc data binding.
+		//		If the templateString contains ${xxx}, it will throw an template error, use #{xxx} with exprchar :"#" instead.
+		//		See how it works in test_mvc_widget.html and test_mvc_widget_template.html
+
+		// ctrl: dojox.mvc.ModelRefController
+		//		The controller that the form widgets in the template refer to.
+		ctrl: null,
+
+		templateString: template,
+
+		startup: function(){
+			console.log("startup called  in myMvcTemplated2!!! ");
+			this.labelNode.set("value", at("rel:", "Serial"));
+			this.inputNode.set("value", at("rel:", "First"));
+//			this.nameInputNode.set("value", at("rel:", "First"));
+			this.inherited("startup", arguments);
+		},
+
+		buildRendering: function(){
+			console.log("call myMvcTemplated2 buildRendering");
+			window.at = at;			
+			this.inherited(arguments);
+		},
+
+		showDetails: function(){
+			// this works, but we can use this.indexAtStartup since it will be set.
+			//var index = this.parent.children.indexOf(this.target);
+			var index = this.indexAtStartup;
+			console.log("Called myMvcTemplated2 showDetails selected index="+index);
+			this.ctrl.set("cursorIndex", index);
+		},
+
+		getParent: function(){
+			console.log("Call myMvcTemplated2 getParent");
+			return null;
+		}
+	});
+});
diff --git a/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated3.js b/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated3.js
new file mode 100644
index 0000000..7fb141b
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated3.js
@@ -0,0 +1,54 @@
+define([
+	"dojo/_base/declare",
+	"dojox/mvc/Templated",
+	"dijit/registry",
+	"dojo/text!./test_mvc_widget_template3.html",
+	"dojox/mvc/at",
+	"dijit/form/TextBox",
+	"dijit/form/Button",
+	"dojox/mvc/Group",
+	"dojox/mvc/Output",
+	"dojox/mvc/Repeat"
+], function(declare, Templated, registry, template, at){
+	return dojo.declare("dojox.mvc.tests.test_templatedWidgetList.myMvcTemplated", [Templated], {
+		// summary:
+		//		A sample templated widget for dojox.mvc
+		// description:
+		//		This template is used to show how to use exprchar to avoid instance of _TemplatedMixin error in dojo.mvc data binding.
+		//		If the templateString contains ${xxx}, it will throw an template error, use #{xxx} with exprchar :"#" instead.
+		//		See how it works in test_mvc_widget.html and test_mvc_widget_template.html
+
+		// ctrl: dojox.mvc.ModelRefController
+		//		The controller that the form widgets in the template refer to.
+		ctrl: null,
+
+		templateString: template,
+
+		startup: function(){
+			console.log("startup called  in myMvcTemplated3!!! ");
+			this.labelNode.set("value", at("rel:", "Serial"));
+			this.inputNode.set("value", at("rel:", "First"));
+//			this.nameInputNode.set("value", at("rel:", "First"));
+			this.inherited("startup", arguments);
+		},
+
+		buildRendering: function(){
+			console.log("call myMvcTemplated3 buildRendering");
+			window.at = at;			
+			this.inherited(arguments);
+		},
+
+		showDetails: function(){
+			// this works, but we can use this.indexAtStartup since it will be set.
+			//var index = this.parent.children.indexOf(this.target);
+			var index = this.indexAtStartup;
+			console.log("Called myMvcTemplated3 showDetails selected index="+index);
+			this.ctrl.set("cursorIndex", index);
+		},
+
+		getParent: function(){
+			console.log("Call myMvcTemplated3 getParent");
+			return null;
+		}
+	});
+});
diff --git a/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated3bDetails.js b/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated3bDetails.js
new file mode 100644
index 0000000..0331b2a
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated3bDetails.js
@@ -0,0 +1,49 @@
+define([
+	"dojo/_base/declare",
+	"dojox/mvc/Templated",
+	"dijit/registry",
+	"dojo/text!./test_mvc_widget_template3bDetails.html",
+	"dojox/mvc/at",
+	"dijit/form/TextBox",
+	"dijit/form/Button",
+	"dojox/mvc/Group",
+	"dojox/mvc/Output",
+	"dojox/mvc/Repeat"
+], function(declare, Templated, registry, template, at){
+	return dojo.declare("dojox.mvc.tests.test_templatedWidgetList.myMvcTemplated3bDetails", [Templated], {
+		// summary:
+		//		A sample templated widget for dojox.mvc
+		// description:
+		//		This template is used to show how to use exprchar to avoid instance of _TemplatedMixin error in dojo.mvc data binding.
+		//		If the templateString contains ${xxx}, it will throw an template error, use #{xxx} with exprchar :"#" instead.
+		//		See how it works in test_mvc_widget.html and test_mvc_widget_template.html
+
+		// ctrl: dojox.mvc.ModelRefController
+		//		The controller that the form widgets in the template refer to.
+		ctrl: null,
+
+		templateString: template,
+
+		startup: function(){
+			console.log("startup called  in myMvcTemplated3bDetails!!! ");
+			this.groupNode.set("target", at(ctrl, 'cursor'));
+			
+			this.serialNode.set("value", at("rel:", "Serial"));
+			this.firstNode.set("value", at("rel:", "First"));
+			this.lastNode.set("value", at("rel:", "Last"));
+//			this.nameInputNode.set("value", at("rel:", "First"));
+			this.inherited("startup", arguments);
+		},
+
+		buildRendering: function(){
+			console.log("call myMvcTemplated3bDetails buildRendering");
+			window.at = at;			
+			this.inherited(arguments);
+		},
+
+		getParent: function(){
+			console.log("Call myMvcTemplated3bDetails getParent");
+			return null;
+		}
+	});
+});
diff --git a/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget.html b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget.html
new file mode 100644
index 0000000..5eaef29
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Test template with Repeat using different exprchars.</title>
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: 1, mvc: {debugBindings: 1}">
+		</script>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript">
+			require([
+				"dojo/parser",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/ModelRefController",
+				"dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated",
+				"dojox/mvc/WidgetList",
+				"dojo/dom",
+				"dojo/domReady!"
+			], function(parser, getStateful, ModelRefController, myMvcTemplated, WidgetList, dom){
+				array = getStateful([
+					{
+						Serial: "A111",
+						First: "Anne",
+						Last: "Ackerman",
+						Location: "NY",
+						Office: "1S76",
+						Email: "a.a at test.com",
+						Tel: "123-764-8237",
+						Fax: "123-764-8228"
+					},
+					{
+						Serial: "B111",
+						First: "Ben",
+						Last: "Beckham",
+						Location: "NY",
+						Office: "5N47",
+						Email: "b.b at test.com",
+						Tel: "123-764-8599",
+						Fax: "123-764-8600"
+					},
+					{
+						Serial: "C111",
+						First: "Chad",
+						Last: "Chapman",
+						Location: "CA",
+						Office: "1278",
+						Email: "c.c at test.com",
+						Tel: "408-764-8237",
+						Fax: "408-764-8228"
+					}
+				]);
+
+				ctrl = new ModelRefController({model: array});
+
+
+				parser.parse();
+
+		//		(new WidgetList({children: array, childClz: myMvcTemplated, childParams: {
+				//	startup: function(){
+					//	this.labelNode.set("value", at("rel:", "Serial"));
+					//	this.inputNode.set("value", at("rel:", "First"));
+					//	this.nameInputNode.set("value", at("rel:", "First"));
+					//	this.inherited("startup", arguments);
+				//	}
+		//		}}, dom.byId("programmaticRepeat"))).startup();
+			
+				(new WidgetList({children: array, childClz: myMvcTemplated}, 
+					dom.byId("programmaticRepeat"))).startup();
+			
+				(new WidgetList({children: ctrl.model, childClz: myMvcTemplated}, 
+					dom.byId("programmaticRepeat2"))).startup();
+				
+			});
+		</script>
+	</head>
+	<body class="claro" style="background-image: url(../images/master_detail.png)">
+		<div id="wrapper">
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div>
+						Test exprchar. Widget template test uses exprchar of # and others for template:#{this.index} etc.
+					</div>
+					<br/>
+			<!--
+					<div id="container2" data-dojo-type="dojox.mvc.tests.test_templatedWidgetList.myMvcTemplated" data-dojo-props="ctrl: ctrl"></div>
+			-->		
+					<h1>First Repeating programmatically created template widget</h1>
+					<div id="programmaticRepeat"></div>
+
+					<h1>Second Repeating programmatically created template widget</h1>
+					<div id="programmaticRepeat2"></div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget2.html b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget2.html
new file mode 100644
index 0000000..dcfc7ad
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget2.html
@@ -0,0 +1,127 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Test template with Repeat using different exprchars.</title>
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: 1, mvc: {debugBindings: 1}">
+		</script>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript">
+			require([
+				"dojo/parser",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/ListController",
+				"dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated2",
+				"dojox/mvc/WidgetList",
+				"dojo/dom",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dijit/form/TextBox",
+				"dojo/domReady!"
+			], function(parser, getStateful, ListController, myMvcTemplated2, WidgetList, dom){
+				array = getStateful([
+					{
+						Serial: "A111",
+						First: "Anne",
+						Last: "Ackerman",
+						Location: "NY",
+						Office: "1S76",
+						Email: "a.a at test.com",
+						Tel: "123-764-8237",
+						Fax: "123-764-8228"
+					},
+					{
+						Serial: "B111",
+						First: "Ben",
+						Last: "Beckham",
+						Location: "NY",
+						Office: "5N47",
+						Email: "b.b at test.com",
+						Tel: "123-764-8599",
+						Fax: "123-764-8600"
+					},
+					{
+						Serial: "C111",
+						First: "Chad",
+						Last: "Chapman",
+						Location: "CA",
+						Office: "1278",
+						Email: "c.c at test.com",
+						Tel: "408-764-8237",
+						Fax: "408-764-8228"
+					}
+				]);
+
+				ctrl = new ListController({model: array});
+
+
+				parser.parse();
+
+		//		(new WidgetList({children: array, childClz: myMvcTemplated2, childParams: {
+				//	startup: function(){
+					//	this.labelNode.set("value", at("rel:", "Serial"));
+					//	this.inputNode.set("value", at("rel:", "First"));
+					//	this.nameInputNode.set("value", at("rel:", "First"));
+					//	this.inherited("startup", arguments);
+				//	}
+		//		}}, dom.byId("programmaticRepeat"))).startup();
+			
+				(new WidgetList({children: array, childClz: myMvcTemplated2, childParams: {
+						ctrl : ctrl
+					}}, 
+					dom.byId("programmaticRepeat"))).startup();
+			
+				(new WidgetList({children: ctrl.model, childClz: myMvcTemplated2, childParams: {
+						ctrl : ctrl
+					}}, 
+					dom.byId("programmaticRepeat2"))).startup();
+				
+			});
+		</script>
+	</head>
+	<body class="claro" style="background-image: url(../images/master_detail.png)">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div>
+						Test exprchar. Widget template test uses exprchar of # and others for template:#{this.index} etc.
+					</div>
+					<br/>
+			<!--
+					<div id="container2" data-dojo-type="dojox.mvc.tests.test_templatedWidgetList.myMvcTemplated2" data-dojo-props="ctrl: ctrl"></div>
+			-->		
+					<h1>First Repeating programmatically created template widget</h1>
+					<div id="programmaticRepeat"></div>
+
+					<h1>Second Repeating programmatically created template widget</h1>
+					<div id="programmaticRepeat2"></div>
+				<div data-dojo-type="dojox/mvc/Group"
+					data-dojo-props="target: at(ctrl, 'cursor')">
+					<div class="row">
+						<div style="display: inline-block;" id="detailsBanner">Details for result index:</div>
+						<span class="cell" id="indexOutput"
+							data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at(ctrl, 'cursorIndex')"></span>
+					</div>
+					<div class="row">
+						<label class="cell" for="firstInputx">First Name:</label> 
+						<input class="cell" id="firstInputx" data-dojo-type="dijit/form/TextBox"
+							data-dojo-props="value: at('rel:', 'First')">
+					</div>
+					<div class="row">
+						<label class="cell" for="lastInput">Last Name:</label> 
+						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-props="value: at('rel:', 'Last')">
+					</div>
+				</div>
+
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget3.html b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget3.html
new file mode 100644
index 0000000..de39bee
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget3.html
@@ -0,0 +1,94 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Test template with Repeat using different exprchars.</title>
+		<script src="../../../../dojo/dojo.js" type="text/javascript" data-dojo-config="parseOnLoad: 0, isDebug: 1, mvc: {debugBindings: 1}">
+		</script>
+		<style type="text/css">
+			@import "../css/app-format.css";
+			@import "../../../../dijit/themes/claro/claro.css";
+		</style>
+		<script type="text/javascript">
+			require([
+				"dojo/parser",
+				"dojox/mvc/getStateful",
+				"dojox/mvc/ListController",
+				"dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated3",
+				"dojox/mvc/tests/test_templatedWidgetList/myMvcTemplated3bDetails",
+				"dojox/mvc/WidgetList",
+				"dojo/dom",
+				"dojox/mvc/Group",
+				"dojox/mvc/Output",
+				"dijit/form/TextBox",
+				"dojo/domReady!"
+			], function(parser, getStateful, ListController, myMvcTemplated3, myMvcTemplated3bDetails, WidgetList, dom){
+				array = getStateful([
+					{
+						Serial: "A111",
+						First: "Anne",
+						Last: "Ackerman",
+						Location: "NY",
+						Office: "1S76",
+						Email: "a.a at test.com",
+						Tel: "123-764-8237",
+						Fax: "123-764-8228"
+					},
+					{
+						Serial: "B111",
+						First: "Ben",
+						Last: "Beckham",
+						Location: "NY",
+						Office: "5N47",
+						Email: "b.b at test.com",
+						Tel: "123-764-8599",
+						Fax: "123-764-8600"
+					},
+					{
+						Serial: "C111",
+						First: "Chad",
+						Last: "Chapman",
+						Location: "CA",
+						Office: "1278",
+						Email: "c.c at test.com",
+						Tel: "408-764-8237",
+						Fax: "408-764-8228"
+					}
+				]);
+
+				ctrl = new ListController({model: array});
+
+
+				parser.parse();
+
+				(new WidgetList({children: ctrl.model, childClz: myMvcTemplated3, childParams: {
+						ctrl : ctrl
+					}}, 
+					dom.byId("programmaticRepeat2"))).startup();
+
+				(new myMvcTemplated3bDetails({ctrl : ctrl}, 
+					dom.byId("programmatic3bDetails"))).startup();				
+			});
+		</script>
+	</head>
+	<body class="claro" style="background-image: url(../images/master_detail.png)">
+	<script type="dojo/require">at: "dojox/mvc/at"</script>
+		<div id="wrapper">
+			<div id="main">
+				<div id="leftNav"></div>
+				<div id="mainContent">
+					<div>
+						Widget template test uses a custom widget for the WidgetList and the details.
+					</div>
+					<br/>
+	
+					<h1>Repeating programmatically created template widget</h1>
+					<div id="programmaticRepeat2"></div>
+
+					<h1>Details for selected item programmatically created template widget</h1>
+					<div id="programmatic3bDetails"></div>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template.html b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template.html
new file mode 100644
index 0000000..844a753
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template.html
@@ -0,0 +1,16 @@
+<div>
+<!-- this also works	
+	<span data-dojo-type="dijit/_WidgetBase"
+			data-dojo-attach-point="labelNode"
+			data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}">
+	</span>: 
+	<span data-dojo-type="dijit/form/TextBox"
+				data-dojo-attach-point="inputNode">
+	</span>
+-->	
+	<span>${indexAtStartup}</span>: 
+	<span data-dojo-type="dojox.mvc.Output" data-dojo-attach-point="labelNode"></span>:
+	<span data-dojo-type="dijit/form/TextBox"
+				data-dojo-attach-point="inputNode">
+	</span>
+</div>
diff --git a/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template2.html b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template2.html
new file mode 100644
index 0000000..4488280
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template2.html
@@ -0,0 +1,19 @@
+<div>
+<!-- this works	
+	<span data-dojo-type="dijit/_WidgetBase"
+			data-dojo-attach-point="labelNode"
+			data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}">
+	</span>: 
+	<span data-dojo-type="dijit/form/TextBox"
+				data-dojo-attach-point="inputNode">
+	</span>
+
+-->	
+	<span>${indexAtStartup}</span>: 
+	<span data-dojo-type="dojox/mvc/Output" data-dojo-attach-point="labelNode"></span>:
+	<span data-dojo-type="dijit/form/TextBox"
+				data-dojo-attach-point="inputNode">
+	</span>
+	<button type="button" data-dojo-type="dijit/form/Button"
+			data-dojo-attach-event="onClick: showDetails">Details</button>
+</div>
diff --git a/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template3.html b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template3.html
new file mode 100644
index 0000000..4488280
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template3.html
@@ -0,0 +1,19 @@
+<div>
+<!-- this works	
+	<span data-dojo-type="dijit/_WidgetBase"
+			data-dojo-attach-point="labelNode"
+			data-dojo-props="_setValueAttr: {node: 'domNode', type: 'innerText'}">
+	</span>: 
+	<span data-dojo-type="dijit/form/TextBox"
+				data-dojo-attach-point="inputNode">
+	</span>
+
+-->	
+	<span>${indexAtStartup}</span>: 
+	<span data-dojo-type="dojox/mvc/Output" data-dojo-attach-point="labelNode"></span>:
+	<span data-dojo-type="dijit/form/TextBox"
+				data-dojo-attach-point="inputNode">
+	</span>
+	<button type="button" data-dojo-type="dijit/form/Button"
+			data-dojo-attach-event="onClick: showDetails">Details</button>
+</div>
diff --git a/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template3bDetails.html b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template3bDetails.html
new file mode 100644
index 0000000..866fd4d
--- /dev/null
+++ b/dojox/mvc/tests/test_templatedWidgetList/test_mvc_widget_template3bDetails.html
@@ -0,0 +1,26 @@
+<div>
+				<div data-dojo-type="dojox/mvc/Group"
+					 data-dojo-attach-point="groupNode">
+					<div class="row">
+						<div style="display: inline-block;" id="detailsBanner">Details for result index:</div>
+						<span class="cell" id="indexOutput"
+							data-dojo-type="dojox/mvc/Output"
+							data-dojo-props="value: at(ctrl, 'cursorIndex')"></span>
+					</div>
+					<div class="row">
+						<label class="cell">Serial:</label> 
+						<div class="cell" data-dojo-type="dojox/mvc/Output"
+							data-dojo-attach-point="serialNode"></div>
+						</div>
+					<div class="row">
+						<label class="cell" for="firstInputx">First Name:</label> 
+						<input class="cell" id="firstInputx" data-dojo-type="dijit/form/TextBox"
+							data-dojo-attach-point="firstNode">
+					</div>
+					<div class="row">
+						<label class="cell" for="lastInput">Last Name:</label> 
+						<input class="cell" id="lastInput" data-dojo-type="dijit.form.TextBox"
+							data-dojo-attach-point="lastNode">
+					</div>
+				</div>
+</div>
diff --git a/dojox/mvc/tests/zips/10024.json b/dojox/mvc/tests/zips/10024.json
old mode 100755
new mode 100644
index 6952bf4..e580e26
--- a/dojox/mvc/tests/zips/10024.json
+++ b/dojox/mvc/tests/zips/10024.json
@@ -9,4 +9,4 @@
 	 "lat":40.987797,
 	 "adminName1":"New York"
 	}
-]}
\ No newline at end of file
+]}
diff --git a/dojox/mvc/tests/zips/10706.json b/dojox/mvc/tests/zips/10706.json
old mode 100755
new mode 100644
index 4c242dc..68e061a
--- a/dojox/mvc/tests/zips/10706.json
+++ b/dojox/mvc/tests/zips/10706.json
@@ -9,4 +9,4 @@
 	 "lat":40.987797,
 	 "adminName1":"New York"
 	}
-]}
\ No newline at end of file
+]}
diff --git a/dojox/package.json b/dojox/package.json
index 7a3642f..a906359 100644
--- a/dojox/package.json
+++ b/dojox/package.json
@@ -1,10 +1,14 @@
 {
 	"name": "dojox",
-	"version":"1.7.2",
+	"version":"1.9.1",
 	"directories": {
 		"lib": "."
 	},
 	"main": "main",
+	"dependencies": {
+		"dojo":"1.9.1",
+		"dijit":"1.9.1"
+	},
 	"description": "Dojo eXtensions, a rollup of many useful sub-projects and varying states of maturity – from very stable and robust, to alpha and experimental. See individual projects contain README files for details.",
 	"licenses": [
 		 {
diff --git a/dojox/rails/tests/test_rails.html b/dojox/rails/tests/test_rails.html
index c998efd..f972620 100644
--- a/dojox/rails/tests/test_rails.html
+++ b/dojox/rails/tests/test_rails.html
@@ -36,12 +36,12 @@
 		}
 	</style>
 	
-	<script src='../../../dojo/dojo.js' djConfig='isDebug:true, parseOnLoad:true'></script>
+	<script src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad:true"></script>
 	<script type="text/javascript">
     // dojo.registerModulePath('dojox.rails.tests.plugd', '../dojox/rails/tests/plugd'); 
 		dojo.require('doh.runner');
 		dojo.require('dojox.rails');
-    dojo.require('dojox.rails.tests.plugd.trigger');
+    	dojo.require('dojox.rails.tests.plugd.trigger');
 		dojo.require('dojo.NodeList-manipulate');
 
     var subscriptions = [];
diff --git a/dojox/resources/_modules.js b/dojox/resources/_modules.js
deleted file mode 100644
index 9b8bfa6..0000000
--- a/dojox/resources/_modules.js
+++ /dev/null
@@ -1,252 +0,0 @@
-/*=====
-// this file is in place as a quick way to give summaries to all available dojox projects.
-
-dojox = {
-	// summary:
-	//	DojoX: the home for Dojo eXtensions
-	//
-	// description:
-	//	DojoX is a collection of subprojects provided by Dojo committers and subject to
-	//	the generous licensing and policies of the [Dojo CLA](http://dojotoolkit.org/cla)
-	//	Each subproject in DojoX has its own top-level directory and a README file with
-	//	status information and project status and a stability rating (experimental, beta, stable)
-	//
-	//	Projects may or may not depend on other top-level Dojo projects, like Dojo or Dijit.
-	//	Unlike Dojo and Dijit, code is not subject to i18n and a11y restrictions and may vary
-	//	in quality (experimental code is encouraged in DojoX, but currently prohibited in Dojo
-	//	and Dijit)
-	//
-	//	DojoX projects may mature to a stable state and stay in DojoX, or on occasion
-	//	after proving themselves may migrate to Dojo Core or Dijit.  Dojo and Dijit projects
-	//	are constrained both by development resources as well as design goals, so DojoX is
-	//	a natural place to provide enhanced behavior or extend Dojo Core or Dijit primitives.
-	//	DojoX can also be an incubator for entirely new projects.
-}
-
-dojox.analytics = {
-	// summary: Website analytics and client monitoring system
-};
-
-dojox.atom = {
-	// summary: Implements the Atom Syndication Format and Atom Publishing Protocol
-};
-
-dojox.av = {
-	// summary: Provides Audio/Video capabilities
-};
-
-dojox.charting = {
-	// summary: Vector graphic, data-driven graphs and charts
-};
-
-dojox.collections = {
-	// summary: A set of lists and hashes for easy use within your applications.
-};
-
-dojox.color = {
-	// summary: Advanced color methods, including HSV, HSL, and CMYK conversion, a color generator and advanced colorspace calculations.
-};
-
-dojox.cometd = {
-	// summary: A cometd client written in Dojo
-};
-
-dojox.data = {
-	// summary: Additional dojo.data data stores and demos
-};
-
-dojox.date = {
-	// summary: Additional date manipulation functions
-};
-
-dojox.drawing = {
-	// summary: A vector drawing program
-};
-
-dojox.dtl = {
-	// summary: Django Templating Language implementation
-};
-
-dojox.editor = {
-	// summary: Extensions for dijit.Editor
-};
-
-dojox.embed = {
-	// summary: Base code for embedding for external objects like Flash, Quicktime
-};
-
-dojox.encoding = {
-	// summary: Various encoding algorithms, including crypto and digests.
-};
-
-dojox.flash = {
-	// summary: Utilities to embed and communicate with Flash-based objects
-};
-
-dojox.form = {
-	// summary: Form-related widgets
-};
-
-dojox.fx = {
-	// summary: Extension animations to the core dojo FX project
-	//
-	// description:
-	//	A package of animations, and FX-related code, extending Dojo Core fx.
-	//	Including this package includes all the Base and Core fx packages.
-	//
-	
-	style: { // summary: Module to provide CSS animations
-	},
-
-	scroll: { // summary: Module to provide scroll-related FX
-	}
-};
-dojox.fx["ext-dojo"] = {
-	// summary: Direct extensions to dojo.fx namespace
-	NodeList: {
-		// summary: module to include to support dojox.fx animations in dojo.query()
-	}
-};
-
-dojox.gfx = {
-	// summary: Cross-browser vector graphics API
-	// description:
-	//
-	//	dojox.gfx is an advanced API providing normalized vector drawing
-	//	in a variety of browsers. It has individual renderers for SVG, VML,
-	//	Canvas, and Silverlight.
-};
-
-dojox.gfx3d = {
-	// summary: A 3d API for dojox.gfx
-};
-
-dojox.grid = {
-	// summary: An advanced Grid widget with virtual scrolling, cell editing, and much more
-};
-
-dojox.help = {
-	// summary: TODOC
-};
-
-dojox.highlight = {
-	// summary: A client-side syntax highlighting engine.
-	// description:
-	//	This project parses pre > code nodes, and applies syntax highlighting for
-	//	a wide variety of languages. Simply dojo.require() in all the
-	//	dojox.highlight.languages you wish to include in your highlighingting,
-	//	and customize colors in the highlight.css.
-	//
-	//	It is provided as a dojo package, contributed under CLA
-	//	by Ivan Sagalaev and is available originally from:
-	// 	http://softwaremaniacs.org/soft/highlight/en/
-	//
-};
-
-dojox.html = {
-	// summary: TODOC
-};
-
-dojox.image = {
-	// summary: A collection of image related widgets
-};
-
-dojox.io = {
-	// summary: Extensions to the Core dojo.io transports
-};
-
-dojox.jq = {
-	// summary: A JQuery compatibility layer
-};
-
-dojox.jsonPath = {
-	// summary: A query system for JavaScript objects
-};
-
-dojox.lang = {
-	// summary: Language specific extensions
-	functional: {
-		// summary: Functional language constructs, including currying and lambda.
-	}
-};
-
-dojox.layout = {
-	// summary: A collection of layout related Widgets
-};
-
-dojox.math = {
-	// summary: A collection of various advanced math functions.
-};
-
-dojox.robot = {
-	// summary: TODOC
-};
-
-dojox.rpc = {
-	// summary: TODOC
-};
-
-dojox.secure = {
-	// summary: TODOC
-};
-
-dojox.sketch = {
-	// summary: TODOC
-};
-
-dojox.sql = {
-	// summary: objects to support Dojo Offline (dojox.off)  DEPRECATED
-};
-
-dojox.storage = {
-	// summary: Objects for mass storage within the browser.  For when cookies just aren't enough.
-};
-
-dojox.string = {
-	// summary: A collection of various objects for advanced string manipulation, including a Builder and a tokenizer.
-};
-
-dojox.testing = {
-	// summary: TODOC
-};
-
-dojox.timing = {
-	// summary: A set of objects to perform advanced time-based tasks, including a basic Timer.
-};
-
-dojox.uuid = {
-	// summary: Universally Unique Identifier (UUID) implementations, including an implementation of UUID 2
-};
-
-dojox.validate = {
-	// summary: Additional input validation methods
-	ca : {
-		// summary: Methods specific to the Canadian provinces
-	},
-	creditCard : {
-		// summary: Validate various credit card types
-	}
-};
-
-dojox.widget = {
-	// summary: A collection of un-categorized widgets, or code not requiring its own package.
-	//
-	// description:
-	// 	These are standalone widgets with varying levels of stability. Some are useful,
-	//	some were created for demonstration purposes, and learning tools. The each maintain
-	//	their own .css file (typically dojox/widget/WidgetName/WidgetName.css)
-};
-
-dojox.wire = {
-	// summary:
-	//	Declarative data binding and action tags for simplified MVC
-};
-
-dojox.xml = {
-	// summary: XML utilities.  Currently only includes a DomParser, which returns a psuedo-XML document in JSON-like form.
-};
-
-dojox.xmpp = {
-	// summary: TODOC
-};
-=====*/
diff --git a/dojox/robot/tests/test_recorder.html b/dojox/robot/tests/test_recorder.html
index 34a1c92..7cf40a7 100644
--- a/dojox/robot/tests/test_recorder.html
+++ b/dojox/robot/tests/test_recorder.html
@@ -14,7 +14,7 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/rpc/JsonRPC.js b/dojox/rpc/JsonRPC.js
index c45a527..b308b9f 100644
--- a/dojox/rpc/JsonRPC.js
+++ b/dojox/rpc/JsonRPC.js
@@ -1,4 +1,4 @@
-define("dojox/rpc/JsonRPC", ["dojo", "dojox", "dojox/rpc/Service"], function(dojo, dojox) {
+define("dojox/rpc/JsonRPC", ["dojo", "dojox", "dojox/rpc/Service", "dojo/errors/RequestError"], function(dojo, dojox, Service, RequestError) {
 
 	function jsonRpcEnvelope(version){
 		return {
@@ -23,7 +23,9 @@ define("dojox/rpc/JsonRPC", ["dojo", "dojox", "dojox/rpc/Service"], function(doj
 			},
 	
 			deserialize: function(obj){
-				if ('Error' == obj.name){
+				if ('Error' == obj.name // old xhr
+					|| obj instanceof RequestError // new xhr
+				){
 					obj = dojo.fromJson(obj.responseText);
 				}
 				if(obj.error) {
@@ -40,7 +42,7 @@ define("dojox/rpc/JsonRPC", ["dojo", "dojox", "dojox/rpc/Service"], function(doj
 		function(str){
 			return str == "JSON-RPC-1.0";
 		},
-		dojo.mixin({namedParams:false},jsonRpcEnvelope()) // 1.0 will only work with ordered params
+		dojo.mixin({namedParams:false}, jsonRpcEnvelope()) // 1.0 will only work with ordered params
 	);
 
 	dojox.rpc.envelopeRegistry.register(
@@ -48,7 +50,7 @@ define("dojox/rpc/JsonRPC", ["dojo", "dojox", "dojox/rpc/Service"], function(doj
 		function(str){
 			return str == "JSON-RPC-2.0";
 		},
-		jsonRpcEnvelope("2.0")
+		dojo.mixin({namedParams:true }, jsonRpcEnvelope("2.0")) // 2.0 supports named params
 	);
 
 });
diff --git a/dojox/rpc/JsonRest.js b/dojox/rpc/JsonRest.js
index 88231ac..e1b9c48 100644
--- a/dojox/rpc/JsonRest.js
+++ b/dojox/rpc/JsonRest.js
@@ -16,7 +16,7 @@ define("dojox/rpc/JsonRest", ["dojo", "dojox", "dojox/json/ref", "dojox/rpc/Rest
 			index: Rest._index,
 			timeStamps: timeStamp && Rest._timeStamps,
 			time: timeStamp,
-			idPrefix: service.servicePath.replace(/[^\/]*$/,''),
+			idPrefix: service._store.allowNoTrailingSlash ? service.servicePath + '/' : service.servicePath.replace(/[^\/]*$/,''),
 			idAttribute: jr.getIdAttribute(service),
 			schemas: jr.schemas,
 			loader:	jr._loader,
@@ -112,7 +112,9 @@ define("dojox/rpc/JsonRest", ["dojo", "dojox", "dojox/json/ref", "dojox/rpc/Rest
 					dirtyObjects = postCommitDirtyObjects;
 				}
 				else{
-					dirtyObjects = dirtyObject.concat(savingObjects);
+					dojo.forEach(savingObjects, function(obj) {
+						jr.changing(obj.object, !obj.object);
+				    });
 				}
 			});
 			jr.sendToServer(actions, kwArgs);
@@ -279,13 +281,13 @@ define("dojox/rpc/JsonRest", ["dojo", "dojox", "dojox/json/ref", "dojox/rpc/Rest
 		deleteObject: function(object){
 			// summary:
 			//		deletes an object
-			//	object:
-			//  	object to delete
+			// object:
+			//		object to delete
 			this.changing(object,true);
 		},
 		getConstructor: function(/*Function|String*/service, schema){
 			// summary:
-			// 		Creates or gets a constructor for objects from this service
+			//		Creates or gets a constructor for objects from this service
 			if(typeof service == 'string'){
 				var servicePath = service;
 				service = new dojox.rpc.Rest(service,true);
@@ -297,8 +299,7 @@ define("dojox/rpc/JsonRest", ["dojo", "dojox", "dojox/json/ref", "dojox/rpc/Rest
 			service._constructor = function(data){
 				// summary:
 				//		creates a new object for this table
-				//
-				//	data:
+				// data:
 				//		object to mixed in
 				var self = this;
 				var args = arguments;
@@ -361,8 +362,8 @@ define("dojox/rpc/JsonRest", ["dojo", "dojox", "dojox/json/ref", "dojox/rpc/Rest
 		getServiceAndId: function(/*String*/absoluteId){
 			// summary:
 			//		Returns the REST service and the local id for the given absolute id. The result
-			// 		is returned as an object with a service property and an id property
-			//	absoluteId:
+			//		is returned as an object with a service property and an id property
+			// absoluteId:
 			//		This is the absolute id of the object
 			var serviceName = '';
 			
@@ -380,13 +381,13 @@ define("dojox/rpc/JsonRest", ["dojo", "dojox", "dojox/json/ref", "dojox/rpc/Rest
 		services:{},
 		schemas:{},
 		registerService: function(/*Function*/ service, /*String*/ servicePath, /*Object?*/ schema){
-			//	summary:
+			// summary:
 			//		Registers a service for as a JsonRest service, mapping it to a path and schema
-			//	service:
+			// service:
 			//		This is the service to register
-			//	servicePath:
+			// servicePath:
 			//		This is the path that is used for all the ids for the objects returned by service
-			//	schema:
+			// schema:
 			//		This is a JSON Schema object to associate with objects returned by this service
 			servicePath = service.servicePath = servicePath || service.servicePath;
 			service._schema = jr.schemas[servicePath] = schema || service._schema || {};
@@ -437,7 +438,7 @@ define("dojox/rpc/JsonRest", ["dojo", "dojox", "dojox/json/ref", "dojox/rpc/Rest
 			});
 		},
 		isDirty: function(item, store){
-			// summary
+			// summary:
 			//		returns true if the item is marked as dirty or true if there are any dirty items
 			if(!item){
 				if(store){
diff --git a/dojox/rpc/OfflineRest.js b/dojox/rpc/OfflineRest.js
index c7ebd0f..58c93ca 100644
--- a/dojox/rpc/OfflineRest.js
+++ b/dojox/rpc/OfflineRest.js
@@ -1,7 +1,5 @@
 define("dojox/rpc/OfflineRest", ["dojo", "dojox", "dojox/data/ClientFilter", "dojox/rpc/Rest", "dojox/storage"], function(dojo, dojox) {
-// summary:
-// 		Makes the REST service be able to store changes in local
-// 		storage so it can be used offline automatically.
+
 	var Rest = dojox.rpc.Rest;
 	var namespace = "dojox_rpc_OfflineRest";
 	var loaded;
@@ -53,6 +51,10 @@ define("dojox/rpc/OfflineRest", ["dojo", "dojox", "dojox/data/ClientFilter", "do
 	var syncId = setInterval(sync,15000);
 	dojo.connect(document, "ononline", sync);
 	OfflineRest = dojox.rpc.OfflineRest = {
+		// summary:
+		//		Makes the REST service be able to store changes in local
+		//		storage so it can be used offline automatically.
+
 		turnOffAutoSync: function(){
 			clearInterval(syncId);
 		},
@@ -64,9 +66,9 @@ define("dojox/rpc/OfflineRest", ["dojo", "dojox", "dojox/data/ClientFilter", "do
 		addStore: function(/*data-store*/store,/*query?*/baseQuery){
 			// summary:
 			//		Adds a store to the monitored store for local storage
-			//	store:
+			// store:
 			//		Store to add
-			//	baseQuery:
+			// baseQuery:
 			//		This is the base query to should be used to load the items for
 			//		the store. Generally you want to load all the items that should be
 			//		available when offline.
@@ -252,5 +254,5 @@ define("dojox/rpc/OfflineRest", ["dojo", "dojox", "dojox/data/ClientFilter", "do
 	dojo.connect(index,"onLoad",saveObject);
 	dojo.connect(index,"onUpdate",saveObject);
 
-	return dojox.rpc.OfflineRest;
+	return OfflineRest;
 });
diff --git a/dojox/rpc/Rest.js b/dojox/rpc/Rest.js
index c74107f..21aa9bd 100644
--- a/dojox/rpc/Rest.js
+++ b/dojox/rpc/Rest.js
@@ -2,24 +2,6 @@ define("dojox/rpc/Rest", ["dojo", "dojox"], function(dojo, dojox) {
 // Note: This doesn't require dojox.rpc.Service, and if you want it you must require it
 // yourself, and you must load it prior to dojox.rpc.Rest.
 
-// summary:
-// 		This provides a HTTP REST service with full range REST verbs include PUT,POST, and DELETE.
-// description:
-// 		A normal GET query is done by using the service directly:
-// 		| var restService = dojox.rpc.Rest("Project");
-// 		| restService("4");
-//		This will do a GET for the URL "/Project/4".
-//		| restService.put("4","new content");
-//		This will do a PUT to the URL "/Project/4" with the content of "new content".
-//		You can also use the SMD service to generate a REST service:
-// 		| var services = dojox.rpc.Service({services: {myRestService: {transport: "REST",...
-// 		| services.myRestService("parameters");
-//
-// 		The modifying methods can be called as sub-methods of the rest service method like:
-//  	| services.myRestService.put("parameters","data to put in resource");
-//  	| services.myRestService.post("parameters","data to post to the resource");
-//  	| services.myRestService['delete']("parameters");
-
   dojo.getObject("rpc.Rest", true, dojox);
 
 	if(dojox.rpc && dojox.rpc.transportRegistry){
@@ -64,7 +46,23 @@ define("dojox/rpc/Rest", ["dojo", "dojox"], function(dojo, dojox) {
 	}
 	drr = dojox.rpc.Rest = function(/*String*/path, /*Boolean?*/isJson, /*Object?*/schema, /*Function?*/getRequest){
 		// summary:
-		//		Creates a REST service using the provided path.
+		//		This provides a HTTP REST service with full range REST verbs include PUT,POST, and DELETE.
+		// description:
+		//		A normal GET query is done by using the service directly:
+		//		| var restService = dojox.rpc.Rest("Project");
+		//		| restService("4");
+		//		This will do a GET for the URL "/Project/4".
+		//		| restService.put("4","new content");
+		//		This will do a PUT to the URL "/Project/4" with the content of "new content".
+		//		You can also use the SMD service to generate a REST service:
+		//		| var services = dojox.rpc.Service({services: {myRestService: {transport: "REST",...
+		//		| services.myRestService("parameters");
+		//
+		//		The modifying methods can be called as sub-methods of the rest service method like:
+		//		| services.myRestService.put("parameters","data to put in resource");
+		//		| services.myRestService.post("parameters","data to post to the resource");
+		//		| services.myRestService['delete']("parameters");
+
 		var service;
 		// it should be in the form /Table/
 		service = function(id, args){
@@ -74,8 +72,8 @@ define("dojox/rpc/Rest", ["dojo", "dojox"], function(dojo, dojox) {
 		service._schema = schema;
 		// cache:
 		//		This is an object that provides indexing service
-		// 		This can be overriden to take advantage of more complex referencing/indexing
-		// 		schemes
+		//		This can be overriden to take advantage of more complex referencing/indexing
+		//		schemes
 		service.cache = {
 			serialize: isJson ? ((dojox.json && dojox.json.ref) || dojo).toJson : function(result){
 				return result;
@@ -142,5 +140,5 @@ define("dojox/rpc/Rest", ["dojo", "dojox"], function(dojo, dojox) {
 		return index(dojo.xhrGet(service._getRequest(id, args)), service, (args.start >= 0 || args.count >= 0), id);
 	};
 
-	return dojox.rpc.Rest;
+	return drr;
 });
diff --git a/dojox/rpc/SMDLibrary/twitter.smd b/dojox/rpc/SMDLibrary/twitter.smd
index 6c19b3a..1311e9a 100644
--- a/dojox/rpc/SMDLibrary/twitter.smd
+++ b/dojox/rpc/SMDLibrary/twitter.smd
@@ -1,35 +1,35 @@
-{
-	
-	"SMDVersion": "2.0",
-	"id": "http://apiwiki.twitter.com/w/page/22554756/Twitter-Search-API-Method:-search", 
-	"description": "Twitter Search API",
-		
-	"transport": "JSONP",
-	"envelope": "URL",
-	"additionalParameters": true,
-	
-	"parameters": [
-		// the most important param, the search query:
-		{ "name": "q", optional: false, "default":"" },
-		
-
-		// result size: large | small (8 or 4 per page)
-		{ "name": "rpp", optional:true, "default": 10 },
-
-		// language selection:
-		{ "name": "lang", optional:true, "default": "en" },
-
-		// starting page
-		{ "name": "page", optional:true, "default": 0 }
-
-	],
-
-	"services": {
-
-		"search": {
-			"target": "http://search.twitter.com/search.json",
-			"parameters": [
-			]
-		}		
-	}
-}
+{
+	
+	"SMDVersion": "2.0",
+	"id": "http://apiwiki.twitter.com/w/page/22554756/Twitter-Search-API-Method:-search", 
+	"description": "Twitter Search API",
+		
+	"transport": "JSONP",
+	"envelope": "URL",
+	"additionalParameters": true,
+	
+	"parameters": [
+		// the most important param, the search query:
+		{ "name": "q", optional: false, "default":"" },
+		
+
+		// result size: large | small (8 or 4 per page)
+		{ "name": "rpp", optional:true, "default": 10 },
+
+		// language selection:
+		{ "name": "lang", optional:true, "default": "en" },
+
+		// starting page
+		{ "name": "page", optional:true, "default": 0 }
+
+	],
+
+	"services": {
+
+		"search": {
+			"target": "http://search.twitter.com/search.json",
+			"parameters": [
+			]
+		}		
+	}
+}
diff --git a/dojox/rpc/Service.js b/dojox/rpc/Service.js
index 79564b5..6345930 100644
--- a/dojox/rpc/Service.js
+++ b/dojox/rpc/Service.js
@@ -5,8 +5,11 @@ dojo.declare("dojox.rpc.Service", null, {
 		// summary:
 		//		Take a string as a url to retrieve an smd or an object that is an smd or partial smd to use
 		//		as a definition for the service
-		//
-		//	smd: object
+		// description:
+		//		dojox.rpc.Service must be loaded prior to any plugin services like dojox.rpc.Rest
+		//		dojox.rpc.JsonRpc in order for them to register themselves, otherwise you get
+		//		a "No match found" error.
+		// smd: object
 		//		Takes a number of properties as kwArgs for defining the service.  It also
 		//		accepts a string.  When passed a string, it is treated as a url from
 		//		which it should synchronously retrieve an smd file.  Otherwise it is a kwArgs
@@ -16,11 +19,7 @@ dojo.declare("dojox.rpc.Service", null, {
 		//		matches those defined in the smd.  smdString allows a developer to pass
 		//		a jsonString directly, which will be converted into an object or alternatively
 		//		smdObject is accepts an smdObject directly.
-		//
-		//	description:
-		//		dojox.rpc.Service must be loaded prior to any plugin services like dojox.rpc.Rest
-		// 		dojox.rpc.JsonRpc in order for them to register themselves, otherwise you get
-		// 		a "No match found" error.
+
 		var url;
 		var self = this;
 		function processSmd(smd){
@@ -105,7 +104,7 @@ dojo.declare("dojox.rpc.Service", null, {
 				for(i in args){
 					var found=false;
 					for(var j=0; j<parameters.length;j++){
-						if(parameters[i].name==i){ found=true; }
+						if(parameters[j].name==i){ found=true; }
 					}
 					if(!found){
 						delete args[i];
diff --git a/dojox/rpc/demos/demo_GoogleAjax.html b/dojox/rpc/demos/demo_GoogleAjax.html
index fdd224f..3204996 100644
--- a/dojox/rpc/demos/demo_GoogleAjax.html
+++ b/dojox/rpc/demos/demo_GoogleAjax.html
@@ -31,7 +31,7 @@
 		}
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.rpc.Service");
 		dojo.require("dojo.io.script");
diff --git a/dojox/rpc/demos/demo_GoogleAjaxTranslate.html b/dojox/rpc/demos/demo_GoogleAjaxTranslate.html
index d6d0d5f..aa5a44a 100644
--- a/dojox/rpc/demos/demo_GoogleAjaxTranslate.html
+++ b/dojox/rpc/demos/demo_GoogleAjaxTranslate.html
@@ -35,7 +35,7 @@
 		.over { color:red !important; }
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.rpc.Service");
 		dojo.require("dojo.io.script");
diff --git a/dojox/rpc/demos/demo_GoogleFeed.html b/dojox/rpc/demos/demo_GoogleFeed.html
index 5ec3d0a..2444463 100644
--- a/dojox/rpc/demos/demo_GoogleFeed.html
+++ b/dojox/rpc/demos/demo_GoogleFeed.html
@@ -13,7 +13,7 @@ th, td {
 	border:1px solid #ddd;
 }
 </style>
-<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 	dojo.require("dojox.rpc.Service");
 	dojo.require("dojo.io.script");
diff --git a/dojox/rpc/demos/demo_jabsorb.html b/dojox/rpc/demos/demo_jabsorb.html
index 8452341..b9dab60 100644
--- a/dojox/rpc/demos/demo_jabsorb.html
+++ b/dojox/rpc/demos/demo_jabsorb.html
@@ -16,7 +16,7 @@ This uses the Hello example from the jabsorb framework (Hello.java and hello.jsp
 		@import "../../../dojo/resources/dojo.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.rpc.Service");
 		dojo.require("dojox.rpc.JsonRPC");
diff --git a/dojox/rpc/demos/documentation.html b/dojox/rpc/demos/documentation.html
index b5a2a44..c5dd0e3 100644
--- a/dojox/rpc/demos/documentation.html
+++ b/dojox/rpc/demos/documentation.html
@@ -1,6 +1,6 @@
 <html>
 	<head>
-		<script src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+		<script src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
 		<script>
 			dojo.require("dojo.io.script")
 			dojo.require("dojox.rpc.Service");
diff --git a/dojox/rpc/demos/wikipedia.html b/dojox/rpc/demos/wikipedia.html
index 4aeb233..71c1376 100644
--- a/dojox/rpc/demos/wikipedia.html
+++ b/dojox/rpc/demos/wikipedia.html
@@ -4,7 +4,7 @@
 			Wikipedia Article Grabber Demo
 		</title>
 		<script src="../../../dojo/dojo.js" type="text/javascript"
-			djConfig="parseOnLoad: true, isDebug: true"></script>
+			data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.io.script")
 			dojo.require("dojox.rpc.Service");
diff --git a/dojox/rpc/demos/yahoo.html b/dojox/rpc/demos/yahoo.html
index 4f1d705..14af007 100644
--- a/dojox/rpc/demos/yahoo.html
+++ b/dojox/rpc/demos/yahoo.html
@@ -4,7 +4,7 @@
 			Yahoo Search Demo
 		</title>
 		<script src="../../../dojo/dojo.js" type="text/javascript"
-			djConfig="parseOnLoad: true, isDebug: true"></script>
+			data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.io.script")
 			dojo.require("dojox.rpc.Service");
diff --git a/dojox/rpc/tests/resources/bigQuery b/dojox/rpc/tests/resources/bigQuery
index e8f9429..4f8515d 100644
--- a/dojox/rpc/tests/resources/bigQuery
+++ b/dojox/rpc/tests/resources/bigQuery
@@ -1 +1 @@
-[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
\ No newline at end of file
+[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
diff --git a/dojox/rpc/tests/resources/bigQuery5 b/dojox/rpc/tests/resources/bigQuery5
index e77ca8d..bfedf5b 100644
--- a/dojox/rpc/tests/resources/bigQuery5
+++ b/dojox/rpc/tests/resources/bigQuery5
@@ -1 +1 @@
-[1,2,3,4,5]
\ No newline at end of file
+[1,2,3,4,5]
diff --git a/dojox/rpc/tests/resources/obj1 b/dojox/rpc/tests/resources/obj1
index ff02ba8..889b091 100644
--- a/dojox/rpc/tests/resources/obj1
+++ b/dojox/rpc/tests/resources/obj1
@@ -1 +1 @@
-{"id":"obj1","name":"Object 1","updated":1202755814406,"obj":{"foo":"bar"},"obj dup":{"$ref":"obj1.obj"},"testArray":[1,2,3,4]}
\ No newline at end of file
+{"id":"obj1","name":"Object 1","updated":1202755814406,"obj":{"foo":"bar"},"obj dup":{"$ref":"obj1.obj"},"testArray":[1,2,3,4]}
diff --git a/dojox/rpc/tests/resources/obj1lazyValue b/dojox/rpc/tests/resources/obj1lazyValue
index 6e6f460..fa72afe 100644
--- a/dojox/rpc/tests/resources/obj1lazyValue
+++ b/dojox/rpc/tests/resources/obj1lazyValue
@@ -1 +1 @@
-"Finally loaded"
\ No newline at end of file
+"Finally loaded"
diff --git a/dojox/rpc/tests/resources/obj1testArray b/dojox/rpc/tests/resources/obj1testArray
index 0c624c1..99e252a 100644
--- a/dojox/rpc/tests/resources/obj1testArray
+++ b/dojox/rpc/tests/resources/obj1testArray
@@ -1 +1 @@
-[1,2,3,undefined,4]
\ No newline at end of file
+[1,2,3,undefined,4]
diff --git a/dojox/rpc/tests/resources/obj3 b/dojox/rpc/tests/resources/obj3
index 21cb328..49e2c94 100644
--- a/dojox/rpc/tests/resources/obj3
+++ b/dojox/rpc/tests/resources/obj3
@@ -1 +1 @@
-{"id":"obj3","name":"Object 3"}
\ No newline at end of file
+{"id":"obj3","name":"Object 3"}
diff --git a/dojox/rpc/tests/resources/obj4 b/dojox/rpc/tests/resources/obj4
index a429ecf..2ced7c8 100644
--- a/dojox/rpc/tests/resources/obj4
+++ b/dojox/rpc/tests/resources/obj4
@@ -1 +1 @@
-{"id":"obj4","name":"Object 4"}
\ No newline at end of file
+{"id":"obj4","name":"Object 4"}
diff --git a/dojox/rpc/tests/resources/res b/dojox/rpc/tests/resources/res
index 3c22137..71779d2 100644
--- a/dojox/rpc/tests/resources/res
+++ b/dojox/rpc/tests/resources/res
@@ -1 +1 @@
-deleted
\ No newline at end of file
+deleted
diff --git a/dojox/rpc/tests/stores/JsonRestStore.js b/dojox/rpc/tests/stores/JsonRestStore.js
index 9e39a50..33aa31b 100644
--- a/dojox/rpc/tests/stores/JsonRestStore.js
+++ b/dojox/rpc/tests/stores/JsonRestStore.js
@@ -5,7 +5,7 @@ dojo.require("dojo.data.api.Read");
 dojo.require("dojox.rpc.Service");
 
 dojox.rpc.tests.stores.JsonRestStore.error = function(t, d, errData){
-	//  summary:
+	// summary:
 	//		The error callback function to be used for all of the tests.
 	d.errback(errData);
 }
@@ -18,7 +18,7 @@ doh.register("dojox.rpc.tests.stores.JsonRestStore",
 			name: "Fetch some items",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonRestStore of a simple query.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"query",
@@ -34,7 +34,7 @@ doh.register("dojox.rpc.tests.stores.JsonRestStore",
 			name: "fetch by id",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Simple test of a basic fetch on JsonRestStore of a single item.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"obj1",
@@ -53,7 +53,7 @@ doh.register("dojox.rpc.tests.stores.JsonRestStore",
 			name: "Modify,save, check by id",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		Fetch an item from a query, modify and save it, and check to see if it was modified correctly
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"query",
@@ -82,7 +82,7 @@ doh.register("dojox.rpc.tests.stores.JsonRestStore",
 			name: "Post, delete, and put",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		append/post an item, delete it, sort the lists, resort the list, saving each time.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"obj1",
@@ -108,7 +108,7 @@ doh.register("dojox.rpc.tests.stores.JsonRestStore",
 			name: "Revert",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		append/post an item, delete it, sort the lists, resort the list, saving each time.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"obj1",
@@ -133,7 +133,7 @@ doh.register("dojox.rpc.tests.stores.JsonRestStore",
 			name: "Lazy loading",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		test lazy loading
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"query",
@@ -153,7 +153,7 @@ doh.register("dojox.rpc.tests.stores.JsonRestStore",
 			name: "Array manipulation",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		test array manipulation
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:"obj1",
@@ -177,7 +177,7 @@ doh.register("dojox.rpc.tests.stores.JsonRestStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Json can sometimes be slow.
 			runTest: function(t) {
-				//	summary:
+				// summary:
 				//		fetching with paging
 
 				var d = new doh.Deferred();
@@ -206,9 +206,9 @@ doh.register("dojox.rpc.tests.stores.JsonRestStore",
 			}
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary:
+			// summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
-			//	description:
+			// description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 
 			var readApi = new dojo.data.api.Read();
diff --git a/dojox/secure/capability.js b/dojox/secure/capability.js
index 35cbdd6..c221ab9 100644
--- a/dojox/secure/capability.js
+++ b/dojox/secure/capability.js
@@ -8,21 +8,19 @@ dojox.secure.capability = {
 		 "throw", "true", "try", "typeof", "var", "void", "while"],
 	validate : function(/*string*/script,/*Array*/safeLibraries,/*Object*/safeGlobals) {
 		// summary:
-		// 		pass in the text of a script. If it passes and it can be eval'ed, it should be safe.
-		// 		Note that this does not do full syntax checking, it relies on eval to reject invalid scripts.
-		// 		There are also known false rejections:
-		// 			Nesting vars inside blocks will not declare the variable for the outer block
-		// 	 		Named functions are not treated as declaration so they are generally not allowed unless the name is declared with a var.
-		//			Var declaration that involve multiple comma delimited variable assignments are not accepted
+		//		pass in the text of a script. If it passes and it can be eval'ed, it should be safe.
+		//		Note that this does not do full syntax checking, it relies on eval to reject invalid scripts.
+		//		There are also known false rejections:
 		//
+		//		- Nesting vars inside blocks will not declare the variable for the outer block
+		// 	 	- Named functions are not treated as declaration so they are generally not allowed unless the name is declared with a var.
+		//		- Var declaration that involve multiple comma delimited variable assignments are not accepted
 		// script:
-		// 		 the script to execute
-		//
+		//		 the script to execute
 		// safeLibraries:
-		// 		The safe libraries that can be called (the functions can not be access/modified by the untrusted code, only called)
-		//
+		//		The safe libraries that can be called (the functions can not be access/modified by the untrusted code, only called)
 		// safeGlobals:
-		// 		These globals can be freely interacted with by the untrusted code
+		//		These globals can be freely interacted with by the untrusted code
 		
 	
 		var keywords = this.keywords;
diff --git a/dojox/secure/fromJson.js b/dojox/secure/fromJson.js
index e5ab8d7..9af0843 100644
--- a/dojox/secure/fromJson.js
+++ b/dojox/secure/fromJson.js
@@ -7,9 +7,9 @@ dojo.provide("dojox.secure.fromJson");
 
 
 dojox.secure.fromJson = typeof JSON != "undefined" ? JSON.parse :
-//	summary:
+// summary:
 //		Parses a string of well-formed JSON text.
-//	description:
+// description:
 //		Parses a string of well-formed JSON text. If the input is not well-formed,
 //		then behavior is undefined, but it is
 //		deterministic and is guaranteed not to modify any object other than its
@@ -28,36 +28,34 @@ dojox.secure.fromJson = typeof JSON != "undefined" ? JSON.parse :
 //		looks like JSON, but that executes arbitrary javascript.
 //
 //		To configure dojox.secure.fromJson as the JSON parser for all Dojo
-// 		JSON parsing, simply do:
+//		JSON parsing, simply do:
 //		|	dojo.require("dojox.secure.fromJson");
 //		|	dojo.fromJson = dojox.secure.fromJson;
 //		or alternately you could configure dojox.secure.fromJson to only handle
-// 		XHR responses:
+//		XHR responses:
 //		|	dojo._contentHandlers.json = function(xhr){
 //		|		return dojox.secure.fromJson.fromJson(xhr.responseText);
 //		|	};
-//
-//	json: String
-// 		per RFC 4627
-//	optReviver: Function (this:Object, string, *)
-// 		optional function
-//				that reworks JSON objects post-parse per Chapter 15.12 of EcmaScript3.1.
-//				If supplied, the function is called with a string key, and a value.
-//				The value is the property of 'this'.	The reviver should return
-//				the value to use in its place.	So if dates were serialized as
-//				{@code { "type": "Date", "time": 1234 }}, then a reviver might look like
-//				{@code
-//				function (key, value) {
-//					if (value && typeof value === 'object' && 'Date' === value.type) {
-//						return new Date(value.time);
-//					} else {
-//						return value;
-//					}
-//				}}.
-//				If the reviver returns {@code undefined} then the property named by key
-//				will be deleted from its container.
-//				{@code this} is bound to the object containing the specified property.
-//	returns: {Object|Array}
+// json: String
+//		per RFC 4627
+// optReviver: Function (this:Object, string, *)
+//		optional function
+//		that reworks JSON objects post-parse per Chapter 15.12 of EcmaScript3.1.
+//		If supplied, the function is called with a string key, and a value.
+//		The value is the property of 'this'.	The reviver should return
+//		the value to use in its place.	So if dates were serialized as
+//		`{ "type": "Date", "time": 1234 }`, then a reviver might look like
+// |	function (key, value) {
+// |		if (value && typeof value === 'object' && 'Date' === value.type) {
+// |			return new Date(value.time);
+// |		} else {
+// |			return value;
+// |		}
+// |	}}.
+//		If the reviver returns {@code undefined} then the property named by key
+//		will be deleted from its container.
+//		`this` is bound to the object containing the specified property.
+// returns: Object|Array
 (function () {
 	var number
 			= '(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)';
diff --git a/dojox/secure/sandbox.js b/dojox/secure/sandbox.js
index 033abe2..4a0bff4 100644
--- a/dojox/secure/sandbox.js
+++ b/dojox/secure/sandbox.js
@@ -37,18 +37,18 @@ dojo.require("dojo._base.url");
 		return dojo.xhrGet.apply(dojo,arguments);
 	};
 	dojox.secure.sandbox = function(element) {
-		//	summary:
+		// summary:
 		//		Creates a secure sandbox from which scripts and HTML can be loaded that
 		//		will only be able to access the provided element and it's descendants, the
 		//		rest of the DOM and JS environment will not be accessible to the sandboxed
 		//		scripts and HTML.
 		//
-		//	element:
+		// element:
 		//		The DOM element to use as the container for the sandbox
 		//
-		//	description:
+		// description:
 		//		This function will create and return a sandbox object (see dojox.secure.__Sandbox)
-		// 		for the provided element.
+		//		for the provided element.
 		var wrap = dojox.secure.DOM(element);
 		element = wrap(element);
 		var document = element.ownerDocument;
@@ -124,32 +124,32 @@ dojo.require("dojo._base.url");
 		}
 		function Class(/*Function*/superclass, /*Object*/properties, /*Object*/classProperties) {
 			// summary:
-			// 		A safe class constructor
+			//		A safe class constructor
 			//
 			// superclass:
-			// 		There may be zero or more superclass arguments. The constructed class
-			// 		will inherit from any provided superclasses, protypically from the first,
-			// 		via mixin for the subsequent. Later arguments
-			// 		will override properties/methods from earlier arguments
+			//		There may be zero or more superclass arguments. The constructed class
+			//		will inherit from any provided superclasses, protypically from the first,
+			//		via mixin for the subsequent. Later arguments
+			//		will override properties/methods from earlier arguments
 			//
 			// properties:
-			// 		The constructed
-			// 		"class" will also have the methods/properties defined in this argument.
+			//		The constructed
+			//		"class" will also have the methods/properties defined in this argument.
 			//		These methods may utilize the <em>this</em> operator, and they
-			// 		are only the code that has access to <em>this</em>. Inner functions
-			// 		are also prohibited from using <em>this</em>.
+			//		are only the code that has access to <em>this</em>. Inner functions
+			//		are also prohibited from using <em>this</em>.
 			//
-			// 		If no superclasses are provided, this object will be the prototype of the
-			// 		constructed class (no copying
-			// 		will be done). Consequently you can "beget" by calling new (Class(obj)).
-			// 		All methods are "bound", each call results in |this| safety checking call.
+			//		If no superclasses are provided, this object will be the prototype of the
+			//		constructed class (no copying
+			//		will be done). Consequently you can "beget" by calling new (Class(obj)).
+			//		All methods are "bound", each call results in |this| safety checking call.
 			//
 			// classProperties:
-			// 		This properties will be copied to the new class function.
+			//		This properties will be copied to the new class function.
 			//
-			// 		Note that neither dojo.declare nor dojo.extend are acceptable class constructors as
-			// 		they are completely unsecure. This class constructor is conceptually based on declare
-			// 		but also somewhat influenced by base2, prototype, YUI, resig's patterns, etc.
+			//		Note that neither dojo.declare nor dojo.extend are acceptable class constructors as
+			//		they are completely unsecure. This class constructor is conceptually based on declare
+			//		but also somewhat influenced by base2, prototype, YUI, resig's patterns, etc.
 			//
 			// example:
 			// |	var Car = Class({drive:function(speed) { ... } ); // create a Car class with a "drive" method
@@ -252,11 +252,11 @@ dojo.require("dojo._base.url");
 		};
 		return /*===== dojo.declare("dojox.secure.__Sandbox", null, =====*/ { // dojox.secure.__Sandbox
 			loadJS : function(url){
-				//	summary:
-				// 		Loads the script from the given URL using XHR (assuming
-				// 		a plugin system is in place for cross-site requests) within the sandbox
+				// summary:
+				//		Loads the script from the given URL using XHR (assuming
+				//		a plugin system is in place for cross-site requests) within the sandbox
 				//
-				//	url:
+				// url:
 				//		The url of the script to load
 				wrap.rootUrl = url;
 				return xhrGet({url:url,secure:true}).addCallback(function(result) {
@@ -264,12 +264,12 @@ dojo.require("dojo._base.url");
 				});
 			},
 			loadHTML : function(url){
-				//	summary:
+				// summary:
 				//		Loads the web page from the provided URL using XHR (assuming the
 				//		plugin system is in place) within the sandbox. All scripts within the web
 				//		page will also be sandboxed.
 				//
-				//	url:
+				// url:
 				//		The url of the web page to load
 
 				wrap.rootUrl = url;
@@ -278,10 +278,10 @@ dojo.require("dojo._base.url");
 				});
 			},
 			evaluate : function(script){
-				//	summary:
+				// summary:
 				//		Evaluates the given script within the sandbox
 				//
-				//	script:
+				// script:
 				//		The JavaScript text to evaluate
 				return wrap.evaluate(script);
 			}
diff --git a/dojox/sketch.js b/dojox/sketch.js
index 0fd903c..1ecb96e 100644
--- a/dojox/sketch.js
+++ b/dojox/sketch.js
@@ -7,5 +7,13 @@ define([
 	"./sketch/Toolbar"
 ], function(dojo){
 	dojo.getObject("sketch", true, dojox);
+
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/sketch modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
 	return dojox.sketch;
 });
diff --git a/dojox/sketch/Figure.js b/dojox/sketch/Figure.js
index 358a232..07e9720 100644
--- a/dojox/sketch/Figure.js
+++ b/dojox/sketch/Figure.js
@@ -177,6 +177,11 @@ define([
 		};
 		this._mm=function(e){
 			if(!self._ctr){ return; }
+			if(self._c && !self._c.shape){
+				//the selected item is gone, cancel editing mode
+				self._clearMouse();
+				return;
+			}
 			var x=e.clientX-self._ctr.x;
 			var y=e.clientY-self._ctr.y;
 			var dx=x-self._lp.x;
@@ -202,11 +207,15 @@ define([
 		this._mu=function(e){
 			if(self._c){
 				//	record the event.
-				self._c.endEdit();
+				if(self._c.shape){
+					self._c.endEdit(); //make sure it's not deleted
+				}
 			}else{
 				self._ctool.onMouseUp(e);
 			}
-
+			self._clearMouse();
+		};
+		this._clearMouse=function(){
 			//	clear the stuff out.
 			self._c=self._ctr=self._lp=self._action=self._prevState=self._startPoint=null;
 			self._cshape=self._start=self._end=self._absEnd=null;
@@ -223,10 +232,10 @@ define([
 		this._ctool=t;
 	};
     //gridSize: int
-    //      if it is greater than 0, all new shapes placed on the drawing will have coordinates
-    //      snapped to the gridSize. For example, if gridSize is set to 10, all coordinates
-    //      (only including coordinates which specifies the x/y position of shape are affected
-    //      by this parameter) will be dividable by 10
+    //		if it is greater than 0, all new shapes placed on the drawing will have coordinates
+    //		snapped to the gridSize. For example, if gridSize is set to 10, all coordinates
+    //		(only including coordinates which specifies the x/y position of shape are affected
+    //		by this parameter) will be dividable by 10
     p.gridSize=0;
     p._calCol=function(v){
         return this.gridSize?(Math.round(v/this.gridSize)*this.gridSize):v;
diff --git a/dojox/sketch/_Plugin.js b/dojox/sketch/_Plugin.js
index 5d01ae9..3eabf58 100644
--- a/dojox/sketch/_Plugin.js
+++ b/dojox/sketch/_Plugin.js
@@ -6,9 +6,8 @@ define([
 	"dojo/_base/connect",
 	"dijit/form/ToggleButton"
 ], function(dojo){
-	dojo.getObject("sketch", true, dojox);
-	dojo.declare("dojox.sketch._Plugin", null, {
-		// summary
+	return dojo.declare("dojox.sketch._Plugin", null, {
+		// summary:
 		//		This represents a "plugin" to the dojox.sketch.Figure, which is basically
 		//		a single button on the Toolbar and some associated code
 		constructor: function(/*Object?*/args){
@@ -77,5 +76,4 @@ define([
 			}
 		}
 	});
-	return dojox.sketch._Plugin;
 });
diff --git a/dojox/socket.js b/dojox/socket.js
index 52df546..0b575a5 100644
--- a/dojox/socket.js
+++ b/dojox/socket.js
@@ -1,24 +1,24 @@
-define("dojox/socket", ["dojo", "dojo/Evented", "dojo/cookie", "dojo/_base/url"], function(dojo, Evented) {
+define("dojox/socket", ["dojo", "dojo/on", "dojo/Evented", "dojo/cookie", "dojo/_base/url"], function(dojo, on, Evented) {
 
 var WebSocket = window.WebSocket;
 
 function Socket(/*dojo.__XhrArgs*/ argsOrUrl){
 	// summary:
 	//		Provides a simple socket connection using WebSocket, or alternate
-	// 		communication mechanisms in legacy browsers for comet-style communication. This is based
+	//		communication mechanisms in legacy browsers for comet-style communication. This is based
 	//		on the WebSocket API and returns an object that implements the WebSocket interface:
 	//		http://dev.w3.org/html5/websockets/#websocket
-	//	description:
+	// description:
 	//		Provides socket connections. This can be used with virtually any Comet protocol.
-	//	argsOrUrl:
+	// argsOrUrl:
 	//		This uses the same arguments as the other I/O functions in Dojo, or a
-	// 		URL to connect to. The URL should be a relative URL in order to properly
+	//		URL to connect to. The URL should be a relative URL in order to properly
 	//		work with WebSockets (it can still be host relative, like //other-site.org/endpoint)
 	// returns:
-	// 		An object that implements the WebSocket API
+	//		An object that implements the WebSocket API
 	// example:
 	//		| dojo.require("dojox.socket");
-	//		| var socket = dojox.socket({"//comet-server/comet");
+	//		| var socket = dojox.socket({"url://comet-server/comet");
 	//		| // we could also add auto-reconnect support
 	//		| // now we can connect to standard HTML5 WebSocket-style events
 	//		| dojo.connect(socket, "onmessage", function(event){
@@ -75,29 +75,27 @@ Socket.replace = function(socket, newSocket, listenForOpen){
 	dojo.forEach(["message", "close", "error"], proxyEvent);
 	function proxyEvent(type){
 		(newSocket.addEventListener || newSocket.on).call(newSocket, type, function(event){
-			var newEvent = document.createEvent("MessageEvent");
-			newEvent.initMessageEvent(event.type, false, false, event.data, event.origin, event.lastEventId, event.source);
-			socket.dispatchEvent(newEvent);
+			on.emit(socket, event.type, event);
 		}, true);
 	}
 };
 Socket.LongPoll = function(/*dojo.__XhrArgs*/ args){
 	// summary:
 	//		Provides a simple long-poll based comet-style socket/connection to a server and returns an
-	// 		object implementing the WebSocket interface:
+	//		object implementing the WebSocket interface:
 	//		http://dev.w3.org/html5/websockets/#websocket
-	//	args:
+	// args:
 	//		This uses the same arguments as the other I/O functions in Dojo, with this addition:
 	//	args.interval:
 	//		Indicates the amount of time (in milliseconds) after a response was received
 	//		before another request is made. By default, a request is made immediately
 	//		after getting a response. The interval can be increased to reduce load on the
 	//		server or to do simple time-based polling where the server always responds
-	// 		immediately.
+	//		immediately.
 	//	args.transport:
 	//		Provide an alternate transport like dojo.io.script.get
 	// returns:
-	// 		An object that implements the WebSocket API
+	//		An object that implements the WebSocket API
 	// example:
 	//		| dojo.require("dojox.socket.LongPoll");
 	//		| var socket = dojox.socket.LongPoll({url:"/comet"});
@@ -115,7 +113,7 @@ var cancelled = false,
 	var socket = {
 		send: function(data){
 			// summary:
-			// 		Send some data using XHR or provided transport
+			//		Send some data using XHR or provided transport
 			var sendArgs = dojo.delegate(args);
 			sendArgs.rawBody = data;
 			clearTimeout(timeoutId);
@@ -151,7 +149,7 @@ var cancelled = false,
 		},
 		close: function(){
 			// summary:
-			// 		Close the connection
+			//		Close the connection
 			socket.readyState = 2;
 			cancelled = true;
 			for(var i = 0; i < connections.length; i++){
@@ -168,17 +166,14 @@ var cancelled = false,
 		OPEN: 1,
 		CLOSING: 2,
 		CLOSED: 3,
-		dispatchEvent: function(event){
-			fire(event.type, event);
-		},
 		on: Evented.prototype.on,
 		firstRequest: function(args){
 			// summary:
-			// 		This allows for special handling for the first request. This is useful for
+			//		This allows for special handling for the first request. This is useful for
 			//		providing information to disambiguate between the first request and
 			//		subsequent long-poll requests so the server can properly setup a
-			// 		connection on the first connection or reject a request for an expired
-			// 		connection if the request is not expecting to be the first for a connection.
+			//		connection on the first connection or reject a request for an expired
+			//		connection if the request is not expecting to be the first for a connection.
 			//		This method can be overriden. The default behavior is to include a Pragma
 			//		header with a value of "start-long-poll"
 			var headers = (args.headers || (args.headers = {}));
@@ -205,11 +200,9 @@ var cancelled = false,
 	}
 	function fire(type, object, deferred){
 		if(socket["on" + type]){
-			var event = document.createEvent("HTMLEvents");
-			event.initEvent(type, false, false);
-			dojo.mixin(event, object);
-			event.ioArgs = deferred && deferred.ioArgs;
-			socket["on" + type](event);
+			object.ioArgs = deferred && deferred.ioArgs;
+			object.type = type;
+			on.emit(socket, type, object);
 		}
 	}
 	// provide an alias for Dojo's connect method
diff --git a/dojox/socket/Reconnect.js b/dojox/socket/Reconnect.js
index fa932a6..6ae4ad2 100644
--- a/dojox/socket/Reconnect.js
+++ b/dojox/socket/Reconnect.js
@@ -3,10 +3,10 @@ dojo.provide("dojox.socket.Reconnect");
 dojox.socket.Reconnect = function(socket, options){
 	// summary:
 	//		Provides auto-reconnection to a websocket after it has been closed
-	//	socket:
+	// socket:
 	//		Socket to add reconnection support to.
 	// returns:
-	// 		An object that implements the WebSocket API
+	//		An object that implements the WebSocket API
 	// example:
 	//		You can use the Reconnect module:
 	//		| dojo.require("dojox.socket");
diff --git a/dojox/sql.js b/dojox/sql.js
index 87da461..2febb3a 100644
--- a/dojox/sql.js
+++ b/dojox/sql.js
@@ -1,2 +1,9 @@
-dojo.provide("dojox.sql");
-dojo.require("dojox.sql._base");
+define(['./sql/_base'],function(){
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/sql modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
+});
diff --git a/dojox/sql/_base.js b/dojox/sql/_base.js
index 744bf0d..31c55ff 100644
--- a/dojox/sql/_base.js
+++ b/dojox/sql/_base.js
@@ -3,41 +3,42 @@ dojo.require("dojox.sql._crypto");
 
 dojo.mixin(dojox.sql, {
 	// summary:
-	//	Executes a SQL expression.
+	//		Executes a SQL expression.
 	// description:
-	// 	There are four ways to call this:
-	// 	1) Straight SQL: dojox.sql("SELECT * FROM FOOBAR");
-	// 	2) SQL with parameters: dojox.sql("INSERT INTO FOOBAR VALUES (?)", someParam)
-	// 	3) Encrypting particular values:
-	//			dojox.sql("INSERT INTO FOOBAR VALUES (ENCRYPT(?))", someParam, "somePassword", callback)
-	// 	4) Decrypting particular values:
-	//			dojox.sql("SELECT DECRYPT(SOMECOL1), DECRYPT(SOMECOL2) FROM
-	//					FOOBAR WHERE SOMECOL3 = ?", someParam,
-	//					"somePassword", callback)
+	// 		There are four ways to call this:
 	//
-	// 	For encryption and decryption the last two values should be the the password for
-	// 	encryption/decryption, and the callback function that gets the result set.
+	// 		1. Straight SQL: dojox.sql("SELECT * FROM FOOBAR");
+	// 		2. SQL with parameters: dojox.sql("INSERT INTO FOOBAR VALUES (?)", someParam)
+	// 		3. Encrypting particular values:
+	//			dojox.sql("INSERT INTO FOOBAR VALUES (ENCRYPT(?))", someParam, "somePassword", callback)
+	// 		4. Decrypting particular values:
+	//	|		dojox.sql("SELECT DECRYPT(SOMECOL1), DECRYPT(SOMECOL2) FROM
+	//	|				FOOBAR WHERE SOMECOL3 = ?", someParam,
+	//	|				"somePassword", callback)
 	//
-	// 	Note: We only support ENCRYPT(?) statements, and
-	// 	and DECRYPT(*) statements for now -- you can not have a literal string
-	// 	inside of these, such as ENCRYPT('foobar')
+	// 		For encryption and decryption the last two values should be the the password for
+	// 		encryption/decryption, and the callback function that gets the result set.
 	//
-	// 	Note: If you have multiple columns to encrypt and decrypt, you can use the following
-	// 	convenience form to not have to type ENCRYPT(?)/DECRYPT(*) many times:
+	// 		Note: We only support ENCRYPT(?) statements, and
+	// 		and DECRYPT(*) statements for now -- you can not have a literal string
+	// 		inside of these, such as ENCRYPT('foobar')
 	//
-	// 	dojox.sql("INSERT INTO FOOBAR VALUES (ENCRYPT(?, ?, ?))",
-	//					someParam1, someParam2, someParam3,
-	//					"somePassword", callback)
+	// 		Note: If you have multiple columns to encrypt and decrypt, you can use the following
+	// 		convenience form to not have to type ENCRYPT(?)/DECRYPT(*) many times:
 	//
-	// 	dojox.sql("SELECT DECRYPT(SOMECOL1, SOMECOL2) FROM
-	//					FOOBAR WHERE SOMECOL3 = ?", someParam,
-	//					"somePassword", callback)
+	// | 	dojox.sql("INSERT INTO FOOBAR VALUES (ENCRYPT(?, ?, ?))",
+	// |					someParam1, someParam2, someParam3,
+	// |					"somePassword", callback)
+	// |
+	// | 	dojox.sql("SELECT DECRYPT(SOMECOL1, SOMECOL2) FROM
+	// |				FOOBAR WHERE SOMECOL3 = ?", someParam,
+	// |				"somePassword", callback)
 
 	dbName: null,
 	
-	// summary:
-	//	If true, then we print out any SQL that is executed
-	//	to the debug window
+	// debug: Boolean
+	//		If true, then we print out any SQL that is executed
+	//		to the debug window
 	debug: (dojo.exists("dojox.sql.debug") ? dojox.sql.debug:false),
 
 	open: function(dbName){
@@ -241,10 +242,10 @@ dojo.mixin(dojox.sql, {
 
 dojo.declare("dojox.sql._SQLCrypto", null, {
 	// summary:
-	//	A private class encapsulating any cryptography that must be done
-	// 	on a SQL statement. We instantiate this class and have it hold
-	//	it's state so that we can potentially have several encryption
-	//	operations happening at the same time by different SQL statements.
+	//		A private class encapsulating any cryptography that must be done
+	// 		on a SQL statement. We instantiate this class and have it hold
+	//		it's state so that we can potentially have several encryption
+	//		operations happening at the same time by different SQL statements.
 	constructor: function(action, sql, password, args, callback){
 		if(action == "encrypt"){
 			this._execEncryptSQL(sql, password, args, callback);
diff --git a/dojox/sql/_crypto.js b/dojox/sql/_crypto.js
index bf29f82..d877546 100644
--- a/dojox/sql/_crypto.js
+++ b/dojox/sql/_crypto.js
@@ -1,20 +1,21 @@
 dojo.provide("dojox.sql._crypto");
 dojo.mixin(dojox.sql._crypto, {
-	// summary: dojox.sql cryptography code
+	// summary:
+	//		dojox.sql cryptography code
 	// description:
-	//	Taken from http://www.movable-type.co.uk/scripts/aes.html by
-	// 	Chris Veness (CLA signed); adapted for Dojo and Google Gears Worker Pool
-	// 	by Brad Neuberg, bkn3 at columbia.edu
-	//
+	//		Taken from http://www.movable-type.co.uk/scripts/aes.html by
+	//		Chris Veness (CLA signed); adapted for Dojo and Google Gears Worker Pool
+	//		by Brad Neuberg, bkn3 at columbia.edu
+
 	// _POOL_SIZE:
-	//	Size of worker pool to create to help with crypto
+	//		Size of worker pool to create to help with crypto
 	_POOL_SIZE: 100,
 
 	encrypt: function(plaintext, password, callback){
 		// summary:
-		//	Use Corrected Block TEA to encrypt plaintext using password
-		//	(note plaintext & password must be strings not string objects).
-		//	Results will be returned to the 'callback' asychronously.
+		//		Use Corrected Block TEA to encrypt plaintext using password
+		//		(note plaintext & password must be strings not string objects).
+		//		Results will be returned to the 'callback' asychronously.
 		this._initWorkerPool();
 
 		var msg ={plaintext: plaintext, password: password};
@@ -26,9 +27,9 @@ dojo.mixin(dojox.sql._crypto, {
 
 	decrypt: function(ciphertext, password, callback){
 		// summary:
-		//	Use Corrected Block TEA to decrypt ciphertext using password
-		//	(note ciphertext & password must be strings not string objects).
-		//	Results will be returned to the 'callback' asychronously.
+		//		Use Corrected Block TEA to decrypt ciphertext using password
+		//		(note ciphertext & password must be strings not string objects).
+		//		Results will be returned to the 'callback' asychronously.
 		this._initWorkerPool();
 
 		var msg = {ciphertext: ciphertext, password: password};
@@ -83,7 +84,7 @@ dojo.mixin(dojox.sql._crypto, {
 			
 					// return results
 					callback(msg);
-				}
+				};
 			
 				var workerInit = "function _workerInit(){"
 									+ "gearsWorkerPool.onmessage = "
diff --git a/dojox/sql/demos/customers/customers.html b/dojox/sql/demos/customers/customers.html
index a4c0c03..9ec1a31 100644
--- a/dojox/sql/demos/customers/customers.html
+++ b/dojox/sql/demos/customers/customers.html
@@ -3,7 +3,7 @@
 <html>
 	<head>
 	    <script type="text/javascript" 
-	            src="../../../../dojo/dojo.js" djConfig="isDebug: false"></script>
+	            src="../../../../dojo/dojo.js" data-dojo-config="isDebug: false"></script>
 		<script type="text/javascript" src="../../../../dojox/off/offline.js"></script>
 		
 		<style type="text/css">
diff --git a/dojox/storage.js b/dojox/storage.js
index 1c2d149..09ff1da 100644
--- a/dojox/storage.js
+++ b/dojox/storage.js
@@ -1,2 +1,9 @@
-dojo.provide("dojox.storage");
-dojo.require("dojox.storage._common");
+define(['./storage/_common'],function(){
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/storage modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
+});
diff --git a/dojox/store/LightstreamerStore.js b/dojox/store/LightstreamerStore.js
deleted file mode 100644
index 052c56a..0000000
--- a/dojox/store/LightstreamerStore.js
+++ /dev/null
@@ -1,204 +0,0 @@
-define([
-	"dojo/_base/lang",
-	"dojo/_base/array",
-	"dojo/_base/declare",
-	"dojo/_base/Deferred",
-	"dojo/store/util/QueryResults"
-], function(dojo){
-	dojo.getObject("store", true, dojox);
-	
-	//	NOTE: The usual Lightstreamer web client MUST be loaded to use this store,
-	//	and will not be wrapped as an AMD module for now.
-	var nextId = 0;
-
-	function translate(id, updateInfo, schema, o){
-		//	private function to convert the returned object from an update to a JSON-like object.
-		o = o || {};
-		dojo.forEach(schema, function(field){
-			o[field] = updateInfo.getNewValue(field);
-		});
-		if(!("id" in o)){ o["id"] = id; }
-		return o;
-	}
-
-/*=====
-dojox.store.LightstreamerStore.__queryOptionsArgs = function(dataAdapter, itemsRange, requestedBufferSize, requestedMaxFrequency, selector, snapshotRequired, commandLogic){
-	//	dataAdapter: String?
-	//		The data adapter to be used for a query.
-	//	itemsRange: Array?
-	//		The range of items in the form of [ start, end ] to receive back from Lightstreamer.
-	//	requestedBufferSize: Number?
-	//		The length of the internal queuing buffers to be used by the server.
-	//	requestedMaxFrequency: Number?
-	//		The maximum update frequency (updates per second) to be used by Lightstreamer.
-	//	selector: String?
-	//		The name of a selector, to be recognized by the Metadata Adapter in Lightstreamer.
-	//	snapshotRequired: Boolean?
-	//		Whether or not to request snapshot delivery.
-	//	commandLogic: Array?
-	//		An array of arguments in the following form: [ flag, commandPos, keyPos, underSchema, underDataAdapter ]
-
-	this.dataAdapter = dataAdapter;
-	this.itemsRange = itemsRange;
-	this.requestedBufferSize = requestedBufferSize;
-	this.requestedMaxFrequency = requestedMaxFrequency;
-	this.selector = selector;
-	this.snapshotRequired = snapshotRequired;
-	this.commandLogic = commandLogic;
-}
-=====*/
-
-	dojo.declare("dojox.store.LightstreamerStore", [], {
-		_index: {},	//	a cache for data objects returned
-
-		//	pushPage: (Lightstreamer)pushPage
-		//		The main connection created by the typical Lightstreamer Web Client
-		pushPage: null,
-
-		//	group: String[]
-		//		The group of items to be returned from the Lightstreamer Server.
-		group: [],
-
-		//	schema: String[]
-		//		The list of fields for each item you wish to get back from Lightstreamer
-		schema: [],
-
-		constructor: function(pushPage, group, schema, dataAdapter){
-			//	summary:
-			//		The constructor for the LightstreamerStore.
-			//	pushPage: pushPage
-			//		This is the pushPage created by using the typical Lightstreamer web client
-			//	dataAdapter: String
-			//		This is the data adapter to connect to (defined with the Lightstreamer server)
-			//	group: String[]
-			//		An array of the item names you wish to get back from Lightstreamer.
-			//	schema: String[]
-			//		The list of fields for each item you wish to get back from Lightstreamer.
-
-			this.pushPage = pushPage;
-			this.group = group;
-			this.schema = schema;
-			this.dataAdapter = dataAdapter || "DEFAULT";
-		},
-
-		query: function(query, options){
-			//	summary:
-			//		Start receiving streams from the Lightstreamer server.
-			//
-			//	description:
-			//		The main method of the LightstreamerStore, query opens up a data stream
-			//		from a Lightstreamer server (based on the pushPage definition used in the
-			//		constructor) and sets up a way to observe the returned results from said
-			//		stream.  It is based on Lightstreamer's NonVisualTable object, and by
-			//		default will run the return from the Lightstreamer server through a 
-			//		private "translate" function, which takes the updateInfo object normally
-			//		returned by Lightstreamer's web client and converts it into a straight
-			//		JSON-like object that can be used for data consumption.
-			//
-			//	query: String
-			//		The name of the mode to use for the resulting stream. (RAW, MERGE, COMMAND or DISTINCT)
-			//		
-			//	options: LightstreamerStore.__QueryOptionsArgs
-			//		Additional options to consume. See http://www.lightstreamer.com/docs/client_web_jsdoc/NonVisualTable.html
-			//		for more information on these properties. All properties are optional.
-			//
-			//	returns: dojo.store.util.QueryResults
-			//		A query results object that can be used to observe data being returned,
-			//		as well as stop the stream of data.  Note that this results object is
-			//		customized with an "observe" method and a "close" method; observe is the
-			//		main hook into the constant data stream returned by Lightstreamer, and
-			//		the close method will stop the query/stream.
-			//
-			//	example:
-			//		Query a server:
-			//	|	var results = myLSStore.query("MERGE", { dataAdapter: "QUOTE_ADAPTER", snapshotRequired: true });
-			//	|	results.observe(function(obj){
-			//	|		//	do something with obj
-			//	|	});
-
-			options = options || {};
-			var results = new dojo.Deferred(),
-				snapshotReceived,
-				resultsArray = [],
-				self = this,
-				id = "store-" + nextId++,
-				pushPage = this.pushPage,
-				table = new NonVisualTable(this.group, this.schema, query);
-        
-			if(!("dataAdapter" in options) && this.dataAdapter){
-				table.setDataAdapter(this.dataAdapter);
-			}
-
-			for(var prop in options) {
-				var setter = "set" + prop.charAt(0).toUpperCase() + prop.slice(1);
-				if(setter in table && dojo.isFunction(table[setter])){
-					table[setter][(dojo.isArray(options[prop])?"apply":"call")](table, options[prop]);
-				}
-			}
-        
-			table.onItemUpdate = function(id, updateInfo){
-				var obj = translate(id, updateInfo, self.schema, self._index[id]);
-				var newObject;
-				if(!self._index[id]){
-					newObject = true;
-					self._index[id] = obj;
-					if(!snapshotReceived){
-						resultsArray.push(obj);
-					}
-				}
-				table[snapshotReceived?"onPostSnapShot":"onPreSnapShot"](obj, newObject);
-			};
-
-			if(query == "MERGE" || options.snapshotRequired === false){
-				snapshotReceived = true;
-				results.resolve(resultsArray);
-			} else { // eventually properly handle other subscription modes
-				table.onEndOfSnapshot = function(){
-					snapshotReceived = true;
-					results.resolve(resultsArray);
-				};
-			}			
-
-			//	note that these need to be two separate function objects.
-			table.onPreSnapShot = function(){};
-			table.onPostSnapShot = function(){};
-
-			//	modify the deferred
-			results = dojo.store.util.QueryResults(results);
-
-			//	set up the two main ways of working with results
-			var foreachHandler;
-			results.forEach = function(callback){
-				foreachHandler = dojo.connect(table, "onPreSnapShot", callback);
-			};
-
-			var observeHandler;
-			results.observe = function(listener){
-				observeHandler = dojo.connect(table, "onPostSnapShot", function(object, newObject){
-					listener.call(results, object, newObject ? -1 : undefined);
-				});
-			};
-
-			//	set up the way to stop the stream
-			results.close = function(){
-				if(foreachHandler){ dojo.disconnect(foreachHandler); }
-				if(observeHandler){ dojo.disconnect(observeHandler); }
-				pushPage.removeTable(id);
-				table = null;
-			};
-
-			//	start up the stream
-			pushPage.addTable(table, id);
-			return results;
-		},
-		get: function(id){
-			//	summary:
-			//		Return a (cached) object from the Lightstreamer.
-			//	id: String
-			//		The identity of the object to retrieve.
-			return this._index[id];
-		}
-	});
-
-	return dojox.store.LightstreamerStore;
-});
diff --git a/dojox/store/README b/dojox/store/README
index 123a4e7..436a892 100644
--- a/dojox/store/README
+++ b/dojox/store/README
@@ -1,8 +1,8 @@
 -------------------------------------------------------------------------------
 DojoX Stores (data)
 -------------------------------------------------------------------------------
-Version 1.000
-Release date: 03/04/2011
+Version 1.8
+Release date: 06/13/2012
 -------------------------------------------------------------------------------
 Project state:
 LightstreamerStore:	beta
@@ -27,6 +27,11 @@ one to connect to a Lightstreamer server and get continuous updates (depending
 on the data adapter and mode used).  Because it requires the Lightstreamer
 server, unit tests are not functional here; there is a demonstration of it in 
 action (URL to be determined).
+
+Note, as of Dojo 1.8, the LightstreamerStore should now be downloaded either
+from their GitHub repository, or through CPM. The new version will work with
+Version 5 of their library, which is now fully AMD-compliant.
+
 -------------------------------------------------------------------------------
 Dependencies:
 
diff --git a/dojox/store/tests/test_LightstreamerStore.html b/dojox/store/tests/test_LightstreamerStore.html
deleted file mode 100644
index 99ef181..0000000
--- a/dojox/store/tests/test_LightstreamerStore.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<html>
-	<head>
-		<title>DojoX LightstreamerStore test</title>
-		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
-			@import "../../../dijit/tests/css/dijitTests.css";
-			.price {
-				font-weight: bold;
-			}
-		</style>
-		<script type="text/javascript" src="path/to/ls/commons/lightstreamer/lscommons.js"></script>
-		<script type="text/javascript" src="path/to/ls/commons/lightstreamer/lspushpage.js"></script>
-		<script type="text/javascript" src="path/to/ls/commons/custom/misc.js"></script>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
-		<script type="text/javascript">
-			dojo.require("dojox.store.LightstreamerStore");
-
-			var group = ["item1", "item2", "item3", "item4", "item5" ],
-				schema = [ "last_price", "stock_name" ];
-
-			dojo.ready(function(){
-				//	the following two lines are defined in misc.js; they are a part of the demo
-				//	code that comes with a default Lightstreamer server install.  Make sure the
-				//	paths in both functions point to the right place, just like with the three
-				//	script tag references above.
-				var pushPage = initializeDemoPushPage("path/to/ls/commons/custom/", true, null, null);
-				initializeDemoEngine(pushPage, "path/to/ls/commons/lightstreamer/", null);
-
-				//	The actual demonstration.
-				var stopHandler, store;
-				dojo.connect(dojo.byId("starter"), "onclick", function(e){
-					dojo.stopEvent(e);
-					if(!store){
-						store = new dojox.store.LightstreamerStore(pushPage, group, schema);
-					}
-
-					var results = store.query("MERGE", { dataAdapter: "QUOTE_ADAPTER" });
-					results.observe(function(o){
-						var d = dojo.byId("price-" + o.id);
-						if(!d){
-							var c = dojo.byId("resultContainer");
-							var div = dojo.create("div", { 
-								innerHTML: o.stock_name + ': <span class="price" id="price-' + o.id + '"></span>'
-							}, c);
-							d = dojo.byId("price-" + o.id);
-						}
-						d.innerHTML = o.last_price;
-					});
-
-					stopHandler = dojo.connect(dojo.byId("stopper"), "onclick", function(e){
-						dojo.stopEvent(e);
-						if(results){
-							results.close();
-						}
-						dojo.disconnect(stopHandler);
-					});
-				});
-			});
-		</script>
-	</head>
-	<body>
-		<h1>dojox.store.LightstreamerStore test</h1>
-		<p><strong>NOTE:</strong> You must have the Lightstreamer Web Client installed and included in this page.
-		When attempting to try this demo, change the three script lines in the head to include the right path,
-		and make sure you change the paths in the first two statements in the script block in the head.</p>
-		<div>
-			<div>Start and stop the stream from the Lightstreamer server:</div>
-			<input type="button" id="starter" value="start" />
-			<input type="button" id="stopper" value="stop" />
-		</div>
-		<h2>Results:</h2>
-		<div id="resultContainer"></div>
-	</body>
-</html>
diff --git a/dojox/string/BidiComplex.js b/dojox/string/BidiComplex.js
index 912aaca..c5ba151 100644
--- a/dojox/string/BidiComplex.js
+++ b/dojox/string/BidiComplex.js
@@ -311,5 +311,5 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "dojo/_base/array", "dojo/_base/
 		}
 		return segmentsPointers;
 	};
-	return dojox.string.BidiComplex;
+	return bdc;
 });
diff --git a/dojox/string/BidiEngine.js b/dojox/string/BidiEngine.js
index 3d3625a..47fd620 100644
--- a/dojox/string/BidiEngine.js
+++ b/dojox/string/BidiEngine.js
@@ -2,7 +2,7 @@ define(["dojo/_base/lang", "dojo/_base/declare"],
   function(lang,declare){
 lang.getObject("string", true, dojox);
 
-declare("dojox.string.BidiEngine", null, {
+var BidiEngine = declare("dojox.string.BidiEngine", null, {
 	// summary:
 	//		This class provides a bidi transformation engine, i.e.
 	//		functions for reordering and shaping bidi text.
@@ -14,28 +14,29 @@ declare("dojox.string.BidiEngine", null, {
 	//		Unicode Bidi Algorithm is not invoked or is not properly applied. This may occur in situation in which software
 	//		responsible for rendering the text is not leveraging Unicode Bidi Algorithm implemented by OS (e.g. dojox.GFX renderers).
 	//
-	//		Bidi engine provided in this class implements Unicode Bidi Algorithm as specified at:
-	//			http://www.unicode.org/reports/tr9/. 
+	//		Bidi engine provided in this class implements Unicode Bidi Algorithm as specified at
+	//		http://www.unicode.org/reports/tr9/.
 	//
-	//		For more information on basic Bidi concepts please read following article:
-	//			"Bidirectional script support - A primer" available from:
-	//				http://www.ibm.com/developerworks/websphere/library/techarticles/bidi/bidigen.html
+	//		For more information on basic Bidi concepts please read
+	//		"Bidirectional script support - A primer" available from
+	//		http://www.ibm.com/developerworks/websphere/library/techarticles/bidi/bidigen.html.
 	//
 	//		As of February 2011, Bidi engine has following limitations:
-	//			1. No support for following numeric shaping options: 
-	//				H - Hindi, 
-	//				C - Contextual, 
-	//				N - Nominal.
-	//			2. No support for following shaping options: 
-	//				I - Initial shaping, 
-	//				M - Middle shaping, 
-	//				F - Final shaping, 
-	//				B - Isolated shaping.
-	//			3. No support for source-to-target or/and target-to-source maps.
-	//			4. No support for LRE/RLE/LRO/RLO/PDF (they are handled like neutrals).
-	//			5. No support for Windows compatibility.
-	//			6. No support for  insert/remove marks.
-	//			7. No support for code pages (currently only UTF-8 is supported. Ideally we should convert from any code page to UTF-8).
+	//
+	//		1. No support for following numeric shaping options:
+	//		    - H - Hindi,
+	//		    - C - Contextual,
+	//		    - N - Nominal.
+	//		2. No support for following shaping options:
+	//		    - I - Initial shaping,
+	//		    - M - Middle shaping,
+	//		    - F - Final shaping,
+	//		    - B - Isolated shaping.
+	//		3. No support for source-to-target or/and target-to-source maps.
+	//		4. No support for LRE/RLE/LRO/RLO/PDF (they are handled like neutrals).
+	//		5. No support for Windows compatibility.
+	//		6. No support for  insert/remove marks.
+	//		7. No support for code pages (currently only UTF-8 is supported. Ideally we should convert from any code page to UTF-8).
 	
 	bidiTransform: function (/*String*/text, /*String*/formatIn, /*String*/formatOut){
 		// summary:
@@ -53,60 +54,65 @@ declare("dojox.string.BidiEngine", null, {
 		//		Possible and default values for each one of the letters are provided below:
 		//
 		//		First letter:
-		//			Letter position/index:	
-		//				1
-		//			Letter meaning:			
-		//				Ordering Schema.
-		//			Possible values:
-		//				I - Implicit (Logical).
-		//				V - Visual.
-		//			Default value:
-		//				I
+		//
+		//		- Letter position/index:
+		//			1
+		//		- Letter meaning:
+		//			Ordering Schema.
+		//		- Possible values:
+		//			- I - Implicit (Logical).
+		//			- V - Visual.
+		//		- Default value:
+		//			I
 		//
 		//		Second letter:
-		//			Letter position/index:	
-		//				2
-		//			Letter meaning:			
-		//				Orientation.
-		//			Possible values:
-		//				L - Left To Right.
-		//				R - Right To Left.
-		//				C - Contextual Left to Right.
-		//				D - Contextual Right to Left.
-		//			Default value:
-		//				L		
+		//
+		//		- Letter position/index:
+		//			2
+		//		- Letter meaning:
+		//			Orientation.
+		//		- Possible values:
+		//			- L - Left To Right.
+		//			- R - Right To Left.
+		//			- C - Contextual Left to Right.
+		//			- D - Contextual Right to Left.
+		//		- Default value:
+		//			L		
 		//
 		//		Third letter:
-		//			Letter position/index:	
-		//				3
-		//			Letter meaning:			
-		//				Symmetric Swapping.
-		//			Possible values:
-		//				Y - Symmetric swapping is on.
-		//				N - Symmetric swapping is off.
-		//			Default value:
-		//				Y		
+		//
+		//		- Letter position/index:
+		//			3
+		//		- Letter meaning:
+		//			Symmetric Swapping.
+		//		- Possible values:
+		//			- Y - Symmetric swapping is on.
+		//			- N - Symmetric swapping is off.
+		//		- Default value:
+		//			Y		
 		//
 		//		Fourth letter:
-		//			Letter position/index:	
-		//				4
-		//			Letter meaning:			
-		//				Shaping.
-		//			Possible values:
-		//				S - Text is shaped.
-		//				N - Text is not shaped.
-		//			Default value:
-		//				N				
+		//
+		//		- Letter position/index:
+		//			4
+		//		- Letter meaning:
+		//			Shaping.
+		//		- Possible values:
+		//			- S - Text is shaped.
+		//			- N - Text is not shaped.
+		//		- Default value:
+		//			N				
 		//
 		//		Fifth letter:
-		//			Letter position/index:	
-		//				5
-		//			Letter meaning:			
-		//				Numeric Shaping.
-		//			Possible values:
-		//				N - Nominal.
-		//			Default value:
-		//				N				
+		//
+		//		- Letter position/index:
+		//			5
+		//		- Letter meaning:
+		//			Numeric Shaping.
+		//		- Possible values:
+		//			- N - Nominal.
+		//		- Default value:
+		//			N				
 		//
 		//		The output of this function is original text (passed via first argument) transformed from input Bidi layout (second argument)
 		//		to output Bidi layout (last argument). 
@@ -115,7 +121,7 @@ declare("dojox.string.BidiEngine", null, {
 		//	|	mytext = bidiTransform("HELLO WORLD", "ILYNN", "VLYNN");
 		//		In this case, "HELLO WORLD" text is transformed from Logical - LTR to Visual - LTR Bidi layout with 
 		//		default values for symmetric swapping (Yes), shaping (Not shaped) and numeric shaping (Nominal).
-		// returns: /*String*/ or throws an exception.
+		// returns: String
 		//		Original text transformed from input Bidi layout (second argument)
 		//		to output Bidi layout (last argument).
 		//		Throws an exception if the bidi layout strings are not valid.
@@ -182,7 +188,7 @@ declare("dojox.string.BidiEngine", null, {
 		}
 	},
 	checkContextual: function(/*String*/text){
-		// summary: 	
+		// summary:
 		//		Determine the base direction of a bidi text according
 		//		to its first strong directional character.
 		// text: 
@@ -235,12 +241,12 @@ declare("dojox.string.BidiEngine", null, {
 
 function doBidiReorder(/*String*/text, /*String*/inFormat,
 						/*String*/outFormat, /*String*/swap){
-	// summary: 	
+	// summary:
 	//		Reorder the source text according to the bidi attributes
 	//		of source and result.
-	//	text:
+	// text:
 	//		The text to reorder.
-	//	inFormat:	
+	// inFormat:
 	//		Ordering scheme and base direction of the source text.
 	//		Can be "LLTR", "LRTL", "LCLR", "LCRL", "VLTR", "VRTL",
 	//		"VCLR", "VCRL".
@@ -252,11 +258,11 @@ function doBidiReorder(/*String*/text, /*String*/inFormat,
 	//		"CRL" means contextual direction defaulting to RTL if
 	//		there is no strong letter.
 	//		The initial value is "LLTR", if none, the initial value is used.
-	//	outFormat:	
+	// outFormat:
 	//		Required ordering scheme and base direction of the
 	//		result. Has the same format as inFormat.
 	//		If none, the initial value "VLTR" is used.
-	//	swap:
+	// swap:
 	//		Symmetric swapping attributes of source and result.
 	//		The allowed values can be "YN", "NY", "YY" and "NN".
 	//		The first letter reflects the symmetric swapping attribute
@@ -372,7 +378,7 @@ function doBidiReorder(/*String*/text, /*String*/inFormat,
 		return text;
 	}
 
-};
+}
 
 function shape(/*boolean*/rtl, /*String*/text, /*boolean*/compress){
 	// summary:
@@ -385,7 +391,8 @@ function shape(/*boolean*/rtl, /*String*/text, /*boolean*/compress){
 	// compress:
 	//		A flag indicates to insert extra space after the lam alef compression
 	//		to preserve the buffer size or not insert an extra space which will lead
-	//		to decrease the buffer size. this option can be:
+	//		to decrease the buffer size. This option can be:
+	//
 	//		- true (default) to not insert extra space after compressing Lam+Alef into one character Lamalef
 	//		- false to insert an extra space after compressed Lamalef to preserve the buffer size
 	// returns:
@@ -464,7 +471,8 @@ function shape(/*boolean*/rtl, /*String*/text, /*boolean*/compress){
 		}
 	}
 	return outBuf;
-};
+}
+
 function firstStrongDir(/*String*/text){
 	// summary:
 	//		Return the first strong character direction
@@ -475,7 +483,7 @@ function firstStrongDir(/*String*/text){
 	//		searching for first "strong" character. 
 	//		Returns if strong character was found with the direction defined by this 
 	//		character, if no strong character was found returns an empty string.
-	// returns: /*String*/
+	// returns: String
 	//		"ltr" - if the first strong character is Latin.
 	//		"rtl" - if the first strong character is RTL directed character.
 	//		"" - if the strong character wasn't found.
@@ -498,7 +506,8 @@ function firstStrongDir(/*String*/text){
 		}
 	}
 	return "";
-};
+}
+
 function lastStrongDir(text){
 	// summary:
 	//		Return the last strong character direction
@@ -525,7 +534,8 @@ function lastStrongDir(text){
 		}
 	}
 	return "";
-};
+}
+
 function deshape(/*String*/text, /*boolean*/rtl, /*boolean*/consume_next_space){
 	// summary:
 	//		deshape the source text.
@@ -539,7 +549,8 @@ function deshape(/*String*/text, /*boolean*/rtl, /*boolean*/consume_next_space){
 	//		the lam alef if there is a space followed the Lamalef character to preserve the buffer size. 
 	//		In case there is no space next to the lam alef the buffer size will be increased due to the
 	//		expansion of the lam alef one character into lam+alef two characters
-	// returns:	text deshaped.
+	// returns:
+	//		text deshaped.
 	if(text.length == 0){
 		return;
 	}
@@ -596,7 +607,8 @@ function deshape(/*String*/text, /*boolean*/rtl, /*boolean*/consume_next_space){
 		}
 	}
 	return outBuf;
-};
+}
+
 function doReorder(str){
 	// summary:
 	//		Helper to the doBidiReorder. Manages the UBA.
@@ -613,7 +625,8 @@ function doReorder(str){
 	invertLevel(2, chars, levels);
 	invertLevel(1, chars, levels);
 	return chars.join("");
-};
+}
+
 function computeLevels(chars, levels){
 	var len = chars.length
 		, impTab = bdx.dir ? impTab_RTL : impTab_LTR
@@ -679,7 +692,8 @@ function computeLevels(chars, levels){
 			}
 		}
 	}
-};
+}
+
 function swapChars(chars, levels){
 	// summary:
 	//		Swap characters with symmetrical mirroring as all kinds of parenthesis.
@@ -697,13 +711,14 @@ function swapChars(chars, levels){
 
 	if(bdx.hiLevel == 0 || bdx.swap.substr(0, 1) == bdx.swap.substr(1, 2)){
 		return;
-	};
+	}
 
 	//console.log("bdx.hiLevel == 0: " + bdx.hiLevel + "bdx.swap[0]: "+ bdx.swap[0] +" bdx.swap[1]: " +bdx.swap[1]);
 	for(var i = 0; i < chars.length; i++){
 		if(levels[i] == 1){chars[i] = getMirror(chars[i]);}
 	}
-};
+}
+
 function getCharacterType(ch){
 	// summary:
 	//		Return the type of the character.
@@ -718,7 +733,8 @@ function getCharacterType(ch){
 	var uc = ch.charCodeAt(0)
 		, hi = MasterTable[uc >> 8];
 	return (hi < TBBASE) ? hi : UnicodeTable[hi - TBBASE][uc & 0xFF];
-};
+}
+
 function invertStr(str){
 	// summary:
 	//		Return the reversed string.
@@ -731,7 +747,8 @@ function invertStr(str){
 	var chars = str.split("");
 	chars.reverse();
 	return chars.join("");
-};
+}
+
 function indexOf(cArray, cLength, idx){
 	var counter = -1;
 	for(var i = 0; i < cLength; i++){
@@ -740,7 +757,8 @@ function indexOf(cArray, cLength, idx){
 		}
 	}
 	return -1;
-};
+}
+
 function isArabicAlefbet(c){
 	for(var i = 0; i < ArabicAlefBetIntervalsBegine.length; i++){
 		if(c >= ArabicAlefBetIntervalsBegine[i] && c <= ArabicAlefBetIntervalsEnd[i]){
@@ -748,7 +766,8 @@ function isArabicAlefbet(c){
 		}
 	}
 	return false;
-};
+}
+
 function isNextArabic(str06, index, step, nIEnd){
 	while(((index) * step) < nIEnd && isArabicDiacritics(str06[index])){
 		index += step;
@@ -757,7 +776,8 @@ function isNextArabic(str06, index, step, nIEnd){
 		return true;
 	}
 	return false;
-};
+}
+
 function isNextAlef(str06, index, step, nIEnd){
 	while(((index) * step) < nIEnd && isArabicDiacritics(str06[index])){
 		index += step;
@@ -774,7 +794,8 @@ function isNextAlef(str06, index, step, nIEnd){
 		}
 	}
 	return false;
-};
+}
+
 function invertLevel(lev, chars, levels){
 	if(bdx.hiLevel < lev){
 		return;
@@ -799,7 +820,8 @@ function invertLevel(lev, chars, levels){
 		}
 		start++;
 	}
-};
+}
+
 function getCharClass(chars, types, classes, ix){
 	// summary:
 	//		Return the class if ix character in chars.
@@ -896,7 +918,8 @@ function getCharClass(chars, types, classes, ix){
 		case UBAT_BN:
 			return UBAT_ON;
 	}
-};
+}
+
 function getMirror(c){
 	// summary:
 	//		Calculates the mirrored character of c
@@ -917,7 +940,8 @@ function getMirror(c){
 		}
 	}
 	return c;
-};
+}
+
 function isStandAlonCharacter(c){
 	for(var i = 0; i < StandAlonForm.length; i++){
 		if(StandAlonForm[i] == c){
@@ -925,7 +949,8 @@ function isStandAlonCharacter(c){
 		}
 	}
 	return false;
-};
+}
+
 function getMedialFormCharacterFE(c){
 	for(var i = 0; i < BaseForm.length; i++){
 		if(c == BaseForm[i]){
@@ -933,7 +958,8 @@ function getMedialFormCharacterFE(c){
 		}
 	}
 	return c;
-};
+}
+
 function getFormCharacterFE(/*char*/ c, /*char[]*/formArr){
 	for(var i = 0; i < BaseForm.length; i++){
 		if(c == BaseForm[i]){
@@ -941,10 +967,12 @@ function getFormCharacterFE(/*char*/ c, /*char[]*/formArr){
 		}
 	}
 	return c;
-};
+}
+
 function isArabicDiacritics(c){
 	return	(c >= '\u064b' && c <= '\u0655') ? true : false;
-};
+}
+
 function getOrientation(/*Char*/ oc){
 	if(oc == 'L'){
 		return "LTR";
@@ -958,7 +986,8 @@ function getOrientation(/*Char*/ oc){
 	if(oc == 'D'){
 		return "CRL";
 	}
-};
+}
+
 function setAlefToSpace(str06, index, step, nIEnd){
 	while(((index) * step) < nIEnd && isArabicDiacritics(str06[index])){
 		index += step;
@@ -968,7 +997,8 @@ function setAlefToSpace(str06, index, step, nIEnd){
 		return true;
 	}
 	return false;
-};
+}
+
 function getLamAlefFE(alef06, LamAlefForm){
 	for(var i = 0; i < AlefTable.length; i++){
 		if(alef06 == AlefTable[i]){
@@ -976,7 +1006,8 @@ function getLamAlefFE(alef06, LamAlefForm){
 		}
 	}
 	return alef06;
-};
+}
+
 function LamAlef(alef){
 	// summary:
 	//		If the alef variable is an ARABIC ALEF letter,
@@ -995,7 +1026,7 @@ function LamAlef(alef){
 		}
 	}
 	return 0;
-};
+}
 
 var	bdx = {
 		dir: 0,
@@ -1502,5 +1533,5 @@ delete LRO;
 delete RLO;
 delete BN;
 
-return dojox.string.BidiEngine;
+return BidiEngine;
 });
diff --git a/dojox/string/Builder.js b/dojox/string/Builder.js
index 4ceb9c5..ed4c949 100644
--- a/dojox/string/Builder.js
+++ b/dojox/string/Builder.js
@@ -1,20 +1,21 @@
 define(["dojo/_base/lang"], 
   function(lang){
-	lang.getObject("string", true, dojox).Builder = 
+	var Builder = lang.getObject("string", true, dojox).Builder =
 	  function(/*String?*/str){
-		//	summary:
+		// summary:
 		//		A fast buffer for creating large strings.
-		//
-		//	length: Number
-		//		The current length of the internal string.
 
 		//	N.B. the public nature of the internal buffer is no longer
 		//	needed because the IE-specific fork is no longer needed--TRT.
 		var b = "";
+
+		// length: Number
+		//		The current length of the internal string.
 		this.length = 0;
 		
 		this.append = function(/* String... */s){
-			// summary: Append all arguments to the end of the buffer
+			// summary:
+			//		Append all arguments to the end of the buffer
 			if(arguments.length>1){
 				/*
 					This is a loop unroll was designed specifically for Firefox;
@@ -68,13 +69,13 @@ define(["dojo/_base/lang"],
 		};
 		
 		this.concat = function(/*String...*/s){
-			//	summary:
+			// summary:
 			//		Alias for append.
 			return this.append.apply(this, arguments);	//	dojox.string.Builder
 		};
 		
 		this.appendArray = function(/*Array*/strings) {
-			//	summary:
+			// summary:
 			//		Append an array of items to the internal buffer.
 
 			//	Changed from String.prototype.concat.apply because of IE.
@@ -82,7 +83,7 @@ define(["dojo/_base/lang"],
 		};
 		
 		this.clear = function(){
-			//	summary:
+			// summary:
 			//		Remove all characters from the buffer.
 			b = "";
 			this.length = 0;
@@ -90,7 +91,7 @@ define(["dojo/_base/lang"],
 		};
 		
 		this.replace = function(/* String */oldStr, /* String */ newStr){
-			// 	summary:
+			// summary:
 			//		Replace instances of one string with another in the buffer.
 			b = b.replace(oldStr,newStr);
 			this.length = b.length;
@@ -98,7 +99,7 @@ define(["dojo/_base/lang"],
 		};
 		
 		this.remove = function(/* Number */start, /* Number? */len){
-			//	summary:
+			// summary:
 			//		Remove len characters starting at index start.  If len
 			//		is not provided, the end of the string is assumed.
 			if(len===undefined){ len = b.length; }
@@ -109,7 +110,7 @@ define(["dojo/_base/lang"],
 		};
 		
 		this.insert = function(/* Number */index, /* String */str){
-			//	summary:
+			// summary:
 			//		Insert string str starting at index.
 			if(index == 0){
 				b = str + b;
@@ -121,7 +122,7 @@ define(["dojo/_base/lang"],
 		};
 		
 		this.toString = function(){
-			//	summary:
+			// summary:
 			//		Return the string representation of the internal buffer.
 			return b;	//	String
 		};
@@ -129,5 +130,5 @@ define(["dojo/_base/lang"],
 		//	initialize the buffer.
 		if(str){ this.append(str); }
 	};
-	return dojox.string.Builder;
+	return Builder;
 });
diff --git a/dojox/string/sprintf.js b/dojox/string/sprintf.js
index 7da4fc3..68ece3d 100644
--- a/dojox/string/sprintf.js
+++ b/dojox/string/sprintf.js
@@ -304,8 +304,8 @@ define([
 					throw new Error("format argument '" + token.arg + "' not a float; parseFloat returned " + f);
 				}
 				// C99 says that for 'f':
-				//   infinity -> '[-]inf' or '[-]infinity' ('[-]INF' or '[-]INFINITY' for 'F')
-				//   NaN -> a string  starting with 'nan' ('NAN' for 'F')
+				//	 infinity -> '[-]inf' or '[-]infinity' ('[-]INF' or '[-]INFINITY' for 'F')
+				//	 NaN -> a string  starting with 'nan' ('NAN' for 'F')
 				// this is not commonly implemented though.
 				//return '' + f;
 				f = 0;
diff --git a/dojox/string/tests/BuilderArguments.html b/dojox/string/tests/BuilderArguments.html
index 6d49866..a5f4c3b 100644
--- a/dojox/string/tests/BuilderArguments.html
+++ b/dojox/string/tests/BuilderArguments.html
@@ -3,7 +3,7 @@
 <html>
   <head>
     <title>Builder Perf Arguments Tests</title>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
     <script type="text/javascript" src="../Builder.js"></script>
     <script type="text/javascript" src="lipsum.js"></script>
     <script type="text/javascript">
diff --git a/dojox/string/tests/PerfFun.html b/dojox/string/tests/PerfFun.html
index f317428..afe7374 100644
--- a/dojox/string/tests/PerfFun.html
+++ b/dojox/string/tests/PerfFun.html
@@ -3,7 +3,7 @@
 <html>
   <head>
     <title>Perf Tests</title>
-    <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true"></script>
+    <script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true"></script>
     <script type="text/javascript" src="lipsum.js"></script>
     <script type="text/javascript">
     dojo.addOnLoad(function(){
diff --git a/dojox/string/tests/test_BidiComplex.html b/dojox/string/tests/test_BidiComplex.html
index aee94e2..22765af 100644
--- a/dojox/string/tests/test_BidiComplex.html
+++ b/dojox/string/tests/test_BidiComplex.html
@@ -3,7 +3,7 @@
 		<title></title>
 		<meta name="vs_snapToGrid" content="True">
 		<meta name="vs_showGrid" content="True">
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 		<script language="javascript" type="text/javascript">
 			dojo.require("dojox.string.BidiComplex");
 			
diff --git a/dojox/testing/DocTest.js b/dojox/testing/DocTest.js
index 27de034..81570b8 100644
--- a/dojox/testing/DocTest.js
+++ b/dojox/testing/DocTest.js
@@ -1,12 +1,12 @@
 define("dojox/testing/DocTest", ["dojo/string"], function() {
 
-dojo.declare(
+return dojo.declare(
 	"dojox.testing.DocTest",
 	null,
 	{
-		//	summary:
+		// summary:
 		//		This class executes doctests.
-		//	description:
+		// description:
 		//		DocTests are tests that are defined inside the comment.
 		//		A doctest looks as if it was copied from the shell (which it mostly is).
 		//		A doctest is executed when the following conditions match:
@@ -56,9 +56,10 @@ dojo.declare(
 		errors: [],
 		
 		getTests:function(/*String*/moduleName){
-			// summary: Extract the tests from the given module or string.
+			// summary:
+			//		Extract the tests from the given module or string.
 			// examples:
-			// 		>>> dojo.isArray(new dojox.testing.DocTest().getTests("dojox.testing.DocTest")) // Use the module name to extract the tests from.
+			//		>>> dojo.isArray(new dojox.testing.DocTest().getTests("dojox.testing.DocTest")) // Use the module name to extract the tests from.
 			//		true
 			var path = dojo.moduleUrl(moduleName).path;
 			// TODO:
@@ -79,8 +80,10 @@ dojo.declare(
 		},
 		
 		_getTestsFromString:function(/*String*/data, /*Boolean*/insideComments){
-			// summary: Parse the given string for tests.
-			// insideComments: Boolean, if false "data" contains only the pure tests, comments already stripped.
+			// summary:
+			//		Parse the given string for tests.
+			// insideComments: Boolean
+			//		if false "data" contains only the pure tests, comments already stripped.
 			var trim = dojo.hitch(dojo.string, "trim");
 			var lines = data.split("\n");
 			var len = lines.length;
@@ -149,9 +152,9 @@ dojo.declare(
 		},
 		
 		run: function(moduleName){
-			//	summary:
+			// summary:
 			//		Run the doctests in the module given.
-			//	example:
+			// example:
 			//		doctest = new dojox.testing.DocTest();
 			//		doctest.run("dojox.testing.DocTest");
 			//		doctest.errors should finally be an empty array.
@@ -186,10 +189,10 @@ dojo.declare(
 		},
 		
 		_run: function(/*Array*/tests){
-			//	summary:
+			// summary:
 			//		Each element in the array contains the test in the first element,
 			//		and the expected result in the second element.
-			//	tests:
+			// tests:
 			//		Make sure that the types are compared properly. There used to be
 			//		the bug that a return value false was compared to "false" which
 			//		made the test fail. This is fixed and should be verified by the
@@ -275,5 +278,4 @@ dojo.declare(
 	}
 );
 
-return dojox.testing.DocTest;
 });
\ No newline at end of file
diff --git a/dojox/timing.js b/dojox/timing.js
index b595ef3..8fc02de 100644
--- a/dojox/timing.js
+++ b/dojox/timing.js
@@ -1,3 +1,10 @@
 define(["./timing/_base"], function(timing){
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/timing modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
 	return timing;
 });
diff --git a/dojox/timing/Sequence.js b/dojox/timing/Sequence.js
index abc0116..4741c41 100644
--- a/dojox/timing/Sequence.js
+++ b/dojox/timing/Sequence.js
@@ -6,7 +6,8 @@ define([
 	"./_base"
 ], function(dojo){
 	dojo.experimental("dojox.timing.Sequence");
-	dojo.declare("dojox.timing.Sequence", null, {
+
+	return dojo.declare("dojox.timing.Sequence", null, {
 		// summary:
 		//	This class provides functionality to really sequentialize
 		//	function calls. You need to provide a list of functions and
@@ -44,8 +45,8 @@ define([
 		},
 
 		go: function(/* Array */defs, /* Function|Array? */doneFunction){
-			// summary: Run the passed sequence definition
-			//
+			// summary:
+			//		Run the passed sequence definition
 			// defs: Array
 			//		The sequence of actions
 			// doneFunction: Function|Array?
@@ -73,7 +74,8 @@ define([
 		},
 
 		_go: function(){
-			// summary: Execute one task of this._defsResolved.
+			// summary:
+			//		Execute one task of this._defsResolved.
 
 			// if _running was set to false stop the sequence, this is the
 			// case when i.e. stop() was called.
@@ -127,7 +129,8 @@ define([
 		},
 
 		goOn: function(){
-			// summary: This method just provides a hook from the outside, so that
+			// summary:
+			//		This method just provides a hook from the outside, so that
 			//		an interrupted sequence can be continued.
 			if(this._goOnPause){
 				setTimeout(dojo.hitch(this, "_go"), this._goOnPause);
@@ -136,8 +139,8 @@ define([
 		},
 
 		stop: function(){
-			// summary:  Stop the currently running sequence.
-			//
+			// summary:
+			//		Stop the currently running sequence.
 			// description:
 			//		This can only interrupt the sequence not the last function that
 			//		had been started. If the last function was i.e. a slideshow
@@ -150,5 +153,4 @@ define([
 		}
 
 	});
-	return dojox.timing.Sequence;
 });
diff --git a/dojox/timing/Streamer.js b/dojox/timing/Streamer.js
index 12d90ba..08ab563 100644
--- a/dojox/timing/Streamer.js
+++ b/dojox/timing/Streamer.js
@@ -1,21 +1,26 @@
 define(["./_base"], function(){
 	dojo.experimental("dojox.timing.Streamer");
-	dojox.timing.Streamer = function(
+
+	return dojox.timing.Streamer = function(
 		/* function */input,
 		/* function */output,
 		/* int */interval,
 		/* int */minimum,
 		/* array */initialData
 	){
-		//	summary
-		//	Streamer will take an input function that pushes N datapoints into a
+		// summary:
+		//		Streamer will take an input function that pushes N datapoints into a
 		//		queue, and will pass the next point in that queue out to an
 		//		output function at the passed interval; this way you can emulate
 		//		a constant buffered stream of data.
-		//	input: the function executed when the internal queue reaches minimumSize
-		//	output: the function executed on internal tick
-		//	interval: the interval in ms at which the output function is fired.
-		//	minimum: the minimum number of elements in the internal queue.
+		// input:
+		//		the function executed when the internal queue reaches minimumSize
+		// output:
+		//		the function executed on internal tick
+		// interval:
+		//		the interval in ms at which the output function is fired.
+		// minimum:
+		//		the minimum number of elements in the internal queue.
 
 		var self = this;
 		var queue = [];
@@ -53,7 +58,7 @@ define(["./_base"], function(){
 		};
 
 		this.setInterval = function(/* int */ms){
-			//	summary
+			// summary:
 			//	sets the interval in milliseconds of the internal timer
 			this.interval = ms;
 			timer.setInterval(ms);
@@ -62,7 +67,7 @@ define(["./_base"], function(){
 		this.onTick = function(/* dojox.timing.Streamer */obj){ };
 		// wrap the timer functions so that we can connect to them if needed.
 		this.start = function(){
-			//	summary
+			// summary:
 			//	starts the Streamer
 			if(typeof(this.inputFunction) == "function" && typeof(this.outputFunction) == "function"){
 				timer.start();
@@ -72,7 +77,7 @@ define(["./_base"], function(){
 		};
 		this.onStart = function(){ };
 		this.stop = function(){
-			//	summary
+			// summary:
 			//	stops the Streamer
 			timer.stop();
 		};
@@ -86,5 +91,4 @@ define(["./_base"], function(){
 			queue.concat(initialData);
 		}
 	};
-	return dojox.timing.Streamer;
 });
diff --git a/dojox/timing/ThreadPool.js b/dojox/timing/ThreadPool.js
index 51bc186..65263b8 100644
--- a/dojox/timing/ThreadPool.js
+++ b/dojox/timing/ThreadPool.js
@@ -73,7 +73,7 @@ define(["./_base"], function(){
 		this.getMaxThreads=function(){ return maxThreads; };
 		this.getAvailableThreads=function(){ return availableThreads; };
 		this.getTickInterval=function(){ return interval; };
-		this.queueUserWorkItem=function(/* Function || dojox.timing.Thread */fn){
+		this.queueUserWorkItem=function(/* Function|dojox/timing/Thread */fn){
 			var item=fn;
 			if(item instanceof Function){
 				item=new t.Thread(item);
@@ -92,7 +92,7 @@ define(["./_base"], function(){
 			}
 			return true;
 		};
-		this.removeQueuedUserWorkItem=function(/* Function || dojox.timing.Thread */item){
+		this.removeQueuedUserWorkItem=function(/* Function|dojox/timing/Thread */item){
 			if(item instanceof Function){
 				var idx=-1;
 				for(var i=0; i<queue.length; i++){
diff --git a/dojox/timing/_base.js b/dojox/timing/_base.js
index 3a7ffc7..ec02cab 100644
--- a/dojox/timing/_base.js
+++ b/dojox/timing/_base.js
@@ -3,9 +3,11 @@ define(["dojo/_base/kernel", "dojo/_base/lang"], function(dojo){
 	dojo.getObject("timing", true, dojox);
 
 	dojox.timing.Timer = function(/*int*/ interval){
-		// summary: Timer object executes an "onTick()" method repeatedly at a specified interval.
-		//			repeatedly at a given interval.
-		// interval: Interval between function calls, in milliseconds.
+		// summary:
+		//		Timer object executes an "onTick()" method repeatedly at a specified interval.
+		//		repeatedly at a given interval.
+		// interval:
+		//		Interval between function calls, in milliseconds.
 		this.timer = null;
 		this.isRunning = false;
 		this.interval = interval;
@@ -16,12 +18,15 @@ define(["dojo/_base/kernel", "dojo/_base/lang"], function(dojo){
 
 	dojo.extend(dojox.timing.Timer, {
 		onTick: function(){
-			// summary: Method called every time the interval passes.  Override to do something useful.
+			// summary:
+			//		Method called every time the interval passes.  Override to do something useful.
 		},
 			
 		setInterval: function(interval){
-			// summary: Reset the interval of a timer, whether running or not.
-			// interval: New interval, in milliseconds.
+			// summary:
+			//		Reset the interval of a timer, whether running or not.
+			// interval:
+			//		New interval, in milliseconds.
 			if (this.isRunning){
 				window.clearInterval(this.timer);
 			}
@@ -32,10 +37,12 @@ define(["dojo/_base/kernel", "dojo/_base/lang"], function(dojo){
 		},
 		
 		start: function(){
-			// summary: Start the timer ticking.
-			// description: Calls the "onStart()" handler, if defined.
-			// 				Note that the onTick() function is not called right away,
-			//				only after first interval passes.
+			// summary:
+			//		Start the timer ticking.
+			// description:
+			//		Calls the "onStart()" handler, if defined.
+			//		Note that the onTick() function is not called right away,
+			//		only after first interval passes.
 			if (typeof this.onStart == "function"){
 				this.onStart();
 			}
@@ -44,8 +51,10 @@ define(["dojo/_base/kernel", "dojo/_base/lang"], function(dojo){
 		},
 		
 		stop: function(){
-			// summary: Stop the timer.
-			// description: Calls the "onStop()" handler, if defined.
+			// summary:
+			//		Stop the timer.
+			// description:
+			//		Calls the "onStop()" handler, if defined.
 			if (typeof this.onStop == "function"){
 				this.onStop();
 			}
diff --git a/dojox/timing/doLater.js b/dojox/timing/doLater.js
index 61b23ee..3762e1c 100644
--- a/dojox/timing/doLater.js
+++ b/dojox/timing/doLater.js
@@ -1,8 +1,6 @@
 define(["./_base"], function(dxt){
 	dojo.experimental("dojox.timing.doLater");
-/*=====
-var dxt = dojox.timing;
-=====*/
+
 	dxt.doLater = function(/*anything*/conditional,/*Object ?*/context, /* Number ? */interval){
 		// summary:
 		//		Check if a parameter is ready, and if not,
@@ -11,26 +9,25 @@ var dxt = dojox.timing;
 		//		It thens calls the caller with original
 		//		arguments, using the supplied context or
 		//		window.
-		//	description:
+		// description:
 		//		dojox.timing.doLater(conditional) is testing if the call
 		//		should be done later. So it returns
 		//		true if the param is false.
-		//	arguments:
-		//		conditional: anything
-		//			Can be a property that eventually gets set, or
-		//			an expression, method... anything that can be
-		//			evaluated.
-		//		context:	Object
-		//			The namespace where the call originated.
-		//			Defaults to global and anonymous functions
-		//		interval:	Number
-		//			Poll time to check conditional in Milliseconds
+		// conditional: anything
+		//		Can be a property that eventually gets set, or
+		//		an expression, method... anything that can be
+		//		evaluated.
+		// context:	Object
+		//		The namespace where the call originated.
+		//		Defaults to global and anonymous functions
+		// interval:	Number
+		//		Poll time to check conditional in Milliseconds
 		// example:
-		//		| setTimeout(function(){
-		//		| 		if(dojox.timing.doLater(app.ready)){return;}
-		//		| 		console.log("Code is ready! anonymous.function SUCCESS")
-		//		| 	},700);
-		//
+		//	| setTimeout(function(){
+		//	| 		if(dojox.timing.doLater(app.ready)){return;}
+		//	| 		console.log("Code is ready! anonymous.function SUCCESS")
+		//	| 	},700);
+
 		if(conditional){ return false; }  // Boolean
 		var callback = dxt.doLater.caller,
 			args = dxt.doLater.caller.arguments;
diff --git a/dojox/timing/tests/test_Sequence.html b/dojox/timing/tests/test_Sequence.html
index 5f93e59..8f285bd 100644
--- a/dojox/timing/tests/test_Sequence.html
+++ b/dojox/timing/tests/test_Sequence.html
@@ -10,7 +10,7 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true" ></script>
 	<!--
 	<script type="text/javascript" src="../Sequence.js"></script>
 	-->
diff --git a/dojox/timing/tests/test_ThreadPool.html b/dojox/timing/tests/test_ThreadPool.html
index 8328df2..4942d31 100644
--- a/dojox/timing/tests/test_ThreadPool.html
+++ b/dojox/timing/tests/test_ThreadPool.html
@@ -1,7 +1,7 @@
 <html>
 	<head>
 		<title>Quick Thread Pool Test</title>
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true" ></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true" ></script>
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
 		</style>
diff --git a/dojox/timing/tests/test_doLater.html b/dojox/timing/tests/test_doLater.html
index d2cfe1a..e89a343 100644
--- a/dojox/timing/tests/test_doLater.html
+++ b/dojox/timing/tests/test_doLater.html
@@ -6,7 +6,7 @@
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
-    <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true" ></script>
+    <script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true" ></script>
     <script>
        dojo.require("dojox.timing.doLater");
 		
diff --git a/dojox/treemap/DrillDownUp.js b/dojox/treemap/DrillDownUp.js
new file mode 100644
index 0000000..0a2a3f2
--- /dev/null
+++ b/dojox/treemap/DrillDownUp.js
@@ -0,0 +1,125 @@
+define(["dojo/_base/lang", "dojo/_base/event", "dojo/_base/declare", "dojo/on", "dojo/dom-geometry", "dojo/dom-construct",
+	"dojo/dom-style", "dojo/_base/fx", "dojo/has!touch?dojox/gesture/tap"],
+	function(lang, event, declare, on, domGeom, domConstruct, domStyle, fx, tap){
+
+	return declare("dojox.treemap.DrillDownUp", null, {
+		// summary:
+		//		Specializes TreeMap to support drill down and up operations.
+
+		postCreate: function(){
+			this.inherited(arguments);
+			this.own(on(this.domNode, "dblclick", lang.hitch(this, this._onDoubleClick)));
+			if(tap){
+				this.own(on(this.domNode, tap.doubletap, lang.hitch(this, this._onDoubleClick)));
+			}
+		},
+
+		_onDoubleClick: function(e){
+			var renderer = this._getRendererFromTarget(e.target);
+			if(renderer.item){
+				var item = renderer.item;
+				if(this._isLeaf(item)){
+					// walk up
+					item = renderer.parentItem;
+					renderer = this.itemToRenderer[this.getIdentity(item)];
+					// our leaf parent is the root, we can't do much...
+					if(renderer == null){
+						return;
+					}
+				}
+				// Drill up
+				if(this.rootItem == item){
+					this.drillUp(renderer);
+				}else{
+					this.drillDown(renderer);
+				}
+				event.stop(e);
+			}
+		},
+
+		drillUp: function(renderer){
+			// summary:
+			//		Drill up from the given renderer.
+			// renderer: DomNode
+			//		The item renderer.
+			var item = renderer.item;
+
+			// Remove the current rootItem renderer
+			// rebuild the tree map
+			// and animate the old renderer before deleting it.
+
+			this.domNode.removeChild(renderer);
+			var parent = this._getRenderer(item).parentItem;
+			this.set("rootItem", parent);
+			this.validateRendering(); // Must call this to create the treemap now
+
+			// re-add the old renderer to show the animation
+			domConstruct.place(renderer, this.domNode);
+
+			domStyle.set(renderer, "zIndex", 40);
+
+			var finalBox = domGeom.position(this._getRenderer(item), true);
+			var corner = domGeom.getMarginBox(this.domNode);
+
+			fx.animateProperty({
+				node: renderer, duration: 500, properties: {
+					left: {
+						end: finalBox.x - corner.l
+					}, top: {
+						end: finalBox.y - corner.t
+					}, height: {
+						end: finalBox.h
+					}, width: {
+						end: finalBox.w
+					}
+				}, onAnimate: lang.hitch(this, function(values){
+					var box = domGeom.getContentBox(renderer);
+					this._layoutGroupContent(renderer, box.w, box.h, renderer.level + 1, false, true);
+				}), onEnd: lang.hitch(this, function(){
+					this.domNode.removeChild(renderer);
+				})
+			}).play();
+		},
+
+		drillDown: function(renderer){
+			// summary:
+			//		Drill up from the given renderer.
+			// renderer: DomNode
+			//		The item renderer.
+			var box = domGeom.getMarginBox(this.domNode);
+			var item = renderer.item;
+
+			// Set the new root item into the rootPanel to make it appear on top
+			// of the other nodes, and keep the same global location
+			var parentNode = renderer.parentNode;
+			var spanInfo = domGeom.position(renderer, true);
+			parentNode.removeChild(renderer);
+			domConstruct.place(renderer, this.domNode);
+			domStyle.set(renderer, {
+				left: (spanInfo.x - box.l)+ "px", top: (spanInfo.y - box.t)+ "px"
+			});
+			var zIndex = domStyle.get(renderer, "zIndex");
+			domStyle.set(renderer, "zIndex", 40);
+
+			fx.animateProperty({
+				node: renderer, duration: 500, properties: {
+					left: {
+						end: box.l
+					}, top: {
+						end: box.t
+					}, height: {
+						end: box.h
+					}, width: {
+						end: box.w
+					}
+				}, onAnimate: lang.hitch(this, function(values){
+					var box2 = domGeom.getContentBox(renderer);
+					this._layoutGroupContent(renderer, box2.w, box2.h, renderer.level + 1, false);
+				}), onEnd: lang.hitch(this, function(){
+					domStyle.set(renderer, "zIndex", zIndex);
+					this.set("rootItem", item);
+				})
+			}).play();
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/treemap/GroupLabel.js b/dojox/treemap/GroupLabel.js
new file mode 100644
index 0000000..9a57bc8
--- /dev/null
+++ b/dojox/treemap/GroupLabel.js
@@ -0,0 +1,42 @@
+define(["dojo/_base/declare", "dojo/dom-construct", "dojo/dom-style"],
+	function(declare, domConstruct, domStyle) {
+
+	return declare("dojox.treemap.GroupLabel", null, {
+		// summary:
+		//		Specializes TreeMap to remove leaf labels and display group labels centered on group
+		//		content instead of display them in headers.
+
+		createRenderer: function(item, level, kind){
+			var renderer = this.inherited(arguments);
+			if(kind == "content" || kind == "leaf"){
+				var p = domConstruct.create("div");
+				domStyle.set(p, {
+					"zIndex": 30,
+					"position": "relative",
+					"height": "100%",
+					"textAlign": "center",
+					"top": "50%",
+					"marginTop": "-.5em"
+				});
+				domConstruct.place(p, renderer);
+			}
+			return renderer;
+		},
+
+		styleRenderer: function(renderer, item, level, kind){
+			switch(kind){
+				case "leaf":
+					domStyle.set(renderer, "background", this.getColorForItem(item).toHex());
+				case "content":
+					if(level == 0){
+						renderer.firstChild.innerHTML = this.getLabelForItem(item);
+					}else{
+						renderer.firstChild.innerHTML = null;
+					}
+					break;
+				case "header":
+					domStyle.set(renderer, "display", "none");
+			}
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/treemap/Keyboard.js b/dojox/treemap/Keyboard.js
new file mode 100644
index 0000000..752a56b
--- /dev/null
+++ b/dojox/treemap/Keyboard.js
@@ -0,0 +1,98 @@
+define(["dojo/_base/array", "dojo/_base/lang", "dojo/_base/event", "dojo/_base/declare", "dojo/on", "dojo/keys", "dojo/dom-attr",
+	"./_utils", "dijit/_FocusMixin"],
+	function(arr, lang, event, declare, on, keys, domAttr, utils, _FocusMixin){
+
+	return declare("dojox.treemap.Keyboard", _FocusMixin, {
+		// summary:
+		//		Specializes TreeMap to support keyboard navigation and accessibility.
+		
+		// tabIndex: String
+		//		Order fields are traversed when user hits the tab key
+		tabIndex: "0",
+		_setTabIndexAttr: "domNode",
+			
+		constructor: function(){
+		},
+		
+		postCreate: function(){
+			this.inherited(arguments);
+			this.own(on(this.domNode, "keydown", lang.hitch(this, this._onKeyDown)));
+			this.own(on(this.domNode, "mousedown", lang.hitch(this, this._onMouseDown)));
+		},
+
+		createRenderer: function(item, level, kind){
+			var renderer = this.inherited(arguments);
+			// on Firefox we need a tabindex on sub divs to let the keyboard event be dispatched
+			// put -1 so that it is not tablable
+			domAttr.set(renderer, "tabindex", "-1");
+			return renderer;
+		},
+		
+		_onMouseDown: function(e){
+			this.domNode.focus();
+		},
+	
+		_onKeyDown: function(e){
+			var selected = this.get("selectedItem");
+			if(!selected){
+				// nothing selected selected we can't navigate
+				return;
+			}
+			var renderer = this.itemToRenderer[this.getIdentity(selected)];
+			var parent = renderer.parentItem;
+			var children, childrenI, selectedI;
+			// we also need items to be sorted out
+			if(e.keyCode != keys.UP_ARROW && e.keyCode != keys.NUMPAD_MINUS &&
+				e.keyCode != keys.NUMPAD_PLUS){
+				children = (e.keyCode == keys.DOWN_ARROW)?selected.children:parent.children;
+				if(children){
+					childrenI = utils.initElements(children, lang.hitch(this,
+						this._computeAreaForItem)).elements;
+					selectedI = childrenI[arr.indexOf(children, selected)];
+					childrenI.sort(function(a, b){
+						return b.size - a.size;
+					});
+				}else{
+					return;
+				}
+			}
+			var newSelected;
+			switch(e.keyCode){
+				case keys.LEFT_ARROW:
+				newSelected = children[childrenI[Math.max(0, arr.indexOf(childrenI, selectedI)-1)].index];				
+				break;
+				case keys.RIGHT_ARROW:
+				newSelected = children[childrenI[Math.min(childrenI.length-1, arr.indexOf(childrenI, selectedI)+1)].index];								
+				break;
+				case keys.DOWN_ARROW:
+				newSelected = children[childrenI[0].index];
+				break;
+				case keys.UP_ARROW:
+				newSelected = parent;
+				break;
+				// TODO
+				//case "+":
+				case keys.NUMPAD_PLUS:
+				if(!this._isLeaf(selected) && this.drillDown){
+					this.drillDown(renderer);
+					event.stop(e);
+				}
+				break;
+				// TODO
+				//case "-":
+				case keys.NUMPAD_MINUS:
+				if(!this._isLeaf(selected) && this.drillUp){
+					this.drillUp(renderer);
+					event.stop(e);
+				}
+				break;
+			}
+			if(newSelected){
+				if(!this._isRoot(newSelected)){
+					this.set("selectedItem", newSelected);
+					event.stop(e);
+				}
+			}
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/treemap/README b/dojox/treemap/README
new file mode 100644
index 0000000..6979231
--- /dev/null
+++ b/dojox/treemap/README
@@ -0,0 +1,18 @@
+-------------------------------------------------------------------------------
+dojox.treemap
+-------------------------------------------------------------------------------
+Project state: stable
+-------------------------------------------------------------------------------
+Credits:
+	Christophe Jolif (cjolif)
+	Robert Dupuy
+-------------------------------------------------------------------------------
+Project description:
+Treemap widget for Dojo 1.8+
+-------------------------------------------------------------------------------
+Dependencies:
+Dojo Core, Dijit, dojox.color, dojox.widget, dojox.gesture
+-------------------------------------------------------------------------------
+Documentation:
+    http://docs.dojocampus.org/dojox/treemap
+-------------------------------------------------------------------------------
diff --git a/dojox/treemap/ScaledLabel.js b/dojox/treemap/ScaledLabel.js
new file mode 100644
index 0000000..9ec8ec5
--- /dev/null
+++ b/dojox/treemap/ScaledLabel.js
@@ -0,0 +1,56 @@
+define(["dojo/_base/declare", "dojo/dom-geometry", "dojo/dom-construct", "dojo/dom-style"],
+	function(declare, domGeom, domConstruct, domStyle) {
+
+	return declare("dojox.treemap.ScaledLabel", null, {
+		// summary:
+		//		Specializes TreeMap to display scaled leaf labels instead of constant size labels.
+
+		onRendererUpdated: function(evt){
+			if(evt.kind == "leaf"){
+				var renderer = evt.renderer;
+				// start back with default size
+				var oldSize = domStyle.get(renderer, "fontSize");
+				domStyle.set(renderer.firstChild, "fontSize", oldSize);
+				oldSize = parseInt(oldSize);
+				var hRatio = 0.75 * domGeom.getContentBox(renderer).w / domGeom.getMarginBox(renderer.firstChild).w;
+				var vRatio = domGeom.getContentBox(renderer).h  / domGeom.getMarginBox(renderer.firstChild).h;
+				var hDiff = domGeom.getContentBox(renderer).w - domGeom.getMarginBox(renderer.firstChild).w;
+				var vDiff = domGeom.getContentBox(renderer).h - domGeom.getMarginBox(renderer.firstChild).h;
+				var newSize = Math.floor(oldSize * Math.min(hRatio, vRatio));
+				while(vDiff > 0 && hDiff > 0){
+					domStyle.set(renderer.firstChild, "fontSize", newSize + "px");
+					hDiff = domGeom.getContentBox(renderer).w - domGeom.getMarginBox(renderer.firstChild).w;
+					vDiff = domGeom.getContentBox(renderer).h - domGeom.getMarginBox(renderer.firstChild).h;
+					oldSize = newSize;
+					newSize += 1;
+				}
+				if(vDiff < 0 || hDiff < 0){
+					// back track
+					domStyle.set(renderer.firstChild, "fontSize", oldSize + "px");
+				}
+			}
+		},
+
+		createRenderer: function(item, level, kind){
+			var renderer = this.inherited(arguments);
+			if(kind == "leaf"){
+				var p = domConstruct.create("div");
+				domStyle.set(p, {
+					"position": "absolute",
+					"width": "auto"
+				});
+				domConstruct.place(p, renderer);
+			}
+			return renderer;
+		},
+		
+		styleRenderer: function(renderer, item, level, kind){
+			if (kind != "leaf"){
+				this.inherited(arguments);
+			}else{
+				domStyle.set(renderer, "background", this.getColorForItem(item).toHex());
+				renderer.firstChild.innerHTML = this.getLabelForItem(item);
+			}
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/treemap/TreeMap.js b/dojox/treemap/TreeMap.js
new file mode 100644
index 0000000..3bf8f56
--- /dev/null
+++ b/dojox/treemap/TreeMap.js
@@ -0,0 +1,803 @@
+define(["dojo/_base/array", "dojo/_base/lang", "dojo/_base/declare", "dojo/_base/event", "dojo/_base/Color", "dojo/touch",
+		"dojo/when", "dojo/on", "dojo/query", "dojo/dom-construct", "dojo/dom-geometry", "dojo/dom-class", "dojo/dom-style",
+		"./_utils", "dijit/_WidgetBase", "dojox/widget/_Invalidating", "dojox/widget/Selection",
+		"dojo/_base/sniff", "dojo/uacss"],
+	function(arr, lang, declare, event, Color, touch, when, on, query, domConstruct, domGeom, domClass, domStyle,
+		utils, _WidgetBase, _Invalidating, Selection, has){
+
+	return declare("dojox.treemap.TreeMap", [_WidgetBase, _Invalidating, Selection], {
+		// summary:
+		//		A treemap widget.
+		
+		baseClass: "dojoxTreeMap",
+		
+		// store: dojo/store/api/Store
+		//		The store that contains the items to display.
+		store: null,
+		
+		// query: Object
+		//		A query that can be passed to when querying the store.
+		query: {},
+
+		// queryOptions: dojo/store/api/Store.QueryOptions?
+		//		Options to be applied when querying the store.
+		queryOptions: null,
+		
+		// itemToRenderer: [protected] Object
+		//		The associated array item to renderer list.
+		itemToRenderer: null,
+
+		// Data
+		_dataChanged: false,
+	
+		// rootItem: Object
+		//		The root item of the treemap, that is the first visible item.
+		//		If null the entire treemap hierarchy is shown.	
+		//		Default is null.
+		rootItem: null,
+		_rootItemChanged: false,
+	
+		// tooltipAttr: String
+		//		The attribute of the store item that contains the tooltip text of a treemap cell.	
+		//		Default is "". 
+		tooltipAttr: "",
+	
+		// areaAttr: String
+		//		The attribute of the store item that contains the data used to compute the area of a treemap cell.	
+		//		Default is "". 
+		areaAttr: "",
+		_areaChanged: false,
+	
+		// labelAttr: String
+		//		The attribute of the store item that contains the label of a treemap cell.	
+		//		Default is "label". 
+		labelAttr: "label",
+		
+		// labelThreshold: Number
+		//		The starting depth level at which the labels are not displayed anymore on cells.  
+		//		If NaN no threshold is applied. The depth is the visual depth of the items on the screen not
+		//		in the data (i.e. after drill down the depth of an item might change).
+		//		Default is NaN.
+		labelThreshold: NaN, 
+		
+		// colorAttr: String
+		//		The attribute of the store item that contains the data used to compute the color of a treemap cell.
+		//		Default is "". 
+		colorAttr: "",
+		// colorModel: dojox/color/api/ColorModel
+		//		The optional color model that converts data to color.	
+		//		Default is null.
+		colorModel: null,
+		_coloringChanged: false,
+		
+		// groupAttrs: Array
+		//		An array of data attributes used to group data in the treemap.	
+		//		Default is []. 
+		groupAttrs: [],
+
+		// groupFuncs: Array
+		//		An array of grouping functions used to group data in the treemap.
+		//		When null, groupAttrs is to compute grouping functions.
+		//		Default is null.
+		groupFuncs: null,
+
+        _groupFuncs: null,
+		_groupingChanged: false,
+	
+		constructor: function(){
+			this.itemToRenderer = {};
+			this.invalidatingProperties = [ "colorModel", "groupAttrs", "groupFuncs", "areaAttr", "areaFunc",
+				"labelAttr", "labelFunc", "labelThreshold", "tooltipAttr", "tooltipFunc",
+				"colorAttr", "colorFunc", "rootItem" ];
+		},
+		
+		getIdentity: function(item){
+			return item.__treeID?item.__treeID:this.store.getIdentity(item);
+		},
+	
+		resize: function(box){
+			if(box){
+				domGeom.setMarginBox(this.domNode, box);
+				this.invalidateRendering();						
+			}
+		},
+		
+		postCreate: function(){
+			this.inherited(arguments);
+			this.own(on(this.domNode, "mouseover", lang.hitch(this, this._onMouseOver)));
+			this.own(on(this.domNode, "mouseout", lang.hitch(this, this._onMouseOut)));
+			this.own(on(this.domNode, touch.release, lang.hitch(this, this._onMouseUp)));
+			this.domNode.setAttribute("role", "presentation");
+			this.domNode.setAttribute("aria-label", "treemap");
+		},
+		
+		buildRendering: function(){
+			this.inherited(arguments);
+			this.refreshRendering();
+		},
+	
+		refreshRendering: function(){
+			var forceCreate = false;
+	
+			if(this._dataChanged){
+				this._dataChanged = false;
+				this._groupingChanged = true;
+				this._coloringChanged = true;
+			}
+	
+			if(this._groupingChanged){
+				this._groupingChanged = false;
+				this._set("rootItem", null);
+				this._updateTreeMapHierarchy();
+				forceCreate = true;
+			}
+	
+			if(this._rootItemChanged){
+				this._rootItemChanged = false;
+				forceCreate = true;
+			}
+	
+			if(this._coloringChanged){
+				this._coloringChanged = false;			
+				if(this.colorModel != null && this._data != null && this.colorModel.initialize){
+					this.colorModel.initialize(this._data, lang.hitch(this, function(item){
+						return this.colorFunc(item, this.store);
+					}));
+				}
+			}
+	
+			if(this._areaChanged){
+				this._areaChanged = false;
+				this._removeAreaForGroup();
+			}
+	
+			if(this.domNode == undefined || this._items == null){
+				return;
+			}
+			
+			if(forceCreate){
+				domConstruct.empty(this.domNode);
+			}
+	
+			var rootItem = this.rootItem;
+	
+			if(rootItem != null){
+				if(this._isLeaf(rootItem)){
+					rootItem = this._getRenderer(rootItem).parentItem;
+				}
+			}
+
+			var box = domGeom.getMarginBox(this.domNode);
+			if(rootItem != null){
+				this._buildRenderer(this.domNode, null, rootItem, {
+					x: box.l, y: box.t, w: box.w, h: box.h
+				}, 0, forceCreate);
+			}else{
+				this._buildChildrenRenderers(this.domNode, rootItem?rootItem:{ __treeRoot: true, children : this._items },
+					0, forceCreate, box);
+			}
+		},
+	
+		_setRootItemAttr: function(value){
+			this._rootItemChanged = true;
+			this._set("rootItem", value);
+		},
+	
+		_setStoreAttr: function(value){
+			var r;
+			if(this._observeHandler){
+				this._observeHandler.remove();
+				this._observeHandler = null;
+			}
+			if(value != null){
+				var results = value.query(this.query, this.queryOptions);
+				if(results.observe){
+					// user asked us to observe the store
+					this._observeHandler = results.observe(lang.hitch(this, this._updateItem), true);
+				}				
+				r = when(results, lang.hitch(this, this._initItems));
+			}else{
+				r = this._initItems([]);
+			}
+			this._set("store", value);
+			return r;
+		},
+	
+		_initItems: function(items){
+			this._dataChanged = true;
+			this._data = items;
+			this.invalidateRendering();
+			return items;
+		},
+
+		_updateItem: function(item, previousIndex, newIndex){
+			if(previousIndex!=-1){
+				if(newIndex!=previousIndex){
+					// this is a remove or a move
+					this._data.splice(previousIndex, 1);
+				}else{
+					// this is a put, previous and new index identical
+					// we don't know what has change exactly with store API
+					this._data[newIndex] = item;
+				}
+			}else if(newIndex!=-1){
+				// this is a add 
+				this._data.splice(newIndex, 0, item);
+			}
+			// as we have no details let's refresh everything...
+			this._dataChanged = true;			
+			this.invalidateRendering();
+		},
+	
+		_setGroupAttrsAttr: function(value){
+			this._groupingChanged = true;
+			if(this.groupFuncs == null){
+				if(value !=null){
+					this._groupFuncs = arr.map(value, function(attr){
+						return function(item){
+							return item[attr];
+						};
+					});
+				}else{
+					this._groupFuncs = null;
+				}
+			}
+			this._set("groupAttrs", value);
+		},
+
+        _setGroupFuncsAttr: function(value){
+			this._groupingChanged = true;
+			this._set("groupFuncs", this._groupFuncs = value);
+			if(value == null && this.groupAttrs != null){
+				this._groupFuncs = arr.map(this.groupAttrs, function(attr){
+					return function(item){
+						return item[attr];
+					};
+				});
+			}
+		},
+
+		_setAreaAttrAttr: function(value){
+			this._areaChanged = true;
+			this._set("areaAttr", value);
+		},
+	
+		// areaFunc: Function
+		//		A function that returns the value use to compute the area of cell from a store item.
+		//		Default implementation is using areaAttr.	
+		areaFunc: function(/*Object*/ item, /*dojo/store/api/Store*/ store){
+			return (this.areaAttr && this.areaAttr.length > 0)?parseFloat(item[this.areaAttr]):1;
+		},
+		
+		_setAreaFuncAttr: function(value){
+			this._areaChanged = true;
+			this._set("areaFunc", value);
+		},
+
+		// labelFunc: Function
+		//		A function that returns the label of cell from a store item.	
+		//		Default implementation is using labelAttr.
+		labelFunc: function(/*Object*/ item, /*dojo/store/api/Store*/ store){
+			var label = (this.labelAttr && this.labelAttr.length > 0)?item[this.labelAttr]:null;
+			return label?label.toString():null;
+		},
+	
+		// tooltipFunc: Function
+		//		A function that returns the tooltip of cell from a store item.	
+		//		Default implementation is using tooltipAttr.
+		tooltipFunc: function(/*Object*/ item, /*dojo/store/api/Store*/ store){
+			var tooltip = (this.tooltipAttr && this.tooltipAttr.length > 0)?item[this.tooltipAttr]:null;
+			return tooltip?tooltip.toString():null;
+		},
+
+		_setColorModelAttr: function(value){
+			this._coloringChanged = true;
+			this._set("colorModel", value);
+		},
+	
+		_setColorAttrAttr: function(value){
+			this._coloringChanged = true;
+			this._set("colorAttr", value);
+		},
+	
+		// colorFunc: Function
+		//		A function that returns from a store item the color value of cell or the value used by the 
+		//		ColorModel to compute the cell color. If a color must be returned it must be in form accepted by the
+		//		dojo/_base/Color constructor. If a value must be returned it must be a Number.
+		//		Default implementation is using colorAttr.
+		colorFunc: function(/*Object*/ item, /*dojo/store/api/Store*/ store){
+			var color = (this.colorAttr && this.colorAttr.length > 0)?item[this.colorAttr]:0;
+			if(color == null){
+				color = 0;
+			}
+			return parseFloat(color);
+		},
+		
+		_setColorFuncAttr: function(value){
+			this._coloringChanged = true;
+			this._set("colorFunc", value);
+		},
+		
+		createRenderer: function(item, level, kind){
+			// summary:
+			//		Creates an item renderer of the specified kind. This is called only when the treemap
+			//		is created. Default implementation always create div nodes. It also sets overflow
+			//		to hidden and position to absolute on non-header renderers.
+			// item: Object
+			//		The data item.
+			// level: Number
+			//		The item depth level.		
+			// kind: String
+			//		The specified kind. This can either be "leaf", "group", "header" or "content". 
+			// returns: DomNode
+			//		The renderer use for the specified kind.
+			// tags:
+			//		protected					
+			var div = domConstruct.create("div");
+			if(kind != "header"){
+				domStyle.set(div, "overflow", "hidden");
+				domStyle.set(div, "position", "absolute");					
+			}
+			return div;
+		},
+		
+		styleRenderer: function(renderer, item, level, kind){
+			// summary:
+			//		Style the item renderer. This is called each time the treemap is refreshed.
+			//		For leaf items it colors them with the color computed from the color model. 
+			//		For other items it does nothing.
+			// renderer: DomNode
+			//		The item renderer.
+			// item: Object
+			//		The data item.
+			// level: Number
+			//		The item depth level.
+			// kind: String
+			//		The specified kind. This can either be "leaf", "group", "header" or "content". 
+			// tags:
+			//		protected
+			switch(kind){
+				case "leaf":
+					domStyle.set(renderer, "background", this.getColorForItem(item).toHex());
+				case "header":
+					var label = this.getLabelForItem(item);
+					if(label && (isNaN(this.labelThreshold) || level < this.labelThreshold)){
+						renderer.innerHTML = label;
+					}else{
+						domConstruct.empty(renderer);
+					}
+					break;
+				default:
+				
+			}				
+		},
+		
+		_updateTreeMapHierarchy: function(){
+			if(this._data == null){
+				return;
+			}
+			if(this._groupFuncs != null && this._groupFuncs.length > 0){
+				this._items = utils.group(this._data, this._groupFuncs, lang.hitch(this, this._getAreaForItem)).children;
+			}else{
+				this._items = this._data;
+			}
+		},
+	
+		_removeAreaForGroup: function(item){
+			var children;
+			if(item != null){
+				if(item.__treeValue){
+					delete item.__treeValue;
+					children = item.children;
+				}else{
+					// not a grouping item
+					return;
+				}
+			}else{
+				children = this._items;
+			}
+			if(children){
+				for(var i = 0; i < children.length; ++i){
+					this._removeAreaForGroup(children[i]);
+				}
+			}
+		},
+	
+		_getAreaForItem: function(item){
+			var area = this.areaFunc(item, this.store);
+			return isNaN(area) ? 0 : area;
+		},
+
+		_computeAreaForItem: function(item){
+			var value;
+			if(item.__treeID){ // group
+				value = item.__treeValue;
+				if(!value){
+					value = 0;
+					var children = item.children;
+					for(var i = 0; i < children.length; ++i){
+						value += this._computeAreaForItem(children[i]);
+					}
+					item.__treeValue = value;
+				}
+			}else{
+				value = this._getAreaForItem(item);
+			}
+			return value;
+		},
+	
+		getColorForItem: function(item){
+			// summary:
+			//		Returns the color for a given item. This either use the colorModel if not null
+			//		or just the result of the colorFunc.
+			// item: Object
+			//		The data item.
+			// tags:
+			//		protected	
+			var value = this.colorFunc(item, this.store);
+			if(this.colorModel != null){
+				return this.colorModel.getColor(value);
+			}else{
+				return new Color(value);
+			}
+		},
+	
+		getLabelForItem: function(item){
+			// summary:
+			//		Returns the label for a given item.
+			// item: Object
+			//		The data item.
+			// tags:
+			//		protected	
+			return item.__treeName?item.__treeName:this.labelFunc(item, this.store);
+		},
+	
+		_buildChildrenRenderers: function(domNode, item, level, forceCreate, delta, anim){
+			var children = item.children;
+			var box = domGeom.getMarginBox(domNode);
+
+			var solution = utils.solve(children, box.w, box.h, lang.hitch(this,
+					this._computeAreaForItem), !this.isLeftToRight());
+					
+			var rectangles = solution.rectangles;
+			
+			if(delta){
+				rectangles = arr.map(rectangles, function(item){
+					item.x += delta.l;
+					item.y += delta.t;
+					return item;
+				});
+			}
+	
+			var rectangle;
+			for(var j = 0; j < children.length; ++j){
+				rectangle = rectangles[j];
+				this._buildRenderer(domNode, item, children[j], rectangle, level, forceCreate, anim);
+			}
+		},
+		
+		_isLeaf: function(item){
+			return !item.children;
+		},
+		
+		_isRoot: function(item){
+			return item.__treeRoot;
+		},
+		
+		_getRenderer: function(item, anim, parent){
+			if(anim){
+				// while animating we do that on a copy of the subtree
+				// so we can use our hash object to get to the renderer
+				for(var i = 0; i < parent.children.length; ++i){
+	        		if(parent.children[i].item == item){
+	            		return parent.children[i];
+	                }
+				}	
+			}
+			return this.itemToRenderer[this.getIdentity(item)];
+		},
+
+		_buildRenderer: function(container, parent, child, rect, level, forceCreate, anim){
+			var isLeaf = this._isLeaf(child);
+			var renderer = !forceCreate ? this._getRenderer(child, anim, container) : null;
+			renderer = isLeaf ? this._updateLeafRenderer(renderer, child, level) : this._updateGroupRenderer(renderer,
+					child, level);
+			if(forceCreate){
+				renderer.level = level;
+				renderer.item = child;
+				renderer.parentItem = parent;
+				this.itemToRenderer[this.getIdentity(child)] = renderer;
+				// update its selection status
+				this.updateRenderers(child);
+			}
+	
+			// in some cases the computation might be slightly incorrect (0.0000...1)
+			// and due to the floor this will cause 1px gaps 
+	
+			var x = Math.floor(rect.x);
+			var y = Math.floor(rect.y);
+			var w = Math.floor(rect.x + rect.w + 0.00000000001) - x;
+			var h = Math.floor(rect.y + rect.h + 0.00000000001) - y;
+
+			// before sizing put the item inside its parent so that styling
+			// is applied and taken into account
+			if(forceCreate){
+				domConstruct.place(renderer, container);
+			}
+
+			domGeom.setMarginBox(renderer, {
+				l: x, t: y, w: w, h: h
+			});
+			
+			if(!isLeaf){
+				var box = domGeom.getContentBox(renderer);
+				this._layoutGroupContent(renderer, box.w, box.h, level + 1, forceCreate, anim);
+			}
+			
+			this.onRendererUpdated({ renderer: renderer, item: child, kind: isLeaf?"leaf":"group", level: level });		
+		},
+	
+		_layoutGroupContent: function(renderer, width, height, level, forceCreate, anim){
+			var header = query(".dojoxTreeMapHeader", renderer)[0];
+			var content = query(".dojoxTreeMapGroupContent", renderer)[0];
+			if(header == null || content == null){
+				return;
+			}
+	
+			var box = domGeom.getMarginBox(header);
+	
+			// If the header is too high, reduce its area
+			// and don't show the children..
+			if(box.h > height){
+				// TODO: this might cause pb when coming back to visibility later
+				// as the getMarginBox of the header will keep that value?
+				box.h = height;
+				domStyle.set(content, "display", "none");
+			}else{
+				domStyle.set(content, "display", "block");
+				domGeom.setMarginBox(content, {
+					l: 0, t: box.h, w: width, h: (height - box.h)
+				});
+				this._buildChildrenRenderers(content, renderer.item, level, forceCreate, null, anim);
+			}
+	
+			domGeom.setMarginBox(header, {
+				l: 0, t: 0, w: width, h: box.h
+			});
+		},
+	
+		_updateGroupRenderer: function(renderer, item, level){
+			// summary:
+			//		Update a group renderer. This creates the renderer if not already created,
+			//		call styleRender for it and recurse into children.
+			// renderer: DomNode
+			//		The item renderer.
+			// item: Object
+			//		The data item.
+			// level: Number
+			//		The item depth level.
+			// tags:
+			//		private				
+			var forceCreate = renderer == null;
+			if(renderer == null){
+				renderer = this.createRenderer("div", level, "group");
+				domClass.add(renderer, "dojoxTreeMapGroup");
+			}
+			this.styleRenderer(renderer, item, level, "group");
+			var header = query(".dojoxTreeMapHeader", renderer)[0];
+			header = this._updateHeaderRenderer(header, item, level);
+			if(forceCreate){
+				domConstruct.place(header, renderer);
+			}
+			var content = query(".dojoxTreeMapGroupContent", renderer)[0];
+			content = this._updateGroupContentRenderer(content, item, level);
+			if(forceCreate){
+				domConstruct.place(content, renderer);
+			}
+			return renderer;
+		},
+	
+		_updateHeaderRenderer: function(renderer, item, level){
+			// summary:
+			//		Update a leaf renderer. This creates the renderer if not already created,
+			//		call styleRender for it and set the label as its innerHTML.
+			// renderer: DomNode
+			//		The item renderer.
+			// item: Object
+			//		The data item.
+			// level: Number
+			//		The item depth level.
+			// tags:
+			//		private			
+			if(renderer == null){
+				renderer = this.createRenderer(item, level, "header");
+				domClass.add(renderer, "dojoxTreeMapHeader");
+				domClass.add(renderer, "dojoxTreeMapHeader_" + level);				
+			}
+			this.styleRenderer(renderer, item, level, "header");
+			return renderer;
+		},
+	
+		_updateLeafRenderer: function(renderer, item, level){
+			// summary:
+			//		Update a leaf renderer. This creates the renderer if not already created,
+			//		call styleRender for it and set the label as its innerHTML.
+			// renderer: DomNode
+			//		The item renderer.
+			// item: Object
+			//		The data item.
+			// level: Number
+			//		The item depth level.
+			// tags:
+			//		private				
+			if(renderer == null){
+				renderer = this.createRenderer(item, level, "leaf");
+				domClass.add(renderer, "dojoxTreeMapLeaf");
+				domClass.add(renderer, "dojoxTreeMapLeaf_" + level);
+			}		
+			this.styleRenderer(renderer, item, level, "leaf");
+			var tooltip = this.tooltipFunc(item, this.store);
+			if(tooltip){
+				renderer.title = tooltip;
+			}
+			return renderer;
+		},
+	
+		_updateGroupContentRenderer: function(renderer, item, level){
+			// summary:
+			//		Update a group content renderer. This creates the renderer if not already created,
+			//		and call styleRender for it.
+			// renderer:
+			//		The item renderer.
+			// item: Object
+			//		The data item.
+			// level: Number
+			//		The item depth level.
+			// tags:
+			//		private				
+			if(renderer == null){
+				renderer = this.createRenderer(item, level, "content");
+				domClass.add(renderer, "dojoxTreeMapGroupContent");
+				domClass.add(renderer, "dojoxTreeMapGroupContent_" + level);
+			}
+			this.styleRenderer(renderer, item, level, "content");
+			return renderer;
+		},
+		
+		_getRendererFromTarget: function(target){
+			var renderer = target;
+			while(renderer != this.domNode && !renderer.item){
+				renderer = renderer.parentNode;
+			}			
+			return renderer;
+		},
+
+		_onMouseOver: function(e){
+			var renderer = this._getRendererFromTarget(e.target);
+			if(renderer.item){	
+				var item = renderer.item;
+				this._hoveredItem = item;
+				this.updateRenderers(item);
+				this.onItemRollOver({renderer: renderer, item : item, triggerEvent: e});
+			}
+		},
+	
+		_onMouseOut: function(e){
+			var renderer = this._getRendererFromTarget(e.target);
+			if(renderer.item){	
+				var item = renderer.item;
+				this._hoveredItem = null;
+				this.updateRenderers(item);
+				this.onItemRollOut({renderer: renderer, item : item, triggerEvent: e});
+			}
+		},
+		
+		_onMouseUp: function(e){
+			var renderer = this._getRendererFromTarget(e.target);
+			if(renderer.item){
+				this.selectFromEvent(e, renderer.item, e.currentTarget, true);
+				//event.stop(e);
+			}
+		},
+		
+		onRendererUpdated: function(){
+			// summary:
+			//		Called when a renderer has been updated. This is called after creation, styling and sizing for 
+			//		each group and leaf renderers. For group renders this is also called after creation of children
+			//		renderers. 
+			// tags:
+			//		callback			
+		},
+		
+		onItemRollOver: function(){
+			// summary:
+			//		Called when an item renderer has been hovered.
+			// tags:
+			//		callback			
+		},
+		
+		onItemRollOut: function(){
+			// summary:
+			//		Called when an item renderer has been rolled out.
+			// tags:
+			//		callback			
+		},		
+		
+		updateRenderers: function(items){
+			// summary:
+			//		Updates the renderer(s) that represent the specified item(s).
+			// item: Object|Array
+			//		The item(s).
+			if(!items){
+				return;
+			}			
+			if(!lang.isArray(items)){
+				items = [items];
+			}
+			for(var i=0; i<items.length;i++){
+				var item = items[i];
+				var renderer = this._getRenderer(item);
+				// at init time the renderer might not be ready
+				if(!renderer){
+					continue;
+				}
+				var selected = this.isItemSelected(item);
+				var ie = has("ie");
+				var div;
+				if(selected){
+					domClass.add(renderer, "dojoxTreeMapSelected");
+					if(ie && (has("quirks") || ie < 9)){
+						// let's do all of this only if not already done
+						div = renderer.previousSibling;
+						var rStyle = domStyle.get(renderer);
+						if(!div || !domClass.contains(div, "dojoxTreeMapIEHack")){
+							div = this.createRenderer(item, -10, "group");
+							domClass.add(div, "dojoxTreeMapIEHack");
+							domClass.add(div, "dojoxTreeMapSelected");
+							domStyle.set(div, {
+								position: "absolute",
+								overflow: "hidden"
+							});
+							domConstruct.place(div, renderer, "before");
+						}
+						// TODO: might fail if different border widths for different sides
+						var bWidth = 2*parseInt(domStyle.get(div, "border-width"));
+						if(this._isLeaf(item)){
+							bWidth -= 1;
+						}else{
+							bWidth += 1;
+						}
+						// if we just drill down some renders might not be laid out?
+						if(rStyle["left"] != "auto"){
+							domStyle.set(div, {
+								left: (parseInt(rStyle["left"])+1)+"px",
+								top: (parseInt(rStyle["top"])+1)+"px",
+								width: (parseInt(rStyle["width"])-bWidth)+"px",
+								height: (parseInt(rStyle["height"])-bWidth)+"px"
+							});
+						}
+					}
+				}else{
+					if(ie && (has("quirks") || ie < 9)){
+						div = renderer.previousSibling;
+						if(div && domClass.contains(div, "dojoxTreeMapIEHack")){
+							div.parentNode.removeChild(div);
+						}
+					}
+					domClass.remove(renderer, "dojoxTreeMapSelected");
+
+				}
+				if(this._hoveredItem == item){
+					domClass.add(renderer, "dojoxTreeMapHovered");
+				}else{
+					domClass.remove(renderer, "dojoxTreeMapHovered");
+				}
+				if(selected || this._hoveredItem == item){
+					domStyle.set(renderer, "zIndex", 20);
+				}else{
+					domStyle.set(renderer, "zIndex", (has("ie")<=7)?0:"auto");
+				}
+			}
+		}
+	});
+});
diff --git a/dojox/treemap/_utils.js b/dojox/treemap/_utils.js
new file mode 100644
index 0000000..dcc261d
--- /dev/null
+++ b/dojox/treemap/_utils.js
@@ -0,0 +1,253 @@
+define(["dojo/_base/array"], function(arr){
+	var utils = {
+		group: function(/*Array*/items, /*Array*/groupingFunctions,  /*Function*/measureFunction){
+			var response = {
+				children: []
+			};
+			var merge = function(obj, entry){
+				if(!obj.__treeValue){
+					obj.__treeValue = 0;
+				}
+				obj.__treeValue += measureFunction(entry);
+				return obj;
+			};
+			// we go over each entry in the array
+			arr.forEach(items, function(entry){
+				var r = response;
+				// for this entry, for each rowField we
+				// look at the actual value for this rowField
+				// and create a holding object for this
+				// value in response if it does not exist
+				arr.forEach(groupingFunctions, function(groupingFunction, j){
+					// actual value for the rowField
+					var data = groupingFunction(entry);
+					// create child if undefined
+					var child = utils.find(r.children, function(item){
+						return (item.__treeName == data);
+					});
+					if(!child){
+						r.children.push(child = {
+							__treeName: data,
+							__treeID: data+Math.random(),
+							children: []
+						});
+					}
+					child = merge(child, entry);
+					if(j != groupingFunctions.length - 1){
+						// branch & prepare response for 
+						// next call
+						r = child;
+					}else{
+						// add the entry to the leaf!
+						child.children.push(entry);
+					}
+				});
+				r = merge(r, entry);
+			});
+			return response;
+		},
+		find: function(/*Array*/array, /*Function*/callback){
+			var l = array.length;
+			for (var i = 0; i < l; ++i) {
+				if (callback.call(null, array[i])){ 					
+					return array[i];
+				}
+			}
+			return null;
+		},
+		solve: function(items, width, height, areaFunc, rtl){
+			//
+			// Create temporary TreeMap elements
+			//
+			var treeMapElements = utils.initElements(items, areaFunc);
+			var dataTotal = treeMapElements.total;
+			var elements = treeMapElements.elements;
+	
+			var realSize = dataTotal;
+	
+			if(dataTotal == 0){
+				if(elements.length == 0){
+					return {
+						items: items, rects: [], total: 0
+					};
+				}
+				arr.forEach(elements, function(element){
+					element.size = element.sizeTmp = 100;
+				});
+				dataTotal = elements.length * 100;
+			}
+	
+			//
+			// 	Sort the TreeMap elements
+			//
+			elements.sort(function(b, a){
+				return a.size - b.size;
+			});
+	
+			utils._compute(width, height, elements, dataTotal);
+	
+			//
+			// Restore initial Sort order
+			// 
+			elements.sort(function(a, b){
+				return a.index - b.index;
+			});
+	
+			var result = {};
+			result.elements = elements;
+			result.size = realSize;
+	
+			rects = arr.map(elements, function(element){
+				return {
+					x: rtl?width - element.x - element.width:element.x, y: element.y, w: element.width, h: element.height
+				};
+			});
+	
+			result.rectangles = rects;
+	
+			return result;
+		},
+		initElements: function(items, areaFunc){
+			var total = 0;
+			var elements = arr.map(items, function(item, index){
+				var size = areaFunc != null ? areaFunc(item) : 0;
+				if(size < 0){
+					throw new Error("item size dimension must be positive");
+				}
+				total += size;
+				return {
+					index: index, size: size, sizeTmp: size
+				};
+			});
+			return {
+				elements: elements, total: total
+			};
+		},
+		_compute: function(width, height, elements, total){
+			var valueScale = ((width * height) / total) / 100;
+	
+			arr.forEach(elements, function(element){
+				element.sizeTmp *= valueScale;
+			});
+	
+			var start = 0;
+			var end = 0;
+			var aspectCurr = -1 >>> 1; // int.MaxValue;
+			var aspectLast;
+			var offsetX = 0;
+			var offsetY = 0;
+			var tmp_width = width;
+			var tmp_height = height;
+	
+			var vert = tmp_width > tmp_height;
+	
+			while(end != elements.length){
+				aspectLast = utils._trySolution(elements, start, end, vert, tmp_width, tmp_height);
+	
+				if((aspectLast > aspectCurr) || (aspectLast < 1)){
+					var currX = 0;
+					var currY = 0;
+	
+					for(var n = start; n < end; n++){
+						elements[n].x = offsetX + currX;
+						elements[n].y = offsetY + currY;
+						if(vert){
+							currY += elements[n].height;
+						}else{
+							currX += elements[n].width;
+						}
+					}
+	
+					if(vert){
+						offsetX += elements[start].width;
+					}else{
+						offsetY += elements[start].height;
+					}
+	
+					tmp_width = width - offsetX;
+					tmp_height = height - offsetY;
+	
+					vert = tmp_width > tmp_height;
+	
+					start = end;
+					end = start;
+	
+					aspectCurr = -1 >>> 1; // int.MaxValue;
+					continue;
+				}else{
+					for(var n = start; n <= end; n++){
+						elements[n].width = elements[n].widthTmp;
+						elements[n].height = elements[n].heightTmp;
+					}
+					aspectCurr = aspectLast;
+				}
+				end++;
+			}
+	
+			var currX1 = 0;
+			var currY1 = 0;
+	
+			for(var n = start; n < end; n++){
+				elements[n].x = offsetX + currX1;
+				elements[n].y = offsetY + currY1;
+				if(vert){
+					currY1 += elements[n].height;
+				}else{
+					currX1 += elements[n].width;
+				}
+			}
+	
+		},
+		_trySolution: function(elements, start, end, vert, tmp_width, tmp_height){
+			var total = 0;
+			var aspect = 0;
+			var localWidth = 0;
+			var localHeight = 0;
+	
+			for(var n = start; n <= end; n++){
+				total += elements[n].sizeTmp;
+			}
+	
+			if(vert){
+				if(tmp_height == 0){
+					localWidth = localHeight = 0;
+				}else{
+					localWidth = total / tmp_height * 100;
+					localHeight = tmp_height;
+				}
+			}else{
+				if(tmp_width == 0){
+					localWidth = localHeight = 0;
+				}else{
+					localHeight = total / tmp_width * 100;
+					localWidth = tmp_width;
+				}
+			}
+	
+			for(var n = start; n <= end; n++){
+				if(vert){
+					elements[n].widthTmp = localWidth;
+					if(total == 0){
+						elements[n].heightTmp = 0;
+					}else{
+						elements[n].heightTmp = localHeight * elements[n].sizeTmp / total;
+					}
+				}else{
+					if(total == 0){
+						elements[n].widthTmp = 0;
+					}else{
+						elements[n].widthTmp = localWidth * elements[n].sizeTmp / total;
+					}
+					elements[n].heightTmp = localHeight;
+				}
+			}
+			aspect = Math.max(elements[end].heightTmp / elements[end].widthTmp, elements[end].widthTmp
+					/ elements[end].heightTmp);
+			if(aspect == undefined){
+				return 1;
+			}
+			return aspect;
+		}
+	};
+	return utils;
+});
diff --git a/dojox/treemap/tests/Store.js b/dojox/treemap/tests/Store.js
new file mode 100644
index 0000000..40d586b
--- /dev/null
+++ b/dojox/treemap/tests/Store.js
@@ -0,0 +1,14 @@
+define(["doh", "dojo/_base/declare", "../TreeMap", "dojo/store/JsonRest", "dojo/when"],
+	function(doh, declare, TreeMap, JsonRest, when){
+	doh.register("dojox.treemap.tests.Store", [
+		function test_Error(t){
+			var treeMap = new TreeMap();
+			var d = when(treeMap.set("store", new JsonRest({ target: "/" }), function(){
+				t.f(true, "ok fct must not have been called");
+			}, function(){
+				t.t(true, "failure fct must have been called");
+			}));
+			treeMap.startup();
+		}
+	]);
+});
diff --git a/dojox/treemap/tests/freight.csv b/dojox/treemap/tests/freight.csv
new file mode 100644
index 0000000..9307fff
--- /dev/null
+++ b/dojox/treemap/tests/freight.csv
@@ -0,0 +1,51 @@
+Name,State,Mode,Rank,Trade,Exports,Imports,Percent
+Port of Los Angeles,CA,Water,1,170,26.3,143.7,15.5
+Port of New York,NY,Water,2,149.3,33.2,116.1,22.3
+JFK International Airport,NY,Air,3,147.8,68.4,79.4,46.3
+Port of Detroit,MI,Land,4,137.2,72.8,64.5,53
+Port of Long Beach,CA,Water,5,134.7,21.4,113.3,15.9
+Port of Laredo,TX,Land,6,104,45.8,58.2,44
+Port of Houston,TX,Water,7,102.9,41.9,60.9,40.8
+Los Angeles International Airport,CA,Air,8,79.1,41,38,51.9
+Chicago,IL,Air,9,78.1,31.3,46.7,40.1
+Port of Buffalo-Niagara Falls,NY,Land,10,75.5,35.5,40,47
+Port of Huron,MI,Land,11,70.3,25.5,44.9,36.2
+San Francisco International Airport,CA,Air,12,63.8,29.5,34.3,46.2
+Port of Charleston,SC,Water,13,55.1,16.1,39.1,29.1
+Port of El Paso,TX,Land,14,46.7,21,25.7,44.9
+Anchorage,AK,Air,15,44.6,11.5,33.2,25.7
+Port of Norfolk Harbor,VA,Water,16,44.5,17.4,27.1,39
+Dallas-Fort Worth,TX,Air,17,41.6,17.5,24.1,42.1
+Port of Savannah,GA,Water,18,39.7,13.6,26.1,34.2
+Port of Baltimore,MD,Water,19,36.6,9.6,27,26.3
+Port of Seattle,WA,Water,20,34.6,8.6,26,24.8
+Port of South Louisiana,LA,Air,21,34.1,14.2,20,41.5
+Port of Oakland,CA,Water,22,33.3,9.8,23.6,29.3
+Atlanta,GA,Air,23,33.2,12.4,20.9,37.2
+Port of Tacoma,WA,Water,24,32.6,4.9,27.7,15.1
+Miami International Airport,FL,Air,25,30.3,20.7,9.6,68.2
+Port of Otay Mesa Station,CA,Land,26,28.6,9.9,18.7,34.8
+Port of Oakland,CA,Water,27,26,11.5,14.5,44.4
+Port of New Orleans,LA,Air,28,25.8,16.1,9.7,62.4
+Cleveland,OH,Water,29,25.6,0.1,25.4,0.5
+Port of Morgan City,LA,Water,30,22,1.9,20.2,8.5
+Port of Beaumont,TX,Water,31,21.2,8.7,12.5,41.1
+Port of Jacksonville,FL,Water,32,20.7,1.7,19,8.2
+Port of Philadelphia,PA,Water,33,20.3,8.9,11.4,43.8
+Port of Miami,FL,Land,34,20,8.3,11.8,41.2
+Port of Hidalgo,TX,Land,35,19.9,7.2,12.8,36.1
+Port of Champlain-Rouses Pt.,NY,Water,36,19,3.3,15.7,17.4
+Port of Corpus Christi,TX,Land,37,18.9,6.3,12.5,33.6
+Port of Nogales,AZ,Water,38,18.6,8,10.5,43.4
+Port of Blaine,WA,Land,39,17.1,8.8,8.4,51.1
+Port of Pembina,ND,Land,40,15.4,8.5,6.9,55.1
+Port of Newark Liberty International,NJ,Air,41,15.2,3.1,12.1,20.3
+Port of Dulles Interational,DC,Air,42,15.1,5.1,10,33.7
+Port of Portland,OR,Water,43,14.1,2.6,11.5,18.3
+Port of Texas City,TX,Water,44,13.7,1.6,12,11.9
+Port of General Edward Lawrence Logan International,MA,Air,45,13.6,8.3,5.3,61
+Port of Luis Munoz Marin International,PR,Air,46,12.6,7.6,5,60.5
+Port of Brownsville-Cameron,TX,Land,47,12.4,6.8,5.6,54.9
+Port of Sweetgrass,MT,Land,48,12.2,6.3,6,51.1
+Port of Alexandria Bay,NY,Land,49,12.2,4.7,7.5,38.9
+Port of Portal,ND,Land,50,11.9,6.8,5.1,57.2
diff --git a/dojox/treemap/tests/module.js b/dojox/treemap/tests/module.js
new file mode 100644
index 0000000..4330570
--- /dev/null
+++ b/dojox/treemap/tests/module.js
@@ -0,0 +1,3 @@
+define([
+	"dojox/treemap/tests/Store",
+], 1);
diff --git a/dojox/treemap/tests/runTests.html b/dojox/treemap/tests/runTests.html
new file mode 100644
index 0000000..f52905b
--- /dev/null
+++ b/dojox/treemap/tests/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+  <head>
+  <title>Dojox Widget Unit Test Runner</title>
+    <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?test=dojox/treemap/tests/module"></HEAD>
+  <BODY>
+    Redirecting to D.O.H runner.
+  </BODY>
+</HTML>
\ No newline at end of file
diff --git a/dojox/treemap/tests/test.html b/dojox/treemap/tests/test.html
new file mode 100644
index 0000000..bf99d59
--- /dev/null
+++ b/dojox/treemap/tests/test.html
@@ -0,0 +1,200 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+	<style type="text/css">
+		body, html { width:100%; height:100%; margin:0; padding:0 }
+		#borderContainer { width:100%; height:100% }
+	</style>
+
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../themes/TreeMap.css";
+		@import "../themes/DrillDownUp.css";
+		@import "../../../dijit/themes/claro/claro.css";
+	</style>
+
+	<script type="text/javascript">
+		var djConfig = {
+			parseOnLoad: false,
+			async: true
+		}
+	</script>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js">
+	</script>
+
+	<script type="text/javascript">
+
+		var groupByChanged, sizeByChanged, colorByChanged,
+				thresholdChanged, neutralChanged, MyTreeMap, refreshData;
+
+		require(["dojo/ready", "dojo/dom", "dojo/_base/Color", "dojo/_base/declare", "dojo/parser",
+			"dijit/registry",
+			"dijit/layout/BorderContainer", "dijit/layout/ContentPane", "dojox/treemap/TreeMap",
+			"dojox/color/MeanColorModel", "dojox/data/CsvStore", "dojo/store/DataStore",
+			"dojo/store/Observable",
+			"dijit/form/RadioButton", "dijit/form/ComboBox", "dijit/form/Button", "dojox/treemap/Keyboard",
+			"dojox/treemap/DrillDownUp"],
+			function(ready, dom, Color, declare, parser, registry, BorderContainer, ContentPane, TreeMap,
+					 MeanColorModel, CsvStore, DataStore, Observable, RadioButton, ComboBox, Button, Keyboard,
+					 DrillDownUp) {
+
+				var colorModel = new MeanColorModel(new Color(Color.named.green), new Color(Color.named.red));
+				var store = new DataStore({ store: new CsvStore({url: "freight.csv"}) });
+
+				ready(function(){
+					MyTreeMap = declare([TreeMap, Keyboard, DrillDownUp]);
+					parser.parse();
+					var treeMap = registry.byId("treeMap");
+					treeMap.set("colorModel", colorModel);
+					treeMap.set("tooltipFunc",
+							function(data, store) { return "Total Trade:" + data["Trade"]; });
+					treeMap.set("store", Observable(store));
+					treeMap.on("change", function(){
+						console.log("toto");
+					});
+				});
+
+				groupByChanged = function(value){
+					var groupBy = null;
+					if(dom.byId("g2").checked){
+						groupBy = ["Mode"];
+					} else if(dom.byId("g3").checked){
+						groupBy = ["State"];
+					}else if(dom.byId("g4").checked){
+						groupBy = ["Mode", "State"];
+					}
+					var treeMap = registry.byId("treeMap");
+					if(groupBy != null){
+						treeMap.set("groupAttrs", groupBy);
+					}else{
+						treeMap.set("groupAttrs", null);
+					}
+				}
+
+				sizeByChanged = function(value){
+					var sizeBy = null;
+					if(dom.byId("s2").checked){
+						sizeBy = "Trade";
+					}else if(dom.byId("s3").checked){
+						sizeBy = "Exports";
+					}else if(dom.byId("s4").checked){
+						sizeBy = "Imports";
+					}
+					var treeMap = registry.byId("treeMap");
+					treeMap.set("areaAttr", sizeBy);
+				}
+
+				colorByChanged = function(value){
+					var colorBy = null;
+					if(dom.byId("c2").checked){
+						colorBy = "Trade";
+					}else if(dom.byId("c3").checked){
+						colorBy = "Exports";
+					}else if(dom.byId("c4").checked){
+						colorBy = "Imports";
+					}
+					var treeMap = registry.byId("treeMap");
+					treeMap.set("colorAttr", colorBy);
+				}
+
+				thresholdChanged = function(value){
+					var treeMap = registry.byId("treeMap");
+					treeMap.set("labelThreshold", value);
+				};
+
+				neutralChanged = function(value){
+					var treeMap = registry.byId("treeMap");
+					if(value){
+						var newModel = new MeanColorModel(new Color(Color.named.green), new Color(Color.named.red));
+						newModel.computeNeutral = function(min, max, sum, values){
+							return sum / values.length;
+						}
+						treeMap.set("colorModel", newModel);
+					}else{
+						treeMap.set("colorModel", colorModel);
+					}
+				}
+			});
+	</script>
+
+</head>
+
+<body class="claro">
+
+<div dojoType="dijit.layout.BorderContainer" design="sidebar" gutters="true" liveSplitters="true" id="borderContainer">
+	<div dojoType="dijit.layout.ContentPane" splitter="true" region="center">
+		<div id="treeMap" dojoType="MyTreeMap" labelAttr="Name" selectionMode="multiple"
+			 style="width: 100%; height: 100%;">
+		</div>
+	</div>
+	<div dojoType="dijit.layout.ContentPane" splitter="true" region="trailing"  style="width: 200px;">
+		<label>Group by:</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="groupBy" id="g1" checked value="none" onChange="groupByChanged" />
+		<label for="g1">None</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="groupBy" id="g2" value="continent" onChange="groupByChanged" />
+		<label for="g2">Mode</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="groupBy" id="g3" value="government" onChange="groupByChanged" />
+		<label for="g3">State</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="groupBy" id="g4" value="government" onChange="groupByChanged" />
+		<label for="g4">Mode then State</label>
+		<br/>
+		<br/>
+		<br/>
+		<label>Size by:</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="sizeBy" id="s1" checked value="none" onChange="sizeByChanged" />
+		<label for="s1">None</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="sizeBy" id="s2" onChange="sizeByChanged" />
+		<label for="s2">Trade</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="sizeBy" id="s3" onChange="sizeByChanged" />
+		<label for="s3">Exports</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="sizeBy" id="s4" onChange="sizeByChanged" />
+		<label for="s3">Imports</label>
+		<br/>
+		<br/>
+		<br/>
+		<label>Color by:</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="colorBy" id="c1" checked value="none" onChange="colorByChanged"/>
+		<label for="c1">None</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="colorBy" id="c2" onChange="colorByChanged" />
+		<label for="c2">Trade</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="colorBy" id="c3" onChange="colorByChanged" />
+		<label for="c3">Exports</label>
+		<br/>
+		<input type="radio" dojoType="dijit.form.RadioButton" name="colorBy" id="c4" onChange="colorByChanged" />
+		<label for="c4">Imports</label>
+		<br/>
+		<br/>
+		<br/>
+		<label>Label threshold</label>
+		<br/>
+		<select id="labelThreshold" dojoType="dijit.form.ComboBox" onChange="thresholdChanged">
+			<option selected>NaN</option>
+			<option>1</option>
+			<option>2</option>
+		</select>
+		<br/>
+		<br/>
+		<br/>
+		<label>Mean/Average neutral value</label>
+		<br/>
+		<select id="neutral" dojoType="dijit.form.CheckBox" onChange="neutralChanged">
+		</select>
+	</div>
+</div>
+
+</body>
+
+</html>
diff --git a/dojox/treemap/tests/test_attr.html b/dojox/treemap/tests/test_attr.html
new file mode 100644
index 0000000..f0eb2d8
--- /dev/null
+++ b/dojox/treemap/tests/test_attr.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../themes/TreeMap.css";
+	</style>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true">
+	</script>
+
+	<script type="text/javascript">
+
+		require(["dojo/ready", "dojo/dom", "dojox/treemap/TreeMap",
+			"dojo/store/Memory", "dojox/color/MeanColorModel", "dojo/_base/Color"],
+			function(ready, dom, TreeMap, Memory, MeanColorModel, Color) {
+				ready(function(){
+					var dataStore = new Memory({idProperty: "label", data:
+							[
+								{ label: "France", sales: 500, profit: 50, region: "EU" },
+								{ label: "Germany", sales: 450, profit: 48, region: "EU" },
+								{ label: "UK", sales: 700, profit: 60, region: "EU" },
+								{ label: "USA", sales: 2000, profit: 250, region: "America" },
+								{ label: "Canada", sales: 600, profit: 30, region: "America" },
+								{ label: "Brazil", sales: 450, profit: 30, region: "America" },
+								{ label: "China", sales: 500, profit: 40, region: "Asia" },
+								{ label: "Japan", sales: 900, profit: 100, region: "Asia" }
+							]
+					});
+					var colorModel = new MeanColorModel(new Color(Color.named.red), new Color(Color.named.green));
+					new TreeMap({store: dataStore,
+								areaAttr: "sales", colorAttr: "profit", groupAttrs: ["region"],
+								colorModel: colorModel }, dom.byId("treeMap"));
+				});
+			}
+		);
+	</script>
+</head>
+<body>
+	<div id="treeMap" style="width:640px;height:640px"></div>
+</body>
+</html>
diff --git a/dojox/treemap/tests/test_drilldown.html b/dojox/treemap/tests/test_drilldown.html
new file mode 100644
index 0000000..0e00d93
--- /dev/null
+++ b/dojox/treemap/tests/test_drilldown.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../themes/TreeMap.css";
+		@import "../themes/DrillDownUp.css";
+	</style>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true">
+	</script>
+
+	<script type="text/javascript">
+
+		require(["dojo/ready", "dojo/dom", "dojo/_base/declare", "dojox/treemap/TreeMap",
+			"dojo/store/Memory", "dojox/color/MeanColorModel", "dojo/_base/Color", "dojox/treemap/DrillDownUp"],
+			function(ready, dom, declare, TreeMap, Memory, MeanColorModel, Color, DrillDownUp) {
+				ready(function(){
+					var dataStore = new Memory({idProperty: "label", data:
+							[
+								{ label: "France", sales: 500, profit: 50, region: "EU" },
+								{ label: "Germany", sales: 450, profit: 48, region: "EU" },
+								{ label: "UK", sales: 700, profit: 60, region: "EU" },
+								{ label: "USA", sales: 2000, profit: 250, region: "America" },
+								{ label: "Canada", sales: 600, profit: 30, region: "America" },
+								{ label: "Brazil", sales: 450, profit: 30, region: "America" },
+								{ label: "China", sales: 500, profit: 40, region: "Asia" },
+								{ label: "Japan", sales: 900, profit: 100, region: "Asia" }
+							]
+					});
+					var colorModel = new MeanColorModel(new Color(Color.named.red), new Color(Color.named.green));
+					new declare([TreeMap, DrillDownUp])({store: dataStore,
+								areaAttr: "sales", colorAttr: "profit", tooltipAttr: "label", groupAttrs: ["region"],
+								colorModel: colorModel }, dom.byId("treeMap"));
+				});
+			}
+		);
+	</script>
+</head>
+<body>
+	<div id="treeMap" style="width:640px;height:640px"></div>
+</body>
+</html>
diff --git a/dojox/treemap/tests/test_evt.html b/dojox/treemap/tests/test_evt.html
new file mode 100644
index 0000000..5d35667
--- /dev/null
+++ b/dojox/treemap/tests/test_evt.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../themes/TreeMap.css";
+	</style>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true">
+	</script>
+
+	<script type="text/javascript">
+
+		require(["dojo/ready", "dojo/dom", "dojox/treemap/TreeMap",
+			"dojo/store/Memory", "dojox/color/MeanColorModel", "dojo/_base/Color"],
+			function(ready, dom, TreeMap, Memory, MeanColorModel, Color) {
+				ready(function(){
+					var dataStore = new Memory({idProperty: "label", data:
+							[
+								{ label: "France", sales: 500, profit: 50, region: "EU" },
+								{ label: "Germany", sales: 450, profit: 48, region: "EU" },
+								{ label: "UK", sales: 700, profit: 60, region: "EU" },
+								{ label: "USA", sales: 2000, profit: 250, region: "America" },
+								{ label: "Canada", sales: 600, profit: 30, region: "America" },
+								{ label: "Brazil", sales: 450, profit: 30, region: "America" },
+								{ label: "China", sales: 500, profit: 40, region: "Asia" },
+								{ label: "Japan", sales: 900, profit: 100, region: "Asia" }
+							]
+					});
+					var colorModel = new MeanColorModel(new Color(Color.named.red), new Color(Color.named.green));
+					var treeMap = new TreeMap({store: dataStore,
+								areaAttr: "sales", colorAttr: "profit", groupAttrs: ["region"],
+								colorModel: colorModel }, dom.byId("treeMap"));
+					treeMap.on("change", function(e){
+						if(e.newValue){
+							dom.byId("output").innerHTML = e.newValue.label;
+						}
+					});
+				});
+			}
+		);
+	</script>
+</head>
+<body>
+	<div id="treeMap" style="width:640px;height:640px"></div>
+	<div id="output"></div>
+</body>
+</html>
diff --git a/dojox/treemap/tests/test_func.html b/dojox/treemap/tests/test_func.html
new file mode 100644
index 0000000..128ae57
--- /dev/null
+++ b/dojox/treemap/tests/test_func.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../themes/TreeMap.css";
+	</style>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true">
+	</script>
+
+	<script type="text/javascript">
+
+		require(["dojo/ready", "dojo/dom", "dojox/treemap/TreeMap",
+			"dojo/store/Memory", "dojox/color/MeanColorModel", "dojo/_base/Color"],
+			function(ready, dom, TreeMap, Memory, MeanColorModel, Color) {
+				ready(function(){
+					var dataStore = new Memory({idProperty: "label", data:
+							[
+								{ label: "France", sales: 500, profit: 50, region: "EU" },
+								{ label: "Germany", sales: 450, profit: 48, region: "EU" },
+								{ label: "UK", sales: 700, profit: 60, region: "EU" },
+								{ label: "USA", sales: 2000, profit: 250, region: "America" },
+								{ label: "Canada", sales: 600, profit: 30, region: "America" },
+								{ label: "Brazil", sales: 450, profit: 30, region: "America" },
+								{ label: "China", sales: 500, profit: 40, region: "Asia" },
+								{ label: "Japan", sales: 900, profit: 100, region: "Asia" }
+							]
+					});
+					var colorModel = new MeanColorModel(new Color(Color.named.red), new Color(Color.named.green));
+					new TreeMap({store: dataStore,
+								areaAttr: "sales",
+								colorFunc: function(item){
+									// use benefit % instead of absolute profit
+									return item.profit / item.sales;
+								},
+								groupAttrs: ["region"],
+								colorModel: colorModel,
+								query: function(item){
+									return item.sales > 500;
+								}}, dom.byId("treeMap"));
+				});
+			}
+		);
+	</script>
+</head>
+<body>
+	<div id="treeMap" style="width:640px;height:640px"></div>
+</body>
+</html>
diff --git a/dojox/treemap/tests/test_grouplabel.html b/dojox/treemap/tests/test_grouplabel.html
new file mode 100644
index 0000000..8bcb5d7
--- /dev/null
+++ b/dojox/treemap/tests/test_grouplabel.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../themes/TreeMap.css";
+		@import "../themes/GroupLabel.css";
+	</style>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true">
+	</script>
+
+	<script type="text/javascript">
+
+		require(["dojo/ready", "dojo/dom", "dojo/_base/declare", "dojox/treemap/TreeMap",
+			"dojo/store/Memory", "dojox/color/MeanColorModel", "dojo/_base/Color", "dojox/treemap/GroupLabel"],
+			function(ready, dom, declare, TreeMap, Memory, MeanColorModel, Color, GroupLabel) {
+				ready(function(){
+					var dataStore = new Memory({idProperty: "label", data:
+							[
+								{ label: "France", sales: 500, profit: 50, region: "EU" },
+								{ label: "Germany", sales: 450, profit: 48, region: "EU" },
+								{ label: "UK", sales: 700, profit: 60, region: "EU" },
+								{ label: "USA", sales: 2000, profit: 250, region: "America" },
+								{ label: "Canada", sales: 600, profit: 30, region: "America" },
+								{ label: "Brazil", sales: 450, profit: 30, region: "America" },
+								{ label: "China", sales: 500, profit: 40, region: "Asia" },
+								{ label: "Japan", sales: 900, profit: 100, region: "Asia" }
+							]
+					});
+					var colorModel = new MeanColorModel(new Color(Color.named.red), new Color(Color.named.green));
+					new declare([TreeMap, GroupLabel])({store: dataStore,
+								areaAttr: "sales", colorAttr: "profit", tooltipAttr: "label", groupAttrs: ["region"],
+								colorModel: colorModel }, dom.byId("treeMap"));
+				});
+			}
+		);
+	</script>
+</head>
+<body>
+	<div id="treeMap" style="width:640px;height:640px"></div>
+</body>
+</html>
diff --git a/dojox/treemap/tests/test_key.html b/dojox/treemap/tests/test_key.html
new file mode 100644
index 0000000..d06a2bc
--- /dev/null
+++ b/dojox/treemap/tests/test_key.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../themes/TreeMap.css";
+	</style>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true">
+	</script>
+
+	<script type="text/javascript">
+
+		require(["dojo/ready", "dojo/dom", "dojo/_base/declare", "dojox/treemap/TreeMap",
+			"dojo/store/Memory", "dojox/color/MeanColorModel", "dojo/_base/Color", "dojox/treemap/Keyboard"],
+			function(ready, dom, declare, TreeMap, Memory, MeanColorModel, Color, Keyboard) {
+				ready(function(){
+					var dataStore = new Memory({idProperty: "label", data:
+							[
+								{ label: "France", sales: 500, profit: 50, region: "EU" },
+								{ label: "Germany", sales: 450, profit: 48, region: "EU" },
+								{ label: "UK", sales: 700, profit: 60, region: "EU" },
+								{ label: "USA", sales: 2000, profit: 250, region: "America" },
+								{ label: "Canada", sales: 600, profit: 30, region: "America" },
+								{ label: "Brazil", sales: 450, profit: 30, region: "America" },
+								{ label: "China", sales: 500, profit: 40, region: "Asia" },
+								{ label: "Japan", sales: 900, profit: 100, region: "Asia" }
+							]
+					});
+					var colorModel = new MeanColorModel(new Color(Color.named.red), new Color(Color.named.green));
+					new declare([TreeMap, Keyboard])({store: dataStore,
+								areaAttr: "sales", colorAttr: "profit", tooltipAttr: "label", groupAttrs: ["region"],
+								colorModel: colorModel }, dom.byId("treeMap"));
+				});
+			}
+		);
+	</script>
+</head>
+<body>
+	<div id="treeMap" style="width:640px;height:640px"></div>
+</body>
+</html>
diff --git a/dojox/treemap/tests/test_props.html b/dojox/treemap/tests/test_props.html
new file mode 100644
index 0000000..faa3163
--- /dev/null
+++ b/dojox/treemap/tests/test_props.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../themes/TreeMap.css";
+	</style>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true">
+	</script>
+
+	<script type="text/javascript">
+
+		require(["dojo/ready", "dojo/dom", "dojox/treemap/TreeMap",
+			"dojo/store/Memory", "dojox/color/MeanColorModel", "dojo/_base/Color"],
+			function(ready, dom, TreeMap, Memory, MeanColorModel, Color) {
+				ready(function(){
+					var dataStore = new Memory({idProperty: "label", data:
+							[
+								{ label: "France", sales: 500, profit: 50, region: "EU" },
+								{ label: "Germany", sales: 450, profit: 48, region: "EU" },
+								{ label: "UK", sales: 700, profit: 60, region: "EU" },
+								{ label: "USA", sales: 2000, profit: 250, region: "America" },
+								{ label: "Canada", sales: 600, profit: 30, region: "America" },
+								{ label: "Brazil", sales: 450, profit: 30, region: "America" },
+								{ label: "China", sales: 500, profit: 40, region: "Asia" },
+								{ label: "Japan", sales: 900, profit: 100, region: "Asia" }
+							]
+					});
+					var colorModel = new MeanColorModel(new Color(Color.named.red), new Color(Color.named.green));
+					new TreeMap({store: dataStore, labelThreshold: 1, selectedItem:  dataStore.get("France") ,
+								areaAttr: "sales", colorAttr: "profit", groupAttrs: ["region"],
+								colorModel: colorModel }, dom.byId("treeMap"));
+				});
+			}
+		);
+	</script>
+</head>
+<body>
+	<div id="treeMap" style="width:640px;height:640px"></div>
+</body>
+</html>
diff --git a/dojox/treemap/tests/test_scaledlabel.html b/dojox/treemap/tests/test_scaledlabel.html
new file mode 100644
index 0000000..7c2cd7d
--- /dev/null
+++ b/dojox/treemap/tests/test_scaledlabel.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../themes/TreeMap.css";
+	</style>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true">
+	</script>
+
+	<script type="text/javascript">
+
+		require(["dojo/ready", "dojo/dom", "dojo/_base/declare", "dojox/treemap/TreeMap",
+			"dojo/store/Memory", "dojox/color/MeanColorModel", "dojo/_base/Color", "dojox/treemap/ScaledLabel"],
+			function(ready, dom, declare, TreeMap, Memory, MeanColorModel, Color, ScaledLabel) {
+				ready(function(){
+					var dataStore = new Memory({idProperty: "label", data:
+							[
+								{ label: "France", sales: 500, profit: 50, region: "EU" },
+								{ label: "Germany", sales: 450, profit: 48, region: "EU" },
+								{ label: "UK", sales: 700, profit: 60, region: "EU" },
+								{ label: "USA", sales: 2000, profit: 250, region: "America" },
+								{ label: "Canada", sales: 600, profit: 30, region: "America" },
+								{ label: "Brazil", sales: 450, profit: 30, region: "America" },
+								{ label: "China", sales: 500, profit: 40, region: "Asia" },
+								{ label: "Japan", sales: 900, profit: 100, region: "Asia" }
+							]
+					});
+					var colorModel = new MeanColorModel(new Color(Color.named.red), new Color(Color.named.green));
+					new declare([TreeMap, ScaledLabel])({store: dataStore,
+								areaAttr: "sales", colorAttr: "profit", tooltipAttr: "label", groupAttrs: ["region"],
+								colorModel: colorModel }, dom.byId("treeMap"));
+				});
+			}
+		);
+	</script>
+</head>
+<body>
+	<div id="treeMap" style="width:640px;height:640px"></div>
+</body>
+</html>
diff --git a/dojox/treemap/tests/test_style.html b/dojox/treemap/tests/test_style.html
new file mode 100644
index 0000000..7b691c3
--- /dev/null
+++ b/dojox/treemap/tests/test_style.html
@@ -0,0 +1,65 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../themes/TreeMap.css";
+
+		.dojoxTreeMap {
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			font-size: 16px;
+			text-align: center;
+			background: none;
+		}
+
+		.dojoxTreeMapLeaf {
+			-webkit-border-radius: 15px 15px;
+			-moz-border-radius: 15px 15px;
+			border-radius: 15px 15px;
+			margin: 1px;
+		}
+
+		.dojoxTreeMapHeader {
+			text-align: center;
+			-webkit-border-radius: 15px 15px;
+			-moz-border-radius: 15px 15px;
+			border-radius: 15px 15px;
+			background:  #0B8CD4;
+		}
+	</style>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true">
+	</script>
+
+	<script type="text/javascript">
+
+		require(["dojo/ready", "dojo/dom", "dojox/treemap/TreeMap",
+			"dojo/store/Memory", "dojox/color/MeanColorModel", "dojo/_base/Color"],
+			function(ready, dom, TreeMap, Memory, MeanColorModel, Color) {
+				ready(function(){
+					var dataStore = new Memory({idProperty: "label", data:
+							[
+								{ label: "France", sales: 500, profit: 50, region: "EU" },
+								{ label: "Germany", sales: 450, profit: 48, region: "EU" },
+								{ label: "UK", sales: 700, profit: 60, region: "EU" },
+								{ label: "USA", sales: 2000, profit: 250, region: "America" },
+								{ label: "Canada", sales: 600, profit: 30, region: "America" },
+								{ label: "Brazil", sales: 450, profit: 30, region: "America" },
+								{ label: "China", sales: 500, profit: 40, region: "Asia" },
+								{ label: "Japan", sales: 900, profit: 100, region: "Asia" }
+							]
+					});
+					var colorModel = new MeanColorModel(new Color(Color.named.red), new Color(Color.named.green));
+					new TreeMap({store: dataStore,
+								areaAttr: "sales", colorAttr: "profit", groupAttrs: ["region"],
+								colorModel: colorModel }, dom.byId("treeMap"));
+				});
+			}
+		);
+	</script>
+</head>
+<body>
+	<div id="treeMap" style="width:640px;height:640px"></div>
+</body>
+</html>
diff --git a/dojox/treemap/themes/DrillDownUp.css b/dojox/treemap/themes/DrillDownUp.css
new file mode 100644
index 0000000..f8fb0b9
--- /dev/null
+++ b/dojox/treemap/themes/DrillDownUp.css
@@ -0,0 +1,3 @@
+.dojoxTreeMapGroup.dojoxTreeMapSelected:before {
+	border: none;
+}
\ No newline at end of file
diff --git a/dojox/treemap/themes/GroupLabel.css b/dojox/treemap/themes/GroupLabel.css
new file mode 100644
index 0000000..359a529
--- /dev/null
+++ b/dojox/treemap/themes/GroupLabel.css
@@ -0,0 +1,7 @@
+.dojoxTreeMapLeaf {
+	border: none;
+}
+
+.dojoxTreeMapGroupContent_0 {
+	border: 1px solid black;
+}
diff --git a/dojox/treemap/themes/MobileTreeMap.css b/dojox/treemap/themes/MobileTreeMap.css
new file mode 100644
index 0000000..639fca2
--- /dev/null
+++ b/dojox/treemap/themes/MobileTreeMap.css
@@ -0,0 +1,35 @@
+.dojoxTreeMap {
+	background-color: #EBEADB;
+	font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+
+.dojoxTreeMapLeaf {
+	border: 1px solid black;
+}
+
+.dojoxTreeMapGroup {
+}
+
+.dojoxTreeMapGroupContent {
+}
+
+.dojoxTreeMapHeader {
+	background-color: white;
+	border: 1px solid black;
+}
+
+.dojoxTreeMapSelected {
+	border-color: red;
+}
+
+.dojoxTreeMapGroup.dojoxTreeMapSelected:before {
+	content: '';
+	position: absolute;
+	left: 1px;
+	top: 1px;
+	right: 1px;
+	bottom: 1px;
+	border: 1px solid red;
+	pointer-events: none;
+	z-index: 20;
+}
diff --git a/dojox/treemap/themes/TreeMap.css b/dojox/treemap/themes/TreeMap.css
new file mode 100644
index 0000000..daf3d33
--- /dev/null
+++ b/dojox/treemap/themes/TreeMap.css
@@ -0,0 +1,81 @@
+.dojoxTreeMap {
+	background-color: #EBEADB;
+	font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+
+.dojoxTreeMapLeaf {
+	border: 1px solid black;
+	padding: 3px;
+}
+
+.dojoxTreeMapGroup {
+}
+
+.dojoxTreeMapGroupContent {
+}
+
+.dojoxTreeMapHeader {
+	background-color: white;
+	border: 1px solid black;
+}
+
+/* on desktop recent browsers you may prefer to use :hover pseudo-class instead
+   of dojoxTreeMapHovered */
+
+.dojoxTreeMapLeaf.dojoxTreeMapHovered {
+	border-color: white;
+}
+
+.dojoxTreeMapGroup.dojoxTreeMapHovered {
+}
+
+.dojoxTreeMapSelected {
+	border-color: red;
+}
+
+.dojoxTreeMapSelected:before {
+	content: '';
+	position: absolute;
+	left: 0px;
+	top: 0px;
+	right: 0px;
+	bottom: 0px;
+	border: 3px dashed red;
+	pointer-events: none;
+	z-index: 20;
+}
+
+.dojoxTreeMapGroup.dojoxTreeMapSelected:before {
+	content: '';
+	position: absolute;
+	left: 1px;
+	top: 1px;
+	right: 1px;
+	bottom: 1px;
+	border: 1px solid red;
+	pointer-events: none;
+	z-index: 20;
+}
+
+.dojoxTreeMapSelected:before {
+	content: '';
+	position: absolute;
+	left: 0px;
+	top: 0px;
+	right: 0px;
+	bottom: 0px;
+	border: 2px dashed white;
+	pointer-events: none;
+	z-index: 20;
+}
+
+.dojoxTreeMapGroup.dojoxTreeMapSelected{
+	border:2px dashed red;
+}
+
+.dj_iequircks .dojoxTreeMapIEHack.dojoxTreeMapSelected,
+.dj_ie7 .dojoxTreeMapIEHack.dojoxTreeMapSelected + div,
+.dj_ie8 .dojoxTreeMapIEHack.dojoxTreeMapSelected + div {
+	border:  1px solid red;
+	z-index: 20;
+}
diff --git a/dojox/uuid.js b/dojox/uuid.js
index 962bd99..5038ad4 100644
--- a/dojox/uuid.js
+++ b/dojox/uuid.js
@@ -1,3 +1,11 @@
 define(['dojox/uuid/_base'], function(uuid){
+
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/uuid modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
 	return uuid;
 });
diff --git a/dojox/uuid/Uuid.js b/dojox/uuid/Uuid.js
index 740b229..489dc1a 100644
--- a/dojox/uuid/Uuid.js
+++ b/dojox/uuid/Uuid.js
@@ -110,10 +110,10 @@ dojox.uuid.Uuid.prototype.getVariant = function(){
 	//		var variant = uuid.getVariant();
 	//		dojox.uuid.assert(variant == dojox.uuid.variant.DCE);
 	// example:
-	// "3b12f1df-5232-4804-897e-917bf397618a"
-	//                     ^
-	//                     |
-	//         (variant "10__" == DCE)
+	// | "3b12f1df-5232-4804-897e-917bf397618a"
+	// |                     ^
+	// |                     |
+	// |         (variant "10__" == DCE)
 	return dojox.uuid.getVariant(this);
 };
 
diff --git a/dojox/uuid/_base.js b/dojox/uuid/_base.js
index 5a6fa98..29cbc29 100644
--- a/dojox/uuid/_base.js
+++ b/dojox/uuid/_base.js
@@ -81,10 +81,10 @@ dojox.uuid.getVariant = function(/*String*/ uuidString){
 	//		var variant = dojox.uuid.getVariant("3b12f1df-5232-4804-897e-917bf397618a");
 	//		dojox.uuid.assert(variant == dojox.uuid.variant.DCE);
 	// example:
-	// "3b12f1df-5232-4804-897e-917bf397618a"
-	//                     ^
-	//                     |
-	//         (variant "10__" == DCE)
+	//	|	"3b12f1df-5232-4804-897e-917bf397618a"
+	//	|                   ^
+	//	|                   |
+	//	|       (variant "10__" == DCE)
 	if(!dojox.uuid._ourVariantLookupTable){
 		var variant = dojox.uuid.variant;
 		var lookupTable = [];
@@ -134,9 +134,9 @@ dojox.uuid.getVersion = function(/*String*/ uuidString){
 	uuidString = uuidString.toString();
 	
 		// "b4308fb0-86cd-11da-a72b-0800200c9a66"
-		//                ^
-		//                |
-		//       (version 1 == TIME_BASED)
+		//			      ^
+		//			      |
+		//		 (version 1 == TIME_BASED)
 	var versionCharacter = uuidString.charAt(14);
 	var HEX_RADIX = 16;
 	var versionNumber = parseInt(versionCharacter, HEX_RADIX);
@@ -165,7 +165,8 @@ dojox.uuid.getTimestamp = function(/*String*/ uuidString, /*String?*/ returnType
 	//		the timestamp value encoded in the UUID.  The caller can ask for the
 	//		timestamp to be returned either as a JavaScript Date object or as a
 	//		15-character string of hex digits.
-	// returnType: Any of these five values: "string", String, "hex", "date", Date
+	// returnType:
+	//		Any of these five values: "string", String, "hex", "date", Date
 	// returns:
 	//		Returns the timestamp value as a JavaScript Date object or a 15-character string of hex digits.
 	// examples:
diff --git a/dojox/uuid/generateTimeBasedUuid.js b/dojox/uuid/generateTimeBasedUuid.js
index da58816..f47ce9f 100644
--- a/dojox/uuid/generateTimeBasedUuid.js
+++ b/dojox/uuid/generateTimeBasedUuid.js
@@ -4,7 +4,7 @@ dojox.uuid.generateTimeBasedUuid = function(/*String?*/ node){
 	// summary:
 	//		This function generates time-based UUIDs, meaning "version 1" UUIDs.
 	// description:
-	// For more info, see
+	//		For more info, see
 	//		http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt
 	//		http://www.infonuovo.com/dma/csdocs/sketch/instidid.htm
 	//		http://kruithof.xs4all.nl/uuid/uuidgen
@@ -52,7 +52,7 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 	this.GREGORIAN_CHANGE_OFFSET_IN_HOURS = 3394248;
 	
 	// Number of seconds between October 15, 1582 and January 1, 1970:
-	//   dojox.uuid.generateTimeBasedUuid.GREGORIAN_CHANGE_OFFSET_IN_SECONDS = 12219292800;
+	//	 dojox.uuid.generateTimeBasedUuid.GREGORIAN_CHANGE_OFFSET_IN_SECONDS = 12219292800;
 	
 	// --------------------------------------------------
 	// Private variables:
diff --git a/dojox/validate.js b/dojox/validate.js
index a6e10d1..c6c78ce 100644
--- a/dojox/validate.js
+++ b/dojox/validate.js
@@ -1,8 +1,12 @@
 define(["./validate/_base"], function(validate){
-	/*===== 
-	dojox.validate = {
-		// summary: Additional validation routines for Strings, Numbers, credit cards, and other esoteric needs. 
-	};
-	=====*/
+
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/validate modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
+
 	return validate;
 });
diff --git a/dojox/validate/_base.js b/dojox/validate/_base.js
index f612d30..16cccc8 100644
--- a/dojox/validate/_base.js
+++ b/dojox/validate/_base.js
@@ -5,21 +5,19 @@ define([
 	"./regexp" // additional expressions
 ], function(lang, regexp, number, xregexp) {
 
-	var validate = lang.getObject("dojox.validate", true);
-	/*=====
-		validate = dojox.validate;
-	=====*/
+var validate = lang.getObject("dojox.validate", true);
 
-validate.isText = function(/*String*/value, /*Object?*/flags){
+validate.isText = function(value, flags){
 	// summary:
-	//	Checks if a string has non whitespace characters.
-	//	Parameters allow you to constrain the length.
+	//		Checks if a string has non whitespace characters.
+	//		Parameters allow you to constrain the length.
+	// value: String
+	// flags: Object?
+	//		{length: Number, minlength: Number, maxlength: Number}
 	//
-	// value: A string
-	// flags: {length: Number, minlength: Number, maxlength: Number}
-	//    flags.length  If set, checks if there are exactly flags.length number of characters.
-	//    flags.minlength  If set, checks if there are at least flags.minlength number of characters.
-	//    flags.maxlength  If set, checks if there are at most flags.maxlength number of characters.
+	//		- flags.length  If set, checks if there are exactly flags.length number of characters.
+	//		- flags.minlength  If set, checks if there are at least flags.minlength number of characters.
+	//		- flags.maxlength  If set, checks if there are at most flags.maxlength number of characters.
 	
 	flags = (typeof flags == "object") ? flags : {};
 	
@@ -36,16 +34,17 @@ validate.isText = function(/*String*/value, /*Object?*/flags){
 };
 
 validate._isInRangeCache = {};
-validate.isInRange = function(/*String*/value, /*Object?*/flags){
+validate.isInRange = function(value, flags){
 	// summary:
-	//	Validates whether a string denoting a number
-	//	is between a max and min.
+	//		Validates whether a string denoting a number
+	//		is between a max and min.
+	// value: String
+	// flags: Object?
+	//		{max:Number, min:Number, decimal:String}
 	//
-	// value: A string
-	// flags: {max:Number, min:Number, decimal:String}
-	//    flags.max  A number, which the value must be less than or equal to for the validation to be true.
-	//    flags.min  A number, which the value must be greater than or equal to for the validation to be true.
-	//    flags.decimal  The character used for the decimal point.  Default is ".".
+	//		- flags.max  A number, which the value must be less than or equal to for the validation to be true.
+	//		- flags.min  A number, which the value must be greater than or equal to for the validation to be true.
+	//		- flags.decimal  The character used for the decimal point.  Default is ".".
 	
 	value = number.parse(value, flags);
 	if(isNaN(value)){
@@ -70,41 +69,36 @@ validate.isInRange = function(/*String*/value, /*Object?*/flags){
 
 };
 
-validate.isNumberFormat = function(/* String */value, /* Object? */flags){
-	// summary: Validates any sort of number based format
-	//
+validate.isNumberFormat = function(value, flags){
+	// summary:
+	//		Validates any sort of number based format
 	// description:
 	//		Validates any sort of number based format. Use it for phone numbers,
 	//		social security numbers, zip-codes, etc. The value can be validated
 	//		against one format or one of multiple formats.
 	//
-	// Format Definition
-	// |   #        Stands for a digit, 0-9.
-	// |   ?        Stands for an optional digit, 0-9 or nothing.
-	//    All other characters must appear literally in the expression.
-	//
+	//		Format Definition
+	//		|   #        Stands for a digit, 0-9.
+	//		|   ?        Stands for an optional digit, 0-9 or nothing.
+	//		All other characters must appear literally in the expression.
 	// example:
 	// |  "(###) ###-####"       ->   (510) 542-9742
 	// |  "(###) ###-#### x#???" ->   (510) 542-9742 x153
 	// |  "###-##-####"          ->   506-82-1089       i.e. social security number
 	// |  "#####-####"           ->   98225-1649        i.e. zip code
-	//
-	// value: A string
-	//
+	// value: String
 	// flags: Object?
-	//		FIXME: make pseudo-object for this
-	//		format: String
-	//
-	//    flags.format  A string or an Array of strings for multiple formats.
-	//
+	//		- flags.format  A string or an Array of strings for multiple formats.
 	// example:
-	// | // returns true:
-	// | dojox.validate.isNumberFormat("123-45", { format:"###-##" });
-	//
+	// |	require(["dojox/validate/_base"], function(validate){
+	// |		// returns true:
+	// |		validate.isNumberFormat("123-45", { format:"###-##" });
+	// |	});		
 	// example:
-	// 		Check Multiple formats:
-	// |	dojox.validate.isNumberFormat("123-45", {
-	// |		format:["### ##","###-##","## ###"]
+	//		Check Multiple formats:
+	// |	require(["dojox/validate/_base"], function(validate){
+	// |		validate.isNumberFormat("123-45", {
+	// |			format:["### ##","###-##","## ###"]
 	// |	});
 	//
 
@@ -113,7 +107,8 @@ validate.isNumberFormat = function(/* String */value, /* Object? */flags){
 };
 
 validate.isValidLuhn = function(/* String */value){
-	// summary: Validate a String value against the Luhn algorithm.
+	// summary:
+	//		Validate a String value against the Luhn algorithm.
 	// description:
 	//		Validate a String value against the Luhn algorithm to verify
 	//		its integrity.
diff --git a/dojox/validate/br.js b/dojox/validate/br.js
index ac7907b..e6be276 100755
--- a/dojox/validate/br.js
+++ b/dojox/validate/br.js
@@ -4,7 +4,6 @@ var br = lang.getObject("br", true, validate);
 br.isValidCnpj = function(/*String*/value){
 	// summary:
 	//		Validates a CNPJ/CGC number
-	//
 	// value: String
 	//		The CNPJ/CGC number in ##.###.###/####-##, ########/####-##,
 	//		############-## or ############## format
@@ -78,9 +77,10 @@ br.isValidCnpj = function(/*String*/value){
 };
 
 br.computeCnpjDv = function(/*String*/value){
-	// summary: Generate the DV code (checksum part) for a Cnpj number
-	//
-	// value: The CGC number in ##.###.###/#### or ############ format
+	// summary:
+	//		Generate the DV code (checksum part) for a Cnpj number
+	// value:
+	//		The CGC number in ##.###.###/#### or ############ format
 	if(!lang.isString(value)){
 		if(!value){
 			return "";
@@ -141,7 +141,6 @@ br.computeCnpjDv = function(/*String*/value){
 br.isValidCpf = function(/*String*/value){
 	// summary:
 	//		Validates a CPF number
-	//
 	// value: String
 	//		The CPF number in #########-## or ###########,
 	//		format
@@ -216,7 +215,6 @@ br.isValidCpf = function(/*String*/value){
 br.computeCpfDv = function(/*String*/value){
 	// summary:
 	//		Generate the DV code (checksum part) for a CPF number
-	//
 	// value: String
 	//		The CPF number in ######### format
 	if(!lang.isString(value)){
diff --git a/dojox/validate/ca.js b/dojox/validate/ca.js
index e991d18..d1b4651 100644
--- a/dojox/validate/ca.js
+++ b/dojox/validate/ca.js
@@ -1,49 +1,49 @@
 define(["dojo/_base/lang", "./_base", "./regexp", "./us"], 
  function(lang, validate, xregexp, us){
-/*=====
-
-	dojox.validate.ca = {
-		// summary: Module which includes Canadian-specific methods for dojox.validate
-	}
 
+var ca = lang.getObject("ca", true, validate);
+/*=====
+ca = {
+	// summary:
+	//		Module which includes Canadian-specific methods for dojox.validate
+};
 =====*/
 
-var ca = lang.getObject("ca", true, validate);
 lang.mixin(ca, {
 	
 	isPhoneNumber: function(/* String */value){
-		// summary: Validates Canadian 10-digit phone number for several common formats
+		// summary:
+		//		Validates Canadian 10-digit phone number for several common formats
 		return us.isPhoneNumber(value);  // Boolean
 	},
 
 	isProvince: function(/* String[2] */value) {
-		// summary: Validates Canadian province abbreviations (2 characters)
+		// summary:
+		//		Validates Canadian province abbreviations (2 characters)
 		var re = new RegExp("^" + xregexp.ca.province() + "$", "i");
 		return re.test(value); // Boolean
 	},
  
 	isSocialInsuranceNumber: function(/* String */value) {
-		// summary: Validates Canadian 9 digit social insurance number for several
+		// summary:
+		//		Validates Canadian 9 digit social insurance number for several
 		//		common formats
-		//
 		// description:
 		//		Validates Canadian 9 digit social insurance number for several
 		//		common formats. This routine only pattern matches and does not
 		//		use the Luhn Algorithm to validate number.
-		//
 		var flags = { format: [ "###-###-###", "### ### ###", "#########" ]};
 		return validate.isNumberFormat(value, flags); // Boolean
 	},
 
 	isPostalCode: function(value) {
-		// summary: Validates Canadian 6 digit postal code
-		//
+		// summary:
+		//		Validates Canadian 6 digit postal code
 		// description:
 		//		Validates Canadian 6 digit postal code.
 		//		Canadian postal codes are in the format ANA NAN,
 		//		where A is a letter and N is a digit, with a space
 		//		separating the third and fourth characters.
-		//
 		var re = new RegExp("^" + xregexp.ca.postalCode() + "$", "i");
 		return re.test(value); // Boolean
 	}
diff --git a/dojox/validate/check.js b/dojox/validate/check.js
index bd515d3..1ad466b 100644
--- a/dojox/validate/check.js
+++ b/dojox/validate/check.js
@@ -2,11 +2,6 @@ define(["dojo/_base/kernel", "dojo/_base/lang", "./_base"],
  function(kernel, lang, validate){
 kernel.experimental("dojox.validate.check");
 
-/*=====
-
-	validate = dojox.validate;
-
-=====*/
 /**
 	FIXME: How much does this overlap with dojox.form.Manager and friends?
 
@@ -75,15 +70,16 @@ kernel.experimental("dojox.validate.check");
 */
 
 validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
-	// summary: validates user input of an HTML form based on input profile
-	//
+	// summary:
+	//		validates user input of an HTML form based on input profile
 	// description:
-	//	returns an object that contains several methods summarizing the results of the validation
-	//
-	// form: form to be validated
-	// profile: specifies how the form fields are to be validated
-	// {trim:Array, uppercase:Array, lowercase:Array, ucfirst:Array, digit:Array,
-	//	required:Array, dependencies:Object, constraints:Object, confirm:Object}
+	//		returns an object that contains several methods summarizing the results of the validation
+	// form:
+	//		form to be validated
+	// profile:
+	//		specifies how the form fields are to be validated
+	//		{trim:Array, uppercase:Array, lowercase:Array, ucfirst:Array, digit:Array,
+	//		required:Array, dependencies:Object, constraints:Object, confirm:Object}
 
 	// Essentially private properties of results object
 	var missing = [];
@@ -300,24 +296,27 @@ validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 //TODO: evaluateConstraint doesn't use profile or fieldName args?
 validate.evaluateConstraint=function(profile, /*Array*/constraint, fieldName, elem){
 	// summary:
-	//	Evaluates dojo.validate.check() constraints that are specified as array
-	//	arguments
-	//
-	// description: The arrays are expected to be in the format of:
-	//      constraints:{
-	//              fieldName: [functionToCall, param1, param2, etc.],
-	//              fieldName: [[functionToCallFirst, param1],[functionToCallSecond,param2]]
-	//      }
-	//
-	//  This function evaluates a single array function in the format of:
-	//      [functionName, argument1, argument2, etc]
+	//		Evaluates dojo.validate.check() constraints that are specified as array
+	//		arguments
+	// description:
+	//		The arrays are expected to be in the format of:
+	//	|    constraints:{
+	//	|            fieldName: [functionToCall, param1, param2, etc.],
+	//	|            fieldName: [[functionToCallFirst, param1],[functionToCallSecond,param2]]
+	//	|    }
 	//
-	//  The function will be parsed out and evaluated against the incoming parameters.
+	//		This function evaluates a single array function in the format of:
+	//		[functionName, argument1, argument2, etc]
 	//
-	// profile: The dojo.validate.check() profile that this evaluation is against.
-	// constraint: The single [] array of function and arguments for the function.
-	// fieldName: The form dom name of the field being validated.
-	// elem: The form element field.
+	//		The function will be parsed out and evaluated against the incoming parameters.
+	// profile:
+	//		The dojo.validate.check() profile that this evaluation is against.
+	// constraint:
+	//		The single [] array of function and arguments for the function.
+	// fieldName:
+	//		The form dom name of the field being validated.
+	// elem:
+	//		The form element field.
 	
  	var isValidSomething = constraint[0];
 	var params = constraint.slice(1);
diff --git a/dojox/validate/creditCard.js b/dojox/validate/creditCard.js
index b979c27..ef37632 100644
--- a/dojox/validate/creditCard.js
+++ b/dojox/validate/creditCard.js
@@ -1,34 +1,29 @@
 define(["dojo/_base/lang", "./_base"], function(lang, validate){
-/*=====
 
-	dojox.validate.creditCard = {
+/*=====
+	return {
 		// summary:
 		//		Module provides validation functions for Credit Cards, using account number
-		//		rules in conjunction with the Luhn algorigthm, with a plugable card info database.
+		//		rules in conjunction with the Luhn algorigthm, with a pluggable card info database.
 	};
-
-	validate = dojox.validate;
-
 =====*/
 
 validate._cardInfo = {
-	// summary: A dictionary list of credit card abbreviations
-	//
+	// summary:
+	//		A dictionary list of credit card abbreviations
 	// description:
-	//
 	//		A hash of valid CC abbreviations and regular expressions
 	//
-	//		mc: Mastercard
-	//		ec: Eurocard
-	//		vi: Visa
-	//		ax: American Express
-	//		dc: Diners Club
-	//		bl: Carte Blanch
-	//		di: Discover
-	//		jcb: JCB
-	//		er: Enroute
-	//
-	//	example:
+	//		- mc: Mastercard
+	//		- ec: Eurocard
+	//		- vi: Visa
+	//		- ax: American Express
+	//		- dc: Diners Club
+	//		- bl: Carte Blanch
+	//		- di: Discover
+	//		- jcb: JCB
+	//		- er: Enroute
+	// example:
 	//		Define your own card, gift-card, whatever. Starts with 7,
 	//		is 15 total length.
 	//	| dojo.mixin(dojox.validate._cardInfo, {
@@ -47,19 +42,16 @@ validate._cardInfo = {
 };
 
 validate.isValidCreditCard = function(value, ccType){
-	// summary: Validate a credit card number by type with Luhn checking.
-	//
+	// summary:
+	//		Validate a credit card number by type with Luhn checking.
 	// description:
 	//		Checks if a credit card type matches the # scheme in a passed value, and if
 	//		the Luhn checksum is accurate (unless its an Enroute card, in which case
 	//		the checkSum is skipped), returning a Boolean to check against.
-	//
 	// value: String|Int
 	//		A Value (credit card number) to validate
-	//
 	// ccType: String
 	//		A credit-card abbreviation.
-	//
 	// example:
 	// |	if(dojox.validate.isValidCreditCard("12345", "mc")){
 	// |		console.log('inconceivable');
@@ -72,10 +64,8 @@ validate.isValidCreditCard = function(value, ccType){
 validate.isValidCreditCardNumber = function(value, ccType){
 	// summary:
 	//		Checks if value matches the pattern for that card or any card types if none is specified
-	//
 	// value: String|Int
 	//		CC #, white spaces and dashes are ignored
-	//
 	// ccType: String?
 	//		One of the abbreviation values in `dojox.validate._cardInfo` --
 	//		if Omitted, function returns a `|` delimited string of matching card types,
@@ -94,16 +84,12 @@ validate.isValidCreditCardNumber = function(value, ccType){
 			results.push(p);
 		}
 	}
-	return results.length ? results.join('|') : false; // String | boolean
+	return results.length ? results.join('|') : false; // String|Boolean
 };
 
 validate.isValidCvv = function(/* String|Int */value, /* String */ccType) {
 	// summary:
-	//  	Validate the security code (CCV) for a passed credit-card type.
-	//
-	// description:
-	//
-	// value:
+	//		Validate the security code (CCV) for a passed credit-card type.
 	
 	if(!lang.isString(value)){
 		value = String(value);
@@ -124,5 +110,6 @@ validate.isValidCvv = function(/* String|Int */value, /* String */ccType) {
 	return !!format && value.length && validate.isNumberFormat(value, { format: format }); // Boolean
 };
 
+// TODO: return functions defined in this module, rather than sticking them into "validate"
 return validate;
 });
diff --git a/dojox/validate/isbn.js b/dojox/validate/isbn.js
index 9553f9b..40d4522 100644
--- a/dojox/validate/isbn.js
+++ b/dojox/validate/isbn.js
@@ -1,15 +1,8 @@
 define(["dojo/_base/lang", "./_base"], function(lang, validate){
-// summary: Provides ISBN validation functions in `dojox.validate`
-//
-
-/*=====
-
-	validate = dojox.validate;
-
-=====*/
 
 validate.isValidIsbn = function(/* String */value) {
-	// summary: Validate ISBN-10 or ISBN-13 based on the length of value
+	// summary:
+	//		Validate ISBN-10 or ISBN-13 based on the length of value
 	// value: String
 	//		An ISBN to validate
 	// returns: Boolean
diff --git a/dojox/validate/regexp.js b/dojox/validate/regexp.js
index 4c4fcff..14547be 100644
--- a/dojox/validate/regexp.js
+++ b/dojox/validate/regexp.js
@@ -4,24 +4,26 @@ define(["dojo/_base/lang", "dojo/regexp", "dojox/main"],
 var dxregexp = lang.getObject("validate.regexp", true, dojox);
 dxregexp = dojox.validate.regexp = {
 	
-	ipAddress: function(/*Object?*/flags){
-		// summary: Builds a RE that matches an IP Address
-		//
+	ipAddress: function(flags){
+		// summary:
+		//		Builds a RE that matches an IP Address
 		// description:
-		//  Supports 5 formats for IPv4: dotted decimal, dotted hex, dotted octal, decimal and hexadecimal.
-		//  Supports 2 formats for Ipv6.
+		//		Supports 5 formats for IPv4: dotted decimal, dotted hex, dotted octal, decimal and hexadecimal.
+		//		Supports 2 formats for Ipv6.
+		// flags: Object?
+		//		All flags are boolean with default = true.
 		//
-		// flags  An object.  All flags are boolean with default = true.
-		//    flags.allowDottedDecimal  Example, 207.142.131.235.  No zero padding.
-		//    flags.allowDottedHex  Example, 0x18.0x11.0x9b.0x28.  Case insensitive.  Zero padding allowed.
-		//    flags.allowDottedOctal  Example, 0030.0021.0233.0050.  Zero padding allowed.
-		//    flags.allowDecimal  Example, 3482223595.  A decimal number between 0-4294967295.
-		//    flags.allowHex  Example, 0xCF8E83EB.  Hexadecimal number between 0x0-0xFFFFFFFF.
-		//      Case insensitive.  Zero padding allowed.
-		//    flags.allowIPv6   IPv6 address written as eight groups of four hexadecimal digits.
+		//		- flags.allowDottedDecimal  Example, 207.142.131.235.  No zero padding.
+		//		- flags.allowDottedHex  Example, 0x18.0x11.0x9b.0x28.  Case insensitive.  Zero padding allowed.
+		//		- flags.allowDottedOctal  Example, 0030.0021.0233.0050.  Zero padding allowed.
+		//		- flags.allowDecimal  Example, 3482223595.  A decimal number between 0-4294967295.
+		//		- flags.allowHex  Example, 0xCF8E83EB.  Hexadecimal number between 0x0-0xFFFFFFFF.
+		//		  Case insensitive.  Zero padding allowed.
+		//		- flags.allowIPv6   IPv6 address written as eight groups of four hexadecimal digits.
+		
 		//	FIXME: ipv6 can be written multiple ways IIRC
-		//    flags.allowHybrid   IPv6 address written as six groups of four hexadecimal digits
-		//      followed by the usual 4 dotted decimal digit notation of IPv4. x:x:x:x:x:x:d.d.d.d
+		//		- flags.allowHybrid   IPv6 address written as six groups of four hexadecimal digits
+		//		-   followed by the usual 4 dotted decimal digit notation of IPv4. x:x:x:x:x:x:d.d.d.d
 
 		// assign default values to missing paramters
 		flags = (typeof flags == "object") ? flags : {};
@@ -81,15 +83,17 @@ dxregexp = dojox.validate.regexp = {
 		return ipAddressRE; // String
 	},
 
-	host: function(/*Object?*/flags){
-		// summary: Builds a RE that matches a host
-		// description: A host is a named host (A-z0-9_- but not starting with -), a domain name or an IP address, possibly followed by a port number.
-		// flags: An object.
-		//	  flags.allowNamed Allow a named host for local networks. Default is false.
-		//    flags.allowIP  Allow an IP address for hostname.  Default is true.
-		//    flags.allowLocal  Allow the host to be "localhost".  Default is false.
-		//    flags.allowPort  Allow a port number to be present.  Default is true.
-		//    flags in regexp.ipAddress can be applied.
+	host: function(flags){
+		// summary:
+		//		Builds a RE that matches a host
+		// description:
+		//		A host is a named host (A-z0-9_- but not starting with -), a domain name or an IP address, possibly followed by a port number.
+		// flags: Object?
+		//		- flags.allowNamed Allow a named host for local networks. Default is false.
+		//		- flags.allowIP  Allow an IP address for hostname.  Default is true.
+		//		- flags.allowLocal  Allow the host to be "localhost".  Default is false.
+		//		- flags.allowPort  Allow a port number to be present.  Default is true.
+		//		- flags in regexp.ipAddress can be applied.
 
 		// assign default values to missing paramters
 		flags = (typeof flags == "object") ? flags : {};
@@ -116,14 +120,14 @@ dxregexp = dojox.validate.regexp = {
 
 	},
 
-	url: function(/*Object?*/flags){
-		// summary: Builds a regular expression that matches a URL
-		//
-		// flags: An object
-		//    flags.scheme  Can be true, false, or [true, false].
-		//      This means: required, not allowed, or match either one.
-		//    flags in regexp.host can be applied.
-		//    flags in regexp.ipAddress can be applied.
+	url: function(flags){
+		// summary:
+		//		Builds a regular expression that matches a URL
+		// flags: Object?
+		//		- flags.scheme  Can be true, false, or [true, false].
+		//		-   This means: required, not allowed, or match either one.
+		//		- flags in regexp.host can be applied.
+		//		- flags in regexp.ipAddress can be applied.
 
 		// assign default values to missing paramters
 		flags = (typeof flags == "object") ? flags : {};
@@ -140,14 +144,13 @@ dxregexp = dojox.validate.regexp = {
 		return protocolRE + dxregexp.host(flags) + pathRE;
 	},
 
-	emailAddress: function(/*Object?*/flags){
-
-		// summary: Builds a regular expression that matches an email address
-		//
-		//flags: An object
-		//    flags.allowCruft  Allow address like <mailto:foo at yahoo.com>.  Default is false.
-		//    flags in regexp.host can be applied.
-		//    flags in regexp.ipAddress can be applied.
+	emailAddress: function(flags){
+		// summary:
+		//		Builds a regular expression that matches an email address
+		// flags: Object?
+		//		- flags.allowCruft  Allow address like `<mailto:foo at yahoo.com>`.  Default is false.
+		//		- flags in regexp.host can be applied.
+		//		- flags in regexp.ipAddress can be applied.
 
 		// assign default values to missing paramters
 		flags = (typeof flags == "object") ? flags : {};
@@ -168,14 +171,14 @@ dxregexp = dojox.validate.regexp = {
 		return emailAddressRE; // String
 	},
 
-	emailAddressList: function(/*Object?*/flags){
-		// summary: Builds a regular expression that matches a list of email addresses.
-		//
-		// flags: An object.
-		//    flags.listSeparator  The character used to separate email addresses.  Default is ";", ",", "\n" or " ".
-		//    flags in regexp.emailAddress can be applied.
-		//    flags in regexp.host can be applied.
-		//    flags in regexp.ipAddress can be applied.
+	emailAddressList: function(flags){
+		// summary:
+		//		Builds a regular expression that matches a list of email addresses.
+		// flags: Object?
+		//		- flags.listSeparator  The character used to separate email addresses.  Default is ";", ",", "\n" or " ".
+		//		- flags in regexp.emailAddress can be applied.
+		//		- flags in regexp.host can be applied.
+		//		- flags in regexp.ipAddress can be applied.
 
 		// assign default values to missing paramters
 		flags = (typeof flags == "object") ? flags : {};
@@ -189,25 +192,27 @@ dxregexp = dojox.validate.regexp = {
 		return emailAddressListRE; // String
 	},
 	
-	numberFormat: function(/*Object?*/flags){
-		// summary: Builds a regular expression to match any sort of number based format
+	numberFormat: function(flags){
+		// summary:
+		//		Builds a regular expression to match any sort of number based format
 		// description:
-		//  Use this method for phone numbers, social security numbers, zip-codes, etc.
-		//  The RE can match one format or one of multiple formats.
+		//		Use this method for phone numbers, social security numbers, zip-codes, etc.
+		//		The RE can match one format or one of multiple formats.
+		//
+		//		Format:
 		//
-		//  Format
-		//    #        Stands for a digit, 0-9.
-		//    ?        Stands for an optional digit, 0-9 or nothing.
-		//    All other characters must appear literally in the expression.
+		//		- #        Stands for a digit, 0-9.
+		//		- ?        Stands for an optional digit, 0-9 or nothing.
+		//		- All other characters must appear literally in the expression.
 		//
-		//  Example
-		//    "(###) ###-####"       ->   (510) 542-9742
-		//    "(###) ###-#### x#???" ->   (510) 542-9742 x153
-		//    "###-##-####"          ->   506-82-1089       i.e. social security number
-		//    "#####-####"           ->   98225-1649        i.e. zip code
+		// example:
+		//		- "(###) ###-####"		-    ->   (510) 542-9742
+		//		- "(###) ###-#### x#???" ->   (510) 542-9742 x153
+		//		- "###-##-####"		- 		-   ->   506-82-1089		-    i.e. social security number
+		//		- "#####-####"		- 		-    ->   98225-1649		- 		- i.e. zip code
 		//
-		// flags:  An object
-		//    flags.format  A string or an Array of strings for multiple formats.
+		// flags:  Object?
+		//		- flags.format  A string or an Array of strings for multiple formats.
 
 		// assign default values to missing paramters
 		flags = (typeof flags == "object") ? flags : {};
@@ -231,27 +236,28 @@ dxregexp = dojox.validate.regexp = {
 	ca: {
 
 		postalCode: function(){
-			// summary: String regular Express to match Canadain Postal Codes
+			// summary:
+			//		String regular Express to match Canadain Postal Codes
 			return "([A-Z][0-9][A-Z] [0-9][A-Z][0-9])";
 		},
 
 		province: function(){
-			// summary: a regular expression to match Canadian Province Abbreviations
+			// summary:
+			//		a regular expression to match Canadian Province Abbreviations
 			return "(AB|BC|MB|NB|NL|NS|NT|NU|ON|PE|QC|SK|YT)";
 		}
 
 	},
 	
 	us:{
-
-		state: function(/*Object?*/flags){
-			// summary: A regular expression to match US state and territory abbreviations
-			//
-			// flags  An object.
-			//    flags.allowTerritories  Allow Guam, Puerto Rico, etc.  Default is true.
-			//    flags.allowMilitary  Allow military 'states', e.g. Armed Forces Europe (AE).  Default is true.
-
-			// assign default values to missing paramters
+		state: function(flags){
+			// summary:
+			//		A regular expression to match US state and territory abbreviations
+			// flags: Object?
+			//		- flags.allowTerritories  Allow Guam, Puerto Rico, etc.  Default is true.
+			//		- flags.allowMilitary  Allow military 'states', e.g. Armed Forces Europe (AE).  Default is true.
+
+			// assign default values to missing parameters
 			flags = (typeof flags == "object") ? flags : {};
 			if(typeof flags.allowTerritories != "boolean"){ flags.allowTerritories = true; }
 			if(typeof flags.allowMilitary != "boolean"){ flags.allowMilitary = true; }
diff --git a/dojox/validate/tests/creditcard.js b/dojox/validate/tests/creditcard.js
index a81a9c6..c582ee2 100644
--- a/dojox/validate/tests/creditcard.js
+++ b/dojox/validate/tests/creditcard.js
@@ -73,6 +73,7 @@ doh.register("dojox.validate.tests.creditcard",
 		name:"isValidCreditCardNumber",
 		runTest: function(tests) {
 			//misc checks
+			tests.f(validate.isValidCreditCardNumber('a4111111111111', 'vi')); //fails, alphas are not allowed
 			tests.t(validate.isValidCreditCardNumber('5105105105105100','mc')); //test string input
 			tests.t(validate.isValidCreditCardNumber('5105-1051 0510-5100','mc')); //test string input with dashes and spaces (commonly used when entering card #'s)
 			tests.t(validate.isValidCreditCardNumber(5105105105105100,'mc')); //test numerical input as well
diff --git a/dojox/validate/us.js b/dojox/validate/us.js
index 8669cbe..c24cd65 100644
--- a/dojox/validate/us.js
+++ b/dojox/validate/us.js
@@ -2,21 +2,24 @@ define(["dojo/_base/lang", "./_base", "./regexp"],
  function(lang, validate, xregexp){
 
 var us = lang.getObject("us", true, validate);
-us.isState = function(/*String*/value, /*Object?*/flags){
-	// summary: Validates US state and territory abbreviations.
-	//
-	// value: A two character string
-	// flags: An object
-	//    flags.allowTerritories  Allow Guam, Puerto Rico, etc.  Default is true.
-	//    flags.allowMilitary  Allow military 'states', e.g. Armed Forces Europe (AE).  Default is true.
+us.isState = function(value, flags){
+	// summary:
+	//		Validates US state and territory abbreviations.
+	// value: String
+	//		A two character string
+	// flags: Object?
+	//		- flags.allowTerritories  Allow Guam, Puerto Rico, etc.  Default is true.
+	//		- flags.allowMilitary  Allow military 'states', e.g. Armed Forces Europe (AE).  Default is true.
 
 	var re = new RegExp("^" + xregexp.us.state(flags) + "$", "i");
 	return re.test(value); // Boolean
 };
 
 us.isPhoneNumber = function(/*String*/value){
-	// summary: Validates 10 US digit phone number for several common formats
-	// value: The telephone number string
+	// summary:
+	//		Validates 10 US digit phone number for several common formats
+	// value:
+	//		The telephone number string
 
 	var flags = {
 		format: [
@@ -39,7 +42,8 @@ us.isPhoneNumber = function(/*String*/value){
 };
 
 us.isSocialSecurityNumber = function(/*String*/value){
-	// summary: Validates social security number
+	// summary:
+	//		Validates social security number
 	var flags = {
 		format: [
 			"###-##-####",
@@ -51,7 +55,8 @@ us.isSocialSecurityNumber = function(/*String*/value){
 };
 
 us.isZipCode = function(/*String*/value){
-	// summary: Validates U.S. zip-code
+	// summary:
+	//		Validates U.S. zip-code
 	var flags = {
 		format: [
 			"#####-####",
diff --git a/dojox/validate/web.js b/dojox/validate/web.js
index c6665fa..861029b 100644
--- a/dojox/validate/web.js
+++ b/dojox/validate/web.js
@@ -1,84 +1,81 @@
 define(["./_base", "./regexp"], function(validate, xregexp){
 
-/*=====
-
-	validate = dojox.validate;
-
-=====*/
-
-validate.isIpAddress = function(/*String*/value, /*Object?*/flags) {
-	// summary: Validates an IP address
-	//
+validate.isIpAddress = function(value, flags) {
+	// summary:
+	//		Validates an IP address
 	// description:
-	//  Supports 5 formats for IPv4: dotted decimal, dotted hex, dotted octal, decimal and hexadecimal.
-	//  Supports 2 formats for Ipv6.
+	//		Supports 5 formats for IPv4: dotted decimal, dotted hex, dotted octal, decimal and hexadecimal.
+	//		Supports 2 formats for Ipv6.
+	// value: String
+	// flags: Object?
+	//		All flags are boolean with default = true.
 	//
-	// value  A string.
-	// flags  An object.  All flags are boolean with default = true.
-	//    flags.allowDottedDecimal  Example, 207.142.131.235.  No zero padding.
-	//    flags.allowDottedHex  Example, 0x18.0x11.0x9b.0x28.  Case insensitive.  Zero padding allowed.
-	//    flags.allowDottedOctal  Example, 0030.0021.0233.0050.  Zero padding allowed.
-	//    flags.allowDecimal  Example, 3482223595.  A decimal number between 0-4294967295.
-	//    flags.allowHex  Example, 0xCF8E83EB.  Hexadecimal number between 0x0-0xFFFFFFFF.
-	//      Case insensitive.  Zero padding allowed.
-	//    flags.allowIPv6   IPv6 address written as eight groups of four hexadecimal digits.
-	//    flags.allowHybrid   IPv6 address written as six groups of four hexadecimal digits
-	//      followed by the usual 4 dotted decimal digit notation of IPv4. x:x:x:x:x:x:d.d.d.d
+	//		- flags.allowDottedDecimal  Example, 207.142.131.235.  No zero padding.
+	//		- flags.allowDottedHex  Example, 0x18.0x11.0x9b.0x28.  Case insensitive.  Zero padding allowed.
+	//		- flags.allowDottedOctal  Example, 0030.0021.0233.0050.  Zero padding allowed.
+	//		- flags.allowDecimal  Example, 3482223595.  A decimal number between 0-4294967295.
+	//		- flags.allowHex  Example, 0xCF8E83EB.  Hexadecimal number between 0x0-0xFFFFFFFF.
+	//		  Case insensitive.  Zero padding allowed.
+	//		- flags.allowIPv6   IPv6 address written as eight groups of four hexadecimal digits.
+	//		- flags.allowHybrid   IPv6 address written as six groups of four hexadecimal digits
+	//		  followed by the usual 4 dotted decimal digit notation of IPv4. x:x:x:x:x:x:d.d.d.d
 
 	var re = new RegExp("^" + xregexp.ipAddress(flags) + "$", "i");
 	return re.test(value); // Boolean
 };
 
 
-validate.isUrl = function(/*String*/value, /*Object?*/flags) {
-	// summary: Checks if a string could be a valid URL
-	// value: A string
-	// flags: An object
-	//    flags.scheme  Can be true, false, or [true, false].
-	//      This means: required, not allowed, or either.
-	//    flags in regexp.host can be applied.
-	//    flags in regexp.ipAddress can be applied.
-	//    flags in regexp.tld can be applied.
+validate.isUrl = function(value, flags) {
+	// summary:
+	//		Checks if a string could be a valid URL
+	// value: String
+	// flags: Object?
+	//		- flags.scheme  Can be true, false, or [true, false].
+	//		  This means: required, not allowed, or either.
+	//		- flags in regexp.host can be applied.
+	//		- flags in regexp.ipAddress can be applied.
+	//		- flags in regexp.tld can be applied.
 
 	var re = new RegExp("^" + xregexp.url(flags) + "$", "i");
 	return re.test(value); // Boolean
 };
 
-validate.isEmailAddress = function(/*String*/value, /*Object?*/flags) {
-	// summary: Checks if a string could be a valid email address
-	//
-	// value: A string
-	// flags: An object
-	//    flags.allowCruft  Allow address like <mailto:foo at yahoo.com>.  Default is false.
-	//    flags in regexp.host can be applied.
-	//    flags in regexp.ipAddress can be applied.
-	//    flags in regexp.tld can be applied.
+validate.isEmailAddress = function(value, flags) {
+	// summary:
+	//		Checks if a string could be a valid email address
+	// value: String
+	// flags: Object?
+	//		- flags.allowCruft  Allow address like `<mailto:foo at yahoo.com>`.  Default is false.
+	//		- flags in regexp.host can be applied.
+	//		- flags in regexp.ipAddress can be applied.
+	//		- flags in regexp.tld can be applied.
 
 	var re = new RegExp("^" + xregexp.emailAddress(flags) + "$", "i");
 	return re.test(value); // Boolean
 };
 
-validate.isEmailAddressList = function(/*String*/value, /*Object?*/flags) {
-	// summary: Checks if a string could be a valid email address list.
-	//
-	// value  A string.
-	// flags  An object.
-	//    flags.listSeparator  The character used to separate email addresses.  Default is ";", ",", "\n" or " ".
-	//    flags in regexp.emailAddress can be applied.
-	//    flags in regexp.host can be applied.
-	//    flags in regexp.ipAddress can be applied.
-	//    flags in regexp.tld can be applied.
+validate.isEmailAddressList = function(value, flags) {
+	// summary:
+	//		Checks if a string could be a valid email address list.
+	// value: String
+	// flags: Object?
+	//		- flags.listSeparator  The character used to separate email addresses.  Default is ";", ",", "\n" or " ".
+	//		- flags in regexp.emailAddress can be applied.
+	//		- flags in regexp.host can be applied.
+	//		- flags in regexp.ipAddress can be applied.
+	//		- flags in regexp.tld can be applied.
 
 	var re = new RegExp("^" + xregexp.emailAddressList(flags) + "$", "i");
 	return re.test(value); // Boolean
 };
 
-validate.getEmailAddressList = function(/*String*/value, /*Object?*/flags) {
-	// summary: Check if value is an email address list. If an empty list
-	//  is returned, the value didn't pass the test or it was empty.
-	//
-	// value: A string
-	// flags: An object (same as dojo.validate.isEmailAddressList)
+validate.getEmailAddressList = function(value, flags) {
+	// summary:
+	//		Check if value is an email address list. If an empty list
+	//		is returned, the value didn't pass the test or it was empty.
+	// value: String
+	// flags: Object?
+	//		An object (same as dojo.validate.isEmailAddressList)
 
 	if(!flags) { flags = {}; }
 	if(!flags.listSeparator) { flags.listSeparator = "\\s;,"; }
diff --git a/dojox/widget/AutoRotator.js b/dojox/widget/AutoRotator.js
index f66f9a2..c9a5c9a 100644
--- a/dojox/widget/AutoRotator.js
+++ b/dojox/widget/AutoRotator.js
@@ -1,62 +1,64 @@
-dojo.provide("dojox.widget.AutoRotator");
-dojo.require("dojox.widget.Rotator");
-
-(function(d){
-
-	d.declare("dojox.widget.AutoRotator", dojox.widget.Rotator, {
-		//	summary:
-		//		A rotator that automatically transitions between child nodes.
-		//
-		//	description:
-		//		Adds automatic rotating to the dojox.widget.Rotator.  The
-		//		AutoRotator has parameters that control how user input can
-		//		affect the rotator including a suspend when hovering over the
-		//		rotator and pausing when the user manually advances to another
-		//		pane.
-		//
-		//	example:
-		//	|	<div dojoType="dojox.widget.AutoRotator" duration="3000">
-		//	|		<div>
-		//	|			Pane 1!
-		//	|		</div>
-		//	|		<div duration="5000">
-		//	|			Pane 2 with an overrided duration!
-		//	|		</div>
-		//	|	</div>
-
-		//	suspendOnHover: boolean
-		//		Pause the rotator when the mouse hovers over it.
-		suspendOnHover: false,
-
-		//	duration: int
-		//		The time in milliseconds before transitioning to the next pane.  The
-		//		default value is 4000 (4 seconds).
-		duration: 4000,
-
-		//	autoStart: boolean
-		//		Starts the timer to transition children upon creation.
-		autoStart: true,
-
-		//	pauseOnManualChange: boolean
-		//		Pause the rotator when the pane is changed or a controller's next or
-		//		previous buttons are clicked.
-		pauseOnManualChange: false,
-
-		//	cycles: int
-		//		Number of cycles before pausing.
-		cycles: -1,
-
-		//	random: boolean
-		//		Determines if the panes should cycle randomly.
-		random: false,
-
-		//	reverse: boolean
-		//		Causes the rotator to rotate in reverse order.
-		reverse: false,
-
-		constructor: function(){
-			//	summary:
-			//		Initializes the timer and connect to the rotator.
+define([
+	"dojo/_base/declare",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/on",
+	"dojo/mouse",
+	"dojox/widget/Rotator"
+], function(declare, array, lang, on, mouse, Rotator) {
+
+return declare("dojox.widget.AutoRotator", Rotator,{
+	// summary:
+	//		A rotator that automatically transitions between child nodes.
+	// description:
+	//		Adds automatic rotating to the dojox.widget.Rotator.  The
+	//		AutoRotator has parameters that control how user input can
+	//		affect the rotator including a suspend when hovering over the
+	//		rotator and pausing when the user manually advances to another
+	//		pane.
+	// example:
+	//	|	<div dojoType="dojox.widget.AutoRotator" duration="3000">
+	//	|		<div>
+	//	|			Pane 1!
+	//	|		</div>
+	//	|		<div duration="5000">
+	//	|			Pane 2 with an overrided duration!
+	//	|		</div>
+	//	|	</div>
+
+	// suspendOnHover: Boolean
+	//		Pause the rotator when the mouse hovers over it.
+	suspendOnHover: false,
+
+	// duration: int
+	//		The time in milliseconds before transitioning to the next pane.  The
+	//		default value is 4000 (4 seconds).
+	duration: 4000,
+	
+	// autoStart: Boolean
+	//		Starts the timer to transition children upon creation.
+	autoStart: true,
+	
+	// pauseOnManualChange: Boolean
+	//		Pause the rotator when the pane is changed or a controller's next or
+	//		previous buttons are clicked.
+	pauseOnManualChange: false,
+	
+	// cycles: int
+	//		Number of cycles before pausing.
+	cycles: -1,
+
+	// random: Boolean
+	//		Determines if the panes should cycle randomly.
+	random: false,
+
+	// reverse: Boolean
+	//		Causes the rotator to rotate in reverse order.
+	reverse: false,
+
+  constructor: function(){
+	// summary:
+	//		Initializes the timer and connect to the rotator.
 
 			var _t = this;
 
@@ -69,8 +71,8 @@ dojo.require("dojox.widget.Rotator");
 			}
 
 			// wire up the mouse hover events
-			_t._connects = [
-				d.connect(_t._domNode, "onmouseover", function(){
+			_t._signals = [
+				on(_t._domNode, mouse.enter, function(){
 					// temporarily suspend the cycling, but don't officially pause
 					// it and don't allow suspending if we're transitioning
 					if(_t.suspendOnHover && !_t.anim && !_t.wfe){
@@ -82,7 +84,7 @@ dojo.require("dojox.widget.Rotator");
 					}
 				}),
 
-				d.connect(_t._domNode, "onmouseout", function(){
+				on(_t._domNode, mouse.leave, function(){
 					// if we were playing, resume playback unless were in the
 					// middle of a transition
 					if(_t.suspendOnHover && !_t.anim){
@@ -105,14 +107,16 @@ dojo.require("dojox.widget.Rotator");
 		},
 
 		destroy: function(){
-			//	summary:
+			// summary:
 			//		Disconnect the AutoRotator's events.
-			d.forEach(this._connects, d.disconnect);
+			array.forEach(this._signals, function(signal) { signal.remove(); });
+			delete this._signals;
+			dojo.forEach(this._connects, dojo.disconnect);
 			this.inherited(arguments);
 		},
 
-		play: function(/*boolean?*/skipCycleDecrement, /*boolean?*/skipDuration){
-			//	summary:
+		play: function(/*Boolean?*/skipCycleDecrement, /*Boolean?*/skipDuration){
+			// summary:
 			//		Sets the state to "playing" and schedules the next cycle to run.
 			this.playing = true;
 			this._resetTimer();
@@ -137,13 +141,13 @@ dojo.require("dojox.widget.Rotator");
 					// call _cycle() after a duration and pass in false so it isn't manual
 					this._resumeDuration = 0;
 					this._endTime = this._now() + u;
-					this._timer = setTimeout(d.hitch(this, "_cycle", false), u);
+					this._timer = setTimeout(lang.hitch(this, "_cycle", false), u);
 				}
 			}
 		},
 
 		pause: function(){
-			//	summary:
+			// summary:
 			//		Sets the state to "not playing" and clears the cycle timer.
 			this.playing = this._suspended = false;
 			this.cycles = -1;
@@ -154,19 +158,19 @@ dojo.require("dojox.widget.Rotator");
 		},
 
 		_now: function(){
-			//	summary:
+			// summary:
 			//		Helper function to return the current system time in milliseconds.
-			return (new Date()).getTime(); /*int*/
+			return (new Date()).getTime(); // int
 		},
 
 		_resetTimer: function(){
-			//	summary:
+			// summary:
 			//		Resets the timer used to schedule the next transition.
 			clearTimeout(this._timer);
 		},
 
-		_cycle: function(/*boolean|int?*/manual){
-			//	summary:
+		_cycle: function(/*Boolean|int?*/manual){
+			// summary:
 			//		Cycles the rotator to the next/previous pane.
 			var _t = this,
 				i = _t.idx,
@@ -185,7 +189,7 @@ dojo.require("dojox.widget.Rotator");
 			var def = _t.go(j);
 
 			if(def){
-				def.addCallback(function(/*boolean?*/skipDuration){
+				def.addCallback(function(/*Boolean?*/skipDuration){
 					_t.onUpdate("cycle");
 					if(_t.playing){
 						_t.play(false, skipDuration);
@@ -195,7 +199,7 @@ dojo.require("dojox.widget.Rotator");
 		},
 
 		onManualChange: function(/*string*/action){
-			//	summary:
+			// summary:
 			//		Override the Rotator's onManualChange so we can pause.
 
 			this.cycles = -1;
@@ -211,7 +215,6 @@ dojo.require("dojox.widget.Rotator");
 			if(this.playing){
 				this.play();
 			}
-		}
-	});
-
-})(dojo);
\ No newline at end of file
+		}		
+});
+});
diff --git a/dojox/widget/Calendar.js b/dojox/widget/Calendar.js
index 9a44fae..a421619 100644
--- a/dojox/widget/Calendar.js
+++ b/dojox/widget/Calendar.js
@@ -1,939 +1,15 @@
-dojo.provide("dojox.widget.Calendar");
-dojo.experimental("dojox.widget.Calendar");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Container");
-dojo.require("dijit.typematic");
-
-dojo.require("dojo.date");
-dojo.require("dojo.date.locale");
-
-dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dijit._Container], {
-	// summary:
-	//		The Root class for all _Calendar extensions
-
-	// templateString: String
-	//		The template to be used to construct the widget.
-	templateString: dojo.cache("dojox.widget","Calendar/Calendar.html"),
-
-	// _views: Array
-	//		The list of mixin views available on this calendar.
-	_views: null,
-
-	// useFx: Boolean
-	//		Specifies if visual effects should be applied to the widget.
-	//		The default behavior of the widget does not contain any effects.
-	//		The dojox.widget.CalendarFx package is needed for these.
-	useFx: true,
-
-	// widgetsInTemplate: Boolean
-	//		This widget is a container of other widgets, so this is true.
-	widgetsInTemplate: true,
-
-	// value: Date
-	//		The currently selected Date
-	value: new Date(),
-
-	constraints: null,
-
-	// footerFormat: String
-	//		The date format of the date displayed in the footer.	Can be
-	//		'short', 'medium', and 'long'
-	footerFormat: "medium",
-
-	constructor: function(){
-		this._views = [];
-		this.value = new Date();
-	},
-
-	postMixInProperties: function(){
-		var c = this.constraints;
-		if(c){
-			var fromISO = dojo.date.stamp.fromISOString;
-			if(typeof c.min == "string"){
-				c.min = fromISO(c.min);
-			}
-			if(typeof c.max == "string"){
-				c.max = fromISO(c.max);
-			}
-		}
-		this.value = this.parseInitialValue(this.value);
-	},
-
-	parseInitialValue: function(value){
-		if (!value || value === -1){
-			return new Date();
-		}else if(value.getFullYear){
-			return value;
-		}else if (!isNaN(value)) {
-			if (typeof this.value == "string") {
-				value = parseInt(value);
-			}
-			value = this._makeDate(value);
-		}
-		return value;
-	},
-
-	_makeDate: function(value){
-		return value;//new Date(value);
-	},
-
-	postCreate: function(){
-		// summary:
-		//		Instantiates the mixin views
-
-		this.displayMonth = new Date(this.get('value'));
-
-		if(this._isInvalidDate(this.displayMonth)){
-			this.displayMonth = new Date();
-		}
-
-		var mixin = {
-			parent: this,
-			_getValueAttr: dojo.hitch(this, function(){return new Date(this._internalValue || this.value);}),
-			_getDisplayMonthAttr: dojo.hitch(this, function(){return new Date(this.displayMonth);}),
-			_getConstraintsAttr: dojo.hitch(this, function(){return this.constraints;}),
-			getLang: dojo.hitch(this, function(){return this.lang;}),
-			isDisabledDate: dojo.hitch(this, this.isDisabledDate),
-			getClassForDate: dojo.hitch(this, this.getClassForDate),
-			addFx: this.useFx ? dojo.hitch(this, this.addFx) : function(){}
-		};
-
-		//Add the mixed in views.
-		dojo.forEach(this._views, function(widgetType){
-			var widget = new widgetType(mixin, dojo.create('div'));
-			this.addChild(widget);
-
-			var header = widget.getHeader();
-			if(header){
-			//place the views's header node in the header of the main widget
-				this.header.appendChild(header);
-
-				//hide the header node of the widget
-				dojo.style(header, "display", "none");
-			}
-			//Hide all views
-			dojo.style(widget.domNode, "visibility", "hidden");
-
-			//Listen for the values in a view to be selected
-			dojo.connect(widget, "onValueSelected", this, "_onDateSelected");
-			widget.set("value", this.get('value'));
-		}, this);
-
-		if(this._views.length < 2){
-			dojo.style(this.header, "cursor", "auto");
-		}
-
-		this.inherited(arguments);
-
-		// Cache the list of children widgets.
-		this._children = this.getChildren();
-
-		this._currentChild = 0;
-
-		//Populate the footer with today's date.
-		var today = new Date();
-
-		this.footer.innerHTML = "Today: "
-			+ dojo.date.locale.format(today, {
-				formatLength:this.footerFormat,
-				selector:'date',
-				locale:this.lang});
-
-		dojo.connect(this.footer, "onclick", this, "goToToday");
-
-		var first = this._children[0];
-
-		dojo.style(first.domNode, "top", "0px");
-		dojo.style(first.domNode, "visibility", "visible");
-
-		var header = first.getHeader();
-		if(header){
-			dojo.style(first.getHeader(), "display", "");
-		}
-
-		dojo[first.useHeader ? "removeClass" : "addClass"](this.container, "no-header");
-
-		first.onDisplay();
-
-		var _this = this;
-
-		var typematic = function(nodeProp, dateProp, adj){
-			dijit.typematic.addMouseListener(_this[nodeProp], _this, function(count){
-				if(count >= 0){	_this._adjustDisplay(dateProp, adj);}
-			}, 0.8, 500);
-		};
-		typematic("incrementMonth", "month", 1);
-		typematic("decrementMonth", "month", -1);
-		this._updateTitleStyle();
-	},
-
-	addFx: function(query, fromNode){
-		// Stub function than can be overridden to add effects.
-	},
-
-	_isInvalidDate: function(/*Date*/ value){
-		// summary:
-		//		Runs various tests on the value, checking for invalid conditions
-		// tags:
-		//		private
-		return !value || isNaN(value) || typeof value != "object" || value.toString() == this._invalidDate;
-	},
-
-	_setValueAttr: function(/*Date*/ value){
-		// summary:
-		//		Set the current date and update the UI.	If the date is disabled, the selection will
-		//		not change, but the display will change to the corresponding month.
-		if(!value){
-			value = new Date();
-		}
-		if(!value["getFullYear"]){
-			value = dojo.date.stamp.fromISOString(value + "");
-		}
-		if(this._isInvalidDate(value)){
-			return false;
-		}
-		if(!this.value || dojo.date.compare(value, this.value)){
-			value = new Date(value);
-			this.displayMonth = new Date(value);
-			this._internalValue = value;
-			if(!this.isDisabledDate(value, this.lang) && this._currentChild == 0){
-				this.value = value;
-				this.onChange(value);
-			}
-			if (this._children && this._children.length > 0) {
-				this._children[this._currentChild].set("value", this.value);
-			}
-			return true;
-		}
-		return false;
-	},
-
-	isDisabledDate: function(/*Date*/date, /*String?*/locale){
-		// summary:
-		//		May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
-		var c = this.constraints;
-		var compare = dojo.date.compare;
-		return c && (c.min && (compare(c.min, date, "date") > 0) ||
-							(c.max && compare(c.max, date, "date") < 0));
-	},
-
-	onValueSelected: function(/*Date*/date){
-		// summary:
-		//		A date cell was selected. It may be the same as the previous value.
-	},
-
-	_onDateSelected: function(date, formattedValue, force){
-		this.displayMonth = date;
-
-		this.set("value", date)
-		//Only change the selected value if it was chosen from the
-		//first child.
-		if(!this._transitionVert(-1)){
-			if(!formattedValue && formattedValue !== 0){
-				formattedValue = this.get('value');
-			}
-			this.onValueSelected(formattedValue);
-		}
-
-	},
-
-	onChange: function(/*Date*/date){
-		// summary:
-		//		Called only when the selected date has changed
-	},
-
-	onHeaderClick: function(e){
-		// summary:
-		//	Transitions to the next view.
-		this._transitionVert(1);
-	},
-
-	goToToday: function(){
-		this.set("value", new Date());
-		this.onValueSelected(this.get('value'));
-	},
-
-	_transitionVert: function(/*Number*/direction){
-		// summary:
-		//		Animates the views to show one and hide another, in a
-		//		vertical direction.
-		//		If 'direction' is 1, then the views slide upwards.
-		//		If 'direction' is -1, the views slide downwards.
-		var curWidget = this._children[this._currentChild];
-		var nextWidget = this._children[this._currentChild + direction];
-		if(!nextWidget){return false;}
-
-		dojo.style(nextWidget.domNode, "visibility", "visible");
-
-		var height = dojo.style(this.containerNode, "height");
-		nextWidget.set("value", this.displayMonth);
-
-		if(curWidget.header){
-			dojo.style(curWidget.header, "display", "none");
-		}
-		if(nextWidget.header){
-			dojo.style(nextWidget.header, "display", "");
-		}
-		dojo.style(nextWidget.domNode, "top", (height * -1) + "px");
-		dojo.style(nextWidget.domNode, "visibility", "visible");
-
-		this._currentChild += direction;
-
-		var height1 = height * direction;
-		var height2 = 0;
-		dojo.style(nextWidget.domNode, "top", (height1 * -1) + "px");
-
-		// summary: Slides two nodes vertically.
-		var anim1 = dojo.animateProperty({
-			node: curWidget.domNode,
-			properties: {top: height1},
-			onEnd: function(){
-				dojo.style(curWidget.domNode, "visibility", "hidden");
-			}
-		});
-		var anim2 = dojo.animateProperty({
-			node: nextWidget.domNode,
-			properties: {top: height2},
-			onEnd: function(){
-				nextWidget.onDisplay();
-			}
-		});
-
-		dojo[nextWidget.useHeader ? "removeClass" : "addClass"](this.container, "no-header");
-
-		anim1.play();
-		anim2.play();
-		curWidget.onBeforeUnDisplay()
-		nextWidget.onBeforeDisplay();
-
-		this._updateTitleStyle();
-		return true;
-	},
-
-	_updateTitleStyle: function(){
-		dojo[this._currentChild < this._children.length -1 ? "addClass" : "removeClass"](this.header, "navToPanel");
-	},
-
-	_slideTable: function(/*String*/widget, /*Number*/direction, /*Function*/callback){
-		// summary:
-		//		Animates the horizontal sliding of a table.
-		var table = widget.domNode;
-
-		//Clone the existing table
-		var newTable = table.cloneNode(true);
-		var left = dojo.style(table, "width");
-
-		table.parentNode.appendChild(newTable);
-
-		//Place the existing node either to the left or the right of the new node,
-		//depending on which direction it is to slide.
-		dojo.style(table, "left", (left * direction) + "px");
-
-		//Call the function that generally populates the new cloned node with new data.
-		//It may also attach event listeners.
-		callback();
-
-		//Animate the two nodes.
-		var anim1 = dojo.animateProperty({node: newTable, properties:{left: left * direction * -1}, duration: 500, onEnd: function(){
-			newTable.parentNode.removeChild(newTable);
-		}});
-		var anim2 = dojo.animateProperty({node: table, properties:{left: 0}, duration: 500});
-
-		anim1.play();
-		anim2.play();
-	},
-
-	_addView: function(view){
-		//Insert the view at the start of the array.
-		this._views.push(view);
-	},
-
-	getClassForDate: function(/*Date*/dateObject, /*String?*/locale){
-		// summary:
-		//		May be overridden to return CSS classes to associate with the date entry for the given dateObject,
-		//		for example to indicate a holiday in specified locale.
-
-/*=====
-		return ""; // String
-=====*/
-	},
-
-	_adjustDisplay: function(/*String*/part, /*int*/amount, noSlide){
-		// summary:
-		//		This function overrides the base function defined in dijit.Calendar.
-		//		It changes the displayed years, months and days depending on the inputs.
-		var child = this._children[this._currentChild];
-
-		var month = this.displayMonth = child.adjustDate(this.displayMonth, amount);
-
-		this._slideTable(child, amount, function(){
-			child.set("value", month);
-		});
-	}
-});
-
-dojo.declare("dojox.widget._CalendarView", dijit._Widget, {
-	// summary:
-	//		Base implementation for all view mixins.
-	//		All calendar views should extend this widget.
-	headerClass: "",
-
-	useHeader: true,
-
-	cloneClass: function(clazz, n, before){
-		// summary:
-		//		Clones all nodes with the class 'clazz' in a widget
-		var template = dojo.query(clazz, this.domNode)[0];
-		var i;
-		if(!before){
-			for(i = 0; i < n; i++){
-				template.parentNode.appendChild(template.cloneNode(true));
-			}
-		}else{
-			var bNode = dojo.query(clazz, this.domNode)[0];
-			for(i = 0; i < n; i++){
-				template.parentNode.insertBefore(template.cloneNode(true), bNode);
-			}
-		}
-	},
-
-	_setText: function(node, text){
-		// summary:
-		//		Sets the text inside a node
-		if(node.innerHTML != text){
-			dojo.empty(node);
-			node.appendChild(dojo.doc.createTextNode(text));
-		}
-	},
-
-	getHeader: function(){
-		// summary:
-		//		Returns the header node of a view. If none exists,
-		//		an empty DIV is created and returned.
-		return this.header || (this.header = this.header = dojo.create("span", { "class":this.headerClass }));
-	},
-
-	onValueSelected: function(date){
-		//Stub function called when a date is selected
-	},
-
-	adjustDate: function(date, amount){
-		// summary:
-		//		Adds or subtracts values from a date.
-		//		The unit, e.g. "day", "month" or "year", is
-		//		specified in the "datePart" property of the
-		//		calendar view mixin.
-		return dojo.date.add(date, this.datePart, amount);
-	},
-
-	onDisplay: function(){
-		// summary:
-		//		Stub function that can be used to tell a view when it is shown.
-	},
-
-	onBeforeDisplay: function(){
-		// summary:
-		//		Stub function that can be used to tell a view it is about to be shown.
-	},
-
-	onBeforeUnDisplay: function(){
-		// summary:
-		//		Stub function that can be used to tell
-		//		a view when it is no longer shown.
-	}
-});
-
-dojo.declare("dojox.widget._CalendarDay", null, {
-	// summary:
-	//		Mixin for the dojox.widget.Calendar which provides
-	//		the standard day-view. A single month is shown at a time.
-	parent: null,
-
-	constructor: function(){
-		this._addView(dojox.widget._CalendarDayView);
-	}
-});
-
-dojo.declare("dojox.widget._CalendarDayView", [dojox.widget._CalendarView, dijit._Templated], {
-	// summary: View class for the dojox.widget.Calendar.
-	//		Adds a view showing every day of a single month to the calendar.
-	//		This should not be mixed in directly with dojox.widget._CalendarBase.
-	//		Instead, use dojox.widget._CalendarDay
-
-	// templateString: String
-	//		The template to be used to construct the widget.
-	templateString: dojo.cache("dojox.widget","Calendar/CalendarDay.html"),
-
-	// datePart: String
-	//		Specifies how much to increment the displayed date when the user
-	//		clicks the array button to increment of decrement the view.
-	datePart: "month",
-
-	// dayWidth: String
-	//		Specifies the type of day name to display.	"narrow" causes just one letter to be shown.
-	dayWidth: "narrow",
-
-	postCreate: function(){
-		// summary:
-		//		Constructs the calendar view.
-		this.cloneClass(".dijitCalendarDayLabelTemplate", 6);
-		this.cloneClass(".dijitCalendarDateTemplate", 6);
-
-		// now make 6 week rows
-		this.cloneClass(".dijitCalendarWeekTemplate", 5);
-
-		// insert localized day names in the header
-		var dayNames = dojo.date.locale.getNames('days', this.dayWidth, 'standAlone', this.getLang());
-		var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.getLang());
-
-		// Set the text of the day labels.
-		dojo.query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){
-			this._setText(label, dayNames[(i + dayOffset) % 7]);
-		}, this);
-	},
-
-	onDisplay: function(){
-		if(!this._addedFx){
-		// Add visual effects to the view, if any has been specified.
-			this._addedFx = true;
-			this.addFx(".dijitCalendarDateTemplate div", this.domNode);
-		}
-	},
-
-	_onDayClick: function(e){
-		// summary:
-		//		Executed when a day value is clicked.
-
-		// If the user somehow clicked the TR, rather than a
-		// cell, ignore it.
-		if(typeof(e.target._date) == "undefined"){return;}
-
-		var date = new Date(this.get("displayMonth"));
-
-		var p = e.target.parentNode;
-		var c = "dijitCalendar";
-		var d = dojo.hasClass(p, c + "PreviousMonth") ? -1 :
-							(dojo.hasClass(p, c + "NextMonth") ? 1 : 0);
-		if(d){date = dojo.date.add(date, "month", d)}
-		date.setDate(e.target._date);
-
-		// If the day is disabled, ignore it
-		if(this.isDisabledDate(date)){
-			dojo.stopEvent(e);
-			return;
-		}
-		this.parent._onDateSelected(date);
-	},
-
-	_setValueAttr: function(value){
-		//Change the day values
-		this._populateDays();
-	},
-
-	_populateDays: function(){
-		// summary:
-		//		Fills the days of the current month.
-
-		var currentDate = new Date(this.get("displayMonth"));
-		currentDate.setDate(1);
-		var firstDay = currentDate.getDay();
-		var daysInMonth = dojo.date.getDaysInMonth(currentDate);
-		var daysInPreviousMonth = dojo.date.getDaysInMonth(dojo.date.add(currentDate, "month", -1));
-		var today = new Date();
-		var selected = this.get('value');
-
-		var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.getLang());
-		if(dayOffset > firstDay){ dayOffset -= 7; }
-
-		var compareDate = dojo.date.compare;
-		var templateCls = ".dijitCalendarDateTemplate";
-		var selectedCls = "dijitCalendarSelectedDate";
-
-		var oldDate = this._lastDate;
-		var redrawRequired = oldDate == null
-				|| oldDate.getMonth() != currentDate.getMonth()
-				|| oldDate.getFullYear() != currentDate.getFullYear();
-		this._lastDate = currentDate;
-
-		// If still showing the same month, it's much faster to not redraw,
-		// and just change the selected date.
-		if(!redrawRequired){
-			dojo.query(templateCls, this.domNode)
-					.removeClass(selectedCls)
-					.filter(function(node){
-						return node.className.indexOf("dijitCalendarCurrent") > -1
-									&& node._date == selected.getDate();
-					})
-					.addClass(selectedCls);
-			return;
-		}
-
-		// Iterate through dates in the calendar and fill in date numbers and style info
-		dojo.query(templateCls, this.domNode).forEach(function(template, i){
-			i += dayOffset;
-			var date = new Date(currentDate);
-			var number, clazz = "dijitCalendar", adj = 0;
-
-			if(i < firstDay){
-				number = daysInPreviousMonth - firstDay + i + 1;
-				adj = -1;
-				clazz += "Previous";
-			}else if(i >= (firstDay + daysInMonth)){
-				number = i - firstDay - daysInMonth + 1;
-				adj = 1;
-				clazz += "Next";
-			}else{
-				number = i - firstDay + 1;
-				clazz += "Current";
-			}
-
-			if(adj){
-				date = dojo.date.add(date, "month", adj);
-			}
-			date.setDate(number);
-
-			if(!compareDate(date, today, "date")){
-				clazz = "dijitCalendarCurrentDate " + clazz;
-			}
-
-			if(!compareDate(date, selected, "date")
-					&& !compareDate(date, selected, "month")
-					&& !compareDate(date, selected, "year") ){
-				clazz = selectedCls + " " + clazz;
-			}
-
-			if(this.isDisabledDate(date, this.getLang())){
-				clazz = " dijitCalendarDisabledDate " + clazz;
-			}
-
-			var clazz2 = this.getClassForDate(date, this.getLang());
-			if(clazz2){
-				clazz = clazz2 + " " + clazz;
-			}
-
-			template.className = clazz + "Month dijitCalendarDateTemplate";
-			template.dijitDateValue = date.valueOf();
-			var label = dojo.query(".dijitCalendarDateLabel", template)[0];
-
-			this._setText(label, date.getDate());
-
-			label._date = label.parentNode._date = date.getDate();
-		}, this);
-
-		// Fill in localized month name
-		var monthNames = dojo.date.locale.getNames('months', 'wide', 'standAlone', this.getLang());
-		this._setText(this.monthLabelNode, monthNames[currentDate.getMonth()]);
-		this._setText(this.yearLabelNode, currentDate.getFullYear());
-	}
-});
-
-
-dojo.declare("dojox.widget._CalendarMonthYear", null, {
-	// summary:
-	//		Mixin class for adding a view listing all 12
-	//		months of the year to the dojox.widget._CalendarBase
-
-	constructor: function(){
-		// summary:
-		//		Adds a dojox.widget._CalendarMonthView view to the calendar widget.
-		this._addView(dojox.widget._CalendarMonthYearView);
-	}
-});
-
-dojo.declare("dojox.widget._CalendarMonthYearView", [dojox.widget._CalendarView, dijit._Templated], {
-	// summary:
-	//		A Calendar view listing the 12 months of the year
-
-	// templateString: String
-	//		The template to be used to construct the widget.
-	templateString: dojo.cache("dojox.widget","Calendar/CalendarMonthYear.html"),
-
-	// datePart: String
-	//		Specifies how much to increment the displayed date when the user
-	//		clicks the array button to increment of decrement the view.
-	datePart: "year",
-
-	// displayedYears: Number
-	//		The number of years to display at once.
-	displayedYears: 10,
-
-	useHeader: false,
-
-	postCreate: function(){
-		this.cloneClass(".dojoxCal-MY-G-Template", 5, ".dojoxCal-MY-btns");
-		this.monthContainer = this.yearContainer = this.myContainer;
-
-		var yClass = "dojoxCalendarYearLabel";
-		var dClass = "dojoxCalendarDecrease";
-		var iClass = "dojoxCalendarIncrease";
-
-		dojo.query("." + yClass, this.myContainer).forEach(function(node, idx){
-			var clazz = iClass;
-			switch(idx){
-				case 0:
-					clazz = dClass;
-				case 1:
-					dojo.removeClass(node, yClass);
-					dojo.addClass(node, clazz);
-					break;
-			}
-		});
-		// Get the year increment and decrement buttons.
-		this._decBtn = dojo.query('.' + dClass, this.myContainer)[0];
-		this._incBtn = dojo.query('.' + iClass, this.myContainer)[0];
-
-		dojo.query(".dojoxCal-MY-M-Template", this.domNode)
-			.filter(function(item){
-				return item.cellIndex == 1;
-			})
-			.addClass("dojoxCal-MY-M-last");
-
-		dojo.connect(this, "onBeforeDisplay", dojo.hitch(this, function(){
-			this._cachedDate = new Date(this.get("value").getTime());
-			this._populateYears(this._cachedDate.getFullYear());
-			this._populateMonths();
-			this._updateSelectedMonth();
-			this._updateSelectedYear();
-		}));
-
-		dojo.connect(this, "_populateYears", dojo.hitch(this, function(){
-			this._updateSelectedYear();
-		}));
-		dojo.connect(this, "_populateMonths", dojo.hitch(this, function(){
-			this._updateSelectedMonth();
-		}));
-
-		this._cachedDate = this.get("value");
-
-		this._populateYears();
-		this._populateMonths();
-
-		// Add visual effects to the view, if any have been mixed in
-		this.addFx(".dojoxCalendarMonthLabel,.dojoxCalendarYearLabel ", this.myContainer);
-	},
-
-	_setValueAttr: function(value){
-		if (value && value.getFullYear()) {
-			this._populateYears(value.getFullYear());
-		}
-	},
-
-	getHeader: function(){
-		return null;
-	},
-
-	_getMonthNames: function(format){
-		// summary:
-		//		Returns localized month names
-		this._monthNames	= this._monthNames || dojo.date.locale.getNames('months', format, 'standAlone', this.getLang());
-		return this._monthNames;
-	},
-
-	_populateMonths: function(){
-		// summary:
-		//		Populate the month names using the localized values.
-		var monthNames = this._getMonthNames('abbr');
-		dojo.query(".dojoxCalendarMonthLabel", this.monthContainer).forEach(dojo.hitch(this, function(node, cnt){
-			this._setText(node, monthNames[cnt]);
-		}));
-		var constraints = this.get('constraints');
-
-		if(constraints){
-			var date = new Date();
-			date.setFullYear(this._year);
-			var min = -1, max = 12;
-			if(constraints.min){
-				var minY = constraints.min.getFullYear();
-				if(minY > this._year){
-					min = 12;
-				}else if(minY == this._year){
-					min = constraints.min.getMonth();
-				}
-			}
-			if(constraints.max){
-				var maxY = constraints.max.getFullYear();
-				if(maxY < this._year){
-					max = -1;
-				}else if(maxY == this._year){
-					max = constraints.max.getMonth();
-				}
-			}
-
-			dojo.query(".dojoxCalendarMonthLabel", this.monthContainer)
-				.forEach(dojo.hitch(this, function(node, cnt){
-					dojo[(cnt < min || cnt > max) ? "addClass" : "removeClass"]
-						(node, 'dijitCalendarDisabledDate');
-			}));
-		}
-
-		var h = this.getHeader();
-		if(h){
-			this._setText(this.getHeader(), this.get("value").getFullYear());
-		}
-	},
-
-	_populateYears: function(year){
-		// summary:
-		//		Fills the list of years with a range of 12 numbers, with the current year
-		//		being the 6th number.
-		var constraints = this.get('constraints');
-		var dispYear = year || this.get("value").getFullYear();
-		var firstYear = dispYear - Math.floor(this.displayedYears/2);
-		var min = constraints && constraints.min ? constraints.min.getFullYear() : firstYear -10000;
-		firstYear = Math.max(min, firstYear);
-
-		// summary: Writes the years to display to the view
-		this._displayedYear = dispYear;
-
-		var yearLabels = dojo.query(".dojoxCalendarYearLabel", this.yearContainer);
-
-		var max = constraints && constraints.max ? constraints.max.getFullYear() - firstYear :	yearLabels.length;
-		var disabledClass = 'dijitCalendarDisabledDate';
-
-		yearLabels.forEach(dojo.hitch(this, function(node, cnt){
-			if(cnt <= max){
-				this._setText(node, firstYear + cnt);
-				dojo.removeClass(node, disabledClass);
-			}else{
-				dojo.addClass(node, disabledClass);
-			}
-		}));
-
-		if(this._incBtn){
-			dojo[max < yearLabels.length ? "addClass" : "removeClass"](this._incBtn, disabledClass);
-		}
-		if(this._decBtn){
-			dojo[min >= firstYear ? "addClass" : "removeClass"](this._decBtn, disabledClass);
-		}
-
-		var h = this.getHeader();
-		if(h){
-			this._setText(this.getHeader(), firstYear + " - " + (firstYear + 11));
-		}
-	},
-
-	_updateSelectedYear: function(){
-		this._year = String((this._cachedDate || this.get("value")).getFullYear());
-		this._updateSelectedNode(".dojoxCalendarYearLabel", dojo.hitch(this, function(node, idx){
-			return this._year !== null && node.innerHTML == this._year;
-		}));
-	},
-
-	_updateSelectedMonth: function(){
-		var month = (this._cachedDate || this.get("value")).getMonth();
-		this._month = month;
-		this._updateSelectedNode(".dojoxCalendarMonthLabel", function(node, idx){
-			return idx == month;
-		});
-	},
-
-	_updateSelectedNode: function(query, filter){
-		var sel = "dijitCalendarSelectedDate";
-		dojo.query(query, this.domNode)
-			.forEach(function(node, idx, array){
-				dojo[filter(node, idx, array) ? "addClass" : "removeClass"](node.parentNode, sel);
-		});
-		var selMonth = dojo.query('.dojoxCal-MY-M-Template div', this.myContainer)
-			.filter(function(node){
-				return dojo.hasClass(node.parentNode, sel);
-		})[0];
-		if(!selMonth){return;}
-		var disabled = dojo.hasClass(selMonth, 'dijitCalendarDisabledDate');
-
-		dojo[disabled ? 'addClass' : 'removeClass'](this.okBtn, "dijitDisabled");
-	},
-
-	onClick: function(evt){
-		// summary:
-		//		Handles clicks on month names
-		var clazz;
-		var _this = this;
-		var sel = "dijitCalendarSelectedDate";
-		function hc(c){
-			return dojo.hasClass(evt.target, c);
-		}
-
-		if(hc('dijitCalendarDisabledDate')){
-			dojo.stopEvent(evt);
-			return false;
-		}
-
-		if(hc("dojoxCalendarMonthLabel")){
-			clazz = "dojoxCal-MY-M-Template";
-			this._month = evt.target.parentNode.cellIndex + (evt.target.parentNode.parentNode.rowIndex * 2);
-			this._cachedDate.setMonth(this._month);
-			this._updateSelectedMonth();
-		}else if(hc( "dojoxCalendarYearLabel")){
-			clazz = "dojoxCal-MY-Y-Template";
-			this._year = Number(evt.target.innerHTML);
-			this._cachedDate.setYear(this._year);
-			this._populateMonths();
-			this._updateSelectedYear();
-		}else if(hc("dojoxCalendarDecrease")){
-			this._populateYears(this._displayedYear - 10);
-			return true;
-		}else if(hc("dojoxCalendarIncrease")){
-			this._populateYears(this._displayedYear + 10);
-			return true;
-		}else{
-			return true;
-		}
-		dojo.stopEvent(evt);
-		return false;
-	},
-
-	onOk: function(evt){
-		dojo.stopEvent(evt);
-		if(dojo.hasClass(this.okBtn, "dijitDisabled")){
-			return false;
-		}
-		this.onValueSelected(this._cachedDate);
-		return false;
-	},
-
-	onCancel: function(evt){
-		dojo.stopEvent(evt);
-		this.onValueSelected(this.get("value"));
-		return false;
-	}
-});
-
-dojo.declare("dojox.widget.Calendar2Pane",
-	[dojox.widget._CalendarBase,
-	 dojox.widget._CalendarDay,
-	 dojox.widget._CalendarMonthYear], {
-	 	// summary: A Calendar withtwo panes, the second one
-		//		 containing both month and year
-	 }
-);
-
-dojo.declare("dojox.widget.Calendar",
-	[dojox.widget._CalendarBase,
-	 dojox.widget._CalendarDay,
-	 dojox.widget._CalendarMonthYear], {
-	 	// summary: The standard Calendar. It includes day and month/year views.
-		//	No visual effects are included.
-	 }
-);
-
-dojo.declare("dojox.widget.DailyCalendar",
-	[dojox.widget._CalendarBase,
-	 dojox.widget._CalendarDay], {
-	 	// summary: A calendar withonly a daily view.
-		_makeDate: function(value){
-			var now = new Date();
-			now.setDate(value);
-			return now;
-		}
-	 }
-
-);
-
-dojo.declare("dojox.widget.MonthAndYearlyCalendar",
-	[dojox.widget._CalendarBase,
-	 dojox.widget._CalendarMonthYear], {
-	 	// summary: A calendar withonly a daily view.
-	 }
-);
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"./_CalendarBase",
+	"./_CalendarDay",
+	"./_CalendarMonthYear"
+], function(kernel, declare, _CalendarBase, _CalendarDay, _CalendarMonthYear){
+	kernel.experimental("dojox/widget/Calendar");
+
+	return declare("dojox.widget.Calendar", [_CalendarBase, _CalendarDay, _CalendarMonthYear], {
+		// summary:
+		//		The standard Calendar. It includes day and month/year views.
+		//		No visual effects are included.
+	});
+});
\ No newline at end of file
diff --git a/dojox/widget/Calendar/Calendar.css b/dojox/widget/Calendar/Calendar.css
index 4837459..6663cf5 100644
--- a/dojox/widget/Calendar/Calendar.css
+++ b/dojox/widget/Calendar/Calendar.css
@@ -60,6 +60,7 @@
 .dojoxCalendarContainer table {
 	font-size: 11px;
 	border-bottom: 4px solid white;
+	border-collapse: separate;
 }
 
 .dojoxCalendarHeader {
diff --git a/dojox/widget/Calendar2Pane.js b/dojox/widget/Calendar2Pane.js
new file mode 100644
index 0000000..5f385c6
--- /dev/null
+++ b/dojox/widget/Calendar2Pane.js
@@ -0,0 +1,11 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarBase",
+	"./_CalendarDay",
+	"./_CalendarMonthYear"
+	], function(declare, _CalendarBase, _CalendarDay, _CalendarMonthYear){
+		return declare("dojox.widget.Calendar2Pane", [_CalendarBase, _CalendarDay, _CalendarMonthYear], {
+			// summary:
+			//		A Calendar with two panes, the second one containing both month and year
+	});
+});
\ No newline at end of file
diff --git a/dojox/widget/Calendar3Pane.js b/dojox/widget/Calendar3Pane.js
new file mode 100644
index 0000000..f2bd412
--- /dev/null
+++ b/dojox/widget/Calendar3Pane.js
@@ -0,0 +1,12 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarBase",
+	"./_CalendarDay",
+	"./_CalendarMonth",
+	"./_CalendarYear"
+	], function(declare, _CalendarBase, _CalendarDay, _CalendarMonth, _CalendarYear){
+		return declare("dojox.widget.Calendar3Pane", [_CalendarBase, _CalendarDay, _CalendarMonth, _CalendarYear], {
+			// summary:
+			//		A Calendar with three panes, includes day, month, and year views
+	});
+});
\ No newline at end of file
diff --git a/dojox/widget/CalendarFisheye.js b/dojox/widget/CalendarFisheye.js
new file mode 100644
index 0000000..49d8a29
--- /dev/null
+++ b/dojox/widget/CalendarFisheye.js
@@ -0,0 +1,11 @@
+define([
+	"dojo/_base/declare",
+	"./Calendar",
+	"./_FisheyeFX"
+], function(declare, Calendar, _FisheyeFX) {
+	return declare("dojox.widget.CalendarFisheye", [ Calendar, _FisheyeFX ], {
+		// summary:
+		//		The standard Calendar. It includes day, month and year views.
+		//		FisheyeLite effects are included.
+	});
+});
diff --git a/dojox/widget/CalendarFx.js b/dojox/widget/CalendarFx.js
index c3b6278..780bff2 100644
--- a/dojox/widget/CalendarFx.js
+++ b/dojox/widget/CalendarFx.js
@@ -1,26 +1,13 @@
-dojo.provide("dojox.widget.CalendarFx");
-dojo.require("dojox.widget.FisheyeLite");
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"./CalendarFisheye",
+	"./_FisheyeFX"
+], function(kernel, declare, CalendarFisheye, _FisheyeFX){
+	kernel.experimental("dojox/widget/CalendarFx");
 
-dojo.declare("dojox.widget._FisheyeFX",null, {
-	// summary
-	//   A mixin to add a FisheyeLite effect to the calendar
-	addFx: function(query, fromNode) {
-		//Use the query and base node passed from the calendar view mixin
-		//to select the nodes to attach the event to.
-		dojo.query(query, fromNode).forEach(function(node){
-			new dojox.widget.FisheyeLite({
-				properties: {
-					fontSize: 1.1
-				}
-			}, node);
-		});
-	}
+	return declare("dojox.widget.CalendarFx", [CalendarFisheye, _FisheyeFX], {
+		// summary:
+		//		The visual effects extensions for dojox/widget/Calendar.
+	});
 });
-
-dojo.declare("dojox.widget.CalendarFisheye",
-	[dojox.widget.Calendar,
-	 dojox.widget._FisheyeFX], {
-	 	// summary: The standard Calendar. It includes day, month and year views.
-		//  FisheyeLite effects are included.
-	 }
-);
diff --git a/dojox/widget/CalendarViews.js b/dojox/widget/CalendarViews.js
index 587d38d..3b788a7 100644
--- a/dojox/widget/CalendarViews.js
+++ b/dojox/widget/CalendarViews.js
@@ -1,148 +1,6 @@
-dojo.provide("dojox.widget.CalendarViews");
-dojo.experimental("dojox.widget.CalendarViews");
-
-dojo.require("dojox.widget.Calendar");
-
-dojo.declare("dojox.widget._CalendarMonth", null, {
-	// summary: Mixin class for adding a view listing all 12 months of the year to the
-	//	 dojox.widget._CalendarBase
-
-
-	constructor: function(){
-		// summary: Adds a dojox.widget._CalendarMonthView view to the calendar widget.
-		this._addView(dojox.widget._CalendarMonthView);
-	}
+define([
+	"dojo/_base/kernel"
+], function(kernel){
+	kernel.experimental("dojox/widget/CalendarViews");
+	return {};
 });
-
-dojo.declare("dojox.widget._CalendarMonthView", [dojox.widget._CalendarView, dijit._Templated], {
-	// summary: A Calendar view listing the 12 months of the year
-
-	// templateString: String
-	//	The template to be used to construct the widget.
-	templateString: dojo.cache("dojox.widget","Calendar/CalendarMonth.html"),
-
-	// datePart: String
-	//	Specifies how much to increment the displayed date when the user
-	//	clicks the array button to increment of decrement the view.
-	datePart: "year",
-
-	// headerClass: String
-	//	Specifies the CSS class to apply to the header node for this view.
-	headerClass: "dojoxCalendarMonthHeader",
-
-	postCreate: function(){
-		// summary: Constructs the view
-		this.cloneClass(".dojoxCalendarMonthTemplate", 3);
-		this.cloneClass(".dojoxCalendarMonthGroupTemplate", 2);
-		this._populateMonths();
-
-		// Add visual effects to the view, if any have been mixed in
-		this.addFx(".dojoxCalendarMonthLabel", this.domNode);
-	},
-
-	_setValueAttr: function(value){
-		this.header.innerHTML = value.getFullYear();
-	},
-
-	_getMonthNames: dojox.widget._CalendarMonthYearView.prototype._getMonthNames,
-
-	_populateMonths: dojox.widget._CalendarMonthYearView.prototype._populateMonths,
-
-	onClick: function(evt){
-		// summary: Handles clicks on month names
-		if(!dojo.hasClass(evt.target, "dojoxCalendarMonthLabel")){dojo.stopEvent(evt); return;}
-		var parentNode = evt.target.parentNode;
-		var month = parentNode.cellIndex + (parentNode.parentNode.rowIndex * 4);
-		var date = this.get("value");
-
-		// Seeing a really strange bug in FF3.6 where this has to be called twice
-		// in order to take affect
-		date.setMonth(month);
-		date.setMonth(month);
-		this.onValueSelected(date, month);
-	}
-});
-
-dojo.declare("dojox.widget._CalendarYear", null, {
-	// summary: Mixin class for adding a view listing 12 years to the
-	//	 dojox.widget._CalendarBase
-	parent: null,
-
-	constructor: function(){
-		// summary: Adds a dojox.widget._CalendarYearView view to the
-		//	dojo.widget._CalendarBase widget.
-		this._addView(dojox.widget._CalendarYearView);
-	}
-});
-
-dojo.declare("dojox.widget._CalendarYearView", [dojox.widget._CalendarView, dijit._Templated], {
-	// summary: A Calendar view listing 12 years
-
-	// templateString: String
-	//		The template to be used to construct the widget.
-	templateString: dojo.cache("dojox.widget","Calendar/CalendarYear.html"),
-
-	displayedYears: 6,
-
-	postCreate: function(){
-		// summary: Constructs the view
-		this.cloneClass(".dojoxCalendarYearTemplate", 3);
-		this.cloneClass(".dojoxCalendarYearGroupTemplate", 2);
-		this._populateYears();
-		this.addFx(".dojoxCalendarYearLabel", this.domNode);
-	},
-
-	_setValueAttr: function(value){
-		this._populateYears(value.getFullYear());
-	},
-
-	_populateYears: dojox.widget._CalendarMonthYearView.prototype._populateYears,
-
-	adjustDate: function(date, amount){
-		// summary: Adjusts the value of a date. It moves it by 12 years each time.
-		return dojo.date.add(date, "year", amount * 12);
-	},
-
-	onClick: function(evt){
-		// summary: Handles clicks on year values.
-		if(!dojo.hasClass(evt.target, "dojoxCalendarYearLabel")){dojo.stopEvent(evt); return;}
-		var year = Number(evt.target.innerHTML);
-		var date = this.get("value");
-		date.setYear(year);
-		this.onValueSelected(date, year);
-	}
-});
-
-
-dojo.declare("dojox.widget.Calendar3Pane",
-	[dojox.widget._CalendarBase,
-	 dojox.widget._CalendarDay,
-	 dojox.widget._CalendarMonth,
-	 dojox.widget._CalendarYear], {
-	 	// summary: The Calendar includes day, month and year views.
-		//	No visual effects are included.
-	 }
-);
-
-dojo.declare("dojox.widget.MonthlyCalendar",
-	[dojox.widget._CalendarBase,
-	 dojox.widget._CalendarMonth], {
-	 	// summary: A calendar with only a month view.
-		_makeDate: function(value){
-			var now = new Date();
-			now.setMonth(value);
-			return now;
-		}
-	 }
-);
-dojo.declare("dojox.widget.YearlyCalendar",
-	[dojox.widget._CalendarBase,
-	 dojox.widget._CalendarYear], {
-	 	// summary: A calendar with only a year view.
-		_makeDate: function(value){
-			var now = new Date();
-			now.setFullYear(value);
-			return now;
-		}
-	 }
-);
diff --git a/dojox/widget/ColorPicker.js b/dojox/widget/ColorPicker.js
index f724557..bb92cf0 100644
--- a/dojox/widget/ColorPicker.js
+++ b/dojox/widget/ColorPicker.js
@@ -14,20 +14,16 @@ define([
 		// stub, this is planned later:
 		return hex;
 	};
-/*===== 
-	var FormWidget = dijit.form._FormWidget;
-=====*/
+
 	// TODO: shouldn't this extend _FormValueWidget?
 	return declare("dojox.widget.ColorPicker", FormWidget, {
 		// summary:
 		//		a HSV color picker - similar to Photoshop picker
-		//
 		// description:
 		//		Provides an interactive HSV ColorPicker similar to
 		//		PhotoShop's color selction tool. This is an enhanced
 		//		version of the default dijit.ColorPalette, though provides
 		//		no accessibility.
-		//
 		// example:
 		// |	var picker = new dojox.widget.ColorPicker({
 		// |		// a couple of example toggles:
@@ -36,33 +32,32 @@ define([
 		// |		webSafe: false,
 		// |		showRgb: false
 		// |	});
-		//
 		// example:
 		// |	<!-- markup: -->
 		// |	<div dojoType="dojox.widget.ColorPicker"></div>
-		//
+
 		// showRgb: Boolean
-		//	show/update RGB input nodes
+		//		show/update RGB input nodes
 		showRgb: true,
 	
 		// showHsv: Boolean
-		//	show/update HSV input nodes
+		//		show/update HSV input nodes
 		showHsv: true,
 	
 		// showHex: Boolean
-		//	show/update Hex value field
+		//		show/update Hex value field
 		showHex: true,
 
 		// webSafe: Boolean
-		//	deprecated? or just use a toggle to show/hide that node, too?
+		//		deprecated? or just use a toggle to show/hide that node, too?
 		webSafe: true,
 
 		// animatePoint: Boolean
-		//	toggle to use slideTo (true) or just place the cursor (false) on click
+		//		toggle to use slideTo (true) or just place the cursor (false) on click
 		animatePoint: true,
 
 		// slideDuration: Integer
-		//	time in ms picker node will slide to next location (non-dragging) when animatePoint=true
+		//		time in ms picker node will slide to next location (non-dragging) when animatePoint=true
 		slideDuration: 250,
 
 		// liveUpdate: Boolean
@@ -70,15 +65,15 @@ define([
 		liveUpdate: false,
 
 		// PICKER_HUE_H: int
-		//     Height of the hue picker, used to calculate positions
+		//		Height of the hue picker, used to calculate positions
 		PICKER_HUE_H: 150,
 		
 		// PICKER_SAT_VAL_H: int
-		//     Height of the 2d picker, used to calculate positions
+		//		Height of the 2d picker, used to calculate positions
 		PICKER_SAT_VAL_H: 150,
 		
 		// PICKER_SAT_VAL_W: int
-		//     Width of the 2d picker, used to calculate positions
+		//		Width of the 2d picker, used to calculate positions
 		PICKER_SAT_VAL_W: 150,
 
 		// PICKER_HUE_SELECTOR_H: int
@@ -97,9 +92,9 @@ define([
 		PICKER_SAT_SELECTOR_W: 10,
 
 		// value: String
-		//	Default color for this component. Only hex values are accepted as incoming/returned
-		//	values. Adjust this value with `.attr`, eg: dijit.byId("myPicker").attr("value", "#ededed");
-		//	to cause the points to adjust and the values to reflect the current color.
+		//		Default color for this component. Only hex values are accepted as incoming/returned
+		//		values. Adjust this value with `.attr`, eg: dijit.byId("myPicker").attr("value", "#ededed");
+		//		to cause the points to adjust and the values to reflect the current color.
 		value: "#ffffff",
 		
 		_underlay: kernel.moduleUrl("dojox.widget","ColorPicker/images/underlay.png"),
@@ -223,16 +218,17 @@ define([
 		},
 		
 		setColor: function(/* String */col, force){
-			// summary: Set a color on a picker. Usually used to set
-			//          initial color as an alternative to passing defaultColor option
-			//          to the constructor.
+			// summary:
+			//		Set a color on a picker. Usually used to set
+			//		initial color as an alternative to passing defaultColor option
+			//		to the constructor.
 			col = color.fromString(col);
 			this._updatePickerLocations(col);
 			this._updateColorInputs(col);
 			this._updateValue(col, force);
 		},
 		
-		_setTimer: function(/* d.dnd.Mover */mover){
+		_setTimer: function(/* dojo/dnd/Mover */mover){
 			if(mover.node != this.cursorNode){ return; }
 			// FIXME: should I assume this? focus on mouse down so on mouse up
 			FocusManager.focus(mover.node);
@@ -240,7 +236,7 @@ define([
 			this._timer = setInterval(lang.hitch(this, "_updateColor"), 45);
 		},
 		
-		_clearTimer: function(/* d.dnd.Mover */mover){
+		_clearTimer: function(/* dojo/dnd/Mover */mover){
 			if(!this._timer){ return; }
 			clearInterval(this._timer);
 			this._timer = null;
@@ -248,11 +244,12 @@ define([
 			DOM.setSelectable(this.domNode,true);
 		},
 		
-		_setHue: function(/* Decimal */h){
+		_setHue: function(/* Float */h){
 			// summary:
 			//		Sets a natural color background for the
 			//		underlay image against closest hue value (full saturation)
-			//		h: 0..360
+			// h:
+			//		0..360
 			html.style(this.colorUnderlay, "backgroundColor", color.fromHsv(h,100,100).toHex());
 			
 		},
@@ -261,11 +258,11 @@ define([
 			// summary:
 			//		Function used by the typematic code to handle cursor position and update
 			//		via keyboard.
-			// count:
+			// count: Number
 			//		-1 means stop, anything else is just how many times it was called.
-			// node:
+			// node: DomNode
 			//		The node generating the event.
-			// e:
+			// e: Event
 			//		The event.
 			if(count !== -1){
 				var y = html.style(this.hueCursorNode, "top");
@@ -349,8 +346,9 @@ define([
 			}
 		},
 
-		_updateColor: function(){
-			// summary: update the previewNode color, and input values [optional]
+		_updateColor: function(fireChange){
+			// summary:
+			//		update the previewNode color, and input values [optional]
 			
 			var hueSelCenter = this.PICKER_HUE_SELECTOR_H/2,
 				satSelCenterH = this.PICKER_SAT_SELECTOR_H/2,
@@ -364,7 +362,7 @@ define([
 			;
 			
 			this._updateColorInputs(col);
-			this._updateValue(col, true);
+			this._updateValue(col, fireChange);
 			
 			// update hue, not all the pickers
 			if(h!=this._hue){
@@ -373,8 +371,9 @@ define([
 		},
 		
 		_colorInputChange: function(e){
-			//summary: updates picker position and inputs
-			//         according to rgb, hex or hsv input changes
+			// summary:
+			//		updates picker position and inputs
+			//		according to rgb, hex or hsv input changes
 			var col, hasit = false;
 			switch(e.target){
 				//transform to hsv to pixels
@@ -406,9 +405,10 @@ define([
 			
 		},
 		
-		_updateValue: function(/* dojox.color.Color */col, /* Boolean */fireChange){
-			// summary: updates the value of the widget
-			//          can cancel reverse onChange by specifying second param
+		_updateValue: function(/* dojox/color/Color */col, /* Boolean */fireChange){
+			// summary:
+			//		updates the value of the widget
+			//		can cancel reverse onChange by specifying second param
 			var hex = col.toHex();
 			
 			this.value = this.valueNode.value = hex;
@@ -419,9 +419,10 @@ define([
 			}
 		},
 		
-		_updatePickerLocations: function(/* dojox.color.Color */col){
-			//summary: update handles on the pickers acording to color values
-			//
+		_updatePickerLocations: function(/* dojox/color/Color */col){
+			// summary:
+			//		update handles on the pickers acording to color values
+			
 			var hueSelCenter = this.PICKER_HUE_SELECTOR_H/2,
 				satSelCenterH = this.PICKER_SAT_SELECTOR_H/2,
 				satSelCenterW = this.PICKER_SAT_SELECTOR_W/2;
@@ -463,9 +464,10 @@ define([
 			
 		},
 		
-		_updateColorInputs: function(/* dojox.color.Color */col){
-			//summary: updates color inputs that were changed through other inputs
-			//or by clicking on the picker
+		_updateColorInputs: function(/* dojox/color/Color */ col){
+			// summary:
+			//		updates color inputs that were changed through other inputs
+			//		or by clicking on the picker
 			
 			var hex = col.toHex();
 			
@@ -494,7 +496,8 @@ define([
 		},
 		
 		_setHuePoint: function(/* Event */evt){
-			// summary: set the hue picker handle on relative y coordinates
+			// summary:
+			//		set the hue picker handle on relative y coordinates
 			var selCenter = this.PICKER_HUE_SELECTOR_H/2;
 			var ypos = evt.layerY - selCenter;
 			if(this.animatePoint){
@@ -503,7 +506,7 @@ define([
 					duration:this.slideDuration,
 					top: ypos,
 					left: 0,
-					onEnd: lang.hitch(this, function(){ this._updateColor(true); FocusManager.focus(this.hueCursorNode); })
+					onEnd: lang.hitch(this, function(){ this._updateColor(false); FocusManager.focus(this.hueCursorNode); })
 				}).play();
 			}else{
 				html.style(this.hueCursorNode, "top", ypos + "px");
@@ -512,8 +515,10 @@ define([
 		},
 		
 		_setPoint: function(/* Event */evt){
-			// summary: set our picker point based on relative x/y coordinates
-			//  evt.preventDefault();
+			// summary:
+			//		set our picker point based on relative x/y coordinates
+
+			//	evt.preventDefault();
 			var satSelCenterH = this.PICKER_SAT_SELECTOR_H/2;
 			var satSelCenterW = this.PICKER_SAT_SELECTOR_W/2;
 			var newTop = evt.layerY - satSelCenterH;
@@ -539,7 +544,7 @@ define([
 		},
 		
 		_handleKey: function(/* Event */e){
-			// FIXME: not implemented YET
+			// TODO: not implemented YET
 			// var keys = d.keys;
 		},
 
@@ -553,8 +558,8 @@ define([
 
 		_stopDrag: function(e){
 			// summary:
-			//		Function to hald the mouse down default
-			//		to disable draggong of images out of the color
+			//		Function to halt the mouse down default
+			//		to disable dragging of images out of the color
 			//		picker.
 			Event.stop(e);
 		},
diff --git a/dojox/widget/ColorPicker/ColorPicker.html b/dojox/widget/ColorPicker/ColorPicker.html
index 2939ac6..89db5eb 100644
--- a/dojox/widget/ColorPicker/ColorPicker.html
+++ b/dojox/widget/ColorPicker/ColorPicker.html
@@ -1,26 +1,26 @@
-<table class="dojoxColorPicker" dojoAttachEvent="onkeypress: _handleKey" cellpadding="0" cellspacing="0">
+<table class="dojoxColorPicker" dojoAttachEvent="onkeypress: _handleKey" cellpadding="0" cellspacing="0" role="presentation">
 	<tr>
 		<td valign="top" class="dojoxColorPickerRightPad">
 			<div class="dojoxColorPickerBox">
 				<!-- Forcing ABS in style attr due to dojo DND issue with not picking it up form the class. -->
-				<img role="status" title="${saturationPickerTitle}" alt="${saturationPickerTitle}" class="dojoxColorPickerPoint" src="${_pickerPointer}" tabIndex="0" dojoAttachPoint="cursorNode" style="position: absolute; top: 0px; left: 0px;">
+				<img title="${saturationPickerTitle}" alt="${saturationPickerTitle}" class="dojoxColorPickerPoint" src="${_pickerPointer}" tabIndex="0" dojoAttachPoint="cursorNode" style="position: absolute; top: 0px; left: 0px;">
 				<img role="presentation" alt="" dojoAttachPoint="colorUnderlay" dojoAttachEvent="onclick: _setPoint, onmousedown: _stopDrag" class="dojoxColorPickerUnderlay" src="${_underlay}" ondragstart="return false">
 			</div>
 		</td>
 		<td valign="top" class="dojoxColorPickerRightPad">
 			<div class="dojoxHuePicker">
 				<!-- Forcing ABS in style attr due to dojo DND issue with not picking it up form the class. -->
-				<img role="status" dojoAttachPoint="hueCursorNode" tabIndex="0" class="dojoxHuePickerPoint" title="${huePickerTitle}" alt="${huePickerTitle}" src="${_huePickerPointer}" style="position: absolute; top: 0px; left: 0px;">
+				<img dojoAttachPoint="hueCursorNode" tabIndex="0" class="dojoxHuePickerPoint" title="${huePickerTitle}" alt="${huePickerTitle}" src="${_huePickerPointer}" style="position: absolute; top: 0px; left: 0px;">
 				<div class="dojoxHuePickerUnderlay" dojoAttachPoint="hueNode">
 				    <img role="presentation" alt="" dojoAttachEvent="onclick: _setHuePoint, onmousedown: _stopDrag" src="${_hueUnderlay}">
 				</div>
 			</div>
 		</td>
 		<td valign="top">
-			<table cellpadding="0" cellspacing="0">
+			<table cellpadding="0" cellspacing="0" role="presentation">
 				<tr>
 					<td valign="top" class="dojoxColorPickerPreviewContainer">
-						<table cellpadding="0" cellspacing="0">
+						<table cellpadding="0" cellspacing="0" role="presentation">
 							<tr>
 								<td valign="top" class="dojoxColorPickerRightPad">
 									<div dojoAttachPoint="previewNode" class="dojoxColorPickerPreview"></div>
@@ -34,11 +34,11 @@
 				</tr>
 				<tr>
 					<td valign="bottom">
-						<table class="dojoxColorPickerOptional" cellpadding="0" cellspacing="0">
+						<table class="dojoxColorPickerOptional" cellpadding="0" cellspacing="0" role="presentation">
 							<tr>
 								<td>
 									<div class="dijitInline dojoxColorPickerRgb" dojoAttachPoint="rgbNode">
-										<table cellpadding="1" cellspacing="1">
+										<table cellpadding="1" cellspacing="1" role="presentation">
 										<tr><td><label for="${_uId}_r">${redLabel}</label></td><td><input id="${_uId}_r" dojoAttachPoint="Rval" size="1" dojoAttachEvent="onchange: _colorInputChange"></td></tr>
 										<tr><td><label for="${_uId}_g">${greenLabel}</label></td><td><input id="${_uId}_g" dojoAttachPoint="Gval" size="1" dojoAttachEvent="onchange: _colorInputChange"></td></tr>
 										<tr><td><label for="${_uId}_b">${blueLabel}</label></td><td><input id="${_uId}_b" dojoAttachPoint="Bval" size="1" dojoAttachEvent="onchange: _colorInputChange"></td></tr>
@@ -47,7 +47,7 @@
 								</td>
 								<td>
 									<div class="dijitInline dojoxColorPickerHsv" dojoAttachPoint="hsvNode">
-										<table cellpadding="1" cellspacing="1">
+										<table cellpadding="1" cellspacing="1" role="presentation">
 										<tr><td><label for="${_uId}_h">${hueLabel}</label></td><td><input id="${_uId}_h" dojoAttachPoint="Hval"size="1" dojoAttachEvent="onchange: _colorInputChange"> ${degLabel}</td></tr>
 										<tr><td><label for="${_uId}_s">${saturationLabel}</label></td><td><input id="${_uId}_s" dojoAttachPoint="Sval" size="1" dojoAttachEvent="onchange: _colorInputChange"> ${percentSign}</td></tr>
 										<tr><td><label for="${_uId}_v">${valueLabel}</label></td><td><input id="${_uId}_v" dojoAttachPoint="Vval" size="1" dojoAttachEvent="onchange: _colorInputChange"> ${percentSign}</td></tr>
diff --git a/dojox/widget/DailyCalendar.js b/dojox/widget/DailyCalendar.js
new file mode 100644
index 0000000..1a5f301
--- /dev/null
+++ b/dojox/widget/DailyCalendar.js
@@ -0,0 +1,15 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarBase",
+	"./_CalendarDay"
+], function(declare, _CalendarBase, _CalendarDay){
+	return declare("dojox.widget.DailyCalendar", [_CalendarBase, _CalendarDay], {
+		// summary:
+		//		A calendar with only a daily view.
+		_makeDate: function(value){
+			var now = new Date();
+			now.setDate(value);
+			return now;
+		}
+	});
+});
diff --git a/dojox/widget/DataPresentation.js b/dojox/widget/DataPresentation.js
index 44e5800..62479b9 100644
--- a/dojox/widget/DataPresentation.js
+++ b/dojox/widget/DataPresentation.js
@@ -357,216 +357,212 @@ dojo.require("dojo.data.ItemFileWriteStore");
 	};
 	
 	dojo.declare("dojox.widget.DataPresentation", null, {
-		//	summary:
-		//
-		//		DataPresentation
-		//
+		// summary:
 		//		A widget that connects to a data store in a simple manner,
-		//      and also provides some additional convenience mechanisms
-		//      for connecting to common data sources without needing to
-		//      explicitly construct a Dojo data store. The widget can then
-		//      present the data in several forms: as a graphical chart,
-		//      as a tabular grid, or as display panels presenting meta-data
-		//      (title, creation information, etc) from the data. The
-		//      widget can also create and manage several of these forms
-		//      in one simple construction.
-		//
-		//      Note: this is a first experimental draft and any/all details
-		//      are subject to substantial change in later drafts.
-		//
-		//	example:
-		//
-		//	 	var pres = new dojox.data.DataPresentation("myChartNode", {
-		//	 		type: "chart",
-		//	 		url: "/data/mydata",
-		//          gridNode: "myGridNode"
-		//	 	});
-		//
-		//	properties:
-		//
-		//  store: Object
-		//      Dojo data store used to supply data to be presented. This may
-		//      be supplied on construction or created implicitly based on
-		//      other construction parameters ('data', 'url').
-		//
-		//  query: String
-		//      Query to apply to the Dojo data store used to supply data to
-		//      be presented.
-		//
-		//  queryOptions: String
-		//      Query options to apply to the Dojo data store used to supply
-		//      data to be presented.
-		//
-		//  data: Object
-		//      Data to be presented. If supplied on construction this property
-		//      will override any value supplied for the 'store' property.
-		//
-		//  url: String
-		//      URL to fetch data from in JSON format. If supplied on
-		//      construction this property will override any values supplied
-		//      for the 'store' and/or 'data' properties. Note that the data
-		//      can also be comment-filtered JSON, although this will trigger
-		//      a warning message in the console unless djConfig.useCommentedJson
-		//      has been set to true.
-		//
-		//  urlContent: Object
-		//      Content to be passed to the URL when fetching data. If a URL has
-		//      not been supplied, this value is ignored.
-		//
-		//  urlError: function
-		//      A function to be called if an error is encountered when fetching
-		//      data from the supplied URL. This function will be supplied with
-		//      two parameters exactly as the error function supplied to the
-		//      dojo.xhrGet function. This function may be called multiple times
-		//      if a refresh interval has been supplied.
-		//
-		//  refreshInterval: Number
-		//      the time interval in milliseconds after which the data supplied
-		//      via the 'data' property or fetched from a URL via the 'url'
-		//      property should be regularly refreshed. This property is
-		//      ignored if neither the 'data' nor 'url' property has been
-		//      supplied. If the refresh interval is zero, no regular refresh is done.
-		//
-		//  refreshIntervalPending:
-		//      the JavaScript set interval currently in progress, if any
-		//
-		//  series: Array
-		//      an array of objects describing the data series to be included
-		//      in the data presentation. Each object may contain the
-		//      following fields:
-		//			datapoints: the name of the field from the source data which
-		//				contains an array of the data points for this data series.
-		//				If not supplied, the source data is assumed to be an array
-		//				of data points to be used.
-		//			field: the name of the field within each data point which
-		//				contains the data for this data series. If not supplied,
-		//				each data point is assumed to be the value for the series.
-		//      	name: a name for the series, used in the legend and grid headings
-		//          namefield: the name of the field from the source data which
-		//              contains the name the series, used in the legend and grid
-		//              headings. If both name and namefield are supplied, name takes
-		//              precedence. If neither are supplied, a default name is used.
-		//			chart: true if the series should be included in a chart presentation (default: true)
-		//          charttype: the type of presentation of the series in the chart, which can be
-		//				"range", "line", "bar" (default: "bar")
-		//          linestyle: the stroke style for lines (if applicable) (default: "Solid")
-		//          axis: the dependant axis to which the series will be attached in the chart,
-		//              which can be "primary" or "secondary"
-		//			grid: true if the series should be included in a data grid presentation (default: true)
-		//			gridformatter: an optional formatter to use for this series in the data grid
-		//
-		//      a call-back function may alternatively be supplied. The function takes
-		//      a single parameter, which will be the data (from the 'data' field or
-		//      loaded from the value in the 'url' field), and should return the array
-		//      of objects describing the data series to be included in the data
-		//      presentation. This enables the series structures to be built dynamically
-		//      after data load, and rebuilt if necessary on data refresh. The call-back
-		//      function will be called each time new data is set, loaded or refreshed.
-		//      A call-back function cannot be used if the data is supplied directly
-		//      from a Dojo data store.
-		//
-		//  type: String
-		//      the type of presentation to be applied at the DOM attach point.
-		//      This can be 'chart', 'legend', 'grid', 'title', 'footer'. The
-		//      default type is 'chart'.
+		//		and also provides some additional convenience mechanisms
+		//		for connecting to common data sources without needing to
+		//		explicitly construct a Dojo data store. The widget can then
+		//		present the data in several forms: as a graphical chart,
+		//		as a tabular grid, or as display panels presenting meta-data
+		//		(title, creation information, etc) from the data. The
+		//		widget can also create and manage several of these forms
+		//		in one simple construction.
+		//
+		//		Note: this is a first experimental draft and any/all details
+		//		are subject to substantial change in later drafts.
+		// example:
+		// |	var pres = new dojox.data.DataPresentation("myChartNode", {
+		// |		type: "chart",
+		// |		url: "/data/mydata",
+		// |		gridNode: "myGridNode"
+		// |	});
+
+		// store: Object
+		//		Dojo data store used to supply data to be presented. This may
+		//		be supplied on construction or created implicitly based on
+		//		other construction parameters ('data', 'url').
+
+		// query: String
+		//		Query to apply to the Dojo data store used to supply data to
+		//		be presented.
+
+		// queryOptions: String
+		//		Query options to apply to the Dojo data store used to supply
+		//		data to be presented.
+
+		// data: Object
+		//		Data to be presented. If supplied on construction this property
+		//		will override any value supplied for the 'store' property.
+
+		// url: String
+		//		URL to fetch data from in JSON format. If supplied on
+		//		construction this property will override any values supplied
+		//		for the 'store' and/or 'data' properties. Note that the data
+		//		can also be comment-filtered JSON, although this will trigger
+		//		a warning message in the console unless djConfig.useCommentedJson
+		//		has been set to true.
+
+		// urlContent: Object
+		//		Content to be passed to the URL when fetching data. If a URL has
+		//		not been supplied, this value is ignored.
+
+		// urlError: function
+		//		A function to be called if an error is encountered when fetching
+		//		data from the supplied URL. This function will be supplied with
+		//		two parameters exactly as the error function supplied to the
+		//		dojo.xhrGet function. This function may be called multiple times
+		//		if a refresh interval has been supplied.
+
+		// refreshInterval: Number
+		//		the time interval in milliseconds after which the data supplied
+		//		via the 'data' property or fetched from a URL via the 'url'
+		//		property should be regularly refreshed. This property is
+		//		ignored if neither the 'data' nor 'url' property has been
+		//		supplied. If the refresh interval is zero, no regular refresh is done.
+
+		// refreshIntervalPending:
+		//		the JavaScript set interval currently in progress, if any
+
+		// series: Array
+		//		an array of objects describing the data series to be included
+		//		in the data presentation. Each object may contain the
+		//		following fields:
+		//
+		//		- datapoints: the name of the field from the source data which
+		//			contains an array of the data points for this data series.
+		//			If not supplied, the source data is assumed to be an array
+		//			of data points to be used.
+		//		- field: the name of the field within each data point which
+		//			contains the data for this data series. If not supplied,
+		//			each data point is assumed to be the value for the series.
+		//		- name: a name for the series, used in the legend and grid headings
+		//		- namefield:
+		//			the name of the field from the source data which
+		//			contains the name the series, used in the legend and grid
+		//			headings. If both name and namefield are supplied, name takes
+		//		    precedence. If neither are supplied, a default name is used.
+		//		- chart: true if the series should be included in a chart presentation (default: true)
+		//		- charttype: the type of presentation of the series in the chart, which can be
+		//			"range", "line", "bar" (default: "bar")
+		//		- linestyle: the stroke style for lines (if applicable) (default: "Solid")
+		//		- axis: the dependant axis to which the series will be attached in the chart,
+		//		    which can be "primary" or "secondary"
+		//		- grid: true if the series should be included in a data grid presentation (default: true)
+		//		- gridformatter: an optional formatter to use for this series in the data grid
+		//
+		//		a call-back function may alternatively be supplied. The function takes
+		//		a single parameter, which will be the data (from the 'data' field or
+		//		loaded from the value in the 'url' field), and should return the array
+		//		of objects describing the data series to be included in the data
+		//		presentation. This enables the series structures to be built dynamically
+		//		after data load, and rebuilt if necessary on data refresh. The call-back
+		//		function will be called each time new data is set, loaded or refreshed.
+		//		A call-back function cannot be used if the data is supplied directly
+		//		from a Dojo data store.
+
+		// type: String
+		//		the type of presentation to be applied at the DOM attach point.
+		//		This can be 'chart', 'legend', 'grid', 'title', 'footer'. The
+		//		default type is 'chart'.
 		type: "chart",
-		//
-		//  chartType: String
-		//      the type of chart to display. This can be 'clusteredbars',
-		//      'areas', 'stackedcolumns', 'stackedbars', 'stackedareas',
-		//      'lines', 'hybrid'. The default type is 'bar'.
+
+		// chartType: String
+		//		the type of chart to display. This can be 'clusteredbars',
+		//		'areas', 'stackedcolumns', 'stackedbars', 'stackedareas',
+		//		'lines', 'hybrid'. The default type is 'bar'.
 		chartType: "clusteredBars",
-		//
-		//  reverse: Boolean
-		//      true if the chart independant axis should be reversed.
+
+		// reverse: Boolean
+		//		true if the chart independent axis should be reversed.
 		reverse: false,
-		//
-		//  animate: Object
-		//      if an object is supplied, then the chart bars or columns will animate
-		//      into place. If the object contains a field 'duration' then the value
-		//      supplied is the duration of the animation in milliseconds, otherwise
-		//      a default duration is used. A boolean value true can alternatively be
-		//      supplied to enable animation with the default duration.
-		//      The default is null (no animation).
+
+		// animate: Object
+		//		if an object is supplied, then the chart bars or columns will animate
+		//		into place. If the object contains a field 'duration' then the value
+		//		supplied is the duration of the animation in milliseconds, otherwise
+		//		a default duration is used. A boolean value true can alternatively be
+		//		supplied to enable animation with the default duration.
+		//		The default is null (no animation).
 		animate: null,
-		//
-		//  labelMod: Integer
-		//      the frequency of label annotations to be included on the
-		//      independent axis. 1=every label. 0=no labels. The default is 1.
+
+		// labelMod: Integer
+		//		the frequency of label annotations to be included on the
+		//		independent axis. 1=every label. 0=no labels. The default is 1.
 		labelMod: 1,
-		//
-		//  tooltip: String | Function
-		//      a string pattern defining the tooltip text to be applied to chart
-		//      data points, or a function which takes a single parameter and returns
-		//      the tooltip text to be applied to chart data points. The string pattern
-		//      will have the following substitutions applied:
-		//       {0} - the type of chart element ('bar', 'surface', etc)
-		//       {1} - the name of the data series
-		//       {2} - the independent axis value at the tooltip data point
-		//       {3} - the series value at the tooltip data point point
-		//      The function, if supplied, will receive a single parameter exactly
-		//      as per the dojox.charting.action2D.Tooltip class. The default value
-		//      is to apply the default tooltip as defined by the
-		//      dojox.charting.action2D.Tooltip class.
-		//
-		//  legendHorizontal: Boolean | Number
-		//      true if the legend should be rendered horizontally, or a number if
-		//      the legend should be rendered as horizontal rows with that number of
-		//      items in each row, or false if the legend should be rendered
-		//      vertically (same as specifying 1). The default is true (legend
-		//      rendered horizontally).
+
+		// tooltip: String|Function
+		//		a string pattern defining the tooltip text to be applied to chart
+		//		data points, or a function which takes a single parameter and returns
+		//		the tooltip text to be applied to chart data points. The string pattern
+		//		will have the following substitutions applied:
+		//
+		//		- {0} - the type of chart element ('bar', 'surface', etc)
+		//		- {1} - the name of the data series
+		//		- {2} - the independent axis value at the tooltip data point
+		//		- {3} - the series value at the tooltip data point point
+		//
+		//		The function, if supplied, will receive a single parameter exactly
+		//		as per the dojox.charting.action2D.Tooltip class. The default value
+		//		is to apply the default tooltip as defined by the
+		//		dojox.charting.action2D.Tooltip class.
+
+		// legendHorizontal: Boolean|Number
+		//		true if the legend should be rendered horizontally, or a number if
+		//		the legend should be rendered as horizontal rows with that number of
+		//		items in each row, or false if the legend should be rendered
+		//		vertically (same as specifying 1). The default is true (legend
+		//		rendered horizontally).
 		legendHorizontal: true,
-		//
-		//  theme: String|Theme
-		//      a theme to use for the chart, or the name of a theme.
-		//
-		//  chartNode: String|DomNode
-		//      an optional DOM node or the id of a DOM node to receive a
-		//      chart presentation of the data. Supply only when a chart is
-		//      required and the type is not 'chart'; when the type is
-		//      'chart' this property will be set to the widget attach point.
-		//
-		//  legendNode: String|DomNode
-		//      an optional DOM node or the id of a DOM node to receive a
-		//      chart legend for the data. Supply only when a legend is
-		//      required and the type is not 'legend'; when the type is
-		//      'legend' this property will be set to the widget attach point.
-		//
-		//  gridNode: String|DomNode
-		//      an optional DOM node or the id of a DOM node to receive a
-		//      grid presentation of the data. Supply only when a grid is
-		//      required and the type is not 'grid'; when the type is
-		//      'grid' this property will be set to the widget attach point.
-		//
-		//  titleNode: String|DomNode
-		//      an optional DOM node or the id of a DOM node to receive a
-		//      title for the data. Supply only when a title is
-		//      required and the type is not 'title'; when the type is
-		//      'title' this property will be set to the widget attach point.
-		//
-		//  footerNode: String|DomNode
-		//      an optional DOM node or the id of a DOM node to receive a
-		//      footer presentation of the data. Supply only when a footer is
-		//      required and the type is not 'footer'; when the type is
-		//      'footer' this property will be set to the widget attach point.
-		//
-		//  chartWidget: Object
-		//      the chart widget, if any
-		//
-		//  legendWidget: Object
-		//      the legend widget, if any
-		//
-		//  gridWidget: Object
-		//      the grid widget, if any
+
+		// theme: String|Theme
+		//		a theme to use for the chart, or the name of a theme.
+
+		// chartNode: String|DomNode
+		//		an optional DOM node or the id of a DOM node to receive a
+		//		chart presentation of the data. Supply only when a chart is
+		//		required and the type is not 'chart'; when the type is
+		//		'chart' this property will be set to the widget attach point.
+
+		// legendNode: String|DomNode
+		//		an optional DOM node or the id of a DOM node to receive a
+		//		chart legend for the data. Supply only when a legend is
+		//		required and the type is not 'legend'; when the type is
+		//		'legend' this property will be set to the widget attach point.
+
+		// gridNode: String|DomNode
+		//		an optional DOM node or the id of a DOM node to receive a
+		//		grid presentation of the data. Supply only when a grid is
+		//		required and the type is not 'grid'; when the type is
+		//		'grid' this property will be set to the widget attach point.
+
+		// titleNode: String|DomNode
+		//		an optional DOM node or the id of a DOM node to receive a
+		//		title for the data. Supply only when a title is
+		//		required and the type is not 'title'; when the type is
+		//		'title' this property will be set to the widget attach point.
+
+		// footerNode: String|DomNode
+		//		an optional DOM node or the id of a DOM node to receive a
+		//		footer presentation of the data. Supply only when a footer is
+		//		required and the type is not 'footer'; when the type is
+		//		'footer' this property will be set to the widget attach point.
+
+		// chartWidget: Object
+		//		the chart widget, if any
+
+		// legendWidget: Object
+		//		the legend widget, if any
+
+		// gridWidget: Object
+		//		the grid widget, if any
 		
 		constructor: function(node, args){
 			// summary:
 			//		Set up properties and initialize.
-			//
-			//	arguments:
-			//		node: DomNode
-			//			The node to attach the data presentation to.
-			//		kwArgs:	Object (see above)
+			// node: DomNode
+			//		The node to attach the data presentation to.
+			// args: Object
+			//		(see above)
 			
 			// apply arguments directly
 			dojo.mixin(this, args);
@@ -610,9 +606,9 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		
 		setURL: function(/*String?*/url, /*Object?*/ urlContent, /*Number?*/refreshInterval){
 			// summary:
-			//      Sets the URL to fetch data from, with optional content
-			//      supplied with the request, and an optional
-			//      refresh interval in milliseconds (0=no refresh)
+			//		Sets the URL to fetch data from, with optional content
+			//		supplied with the request, and an optional
+			//		refresh interval in milliseconds (0=no refresh)
 
 			// if a refresh interval is supplied we will start a fresh
 			// refresh after storing the supplied url
@@ -649,8 +645,8 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		
 		setData: function(/*Object?*/data, /*Number?*/refreshInterval){
 			// summary:
-			//      Sets the data to be presented, and an optional
-			//      refresh interval in milliseconds (0=no refresh)
+			//		Sets the data to be presented, and an optional
+			//		refresh interval in milliseconds (0=no refresh)
 			
 			// if a refresh interval is supplied we will start a fresh
 			// refresh after storing the supplied data reference
@@ -759,11 +755,11 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		
 		refresh: function(){
 			// summary:
-			//      If a URL or data has been supplied, refreshes the
-			//      presented data from the URL or data. If a refresh
-			//      interval is also set, the periodic refresh is
-			//      restarted. If a URL or data was not supplied, this
-			//      method has no effect.
+			//		If a URL or data has been supplied, refreshes the
+			//		presented data from the URL or data. If a refresh
+			//		interval is also set, the periodic refresh is
+			//		restarted. If a URL or data was not supplied, this
+			//		method has no effect.
 			if(this.url){
 				this.setURL(this.url, this.urlContent, this.refreshInterval);
 			}else if(this.data){
@@ -773,7 +769,7 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		
 		cancelRefresh: function(){
 			// summary:
-			//      Cancels any and all outstanding data refreshes
+			//		Cancels any and all outstanding data refreshes
 			if(this.refreshIntervalPending){
 				// cancel existing refresh
 				clearInterval(this.refreshIntervalPending);
@@ -789,14 +785,14 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		setPreparedStore: function(/*Object?*/store, /*String?*/query, /*Object?*/queryOptions){
 			// summary:
 			//		Sets the store and query.
-			//
+
 			this.preparedstore = store || this.store;
 			this.query = query || this.query;
 			this.queryOptions = queryOptions || this.queryOptions;
 			
 			if(this.preparedstore){
 				if(this.chartNode){
-					this.chartWidget = setupChart(this.chartNode, this.chartWidget, this.chartType, this.reverse, this.animate, this.labelMod, this.theme, this.tooltip, this.preparedstore, this.query, this,queryOptions);
+					this.chartWidget = setupChart(this.chartNode, this.chartWidget, this.chartType, this.reverse, this.animate, this.labelMod, this.theme, this.tooltip, this.preparedstore, this.query, this.queryOptions);
 					this.renderChartWidget();
 				}
 				if(this.legendNode){
@@ -817,9 +813,9 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		
 		renderChartWidget: function(){
 			// summary:
-			//      Renders the chart widget (if any). This method is
-			//      called whenever a chart widget is created or
-			//      configured, and may be connected to.
+			//		Renders the chart widget (if any). This method is
+			//		called whenever a chart widget is created or
+			//		configured, and may be connected to.
 			if(this.chartWidget){
 				this.chartWidget.render();
 			}
@@ -827,9 +823,9 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		
 		renderGridWidget: function(){
 			// summary:
-			//      Renders the grid widget (if any). This method is
-			//      called whenever a grid widget is created or
-			//      configured, and may be connected to.
+			//		Renders the grid widget (if any). This method is
+			//		called whenever a grid widget is created or
+			//		configured, and may be connected to.
 			if(this.gridWidget){
 				this.gridWidget.render();
 			}
@@ -837,15 +833,15 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		
 		getChartWidget: function(){
 			// summary:
-			//      Returns the chart widget (if any) created if the type
-			//      is "chart" or the "chartNode" property was supplied.
+			//		Returns the chart widget (if any) created if the type
+			//		is "chart" or the "chartNode" property was supplied.
 			return this.chartWidget;
 		},
 		
 		getGridWidget: function(){
 			// summary:
-			//      Returns the grid widget (if any) created if the type
-			//      is "grid" or the "gridNode" property was supplied.
+			//		Returns the grid widget (if any) created if the type
+			//		is "grid" or the "gridNode" property was supplied.
 			return this.gridWidget;
 		},
 		
diff --git a/dojox/widget/Dialog.js b/dojox/widget/Dialog.js
index 6845f38..5ee7c30 100644
--- a/dojox/widget/Dialog.js
+++ b/dojox/widget/Dialog.js
@@ -5,11 +5,10 @@ define([
 
 	dojo.getObject('widget', true, dojox);
 	
-	dojo.declare('dojox.widget.Dialog', dojox.widget.DialogSimple,
+	return dojo.declare('dojox.widget.Dialog', dojox.widget.DialogSimple,
 		{
 		// summary:
 		//		A Lightbox-like Modal-dialog for HTML Content
-		//
 		// description:
 		//		An HTML-capable Dialog widget with advanced sizing
 		//		options, animated show/hide and other useful options.
@@ -24,8 +23,8 @@ define([
 		// sizeToViewport: Boolean
 		//		If true, fix the size of the dialog to the Viewport based on
 		//		viewportPadding value rather than the calculated or natural
-		//		stlye. If false, base the size on a passed dimension attribute.
-		//		Eitherway, the viewportPadding value is used if the the content
+		//		style. If false, base the size on a passed dimension attribute.
+		//		Either way, the viewportPadding value is used if the the content
 		//		extends beyond the viewport size for whatever reason.
 		sizeToViewport: false,
 
@@ -37,7 +36,7 @@ define([
 		viewportPadding: 35,
 
 		// dimensions: Array
-		//		A two-element array of [widht,height] to animate the Dialog to if sizeToViewport="false"
+		//		A two-element array of [width,height] to animate the Dialog to if sizeToViewport="false"
 		//		Defaults to [300,300]
 		dimensions: null,
 
@@ -74,7 +73,8 @@ define([
 		},
 
 		_setup: function(){
-			// summary: Piggyback on dijit.Dialog's _setup for load-time options, deferred to
+			// summary:
+			//		Piggyback on dijit.Dialog's _setup for load-time options, deferred to
 
 			this.inherited(arguments);
 			if(!this._alreadyInitialized){
@@ -92,7 +92,8 @@ define([
 		},
 
 		_setSize: function(){
-			// summary: cache and set our desired end position
+			// summary:
+			//		cache and set our desired end position
 			this._vp = dojo.window.getBox();
 			var tc = this.containerNode,
 				vpSized = this.sizeToViewport
@@ -140,7 +141,8 @@ define([
 		},
 
 		_handleNav: function(e){
-			// summary: Handle's showing or hiding the close icon
+			// summary:
+			//		Handle's showing or hiding the close icon
 
 			var navou = "_navOut",
 				navin = "_navIn",
@@ -156,7 +158,8 @@ define([
 		// an experiment in a quicksilver-like hide. too choppy for me.
 		/*
 		hide: function(){
-			// summary: Hide the dialog
+			// summary:
+			//		Hide the dialog
 
 			// if we haven't been initialized yet then we aren't showing and we can just return
 			if(!this._alreadyInitialized){
@@ -226,7 +229,8 @@ define([
 		},
 
 		_showContent: function(e){
-			// summary: Show the inner container after sizing animation
+			// summary:
+			//		Show the inner container after sizing animation
 
 			var container = this.containerNode;
 			dojo.style(this.domNode, {
@@ -243,8 +247,5 @@ define([
 		}
 
 	});
-
-	return dojox.widget.Dialog;
-
 });
 
diff --git a/dojox/widget/DialogSimple.js b/dojox/widget/DialogSimple.js
index 6a8e32a..0a21ec8 100644
--- a/dojox/widget/DialogSimple.js
+++ b/dojox/widget/DialogSimple.js
@@ -1,11 +1,12 @@
-define(["dojo", "dijit", "dojox", "dijit/Dialog", "dojox/layout/ContentPane"], function(dojo, dijit, dojox){
+define([
+	"dojo/_base/declare", "dijit/Dialog", "dojox/layout/ContentPane"
+], function(declare, Dialog, ContentPane){
 
-	dojo.getObject("widget", true, dojox);
-	return dojo.declare("dojox.widget.DialogSimple", [dojox.layout.ContentPane, dijit._DialogBase], {
-		// summary: A Simple Dialog Mixing the `dojox.layout.ContentPane` functionality over
+	return declare("dojox.widget.DialogSimple", [ContentPane, Dialog._DialogBase], {
+		// summary:
+		//		A Simple Dialog Mixing the `dojox.layout.ContentPane` functionality over
 		//		top of a vanilla `dijit.Dialog`. See `dojox.widget.Dialog` for a more flexible
 		//		dialog option allowing animations and different styles/theme support.
 	});
-	
 });
 
diff --git a/dojox/widget/DocTester.js b/dojox/widget/DocTester.js
index a48291a..8fef1e3 100644
--- a/dojox/widget/DocTester.js
+++ b/dojox/widget/DocTester.js
@@ -9,13 +9,15 @@ dojo.require("dojox.testing.DocTest");
 dojo.declare('dojox.widget.DocTester',
 	[dijit._Widget, dijit._Templated],
 	{
-		// summary: A widget to run DocTests inside an HTML page.
-		//
+		// summary:
+		//		A widget to run DocTests inside an HTML page.
+
 		templateString: dojo.cache('dojox.widget','DocTester/DocTester.html'),
 		widgetsInTemplate: true,
 	
 		_fillContent:function(/*DomNode*/source){
-			// summary: Overridden from _Templates.js, which actually just takes care of filling the containerNode.
+			// summary:
+			//		Overridden from _Templates.js, which actually just takes care of filling the containerNode.
 			var src = source.innerHTML;
 			this.doctests = new dojox.testing.DocTest();
 			this.tests = this.doctests.getTestsFromString(this._unescapeHtml(src));
@@ -65,7 +67,8 @@ dojo.declare('dojox.widget.DocTester',
 		},
 		
 		reset:function(){
-			// summary: Reset the DocTester visuals and enable the "Run tests" button again.
+			// summary:
+			//		Reset the DocTester visuals and enable the "Run tests" button again.
 			dojo.style(this.runButtonNode.domNode, "display", "");
 			dojo.style(this.resetButtonNode.domNode, "display", "none");
 			this.numTestsOkNode.innerHTML = "0";
@@ -74,13 +77,13 @@ dojo.declare('dojox.widget.DocTester',
 			dojo.query(".testCase", this.domNode).removeClass("resultOk").removeClass("resultNok");
 		},
 		
-		_unescapeHtml:function(/*string*/str){
-			// TODO Should become dojo.html.unentities() or so, when exists use instead
+		_unescapeHtml:function(/* String */ str){
 			// summary:
 			//		Adds escape sequences for special characters in XML: &<>"'
 			str = String(str).replace(/&/gm, "&").replace(/</gm, "<")
 				.replace(/>/gm, ">").replace(/"/gm, '"');
-			return str; // string
+			// TODO Should become dojo.html.unentities() or so, when exists use instead
+			return str; // String
 		}
 	}
 );
\ No newline at end of file
diff --git a/dojox/widget/DynamicTooltip.js b/dojox/widget/DynamicTooltip.js
index 3dbbdbf..5217dc3 100644
--- a/dojox/widget/DynamicTooltip.js
+++ b/dojox/widget/DynamicTooltip.js
@@ -7,7 +7,7 @@ dojo.requireLocalization("dijit", "loading");
 dojo.declare("dojox.widget.DynamicTooltip", dijit.Tooltip,
 	{
 		// summary:
-		//		Extention of dijit.Tooltip providing content set via XHR
+		//		Extension of dijit.Tooltip providing content set via XHR
 		//		request via href param
 
 		// hasLoaded: Boolean
@@ -19,11 +19,11 @@ dojo.declare("dojox.widget.DynamicTooltip", dijit.Tooltip,
 		href: "",
 		
 		// label: String
-		//		contents to diplay in the tooltip. Initialized to a loading icon.
+		//		contents to display in the tooltip. Initialized to a loading icon.
 		label: "",
 
 		// preventCache: Boolean
-		//		Cache content retreived externally
+		//		Cache content retrieved externally
 		preventCache:	false,
 		
 		postMixInProperties: function(){
@@ -54,7 +54,7 @@ dojo.declare("dojox.widget.DynamicTooltip", dijit.Tooltip,
 			//		Hook so attr("href", ...) works.
 			// description:
 			//		resets so next show loads new href
-			//	href:
+			// href:
 			//		url to the content you want to show, must be within the same domain as your mainpage
 		
 			this.href = href;
diff --git a/dojox/widget/FeedPortlet.js b/dojox/widget/FeedPortlet.js
index 0e0f9df..a06c76c 100644
--- a/dojox/widget/FeedPortlet.js
+++ b/dojox/widget/FeedPortlet.js
@@ -8,7 +8,8 @@ dojo.require("dojox.data.GoogleFeedStore");
 dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
 	// summary:
 	//		A Portlet that loads a XML feed.
-	// description: The feed is displayed as
+	// description:
+	//		The feed is displayed as
 	//		an unordered list of links.	When a link is hovered over
 	//		by the mouse, it displays a summary in a tooltip.
 
@@ -287,21 +288,22 @@ dojo.declare("dojox.widget.PortletFeedSettings",
 	// description:
 	//		It provides form items that the user can use to change the URL
 	//		for a feed to load into the FeedPortlet.
-	//		There are two forms that it can take.	<br>
+	//		There are two forms that it can take.
+	//
 	//		The first is to display a text field, with Load and Cancel buttons,
 	//		which is prepopulated with the enclosing FeedPortlet's URL.
-	//		If a <select> DOM node is used as the source node for this widget,
+	//		If a `<select>` DOM node is used as the source node for this widget,
 	//		it displays a list of predefined URLs that the user can select from
 	//		to load into the enclosing FeedPortlet.
 	//
 	// example:
-	//		<div dojoType="dojox.widget.PortletFeedSettings"></div>
+	// |	<div dojoType="dojox.widget.PortletFeedSettings"></div>
 	//
 	// example:
-	//		<select dojoType="dojox.widget.PortletFeedSettings">
-	//			<option>http://www.dojotoolkit.org/aggregator/rss</option>
-	//			<option>http://dojocampus.org/content/category/podcast/feed/</option>
-	//		</select>
+	// |	<select dojoType="dojox.widget.PortletFeedSettings">
+	// |		<option>http://www.dojotoolkit.org/aggregator/rss</option>
+	// |		<option>http://dojocampus.org/content/category/podcast/feed/</option>
+	// |	</select>
 
 	"class" : "dojoxPortletFeedSettings",
 
diff --git a/dojox/widget/FilePicker.js b/dojox/widget/FilePicker.js
index f8dc179..7f7ddce 100644
--- a/dojox/widget/FilePicker.js
+++ b/dojox/widget/FilePicker.js
@@ -7,11 +7,12 @@ dojo.requireLocalization("dojox.widget", "FilePicker");
 
 dojo.declare("dojox.widget._FileInfoPane",
 	[dojox.widget._RollingListPane], {
-	// summary: a pane to display the information for the currently-selected
-	//	file
+	// summary:
+	//		a pane to display the information for the currently-selected
+	//		file
 	
 	// templateString: string
-	//	delete our template string
+	//		delete our template string
 	templateString: "",
 	
 	// templateString: String
@@ -25,8 +26,8 @@ dojo.declare("dojox.widget._FileInfoPane",
 
 	onItems: function(){
 		// summary:
-		//	called after a fetch or load - at this point, this.items should be
-		//  set and loaded.
+		//		called after a fetch or load - at this point, this.items should be
+		//		set and loaded.
 		var store = this.store, item = this.items[0];
 		if(!item){
 			this._onError("Load", new Error("No item defined"));
@@ -41,46 +42,48 @@ dojo.declare("dojox.widget._FileInfoPane",
 });
 
 dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
-	// summary: a specialized version of RollingList that handles file information
-	//  in a store
+	// summary:
+	//		a specialized version of RollingList that handles file information
+	//		in a store
 	
 	className: "dojoxFilePicker",
 	
-	// pathSeparator: string
-	//  Our file separator - it will be guessed if not set
+	// pathSeparator: String
+	//		Our file separator - it will be guessed if not set
 	pathSeparator: "",
 	
-	// topDir: string
-	//	The top directory string - it will be guessed if not set
+	// topDir: String
+	//		The top directory string - it will be guessed if not set
 	topDir: "",
 		
-	// parentAttr: string
-	//	the attribute to read for finding our parent directory
+	// parentAttr: String
+	//		the attribute to read for finding our parent directory
 	parentAttr: "parentDir",
 	
-	// pathAttr: string
-	//  the attribute to read for getting the full path of our file
+	// pathAttr: String
+	//		the attribute to read for getting the full path of our file
 	pathAttr: "path",
 	
-	// preloadItems: boolean or int
-	//  Set this to a sane number - since we expect to mostly be using the
-	//	dojox.data.FileStore - which doesn't like loading lots of items
-	//	all at once.
+	// preloadItems: Boolean|Int
+	//		Set this to a sane number - since we expect to mostly be using the
+	//		dojox.data.FileStore - which doesn't like loading lots of items
+	//		all at once.
 	preloadItems: 50,
 
-	// selectDirectories: boolean
-	//  whether or not we allow selection of directories - that is, whether or
-	//  our value can be set to a directory.
+	// selectDirectories: Boolean
+	//		whether or not we allow selection of directories - that is, whether or
+	//		our value can be set to a directory.
 	selectDirectories: true,
 
-	// selectFiles: boolean
-	//  whether or not we allow selection of files - that is, we will disable
-	//  the file entries.
+	// selectFiles: Boolean
+	//		whether or not we allow selection of files - that is, we will disable
+	//		the file entries.
 	selectFiles: true,
 
 	_itemsMatch: function(/*item*/ item1, /*item*/ item2){
-		// Summary: returns whether or not the two items match - checks ID if
-		//  they aren't the exact same object - ignoring trailing slashes
+		// Summary:
+		//		Returns whether or not the two items match - checks ID if
+		//		they aren't the exact same object - ignoring trailing slashes
 		if(!item1 && !item2){
 			return true;
 		}else if(!item1 || !item2){
@@ -145,7 +148,7 @@ dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
 		return ret;
 	},
 	
-	getMenuItemForItem: function(/*item*/ item, /* dijit._Contained */ parentPane, /* item[]? */ children){
+	getMenuItemForItem: function(/*item*/ item, /* dijit/_Contained */ parentPane, /* item[]? */ children){
 		var menuOptions = {iconClass: "dojoxDirectoryItemIcon"};
 		if(!this.store.getValue(item, "directory")){
 			menuOptions.iconClass = "dojoxFileItemIcon";
@@ -161,7 +164,7 @@ dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
 		return ret;
 	},
 	
-	getPaneForItem: function(/*item*/ item, /* dijit._Contained */ parentPane, /* item[]? */ children){
+	getPaneForItem: function(/*item*/ item, /* dijit/_Contained */ parentPane, /* item[]? */ children){
 		var ret = null;
 		if(!item || (this.store.isItem(item) && this.store.getValue(item, "directory"))){
 			ret = new dojox.widget._RollingListGroupPane({});
@@ -171,8 +174,9 @@ dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
 		return ret;
 	},
 	
-	_setPathValueAttr: function(/*string*/ path, /*boolean?*/ resetLastExec, /*function?*/ onSet){
-		// Summary: sets the value of this widget based off the given path
+	_setPathValueAttr: function(/*String*/ path, /*Boolean?*/ resetLastExec, /*function?*/ onSet){
+		// summary:
+		//		sets the value of this widget based off the given path
 		if(!path){
 			this.set("value", null);
 			return;
@@ -192,8 +196,9 @@ dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
 	},
 	
 	_getPathValueAttr: function(/*item?*/val){
-		// summary: returns the path value of the given value (or current value
-		//  if not passed a value)
+		// summary:
+		//		returns the path value of the given value (or current value
+		//		if not passed a value)
 		if(!val){
 			val = this.value;
 		}
@@ -205,7 +210,8 @@ dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
 	},
 	
 	_setValue: function(/* item */ value){
-		// summary: internally sets the value and fires onchange
+		// summary:
+		//		internally sets the value and fires onchange
 		delete this._setInProgress;
 		var store = this.store;
 		if(value && store.isItem(value)){
@@ -220,4 +226,4 @@ dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
 			this._onChange(value);
 		}
 	}
-});
\ No newline at end of file
+});
diff --git a/dojox/widget/FisheyeList.js b/dojox/widget/FisheyeList.js
index 86cc17a..c7f80f9 100644
--- a/dojox/widget/FisheyeList.js
+++ b/dojox/widget/FisheyeList.js
@@ -1,708 +1,594 @@
-dojo.provide("dojox.widget.FisheyeList");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Container");
-dojo.require("dijit._Contained");
-
-dojo.declare("dojox.widget.FisheyeList", [dijit._Widget, dijit._Templated, dijit._Container], {
-	// summary:
-	//	Menu similar to the fish eye menu on the Mac OS
-	// example:
-	// |	<div dojoType="FisheyeList"
-	// |		itemWidth="40" itemHeight="40"
-	// |		itemMaxWidth="150" itemMaxHeight="150"
-	// |		orientation="horizontal"
-	// |		effectUnits="2"
-	// |		itemPadding="10"
-	// |		attachEdge="center"
-	// |		labelEdge="bottom">
-	// |
-	// |		<div dojoType="FisheyeListItem"
-	// |			id="item1"
-	// |			onclick="alert('click on' + this.label + '(from widget id ' + this.widgetId + ')!');"
-	// |			label="Item 1"
-	// |			iconSrc="images/fisheye_1.png">
-	// |		</div>
-	// |		...
-	// |	</div>
-	//
-	constructor: function(){
-		//
-		// TODO
-		// fix really long labels in vertical mode
-		//
-	
-		this.pos = {'x': -1, 'y': -1};	// current cursor position, relative to the grid
-		
-		// for conservative trigger mode, when triggered, timerScale is gradually increased from 0 to 1
-		this.timerScale = 1.0;
-	
-	},
-
-	EDGE: {
-		CENTER: 0,
-		LEFT: 1,
-		RIGHT: 2,
-		TOP: 3,
-		BOTTOM: 4
-	},
-
-	templateString: '<div class="dojoxFisheyeListBar" dojoAttachPoint="containerNode"></div>',
-
-	snarfChildDomOutput: true,
-	
-	// itemWidth: Integer
-	//	width of menu item (in pixels) in it's dormant state (when the mouse is far away)
-	itemWidth: 40,
-	
-	// itemHeight: Integer
-	//	height of menu item (in pixels) in it's dormant state (when the mouse is far away)
-	itemHeight: 40,
-	
-	// itemMaxWidth: Integer
-	//	width of menu item (in pixels) in it's fully enlarged state (when the mouse is directly over it)
-	itemMaxWidth: 150,
-	
-	// itemMaxHeight: Integer
-	//	height of menu item (in pixels) in it's fully enlarged state (when the mouse is directly over it)
-	itemMaxHeight: 150,
-
-	imgNode: null,
-	
-	// orientation: String
-	//	orientation of the menu, either "horizontal" or "vertical"
-	orientation: 'horizontal',
-
-	// isFixed: Boolean
-	//	toggle to enable additional listener (window scroll) if FisheyeList is in a fixed postion
-	isFixed: false,
-	
-	// conservativeTrigger: Boolean
-	//	if true, don't start enlarging menu items until mouse is over an image;
-	//	if false, start enlarging menu items as the mouse moves near them.
-	conservativeTrigger: false,
-	
-	// effectUnits: Number
-	//	controls how much reaction the menu makes, relative to the distance of the mouse from the menu
-	effectUnits: 2,
-		
-	// itemPadding: Integer
-	//	padding (in pixels) betweeen each menu item
-	itemPadding: 10,
-	
-	// attachEdge: String
-	//	controls the border that the menu items don't expand past;
-	//	for example, if set to "top", then the menu items will drop downwards as they expand.
-	// values
-	//	"center", "left", "right", "top", "bottom".
-	attachEdge: 'center',
-
-	// labelEdge: String
-	//	controls were the labels show up in relation to the menu item icons
-	// values
-	//	"center", "left", "right", "top", "bottom".
-	labelEdge: 'bottom',
-
-	postCreate: function(){
-		var e = this.EDGE;
-		dojo.setSelectable(this.domNode, false);
-
-		var isHorizontal = this.isHorizontal = (this.orientation == 'horizontal');
-		this.selectedNode = -1;
-
-		this.isOver = false;
-		this.hitX1 = -1;
-		this.hitY1 = -1;
-		this.hitX2 = -1;
-		this.hitY2 = -1;
-
-		//
-		// only some edges make sense...
-		//
-		this.anchorEdge = this._toEdge(this.attachEdge, e.CENTER);
-		this.labelEdge  = this._toEdge(this.labelEdge,  e.TOP);
-
-		if(this.labelEdge == e.CENTER){ this.labelEdge = e.TOP; }
-
-		if(isHorizontal){
-			if(this.anchorEdge == e.LEFT){ this.anchorEdge = e.CENTER; }
-			if(this.anchorEdge == e.RIGHT){ this.anchorEdge = e.CENTER; }
-			if(this.labelEdge == e.LEFT){ this.labelEdge = e.TOP; }
-			if(this.labelEdge == e.RIGHT){ this.labelEdge = e.TOP; }
-		}else{
-			if(this.anchorEdge == e.TOP){ this.anchorEdge = e.CENTER; }
-			if(this.anchorEdge == e.BOTTOM){ this.anchorEdge = e.CENTER; }
-			if(this.labelEdge == e.TOP){ this.labelEdge = e.LEFT; }
-			if(this.labelEdge == e.BOTTOM){ this.labelEdge = e.LEFT; }
-		}
-
-		//
-		// figure out the proximity size
-		//
-		var effectUnits = this.effectUnits;
-		this.proximityLeft   = this.itemWidth  * (effectUnits - 0.5);
-		this.proximityRight  = this.itemWidth  * (effectUnits - 0.5);
-		this.proximityTop    = this.itemHeight * (effectUnits - 0.5);
-		this.proximityBottom = this.itemHeight * (effectUnits - 0.5);
-	
-		if(this.anchorEdge == e.LEFT){
-			this.proximityLeft = 0;
-		}
-		if(this.anchorEdge == e.RIGHT){
-			this.proximityRight = 0;
-		}
-		if(this.anchorEdge == e.TOP){
-			this.proximityTop = 0;
-		}
-		if(this.anchorEdge == e.BOTTOM){
-			this.proximityBottom = 0;
-		}
-		if(this.anchorEdge == e.CENTER){
-			this.proximityLeft   /= 2;
-			this.proximityRight  /= 2;
-			this.proximityTop    /= 2;
-			this.proximityBottom /= 2;
-		}
-	},
-	
-	startup: function(){
-		// summary: create our connections and setup our FisheyeList
-		this.children = this.getChildren();
-		//original postCreate() --tk
-		this._initializePositioning();
-	
-		//
-		// in liberal trigger mode, activate menu whenever mouse is close
-		//
-		if(!this.conservativeTrigger){
-			this._onMouseMoveHandle = dojo.connect(document.documentElement, "onmousemove", this, "_onMouseMove");
-		}
-		if(this.isFixed){
-			this._onScrollHandle = dojo.connect(document,"onscroll",this,"_onScroll");
-		}
-			
-		// Deactivate the menu if mouse is moved off screen (doesn't work for FF?)
-		this._onMouseOutHandle = dojo.connect(document.documentElement, "onmouseout", this, "_onBodyOut");
-		this._addChildHandle = dojo.connect(this, "addChild", this, "_initializePositioning");
-		this._onResizeHandle = dojo.connect(window,"onresize", this, "_initializePositioning");
-	},
-	
-	_initializePositioning: function(){
-		this.itemCount = this.children.length;
-	
-		this.barWidth  = (this.isHorizontal ? this.itemCount : 1) * this.itemWidth;
-		this.barHeight = (this.isHorizontal ? 1 : this.itemCount) * this.itemHeight;
-	
-		this.totalWidth  = this.proximityLeft + this.proximityRight  + this.barWidth;
-		this.totalHeight = this.proximityTop  + this.proximityBottom + this.barHeight;
-	
-		//
-		// calculate effect ranges for each item
-		//
-
-		for(var i=0; i<this.children.length; i++){
-
-			this.children[i].posX = this.itemWidth  * (this.isHorizontal ? i : 0);
-			this.children[i].posY = this.itemHeight * (this.isHorizontal ? 0 : i);
-
-			this.children[i].cenX = this.children[i].posX + (this.itemWidth  / 2);
-			this.children[i].cenY = this.children[i].posY + (this.itemHeight / 2);
-
-			var isz = this.isHorizontal ? this.itemWidth : this.itemHeight;
-			var r = this.effectUnits * isz;
-			var c = this.isHorizontal ? this.children[i].cenX : this.children[i].cenY;
-			var lhs = this.isHorizontal ? this.proximityLeft : this.proximityTop;
-			var rhs = this.isHorizontal ? this.proximityRight : this.proximityBottom;
-			var siz = this.isHorizontal ? this.barWidth : this.barHeight;
-
-			var range_lhs = r;
-			var range_rhs = r;
-
-			if(range_lhs > c+lhs){ range_lhs = c+lhs; }
-			if(range_rhs > (siz-c+rhs)){ range_rhs = siz-c+rhs; }
-
-			this.children[i].effectRangeLeft = range_lhs / isz;
-			this.children[i].effectRangeRght = range_rhs / isz;
-
-			//dojo.debug('effect range for '+i+' is '+range_lhs+'/'+range_rhs);
-		}
-
-		//
-		// create the bar
-		//
-		this.domNode.style.width = this.barWidth + 'px';
-		this.domNode.style.height = this.barHeight + 'px';
-
-		//
-		// position the items
-		//
-		for(i=0; i<this.children.length; i++){
-			var itm = this.children[i];
-			var elm = itm.domNode;
-			elm.style.left   = itm.posX + 'px';
-			elm.style.top    = itm.posY + 'px';
-			elm.style.width  = this.itemWidth + 'px';
-			elm.style.height = this.itemHeight + 'px';
-			
-			itm.imgNode.style.left = this.itemPadding+'%';
-			itm.imgNode.style.top = this.itemPadding+'%';
-			itm.imgNode.style.width = (100 - 2 * this.itemPadding) + '%';
-			itm.imgNode.style.height = (100 - 2 * this.itemPadding) + '%';
-		}
-
-		//
-		// calc the grid
-		//
-		this._calcHitGrid();
-	},
-
-	_overElement: function(/* DomNode|String */node, /* Event */e){
-		// summary:
-		//	Returns whether the mouse is over the passed element.
-		// Node: Must must be display:block (ie, not a <span>)
-		node = dojo.byId(node);
-		var mouse = {x: e.pageX, y: e.pageY};
-		var absolute = dojo.position(node, true);
-		var top = absolute.y;
-		var bottom = top + absolute.h;
-		var left = absolute.x;
-		var right = left + absolute.w;
-
-		return (mouse.x >= left
-			&& mouse.x <= right
-			&& mouse.y >= top
-			&& mouse.y <= bottom
-		);	//	boolean
-	},
-
-	_onBodyOut: function(/*Event*/ e){
-		// clicking over an object inside of body causes this event to fire; ignore that case
-		if( this._overElement(dojo.body(), e) ){
-			return;
-		}
-		this._setDormant(e);
-	},
-
-	_setDormant: function(/*Event*/ e){
-		// summary: called when mouse moves out of menu's range
-
-		if(!this.isOver){ return; }	// already dormant?
-		this.isOver = false;
-
-		if(this.conservativeTrigger){
-			// user can't re-trigger the menu expansion
-			// until he mouses over a icon again
-			dojo.disconnect(this._onMouseMoveHandle);
-		}
-		this._onGridMouseMove(-1, -1);
-	},
-
-	_setActive: function(/*Event*/ e){
-		// summary: called when mouse is moved into menu's range
-
-		if(this.isOver){ return; }	// already activated?
-		this.isOver = true;
-
-		if(this.conservativeTrigger){
-			// switch event handlers so that we handle mouse events from anywhere near
-			// the menu
-			this._onMouseMoveHandle = dojo.connect(document.documentElement, "onmousemove", this, "_onMouseMove");
-
-			this.timerScale=0.0;
-
-			// call mouse handler to do some initial necessary calculations/positioning
-			this._onMouseMove(e);
-
-			// slowly expand the icon size so it isn't jumpy
-			this._expandSlowly();
-		}
-	},
-
-	_onMouseMove: function(/*Event*/ e){
-		// summary: called when mouse is moved
-		if(	(e.pageX >= this.hitX1) && (e.pageX <= this.hitX2) &&
-			(e.pageY >= this.hitY1) && (e.pageY <= this.hitY2)	){
-			if(!this.isOver){
-				this._setActive(e);
-			}
-			this._onGridMouseMove(e.pageX-this.hitX1, e.pageY-this.hitY1);
-		}else{
-			if(this.isOver){
-				this._setDormant(e);
-			}
-		}
-	},
-
-	_onScroll: function(){
-		this._calcHitGrid();
-	},
-
-	onResized: function(){
-		this._calcHitGrid();
-	},
-
-	_onGridMouseMove: function(x, y){
-		// summary: called when mouse is moved in the vicinity of the menu
-		this.pos = {x:x, y:y};
-		this._paint();
-	},
-
-	_paint: function(){
-		var x=this.pos.x;
-		var y=this.pos.y;
-
-		if(this.itemCount <= 0){ return; }
-
-		//
-		// figure out our main index
-		//
-		var pos = this.isHorizontal ? x : y;
-		var prx = this.isHorizontal ? this.proximityLeft : this.proximityTop;
-		var siz = this.isHorizontal ? this.itemWidth : this.itemHeight;
-		var sim = this.isHorizontal ?
-			(1.0-this.timerScale)*this.itemWidth + this.timerScale*this.itemMaxWidth :
-			(1.0-this.timerScale)*this.itemHeight + this.timerScale*this.itemMaxHeight ;
-
-		var cen = ((pos - prx) / siz) - 0.5;
-		var max_off_cen = (sim / siz) - 0.5;
-
-		if(max_off_cen > this.effectUnits){ max_off_cen = this.effectUnits; }
-
-		//
-		// figure out our off-axis weighting
-		//
-		var off_weight = 0, cen2;
-
-		if(this.anchorEdge == this.EDGE.BOTTOM){
-			cen2 = (y - this.proximityTop) / this.itemHeight;
-			off_weight = (cen2 > 0.5) ? 1 : y / (this.proximityTop + (this.itemHeight / 2));
-		}
-		if(this.anchorEdge == this.EDGE.TOP){
-			cen2 = (y - this.proximityTop) / this.itemHeight;
-			off_weight = (cen2 < 0.5) ? 1 : (this.totalHeight - y) / (this.proximityBottom + (this.itemHeight / 2));
-		}
-		if(this.anchorEdge == this.EDGE.RIGHT){
-			cen2 = (x - this.proximityLeft) / this.itemWidth;
-			off_weight = (cen2 > 0.5) ? 1 : x / (this.proximityLeft + (this.itemWidth / 2));
-		}
-		if(this.anchorEdge == this.EDGE.LEFT){
-			cen2 = (x - this.proximityLeft) / this.itemWidth;
-			off_weight = (cen2 < 0.5) ? 1 : (this.totalWidth - x) / (this.proximityRight + (this.itemWidth / 2));
-		}
-		if(this.anchorEdge == this.EDGE.CENTER){
-			if(this.isHorizontal){
-				off_weight = y / (this.totalHeight);
-			}else{
-				off_weight = x / (this.totalWidth);
-			}
-
-			if(off_weight > 0.5){
-				off_weight = 1 - off_weight;
-			}
-
-			off_weight *= 2;
-		}
-
-		//
-		// set the sizes
-		//
-		for(var i=0; i<this.itemCount; i++){
-			var weight = this._weighAt(cen, i);
-			if(weight < 0){weight = 0;}
-			this._setItemSize(i, weight * off_weight);
-		}
-
-		//
-		// set the positions
-		//
-
-		var main_p = Math.round(cen);
-		var offset = 0;
-
-		if(cen < 0){
-
-			main_p = 0;
-
-		}else if(cen > this.itemCount - 1){
-
-			main_p = this.itemCount -1;
-
-		}else{
-
-			offset = (cen - main_p) * ((this.isHorizontal ? this.itemWidth : this.itemHeight) - this.children[main_p].sizeMain);
-		}
-
-		this._positionElementsFrom(main_p, offset);
-	},
-
-	_weighAt: function(/*Integer*/ cen, /*Integer*/ i){
-		var dist = Math.abs(cen - i);
-		var limit = ((cen - i) > 0) ? this.children[i].effectRangeRght : this.children[i].effectRangeLeft;
-		return (dist > limit) ? 0 : (1 - dist / limit); // Integer
-	},
-
-	_setItemSize: function(p, scale){
-		if(this.children[p].scale == scale){ return; }
-		this.children[p].scale = scale;
-
-		scale *= this.timerScale;
-		var w = Math.round(this.itemWidth  + ((this.itemMaxWidth  - this.itemWidth ) * scale));
-		var h = Math.round(this.itemHeight + ((this.itemMaxHeight - this.itemHeight) * scale));
-
-		if(this.isHorizontal){
-
-			this.children[p].sizeW = w;
-			this.children[p].sizeH = h;
-
-			this.children[p].sizeMain = w;
-			this.children[p].sizeOff  = h;
-
-			var y = 0;
-			if(this.anchorEdge == this.EDGE.TOP){
-				y = (this.children[p].cenY - (this.itemHeight / 2));
-			}else if(this.anchorEdge == this.EDGE.BOTTOM){
-				y = (this.children[p].cenY - (h - (this.itemHeight / 2)));
-			}else{
-				y = (this.children[p].cenY - (h / 2));
-			}
-
-			this.children[p].usualX = Math.round(this.children[p].cenX - (w / 2));
-			this.children[p].domNode.style.top  = y + 'px';
-			this.children[p].domNode.style.left  = this.children[p].usualX + 'px';
-
-		}else{
-
-			this.children[p].sizeW = w;
-			this.children[p].sizeH = h;
-
-			this.children[p].sizeOff  = w;
-			this.children[p].sizeMain = h;
-
-			var x = 0;
-			if(this.anchorEdge == this.EDGE.LEFT){
-				x = this.children[p].cenX - (this.itemWidth / 2);
-			}else if(this.anchorEdge == this.EDGE.RIGHT){
-				x = this.children[p].cenX - (w - (this.itemWidth / 2));
-			}else{
-				x = this.children[p].cenX - (w / 2);
-			}
-
-			this.children[p].domNode.style.left = x + 'px';
-			this.children[p].usualY = Math.round(this.children[p].cenY - (h / 2));
-
-			this.children[p].domNode.style.top  = this.children[p].usualY + 'px';
-		}
-
-		this.children[p].domNode.style.width  = w + 'px';
-		this.children[p].domNode.style.height = h + 'px';
-
-		if(this.children[p].svgNode){
-			this.children[p].svgNode.setSize(w, h);
-		}
-	},
-
-	_positionElementsFrom: function(p, offset){
-		var pos = 0;
-
-		var usual, start;
-		if(this.isHorizontal){
-			usual = "usualX";
-			start = "left";
-		}else{
-			usual = "usualY";
-			start = "top";
-		}
-		pos = Math.round(this.children[p][usual] + offset);
-		if(this.children[p].domNode.style[start] != (pos + 'px')){
-			this.children[p].domNode.style[start] = pos + 'px';
-			this._positionLabel(this.children[p]);
-		}
-
-		// position before
-		var bpos = pos;
-		for(var i=p-1; i>=0; i--){
-			bpos -= this.children[i].sizeMain;
-
-			if(this.children[p].domNode.style[start] != (bpos + 'px')){
-				this.children[i].domNode.style[start] = bpos + 'px';
-				this._positionLabel(this.children[i]);
-			}
-		}
-
-		// position after
-		var apos = pos;
-		for(i=p+1; i<this.itemCount; i++){
-			apos += this.children[i-1].sizeMain;
-			if(this.children[p].domNode.style[start] != (apos + 'px')){
-				this.children[i].domNode.style[start] = apos + 'px';
-				this._positionLabel(this.children[i]);
-			}
-		}
-
-	},
-
-	_positionLabel: function(itm){
-		var x = 0;
-		var y = 0;
-		
-		var mb = dojo.marginBox(itm.lblNode);
-
-		if(this.labelEdge == this.EDGE.TOP){
-			x = Math.round((itm.sizeW / 2) - (mb.w / 2));
-			y = -mb.h;
-		}
-
-		if(this.labelEdge == this.EDGE.BOTTOM){
-			x = Math.round((itm.sizeW / 2) - (mb.w / 2));
-			y = itm.sizeH;
-		}
-
-		if(this.labelEdge == this.EDGE.LEFT){
-			x = -mb.w;
-			y = Math.round((itm.sizeH / 2) - (mb.h / 2));
-		}
-
-		if(this.labelEdge == this.EDGE.RIGHT){
-			x = itm.sizeW;
-			y = Math.round((itm.sizeH / 2) - (mb.h / 2));
-		}
-
-		itm.lblNode.style.left = x + 'px';
-		itm.lblNode.style.top  = y + 'px';
-	},
-
-	_calcHitGrid: function(){
-
-		var pos = dojo.coords(this.domNode, true);
-
-		this.hitX1 = pos.x - this.proximityLeft;
-		this.hitY1 = pos.y - this.proximityTop;
-		this.hitX2 = this.hitX1 + this.totalWidth;
-		this.hitY2 = this.hitY1 + this.totalHeight;
-
-	},
-
-	_toEdge: function(inp, def){
-		return this.EDGE[inp.toUpperCase()] || def;
-	},
-
-	_expandSlowly: function(){
-		// summary: slowly expand the image to user specified max size
-		if(!this.isOver){ return; }
-		this.timerScale += 0.2;
-		this._paint();
-		if(this.timerScale<1.0){
-			setTimeout(dojo.hitch(this, "_expandSlowly"), 10);
-		}
-	},
-
-	destroyRecursive: function(){
-		// need to disconnect when we destroy
-		dojo.disconnect(this._onMouseOutHandle);
-		dojo.disconnect(this._onMouseMoveHandle);
-		dojo.disconnect(this._addChildHandle);
-		if(this.isFixed){ dojo.disconnect(this._onScrollHandle); }
-		dojo.disconnect(this._onResizeHandle);
-		this.inherited("destroyRecursive",arguments);
-	}
-});
-
-dojo.declare("dojox.widget.FisheyeListItem", [dijit._Widget, dijit._Templated, dijit._Contained], {
-	/*
-	 * summary
-	 *	Menu item inside of a FisheyeList.
-	 *	See FisheyeList documentation for details on usage.
-	 */
-
-	// iconSrc: String
-	//	pathname to image file (jpg, gif, png, etc.) of icon for this menu item
-	iconSrc: "",
-
-	// label: String
-	//	label to print next to the icon, when it is moused-over
-	label: "",
-
-	// id: String
-	//	will be set to the id of the orginal div element
-	id: "",
-
-	templateString:
-		'<div class="dojoxFisheyeListItem">' +
-		'  <img class="dojoxFisheyeListItemImage" dojoAttachPoint="imgNode" dojoAttachEvent="onmouseover:onMouseOver,onmouseout:onMouseOut,onclick:onClick">' +
-		'  <div class="dojoxFisheyeListItemLabel" dojoAttachPoint="lblNode"></div>' +
-		'</div>',
-
-	_isNode: function(/* object */wh){
-		//	summary:
-		//		checks to see if wh is actually a node.
-		if(typeof Element == "function"){
-			try{
-				return wh instanceof Element;	//	boolean
-			}catch(e){}
-		}else{
-			// best-guess
-			return wh && !isNaN(wh.nodeType);	//	boolean
-		}
-		return false;
-	},
-
-	_hasParent: function(/*Node*/node){
-		//	summary:
-		//		returns whether or not node is a child of another node.
-		return Boolean(node && node.parentNode && this._isNode(node.parentNode));	//	boolean
-	},
-
-	postCreate: function(){
-
-		// set image
-		var parent;
-		if((this.iconSrc.toLowerCase().substring(this.iconSrc.length-4)==".png") && dojo.isIE < 7){
-			/* we set the id of the new fisheyeListItem to the id of the div defined in the HTML */
-			if(this._hasParent(this.imgNode) && this.id != ""){
-				parent = this.imgNode.parentNode;
-				parent.setAttribute("id", this.id);
-			}
-			this.imgNode.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.iconSrc+"', sizingMethod='scale')";
-			this.imgNode.src = this._blankGif.toString();
-		}else{
-			if(this._hasParent(this.imgNode) && this.id != ""){
-				parent = this.imgNode.parentNode;
-				parent.setAttribute("id", this.id);
-			}
-			this.imgNode.src = this.iconSrc;
-		}
-
-		// Label
-		if(this.lblNode){
-			this.lblNode.appendChild(document.createTextNode(this.label));
-		}
-		dojo.setSelectable(this.domNode, false);
-		this.startup();
-	},
-
-	startup: function(){
-		this.parent = this.getParent();
-	},
-	
-	onMouseOver: function(/*Event*/ e){
-		// summary: callback when user moves mouse over this menu item
-		// in conservative mode, don't activate the menu until user mouses over an icon
-		if(!this.parent.isOver){
-			this.parent._setActive(e);
-		}
-		if(this.label != "" ){
-			dojo.addClass(this.lblNode, "dojoxFishSelected");
-			this.parent._positionLabel(this);
-		}
-	},
-	
-	onMouseOut: function(/*Event*/ e){
-		// summary: callback when user moves mouse off of this menu item
-		dojo.removeClass(this.lblNode, "dojoxFishSelected");
-	},
-
-	onClick: function(/*Event*/ e){
-		// summary: user overridable callback when user clicks this menu item
-	}
-});
+define(["dojo/_base/declare", "dojo/_base/sniff", "dojo/_base/lang", "dojo/aspect", "dojo/dom", "dojo/dom-attr", "dojo/dom-class", "dojo/dom-geometry", "dojo/dom-style", "dojo/dom-construct", "dojo/on", "dojo/_base/window", "dojo/mouse", "dijit/_WidgetBase", "dijit/_TemplatedMixin", "dijit/_Container", "./FisheyeListItem"],
+	function(declare, has, lang, aspect, dom, attr, domClass, geometry, style, construct, on, winUtil, mouse, _WidgetBase, _TemplatedMixin, _Container, FisheyeListItem){
+
+		return declare("dojox.widget.FisheyeList",
+			[_WidgetBase, _TemplatedMixin, _Container], {
+				// summary:
+				//		Menu similar to the fish eye menu on the Mac OS
+				// example:
+				// |	<div dojoType="dojo.widget.FisheyeList"
+				// |		itemWidth="40" itemHeight="40"
+				// |		itemMaxWidth="150" itemMaxHeight="150"
+				// |		orientation="horizontal"
+				// |		effectUnits="2"
+				// |		itemPadding="10"
+				// |		attachEdge="center"
+				// |		labelEdge="bottom">
+				// |
+				// |		<div dojoType="dojox.widget.FisheyeListItem"
+				// |			id="item1"
+				// |			onclick="alert('click on' + this.label + '(from widget id ' + this.widgetId + ')!');"
+				// |			label="Item 1"
+				// |			iconSrc="images/fisheye_1.png">
+				// |		</div>
+				// |		...
+				// |	</div>
+
+				constructor: function(){
+					//
+					// TODO
+					// fix really long labels in vertical mode
+					//
+
+					this.pos = {'x': -1, 'y': -1};	// current cursor position, relative to the grid
+
+					// for conservative trigger mode, when triggered, timerScale is gradually increased from 0 to 1
+					this.timerScale = 1.0;
+				},
+
+				EDGE: {
+					CENTER: 0,
+					LEFT: 1,
+					RIGHT: 2,
+					TOP: 3,
+					BOTTOM: 4
+				},
+
+				templateString: '<div class="dojoxFisheyeListBar" data-dojo-attach-point="containerNode"></div>',
+
+				snarfChildDomOutput: true,
+
+				// itemWidth: Integer
+				//		width of menu item (in pixels) in it's dormant state (when the mouse is far away)
+				itemWidth: 40,
+
+				// itemHeight: Integer
+				//		height of menu item (in pixels) in it's dormant state (when the mouse is far away)
+				itemHeight: 40,
+
+				// itemMaxWidth: Integer
+				//		width of menu item (in pixels) in it's fully enlarged state (when the mouse is directly over it)
+				itemMaxWidth: 150,
+
+				// itemMaxHeight: Integer
+				//		height of menu item (in pixels) in it's fully enlarged state (when the mouse is directly over it)
+				itemMaxHeight: 150,
+
+				imgNode: null,
+
+				// orientation: String
+				//		orientation of the menu, either "horizontal" or "vertical"
+				orientation: 'horizontal',
+
+				// isFixed: Boolean
+				//		toggle to enable additional listener (window scroll) if FisheyeList is in a fixed postion
+				isFixed: false,
+
+				// conservativeTrigger: Boolean
+				//		if true, don't start enlarging menu items until mouse is over an image;
+				//		if false, start enlarging menu items as the mouse moves near them.
+				conservativeTrigger: false,
+
+				// effectUnits: Number
+				//		controls how much reaction the menu makes, relative to the distance of the mouse from the menu
+				effectUnits: 2,
+
+				// itemPadding: Integer
+				//		padding (in pixels) between each menu item
+				itemPadding: 10,
+
+				// attachEdge: String
+				//		Controls the border that the menu items don't expand past;
+				//		for example, if set to "top", then the menu items will drop downwards as they expand.
+				//		Values: "center", "left", "right", "top", "bottom".
+				attachEdge: 'center',
+
+				// labelEdge: String
+				//		Controls were the labels show up in relation to the menu item icons.
+				//		Values: "center", "left", "right", "top", "bottom".
+				labelEdge: 'bottom',
+
+				postCreate: function(){
+					var e = this.EDGE,
+						isHorizontal = this.isHorizontal = (this.orientation == 'horizontal');
+
+					dom.setSelectable(this.domNode, false);
+
+					this.selectedNode = -1;
+
+					this.isOver = false;
+					this.hitX1 = -1;
+					this.hitY1 = -1;
+					this.hitX2 = -1;
+					this.hitY2 = -1;
+
+					//
+					// only some edges make sense...
+					//
+					this.anchorEdge = this._toEdge(this.attachEdge, e.CENTER);
+					this.labelEdge  = this._toEdge(this.labelEdge,  e.TOP);
+
+					if(this.labelEdge == e.CENTER){ this.labelEdge = e.TOP; }
+
+					if(isHorizontal){
+						if(this.anchorEdge == e.LEFT){ this.anchorEdge = e.CENTER; }
+						if(this.anchorEdge == e.RIGHT){ this.anchorEdge = e.CENTER; }
+						if(this.labelEdge == e.LEFT){ this.labelEdge = e.TOP; }
+						if(this.labelEdge == e.RIGHT){ this.labelEdge = e.TOP; }
+					}else{
+						if(this.anchorEdge == e.TOP){ this.anchorEdge = e.CENTER; }
+						if(this.anchorEdge == e.BOTTOM){ this.anchorEdge = e.CENTER; }
+						if(this.labelEdge == e.TOP){ this.labelEdge = e.LEFT; }
+						if(this.labelEdge == e.BOTTOM){ this.labelEdge = e.LEFT; }
+					}
+
+					//
+					// figure out the proximity size
+					//
+					var effectUnits = this.effectUnits;
+					this.proximityLeft   = this.itemWidth  * (effectUnits - 0.5);
+					this.proximityRight  = this.itemWidth  * (effectUnits - 0.5);
+					this.proximityTop	= this.itemHeight * (effectUnits - 0.5);
+					this.proximityBottom = this.itemHeight * (effectUnits - 0.5);
+
+					if(this.anchorEdge == e.LEFT){
+						this.proximityLeft = 0;
+					}
+					if(this.anchorEdge == e.RIGHT){
+						this.proximityRight = 0;
+					}
+					if(this.anchorEdge == e.TOP){
+						this.proximityTop = 0;
+					}
+					if(this.anchorEdge == e.BOTTOM){
+						this.proximityBottom = 0;
+					}
+					if(this.anchorEdge == e.CENTER){
+						this.proximityLeft   /= 2;
+						this.proximityRight  /= 2;
+						this.proximityTop	/= 2;
+						this.proximityBottom /= 2;
+					}
+				},
+
+				startup: function(){
+					// summary:
+					//		create our connections and setup our FisheyeList
+					this.children = this.getChildren();
+					//original postCreate() --tk
+					this._initializePositioning();
+
+					//
+					// in liberal trigger mode, activate menu whenever mouse is close, in conservative mode, pause until needed
+					//
+					this._onMouseMoveHandle = on.pausable(winUtil.doc.documentElement, "mousemove", lang.hitch(this, "_onMouseMove"));
+					if(this.conservativeTrigger){
+						this._onMouseMoveHandle.pause();
+					}
+					if(this.isFixed){
+						this.own(on(winUtil.doc,"scroll", lang.hitch(this, this._onScroll)));
+					}
+
+					// Deactivate the menu if mouse is moved off screen (doesn't work for FF?)
+					this.own(
+						on(winUtil.doc.documentElement, mouse.leave, lang.hitch(this, "_onBodyOut")),
+						aspect.after(this, "addChild", lang.hitch(this, "_initializePositioning"), true),
+						aspect.after(winUtil.global, "onresize", lang.hitch(this, "_initializePositioning"), true)
+					);
+				},
+
+				_initializePositioning: function(){
+					this.itemCount = this.children.length;
+
+					this.barWidth  = (this.isHorizontal ? this.itemCount : 1) * this.itemWidth;
+					this.barHeight = (this.isHorizontal ? 1 : this.itemCount) * this.itemHeight;
+
+					this.totalWidth  = this.proximityLeft + this.proximityRight  + this.barWidth;
+					this.totalHeight = this.proximityTop  + this.proximityBottom + this.barHeight;
+
+					//
+					// calculate effect ranges for each item
+					//
+
+					for(var i=0; i<this.children.length; i++){
+
+						this.children[i].posX = this.itemWidth  * (this.isHorizontal ? i : 0);
+						this.children[i].posY = this.itemHeight * (this.isHorizontal ? 0 : i);
+
+						this.children[i].cenX = this.children[i].posX + (this.itemWidth  / 2);
+						this.children[i].cenY = this.children[i].posY + (this.itemHeight / 2);
+
+						var isz = this.isHorizontal ? this.itemWidth : this.itemHeight,
+							r = this.effectUnits * isz,
+							c = this.isHorizontal ? this.children[i].cenX : this.children[i].cenY,
+							lhs = this.isHorizontal ? this.proximityLeft : this.proximityTop,
+							rhs = this.isHorizontal ? this.proximityRight : this.proximityBottom,
+							siz = this.isHorizontal ? this.barWidth : this.barHeight,
+
+							range_lhs = r,
+							range_rhs = r;
+
+						if(range_lhs > c+lhs){ range_lhs = c+lhs; }
+						if(range_rhs > (siz-c+rhs)){ range_rhs = siz-c+rhs; }
+
+						this.children[i].effectRangeLeft = range_lhs / isz;
+						this.children[i].effectRangeRght = range_rhs / isz;
+
+						//dojo.debug('effect range for '+i+' is '+range_lhs+'/'+range_rhs);
+					}
+
+					//
+					// create the bar
+					//
+					style.set(this.domNode, {width: this.barWidth + 'px', height: this.barHeight + 'px'});
+
+					//
+					// position the items
+					//
+					for(i=0; i<this.children.length; i++){
+						var itm = this.children[i];
+						var elm = itm.domNode;
+						style.set(elm, {left: itm.posX + 'px', top: itm.posY + 'px', width: this.itemWidth + 'px', height: this.itemHeight + 'px'});
+
+						style.set(itm.imgNode, {left: this.itemPadding+'%', top: this.itemPadding+'%', width: (100 - 2 * this.itemPadding) + '%', height: (100 - 2 * this.itemPadding) + '%'});
+					}
+					//
+					// calc the grid
+					//
+					this._calcHitGrid();
+				},
+
+				_overElement: function(/* DomNode|String */ node, /* Event */ e){
+					// summary:
+					//		Returns whether the mouse is over the passed element.
+					// node:
+					//		Must must be display:block (ie, not a `<span>`)
+					node = dom.byId(node);
+					var mouse = {x: e.pageX, y: e.pageY},
+						absolute = geometry.position(node, true),
+						top = absolute.y,
+						bottom = top + absolute.h,
+						left = absolute.x,
+						right = left + absolute.w;
+
+					return (mouse.x >= left
+						&& mouse.x <= right
+						&& mouse.y >= top
+						&& mouse.y <= bottom
+						);	// Boolean
+				},
+
+				_onBodyOut: function(/*Event*/ e){
+					// clicking over an object inside of body causes this event to fire; ignore that case
+					if( this._overElement(winUtil.body(), e) ){
+						return;
+					}
+					this._setDormant(e);
+				},
+
+				_setDormant: function(/*Event*/ e){
+					// summary:
+					//		called when mouse moves out of menu's range
+
+					if(!this.isOver){ return; }	// already dormant?
+					this.isOver = false;
+
+					if(this.conservativeTrigger){
+						// user can't re-trigger the menu expansion
+						// until he mouses over a icon again
+						this._onMouseMoveHandle.pause();
+					}
+					this._onGridMouseMove(-1, -1);
+				},
+
+				_setActive: function(/*Event*/ e){
+					// summary:
+					//		called when mouse is moved into menu's range
+
+					if(this.isOver){ return; }	// already activated?
+					this.isOver = true;
+
+					if(this.conservativeTrigger){
+						// switch event handlers so that we handle mouse events from anywhere near
+						// the menu
+						this._onMouseMoveHandle.resume();
+
+						this.timerScale=0.0;
+
+						// call mouse handler to do some initial necessary calculations/positioning
+						this._onMouseMove(e);
+
+						// slowly expand the icon size so it isn't jumpy
+						this._expandSlowly();
+					}
+				},
+
+				_onMouseMove: function(/*Event*/ e){
+					// summary:
+					//		called when mouse is moved
+					if(	(e.pageX >= this.hitX1) && (e.pageX <= this.hitX2) &&
+						(e.pageY >= this.hitY1) && (e.pageY <= this.hitY2)	){
+						if(!this.isOver){
+							this._setActive(e);
+						}
+						this._onGridMouseMove(e.pageX-this.hitX1, e.pageY-this.hitY1);
+					}else{
+						if(this.isOver){
+							this._setDormant(e);
+						}
+					}
+				},
+
+				_onScroll: function(){
+					this._calcHitGrid();
+				},
+
+				onResized: function(){
+					this._calcHitGrid();
+				},
+
+				_onGridMouseMove: function(x, y){
+					// summary:
+					//		called when mouse is moved in the vicinity of the menu
+					this.pos = {x:x, y:y};
+					this._paint();
+				},
+
+				_paint: function(){
+					var x=this.pos.x;
+					var y=this.pos.y;
+
+					if(this.itemCount <= 0){ return; }
+
+					//
+					// figure out our main index
+					//
+					var pos = this.isHorizontal ? x : y,
+						prx = this.isHorizontal ? this.proximityLeft : this.proximityTop,
+						siz = this.isHorizontal ? this.itemWidth : this.itemHeight,
+						sim = this.isHorizontal ?
+							(1.0-this.timerScale)*this.itemWidth + this.timerScale*this.itemMaxWidth :
+							(1.0-this.timerScale)*this.itemHeight + this.timerScale*this.itemMaxHeight,
+
+						cen = ((pos - prx) / siz) - 0.5,
+						max_off_cen = (sim / siz) - 0.5;
+
+					if(max_off_cen > this.effectUnits){ max_off_cen = this.effectUnits; }
+
+					//
+					// figure out our off-axis weighting
+					//
+					var off_weight = 0, cen2;
+
+					if(this.anchorEdge == this.EDGE.BOTTOM){
+						cen2 = (y - this.proximityTop) / this.itemHeight;
+						off_weight = (cen2 > 0.5) ? 1 : y / (this.proximityTop + (this.itemHeight / 2));
+					}
+					if(this.anchorEdge == this.EDGE.TOP){
+						cen2 = (y - this.proximityTop) / this.itemHeight;
+						off_weight = (cen2 < 0.5) ? 1 : (this.totalHeight - y) / (this.proximityBottom + (this.itemHeight / 2));
+					}
+					if(this.anchorEdge == this.EDGE.RIGHT){
+						cen2 = (x - this.proximityLeft) / this.itemWidth;
+						off_weight = (cen2 > 0.5) ? 1 : x / (this.proximityLeft + (this.itemWidth / 2));
+					}
+					if(this.anchorEdge == this.EDGE.LEFT){
+						cen2 = (x - this.proximityLeft) / this.itemWidth;
+						off_weight = (cen2 < 0.5) ? 1 : (this.totalWidth - x) / (this.proximityRight + (this.itemWidth / 2));
+					}
+					if(this.anchorEdge == this.EDGE.CENTER){
+						if(this.isHorizontal){
+							off_weight = y / (this.totalHeight);
+						}else{
+							off_weight = x / (this.totalWidth);
+						}
+
+						if(off_weight > 0.5){
+							off_weight = 1 - off_weight;
+						}
+
+						off_weight *= 2;
+					}
+
+					//
+					// set the sizes
+					//
+					for(var i=0; i<this.itemCount; i++){
+						var weight = this._weighAt(cen, i);
+						if(weight < 0){weight = 0;}
+						this._setItemSize(i, weight * off_weight);
+					}
+
+					//
+					// set the positions
+					//
+
+					var main_p = Math.round(cen),
+						offset = 0;
+
+					if(cen < 0){
+
+						main_p = 0;
+
+					}else if(cen > this.itemCount - 1){
+
+						main_p = this.itemCount -1;
+
+					}else{
+
+						offset = (cen - main_p) * ((this.isHorizontal ? this.itemWidth : this.itemHeight) - this.children[main_p].sizeMain);
+					}
+
+					this._positionElementsFrom(main_p, offset);
+				},
+
+				_weighAt: function(/*Integer*/ cen, /*Integer*/ i){
+					var dist = Math.abs(cen - i),
+						limit = ((cen - i) > 0) ? this.children[i].effectRangeRght : this.children[i].effectRangeLeft;
+
+					return (dist > limit) ? 0 : (1 - dist / limit); // Integer
+				},
+
+				_setItemSize: function(p, scale){
+					if(this.children[p].scale == scale){ return; }
+					this.children[p].scale = scale;
+
+					scale *= this.timerScale;
+					var w = Math.round(this.itemWidth  + ((this.itemMaxWidth  - this.itemWidth ) * scale)),
+						h = Math.round(this.itemHeight + ((this.itemMaxHeight - this.itemHeight) * scale));
+
+					if(this.isHorizontal){
+
+						this.children[p].sizeW = w;
+						this.children[p].sizeH = h;
+
+						this.children[p].sizeMain = w;
+						this.children[p].sizeOff  = h;
+
+						var y = 0;
+						if(this.anchorEdge == this.EDGE.TOP){
+							y = (this.children[p].cenY - (this.itemHeight / 2));
+						}else if(this.anchorEdge == this.EDGE.BOTTOM){
+							y = (this.children[p].cenY - (h - (this.itemHeight / 2)));
+						}else{
+							y = (this.children[p].cenY - (h / 2));
+						}
+
+						this.children[p].usualX = Math.round(this.children[p].cenX - (w / 2));
+						style.set(this.children[p].domNode, {top: y + 'px', left: this.children[p].usualX + 'px'});
+
+					}else{
+
+						this.children[p].sizeW = w;
+						this.children[p].sizeH = h;
+
+						this.children[p].sizeOff  = w;
+						this.children[p].sizeMain = h;
+
+						var x = 0;
+						if(this.anchorEdge == this.EDGE.LEFT){
+							x = this.children[p].cenX - (this.itemWidth / 2);
+						}else if(this.anchorEdge == this.EDGE.RIGHT){
+							x = this.children[p].cenX - (w - (this.itemWidth / 2));
+						}else{
+							x = this.children[p].cenX - (w / 2);
+						}
+
+						this.children[p].usualY = Math.round(this.children[p].cenY - (h / 2));
+						style.set(this.children[p].domNode, {left: x + 'px', top: this.children[p].usualY + 'px'});
+					}
+
+					style.set(this.children[p].domNode, {width: w + 'px', height: h + 'px'});
+
+					if(this.children[p].svgNode){
+						this.children[p].svgNode.setSize(w, h);
+					}
+				},
+
+				_positionElementsFrom: function(p, offset){
+					var pos = 0;
+
+					var usual, start;
+					if(this.isHorizontal){
+						usual = "usualX";
+						start = "left";
+					}else{
+						usual = "usualY";
+						start = "top";
+					}
+					pos = Math.round(this.children[p][usual] + offset);
+					if(style.get(this.children[p].domNode, start) != (pos + 'px')){
+						style.set(this.children[p].domNode, start, pos + 'px');
+						this._positionLabel(this.children[p]);
+					}
+
+					// position before
+					var bpos = pos;
+					for(var i=p-1; i>=0; i--){
+						bpos -= this.children[i].sizeMain;
+
+						if(style.get(this.children[p].domNode, start) != (bpos + 'px')){
+							style.set(this.children[i].domNode, start, bpos + 'px');
+							this._positionLabel(this.children[i]);
+						}
+					}
+
+					// position after
+					var apos = pos;
+					for(i=p+1; i<this.itemCount; i++){
+						apos += this.children[i-1].sizeMain;
+						if(style.get(this.children[p].domNode, start) != (apos + 'px')){
+							style.set(this.children[i].domNode, start, apos + 'px');
+							this._positionLabel(this.children[i]);
+						}
+					}
+
+				},
+
+				_positionLabel: function(itm){
+					var x = 0;
+					var y = 0;
+
+					var mb = geometry.getMarginBox(itm.lblNode);
+
+					if(this.labelEdge == this.EDGE.TOP){
+						x = Math.round((itm.sizeW / 2) - (mb.w / 2));
+						y = -mb.h;
+					}
+
+					if(this.labelEdge == this.EDGE.BOTTOM){
+						x = Math.round((itm.sizeW / 2) - (mb.w / 2));
+						y = itm.sizeH;
+					}
+
+					if(this.labelEdge == this.EDGE.LEFT){
+						x = -mb.w;
+						y = Math.round((itm.sizeH / 2) - (mb.h / 2));
+					}
+
+					if(this.labelEdge == this.EDGE.RIGHT){
+						x = itm.sizeW;
+						y = Math.round((itm.sizeH / 2) - (mb.h / 2));
+					}
+
+					style.set(itm.lblNode, {left: x + 'px', top: y + 'px'});
+				},
+
+				_calcHitGrid: function(){
+
+					var pos = geometry.position(this.domNode, true);
+
+					this.hitX1 = pos.x - this.proximityLeft;
+					this.hitY1 = pos.y - this.proximityTop;
+					this.hitX2 = this.hitX1 + this.totalWidth;
+					this.hitY2 = this.hitY1 + this.totalHeight;
+
+				},
+
+				_toEdge: function(inp, def){
+					return this.EDGE[inp.toUpperCase()] || def;
+				},
+
+				_expandSlowly: function(){
+					// summary:
+					//		slowly expand the image to user specified max size
+					if(!this.isOver){ return; }
+					this.timerScale += 0.2;
+					this._paint();
+					if(this.timerScale<1.0){
+						setTimeout(lang.hitch(this, "_expandSlowly"), 10);
+					}
+				}
+			});
+
+	});
diff --git a/dojox/widget/FisheyeListItem.js b/dojox/widget/FisheyeListItem.js
new file mode 100644
index 0000000..f43a413
--- /dev/null
+++ b/dojox/widget/FisheyeListItem.js
@@ -0,0 +1,104 @@
+define(["dojo/_base/declare", "dojo/_base/sniff", "dojo/dom", "dojo/dom-attr", "dojo/dom-class", "dojo/dom-style", "dojo/dom-construct", "dojo/_base/window", "dijit/_WidgetBase", "dijit/_TemplatedMixin", "dijit/_Contained"],
+	function(declare, has, dom, attr, domClass, style, construct, winUtil, _WidgetBase, _TemplatedMixin, _Contained){
+
+	return declare("dojox.widget.FisheyeListItem",
+		[_WidgetBase, _TemplatedMixin, _Contained], {
+		// summary:
+		//		Menu item inside of a FisheyeList.
+		//		See FisheyeList documentation for details on usage.
+
+		// iconSrc: String
+		//		pathname to image file (jpg, gif, png, etc.) of icon for this menu item
+		iconSrc: "",
+
+		// label: String
+		//		label to print next to the icon, when it is moused-over
+		label: "",
+
+		// id: String
+		//		will be set to the id of the orginal div element
+		id: "",
+
+		templateString:
+			'<div class="dojoxFisheyeListItem">' +
+			'  <img class="dojoxFisheyeListItemImage" data-dojo-attach-point="imgNode" data-dojo-attach-event="onmouseover:onMouseOver,onmouseout:onMouseOut,onclick:onClick">' +
+			'  <div class="dojoxFisheyeListItemLabel" data-dojo-attach-point="lblNode"></div>' +
+			'</div>',
+
+		_isNode: function(/* object */wh){
+			// summary:
+			//		checks to see if wh is actually a node.
+			if(typeof Element == "function"){
+				try{
+					return wh instanceof Element;   // Boolean
+				}catch(e){}
+			}else{
+				// best-guess
+				return wh && !isNaN(wh.nodeType);   // Boolean
+			}
+			return false;
+		},
+
+		_hasParent: function(/*Node*/ node){
+			// summary:
+			//		returns whether or not node is a child of another node.
+			return Boolean(node && node.parentNode && this._isNode(node.parentNode));   // Boolean
+		},
+
+		postCreate: function(){
+
+			// set image
+			var parent;
+			if((this.iconSrc.toLowerCase().substring(this.iconSrc.length-4)==".png") && has("ie") < 7){
+				/* we set the id of the new fisheyeListItem to the id of the div defined in the HTML */
+				if(this._hasParent(this.imgNode) && this.id != ""){
+					parent = this.imgNode.parentNode;
+					attr.set(parent, "id", this.id);
+				}
+				style.set(this.imgNode, "filter", "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.iconSrc+"', sizingMethod='scale')");
+				this.imgNode.src = this._blankGif.toString();
+			}else{
+				if(this._hasParent(this.imgNode) && this.id != ""){
+					parent = this.imgNode.parentNode;
+					attr.set(parent, "id", this.id);
+				}
+				this.imgNode.src = this.iconSrc;
+			}
+
+			// Label
+			if(this.lblNode){
+				construct.place(winUtil.doc.createTextNode(this.label), this.lblNode);
+			}
+			dom.setSelectable(this.domNode, false);
+			this.startup();
+		},
+
+		startup: function(){
+			this.parent = this.getParent();
+		},
+
+		onMouseOver: function(/*Event*/ e){
+			// summary:
+			//		callback when user moves mouse over this menu item
+			//		in conservative mode, don't activate the menu until user mouses over an icon
+			if(!this.parent.isOver){
+				this.parent._setActive(e);
+			}
+			if(this.label != "" ){
+				domClass.add(this.lblNode, "dojoxFishSelected");
+				this.parent._positionLabel(this);
+			}
+		},
+
+		onMouseOut: function(/*Event*/ e){
+			// summary:
+			//		callback when user moves mouse off of this menu item
+			domClass.remove(this.lblNode, "dojoxFishSelected");
+		},
+
+		onClick: function(/*Event*/ e){
+			// summary:
+			//		user overridable callback when user clicks this menu item
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/widget/FisheyeLite.js b/dojox/widget/FisheyeLite.js
index 78e635e..a482812 100644
--- a/dojox/widget/FisheyeLite.js
+++ b/dojox/widget/FisheyeLite.js
@@ -1,18 +1,27 @@
-define(["dojo", "dojox", "dijit/_Widget", "dojo/fx/easing"], function(dojo, dojox, widget, easing){
+define([
+	"dojo/_base/kernel",
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/on",
+	"dojo/query",
+	"dojo/dom-style",
+	"dojo/_base/fx",
+	"dijit/_WidgetBase",
+	"dojo/fx/easing"
 	
-	dojo.getObject("widget", true, dojox);
-	dojo.experimental("dojox.widget.FisheyeLite");
-
-	return dojo.declare("dojox.widget.FisheyeLite",
-		dijit._Widget,
-		{
-		// summary:  A Light-weight Fisheye Component, or an exhanced version
-		//		of dojo.fx.Toggler ...
-		//
+], function(kernel, declare, lang, on, query, domStyle, fx, _WidgetBase, easing){
+	
+	lang.getObject("widget", true, dojox);
+	kernel.experimental("dojox/widget/FisheyeLite");
+
+	return dojo.declare("dojox.widget.FisheyeLite", [_WidgetBase], {
+		// summary:
+		//		A Light-weight Fisheye Component, or an exhanced version
+		//		of dojo/fx/Toggler ...
 		// description:
 		//		A Simple FisheyeList-like widget which (in the interest of
 		//		performance) relies on well-styled content for positioning,
-		// 		and natural page layout for rendering.
+		//		and natural page layout for rendering.
 		//
 		//		use position:absolute/relative nodes to prevent layout
 		//		changes, and use caution when seleting properties to
@@ -26,20 +35,25 @@ define(["dojo", "dojox", "dijit/_Widget", "dojo/fx/easing"], function(dojo, dojo
 		//
 		// example:
 		//	|	// make all the LI's in a node Fisheye's:
-		//	|   dojo.query("#node li").forEach(function(n){
-		// 	|		new dojox.widget.FisheyeLite({},n);
+		//	|	require(["dojo/query", "dojox/widget/FisheyeLite"],
+		//	|		function(query, FisheyeLite){
+		//	|   	query("#node li").forEach(function(n){
+		// 	|			new FisheyeLite({},n);
+		//	|		});
 		//	|	});
 		//
 		//
 		// example:
-		//	|	new dojox.widget.FisheyeLite({
-		//	|		properties:{
-		//	|			// height is literal, width is multiplied
-		//	|			height:{ end: 200 }, width:2.3
-		//	|		}
-		//	|	}, "someNode");
-		//
-		// duationIn: Integer
+		//	|	require(["dojox/widget/FisheyeLite"], function(FisheyeLite){
+		//	|		new FisheyeLite({
+		//	|			properties:{
+		//	|				// height is literal, width is multiplied
+		//	|				height:{ end: 200 }, width:2.3
+		//	|			}
+		//	|		}, "someNode");
+		//	|	});
+		
+		// durationIn: Integer
 		//		The time (in ms) the run the show animation
 		durationIn: 350,
 
@@ -52,15 +66,15 @@ define(["dojo", "dojox", "dijit/_Widget", "dojo/fx/easing"], function(dojo, dojo
 		durationOut: 1420,
 
 		// easeOut: Function
-		// 		An easing function to use for the hide animation
+		//		An easing function to use for the hide animation
 		easeOut: easing.elasticOut,
 
-		//	properties: Object
-		//			An object of "property":scale pairs, or "property":{} pairs.
-		//			defaults to font-size with a scale of 2.75
-		//			If a named property is an integer or float, the "scale multiplier"
-		//			is used. If the named property is an object, that object is mixed
-		//			into the animation directly. eg: height:{ end:20, units:"em" }
+		// properties: Object
+		//		An object of "property":scale pairs, or "property":{} pairs.
+		//		defaults to font-size with a scale of 2.75
+		//		If a named property is an integer or float, the "scale multiplier"
+		//		is used. If the named property is an object, that object is mixed
+		//		into the animation directly. eg: height:{ end:20, units:"em" }
 		properties: null,
 
 		// units: String
@@ -77,7 +91,7 @@ define(["dojo", "dojox", "dijit/_Widget", "dojo/fx/easing"], function(dojo, dojo
 		postCreate: function(){
 
 			this.inherited(arguments);
-			this._target = dojo.query(".fisheyeTarget", this.domNode)[0] || this.domNode;
+			this._target = query(".fisheyeTarget", this.domNode)[0] || this.domNode;
 			this._makeAnims();
 
 			this.connect(this.domNode, "onmouseover", "show");
@@ -105,46 +119,48 @@ define(["dojo", "dojox", "dijit/_Widget", "dojo/fx/easing"], function(dojo, dojo
 			//		Pre-generate the animations
 
 			// create two properties: objects, one for each "state"
-			var _in = {}, _out = {}, cs = dojo.getComputedStyle(this._target);
+			var _in = {}, _out = {}, cs = domStyle.getComputedStyle(this._target);
 			for(var p in this.properties){
 				var prop = this.properties[p],
-					deep = dojo.isObject(prop),
-					v = parseInt(cs[p])
+					deep = lang.isObject(prop),
+					v = parseFloat(cs[p])
 				;
 				// note: do not set negative scale for [a list of properties] for IE support
 				// note: filter:'s are your own issue, too ;)
-				// FIXME: this.unit here is bad, likely. d._toPixelValue ?
+				// FIXME: this.units here is bad, likely. d._toPixelValue ?
 				_out[p] = { end: v, units:this.units };
 				_in[p] = deep ? prop : { end: prop * v, units:this.units };
 			}
 
-			this._runningIn = dojo.animateProperty({
+			this._runningIn = fx.animateProperty({
 				node: this._target,
 				easing: this.easeIn,
 				duration: this.durationIn,
 				properties: _in
 			});
 
-			this._runningOut = dojo.animateProperty({
+			this._runningOut = fx.animateProperty({
 				node: this._target,
 				duration: this.durationOut,
 				easing: this.easeOut,
 				properties: _out
 			});
 
-			this.connect(this._runningIn, "onEnd", dojo.hitch(this, "onSelected", this));
+			this.connect(this._runningIn, "onEnd", lang.hitch(this, "onSelected", this));
 		},
 
 		onClick: function(/* Event */e){
-			// summary: stub function fired when target is clicked
+			// summary:
+			//		stub function fired when target is clicked
 			//		connect or override to use.
 		},
 
 		onSelected: function(/* Object */e){
-			// summary: stub function fired when Fisheye Item is fully visible and
-			// 		hovered. connect or override use.
+			// summary:
+			//		stub function fired when Fisheye Item is fully visible and
+			//		hovered. connect or override use.
 		}
 
 	});
 	
-});
\ No newline at end of file
+});
diff --git a/dojox/widget/Loader.js b/dojox/widget/Loader.js
index 04a5ca6..31b11bc 100644
--- a/dojox/widget/Loader.js
+++ b/dojox/widget/Loader.js
@@ -5,33 +5,34 @@ dojo.require("dijit._Widget");
 dojo.require("dijit._Templated");
 
 dojo.declare("dojox.widget.Loader", [dijit._Widget,dijit._Templated], {
-	// summary: a configurable global xhr-listener to display
-	// a loading message during running xhr's or to simply provide
-	// base-level topic to subscribe to for custom loading messages
-	//
+	// summary:
+	//		a configurable global xhr-listener to display
+	//		a loading message during running xhr's or to simply provide
+	//		base-level topic to subscribe to for custom loading messages
+
 	// loadIcon: String
-	// 	location to the icon used.
+	// 		location to the icon used.
 	loadIcon: dojo.moduleUrl("dojox.widget.Loader","icons/loading.gif"),
 
 	// loadMessage: String
-	//	string to use for progress loading
+	//		string to use for progress loading
 	loadMessage: 'Loading ...',
 
 	// hasVisuals: Boolean
-	// 	true to display a fixed loading message in TR cornder, false to unly provide
-	//	"Loader" topic to subscribe to for your own custom loading message.
+	//		true to display a fixed loading message in TR cornder, false to unly provide
+	//		"Loader" topic to subscribe to for your own custom loading message.
 	hasVisuals: true,
 
 	// attachToPointer
-	// 	true to use visual indicator where cursor is
+	//		true to use visual indicator where cursor is
 	attachToPointer: true,
 
 	// duration: Integer
-	//	time in ms to toggle in/out the visual load indicator
+	//		time in ms to toggle in/out the visual load indicator
 	duration: 125,
 
 	// _offset: Integer
-	//	distance in px from the mouse pointer to show attachToPointer avatar
+	//		distance in px from the mouse pointer to show attachToPointer avatar
 	_offset: 16,
 
 	// holder for mousemove connection
@@ -44,7 +45,8 @@ dojo.declare("dojox.widget.Loader", [dijit._Widget,dijit._Templated], {
 		+'</div>',
 	
 	postCreate: function(){
-		// summary: setup the loader
+		// summary:
+		//		setup the loader
 
 		if(!this.hasVisuals){
 			this.loadNode.style.display = "none"; // _destroy()?
@@ -65,17 +67,20 @@ dojo.declare("dojox.widget.Loader", [dijit._Widget,dijit._Templated], {
 	},
 
 	_setMessage: function(/* String */ message){
-		// summary: set's the message in the loader
+		// summary:
+		//		set's the message in the loader
 		this.loadMessageNode.innerHTML = message;
 	},
 
 	_putLoader: function(/* Event */ e){
-		// summary: place the floating loading element based on mousemove connection position
+		// summary:
+		//		place the floating loading element based on mousemove connection position
 		dijit.placeOnScreen(this.loadNode,{ x: e.clientX+this._offset, y:e.clientY+this._offset }, ["TL","BR"]);
 	},
 
 	_show: function(){
-		// summary: publish and show progress indicator
+		// summary:
+		//		publish and show progress indicator
 		dojo.publish("Loader",[{ message: 'started' }]);
 		if(this.hasVisuals){
 			if(this.attachToPointer){
@@ -89,7 +94,8 @@ dojo.declare("dojox.widget.Loader", [dijit._Widget,dijit._Templated], {
 	},
 
 	_hide: function(){
-		// summary: publish "xhr ended" and hide progress indicator
+		// summary:
+		//		publish "xhr ended" and hide progress indicator
 		dojo.publish("Loader",[{ message: 'ended' }]);
 		if(this.hasVisuals){
 			if(this.attachToPointer){
diff --git a/dojox/widget/MonthAndYearlyCalendar.js b/dojox/widget/MonthAndYearlyCalendar.js
new file mode 100644
index 0000000..cab6f1b
--- /dev/null
+++ b/dojox/widget/MonthAndYearlyCalendar.js
@@ -0,0 +1,10 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarBase",
+	"./_CalendarMonthYear"
+], function(declare, _CalendarBase, _CalendarMonthYear){
+	return declare("dojox.widget.MonthAndYearlyCalendar", [_CalendarBase, _CalendarMonthYear], {
+		// summary:
+		//		A calendar with only a daily view.
+	});
+});
diff --git a/dojox/widget/MonthlyCalendar.js b/dojox/widget/MonthlyCalendar.js
new file mode 100644
index 0000000..e9dd51e
--- /dev/null
+++ b/dojox/widget/MonthlyCalendar.js
@@ -0,0 +1,15 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarBase",
+	"./_CalendarMonth"
+], function(declare, _CalendarBase, _CalendarMonth){
+	return declare("dojox.widget.MonthlyCalendar", [_CalendarBase, _CalendarMonth], {
+		// summary:
+		//		A calendar with only a month view.
+		_makeDate: function(value){
+			var now = new Date();
+			now.setMonth(value);
+			return now;
+		}
+	});
+});
diff --git a/dojox/widget/MultiSelectCalendar.js b/dojox/widget/MultiSelectCalendar.js
index 3718835..69af4b4 100644
--- a/dojox/widget/MultiSelectCalendar.js
+++ b/dojox/widget/MultiSelectCalendar.js
@@ -4,14 +4,18 @@ define("dojox/widget/MultiSelectCalendar", [
     "dojo/cldr/supplemental", 
     "dojo/date", 
     "dojo/date/locale", 
-    "dijit/_Widget", "dijit/_Templated", "dijit/_CssStateMixin", "dijit/form/DropDownButton", "dijit/typematic"],
-    function(dojo, dijit, template) {
+    "dijit/_Widget", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin",
+	"dijit/_CssStateMixin", "dijit/form/DropDownButton", "dijit/typematic"
+],
+    function(dojo, dijit, template, supplemental, date, locale,
+		_Widget, _TemplatedMixin, _WidgetsInTemplateMixin,
+		_CssStateMixin, DropDownButton, typematic) {
 
 dojo.experimental("dojox.widget.MultiSelectCalendar");
 
-dojo.declare(
+var MultiSelectCalendar = dojo.declare(
 	"dojox.widget.MultiSelectCalendar",
-	[dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin, dijit._CssStateMixin],
+	[_Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _CssStateMixin],
 	{
 		// summary:
 		//		A simple GUI for choosing several dates in the context of a monthly calendar.
@@ -44,7 +48,7 @@ dojo.declare(
 		//		How to represent the days of the week in the calendar header. See dojo.date.locale
 		dayWidth: "narrow",
 
-		// tabIndex: Integer
+		// tabIndex: String
 		//		Order fields are traversed when user hits the tab key
 		tabIndex: "0",
 		
@@ -81,7 +85,8 @@ dojo.declare(
 		},
 
 		_getValueAttr: function(){
-			// summary: this method returns the list of selected dates in an array structure
+			// summary:
+			//		this method returns the list of selected dates in an array structure
 			if(this.returnIsoRanges){
 				datesWithRanges = this._returnDatesWithIsoRanges(this._sort());
 				return datesWithRanges;
@@ -94,12 +99,12 @@ dojo.declare(
 			// summary:
 			//		Support set("value", ...)
 			// description:
-			// 		Set the passed dates to the selected date and updates the value of this widget
+			//		Set the passed dates to the selected date and updates the value of this widget
 			//		to reflect that
 			// value:
 			//		Can be a Date, the number of milliseconds since 1970 or an array of ISO dates (['2011-07-01', '2001-06-01']).
 			// tags:
-			//      protected
+			//		protected
 			
 			//If we are passed an array of ISO dates, we are going to mark each date in the list as selected
 			//We perform the normalization of the passed date
@@ -113,8 +118,8 @@ dojo.declare(
 						this.value[element] = 1;
 					}else{
 						//We have a slash somewhere in the string so this is an ISO date range
-						var dateA=new dojo.date.stamp.fromISOString(element.substr(0,10));
-						var dateB=new dojo.date.stamp.fromISOString(element.substr(11,10));
+						var dateA = dojo.date.stamp.fromISOString(element.substr(0,10));
+						var dateB = dojo.date.stamp.fromISOString(element.substr(11,10));
 						
 						this.toggleDate(dateA,[],[]);
 						if((dateA - dateB) > 0){
@@ -190,7 +195,7 @@ dojo.declare(
 			//		This just sets the content of node to the specified text.
 			//		Can't do "node.innerHTML=text" because of an IE bug w/tables, see #3434.
 			// tags:
-			//      private
+			//		private
 			while(node.firstChild){
 				node.removeChild(node.firstChild);
 			}
@@ -199,9 +204,9 @@ dojo.declare(
 
 		_populateGrid: function(){
 			// summary:
-			//      Fills in the calendar grid with each day (1-31)
+			//		Fills in the calendar grid with each day (1-31)
 			// tags:
-			//      private
+			//		private
 
 			var month = new this.dateClassObj(this.currentFocus);
 			month.setDate(1);
@@ -304,7 +309,7 @@ dojo.declare(
 
 		goToToday: function(){
 			// summary:
-			//      We go to today but we do no select it
+			//		We go to today but we do no select it
 			this.set('currentFocus', new this.dateClassObj(), false);
 		},
 
@@ -343,7 +348,7 @@ dojo.declare(
 
 			var dateObj = new this.dateClassObj(this.currentFocus);
 
-			this.monthDropDownButton.dropDown = new dojox.widget._MonthDropDown({
+			this.monthDropDownButton.dropDown = new MonthDropDown({
 				id: this.id + "_mdd",
 				onChange: dojo.hitch(this, "_onMonthSelect")
 			});
@@ -367,13 +372,13 @@ dojo.declare(
 
 		_adjustDisplay: function(/*String*/ part, /*int*/ amount){
 			// summary:
-			//      Moves calendar forwards or backwards by months or years
+			//		Moves calendar forwards or backwards by months or years
 			// part:
-			//      "month" or "year"
+			//		"month" or "year"
 			// amount:
-			//      Number of months or years
+			//		Number of months or years
 			// tags:
-			//      private
+			//		private
 			this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus, part, amount));
 		},
 
@@ -402,7 +407,7 @@ dojo.declare(
 			}
 
 			// set tabIndex=0 on new cell, and focus it (but only if Calendar itself is focused)
-			var newCell = dojo.query("[dijitDateValue=" + date.valueOf() + "]", this.domNode)[0];
+			var newCell = dojo.query("[dijitDateValue='" + date.valueOf() + "']", this.domNode)[0];
 			newCell.setAttribute("tabIndex", this.tabIndex);
 			if(this._focused || forceFocus){
 				newCell.focus();
@@ -426,9 +431,9 @@ dojo.declare(
 
 		_onMonthSelect: function(/*Number*/ newMonth){
 			// summary:
-			//      Handler for when user selects a month from the drop down list
+			//		Handler for when user selects a month from the drop down list
 			// tags:
-			//      protected
+			//		protected
 
 			// move to selected month, bounding by the number of days in the month
 			// (ex: dec 31 --> jan 28, not jan 31)
@@ -482,9 +487,9 @@ dojo.declare(
 
 		_onDayClick: function(/*Event*/ evt){
 			// summary:
-			//      Handler for day clicks, selects the date if appropriate
+			//		Handler for day clicks, selects the date if appropriate
 			// tags:
-			//      protected
+			//		protected
 			
 			//If we coming out of selecting a range, we need to skip this onDayClick or else we
 			//are going to deselect a date that has just been selected or deselect one that just was 
@@ -510,9 +515,9 @@ dojo.declare(
 
 		_onDayMouseOver: function(/*Event*/ evt){
 			// summary:
-			//      Handler for mouse over events on days, sets hovered style
+			//		Handler for mouse over events on days, sets hovered style
 			// tags:
-			//      protected
+			//		protected
 
 			// event can occur on <td> or the <span> inside the td,
 			// set node to the <td>.
@@ -528,9 +533,9 @@ dojo.declare(
 		},
 		_setEndRangeAttr: function(/*Date*/ value){
 			// description:
-			// 		records the end of a date range
+			//		records the end of a date range
 			// tags:
-			//      protected
+			//		protected
 			value = new this.dateClassObj(value);
 			value.setHours(1); // to avoid issues when DST shift occurs at midnight, see #8521, #9366
 			this.endRange = value;
@@ -550,9 +555,9 @@ dojo.declare(
 
 		_onDayMouseOut: function(/*Event*/ evt){
 			// summary:
-			//      Handler for mouse out events on days, clears hovered style
+			//		Handler for mouse out events on days, clears hovered style
 			// tags:
-			//      protected
+			//		protected
 	
 			if(!this._currentNode){ return; }
 			
@@ -597,7 +602,7 @@ dojo.declare(
 			// summary:
 			//		Provides keyboard navigation of calendar.
 			// description:
-			//		Called from _onKeyPress() to handle keypress on a stand alone Calendar,
+			//		Called from _onKeyDown() to handle keypress on a stand alone Calendar,
 			//		and also from `dijit.form._DateTimeTextBox` to pass a keypress event 
 			//		from the `dijit.form.DateTextBox` to be handled in this widget
 			// returns:
@@ -670,7 +675,7 @@ dojo.declare(
 			return false;
 		},
 
-		_onKeyPress: function(/*Event*/ evt){
+		_onKeyDown: function(/*Event*/ evt){
 			// summary:
 			//		For handling keypress events on a stand alone calendar
 			if(!this.handleKey(evt)){
@@ -823,18 +828,18 @@ dojo.declare(
 			// summary:
 			//		Notification that a date cell or more were selected.
 			// description:
-			//      Passes on the list of ISO dates that are selected
+			//		Passes on the list of ISO dates that are selected
 			// tags:
-			//      protected
+			//		protected
 		},
 
 		onValueUnselected: function(/*array of ISO dates*/ dates){
 			// summary:
 			//		Notification that a date cell or more were unselected.
 			// description:
-			//      Passes on the list of ISO dates that are unselected
+			//		Passes on the list of ISO dates that are unselected
 			// tags:
-			//      protected
+			//		protected
 		},
 		onChange: function(/*Date*/ date){
 			// summary:
@@ -853,7 +858,7 @@ dojo.declare(
 			// summary:
 			//		May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
 			// tags:
-			//      extension
+			//		extension
 /*=====
 			return false; // Boolean
 =====*/
@@ -864,7 +869,7 @@ dojo.declare(
 			//		May be overridden to return CSS classes to associate with the date entry for the given dateObject,
 			//		for example to indicate a holiday in specified locale.
 			// tags:
-			//      extension
+			//		extension
 
 /*=====
 			return ""; // String
@@ -938,7 +943,8 @@ dojo.declare(
 );
 
 //FIXME: can we use dijit.Calendar._MonthDropDown directly?
-dojo.declare("dojox.widget._MonthDropDown", [dijit._Widget, dijit._TemplatedMixin, dijit._WidgetsInTemplateMixin], {
+var MonthDropDown = MultiSelectCalendar._MonthDropDown = dojo.declare("dojox.widget._MonthDropDown",
+    [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin], {
 	// summary:
 	//		The month drop down
 
@@ -970,5 +976,6 @@ dojo.declare("dojox.widget._MonthDropDown", [dijit._Widget, dijit._TemplatedMixi
 	}
 });
 
-return dojox.widget.MultiSelectCalendar;
+return MultiSelectCalendar;
+
 });
diff --git a/dojox/widget/MultiSelectCalendar/MultiSelectCalendar.html b/dojox/widget/MultiSelectCalendar/MultiSelectCalendar.html
index 15294bd..7e4627f 100644
--- a/dojox/widget/MultiSelectCalendar/MultiSelectCalendar.html
+++ b/dojox/widget/MultiSelectCalendar/MultiSelectCalendar.html
@@ -1,4 +1,4 @@
-<table cellspacing="0" cellpadding="0" class="dijitCalendarContainer" role="grid" dojoAttachEvent="onkeypress: _onKeyPress" aria-labelledby="${id}_year">
+<table cellspacing="0" cellpadding="0" class="dijitCalendarContainer" role="grid" dojoAttachEvent="onkeydown: _onKeyDown" aria-labelledby="${id}_year">
 	<thead>
 		<tr class="dijitReset dijitCalendarMonthContainer" valign="top">
 			<th class='dijitReset dijitCalendarArrow' dojoAttachPoint="decrementMonth">
diff --git a/dojox/widget/Pager.js b/dojox/widget/Pager.js
index 3ea4b4d..1569e66 100644
--- a/dojox/widget/Pager.js
+++ b/dojox/widget/Pager.js
@@ -1,31 +1,30 @@
-dojo.provide("dojox.widget.Pager");
-dojo.experimental("dojox.widget.Pager");
+define(["dojo/aspect", "dojo/_base/array", "dojo/_base/declare", "dojo/dom", "dojo/dom-attr", "dojo/dom-class", "dojo/dom-construct", "dojo/dom-geometry", "dojo/dom-style", "dojo/fx", "dojo/_base/kernel", "dojo/keys",
+	"dojo/_base/lang", "dojo/on", "dijit/_WidgetBase", "dijit/_TemplatedMixin", "./PagerItem", "dojo/text!./Pager/Pager.html"],
+	function(aspect, array, declare, dom, attr, domClass, domConstruct, geometry, style, fx, kernel, keys, lang, on, _WidgetBase, _TemplatedMixin, PagerItem, template){
 
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dojo.fx");
+kernel.experimental("dojox.widget.Pager");
 
-dojo.declare("dojox.widget.Pager",
-	[dijit._Widget, dijit._Templated],
+return declare("dojox.widget.Pager",
+	[_WidgetBase, _TemplatedMixin],
 	{
-	// summary: A Pager, displaying a list of sized nodes
-	
-	
-	templateString: dojo.cache("dojox.widget", "Pager/Pager.html"),
+	// summary:
+	//		A Pager, displaying a list of sized nodes
+
+
+	templateString: template,
+
 
-/*=====
 	// iconPrevious: String?
 	//		The url of the previous page icon
 	iconPrevious: "",
-	
+
 	// iconNext: String?
 	//		The url of the next page icon
 	iconNext: "",
-=====*/
 
-	iconPage: dojo.moduleUrl("dojox.widget", "Pager/images/pageInactive.png"),
-	iconPageActive: dojo.moduleUrl("dojox.widget", "Pager/images/pageActive.png"),
-	
+	iconPage: require.toUrl("dojox/widget/Pager/images/pageInactive.png"),
+	iconPageActive: require.toUrl("dojox/widget/Pager/images/pageActive.png"),
+
 	// store: Object
 	//		A dojo.data Data store
 	store: null, // data store for items
@@ -33,87 +32,87 @@ dojo.declare("dojox.widget.Pager",
 	// orientation: String
 	//		Either "horizontal or "vertical" to define the direction the pages will slide
 	orientation: "horizontal", // or vertical
-	
+
 	// statusPos: String
 	//		A string describing where to put the Pager "current page" indicator. Options are
 	//		"leading" or "trailing". In the case of horiztonal orientation, "leading" indicates
 	//		positioned above the PageItems. In the case of vertical, "leading" indicates "before".
 	statusPos: "leading",
-	
+
 	// pagerPos: String
 	//		TODOC
 	pagerPos: "center",
 
 	// duration: Integer
-	// 		Time in milliseconds to transition the pages
+	//		Time in milliseconds to transition the pages
 	duration: 500,
-	
+
 	// itemSpace: Integer
 	//		Spacing between items? TODOC
 	itemSpace: 2,
-	
+
 	// resizeChildren: Boolean
-	// 		TODOC
+	//		TODOC
 	resizeChildren: true,
-	
-	// itemClass: String
-	//		The full dotted named of a Class to use for the internal Pager Items.
-	itemClass: "dojox.widget._PagerItem",
-	
+
+	// itemClass: String|Widget
+	//		The full dotted named of a Class or Widget constructor to use for the internal Pager Items.
+	itemClass: PagerItem,
+
 	// itemsPage: Integer
 	//		The numbers of items to display in each "Page"
 	itemsPage: 3,
-	
+
 	postMixInProperties: function(){
 		var h = (this.orientation == "horizontal");
-		dojo.mixin(this,{
+		lang.mixin(this,{
 			_totalPages:0,
 			_currentPage:1,
 			dirClass: "pager" + (h ? "Horizontal" : "Vertical"),
-			iconNext: dojo.moduleUrl("dojox.widget", "Pager/images/" + (h ? "h" : "v") + "Next.png"),
-			iconPrevious: dojo.moduleUrl("dojox.widget", "Pager/images/" + (h ? "h" : "v") + "Previous.png")
+			iconNext: require.toUrl("dojox/widget/Pager/images/" + (h ? "h" : "v") + "Next.png"),
+			iconPrevious: require.toUrl("dojox/widget/Pager/images/" + (h ? "h" : "v") + "Previous.png")
 		});
 	},
-		
+
 	postCreate: function(){
 		this.inherited(arguments);
-		//this.connect(this.domNode,"onkeypress","_handleKey");
 		this.store.fetch({
-			onComplete: dojo.hitch(this, "_init")
+			onComplete: lang.hitch(this, "_init")
 		});
-		
+
 	},
-	
+
 	_a11yStyle: function(e){
-		// summary: top level onfocus/onblur listen to set a class "pagerFocus" on some node
-		// 		and remove it onblur
-		dojo[(e.type == "focus" ? "addClass" : "removeClass")](e.target,"pagerFocus");
+		// summary:
+		//		top level onfocus/onblur listen to set a class "pagerFocus" on some node
+		//		and remove it onblur
+		domClass.toggle(e.target, "pagerFocus", (e.type == "focus"));
 	},
-	
+
 	_handleKey: function(e){
-		// summary: Handle keyboard navigation internally
+		// summary:
+		//		Handle keyboard navigation internally
 
-		var dk = dojo.keys;
-		var key = (e.charCode == dk.SPACE ? dk.SPACE : e.keyCode);
+		var key = (e.charCode == keys.SPACE ? keys.SPACE : e.keyCode);
 		switch(key){
-			
-			case dk.UP_ARROW:
-			case dk.RIGHT_ARROW:
+
+			case keys.UP_ARROW:
+			case keys.RIGHT_ARROW:
 			case 110:
 			case 78: // key "n"
 				e.preventDefault();
 				this._pagerNext();
 				break;
 
-			case dk.DOWN_ARROW:
-			case dk.LEFT_ARROW:
+			case keys.DOWN_ARROW:
+			case keys.LEFT_ARROW:
 			case 112:
 			case 80: // key "p"
 				e.preventDefault();
 				this._pagerPrevious();
 				break;
-			
-			case dk.ENTER:
+
+			case keys.ENTER:
 				switch(e.target){
 					case this.pagerNext : this._pagerNext(); break;
 					case this.pagerPrevious : this._pagerPrevious(); break;
@@ -121,162 +120,175 @@ dojo.declare("dojox.widget.Pager",
 				break;
 		}
 	},
-	
+
 	_init: function(items) {
 		this.items = items;
 		this._renderPages();
 		this._renderStatus();
 		this._renderPager();
 	},
-	
+
+	generatePagerItem: function(/*item */ item, /* Number */ cnt){
+		// summary:
+		//		this method instantiates pagerItems to be used by the pager, it is overridable to allow
+		//		customizing these items
+
+		// only use getObject if its not the default _PagerItem value
+		var itemClass = this.itemClass,
+			pagerItem = (typeof itemClass == "string" ? lang.getObject(itemClass) : itemClass);
+
+		var contentContainer = domConstruct.create('div', {
+				innerHTML: item.content
+			});
+
+		return new pagerItem({
+			  id: this.id + '-item-' + (cnt + 1)
+		  }, contentContainer);
+	},
+
 	_renderPages: function(){
-		var pcv = this.pagerContainerView;
-		var _h = (this.orientation == "horizontal");
-		var style = dojo.style;
+		var pcv = this.pagerContainerView,
+			_h = (this.orientation == "horizontal");
+
 		if(_h){
+			var pagerH = geometry.getMarginBox(this.pagerContainerPager).h,
+				statusH = geometry.getMarginBox(this.pagerContainerStatus).h;
 
-			var pagerH = dojo.marginBox(this.pagerContainerPager).h;
-			var statusH = dojo.marginBox(this.pagerContainerStatus).h;
 			if (this.pagerPos != 'center'){
 				var addonHeight = pagerH+statusH;
 			}else{
 				var addonHeight = statusH;
-				var widthSub = this.pagerIconNext.width;
-				var containerWidth = style(pcv, 'width');
-				var newWidth = containerWidth-(2*widthSub);
-				style(pcv, {
+
+				var	widthSub = this.pagerIconNext.width,
+					containerWidth = style.get(pcv, 'width'),
+					newWidth = containerWidth-(2*widthSub);
+
+				style.set(pcv, {
 					width: newWidth+'px',
 					marginLeft: this.pagerIconNext.width+'px',
 					marginRight: this.pagerIconNext.width+'px'
 				});
 			}
-			var totalH = style(this.pagerContainer, 'height') - addonHeight;
-			style(this.pagerContainerView, 'height', totalH+'px');
-			
-			var itemSpace = Math.floor(style(pcv, 'width') / this.itemsPage);
+			var totalH = style.get(this.pagerContainer, 'height') - addonHeight;
+			style.set(this.pagerContainerView, 'height', totalH+'px');
+
+			var itemSpace = Math.floor(style.get(pcv, 'width') / this.itemsPage);
 			if(this.statusPos == 'trailing'){
 				if(this.pagerPos != 'center'){
-					style(pcv, 'marginTop', pagerH+'px');
+					style.set(pcv, 'marginTop', pagerH+'px');
 				}
-				style(pcv, 'marginBottom', statusH+'px');
+				style.set(pcv, 'marginBottom', statusH+'px');
 			}else{
-				style(pcv, 'marginTop', statusH+'px');
+				style.set(pcv, 'marginTop', statusH+'px');
 				if (this.pagerPos != 'center'){
-					style(pcv, 'marginTop', pagerH+'px');
+					style.set(pcv, 'marginTop', pagerH+'px');
 				}
 			}
-			
 		}else{
+			var pagerW = geometry.getMarginBox(this.pagerContainerPager).w,
+				statusW = geometry.getMarginBox(this.pagerContainerStatus).w,
+				containerW = style.get(this.pagerContainer, 'width');
 
-			var pagerW = dojo.marginBox(this.pagerContainerPager).w;
-			var statusW = dojo.marginBox(this.pagerContainerStatus).w;
-			var containerW = style(this.pagerContainer, 'width');
 			if(this.pagerPos != 'center'){
 				var addonWidth = pagerW + statusW;
 			}else{
-				var addonWidth = statusW;
-				var heightSub = this.pagerIconNext.height;
-				var containerHeight = style(pcv, 'height');
-				var newHeight = containerHeight - (2 * heightSub);
-				style(pcv,{
+				var addonWidth = statusW,
+					heightSub = this.pagerIconNext.height,
+					containerHeight = style.get(pcv, 'height'),
+					newHeight = containerHeight - (2 * heightSub);
+
+				style.set(pcv,{
 					height: newHeight+'px',
 					marginTop: this.pagerIconNext.height+'px',
 					marginBottom: this.pagerIconNext.height+'px'
 				});
 			}
-			var totalW = style(this.pagerContainer, 'width') - addonWidth;
-			style(pcv, 'width', totalW+'px');
-			
-			var itemSpace = Math.floor(style(pcv, 'height') / this.itemsPage);
+			var totalW = style.get(this.pagerContainer, 'width') - addonWidth;
+			style.set(pcv, 'width', totalW+'px');
+
+			var itemSpace = Math.floor(style.get(pcv, 'height') / this.itemsPage);
 			if(this.statusPos == 'trailing'){
 				if (this.pagerPos != 'center'){
-					style(pcv, 'marginLeft', pagerW + 'px');
+					style.set(pcv, 'marginLeft', pagerW + 'px');
 				}
-				style(pcv, 'marginRight', statusW + 'px');
+				style.set(pcv, 'marginRight', statusW + 'px');
 			}else{
-				style(pcv, 'marginLeft', statusW + 'px');
+				style.set(pcv, 'marginLeft', statusW + 'px');
 				if(this.pagerPos != 'center'){
-					style(pcv, 'marginRight', pagerW+'px');
+					style.set(pcv, 'marginRight', pagerW+'px');
 				}
 			}
 		}
-		
-		var _PagerItem = dojo.getObject(this.itemClass);
-		var paddingLead = "padding" + (_h ? "Left" : "Top");
-		var paddingTrail = "padding" + (_h ? "Right" : "Bottom");
-			
-		dojo.forEach(this.items, function(item, cnt){
-			
-			var contentContainer = dojo.create('div', {
-				innerHTML: item.content
-			});
+		var paddingLead = "padding" + (_h ? "Left" : "Top"),
+			paddingTrail = "padding" + (_h ? "Right" : "Bottom");
+
+		array.forEach(this.items, function(item, cnt){
+			var pagerItem = this.generatePagerItem(item, cnt),
+				containerProps = {};
 
-			var pagerItem = new _PagerItem({
-				id: this.id + '-item-' + (cnt + 1)
-			}, contentContainer);
-			
 			this.pagerItems.appendChild(pagerItem.domNode);
-			
-			var containerProps = {};
+
 			containerProps[(_h ? "width" : "height")] = (itemSpace - this.itemSpace) + "px";
 			var p = (_h ? "height" : "width");
-			containerProps[p] = style(pcv, p) + "px";
-			style(pagerItem.containerNode, containerProps);
+			containerProps[p] = style.get(pcv, p) + "px";
+			style.set(pagerItem.containerNode, containerProps);
 
 			if(this.resizeChildren){
 				pagerItem.resizeChildren();
 			}
 			pagerItem.parseChildren();
-			
+
 			// only display amount of items as defined in itemsPage
-			style(pagerItem.domNode, "position", "absolute");
+			style.set(pagerItem.domNode, "position", "absolute");
 
 			if (cnt < this.itemsPage){
-				var pos = (cnt) * itemSpace;
-				var trailingDir = (_h ? "left" : "top");
-				var dir = (_h ? "top" : "left");
-				style(pagerItem.domNode, dir, "0px");
-				style(pagerItem.domNode, trailingDir, pos+"px");
+				var pos = (cnt) * itemSpace,
+					trailingDir = (_h ? "left" : "top"),
+					dir = (_h ? "top" : "left");
+
+				style.set(pagerItem.domNode, dir, "0px");
+				style.set(pagerItem.domNode, trailingDir, pos+"px");
 			}else{
-				style(pagerItem.domNode, "top", "-1000px");
-				style(pagerItem.domNode, "left", "-1000px");
+				style.set(pagerItem.domNode, "top", "-1000px");
+				style.set(pagerItem.domNode, "left", "-1000px");
 			}
 
-			style(pagerItem.domNode, paddingTrail, (this.itemSpace/2)+"px");
-			style(pagerItem.domNode, paddingLead, (this.itemSpace/2)+"px");
-			
+			style.set(pagerItem.domNode, paddingTrail, (this.itemSpace/2)+"px");
+			style.set(pagerItem.domNode, paddingLead, (this.itemSpace/2)+"px");
+
 		}, this);
 	},
-	
+
 	_renderPager: function() {
-		var tcp = this.pagerContainerPager;
-		var zero = "0px";
-		var _h = (this.orientation == "horizontal");
+		var tcp = this.pagerContainerPager,
+			zero = "0px",
+			_h = (this.orientation == "horizontal");
+
 		if(_h){
 
 			if(this.statusPos == 'center'){
-				
+
 			}else if (this.statusPos == 'trailing'){
-				dojo.style(tcp, 'top', zero);
+				style.set(tcp, 'top', zero);
 			}else{
-				dojo.style(tcp, 'bottom', zero);
+				style.set(tcp, 'bottom', zero);
 			}
-			dojo.style(this.pagerNext, 'right', zero);
-			dojo.style(this.pagerPrevious, 'left', zero);
-			
+			style.set(this.pagerNext, 'right', zero);
+			style.set(this.pagerPrevious, 'left', zero);
+
 		}else{
-			
+
 			if (this.statusPos == 'trailing'){
-				dojo.style(tcp, 'left', zero);
+				style.set(tcp, 'left', zero);
 			}else{
-				dojo.style(tcp, 'right', zero);
+				style.set(tcp, 'right', zero);
 			}
-			dojo.style(this.pagerNext, 'bottom', zero);
-			dojo.style(this.pagerPrevious, 'top', zero);
+			style.set(this.pagerNext, 'bottom', zero);
+			style.set(this.pagerPrevious, 'top', zero);
 		}
-		
+
 	},
-	
+
 	_renderStatus: function() {
 		this._totalPages = Math.ceil(this.items.length / this.itemsPage);
 		// FIXME!!
@@ -284,16 +296,14 @@ dojo.declare("dojox.widget.Pager",
 		this.iconHeight = 0;
 		this.iconsLoaded = 0;
 		this._iconConnects = [];
-		
+
 		for (var i = 1; i <= this._totalPages; i++){
 			var icon = new Image();
-			
+
 			var pointer = i;
-			dojo.connect(icon, 'onclick', dojo.hitch(this, function(pointer) {
-				this._pagerSkip(pointer);
-			}, pointer));
-			
-			this._iconConnects[pointer] = dojo.connect(icon, 'onload', dojo.hitch(this,function(pointer){
+			on(icon, 'click', lang.hitch(this, "_pagerSkip", pointer));
+
+			this._iconConnects[pointer] = on(icon, 'load', lang.hitch(this, function(pointer){
 				this.iconWidth += icon.width;
 				this.iconHeight += icon.height;
 				this.iconsLoaded++;
@@ -302,45 +312,49 @@ dojo.declare("dojox.widget.Pager",
 					if (this.orientation == "horizontal"){
 						if (this.statusPos == 'trailing'){
 							if (this.pagerPos == 'center'){
-								var containerHeight = dojo.style(this.pagerContainer, 'height');
-								var statusHeight = dojo.style(this.pagerContainerStatus, 'height');
-								dojo.style(this.pagerContainerPager, 'top', ((containerHeight/2)-(statusHeight/2))+'px');
+								var containerHeight = style.get(this.pagerContainer, 'height'),
+									statusHeight = style.get(this.pagerContainerStatus, 'height');
+
+								style.set(this.pagerContainerPager, 'top', ((containerHeight/2)-(statusHeight/2))+'px');
 							}
-							dojo.style(this.pagerContainerStatus, 'bottom', '0px');
+							style.set(this.pagerContainerStatus, 'bottom', '0px');
 						}else{
 							if (this.pagerPos == 'center'){
-								var containerHeight = dojo.style(this.pagerContainer, 'height');
-								var statusHeight = dojo.style(this.pagerContainerStatus, 'height');
-								dojo.style(this.pagerContainerPager, 'bottom', ((containerHeight/2)-(statusHeight/2))+'px');
+								var containerHeight = style.get(this.pagerContainer, 'height'),
+									statusHeight = style.get(this.pagerContainerStatus, 'height');
+
+								style.set(this.pagerContainerPager, 'bottom', ((containerHeight/2)-(statusHeight/2))+'px');
 							}
-							dojo.style(this.pagerContainerStatus, 'top', '0px');
+							style.set(this.pagerContainerStatus, 'top', '0px');
 						}
-					
-						var position = (dojo.style(this.pagerContainer, 'width')/2)-(this.iconWidth/2);
-						dojo.style(this.pagerContainerStatus, 'paddingLeft', position+'px');
+
+						var position = (style.get(this.pagerContainer, 'width')/2)-(this.iconWidth/2);
+						style.set(this.pagerContainerStatus, 'paddingLeft', position+'px');
 					}else{
 						if (this.statusPos == 'trailing'){
 							if (this.pagerPos == 'center'){
-								var containerWidth = dojo.style(this.pagerContainer, 'width');
-								var statusWidth = dojo.style(this.pagerContainerStatus, 'width');
-								dojo.style(this.pagerContainerPager, 'left', ((containerWidth/2)-(statusWidth/2))+'px');
+								var containerWidth = style.get(this.pagerContainer, 'width'),
+									statusWidth = style.get(this.pagerContainerStatus, 'width');
+
+								style.set(this.pagerContainerPager, 'left', ((containerWidth/2)-(statusWidth/2))+'px');
 							}
-							dojo.style(this.pagerContainerStatus, 'right', '0px');
+							style.set(this.pagerContainerStatus, 'right', '0px');
 						}else{
 							if (this.pagerPos == 'center'){
-								var containerWidth = dojo.style(this.pagerContainer, 'width');
-								var statusWidth = dojo.style(this.pagerContainerStatus, 'width');
-								dojo.style(this.pagerContainerPager, 'right', ((containerWidth/2)-(statusWidth/2))+'px');
+								var containerWidth = style.get(this.pagerContainer, 'width'),
+									statusWidth = style.get(this.pagerContainerStatus, 'width');
+
+								style.set(this.pagerContainerPager, 'right', ((containerWidth/2)-(statusWidth/2))+'px');
 							}
-							dojo.style(this.pagerContainerStatus, 'left', '0px');
+							style.set(this.pagerContainerStatus, 'left', '0px');
 						}
-						var position = (dojo.style(this.pagerContainer, 'height')/2)-(this.iconHeight/2);
-						dojo.style(this.pagerContainerStatus, 'paddingTop', position+'px');
+						var position = (style.get(this.pagerContainer, 'height')/2)-(this.iconHeight/2);
+						style.set(this.pagerContainerStatus, 'paddingTop', position+'px');
 					}
 				}
-				dojo.disconnect(this._iconConnects[pointer]);
+				this._iconConnects[pointer].remove();
 			}, pointer));
-			
+
 			if (i==this._currentPage){
 				icon.src=this.iconPageActive;
 			}else{
@@ -348,16 +362,16 @@ dojo.declare("dojox.widget.Pager",
 			}
 			var pointer = i;
 
-			dojo.addClass(icon, this.orientation+'PagerIcon');
-			dojo.attr(icon, 'id', this.id+'-status-'+i);
+			domClass.add(icon, this.orientation+'PagerIcon');
+			attr.set(icon, 'id', this.id+'-status-'+i);
 			this.pagerContainerStatus.appendChild(icon);
-					
+
 			if (this.orientation == "vertical"){
-				dojo.style(icon, 'display', 'block');
+				style.set(icon, 'display', 'block');
 			}
 		}
 	},
-	
+
 	_pagerSkip: function(page){
 		if (this._currentPage == page){
 			return;
@@ -371,23 +385,23 @@ dojo.declare("dojox.widget.Pager",
 				distanceP = (this._totalPages + this._currentPage) - page;
 				distanceN = page - this._currentPage;
 			}
-			
+
 			var b = (distanceN > distanceP);
 			this._toScroll = (b ? distanceP : distanceN);
-			var cmd = (b ? "_pagerPrevious" : "_pagerNext");
-			var connect = this.connect(this, "onScrollEnd", function(){
-				this._toScroll--;
-				if(this._toScroll < 1){
-					this.disconnect(connect);
-				}else{
-					this[cmd]();
-				}
-			});
+			var cmd = (b ? "_pagerPrevious" : "_pagerNext"),
+				handle = aspect.after(this, "onScrollEnd", lang.hitch(this, function(){
+					this._toScroll--;
+					if(this._toScroll < 1){
+						handle.remove();
+					}else{
+						this[cmd]();
+					}
+				}), true);
+
 			this[cmd]();
-			
 		}
 	},
-	
+
 	_pagerNext: function(){
 		if(this._anim) return;
 
@@ -397,16 +411,16 @@ dojo.declare("dojox.widget.Pager",
 		 */
 		var _anims = [];
 		for (var i = this._currentPage * this.itemsPage; i > (this._currentPage - 1) * this.itemsPage; i--){
-			if (!dojo.byId(this.id+'-item-'+i)) continue;
-			
-			var currentItem = dojo.byId(this.id+'-item-'+i);
-			var marginBox = dojo.marginBox(currentItem);
+			if (!dom.byId(this.id+'-item-'+i)) continue;
+
+			var currentItem = dom.byId(this.id+'-item-'+i);
+			var marginBox = geometry.getMarginBox(currentItem);
 			if (this.orientation == "horizontal") {
 				var move = marginBox.l - (this.itemsPage * marginBox.w);
-				_anims.push(dojo.fx.slideTo({node: currentItem, left: move, duration: this.duration}));
+				_anims.push(fx.slideTo({node: currentItem, left: move, duration: this.duration}));
 			}else{
 				var move = marginBox.t - (this.itemsPage * marginBox.h);
-				_anims.push(dojo.fx.slideTo({node: currentItem, top: move, duration: this.duration}));
+				_anims.push(fx.slideTo({node: currentItem, top: move, duration: this.duration}));
 			}
 
 		}
@@ -416,59 +430,60 @@ dojo.declare("dojox.widget.Pager",
 		}else{
 			this._currentPage++;
 		}
-		
+
 		var cnt = this.itemsPage;
 		for (var i=this._currentPage*this.itemsPage; i>(this._currentPage-1)*this.itemsPage; i--){
-			if (dojo.byId(this.id+'-item-'+i)){
-				var currentItem = dojo.byId(this.id+'-item-'+i);
-				var marginBox = dojo.marginBox(currentItem);
+			if (dom.byId(this.id+'-item-'+i)){
+				var currentItem = dom.byId(this.id+'-item-'+i);
+				var marginBox = geometry.getMarginBox(currentItem);
 				if (this.orientation == "horizontal") {
-					var newPos = (dojo.style(this.pagerContainerView, 'width')+((cnt-1)*marginBox.w))-1;
-					dojo.style(currentItem, 'left', newPos+'px');
-					dojo.style(currentItem, 'top', '0px');
-					
+					var newPos = (style.get(this.pagerContainerView, 'width')+((cnt-1)*marginBox.w))-1;
+					style.set(currentItem, 'left', newPos+'px');
+					style.set(currentItem, 'top', '0px');
+
 					var move = newPos-(this.itemsPage*marginBox.w);
-					_anims.push(dojo.fx.slideTo({node: currentItem, left: move, duration: this.duration}));
+					_anims.push(fx.slideTo({node: currentItem, left: move, duration: this.duration}));
 				}else{
-					newPos = (dojo.style(this.pagerContainerView, 'height')+((cnt-1)*marginBox.h))-1;
-					dojo.style(currentItem, 'top', newPos+'px');
-					dojo.style(currentItem, 'left', '0px');
-					
+					newPos = (style.get(this.pagerContainerView, 'height')+((cnt-1)*marginBox.h))-1;
+					style.set(currentItem, 'top', newPos+'px');
+					style.set(currentItem, 'left', '0px');
+
 					var move = newPos-(this.itemsPage*marginBox.h);
-					_anims.push(dojo.fx.slideTo({ node: currentItem, top: move, duration: this.duration}));
+					_anims.push(fx.slideTo({ node: currentItem, top: move, duration: this.duration}));
 				}
 			}
 			cnt--;
 		}
-		
-		this._anim = dojo.fx.combine(_anims);
-		var animConnect = this.connect(this._anim, "onEnd", function(){
+
+		this._anim = fx.combine(_anims);
+		var animHandle = aspect.after(this._anim, "onEnd", lang.hitch(this, function(){
 			delete this._anim;
 			this.onScrollEnd();
-			this.disconnect(animConnect);
-		});
+			animHandle.remove();
+		}), true);
+
 		this._anim.play();
-		
+
 		// set pager icons
-		dojo.byId(this.id+'-status-'+previousPage).src = this.iconPage;
-		dojo.byId(this.id+'-status-'+this._currentPage).src = this.iconPageActive;
+		dom.byId(this.id+'-status-'+previousPage).src = this.iconPage;
+		dom.byId(this.id+'-status-'+this._currentPage).src = this.iconPageActive;
 	},
 
-    _pagerPrevious: function(){
+	_pagerPrevious: function(){
 		if(this._anim) return;
-   
+
 		var _anims = [];
 		for (var i=this._currentPage*this.itemsPage; i>(this._currentPage-1)*this.itemsPage; i--){
-				if (!dojo.byId(this.id+'-item-'+i)) continue;
-		   
-				var currentItem = dojo.byId(this.id+'-item-'+i);
-				var marginBox = dojo.marginBox(currentItem);
+				if (!dom.byId(this.id+'-item-'+i)) continue;
+
+				var currentItem = dom.byId(this.id+'-item-'+i);
+				var marginBox = geometry.getMarginBox(currentItem);
 				if (this.orientation == "horizontal") {
-						var move = dojo.style(currentItem, 'left')+(this.itemsPage*marginBox.w);
-						_anims.push(dojo.fx.slideTo({node: currentItem, left: move, duration: this.duration}));
+						var move = style.get(currentItem, 'left')+(this.itemsPage*marginBox.w);
+						_anims.push(fx.slideTo({node: currentItem, left: move, duration: this.duration}));
 				}else{
-						var move = dojo.style(currentItem, 'top')+(this.itemsPage*marginBox.h);
-						_anims.push(dojo.fx.slideTo({node: currentItem, top: move, duration: this.duration}));
+						var move = style.get(currentItem, 'top')+(this.itemsPage*marginBox.h);
+						_anims.push(fx.slideTo({node: currentItem, top: move, duration: this.duration}));
 				}
 		}
 
@@ -478,73 +493,58 @@ dojo.declare("dojox.widget.Pager",
 		}else{
 				this._currentPage--;
 		}
-   
+
 		var cnt = this.itemsPage;
 		var j=1;
 		for (var i=this._currentPage*this.itemsPage; i>(this._currentPage-1)*this.itemsPage; i--){
-			if(dojo.byId(this.id+'-item-'+i)){
-				var currentItem = dojo.byId(this.id+'-item-'+i);
-				var marginBox = dojo.marginBox(currentItem);
-   
+			if(dom.byId(this.id+'-item-'+i)){
+				var currentItem = dom.byId(this.id+'-item-'+i),
+					marginBox = geometry.getMarginBox(currentItem);
+
 				if (this.orientation == "horizontal") {
 					var newPos = -(j * marginBox.w) + 1;
-					dojo.style(currentItem, 'left', newPos+'px');
-					dojo.style(currentItem, 'top', '0px');
-			   
+					style.set(currentItem, 'left', newPos+'px');
+					style.set(currentItem, 'top', '0px');
+
 					var move = ((cnt - 1) * marginBox.w);
-					_anims.push(dojo.fx.slideTo({node: currentItem, left: move, duration: this.duration}));
-			   
+					_anims.push(fx.slideTo({node: currentItem, left: move, duration: this.duration}));
+
 					var move = newPos+(this.itemsPage * marginBox.w);
-					_anims.push(dojo.fx.slideTo({node: currentItem, left: move, duration: this.duration}));
+					_anims.push(fx.slideTo({node: currentItem, left: move, duration: this.duration}));
 				}else{
 					newPos = -((j * marginBox.h) + 1);
-					dojo.style(currentItem, 'top', newPos+'px');
-					dojo.style(currentItem, 'left', '0px');
-			   
+					style.set(currentItem, 'top', newPos+'px');
+					style.set(currentItem, 'left', '0px');
+
 					var move = ((cnt - 1) * marginBox.h);
-					_anims.push(dojo.fx.slideTo({node: currentItem, top: move, duration: this.duration}));
+					_anims.push(fx.slideTo({node: currentItem, top: move, duration: this.duration}));
 				}
-		   
+
 			}
 			cnt--;
 			j++;
 		}
-   
-		this._anim = dojo.fx.combine(_anims);
-		var animConnect = dojo.connect(this._anim, "onEnd", dojo.hitch(this, function(){
+
+		this._anim = fx.combine(_anims);
+		var animHandle = aspect.after(this._anim, "onEnd", lang.hitch(this, function(){
 			delete this._anim;
 			this.onScrollEnd();
-			dojo.disconnect(animConnect);
-		}));
+			animHandle.remove();
+		}), true);
+
 		this._anim.play();
-   
+
 		// set pager icons
-		dojo.byId(this.id + '-status-' + previousPage).src = this.iconPage;
-		dojo.byId(this.id + '-status-' + this._currentPage).src = this.iconPageActive;
+		dom.byId(this.id + '-status-' + previousPage).src = this.iconPage;
+		dom.byId(this.id + '-status-' + this._currentPage).src = this.iconPageActive;
 
 	},
-	
+
 	onScrollEnd: function(){
-		// summary: Stub Function. Fired after the slide is complete. Override or connect.
+		// summary:
+		//		Stub Function. Fired after the slide is complete. Override or connect.
 	}
 
 });
 
-dojo.declare("dojox.widget._PagerItem",
-	[dijit._Widget, dijit._Templated],
-	{
-	
-	templateString: '<li class="pagerItem" dojoAttachPoint="containerNode"></li>',
-	
-	resizeChildren: function(){
-		var box = dojo.marginBox(this.containerNode);
-		dojo.style(this.containerNode.firstChild, {
-			width: box.w +'px',
-			height: box.h + 'px'
-		});
-	},
-	
-	parseChildren: function(){
-		dojo.parser.parse(this.containerNode);
-	}
 });
diff --git a/dojox/widget/PagerItem.js b/dojox/widget/PagerItem.js
new file mode 100644
index 0000000..865b18d
--- /dev/null
+++ b/dojox/widget/PagerItem.js
@@ -0,0 +1,23 @@
+define(["dojo/_base/declare", "dojo/dom-geometry", "dojo/dom-style", "dojo/parser", "dijit/_WidgetBase", "dijit/_TemplatedMixin"],
+    function(declare, geometry, style, parser, _WidgetBase, _TemplatedMixin){
+
+return declare("dojox.widget._PagerItem",
+    [_WidgetBase, _TemplatedMixin],
+    {
+
+    templateString: '<li class="pagerItem" data-dojo-attach-point="containerNode"></li>',
+
+    resizeChildren: function(){
+        var box = geometry.getMarginBox(this.containerNode);
+        style.set(this.containerNode.firstChild, {
+            width: box.w +'px',
+            height: box.h + 'px'
+        });
+    },
+
+    parseChildren: function(){
+        parser.parse(this.containerNode);
+    }
+});
+
+});
\ No newline at end of file
diff --git a/dojox/widget/PlaceholderMenuItem.js b/dojox/widget/PlaceholderMenuItem.js
index e3fec6b..ff91ba6 100644
--- a/dojox/widget/PlaceholderMenuItem.js
+++ b/dojox/widget/PlaceholderMenuItem.js
@@ -1,7 +1,9 @@
-define(["dojo", "dijit", "dojox", "dijit/Menu","dijit/MenuItem"], function(dojo, dijit, dojox){
-dojo.experimental("dojox.widget.PlaceholderMenuItem");
+define(["dojo/_base/array", "dojo/_base/declare", "dojo/_base/lang", "dojo/dom-style", "dojo/_base/kernel", "dojo/query", "dijit/registry", "dijit/Menu","dijit/MenuItem"],
+    function(array, declare, lang, style, kernel, query, registry, Menu, MenuItem){
 
-dojo.declare("dojox.widget.PlaceholderMenuItem", dijit.MenuItem, {
+kernel.experimental("dojox.widget.PlaceholderMenuItem");
+
+var PlaceholderMenuItem = declare("dojox.widget.PlaceholderMenuItem", MenuItem, {
 	// summary:
 	//		A menu item that can be used as a placeholder.  Set the label
 	//		of this item to a unique key and you can then use it to add new
@@ -12,7 +14,7 @@ dojo.declare("dojox.widget.PlaceholderMenuItem", dijit.MenuItem, {
 	_isPlaceholder: true,
 
 	postCreate: function(){
-		this.domNode.style.display = "none";
+		style.set(this.domNode, "display", "none");
 		this._replacedWith = [];
 		if(!this.label){
 			this.label = this.containerNode.innerHTML;
@@ -20,7 +22,7 @@ dojo.declare("dojox.widget.PlaceholderMenuItem", dijit.MenuItem, {
 		this.inherited(arguments);
 	},
 	
-	replace: function(/*dijit.MenuItem[]*/ menuItems){
+	replace: function(/*dijit/MenuItem[]*/ menuItems){
 		// summary:
 		//		replaces this menu item with the given menuItems.  The original
 		//		menu item is not actually removed from the menu - so if you want
@@ -34,7 +36,7 @@ dojo.declare("dojox.widget.PlaceholderMenuItem", dijit.MenuItem, {
 
 		var p = this.getParent();
 
-		dojo.forEach(menuItems, function(item){
+		array.forEach(menuItems, function(item){
 			p.addChild(item, index++);
 		});
 		this._replacedWith = menuItems;
@@ -59,7 +61,7 @@ dojo.declare("dojox.widget.PlaceholderMenuItem", dijit.MenuItem, {
 		if(!p){ return []; }
 
 		var r = this._replacedWith;
-		dojo.forEach(this._replacedWith, function(item){
+		array.forEach(this._replacedWith, function(item){
 			p.removeChild(item);
 			if(destroy){
 				item.destroyRecursive();
@@ -68,12 +70,12 @@ dojo.declare("dojox.widget.PlaceholderMenuItem", dijit.MenuItem, {
 		this._replacedWith = [];
 		this._replaced = false;
 
-		return r; // dijit.MenuItem[]
+		return r; // dijit/MenuItem[]
 	}
 });
 
 // Se need to extend dijit.Menu so that we have a getPlaceholders function.
-dojo.extend(dijit.Menu, {
+lang.extend(Menu, {
 	getPlaceholders: function(/*String?*/ label){
 		// summary:
 		//		Returns an array of placeholders with the given label.  There
@@ -86,22 +88,23 @@ dojo.extend(dijit.Menu, {
 		var r = [];
 
 		var children = this.getChildren();
-		dojo.forEach(children, function(child){
+		array.forEach(children, function(child){
 			if(child._isPlaceholder && (!label || child.label == label)){
 				r.push(child);
 			}else if(child._started && child.popup && child.popup.getPlaceholders){
 				r = r.concat(child.popup.getPlaceholders(label));
 			}else if(!child._started && child.dropDownContainer){
-				var node = dojo.query("[widgetId]", child.dropDownContainer)[0];
-				var menu = dijit.byNode(node);
+				var node = query("[widgetId]", child.dropDownContainer)[0];
+				var menu = registry.byNode(node);
 				if(menu.getPlaceholders){
 					r = r.concat(menu.getPlaceholders(label));
 				}
 			}
 		}, this);
-		return r; // dojox.widget.PlaceholderMenuItem[]
+		return r; // dojox/widget/PlaceholderMenuItem[]
 	}
 });
 
-return dojox.widget.PlaceholderMenuItem;
+return PlaceholderMenuItem;
+
 });
diff --git a/dojox/widget/Portlet.js b/dojox/widget/Portlet.js
old mode 100644
new mode 100755
index 3f17784..ff1d57e
--- a/dojox/widget/Portlet.js
+++ b/dojox/widget/Portlet.js
@@ -1,430 +1,349 @@
-dojo.experimental("dojox.widget.Portlet");
-dojo.provide("dojox.widget.Portlet");
-dojo.require("dijit.TitlePane");
-dojo.require("dojo.fx");
-
-dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
-	// summary: A container widget that is designed to be contained
-	//		in a dojox.layout.GridContainer. Child widgets can insert
-	//		an icon into the title bar of the Portlet, which when
-	//		clicked, executes the "toggle" method of the child widget.
-	//		A child widget must specify the attribute
-	//		"portletIconClass", and the optional class
-	//		"portletIconHoverClass", as well as the
-	//		"toggle" function.
-
-	// resizeChildren: Boolean
-	//		If true, when the Portlet is resized, any child widgets
-	//		with a 'resize' method have that method called.
-	resizeChildren: true,
-
-	// closable: Boolean
-	//		If true, a close button is placed in the title bar,
-	//		and the Portlet can be hidden. If false, the Portlet
-	//		cannot be closed.
-	closable: true,
-
-	// _parents: Array
-	//		 An array of all the StackContainer widgets that this Portlet
-	//		is contained in.	These are used to determine if the portlet
-	//		is visible or not.
-	_parents: null,
-
-	// _size: Object
-	//		Cache of the previous size of the portlet, used to determine
-	//		if the size has changed and if the child widgets should be
-	//		resized.
-	_size: null,
-
-	// dragRestriction: Boolean
-	//		To remove the drag capability.
-	dragRestriction : false,
-
-	buildRendering: function(){
-		this.inherited(arguments);
-
-		// Hide the portlet until it is fully constructed.
-		dojo.style(this.domNode, "visibility", "hidden");
-	},
-
-	postCreate: function(){
-		this.inherited(arguments);
-
-		// Add the portlet classes
-		dojo.addClass(this.domNode, "dojoxPortlet");
-		dojo.removeClass(this.arrowNode, "dijitArrowNode");
-		dojo.addClass(this.arrowNode, "dojoxPortletIcon dojoxArrowDown");
-		dojo.addClass(this.titleBarNode, "dojoxPortletTitle");
-		dojo.addClass(this.hideNode, "dojoxPortletContentOuter");
-
-		// Choose the class to add depending on if the portlet is draggable or not.
-		dojo.addClass(this.domNode, "dojoxPortlet-" + (!this.dragRestriction ? "movable" : "nonmovable"));
-
-		var _this = this;
-		if(this.resizeChildren){
-			// If children should be resized	when the portlet size changes,
-			// listen for items being dropped, when the window is resized,
-			// or when another portlet's size changes.
-
-			this.subscribe("/dnd/drop", function(){_this._updateSize();});
-
-			this.subscribe("/Portlet/sizechange", function(widget){_this.onSizeChange(widget);});
-			this.connect(window, "onresize", function(){_this._updateSize();});
-
-			// Subscribe to all possible child-selection events that could affect this
-			// portlet
-			var doSelectSubscribe = dojo.hitch(this, function(id, lastId){
-				var widget = dijit.byId(id);
-				if(widget.selectChild){
-					var s = this.subscribe(id + "-selectChild", function(child){
-						var n = _this.domNode.parentNode;
-
-						while(n){
-							if(n == child.domNode){
-
-								// Only fire this once, as the widget is now visible
-								// at least once, so child measurements should be accurate.
-								_this.unsubscribe(s);
-								_this._updateSize();
-								break;
+define([
+	"dojo/_base/declare",
+	"dojo/_base/kernel",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/event",
+	"dojo/_base/connect",
+	"dojo/dom-style",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/fx",
+	"dijit/registry",
+	"dijit/TitlePane",
+	"dijit/_Container",
+	"./PortletSettings",
+	"./PortletDialogSettings"
+	], function(declare, kernel, lang, array, event, connect, domStyle, domClass, domConstruct, fx, registry,
+				TitlePane, _Container, PortletSettings, PortletDialogSettings){
+	
+	kernel.experimental("dojox.widget.Portlet");
+	
+	return declare("dojox.widget.Portlet", [TitlePane, _Container],{
+		// summary:
+		//		A container widget that is designed to be contained
+		//		in a dojox.layout.GridContainer. Child widgets can insert
+		//		an icon into the title bar of the Portlet, which when
+		//		clicked, executes the "toggle" method of the child widget.
+		//		A child widget must specify the attribute
+		//		"portletIconClass", and the optional class
+		//		"portletIconHoverClass", as well as the
+		//		"toggle" function.
+
+		// resizeChildren: Boolean
+		//		If true, when the Portlet is resized, any child widgets
+		//		with a 'resize' method have that method called.
+		resizeChildren: true,
+
+		// closable: Boolean
+		//		If true, a close button is placed in the title bar,
+		//		and the Portlet can be hidden. If false, the Portlet
+		//		cannot be closed.
+		closable: true,
+
+		// _parents: Array
+		//		 An array of all the StackContainer widgets that this Portlet
+		//		is contained in.	These are used to determine if the portlet
+		//		is visible or not.
+		_parents: null,
+
+		// _size: Object
+		//		Cache of the previous size of the portlet, used to determine
+		//		if the size has changed and if the child widgets should be
+		//		resized.
+		_size: null,
+
+		// dragRestriction: Boolean
+		//		To remove the drag capability.
+		dragRestriction : false,
+
+		buildRendering: function(){
+			this.inherited(arguments);
+
+			// Hide the portlet until it is fully constructed.
+			domStyle.set(this.domNode, "visibility", "hidden");
+		},
+
+		postCreate: function(){
+			this.inherited(arguments);
+
+			// Add the portlet classes
+			domClass.add(this.domNode, "dojoxPortlet");
+			domClass.remove(this.arrowNode, "dijitArrowNode");
+			domClass.add(this.arrowNode, "dojoxPortletIcon dojoxArrowDown");
+			domClass.add(this.titleBarNode, "dojoxPortletTitle");
+			domClass.add(this.hideNode, "dojoxPortletContentOuter");
+
+			// Choose the class to add depending on if the portlet is draggable or not.
+			domClass.add(this.domNode, "dojoxPortlet-" + (!this.dragRestriction ? "movable" : "nonmovable"));
+
+			var _this = this;
+			if(this.resizeChildren){
+				// If children should be resized	when the portlet size changes,
+				// listen for items being dropped, when the window is resized,
+				// or when another portlet's size changes.
+
+				this.subscribe("/dnd/drop", function(){_this._updateSize();});
+
+				this.subscribe("/Portlet/sizechange", function(widget){_this.onSizeChange(widget);});
+				this.connect(window, "onresize", function(){_this._updateSize();});
+
+				// Subscribe to all possible child-selection events that could affect this
+				// portlet
+				var doSelectSubscribe = lang.hitch(this, function(id, lastId){
+					var widget = registry.byId(id);
+					if(widget.selectChild){
+						var s = this.subscribe(id + "-selectChild", function(child){
+							var n = _this.domNode.parentNode;
+
+							while(n){
+								if(n == child.domNode){
+
+									// Only fire this once, as the widget is now visible
+									// at least once, so child measurements should be accurate.
+									_this.unsubscribe(s);
+									_this._updateSize();
+									break;
+								}
+								n = n.parentNode;
 							}
-							n = n.parentNode;
+						});
+
+						// Record the StackContainer and child widget that this portlet
+						// is in, so it can figure out whether or not it is visible.
+						// If it is not visible, it will not update it's size dynamically.
+						var child = registry.byId(lastId);
+						if(widget && child){
+							_this._parents.push({parent: widget, child: child});
 						}
-					});
-
-					// Record the StackContainer and child widget that this portlet
-					// is in, so it can figure out whether or not it is visible.
-					// If it is not visible, it will not update it's size dynamically.
-					var child = dijit.byId(lastId);
-					if(widget && child){
-						_this._parents.push({parent: widget, child: child});
 					}
-				}
-			});
-			var lastId;
-			this._parents = [];
-
-			// Find all parent widgets, and if they are StackContainers,
-			// subscribe to their selectChild method calls.
-			for(var p = this.domNode.parentNode; p != null; p = p.parentNode){
-				var id = p.getAttribute ? p.getAttribute("widgetId") : null;
-				if(id){
-					doSelectSubscribe(id, lastId);
-					lastId = id;
+				});
+				var lastId;
+				this._parents = [];
+
+				// Find all parent widgets, and if they are StackContainers,
+				// subscribe to their selectChild method calls.
+				for(var p = this.domNode.parentNode; p != null; p = p.parentNode){
+					var id = p.getAttribute ? p.getAttribute("widgetId") : null;
+					if(id){
+						doSelectSubscribe(id, lastId);
+						lastId = id;
+					}
 				}
 			}
-		}
 
-		// Prevent clicks on icons from causing a drag to start.
-		this.connect(this.titleBarNode, "onmousedown", function(evt){
-			if (dojo.hasClass(evt.target, "dojoxPortletIcon")) {
-				dojo.stopEvent(evt);
-				return false;
-			}
-			return true;
-		});
+			// Prevent clicks on icons from causing a drag to start.
+			this.connect(this.titleBarNode, "onmousedown", function(evt){
+				if (domClass.contains(evt.target, "dojoxPortletIcon")) {
+					event.stop(evt);
+					return false;
+				}
+				return true;
+			});
 
-		// Inform all portlets that the size of this one has changed,
-		// and therefore perhaps they have too
-		this.connect(this._wipeOut, "onEnd", function(){_this._publish();});
-		this.connect(this._wipeIn, "onEnd", function(){_this._publish();});
+			// Inform all portlets that the size of this one has changed,
+			// and therefore perhaps they have too
+			this.connect(this._wipeOut, "onEnd", function(){_this._publish();});
+			this.connect(this._wipeIn, "onEnd", function(){_this._publish();});
 
-		if(this.closable){
-			this.closeIcon = this._createIcon("dojoxCloseNode", "dojoxCloseNodeHover", dojo.hitch(this, "onClose"));
-			dojo.style(this.closeIcon, "display", "");
-		}
-	},
+			if(this.closable){
+				this.closeIcon = this._createIcon("dojoxCloseNode", "dojoxCloseNodeHover", lang.hitch(this, "onClose"));
+				domStyle.set(this.closeIcon, "display", "");
+			}
+		},
 
-	startup: function(){
-		if(this._started){return;}
+		startup: function(){
+			if(this._started){return;}
 
-		var children = this.getChildren();
-		this._placeSettingsWidgets();
+			var children = this.getChildren();
+			this._placeSettingsWidgets();
 
-		// Start up the children
-		dojo.forEach(children, function(child){
-			try{
-				if(!child.started && !child._started){
-					child.startup()
+			// Start up the children
+			array.forEach(children, function(child){
+				try{
+					if(!child.started && !child._started){
+						child.startup()
+					}
 				}
-			}
-			catch(e){
-				console.log(this.id + ":" + this.declaredClass, e);
-			}
-		});
-
-		this.inherited(arguments);
-
-		//this._updateSize();
-		dojo.style(this.domNode, "visibility", "visible");
-	},
-
-	_placeSettingsWidgets: function(){
-		// summary: Checks all the children to see if they are instances
-		//		of dojox.widget.PortletSettings. If they are,
-		//		create an icon for them in the title bar which when clicked,
-		//		calls their toggle() method.
-
-		dojo.forEach(this.getChildren(), dojo.hitch(this, function(child){
-			if(child.portletIconClass && child.toggle && !child.attr("portlet")){
-				this._createIcon(child.portletIconClass, child.portletIconHoverClass, dojo.hitch(child, "toggle"));
-				dojo.place(child.domNode, this.containerNode, "before");
-				child.attr("portlet", this);
-				this._settingsWidget = child;
-			}
-		}));
-	},
+				catch(e){
+					console.log(this.id + ":" + this.declaredClass, e);
+				}
+			});
 
-	_createIcon: function(clazz, hoverClazz, fn){
-		// summary:
-		//		creates an icon in the title bar.
+			this.inherited(arguments);
 
-		var icon = dojo.create("div",{
-			"class": "dojoxPortletIcon " + clazz,
-			"waiRole": "presentation"
-		});
-		dojo.place(icon, this.arrowNode, "before");
+			//this._updateSize();
+			domStyle.set(this.domNode, "visibility", "visible");
+		},
+
+		_placeSettingsWidgets: function(){
+			// summary:
+			//		Checks all the children to see if they are instances
+			//		of dojox.widget.PortletSettings. If they are,
+			//		create an icon for them in the title bar which when clicked,
+			//		calls their toggle() method.
+
+			array.forEach(this.getChildren(), lang.hitch(this, function(child){
+				if(child.portletIconClass && child.toggle && !child.get("portlet")){
+					this._createIcon(child.portletIconClass, child.portletIconHoverClass, lang.hitch(child, "toggle"));
+					domConstruct.place(child.domNode, this.containerNode, "before");
+					child.set("portlet", this);
+					this._settingsWidget = child;
+				}
+			}));
+		},
 
-		this.connect(icon, "onclick", fn);
+		_createIcon: function(clazz, hoverClazz, fn){
+			// summary:
+			//		creates an icon in the title bar.
 
-		if(hoverClazz){
-			this.connect(icon, "onmouseover", function(){
-				dojo.addClass(icon, hoverClazz);
+			var icon = domConstruct.create("div",{
+				"class": "dojoxPortletIcon " + clazz,
+				"waiRole": "presentation"
 			});
-			this.connect(icon, "onmouseout", function(){
-				dojo.removeClass(icon, hoverClazz);
-			});
-		}
-		return icon;
-	},
+			domConstruct.place(icon, this.arrowNode, "before");
 
-	onClose: function(evt){
-		// summary:
-		//		Hides the portlet. Note that it does not
-		//		persist this, so it is up to the client to
-		//		listen to this method and persist the closed state
-		//		in their own way.
-		dojo.style(this.domNode, "display", "none");
-	},
-
-	onSizeChange: function(widget){
-		// summary:
-		//		Updates the Portlet size if any other Portlet
-		//		changes its size.
-		if(widget == this){
-			return;
-		}
-		this._updateSize();
-	},
+			this.connect(icon, "onclick", fn);
 
-	_updateSize: function(){
-		// summary:
-		//		Updates the size of all child widgets.
-		if(!this.open || !this._started || !this.resizeChildren){
-			return;
-		}
+			if(hoverClazz){
+				this.connect(icon, "onmouseover", function(){
+					domClass.add(icon, hoverClazz);
+				});
+				this.connect(icon, "onmouseout", function(){
+					domClass.remove(icon, hoverClazz);
+				});
+			}
+			return icon;
+		},
+
+		onClose: function(evt){
+			// summary:
+			//		Hides the portlet. Note that it does not
+			//		persist this, so it is up to the client to
+			//		listen to this method and persist the closed state
+			//		in their own way.
+			domStyle.set(this.domNode, "display", "none");
+		},
+
+		onSizeChange: function(widget){
+			// summary:
+			//		Updates the Portlet size if any other Portlet
+			//		changes its size.
+			if(widget == this){
+				return;
+			}
+			this._updateSize();
+		},
 
-		if(this._timer){
-			clearTimeout(this._timer);
-		}
-		// Delay applying the size change in case the size
-		// changes very frequently, for performance reasons.
-		this._timer = setTimeout(dojo.hitch(this, function(){
-			var size ={
-				w: dojo.style(this.domNode, "width"),
-				h: dojo.style(this.domNode, "height")
-			};
-
-			// If the Portlet is in a StackWidget, and it is not
-			// visible, do not update the size, as it could
-			// make child widgets miscalculate.
-			for(var i = 0; i < this._parents.length; i++){
-				var p = this._parents[i];
-				var sel = p.parent.selectedChildWidget
-				if(sel && sel != p.child){
-					return;
-				}
+		_updateSize: function(){
+			// summary:
+			//		Updates the size of all child widgets.
+			if(!this.open || !this._started || !this.resizeChildren){
+				return;
 			}
 
-			if(this._size){
-				// If the size of the portlet hasn't changed, don't
-				// resize the children, as this can be expensive
-				if(this._size.w == size.w && this._size.h == size.h){
-					return;
-				}
+			if(this._timer){
+				clearTimeout(this._timer);
 			}
-			this._size = size;
-
-			var fns = ["resize", "layout"];
-			this._timer = null;
-			var kids = this.getChildren();
-
-			dojo.forEach(kids, function(child){
-				for(var i = 0; i < fns.length; i++){
-					if(dojo.isFunction(child[fns[i]])){
-						try{
-							child[fns[i]]();
-						} catch(e){
-							console.log(e);
-						}
-						break;
+			// Delay applying the size change in case the size
+			// changes very frequently, for performance reasons.
+			this._timer = setTimeout(lang.hitch(this, function(){
+				var size ={
+					w: domStyle.get(this.domNode, "width"),
+					h: domStyle.get(this.domNode, "height")
+				};
+
+				// If the Portlet is in a StackWidget, and it is not
+				// visible, do not update the size, as it could
+				// make child widgets miscalculate.
+				for(var i = 0; i < this._parents.length; i++){
+					var p = this._parents[i];
+					var sel = p.parent.selectedChildWidget
+					if(sel && sel != p.child){
+						return;
 					}
 				}
-			});
-			this.onUpdateSize();
-		}), 100);
-	},
 
-	onUpdateSize: function(){
-		// summary:
-		//		Stub function called when the size is changed.
-	},
-
-	_publish: function(){
-		// summary: Publishes an event that all other portlets listen to.
-		//		This causes them to update their child widgets if their
-		//		size has changed.
-		dojo.publish("/Portlet/sizechange",[this]);
-	},
-
-	_onTitleClick: function(evt){
-		if(evt.target == this.arrowNode){
-			this.inherited(arguments);
-		}
-	},
-
-	addChild: function(child){
- 		// summary:
-		//		Adds a child widget to the portlet.
-		this._size = null;
-		this.inherited(arguments);
-
-		if(this._started){
-			this._placeSettingsWidgets();
-			this._updateSize();
-		}
-		if(this._started && !child.started && !child._started){
-			child.startup();
-		}
-	},
-
-	destroyDescendants: function(/*Boolean*/ preserveDom){
-		this.inherited(arguments);
-		if(this._settingsWidget){
-			this._settingsWidget.destroyRecursive(preserveDom);
-		}
-	},
-
-	destroy: function(){
-		if(this._timer){
-			clearTimeout(this._timer);
-		}
-		this.inherited(arguments);
-	},
-
-	_setCss: function(){
-		this.inherited(arguments);
-		dojo.style(this.arrowNode, "display", this.toggleable ? "":"none");
-	}
-});
-
-dojo.declare("dojox.widget.PortletSettings", [dijit._Container, dijit.layout.ContentPane],{
-	// summary:
-	//		A settings widget to be used with a dojox.widget.Portlet.
-	// description:
-	//		This widget should be placed inside a dojox.widget.Portlet widget.
-	//		It is used to set some preferences for that Portlet.	It is essentially
-	//		a ContentPane, and should contain other widgets and DOM nodes that
-	//		do the real work of setting preferences for the portlet.
-
-	// portletIconClass: String
-	//		The CSS class to apply to the icon in the Portlet title bar that is used
-	//		to toggle the visibility of this widget.
-	portletIconClass: "dojoxPortletSettingsIcon",
-
-	// portletIconHoverClass: String
-	//		The CSS class to apply to the icon in the Portlet title bar that is used
-	//		to toggle the visibility of this widget when the mouse hovers over it.
-	portletIconHoverClass: "dojoxPortletSettingsIconHover",
-
-	postCreate: function(){
-		// summary:
-		//		Sets the require CSS classes on the widget.
-
-		// Start the PortletSettings widget hidden, always.
-		dojo.style(this.domNode, "display", "none");
-		dojo.addClass(this.domNode, "dojoxPortletSettingsContainer");
-
-		// Remove the unwanted content pane class.
-		dojo.removeClass(this.domNode, "dijitContentPane");
-	},
-
-	_setPortletAttr: function(portlet){
-		// summary:
-		//		Sets the portlet that encloses this widget.
-		this.portlet = portlet;
-	},
-
-	toggle: function(){
-		// summary:
-		//		Toggles the visibility of this widget.
-		var n = this.domNode;
-		if(dojo.style(n, "display") == "none"){
-			dojo.style(n,{
-				"display": "block",
-				"height": "1px",
-				"width": "auto"
-			});
-			dojo.fx.wipeIn({
-				node: n
-			}).play();
-		}else{
-			dojo.fx.wipeOut({
-				node: n,
-				onEnd: dojo.hitch(this, function(){
-					dojo.style(n,{"display": "none", "height": "", "width":""});
+				if(this._size){
+					// If the size of the portlet hasn't changed, don't
+					// resize the children, as this can be expensive
+					if(this._size.w == size.w && this._size.h == size.h){
+						return;
+					}
 				}
-			)}).play();
-		}
-	}
-});
-
-dojo.declare("dojox.widget.PortletDialogSettings",
-	dojox.widget.PortletSettings,{
-	// summary:
-	//		A settings widget to be used with a dojox.widget.Portlet, which displays
-	//		the contents of this widget in a dijit.Dialog box.
-
-	// dimensions: Array
-	//		The size of the dialog to display.	This defaults to [300, 300]
-	dimensions: null,
+				this._size = size;
+
+				var fns = ["resize", "layout"];
+				this._timer = null;
+				var kids = this.getChildren();
+
+				array.forEach(kids, function(child){
+					for(var i = 0; i < fns.length; i++){
+						if(lang.isFunction(child[fns[i]])){
+							try{
+								child[fns[i]]();
+							} catch(e){
+								console.log(e);
+							}
+							break;
+						}
+					}
+				});
+				this.onUpdateSize();
+			}), 100);
+		},
+
+		onUpdateSize: function(){
+			// summary:
+			//		Stub function called when the size is changed.
+		},
+
+		_publish: function(){
+			// summary:
+			//		Publishes an event that all other portlets listen to.
+			//		This causes them to update their child widgets if their
+			//		size has changed.
+			connect.publish("/Portlet/sizechange",[this]);
+		},
+
+		_onTitleClick: function(evt){
+			if(evt.target == this.arrowNode){
+				this.inherited(arguments);
+			}
+		},
 
-	constructor: function(props, node){
-		this.dimensions = props.dimensions || [300, 100];
-	},
+		addChild: function(child){
+			// summary:
+			//		Adds a child widget to the portlet.
+			this._size = null;
+			this.inherited(arguments);
 
-	toggle: function(){
-		// summary:
-		//		Shows and hides the Dialog box.
-		if(!this.dialog){
-			dojo["require"]("dijit.Dialog");
-			this.dialog = new dijit.Dialog({title: this.title});
+			if(this._started){
+				this._placeSettingsWidgets();
+				this._updateSize();
+			}
+			if(this._started && !child.started && !child._started){
+				child.startup();
+			}
+		},
 
-			dojo.body().appendChild(this.dialog.domNode);
+		destroyDescendants: function(/*Boolean*/ preserveDom){
+			this.inherited(arguments);
+			if(this._settingsWidget){
+				this._settingsWidget.destroyRecursive(preserveDom);
+			}
+		},
 
-			// Move this widget inside the dialog
-			this.dialog.containerNode.appendChild(this.domNode);
+		destroy: function(){
+			if(this._timer){
+				clearTimeout(this._timer);
+			}
+			this.inherited(arguments);
+		},
 
-			dojo.style(this.dialog.domNode,{
-				"width" : this.dimensions[0] + "px",
-				"height" : this.dimensions[1] + "px"
-			});
-			dojo.style(this.domNode, "display", "");
-		}
-		if(this.dialog.open){
-			this.dialog.hide();
-		}else{
-			this.dialog.show(this.domNode);
+		_setCss: function(){
+			this.inherited(arguments);
+			domStyle.set(this.arrowNode, "display", this.toggleable ? "":"none");
 		}
-	}
-});
+	});
+});
\ No newline at end of file
diff --git a/dojox/widget/PortletDialogSettings.js b/dojox/widget/PortletDialogSettings.js
new file mode 100755
index 0000000..79fcfa3
--- /dev/null
+++ b/dojox/widget/PortletDialogSettings.js
@@ -0,0 +1,48 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/window",
+	"dojo/dom-style",
+	"./PortletSettings",
+	"dijit/Dialog"
+	], function(declare, window, domStyle, PortletSettings, Dialog){
+		
+	return declare("dojox.widget.PortletDialogSettings", [PortletSettings],{
+			// summary:
+			//		A settings widget to be used with a dojox.widget.Portlet, which displays
+			//		the contents of this widget in a dijit.Dialog box.
+
+			// dimensions: Array
+			//		The size of the dialog to display.	This defaults to [300, 300]
+			dimensions: null,
+
+			constructor: function(props, node){
+				this.dimensions = props.dimensions || [300, 100];
+			},
+
+			toggle: function(){
+				// summary:
+				//		Shows and hides the Dialog box.
+				
+				if(!this.dialog){
+					//require("dijit.Dialog");
+					this.dialog = new Dialog({title: this.title});
+
+					window.body().appendChild(this.dialog.domNode);
+
+					// Move this widget inside the dialog
+					this.dialog.containerNode.appendChild(this.domNode);
+
+					domStyle.set(this.dialog.domNode,{
+						"width" : this.dimensions[0] + "px",
+						"height" : this.dimensions[1] + "px"
+					});
+					domStyle.set(this.domNode, "display", "");
+				}
+				if(this.dialog.open){
+					this.dialog.hide();
+				}else{
+					this.dialog.show(this.domNode);
+				}
+			}
+	});
+});
diff --git a/dojox/widget/PortletSettings.js b/dojox/widget/PortletSettings.js
new file mode 100755
index 0000000..a6986cc
--- /dev/null
+++ b/dojox/widget/PortletSettings.js
@@ -0,0 +1,72 @@
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/dom-style",
+	"dojo/dom-class",
+	"dojo/fx",
+	"dijit/_Container",
+	"dijit/layout/ContentPane"
+	], function(declare, lang, domStyle, domClass, fx, _Container, ContentPane){
+		
+return declare("dojox.widget.PortletSettings", [_Container, ContentPane], {
+	// summary:
+	//		A settings widget to be used with a dojox.widget.Portlet.
+	// description:
+	//		This widget should be placed inside a dojox.widget.Portlet widget.
+	//		It is used to set some preferences for that Portlet.	It is essentially
+	//		a ContentPane, and should contain other widgets and DOM nodes that
+	//		do the real work of setting preferences for the portlet.
+
+	// portletIconClass: String
+	//		The CSS class to apply to the icon in the Portlet title bar that is used
+	//		to toggle the visibility of this widget.
+	portletIconClass: "dojoxPortletSettingsIcon",
+
+	// portletIconHoverClass: String
+	//		The CSS class to apply to the icon in the Portlet title bar that is used
+	//		to toggle the visibility of this widget when the mouse hovers over it.
+	portletIconHoverClass: "dojoxPortletSettingsIconHover",
+
+	postCreate: function(){
+		// summary:
+		//		Sets the require CSS classes on the widget.
+
+		// Start the PortletSettings widget hidden, always.
+		domStyle.set(this.domNode, "display", "none");
+		domClass.add(this.domNode, "dojoxPortletSettingsContainer");
+
+		// Remove the unwanted content pane class.
+		domClass.remove(this.domNode, "dijitContentPane");
+	},
+
+	_setPortletAttr: function(portlet){
+		// summary:
+		//		Sets the portlet that encloses this widget.
+		this.portlet = portlet;
+	},
+
+	toggle: function(){
+		// summary:
+		//		Toggles the visibility of this widget.
+		var n = this.domNode;
+		if(domStyle.get(n, "display") == "none"){
+			domStyle.set(n,{
+				"display": "block",
+				"height": "1px",
+				"width": "auto"
+			});
+			fx.wipeIn({
+				node: n
+			}).play();
+		}else{
+			fx.wipeOut({
+				node: n,
+				onEnd: lang.hitch(this, function(){
+					domStyle.set(n,{"display": "none", "height": "", "width":""});
+				}
+			)}).play();
+		}
+	}
+});
+
+});
diff --git a/dojox/widget/README b/dojox/widget/README
index d211a8e..59315f7 100644
--- a/dojox/widget/README
+++ b/dojox/widget/README
@@ -33,8 +33,8 @@ Project state:
 -------------------------------------------------------------------------------
 Credits:
 
-[Calendar]		Shane O'Sullivan
-[CalendarFx]	Shane O'Sullivan
+[Calendar]		Shane O'Sullivan, Dylan Schiemann (dylan)
+[CalendarFx]	Shane O'Sullivan, Dylan Schiemann (dylan)
 [ColorPicker]	Peter Higgins (dante)
 [Dialog]		Peter Higgins (dante)
 [DialogSimple]	Peter Higgins (dante)
diff --git a/dojox/widget/Roller.js b/dojox/widget/Roller.js
index f177374..79aad24 100644
--- a/dojox/widget/Roller.js
+++ b/dojox/widget/Roller.js
@@ -1,8 +1,8 @@
 define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 
-	dojo.declare("dojox.widget.Roller", dijit._Widget, {
-		// summary: A simple widget to take an unordered-list of Text and roll through them
-		//
+	var Roller = dojo.declare("dojox.widget.Roller", dijit._Widget, {
+		// summary:
+		//		A simple widget to take an unordered-list of Text and roll through them
 		// description:
 		//		The Roller widget takes an unordered-list of items, and converts
 		//		them to a single-area (the size of one list-item, however you so choose
@@ -15,23 +15,22 @@ define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 		//		standard array manipulation techniques.
 		//
 		//		The class "dojoxRoller" is added to the UL element for styling purposes.
-		//
-		//	example:
+		// example:
 		//	|	// create a scroller from a unordered list with id="lister"
-		//  |	var thinger = new dojox.widget.Roller.Roller({},"lister");
+		//	|	var thinger = new dojox.widget.Roller.Roller({},"lister");
 		//
-		//	example:
+		// example:
 		//	|	// create a scroller from a fixed array, and place in the DOM:
 		//	|	new dojox.widget.Roller({ items:["one","two","three"] }).placeAt(dojo.body());
 		//
-		//	example:
+		// example:
 		//	|	// add an item:
 		//	|	dijit.byId("roller").items.push("I am a new Label");
 		//
-		//  example:
+		// example:
 		//	|	// stop a roller from rolling:
 		//	|	dijit.byId("roller").stop();
-		//
+		
 		// delay: Integer
 		//		Interval between rolls
 		delay: 2000,
@@ -48,7 +47,7 @@ define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 		itemSelector: "> li",
 
 		// durationIn: Integer
-		// 		Speed (in ms) to apply to the "in" animation (show the node)
+		//		Speed (in ms) to apply to the "in" animation (show the node)
 		durationIn: 400,
 
 		// durationOut: Integer
@@ -96,8 +95,9 @@ define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 		},
 
 		makeAnims: function(){
-			// summary: Animation creator function. Need to create an 'in' and 'out'
-			// 		Animation stored in _anim Object, which the rest of the widget
+			// summary:
+			//		Animation creator function. Need to create an 'in' and 'out'
+			//		Animation stored in _anim Object, which the rest of the widget
 			//		will reuse.
 			var n = this.domNode;
 			dojo.mixin(this, {
@@ -111,7 +111,8 @@ define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 		},
 
 		_setupConnects: function(){
-			// summary: setup the loop connection logic
+			// summary:
+			//		setup the loop connection logic
 			var anim = this._anim;
 
 			this.connect(anim["out"], "onEnd", function(){
@@ -127,7 +128,8 @@ define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 		},
 
 		start: function(){
-			// summary: Starts to Roller looping
+			// summary:
+			//		Starts to Roller looping
 			if(!this.rolling){
 				this.rolling = true;
 				this._run();
@@ -139,7 +141,8 @@ define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 		},
 
 		stop: function(){
-			// summary: Stops the Roller from looping anymore.
+			// summary:
+			//		Stops the Roller from looping anymore.
 			this.rolling = false;
 
 			var m = this._anim,
@@ -151,7 +154,8 @@ define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 		},
 
 		_setIndex: function(i){
-			// summary: Set the Roller to some passed index. If beyond range, go to first.
+			// summary:
+			//		Set the Roller to some passed index. If beyond range, go to first.
 			var l = this.items.length - 1;
 			if(i < 0){ i = l; }
 			if(i > l){ i = 0; }
@@ -161,16 +165,18 @@ define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 
 	});
 
-	dojo.declare("dojox.widget.RollerSlide", dojox.widget.Roller, {
-		// summary: An add-on to the Roller to modify animations. This produces
+	Roller.RollerSlide = dojo.declare("dojox.widget.RollerSlide", dojox.widget.Roller, {
+		// summary:
+		//		An add-on to the Roller to modify animations. This produces
 		//		a slide-from-bottom like effect. See `dojox.widget.Roller` for
 		//		full API information.
 
 		durationOut: 175, // slightly faster than default
 
 		makeAnims: function(){
-			// summary: Animation creator function. Need to create an 'in' and 'out'
-			// 		Animation stored in _anim Object, which the rest of the widget
+			// summary:
+			//		Animation creator function. Need to create an 'in' and 'out'
+			//		Animation stored in _anim Object, which the rest of the widget
 			//		will reuse.
 
 			var n = this.domNode, pos = "position",
@@ -201,12 +207,13 @@ define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 
 	});
 
-	dojo.declare("dojox.widget._RollerHover", null, {
-		// summary: A mixin class to provide a way to automate the "stop on hover" functionality.
+	Roller._Hover = dojo.declare("dojox.widget._RollerHover", null, {
+		// summary:
+		//		A mixin class to provide a way to automate the "stop on hover" functionality.
 		//
 		// description:
 		//		A mixin class used to provide a way to automate a "stop on hover" behavior,
-		//		while still allowing for ambigious subclassing for custom animations.
+		//		while still allowing for ambiguous subclassing for custom animations.
 		//		Simply mix this class into a `dojox.widget.Roller` variant, and instantiate
 		//		as you would. The hover connection is done automatically.
 		//
@@ -215,8 +222,8 @@ define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 		//		will start if a mouse enters and leaves the node in this case.
 		//
 		// example:
-		// | dojo.declare("my.Roller", [dojox.widget.RollerSlide, dojox.widget._RollerHover], {});
-		// | new my.Roller({}, "myList");
+		// |	dojo.declare("my.Roller", [Roller.RollerSlide, Roller._Hover], {});
+		// |	new my.Roller({}, "myList");
 
 		postCreate: function(){
 			this.inherited(arguments);
@@ -225,7 +232,6 @@ define(["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit){
 		}
 
 	});
-	
-	return dojox.widget.Roller;
-	
+
+	return Roller;
 });
diff --git a/dojox/widget/RollingList.js b/dojox/widget/RollingList.js
index 413b567..89844e0 100644
--- a/dojox/widget/RollingList.js
+++ b/dojox/widget/RollingList.js
@@ -19,57 +19,60 @@ dojo.requireLocalization("dijit", "common");
 
 dojo.declare("dojox.widget._RollingListPane",
 	[dijit.layout.ContentPane, dijit._Templated, dijit._Contained], {
-	// summary: a core pane that can be attached to a RollingList.  All panes
-	//  should extend this one
+	// summary:
+	//		a core pane that can be attached to a RollingList.  All panes
+	//		should extend this one
 
 	// templateString: string
-	//	our template
+	//		our template
 	templateString: '<div class="dojoxRollingListPane"><table><tbody><tr><td dojoAttachPoint="containerNode"></td></tr></tbody></div>',
 
 	// parentWidget: dojox.widget.RollingList
-	//  Our rolling list widget
+	//		Our rolling list widget
 	parentWidget: null,
 	
 	// parentPane: dojox.widget._RollingListPane
-	//  The pane that immediately precedes ours
+	//		The pane that immediately precedes ours
 	parentPane: null,
 			
 	// store: store
-	//  the store we must use
+	//		the store we must use
 	store: null,
 
 	// items: item[]
-	//  an array of (possibly not-yet-loaded) items to display in this.
-	//  If this array is null, then the query and query options are used to
-	//  get the top-level items to use.  This array is also used to watch and
-	//  see if the pane needs to be reloaded (store notifications are handled)
-	//  by the pane
+	//		an array of (possibly not-yet-loaded) items to display in this.
+	//		If this array is null, then the query and query options are used to
+	//		get the top-level items to use.  This array is also used to watch and
+	//		see if the pane needs to be reloaded (store notifications are handled)
+	//		by the pane
 	items: null,
 	
 	// query: object
-	//  a query to pass to the datastore.  This is only used if items are null
+	//		a query to pass to the datastore.  This is only used if items are null
 	query: null,
 	
 	// queryOptions: object
-	//  query options to be passed to the datastore
+	//		query options to be passed to the datastore
 	queryOptions: null,
 	
 	// focusByNode: boolean
-	//  set to false if the subclass will handle its own node focusing
+	//		set to false if the subclass will handle its own node focusing
 	_focusByNode: true,
 	
 	// minWidth: integer
-	//	the width (in px) for this pane
+	//		the width (in px) for this pane
 	minWidth: 0,
 	
 	_setContentAndScroll: function(/*String|DomNode|Nodelist*/cont, /*Boolean?*/isFakeContent){
-		// summary: sets the value of the content and scrolls it into view
+		// summary:
+		//		sets the value of the content and scrolls it into view
 		this._setContent(cont, isFakeContent);
 		this.parentWidget.scrollIntoView(this);
 	},
 
 	_updateNodeWidth: function(n, min){
-		// summary: updates the min width of the pane to be minPaneWidth
+		// summary:
+		//		updates the min width of the pane to be minPaneWidth
 		n.style.width = "";
 		var nWidth = dojo.marginBox(n).w;
 		if(nWidth < min){
@@ -108,7 +111,8 @@ dojo.declare("dojox.widget._RollingListPane",
 	},
 
 	_focusKey: function(/*Event*/e){
-		// summary: called when a keypress happens on the widget
+		// summary:
+		//		called when a keypress happens on the widget
 		if(e.charOrCode == dojo.keys.BACKSPACE){
 			dojo.stopEvent(e);
 			return;
@@ -121,7 +125,8 @@ dojo.declare("dojox.widget._RollingListPane",
 	},
 	
 	focus: function(/*boolean*/force){
-		// summary: sets the focus to this current widget
+		// summary:
+		//		sets the focus to this current widget
 		if(this.parentWidget._focusedPane != this){
 			this.parentWidget._focusedPane = this;
 			this.parentWidget.scrollIntoView(this);
@@ -130,16 +135,19 @@ dojo.declare("dojox.widget._RollingListPane",
 			}
 		}
 	},
-	
+
 	_onShow: function(){
-		// summary: checks that the store is loaded
+		// summary:
+		//		checks that the store is loaded
+		this.inherited(arguments);
 		if((this.store || this.items) && ((this.refreshOnShow && this.domNode) || (!this.isLoaded && this.domNode))){
 			this.refresh();
 		}
 	},
-	
+
 	_load: function(){
-		// summary: sets the "loading" message and then kicks off a query asyncronously
+		// summary:
+		//		sets the "loading" message and then kicks off a query asyncronously
 		this.isLoaded = false;
 		if(this.items){
 			this._setContentAndScroll(this.onLoadStart(), true);
@@ -150,7 +158,8 @@ dojo.declare("dojox.widget._RollingListPane",
 	},
 	
 	_doLoadItems: function(/*item[]*/items, /*function*/callback){
-		// summary: loads the given items, and then calls the callback when they
+		// summary:
+		//		loads the given items, and then calls the callback when they
 		//		are finished.
 		var _waitCount = 0, store = this.store;
 		dojo.forEach(items, function(item){
@@ -174,7 +183,8 @@ dojo.declare("dojox.widget._RollingListPane",
 	},
 	
 	_doQuery: function(){
-		// summary: either runs the query or loads potentially not-yet-loaded items.
+		// summary:
+		//		either runs the query or loads potentially not-yet-loaded items.
 		if(!this.domNode){return;}
 		var preload = this.parentWidget.preloadItems;
 		preload = (preload === true || (this.items && this.items.length <= Number(preload)));
@@ -197,8 +207,9 @@ dojo.declare("dojox.widget._RollingListPane",
 	},
 
 	_hasItem: function(/* item */ item){
-		// summary: returns whether or not the given item is handled by this
-		//  pane
+		// summary:
+		//		returns whether or not the given item is handled by this
+		//		pane
 		var items = this.items || [];
 		for(var i = 0, myItem; (myItem = items[i]); i++){
 			if(this.parentWidget._itemsMatch(myItem, item)){
@@ -210,16 +221,18 @@ dojo.declare("dojox.widget._RollingListPane",
 	
 	_onSetItem: function(/* item */ item,
 					/* attribute-name-string */ attribute,
-					/* object | array */ oldValue,
-					/* object | array */ newValue){
-		// Summary: called when an item in the store has changed
+					/* Object|Array */ oldValue,
+					/* Object|Array */ newValue){
+		// summary:
+		//		called when an item in the store has changed
 		if(this._hasItem(item)){
 			this.refresh();
 		}
 	},
 	
 	_onNewItem: function(/* item */ newItem, /*object?*/ parentInfo){
-		// Summary: called when an item is added to the store
+		// summary:
+		//		called when an item is added to the store
 		var sel;
 		if((!parentInfo && !this.parentPane) ||
 			(parentInfo && this.parentPane && this.parentPane._hasItem(parentInfo.item) &&
@@ -232,7 +245,8 @@ dojo.declare("dojox.widget._RollingListPane",
 	},
 	
 	_onDeleteItem: function(/* item */ deletedItem){
-		// Summary: called when an item is removed from the store
+		// summary:
+		//		called when an item is removed from the store
 		if(this._hasItem(deletedItem)){
 			this.items = dojo.filter(this.items, function(i){
 				return (i != deletedItem);
@@ -249,7 +263,7 @@ dojo.declare("dojox.widget._RollingListPane",
 	
 	onFetchError: function(/*Error*/ error){
 		// summary:
-		//	called when a fetch error occurs.
+		//		called when a fetch error occurs.
 		return this.errorMessage;
 	},
 
@@ -261,14 +275,14 @@ dojo.declare("dojox.widget._RollingListPane",
 	
 	onLoadError: function(/*Error*/ error){
 		// summary:
-		//	called when a load error occurs.
+		//		called when a load error occurs.
 		return this.errorMessage;
 	},
 	
 	onItems: function(){
 		// summary:
-		//	called after a fetch or load - at this point, this.items should be
-		//  set and loaded.  Override this function to "do your stuff"
+		//		called after a fetch or load - at this point, this.items should be
+		//  	set and loaded.  Override this function to "do your stuff"
 		if(!this.onLoadDeferred){
 			this.cancel();
 			this.onLoadDeferred = new dojo.Deferred(dojo.hitch(this, "cancel"));
@@ -280,17 +294,18 @@ dojo.declare("dojox.widget._RollingListPane",
 
 dojo.declare("dojox.widget._RollingListGroupPane",
 	[dojox.widget._RollingListPane], {
-	// summary: a pane that will handle groups (treats them as menu items)
+	// summary:
+	//		a pane that will handle groups (treats them as menu items)
 	
 	// templateString: string
-	//	our template
+	//		our template
 	templateString: '<div><div dojoAttachPoint="containerNode"></div>' +
 					'<div dojoAttachPoint="menuContainer">' +
 						'<div dojoAttachPoint="menuNode"></div>' +
 					'</div></div>',
 
 	// _menu: dijit.Menu
-	//  The menu that we will call addChild() on for adding items
+	//		The menu that we will call addChild() on for adding items
 	_menu: null,
 	
 	_setContent: function(/*String|DomNode|Nodelist*/cont){
@@ -310,7 +325,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 
 	onItems: function(){
 		// summary:
-		//	called after a fetch or load
+		//		called after a fetch or load
 		var selectItem, hadChildren = false;
 		if(this._menu){
 			selectItem = this._getSelected();
@@ -358,9 +373,10 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 	},
 	
 	_checkScrollConnection: function(doLoad){
-		// summary: checks whether or not we need to connect to our onscroll
+		// summary:
+		//		checks whether or not we need to connect to our onscroll
 		//		function
-		var store = this.store
+		var store = this.store;
 		if(this._scrollConn){
 			this.disconnect(this._scrollConn);
 		}
@@ -379,7 +395,8 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 	},
 	
 	focus: function(/*boolean*/force){
-		// summary: sets the focus to this current widget
+		// summary:
+		//		sets the focus to this current widget
 		if(this._menu){
 			if(this._pendingFocus){
 				this.disconnect(this._pendingFocus);
@@ -387,7 +404,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 			delete this._pendingFocus;
 			
 			// We focus the right widget - either the focusedChild, the
-			//   selected node, the first menu item, or the menu itself
+			// selected node, the first menu item, or the menu itself
 			var focusWidget = this._menu.focusedChild;
 			if(!focusWidget){
 				var focusNode = dojo.query(".dojoxRollingListItemSelected", this.domNode)[0];
@@ -422,7 +439,8 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 	},
 	
 	_getMenu: function(){
-		// summary: returns a widget to be used for the container widget.
+		// summary:
+		//		returns a widget to be used for the container widget.
 		var self = this;
 		var menu = new dijit.Menu({
 			parentMenu: this.parentPane ? this.parentPane._menu : null,
@@ -433,7 +451,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 			},
 			_moveToPopup: function(/*Event*/ evt){
 				if(this.focusedChild && !this.focusedChild.disabled){
-					this.focusedChild._onClick(evt);
+					this.onItemClick(this.focusedChild, evt);
 				}
 			}
 		}, this.menuNode);
@@ -463,7 +481,8 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 	},
 	
 	_onScrollPane: function(){
-		// summary: called when the pane has been scrolled - it sets a timeout
+		// summary:
+		//		called when the pane has been scrolled - it sets a timeout
 		//		so that we don't try and load our visible items too often during
 		//		a scroll
 		if(this._visibleLoadPending){
@@ -473,8 +492,9 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 	},
 	
 	_loadVisibleItems: function(){
-		// summary: loads the items that are currently visible in the pane
-		delete this._visibleLoadPending
+		// summary:
+		//		loads the items that are currently visible in the pane
+		delete this._visibleLoadPending;
 		var menu = this._menu;
 		if(!menu){ return; }
 		var children = menu.getChildren();
@@ -528,7 +548,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 	
 	_getSelected: function(/*dijit.Menu?*/ menu){
 		// summary:
-		//	returns the selected menu item - or null if none are selected
+		//		returns the selected menu item - or null if none are selected
 		if(!menu){ menu = this._menu; }
 		if(menu){
 			var children = this._menu.getChildren();
@@ -543,7 +563,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 	
 	_setSelected: function(/*dijit.MenuItem?*/ item, /*dijit.Menu?*/ menu){
 		// summary:
-		//	selectes the given item in the given menu (defaults to pane's menu)
+		//		selects the given item in the given menu (defaults to pane's menu)
 		if(!menu){ menu = this._menu;}
 		if(menu){
 			dojo.forEach(menu.getChildren(), function(i){
@@ -555,7 +575,8 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 
 dojo.declare("dojox.widget.RollingList",
 	[dijit._Widget, dijit._Templated, dijit._Container], {
-	// summary: a rolling list that can be tied to a data store with children
+	// summary:
+	//		a rolling list that can be tied to a data store with children
 		
 	// templateString: String
 	//		The template to be used to construct the widget.
@@ -563,19 +584,19 @@ dojo.declare("dojox.widget.RollingList",
 	widgetsInTemplate: true,
 	
 	// className: string
-	//  an additional class (or space-separated classes) to add for our widget
+	//		an additional class (or space-separated classes) to add for our widget
 	className: "",
 	
 	// store: store
-	//  the store we must use
+	//		the store we must use
 	store: null,
 	
 	// query: object
-	//  a query to pass to the datastore.  This is only used if items are null
+	//		a query to pass to the datastore.  This is only used if items are null
 	query: null,
 	
 	// queryOptions: object
-	//  query options to be passed to the datastore
+	//		query options to be passed to the datastore
 	queryOptions: null,
 	
 	// childrenAttrs: String[]
@@ -583,7 +604,7 @@ dojo.declare("dojox.widget.RollingList",
 	childrenAttrs: ["children"],
 
 	// parentAttr: string
-	//	the attribute to read for finding our parent item (if any)
+	//		the attribute to read for finding our parent item (if any)
 	parentAttr: "",
 	
 	// value: item
@@ -620,12 +641,13 @@ dojo.declare("dojox.widget.RollingList",
 	cancelButtonLabel: "",
 
 	// minPaneWidth: integer
-	//	the minimum pane width (in px) for all child panes.  If they are narrower,
-	//  the width will be increased to this value.
+	//		the minimum pane width (in px) for all child panes.  If they are narrower,
+	//		the width will be increased to this value.
 	minPaneWidth: 0,
 	
 	postMixInProperties: function(){
-		// summary: Mix in our labels, if they are not set
+		// summary:
+		//		Mix in our labels, if they are not set
 		this.inherited(arguments);
 		var loc = dojo.i18n.getLocalization("dijit", "common");
 		this.okButtonLabel = this.okButtonLabel || loc.buttonOk;
@@ -633,7 +655,8 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_setShowButtonsAttr: function(doShow){
-		// summary: Sets the visibility of the buttons for the widget
+		// summary:
+		//		Sets the visibility of the buttons for the widget
 		var needsLayout = false;
 		if((this.showButtons != doShow && this._started) ||
 			(this.showButtons == doShow && !this.started)){
@@ -651,8 +674,9 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_itemsMatch: function(/*item*/ item1, /*item*/ item2){
-		// Summary: returns whether or not the two items match - checks ID if
-		//  they aren't the exact same object
+		// summary:
+		//		returns whether or not the two items match - checks ID if
+		//		they aren't the exact same object
 		if(!item1 && !item2){
 			return true;
 		}else if(!item1 || !item2){
@@ -663,7 +687,8 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_removeAfter: function(/*Widget or int*/ idx){
-		// summary: removes all widgets after the given widget (or index)
+		// summary:
+		//		removes all widgets after the given widget (or index)
 		if(typeof idx != "number"){
 			idx = this.getIndexOfChild(idx);
 		}
@@ -690,9 +715,10 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	addChild: function(/*dijit._Widget*/ widget, /*int?*/ insertIndex){
-		// summary: adds a child to this rolling list - if passed an insertIndex,
-		//  then all children from that index on will be removed and destroyed
-		//  before adding the child.
+		// summary:
+		//		adds a child to this rolling list - if passed an insertIndex,
+		//		then all children from that index on will be removed and destroyed
+		//		before adding the child.
 		if(insertIndex > 0){
 			this._removeAfter(insertIndex - 1);
 		}
@@ -742,7 +768,8 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	scrollIntoView: function(/*dijit._Widget*/ childWidget){
-		// summary: scrolls the given widget into view
+		// summary:
+		//		scrolls the given widget into view
 		if(this._scrollingTimeout){
 			window.clearTimeout(this._scrollingTimeout);
 		}
@@ -788,7 +815,8 @@ dojo.declare("dojox.widget.RollingList",
 	},
 
 	_setValue: function(/* item */ value){
-		// summary: internally sets the value and fires onchange
+		// summary:
+		//		internally sets the value and fires onchange
 		delete this._setInProgress;
 		if(!this._itemsMatch(this.value, value)){
 			this.value = value;
@@ -797,7 +825,8 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_setValueAttr: function(/* item */ value){
-		// summary: sets the value of this widget to the given store item
+		// summary:
+		//		sets the value of this widget to the given store item
 		if(this._itemsMatch(this.value, value) && !value){ return; }
 		if(this._setInProgress && this._setInProgress === value){ return; }
 		this._setInProgress = value;
@@ -809,7 +838,8 @@ dojo.declare("dojox.widget.RollingList",
 		}
 		
 		var fetchParentItems = dojo.hitch(this, function(/*item*/ item, /*function*/callback){
-			// Summary: Fetchs the parent items for the given item
+			// summary:
+			//		Fetches the parent items for the given item
 			var store = this.store, id;
 			if(this.parentAttr && store.getFeatures()["dojo.data.api.Identity"] &&
 				((id = this.store.getValue(item, this.parentAttr)) || id === "")){
@@ -852,8 +882,9 @@ dojo.declare("dojox.widget.RollingList",
 		});
 		
 		var setFromChain = dojo.hitch(this, function(/*item[]*/itemChain, /*integer*/idx){
-			// Summary: Sets the value of the widget at the given index in the chain - onchanges are not
-			// fired here
+			// summary:
+			//		Sets the value of the widget at the given index in the chain - onchanges are not
+			//		fired here
 			var set = itemChain[idx];
 			var child = this.getChildren()[idx];
 			var conn;
@@ -894,7 +925,8 @@ dojo.declare("dojox.widget.RollingList",
 		
 		var parentChain = [];
 		var onParents = dojo.hitch(this, function(/*item[]*/ parents){
-			// Summary: recursively grabs the parents - only the first one is followed
+			// summary:
+			//		recursively grabs the parents - only the first one is followed
 			if(parents && parents.length){
 				parentChain.push(parents[0]);
 				fetchParentItems(parents[0], onParents);
@@ -919,7 +951,8 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_onItemClick: function(/* Event */ evt, /* dijit._Contained */ pane, /* item */ item, /* item[]? */ children){
-		// summary: internally called when a widget should pop up its child
+		// summary:
+		//		internally called when a widget should pop up its child
 		
 		if(evt){
 			var itemPane = this._getPaneForItem(item, pane, children);
@@ -952,9 +985,11 @@ dojo.declare("dojox.widget.RollingList",
 		this._visibleItem = item;
 	},
 	
-	_getPaneForItem: function(/* item? */ item, /* dijit._Contained? */ parentPane, /* item[]? */ children){		// summary: gets the pane for the given item, and mixes in our needed parts
-		// Returns the pane for the given item (null if the root pane) - after mixing in
-		// its stuff.
+	_getPaneForItem: function(/* item? */ item, /* dijit._Contained? */ parentPane, /* item[]? */ children){
+		// summary:
+		//		gets the pane for the given item, and mixes in our needed parts
+		//		Returns the pane for the given item (null if the root pane) - after mixing in
+		//		its stuff.
 		var ret = this.getPaneForItem(item, parentPane, children);
 		ret.store = this.store;
 		ret.parentWidget = this;
@@ -971,9 +1006,10 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_getMenuItemForItem: function(/*item*/ item, /* dijit._Contained */ parentPane){
-		// summary: returns a widget for the given store item.  The returned
-		//  item will be added to this widget's container widget.  null will
-		//  be passed in for an "empty" item.
+		// summary:
+		//		returns a widget for the given store item.  The returned
+		//		item will be added to this widget's container widget.  null will
+		//		be passed in for an "empty" item.
 		var store = this.store;
 		if(!item || !store || !store.isItem(item)){
 			var i = new dijit.MenuItem({
@@ -997,10 +1033,10 @@ dojo.declare("dojox.widget.RollingList",
 				if(!widgetItem._started){
 					var c = widgetItem.connect(widgetItem, "startup", function(){
 						this.disconnect(c);
-						dojo.style(this.arrowWrapper, "display", "");
+						dojo.style(this.arrowWrapper, "visibility", "");
 					});
 				}else{
-					dojo.style(widgetItem.arrowWrapper, "display", "");
+					dojo.style(widgetItem.arrowWrapper, "visibility", "");
 				}
 			}else{
 				widgetItem = this.getMenuItemForItem(item, parentPane, null);
@@ -1049,8 +1085,9 @@ dojo.declare("dojox.widget.RollingList",
 		}
 	},
 	
-	_setStore: function(/* dojo.data.api.Read */ store){
-		// summary: sets the store for this widget */
+	_setStore: function(/* dojo/data/api/Read */ store){
+		// summary:
+		//		sets the store for this widget */
 		if(store === this.store && this._started){ return; }
 		this.store = store;
 		this._isIdentity = store.getFeatures()["dojo.data.api.Identity"];
@@ -1059,7 +1096,8 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_onKey: function(/*Event*/ e){
-		// summary: called when a keypress event happens on this widget
+		// summary:
+		//		called when a keypress event happens on this widget
 		if(e.charOrCode == dojo.keys.BACKSPACE){
 			dojo.stopEvent(e);
 			return;
@@ -1075,26 +1113,30 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_resetValue: function(){
-		// Summary: function called when the value is reset.
+		// summary:
+		//		function called when the value is reset.
 		this.set("value", this._lastExecutedValue);
 	},
 	
 	_onCancel: function(){
-		// Summary: function called when the cancel button is clicked.  It
+		// summary:
+		//		function called when the cancel button is clicked.  It
 		//		resets its value to whatever was last executed and then cancels
 		this._resetValue();
 		this.onCancel();
 	},
 	
 	_onExecute: function(){
-		// Summary: function called when the OK button is clicked or when an
+		// summary:
+		//		function called when the OK button is clicked or when an
 		//		item is selected (double-clicked or "enter" pressed on it)
 		this._lastExecutedValue = this.get("value");
 		this.onExecute();
 	},
 	
 	focus: function(){
-		// summary: sets the focus state of this widget
+		// summary:
+		//		sets the focus state of this widget
 		var wasSaved = this._savedFocus;
 		this._savedFocus = dijit.getFocus(this);
 		if(!this._savedFocus.node){
@@ -1116,13 +1158,14 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	handleKey:function(/*Event*/e){
-		// summary: handle the key for the given event - called by dropdown
-		//	widgets
-		if(e.charOrCode == dojo.keys.DOWN_ARROW){
+		// summary:
+		//		handle the key for the given event - called by dropdown
+		//		widgets
+		if(e.keyCode == dojo.keys.DOWN_ARROW){
 			delete this._savedFocus;
 			this.focus();
 			return false;
-		}else if(e.charOrCode == dojo.keys.ESCAPE){
+		}else if(e.keyCode == dojo.keys.ESCAPE){
 			this._onCancel();
 			return false;
 		}
@@ -1130,9 +1173,10 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_updateChildClasses: function(){
-		// summary: Called when a child is added or removed - so that we can
-		//	update the classes for styling the "current" one differently than
-		//	the others
+		// summary:
+		//		Called when a child is added or removed - so that we can
+		//		update the classes for styling the "current" one differently than
+		//		the others
 		var children = this.getChildren();
 		var length = children.length;
 		dojo.forEach(children, function(c, idx){
@@ -1156,7 +1200,8 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	getChildItems: function(/*item*/ item){
-		// summary: Returns the child items for the given store item
+		// summary:
+		//		Returns the child items for the given store item
 		var childItems, store = this.store;
 		dojo.forEach(this.childrenAttrs, function(attr){
 			var vals = store.getValues(item, attr);
@@ -1168,17 +1213,19 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	getMenuItemForItem: function(/*item*/ item, /* dijit._Contained */ parentPane, /* item[]? */ children){
-		// summary: user overridable function to return a widget for the given item
-		//  and its children.
+		// summary:
+		//		user overridable function to return a widget for the given item
+		//		and its children.
 		return new dijit.MenuItem({});
 	},
 
 	getPaneForItem: function(/* item? */ item, /* dijit._Contained? */ parentPane, /* item[]? */ children){
-		// summary: user-overridable function to return a pane that corresponds
-		//  to the given item in the store.  It can return null to not add a new pane
-		//  (ie, you are planning on doing something else with it in onItemClick)
-		//
-		//  Item is undefined for the root pane, children is undefined for non-group panes
+		// summary:
+		//		user-overridable function to return a pane that corresponds
+		//		to the given item in the store.  It can return null to not add a new pane
+		//		(ie, you are planning on doing something else with it in onItemClick)
+
+		// Item is undefined for the root pane, children is undefined for non-group panes
 		if(!item || children){
 			return new dojox.widget._RollingListGroupPane({});
 		}else{
@@ -1187,19 +1234,23 @@ dojo.declare("dojox.widget.RollingList",
 	},
 
 	onItemClick: function(/* item */ item, /* dijit._Contained */ pane, /* item[]? */ children){
-		// summary: called when an item is clicked - it receives the store item
+		// summary:
+		//		called when an item is clicked - it receives the store item
 	},
 	
 	onExecute: function(){
-		// summary: exists so that popups don't disappear too soon
+		// summary:
+		//		exists so that popups don't disappear too soon
 	},
 	
 	onCancel: function(){
-		// summary: exists so that we can close ourselves if we wish
+		// summary:
+		//		exists so that we can close ourselves if we wish
 	},
 	
 	onChange: function(/* item */ value){
-		// summary: called when the value of this widget has changed
+		// summary:
+		//		called when the value of this widget has changed
 	}
 	
 });
diff --git a/dojox/widget/Rotator.js b/dojox/widget/Rotator.js
index 58b45ef..b3afba5 100644
--- a/dojox/widget/Rotator.js
+++ b/dojox/widget/Rotator.js
@@ -1,7 +1,23 @@
-dojo.provide("dojox.widget.Rotator");
-dojo.require("dojo.parser");
-
-(function(d){
+define([
+	"dojo/aspect",
+	"dojo/_base/declare",
+	"dojo/_base/Deferred",
+	"dojo/_base/lang",
+	"dojo/_base/array",
+	"dojo/_base/fx",
+	"dojo/dom",
+	"dojo/dom-attr",
+	"dojo/dom-construct",
+	"dojo/dom-geometry",
+	"dojo/dom-style",
+	"dojo/topic",
+	"dojo/on",
+	"dojo/parser",
+	"dojo/query",
+	"dojo/fx/easing",
+	"dojo/NodeList-dom"
+], function(aspect, declare, Deferred, lang, array, fx, dom, domAttr, domConstruct, domGeometry, domStyle, topic,
+			on, parser, query){
 
 	// build friendly strings
 	var _defaultTransition = "dojox.widget.rotator.swap", // please do NOT change
@@ -10,11 +26,11 @@ dojo.require("dojo.parser");
 		_noneStr = "none",
 		_zIndex = "zIndex";
 
-	d.declare("dojox.widget.Rotator", null, {
-		//	summary:
+	var Rotator = declare("dojox.widget.Rotator", null, {
+		// summary:
 		//		A widget for rotating through child nodes using transitions.
 		//
-		//	description:
+		// description:
 		//		A small, fast, extensible, awesome rotator that cycles, with transitions,
 		//		through panes (child nodes) displaying only one at a time and ties into
 		//		controllers used to change state.
@@ -30,69 +46,74 @@ dojo.require("dojo.parser");
 		//
 		//		Note: When the Rotator begins, it does not transition the first pane.
 		//
-		//	subscribed topics:
-		//		[id]/rotator/control - Controls the Rotator
+		//		subscribed topics:
+		//
+		//			[id]/rotator/control - Controls the Rotator
 		//			Parameters:
-		//				/*string*/ action        - The name of a method of the Rotator to run
-		//				/*anything?*/ args       - One or more arguments to pass to the action
 		//
-		//	published topics:
+		//			- /*string*/ action        - The name of a method of the Rotator to run
+		//			- /*anything?*/ args       - One or more arguments to pass to the action
+		//
+		//		published topics:
+		//
 		//		[id]/rotator/update - Notifies controllers that a pane or state has changed.
-		//			Parameters:
-		//				/*string*/ type          - the type of notification
-		//				/*dojox.widget.Rotator*/ rotator
-		//										 - the rotator instance
-		//				/*object?*/ params		 - params
+		//		Parameters:
+		//
+		//		- /*string*/ type          - the type of notification
+		//		- /*dojox.widget.Rotator*/ rotator - the rotator instance
+		//		- /*object?*/ params		 - params
+		//
+		//		declarative dojo/method events (per pane):
 		//
-		//	declarative dojo/method events (per pane):
-		//		onBeforeIn  - Fired before the transition in starts.
-		//		onAfterIn   - Fired after the transition in ends.
-		//		onBeforeOut - Fired before the transition out starts.
-		//		onAfterOut  - Fired after the transition out ends.
+		//		- onBeforeIn  - Fired before the transition in starts.
+		//		- onAfterIn   - Fired after the transition in ends.
+		//		- onBeforeOut - Fired before the transition out starts.
+		//		- onAfterOut  - Fired after the transition out ends.
 		//
-		//	example:
+		// example:
 		//	|	<div dojoType="dojox.widget.Rotator">
 		//	|		<div>Pane 1!</div>
 		//	|		<div>Pane 2!</div>
 		//	|	</div>
 		//
-		//	example:
+		// example:
 		//	|	<script type="text/javascript">
-		//	|		dojo.require("dojox.widget.rotator.Fade");
+		//	|		require("dojo/parser", "dojo/domReady!", "dojox/widget/Rotator", "dojox/widget/rotator/Fade"],
+		//	|           function(parser) { parser.parse(); });
 		//	|	</script>
-		//	|	<div dojoType="dojox.widget.Rotator" transition="dojox.widget.rotator.crossFade">
+		//	|	<div dojoType="dojox/widget/Rotator" transition="dojox/widget/rotator/crossFade">
 		//	|		<div>Pane 1!</div>
 		//	|		<div>Pane 2!</div>
 		//	|	</div>
 
-		//	transition: string
+		// transition: string
 		//		The name of a function that is passed two panes nodes and a duration,
 		//		then returns a dojo.Animation object. The default value is
 		//		"dojox.widget.rotator.swap".
 		transition: _defaultTransition,
 
-		//	transitionParams: string
+		// transitionParams: string
 		//		Parameters for the transition. The string is read in and eval'd as an
 		//		object.  If the duration is absent, the default value will be used.
 		transitionParams: "duration:" + _defaultTransitionDuration,
 
-		//	panes: array
+		// panes: array
 		//		Array of panes to be created in the Rotator. Each array element
-		//		will be passed as attributes to a dojo.create() call.
+		//		will be passed as attributes to a html.create() call.
 		panes: null,
 
 		constructor: function(/*Object*/params, /*DomNode|string*/node){
-			//	summary:
+			// summary:
 			//		Initializes the panes and events.
-			d.mixin(this, params);
+			lang.mixin(this, params);
 
 			var _t = this,
 				t = _t.transition,
 				tt = _t._transitions = {},
 				idm = _t._idMap = {},
 				tp = _t.transitionParams = eval("({ " + _t.transitionParams + " })"),
-				node = _t._domNode = dojo.byId(node),
-				cb = _t._domNodeContentBox = d.contentBox(node), // we are going to assume the rotator will not be changing size
+				node = _t._domNode = dom.byId(node),
+				cb = _t._domNodeContentBox = domGeometry.getContentBox(node), // we are going to assume the rotator will not be changing size
 
 				// default styles to apply to all the container node and rotator's panes
 				p = {
@@ -108,12 +129,12 @@ dojo.require("dojo.parser");
 			_t.id = node.id || (new Date()).getTime();
 
 			// force the rotator DOM node to a relative position and attach the container node to it
-			if(d.style(node, "position") == "static"){
-				d.style(node, "position", "relative");
+			if(domStyle.get(node, "position") == "static"){
+				domStyle.set(node, "position", "relative");
 			}
 
 			// create our object for caching transition objects
-			tt[t] = d.getObject(t);
+			tt[t] = lang.getObject(t);
 			if(!tt[t]){
 				warn(t, _defaultTransition);
 				tt[_t.transition = _defaultTransition] = d.getObject(_defaultTransition);
@@ -125,21 +146,21 @@ dojo.require("dojo.parser");
 			}
 
 			// if there are any panes being passed in, add them to this node
-			d.forEach(_t.panes, function(p){
-				d.create("div", p, node);
+			array.forEach(_t.panes, function(p){
+				domConstruct.create("div", p, node);
 			});
 
 			// zero out our panes array to store the real pane instance
 			var pp = _t.panes = [];
 
 			// find and initialize the panes
-			d.query(">", node).forEach(function(n, i){
-				var q = { node: n, idx: i, params: d.mixin({}, tp, eval("({ " + (d.attr(n, "transitionParams") || "") + " })")) },
-					r = q.trans = d.attr(n, "transition") || _t.transition;
+			query("> *", node).forEach(function(n, i){
+				var q = { node: n, idx: i, params: lang.mixin({}, tp, eval("({ " + (domAttr.get(n, "transitionParams") || "") + " })")) },
+					r = q.trans = domAttr.get(n, "transition") || _t.transition;
 
 				// cache each pane's title, duration, and waitForEvent attributes
-				d.forEach(["id", "title", "duration", "waitForEvent"], function(a){
-					q[a] = d.attr(n, a);
+				array.forEach(["id", "title", "duration", "waitForEvent"], function(a){
+					q[a] = domAttr.get(n, a);
 				});
 
 				if(q.id){
@@ -147,7 +168,7 @@ dojo.require("dojo.parser");
 				}
 
 				// cache the transition function
-				if(!tt[r] && !(tt[r] = d.getObject(r))){
+				if(!tt[r] && !(tt[r] = lang.getObject(r))){
 					warn(r, q.trans = _t.transition);
 				}
 
@@ -155,20 +176,20 @@ dojo.require("dojo.parser");
 				p.display = _noneStr;
 
 				// find the selected pane and initialize styles
-				if(_t.idx == null || d.attr(n, "selected")){
+				if(_t.idx == null || domAttr.get(n, "selected")){
 					if(_t.idx != null){
-						d.style(pp[_t.idx].node, _displayStr, _noneStr);
+						domStyle.set(pp[_t.idx].node, _displayStr, _noneStr);
 					}
 					_t.idx = i;
 					p.display = "";
 				}
-				d.style(n, p);
+				domStyle.set(n, p);
 
 				// check for any declarative script blocks
-				d.query("> script[type^='dojo/method']", n).orphan().forEach(function(s){
-					var e = d.attr(s, "event");
+				query("> script[type^='dojo/method']", n).orphan().forEach(function(s){
+					var e = domAttr.get(s, "event");
 					if(e){
-						q[e] = d.parser._functionFromScript(s);
+						q[e] = parser._functionFromScript(s);
 					}
 				});
 
@@ -176,30 +197,30 @@ dojo.require("dojo.parser");
 				pp.push(q);
 			});
 
-			_t._controlSub = d.subscribe(_t.id + "/rotator/control", _t, "control");
+			_t._controlSub = topic.subscribe(_t.id + "/rotator/control", lang.hitch(_t, this.control));
 		},
 
 		destroy: function(){
-			//	summary:
+			// summary:
 			//		Destroys the Rotator and its DOM node.
-			d.forEach([this._controlSub, this.wfe], d.unsubscribe);
-			d.destroy(this._domNode);
+			array.forEach([this._controlSub, this.wfe], function(wfe) { wfe.remove() });
+			domConstruct.destroy(this._domNode);
 		},
 
 		next: function(){
-			//	summary:
+			// summary:
 			//		Transitions the Rotator to the next pane.
 			return this.go(this.idx + 1);
 		},
 
 		prev: function(){
-			//	summary:
+			// summary:
 			//		Transitions the Rotator to the previous pane.
 			return this.go(this.idx - 1);
 		},
 
 		go: function(/*int|string?*/p){
-			//	summary:
+			// summary:
 			//		Transitions the Rotator to the specified pane index.
 			var _t = this,
 				i = _t.idx,
@@ -226,8 +247,8 @@ dojo.require("dojo.parser");
 
 			// adjust the zIndexes so our animations look good... this must be done before
 			// the animation is created so the animation could override it if necessary
-			d.style(current.node, _zIndex, 2);
-			d.style(next.node, _zIndex, 1);
+			domStyle.set(current.node, _zIndex, 2);
+			domStyle.set(next.node, _zIndex, 1);
 
 			// info object passed to animations and onIn/Out events
 			var info = {
@@ -237,47 +258,47 @@ dojo.require("dojo.parser");
 				},
 
 				// get the transition
-				anim = _t.anim = _t._transitions[next.trans](d.mixin({
+				anim = _t.anim = _t._transitions[next.trans](lang.mixin({
 					rotatorBox: _t._domNodeContentBox
 				}, info, next.params));
 
 			if(anim){
 				// create the deferred that we'll be returning
-				var def = new d.Deferred(),
+				var def = new Deferred(),
 					ev = next.waitForEvent,
 
-					h = d.connect(anim, "onEnd", function(){
-						// reset the node styles
-						d.style(current.node, {
-							display: _noneStr,
-							left: 0,
-							opacity: 1,
-							top: 0,
-							zIndex: 0
-						});
-
-						d.disconnect(h);
-						_t.anim = null;
-						_t.idx = p;
-
-						// fire end events
-						if(current.onAfterOut){ current.onAfterOut(info); }
-						if(next.onAfterIn){ next.onAfterIn(info); }
-
-						_t.onUpdate("onAfterTransition");
-
-						if(!ev){
-							// if there is a previous waitForEvent, then we need to make
-							// sure it gets unsubscribed
-							_t._resetWaitForEvent();
-
-							// animation is all done, fire the deferred callback.
-							def.callback();
-						}
+				h = aspect.after(anim, "onEnd", function(){
+					// reset the node styles
+					domStyle.set(current.node, {
+						display: _noneStr,
+						left: 0,
+						opacity: 1,
+						top: 0,
+						zIndex: 0
 					});
 
+					h.remove();
+					_t.anim = null;
+					_t.idx = p;
+
+					// fire end events
+					if(current.onAfterOut){ current.onAfterOut(info); }
+					if(next.onAfterIn){ next.onAfterIn(info); }
+
+					_t.onUpdate("onAfterTransition");
+
+					if(!ev){
+						// if there is a previous waitForEvent, then we need to make
+						// sure it gets unsubscribed
+						_t._resetWaitForEvent();
+
+						// animation is all done, fire the deferred callback.
+						def.callback();
+					}
+				}, true);
+
 				// if we're waiting for an event, subscribe to it so we know when to continue
-				_t.wfe = ev ? d.subscribe(ev, function(){
+				_t.wfe = ev ? topic.subscribe(ev, function(){
 					_t._resetWaitForEvent();
 					def.callback(true);
 				}) : null;
@@ -297,24 +318,24 @@ dojo.require("dojo.parser");
 		},
 
 		onUpdate: function(/*string*/type, /*object?*/params){
-			//	summary:
+			// summary:
 			//		Send a notification to all controllers with the state of the rotator.
-			d.publish(this.id + "/rotator/update", [type, this, params || {}]);
+			topic.publish(this.id + "/rotator/update", type, this, params || {});
 		},
 
 		_resetWaitForEvent: function(){
-			//	summary:
+			// summary:
 			//		If there is a waitForEvent pending, kill it.
 			if(this.wfe){
-				d.unsubscribe(this.wfe);
-				this.wfe = null;
+				this.wfe.remove();
+				delete this.wfe;
 			}
 		},
 
 		control: function(/*string*/action){
-			//	summary:
+			// summary:
 			//		Dispatches an action, first to this engine, then to the Rotator.
-			var args = d._toArray(arguments),
+			var args = lang._toArray(arguments),
 				_t = this;
 			args.shift();
 
@@ -339,26 +360,27 @@ dojo.require("dojo.parser");
 
 		resize: function(/*int*/width, /*int*/height){
 			var b = this._domNodeContentBox = { w: width, h: height };
-			d.contentBox(this._domNode, b);
-			d.forEach(this.panes, function(p){ d.contentBox(p.node, b); });
+			domGeometry.setContentSize(this._domNode, b);
+			array.forEach(this.panes, function(p){ domGeometry.setContentSize(p.node, b); });
 		},
 
 		onManualChange: function(){
-			//	summary:
+			// summary:
 			//		Stub function that can be overriden or connected to.
 		}
 	});
 
-	d.setObject(_defaultTransition, function(/*Object*/args){
-		//	summary:
+	lang.setObject(_defaultTransition, function(/*Object*/args){
+		// summary:
 		//		The default rotator transition which swaps two panes.
-		return new d._Animation({ // dojo.Animation
+		return new fx.Animation({ // dojo.Animation
 			play: function(){
-				d.style(args.current.node, _displayStr, _noneStr);
-				d.style(args.next.node, _displayStr, "");
+				domStyle.set(args.current.node, _displayStr, _noneStr);
+				domStyle.set(args.next.node, _displayStr, "");
 				this._fire("onEnd");
 			}
 		});
 	});
 
-})(dojo);
\ No newline at end of file
+	return Rotator;
+});
diff --git a/dojox/widget/Selection.js b/dojox/widget/Selection.js
new file mode 100644
index 0000000..badc04c
--- /dev/null
+++ b/dojox/widget/Selection.js
@@ -0,0 +1,220 @@
+define(["dojo/_base/declare", "dojo/_base/array", "dojo/_base/lang", "dojo/Stateful"], 
+	function(declare, arr, lang, Stateful){
+		
+	return declare("dojox.widget.Selection", Stateful, {
+		// summary:
+		//		Base class for widgets that manage a list of selected data items.
+
+		constructor: function(){
+			this.selectedItems = [];
+		},
+		
+		// selectionMode: String
+		//		Valid values are:
+		//
+		//		1. "none": No selection can be done.
+		//		2. "single": Only one item can be selected at a time.
+		//		3. "multiple": Several item can be selected using the control key modifier.
+		//		Default value is "single".
+		selectionMode: "single",
+		
+		_setSelectionModeAttr: function(value){
+			if(value != "none" && value != "single" && value != "multiple"){
+				value = "single"; //default value
+			}			
+			if(value != this.selectionMode){
+				this.selectionMode = value;
+				if(value == "none"){
+					this.set("selectedItems", null);
+				}else if(value == "single"){
+					this.set("selectedItem", this.selectedItem); // null or last selected item 
+				}
+			}
+		},
+		
+		// selectedItem: Object
+		//		In single selection mode, the selected item or in multiple selection mode the last selected item.
+		//		Warning: Do not use this property directly, make sure to call set() or get() methods.
+		selectedItem: null,
+		
+		_setSelectedItemAttr: function(value){
+			if(this.selectedItem != value){
+				this._set("selectedItem", value);
+				this.set("selectedItems", value ? [value] : null);
+			}
+		},
+		
+		// selectedItems: Object[]
+		//		The list of selected items.
+		//		Warning: Do not use this property directly, make sure to call set() or get() methods.
+		selectedItems: null,
+		
+		_setSelectedItemsAttr: function(value){
+			var oldSelectedItems = this.selectedItems;
+			
+			this.selectedItems = value;
+			this.selectedItem = null;
+			
+			if(oldSelectedItems != null && oldSelectedItems.length>0){
+				this.updateRenderers(oldSelectedItems, true);
+			}
+			if(this.selectedItems && this.selectedItems.length>0){
+				this.selectedItem = this.selectedItems[0];
+				this.updateRenderers(this.selectedItems, true);
+			}
+		},
+		
+		_getSelectedItemsAttr: function(){
+			return this.selectedItems == null ? [] : this.selectedItems.concat();
+		},
+		
+		isItemSelected: function(item){
+			// summary:
+			//		Returns wether an item is selected or not.
+			// item: Object
+			//		The item to test the selection for.			
+			if(this.selectedItems == null || this.selectedItems.length== 0){
+				return false;
+			}
+			 
+			return arr.some(this.selectedItems, lang.hitch(this, function(sitem){
+				return this.getIdentity(sitem) == this.getIdentity(item);
+			}));
+		},
+		
+		getIdentity: function(item){
+			// summary:
+			//		This function must be implemented to return the id of a item.
+			// item: Object
+			//		The item to query the identity for.
+		},
+		
+		setItemSelected: function(item, value){
+			// summary:
+			//		Change the selection state of an item.
+			// item: Object
+			//		The item to change the selection state for.
+			// value: Boolean
+			//		True to select the item, false to deselect it. 
+			
+			if(this.selectionMode == "none" || item == null){
+				return;
+			}
+
+			// copy is returned
+			var sel = this.get("selectedItems");
+			var old = this.get("selectedItems");
+			
+			if(this.selectionMode == "single"){
+				if(value){
+					this.set("selectedItem", item);
+				}else if(this.isItemSelected(item)){
+					this.set("selectedItems", null);
+				}
+			}else{ // multiple
+				if(value){
+					if(this.isItemSelected(item)){
+						return; // already selected
+					}
+					if(sel == null){
+						sel = [item];
+					}else{
+						sel.unshift(item);
+					}
+					this.set("selectedItems", sel);
+				}else{
+					var res = arr.filter(sel, function(sitem){
+						return sitem.id != item.id; 
+					});
+					if(res == null || res.length == sel.length){
+						return; // already not selected
+					}
+					this.set("selectedItems", res);
+				}
+			}
+		},
+		
+		selectFromEvent: function(e, item, renderer, dispatch){
+			// summary:
+			//		Applies selection triggered by an user interaction
+			// e: Event
+			//		The source event of the user interaction.
+			// item: Object
+			//		The render item that has been selected/deselected.
+			// renderer: Object
+			//		The visual renderer of the selected/deselected item.			
+			// dispatch: Boolean
+			//		Whether an event must be dispatched or not.
+			// returns: Boolean
+			//		Returns true if the selection has changed and false otherwise.
+			// tags:
+			//		protected
+			
+			if(this.selectionMode == "none"){
+				return false;
+			}
+			
+			var changed;
+			var oldSelectedItem = this.get("selectedItem");
+			var selected = item ? this.isItemSelected(item): false;
+			
+			if(item == null){
+				if(!e.ctrlKey && this.selectedItem != null){
+					this.set("selectedItem", null);
+					changed = true;
+				}
+			}else if(this.selectionMode == "multiple"){
+				 if(e.ctrlKey){
+					this.setItemSelected(item, !selected);
+					changed = true;
+				}else{
+					this.set("selectedItem", item);					
+					changed = true;						
+				}				 								
+			}else{ // single
+				if(e.ctrlKey){					
+					//if the object is selected deselects it.
+					this.set("selectedItem", selected ? null : item);
+					changed = true;					
+				}else{
+					if(!selected){							
+						this.set("selectedItem", item);
+						changed = true;
+					}
+				}
+			}						
+			
+			if(dispatch && changed){
+				this.dispatchChange(oldSelectedItem, this.get("selectedItem"), renderer, e);
+			}
+			
+			return changed;
+		},
+		
+		dispatchChange: function(oldSelectedItem, newSelectedItem, renderer, triggerEvent){
+			// summary:
+			//		Dispatch a selection change event.
+			// oldSelectedItem: Object
+			//		The previously selectedItem.
+			// newSelectedItem: Object
+			//		The new selectedItem.
+			// renderer: Object
+			//		The visual renderer of the selected/deselected item.
+			// triggerEvent: Event
+			//		The event that lead to the selection of the item. 			
+			this.onChange({
+				oldValue: oldSelectedItem,
+				newValue: newSelectedItem,
+				renderer: renderer,
+				triggerEvent: triggerEvent
+			});
+		},
+		
+		onChange: function(){
+			// summary:
+			//		Called when the selection changed.
+			// tags:
+			//		callback			
+		}
+	});
+});
diff --git a/dojox/widget/SortList.js b/dojox/widget/SortList.js
index 6d53bde..e42d3d1 100644
--- a/dojox/widget/SortList.js
+++ b/dojox/widget/SortList.js
@@ -7,7 +7,8 @@ dojo.require("dijit._Templated");
 dojo.declare("dojox.widget.SortList",
 	[dijit.layout._LayoutWidget, dijit._Templated],
 	{
-	// summary: A sortable unordered-list with a fixed header for use in dijit.demos.chat
+	// summary:
+	//		A sortable unordered-list with a fixed header for use in dijit.demos.chat
 	//		for demonstration purposes only for now. feel free to make API suggestions
 	//		or fixes.
 	//
@@ -26,11 +27,11 @@ dojo.declare("dojox.widget.SortList",
 	descending: true,
 
 	// selected: Array
-	//		A list of the selected <li> nodes at any given time.
+	//		A list of the selected `<li>` nodes at any given time.
 	selected: null,
 
 	// sortable: Boolean
-	//	toggle to enable/disable sorting
+	//		toggle to enable/disable sorting
 	sortable: true,
 
 	// FIXME: this is really simple store support
@@ -71,7 +72,8 @@ dojo.declare("dojox.widget.SortList",
 	},
 
 	resize: function(){
-		// summary: do our additional calculations when resize() is called by or in a parent
+		// summary:
+		//		do our additional calculations when resize() is called by or in a parent
 		this.inherited(arguments);
 		// FIXME:
 		// the 10 comes from the difference between the contentBox and calculated height
@@ -83,7 +85,8 @@ dojo.declare("dojox.widget.SortList",
 	},
 	
 	onSort: function(/* Event */e){
-		// summary: sort the data, and style the nodes.
+		// summary:
+		//		sort the data, and style the nodes.
 
 		var arr = dojo.query("li",this.domNode);
 		if (this.sortable){
@@ -101,20 +104,23 @@ dojo.declare("dojox.widget.SortList",
 	},
 	
 	_set: function(/* Event */e){
-		// summary: set hover state
+		// summary:
+		//		set hover state
 		if(e.target !== this.bodyWrapper){
 			dojo.addClass(e.target,"sortListItemHover");
 		}
 	},
 
-	_unset: function(/* Event */e){
-		// summary: remove hover state (FIXME: combine with _set?)
+	_unset: function(/* Event */ e){
+		// summary:
+		//		remove hover state (FIXME: combine with _set?)
 		dojo.removeClass(e.target,"sortListItemHover");
 	},
 
-	_handleClick: function(/* Event */e){
-		// summary: click listener for data portion of widget. toggle selected state
-		//	of node, and update this.selected array accordingly
+	_handleClick: function(/* Event */ e){
+		// summary:
+		//		click listener for data portion of widget. toggle selected state
+		//		of node, and update this.selected array accordingly
 		dojo.toggleClass(e.target,"sortListItemSelected");
 		e.target.focus();
 		this._updateValues(e.target.innerHTML);
@@ -130,7 +136,8 @@ dojo.declare("dojox.widget.SortList",
 	},
 
 	_sorter: function(a,b){
-		// summary: a basic sort function, use query sort, or keep this?
+		// summary:
+		//		a basic sort function, use query sort, or keep this?
 		var aStr = a.innerHTML;
 		var bStr = b.innerHTML;
 		if(aStr>bStr){ return 1; }
@@ -138,13 +145,15 @@ dojo.declare("dojox.widget.SortList",
 		return 0;
 	},
 
-	setTitle: function(/* String */title){
-		// summary: Sets the widget title to a String
+	setTitle: function(/* String */ title){
+		// summary:
+		//		Sets the widget title to a String
 		this.focusNode.innerHTML = this.title = title;
 	},
 
 	onChanged: function(){
-		// summary: stub function, passes the last changed item, and is fired after current state
+		// summary:
+		//		stub function, passes the last changed item, and is fired after current state
 	}
 	
 });
diff --git a/dojox/widget/Standby.js b/dojox/widget/Standby.js
index 2f9bdbb..2913fc0 100755
--- a/dojox/widget/Standby.js
+++ b/dojox/widget/Standby.js
@@ -41,38 +41,58 @@ return declare("dojox.widget.Standby", [_Widget, _TemplatedMixin],{
 	//		A widget designed to act as a Standby/Busy/Disable/Blocking widget to indicate a
 	//		particular DOM node is processing and cannot be clicked on at this time.
 	//		This widget uses absolute positioning to apply the overlay and image.
-	//
-	// image:
+
+	// image: String
 	//		A URL to an image to center within the blocking overlay.
 	//		The default is a basic spinner.
-	//
-	// imageText:
+	image: require.toUrl("dojox/widget/Standby/images/loading.gif").toString(),
+
+	// imageText: String
 	//		Text to set on the ALT tag of the image.
 	//		The default is 'Please wait...'
-	//
-	// text:
-	//		Text to display in the center instead of an image.
+	imageText: "Please Wait...", // TODO: i18n
+
+	// text: String
+	//		Text/HTML to display in the center of the overlay
+	//		This is used if image center is disabled.
 	//		Defaults to 'Please Wait...'
-	//
-	// centerIndicator:
-	//		Which to use as the center info, the text or the image.
-	//		Defaults to image.
-	//
-	// color:
-	//		The color to use for the translucent overlay.
-	//		Text string such as: darkblue, #FE02FD, etc.
-	//
-	// duration:
-	//		How long the fade in and out effects should run in milliseconds.
-	//		Default is 500ms
-	//
-	// zIndex:
+	text: "Please wait...",
+
+	// centerIndicator: String
+	//		Property to define if the image and its alt text should be used, or
+	//		a simple Text/HTML node should be used.  Allowable values are 'image'
+	//		and 'text'.
+	//		Default is 'image'.
+	centerIndicator: "image",
+	
+	// target: DOMNode||DOMID(String)||WidgetID(String)
+	//		The target to overlay when active.  Can be a widget id, a
+	//		dom id, or a direct node reference.
+	target: "",
+
+	// color:	String
+	//		The color to set the overlay.  Should be in #XXXXXX form.
+	//		Default color for the translucent overlay is light gray.
+	color: "#C0C0C0",
+
+	// duration: Integer
+	//		Integer defining how long the show and hide effects should take in milliseconds.
+	//		Defaults to 500
+	duration: 500,
+	
+	// zIndex: String
 	//		Control that lets you specify if the zIndex for the overlay
 	//		should be auto-computed based off parent zIndex, or should be set
 	//		to a particular value.  This is useful when you want to overlay
 	//		things in digit.Dialogs, you can specify a base zIndex to append from.
-	//		Default is 'auto'.
-
+	zIndex: "auto",
+	
+	// opacity: float
+	//		The opacity to make the overlay when it is displayed/faded in.
+	//		The default is 0.75.  This does not affect the image opacity, only the
+	//		overlay.
+	opacity: 0.75,	
+	
 	// templateString: [protected] String
 	//		The template string defining out the basics of the widget.  No need for an external
 	//		file.
@@ -104,26 +124,6 @@ return declare("dojox.widget.Standby", [_Widget, _TemplatedMixin],{
 	//		Which node to use as the center node, the image or the text node.
 	_centerNode: null,
 
-	// image: String
-	//		The URL to the image to center in the overlay.
-	image: require.toUrl("dojox/widget/Standby/images/loading.gif").toString(),
-
-	// imageText: String
-	//		Text for the ALT tag.
-	imageText: "Please Wait...", // TODO: i18n
-
-	// text: String
-	//		Text/HTML to display in the center of the overlay
-	//		This is used if image center is disabled.
-	text: "Please wait...",
-
-	// centerIndicator: String
-	//		Property to define if the image and its alt text should be used, or
-	//		a simple Text/HTML node should be used.  Allowable values are 'image'
-	//		and 'text'.
-	//		Default is 'image'.
-	centerIndicator: "image",
-
 	// _displayed: [private] Boolean
 	//		Flag to indicate if the overlay is displayed or not.
 	_displayed: false,
@@ -131,20 +131,6 @@ return declare("dojox.widget.Standby", [_Widget, _TemplatedMixin],{
 	// _resizeCheck: [private] Object
 	//		Handle to interval function that checks the target for changes.
 	_resizeCheck: null,
-	
-	// target: DOMNode||DOMID(String)||WidgetID(String)
-	//		The target to overlay when active.  Can be a widget id, a
-	//		dom id, or a direct node reference.
-	target: "",
-
-	// color:	String
-	//		The color to set the overlay.  Should be in #XXXXXX form.
-	//		Default color for the translucent overlay is light gray.
-	color: "#C0C0C0",
-
-	// duration: integer
-	//		Integer defining how long the show and hide effects should take.
-	duration: 500,
 
 	// _started: [private] Boolean
 	//		Trap flag to ensure startup only processes once.
@@ -155,13 +141,6 @@ return declare("dojox.widget.Standby", [_Widget, _TemplatedMixin],{
 	//		zoom issue.
 	_parent: null,
 
-	// zIndex: String
-	//		Control that lets you specify if the zIndex for the overlay
-	//		should be auto-computed based off parent zIndex, or should be set
-	//		to a particular value.  This is useful when you want to overlay
-	//		things in digit.Dialogs, you can specify a base zIndex to append from.
-	zIndex: "auto",
-
 	startup: function(args){
 		// summary:
 		//		Over-ride of the basic widget startup function.
@@ -557,7 +536,7 @@ return declare("dojox.widget.Standby", [_Widget, _TemplatedMixin],{
 		var underlayNodeAnim = baseFx.animateProperty({
 			duration: self.duration,
 			node: self._underlayNode,
-			properties: {opacity: {start: 0, end: 0.75}}
+			properties: {opacity: {start: 0, end: self.opacity}}
 		});
 		var imageAnim = baseFx.animateProperty({
 			duration: self.duration,
@@ -581,7 +560,7 @@ return declare("dojox.widget.Standby", [_Widget, _TemplatedMixin],{
 		var underlayNodeAnim = baseFx.animateProperty({
 			duration: self.duration,
 			node: self._underlayNode,
-			properties: {opacity: {start: 0.75, end: 0}},
+			properties: {opacity: {start: self.opacity, end: 0}},
 			onEnd: function(){
 				domStyle.set(this.node,{"display":"none", "zIndex": "-1000"});
 			}
@@ -719,7 +698,7 @@ return declare("dojox.widget.Standby", [_Widget, _TemplatedMixin],{
 			 this._overflowDisabled = true;
 			 var body = baseWindow.body();
 			 if(body.style && body.style.overflow){
-				 this._oldOverflow = domStyle.set(body, "overflow");
+				 this._oldOverflow = domStyle.get(body, "overflow");
 			 }else{
 				 this._oldOverflow = "";
 			 }
@@ -733,7 +712,7 @@ return declare("dojox.widget.Standby", [_Widget, _TemplatedMixin],{
 					 this._oldBodyParentOverflow = body.parentNode.style.overflow;
 				 }else{
 					 try{
-						this._oldBodyParentOverflow = domStyle.set(body.parentNode, "overflow");
+						this._oldBodyParentOverflow = domStyle.get(body.parentNode, "overflow");
 					 }catch(e){
 						 this._oldBodyParentOverflow = "scroll";
 					 }
diff --git a/dojox/widget/TitleGroup.js b/dojox/widget/TitleGroup.js
index e06cccf..e04e37c 100644
--- a/dojox/widget/TitleGroup.js
+++ b/dojox/widget/TitleGroup.js
@@ -10,7 +10,8 @@ define(["dojo", "dijit/registry", "dijit/_Widget", "dijit/TitlePane"], function(
 	
 	// this might hide this uberprivate function from the docparser.
 	tp._dxfindParent = function(){
-		// summary: TitlePane's MUST be first-children of a TitleGroup. only used by
+		// summary:
+		//		TitlePane's MUST be first-children of a TitleGroup. only used by
 		//		`dojox.widget.TitleGroup`. Finds a possible parent TitleGroup of a TitlePane
 		var n = this.domNode.parentNode;
 		if(n){
@@ -31,16 +32,15 @@ define(["dojo", "dijit/registry", "dijit/_Widget", "dijit/TitlePane"], function(
 	});
 		
 	return dojo.declare("dojox.widget.TitleGroup", dijit._Widget, {
-		// summary: A container which controls a series of `dijit.TitlePane`s,
+		// summary:
+		//		A container which controls a series of `dijit.TitlePane`s,
 		//		allowing one to be visible and hiding siblings
-		//
 		// description:
 		//		A container which controls a series of `dijit.TitlePane`s,
 		//		allowing one to be visible and hiding siblings. Behaves similarly
 		//		to a `dijit.layout.AccordionContainer` in that the children
 		//		are all stacked, though merges the TitlePane behavior of
 		//		variable height
-		//
 		// example:
 		//	|	var group = new dojox.widget.TitleGroup().placeAt(dojo.body());
 		//	|	new dijit.TitlePane({ title:"One" }, "fromsource").placeAt(group);
@@ -49,18 +49,19 @@ define(["dojo", "dijit/registry", "dijit/_Widget", "dijit/TitlePane"], function(
 		"class":"dojoxTitleGroup",
 
 		addChild: function(widget, position){
-			// summary: Add a passed widget reference to this container at an optional
+			// summary:
+			//		Add a passed widget reference to this container at an optional
 			//		position index.
-			//
 			// widget: dijit.TitlePane
 			//		A widget reference to add
-			// position: String?|Int?
+			// position: String|Int?
 			//		An optional index or position to pass. defaults to "last"
 			return widget.placeAt(this.domNode, position); // dijit.TitlePane
 		},
 		
 		removeChild: function(widget){
-			// summary: Remove the passed widget from this container. Does not destroy
+			// summary:
+			//		Remove the passed widget from this container. Does not destroy
 			//		child.
 			
 			this.domNode.removeChild(widget.domNode);
@@ -68,13 +69,14 @@ define(["dojo", "dijit/registry", "dijit/_Widget", "dijit/TitlePane"], function(
 		},
 		
 		selectChild: function(widget){
-			// summary: close all found titlePanes within this group, excluding
-			// the one the we pass to select
+			// summary:
+			//		close all found titlePanes within this group, excluding
+			//		the one the we pass to select
 			widget && dojo.query("> .dijitTitlePane", this.domNode).forEach(function(n){
 				var tp = registry.byNode(n);
 				tp && tp !== widget && tp.open && tp.toggle(); // could race if open is set onEnd of slide
 			});
-			return widget; // dijit.TitlePane
+			return widget; // dijit/TitlePane
 		}
 	
 	});
diff --git a/dojox/widget/Toaster.js b/dojox/widget/Toaster.js
index bf87d5f..29fc9ae 100644
--- a/dojox/widget/Toaster.js
+++ b/dojox/widget/Toaster.js
@@ -65,10 +65,10 @@ define([
 
 		// slideDuration: Integer
 		//		Number of milliseconds for the slide animation, increasing will cause the Toaster
-		//    to slide in more slowly.
+		//		to slide in more slowly.
 		slideDuration: 500,
 
-		//separator: String
+		// separator: String
 		//		String used to separate messages if consecutive calls are made to setContent before previous messages go away
 		separator: "<hr></hr>",
 
@@ -244,6 +244,8 @@ define([
 				style.left = (view.w - nodeSize.w - 1 - view.l)+"px";
 			}else if(pd.match(/^[tb]l-/)){
 				style.left = 0 + "px";
+			}else if(pd.match(/^[tb]c-/)){
+				style.left = Math.round((view.w - nodeSize.w - 1 - view.l)/2)+"px";
 			}
 
 			style.clip = "rect(0px, " + nodeSize.w + "px, " + nodeSize.h + "px, 0px)";
@@ -258,11 +260,13 @@ define([
 		},
 
 		onSelect: function(/*Event*/e){
-			// summary: callback for when user clicks the message
+			// summary:
+			//		callback for when user clicks the message
 		},
 
 		show: function(){
-			// summary: show the Toaster
+			// summary:'
+			//		show the Toaster
 			domStyle.set(this.domNode, 'display', 'block');
 
 			this._placeClip();
@@ -273,7 +277,8 @@ define([
 		},
 
 		hide: function(){
-			// summary: hide the Toaster
+			// summary:
+			//		hide the Toaster
 
 			domStyle.set(this.domNode, 'display', 'none');
 
diff --git a/dojox/widget/Toaster/Toaster.css b/dojox/widget/Toaster/Toaster.css
index 5ac90b5..3418d08 100644
--- a/dojox/widget/Toaster/Toaster.css
+++ b/dojox/widget/Toaster/Toaster.css
@@ -10,7 +10,7 @@
 	color:#fff;
 }
 
-.dijitToasterWarning{ }
+.dijitToasterWarning,
 .dijitToasterError,
 .dijitToasterFatal{
 	font-weight:bold;
diff --git a/dojox/widget/UpgradeBar.js b/dojox/widget/UpgradeBar.js
index cb3820e..7da969d 100755
--- a/dojox/widget/UpgradeBar.js
+++ b/dojox/widget/UpgradeBar.js
@@ -1,70 +1,85 @@
-dojo.provide("dojox.widget.UpgradeBar");
-
-dojo.require("dojo.window");
-dojo.require("dojo.fx");
-dojo.require("dojo.cookie");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
+define([
+	"dojo/_base/kernel", // dojo.eval
+	"dojo/_base/array", // array.forEach
+	"dojo/_base/connect", // connect
+	"dojo/_base/declare", // declare
+	"dojo/_base/fx", // baseFx.animateProperty
+	"dojo/_base/lang", // lang.mixin, lang.hitch
+	"dojo/_base/sniff", // has("ie")
+	"dojo/_base/window", // baseWin.body
+	"dojo/dom-attr", // domAttr.get
+	"dojo/dom-class", // domClass.addClass, domClass.removeClass
+	"dojo/dom-construct", // domConstruct.destroy
+	"dojo/dom-geometry", // domGeo.getContentBox
+	"dojo/dom-style", // style.get, style.set
+	"dojo/cache", // cache
+	"dojo/cookie", // cookie
+	"dojo/domReady", // domReady
+	"dojo/fx", // fx.combine
+	"dojo/window", // win.getBox
+	"dijit/_WidgetBase", // _WidgetBase
+	"dijit/_TemplatedMixin" // _TemplatedMixin
+], function(dojo, array, connect, declare, baseFx, lang, has, baseWin,
+            domAttr, domClass, domConstruct, domGeo, style, cache, cookie,
+            domReady, fx, win, _WidgetBase, _TemplatedMixin){
 
 dojo.experimental("dojox.widget.UpgradeBar");
 
-
-dojo.declare("dojox.widget.UpgradeBar", [dijit._Widget, dijit._Templated], {
-	//	summary:
-	//				Shows a bar at the top of the screen when the user is to
-	//				be notified that they should upgrade their browser or a
-	//				plugin.
+var UpgradeBar = declare("dojox.widget.UpgradeBar", [_WidgetBase, _TemplatedMixin], {
+	// summary:
+	//		Shows a bar at the top of the screen when the user is to
+	//		be notified that they should upgrade their browser or a
+	//		plugin.
+	// description:
+	//		You can insert custom validations to trigger the UpgradeBar
+	//		to display. An evaluation of 'true' shows the bar (as this
+	//		version *is* less than it should be). Multiple validations
+	//		may be checked, although only the first in the list will be
+	//		displayed.
+	//		Markup and programmatic are supported. Markup is a little
+	//		cleaner, since a majority of the parameters are the HTML
+	//		snippets to be displayed. In markup, the validate code should
+	//		be an expression that will evaluate to true or false. This
+	//		expression is wrapped in a try/catch, so if it blows up, it
+	//		is assumed to be true and trigger the bar.
+	//		In programmatic, a function should be used that returns true
+	//		or false. You would need to use your own try/catch in that.
+	// example:
+	//		See tests for examples.
+
+
+	// notifications: Array
+	//		An array of objects that hold the criteria for upgrades:
 	//
-	//	description:
-	//				You can insert custom validations to trigger the UpgradeBar
-	//				to display. An evaluation of 'true' shows the bar (as this
-	//				version *is* less than it should be). Multiple validations
-	//				may be checked, although only the first in the list will be
-	//				displayed.
-	//				Markup and programmatic are supported. Markup is a little
-	//				cleaner, since a majority of the parameters are the HTML
-	//				snippets to be displayed. In markup, the validate code should
-	//				be an expression that will evaluate to true or false. This
-	//				expression is wrapped in a try/catch, so if it blows up, it
-	//				is assumed to be true and trigger the bar.
-	//				In programmtic, a function should be used that returns true
-	//				or false. You would need to use your own try/catch in that.
+	//		- message: String: The message to display in the bar. Can be HTML.
+	//		- validate: Function: The expression to evaluate to determine if the
+	//			bar should show or not. Should be a simple expression
+	//			if used in HTML:
 	//
-	//	example:	See tests for examples.
-	//
-	//	notifications: Array
-	//		An array of objects that hold the criteria for upgrades.
-	//			message: String
-	//				The message to display in the bar. Can be HTML.
-	//			validate:Function
-	//				The expression to evaluate to determine if the
-	//				bar should show or not. Should be a simple expression
-	//				if used in HTML:
-	//				|	<div validate="!google.gears">
-	//				|	<div validate="dojo.isIE<8">
+	//	|	<div validate="!google.gears">
+	//	|	<div validate="has('ie')<8">
 	notifications:[],
-	//
-	//	buttonCancel:String
+
+	// buttonCancel:String
 	//		The HTML tip show when hovering over the close button.
 	buttonCancel:"Close for now",
-	//
-	//	noRemindButton:String
+
+	// noRemindButton:String
 	//		The text link shown that when clicked, permanently dismisses
 	//		the message (sets a cookie). If this string is blank, this
 	//		link is not displayed.
 	noRemindButton:"Don't Remind Me Again",
 
-	templateString: dojo.cache("dojox.widget","UpgradeBar/UpgradeBar.html"),
+	templateString: cache("dojox.widget","UpgradeBar/UpgradeBar.html"),
 
 	constructor: function(props, node){
 
 		if(!props.notifications && node){
 			// From markup. Create the notifications Array from the
-			//	srcRefNode children.
-			dojo.forEach(node.childNodes, function(n){
+			// srcRefNode children.
+			array.forEach(node.childNodes, function(n){
 				if(n.nodeType==1){
-					var val = dojo.attr(n, "validate");
+					var val = domAttr.get(n, "validate");
 					this.notifications.push({
 						message:n.innerHTML,
 						validate:function(){
@@ -84,12 +99,12 @@ dojo.declare("dojox.widget.UpgradeBar", [dijit._Widget, dijit._Templated], {
 	},
 
 	checkNotifications: function(){
-		// 	summary:
-		//			Internal. Go through the notifications Array
-		//			and check for any that evaluate to true.
+		// summary:
+		//		Internal. Go through the notifications Array
+		//		and check for any that evaluate to true.
 		// tags:
 		//		private
-		//
+
 		if(!this.notifications.length){
 			// odd. why use the bar but not set any notifications?
 			return;
@@ -109,15 +124,15 @@ dojo.declare("dojox.widget.UpgradeBar", [dijit._Widget, dijit._Templated], {
 	postCreate: function(){
 		this.inherited(arguments);
 		if(this.domNode.parentNode){
-			dojo.style(this.domNode, "display", "none");
+			style.set(this.domNode, "display", "none");
 		}
-		dojo.mixin(this.attributeMap, {
+		lang.mixin(this.attributeMap, {
 			message:{ node:"messageNode", type:"innerHTML" }
 		});
 		if(!this.noRemindButton){
-			dojo.destroy(this.dontRemindButtonNode)
+			domConstruct.destroy(this.dontRemindButtonNode);
 		}
-		if(dojo.isIE==6){
+		if(has("ie")==6){
 			// IE6 is challenged when it comes to 100% width.
 			// It thinks the body has more padding and more
 			// margin than it really does. It would work to
@@ -126,33 +141,33 @@ dojo.declare("dojox.widget.UpgradeBar", [dijit._Widget, dijit._Templated], {
 			//
 			var self = this;
 			var setWidth = function(){
-				var v = dojo.window.getBox();
-				dojo.style(self.domNode, "width", v.w+"px");
-			}
+				var v = win.getBox();
+				style.set(self.domNode, "width", v.w+"px");
+			};
 			this.connect(window, "resize", function(){
 				setWidth();
 			});
 
 			setWidth();
 		}
-		dojo.addOnLoad(this, "checkNotifications");
+		domReady(lang.hitch(this, "checkNotifications"));
 		//this.checkNotifications();
 	},
 
 	notify: function(msg){
-		// 	summary:
+		// summary:
 		//		Triggers the bar to display. An internal function,
-		//		but could ne called externally for fun.
+		//		but could be called externally for fun.
 		// tags:
 		//		protected
-		//
-		if(dojo.cookie("disableUpgradeReminders")){
+
+		if(cookie("disableUpgradeReminders")){
 			return;
 		}
 		if(!this.domNode.parentNode || !this.domNode.parentNode.innerHTML){
 			document.body.appendChild(this.domNode);
 		}
-		dojo.style(this.domNode, "display", "");
+		style.set(this.domNode, "display", "");
 		if(msg){
 			this.set("message", msg);
 		}
@@ -160,36 +175,36 @@ dojo.declare("dojox.widget.UpgradeBar", [dijit._Widget, dijit._Templated], {
 	},
 
 	show: function(){
-		//	summary:
+		// summary:
 		//		Internal. Shows the bar. Do not call directly.
 		//		Use notify();
 		// tags:
 		//		private
-		//
-		this._bodyMarginTop = dojo.style(dojo.body(), "marginTop");
-		this._size = dojo.contentBox(this.domNode).h;
-		dojo.style(this.domNode, { display:"block", height:0, opacity:0 });
+
+		this._bodyMarginTop = style.get(baseWin.body(), "marginTop");
+		this._size = domGeo.getContentBox(this.domNode).h;
+		style.set(this.domNode, { display:"block", height:0, opacity:0 });
 
 		if(!this._showAnim){
-			this._showAnim = dojo.fx.combine([
-				dojo.animateProperty({ node:dojo.body(), duration:500, properties:{ marginTop:this._bodyMarginTop+this._size } }),
-				dojo.animateProperty({ node:this.domNode, duration:500, properties:{ height:this._size, opacity:1 } })
+			this._showAnim = fx.combine([
+				baseFx.animateProperty({ node:baseWin.body(), duration:500, properties:{ marginTop:this._bodyMarginTop+this._size } }),
+				baseFx.animateProperty({ node:this.domNode, duration:500, properties:{ height:this._size, opacity:1 } })
 			]);
 		}
 		this._showAnim.play();
 	},
 
 	hide: function(){
-		//	summary:
+		// summary:
 		//		Hides the bar. May be called externally.
-		//
+
 		if(!this._hideAnim){
-			this._hideAnim = dojo.fx.combine([
-				dojo.animateProperty({ node:dojo.body(), duration:500, properties:{ marginTop:this._bodyMarginTop } }),
-				dojo.animateProperty({ node:this.domNode, duration:500, properties:{ height:0, opacity:0 } })
+			this._hideAnim = fx.combine([
+				baseFx.animateProperty({ node:baseWin.body(), duration:500, properties:{ marginTop:this._bodyMarginTop } }),
+				baseFx.animateProperty({ node:this.domNode, duration:500, properties:{ height:0, opacity:0 } })
 			]);
-			dojo.connect(this._hideAnim, "onEnd", this, function(){
-				dojo.style(this.domNode, "display", "none");
+			connect.connect(this._hideAnim, "onEnd", this, function(){
+				style.set(this.domNode, {display:"none", opacity:1});
 			});
 		}
 		this._hideAnim.play();
@@ -200,7 +215,7 @@ dojo.declare("dojox.widget.UpgradeBar", [dijit._Widget, dijit._Templated], {
 		//		Called when user clicks the "do not remind" link.
 		// tags:
 		//		private
-		dojo.cookie("disableUpgradeReminders", true, { expires:3650 });
+		cookie("disableUpgradeReminders", true, { expires:3650 });
 		this.hide();
 	},
 
@@ -209,7 +224,7 @@ dojo.declare("dojox.widget.UpgradeBar", [dijit._Widget, dijit._Templated], {
 		//		Called when user hovers over close icon
 		// tags:
 		//		private
-		dojo.addClass(this.closeButtonNode, "dojoxUpgradeBarCloseIcon-hover");
+		domClass.add(this.closeButtonNode, "dojoxUpgradeBarCloseIcon-hover");
 	},
 
 	_onCloseLeave: function(){
@@ -217,7 +232,10 @@ dojo.declare("dojox.widget.UpgradeBar", [dijit._Widget, dijit._Templated], {
 		//		Called when user stops hovering over close icon
 		// tags:
 		//		private
-		dojo.removeClass(this.closeButtonNode, "dojoxUpgradeBarCloseIcon-hover");
+		domClass.remove(this.closeButtonNode, "dojoxUpgradeBarCloseIcon-hover");
 	}
+});
+
 
+return UpgradeBar;
 });
diff --git a/dojox/widget/Wizard.js b/dojox/widget/Wizard.js
index 8ac0665..ddc0d59 100644
--- a/dojox/widget/Wizard.js
+++ b/dojox/widget/Wizard.js
@@ -3,21 +3,19 @@ define([
 	"dojo/_base/declare",
 	"dojo/_base/connect",
 	"dijit/layout/StackContainer",
-	"dijit/layout/ContentPane",
-	"dijit/form/Button",
 	"dijit/_TemplatedMixin",
 	"dijit/_WidgetsInTemplateMixin",
 	"dojo/i18n",
 	"dojo/text!./Wizard/Wizard.html",
 	"dojo/i18n!dijit/nls/common",
-	"dojo/i18n!./nls/Wizard"
-], function (lang, declare, connect, StackContainer, ContentPane, Button, _TemplatedMixin, _WidgetsInTemplateMixin, i18n, template) {
+	"dojo/i18n!./nls/Wizard",
+	"dijit/form/Button"		// used by template
+], function (lang, declare, connect, StackContainer, _TemplatedMixin, _WidgetsInTemplateMixin, i18n, template) {
   
 var Wizard = declare("dojox.widget.Wizard", [StackContainer, _TemplatedMixin, _WidgetsInTemplateMixin], {
 	// summary:
 	//		A set of panels that display sequentially, typically notating a step-by-step
 	//		procedure like an install
-	//
 	
 	templateString: template,
 	
@@ -115,14 +113,16 @@ var Wizard = declare("dojox.widget.Wizard", [StackContainer, _TemplatedMixin, _W
 	},
 
 	_forward: function(){
-		// summary: callback when next button is clicked
+		// summary:
+		//		callback when next button is clicked
 		if(this.selectedChildWidget._checkPass()){
 			this.forward();
 		}
 	},
 	
 	done: function(){
-		// summary: Finish the wizard's operation
+		// summary:
+		//		Finish the wizard's operation
 		this.selectedChildWidget.done();
 	},
 	
@@ -133,75 +133,5 @@ var Wizard = declare("dojox.widget.Wizard", [StackContainer, _TemplatedMixin, _W
 	
 });
 
-declare("dojox.widget.WizardPane", ContentPane, {
-	// summary: A panel in a `dojox.widget.Wizard`
-	//
-	// description:
-	//	An extended ContentPane with additional hooks for passing named
-	//	functions to prevent the pane from going either forward or
-	//	backwards.
-	//
-	// canGoBack: Boolean
-	//		If true, then can move back to a previous panel (by clicking the "Previous" button)
-	canGoBack: true,
-
-	// passFunction: String
-	//		Name of function that checks if it's OK to advance to the next panel.
-	//		If it's not OK (for example, mandatory field hasn't been entered), then
-	//		returns an error message (String) explaining the reason. Can return null (pass)
-	//		or a Boolean (true == pass)
-	passFunction: null,
-	
-	// doneFunction: String
-	//		Name of function that is run if you press the "Done" button from this panel
-	doneFunction: null,
-
-	startup: function(){
-		this.inherited(arguments);
-		if(this.isFirstChild){ this.canGoBack = false; }
-		if(lang.isString(this.passFunction)){
-			this.passFunction = lang.getObject(this.passFunction);
-		}
-		if(lang.isString(this.doneFunction) && this.doneFunction){
-			this.doneFunction = lang.getObject(this.doneFunction);
-		}
-	},
-
-	_onShow: function(){
-		if(this.isFirstChild){ this.canGoBack = false; }
-		this.inherited(arguments);
-	},
-
-	_checkPass: function(){
-		// summary:
-		//		Called when the user presses the "next" button.
-		//		Calls passFunction to see if it's OK to advance to next panel, and
-		//		if it isn't, then display error.
-		//		Returns true to advance, false to not advance. If passFunction
-		//		returns a string, it is assumed to be a custom error message, and
-		//		is alert()'ed
-		var r = true;
-		if(this.passFunction && lang.isFunction(this.passFunction)){
-			var failMessage = this.passFunction();
-			switch(typeof failMessage){
-				case "boolean":
-					r = failMessage;
-					break;
-				case "string":
-					alert(failMessage);
-					r = false;
-					break;
-			}
-		}
-		return r; // Boolean
-	},
-
-	done: function(){
-		if(this.doneFunction && lang.isFunction(this.doneFunction)){ this.doneFunction(); }
-	}
-
-});
-
 return Wizard;
-
 });
diff --git a/dojox/widget/WizardPane.js b/dojox/widget/WizardPane.js
new file mode 100644
index 0000000..37b30c0
--- /dev/null
+++ b/dojox/widget/WizardPane.js
@@ -0,0 +1,76 @@
+define([
+	"dojo/_base/lang",
+	"dojo/_base/declare",
+	"dijit/layout/ContentPane"
+], function(lang, declare, ContentPane){
+  
+return declare("dojox.widget.WizardPane", ContentPane, {
+	// summary:
+	//		A panel in a `dojox.widget.Wizard`
+	// description:
+	//		An extended ContentPane with additional hooks for passing named
+	//		functions to prevent the pane from going either forward or
+	//		backwards.
+
+	// canGoBack: Boolean
+	//		If true, then can move back to a previous panel (by clicking the "Previous" button)
+	canGoBack: true,
+
+	// passFunction: String
+	//		Name of function that checks if it's OK to advance to the next panel.
+	//		If it's not OK (for example, mandatory field hasn't been entered), then
+	//		returns an error message (String) explaining the reason. Can return null (pass)
+	//		or a Boolean (true == pass)
+	passFunction: null,
+	
+	// doneFunction: String
+	//		Name of function that is run if you press the "Done" button from this panel
+	doneFunction: null,
+
+	startup: function(){
+		this.inherited(arguments);
+		if(this.isFirstChild){ this.canGoBack = false; }
+		if(lang.isString(this.passFunction)){
+			this.passFunction = lang.getObject(this.passFunction);
+		}
+		if(lang.isString(this.doneFunction) && this.doneFunction){
+			this.doneFunction = lang.getObject(this.doneFunction);
+		}
+	},
+
+	_onShow: function(){
+		if(this.isFirstChild){ this.canGoBack = false; }
+		this.inherited(arguments);
+	},
+
+	_checkPass: function(){
+		// summary:
+		//		Called when the user presses the "next" button.
+		//		Calls passFunction to see if it's OK to advance to next panel, and
+		//		if it isn't, then display error.
+		//		Returns true to advance, false to not advance. If passFunction
+		//		returns a string, it is assumed to be a custom error message, and
+		//		is alert()'ed
+		var r = true;
+		if(this.passFunction && lang.isFunction(this.passFunction)){
+			var failMessage = this.passFunction();
+			switch(typeof failMessage){
+				case "boolean":
+					r = failMessage;
+					break;
+				case "string":
+					alert(failMessage);
+					r = false;
+					break;
+			}
+		}
+		return r; // Boolean
+	},
+
+	done: function(){
+		if(this.doneFunction && lang.isFunction(this.doneFunction)){ this.doneFunction(); }
+	}
+});
+
+});
+
diff --git a/dojox/widget/YearlyCalendar.js b/dojox/widget/YearlyCalendar.js
new file mode 100644
index 0000000..1e3f893
--- /dev/null
+++ b/dojox/widget/YearlyCalendar.js
@@ -0,0 +1,15 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarBase",
+	"./_CalendarYear"
+], function(declare, _CalendarBase, _CalendarYear){
+	return declare("dojox.widget.YearlyCalendar", [_CalendarBase, _CalendarYear], {
+		// summary:
+		//		A calendar with only a year view.
+		_makeDate: function(value){
+			var now = new Date();
+			now.setFullYear(value);
+			return now;
+		}
+	});
+});
diff --git a/dojox/widget/_CalendarBase.js b/dojox/widget/_CalendarBase.js
new file mode 100644
index 0000000..e75688a
--- /dev/null
+++ b/dojox/widget/_CalendarBase.js
@@ -0,0 +1,385 @@
+define([
+	"dijit/_WidgetBase",
+	"dijit/_TemplatedMixin",
+	"dijit/_Container",
+	"dijit/_WidgetsInTemplateMixin",
+	"dijit/typematic",
+	"dojo/_base/declare",
+	"dojo/date",
+	"dojo/date/stamp",
+	"dojo/date/locale",
+	"dojo/dom-style",
+	"dojo/dom-class",
+	"dojo/_base/fx",
+	"dojo/on",
+	"dojo/_base/array",
+	"dojo/_base/lang",
+	"dojo/text!./Calendar/Calendar.html"
+], function(_WidgetBase, _TemplatedMixin, _Container, _WidgetsInTemplateMixin, dijitTypematic,
+		declare, dojoDate, stamp, dojoDateLocale, domStyle, domClass, fx, on, array, lang, template){
+	return declare("dojox.widget._CalendarBase", [_WidgetBase, _TemplatedMixin, _Container, _WidgetsInTemplateMixin], {
+		// summary:
+		//		The Root class for all _Calendar extensions
+
+		// templateString: String
+		//		The template to be used to construct the widget.
+		templateString: template,
+
+		// _views: Array
+		//		The list of mixin views available on this calendar.
+		_views: null,
+
+		// useFx: Boolean
+		//		Specifies if visual effects should be applied to the widget.
+		//		The default behavior of the widget does not contain any effects.
+		//		The dojox.widget.CalendarFx package is needed for these.
+		useFx: true,
+
+		// value: Date
+		//		The currently selected Date
+		value: new Date(),
+
+		constraints: null,
+
+		// footerFormat: String
+		//		The date format of the date displayed in the footer.	Can be
+		//		'short', 'medium', and 'long'
+		footerFormat: "medium",
+
+		constructor: function(){
+			this._views = [];
+			this.value = new Date();
+		},
+
+		_setConstraintsAttr: function(constraints){
+			// summary:
+			//		Sets minimum and maximum constraints
+			var c = this.constraints = constraints;
+			if(c){
+				if(typeof c.min == "string"){
+					c.min = stamp.fromISOString(c.min);
+				}
+				if(typeof c.max == "string"){
+					c.max = stamp.fromISOString(c.max);
+				}
+			}
+		},
+
+		postMixInProperties: function () {
+			this.inherited(arguments);
+			this.value = this.parseInitialValue(this.value);
+		},
+
+		parseInitialValue: function(value){
+			if (!value || value === -1){
+				return new Date();
+			}else if(value.getFullYear){
+				return value;
+			}else if (!isNaN(value)) {
+				if (typeof this.value == "string") {
+					value = parseInt(value);
+				}
+				value = this._makeDate(value);
+			}
+			return value;
+		},
+
+		_makeDate: function(value){
+			return value;//new Date(value);
+		},
+
+		postCreate: function(){
+			// summary:
+			//		Instantiates the mixin views
+
+			this.displayMonth = new Date(this.get('value'));
+
+			if(this._isInvalidDate(this.displayMonth)){
+				this.displayMonth = new Date();
+			}
+
+			var mixin = {
+				parent: this,
+				_getValueAttr: lang.hitch(this, function(){return new Date(this._internalValue || this.value);}),
+				_getDisplayMonthAttr: lang.hitch(this, function(){return new Date(this.displayMonth);}),
+				_getConstraintsAttr: lang.hitch(this, function(){return this.constraints;}),
+				getLang: lang.hitch(this, function(){return this.lang;}),
+				isDisabledDate: lang.hitch(this, this.isDisabledDate),
+				getClassForDate: lang.hitch(this, this.getClassForDate),
+				addFx: this.useFx ? lang.hitch(this, this.addFx) : function(){}
+			};
+
+			//Add the mixed in views.
+			array.forEach(this._views, function(widgetType){
+				var widget = new widgetType(mixin).placeAt(this);
+
+				var header = widget.getHeader();
+				if(header){
+				//place the views's header node in the header of the main widget
+					this.header.appendChild(header);
+
+					//hide the header node of the widget
+					domStyle.set(header, "display", "none");
+				}
+				//Hide all views
+				domStyle.set(widget.domNode, "visibility", "hidden");
+
+				//Listen for the values in a view to be selected
+				widget.on("valueSelected", lang.hitch(this, "_onDateSelected"));
+				widget.set("value", this.get('value'));
+			}, this);
+
+			if(this._views.length < 2){
+				domStyle.set(this.header, "cursor", "auto");
+			}
+
+			this.inherited(arguments);
+
+			// Cache the list of children widgets.
+			this._children = this.getChildren();
+
+			this._currentChild = 0;
+
+			//Populate the footer with today's date.
+			var today = new Date();
+
+			this.footer.innerHTML = "Today: "
+				+ dojoDateLocale.format(today, {
+					formatLength:this.footerFormat,
+					selector:'date',
+					locale:this.lang});
+
+			on(this.footer, "click", lang.hitch(this, "goToToday"));
+
+			var first = this._children[0];
+
+			domStyle.set(first.domNode, "top", "0px");
+			domStyle.set(first.domNode, "visibility", "visible");
+
+			var header = first.getHeader();
+			if(header){
+				domStyle.set(first.getHeader(), "display", "");
+			}
+
+			domClass.toggle(this.container, "no-header", !first.useHeader);
+
+			first.onDisplay();
+
+			var _this = this;
+
+			var typematic = function(nodeProp, dateProp, adj){
+				dijitTypematic.addMouseListener(_this[nodeProp], _this, function(count){
+					if(count >= 0){	_this._adjustDisplay(dateProp, adj);}
+				}, 0.8, 500);
+			};
+			typematic("incrementMonth", "month", 1);
+			typematic("decrementMonth", "month", -1);
+			this._updateTitleStyle();
+		},
+
+		addFx: function(query, fromNode){
+			// Stub function than can be overridden to add effects.
+		},
+
+		_isInvalidDate: function(/*Date*/ value){
+			// summary:
+			//		Runs various tests on the value, checking for invalid conditions
+			// tags:
+			//		private
+			return !value || isNaN(value) || typeof value != "object" || value.toString() == this._invalidDate;
+		},
+
+		_setValueAttr: function(/*Date*/ value){
+			// summary:
+			//		Set the current date and update the UI.	If the date is disabled, the selection will
+			//		not change, but the display will change to the corresponding month.
+			if(!value){
+				value = new Date();
+			}
+			if(!value["getFullYear"]){
+				value = stamp.fromISOString(value + "");
+			}
+			if(this._isInvalidDate(value)){
+				return false;
+			}
+			if(!this.value || dojoDate.compare(value, this.value)){
+				value = new Date(value);
+				this.displayMonth = new Date(value);
+				this._internalValue = value;
+				if(!this.isDisabledDate(value, this.lang) && this._currentChild == 0){
+					this.value = value;
+					this.onChange(value);
+				}
+				if (this._children && this._children.length > 0) {
+					this._children[this._currentChild].set("value", this.value);
+				}
+				return true;
+			}
+			return false;
+		},
+
+		isDisabledDate: function(/*Date*/date, /*String?*/locale){
+			// summary:
+			//		May be overridden to disable certain dates in the calendar e.g. `isDisabledDate=dojo.date.locale.isWeekend`
+			var c = this.constraints;
+			var compare = dojoDate.compare;
+			return c && (c.min && (compare(c.min, date, "date") > 0) ||
+								(c.max && compare(c.max, date, "date") < 0));
+		},
+
+		onValueSelected: function(/*Date*/date){
+			// summary:
+			//		A date cell was selected. It may be the same as the previous value.
+		},
+
+		_onDateSelected: function(date, formattedValue, force){
+			this.displayMonth = date;
+
+			this.set("value", date);
+			//Only change the selected value if it was chosen from the
+			//first child.
+			if(!this._transitionVert(-1)){
+				if(!formattedValue && formattedValue !== 0){
+					formattedValue = this.get('value');
+				}
+				this.onValueSelected(formattedValue);
+			}
+
+		},
+
+		onChange: function(/*Date*/date){
+			// summary:
+			//		Called only when the selected date has changed
+		},
+
+		onHeaderClick: function(e){
+			// summary:
+			//		Transitions to the next view.
+			this._transitionVert(1);
+		},
+
+		goToToday: function(){
+			this.set("value", new Date());
+			this.onValueSelected(this.get('value'));
+		},
+
+		_transitionVert: function(/*Number*/direction){
+			// summary:
+			//		Animates the views to show one and hide another, in a
+			//		vertical direction.
+			//		If 'direction' is 1, then the views slide upwards.
+			//		If 'direction' is -1, the views slide downwards.
+			var curWidget = this._children[this._currentChild];
+			var nextWidget = this._children[this._currentChild + direction];
+			if(!nextWidget){return false;}
+
+			domStyle.set(nextWidget.domNode, "visibility", "visible");
+
+			var height = domStyle.get(this.containerNode, "height");
+			nextWidget.set("value", this.displayMonth);
+
+			if(curWidget.header){
+				domStyle.set(curWidget.header, "display", "none");
+			}
+			if(nextWidget.header){
+				domStyle.set(nextWidget.header, "display", "");
+			}
+			domStyle.set(nextWidget.domNode, "top", (height * -1) + "px");
+			domStyle.set(nextWidget.domNode, "visibility", "visible");
+
+			this._currentChild += direction;
+
+			var height1 = height * direction;
+			var height2 = 0;
+			domStyle.set(nextWidget.domNode, "top", (height1 * -1) + "px");
+
+			// summary:
+			//		Slides two nodes vertically.
+			var anim1 = fx.animateProperty({
+				node: curWidget.domNode,
+				properties: {top: height1},
+				onEnd: function(){
+					domStyle.set(curWidget.domNode, "visibility", "hidden");
+				}
+			});
+			var anim2 = fx.animateProperty({
+				node: nextWidget.domNode,
+				properties: {top: height2},
+				onEnd: function(){
+					nextWidget.onDisplay();
+				}
+			});
+
+			domClass.toggle(this.container, "no-header", !nextWidget.useHeader);
+
+			anim1.play();
+			anim2.play();
+			curWidget.onBeforeUnDisplay();
+			nextWidget.onBeforeDisplay();
+
+			this._updateTitleStyle();
+			return true;
+		},
+
+		_updateTitleStyle: function(){
+			domClass.toggle(this.header, "navToPanel", this._currentChild < this._children.length -1);
+		},
+
+		_slideTable: function(/*String*/widget, /*Number*/direction, /*Function*/callback){
+			// summary:
+			//		Animates the horizontal sliding of a table.
+			var table = widget.domNode;
+
+			//Clone the existing table
+			var newTable = table.cloneNode(true);
+			var left = domStyle.get(table, "width");
+
+			table.parentNode.appendChild(newTable);
+
+			//Place the existing node either to the left or the right of the new node,
+			//depending on which direction it is to slide.
+			domStyle.set(table, "left", (left * direction) + "px");
+
+			//Call the function that generally populates the new cloned node with new data.
+			//It may also attach event listeners.
+			callback();
+
+			//Animate the two nodes.
+			var anim1 = fx.animateProperty({node: newTable, properties:{left: left * direction * -1}, duration: 500, onEnd: function(){
+				newTable.parentNode.removeChild(newTable);
+			}});
+			var anim2 = fx.animateProperty({node: table, properties:{left: 0}, duration: 500});
+
+			anim1.play();
+			anim2.play();
+		},
+
+		_addView: function(view){
+			//Insert the view at the start of the array.
+			this._views.push(view);
+		},
+
+		getClassForDate: function(/*Date*/dateObject, /*String?*/locale){
+			// summary:
+			//		May be overridden to return CSS classes to associate with the date entry for the given dateObject,
+			//		for example to indicate a holiday in specified locale.
+
+	/*=====
+			return ""; // String
+	=====*/
+		},
+
+		_adjustDisplay: function(/*String*/part, /*int*/amount, noSlide){
+			// summary:
+			//		This function overrides the base function defined in dijit/Calendar.
+			//		It changes the displayed years, months and days depending on the inputs.
+			var child = this._children[this._currentChild];
+
+			var month = this.displayMonth = child.adjustDate(this.displayMonth, amount);
+
+			this._slideTable(child, amount, function(){
+				child.set("value", month);
+			});
+		}
+	});
+});
diff --git a/dojox/widget/_CalendarDay.js b/dojox/widget/_CalendarDay.js
new file mode 100644
index 0000000..b9b8eea
--- /dev/null
+++ b/dojox/widget/_CalendarDay.js
@@ -0,0 +1,15 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarDayView"
+], function(declare, _CalendarDayView){
+	return declare("dojox.widget._CalendarDay", null, {
+		// summary:
+		//		Mixin for the dojox.widget.Calendar which provides
+		//		the standard day-view. A single month is shown at a time.
+		parent: null,
+
+		constructor: function(){
+			this._addView(_CalendarDayView);
+		}
+	});
+});
diff --git a/dojox/widget/_CalendarDayView.js b/dojox/widget/_CalendarDayView.js
new file mode 100644
index 0000000..66ef023
--- /dev/null
+++ b/dojox/widget/_CalendarDayView.js
@@ -0,0 +1,188 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarView",
+	"dijit/_TemplatedMixin",
+	"dojo/query",
+	"dojo/dom-class",
+	"dojo/_base/event",
+	"dojo/date",
+	"dojo/date/locale",
+	"dojo/text!./Calendar/CalendarDay.html",
+	"dojo/cldr/supplemental",
+	"dojo/NodeList-dom"
+], function(declare, _CalendarView, _TemplatedMixin, query, domClass, event, date, locale, template, supplemental){
+	return declare("dojox.widget._CalendarDayView", [_CalendarView, _TemplatedMixin], {
+		// summary:
+		//		View class for the dojox/widget/Calendar.
+		//		Adds a view showing every day of a single month to the calendar.
+		//		This should not be mixed in directly with dojox/widget._CalendarBase.
+		//		Instead, use dojox/widget._CalendarDay
+
+		// templateString: String
+		//		The template to be used to construct the widget.
+		templateString: template,
+
+		// datePart: String
+		//		Specifies how much to increment the displayed date when the user
+		//		clicks the array button to increment of decrement the view.
+		datePart: "month",
+
+		// dayWidth: String
+		//		Specifies the type of day name to display.	"narrow" causes just one letter to be shown.
+		dayWidth: "narrow",
+
+		postCreate: function(){
+			// summary:
+			//		Constructs the calendar view.
+			this.cloneClass(".dijitCalendarDayLabelTemplate", 6);
+			this.cloneClass(".dijitCalendarDateTemplate", 6);
+
+			// now make 6 week rows
+			this.cloneClass(".dijitCalendarWeekTemplate", 5);
+
+			// insert localized day names in the header
+			var dayNames = locale.getNames('days', this.dayWidth, 'standAlone', this.getLang());
+			var dayOffset = supplemental.getFirstDayOfWeek(this.getLang());
+
+			// Set the text of the day labels.
+			query(".dijitCalendarDayLabel", this.domNode).forEach(function(label, i){
+				this._setText(label, dayNames[(i + dayOffset) % 7]);
+			}, this);
+		},
+
+		onDisplay: function(){
+			if(!this._addedFx){
+			// Add visual effects to the view, if any has been specified.
+				this._addedFx = true;
+				this.addFx(".dijitCalendarDateTemplate div", this.domNode);
+			}
+		},
+
+		// TODO: This method needs serious work
+		_onDayClick: function(/*Event*/ e){
+			// summary:
+			//		Executed when a day value is clicked.
+
+			// If the user somehow clicked the TR, rather than a
+			// cell, ignore it.
+			if(typeof(e.target._date) == "undefined"){return;}
+
+			var displayMonth = new Date(this.get("displayMonth"));
+
+			var p = e.target.parentNode;
+			var c = "dijitCalendar";
+			var d = domClass.contains(p, c + "PreviousMonth") ? -1 :
+								(domClass.contains(p, c + "NextMonth") ? 1 : 0);
+			if(d){displayMonth = date.add(displayMonth, "month", d);}
+			displayMonth.setDate(e.target._date);
+
+			// If the day is disabled, ignore it
+			if(this.isDisabledDate(displayMonth)){
+				event.stop(e);
+				return;
+			}
+			this.parent._onDateSelected(displayMonth);
+		},
+
+		_setValueAttr: function(value){
+			//Change the day values
+			this._populateDays();
+		},
+
+		_populateDays: function(){
+			// summary:
+			//		Fills the days of the current month.
+
+			var currentDate = new Date(this.get("displayMonth"));
+			currentDate.setDate(1);
+			var firstDay = currentDate.getDay();
+			var daysInMonth = date.getDaysInMonth(currentDate);
+			var daysInPreviousMonth = date.getDaysInMonth(date.add(currentDate, "month", -1));
+			var today = new Date();
+			var selected = this.get('value');
+
+			var dayOffset = supplemental.getFirstDayOfWeek(this.getLang());
+			if(dayOffset > firstDay){ dayOffset -= 7; }
+
+			var compareDate = date.compare;
+			var templateCls = ".dijitCalendarDateTemplate";
+			var selectedCls = "dijitCalendarSelectedDate";
+
+			var oldDate = this._lastDate;
+			var redrawRequired = oldDate == null
+					|| oldDate.getMonth() != currentDate.getMonth()
+					|| oldDate.getFullYear() != currentDate.getFullYear();
+			this._lastDate = currentDate;
+
+			// If still showing the same month, it's much faster to not redraw,
+			// and just change the selected date.
+			if(!redrawRequired){
+				query(templateCls, this.domNode)
+						.removeClass(selectedCls)
+						.filter(function(node){
+							return node.className.indexOf("dijitCalendarCurrent") > -1
+										&& node._date == selected.getDate();
+						})
+						.addClass(selectedCls);
+				return;
+			}
+
+			// Iterate through dates in the calendar and fill in date numbers and style info
+			query(templateCls, this.domNode).forEach(function(template, i){
+				i += dayOffset;
+				var eachDate = new Date(currentDate);
+				var number, clazz = "dijitCalendar", adj = 0;
+
+				if(i < firstDay){
+					number = daysInPreviousMonth - firstDay + i + 1;
+					adj = -1;
+					clazz += "Previous";
+				}else if(i >= (firstDay + daysInMonth)){
+					number = i - firstDay - daysInMonth + 1;
+					adj = 1;
+					clazz += "Next";
+				}else{
+					number = i - firstDay + 1;
+					clazz += "Current";
+				}
+
+				if(adj){
+					eachDate = date.add(eachDate, "month", adj);
+				}
+				eachDate.setDate(number);
+
+				if(!compareDate(eachDate, today, "date")){
+					clazz = "dijitCalendarCurrentDate " + clazz;
+				}
+
+				if(!compareDate(eachDate, selected, "date")
+						&& !compareDate(eachDate, selected, "month")
+						&& !compareDate(eachDate, selected, "year") ){
+					clazz = selectedCls + " " + clazz;
+				}
+
+				if(this.isDisabledDate(eachDate, this.getLang())){
+					clazz = " dijitCalendarDisabledDate " + clazz;
+				}
+
+				var clazz2 = this.getClassForDate(eachDate, this.getLang());
+				if(clazz2){
+					clazz = clazz2 + " " + clazz;
+				}
+
+				template.className = clazz + "Month dijitCalendarDateTemplate";
+				template.dijitDateValue = eachDate.valueOf();
+				var label = query(".dijitCalendarDateLabel", template)[0];
+
+				this._setText(label, eachDate.getDate());
+
+				label._date = label.parentNode._date = eachDate.getDate();
+			}, this);
+
+			// Fill in localized month name
+			var monthNames = locale.getNames('months', 'wide', 'standAlone', this.getLang());
+			this._setText(this.monthLabelNode, monthNames[currentDate.getMonth()]);
+			this._setText(this.yearLabelNode, currentDate.getFullYear());
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/widget/_CalendarMonth.js b/dojox/widget/_CalendarMonth.js
new file mode 100644
index 0000000..d44cf5f
--- /dev/null
+++ b/dojox/widget/_CalendarMonth.js
@@ -0,0 +1,16 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarMonthView"
+], function(declare, _CalendarMonthView){
+	return declare("dojox.widget._CalendarMonth", null, {
+		// summary:
+		//		Mixin class for adding a view listing all 12 months of the year to the
+		//		dojox/widget/_CalendarBase
+
+		constructor: function(){
+			// summary:
+			//		Adds a dojox/widget/_CalendarMonthView view to the calendar widget.
+			this._addView(_CalendarMonthView);
+		}
+	});
+});
diff --git a/dojox/widget/_CalendarMonthView.js b/dojox/widget/_CalendarMonthView.js
new file mode 100644
index 0000000..750c128
--- /dev/null
+++ b/dojox/widget/_CalendarMonthView.js
@@ -0,0 +1,69 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarView",
+	"dijit/_TemplatedMixin",
+	"./_CalendarMonthYearView",
+	"dojo/dom-class",
+	"dojo/_base/event",
+	"dojo/text!./Calendar/CalendarMonth.html"
+], function(declare, _CalendarView, _TemplatedMixin, _CalendarMonthYearView, domClass, event, template){
+	return declare("dojox.widget._CalendarMonthView", [_CalendarView, _TemplatedMixin], {
+		// summary:
+		//		A Calendar view listing the 12 months of the year
+
+		// templateString: String
+		//		The template to be used to construct the widget.
+		templateString: template,
+
+		// datePart: String
+		//		Specifies how much to increment the displayed date when the user
+		//		clicks the array button to increment of decrement the view.
+		datePart: "year",
+
+		// headerClass: String
+		//		Specifies the CSS class to apply to the header node for this view.
+		headerClass: "dojoxCalendarMonthHeader",
+
+		// displayedYear: String 
+		//              The current year being displayed 
+		displayedYear: "", 
+
+		postCreate: function(){
+			// summary:
+			//		Constructs the view
+			this.cloneClass(".dojoxCalendarMonthTemplate", 3);
+			this.cloneClass(".dojoxCalendarMonthGroupTemplate", 2);
+			this._populateMonths();
+
+			// Add visual effects to the view, if any have been mixed in
+			this.addFx(".dojoxCalendarMonthLabel", this.domNode);
+		},
+
+		_setValueAttr: function(value){
+			var year = this.header.innerHTML = value.getFullYear(); 
+			// We should be keeping this info around, might as well expose it too. 
+			// Added while patching http://bugs.dojotoolkit.org/ticket/15520 
+			this.set("displayedYear", year); 
+			this._populateMonths(); 
+		},
+
+		_getMonthNames: _CalendarMonthYearView.prototype._getMonthNames,
+
+		_populateMonths: _CalendarMonthYearView.prototype._populateMonths,
+
+		onClick: function(evt){
+			// summary:
+			//		Handles clicks on month names
+			if(!domClass.contains(evt.target, "dojoxCalendarMonthLabel")){event.stop(evt); return;}
+			var parentNode = evt.target.parentNode;
+			var month = parentNode.cellIndex + (parentNode.parentNode.rowIndex * 4);
+			var date = this.get("value");
+			// Seeing a really strange bug in FF3.6 where this has to be called twice
+			// in order to take affect
+			date.setMonth(month);
+			date.setMonth(month);
+			date.setYear(this.displayedYear);
+			this.onValueSelected(date, month);
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/widget/_CalendarMonthYear.js b/dojox/widget/_CalendarMonthYear.js
new file mode 100644
index 0000000..3dc22c5
--- /dev/null
+++ b/dojox/widget/_CalendarMonthYear.js
@@ -0,0 +1,16 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarMonthYearView"
+], function(declare, _CalendarMonthYearView){
+	return declare("dojox.widget._CalendarMonthYear", null, {
+		// summary:
+		//		Mixin class for adding a view listing all 12
+		//		months of the year to the dojox/widget/_CalendarBase
+
+		constructor: function(){
+			// summary:
+			//		Adds a dojox/widget/_CalendarMonthView view to the calendar widget.
+			this._addView(_CalendarMonthYearView);
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/widget/_CalendarMonthYearView.js b/dojox/widget/_CalendarMonthYearView.js
new file mode 100644
index 0000000..055b452
--- /dev/null
+++ b/dojox/widget/_CalendarMonthYearView.js
@@ -0,0 +1,277 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarView",
+	"dijit/_TemplatedMixin",
+	"dojo/query",
+	"dojo/dom-class",
+	"dojo/_base/connect",
+	"dojo/_base/event",
+	"dojo/_base/lang",
+	"dojo/date/locale",
+	"dojo/text!./Calendar/CalendarMonthYear.html"
+], function(declare, _CalendarView, _TemplatedMixin, query, domClass, connect, event, lang, dojoDateLocale, template){
+	return declare("dojox.widget._CalendarMonthYearView", [_CalendarView, _TemplatedMixin], {
+
+		// summary:
+		//		A Calendar view listing the 12 months of the year
+
+		// templateString: String
+		//		The template to be used to construct the widget.
+		templateString: template,
+
+		// datePart: String
+		//		Specifies how much to increment the displayed date when the user
+		//		clicks the array button to increment of decrement the view.
+		datePart: "year",
+
+		// displayedYears: Number
+		//		The number of years to display at once.
+		displayedYears: 10,
+
+		useHeader: false,
+
+		postCreate: function(){
+			this.cloneClass(".dojoxCal-MY-G-Template", 5, ".dojoxCal-MY-btns");
+			this.monthContainer = this.yearContainer = this.myContainer;
+
+			var yClass = "dojoxCalendarYearLabel";
+			var dClass = "dojoxCalendarDecrease";
+			var iClass = "dojoxCalendarIncrease";
+
+			query("." + yClass, this.myContainer).forEach(function(node, idx){
+				var clazz = iClass;
+				switch(idx){
+					case 0:
+						clazz = dClass;
+					case 1:
+						domClass.remove(node, yClass);
+						domClass.add(node, clazz);
+						break;
+				}
+			});
+			// Get the year increment and decrement buttons.
+			this._decBtn = query('.' + dClass, this.myContainer)[0];
+			this._incBtn = query('.' + iClass, this.myContainer)[0];
+
+			query(".dojoxCal-MY-M-Template", this.domNode)
+				.filter(function(item){
+					return item.cellIndex == 1;
+				})
+				.addClass("dojoxCal-MY-M-last");
+
+			connect.connect(this, "onBeforeDisplay", lang.hitch(this, function(){
+				this._cachedDate = new Date(this.get("value").getTime());
+				this._populateYears(this._cachedDate.getFullYear());
+				this._populateMonths();
+				this._updateSelectedMonth();
+				this._updateSelectedYear();
+			}));
+
+			connect.connect(this, "_populateYears", lang.hitch(this, function(){
+				this._updateSelectedYear();
+			}));
+			connect.connect(this, "_populateMonths", lang.hitch(this, function(){
+				this._updateSelectedMonth();
+			}));
+
+			this._cachedDate = this.get("value");
+
+			this._populateYears();
+			this._populateMonths();
+
+			// Add visual effects to the view, if any have been mixed in
+			this.addFx(".dojoxCalendarMonthLabel,.dojoxCalendarYearLabel ", this.myContainer);
+		},
+
+		_setValueAttr: function(value){
+			if (value && value.getFullYear()) {
+				this._populateYears(value.getFullYear());
+			}
+		},
+
+		getHeader: function(){
+			return null;
+		},
+
+		_getMonthNames: function(format){
+			// summary:
+			//		Returns localized month names
+			this._monthNames	= this._monthNames || dojoDateLocale.getNames('months', format, 'standAlone', this.getLang());
+			return this._monthNames;
+		},
+
+		_populateMonths: function(){
+			// summary:
+			//		Populate the month names using the localized values.
+			var match,
+				monthNames = this._getMonthNames('abbr'),
+				currYear = this.get("value").getFullYear(),
+				currMonth = monthNames[this.get("value").getMonth()],
+				displayedYear = this.get("displayedYear");
+
+			query(".dojoxCalendarMonthLabel", this.monthContainer).forEach(lang.hitch(this, function(node, cnt){
+				this._setText(node, monthNames[cnt]);
+				match = ((currMonth === monthNames[cnt]) && (currYear === displayedYear));
+				// If this month in this year, style it accordingly.
+				// Don't use dojox/date stuff, we don't need it here
+				// http://bugs.dojotoolkit.org/ticket/15520
+				domClass.toggle(node.parentNode, ["dijitCalendarSelectedDate", "dijitCalendarCurrentDate"], match);
+			}));
+			var constraints = this.get('constraints');
+
+			if(constraints){
+				var date = new Date();
+				date.setFullYear(this._year);
+				var min = -1, max = 12;
+				if(constraints.min){
+					var minY = constraints.min.getFullYear();
+					if(minY > this._year){
+						min = 12;
+					}else if(minY == this._year){
+						min = constraints.min.getMonth();
+					}
+				}
+				if(constraints.max){
+					var maxY = constraints.max.getFullYear();
+					if(maxY < this._year){
+						max = -1;
+					}else if(maxY == this._year){
+						max = constraints.max.getMonth();
+					}
+				}
+
+				query(".dojoxCalendarMonthLabel", this.monthContainer)
+					.forEach(lang.hitch(this, function(node, cnt){
+						domClass[(cnt < min || cnt > max) ? "add" : "remove"]
+							(node, 'dijitCalendarDisabledDate');
+				}));
+			}
+		},
+
+		_populateYears: function(year){
+			// summary:
+			//		Fills the list of years with a range of 12 numbers, with the current year
+			//		being the 6th number.
+
+			var match,
+				constraints = this.get('constraints'),
+				thisYear = this.get("value").getFullYear(),
+				dispYear = year || thisYear,
+				firstYear = dispYear - Math.floor(this.displayedYears/2),
+				min = constraints && constraints.min ? constraints.min.getFullYear() : firstYear -10000;
+
+			this._displayedYear = dispYear;
+
+			var yearLabels = query(".dojoxCalendarYearLabel", this.yearContainer);
+
+			var max = constraints && constraints.max ? constraints.max.getFullYear() - firstYear :	yearLabels.length;
+			var disabledClass = 'dijitCalendarDisabledDate';
+			var today;
+			yearLabels.forEach(lang.hitch(this, function(node, cnt){
+				if(cnt <= max){
+					this._setText(node, firstYear + cnt);
+				}
+				today = (firstYear+cnt) == thisYear;
+				domClass.toggle(node.parentNode, ["dijitCalendarSelectedDate", "dijitCalendarCurrentDate"], today);
+				domClass.toggle(node, disabledClass, cnt > max);
+				match = (firstYear+cnt) == thisYear;
+				domClass.toggle(node.parentNode, ["dijitCalendarSelectedDate", "dijitCalendarCurrentDate"], match);
+			}));
+
+			if(this._incBtn){
+				domClass.toggle(this._incBtn, disabledClass, max < yearLabels.length);
+			}
+			if(this._decBtn){
+				domClass.toggle(this._decBtn, disabledClass, min >= firstYear);
+			}
+
+			var h = this.getHeader();
+			if(h){
+				this._setText(this.getHeader(), firstYear + " - " + (firstYear + 11));
+			}
+		},
+
+		_updateSelectedYear: function(){
+			this._year = String((this._cachedDate || this.get("value")).getFullYear());
+			this._updateSelectedNode(".dojoxCalendarYearLabel", lang.hitch(this, function(node){
+				return this._year !== null && node.innerHTML == this._year;
+			}));
+		},
+
+		_updateSelectedMonth: function(){
+			var month = (this._cachedDate || this.get("value")).getMonth();
+			this._month = month;
+			this._updateSelectedNode(".dojoxCalendarMonthLabel", function(node, idx){
+				return idx == month;
+			});
+		},
+
+		_updateSelectedNode: function(queryNode, filter){
+			var sel = "dijitCalendarSelectedDate";
+			query(queryNode, this.domNode)
+				.forEach(function(node, idx, array){
+					domClass.toggle(node.parentNode, sel, filter(node, idx, array));
+			});
+			var selMonth = query('.dojoxCal-MY-M-Template div', this.myContainer)
+				.filter(function(node){
+					return domClass.contains(node.parentNode, sel);
+			})[0];
+			if(!selMonth){return;}
+			var disabled = domClass.contains(selMonth, 'dijitCalendarDisabledDate');
+
+			domClass.toggle(this.okBtn, "dijitDisabled", disabled);
+		},
+
+		onClick: function(evt){
+			// summary:
+			//		Handles clicks on month names
+			var clazz;
+			function hc(c){
+				return domClass.contains(evt.target, c);
+			}
+
+			if(hc('dijitCalendarDisabledDate')){
+				event.stop(evt);
+				return false;
+			}
+
+			if(hc("dojoxCalendarMonthLabel")){
+				clazz = "dojoxCal-MY-M-Template";
+				this._month = evt.target.parentNode.cellIndex + (evt.target.parentNode.parentNode.rowIndex * 2);
+				this._cachedDate.setMonth(this._month);
+				this._updateSelectedMonth();
+			}else if(hc( "dojoxCalendarYearLabel")){
+				clazz = "dojoxCal-MY-Y-Template";
+				this._year = Number(evt.target.innerHTML);
+				this._cachedDate.setYear(this._year);
+				this._populateMonths();
+				this._updateSelectedYear();
+			}else if(hc("dojoxCalendarDecrease")){
+				this._populateYears(this._displayedYear - 10);
+				return true;
+			}else if(hc("dojoxCalendarIncrease")){
+				this._populateYears(this._displayedYear + 10);
+				return true;
+			}else{
+				return true;
+			}
+			event.stop(evt);
+			return false;
+		},
+
+		onOk: function(evt){
+			event.stop(evt);
+			if(domClass.contains(this.okBtn, "dijitDisabled")){
+				return false;
+			}
+			this.onValueSelected(this._cachedDate);
+			return false;
+		},
+
+		onCancel: function(evt){
+			event.stop(evt);
+			this.onValueSelected(this.get("value"));
+			return false;
+		}
+	});
+});
diff --git a/dojox/widget/_CalendarView.js b/dojox/widget/_CalendarView.js
new file mode 100644
index 0000000..530653f
--- /dev/null
+++ b/dojox/widget/_CalendarView.js
@@ -0,0 +1,80 @@
+define([
+	"dojo/_base/declare",
+	"dijit/_WidgetBase",
+	"dojo/dom-construct",
+	"dojo/query",
+	"dojo/date",
+	"dojo/_base/window"
+], function(declare, _WidgetBase, domConstruct, query, dojoDate, win){
+	return declare("dojox.widget._CalendarView", _WidgetBase, {
+		// summary:
+		//		Base implementation for all view mixins.
+		//		All calendar views should extend this widget.
+		headerClass: "",
+
+		useHeader: true,
+
+		cloneClass: function(clazz, n, before){
+			// summary:
+			//		Clones all nodes with the class 'clazz' in a widget
+			var template = query(clazz, this.domNode)[0];
+			var i;
+			if(!before){
+				for(i = 0; i < n; i++){
+					template.parentNode.appendChild(template.cloneNode(true));
+				}
+			}else{
+				// XXX: this is the same as template!
+				var bNode = query(clazz, this.domNode)[0];
+				for(i = 0; i < n; i++){
+					template.parentNode.insertBefore(template.cloneNode(true), bNode);
+				}
+			}
+		},
+
+		_setText: function(node, text){
+			// summary:
+			//		Sets the text inside a node
+			if(node.innerHTML != text){
+				domConstruct.empty(node);
+				node.appendChild(win.doc.createTextNode(text));
+			}
+		},
+
+		getHeader: function(){
+			// summary:
+			//		Returns the header node of a view. If none exists,
+			//		an empty DIV is created and returned.
+			return this.header || (this.header = domConstruct.create("span", { "class":this.headerClass }));
+		},
+
+		onValueSelected: function(date){
+			//Stub function called when a date is selected
+		},
+
+		adjustDate: function(date, amount){
+			// summary:
+			//		Adds or subtracts values from a date.
+			//		The unit, e.g. "day", "month" or "year", is
+			//		specified in the "datePart" property of the
+			//		calendar view mixin.
+			return dojoDate.add(date, this.datePart, amount);
+		},
+
+		onDisplay: function(){
+			// summary:
+			//		Stub function that can be used to tell a view when it is shown.
+		},
+
+		onBeforeDisplay: function(){
+			// summary:
+			//		Stub function that can be used to tell a view it is about to be shown.
+		},
+
+		onBeforeUnDisplay: function(){
+			// summary:
+			//		Stub function that can be used to tell
+			//		a view when it is no longer shown.
+		}
+	});
+});
diff --git a/dojox/widget/_CalendarYear.js b/dojox/widget/_CalendarYear.js
new file mode 100644
index 0000000..66ec3f2
--- /dev/null
+++ b/dojox/widget/_CalendarYear.js
@@ -0,0 +1,19 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarYearView"
+], function(declare, _CalendarYearView){
+	return declare("dojox.widget._CalendarYear", null, {
+		// summary:
+		//		Mixin class for adding a view listing 12 years to the
+		//		dojox/widget/_CalendarBase
+
+		parent: null,
+
+		constructor: function(){
+			// summary:
+			//		Adds a dojox/widget/_CalendarYearView view to the
+			//		dojo/widget/_CalendarBase widget.
+			this._addView(_CalendarYearView);
+		}
+	});
+});
\ No newline at end of file
diff --git a/dojox/widget/_CalendarYearView.js b/dojox/widget/_CalendarYearView.js
new file mode 100644
index 0000000..693521a
--- /dev/null
+++ b/dojox/widget/_CalendarYearView.js
@@ -0,0 +1,52 @@
+define([
+	"dojo/_base/declare",
+	"./_CalendarView",
+	"dijit/_TemplatedMixin",
+	"dojo/date",
+	"dojo/dom-class",
+	"dojo/_base/event",
+	"dojo/text!./Calendar/CalendarYear.html",
+	"./_CalendarMonthYearView"
+], function(declare, _CalendarView, _TemplatedMixin, dojoDate, domClass, event, template, _CalendarMonthYearView){
+	return declare("dojox.widget._CalendarYearView", [_CalendarView, _TemplatedMixin], {
+		// summary:
+		//		A Calendar view listing 12 years
+
+		// templateString: String
+		//		The template to be used to construct the widget.
+		templateString: template,
+
+		displayedYears: 6,
+
+		postCreate: function(){
+			// summary:
+			//		Constructs the view
+			this.cloneClass(".dojoxCalendarYearTemplate", 3);
+			this.cloneClass(".dojoxCalendarYearGroupTemplate", 2);
+			this._populateYears();
+			this.addFx(".dojoxCalendarYearLabel", this.domNode);
+		},
+
+		_setValueAttr: function(value){
+			this._populateYears(value.getFullYear());
+		},
+
+		_populateYears: _CalendarMonthYearView.prototype._populateYears,
+
+		adjustDate: function(date, amount){
+			// summary:
+			//		Adjusts the value of a date. It moves it by 12 years each time.
+			return dojoDate.add(date, "year", amount * 12);
+		},
+
+		onClick: function(evt){
+			// summary:
+			//		Handles clicks on year values.
+			if(!domClass.contains(evt.target, "dojoxCalendarYearLabel")){event.stop(evt); return;}
+			var year = Number(evt.target.innerHTML);
+			var date = this.get("value");
+			date.setYear(year);
+			this.onValueSelected(date, year);
+		}
+	});
+});
diff --git a/dojox/widget/_FisheyeFX.js b/dojox/widget/_FisheyeFX.js
new file mode 100644
index 0000000..e2f9a86
--- /dev/null
+++ b/dojox/widget/_FisheyeFX.js
@@ -0,0 +1,23 @@
+define([
+	"dojo/_base/declare",
+	"dojo/query",
+	// TODO: FisheyeLite still needs AMD conversion
+	"./FisheyeLite"
+], function(declare, query, FisheyeLite) {
+
+	return declare("dojox.widget._FisheyeFX", null, {
+		// summary:
+		//		A mixin to add a FisheyeLite effect to the calendar
+		addFx: function(theQuery, fromNode) {
+			//Use the query and base node passed from the calendar view mixin
+			//to select the nodes to attach the event to.
+			query(theQuery, fromNode).forEach(function(node){
+				new FisheyeLite({
+					properties: {
+						fontSize: 1.1
+					}
+				}, node);
+			});
+		}
+	});
+});
diff --git a/dojox/widget/_Invalidating.js b/dojox/widget/_Invalidating.js
new file mode 100644
index 0000000..c1fdb3c
--- /dev/null
+++ b/dojox/widget/_Invalidating.js
@@ -0,0 +1,62 @@
+define(["dojo/_base/declare", "dojo/_base/lang", "dojo/Stateful"], 
+	function(declare, lang, Stateful){
+		
+	return declare("dojox.widget._Invalidating", Stateful, {
+		// summary:
+		//		Base class for classes (usually widgets) that watch invalidated properties and delay the rendering
+		//		after these properties modifications to the next execution frame.
+		
+		// invalidatingPoperties: String[]
+		//		The list of properties to watch for to trigger invalidation. This list must be initialized in the
+		//		constructor. Default value is null.
+		invalidatingProperties: null,
+		// invalidRenderering: Boolean
+		//		Whether the rendering is invalid or not. This is a readonly information, one must call 
+		//		invalidateRendering to modify this flag. 
+		invalidRendering: false,
+		postscript: function(mixin){
+			this.inherited(arguments);
+			if(this.invalidatingProperties){
+				var props = this.invalidatingProperties;
+				for(var i = 0; i < props.length; i++){
+					this.watch(props[i], lang.hitch(this, this.invalidateRendering));
+					if(mixin && props[i] in mixin){
+						// if the prop happens to have been passed in the ctor mixin we are invalidated
+						this.invalidateRendering();
+					}
+				}
+			}
+		},
+		addInvalidatingProperties: function(/*String[]*/ properties){
+			// summary:
+			//		Add properties to the watched properties to trigger invalidation. This method must be called in
+			//		the constructor. It is typically used by subclasses of a _Invalidating class to add more properties
+			//		to watch for.
+			// properties:
+			//		The list of properties to watch for.
+			this.invalidatingProperties = this.invalidatingProperties?this.invalidatingProperties.concat(properties):properties;
+		},
+		invalidateRendering: function(){
+			// summary:
+			//		Invalidating the rendering for the next executation frame.
+			if(!this.invalidRendering){
+				this.invalidRendering = true;
+				setTimeout(lang.hitch(this, this.validateRendering), 0);
+			}
+		},
+		validateRendering: function(){
+			// summary:
+			//		Immediately validate the rendering if it has been invalidated. You generally do not call that method yourself.
+			// tags:
+			//		protected
+			if(this.invalidRendering){
+				this.refreshRendering();
+				this.invalidRendering = false;
+			}
+		},
+		refreshRendering: function(){
+			// summary:
+			//		Actually refresh the rendering. Implementation should implement that method.
+		}
+	});
+});
diff --git a/dojox/widget/nls/ColorPicker.js b/dojox/widget/nls/ColorPicker.js
index c06981f..dba0554 100644
--- a/dojox/widget/nls/ColorPicker.js
+++ b/dojox/widget/nls/ColorPicker.js
@@ -16,6 +16,7 @@ saturationPickerTitle: "Saturation Selector"
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -43,6 +44,7 @@ saturationPickerTitle: "Saturation Selector"
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dojox/widget/nls/FilePicker.js b/dojox/widget/nls/FilePicker.js
index 810c63c..b5bae49 100644
--- a/dojox/widget/nls/FilePicker.js
+++ b/dojox/widget/nls/FilePicker.js
@@ -9,6 +9,7 @@ define({ root:
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -36,6 +37,7 @@ define({ root:
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dojox/widget/nls/Wizard.js b/dojox/widget/nls/Wizard.js
index 2bd73a4..b2d5762 100644
--- a/dojox/widget/nls/Wizard.js
+++ b/dojox/widget/nls/Wizard.js
@@ -9,6 +9,7 @@ done: "Done"
 ,
 "zh": true,
 "zh-tw": true,
+"uk": true,
 "tr": true,
 "th": true,
 "sv": true,
@@ -36,6 +37,7 @@ done: "Done"
 "da": true,
 "cs": true,
 "ca": true,
+"bg": true,
 "az": true,
 "ar": true
 });
diff --git a/dojox/widget/nls/ar/ColorPicker.js b/dojox/widget/nls/ar/ColorPicker.js
index 4e15b89..3d87ec6 100644
--- a/dojox/widget/nls/ar/ColorPicker.js
+++ b/dojox/widget/nls/ar/ColorPicker.js
@@ -1,8 +1,6 @@
 define(
-//begin v1.x content
 ({
 huePickerTitle: "محدد تدرج اللون",
 saturationPickerTitle: "محدد درجة التشبع"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/ar/FilePicker.js b/dojox/widget/nls/ar/FilePicker.js
index 6329f21..fbb7811 100644
--- a/dojox/widget/nls/ar/FilePicker.js
+++ b/dojox/widget/nls/ar/FilePicker.js
@@ -1,6 +1,7 @@
+define(
 ({
-name: "الاسم",
-path: "‏المسار‏",
-size: "الحجم (بالبايت)"
+	name: "الاسم",
+	path: "‏المسار‏",
+	size: "الحجم (بالبايت)"
 })
-
+);
diff --git a/dojox/widget/nls/ar/Wizard.js b/dojox/widget/nls/ar/Wizard.js
index ee3f305..9751692 100644
--- a/dojox/widget/nls/ar/Wizard.js
+++ b/dojox/widget/nls/ar/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "تالي",
 previous: "‏سابق‏",
 done: "اتمام"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/az/ColorPicker.js b/dojox/widget/nls/az/ColorPicker.js
index bbf0e9b..40ea01d 100644
--- a/dojox/widget/nls/az/ColorPicker.js
+++ b/dojox/widget/nls/az/ColorPicker.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 	"redLabel" : "q",
 	"valueLabel" : "d",
@@ -12,5 +11,4 @@ define(
 	"huePickerTitle" : "Çalar seçimi",
 	"degLabel" : "°"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/az/FilePicker.js b/dojox/widget/nls/az/FilePicker.js
index c74413d..5da0375 100644
--- a/dojox/widget/nls/az/FilePicker.js
+++ b/dojox/widget/nls/az/FilePicker.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	"name" : "Ad",
 	"size" : "Həcmi (bayt cinsindən)",
 	"path" : "Yol"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/az/Wizard.js b/dojox/widget/nls/az/Wizard.js
index c6ba9ce..3e866fc 100644
--- a/dojox/widget/nls/az/Wizard.js
+++ b/dojox/widget/nls/az/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 	"next" : "Irəli",
 	"done" : "Qurtardı",
 	"previous" : "Geri"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/bg/ColorPicker.js b/dojox/widget/nls/bg/ColorPicker.js
new file mode 100644
index 0000000..2d3c863
--- /dev/null
+++ b/dojox/widget/nls/bg/ColorPicker.js
@@ -0,0 +1,14 @@
+define(
+({
+	redLabel: "r",
+	greenLabel: "g",
+	blueLabel: "b",
+	hueLabel: "h",
+	saturationLabel: "s",
+	valueLabel: "v", /* aka intensity or brightness */
+	degLabel: "\u00B0",
+	hexLabel: "шестнадесетичен",
+	huePickerTitle: "Селектро на нюанси",
+	saturationPickerTitle: "Селектор на наситеност"
+})
+);
diff --git a/dojox/widget/nls/bg/FilePicker.js b/dojox/widget/nls/bg/FilePicker.js
new file mode 100644
index 0000000..21ad7f4
--- /dev/null
+++ b/dojox/widget/nls/bg/FilePicker.js
@@ -0,0 +1,7 @@
+define(
+({
+	name: "Име",
+	path: "Пътека",
+	size: "Размер (в байтове)"
+})
+);
diff --git a/dojox/widget/nls/bg/Wizard.js b/dojox/widget/nls/bg/Wizard.js
new file mode 100644
index 0000000..92fa54f
--- /dev/null
+++ b/dojox/widget/nls/bg/Wizard.js
@@ -0,0 +1,7 @@
+define(
+({
+	next: "Следващ",
+	previous: "Предишен",
+	done: "Готово"
+})
+);
diff --git a/dojox/widget/nls/ca/ColorPicker.js b/dojox/widget/nls/ca/ColorPicker.js
index 3fdd070..63fc852 100644
--- a/dojox/widget/nls/ca/ColorPicker.js
+++ b/dojox/widget/nls/ca/ColorPicker.js
@@ -1,10 +1,14 @@
 define(
-//begin v1.x content
 ({
 redLabel: "v",
 greenLabel: "e",
+blueLabel: "b",
 hueLabel: "m",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Selector de matís",
 saturationPickerTitle: "Selector de saturació"
 })
-);
\ No newline at end of file
+);
diff --git a/dojox/widget/nls/ca/FilePicker.js b/dojox/widget/nls/ca/FilePicker.js
index 4f7a56f..4fb891e 100644
--- a/dojox/widget/nls/ca/FilePicker.js
+++ b/dojox/widget/nls/ca/FilePicker.js
@@ -1,6 +1,7 @@
+define(
 ({
-name: "Nom",
-path: "Camí d'accés",
-size: "Mida (en bytes)"
+	name: "Nom",
+	path: "Camí d'accés",
+	size: "Mida (en bytes)"
 })
-
+);
diff --git a/dojox/widget/nls/ca/Wizard.js b/dojox/widget/nls/ca/Wizard.js
index 9d1b280..f0757dc 100644
--- a/dojox/widget/nls/ca/Wizard.js
+++ b/dojox/widget/nls/ca/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Següent",
 previous: "Anterior",
 done: "Fet"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/cs/ColorPicker.js b/dojox/widget/nls/cs/ColorPicker.js
index 2af46cc..15784ae 100644
--- a/dojox/widget/nls/cs/ColorPicker.js
+++ b/dojox/widget/nls/cs/ColorPicker.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 redLabel: "č",
 greenLabel: "z",
@@ -7,6 +6,8 @@ blueLabel: "m",
 hueLabel: "o",
 saturationLabel: "n",
 valueLabel: "j", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Selektor odstínu",
 saturationPickerTitle: "Selektor sytosti"
 })
diff --git a/dojox/widget/nls/cs/FilePicker.js b/dojox/widget/nls/cs/FilePicker.js
index 662cec3..c8bcf7c 100644
--- a/dojox/widget/nls/cs/FilePicker.js
+++ b/dojox/widget/nls/cs/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Název",
-path: "Cesta",
-size: "Velikost (v bajtech)"
+	name: "Název",
+	path: "Cesta",
+	size: "Velikost (v bajtech)"
 })
+);
diff --git a/dojox/widget/nls/cs/Wizard.js b/dojox/widget/nls/cs/Wizard.js
index 18a312e..22e2814 100644
--- a/dojox/widget/nls/cs/Wizard.js
+++ b/dojox/widget/nls/cs/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Další",
 previous: "Předchozí",
 done: "Hotovo"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/da/ColorPicker.js b/dojox/widget/nls/da/ColorPicker.js
index d7b545f..5229a25 100644
--- a/dojox/widget/nls/da/ColorPicker.js
+++ b/dojox/widget/nls/da/ColorPicker.js
@@ -1,6 +1,13 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "n",
+saturationLabel: "m",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Vælg nuance",
 saturationPickerTitle: "Vælg mætning"
 })
diff --git a/dojox/widget/nls/da/FilePicker.js b/dojox/widget/nls/da/FilePicker.js
index 282de00..7920f27 100644
--- a/dojox/widget/nls/da/FilePicker.js
+++ b/dojox/widget/nls/da/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Navn",
-path: "Sti",
-size: "Størrelse (i byte)"
+	name: "Navn",
+	path: "Sti",
+	size: "Størrelse (i byte)"
 })
+);
diff --git a/dojox/widget/nls/da/Wizard.js b/dojox/widget/nls/da/Wizard.js
index 569fe3e..a8ec6a3 100644
--- a/dojox/widget/nls/da/Wizard.js
+++ b/dojox/widget/nls/da/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Næste",
 previous: "Forrige",
 done: "Udført"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/de/ColorPicker.js b/dojox/widget/nls/de/ColorPicker.js
index 92c05eb..3c7e697 100644
--- a/dojox/widget/nls/de/ColorPicker.js
+++ b/dojox/widget/nls/de/ColorPicker.js
@@ -1,6 +1,13 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "h",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Farbtonauswahl",
 saturationPickerTitle: "Sättigungsauswahl"
 })
diff --git a/dojox/widget/nls/de/FilePicker.js b/dojox/widget/nls/de/FilePicker.js
index 5d931eb..e89a8c4 100644
--- a/dojox/widget/nls/de/FilePicker.js
+++ b/dojox/widget/nls/de/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Name",
-path: "Pfad",
-size: "Größe (in Byte)"
+	name: "Name",
+	path: "Pfad",
+	size: "Größe (in Byte)"
 })
+);
diff --git a/dojox/widget/nls/de/Wizard.js b/dojox/widget/nls/de/Wizard.js
index 6624ca5..cca62c8 100644
--- a/dojox/widget/nls/de/Wizard.js
+++ b/dojox/widget/nls/de/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Weiter",
 previous: "Zurück",
 done: "Fertig"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/el/ColorPicker.js b/dojox/widget/nls/el/ColorPicker.js
index 6252042..c002336 100644
--- a/dojox/widget/nls/el/ColorPicker.js
+++ b/dojox/widget/nls/el/ColorPicker.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 redLabel: "κ",
 greenLabel: "π",
@@ -7,6 +6,7 @@ blueLabel: "μ",
 hueLabel: "α",
 saturationLabel: "κ",
 valueLabel: "τ", /* aka intensity or brightness */
+degLabel: "\u00B0",
 hexLabel: "16-αδικό",
 huePickerTitle: "Επιλογή απόχρωσης",
 saturationPickerTitle: "Επιλογή κορεσμού"
diff --git a/dojox/widget/nls/el/FilePicker.js b/dojox/widget/nls/el/FilePicker.js
index 19ba81e..c629c27 100644
--- a/dojox/widget/nls/el/FilePicker.js
+++ b/dojox/widget/nls/el/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Όνομα",
-path: "Διαδρομή",
-size: "Μέγεθος (σε bytes)"
+	name: "Όνομα",
+	path: "Διαδρομή",
+	size: "Μέγεθος (σε bytes)"
 })
+);
diff --git a/dojox/widget/nls/el/Wizard.js b/dojox/widget/nls/el/Wizard.js
index 035a222..42205ce 100644
--- a/dojox/widget/nls/el/Wizard.js
+++ b/dojox/widget/nls/el/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Επόμενο",
 previous: "Προηγούμενο",
 done: "Ολοκλήρωση"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/es/ColorPicker.js b/dojox/widget/nls/es/ColorPicker.js
index 1eec6a1..c1c4aeb 100644
--- a/dojox/widget/nls/es/ColorPicker.js
+++ b/dojox/widget/nls/es/ColorPicker.js
@@ -1,9 +1,13 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
 greenLabel: "v",
 blueLabel: "a",
 hueLabel: "m",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Selector de tono",
 saturationPickerTitle: "Selector de saturación"
 })
diff --git a/dojox/widget/nls/es/FilePicker.js b/dojox/widget/nls/es/FilePicker.js
index a313e9f..4044e61 100644
--- a/dojox/widget/nls/es/FilePicker.js
+++ b/dojox/widget/nls/es/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Nombre",
-path: "Vía de acceso",
-size: "Tamaño (en bytes)"
+	name: "Nombre",
+	path: "Vía de acceso",
+	size: "Tamaño (en bytes)"
 })
+);
diff --git a/dojox/widget/nls/es/Wizard.js b/dojox/widget/nls/es/Wizard.js
index 257a7d9..e441a0c 100644
--- a/dojox/widget/nls/es/Wizard.js
+++ b/dojox/widget/nls/es/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Siguiente",
 previous: "Anterior",
 done: "Terminado"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/fi/ColorPicker.js b/dojox/widget/nls/fi/ColorPicker.js
index 99a1467..d5ba23e 100644
--- a/dojox/widget/nls/fi/ColorPicker.js
+++ b/dojox/widget/nls/fi/ColorPicker.js
@@ -1,6 +1,13 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "h",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Sävyn valitsin",
 saturationPickerTitle: "Kylläisyyden valitsin"
 })
diff --git a/dojox/widget/nls/fi/FilePicker.js b/dojox/widget/nls/fi/FilePicker.js
index 5d8e1f0..eddd280 100644
--- a/dojox/widget/nls/fi/FilePicker.js
+++ b/dojox/widget/nls/fi/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Nimi",
-path: "Polku",
-size: "Koko (tavuina)"
+	name: "Nimi",
+	path: "Polku",
+	size: "Koko (tavuina)"
 })
+);
diff --git a/dojox/widget/nls/fi/Wizard.js b/dojox/widget/nls/fi/Wizard.js
index ea05b1f..50ebcf8 100644
--- a/dojox/widget/nls/fi/Wizard.js
+++ b/dojox/widget/nls/fi/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Seuraava",
 previous: "Edellinen",
 done: "Valmis"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/fr/ColorPicker.js b/dojox/widget/nls/fr/ColorPicker.js
index c49f4f4..749d068 100644
--- a/dojox/widget/nls/fr/ColorPicker.js
+++ b/dojox/widget/nls/fr/ColorPicker.js
@@ -1,8 +1,13 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
 greenLabel: "v",
+blueLabel: "b",
 hueLabel: "t",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Sélecteur de teinte",
 saturationPickerTitle: "Sélecteur de saturation"
 })
diff --git a/dojox/widget/nls/fr/FilePicker.js b/dojox/widget/nls/fr/FilePicker.js
index 4d6530d..d4ffeae 100644
--- a/dojox/widget/nls/fr/FilePicker.js
+++ b/dojox/widget/nls/fr/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Nom",
-path: "Chemin",
-size: "Taille (en octets)"
+	name: "Nom",
+	path: "Chemin",
+	size: "Taille (en octets)"
 })
+);
diff --git a/dojox/widget/nls/fr/Wizard.js b/dojox/widget/nls/fr/Wizard.js
index 5fcab0e..982e207 100644
--- a/dojox/widget/nls/fr/Wizard.js
+++ b/dojox/widget/nls/fr/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Suivant",
 previous: "Précédent",
 done: "Terminé"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/he/ColorPicker.js b/dojox/widget/nls/he/ColorPicker.js
index b4bb8af..491b932 100644
--- a/dojox/widget/nls/he/ColorPicker.js
+++ b/dojox/widget/nls/he/ColorPicker.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 redLabel: "א",
 greenLabel: "י",
diff --git a/dojox/widget/nls/he/FilePicker.js b/dojox/widget/nls/he/FilePicker.js
index d1d4296..f032e6b 100644
--- a/dojox/widget/nls/he/FilePicker.js
+++ b/dojox/widget/nls/he/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "שם",
-path: "נתיב",
-size: "גודל (בבתים)"
+	name: "שם",
+	path: "נתיב",
+	size: "גודל (בבתים)"
 })
+);
diff --git a/dojox/widget/nls/he/Wizard.js b/dojox/widget/nls/he/Wizard.js
index 07e2e47..619ea8c 100644
--- a/dojox/widget/nls/he/Wizard.js
+++ b/dojox/widget/nls/he/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "הבא",
 previous: "הקודם",
 done: "סיום"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/hu/ColorPicker.js b/dojox/widget/nls/hu/ColorPicker.js
index 56838e2..7fbc6f8 100644
--- a/dojox/widget/nls/hu/ColorPicker.js
+++ b/dojox/widget/nls/hu/ColorPicker.js
@@ -1,6 +1,13 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "h",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Árnyalat kiválasztó",
 saturationPickerTitle: "Telítettség kiválasztó"
 })
diff --git a/dojox/widget/nls/hu/FilePicker.js b/dojox/widget/nls/hu/FilePicker.js
index c9b183e..45e1cde 100644
--- a/dojox/widget/nls/hu/FilePicker.js
+++ b/dojox/widget/nls/hu/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Név",
-path: "Elérési út",
-size: "Méret (byte)"
+	name: "Név",
+	path: "Elérési út",
+	size: "Méret (byte)"
 })
+);
diff --git a/dojox/widget/nls/hu/Wizard.js b/dojox/widget/nls/hu/Wizard.js
index 735ff4e..2ce7c14 100644
--- a/dojox/widget/nls/hu/Wizard.js
+++ b/dojox/widget/nls/hu/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
-next: "Következő",
+next: "Tovább",
 previous: "Előző",
 done: "Kész"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/it/ColorPicker.js b/dojox/widget/nls/it/ColorPicker.js
index 248bb12..2d7aaea 100644
--- a/dojox/widget/nls/it/ColorPicker.js
+++ b/dojox/widget/nls/it/ColorPicker.js
@@ -1,6 +1,13 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "v",
+blueLabel: "b",
+hueLabel: "t",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Selettore tonalità",
 saturationPickerTitle: "Selettore saturazione"
 })
diff --git a/dojox/widget/nls/it/FilePicker.js b/dojox/widget/nls/it/FilePicker.js
index d34d5c7..57b8d60 100644
--- a/dojox/widget/nls/it/FilePicker.js
+++ b/dojox/widget/nls/it/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Nome",
-path: "Percorso",
-size: "Dimensione (in byte)"
+	name: "Nome",
+	path: "Percorso",
+	size: "Dimensione (in byte)"
 })
+);
diff --git a/dojox/widget/nls/it/Wizard.js b/dojox/widget/nls/it/Wizard.js
index 7586baf..dcd2b20 100644
--- a/dojox/widget/nls/it/Wizard.js
+++ b/dojox/widget/nls/it/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Successivo",
-previous: "Precedente",
-done: "Eseguito"
+previous: "Indietro",
+done: "Fine"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/ja/ColorPicker.js b/dojox/widget/nls/ja/ColorPicker.js
index a4d1779..1126ca3 100644
--- a/dojox/widget/nls/ja/ColorPicker.js
+++ b/dojox/widget/nls/ja/ColorPicker.js
@@ -1,8 +1,14 @@
 define(
-//begin v1.x content
 ({
-hexLabel: "16 進",
+redLabel: "R",
+greenLabel: "G",
+blueLabel: "B",
+hueLabel: "H",
+saturationLabel: "S",
+valueLabel: "V", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "Hex",
 huePickerTitle: "色調セレクター",
 saturationPickerTitle: "彩度セレクター"
 })
-);
\ No newline at end of file
+);
diff --git a/dojox/widget/nls/ja/FilePicker.js b/dojox/widget/nls/ja/FilePicker.js
index 5ee41d2..a9cb25c 100644
--- a/dojox/widget/nls/ja/FilePicker.js
+++ b/dojox/widget/nls/ja/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "名前",
-path: "パス",
-size: "サイズ (バイト単位)"
+	name: "名前",
+	path: "パス",
+	size: "サイズ (バイト単位)"
 })
+);
diff --git a/dojox/widget/nls/ja/Wizard.js b/dojox/widget/nls/ja/Wizard.js
index 963db06..2a1158b 100644
--- a/dojox/widget/nls/ja/Wizard.js
+++ b/dojox/widget/nls/ja/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "次へ",
 previous: "前へ",
 done: "完了"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/kk/ColorPicker.js b/dojox/widget/nls/kk/ColorPicker.js
index 5022643..8d0bd10 100644
--- a/dojox/widget/nls/kk/ColorPicker.js
+++ b/dojox/widget/nls/kk/ColorPicker.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 redLabel: "r",
 greenLabel: "д",
@@ -7,6 +6,7 @@ blueLabel: "ә",
 hueLabel: "е",
 saturationLabel: "ң",
 valueLabel: "п", /* aka intensity or brightness */
+degLabel: "\u00B0",
 hexLabel: "алтылық",
 huePickerTitle: "Реңкті іріктеу",
 saturationPickerTitle: "Қанықтықты іріктеу"
diff --git a/dojox/widget/nls/kk/FilePicker.js b/dojox/widget/nls/kk/FilePicker.js
index 5957224..8ab1427 100644
--- a/dojox/widget/nls/kk/FilePicker.js
+++ b/dojox/widget/nls/kk/FilePicker.js
@@ -1,6 +1,7 @@
+define(
 ({
-name: "Атауы",
-path: "Жол",
-size: "Өлшемі (байт)"
+	name: "Аты",
+	path: "Жол",
+	size: "Өлшемі (байт)"
 })
-
+);
diff --git a/dojox/widget/nls/kk/Wizard.js b/dojox/widget/nls/kk/Wizard.js
index 4c796ee..b149aca 100644
--- a/dojox/widget/nls/kk/Wizard.js
+++ b/dojox/widget/nls/kk/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Келесі",
 previous: "Алдыңғы",
-done: "Орындалған"
+done: "Дайын"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/ko/ColorPicker.js b/dojox/widget/nls/ko/ColorPicker.js
index d0d75d4..378a21f 100644
--- a/dojox/widget/nls/ko/ColorPicker.js
+++ b/dojox/widget/nls/ko/ColorPicker.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 redLabel: "R",
 greenLabel: "G",
@@ -7,8 +6,9 @@ blueLabel: "B",
 hueLabel: "H",
 saturationLabel: "S",
 valueLabel: "V", /* aka intensity or brightness */
+degLabel: "\u00B0",
 hexLabel: "16진",
 huePickerTitle: "색상 선택자",
 saturationPickerTitle: "채도 선택자"
 })
-);
\ No newline at end of file
+);
diff --git a/dojox/widget/nls/ko/FilePicker.js b/dojox/widget/nls/ko/FilePicker.js
index fc21dba..2466ff0 100644
--- a/dojox/widget/nls/ko/FilePicker.js
+++ b/dojox/widget/nls/ko/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "이름",
-path: "경로",
-size: "크기(바이트)"
+	name: "이름",
+	path: "경로",
+	size: "크기(바이트)"
 })
+);
diff --git a/dojox/widget/nls/ko/Wizard.js b/dojox/widget/nls/ko/Wizard.js
index 4347eb1..b1a1a76 100644
--- a/dojox/widget/nls/ko/Wizard.js
+++ b/dojox/widget/nls/ko/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "다음",
 previous: "이전",
 done: "완료"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/nb/ColorPicker.js b/dojox/widget/nls/nb/ColorPicker.js
index 4fac4eb..4eff936 100644
--- a/dojox/widget/nls/nb/ColorPicker.js
+++ b/dojox/widget/nls/nb/ColorPicker.js
@@ -1,7 +1,14 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "h",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Nyansevelger",
 saturationPickerTitle: "Metningsvelger"
 })
-);
\ No newline at end of file
+);
diff --git a/dojox/widget/nls/nb/FilePicker.js b/dojox/widget/nls/nb/FilePicker.js
index 36775a3..980c4d5 100644
--- a/dojox/widget/nls/nb/FilePicker.js
+++ b/dojox/widget/nls/nb/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Navn",
-path: "Bane",
-size: "Størrelse (i byte)"
+	name: "Navn",
+	path: "Bane",
+	size: "Størrelse (i byte)"
 })
+);
diff --git a/dojox/widget/nls/nb/Wizard.js b/dojox/widget/nls/nb/Wizard.js
index 453de26..0b16c1e 100644
--- a/dojox/widget/nls/nb/Wizard.js
+++ b/dojox/widget/nls/nb/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Neste",
 previous: "Forrige",
 done: "Ferdig"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/nl/ColorPicker.js b/dojox/widget/nls/nl/ColorPicker.js
index a3b4bec..e4a301e 100644
--- a/dojox/widget/nls/nl/ColorPicker.js
+++ b/dojox/widget/nls/nl/ColorPicker.js
@@ -1,9 +1,13 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
 hueLabel: "t",
 saturationLabel: "i",
 valueLabel: "h", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Tint selecteren",
 saturationPickerTitle: "Intensiteit selecteren"
 })
diff --git a/dojox/widget/nls/nl/FilePicker.js b/dojox/widget/nls/nl/FilePicker.js
index 2cf5365..baf4824 100644
--- a/dojox/widget/nls/nl/FilePicker.js
+++ b/dojox/widget/nls/nl/FilePicker.js
@@ -1,6 +1,7 @@
+define(
 ({
-name: "Naam",
-path: "Pad",
-size: "Grootte (in bytes)"
+	name: "Naam",
+	path: "Pad",
+	size: "Grootte (in bytes)"
 })
-
+);
diff --git a/dojox/widget/nls/nl/Wizard.js b/dojox/widget/nls/nl/Wizard.js
index fae9a5b..f87f7fe 100644
--- a/dojox/widget/nls/nl/Wizard.js
+++ b/dojox/widget/nls/nl/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Volgende",
 previous: "Vorige",
 done: "Klaar"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/pl/ColorPicker.js b/dojox/widget/nls/pl/ColorPicker.js
index 0b07a8c..4192597 100644
--- a/dojox/widget/nls/pl/ColorPicker.js
+++ b/dojox/widget/nls/pl/ColorPicker.js
@@ -1,12 +1,12 @@
 define(
-//begin v1.x content
 ({
-redLabel: "c",
-greenLabel: "z",
-blueLabel: "n",
-hueLabel: "barwa",
-saturationLabel: "nas.",
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "g.",
+saturationLabel: "s",
 valueLabel: "jas.", /* aka intensity or brightness */
+degLabel: "\u00B0",
 hexLabel: "szesnastkowe",
 huePickerTitle: "Selektor barwy",
 saturationPickerTitle: "Selektor nasycenia"
diff --git a/dojox/widget/nls/pl/FilePicker.js b/dojox/widget/nls/pl/FilePicker.js
index 5ac0739..0c3d78b 100644
--- a/dojox/widget/nls/pl/FilePicker.js
+++ b/dojox/widget/nls/pl/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Nazwa",
-path: "Ścieżka",
-size: "Wielkość (w bajtach)"
+	name: "Nazwa",
+	path: "Ścieżka",
+	size: "Wielkość (w bajtach)"
 })
+);
diff --git a/dojox/widget/nls/pl/Wizard.js b/dojox/widget/nls/pl/Wizard.js
index 159c701..663a197 100644
--- a/dojox/widget/nls/pl/Wizard.js
+++ b/dojox/widget/nls/pl/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Dalej",
 previous: "Wstecz",
 done: "Gotowe"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/pt-pt/ColorPicker.js b/dojox/widget/nls/pt-pt/ColorPicker.js
index f74664d..c73f49e 100644
--- a/dojox/widget/nls/pt-pt/ColorPicker.js
+++ b/dojox/widget/nls/pt-pt/ColorPicker.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 redLabel: "e",
 greenLabel: "v",
diff --git a/dojox/widget/nls/pt-pt/FilePicker.js b/dojox/widget/nls/pt-pt/FilePicker.js
index 26465b7..a223c23 100644
--- a/dojox/widget/nls/pt-pt/FilePicker.js
+++ b/dojox/widget/nls/pt-pt/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Nome",
-path: "Caminho",
-size: "Tamanho (em bytes)"
+	name: "Nome",
+	path: "Caminho",
+	size: "Tamanho (em bytes)"
 })
+);
diff --git a/dojox/widget/nls/pt-pt/Wizard.js b/dojox/widget/nls/pt-pt/Wizard.js
index cd77ad2..8e54ad0 100644
--- a/dojox/widget/nls/pt-pt/Wizard.js
+++ b/dojox/widget/nls/pt-pt/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Seguinte",
 previous: "Anterior",
 done: "Concluído"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/pt/ColorPicker.js b/dojox/widget/nls/pt/ColorPicker.js
index 026d356..73d2292 100644
--- a/dojox/widget/nls/pt/ColorPicker.js
+++ b/dojox/widget/nls/pt/ColorPicker.js
@@ -1,7 +1,14 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "h",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Seletor de Matiz",
 saturationPickerTitle: "Seletor de Saturação"
 })
-);
\ No newline at end of file
+);
diff --git a/dojox/widget/nls/pt/FilePicker.js b/dojox/widget/nls/pt/FilePicker.js
index 26465b7..a223c23 100644
--- a/dojox/widget/nls/pt/FilePicker.js
+++ b/dojox/widget/nls/pt/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Nome",
-path: "Caminho",
-size: "Tamanho (em bytes)"
+	name: "Nome",
+	path: "Caminho",
+	size: "Tamanho (em bytes)"
 })
+);
diff --git a/dojox/widget/nls/pt/Wizard.js b/dojox/widget/nls/pt/Wizard.js
index fc5040d..88cd1d7 100644
--- a/dojox/widget/nls/pt/Wizard.js
+++ b/dojox/widget/nls/pt/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Próximo",
 previous: "Anterior",
 done: "Concluído"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/ro/ColorPicker.js b/dojox/widget/nls/ro/ColorPicker.js
index 781c510..6a9831a 100644
--- a/dojox/widget/nls/ro/ColorPicker.js
+++ b/dojox/widget/nls/ro/ColorPicker.js
@@ -1,6 +1,13 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "h",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "Selector nuanţă",
 saturationPickerTitle: "Selector saturaţie"
 })
diff --git a/dojox/widget/nls/ro/FilePicker.js b/dojox/widget/nls/ro/FilePicker.js
index 922ae7d..fa2dde9 100644
--- a/dojox/widget/nls/ro/FilePicker.js
+++ b/dojox/widget/nls/ro/FilePicker.js
@@ -1,6 +1,7 @@
+define(
 ({
-name: "Nume",
-path: "Cale ",
-size: "Dimensiune (în octeţi)"
+	name: "Nume",
+	path: "Cale",
+	size: "Mărime (în octeţi)"
 })
-
+);
diff --git a/dojox/widget/nls/ro/Wizard.js b/dojox/widget/nls/ro/Wizard.js
index 29c3075..74d47d9 100644
--- a/dojox/widget/nls/ro/Wizard.js
+++ b/dojox/widget/nls/ro/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Următor",
 previous: "Anterior",
 done: "Gata"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/ru/ColorPicker.js b/dojox/widget/nls/ru/ColorPicker.js
index a3d672f..dac127d 100644
--- a/dojox/widget/nls/ru/ColorPicker.js
+++ b/dojox/widget/nls/ru/ColorPicker.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 redLabel: "к",
 greenLabel: "з",
@@ -7,6 +6,7 @@ blueLabel: "с",
 hueLabel: "о",
 saturationLabel: "н",
 valueLabel: "з", /* aka intensity or brightness */
+degLabel: "\u00B0",
 hexLabel: "шест",
 huePickerTitle: "Выбор оттенка",
 saturationPickerTitle: "Выбор насыщенности"
diff --git a/dojox/widget/nls/ru/FilePicker.js b/dojox/widget/nls/ru/FilePicker.js
index 303a58f..9e67be2 100644
--- a/dojox/widget/nls/ru/FilePicker.js
+++ b/dojox/widget/nls/ru/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Имя",
-path: "Путь",
-size: "Размер (байт)"
+	name: "Имя",
+	path: "Путь",
+	size: "Размер (байт)"
 })
+);
diff --git a/dojox/widget/nls/ru/Wizard.js b/dojox/widget/nls/ru/Wizard.js
index f597ba2..f6e20a1 100644
--- a/dojox/widget/nls/ru/Wizard.js
+++ b/dojox/widget/nls/ru/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Далее",
 previous: "Назад",
 done: "Готово"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/sk/ColorPicker.js b/dojox/widget/nls/sk/ColorPicker.js
index b2e8961..dedf59c 100644
--- a/dojox/widget/nls/sk/ColorPicker.js
+++ b/dojox/widget/nls/sk/ColorPicker.js
@@ -1,5 +1,14 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "h",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
+huePickerTitle: "Výber odtieňa",
+saturationPickerTitle: "Výber sýtosti"
 })
 );
diff --git a/dojox/widget/nls/sk/FilePicker.js b/dojox/widget/nls/sk/FilePicker.js
index dad2f6b..3d8deb9 100644
--- a/dojox/widget/nls/sk/FilePicker.js
+++ b/dojox/widget/nls/sk/FilePicker.js
@@ -1,6 +1,7 @@
+define(
 ({
-name: "Názov",
-path: "Cesta",
-size: "Veľkosť (v bajtoch)"
+	name: "Meno",
+	path: "Cesta",
+	size: "Veľkosť (v bajtoch)"
 })
-
+);
diff --git a/dojox/widget/nls/sk/Wizard.js b/dojox/widget/nls/sk/Wizard.js
index 32a1796..05bdd33 100644
--- a/dojox/widget/nls/sk/Wizard.js
+++ b/dojox/widget/nls/sk/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
-next: "Ďalej",
-previous: "Späť",
+next: "Nasledujúci",
+previous: "Predchádzajúci",
 done: "Hotovo"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/sl/ColorPicker.js b/dojox/widget/nls/sl/ColorPicker.js
index 8591d25..6f8ef44 100644
--- a/dojox/widget/nls/sl/ColorPicker.js
+++ b/dojox/widget/nls/sl/ColorPicker.js
@@ -1,7 +1,14 @@
 define(
-//begin v1.x content
 ({
-huePickerTitle: "Izbirnik odtenka ",
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "h",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
+huePickerTitle: "Izbirnik odtenka",
 saturationPickerTitle: "Izbirnik nasičenosti"
 })
 );
diff --git a/dojox/widget/nls/sl/FilePicker.js b/dojox/widget/nls/sl/FilePicker.js
index d2eac31..07d2986 100644
--- a/dojox/widget/nls/sl/FilePicker.js
+++ b/dojox/widget/nls/sl/FilePicker.js
@@ -1,6 +1,7 @@
+define(
 ({
-name: "Ime",
-path: "Pot",
-size: "Velikost (v bajtih)"
+	name: "Ime",
+	path: "Pot",
+	size: "Velikost (v bajtih)"
 })
-
+);
diff --git a/dojox/widget/nls/sl/Wizard.js b/dojox/widget/nls/sl/Wizard.js
index 8880d1b..5ccdf7c 100644
--- a/dojox/widget/nls/sl/Wizard.js
+++ b/dojox/widget/nls/sl/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Naprej",
-previous: "Nazaj",
+previous: "Prejšnji",
 done: "Opravljeno"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/sv/ColorPicker.js b/dojox/widget/nls/sv/ColorPicker.js
index 523365d..1aba763 100644
--- a/dojox/widget/nls/sv/ColorPicker.js
+++ b/dojox/widget/nls/sv/ColorPicker.js
@@ -1,10 +1,14 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
 hueLabel: "n",
 saturationLabel: "m",
-valueLabel: "l", /* aka intensity or brightness */
-huePickerTitle: "Välj färgton",
-saturationPickerTitle: "Välj mättnad"
+valueLabel: "k", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
+huePickerTitle: "Nyans",
+saturationPickerTitle: "Mättnad"
 })
 );
diff --git a/dojox/widget/nls/sv/FilePicker.js b/dojox/widget/nls/sv/FilePicker.js
index 295ed0a..4c23e32 100644
--- a/dojox/widget/nls/sv/FilePicker.js
+++ b/dojox/widget/nls/sv/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Namn",
-path: "Sökväg",
-size: "Storlek (byte)"
+	name: "Namn",
+	path: "Sökväg",
+	size: "Storlek (i byte)"
 })
+);
diff --git a/dojox/widget/nls/sv/Wizard.js b/dojox/widget/nls/sv/Wizard.js
index fab4300..2b69721 100644
--- a/dojox/widget/nls/sv/Wizard.js
+++ b/dojox/widget/nls/sv/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "Nästa",
 previous: "Föregående",
-done: "Stäng"
+done: "Klart"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/th/ColorPicker.js b/dojox/widget/nls/th/ColorPicker.js
index 44769f2..12e2628 100644
--- a/dojox/widget/nls/th/ColorPicker.js
+++ b/dojox/widget/nls/th/ColorPicker.js
@@ -1,12 +1,13 @@
 define(
-//begin v1.x content
 ({
-redLabel: "อาร์",
-greenLabel: "จี",
-blueLabel: "บี",
-hueLabel: "เอช",
-saturationLabel: "เอส",
-valueLabel: "วี", /* aka intensity or brightness */
+redLabel: "r",
+greenLabel: "ก.",
+blueLabel: "b",
+hueLabel: "ชม.",
+saturationLabel: "วิ.",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
+hexLabel: "hex",
 huePickerTitle: "ตัวเลือกสี",
 saturationPickerTitle: "ตัวเลือกความอิ่มของสี"
 })
diff --git a/dojox/widget/nls/th/FilePicker.js b/dojox/widget/nls/th/FilePicker.js
index c59ae24..6c1f117 100644
--- a/dojox/widget/nls/th/FilePicker.js
+++ b/dojox/widget/nls/th/FilePicker.js
@@ -1,6 +1,7 @@
+define(
 ({
-name: "ชื่อ",
-path: "พาธ",
-size: "ขนาด (ไบต์)"
+	name: "ชื่อ",
+	path: "พาธ",
+	size: "ขนาด (เป็นไบต์)"
 })
-
+);
diff --git a/dojox/widget/nls/th/Wizard.js b/dojox/widget/nls/th/Wizard.js
index 2e91467..8a30d42 100644
--- a/dojox/widget/nls/th/Wizard.js
+++ b/dojox/widget/nls/th/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "ถัดไป",
-previous: "ก่อนหน้า",
-done: "เสร็จสิ้น"
+previous: "ก่อนหน้านี้",
+done: "เสร็จแล้ว"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/tr/ColorPicker.js b/dojox/widget/nls/tr/ColorPicker.js
index 0e989a6..eb85654 100644
--- a/dojox/widget/nls/tr/ColorPicker.js
+++ b/dojox/widget/nls/tr/ColorPicker.js
@@ -1,5 +1,4 @@
 define(
-//begin v1.x content
 ({
 redLabel: "k",
 greenLabel: "y",
@@ -7,6 +6,7 @@ blueLabel: "m",
 hueLabel: "t",
 saturationLabel: "d",
 valueLabel: "d", /* aka intensity or brightness */
+degLabel: "\u00B0",
 hexLabel: "onaltılı",
 huePickerTitle: "Ton Seçici",
 saturationPickerTitle: "Doygunluk Seçici"
diff --git a/dojox/widget/nls/tr/FilePicker.js b/dojox/widget/nls/tr/FilePicker.js
index c561303..3878e98 100644
--- a/dojox/widget/nls/tr/FilePicker.js
+++ b/dojox/widget/nls/tr/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "Ad",
-path: "Yol",
-size: "Boyut (bayt cinsinden)"
+	name: "Ad",
+	path: "Yol",
+	size: "Boyut (bayt cinsinden)"
 })
+);
diff --git a/dojox/widget/nls/tr/Wizard.js b/dojox/widget/nls/tr/Wizard.js
index cba09c9..19625a9 100644
--- a/dojox/widget/nls/tr/Wizard.js
+++ b/dojox/widget/nls/tr/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "İleri",
 previous: "Geri",
 done: "Bitti"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/uk/ColorPicker.js b/dojox/widget/nls/uk/ColorPicker.js
new file mode 100644
index 0000000..64cfc90
--- /dev/null
+++ b/dojox/widget/nls/uk/ColorPicker.js
@@ -0,0 +1,14 @@
+define(
+({
+	redLabel: "r",
+	greenLabel: "g",
+	blueLabel: "b",
+	hueLabel: "h",
+	saturationLabel: "s",
+	valueLabel: "v", /* aka intensity or brightness */
+	degLabel: "\u00B0",
+	hexLabel: "hex",
+	huePickerTitle: "Відтінок",
+	saturationPickerTitle: "Насиченість"
+})
+);
diff --git a/dojox/widget/nls/uk/FilePicker.js b/dojox/widget/nls/uk/FilePicker.js
new file mode 100644
index 0000000..8224652
--- /dev/null
+++ b/dojox/widget/nls/uk/FilePicker.js
@@ -0,0 +1,7 @@
+define(
+({
+	name: "Ім'я",
+	path: "Шлях",
+	size: "Розмір (у байтах)"
+})
+);
diff --git a/dojox/widget/nls/uk/Wizard.js b/dojox/widget/nls/uk/Wizard.js
new file mode 100644
index 0000000..4bc38a6
--- /dev/null
+++ b/dojox/widget/nls/uk/Wizard.js
@@ -0,0 +1,7 @@
+define(
+({
+	next: "Далі",
+	previous: "Назад",
+	done: "Готово"
+})
+);
diff --git a/dojox/widget/nls/zh-tw/ColorPicker.js b/dojox/widget/nls/zh-tw/ColorPicker.js
index 11cbe6d..ce2712a 100644
--- a/dojox/widget/nls/zh-tw/ColorPicker.js
+++ b/dojox/widget/nls/zh-tw/ColorPicker.js
@@ -1,8 +1,14 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "h",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
 hexLabel: "十六進位",
 huePickerTitle: "色調選取元",
 saturationPickerTitle: "飽和度選取元"
 })
-);
\ No newline at end of file
+);
diff --git a/dojox/widget/nls/zh-tw/FilePicker.js b/dojox/widget/nls/zh-tw/FilePicker.js
index dd33b12..afe7ee0 100644
--- a/dojox/widget/nls/zh-tw/FilePicker.js
+++ b/dojox/widget/nls/zh-tw/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "名稱",
-path: "路徑",
-size: "大小 (以位元組為單位)"
+	name: "名稱",
+	path: "路徑",
+	size: "大小 (以位元組為單位)"
 })
+);
diff --git a/dojox/widget/nls/zh-tw/Wizard.js b/dojox/widget/nls/zh-tw/Wizard.js
index 017f106..8ca4c0b 100644
--- a/dojox/widget/nls/zh-tw/Wizard.js
+++ b/dojox/widget/nls/zh-tw/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
 next: "下一步",
 previous: "上一步",
 done: "完成"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/nls/zh/ColorPicker.js b/dojox/widget/nls/zh/ColorPicker.js
index e5afeac..d849614 100644
--- a/dojox/widget/nls/zh/ColorPicker.js
+++ b/dojox/widget/nls/zh/ColorPicker.js
@@ -1,8 +1,14 @@
 define(
-//begin v1.x content
 ({
+redLabel: "r",
+greenLabel: "g",
+blueLabel: "b",
+hueLabel: "h",
+saturationLabel: "s",
+valueLabel: "v", /* aka intensity or brightness */
+degLabel: "\u00B0",
 hexLabel: "十六进制",
 huePickerTitle: "色彩选择器",
 saturationPickerTitle: "饱和度选择器"
 })
-);
\ No newline at end of file
+);
diff --git a/dojox/widget/nls/zh/FilePicker.js b/dojox/widget/nls/zh/FilePicker.js
index 9e8aa6c..18d70b4 100644
--- a/dojox/widget/nls/zh/FilePicker.js
+++ b/dojox/widget/nls/zh/FilePicker.js
@@ -1,5 +1,7 @@
+define(
 ({
-name: "名称",
-path: "路径",
-size: "大小(字节)"
+	name: "名称",
+	path: "路径",
+	size: "大小(以字节计)"
 })
+);
diff --git a/dojox/widget/nls/zh/Wizard.js b/dojox/widget/nls/zh/Wizard.js
index 017f106..10dbc11 100644
--- a/dojox/widget/nls/zh/Wizard.js
+++ b/dojox/widget/nls/zh/Wizard.js
@@ -1,9 +1,7 @@
 define(
-//begin v1.x content
 ({
-next: "下一步",
-previous: "上一步",
+next: "下一个",
+previous: "上一个",
 done: "完成"
 })
-//end v1.x content
 );
diff --git a/dojox/widget/rotator/Controller.js b/dojox/widget/rotator/Controller.js
index 9931742..a6e6c79 100644
--- a/dojox/widget/rotator/Controller.js
+++ b/dojox/widget/rotator/Controller.js
@@ -1,6 +1,12 @@
-dojo.provide("dojox.widget.rotator.Controller");
-
-(function(d){
+define([
+	"dojo/_base/declare",
+	"dojo/_base/lang",
+	"dojo/_base/html",
+	"dojo/_base/event",
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/query"
+], function(declare, lang, html, event, array, connect, query) {
 
 	var _dojoxRotator = "dojoxRotator",
 		_play = _dojoxRotator + "Play",
@@ -9,51 +15,47 @@ dojo.provide("dojox.widget.rotator.Controller");
 		_tab = _dojoxRotator + "Tab",
 		_selected = _dojoxRotator + "Selected";
 
-	d.declare("dojox.widget.rotator.Controller", null, {
-		//	summary:
+	return declare("dojox.widget.rotator.Controller", null, {
+		// summary:
 		//		A controller that manipulates a Rotator or AutoRotator.
-		//
-		//	description:
+		// description:
 		//		Displays a series of controls that send actions to a Rotator or
 		//		AutoRotator.  The Controller supports the following controls:
 		//
-		//		* Next pane
-		//		* Previous pane
-		//		* Play/Pause toggler
-		//		* Numbered tabs
-		//		* Titled tabs
-		//		* Information
+		//		- Next pane
+		//		- Previous pane
+		//		- Play/Pause toggler
+		//		- Numbered tabs
+		//		- Titled tabs
+		//		- Information
 		//
 		//		You may specify any of these controls in any order.  You may also
 		//		have multiple Controllers tied to a single Rotator instance.
 		//
 		//		The Controller's DOM node may also be styled for positioning or
 		//		other styled preferences.
-		//
-		//	example:
+		// example:
 		//	|	<div dojoType="dojox.widget.rotator.Controller"
 		//	|		rotator="myRotator"
 		//	|	></div>
-		//
-		//	example:
+		// example:
 		//	|	<div dojoType="dojox.widget.rotator.Controller"
 		//	|		rotator="myRotator"
 		//	|		controls="prev,#,next"
 		//	|		class="myCtrl"
 		//	|	></div>
-		//
-		//	example:
+		// example:
 		//	|	<div dojoType="dojox.widget.rotator.Controller"
 		//	|		rotator="myRotator"
 		//	|		controls="titles"
 		//	|		class="myCtrl"
 		//	|	></div>s
 
-		//	rotator: dojox.widget.Rotator
+		// rotator: dojox.widget.Rotator
 		//		An instance of a Rotator widget.
 		rotator: null,
 
-		//	commands: string
+		// commands: string
 		//		A comma-separated list of commands. Valid commands are:
 		//		  prev			An icon button to go to the previous pane.
 		//		  next			An icon button to go to the next pane.
@@ -64,10 +66,10 @@ dojo.provide("dojox.widget.rotator.Controller");
 		commands: "prev,play/pause,info,next",
 
 		constructor: function(/*Object*/params, /*DomNode|string*/node){
-			//	summary:
+			// summary:
 			//		Initializes the pager and connect to the rotator.
 
-			d.mixin(this, params);
+			lang.mixin(this, params);
 
 			// check if we have a valid rotator
 			var r = this.rotator;
@@ -77,16 +79,16 @@ dojo.provide("dojox.widget.rotator.Controller");
 					node.removeChild(node.firstChild);
 				}
 
-				var ul = this._domNode = d.create("ul", null, node),
+				var ul = this._domNode = html.create("ul", null, node),
 					icon = " " + _dojoxRotator + "Icon",
 
 					// helper function for creating a button
 					cb = function(/*string*/label, /*string*/css, /*array*/action){
-						d.create("li", {
+						html.create("li", {
 							className: css,
 							innerHTML: '<a href="#"><span>' + label + '</span></a>',
 							onclick: function(/*event*/e){
-								d.stopEvent(e);
+								event.stop(e);
 								if(r){
 									r.control.apply(r, action);
 								}
@@ -95,7 +97,7 @@ dojo.provide("dojox.widget.rotator.Controller");
 					};
 
 				// build out the commands
-				d.forEach(this.commands.split(','), function(b, i){
+				array.forEach(this.commands.split(','), function(b, i){
 					switch(b){
 						case "prev":
 							cb("Prev", _dojoxRotator + "Prev" + icon, ["prev"]);
@@ -105,7 +107,7 @@ dojo.provide("dojox.widget.rotator.Controller");
 							cb("Pause", _pause + icon, ["pause"]);
 							break;
 						case "info":
-							this._info = d.create("li", {
+							this._info = html.create("li", {
 								className: _dojoxRotator + "Info",
 								innerHTML: this._buildInfo(r)
 							}, ul);
@@ -127,40 +129,40 @@ dojo.provide("dojox.widget.rotator.Controller");
 				}, this);
 
 				// add the first/last classes for styling
-				d.query("li:first-child", ul).addClass(_dojoxRotator + "First");
-				d.query("li:last-child", ul).addClass(_dojoxRotator + "Last");
+				query("li:first-child", ul).addClass(_dojoxRotator + "First");
+				query("li:last-child", ul).addClass(_dojoxRotator + "Last");
 
 				// set the initial state of the play/pause toggle button
 				this._togglePlay();
 
-				this._con = d.connect(r, "onUpdate", this, "_onUpdate");
+				this._con = connect.connect(r, "onUpdate", this, "_onUpdate");
 			}
 		},
 
 		destroy: function(){
-			//	summary:
+			// summary:
 			//		Disconnect from the rotator.
-			d.disconnect(this._con);
-			d.destroy(this._domNode);
+			connect.disconnect(this._con);
+			html.destroy(this._domNode);
 		},
 
 		_togglePlay: function(/*boolean*/playing){
-			//	summary:
+			// summary:
 			//		Toggles the play/pause button, if it exists.
 
 			var p = this.rotator.playing;
-			d.query('.'+_play, this._domNode).style("display", p ? "none" : "");
-			d.query('.'+_pause, this._domNode).style("display", p ? "" : "none");
+			query('.'+_play, this._domNode).style("display", p ? "none" : "");
+			query('.'+_pause, this._domNode).style("display", p ? "" : "none");
 		},
 
 		_buildInfo: function(/*dojox.widget.Rotator*/r){
-			//	summary:
+			// summary:
 			//		Return a string containing the current pane number and the total number of panes.
 			return '<span>' + (r.idx+1) + ' / ' + r.panes.length + '</span>'; /*string*/
 		},
 
 		_onUpdate: function(/*string*/type){
-			//	summary:
+			// summary:
 			//		Updates various pager controls when the rotator updates.
 
 			var r = this.rotator; // no need to test if this is null since _onUpdate is only fired by the rotator
@@ -178,15 +180,14 @@ dojo.provide("dojox.widget.rotator.Controller");
 					// helper function for selecting the current tab
 					var s = function(/*NodeList*/n){
 						if(r.idx < n.length){
-							d.addClass(n[r.idx], _selected);
+							html.addClass(n[r.idx], _selected);
 						}
 					};
 
-					s(d.query('.' + _number, this._domNode).removeClass(_selected));
-					s(d.query('.' + _tab, this._domNode).removeClass(_selected));
+					s(query('.' + _number, this._domNode).removeClass(_selected));
+					s(query('.' + _tab, this._domNode).removeClass(_selected));
 					break;
 			}
 		}
 	});
-
-})(dojo);
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/dojox/widget/rotator/Fade.js b/dojox/widget/rotator/Fade.js
index 3fdf974..0675669 100644
--- a/dojox/widget/rotator/Fade.js
+++ b/dojox/widget/rotator/Fade.js
@@ -1,40 +1,46 @@
-dojo.provide("dojox.widget.rotator.Fade");
-dojo.require("dojo.fx");
-
-(function(d){
+define([
+	"dojo/_base/lang",
+	"dojo/_base/fx",
+	"dojo/dom-style",
+	"dojo/fx"
+], function(lang, baseFx, domStyle, fx) {
 
 	function _fade(/*Object*/args, /*string*/action){
-		//	summary:
+		// summary:
 		//		Returns an animation of a fade out and fade in of the current and next
 		//		panes.  It will either chain (fade) or combine (crossFade) the fade
 		//		animations.
 		var n = args.next.node;
-		d.style(n, {
+		domStyle.set(n, {
 			display: "",
 			opacity: 0
 		});
 
 		args.node = args.current.node;
 
-		return d.fx[action]([ /*dojo.Animation*/
-			d.fadeOut(args),
-			d.fadeIn(d.mixin(args, { node: n }))
+		return fx[action]([ /*dojo.Animation*/
+			baseFx.fadeOut(args),
+			baseFx.fadeIn(lang.mixin(args, { node: n }))
 		]);
 	}
 
-	d.mixin(dojox.widget.rotator, {
+	var exports = {
 		fade: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that fades out the current pane, then fades in
 			//		the next pane.
 			return _fade(args, "chain"); /*dojo.Animation*/
 		},
 
 		crossFade: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that cross fades two rotator panes.
 			return _fade(args, "combine"); /*dojo.Animation*/
 		}
-	});
+	};
+
+	// back-compat, remove for 2.0
+	lang.mixin(lang.getObject("dojox.widget.rotator"), exports);
 
-})(dojo);
\ No newline at end of file
+	return exports;
+});
\ No newline at end of file
diff --git a/dojox/widget/rotator/Pan.js b/dojox/widget/rotator/Pan.js
index 834b363..7b1f2de 100644
--- a/dojox/widget/rotator/Pan.js
+++ b/dojox/widget/rotator/Pan.js
@@ -1,7 +1,11 @@
-dojo.provide("dojox.widget.rotator.Pan");
-dojo.require("dojo.fx");
-
-(function(d){
+define([
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/lang",
+	"dojo/dom-style",
+	"dojo/_base/fx",
+	"dojo/fx"
+], function(array, connect, lang, domStyle, baseFx, fx) {
 
 	// Constants used to identify which edge the pane pans in from.
 	var DOWN = 0,
@@ -10,7 +14,7 @@ dojo.require("dojo.fx");
 		LEFT = 3;
 
 	function _pan(/*int*/type, /*Object*/args){
-		//	summary:
+		// summary:
 		//		Handles the preparation of the dom node and creates the dojo.Animation object.
 		var n = args.next.node,
 			r = args.rotatorBox,
@@ -20,7 +24,7 @@ dojo.require("dojo.fx");
 			p = {},
 			q = {};
 
-		d.style(n, "display", "");
+		domStyle.set(n, "display", "");
 
 		p[a] = {
 			start: 0,
@@ -32,14 +36,14 @@ dojo.require("dojo.fx");
 			end: 0
 		};
 
-		return d.fx.combine([ /*dojo.Animation*/
-			d.animateProperty({
+		return fx.combine([ /*dojo.Animation*/
+			baseFx.animateProperty({
 				node: args.current.node,
 				duration: args.duration,
 				properties: p,
 				easing: args.easing
 			}),
-			d.animateProperty({
+			baseFx.animateProperty({
 				node: n,
 				duration: args.duration,
 				properties: q,
@@ -49,14 +53,14 @@ dojo.require("dojo.fx");
 	}
 
 	function _setZindex(/*DomNode*/n, /*int*/z){
-		//	summary:
+		// summary:
 		//		Helper function for continuously panning.
-		d.style(n, "zIndex", z);
+		domStyle.set(n, "zIndex", z);
 	}
 
-	d.mixin(dojox.widget.rotator, {
+	var exports = {
 		pan: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that either pans left or right to the next pane.
 			//		The actual direction depends on the order of the panes.
 			//
@@ -137,7 +141,7 @@ dojo.require("dojo.fx");
 					_setZindex(y.node, z--);
 
 					// build the pan animation
-					_pans.push(_pan(_dir, d.mixin({
+					_pans.push(_pan(_dir, lang.mixin({
 						easing: function(m){ return m; } // continuous gets a linear easing by default
 					}, args, {
 						current: x,
@@ -156,13 +160,13 @@ dojo.require("dojo.fx");
 				}
 
 				// build the chained animation of all pan animations
-				var _anim = d.fx.chain(_pans),
+				var _anim = fx.chain(_pans),
 
 					// clean up styles when the chained animation finishes
-					h = d.connect(_anim, "onEnd", function(){
-						d.disconnect(h);
-						d.forEach(_nodes, function(q){
-							d.style(q, {
+					h = connect.connect(_anim, "onEnd", function(){
+						connect.disconnect(h);
+						array.forEach(_nodes, function(q){
+							domStyle.set(q, {
 								display: "none",
 								left: 0,
 								opacity: 1,
@@ -180,28 +184,32 @@ dojo.require("dojo.fx");
 		},
 
 		panDown: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that pans in the next rotator pane from the top.
 			return _pan(DOWN, args); /*dojo.Animation*/
 		},
 
 		panRight: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that pans in the next rotator pane from the right.
 			return _pan(RIGHT, args); /*dojo.Animation*/
 		},
 
 		panUp: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that pans in the next rotator pane from the bottom.
 			return _pan(UP, args); /*dojo.Animation*/
 		},
 
 		panLeft: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that pans in the next rotator pane from the left.
 			return _pan(LEFT, args); /*dojo.Animation*/
 		}
-	});
+	};
+
+	// back-compat, remove for 2.0
+	lang.mixin(lang.getObject("dojox.widget.rotator"), exports);
 
-})(dojo);
+	return exports;
+});
\ No newline at end of file
diff --git a/dojox/widget/rotator/PanFade.js b/dojox/widget/rotator/PanFade.js
index bd241c4..7d65717 100644
--- a/dojox/widget/rotator/PanFade.js
+++ b/dojox/widget/rotator/PanFade.js
@@ -1,7 +1,11 @@
-dojo.provide("dojox.widget.rotator.PanFade");
-dojo.require("dojo.fx");
-
-(function(d){
+define([
+	"dojo/_base/array",
+	"dojo/_base/connect",
+	"dojo/_base/lang",
+	"dojo/_base/fx",
+	"dojo/dom-style",
+	"dojo/fx"
+], function(array, connect, lang, baseFx, domStyle, fx) {
 
 	// Constants used to identify which edge the pane pans in from.
 	var DOWN = 0,
@@ -10,7 +14,7 @@ dojo.require("dojo.fx");
 		LEFT = 3;
 
 	function _pan(/*int*/type, /*Object*/args){
-		//	summary:
+		// summary:
 		//		Handles the preparation of the dom node and creates the dojo.Animation object.
 		var j = {
 				node: args.current.node,
@@ -29,7 +33,7 @@ dojo.require("dojo.fx");
 			p = {},
 			q = {};
 
-		d.style(k.node, {
+		domStyle.set(k.node, {
 			display: "",
 			opacity: 0
 		});
@@ -44,23 +48,23 @@ dojo.require("dojo.fx");
 			end: 0
 		};
 
-		return d.fx.combine([ /*dojo.Animation*/
-			d.animateProperty(d.mixin({ properties: p }, j)),
-			d.fadeOut(j),
-			d.animateProperty(d.mixin({ properties: q }, k)),
-			d.fadeIn(k)
+		return fx.combine([ /*dojo.Animation*/
+			baseFx.animateProperty(lang.mixin({ properties: p }, j)),
+			baseFx.fadeOut(j),
+			baseFx.animateProperty(lang.mixin({ properties: q }, k)),
+			baseFx.fadeIn(k)
 		]);
 	}
 
 	function _setZindex(/*DomNode*/n, /*int*/z){
-		//	summary:
+		// summary:
 		//		Helper function for continuously panning.
-		d.style(n, "zIndex", z);
+		domStyle.set(n, "zIndex", z);
 	}
 
-	d.mixin(dojox.widget.rotator, {
+	var exports = {
 		panFade: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that either pans left or right to the next pane.
 			//		The actual direction depends on the order of the panes.
 			//
@@ -141,7 +145,7 @@ dojo.require("dojo.fx");
 					_setZindex(y.node, z--);
 
 					// build the pan animation
-					_pans.push(_pan(_dir, d.mixin({
+					_pans.push(_pan(_dir, lang.mixin({
 						easing: function(m){ return m; } // continuous gets a linear easing by default
 					}, args, {
 						current: x,
@@ -160,21 +164,21 @@ dojo.require("dojo.fx");
 				}
 
 				// build the chained animation of all pan animations
-				var _anim = d.fx.chain(_pans),
-
-					// clean up styles when the chained animation finishes
-					h = d.connect(_anim, "onEnd", function(){
-						d.disconnect(h);
-						d.forEach(_nodes, function(q){
-							d.style(q, {
-								display: "none",
-								left: 0,
-								opacity: 1,
-								top: 0,
-								zIndex: 0
-							});
+				var _anim = fx.chain(_pans);
+
+				// clean up styles when the chained animation finishes
+				var h = connect.connect(_anim, "onEnd", function(){
+					connect.disconnect(h);
+					array.forEach(_nodes, function(q){
+						domStyle.set(q, {
+							display: "none",
+							left: 0,
+							opacity: 1,
+							top: 0,
+							zIndex: 0
 						});
 					});
+				});
 
 				return _anim;
 			}
@@ -184,28 +188,32 @@ dojo.require("dojo.fx");
 		},
 
 		panFadeDown: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that pans in the next rotator pane from the top.
 			return _pan(DOWN, args); /*dojo.Animation*/
 		},
 
 		panFadeRight: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that pans in the next rotator pane from the right.
 			return _pan(RIGHT, args); /*dojo.Animation*/
 		},
 
 		panFadeUp: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that pans in the next rotator pane from the bottom.
 			return _pan(UP, args); /*dojo.Animation*/
 		},
 
 		panFadeLeft: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that pans in the next rotator pane from the left.
 			return _pan(LEFT, args); /*dojo.Animation*/
 		}
-	});
+	};
+
+	// back-compat, remove for 2.0
+	lang.mixin(lang.getObject("dojox.widget.rotator"), exports);
 
-})(dojo);
+	return exports;
+});
\ No newline at end of file
diff --git a/dojox/widget/rotator/Slide.js b/dojox/widget/rotator/Slide.js
index dc1196c..6ed67ac 100644
--- a/dojox/widget/rotator/Slide.js
+++ b/dojox/widget/rotator/Slide.js
@@ -1,6 +1,8 @@
-dojo.provide("dojox.widget.rotator.Slide");
-
-(function(d){
+define([
+	"dojo/_base/lang",
+	"dojo/_base/fx",
+	"dojo/dom-style"
+], function(lang, baseFx, domStyle){
 
 	// Constants used to identify which edge the pane slides in from.
 	var DOWN = 0,
@@ -9,16 +11,16 @@ dojo.provide("dojox.widget.rotator.Slide");
 		LEFT = 3;
 
 	function _slide(/*int*/type, /*Object*/args){
-		//	summary:
+		// summary:
 		//		Handles the preparation of the dom node and creates the dojo.Animation object.
 		var node = args.node = args.next.node,
 			r = args.rotatorBox,
 			m = type % 2,
 			s = (m ? r.w : r.h) * (type < 2 ? -1 : 1);
 
-		d.style(node, {
+		domStyle.set(node, {
 			display: "",
-			zIndex: (d.style(args.current.node, "zIndex") || 1) + 1
+			zIndex: (domStyle.get(args.current.node, "zIndex") || 1) + 1
 		});
 
 		if(!args.properties){
@@ -29,33 +31,37 @@ dojo.provide("dojox.widget.rotator.Slide");
 			end: 0
 		};
 
-		return d.animateProperty(args); /*dojo.Animation*/
+		return baseFx.animateProperty(args); /*dojo.Animation*/
 	}
 
-	d.mixin(dojox.widget.rotator, {
+	var exports = {
 		slideDown: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that slides in the next rotator pane from the top.
 			return _slide(DOWN, args); /*dojo.Animation*/
 		},
 
 		slideRight: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that slides in the next rotator pane from the right.
 			return _slide(RIGHT, args); /*dojo.Animation*/
 		},
 
 		slideUp: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that slides in the next rotator pane from the bottom.
 			return _slide(UP, args); /*dojo.Animation*/
 		},
 
 		slideLeft: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that slides in the next rotator pane from the left.
 			return _slide(LEFT, args); /*dojo.Animation*/
 		}
-	});
+	};
+
+	// back-compat, remove for 2.0
+	lang.mixin(lang.getObject("dojox.widget.rotator"), exports);
 
-})(dojo);
+	return exports;
+});
\ No newline at end of file
diff --git a/dojox/widget/rotator/ThumbnailController.js b/dojox/widget/rotator/ThumbnailController.js
index c080c8f..6a237be 100644
--- a/dojox/widget/rotator/ThumbnailController.js
+++ b/dojox/widget/rotator/ThumbnailController.js
@@ -1,38 +1,44 @@
-dojo.provide("dojox.widget.rotator.ThumbnailController");
-
-(function(d){
+define([
+	"dojo/_base/declare",
+	"dojo/_base/connect",
+	"dojo/_base/lang",
+	"dojo/_base/event",
+	"dojo/aspect",
+	"dojo/dom-attr",
+	"dojo/dom-class",
+	"dojo/dom-construct",
+	"dojo/query"
+], function(declare, connect, lang, event, aspect, domAttr, domClass, domConstruct, query) {
 
 	var _css = "dojoxRotatorThumb",
 		_selected = _css + "Selected";
 
-	d.declare("dojox.widget.rotator.ThumbnailController", null, {
-		//	summary:
+	return declare("dojox.widget.rotator.ThumbnailController", null, {
+		// summary:
 		//		A rotator controller that displays thumbnails of each rotator pane.
-		//
-		//	description:
+		// description:
 		//		The ThumbnailController will look at each of the rotator's panes and
-		//		only if the node is an <img> tag, then it will create an thumbnail of
-		//		the pane's image using the <img> tag's "thumbsrc" or "src" attribute.
+		//		only if the node is an `<img>` tag, then it will create an thumbnail of
+		//		the pane's image using the `<img>` tag's "thumbsrc" or "src" attribute.
 		//
 		//		The size of the thumbnails and the style of the selected thumbnail is
 		//		controlled using CSS.
-		//
-		//	example:
+		// example:
 		//	|	<div dojoType="dojox.widget.Rotator" jsId="myRotator">
 		//	|		<img src="/path/to/image1.jpg" thumbsrc="/path/to/thumb1.jpg" alt="Image 1"/>
 		//	|		<img src="/path/to/image2.jpg" thumbsrc="/path/to/thumb2.jpg" alt="Image 2"/>
 		//	|	</div>
 		//	|	<div dojoType="dojox.widget.rotator.ThumbnailController" rotator="myRotator"></div>
 
-		//	rotator: dojox.widget.Rotator
+		// rotator: dojox/widget/Rotator
 		//		An instance of a Rotator widget.
 		rotator: null,
 
 		constructor: function(/*Object*/params, /*DomNode|string*/node){
-			//	summary:
+			// summary:
 			//		Initializes the thumbnails and connect to the rotator.
 
-			d.mixin(this, params);
+			lang.mixin(this, params);
 
 			this._domNode = node;
 
@@ -46,16 +52,16 @@ dojo.provide("dojox.widget.rotator.ThumbnailController");
 
 				for(var i=0; i<r.panes.length; i++){
 					var n = r.panes[i].node,
-						s = d.attr(n, "thumbsrc") || d.attr(n, "src"),
-						t = d.attr(n, "alt") || "";
+						s = domAttr.get(n, "thumbsrc") || domAttr.get(n, "src"),
+						t = domAttr.get(n, "alt") || "";
 
 					if(/img/i.test(n.tagName)){
 						(function(j){
-							d.create("a", {
+							domConstruct.create("a", {
 								classname: _css + ' ' + _css + j + ' ' + (j == r.idx ? _selected : ""),
 								href: s,
 								onclick: function(e){
-									d.stopEvent(e);
+									event.stop(e);
 									if(r){
 										r.control.apply(r, ["go", j]);
 									}
@@ -67,30 +73,29 @@ dojo.provide("dojox.widget.rotator.ThumbnailController");
 					}
 				}
 
-				this._con = d.connect(r, "onUpdate", this, "_onUpdate");
+				aspect.after(r, 'onUpdate', lang.hitch(this, "_onUpdate"), true);
 			}
 		},
 
 		destroy: function(){
-			//	summary:
+			// summary:
 			//		Disconnect from the rotator.
 
-			d.disconnect(this._con);
-			d.destroy(this._domNode);
+			domConstruct.destroy(this._domNode);
 		},
 
 		_onUpdate: function(/*string*/type){
-			//	summary:
+			// summary:
 			//		Updates various pager controls when the rotator updates.
 
 			var r = this.rotator; // no need to test if this is null since _onUpdate is only fired by the rotator
 			if(type == "onAfterTransition"){
-				var n = d.query('.' + _css, this._domNode).removeClass(_selected);
+				var n = query('.' + _css, this._domNode).removeClass(_selected);
 				if(r.idx < n.length){
-					d.addClass(n[r.idx], _selected);
+					domClass.add(n[r.idx], _selected);
 				}
 			}
 		}
 	});
 
-})(dojo);
\ No newline at end of file
+});
\ No newline at end of file
diff --git a/dojox/widget/rotator/Wipe.js b/dojox/widget/rotator/Wipe.js
index 763c187..a0eba08 100644
--- a/dojox/widget/rotator/Wipe.js
+++ b/dojox/widget/rotator/Wipe.js
@@ -1,6 +1,8 @@
-dojo.provide("dojox.widget.rotator.Wipe");
-
-(function(d){
+define([
+	"dojo/_base/lang",
+	"dojo/_base/fx",
+	"dojo/dom-style"
+], function(lang, fx, domStyle) {
 
 	// Constants used to identify which clip edge is being wiped. The values are
 	// the index of the clip array that is changed during the animation.
@@ -29,27 +31,27 @@ dojo.provide("dojox.widget.rotator.Wipe");
 	}
 
 	function _setClip(/*DomNode*/n, /*int*/type, /*int*/w, /*int*/h, /*number*/x){
-		//	summary:
+		// summary:
 		//		Sets the clip region of the node. If a type is passed in then we
 		//		return a rect(), otherwise return "auto".
-		d.style(n, "clip", type == null ? "auto" : "rect(" + _clipArray(type, w, h, x).join("px,") + "px)");
+		domStyle.set(n, "clip", type == null ? "auto" : "rect(" + _clipArray(type, w, h, x).join("px,") + "px)");
 	}
 
 	function _wipe(/*int*/type, /*Object*/args){
-		//	summary:
-		//		Handles the preparation of the dom node and creates the dojo.Animation object.
+		// summary:
+		//		Handles the preparation of the dom node and creates the Animation object.
 		var node = args.next.node,
 			w = args.rotatorBox.w,
 			h = args.rotatorBox.h;
 
-		d.style(node, {
+		domStyle.set(node, {
 			display: "",
-			zIndex: (d.style(args.current.node, "zIndex") || 1) + 1
+			zIndex: (domStyle.get(args.current.node, "zIndex") || 1) + 1
 		});
 
 		_setClip(node, type, w, h);
 
-		return new d.Animation(d.mixin({ /*dojo.Animation*/
+		return new fx.Animation(lang.mixin({
 			node: node,
 			curve: [0, type % 2 ? w : h],
 			onAnimate: function(x){
@@ -58,30 +60,34 @@ dojo.provide("dojox.widget.rotator.Wipe");
 		}, args));
 	}
 
-	d.mixin(dojox.widget.rotator, {
+	var exports = {
 		wipeDown: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that wipes in the next rotator pane from the top.
 			return _wipe(DOWN, args); /*dojo.Animation*/
 		},
 
 		wipeRight: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that wipes in the next rotator pane from the right.
 			return _wipe(RIGHT, args); /*dojo.Animation*/
 		},
 
 		wipeUp: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that wipes in the next rotator pane from the bottom.
 			return _wipe(UP, args); /*dojo.Animation*/
 		},
 
 		wipeLeft: function(/*Object*/args){
-			//	summary:
+			// summary:
 			//		Returns a dojo.Animation that wipes in the next rotator pane from the left.
 			return _wipe(LEFT, args); /*dojo.Animation*/
 		}
-	});
+	};
+
+	// back-compat, remove for 2.0
+	lang.mixin(lang.getObject("dojox.widget.rotator"), exports);
 
-})(dojo);
+	return exports;
+});
\ No newline at end of file
diff --git a/dojox/widget/tests/Selection.js b/dojox/widget/tests/Selection.js
new file mode 100644
index 0000000..7f35b67
--- /dev/null
+++ b/dojox/widget/tests/Selection.js
@@ -0,0 +1,21 @@
+define(["doh", "dojo/_base/declare", "../Selection", "dijit/_WidgetBase"], 
+	function(doh, declare, Selection, _WidgetBase){
+	doh.register("tests.Selection", [
+		function test_Lifecycle(t){
+			var C = declare("MyWidget", [_WidgetBase, Selection], {
+				updateRenderers: function(){
+				}
+			});
+			var o = new C();
+			o.set("selectedItem", "1");
+			t.is("1", o.get("selectedItem"));
+			t.is(["1"], o.get("selectedItems"));
+			o.set("selectedItems", ["2"]);
+			t.is("2", o.get("selectedItem"));
+			t.is(["2"], o.get("selectedItems"));
+			o = new C({selectedItem: "1"});
+			t.is("1", o.get("selectedItem"));
+			t.is(["1"], o.get("selectedItems"));
+		}
+	]);
+});
diff --git a/dojox/widget/tests/_Invalidating.js b/dojox/widget/tests/_Invalidating.js
new file mode 100644
index 0000000..2a61c16
--- /dev/null
+++ b/dojox/widget/tests/_Invalidating.js
@@ -0,0 +1,16 @@
+define(["doh", "dojo/_base/declare", "../_Invalidating", "dijit/_WidgetBase"], 
+	function(doh, declare, _Invalidating, _WidgetBase){
+	doh.register("tests._Invalidating", [
+		function test_Lifecycle(t){
+			var C = declare("MyWidget", [_WidgetBase, _Invalidating], {
+				constructor: function(){
+					this.invalidatingProperties = ["a"];
+					this.addInvalidatingProperties(["b"]);
+				}					
+			});
+			var o = new C();
+			o.startup();
+			t.is(["a", "b"], o.invalidatingProperties);
+		}
+	]);
+});
diff --git a/dojox/widget/tests/demo_FisheyeList.html b/dojox/widget/tests/demo_FisheyeList.html
index 703fc55..3a780a3 100644
--- a/dojox/widget/tests/demo_FisheyeList.html
+++ b/dojox/widget/tests/demo_FisheyeList.html
@@ -43,7 +43,7 @@
 		}
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.widget.FisheyeLite");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
diff --git a/dojox/widget/tests/module.js b/dojox/widget/tests/module.js
new file mode 100644
index 0000000..0c5e17a
--- /dev/null
+++ b/dojox/widget/tests/module.js
@@ -0,0 +1,4 @@
+define([
+	"dojox/widget/tests/_Invalidating",
+	"dojox/widget/tests/Selection"
+], 1);
diff --git a/dojox/widget/tests/runTests.html b/dojox/widget/tests/runTests.html
new file mode 100644
index 0000000..55277a0
--- /dev/null
+++ b/dojox/widget/tests/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+  <head>
+  <title>Dojox Widget Unit Test Runner</title>
+    <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?test=dojox/widget/tests/module"></HEAD>
+  <BODY>
+    Redirecting to D.O.H runner.
+  </BODY>
+</HTML>
\ No newline at end of file
diff --git a/dojox/widget/tests/test_AutoRotator.html b/dojox/widget/tests/test_AutoRotator.html
index ed4ab84..58fe2f9 100644
--- a/dojox/widget/tests/test_AutoRotator.html
+++ b/dojox/widget/tests/test_AutoRotator.html
@@ -1,4 +1,4 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE HTML>
 <html>
 <head>
 	<title>dojox.widget.AutoRotator Test</title>
@@ -32,16 +32,20 @@
 	}
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:true, isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, selectorEngine: 'acme'"></script>
 	<script type="text/javascript">
-	dojo.require("dojo.parser");
-	dojo.require("dojox.widget.AutoRotator");
-	dojo.require("dojox.widget.rotator.Fade");
-	dojo.require("dojox.widget.rotator.Pan");
-	dojo.require("dojox.widget.rotator.Slide");
-	dojo.require("dojox.widget.rotator.Wipe");
+		require([
+			"dojo/parser",
+			"dojo/domReady!",
+			"dojox/widget/AutoRotator",
+			"dojox/widget/rotator/Fade",
+			"dojox/widget/rotator/Pan",
+			"dojox/widget/rotator/Slide",
+			"dojox/widget/rotator/Wipe"
+		], function(parser) {
+
+		parser.parse();
 
-	dojo.addOnLoad(function(){
 		// programmatic example
 		var contributors = [
 			[ "http://www.nexaweb.com",		"nexaweb.png",		"Nexaweb" ],
@@ -110,7 +114,8 @@
 	<button onclick="dojo.publish('myRotator/rotator/control', ['test']);">Bad Action</button>
 	</p>
 	
-	<div dojoType="dojox.widget.AutoRotator" class="rotator" id="myRotator" duration="2000">
+	<div data-dojo-type="dojox/widget/AutoRotator" class="rotator" id="myRotator"
+		 data-dojo-props="duration: 2000">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -163,7 +168,9 @@
 	<button onclick="myRotator2.go(8);">Goto 8 (bad)</button>
 	</p>
 	
-	<div dojoType="dojox.widget.AutoRotator" class="rotator" jsId="myRotator2" random="true" duration="2000" cycles="4">
+	<div data-dojo-type="dojox/widget/AutoRotator" class="rotator"
+		 data-dojo-id="myRotator2"
+		 data-dojo-props="random: true, duration: 2000, cycles: 4">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -202,7 +209,9 @@
 	
 	<p>The 2nd pane will wait for a event to be published by the button before proceeding.</p>
 	
-	<div dojoType="dojox.widget.AutoRotator" class="rotator" jsId="myRotator3" duration="2000" transition="dojox.widget.rotator.crossFade">
+	<div data-dojo-type="dojox/widget/AutoRotator" class="rotator"
+		 data-dojo-id="myRotator3"
+		 data-dojo-props="duration: 2000, transition: 'dojox.widget.rotator.crossFade'">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -251,7 +260,9 @@
 	</p>
 
 	<div class="rotator" style="position:relative;">
-		<div dojoType="dojox.widget.AutoRotator" class="rotatorStacked" style="z-index:100;" jsId="myRotator3_3" duration="1500" transition="dojox.widget.rotator.panLeft">
+		<div data-dojo-type="dojox/widget/AutoRotator" class="rotatorStacked" style="z-index:100;"
+			 data-dojo-id="myRotator3_3"
+			 data-dojo-props="duration: 1500, transition: 'dojox.widget.rotator.panLeft'">
 			<div class="pane">
 				<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 				<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -269,7 +280,9 @@
 				<a href="http://www.google.com" target="_new"><img src="images/rotator_google.png" width="130" alt="Google"/></a>
 			</div>
 		</div>
-		<div dojoType="dojox.widget.AutoRotator" class="rotatorStacked" style="z-index:50;" jsId="myRotator3_4" duration="1500" transition="dojox.widget.rotator.crossFade">
+		<div data-dojo-type="dojox/widget/AutoRotator" class="rotatorStacked" style="z-index:50;"
+			 data-dojo-id="myRotator3_4"
+			 data-dojo-props="duration: 1500, transition: 'dojox.widget.rotator.crossFade'">
 			<div class="pane" style="background-color:red;"></div>
 			<div class="pane" style="background-color:yellow;"></div>
 			<div class="pane" style="background-color:green;"></div>
@@ -296,7 +309,8 @@
 	<button onclick="dojo.publish('myRotator5/rotator/control', ['test']);">Bad Action</button>
 	</p>
 	
-	<div dojoType="dojox.widget.AutoRotator" class="rotator" id="myRotator5" suspendOnHover="true" duration="1000">
+	<div data-dojo-type="dojox/widget/AutoRotator" class="rotator" id="myRotator5"
+		 data-dojo-props="suspendOnHover: true, duration: 1000">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -350,7 +364,8 @@
 	<button onclick="dojo.publish('myRotator6/rotator/control', ['test']);">Bad Action</button>
 	</p>
 	
-	<div dojoType="dojox.widget.AutoRotator" class="rotator" id="myRotator6" pauseOnManualChange="true" duration="1000">
+	<div data-dojo-type="dojox/widget/AutoRotator" class="rotator" id="myRotator6"
+		 data-dojo-props="pauseOnManualChange: true, duration: 1000">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
diff --git a/dojox/widget/tests/test_Calendar.html b/dojox/widget/tests/test_Calendar.html
index c78ca7e..0c36d6e 100644
--- a/dojox/widget/tests/test_Calendar.html
+++ b/dojox/widget/tests/test_Calendar.html
@@ -1,7 +1,7 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE HTML>
 <html>
 	<head>
+	    <meta charset="utf-8">
 		<title>Dojox Calendar Test</title>
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
@@ -15,35 +15,43 @@
 			}
 		</style>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js"
+        		data-dojo-config="async:1, transparentColor: [ 255, 255, 255 ]"></script>
 
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
 		<script type="text/javascript">
-			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-			dojo.require("dijit.dijit");
-			dojo.require("dojox.fx._base");
-			dojo.require("dojox.widget.Calendar");
-			dojo.require("dojox.widget.FisheyeLite");
-			dojo.require("dojox.widget.CalendarFx");
-
-			dojo.declare(
-				"test.CalendarCustomFx",
-			 	[dojox.widget.Calendar], {
-
-				addFx: function(query, fromNode){
-					dojo.query(query, fromNode).onmouseover(function(evt){
-						dojox.fx.highlight({node: evt.target}).play();
-					});
-				}
-			});
-			function log(str){
-					dojo.byId("report").innerHTML = str;
-				}
-
+			require([
+			    "dojo/_base/declare",
+				"dojo/parser",
+				"dojo/query",
+				"dojox/fx/_base",
+				"dojox/widget/Calendar",
+				"dojo/dom",
+				"dojox/widget/DailyCalendar",
+				"dojox/widget/MonthAndYearlyCalendar",
+				"dojox/widget/MonthlyCalendar",
+				"dojox/widget/CalendarFisheye",
+				"dojo/aspect",
+				"dojo/domReady!"
+			], function(declare, parser, query, xFx, Calendar, dom){
+
+				declare("test/CalendarCustomFx", [Calendar], {
+
+					addFx: function(theQuery, fromNode){
+						query(theQuery, fromNode).on("mouseover", function(evt){
+							xFx.highlight({node: evt.target}).play();
+						});
+					}
+				});
+				//window['log'] = function(str){
+				//	dom.byId("report").innerHTML = str;
+                //}
+                parser.parse();
+            });
 		</script>
 	</head>
-	<body>
+	<body class="soria">
 		<div>
 			Use different theme:
 			<a href="test_Calendar.html?theme=tundra">tundra</a>
@@ -55,9 +63,9 @@
 		<div>
 			<span style="width:33%;float:left;">
 				<div class="title">Typical Calendar usage, with day, and month/year views</div>
-				<div dojoType="dojox.widget.Calendar" id="cal">
-					<script type="dojo/connect" event="onValueSelected" args="value">
-						log("Date Value selected: " + value);
+				<div data-dojo-type="dojox/widget/Calendar" id="cal">
+					<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="onValueSelected" data-dojo-args="value">
+						console.log("Date Value selected: " + value);
 					</script>
 				</div>
 
@@ -74,9 +82,9 @@
 			<span style="width:33%;float:left;">
 				<div class="title">With day only view, no month/year view</div>
 
-				<div dojoType="dojox.widget.DailyCalendar" id="calDayOnly">
-					<script type="dojo/connect" event="onValueSelected" args="value">
-						log("Day Value selected: " + value);
+				<div data-dojo-type="dojox/widget/DailyCalendar" id="calDayOnly">
+					<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="onValueSelected" data-dojo-args="value">
+						console.log("Day Value selected: " + value);
 					</script>
 				</div>
 
@@ -92,9 +100,9 @@
 			<span style="width:33%;float:left;">
 				<div class="title">With day only view, no month/year view</div>
 
-				<div dojoType="dojox.widget.MonthAndYearlyCalendar" id="calMonthAndYearOnly">
-					<script type="dojo/connect" event="onValueSelected" args="value">
-						log("Date Value selected from Month and Year Only Calendar: " + value);
+				<div data-dojo-type="dojox/widget/MonthAndYearlyCalendar" id="calMonthAndYearOnly">
+					<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="onValueSelected" data-dojo-args="value">
+						console.log("Date Value selected from Month and Year Only Calendar: " + value);
 					</script>
 				</div>
 
@@ -111,11 +119,11 @@
 
     <div>
 			<span style="width:33%;float:left;">
-				<div class="title">Typical calendar, with min/max constraints = {min:'2008-12-12',max:'2009-01-15'}</div>
-				<div dojoType="dojox.widget.Calendar" id="calLimits" value="2008-12-25"
-						constraints="{min:'2008-12-12',max:'2009-01-15'}">
-					<script type="dojo/connect" event="onValueSelected" args="value">
-						log("Date Value selected: " + value);
+				<div class="title">Typical calendar, with min/max constraints = {min:'2012-12-12',max:'2013-01-15'}</div>
+				<div data-dojo-type="dojox/widget/Calendar" id="calLimits" value="2012-12-25"
+						constraints="{min:'2012-12-12',max:'2013-01-15'}">
+    				<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="onValueSelected" data-dojo-args="value">
+						console.log("Date Value selected: " + value);
 					</script>
 				</div>
 
@@ -130,18 +138,20 @@
 			</span>
 			<span style="width:33%;float:left;">
 				<div class="title">Typical calendar, with min/max constraints a week before and after the current date</div>
-				<div dojoType="dojox.widget.Calendar" id="calLimitsWeek">
-					<script type="dojo/method" event="postMixInProperties">						
-						// This runs after the constructor, before properties are mixed in
-						var currentDate = new Date();
-						this.constraints = {
-						  min: dojo.date.add(currentDate, 'week', -1),
-							max: dojo.date.add(currentDate, 'week', +1)
-						};
-						dojox.widget.Calendar.prototype.postMixInProperties.call(this);
+				<div data-dojo-type="dojox/widget/Calendar" id="calLimitsWeek">
+				    <script type="dojo/aspect" data-dojo-advice="before" data-dojo-method="postMixInProperties">
+					    //TODO: This never gets called...
+						require(["dojox/widget/Calendar", "dojo/date"], function(Calendar, date){
+    						var currentDate = new Date();
+    						var constraints = {
+    						    min: date.add(currentDate, 'week', -1),
+    							max: date.add(currentDate, 'week', +1)
+    						};
+    						Calendar._setConstraintsAttr(constraints);
+						});
 					</script>
-					<script type="dojo/connect" event="onValueSelected" args="value">
-						log("Date Value selected: " + value);
+					<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="onValueSelected" data-dojo-args="value">
+						console.log("Date Value selected: " + value);
 					</script>
 				</div>
 
@@ -155,10 +165,10 @@
 				</p>
 			</span>
 			<span style="width:33%;float:left;">
-				<div class="title">Typical calendar, initial date set in HTML to December 25th, 2007</div>
-				<div dojoType="dojox.widget.Calendar" id="calXmas" value="2007-12-25">
-					<script type="dojo/connect" event="onValueSelected" args="value">
-						log("Date Value selected: " + value);
+				<div class="title">Typical calendar, initial date set in HTML to December 25th, 2012</div>
+				<div data-dojo-type="dojox/widget/Calendar" id="calXmas" value="2012-12-25">
+					<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="onValueSelected" data-dojo-args="value">
+						console.log("Date Value selected: " + value);
 					</script>
 				</div>
 
@@ -177,9 +187,9 @@
 			<span style="width:50%;float:left;">
 				<div class="title">Standard calendar, with FisheyeLite effects (in development, just here to show that FX can be applied)</div>
 
-				<div dojoType="dojox.widget.CalendarFisheye" id="calFisheye">
-					<script type="dojo/connect" event="onValueSelected" args="value">
-						log("Date Value selected from Fisheye Calendar: " + value);
+				<div data-dojo-type="dojox/widget/CalendarFisheye" id="calFisheye">
+					<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="onValueSelected" data-dojo-args="value">
+						console.log("Date Value selected from Fisheye Calendar: " + value);
 					</script>
 				</div>
 
@@ -195,9 +205,9 @@
 			<span style="width:50%;float:left;">
 				<div class="title">With custom Highlighting effects (in development, just here to show that FX can be applied)</div>
 
-				<div dojoType="test.CalendarCustomFx" id="calCustomFx">
-					<script type="dojo/connect" event="onValueSelected" args="value">
-						log("Date Value selected in FX Calendar: " + value);
+				<div data-dojo-type="test/CalendarCustomFx" id="calCustomFx">
+					<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="onValueSelected" data-dojo-args="value">
+						console.log("Date Value selected in FX Calendar: " + value);
 					</script>
 				</div><p>
 				Lorem ipsum dolor sit amet, <a href="#">consectetuer</a> adipiscing elit. Aenean
@@ -208,6 +218,7 @@
 				magna. Sed vitae risus.
 				</p>
 			</span>
+		
 		</div>
 
 
diff --git a/dojox/widget/tests/test_CalendarViews.html b/dojox/widget/tests/test_CalendarViews.html
index 358d7fc..51c181e 100644
--- a/dojox/widget/tests/test_CalendarViews.html
+++ b/dojox/widget/tests/test_CalendarViews.html
@@ -1,5 +1,4 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE HTML>
 <html>
 	<head>
 		<title>Dojox Calendar Views Test</title>
@@ -8,7 +7,6 @@
 			@import "../../../dijit/themes/tundra/tundra.css";
 			@import "../../../dijit/themes/soria/soria.css";
 			@import "../../../dijit/themes/nihilo/nihilo.css";
-			@import "../../../dijit/themes/dijit.css";
 			@import "../../../dijit/tests/css/dijitTests.css";
 			@import "../Calendar/Calendar.css";
 
@@ -17,21 +15,23 @@
 			}
 		</style>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" 
+		    data-dojo-config="async:1, transparentColor: [ 255, 255, 255 ]"></script>
 
 		<!-- not needed, for testing alternate themes -->
 		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
 		<script type="text/javascript">
-			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-			dojo.require("dijit.dijit");
-			dojo.require("dojox.fx");
-			dojo.require("dojox.widget.Calendar");
-			dojo.require("dojox.widget.CalendarViews");
-
-			function log(str){
-				dojo.byId("report").innerHTML = str;
-			}
+		require([
+			"dojo/parser",
+			"dojo/domReady!"
+		], function(parser){
+			
+			//window['log'] = function(str){
+				//dom.byId("report").innerHTML = str;
+            //}
+            parser.parse();
+		});
 		</script>
 	</head>
 	<body class="soria">
@@ -43,7 +43,7 @@
 		</div>
 		<div id="report" style="float:left; width:100%;height:40px;color:red;font-weight:bold;"></div>
 		<p>
-			This page shows the dojox.widget.Calendar widget with three panes, a day, month and year view.
+			This page shows the dojox/widget/Calendar widget with three panes, a day, month and year view.
 			Click on the date on the top of the widget to select the month, and click it again to
 			select the year.
 		</p>
@@ -52,10 +52,10 @@
 			<span style="width:33%;float:left;">
 				<div class="title">With day, month and year views</div>
 
-				<div dojoType="dojox.widget.Calendar3Pane" id="cal3Pane">
-					<script type="dojo/connect" event="onValueSelected" args="value">
-						log("Date Value selected: " + value);
-					</script>
+				<div dojoType="dojox/widget/Calendar3Pane" id="cal3Pane">
+					<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="onValueSelected" data-dojo-args="value">
+					    console.log("Date Value selected: " + value);
+                    </script>
 				</div>
 
 				<p>
@@ -70,10 +70,10 @@
 			<span style="width:33%;float:left;">
 				<div class="title">With month only view, no daily or yearly</div>
 
-				<div dojoType="dojox.widget.MonthlyCalendar" id="calMonthOnly">
-					<script type="dojo/connect" event="onValueSelected" args="value">
-						log("Month Value selected: " + value);
-					</script>
+				<div dojoType="dojox/widget/MonthlyCalendar" id="calMonthOnly">
+					<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="onValueSelected" data-dojo-args="value">
+					    console.log("Month Value selected: " + value);
+                    </script>
 				</div>
 
 				<p>
@@ -88,10 +88,10 @@
 			<span style="width:33%;float:left;">
 				<div class="title">With year only view, no daily or yearly</div>
 
-				<div dojoType="dojox.widget.YearlyCalendar" id="calYearOnly">
-					<script type="dojo/connect" event="onValueSelected" args="value">
-						log("Year Value selected: " + value);
-					</script>
+				<div dojoType="dojox/widget/YearlyCalendar" id="calYearOnly">
+					<script type="dojo/aspect" data-dojo-advice="after" data-dojo-method="onValueSelected" data-dojo-args="value">
+					    console.log("Year Value selected: " + value);
+                    </script>
 				</div><p>
 				Lorem ipsum dolor sit amet, <a href="#">consectetuer</a> adipiscing elit. Aenean
 				semper sagittis velit. Cras in mi. Duis porta mauris ut ligula.
diff --git a/dojox/widget/tests/test_ColorPicker-async.html b/dojox/widget/tests/test_ColorPicker-async.html
index 87782cc..63af82c 100644
--- a/dojox/widget/tests/test_ColorPicker-async.html
+++ b/dojox/widget/tests/test_ColorPicker-async.html
@@ -18,7 +18,7 @@
 			left: 362px;
 		}
 	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:1,isDebug:1,async:1"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:1,isDebug:1,async:1"></script>
 	<script type="text/javascript">
 		require([
 				"dojo",
diff --git a/dojox/widget/tests/test_ColorPicker.html b/dojox/widget/tests/test_ColorPicker.html
index 592e541..17aed77 100644
--- a/dojox/widget/tests/test_ColorPicker.html
+++ b/dojox/widget/tests/test_ColorPicker.html
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="en">
 <head>
 	
 	<title>Dojox ColorPicker Test</title>
@@ -20,7 +20,7 @@
 	</style>
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes 
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -42,7 +42,7 @@
 		});
 	</script>
 </head>
-<body class="tundra">
+<body class="tundra" role="main">
 
 	<h1 class="testTitle">Dojox ColorPicker test</h1>
 
@@ -51,7 +51,7 @@
 		value="#9ebf6c"
 		onChange="handler(arguments[0],'onchangeOne')"
 	></div>
-	<p>Current value: <input readonly="true" id="onchangeOne" value="???" /></p>
+	<p><label for="onchangeOne">Current value: </label><input readonly="true" id="onchangeOne" value="???" /></p>
 	
 	<h3>no animation, no hsv, no rgb, no webSafe info:</h3>
 	<div id="pickerToo" dojoType="dojox.widget.ColorPicker"
@@ -61,7 +61,7 @@
 		webSafe="false"
 		onChange="handler(arguments[0],'onchangeTwo')"
 	></div>
-	<p>Current value: <input readonly="true" id="onchangeTwo" value="???" /></p>
+	<p><label for="onchangeTwo">Current value: </label><input readonly="true" id="onchangeTwo" value="???" /></p>
 	
 	<h3>Fires onChange a lot:</h3>
 	<div id="pickerLive" dojoType="dojox.widget.ColorPicker"
@@ -69,7 +69,7 @@
 		liveUpdate="true"
 		onChange="handler(arguments[0],'onchangeThree')"
 	></div>
-	<p>Current value: <input readonly="true" id="onchangeThree" value="???" /></p>
+	<p><label for="onchangeThree">Current value: </label><input readonly="true" id="onchangeThree" value="???" /></p>
 	
 	<div id="absolutey">
 		<h3>To See how it positions in an absolute node (editor plugin, input popup)</h3>
@@ -79,6 +79,6 @@
 	<button id="testFocusButton" type="button" dojoType="dijit.form.Button">Click to focus first widget</button>
 	
 	<p>that's all folks!</p>
-	
+
 </body>
 </html>
diff --git a/dojox/widget/tests/test_DataPresentation.html b/dojox/widget/tests/test_DataPresentation.html
index 91ebd5d..74ebe55 100644
--- a/dojox/widget/tests/test_DataPresentation.html
+++ b/dojox/widget/tests/test_DataPresentation.html
@@ -11,7 +11,7 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
 	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad: true"></script>
 	<script type="text/javascript">
 
 		dojo.require("dojox.widget.DataPresentation");
diff --git a/dojox/widget/tests/test_Dialog.html b/dojox/widget/tests/test_Dialog.html
index aa36ff8..5a89659 100644
--- a/dojox/widget/tests/test_Dialog.html
+++ b/dojox/widget/tests/test_Dialog.html
@@ -19,7 +19,7 @@
 	</style>		
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/widget/tests/test_DocTester.html b/dojox/widget/tests/test_DocTester.html
index 54ed592..32a8c09 100644
--- a/dojox/widget/tests/test_DocTester.html
+++ b/dojox/widget/tests/test_DocTester.html
@@ -10,7 +10,7 @@
 		@import "../DocTester/DocTester.css"; 
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../DocTester.js"></script>
 </head>
 <body class="tundra">
diff --git a/dojox/widget/tests/test_DynamicTooltip.html b/dojox/widget/tests/test_DynamicTooltip.html
index ae46854..f335e0b 100644
--- a/dojox/widget/tests/test_DynamicTooltip.html
+++ b/dojox/widget/tests/test_DynamicTooltip.html
@@ -16,7 +16,7 @@
 	
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 	
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
diff --git a/dojox/widget/tests/test_FilePicker.html b/dojox/widget/tests/test_FilePicker.html
index 142a242..ec8a07a 100644
--- a/dojox/widget/tests/test_FilePicker.html
+++ b/dojox/widget/tests/test_FilePicker.html
@@ -18,7 +18,7 @@
 	
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true, useCommentedJson: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true, useCommentedJson: true"></script>
 	
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -36,8 +36,8 @@
 	<p>The picker below uses the dojox.data.FileStore and a PHP implementation for the serverside to browse the dojo tree hierarchy in a lazy-load fashion.</p>
 	<p><i><b>This demo must be run from a web-server with PHP support enabled.  Without PHP support, this demo cannot function.</b></i></p>
 	<hr>
-	<div dojoType="dojox.data.FileStore" url="../../data/demos/stores/filestore_dojotree.php" jsId="fileStore" pathAsQueryParam="true"></div>
-	<div dojoType="dojox.widget.FilePicker" jsId="myPicker" id="myPicker" style="width: 50%;" store="fileStore" query="{}"></div>
+	<div dojoType="dojox.data.FileStore" url="../../data/demos/stores/filestore_dojotree.php" data-dojo-id="fileStore" pathAsQueryParam="true"></div>
+	<div dojoType="dojox.widget.FilePicker" data-dojo-id="myPicker" id="myPicker" style="width: 50%;" store="fileStore" query="{}"></div>
 </body>
 </html>
 
diff --git a/dojox/widget/tests/test_FisheyeList.html b/dojox/widget/tests/test_FisheyeList.html
index 348ea13..f0f328e 100644
--- a/dojox/widget/tests/test_FisheyeList.html
+++ b/dojox/widget/tests/test_FisheyeList.html
@@ -1,5 +1,5 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
+		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
 	<title>FisheyeList Widget Dojo Tests</title>
@@ -11,28 +11,33 @@
 		@import "../FisheyeList/FisheyeList.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
-	<script type="text/javascript" src="../FisheyeList.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
-		//dojo.require("dojox.widget.FisheyeList");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-		dojo.addOnLoad(function(){
-			fish1 = dijit.byId("fisheye1");
-			fish2 = dijit.byId("fisheye2");
+	require([
+		 "dojox/widget/FisheyeList",
+		 "dojox/widget/FisheyeListItem",
+		 "dijit/registry",
+		 "dojo/parser",
+		 "dojo/ready"
+	], function(FisheyeList, FisheyeListItem, registry, parser, ready){
+
+		ready(function(){
+			fish1 = registry.byId("fisheye1");
+			fish2 = registry.byId("fisheye2");
 		});
 		var counter = 1;
-		function addToFirstList(){
-			var item = new dojox.widget.FisheyeListItem();
-			item.label = "Dynamically Added "+counter;
-			item.iconSrc = "images/fisheye_"+counter+".png"
-			item.postCreate();
+		addToFirstList = function(){
+			var item = new FisheyeListItem({
+				label:"Dynamically Added "+counter,
+				iconSrc: "images/fisheye_"+counter+".png"
+			});
 			counter++;
 			if(counter>4){counter=1;}
 			fish1.addChild(item);
 			fish1.startup();
 			item.startup();
 		}
+	});
 	</script>
 </head>
 <body class="tundra">
@@ -55,7 +60,7 @@
 
 	<div dojoType="dojox.widget.FisheyeListItem"
 		id="item1"
-		onclick="alert('click on ' + this.label + '(from widget id ' + this.widgetId + ')!');"
+		onClick="alert('click on ' + this.label + '(from widget id ' + this.id + ')!');"
 		label="Item 1"
 		iconSrc="images/fisheye_1.png">
 	</div>
@@ -106,7 +111,7 @@
 
 	<div dojoType="dojox.widget.FisheyeListItem"
 		id="item1b"
-		onclick="alert('click on ' + this.label + '(from widget id ' + this.widgetId + ')!');"
+		onClick="alert('click on ' + this.label + '(from widget id ' + this.id + ')!');"
 		label="Item 1"
 		iconSrc="images/fisheye_1.png">
 	</div>
diff --git a/dojox/widget/tests/test_FisheyeLite.html b/dojox/widget/tests/test_FisheyeLite.html
index befe1a6..eb21060 100644
--- a/dojox/widget/tests/test_FisheyeLite.html
+++ b/dojox/widget/tests/test_FisheyeLite.html
@@ -61,100 +61,109 @@
 	<script type="text/javascript">
 		var djConfig = { isDebug:true, parseOnLoad:true };
 	</script>
-	<script type="text/javascript" src="../../../dojo/dojo.js"></script>
-	<script type="text/javascript" src="../FisheyeLite.js"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async:true"></script>
 	<script type="text/javascript">
-		dojo.require("dojo.parser");
-		dojo.require("dojox.widget.FisheyeLite");
+        require([
+            "dijit/registry",
+            "dojox/widget/FisheyeLite",
+            "dojo/parser",
+            "dojo/query",
+            "dojo/fx/easing",
+            "dojo/on",
+            "dojo/_base/Deferred",
+            "dojo/domReady!"
+        ], function(registry, FisheyeLite, parser, query, easing, on, Deferred){
 
-		var beenDestroyed = false;
-		var hasInit = false;
-		var init = function(e){
+    		var beenDestroyed = false;
+    		var hasInit = false;
+    		var init = function(e){
 			
-			if(e && !beenDestroyed){ return; }
-			e && e.preventDefault();
+    			if(e && !beenDestroyed){ return; }
+    			e && e.preventDefault();
 			
-			// turn li's in this page into fisheye items, presumtiously:	
-			dojo.query("li.bounce").instantiate(dojox.widget.FisheyeLite,{});
+    			// turn li's in this page into fisheye items, presumtiously:	
+    			query("li.bounce").instantiate(dojox.widget.FisheyeLite,{});
 
-			var l = dojo.query("span.line")
-				.instantiate(dojox.widget.FisheyeLite,{
-				// make a widget from each of the lines in the lineHeightTest
-					properties: {
-						fontSize:1.75
-					},
-					easeOut: dojo.fx.easing.backInOut,
-					durationOut: 500
-				});
+    			var l = query("span.line")
+    				.instantiate(dojox.widget.FisheyeLite,{
+    				// make a widget from each of the lines in the lineHeightTest
+    					properties: {
+    						fontSize:1.75
+    					},
+    					easeOut: easing.backInOut,
+    					durationOut: 500
+    				});
 				
-			if(!hasInit){
-				l.connect("onclick",function(e){
-				// you can still access the onclick of the real node
-					alert(e.target.innerHTML);
-				});
-			}
+    			if(!hasInit){
+    				on(l, "click",function(e){
+    				// you can still access the onclick of the real node
+    					alert(e.target.innerHTML);
+    				});
+    			}
 
-			var lm = dojo.query("a").instantiate(dojox.widget.FisheyeLite,{
-				properties:{
-					fontSize:1.15,
-					letterSpacing:2.85
-				}
-			});
-			if(!hasInit){
-			// stop anchors from doing _anything_	
-				lm.connect("onclick",dojo,"stopEvent");
-			}
+    			var lm = query("a").instantiate(dojox.widget.FisheyeLite,{
+    				properties:{
+    					fontSize:1.15,
+    					letterSpacing:2.85
+    				}
+    			});
+    			if(!hasInit){
+    			// stop anchors from doing _anything_	
+    				on(lm, "click", function(){
+    				  //TODO: stop event  
+    				});
+    			}
 
-			dojo.query(".imgBounce").instantiate(dojox.widget.FisheyeLite,{
-				// all the images need a width and a height (well, not need,
-				// but to scale you do)				
-				properties: {
-					height:1.75,
-					width:1.75
-				}
-			});
+    			query(".imgBounce").instantiate(dojox.widget.FisheyeLite,{
+    				// all the images need a width and a height (well, not need,
+    				// but to scale you do)				
+    				properties: {
+    					height:1.75,
+    					width:1.75
+    				}
+    			});
 			
-			// show the new non-numeric multiplier version of fisheyelite
-			dojo.query(".advancedProps").instantiate(dojox.widget.FisheyeLite,{
-				properties:{
-					height: {
-						end: 100
-					}
-				}
-			})
+    			// show the new non-numeric multiplier version of fisheyelite
+    			query(".advancedProps").instantiate(dojox.widget.FisheyeLite,{
+    				properties:{
+    					height: {
+    						end: 100
+    					}
+    				}
+    			})
 			
-			// 
-			var vv = 0;
-			var r = dijit.registry.byClass("dojox.widget.FisheyeLite")._hash;
-			for(var l in r){
-				vv++;
-			}
+    			// 
+    			var vv = 0;
+    			var r = registry.byClass("dojox.widget.FisheyeLite")._hash;
+    			for(var l in r){
+    				vv++;
+    			}
 			
-			// a few in markup, mostly from the query()'ies:
-			console.log("fisheyes on this page: ", vv);
+    			// a few in markup, mostly from the query()'ies:
+    			console.log("fisheyes on this page: ", vv);
 				
-			beenDestroyed = false;
-			hasInit = true;
-		};
-		dojo.addOnLoad(init);
+    			beenDestroyed = false;
+    			hasInit = true;
+    		};
 		
-		dojo.addOnLoad(function(){
-			dojo.query("#restore").connect("onclick",init);
-			dojo.query("#destroy").connect("onclick",destroyAll);
+    		var destroyAll = function(e){
+    			e && e.preventDefault();
+    			if(confirm("really?")){
+    				dijit.registry.filter(function(w){
+    					return w && w.declaredClass == "dojox.widget.FisheyeLite";
+    				}).forEach(function(w){
+    					w.destroy(true);
+    				});
+    				beenDestroyed = true;
+    			}
+    		};
+    		
+    		Deferred.when(parser.parse(), function(){
+			    init();
+    			query("#restore").on("click",init);
+    			query("#destroy").on("click",destroyAll);
+			});
 		});
-		
-		var destroyAll = function(e){
-			e && e.preventDefault();
-			if(confirm("really?")){
-				dijit.registry.filter(function(w){
-					return w && w.declaredClass == "dojox.widget.FisheyeLite";
-				}).forEach(function(w){
-					w.destroy(true);
-				});
-				beenDestroyed = true;
-			}
-		};
-			
 	</script>
     </head>
     <body class="tundra">
@@ -203,10 +212,10 @@
 				</div>
 
 				<div>
-					<div dojoType="dojox.widget.FisheyeLite" properties="{ fontSize:1.25 }" style="padding:3px"
+					<div data-dojo-type="dojox/widget/FisheyeLite" data-dojo-props="fontSize:1.25" style="padding:3px"
 					><a id='destroy' href="#" class="fisheyeTarget">test destroy()</a></div>
 
-					<div dojoType="dojox.widget.FisheyeLite" properties="{ fontSize:1.25 }" style="padding:3px"
+					<div data-dojo-type="dojox/widget/FisheyeLite" data-dojo-props="fontSize:1.25" style="padding:3px"
 					><a id='restore' href="#" class="fisheyeTarget">restore</a></div>
 				</div>
 
@@ -276,8 +285,8 @@
 					<img src="images/fisheye_1.png" class="imgBounce" onClick="alert('clicked img 1')"/>
 				</div>
 				
-				<p dojoType="dojox.widget.FisheyeLite"
-				   properties="{ padding:1.55 }"
+				<p data-dojo-type="dojox/widget/FisheyeLite"
+				   data-dojo-props="padding:1.55"
 				   style="padding:12px; text-align:justify;">
 					
 				Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
@@ -296,12 +305,9 @@
 				</p>
 				
 				<p class="advancedProps" style="height:25px; background:#000">Lorem</p>
-				<p class="advancedPropsToo" dojoType="dojox.widget.FisheyeLite"
+				<p class="advancedPropsToo" data-dojo-type="dojox/widget/FisheyeLite"
 					style="height:25px; background:#000"
-					properties="{ height:{ end: 150 } }"
-					easeIn="dojo._defaultEasing"
-					easeOut="dojo._defaultEasing"
-					durationOut="175"
+					data-dojo-props="height:{end:150}, /*easeIn: fx._defaultEasing, easeOut: fx._defaultEasing,*/ durationOut: 175"
 				>Lorem</p>
 				
 				<p>the end</p>
diff --git a/dojox/widget/tests/test_Iterator.html b/dojox/widget/tests/test_Iterator.html
index c14b9a2..bfb93f0 100644
--- a/dojox/widget/tests/test_Iterator.html
+++ b/dojox/widget/tests/test_Iterator.html
@@ -11,7 +11,7 @@
 	</style>
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -31,7 +31,7 @@
 
 	<div dojoType="dojo.data.ItemFileReadStore" 
 		url="../../../dijit/tests/_data/countries.json" 
-		jsId="stateStore"></div>
+		data-dojo-id="stateStore"></div>
 	
 	<h3>Data store backed Iterator</h3>
 	<ul>
diff --git a/dojox/widget/tests/test_Loader.html b/dojox/widget/tests/test_Loader.html
index 637bef5..3ab2388 100644
--- a/dojox/widget/tests/test_Loader.html
+++ b/dojox/widget/tests/test_Loader.html
@@ -11,7 +11,7 @@
 		@import "../Loader/Loader.css"; 
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript" src="../Loader.js"></script>
 	<script type="text/javascript">
 		// dojo.require("dojox.widget.Loader"); 
diff --git a/dojox/widget/tests/test_MultiSelectCalendar-async.html b/dojox/widget/tests/test_MultiSelectCalendar-async.html
index b9d4194..db83477 100644
--- a/dojox/widget/tests/test_MultiSelectCalendar-async.html
+++ b/dojox/widget/tests/test_MultiSelectCalendar-async.html
@@ -6,7 +6,7 @@
 <style type="text/css">
 		@import "../../../dijit/themes/claro/claro.css";
 </style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"  djConfig="parseOnLoad:1,isDebug:1,async:1"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js"  data-dojo-config="parseOnLoad:1,isDebug:1,async:1"></script>
 	<script type="text/javascript">
 		require([
 				"dojox/widget/MultiSelectCalendar",
diff --git a/dojox/widget/tests/test_MultiSelectCalendar.html b/dojox/widget/tests/test_MultiSelectCalendar.html
index 2bc5fc0..1474ae4 100644
--- a/dojox/widget/tests/test_MultiSelectCalendar.html
+++ b/dojox/widget/tests/test_MultiSelectCalendar.html
@@ -6,7 +6,7 @@
 <style type="text/css">
 		@import "../../../dijit/themes/claro/claro.css";
 </style>
-    <script type="text/javascript" src="../../../dojo/dojo.js"  djConfig="parseOnLoad: true"></script>
+    <script type="text/javascript" src="../../../dojo/dojo.js"  data-dojo-config="parseOnLoad: true"></script>
     <script type="text/javascript">
        dojo.require("dojo.parser");
 		dojo.require('dojox.widget.MultiSelectCalendar');
diff --git a/dojox/widget/tests/test_Pager.html b/dojox/widget/tests/test_Pager.html
index 96740c7..6ec3000 100644
--- a/dojox/widget/tests/test_Pager.html
+++ b/dojox/widget/tests/test_Pager.html
@@ -8,25 +8,24 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 		@import "../Pager/Pager.css";
 	</style>
-	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djconfig="parseOnLoad:true, isDebug: true"></script>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, isDebug: true"></script>
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
 
-	<script type="text/javascript" src="../Pager.js"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.data.ItemFileReadStore");
 		dojo.require("dojox.widget.Pager");
 	</script>
-	
+
 	<style type="text/css">
 		body {
 			font-family: Arial;
 		}
-		
+
 		ol li, ul li {
 			font-size:1em;
 			line-height:1.5em;
-			margin:0pt;
+			margin:0;
 		}
 		#result {
 			font-size: 12px;
@@ -35,13 +34,13 @@
 	</style>
 </head>
 <body class="tundra">
-	
+
 	<h1 class="testTitle">dojox.widget.Pager</h1>
 
 	<div style="clear: both" id="result">Click on one of the menu items</div>
 
 	<!-- the datastore -->
-	<div dojoType="dojo.data.ItemFileReadStore" jsId="pagerStore" id="pagerStore" url="_pager-data.json"></div>
+	<div dojoType="dojo.data.ItemFileReadStore" data-dojo-id="pagerStore" id="pagerStore" url="_pager-data.json"></div>
 
 	<h2>Horizontal</h2>
 
@@ -61,9 +60,9 @@
 		<div dojoType="dojox.widget.Pager" id="dojoxMenu2s" itemsPage="4" pagerPos="none" 
 			store="pagerStore" statusPos="trailing" style="width: 410px; height: 150px"></div>
 	</div>
-	
+
 	<h2>Vertical</h2>
-	
+
 	<div style="padding:8px; float:left;">
 		<div dojoType="dojox.widget.Pager" id="dojoxMenu3" itemsPage="2" orientation="vertical" 
 			store="pagerStore" style="width: 150px; height: 400px"></div>
diff --git a/dojox/widget/tests/test_PlaceholderMenuItem.html b/dojox/widget/tests/test_PlaceholderMenuItem.html
index a675d8e..c9d1484 100644
--- a/dojox/widget/tests/test_PlaceholderMenuItem.html
+++ b/dojox/widget/tests/test_PlaceholderMenuItem.html
@@ -15,7 +15,7 @@
 	
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 	
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/widget/tests/test_Portlet.html b/dojox/widget/tests/test_Portlet.html
index 0eb909e..5df4967 100644
--- a/dojox/widget/tests/test_Portlet.html
+++ b/dojox/widget/tests/test_Portlet.html
@@ -17,7 +17,7 @@
 	</style>		
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -45,7 +45,7 @@
 		<div dojoType="dojox.widget.Portlet" title="Test Title 1" id="portlet1">
 			<div dojoType="dojox.widget.PortletSettings">
 				Use Bold Text: <div dojoType="dijit.form.CheckBox">
-					<script type="dojo/connect" event="onClick">
+					<script type="dojo/connect" data-dojo-event="onClick">
 						var portlet = dijit.byId("portlet1");
 					  dojo.style(portlet.containerNode, "fontWeight", this.checked ? "bold" : "normal");
 					</script>
@@ -69,7 +69,7 @@
 		<div dojoType="dojox.widget.Portlet" title="Portlet with Dialog Settings" id="portlet2">
 			<div dojoType="dojox.widget.PortletDialogSettings" title="Settings in a Dialog">
 				Use Bold Text: <div dojoType="dijit.form.CheckBox">
-					<script type="dojo/connect" event="onClick">
+					<script type="dojo/connect" data-dojo-event="onClick">
 					  dojo.style(dijit.byId('portlet2').containerNode, "fontWeight", this.checked ? "bold" : "normal");
 					</script>
 				</div>
diff --git a/dojox/widget/tests/test_PortletInGridContainer.html b/dojox/widget/tests/test_PortletInGridContainer.html
index 9a37f07..d7437e6 100644
--- a/dojox/widget/tests/test_PortletInGridContainer.html
+++ b/dojox/widget/tests/test_PortletInGridContainer.html
@@ -78,7 +78,7 @@
 	</style>
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: false"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:false, parseOnLoad: false"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -92,16 +92,16 @@
 	<div id="masker"></div>
 
 	<span dojoType="dojox.data.HtmlStore"
-		jsId="htmlStore" dataId="gridDataTable">
+		data-dojo-id="htmlStore" dataId="gridDataTable">
 	</span>
 
 	<div dojoType="dojox.data.FileStore" url="../../data/demos/stores/filestore_dojotree.php"
-					jsId="fileStore" pathAsQueryParam="true"></div>
+					data-dojo-id="fileStore" pathAsQueryParam="true"></div>
 
-	<div dojoType="dijit.tree.ForestStoreModel" jsId="fileModel"
+	<div dojoType="dijit.tree.ForestStoreModel" data-dojo-id="fileModel"
 		store="fileStore" query="{}"
 		rootId="DojoFiles" rootLabel="Dojo Files" childrenAttrs="children">
-		<script type="dojo/method" event="getChildren" args="parent, callback">
+		<script type="dojo/method" data-dojo-event="getChildren" data-dojo-args="parent, callback">
 			if (!this._allItems) {
 			  this._allItems = [];
 			}
@@ -115,7 +115,7 @@
 
 	</div>
 
-	<div dojoType="dijit.Menu" id="gridCols" jsId="gridCols" style="display: none">
+	<div dojoType="dijit.Menu" id="gridCols" data-dojo-id="gridCols" style="display: none">
 		<div dojoType="dojox.widget.PlaceholderMenuItem" label="GridColumns"></div>
 	</div>
 
@@ -200,7 +200,7 @@
 						  <div dojoType="dijit.form.Button" onClick="dijit.byId('lineChartSettings').toggle();">OK</div>
 						</div>
 					</div>
-					<script type="dojo/connect" event="onUpdateSize">
+					<script type="dojo/connect" data-dojo-event="onUpdateSize">
 						if(window.chart){chart.resize();}
 					</script>
 					<div>
@@ -311,7 +311,7 @@
 						<script type="dojo/connect">
 							this.set("selectedIndex", dojo.cookie(this.id + "-selectedIndex") || 0);
 						</script>
-						<script type="dojo/connect" event="attr" args="name, value">
+						<script type="dojo/connect" data-dojo-event="attr" data-dojo-args="name, value">
 							if(name == "selectedIndex"){
 								dojo.cookie(this.id + "-selectedIndex", value);
 
@@ -420,7 +420,7 @@
 					model="fileModel"
 					persist="false"
 					style="overflow-y: auto;height: 100%;max-width: 230px;">
-					<script type="dojo/method" event="onClick" args="item">
+					<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="item">
 						if (fileStore.isItem(item)){
 							dojo.publish("/fileinfo", [fileStore, item]);
 						}
@@ -475,7 +475,7 @@
 						<div dojoType="dojox.widget.Portlet" dndType="Portlet" title="File Contents"
 							id="fileContentPortlet"
 								style="max-height: 350px;">
-							<script type="dojo/connect" event="startup">
+							<script type="dojo/connect" data-dojo-event="startup">
 								var widget = dijit.byId("fileContents");
 								dojo.style(this.containerNode, {
 								  height: "310px",
@@ -498,7 +498,7 @@
 								});
 							</script>
 							<div dojoType="dijit.layout.ContentPane" id="fileContents" parseOnLoad="false">
-								<script type="dojo/method" event="_setContent" args="data, isFake">
+								<script type="dojo/method" data-dojo-event="_setContent" data-dojo-args="data, isFake">
 									var text = typeof data == "string" ? data : data.textContent;
 									if (text.indexOf("<img") != 0 && text.indexOf("<span") != 0) {
 									  text = text.replace(/</gm, "<").replace(/>/gm, ">")
@@ -525,7 +525,7 @@
 								}));
 
 							</script>
-							<script type="dojo/connect" event="startup">
+							<script type="dojo/connect" data-dojo-event="startup">
 								dojo.require("dojox.charting.themes.Bahamation");
 								var dc = dojox.charting;
 
@@ -545,7 +545,7 @@
 								});
 								this.updateChart();
 							</script>
-							<script type="dojo/method" event="updateChart">
+							<script type="dojo/method" data-dojo-event="updateChart">
 								var extensions = {};
 								var items = this._items;
 								var dc = dojox.charting;
diff --git a/dojox/widget/tests/test_PortletInGridContainer.js b/dojox/widget/tests/test_PortletInGridContainer.js
index 83852b3..45ceff5 100644
--- a/dojox/widget/tests/test_PortletInGridContainer.js
+++ b/dojox/widget/tests/test_PortletInGridContainer.js
@@ -1,3 +1,4 @@
+dojo.provide("dojox.widget.tests.test_PortletInGridContainer");
 dojo.require("dijit.dijit");
 dojo.require("dojo.date.locale");
 dojo.require("dojo.cookie");
diff --git a/dojox/widget/tests/test_PortletInGridContainerColumns.html b/dojox/widget/tests/test_PortletInGridContainerColumns.html
index 4dc493d..f74e681 100644
--- a/dojox/widget/tests/test_PortletInGridContainerColumns.html
+++ b/dojox/widget/tests/test_PortletInGridContainerColumns.html
@@ -23,7 +23,7 @@
 	</style>		
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:false, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/widget/tests/test_Roller.html b/dojox/widget/tests/test_Roller.html
index ef6fa79..9e8200b 100644
--- a/dojox/widget/tests/test_Roller.html
+++ b/dojox/widget/tests/test_Roller.html
@@ -9,7 +9,7 @@
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<title>Testing the Roller / Slider / Exploder</title>
 	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djconfig="parseOnLoad:true, isDebug: true, defaultTestTheme:'soria'"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, isDebug: true, defaultTestTheme:'soria'"></script>
 	<script type="text/javascript" src="../Roller.js"></script>
 	<script type="text/javascript">
 	dojo.require("dojo.parser");
diff --git a/dojox/widget/tests/test_RollingList.html b/dojox/widget/tests/test_RollingList.html
index 9fd0f2c..639b8ab 100644
--- a/dojox/widget/tests/test_RollingList.html
+++ b/dojox/widget/tests/test_RollingList.html
@@ -17,7 +17,7 @@
 	
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 	
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -154,22 +154,22 @@
 
 	<h1 class="testTitle">Dojox Rolling List Test</h1>
 
-	<div dojoType="dojox.widget.RollingStore" jsId="continentStore" 
+	<div dojoType="dojox.widget.RollingStore" data-dojo-id="continentStore"
 		url="../../../dijit/tests/_data/countries.json">
 	</div>
 	
 	<h3>Rolling List - <input dojoType="dijit.form.TextBox" type="text" id="clickWatch" disabled value="None Selected..."></h3>
-	<div dojoType="dojox.widget.RollingList" jsId="myList" id="myList" store="continentStore"
+	<div dojoType="dojox.widget.RollingList" data-dojo-id="myList" id="myList" store="continentStore"
 		query="{type:'continent'}">
-		<script type="dojo/method" event="onChange" args="value">
-			console.debug("Set Value:", value);
+		<script type="dojo/method" data-dojo-event="onChange" data-dojo-args="value">
+			console.log("Set Value:", value);
 			if(value){
 				dijit.byId("clickWatch").attr("value", this.store.getIdentity(value));
 			}else{
 				dijit.byId("clickWatch").attr("value", "None Selected...");
 			}
 		</script>
-		<script type="dojo/method" event="getPaneForItem" args="item,parentPane,children">
+		<script type="dojo/method" data-dojo-event="getPaneForItem" data-dojo-args="item,parentPane,children">
 			var ret = dojox.widget.RollingList.prototype.getPaneForItem.apply(this, arguments);
 
 			if(!ret){
diff --git a/dojox/widget/tests/test_Rotator.html b/dojox/widget/tests/test_Rotator.html
index 743b2ac..7a25092 100644
--- a/dojox/widget/tests/test_Rotator.html
+++ b/dojox/widget/tests/test_Rotator.html
@@ -1,4 +1,4 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE HTML>
 <html>
 <head>
 	<title>dojox.widget.Rotator Test</title>
@@ -39,23 +39,34 @@
 	}
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:true, isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="async: true, selectorEngine:'acme'"></script>
 	<script type="text/javascript">
-	dojo.require("dojo.parser");
-	dojo.require("dojo.fx.easing");
-	dojo.require("dojox.widget.Rotator");
-	dojo.require("dojox.widget.rotator.Fade");
-	dojo.require("dojox.widget.rotator.Pan");
-	dojo.require("dojox.widget.rotator.Slide");
-	dojo.require("dojox.widget.rotator.Wipe");
-	
-	function log(id, msg){
-		var e = dojo.byId(id);
-		e.innerHTML += msg + "<br>";
-		e.scrollTop = 9999;
-	}
-	
-	dojo.addOnLoad(function(){
+	require([
+		"dojo/parser",
+		"dojo/_base/html",
+		"dojo/dom",
+		"dojox/widget/Rotator",
+		"dojo/fx/easing",
+		"dojo/domReady!",
+		"dojox/widget/rotator/Fade",
+		"dojox/widget/rotator/Pan",
+		"dojox/widget/rotator/PanFade",
+		"dojox/widget/rotator/Slide",
+		"dojox/widget/rotator/Wipe"
+	], function(parser, html, dom, Rotator, e) {
+
+		// Set global variable used in transitionParams
+		easing = e;
+
+		parser.parse();
+
+		log = function(id, msg){
+			var e = dom.byId(id);
+			e.innerHTML += msg + "<br>";
+			e.scrollTop = 9999;
+		};
+
 		// programmatic example
 		var contributors = [
 			[ "http://www.nexaweb.com",		"nexaweb.png",		"Nexaweb" ],
@@ -75,7 +86,7 @@
 			[ "http://www.wavemaker.com",	"wavemaker.png",	"WaveMaker" ],
 			[ "http://www.aptana.com",		"aptana.png",		"Aptana" ]
 		];
-		
+
 		var panes = [];
 		for(var i=0; i<contributors.length; i++){
 			var html = '<a href="' + contributors[i][0] + '" target="_new"><img src="images/rotator_'
@@ -90,15 +101,15 @@
 			}
 		}
 
-		var r = new dojox.widget.Rotator({
+		var r = new Rotator({
 				id: "myRotator13",
 				duration: 2000,
 				transition: "dojox.widget.rotator.fade",
 				panes: panes
 			},
-			dojo.byId("myRotator13")
+			dom.byId("myRotator13")
 		);
-	});
+	})
 	</script>
 </head>
 <body>
@@ -122,7 +133,7 @@
 	<button onclick="dojo.publish('myRotator/rotator/control', ['test']);">Bad Action</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" id="myRotator">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" id="myRotator">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -157,7 +168,7 @@
 		</div>
 	</div>
 
-	<h2>Controlled By jsId Reference, Default Swap Transition</h2>
+	<h2>Controlled By data-dojo-id Reference, Default Swap Transition</h2>
 	
 	<p>
 	<button onclick="myRotator2.prev();">Prev</button>
@@ -173,7 +184,7 @@
 	<button onclick="myRotator2.go(8);">Goto 8 (bad)</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator2">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator2">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -223,7 +234,8 @@
 	<button onclick="myRotator3.go(7);">Goto 7 (WaveMaker, Aptana)</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator3" transition="dojox.widget.rotator.crossFade">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator3"
+		 data-dojo-props="transition: 'dojox.widget.rotator.crossFade'">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -269,7 +281,8 @@
 	<button onclick="myRotator3_2.go(3);">Goto 3 (Sun, Google)</button>
 	</p>
 
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator3_2" transition="dojox.widget.rotator.crossFade">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator3_2"
+		 data-dojo-props="transition: 'dojox.widget.rotator.crossFade'">
 		<div class="pane" style="background-color:red;"></div>
 		<div class="pane" style="background-color:yellow;"></div>
 		<div class="pane" style="background-color:green;"></div>
@@ -287,7 +300,8 @@
 	<button onclick="myRotator4.go(3);">Goto 3 (Sun, Google) [pan up]</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator4" transition="dojox.widget.rotator.panLeft">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator4"
+		 data-dojo-props="transition: 'dojox.widget.rotator.panLeft'">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -324,8 +338,110 @@
 	<button onclick="myRotator5.go(7);">Goto 7 (WaveMaker, Aptana)</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator5" transition="dojox.widget.rotator.pan"
-			transitionParams="continuous:true,wrap:true,quick:true,duration:1000">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator5"
+		 data-dojo-props="transition: 'dojox.widget.rotator.pan', transitionParams: 'continuous:true,wrap:true,quick:true,duration:1000'">
+		<div class="pane">
+			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
+			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.sitepen.com" target="_new"><img src="images/rotator_sitepen.png" width="130" alt="Sitepen"/></a>
+			<a href="http://www.tibco.com" target="_new"><img src="images/rotator_tibco.png" width="130" alt="Tibco"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.webtide.com/" target="_new"><img src="images/rotator_webtide.png" width="130" alt="Webtide"/></a>
+			<a href="http://www.openlaszlo.com" target="_new"><img src="images/rotator_openlaszlo.png" width="150" alt="OpenLaszlo"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.sun.com" target="_new"><img src="images/rotator_sun.png" width="130" alt="Sun"/></a>
+			<a href="http://www.google.com" target="_new"><img src="images/rotator_google.png" width="130" alt="Google"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.aptana.com" target="_new"><img src="images/rotator_aptana.png" width="130" alt="Aptana"/></a>
+			<a href="http://www.aol.com" target="_new"><img src="images/rotator_aol.png" width="130" alt="AOL"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.ibm.com" target="_new"><img src="images/rotator_ibm.png" width="100" alt="IBM"/></a>
+			<a href="http://www.zend.com/" target="_new"><img src="images/rotator_zend.png" width="130" alt="Zend"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.bea.com" target="_new"><img src="images/rotator_bea.png" width="80" alt="BEA"/></a>
+			<a href="http://www.uxebu.com" target="_new"><img src="images/rotator_uxebu.png" width="120" alt="Uxebu"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.wavemaker.com" target="_new"><img src="images/rotator_wavemaker.png" width="130" alt="WaveMaker"/></a>
+			<a href="http://www.aptana.com" target="_new"><img src="images/rotator_aptana.png" width="130" alt="Aptana"/></a>
+		</div>
+	</div>
+
+	<h2>PanFade Transition</h2>
+	
+	<p>
+	<button onclick="myRotatorPanFade.prev();">Prev</button>
+	<button onclick="myRotatorPanFade.next();">Next</button>
+	<button onclick="myRotatorPanFade.go(0);">Goto 0 (Nexaweb, Renkoo)</button>
+	<button onclick="myRotatorPanFade.go(1);">Goto 1 (Sitepen, Tibco)</button>
+	<button onclick="myRotatorPanFade.go(2);">Goto 2 (Webtide, OpenLaszlo)</button>
+	<button onclick="myRotatorPanFade.go(3);">Goto 3 (Sun, Google)</button>
+	<button onclick="myRotatorPanFade.go(4);">Goto 4 (Aptana, AOL)</button>
+	<button onclick="myRotatorPanFade.go(5);">Goto 5 (IBM, Zend)</button>
+	<button onclick="myRotatorPanFade.go(6);">Goto 6 (BEA, Uxebu)</button>
+	<button onclick="myRotatorPanFade.go(7);">Goto 7 (WaveMaker, Aptana)</button>
+	</p>
+	
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotatorPanFade"
+		 data-dojo-props="transition: 'dojox.widget.rotator.panFade'">
+		<div class="pane">
+			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
+			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.sitepen.com" target="_new"><img src="images/rotator_sitepen.png" width="130" alt="Sitepen"/></a>
+			<a href="http://www.tibco.com" target="_new"><img src="images/rotator_tibco.png" width="130" alt="Tibco"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.webtide.com/" target="_new"><img src="images/rotator_webtide.png" width="130" alt="Webtide"/></a>
+			<a href="http://www.openlaszlo.com" target="_new"><img src="images/rotator_openlaszlo.png" width="150" alt="OpenLaszlo"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.sun.com" target="_new"><img src="images/rotator_sun.png" width="130" alt="Sun"/></a>
+			<a href="http://www.google.com" target="_new"><img src="images/rotator_google.png" width="130" alt="Google"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.aptana.com" target="_new"><img src="images/rotator_aptana.png" width="130" alt="Aptana"/></a>
+			<a href="http://www.aol.com" target="_new"><img src="images/rotator_aol.png" width="130" alt="AOL"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.ibm.com" target="_new"><img src="images/rotator_ibm.png" width="100" alt="IBM"/></a>
+			<a href="http://www.zend.com/" target="_new"><img src="images/rotator_zend.png" width="130" alt="Zend"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.bea.com" target="_new"><img src="images/rotator_bea.png" width="80" alt="BEA"/></a>
+			<a href="http://www.uxebu.com" target="_new"><img src="images/rotator_uxebu.png" width="120" alt="Uxebu"/></a>
+		</div>
+		<div class="pane">
+			<a href="http://www.wavemaker.com" target="_new"><img src="images/rotator_wavemaker.png" width="130" alt="WaveMaker"/></a>
+			<a href="http://www.aptana.com" target="_new"><img src="images/rotator_aptana.png" width="130" alt="Aptana"/></a>
+		</div>
+	</div>
+
+	<h2>PanFade Continuous Transition</h2>
+	
+	<p>
+	<button onclick="myRotatorPanFadeCont.prev();">Prev</button>
+	<button onclick="myRotatorPanFadeCont.next();">Next</button>
+	<button onclick="myRotatorPanFadeCont.go(0);">Goto 0 (Nexaweb, Renkoo)</button>
+	<button onclick="myRotatorPanFadeCont.go(1);">Goto 1 (Sitepen, Tibco)</button>
+	<button onclick="myRotatorPanFadeCont.go(2);">Goto 2 (Webtide, OpenLaszlo)</button>
+	<button onclick="myRotatorPanFadeCont.go(3);">Goto 3 (Sun, Google)</button>
+	<button onclick="myRotatorPanFadeCont.go(4);">Goto 4 (Aptana, AOL)</button>
+	<button onclick="myRotatorPanFadeCont.go(5);">Goto 5 (IBM, Zend)</button>
+	<button onclick="myRotatorPanFadeCont.go(6);">Goto 6 (BEA, Uxebu)</button>
+	<button onclick="myRotatorPanFadeCont.go(7);">Goto 7 (WaveMaker, Aptana)</button>
+	</p>
+	
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotatorPanFadeCont"
+		 data-dojo-props="transition: 'dojox.widget.rotator.panFade', transitionParams: 'continuous:true,wrap:true,quick:true,duration:1000'">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -371,8 +487,8 @@
 	<button onclick="myRotator6.go(3);">Goto 3 (Sun, Google) [pan up]</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator6" transition="dojox.widget.rotator.panLeft"
-			transitionParams="easing:dojo.fx.easing.cubicInOut">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator6"
+		 data-dojo-props="transition: 'dojox.widget.rotator.panLeft', transitionParams: 'easing: easing.cubicInOut'">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -408,8 +524,8 @@
 	<button onclick="myRotator7.go(7);">Goto 7 (WaveMaker, Aptana)</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator7" transition="dojox.widget.rotator.pan"
-			transitionParams="continuous:true,quick:true,duration:500,easing:dojo.fx.easing.cubicInOut">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator7"
+		 data-dojo-props="transition: 'dojox.widget.rotator.pan', transitionParams: 'continuous:true,quick:true,duration:500,easing: easing.cubicInOut'">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -457,7 +573,8 @@
 	<button onclick="myRotator8.resize(384, 90);">Resize to 384 x 90</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator8" transition="dojox.widget.rotator.slideLeft">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator8"
+		 data-dojo-props="transition: 'dojox.widget.rotator.slideLeft'">
 		<div class="pane" style="background-color:#fff799;">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -487,8 +604,8 @@
 	<button onclick="myRotator9.go(3);">Goto 3 (Sun, Google) [slide up]</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator9" transition="dojox.widget.rotator.slideLeft"
-			transitionParams="duration:1000,easing:dojo.fx.easing.cubicInOut">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator9"
+		 data-dojo-props="transition: 'dojox.widget.rotator.slideLeft', transitionParams: 'duration:1000, easing: easing.cubicInOut'">
 		<div class="pane" style="background-color:#fff799;">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -518,7 +635,8 @@
 	<button onclick="myRotator10.go(3);">Goto 3 (Sun, Google) [wipe up]</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator10" transition="dojox.widget.rotator.wipeLeft">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator10"
+		 data-dojo-props="transition: 'dojox.widget.rotator.wipeLeft'">
 		<div class="pane" style="background-color:#fff799;">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -548,8 +666,8 @@
 	<button onclick="myRotator11.go(3);">Goto 3 (Sun, Google) [wipe up]</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator11" transition="dojox.widget.rotator.wipeLeft"
-			transitionParams="duration:500,easing:dojo.fx.easing.cubicInOut">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator11"
+		 data-dojo-props="transition: 'dojox.widget.rotator.wipeLeft', transitionParams: 'duration:500, easing: easing.cubicInOut'">
 		<div class="pane" style="background-color:#fff799;">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -583,22 +701,23 @@
 	
 	<table><tr><td>
 	
-		<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator12" transition="dojox.widget.rotator.panLeft">
+		<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator12"
+			 data-dojo-props="transition: 'dojox.widget.rotator.panLeft'">
 			<div class="pane">
 				<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 				<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
 			</div>
 			<div class="pane" transition="dojox.widget.rotator.panDown">
-				<script type="dojo/method" event="onBeforeIn" args="args">
+				<script type="dojo/method" data-dojo-event="onBeforeIn" data-dojo-args="args">
 					log("myRotator12Log", "onBeforeIn - get dom nodes ready to be displayed, wire events");
 				</script>
-				<script type="dojo/method" event="onAfterIn" args="args">
+				<script type="dojo/method" data-dojo-event="onAfterIn" data-dojo-args="args">
 					log("myRotator12Log", "onAfterIn - this pane is now visible, so do cool stuff!");
 				</script>
-				<script type="dojo/method" event="onBeforeOut" args="args">
+				<script type="dojo/method" data-dojo-event="onBeforeOut" data-dojo-args="args">
 					log("myRotator12Log", "onBeforeOut - stop any animations, disconnect events, etc");
 				</script>
-				<script type="dojo/method" event="onAfterOut" args="args">
+				<script type="dojo/method" data-dojo-event="onAfterOut" data-dojo-args="args">
 					log("myRotator12Log", "onAfterOut - clean up dom, reset state, disconnect events, etc");
 				</script>
 				<a href="http://www.sitepen.com" target="_new"><img src="images/rotator_sitepen.png" width="130" alt="Sitepen"/></a>
@@ -647,7 +766,8 @@
 	</p>
 
 	<div class="rotator" style="position:relative;">
-		<div dojoType="dojox.widget.Rotator" class="rotatorStacked" style="z-index:100;" jsId="myRotator3_3" transition="dojox.widget.rotator.panLeft">
+		<div data-dojo-type="dojox/widget/Rotator" class="rotatorStacked" style="z-index:100;" data-dojo-id="myRotator3_3"
+			 data-dojo-props="transition: 'dojox.widget.rotator.panLeft'">
 			<div class="pane">
 				<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 				<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -665,7 +785,7 @@
 				<a href="http://www.google.com" target="_new"><img src="images/rotator_google.png" width="130" alt="Google"/></a>
 			</div>
 		</div>
-		<div dojoType="dojox.widget.Rotator" class="rotatorStacked" style="z-index:50;" jsId="myRotator3_4" transition="dojox.widget.rotator.crossFade">
+		<div data-dojo-type="dojox/widget/Rotator" class="rotatorStacked" style="z-index:50;" data-dojo-id="myRotator3_4" transition="dojox.widget.rotator.crossFade">
 			<div class="pane" style="background-color:red;"></div>
 			<div class="pane" style="background-color:yellow;"></div>
 			<div class="pane" style="background-color:green;"></div>
@@ -686,7 +806,8 @@
 	<button onclick="myRotator14.go(3);">Goto 3 (Sun, Google)</button>
 	</p>
 	
-	<div dojoType="dojox.widget.Rotator" class="rotator" jsId="myRotator14" transition="dojox.widget.rotator.doesNotExist">
+	<div data-dojo-type="dojox/widget/Rotator" class="rotator" data-dojo-id="myRotator14"
+		 data-dojo-props="transition: 'dojox.widget.rotator.doesNotExist'">
 		<div class="pane">
 			<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 			<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
diff --git a/dojox/widget/tests/test_RotatorController.html b/dojox/widget/tests/test_RotatorController.html
index aef8731..fff91b6 100644
--- a/dojox/widget/tests/test_RotatorController.html
+++ b/dojox/widget/tests/test_RotatorController.html
@@ -1,4 +1,4 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE HTML>
 <html>
 <head>
 	<title>dojox.widget.rotator.Controller Test</title>
@@ -212,13 +212,18 @@
 	}
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:true, isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, selectorEngine:'acme'"></script>
 	<script type="text/javascript">
-	dojo.require("dojo.parser");
-	dojo.require("dojox.widget.AutoRotator");
-	dojo.require("dojox.widget.rotator.Controller");
-	dojo.require("dojox.widget.rotator.Fade");
-	dojo.require("dojox.widget.rotator.Pan");
+		require([
+			"dojo/parser",
+			"dojox/widget/AutoRotator",
+			"dojox/widget/rotator/Controller",
+			"dojox/widget/rotator/Fade",
+			"dojox/widget/rotator/Pan",
+			"dojo/domReady!"
+		], function(parser) {
+			parser.parse()
+		})
 	</script>
 </head>
 <body>
@@ -229,7 +234,9 @@
 	
 	<div class="test1">
 		
-		<div dojoType="dojox.widget.AutoRotator" class="rotator" jsId="myRotator" duration="1000" transition="dojox.widget.rotator.crossFade">
+		<div data-dojo-type="dojox.widget.AutoRotator" class="rotator"
+			 data-dojo-id="myRotator"
+			 data-dojo-props="duration: 1000, transition: 'dojox.widget.rotator.crossFade'">
 			<div class="pane" title="Nexaweb/Renkoo">
 				<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 				<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -268,36 +275,44 @@
 			<tr>
 				<td>
 					<h3>Default</h3>
-					<div dojoType="dojox.widget.rotator.Controller" rotator="myRotator"></div>
+					<div data-dojo-type="dojox/widget/rotator/Controller"
+						 data-dojo-props="rotator: myRotator"></div>
 				</td>
 				<td>
 					<h3>Prev, Next</h3>
-					<div dojoType="dojox.widget.rotator.Controller" rotator="myRotator" commands="prev,next"></div>
+					<div data-dojo-type="dojox/widget/rotator/Controller"
+						 data-dojo-props="rotator: myRotator, commands: 'prev,next'"></div>
 				</td>
 				<td>
 					<h3>Prev, Play/Pause, Next</h3>
-					<div dojoType="dojox.widget.rotator.Controller" rotator="myRotator" commands="prev,play/pause,next"></div>
+					<div data-dojo-type="dojox/widget/rotator/Controller"
+						 data-dojo-props="rotator: myRotator, commands: 'prev,play/pause,next'"></div>
 				</td>
 				<td>
 					<h3>Prev, Numbers, Next</h3>
-					<div dojoType="dojox.widget.rotator.Controller" rotator="myRotator" commands="prev,#,next"></div>
+					<div data-dojo-type="dojox/widget/rotator/Controller"
+						 data-dojo-props="rotator: myRotator, commands: 'prev,#,next'"></div>
 				</td>
 				<td>
 					<h3>Titles</h3>
-					<div dojoType="dojox.widget.rotator.Controller" rotator="myRotator" commands="titles"></div>
-					<div>Note: Last pane has no title and<br>uses default.</div>
+					<div data-dojo-type="dojox/widget/rotator/Controller"
+						 data-dojo-props="rotator: myRotator, commands: 'titles'"></div>
+					<div>Note: Last pane has no title and<br>uses default/</div>
 				</td>
 				<td>
 					<h3>Play/Pause, Info</h3>
-					<div dojoType="dojox.widget.rotator.Controller" rotator="myRotator" commands="play/pause,info"></div>
+					<div data-dojo-type="dojox/widget/rotator/Controller"
+						 data-dojo-props="rotator: myRotator, commands: 'play/pause,info'"></div>
 				</td>
 				<td>
 					<h3>Numbers, Info</h3>
-					<div dojoType="dojox.widget.rotator.Controller" rotator="myRotator" commands="#,info"></div>
+					<div data-dojo-type="dojox.widget.rotator.Controller"
+						 data-dojo-props="rotator: myRotator, commands: '#,info'"></div>
 				</td>
 				<td>
 					<h3>Info</h3>
-					<div dojoType="dojox.widget.rotator.Controller" rotator="myRotator" commands="info"></div>
+					<div data-dojo-type="dojox/widget/rotator/Controller"
+						 data-dojo-props="rotator: myRotator, commands: 'info'"></div>
 				</td>
 			</tr>
 		</table>
@@ -310,8 +325,9 @@
 	
 		<div class="rotatorContainer">
 			
-			<div dojoType="dojox.widget.AutoRotator" class="rotator" jsId="myRotator2" duration="1000" transition="dojox.widget.rotator.pan"
-					transitionParams="quick:true,continuous:true" pauseOnManualChange="true" suspendOnHover="true">
+			<div data-dojo-type="dojox/widget/AutoRotator" class="rotator"
+				 data-dojo-id="myRotator2"
+				 data-dojo-props="duration: 1000, transition: 'dojox.widget.rotator.pan', transitionParams: 'quick:true,continuous:true,pauseOnManualChange:true,suspendOnHover:true'">
 				<div class="pane" title="Nexaweb/Renkoo">
 					<a href="http://www.nexaweb.com" target="_new"><img src="images/rotator_nexaweb.png" width="130" alt="Nexaweb"/></a>
 					<a href="http://www.renkoo.com" target="_new"><img src="images/rotator_renkoo.png" width="130" alt="Renkoo"/></a>
@@ -330,13 +346,17 @@
 				</div>
 			</div>
 			
-			<div dojoType="dojox.widget.rotator.Controller" class="tabs" rotator="myRotator2" commands="titles"></div>
+			<div data-dojo-type="dojox/widget/rotator/Controller" class="tabs"
+				 data-dojo-props="rotator: myRotator2, commands: 'titles'"></div>
 			
-			<div dojoType="dojox.widget.rotator.Controller" class="dots" rotator="myRotator2" commands="#"></div>
+			<div data-dojo-type="dojox/widget/rotator/Controller" class="dots"
+				 data-dojo-props="rotator: myRotator2, commands: '#'"></div>
 			
-			<div dojoType="dojox.widget.rotator.Controller" class="pager1" rotator="myRotator2" commands="prev,#,next"></div>
+			<div data-dojo-type="dojox/widget/rotator/Controller" class="pager1"
+				 data-dojo-props="rotator: myRotator2, commands: 'prev,#,next'"></div>
 			
-			<div dojoType="dojox.widget.rotator.Controller" class="pager2" rotator="myRotator2" commands="prev,play/pause,info,next"></div>
+			<div data-dojo-type="dojox/widget/rotator/Controller" class="pager2"
+				 data-dojo-props="rotator: myRotator2, commands: 'prev,play/pause,info,next'"></div>
 			
 		</div>
 		
diff --git a/dojox/widget/tests/test_Rotator_ThumbnailController.html b/dojox/widget/tests/test_Rotator_ThumbnailController.html
index 28ea74a..bea7fd8 100644
--- a/dojox/widget/tests/test_Rotator_ThumbnailController.html
+++ b/dojox/widget/tests/test_Rotator_ThumbnailController.html
@@ -1,4 +1,4 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE HTML>
 <html>
 <head>
 	<title>dojox.widget.rotator.ThumbnailController Test</title>
@@ -35,12 +35,17 @@
 	}
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad:true, isDebug:true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="async: true, selectorEngine: 'acme'"></script>
 	<script type="text/javascript">
-	dojo.require("dojo.parser");
-	dojo.require("dojox.widget.AutoRotator");
-	dojo.require("dojox.widget.rotator.Fade");
-	dojo.require("dojox.widget.rotator.ThumbnailController");
+		require([
+			"dojo/parser",
+			"dojo/domReady!",
+			"dojox/widget/AutoRotator",
+			"dojox/widget/rotator/Fade",
+			"dojox/widget/rotator/ThumbnailController"
+		], function(parser) {
+			parser.parse();
+		})
 	</script>
 </head>
 <body>
@@ -49,13 +54,16 @@
 	
 	<div class="test1">
 		
-		<div dojoType="dojox.widget.AutoRotator" class="rotator" jsId="myRotator" duration="1000" transition="dojox.widget.rotator.crossFade">
+		<div data-dojo-type="dojox/widget/AutoRotator" class="rotator"
+			 data-dojo-id="myRotator"
+			 data-dojo-props="duration: 1000, transition: 'dojox.widget.rotator.crossFade'">
 			<img src="../../image/tests/images/chris1_lg.jpg" thumbsrc="../../image/tests/images/chris1_sm.jpg" alt="Image 1"/>
 			<img src="../../image/tests/images/chris2_lg.jpg" thumbsrc="../../image/tests/images/chris2_sm.jpg" alt="Image 2"/>
 			<img src="../../image/tests/images/chris3_lg.jpg" thumbsrc="../../image/tests/images/chris3_sm.jpg" alt="Image 3"/>
 		</div>
 
-		<div dojoType="dojox.widget.rotator.ThumbnailController" rotator="myRotator"></div>
+		<div data-dojo-type="dojox/widget/rotator/ThumbnailController"
+			 data-dojo-props="rotator: myRotator"></div>
 		
 	</div>
 	
diff --git a/dojox/widget/tests/test_SortList.html b/dojox/widget/tests/test_SortList.html
index dcc4cf8..b1d9e0d 100644
--- a/dojox/widget/tests/test_SortList.html
+++ b/dojox/widget/tests/test_SortList.html
@@ -14,7 +14,7 @@
 	</style>
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -34,7 +34,7 @@
 
 	<h1 class="testTitle">Dojox SortList test</h1>
 
-	<div dojoType="dojo.data.ItemFileReadStore" url="../../../dijit/tests/_data/countries.json" jsId="stateStore"></div>
+	<div dojoType="dojo.data.ItemFileReadStore" url="../../../dijit/tests/_data/countries.json" data-dojo-id="stateStore"></div>
 	
 	<h3>Simple sortable example</h3>
 	<ul dojoType="dojox.widget.SortList" store="stateStore" title="sortable List" style="width:200px; height:200px;"></ul>
diff --git a/dojox/widget/tests/test_Standby.html b/dojox/widget/tests/test_Standby.html
index ae929db..6334412 100755
--- a/dojox/widget/tests/test_Standby.html
+++ b/dojox/widget/tests/test_Standby.html
@@ -18,7 +18,7 @@
 		}
 	</style>
 	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djconfig="parseOnLoad:true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dojox.widget.Standby");
@@ -286,7 +286,7 @@
 	<button id ="overlay8Button1" dojoType="dijit.form.Button">Click to show the standby overlay</button>
 	<br>
 	<button id ="overlay8Button2" dojoType="dijit.form.Button">Click to hide the standby overlay</button>
-	<div jsId="ifsStore" dojoType="dojo.data.ItemFileReadStore" url="../../../dijit/tests/_data/countries.json"></div>
+	<div data-dojo-id="ifsStore" dojoType="dojo.data.ItemFileReadStore" url="../../../dijit/tests/_data/countries.json"></div>
 	<table id ="overlayTarget8" dojoType="dojox.grid.DataGrid" style="width: 500px; height: 300px; margin: auto" store="ifsStore" query="{}">
 		<thead>
 			<tr>
@@ -303,8 +303,8 @@
 	<button id ="overlay9Button1" dojoType="dijit.form.Button">Click to show the standby overlay</button>
 	<br>
 	<button id ="overlay9Button2" dojoType="dijit.form.Button">Click to hide the standby overlay</button>
-	<div jsId="ifsStore2" dojoType="dojo.data.ItemFileReadStore" url="../../../dijit/tests/_data/countries.json"></div>
-	<div dojoType="dijit.tree.ForestStoreModel" jsId="continentModel" store="ifsStore2" query="{type:'continent'}" rootId="continentRoot" rootLabel="Continents" childrenAttrs="children"></div>
+	<div data-dojo-id="ifsStore2" dojoType="dojo.data.ItemFileReadStore" url="../../../dijit/tests/_data/countries.json"></div>
+	<div dojoType="dijit.tree.ForestStoreModel" data-dojo-id="continentModel" store="ifsStore2" query="{type:'continent'}" rootId="continentRoot" rootLabel="Continents" childrenAttrs="children"></div>
 	<div id ="overlayTarget9" dojoType="dijit.Tree" style="width: 30%" model="continentModel" query="{}"></div>
 	<div id ="standby9" target="overlayTarget9" dojoType="dojox.widget.Standby"></div>
 	<hr>
diff --git a/dojox/widget/tests/test_Standby_quirks.html b/dojox/widget/tests/test_Standby_quirks.html
index e858b94..c36b856 100755
--- a/dojox/widget/tests/test_Standby_quirks.html
+++ b/dojox/widget/tests/test_Standby_quirks.html
@@ -16,7 +16,7 @@
 		}
 	</style>
 	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djconfig="parseOnLoad:true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dojox.widget.Standby");
@@ -277,7 +277,7 @@
 	<button id ="overlay8Button1" dojoType="dijit.form.Button">Click to show the standby overlay</button>
 	<br>
 	<button id ="overlay8Button2" dojoType="dijit.form.Button">Click to hide the standby overlay</button>
-	<div jsId="ifsStore" dojoType="dojo.data.ItemFileReadStore", url="../../../dijit/tests/_data/countries.json"></div>
+	<div data-dojo-id="ifsStore" dojoType="dojo.data.ItemFileReadStore", url="../../../dijit/tests/_data/countries.json"></div>
 	<table id ="overlayTarget8" dojoType="dojox.grid.DataGrid", style="width: 500px; height: 300px; margin: auto" store="ifsStore", query="{}">
 		<thead>
 			<tr>
@@ -294,8 +294,8 @@
 	<button id ="overlay9Button1" dojoType="dijit.form.Button">Click to show the standby overlay</button>
 	<br>
 	<button id ="overlay9Button2" dojoType="dijit.form.Button">Click to hide the standby overlay</button>
-	<div jsId="ifsStore2" dojoType="dojo.data.ItemFileReadStore", url="../../../dijit/tests/_data/countries.json"></div>
-	<div dojoType="dijit.tree.ForestStoreModel" jsId="continentModel" store="ifsStore2" query="{type:'continent'}" rootId="continentRoot" rootLabel="Continents" childrenAttrs="children"></div>
+	<div data-dojo-id="ifsStore2" dojoType="dojo.data.ItemFileReadStore", url="../../../dijit/tests/_data/countries.json"></div>
+	<div dojoType="dijit.tree.ForestStoreModel" data-dojo-id="continentModel" store="ifsStore2" query="{type:'continent'}" rootId="continentRoot" rootLabel="Continents" childrenAttrs="children"></div>
 	<div id ="overlayTarget9" dojoType="dijit.Tree", style="width: 30%" model="continentModel", query="{}"></div>
 	<div id ="standby9" target="overlayTarget9" dojoType="dojox.widget.Standby"></div>
 	<hr>
diff --git a/dojox/widget/tests/test_Standby_rtl.html b/dojox/widget/tests/test_Standby_rtl.html
index f315f5b..69c87d2 100755
--- a/dojox/widget/tests/test_Standby_rtl.html
+++ b/dojox/widget/tests/test_Standby_rtl.html
@@ -17,7 +17,7 @@
 		}
 	</style>
 	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djconfig="parseOnLoad:true, isDebug: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dojox.widget.Standby");
@@ -278,7 +278,7 @@
 	<button id ="overlay8Button1" dojoType="dijit.form.Button">Click to show the standby overlay</button>
 	<br>
 	<button id ="overlay8Button2" dojoType="dijit.form.Button">Click to hide the standby overlay</button>
-	<div jsId="ifsStore" dojoType="dojo.data.ItemFileReadStore", url="../../../dijit/tests/_data/countries.json"></div>
+	<div data-dojo-id="ifsStore" dojoType="dojo.data.ItemFileReadStore", url="../../../dijit/tests/_data/countries.json"></div>
 	<table id ="overlayTarget8" dojoType="dojox.grid.DataGrid", style="width: 500px; height: 300px; margin: auto" store="ifsStore", query="{}">
 		<thead>
 			<tr>
@@ -295,8 +295,8 @@
 	<button id ="overlay9Button1" dojoType="dijit.form.Button">Click to show the standby overlay</button>
 	<br>
 	<button id ="overlay9Button2" dojoType="dijit.form.Button">Click to hide the standby overlay</button>
-	<div jsId="ifsStore2" dojoType="dojo.data.ItemFileReadStore", url="../../../dijit/tests/_data/countries.json"></div>
-	<div dojoType="dijit.tree.ForestStoreModel" jsId="continentModel" store="ifsStore2" query="{type:'continent'}" rootId="continentRoot" rootLabel="Continents" childrenAttrs="children"></div>
+	<div data-dojo-id="ifsStore2" dojoType="dojo.data.ItemFileReadStore", url="../../../dijit/tests/_data/countries.json"></div>
+	<div dojoType="dijit.tree.ForestStoreModel" data-dojo-id="continentModel" store="ifsStore2" query="{type:'continent'}" rootId="continentRoot" rootLabel="Continents" childrenAttrs="children"></div>
 	<div id ="overlayTarget9" dojoType="dijit.Tree", style="width: 30%" model="continentModel", query="{}"></div>
 	<div id ="standby9" target="overlayTarget9" dojoType="dojox.widget.Standby"></div>
 	<hr>
diff --git a/dojox/widget/tests/test_TitleGroup.html b/dojox/widget/tests/test_TitleGroup.html
index 33e21ac..60b33ed 100644
--- a/dojox/widget/tests/test_TitleGroup.html
+++ b/dojox/widget/tests/test_TitleGroup.html
@@ -25,7 +25,7 @@
 	</style>
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
diff --git a/dojox/widget/tests/test_Toaster.html b/dojox/widget/tests/test_Toaster.html
index d35f311..c4cd2a4 100644
--- a/dojox/widget/tests/test_Toaster.html
+++ b/dojox/widget/tests/test_Toaster.html
@@ -11,7 +11,7 @@
 		@import "../Toaster/Toaster.css";
 	</style>
 
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojox.widget.Toaster");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
diff --git a/dojox/widget/tests/test_UpgradeBar.html b/dojox/widget/tests/test_UpgradeBar.html
index 16fa52a..82f47a8 100755
--- a/dojox/widget/tests/test_UpgradeBar.html
+++ b/dojox/widget/tests/test_UpgradeBar.html
@@ -10,50 +10,51 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
 	<link href="../UpgradeBar/UpgradeBar.css" rel="stylesheet" />
-	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djconfig="parseOnLoad:false, isDebug: false"></script>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:false, isDebug: false"></script>
 
 	<script type="text/javascript">
-		dojo.require("dojox.widget.UpgradeBar");
-		
-		new dojox.widget.UpgradeBar({
-			notifications:[
-				{
-					validate:function(){
-						return dojo.isIE<10;	
-					},
-					message:   '<span>Your version of Internet Explorer needs to be upgraded to Firefox.</span>'
-							 + '<a href="http://www.getfirefox.net/">Get Firefox</a>'
-				},
-				{
-					validate:function(){
-						return dojo.isFF<4;
+		require(["dojox/widget/UpgradeBar", "dojo/sniff", "dojox/embed/Flash"], function(UpgradeBar, has, flash){
+
+			new UpgradeBar({
+				notifications:[
+					{
+						validate:function(){
+							return has("ie")<10;
+						},
+						message:   '<span>Your version of Internet Explorer needs to be upgraded to Firefox.</span>'
+								 + '<a href="http://www.getfirefox.net/">Get Firefox</a>'
 					},
-					message:   '<span>Your version of Firefox needs to be upgraded to a version that does not exist.</span>'
-							 + '<a href="http://www.getfirefox.net/">Get Firefox</a>'
-				},
-				{
-					validate:function(){
-						var evals = true;
-						try{ evals = dojox.embed.Flash.available<14}catch(e){}
-						return evals;	
+					{
+						validate:function(){
+							return has("ff")<20;
+						},
+						message:   '<span>Your version of Firefox needs to be upgraded to a version that does not exist.</span>'
+								 + '<a href="http://www.getfirefox.net/">Get Firefox</a>'
 					},
-					message:   '<span>This app needs a version of Flash that has never been released.</span>'
-							 + '<a href="http://www.adobe.com/downloads/">Get Flash Player</a>'
-				},
-				{
-					validate:function(){
-						return !google.gears;	
+					{
+						validate:function(){
+							var evals = true;
+							try{ evals = flash.available<14}catch(e){}
+							return evals;
+						},
+						message:   '<span>This app needs a version of Flash that has never been released.</span>'
+								 + '<a href="http://www.adobe.com/downloads/">Get Flash Player</a>'
 					},
-					message:   '<span>This app will perform better with Google Gears.</span>'
-							 + '<a href="http://gears.google.com/download.html">Download Google Gears</a>'
-				}
-			]	
+					{
+						validate:function(){
+							return typeof google == "undefined" || !google.gears;
+						},
+						message:   '<span>This app will perform better with Google Gears.</span>'
+								 + '<a href="http://gears.google.com/download.html">Download Google Gears</a>'
+					}
+				]
+			});
 		});
 	</script>
-	
+
 </head>
 <body class="tundra">
-	<h1 class="testTitle">dojox.widget.UpgradeBar</h1>
+	<h1 class="testTitle">dojox/widget/UpgradeBar</h1>
 </body>
 </html>
diff --git a/dojox/widget/tests/test_UpgradeBar_markup.html b/dojox/widget/tests/test_UpgradeBar_markup.html
index 387649c..02e96cf 100644
--- a/dojox/widget/tests/test_UpgradeBar_markup.html
+++ b/dojox/widget/tests/test_UpgradeBar_markup.html
@@ -7,40 +7,40 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
 	<link href="../UpgradeBar/UpgradeBar.css" rel="stylesheet" />
-	
-	<script type="text/javascript" src="../../../dojo/dojo.js" djconfig="parseOnLoad:true, isDebug: false, popup:true"></script>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="parseOnLoad:true, isDebug: false, popup:true"></script>
 
 	<script type="text/javascript">
-		dojo.require("dojo.parser");
-		dojo.require("dojox.widget.UpgradeBar");
-		
-		// for testing:
-		//dojo.require("dojo.gears");
-		//dojo.require("dojox.embed.Flash");
-		
+		require(["dojo/parser", "dojo/domReady", "dojox/widget/UpgradeBar", "dojox/embed/Flash", "dojo/sniff"], function(parser, domReady, UpgradeBar, flashModule, hasModule){
+			// globalize these; eww, yes, but useful for demo purposes,
+			// for the inline functions in the validate attributes
+			has = hasModule;
+			flash = flashModule;
+			domReady(dojo.hitch(parser, "parse"));
+		});
 	</script>
-	
+
 </head>
 <body class="tundra">
-	
+
 	<h1 class="testTitle">dojox.widget.UpgradeBar</h1>
-	
-	<div dojoType="dojox.widget.UpgradeBar" id="upgradeBar" permDismiss="true">
-		<div validate="dojo.isIE<10">
+
+	<div data-dojo-type="dojox.widget.UpgradeBar" id="upgradeBar">
+		<div validate="has('ie')<10">
 			<span>Your browser sucks. Download a good one.</span>
-			<a href="http://www.getfirefox.net/">Get Firefox</a>	
+			<a href="http://www.getfirefox.net/">Get Firefox</a>
 		</div>
-	
-		<div validate="dojo.isFF<3">
-			<span>Your version of Firefox needs to be upgraded to version 3.</span>
-			<a href="http://www.getfirefox.net/">Get Firefox</a>	
+
+		<div validate="has('ff')<20">
+			<span>Your version of Firefox needs to be upgraded to version 20.</span>
+			<a href="http://www.getfirefox.net/">Get Firefox</a>
 		</div>
-		
-		<div validate="dojox.embed.Flash.available<14">
+
+		<div validate="flash.available<14">
 			<span>This app needs a version of Flash that does not yet exist.</span>
 			<a href="http://www.adobe.com/downloads/">Download Flash 14</a>
 		</div>
-		
+
 		<div validate="!google.gears">
 			<span>This app will perform better with Google Gears.</span>
 			<a href="http://gears.google.com/download.html">Download Google Gears</a>
diff --git a/dojox/widget/tests/test_Wizard.html b/dojox/widget/tests/test_Wizard.html
index 711f28c..a88bfe4 100644
--- a/dojox/widget/tests/test_Wizard.html
+++ b/dojox/widget/tests/test_Wizard.html
@@ -16,6 +16,7 @@
 
 	<script type="text/javascript">
 		dojo.require("dojox.widget.Wizard");
+		dojo.require("dojox.widget.WizardPane");
 	
 		dojo.require("dijit.Dialog");
 		dojo.require("dijit.layout.AccordionContainer");
@@ -161,7 +162,7 @@
 				<h1>Tab 5</h1>
 				... and now you can finish up.
 			</div>
-			<script type="dojo/method" event="cancelFunction">
+			<script type="dojo/method" data-dojo-event="cancelFunction">
 				alert("dojo/method cancel function on container! bye.")
 				this.destroy();
 			</script>
diff --git a/dojox/wire.js b/dojox/wire.js
index 3426381..0d2a2ee 100644
--- a/dojox/wire.js
+++ b/dojox/wire.js
@@ -1,3 +1,9 @@
-dojo.provide("dojox.wire");
-dojo.require("dojox.wire._base");
-
+define(['./wire/_base'],function(){
+	/*=====
+	 return {
+	 // summary:
+	 //		Deprecated.  Should require dojox/wire modules directly rather than trying to access them through
+	 //		this module.
+	 };
+	 =====*/
+});
diff --git a/dojox/wire/CompositeWire.js b/dojox/wire/CompositeWire.js
index 5dc145b..f73cc80 100644
--- a/dojox/wire/CompositeWire.js
+++ b/dojox/wire/CompositeWire.js
@@ -4,9 +4,9 @@ dojo.require("dojox.wire._base");
 dojo.require("dojox.wire.Wire");
 
 dojo.declare("dojox.wire.CompositeWire", dojox.wire.Wire, {
-	//	summary:
+	// summary:
 	//		A Wire for composite values in object or array
-	//	description:
+	// description:
 	//		This class has multiple child Wires for object properties or array
 	//		elements.
 	//		When an object with Wires is specified to 'children' property, they
@@ -17,29 +17,29 @@ dojo.declare("dojox.wire.CompositeWire", dojox.wire.Wire, {
 	_wireClass: "dojox.wire.CompositeWire",
 
 	constructor: function(/*Object*/args){
-		//	summary:
+		// summary:
 		//		Initialize properties
-		//	description:
+		// description:
 		//		If object properties or array elements specified in 'children'
 		//		property are not Wires, Wires are created from them as
 		//		arguments, with 'parent' property set to this Wire instance.
-		//	args:
-		//		Arguments to initialize properties
-		//		children:
-		//			An object or array containing child Wires
+		// args:
+		//		Arguments to initialize properties.
+		//
+		//		- children: An object or array containing child Wires
 		this._initializeChildren(this.children);
 	},
 	_getValue: function(/*Object||Array*/object){
-		//	summary:
+		// summary:
 		//		Return an object with property values or an array with element
 		//		values
-		//	description:
+		// description:
 		//		This method calls getValue() method of the child Wires with
 		//		'object' argument and returns an object with the values as
 		//		properties or an arary of the values as elements.
-		//	object:
+		// object:
 		//		A root object
-		//	returns:
+		// returns:
 		//		An object or array with values
 		if(!object || !this.children){
 			return object; //Object||Array
@@ -53,17 +53,17 @@ dojo.declare("dojox.wire.CompositeWire", dojox.wire.Wire, {
 	},
 
 	_setValue: function(/*Object||Array*/object, /*Object||Array*/value){
-		//	summary:
+		// summary:
 		//		Set an object properties or an array elements to an object
-		//	desription:
+		// description:
 		//		This method calls setValues() method of the child Wires with
 		//		a corresponding property or element in 'value' argument and
 		//		'object' argument.
-		//	object:
+		// object:
 		//		A root object
-		//	value:
+		// value:
 		//		An object or array with values to set
-		//	returns:
+		// returns:
 		//		'object'
 		if(!object || !this.children){
 			return object; //Object||Array
@@ -76,13 +76,13 @@ dojo.declare("dojox.wire.CompositeWire", dojox.wire.Wire, {
 	},
 
 	_initializeChildren: function(/*Object||Array*/children){
-		//	summary:
+		// summary:
 		//		Initialize child Wires
-		//	description:
+		// description:
 		//		If object properties or array elements specified in 'children'
 		//		argument are not Wires, Wires are created from them as
 		//		arguments, with 'parent' property set to this Wire instance.
-		//	children:
+		// children:
 		//		An object or array containing child Wires
 		if(!children){
 			return; //undefined
diff --git a/dojox/wire/DataWire.js b/dojox/wire/DataWire.js
index 01f2327..75ddb8a 100644
--- a/dojox/wire/DataWire.js
+++ b/dojox/wire/DataWire.js
@@ -3,9 +3,9 @@ dojo.provide("dojox.wire.DataWire");
 dojo.require("dojox.wire.Wire");
 
 dojo.declare("dojox.wire.DataWire", dojox.wire.Wire, {
-	//	summary:
+	// summary:
 	//		A Wire for item attributes of data stores
-	//	description:
+	// description:
 	//		This class accesses item attributes of data stores with a dotted
 	//		notation of attribute names specified to 'attribute' property,
 	//		using data APIs of a data store specified to 'dataStore' property.
@@ -18,26 +18,25 @@ dojo.declare("dojox.wire.DataWire", dojox.wire.Wire, {
 	
 	_wireClass: "dojox.wire.DataWire",
 
-	constructor: function(/*Object*/args){
-		//	summary:
+	constructor: function(/*Object*/ args){
+		// summary:
 		//		Initialize properties
-		//	description:
+		// description:
 		//		If 'dataStore' property is not specified, but 'parent' property
 		//		is specified, 'dataStore' property is copied from the parent.
-		//	args:
-		//		Arguments to initialize properties
-		//		dataStore:
-		//			A data store
-		//		attribute:
-		//			A dotted notation to a descendant attribute
+		// args:
+		//		Arguments to initialize properties:
+		//
+		//		- dataStore: A data store
+		//		- attribute: A dotted notation to a descendant attribute
 		if(!this.dataStore && this.parent){
 			this.dataStore = this.parent.dataStore;
 		}
 	},
 	_getValue: function(/*Object*/object){
-		//	summary:
+		// summary:
 		//		Return an attribute value of an item
-		//	description:
+		// description:
 		//		This method uses a root item passed in 'object' argument and
 		//		'attribute' property to call getValue() method of
 		//		'dataStore'.
@@ -45,9 +44,9 @@ dojo.declare("dojox.wire.DataWire", dojox.wire.Wire, {
 		//		method is called, instead.
 		//		If an index is specified in the array suffix, an array element
 		//		for the index is returned, instead of the array itself.
-		//	object:
+		// object:
 		//		A root item
-		//	returns:
+		// returns:
 		//		A value found, otherwise 'undefined'
 		if(!object || !this.attribute || !this.dataStore){
 			return object; //Object
@@ -65,9 +64,9 @@ dojo.declare("dojox.wire.DataWire", dojox.wire.Wire, {
 	},
 
 	_setValue: function(/*Object*/object, /*anything*/value){
-		//	summary:
+		// summary:
 		//		Set an attribute value to an item
-		//	description:
+		// description:
 		//		This method uses a root item passed in 'object' argument and
 		//		'attribute' property to identify an item.
 		//		Then, setValue() method of 'dataStore' is called with a leaf
@@ -76,11 +75,11 @@ dojo.declare("dojox.wire.DataWire", dojox.wire.Wire, {
 		//		method is called, instead.
 		//		If an index is specified in the array suffix, an array element
 		//		for the index is set to 'value', instead of the array itself.
-		//	object:
+		// object:
 		//		A root item
-		//	value:
+		// value:
 		//		A value to set
-		//	returns:
+		// returns:
 		//		'object', or 'undefined' for invalid attribute
 		if(!object || !this.attribute || !this.dataStore){
 			return object; //Object
@@ -100,20 +99,20 @@ dojo.declare("dojox.wire.DataWire", dojox.wire.Wire, {
 	},
 
 	_getAttributeValue: function(/*Object*/item, /*String*/attribute){
-		//	summary:
+		// summary:
 		//		Return an attribute value of an item
-		//	description:
+		// description:
 		//		This method uses an item passed in 'item' argument and
 		//		'attribute' argument to call getValue() method of 'dataStore'.
 		//		If an attribute name have an array suffix ("[]"), getValues()
 		//		method is called, instead.
 		//		If an index is specified in the array suffix, an array element
 		//		for the index is returned, instead of the array itself.
-		//	item:
+		// item:
 		//		An item
-		//	attribute
+		// attribute:
 		//		An attribute name
-		//	returns:
+		// returns:
 		//		A value found, otherwise 'undefined'
 		var value = undefined;
 		var i1 = attribute.indexOf('[');
@@ -136,9 +135,9 @@ dojo.declare("dojox.wire.DataWire", dojox.wire.Wire, {
 	},
 
 	_setAttributeValue: function(/*Object*/item, /*String*/attribute, /*anything*/value){
-		//	summary:
+		// summary:
 		//		Set an attribute value to an item
-		//	description:
+		// description:
 		//		This method uses an item passed in 'item' argument and
 		//		'attribute' argument to call setValue() method of 'dataStore'
 		//		with 'value' argument.
@@ -146,11 +145,11 @@ dojo.declare("dojox.wire.DataWire", dojox.wire.Wire, {
 		//		method is called, instead.
 		//		If an index is specified in the array suffix, an array element
 		//		for the index is set to 'value', instead of the array itself.
-		//	item:
+		// item:
 		//		An item
-		//	attribute:
+		// attribute:
 		//		An attribute name
-		//	value:
+		// value:
 		//		A value to set
 		var i1 = attribute.indexOf('[');
 		if(i1 >= 0){
diff --git a/dojox/wire/TableAdapter.js b/dojox/wire/TableAdapter.js
index 292cb7f..69378f0 100644
--- a/dojox/wire/TableAdapter.js
+++ b/dojox/wire/TableAdapter.js
@@ -3,9 +3,9 @@ dojo.provide("dojox.wire.TableAdapter");
 dojo.require("dojox.wire.CompositeWire");
 
 dojo.declare("dojox.wire.TableAdapter", dojox.wire.CompositeWire, {
-	//	summary:
+	// summary:
 	//		A composite Wire for table rows
-	//	description:
+	// description:
 	//		This class has multiple child Wires for object properties or array
 	//		elements of a table row.
 	//		The root object for this class must be an array.
@@ -18,31 +18,31 @@ dojo.declare("dojox.wire.TableAdapter", dojox.wire.CompositeWire, {
 	
 	_wireClass: "dojox.wire.TableAdapter",
 	
-	constructor: function(/*Object*/args){
-		//	summary:
+	constructor: function(/*Object*/ args){
+		// summary:
 		//		Initialize properties
-		//	description:
+		// description:
 		//		If object properties or array elements specified in 'columns'
 		//		property are not Wires, Wires are created from them as
 		//		arguments, with 'parent' property set to this Wire instance.
-		//	args:
-		//		Arguments to initialize properties
-		//		columns:
-		//			An object or array containing child Wires for column values
+		// args:
+		//		Arguments to initialize properties:
+		//
+		//		- columns: An object or array containing child Wires for column values
 		this._initializeChildren(this.columns);
 	},
 
 	_getValue: function(/*Array*/object){
-		//	summary:
+		// summary:
 		//		Return an array of table row value (object or array)
-		//	description:
+		// description:
 		//		This method iterates over an array specified to 'object'
 		//		argument and calls getValue() method of the child Wires with
 		//		each element of the array to get a row object or array.
 		//		Finally, an array with the row objects or arrays are retuned.
-		//	object:
+		// object:
 		//		A root array
-		//	returns:
+		// returns:
 		//		An array of table row value
 		if(!object || !this.columns){
 			return object; //Array
@@ -62,18 +62,18 @@ dojo.declare("dojox.wire.TableAdapter", dojox.wire.CompositeWire, {
 	},
 
 	_setValue: function(/*Array*/object, /*Array*/value){
-		//	summary:
+		// summary:
 		//		Not supported
 		throw new Error("Unsupported API: " + this._wireClass + "._setValue");
 	},
 
 	_getRow: function(/*Object||Array*/object){
-		//	summary:
+		// summary:
 		//		Return an array or object for a table row
-		//	description:
+		// description:
 		//		This method calls getValue() method of the child Wires to
 		//		create a row object or array.
-		//	returns:
+		// returns:
 		//		An array or object for a table row
 		var row = (dojo.isArray(this.columns) ? [] : {}); // array or object
 		for(var c in this.columns){
diff --git a/dojox/wire/TextAdapter.js b/dojox/wire/TextAdapter.js
index 8293bbe..63124e3 100644
--- a/dojox/wire/TextAdapter.js
+++ b/dojox/wire/TextAdapter.js
@@ -3,9 +3,9 @@ dojo.provide("dojox.wire.TextAdapter");
 dojo.require("dojox.wire.CompositeWire");
 
 dojo.declare("dojox.wire.TextAdapter", dojox.wire.CompositeWire, {
-	//	summary:
+	// summary:
 	//		A composite Wire for a concatenated text
-	//	description:
+	// description:
 	//		This class has multiple child Wires for text segment values.
 	//		Wires in 'segments' property are used to get text segments and
 	//		values are concatenated with an optional delimiter string specified
@@ -13,19 +13,18 @@ dojo.declare("dojox.wire.TextAdapter", dojox.wire.CompositeWire, {
 	
 	_wireClass: "dojox.wire.TextAdapter",
 	
-	constructor: function(/*Object*/args){
-		//	summary:
+	constructor: function(/*Object*/ args){
+		// summary:
 		//		Initialize properties
-		//	description:
+		// description:
 		//		If array elements specified in 'segments' are not Wires, Wires
 		//		are created from them as arguments, with 'parent' property set
 		//		to this Wire instance.
-		//	args:
-		//		Arguments to initialize properties
-		//		segments:
-		//			An array containing child Wires for text segment values
-		//		delimiter:
-		//			A delimiter string
+		// args:
+		//		Arguments to initialize properties:
+		//
+		//		- segments: An array containing child Wires for text segment values
+		//		- delimiter: A delimiter string
 		this._initializeChildren(this.segments);
 		if(!this.delimiter){
 			this.delimiter = "";
@@ -33,15 +32,15 @@ dojo.declare("dojox.wire.TextAdapter", dojox.wire.CompositeWire, {
 	},
 
 	_getValue: function(/*Object||Array*/object){
-		//	summary:
+		// summary:
 		//		Return a concatenated text
-		//	description:
+		// description:
 		//		This method calls getValue() method of the child Wires wuth
 		//		'object' argument and concatenate the values with 'delimiter'
 		//		property to return.
-		//	arg:
+		// arg:
 		//		A root object
-		//	returns:
+		// returns:
 		//		A concatinated text
 		if(!object || !this.segments){
 			return object; //Object||Array
@@ -56,22 +55,22 @@ dojo.declare("dojox.wire.TextAdapter", dojox.wire.CompositeWire, {
 	},
 
 	_setValue: function(/*Object||Array*/object, /*String*/value){
-		//	summary:
+		// summary:
 		//		Not supported
 		throw new Error("Unsupported API: " + this._wireClass + "._setValue");
 	},
 
 	_addSegment: function(/*String*/text, /*String*/segment){
-		//	summary:
+		// summary:
 		//		Return a concatenated text
-		//	description:
+		// description:
 		//		This method add a text segment specified to 'segment' argument
 		//		to a base text specified to 'text', with 'delimiter' property.
-		//	text:
+		// text:
 		//		A base text
-		//	segment:
+		// segment:
 		//		A text segment to add
-		//	returns:
+		// returns:
 		//		A concatinated text
 		if(!segment){
 			return text; //String
diff --git a/dojox/wire/TreeAdapter.js b/dojox/wire/TreeAdapter.js
index 55897c0..608b8f0 100644
--- a/dojox/wire/TreeAdapter.js
+++ b/dojox/wire/TreeAdapter.js
@@ -3,9 +3,9 @@ dojo.provide("dojox.wire.TreeAdapter");
 dojo.require("dojox.wire.CompositeWire");
 
 dojo.declare("dojox.wire.TreeAdapter", dojox.wire.CompositeWire, {
-	//	summary:
+	// summary:
 	//		A composite Wire for tree nodes
-	//	description:
+	// description:
 	//		This class has multiple child Wires for tree nodes, their title and
 	//		child nodes.
 	//		The root object for this class must be an array.
@@ -16,42 +16,42 @@ dojo.declare("dojox.wire.TreeAdapter", dojox.wire.CompositeWire, {
 	//		'children' Wires in 'nodes' property is used to iterate over child
 	//		node objects.
 	//		The node values are returned in an array as follows:
-	//			[
-	//				{title: title1,
-	//		  	 	children: [
-	//					{title: title2,
-	//					 child: ...},
-	//					{title: title3,
-	//					 child: ...},
-	//					...
-	//				]},
-	//				...
-	//			]
+	// |		[
+	// |			{title: title1,
+	// |	  	 	children: [
+	// |				{title: title2,
+	// |				 child: ...},
+	// |				{title: title3,
+	// |				 child: ...},
+	// |				...
+	// |			]},
+	// |			...
+	// |		]
 	//		This class only supports getValue(), but not setValue().
 	
 	_wireClass: "dojox.wire.TreeAdapter",
 	
-	constructor: function(/*Object*/args){
-		//	summary:
+	constructor: function(/*Object*/ args){
+		// summary:
 		//		Initialize properties
-		//	description:
+		// description:
 		//		If object properties ('node', 'title' and 'children') of array
 		//		elements specified in 'nodes' property are not Wires, Wires are
 		//		created from them as arguments, with 'parent' property set to
 		//		this Wire instance.
-		//	args:
-		//		Arguments to initialize properties
-		//		nodes:
-		//			An array containing objects for child Wires for node values
+		// args:
+		//		Arguments to initialize properties:
+		//
+		//		- nodes: An array containing objects for child Wires for node values
 		this._initializeChildren(this.nodes);
 	},
 	_getValue: function(/*Array*/object){
-		//	summary:
+		// summary:
 		//		Return an array of tree node values
-		//	description:
+		// description:
 		//		This method iterates over an array specified to 'object'
 		//		argument and calls getValue() method of 'node' Wires with each
-		//		element of the array to get object(s) that represetns nodes.
+		//		element of the array to get object(s) that represents nodes.
 		//		(If 'node' Wires are omitted, the array element is used for
 		//		further processing.)
 		//		Then, getValue() method of 'title' Wires are called to get
@@ -62,9 +62,9 @@ dojo.declare("dojox.wire.TreeAdapter", dojox.wire.CompositeWire, {
 		//		specified to 'children', it is used to gather child nodes and
 		//		their title strings in the same way recursively.
 		//		Finally, an array of the top-level node objects are retuned.
-		//	object:
+		// object:
 		//		A root array
-		//	returns:
+		// returns:
 		//		An array of tree node values
 		if(!object || !this.nodes){
 			return object; //Array
@@ -85,21 +85,21 @@ dojo.declare("dojox.wire.TreeAdapter", dojox.wire.CompositeWire, {
 	},
 
 	_setValue: function(/*Array*/object, /*Array*/value){
-		//	summary:
+		// summary:
 		//		Not supported
 		throw new Error("Unsupported API: " + this._wireClass + "._setValue");
 	},
 
 	_initializeChildren: function(/*Array*/children){
-		//	summary:
+		// summary:
 		//		Initialize child Wires
-		//	description:
+		// description:
 		//		If 'node' or 'title' properties of array elements specified in
 		//		'children' argument are not Wires, Wires are created from them
 		//		as arguments, with 'parent' property set to this Wire instance.
 		//		If an array element has 'children' property, this method is
 		//		called recursively with it.
-		//	children:
+		// children:
 		//		An array of objects containing child Wires
 		if(!children){
 			return; //undefined
@@ -126,9 +126,9 @@ dojo.declare("dojox.wire.TreeAdapter", dojox.wire.CompositeWire, {
 	},
 
 	_getNodes: function(/*Object*/object, /*Object*/child){
-		//	summary:
+		// summary:
 		//		Return an array of tree node values
-		//	description:
+		// description:
 		//		This method calls getValue() method of 'node' Wires with
 		//		'object' argument to get object(s) that represents nodes.
 		//		(If 'node' Wires are omitted, 'object' is used for further
@@ -141,11 +141,11 @@ dojo.declare("dojox.wire.TreeAdapter", dojox.wire.CompositeWire, {
 		//		specified to 'children', it is used to gather child nodes and
 		//		their title strings in the same way recursively.
 		//		Finally, an array of node objects are returned.
-		//	object:
+		// object:
 		//		An object
-		//	child:
+		// child:
 		//		An object with child Wires
-		//	returns:
+		// returns:
 		var array = null;
 		if(child.node){
 			array = child.node.getValue(object);
diff --git a/dojox/wire/Wire.js b/dojox/wire/Wire.js
index ffd2459..23dd14d 100644
--- a/dojox/wire/Wire.js
+++ b/dojox/wire/Wire.js
@@ -3,9 +3,9 @@ dojo.provide("dojox.wire.Wire");
 dojo.require("dojox.wire._base");
 
 dojo.declare("dojox.wire.Wire", null, {
-	//	summary:
+	// summary:
 	//		A default and base Wire to access an object property
-	//	description:
+	// description:
 	//		This class accesses a property of an object with a dotted notation
 	//		specified to 'property' property, such as "a.b.c", which identifies
 	//		a descendant property, "object.a.b.c".
@@ -22,22 +22,19 @@ dojo.declare("dojox.wire.Wire", null, {
 	_wireClass: "dojox.wire.Wire",
 	
 	constructor: function(/*Object*/args){
-		//	summary:
+		// summary:
 		//		Initialize properties
-		//	description:
+		// description:
 		//		If 'converter' property is specified and is a string for
 		//		a converter class, an instanceof the converter class is
 		//		created.
-		//	args:
-		//		Arguments to initialize properties
-		//		object:
-		//			A root object (or another Wire to access a root object)
-		//		property:
-		//			A dotted notation to a descendant property
-		//		type:
-		//			A type of the return value (for the source Wire)
-		//		converter:
-		//			A converter object (or class name) to convert the return
+		// args:
+		//		Arguments to initialize properties:
+		//
+		//		- object: A root object (or another Wire to access a root object)
+		//		- property: A dotted notation to a descendant property
+		//		- type: A type of the return value (for the source Wire)
+		//		- converter: A converter object (or class name) to convert the return
 		//			value (for the source Wire)
 		dojo.mixin(this, args);
 
@@ -83,17 +80,19 @@ dojo.declare("dojox.wire.Wire", null, {
 	},
 
 	getValue: function(/*Object||Array*/defaultObject){
-		//	summary:
+		// summary:
 		//		Return a value of an object
-		//	description:
-		//		This method first determins a root object as follows:
-		//		1. If 'object' property specified,
-		//		1.1 If 'object' is a Wire, its getValue() method is called to
-		//	    	obtain a root object.
-		//		1.2 Otherwise, use 'object' as a root object.
-		//		2. Otherwise, use 'defaultObject' argument.
-		//		3. If 'property' is specified, it is used to get a property
-		//			value.
+		// description:
+		//		This method first determines a root object as follows:
+		//
+		//			1. If 'object' property specified,
+		//			1.1 If 'object' is a Wire, its getValue() method is called to
+		//			obtain a root object.
+		//			1.2 Otherwise, use 'object' as a root object.
+		//			2. Otherwise, use 'defaultObject' argument.
+		//			3. If 'property' is specified, it is used to get a property
+		//				value.
+		//
 		//		Then, if a sub-class implements _getValue() method, it is
 		//		called with the root object to get the return value.
 		//		Otherwise, the root object (typically, a property valye) is
@@ -103,9 +102,9 @@ dojo.declare("dojox.wire.Wire", null, {
 		//		"boolean" and "array").
 		//		If 'converter' property is specified, its convert() method is
 		//		called to convert the value.
-		//	defaultObject:
+		// defaultObject:
 		//		A default root object
-		//	returns:
+		// returns:
 		//		A value found
 		var object = undefined;
 		if(dojox.wire.isWire(this.object)){
@@ -153,17 +152,19 @@ dojo.declare("dojox.wire.Wire", null, {
 	},
 
 	setValue: function(/*anything*/value, /*Object||Array*/defaultObject){
-		//	summary:
+		// summary:
 		//		Set a value to an object
-		//	description:
-		//		This method first determins a root object as follows:
-		//		1. If 'object' property specified,
-		//		1.1 If 'object' is a Wire, its getValue() method is called to
-		//	    	obtain a root object.
-		//		1.2 Otherwise, use 'object' as a root object.
-		//		2. Otherwise, use 'defaultObject' argument.
-		//		3. If 'property' is specified, it is used to get a property
-		//			value.
+		// description:
+		//		This method first determines a root object as follows:
+		//
+		//			1. If 'object' property specified,
+		//			1.1 If 'object' is a Wire, its getValue() method is called to
+		//				obtain a root object.
+		//			1.2 Otherwise, use 'object' as a root object.
+		//			2. Otherwise, use 'defaultObject' argument.
+		//			3. If 'property' is specified, it is used to get a property
+		//				value.
+		//
 		//		Then, if a sub-class implements _setValue() method, it is
 		//		called with the root object and 'value' argument to set
 		//		the value.
@@ -172,9 +173,9 @@ dojo.declare("dojox.wire.Wire", null, {
 		//		If the root object is undefined and 'object' property is a Wire
 		//		and a new object is created and returned by _setValue() it is
 		//		set through 'object' (setValue() method).
-		//	value:
+		// value:
 		//		A value to set
-		//	defaultObject:
+		// defaultObject:
 		//		A default root object
 		var object = undefined;
 		if(dojox.wire.isWire(this.object)){
@@ -239,9 +240,9 @@ dojo.declare("dojox.wire.Wire", null, {
 	},
 
 	_getPropertyValue: function(/*Object||Array*/object, /*String*/property){
-		//	summary:
+		// summary:
 		//		Return a property value of an object
-		//	description:
+		// description:
 		//		A value for 'property' of 'object' is returned.
 		//		If 'property' ends with an array index, it is used to indentify
 		//		an element of an array property.
@@ -249,11 +250,11 @@ dojo.declare("dojox.wire.Wire", null, {
 		//		'property' to obtain the property value.
 		//		If 'object' implements a getter for the property, it is called
 		//		to obtain the property value.
-		//	object:
+		// object:
 		//		A default root object
-		//	property:
+		// property:
 		//		A property name
-		//	returns:
+		// returns:
 		//		A value found, otherwise 'undefined'
 		var value = undefined;
 		var i1 = property.indexOf('[');
@@ -291,9 +292,9 @@ dojo.declare("dojox.wire.Wire", null, {
 	},
 
 	_setPropertyValue: function(/*Object||Array*/object, /*String*/property, /*anything*/value){
-		//	summary:
+		// summary:
 		//		Set a property value to an object
-		//	description:
+		// description:
 		//		'value' is set to 'property' of 'object'.
 		//		If 'property' ends with an array index, it is used to indentify
 		//		an element of an array property to set the value.
@@ -301,11 +302,11 @@ dojo.declare("dojox.wire.Wire", null, {
 		//		'property' and 'value' to set the property value.
 		//		If 'object' implements a setter for the property, it is called
 		//		with 'value' to set the property value.
-		//	object:
+		// object:
 		//		An object
-		//	property:
+		// property:
 		//		A property name
-		//	value:
+		// value:
 		//		A value to set
 		var i1 = property.indexOf('[');
 		if(i1 >= 0){
diff --git a/dojox/wire/XmlWire.js b/dojox/wire/XmlWire.js
index 90dd60e..ba0c464 100644
--- a/dojox/wire/XmlWire.js
+++ b/dojox/wire/XmlWire.js
@@ -4,9 +4,9 @@ dojo.require("dojox.xml.parser");
 dojo.require("dojox.wire.Wire");
 
 dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
-	//	summary:
+	// summary:
 	//		A Wire for XML nodes or values (element, attribute and text)
-	//	description:
+	// description:
 	//		This class accesses XML nodes or value with a simplified XPath
 	//		specified to 'path' property.
 	//		The root object for this class must be an DOM document or element
@@ -21,19 +21,19 @@ dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
 	_wireClass: "dojox.wire.XmlWire",
 	
 	constructor: function(/*Object*/args){
-		//	summary:
+		// summary:
 		//		Initialize properties
-		//	description:
+		// description:
 		//		'args' is just mixed in with no further processing.
-		//	args:
-		//		Arguments to initialize properties
-		//		path:
-		//			A simplified XPath to an attribute, a text or elements
+		// args:
+		//		Arguments to initialize properties:
+		//
+		//		- path: A simplified XPath to an attribute, a text or elements
 	},
 	_getValue: function(/*Node*/object){
-		//	summary:
+		// summary:
 		//		Return an attribute value, a text value or an array of elements
-		//	description:
+		// description:
 		//		This method first uses a root node passed in 'object' argument
 		//		and 'path' property to identify an attribute, a text or
 		//		elements.
@@ -42,9 +42,9 @@ dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
 		//		(That is, "/a/b/@c" and "b/@c" against a root node access
 		//		the same attribute value, assuming the root node is an element
 		//		with a tag name, "a".)
-		//	object:
+		// object:
 		//		A root node
-		//	returns:
+		// returns:
 		//		A value found, otherwise 'undefined'
 		if(!object || !this.path){
 			return object; //Node
@@ -71,9 +71,9 @@ dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
 	},
 
 	_setValue: function(/*Node*/object, /*String*/value){
-		//	summary:
+		// summary:
 		//		Set an attribute value or a child text value to an element
-		//	description:
+		// description:
 		//		This method first uses a root node passed in 'object' argument
 		//		and 'path' property to identify an attribute, a text or
 		//		elements.
@@ -82,9 +82,9 @@ dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
 		//		node of the current node.
 		//		Finally, 'value' argument is set to an attribute or a text
 		//		(a child node) of the leaf element.
-		//	object:
+		// object:
 		//		A root node
-		//	value:
+		// value:
 		//		A value to set
 		if(!this.path){
 			return object; //Node
@@ -124,19 +124,19 @@ dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
 	},
 
 	_getNodeValue: function(/*Node*/node, /*String*/exp){
-		//	summary:
+		// summary:
 		//		Return an attribute value, a text value or an array of elements
-		//	description:
+		// description:
 		//		If 'exp' starts with '@', an attribute value of the specified
 		//		attribute is returned.
 		//		If 'exp' is "text()", a child text value is returned.
 		//		Otherwise, an array of child elements, the tag name of which
 		//		match 'exp', is returned.
-		//	node:
+		// node:
 		//		A node
-		//	exp:
+		// exp:
 		//		An expression for attribute, text or elements
-		//	returns:
+		// returns:
 		//		A value found, otherwise 'undefined'
 		var value = undefined;
 		if(exp.charAt(0) == '@'){
@@ -160,17 +160,17 @@ dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
 	},
 
 	_setNodeValue: function(/*Node*/node, /*String*/exp, /*String*/value){
-		//	summary:
+		// summary:
 		//		Set an attribute value or a child text value to an element
-		//	description:
+		// description:
 		//		If 'exp' starts with '@', 'value' is set to the specified
 		//		attribute.
 		//		If 'exp' is "text()", 'value' is set to a child text.
-		//	node:
+		// node:
 		//		A node
-		//	exp:
+		// exp:
 		//		An expression for attribute or text
-		//	value:
+		// value:
 		//		A value to set
 		if(exp.charAt(0) == '@'){
 			var attribute = exp.substring(1);
@@ -192,18 +192,18 @@ dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
 	},
 
 	_getChildNode: function(/*Node*/node, /*String*/name){
-		//	summary:
+		// summary:
 		//		Return a child node
-		//	description:
+		// description:
 		//		A child element of the tag name specified with 'name' is
 		//		returned.
 		//		If 'name' ends with an array index, it is used to pick up
 		//		the corresponding element from multiple child elements.
-		//	node:
+		// node:
 		//		A parent node
-		//	name:
+		// name:
 		//		A tag name
-		//	returns:
+		// returns:
 		//		A child node
 		var index = 1;
 		var i1 = name.indexOf('[');
@@ -226,12 +226,12 @@ dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
 	},
 
 	_getDocument: function(/*Node*/node){
-		//	summary:
+		// summary:
 		//		Return a DOM document
-		//	description:
+		// description:
 		//		If 'node' is specified, a DOM document of the node is returned.
 		//		Otherwise, a DOM document is created.
-		//	returns:
+		// returns:
 		//		A DOM document
 		if(node){
 			return (node.nodeType == 9 /* DOCUMENT_NODE */ ? node : node.ownerDocument); //Document
diff --git a/dojox/wire/_base.js b/dojox/wire/_base.js
index 6f1aeca..d5cf3ea 100644
--- a/dojox/wire/_base.js
+++ b/dojox/wire/_base.js
@@ -12,14 +12,14 @@ dojox.wire._wireClasses = {
 };
 
 dojox.wire.register = function(/*Function||String*/wireClass, /*String*/key){
-	//	summary:
+	// summary:
 	//		Register a Wire class
-	//	desription:
+	// description:
 	//		The specified Wire class or a class name is registered with
 	//		a key property of arguments to create a Wire
-	//	wireClass:
+	// wireClass:
 	//		A class or full qualified class name
-	//	key:
+	// key:
 	//		A key property of arguments to create a Wire
 	if(!wireClass || !key){
 		return; //undefined
@@ -31,31 +31,31 @@ dojox.wire.register = function(/*Function||String*/wireClass, /*String*/key){
 };
 
 dojox.wire._getClass = function(/*String*/name){
-	//	summary:
+	// summary:
 	//		Returns a class
-	//	description:
+	// description:
 	//		The class is loaded by dojo.require() and returned
 	//		by dojo.getObject().
-	//	name:
+	// name:
 	//		A class name
-	//	returns:
+	// returns:
 	//		A class
 	dojo["require"](name); // use dojo["require"] instead of dojo.require to avoid a build problem
 	return dojo.getObject(name); //Function
 };
 
 dojox.wire.create = function(/*Object*/args){
-	//	summary:
+	// summary:
 	//		Create a Wire from arguments
-	//	description:
+	// description:
 	//		If 'args' specifies 'wireClass', it is used as a class or full
 	//		qualified class name to create a Wire with 'args' as arguments.
 	//		Otherwise, a Wire class is determined by other proeprties of 'args'
 	//		checking if 'args' specifies a key property for a Wire class.
 	//		If no key property found, the default Wire class is used.
-	//	args:
+	// args:
 	//		Arguments to create a Wire
-	//	returns:
+	// returns:
 	//		A Wire
 	if(!args){
 		args = {};
@@ -90,22 +90,22 @@ dojox.wire.create = function(/*Object*/args){
 };
 
 dojox.wire.isWire = function(/*Object*/wire){
-	//	summary:
+	// summary:
 	//		Check if an object is a Wire
-	//	description:
+	// description:
 	//		If the specified object is a Wire, true is returned.
 	//		Otherwise, false is returned.
-	//	wire:
+	// wire:
 	//		An object to check
-	//	returns:
+	// returns:
 	//		True if the object is a Wire, otherwise false
 	return (wire && wire._wireClass); //Boolean
 };
 
 dojox.wire.transfer = function(/*Wire||Object*/source, /*Wire||Object*/target, /*Object?*/defaultObject, /*Object?*/defaultTargetObject){
-	//	summary:
+	// summary:
 	//		Transfer a source value to a target value
-	//	description:
+	// description:
 	//		If 'source' and/or 'target' are not Wires, Wires are created with
 	//		them as arguments.
 	//		A value is got through the source Wire and set through the target
@@ -113,13 +113,14 @@ dojox.wire.transfer = function(/*Wire||Object*/source, /*Wire||Object*/target, /
 	//		'defaultObject' is passed to Wires as a default root object.
 	//		If 'defaultTargetObject' is specified, it is passed to the target
 	//		Wire as a default root object, instead of 'defaultObject'.
-	//	source:
+	// source:
 	//		A Wire or arguments to create a Wire for a source value
-	//	target:
+	// target:
 	//		A Wire or arguments to create a Wire for a target value
-	//	defaultObject:
-	//	defaultTargetObject;
-	//		Optional default root objects passed to Wires
+	// defaultObject:
+	//		Optional default root object passed to Wires
+	// defaultTargetObject:
+	//		Optional default root object passed to Wires
 	if(!source || !target){
 		return; //undefined
 	}
@@ -135,10 +136,10 @@ dojox.wire.transfer = function(/*Wire||Object*/source, /*Wire||Object*/target, /
 };
 
 dojox.wire.connect = function(/*Object*/trigger, /*Wire||Object*/source, /*Wire||Object*/target){
-	//	summary:
+	// summary:
 	//		Transfer a source value to a target value on a trigger event or
 	//		topic
-	//	description:
+	// description:
 	//		If 'trigger' specifies 'topic', the topic is subscribed to transer
 	//		a value on the topic.
 	//		Otherwise, the event specified to 'event' of 'trigger' is listened
@@ -146,13 +147,13 @@ dojox.wire.connect = function(/*Object*/trigger, /*Wire||Object*/source, /*Wire|
 	//		On the specified event or topic, transfer() is called with
 	//		'source', 'target' and the arguments of the event or topic (as
 	//		default root objects).
-	//	trigger:
+	// trigger:
 	//		An event or topic to trigger a transfer
-	//	source:
+	// source:
 	//		A Wire or arguments to create a Wire for a source value
-	//	target:
+	// target:
 	//		A Wire or arguments to create a Wire for a target value
-	//	returns:
+	// returns:
 	//		A connection handle for disconnect()
 	if(!trigger || !source || !target){
 		return; //undefined
@@ -172,12 +173,12 @@ dojox.wire.connect = function(/*Object*/trigger, /*Wire||Object*/source, /*Wire|
 };
 
 dojox.wire.disconnect = function(/*Object*/connection){
-	//	summary:
+	// summary:
 	//		Remove a connection or subscription for transfer
-	//	description:
+	// description:
 	//		If 'handle' has 'topic', the topic is unsubscribed.
 	//		Otherwise, the listener to an event is removed.
-	//	connection:
+	// connection:
 	//		A connection handle returned by connect()
 	if(!connection || !connection.handle){
 		return; //undefined
diff --git a/dojox/wire/demos/TableContainer.js b/dojox/wire/demos/TableContainer.js
index 5e8d2ce..d72ad6c 100644
--- a/dojox/wire/demos/TableContainer.js
+++ b/dojox/wire/demos/TableContainer.js
@@ -5,7 +5,7 @@ dojo.require("dijit._Widget");
 dojo.require("dijit._Templated");
 
 dojo.declare("dojox.wire.demos.TableContainer", [ dijit._Widget, dijit._Templated, dijit._Container ], {
-	//	summary:
+	// summary:
 	//		Extremely simple 'widget' that is a table generator with an addRow function that takes an array
 	//		as the row to add, where each entry is a cell in the row.  This demo widget is for use with the
 	//		wire demos.
@@ -14,9 +14,9 @@ dojo.declare("dojox.wire.demos.TableContainer", [ dijit._Widget, dijit._Template
 	rowCount: 0,
 	headers: "",
 	addRow: function(array){
-		//	summary:
+		// summary:
 		//		Function to add in a new row from the elements in the array map to cells in the row.
-		//	array:
+		// array:
 		//		Array of row values to add.
 		try{
 			var row = document.createElement("tr");
@@ -36,7 +36,7 @@ dojo.declare("dojox.wire.demos.TableContainer", [ dijit._Widget, dijit._Template
 	},
 
 	clearTable: function(){
-		//	summary:
+		// summary:
 		//		Function to clear all the current rows in the table, except for the header.
 
 		//Always leave the first row, which is the table header.
@@ -47,7 +47,7 @@ dojo.declare("dojox.wire.demos.TableContainer", [ dijit._Widget, dijit._Template
 	},
 
 	postCreate: function(){
-		//	summary:
+		// summary:
 		//		Widget lifecycle function to handle generation of the header elements in the table.
 		var headers = this.headers.split(",");
 		var tr = document.createElement("tr");
diff --git a/dojox/wire/demos/WidgetRepeater.js b/dojox/wire/demos/WidgetRepeater.js
index 3304ec5..79a3569 100644
--- a/dojox/wire/demos/WidgetRepeater.js
+++ b/dojox/wire/demos/WidgetRepeater.js
@@ -6,16 +6,16 @@ dojo.require("dijit._Templated");
 dojo.require("dijit._Container");
 
 dojo.declare("dojox.wire.demos.WidgetRepeater", [ dijit._Widget, dijit._Templated, dijit._Container ], {
-	//	summary:
+	// summary:
 	//		Simple widget that does generation of widgets repetatively, based on calls to
 	//		the createNew function and contains them as child widgets.
 	templateString: "<div class='WidgetRepeater' dojoAttachPoint='repeaterNode'></div>",
 	widget: null,
 	repeater: null,
 	createNew: function(obj){
-		//	summary:
+		// summary:
 		//		Function to handle the creation of a new widget and appending it into the widget tree.
-		//	obj:
+		// obj:
 		//		The parameters to pass to the widget.
 		try{
 			if(dojo.isString(this.widget)){
diff --git a/dojox/wire/demos/markup/demo_ActionChaining.html b/dojox/wire/demos/markup/demo_ActionChaining.html
index bba408a..ab057d0 100644
--- a/dojox/wire/demos/markup/demo_ActionChaining.html
+++ b/dojox/wire/demos/markup/demo_ActionChaining.html
@@ -23,7 +23,7 @@
 		}
 	</style>
 
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
 		dojo.require("dojox.wire");
diff --git a/dojox/wire/demos/markup/demo_ActionWiring.html b/dojox/wire/demos/markup/demo_ActionWiring.html
index 3f57a74..6998b40 100644
--- a/dojox/wire/demos/markup/demo_ActionWiring.html
+++ b/dojox/wire/demos/markup/demo_ActionWiring.html
@@ -26,7 +26,7 @@
 		}
 	</style>
 
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
 		dojo.require("dojox.wire.ml.Invocation");
@@ -70,16 +70,16 @@
 			<table style="width: 90%;">
 				<tr>
 					<td align="left">
-						<div dojoType="dijit.form.Button" jsId="searchButton">Search Datastore</div>
+						<div dojoType="dijit.form.Button" data-dojo-id="searchButton">Search Datastore</div>
 					</td>
 					<td align="right">
-						<div dojoType="dijit.form.TextBox" jsId="inputField" value="*" intermediateChanges="true"></div>
+						<div dojoType="dijit.form.TextBox" data-dojo-id="inputField" value="*" intermediateChanges="true"></div>
 					</td>
 				</tr>
 			</table>
 		</div>
 		<div dojoType="dijit.layout.ContentPane" region="right" style="width: 50%; overflow: auto;">
-			<div class="dataTable" dojoType="dojox.wire.demos.TableContainer" jsId="dataTable" headers="Name,Location Type"></div>
+			<div class="dataTable" dojoType="dojox.wire.demos.TableContainer" data-dojo-id="dataTable" headers="Name,Location Type"></div>
 		</div>
 	</div>
 
@@ -87,7 +87,7 @@
 
 	<!-- The store that is queried in this demo -->    
 	<div dojoType="dojo.data.ItemFileReadStore"
-		jsId="DataStore1"
+		data-dojo-id="DataStore1"
 		url="countries.json">
 	</div>
 
diff --git a/dojox/wire/demos/markup/demo_BasicChildWire.html b/dojox/wire/demos/markup/demo_BasicChildWire.html
index f5973e7..b4c9d2f 100644
--- a/dojox/wire/demos/markup/demo_BasicChildWire.html
+++ b/dojox/wire/demos/markup/demo_BasicChildWire.html
@@ -16,7 +16,7 @@
 			@import "../../../../dijit/tests/css/dijitTests.css";
 		</style>
 
-		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
 			dojo.require("dijit.form.Button");
@@ -47,7 +47,7 @@
 			The store that is queried in this demo 
 		-->    
 		<div dojoType="dojo.data.ItemFileReadStore"
-			jsId="DataStore1"
+			data-dojo-id="DataStore1"
 			url="countries.json">
 		</div>
 
@@ -56,7 +56,7 @@
 			As defined by the widget type it contains.
 		-->
 		<div dojoType="dojox.wire.demos.WidgetRepeater"
-			widget="dijit.form.Button" jsId="r1">
+			widget="dijit.form.Button" data-dojo-id="r1">
 		</div>
 
 		<!-- 
diff --git a/dojox/wire/demos/markup/demo_BasicColumnWiring.html b/dojox/wire/demos/markup/demo_BasicColumnWiring.html
index 48c327e..2c0bb3c 100644
--- a/dojox/wire/demos/markup/demo_BasicColumnWiring.html
+++ b/dojox/wire/demos/markup/demo_BasicColumnWiring.html
@@ -19,7 +19,7 @@
 		@import "../TableContainer.css";
 	</style>
 
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
 		dojo.require("dojox.wire.ml.Invocation");
@@ -48,7 +48,7 @@
 		The store that is queried in this demo 
 	-->    
 	<div dojoType="dojo.data.ItemFileReadStore"
-		jsId="DataStore1"
+		data-dojo-id="DataStore1"
 		url="countries.json">
 	</div>
 
@@ -63,7 +63,7 @@
 	<!--
 		Simple container widget for creating a 'table from rows defined by an array
 	-->    
-	<div dojoType="dojox.wire.demos.TableContainer" jsId="r1" headers="Name,Location Type"></div>
+	<div dojoType="dojox.wire.demos.TableContainer" data-dojo-id="r1" headers="Name,Location Type"></div>
 
 	<!-- 
 		On the call of the onItem function of 'dataHolder', trigger a binding/mapping of the
diff --git a/dojox/wire/demos/markup/demo_ConditionalActions.html b/dojox/wire/demos/markup/demo_ConditionalActions.html
index 1a6dc91..7593942 100644
--- a/dojox/wire/demos/markup/demo_ConditionalActions.html
+++ b/dojox/wire/demos/markup/demo_ConditionalActions.html
@@ -30,7 +30,7 @@
 
 	</style>
 
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
 		dojo.require("dojo.data.ItemFileReadStore");
@@ -54,7 +54,7 @@
 	shipping address if the 'Use Same Address' checkbox is checked true.
 	<br/>
 	<br/>
-	<div dojoType="dojo.data.ItemFileReadStore" url="states.json" jsId="statesStore"></div>
+	<div dojoType="dojo.data.ItemFileReadStore" url="states.json" data-dojo-id="statesStore"></div>
 	<table width="100%">
 		<tr>
 			<td colspan="2" align="center">
diff --git a/dojox/wire/demos/markup/demo_FlickrStoreWire.html b/dojox/wire/demos/markup/demo_FlickrStoreWire.html
index 4d0d9ec..408a1ba 100644
--- a/dojox/wire/demos/markup/demo_FlickrStoreWire.html
+++ b/dojox/wire/demos/markup/demo_FlickrStoreWire.html
@@ -14,7 +14,7 @@
 		@import "./flickrDemo.css";
 	</style>
 
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
 		dojo.require("dijit.form.TextBox");
@@ -83,7 +83,7 @@
 					<b>Status:</b>
 				</td>
 				<td>
-					<div dojoType="dijit.form.TextBox" size="50" id="status" jsId="statusWidget" disabled="true"></div>
+					<div dojoType="dijit.form.TextBox" size="50" id="status" data-dojo-id="statusWidget" disabled="true"></div>
 				</td>
 			</tr>
 			<tr>
@@ -91,7 +91,7 @@
 					<b>ID:</b>
 				</td>
 				<td>
-					<div dojoType="dijit.form.TextBox" size="50" id="userid" jsId="idWidget"></div>
+					<div dojoType="dijit.form.TextBox" size="50" id="userid" data-dojo-id="idWidget"></div>
 				</td>
 			</tr>
 			<tr>
@@ -99,7 +99,7 @@
 					<b>Tags:</b>
 				</td>
 				<td>
-					<div dojoType="dijit.form.TextBox" size="50" id="tags" jsId="tagsWidget" value="3dny"></div>
+					<div dojoType="dijit.form.TextBox" size="50" id="tags" data-dojo-id="tagsWidget" value="3dny"></div>
 				</td>
 			</tr>
 			<tr>
@@ -108,7 +108,7 @@
 				</td>
 				<td>
 					<select id="tagmode"
-							jsId="tagmodeWidget"
+							data-dojo-id="tagmodeWidget"
 							dojoType="dijit.form.ComboBox"
 							autocomplete="false"
 							value="any"
@@ -125,7 +125,7 @@
 				<td>
 					<div   
 						id="count"
-						jsId="countWidget"
+						data-dojo-id="countWidget"
 						dojoType="dijit.form.NumberSpinner"
 						value="20"
 						constraints="{min:1,max:20,places:0}" 
@@ -136,7 +136,7 @@
 				<td>
 				</td>
 				<td>
-					<div dojoType="dijit.form.Button" label="Search" id="searchButton" jsId="searchButtonWidget"></div>
+					<div dojoType="dijit.form.Button" label="Search" id="searchButton" data-dojo-id="searchButtonWidget"></div>
 				</td>
 			</tr>
 		</tbody>
@@ -145,8 +145,8 @@
 	<!--
 		The store instance used by this demo.
 	-->
-	<div dojoType="dojox.data.FlickrStore" jsId="flickrStore" label="title"></div>
-	<div dojoType="dojox.data.demos.widgets.FlickrViewList" store="flickrStore" id="flickrViews" jsId="flickrViewsWidget"></div>
+	<div dojoType="dojox.data.FlickrStore" data-dojo-id="flickrStore" label="title"></div>
+	<div dojoType="dojox.data.demos.widgets.FlickrViewList" store="flickrStore" id="flickrViews" data-dojo-id="flickrViewsWidget"></div>
 
 	<!-------------------------------- Using dojox.wire, declaratively wire up the widgets. --------------------------->
 
@@ -157,7 +157,7 @@
 	-->
 	<div dojoType="dojox.wire.ml.Data"
 		id="messageData"
-		jsId="messageData">
+		data-dojo-id="messageData">
 		<div dojoType="dojox.wire.ml.DataProperty"
 			name="processingStart"
 			value="PROCESSING REQUEST">
diff --git a/dojox/wire/demos/markup/demo_TopicWiring.html b/dojox/wire/demos/markup/demo_TopicWiring.html
index b56fa6b..c55d5bc 100644
--- a/dojox/wire/demos/markup/demo_TopicWiring.html
+++ b/dojox/wire/demos/markup/demo_TopicWiring.html
@@ -24,7 +24,7 @@
 		}
 	</style>
 
-	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dojo.parser");
 		dojo.require("dojox.wire");
@@ -47,12 +47,12 @@
 	<table>
 		<tr>
 			<td>
-				<div dojoType="dijit.form.TextBox" jsId="inputField" value="" size="50" intermediateChanges="true"></div>
+				<div dojoType="dijit.form.TextBox" data-dojo-id="inputField" value="" size="50" intermediateChanges="true"></div>
 			</td>
 		</tr>
 		<tr>
 			<td>
-				<div dojoType="dijit.form.TextBox" jsId="targetField1" value="" disabled="true" size="50"></div>
+				<div dojoType="dijit.form.TextBox" data-dojo-id="targetField1" value="" disabled="true" size="50"></div>
 			</td>
 		</tr>
 	</table>
diff --git a/dojox/wire/ml/Action.js b/dojox/wire/ml/Action.js
index 0f249e0..2d66ecf 100644
--- a/dojox/wire/ml/Action.js
+++ b/dojox/wire/ml/Action.js
@@ -6,9 +6,9 @@ dojo.require("dojox.wire.Wire");
 dojo.require("dojox.wire.ml.util");
 
 dojo.declare("dojox.wire.ml.Action", [dijit._Widget, dijit._Container], {
-	//	summary:
+	// summary:
 	//		A base widget to "run" a task on an event or a topic
-	//	description:
+	// description:
 	//		This widget represents a controller task to be run when an event
 	//		(a function) or a topic is issued.
 	//		Sub-classes must implement _run() method to implement their tasks.
@@ -19,28 +19,28 @@ dojo.declare("dojox.wire.ml.Action", [dijit._Widget, dijit._Container], {
 	//		If one of filter() methods returns false, run() won't be invoked.
 	//		This widget also can serve as a composite task to run child
 	//		Actions on an event or a topic specified to this widget.
-	//	trigger:
+	// trigger:
 	//		An event scope
-	//	triggerEvent:
+	// triggerEvent:
 	//		An event (function) name
-	//	triggerTopic:
+	// triggerTopic:
 	//		A topic name
 	trigger: "",
 	triggerEvent: "",
 	triggerTopic: "",
 
 	postCreate: function(){
-		//	summary:
+		// summary:
 		//		Call _connect()
-		//	description:
+		// description:
 		//		See _connect().
 		this._connect();
 	},
 
 	_connect: function(){
-		//	summary:
+		// summary:
 		//		Connect run() method to an event or a topic
-		//	description:
+		// description:
 		//		If 'triggerEvent' and 'trigger' are specified, connect() is
 		//		used to set up run() to be called on the event.
 		//		If 'triggerTopic' is specified, subscribe() is used to set up
@@ -70,9 +70,9 @@ dojo.declare("dojox.wire.ml.Action", [dijit._Widget, dijit._Container], {
 	},
 
 	_disconnect: function(){
-		//	summary:
+		// summary:
 		//		Disconnect run() method from an event or a topic
-		//	description:
+		// description:
 		//		If 'triggerEvent' and 'trigger' are specified, disconnect() is
 		//		used to set up run() not to be called on the event.
 		//		If 'triggerTopic' is specified, unsubscribe() is used to set up
@@ -87,9 +87,9 @@ dojo.declare("dojox.wire.ml.Action", [dijit._Widget, dijit._Container], {
 	},
 
 	run: function(){
-		//	summary:
+		// summary:
 		//		Run a task
-		//	description:
+		// description:
 		//		This method calls filter() method of child ActionFilter
 		//		widgets.
 		//		If one of them returns false, this method returns.
@@ -107,9 +107,9 @@ dojo.declare("dojox.wire.ml.Action", [dijit._Widget, dijit._Container], {
 	},
 
 	_run: function(){
-		//	summary:
+		// summary:
 		//		Call run() methods of child Action widgets
-		//	description:
+		// description:
 		//		If this widget has child Action widgets, their run() methods
 		//		are called.
 		var children = this.getChildren();
@@ -122,7 +122,7 @@ dojo.declare("dojox.wire.ml.Action", [dijit._Widget, dijit._Container], {
 	},
 
 	uninitialize: function(){
-		//	summary:
+		// summary:
 		//		Over-ride of base widget unitialize function to do some connection cleanup.
 		this._disconnect();
 		return true;
@@ -130,26 +130,26 @@ dojo.declare("dojox.wire.ml.Action", [dijit._Widget, dijit._Container], {
 });
 
 dojo.declare("dojox.wire.ml.ActionFilter", dijit._Widget, {
-	//	summary:
+	// summary:
 	//		A widget to define a filter for the parent Action to run
-	//	description:
+	// description:
 	//		This base class checks a required property specified with
 	//		'required' attribute.
 	//		If 'message' is specified, the message is set to a property
 	//		specified with 'error'.
 	//		Subclasses may implement their own filter() method.
-	//	required:
+	// required:
 	//		A property required
-	//	requiredValue:
+	// requiredValue:
 	//		Optional.  A specific value the property is required to have.  If this isn't provided
 	//		than any non-false/non-null value of the required propery will cause this filter
 	//		to pass.
-	//	type:
+	// type:
 	//		Optional.  A specific type to compare the values as (if requiredValue is set)
 	//		Valid values for type are boolean, int, string.  Default is string.
-	//	message:
+	// message:
 	//		An error message to emit if the filter doesn't execute due to property mismatch.
-	//	error:
+	// error:
 	//		A property to store an error due to property mismatch.
 	required: "",
 	requiredValue: "",
@@ -159,10 +159,10 @@ dojo.declare("dojox.wire.ml.ActionFilter", dijit._Widget, {
 
 
 	filter: function(){
-		//	summary:
+		// summary:
 		//		Check if a required property is specified.  Also, if provided, check to see
 		//		if the required property contains a specific value.
-		//	description:
+		// description:
 		//		If a value is undefined for a property, specified with
 		//		'required', this method returns false.
 		//		If the value for a property is defined, but there isn't a requiredValue for it
@@ -175,7 +175,7 @@ dojo.declare("dojox.wire.ml.ActionFilter", dijit._Widget, {
 		//		with 'error' or shown with alert().
 		//		If 'required' starts with "arguments", a property of
 		//		the method arguments are checked.
-		//	returns:
+		// returns:
 		//		True if a required property is specified (and if requiredValue is specified,
 		//		that they match), otherwise false
 		if(this.required === ""){
diff --git a/dojox/wire/ml/Data.js b/dojox/wire/ml/Data.js
index 0d62e24..f981ad6 100644
--- a/dojox/wire/ml/Data.js
+++ b/dojox/wire/ml/Data.js
@@ -5,29 +5,29 @@ dojo.require("dijit._Container");
 dojo.require("dojox.wire.ml.util");
 
 dojo.declare("dojox.wire.ml.Data", [dijit._Widget, dijit._Container], {
-	//	summary:
+	// summary:
 	//		A widget for a data object
-	//	description:
+	// description:
 	//		This widget represents an object with '_properties' property.
 	//		If child 'DataProperty' widgets exist, they are used to initialize
 	//		propertiy values of '_properties' object.
 
 	startup: function(){
-		//	summary:
+		// summary:
 		//		Call _initializeProperties()
-		//	description:
+		// description:
 		//		See _initializeProperties().
 		this._initializeProperties();
 	},
 
 	_initializeProperties: function(/*Boolean*/reset){
-		//	summary:
+		// summary:
 		//		Initialize a data object
-		//	description:
+		// description:
 		//		If this widget has child DataProperty widgets, their getValue()
 		//		methods are called and set the return value to a property
 		//		specified by 'name' attribute of the child widgets.
-		//	reset:
+		// reset:
 		//		A boolean to reset current properties
 		if(!this._properties || reset){
 			this._properties = {};
@@ -42,36 +42,36 @@ dojo.declare("dojox.wire.ml.Data", [dijit._Widget, dijit._Container], {
 	},
 
 	getPropertyValue: function(/*String*/property){
-		//	summary:
+		// summary:
 		//		Return a property value
-		//	description:
+		// description:
 		//		This method returns the value of a property, specified with
 		//		'property' argument, in '_properties' object.
-		//	property:
+		// property:
 		//		A property name
-		//	returns:
+		// returns:
 		//		A property value
 		return this._properties[property]; //anything
 	},
 
 	setPropertyValue: function(/*String*/property, /*anything*/value){
-		//	summary:
+		// summary:
 		//		Store a property value
-		//	description:
+		// description:
 		//		This method stores 'value' as a property, specified with
 		//		'property' argument, in '_properties' object.
-		//	property:
+		// property:
 		//		A property name
-		//	value:
+		// value:
 		//		A property value
 		this._properties[property] = value;
 	}
 });
 
 dojo.declare("dojox.wire.ml.DataProperty", [dijit._Widget, dijit._Container], {
-	//	summary:
+	// summary:
 	//		A widget to define a data property
-	//	description:
+	// description:
 	//		Attributes of this widget are used to add a property to the parent
 	//		Data widget.
 	//		'type' attribute specifies one of "string", "number", "boolean",
@@ -79,11 +79,11 @@ dojo.declare("dojox.wire.ml.DataProperty", [dijit._Widget, dijit._Container], {
 	//		(default to "string").
 	//		If 'type' is "array" or "object", child DataProperty widgets are
 	//		used to initialize the array elements or the object properties.
-	//	name:
+	// name:
 	//		A property name
-	//	type:
+	// type:
 	//		A property type name
-	//	value:
+	// value:
 	//		A property value
 	name: "",
 	type: "",
@@ -94,13 +94,13 @@ dojo.declare("dojox.wire.ml.DataProperty", [dijit._Widget, dijit._Container], {
 	},
 
 	getValue: function(){
-		//	summary:
+		// summary:
 		//		Returns a property value
-		//	description:
+		// description:
 		//		If 'type' is specified, 'value' attribute is converted to
 		//		the specified type and returned.
 		//		Otherwise, 'value' attribute is returned as is.
-		//	returns:
+		// returns:
 		//		A property value
 		var value = this.value;
 		if(this.type){
diff --git a/dojox/wire/ml/DataStore.js b/dojox/wire/ml/DataStore.js
index d10aebf..ff0455a 100644
--- a/dojox/wire/ml/DataStore.js
+++ b/dojox/wire/ml/DataStore.js
@@ -4,29 +4,29 @@ dojo.require("dijit._Widget");
 dojo.require("dojox.wire._base");
 
 dojo.declare("dojox.wire.ml.DataStore", dijit._Widget, {
-	//	summary:
+	// summary:
 	//		A widget for a data store
-	//	description:
+	// description:
 	//		This widget represents a data store of 'storeClass' attribute.
-	//	storeClass:
+	// storeClass:
 	//		A class name of a data store
 	storeClass: "",
 
 	postCreate: function(){
-		//	summary:
+		// summary:
 		//		Call _createStore()
-		//	description:
+		// description:
 		//		See _createStore().
 		this.store = this._createStore();
 	},
 
 	_createStore: function(){
-		//	summary:
+		// summary:
 		//		Create a data store
-		//	desription:
+		// description:
 		//		A data store of 'storeClass' is created with arguments
 		//		specified with attributes.
-		//	returns:
+		// returns:
 		//		A data store
 		if(!this.storeClass){
 			return null; //null
@@ -47,65 +47,65 @@ dojo.declare("dojox.wire.ml.DataStore", dijit._Widget, {
 	},
 
 	getFeatures: function(){
-		//	summary:
+		// summary:
 		//		Call getFeatures() method of a data store
-		//	description:
-		//		See dojo.data.api.Read.getFeatures().
-		//	returns:
+		// description:
+		//		See dojo/data/api/Read.getFeatures().
+		// returns:
 		//		A features object
 		return this.store.getFeatures(); //Object
 	},
 
 	fetch: function(/*Object*/request){
-		//	summary:
+		// summary:
 		//		Call fetch() method of a data store
-		//	description:
-		//		See dojo.data.api.Read.fetch().
-		//	request:
+		// description:
+		//		See dojo/data/api/Read.fetch().
+		// request:
 		//		A request object
-		//	returns:
+		// returns:
 		//		A request object
 		return this.store.fetch(request); //Object
 	},
 
 	save: function(/*Object*/args){
-		//	summary:
+		// summary:
 		//		Call save() method of a data store
-		//	description:
-		//		See dojo.data.api.Write.save().
-		//	args:
+		// description:
+		//		See dojo/data/api/Write.save().
+		// args:
 		//		A save arguments object
 		this.store.save(args);
 	},
 
 	newItem: function(/*Object*/args){
-		//	summary:
+		// summary:
 		//		Call newItem() method of a data store
-		//	description:
-		//		See dojo.data.api.Write.newItem().
-		//	args:
+		// description:
+		//		See dojo/data/api/Write.newItem().
+		// args:
 		//		A new item arguments object
-		//	returns:
+		// returns:
 		//		A new item
 		return this.store.newItem(args); //Object
 	},
 
 	deleteItem: function(/*Object*/item){
-		//	summary:
+		// summary:
 		//		Call deleteItem() method of a data store
-		//	description:
-		//		See dojo.data.api.Write.deleteItem().
-		//	returns:
+		// description:
+		//		See dojo/data/api/Write.deleteItem().
+		// returns:
 		//		A boolean
 		return this.store.deleteItem(item); //Boolean
 	},
 
 	revert: function(){
-		//	summary:
+		// summary:
 		//		Call revert() method of a data store
-		//	description:
-		//		See dojo.data.api.Write.revert().
-		//	returns:
+		// description:
+		//		See dojo/data/api/Write.revert().
+		// returns:
 		//		A boolean
 		return this.store.revert(); //Boolean
 	}
diff --git a/dojox/wire/ml/Invocation.js b/dojox/wire/ml/Invocation.js
index e0ba0f5..c50ab28 100644
--- a/dojox/wire/ml/Invocation.js
+++ b/dojox/wire/ml/Invocation.js
@@ -3,34 +3,40 @@ dojo.provide("dojox.wire.ml.Invocation");
 dojo.require("dojox.wire.ml.Action");
 
 dojo.declare("dojox.wire.ml.Invocation", dojox.wire.ml.Action, {
-	//	summary:
+	// summary:
 	//		A widget to invoke a method or publish a topic
-	//	description:
+	// description:
 	//		This widget represents a controller task to invoke a method or
 	//		publish a topic when an event (a function) or a topic is issued.
-	//	object:
+
+	// object:
 	//		A scope of a method to invoke
-	//	method:
-	//		A name of a method to invoke
-	//	topic:
-	//		A name of a topic to publish
-	//	parameters:
-	//		Arguments for the method or the topic
-	//	result:
-	//		A property to store a return value of the method call
-	//	error:
-	//		A property to store an error on the method call
 	object: "",
+
+	// method:
+	//		A name of a method to invoke
 	method: "",
+
+	// topic:
+	//		A name of a topic to publish
 	topic: "",
+
+	// parameters:
+	//		Arguments for the method or the topic
 	parameters: "",
+
+	// result:
+	//		A property to store a return value of the method call
 	result: "",
+
+	// error:
+	//		A property to store an error on the method call
 	error: "",
 
 	_run: function(){
-		//	summary:
+		// summary:
 		//		Invoke a method or publish a topic
-		//	description:
+		// description:
 		//		If 'topic' is specified, the topic is published with arguments
 		//		specified to 'parameters'.
 		//		If 'method' and 'object' are specified, the method is invoked
@@ -101,13 +107,13 @@ dojo.declare("dojox.wire.ml.Invocation", dojox.wire.ml.Action, {
 	},
 
 	onComplete: function(/*anything*/result){
-		//	summary:
+		// summary:
 		//		A function called when the method or the topic publish
 		//		completed
-		//	description:
+		// description:
 		//		If 'result' attribute is specified, the result object also set
 		//		to the specified property.
-		//	result:
+		// result:
 		//		The return value of a method or undefined for a topic
 		if(this.result){
 			dojox.wire.ml._setValue(this.result, result);
@@ -118,12 +124,12 @@ dojo.declare("dojox.wire.ml.Invocation", dojox.wire.ml.Action, {
 	},
 
 	onError: function(/*anything*/error){
-		//	summary:
+		// summary:
 		//		A function called on an error occurs
-		//	description:
+		// description:
 		//		If 'error' attribute is specified, the error object also set to
 		//		the specified property.
-		//	error:
+		// error:
 		//		The exception or error occurred
 		if(this.error){
 			if(error && error.message){
@@ -134,15 +140,15 @@ dojo.declare("dojox.wire.ml.Invocation", dojox.wire.ml.Action, {
 	},
 
 	_getParameters: function(/*Array*/args){
-		//	summary:
+		// summary:
 		//		Returns arguments to a method or topic to invoke
-		//	description:
+		// description:
 		//		This method retunrs an array of arguments specified by
 		//		'parameters' attribute, a comma-separated list of IDs and
 		//		their properties in a dotted notation.
 		//		If 'parameters' are omitted, the original arguments are
 		//		used.
-		//	args:
+		// args:
 		//		Arguments to a trigger event or topic
 		if(!this.parameters){
 		 	// use arguments as is
diff --git a/dojox/wire/ml/JsonHandler.js b/dojox/wire/ml/JsonHandler.js
index ab98184..3c71c03 100644
--- a/dojox/wire/ml/JsonHandler.js
+++ b/dojox/wire/ml/JsonHandler.js
@@ -6,25 +6,25 @@ dojo.require("dojox.wire.ml.util");
 
 
 dojo.declare("dojox.wire.ml.JsonHandler", dojox.wire.ml.RestHandler, {
-	//	summary:
+	// summary:
 	//		A REST service handler for JSON
-	//	description:
+	// description:
 	//		This class provides JSON handling for a REST service.
 	contentType: "text/json",
 	handleAs: "json",
 	headers: {"Accept": "*/json"},
 
 	_getContent: function(/*String*/method, /*Array*/parameters){
-		//	summary:
+		// summary:
 		//		Generate a request content
-		//	description:
+		// description:
 		//		If 'method' is "POST" or "PUT", the first parameter in
 		//		'parameter' is used to generate a JSON content.
-		//	method:
+		// method:
 		//		A method name
-		//	parameters:
+		// parameters:
 		//		An array of parameters
-		//	returns:
+		// returns:
 		//		A request content
 		var content = null;
 		if(method == "POST" || method == "PUT"){
diff --git a/dojox/wire/ml/RestHandler.js b/dojox/wire/ml/RestHandler.js
index 7c70b98..ae1c633 100644
--- a/dojox/wire/ml/RestHandler.js
+++ b/dojox/wire/ml/RestHandler.js
@@ -4,9 +4,9 @@ dojo.require("dojox.wire._base");
 dojo.require("dojox.wire.ml.util");
 
 dojo.declare("dojox.wire.ml.RestHandler", null, {
-	//	summary:
+	// summary:
 	//		A REST service handler
-	//	description:
+	// description:
 	//		This class serves as a base REST service.
 	//		Sub-classes may override _getContent() and _getResult() to handle
 	//		specific content types.
@@ -14,21 +14,21 @@ dojo.declare("dojox.wire.ml.RestHandler", null, {
 	handleAs: "text",
 
 	bind: function(method, parameters, deferred, url){
-		//	summary:
+		// summary:
 		//		Call a service method with parameters.
-		//	description:
+		// description:
 		//		A service is called with a URL generated by _getUrl() and
 		//		an HTTP method specified with 'method'.
 		//		For "POST" and "PUT", a content is generated by _getContent().
 		//		When data is loaded, _getResult() is used to pass the result to
 		//		Deferred.callback().
-		//	method:
+		// method:
 		//		A method name
-		//	parameters:
+		// parameters:
 		//		An array of parameters
-		//	deferred:
+		// deferred:
 		//		'Deferred'
-		//	url:
+		// url:
 		//		A URL for the method
 		method = method.toUpperCase();
 		var self = this;
@@ -59,21 +59,21 @@ dojo.declare("dojox.wire.ml.RestHandler", null, {
 	},
 
 	_getUrl: function(/*String*/method, /*Array*/parameters, /*String*/url){
-		//	summary:
+		// summary:
 		//		Generate a URL
-		//	description:
+		// description:
 		//		If 'method' is "GET" or "DELETE", a query string is generated
 		//		from a query object specified to the first parameter in
 		//		'parameters' and appended to 'url'.
 		//		If 'url' contains variable seguments ("{parameter_name}"),
 		//		they are replaced with corresponding parameter values, instead.
-		//	method:
+		// method:
 		//		A method name
-		//	parameters:
+		// parameters:
 		//		An array of parameters
-		//	url:
+		// url:
 		//		A base URL
-		//	returns:
+		// returns:
 		//		A URL
 		var query;
 		if(method == "GET" || method == "DELETE"){
@@ -111,16 +111,16 @@ dojo.declare("dojox.wire.ml.RestHandler", null, {
 	},
 
 	_getContent: function(/*String*/method, /*Array*/parameters){
-		//	summary:
+		// summary:
 		//		Generate a request content
-		//	description:
+		// description:
 		//		If 'method' is "POST" or "PUT", the first parameter in
 		//		'parameters' is returned.
-		//	method:
+		// method:
 		//		A method name
-		//	parameters:
+		// parameters:
 		//		An array of parameters
-		//	returns:
+		// returns:
 		//		A request content
 		if(method == "POST" || method == "PUT"){
 			return (parameters ? parameters[0] : null); //anything
@@ -130,13 +130,13 @@ dojo.declare("dojox.wire.ml.RestHandler", null, {
 	},
 
 	_getResult: function(/*anything*/data){
-		//	summary:
+		// summary:
 		//		Extract a result
-		//	description:
+		// description:
 		//		A response data is returned as is.
-		//	data:
+		// data:
 		//		A response data returned by a service
-		//	returns:
+		// returns:
 		//		A result object
 		return data; //anything
 	}
diff --git a/dojox/wire/ml/Service.js b/dojox/wire/ml/Service.js
index c454622..91861fa 100644
--- a/dojox/wire/ml/Service.js
+++ b/dojox/wire/ml/Service.js
@@ -6,31 +6,36 @@ dojo.require("dojox.wire._base");
 dojo.require("dojox.wire.ml.util");
 
 dojo.declare("dojox.wire.ml.Service", dijit._Widget, {
-	//	summary:
+	// summary:
 	//		A widget for a service
-	//	description:
+	// description:
 	//		This widget represents a service defined by a service description
 	//		specified with 'url' attribute.
 	//		If 'serviceType' and 'serviceUrl' attributes are specified, 'url'
 	//		attribute can be omitted.
-	//	url:
+
+	// url:
 	//		A URL to a service description
-	//	serviceUrl:
-	//		A URL to a service
-	//	serviceType:
-	//		A service type
-	//	handlerClass:
-	//		A service handler class name
 	url: "",
+
+	// serviceUrl:
+	//		A URL to a service
 	serviceUrl: "",
+
+	// serviceType:
+	//		A service type
 	serviceType: "",
+
+	// handlerClass:
+	//		A service handler class name
 	handlerClass: "",
+
 	preventCache: true,
 
 	postCreate: function(){
-		//	summary:
+		// summary:
 		//		Call _createHandler()
-		//	description:
+		// description:
 		//		See _createHandler().
 		this.handler = this._createHandler();
 	},
@@ -43,14 +48,15 @@ dojo.declare("dojox.wire.ml.Service", dijit._Widget, {
 	},
 
 	_createHandler: function(){
-		//	summary:
+		// summary:
 		//		Create a service handler
-		//	desription:
+		// description:
 		//		A service handler class is determined by:
+		//
 		//		1. 'handlerClass' attribute
 		//		2. 'serviceType' attribute
 		//		3. 'serviceType' property in a service description
-		//	returns:
+		// returns:
 		//		A service handler
 		if(this.url){
 			var self = this;
@@ -89,11 +95,11 @@ dojo.declare("dojox.wire.ml.Service", dijit._Widget, {
 	},
 
 	callMethod: function(method, parameters){
-		//	summary:
+		// summary:
 		//		Call a service method with parameters
-		//	method:
+		// method:
 		//		A method name
-		//	parameters:
+		// parameters:
 		//		An array parameters
 		var deferred = new dojo.Deferred();
 		this.handler.bind(method, parameters, deferred, this.serviceUrl);
diff --git a/dojox/wire/ml/Transfer.js b/dojox/wire/ml/Transfer.js
index 047e914..5cf00c1 100644
--- a/dojox/wire/ml/Transfer.js
+++ b/dojox/wire/ml/Transfer.js
@@ -6,51 +6,62 @@ dojo.require("dojox.wire._base");
 dojo.require("dojox.wire.ml.Action");
 
 dojo.declare("dojox.wire.ml.Transfer", dojox.wire.ml.Action, {
-	//	summary:
+	// summary:
 	//		A widget to transfer values through source and target Wires
-	//	description:
+	// description:
 	//		This widget represents a controller task to transfer a value from
 	//		a source to a target, through a source and a target Wires, when
 	//		an event (a function) or a topic is issued.
 	//		If this widget has child ChildWire widgets, their _addWire()
 	//		methods are called to add Wire arguments to a source or a target
 	//		Wire.
-	//	source:
+
+	// source:
 	//		A source object and/or property
-	//	sourceStore:
-	//		A data store for a source data item
-	//	sourceAttribute:
-	//		An attribute of a source data item
-	//	sourcePath:
-	//		A simplified XPath to a source property of an XML element
-	//	type:
-	//		A type of the value to be transferred
-	//	converter:
-	//		A class name of a converter for the value to be transferred
-	//	target:
-	//		A target object and/or property
-	//	targetStore:
-	//		A data store for a target data item
-	//	targetAttribute:
-	//		An attribute of a target data item
-	//	targetPath:
-	//		A simplified XPath to a target property of an XML element
 	source: "",
+
+	// sourceStore:
+	//		A data store for a source data item
 	sourceStore: "",
+
+	// sourceAttribute:
+	//		An attribute of a source data item
 	sourceAttribute: "",
+
+	// sourcePath:
+	//		A simplified XPath to a source property of an XML element
 	sourcePath: "",
+
+	// type:
+	//		A type of the value to be transferred
 	type: "",
+
+	// converter:
+	//		A class name of a converter for the value to be transferred
 	converter: "",
-	delimiter: "",
+
+	// target:
+	//		A target object and/or property
 	target: "",
+
+	// targetStore:
+	//		A data store for a target data item
 	targetStore: "",
+
+	// targetAttribute:
+	//		An attribute of a target data item
 	targetAttribute: "",
+
+	// targetPath:
+	//		A simplified XPath to a target property of an XML element
 	targetPath: "",
 
+	delimiter: "",
+
 	_run: function(){
-		//	summary:
+		// summary:
 		//		Transfer a value from a source to a target
-		//	description:
+		// description:
 		//		First, Wires for a source and a target are created from attributes.
 		//		Then, a value is obtained by getValue() of the source Wire is set
 		//		by setValue() of the target Wire.
@@ -63,15 +74,15 @@ dojo.declare("dojox.wire.ml.Transfer", dojox.wire.ml.Action, {
 	},
 
 	_getWire: function(/*String*/which){
-		//	summary:
+		// summary:
 		//		Build Wire arguments from attributes
-		//	description:
+		// description:
 		//		Arguments object for a source or a target Wire, specified by
 		//		'which' argument, are build from corresponding attributes,
 		//		including '*Store' (for 'dataStore'), '*Attribute'
 		//		(for 'attribute), '*Path' (for 'path'), 'type' and 'converter'.
 		//		'source' or 'target' attribute is parsed as:
-		//			"object_id.property_name[.sub_property_name...]"
+		// |		"object_id.property_name[.sub_property_name...]"
 		//		If 'source' or 'target' starts with "arguments", 'object'
 		//		argument for a Wire is set to null, so that the root object is
 		//		given as an event or topic arguments.
@@ -79,9 +90,9 @@ dojo.declare("dojox.wire.ml.Transfer", dojox.wire.ml.Action, {
 		//		'which' attribute, their _addWire() methods are called to add
 		//		additional Wire arguments and nested Wire is created,
 		//		specifying the Wire defined by this widget to 'object' argument.
-		//	which:
+		// which:
 		//		Which Wire arguments to build, "source" or "target"
-		//	returns:
+		// returns:
 		//		Wire arguments object
 		var args = undefined;
 		if(which == "source"){
@@ -139,27 +150,27 @@ dojo.declare("dojox.wire.ml.Transfer", dojox.wire.ml.Action, {
 });
 
 dojo.declare("dojox.wire.ml.ChildWire", dijit._Widget, {
-	//	summary:
+	// summary:
 	//		A widget to add a child wire
-	//	description:
+	// description:
 	//		Attributes of this widget are used to add a child Wire to
 	//		a composite Wire of the parent Transfer widget.
-	//	which:
+	// which:
 	//		Which Wire to add a child Wire, "source" or "target", default to
 	//		"source"
-	//	object:
+	// object:
 	//		A root object for the value
-	//	property:
+	// property:
 	//		A property for the value
-	//	type:
+	// type:
 	//		A type of the value
-	//	converter:
+	// converter:
 	//		A class name of a converter for the value
-	//	attribute:
+	// attribute:
 	//		A data item attribute for the value
-	//	path:
+	// path:
 	//		A simplified XPath for the value
-	//	name:
+	// name:
 	//		A composite property name
 	which: "source",
 	object: "",
@@ -171,15 +182,15 @@ dojo.declare("dojox.wire.ml.ChildWire", dijit._Widget, {
 	name: "",
 
 	_addWire: function(/*Transfer*/parent, /*Object*/args){
-		//	summary:
+		// summary:
 		//		Add a child Wire to Wire arguments
-		//	description:
+		// description:
 		//		If 'name' attribute is specified, a child Wire is added as
 		//		the named property of 'children' object of 'args'.
 		//		Otherwise, a child Wire is added to 'children' array of 'args'.
-		//	parent:
+		// parent:
 		//		A parent Transfer widget
-		//	args:
+		// args:
 		//		Wire arguments
 		if(this.name){ // object
 			if(!args.children){
@@ -195,15 +206,15 @@ dojo.declare("dojox.wire.ml.ChildWire", dijit._Widget, {
 	},
 
 	_getWire: function(/*Transfer*/parent){
-		//	summary:
+		// summary:
 		//		Build child Wire arguments from attributes
-		//	description:
+		// description:
 		//		Arguments object for a child Wire are build from attributes,
 		//		including 'object', 'property', 'type', 'converter',
 		//		'attribute' and 'path'.
-		//	parent:
+		// parent:
 		//		A parent Transfer widget
-		//	returns:
+		// returns:
 		//		Wire arguments object
 		return {
 			object: (this.object ? dojox.wire.ml._getValue(this.object) : undefined),
@@ -217,25 +228,25 @@ dojo.declare("dojox.wire.ml.ChildWire", dijit._Widget, {
 });
 
 dojo.declare("dojox.wire.ml.ColumnWire", dojox.wire.ml.ChildWire, {
-	//	summary:
+	// summary:
 	//		A widget to add a column wire
-	//	description:
+	// description:
 	//		Attributes of this widget are used to add a column Wire to
 	//		a TableAdapter of the parent Transfer widget.
-	//	column:
+	// column:
 	//		A column name
 	column: "",
 
 	_addWire: function(/*Transfer*/parent, /*Object*/args){
-		//	summary:
+		// summary:
 		//		Add a column Wire to Wire arguments
-		//	description:
+		// description:
 		//		If 'column' attribute is specified, a column Wire is added as
 		//		the named property of 'columns' object of 'args'.
 		//		Otherwise, a column Wire is added to 'columns' array of 'args'.
-		//	parent:
+		// parent:
 		//		A parent Transfer widget
-		//	args:
+		// args:
 		//		Wire arguments
 		if(this.column){ // object
 			if(!args.columns){
@@ -252,29 +263,29 @@ dojo.declare("dojox.wire.ml.ColumnWire", dojox.wire.ml.ChildWire, {
 });
 
 dojo.declare("dojox.wire.ml.NodeWire", [dojox.wire.ml.ChildWire, dijit._Container], {
-	//	summary:
+	// summary:
 	//		A widget to add node wires
-	//	description:
+	// description:
 	//		Attributes of this widget are used to add node Wires to
 	//		a TreeAdapter of the parent Transfer widget.
-	//	titleProperty:
+	// titleProperty:
 	//		A property for the node title
-	//	titleAttribute:
+	// titleAttribute:
 	//		A data item attribute for the node title
-	//	titlePath:
+	// titlePath:
 	//		A simplified XPath for the node title
 	titleProperty: "",
 	titleAttribute: "",
 	titlePath: "",
 
 	_addWire: function(/*Transfer*/parent, /*Object*/args){
-		//	summary:
+		// summary:
 		//		Add node Wires to Wire arguments
-		//	description:
+		// description:
 		//		Node Wires are added to 'nodes' array of 'args'.
-		//	parent:
+		// parent:
 		//		A parent Transfer widget
-		//	args:
+		// args:
 		//		Wire arguments
 		if(!args.nodes){
 			args.nodes = [];
@@ -283,9 +294,9 @@ dojo.declare("dojox.wire.ml.NodeWire", [dojox.wire.ml.ChildWire, dijit._Containe
 	},
 
 	_getWires: function(/*Transfer*/parent){
-		//	summary:
+		// summary:
 		//		Build node Wires arguments from attributes
-		//	description:
+		// description:
 		//		Arguments object for 'node' Wire are build from attributes,
 		//		including 'object', 'property', 'type', 'converter',
 		//		'attribute' and 'path'.
@@ -294,9 +305,9 @@ dojo.declare("dojox.wire.ml.NodeWire", [dojox.wire.ml.ChildWire, dijit._Containe
 		//		If this widget has child NodeWire widgets, their _getWires()
 		//		methods are called recursively to build 'children' array of
 		//		'args'.
-		//	parent:
+		// parent:
 		//		A parent Transfer widget
-		//	returns:
+		// returns:
 		//		Wire arguments object
 		var args = {
 			node: this._getWire(parent),
@@ -323,22 +334,22 @@ dojo.declare("dojox.wire.ml.NodeWire", [dojox.wire.ml.ChildWire, dijit._Containe
 });
 
 dojo.declare("dojox.wire.ml.SegmentWire", dojox.wire.ml.ChildWire, {
-	//	summary:
+	// summary:
 	//		A widget to add a segment wire
-	//	description:
+	// description:
 	//		Attributes of this widget are used to add a segment Wire to
 	//		a TextAdapter of the parent Transfer widget.
 
 	_addWire: function(/*Transfer*/parent, /*Object*/args){
-		//	summary:
-		//		Add a segument Wire to Wire arguments
-		//	description:
+		// summary:
+		//		Add a segment Wire to Wire arguments
+		// description:
 		//		A segment Wire is added to 'segments' array of 'args'.
 		//		If 'parent' has 'delimiter' attribute, it is used for
 		//		'delimiter' property of 'args'.
-		//	parent:
+		// parent:
 		//		A parent Transfer widget
-		//	args:
+		// args:
 		//		Wire arguments
 		if(!args.segments){
 			args.segments = [];
diff --git a/dojox/wire/ml/XmlHandler.js b/dojox/wire/ml/XmlHandler.js
index 5763233..bad042c 100644
--- a/dojox/wire/ml/XmlHandler.js
+++ b/dojox/wire/ml/XmlHandler.js
@@ -7,22 +7,23 @@ dojo.require("dojox.wire.ml.util");
 
 
 dojo.declare("dojox.wire.ml.XmlHandler", dojox.wire.ml.RestHandler, {
-	//	summary:
+	// summary:
 	//		A REST service handler for XML
-	//	description:
+	// description:
 	//		This class provides XML handling for a REST service.
+
 	contentType: "text/xml",
 	handleAs: "xml",
 
 	_getContent: function(/*String*/method, /*Array*/parameters){
-		//	description:
+		// description:
 		//		If 'method' is "POST" or "PUT", the first parameter in
 		//		'parameters' is used to generate an XML content.
-		//	method:
+		// method:
 		//		A method name
-		//	parameters:
+		// parameters:
 		//		An array of parameters
-		//	returns:
+		// returns:
 		//		A request content
 		var content = null;
 		if(method == "POST" || method == "PUT"){
@@ -46,14 +47,14 @@ dojo.declare("dojox.wire.ml.XmlHandler", dojox.wire.ml.RestHandler, {
 	},
 
 	_getResult: function(/*Document*/data){
-		//	summary:
+		// summary:
 		//		Extract a result
-		//	description:
+		// description:
 		//		A response data (XML Document) is returned wrapped with
 		//		XmlElement.
-		//	data:
+		// data:
 		//		A response data returned by a service
-		//	returns:
+		// returns:
 		//		A result object
 		if(data){
 			data = new dojox.wire.ml.XmlElement(data);
diff --git a/dojox/wire/ml/util.js b/dojox/wire/ml/util.js
index 6697246..cbb5214 100644
--- a/dojox/wire/ml/util.js
+++ b/dojox/wire/ml/util.js
@@ -4,20 +4,20 @@ dojo.require("dojox.xml.parser");
 dojo.require("dojox.wire.Wire");
 
 dojox.wire.ml._getValue = function(/*String*/source, /*Array*/args){
-	//	summary:
+	// summary:
 	//		Return a value
-	//	description:
+	// description:
 	//		This method obtains an object by an ID of a widget or an DOM
 	//		element.
 	//		If 'source' specifies a dotted notation to its property, a Wire is
 	//		used to get the object property.
 	//		If 'source' starts with "arguments", 'args' is used as a root
 	//		object for the Wire.
-	//	source:
+	// source:
 	//		A string to specify an object and its property
-	//	args:
+	// args:
 	//		An optional arguments array
-	//	returns:
+	// returns:
 	//		A value
 	if(!source){
 		return undefined; //undefined
@@ -44,14 +44,14 @@ dojox.wire.ml._getValue = function(/*String*/source, /*Array*/args){
 };
 
 dojox.wire.ml._setValue = function(/*String*/target, /*anything*/value){
-	//	summary:
+	// summary:
 	//		Store a value
-	//	description:
+	// description:
 	//		This method stores a value by an ID of a widget or an DOM
 	//		element with a dotted notation to its property, using a Wire.
-	//	target:
+	// target:
 	//		A string to specify an object and its property
-	//	value:
+	// value:
 	//		A value
 	if(!target){
 		return; //undefined
@@ -69,15 +69,15 @@ dojox.wire.ml._setValue = function(/*String*/target, /*anything*/value){
 };
 
 dojo.declare("dojox.wire.ml.XmlElement", null, {
-	//	summary:
+	// summary:
 	//		An object wrapping an XML element
-	//	description:
+	// description:
 	//		This class represents an XML element.
 
 	constructor: function(/*Element||String*/element){
-		//	summary:
+		// summary:
 		//		Initialize with an XML element or a tag name
-		//	element:
+		// element:
 		//		An XML element or a tag name
 		if(dojo.isString(element)){
 			element = this._getDocument().createElement(element);
@@ -85,17 +85,17 @@ dojo.declare("dojox.wire.ml.XmlElement", null, {
 		this.element = element;
 	},
 	getPropertyValue: function(/*String*/property){
-		//	summary:
+		// summary:
 		//		Return a property value
-		//	description:
+		// description:
 		//		If 'property' starts with '@', the attribute value is returned.
 		//		If 'property' specifies "text()", the value of the first child
 		//		text is returned.
 		//		Otherwise, child elements of the tag name specified with
 		//		'property' are returned.
-		//	property:
+		// property:
 		//		A property name
-		//	returns:
+		// returns:
 		//		A property value
 		var value = undefined;
 		if(!this.element){
@@ -133,9 +133,9 @@ dojo.declare("dojox.wire.ml.XmlElement", null, {
 	},
 
 	setPropertyValue: function(/*String*/property, /*String||Array||XmlElement*/value){
-		//	summary:
+		// summary:
 		//		Store a property value
-		//	description:
+		// description:
 		//		If 'property' starts with '@', 'value' is set to the attribute.
 		//		If 'property' specifies "text()", 'value' is set as the first
 		//		child text.
@@ -143,9 +143,9 @@ dojo.declare("dojox.wire.ml.XmlElement", null, {
 		//		specified with 'property' is created and 'value' is set as
 		//		the first child text of the child element.
 		//		Otherwise, 'value' is set to as child elements.
-		//	property:
+		// property:
 		//		A property name
-		//	value:
+		// value:
 		//		A property value
 		var i;
 		var text;
@@ -206,11 +206,11 @@ dojo.declare("dojox.wire.ml.XmlElement", null, {
 	},
 
 	toString: function(){
-		//	summary:
+		// summary:
 		//		Return a value of the first text child of the element
-		//	description:
+		// description:
 		//		A value of the first text child of the element is returned.
-		//	returns:
+		// returns:
 		//		A value of the first text child of the element
 		var s = "";
 		if(this.element){
@@ -223,12 +223,12 @@ dojo.declare("dojox.wire.ml.XmlElement", null, {
 	},
 
 	toObject: function(){
-		//	summary:
+		// summary:
 		//		Return an object representation of the element
-		//	description:
+		// description:
 		//		An object with properties for child elements, attributes and
 		//		text is returned.
-		//	returns:
+		// returns:
 		//		An object representation of the element
 		if(!this.element){
 			return null; //null
@@ -277,13 +277,13 @@ dojo.declare("dojox.wire.ml.XmlElement", null, {
 	},
 
 	_getDocument: function(){
-		//	summary:
+		// summary:
 		//		Return a DOM document
-		//	description:
+		// description:
 		//		If 'element' is specified, a DOM document of the element is
 		//		returned.
 		//		Otherwise, a DOM document is created.
-		//	returns:
+		// returns:
 		//		A DOM document
 		if(this.element){
 			return (this.element.nodeType == 9 /* DOCUMENT_NODE */ ?
diff --git a/dojox/wire/tests/markup/Action.html b/dojox/wire/tests/markup/Action.html
index 75cbd49..36ae1e3 100644
--- a/dojox/wire/tests/markup/Action.html
+++ b/dojox/wire/tests/markup/Action.html
@@ -1,7 +1,7 @@
 <html>
 <head>
 <title>Test Action</title>
-<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 dojo.provide("dojox.wire.ml.tests.markup.Action");
 
diff --git a/dojox/wire/tests/markup/Data.html b/dojox/wire/tests/markup/Data.html
index b1107c0..0635693 100644
--- a/dojox/wire/tests/markup/Data.html
+++ b/dojox/wire/tests/markup/Data.html
@@ -1,7 +1,7 @@
 <html>
 <head>
 <title>Test Data</title>
-<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 dojo.provide("dojox.wire.ml.tests.markup.Data");
 
diff --git a/dojox/wire/tests/markup/DataStore.html b/dojox/wire/tests/markup/DataStore.html
index 3c55f7e..6ad8397 100644
--- a/dojox/wire/tests/markup/DataStore.html
+++ b/dojox/wire/tests/markup/DataStore.html
@@ -1,7 +1,7 @@
 <html>
 <head>
 <title>Test DataStore</title>
-<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 dojo.provide("dojox.wire.ml.tests.markup.DataStore");
 
diff --git a/dojox/wire/tests/markup/Invocation.html b/dojox/wire/tests/markup/Invocation.html
index dd6f6e4..9d2ddbe 100644
--- a/dojox/wire/tests/markup/Invocation.html
+++ b/dojox/wire/tests/markup/Invocation.html
@@ -1,7 +1,7 @@
 <html>
 <head>
 <title>Test Invocation</title>
-<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad:true "></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad:true "></script>
 <script type="text/javascript">
 dojo.provide("dojox.wire.ml.tests.markup.Invocation");
 
diff --git a/dojox/wire/tests/markup/Service.html b/dojox/wire/tests/markup/Service.html
index 0448c61..f73280d 100644
--- a/dojox/wire/tests/markup/Service.html
+++ b/dojox/wire/tests/markup/Service.html
@@ -1,7 +1,7 @@
 <html>
 <head>
 <title>Test Service</title>
-<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 dojo.provide("dojox.wire.ml.tests.markup.Service");
 
diff --git a/dojox/wire/tests/markup/Transfer.html b/dojox/wire/tests/markup/Transfer.html
index afab400..fdfd649 100644
--- a/dojox/wire/tests/markup/Transfer.html
+++ b/dojox/wire/tests/markup/Transfer.html
@@ -1,7 +1,7 @@
 <html>
 <head>
 <title>Test Transfer</title>
-<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+<script type="text/javascript" src="../../../../dojo/dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 <script type="text/javascript">
 dojo.provide("dojox.wire.ml.tests.markup.Transfer");
 
diff --git a/dojox/xml/parser.js b/dojox/xml/parser.js
index 0559b7a..3ac13a4 100644
--- a/dojox/xml/parser.js
+++ b/dojox/xml/parser.js
@@ -18,13 +18,13 @@ dojo.getObject("xml.parser", true, dojox);
 //NOTATION_NODE                 = 12;
 
 dojox.xml.parser.parse = function(/*String?*/ str, /*String?*/ mimetype){
-	//	summary:
+	// summary:
 	//		cross-browser implementation of creating an XML document object from null, empty string, and XML text..
 	//
-	//	str:
+	// str:
 	//		Optional text to create the document from.  If not provided, an empty XML document will be created.
 	//		If str is empty string "", then a new empty document will be created.
-	//	mimetype:
+	// mimetype:
 	//		Optional mimetype of the text.  Typically, this is text/xml.  Will be defaulted to text/xml if not provided.
 	var _document = dojo.doc;
 	var doc;
@@ -89,15 +89,15 @@ dojox.xml.parser.parse = function(/*String?*/ str, /*String?*/ mimetype){
 };
 
 dojox.xml.parser.textContent = function(/*Node*/node, /*String?*/text){
-	//	summary:
+	// summary:
 	//		Implementation of the DOM Level 3 attribute; scan node for text
-	//	description:
+	// description:
 	//		Implementation of the DOM Level 3 attribute; scan node for text
 	//		This function can also update the text of a node by replacing all child
 	//		content of the node.
-	//	node:
+	// node:
 	//		The node to get the text off of or set the text on.
-	//	text:
+	// text:
 	//		Optional argument of the text to apply to the node.
 	if(arguments.length>1){
 		var _document = node.ownerDocument || dojo.doc;  //Preference is to get the node owning doc first or it may fail
@@ -126,16 +126,16 @@ dojox.xml.parser.textContent = function(/*Node*/node, /*String?*/text){
 	}
 };
 
-dojox.xml.parser.replaceChildren = function(/*Element*/node, /*Node || Array*/ newChildren){
-	//	summary:
+dojox.xml.parser.replaceChildren = function(/*Element*/node, /*Node|Array*/ newChildren){
+	// summary:
 	//		Removes all children of node and appends newChild. All the existing
 	//		children will be destroyed.
-	//	description:
+	// description:
 	//		Removes all children of node and appends newChild. All the existing
 	//		children will be destroyed.
-	// 	node:
+	// node:
 	//		The node to modify the children on
-	//	newChildren:
+	// newChildren:
 	//		The children to add to the node.  It can either be a single Node or an
 	//		array of Nodes.
 	var nodes = [];
@@ -159,11 +159,11 @@ dojox.xml.parser.replaceChildren = function(/*Element*/node, /*Node || Array*/ n
 };
 
 dojox.xml.parser.removeChildren = function(/*Element*/node){
-	//	summary:
+	// summary:
 	//		removes all children from node and returns the count of children removed.
 	//		The children nodes are not destroyed. Be sure to call dojo.destroy on them
 	//		after they are not used anymore.
-	//	node:
+	// node:
 	//		The node to remove all the children from.
 	var count = node.childNodes.length;
 	while(node.hasChildNodes()){
@@ -174,9 +174,9 @@ dojox.xml.parser.removeChildren = function(/*Element*/node){
 
 
 dojox.xml.parser.innerXML = function(/*Node*/node){
-	//	summary:
+	// summary:
 	//		Implementation of MS's innerXML function.
-	//	node:
+	// node:
 	//		The node from which to generate the XML text representation.
 	if(node.innerXML){
 		return node.innerXML;	//	String
diff --git a/dojox/xml/tests/mail.html b/dojox/xml/tests/mail.html
index cc8d0ab..28e9f10 100644
--- a/dojox/xml/tests/mail.html
+++ b/dojox/xml/tests/mail.html
@@ -11,7 +11,7 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true, defaultTestTheme: 'soria'"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true, defaultTestTheme: 'soria'"></script>
 	<script type="text/javascript" src="../../../dijit/tests/tests/_testCommon.js"></script>
 	<script type="text/javascript">
 		// Use profile builds, if available. Since we use pretty much all of
@@ -110,7 +110,7 @@
 <body class="soria">
 	<script type="text/xml" dojoType="dojox.xml.Script">
 		<ui xmlns:dojo="dojo" xmlns="html">
-			<dojo:data.ItemFileWriteStore jsId="mailStore" url="mail/mail.json"/>
+			<dojo:data.ItemFileWriteStore data-dojo-id="mailStore" url="mail/mail.json"/>
 		</ui>
 	</script>
 
@@ -311,7 +311,7 @@
 			<dijit:Tooltip connectId="options">Set various options</dijit:Tooltip>
 		</dijit:Toolbar>
 
-		<dijit:layout.TabContainer dojoType="dijit.layout.TabContainer" id="tabs" jsId="tabs" layoutAlign="client">
+		<dijit:layout.TabContainer dojoType="dijit.layout.TabContainer" id="tabs" data-dojo-id="tabs" layoutAlign="client">
 			<!-- main section with tree, table, and preview -->
 			<dijit:layout.SplitContainer
 				orientation="horizontal"
@@ -377,7 +377,7 @@
 					<dijit:layout.ContentPane id="listPane" sizeMin="20" sizeShare="20">
 						<span dojoType="demo.Table" store="mailStore"
 							query="{ query: { type: 'message' }, sort: [ { attribute: 'label' } ]  }"
-							id="foo" jsId="table" style="width: 100%">
+							id="foo" data-dojo-id="table" style="width: 100%">
 							<html:script type="dojo/method" event="onClick" args="item">
 							var sender = this.store.getValue(item, "sender");
 								var subject = this.store.getValue(item, "label");
diff --git a/dojox/xml/tests/widgetParser.html b/dojox/xml/tests/widgetParser.html
index 06b0c7a..407f740 100644
--- a/dojox/xml/tests/widgetParser.html
+++ b/dojox/xml/tests/widgetParser.html
@@ -10,7 +10,7 @@
 
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 		
 	<script type="text/javascript">
 		require([
diff --git a/dojox/xml/widgetParser.js b/dojox/xml/widgetParser.js
index 8cdfc76..c6e8149 100644
--- a/dojox/xml/widgetParser.js
+++ b/dojox/xml/widgetParser.js
@@ -132,7 +132,7 @@ xXml.widgetParser = new function(){
 			newNode.setAttribute("dojoType", dojoType);
 		}
 		
-		//	TODO:
+		// TODO:
 		//		we should probably set this up different, mixin a function
 		//		depending on if it is IE rather than checking every time here
 		//		the xmlns problem and the style problem are both IE specific
diff --git a/dojox/xmpp/ChatService.js b/dojox/xmpp/ChatService.js
index 365d219..4b0d52d 100644
--- a/dojox/xmpp/ChatService.js
+++ b/dojox/xmpp/ChatService.js
@@ -8,7 +8,7 @@ dojox.xmpp.chat = {
 	INACTIVE_STATE: 'inactive',
 	PAUSED_STATE: 'paused',
 	GONE_STATE: 'gone'
-}
+};
 
 dojo.declare("dojox.xmpp.ChatService", null, {
 	state: "",
diff --git a/dojox/xmpp/PresenceService.js b/dojox/xmpp/PresenceService.js
index 90cfba9..3a5bcca 100644
--- a/dojox/xmpp/PresenceService.js
+++ b/dojox/xmpp/PresenceService.js
@@ -21,7 +21,7 @@ dojox.xmpp.presence = {
 	STATUS_OFFLINE: 'offline',
 	
 	STATUS_INVISIBLE: 'invisible'
-}
+};
 
 dojo.declare("dojox.xmpp.PresenceService", null, {
 	constructor: function(xmppService){
diff --git a/dojox/xmpp/RosterService.js b/dojox/xmpp/RosterService.js
index 8d78eb5..e3fc278 100644
--- a/dojox/xmpp/RosterService.js
+++ b/dojox/xmpp/RosterService.js
@@ -4,7 +4,7 @@ dojox.xmpp.roster = {
 	ADDED: 101,
 	CHANGED: 102,
 	REMOVED: 103
-}
+};
 
 dojo.declare("dojox.xmpp.RosterService", null, {
 	constructor: function(xmppSession){
diff --git a/dojox/xmpp/TransportSession.js b/dojox/xmpp/TransportSession.js
index 216b445..d7f4220 100644
--- a/dojox/xmpp/TransportSession.js
+++ b/dojox/xmpp/TransportSession.js
@@ -157,12 +157,12 @@ dojo.extend(dojox.xmpp.TransportSession, {
 		},
 
 		dispatchPacket: function(msg, protocolMatchType, matchId, matchProperty){
-			// summary
-			// Main Packet dispatcher, most calls should be made with this other
-			// than a few setup calls which use add items to the queue directly
-			//protocolMatchType, matchId, and matchProperty are optional params
-			//that allow a deferred to be tied to a protocol response instad of the whole
-			//rid
+			// summary:
+			//		Main Packet dispatcher, most calls should be made with this other
+			//		than a few setup calls which use add items to the queue directly
+			//		protocolMatchType, matchId, and matchProperty are optional params
+			//		that allow a deferred to be tied to a protocol response instad of the whole
+			//		rid
 	
 		//	//console.log("In dispatchPacket ", msg, protocolMatchType, matchId, matchProperty);
 			if (msg){
@@ -200,7 +200,7 @@ dojo.extend(dojox.xmpp.TransportSession, {
 
 			if (!this.authId){
 				//FIXME according to original nodes, this should wait a little while and try
-				//      again up to three times to see if we get this data.
+				//		again up to three times to see if we get this data.
 				console.debug("TransportSession::dispatchPacket() No authId, packet dropped [FIXME]")
 				return;
 			}
@@ -426,10 +426,10 @@ dojo.extend(dojox.xmpp.TransportSession, {
 
 
 		processProtocolResponse: function(msg, rid){
-			//summary
-			//process the individual protocol messages and if there
-			//is a matching set of protocolMatchType, matchId, and matchPropery
-			//fire off the deferred
+			// summary:
+			//		process the individual protocol messages and if there
+			//		is a matching set of protocolMatchType, matchId, and matchPropery
+			//		fire off the deferred
 
 			this.onProcessProtocolResponse(msg);
 			var key = msg.nodeName + "-" +msg.getAttribute("id");
diff --git a/dojox/xmpp/bosh.js b/dojox/xmpp/bosh.js
index 7d527f4..39031fc 100644
--- a/dojox/xmpp/bosh.js
+++ b/dojox/xmpp/bosh.js
@@ -7,11 +7,11 @@ dojo.require("dojox.xml.parser");
 /*=====
 dojo.declare("dojox.xmpp.bosh.__initArgs", null, {
 	constructor: function(){
-		//	summary:
+		// summary:
 		//		The arguments passed to dojox.xmpp.bosh.initialize
-		//	iframes:
+		// iframes:
 		//		The number of iframes to use for transmission
-		//	load:
+		// load:
 		//		The function called when the first iframe is
 		//		loaded.  Generally used to signal when to send
 		//		login information
@@ -21,12 +21,12 @@ dojo.declare("dojox.xmpp.bosh.__initArgs", null, {
 });
 dojo.declare("dojox.xmpp.bosh.__ioArgs", dojo.__IoArgs, {
 	constructor: function(){
-		//	summary:
+		// summary:
 		//		All the properties described in the dojo.__ioArgs type, apply to this
 		//		type as well, EXCEPT "handleAs". It is not applicable to
 		//		dojox.xmpp.bosh.get() calls, since it is implied that the
 		//		return will be a string of XML.
-		//	rid:
+		// rid:
 		//		The rid of the message being sent.
 		this.rid = rid;
 	}
@@ -92,7 +92,7 @@ dojox.xmpp.bosh = {
 	},
 
 	get: function(/*dojox.xmpp.bosh.__ioArgs*/args){
-		//	summary:
+		// summary:
 		//		sends a get request using a dynamically created script tag.
 		var iframe = this.findOpenIframe();
 		var iframeDoc = dojo.io.iframe.doc(iframe);
@@ -115,8 +115,9 @@ dojox.xmpp.bosh = {
 	},
 
 	remove: function(/*String*/id, /*Document?*/frameDocument){
-		//summary: removes the script element with the given id, from the given frameDocument.
-		//If no frameDocument is passed, the current document is used.
+		// summary:
+		//		removes the script element with the given id, from the given frameDocument.
+		//		If no frameDocument is passed, the current document is used.
 		dojo.destroy(dojo.byId(id, frameDocument));
 
 		//Remove the BOSH callback on dojox.xmpp.bosh, if it exists.
@@ -126,7 +127,7 @@ dojox.xmpp.bosh = {
 	},
 
 	_makeScriptDeferred: function(/*Object*/args){
-		//summary:
+		// summary:
 		//		sets up a Deferred object for an IO request.
 		var dfd = dojo._ioSetArgs(args, this._deferredCancel, this._deferredOk, this._deferredError);
 
@@ -143,7 +144,8 @@ dojox.xmpp.bosh = {
 	},
 
 	_deferredCancel: function(/*Deferred*/dfd){
-		//summary: canceller function for dojo._ioSetArgs call.
+		// summary:
+		//		canceller function for dojo._ioSetArgs call.
 
 		//DO NOT use "this" and expect it to be dojox.xmpp.bosh.
 		dfd.canceled = true;
@@ -153,7 +155,8 @@ dojox.xmpp.bosh = {
 	},
 
 	_deferredOk: function(/*Deferred*/dfd){
-		//summary: okHandler function for dojo._ioSetArgs call.
+		// summary:
+		//		okHandler function for dojo._ioSetArgs call.
 
 		//DO NOT use "this" and expect it to be dojo.xmpp.bosh.
 		var ioArgs = dfd.ioArgs;
@@ -171,7 +174,8 @@ dojox.xmpp.bosh = {
 	},
 
 	_deferredError: function(/*Error*/error, /*Deferred*/dfd){
-		//summary: errHandler function for dojo._ioSetArgs call.
+		// summary:
+		//		errHandler function for dojo._ioSetArgs call.
 
 		if(dfd.ioArgs.canDelete){
 			//DO NOT use "this" and expect it to be dojox.xmpp.bosh
@@ -188,14 +192,16 @@ dojox.xmpp.bosh = {
 
 	_deadScripts: [],
 	_addDeadScript: function(/*Object*/ioArgs){
-		//summary: sets up an entry in the deadScripts array.
+		// summary:
+		//		sets up an entry in the deadScripts array.
 		dojox.xmpp.bosh._deadScripts.push({id: ioArgs.id, frameDoc: ioArgs.frameDoc});
 		//Being extra paranoid about leaks:
 		ioArgs.frameDoc = null;
 	},
 
 	_validCheck: function(/*Deferred*/dfd){
-		//summary: inflight check function to see if dfd is still valid.
+		// summary:
+		//		inflight check function to see if dfd is still valid.
 
 		//Do script cleanup here. We wait for one inflight pass
 		//to make sure we don't get any weird things by trying to remove a script
@@ -216,7 +222,8 @@ dojox.xmpp.bosh = {
 	},
 
 	_ioCheck: function(/*Deferred*/dfd){
-		//summary: inflight check function to see if IO finished.
+		// summary:
+		//		inflight check function to see if IO finished.
 		var ioArgs = dfd.ioArgs;
 		//Check for returned message
 		if(ioArgs.xmppMessage){
@@ -226,7 +233,8 @@ dojox.xmpp.bosh = {
 	},
 
 	_resHandle: function(/*Deferred*/dfd){
-		//summary: inflight function to handle a completed response.
+		// summary:
+		//		inflight function to handle a completed response.
 		if(dojox.xmpp.bosh._ioCheck(dfd)){
 			dfd.callback(dfd);
 		}else{
diff --git a/dojox/xmpp/tests/test_xmppService.html b/dojox/xmpp/tests/test_xmppService.html
index c8f6eef..4313814 100644
--- a/dojox/xmpp/tests/test_xmppService.html
+++ b/dojox/xmpp/tests/test_xmppService.html
@@ -46,7 +46,7 @@
 		<title>xmpp test page</title>
 
 		<script type="text/javascript" 
-			src="../../../dojo/dojo.js" djConfig="isDebug:true,parseOnLoad:true">
+			src="../../../dojo/dojo.js" data-dojo-config="isDebug:true,parseOnLoad:true">
 		</script>
 		<script type="text/javascript">
 
diff --git a/dojox/xmpp/util.js b/dojox/xmpp/util.js
index 2962dbb..02bb466 100644
--- a/dojox/xmpp/util.js
+++ b/dojox/xmpp/util.js
@@ -7,46 +7,46 @@ dojox.xmpp.util.xmlEncode = function(str) {
 		str = str.replace("&", "&").replace(">", ">").replace("<", "<").replace("'", "'").replace('"', """);
 	}
 	return str;
-}
+};
 
 dojox.xmpp.util.encodeJid = function(jid) {
-		var buffer = new dojox.string.Builder();
-		for(var i =0; i < jid.length; i++) {
-			var ch = jid.charAt(i);
-			var rep = ch;
-			switch(ch){
-				case ' ' :
-					rep = "\\20";
-				break;
-				case '"' :
-					rep = "\\22";
-				break;
-				case '#' :
-					rep = "\\23";
-				break;
-				case '&' :
-					rep = "\\26";
-				break;
-				case "'" :
-					rep = "\\27";
-				break;
-				case '/' :
-					rep = "\\2f";
-				break;
-				case ':' :
-					rep = "\\3a";
-				break;
-				case '<' :
-					rep = "\\3c";
-				break;
-				case '>' :
-					rep = "\\3e";
-				break;
-			}
-			buffer.append(rep);
+	var buffer = new dojox.string.Builder();
+	for(var i =0; i < jid.length; i++) {
+		var ch = jid.charAt(i);
+		var rep = ch;
+		switch(ch){
+			case ' ' :
+				rep = "\\20";
+			break;
+			case '"' :
+				rep = "\\22";
+			break;
+			case '#' :
+				rep = "\\23";
+			break;
+			case '&' :
+				rep = "\\26";
+			break;
+			case "'" :
+				rep = "\\27";
+			break;
+			case '/' :
+				rep = "\\2f";
+			break;
+			case ':' :
+				rep = "\\3a";
+			break;
+			case '<' :
+				rep = "\\3c";
+			break;
+			case '>' :
+				rep = "\\3e";
+			break;
 		}
-		return buffer.toString();
+		buffer.append(rep);
 	}
+	return buffer.toString();
+};
 
 dojox.xmpp.util.decodeJid = function(jid) {
 	
@@ -75,7 +75,7 @@ dojox.xmpp.util.decodeJid = function(jid) {
 	});
 	
 	return jid;
-}
+};
 
 
 dojox.xmpp.util.createElement = function(tag, attributes, terminal){
@@ -95,32 +95,33 @@ dojox.xmpp.util.createElement = function(tag, attributes, terminal){
 	}
 
 	return elem.toString();
-}
+};
 
 dojox.xmpp.util.stripHtml = function(str){
-	// summary
+	// summary:
 	//		Strips all HTML, including attributes and brackets
 	//		| <div onmouse="doBadThing()">Click <b>Me</b></div>
 	//		| becomes: Click Me
 	var re=/<[^>]*?>/gi;
 	for (var i=0; i<arguments.length; i++) {}
 	return str.replace(re, "");
-}
+};
 
 dojox.xmpp.util.decodeHtmlEntities = function(str){
-	// Summary: decodes HTML entities to js characters so the string can be
-	// fed to a textarea.value
+	// summary:
+	//		decodes HTML entities to js characters so the string can be
+	//		fed to a textarea.value
 	var ta = dojo.doc.createElement("textarea");
 	ta.innerHTML = str.replace(/</g,"<").replace(/>/g,">");
 	return ta.value;
-}
+};
 
 dojox.xmpp.util.htmlToPlain = function(str){
 	str = dojox.xmpp.util.decodeHtmlEntities(str);
 	str = str.replace(/<br\s*[i\/]{0,1}>/gi,"\n");
 	str = dojox.xmpp.util.stripHtml(str);
 	return str;
-}
+};
 
 dojox.xmpp.util.Base64 = {};
 
@@ -133,7 +134,7 @@ dojox.xmpp.util.Base64.encode = function(input){
 		return b;
 	};
 	return dojox.encoding.base64.encode(s2b(input));
-}
+};
 
 
 dojox.xmpp.util.Base64.decode = function(input){
@@ -143,4 +144,4 @@ dojox.xmpp.util.Base64.decode = function(input){
 		return s.join("");
 	};
 	return b2s(dojox.encoding.base64.decode(input));
-}
+};
diff --git a/dojox/xmpp/xmppSession.js b/dojox/xmpp/xmppSession.js
index 6329b3d..65325c1 100644
--- a/dojox/xmpp/xmppSession.js
+++ b/dojox/xmpp/xmppSession.js
@@ -15,7 +15,7 @@ dojox.xmpp.xmpp = {
 	BIND_NS: 'urn:ietf:params:xml:ns:xmpp-bind',
 	SESSION_NS: 'urn:ietf:params:xml:ns:xmpp-session',
 	BODY_NS: "http://jabber.org/protocol/httpbind",
-	
+
 	XHTML_BODY_NS: "http://www.w3.org/1999/xhtml",
 	XHTML_IM_NS: "http://jabber.org/protocol/xhtml-im",
 
@@ -68,7 +68,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 		roster: [],
 		chatRegister: [],
 		_iqId: 0,
-	
+
 		open: function(user, password, resource){
 
 			if (!user) {
@@ -78,7 +78,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				if(user.indexOf('@') == -1) {
 					this.jid = this.jid + '@' + this.domain;
 				}
-        	}
+			}
 
 			//allow null password here as its not needed in the SSO case
 			if (password) {
@@ -130,10 +130,11 @@ dojo.extend(dojox.xmpp.xmppSession, {
 					this.chatHandler(msg);
 					break;
 				case "normal":
+					break;
 				default:
 					this.simpleMessageHandler(msg);
 			}
-			
+
 		},
 
 		iqHandler: function(msg){
@@ -242,7 +243,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 			var message = {
 				from: msg.getAttribute('from'),
 				to: msg.getAttribute('to')
-			}
+			};
 
 			var chatState = null;
 				//console.log("chat child node ", msg.childNodes, msg.childNodes.length);
@@ -255,12 +256,13 @@ dojo.extend(dojox.xmpp.xmppSession, {
 							message.chatid = n.firstChild.nodeValue;
 							break;
 						case 'body':
-							if (!n.getAttribute('xmlns') || (n.getAttribute('xmlns')=="")){
+							if (!n.getAttribute('xmlns') || (n.getAttribute('xmlns')==="")){
 								message.body = n.firstChild.nodeValue;
 							}
 							break;
 						case 'subject':
 							message.subject = n.firstChild.nodeValue;
+							break;
 						case 'html':
 							if (n.getAttribute('xmlns')==dojox.xmpp.xmpp.XHTML_IM_NS){
 								message.xhtml = n.getElementsByTagName("body")[0];
@@ -305,13 +307,13 @@ dojo.extend(dojox.xmpp.xmppSession, {
 
 				if (chat.firstMessage){
 					if (chatState == dojox.xmpp.chat.ACTIVE_STATE) {
-						chat.useChatState = (chatState != null) ? true : false;
+						chat.useChatState = (chatState !== null) ? true : false;
 						chat.firstMessage = false;
 					}
 				}
 			}
 
-			if ((!message.body || message.body=="") && !message.xhtml) {return;}
+			if ((!message.body || message.body==="") && !message.xhtml) {return;}
 
 			if (found>-1){
 				var chat = this.chatRegister[found];
@@ -338,7 +340,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 			this.onRegisterChatInstance(chatInstance, message);
 			chatInstance.recieveMessage(message,true);
 		},
-		
+
 		iqSetHandler: function(msg){
 			if (msg.hasChildNodes()){
 				var fn = msg.firstChild;
@@ -362,22 +364,23 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				to: to || this.domain,
 				type: 'result',
 				from: this.jid + "/" + this.resource
-			}
+			};
 			this.dispatchPacket(dojox.xmpp.util.createElement("iq",req,true));
 		},
 
 		rosterSetHandler: function(elem){
 			//console.log("xmppSession::rosterSetHandler()", arguments);
+			var r;
 			for (var i=0; i<elem.childNodes.length;i++){
 				var n = elem.childNodes[i];
-			
+
 				if (n.nodeName=="item"){
 					var found = false;
 					var state = -1;
 					var rosterItem = null;
 					var previousCopy = null;
 					for(var x=0; x<this.roster.length;x++){
-						var r = this.roster[x];
+						r = this.roster[x];
 						if(n.getAttribute('jid')==r.jid){
 							found = true;
 							if(n.getAttribute('subscription')=='remove'){
@@ -386,7 +389,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 									id: r.jid,
 									name: r.name,
 									groups:[]
-								}
+								};
 
 								for (var y=0;y<r.groups.length;y++){
 									rosterItem.groups.push(r.groups[y]);
@@ -407,12 +410,12 @@ dojo.extend(dojox.xmpp.xmppSession, {
 								if (n.getAttribute('subscription')){
 									r.status = n.getAttribute('subscription');
 								}
-						
+
 								r.substatus = dojox.xmpp.presence.SUBSCRIPTION_SUBSTATUS_NONE;
 								if(n.getAttribute('ask')=='subscribe'){
 									r.substatus = dojox.xmpp.presence.SUBSCRIPTION_REQUEST_PENDING;
 								}
-					
+
 								for(var y=0;y<n.childNodes.length;y++){
 									var groupNode = n.childNodes[y];
 									if ((groupNode.nodeName=='group')&&(groupNode.hasChildNodes())){
@@ -431,7 +434,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 						rosterItem = r;
 						state = dojox.xmpp.roster.ADDED;
 					}
-				
+
 					switch(state){
 						case dojox.xmpp.roster.ADDED:
 							this.onRosterAdded(rosterItem);
@@ -464,10 +467,10 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				show: dojox.xmpp.presence.STATUS_ONLINE,
 				priority: 5,
 				hasAvatar: false
-			}
+			};
 
 			if(msg.getAttribute('type')=='unavailable'){
-				p.show=dojox.xmpp.presence.STATUS_OFFLINE
+				p.show=dojox.xmpp.presence.STATUS_OFFLINE;
 			}
 
 			for (var i=0; i<msg.childNodes.length;i++){
@@ -478,11 +481,11 @@ dojo.extend(dojox.xmpp.xmppSession, {
 						case 'show':
 							p[n.nodeName]=n.firstChild.nodeValue;
 							break;
-						case 'status':
-							p.priority=parseInt(n.firstChild.nodeValue);
+						case 'priority':
+							p.priority=parseInt(n.firstChild.nodeValue, 10);
 							break;
 						case 'x':
-							if(n.firstChild && n.firstChild.firstChild &&  n.firstChild.firstChild.nodeValue != "") {
+							if(n.firstChild && n.firstChild.firstChild && n.firstChild.firstChild.nodeValue !== "") {
 								p.avatarHash= n.firstChild.firstChild.nodeValue;
 								p.hasAvatar = true;
 							}
@@ -500,14 +503,14 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				id: this.getNextIqId(),
 				from: this.jid + "/" + this.resource,
 				type: "get"
-			}
+			};
 			var req = new dojox.string.Builder(dojox.xmpp.util.createElement("iq",props,false));
 			req.append(dojox.xmpp.util.createElement("query",{xmlns: "jabber:iq:roster"},true));
 			req.append("</iq>");
 
 			var def = this.dispatchPacket(req,"iq", props.id);
 			def.addCallback(this, "onRetrieveRoster");
-			
+
 		},
 
 		getRosterIndex: function(jid){
@@ -529,13 +532,13 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				status: dojox.xmpp.presence.SUBSCRIPTION_NONE,
 				substatus: dojox.xmpp.presence.SUBSCRIPTION_SUBSTATUS_NONE
 			//	displayToUser: false
-			}
+			};
 
 			if (!re.name){
 				re.name = re.id;
 			}
-			
-			
+
+
 
 			for(var i=0; i<elem.childNodes.length;i++){
 				var n = elem.childNodes[i];
@@ -568,7 +571,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 			var props = {
 				id: this.getNextIqId(),
 				type: "set"
-			}
+			};
 			var bindReq = new dojox.string.Builder(dojox.xmpp.util.createElement("iq", props, false));
 			bindReq.append(dojox.xmpp.util.createElement("bind", {xmlns: dojox.xmpp.xmpp.BIND_NS}, false));
 
@@ -608,6 +611,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 			if (this.state != "Terminate") {
 				return this.session.dispatchPacket(msg,type,matchId);
 			}else{
+
 				//console.log("xmppSession::dispatchPacket - Session in Terminate state, dropping packet");
 			}
 		},
@@ -628,7 +632,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				type: 'set',
 				from: this.jid + '/' + this.resource,
 				to: service
-			}
+			};
 			var request = new dojox.string.Builder(dojox.xmpp.util.createElement("iq",req,false));
 			request.append(dojox.xmpp.util.createElement('query',{xmlns:'jabber:iq:search'},false));
 			request.append(dojox.xmpp.util.createElement(searchAttribute,{},false));
@@ -662,7 +666,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 
 		onBindResource: function(msg, hasSession){
 			//console.log("xmppSession::onBindResource() ", msg);
-		
+
 			if (msg.getAttribute('type')=='result'){
 				//console.log("xmppSession::onBindResource() Got Result Message");
 				if ((msg.hasChildNodes()) && (msg.firstChild.nodeName=="bind")){
@@ -678,7 +682,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 						var props = {
 							id: this.getNextIqId(),
 							type: "set"
-						}
+						};
 						var bindReq = new dojox.string.Builder(dojox.xmpp.util.createElement("iq", props, false));
 						bindReq.append(dojox.xmpp.util.createElement("session", {xmlns: dojox.xmpp.xmpp.SESSION_NS}, true));
 						bindReq.append("</iq>");
@@ -692,7 +696,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				}
 
 				this.onLogin();
-		
+
 			}else if(msg.getAttribute('type')=='error'){
 				//console.log("xmppSession::onBindResource() Bind Error ", msg);
 				var err = this.processXmppError(msg);
@@ -736,7 +740,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 
 			return msg;
 		},
-		
+
 		onRosterUpdated: function() {},
 
 		onSubscriptionRequest: function(req){},
@@ -784,8 +788,8 @@ dojo.extend(dojox.xmpp.xmppSession, {
 			var err = {
 				stanzaType: msg.nodeName,
 				id: msg.getAttribute('id')
-			}
-	
+			};
+
 			for (var i=0; i<msg.childNodes.length; i++){
 				var n = msg.childNodes[i];
 				switch(n.nodeName){
@@ -812,7 +816,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 			var req = {type:'error'};
 			if (to) { req.to=to; }
 			if (id) { req.id=id; }
-		
+
 			var request = new dojox.string.Builder(dojox.xmpp.util.createElement(stanzaType,req,false));
 			request.append(dojox.xmpp.util.createElement('error',{type:errorType},false));
 			request.append(dojox.xmpp.util.createElement('condition',{xmlns:dojox.xmpp.xmpp.STANZA_NS},true));
@@ -821,7 +825,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				var textAttr={
 					xmlns: dojox.xmpp.xmpp.STANZA_NS,
 					"xml:lang":this.lang
-				}
+				};
 				request.append(dojox.xmpp.util.createElement('text',textAttr,false));
 				request.append(text).append("</text>");
 			}
diff --git a/util/.gitmodules b/util/.gitmodules
new file mode 100644
index 0000000..19a6fb9
--- /dev/null
+++ b/util/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "less"]
+	path = less
+	url = git://github.com/cloudhead/less.js.git
diff --git a/util/LICENSE b/util/LICENSE
index aa6b39f..b1ddd34 100644
--- a/util/LICENSE
+++ b/util/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2011, The Dojo Foundation
+Copyright (c) 2005-2013, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/util/build/argv.js b/util/build/argv.js
index cd21ebe..c6589af 100644
--- a/util/build/argv.js
+++ b/util/build/argv.js
@@ -1,6 +1,6 @@
 define([
 	"require",
-	"dojo",
+	"dojo/json",
 	"dojo/has",
 	"./fs",
 	"./fileUtils",
@@ -11,7 +11,7 @@ define([
 	"./messages",
 	"./v1xProfiles",
 	"dojo/text!./help.txt"
-], 	function(require, dojo, has, fs, fileUtils, process, argv, stringify, version, messages, v1xProfiles, help){
+], function(require, json, has, fs, fileUtils, process, argv, stringify, version, messages, v1xProfiles, help){
 	///
 	// AMD-ID build/argv
 	//
@@ -60,7 +60,7 @@ define([
 				}else if(arg=="null"){
 					return null;
 				}else if(isNaN(arg)){
-					return dojo.fromJson("{\"result\":\"" + arg + "\"}").result;
+					return arg+"";
 				}else{
 					return Number(arg);
 				}
@@ -151,7 +151,6 @@ define([
 				},
 				f, profile;
 			try{
-				src = fs.readFileSync(filename, "utf8");
 				if(scriptType=="require"){
 					f = new Function("var __result, require= function(config){__result=config;};" + src + "; return __result || require;");
 					profile = f();
@@ -163,7 +162,7 @@ define([
 				}else if(scriptType=="profile"){
 					f = new Function("selfPath", "logger", "profile", "dependencies",
 									 src + "; return {profile:profile, dependencies:dependencies}");
-					profile = f(path, messages, 0, 0, 0);
+					profile = f(path, messages, 0, 0);
 					if(profile.profile){
 						profile = profile.profile;
 						fixupBasePath(profile);
@@ -222,7 +221,7 @@ define([
 				messages.log(missingMessageId, ["filename", filename]);
 			}else{
 				try{
-					var result = dojo.fromJson(fs.readFileSync(filename, "utf8"));
+					var result = json.parse(fs.readFileSync(filename, "utf8"));
 					result.selfFilename = filename;
 					return result;
 				}catch(e){
@@ -402,15 +401,19 @@ define([
 			default:
 				// possible formats
 				//
-				//   -switch value
-				//   --switch value
-				//   switch=value
+				//	 -switch value
+				//	 --switch value
+				//	 switch=value
 
 				var match = arg.match(/^\-\-?(.+)/);
 				if(match && i<end){
 					// all of the switches that take no values are listed above; therefore,
 					// *must* provide a value
-					result[match[1]] = evalScriptArg(argv[i++]);
+					if(i<=end){
+						result[match[1]] = evalScriptArg(argv[i++]);
+					}else{
+						illegalArgumentValue(arg, i);
+					}
 				}else{
 					// the form switch=value does *not* provide an individual value arg (it's all one string)
 					var parts = arg.split("=");
@@ -549,7 +552,7 @@ define([
 		}
 		result.unitTestParam = testId;
 		var expectedFilename = compactPath(utilBuildscriptsPath + "/../build/tests/argvTestsExpected.js"),
-			expected = dojo.fromJson(fs.readFileSync(expectedFilename, "utf8")),
+			expected = json.parse(fs.readFileSync(expectedFilename, "utf8")),
 			pathNormalize = utilBuildscriptsPath.match(/(.*)\/util\/buildscripts/)[1],
 			testResult = stringify(result).replace(RegExp(pathNormalize, "g"), "~"),
 			passed = 1;
@@ -559,7 +562,7 @@ define([
 			console.log("result:");
 			debug(testResult);
 			expected[result.unitTestParam] = testResult;
-			fs.writeFileSync(expectedFilename, dojo.toJson(expected), "utf8");
+			fs.writeFileSync(expectedFilename, json.stringify(expected), "utf8");
 		}else{
 			passed = testResult==expected[result.unitTestParam];
 			console.log(result.unitTestParam + ":" + (passed ? "PASSED" : "FAILED"));
diff --git a/util/build/buildControl.js b/util/build/buildControl.js
index 45c5e63..bafd5ed 100644
--- a/util/build/buildControl.js
+++ b/util/build/buildControl.js
@@ -10,7 +10,7 @@ define([
 	"./process",
 	"./messages",
 	"dojo/text!./help.txt"
-], function(require, lang, argv, fs, fileUtils, bc, v1xProfiles, stringify, process, messages, helpText) {
+], function(require, lang, argv, fs, fileUtils, bc, v1xProfiles, stringify, process, messages, helpText){
 	//
 	// Process the arguments given on the command line to build up a profile object that is used to instruct and control
 	// the build process.
@@ -28,67 +28,82 @@ define([
 
 	eval(require.scopeify("./fs, ./fileUtils, ./v1xProfiles"));
 	var
-		isString= function(it) {
+		isString = function(it){
 			return typeof it === "string";
 		},
 
-		isNonemptyString= function(it){
+		isNonemptyString = function(it){
 			return isString(it) && it.length;
 		},
 
-		isDefined= function(it){
+		isDefined = function(it){
 			return typeof it !="undefined";
 		},
 
-		cleanupFilenamePair= function(item, srcBasePath, destBasePath, hint) {
+		cleanupFilenamePair = function(item, srcBasePath, destBasePath, hint){
 			var result;
-			if (isString(item)) {
-				result= [computePath(item, srcBasePath), computePath(item, destBasePath)];
-			} else {
-				result= [computePath(item[0], srcBasePath), computePath(item[1], destBasePath)].concat(item.slice(2));
+			if(isString(item)){
+				result = [computePath(item, srcBasePath), computePath(item, destBasePath)];
+			}else{
+				result = [computePath(item[0], srcBasePath), computePath(item[1], destBasePath)].concat(item.slice(2));
 			}
-			if (!isAbsolutePath(result[0]) || !isAbsolutePath(result[1])) {
+			if(!isAbsolutePath(result[0]) || !isAbsolutePath(result[1])){
 				bc.log("inputInvalidPath", ["path", item, "hint", hint]);
 			}
 			return result;
 		},
 
-		slashTerminate= function(path){
+		slashTerminate = function(path){
 			return path + /\/$/.test(path) ? "" : "/";
 		},
 
-		isEmpty= function(it) {
-			for (var p in it) return false;
+		isEmpty = function(it){
+			for(var p in it) return false;
 			return true;
 		},
 
-		mix= function(dest, src) {
-			dest= dest || {};
-			src= src || {};
-			for (var p in src) dest[p]= src[p];
+		cleanDeprecated = function(o, inputFile){
+			var deprecated = [];
+			for(p in o){
+				if(/^(log|loader|xdDojoPath|scopeDjConfig|xdScopeArgs|xdDojoScopeName|expandProvide|buildLayers|query|removeDefaultNameSpaces|addGuards)$/.test(p)){
+					deprecated.push(p);
+					bc.log("inputDeprecated", ["switch", p, inputFile]);
+				}
+			}
+			deprecated.forEach(function(p){
+				delete o[p];
+			});
+		},
+
+		mix = function(dest, src){
+			dest = dest || {};
+			src = src || {};
+			for(var p in src) dest[p] = src[p];
 			return dest;
 		},
 
-		mixPackage= function(packageInfo) {
-			var name= packageInfo.name;
-			bc.packageMap[name]= mix(bc.packageMap[name], packageInfo);
+		mixPackage = function(packageInfo){
+			var name = packageInfo.name;
+			bc.packageMap[name] = mix(bc.packageMap[name], packageInfo);
 		},
 
 		// mix a profile object into the global profile object
-		mixProfileObject= function(src) {
+		mixProfileObject = function(src){
+			cleanDeprecated(src, src.selfFilename);
+
 			// the profile properties...
 			//	 paths, plugins, transforms, staticHasFeatures
 			// ...are mixed one level deep; messageCategories, messages, packages, and packagePaths require special handling; all others are over-written
 			// FIXME: the only way to modify the transformJobs vector is to create a whole new vector?
-			for (var p in src) {
-				if (!/paths|plugins|messages|transforms|staticHasFeatures|packages|packagePaths|defaultConfig/.test(p)) {
-					bc[p]= src[p];
+			for(var p in src){
+				if(!/paths|plugins|messages|transforms|staticHasFeatures|packages|packagePaths|defaultConfig/.test(p)){
+					bc[p] = src[p];
 				}
 			}
 
 			// the one-level-deep mixers
-			["paths","plugins","transforms","staticHasFeatures"].forEach(function(p) {
-				bc[p]= mix(bc[p], src[p]);
+			["paths","plugins","transforms","staticHasFeatures"].forEach(function(p){
+				bc[p] = mix(bc[p], src[p]);
 			});
 
 			// messages require special handling
@@ -99,23 +114,22 @@ define([
 			}
 			(src.messages || []).forEach(function(item){bc.addMessage.apply(bc, item);});
 
-
 			// packagePaths and packages require special processing to get their contents into packageMap; do that first...
 			// process packagePaths before packages before packageMap since packagePaths is less specific than
 			// packages is less specific than packageMap. Notice that attempts to edit an already-existing package
 			// only edits specific package properties given (see mixPackage, above)
-			for (var base in src.packagePaths) {
-				src.packagePaths[base].forEach(function(packageInfo) {
-					if (isString(packageInfo)) {
-						packageInfo= {name:packageInfo};
+			for(var base in src.packagePaths){
+				src.packagePaths[base].forEach(function(packageInfo){
+					if(isString(packageInfo)){
+						packageInfo = {name:packageInfo};
 					}
-					packageInfo.location= catPath(base, packageInfo.name);
+					packageInfo.location = catPath(base, packageInfo.name);
 					mixPackage(packageInfo);
 				});
 			};
-			(src.packages || []).forEach(function(packageInfo) {
-					if (isString(packageInfo)) {
-						packageInfo= {name:packageInfo};
+			(src.packages || []).forEach(function(packageInfo){
+					if(isString(packageInfo)){
+						packageInfo = {name:packageInfo};
 					}
 					mixPackage(packageInfo);
 			});
@@ -125,28 +139,30 @@ define([
 				if(p=="hasCache"){
 					mix(bc.defaultConfig.hasCache, src.defaultConfig.hasCache);
 				}else{
-					bc.defaultConfig[p]= src.defaultConfig[p];
+					bc.defaultConfig[p] = src.defaultConfig[p];
 				}
 			}
 		};
 
-	argv.args.profiles.forEach(function(item) {
-		var temp= mix({}, item),
-			build= item.build;
+	argv.args.profiles.forEach(function(item){
+		var temp = mix({}, item),
+			build = item.build;
 		delete temp.build;
 		mixProfileObject(temp);
 		build && mixProfileObject(build);
 	});
 
+	cleanDeprecated(argv.args, "command line");
+
 	// lastly, explicit command line switches override any evaluated profile objects
-	for (var argName in argv.args) if (argName!="profiles") {
-		bc[argName]= argv.args[argName];
+	for(var argName in argv.args) if(argName!="profiles"){
+		bc[argName] = argv.args[argName];
 	}
 
 	// at this point the raw profile object has been fully initialized; clean it up and look for errors...
-	bc.basePath= computePath(bc.basePath, process.cwd());
+	bc.basePath = computePath(bc.basePath, process.cwd());
 	var releaseDir = catPath(bc.releaseDir || "../release", bc.releaseName || "");
-	bc.destBasePath= computePath(releaseDir, bc.basePath);
+	bc.destBasePath = computePath(releaseDir, bc.basePath);
 
 	// compute global copyright, if any
 	bc.copyright = isNonemptyString(bc.copyright) ? (maybeRead(computePath(bc.copyright, bc.basePath)) || bc.copyright) : "";
@@ -154,10 +170,10 @@ define([
 	bc.copyrightNonlayers = !!bc.copyrightNonlayers;
 
 	// compute files, dirs, and trees
-	(function () {
-		for (var property in {files:1, dirs:1, trees:1}) {
+	(function(){
+		for(var property in {files:1, dirs:1, trees:1}){
 			if(bc[property] instanceof Array){
-				bc[property]= bc[property].map(function(item) {
+				bc[property] = bc[property].map(function(item){
 					return cleanupFilenamePair(item, bc.basePath, bc.destBasePath, property);
 				});
 			}
@@ -165,12 +181,12 @@ define([
 	})();
 
 	// cleanup the replacements (if any)
-	(function() {
-		var cleanSet= {}, src, dest;
-		for (src in bc.replacements) {
-			cleanSet[computePath(src, bc.basePath)]= bc.replacements[src];
+	(function(){
+		var cleanSet = {}, src, dest;
+		for(src in bc.replacements){
+			cleanSet[computePath(src, bc.basePath)] = bc.replacements[src];
 		}
-		bc.replacements= cleanSet;
+		bc.replacements = cleanSet;
 	})();
 
 	// explicit mini and/or copyTests wins; explicit copyTests ignores explicit mini
@@ -188,19 +204,31 @@ define([
 		bc.copyTests = !!bc.copyTests;
 	}
 
+	function getDiscreteLocales(locale){
+		for(var locales = locale.split("-"), result = [], current = "", i = 0; i<locales.length; i++){
+			result.push(current += (i ? "-" : "") + locales[i]);
+		}
+		return result;
+	}
 	if(isString(bc.localeList)){
 		bc.localeList = bc.localeList.split(",");
 	}
-	bc.localeList = bc.localeList ? bc.localeList.map(lang.trim) : [];
+	if(bc.localeList && bc.localeList.length){
+		if(bc.localeList.indexOf("ROOT")==-1){
+			bc.localeList.push("ROOT");
+		}
+		var localeList = {};
+		bc.localeList.forEach(function(locale){
+			locale = lang.trim(locale);
+			localeList[locale] = getDiscreteLocales(locale);
+		});
+		bc.localeList.discreteLocales = localeList;
+	}else{
+		bc.localeList = false;
+	}
 
-	// clean up bc.packageMap and bc.paths so they can be used just as in dojo loader/bdLoad
-	(function() {
-		// so far, we've been using bc.packageMap to accumulate package info as it is provided by packagePaths and/or packages
-		// in zero to many profile scripts. This routine moves each package config into bc.packages which is a map
-		// from package name to package config (this is different from the array the user uses to pass package config info). Along
-		// the way, each package config object is cleaned up and all default values are calculated. Finally, the
-		// global packageMap (a map from package name to package name) is computed.
 
+	(function(){
 		function processPackage(pack){
 			var packName = pack.name,
 				basePath = pack.basePath || bc.basePath;
@@ -225,20 +253,22 @@ define([
 				}
 				if("dojoBuild" in packageJson){
 					var defaultProfile = argv.readProfile("profile", catPath(getFilepath(packageJson.selfFilename), packageJson.dojoBuild));
-					for (var p in defaultProfile) {
-						if (!(p in pack)) {
-							pack[p]= defaultProfile[p];
+					for(var p in defaultProfile){
+						if(!(p in pack)){
+							pack[p] = defaultProfile[p];
 						}else if(p in {resourceTags:1}){
 							// these are mixed one level deep
 							// TODO: review all profile properties and see if there are any others than resourceTags that ought to go here
 							mix(pack[p], defaultProfile[p]);
 						}
 					}
+				}else{
+					bc.log("missingProfile", ["package", packageJson.name]);
 				}
 			}
 
 			// build up info to tell all about a package; all properties semantically identical to definitions used by dojo loader/bdLoad
-			pack.main= isString(pack.main) ? pack.main : "main";
+			pack.main = isString(pack.main) ? pack.main : "main";
 			if(pack.main.indexOf("./")==0){
 				pack.main = pack.main.substring(2);
 			}
@@ -246,9 +276,7 @@ define([
 				pack.destMain = pack.destMain.substring(2);
 			}
 
-			pack.location= computePath(pack.location || ("./" + packName), basePath);
-			pack.packageMap= pack.packageMap || 0;
-			require.computeMapProg(pack.packageMap, (pack.mapProg= []));
+			pack.location = computePath(pack.location || ("./" + packName), basePath);
 
 			pack.copyright = isNonemptyString(pack.copyright) ?
 				(maybeRead(computePath(pack.copyright, pack.location)) || maybeRead(computePath(pack.copyright, bc.basePath)) || pack.copyright) :
@@ -257,40 +285,38 @@ define([
 			pack.copyrightNonlayers = isDefined(pack.copyrightNonlayers) ? !!pack.copyrightNonlayers : bc.copyrightNonlayers;
 
 			// dest says where to output the compiled code stack
-			var destPack= bc.destPackages[packName]= {
+			var destPack = bc.destPackages[packName] = {
 				name:pack.destName || packName,
 				main:pack.destMain || pack.main,
-				location:computePath(pack.destLocation || ("./" + (pack.destName || packName)), bc.destBasePath),
-				packageMap:pack.destPackageMap || pack.packageMap
+				location:computePath(pack.destLocation || ("./" + (pack.destName || packName)), bc.destBasePath)
 			};
-			require.computeMapProg(pack.destPackageMap, (destPack.mapProg= []));
 			delete pack.destName;
 			delete pack.destMain;
 			delete pack.destLocation;
-			delete pack.destPackageMap;
 
 
-			if (!pack.trees) {
+			if(!pack.trees){
 				// copy the package tree; don't copy any hidden directorys (e.g., .git, .svn) or temp files
-				pack.trees= [[pack.location, destPack.location, /(\/\.)|(~$)/]];
+				pack.trees = [[pack.location, destPack.location, /(\/\.)|(^\.)|(~$)/]];
 			} // else the user has provided explicit copy instructions
 
 			// filenames, dirs, trees just like global, except relative to the pack.(src|dest)Location
-			for (var property in {files:1, dirs:1, trees:1}) {
-				pack[property]= (pack[property] || []).map(function(item) {
+			for(var property in {files:1, dirs:1, trees:1}){
+				pack[property] = (pack[property] || []).map(function(item){
 					return cleanupFilenamePair(item, pack.location, destPack.location, property + " in package " + packName);
 				});
 			}
-			bc.packageMap[packName]= packName;
-			bc.destPackageMap[destPack.name]= destPack.name;
 		}
 
-		bc.packages= bc.packageMap;
-		bc.destPackages= {};
-		bc.packageMap= {};
-		bc.destPackageMap= {};
-		for (var packageName in bc.packages) {
-			var pack= bc.packages[packageName];
+		// so far, we've been using bc.packageMap to accumulate package info as it is provided by packagePaths and/or packages
+		// in zero to many profile scripts. This routine moves each package config into bc.packages which is a map
+		// from package name to package config (this is different from the array the user uses to pass package config info). Along
+		// the way, each package config object is cleaned up and all default values are calculated.
+		bc.packages = bc.packageMap;
+		delete bc.packageMap;
+		bc.destPackages = {};
+		for(var packageName in bc.packages){
+			var pack = bc.packages[packageName];
 			pack.name = pack.name || packageName;
 			processPackage(pack);
 		}
@@ -305,44 +331,46 @@ define([
 			processPackage(bc.packages.doh);
 		}
 
-		// now that bc.packageMap is initialized...
-		require.computeMapProg(bc.packageMap, (bc.packageMapProg= []));
-		require.computeMapProg(bc.destPackageMap, (bc.destPackageMapProg= []));
-
 		// get this done too...
-		require.computeMapProg(bc.paths, (bc.pathsMapProg= []));
-		require.computeMapProg(bc.destPaths || bc.paths, (bc.destPathsMapProg= []));
+		require.computeAliases(bc.aliases, (bc.aliasesMap = []));
+		require.computeMapProg(bc.paths, (bc.pathsMapProg = []));
 
 		// add some methods to bc to help with resolving AMD module info
-		bc.srcModules= {};
-		bc.destModules= {};
+		bc.srcModules = {};
+		bc.destModules = {};
 
-		var trimLastChars= function(text, n){
+		var trimLastChars = function(text, n){
 			return text.substring(0, text.length-n);
 		};
 
-		bc.getSrcModuleInfo= function(mid, referenceModule, ignoreFileType) {
+		bc.getSrcModuleInfo = function(mid, referenceModule, ignoreFileType){
+			// notice that aliases and paths are applied, but map is not (and never will be)
 			if(ignoreFileType){
-				var result= require.getModuleInfo(mid+"/x", referenceModule, bc.packages, bc.srcModules, bc.basePath + "/", bc.packageMapProg, bc.pathsMapProg, true);
-				// trim /x.js
-				result.mid= trimLastChars(result.mid, 2);
-				result.url= trimLastChars(result.url, 5);
+				var result = require.getModuleInfo(mid+"/x", referenceModule, bc.packages, bc.srcModules, bc.basePath + "/", [], bc.pathsMapProg, bc.aliasesMap, true);
+				result.mid = trimLastChars(result.mid, 2);
+				if(result.pid!==0){
+					// trim /x.js
+					result.url = trimLastChars(result.url, 5);
+				}
 				return result;
 			}else{
-				return require.getModuleInfo(mid, referenceModule, bc.packages, bc.srcModules, bc.basePath + "/", bc.packageMapProg, bc.pathsMapProg, true);
+				return require.getModuleInfo(mid, referenceModule, bc.packages, bc.srcModules, bc.basePath + "/", [], bc.pathsMapProg, bc.aliasesMap, true);
 			}
 		};
 
-		bc.getDestModuleInfo= function(mid, referenceModule, ignoreFileType) {
-			// note: bd.destPagePath should never be required; but it's included for completeness and up to the user to provide it if some transform does decide to use it
+
+		bc.getDestModuleInfo = function(mid, referenceModule, ignoreFileType){
+			// notice no mapping, paths, aliases in the dest getModuleInfo....just send stuff to where it should go without manipulation
 			if(ignoreFileType){
-				var result= require.getModuleInfo(mid+"/x", referenceModule, bc.destPackages, bc.destModules, bc.destBasePath + "/", bc.destPackageMapProg, bc.destPathsMapProg, true);
-				// trim /x.js
-				result.mid= trimLastChars(result.mid, 2);
-				result.url= trimLastChars(result.url, 5);
+				var result = require.getModuleInfo(mid+"/x", referenceModule, bc.destPackages, bc.destModules, bc.destBasePath + "/", [], [], [], true);
+				result.mid = trimLastChars(result.mid, 2);
+				if(result.pid!==0){
+					// trim /x.js
+					result.url = trimLastChars(result.url, 5);
+				}
 				return result;
 			}else{
-				return require.getModuleInfo(mid, referenceModule, bc.destPackages, bc.destModules, bc.destBasePath + "/", bc.destPackageMapProg, bc.destPathsMapProg, true);
+				return require.getModuleInfo(mid, referenceModule, bc.destPackages, bc.destModules, bc.destBasePath + "/", [], [], [], true);
 			}
 		};
 	})();
@@ -352,18 +380,18 @@ define([
 		bc.defaultConfig.hasCache["config-selectorEngine"] = bc.selectorEngine;
 	}
 
-	(function() {
+	(function(){
 		// a layer is a module that should be written with all of its dependencies, as well as all modules given in
 		// the include vector together with their dependencies, excluding modules contained in the exclude vector and their dependencies
-		var layer, fixedLayers= {};
-		for (var mid in bc.layers) {
-			layer= bc.layers[mid];
-			layer.exclude= layer.exclude || [];
-			layer.include= layer.include || [];
+		var layer, fixedLayers = {};
+		for(var mid in bc.layers){
+			layer = bc.layers[mid];
+			layer.exclude = layer.exclude || [];
+			layer.include = layer.include || [];
 			layer.boot = !!layer.boot;
 			layer.discard = !!layer.discard;
-			layer.noref = !!(layer.noref!==undefined ? layer.noref : bc.noref);
 			layer.compat = layer.compat!==undefined ? layer.compat : (bc.layerCompat ||"");
+			layer.noref = !!(layer.noref!==undefined ? layer.noref : (layer.compat=="1.6" ? true : bc.noref));
 
 			var tlm = mid.split("/")[0],
 				pack = bc.packages[tlm],
@@ -382,9 +410,9 @@ define([
 			if(!layer.copyright){
 				layer.copyright = "";
 			}
-			fixedLayers[mid]= layer;
+			fixedLayers[mid] = layer;
 		}
-		bc.layers= fixedLayers;
+		bc.layers = fixedLayers;
 
 		// if (and only if) we're doing a build that includes the dojo tree, then ensure the loader layer is defined correctly
 		// and make sure all other layers exclude the loader unless they are marked with custome base
@@ -413,28 +441,27 @@ define([
 				}
 			}
 		}
-
 	})();
 
 
 	// for the static has flags, -1 means its not static; this gives a way of combining several static has flag sets
 	// and still allows later sets to delete flags set in earlier sets
-	var deleteStaticHasFlagSet= [];
-	for (var p in bc.staticHasFeatures) if (bc.staticHasFeatures[p]==-1) deleteStaticHasFlagSet.push(p);
+	var deleteStaticHasFlagSet = [];
+	for(var p in bc.staticHasFeatures) if(bc.staticHasFeatures[p]==-1) deleteStaticHasFlagSet.push(p);
 	deleteStaticHasFlagSet.forEach(function(flag){delete bc.staticHasFeatures[flag];});
 
 	if(bc.action){
 		bc.action.split(/\W|\s/).forEach(function(action){
-			action= action.match(/\s*(\S+)\s*/)[1];
+			action = action.match(/\s*(\S+)\s*/)[1];
 			switch(action){
 				case "check":
-					bc.check= true;
+					bc.check = true;
 					break;
 				case "clean":
-					bc.clean= true;
+					bc.clean = true;
 					break;
 				case "release":
-					bc.release= true;
+					bc.release = true;
 					break;
 				default:
 					bc.log("inputUnknownAction", ["action", action]);
@@ -447,25 +474,25 @@ define([
 	}
 
 	// understand stripConsole from dojo 1.3 and before
-	var stripConsole= bc.stripConsole;
-	if (!stripConsole || stripConsole=="none") {
-		stripConsole= false;
-	} else if (stripConsole == "normal,warn") {
+	var stripConsole = bc.stripConsole;
+	if(!stripConsole || stripConsole=="none"){
+		stripConsole = false;
+	}else if(stripConsole == "normal,warn"){
 		bc.log("inputDeprecatedStripConsole", ["deprecated", "normal,warn", "use", "warn"]);
 		stripConsole = "warn";
-	} else if (stripConsole == "normal,error") {
+	}else if(stripConsole == "normal,error"){
 		bc.log("inputDeprecatedStripConsole", ["deprecated", "normal,error", "use", "all"]);
 		stripConsole = "all";
-	} else if (!/normal|warn|all|none/.test(stripConsole)){
+	}else if(!/normal|warn|all|none/.test(stripConsole)){
 		bc.log("inputUnknownStripConsole", ["value", stripConsole]);
 	}
-	bc.stripConsole= stripConsole;
+	bc.stripConsole = stripConsole;
 
 	function fixupOptimize(value){
 		if(value){
-			value= value + "";
-			value= value.toLowerCase();
-			if(!/^(comments|shrinksafe(\.keeplines)?|closure(\.keeplines)?)$/.test(value)){
+			value = value + "";
+			value = value.toLowerCase();
+			if(!/^(((comments|shrinksafe)(\.keeplines)?)|(closure(\.keeplines)?|uglify(\.keeplines)?))$/.test(value)){
 				bc.log("inputUnknownOptimize", ["value", value]);
 				value = 0;
 			}else{
@@ -482,7 +509,11 @@ define([
 	(function(){
 		var fixedScopeMap = {dojo:"dojo", dijit:"dijit", dojox:"dojox"};
 		(bc.scopeMap || []).forEach(function(pair){
-			fixedScopeMap[pair[0]] = pair[1];
+			if(!pair[1]){
+				delete fixedScopeMap[pair[0]];
+			}else{
+				fixedScopeMap[pair[0]] = pair[1];
+			}
 		});
 		bc.scopeMap = fixedScopeMap;
 
@@ -492,58 +523,56 @@ define([
 		}
 	})();
 
-	var fixedInternStringsSkipList = {};
-	(bc.internSkipList || bc.internStringsSkipList || []).forEach(function(mid){
-		if(/.*\..*\./.test(mid)){
-			bc.log("possibleLegacyModuleId", ["name", mid]);
-		}
-		fixedInternStringsSkipList[mid] = 1;
-	});
-	bc.internStringsSkipList = fixedInternStringsSkipList;
-
-	var deprecated= [];
-	for(p in bc){
-		if(/^(loader|xdDojoPath|scopeDjConfig|xdScopeArgs|xdDojoScopeName|expandProvide|buildLayers|query|removeDefaultNameSpaces|addGuards)$/.test(p)){
-			deprecated.push(p);
-			bc.log("inputDeprecated", ["switch", p]);
-		}
+	bc.internSkip = function(){return false;};
+	if(bc.internSkipList){
+		bc.internSkip = function(mid, referenceModule){
+			return bc.internSkipList.some(function(item){
+				var result = false;
+				if(item instanceof RegExp){
+					result = item.test(mid);
+				}else if(item instanceof Function){
+					result = item(mid, referenceModule);
+				}else{
+					result = item==mid;
+				}
+				if(result){
+					bc.log("internStrings", ["module", referenceModule.mid, "skipping", mid]);
+				}
+				return result;
+			});
+		};
 	}
-	deprecated.forEach(function(p){
-		delete bc[p];
-	});
 
 	// dump bc (if requested) before changing gate names to gate ids below
 	if(bc.check){
-		(function() {
+		(function(){
 			var toDump = {
+				aliases:1,
 				basePath:1,
-				buildFlags:1,
 				buildReportDir:1,
 				buildReportFilename:1,
 				closureCompilerPath:1,
-				compactCssSet:1,
 				copyright:1,
 				copyrightLayers:1,
 				copyrightNonlayers:1,
 				copyTests:1,
 				destBasePath:1,
 				destModules:1,
-				destPackageMap:1,
-				destPackageMapProg:1,
 				destPackages:1,
 				destPathTransforms:1,
-				destPathsMapProg:1,
 				dirs:1,
 				discoveryProcs:1,
 				files:1,
+				insertAbsMids:1,
 				internStringsSkipList:1,
 				layers:1,
 				localeList:1,
+				includeLocales: 1,
 				maxOptimizationProcesses:1,
 				mini:1,
+				optimize:1,
+				layerOptimize:1,
 				"package":1,
-				packageMap:1,
-				packageMapProg:1,
 				packages:1,
 				paths:1,
 				pathsMapProg:1,
@@ -563,7 +592,8 @@ define([
 	}
 
 	if(bc.writeProfile){
-
+		// TODO
+		// fs.writeFileSync(bc.writeProfile, "dependencies = " + dojo.toJson(profileProperties, true), "utf8");
 	}
 
 	if(bc.debugCheck){
@@ -589,64 +619,64 @@ define([
 	}
 
 	// clean up the gates and transforms
-	(function() {
+	(function(){
 		// check that each transform references a valid gate
-		for (var gates= {}, i= 0; i<bc.gates.length; i++) {
-			gates[bc.gates[i][1]]= i;
+		for(var gates = {}, i = 0; i<bc.gates.length; i++){
+			gates[bc.gates[i][1]] = i;
 		}
 		var
-			transforms= bc.transforms,
+			transforms = bc.transforms,
 			gateId;
-		for (var transformId in transforms) {
+		for(var transformId in transforms){
 			// each item is a [AMD-MID, gateName] pair
-			gateId= gates[transforms[transformId][1]];
-			if (typeof gateId == "undefined") {
+			gateId = gates[transforms[transformId][1]];
+			if(typeof gateId == "undefined"){
 				bc.log("inputUnknownGate", ["transform", transformId, "gate", transforms[transformId][1]]);
-			} else {
-				transforms[transformId][1]= gateId;
+			}else{
+				transforms[transformId][1] = gateId;
 			}
 		}
 	})();
 
 	// clean up the transformJobs
-	(function() {
+	(function(){
 		// check that that each transformId referenced in transformJobs references an existing item in transforms
 		// ensure proper gate order of the transforms given in transformJobs; do not disturb order within a given
 		// gate--this is the purview of the user
-		var transforms= bc.transforms;
-		bc.transformJobs.forEach(function(item) {
+		var transforms = bc.transforms;
+		bc.transformJobs.forEach(function(item){
 			// item is a [predicate, vector of transformId] pairs
-			var error= false;
-			var tlist= item[1].map(function(id) {
+			var error = false;
+			var tlist = item[1].map(function(id){
 				// item is a transformId
-				if (transforms[id]) {
+				if(transforms[id]){
 					// return a [trandformId, gateId] pair
 					return [id, transforms[id][1]];
-				} else {
-					error= true;
+				}else{
+					error = true;
 					bc.log("inputUnknownTransform", ["transform", id]);
 					return 0;
 				}
 			});
 			// tlist is a vector of [transformId, gateId] pairs than need to be checked for order
-			if (!error) {
-				for (var i= 0, end= tlist.length - 1; i<end;) {
-					if (tlist[i][1]>tlist[i+1][1]) {
-						var t= tlist[i];
-						tlist[i]= tlist[i+1];
-						tlist[i+1]= t;
+			if(!error){
+				for(var i = 0, end = tlist.length - 1; i<end;){
+					if(tlist[i][1]>tlist[i+1][1]){
+						var t = tlist[i];
+						tlist[i] = tlist[i+1];
+						tlist[i+1] = t;
 						i && i--;
-					} else {
+					}else{
 						i++;
 					}
 				}
 				// now replace the vector of transformIds with the sorted list
-				item[1]= tlist;
+				item[1] = tlist;
 			}
 		});
 	})();
 
-	if (argv.args.unitTest=="dumpbc") {
+	if(argv.args.unitTest=="dumpbc"){
 		console.log(stringify(bc) + "\n");
 	}
 
diff --git a/util/build/buildControlBase.js b/util/build/buildControlBase.js
index 5053739..bb48fa3 100644
--- a/util/build/buildControlBase.js
+++ b/util/build/buildControlBase.js
@@ -1,13 +1,13 @@
 define([
-	"dojo",
 	"./messages",
 	"dojo/text!./copyright.txt",
 	"dojo/text!./buildNotice.txt"
-], function(dojo, messages, defaultCopyright, defaultBuildNotice) {
-	var bc= {
+], function(messages, defaultCopyright, defaultBuildNotice){
+	var bc = {
+		// 0 => no errors
+		// 1 => messages.getErrorCount()>0 at exist
 		exitCode:0,
 
-
 		// use this variable for all newlines inserted by build transforms
 		newline:"\n",
 
@@ -15,8 +15,8 @@ define([
 		// however they desire. For example,
 		//
 		// newlineFilter: function(s){
-		//   // convert all DOS-style newlines to Unix-style newlines
-		//   return s.replace(/\r\n/g, "\n").replace(/\n\r/g, "\n");
+		//	 // convert all DOS-style newlines to Unix-style newlines
+		//	 return s.replace(/\r\n/g, "\n").replace(/\n\r/g, "\n");
 		// }
 		//
 		newlineFilter:function(s, resource, hint){return s;},
diff --git a/util/build/buildControlDefault.js b/util/build/buildControlDefault.js
index 83fad71..5fce434 100644
--- a/util/build/buildControlDefault.js
+++ b/util/build/buildControlDefault.js
@@ -1,5 +1,7 @@
-define(["./buildControlBase"], function(bc) {
-	var defaultBc= {
+define([
+	"./buildControlBase"
+], function(bc){
+	var defaultBc = {
 		// v1.6- default values
 		internStrings:true,
 		internSkipList:[],
@@ -11,7 +13,7 @@ define(["./buildControlBase"], function(bc) {
 		scopeMap:[],
 		insertAbsMids:1,
 		applyDojoPragmas:1,
-		localeList:"ar,ca,cs,da,de-de,el,en-gb,en-us,es-es,fi-fi,fr-fr,he-il,hu,it-it,ja-jp,ko-kr,nl-nl,nb,pl,pt-br,pt-pt,ru,sk,sl,sv,th,tr,zh-tw,zh-cn".split(","),
+		localeList:"ar,ca,cs,da,de,el,en-gb,en-us,es-es,fi-fi,fr-fr,he-il,hu,it-it,ja-jp,ko-kr,nl-nl,nb,pl,pt-br,pt-pt,ru,sk,sl,sv,th,tr,zh-tw,zh-cn".split(","),
 
 
 		// this is a dojo pragma
@@ -67,17 +69,14 @@ define(["./buildControlBase"], function(bc) {
 			'dojo-undef-api':0,
 			'dojo-v1x-i18n-Api':1,
 			'dojo-xhr-factory':1,
+			"dojo-fast-sync-require":1,
+			'config-deferredInstrumentation':1,
 			'dom':1,
 			'host-browser':1,
 			'host-node':0,
 			'host-rhino':0
 		},
 
-		buildFlags:{
-			stripConsole:"error",
-			optimizeHas:1
-		},
-
 		discoveryProcs:["build/discover"],
 
 		plugins:{
@@ -107,54 +106,55 @@ define(["./buildControlBase"], function(bc) {
 		transformConfig: {},
 
 		transforms:{
-			trace:          ["build/transforms/trace", "read"],
-			read:           ["build/transforms/read", "read"],
-			dojoPragmas:    ["build/transforms/dojoPragmas", "read"],
-			insertSymbols:  ["build/transforms/insertSymbols", "read"],
-			depsScan:       ["build/transforms/depsScan", "ast"],
-			hasFixup:       ["build/transforms/hasFixup", "ast"],
-			write:          ["build/transforms/write", "write"],
-			writeAmd:       ["build/transforms/writeAmd", "write"],
-			writeOptimized: ["build/transforms/writeOptimized", "write"],
-			copy:           ["build/transforms/copy", "write"],
-			writeDojo:      ["build/transforms/writeDojo", "write"],
-			optimizeCss:    ["build/transforms/optimizeCss", "optimize"],
-			writeCss:       ["build/transforms/writeCss", "write"],
-			hasFindAll:     ["build/transforms/hasFindAll", "read"],
-			hasReport:      ["build/transforms/hasReport", "cleanup"],
-			depsDump:       ["build/transforms/depsDump", "cleanup"],
-			dojoReport:     ["build/transforms/dojoReport", "report"],
-			report:         ["build/transforms/report", "report"]
+			trace:				["build/transforms/trace", "read"],
+			read:				["build/transforms/read", "read"],
+			dojoPragmas:		["build/transforms/dojoPragmas", "read"],
+			insertSymbols:		["build/transforms/insertSymbols", "read"],
+			depsDeclarative:	["build/transforms/depsDeclarative", "read"],
+			depsScan:			["build/transforms/depsScan", "ast"],
+			hasFixup:			["build/transforms/hasFixup", "ast"],
+			write:				["build/transforms/write", "write"],
+			writeAmd:			["build/transforms/writeAmd", "write"],
+			writeOptimized: 	["build/transforms/writeOptimized", "write"],
+			copy:				["build/transforms/copy", "write"],
+			writeDojo:			["build/transforms/writeDojo", "write"],
+			optimizeCss:		["build/transforms/optimizeCss", "optimize"],
+			writeCss:			["build/transforms/writeCss", "write"],
+			hasFindAll:			["build/transforms/hasFindAll", "read"],
+			hasReport:			["build/transforms/hasReport", "cleanup"],
+			depsDump:			["build/transforms/depsDump", "cleanup"],
+			dojoReport:			["build/transforms/dojoReport", "report"],
+			report:				["build/transforms/report", "report"]
 		},
 
 		transformJobs:[[
 				// immediately filter the stuff to not be transformed in any way
-				function(resource, bc) {
-					return (bc.mini && resource.tag.miniExclude) || (!bc.copyTests && resource.tag.test) || (resource.tag.ignore);
+				function(resource, bc){
+					return(bc.mini && resource.tag.miniExclude) || (!bc.copyTests && resource.tag.test) || (resource.tag.ignore);
 				},
 				[]
 			],[
 				// if the tag says just copy, then just copy
-				function(resource) {
+				function(resource, bc){
 					return resource.tag.copyOnly;
 				},
 				["copy"]
 			],[
 				// the synthetic report module
-				function(resource) {
+				function(resource, bc){
 					return resource.tag.report;
 				},
 				["dojoReport", "insertSymbols", "report"]
 			],[
 				// dojo.js, the loader
-				function(resource, bc) {
-					if (resource.mid=="dojo/dojo") {
-						bc.loader= resource;
-						resource.boots= [];
+				function(resource, bc){
+					if(resource.mid=="dojo/dojo"){
+						bc.loader = resource;
+						resource.boots = [];
 						// the loader is treated as an AMD module when creating the "dojo" layer, but and AMD dependency scan won't
 						// work because it's not an AMD module; therefore, initialize deps here and make sure not to do the depsScan transform
-						resource.deps= [];
-						bc.amdResources[resource.mid]= resource;
+						resource.deps = [];
+						bc.amdResources[resource.mid] = resource;
 						return true;
 					}
 					return false;
@@ -162,30 +162,36 @@ define(["./buildControlBase"], function(bc) {
 				["read", "dojoPragmas", "hasFindAll", "hasFixup", "writeDojo", "writeOptimized"]
 			],[
 				// package has module
-				function(resource) {
-					if (/^\w+\/has$/.test(resource.mid)) {
-						bc.amdResources[resource.mid]= resource;
+				function(resource, bc){
+					if(/^\w+\/has$/.test(resource.mid)){
+						bc.amdResources[resource.mid] = resource;
 						return true;
 					}
 					return false;
 				},
 				["read", "dojoPragmas", "hasFindAll", "hasFixup", "depsScan", "writeAmd", "writeOptimized", "hasReport", "depsDump"]
 			],[
+				// flattened nls bundles
+				function(resource, bc){
+					return !!resource.tag.flattenedNlsBundle;
+				},
+				["writeAmd", "writeOptimized"]
+			],[
 				// nls resources
-				function(resource) {
-					if (/\/nls\//.test(resource.mid) ||	/\/nls\/.+\.js$/.test(resource.src)) {
-						resource.tag.nls= 1;
-						bc.amdResources[resource.mid]= resource;
+				function(resource, bc){
+					if((/\/nls\//.test(resource.mid) || /\/nls\/.+\.js$/.test(resource.src)) && ((!resource.tag.test || bc.copyTests=="build"))){
+						resource.tag.nls = 1;
+						bc.amdResources[resource.mid] = resource;
 						return true;
 					}
 					return false;
 				},
-				["read", "dojoPragmas", "hasFindAll", "hasFixup", "depsScan", "writeAmd"]
+				["read", "dojoPragmas", "hasFindAll", "hasFixup", "depsScan", "writeAmd", "writeOptimized"]
 			],[
 				// synthetic AMD modules (used to create layers on-the-fly
-				function(resource) {
-					if (resource.tag.synthetic && resource.tag.amd){
-						bc.amdResources[resource.mid]= resource;
+				function(resource, bc){
+					if(resource.tag.synthetic && resource.tag.amd){
+						bc.amdResources[resource.mid] = resource;
 						return true;
 					}
 					return false;
@@ -195,9 +201,9 @@ define(["./buildControlBase"], function(bc) {
 			],[
 				// synthetic dojo/loadInit! resources
 				// FIXME: can't this be added to the previous transform?
-				function(resource) {
-					if (resource.tag.loadInitResource){
-						bc.amdResources[resource.mid]= resource;
+				function(resource, bc){
+					if(resource.tag.loadInitResource){
+						bc.amdResources[resource.mid] = resource;
 						return true;
 					}
 					return false;
@@ -209,43 +215,50 @@ define(["./buildControlBase"], function(bc) {
 				// already marked as an amd resource
 				// ...or...
 				// not dojo/dojo.js (filtered above), not package has module (filtered above), not nls bundle (filtered above), not test or building test, not build control script or profile script but still a Javascript resource...
-				function(resource) {
-					if (resource.tag.amd || (/\.js$/.test(resource.src) && (!resource.tag.test || bc.copyTests=="build") && !/\.(bcs|profile)\.js$/.test(resource.src))) {
-						bc.amdResources[resource.mid]= resource;
+				function(resource, bc){
+					if(resource.tag.amd || (/\.js$/.test(resource.src) && (!resource.tag.test || bc.copyTests=="build") && !/\.(bcs|profile)\.js$/.test(resource.src))){
+						bc.amdResources[resource.mid] = resource;
 						return true;
 					}
 					return false;
 				},
 				["read", "dojoPragmas", "hasFindAll", "insertSymbols", "hasFixup", "depsScan", "writeAmd", "writeOptimized"]
 			],[
+				// Declarative Resource:
+				// This resource (usually HTML) should be scanned for declarative dependencies and copied.
+				function(resource, bc){
+					return resource.tag.declarative;
+				},
+				["read", "dojoPragmas", "depsDeclarative", "write"]
+			],[
 				// a test resource; if !bc.copyTests then the resource was filtered in the first item; otherwise, if the resource is a potential module and building tests, then it was filtered above;
-				function(resource, bc) {
+				function(resource, bc){
 					return resource.tag.test;
 				},
 				["read", "dojoPragmas", "write"]
 			],[
 				// html file; may need access contents for template interning and/or dojoPragmas; therefore, can't use copy transform
-				function(resource, bc) {
+				function(resource, bc){
 					return /\.(html|htm)$/.test(resource.src);
 				},
 				["read", "dojoPragmas", "write"]
 			],[
 				// css that are designated to compact
-				function(resource, bc) {
+				function(resource, bc){
 					return /\.css$/.test(resource.src);
 				},
 				["read", "optimizeCss", "write"]
 			],[
 				// just copy everything else except tests which were copied above iff desired...
-				function(resource) {
+				function(resource, bc){
 					return !resource.tag.test;
 				},
 				["copy"]
 			]
 		]
 	};
-	for (var p in defaultBc) {
-		bc[p]= defaultBc[p];
+	for(var p in defaultBc){
+		bc[p] = defaultBc[p];
 	}
 	return bc;
 });
diff --git a/util/build/discover.js b/util/build/discover.js
index 741e8b2..cf5bbac 100644
--- a/util/build/discover.js
+++ b/util/build/discover.js
@@ -1,4 +1,8 @@
-define(["./buildControl", "./fileUtils", "./fs", "./stringify", "dojo/has", "./process"], function(bc, fileUtils, fs, stringify, has, process){
+define([
+	"./buildControl",
+	"./fileUtils",
+	"./fs"
+], function(bc, fileUtils, fs){
 	// find all files as given by files, dirs, trees, and packages
 	var
 		dirsProcessed =
@@ -37,10 +41,10 @@ define(["./buildControl", "./fileUtils", "./fs", "./stringify", "dojo/has", "./p
 						};
 				},
 				tag = {},
-				gotOne  = false;
+				gotOne	= false;
 			for(var p in resourceTags){
 				tag[p] = getFilterFunction(resourceTags[p]);
-				gotOne  = true;
+				gotOne	= true;
 			}
 			if(!gotOne){
 				return 0;
@@ -71,32 +75,45 @@ define(["./buildControl", "./fileUtils", "./fs", "./stringify", "dojo/has", "./p
 			}
 		},
 
-		readSingleDir = function(srcPath, destPath, excludes, advise, traverse){
-			if(dirsProcessed[srcPath]){
-				return;
-			}
-			dirsProcessed[srcPath] = 1;
-			if(!fileUtils.dirExists(srcPath)){
-				bc.log("missingDirDuringDiscovery", ["directory", srcPath]);
+		readSingleDir = function(srcBase, destBase, current, excludes, advise, traverse){
+			// Read a directory and advise of each child contained therein if the child is
+			// not excluded.
+			//
+			// If traverse is truthy, then traverse the directory tree. When traversing,
+			// current gives the current position in the traversal relative to srcBase.
+			// The first call when traversing (or only call when not traversing) must
+			// have current set to falsy.
+			//
+			// Notice that only the complete child path relative to srcBase is submitted
+			// to excludes. This simplifies constructing exclude functions since srcBase
+			// will never be part of the input to those functions.
+
+			var dir = srcBase + (current ? "/" + current : ""),
+				fullPrefix = dir + "/",
+				currentPrefix = current ? current + "/" : "",
+				subdirs = [];
+
+			// inspect each directory once per build
+			if(dirsProcessed[dir]){
 				return;
 			}
-			var
-				srcPathLength = srcPath.length,
-				subdirs = [];
-			fs.readdirSync(srcPath).forEach(function(filename){
-				var fullFilename = srcPath + "/" + filename;
-				if(!excludes || !excludes(fullFilename)){
-					var stats = fs.statSync(fullFilename);
+			dirsProcessed[dir] = 1;
+
+			fs.readdirSync(dir).forEach(function(filename){
+				var current = currentPrefix + filename;
+				if(!excludes || !excludes(current)){
+					var fullFilename = fullPrefix + filename,
+						stats = fs.statSync(fullFilename);
 					if(stats.isDirectory()){
-						subdirs.push(fullFilename);
+						subdirs.push(current);
 					}else{
-						advise(fullFilename, destPath + "/" + filename);
+						advise(fullFilename, destBase + "/" + current);
 					}
 				}
 			});
 			if(traverse && subdirs.length){
-				subdirs.forEach(function(path){
-					readSingleDir(path, destPath + path.substring(srcPathLength), excludes, advise, 1);
+				subdirs.forEach(function(current){
+					readSingleDir(srcBase, destBase, current, excludes, advise, 1);
 				});
 			}
 		},
@@ -105,12 +122,24 @@ define(["./buildControl", "./fileUtils", "./fs", "./stringify", "dojo/has", "./p
 			advise(item[0], item[1]);
 		},
 
+		srcPathExists = function(srcPath){
+			if(!fileUtils.dirExists(srcPath)){
+				bc.log("missingDirDuringDiscovery", ["directory", srcPath]);
+				return 0;
+			}
+			return 1;
+		},
+
 		readDir = function(item, advise){
-			readSingleDir(item[0], item[1], getExcludes(item[2]), advise, 0, 0);
+			if(srcPathExists(item[0])){
+				readSingleDir(item[0], item[1], 0, getExcludes(item[2]), advise, 0, 0);
+			}
 		},
 
 		readTree = function(item, advise){
-			readSingleDir(item[0], item[1], getExcludes(item[2]), advise, 1);
+			if(srcPathExists(item[0])){
+				readSingleDir(item[0], item[1], 0, getExcludes(item[2]), advise, 1);
+			}
 		},
 
 		discover = {
@@ -130,7 +159,7 @@ define(["./buildControl", "./fileUtils", "./fs", "./stringify", "dojo/has", "./p
 			}
 			if(!treeItem){
 				// create a tree item; don't traverse into hidden, backup, etc. files (e.g., .svn, .git, etc.)
-				treeItem = [pack.location, destPack.location, /(\/\.)|(~$)/];
+				treeItem = [pack.location, destPack.location, /(\/\.)|(^\.)|(~$)/];
 			}
 
 			var filenames = [];
@@ -156,6 +185,7 @@ define(["./buildControl", "./fileUtils", "./fs", "./stringify", "dojo/has", "./p
 				}else if(filename==mainModuleFilename){
 					maybeAmdModules[packName] = mainModuleInfo;
 				}else{
+					// notice that this may result in mapping the module to a different location
 					maybeAmdModules[mid] = moduleInfo;
 				}
 			});
diff --git a/util/build/examples/require.js b/util/build/examples/require.js
index 55af9a3..60b6ed2 100644
--- a/util/build/examples/require.js
+++ b/util/build/examples/require.js
@@ -4,7 +4,7 @@ require({
 		location:"../../../dojo"
 	},{
 		name:"dijit",
-		location:"../../../dijig"
+		location:"../../../dijit"
 	}]
 });
 
diff --git a/util/build/fileHandleThrottle.js b/util/build/fileHandleThrottle.js
index 86af065..bfe96ab 100644
--- a/util/build/fileHandleThrottle.js
+++ b/util/build/fileHandleThrottle.js
@@ -1,17 +1,17 @@
 define([], function(){
 	var
-		count= 0,
-		max= 10,
-		queue= [];
+		count = 0,
+		max = 10,
+		queue = [];
 	return {
-		release: function(){
+		release:function(){
 			if(queue.length){
 				(queue.shift())();
 			}else{
 				count--;
 			}
 		},
-		enqueue: function(proc){
+		enqueue:function(proc){
 			if(count<max){
 				count++;
 				proc();
diff --git a/util/build/fileUtils.js b/util/build/fileUtils.js
index 7f34ed3..21b75b2 100644
--- a/util/build/fileUtils.js
+++ b/util/build/fileUtils.js
@@ -1,51 +1,55 @@
-define(["./fs", "./buildControlBase", "dojo/has"], function(fs, bc, has) {
+define([
+	"./fs",
+	"./buildControlBase",
+	"dojo/has"
+], function(fs, bc, has){
 	var
-		getFilename= function(filename) {
-			if (/\//.test(filename)) {
+		getFilename = function(filename){
+			if(/\//.test(filename)){
 				return filename.match(/^.*\/([^\/]+)$/)[1];
 			}
 			return filename;
 		},
 
-		getFilepath= function(filename) {
-			if (/\//.test(filename)) {
-				var result= filename.match(/^(.*)\/[^\/]+$/)[1];
+		getFilepath = function(filename){
+			if(/\//.test(filename)){
+				var result = filename.match(/^(.*)\/[^\/]+$/)[1];
 				// if result=="", then must have been something like "/someFile"
 				return result.length ? result : "/";
 			}
 			return "";
 		},
 
-		getFiletype= function(filename, trimDot) {
-			var match= filename.match(/(\.([^\/]*))$/);
+		getFiletype = function(filename, trimDot){
+			var match = filename.match(/(\.([^\/]*))$/);
 			return (match && (trimDot ? match[2] : match[1])) || "";
 		},
 
-		cleanupPath= function(path) {
+		cleanupPath = function(path){
 			// change any falsy to ""
-			path= path || "";
+			path = path || "";
 
 			// change all backslashes to forward slashes for those with bad habits from windows
-			path= path.replace(/\\/g, "/");
+			path = path.replace(/\\/g, "/");
 
 			// remove any trailing "/" to be less sensitive to careless user input
 			// but remember "/" is not a trailing slash--it's the root
-			if (path.length>1 && path.charAt(path.length-1)=="/") {
-				path= path.substring(0, path.length-1);
+			if(path.length>1 && path.charAt(path.length-1)=="/"){
+				path = path.substring(0, path.length-1);
 			}
 			return path;
 		},
 
-		catPath= function(lhs, rhs) {
-			if (arguments.length>2) {
-				for (var args= [], i= 1; i<arguments.length; args.push(arguments[i++]));
-				return catPath(lhs, catPath.apply(this, args));
-			} else if (!rhs || !rhs.length) {
-				return lhs;
-			} else if (!lhs || !lhs.length) {
-				return rhs;
-			} else {
-				return (lhs + "/" + rhs).replace(/\/\/\/?/g, "/");
+		catPath = function(lhs, rhs){
+			if(arguments.length>2){
+				for(var args = [], i = 1; i<arguments.length; args.push(arguments[i++]));
+				return catPath(cleanupPath(lhs), catPath.apply(this, args));
+			}else if(!rhs || !rhs.length){
+				return cleanupPath(lhs);
+			}else if(!lhs || !lhs.length){
+				return cleanupPath(rhs);
+			}else{
+				return (cleanupPath(lhs) + "/" + cleanupPath(rhs)).replace(/\/\/\/?/g, "/");
 			}
 		},
 
@@ -59,104 +63,104 @@ define(["./fs", "./buildControlBase", "dojo/has"], function(fs, bc, has) {
 					result.pop();
 					lastSegment = result[result.length - 1];
 				}else if(segment!="."){
-					result.push(lastSegment= segment);
-				} // else ignore "."
+					result.push(lastSegment = segment);
+				}// else ignore "."
 			}
 			return result.join("/");
 		},
 
-		isAbsolutePathRe= has("is-windows") ?
+		isAbsolutePathRe = has("is-windows") ?
 			// for windows, starts with "\\" or a drive designator (anything other than "/" or "\" followed by a ":")
 			/^((\\\\)|([^\/\\]+\:))/ :
 			// for unix, starts with "/"
 			/^\//,
 
-		isAbsolutePath= function(path) {
+		isAbsolutePath = function(path){
 			return path && path.length && isAbsolutePathRe.test(path);
 		},
 
-		normalize= function(filename){
+		normalize = function(filename){
 			return has("is-windows") ? filename.replace(/\//g, "\\") : filename;
 		},
 
-		getAbsolutePath= function(src, base) {
-			src= cleanupPath(src);
-			if (!isAbsolutePath(src)) {
-				src= catPath(base, src);
+		getAbsolutePath = function(src, base){
+			src = cleanupPath(src);
+			if(!isAbsolutePath(src)){
+				src = catPath(base, src);
 			}
 			return compactPath(src);
 		},
 
-		computePath= function(path, base) {
-			path= cleanupPath(path);
+		computePath = function(path, base){
+			path = cleanupPath(path);
 			return compactPath(isAbsolutePath(path) ? path : catPath(base, path));
 		},
 
-		getTimestamp= function(ts) {
-			var f= function(i) { return "-" + (i<10 ? "0" + i : i); };
+		getTimestamp = function(ts){
+			var f = function(i){ return "-" + (i<10 ? "0" + i : i); };
 			return ts.getFullYear() + f(ts.getMonth()+1) + f(ts.getDate()) + f(ts.getHours()) + f(ts.getMinutes()) + f(ts.getSeconds());
 		},
 
-		dirExists= function(
+		dirExists = function(
 			filename
-		) {
-			try {
+		){
+			try{
 				return fs.statSync(filename).isDirectory();
-			} catch(e) {
+			}catch(e){
 				return false;
 			}
 		},
 
-		fileExists= function(
+		fileExists = function(
 			filename
-		) {
-			try {
+		){
+			try{
 				return fs.statSync(filename).isFile();
-			} catch(e) {
+			}catch(e){
 				return false;
 			}
 		},
 
-		checkedDirectories= {},
+		checkedDirectories = {},
 
-		clearCheckedDirectoriesCache= function() {
-			checkedDirectories= {};
+		clearCheckedDirectoriesCache = function(){
+			checkedDirectories = {};
 		},
-		ensureDirectory= function(path) {
-			if (!checkedDirectories[path]) {
-				if (!dirExists(path)) {
+		ensureDirectory = function(path){
+			if(!checkedDirectories[path]){
+				if(!dirExists(path)){
 					ensureDirectory(getFilepath(path));
-					try {
+					try{
 						fs.mkdirSync(path, 0755);
-					} catch (e) {
+					}catch(e){
 						//squelch
 					}
 				}
-				checkedDirectories[path]= 1;
+				checkedDirectories[path] = 1;
 			}
 		},
 
-		ensureDirectoryByFilename= function(filename) {
+		ensureDirectoryByFilename = function(filename){
 			ensureDirectory(getFilepath(filename));
 		},
 
-		readAndEval= function(filename, type) {
-			try {
-				if (fileExists(filename)) {
+		readAndEval = function(filename, type){
+			try{
+				if(fileExists(filename)){
 					return eval("(" + fs.readFileSync(filename, "utf8") + ")");
 				}
-			} catch (e) {
+			}catch(e){
 				bc.log("failedReadAndEval", ["filename", filename, "type", type, "error", e]);
 			}
 			return {};
 		},
 
-		maybeRead = function(filename) {
-			try {
-				if (fileExists(filename)) {
+		maybeRead = function(filename){
+			try{
+				if(fileExists(filename)){
 					return fs.readFileSync(filename, "utf8");
 				}
-			} catch (e) {
+			}catch(e){
 			}
 			return 0;
 		};
diff --git a/util/build/help.txt b/util/build/help.txt
index feebcbc..9c73c61 100644
--- a/util/build/help.txt
+++ b/util/build/help.txt
@@ -60,10 +60,24 @@ OPTIONS
      --releaseDir <path>       base directory for build output
      
      --releaseName <string>    path segment to append to releaseDir that gives base directory for build output
-     
-     --writeProfile <filename> write the processed profile to filename
-     
-     --copyTests               Copy test files and the DOH package.
+
+     --layerOptimize <arg>     process all layer resources in order to minimize resource size; arg as follows:
+                                   comments             => remove comments with ShrinkSafe
+                                   comments.keeplines   => as above, but don't remove newlines
+                                   shrinksafe           => minimize with ShrinkSafe
+                                   shrinksafe.keeplines => as above, but don't remove newlines
+                                   closure              => minimize with the Google Closure compiler
+                                   closure.keeplines    => as above, but don't remove newlines
+                                   uglify               => minimize with Uglify
+                                   uglify.keeplines     => as above, but don't remove newlines
+                               (note: all args are case-insensitive)
+
+     --optimize <arg>          analogous to --layerOptimize, but applied to non-layer resources
+
+     --copyTests <arg>         copy test files and the DOH package; arg as follows:
+                                   false => don't copy tests
+                                   true  => copy test resources, but don't apply any transforms
+                                   build => copy and build tests resources just as if they were normal resources
      
      --mini                    Ignore resources tagged as not mini (e.g. tests, demos dijit/bench, etc.)
      
diff --git a/util/build/main.js b/util/build/main.js
index 4cc4f9e..31c3e9e 100644
--- a/util/build/main.js
+++ b/util/build/main.js
@@ -33,29 +33,28 @@
 // github: https://github.com/altoviso/bdBuild
 // docs: http://bdframework.org/bdBuild/docs
 
-define(["require", "dojo/has"], function(require, has) {
+define(["require", "dojo/has"], function(require, has){
 
 	// host-dependent environment initialization
-	if (has("host-node")) {
-		define("commandLineArgs", function() {
+	if(has("host-node")){
+		define("commandLineArgs", function(){
 			//arg[0] is node; argv[1] is dojo.js; therefore, start with argv[2]
 			return process.argv.slice(2);
 		});
 
 		// helps during dev or heavily async node...
 		var util = require.nodeRequire("util");
-		debug= function(it, depth, inspect){
+		debug = function(it, depth, inspect){
 			util.debug(inspect ? util.inspect(it, false, depth) : it);
 		};
 
-		// TODO: make this real
-		has.add("is-windows", 0);
-	} else if (has("host-rhino")) {
-		define("commandLineArgs", [], function() {
-			var result= [];
-			require.rawConfig.commandLineArgs.forEach(function(item) {
-				var parts= item.split("=");
-				if (parts[0]!="baseUrl") {
+		has.add("is-windows", process.platform == "win32");
+	}else if(has("host-rhino")){
+		define("commandLineArgs", [], function(){
+			var result = [];
+			require.rawConfig.commandLineArgs.forEach(function(item){
+				var parts = item.split("=");
+				if(parts[0]!="baseUrl"){
 					result.push(item);
 				}
 			});
@@ -63,17 +62,17 @@ define(["require", "dojo/has"], function(require, has) {
 		});
 		// TODO: make this real
 		has.add("is-windows", /indows/.test(environment["os.name"]));
-	} else {
+	}else{
 		console.log("unknown environment; terminating.");
 		return 0;
 	}
 
-	this.require.scopeify= function(moduleList) {
-		for (var p, mid, module, text= "", contextRequire= this, args= moduleList.split(","), i= 0; i<args.length;) {
-			mid= args[i++].match(/\S+/)[0];
-			module= contextRequire(mid);
-			mid= mid.match(/[^\/]+$/)[0];
-			for (p in module) {
+	this.require.scopeify = function(moduleList){
+		for(var p, mid, module, text = "", contextRequire = this, args = moduleList.split(","), i = 0; i<args.length;){
+			mid = args[i++].match(/\S+/)[0];
+			module = contextRequire(mid);
+			mid = mid.match(/[^\/]+$/)[0];
+			for(p in module){
 				text+= "var " + p + "=" + mid + "." + p + ";\n";
 			}
 		}
@@ -81,56 +80,56 @@ define(["require", "dojo/has"], function(require, has) {
 	};
 
 	// run the build program
-	require(["./buildControl", "./process"], function(bc, process) {
+	require(["./buildControl", "./process"], function(bc, process){
 		var
-			gateListeners= bc.gateListeners= [],
+			gateListeners = bc.gateListeners = [],
 
-			transforms= bc.transforms,
-			transformJobs= bc.transformJobs,
-			transformJobsLength= transformJobs.length,
+			transforms = bc.transforms,
+			transformJobs = bc.transformJobs,
+			transformJobsLength = transformJobs.length,
 
 			// all discovered resources
-			resources= [],
+			resources = [],
 
-			reportError= function(resource, err) {
+			reportError = function(resource, err){
 				bc.log("transformFailed", ["resource", resource.src, "transform", resource.jobPos, "error", err]);
-				resource.error= true;
+				resource.error = true;
 			},
 
-			returnFromAsyncProc= function(resource, err) {
+			returnFromAsyncProc = function(resource, err){
 				bc.waiting--;
-				if (err) {
+				if(err){
 					// notice reportError can decide to continue or panic
 					reportError(resource, err);
 				}
 				advance(resource, true);
 			},
 
-			advance= function(resource, continuingSameGate) {
-				if (resource.error) {
+			advance = function(resource, continuingSameGate){
+				if(resource.error){
 					return;
 				}
-				if (!continuingSameGate) {
+				if(!continuingSameGate){
 					// first time trying to advance through the current gate
 					bc.waiting++;
 				}
 
 				// apply all transforms with a gateId <= the current gate for resource that have not yet been applied
 				var err, nextJobPos, candidate;
-				while (1) {
-					nextJobPos= resource.jobPos + 1,
-					candidate= nextJobPos<resource.job.length && resource.job[nextJobPos];
+				while(1){
+					nextJobPos = resource.jobPos + 1;
+					candidate = nextJobPos<resource.job.length && resource.job[nextJobPos];
 					// candidate (if any) is a [transformProc, gateId] pair
-					if (candidate && candidate[1]<=bc.currentGate) {
+					if(candidate && candidate[1]<=bc.currentGate){
 						resource.jobPos++;
 						bc.waiting++;
-						err= candidate[0](resource, returnFromAsyncProc);
-						if (err===returnFromAsyncProc) {
+						err = candidate[0](resource, returnFromAsyncProc);
+						if(err===returnFromAsyncProc){
 							// the transform proc must call returnFromAsyncProc when complete
 							return;
 						}
 						bc.waiting--;
-						if (err) {
+						if(err){
 							// notice we reportError can decide to continue or panic
 							reportError(resource, err);
 							// if reportError didn't panic, then this break will cause this resource to clear the next
@@ -138,7 +137,7 @@ define(["require", "dojo/has"], function(require, has) {
 							// quit
 							break;
 						}
-					} else {
+					}else{
 						break;
 					}
 				}
@@ -147,22 +146,22 @@ define(["require", "dojo/has"], function(require, has) {
 				passGate();
 			},
 
-			advanceGate= function(currentGate) {
-				while (1) {
-					bc.currentGate= ++currentGate;
+			advanceGate = function(currentGate){
+				while(1){
+					bc.currentGate = ++currentGate;
 					bc.log("pacify", "starting " + bc.gates[bc.currentGate][2] + "...");
 					gateListeners.forEach(function(listener){
 						listener(bc.gates[bc.currentGate][1]);
 					});
-					if (currentGate==bc.gates.length-1 || bc.gates[currentGate+1][0]) {
+					if(currentGate==bc.gates.length-1 || bc.gates[currentGate+1][0]){
 						// if we've either advanced to the last gate or the next gate is a synchronized gate, then hold at the current gate
 						return;
 					}
 				}
 			},
 
-			passGate= bc.passGate= function() {
-				if (--bc.waiting) {
+			passGate = bc.passGate = function(){
+				if(--bc.waiting){
 					return;
 				} //	else all processes have passed through bc.currentGate
 
@@ -171,41 +170,44 @@ define(["require", "dojo/has"], function(require, has) {
 					process.exit(0);
 				}
 
-				if (bc.currentGate<bc.gates.length-1) {
+				if(bc.currentGate<bc.gates.length-1){
 					advanceGate(bc.currentGate);
 					// hold the next gate until all resources have been advised
 					bc.waiting++;
 					resources.forEach(function(resource){ advance(resource, 0); });
 					// release the hold placed above
 					passGate();
-				} else {
-					if (!resources.length) {
+				}else{
+					if(!resources.length){
 						bc.log("discoveryFailed");
 					}
 					bc.log("pacify", "Process finished normally.\n\terrors: " + bc.getErrorCount() + "\n\twarnings: " + bc.getWarnCount() + "\n\tbuild time: " + ((new Date()).getTime() - bc.startTimestamp.getTime()) / 1000 + " seconds");
+					if(!bc.exitCode && bc.getErrorCount()){
+						bc.exitCode = 1;
+					}
 					process.exit(bc.exitCode);
 					// that's all, folks...
 				}
 			};
 
-		bc.start= function(resource) {
+		bc.start = function(resource){
 			// check for collisions
 			var
-				src= resource.src,
-				dest= resource.dest;
-			if (bc.resourcesByDest[src]) {
+				src = resource.src,
+				dest = resource.dest;
+			if(bc.resourcesByDest[src]){
 				// a dest is scheduled to overwrite a source
 				bc.log("overwrite", ["input", src, "resource destined for same location: ", bc.resourcesByDest[src].src]);
 				return;
 			}
-			if (bc.resourcesByDest[dest]) {
+			if(bc.resourcesByDest[dest]){
 				// multiple srcs scheduled to write into a single dest
 				bc.log("outputCollide", ["source-1", src, "source-2", bc.resourcesByDest[dest].src]);
 				return;
 			}
 			// remember the resources in the global maps
-			bc.resources[resource.src]= resource;
-			bc.resourcesByDest[resource.dest]= resource;
+			bc.resources[resource.src] = resource;
+			bc.resourcesByDest[resource.dest] = resource;
 
 			if(bc.checkDiscovery){
 				bc.log("pacify", src + "-->" + dest);
@@ -213,13 +215,13 @@ define(["require", "dojo/has"], function(require, has) {
 			}
 
 			// find the transformJob and start it...
-			for (var i= 0; i<transformJobsLength; i++) {
-				if (transformJobs[i][0](resource, bc)) {
+			for(var i = 0; i<transformJobsLength; i++){
+				if(transformJobs[i][0](resource, bc)){
 					// job gives a vector of functions to apply to the resource
 					// jobPos says the index in the job vector that has been applied
 					resources.push(resource);
-					resource.job= transformJobs[i][1];
-					resource.jobPos= -1;
+					resource.job = transformJobs[i][1];
+					resource.jobPos = -1;
 					advance(resource);
 					return;
 				}
@@ -229,55 +231,55 @@ define(["require", "dojo/has"], function(require, has) {
 
 		function doBuild(){
 			var
-				transformNames= [],
-				pluginNames= [],
-				deps= [];
-			bc.discoveryProcs.forEach(function(mid) { deps.push(mid); });
-			for (var p in bc.transforms) {
+				transformNames = [],
+				pluginNames = [],
+				deps = [];
+			bc.discoveryProcs.forEach(function(mid){ deps.push(mid); });
+			for(var p in bc.transforms){
 				// each item is a [AMD-MID, gateId] pair
 				transformNames.push(p);
 				deps.push(bc.transforms[p][0]);
 			}
-			for (p in bc.plugins) {
+			for(p in bc.plugins){
 				pluginNames.push(p);
 				deps.push(bc.plugins[p]);
 			}
-			bc.plugins= {};
-			require(deps, function() {
+			bc.plugins = {};
+			require(deps, function(){
 				// pull out the discovery procedures
-				for (var discoveryProcs= [], argsPos= 0; argsPos<bc.discoveryProcs.length; discoveryProcs.push(arguments[argsPos++]));
+				for(var discoveryProcs = [], argsPos = 0; argsPos<bc.discoveryProcs.length; discoveryProcs.push(arguments[argsPos++]));
 
 				// replace the transformIds in the transformJobs with the actual transform procs; similarly for plugins
-				for (var id, proc, i=0; i<transformNames.length;) {
-					id= transformNames[i++];
-					proc= arguments[argsPos++];
+				for(var id, proc, i=0; i<transformNames.length;){
+					id = transformNames[i++];
+					proc = arguments[argsPos++];
 					// replace every occurence of id with proc
-					transformJobs.forEach(function(item) {
+					transformJobs.forEach(function(item){
 						// item is a [predicate, vector of [transformId, gateId] pairs] pairs
-						for (var transforms=item[1], i= 0; i<transforms.length; i++) {
-							if (transforms[i][0]==id) {
-								transforms[i][0]= proc;
+						for(var transforms=item[1], i = 0; i<transforms.length; i++){
+							if(transforms[i][0]==id){
+								transforms[i][0] = proc;
 								break;
 							}
 						}
 					});
 				}
-				for (i=0; i<pluginNames.length;) {
-					bc.plugins[bc.getSrcModuleInfo(pluginNames[i++]).mid]= arguments[argsPos++];
+				for(i=0; i<pluginNames.length;){
+					bc.plugins[bc.getSrcModuleInfo(pluginNames[i++]).mid] = arguments[argsPos++];
 				}
 
 				// start the transform engine: initialize bc.currentGate and bc.waiting, then discover and start each resource.
 				// note: discovery procs will call bc.start with each discovered resource, which will call advance, which will
 				// enter each resource in a race to the next gate, which will result in many bc.waiting incs/decs
-				bc.waiting= 1;  // matches *1*
+				bc.waiting = 1;	// matches *1*
 				bc.log("pacify", "discovering resources...");
 				advanceGate(-1);
-				discoveryProcs.forEach(function(proc) { proc(); });
-				passGate();  // matched *1*
+				discoveryProcs.forEach(function(proc){ proc(); });
+				passGate();	 // matched *1*
 			});
 		}
 
-		if(!bc.errorCount && bc.release){
+		if(!bc.getErrorCount() && bc.release){
 			doBuild();
 		}
 	});
diff --git a/util/build/messages.js b/util/build/messages.js
index 44785a4..1ca6108 100644
--- a/util/build/messages.js
+++ b/util/build/messages.js
@@ -20,7 +20,10 @@ define([], function(){
 		[1, 108, "internStrings", "Interning strings."],
 		[1, 109, "processHtmlFiles", "Processing HTML files."],
 		[1, 110, "userTrace", "User trace:"],
-		[1, 110, "userInfo", "User info:"],
+		[1, 111, "userInfo", "User info:"],
+		[1, 112, "cssOptimizeIgnored", "While optimizing a CSS file, an import directive was not expanded as instructed by the profile."],
+		[1, 113, "cssOptimizeIgnoredMultiMediaTypes", "While optimizing a CSS file, an import directive was not expanded because it indicated multiple media types."],
+
 
 		// warn 200-299
 		[1, 200, "configUnresolvedValues", "Configuration contains unsolved values."],
@@ -46,8 +49,10 @@ define([], function(){
 		[1, 221, "assumeLayerIsDojoModule", "Assumed layer is referencing a dojo module."],
 		[1, 222, "assumeLayerDependencyIsDojoModule", "Assumed layer is referencing a dojo module."],
 		[1, 223, "possibleLegacyModuleId", "Name in internStringsSkipList looks like a legacy module identifier."],
-		[1, 224, "missingPluginResolver", "A plugin dependency was encountered but there was not build-time plugin resolver."],
+		[1, 224, "missingPluginResolver", "A plugin dependency was encountered but there was no build-time plugin resolver."],
 		[1, 225, "missingDirDuringDiscovery", "A directory that was scheduled to be read during discovery did not exist."],
+		[1, 226, "missingProfile", "A package without a profile could throw errors or warnings."],
+		[1, 227, "symbolsLeak", "Inserting symbols (by setting the profile variable 'symbol') causes leaks in IE."],
 
 		// error 300-399
 		[1, 300, "dojoHasMissingPlugin", "Missing dojo/has module."],
@@ -93,7 +98,7 @@ define([], function(){
 		[1, 340, "inputHTMLFileDoesNotExist", "HTML file given for \"htmlFiles\" switch does not exist."],
 		[1, 341, "inputHTMLDirDoesNotExist", "HTML directory given for \"htmlDir\" switch does not exist."],
 		[1, 342, "inputHTMLDirNoFiles","HTML directory given for \"htmlDir\" switch contains no HTML files."],
-		[1, 343, "inputIllegalCommandlineArg", "Illegal command line argument."],
+		[1, 343, "inputIllegalCommandlineArg", "Illegal or missing argument for command line flag."],
 		[1, 344, "inputFileDoesNotExist", "File does not exist."],
 		[1, 345, "inputProcessingHtmlFileNotImplemented", "Pulling profiles from HTML files is not implemented."],
 		[1, 346, "inputFailedReadfile", "Failed to read input file."],
@@ -104,8 +109,13 @@ define([], function(){
 		[1, 351, "cannotDeduceModuleIdFrom16LayerDependency", "Cannot deduce module identifier from layer dependency"],
 		[1, 352, "optimizerReportedErrors", "Optimizer reported errors; consult build report for details."],
 		[1, 352, "failedToReadLayerCopyrightFile", "Failed to read copyright file given with layer."],
-
-
+		[1, 353, "i18nUnevaluableBundle", "I18n bundle was not evaluable in the build environment; therefore it will not be included in the flattening computations."],
+		[1, 354, "missingL10n", "Root bundle indicates localized bundles that don't exist."],
+		[1, 355, "declarativeRequireFailed", "Unable to convert declarative require."],
+		[1, 356, "optimizeFailed", "The optimizer threw an exception; the module probably contains syntax errors."],
+		[1, 357, "cssOptimizeUnableToResolveURL", "While optimizing a CSS file, it was impossible to compute the destination location of a relative URL."],
+		[1, 358, "cssOptimizeImproperComment", "While optimizing a CSS file, an improper comment was encountered."],
+		[1, 359, "cssOptimizeIgnoredNoResource", "While optimizing a CSS file, an import directive was not expanded because the source for the import was not available to the builder."],
 
 		// reports 400-499
 		[1, 400, "hasReport", "Has Features Detected"],
diff --git a/util/build/node/fs.js b/util/build/node/fs.js
index 093dd47..00b5804 100644
--- a/util/build/node/fs.js
+++ b/util/build/node/fs.js
@@ -1,5 +1,5 @@
-define(["../fileHandleThrottle"], function(fht) {
-	var fs= require.nodeRequire("fs");
+define(["../fileHandleThrottle"], function(fht){
+	var fs = require.nodeRequire("fs");
 	return {
 		statSync:fs.statSync,
 		mkdirSync:fs.mkdirSync,
@@ -7,7 +7,7 @@ define(["../fileHandleThrottle"], function(fht) {
 		writeFileSync:fs.writeFileSync,
 		readdirSync:fs.readdirSync,
 
-		readFile: function(filename, encoding, cb) {
+		readFile:function(filename, encoding, cb){
 			fht.enqueue(function(){
 				fs.readFile(filename, encoding, function(code){
 					fht.release();
@@ -16,7 +16,7 @@ define(["../fileHandleThrottle"], function(fht) {
 			});
 		},
 
-		writeFile: function(filename, contents, encoding, cb) {
+		writeFile:function(filename, contents, encoding, cb){
 			fht.enqueue(function(){
 				fs.writeFile(filename, contents, encoding, function(code){
 					fht.release();
diff --git a/util/build/node/process.js b/util/build/node/process.js
index 80c2687..b079f9f 100644
--- a/util/build/node/process.js
+++ b/util/build/node/process.js
@@ -1,37 +1,52 @@
-define(["../fileHandleThrottle", "../messages"], function(fht, messages) {
-	var spawn= require.nodeRequire("child_process").spawn;
+define(["../fileHandleThrottle", "../messages"], function(fht, messages){
+
+	var match = process.version.match(/(\d+)\.(\d+)\.(\d+)/),
+		versionMajor = Number(match[1]),
+		versionMinor = Number(match[2]),
+		versionPatch = Number(match[3]),
+		spawn = require.nodeRequire("child_process").spawn;
 	return {
 		cwd:process.cwd,
 		exit:function(code){
 			// no more messages
 			messages.stop();
 
-			// allow whatever is in the stdout buffer to be pumped
-			process.stdout.on('close', function(){
-				process.exit(code);
-			});
+			process.exit(code);
 		},
 
 		exec:function() {
 			// signature is (command, arg1, ..., argn, errorMessage, bc, callback)
-			for(var command= arguments[0], args= [], i= 1; i<arguments.length-3; i++){
+			for(var command = arguments[0], args = [], i = 1; i<arguments.length-3; i++){
 				args.push(arguments[i]);
 			}
 			var
-				errorMessage= arguments[i++],
-				bc= arguments[i++],
-				callback= arguments[i];
+				errorMessage = arguments[i++],
+				bc = arguments[i++],
+				callback = arguments[i];
 			fht.enqueue(function(){
 				var
-					text= "",
-					process= spawn(command, args);
-				process.on("exit", function(code){
-					fht.release();
-					if(code){
-						bc.log("execFailed", ["message", errorMessage, "output", text]);
-					}
-					callback && callback(code, text);
-				});
+					text = "",
+					process = spawn(command, args),
+					status = 0,
+					finish = function(code){
+						// release when both exit and close events occur; see below
+						if(++status===2){
+							fht.release();
+							if(code){
+								bc.log("execFailed", ["message", errorMessage, "output", text]);
+							}
+							callback && callback(code, text);
+						}
+					};
+
+				process.on("exit", finish);
+				// for node>=0.8, close is called; for node <0.8 close appears to not be called (verified for 0.6)
+				// in 0.8+ releasing the file handle before close is called can use up file handles too fast (see #15620)
+				if(versionMajor==0 && versionMinor<=7){
+					++status;
+				}else{
+					process.on("close", finish);
+				}
 				process.stdout.on("data", function(data){
 					text+= data;
 				});
diff --git a/util/build/optimizeRunner.js b/util/build/optimizeRunner.js
index 92c5c1f..d101735 100644
--- a/util/build/optimizeRunner.js
+++ b/util/build/optimizeRunner.js
@@ -1,7 +1,9 @@
+/*jshint rhino:true white:false */
+/*global Packages:false com:false */
 function writeFile(filename, contents, encoding, cb) {
-	if (arguments.length==3 && typeof encoding!="string") {
-		cb= encoding;
-		encoding= 0;
+	if (arguments.length === 3 && typeof encoding !== "string") {
+		cb = encoding;
+		encoding = 0;
 	}
 	var
 		outFile = new java.io.File(filename),
@@ -20,7 +22,7 @@ function writeFile(filename, contents, encoding, cb) {
 	}
 	if (cb) {
 		cb(0);
-	};
+	}
 }
 
 var built = "//>>built\n";
@@ -28,37 +30,38 @@ var built = "//>>built\n";
 function sscompile(src, dest, optimizeSwitch, copyright){
 	// decode the optimize switch
 	var
-		options= optimizeSwitch.split("."),
-		comments= 0,
-		keepLines= 0,
-		strip= null;
+		options = optimizeSwitch.split("."),
+		comments = 0,
+		keepLines = 0,
+		strip = null;
 	while(options.length){
 		switch(options.pop()){
 			case "normal":
-				strip= "normal";
+				strip = "normal";
 				break;
 			case "warn":
-				strip= "warn";
+				strip = "warn";
 				break;
 			case "all":
-				strip= "all";
+				strip = "all";
 				break;
 			case "keeplines":
-				keepLines= 1;
+				keepLines = 1;
 				break;
 			case "comments":
-				comments= 1;
+				comments = 1;
 				break;
 		}
 	}
 
 	//Use rhino to help do minifying/compressing.
-	var context = Packages.org.mozilla.javascript.Context.enter();
+	var context = Packages.org.mozilla.javascript.Context.enter(),
+		text;
 	try{
 		// Use the interpreter for interactive input (copied this from Main rhino class).
 		context.setOptimizationLevel(-1);
 
-		var text= readFile(src, "utf-8");
+		text = readFile(src, "utf-8");
 		if(comments){
 			//Strip comments
 			var script = context.compileString(text, dest, 1, null);
@@ -66,7 +69,7 @@ function sscompile(src, dest, optimizeSwitch, copyright){
 
 			//Replace the spaces with tabs.
 			//Ideally do this in the pretty printer rhino code.
-			text = text.replace(/    /g, "\t");
+			text = text.replace(/	 /g, "\t");
 		}else{
 			//Apply compression using custom compression call in Dojo-modified rhino.
 			text = new String(Packages.org.dojotoolkit.shrinksafe.Compressor.compressScript(text, 0, 1, strip));
@@ -80,62 +83,88 @@ function sscompile(src, dest, optimizeSwitch, copyright){
 	writeFile(dest, copyright + built + text, "utf-8");
 }
 
-var JSSourceFilefromCode, closurefromCode, jscomp= 0;
-function ccompile(src, dest, optimizeSwitch, copyright){
+var JSSourceFilefromCode, closurefromCode, jscomp = 0;
+function ccompile(src, dest, optimizeSwitch, copyright, optimizeOptions){
 	if(!jscomp){
-		// don't do this unless demanded...it may not be available
-		JSSourceFilefromCode=java.lang.Class.forName('com.google.javascript.jscomp.JSSourceFile').getMethod('fromCode',[java.lang.String,java.lang.String]);
+		JSSourceFilefromCode=java.lang.Class.forName("com.google.javascript.jscomp.JSSourceFile").getMethod("fromCode", [java.lang.String, java.lang.String]);
 		closurefromCode = function(filename,content){
 			return JSSourceFilefromCode.invoke(null,[filename,content]);
 		};
 		jscomp = com.google.javascript.jscomp;
 	}
+
 	//Fake extern
 	var externSourceFile = closurefromCode("fakeextern.js", " ");
 
 	//Set up source input
-	var jsSourceFile = closurefromCode(String(dest), String(readFile(src, "utf-8")));
+	// it is possible dest could have backslashes on windows (particularly with cygwin)
+	var destFilename = dest.match(/^.+[\\\/](.+)$/)[1],
+		jsSourceFile = closurefromCode(destFilename + ".uncompressed.js", String(readFile(src, "utf-8")));
 
 	//Set up options
 	var options = new jscomp.CompilerOptions();
-	options.prettyPrint = optimizeSwitch.indexOf(".keepLines") !== -1;
+	for(var k in optimizeOptions){
+		options[k] = optimizeOptions[k];
+	}
+	// Must have non-null path to trigger source map generation, also fix version
+	options.setSourceMapOutputPath("");
+	options.setSourceMapFormat(jscomp.SourceMap.Format.V3);
+	if(optimizeSwitch.indexOf(".keeplines") !== -1){
+		options.prettyPrint = true;
+	}
 
 	var FLAG_compilation_level = jscomp.CompilationLevel.SIMPLE_OPTIMIZATIONS;
 	FLAG_compilation_level.setOptionsForCompilationLevel(options);
 	var FLAG_warning_level = jscomp.WarningLevel.DEFAULT;
 	FLAG_warning_level.setOptionsForWarningLevel(options);
 
-	//Run the compiler
-	var compiler = new Packages.com.google.javascript.jscomp.Compiler(Packages.java.lang.System.err);
-	var result = compiler.compile(externSourceFile, jsSourceFile, options);
-	writeFile(dest, copyright + built + compiler.toSource(), "utf-8");
+	//Prevent too-verbose logging output
+	Packages.com.google.javascript.jscomp.Compiler.setLoggingLevel(java.util.logging.Level.SEVERE);
+
+	// Run the compiler
+	// File name and associated map name
+	var map_tag = "//@ sourceMappingURL=" + destFilename + ".map",
+		compiler = new Packages.com.google.javascript.jscomp.Compiler(Packages.java.lang.System.err);
+	compiler.compile(externSourceFile, jsSourceFile, options);
+	writeFile(dest, copyright + built + compiler.toSource() + "\n" + map_tag, "utf-8");
+
+	var sourceMap = compiler.getSourceMap();
+	sourceMap.setWrapperPrefix(copyright + "//>>built");
+	var sb = new java.lang.StringBuffer();
+	sourceMap.appendTo(sb, destFilename);
+	writeFile(dest + ".map", sb.toString(), "utf-8");
 }
 
 
 var
-	console= new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.System["in"])),
-	readLine= function(){
+	console = new java.io.BufferedReader(new java.io.InputStreamReader(java.lang.System["in"])),
+	readLine = function(){
 		// the + "" convert to a Javascript string
 		return console.readLine() + "";
 	},
-	src, dest, optimizeSwitch, copyright;
+	src,
+	dest,
+	optimizeSwitch;
 
 while(1){
-	// the + "" convert to a Javascript string
-	src= readLine();
-	if(src=="."){
+	src = readLine();
+	if(src === "."){
 		break;
 	}
-	dest= readLine();
-	optimizeSwitch= readLine();
-	copyright= eval(readLine());
+	dest = readLine();
+	optimizeSwitch = readLine();
+	var options = eval("(" + readLine() + ")");
 	print(dest + ":");
-	var start= (new Date()).getTime();
-	if(/closure/.test(optimizeSwitch)){
-		ccompile(src, dest, optimizeSwitch, copyright);
-	}else{
-		sscompile(src, dest, optimizeSwitch, copyright);
+	var start = (new Date()).getTime(),
+		exception = "";
+	try{
+		if(/closure/.test(optimizeSwitch)){
+			ccompile(src, dest, optimizeSwitch, options.copyright, options.options);
+		}else{
+			sscompile(src, dest, optimizeSwitch, options.copyright);
+		}
+	}catch(e){
+		exception = ". OPTIMIZER FAILED: " + e;
 	}
-	print("Done (compile time:" + ((new Date()).getTime()-start)/1000 + "s)");
+	print("Done (compile time:" + ((new Date()).getTime()-start)/1000 + "s)" + exception);
 }
-
diff --git a/util/build/plugins/domReady.js b/util/build/plugins/domReady.js
index 944f7e7..06bb787 100644
--- a/util/build/plugins/domReady.js
+++ b/util/build/plugins/domReady.js
@@ -1,11 +1,9 @@
-///
-// \module build/plugins/domReady
-//
-define(["../buildControl"], function(bc) {
+define(function() {
 	return {
 		start:function(
 			mid,
-			referenceModule
+			referenceModule,
+			bc
 		){
 			return bc.amdResources[bc.getSrcModuleInfo("dojo/domReady", referenceModule).mid];
 		}
diff --git a/util/build/plugins/has.js b/util/build/plugins/has.js
index af292c6..4ff2045 100644
--- a/util/build/plugins/has.js
+++ b/util/build/plugins/has.js
@@ -6,8 +6,8 @@ define(["dojo/regexp"], function(dojoRegExp) {
 			bc
 		) {
 			var
-				getHasPluginDependency= function(){
-					var hasPlugin= bc.amdResources["dojo/has"];
+				getHasPluginDependency = function(){
+					var hasPlugin = bc.amdResources["dojo/has"];
 					if(!hasPlugin){
 						bc.log("dojoHasMissingPlugin");
 						return [];
@@ -33,7 +33,7 @@ define(["dojo/regexp"], function(dojoRegExp) {
 					}else{
 						// postfixed with a ? means it is a feature to branch on, the term is the name of the feature
 						if(tokens[i++] == "?"){
-							var hasResult= has(term);
+							var hasResult = has(term);
 							if(hasResult===undefined){
 								return undefined;
 							}else if(!skip && hasResult){
@@ -58,18 +58,18 @@ define(["dojo/regexp"], function(dojoRegExp) {
 				return getHasPluginDependency();
 			}
 
-			var regex= new RegExp("((dojo\\/)|([./]+))has\\!" + dojoRegExp.escapeString(id));
+			var regex = new RegExp("((dojo\\/)|([./]+))has\\!" + dojoRegExp.escapeString(id));
 			if(!resolvedId){
 				// replace the unneeded module with a module that's guaranteed available
 				// this keeps the module order, and therefore, argument order to the factory correct
-				referenceModule.text= referenceModule.text.replace(regex, "require");
+				referenceModule.text = referenceModule.text.replace(regex, "require");
 				return [];
 			}else{
 				var
-					moduleInfo= bc.getSrcModuleInfo(resolvedId, referenceModule),
-					module= bc.amdResources[moduleInfo.mid];
+					moduleInfo = bc.getSrcModuleInfo(resolvedId, referenceModule),
+					module = bc.amdResources[moduleInfo.mid];
 				if(module){
-					referenceModule.text= referenceModule.text.replace(regex, resolvedId);
+					referenceModule.text = referenceModule.text.replace(regex, resolvedId);
 					return [module];
 				}else{
 					bc.log("dojoHasMissingMid", ["plugin resource id", id, "resolved plugin resource id", moduleInfo.mid, "reference module id", referenceModule && referenceModule.mid]);
diff --git a/util/build/plugins/i18n.js b/util/build/plugins/i18n.js
index d10a8d3..41522c4 100644
--- a/util/build/plugins/i18n.js
+++ b/util/build/plugins/i18n.js
@@ -1,67 +1,35 @@
-///
-// \module build/plugins/i18n
-//
-define(["../buildControl"], function(bc) {
-	var
-		nlsRe=
-			// regexp for reconstructing the master bundle name from parts of the regexp match
-			// nlsRe.exec("foo/bar/baz/nls/en-ca/foo") gives:
-			// ["foo/bar/baz/nls/en-ca/foo", "foo/bar/baz/nls/", "/", "/", "en-ca", "foo"]
-			// nlsRe.exec("foo/bar/baz/nls/foo") gives:
-			// ["foo/bar/baz/nls/foo", "foo/bar/baz/nls/", "/", "/", "foo", ""]
-			// so, if match[5] is blank, it means this is the top bundle definition.
-			// courtesy of http://requirejs.org
-			/(^.*(^|\/)nls(\/|$))([^\/]*)\/?([^\/]*)/,
+define(function() {
+	var nlsRe=
+		// regexp for reconstructing the master bundle name from parts of the regexp match
+		// nlsRe.exec("foo/bar/baz/nls/en-ca/foo") gives:
+		// ["foo/bar/baz/nls/en-ca/foo", "foo/bar/baz/nls/", "/", "/", "en-ca", "foo"]
+		// nlsRe.exec("foo/bar/baz/nls/foo") gives:
+		// ["foo/bar/baz/nls/foo", "foo/bar/baz/nls/", "/", "/", "foo", ""]
+		// so, if match[5] is blank, it means this is the top bundle definition.
+		// courtesy of http://requirejs.org
+		/(^.*(^|\/)nls(\/|$))([^\/]*)\/?([^\/]*)/;
 
-		getAvailableLocales= function(
-			root,
-			locale,
-			bundlePath,
-			bundleName,
-			availableLocales
-		) {
-			for (var localeParts= locale.split("-"), current= "", i= 0; i<localeParts.length; i++) {
-				current+= localeParts[i];
-				if (root[current]) {
-					availableLocales[bundlePath + current + "/" + bundleName]= 1;
-				}
-			}
-		},
-
-		start= function(
+	return {
+		start:function(
 			mid,
 			referenceModule,
 			bc
-		) {
-			var
-				i18nPlugin= bc.amdResources["dojo/i18n"],
-				match= nlsRe.exec(mid),
-				bundleName= match[5] || match[4],
-				bundlePath= bc.getSrcModuleInfo(match[1] + bundleName, referenceModule).mid.match(/(.+\/)[^\/]+/)[1],
-				locale= (match[5] && match[4]),
-				i18nResourceMid= bundlePath + (locale ? locale + "/" : "") + bundleName,
-				i18nResource= bc.amdResources[i18nResourceMid];
+		){
+			var i18nPlugin = bc.amdResources["dojo/i18n"],
+			match = nlsRe.exec(mid),
+			bundleName = match[5] || match[4],
+			bundlePath = bc.getSrcModuleInfo(match[1] + bundleName, referenceModule).mid.match(/(.+\/)[^\/]+/)[1],
+			locale = (match[5] && match[4]),
+			i18nResourceMid = bundlePath + (locale ? locale + "/" : "") + bundleName,
+			i18nResource = bc.amdResources[i18nResourceMid];
 
-			if (!i18nPlugin) {
+			if(!i18nPlugin){
 				throw new Error("i18n! plugin missing");
 			}
-			if (!i18nResource) {
+			if(!i18nResource){
 				throw new Error("i18n resource (" + i18nResourceMid + ") missing");
 			}
-	return [i18nPlugin, i18nResource];
-
-			var result = [i18nPlugin, i18nResource];
-			(bc.extraLocales||[]).forEach(function(locale){
-				i18nResourceMid= bundlePath + locale + "/" + bundleName,
-				i18nResource= bc.amdResources[i18nResourceMid];
-				if(i18nResource){
-					result.push(i18nResource);
-				}
-			});
-			return result;
-		};
-
-	return {
-		start:start
+			return [i18nPlugin, i18nResource];
+		}
 	};
 });
diff --git a/util/build/plugins/loadInit.js b/util/build/plugins/loadInit.js
index 4c7545d..25090fe 100644
--- a/util/build/plugins/loadInit.js
+++ b/util/build/plugins/loadInit.js
@@ -1,13 +1,11 @@
-///
-// \module build/plugins/loadInit
-//
-define(["../buildControl"], function(bc) {
+define(function() {
 	return {
 		start:function(
 			mid,
-			referenceModule
+			referenceModule,
+			bc
 		){
-			return bc.amdResources[bc.getSrcModuleInfo(mid, referenceModule).mid];
+			return [bc.amdResources["dojo/require"], bc.amdResources[bc.getSrcModuleInfo(mid, referenceModule).mid]];
 		}
 	};
 });
diff --git a/util/build/plugins/require.js b/util/build/plugins/require.js
index 430382f..3a316b8 100644
--- a/util/build/plugins/require.js
+++ b/util/build/plugins/require.js
@@ -1,17 +1,14 @@
-///
-// \module build/plugins/require
-//
-define([], function() {
+define([], function(){
 	return {
 		start:function(
 			mid,
 			referenceModule,
 			bc
-		) {
-			var result = [];
+		){
+			var result = [bc.amdResources["dojo/require"]];
 			mid.split(",").map(function(mid){
 				var module = bc.amdResources[mid];
-				if (!module) {
+				if(!module){
 					bc.log("legacyMissingDependency", ["reference module", referenceModule.mid, "dependency", mid]);
 				}else{
 					result.push(module);
diff --git a/util/build/plugins/text.js b/util/build/plugins/text.js
index 1ae5ab0..0bdd24d 100644
--- a/util/build/plugins/text.js
+++ b/util/build/plugins/text.js
@@ -1,59 +1,45 @@
-define(["../buildControl", "dojo/json"], function(bc, json) {
-	// note: this builder plugin only writes text that is part of a package
-	var makePluginPseudoModule= function(module, moduleInfo) {
-			return {
-				module:module,
-				pid:moduleInfo.pid,
-				mid:moduleInfo.mid,
-				deps:[],
-				getText:function(){
-					return json.stringify(this.module.text+"");
-				},
-				internStrings:function(){
-					return ["url:" + this.mid, json.stringify(this.module.text+"")];
-				}
-			};
-		},
-
-		start= function(
+define(["dojo/json", "../fs"], function(json, fs){
+	return {
+		start:function(
 			mid,
 			referenceModule,
 			bc
-		) {
-			var textPlugin= bc.amdResources["dojo/text"];
-			if (!textPlugin) {
-				throw new Error("text! plugin missing");
-			}
-
+		){
 			// mid may contain a pragma (e.g. "!strip"); remove
-			mid= mid.split("!")[0];
+			mid = mid.split("!")[0];
 
-			// the following taken from the loader toUrl function
-			// name must include a filetype; fault tolerate to allow no filetype (but things like "path/to/version2.13" will assume filetype of ".13")
-			var
-				match = mid.match(/(.+)(\.[^\/\.]+?)$/),
-				root = (match && match[1]) || mid,
-				ext = (match && match[2]) || "",
-				moduleInfo =  bc.getSrcModuleInfo(root, referenceModule),
-				url= moduleInfo.url;
-			// recall, getModuleInfo always returns a url with a ".js" suffix iff pid; therefore, we've got to trim it
-			url= (typeof moduleInfo.pid == "string" ? url.substring(0, url.length - 3) : url) + ext;
+			var textPlugin = bc.amdResources["dojo/text"],
+			moduleInfo = bc.getSrcModuleInfo(mid, referenceModule, true),
+			textResource = bc.resources[moduleInfo.url];
 
-			// fixup the moduleInfo to reflect type filetype extention
-			moduleInfo.url= url;
-			moduleInfo.mid+= ext;
-
-			var textResource= bc.resources[url];
-			if (!textResource) {
-				throw new Error("text resource (" + url + ") missing");
+			if (!textPlugin){
+				throw new Error("text! plugin missing");
 			}
-			if(bc.internStrings){
-				textResource.tag.noWrite= 0;
+			if (!textResource){
+				throw new Error("text resource (" + moduleInfo.url + ") missing");
 			}
-			return [textPlugin, makePluginPseudoModule(textResource, moduleInfo)];
-		};
 
-	return {
-		start:start
+			var result = [textPlugin];
+			if(bc.internStrings && !bc.internSkip(moduleInfo.mid, referenceModule)){
+				result.push({
+					module:textResource,
+					pid:moduleInfo.pid,
+					mid:moduleInfo.mid,
+					deps:[],
+					getText:function(){
+						var text = this.module.getText ? this.module.getText() : this.module.text;
+						if(text===undefined){
+							// the module likely did not go through the read transform; therefore, just read it manually
+							text= fs.readFileSync(this.module.src, "utf8");
+						}
+						return json.stringify(text+"");
+					},
+					internStrings:function(){
+						return ["url:" + this.mid, this.getText()];
+					}
+				});
+			}
+			return result;
+		}
 	};
 });
diff --git a/util/build/replace.js b/util/build/replace.js
index 7e26b79..29ae7fa 100644
--- a/util/build/replace.js
+++ b/util/build/replace.js
@@ -1,43 +1,43 @@
-define(["./fs"], function(fs) {
-	var cached= {};
+define(["./fs"], function(fs){
+	var cached = {};
 
-	return function(contents, replacement) {
-		var encoding= "utf8";
-		if (replacement instanceof Array) {
+	return function(contents, replacement){
+		var encoding = "utf8";
+		if(replacement instanceof Array){
 			// replacement is a vector of replacement instructions; maybe the first item is an encoding
-			if (typeof replacement[0]=="string") {
-				encoding= replacement[0];
-				replacement= replacement.slice(1);
+			if(typeof replacement[0]=="string"){
+				encoding = replacement[0];
+				replacement = replacement.slice(1);
 			}
-		} else {
+		}else{
 			// replacement is a single replacement [search, replacement, type] triple
-			replacement= [replacement];
+			replacement = [replacement];
 		}
 		// at this point, encoding has been determined and replacement is a vector of [search, replacement, type] triples
 
-		replacement.forEach(function(item) {
+		replacement.forEach(function(item){
 			var
-				searchText= item[0],
-				replacementText= item[1],
-				type= item[2];
-			if (type=="file") {
+				searchText = item[0],
+				replacementText = item[1],
+				type = item[2];
+			if(type=="file"){
 				// replacementText gives a filename that holds the replacement text
 				// TODO add type AMD module
-				replacementText= (cached[filename]= cached[filename] || fs.readFileSynch(replacementText, encoding));
+				replacementText = (cached[filename] = cached[filename] || fs.readFileSynch(replacementText, encoding));
 			}
-			if (searchText instanceof RegExp) {
-				contents= contents.replace(searchText, replacementText);
-			} else if (typeof searchText=="function") {
-				contents= searchText(contents);
-			} else {
+			if(searchText instanceof RegExp){
+				contents = contents.replace(searchText, replacementText);
+			}else if(typeof searchText=="function"){
+				contents = searchText(contents);
+			}else{
 				// replace all occurences of searchText with replacementText
 				var
-					searchTextLength= searchText.length,
-					replacementTextLength= replacementText.length,
-					start= contents.indexOf(searchText);
-				while (start!=-1) {
-					contents= contents.substring(0, start) + replacementText + contents.substring(start + searchTextLength);
-					start= contents.indexOf(searchText, start + replacementTextLength);
+					searchTextLength = searchText.length,
+					replacementTextLength = replacementText.length,
+					start = contents.indexOf(searchText);
+				while(start!=-1){
+					contents = contents.substring(0, start) + replacementText + contents.substring(start + searchTextLength);
+					start = contents.indexOf(searchText, start + replacementTextLength);
 				}
 			}
 		});
diff --git a/util/build/rhino/fs.js b/util/build/rhino/fs.js
index 5b8974c..e2fc760 100644
--- a/util/build/rhino/fs.js
+++ b/util/build/rhino/fs.js
@@ -1,20 +1,20 @@
 define([], function() {
 	var
-		readFileSync= function(filename, encoding) {
+		readFileSync = function(filename, encoding) {
 			if (encoding=="utf8") {
 				// convert node.js idiom to rhino idiom
-				encoding= "utf-8";
+				encoding = "utf-8";
 			}
 			return readFile(filename, encoding || "utf-8");
 		},
 
-		writeFileSync= function(filename, contents, encoding){
+		writeFileSync = function(filename, contents, encoding){
 			var
 				outFile = new java.io.File(filename),
 				outWriter;
 			if (encoding=="utf8") {
 				// convert node.js idiom to java idiom
-				encoding= "UTF-8";
+				encoding = "UTF-8";
 			}
 			if(encoding){
 				outWriter = new java.io.OutputStreamWriter(new java.io.FileOutputStream(outFile), encoding);
@@ -31,28 +31,28 @@ define([], function() {
 		};
 
 	return {
-		statSync: function(filename) {
+		statSync:function(filename) {
 			return new java.io.File(filename);
 		},
 
-		mkdirSync: function(filename) {
-			var dir= new java.io.File(filename);
+		mkdirSync:function(filename) {
+			var dir = new java.io.File(filename);
 			if (!dir.exists()) {
 				dir.mkdirs();
 			}
 		},
 
-		readFileSync: readFileSync,
+		readFileSync:readFileSync,
 
-		readdirSync: function(path) {
-			// java returns the complete path with each filename in listFiles; node returns just the filename
+		readdirSync:function(path) {
 			// the item+"" is necessary because item is a java object that doesn't have the substring method
-			var l= path.length + 1;
-			return (new java.io.File(path)).listFiles().map(function(item){ return (item+"").substring(l); });
+			return (new java.io.File(path)).listFiles().map(function(item){ return (item.name+""); });
 		},
 
-		readFile: function(filename, encoding, cb) {
-			var result= readFileSync(filename, encoding);
+
+
+		readFile:function(filename, encoding, cb) {
+			var result = readFileSync(filename, encoding);
 			if (cb) {
 				cb(0, result);
 			}
@@ -60,10 +60,10 @@ define([], function() {
 
 		writeFileSync:writeFileSync,
 
-		writeFile: function(filename, contents, encoding, cb) {
+		writeFile:function(filename, contents, encoding, cb) {
 			if (arguments.length==3 && typeof encoding!="string") {
-				cb= encoding;
-				encoding= 0;
+				cb = encoding;
+				encoding = 0;
 			}
 			writeFileSync(filename, contents, encoding);
 			if (cb) {
diff --git a/util/build/rhino/process.js b/util/build/rhino/process.js
index 17eef9c..af83923 100644
--- a/util/build/rhino/process.js
+++ b/util/build/rhino/process.js
@@ -14,14 +14,14 @@ define([], function() {
 
 		exec:function() {
 			// signature is (command, arg1, ..., argn, errorMessage, bc, callback)
-			for(var args= [], i= 0; i<arguments.length-3; i++){
+			for(var args = [], i = 0; i<arguments.length-3; i++){
 				args.push(arguments[i]);
 			}
 			var
-				errorMessage= arguments[i++],
-				bc= arguments[i++],
-				callback= arguments[i],
-				options= {output:""};
+				errorMessage = arguments[i++],
+				bc = arguments[i++],
+				callback = arguments[i],
+				options = {output:""};
 			args.push(options);
 			try{
 				runCommand.apply(this, args);
diff --git a/util/build/stringify.js b/util/build/stringify.js
index 41686fe..dfb71ee 100644
--- a/util/build/stringify.js
+++ b/util/build/stringify.js
@@ -1,22 +1,22 @@
-///
-// \amd-mid build/stringify
-//
-define(["dojo", "./buildControlBase"], function(dojo, bc) {
+define([
+	"dojo/json",
+	"./buildControlBase"
+], function(json, bc){
 var
-	spaces= "					 ",
-	indentFactor= 2,
+	spaces = "					 ",
+	indentFactor = 2,
 
-	setIndentFactor= function(factor) {
-		indentFactor= factor;
+	setIndentFactor = function(factor){
+		indentFactor = factor;
 	},
 
-	indent= function(n, factor) {
-		n= n * (factor || indentFactor);
-		while (spaces.length<n) spaces+= spaces;
+	indent = function(n, factor){
+		n = n * (factor || indentFactor);
+		while(spaces.length<n) spaces+= spaces;
 		return spaces.substring(0, n);
 	},
 
-	propName= function(name) {
+	propName = function(name){
 		return /^[\w\$]+$/.test(name) ?
 			name + ":" :
 			"'" + name + "':";
@@ -25,31 +25,31 @@ var
 	text,
 	unsolved,
 
-	split= function(
-			text //(string) Text to split into lines.
-		) {
-			///
-			// Split text into a vector lines as given by new-line indicators contained in text
-			///
-			// Three-step algorithm:
-			//	 * turn CR-LF or LF-CR into simple LF
-			//	 * turn lone CR into LF
-			//	 * then split on LF
-			//
-			// This should be platform-independent
-			return text.replace(/(\r\n)|(\n\r)/g, "\n").replace(/\r/, "\n").split("\n");
-		},
+	split = function(
+		text //(string) Text to split into lines.
+	){
+		///
+		// Split text into a vector lines as given by new-line indicators contained in text
+		///
+		// Three-step algorithm:
+		//	 * turn CR-LF or LF-CR into simple LF
+		//	 * turn lone CR into LF
+		//	 * then split on LF
+		//
+		// This should be platform-independent
+		return text.replace(/(\r\n)|(\n\r)/g, "\n").replace(/\r/, "\n").split("\n");
+	},
 
-	stringify= function(it, level) {
-		if (!level) {
-			text= "";
-			unsolved= false;
-			level= 1;
-		} else {
+	stringify = function(it, level){
+		if(!level){
+			text = "";
+			unsolved = false;
+			level = 1;
+		}else{
 			level++;
 		}
 		var temp, space, p, i, newline = bc.newline;
-		switch (typeof it) {
+		switch(typeof it){
 			case "undefined":
 				text+= "undefined";
 				break;
@@ -63,18 +63,18 @@ var
 				break;
 
 			case "string":
-				text+= dojo.toJson(it);
+				text+= json.stringify(it);
 				break;
 
 			case "object":
-				if (it===null) {
+				if(it===null){
 					text+= "null";
-				} else if (it instanceof RegExp) {
-					text+= RegExp.toString();
-				} else if (it instanceof Array) {
-					if (it.length>1) {
+				}else if(it instanceof RegExp){
+					text+= it.toString();
+				}else if(it instanceof Array){
+					if(it.length>1){
 						text+= "[" + newline;
-						for (i= 0; i<it.length-1; i++) {
+						for(i = 0; i<it.length-1; i++){
 							text+= indent(level);
 							stringify(it[i], level);
 							text+= "," + newline;
@@ -82,20 +82,20 @@ var
 						text+= indent(level);
 						stringify(it[i], level);
 						text+= newline + indent(level-1) + "]";
-					} else if (it.length) {
+					}else if(it.length){
 						text+= "[";
 						stringify(it[0], level);
 						text+= "]";
-					} else {
+					}else{
 						text+= "[]";
 					}
-				} else {
-					temp= [];
-					for (p in it) temp.push(p);
+				}else{
+					temp = [];
+					for(p in it) temp.push(p);
 					temp.sort();
-					if (temp.length>1) {
+					if(temp.length>1){
 						text+= "{" + newline;
-						for (i= 0; i<temp.length-1; i++) {
+						for(i = 0; i<temp.length-1; i++){
 							text+= indent(level) + propName(temp[i]);
 							stringify(it[temp[i]], level);
 							text+= "," + newline;
@@ -104,47 +104,47 @@ var
 						stringify(it[temp[i]], level);
 						text+= newline;
 						text+= indent(level-1) + "}";
-					} else if (temp.length) {
+					}else if(temp.length){
 						text+= "{" + propName(temp[0]);
 						stringify(it[temp[0]], level);
 						text+= "}";
-					} else {
+					}else{
 						text+= "{}";
 					}
 				}
 				break;
 
 			case "function":
-				space= indent(level);
+				space = indent(level);
 				// the V8 engine seems to strip the leading space from the first line of the function?!?
 				var
-					functionText= split(it.toString()),
-					firstLine= functionText.shift(),
-					minSpaces= Number.MAX_VALUE;
-				functionText.forEach(function(line) {
+					functionText = split(it.toString()),
+					firstLine = functionText.shift(),
+					minSpaces = Number.MAX_VALUE;
+				functionText.forEach(function(line){
 					// ignoring lines that have no non-space chars
-					var match= line.match(/(\s*)\S/);
-					if (match) minSpaces= Math.min(minSpaces, match[1].length);
+					var match = line.match(/(\s*)\S/);
+					if(match) minSpaces = Math.min(minSpaces, match[1].length);
 				});
-				if (minSpaces==Number.MAX_VALUE) {
+				if(minSpaces==Number.MAX_VALUE){
 					//every line started without any spaces and we never got a match
-					minSpaces= 0;
+					minSpaces = 0;
 				}
 				functionText.unshift(indent(minSpaces, 1) + firstLine);
 				//every line has at least minSpaces indentation...
-				text+= newline + functionText.map(function(line) { return space + line.substring(minSpaces); }).join(newline);
+				text+= newline + functionText.map(function(line){ return space + line.substring(minSpaces); }).join(newline);
 				break;
 
 			default:
 				text+= "undefined /* unsolved */";
-				unsolved= true;
+				unsolved = true;
 		}
-		text.unsolved= unsolved;
+		text.unsolved = unsolved;
 		return text;
 	};
 
-stringify.setIndentFactor= setIndentFactor;
-stringify.split= split;
+stringify.setIndentFactor = setIndentFactor;
+stringify.split = split;
 return stringify;
 
 });
diff --git a/util/build/transforms/copy.js b/util/build/transforms/copy.js
index 913bda3..d96b77b 100644
--- a/util/build/transforms/copy.js
+++ b/util/build/transforms/copy.js
@@ -1,12 +1,17 @@
-define(["../buildControl", "../process", "../fileUtils", "dojo/has"], function(bc, process, fileUtils, has) {
+define([
+	"../buildControl",
+	"../process",
+	"../fileUtils",
+	"dojo/has"
+], function(bc, process, fileUtils, has) {
 	return function(resource, callback) {
 		fileUtils.ensureDirectoryByFilename(resource.dest);
 		var
-			cb= function(code, text){
+			cb = function(code, text){
 				callback(resource, code);
 			},
-			errorMessage= "failed to copy file from \"" + resource.src + "\" to \"" + resource.dest + "\"",
-			args= has("is-windows") ?
+			errorMessage = "failed to copy file from \"" + resource.src + "\" to \"" + resource.dest + "\"",
+			args = has("is-windows") ?
 				["cmd", "/c", "copy", fileUtils.normalize(resource.src), fileUtils.normalize(resource.dest), errorMessage, bc, cb] :
 				["cp", resource.src, resource.dest, errorMessage, bc, cb];
 		process.exec.apply(process, args);
diff --git a/util/build/transforms/depsDeclarative.js b/util/build/transforms/depsDeclarative.js
new file mode 100644
index 0000000..001c8f8
--- /dev/null
+++ b/util/build/transforms/depsDeclarative.js
@@ -0,0 +1,93 @@
+define([
+	"../buildControl",
+	"../fs",
+	"../fileUtils",
+	"dojo/_base/lang",
+	"dojo/_base/json"
+], function(bc, fs, fileUtils, lang, json){
+	return function(resource){
+		var
+			// Array of MIDs discovered in the declarative resource
+			aggregateDeps = [],
+
+			// Looks for "data-dojo-type" and "data-dojo-mids" for declarative modules
+			interningAutoRequireRegExp = /\sdata-dojo-(?:type|mids)\s*=\s*["']([^"']+\/[^"']+)["']/gi,
+
+			// Looks for '<script type="dojo/require">' blocks
+			interningDeclarativeRequireRegExp = /<script\s+[^>]*type=["']dojo\/require["'][^>]*>([^<]*)<\/script>/gi,
+
+			processAutoRequire = function(){
+				// Parses the resource for any MIDs that might need to be built into the layer
+				var mids = [],
+					str = resource.text,
+					match;
+
+				// Run the RegExp over the text
+				while(match = interningAutoRequireRegExp.exec(str)){
+					match[1].split(/\s*,\s*/).forEach(function(mid){
+						mids.push(mid);
+					});
+				}
+
+				return mids;
+			},
+
+			processDeclarativeRequire = function(){
+				// Parses the resource for and declarative require script blocks and
+				// analyses the bocks for their MIDs to be included in the layer.
+				var mids = [],
+					str = resource.text,
+					match;
+
+				while(match = interningDeclarativeRequireRegExp.exec(str)){
+					// Try and convert <script type="dojo/require"> into object
+					try{
+						var h = json.fromJson("{" + match[1] + "}");
+					}catch(e){
+						bc.log("declarativeRequireFailed", ["resource", resource.src, "error", e]);
+					}
+					// Cycle through each key and add module as dependency
+					for(var i in h){
+						var mid = h[i];
+						if(typeof mid == "string"){
+							mids.push(mid);
+						}else{
+							bc.log("userWarn", ["declarative require has invalid value", "resource", resource.src, "key", i, "value", mid]);
+						}
+					}
+				}
+
+				return mids;
+			};
+
+		// Intern the resources strings and identify any mids used in declarative syntax
+		aggregateDeps = aggregateDeps.concat(processAutoRequire());
+		
+		// Intern the resources strings and identify any declarative require script blocs and parse out the mids
+		aggregateDeps = aggregateDeps.concat(processDeclarativeRequire());
+
+
+		// Iterate through the layers, identify those that contain this resource.mid, 
+		// remove it from the include array and then add this resource's includes
+		for(var mid in bc.amdResources){
+			if(bc.amdResources[mid].layer){ // This resource is a layer
+				var includes = bc.amdResources[mid].layer.include,
+					idx = includes.indexOf(resource.mid);
+				// Bitwise operator that returns true if the layer contains this resource
+				if(~idx){
+					// Remove this resources mid from the layer's include array
+					includes.splice(idx, 1);
+					aggregateDeps.forEach(function(dep){
+						// Uniquely add appropriate mids to the layer's include array
+						if(!(/^(require|exports|module)$/.test(dep))){
+							if(!~includes.indexOf(dep)){
+								includes.push(dep);
+							}
+						}
+					});
+				}
+			}
+		}
+
+	};
+});
\ No newline at end of file
diff --git a/util/build/transforms/depsDump.js b/util/build/transforms/depsDump.js
index b7a8e6d..048d16e 100644
--- a/util/build/transforms/depsDump.js
+++ b/util/build/transforms/depsDump.js
@@ -34,7 +34,7 @@ define([
 						if (dotModules[module.mid]!==traceForDotDone){
 							dotModules[module.mid] = traceForDot;
 						}
-	 				});
+					});
 				}
 				r.uid = i;
 				midToId[bc.resources[p].mid] = i;
@@ -58,7 +58,7 @@ define([
 								if (dotModules[module.mid]!==traceForDotDone){
 									dotModules[module.mid] = traceForDot;
 								}
-	 						});
+							});
 						}
 					}
 				}
diff --git a/util/build/transforms/depsScan.js b/util/build/transforms/depsScan.js
index d43ef72..b6d4b31 100644
--- a/util/build/transforms/depsScan.js
+++ b/util/build/transforms/depsScan.js
@@ -1,7 +1,17 @@
-define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo/json", "dojo/_base/lang", "dojo/_base/loader", "../fs"],
-	function(require, bc, fileUtils, removeComments, json, lang, syncLoader, fs) {
-	return function(resource) {
+define([
+	"require",
+	"../buildControl",
+	"../fileUtils",
+	"../removeComments",
+	"dojo/json",
+	"dojo/_base/lang",
+	"dojo/_base/loader",
+	"../fs"
+], function(require, bc, fileUtils, removeComments, json, lang, syncLoader, fs){
+	return function(resource){
 		var
+			newline = bc.newline,
+
 			mix = function(dest, src){
 				dest = dest || {};
 				for(var p in src){
@@ -16,46 +26,52 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 
 			defineApplied = 0,
 
-			simulatedDefine= function(mid, dependencies, factory) {
+			simulatedDefine = function(mid, dependencies, factory){
 				defineApplied = 1;
-				var
-					arity = arguments.length,
+				var arity = arguments.length,
 					args = 0,
 					defaultDeps = ["require", "exports", "module"];
 
 				// TODO: add the factory scan?
-				if (0) {
-					if (arity==1) {
-						dependencies= [];
-						mid.toString()
-							.replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "")
-							.replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function (match, dep) {
-								dependencies.push(dep);
-							});
-						args= [0, defaultDeps.concat(dependencies), mid];
-					}
+				if(bc.factoryScan && arity == 1 && typeof mid === 'function'){
+					dependencies = [];
+					mid.toString()
+						.replace(/(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, "")
+						.replace(/require\(["']([\w\!\-_\.\/]+)["']\)/g, function(match, dep){
+							dependencies.push(dep);
+						});
+					args = [0, defaultDeps.concat(dependencies), mid];
+					resource.text = resource.text.replace(/define\s*\(/, 'define(["' + args[1].join('","') + '"],');
 				}
-				if (!args) {
-					args= arity==1 ? [0, defaultDeps, mid] :
-						(arity==2 ? (mid instanceof Array ? [0, mid, dependencies] : [mid, defaultDeps, dependencies]) :
+
+				if(!args){
+					args = arity == 1 ? [0, defaultDeps, mid] :
+						(arity == 2 ? (mid instanceof Array ? [0, mid, dependencies] : [mid, defaultDeps, dependencies]) :
 							[mid, dependencies, factory]);
 				}
 
-				if(args[1].some(function(item){return !lang.isString(item);})){
+				if(args[1].some(function(item){
+					return !lang.isString(item);
+				})){
 					throw new Error("define dependency vector contains elements that are not of type string.");
 				}
 
 				absMid = args[0];
-				aggregateDeps= aggregateDeps.concat(args[1]);
+				aggregateDeps = aggregateDeps.concat(args[1]);
+			},
+
+			_tag_simulatedDefine = simulatedDefine.amd = {
+				vendor:"dojotoolkit.org",
+				context:"build"
 			},
 
-			simulatedRequire= function(depsOrConfig, callbackOrDeps) {
+			simulatedRequire = function(depsOrConfig, callbackOrDeps){
 				// add contents of deps vector to aggregateDeps iff it contains no relative ids; do not process deps property in config
 				var hasRelativeIds = function(deps){ return deps.some(function(item){ return /^\./.test(item); }); };
-				if (lang.isArray(depsOrConfig) && !hasRelativeIds(depsOrConfig)){
-					aggregateDeps= aggregateDeps.concat(depsOrConfig);
-				} else if(lang.isArray(callbackOrDeps) && !hasRelativeIds(callbackOrDeps)){
-					aggregateDeps= aggregateDeps.concat(callbackOrDeps);
+				if(lang.isArray(depsOrConfig) && !hasRelativeIds(depsOrConfig)){
+					aggregateDeps = aggregateDeps.concat(depsOrConfig);
+				}else if(lang.isArray(callbackOrDeps) && !hasRelativeIds(callbackOrDeps)){
+					aggregateDeps = aggregateDeps.concat(callbackOrDeps);
 				}
 			},
 
@@ -78,16 +94,16 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 			simulatedDojo =
 				// the dojo legacy loader API
 				{
-					require:function(moduleName, omitModuleCheck) {
+					require:function(moduleName, omitModuleCheck){
 						dojoRequires.push(slashName(moduleName));
 					},
-					provide:function(moduleName) {
+					provide:function(moduleName){
 						dojoProvides.push(slashName(moduleName));
 					},
-					requireLocalization: function(moduleName, bundleName, locale) {
+					requireLocalization: function(moduleName, bundleName, locale){
 						aggregateDeps.push("dojo/i18n!" + slashName(moduleName) + "/nls/" + (!locale || /root/i.test(locale) ? "" : locale + "/") + slashName(bundleName));
 					},
-					platformRequire:function(modMap) {
+					platformRequire:function(modMap){
 						pluginStrategyRequired = 1;
 						(modMap.common || []).concat((bc.platform && modMap[bc.platform]) || []).forEach(function(item){
 							dojoRequires.push(lang.isArray(item) ? slashName(item[0]) : slashName(item));
@@ -97,11 +113,11 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 						pluginStrategyRequired = 1;
 						callback();
 					},
-					requireIf:function(expr, moduleName, omitModuleCheck) {
+					requireIf:function(expr, moduleName, omitModuleCheck){
 						pluginStrategyRequired = 1;
 						expr && dojoRequires.push(slashName(moduleName));
 					},
-					requireAfterIf:function(expr, moduleName, omitModuleCheck) {
+					requireAfterIf:function(expr, moduleName, omitModuleCheck){
 						pluginStrategyRequired = 1;
 						expr && dojoRequires.push(slashName(moduleName));
 					}
@@ -152,13 +168,13 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 			getAmdModule = function(
 				mid,
 				referenceModule
-			) {
-				var match= mid.match(/^([^\!]+)\!(.*)$/);
-				if (match) {
+			){
+				var match = mid.match(/^([^\!]+)\!(.*)$/);
+				if(match){
 					var pluginModuleInfo = bc.getSrcModuleInfo(match[1], referenceModule),
-						pluginModule = pluginModuleInfo &&  bc.amdResources[pluginModuleInfo.mid],
-						pluginId= pluginModule && pluginModule.mid,
-						pluginProc= bc.plugins[pluginId];
+						pluginModule = pluginModuleInfo &&	bc.amdResources[pluginModuleInfo.mid],
+						pluginId = pluginModule && pluginModule.mid,
+						pluginProc = bc.plugins[pluginId];
 					if(!pluginModule){
 						return 0;
 					}else if(!pluginProc){
@@ -169,14 +185,14 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 					}else{
 						return pluginProc.start(match[2], referenceModule, bc);
 					}
-				} else {
-					var moduleInfo= bc.getSrcModuleInfo(mid, referenceModule),
-						module= moduleInfo && bc.amdResources[moduleInfo.mid];
+				}else{
+					var moduleInfo = bc.getSrcModuleInfo(mid, referenceModule),
+						module = moduleInfo && bc.amdResources[moduleInfo.mid];
 					return module;
 				}
 			},
 
-			tagAbsMid = function(){
+			tagAbsMid = function(absMid){
 				if(absMid && absMid!=resource.mid){
 					bc.log("amdInconsistentMid", ["module", resource.mid, "specified", absMid]);
 				}
@@ -185,22 +201,22 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 				}
 			},
 
-			processPureAmdModule= function() {
+			processPureAmdModule = function(){
 				// find the dependencies for this resource using the fast path if the module says it's OK
 				// pure AMD says the module can be executed in the build environment
 				// note: the user can provide a build environment with TODO
-				try {
+				try{
 					if(resource.mid!="dojo/_base/loader" && /dojo\.(require|provide)\s*\(/.test(removeComments(resource.text))){
 						bc.log("amdPureContainedLegacyApi", ["module", resource.mid]);
 					}
 					(new Function("define", "require", resource.text))(simulatedDefine, simulatedRequire);
-					tagAbsMid();
-				} catch (e) {
+					tagAbsMid(absMid);
+				}catch (e){
 					bc.log("amdFailedEval", ["module", resource.mid, "error", e]);
 				}
 			},
 
-			convertToStrings= function(text){
+			convertToStrings = function(text){
 				var strings = [],
 
 					// a DFA, the states...
@@ -217,7 +233,7 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 								return spaces;
 							}
 							if(c=="'" || c=='"'){
-								quoteType= c;
+								quoteType = c;
 								current = "";
 								return string;
 							}
@@ -254,7 +270,7 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 					quoteType, current;
 
 
-				for (var i= 0; i<text.length; i++){
+				for(var i = 0; i<text.length; i++){
 					state = dfa[state](text.charAt(i));
 					if(state==error){
 						return 0;
@@ -266,7 +282,7 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 				return 0;
 			},
 
-			processPossibleAmdWithRegExs= function(text) {
+			processPossibleAmdWithRegExs = function(text){
 				// look for AMD define and/or require; require must not have relative mids; require signature with config argument is not discovered
 				// (remember, a config could have a string or regex that could have an unmatched right "}", so there is not way to guarantee we can find the correct
 				// end of the config arg without parsing)
@@ -284,36 +300,36 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 						//	'define("test", ["test1"])',
 						//	'define("test", ["test1", "test2"])',
 						//	'define(["test1"])',
- 						//	'define(["test1", "test2"])',
+						//	'define(["test1", "test2"])',
 						//	'define("test", ["test1"], function(test){ hello;})',
 						//	'define("test", function(test){ hello;})',
 						//	'define(["test1"], function(test){ hello;})',
 						//	'define(function(test){ hello;})',
 						//	'define({a:1})'
 						// ]
-					    //                    2                   3      4                5
+						//					  2					  3		 4				  5
 						/(^|\s)define\s*\(\s*(["'][^'"]+['"])?\s*(,)?\s*(\[[^\]]*?\])?\s*(,)?/g,
 
 					result;
-				while((result= defineExp.exec(text)) != null) {
-					try {
+				while((result = defineExp.exec(text)) != null){
+					try{
 						if(result[2]){
 							// first arg a string
 							if(result[3]){
 								// first arg a module id
 								if(result[5]){
 									// (mid, deps, <factory>)
-									result= result[0] + "{})";
+									result = result[0] + "{})";
 								}else if(result[4]){
 									// (mid, <factory:array value>)
 									result = result[0] + ")";
-								}else {
+								}else{
 									// (mid, <factory>)
 									result = result[0] + "{})";
 								}
 							}else{
 								// (<factory:string-value>)
-								result= result[0]  + ")";
+								result = result[0]	+ ")";
 							}
 						}else if(result[4]){
 							// first arg an array
@@ -330,8 +346,8 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 						}
 						amdCallCount++;
 						(new Function("define", result))(simulatedDefine);
-						tagAbsMid();
-					} catch (e) {
+						tagAbsMid(absMid);
+					}catch(e){
 						amdCallCount--;
 						bc.log("amdFailedDefineEval", ["module", resource.mid, "text", result, "error", e]);
 					}
@@ -340,102 +356,105 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 				var requireExp=
 						// look for require applications with an array for the first arg; notice the regex stops after the first arg and config signature is not processed
 						/(^|\s)require\s*\(\s*\[([^\]]*?)\]/g;
-				while((result= requireExp.exec(text)) != null) {
+				while((result = requireExp.exec(text)) != null){
 					var mids = convertToStrings(result[2]);
 					if(mids){
 						amdCallCount++;
-						aggregateDeps= aggregateDeps.concat(mids.filter(function(item){return item.charAt(0)!=".";}));
+						aggregateDeps = aggregateDeps.concat(mids.filter(function(item){return item.charAt(0)!=".";}));
 					}
 				}
 				return amdCallCount;
 			},
 
-			amdBundle= {},
-
-			syncBundle= {},
-
-			evalNlsResource= function(text){
+			evalNlsResource = function(resource){
+				var bundleValue = 0;
 				try{
+					function simulatedDefine(a1, a2){
+						if(lang.isString(a1) && lang.isObject(a2)){
+							tagAbsMid(a1);
+							bundleValue = a2;
+						}else if(lang.isObject(a1)){
+							bundleValue = a1;
+						}
+					}
 					(new Function("define", resource.text))(simulatedDefine);
-					if(defineApplied){
-						return amdBundle;
+					if(bundleValue){
+						resource.bundleValue = bundleValue;
+						resource.bundleType = "amd";
+						return;
 					}
 				}catch(e){
+					// TODO: consider a profile flag to cause errors to be logged
 				}
 				try{
-					var result= eval("(" + text + ")");
-					if(lang.isObject(result)){
-						return syncBundle;
+					bundleValue = (new Function("return " + resource.text + ";"))();
+					if(lang.isObject(bundleValue)){
+						resource.bundleValue = bundleValue;
+						resource.bundleType = "legacy";
+						return;
 					}
 				}catch(e){
+					// TODO: consider a profile flag to cause errors to be logged
+				}
+
+				// if not building flattened layer bundles, then it's not necessary for the bundle
+				// to be evaluable; still run processPureAmdModule to compute possible dependencies
+				processPureAmdModule();
+				if(!defineApplied){
+					bc.log("i18nImproperBundle", ["module", resource.mid]);
 				}
-				return 0;
 			},
 
 			processNlsBundle = function(){
 				// either a v1.x sync bundle or an AMD NLS bundle
 
 				// compute and remember the set of localized bundles; attach this info to the root bundle
-				var
-					match= resource.mid.match(/(^.*\/nls\/)(([^\/]+)\/)?([^\/]+)$/),
-					prefix= resource.prefix = match[1],
-					locale= resource.locale = match[3],
-					bundle= resource.bundle = match[4],
-					rootPath= prefix + bundle,
-					rootBundle= bc.amdResources[rootPath];
-				if(locale){
-					if(rootBundle){
-						var localizedSet= rootBundle.localizedSet || (rootBundle.localizedSet= {});
-						localizedSet[locale]= 1;
-					}else{
-						bc.log("i18nNoRoot" ["bundle", resource.mid]);
-					}
+				var match = resource.mid.match(/(^.*\/nls\/)(([^\/]+)\/)?([^\/]+)$/),
+					prefix = resource.prefix = match[1],
+					locale = resource.locale = match[3],
+					bundle = resource.bundle = match[4],
+					rootPath = prefix + bundle,
+					rootBundle = bc.amdResources[rootPath];
+
+				// if not root, don't process any localized bundles; a missing root bundle serves as a signal
+				// to other transforms (e.g., writeAmd) to ignore this bundle family
+				if(!rootBundle){
+					bc.log("i18nNoRoot", ["bundle", resource.mid]);
+					return;
+				}
+				// accumulate all the localized versions in the root bundle
+				if(!rootBundle.localizedSet){
+					rootBundle.localizedSet = {};
 				}
 
-				var nlsResult= evalNlsResource(resource.text);
-				if(nlsResult===syncBundle){
-					// transform a 1.6- bundle into and AMD-style bundle
-					var getText= resource.getText;
-					resource.getText= function(){
-						var text= getText.call(this),
-						newline = bc.newline;
-
-						// this is frome the old builder...
-						// TODO: consider removing this
-						// If this is an nls bundle, make sure it does not end in a ; Otherwise, bad things happen.
-						if(text.match(/\/nls\//)){
-							text = text.replace(/;\s*$/, "");
-						}
+				// try to compute the value of the bundle; sets properties bundleValue and bundleType
+				evalNlsResource(resource);
 
-						if(this.localizedSet){
-							// this is the root bundle
-							var availableLocales= [];
-							for(var p in this.localizedSet){
-								availableLocales.push("\"" + p + "\":1");
-							}
-							text = "define({root:" + newline + text + "," + newline + availableLocales.join("," + newline) + "}" + newline + ");" + newline;
-						}else{
-							text = "define(" + newline + text + newline + ");";
-						}
-						return resource.setText(text);
-					};
-				}else if(nlsResult===amdBundle){
-					processPureAmdModule();
-				}else{
-					bc.log("i18nImproperBundle", ["module", resource.mid]);
+				if((bc.localeList || resource.bundleType=="legacy") && !resource.bundleValue){
+					// profile is building flattened layer bundles or converting a legacy-style bundle
+					// to an AMD-style bundle; either way, we need the value of the bundle
+					bc.log("i18nUnevaluableBundle", ["module", resource.mid]);
+				}
+
+				if(resource.bundleType=="legacy" && resource===rootBundle && resource.bundleValue){
+					resource.bundleValue = {root:resource.bundleValue};
+				}
+
+				if(resource!==rootBundle){
+					rootBundle.localizedSet[locale] = resource;
 				}
 			},
 
 			interningDojoUriRegExpString =
 				// the following is a direct copy from the v1.6- build util; this is so janky, we dare not touch
-				//23                                 4                5                                                     6                      78                   9                         0           1
+				//23								 4				  5														6					   78					9						  0			  1
 				"(((templatePath|templateCssPath)\\s*(=|:)\\s*)dojo\\.(module)?Url\\(|dojo\\.cache\\s*\\(\\s*)\\s*?[\\\"\\']([\\w\\.\\/]+)[\\\"\\'](([\\,\\s]*)[\\\"\\']([\\w\\.\\/-]*)[\\\"\\'])?(\\s*,\\s*)?([^\\)]*)?\\s*\\)",
 
 			interningGlobalDojoUriRegExp = new RegExp(interningDojoUriRegExpString, "g"),
 
 			interningLocalDojoUriRegExp = new RegExp(interningDojoUriRegExpString),
 
-			internStrings = function(){
+			internStrings = function() {
 				var getText = function(src){
 						return fs.readFileSync(src, "utf8");
 					},
@@ -448,8 +467,7 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 					var parts = matchString.match(interningLocalDojoUriRegExp);
 
 					var textModuleInfo = bc.getSrcModuleInfo(fileUtils.catPath(parts[6].replace(/\./g, "/"), parts[9]), 0, true);
-					if(bc.internStringsSkipList[textModuleInfo.mid]){
-						skipping.push(textModuleInfo.url);
+					if(bc.internSkip(textModuleInfo.mid, resource)){
 						return matchString;
 					}
 
@@ -491,25 +509,27 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 						return matchString;
 					}
 				});
-				var logArgs = ["module", resource.mid];
-				if(skipping.length){
-					logArgs.push("skipping", skipping);
-				}
-				if(notFound.length){
-					logArgs.push("not found", notFound);
-				}
-				if(nothing.length){
-					logArgs.push("nothing to intern", nothing);
+				if(skipping.length || notFound.length || nothing.length){
+					var logArgs = ["module", resource.mid];
+					if(skipping.length){
+						logArgs.push("skipping", skipping);
+					}
+					if(notFound.length){
+						logArgs.push("not found", notFound);
+					}
+					if(nothing.length){
+						logArgs.push("nothing to intern", nothing);
+					}
+					bc.log("internStrings", logArgs);
 				}
-				bc.log("internStrings", logArgs);
 			},
 
-			processWithRegExs = function() {
+			processWithRegExs = function(){
 				// try to figure out if the module is legacy or AMD and then process the loader applications found
 				//
-				// Warning: the process is flawed because regexs will find things that are not there and miss things that are
-				// there is no way around this without a proper parser.  Note however, this kind of process has been in use
-				// with the v1.x build system for a long time.
+				// Warning: the process is flawed because regexs will find things that are not there and miss things that are,
+				// and there is no way around this without a proper parser.	 Note however, this kind of process has been in use
+				// with the v1.x build system from the beginning.
 				//
 				// TODO: replace this process with a parser
 				//
@@ -519,9 +539,7 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 					internStrings();
 				}
 
-				var newline = bc.newline,
-
-					text =
+				var text =
 						// apply any replacements before processing
 						resource.getText(),
 
@@ -530,8 +548,8 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 
 					extractResult =
 						// a vector of legacy loader API applications as pairs of [function-name, complete-function-application-text] + the following two properties
-						//   * text: the original text with all dojo.loadInit applications preceeded by 0 &&, thereby causing those applications to be discarded by the minifier
-						//   * extractText: all legacy loader applications, with all dojo.loadInit applications moved to the beginning
+						//	 * text: the original text with all dojo.loadInit applications preceeded by 0 &&, thereby causing those applications to be discarded by the minifier
+						//	 * extractText: all legacy loader applications, with all dojo.loadInit applications moved to the beginning
 						// See dojo.js
 						syncLoader.extractLegacyApiApplications(text, removeComments(text));
 				if(!extractResult.extractText && processPossibleAmdWithRegExs(removeComments(text))){
@@ -550,12 +568,12 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 				applyLegacyCalls(extractResult[2]);
 
 				// check for multiple or irrational dojo.provides
-				if (dojoProvides.length) {
-					if (dojoProvides.length>1) {
+				if(dojoProvides.length){
+					if(dojoProvides.length>1){
 						bc.log("legacyMultipleProvides", ["module", resource.mid, "provides", dojoProvides]);
 					}
-					dojoProvides.forEach(function(item) {
-						if (item.replace(/\./g, "/")!=resource.mid) {
+					dojoProvides.forEach(function(item){
+						if(item.replace(/\./g, "/")!=resource.mid){
 							bc.log("legacyImproperProvide", ["module", resource.mid, "provide", item]);
 						}
 					});
@@ -574,14 +592,14 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 						"\tdef:function(" + names.join(",") + "){" + newline + extractResult[1] + "}" + newline +
 						"});" + newline;
 					mid = resource.mid + "-loadInit";
-					pluginResource = mix({}, mix(resource, {
+					pluginResource = mix(mix({}, resource), {
 						src:resource.src.substring(0, resource.src.length-3) + "-loadInit.js",
 						dest:bc.getDestModuleInfo(mid).url,
 						mid:mid,
-						tag: {loadInitResource:1},
+						tag:{loadInitResource:1},
 						deps:[],
-						getText:function() { return pluginText; }
-					}));
+						getText:function(){ return pluginText; }
+					});
 					bc.start(pluginResource);
 
 					pluginResourceId = "dojo/loadInit!" + mid;
@@ -597,27 +615,27 @@ define(["require", "../buildControl", "../fileUtils", "../removeComments", "dojo
 		// scan the resource for dependencies
 		if(resource.tag.nls){
 			processNlsBundle();
-		}else if(resource.tag.amd || /\/\/>>\s*pure-amd/.test(resource.text)) {
+		}else if(resource.tag.amd || /\/\/>>\s*pure-amd/.test(resource.text)){
 			processPureAmdModule();
 		}else{
 			processWithRegExs();
 		}
 
 		// resolve the dependencies into modules
-		var deps= resource.deps;
+		var deps = resource.deps;
 		resource.aggregateDeps = aggregateDeps;
-		aggregateDeps.forEach(function(dep) {
-			if (!(/^(require|exports|module)$/.test(dep))) {
-				try {
-					var module= getAmdModule(dep, resource);
-					if (lang.isArray(module)) {
+		aggregateDeps.forEach(function(dep){
+			if(!(/^(require|exports|module)$/.test(dep))){
+				try{
+					var module = getAmdModule(dep, resource);
+					if(lang.isArray(module)){
 						module.forEach(function(module){ deps.push(module); });
-					} else if (module) {
+					}else if(module){
 						deps.push(module);
-					} else {
+					}else{
 						bc.log("amdMissingDependency", ["module", resource.mid, "dependency", dep]);
 					}
-				} catch (e) {
+				}catch(e){
 					bc.log("amdMissingDependency", ["module", resource.mid, "dependency", dep, "error", e]);
 				}
 			}
diff --git a/util/build/transforms/dojoReport.js b/util/build/transforms/dojoReport.js
index f6466a4..b78ea28 100644
--- a/util/build/transforms/dojoReport.js
+++ b/util/build/transforms/dojoReport.js
@@ -1,4 +1,8 @@
-define(["../buildControl", "../version", "../fileUtils"], function(bc, version, fileUtils) {
+define([
+	"../buildControl",
+	"../version",
+	"../fileUtils"
+], function(bc, version, fileUtils) {
 	var dir = bc.buildReportDir || ".",
 		filename = bc.buildReportFilename || "build-report.txt";
 
diff --git a/util/build/transforms/hasFindAll.js b/util/build/transforms/hasFindAll.js
index 626385f..0815887 100644
--- a/util/build/transforms/hasFindAll.js
+++ b/util/build/transforms/hasFindAll.js
@@ -1,18 +1,18 @@
 define(["../buildControl"], function(bc) {
-	return function(resource) {
-		if (resource.hasTest) {
+	return function(resource){
+		if(resource.hasTest){
 			return 0;
 		}
 		var
-			hasFeatures= bc.hasFeatures= bc.hasFeatures || {},
-			text= resource.text,
-			hasRe= /[^\w\.]has\s*\(\s*["']([^"']+)["']\s*\)/g,
+			hasFeatures = bc.hasFeatures = bc.hasFeatures || {},
+			text = resource.text,
+			hasRe = /[^\w\.]has\s*\(\s*["']([^"']+)["']\s*\)/g,
 			result;
-		while ((result= hasRe.exec(text)) != null) {
+		while((result = hasRe.exec(text)) != null){
 			var
-				featureName= result[1],
-				sourceSet= hasFeatures[featureName]= hasFeatures[featureName] || {};
-			sourceSet[resource.mid]= 1;
+				featureName = result[1],
+				sourceSet = hasFeatures[featureName] = hasFeatures[featureName] || {};
+			sourceSet[resource.mid] = 1;
 		}
 		return 0;
 	};
diff --git a/util/build/transforms/hasFixup.js b/util/build/transforms/hasFixup.js
index 0804845..31c89e5 100644
--- a/util/build/transforms/hasFixup.js
+++ b/util/build/transforms/hasFixup.js
@@ -1,46 +1,127 @@
-define(["../buildControl"], function(bc) {
-	var
-		mappedNames= 0,
+define(["../buildControl"], function(bc){
+	//
+	// For and feature, "x", in bc.staticHasFeatures, replace the string has("x") with the value as provided by bc.staticHasFeatures.
+	//
+	// For example, consider the following code
+	//
+	// if(has("feature-a")){
+	//   //...
+	// }
+	//
+	// if(has("feature-b")>=7){
+	//   //...
+	// }
+	//
+	// if(has("feature-c")){
+	//   //...
+	// }
+	//
+	// if(has("feature-d")){
+	//   //...
+	// }
+	//
+	// if(has("feature-e")=="goodbye"){
+	//   //...
+	// }
+	//
+	// Then, given bc.staticHasFeatures of
+	//
+	//   {
+	//		"feature-a":undefined,
+	//		"feature-b":7,
+	//		"feature-c":true,
+	//		"feature-d":false,
+	//		"feature-e":"'hello, world'"
+	//   }
+	//
+	// The source is modified as follows:
+	// if(undefined){
+	//   //...
+	// }
+	//
+	// if(7>=7){
+	//   //...
+	// }
+	//
+	// if(true){
+	//   //...
+	// }
+	//
+	// if(false){
+	//   //...
+	// }
+	//
+	// if('hello, world'=="goodbye"){
+	//   //...
+	// }
+	//
+	// Recall that has.add has a now parameter that causes the test to be executed immediately and return the value.
+	// If a static has value is truthy, then using || causes the first truthy operand to be returned...the truthy static value.
+	// If a static value is falsy, then using && causes the first falsy operand to be returned...the falsy static value.
+	//
+	// For example:
+	//
+	// if(has.add("feature-a", function(global, doc, element){
+	//   //some really long, painful has test
+	// }, true)){
+	//   //...
+	// }
+	//
+	// Consider static has values for feature-a of undefined, 7, true, false, "'hello, world'"
+	//
+	//
+	// if(undefined && has.add("feature-a", function(global, doc, element){ // NOTE: the value of the if conditional is static undefined
+	//   //some really long, painful has test
+	// }, true)){
+	//   //...
+	// }
+	//
+	// if(7 || has.add("feature-a", function(global, doc, element){ // NOTE: the value of the if conditional is static 7
+	//   //some really long, painful has test
+	// }, true)){
+	//   //...
+	// }
+	//
+	// if(true || has.add("feature-a", function(global, doc, element){ // NOTE: the value of the if conditional is static true
+	//   //some really long, painful has test
+	// }, true)){
+	//   //...
+	// }
+	//
+	// if(false && has.add("feature-a", function(global, doc, element){ // NOTE: the value of the if conditional is static false
+	//   //some really long, painful has test
+	// }, true)){
+	//   //...
+	// }
+	//
+	// if('hello, world' || has.add("feature-a", function(global, doc, element){ // NOTE: the value of the if conditional is static 'hello, world'
+	//   //some really long, painful has test
+	// }, true)){
+	//   //...
+	// }
+	//
+	// This technique is employed to avoid attempting to parse and find the boundaries of "some really long painful has test" with regexs.
+	// Instead, this is left to an optimizer like the the closure compiler or uglify etc.
 
-		mapNames= function() {
-			mappedNames= {};
-			var id= 2;
-			for (var p in bc.hasFeatures) {
-				if (typeof bc.staticHasFeatures[p]!="undefined") {
-					mappedNames[p]= bc.staticHasFeatures[p] ? 1 : 0;
-				} else {
-					//mappedNames[p]= id++;
-					mappedNames[p]= '"' + p + '"';
-				}
-			}
-		};
-
-	return function(resource) {
-		if (!mappedNames) {
-			mapNames();
-		}
+	function stringifyString(s){
+		return typeof s === "string" ? '"' + s + '"' : s;
+	}
 
-		var result= resource.text.replace(/([^\w\.])has\s*\(\s*["']([^'"]+)["']\s*\)/g, function(match, prefix, featureName) {
-			var value= mappedNames[featureName];
-			if (value==1 || value==0) {
-				return prefix + mappedNames[featureName] + "";
-			} else {
-				return prefix + "has(" + value + ")";
+	return function(resource){
+		resource.text = resource.text.replace(/([^\w\.])has\s*\(\s*["']([^'"]+)["']\s*\)/g, function(match, prefix, featureName){
+			if(featureName in bc.staticHasFeatures){
+				return prefix + " " + bc.staticHasFeatures[featureName] + " ";
+			}else{
+				return match;
 			}
-		});
-
-		result= result.replace(/(has.add\s*\(\s*)["']([^'"]+)["']/g, function(match, prefix, featureName) {
-			if (mappedNames[featureName]<2) {
-				return (mappedNames[featureName]==0 ? "false && " : "true || ") + match;
-			} else if(mappedNames[featureName]!==undefined) {
-				return prefix + mappedNames[featureName];
-			} else {
+		}).replace(/([^\w\.])((has.add\s*\(\s*)["']([^'"]+)["'])/g, function(match, prefix, hasAdd, notUsed, featureName){
+			if(featureName in bc.staticHasFeatures){
+				return prefix + " " + stringifyString(bc.staticHasFeatures[featureName]) + (bc.staticHasFeatures[featureName] ? " || " : " && " ) + hasAdd;
+			}else{
 				return match;
 			}
 		});
-
-		resource.text= result;
-
 		return 0;
 	};
+
 });
diff --git a/util/build/transforms/hasReport.js b/util/build/transforms/hasReport.js
index 5760dd7..fdfc84d 100644
--- a/util/build/transforms/hasReport.js
+++ b/util/build/transforms/hasReport.js
@@ -1,25 +1,26 @@
-define(["../buildControl", "../stringify"], function(bc, stringify) {
-	return function() {
+define(["../buildControl", "../stringify"], function(bc, stringify){
+	return function(){
 		if(bc.hasReport){
-			var
-				p,
+			var p,
 				features= bc.hasFeatures,
 				sorted= [];
-			for (p in features) {
-				if (1 || !(p in bc.staticHasFeatures)) sorted.push([[p], features[p]]);
+			for(p in features){
+				if(1 || !(p in bc.staticHasFeatures)) {
+					sorted.push([[p], features[p]]);
+				}
 			}
 			sorted.sort(function(lhs, rhs){ return lhs[0]<rhs[0] ? -1 : (lhs[0]>rhs[0] ? 1 : 0); });
 
-			var sort= function(set) {
+			var sort= function(set){
 				var sorted= [];
-				for (var p in set) {
+				for(var p in set){
 					sorted.push(p);
 				}
 				return sorted.sort();
 			};
 
 			var newline = bc.newline;
-			bc.log("hasReport", sorted.map(function(item) {
+			bc.log("hasReport", sorted.map(function(item){
 				return "	// " + sort(item[1]).join(", ") + newline + "	 '" + item[0] + "':1";
 			}).join("," + newline + newline));
 		}
diff --git a/util/build/transforms/insertSymbols.js b/util/build/transforms/insertSymbols.js
index a38632b..cf7385e 100644
--- a/util/build/transforms/insertSymbols.js
+++ b/util/build/transforms/insertSymbols.js
@@ -1,4 +1,9 @@
-define(["../buildControl", "../fileUtils", "../fs", "../replace"], function(bc, fileUtils, fs, replace) {
+define([
+	"../buildControl",
+	"../fileUtils",
+	"../fs",
+	"../replace"
+], function(bc, fileUtils, fs, replace) {
 	var symctr = 1,
 		m = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
 		len = m.length,
@@ -74,7 +79,9 @@ define(["../buildControl", "../fileUtils", "../fs", "../replace"], function(bc,
 				return p1+p2+p3+" "+convertSym(p2, symtbl)+p4;
 			});
 			return content;
-		};
+		},
+
+		warningIssued = 0;
 
 	return function(resource, callback) {
 		if(bc.symbol){
@@ -94,6 +101,10 @@ define(["../buildControl", "../fileUtils", "../fs", "../replace"], function(bc,
 					});
 				}
 			}else{
+				if(!warningIssued){
+					warningIssued = 1;
+					bc.log("symbolsLeak", []);
+				}
 				fileUtils.ensureDirectoryByFilename(resource.dest);
 				resource.text = insertSymbols(resource, bc.symbolTable);
 			}
diff --git a/util/build/transforms/optimizeCss.js b/util/build/transforms/optimizeCss.js
index acf374d..30d825d 100644
--- a/util/build/transforms/optimizeCss.js
+++ b/util/build/transforms/optimizeCss.js
@@ -1,132 +1,184 @@
-define(["../buildControl", "../fileUtils"], function(bc, fileUtils) {
-	// note: this transform was copied from the v1.6 build system; the expression was cleaned up, but the
-	// algorithm is *exactly* as before
-
-	var
-		//Make sure we have a delimited ignore list to make matching faster
-		cssImportIgnore= bc.cssImportIgnore? bc.cssImportIgnore + "," : 0,
-
-		cssImportRegExp = /\@import\s+(url\()?\s*([^);]+)\s*(\))?([\w, ]*)(;)?/g,
-		cssUrlRegExp = /\url\(\s*([^\)]+)\s*\)?/g,
-
-		checkSlashes= function(name){
+define([
+	"../buildControl",
+	"../fileUtils",
+ 	"dojo/_base/lang"
+], function(bc, fileUtils, lang) {
+	// note: this transform originated from the v1.6 build system. In 1.8 it has been enhanced to handle
+	// relative paths for imports when the src and destination tree structures are not predictable.
+	//
+	// The cssImportIgnore logic remains although it is of questionable value because it depends on naming a file
+	// exactly as it is named in an import directive. Instead, the tag "importIgnore" can be used to prevent expanding
+	// a CSS file and the tag "noOptimize" can be used to prevent optimizing a CSS file. The tag system gives a
+	// much more general method to handle this problem. Of course cssImportIgnore can be disabled by simply setting
+	// it to falsy.
+
+	var cssImportRegExp = /\@import\s+(url\()?\s*([^);]+)\s*(\))?([\w, ]*)(;)?/g,
+		cssUrlRegExp = /url\(\s*([^\)]+)\s*\)?/g,
+
+		checkSlashes = function(name){
 			return name.replace(/\\/g, "/");
 		},
 
-		cleanCssUrlQuotes = function(/*String*/url){
-			//summary: If an URL from a CSS url value contains start/end quotes, remove them.
-			//This is not done in the regexp, since my regexp fu is not that strong,
-			//and the CSS spec allows for ' and " in the URL if they are backslash escaped.
+		cssImportIgnore = (bc.cssImportIgnore ?
+			// trim any spaces off of all items; add a trailing comma for fast lookups
+			bc.cssImportIgnore.split(",").map(function(item){return lang.trim(item);}).join(",") + "," :
+			""),
 
-			//Make sure we are not ending in whitespace.
-			//Not very confident of the css regexps above that there will not be ending whitespace.
-			url = url.replace(/\s+$/, "");
-			if(url.charAt(0) == "'" || url.charAt(0) == "\""){
+		cleanCssUrlQuotes = function(url){
+			// If an URL from a CSS url value contains start/end quotes, remove them.
+			// This is not done in the regexp, since the CSS spec allows for ' and " in the URL
+			// which makes the regex overly complicated if they are backslash escaped.
+
+			url = lang.trim(url);
+			if(url.charAt(0) == "'" || url.charAt(0) == '"'){
 				url = url.substring(1, url.length - 1);
 			}
 			return url;
 		},
 
-		removeComments = function(text, fileName){
-			var startIndex = -1;
-			//Get rid of comments.
+		removeComments = function(text, filename){
+			var originalText = text,
+				startIndex = -1,
+				endIndex;
 			while((startIndex = text.indexOf("/*")) != -1){
-				var endIndex = text.indexOf("*/", startIndex + 2);
+				endIndex = text.indexOf("*/", startIndex + 2);
 				if(endIndex == -1){
-					throw "Improper comment in CSS file: " + fileName;
+					bc.log("cssOptimizeImproperComment", ["CSS file", filename]);
+					return originalText;
 				}
 				text = text.substring(0, startIndex) + text.substring(endIndex + 2, text.length);
 			}
 			return text;
 		},
 
-		flattenCss = function(/*String*/fileName, /*String*/text, cssImportIgnore){
-			//summary: inlines nested stylesheets that have @import calls in them.
+		isRelative = function(url){
+			var colonIndex = url.indexOf(":");
+			return url.charAt(0) != "/" && (colonIndex == -1 || colonIndex > url.indexOf("/"));
+		},
 
-			text= removeComments(text, fileName);
+		getDestRelativeFilename = function(dest, relativeResource){
+			var referenceSegments = dest.split("/"),
+				relativeSegments = relativeResource.dest.split("/");
+			referenceSegments.pop();
+			while(referenceSegments.length && relativeSegments.length && referenceSegments[0]==relativeSegments[0]){
+				referenceSegments.shift();
+				relativeSegments.shift();
+			}
+			for(var i = 0; i<referenceSegments.length; i++){
+				relativeSegments.unshift("..");
+			}
+			return relativeSegments.join("/");
+		},
 
-			// get the path of the reference resource
-			var referencePath = fileUtils.getFilepath(checkSlashes(fileName));
+		getDestRelativeUrlFromSrcUrl = function(dest, fullSrcFilename, msgInfo){
+			var relativeResource = bc.resources[fullSrcFilename];
+			if(relativeResource){
+				return getDestRelativeFilename(dest, relativeResource);
+			}else{
+				bc.log("cssOptimizeUnableToResolveURL", msgInfo);
+			}
+			return 0;
+		},
 
-			return text.replace(cssImportRegExp, function(fullMatch, urlStart, importFileName, urlEnd, mediaTypes){
-				//Only process media type "all" or empty media type rules.
-				if(mediaTypes && ((mediaTypes.replace(/^\s\s*/, '').replace(/\s\s*$/, '')) != "all")){
-					return fullMatch;
+		flattenCss = function(resource){
+			if(resource.optimizedText){
+				return;
+			}
+			var dest = resource.dest,
+				src = resource.src,
+				srcReferencePath = fileUtils.getFilepath(checkSlashes(src)),
+				text = resource.text;
+			text = text.replace(/^\uFEFF/, ''); // remove BOM
+			text = removeComments(text, src);
+			text = text.replace(cssImportRegExp, function(fullMatch, urlStart, importUrl, urlEnd, mediaTypes){
+				importUrl = checkSlashes(cleanCssUrlQuotes(importUrl));
+				var fixedRelativeUrl,
+					fullSrcFilename = (isRelative(importUrl) ? fileUtils.compactPath(fileUtils.catPath(srcReferencePath, importUrl)) : importUrl),
+					importResource = bc.resources[fullSrcFilename],
+					ignore = false;
+
+				// don't expand if explicitly instructed not to by build control
+				if(
+					(cssImportIgnore && cssImportIgnore.indexOf(importUrl + ",") != -1) || // the v1.6- technique
+					(importResource && importResource.tag.importIgnore)                    // the v1.8+ technique
+				 ){
+					ignore = true;
+					bc.log("cssOptimizeIgnored", ["CSS file", src, "import directive", fullMatch]);
 				}
 
-				importFileName = cleanCssUrlQuotes(importFileName);
+				// don't expand if multiple media types given
+				if(mediaTypes && lang.trim(mediaTypes)!="all"){
+					ignore = true;
+					bc.log("cssOptimizeIgnoredMultiMediaTypes", ["CSS file", src, "import directive", fullMatch]);
+				}
 
-				//Ignore the file import if it is part of an ignore list.
-				if(cssImportIgnore && cssImportIgnore.indexOf(importFileName + ",") != -1){
-					return fullMatch;
+				// even if not expanding, make sure relative urls are adjusted correctly
+				if(ignore){
+					if(isRelative(importUrl) && (fixedRelativeUrl = getDestRelativeUrlFromSrcUrl(dest, fullSrcFilename, ["CSS file", src, "import directive", fullMatch]))){
+						return '@import url("' + fixedRelativeUrl + '")' + (mediaTypes || "") + ";";
+					}else{
+						// right or wrong, this is our only choice at this point
+						return fullMatch;
+					}
 				}
 
-				//Make sure we have a unix path for the rest of the operation.
-				importFileName = checkSlashes(importFileName);
-				var
-					fullImportFileName = importFileName.charAt(0) == "/" ? importFileName : fileUtils.compactPath(fileUtils.catPath(referencePath, importFileName)),
-					importPath= fileUtils.getFilepath(importFileName),
-					importModule= bc.resources[fullImportFileName],
-					importContents = importModule && (importModule.rawText || importModule.text);
-				if(!importContents){
-					skipped.push([importFileName, fileName]);
+				// at this point, we want to expand the import into the calling resource
+
+				if(!importResource){
+					bc.log("cssOptimizeIgnoredNoResource", ["CSS file", src, "import directive", fullMatch]);
 					return fullMatch;
 				}
 
-				//Make sure to flatten any nested imports.
-				importContents = flattenCss(fullImportFileName, importContents);
-
-				//Modify URL paths to match the path represented by this file.
-				importContents = importContents.replace(cssUrlRegExp, function(fullMatch, urlMatch){
-					var fixedUrlMatch = cleanCssUrlQuotes(urlMatch);
-					fixedUrlMatch = checkSlashes(fixedUrlMatch);
+				flattenCss(importResource);
+				var importContents = importResource.optimizedText;
+
+				// since importContents is flattened, all relative urls are computed with respect to the destination location of importResource
+				// these urls need to be adjusted with respect to resource
+				var importResourceDestPath = fileUtils.getFilepath(importResource.dest);
+				return importContents.replace(cssUrlRegExp, function(fullMatch, urlMatch){
+					var fixedUrl = checkSlashes(cleanCssUrlQuotes(urlMatch)),
+						queryString = "",
+						queryStart = fixedUrl.indexOf("?");
+					if(queryStart > 0){
+						queryString = fixedUrl.slice(queryStart);
+						fixedUrl = fixedUrl.slice(0, queryStart);
+					}
 
-					//Only do the work for relative URLs. Skip things that start with / or have a protocol.
-					var colonIndex = fixedUrlMatch.indexOf(":");
-					if(fixedUrlMatch.charAt(0) != "/" && (colonIndex == -1 || colonIndex > fixedUrlMatch.indexOf("/"))){
-						//It is a relative URL, tack on the path prefix
-						urlMatch =  fileUtils.compactPath(fileUtils.catPath(importPath, fixedUrlMatch));
-					}else{
-						nonrelative.push([urlMatch, importFileName]);
+					if(isRelative(fixedUrl)){
+						var fullDestFilename = fileUtils.compactPath(fileUtils.catPath(importResourceDestPath, fixedUrl)),
+							relativeResource = bc.resourcesByDest[fullDestFilename];
+						if(!relativeResource){
+							bc.log("cssOptimizeUnableToResolveURL", ["CSS file", src, "import", importResource.src, "relative URL", fullMatch]);
+						}else{
+							return 'url("' + getDestRelativeFilename(resource.dest, relativeResource) + queryString + '")';
+						}
 					}
-					return "url(" + fileUtils.compactPath(urlMatch) + ")";
+					// right or wrong, this is our only choice at this point
+					return fullMatch;
 				});
-
-				return importContents;
 			});
-		},
 
-		skipped, nonrelative;
+			if(/keepLines/i.test(bc.cssOptimize)){
+				// remove multiple empty lines.
+				text = text.replace(/(\r\n)+/g, "\r\n").replace(/\n+/g, "\n");
+			}else{
+				// remove newlines and extra spaces
+				text = text.replace(/[\r\n]/g, "").replace(/\s+/g, " ").replace(/\{\s/g, "{").replace(/\s\}/g, "}");
+			}
 
+			resource.optimizedText = text;
+			if(!resource.tag.noOptimize){
+				resource.rawText = resource.text;
+				resource.text = text;
+			}
+		};
 
 	return function(resource, callback) {
-		if(!bc.cssOptimize){
-			return;
-		}
-
-		skipped = [];
-		nonrelative = [];
-		var text = flattenCss(resource.src, resource.text, cssImportIgnore);
-
 		try{
-			//Get rid of newlines.
-			if(/keepLines/i.test(bc.cssOptimize)){
-				//Remove multiple empty lines.
-				text = text.replace(/(\r\n)+/g, "\r\n");
-				text = text.replace(/\n+/g, "\n");
-			}else{
-				text = text.replace(/[\r\n]/g, "");
-				text = text.replace(/\s+/g, " ");
-				text = text.replace(/\{\s/g, "{");
-				text = text.replace(/\s\}/g, "}");
+			if(bc.cssOptimize && !resource.tag.noOptimize){
+				flattenCss(resource);
+				bc.log("cssOptimize", ["file", resource.src]);
 			}
-			resource.rawText = resource.text;
-			resource.text= text;
-			var messageArgs = ["file", resource.src];
-			skipped.length && messageArgs.push("skipped", skipped);
-			nonrelative.length && messageArgs.push("non-relative URLs skipped", nonrelative);
-
-			bc.log("cssOptimize", messageArgs);
 		}catch(e){
 			bc.log("cssOptimizeFailed", ["file", resource.src, "error", e]);
 		}
diff --git a/util/build/transforms/optimizer/closure.js b/util/build/transforms/optimizer/closure.js
new file mode 100644
index 0000000..88de323
--- /dev/null
+++ b/util/build/transforms/optimizer/closure.js
@@ -0,0 +1,105 @@
+define([
+	"../../buildControl",
+	"dojo/has!host-node?./sendJob:",
+	"../../fs",
+	"../../fileUtils",
+	"./stripConsole",
+	"dojo/_base/lang",
+	"dojo/has"
+], function(bc, sendJob, fs, fileUtils, stripConsole, lang, has){
+	if(has("host-node")){
+		return function(resource, text, copyright, optimizeSwitch, callback){
+			copyright = copyright || "";
+			if(bc.stripConsole){
+				var tempFilename = resource.dest + ".consoleStripped.js";
+				text = stripConsole(text);
+				fs.writeFile(tempFilename, bc.newlineFilter(text, resource, "closureStripConsole"), resource.encoding, function(err){
+					if(!err){
+						sendJob(tempFilename, resource.dest, optimizeSwitch, copyright);
+					}
+					callback(resource, err);
+				});
+				return callback;
+			}else{
+				sendJob(resource.dest + ".uncompressed.js", resource.dest, optimizeSwitch, copyright);
+				return 0;
+			}
+		};
+	}
+
+	if(has("host-rhino")){
+		var JSSourceFilefromCode,
+			closurefromCode,
+			jscomp = 0;
+
+		var ccompile = function(text, dest, optimizeSwitch, copyright){
+			/*jshint rhino:true */
+			/*global com:false Packages:false */
+			if(!jscomp){
+				JSSourceFilefromCode = java.lang.Class.forName("com.google.javascript.jscomp.JSSourceFile").getMethod("fromCode", [ java.lang.String, java.lang.String ]);
+				closurefromCode = function(filename,content){
+					return JSSourceFilefromCode.invoke(null, [filename, content]);
+				};
+				jscomp = com.google.javascript.jscomp;
+			}
+			//Fake extern
+			var externSourceFile = closurefromCode("fakeextern.js", " ");
+
+			//Set up source input
+			var destFilename = dest.split("/").pop(),
+				jsSourceFile = closurefromCode(destFilename + ".uncompressed.js", String(text));
+
+			//Set up options
+			var options = new jscomp.CompilerOptions();
+			lang.mixin(options, bc.optimizeOptions);
+			// Must have non-null path to trigger source map generation, also fix version
+			options.setSourceMapOutputPath("");
+			options.setSourceMapFormat(jscomp.SourceMap.Format.V3);
+			if(optimizeSwitch.indexOf(".keeplines") !== -1){
+				options.prettyPrint = true;
+			}
+			var FLAG_compilation_level = jscomp.CompilationLevel.SIMPLE_OPTIMIZATIONS;
+			FLAG_compilation_level.setOptionsForCompilationLevel(options);
+			var FLAG_warning_level = jscomp.WarningLevel.DEFAULT;
+			FLAG_warning_level.setOptionsForWarningLevel(options);
+
+			//Prevent too-verbose logging output
+			Packages.com.google.javascript.jscomp.Compiler.setLoggingLevel(java.util.logging.Level.SEVERE);
+
+			// Run the compiler
+			// File name and associated map name
+			var map_tag = "//@ sourceMappingURL=" + destFilename + ".map";
+            var compiler = new Packages.com.google.javascript.jscomp.Compiler(Packages.java.lang.System.err);
+            compiler.compile(externSourceFile, jsSourceFile, options);
+            var result = copyright + "//>>built" + bc.newline + compiler.toSource() + bc.newline + map_tag;
+
+			var sourceMap = compiler.getSourceMap();
+			sourceMap.setWrapperPrefix(copyright + "//>>built");
+			var sb = new java.lang.StringBuffer();
+			sourceMap.appendTo(sb, destFilename);
+			fs.writeFile(dest + ".map", sb.toString(), "utf-8");
+
+			return result;
+		};
+
+		return function(resource, text, copyright, optimizeSwitch, callback){
+			bc.log("optimize", ["module", resource.mid]);
+			copyright = copyright || "";
+			try{
+				var result = ccompile(stripConsole(text), resource.dest, optimizeSwitch, copyright);
+				fs.writeFile(resource.dest, result, resource.encoding, function(err){
+					if(err){
+						bc.log("optimizeFailedWrite", ["filename", result.dest]);
+					}
+					callback(resource, err);
+				});
+			}catch(e){
+				bc.log("optimizeFailed", ["module identifier", resource.mid, "exception", e + ""]);
+				callback(resource, 0);
+			}
+			return callback;
+		};
+	}
+
+	throw new Error("Unknown host environment: only nodejs and rhino are supported by closure optimizer.");
+});
\ No newline at end of file
diff --git a/util/build/transforms/optimizer/sendJob.js b/util/build/transforms/optimizer/sendJob.js
new file mode 100644
index 0000000..aef2f0b
--- /dev/null
+++ b/util/build/transforms/optimizer/sendJob.js
@@ -0,0 +1,153 @@
+/*jshint node:true */
+define([
+	"../../buildControl",
+	"../../fileUtils",
+	"dojo/has"
+], function(bc, fileUtils, has){
+	// start up a few processes to compensate for the miserably slow closure compiler
+
+	var processes = [],
+		killAllRunners = function(){
+			processes.forEach(function(proc){
+				try{
+					proc.runner && proc.runner.kill();
+					proc.runner = 0;
+				}catch(e){
+					//squelch
+				}
+			});
+		};
+
+	// don't leave orphan child procs
+	global.process.on("exit", killAllRunners);
+	global.process.on("uncaughtException", function(err){
+		killAllRunners();
+		// TODO: log these via bc.log
+		console.log(err);
+		console.log(err.stack);
+		global.process.exit(-1);
+	});
+
+	var
+		processesStarted = 0,
+		totalOptimizerOutput = "",
+		nextProcId = 0,
+		i, //used in for loop
+		sendJob = function(src, dest, optimizeSwitch, copyright){
+			processes[nextProcId++].write(src, dest, optimizeSwitch, copyright);
+			nextProcId= nextProcId % bc.maxOptimizationProcesses;
+		},
+		doneRe = new RegExp("^Done\\s\\(compile\\stime.+$", "m"),
+		optimizerRunner = require.toUrl("build/optimizeRunner.js"),
+		buildRoot = optimizerRunner.match(/(.+)\/build\/optimizeRunner\.js$/)[1],
+		runJava, //function, defined later
+		oldSendJob = sendJob, //preserves reference if sendJob is replaced
+		child_process = require.nodeRequire("child_process"),
+		isCygwin = global.process.platform === 'cygwin',
+		separator = has("is-windows") ? ";" : ":",
+		javaClasses = fileUtils.catPath(buildRoot, "closureCompiler/compiler.jar") + separator + fileUtils.catPath(buildRoot, "shrinksafe/js.jar") + separator + fileUtils.catPath(buildRoot, "shrinksafe/shrinksafe.jar");
+	if(isCygwin){
+		//assume we're working with Windows Java, and need to translate paths
+		runJava = function(cb){
+			child_process.exec("cygpath -wp '" + javaClasses + "'", function(err, stdout){
+				javaClasses = stdout.trim();
+				child_process.exec("cygpath -w '" + optimizerRunner + "'", function(err, stdout){
+					optimizerRunner = stdout.trim();
+					cb();
+				});
+			});
+		};
+		//wrap sendJob calls to convert to windows paths first
+		sendJob = function(src, dest, optimizeSwitch, copyright){
+			child_process.exec("cygpath -wp '" + src + "'", function(err, srcstdout){
+				child_process.exec("cygpath -wp '" + dest + "'", function(err, deststdout){
+					oldSendJob(srcstdout.trim(), deststdout.trim(),
+						optimizeSwitch, copyright);
+				});
+			});
+		};
+	}else if(has("is-windows")){
+		runJava = function(cb){
+			javaClasses = fileUtils.normalize(javaClasses);
+			optimizerRunner = fileUtils.normalize(optimizerRunner);
+			cb();
+		};
+		sendJob = function(src, dest, optimizeSwitch, copyright){
+			var wsrc = fileUtils.normalize(src);
+			var wdest = fileUtils.normalize(dest);
+			oldSendJob(wsrc, wdest, optimizeSwitch, copyright);
+		};
+	}else{
+		//no waiting necessary, pass through
+		runJava = function(cb) { cb(); };
+	}
+	runJava(function() {
+		for(i = 0; i < bc.maxOptimizationProcesses; i++) {(function(){
+			var
+				runner = child_process.spawn("java", ["-cp", javaClasses, "org.mozilla.javascript.tools.shell.Main", optimizerRunner]),
+				proc = {
+					runner:runner,
+					results:"",
+					tempResults:"",
+					sent:[],
+					write:function(src, dest, optimizeSwitch, copyright){
+						proc.sent.push(dest);
+						runner.stdin.write(src + "\n" + dest + "\n" + optimizeSwitch + "\n" + JSON.stringify({ copyright: copyright, options: bc.optimizeOptions }) + "\n");
+					},
+					sink:function(output){
+						proc.tempResults += output;
+						var match, message, chunkLength;
+						while((match = proc.tempResults.match(doneRe))){
+							message = match[0];
+							if(/OPTIMIZER\sFAILED/.test(message)){
+								bc.log("optimizeFailed", ["module identifier", proc.sent.shift(), "exception", message.substring(5)]);
+							}else{
+								bc.log("optimizeDone", [proc.sent.shift() + " " + message.substring(5)]);
+							}
+							chunkLength = match.index + message.length;
+							proc.results += proc.tempResults.substring(0, chunkLength);
+							proc.tempResults = proc.tempResults.substring(chunkLength);
+						}
+					}
+				};
+			processesStarted++; // matches *3*
+			runner.stdout.on("data", function(data){
+				// the +"" converts to Javascript string
+				proc.sink(data + "");
+			}),
+			runner.stderr.on("data", function(data){
+				// the +"" converts to Javascript string
+				proc.sink(data + "");
+			}),
+			runner.on("exit", function(){
+				proc.results += proc.tempResults;
+				totalOptimizerOutput += proc.results;
+				bc.logOptimizerOutput(totalOptimizerOutput);
+				processesStarted--; // matches *3*
+				if(!processesStarted){
+					// all the processes have completed and shut down at this point
+					if(bc.showOptimizerOutput){
+						bc.log("optimizeMessages", [totalOptimizerOutput]);
+					}
+					bc.passGate(); // matched with *1*
+				}
+			});
+			processes.push(proc);
+		})();}
+	}); //end runJava(function...)
+
+	bc.gateListeners.push(function(gate){
+		if(gate==="cleanup"){
+			// going through the cleanup gate signals that all optimizations have been started;
+			// we now signal the runner there are no more files and wait for the runner to stop
+			bc.log("pacify", "waiting for the optimizer runner to finish...");
+			bc.waiting++;  // matched with *1*
+			processes.forEach(function(proc){
+				proc.write(".\n");
+			});
+			processes = [];
+		}
+	});
+
+	return sendJob;
+});
\ No newline at end of file
diff --git a/util/build/transforms/optimizer/shrinksafe.js b/util/build/transforms/optimizer/shrinksafe.js
new file mode 100644
index 0000000..e680f38
--- /dev/null
+++ b/util/build/transforms/optimizer/shrinksafe.js
@@ -0,0 +1,94 @@
+/*jshint white:false */
+define([
+	"../../buildControl",
+	"dojo/has!host-node?./sendJob:",
+	"../../fs",
+	"dojo/has"
+], function(bc, sendJob, fs, has){
+	if(has("host-node")){
+		return function(resource, text, copyright, optimizeSwitch/*, callback*/){
+			copyright = copyright || "";
+			sendJob(resource.dest + ".uncompressed.js", resource.dest, optimizeSwitch, copyright);
+			return 0;
+		};
+	}
+
+	if(has("host-rhino")){
+		var sscompile = function(text, dest, optimizeSwitch, copyright){
+			/*jshint rhino:true */
+			/*global Packages:false */
+			// decode the optimize switch
+			var
+				options = optimizeSwitch.split("."),
+				comments = 0,
+				keepLines = 0,
+				strip = null;
+			while(options.length){
+				switch(options.pop()){
+				case "normal":
+					strip = "normal";
+					break;
+				case "warn":
+					strip = "warn";
+					break;
+				case "all":
+					strip = "all";
+					break;
+				case "keeplines":
+					keepLines = 1;
+					break;
+				case "comments":
+					comments = 1;
+					break;
+				}
+			}
+
+			//Use rhino to help do minifying/compressing.
+			var context = Packages.org.mozilla.javascript.Context.enter();
+			try{
+				// Use the interpreter for interactive input (copied this from Main rhino class).
+				context.setOptimizationLevel(-1);
+
+				if(comments){
+					//Strip comments
+					var script = context.compileString(text, dest, 1, null);
+					text = new String(context.decompileScript(script, 0));
+
+					//Replace the spaces with tabs.
+					//Ideally do this in the pretty printer rhino code.
+					text = text.replace(/	 /g, "\t");
+				}else{
+					//Apply compression using custom compression call in Dojo-modified rhino.
+					text = new String(Packages.org.dojotoolkit.shrinksafe.Compressor.compressScript(text, 0, 1, strip));
+					if(!keepLines){
+						text = text.replace(/[\r\n]/g, "");
+					}
+				}
+			}finally{
+				Packages.org.mozilla.javascript.Context.exit();
+			}
+			return copyright + "//>>built" + bc.newline + text;
+		};
+
+		return function(resource, text, copyright, optimizeSwitch, callback){
+			bc.log("optimize", ["module", resource.mid]);
+			copyright = copyright || "";
+			try{
+				var result = sscompile(text, resource.dest, optimizeSwitch, copyright);
+
+				fs.writeFile(resource.dest, result, resource.encoding, function(err){
+					if(err){
+						bc.log("optimizeFailedWrite", ["filename", result.dest]);
+					}
+					callback(resource, err);
+				});
+			}catch(e){
+				bc.log("optimizeFailed", ["module identifier", resource.mid, "exception", e + ""]);
+				callback(resource, 0);
+			}
+			return callback;
+		};
+	}
+
+	throw new Error("Unknown host environment: only nodejs and rhino are supported by shrinksafe optimizer.");
+});
\ No newline at end of file
diff --git a/util/build/transforms/optimizer/stripConsole.js b/util/build/transforms/optimizer/stripConsole.js
new file mode 100644
index 0000000..65d144a
--- /dev/null
+++ b/util/build/transforms/optimizer/stripConsole.js
@@ -0,0 +1,18 @@
+define(["../../buildControl"], function(bc){
+	if(bc.stripConsole){
+		var consoleMethods = "assert|count|debug|dir|dirxml|group|groupEnd|info|profile|profileEnd|time|timeEnd|trace|log";
+		if(bc.stripConsole === "warn"){
+			consoleMethods += "|warn";
+		}else if(bc.stripConsole === "all"){
+			consoleMethods += "|warn|error";
+		}
+		var stripConsoleRe = new RegExp("console\\.(" + consoleMethods + ")\\s*\\(", "g");
+		return function(text){
+			return text.replace(stripConsoleRe, "0 && $&");
+		};
+	}else{
+		return function(text){
+			return text;
+		};
+	}
+});
\ No newline at end of file
diff --git a/util/build/transforms/optimizer/uglify.js b/util/build/transforms/optimizer/uglify.js
new file mode 100644
index 0000000..155c8bb
--- /dev/null
+++ b/util/build/transforms/optimizer/uglify.js
@@ -0,0 +1,46 @@
+/*jshint node:true */
+define([
+	"../../buildControl",
+	"../../fs",
+	"./stripConsole",
+	"dojo/_base/lang",
+	"dojo/has",
+	"dojo/has!host-node?dojo/node!uglify-js:"
+], function(bc, fs, stripConsole, lang, has, uglify){
+	if(!uglify){
+		throw new Error("Unknown host environment: only nodejs is supported by uglify optimizer.");
+	}
+
+	return function(resource, text, copyright, optimizeSwitch, callback){
+		copyright = copyright || "";
+
+		var options = bc.optimizeOptions || {};
+
+		if(optimizeSwitch.indexOf(".keeplines") > -1){
+			options.gen_options = options.gen_options || {};
+			options.gen_options.beautify = true;
+			options.gen_options.indent_level = 0; //don't indent, just keep new lines
+		}
+		if(optimizeSwitch.indexOf(".comments") > -1){
+			throw new Error("'comments' option is not supported by uglify optimizer.");
+		}
+
+		process.nextTick(function(){
+			try{
+				var result = copyright + "//>>built" + bc.newline + uglify(stripConsole(text), options);
+
+				fs.writeFile(resource.dest, result, resource.encoding, function(err){
+					if(err){
+						bc.log("optimizeFailedWrite", ["filename", result.dest]);
+					}
+					callback(resource, err);
+				});
+			}catch(e){
+				bc.log("optimizeFailed", ["module identifier", resource.mid, "exception", e + ""]);
+				callback(resource, 0);
+			}
+		});
+
+		return callback;
+	};
+});
diff --git a/util/build/transforms/read.js b/util/build/transforms/read.js
index a286597..a125a13 100644
--- a/util/build/transforms/read.js
+++ b/util/build/transforms/read.js
@@ -1,6 +1,11 @@
-define(["../buildControl", "../fileUtils", "../fs", "../replace"], function(bc, fileUtils, fs, replace) {
+define([
+	"../buildControl",
+	"../fileUtils",	
+	"../fs",
+	"../replace"
+], function(bc, fileUtils, fs, replace){
 	var
-		getFiletype= fileUtils.getFiletype,
+		getFiletype = fileUtils.getFiletype,
 
 		encodingMap=
 			// map from file type to encoding
@@ -25,12 +30,12 @@ define(["../buildControl", "../fileUtils", "../fs", "../replace"], function(bc,
 				gif:undefined
 			};
 
-	return function(resource, callback) {
-		resource.getText= function() {
-			if (!this.replacementsApplied) {
-				this.replacementsApplied= true;
-				if (bc.replacements[this.src]) {
-					this.text= replace(this.text, bc.replacements[this.src]);
+	return function(resource, callback){
+		resource.getText = function(){
+			if(!this.replacementsApplied){
+				this.replacementsApplied = true;
+				if(bc.replacements[this.src]){
+					this.text = replace(this.text, bc.replacements[this.src]);
 				}
 			}
 			return this.text;
@@ -42,13 +47,12 @@ define(["../buildControl", "../fileUtils", "../fs", "../replace"], function(bc,
 			return text;
 		};
 
-
-		var filetype= getFiletype(resource.src, 1);
+		var filetype = getFiletype(resource.src, 1);
 		// the expression is a little odd since undefined is a legitimate encodingMap value
-		resource.encoding= resource.encoding || (!(filetype in encodingMap) && "utf8") || encodingMap[filetype];
-		fs.readFile(resource.src, resource.encoding, function(err, data) {
-			if (!err) {
-				resource.text= data;
+		resource.encoding = resource.encoding ||(!(filetype in encodingMap) && "utf8") || encodingMap[filetype];
+		fs.readFile(resource.src, resource.encoding, function(err, data){
+			if(!err){
+				resource.text = data;
 			}
 			callback(resource, err);
 		});
diff --git a/util/build/transforms/report.js b/util/build/transforms/report.js
index f8aac95..ec67eb6 100644
--- a/util/build/transforms/report.js
+++ b/util/build/transforms/report.js
@@ -1,12 +1,16 @@
-define(["../buildControl", "../fileUtils", "../fs"], function(bc, fileUtils, fs) {
+define([
+	"../buildControl",
+	"../fileUtils",
+	"../fs"
+], function(bc, fileUtils, fs) {
 	return function(resource, callback) {
 		resource.reports.forEach(function(report){
 			// report is a hash of dir, filename, content; content may be a function
 			var
-				dest= fileUtils.computePath(fileUtils.catPath(report.dir, report.filename), bc.destBasePath),
-				content= report.content;
+				dest = fileUtils.computePath(fileUtils.catPath(report.dir, report.filename), bc.destBasePath),
+				content = report.content;
 			if(typeof content=="function"){
-				content= content(bc);
+				content = content(bc);
 			};
 			bc.waiting++; // matches *1*
 			fileUtils.ensureDirectory(fileUtils.getFilepath(dest));
diff --git a/util/build/transforms/write.js b/util/build/transforms/write.js
index fc77ead..4ca689c 100644
--- a/util/build/transforms/write.js
+++ b/util/build/transforms/write.js
@@ -1,4 +1,9 @@
-define(["../buildControl", "../fileUtils", "../fs", "../replace"], function(bc, fileUtils, fs, replace) {
+define([
+	"../buildControl",
+	"../fileUtils",
+	"../fs",
+	"../replace"
+], function(bc, fileUtils, fs, replace) {
 	return function(resource, callback) {
 		if(resource.tag.noWrite){
 			return 0;
diff --git a/util/build/transforms/writeAmd.js b/util/build/transforms/writeAmd.js
index b1f7ce2..1077fa0 100644
--- a/util/build/transforms/writeAmd.js
+++ b/util/build/transforms/writeAmd.js
@@ -1,90 +1,99 @@
-define(["../buildControl", "../fileUtils", "../fs", "dojo/_base/lang", "dojo/json"], function(bc, fileUtils, fs, lang, json) {
+define([
+	"../buildControl",
+	"../fileUtils",
+	"../fs",
+	"dojo/_base/lang",
+	"dojo/json"
+], function(bc, fileUtils, fs, lang, json){
 	var
 		computingLayers
 			// the set of layers being computed; use this to detect circular layer dependencies
 			= {},
 
-		computeLayerContents= function(
+		computeLayerContents = function(
 			layerModule,
 			include,
 			exclude
-		) {
+		){
 			// add property layerSet (a set of mid) to layerModule that...
 			//
+			//	 * includes the layerModule itself
 			//	 * includes dependency tree of layerModule
 			//	 * includes all modules in layerInclude and their dependency trees
 			//	 * excludes all modules in layerExclude and their dependency trees
-			//	 * excludes layerModule itself
 			//
 			// note: layerSet is built exactly as given above, so included modules that are later excluded
 			// are *not* in result layerSet
-			if(layerModule && computingLayers[layerModule.mid]){
+
+			if(computingLayers[layerModule.mid]){
 				bc.log("amdCircularDependency", ["module", layerModule.mid]);
 				return {};
 			}
-			computingLayers[layerModule.mid]= 1;
+			computingLayers[layerModule.mid] = 1;
 
 			var
-				includeSet= {},
+				includeSet = {},
 				visited,
 				includePhase,
-				traverse= function(module) {
-					var mid= module.mid;
+				traverse = function(module){
+					var mid = module.mid;
 
-					if (visited[mid]) {
+					if(visited[mid]){
 						return;
 					}
-					visited[mid]= 1;
-					if (includePhase) {
-						includeSet[mid]= module;
-					} else {
+					visited[mid] = 1;
+					if(includePhase){
+						includeSet[mid] = module;
+					}else{
 						delete includeSet[mid];
 					}
 					if(module!==layerModule && module.layer){
-						var layerModuleSet= module.moduleSet || computeLayerContents(module, module.layer.include, module.layer.exclude);
+						var layerModuleSet = module.moduleSet || computeLayerContents(module, module.layer.include, module.layer.exclude);
 						for(var p in layerModuleSet){
-							if (includePhase) {
-								includeSet[p]= layerModuleSet[p];
-							} else {
+							if(includePhase){
+								includeSet[p] = layerModuleSet[p];
+							}else{
 								delete includeSet[p];
 							}
 						}
 					}else{
-						for (var deps= module.deps, i= 0; deps && i<deps.length; traverse(deps[i++])){
+						for(var deps = module.deps, i = 0; deps && i<deps.length; traverse(deps[i++])){
 						}
 					}
 				};
 
-			visited= {};
-			includePhase= true;
-			if (layerModule) {
-				traverse(layerModule);
-			}
-			include.forEach(function(mid) {
-				var module= bc.amdResources[bc.getSrcModuleInfo(mid, layerModule).mid];
-				if (!module) {
-					bc.log("amdMissingLayerIncludeModule", ["missing", mid, "layer", layerModule && layerModule.mid]);
-				} else {
+			visited = {};
+			includePhase = true;
+			traverse(layerModule);
+			include.forEach(function(mid){
+				var module = bc.amdResources[bc.getSrcModuleInfo(mid, layerModule).mid];
+				if(!module){
+					bc.log("amdMissingLayerIncludeModule", ["missing", mid, "layer", layerModule.mid]);
+				}else{
 					traverse(module);
 				}
 			});
 
-			visited= {};
-			includePhase= false;
-			exclude.forEach(function(mid) {
-				var module= bc.amdResources[bc.getSrcModuleInfo(mid, layerModule).mid];
-				if (!module) {
-					bc.log("amdMissingLayerExcludeModule", ["missing", mid, "layer", layerModule && layerModule.mid]);
-				} else {
+			visited = {};
+			includePhase = false;
+			exclude.forEach(function(mid){
+				var module = bc.amdResources[bc.getSrcModuleInfo(mid, layerModule).mid];
+				if(!module){
+					bc.log("amdMissingLayerExcludeModule", ["missing", mid, "layer", layerModule.mid]);
+				}else{
 					traverse(module);
 				}
 			});
 
-			if(layerModule){
-				layerModule.moduleSet= includeSet;
-				delete computingLayers[layerModule.mid];
+			layerModule.moduleSet = includeSet;
+			delete computingLayers[layerModule.mid];
+
+			// return a copy so that clients can not mutate layerModule.moduleSet
+			var result = {};
+			for(var p in includeSet){
+				result[p] = includeSet[p];
 			}
-			return includeSet;
+			return result;
 		},
 
 		insertAbsMid = function(
@@ -95,192 +104,222 @@ define(["../buildControl", "../fileUtils", "../fs", "dojo/_base/lang", "dojo/jso
 				text : text.replace(/(define\s*\(\s*)(.*)/, "$1\"" + resource.mid + "\", $2");
 		},
 
-		getCacheEntry = function(
+		pushString = function(
+			strings,
 			pair
 		){
-			return "'" + pair[0] + "':" + pair[1];
+			strings[pair[0]] = pair[1];
 		},
 
-		getDiscreteLocales = function(locale){
-			for(var locales = locale.split("-"), result = [], current = "", i= 0; i<locales.length; i++){
-				result.push(current += (i ? "-" : "") + locales[i]);
+		appendStringsToCache = function(
+			strings,
+			cache
+		) {
+			for(var p in strings){
+				cache.push("'" + p + "':" + strings[p])
 			}
-			return result;
 		},
 
-		getPreloadLocalizationsRootPath = function(dest){
-			var match= dest.match(/(.+)\/([^\/]+)$/);
+		getPreloadL10nRootPath = function(
+			dest
+		){
+			var match = dest.match(/(.+)\/([^\/]+)$/);
 			return match[1] + "/nls/" + match[2];
 		},
 
-		getFlattenedNlsBundles = function(
+		flattenRootBundle = function(
+			resource
+		){
+			if(resource.flattenedBundles){
+				return;
+			}
+			resource.flattenedBundles = {};
+			bc.localeList.forEach(function(locale){
+				var accumulator = lang.mixin({}, resource.bundleValue.root);
+				bc.localeList.discreteLocales[locale].forEach(function(discreteLocale){
+					var localizedBundle = resource.localizedSet[discreteLocale];
+					if(localizedBundle && localizedBundle.bundleValue){
+						lang.mixin(accumulator, localizedBundle.bundleValue);
+					}
+				});
+				resource.flattenedBundles[locale] = accumulator;
+			});
+		},
+
+		getFlattenedBundles = function(
 			resource,
-			rootBundles,
-			noref
+			rootBundles
 		){
+			rootBundles.forEach(flattenRootBundle);
+
 			var newline = bc.newline,
-				rootPath = getPreloadLocalizationsRootPath(resource.dest.match(/(.+)(\.js)$/)[1]),
-				result = resource.flattenedNlsBundles = {};
+				rootPath = getPreloadL10nRootPath(resource.dest.match(/(.+)(\.js)$/)[1]),
+				mid, cache;
 			bc.localeList.forEach(function(locale){
-				var locales = getDiscreteLocales(locale),
-					cache = [];
-				rootBundles.forEach(function(bundleRoot){
-					var prefix = bundleRoot.prefix,
-						bundle = "/" + bundleRoot.bundle;
-					locales.forEach(function(locale){
-						var mid = prefix + locale + bundle,
-							module = bc.amdResources[mid],
-							text = "define('" + mid + "',{});";
-						if(bundleRoot.localizedSet[locale] && module){
-							text = module.getText();
-						}else{
-							//TODO real msg
-							//console.log("NOT FOUND - 1: " + mid);
-						}
-						cache.push("'" + mid + "':function(){" + newline + text + newline + "}");
-					});
+				cache = [];
+				rootBundles.forEach(function(rootResource){
+					cache.push("'" + rootResource.prefix + rootResource.bundle + "':" + json.stringify(rootResource.flattenedBundles[locale]) + newline);
 				});
-				if(cache.length && noref){
-					cache.push("'*noref':1");
+				mid = getPreloadL10nRootPath(resource.mid) + "_" + locale;
+				var flattenedResource = {
+					src:"*synthetic*",
+					dest:rootPath + "_" + locale + ".js",
+					pid:resource.pid,
+					mid:mid,
+					pack:resource.pack,
+					deps:[],
+					tag:{flattenedNlsBundle:1},
+					encoding:'utf8',
+					text:"define(" + (bc.insertAbsMids ? "'" + mid + "',{" : "{") + newline + cache.join("," + newline) + "});",
+					getText:function(){ return this.text; }
+				};
+				if(bc.insertAbsMids){
+					flattenedResource.tag.hasAbsMid = 1;
 				}
-				var
-					match = resource.mid.match(/(.+)\/([^\/]+)$/),
-					flattenedMid = match[1] + "/nls/" + match[2] + "_" + locale;
-				result[locale]  = [rootPath + "_" + locale + ".js", cache.length ? "require({cache:{" + newline + cache.join("," + newline) + "}});" + newline + 'define("' + flattenedMid + '", [], 1);' + newline : ""];
+				bc.start(flattenedResource);
 			});
 		},
 
-		getLayerText= function(
+		getLayerText = function(
 			resource,
-			include,
-			exclude,
-			noref
-		) {
-			var
-				newline = bc.newline,
+			resourceText // ===undefined (normal case) => AMD define() the resource at the end of the layer
+						 // ===false => put the resource in the cache
+						 // otherwise write the value of resourceText at the end of the layer (so far only used in the writeDojo transform)
+		){
+			var newline = bc.newline,
 				rootBundles = [],
-				cache= [],
-				moduleSet= computeLayerContents(resource, include, exclude);
-			for (var p in moduleSet) if(!resource || p!=resource.mid){
-				var module= moduleSet[p];
-				if (module.internStrings) {
-					cache.push(getCacheEntry(module.internStrings()));
-				} else if(module.getText){
-					cache.push("'" + p + "':function(){" + newline + module.getText() + newline + "}");
-				} else {
-					bc.log("amdMissingLayerModuleText", ["module", module.mid, "layer", resource.mid]);
-				}
-				if(module.localizedSet){
-					// this is a root NLS bundle
-					rootBundles.push(module);
+				strings = {},
+				cache = [],
+				layer = resource.layer,
+				moduleSet = computeLayerContents(resource, layer.include, layer.exclude),
+				includeLocales = "includeLocales" in layer ? layer.includeLocales : bc.includeLocales;			
+			for(var p in moduleSet){
+				// always put modules!=resource in the cache; put resource in the cache if it's a boot layer and an explicit resourceText wasn't given
+				if(p!=resource.mid || resourceText===false){
+					var module = moduleSet[p];
+					if(module.localizedSet && bc.localeList){
+						// this is a root NLS bundle and the profile is building flattened layer bundles;
+						// therefore, add this bundle to the set to be flattened, but don't write the root bundle
+						// to the cache since the loader will explicitly load the flattened bundle
+						rootBundles.push(module);
+						if(includeLocales){
+							// include the ROOT always
+							cache.push("'" + p + "':function(){" + newline + module.getText() + newline + "}");
+							// now include each locale in the layer
+							includeLocales.forEach(function(locale){
+								var parts = locale.split("-");
+								for(var i = parts.length; i > 0; i--){
+									var localizedSet = module.localizedSet[parts.slice(0, i).join("-")];
+									// see if the localized set is there
+									if(localizedSet){
+										// put the bundle in the cache
+										cache.push("'" + localizedSet.mid + "':function(){" + newline + localizedSet.getText() + newline + "}");
+									}
+								}
+							});
+						}
+					}else if(module.internStrings){
+						pushString(strings, module.internStrings());
+					}else if(module.getText){
+						cache.push("'" + p + "':function(){" + newline + module.getText() + newline + "}");
+					}else{
+						bc.log("amdMissingLayerModuleText", ["module", module.mid, "layer", resource.mid]);
+					}
 				}
 			}
+			appendStringsToCache(strings, cache);
+
+			// compute the flattened layer bundles (if any)
+			if(rootBundles.length){
+				getFlattenedBundles(resource, rootBundles);
+				// push an *now into the cache that causes the flattened layer bundles to be loaded immediately
+				cache.push("'*now':function(r){r(['dojo/i18n!*preload*" + getPreloadL10nRootPath(resource.mid) + "*" + 
+					json.stringify(bc.localeList.filter(function(locale){
+						return !includeLocales || (includeLocales.indexOf(locale) == -1 && locale != "ROOT");
+					})) + "']);}" + newline);
+			}
 
 			// construct the cache text
-			if(cache.length && noref){
+			if(cache.length && resource.layer.noref){
 				cache.push("'*noref':1");
 			}
-			cache = cache.length ? "require({cache:{" + newline + cache.join("," + newline) + "}});" + newline : "";
-
-			// compute the flattened NLS bundles if required
-			if(resource && bc.localeList && rootBundles.length && resource.flattenedNlsBundles===undefined){
-				getFlattenedNlsBundles(resource, rootBundles, noref);
-			}
-
-			// !resource implies a boot module; don't preloadLocalizations for that kind of new module since it is new in 1.7
-			// prefer the bc.preloadLocations switch, which allows turning off this feature
-			// default to include preloadLocalizations iff the config is synch mode
-			var preloadText = "";
-			if(resource && (bc.preloadLocalizations || (!("preloadLocalizations" in bc) && !bc.defaultConfig.async))){
-				var localeList = [];
-				for(p in resource.flattenedNlsBundles){
-					localeList.push('"' + p + '"');
-				}
-
-				preloadText = 'i18n._preloadLocalizations("' + getPreloadLocalizationsRootPath(resource.mid) + '", [' + localeList.join(",") + "]);" + newline;
-				preloadText = 'require(["dojo/i18n"], function(i18n){' + newline + preloadText + "});" + newline;
-			}
-
-			var text= "";
-			if(resource){
-				text= insertAbsMid(resource.getText(), resource);
-			}
-
-			text = cache + newline + preloadText + text;
-
-			if(resource && resource.layer && resource.layer.postscript){
-				text+= resource.layer.postscript;
-			}
-
-			return text;
+			return	(cache.length ? "require({cache:{" + newline + cache.join("," + newline) + "}});" + newline : "") +
+				(resourceText===undefined ?	 insertAbsMid(resource.getText(), resource) : (resourceText==false ? "" : resourceText)) +
+				(resource.layer.postscript ? resource.layer.postscript : "");
 		},
 
-		getStrings= function(
+		getStrings = function(
 			resource
 		){
-			var cache = [],
+			var strings = {},
+				cache = [],
 				newline = bc.newline;
 			resource.deps && resource.deps.forEach(function(dep){
 				if(dep.internStrings){
-					cache.push(getCacheEntry(dep.internStrings()));
+					pushString(strings, dep.internStrings());
 				}
 			});
+			appendStringsToCache(strings, cache);
 			return cache.length ? "require({cache:{" + newline + cache.join("," + newline) + "}});" + newline : "";
 		},
 
-		getDestFilename= function(resource){
-			if(!resource.tag.nls && ((resource.layer && bc.layerOptimize) || (!resource.layer && bc.optimize))){
+		getDestFilename = function(
+			resource
+		){
+			if((resource.layer && bc.layerOptimize) || (!resource.layer && bc.optimize)){
 				return resource.dest + ".uncompressed.js";
-			}else{
-				return resource.dest;
 			}
+			return resource.dest;
 		},
 
-		writeNls = function(rootResource, copyright, callback){
-			// this is a root bundle; therefore write it *and* all of the localized bundles.
-			var
-				waitCount = 1, // matches *1*
-				errors = [],
-				onWriteComplete = function(err) {
-					if(err){
-						errors.push(err);
+		processNlsBundle = function(
+			resource
+		){
+			var newline = bc.newline, text, p;
+
+			if(resource.localizedSet && resource.bundleValue){
+				// do a check that all localizations mentioned in the root actually exist
+				var missing = [];
+				for(p in resource.bundleValue){
+					if(p!="root" && !resource.localizedSet[p]){
+						missing.push("'" + p + "'");
 					}
-					if(--waitCount==0){
-						callback(rootResource, errors.length && errors);
+				}
+				if(missing.length){
+					missing.sort();
+					bc.log("missingL10n", "Root: " + resource.mid + "; missing bundles: " + missing.join(",") + ".");
+				}
+			}
+			if(resource.bundleType=="legacy"){
+				if(resource.bundleValue){
+					if(resource.localizedSet){
+						// this is the root bundle; augment with all available localizations
+						for(p in resource.localizedSet){
+							resource.bundleValue[p] = 1;
+						}
 					}
-				},
-				prefix = rootResource.prefix,
-				bundle = "/" + rootResource.bundle,
-				localizedSet = rootResource.localizedSet;
-			for(var p in localizedSet){
-				var mid = prefix + p + bundle,
-					module = bc.amdResources[mid];
-				if(!module){
-					// TODO: add proper message log
-					console.log("MISSING: " + mid);
+					text = json.stringify(resource.bundleValue);
 				}else{
-					var text = insertAbsMid(module.getText(), module);
-					module.setText(text);
-					var filename = getDestFilename(module);
-					fileUtils.ensureDirectoryByFilename(filename);
-					waitCount++; // matches *2*
-					fs.writeFile(filename, bc.newlineFilter(copyright + "//>>built" + bc.newline + text, module, "writeAmd"), module.encoding, onWriteComplete); // *2*
-
+					text = "// ERROR: builder was unable to evaluate source bundle; therefore, this empty conversion was written" + newline + "{}";
 				}
+				return "define(" + (bc.insertAbsMids ? "'" + resource.mid + "'," : "") + newline + text  + newline + ");";
+			}else{
+				return insertAbsMid(resource.getText(), resource);
 			}
-
-			text = insertAbsMid(rootResource.getText(), rootResource);
-			rootResource.setText(text);
-			fs.writeFile(getDestFilename(rootResource), bc.newlineFilter(copyright + "//>>built" + bc.newline + text, rootResource, "writeAmd"), module.encoding, onWriteComplete); // *1*
-			return callback;
 		},
 
-		write= function(resource, callback) {
-			fileUtils.ensureDirectoryByFilename(resource.dest);
+		write = function(
+			resource,
+			callback
+		){
+			if(resource.layer && (resource.layer.boot || resource.layer.discard)){
+				// resource.layer.boot layers are written by the writeDojo transform
+				return 0;
+			}
 
 			var copyright;
 			if(resource.pack){
-				copyright= resource.pack.copyrightNonlayers && (resource.pack.copyright || bc.copyright);
+				copyright = resource.pack.copyrightNonlayers && (resource.pack.copyright || bc.copyright);
 			}else{
 				copyright = bc.copyrightNonlayers &&  bc.copyright;
 			}
@@ -288,55 +327,37 @@ define(["../buildControl", "../fileUtils", "../fs", "dojo/_base/lang", "dojo/jso
 				copyright = "";
 			}
 
-			if(resource.tag.nls){
-				return resource.localizedSet ? writeNls(resource, copyright, callback) : 0;
-			}
-
 			var text;
-			if(resource.layer){
-				if(resource.layer.boot || resource.layer.discard){
-					// resource.layer.boot layers are written by the writeDojo transform
-					return 0;
-				}
-				text= resource.layerText= getLayerText(resource, resource.layer.include, resource.layer.exclude, resource.layer.noref);
+			if(resource.tag.nls){
+				text = processNlsBundle(resource);
+			}else if(resource.layer){
+				// don't insertAbsMid or internStrings since that's done in getLayerText
+				text= getLayerText(resource);
 				if(resource.layer.compat=="1.6"){
-					text= resource.layerText= text + "require(" + json.stringify(resource.layer.include) + ");" + bc.newline;
+					text += "require(" + json.stringify(resource.layer.include) + ");" + bc.newline;
 				}
-
-				copyright= resource.layer.copyright || "";
+				copyright = resource.layer.copyright || "";
 			}else{
-				text= insertAbsMid(resource.getText(), resource);
-				text= (bc.internStrings ? getStrings(resource) : "") + text;
-				resource.text= text;
-			}
-
-			var
-				waitCount = 1, // matches *1*
-				errors = [],
-				onWriteComplete = function(err) {
-					if(err){
-						errors.push(err);
-					}
-					if(--waitCount==0){
-						callback(resource, errors.length && errors);
-					}
-				};
-
-			if(resource.flattenedNlsBundles){
-				for(var p in resource.flattenedNlsBundles){
-					var item = resource.flattenedNlsBundles[p];
-					waitCount++;
-					fileUtils.ensureDirectoryByFilename(item[0]);
-					fs.writeFile(item[0], item[1], resource.encoding, onWriteComplete);
+				text = insertAbsMid(resource.getText(), resource);
+				if(bc.internStrings){
+					text = getStrings(resource) + text;
 				}
 			}
 
-			fs.writeFile(getDestFilename(resource), bc.newlineFilter(copyright + "//>>built" + bc.newline + text, resource, "writeAmd"), resource.encoding, onWriteComplete);
+			// remember the uncompressed text for the optimizer
+			resource.uncompressedText = text;
+
+			var destFilename = getDestFilename(resource);
+			fileUtils.ensureDirectoryByFilename(destFilename);
+			fs.writeFile(destFilename, bc.newlineFilter(text, resource, "writeAmd"), resource.encoding, function(err){
+				callback(resource, err);
+			});
 			return callback;
 		};
-		write.getLayerText= getLayerText;
-		write.getDestFilename= getDestFilename;
-		write.computeLayerContents= computeLayerContents;
+
+		write.getLayerText = getLayerText;
+		write.getDestFilename = getDestFilename;
+		write.computeLayerContents = computeLayerContents;
 
 		return write;
 });
diff --git a/util/build/transforms/writeCss.js b/util/build/transforms/writeCss.js
index 8146aec..5f37cb2 100644
--- a/util/build/transforms/writeCss.js
+++ b/util/build/transforms/writeCss.js
@@ -1,63 +1,61 @@
-///
-// \amd-mid build/transforms/writeCssResources
-//
-// A function to compact CSS resources.
-//
-//
-define(["../buildControl", "../fileUtils", "../fs"], function(bc, fileUtils, fs) {
-	return function(resource, callback) {
+define([
+	"../buildControl",
+	"../fileUtils",
+	"../fs"
+], function(bc, fileUtils, fs){
+	return function(resource, callback){
 		var
-			waitCount= 0,
+			waitCount = 0,
 
-			errors= [],
+			errors = [],
 
-			onWriteComplete= function(err) {
-				if (err) {
+			onWriteComplete = function(err){
+				if(err){
 					errors.push(err);
 				}
-				if (--waitCount==0) {
+				if(--waitCount==0){
 					callback(resource, errors.length && errors);
 				}
 			},
 
-			doWrite= function(filename, text, encoding) {
+			doWrite = function(filename, text, encoding){
 				fileUtils.ensureDirectoryByFilename(filename);
 				waitCount++;
 				fs.writeFile(filename, bc.newlineFilter(text, resource, "writeCss"), encoding || "utf8", onWriteComplete);
 				// this must go *after* the async call
 			},
 
-			wroteExterns= 0;
+			wroteExterns = 0;
 
-		try {
+		try{
 			doWrite(resource.dest, resource.text);
-			if (resource.compactDest!=resource.dest) {
+			if(resource.compactDest!=resource.dest){
 				doWrite(resource.compactDest, resource.compactText);
 			}
 
 			// only need to tranverse bc.destDirToExternSet once...
-			if (wroteExterns) {
+			if(wroteExterns){
 				return callback;
 			}
-			wroteExterns= 1;
+			wroteExterns = 1;
 			// bc.destDirToExternSet is a map from dest directory name to resourceSet;
 			// resourceSet is a map from src filename (complete with path) to dest filename (name only)
 			// bc.destDirToExternSet[dir][src]= dest implies copy filename src to dir + "/" + dest
 			var
-				destDirToExternSet= bc.destDirToExternSet,
+				destDirToExternSet = bc.destDirToExternSet,
 				dir, resourceSet, src;
-			for (dir in destDirToExternSet) {
-				resourceSet= destDirToExternSet[dir];
-				for (src in resourceSet) {
+			for(dir in destDirToExternSet){
+				resourceSet = destDirToExternSet[dir];
+				for(src in resourceSet){
 					doWrite(dir + "/" + resourceSet[src], bc.resources[src].text, resource.encoding);
 				}
 			}
-		} catch (e) {
-			if (waitCount) {
+		}catch(e){
+			if(waitCount){
 				// can't return the error since there are async processes already going
 				errors.push(e);
 				return 0;
-			} else {
+			}else{
 				return e;
 			}
 		}
diff --git a/util/build/transforms/writeDojo.js b/util/build/transforms/writeDojo.js
index 8f48b56..62af488 100644
--- a/util/build/transforms/writeDojo.js
+++ b/util/build/transforms/writeDojo.js
@@ -1,16 +1,3 @@
-///
-// \amd-mid build/lib/transforms/writeBdLoad
-//
-// A function to write the bdLoad resource.
-//
-// The function writes the results of transforming the loader source. has.js is integrated as follows:
-//	 * if bc.has=="*build", then build/has/bdBuildHas is provided to the loader boot; otherwise...
-//	 * if bc.has.getText exists and is a function, then the result of that function is provided to the loader boot; otherwise...
-//	 * build/has/naiveHas is provided to the loader boot bc.loader.boots
-//
-// Other transforms may request a bootstrap be written for them that includes the loader and loader config. They
-// may execute such a request by pushing a function into bc.loader.boots. The function must return a [filename, text]
-// pair that indicates the bootstrap text to append to the loader and the destination to write the result.
 define([
 	"../buildControl",
 	"../fileUtils",
@@ -20,56 +7,56 @@ define([
 	"../process",
 	"dojo/json",
 	"dojo/text!./dojoBoot.js"
-], function(bc, fileUtils, fs, stringify, writeAmd, process, json, dojoBootText) {
-	return function(resource, callback) {
+], function(bc, fileUtils, fs, stringify, writeAmd, process, json, dojoBootText){
+	return function(resource, callback){
 		var
-			getUserConfig= function() {
-				if (!bc.userConfig) {
+			getUserConfig = function(){
+				if(!bc.userConfig){
 					return "this.dojoConfig || this.djConfig || this.require || {}";
 				}
 				if(typeof bc.userConfig == "string"){
 					return bc.userConfig;
 				}
-				var result= stringify(bc.userConfig);
-				if (result.unsolved) {
+				var result = stringify(bc.userConfig);
+				if(result.unsolved){
 					bc.log("configUnresolvedValues");
 				}
 				return result;
 			},
 
-			computeLocation= function(basePath, path) {
-				if (path.indexOf(basePath + "/")==0) {
+			computeLocation = function(basePath, path){
+				if(path.indexOf(basePath + "/")==0){
 					return "." + path.substring(basePath.length);
 				}
 				var
-					parts= basePath.split("/"),
-					prefix= "";
-				for (var i= parts.length-1; i>=0; i--) {
+					parts = basePath.split("/"),
+					prefix = "";
+				for(var i = parts.length-1; i>=0; i--){
 					 prefix+= (prefix ? "/.." : "..");
-					var check= parts.slice(0, i).join("/") + "/";
-					if (path.indexOf(check)==0) {
+					var check = parts.slice(0, i).join("/") + "/";
+					if(path.indexOf(check)==0){
 						return prefix + path.substring(check.length-1);
 					}
 				}
 				return path;
 			},
 
-			getPackage= function(name) {
+			getPackage = function(name){
 				// the purpose of this somewhat verbose routine is to write a minimal package object for each
 				// package, yet allow client code to pass extra (i.e., outside the scope of CJS specs) config
 				// information within the package object
-				var destPack= bc.destPackages[name],
-					result= {};
+				var destPack = bc.destPackages[name],
+					result = {};
 				result.name = destPack.name;
 				if(destPack.main!="main"){
 					result.main = destPack.main;
 				}
 				// everything relative to the dojo dir
 				// TODO: making everything relative to dojo needs to be optional
-				if (name=="dojo") {
-					result.location= ".";
-				} else {
-					result.location= computeLocation(bc.destBasePath + "/dojo", destPack.location);
+				if(name=="dojo"){
+					result.location = ".";
+				}else{
+					result.location = computeLocation(bc.destBasePath + "/dojo", destPack.location);
 				}
 				var packageDefaultConfig = bc.defaultConfig && bc.defaultConfig.packages && bc.defaultConfig.packages[name];
 				for(var p in packageDefaultConfig){
@@ -78,12 +65,12 @@ define([
 				return result;
 			},
 
-			getDefaultConfig= function() {
+			getDefaultConfig = function(){
 				var p, config = {packages:[], hasCache:{}};
-				if (bc.baseUrl) {
-					config.baseUrl= bc.baseUrl;
+				if(bc.baseUrl){
+					config.baseUrl = bc.baseUrl;
 				}
-				for (p in bc.packages) {
+				for(p in bc.packages){
 					config.packages.push(getPackage(p));
 				}
 				for(p in bc.defaultConfig){
@@ -92,17 +79,18 @@ define([
 						config[p] = bc.defaultConfig[p];
 					}
 				}
-				config= stringify(config);
-				if (config.unsolved) {
+				config = stringify(config);
+				if(config.unsolved){
 					bc.log("configUnresolvedValues");
 				}
 				return config;
 			},
 
-			stampVersion= function(text){
-				//summary: Changes the version number for dojo. Input should be the fileContents
-				//of a file that contains the version number.
-				version= bc.version;
+			stampVersion = function(text){
+				// summary:
+				//		Changes the version number for dojo. Input should be the fileContents
+				//		of a file that contains the version number.
+				version = bc.version;
 				if(version){
 					//First, break apart the version string.
 					var verSegments = (version+"").match(/^(\d*)\.?(\d*)\.?(\d*)\.?(.*)$/);
@@ -120,62 +108,60 @@ define([
 				}
 			},
 
-			waitCount= 1, // matches *1*
+			waitCount = 1, // matches *1*
 
-			errors= [],
+			errors = [],
 
-			onWriteComplete= function(err) {
-				if (err) {
+			onWriteComplete = function(err){
+				if(err){
 					errors.push(err);
 				}
-				if (--waitCount==0) {
+				if(--waitCount==0){
 					callback(resource, errors.length && errors);
 				}
 			},
 
-			doWrite= function(filename, text) {
+			doWrite = function(filename, text){
 				fileUtils.ensureDirectoryByFilename(filename);
 				waitCount++;
 				fs.writeFile(filename, bc.newlineFilter(text, resource, "writeDojo"), "utf8", onWriteComplete);
 			};
 
 		// the writeDojo transform...
-		try {
-			// all layer modules compute moduleSet, which may be used for reporting
-			resource.moduleSet= writeAmd.computeLayerContents(0, resource.layer.include, resource.layer.exclude);
-
+		try{
 			var
+				loaderText = resource.getText(),
+
 				// the default application to the loader constructor is replaced with purpose-build user and default config values
-				configText= "(" + getUserConfig() + ", " + getDefaultConfig() + ");",
+				configText = "(" + getUserConfig() + ", " + getDefaultConfig() + ");",
 
 				// the construction of the layer is slightly different than standard, so don't pass a module to getLayerText
-				layerText= writeAmd.getLayerText(0, resource.layer.include, resource.layer.exclude, resource.layer.noref),
+				dojoLayerText = stampVersion(writeAmd.getLayerText(resource, "")),
 
 				// 1.6 compat chunk
-				compat = (resource.layer.compat=="1.6" && resource.layer.include.length) ? "require(" + json.stringify(resource.layer.include) + ");" + bc.newline : "";
+				dojoLayerCompat = (resource.layer.compat=="1.6" && resource.layer.include.length) ? "require(" + json.stringify(resource.layer.include) + ");" + bc.newline : "";
 
 			// assemble and write the dojo layer
-			resource.layerText= resource.getText() + configText + stampVersion(layerText) + (bc.dojoBootText || dojoBootText) + compat;
-			doWrite(writeAmd.getDestFilename(resource), resource.layer.copyright + resource.layerText);
+			resource.uncompressedText = loaderText + configText + dojoLayerText + (bc.dojoBootText || dojoBootText) + dojoLayerCompat;
+			doWrite(writeAmd.getDestFilename(resource), resource.layer.copyright + resource.uncompressedText);
 
 			//write any bootstraps; boots is a vector of resources that have been marked as bootable by the discovery process
-			resource.boots.forEach(function(item) {
+			resource.boots.forEach(function(item){
 				// don't process the dojo layer, which is === resource
 				if(item!==resource){
 					// each item is a hash of include, exclude, boot, bootText
 					var compat = (item.layer.compat=="1.6" && item.layer.include.length) ? "require(" + json.stringify(item.layer.include) + ");" + bc.newline : "";
-					item.layerText= resource.layerText + writeAmd.getLayerText(item, item.layer.include, item.layer.exclude, true) + (item.bootText || "") + compat;
-					doWrite(writeAmd.getDestFilename(item), resource.layer.copyright + item.layerText);
+					item.uncompressedText= loaderText + configText + dojoLayerText + writeAmd.getLayerText(item, false) + (item.layer.bootText || bc.dojoBootText || dojoBootText) + dojoLayerCompat + compat;
+					doWrite(writeAmd.getDestFilename(item), resource.layer.copyright + item.uncompressedText);
 				}
 			});
-
 			onWriteComplete(0); // matches *1*
-		} catch (e) {
-			if (waitCount) {
+		}catch(e){
+			if(waitCount){
 				// can't return the error since there are async processes already going
 				errors.push(e);
 				return 0;
-			} else {
+			}else{
 				return e;
 			}
 		}
diff --git a/util/build/transforms/writeOptimized.js b/util/build/transforms/writeOptimized.js
index 3b04029..88fd608 100644
--- a/util/build/transforms/writeOptimized.js
+++ b/util/build/transforms/writeOptimized.js
@@ -1,297 +1,31 @@
-define(["../buildControl", "../process", "../fs", "../fileUtils", "dojo/has", "dojo"], function(bc, process, fs, fileUtils, has, dojo) {
-	var built = "//>>built" + bc.newline;
-
-	// default to a no-op
-	var compile = function(){};
-
-	if(has("host-rhino") && (bc.optimize || bc.layerOptimize)){
-		function sscompile(text, dest, optimizeSwitch, copyright){
-			// decode the optimize switch
-			var
-				options = optimizeSwitch.split("."),
-				comments = 0,
-				keepLines = 0,
-				strip = null;
-			while(options.length){
-				switch(options.pop()){
-				case "normal":
-					strip = "normal";
-					break;
-				case "warn":
-					strip = "warn";
-					break;
-				case "all":
-					strip = "all";
-					break;
-				case "keeplines":
-					keepLines = 1;
-					break;
-				case "comments":
-					comments = 1;
-					break;
-				}
-			}
-
-			//Use rhino to help do minifying/compressing.
-			var context = Packages.org.mozilla.javascript.Context.enter();
-			try{
-				// Use the interpreter for interactive input (copied this from Main rhino class).
-				context.setOptimizationLevel(-1);
-
-				if(comments){
-					//Strip comments
-					var script = context.compileString(text, dest, 1, null);
-					text = new String(context.decompileScript(script, 0));
-
-					//Replace the spaces with tabs.
-					//Ideally do this in the pretty printer rhino code.
-					text = text.replace(/    /g, "\t");
-				}else{
-					//Apply compression using custom compression call in Dojo-modified rhino.
-					text = new String(Packages.org.dojotoolkit.shrinksafe.Compressor.compressScript(text, 0, 1, strip));
-					if(!keepLines){
-						text = text.replace(/[\r\n]/g, "");
-					}
-				}
-			}finally{
-				Packages.org.mozilla.javascript.Context.exit();
-			}
-			return copyright +  built + text;
-		}
-
-		var JSSourceFilefromCode, closurefromCode, jscomp= 0;
-		function ccompile(text, dest, optimizeSwitch, copyright){
-			if(!jscomp){
-				// don't do this unless demanded...it may not be available
-				JSSourceFilefromCode=java.lang.Class.forName('com.google.javascript.jscomp.JSSourceFile').getMethod('fromCode',[java.lang.String,java.lang.String]);
-				closurefromCode = function(filename,content){
-					return JSSourceFilefromCode.invoke(null,[filename,content]);
-				};
-				jscomp = com.google.javascript.jscomp;
-			}
-			//Fake extern
-			var externSourceFile = closurefromCode("fakeextern.js", " ");
-
-			//Set up source input
-			var jsSourceFile = closurefromCode(String(dest), String(text));
-
-			//Set up options
-			var options = new jscomp.CompilerOptions();
-			options.prettyPrint = optimizeSwitch.indexOf(".keepLines") !== -1;
-
-			var FLAG_compilation_level = jscomp.CompilationLevel.SIMPLE_OPTIMIZATIONS;
-			FLAG_compilation_level.setOptionsForCompilationLevel(options);
-			var FLAG_warning_level = jscomp.WarningLevel.DEFAULT;
-			FLAG_warning_level.setOptionsForWarningLevel(options);
-
-			//Run the compiler
-			var compiler = new Packages.com.google.javascript.jscomp.Compiler(Packages.java.lang.System.err);
-			var result = compiler.compile(externSourceFile, jsSourceFile, options);
-			return copyright + built + compiler.toSource();
-		}
-
-		compile= function(resource, text, copyright, optimizeSwitch, callback){
-			bc.log("optimize", ["module", resource.mid]);
-			copyright = copyright || "";
-			var result;
-			if(/closure/.test(optimizeSwitch)){
-				result= ccompile(stripConsoleRe ? text.replace(stripConsoleRe, "0 && $&") : text, resource.dest, optimizeSwitch, copyright);
-			}else{
-				result= sscompile(text, resource.dest, optimizeSwitch, copyright);
-			}
-			fs.writeFile(resource.dest, result, resource.encoding, function(err){
-				if(err){
-					bc.log("optimizeFailedWrite", ["filename", result.dest]);
-				}
-				callback(resource, err);
-			});
-			return callback;
-		};
+define(["../buildControl", "require"], function(bc, require){
+	var optimizers = {};
+
+	function resolveComments(optimizer) {
+		// This is for back-compat of comments and comments.keepLines,
+		// after the refactor to separate optimizers placed this logic in shrinksafe.
+		// TODO: remove @ 2.0 (along with shrinksafe entirely, perhaps)
+		return /^comments/.test(optimizer) ? "shrinksafe." + optimizer : optimizer;
 	}
-	if(has("host-node") && (bc.optimize || bc.layerOptimize)){
-		// start up a few processes to compensate for the miserably slow closure compiler
 
-		var processes = [],
-			killAllRunners = function(){
-				processes.forEach(function(proc){
-					try{
-						proc.runner && proc.runner.kill();
-						proc.runner = 0;
-					}catch(e){
-						//squelch
-					}
-				});
-			};
-
-		// don't leave orphan child procs
-		global.process.on('exit', killAllRunners);
-		global.process.on('uncaughtException', function(err){
-			killAllRunners();
-			// TODO: log these via bc.log
-			console.log(err);
-			console.log(err.stack);
-			global.process.exit(-1);
+	if(bc.optimize){
+		bc.optimize = resolveComments(bc.optimize);
+		require(["./optimizer/" + bc.optimize.split(".")[0]], function(optimizer){
+			optimizers[bc.optimize] = optimizer;
 		});
-
-		var
-			processesStarted = 0,
-			totalOptimizerOutput = "",
-			nextProcId = 0,
-			i, //used in for loop
-			sendJob = function(src, dest, optimizeSwitch, copyright){
-				processes[nextProcId++].write(src, dest, optimizeSwitch, copyright);
-				nextProcId= nextProcId % bc.maxOptimizationProcesses;
-			},
-			tempFileDirs = {},
-			doneRe = new RegExp("^Done\\s\\(compile\\stime.+$", "m"),
-			optimizerRunner = require.toUrl("build/optimizeRunner.js"),
-			buildRoot = optimizerRunner.match(/(.+)\/build\/optimizeRunner\.js$/)[1],
-			runJava, //function, defined later
-			oldSendJob = sendJob, //preserves reference if sendJob is replaced
-			child_process = require.nodeRequire("child_process"),
-			javaClasses = fileUtils.catPath(buildRoot, "closureCompiler/compiler.jar") + ":" + fileUtils.catPath(buildRoot, "shrinksafe/js.jar") + ":" + fileUtils.catPath(buildRoot, "shrinksafe/shrinksafe.jar");
-			if(global.process.platform === 'cygwin'){
-				//assume we're working with Windows Java, and need to translate paths
-				runJava = function(cb){
-					child_process.exec("cygpath -wp '" + javaClasses + "'", function(err, stdout){
-						javaClasses = stdout.trim();
-						child_process.exec("cygpath -w '" + optimizerRunner + "'", function(err, stdout){
-							optimizerRunner = stdout.trim();
-							cb();
-						});
-					});
-				};
-				//wrap sendJob calls to convert to windows paths first
-				sendJob = function(src, dest, optimizeSwitch, copyright){
-					child_process.exec("cygpath -wp '" + src + "'", function(err, srcstdout){
-						child_process.exec("cygpath -wp '" + dest + "'", function(err, deststdout){
-							oldSendJob(srcstdout.trim(), deststdout.trim(),
-								optimizeSwitch, copyright);
-						});
-					});
-				};
-			}else{
-				//no waiting necessary, pass through
-				runJava = function(cb) { cb(); };
-			}
-		runJava(function(cp) {
-			for(i = 0; i < bc.maxOptimizationProcesses; i++) {(function(){
-				var
-					runner = child_process.spawn("java", ["-cp", javaClasses, "org.mozilla.javascript.tools.shell.Main", optimizerRunner]),
-					proc = {
-						runner:runner,
-						results:"",
-						tempResults:"",
-						sent:[],
-						write:function(src, dest, optimizeSwitch, copyright){
-							proc.sent.push(dest);
-							runner.stdin.write(src + "\n" + dest + "\n" + optimizeSwitch + "\n" + dojo.toJson(copyright) + "\n");
-						},
-						sink:function(output){
-							proc.tempResults += output;
-							var match, message, chunkLength;
-							while((match = proc.tempResults.match(doneRe))){
-								message = match[0];
-								bc.log("optimizeDone", [proc.sent.shift() + " " + message.substring(5)]);
-								chunkLength = match.index + message.length;
-								proc.results += proc.tempResults.substring(0, chunkLength);
-								proc.tempResults = proc.tempResults.substring(chunkLength);
-							}
-						}
-					};
-				processesStarted++; // matches *3*
-				runner.stdout.on("data", function(data){
-					// the +"" converts to Javascript string
-					proc.sink(data + "");
-				}),
-				runner.stderr.on("data", function(data){
-					// the +"" converts to Javascript string
-					proc.sink(data + "");
-				}),
-				runner.on("exit", function(code){
-					// TODO: figure out how to stop closure compiler from emmitting this drivel
-					proc.results += proc.tempResults;
-					totalOptimizerOutput += proc.results.
-						replace(/\n[^\n]+com.google.javascript.jscomp.PhaseOptimizer[^\n]+\n[^\n]+/g, "").
-						replace(/\n[^\n]+com.google.javascript.jscomp.Compiler[^\n]+\n[^\n]+/g, "");
-					bc.logOptimizerOutput(totalOptimizerOutput);
-					processesStarted--; // matches *3*
-					if(!processesStarted){
-						// all the processes have completed and shut down at this point
-						if(1 || bc.showOptimizerOutput){
-							bc.log("optimizeMessages", [totalOptimizerOutput]);
-						}
-						/*
-						for(var p in tempFileDirs){
-							bc.waiting++;  // matched with *2*
-							var
-								cb= function(code, text){
-									bc.passGate(); // matched with *2*
-								},
-								filename= p + "/*consoleStripped*",
-								errorMessage= "failed to delete temporary files (" + filename + ")",
-								args= has("is-windows") ?
-									["cmd", "/c", "del", fileUtils.normalize(filename), errorMessage, bc, cb] :
-									["rm", filename, errorMessage, bc, cb];
-							process.exec.apply(args);
-						}
-						*/
-						bc.passGate(); // matched with *1*
-					}
-				});
-				processes.push(proc);
-			})();}
-		}); //end runJava(function...)
-
-		bc.gateListeners.push(function(gate){
-			if(gate=="cleanup"){
-				// going through the cleanup gate signals that all optimizations have been started;
-				// we now signal the runner there are no more files and wait for the runner to stop
-				bc.log("pacify", "waiting for the optimizer runner to finish...");
-				bc.waiting++;  // matched with *1*
-				processes.forEach(function(proc){
-					proc.write(".\n");
-				});
-				processes = [];
-			}
+	}
+	if(bc.layerOptimize){
+		bc.layerOptimize = resolveComments(bc.layerOptimize);
+		require(["./optimizer/" + bc.layerOptimize.split(".")[0]], function(optimizer){
+			optimizers[bc.layerOptimize] = optimizer;
 		});
-
-		var stripConsoleRe= 0;
-		if(bc.stripConsole){
-			var consoleMethods = "assert|count|debug|dir|dirxml|group|groupEnd|info|profile|profileEnd|time|timeEnd|trace|log";
-			if(bc.stripConsole == "warn"){
-				consoleMethods += "|warn";
-			}else if(bc.stripConsole == "all"){
-				consoleMethods += "|warn|error";
-			}
-			stripConsoleRe= new RegExp("console\\.(" + consoleMethods + ")\\s*\\(", "g");
-		}
-
-		compile = function(resource, text, copyright, optimizeSwitch, callback){
-			copyright = copyright || "";
-			if(stripConsoleRe && /closure/.test(optimizeSwitch)){
-				var tempFilename = resource.dest + ".consoleStripped.js";
-				text= text.replace(stripConsoleRe, "0 && $&");
-				tempFileDirs[fileUtils.getFilepath(tempFilename)]= 1;
-				fs.writeFile(tempFilename, bc.newlineFilter(text, resource, "closureStripConsole"), resource.encoding, function(err){
-					if(!err){
-						sendJob(tempFilename, resource.dest, optimizeSwitch, copyright);
-					}
-					callback(resource, err);
-				});
-				return callback;
-			}else{
-				sendJob(resource.dest + ".uncompressed.js", resource.dest, optimizeSwitch, copyright);
-				return 0;
-			}
-		};
 	}
 
 	return function(resource, callback) {
 		if(bc.optimize && !resource.layer){
-			return compile(resource, resource.getText(), resource.pack.copyright, bc.optimize, callback);
+			return optimizers[bc.optimize](resource, resource.uncompressedText, resource.pack.copyright, bc.optimize, callback);
 		}else if(bc.layerOptimize && resource.layer && !resource.layer.discard){
-			return compile(resource, resource.layerText, resource.layer.copyright, bc.layerOptimize, callback);
+			return optimizers[bc.layerOptimize](resource, resource.uncompressedText, resource.layer.copyright, bc.layerOptimize, callback);
 		}else{
 			return 0;
 		}
diff --git a/util/build/v1xProfiles.js b/util/build/v1xProfiles.js
index 07c598d..c745810 100644
--- a/util/build/v1xProfiles.js
+++ b/util/build/v1xProfiles.js
@@ -1,10 +1,8 @@
 define([
 	"require",
 	"./buildControlBase",
-	"./fs", "./fileUtils",
-	"./process",
-	"dojo"
-], function(require, bc, fs, fileUtils, process, dojo){
+	"./fs", "./fileUtils"
+], function(require, bc, fs, fileUtils){
 	eval(require.scopeify("./fs, ./fileUtils"));
 	var mix = function(dest, src){
 			dest = dest || {};
@@ -40,11 +38,11 @@ define([
 			//
 			//	 * the util/buildscripts/ directory is assumed to be the cwd upon build program startup
 			//	 * the dojo directory as specified in profile dependencies.prefixes (if relative) is
-			//     assumed to be relative to util/buildscripts/; usually, it is not explicitly specified
-			//     and is automatically set by the v1.6 build application to ../../dojo.
+			//	   assumed to be relative to util/buildscripts/; usually, it is not explicitly specified
+			//	   and is automatically set by the v1.6 build application to ../../dojo.
 			//	 * similarly the releaseDir directory (if relative) is assumed to be relative to util/buildscripts/
 			//	 * all other relative paths are relative to the dojo directory (in spite of what some docs say)
-			//   * all input module hierarchies are "flattened" so they are siblings of the dojo directory
+			//	 * all input module hierarchies are "flattened" so they are siblings of the dojo directory
 			//
 			// This has the net effect of forcing the assumption that build program is be executed from util/buildscripts.
 			// when relative paths are used; this may be inconvenient. The behavior is probably consequent to rhino's design
@@ -331,11 +329,6 @@ define([
 				prefixes: prefixPaths,
 				basePath:basePath
 			};
-
-			if(bc.writeProfile){
-				// FIXME: cann't use bc.newlineFilter here because profile has not been fully initialized; move this to buildControl.js
-				fs.writeFileSync(bc.writeProfile, "dependencies = " + dojo.toJson(profileProperties, true), "utf8");
-			}
 			return processProfile(profileProperties, dojoPath, utilBuildscriptsPath);
 		};
 
diff --git a/util/buildscripts/LICENSE b/util/buildscripts/LICENSE
index aa6b39f..b1ddd34 100644
--- a/util/buildscripts/LICENSE
+++ b/util/buildscripts/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2011, The Dojo Foundation
+Copyright (c) 2005-2013, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/util/buildscripts/build.bat b/util/buildscripts/build.bat
index fa38e58..6ef02dd 100644
--- a/util/buildscripts/build.bat
+++ b/util/buildscripts/build.bat
@@ -3,9 +3,7 @@
 @rem Something like this will be required for cygwin... node is not 100% confirmed working at this point
 @rem node ../../dojo/dojo.js load=build %*
 
-
-java -Xms256m -Xmx256m  -cp ../shrinksafe/js.jar;../closureCompiler/compiler.jar;../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main  ../../dojo/dojo.js baseUrl=../../dojo load=build %*
-
+java -Xms256m -Xmx256m  -cp "%~dp0../shrinksafe/js.jar";"%~dp0../closureCompiler/compiler.jar";"%~dp0../shrinksafe/shrinksafe.jar" org.mozilla.javascript.tools.shell.Main  "%~dp0../../dojo/dojo.js" baseUrl="%~dp0../../dojo" load=build %*
 
 @rem java -classpath ../shrinksafe/js.jar;../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main build.js %*
 
diff --git a/util/buildscripts/build.js b/util/buildscripts/build.js
index 3f70a0c..881395f 100644
--- a/util/buildscripts/build.js
+++ b/util/buildscripts/build.js
@@ -258,8 +258,9 @@ function release(){
 
 //********* Start _copyToRelease *********
 function _copyToRelease(/*String*/prefixName, /*String*/prefixPath, /*Object*/kwArgs, /*Array?*/buildLayers){
-	//summary: copies modules and supporting files from the prefix path to the release
-	//directory. Also adds code guards to module resources.
+	// summary:
+	//		copies modules and supporting files from the prefix path to the release
+	//		directory. Also adds code guards to module resources.
 	var prefixSlashName = prefixName.replace(/\./g, "/");
 	var releasePath = kwArgs.releaseDir + "/"  + prefixSlashName;
 	var copyRegExps = {
@@ -344,8 +345,9 @@ function _optimizeReleaseDirs(
 	/*Object*/kwArgs,
 	/*RegExp*/layerIgnoreRegExp,
 	/*RegExp*/nlsIgnoreRegExp){
-	//summary: runs intern strings, i18n bundle flattening and xdomain file generation
-	//on the files in a release directory, if those options are enabled.
+	// summary:
+	//		runs intern strings, i18n bundle flattening and xdomain file generation
+	//		on the files in a release directory, if those options are enabled.
 	var releasePath = kwArgs.releaseDir + "/"  + prefixName.replace(/\./g, "/");
 	var prefixes = kwArgs.profileProperties.dependencies.prefixes;
 
diff --git a/util/buildscripts/build.sh b/util/buildscripts/build.sh
index 9b9bfb6..22264d4 100755
--- a/util/buildscripts/build.sh
+++ b/util/buildscripts/build.sh
@@ -19,8 +19,8 @@ OPTIONS
                 Specifies the Javascript environment to use. Defaults to node, if available, java otherwise.
      
                 node             use node.js, if available, automatic downgrade to java
-                node-dbg         same as node, with the --debug argument
-                node-dbg-brk     same as node with the --debug-brk argument
+                node-debug         same as node, with the --debug argument
+                node-debug-brk     same as node with the --debug-brk argument
                 java             use java
      
      Note: the alternative syntax bin=option is supported but deprecated.
diff --git a/util/buildscripts/build_release.sh b/util/buildscripts/build_release.sh
index fc45f57..3bd9936 100755
--- a/util/buildscripts/build_release.sh
+++ b/util/buildscripts/build_release.sh
@@ -1,15 +1,17 @@
 #!/bin/bash
 
-#version should be something like 0.9.0beta or 0.9.0
+# version should be something like 0.9.0beta or 0.9.0
 version=$1
-#svnUserName is the name you use to connect to Dojo's subversion.
+
+# svnUserName is the name you use to connect to Dojo's subversion.
 svnUserName=$2
-#The svn revision number to use for tag. Should be a number, like 11203
+
+# The svn revision number to use for tag. Should be a number, like 11203
 svnRevision=$3
 
-#If no svnRevision number, get the latest one from the repo.
+# If no svnRevision number, get the latest one from he repo.
 if [ "$svnRevision" = "" ]; then
-	svnRevision=`svn info http://svn.dojotoolkit.org/src/branches/1.7/util/buildscripts/build_release.sh | grep Revision | sed 's/Revision: //'`
+	svnRevision=`svn info http://svn.dojotoolkit.org/src/branches/1.9/util/buildscripts/build_release.sh | grep Revision | sed 's/Revision: //'`
 fi
 
 tagName=release-$version
@@ -18,25 +20,25 @@ buildName=dojo-$tagName
 echo "This is a RELEASE build for Dojo, you probably meant to run build.sh"
 read -p "If you mean to create a tag for Dojo $version from r$svnRevision ... press a key to continue."
 
-#Make the SVN tag.
+# Make the SVN tag.
 svn mkdir -m "Using r$svnRevision to create a tag for the $version release." https://svn.dojotoolkit.org/src/tags/$tagName
-svn copy -r $svnRevision https://svn.dojotoolkit.org/src/branches/1.7/dojo  https://svn.dojotoolkit.org/src/tags/$tagName/dojo -m "Using r$svnRevision to create a tag for the $version release."
-svn copy -r $svnRevision https://svn.dojotoolkit.org/src/branches/1.7/dijit https://svn.dojotoolkit.org/src/tags/$tagName/dijit -m "Using r$svnRevision to create a tag for the $version release."
-svn copy -r $svnRevision https://svn.dojotoolkit.org/src/branches/1.7/dojox https://svn.dojotoolkit.org/src/tags/$tagName/dojox -m "Using r$svnRevision to create a tag for the $version release."
-svn copy -r $svnRevision https://svn.dojotoolkit.org/src/branches/1.7/util  https://svn.dojotoolkit.org/src/tags/$tagName/util -m "Using r$svnRevision to create a tag for the $version release."
-svn copy -r $svnRevision https://svn.dojotoolkit.org/src/branches/1.7/demos https://svn.dojotoolkit.org/src/tags/$tagName/demos -m "Using r$svnRevision to create a tag for the $version release."
+svn copy -r $svnRevision https://svn.dojotoolkit.org/src/branches/1.9/dojo  https://svn.dojotoolkit.org/src/tags/$tagName/dojo -m "Using r$svnRevision to create a tag for the $version release."
+svn copy -r $svnRevision https://svn.dojotoolkit.org/src/branches/1.9/dijit https://svn.dojotoolkit.org/src/tags/$tagName/dijit -m "Using r$svnRevision to create a tag for the $version release."
+svn copy -r $svnRevision https://svn.dojotoolkit.org/src/branches/1.9/dojox https://svn.dojotoolkit.org/src/tags/$tagName/dojox -m "Using r$svnRevision to create a tag for the $version release."
+svn copy -r $svnRevision https://svn.dojotoolkit.org/src/branches/1.9/util  https://svn.dojotoolkit.org/src/tags/$tagName/util -m "Using r$svnRevision to create a tag for the $version release."
+svn copy -r $svnRevision https://svn.dojotoolkit.org/src/branches/1.9/demos https://svn.dojotoolkit.org/src/tags/$tagName/demos -m "Using r$svnRevision to create a tag for the $version release."
 
-#Check out the tag
+# Check out the tag
 mkdir ../../build
 cd ../../build
 svn co https://svn.dojotoolkit.org/src/tags/$tagName $buildName
 cd $buildName/util/buildscripts
 
-#Update the dojo version in the tag
-java -jar ../shrinksafe/js.jar changeVersion.js $version ../../dojo/_base/kernel.js
-java -jar ../shrinksafe/js.jar changeVersion.js $version ../../dojo/package.json
-java -jar ../shrinksafe/js.jar changeVersion.js $version ../../dijit/package.json
-java -jar ../shrinksafe/js.jar changeVersion.js $version ../../dojox/package.json
+# Update the dojo version in the tag
+java -jar ../shrinksafe/js.jar changeVersion.js $version $svnRevision ../../dojo/_base/kernel.js
+java -jar ../shrinksafe/js.jar changeVersion.js $version $svnRevision ../../dojo/package.json
+java -jar ../shrinksafe/js.jar changeVersion.js $version $svnRevision ../../dijit/package.json
+java -jar ../shrinksafe/js.jar changeVersion.js $version $svnRevision ../../dojox/package.json
 cd ../../dojo
 svn commit -m "Updating dojo version for the tag. \!strict" package.json _base/kernel.js
 cd ../dijit
@@ -44,7 +46,7 @@ svn commit -m "Updating dijit version for the tag. \!strict" package.json
 cd ../dojox
 svn commit -m "Updating dojox version for the tag. \!strict" package.json
 
-#Erase the SVN dir and replace with an exported SVN contents.
+# Erase the SVN dir and replace with an exported SVN contents.
 cd ../..
 rm -rf ./$buildName/
 svn export http://svn.dojotoolkit.org/src/tags/$tagName $buildName
@@ -53,7 +55,7 @@ svn export http://svn.dojotoolkit.org/src/tags/$tagName $buildName
 rm -rf ./$buildName/dijit/themes/noir
 rm -rf ./$buildName/dijit/bench
 
-#Make a shrinksafe bundle
+# Make a shrinksafe bundle
 shrinksafeName=$buildName-shrinksafe
 cp -r $buildName/util/shrinksafe $buildName/util/$shrinksafeName
 cd $buildName/util
@@ -64,7 +66,7 @@ mv $shrinksafeName.tar.gz ../../
 cd ../..
 rm -rf $buildName/util/$shrinksafeName
 
-#Make a -demos bundle (note, this is before build. Build profile=demos-all if you want to release them)
+# Make a -demos bundle (note, this is before build. Build profile=demos-all if you want to release them)
 # the -demos archives are meant to be extracted from the same folder -src or release archives, and have
 # a matching prefixed folder in the archive
 demoName=$buildName-demos
@@ -73,14 +75,14 @@ tar -zcf $demoName.tar.gz $buildName/demos/
 # prevent demos/ from appearing in the -src build
 rm -rf $buildName/demos
 
-#Make a src bundle
+# Make a src bundle
 srcName=$buildName-src
 mv $buildName $srcName
 zip -rq $srcName.zip $srcName/
 tar -zcf $srcName.tar.gz $srcName/
 mv $srcName $buildName
 
-#Run the build.
+# Run the build.
 cd $buildName/util/buildscripts/
 chmod +x ./build.sh
 ./build.sh profile=standard version=$1 releaseName=$buildName cssOptimize=comments.keepLines optimize=shrinksafe.keepLines action=release insertAbsMids=1
@@ -89,18 +91,18 @@ chmod +x ./clean_release.sh
 ./clean_release.sh ../../release $buildName
 cd ../../release/
 
-#Pause to allow manual process of packing Dojo.
+# Pause to allow manual process of packing Dojo.
 currDir=`pwd`
 echo "You can find dojo in $currDir/$buildName/dojo/dojo.js"
 read -p "Build Done. If you want to pack Dojo manually, do it now, then press Enter to continue build packaging..."
 
-#Continuing with packaging up the release.
+# Continuing with packaging up the release.
 zip -rq $buildName.zip $buildName/
 tar -zcf $buildName.tar.gz $buildName/
 mv $buildName.zip ../../
 mv $buildName.tar.gz ../../
 
-#copy compressed and uncompressed Dojo to the root
+# copy compressed and uncompressed Dojo to the root
 cp $buildName/dojo/dojo.js* ../../
 
 # remove the testless release build, and unpack a -src archive to rebuild from
@@ -118,11 +120,7 @@ mv $buildName ../../
 cd ..
 rm -rf release/
 
-# generate api.xml and api.json
-cd util/docscripts/
-php -q generate.php
-mv cache/api.* ../../../../build/
-cd ../../../../
+cd ../../
 
 # make a folder structure appropriate for directly extracting on downloads.dojotoolkit.org
 mv build release-$1
@@ -149,10 +147,9 @@ fi
 cd ..
 tar -czvf dj-$1-dtk.tar.gz release-$1
 
-#Finished.
+# Finished.
 outDirName=`pwd`
 echo "Build complete. Files are in: $outDirName"
 echo "A copy/paste command to push files to download.dojotoolkit.org with permission:"
 echo "scp dj-$1-dtk.tar.gz download.dojotoolkit.org:/srv/www/vhosts.d/download.dojotoolkit.org"
 echo "... then extract in place and rm dj-$1-dtk.tar.gz"
-cd ../util/buildscripts
diff --git a/util/buildscripts/cdnBuild.sh b/util/buildscripts/cdnBuild.sh
index 23ace95..efe010f 100755
--- a/util/buildscripts/cdnBuild.sh
+++ b/util/buildscripts/cdnBuild.sh
@@ -12,14 +12,13 @@ if [ -z $version ]; then
 fi
 
 dobuild() {
-	java -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main ../../dojo/dojo.js baseUrl=../../dojo load=build profile=standard profile=cdn releaseName=$1 cssOptimize=comments.keepLines optimize=shrinksafe stripConsole=normal version=$1 copyTests=false mini=true action=release
+	./build.sh profile=standard profile=cdn releaseName=$1 cssOptimize=comments.keepLines optimize=closure layerOptimize=closure stripConsole=normal version=$1 copyTests=false mini=true action=release
 	mv ../../release/$1 ../../release/$1-cdn
 	cd ../../release/$1-cdn
 	zip -rq $1.zip $1/*
 	sha1sum $1.zip > sha1.txt
 	cd $1
 	find . -type f -exec sha1sum {} >> ../sha1.txt \;
-	cd ../../../../util/buildscripts
 }
 
 # Generate locale info
diff --git a/util/buildscripts/changeVersion.js b/util/buildscripts/changeVersion.js
index 36e6848..bd71389 100644
--- a/util/buildscripts/changeVersion.js
+++ b/util/buildscripts/changeVersion.js
@@ -1,9 +1,9 @@
-//Changes the Dojo version in a file. Used during the release process.
+// Changes the Dojo version in a file. Used during the release process.
 
 var
 	version = new String(arguments[0]),
-
-	filename = new String(arguments[1]),
+	revision = new String(arguments[1]),
+	filename = new String(arguments[2]),
 
 	writeFile= function(filename, contents){
 		var
@@ -20,8 +20,9 @@ var
 
 
 	changeVersion = function(/*String*/version, /*String*/fileContents){
-		//summary: Changes the version number for dojo. Input should be the fileContents
-		//of a file that contains the version number.
+		// summary:
+		//		Changes the version number for dojo. Input should be the fileContents
+		//		of a file that contains the version number.
 
 		//Set version number.
 		//First, break apart the version string.
@@ -31,17 +32,18 @@ var
 		var patchValue = verSegments[3] || 0;
 		var flagValue  = verSegments[4] || "";
 
-		//Do the final version replacement.
+		// Do the final version replacement.
 		if(/package/.test(filename)){
 			fileContents = fileContents.replace(
-				/['"]version['"]\s*\:\s*['"][\w\.\-]+?["']/,
-				'"version":"' + version + '"'
+				/['"](version|dojo|dijit)['"]\s*\:\s*['"][\w\.\-]+?["']/g,
+				'"$1":"' + version + '"'
 			);
 		}else{
 			fileContents = fileContents.replace(
 				/major:\s*\d*,\s*minor:\s*\d*,\s*patch:\s*\d*,\s*flag:\s*".*?"\s*,/g,
 				"major: " + majorValue + ", minor: " + minorValue + ", patch: " + patchValue + ", flag: \"" + flagValue + "\","
 			);
+			fileContents = fileContents.replace(/\$Rev(: \d+ |)\$/, "$Rev: " + revision + " $");
 		}
 
 		return fileContents; //String
@@ -51,4 +53,4 @@ print(version);
 print(filename);
 var fileContents = readFile(filename, "utf-8");
 fileContents = changeVersion(version, fileContents);
-writeFile(filename, fileContents);
\ No newline at end of file
+writeFile(filename, fileContents);
diff --git a/util/buildscripts/cldr/alias.js b/util/buildscripts/cldr/alias.js
index 21f663d..cec417c 100644
--- a/util/buildscripts/cldr/alias.js
+++ b/util/buildscripts/cldr/alias.js
@@ -9,7 +9,7 @@
  * #2 is covered by 'specialLocale.js' and may need enhancement for future CLDR versions.
  */
 
-djConfig={baseUrl: "../../../dojo/"};
+djConfig={baseUrl: "../../../dojo/", paths: {"dojo/_base/xhr": "../util/buildscripts/cldr/xhr"}};
 
 load("../../../dojo/dojo.js");
 load("../jslib/logger.js");
@@ -23,7 +23,7 @@ var logDir = arguments[1];
 var logStr = "";
 
 //Add new bundles to the list so that they will be aliased according to the ldml spec.
-var BUNDLES = ['gregorian','hebrew','islamic','islamic-civil','buddhist'];
+var BUNDLES = ['gregorian','hebrew','islamic','islamic-civil','buddhist','persian'];
 
 var LOCALE_ALIAS_MARK = '@localeAlias';
 var LOCALE_ALIAS_SOURCE_PROPERTY = 'source';
@@ -108,12 +108,14 @@ function _calculateAliasPath(bundle, name/*String*/){
 }
 
 function _processLocaleAlias(localeAliasPaths/*Array*/, bundle/*JSON Obj*/, nativeSrcBundle/*JSON Obj*/,locale/*String*/){
-	//Summary: Update all properties as defined by 'locale' alias mapping
-	//		   E.g.'months-format-abbr at localeAlias6':{'target':"months-format-wide", 'bundle':"gregorian"},
-	//		   means the array values of 'months-format-abbr' in current bundle should be
-	//		   merged with(inherit or overwrite) that of 'months-format-wide' in 'gregorian' bundle
+	// summary:
+	//		Update all properties as defined by 'locale' alias mapping
+	//		E.g.'months-format-abbr at localeAlias6':{'target':"months-format-wide", 'bundle':"gregorian"},
+	//		means the array values of 'months-format-abbr' in current bundle should be
+	//		merged with(inherit or overwrite) that of 'months-format-wide' in 'gregorian' bundle
 	//
-	//Note:	   Currently no bundle recognition, always assume 'gregorian'.
+	//		Note:	   Currently no bundle recognition, always assume 'gregorian'.
+
 	var processed = {};
 	for(var i = 0; i < localeAliasPaths.length; i++){
 		var path = localeAliasPaths[i];
diff --git a/util/buildscripts/cldr/arrayInherit.js b/util/buildscripts/cldr/arrayInherit.js
index b1ed693..fd2b2c7 100644
--- a/util/buildscripts/cldr/arrayInherit.js
+++ b/util/buildscripts/cldr/arrayInherit.js
@@ -35,7 +35,7 @@
  *    })
  */
 
-djConfig={baseUrl: "../../../dojo/"};
+djConfig={baseUrl: "../../../dojo/", paths: {"dojo/_base/xhr": "../util/buildscripts/cldr/xhr"}};
 
 load("../../../dojo/dojo.js");
 load("../jslib/logger.js");
@@ -45,11 +45,11 @@ load("cldrUtil.js");
 dojo.require("dojo.i18n");
 
 var _searchLocalePath = function(/*String*/locale, /*Boolean*/down, /*Function*/searchFunc){
-    //      summary:                                                                                                                   
-    //              A helper method to assist in searching for locale-based resources.                                                 
-    //              Will iterate through the variants of a particular locale, either up                                                
-    //              or down, executing a callback function.  For example, "en-us" and                                                  
-    //              true will try "en-us" followed by "en" and finally "ROOT".                                                         
+    // summary:
+    //		A helper method to assist in searching for locale-based resources.
+    //		Will iterate through the variants of a particular locale, either up
+    //		or down, executing a callback function.  For example, "en-us" and
+    //		true will try "en-us" followed by "en" and finally "ROOT".
 
     locale = dojo.i18n.normalizeLocale(locale);
 
diff --git a/util/buildscripts/cldr/build.xml b/util/buildscripts/cldr/build.xml
index ce856bc..648edaa 100644
--- a/util/buildscripts/cldr/build.xml
+++ b/util/buildscripts/cldr/build.xml
@@ -98,7 +98,7 @@
 		<scriptdef name="removeEmptyOutput" language="javascript">
 			<attribute name="dir"/>
 			<![CDATA[
-		function isEmpty(o){
+		var isEmpty = function(o){
 			for(x in o){
 				return false;
 			}
@@ -106,7 +106,7 @@
 		}
 
 		var delTask = project.createTask("delete");
-		function deleteResource(f){
+		var deleteResource = function(f){
 			f.isDirectory() ? delTask.setDir(f) : delTask.setFile(f);
 			delTask.perform();
 		}
@@ -120,6 +120,7 @@
 
 	var load = project.createTask("loadfile");
 	load.setEncoding("UTF8");
+
 	for (var i=0; i<jsFiles.length; i++) {
 		var srcFile = java.io.File(dir, jsFiles[i]);
 		load.setSrcFile(srcFile);
@@ -131,12 +132,16 @@
 		var contents = String(project.getProperty(uniqueId));
 		if(contents.charCodeAt(0) == 0xfeff){ contents = contents.substring(1); } // JDK bug workaround
 
+		var value;
+
 		try{
-			var value = eval(contents);
+			value = eval(contents);
 		}catch(e){
 			java.lang.System.out.print("Syntax error in "+srcFile.getCanonicalPath());
+java.lang.System.out.print(contents);
 			throw e;
 		}
+
 		if(isEmpty(value)){
 			deleteResource(srcFile);
 		}
diff --git a/util/buildscripts/cldr/calendar.xsl b/util/buildscripts/cldr/calendar.xsl
index 859d42d..9aa43b1 100644
--- a/util/buildscripts/cldr/calendar.xsl
+++ b/util/buildscripts/cldr/calendar.xsl
@@ -49,8 +49,8 @@
                         <xsl:for-each select="calendars">
                             <xsl:call-template name="top"></xsl:call-template>
                         </xsl:for-each>
-                    </xsl:if>                 
-                </xsl:otherwise>
+                    </xsl:if>
+				</xsl:otherwise>
             </xsl:choose>
          </xsl:otherwise>
     </xsl:choose>        
@@ -82,12 +82,19 @@
         </xsl:when>
         <xsl:otherwise>
             <xsl:apply-templates/>
-        </xsl:otherwise>
+
+			<!-- <fields> used to be under <calendar> but now it's a sibling of <calendars> -->
+			<xsl:for-each select="../../fields">
+				<xsl:call-template name="fields">
+					<xsl:with-param name="width" select="@type"></xsl:with-param>
+				</xsl:call-template>
+			</xsl:for-each>
+		</xsl:otherwise>
     </xsl:choose>
 </xsl:template>
 
 <!-- process months | days | quarters | dayPeriods -->
-    <xsl:template name="months_days_quarters_dayPeriods" match="months | days | quarters | dayPeriods">
+<xsl:template name="months_days_quarters_dayPeriods" match="months | days | quarters | dayPeriods">
     <xsl:param name="name" select="name()"/>
     <xsl:param name="width" select="@type"/>
     <xsl:param name="ctx" select="../@type"/>
@@ -207,26 +214,26 @@
     </xsl:choose>
 </xsl:template>
   
-    <!-- template for inserting 'locale' alias information, 
-           e.g. for     <calendar type="buddhist">
-                                <months>
-                                    <alias source="locale" path="../../calendar[@type='gregorian']/months"/>
-                                </months>
-                                      ......
-         alias info will be recorded as 'months at localeAlias' : {'target':"months", 'bundle' : 'gregorian'}    -->
-    <xsl:template name="insert_alias_info">
-        <!-- alias source node name-->
-        <xsl:param name="sourceName" select="name()"></xsl:param>
-        <!-- alias target node name, same as source node by default-->
-        <xsl:param name="targetName" select="$sourceName"></xsl:param>
-        <!-- alias target bundle-->
-        <xsl:param name="bundle" select="../@type"></xsl:param>
-        <xsl:call-template name="insert_comma"/>
-	'<xsl:value-of select="$sourceName"/><xsl:text>@localeAlias</xsl:text>
-		<xsl:value-of select="$index"/><saxon:assign name="index" select="sum($index + 1)"/>
-		<xsl:text>':{'target':"</xsl:text><xsl:value-of select="$targetName"/><xsl:text>", 'bundle':"</xsl:text>
-        <xsl:value-of select="$bundle"/><xsl:text>"}</xsl:text>
-    </xsl:template>
+<!-- template for inserting 'locale' alias information,
+	   e.g. for     <calendar type="buddhist">
+							<months>
+								<alias source="locale" path="../../calendar[@type='gregorian']/months"/>
+							</months>
+								  ......
+	 alias info will be recorded as 'months at localeAlias' : {'target':"months", 'bundle' : 'gregorian'}    -->
+<xsl:template name="insert_alias_info">
+	<!-- alias source node name-->
+	<xsl:param name="sourceName" select="name()"></xsl:param>
+	<!-- alias target node name, same as source node by default-->
+	<xsl:param name="targetName" select="$sourceName"></xsl:param>
+	<!-- alias target bundle-->
+	<xsl:param name="bundle" select="../@type"></xsl:param>
+	<xsl:call-template name="insert_comma"/>
+'<xsl:value-of select="$sourceName"/><xsl:text>@localeAlias</xsl:text>
+	<xsl:value-of select="$index"/><saxon:assign name="index" select="sum($index + 1)"/>
+	<xsl:text>':{'target':"</xsl:text><xsl:value-of select="$targetName"/><xsl:text>", 'bundle':"</xsl:text>
+	<xsl:value-of select="$bundle"/><xsl:text>"}</xsl:text>
+</xsl:template>
     
 	
 <!--process am & noon & pm for <dayPeriod> -->
@@ -663,6 +670,8 @@
     </saxon:while>   
 </xsl:template>
     
+<xsl:template name="ignore" match="cyclicNameSets | monthPatterns"></xsl:template>
+
   <!-- too bad that can only use standard xsl:call-template(name can not be variable) 
          error occurs if use <saxon:call-templates($templateToCall)  /> -->
  <xsl:template name="invoke_template_by_name">
diff --git a/util/buildscripts/cldr/cldrUtil.js b/util/buildscripts/cldr/cldrUtil.js
index 66357cd..913ad4c 100644
--- a/util/buildscripts/cldr/cldrUtil.js
+++ b/util/buildscripts/cldr/cldrUtil.js
@@ -1,8 +1,3 @@
-// monkey-patch dojo.xhrGet, as there is no Rhino support there
-dojo.xhrGet = function(args){
-    args.load(readFile(args.url, "utf-8"));
-};
-
 (function(){
 	// monkey patch fromJson to avoid Rhino bug in eval: https://bugzilla.mozilla.org/show_bug.cgi?id=471005
 	var fromJson = dojo.fromJson;
@@ -31,9 +26,10 @@ function isLocaleAliasSrc(prop, bundle){
 }
 
 function getNativeBundle(filePath){
-	//summary: get native bundle content with utf-8 encoding
-	//	native means the content of this bundle is not flattened with parent
-	//	returns empty object if file not found
+	// summary:
+	//		get native bundle content with utf-8 encoding.
+	//		native means the content of this bundle is not flattened with parent.
+	//		returns empty object if file not found.
 	try{
 		var content = readFile(filePath, "utf-8");
 		return (!content || !content.length) ? {} : dojo.fromJson(content);
@@ -43,7 +39,8 @@ function getNativeBundle(filePath){
 }
 
 function compare(a/*String or Array*/, b/*String or Array*/){
-	//summary: simple comparison
+	// summary:
+	//		simple comparison
 	if(dojo.isArray(a) && dojo.isArray(b)){
 		for(var i = 0; i < a.length; i++){
 			if(a[i] != b[i]){ return false; }
diff --git a/util/buildscripts/cldr/ldml/core.zip b/util/buildscripts/cldr/ldml/core.zip
index 402537c..86d1f5f 100644
Binary files a/util/buildscripts/cldr/ldml/core.zip and b/util/buildscripts/cldr/ldml/core.zip differ
diff --git a/util/buildscripts/cldr/number.xsl b/util/buildscripts/cldr/number.xsl
index 85183c4..dd0ab01 100644
--- a/util/buildscripts/cldr/number.xsl
+++ b/util/buildscripts/cldr/number.xsl
@@ -181,7 +181,7 @@
       </xsl:choose>
 </xsl:template>
 
-<xsl:template name="ignore" match="defaultNumberingSystem | currencies"></xsl:template>
+<xsl:template name="ignore" match="defaultNumberingSystem | otherNumberingSystems | currencies"></xsl:template>
 
   <!-- too bad that can only use standard xsl:call-template(name can not be variable) 
          error occurs if use <saxson:call-templates($templateToCall)  /> -->
diff --git a/util/buildscripts/cldr/specialLocale.js b/util/buildscripts/cldr/specialLocale.js
index c918723..4827250 100644
--- a/util/buildscripts/cldr/specialLocale.js
+++ b/util/buildscripts/cldr/specialLocale.js
@@ -13,7 +13,8 @@
  *
  * Note: Here for simplification, we name zh-hk as source locale,and name zh-hant-hk as alias locale.
  */
-djConfig={baseUrl: "../../../dojo/"};
+
+djConfig={baseUrl: "../../../dojo/", paths: {"dojo/_base/xhr": "../util/buildscripts/cldr/xhr"}};
 
 load("../../../dojo/dojo.js");
 load("../jslib/logger.js");
@@ -180,7 +181,8 @@ for(var i= 0; i < srcLocaleList.length; i++){
 //fileUtil.saveUtf8File(logDir + '/specialLocale.log',logStr+'\n');
 
 function validateDir(/*String*/dirPath){
-	//summary:make sure the dir exists
+	// summary:
+	//		make sure the dir exists
 	var dir = new java.io.File(dirPath);
 	if(!dir.exists()){
 		dir.mkdir();
diff --git a/util/buildscripts/cldr/wrap.js b/util/buildscripts/cldr/wrap.js
index 91e8b98..cfd0606 100644
--- a/util/buildscripts/cldr/wrap.js
+++ b/util/buildscripts/cldr/wrap.js
@@ -2,7 +2,7 @@
  * Takes plain JSON structures and wraps them as to requireJS i18n bundles
  */
 
-djConfig={baseUrl: "../../../dojo/"};
+djConfig={baseUrl: "../../../dojo/", paths: {"dojo/_base/xhr": "../util/buildscripts/cldr/xhr"}};
 
 load("../../../dojo/dojo.js");
 load("../jslib/logger.js");
diff --git a/util/buildscripts/cldr/xhr.js b/util/buildscripts/cldr/xhr.js
new file mode 100644
index 0000000..16d6eaa
--- /dev/null
+++ b/util/buildscripts/cldr/xhr.js
@@ -0,0 +1,12 @@
+// Rhino-based replacement for dojo/_base/xhr (get only)
+define(function(){
+	return {
+	    get: function(args){
+		try {
+		    args.load(readFile(args.url, "utf-8"));
+		} catch (e) {
+		    args.error();
+		}
+	    }
+	}
+});
diff --git a/util/buildscripts/copyright.txt b/util/buildscripts/copyright.txt
index 28781c0..e04f6db 100644
--- a/util/buildscripts/copyright.txt
+++ b/util/buildscripts/copyright.txt
@@ -1,5 +1,5 @@
 /*
-	Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
+	Copyright (c) 2004-2013, The Dojo Foundation All Rights Reserved.
 	Available via Academic Free License >= 2.1 OR the modified BSD license.
 	see: http://dojotoolkit.org/license for details
 */
diff --git a/util/buildscripts/jslib/buildUtilXd.js b/util/buildscripts/jslib/buildUtilXd.js
index 2f1b2df..2245c0f 100644
--- a/util/buildscripts/jslib/buildUtilXd.js
+++ b/util/buildscripts/jslib/buildUtilXd.js
@@ -2,12 +2,15 @@
 var buildUtilXd = {};
 
 buildUtilXd.setXdDojoConfig = function(/*String*/fileContents, /*String*/url){
-	//summary: sets sets up xdomain loading for a particular URL.
-	//parameters:
-	//		fileContents: be a built dojo.js (can be uncompressed or compressed).
-	//		url: value should be the url to the directory that contains the dojo,
+	// summary:
+	//		sets sets up xdomain loading for a particular URL.
+	// fileContents:
+	//		be a built dojo.js (can be uncompressed or compressed).
+	// url:
+	//		value should be the url to the directory that contains the dojo,
 	//		dijit and dojox directories.
-	//			Example: "http://some.domain.com/dojo090" (no ending slash)
+	//		Example: "http://some.domain.com/dojo090" (no ending slash)
+
 	//This function will inject some contents after the dojo.registerModulePath() definition.
 	//The contents of fileName should have been a dojo.js that includes the contents
 	//of loader_xd.js (specify loader=xdomain in the build command).
@@ -46,7 +49,8 @@ buildUtilXd.xdgen = function(
 	/*RegExp*/optimizeIgnoreRegExp,
 	/*Object*/kwArgs
 ){
-	//summary: generates the .xd.js files for a build.
+	// summary:
+	//		generates the .xd.js files for a build.
 	var jsFileNames = fileUtil.getFilteredFileList(prefixPath, /\.js$/, true);
 	
 	//Construct a regexp to avoid xd generating loader_xd.js, since shrinksafe
diff --git a/util/buildscripts/jslib/fileUtil.js b/util/buildscripts/jslib/fileUtil.js
index 3ef7916..602643d 100644
--- a/util/buildscripts/jslib/fileUtil.js
+++ b/util/buildscripts/jslib/fileUtil.js
@@ -3,16 +3,18 @@
 var fileUtil = {};
 
 fileUtil.getLineSeparator = function(){
-	//summary: Gives the line separator for the platform.
-	//For web builds override this function.
+	// summary:
+	//		Gives the line separator for the platform.
+	//		For web builds override this function.
 	return java.lang.System.getProperty("line.separator"); //Java String
 }
 
 fileUtil.getFilteredFileList = function(/*String*/startDir, /*RegExp*/regExpFilters, /*boolean?*/makeUnixPaths, /*boolean?*/startDirIsJavaObject, /*boolean?*/dontRecurse){
-	//summary: Recurses startDir and finds matches to the files that match regExpFilters.include
-	//and do not match regExpFilters.exclude. Or just one regexp can be passed in for regExpFilters,
-	//and it will be treated as the "include" case.
-	//Ignores files/directories that start with a period (.).
+	// summary:
+	//		Recurses startDir and finds matches to the files that match regExpFilters.include
+	//		and do not match regExpFilters.exclude. Or just one regexp can be passed in for regExpFilters,
+	//		and it will be treated as the "include" case.
+	//		Ignores files/directories that start with a period (.).
 	var files = [];
 
 	var topDir = startDir;
@@ -60,8 +62,9 @@ fileUtil.getFilteredFileList = function(/*String*/startDir, /*RegExp*/regExpFilt
 
 
 fileUtil.copyDir = function(/*String*/srcDir, /*String*/destDir, /*RegExp*/regExpFilter, /*boolean?*/onlyCopyNew){
-	//summary: copies files from srcDir to destDir using the regExpFilter to determine if the
-	//file should be copied. Returns a list file name strings of the destinations that were copied.
+	// summary:
+	//		copies files from srcDir to destDir using the regExpFilter to determine if the
+	//		file should be copied. Returns a list file name strings of the destinations that were copied.
 	var fileNames = fileUtil.getFilteredFileList(srcDir, regExpFilter, true);
 	var copiedFiles = [];
 	
@@ -148,8 +151,9 @@ fileUtil.transformAsyncModule= function(filename, contents) {
 };
 
 fileUtil.copyFile = function(/*String*/srcFileName, /*String*/destFileName, /*boolean?*/onlyCopyNew){
-	//summary: copies srcFileName to destFileName. If onlyCopyNew is set, it only copies the file if
-	//srcFileName is newer than destFileName. Returns a boolean indicating if the copy occurred.
+	// summary:
+	//		copies srcFileName to destFileName. If onlyCopyNew is set, it only copies the file if
+	//		srcFileName is newer than destFileName. Returns a boolean indicating if the copy occurred.
 	var destFile = new java.io.File(destFileName);
 
 	//logger.trace("Src filename: " + srcFileName);
@@ -187,7 +191,8 @@ fileUtil.copyFile = function(/*String*/srcFileName, /*String*/destFileName, /*bo
 }
 
 fileUtil.readFile = function(/*String*/path, /*String?*/encoding){
-	//summary: reads a file and returns a string
+	// summary:
+	//		reads a file and returns a string
 	encoding = encoding || "utf-8";
 	var file = new java.io.File(path);
 	var lineSeparator = fileUtil.getLineSeparator();
@@ -220,12 +225,14 @@ fileUtil.readFile = function(/*String*/path, /*String?*/encoding){
 }
 
 fileUtil.saveUtf8File = function(/*String*/fileName, /*String*/fileContents){
-	//summary: saves a file using UTF-8 encoding.
+	// summary:
+	//		saves a file using UTF-8 encoding.
 	fileUtil.saveFile(fileName, fileContents, "utf-8");
 }
 
 fileUtil.saveFile = function(/*String*/fileName, /*String*/fileContents, /*String?*/encoding){
-	//summary: saves a file.
+	// summary:
+	//		saves a file.
 	var outFile = new java.io.File(fileName);
 	var outWriter;
 	
@@ -251,7 +258,8 @@ fileUtil.saveFile = function(/*String*/fileName, /*String*/fileContents, /*Strin
 }
 
 fileUtil.deleteFile = function(/*String*/fileName){
-	//summary: deletes a file or directory if it exists.
+	// summary:
+	//		deletes a file or directory if it exists.
 	var file = new java.io.File(fileName);
 	if(file.exists()){
 		if(file.isDirectory()){
diff --git a/util/buildscripts/jslib/i18nUtil.js b/util/buildscripts/jslib/i18nUtil.js
index a426c7b..83b99f5 100644
--- a/util/buildscripts/jslib/i18nUtil.js
+++ b/util/buildscripts/jslib/i18nUtil.js
@@ -1,7 +1,8 @@
 i18nUtil = {};
 
 i18nUtil.setup = function(/*Object*/kwArgs){
-	//summary: loads dojo so we can use it for i18n bundle flattening.
+	// summary:
+	//		loads dojo so we can use it for i18n bundle flattening.
 	
 	//Do the setup only if it has not already been done before.
 	if(typeof djConfig == "undefined" || !(typeof dojo != "undefined" && dojo["i18n"])){
@@ -25,7 +26,7 @@ i18nUtil.setup = function(/*Object*/kwArgs){
 }
 
 i18nUtil.flattenLayerFileBundles = function(/*String*/fileName, /*String*/fileContents, /*Object*/kwArgs){
-	//summary:
+	// summary:
 	//		This little utility is invoked by the build to flatten all of the JSON resource bundles used
 	//		by dojo.requireLocalization(), much like the main build itself, to optimize so that multiple
 	//		web hits will not be necessary to load these resources.  Normally, a request for a particular
@@ -35,13 +36,13 @@ i18nUtil.flattenLayerFileBundles = function(/*String*/fileName, /*String*/fileCo
 	//		memory, then flatten the object and spit it out using dojo.toJson.  The bootstrap
 	//		will be modified to download exactly one of these files, whichever is closest to the user's
 	//		locale.
-	//fileName:
+	// fileName:
 	//		The name of the file to process (like dojo.js). This function will use
 	//		it to determine the best resource name to give the flattened bundle.
-	//fileContents:
+	// fileContents:
 	//		The contents of the file to process (like dojo.js). This function will look in
 	//		the contents for dojo.requireLocation() calls.
-	//kwArgs:
+	// kwArgs:
 	//		The build's kwArgs.
 	
 	var destDirName = fileName.replace(/\/[^\/]+$/, "/") + "nls";
@@ -156,9 +157,10 @@ i18nUtil.flattenLayerFileBundles = function(/*String*/fileName, /*String*/fileCo
 i18nUtil.preloadInsertionRegExp = /\/\/INSERT dojo.i18n._preloadLocalizations HERE/;
 
 i18nUtil.flattenDirBundles = function(/*String*/prefixName, /*String*/prefixDir, /*Object*/kwArgs, /*RegExp*/nlsIgnoreRegExp){
-	//summary: Flattens the i18n bundles inside a directory so that only request
-	//is needed per bundle. Does not handle resource flattening for dojo.js or
-	//layered build files.
+	// summary:
+	//		Flattens the i18n bundles inside a directory so that only request
+	//		is needed per bundle. Does not handle resource flattening for dojo.js or
+	//		layered build files.
 
 	i18nUtil.setup(kwArgs);
 	var fileList = fileUtil.getFilteredFileList(prefixDir, /\.js$/, true);
@@ -182,9 +184,10 @@ i18nUtil.flattenDirBundles = function(/*String*/prefixName, /*String*/prefixDir,
 }
 
 i18nUtil.modifyRequireLocalization = function(/*String*/fileContents, /*Array*/prefixes){
-	//summary: Modifies any dojo.requireLocalization calls in the fileContents to have the
-	//list of supported locales as part of the call. This allows the i18n loading functions
-	//to only make request(s) for locales that actually exist on disk.
+	// summary:
+	//		Modifies any dojo.requireLocalization calls in the fileContents to have the
+	//		list of supported locales as part of the call. This allows the i18n loading functions
+	//		to only make request(s) for locales that actually exist on disk.
 	var dependencies = [];
 	
 	//Make sure we have a JS string, and not a Java string.
@@ -224,7 +227,8 @@ i18nUtil.modifyRequireLocalization = function(/*String*/fileContents, /*Array*/p
 }
 
 i18nUtil.makeFlatBundleContents = function(prefix, prefixPath, srcFileName){
-	//summary: Given a nls file name, flatten the bundles from parent locales into the nls bundle.
+	// summary:
+	//		Given a nls file name, flatten the bundles from parent locales into the nls bundle.
 	var bundleParts = i18nUtil.getBundlePartsFromFileName(prefix, prefixPath, srcFileName);
 	if(!bundleParts){
 		return null;
@@ -271,8 +275,9 @@ i18nUtil.getLocalesForBundle = function(moduleName, bundleName, prefixes){
 }
 
 i18nUtil.getRequireLocalizationArgsFromString = function(argString){
-	//summary: Given a string of the arguments to a dojo.requireLocalization
-	//call, separate the string into individual arguments.
+	// summary:
+	//		Given a string of the arguments to a dojo.requireLocalization
+	//		call, separate the string into individual arguments.
 	var argResult = {
 		moduleName: null,
 		bundleName: null,
diff --git a/util/buildscripts/profiles/amd.profile.js b/util/buildscripts/profiles/amd.profile.js
new file mode 100644
index 0000000..c8ff96b
--- /dev/null
+++ b/util/buildscripts/profiles/amd.profile.js
@@ -0,0 +1,141 @@
+var profile = (function(){
+	return {
+		// relative to this file
+		basePath:"../../..",
+
+		// relative to base path
+		releaseDir:"./dojo-amd",
+
+		packages:[{
+			name:"dojo",
+			location:"./dojo"
+		},{
+			name:"dijit",
+			location:"./dijit"
+		}],
+
+		selectorEngine:"lite",
+
+		defaultConfig:{
+			hasCache:{
+				// these are the values given above, not-built client code may test for these so they need to be available
+				'dojo-built':1,
+				'dojo-loader':1,
+				'dom':1,
+				'host-browser':1,
+
+				// default
+				"config-selectorEngine":"lite"
+			},
+			async:1
+		},
+
+		dojoBootText:"require.boot && require.apply(null, require.boot);",
+
+		// since this build it intended to be utilized with properly-expressed AMD modules;
+		// don't insert absolute module ids into the modules
+		insertAbsMids:0,
+
+		// these are all the has feature that affect the loader and/or the bootstrap
+		// the settings below are optimized for the smallest AMD loader that is configurable
+		// and include dom-ready support
+		staticHasFeatures:{
+			// dojo/dojo
+			'config-dojo-loader-catches':0,
+
+			// dojo/dojo
+			'config-tlmSiblingOfDojo':0,
+
+			// dojo/dojo
+			'dojo-amd-factory-scan':0,
+
+			// dojo/dojo
+			'dojo-combo-api':0,
+
+			// dojo/_base/config, dojo/dojo
+			'dojo-config-api':1,
+
+			// dojo/main
+			'dojo-config-require':0,
+
+			// dojo/_base/kernel
+			'dojo-debug-messages':0,
+
+			// dojo/dojo
+			'dojo-dom-ready-api':1,
+
+			// dojo/main
+			'dojo-firebug':0,
+
+			// dojo/_base/kernel
+			'dojo-guarantee-console':1,
+
+			// dojo/has
+			'dojo-has-api':1,
+
+			// dojo/dojo
+			'dojo-inject-api':1,
+
+			// dojo/_base/config, dojo/_base/kernel, dojo/_base/loader, dojo/ready
+			'dojo-loader':1,
+
+			// dojo/dojo
+			'dojo-log-api':0,
+
+			// dojo/_base/kernel
+			'dojo-modulePaths':0,
+
+			// dojo/_base/kernel
+			'dojo-moduleUrl':0,
+
+			// dojo/dojo
+			'dojo-publish-privates':0,
+
+			// dojo/dojo
+			'dojo-requirejs-api':0,
+
+			// dojo/dojo
+			'dojo-sniff':0,
+
+			// dojo/dojo, dojo/i18n, dojo/ready
+			'dojo-sync-loader':0,
+
+			// dojo/dojo
+			'dojo-test-sniff':0,
+
+			// dojo/dojo
+			'dojo-timeout-api':0,
+
+			// dojo/dojo
+			'dojo-trace-api':0,
+
+			// dojo/dojo
+			'dojo-undef-api':0,
+
+			// dojo/i18n
+			'dojo-v1x-i18n-Api':0,
+
+			// dojo/_base/xhr
+			'dojo-xhr-factory':0,
+
+			// dojo/_base/loader, dojo/dojo, dojo/on
+			'dom':1,
+
+			// dojo/dojo
+			'host-browser':1,
+
+			// dojo/_base/array, dojo/_base/connect, dojo/_base/kernel, dojo/_base/lang
+			'extend-dojo':1
+		},
+
+		layers:{
+			"dojo/dojo":{
+				include:[],
+				customBase:1
+			},
+			"dojo/main":{
+				include:["dojo/selector/lite"]
+			}
+		}
+	};
+})();
diff --git a/util/buildscripts/profiles/demos-all.profile.js b/util/buildscripts/profiles/demos-all.profile.js
index 4ab48f5..113ff36 100644
--- a/util/buildscripts/profiles/demos-all.profile.js
+++ b/util/buildscripts/profiles/demos-all.profile.js
@@ -26,7 +26,6 @@ dependencies = {
 				"dijit.dijit-all"
 			]
 		},
-
 		// Here are the various demos with promotion:
 		{
 			name: "../demos/editor/layer.js",
@@ -303,6 +302,69 @@ dependencies = {
 			dependencies:[
 				"demos.themePreviewer.src"
 			]
+		},
+		{
+			name: "../demos/tracTreemap/src.js",
+			dependencies:[
+				"demos.tracTreemap.src"
+			]
+		},
+		{
+			name: "../demos/calendar/src.js",
+			dependencies: [
+				"demos.calendar.src"
+			]
+		},
+		{
+			name: "../demos/todoApp/src.js",
+			dependencies: [
+				"dojox/mobile/_base",
+				"dojox/mobile/_compat",
+				"dojox/mobile/TabBar",
+				"dojox/mobile/RoundRect",
+				"dojox/mobile/TabBarButton",
+				"dojox/mobile/TextBox",
+				"dojox/mobile/TextArea",
+				"dojox/mobile/CheckBox",
+				"dojox/mobile/ExpandingTextArea",
+				"dojox/mobile/Button",
+				"dojox/mobile/RoundRect",
+				"dojox/mobile/Heading",
+				"dojox/mobile/ListItem",
+				"dojox/mobile/RoundRectList",
+				"dojox/mobile/RoundRectCategory",
+				"dojox/mobile/Switch",
+				"dojox/mobile/SimpleDialog",
+				"dojox/mobile/DatePicker",
+				"dojox/mobile/Opener",
+				"dojox/mobile/SpinWheelDatePicker",
+				"dojo/date/stamp",
+				"dojox/app/main",
+				"dojox/app/View",
+				"dojox/app/ViewBase",
+				"dojox/app/controllers/Load",
+				"dojox/app/controllers/History",
+				"dojox/app/controllers/Transition",
+				"dojox/app/controllers/LayoutBase",
+				"dojox/app/controllers/Layout",
+				"dojox/app/widgets/Container",
+				"dojox/css3/transit",
+				"dojox/css3/transition",
+				"dojox/json/ref",
+				"dojo/store/Memory",
+				"dojo/data/ItemFileWriteStore",
+				"dojo/store/DataStore",
+				"dojox/app/utils/mvcModel",
+				"dojox/mvc/EditStoreRefListController",
+				"dojox/mvc/Repeat",
+				"dojox/mvc/Group",
+				"dojox/mvc/WidgetList",
+				"dojox/mvc/Output",
+				"dojox/mvc/at",
+				"dojox/app/main",
+				"demos/todoApp/utils/utils",
+				"demos.todoApp.src"
+			]
 		}
 	],
 
diff --git a/util/buildscripts/profiles/nano.profile.js b/util/buildscripts/profiles/nano.profile.js
new file mode 100644
index 0000000..f434544
--- /dev/null
+++ b/util/buildscripts/profiles/nano.profile.js
@@ -0,0 +1,51 @@
+var profile = (function(){
+    return {
+        layerOptimize: "closure",
+        releaseDir: "../../../release",
+
+        packages: [{
+            name: "dojo",
+            location: "../../../dojo"
+        }],
+
+        defaultConfig: {
+            async: 1
+        },
+
+        dojoBootText: "require.boot && require.apply(null, require.boot);",
+
+        staticHasFeatures: {
+            'dom': 1,
+            'host-browser': 1,
+            'dojo-inject-api': 1,
+            'dojo-loader-eval-hint-url': 1,
+            'dojo-built': 1,
+            'host-node': 0,
+            'host-rhino': 0,
+            'dojo-trace-api': 0,
+            'dojo-sync-loader': 0,
+            'dojo-config-api': 1,
+            'dojo-cdn': 0,
+            'dojo-sniff': 0,
+            'dojo-requirejs-api': 0,
+            'dojo-test-sniff': 0,
+            'dojo-combo-api': 0,
+            'dojo-undef-api': 0,
+            'config-tlmSiblingOfDojo': 0,
+            'config-dojo-loader-catches': 0,
+            'config-stripStrict': 0,
+            'dojo-timeout-api': 0,
+            'dojo-dom-ready-api': 0,
+            'dojo-log-api': 0,
+            'dojo-amd-factory-scan': 0,
+            'dojo-publish-privates': 0
+        },
+
+        layers: {
+            "dojo/dojo": {
+                include: [],
+                customBase: 1
+            }
+        }
+    };
+})();
diff --git a/util/buildscripts/profiles/node.profile.js b/util/buildscripts/profiles/node.profile.js
new file mode 100644
index 0000000..3a89a8e
--- /dev/null
+++ b/util/buildscripts/profiles/node.profile.js
@@ -0,0 +1,128 @@
+//
+// This is an example profile that may be used as a starting point for a build targeted at node.js
+//
+// Note: generally, there will be very little performance improvement in the node.js environment since
+// that environment does not have the latency and bandwidth issues present in the browser environment.
+//
+var profile = (function(){
+	return {
+		// relative to this file
+		basePath:"../../..",
+
+		// relative to base path
+		releaseDir:"./dojo-node",
+
+		packages:[{
+			name:"dojo",
+			location:"./dojo"
+		}],
+
+
+		defaultConfig:{
+			hasCache:{
+				'dojo-built':1,
+				'dojo-loader':1
+				// recall the dojo/_base/configNode will config the node environment
+			},
+			async:1
+		},
+
+		// since this build it intended to be utilized with properly-expressed AMD modules;
+		// don't insert absolute module ids into the modules
+		insertAbsMids:0,
+
+		// these are all the has feature that affect the loader and/or the bootstrap
+		// the settings below are optimized for the smallest AMD loader that is configurable
+		staticHasFeatures:{
+			// dojo/dojo
+			'config-dojo-loader-catches':0,
+
+			// dojo/dojo
+			'config-tlmSiblingOfDojo':0,
+
+			// dojo/dojo
+			'dojo-amd-factory-scan':1,
+
+			// dojo/dojo
+			'dojo-combo-api':0,
+
+			// dojo/_base/config, dojo/dojo
+			'dojo-config-api':1,
+
+			// dojo/main
+			'dojo-config-require':0,
+
+			// dojo/_base/kernel
+			'dojo-debug-messages':0,
+
+			// dojo/dojo
+			'dojo-dom-ready-api':0,
+
+			// dojo/main
+			'dojo-firebug':0,
+
+			// dojo/_base/kernel
+			'dojo-guarantee-console':0,
+
+			// dojo/has
+			'dojo-has-api':1,
+
+			// dojo/dojo
+			'dojo-inject-api':1,
+
+			// dojo/_base/config, dojo/_base/kernel, dojo/_base/loader, dojo/ready
+			'dojo-loader':1,
+
+			// dojo/dojo
+			'dojo-log-api':0,
+
+			// dojo/_base/kernel
+			'dojo-modulePaths':0,
+
+			// dojo/_base/kernel
+			'dojo-moduleUrl':0,
+
+			// dojo/dojo
+			'dojo-publish-privates':0,
+
+			// dojo/dojo
+			'dojo-requirejs-api':0,
+
+			// dojo/dojo
+			'dojo-sniff':0,
+
+			// dojo/dojo, dojo/i18n, dojo/ready
+			'dojo-sync-loader':0,
+
+			// dojo/dojo
+			'dojo-test-sniff':0,
+
+			// dojo/dojo
+			'dojo-timeout-api':0,
+
+			// dojo/dojo
+			'dojo-trace-api':0,
+
+			// dojo/dojo
+			'dojo-undef-api':0,
+
+			// dojo/i18n
+			'dojo-v1x-i18n-Api':0,
+
+			// dojo/_base/xhr
+			'dojo-xhr-factory':0,
+
+			// dojo/_base/loader, dojo/dojo, dojo/on
+			'dom':0,
+
+			// dojo/dojo
+			'host-node':1,
+
+			// dojo/dojo
+			'host-browser':0,
+
+			// dojo/_base/array, dojo/_base/connect, dojo/_base/kernel, dojo/_base/lang
+			'extend-dojo':1
+		}
+	};
+})();
diff --git a/util/buildscripts/profiles/webkitMobile.profile.js b/util/buildscripts/profiles/webkitMobile.profile.js
new file mode 100755
index 0000000..227733a
--- /dev/null
+++ b/util/buildscripts/profiles/webkitMobile.profile.js
@@ -0,0 +1,185 @@
+// Profile for mobile builds on WebKit.
+//
+// Use when:
+//		- target to webkit platforms (iOS and Android)
+//		- document is in standards mode (i.e., with <!DOCTYPE html>)
+// Usage:
+//		./build.sh releaseDir=... action=release optimize=closure profile=webkitMobile
+
+var profile = {
+	// relative to this file
+	basePath: "../../..",
+
+	// relative to base path
+	releaseDir: "../webkitMobile",
+
+	stripConsole: "normal",
+
+	// Use closure to optimize, to remove code branches for has("ie") etc.
+	optimize: "closure",
+	layerOptimize: "closure",
+
+	packages: [
+		{
+			name: "dojo",
+			location: "./dojo"
+		},
+		{
+			name: "dijit",
+			location: "./dijit"
+		},
+		{
+			name: "dojox",
+			location: "./dojox"
+		}
+	],
+
+	// this is a "new-version" profile since is sets the variable "profile" rather than "dependencies"; therefore
+	// the layers property is a map from AMD module id to layer properties...
+	layers: {
+		"dojo/dojo": {
+			// the module dojo/dojo is the default loader (you can make multiple bootstraps with the new builder)
+			include: [
+				// the include vector gives the modules to include in this layer
+				// note: unless the dojo/dojo layer has the property "customBase" set to truthy, then module
+				// dojo/main will be automatically added...and conversely
+				"dijit/_WidgetBase",
+				"dijit/_Container",
+				"dijit/_Contained",
+				"dijit/registry"
+			],
+			customBase: true
+		},
+		"dojo/main": {
+			include: ["dojo/selector/lite"]
+		},
+		"dojox/mobile": {
+			include: [
+				"dojox/mobile"
+			],
+			exclude: [
+				// exclude gives a dependency forrest to exclude; i tend to put is second since the algorithm is...
+				//
+				// The modules to include in a particular layer are computed as follows:
+				//
+				// 1. The layer module itself.
+				//
+				// 2. Plus the dependency graph implied by the AMD dependencies of the layer module. This is given
+				//	by the dependency vector found in the define application associated with the target module,
+				//	the modules found in the dependency vectors of those modules, and so on until all modules in
+				//	the graph have been found (remember, though not desirable, there may be cycles, so the graph
+				//	is not necessarily a tree).
+				//
+				// 3. Plus all modules given in the include array, along with all of those modules' dependency graphs.
+				//
+				// 4. Less all modules given in the exclude array, along with all of those modules' dependency graphs.
+
+				"dojo/dojo"
+			]
+		},
+		"dojox/mobile/app": {
+			include: [
+				"dojox/mobile/app"
+			],
+			exclude: [
+				"dojo/dojo",
+				"dojox/mobile"
+			]
+
+
+		}
+	},
+
+	staticHasFeatures: {
+		// Default settings for a browser, from dojo.js; apparently these get modified in special cases
+		// like when running under node, or against RequireJS, but nothing we need to worry about.
+		"host-browser": true,
+		"host-node": false,
+		"host-rhino": false,
+		"dom": true,
+		"dojo-amd-factory-scan": true,
+		"dojo-loader": true,
+		"dojo-has-api": true,
+		"dojo-inject-api": true,
+		"dojo-timeout-api": true,
+		"dojo-trace-api": true,
+		"dojo-log-api": true,
+		"dojo-dom-ready-api": true,
+		"dojo-publish-privates": true,
+		"dojo-config-api": true,
+		"dojo-sniff": true,
+		"dojo-sync-loader": true,
+		"dojo-test-sniff": true,
+		"config-tlmSiblingOfDojo": true,
+
+		// Other configuration switches that are hardcoded in the source.
+		// Setting some of these to false may reduce code size, but unclear what they all mean.
+		"config-publishRequireResult": true,
+		"dojo-config-addOnLoad": 1,		// hardcoded to 1 in the source
+		"dojo-config-require": true,
+		"dojo-debug-messages": true,
+		"dojo-gettext-api": true,			// apparently unused
+		"dojo-guarantee-console": true,
+		"dojo-loader-eval-hint-url": true,
+		"dojo-modulePaths": true,
+		"dojo-moduleUrl": true,
+		"dojo-v1x-i18n-Api": true,
+		"dojo-xhr-factory": true,	// if require.getXhr() exists (true for dojo's AMD loader, false for requireJS?)
+		"extend-dojo": true,		// add functions to global dojo object
+
+		// Browser flags
+		"webkit": true,	// this is actually a number like 525 but I don't think anyone is using it
+		"air": false,
+		"ff": undefined,
+		"mozilla": undefined,
+		"ie": undefined,
+
+		// Configuration settings
+		"config-selectorEngine": "lite",
+		"dijit-legacy-requires": false,		// don't load unrequested modules for back-compat
+		"dom-quirks": false,				// we assume/require that the app is in strict mode
+		"quirks": false,					// we assume/require that the app is in strict mode
+
+		// Flags for old IE browser bugs / non-standard behavior
+		"array-extensible": true,		// false for old IE
+		"bug-for-in-skips-shadowed": 0,	// false for old IE
+		"dom-attributes-explicit": true,	// everyone except IE6, 7
+		"dom-attributes-specified-flag": true,	//everyone except IE6-8
+		"dom-addeventlistener": true,		// everyone except IE
+		"native-xhr": true,			// has XMLHTTPRequest
+		"ie-event-behavior": undefined,
+		"dojo-force-activex-xhr": false,	// true is for IE path
+
+		// Flags for features
+		"dom-matches-selector": true,
+		"dom-qsa": true,
+		"dom-qsa2.1": true,
+		"dom-qsa3": true,
+		"json-parse": true,
+		"json-stringify": true,
+
+		// Behavior that varies by browser, but is constant across webkit mobile browsers
+		"events-keypress-typed": true,		// whether printable characters generate keypress event?
+		"events-mouseenter": false,		// this is set by mouse.html but never used
+		"touch": true,
+		"highcontrast": false,			// safari always displays background images, even when device in high-contrast mode
+		"textarea-needs-help-shrinking": true,
+		"css-user-select": "'WebkitUserSelect'"
+
+		// Values which can be different across mobile devices, so intentionally not specified in this list.
+		// "event-orientationchange": true,
+		// "safari": true,
+		// "android": true
+		// "wii": true
+	},
+
+	selectorEngine: "lite",
+
+	defaultConfig: {
+		hasCache: {
+			// default
+			"config-selectorEngine": "lite"
+		},
+		async: true
+	}
+};
diff --git a/util/buildscripts/tests/webkitHasTest.html b/util/buildscripts/tests/webkitHasTest.html
new file mode 100644
index 0000000..b5f87ef
--- /dev/null
+++ b/util/buildscripts/tests/webkitHasTest.html
@@ -0,0 +1,182 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<script src="../../../dojo/dojo.js" data-dojo-config="async:true, isDebug:true, selectorEngine: 'lite'"></script>
+	<script>
+		// These are the values I expect to be the same across all [mobile] webkit browsers
+		var expected = {
+			// Default settings for a browser, from dojo.js; apparently these get modified in special cases
+			// like when running under node, or against RequireJS, but nothing we need to worry about.
+			"host-browser":1,
+			"host-node": false,
+			"host-rhino": false,
+			"dom":1,
+			"dojo-amd-factory-scan":1,
+			"dojo-loader":1,
+			"dojo-has-api":1,
+			"dojo-inject-api":1,
+			"dojo-timeout-api":1,
+			"dojo-trace-api":1,
+			"dojo-log-api":1,
+			"dojo-dom-ready-api":1,
+			"dojo-publish-privates":1,
+			"dojo-config-api":1,
+			"dojo-sniff":1,
+			"dojo-sync-loader":1,
+			"dojo-test-sniff":1,
+			"config-tlmSiblingOfDojo":1,
+
+			// Other configuration switches that are hardcoded in the source.
+			// Setting some of these to false may reduce code size, but unclear what they all mean.
+			"config-publishRequireResult": 1,
+			"dojo-config-addOnLoad": 1,		// hardcoded to 1 in the source
+			"dojo-config-require": 1,
+			"dojo-debug-messages": true,
+			"dojo-gettext-api": 1,			// apparently unused
+			"dojo-guarantee-console": 1,
+			"dojo-loader-eval-hint-url": 1,
+			"dojo-modulePaths": 1,
+			"dojo-moduleUrl": 1,
+			"dojo-v1x-i18n-Api": 1,
+			"dojo-xhr-factory": 1,	// if require.getXhr() exists (true for dojo's AMD loader, false for requireJS?)
+			"extend-dojo": 1,		// add functions to global dojo object
+
+			// Browser flags
+			//"webkit": true,	// this is actually a number like 525 but I don't think anyone is using it
+			"air": false,
+			"ff": undefined,
+			"mozilla": undefined,
+			"ie": undefined,
+
+			// Configuration settings
+			"config-selectorEngine": "lite",
+			"dijit-legacy-requires": false,		// don't load unrequested modules for back-compat
+			"dom-quirks": false,				// we assume/require that the app is in strict mode
+			"quirks": false,					// we assume/require that the app is in strict mode
+
+			// Flags for old IE browser bugs / non-standard behavior
+			"array-extensible": true,		// false for old IE
+			"bug-for-in-skips-shadowed": 0,	// false for old IE
+			"dom-attributes-explicit": true,	// everyone except IE6, 7
+			"dom-attributes-specified-flag": true,	//everyone except IE6-8
+			"dom-addeventlistener": true,		// everyone except IE
+			"native-xhr": true,			// has XMLHTTPRequest
+			"ie-event-behavior": undefined,
+			"dojo-force-activex-xhr": false,	// true is for IE path
+
+			// Flags for features
+			"dom-matches-selector": true,
+			"dom-qsa": true,
+			"dom-qsa2.1": true,
+			"dom-qsa3": true,
+			"json-parse": true,
+			"json-stringify": true,
+
+			// Behavior that varies by browser, but is constant across webkit mobile browsers
+			"events-keypress-typed": true,		// whether printable characters generate keypress event?
+			"events-mouseenter": false,		// this is set by mouse.html but never used
+			"touch": true
+
+			// Values which can be different across mobile devices, so intentionally not specified in this list.
+			// "event-orientationchange": true,
+			// "safari": true,
+			// "android": true
+			// "wii": true
+		};
+		require([
+			// Modules I need for this script to run
+			"dojo/has",
+			"dojo/dom",
+			"dojo/json",
+			"dojo/domReady!",
+
+			// These modules loaded because they have a has.add() call.
+			// Generated from:
+			//		$ cd <root>
+			//		$ find . -name '*.js' -print |xargs fgrep -l 'has.add'
+			"dojo/_base/browser",
+			"dojo/_base/config",
+			"dojo/_base/connect",
+			"dojo/_base/kernel",
+			"dojo/_base/lang",
+			"dojo/_base/loader",
+			"dojo/_base/sniff",
+			"dojo/_base/window",
+			"dojo/_base/xhr",
+			"dojo/dom-class",
+			"dojo/i18n",
+			"dojo/main",
+			"dojo/mouse",
+			"dojo/on",
+			"dojo/query",
+			"dojo/ready",
+			"dojo/selector/_loader",
+			"dojo/selector/lite",
+			"dojox/form/uploader/Base",
+			"dojox/mobile/Audio",
+			"dojox/mobile/sniff"
+		], function(has, dom, json){
+
+			// Code to write output to textarea
+			var res = dom.byId("res");
+			res.value = "";		// in case value was saved from this page from before
+			function log(){
+				for(var i=0; i<arguments.length; i++){
+					res.value += arguments[i];
+				}
+				res.value += "\n";
+			}
+
+			log("userAgent: ", navigator.userAgent);
+			log("appVersion: ", navigator.appVersion);
+
+			/*
+			// Rearrange the has() hash to alphabetical order, and dump it to console.
+			// We could alternately get the list of has() flags from the builder:
+			//		$ cd util/buildscripts
+			//		$ ./build.sh action=release optimize=closure --profile webkitMobile --hasReport 1
+			
+			var keys = [], newHash = {};
+			for(var key in has.cache){
+				keys.push(key);
+			}
+			keys.sort();
+			for(var i=0; i<keys.length; i++){
+				newHash[keys[i]] = has(keys[i]);
+			}
+
+			// Dump the hash
+			log("has() values:")
+			log(json.stringify(newHash, null, "	"));
+			log("Total: " + keys.length);
+			*/
+
+			log("\nDifferences from expected values for webkit:");
+			var cnt = 0;
+			for(key in expected){
+				if(has(key) !== expected[key]){
+					log(key + ": expected = " + json.stringify(expected[key]) + ", actual: " +
+							json.stringify(has(key)));
+					cnt++;
+				}
+			}
+			if(cnt == 0){
+				log("None!");
+			}
+		});
+	</script>
+	<style>
+		textarea {
+			width: 95%;
+			height: 500px;
+		}
+	</style>
+</head>
+<body>
+	<p>
+		This file is for testing if the given browser matches the webkitMobile build profile.
+		Results:
+	</p>
+	<textarea id="res"></textarea>
+</body>
+</html>
\ No newline at end of file
diff --git a/util/buildscripts/webbuild/makeWebBuildModuleList.js b/util/buildscripts/webbuild/makeWebBuildModuleList.js
index 00399eb..abbeabd 100644
--- a/util/buildscripts/webbuild/makeWebBuildModuleList.js
+++ b/util/buildscripts/webbuild/makeWebBuildModuleList.js
@@ -4,7 +4,8 @@
 
 
 function buildTreeData(/*Object*/obj, /*String*/nodeName){
-	//summary: makes a TreeV3-friendly data structure.
+	// summary:
+	//		makes a TreeV3-friendly data structure.
 	
 	var result = null;
 	var childNames = [];
diff --git a/util/buildscripts/webbuild/server/js/build.js b/util/buildscripts/webbuild/server/js/build.js
index 9e20d8b..41d848f 100644
--- a/util/buildscripts/webbuild/server/js/build.js
+++ b/util/buildscripts/webbuild/server/js/build.js
@@ -1,5 +1,6 @@
 function load(/*String*/fileName){
-	//summary: opens the file at fileName and evals the contents as JavaScript.
+	// summary:
+	//		opens the file at fileName and evals the contents as JavaScript.
 	
 	//Read the file
 	var fileContents = readFile(fileName);
@@ -15,7 +16,8 @@ function load(/*String*/fileName){
 }
 
 function readFile(/*String*/path, /*String?*/encoding){
-	//summary: reads a file and returns a string
+	// summary:
+	//		reads a file and returns a string
 	encoding = encoding || "utf-8";
 	var file = new java.io.File(path);
 	var lineSeparator = "\n";
@@ -37,7 +39,8 @@ function readFile(/*String*/path, /*String?*/encoding){
 //TODO: inlining this function since the new shrinksafe.jar is used, and older
 //versions of Dojo's buildscripts are not compatible.
 function optimizeJs(/*String fileName*/fileName, /*String*/fileContents, /*String*/copyright, /*String*/optimizeType, /*String*/stripConsole){
-	//summary: either strips comments from string or compresses it.
+	// summary:
+	//		either strips comments from string or compresses it.
 	copyright = copyright || "";
 
 	//Use rhino to help do minifying/compressing.
diff --git a/util/checkstyle/checkstyleReport.html b/util/checkstyle/checkstyleReport.html
index 57ba0cc..56afea9 100644
--- a/util/checkstyle/checkstyleReport.html
+++ b/util/checkstyle/checkstyleReport.html
@@ -34,7 +34,7 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
@@ -454,7 +454,7 @@
 					region="top"
 					style="height:50%;"
 					>
-					<script type="dojo/connect" event="_onFetchBegin" args="size, req">
+					<script type="dojo/connect" data-dojo-event="_onFetchBegin" data-dojo-args="size, req">
 						dojo.byId("totalErrors").innerHTML = size;
 					</script>
 					<thead>
diff --git a/util/checkstyle/runCheckstyle.js b/util/checkstyle/runCheckstyle.js
index 4427fcd..44006e6 100644
--- a/util/checkstyle/runCheckstyle.js
+++ b/util/checkstyle/runCheckstyle.js
@@ -3,7 +3,6 @@ var buildTimerStart = (new Date()).getTime();
 
 load("../buildscripts/jslib/logger.js");
 load("../buildscripts/jslib/fileUtil.js");
-load("../buildscripts/jslib/buildUtil.js");
 load("checkstyleUtil.js");
 
 //*****************************************************************************
@@ -27,7 +26,7 @@ if(arguments[0] == "help"){
 } else{
 	
 	//Convert arguments to keyword arguments.
-	var kwArgs = buildUtil.makeBuildOptions(arguments);
+	var kwArgs = convertArrayToObject(arguments);
 
 	checkstyle();
 
@@ -37,6 +36,23 @@ if(arguments[0] == "help"){
 }
 //*****************************************************************************
 
+// Take from old buildUtil.js in 1.6
+function convertArrayToObject(/*Array*/ary){
+	// summary:
+	//		converts an array that has String members of "name=value"
+	//		into an object, where the properties on the object are the names in the array
+	//		member name/value pairs.
+	var result = {};
+	for(var i = 0; i < ary.length; i++){
+		var separatorIndex = ary[i].indexOf("=");
+		if(separatorIndex == -1){
+			throw "Malformed name/value pair: [" + ary[i] + "]. Format should be name=value";
+		}
+		result[ary[i].substring(0, separatorIndex)] = ary[i].substring(separatorIndex + 1, ary[i].length);
+	}
+	return result; //Object
+}
+
 //********* Start checkstyle *********
 function checkstyle(){
 	
diff --git a/util/closureCompiler/README b/util/closureCompiler/README
index ece7175..14fc8fe 100644
--- a/util/closureCompiler/README
+++ b/util/closureCompiler/README
@@ -146,13 +146,13 @@ the parse tree data structures were extracted and modified
 significantly for use by Google's JavaScript compiler.
 
 Local Modifications: The packages have been renamespaced. All code not
-relavant to parsing has been removed. A JSDoc parser and static typing
+relevant to parsing has been removed. A JsDoc parser and static typing
 system have been added.
 
 
 -----
 Code in:
-lib/libtrunk_rhino_parser_jarjared.jar
+lib/rhino
 
 Rhino
 URL: http://www.mozilla.org/rhino
@@ -161,9 +161,8 @@ License:  Netscape Public License and MPL / GPL dual license
 
 Description: Mozilla Rhino is an implementation of JavaScript for the JVM.
 
-Local Modifications: None. We've used JarJar to renamespace the code
-post-compilation. See:
-http://code.google.com/p/jarjar/
+Local Modifications: Minor changes to parsing JSDoc that usually get pushed
+up-stream to Rhino trunk.
 
 
 -----
@@ -172,7 +171,7 @@ lib/args4j.jar
 
 Args4j
 URL: https://args4j.dev.java.net/
-Version: 2.0.12
+Version: 2.0.16
 License: MIT
 
 Description:
@@ -188,7 +187,7 @@ lib/guava.jar
 
 Guava Libraries
 URL: http://code.google.com/p/guava-libraries/
-Version:  r08
+Version:  14.0
 License: Apache License 2.0
 
 Description: Google's core Java libraries.
@@ -210,13 +209,28 @@ Description: Annotations for software defect detection.
 Local Modifications: None.
 
 
+-----
+Code in:
+lib/jarjar.jar
+
+Jar Jar Links
+URL: http://jarjar.googlecode.com/
+Version: 1.1
+License: Apache License 2.0
+
+Description:
+A utility for repackaging Java libraries.
+
+Local Modifications: None.
+
+
 ----
 Code in:
 lib/junit.jar
 
 JUnit
 URL:  http://sourceforge.net/projects/junit/
-Version:  4.8.2
+Version:  4.10
 License:  Common Public License 1.0
 
 Description: A framework for writing and running automated tests in Java.
@@ -230,7 +244,7 @@ lib/protobuf-java.jar
 
 Protocol Buffers
 URL: http://code.google.com/p/protobuf/
-Version: 2.3.0
+Version: 2.4.1
 License: New BSD License
 
 Description: Supporting libraries for protocol buffers,
@@ -267,9 +281,9 @@ Local Modifications: None
 
 ---
 Code in:
-tools/maven-ant-tasks-2.1.1.jar
+tools/maven-ant-tasks-2.1.3.jar
 URL: http://maven.apache.org
-Version 2.1.1
+Version 2.1.3
 License: Apache License 2.0
 Description:
   Maven Ant tasks are used to manage dependencies and to install/deploy to
diff --git a/util/closureCompiler/compiler.jar b/util/closureCompiler/compiler.jar
index 2f6837d..e233867 100644
Binary files a/util/closureCompiler/compiler.jar and b/util/closureCompiler/compiler.jar differ
diff --git a/util/docscripts/LICENSE b/util/docscripts/LICENSE
index aa6b39f..b1ddd34 100644
--- a/util/docscripts/LICENSE
+++ b/util/docscripts/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2011, The Dojo Foundation
+Copyright (c) 2005-2013, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/util/docscripts/lib/parser/DojoFunction.php b/util/docscripts/lib/parser/DojoFunction.php
deleted file mode 100644
index e69de29..0000000
diff --git a/util/docscripts/modules/dojox.module.properties b/util/docscripts/modules/dojox.module.properties
index 46bf808..e97e6a8 100755
--- a/util/docscripts/modules/dojox.module.properties
+++ b/util/docscripts/modules/dojox.module.properties
@@ -1 +1 @@
-location = ../../dojox/
\ No newline at end of file
+location = ../../dojox/
diff --git a/util/docscripts/preview.php b/util/docscripts/preview.php
index 2e73fac..ec9b9fa 100644
--- a/util/docscripts/preview.php
+++ b/util/docscripts/preview.php
@@ -73,7 +73,7 @@ $showall = isset($_REQUEST['showall']);
 				}
 			</style>
 			
-			<script type="text/javascript" src="../../dojo/dojo.js" djConfig="parseOnLoad:true"></script>
+			<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="parseOnLoad:true"></script>
 			<script type="text/javascript">
 				dojo.require("dojo.data.ItemFileReadStore");
 				dojo.require("dojo.hash");
diff --git a/util/doh/LICENSE b/util/doh/LICENSE
index aa6b39f..b1ddd34 100644
--- a/util/doh/LICENSE
+++ b/util/doh/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2011, The Dojo Foundation
+Copyright (c) 2005-2013, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/util/doh/Robot.html b/util/doh/Robot.html
index 677abe0..e9076f1 100644
--- a/util/doh/Robot.html
+++ b/util/doh/Robot.html
@@ -20,15 +20,18 @@
 		var domain=unescape(/[\\?&]domain=([^&#]*)/.exec(window.location.href)[1]);
 		document.domain=domain;
 	}
-	// find doh
+
+	// Setup global "doh" and "robot" variables to point to doh and doh/robot modules that have already
+	// been loaded in parent frame (ie, the main document)
 	var doc = window.frameElement.ownerDocument;
 	var w = doc.parentWindow || doc.defaultView || top;
-	doh = w.doh;
+	doh  = w.require("doh/_browserRunner");
+	robot = w.require("doh/robot");
 
 	function init(){
 		var applet = document.getElementsByTagName('applet')[0];
 
-		doh.robot._killApplet = function(){
+		robot._killApplet = function(){
 			document.body.removeChild(applet);
 			applet = null;
 		};
@@ -47,30 +50,40 @@
 
 	function _onfocus(robotField){
 		_robotField = robotField;
-		doh.robot._initWheel();
+		robot._initWheel();
 	}
 
 	function _onblur(e){
 		setTimeout(function(){
-			document.body.removeChild(_robotField);
+			if(_robotField && _robotField.parentNode == document.body){
+				document.body.removeChild(_robotField);
+			}
 		},0);
 	}
 
+	var receivedMouseDown = false;
 	function _onmousedown(e){
+		if(receivedMouseDown){
+			return;
+		}
+		receivedMouseDown=true;
 		e = e||window.event;
 		if(e.screenX == 0||e.clientX == 0){ return; }
 		var docScreenX = e.screenX-e.clientX;
 		var docScreenY = e.screenY-e.clientY;
-		doh.robot._setDocumentBounds(docScreenX, docScreenY);
+		robot._setDocumentBounds(docScreenX, docScreenY);
+		if("stopPropagation" in e){ e.stopPropagation(); }
+		else { e.cancelBubble = false; }
+		return false;
 	}
 
 	function _onmousewheel(e){
 		e = e||window.event;
-		doh.robot.mouseWheelSize = e.detail ? (e.detail * -1) : (e.wheelDelta / 120);
+		robot.mouseWheelSize = e.detail ? (e.detail * -1) : (e.wheelDelta / 120);
 		if(e.preventDefault){ e.preventDefault(); }
 		else { e.returnValue = false; }
-		doh.robot._primePump = true;
-		doh.robot._initKeyboard();
+		robot._primePump = true;
+		robot._initKeyboard();
 		return false;
 	}
 
@@ -78,7 +91,7 @@
 	var keystring = "";
 	var expectedlength = 0;
 
-	doh.robot._nextKeyGroup = function(size){
+	robot._nextKeyGroup = function(size){
 		// called from Robot
 		// moves to the next group of keys to press; shift, alt-graph etc.
 		expectedlength = size;
@@ -90,22 +103,22 @@
 		var c = e.charCode ? e.charCode :
                    (e.keyCode ? e.keyCode :
                    (e.which ? e.which : 0)); // opera
-		if(doh.robot._primePump){
+		if(robot._primePump){
 			// event pump was primed with spaces and JS finally received one
 			// tell robot to stop sending spaces now
 			if(c == 32){
-				doh.robot._spaceReceived = true;
+				robot._spaceReceived = true;
 			}
 			else if(c == 13){
 				// enter: start accepting keys
-				doh.robot._primePump = false;
+				robot._primePump = false;
 			}
 		}
 		else if(c == 32){
 			keystring += String.fromCharCode(charCode);
 			charCode = 32;
 			if(keystring.length >= expectedlength){
-				doh.robot._notified(keystring);
+				robot._notified(keystring);
 			}
 		}
 		else if(c > 32){ // printable
@@ -119,19 +132,20 @@
 	}
 
 	var rf=null;
-	doh.robot._onKeyboard = function(){
+	robot._onKeyboard = function(){
 	 	// called from Robot
 		// Robot calls _onKeyboard after it finishes discovering the keyboard
 		// need to untie from Java thread with setTimeout
 		setTimeout(function(){
 			rf.style.visibility = "hidden";
-			doh.robot._run(window.frameElement);
+			robot._run(window.frameElement);
  		}, 0);
 	};
 </script>
 </head>
-<body style="margin:0px; padding:0px; border:0px none;background-color:transparent;" onload="init()">
-<input type="text" tabIndex="-1" style="border:0px none;margin:0px;padding:0px;width:200px;height:42px;background-color:white;z-index:9998;opacity:0;filter:alpha(opacity=0);cursor:default;"
+<body id="robotBody"
+	  style="margin:0px; padding:0px; border:0px none;background-color:transparent;" onload="init()">
+<input type="text" tabIndex="-1" style="border:0px none;margin:0px;padding:0px;width:200px;height:100px;background-color:white;z-index:9998;opacity:0;filter:alpha(opacity=0);cursor:default;"
 	onmousewheel="_onmousewheel(arguments[0])"
 	onmousedown="_onmousedown(arguments[0])"
 	onkeypress="_onkeypress(arguments[0])"
@@ -151,7 +165,7 @@
 		(Math.max(navigator.appVersion.indexOf("WebKit"), navigator.appVersion.indexOf("Safari"), 0) > 0 && navigator.userAgent.indexOf("Chrome/") == -1 && parseFloat(navigator.appVersion.split("Version/")[1]) < 4) // Safari 3
 		|| (document.all && navigator.userAgent.indexOf("Opera") == -1 && parseFloat(navigator.appVersion.split("MSIE ")[1]) < 8)) // IE6,7
 		?"true":"false")+'">';
-	var appletString = '<applet width="1" height="1" code="DOHRobot.class" archive="robot/DOHRobot.jar" MAYSCRIPT style="position:absolute;left:0px;top:22px;"><param name="mayscript" value="true"><param name="scriptable" value="true"><param name="initial_focus" value="false">'+needsSecurityManager+'</applet>';
+	var appletString = '<applet width="1" height="1" code="DOHRobot.class" archive="robot/DOHRobot.jar" MAYSCRIPT style="position:absolute;left:0px;top:0px;"><param name="mayscript" value="true"><param name="scriptable" value="true"><param name="initial_focus" value="false">'+needsSecurityManager+'</applet>';
 	document.write(appletString);
 	// if no Java, the applet is officially dead
 	if(/MSIE/.test(navigator.appVersion)){
@@ -160,7 +174,7 @@
 			// applet loads synchronously in IE6
 			document.applets[0].isActive();
 		}catch(e){
-			doh.robot._appletDead=true;
+			robot._appletDead=true;
 			// IE skips the dojo.robot XHR test below in the else
 			// since the no java behavior is the same as no applet behavior in IE
 			doh.run();
@@ -168,7 +182,7 @@
 	}else if(!navigator.javaEnabled()){
 		// FF, Safari, Opera etc.
 		// unreliable in IE6
-		doh.robot._appletDead=true;
+		robot._appletDead=true;
 		doh.run();
 	}else{
 		// Opera etc. have Java enabled, but load the applet asychronously so it might still be missing from server at this point
@@ -179,7 +193,7 @@
 			if(dohRobotCheck.readyState == 4 && dohRobotCheck.status == 404){
 				// oops! no applet
 				// move the tests along
-				doh.robot._appletDead=true;
+				robot._appletDead=true;
 				doh.run();
 			}
 		};
diff --git a/util/doh/_browserRunner.js b/util/doh/_browserRunner.js
index e4d525c..b0bd066 100644
--- a/util/doh/_browserRunner.js
+++ b/util/doh/_browserRunner.js
@@ -1,4 +1,8 @@
-define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
+define([
+	"dojo/dom", "dojo/dom-geometry", "dojo/dom-style",
+	"dojo/_base/fx", "dojo/_base/lang", "dojo/query", "dojo/domReady", "dojo/sniff", "dojo/window",
+	"doh/runner"
+], function(dom, domGeom, domStyle, baseFx, lang, query, domReady, has, win, doh){
 	doh.isBrowser= true;
 	var topdog;
 	try{
@@ -27,8 +31,8 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 			}
 			var enclosedFunc = function(){ return funcRef.apply(scope, arguments); };
 
-			if((window["dojo"])&&(type == "load")){
-				dojo.addOnLoad(enclosedFunc);
+			if(domReady && type == "load"){
+				domReady(enclosedFunc);
 			}else{
 				if(window["attachEvent"]){
 					window.attachEvent("on"+type, enclosedFunc);
@@ -44,7 +48,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 		// Over-ride or implement base runner.js-provided methods
 		//
 		var escapeXml = function(str){
-			//summary:
+			// summary:
 			//		Adds escape sequences for special characters in XML: &<>"'
 			//		Optionally skips escapes for single quotes
 			return str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """); // string
@@ -66,8 +70,8 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 		var _logBacklog = [], _loggedMsgLen = 0;
 		var sendToLogPane = function(args, skip){
 			var msg = "";
-			for(var x=0; x<args.length; x++){
-				msg += " "+args[x];
+			for(var x = 0; x < args.length; x++){
+				msg += " " + args[x];
 			}
 
 			msg = escapeXml(msg);
@@ -81,27 +85,27 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 				return;
 			}else if(_logBacklog.length && !skip){
 				var tm;
-				while((tm=_logBacklog.shift())){
+				while((tm = _logBacklog.shift())){
 					sendToLogPane(tm, true);
 				}
 			}
-			var logBody=byId("logBody");
+			var logBody = byId("logBody");
 			var tn = document.createElement("div");
 			tn.innerHTML = msg;
 			//tn.id="logmsg_"+logBody.childNodes.length;
 			logBody.appendChild(tn);
 			_loggedMsgLen++;
-		}
+		};
 
 		var findTarget = function(n){
 			while(n && !n.getAttribute('_target')){
-				n=n.parentNode;
+				n = n.parentNode;
 				if(!n.getAttribute){
-					n=null;
+					n = null;
 				}
 			}
 			return n;
-		}
+		};
 
 		doh._jumpToLog = function(e){
 			//console.log(e);
@@ -117,29 +121,29 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 			}
 			var t = lb.childNodes[_t];
 			t.scrollIntoView();
-			if(window.dojo){
+			if(domStyle && baseFx){
 				//t.parentNode.parentNode is <div class="tabBody">, only it has a explicitly set background-color,
 				//all children of it are transparent
-				var bgColor = dojo.style(t.parentNode.parentNode,'backgroundColor');
+				var bgColor = domStyle.get(t.parentNode.parentNode,'backgroundColor');
 				//node.parentNode is the tr which has background-color set explicitly
-				var hicolor = dojo.style(node.parentNode,'backgroundColor');
-				var unhilight = dojo.animateProperty({
+				var hicolor = domStyle.get(node.parentNode,'backgroundColor');
+				var unhilight = baseFx.animateProperty({
 					node: t,
 					duration: 500,
 					properties:
 					{
-						backgroundColor: { start:hicolor, end: bgColor }
+						backgroundColor: { start: hicolor, end: bgColor }
 					},
 					onEnd: function(){
 						t.style.backgroundColor="";
 					}
 				});
-				var hilight = dojo.animateProperty({
+				var hilight = baseFx.animateProperty({
 					node: t,
 					duration: 500,
 					properties:
 					{
-						backgroundColor: { start:bgColor, end: hicolor }
+						backgroundColor: { start: bgColor, end: hicolor }
 					},
 					onEnd: function(){
 						unhilight.play();
@@ -215,13 +219,59 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 
 			//This location can do the final performance rendering for the results
 			//of any performance tests.
-			var plotResults = null;
-			var standby;
+
 			if(doh.perfTestResults){
-				require(["dojox/math/stats", "dojox/charting/Chart2D", "dojox/charting/DataChart", "dojox/charting/plot2d/Scatter", "dojox/charting/plot2d/Lines", "dojo/data/ItemFileReadStore"], function(stats) {
-					dojo.mixin(doh, stats);
+				require(["dojox/math/stats", "dojox/charting/DataChart", "dojox/charting/plot2d/Scatter", "dojox/charting/plot2d/Lines", "dojo/data/ItemFileReadStore"],
+						function(stats, DataChart, Scatter, Lines, ItemFileReadStore){
+					lang.mixin(doh, stats);
+
+					var plotResults = function(div, name, dataArray) {
+						// Performance report generating functions!
+						var median = doh.median(dataArray);
+						var medarray = [];
+
+						var i;
+						for(i = 0; i < dataArray.length; i++){
+							medarray.push(median);
+						}
+
+						var data = {
+							label: "name",
+							items: [
+								{name: name, trials: dataArray},
+								{name: "Median", trials: medarray}
+							]
+						};
+						var ifs = new ItemFileReadStore({data: data});
+
+						var min = Math.floor(doh.min(dataArray));
+						var max = Math.ceil(doh.max(dataArray));
+						var step = (max - min)/10;
+
+						//Lets try to pad out the bottom and top a bit
+						//Then recalc the step.
+						if(min > 0){
+							min = min - step;
+							if(min < 0){
+								min = 0;
+							}
+							min = Math.floor(min);
+						}
+						if(max > 0){
+							max = max + step;
+							max = Math.ceil(max);
+						}
+						step = (max - min)/10;
+
+						var chart = new DataChart(div, {
+							type: Lines,
+							displayRange: dataArray.length,
+							xaxis: {min: 1, max: dataArray.length, majorTickStep: Math.ceil((dataArray.length - 1)/10), htmlLabels: false},
+							yaxis: {min: min, max: max, majorTickStep: step, vertical: true, htmlLabels: false}
+						});
+						chart.setStore(ifs, {name:"*"}, "trials");
+					};
 
-					plotResults = doh._dojoPlotPerfResults;
 					try{
 						var g;
 						var pBody = byId("perfTestsBody");
@@ -231,7 +281,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 						doh.perfTestAnalytics={};
 						doh.showPerfTestsPage();
 						for(g in doh.perfTestResults){
-							doh.perfTestAnalytics[g]={};
+							doh.perfTestAnalytics[g] = {};
 							var grp = doh.perfTestResults[g];
 							var hdr = document.createElement("h1");
 							hdr.appendChild(document.createTextNode("Group: " + g));
@@ -261,7 +311,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 									iAvgArray.push(fResults.trials[i].average);
 									tAvgArray.push(fResults.trials[i].executionTime);
 								}
-								var analytics=doh.perfTestAnalytics[g][f]={
+								var analytics = doh.perfTestAnalytics[g][f] = {
 									averageTrialExecutionTime: doh.mean(tAvgArray),
 									maxTestIterationTime: doh.max(iAvgArray),
 									minTestIterationTime: doh.min(iAvgArray),
@@ -285,8 +335,8 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 								div.innerHTML = "<h3>Average Test Execution Time (in milliseconds, with median line)</h3>";
 								ind.appendChild(div);
 								div = document.createElement("div");
-								dojo.style(div, "width", "600px");
-								dojo.style(div, "height", "250px");
+								domStyle.set(div, "width", "600px");
+								domStyle.set(div, "height", "250px");
 								ind.appendChild(div);
 								chartsToRender.push({
 									div: div,
@@ -298,8 +348,8 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 								div.innerHTML = "<h3>Average Trial Execution Time (in milliseconds, with median line)</h3>";
 								ind.appendChild(div);
 								div = document.createElement("div");
-								dojo.style(div, "width", "600px");
-								dojo.style(div, "height", "250px");
+								domStyle.set(div, "width", "600px");
+								domStyle.set(div, "height", "250px");
 								ind.appendChild(div);
 								chartsToRender.push({
 									div: div,
@@ -397,7 +447,9 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 		};
 
 		var addGroupToList = function(group){
-			if(!byId("testList")){ return; }
+			if(!byId("testList")){
+				return;
+			}
 			var tb = byId("testList").tBodies[0];
 			var tg = groupTemplate.cloneNode(true);
 			var tds = tg.getElementsByTagName("td");
@@ -405,27 +457,31 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 			toggle.onclick = _getGroupToggler(group, toggle);
 			var cb = tds[1].getElementsByTagName("input")[0];
 			cb.group = group;
-			cb.onclick = function(evt){
+			cb.onclick = function(){
 				doh._groups[group].skip = (!this.checked);
-			}
-			tds[2].innerHTML = "<div class='testGroupName'>"+group+"</div><div style='width:0;'> </div>";
+			};
+			tds[2].innerHTML = "<div class='testGroupName'>" + group + "</div><div style='width:0;'> </div>";
 			tds[3].innerHTML = "";
 
 			tb.appendChild(tg);
 			return tg;
-		}
+		};
 
 		var addFixtureToList = function(group, fixture){
-			if(!testTemplate){ return; }
+			if(!testTemplate){
+				return;
+			}
 			var cgn = groupNodes[group];
-			if(!cgn["__items"]){ cgn.__items = []; }
+			if(!cgn["__items"]){
+				cgn.__items = [];
+			}
 			var tn = testTemplate.cloneNode(true);
 			var tds = tn.getElementsByTagName("td");
 
 			tds[2].innerHTML = fixture.name;
 			tds[3].innerHTML = "";
 
-			var nn = (cgn.__lastFixture||cgn.__groupNode).nextSibling;
+			var nn = (cgn.__lastFixture || cgn.__groupNode).nextSibling;
 			if(nn){
 				nn.parentNode.insertBefore(tn, nn);
 			}else{
@@ -435,21 +491,21 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 			tn.style.display = "none";
 			cgn.__items.push(tn);
 			return (cgn.__lastFixture = tn);
-		}
+		};
 
 		var getFixtureNode = function(group, fixture){
 			if(groupNodes[group]){
 				return groupNodes[group][fixture.name];
 			}
 			return null;
-		}
+		};
 
 		var getGroupNode = function(group){
 			if(groupNodes[group]){
 				return groupNodes[group].__groupNode;
 			}
 			return null;
-		}
+		};
 
 		var updateBacklog = [];
 		doh._updateTestList = function(group, fixture, unwindingBacklog){
@@ -460,7 +516,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 				return;
 			}else if(updateBacklog.length && !unwindingBacklog){
 				var tr;
-				while((tr=updateBacklog.shift())){
+				while((tr = updateBacklog.shift())){
 					doh._updateTestList(tr[0], tr[1], true);
 				}
 			}
@@ -474,7 +530,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 					groupNodes[group][fixture.name] = addFixtureToList(group, fixture)
 				}
 			}
-		}
+		};
 
 		doh._testRegistered = doh._updateTestList;
 
@@ -495,7 +551,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 			if(gn){
 				gn.className = "inProgress";
 			}
-		}
+		};
 
 		doh._groupFinished = function(group, success){
 			// console.debug("_groupFinished", group);
@@ -506,16 +562,16 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 				gn.getElementsByTagName("td")[2].lastChild.className = "";
 				doh._inGroup = null;
 				//doh._runedSuite++;
-				var failure = doh._updateGlobalProgressBar(this._runedSuite/this._groupCount,success,group);
+				var failure = doh._updateGlobalProgressBar(this._runedSuite / this._groupCount, success, group);
 				gn.className = failure ? "failure" : "success";
 				//doh._runedSuite--;
-				doh._currentGlobalProgressBarWidth = parseInt(this._runedSuite/this._groupCount*10000)/100;
+				doh._currentGlobalProgressBarWidth = parseInt(this._runedSuite / this._groupCount * 10000) / 100;
 				//byId("progressOuter").style.width = parseInt(this._runedSuite/this._suiteCount*100)+"%";
 			}
 			if(doh._inGroup == group){
-				this.debug("Total time for GROUP \"",group,"\" is ",formatTime(doh._groupTotalTime));
+				this.debug("Total time for GROUP \"", group, "\" is ", formatTime(doh._groupTotalTime));
 			}
-		}
+		};
 
 		doh._testStarted = function(group, fixture){
 			// console.debug("_testStarted", group, fixture.name);
@@ -523,7 +579,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 			if(fn){
 				fn.className = "inProgress";
 			}
-		}
+		};
 
 		var _nameTimes = {};
 		var _playSound = function(name){
@@ -531,46 +587,47 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 				// console.debug("playing:", name);
 				var nt = _nameTimes[name];
 				// only play sounds once every second or so
-				if((!nt)||(((new Date)-nt) > 700)){
+				if((!nt) || (((new Date) - nt) > 700)){
 					_nameTimes[name] = new Date();
 					var tc = document.createElement("span");
 					byId("hiddenAudio").appendChild(tc);
-					tc.innerHTML = '<embed src="_sounds/'+name+'.wav" autostart="true" loop="false" hidden="true" width="1" height="1"></embed>';
+					tc.innerHTML = '<embed src="_sounds/' + name + '.wav" autostart="true" loop="false" hidden="true" width="1" height="1"></embed>';
 				}
 			}
-		}
+		};
 
-		doh._updateGlobalProgressBar = function(p,success,group){
-			var outerContainer=byId("progressOuter");
+		doh._updateGlobalProgressBar = function(p, success, group){
+			var outerContainer = byId("progressOuter");
 
-			var gdiv=outerContainer.childNodes[doh._runedSuite-1];
+			var gdiv = outerContainer.childNodes[doh._runedSuite - 1];
 			if(!gdiv){
-				gdiv=document.createElement('div');
+				gdiv = document.createElement('div');
 				outerContainer.appendChild(gdiv);
-				gdiv.className='success';
-				gdiv.setAttribute('_target',group);
+				gdiv.className = 'success';
+				gdiv.setAttribute('_target', group);
 			}
 			if(!success && !gdiv._failure){
-				gdiv._failure=true;
-				gdiv.className='failure';
+				gdiv._failure = true;
+				gdiv.className = 'failure';
 				if(group){
-					gdiv.setAttribute('title','failed group '+group);
+					gdiv.setAttribute('title', 'failed group ' + group);
 				}
 			}
-			var tp=parseInt(p*10000)/100;
-			gdiv.style.width = (tp-doh._currentGlobalProgressBarWidth)+"%";
+			var tp = parseInt(p * 10000) / 100;
+			gdiv.style.width = (tp - doh._currentGlobalProgressBarWidth) + "%";
 			return gdiv._failure;
-		}
+		};
 		doh._testFinished = function(group, fixture, success){
 			var fn = getFixtureNode(group, fixture);
 			var elapsed = fixture.endTime-fixture.startTime;
+			var gn;
 			if(fn){
 				fn.getElementsByTagName("td")[3].innerHTML = formatTime(elapsed);
 				fn.className = (success) ? "success" : "failure";
 				fn.getElementsByTagName("td")[2].setAttribute('_target', _loggedMsgLen);
 				if(!success){
 					_playSound("doh");
-					var gn = getGroupNode(group);
+					gn = getGroupNode(group);
 					if(gn){
 						gn.className = "failure";
 						_getGroupToggler(group)(null, true);
@@ -578,7 +635,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 				}
 			}
 			if(doh._inGroup == group){
-				var gn = getGroupNode(group);
+				gn = getGroupNode(group);
 				doh._runed++;
 				if(gn && doh._curTestCount){
 					var p = doh._runed/doh._curTestCount;
@@ -637,43 +694,44 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 			for(i = 0; i < toHide.length; i++){
 				var node = byId(toHide[i]);
 				if(node){
-					node.style.display="none";
+					node.style.display = "none";
 				}
 			}
 			toShow = byId(toShow);
 			if(toShow){
-				with(toShow.style){
-					display = "";
-					zIndex = ++tabzidx;
-				}
+				toShow.style.display = "";
+				toShow.style.zIndex = ++tabzidx;
 			}
-		}
+		};
 
 		doh.showTestPage = function(){
 			_showTab("testBody", ["logBody", "perfTestsBody"]);
-		}
+		};
 
 		doh.showLogPage = function(){
 			_showTab("logBody", ["testBody", "perfTestsBody"]);
-		}
+		};
 
 		doh.showPerfTestsPage = function(){
 			_showTab("perfTestsBody", ["testBody", "logBody"]);
-		}
+		};
 
 		var runAll = true;
 		doh.toggleRunAll = function(){
 			// would be easier w/ query...sigh
 			runAll = !runAll;
-			if(!byId("testList")){ return; }
+			if(!byId("testList")){
+				return;
+			}
 			var tb = byId("testList").tBodies[0];
 			var inputs = tb.getElementsByTagName("input");
-			var x=0; var tn;
-			while((tn=inputs[x++])){
+			var x = 0;
+			var tn;
+			while((tn = inputs[x++])){
 				tn.checked = runAll;
 				doh._groups[tn.group].skip = (!runAll);
 			}
-		}
+		};
 
 		var listHeightTimer = null;
 		var setListHeight = function(){
@@ -681,13 +739,15 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 				clearTimeout(listHeightTimer);
 			}
 			var tl = byId("testList");
-			if(!tl){ return; }
+			if(!tl){
+				return;
+			}
 			listHeightTimer = setTimeout(function(){
 				tl.style.display = "none";
 				tl.style.display = "";
 
 			}, 10);
-		}
+		};
 
 		_addOnEvt("resize", setListHeight);
 		_addOnEvt("load", setListHeight);
@@ -696,7 +756,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 			loaded = true;
 			groupTemplate = byId("groupTemplate");
 			if(!groupTemplate){
-				// make sure we've got an ammenable DOM structure
+				// make sure we've got an amenable DOM structure
 				return;
 			}
 			groupTemplate.parentNode.removeChild(groupTemplate);
@@ -722,7 +782,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 					if(byId("play")){
 						toggleRunning();
 					}
-				}
+				};
 				if(!byId("play")){
 					// make sure we've got an amenable DOM structure
 					return;
@@ -739,7 +799,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 						byId("playingMsg").style.display = byId("pause").style.display = "";
 						isRunning = true;
 					}
-				}
+				};
 				doh.run = (function(oldRun){
 					return function(){
 						if(!doh._currentGroup){
@@ -753,60 +813,12 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 				while((node=btns[idx++])){
 					node.onclick = toggleRunning;
 				}
-
-				//Performance report generating functions!
-				doh._dojoPlotPerfResults = function(div, name, dataArray) {
-					var median = doh.median(dataArray);
-					var medarray = [];
-
-					var i;
-					for(i = 0; i < dataArray.length; i++){
-						medarray.push(median);
-					}
-
-					var data = {
-						label: "name",
-						items: [
-							{name: name, trials: dataArray},
-							{name: "Median", trials: medarray}
-						]
-					};
-					var ifs = new dojo.data.ItemFileReadStore({data: data});
-
-					var min = Math.floor(doh.min(dataArray));
-					var max = Math.ceil(doh.max(dataArray));
-					var step = (max - min)/10;
-
-					//Lets try to pad out the bottom and top a bit
-					//Then recalc the step.
-					if(min > 0){
-						min = min - step;
-						if(min < 0){
-							min = 0;
-						}
-						min = Math.floor(min);
-					}
-					if(max > 0){
-						max = max + step;
-						max = Math.ceil(max);
-					}
-					step = (max - min)/10;
-
-					var chart = new dojox.charting.DataChart(div, {
-						type: dojox.charting.plot2d.Lines,
-						displayRange:dataArray.length,
-						xaxis: {min: 1, max: dataArray.length, majorTickStep: Math.ceil((dataArray.length - 1)/10), htmlLabels: false},
-						yaxis: {min: min, max: max, majorTickStep: step, vertical: true, htmlLabels: false}
-					});
-					chart.setStore(ifs, {name:"*"}, "trials");
-				};
-
 			}
 		);
 	}else{
 		// we're in an iframe environment. Time to mix it up a bit.
 
-		_doh = window.parent.doh;
+		var _doh = window.parent.doh;
 		var _thisGroup = _doh.currentGroupName;
 		var _thisUrl = _doh.currentUrl;
 		if(_thisGroup){
@@ -822,9 +834,9 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 				fixture.name = _thisUrl+"::"+arguments[0]+"::"+fixture.name;
 				_doh._updateTestList(_thisGroup, fixture);
 			};
-			doh.debug = doh.hitch(_doh, "debug");
-			doh.error = doh.hitch(_doh, "error");
-			doh.registerUrl = doh.hitch(_doh, "registerUrl");
+			doh.debug = lang.hitch(_doh, "debug");
+			doh.error = lang.hitch(_doh, "error");
+			doh.registerUrl = lang.hitch(_doh, "registerUrl");
 			doh._testStarted = function(group, fixture){
 				_doh._testStarted(_thisGroup, fixture);
 			};
@@ -835,7 +847,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 				//to the parent, so do that here.
 				if(doh.perfTestResults){
 					try{
-						gName = g.toString();
+						var gName = g.toString();
 						var localFName = f.name;
 						while(localFName.indexOf("::") >= 0){
 							localFName = localFName.substring(localFName.indexOf("::") + 2, localFName.length);
@@ -852,7 +864,7 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 					}
 				}
 			};
-			doh._groupStarted = function(g){
+			doh._groupStarted = function(){
 				if(!this._setParent){
 					_doh._curTestCount = this._testCount;
 					_doh._curGroupCount = this._groupCount;
@@ -863,5 +875,26 @@ define(["dojo", "doh/runner", "dojo/_firebug/firebug"], function(dojo, doh) {
 			};
 		}
 	}
+
+	var fixHeight = doh._fixHeight = function(){
+		// IE9 doesn't give test iframe height because no nodes have an explicit pixel height!
+		// Give outer table a pixel height.
+		if(has("ie")){
+			var headerHeight = 0;
+			var rows = query('#testLayout > tbody > tr');
+			for(var i = 0; i < rows.length-1; i++){
+				headerHeight += domGeom.position(rows[i]).h;
+			}
+			try{
+				// we subtract the headerHeight from the window height because the table row containing the tests is height:100% so they will stretch the table to the intended height.
+				dom.byId('testLayout').style.height = (win.getBox().h - headerHeight)+"px";
+			}catch(e){
+				// An obscure race condition when you load the runner in IE from the command line causes the window reported height to be 0.
+				// Try to recover after the window finishes rendering.
+				setTimeout(function(){ fixHeight(); },0);
+			}
+		}
+	};
+
 	return doh;
 });
diff --git a/util/doh/_nodeRunner.js b/util/doh/_nodeRunner.js
index 827db47..7d7174a 100644
--- a/util/doh/_nodeRunner.js
+++ b/util/doh/_nodeRunner.js
@@ -1,4 +1,12 @@
-define(["doh/runner", "require"], function(doh, require) {
+define(["doh/runner", "require", "dojo/_base/config"], function(doh, require, config){
+	/*=====
+	return {
+		// summary:
+		//		Module for running DOH tests in node (as opposed to a browser).
+		//		Augments return value from doh/runner.
+	};
+	=====*/
+
 	doh.debug= console.log;
 	doh.error= console.log;
 
@@ -16,7 +24,7 @@ define(["doh/runner", "require"], function(doh, require) {
 	console.log("The Dojo Unit Test Harness, $Rev: 23869 $");
 	console.log("Copyright (c) 2011, The Dojo Foundation, All Rights Reserved");
 	console.log("Running with node.js");
-	for (var tests= [], args=doh.config["commandLineArgs"], i= 0, arg; i<args.length; i++) {
+	for (var tests= [], args= config["commandLineArgs"], i= 0, arg; i<args.length; i++) {
 		arg= args[i];
 		if (arg.length==2 && arg[0]=="test") {
 			var test= arg[1];
diff --git a/util/doh/_parseURLargs.js b/util/doh/_parseURLargs.js
index c725092..0648d6c 100644
--- a/util/doh/_parseURLargs.js
+++ b/util/doh/_parseURLargs.js
@@ -1,13 +1,13 @@
 (function(){
 	var
-		boot=
+		boot =
 			// zero to many scripts to load a configuration and/or loader.
 			// i.e. path-to-util/doh/runner.html?boots=path-to/config.js,path-to/require.js
 			["../../dojo/dojo.js"],
 
-		standardDojoBoot= boot,
+		standardDojoBoot = boot,
 
-		test= 
+		test =
 			// zero to many AMD modules and/or URLs to load; provided by csv URL query parameter="test"
 			// For example, the URL...
 			//
@@ -37,7 +37,7 @@
 			false,
 
 		async = 
-			// boolean; config require.asyc==true before loading boot; this will have the effect of making
+			// boolean; config require.async==true before loading boot; this will have the effect of making
 			// version 1.7+ dojo bootstrap/loader operating in async mode
 			false,
 
@@ -45,7 +45,7 @@
 			// boolean; use a loader configuration that sandboxes the dojo and dojox objects used by doh
 			false,
 
-		trim= function(text){
+		trim = function(text){
 			if(text instanceof Array){
 				for (var result= [], i= 0; i<text.length; i++) {
 					result.push(trim(text[i]));
@@ -54,12 +54,12 @@
 			}else{
 				return text.match(/[^\s]*/)[0]; 
 			}
-		}
+		};
 
 		qstr = window.location.search.substr(1);
 
 	if(qstr.length){
-		for(var qparts= qstr.split("&"), x= 0; x<qparts.length; x++){
+		for(var qparts = qstr.split("&"), x = 0; x < qparts.length; x++){
 			var tp = qparts[x].split("="), name=tp[0], value=(tp[1]||"").replace(/[<>"':\(\)]/g, ""); // replace() to avoid XSS attack
 			//Avoid URLs that use the same protocol but on other domains, for security reasons.
 			if (value.indexOf("//") === 0 || value.indexOf("\\\\") === 0) {
@@ -112,122 +112,104 @@
 		}
 	}
 
-	function fixHeight(dojo){
-		// IE9 doesn't give test iframe height because no nodes have an explicit pixel height!
-		// Give outer table a pixel height.
-		if(dojo.isIE){
-			var headerHeight=0;
-			var rows=dojo.query('#testLayout > tbody > tr');
-			for(var i=0; i<rows.length-1; i++){
-				headerHeight+=dojo.position(rows[i]).h;
-			}
-			try{
-				// we subtract the headerHeight from the window height because the table row containing the tests is height:100% so they will stretch the table to the intended height.
-				dojo.byId('testLayout').style.height=(dojo.window.getBox().h-headerHeight)+"px";
-			}catch(e){
-				// An obscure race condition when you load the runner in IE from the command line causes the window reported height to be 0.
-				// Try to recover after the window finishes rendering.
-				setTimeout(function(){ fixHeight(dojo); },0);
-			}
-		}
-	}
-
 	var config;
 	if(sandbox){
 		// configure the loader assuming the dojo loader; of course the injected boot(s) can override this config
 		config= {
 			paths: paths,
 			// this config uses the dojo loader's scoping features to sandbox the version of dojo used by doh
-			packages:[{
-				name:'doh',
-				location:'../util/doh',
-				// here's the magic...everytime doh asks for a "dojo" module, it gets mapped to a "dohDojo"
+			packages: [{
+				name: 'doh',
+				location: '../util/doh',
+				// here's the magic...every time doh asks for a "dojo" module, it gets mapped to a "dohDojo"
 				// module; same goes for dojox/dohDojox since doh uses dojox
-				packageMap:{dojo:"dohDojo", dojox:"dohDojox"} 
+				packageMap: {dojo:"dohDojo", dojox:"dohDojox"}
 			},{
 				// now define the dohDojo package...
-				name:'dohDojo',
-				location:'../dojo',
-				packageMap:{dojo:"dohDojo", dojox:"dohDojox"}
+				name: 'dohDojo',
+				location: '../dojo',
+				packageMap: {dojo: "dohDojo", dojox: "dohDojox"}
 			},{
 				// and the dohDojox package...
-				name:'dohDojox',
-				location:'../dojox',
+				name: 'dohDojox',
+				location: '../dojox',
 				// and dojox uses dojo...that is, dohDojox...which must be mapped to dohDojo in the context of dohDojox
-				packageMap:{dojo:"dohDojo", dojox:"dohDojox"} 
+				packageMap: {dojo: "dohDojo", dojox: "dohDojox"}
 			}],
 			
 			// next, we need to preposition a special configuration for dohDojo
-			cache:{
-				"dohDojo*_base/config":function(){
+			cache: {
+				"dohDojo*_base/config": function(){
 					define([], {
 						// this configuration keeps dojo, dijit, and dojox out of the global space
-						scopeMap:[["dojo", "dohDojo"], ["dijit", "dohDijit"], ["dojox", "dohDojox"]],
-						isDebug:true,
-						noGlobals:true
+						scopeMap: [["dojo", "dohDojo"], ["dijit", "dohDijit"], ["dojox", "dohDojox"]],
+						isDebug: true,
+						noGlobals: true
 					});
 				}
 			},
 
 			// control the loader; don't boot global dojo, doh will ask for dojo itself
-			has:{
-				"dojo-sniff":0,
-				"dojo-loader":1,
-				"dojo-boot":0,
-				"dojo-test-sniff":1
+			has: {
+				"dojo-sniff": 0,
+				"dojo-loader": 1,
+				"dojo-boot": 0,
+				"dojo-test-sniff": 1
 			},
 
 			// no sniffing; therefore, set the baseUrl
-			baseUrl:"../../dojo",
+			baseUrl: "../../dojo",
 
-			deps:["dohDojo", "doh", "dohDojo/window"],
+			deps: ["dohDojo/domReady", "doh"],
 
-			callback:function(dohDojo, doh){
-				dohDojo.ready(function(){
-					fixHeight(dohDojo);
+			callback: function(domReady, doh){
+				domReady(function(){
+					doh._fixHeight();
 					doh.breakOnError= breakOnError;
-					require(test);
-					dohDojo.ready(doh, "run");
+					require(test, function(){
+						doh.run();
+					});
 				});
 			},
 
-			async:async
+			async: async
 		};
 	}else{
 		config= {
 			paths: paths,
-			deps:["dojo", "doh", "dojo/window"],
-			callback:function(dojo, doh){
-				dojo.ready(function(){
-					fixHeight(dojo);
+			deps: ["dojo/domReady", "doh"],
+			callback: function(domReady, doh){
+				domReady(function(){
+					doh._fixHeight();
 					doh.breakOnError= breakOnError;
-					require(test);
-					dojo.ready(doh, "run");
+					require(test, function(){
+						doh.run();
+					});
 				});
 			},
-			async:async,
-			isDebug:1
+			async: async,
+			isDebug: 1
 		};
 	}
 	
 	// load all of the dohPlugins
 	if(dohPlugins){
-		var i=0;
-		for(i=0; i<dohPlugins.length; i++){
+		var i = 0;
+		for(i = 0; i < dohPlugins.length; i++){
 			config.deps.push(dohPlugins[i]);
 		}
 	}
 	
-	require= config;
+	require = config;
 
 	// now script inject any boots
-	for(var e, i= 0; i<boot.length; i++) {
+	for(var e, i = 0; i < boot.length; i++) {
 		if(boot[i]){
-			e= document.createElement("script");
-			e.type= "text/javascript";
-			e.src= boot[i];
-			e.charset= "utf-8";
+			e = document.createElement("script");
+			e.type = "text/javascript";
+			e.src = boot[i];
+			e.charset = "utf-8";
 			document.getElementsByTagName("head")[0].appendChild(e);
 		}
 	}
-})()
\ No newline at end of file
+})();
\ No newline at end of file
diff --git a/util/doh/_rhinoRunner.js b/util/doh/_rhinoRunner.js
index 6fd4555..adaf303 100644
--- a/util/doh/_rhinoRunner.js
+++ b/util/doh/_rhinoRunner.js
@@ -1,4 +1,12 @@
-define(["doh/runner"], function(doh) {
+define(["doh/runner", "require", "dojo/_base/config"], function(doh, require, config){
+	/*=====
+	 return {
+	 // summary:
+	 //		Module for running DOH tests in rhino (as opposed to a browser).
+	 //		Augments return value from doh/runner.
+	 };
+	 =====*/
+
 	doh.debug= print;
 	doh.error= print;
 
@@ -15,7 +23,7 @@ define(["doh/runner"], function(doh) {
 	print("\n"+doh._line);
 	print("The Dojo Unit Test Harness, $Rev: 23869 $");
 	print("Copyright (c) 2011, The Dojo Foundation, All Rights Reserved");
-	for (var tests= [], args= doh.config["commandLineArgs"], i= 0, arg; i<args.length; i++) {
+	for (var tests= [], args= config["commandLineArgs"], i= 0, arg; i<args.length; i++) {
 		arg= (args[i]+"").split("=");
 		if (arg.length==2 && arg[0]=="test") {
 			var test= arg[1];
diff --git a/util/doh/doh.profile.js b/util/doh/doh.profile.js
index 33eaaf7..9d6663f 100644
--- a/util/doh/doh.profile.js
+++ b/util/doh/doh.profile.js
@@ -1,16 +1,16 @@
 var testResourceRe = /^doh\/tests/,
 	list = {
-		"doh/doh.profile":1,
-		"doh/package.json":1,
-		"doh/tests":1,
-		"doh/_parseURLargs":1
+		"doh/doh.profile": 1,
+		"doh/package.json": 1,
+		"doh/tests": 1,
+		"doh/_parseURLargs": 1
 	},
 	copyOnly = function(mid){
 		return (mid in list);
 	};
 
 var profile = {
-	resourceTags:{
+	resourceTags: {
 		test: function(filename, mid){
 			return testResourceRe.test(mid);
 		},
@@ -22,9 +22,5 @@ var profile = {
 		amd: function(filename, mid){
 			return !testResourceRe.test(mid) && !copyOnly(mid) && /\.js$/.test(filename);
 		}
-	},
-
-	trees:[
-		[".", ".", /(\/\.)|(~$)/]
-	]
+	}
 };
diff --git a/util/doh/mobileRunner.html b/util/doh/mobileRunner.html
index b8b6de1..670b66c 100644
--- a/util/doh/mobileRunner.html
+++ b/util/doh/mobileRunner.html
@@ -2,7 +2,7 @@
 <html style="height:100%;">
 	<head>
 		<title>The Dojo Unit Test Harness, $Rev: 25266 $</title>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
+		<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1"/>
 		<meta name="apple-mobile-web-app-capable" content="yes">
 		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
 		<script type="text/javascript">
@@ -70,19 +70,18 @@
 		</style>
 	</head>
 	<body style="height: 100%;">
-				<td style="height: 100%;">
-					<div style="position: relative; width: 100%; height: 100%; top: 0px; left: 0px;">
-						<div class="tabBody"
-							style="z-index: 1;">
-							<pre id="logBody"></pre>
-							<div id="perfTestsBody" style="background-color: white;"></div>
-						</div>
-						<iframe id="testBody" class="tabBody"
-							style="z-index: -1;"></iframe>
-						<!--
-							src="http://redesign.dojotoolkit.org"></iframe>
-						-->
-					</div>
+		<div style="position: relative; width: 100%; height: 100%; top: 0px; left: 0px;">
+			<div class="tabBody"
+				style="z-index: 1;">
+				<pre id="logBody"></pre>
+				<div id="perfTestsBody" style="background-color: white;"></div>
+			</div>
+			<iframe id="testBody" class="tabBody"
+				style="z-index: -1;"></iframe>
+			<!--
+				src="http://redesign.dojotoolkit.org"></iframe>
+			-->
+		</div>
 		<span id="hiddenAudio"></span>
 	</body>
 </html>
diff --git a/util/doh/package.json b/util/doh/package.json
index 1662064..49e6b3e 100644
--- a/util/doh/package.json
+++ b/util/doh/package.json
@@ -1,6 +1,6 @@
 {
 	"name": "doh",
-	"version":"1.7.0dev",
+	"version":"1.9.1",
 	"directories": {
 		"lib": "."
 	},
diff --git a/util/doh/plugins/README.txt b/util/doh/plugins/README.txt
index ced8cfe..2b1c80c 100644
--- a/util/doh/plugins/README.txt
+++ b/util/doh/plugins/README.txt
@@ -5,3 +5,12 @@ These are loaded after the test runner and test url, but before the runner begin
 Usage - e.g.: 
 	util/doh/runner.html?testModule=tests.cache&dohPlugins=doh/plugins/hello
     util/doh/runner.html?testModule=tests.cache&dohPlugins=doh/plugins/hello;doh/plugins/alwaysAudio
+
+Android robot testing
+doh/plugins/remoteRobot bridges the doh.robot API with the WebDriver API.
+On your PC, load android-webdriver-robot.html and follow the instructions to set up your Android phone for robot testing.
+The page links to a patched version of WebDriver that enables cross-domain scripting from the browser; this enables the browser to essentially drive itself.
+Sadly, the corresponding iPhone WebDriver is not as powerful as the Android version and does not use native events; do not expect it to work.
+
+Known issues:
+The mobile tests were broken during the AMD refactor, so don't expect to load the dojox.mobile tests and see them run just yet.
\ No newline at end of file
diff --git a/util/doh/plugins/android-webdriver-robot.html b/util/doh/plugins/android-webdriver-robot.html
new file mode 100644
index 0000000..de24199
--- /dev/null
+++ b/util/doh/plugins/android-webdriver-robot.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
+<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+<script>
+onSubmit1 = null;
+onSubmit2 = null;
+require(["dojo/dom", "dojo/_base/xhr", "dijit/form/Form", "dijit/form/Button", "dojo/parser", "dijit/registry"], function(dom, xhr, Form, Button, parser, registry){
+	var baseURL=null;
+	onSubmit1 = function(){
+		baseURL = "http://"+dom.byId('baseIP').value+":8080/wd/hub";
+		var status = dom.byId('status');
+		var message = dom.byId('message');
+		var sessionId = null;
+		// WebDriver sends a 302 to the new test session.
+		// Sadly, the browser tries to follow it automatically, so the xhr will always throw an error.
+		xhr("POST",{
+			url:baseURL+"/session",
+			headers: { "Content-Type": "application/json"},
+			handleAs:"json",
+			postData:'{desiredCapabilities:{"nativeEvents": "true", "browserName":"android",platform:"ANDROID","version":"","browserConnectionEnabled":"true","javascriptEnabled":"true"}}',
+			load:function(json){
+				// didn't expect a JSON response...
+				console.log(json);
+			},
+			error:function(e,ioArgs){
+				console.log(msg);
+				status.innerHTML = "Check network tab to get session ID.";
+			}
+		});
+		return false;
+	};
+	onSubmit2 = function(){
+		// expected result: couldn't load new address
+		// instead, issue new POST to load test in session
+		var testURL = dom.byId('testURL').value;
+		var status = dom.byId('status');
+		var message = dom.byId('message');
+		sessionId = dom.byId('sessionID').value;
+		dojo.xhr("POST",{
+			url:baseURL+"/session/"+sessionId+"/url",
+			headers: { "Content-Type": "application/json"},
+			handleAs:"json",
+			postData:'{url:"'+testURL+'&remoteRobotURL=http://localhost:8080/wd/hub/session/'+sessionId+'"}',
+			load:function(msg){
+				console.log(msg);
+				status.innerHTML = "Test started";
+				message.innerHTML = msg;
+			},
+			error:function(e){
+				status.innerHTML = "Test did not start";
+				message.innerHTML = e;
+			}
+		});
+	};
+});
+</script>
+</head>
+<body class="claro">
+<p>This is a prototype tool to assist starting a DOH test on an Android WebDriver. The goal is to automate this process into just one form submit.</p>
+<p>To start a test:</p>
+<ol>
+<li>On your Android device, <a href="http://haysmark.dojotoolkit.org/android-server.apk">download the patched WebDriver apk</a> and start it. You will get a black screen that says WebDriver at the top.</li>
+<li>Enter the IP of your Android device: <input type=text id="baseIP" name="baseIP" value="myandroidIP" /></li>
+<li>Open the Network tab in the browser's debugger</li>
+<li>Press <button type="button" id="button" data-dojo-type="dijit/form/Button" data-dojo-props='type:"button",label:"Submit"'>
+	<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+		onSubmit1();
+	</script>
+</button></li>
+<li>Enter the number you see in the Network tab for the failed redirect (should look something like 1342108893269 for instance): <input type=text id="sessionID" name="sessionID" value="1342108893269" /></li>
+<li>Enter the DOH mobileRunner.html URL you want to test (note the loaded plugin at the end): <input type=text id="testURL" name="testURL" value="http://mywebserver/util/doh/mobileRunner.html?test=dojox/mobile/tests/robot/module&dohPlugins=doh/plugins/remoteRobot" /></li>
+<li>Press <button type="button" id="button2" data-dojo-type="dijit/form/Button" data-dojo-props='type:"button",label:"Submit"'>
+	<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="evt">
+		onSubmit2();
+	</script>
+</button></li>
+<li>The test should momentarily start (after ~10s) on the device (if it doesn't load after a minute, repeat the procedure; some times an unbuilt Dojo will time out while the browser is caching everything for the first time.)</li>
+<hr />
+<h1 id="status" />
+<div id="message" />
+</body>
+</html>
diff --git a/util/doh/plugins/android-webdriver-robot.js b/util/doh/plugins/android-webdriver-robot.js
new file mode 100644
index 0000000..3063b01
--- /dev/null
+++ b/util/doh/plugins/android-webdriver-robot.js
@@ -0,0 +1,338 @@
+define(["dojo/has", "dojo/_base/xhr", "doh/runner", "dojo/sniff", "dojo/dom-geometry", "doh/plugins/remoteRobot"], function(has, xhr, doh, sniff, geom, remoteRobotURL){
+	// summary:
+	//		Wraps WebDriver APIs around doh.robot API.
+	//		Should be loaded as a doh plugin.
+	//		In theory, with a change to the base URL, this same file could also be used for iOS WebDriver.
+	// 		WebDriver must be modified to accept cross-domain requests (currently it sends incomplete headers).
+	//
+	
+	var top=window.parent?window.parent:window;
+	
+	// short-term FIFO command queue, similar to the one in the applet
+	var commands=[];
+	var _inFlight=false;
+	// send requests to the WebDriver and get its JSON text back
+	function robotXHR(args){
+		var commandString=args.commandString;
+		var deferred=args.deferred;
+		var immediate=args.immediate;
+		//console.debug("remote url: "+remoteRobotURL+"/"+commandString);
+		if(immediate||!_inFlight){
+			_inFlight=true;
+			xhr(args.method,{
+				url:remoteRobotURL+"/"+commandString,
+				headers: { "Content-Type": "application/json"},
+				postData:args.postData,
+				load:function(response){
+					//console.debug("success sending webdriver command: ", response);
+					_inFlight=false;
+					if(deferred){
+						deferred.callback(response);
+					}
+					if(commands.length){
+						robotXHR(commands.shift());
+					}
+				},
+				error:function(response){
+					console.error("failure sending webdriver command: ", response);
+				}
+			});
+		}else{
+			commands.push(args);
+		}
+	}
+	
+	// record stats about last mouse position
+	var lastX=0;
+	var lastY=0;
+	var mouse=null; // debug mouse cursor so you can see what is being touched; created on demand
+	// map dojo keys to WebDriver key codes
+	// enable/disable as we discover which ones are legit
+	
+	var keyMap={};
+	if(window["dojo"]){
+		// keyMap[dojo.keys.BACKSPACE]=0xE003;
+		//keyMap[dojo.keys.TAB]=0xE004;
+		// keyMap[dojo.keys.CLEAR]=0xE005;
+		// keyMap[dojo.keys.ENTER]=0xE007;
+		// keyMap[dojo.keys.SHIFT]=0xE008;
+		// keyMap[dojo.keys.CTRL]=0xE009;
+		// keyMap[dojo.keys.ALT]=0xE00A;
+		// keyMap[dojo.keys.META]=0xE03D;		// the apple key on macs
+		// keyMap[dojo.keys.PAUSE]=0xE00B;
+		// // dojo.keys.CAPS_LOCK: 20,
+		// keyMap[dojo.keys.ESCAPE]=0xE00C;
+		// keyMap[dojo.keys.SPACE]=0xE00D;
+		// keyMap[dojo.keys.PAGE_UP]=0xE00E;
+		// keyMap[dojo.keys.PAGE_DOWN]=0xE00F;
+		keyMap[dojo.keys.END]=0xE010;
+		keyMap[dojo.keys.HOME]=0xE011;
+		keyMap[dojo.keys.LEFT_ARROW]=0xE012;
+		keyMap[dojo.keys.UP_ARROW]=0xE013;
+		keyMap[dojo.keys.RIGHT_ARROW]=0xE014;
+		keyMap[dojo.keys.DOWN_ARROW]=0xE015;
+		// keyMap[dojo.keys.INSERT]=0xE016;
+		// keyMap[dojo.keys.DELETE]=0xE017;
+		// // dojo.keys.HELP: 47,
+		// // dojo.keys.LEFT_WINDOW: 91,
+		// // dojo.keys.RIGHT_WINDOW: 92,
+		// // dojo.keys.SELECT: 93,
+		// keyMap[dojo.keys.NUMPAD_0]=0xE01A;
+		// keyMap[dojo.keys.NUMPAD_1]=0xE01B;
+		// keyMap[dojo.keys.NUMPAD_2]=0xE01C;
+		// keyMap[dojo.keys.NUMPAD_3]=0xE01D;
+		// keyMap[dojo.keys.NUMPAD_4]=0xE01E;
+		// keyMap[dojo.keys.NUMPAD_5]=0xE01F;
+		// keyMap[dojo.keys.NUMPAD_6]=0xE020;
+		// keyMap[dojo.keys.NUMPAD_7]=0xE021;
+		// keyMap[dojo.keys.NUMPAD_8]=0xE022;
+		// keyMap[dojo.keys.NUMPAD_9]=0xE023;
+		// keyMap[dojo.keys.NUMPAD_MULTIPLY]=0xE024;
+		// keyMap[dojo.keys.NUMPAD_PLUS]=0xE025;
+		// keyMap[dojo.keys.NUMPAD_ENTER]=0xE026;
+		// keyMap[dojo.keys.NUMPAD_MINUS]=0xE027;
+		// keyMap[dojo.keys.NUMPAD_PERIOD]=0xE028;
+		// keyMap[dojo.keys.NUMPAD_DIVIDE]=0xE029;
+		keyMap[dojo.keys.F1]=0xE031;
+		keyMap[dojo.keys.F2]=0xE032;
+		keyMap[dojo.keys.F3]=0xE033;
+		keyMap[dojo.keys.F4]=0xE034;
+		keyMap[dojo.keys.F5]=0xE035;
+		keyMap[dojo.keys.F6]=0xE036;
+		keyMap[dojo.keys.F7]=0xE037;
+		keyMap[dojo.keys.F8]=0xE038;
+		keyMap[dojo.keys.F9]=0xE039;
+		keyMap[dojo.keys.F10]=0xE03A;
+		keyMap[dojo.keys.F11]=0xE03B;
+		keyMap[dojo.keys.F12]=0xE03C;
+	}
+	var lastElement={node:null,reference:""};
+	// replace applet with methods to call WebDriver
+	_robot={
+		_setKey:function(sec){
+			// initialization
+			// switch WebDriver to test frame so it can resolve elements!
+			/*robotXHR({
+				method:"POST",
+				commandString:"frame",
+				postData:'{"id":"testBody"}',
+				deferred:null,
+				immediate:false
+			});*/
+			// skip keyboard initialization
+			doh.robot._onKeyboard();
+		},
+		
+		_callLoaded:function(sec){
+			// shouldn't be called
+		},
+		
+		_initKeyboard:function(sec){
+			// shouldn't be called
+		},
+		
+		_initWheel:function(sec){
+			// shouldn't be called
+		},
+		
+		setDocumentBounds:function(sec, docScreenX, docScreenY, width, height){
+			// shouldn't be called
+		},
+		
+		_spaceReceived:function(){
+			// shouldn't be called
+		},
+		
+		_notified:function(sec, keystring){
+			// shouldn't be called
+		},
+		
+		_nextKeyGroupACK: function(sec){
+			// shouldn't be called
+		},
+		
+		typeKey:function(sec, charCode, keyCode, alt, ctrl, shift, meta, delay, async){
+			// send keys to active element
+			var deferred=new dojo.Deferred();
+			// after active element received...
+			deferred.then(function(response){
+				// remove garbage characters
+				response=response.replace(/\{/g,"({").replace(/\}/g,"})");
+				response=response.replace(/[^ -~]/g, "");
+				//response=response.substring(0,response.lastIndexOf(")")+1);
+				var json=dojo.fromJson(response);
+				var activeElement=json.value.ELEMENT;
+				// send keys to active element
+				var keys=(ctrl?'"'+String.fromCharCode(dojo.keys.CTRL)+'",':'')
+					+(shift?'"'+String.fromCharCode(dojo.keys.SHIFT)+'",':'');
+				if(keyCode in keyMap){
+					keys+='"'+String.fromCharCode(keyMap[keyCode])+'"';
+				}else if(keyCode){
+					keys+='"'+String.fromCharCode(keyCode)+'"';
+				}else{
+					keys+='"'+String.fromCharCode(charCode)+'"';
+				}
+				robotXHR({
+					method:"POST",
+					commandString:"element/"+activeElement+"/value",
+					postData:'{"value":['+keys+']}',
+					deferred:null,
+					immediate:false
+				});
+			});
+			// get active element to send keys to
+			// strangely, this request is a POST in the WebDriver API??
+			robotXHR({
+				method:"POST",
+				commandString:"execute",
+				postData:'{"script":"return document.activeElement;","args":[]}',
+				deferred:deferred,
+				immediate:false
+			});
+		},
+		
+		/* ---- do we need to add the keyUp and keyDown here? */
+		upKey:function(sec,charCode,keyCode,delay){
+			//robotXHR("upKey?sec="+sec+"&charCode="+charCode+"&keyCode="+keyCode+"&delay="+delay);
+		},
+		
+		downKey:function(sec,charCode,keyCode,delay){
+			//robotXHR("downKey?sec="+sec+"&charCode="+charCode+"&keyCode="+keyCode+"&delay="+delay);
+		},
+		
+		moveMouse:function(sec, x, y, delay, duration){
+			// x,y are not being computed relative to the mobile screen for some reason (probably iframe)
+			x=Math.round(x);
+			y=Math.round(y);
+			if(!mouse){
+				// create fake mouse
+				mouse=dojo.doc.createElement("div");
+				dojo.style(mouse, {
+					// x, y relative to screen (same coordinates as WebDriver)
+					position:"fixed",
+					left:"0px",
+					top:"0px",
+					width:"5px",
+					height:"5px",
+					"background-color":"red"
+				});
+				dojo.body().appendChild(mouse);
+			}
+			// fix x and y
+			lastX=x-top.scrollX;
+			lastY=y-top.scrollY;
+			// cursor needs to be away from center of event or else the cursor itself will interfere with the event!
+			mouse.style.left=(x+5)+"px";
+			mouse.style.top=(y+5)+"px";
+			//mouse.style.left=((lastX+top.scrollX+dojo.global.scrollX)+5)+"px";
+			//mouse.style.top=((lastY+top.scrollY+dojo.global.scrollY)+5)+"px";
+			robotXHR({
+				method:"POST",
+				commandString:"touch/move",
+				postData:'{"x":'+lastX+',"y":'+lastX+'}',
+				//content:{x:x,y:y},
+				deferred:null,
+				immediate:false
+			});
+		},
+		
+		pressMouse:function(sec, left, middle, right, delay){
+			//robotXHR("pressMouse?sec="+sec+"&left="+left+"&middle="+middle+"&right="+right+"&delay="+delay,null,true);
+			var deferred=new dojo.Deferred();
+			deferred.then(function(){
+				mouse.style.backgroundColor="yellow";
+			});
+			robotXHR({
+				method:"POST",
+				commandString:"touch/down",
+				postData:'{"x":'+(lastX)+',"y":'+(lastY)+'}',
+				//content:{x:lastX,y:lastY},
+				deferred:deferred,
+				immediate:false
+			});
+		},
+		
+		releaseMouse:function(sec, left, middle, right, delay){
+			//robotXHR("releaseMouse?sec="+sec+"&left="+left+"&middle="+middle+"&right="+right+"&delay="+delay,null,true);
+			var deferred=new dojo.Deferred();
+			deferred.then(function(){
+				mouse.style.backgroundColor="red";
+			});
+			robotXHR({
+				method:"POST",
+				commandString:"touch/up",
+				postData:'{"x":'+(lastX+1)+',"y":'+(lastY+1)+'}',
+				//content:{x:lastX,y:lastY},
+				deferred:deferred,
+				immediate:false
+			});
+		},
+		
+		// doh.robot will call these functions in place of its own
+		typeKeys:function(/*String||Number*/ chars, /*Integer, optional*/ delay, /*Integer, optional*/ duration){
+			// send keys to active element
+			var deferred=new dojo.Deferred();
+			// after active element received...
+			deferred.then(function(response){
+				response=response.replace(/\{/g,"({").replace(/\}/g,"})");
+				response=response.replace(/[^ -~]/g, "");
+				//response=response.substring(0,response.lastIndexOf(")")+1);
+				var json=dojo.fromJson(response);
+				var activeElement=json.value.ELEMENT;
+				// send keys to active element
+				var deferred2= new dojo.Deferred();
+				deferred2.then(function(){
+					lastElement={node:dojo.doc.activeElement,reference:activeElement};
+				});
+				robotXHR({
+					method:"POST",
+					commandString:"element/"+activeElement+"/value",
+					// TODO: add codes to sent array for press and release modifiers
+					postData:'{"value":["'+chars+'"]}',
+					deferred:deferred2,
+					immediate:false
+				});
+			});
+			// get active element to send keys to
+			// strangely, this request is a POST in the WebDriver API??
+			if(dojo.doc.activeElement!=lastElement.node){
+				lastElement={node:dojo.doc.activeElement,reference:null};
+				robotXHR({
+					method:"POST",
+					commandString:"execute",
+					postData:"{script:'return document.activeElement;',args:[]}",
+					deferred:deferred,
+					immediate:false
+				});
+			}else{
+				deferred.callback("{value:{ELEMENT:'"+lastElement.reference+"'}}");
+			}
+		},
+		
+		_scrollIntoView:function(node){
+			// for whatever reason, scrollIntoView does not work...
+			//node.scrollIntoView(true);
+			p = geom.position(node);
+			// scrolling the iframe doesn't seem to do anything
+			//dojo.global.scrollTo(p.x,p.y);
+			// this seems to work
+			top.scrollTo(p.x,p.y);
+			// this is also reasonable
+			/*var scrollBy={dx:p.x-top.scrollX,dy:p.y-top.scrollY};
+			robotXHR({
+				method:"POST",
+				commandString:"touch/scroll",
+				// TODO: add codes to sent array for press and release modifiers
+				postData:'{"xoffset":'+scrollBy.dx+', "yoffset":'+scrollBy.dy+'}',
+				deferred:null,
+				immediate:false
+			});*/
+		}
+	};
+	
+	// robot.js will use this robot instead of the applet
+	has.add("doh-custom-robot", function(){
+		return has("android") && _robot;
+	});
+	return _robot;
+});
diff --git a/util/doh/plugins/hello.js b/util/doh/plugins/hello.js
index a5e1f82..0ab703f 100644
--- a/util/doh/plugins/hello.js
+++ b/util/doh/plugins/hello.js
@@ -1,7 +1,7 @@
 define(["doh/runner"], function(doh) {
-	// summary: 
-	// 		A sample DOH plugin showing wrapping/augmentation of DOH
-	// 		We extend the 'run' method	to inject a 'hello world' kind of statement into the output
+	// summary:
+	//		A sample DOH plugin showing wrapping/augmentation of DOH
+	//		We extend the 'run' method	to inject a 'hello world' kind of statement into the output
 	var origRun = doh.run, 
 		registered = false;
 
diff --git a/util/doh/plugins/remoteRobot.js b/util/doh/plugins/remoteRobot.js
new file mode 100644
index 0000000..5ca432a
--- /dev/null
+++ b/util/doh/plugins/remoteRobot.js
@@ -0,0 +1,46 @@
+define("doh/plugins/remoteRobot", ["doh/runner", "dojo/_base/lang"], function(runner, lang){
+
+/*=====
+return {
+	// summary:
+	//		Plugin that bridges the doh.robot and WebDriver APIs.
+};
+=====*/
+	
+	// read in the test and port parameters from the URL
+	var remoteRobotURL = "";
+	var paths = "";
+	var qstr = window.location.search.substr(1);
+	if(qstr.length){	
+	var qparts = qstr.split("&");
+		for(var x=0; x<qparts.length; x++){
+			var tp = qparts[x].split("="), name = tp[0], value = tp[1].replace(/[<>"'\(\)]/g, "");	// replace() to avoid XSS attack
+			//Avoid URLs that use the same protocol but on other domains, for security reasons.
+			if (value.indexOf("//") === 0 || value.indexOf("\\\\") === 0) {
+				throw "Insupported URL";
+			}
+			switch(name){
+				case "remoteRobotURL":
+					remoteRobotURL = value;
+					break;
+				case "paths":
+					paths = value;
+					break;
+			}
+		}
+	}
+	// override doh runner so that it appends the remote robot url to each test
+	runner._registerUrl = (function(oi){
+		return lang.hitch(runner, function(group, url, timeout, type, dohArgs){
+			// append parameter, or specify new query string if appropriate
+			if(remoteRobotURL){
+				url += (/\?/.test(url)?"&":"?") + "remoteRobotURL=" + remoteRobotURL
+			}
+			if(paths){
+				url += (/\?/.test(url)?"&":"?") + "paths=" + paths;
+			}
+			oi.apply(runner, [group, url, timeout, type, dohArgs]);
+		});
+	})(runner._registerUrl);
+	return remoteRobotURL;
+});
\ No newline at end of file
diff --git a/util/doh/robot.js b/util/doh/robot.js
index 79f9937..05d6756 100644
--- a/util/doh/robot.js
+++ b/util/doh/robot.js
@@ -1,50 +1,55 @@
-define(["doh/_browserRunner", "require"], function(doh, require){
-
-	// loading state
-	var _robot = null;
-
-	var isSecure = (function(){
-		var key = Math.random();
-		return function(fcn){
-			return key;
-		};
-	})();
-
-	// no dojo available
-	// hijack doh.run instead
-	var _run = doh.run;
-	doh.run = function(){
-		if(!doh.robot._runsemaphore.unlock()){
-			// hijack doh._onEnd to clear the applet
-			// have to do it here because browserRunner sets it in onload in standalone case
-			var __onEnd = doh._onEnd;
-			doh._onEnd = function(){
-				doh.robot.killRobot();
-				doh._onEnd = __onEnd;
-				doh._onEnd();
-			};
-			doh.robot.startRobot();
-		}
+define([
+	"doh/_browserRunner", "require",
+	"dojo/aspect", "dojo/Deferred", "dojo/dom-class", "dojo/dom-construct", "dojo/dom-geometry", "dojo/_base/lang", "dojo/ready",
+	"dojo/_base/unload", "dojo/when", "dojo/_base/window", "dojo/sniff", "dojo/has", "dojo/has!android?doh/plugins/android-webdriver-robot"
+], function(doh, require, aspect, Deferred, domClass, construct, geom, lang, ready, unload, when, win, sniff, has, webdriver){
+
+// loading state
+var _robot = null;
+
+var isSecure = (function(){
+	var key = Math.random();
+	return function(fcn){
+		return key;
 	};
+})();
+
+var _keyPress = function(/*Number*/ charCode, /*Number*/ keyCode, /*Boolean*/ alt, /*Boolean*/ ctrl, /*Boolean*/ shift, /*Boolean*/ meta, /*Integer?*/ delay, /*Boolean*/ async){
+	// internal function to type one non-modifier key
+
+	// typecasting Numbers helps Sun's IE plugin lookup methods that take int arguments
+
+	// otherwise JS will send a double and Sun will complain
+	_robot.typeKey(isSecure(), Number(charCode), Number(keyCode), Boolean(alt), Boolean(ctrl), Boolean(shift), Boolean(meta), Number(delay||0), Boolean(async||false));
+};
+
+// Queue of pending actions plus the currently executing action registered via sequence().
+// Each action is a function that either:
+//		1. does a setTimeout()
+//		2. calls java Robot (mouse movement, typing a single letter, etc.)
+//		3. executes user defined function (for when app called sequence() directly).
+// Each function can return a Promise, or just a plain value if it executes synchronously.
+var seqPromise;
+aspect.before(doh, "_runFixture", function(){
+	// At the start of each new test fixture, clear any leftover queued actions from the previous test fixture.
+	// This will happen when the previous test throws an error, or times out.
+	var _seqPromise = seqPromise;
+	// need setTimeout to avoid false error; seqPromise from passing test is not fulfilled until after this execution trace finishes!
+	// really we should not have both `seqPromise` here and `var d = new doh.Deferred()` in the test
+	setTimeout(function(){
+		if(_seqPromise && !_seqPromise.isFulfilled()){
+			_seqPromise.cancel(new Error("new test starting, cancelling pending & in-progress queued events from previous test")); 
+		}
+	},0);
+	seqPromise = new Deferred();
+	seqPromise.resolve(true);
+});
 
-	var cleanup=function(){
-		doh.robot.killRobot();
-	}
-	if(typeof dojo !== 'undefined'){
-		dojo.addOnUnload(cleanup)
-	}else{
-		window.onunload=cleanup;
-	}
-	var _keyPress = function(/*Number*/ charCode, /*Number*/ keyCode, /*Boolean*/ alt, /*Boolean*/ ctrl, /*Boolean*/ shift, /*Boolean*/ meta, /*Integer, optional*/ delay, /*Boolean*/ async){
-		// internal function to type one non-modifier key
-
-		// typecasting Numbers helps Sun's IE plugin lookup methods that take int arguments
-
-		// otherwise JS will send a double and Sun will complain
-		_robot.typeKey(isSecure(), Number(charCode), Number(keyCode), Boolean(alt), Boolean(ctrl), Boolean(shift), Boolean(meta), Number(delay||0), Boolean(async||false));
-	};
+// Previous mouse position (from most recent mouseMoveTo() command)
+var lastMouse = {x: 5, y: 5};
 
-	doh.robot = {
+// For 2.0, remove code to set doh.robot global.
+var robot = doh.robot = {
 	_robotLoaded: true,
 	_robotInitialized: false,
 	// prime the event pump for fast browsers like Google Chrome - it's so fast, it doesn't stop to listen for keypresses!
@@ -54,10 +59,10 @@ define(["doh/_browserRunner", "require"], function(doh, require){
 	_killApplet: function(){}, // overridden by Robot.html
 
 	killRobot: function(){
-		if(doh.robot._robotLoaded){
-			doh.robot._robotLoaded = false;
-			document.documentElement.className = document.documentElement.className.replace(/ ?dohRobot/, "");
-			doh.robot._killApplet();
+		if(robot._robotLoaded){
+			robot._robotLoaded = false;
+			domClass.remove(document.documentElement, "dohRobot");
+			robot._killApplet();
 		}
 	},
 
@@ -68,8 +73,8 @@ define(["doh/_browserRunner", "require"], function(doh, require){
 	// one (or more after the robot loads) from the test page
 	// one from either the applet or an error condition
 	_runsemaphore: {
-		lock:["lock"],
-		unlock:function(){
+		lock: ["lock"],
+		unlock: function(){
 			try{
 				return this.lock.shift();
 			}catch(e){
@@ -86,13 +91,23 @@ define(["doh/_browserRunner", "require"], function(doh, require){
 			this._robotInitialized = true;
 			// if the iframe requested the applet and got a 404, then _robot is obviously unavailable
 			// at least run the non-robot tests!
-			if(doh.robot._appletDead){
-				doh.robot._onKeyboard();
+			if(robot._appletDead){
+				robot._onKeyboard();
 			}else{
 				_robot._callLoaded(isSecure());
 			}
 		}
+
+		// When robot finishes initializing it types a key, firing the _onKeyboard() listener, which calls _run(),
+		// which resolves this Deferred.
+		return this._started;
 	},
+
+	// _loaded: Deferred
+	//		Deferred that resolves when the _initRobot() has been called.
+	//		Note to be confused with dojo/robotx.js, which defines initRobot() without an underscore
+	_loaded: new doh.Deferred(),
+
 	_initRobot: function(r){
 		// called from Robot
 		// Robot calls _initRobot in its startup sequence
@@ -102,26 +117,36 @@ define(["doh/_browserRunner", "require"], function(doh, require){
 		doh._initRobotCalled = true;
 
 		// add dohRobot class to HTML element so tests can use that in CSS rules if desired
-		document.documentElement.className += " dohRobot";
+		domClass.add(document.documentElement, "dohRobot");
 		window.scrollTo(0, 0);
 //		document.documentElement.scrollTop = document.documentElement.scrollLeft = 0;
 		_robot = r;
 		_robot._setKey(isSecure());
-		// lazy load
-		doh.run();
+		this._loaded.resolve(true);
 	},
 
+	// _started: Deferred
+	//		Deferred that resolves when startRobot() has signaled completing by typing on the keyboard,
+	//		which in turn calls _run().
+	_started: new doh.Deferred(),
+
 	// some utility functions to help the iframe use private variables
 	_run: function(frame){
+		// called after the robot has been able to type on the keyboard, indicating that it's started
 		frame.style.visibility = "hidden";
-		doh.run = _run;
-		doh.run();
+		this._started.resolve(true);
 	},
 
 	_initKeyboard: function(){
 		_robot._initKeyboard(isSecure());
 	},
 
+	_onKeyboard: function(){
+		// replaced by iframe when applet present.
+		// remote robots don't have frames so pass a mock frame.
+		this._run({style:{visibility:""}});
+	},
+
 	_initWheel: function(){
 		_robot._initWheel(isSecure());
 	},
@@ -135,123 +160,117 @@ define(["doh/_browserRunner", "require"], function(doh, require){
 		_robot._notified(isSecure(), keystring);
 	},
 
-	_time:0,
-
 	// if the applet is 404 or cert is denied, this becomes true and kills tests
-	_appletDead:false,
+	_appletDead: false,
 
-	_assertRobot:function(){
+	_assertRobot: function(){
 		// make sure the applet is there and cert accepted
 		// otherwise, skip the test requesting the robot action
-		if(doh.robot._appletDead){ throw new Error('doh.robot not available; skipping test.'); }
+		if(robot._appletDead){ throw new Error('robot not available; skipping test.'); }
 	},
 
-	_mouseMove: function(/*Number*/ x, /*Number*/ y, /*Boolean*/ absolute, /*Integer, optional*/ duration){
+	_mouseMove: function(/*Number*/ x, /*Number*/ y, /*Boolean*/ absolute, /*Integer?*/ duration){
+		// This function is no longer used, but left for back-compat
 		if(absolute){
 			var scroll = {y: (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0),
-			x: (window.pageXOffset || (window["dojo"]?dojo._fixIeBiDiScrollLeft(document.documentElement.scrollLeft):undefined) || document.body.scrollLeft || 0)};
+			x: (window.pageXOffset || geom.fixIeBiDiScrollLeft(document.documentElement.scrollLeft) || document.body.scrollLeft || 0)};
 			y -= scroll.y;
 			x -= scroll.x;
 		}
 		_robot.moveMouse(isSecure(), Number(x), Number(y), Number(0), Number(duration||100));
 	},
 
-	// Main doh.robot API
-	sequence:function(/*Function*/ f, /*Integer, optional*/ delay, /*Integer, optional*/ duration){
+	// Main robot API
+	sequence: function(/*Function*/ f, /*Integer?*/ delay, /*Integer?*/ duration){
 		// summary:
 		//		Defer an action by adding it to the robot's incrementally delayed queue of actions to execute.
-		//
 		// f:
-		//		A function containing actions you want to defer.
-		//
+		//		A function containing actions you want to defer.  It can return a Promise
+		//		to delay further actions.
 		// delay:
 		//		Delay, in milliseconds, to wait before firing.
 		//		The delay is a delta with respect to the previous automation call.
 		//		For example, the following code ends after 600ms:
-		//			doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
-		//			doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
-		//
+		// |		robot.mouseClick({left: true}, 100) // first call; wait 100ms
+		// |		robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
 		// duration:
 		//		Delay to wait after firing.
-		//
 
-		var currentTime = (new Date()).getTime();
-		if(currentTime > (doh.robot._time || 0)){
-			doh.robot._time = currentTime;
+		function waitFunc(ms){
+			// Returns a function that returns a Promise that fires after ms milliseconds.
+			return function(){
+				var timer, d;
+				d = new Deferred(function(){ clearTimeout(timer); });
+				timer = setTimeout(function(){ d.resolve(true); }, ms);
+				return d;
+			};
 		}
-		doh.robot._time += delay || 1;
-		setTimeout(f, doh.robot._time - currentTime);
-		doh.robot._time += duration || 0;
+
+		// Queue action to run specified function, plus optional "wait" actions for delay and duration.
+		if(delay){ seqPromise = seqPromise.then(waitFunc(delay)); }
+		seqPromise = seqPromise.then(f);
+		if(duration){ seqPromise = seqPromise.then(waitFunc(duration)); }
 	},
 
-	typeKeys: function(/*String||Number*/ chars, /*Integer, optional*/ delay, /*Integer, optional*/ duration){
+	typeKeys: function(/*String|Number*/ chars, /*Integer?*/ delay, /*Integer?*/ duration){
 		// summary:
 		//		Types a string of characters in order, or types a dojo.keys.* constant.
-		//
 		// description:
-		// 		Types a string of characters in order, or types a dojo.keys.* constant.
-		// 		Example: doh.robot.typeKeys("dijit.ed", 500);
-		//
+		//		Types a string of characters in order, or types a dojo.keys.* constant.
+		// example:
+		// |	robot.typeKeys("dijit.ed", 500);
 		// chars:
 		//		String of characters to type, or a dojo.keys.* constant
-		//
 		// delay:
 		//		Delay, in milliseconds, to wait before firing.
 		//		The delay is a delta with respect to the previous automation call.
 		//		For example, the following code ends after 600ms:
-		//			doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
-		//			doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
-		//
+		// |		robot.mouseClick({left: true}, 100) // first call; wait 100ms
+		// |		robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
 		// duration:
 		//		Time, in milliseconds, to spend pressing all of the keys.
 		//		The default is (string length)*50 ms.
-		//
 
 		this._assertRobot();
-		this.sequence(function(){
-			var isNum = typeof(chars) == Number;
-			duration=duration||(isNum?50:chars.length*50);
-			if(isNum){
-				_keyPress(chars, chars, false, false, false, false, 0);
-			}else if(chars.length){
-				_keyPress(chars.charCodeAt(0), 0, false, false, false, false, 0);
-				for(var i = 1; i<chars.length; i++){
-					_keyPress(chars.charCodeAt(i), 0, false, false, false, false, Math.max(Math.floor(duration/chars.length), 0));
-				}
+		var isNum = typeof(chars) == Number;
+		duration = duration||(isNum?50: chars.length*50);
+		if(isNum){
+			this.sequence(lang.partial(_keyPress, chars, chars, false, false, false, false, 0, 0),
+				delay, duration);
+		}else{
+			for(var i = 0; i < chars.length; i++){
+				this.sequence(lang.partial(_keyPress, chars.charCodeAt(i), 0, false, false, false, false, 0, 0),
+					i == 0 ? delay : 0, Math.max(Math.ceil(duration/chars.length), 0));
 			}
-		}, delay, duration);
+		}
 	},
 
-	keyPress: function(/*Integer*/ charOrCode, /*Integer, optional*/ delay, /*Object*/ modifiers, /*Boolean*/ asynchronous){
+	keyPress: function(/*Integer*/ charOrCode, /*Integer?*/ delay, /*Object*/ modifiers, /*Boolean*/ asynchronous){
 		// summary:
 		//		Types a key combination, like SHIFT-TAB.
-		//
 		// description:
-		// 		Types a key combination, like SHIFT-TAB.
-		// 		Example: to press shift-tab immediately, call doh.robot.keyPress(dojo.keys.TAB, 0, {shift:true})
-		//
+		//		Types a key combination, like SHIFT-TAB.
+		// example:
+		//		to press shift-tab immediately, call robot.keyPress(dojo.keys.TAB, 0, {shift: true})
 		// charOrCode:
 		//		char/JS keyCode/dojo.keys.* constant for the key you want to press
-		//
 		// delay:
 		//		Delay, in milliseconds, to wait before firing.
 		//		The delay is a delta with respect to the previous automation call.
 		//		For example, the following code ends after 600ms:
-		//			doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
-		//			doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
-		//
+		// |		robot.mouseClick({left: true}, 100) // first call; wait 100ms
+		// |		robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
 		// modifiers:
 		//		JSON object that represents all of the modifier keys being pressed.
 		//		It takes the following Boolean attributes:
-		//			- shift
-		//			- alt
-		//			- ctrl
-		//			- meta
 		//
+		//		- shift
+		//		- alt
+		//		- ctrl
+		//		- meta
 		// asynchronous:
 		//		If true, the delay happens asynchronously and immediately, outside of the browser's JavaScript thread and any previous calls.
 		//		This is useful for interacting with the browser's modal dialogs.
-		//
 
 		this._assertRobot();
 		if(!modifiers){
@@ -272,100 +291,91 @@ define(["doh/_browserRunner", "require"], function(doh, require){
 		}
 		this.sequence(function(){
 			_keyPress(isChar?charOrCode.charCodeAt(0):0, isChar?0:charOrCode, modifiers.alt, modifiers.ctrl, modifiers.shift, modifiers.meta, 0);
-		},delay);
+		}, delay);
 	},
 
-	keyDown: function(/*Integer*/ charOrCode, /*Integer, optional*/ delay){
+	keyDown: function(/*Integer*/ charOrCode, /*Integer?*/ delay){
 		// summary:
 		//		Holds down a single key, like SHIFT or 'a'.
-		//
 		// description:
-		// 		Holds down a single key, like SHIFT or 'a'.
-		// 		Example: to hold down the 'a' key immediately, call doh.robot.keyDown('a')
-		//
+		//		Holds down a single key, like SHIFT or 'a'.
+		// example:
+		//		to hold down the 'a' key immediately, call robot.keyDown('a')
 		// charOrCode:
 		//		char/JS keyCode/dojo.keys.* constant for the key you want to hold down
 		//		Warning: holding down a shifted key, like 'A', can have unpredictable results.
-		//
 		// delay:
 		//		Delay, in milliseconds, to wait before firing.
 		//		The delay is a delta with respect to the previous automation call.
 		//		For example, the following code ends after 600ms:
-		//			doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
-		//			doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
-		//
+		// |		robot.mouseClick({left: true}, 100) // first call; wait 100ms
+		// |		robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
 
 		this._assertRobot();
 		this.sequence(function(){
 			var isChar = typeof(charOrCode)=="string";
 			_robot.downKey(isSecure(), isChar?charOrCode:0, isChar?0:charOrCode, 0);
-		},delay);
+		}, delay);
 	},
 
-	keyUp: function(/*Integer*/ charOrCode, /*Integer, optional*/ delay){
+	keyUp: function(/*Integer*/ charOrCode, /*Integer?*/ delay){
 		// summary:
 		//		Releases a single key, like SHIFT or 'a'.
-		//
 		// description:
-		// 		Releases a single key, like SHIFT or 'a'.
-		// 		Example: to release the 'a' key immediately, call doh.robot.keyUp('a')
-		//
+		//		Releases a single key, like SHIFT or 'a'.
+		// example:
+		//		to release the 'a' key immediately, call robot.keyUp('a')
 		// charOrCode:
 		//		char/JS keyCode/dojo.keys.* constant for the key you want to release
 		//		Warning: releasing a shifted key, like 'A', can have unpredictable results.
-		//
 		// delay:
 		//		Delay, in milliseconds, to wait before firing.
 		//		The delay is a delta with respect to the previous automation call.
 		//		For example, the following code ends after 600ms:
-		//			doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
-		//			doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
-		//
+		// |		robot.mouseClick({left: true}, 100) // first call; wait 100ms
+		// |		robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
 
 		this._assertRobot();
 		this.sequence(function(){
 			var isChar=typeof(charOrCode)=="string";
 			_robot.upKey(isSecure(), isChar?charOrCode:0, isChar?0:charOrCode, 0);
-		},delay);
+		}, delay);
 	},
 
 
-	mouseClick: function(/*Object*/ buttons, /*Integer, optional*/ delay){
+	mouseClick: function(/*Object*/ buttons, /*Integer?*/ delay){
 		// summary:
 		//		Convenience function to do a press/release.
-		//		See doh.robot.mousePress for more info.
-		//
+		//		See robot.mousePress for more info.
 		// description:
 		//		Convenience function to do a press/release.
-		//		See doh.robot.mousePress for more info.
-		//
+		//		See robot.mousePress for more info.
 
 		this._assertRobot();
-		doh.robot.mousePress(buttons, delay);
-		doh.robot.mouseRelease(buttons, 1);
+		robot.mousePress(buttons, delay);
+		robot.mouseRelease(buttons, 1);
 	},
 
-	mousePress: function(/*Object*/ buttons, /*Integer, optional*/ delay){
+	mousePress: function(/*Object*/ buttons, /*Integer?*/ delay){
 		// summary:
-		// 		Presses mouse buttons.
+		//		Presses mouse buttons.
 		// description:
-		// 		Presses the mouse buttons you pass as true.
-		// 		Example: to press the left mouse button, pass {left:true}.
-		// 		Mouse buttons you don't specify keep their previous pressed state.
-		//
-		// buttons:	JSON object that represents all of the mouse buttons being pressed.
+		//		Presses the mouse buttons you pass as true.
+		//		Example: to press the left mouse button, pass {left: true}.
+		//		Mouse buttons you don't specify keep their previous pressed state.
+		// buttons:
+		//		JSON object that represents all of the mouse buttons being pressed.
 		//		It takes the following Boolean attributes:
-		//			- left
-		//			- middle
-		//			- right
 		//
+		//		- left
+		//		- middle
+		//		- right
 		// delay:
 		//		Delay, in milliseconds, to wait before firing.
 		//		The delay is a delta with respect to the previous automation call.
 		//		For example, the following code ends after 600ms:
-		//			doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
-		//			doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
-		//
+		// |		robot.mouseClick({left: true}, 100) // first call; wait 100ms
+		// |		robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
 
 		this._assertRobot();
 		if(!buttons){ return; }
@@ -377,54 +387,106 @@ define(["doh/_browserRunner", "require"], function(doh, require){
 				}
 			}
 			_robot.pressMouse(isSecure(), Boolean(buttons.left), Boolean(buttons.middle), Boolean(buttons.right), Number(0));
-		},delay);
+		}, delay);
 	},
 
-	mouseMove: function(/*Number*/ x, /*Number*/ y, /*Integer, optional*/ delay, /*Integer, optional*/ duration, /*Boolean*/ absolute){
+	mouseMoveTo: function(/*Object*/ point, /*Integer?*/ delay, /*Integer?*/ duration, /*Boolean*/ absolute){
 		// summary:
-		// 		Moves the mouse to the specified x,y offset relative to the viewport.
-		//
+		//		Move the mouse from the current position to the specified point.
+		//		Delays reading contents point until queued command starts running.
+		//		See mouseMove() for details.
+		// point: Object
+		//		x, y position relative to viewport, or if absolute == true, to document
+
+		this._assertRobot();
+		duration = duration||100;
+
+		// Calculate number of mouse movements we will do, based on specified duration.
+		// IE6-8 timers have a granularity of 15ms, so only do one mouse move every 15ms
+		var steps = duration<=1 ? 1 : // duration==1 -> user wants to jump the mouse
+			(duration/15)|1; // |1 to ensure an odd # of intermediate steps for sensible interpolation
+		var stepDuration = Math.floor(duration/steps);
+
+		// Starting and ending points of the mouse movement.
+		var start, end;
+
+		this.sequence(function(){
+			// This runs right before we start moving the mouse.   At this time (but not before), point is guaranteed
+			// to be filled w/the correct data.   So set start and end points for the movement of the mouse.
+			start = lastMouse;
+			if(absolute){
+				// Adjust end to be relative to viewport
+				var scroll = {y: (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0),
+					x: (window.pageXOffset || geom.fixIeBiDiScrollLeft(document.documentElement.scrollLeft) || document.body.scrollLeft || 0)};
+				end = { y: point.y - scroll.y, x: point.x - scroll.x };
+			}else{
+				end = point;
+			}
+			//console.log("mouseMoveTo() start, going from (", lastMouse.x, lastMouse.y, "), (", end.x, end.y, "), delay = " +
+			//	delay + ", duration = " + duration);
+		}, delay || 0);
+
+		// Function to positions the mouse along the line from start to end at the idx'th position (from 0 .. steps)
+		function step(idx){
+			function easeInOutQuad(/*Number*/ t, /*Number*/ b, /*Number*/ c, /*Number*/ d){
+				t /= d / 2;
+				if(t < 1)
+					return Math.round(c / 2 * t * t + b);
+				t--;
+				return Math.round(-c / 2 * (t * (t - 2) - 1) + b);
+			}
+
+			var x = idx == steps ? end.x : easeInOutQuad(idx, start.x, end.x - start.x, steps),
+				y = idx == steps ? end.y : easeInOutQuad(idx, start.y, end.y - start.y, steps);
+
+			// If same position as the last time, don't bother calling java robot.
+			if(x == lastMouse.x && y == lastMouse.y){ return true; }
+
+			_robot.moveMouse(isSecure(), Number(x), Number(y), Number(0), Number(1));
+			lastMouse = {x: x, y: y};
+		}
+
+		// Schedule mouse moves from beginning to end of line.
+		// Start from t=1 because there's no need to move the mouse to where it already is
+		for (var t = 1; t <= steps; t++){
+			// Use lang.partial() to lock in value of t before the t++
+			this.sequence(lang.partial(step, t), 0, stepDuration);
+		}
+	},
+
+	mouseMove: function(/*Number*/ x, /*Number*/ y, /*Integer?*/ delay, /*Integer?*/ duration, /*Boolean*/ absolute){
+		// summary:
+		//		Moves the mouse to the specified x,y offset relative to the viewport.
 		// x:
 		//		x offset relative to the viewport, in pixels, to move the mouse.
-		//
 		// y:
 		//		y offset relative to the viewport, in pixels, to move the mouse.
-		//
 		// delay:
 		//		Delay, in milliseconds, to wait before firing.
 		//		The delay is a delta with respect to the previous automation call.
 		//		For example, the following code ends after 600ms:
-		//			doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
-		//			doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
-		//
+		// |		robot.mouseClick({left: true}, 100) // first call; wait 100ms
+		// |		robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
 		// duration:
 		//		Approximate time Robot will spend moving the mouse
 		//		The default is 100ms. This also affects how many mousemove events will
 		//		be generated, which is the log of the duration.
-		//
 		// absolute:
 		//		Boolean indicating whether the x and y values are absolute coordinates.
 		//		If false, then mouseMove expects that the x,y will be relative to the window. (clientX/Y)
 		//		If true, then mouseMove expects that the x,y will be absolute. (pageX/Y)
-		//
 
-		this._assertRobot();
-		duration = duration||100;
-		this.sequence(function(){
-			doh.robot._mouseMove(x, y, absolute, duration);
-		},delay,duration);
+		this.mouseMoveTo({x: x, y: y}, delay, duration, absolute);
 	},
 
-	mouseRelease: function(/*Object*/ buttons, /*Integer, optional*/ delay){
+	mouseRelease: function(/*Object*/ buttons, /*Integer?*/ delay){
 		// summary:
-		// 		Releases mouse buttons.
-		//
+		//		Releases mouse buttons.
 		// description:
-		// 		Releases the mouse buttons you pass as true.
-		// 		Example: to release the left mouse button, pass {left:true}.
-		// 		Mouse buttons you don't specify keep their previous pressed state.
-		//		See doh.robot.mousePress for more info.
-		//
+		//		Releases the mouse buttons you pass as true.
+		//		Example: to release the left mouse button, pass {left: true}.
+		//		Mouse buttons you don't specify keep their previous pressed state.
+		//		See robot.mousePress for more info.
 
 		this._assertRobot();
 		if(!buttons){ return; }
@@ -436,74 +498,68 @@ define(["doh/_browserRunner", "require"], function(doh, require){
 				}
 			}
 			_robot.releaseMouse(isSecure(), Boolean(buttons.left), Boolean(buttons.middle), Boolean(buttons.right), Number(0));
-		},delay);
+		}, delay);
 	},
 
 	// mouseWheelSize: Integer value that determines the amount of wheel motion per unit
 	mouseWheelSize: 1,
 
-	mouseWheel: function(/*Number*/ wheelAmt, /*Integer, optional*/ delay, /*Integer, optional*/ duration){
+	mouseWheel: function(/*Number*/ wheelAmt, /*Integer?*/ delay, /*Integer?*/ duration){
 		// summary:
 		//		Spins the mouse wheel.
-		//
 		// description:
-		// 		Spins the wheel wheelAmt "notches."
-		// 		Negative wheelAmt scrolls up/away from the user.
-		// 		Positive wheelAmt scrolls down/toward the user.
-		// 		Note: this will all happen in one event.
-		// 		Warning: the size of one mouse wheel notch is an OS setting.
-		//		You can accesss this size from doh.robot.mouseWheelSize
-		//
+		//		Spins the wheel wheelAmt "notches."
+		//		Negative wheelAmt scrolls up/away from the user.
+		//		Positive wheelAmt scrolls down/toward the user.
+		//		Note: this will all happen in one event.
+		//		Warning: the size of one mouse wheel notch is an OS setting.
+		//		You can access this size from robot.mouseWheelSize
 		// wheelAmt:
 		//		Number of notches to spin the wheel.
-		// 		Negative wheelAmt scrolls up/away from the user.
-		// 		Positive wheelAmt scrolls down/toward the user.
-		//
+		//		Negative wheelAmt scrolls up/away from the user.
+		//		Positive wheelAmt scrolls down/toward the user.
 		// delay:
 		//		Delay, in milliseconds, to wait before firing.
 		//		The delay is a delta with respect to the previous automation call.
 		//		For example, the following code ends after 600ms:
-		//			doh.robot.mouseClick({left:true}, 100) // first call; wait 100ms
-		//			doh.robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
-		//
+		//			robot.mouseClick({left: true}, 100) // first call; wait 100ms
+		//			robot.typeKeys("dij", 500) // 500ms AFTER previous call; 600ms in all
 		// duration:
 		//		Approximate time Robot will spend moving the mouse
 		//		By default, the Robot will wheel the mouse as fast as possible.
-		//
-
 
 		this._assertRobot();
 		if(!wheelAmt){ return; }
 		this.sequence(function(){
 			_robot.wheelMouse(isSecure(), Number(wheelAmt), Number(0), Number(duration||0));
-		},delay,duration);
+		}, delay, duration);
 	},
 
-	setClipboard: function(/*String*/data,/*String, optional*/format){
+	setClipboard: function(/*String*/ data,/*String?*/ format){
 		// summary:
 		//		Set clipboard content.
-		//
 		// description:
-		// 		Set data as clipboard content, overriding anything already there. The
+		//		Set data as clipboard content, overriding anything already there. The
 		//		data will be put to the clipboard using the given format.
-		//
 		// data:
 		//		New clipboard content to set
-		//
 		// format:
 		//		Set this to "text/html" to put richtext to the clipboard.
 		//		Otherwise, data is treated as plaintext. By default, plaintext
 		//		is used.
 		if(format==='text/html'){
-			_robot.setClipboardHtml(isSecure(),data);
+			_robot.setClipboardHtml(isSecure(), data);
 		}else{
-			_robot.setClipboardText(isSecure(),data);
+			_robot.setClipboardText(isSecure(), data);
 		}
 	}
-	};
+};
 
-	// the applet itself
-	// needs to be down here so the handlers are set up
+// After page has finished loading, create the applet iframe.
+// Note: could eliminate dojo/ready dependency by tying this code to startRobot() call, but then users
+// are required to put doh.run() inside of a dojo/ready.   Probably they are already doing that though.
+ready(function(){
+	// console.log("creating applet iframe");
 	var iframesrc;
 	var scripts = document.getElementsByTagName("script");
 	for(var x = 0; x<scripts.length; x++){
@@ -513,11 +569,70 @@ define(["doh/_browserRunner", "require"], function(doh, require){
 			break;
 		}
 	}
-	// if loaded with dojo, there might not be a runner.js!
-	if(!iframesrc && window["dojo"]){
+
+	if(!iframesrc){
 		// if user set document.domain to something else, send it to the Robot too
 		iframesrc = require.toUrl("./Robot.html") + "?domain=" + escape(document.domain);
 	}
-	document.writeln('<div id="dohrobotview" style="border:0px none; margin:0px; padding:0px; position:absolute; bottom:0px; right:0px; width:1px; height:1px; overflow:hidden; visibility:hidden; background-color:red;"></div>'+
-		'<iframe application="true" style="border:0px none; z-index:32767; padding:0px; margin:0px; position:absolute; left:0px; top:0px; height:42px; width:200px; overflow:hidden; background-color:transparent;" tabIndex="-1" src="'+iframesrc+'" ALLOWTRANSPARENCY="true"></iframe>');
+	construct.place('<div id="dohrobotview" style="border:0px none; margin:0px; padding:0px; position:absolute; bottom:0px; right:0px; width:1px; height:1px; overflow:hidden; visibility:hidden; background-color:red;"></div>',
+		win.body());
+
+	if(!has("doh-custom-robot")){
+		// load default robot when not custom def given
+		construct.place('<iframe application="true" style="border:0px none; z-index:32767; padding:0px; margin:0px; position:absolute; left:0px; top:0px; height:100px; width:200px; overflow:hidden; background-color:transparent;" tabIndex="-1" src="'+iframesrc+'" ALLOWTRANSPARENCY="true"></iframe>',
+			win.body());
+	}else{
+		// custom def given
+		console.log("using custom robot");
+		_robot = webdriver;
+		// mix in exports
+		for(var i in _robot){
+			if(robot[i]&&_robot[i]){
+				robot[i]=_robot[i];
+			}
+		}
+		// continue init instead of waiting on frame
+		robot._initRobot(_robot);
+	}
+});
+
+// Start the robot as the first "test" when DOH runs.
+doh.registerGroup("initialize robot", [
+	{
+		name: "load robot",
+		timeout: 20000,
+		runTest: function(){
+			// first wait for robot to tell us it's loaded, i.e. that _initRobot() has been called
+			return robot._loaded;
+		}
+	},
+	{
+		name: "start robot",
+		timeout: 20000,
+		runTest: function(){
+			// then we call startRobot(), and wait it to asynchronously complete
+			return robot.startRobot();
+		}
+	}
+]);
+
+// Register the killRobot() command as the last "test" to run.
+// There's no good API to do this, so instead call doh.registerGroup() when the app first calls doh.run(),
+// since presumably all the real tests have already been registered.   Note that doh.run() is called multiple times,
+// so make sure to only call registerGroup() once.
+var _oldRun = doh.run;
+doh.run = function(){
+	doh.registerGroup("kill robot", {
+		name: "killRobot",
+		timeout: 10000,
+		runTest: function(){
+			robot.killRobot();
+		}
+	});
+	doh.run = _oldRun;
+	doh.run();
+};
+
+
+return robot;
 });
diff --git a/util/doh/robot/DOHRobot.jar b/util/doh/robot/DOHRobot.jar
index 8d4479b..9041ad6 100644
Binary files a/util/doh/robot/DOHRobot.jar and b/util/doh/robot/DOHRobot.jar differ
diff --git a/util/doh/robot/DOHRobot.java b/util/doh/robot/DOHRobot.java
index 23daa41..9c87d80 100644
--- a/util/doh/robot/DOHRobot.java
+++ b/util/doh/robot/DOHRobot.java
@@ -83,6 +83,7 @@ public final class DOHRobot extends Applet{
 	private int docScreenYMax;
 	private Point margin = null;
 	private boolean mouseSecurity = false;
+	private int dohscreen = -1;
 
 	// The last reported mouse x,y.
 	// If this is different from the real one, something's up.
@@ -125,10 +126,17 @@ public final class DOHRobot extends Applet{
 		public void componentShown(ComponentEvent evt){
 			// sets the security manager to fix a bug in liveconnect in Safari on Mac
 			if(key != -1){ return; }
-			Thread thread = new Thread(){
+			Runnable thread = new Runnable(){
 				public void run(){
 					log("Document root: ~"+applet().getLocationOnScreen().toString());
-					window = (JSObject) JSObject.getWindow(applet());   
+					while(true){
+						try{
+							window = (JSObject) JSObject.getWindow(applet());
+							break;
+						}catch(Exception e){
+							// wait
+						}
+					}
 					AccessController.doPrivileged(new PrivilegedAction(){
 						public Object run(){
 							log("> init Robot");
@@ -158,6 +166,8 @@ public final class DOHRobot extends Applet{
 									securitymanager.checkTopLevelWindow(null);
 									System.setSecurityManager(securitymanager);
 								}
+							}catch(SecurityException e){
+								// OpenJDK is very strict; fail gracefully
 							}catch(Exception e){
 								log("Error calling _init_: "+e.getMessage());
 								key = -2;
@@ -215,12 +225,14 @@ public final class DOHRobot extends Applet{
 		Method getPointerInfo = mouseInfoClass.getMethod("getPointerInfo", new Class[0]);
 		Method getLocation = pointerInfoClass.getMethod("getLocation", new Class[0]);
 		Object pointer=null;
+		Point p=null;
 		try{
 			pointer = getPointerInfo.invoke(pointerInfoClass,new Object[0]);
+			p = (Point)(getLocation.invoke(pointer,new Object[0]));
 		}catch(java.lang.reflect.InvocationTargetException e){
 			e.getTargetException().printStackTrace();
 		}
-		return (Point)(getLocation.invoke(pointer,new Object[0]));
+		return p;
 	}
 	
 	public Point getLocationOnScreen(){
@@ -234,6 +246,7 @@ public final class DOHRobot extends Applet{
 		Point mousePosition=null;
 		try{
 			mousePosition=getDesktopMousePosition();
+			log("Mouse position: "+mousePosition);
 		}catch(Exception e){
 			return true;
 		}
@@ -244,8 +257,10 @@ public final class DOHRobot extends Applet{
 	}
 
 	private boolean isSecure(double key){
+		// make sure key is not unset (-1) or error state (-2) and is the expected key
 		boolean result = this.key != -1 && this.key != -2 && this.key == key;
 		try{
+			// also make sure mouse in good spot
 			result=result&&mouseSecure();
 		}catch(Exception e){
 			e.printStackTrace();
@@ -256,8 +271,10 @@ public final class DOHRobot extends Applet{
 			window.eval("doh.robot._appletDead=true;");
 			log("User aborted test; mouse moved off of browser");
 			alert("User aborted test; mouse moved off of browser.");
+			log("Key secure: false; mouse in bad spot?");
+		}else{
+			log("Key secure: " + result);
 		}
-		log("Key secure: " + result);
 		return result;
 	}
 
@@ -276,11 +293,13 @@ public final class DOHRobot extends Applet{
 							// Seems to have to do with the plugin they compile with rather than the jvm itself because Safari5.0 and FF3.6 still work.
 							p = new Point();
 							int screen=0;
-							int minscreen=-1;
+							dohscreen=-1;
 							int mindifference=Integer.MAX_VALUE;
 							GraphicsDevice[] screens=GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
 							try{
 								for(screen=0; screen<screens.length; screen++){
+									// get origin of screen in Java virtual coordinates
+									Rectangle bounds=screens[screen].getDefaultConfiguration().getBounds();
 									// take picture
 									DisplayMode mode=screens[screen].getDisplayMode();
 									int width=mode.getWidth();
@@ -310,16 +329,17 @@ public final class DOHRobot extends Applet{
 												}
 											}
 											if(difference<mindifference){
-												p.x=x;
-												p.y=y;
+												// convert device coordinates to virtual coordinates by adding screen's origin
+												p.x=x+(int)bounds.getX();
+												p.y=y+(int)bounds.getY();
 												mindifference=difference;
-												minscreen=screen;
+												dohscreen=screen;
 											}
 										}
 									}
 								}
 								// create temp robot to put mouse in right spot
-								robot=new Robot(screens[minscreen]);
+								robot=new Robot(screens[dohscreen]);
 								robot.setAutoWaitForIdle(true);
 							}catch(Exception e){
 								e.printStackTrace();
@@ -343,21 +363,26 @@ public final class DOHRobot extends Applet{
 						try{
 							Thread.sleep(100);
 						}catch(Exception e){};
-						robot.mouseMove(x, y);
+						
 						try{
 							// mouse in right spot; restore control to original robot using browser's preferred coordinates
 							robot = new Robot();
 							robot.setAutoWaitForIdle(true);
+							robot.mouseMove(x, y);
 							Thread.sleep(100);
-						}catch(Exception e){};
-						robot.mousePress(InputEvent.BUTTON1_MASK);
-						try{
-							Thread.sleep(100);
-						}catch(Exception e){}
-						robot.mouseRelease(InputEvent.BUTTON1_MASK);
-						try{
-							Thread.sleep(100);
-						}catch(Exception e){}
+							// click 50 times then abort
+							int i=0;
+							for(i=0; i<50&&!inited; i++){
+								robot.mousePress(InputEvent.BUTTON1_MASK);
+								Thread.sleep(100);
+								robot.mouseRelease(InputEvent.BUTTON1_MASK);
+								Thread.sleep(100);
+								log("mouse clicked");
+							}
+							if(i==50){
+								applet().stop();
+							}
+						}catch(Exception e){ e.printStackTrace(); }
 						log("< _callLoaded Robot");
 						return null;
 					}
@@ -402,7 +427,7 @@ public final class DOHRobot extends Applet{
 	}
 
 	// mouse discovery code
-	public void setDocumentBounds(final double sec, int x, int y, int w, int h) throws Exception{
+	public void setDocumentBounds(final double sec, final int x, final int y, final int w, final int h) throws Exception{
 		// call from JavaScript
 		// tells the Robot where the screen x,y of the upper left corner of the
 		// document are
@@ -412,16 +437,22 @@ public final class DOHRobot extends Applet{
 		if(!isSecure(sec))
 			return;
 		if(!inited){
+			DOHRobot _this=applet();
+			log("initing doc bounds");
 			inited = true;
-			this.lastMouseX = this.docScreenX = x;
-			this.lastMouseY = this.docScreenY = y;
-			this.docScreenXMax = x + w;
-			this.docScreenYMax = y + h;
+			Point location=_this.getLocationOnScreen();
+			_this.lastMouseX = _this.docScreenX = location.x;
+			_this.lastMouseY = _this.docScreenY = location.y;
+			_this.docScreenXMax = _this.docScreenX + w;
+			_this.docScreenYMax = _this.docScreenY + h;
+			log("Doc bounds: "+docScreenX+","+docScreenY+" => "+docScreenXMax+","+docScreenYMax);
 			// compute difference between position and browser edge for future reference
-			this.margin = getLocationOnScreen();
-			this.margin.x -= x;
-			this.margin.y -= y;
+			_this.margin = getLocationOnScreen();
+			_this.margin.x -= x;
+			_this.margin.y -= y;
 			mouseSecurity=true;
+		}else{
+			log("ERROR: tried to reinit bounds?");
 		}
 		log("< setDocumentBounds");
 	}
@@ -1284,7 +1315,9 @@ public final class DOHRobot extends Applet{
 		}
 		public void run(){}
 	}
-	
+
+	// Unclear why we have to fire keypress in a separate thread.
+	// Since delay is no longer used, maybe this code can be simplified.
 	final private class KeyPressThread extends ProfilingThread{
 		private int charCode;
 		private int keyCode;
diff --git a/util/doh/runner.html b/util/doh/runner.html
index 647aa20..f706569 100644
--- a/util/doh/runner.html
+++ b/util/doh/runner.html
@@ -1,29 +1,7 @@
 <!DOCTYPE html>
 <html style="height:100%;">
 	<head>
-		<title>The Dojo Unit Test Harness, $Rev: 25896 $</title>
-
-		<script type="text/javascript">
-			// workaround for bug in Safari 3.	See #7189
-			if (/3[\.0-9]+ Safari/.test(navigator.appVersion))
-			{
-				window.console = {
-					origConsole: window.console,
-						log: function(s){
-						this.origConsole.log(s);
-					},
-					info: function(s){
-						this.origConsole.info(s);
-					},
-					error: function(s){
-						this.origConsole.error(s);
-					},
-					warn: function(s){
-						this.origConsole.warn(s);
-					}
-				};
-			}
-		</script>
+		<title>The Dojo Unit Test Harness, $Rev$</title>
 
 		<script type="text/javascript" src="_parseURLargs.js"></script>
 	
@@ -91,15 +69,16 @@
 			}
 
 			#progressOuter {
-				background:#e9e9e9 url("http://o.aolcdn.com/dojo/1.3/dijit/themes/tundra/images/dojoTundraGradientBg.png") repeat-x 0 0;
+				background-color: #e9e9e9;
+				background-image: -webkit-linear-gradient(rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%);
+				background-image: -moz-linear-gradient(rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%);
+				background-image: -ms-linear-gradient(rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%);
+				background-image: -o-linear-gradient(rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%);
+
 				height: 1em;
 				/*the following trick is necessary to prevent IE from wrapping the last piece of progress bar into a new line*/
 				_margin:1px;
 				_padding: -1px;
-				
-				/*
-				border-color: #e8e8e8;
-				*/
 			}
 
 			#progressOuter .success, #progressOuter .failure{
diff --git a/util/doh/runner.js b/util/doh/runner.js
index e26420d..940a07f 100644
--- a/util/doh/runner.js
+++ b/util/doh/runner.js
@@ -1,10 +1,14 @@
-define("doh/runner", ["dojo"], function(dojo) {
-var doh= dojo.mixin({}, dojo);
+define("doh/runner", ["dojo/_base/lang"], function(lang){
+
+var doh = {
+	// summary:
+	//		Functions for registering and running automated tests.
+};
 
 // intentionally define global tests and global doh symbols
-// TODO: scrub these globals from tests and remove this pollution
+// TODO: scrub these globals from tests and remove this pollution for 2.0
 tests = doh;
-this.doh= doh;
+this.doh = doh;
 
 doh._line = "------------------------------------------------------------";
 
@@ -27,7 +31,9 @@ doh.error = function(){
 
 doh._AssertFailure = function(msg, hint){
 	if (doh.breakOnError) {
+		//>>excludeStart("debuggerCrashesRhino", /^shrinksafe.comments/.test(kwArgs.optimize));
 		debugger;
+		//>>excludeEnd("debuggerCrashesRhino")
 	}
 	if(!(this instanceof doh._AssertFailure)){
 		return new doh._AssertFailure(msg, hint);
@@ -52,15 +58,16 @@ doh.Deferred = function(canceller){
 	this.silentlyCancelled = false;
 };
 
-doh.extend(doh.Deferred, {
+lang.extend(doh.Deferred, {
 	getTestErrback: function(cb, scope){
-		// summary: Replaces outer getTextCallback's in nested situations to avoid multiple callback(true)'s
+		// summary:
+		//		Replaces outer getTextCallback's in nested situations to avoid multiple callback(true)'s
 		var _this = this;
 		return function(){
 			try{
 				cb.apply(scope||doh.global||_this, arguments);
 			}catch(e){
-				_this.errback(e);
+				_this.reject(e);
 			}
 		};
 	},
@@ -71,34 +78,13 @@ doh.extend(doh.Deferred, {
 			try{
 				cb.apply(scope||doh.global||_this, arguments);
 			}catch(e){
-				_this.errback(e);
+				_this.reject(e);
 				return;
 			}
-			_this.callback(true);
+			_this.resolve(true);
 		};
 	},
 
-	getFunctionFromArgs: function(){
-		//TODO: this looks like dojo.hitch? remove and replace?
-		var a = arguments;
-		if((a[0])&&(!a[1])){
-			if(typeof a[0] == "function"){
-				return a[0];
-			}else if(typeof a[0] == "string"){
-				return doh.global[a[0]];
-			}
-		}else if((a[0])&&(a[1])){
-			return doh.hitch(a[0], a[1]);
-		}
-		return null;
-	},
-
-	makeCalled: function() {
-		var deferred = new doh.Deferred();
-		deferred.callback();
-		return deferred;
-	},
-
 	_nextId: (function(){
 		var n = 1;
 		return function(){ return n++; };
@@ -112,7 +98,7 @@ doh.extend(doh.Deferred, {
 				this.silentlyCancelled = true;
 			}
 			if(this.fired == -1){
-				this.errback(new Error("Deferred(unfired)"));
+				this.reject(new Error("Deferred(unfired)"));
 			}
 		}else if(this.fired == 0 && this.results[0] && this.results[0].cancel){
 			this.results[0].cancel();
@@ -147,16 +133,15 @@ doh.extend(doh.Deferred, {
 				throw new Error("already called!");
 			}
 			this.silentlyCancelled = false;
-			return;
 		}
 	},
 
-	callback: function(res){
+	resolve: function(res){
 		this._check();
 		this._resback(res);
 	},
 
-	errback: function(res){
+	reject: function(res){
 		this._check();
 		if(!(res instanceof Error)){
 			res = new Error(res);
@@ -164,39 +149,32 @@ doh.extend(doh.Deferred, {
 		this._resback(res);
 	},
 
-	addBoth: function(cb, cbfn){
-		//TODO: this looks like dojo.hitch? remove and replace?
-		var enclosed = this.getFunctionFromArgs(cb, cbfn);
-		if(arguments.length > 2){
-			enclosed = doh.hitch(null, enclosed, arguments, 2);
+	then: function(cb, eb){
+		this.chain.push([cb, eb]);
+		if(this.fired >= 0){
+			this._fire();
 		}
-		return this.addCallbacks(enclosed, enclosed);
+		return this;
 	},
 
-	addCallback: function(cb, cbfn){
-		//TODO: this looks like dojo.hitch? remove and replace?
-		var enclosed = this.getFunctionFromArgs(cb, cbfn);
-		if(arguments.length > 2){
-			enclosed = doh.hitch(null, enclosed, arguments, 2);
-		}
-		return this.addCallbacks(enclosed, null);
+	always: function(cb){
+		this.then(cb, cb);
 	},
 
-	addErrback: function(cb, cbfn){
-		//TODO: this looks like dojo.hitch? remove and replace?
-		var enclosed = this.getFunctionFromArgs(cb, cbfn);
-		if(arguments.length > 2){
-			enclosed = doh.hitch(null, enclosed, arguments, 2);
-		}
-		return this.addCallbacks(null, enclosed);
+	otherwise: function(eb){
+		this.then(null, eb);
 	},
 
-	addCallbacks: function(cb, eb){
-		this.chain.push([cb, eb]);
-		if(this.fired >= 0){
-			this._fire();
-		}
-		return this;
+	isFulfilled: function(){
+		return this.fired >= 0;
+	},
+
+	isResolved: function(){
+		return this.fired == 0;
+	},
+
+	isRejected: function(){
+		return this.fired == 1;
 	},
 
 	_fire: function(){
@@ -215,7 +193,7 @@ doh.extend(doh.Deferred, {
 			try {
 				res = f(res);
 				fired = ((res instanceof Error) ? 1 : 0);
-				if(res && res.addCallback){
+				if(res && res.then){
 					cb = function(res){
 						self._continue(res);
 					};
@@ -229,8 +207,63 @@ doh.extend(doh.Deferred, {
 		this.fired = fired;
 		this.results[fired] = res;
 		if((cb)&&(this.paused)){
-			res.addBoth(cb);
+			res.always(cb);
+		}
+	}
+});
+
+lang.extend(doh.Deferred, {
+	// Back compat methods, remove for 2.0
+
+	getFunctionFromArgs: function(){
+		// Like lang.hitch but first arg (context) is optional
+		var a = arguments;
+		if((a[0])&&(!a[1])){
+			if(typeof a[0] == "function"){
+				return a[0];
+			}else if(typeof a[0] == "string"){
+				return doh.global[a[0]];
+			}
+		}else if((a[0])&&(a[1])){
+			return lang.hitch(a[0], a[1]);
+		}
+		return null;
+	},
+
+	addCallbacks: function(cb, eb){
+		this.then(cb, eb);
+	},
+
+	addCallback: function(cb, cbfn){
+		var enclosed = this.getFunctionFromArgs(cb, cbfn);
+		if(arguments.length > 2){
+			enclosed = lang.hitch(null, enclosed, arguments, 2);
+		}
+		return this.then(enclosed);
+	},
+
+	addErrback: function(cb, cbfn){
+		var enclosed = this.getFunctionFromArgs(cb, cbfn);
+		if(arguments.length > 2){
+			enclosed = lang.hitch(null, enclosed, arguments, 2);
+		}
+		return this.otherwise(enclosed);
+	},
+
+	addBoth: function(cb, cbfn){
+		var enclosed = this.getFunctionFromArgs(cb, cbfn);
+		if(arguments.length > 2){
+			enclosed = lang.hitch(null, enclosed, arguments, 2);
 		}
+		return this.always(enclosed);
+	},
+
+	callback: function(val){
+		this.resolve(val);
+	},
+
+	errback: function(val){
+		this.reject(val);
 	}
 });
 
@@ -263,22 +296,22 @@ doh._testTypes= {};
 
 doh.registerTestType= function(name, initProc){
 	// summary:
-	//	 Adds a test type and associates a function used to initialize each test of the given type
+	//		Adds a test type and associates a function used to initialize each test of the given type
 	// name: String
-	//	 The name of the type.
+	//		The name of the type.
 	// initProc: Function
-	//	 Type specific test initializer; called after the test object is created.
+	//		Type specific test initializer; called after the test object is created.
 	doh._testTypes[name]= initProc;
 };
 
 doh.registerTestType("perf", function(group, tObj, type){
-	//Augment the test with some specific options to make it identifiable as a
-	//particular type of test so it can be executed properly.
+	// Augment the test with some specific options to make it identifiable as a
+	// particular type of test so it can be executed properly.
 	if(type === "perf" || tObj.testType === "perf"){
 		tObj.testType = "perf";
 
-		//Build an object on the root DOH class to contain all the test results.
-		//Cache it on the test object for quick lookup later for results storage.
+		// Build an object on the root DOH class to contain all the test results.
+		// Cache it on the test object for quick lookup later for results storage.
 		if(!doh.perfTestResults){
 			doh.perfTestResults = {};
 			doh.perfTestResults[group] = {};
@@ -291,18 +324,18 @@ doh.registerTestType("perf", function(group, tObj, type){
 		}
 		tObj.results = doh.perfTestResults[group][tObj.name];
 
-		//If it's not set, then set the trial duration; default to 100ms.
+		// If it's not set, then set the trial duration; default to 100ms.
 		if(!("trialDuration" in tObj)){
 			tObj.trialDuration = 100;
 		}
 
-		//If it's not set, then set the delay between trial runs to 100ms
-		//default to 100ms to allow for GC and to make IE happy.
+		// If it's not set, then set the delay between trial runs to 100ms
+		// default to 100ms to allow for GC and to make IE happy.
 		if(!("trialDelay" in tObj)){
 			tObj.trialDelay = 100;
 		}
 
-		//If it's not set, then set number of times a trial is run to 10.
+		// If it's not set, then set number of times a trial is run to 10.
 		if(!("trialIterations" in tObj)){
 			tObj.trialIterations = 10;
 		}
@@ -317,12 +350,12 @@ var
 	createFixture= function(group, test, type){
 		// test is a function, string, or fixture object
 		var tObj = test;
-		if(dojo.isString(test)){
+		if(lang.isString(test)){
 			tObj = {
 				name: test.replace("/\s/g", "_"), // FIXME: bad escapement
 				runTest: new Function("t", test)
 			};
-		}else if(dojo.isFunction(test)){
+		}else if(lang.isFunction(test)){
 			// if we didn't get a fixture, wrap the function
 			tObj = { "runTest": test };
 			if(test["name"]){
@@ -339,7 +372,7 @@ var
 				}
 			}
 			// FIXME: try harder to get the test name here
-		}else if(dojo.isString(tObj.runTest)){
+		}else if(lang.isString(tObj.runTest)){
 			tObj.runTest= new Function("t", tObj.runTest);
 		}
 		if(!tObj.runTest){
@@ -361,7 +394,7 @@ var
 	},
 
 	dumpArg= function(arg){
-		if(dojo.isString(arg)){
+		if(lang.isString(arg)){
 			return "string(" + arg + ")";
 		} else {
 			return typeof arg;
@@ -372,21 +405,16 @@ var
 		var hint= "\targuments: ";
 		for(var i= 0; i<5; i++){
 			hint+= dumpArg(args[i]);
-		};
+		}
 		doh.debug("ERROR:");
 		if(testArgPosition){
-			doh.debug("\tillegal arguments provided to dojo.register; the test at argument " + testArgPosition + " wasn't a test.");
+			doh.debug("\tillegal arguments provided to doh.register; the test at argument " + testArgPosition + " wasn't a test.");
 		}else{
-			doh.debug("\tillegal arguments provided to dojo.register");
+			doh.debug("\tillegal arguments provided to doh.register");
 		}
 		doh.debug(hint);
-	},
-
-	isUrl= function(arg){
-		return dojo.isString(arg) && (/^url\:/.test(arg) || !/\(/.test(arg));
 	};
 
-
 doh._testRegistered = function(group, fixture){
 	// slot to be filled in
 };
@@ -421,10 +449,10 @@ doh._registerTest = function(group, test, type){
 
 	// get, possibly create, the group object
 
-	var groupObj= this._groups[group];
+	var groupObj = this._groups[group];
 	if(!groupObj){
 		this._groupCount++;
-		groupObj= this._groups[group] = [];
+		groupObj = this._groups[group] = [];
 		groupObj.inFlight = 0;
 	}
 	if(!test){
@@ -433,11 +461,11 @@ doh._registerTest = function(group, test, type){
 
 	// create the test fixture
 	var tObj;
-	if(dojo.isFunction(test) || dojo.isString(test) || "runTest" in test){
+	if(lang.isFunction(test) || lang.isString(test) || "runTest" in test){
 		return createFixture(group, test, type) ? groupObj : 0;
-	}else if(dojo.isArray(test)){
+	}else if(lang.isArray(test)){
 		// a vector of tests...
-		for(var i= 0; i<test.length; i++){
+		for(var i=0; i<test.length; i++){
 			tObj = createFixture(group, test[i], type);
 			if(!tObj){
 				this.debug("ERROR:");
@@ -449,12 +477,12 @@ doh._registerTest = function(group, test, type){
 	}else{
 		// a hash of tests...
 		for(var testName in test){
-			var theTest= test[testName];
-			if(dojo.isFunction(theTest) || dojo.isString(theTest)){
-				tObj = createFixture(group, {name:testName, runTest:theTest}, type);
+			var theTest = test[testName];
+			if(lang.isFunction(theTest) || lang.isString(theTest)){
+				tObj = createFixture(group, {name: testName, runTest: theTest}, type);
 			}else{
 				// should be an object
-				theTest.name= theTest.name || testName;
+				theTest.name = theTest.name || testName;
 				tObj = createFixture(group, theTest, type);
 			}
 			if(!tObj){
@@ -467,45 +495,45 @@ doh._registerTest = function(group, test, type){
 	}
 };
 
-doh._registerTestAndCheck= function(groupId, test, type, testArgPosition, args, setUp, tearDown){
-	var amdMid= 0;
+doh._registerTestAndCheck = function(groupId, test, type, testArgPosition, args, setUp, tearDown){
+	var amdMid = 0;
 	if(groupId){
 		if(type){
 			// explicitly provided type; therefore don't try to get type from groupId
-			var match= groupId.match(/([^\!]+)\!(.+)/);
+			var match = groupId.match(/([^\!]+)\!(.+)/);
 			if(match){
-				amdMid= match[1];
-				groupId= match[2];
+				amdMid = match[1];
+				groupId = match[2];
 			}
 		}else{
-			var parts= groupId && groupId.split("!");
-			if(parts.length==3){
-				amdMid= parts[0];
-				groupId= parts[1];
-				type= parts[2];
-			}else if(parts.length==2){
+			var parts = groupId && groupId.split("!");
+			if(parts.length == 3){
+				amdMid = parts[0];
+				groupId = parts[1];
+				type = parts[2];
+			}else if(parts.length == 2){
 				// either (amdMid, group) or (group, type)
 				if(parts[1] in doh._testTypes){
-					groupId= parts[0];
-					type= parts[1];
+					groupId = parts[0];
+					type = parts[1];
 				}else{
-					amdMid= parts[0];
-					groupId= parts[1];
+					amdMid = parts[0];
+					groupId = parts[1];
 				}
 			} // else, no ! and just a groupId
 		}
 	}
 
-	var group= doh._registerTest(groupId, test, type);
+	var group = doh._registerTest(groupId, test, type);
 	if(group){
 		if(amdMid){
-			group.amdMid= amdMid;
+			group.amdMid = amdMid;
 		}
 		if(setUp){
-			group.setUp= setUp;
+			group.setUp = setUp;
 		}
 		if(tearDown){
-			group.tearDown= tearDown;
+			group.tearDown = tearDown;
 		}
 	}else{
 		illegalRegister(arguments, testArgPosition);
@@ -518,10 +546,10 @@ doh._registerUrl = function(/*String*/ group, /*String*/ url, /*Integer*/ timeou
 	this.debug("\tNO registerUrl() METHOD AVAILABLE.");
 };
 
-var typeSigs= (function(){
+var typeSigs = (function(){
 	// Generate machinery to decode the many register signatures; these are the possible signatures.
 
-	var sigs= [
+	var sigs = [
 		// note: to===timeout, up===setUp, down===tearDown
 
 		// 1 arg
@@ -550,7 +578,7 @@ var typeSigs= (function(){
 		"url-type-args", function(args, a1, a2, a3){doh._registerUrl("ungrouped", a1, undefined, a2, a3);},
 
 		// 4 args
-		"group-test-type-up", function(args, a1, a2, a3, a4){doh._registerTestAndCheck(a1, a2, a3, 2, args, a3, 0);},
+		"group-test-type-up", function(args, a1, a2, a3, a4){doh._registerTestAndCheck(a1, a2, a3, 2, args, a4, 0);},
 		"group-test-up-down", function(args, a1, a2, a3, a4){doh._registerTestAndCheck(a1, a2, 0, 2, args, a3, a4);},
 		"test-type-up-down", function(args, a1, a2, a3, a4){doh._registerTestAndCheck("ungrouped", a1, 2, 0, args, a3, a4);},
 		"group-url-to-type", function(args, a1, a2, a3, a4){doh._registerUrl(a1, a2, a3, a4);},
@@ -560,7 +588,7 @@ var typeSigs= (function(){
 
 		// 5 args
 		"group-test-type-up-down", function(args, a1, a2, a3, a4, a5){doh._registerTestAndCheck(a1, a2, a3, 2, args, a4, a5);},
-		"group-url-to-type-args", function(args, a1, a2, a3, a4){doh._registerUrl(a1, a2, a3, a4, a5);}
+		"group-url-to-type-args", function(args, a1, a2, a3, a4, a5){doh._registerUrl(a1, a2, a3, a4, a5);}
 	];
 
 	// type-ids
@@ -572,7 +600,7 @@ var typeSigs= (function(){
 	// f - function
 	// n - number
     // see getTypeId inside doh.register
-	var argTypes= {
+	var argTypes = {
 		group:"st.sf.s",
 		test:"a.sf.o.f",
 		type:"st",
@@ -584,11 +612,11 @@ var typeSigs= (function(){
 	};
 	for(var p in argTypes){
 		argTypes[p]= argTypes[p].split(".");
-	};
+	}
 
 	function generateTypeSignature(sig, pattern, dest, func){
-		for(var nextPattern, reducedSig= sig.slice(1), typeList= argTypes[sig[0]], i= 0; i<typeList.length; i++){
-			nextPattern=  pattern + (pattern ? "-" : "") + typeList[i];
+		for(var nextPattern, reducedSig= sig.slice(1), typeList= argTypes[sig[0]], i=0; i<typeList.length; i++){
+			nextPattern =  pattern + (pattern ? "-" : "") + typeList[i];
 			if(reducedSig.length){
 				generateTypeSignature(reducedSig, nextPattern, dest, func);
 			}else{
@@ -597,11 +625,11 @@ var typeSigs= (function(){
 		}
 	}
 
-	var typeSigs= [];
-	for(var sig, func, dest, i= 0; i<sigs.length; i++){
-		sig= sigs[i++].split("-");
-		func= sigs[i];
-		dest= typeSigs[sig.length-1] || (typeSigs[sig.length-1]= []);
+	var typeSigs = [];
+	for(var sig, func, dest, i = 0; i<sigs.length; i++){
+		sig = sigs[i++].split("-");
+		func = sigs[i];
+		dest = typeSigs[sig.length-1] || (typeSigs[sig.length-1]= []);
 		generateTypeSignature(sig, "", dest, func);
 	}
 	return typeSigs;
@@ -612,7 +640,16 @@ doh.register = function(a1, a2, a3, a4, a5){
 	/*=====
 	doh.register = function(groupId, testOrTests, timeoutOrSetUp, tearDown){
 	// summary:
-	//	 Add a test or group of tests.
+	//		Add a test or group of tests.
+	// description:
+	//		Adds the test or tests given by testsOrUrl to the group given by group (if any). For URL tests, unless
+	//		a group is explicitly provided the group given by the URL until the document arrives at which
+	//		point the group is renamed to the title of the document. For non-URL tests, if groupId is
+	//		not provided, then tests are added to the group "ungrouped"; otherwise if the given groupId does not
+	//		exist, it is created; otherwise, tests are added to the already-existing group.
+	//
+	//		groupIds may contain embedded AMD module identifiers as prefixes and/or test types as suffixes. Prefixes
+	//		and suffixes are denoted by a "!". For example
 	// groupId: String?
 	//		The name of the group, optionally with an AMD module identifier prefix and/or
 	//		test type suffix. The value character set for group names and AMD module indentifiers
@@ -634,94 +671,85 @@ doh.register = function(a1, a2, a3, a4, a5){
 	// timeoutOrSetUp: integer||Function?
 	//		If tests is a URL, then must be an integer giving the number milliseconds to wait for the test
 	//		page to load before signaling an error; otherwise, a function for initializing the test group.
-	//      If a tearDown function is given, then a setup function must also be given.
+	//		If a tearDown function is given, then a setup function must also be given.
 	// tearDown: Function?
 	//		A function for deinitializing the test group.
-	// decription:
-	//	 Adds the test or tests given by testsOrUrl to the group given by group (if any). For URL tests, unless
-	//	 a group is explicitly provided the group given by the URL until the document arrives at which
-	//	 point the group is renamed to the title of the document. For non-URL tests, if groupId is
-	//	 not provided, then tests are added to the group "ungrouped"; otherwise if the given groupId does not
-	//	 exist, it is created; otherwise, tests are added to the already-existing group.
-	//
-	//	 groupIds may contain embedded AMD module identifiers as prefixes and/or test types as suffixes. Prefixes
-	//	 and suffixes are denoted by a "!". For example
 	// example:
-	// | `"myTest/MyGroup"`							 // just a group, group ids need not include a slash
-	// | `"myTest/MyGroup!perf"`					 // group with test type
-	// | `"path/to/amd/module!myTest/MyGroup"`		 // group with AMD module identifier
-	// | `"path/to/amd/module!myTest/MyGroup!perf"`	 // group with both AMD module identifier and test type
+	// | `"myTest/MyGroup"`							// just a group, group ids need not include a slash
+	// | `"myTest/MyGroup!perf"`					// group with test type
+	// | `"path/to/amd/module!myTest/MyGroup"`		// group with AMD module identifier
+	// | `"path/to/amd/module!myTest/MyGroup!perf"`	// group with both AMD module identifier and test type
 	//
-	//	 Groups associated with AMD module identifiers may be unloaded/reloaded if using an AMD loader with
-	//	 reload support (dojo's AMD loader includes such support). If no AMD module identifier is given,
-	//	 the loader supports reloading, and the user demands a reload, then the groupId will be used
-	//	 as the AMD module identifier.
+	//		Groups associated with AMD module identifiers may be unloaded/reloaded if using an AMD loader with
+	//		reload support (dojo's AMD loader includes such support). If no AMD module identifier is given,
+	//		the loader supports reloading, and the user demands a reload, then the groupId will be used
+	//		as the AMD module identifier.
 	//
-	//	 For URL tests, the groupId is changed to the document title (if any) upon document arrival. The
-	//	 title may include a test type suffix denoted with a "!" as described above.
+	//		For URL tests, the groupId is changed to the document title (if any) upon document arrival. The
+	//		title may include a test type suffix denoted with a "!" as described above.
 	//
-	//	 For URL tests, if timeout is a number, then sets the timeout for loading
-	//	 the particular URL; otherwise, timeout is set to DOH.iframeTimeout.
+	//		For URL tests, if timeout is a number, then sets the timeout for loading
+	//		the particular URL; otherwise, timeout is set to DOH.iframeTimeout.
 	//
-	//	 For non-URL tests, if setUp and/or tearDown are provided, then any previous setUp and/or
-	//	 tearDown functions for the group are replaced as given. You may affect just setUp and/or tearDown
-	//	 for a group and not provide/add any tests by providing falsy for the test argument.
+	//		For non-URL tests, if setUp and/or tearDown are provided, then any previous setUp and/or
+	//		tearDown functions for the group are replaced as given. You may affect just setUp and/or tearDown
+	//		for a group and not provide/add any tests by providing falsy for the test argument.
 	// example:
 	// | var
-	// |	 t1= function(t) {
-	// |		 // this is a test
-	// |		 // t will be set to DOH when the test is executed by DOH
-	// |		 // etc.
-	// |	 },
+	// |	t1= function(t) {
+	// |		// this is a test
+	// |		// t will be set to DOH when the test is executed by DOH
+	// |		// etc.
+	// |	},
 	// |
-	// |	 t2= {
-	// |		 // this is a test fixture and may be passed as a test
+	// |	t2= {
+	// |		// this is a test fixture and may be passed as a test
 	// |
-	// |		 // runTest is always required...
-	// |		 runTest:function(t){
-	// |			 //the test...
-	// |		 },
+	// |		// runTest is always required...
+	// |		runTest: function(t){
+	// |			// the test...
+	// |		},
 	// |
-	// |		 // name is optional, but recommended...
-	// |		 name:"myTest",
+	// |		// name is optional, but recommended...
+	// |		name:"myTest",
 	// |
-	// |		 // preamble is optional...
-	// |		 setUp:function(){
-	// |			 // will be executed by DOH prior to executing the test
-	// |		 },
+	// |		// preamble is optional...
+	// |		setUp: function(){
+	// |			// will be executed by DOH prior to executing the test
+	// |		},
 	// |
-	// |		 // postscript is optional...
-	// |		 tearDown:function(){ //op
-	// |			 // will be executed by DOH after executing the test
-	// |		 }
-	// |	 }
+	// |		// postscript is optional...
+	// |		tearDown: function(){ // op
+	// |			// will be executed by DOH after executing the test
+	// |		}
+	// |	}
 	// |
-	// |	 t3= [
-	// |		 // this is a vector of tests...
-	// |		 t1, t2
-	// |	 ],
+	// |	t3= [
+	// |		// this is a vector of tests...
+	// |		t1, t2
+	// |	],
 	// |
-	// |	 t4= {
-	// |		 // this is a map from test name to test or test fixture
-	// |		 t5:function(t){
-	// |			 //etc.
-	// |		 },
+	// |	t4= {
+	// |		// this is a map from test name to test or test fixture
+	// |		t5: function(t){
+	// |			// etc.
+	// |		},
 	// |
-	// |		 t6:{
-	// |			 runTest:function(t){
-	// |				//etc.
-	// |			 }
-	// |			 // name will be automatically added as "t6"
-	// |		 }
-	// |	 },
+	// |		t6: {
+	// |			runTest: function(t){
+	// |			// etc.
+	// |			}
+	// |			// name will be automatically added as "t6"
+	// |		}
+	// |	},
 	// |
-	// |	 aSetup:function(){
-	// |		 // etc.
-	// |	 },
+	// |	aSetup: function(){
+	// |		// etc.
+	// |	},
 	// |
-	// |	 aTearDown:function(){
-	// |		 // etc.
-	// |	 };
+	// |	aTearDown: function(){
+	// |		// etc.
+	// |	};
 	// | // (test); note, can't provide setup/tearDown without a group
 	// | doh.register(t1);
 	// |
@@ -743,8 +771,8 @@ doh.register = function(a1, a2, a3, a4, a5){
 	// | // add a perf test with an AMD module identifier
 	// | doh.register("path/to/my/module!myGroup!perf", t1);
 	//
-	//	 doh.register also supports Dojo, v1.6- signature (group, test, type), although this signature is deprecated.
-	}
+	//	doh.register also supports Dojo, v1.6- signature (group, test, type), although this signature is deprecated.
+	};
 	=====*/
 
 	function getTypeId(a){
@@ -768,15 +796,15 @@ doh.register = function(a1, a2, a3, a4, a5){
 	}
 
 	var
-		arity= arguments.length,
-		search= typeSigs[arity-1],
-		sig= [],
+		arity = arguments.length,
+		search = typeSigs[arity-1],
+		sig = [],
 		i;
-	for(i= 0; i<arity; i++){
+	for(i =0; i<arity; i++){
 		sig.push(getTypeId(arguments[i]));
 	}
-	sig= sig.join("-");
-	for(i= 0; i<search.length; i+= 2){
+	sig = sig.join("-");
+	for(i=0; i<search.length; i+= 2){
 		if(search[i]==sig){
 			search[i+1](arguments, a1, a2, a3, a4, a5);
 			return;
@@ -786,10 +814,10 @@ doh.register = function(a1, a2, a3, a4, a5){
 };
 
 doh.registerDocTests = function(module){
-	//	summary:
-	//		Get all the doctests from the given module and register each of them
-	//		as a single test case here.
-	//
+	// summary:
+	//		Deprecated.    Won't work unless you manually load dojox.testing.DocTest, and likely not even then.
+	//		Gets all the doctests from the given module and register each of them as a single test case here.
+
 	var docTest = new dojox.testing.DocTest();
 	var docTests = docTest.getTests(module);
 	var len = docTests.length;
@@ -800,7 +828,7 @@ doh.registerDocTests = function(module){
 		var comment = "";
 		if (test.commands.length && test.commands[0].indexOf("//")!=-1) {
 			var parts = test.commands[0].split("//");
-			comment = ", "+parts[parts.length-1]; // Get all after the last //, so we dont get trapped by http:// or alikes :-).
+			comment = ", "+parts[parts.length-1]; // Get all after the last //, so we don't get trapped by http:// or alikes :-).
 		}
 		tests.push({
 			runTest: (function(test){
@@ -817,39 +845,39 @@ doh.registerDocTests = function(module){
 };
 
 //
-// depricated v1.6- register API follows
+// deprecated v1.6- register API follows
 //
 
 doh.registerTest = function(/*String*/ group, /*Array||Function||Object*/ test, /*String*/ type){
 	// summary:
-	//		Deprecated.	 Use doh.register(group/type, test) instead
+	//		Deprecated.  Use doh.register(group/type, test) instead
 	doh.register(group + (type ? "!" + type : ""), test);
 };
 
 doh.registerGroup = function(/*String*/ group, /*Array||Function||Object*/ tests, /*Function*/ setUp, /*Function*/ tearDown, /*String*/ type){
 	// summary:
-	//		Deprecated.	 Use doh.register(group/type, tests, setUp, tearDown) instead
-	var args= [(group ? group : "") + (type ? "!" + type : ""), tests];
+	//		Deprecated.  Use doh.register(group/type, tests, setUp, tearDown) instead
+	var args = [(group ? group : "") + (type ? "!" + type : ""), tests];
 	setUp && args.push(setUp);
 	tearDown && args.push(tearDown);
 	doh.register.apply(doh, args);
-}
+};
 
 doh.registerTestNs = function(/*String*/ group, /*Object*/ ns){
 	// summary:
-	//		Deprecated.	 Use doh.register(group, ns) instead
+	//		Deprecated.  Use doh.register(group, ns) instead
 	doh.register(group, ns);
 };
 
 doh.registerTests = function(/*String*/ group, /*Array*/ testArr, /*String*/ type){
 	// summary:
-	//		Deprecated.	 Use doh.register(group/type, testArr) instead
+	//		Deprecated.  Use doh.register(group/type, testArr) instead
 	doh.register(group + (type ? "!" + type : ""), testArr);
-}
+};
 
 doh.registerUrl = function(/*String*/ group, /*String*/ url, /*Integer*/ timeout, /*String*/ type, /*Object*/ args){
 	// summary:
-	//		Deprecated.	 Use doh.register(group/type, url, timeout) instead
+	//		Deprecated.  Use doh.register(group/type, url, timeout) instead
 	doh.register(group + (type ? "!" + type : ""), url+"", timeout || 10000, args || {});
 };
 
@@ -862,7 +890,7 @@ doh.t = doh.assertTrue = function(/*Object*/ condition, /*String?*/ hint){
 	if(arguments.length < 1){
 		throw new doh._AssertFailure("assertTrue failed because it was not passed at least 1 argument");
 	}
-	//if(dojo.isString(condition) && condition.length){
+	//if(lang.isString(condition) && condition.length){
 	//	return true;
 	//}
 	if(!eval(condition)){
@@ -882,9 +910,9 @@ doh.f = doh.assertFalse = function(/*Object*/ condition, /*String?*/ hint){
 };
 
 doh.e = doh.assertError = function(/*Error object*/expectedError, /*Object*/scope, /*String*/functionName, /*Array*/args, /*String?*/ hint){
-	//	summary:
+	// summary:
 	//		Test for a certain error to be thrown by the given function.
-	//	example:
+	// example:
 	//		t.assertError(dojox.data.QueryReadStore.InvalidAttributeError, store, "getValue", [item, "NOT THERE"]);
 	//		t.assertError(dojox.data.QueryReadStore.InvalidItemError, store, "getValue", ["not an item", "NOT THERE"]);
 	try{
@@ -918,7 +946,7 @@ doh.is = doh.assertEqual = function(/*Object*/ expected, /*Object*/ actual, /*St
 
 		return true;
 	}
-	if( (this.isArray(expected) && this.isArray(actual))&&
+	if( (lang.isArray(expected) && lang.isArray(actual))&&
 		(this._arrayEq(expected, actual)) ){
 		return true;
 	}
@@ -948,7 +976,7 @@ doh.isNot = doh.assertNotEqual = function(/*Object*/ notExpected, /*Object*/ act
 	if((notExpected === actual)||(notExpected == actual)){
 				throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
 	}
-	if( (this.isArray(notExpected) && this.isArray(actual))&&
+	if( (lang.isArray(notExpected) && lang.isArray(actual))&&
 		(this._arrayEq(notExpected, actual)) ){
 		throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
 	}
@@ -958,7 +986,7 @@ doh.isNot = doh.assertNotEqual = function(/*Object*/ notExpected, /*Object*/ act
 			isequal = this._objPropEq(notExpected, actual);
 		}catch(e){
 			if(!(e instanceof doh._AssertFailure)){
-				throw e; //other exceptions, just throw it
+				throw e; // other exceptions, just throw it
 			}
 		}
 		if(isequal){
@@ -992,12 +1020,15 @@ doh._objPropEq = function(expected, actual){
 	var x;
 	// Make sure ALL THE SAME properties are in both objects!
 	for(x in actual){ // Lets check "actual" here, expected is checked below.
-		if(expected[x] === undefined){
+		if(!(x in expected)){
 			return false;
 		}
-	};
+	}
 
 	for(x in expected){
+		if(!(x in actual)){
+			return false;
+		}
 		if(!doh.assertEqual(expected[x], actual[x], 0, true)){
 			return false;
 		}
@@ -1044,199 +1075,206 @@ doh._handleFailure = function(groupName, fixture, e){
 	}
 };
 
-doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
-	//	summary:
+doh._runPerfFixture = function(/*String*/ groupName, /*Object*/ fixture){
+	// summary:
 	//		This function handles how to execute a 'performance' test
-	//		which is different from a straight UT style test.	 These
+	//		which is different from a straight UT style test.  These
 	//		will often do numerous iterations of the same operation and
 	//		gather execution statistics about it, like max, min, average,
 	//		etc.	It makes use of the already in place DOH deferred test
-	//		handling since it is a good idea to put a pause inbetween each
+	//		handling since it is a good idea to put a pause in between each
 	//		iteration to allow for GC cleanup and the like.
-	//
-	//	groupName:
+	// groupName:
 	//		The test group that contains this performance test.
-	//	fixture:
+	// fixture:
 	//		The performance test fixture.
 	var tg = this._groups[groupName];
 	fixture.startTime = new Date();
 
-	//Perf tests always need to act in an async manner as there is a
-	//number of iterations to flow through.
+	// Perf tests always need to act in an async manner as there is a
+	// number of iterations to flow through.
 	var def = new doh.Deferred();
 	tg.inFlight++;
 	def.groupName = groupName;
 	def.fixture = fixture;
 
-	def.addErrback(function(err){
+	var threw = false;
+	def.otherwise(function(err){
 		doh._handleFailure(groupName, fixture, err);
+		threw = true;
 	});
 
-	//Set up the finalizer.
+	// Set up the finalizer.
+	var fulfilled;
 	var retEnd = function(){
+		fulfilled = true;
 		if(fixture["tearDown"]){ fixture.tearDown(doh); }
 		tg.inFlight--;
 		if((!tg.inFlight)&&(tg.iterated)){
 			doh._groupFinished(groupName, !tg.failures);
 		}
-		doh._testFinished(groupName, fixture, def.results[0]);
+		doh._testFinished(groupName, fixture, !threw);
 		if(doh._paused){
 			doh.run();
 		}
 	};
 
-	//Since these can take who knows how long, we don't want to timeout
-	//unless explicitly set
+	// Since these can take who knows how long, we don't want to timeout
+	// unless explicitly set
 	var timer;
 	var to = fixture.timeout;
 	if(to > 0) {
 		timer = setTimeout(function(){
-			// ret.cancel();
-			// retEnd();
-			def.errback(new Error("test timeout in "+fixture.name.toString()));
+			def.reject(new Error("test timeout in "+fixture.name.toString()));
 		}, to);
 	}
 
-	//Set up the end calls to the test into the deferred we'll return.
-	def.addBoth(function(arg){
+	// Set up the end calls to the test into the deferred we'll return.
+	def.always(function(){
 		if(timer){
 			clearTimeout(timer);
 		}
 		retEnd();
 	});
 
-	//Okay, now set up the timing loop for the actual test.
-	//This is down as an async type test where there is a delay
-	//between each execution to allow for GC time, etc, so the GC
-	//has less impact on the tests.
+	// Okay, now set up the timing loop for the actual test.
+	// This is down as an async type test where there is a delay
+	// between each execution to allow for GC time, etc, so the GC
+	// has less impact on the tests.
 	var res = fixture.results;
 	res.trials = [];
 
-	//Try to figure out how many calls are needed to hit a particular threshold.
+	// Try to figure out how many calls are needed to hit a particular threshold.
 	var itrDef = doh._calcTrialIterations(groupName, fixture);
-	itrDef.addErrback(function(err){
-		fixture.endTime = new Date();
-		def.errback(err);
-	});
 
-	//Blah, since tests can be deferred, the actual run has to be deferred until after
-	//we know how many iterations to run.	 This is just plain ugly.
-	itrDef.addCallback(function(iterations){
-		if(iterations){
-			var countdown = fixture.trialIterations;
-			doh.debug("TIMING TEST: [" + fixture.name +
-						"]\n\t\tITERATIONS PER TRIAL: " +
-						iterations + "\n\tTRIALS: " +
-						countdown);
-
-			//Figure out how many times we want to run our 'trial'.
-			//Where each trial consists of 'iterations' of the test.
-
-			var trialRunner = function() {
-				//Set up our function to execute a block of tests
-				var start = new Date();
-				var tTimer = new doh.Deferred();
-				var tCountdown = iterations;
-
-				var tState = {
-					countdown: iterations
-				};
-				var testRunner = function(state){
-					while(state){
-						try{
-							state.countdown--;
-							if(state.countdown){
-								var ret = fixture.runTest(doh);
-								if(ret && ret.addCallback){
-									//Deferreds have to be handled async,
-									//otherwise we just keep looping.
-									var atState = {
-										countdown: state.countdown
-									};
-									ret.addCallback(function(){
-										testRunner(atState);
-									});
-									ret.addErrback(function(err) {
-										doh._handleFailure(groupName, fixture, err);
-										fixture.endTime = new Date();
-										def.errback(err);
-									});
+	// Blah, since tests can be deferred, the actual run has to be deferred until after
+	// we know how many iterations to run.  This is just plain ugly.
+	itrDef.then(
+		function(iterations){
+			if(iterations){
+				var countdown = fixture.trialIterations;
+				doh.debug("TIMING TEST: [" + fixture.name +
+							"]\n\t\tITERATIONS PER TRIAL: " +
+							iterations + "\n\tTRIALS: " +
+							countdown);
+
+				// Figure out how many times we want to run our 'trial'.
+				// Where each trial consists of 'iterations' of the test.
+
+				var trialRunner = function() {
+					// Set up our function to execute a block of tests
+					var start = new Date();
+					var tTimer = new doh.Deferred();
+
+					var tState = {
+						countdown: iterations
+					};
+					var testRunner = function(state){
+						while(state){
+							try{
+								state.countdown--;
+								if(state.countdown){
+									var ret = fixture.runTest(doh);
+									if(ret && ret.then){
+										// Deferreds have to be handled async,
+										// otherwise we just keep looping.
+										var atState = {
+											countdown: state.countdown
+										};
+										ret.then(
+											function(){
+												testRunner(atState)
+											},
+											function(err){
+												doh._handleFailure(groupName, fixture, err);
+												fixture.endTime = new Date();
+												def.reject(err);
+											}
+										);
+										state = null;
+									}
+								}else{
+									tTimer.resolve(new Date());
 									state = null;
 								}
-							}else{
-								tTimer.callback(new Date());
-								state = null;
+							}catch(err){
+								fixture.endTime = new Date();
+								tTimer.reject(err);
 							}
-						}catch(err){
-							fixture.endTime = new Date();
-							tTimer.errback(err);
 						}
-					}
-				};
-				tTimer.addCallback(function(end){
-					//Figure out the results and try to factor out function call costs.
-					var tResults = {
-						trial: (fixture.trialIterations - countdown),
-						testIterations: iterations,
-						executionTime: (end.getTime() - start.getTime()),
-						average: (end.getTime() - start.getTime())/iterations
 					};
-					res.trials.push(tResults);
-					doh.debug("\n\t\tTRIAL #: " +
-								tResults.trial + "\n\tTIME: " +
-								tResults.executionTime + "ms.\n\tAVG TEST TIME: " +
-								(tResults.executionTime/tResults.testIterations) + "ms.");
-
-					//Okay, have we run all the trials yet?
-					countdown--;
-					if(countdown){
-						setTimeout(trialRunner, fixture.trialDelay);
-					}else{
-						//Okay, we're done, lets compute some final performance results.
-						var t = res.trials;
+					tTimer.then(
+						function(end){
+							// Figure out the results and try to factor out function call costs.
+							var tResults = {
+								trial: (fixture.trialIterations - countdown),
+								testIterations: iterations,
+								executionTime: (end.getTime() - start.getTime()),
+								average: (end.getTime() - start.getTime())/iterations
+							};
+							res.trials.push(tResults);
+							doh.debug("\n\t\tTRIAL #: " +
+										tResults.trial + "\n\tTIME: " +
+										tResults.executionTime + "ms.\n\tAVG TEST TIME: " +
+										(tResults.executionTime/tResults.testIterations) + "ms.");
+
+							// Okay, have we run all the trials yet?
+							countdown--;
+							if(countdown){
+								setTimeout(trialRunner, fixture.trialDelay);
+							}else{
+								// Okay, we're done, let's compute some final performance results.
+								var t = res.trials;
 
+								// We're done.
+								fixture.endTime = new Date();
+								def.resolve(true);
+							}
+						},
 
+						// Handler if tTimer gets an error
+						function(err){
+							fixture.endTime = new Date();
+							def.reject(err);
+						}
+					);
+					testRunner(tState);
+				};
+				trialRunner();
+			}
+		},
 
-						//We're done.
-						fixture.endTime = new Date();
-						def.callback(true);
-					}
-				});
-				tTimer.addErrback(function(err){
-					fixture.endTime = new Date();
-					def.errback(err);
-				});
-				testRunner(tState);
-			};
-			trialRunner();
+		// Handler if itrDef gets an error
+		function(err){
+			fixture.endTime = new Date();
+			def.reject(err);
 		}
-	});
+	);
 
-	//Set for a pause, returned the deferred.
-	if(def.fired < 0){
+	// Set for a pause, returned the deferred.
+	if(!fulfilled){
 		doh.pause();
 	}
 	return def;
 };
 
 doh._calcTrialIterations =	function(/*String*/ groupName, /*Object*/ fixture){
-	//	summary:
+	// summary:
 	//		This function determines the rough number of iterations to
-	//		use to reach a particular MS threshold.	 This returns a deferred
-	//		since tests can theoretically by async.	 Async tests aren't going to
+	//		use to reach a particular MS threshold.  This returns a deferred
+	//		since tests can theoretically by async.  Async tests aren't going to
 	//		give great perf #s, though.
 	//		The callback is passed the # of iterations to hit the requested
 	//		threshold.
-	//
-	//	fixture:
+	// fixture:
 	//		The test fixture we want to calculate iterations for.
 	var def = new doh.Deferred();
 	var calibrate = function () {
-		var testFunc = doh.hitch(fixture, fixture.runTest);
+		var testFunc = lang.hitch(fixture, fixture.runTest);
 
-		//Set the initial state.	We have to do this as a loop instead
-		//of a recursive function.	Otherwise, it blows the call stack
-		//on some browsers.
+		// Set the initial state.	We have to do this as a loop instead
+		// of a recursive function.	Otherwise, it blows the call stack
+		// on some browsers.
 		var iState = {
 			start: new Date(),
 			curIter: 0,
@@ -1247,26 +1285,28 @@ doh._calcTrialIterations =	function(/*String*/ groupName, /*Object*/ fixture){
 				if(state.curIter < state.iterations){
 					try{
 						var ret = testFunc(doh);
-						if(ret && ret.addCallback){
+						if(ret && ret.then){
 							var aState = {
 								start: state.start,
 								curIter: state.curIter + 1,
 								iterations: state.iterations
 							};
-							ret.addCallback(function(){
-								handleIteration(aState);
-							});
-							ret.addErrback(function(err) {
-								fixture.endTime = new Date();
-								def.errback(err);
-							});
+							ret.then(
+								function(){
+									handleIteration(aState);
+								},
+								function(err) {
+									fixture.endTime = new Date();
+									def.reject(err);
+								}
+							);
 							state = null;
 						}else{
 							state.curIter++;
 						}
 					}catch(err){
 						fixture.endTime = new Date();
-						def.errback(err);
+						def.reject(err);
 						return;
 					}
 				}else{
@@ -1284,7 +1324,7 @@ doh._calcTrialIterations =	function(/*String*/ groupName, /*Object*/ fixture){
 						}, 50);
 					}else{
 						var itrs = state.iterations;
-						setTimeout(function(){def.callback(itrs)}, 50);
+						setTimeout(function(){def.resolve(itrs)}, 50);
 						state = null;
 					}
 				}
@@ -1296,61 +1336,103 @@ doh._calcTrialIterations =	function(/*String*/ groupName, /*Object*/ fixture){
 	return def;
 };
 
-doh._runRegFixture = function(/*String*/groupName, /*Object*/fixture){
-	//	summary:
-	//		Function to run a generic doh test.	 These are not
+doh._runRegFixture = function(/*String*/ groupName, /*Object*/ fixture){
+	// summary:
+	//		Function to help run a generic doh test.  Called from _runFixture().  These are not
 	//		specialized tests, like performance groups and such.
-	//
-	//	groupName:
+	// groupName:
 	//		The groupName of the test.
-	//	fixture:
+	// fixture:
 	//		The test fixture to execute.
+
 	var tg = this._groups[groupName];
+
 	fixture.startTime = new Date();
+
 	var ret = fixture.runTest(this);
-	fixture.endTime = new Date();
+
 	// if we get a deferred back from the test runner, we know we're
 	// gonna wait for an async result. It's up to the test code to trap
 	// errors and give us an errback or callback.
-	if(ret && ret.addCallback){
+	if(ret && ret.then){
+
+		// If ret is a dojo/Deferred, get the corresponding Promise; it has some additional methods we need.
+		if(ret.promise){
+			ret = ret.promise;
+		}
+
 		tg.inFlight++;
 		ret.groupName = groupName;
 		ret.fixture = fixture;
 
-		ret.addErrback(function(err){
+		// Setup handler for when test fails.
+		var threw = false;
+		ret.otherwise(function(err){
+			if(threw){
+				// the fixture timeout (below) must have already fired
+				return;
+			}
 			doh._handleFailure(groupName, fixture, err);
+			threw = true;
 		});
 
+		var fulfilled;
 		var retEnd = function(){
+			// summary:
+			//		Called when tests finishes successfully, fails, or times out
 
-			if(fixture["tearDown"]){ fixture.tearDown(doh); }
+			if(fulfilled){
+				// retEnd() has already executed; probably the timeout above fired and then later ret completed.
+				return;
+			}
+			fulfilled = true;
+
+			fixture.endTime = new Date();
+
+			if(fixture.tearDown){
+				try {
+					fixture.tearDown(doh);
+				}catch(e){
+					this.debug("Error tearing down test: "+e.message);
+				}
+			}
 			tg.inFlight--;
-			doh._testFinished(groupName, fixture, ret.results[0]);
+			doh._testFinished(groupName, fixture, !threw);
+
 			if((!tg.inFlight)&&(tg.iterated)){
 				doh._groupFinished(groupName, !tg.failures);
 			}
+
+			// Go on to next test
 			if(doh._paused){
 				doh.run();
 			}
 		};
 
-		var timeoutFunction = function(){
-			fixture.endTime = new Date();
-			ret.errback(new Error("test timeout in "+fixture.name.toString()));
-		};
-
-		var timer = setTimeout(function(){ timeoutFunction(); }, fixture["timeout"]||1000);
+		var timer = setTimeout(function(){
+			if(!timer){
+				// we already called clearTimeout(), but it fired anyway, due to IE bug; just ignore.
+				return;
+			}
+			// Note: cannot call ret.reject() because ret may be a readonly promise
+			doh._handleFailure(groupName, fixture, new Error("test timeout in " + fixture.name.toString()));
+			threw = true;
+			retEnd();
+		}, fixture["timeout"]||1000);
 
-		ret.addBoth(function(arg){
-			timeoutFunction = function(){}; // in IE8, the clearTimeout does not always stop the timer, so clear the function as well
+		ret.always(function(){
 			clearTimeout(timer);
-			fixture.endTime = new Date();
+			timer = null;
 			retEnd();
 		});
-		if(ret.fired < 0){
+
+		if(!fulfilled){
 			doh.pause();
 		}
+
 		return ret;
+	}else{
+		// Synchronous test; tearDown etc. handled in _runFixture(), the function that called me
 	}
 };
 
@@ -1367,28 +1449,38 @@ doh._runFixture = function(groupName, fixture){
 		// only execute the parts of the fixture we've got
 
 		if(fixture["setUp"]){ fixture.setUp(this); }
-		if(fixture["runTest"]){	 // should we error out of a fixture doesn't have a runTest?
+		if(fixture["runTest"]){		// should we error out of a fixture doesn't have a runTest?
 			if(fixture.testType === "perf"){
-				//Always async deferred, so return it.
+				// Always async deferred, so return it.
 				return doh._runPerfFixture(groupName, fixture);
 			}else{
-				//May or may not by async.
+				// May or may not by async.
 				var ret = doh._runRegFixture(groupName, fixture);
 				if(ret){
+					// this design is ridiculous, but tearDown etc. is handled in _runRegFixture iff fixture is async;
+					// likewise with runPerfFixture
 					return ret;
 				}
 			}
 		}
-		if(fixture["tearDown"]){ fixture.tearDown(this); }
 	}catch(e){
 		threw = true;
 		err = e;
-		if(!fixture.endTime){
-			fixture.endTime = new Date();
-		}
 	}
+
+	// The rest of the code in this function executes only if test returns synchronously...
+
+	fixture.endTime = new Date();
+
+	// should try to tear down regardless whether test passed or failed...
+	try{
+		if(fixture["tearDown"]){ fixture.tearDown(this); }
+	}catch(e){
+		this.debug("Error tearing down test: "+e.message);
+	}
+
 	var d = new doh.Deferred();
-	setTimeout(this.hitch(this, function(){
+	setTimeout(lang.hitch(this, function(){
 		if(threw){
 			this._handleFailure(groupName, fixture, err);
 		}
@@ -1397,7 +1489,7 @@ doh._runFixture = function(groupName, fixture){
 		if((!tg.inFlight)&&(tg.iterated)){
 			doh._groupFinished(groupName, !tg.failures);
 		}else if(tg.inFlight > 0){
-			setTimeout(this.hitch(this, function(){
+			setTimeout(lang.hitch(this, function(){
 				doh.runGroup(groupName);
 			}), 100);
 			this._paused = true;
@@ -1423,10 +1515,10 @@ doh.runGroup = function(/*String*/ groupName, /*Integer*/ idx){
 
 	// FIXME: need to make fixture execution async!!
 
-	idx= idx || 0;
+	idx = idx || 0;
 	var tg = this._groups[groupName];
 	if(tg.skip === true){ return; }
-	if(this.isArray(tg)){
+	if(lang.isArray(tg)){
 		if(tg.iterated===undefined){
 			tg.iterated = false;
 			tg.inFlight = 0;
@@ -1443,7 +1535,7 @@ doh.runGroup = function(/*String*/ groupName, /*Integer*/ idx){
 			doh._runFixture(groupName, tg[y]);
 			if(this._paused){
 				this._currentTest = y+1;
-				if(this._currentTest == tg.length){ //RCG--don't think we need this; the next time through it will be taken care of
+				if(this._currentTest == tg.length){ // RCG--don't think we need this; the next time through it will be taken care of
 					tg.iterated = true;
 				}
 				// this.debug("PAUSED at:", tg[y].name, this._currentGroup, this._currentTest);
@@ -1490,7 +1582,7 @@ doh.pause = function(){
 doh.run = function(){
 	// summary:
 	//		begins or resumes the test process.
-	// this.debug("STARTING");
+	
 	this._paused = false;
 	var cg = this._currentGroup;
 	var ct = this._currentTest;
@@ -1524,7 +1616,9 @@ doh.run = function(){
 };
 
 doh.runOnLoad = function(){
-	dojo.ready(doh, "run");
+	require(["dojo/ready"], function(ready){
+		ready(doh, "run");
+	});
 };
 
 return doh;
@@ -1534,6 +1628,7 @@ return doh;
 // backcompat hack: if in the browser, then loading doh/runner implies loading doh/_browserRunner. This is the
 // behavior of 1.6- and is leveraged on many test documents that dojo.require("doh.runner"). Note that this
 // hack will only work in synchronous mode; but if you're not in synchronous mode, you don't care about this.
+// Remove for 2.0.
 if (typeof window!="undefined" && typeof location!="undefined" && typeof document!="undefined" && window.location==location && window.document==document) {
 	require(["doh/_browserRunner"]);
 }
diff --git a/util/doh/tests/robot.html b/util/doh/tests/robot.html
index 4b7f932..7d5184b 100644
--- a/util/doh/tests/robot.html
+++ b/util/doh/tests/robot.html
@@ -3,78 +3,68 @@
 	<style>
 		@import "../robot/robot.css";
 	</style>
-	<script src="../runner.js"></script>
-	<script src="../robot.js"></script>
+	<script src="../../../dojo/dojo.js" data-dojo-config="isDebug: true, async: true"></script>
+	<script>
+		require(["doh/runner", "doh/robot", "dojo/domReady!"], function(doh, robot){
+			var textbox = document.getElementById('textbox');
+			var BACKSPACE = 8;
+			var END = 35;
+			var LEFT_ARROW = 37;
+			var SHIFT = 16;
+
+			doh.register("robot", [
+				{
+					name: "dojorobot1",
+					timeout: 6900,
+					setUp: function(){
+						textbox.value="hi";
+					},
+					runTest: function(){
+						var d = new doh.Deferred();
+						robot.mouseMove(30, 30, 500);
+						robot.mouseClick({left: true}, 500);
+						robot.typeKeys(" again", 500, 2500);
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("hi again", document.getElementById('textbox').value);
+						}), 900);
+						return d;
+					}
+				},
+				{
+					name: "shiftarrow",
+					timeout: 10000,
+					setUp: function(){
+						textbox.value="hi again";
+					},
+					runTest: function(){
+						var d = new doh.Deferred();
+						robot.keyPress(END,500);
+						// test shift+arrow with keyPress
+						for(var i=0; i<3; i++){
+							robot.keyPress(LEFT_ARROW, 500, {shift: true});
+						}
+						// test shift+arrow with keyDown then keyUp
+						robot.keyDown(SHIFT,500);
+						for(var i=0; i<3; i++){
+							robot.keyDown(LEFT_ARROW,500);
+							robot.keyUp(LEFT_ARROW,20);
+						}
+						robot.keyUp(SHIFT,500);
+						robot.keyPress(BACKSPACE,500);
+						robot.sequence(d.getTestCallback(function(){
+							doh.is("hi", textbox.value);
+						}), 900);
+						return d;
+					}
+				}
+			]);
+			doh.run();
+		});
+	</script>
 </head>
 <body>
-<form>
-<input type="text" value="hi" id="textbox" style="position:absolute; left:0px; top:20px; font-family:system;"></input>
-</form>
-<script>
-var textbox=document.getElementById('textbox');
-var BACKSPACE=8;
-var END=35;
-var LEFT_ARROW=37;
-var SHIFT=16;
-doh.register("doh.robot",[
-{
-	name:"dojorobot1",
-	timeout:6900,
-	setUp:function(){
-		textbox.value="hi";
-	},
-	runTest:function(){
-		var d=new doh.Deferred();
-		doh.robot.mouseMove(30, 30, 500);
-		doh.robot.mouseClick({left:true}, 500);
-		doh.robot.typeKeys(" again", 500, 2500);
-		doh.robot.sequence(function(){
-			if(textbox.value=="hi again"){
-				textbox.value += ": passed";
-				d.callback(true);
-			}else{
-				textbox.value += ": failed";
-				d.errback(new Error("Expected value 'hi again', got "+textbox.value));
-			}
-		}, 900);
-		return d;
-	}
-},
-{
-	name:"shiftarrow",
-	timeout:10000,
-	setUp:function(){
-		textbox.value="hi again";
-	},
-	runTest:function(){
-		var d=new doh.Deferred();
-		doh.robot.keyPress(END,500);
-		// test shift+arrow with keyPress
-		for(var i=0; i<3; i++){
-			doh.robot.keyPress(LEFT_ARROW,500,{shift:true});
-		}
-		// test shift+arrow with keyDown then keyUp
-		doh.robot.keyDown(SHIFT,500);
-		for(var i=0; i<3; i++){
-			doh.robot.keyDown(LEFT_ARROW,500);
-			doh.robot.keyUp(LEFT_ARROW,20);
-		}
-		doh.robot.keyUp(SHIFT,500);
-		doh.robot.keyPress(BACKSPACE,500);
-		doh.robot.sequence(function(){
-			if(textbox.value=="hi"){
-				textbox.value += ": passed";
-				d.callback(true);
-			}else{
-				textbox.value += ": failed";
-				d.errback(new Error("Expected value 'hi', got "+textbox.value));
-			}
-		}, 900);
-		return d;
-	}
-}
-]);
-doh.run();
-</script>
+	<form>
+	<input type="text" value="hi" id="textbox" style="position:absolute; left:0px; top:20px; font-family:system;"></input>
+	</form>
 </body>
 </html>
diff --git a/util/doh/tests/selfTest.js b/util/doh/tests/selfTest.js
index 5c6fbcd..4f83c66 100644
--- a/util/doh/tests/selfTest.js
+++ b/util/doh/tests/selfTest.js
@@ -205,7 +205,7 @@ define(["doh/runner"], function(doh) {
 	});
 	// a stone-stupid async test
 	doh.register("doh/async", [{
-		name: "deferredSuccess",
+		name: "doh.Deferred success",
 		runTest: function(t){
 			var d = new doh.Deferred();
 			setTimeout(d.getTestCallback(function(){
@@ -215,22 +215,52 @@ define(["doh/runner"], function(doh) {
 			return d;
 		}
 	},{
-		name: "deferredFailure--SHOULD FAIL",
+		name: "dojo.Deferred success",
+		runTest: function(t){
+			var d = new dojo.Deferred();
+			setTimeout(function(){
+				d.resolve(true);
+			}, 50);
+			return d;
+		}
+	},{
+		name: "doh.Deferred failure--SHOULD FAIL",
 		runTest: function(t){
 			console.log("running test that SHOULD FAIL");
 			var d = new doh.Deferred();
+			setTimeout(d.getTestCallback(function(){
+				t.assertTrue(false);
+			}), 50);
+			return d;
+		}
+	},{
+		name: "dojo.Deferred failure--SHOULD FAIL",
+		runTest: function(t){
+			console.log("running test that SHOULD FAIL");
+			var d = new dojo.Deferred();
 			setTimeout(function(){
-				d.errback(new Error("hrm..."));
+				d.reject(new Error("hrm..."));
 			}, 50);
 			return d;
 		}
 	},{
-		name: "timeoutFailure--SHOULD FAIL",
+		name: "doh.Deferred timeout failure--SHOULD FAIL",
 		timeout: 50,
 		runTest: function(t){
 			console.log("running test that SHOULD FAIL");
 			// timeout of 50
 			var d = new doh.Deferred();
+			setTimeout(d.getTestCallback(function(){
+			}), 100);
+			return d;
+		}
+	},{
+		name: "dojo.Deferred timeout failure--SHOULD FAIL",
+		timeout: 50,
+		runTest: function(t){
+			console.log("running test that SHOULD FAIL");
+			// timeout of 50
+			var d = new dojo.Deferred();
 			setTimeout(function(){
 				d.callback(true);
 			}, 100);
diff --git a/util/doh/tests/tearDownTest.js b/util/doh/tests/tearDownTest.js
new file mode 100644
index 0000000..ac8da13
--- /dev/null
+++ b/util/doh/tests/tearDownTest.js
@@ -0,0 +1,65 @@
+define(["doh/runner"], function(doh) {
+	doh.register("doh/tearDownTest",[
+		{
+			name: "sync_pass_teardown",
+			pass: 1,
+			runTest: function(){
+				doh.debug("test sync_pass_teardown called");
+				doh.t(this.pass,"teardown was called out of order???");
+				doh.t(1);
+			},
+			tearDown: function(){
+				doh.debug("teardown sync_pass_teardown called");
+				this.pass=0;
+			}
+		},
+		{
+			name: "sync_fail_teardown",
+			pass: 1,
+			runTest: function(){
+				doh.debug("test sync_fail_teardown called");
+				doh.t(this.pass,"teardown was called out of order???");
+				doh.t(0,"SHOULD FAIL with 'teardown sync_fail_teardown called' in log");
+			},
+			tearDown: function(){
+				doh.debug("teardown sync_fail_teardown called");
+				this.pass=0;
+			}
+		},
+		{
+			name: "async_pass_teardown",
+			pass: 1,
+			runTest: function(){
+				doh.debug("test async_pass_teardown called");
+				var d = new doh.Deferred();
+				var _this=this;
+				setTimeout(d.getTestCallback(function(){
+					doh.t(_this.pass,"teardown was called out of order???");
+				}),900);
+				return d;
+			},
+			tearDown: function(){
+				this.pass=0;
+				doh.debug("teardown async_pass_teardown called");
+			}
+		},
+		{
+			name: "async_fail_teardown",
+			pass: 1,
+			runTest: function(){
+				doh.debug("test async_fail_teardown called");
+				var d = new doh.Deferred();
+				var _this=this;
+				setTimeout(d.getTestCallback(function(){
+					doh.t(_this.pass,"teardown was called out of order???");
+					doh.t(0,"SHOULD FAIL with 'teardown async_fail_teardown called' in log");
+				}),900);
+				return d;
+			},
+			tearDown: function(){
+				doh.debug("teardown async_fail_teardown called");
+				this.pass=0;
+			}
+		}
+	]);
+});
\ No newline at end of file
diff --git a/util/jsdoc/LICENSE b/util/jsdoc/LICENSE
index aa6b39f..b1ddd34 100644
--- a/util/jsdoc/LICENSE
+++ b/util/jsdoc/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2011, The Dojo Foundation
+Copyright (c) 2005-2013, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/util/jsdoc/THEMING b/util/jsdoc/THEMING
deleted file mode 100755
index e69de29..0000000
diff --git a/util/less/.npmignore b/util/less/.npmignore
new file mode 100644
index 0000000..4be6e16
--- /dev/null
+++ b/util/less/.npmignore
@@ -0,0 +1 @@
+dist/*
\ No newline at end of file
diff --git a/util/less/CHANGELOG.md b/util/less/CHANGELOG.md
new file mode 100644
index 0000000..d5cc908
--- /dev/null
+++ b/util/less/CHANGELOG.md
@@ -0,0 +1,118 @@
+# 1.3.3
+
+2012-12-30
+
+ - Fix critical bug with mixin call if using multiple brackets
+ - when using the filter contrast function, the function is passed through if the first argument is not a color
+
+# 1.3.2
+
+2012-12-28
+
+ - browser and server url re-writing is now aligned to not re-write (previous lessc behaviour)
+ - url-rewriting can be made to re-write to be relative to the entry file using the relative-urls option (less.relativeUrls option)
+ - rootpath option can be used to add a base path to every url
+ - Support mixin argument seperator of ';' so you can pass comma seperated values. e.g. `.mixin(23px, 12px;);`
+ - Fix lots of problems with named arguments in corner cases, not behaving as expected
+ - hsv, hsva, unit functions
+ - fixed lots more bad error messages
+ - fix `@import-once` to use the full path, not the relative one for determining if an import has been imported already
+ - support `:not(:nth-child(3))`
+ - mixin guards take units into account
+ - support unicode descriptors (`U+00A1-00A9`)
+ - support calling mixins with a stack when using `&` (broken in 1.3.1)
+ - support `@namespace` and namespace combinators
+ - when using % with colour functions, take into account a colour is out of 256
+ - when doing maths with a % do not divide by 100 and keep the unit
+ - allow url to contain % (e.g. %20 for a space)
+ - if a mixin guard stops execution a default mixin is not required
+ - units are output in strings (use the unit function if you need to get the value without unit)
+ - do not infinite recurse when mixins call mixins of the same name
+ - fix issue on important on mixin calls
+ - fix issue with multiple comments being confused
+ - tolerate multiple semi-colons on rules
+ - ignore subsequant `@charset`
+ - syncImport option for node.js to read files syncronously
+ - write the output directory if it is missing
+ - change dependency on cssmin to ycssmin
+ - lessc can load files over http
+ - allow calling less.watch() in non dev mode
+ - don't cache in dev mode
+ - less files cope with query parameters better
+ - sass debug statements are now chrome compatible
+ - modifyVars function added to re-render with different root variables
+
+# 1.3.1
+
+2012-10-18
+
+- Support for comment and @media debugging statements
+- bug fix for async access in chrome extensions
+- new functions tint, shade, multiply, screen, overlay, hardlight, difference, exclusion, average, negation, softlight, red, green, blue, contrast
+- allow escaped characters in attributes
+- in selectors support @{a} directly, e.g. .a.@{a} { color: black; }
+- add fraction parameter to round function
+- much better support for & selector
+- preserve order of link statements client side
+- lessc has better help
+- rhino version fixed
+- fix bugs in clientside error handling
+- support dpi, vmin, vm, dppx, dpcm units
+- Fix ratios in media statements
+- in mixin guards allow comparing colors and strings
+- support for -*-keyframes (for -khtml but now supports any)
+- in mix function, default weight to 50%
+- support @import-once
+- remove duplicate rules in output
+- implement named parameters when calling mixins
+- many numerous bug fixes
+
+# 1.3.0
+
+2012-03-10
+
+- @media bubbling
+- Support arbitrary entities as selectors
+- [Variadic argument support](https://gist.github.com/1933613)
+- Behaviour of zero-arity mixins has [changed](https://gist.github.com/1933613)
+- Allow `@import` directives in any selector
+- Media-query features can now be a variable
+- Automatic merging of media-query conditions
+- Fix global variable leaks
+- Fix error message on wrong-arity call
+- Fix an `@arguments` behaviour bug
+- Fix `::` selector output
+- Fix a bug when using @media with mixins
+
+
+# 1.2.1
+
+2012-01-15
+
+- Fix imports in browser
+- Improve error reporting in browser
+- Fix Runtime error reports from imported files
+- Fix `File not found` import error reporting
+
+
+# 1.2.0
+
+2012-01-07
+
+- Mixin guards
+- New function `percentage`
+- New `color` function to parse hex color strings
+- New type-checking stylesheet functions
+- Fix Rhino support
+- Fix bug in string arguments to mixin call
+- Fix error reporting when index is 0
+- Fix browser support in WebKit and IE
+- Fix string interpolation bug when var is empty
+- Support `!important` after mixin calls
+- Support vanilla @keyframes directive
+- Support variables in certain css selectors, like `nth-child`
+- Support @media and @import features properly
+- Improve @import support with media features
+- Improve error reports from imported files
+- Improve function call error reporting
+- Improve error-reporting
diff --git a/util/less/CONTRIBUTING.md b/util/less/CONTRIBUTING.md
new file mode 100644
index 0000000..787fd6a
--- /dev/null
+++ b/util/less/CONTRIBUTING.md
@@ -0,0 +1,50 @@
+## Bug Reports
+
+ - Please create a short test case
+ - Test with the latest version
+ - indicate how you use less - browser/lessc/external tool
+
+## Feature Requests
+
+ - Please search feature requests to see if something similar exists already
+ - include a use-case - we do not add language features without a reason
+ - consider whether your language feature would be better as a function
+
+## Pull Requests
+
+Thankyou! Please take the time to read these guidelines
+
+ - Consider adding a feature request first to see if people are pro or con
+ - do not change the dist/ folder - we do this when releasing
+ - tests - please add tests for your work. use `make test` to see if they pass
+ - spaces not tabs
+ - end lines in semi-colons - loosely aim towards jslint standards
+
+## Developing
+
+1. install cygwin - http://cygwin.com/install.html 
+ - default options +
+	- Devel -> Make
+                -> Git
+2. install node.js - http://nodejs.org/
+3. install phantomJS - http://phantomjs.org/download.html
+	- copy to a directory of your choice
+	- (windows) modify the path directory to include whereever you have copied it
+4. clone the repository and download to local computer
+5. run `npm install -g diff` to get diffs in your tests
+
+`lessc or node bin/lessc`
+
+to run the less compiler
+
+`make test`
+
+runs the node tests
+
+`make browser-test`
+
+runs the headless browser tests
+
+`make browser-test-server`
+
+sets up the server for the headless tests.. then go to http://localhost:8081/browser/test-runner-main.htm or one of the other test runner pages created in /test/browser/
diff --git a/util/less/Makefile b/util/less/Makefile
new file mode 100644
index 0000000..9ac013c
--- /dev/null
+++ b/util/less/Makefile
@@ -0,0 +1,87 @@
+#
+# Run all tests
+#
+test: 
+	node test/less-test.js
+
+#
+# Run benchmark
+#
+benchmark:
+	node benchmark/less-benchmark.js
+
+#
+# Build less.js
+#
+SRC = lib/less
+HEADER = build/header.js
+VERSION = `cat package.json | grep version \
+														| grep -o '[0-9]\.[0-9]\.[0-9]\+'`
+DIST = dist/less-${VERSION}.js
+RHINO = dist/less-rhino-${VERSION}.js
+DIST_MIN = dist/less-${VERSION}.min.js
+
+browser-prepare: DIST := test/browser/less.js
+
+less:
+	@@mkdir -p dist
+	@@touch ${DIST}
+	@@cat ${HEADER} | sed s/@VERSION/${VERSION}/ > ${DIST}
+	@@echo "(function (window, undefined) {" >> ${DIST}
+	@@cat build/require.js\
+	      build/ecma-5.js\
+	      ${SRC}/parser.js\
+	      ${SRC}/functions.js\
+	      ${SRC}/colors.js\
+	      ${SRC}/tree/*.js\
+	      ${SRC}/tree.js\
+	      ${SRC}/browser.js\
+	      build/amd.js >> ${DIST}
+	@@echo "})(window);" >> ${DIST}
+	@@echo ${DIST} built.
+	
+browser-prepare: less
+	node test/browser-test-prepare.js
+	
+browser-test: browser-prepare
+	phantomjs test/browser/phantom-runner.js
+
+browser-test-server: browser-prepare
+	phantomjs test/browser/phantom-runner.js --no-tests
+
+rhino:
+	@@mkdir -p dist
+	@@touch ${RHINO}
+	@@cat build/require-rhino.js\
+	      build/ecma-5.js\
+	      ${SRC}/parser.js\
+	      ${SRC}/functions.js\
+	      ${SRC}/colors.js\
+	      ${SRC}/tree/*.js\
+	      ${SRC}/tree.js\
+	      ${SRC}/rhino.js > ${RHINO}
+	@@echo ${RHINO} built.
+
+min: less
+	@@echo minifying...
+	@@uglifyjs ${DIST} > ${DIST_MIN}
+	@@echo ${DIST_MIN} built.
+
+server: less
+	cp dist/less-${VERSION}.js test/html/
+	cd test/html && python -m SimpleHTTPServer
+
+clean:
+	git rm dist/*
+
+dist: clean min
+	git add dist/*
+	git commit -a -m "(dist) build ${VERSION}"
+	git archive master --prefix=less/ -o less-${VERSION}.tar.gz
+	npm publish less-${VERSION}.tar.gz
+
+stable:
+	npm tag less ${VERSION} stable
+
+
+.PHONY: test benchmark
diff --git a/util/less/README b/util/less/README
deleted file mode 100644
index 5d91786..0000000
--- a/util/less/README
+++ /dev/null
@@ -1,7 +0,0 @@
-See http://lesscss.org/ for details on this package, and
-https://github.com/cloudhead/less.js/blob/master/README.md for the original README file.
-
-Files in this directory pulled from: https://github.com/cloudhead/less.js/tree/master/lib/less,
-except for LICENSE which is from https://github.com/cloudhead/less.js/blob/master/LICENSE.
-
-The version is: 1.1.4.
diff --git a/util/less/README.md b/util/less/README.md
new file mode 100644
index 0000000..726d691
--- /dev/null
+++ b/util/less/README.md
@@ -0,0 +1,20 @@
+less.js
+=======
+
+The **dynamic** stylesheet language.
+
+<http://lesscss.org>
+
+about
+-----
+
+This is the JavaScript, and now official, stable version of LESS.
+
+For more information, visit <http://lesscss.org>.
+
+license
+-------
+
+See `LICENSE` file.
+
+> Copyright (c) 2009-2011 Alexis Sellier
diff --git a/util/less/benchmark/benchmark.less b/util/less/benchmark/benchmark.less
new file mode 100644
index 0000000..bf7fef7
--- /dev/null
+++ b/util/less/benchmark/benchmark.less
@@ -0,0 +1,3979 @@
+ at bg: #f01;
+ at white: #fff;
+ at grey: #eee;
+ at black: #000;
+ at blue: #000;
+ at accent_colour: #000;
+ at light_grey: #eee;
+ at dark_grey: #eee;
+ at yellow: #422;
+ at red: #ff0000;
+ at colour_positive: #ff0000;
+ at colour_negative: #ff0000;
+
+.box_shadow (...) {
+}
+.text_shadow (...) {
+}
+.border_radius (...) {
+}
+.border_radius_top_left (...) {
+}
+.border_radius_top_right (...) {
+}
+.border_radius_bottom_right (...) {
+}
+.border_radius_bottom_left (...) {
+}
+.border_radius_top (...) {
+}
+.border_radius_right (...) {
+}
+.border_radius_bottom (...) {
+}
+.border_radius_left (...) {
+}
+div.browse {
+  margin: 0 0 20px;
+  &.class {
+    padding: 0;
+  }
+  div.header {
+    padding: 10px 10px 9px; text-align: left; background: @bg url('/images/panel_header_bg.png') repeat-x top left;
+    border-bottom: 1px solid (@bg * 0.66 + @black * 0.33); line-height: 1; height: 18px;
+    .border_radius_top(3); color: @light_grey;
+    h3 { font-size: 16px; margin: 0; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); }
+    span.filter {
+      float: left; display: block; overflow: hidden; position: relative; z-index: 5;
+      a {
+        margin: 0 1px 0 0; display: block; float: left; padding: 0 8px; height: 18px; font-weight: bold; font-size: 10px; line-height: 18px;
+        text-transform: uppercase; background: url('/images/transparent_backgrounds/black_50.png'); color: @light_grey; text-decoration: none; position: relative; z-index: 3;
+        .active {
+          background: @white; color: @black; z-index: 4;
+          :hover { color: @black; }
+        }
+        :hover { color: @white; }
+        :first-child { .border_radius_left(2); }
+        :last-child { .border_radius_right(2); margin-right: 0; }
+      }
+    }
+
+    span.filter.dropdown {
+      margin: 0; position: relative; overflow: visible;
+      a {
+        .border_radius(2); background: @white; color: @black; margin: 0; position: relative; padding-right: 25px;
+        img { float: left; margin: 4px 5px 0 0; }
+        b.arrow {
+          float: right; display: block; height: 0; width: 0; border: 5px solid transparent; border-top: 5px solid @black; border-bottom: none;
+          position: absolute; top: 6px; right: 10px;
+        }
+        :hover {
+          background: @accent_colour; color: @white;
+          b.arrow { border-top: 5px solid @white; }
+        }
+      }
+      ul {
+        position: absolute; top: 100%; left: 0; margin: 1px 0 0; padding: 0; background: @white; .border_radius(2);
+        .box_shadow(0, 1, 1, @black);
+        li {
+          list-style: none; display: block; padding: 0; margin: 0;
+          a {
+            display: block; height: 18px; line-height: 18px; color: @black; font-size: 10px; text-transform: uppercase; background: transparent;
+            border-bottom: 1px solid (@light_grey * 0.66 + @white * 0.33); float: none; margin: 0; .border_radius(0); white-space: nowrap;
+            :hover { background: url('/images/transparent_backgrounds/accent_colour_25.png'); color: @black; }
+          }
+          :last-child {
+            a { border: none; }
+          }
+        }
+      }
+    }
+    span.filter.dropdown.sort { float: left; margin: 0 0 0 10px; }
+    span.filter.dropdown.localisation { float: left; margin: 0 0 0 10px; }
+    a.more {
+      float: right; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); font-size: 14px; font-weight: bold;
+      position: relative; top: 2px;
+      :hover { text-decoration: none; }
+    }
+  }
+  > ul {
+    margin: 0; background: @white; padding: 10px 0 0 10px; .border_radius(3); position: relative;
+    li {
+      display: block; float: left; list-style: none; margin: 0 10px 10px 0; padding: 5px; position: relative;
+      background: @white; width: 130px; border: 1px solid (@light_grey * 0.33 + @white * 0.66); .border_radius(2);
+      a.remove {
+        position: absolute; height: 16px; width: 16px; padding: 3px; background: @accent_colour;
+        .border_radius(99); display: none; z-index: 3; top: -8px; right: -8px;
+        img { vertical-align: middle; }
+      }
+      div.thumbnail {
+        .border_radius_top(3); position: relative; z-index: 3;
+        .marker {
+          position: absolute; padding: 2px; .border_radius(2); z-index: 3;
+          background: url('/images/transparent_backgrounds/white_75.png'); height: 12px; width: 12px;
+        }
+        .marker.coupon {
+          height: auto; width: auto; top: 10px; right: -3px; padding: 0; background: transparent; overflow: hidden; position: absolute;
+          b {
+            display: block; height: 0; width: 0; float: left; border: 14px solid transparent; border-top: 14px solid @accent_colour;
+            border-bottom: none; border-right: none; float: left;
+          }
+          span {
+            color: @white; font-size: 10px; font-weight: bold; text-transform: uppercase; height: 14px; line-height: 14px; display: block;
+            padding: 0 4px 0 2px; background: @accent_colour; .text_shadow(1, 1, 0px, (@accent_colour * 0.75 + @black * 0.25)); margin: 0 0 0 14px;
+          }
+        }
+        .marker.video {
+          position: absolute; left: 50%; top: 50%; background: @white; width: 10px; height: 10px;
+          b { display: block; width: 0; height: 0; border: 5px solid transparent; border-left: 10px solid @black; border-right: none; }
+        }
+        .marker.endorsed_by_me { background: none; padding: 0; right: 0; bottom: -32px; .border_radius(2); background: @white; }
+        a.thumbnail {
+          display: block; overflow: hidden; position: relative; text-align: center;
+          img { position: relative; display: block; margin: auto; }
+        }
+      }
+      div.text {
+        margin: 3px 0 0; display: block;
+        a { text-decoration: none; }
+        a.title {
+          display: block; text-decoration: none; font-weight: bold; font-size: 12px; line-height: 16px;
+          white-space: nowrap; height: 16px; overflow: hidden;
+          :before {
+            display: block; height: 32px; width: 20px; content: " "; float: right; right: -15px; top: -8px;
+            background: @white; position: relative; z-index: 1; .box_shadow(-5, 0, 10, @white);
+          }
+        }
+        small {
+          font-size: 11px; line-height: 13px; color: @grey; display: block; height: 13px; overflow: hidden; white-space: nowrap;
+          a { font-weight: bold; }
+          :before {
+            display: block; height: 32px; width: 20px; content: " "; float: right; right: -15px; top: -8px;
+            background: @white; position: relative; z-index: 1; .box_shadow(-5, 0, 10, @white);
+          }
+        }
+      }
+      :hover {
+        background: @accent_colour;
+        a.remove { display: block; }
+        div.thumbnail {
+          a.marker.remove, a.marker.video {
+            b { display: inline-block; }
+          }
+          a.marker.video { .box_shadow(0, 0, 2, @black); }
+        }
+        div.text {
+          a { color: @white; }
+          a.title:before { background: @accent_colour; .box_shadow(-5, 0, 10, @accent_colour); }
+          small {
+            color: @white * 0.75 + @accent_colour * 0.25;
+            :before { background: @accent_colour; .box_shadow(-5, 0, 10, @accent_colour); }
+          }
+        }
+        div.footer a { color: @white; }
+      }
+    }
+    > li.ad div.thumbnail a.thumbnail {
+      width: 130px; height: 97px;
+      img { width: 100%; height: 100%; }
+    }
+    > li.brand div.thumbnail a.thumbnail {
+      width: 120px; height: 87px; padding: 5px; background: @white; .border_radius(2);
+      img { max-width: 120px; max-height: 87px; }
+    }
+    li.paginate {
+      margin-bottom: 0;
+      a {
+        display: block; position: relative; text-decoration: none; height: 131px;
+        div.arrow {
+          background: #81c153 url('/images/button_bg.png') repeat-x left top; border: 1px solid (@accent_colour * 0.75 + @black * 0.25);
+          height: 44px; .border_radius(99); width: 44px; margin: 0 auto; position: relative; top: 32px;
+          b { text-indent: -9000px; display: block; border: 10px solid transparent; width: 0; height: 0; position: relative; top: 12px; }
+        }
+        div.label {
+          position: absolute; bottom: 5px; left: 0; right: 0; line-height: 13px;
+          color: @accent_colour * 0.85 + @black * 0.15; text-decoration: none;
+          font-weight: bold; font-size: 12px; text-align: center;
+        }
+        :hover {
+          div.arrow { background: #abd56e url('/images/button_bg.png') repeat-x left -44px; }
+        }
+      }
+      :hover { background: transparent; }
+    }
+    li.paginate.previous a div b { border-right: 15px solid @white; border-left: none; left: 12px; }
+    li.paginate.next a div b { border-left: 15px solid @white; border-right: none; left: 16px; }
+  }  
+  > div.footer {
+    padding: 9px 10px 10px; background: @light_grey * 0.75 + @white * 0.25; overflow: hidden;
+    border-top: 1px solid @light_grey; .border_radius_bottom(3);
+    div.info {
+      float: left; color: @grey;
+      strong { color: @black; font-weight: normal; }
+    }
+    div.pagination {
+      float: right;
+      > * {
+        display: inline-block; line-height: 1; padding: 0 6px; line-height: 18px; height: 18px; background: @white;
+        .border_radius(3); text-decoration: none; font-weight: bold;
+        font-size: 10px; text-transform: uppercase;
+      }
+      a { color: @grey; }
+      a:hover { color: @black; }
+      span.disabled { color: @light_grey; }
+      span.current { color: @white; background: @bg; border: none; }
+      span.current:hover { color: @white; }
+    }
+  }
+}
+div.browse.with_categories { margin: 0 0 0 160px; }
+div.browse.with_options > ul { .border_radius_top(0); }
+div.browse.with_footer > ul { .border_radius_bottom(0); }
+/* Browse List */
+div.browse.list {
+> ul {
+    margin: 0; min-height: 320px;
+    padding: 10px 0 0 10px; overflow: hidden;
+    > li {
+      display: block; list-style: none; margin: 0 10px 10px 0; padding: 5px;
+      .border_radius(3); position: relative; line-height: normal;
+      .marker {
+        position: absolute; padding: 2px; .border_radius(2);
+        background: url('/images/transparent_backgrounds/white_75.png');
+        img { height: 12px; width: 12px; }
+      }
+      img.marker { height: 12px; width: 12px; }
+      span.marker.new {
+        color: black; left: -5px; top: -5px; background: none; background-color: @white * 0.1 + @yellow * 0.6 + @red * 0.3; line-height: 1; padding: 2px 5px;
+        font-weight: bold;
+      }
+      a.marker.media_type {
+        display: inline-block; text-decoration: none; top: 39px; left: 8px;
+        font-size: 10px;
+        b { font-weight: normal; margin: 0 0 0 2px; line-height: 1; display: none; }
+        img { vertical-align: middle; }
+      }
+      a.thumbnail {
+        float: left;
+        width: 68px; display: block; overflow: hidden;
+        border: 1px solid @light_grey;
+        :hover { border-color: @accent_colour; }
+      }
+      span.title_brand {
+        display: block; margin: 0 0 2px 75px;
+        a { margin: 0; display: inline; }
+        a.brand_name { font-weight: normal; font-size: 12px; }
+      }
+      a.ad_title {
+        font-weight: bold; font-size: 14px; margin: 0 0 0 75px; display: block;
+      }
+      a.brand_name {
+        font-weight: bold; font-size: 14px; margin: 0 0 0 75px; display: block;
+      }
+      small {
+        display: block; color: @grey; margin: 0 0 0 75px; font-size: 12px;
+      }
+      small.brand_name { display: inline; margin: 0; }
+      ul.chart {
+        margin: 0 0 0 80px;
+        height: 39px;
+      }
+      ul.networks {
+        margin: 3px 0 0 75px; padding: 0; overflow: hidden;
+        li { display: block; float: left; margin: 0 5px 0 0; line-height: 1; }
+      }
+      div.points {
+        display: none;
+        font-size: 12px; text-align: right;
+        label { color: @grey; }
+      }
+      a.remove { bottom: -3px; right: -3px; }
+    }
+    li.ad {
+      a.thumbnail { height: 51px; }
+      span.title_brand {
+        small.brand_name {
+          display: block;
+        }
+      }
+    }
+    li.brand {
+      a.thumbnail { height: 68px; }
+    }
+  }
+}
+div.browse.list.with_options ul { .border_radius_top(0); }
+div.browse.list.with_footer ul { .border_radius_bottom(0); }
+div.browse.list.cols_2 {
+  > ul {
+    > li {
+      width: 285px; float: left;
+      :hover {
+        background: @white;
+      }
+    }
+  }
+}
+div.browse.ads.list {
+  > ul {
+    > li {
+      height: 53px;
+      a.thumbnail {
+        height: 51px;
+      }
+    }
+  }
+}
+div.browse.brands.list {
+  > ul {
+    > li {
+      height: 68px;
+      a.thumbnail {
+        height: 66px;
+      }
+    }
+  }
+}
+
+/* Categories List */
+#categories {
+  margin: 40px 0 0; width: 160px; float: left; position: relative; z-index: 1;
+  ul {
+    margin: 0; padding: 10px 0 0;
+    li {
+      list-style: none; margin: 0; padding: 0; font-size: 14px;
+      a { color: @grey; display: block; padding: 5px 10px 5px 15px; text-decoration: none; .border_radius_left(3); }
+      a:hover { color: @black; background: @light_grey * 0.15 + @white * 0.85; }
+    }
+    .all a { font-weight: bold; }
+    .current a {
+      background: @white; color: @black; border: 1px solid (@light_grey * 0.25 + @white * 0.75); border-right: none; border-left: 5px solid @bg; 
+      padding-left: 10px;
+    }
+  }
+}
+
+/* Ads > Show */
+#ad {
+  div.header {
+    overflow: hidden;
+    h3 { font-size: 16px; margin: 0 0 3px; }
+    small {
+      a.category { font-weight: bold; color: @accent_colour; }
+      span.networks img { position: relative; top: 3px; }
+    }
+    span.brand {
+      float: right; color: @white;
+      a.brand_name { font-weight: bold; color: @accent_colour; }
+    }
+  }
+  div.content {
+    padding: 0; position: relative;
+    a.toggle_size {
+      display: block; .border_radius(3); background-color: @black; padding: 0 5px 0 26px;
+      background-position: 5px center; background-repeat: no-repeat; text-decoration: none; margin: 5px 5px 0 0;
+      position: absolute; top: 0; right: 0; line-height: 25px; z-index: 45;
+    }
+    img.creative { margin: 0 auto; max-width: 540px; display: block; }
+    object { position: relative; z-index: 44; }
+    object.video { line-height: 0; font-size: 0; }
+    object embed { position: relative; z-index: 45; line-height: 0; font-size: 0; }
+  }
+  div.content.not_video {
+    padding: 40px; text-align: center;
+    * { margin-left: auto; margin-right: auto; }
+    object.flash { margin-bottom: 0; }
+  }
+  div.footer {
+    padding: 0;
+    div.vote_views {
+      padding: 5px 10px; overflow: hidden;
+      div.share { float: right; margin: 2px 0 0 0; }
+      #login_register_msg, #encourage_vote_msg { line-height: 22px; font-weight: bold; color: @black; }
+    }
+  }
+}
+#sidebar {
+  #meta {
+    table {
+      margin: 0;
+      tr:last-child td { padding-bottom: 0; }
+      td {
+        padding: 0 0 5px;
+        ul.networks {
+          margin: 0; padding: 0;
+          li {
+            list-style: none; display: inline;
+          }
+          li {
+          }
+        }
+      }
+      td.label { color: @grey; white-space: nowrap; width: 1%; text-align: right; padding-right: 5px; }
+    }
+  }
+}
+
+/* Voting */
+div.voted {
+  font-size: 12px; line-height: 22px; color: @black; display: inline-block; font-weight: bold;
+  img { float: left; margin-right: 5px; padding: 3px; .border_radius(3); }
+}
+#voted_up {
+  img { background: @colour_positive * 0.66 + @bg * 0.15; }
+}
+#voted_down {
+  img { background: @colour_negative * 0.66 + @bg * 0.15; }
+}
+#encourage_comment {
+  display: inline-block; line-height: 22px; font-weight: bold;
+}
+#vote {
+  overflow: hidden; font-size: 12px; line-height: 22px; color: @black; float: left;
+  a {
+    color: @white; font-weight: bold; overflow: hidden; display: block;
+    width: 16px; text-decoration: none; text-align: center; font-size: 10px; padding: 3px; text-transform: uppercase;
+  }
+  a.up {
+    float: left; background: @colour_positive * 0.66 + @bg * 0.15; .border_radius_left(3);
+    :hover { background: @colour_positive * 0.85 + @bg * 0.15; }
+  } 
+  a.down {
+    float: left; background: @colour_negative * 0.66 + @bg * 0.15; .border_radius_right(3);
+    margin: 0 5px 0 1px;
+    :hover { background: @colour_negative * 0.85 + @bg * 0.15; }
+  }
+}
+#vote.disabled {
+  a.up {
+    background: (@colour_positive * 0.66 + @bg * 0.15) * 0.15 + @grey * 0.85;
+    :hover { background: (@colour_positive * 0.85 + @bg * 0.15) * 0.25 + @grey * 0.75; }
+  }
+  a.down {
+    background: (@colour_negative * 0.66 + @bg * 0.15) * 0.15 + @grey * 0.85;
+    :hover { background: (@colour_negative * 0.85 + @bg * 0.15) * 0.25 + @grey * 0.75; }
+  }
+}
+
+/* Panels */
+div.panel {
+  margin: 0 0 20px; position: relative; .box_shadow(0, 0, 3, @light_grey * 0.66 + @white * 0.33); .border_radius(3);
+  > div.header {
+    background: @bg url('/images/panel_header_bg.png') repeat-x top left; border-bottom: 1px solid (@bg * 0.66 + @black * 0.33);
+    padding: 5px 10px 4px; .border_radius_top(3); min-height: 18px; 
+    h2 { font-size: 16px; margin: 0; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); }
+    h3 { color: @white; font-size: 14px; margin: 0; line-height: 18px; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); }
+    small { display: block; font-size: 12px; color: @light_grey * 0.25 + @white * 0.75; }
+    span.filter {
+      float: left; display: block; overflow: hidden; position: relative; z-index: 5;
+      a {
+        margin: 0 1px 0 0; display: block; float: left; padding: 0 8px; height: 18px; font-weight: bold; font-size: 10px; line-height: 18px;
+        text-transform: uppercase; background: url('/images/transparent_backgrounds/black_50.png'); color: @light_grey; text-decoration: none; position: relative; z-index: 3;
+      }
+      a:first-child { .border_radius_left(2); }
+      a:last-child { .border_radius_right(2); margin-right: 0; }
+      a.active { background: @white; color: @black; z-index: 4; }
+      a:hover { color: @white; }
+      a.active:hover { color: @black; }
+    }
+
+    span.filter.dropdown {
+      margin: 0; position: relative; overflow: visible;
+      a {
+        .border_radius(2); background: @white; color: @black; margin: 0; position: relative; padding-right: 25px;
+        img { float: left; margin: 4px 5px 0 0; }
+        b.arrow {
+          float: right; display: block; height: 0; width: 0; border: 5px solid transparent; border-top: 5px solid @black; border-bottom: none;
+          position: absolute; top: 6px; right: 10px;
+        }
+        :hover {
+          background: @accent_colour; color: @white;
+          b.arrow { border-top: 5px solid @white; }
+        }
+      }
+
+      ul {
+        position: absolute; top: 100%; left: 0; margin: 1px 0 0; padding: 0; background: @white; .border_radius(2);
+        .box_shadow(0, 1, 1, @black);
+        li {
+          list-style: none; display: block; padding: 0; margin: 0;
+          a {
+            display: block; height: 18px; line-height: 18px; color: @black; font-size: 10px; text-transform: uppercase; background: transparent;
+            border-bottom: 1px solid (@light_grey * 0.66 + @white * 0.33); float: none; margin: 0; .border_radius(0); white-space: nowrap;
+            :hover { background: url('/images/transparent_backgrounds/accent_colour_25.png'); color: @black; }
+          }
+        }
+        li:last-child {
+          a { border: none; }
+        }
+      }
+    }
+    span.filter.dropdown.sort { float: left; margin: 0 0 0 10px; }
+    span.filter.dropdown.localisation { float: left; margin: 0 0 0 10px; }
+
+    a.more {
+      float: right; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); font-size: 14px; font-weight: bold;
+      position: relative; top: 2px;
+      :hover { text-decoration: none; }
+    }
+  }
+  > div.content {
+    background: @white; padding: 10px;
+    .no_padding { padding: 0; }
+  }
+  > div.footer {
+    background: @light_grey * 0.33 + @white * 0.66; border-top: 1px solid (@light_grey * 0.5 + @white * 0.5);
+    padding: 4px 10px 5px; .border_radius_bottom(3);
+  }
+}
+div.panel.no_footer div.content { .border_radius_bottom(3); }
+div.panel.no_header div.content { .border_radius_top(3); }
+div.panel.collapsable {
+  div.header {
+    cursor: pointer;
+    b.toggle { float: right; border: 5px solid transparent; border-bottom: 5px solid @white; border-top: none; display: block; width: 0; height: 0; margin: 6px 0 0 0; }
+  }
+  div.header:hover {
+    background-color: @bg * 0.75 + @white * 0.25;
+  }
+}
+div.panel.collapsed {
+  div.header {
+    border-bottom: none; .border_radius(3);
+    b.toggle { border-bottom: none; border-top: 5px solid @white; }
+  }
+  div.blank { border-bottom: none; .border_radius_bottom(3); }
+  div.content, div.footer { display: none; }
+}
+
+
+/* Sidebar Actions */
+#sidebar {
+  #actions {
+    .box_shadow(0, 0, 0, transparent);
+    div.content {
+      background: url('/images/transparent_backgrounds/accent_colour_10.png'); text-align: center;
+      p.endorsement {
+        margin: 0 0 10px; font-size: 14px; font-weight: bold;
+        small { font-weight: normal; line-height: inherit; margin: 10px 0 0; }
+        :last-child { margin: 0; }
+      }
+      div.share { margin: 5px 0 0; }
+      a.button {
+        font-size: 16px; line-height: normal; height: auto; padding: 5px 10px 5px 35px; font-weight: bold; margin: 0; position: relative;
+        img { position: absolute; top: 3px; left: 6px; }
+      }
+      div.flash.notice {
+        margin: 10px 0 0; font-size: 22px;
+        small { font-weight: normal; margin: 0 0 10px; }
+      }
+      div.flash.notice.done { margin: 0; }
+      small {
+        display: block; margin: 10px 0 0; font-size: 11px; color: #808080; line-height: 12px;
+        img.favicon { vertical-align: middle; }
+      }
+      div.blank {
+        border: none; background: none; padding: 10px 0 0; border-top: 1px solid (@accent_colour * 0.5 + @white * 0.5);
+        margin: 10px 0 0;
+      }
+    }
+  }
+}
+
+/* People Lists */
+ul.people {
+  margin: 0; padding: 10px 0 0 10px; background: @white;
+  > li {
+    display: block; margin: 0 10px 10px 0; float: left; padding: 2px; width: 57px; position: relative;
+    .border_radius(2); background: @white; list-style: none; border: 1px solid (@light_grey * 0.33 + @white * 0.66);
+    a.avatar {
+      display: block; width: 59px; height: 59px; overflow: hidden;
+      img { width: 100%; height: 100%; }
+    }
+    a.name { display: block; font-size: 10px; text-align: center; }
+    :hover {
+      background: @accent_colour;
+      a.name { color: @white; }
+    }
+  }
+}
+ul.people.list {
+  padding: 0;
+  > li {
+    margin: 0 0 10px; padding: 0 0 10px; overflow: hidden; float: none; width: auto; .border_radius(0);
+    border: none; border-bottom: 1px solid (@light_grey * 0.33 + @white * 0.66);
+    span.points {
+      float: right; display: block; padding: 5px; background: @light_grey * 0.15 + @white * 0.85; line-height: 1; 
+      text-align: center; width: 50px; height: 30px; .border_radius(3); margin: 0 0 0 10px;
+      strong { display: block; color: @black; font-size: 16px; margin: 2px 0 0; }
+      label { color: @grey; text-transform: uppercase; font-size: 10px; }
+      label.long { display: block; }
+      label.short { display: none; }
+    }
+    a.avatar { float: left; width: 40px; height: 40px; }
+    a.name { font-size: 14px; font-weight: bold; margin: 0 0 0 50px; text-align: left; }
+    a.name.long { display: inline; }
+    a.name.short { display: none; }
+    span.networks {
+      display: block; margin: 0 0 0 50px;
+      img.favicon { vertical-align: middle; }
+    }
+    :hover {
+      background: transparent;
+      a.name { color: @accent_colour * 0.85 + @black * 0.15; }
+    }
+    :last-child { padding-bottom: 0; border-bottom: none; margin-bottom: 0; }
+  }
+}
+ul.people.list.small {
+  > li {
+    span.points {
+      padding: 3px 6px; height: 18px; font-size: 9px; line-height: 17px; width: 60px;
+      strong { font-size: 12px; margin: 0; display: inline; }
+      label { font-size: 9px; }
+      label.long { display: none; }
+      label.short { display: inline; }
+    }
+    a.avatar { width: 24px; height: 24px; }
+    a.name { display: inline; line-height: 24px; margin: 0 0 0 5px; font-size: 12px; height: 24px; }
+    a.name.long { display: none; }
+    a.name.short { display: inline; }
+    span.networks { display: inline; margin: 0; }
+    :last-child { padding-bottom: 0; border-bottom: none; margin-bottom: 0; }
+  }
+}
+ul.people.tiled {
+  > li {
+    width: 28px; padding: 2px;
+    a.avatar { width: 24px; height: 24px; background: @white; padding: 2px; }
+    a.name, small, span.networks, span.points { display: none; }
+  }
+}
+
+/* Comments */
+#comments {
+  ul {
+    margin: 0 0 20px; padding: 0;
+    li {
+      display: block; list-style: none; padding: 0; margin: 0 0 10px;
+      span.meta {
+        margin: 0; overflow: hidden; display: block;
+        small { font-size: 12px; color: @light_grey; float: right; line-height: 16px; display: inline-block; }
+        a.avatar {
+          display: inline-block; height: 16px; width: 16px; position: relative; top: 3px;
+          img { height: 100%; width: 100%; }
+        }
+        a.name { font-weight: bold; line-height: 16px; display: inline-block; }
+        span.inactive { color: @grey; font-weight: bold; line-height: 16px; display: inline-block; }
+      }
+      b.tail {
+        display: block; width: 0; height: 0; margin: 3px 0 0 10px; border: 5px solid transparent; border-top: none;
+        border-bottom: 5px solid @white; position: relative; z-index: 2;
+      }
+      blockquote {
+        margin: 0; padding: 10px; .border_radius(3); font-style: normal; background: @white;
+        color: @dark_grey; .box_shadow(0, 0, 3, @light_grey * 0.66 + @white * 0.33);
+      }
+    }
+  }
+  form {
+    margin: 0;
+    textarea { width: 500px; }
+  }
+}
+
+/* Sidebar Categories */
+#sidebar {
+  #categories {
+    margin: 0 0 20px;
+    width: auto;
+    p { margin: 0; }
+  }
+}
+
+#sidebar {
+  #ads > ul li, #recommendations > ul li {
+    width: 81px;
+    div.thumbnail {
+      a.thumbnail { height: 60px; width: 81px; }
+    }
+    div.text {
+      a.title { font-size: 11px; height: 14px; line-height: 14px; }
+      small { display: none; }
+    }
+  }
+  #brands > ul li {
+    width: 55px;
+    div.thumbnail {
+      a.thumbnail {
+        height: 45px; width: 45px;
+        img { max-height: 45px; max-width: 45px; }
+      }
+    }
+    div.text { display: none; }
+  }
+}
+
+/* My Account */
+#accounts_controller {
+  #top {
+    #page_title {
+      #page_options {
+        a.button.public_profile {
+          float: right; font-size: 16px; line-height: 1; height: auto; padding: 8px 35px 8px 15px; position: relative;
+          b.arrow { display: block; height: 0; width: 0; position: absolute; top: 10px; right: 15px; border: 6px solid transparent; border-right: none; border-left: 6px solid @white; margin: 0; }
+        }
+        a.button.goto_dashboard {
+          float: right; font-size: 16px; line-height: 1; height: auto; padding: 8px 15px 8px 35px; margin-right: 5px; position: relative;
+          b.arrow { display: block; height: 0; width: 0; position: absolute; top: 10px; left: 15px; border: 6px solid transparent; border-left: none; border-right: 6px solid @white; margin: 0; }
+        }
+      }
+    }
+  }
+  #account_nav {
+    float: left; width: 200px; margin: 0 20px 0 0;
+    ul.nav {
+      margin: 0; padding: 0;
+      li {
+        margin: 0 0 5px; display: block; list-style: none; padding: 0;
+        a {
+          display: block; height: 30px; text-decoration: none; color: @white;
+          b {
+            border: 15px solid transparent; border-right: none; border-left: 10px solid transparent; width: 0;
+            height: 0; float: right; display: none;
+          }
+          span {
+            .border_radius(3); background: @bg; display: block; 
+            line-height: 30px; padding: 0 10px; font-size: 14px; font-weight: bold; margin: 0 10px 0 0;
+          }
+        }
+        :hover {
+          a {
+            color: @white;
+            b { border-left-color: @bg; display: block; }
+            span { background: @bg; .border_radius_right(0); }
+          }
+        }
+      }
+      li.current a {
+        b { border-left-color: @accent_colour; display: block; }
+        span { background: @accent_colour; color: @white; .border_radius_right(0); }
+      }
+    }
+  }
+  #main {
+    > div {
+      margin: 0 0 20px;
+      form { margin: 0; }
+    }
+    #profile {
+      a.avatar {
+        float: left; display: block;
+        width: 70px; overflow: hidden; position: relative; text-decoration: none;
+        img { width: 100%; }
+        span {
+          display: block; line-height: 1; padding: 3px; margin: 5px 0 0; color: @white; background: @accent_colour;
+          .border_radius(3); .text_shadow(1, 1, 0, @grey);
+          text-align: center; font-size: 10px; font-weight: bold; text-transform: uppercase;
+        }
+      }
+      form {
+        margin: 0 0 0 90px;
+        h4 { margin: 10px 0 20px; border-bottom: 1px solid (@light_grey * 0.5 + @white * 0.5); padding: 0; color: @bg; font-size: 16px; }
+        ul.choices {
+          li { width: 30%; }
+        }
+        div.extra { margin-top: 20px; }
+      }
+    }
+
+    #networks {
+      ul { margin: 0 -10px -10px 0; padding: 0; overflow: hidden;
+        li:hover
+        {
+          background: @light_grey; display: block; float: left; width: 180px;
+          padding: 10px; margin: 0 10px 10px 0; list-style: none; .border_radius(3);
+          position: relative;
+          * { line-height: normal; }
+          img { vertical-align: middle; float: left; }
+          .name { font-weight: bold; font-size: 14px; display: block; margin: -2px 0 0 42px; }
+          small {
+            font-size: 12px; color: @grey; display: block; margin-left: 42px; 
+            strong { color: @black; font-weight: normal; }
+          }
+          :hover {
+          }
+        }
+        li.installed {
+          background: @white;
+          border: 2px solid @accent_colour; padding: 8px;
+        }
+        li.unavailable {
+          .name { color: @black; }
+          :hover {
+            background: @light_grey;
+          }
+        }
+        li:hover {
+          background: @light_grey * 0.5 + @white * 0.5;
+        }
+      }
+    }
+  }
+}
+
+/* Shopping Style Panel */
+#shopping_style {
+  div.header a.button.small { float: right; }
+  div.content {
+    p {
+      margin: 0 0 10px;
+      label { text-transform: uppercase; font-size: 11px; display: block; color: @bg; font-weight: bold; }
+      span { color: @black; }
+      span.toggle { white-space: nowrap; color: @grey; }
+      :last-child { margin: 0; }
+    }
+    p.more { text-align: left; font-weight: normal; }
+    p.less { display: none; margin: 0; }
+  }
+}
+
+/* People Controller */
+#people_controller.index {
+  #main {
+    div.panel {
+      float: left; width: 300px; margin: 0 20px 0 0;
+      :last-child { margin-right: 0; }
+    }
+  }
+}
+#people_controller.show {
+  #person_overview, #shopping_style {
+    a.button.small {
+    }
+  }
+  #content {
+    #shopping_style {
+      float: left; width: 240px; margin: 0 20px 0 0;
+    }
+    #main { width: 360px; }
+  }
+}
+
+/* Search Results */
+#search_results {
+  margin: 0 0 20px;
+  li {
+    :hover {
+      small { color: @white * 0.75 + @accent_colour * 0.25; }
+    }
+  }
+}
+#search {
+  div.content {
+    padding: 20px;
+    form {
+      margin: 0; float: none;
+      span.submit_and_options {
+        display: block;
+      }
+    }
+    p { margin: 0 0 15px; }
+    h4 { font-weight: normal; margin: 0 0 5px; }
+  }
+}
+
+/* Recommendations */
+#recommendations {
+  div.browse {
+    margin: 0; padding: 0; background: none;
+    ul { min-height: 0; .border_radius(0); }
+  }
+}
+
+/* Blank States */
+div.blank {
+  padding: 20px; background: @bg * 0.05 + @blue * 0.05 + @white * 0.9; position: relative;
+  border: 1px solid (@bg * 0.1 + @blue * 0.1 + @white * 0.8); z-index: 1;
+  h4 { font-size: 18px; margin: 0 0 10px; }
+  h4:last-child { margin: 0; }
+  p { font-size: 16px; margin: 0 0 10px; }
+  p:last-child { margin: 0; }
+  p.with_list_number.large {
+    span { margin-left: 48px; display: block; color: @white; }
+  }
+  p.earn span { font-size: 22px; color: @white; line-height: 48px; font-weight: bold; }
+  a { white-space: nowrap; }
+  a.hide {
+    position: absolute; top: -5px; right: -5px; display: block; height: 16px; width: 16px; padding: 3px; background: #E7E9F6; .border_radius(99);
+  }
+}
+
+div.blank.small {
+  padding: 10px 20px; 
+  h4 { font-weight: normal; font-size: 16px; }
+  p { margin: 0; }
+}
+div.blank.tiny {
+  padding: 10px 20px;
+  h4 { font-weight: normal; font-size: 14px; }
+  p { margin: 0; font-size: 12px; }
+}
+div.blank.rounded {
+  .border_radius(3); margin: 0 0 20px;
+}
+div.blank.rounded.bottom { .border_radius_top(0); }
+div.blank.with_border_bottom { border-bottom: 1px solid (@bg * 0.1 + @blue * 0.1 + @white * 0.8); }
+div.blank.no_border_top { border-top: none; }
+div.blank.no_border_bottom { border-bottom: none; }
+div.blank.no_side_borders { border-right: none; border-left: none; }
+div.panel {
+  div.blank {
+    padding: 10px 20px; overflow: hidden; margin: 0;
+    h4 { font-weight: normal; font-size: 14px; }
+    p, ul { margin: 0 0 10px; font-size: 12px; }
+    p:last-child, ul:last-child { margin: 0; }
+  }
+}
+
+/* Sidebar Browse */
+#sidebar {
+  div.panel {
+    div.content.browse {
+      padding: 0; margin: 0;
+      > ul {
+          min-height: 0; .border_radius(0);
+        > li {
+          div.thumbnail {
+            a.thumbnail { padding: 5px; }
+            img.marker.media_type { top: 48px; left: 8px; }
+          }
+          div.footer {
+            a.title, a.name { font-size: 11px; font-weight: normal; }
+          }
+        }
+      }
+    }
+
+    div.content.browse.ads > ul > li {
+      width: 93px;
+      > div.thumbnail a.thumbnail { width: 83px; height: 62px; } 
+    }
+    div.content.browse.brands {
+      .border_radius(3);
+      > ul {
+        background: none;
+        > li {
+          width: 52px;
+          > div.thumbnail {
+            padding: 3px;
+            a.thumbnail { width: 42px; height: 42px; padding: 2px; }
+          }
+          li.active { background: @accent_colour; }
+        }
+      }
+    }
+    div.footer {
+      div.info { float: none; }
+      div.pagination { float: none; margin: 3px 0 0; }
+    }
+  }
+}
+
+/* List Numbers */
+label.list_number {
+  float: left; background: url('/images/transparent_backgrounds/black_15.png'); padding: 2px; width: 24px; height: 24px; display: block;
+  .border_radius(99);
+  b {
+    display: block; font-weight: bold; font-size: 14px; color: @white; background: @accent_colour; height: 20px; width: 20px; line-height: 20px;
+    text-align: center; .border_radius(99); .text_shadow(1, 1, 0px, (@accent_colour * 0.75 + @black * 0.25));
+    border: 2px solid @white;
+  }
+}
+label.list_number.large {
+  padding: 4px; width: 48px; height: 48px; .border_radius(99); position: relative; left: -10px;
+  b {
+    font-size: 28px; height: 40px; width: 40px; .border_radius(99); line-height: 40px;
+    .text_shadow(2, 2, 0px, (@accent_colour * 0.75 + @black * 0.25)); border-width: 4px;
+  }
+}
+
+/* Dashboard */
+#dashboard_controller {
+  #ads {
+    span.filter.state { float: right; }
+  }
+  #sidebar {
+    #shopping_style div.content {
+      p.less { display: block; }
+      p.more { display: none; }
+    }
+    #influences {
+      div.header {
+        padding-bottom: 0;
+        ul.tabs {
+          position: relative; top: 1px; z-index: 3;
+          li {
+            margin: 0 5px 0 0;
+            a {
+              border: none; background: url('/images/transparent_backgrounds/white_75.png');
+              :hover { color: @black; }
+            }
+          }
+          li.active {
+            a {
+              background: @white; border: none;
+              :hover { color: @black; }
+            }
+          }
+        }
+      }
+
+      div.tab_content {
+        overflow: hidden; padding: 0;
+        > ul {
+          padding: 10px 10px 0; max-height: 280px; min-height: 120px; overflow-y: scroll; .border_radius_bottom(3px);
+        }
+      }
+      div.footer {
+        form {
+          p {
+            margin: 0 0 5px;
+            img.marker { float: right; margin: 5px 0 0 0; }
+            span.invitee {
+              line-height: 26px; padding: 3px 3px 0; font-size: 14px;
+              small { color: @grey; font-size: 12px; }
+            }
+          }
+          p.indent { margin-left: 36px; }
+          p.submit { margin-top: 10px; }
+        }
+      }
+    }
+  }
+
+  div.panel.full {
+    > div.content {
+      margin: 0; padding: 0; background: none;
+      ul {
+        li {
+          width: 148px;
+          div.thumbnail {
+            img.marker.media_type { top: 90px; }
+            a.thumbnail { width: 138px; height: 104px; }
+          }
+        }
+      }
+    }
+  }
+  #people {
+    form {
+      padding: 0 0 5px;
+      input { width: 225px; float: left; margin: 0 5px 0 0; }
+      a.button { height: 23px; line-height: 23px; width: 60px; padding: 0; text-align: center; }
+    }
+  }
+}
+
+/* Remove Pages Titles when Browsing */
+#ads_controller, #brands_controller {
+  #page_title { display: none; }
+}
+
+/* Brands > Show */
+#brands_controller.show {
+  #ads {
+    div.filters {
+      h3 { font-size: 16px; margin: 0; }
+      span.show { float: right; }
+      span.filter.dropdown.localisation { float: right; margin: 0 0 0 10px; }
+      span.filter.state { float: right; margin: 0 0 0 10px; }
+    }
+  }
+}
+
+/* FAQ */
+#pages_controller.faq {
+  #answers {
+    h3 { margin-top: 20px; padding-top: 20px; border-top: 1px solid (@light_grey * 0.75 + @white * 0.25); }
+    h3.first { margin-top: 0; padding-top: 0; border: none; }
+  }
+  #questions {
+    div.content {
+      padding: 20px;
+      ul {
+        margin: 0; padding: 0;
+        li {
+          margin: 0 0 10px; list-style: none; display: block; padding: 0;
+          a { font-size: 14px; }
+        }
+        li:last-child {
+          margin: 0;
+        }
+      }
+    }
+  }
+}
+
+/* Person Overview */
+#person_overview {
+  padding: 20px 10px; position: relative; z-index: 25;
+  #person {
+    float: left; width: 620px;
+    a.avatar {
+      display: block; float: left; width: 60px; height: 60px;
+      img { height: 100%; width: 100%; }
+    }
+    > div {
+      margin: 0 0 0 75px; color: @white; font-size: 14px; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33);
+    }
+    div.name {
+      h2 {
+        margin: 0 0 5px; display: inline;
+        a {
+          font-size: 20px; font-weight: bold; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33);
+          line-height: 1; color: @white; text-decoration: none;
+          :hover { text-decoration: underline; }
+        }
+        a.button.small {
+          font-size: 10px;
+          :hover { text-decoration: none; }
+        }
+      }
+
+      span.points {
+        float: right; display: block; padding: 5px 10px; .border_radius(2); text-align: center; background: @white; position: relative;
+        min-width: 45px;
+        strong { color: @black; font-weight: bold; font-size: 24px; line-height: 1; display: block; .text_shadow(0, 0, 0, transparent); }
+        label { font-size: 9px; text-transform: uppercase; color: @grey; display: block; .text_shadow(0, 0, 0, transparent); font-weight: bold; }
+      }
+      span.points.with_redeem {
+        .border_radius_bottom(0);
+        a.button {
+          display: block; text-align: center; .border_radius_top(0); font-size: 10px; font-weight: bold; padding: 0;
+          position: absolute; height: 18px; left: 0; right: 0; bottom: -19px; line-height: 18px; text-transform: uppercase; border: none;
+        }
+      }
+      div.options { margin: 0; }
+    }
+    div.meta {
+      color: @white * 0.66 + @bg * 0.33;
+      span { color: @white; }
+      label { color: @white * 0.66 + @bg * 0.33; }
+      ul.networks {
+        display: inline; margin: 0; padding: 0;
+        li {
+          display: inline; line-height: 1;
+          img { position: relative; vertical-align: middle; top: -1px; }
+        }
+      }
+    }
+
+    div.extra {
+      font-size: 12px; margin-top: 20px; margin-bottom: 20px;
+      span.toggle {
+        .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33);
+        a { font-size: 10px; font-weight: bold; text-transform: uppercase; text-decoration: none; color: @accent_colour; }
+        b.arrow { display: inline-block; width: 0; height: 0; border: 5px solid transparent; position: relative; top: -2px; }
+      }
+      #less_info {
+        span.toggle {
+          b.arrow { border-top: 5px solid @accent_colour; border-bottom: 0; }
+        }
+      }
+      #more_info {
+        span.toggle {
+          float: right;
+          b.arrow { border-bottom: 5px solid @accent_colour; border-top: 0; }
+        }
+        h4 {
+          color: @white; margin: 0 0 10px 0; border-bottom: 1px solid (@white * 0.25 + @bg * 0.75); .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33);
+          span { font-size: 12px; }
+        }
+        p {
+          margin: 0 0 5px;
+          label { display: block; float: left; width: 120px; color: @white * 0.66 + @bg * 0.33; }
+          span { display: block; margin: 0 0 0 130px; }
+        }
+        p:last-child { margin: 0; }
+        
+      }
+    }
+    div.login {
+      margin: 0 0 0 75px;
+      a.button { font-weight: bold; }
+    }
+  }
+}
+
+/* Dashboard Nav */
+#dashboard_nav {
+  position: absolute; bottom: 0; left: 10px; margin: 0; padding: 0; overflow: hidden;
+  li {
+    display: block; float: left; margin: 0 5px 0 0;
+    a {
+      display: block; height: 28px; padding: 0 10px; line-height: 28px; .border_radius_top(2);
+      text-decoration: none; color: @white; background: url('/images/transparent_backgrounds/accent_colour_30.png'); font-size: 14px;
+      font-weight: bold;
+      :hover { background: url('/images/transparent_backgrounds/accent_colour_45.png'); }
+    }
+  }
+  li.active {
+    a {
+      background: @white; color: @black;
+      :hover { color: @black; }
+    }
+  }
+}
+
+/* Dwellometer */
+#dwellometer {
+  z-index: 45; float: right; .box_shadow(0, 0, 0, transparent); margin: 0;
+  div.content {
+    text-align: center; position: relative;
+    object, object embed { position: relative; z-index: 46; line-height: 0; }
+    div.title {
+      position: absolute; bottom: 10px; left: 0; right: 0; z-index: 50;
+      img { width: 120px; display: block; margin: 0 auto; position: relative; left: -5px; }
+    }
+  }
+}
+
+/* Activity Stream */
+#activity {
+  div.content {
+    ul.events {
+      padding: 0; margin: 0 0 -10px;
+      li {
+        margin: 0; padding: 10px 0; border-bottom: 1px solid (@light_grey * 0.33 + @white * 0.66);
+        list-style: none; overflow: hidden;
+        small.meta {
+          font-size: 12px; color: @light_grey; float: right;
+        }
+        a.button { float: right; margin: 0 0 10px 10px; }
+        a.avatar, a.logo, a.thumbnail {
+          height: 32px; display: block; float: left;
+          img { width: 100%; height: 100%; }
+        }
+        a.avatar, a.logo, a.icon { width: 32px; }
+        a.thumbnail { width: 42px; }
+        div.symbols {
+          float: left; overflow: hidden;
+          b {
+            display: block; float: left; margin: 10px 5px 0;
+            img { height: 12px; width: 12px; }
+          }
+          b.voted { margin: 10px 3px 0; padding: 2px; .border_radius(2); }
+          b.voted.for { background: @colour_positive * 0.33 + @white * 0.66; }
+          b.voted.against { background: @colour_negative * 0.33 + @white * 0.66; }
+        }
+        /* Temporarily removed avatar and symbol */
+/*        div.symbols a.agent, b { display: none; }*/
+        div.description {
+          font-size: 12px; color: @grey;
+          a.agent { font-weight: bold; }
+        }
+        div.comment {
+          margin-top: 2px;
+          b.tail {
+            display: block; margin: 0 0 0 10px; width: 0; height: 0; border: 5px solid transparent;
+            border-top: none; border-bottom: 5px solid (@light_grey * 0.25 + @white * 0.75);
+          }
+          blockquote {
+            margin: 0; font-style: normal; color: @dark_grey;
+            .border_radius(3); background: @light_grey * 0.25 + @white * 0.75; padding: 5px 10px;
+            span.view_comment {
+              color: @grey;
+            }
+          }
+        }
+        div.content {
+          overflow: hidden;
+        }
+      }
+      li.new_comment.ad, li.endorsed.ad, li.voted {
+        div.description, div.content { margin-left: 106px; }
+/*        div.description, div.content { margin-left: 53px; }*/
+      }
+      li.new_comment.brand, li.replied_to, li.endorsed.brand, li.connected, li.sn_setup {
+        div.description, div.content { margin-left: 96px; }
+/*        div.description, div.content { margin-left: 43px; }*/
+      }
+      li.replied_to {
+        div.content {
+          a.thumbnail, a.logo { margin-top: 7px; }
+        }
+      }
+      li.replied_to.ad {
+        div.content {
+          div.comment { margin-left: 52px; }
+        }
+      }
+      li.replied_to.brand {
+        div.content {
+          div.comment { margin-left: 42px; }
+        }
+      }
+      li.voted div.description span.action { .border_radius(2); color: @dark_grey; padding: 0 3px; white-space: nowrap; }
+      li.voted.for div.description span.action { background: @colour_positive * 0.15 + @white * 0.85; }
+      li.voted.against div.description span.action { background: @colour_negative * 0.15 + @white * 0.85; }
+      li:first-child { padding-top: 0; }
+      li:last-child { border-bottom: none; }
+      li:hover div.content div.comment blockquote span.view_comment {
+      }
+    }
+  }
+}
+
+/* Login/Register Modal */
+#login_register {
+  div.location_select,
+  div.location_search { margin-left: 130px; }
+  h3 {
+    small { font-size: 14px; font-weight: normal; display: block; color: @grey; text-align: left; margin: 0; display: block; }
+  }
+}
+
+/* Contact Form in Pages */
+#pages_controller {
+  #sidebar {
+    #contact {
+      margin: 15px 0 0;
+      form {
+        label { text-align: left; float: none; width: auto; font-size: 12px; font-weight: bold; line-height: 1; margin: 0 0 5px; }
+        p.submit.indent {
+          margin: 0;
+          span.with_cancel { display: none; }
+        }
+      }
+    }
+  }
+}
+
+/* Exclusive Offers */
+#offers {
+  div.content {
+    a.gift {
+      display: block; text-align: center;
+      img { height: 100px; }
+    }
+  }
+}
+
+div.browse {
+  margin: 0 0 20px;
+  &.class {
+    padding: 0;
+  }
+  div.header {
+    padding: 10px 10px 9px; text-align: left; background: @bg url('/images/panel_header_bg.png') repeat-x top left;
+    border-bottom: 1px solid (@bg * 0.66 + @black * 0.33); line-height: 1; height: 18px;
+    .border_radius_top(3); color: @light_grey;
+    h3 { font-size: 16px; margin: 0; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); }
+    span.filter {
+      float: left; display: block; overflow: hidden; position: relative; z-index: 5;
+      a {
+        margin: 0 1px 0 0; display: block; float: left; padding: 0 8px; height: 18px; font-weight: bold; font-size: 10px; line-height: 18px;
+        text-transform: uppercase; background: url('/images/transparent_backgrounds/black_50.png'); color: @light_grey; text-decoration: none; position: relative; z-index: 3;
+        .active {
+          background: @white; color: @black; z-index: 4;
+          :hover { color: @black; }
+        }
+        :hover { color: @white; }
+        :first-child { .border_radius_left(2); }
+        :last-child { .border_radius_right(2); margin-right: 0; }
+      }
+    }
+
+    span.filter.dropdown {
+      margin: 0; position: relative; overflow: visible;
+      a {
+        .border_radius(2); background: @white; color: @black; margin: 0; position: relative; padding-right: 25px;
+        img { float: left; margin: 4px 5px 0 0; }
+        b.arrow {
+          float: right; display: block; height: 0; width: 0; border: 5px solid transparent; border-top: 5px solid @black; border-bottom: none;
+          position: absolute; top: 6px; right: 10px;
+        }
+        :hover {
+          background: @accent_colour; color: @white;
+          b.arrow { border-top: 5px solid @white; }
+        }
+      }
+      ul {
+        position: absolute; top: 100%; left: 0; margin: 1px 0 0; padding: 0; background: @white; .border_radius(2);
+        .box_shadow(0, 1, 1, @black);
+        li {
+          list-style: none; display: block; padding: 0; margin: 0;
+          a {
+            display: block; height: 18px; line-height: 18px; color: @black; font-size: 10px; text-transform: uppercase; background: transparent;
+            border-bottom: 1px solid (@light_grey * 0.66 + @white * 0.33); float: none; margin: 0; .border_radius(0); white-space: nowrap;
+            :hover { background: url('/images/transparent_backgrounds/accent_colour_25.png'); color: @black; }
+          }
+          :last-child {
+            a { border: none; }
+          }
+        }
+      }
+    }
+    span.filter.dropdown.sort { float: left; margin: 0 0 0 10px; }
+    span.filter.dropdown.localisation { float: left; margin: 0 0 0 10px; }
+    a.more {
+      float: right; color: @white; .text_shadow(1, 1, 0, @bg * 0.66 + @black * 0.33); font-size: 14px; font-weight: bold;
+      position: relative; top: 2px;
+      :hover { text-decoration: none; }
+    }
+  }
+  > ul {
+    margin: 0; background: @white; padding: 10px 0 0 10px; .border_radius(3); position: relative;
+    li {
+      display: block; float: left; list-style: none; margin: 0 10px 10px 0; padding: 5px; position: relative;
+      background: @white; width: 130px; border: 1px solid (@light_grey * 0.33 + @white * 0.66); .border_radius(2);
+      a.remove {
+        position: absolute; height: 16px; width: 16px; padding: 3px; background: @accent_colour;
+        .border_radius(99); display: none; z-index: 3; top: -8px; right: -8px;
+        img { vertical-align: middle; }
+      }
+      div.thumbnail {
+        .border_radius_top(3); position: relative; z-index: 3;
+        .marker {
+          position: absolute; padding: 2px; .border_radius(2); z-index: 3;
+          background: url('/images/transparent_backgrounds/white_75.png'); height: 12px; width: 12px;
+        }
+        .marker.coupon {
+          height: auto; width: auto; top: 10px; right: -3px; padding: 0; background: transparent; overflow: hidden; position: absolute;
+          b {
+            display: block; height: 0; width: 0; float: left; border: 14px solid transparent; border-top: 14px solid @accent_colour;
+            border-bottom: none; border-right: none; float: left;
+          }
+          span {
+            color: @white; font-size: 10px; font-weight: bold; text-transform: uppercase; height: 14px; line-height: 14px; display: block;
+            padding: 0 4px 0 2px; background: @accent_colour; .text_shadow(1, 1, 0px, (@accent_colour * 0.75 + @black * 0.25)); margin: 0 0 0 14px;
+          }
+        }
+        .marker.video {
+          position: absolute; left: 50%; top: 50%; background: @white; width: 10px; height: 10px;
+          b { display: block; width: 0; height: 0; border: 5px solid transparent; border-left: 10px solid @black; border-right: none; }
+        }
+        .marker.endorsed_by_me { background: none; padding: 0; right: 0; bottom: -32px; .border_radius(2); background: @white; }
+        a.thumbnail {
+          display: block; overflow: hidden; position: relative; text-align: center;
+          img { position: relative; display: block; margin: auto; }
+        }
+      }
+      div.text {
+        margin: 3px 0 0; display: block;
+        a { text-decoration: none; }
+        a.title {
+          display: block; text-decoration: none; font-weight: bold; font-size: 12px; line-height: 16px;
+          white-space: nowrap; height: 16px; overflow: hidden;
+          :before {
+            display: block; height: 32px; width: 20px; content: " "; float: right; right: -15px; top: -8px;
+            background: @white; position: relative; z-index: 1; .box_shadow(-5, 0, 10, @white);
+          }
+        }
+        small {
+          font-size: 11px; line-height: 13px; color: @grey; display: block; height: 13px; overflow: hidden; white-space: nowrap;
+          a { font-weight: bold; }
+          :before {
+            display: block; height: 32px; width: 20px; content: " "; float: right; right: -15px; top: -8px;
+            background: @white; position: relative; z-index: 1; .box_shadow(-5, 0, 10, @white);
+          }
+        }
+      }
+      :hover {
+        background: @accent_colour;
+        a.remove { display: block; }
+        div.thumbnail {
+          a.marker.remove, a.marker.video {
+            b { display: inline-block; }
+          }
+          a.marker.video { .box_shadow(0, 0, 2, @black); }
+        }
+        div.text {
+          a { color: @white; }
+          a.title:before { background: @accent_colour; .box_shadow(-5, 0, 10, @accent_colour); }
+          small {
+            color: @white * 0.75 + @accent_colour * 0.25;
+            :before { background: @accent_colour; .box_shadow(-5, 0, 10, @accent_colour); }
+          }
+        }
+        div.footer a { color: @white; }
+      }
+    }
+    > li.ad div.thumbnail a.thumbnail {
+      width: 130px; height: 97px;
+      img { width: 100%; height: 100%; }
+    }
+    > li.brand div.thumbnail a.thumbnail {
+      width: 120px; height: 87px; padding: 5px; background: @white; .border_radius(2);
+      img { max-width: 120px; max-height: 87px; }
+    }
+    li.paginate {
+      margin-bottom: 0;
+      a {
+        display: block; position: relative; text-decoration: none; height: 131px;
+        div.arrow {
+          background: #81c153 url('/images/button_bg.png') repeat-x left top; border: 1px solid (@accent_colour * 0.75 + @black * 0.25);
+          height: 44px; .border_radius(99); width: 44px; margin: 0 auto; position: relative; top: 32px;
+          b { text-indent: -9000px; display: block; border: 10px solid transparent; width: 0; height: 0; position: relative; top: 12px; }
+        }
+        div.label {
+          position: absolute; bottom: 5px; left: 0; right: 0; line-height: 13px;
+          color: @accent_colour * 0.85 + @black * 0.15; text-decoration: none;
+          font-weight: bold; font-size: 12px; text-align: center;
+        }
+        :hover {
+          div.arrow { background: #abd56e url('/images/button_bg.png') repeat-x left -44px; }
+        }
+      }
+      :hover { background: transparent; }
+    }
+    li.paginate.previous a div b { border-right: 15px solid @white; border-left: none; left: 12px; }
+    li.paginate.next a div b { border-left: 15px solid @white; border-right: none; left: 16px; }
+  }  
+  > div.footer {
+    padding: 9px 10px 10px; background: @light_grey * 0.75 + @white * 0.25; overflow: hidden;
+    border-top: 1px solid @light_grey; .border_radius_bottom(3);
+    div.info {
+      float: left; color: @grey;
+      strong { color: @black; font-weight: normal; }
+    }
+    div.pagination {
+      float: right;
+      > * {
+        display: inline-block; line-height: 1; padding: 0 6px; line-height: 18px; height: 18px; background: @white;
+        .border_radius(3); text-decoration: none; font-weight: bold;
+        font-size: 10px; text-transform: uppercase;
+      }
+      a { color: @grey; }
+      a:hover { color: @black; }
+      span.disabled { color: @light_grey; }
+      span.current { color: @white; background: @bg; border: none; }
+      span.current:hover { color: @white; }
+    }
+  }
+}
+div.browse.with_categories { margin: 0 0 0 160px; }
+div.browse.with_options > ul { .border_radius_top(0); }
+div.browse.with_footer > ul { .border_radius_bottom(0); }
+/* Browse List */
+div.browse.list {
+> ul {
+    margin: 0; min-height: 320px;
+    padding: 10px 0 0 10px; overflow: hidden;
+    > li {
+      display: block; list-style: none; margin: 0 10px 10px 0; padding: 5px;
+      .border_radius(3); position: relative; line-height: normal;
+      .marker {
+        position: absolute; padding: 2px; .border_radius(2);
+        background: url('/images/transparent_backgrounds/white_75.png');
+        img { height: 12px; width: 12px; }
+      }
+      img.marker { height: 12px; width: 12px; }
+      span.marker.new {
+        color: black; left: -5px; top: -5px; background: none; background-color: @white * 0.1 + @yellow * 0.6 + @red * 0.3; line-height: 1; padding: 2px 5px;
+        font-weight: bold;
+      }
+      a.marker.media_type {
+        display: inline-block; text-decoration: none; top: 39px; left: 8px;
+        font-size: 10px;
+        b { font-weight: normal; margin: 0 0 0 2px; line-height: 1; display: none; }
+        img { vertical-align: middle; }
+      }
+      a.thumbnail {
+        float: left;
+        width: 68px; display: block; overflow: hidden;
+        border: 1px solid @light_grey;
+        :hover { border-color: @accent_colour; }
+      }
+      span.title_brand {
+        display: block; margin: 0 0 2px 75px;
+        a { margin: 0; display: inline; }
+        a.brand_name { font-weight: normal; font-size: 12px; }
+      }
+      a.ad_title {
+        font-weight: bold; font-size: 14px; margin: 0 0 0 75px; display: block;
+      }
+      a.brand_name {
+        font-weight: bold; font-size: 14px; margin: 0 0 0 75px; display: block;
+      }
+      small {
+        display: block; color: @grey; margin: 0 0 0 75px; font-size: 12px;
+      }
+      small.brand_name { display: inline; margin: 0; }
+      ul.chart {
+        margin: 0 0 0 80px;
+        height: 39px;
+      }
+      ul.networks {
+        margin: 3px 0 0 75px; padding: 0; overflow: hidden;
+        li { display: block; float: left; margin: 0 5px 0 0; line-height: 1; }
+      }
+      div.points {
+        display: none;
+        font-size: 12px; text-align: right;
+        label { color: @grey; }
+      }
+      a.remove { bottom: -3px; right: -3px; }
+    }
+    li.ad {
+      a.thumbnail { height: 51px; }
+      span.title_brand {
+        small.brand_name {
+          display: block;
+        }
+      }
+    }
+    li.brand {
+      a.thumbnail { height: 68px; }
+    }
+  }
+}
+div.browse.list.with_options ul { .border_radius_top(0); }
+div.browse.list.with_footer ul { .border_radius_bottom(0); }
+div.browse.list.cols_2 {
+  > ul {
+    > li {
+      width: 285px; float: left;
+      :hover {
+        background: @white;
+      }
+    }
+  }
+}
+div.browse.ads.list {
+  > ul {
+    > li {
+      height: 53px;
+      a.thumbnail {
+        height: 51px;
+      }
+    }
+  }
+}
+div.browse.brands.list {
+  > ul {
+    > li {
+      height: 68px;
+      a.thumbnail {
+        height: 66px;
+      }
+    }
+  }
+}
+
+/* Categories List */
+#categories {
+  margin: 40px 0 0; width: 160px; float: left; position: relative; z-index: 1;
+  ul {
+    margin: 0; padding: 10px 0 0;
+    li {
+      list-style: none; margin: 0; padding: 0; font-size: 14px;
+      a { color: @grey; display: block; padding: 5px 10px 5px 15px; text-decoration: none; .border_radius_left(3); }
+      a:hover { color: @black; background: @light_grey * 0.15 + @white * 0.85; }
+    }
+    .all a { font-weight: bold; }
+    .current a {
+      background: @white; color: @black; border: 1px solid (@light_grey * 0.25 + @white * 0.75); border-right: none; border-left: 5px solid @bg; 
+      padding-left: 10px;
+    }
+  }
+}
+
+/* Ads > Show */
+#ad {
+  div.header {
+    overflow: hidden;
+    h3 { font-size: 16px; margin: 0 0 3px; }
+    small {
+      a.category { font-weight: bold; color: @accent_colour; }
+      span.networks img { position: relative; top: 3px; }
+    }
+    span.brand {
+      float: right; color: @white;
+      a.brand_name { font-weight: bold; color: @accent_colour; }
+    }
+  }
+  div.content {
+    padding: 0; position: relative;
+    a.toggle_size {
+      display: block; .border_radius(3); background-color: @black; padding: 0 5px 0 26px;
+      background-position: 5px center; background-repeat: no-repeat; text-decoration: none; margin: 5px 5px 0 0;
+      position: absolute; top: 0; right: 0; line-height: 25px; z-index: 45;
+    }
+    img.creative { margin: 0 auto; max-width: 540px; display: block; }
+    object { position: relative; z-index: 44; }
+    object.video { line-height: 0; font-size: 0; }
+    object embed { position: relative; z-index: 45; line-height: 0; font-size: 0; }
+  }
+  div.content.not_video {
+    padding: 40px; text-align: center;
+    * { margin-left: auto; margin-right: auto; }
+    object.flash { margin-bottom: 0; }
+  }
+  div.footer {
+    padding: 0;
+    div.vote_views {
+      padding: 5px 10px; overflow: hidden;
+      div.share { float: right; margin: 2px 0 0 0; }
+      #login_register_msg, #encourage_vote_msg { line-height: 22px; font-weight: bold; color: @black; }
+    }
+  }
+}
+#sidebar {
+  #meta {
+    table {
+      margin: 0;
+      tr:last-child td { padding-bottom: 0; }
+      td {
+        padding: 0 0 5px;
+        ul.networks {
+          margin: 0; padding: 0;
+          li {
+            list-style: none; display: inline;
+          }
+          li {
+          }
+        }
+      }
+      td.label { color: @grey; white-space: nowrap; width: 1%; text-align: right; padding-right: 5px; }
+    }
+  }
+}
+
+/* Voting */
+div.voted {
+  font-size: 12px; line-height: 22px; color: @black; display: inline-block; font-weight: bold;
+  img { float: left; margin-right: 5px; padding: 3px; .border_radius(3); }
+}
+#voted_up {
+  img { background: @colour_positive * 0.66 + @bg * 0.15; }
+}
+#voted_down {
+  img { background: @colour_negative * 0.66 + @bg * 0.15; }
+}
+#encourage_comment {
+  display: inline-block; line-height: 22px; font-weight: bold;
+}
+#vote {
+  overflow: hidden; font-size: 12px; line-height: 22px; color: @black; float: left;
+  a {
+    color: @white; font-weight: bold; overflow: hidden; display: block;
+    width: 16px; text-decoration: none; text-align: center; font-size: 10px; padding: 3px; text-transform: uppercase;
+  }
+  a.up {
+    float: left; background: @colour_positive * 0.66 + @bg * 0.15; .border_radius_left(3);
+    :hover { background: @colour_positive * 0.85 + @bg * 0.15; }
+  } 
+  a.down {
+    float: left; background: @colour_negative * 0.66 + @bg * 0.15; .border_radius_right(3);
+    margin: 0 5px 0 1px;
+    :hover { background: @colour_negative * 0.85 + @bg * 0.15; }
+  }
+}
+#vote.disabled {
+  a.up {
+    background: (@colour_positive * 0.66 + @bg * 0.15) * 0.15 + @grey * 0.85;
+    :hover { background: (@colour_positive * 0.85 + @bg * 0.15) * 0.25 + @grey * 0.75; }
+  }
+  a.down {
+    background: (@colour_negative * 0.66 + @bg * 0.15) * 0.15 + @grey * 0.85;
+    :hover { background: (@colour_negative * 0.85 + @bg * 0.15) * 0.25 + @grey * 0.75; }
+  }
+}
+#sidebar {
+  #ads > ul li, #recommendations > ul li {
+    width: 81px;
+    div.thumbnail {
+      a.thumbnail { height: 60px; width: 81px; }
+    }
+    div.text {
+      a.title { font-size: 11px; height: 14px; line-height: 14px; }
+      small { display: none; }
+    }
+  }
+  #brands > ul li {
+    width: 55px;
+    div.thumbnail {
+      a.thumbnail {
+        height: 45px; width: 45px;
+        img { max-height: 45px; max-width: 45px; }
+      }
+    }
+    div.text { display: none; }
+  }
+}
+
+/* My Account */
+#accounts_controller {
+  #top {
+    #page_title {
+      #page_options {
+        a.button.public_profile {
+          float: right; font-size: 16px; line-height: 1; height: auto; padding: 8px 35px 8px 15px; position: relative;
+          b.arrow { display: block; height: 0; width: 0; position: absolute; top: 10px; right: 15px; border: 6px solid transparent; border-right: none; border-left: 6px solid @white; margin: 0; }
+        }
+        a.button.goto_dashboard {
+          float: right; font-size: 16px; line-height: 1; height: auto; padding: 8px 15px 8px 35px; margin-right: 5px; position: relative;
+          b.arrow { display: block; height: 0; width: 0; position: absolute; top: 10px; left: 15px; border: 6px solid transparent; border-left: none; border-right: 6px solid @white; margin: 0; }
+        }
+      }
+    }
+  }
+  #account_nav {
+    float: left; width: 200px; margin: 0 20px 0 0;
+    ul.nav {
+      margin: 0; padding: 0;
+      li {
+        margin: 0 0 5px; display: block; list-style: none; padding: 0;
+        a {
+          display: block; height: 30px; text-decoration: none; color: @white;
+          b {
+            border: 15px solid transparent; border-right: none; border-left: 10px solid transparent; width: 0;
+            height: 0; float: right; display: none;
+          }
+          span {
+            .border_radius(3); background: @bg; display: block; 
+            line-height: 30px; padding: 0 10px; font-size: 14px; font-weight: bold; margin: 0 10px 0 0;
+          }
+        }
+        :hover {
+          a {
+            color: @white;
+            b { border-left-color: @bg; display: block; }
+            span { background: @bg; .border_radius_right(0); }
+          }
+        }
+      }
+      li.current a {
+        b { border-left-color: @accent_colour; display: block; }
+        span { background: @accent_colour; color: @white; .border_radius_right(0); }
+      }
+    }
+  }
+  #main {
+    > div {
+      margin: 0 0 20px;
+      form { margin: 0; }
+    }
+    #profile {
+      a.avatar {
+        float: left; display: block;
+        width: 70px; overflow: hidden; position: relative; text-decoration: none;
+        img { width: 100%; }
+        span {
+          display: block; line-height: 1; padding: 3px; margin: 5px 0 0; color: @white; background: @accent_colour;
+          .border_radius(3); .text_shadow(1, 1, 0, @grey);
+          text-align: center; font-size: 10px; font-weight: bold; text-transform: uppercase;
+        }
+      }
+      form {
+        margin: 0 0 0 90px;
+        h4 { margin: 10px 0 20px; border-bottom: 1px solid (@light_grey * 0.5 + @white * 0.5); padding: 0; color: @bg; font-size: 16px; }
+        ul.choices {
+          li { width: 30%; }
+        }
+        div.extra { margin-top: 20px; }
+      }
+    }
+
+    #networks {
+      ul { margin: 0 -10px -10px 0; padding: 0; overflow: hidden;
+        li:hover
+        {
+          background: @light_grey; display: block; float: left; width: 180px;
+          padding: 10px; margin: 0 10px 10px 0; list-style: none; .border_radius(3);
+          position: relative;
+          * { line-height: normal; }
+          img { vertical-align: middle; float: left; }
+          .name { font-weight: bold; font-size: 14px; display: block; margin: -2px 0 0 42px; }
+          small {
+            font-size: 12px; color: @grey; display: block; margin-left: 42px; 
+            strong { color: @black; font-weight: normal; }
+          }
+          :hover {
+          }
+        }
+        li.installed {
+          background: @white;
+          border: 2px solid @accent_colour; padding: 8px;
+        }
+        li.unavailable {
+          .name { color: @black; }
+          :hover {
+            background: @light_grey;
+          }
+        }
+        li:hover {
+          background: @light_grey * 0.5 + @white * 0.5;
+        }
+      }
+    }
+  }
+}
+
+/* Shopping Style Panel */
+#shopping_style {
+  div.header a.button.small { float: right; }
+  div.content {
+    p {
+      margin: 0 0 10px;
+      label { text-transform: uppercase; font-size: 11px; display: block; color: @bg; font-weight: bold; }
+      span { color: @black; }
+      span.toggle { white-space: nowrap; color: @grey; }
+      :last-child { margin: 0; }
+    }
+    p.more { text-align: left; font-weight: normal; }
+    p.less { display: none; margin: 0; }
+  }
+}
+
+/* People Controller */
+#people_controller.index {
+  #main {
+    div.panel {
+      float: left; width: 300px; margin: 0 20px 0 0;
+      :last-child { margin-right: 0; }
+    }
+  }
+}
+#people_controller.show {
+  #person_overview, #shopping_style {
+    a.button.small {
+    }
+  }
+  #content {
+    #shopping_style {
+      float: left; width: 240px; margin: 0 20px 0 0;
+    }
+    #main { width: 360px; }
+  }
+}
+
+/* Search Results */
+#search_results {
+  margin: 0 0 20px;
+  li {
+    :hover {
+      small { color: @white * 0.75 + @accent_colour * 0.25; }
+    }
+  }
+}
+#search {
+  div.content {
+    padding: 20px;
+    form {
+      margin: 0; float: none;
+      span.submit_and_options {
+        display: block;
+      }
+    }
+    p { margin: 0 0 15px; }
+    h4 { font-weight: normal; margin: 0 0 5px; }
+  }
+}
+
+/* Recommendations */
+#recommendations {
+  div.browse {
+    margin: 0; padding: 0; background: none;
+    ul { min-height: 0; .border_radius(0); }
+  }
+}
+
+/* Blank States */
+div.blank {
+  padding: 20px; background: @bg * 0.05 + @blue * 0.05 + @white * 0.9; position: relative;
+  border: 1px solid (@bg * 0.1 + @blue * 0.1 + @white * 0.8); z-index: 1;
+  h4 { font-size: 18px; margin: 0 0 10px; }
+  h4:last-child { margin: 0; }
+  p { font-size: 16px; margin: 0 0 10px; }
+  p:last-child { margin: 0; }
+  p.with_list_number.large {
+    span { margin-left: 48px; display: block; color: @white; }
+  }
+  p.earn span { font-size: 22px; color: @white; line-height: 48px; font-weight: bold; }
+  a { white-space: nowrap; }
+  a.hide {
+    position: absolute; top: -5px; right: -5px; display: block; height: 16px; width: 16px; padding: 3px; background: #E7E9F6; .border_radius(99);
+  }
+}
+
+div.blank.small {
+  padding: 10px 20px; 
+  h4 { font-weight: normal; font-size: 16px; }
+  p { margin: 0; }
+}
+div.blank.tiny {
+  padding: 10px 20px;
+  h4 { font-weight: normal; font-size: 14px; }
+  p { margin: 0; font-size: 12px; }
+}
+div.blank.rounded {
+  .border_radius(3); margin: 0 0 20px;
+}
+div.blank.rounded.bottom { .border_radius_top(0); }
+div.blank.with_border_bottom { border-bottom: 1px solid (@bg * 0.1 + @blue * 0.1 + @white * 0.8); }
+div.blank.no_border_top { border-top: none; }
+div.blank.no_border_bottom { border-bottom: none; }
+div.blank.no_side_borders { border-right: none; border-left: none; }
+div.panel {
+  div.blank {
+    padding: 10px 20px; overflow: hidden; margin: 0;
+    h4 { font-weight: normal; font-size: 14px; }
+    p, ul { margin: 0 0 10px; font-size: 12px; }
+    p:last-child, ul:last-child { margin: 0; }
+  }
+}
+
+#yelow {
+  #short {
+    color: #fea;
+  }
+  #long {
+    color: #ffeeaa;
+  }
+  #rgba {
+    color: rgba(255, 238, 170, 0.1);
+  }
+}
+
+#blue {
+  #short {
+    color: #00f;
+  }
+  #long {
+    color: #0000ff;
+  }
+  #rgba {
+    color: rgba(0, 0, 255, 0.1);
+  }
+}
+
+#overflow {
+  .a { color: #111111 - #444444; } // #000000
+  .b { color: #eee + #fff; } // #ffffff
+  .c { color: #aaa * 3; } // #ffffff
+  .d { color: #00ee00 + #009900; } // #00ff00
+}
+
+#grey {
+  color: rgb(200, 200, 200);
+}
+
+#808080 {
+  color: hsl(50, 0%, 50%);
+}
+
+#00ff00 {
+  color: hsl(120, 100%, 50%);
+}
+/******************\
+*                  *
+*  Comment Header  *
+*                  *
+\******************/
+
+/*
+
+    Comment
+
+*/
+
+/*  
+ * Comment Test
+ * 
+ * - cloudhead (http://cloudhead.net)
+ *
+ */
+
+////////////////
+ at var: "content";
+////////////////
+
+/* Colors
+ * ------
+ *   #EDF8FC (background blue)
+ *   #166C89 (darkest blue)
+ *
+ * Text:
+ *   #333 (standard text) // A comment within a comment!
+ *   #1F9EC9 (standard link)
+ *
+ */
+
+/* @group Variables
+------------------- */
+#comments /* boo */ {
+  /**/ // An empty comment 
+  color: red; /* A C-style comment */
+  background-color: orange; // A little comment
+  font-size: 12px;
+  
+  /* lost comment */ content: @var;
+  
+  border: 1px solid black;
+  
+  // padding & margin //
+  padding: 0;
+  margin: 2em;
+} //
+
+/* commented out
+  #more-comments {
+    color: grey;
+  }
+*/
+
+#last { color: blue }
+//
+.comma-delimited { 
+  background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+  text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
+  -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset,
+    0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
+}
+ at font-face {
+  font-family: Headline;
+  src: local(Futura-Medium),
+       url(fonts.svg#MyGeometricModern) format("svg");
+}
+.other {
+  -moz-transform: translate(0, 11em) rotate(-90deg);
+}
+p:not([class*="lead"]) {
+  color: black; 
+}
+
+input[type="text"].class#id[attr=32]:not(1) {
+  color: white;
+}
+
+div#id.class[a=1][b=2].class:not(1) {
+  color: white;
+}
+
+ul.comma > li:not(:only-child)::after { 
+  color: white;
+}
+
+ol.comma > li:nth-last-child(2)::after {
+  color: white;
+}
+
+li:nth-child(4n+1),
+li:nth-child(-5n),
+li:nth-child(-n+2) {
+  color: white;
+}
+
+a[href^="http://"] {
+  color: black;
+}
+
+a[href$="http://"] {
+  color: black;
+}
+
+form[data-disabled] {
+  color: black;
+}
+
+p::before {
+  color: black;
+}
+ at charset "utf-8";
+div { color: black; }
+div { width: 99%; }
+
+* {
+  min-width: 45em;
+}
+
+h1, h2 > a > p, h3 {
+  color: none;
+}
+
+div.class {
+  color: blue;
+}
+
+div#id {
+  color: green;
+}
+
+.class#id {
+  color: purple;
+}
+
+.one.two.three {
+  color: grey;
+}
+
+ at media print {
+  font-size: 3em;
+}
+
+ at media screen {
+  font-size: 10px;
+}
+
+ at font-face {
+  font-family: 'Garamond Pro';
+  src: url("/fonts/garamond-pro.ttf");
+}
+
+a:hover, a:link {
+  color: #999;
+}
+
+p, p:first-child {
+  text-transform: none;
+}
+
+q:lang(no) {
+  quotes: none;
+}
+
+p + h1 {
+  font-size: 2.2em;
+}
+
+#shorthands {
+  border: 1px solid #000;
+  font: 12px/16px Arial;
+  margin: 1px 0;
+  padding: 0 auto;
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+
+#more-shorthands {
+  margin: 0;
+  padding: 1px 0 2px 0;
+  font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; 
+}
+
+.misc {
+  -moz-border-radius: 2px;
+  display: -moz-inline-stack;
+  width: .1em;
+  background-color: #009998;
+  background-image: url(images/image.jpg);
+  background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
+  margin: ;
+}
+
+#important {
+  color: red !important;
+  width: 100%!important;
+  height: 20px ! important;
+}
+
+#functions {
+  @var: 10;
+  color: color("evil red"); // #660000
+  width: increment(15);
+  height: undefined("self");
+  border-width: add(2, 3);
+  variable: increment(@var);
+}
+
+#built-in {
+  @r: 32;
+  escaped: e("-Some::weird(#thing, y)");
+  lighten: lighten(#ff0000, 50%);
+  darken: darken(#ff0000, 50%);
+  saturate: saturate(#29332f, 20%);
+  desaturate: desaturate(#203c31, 20%);
+  greyscale: greyscale(#203c31);
+  format: %("rgb(%d, %d, %d)", @r, 128, 64);
+  format-string: %("hello %s", "world");
+  eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64));
+}
+
+ at var: @a;
+ at a: 100%;
+
+.lazy-eval {
+  width: @var;
+}
+.mixin (@a: 1px, @b: 50%) {
+  width: @a * 5;
+  height: @b - 1%;
+}
+
+.mixina (@style, @width, @color: black) {
+    border: @width @style @color;
+}
+
+.mixiny
+(@a: 0, @b: 0) {
+  margin: @a;
+  padding: @b;
+}
+
+.hidden() {
+  color: transparent;
+}
+
+.two-args {
+  color: blue;
+  .mixin(2px, 100%);
+  .mixina(dotted, 2px);
+}
+
+.one-arg {
+  .mixin(3px);
+}
+
+.no-parens {
+  .mixin;
+}
+
+.no-args {
+  .mixin();
+}
+
+.var-args {
+  @var: 9;
+  .mixin(@var, @var * 2);
+}
+
+.multi-mix {
+  .mixin(2px, 30%);
+  .mixiny(4, 5);
+}
+
+.maxa(@arg1: 10, @arg2: #f00) {
+  padding: @arg1 * 2px;
+  color: @arg2;
+}
+
+body {
+  .maxa(15);
+}
+
+ at glob: 5;
+.global-mixin(@a:2) {
+  width: @glob + @a;
+}
+
+.scope-mix {
+  .global-mixin(3);
+}
+
+.nested-ruleset (@width: 200px) {
+    width: @width;
+    .column { margin: @width; }
+}
+.content {
+    .nested-ruleset(600px);
+}
+
+//
+
+.same-var-name2(@radius) {
+  radius: @radius;
+}
+.same-var-name(@radius) {
+  .same-var-name2(@radius);
+}
+#same-var-name {
+  .same-var-name(5px);
+}
+
+//
+
+.var-inside () {
+    @var: 10px;
+    width: @var;
+}
+#var-inside { .var-inside; }
+.mix-inner (@var) {
+  border-width: @var;
+}
+
+.mix (@a: 10) {
+  .inner {
+    height: @a * 10;
+
+    .innest {
+      width: @a;  
+      .mix-inner(@a * 2);
+    }  
+  }
+}
+
+.class {
+  .mix(30);
+}
+.mixin () {
+    zero: 0;
+}
+.mixin (@a: 1px) {
+    one: 1;
+}
+.mixin (@a) {
+    one-req: 1;
+}
+.mixin (@a: 1px, @b: 2px) {
+    two: 2;
+}
+
+.mixin (@a, @b, @c) {
+    three-req: 3;
+}
+
+.mixin (@a: 1px, @b: 2px, @c: 3px) {
+    three: 3;
+}
+
+.zero {
+    .mixin();
+}
+
+.one {
+    .mixin(1);
+}
+
+.two {
+    .mixin(1, 2);
+}
+
+.three {
+    .mixin(1, 2, 3);
+}
+
+//
+
+.mixout ('left') {
+    left: 1;
+}
+
+.mixout ('right') {
+    right: 1;
+}
+
+.left {
+    .mixout('left');
+}
+.right {
+    .mixout('right');
+}
+
+//
+
+.border (@side, @width) {
+    color: black;
+    .border-side(@side, @width);
+}
+.border-side (left, @w) {
+    border-left: @w;
+}
+.border-side (right, @w) {
+    border-right: @w;
+}
+
+.border-right {
+    .border(right, 4px);
+}
+.border-left {
+    .border(left, 4px);
+}
+
+//
+
+
+.border-radius (@r) {
+    both: @r * 10;
+}
+.border-radius (@r, left) {
+    left: @r;
+}
+.border-radius (@r, right) {
+    right: @r;
+}
+
+.only-right {
+    .border-radius(33, right);
+}
+.only-left {
+    .border-radius(33, left);
+}
+.left-right {
+    .border-radius(33);
+}
+.mixin { border: 1px solid black; }
+.mixout { border-color: orange; }
+.borders { border-style: dashed; }
+
+#namespace {
+  .borders {
+    border-style: dotted;
+  }
+  .biohazard {
+    content: "death";
+    .man {
+      color: transparent;
+    }
+  }
+}
+#theme {
+  > .mixin {
+    background-color: grey;
+  }
+}
+#container {
+  color: black;
+  .mixin;
+  .mixout;
+  #theme > .mixin;
+}
+
+#header {
+  .milk {
+    color: white;
+    .mixin;
+    #theme > .mixin;
+  }
+  #cookie {
+    .chips {
+      #namespace .borders;
+      .calories {
+        #container;
+      }
+    }
+    .borders;
+  }
+}
+.secure-zone { #namespace .biohazard .man; }
+.direct {
+  #namespace > .borders;
+}
+#operations {
+  color: #110000 + #000011 + #001100; // #111111
+  height: 10px / 2px + 6px - 1px * 2; // 9px
+  width: 2 * 4 - 5em; // 3em
+  .spacing {
+    height: 10px / 2px+6px-1px*2;
+    width: 2  * 4-5em;
+  }
+  substraction: 20 - 10 - 5 - 5; // 0
+  division: 20 / 5 / 4; // 1
+}
+
+ at x: 4;
+ at y: 12em;
+
+.with-variables {
+  height: @x + @y; // 16em
+  width: 12 + @y; // 24em
+  size: 5cm - @x; // 1cm
+}
+
+ at z: -2;
+
+.negative {
+  height: 2px + @z; // 0px
+  width: 2px - @z; // 4px
+}
+
+.shorthands {
+  padding: -1px 2px 0 -4px; //
+}
+
+.colors {
+  color: #123; // #112233
+  border-color: #234 + #111111; // #334455
+  background-color: #222222 - #fff; // #000000
+  .other {
+    color: 2 * #111; // #222222
+    border-color: #333333 / 3 + #111; // #222222
+  }
+}
+.parens {
+  @var: 1px;
+  border: (@var * 2) solid black;
+  margin: (@var * 1) (@var + 2) (4 * 4) 3;
+  width: (6 * 6);
+  padding: 2px (6px * 6px);
+}
+
+.more-parens {
+  @var: (2 * 2);
+  padding: (2 * @var) 4 4 (@var * 1px);
+  width: (@var * @var) * 6;
+  height: (7 * 7) + (8 * 8);
+  margin: 4 * (5 + 5) / 2 - (@var * 2);
+  //margin: (6 * 6)px;
+}
+
+.nested-parens {
+  width: 2 * (4 * (2 + (1 + 6))) - 1;
+  height: ((2+3)*(2+3) / (9-4)) + 1;
+}
+
+.mixed-units {
+  margin: 2px 4em 1 5pc;
+  padding: (2px + 4px) 1em 2px 2;
+}
+#first > .one {
+  > #second .two > #deux {
+    width: 50%;
+    #third {
+      &:focus {
+        color: black;
+        #fifth {
+          > #sixth {
+            .seventh #eighth {
+              + #ninth {
+                color: purple;
+              }
+            }
+          }
+        }
+      }
+      height: 100%;
+    }
+    #fourth, #five, #six {
+      color: #110000;
+      .seven, .eight > #nine {
+        border: 1px solid black;
+      }
+      #ten {
+        color: red;
+      }
+    }
+  }
+  font-size: 2em;
+}
+ at x: blue;
+ at z: transparent;
+ at mix: none;
+
+.mixin {
+  @mix: #989;
+}
+
+.tiny-scope {
+  color: @mix; // #989
+  .mixin;
+}
+
+.scope1 {
+  @y: orange;
+  @z: black;
+  color: @x; // blue
+  border-color: @z; // black
+  .hidden {
+    @x: #131313;
+  }
+  .scope2 {
+    @y: red;
+    color: @x; // blue
+    .scope3 {
+      @local: white;
+      color: @y; // red
+      border-color: @z; // black
+      background-color: @local; // white
+    }
+  }
+}h1, h2, h3 {
+  a, p {
+    &:hover {
+      color: red;
+    }
+  }
+}
+
+#all { color: blue; }
+#the { color: blue; }
+#same { color: blue; }
+
+ul, li, div, q, blockquote, textarea {
+  margin: 0;
+}
+
+td {
+  margin: 0;
+  padding: 0;
+}
+
+td, input {
+  line-height: 1em;
+}
+#strings {
+  background-image: url("http://son-of-a-banana.com");
+  quotes: "~" "~";
+  content: "#*%:&^,)!.(~*})";
+  empty: "";
+  brackets: "{" "}";
+}
+#comments {
+  content: "/* hello */ // not-so-secret";
+}
+#single-quote {
+  quotes: "'" "'";
+  content: '""#!&""';
+  empty: '';
+}
+ at a: 2;
+ at x: @a * @a;
+ at y: @x + 1;
+ at z: @x * 2 + @y;
+
+.variables {
+  width: @z + 1cm; // 14cm
+}
+
+ at b: @a * 10;
+ at c: #888;
+
+ at fonts: "Trebuchet MS", Verdana, sans-serif;
+ at f: @fonts;
+
+ at quotes: "~" "~";
+ at q: @quotes;
+
+.variables {
+  height: @b + @x + 0px; // 24px
+  color: @c;
+  font-family: @f;
+  quotes: @q;
+}
+
+.redefinition {
+    @var: 4;
+    @var: 2;
+    @var: 3;
+    three: @var;
+}
+
+.values {
+    @a: 'Trebuchet';
+    font-family: @a, @a, @a;
+}
+
+
+.whitespace
+  { color: white; }  
+  
+.whitespace
+{
+  color: white;
+}
+  .whitespace
+{ color: white; }
+
+.whitespace{color:white;}  
+.whitespace { color : white ; }
+
+.white,
+.space,
+.mania
+{ color: white; }
+
+.no-semi-column { color: white }
+.no-semi-column {
+  color: white;
+  white-space: pre
+}
+.no-semi-column {border: 2px solid white}
+.newlines {
+  background: the,
+              great,
+              wall;
+  border: 2px
+          solid
+          black;
+}
+.empty {
+  
+}
+#yelow {
+  #short {
+    color: #fea;
+  }
+  #long {
+    color: #ffeeaa;
+  }
+  #rgba {
+    color: rgba(255, 238, 170, 0.1);
+  }
+}
+
+#blue {
+  #short {
+    color: #00f;
+  }
+  #long {
+    color: #0000ff;
+  }
+  #rgba {
+    color: rgba(0, 0, 255, 0.1);
+  }
+}
+
+#overflow {
+  .a { color: #111111 - #444444; } // #000000
+  .b { color: #eee + #fff; } // #ffffff
+  .c { color: #aaa * 3; } // #ffffff
+  .d { color: #00ee00 + #009900; } // #00ff00
+}
+
+#grey {
+  color: rgb(200, 200, 200);
+}
+
+#808080 {
+  color: hsl(50, 0%, 50%);
+}
+
+#00ff00 {
+  color: hsl(120, 100%, 50%);
+}
+/******************\
+*                  *
+*  Comment Header  *
+*                  *
+\******************/
+
+/*
+
+    Comment
+
+*/
+
+/*  
+ * Comment Test
+ * 
+ * - cloudhead (http://cloudhead.net)
+ *
+ */
+
+////////////////
+ at var: "content";
+////////////////
+
+/* Colors
+ * ------
+ *   #EDF8FC (background blue)
+ *   #166C89 (darkest blue)
+ *
+ * Text:
+ *   #333 (standard text) // A comment within a comment!
+ *   #1F9EC9 (standard link)
+ *
+ */
+
+/* @group Variables
+------------------- */
+#comments /* boo */ {
+  /**/ // An empty comment 
+  color: red; /* A C-style comment */
+  background-color: orange; // A little comment
+  font-size: 12px;
+  
+  /* lost comment */ content: @var;
+  
+  border: 1px solid black;
+  
+  // padding & margin //
+  padding: 0;
+  margin: 2em;
+} //
+
+/* commented out
+  #more-comments {
+    color: grey;
+  }
+*/
+
+#last { color: blue }
+//
+.comma-delimited { 
+  background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+  text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
+  -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset,
+    0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
+}
+ at font-face {
+  font-family: Headline;
+  src: local(Futura-Medium),
+       url(fonts.svg#MyGeometricModern) format("svg");
+}
+.other {
+  -moz-transform: translate(0, 11em) rotate(-90deg);
+}
+p:not([class*="lead"]) {
+  color: black; 
+}
+
+input[type="text"].class#id[attr=32]:not(1) {
+  color: white;
+}
+
+div#id.class[a=1][b=2].class:not(1) {
+  color: white;
+}
+
+ul.comma > li:not(:only-child)::after { 
+  color: white;
+}
+
+ol.comma > li:nth-last-child(2)::after {
+  color: white;
+}
+
+li:nth-child(4n+1),
+li:nth-child(-5n),
+li:nth-child(-n+2) {
+  color: white;
+}
+
+a[href^="http://"] {
+  color: black;
+}
+
+a[href$="http://"] {
+  color: black;
+}
+
+form[data-disabled] {
+  color: black;
+}
+
+p::before {
+  color: black;
+}
+ at charset "utf-8";
+div { color: black; }
+div { width: 99%; }
+
+* {
+  min-width: 45em;
+}
+
+h1, h2 > a > p, h3 {
+  color: none;
+}
+
+div.class {
+  color: blue;
+}
+
+div#id {
+  color: green;
+}
+
+.class#id {
+  color: purple;
+}
+
+.one.two.three {
+  color: grey;
+}
+
+ at media print {
+  font-size: 3em;
+}
+
+ at media screen {
+  font-size: 10px;
+}
+
+ at font-face {
+  font-family: 'Garamond Pro';
+  src: url("/fonts/garamond-pro.ttf");
+}
+
+a:hover, a:link {
+  color: #999;
+}
+
+p, p:first-child {
+  text-transform: none;
+}
+
+q:lang(no) {
+  quotes: none;
+}
+
+p + h1 {
+  font-size: 2.2em;
+}
+
+#shorthands {
+  border: 1px solid #000;
+  font: 12px/16px Arial;
+  margin: 1px 0;
+  padding: 0 auto;
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+
+#more-shorthands {
+  margin: 0;
+  padding: 1px 0 2px 0;
+  font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; 
+}
+
+.misc {
+  -moz-border-radius: 2px;
+  display: -moz-inline-stack;
+  width: .1em;
+  background-color: #009998;
+  background-image: url(images/image.jpg);
+  background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
+  margin: ;
+}
+
+#important {
+  color: red !important;
+  width: 100%!important;
+  height: 20px ! important;
+}
+
+#functions {
+  @var: 10;
+  color: color("evil red"); // #660000
+  width: increment(15);
+  height: undefined("self");
+  border-width: add(2, 3);
+  variable: increment(@var);
+}
+
+#built-in {
+  @r: 32;
+  escaped: e("-Some::weird(#thing, y)");
+  lighten: lighten(#ff0000, 50%);
+  darken: darken(#ff0000, 50%);
+  saturate: saturate(#29332f, 20%);
+  desaturate: desaturate(#203c31, 20%);
+  greyscale: greyscale(#203c31);
+  format: %("rgb(%d, %d, %d)", @r, 128, 64);
+  format-string: %("hello %s", "world");
+  eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64));
+}
+
+ at var: @a;
+ at a: 100%;
+
+.lazy-eval {
+  width: @var;
+}
+.mixin (@a: 1px, @b: 50%) {
+  width: @a * 5;
+  height: @b - 1%;
+}
+
+.mixina (@style, @width, @color: black) {
+    border: @width @style @color;
+}
+
+.mixiny
+(@a: 0, @b: 0) {
+  margin: @a;
+  padding: @b;
+}
+
+.hidden() {
+  color: transparent;
+}
+
+.two-args {
+  color: blue;
+  .mixin(2px, 100%);
+  .mixina(dotted, 2px);
+}
+
+.one-arg {
+  .mixin(3px);
+}
+
+.no-parens {
+  .mixin;
+}
+
+.no-args {
+  .mixin();
+}
+
+.var-args {
+  @var: 9;
+  .mixin(@var, @var * 2);
+}
+
+.multi-mix {
+  .mixin(2px, 30%);
+  .mixiny(4, 5);
+}
+
+.maxa(@arg1: 10, @arg2: #f00) {
+  padding: @arg1 * 2px;
+  color: @arg2;
+}
+
+body {
+  .maxa(15);
+}
+
+ at glob: 5;
+.global-mixin(@a:2) {
+  width: @glob + @a;
+}
+
+.scope-mix {
+  .global-mixin(3);
+}
+
+.nested-ruleset (@width: 200px) {
+    width: @width;
+    .column { margin: @width; }
+}
+.content {
+    .nested-ruleset(600px);
+}
+
+//
+
+.same-var-name2(@radius) {
+  radius: @radius;
+}
+.same-var-name(@radius) {
+  .same-var-name2(@radius);
+}
+#same-var-name {
+  .same-var-name(5px);
+}
+
+//
+
+.var-inside () {
+    @var: 10px;
+    width: @var;
+}
+#var-inside { .var-inside; }
+.mix-inner (@var) {
+  border-width: @var;
+}
+
+.mix (@a: 10) {
+  .inner {
+    height: @a * 10;
+
+    .innest {
+      width: @a;  
+      .mix-inner(@a * 2);
+    }  
+  }
+}
+
+.class {
+  .mix(30);
+}
+.mixin () {
+    zero: 0;
+}
+.mixin (@a: 1px) {
+    one: 1;
+}
+.mixin (@a) {
+    one-req: 1;
+}
+.mixin (@a: 1px, @b: 2px) {
+    two: 2;
+}
+
+.mixin (@a, @b, @c) {
+    three-req: 3;
+}
+
+.mixin (@a: 1px, @b: 2px, @c: 3px) {
+    three: 3;
+}
+
+.zero {
+    .mixin();
+}
+
+.one {
+    .mixin(1);
+}
+
+.two {
+    .mixin(1, 2);
+}
+
+.three {
+    .mixin(1, 2, 3);
+}
+
+//
+
+.mixout ('left') {
+    left: 1;
+}
+
+.mixout ('right') {
+    right: 1;
+}
+
+.left {
+    .mixout('left');
+}
+.right {
+    .mixout('right');
+}
+
+//
+
+.border (@side, @width) {
+    color: black;
+    .border-side(@side, @width);
+}
+.border-side (left, @w) {
+    border-left: @w;
+}
+.border-side (right, @w) {
+    border-right: @w;
+}
+
+.border-right {
+    .border(right, 4px);
+}
+.border-left {
+    .border(left, 4px);
+}
+
+//
+
+
+.border-radius (@r) {
+    both: @r * 10;
+}
+.border-radius (@r, left) {
+    left: @r;
+}
+.border-radius (@r, right) {
+    right: @r;
+}
+
+.only-right {
+    .border-radius(33, right);
+}
+.only-left {
+    .border-radius(33, left);
+}
+.left-right {
+    .border-radius(33);
+}
+.mixin { border: 1px solid black; }
+.mixout { border-color: orange; }
+.borders { border-style: dashed; }
+
+#namespace {
+  .borders {
+    border-style: dotted;
+  }
+  .biohazard {
+    content: "death";
+    .man {
+      color: transparent;
+    }
+  }
+}
+#theme {
+  > .mixin {
+    background-color: grey;
+  }
+}
+#container {
+  color: black;
+  .mixin;
+  .mixout;
+  #theme > .mixin;
+}
+
+#header {
+  .milk {
+    color: white;
+    .mixin;
+    #theme > .mixin;
+  }
+  #cookie {
+    .chips {
+      #namespace .borders;
+      .calories {
+        #container;
+      }
+    }
+    .borders;
+  }
+}
+.secure-zone { #namespace .biohazard .man; }
+.direct {
+  #namespace > .borders;
+}
+#operations {
+  color: #110000 + #000011 + #001100; // #111111
+  height: 10px / 2px + 6px - 1px * 2; // 9px
+  width: 2 * 4 - 5em; // 3em
+  .spacing {
+    height: 10px / 2px+6px-1px*2;
+    width: 2  * 4-5em;
+  }
+  substraction: 20 - 10 - 5 - 5; // 0
+  division: 20 / 5 / 4; // 1
+}
+
+ at x: 4;
+ at y: 12em;
+
+.with-variables {
+  height: @x + @y; // 16em
+  width: 12 + @y; // 24em
+  size: 5cm - @x; // 1cm
+}
+
+ at z: -2;
+
+.negative {
+  height: 2px + @z; // 0px
+  width: 2px - @z; // 4px
+}
+
+.shorthands {
+  padding: -1px 2px 0 -4px; //
+}
+
+.colors {
+  color: #123; // #112233
+  border-color: #234 + #111111; // #334455
+  background-color: #222222 - #fff; // #000000
+  .other {
+    color: 2 * #111; // #222222
+    border-color: #333333 / 3 + #111; // #222222
+  }
+}
+.parens {
+  @var: 1px;
+  border: (@var * 2) solid black;
+  margin: (@var * 1) (@var + 2) (4 * 4) 3;
+  width: (6 * 6);
+  padding: 2px (6px * 6px);
+}
+
+.more-parens {
+  @var: (2 * 2);
+  padding: (2 * @var) 4 4 (@var * 1px);
+  width: (@var * @var) * 6;
+  height: (7 * 7) + (8 * 8);
+  margin: 4 * (5 + 5) / 2 - (@var * 2);
+  //margin: (6 * 6)px;
+}
+
+.nested-parens {
+  width: 2 * (4 * (2 + (1 + 6))) - 1;
+  height: ((2+3)*(2+3) / (9-4)) + 1;
+}
+
+.mixed-units {
+  margin: 2px 4em 1 5pc;
+  padding: (2px + 4px) 1em 2px 2;
+}
+#first > .one {
+  > #second .two > #deux {
+    width: 50%;
+    #third {
+      &:focus {
+        color: black;
+        #fifth {
+          > #sixth {
+            .seventh #eighth {
+              + #ninth {
+                color: purple;
+              }
+            }
+          }
+        }
+      }
+      height: 100%;
+    }
+    #fourth, #five, #six {
+      color: #110000;
+      .seven, .eight > #nine {
+        border: 1px solid black;
+      }
+      #ten {
+        color: red;
+      }
+    }
+  }
+  font-size: 2em;
+}
+ at x: blue;
+ at z: transparent;
+ at mix: none;
+
+.mixin {
+  @mix: #989;
+}
+
+.tiny-scope {
+  color: @mix; // #989
+  .mixin;
+}
+
+.scope1 {
+  @y: orange;
+  @z: black;
+  color: @x; // blue
+  border-color: @z; // black
+  .hidden {
+    @x: #131313;
+  }
+  .scope2 {
+    @y: red;
+    color: @x; // blue
+    .scope3 {
+      @local: white;
+      color: @y; // red
+      border-color: @z; // black
+      background-color: @local; // white
+    }
+  }
+}h1, h2, h3 {
+  a, p {
+    &:hover {
+      color: red;
+    }
+  }
+}
+
+#all { color: blue; }
+#the { color: blue; }
+#same { color: blue; }
+
+ul, li, div, q, blockquote, textarea {
+  margin: 0;
+}
+
+td {
+  margin: 0;
+  padding: 0;
+}
+
+td, input {
+  line-height: 1em;
+}
+#strings {
+  background-image: url("http://son-of-a-banana.com");
+  quotes: "~" "~";
+  content: "#*%:&^,)!.(~*})";
+  empty: "";
+  brackets: "{" "}";
+}
+#comments {
+  content: "/* hello */ // not-so-secret";
+}
+#single-quote {
+  quotes: "'" "'";
+  content: '""#!&""';
+  empty: '';
+}
+ at a: 2;
+ at x: @a * @a;
+ at y: @x + 1;
+ at z: @x * 2 + @y;
+
+.variables {
+  width: @z + 1cm; // 14cm
+}
+
+ at b: @a * 10;
+ at c: #888;
+
+ at fonts: "Trebuchet MS", Verdana, sans-serif;
+ at f: @fonts;
+
+ at quotes: "~" "~";
+ at q: @quotes;
+
+.variables {
+  height: @b + @x + 0px; // 24px
+  color: @c;
+  font-family: @f;
+  quotes: @q;
+}
+
+.redefinition {
+    @var: 4;
+    @var: 2;
+    @var: 3;
+    three: @var;
+}
+
+.values {
+    @a: 'Trebuchet';
+    font-family: @a, @a, @a;
+}
+
+
+.whitespace
+  { color: white; }  
+  
+.whitespace
+{
+  color: white;
+}
+  .whitespace
+{ color: white; }
+
+.whitespace{color:white;}  
+.whitespace { color : white ; }
+
+.white,
+.space,
+.mania
+{ color: white; }
+
+.no-semi-column { color: white }
+.no-semi-column {
+  color: white;
+  white-space: pre
+}
+.no-semi-column {border: 2px solid white}
+.newlines {
+  background: the,
+              great,
+              wall;
+  border: 2px
+          solid
+          black;
+}
+.empty {
+  
+}
+#yelow {
+  #short {
+    color: #fea;
+  }
+  #long {
+    color: #ffeeaa;
+  }
+  #rgba {
+    color: rgba(255, 238, 170, 0.1);
+  }
+}
+
+#blue {
+  #short {
+    color: #00f;
+  }
+  #long {
+    color: #0000ff;
+  }
+  #rgba {
+    color: rgba(0, 0, 255, 0.1);
+  }
+}
+
+#overflow {
+  .a { color: #111111 - #444444; } // #000000
+  .b { color: #eee + #fff; } // #ffffff
+  .c { color: #aaa * 3; } // #ffffff
+  .d { color: #00ee00 + #009900; } // #00ff00
+}
+
+#grey {
+  color: rgb(200, 200, 200);
+}
+
+#808080 {
+  color: hsl(50, 0%, 50%);
+}
+
+#00ff00 {
+  color: hsl(120, 100%, 50%);
+}
+/******************\
+*                  *
+*  Comment Header  *
+*                  *
+\******************/
+
+/*
+
+    Comment
+
+*/
+
+/*  
+ * Comment Test
+ * 
+ * - cloudhead (http://cloudhead.net)
+ *
+ */
+
+////////////////
+ at var: "content";
+////////////////
+
+/* Colors
+ * ------
+ *   #EDF8FC (background blue)
+ *   #166C89 (darkest blue)
+ *
+ * Text:
+ *   #333 (standard text) // A comment within a comment!
+ *   #1F9EC9 (standard link)
+ *
+ */
+
+/* @group Variables
+------------------- */
+#comments /* boo */ {
+  /**/ // An empty comment 
+  color: red; /* A C-style comment */
+  background-color: orange; // A little comment
+  font-size: 12px;
+  
+  /* lost comment */ content: @var;
+  
+  border: 1px solid black;
+  
+  // padding & margin //
+  padding: 0;
+  margin: 2em;
+} //
+
+/* commented out
+  #more-comments {
+    color: grey;
+  }
+*/
+
+#last { color: blue }
+//
+.comma-delimited { 
+  background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+  text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
+  -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset,
+    0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
+}
+ at font-face {
+  font-family: Headline;
+  src: local(Futura-Medium),
+       url(fonts.svg#MyGeometricModern) format("svg");
+}
+.other {
+  -moz-transform: translate(0, 11em) rotate(-90deg);
+}
+p:not([class*="lead"]) {
+  color: black; 
+}
+
+input[type="text"].class#id[attr=32]:not(1) {
+  color: white;
+}
+
+div#id.class[a=1][b=2].class:not(1) {
+  color: white;
+}
+
+ul.comma > li:not(:only-child)::after { 
+  color: white;
+}
+
+ol.comma > li:nth-last-child(2)::after {
+  color: white;
+}
+
+li:nth-child(4n+1),
+li:nth-child(-5n),
+li:nth-child(-n+2) {
+  color: white;
+}
+
+a[href^="http://"] {
+  color: black;
+}
+
+a[href$="http://"] {
+  color: black;
+}
+
+form[data-disabled] {
+  color: black;
+}
+
+p::before {
+  color: black;
+}
+ at charset "utf-8";
+div { color: black; }
+div { width: 99%; }
+
+* {
+  min-width: 45em;
+}
+
+h1, h2 > a > p, h3 {
+  color: none;
+}
+
+div.class {
+  color: blue;
+}
+
+div#id {
+  color: green;
+}
+
+.class#id {
+  color: purple;
+}
+
+.one.two.three {
+  color: grey;
+}
+
+ at media print {
+  font-size: 3em;
+}
+
+ at media screen {
+  font-size: 10px;
+}
+
+ at font-face {
+  font-family: 'Garamond Pro';
+  src: url("/fonts/garamond-pro.ttf");
+}
+
+a:hover, a:link {
+  color: #999;
+}
+
+p, p:first-child {
+  text-transform: none;
+}
+
+q:lang(no) {
+  quotes: none;
+}
+
+p + h1 {
+  font-size: 2.2em;
+}
+
+#shorthands {
+  border: 1px solid #000;
+  font: 12px/16px Arial;
+  margin: 1px 0;
+  padding: 0 auto;
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+
+#more-shorthands {
+  margin: 0;
+  padding: 1px 0 2px 0;
+  font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; 
+}
+
+.misc {
+  -moz-border-radius: 2px;
+  display: -moz-inline-stack;
+  width: .1em;
+  background-color: #009998;
+  background-image: url(images/image.jpg);
+  background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
+  margin: ;
+}
+
+#important {
+  color: red !important;
+  width: 100%!important;
+  height: 20px ! important;
+}
+
+#functions {
+  @var: 10;
+  color: color("evil red"); // #660000
+  width: increment(15);
+  height: undefined("self");
+  border-width: add(2, 3);
+  variable: increment(@var);
+}
+
+#built-in {
+  @r: 32;
+  escaped: e("-Some::weird(#thing, y)");
+  lighten: lighten(#ff0000, 50%);
+  darken: darken(#ff0000, 50%);
+  saturate: saturate(#29332f, 20%);
+  desaturate: desaturate(#203c31, 20%);
+  greyscale: greyscale(#203c31);
+  format: %("rgb(%d, %d, %d)", @r, 128, 64);
+  format-string: %("hello %s", "world");
+  eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64));
+}
+
+ at var: @a;
+ at a: 100%;
+
+.lazy-eval {
+  width: @var;
+}
+.mixin (@a: 1px, @b: 50%) {
+  width: @a * 5;
+  height: @b - 1%;
+}
+
+.mixina (@style, @width, @color: black) {
+    border: @width @style @color;
+}
+
+.mixiny
+(@a: 0, @b: 0) {
+  margin: @a;
+  padding: @b;
+}
+
+.hidden() {
+  color: transparent;
+}
+
+.two-args {
+  color: blue;
+  .mixin(2px, 100%);
+  .mixina(dotted, 2px);
+}
+
+.one-arg {
+  .mixin(3px);
+}
+
+.no-parens {
+  .mixin;
+}
+
+.no-args {
+  .mixin();
+}
+
+.var-args {
+  @var: 9;
+  .mixin(@var, @var * 2);
+}
+
+.multi-mix {
+  .mixin(2px, 30%);
+  .mixiny(4, 5);
+}
+
+.maxa(@arg1: 10, @arg2: #f00) {
+  padding: @arg1 * 2px;
+  color: @arg2;
+}
+
+body {
+  .maxa(15);
+}
+
+ at glob: 5;
+.global-mixin(@a:2) {
+  width: @glob + @a;
+}
+
+.scope-mix {
+  .global-mixin(3);
+}
+
+.nested-ruleset (@width: 200px) {
+    width: @width;
+    .column { margin: @width; }
+}
+.content {
+    .nested-ruleset(600px);
+}
+
+//
+
+.same-var-name2(@radius) {
+  radius: @radius;
+}
+.same-var-name(@radius) {
+  .same-var-name2(@radius);
+}
+#same-var-name {
+  .same-var-name(5px);
+}
+
+//
+
+.var-inside () {
+    @var: 10px;
+    width: @var;
+}
+#var-inside { .var-inside; }
+.mix-inner (@var) {
+  border-width: @var;
+}
+
+.mix (@a: 10) {
+  .inner {
+    height: @a * 10;
+
+    .innest {
+      width: @a;  
+      .mix-inner(@a * 2);
+    }  
+  }
+}
+
+.class {
+  .mix(30);
+}
+.mixin () {
+    zero: 0;
+}
+.mixin (@a: 1px) {
+    one: 1;
+}
+.mixin (@a) {
+    one-req: 1;
+}
+.mixin (@a: 1px, @b: 2px) {
+    two: 2;
+}
+
+.mixin (@a, @b, @c) {
+    three-req: 3;
+}
+
+.mixin (@a: 1px, @b: 2px, @c: 3px) {
+    three: 3;
+}
+
+.zero {
+    .mixin();
+}
+
+.one {
+    .mixin(1);
+}
+
+.two {
+    .mixin(1, 2);
+}
+
+.three {
+    .mixin(1, 2, 3);
+}
+
+//
+
+.mixout ('left') {
+    left: 1;
+}
diff --git a/util/less/benchmark/less-benchmark.js b/util/less/benchmark/less-benchmark.js
new file mode 100644
index 0000000..68fe1ad
--- /dev/null
+++ b/util/less/benchmark/less-benchmark.js
@@ -0,0 +1,47 @@
+var path = require('path'),
+    fs = require('fs'),
+    sys = require('util');
+
+var less = require('../lib/less');
+var file = path.join(__dirname, 'benchmark.less');
+
+if (process.argv[2]) { file = path.join(process.cwd(), process.argv[2]) }
+
+fs.readFile(file, 'utf8', function (e, data) {
+    var tree, css, start, end, total;
+
+    sys.puts("Benchmarking...\n", path.basename(file) + " (" +
+             parseInt(data.length / 1024) + " KB)", "");
+
+    start = new(Date);
+
+    new(less.Parser)({ optimization: 2 }).parse(data, function (err, tree) {
+        end = new(Date);
+
+        total = end - start;
+
+        sys.puts("Parsing: " +
+                 total + " ms (" +
+                 parseInt(1000 / total *
+                 data.length / 1024) + " KB\/s)");
+
+        start = new(Date);
+        css = tree.toCSS();
+        end = new(Date);
+
+        sys.puts("Generation: " + (end - start) + " ms (" +
+                 parseInt(1000 / (end - start) *
+                 data.length / 1024) + " KB\/s)");
+
+        total += end - start;
+
+        sys.puts("Total: " + total + "ms (" +
+                 parseInt(1000 / total * data.length / 1024) + " KB/s)");
+
+        if (err) {
+            less.writeError(err);
+            process.exit(3);
+        }
+    });
+});
+
diff --git a/util/less/bin/lessc b/util/less/bin/lessc
new file mode 100755
index 0000000..31a6700
--- /dev/null
+++ b/util/less/bin/lessc
@@ -0,0 +1,190 @@
+#!/usr/bin/env node
+
+var path = require('path'),
+    fs = require('fs'),
+    sys = require('util'),
+    os = require('os');
+
+var less = require('../lib/less');
+var args = process.argv.slice(1);
+var options = {
+    compress: false,
+    yuicompress: false,
+    optimization: 1,
+    silent: false,
+    paths: [],
+    color: true,
+    strictImports: false,
+    rootpath: '',
+    relativeUrls: false
+};
+var continueProcessing = true,
+    currentErrorcode;
+
+// calling process.exit does not flush stdout always
+// so use this to set the exit code
+process.on('exit', function() { process.reallyExit(currentErrorcode) });
+
+args = args.filter(function (arg) {
+    var match;
+
+    if (match = arg.match(/^-I(.+)$/)) {
+        options.paths.push(match[1]);
+        return false;
+    }
+
+    if (match = arg.match(/^--?([a-z][0-9a-z-]*)(?:=([^\s]+))?$/i)) { arg = match[1] }
+    else { return arg }
+
+    switch (arg) {
+        case 'v':
+        case 'version':
+            sys.puts("lessc " + less.version.join('.') + " (LESS Compiler) [JavaScript]");
+            continueProcessing = false;
+        case 'verbose':
+            options.verbose = true;
+            break;
+        case 's':
+        case 'silent':
+            options.silent = true;
+            break;
+        case 'strict-imports':
+            options.strictImports = true;
+            break;
+        case 'h':
+        case 'help':
+            require('../lib/less/lessc_helper').printUsage();
+            continueProcessing = false;
+        case 'x':
+        case 'compress':
+            options.compress = true;
+            break;
+        case 'yui-compress':
+            options.yuicompress = true;
+            break;
+        case 'no-color':
+            options.color = false;
+            break;
+        case 'include-path':
+            if (!match[2]) {
+                sys.puts("include-path option requires a parameter");
+                continueProcessing = false;
+            } else {
+                options.paths = match[2].split(os.type().match(/Windows/) ? ';' : ':')
+                    .map(function(p) {
+                        if (p) {
+                            return path.resolve(process.cwd(), p);
+                        }
+                    });
+            }
+            break;
+        case 'O0': options.optimization = 0; break;
+        case 'O1': options.optimization = 1; break;
+        case 'O2': options.optimization = 2; break;
+        case 'line-numbers':
+            options.dumpLineNumbers = match[2];
+            break;
+        case 'rp':
+        case 'rootpath':
+            if (!match[2]) {
+                sys.puts("rootpath option requires a parameter");
+                continueProcessing = false;
+            } else {
+                options.rootpath = path.normalize(match[2] + '/').replace('\\', '/');
+            }
+            break;
+        case "ru":
+        case "relative-urls":
+            options.relativeUrls = true;
+            break;
+    }
+});
+
+if (!continueProcessing) {
+    return;
+}
+
+var input = args[1];
+if (input && input != '-') {
+    input = path.resolve(process.cwd(), input);
+}
+var output = args[2];
+if (output) {
+    output = path.resolve(process.cwd(), output);
+}
+
+if (! input) {
+    sys.puts("lessc: no input files");
+    sys.puts("");
+    require('../lib/less/lessc_helper').printUsage();
+    currentErrorcode = 1;
+    return;
+}
+
+var ensureDirectory = function (filepath) {
+    var dir = path.dirname(filepath),
+        existsSync = fs.existsSync || path.existsSync;
+    if (!existsSync(dir)) {
+        fs.mkdirSync(dir);
+    }
+};
+
+var parseLessFile = function (e, data) {
+    if (e) {
+        sys.puts("lessc: " + e.message);
+        currentErrorcode = 1;
+        return;
+    }
+
+    new(less.Parser)({
+        paths: [path.dirname(input)].concat(options.paths),
+        optimization: options.optimization,
+        filename: input,
+        rootpath: options.rootpath,
+        relativeUrls: options.relativeUrls,
+        strictImports: options.strictImports,
+        dumpLineNumbers: options.dumpLineNumbers
+    }).parse(data, function (err, tree) {
+        if (err) {
+            less.writeError(err, options);
+            currentErrorcode = 1;
+            return;
+        } else {
+            try {
+                var css = tree.toCSS({
+                    compress: options.compress,
+                    yuicompress: options.yuicompress
+                });
+                if (output) {
+                    ensureDirectory(output);
+                    fs.writeFileSync(output, css, 'utf8');
+                    if (options.verbose) {
+                        console.log('lessc: wrote ' + output);
+                    }
+                } else {
+                    sys.print(css);
+                }
+            } catch (e) {
+                less.writeError(e, options);
+                currentErrorcode = 2;
+                return;
+            }
+        }
+    });
+};
+
+if (input != '-') {
+    fs.readFile(input, 'utf8', parseLessFile);
+} else {
+    process.stdin.resume();
+    process.stdin.setEncoding('utf8');
+
+    var buffer = '';
+    process.stdin.on('data', function(data) {
+        buffer += data;
+    });
+
+    process.stdin.on('end', function() {
+        parseLessFile(false, buffer);
+    });
+}
diff --git a/util/less/browser.js b/util/less/browser.js
deleted file mode 100755
index ae2667d..0000000
--- a/util/less/browser.js
+++ /dev/null
@@ -1,369 +0,0 @@
-//
-// browser.js - client-side engine
-//
-
-var isFileProtocol = (location.protocol === 'file:'    ||
-                      location.protocol === 'chrome:'  ||
-                      location.protocol === 'chrome-extension:'  ||
-                      location.protocol === 'resource:');
-
-less.env = less.env || (location.hostname == '127.0.0.1' ||
-                        location.hostname == '0.0.0.0'   ||
-                        location.hostname == 'localhost' ||
-                        location.port.length > 0         ||
-                        isFileProtocol                   ? 'development'
-                                                         : 'production');
-
-// Load styles asynchronously (default: false)
-//
-// This is set to `false` by default, so that the body
-// doesn't start loading before the stylesheets are parsed.
-// Setting this to `true` can result in flickering.
-//
-less.async = false;
-
-// Interval between watch polls
-less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
-
-//
-// Watch mode
-//
-less.watch   = function () { return this.watchMode = true };
-less.unwatch = function () { return this.watchMode = false };
-
-if (less.env === 'development') {
-    less.optimization = 0;
-
-    if (/!watch/.test(location.hash)) {
-        less.watch();
-    }
-    less.watchTimer = setInterval(function () {
-        if (less.watchMode) {
-            loadStyleSheets(function (root, sheet, env) {
-                if (root) {
-                    createCSS(root.toCSS(), sheet, env.lastModified);
-                }
-            });
-        }
-    }, less.poll);
-} else {
-    less.optimization = 3;
-}
-
-var cache;
-
-try {
-    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
-} catch (_) {
-    cache = null;
-}
-
-//
-// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
-//
-var links = document.getElementsByTagName('link');
-var typePattern = /^text\/(x-)?less$/;
-
-less.sheets = [];
-
-for (var i = 0; i < links.length; i++) {
-    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
-       (links[i].type.match(typePattern)))) {
-        less.sheets.push(links[i]);
-    }
-}
-
-
-less.refresh = function (reload) {
-    var startTime, endTime;
-    startTime = endTime = new(Date);
-
-    loadStyleSheets(function (root, sheet, env) {
-        if (env.local) {
-            log("loading " + sheet.href + " from cache.");
-        } else {
-            log("parsed " + sheet.href + " successfully.");
-            createCSS(root.toCSS(), sheet, env.lastModified);
-        }
-        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
-        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
-        endTime = new(Date);
-    }, reload);
-
-    loadStyles();
-};
-less.refreshStyles = loadStyles;
-
-less.refresh(less.env === 'development');
-
-function loadStyles() {
-    var styles = document.getElementsByTagName('style');
-    for (var i = 0; i < styles.length; i++) {
-        if (styles[i].type.match(typePattern)) {
-            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
-                styles[i].type      = 'text/css';
-                styles[i].innerHTML = tree.toCSS();
-            });
-        }
-    }
-}
-
-function loadStyleSheets(callback, reload) {
-    for (var i = 0; i < less.sheets.length; i++) {
-        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
-    }
-}
-
-function loadStyleSheet(sheet, callback, reload, remaining) {
-    var url       = window.location.href.replace(/[#?].*$/, '');
-    var href      = sheet.href.replace(/\?.*$/, '');
-    var css       = cache && cache.getItem(href);
-    var timestamp = cache && cache.getItem(href + ':timestamp');
-    var styles    = { css: css, timestamp: timestamp };
-
-    // Stylesheets in IE don't always return the full path
-    if (! /^(https?|file):/.test(href)) {
-        if (href.charAt(0) == "/") {
-            href = window.location.protocol + "//" + window.location.host + href;
-        } else {
-            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
-        }
-    }
-
-    xhr(sheet.href, sheet.type, function (data, lastModified) {
-        if (!reload && styles && lastModified &&
-           (new(Date)(lastModified).valueOf() ===
-            new(Date)(styles.timestamp).valueOf())) {
-            // Use local copy
-            createCSS(styles.css, sheet);
-            callback(null, sheet, { local: true, remaining: remaining });
-        } else {
-            // Use remote copy (re-parse)
-            try {
-                new(less.Parser)({
-                    optimization: less.optimization,
-                    paths: [href.replace(/[\w\.-]+$/, '')],
-                    mime: sheet.type
-                }).parse(data, function (e, root) {
-                    if (e) { return error(e, href) }
-                    try {
-                        callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
-                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
-                    } catch (e) {
-                        error(e, href);
-                    }
-                });
-            } catch (e) {
-                error(e, href);
-            }
-        }
-    }, function (status, url) {
-        throw new(Error)("Couldn't load " + url + " (" + status + ")");
-    });
-}
-
-function extractId(href) {
-    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
-               .replace(/^\//,                 '' )  // Remove root /
-               .replace(/\?.*$/,               '' )  // Remove query
-               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
-               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
-               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
-}
-
-function createCSS(styles, sheet, lastModified) {
-    var css;
-
-    // Strip the query-string
-    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
-
-    // If there is no title set, use the filename, minus the extension
-    var id = 'less:' + (sheet.title || extractId(href));
-
-    // If the stylesheet doesn't exist, create a new node
-    if ((css = document.getElementById(id)) === null) {
-        css = document.createElement('style');
-        css.type = 'text/css';
-        css.media = sheet.media || 'screen';
-        css.id = id;
-        document.getElementsByTagName('head')[0].appendChild(css);
-    }
-
-    if (css.styleSheet) { // IE
-        try {
-            css.styleSheet.cssText = styles;
-        } catch (e) {
-            throw new(Error)("Couldn't reassign styleSheet.cssText.");
-        }
-    } else {
-        (function (node) {
-            if (css.childNodes.length > 0) {
-                if (css.firstChild.nodeValue !== node.nodeValue) {
-                    css.replaceChild(node, css.firstChild);
-                }
-            } else {
-                css.appendChild(node);
-            }
-        })(document.createTextNode(styles));
-    }
-
-    // Don't update the local store if the file wasn't modified
-    if (lastModified && cache) {
-        log('saving ' + href + ' to cache.');
-        cache.setItem(href, styles);
-        cache.setItem(href + ':timestamp', lastModified);
-    }
-}
-
-function xhr(url, type, callback, errback) {
-    var xhr = getXMLHttpRequest();
-    var async = isFileProtocol ? false : less.async;
-
-    if (typeof(xhr.overrideMimeType) === 'function') {
-        xhr.overrideMimeType('text/css');
-    }
-    xhr.open('GET', url, async);
-    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
-    xhr.send(null);
-
-    if (isFileProtocol) {
-        if (xhr.status === 0) {
-            callback(xhr.responseText);
-        } else {
-            errback(xhr.status, url);
-        }
-    } else if (async) {
-        xhr.onreadystatechange = function () {
-            if (xhr.readyState == 4) {
-                handleResponse(xhr, callback, errback);
-            }
-        };
-    } else {
-        handleResponse(xhr, callback, errback);
-    }
-
-    function handleResponse(xhr, callback, errback) {
-        if (xhr.status >= 200 && xhr.status < 300) {
-            callback(xhr.responseText,
-                     xhr.getResponseHeader("Last-Modified"));
-        } else if (typeof(errback) === 'function') {
-            errback(xhr.status, url);
-        }
-    }
-}
-
-function getXMLHttpRequest() {
-    if (window.XMLHttpRequest) {
-        return new(XMLHttpRequest);
-    } else {
-        try {
-            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
-        } catch (e) {
-            log("browser doesn't support AJAX.");
-            return null;
-        }
-    }
-}
-
-function removeNode(node) {
-    return node && node.parentNode.removeChild(node);
-}
-
-function log(str) {
-    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
-}
-
-function error(e, href) {
-    var id = 'less-error-message:' + extractId(href);
-
-    var template = ['<ul>',
-                        '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
-                        '<li><label>[0]</label><pre>{current}</pre></li>',
-                        '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
-                    '</ul>'].join('\n');
-
-    var elem = document.createElement('div'), timer, content;
-
-    elem.id        = id;
-    elem.className = "less-error-message";
-
-    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
-              '</h3>' + '<p><a href="' + href   + '">' + href + "</a> ";
-
-    if (e.extract) {
-        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
-            template.replace(/\[(-?\d)\]/g, function (_, i) {
-                return (parseInt(e.line) + parseInt(i)) || '';
-            }).replace(/\{(\d)\}/g, function (_, i) {
-                return e.extract[parseInt(i)] || '';
-            }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
-                                      e.extract[1].slice(e.column)    + '</span>');
-    }
-    elem.innerHTML = content;
-
-    // CSS for error messages
-    createCSS([
-        '.less-error-message ul, .less-error-message li {',
-            'list-style-type: none;',
-            'margin-right: 15px;',
-            'padding: 4px 0;',
-            'margin: 0;',
-        '}',
-        '.less-error-message label {',
-            'font-size: 12px;',
-            'margin-right: 15px;',
-            'padding: 4px 0;',
-            'color: #cc7777;',
-        '}',
-        '.less-error-message pre {',
-            'color: #ee4444;',
-            'padding: 4px 0;',
-            'margin: 0;',
-            'display: inline-block;',
-        '}',
-        '.less-error-message pre.ctx {',
-            'color: #dd4444;',
-        '}',
-        '.less-error-message h3 {',
-            'font-size: 20px;',
-            'font-weight: bold;',
-            'padding: 15px 0 5px 0;',
-            'margin: 0;',
-        '}',
-        '.less-error-message a {',
-            'color: #10a',
-        '}',
-        '.less-error-message .error {',
-            'color: red;',
-            'font-weight: bold;',
-            'padding-bottom: 2px;',
-            'border-bottom: 1px dashed red;',
-        '}'
-    ].join('\n'), { title: 'error-message' });
-
-    elem.style.cssText = [
-        "font-family: Arial, sans-serif",
-        "border: 1px solid #e00",
-        "background-color: #eee",
-        "border-radius: 5px",
-        "-webkit-border-radius: 5px",
-        "-moz-border-radius: 5px",
-        "color: #e00",
-        "padding: 15px",
-        "margin-bottom: 15px"
-    ].join(';');
-
-    if (less.env == 'development') {
-        timer = setInterval(function () {
-            if (document.body) {
-                if (document.getElementById(id)) {
-                    document.body.replaceChild(elem, document.getElementById(id));
-                } else {
-                    document.body.insertBefore(elem, document.body.firstChild);
-                }
-                clearInterval(timer);
-            }
-        }, 10);
-    }
-}
-
diff --git a/util/less/build/amd.js b/util/less/build/amd.js
new file mode 100644
index 0000000..c4b1187
--- /dev/null
+++ b/util/less/build/amd.js
@@ -0,0 +1,6 @@
+// amd.js
+//
+// Define Less as an AMD module.
+if (typeof define === "function" && define.amd) {
+    define("less", [], function () { return less; } );
+}
diff --git a/util/less/build/ecma-5.js b/util/less/build/ecma-5.js
new file mode 100644
index 0000000..420bd88
--- /dev/null
+++ b/util/less/build/ecma-5.js
@@ -0,0 +1,120 @@
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
diff --git a/util/less/build/header.js b/util/less/build/header.js
new file mode 100644
index 0000000..c491d92
--- /dev/null
+++ b/util/less/build/header.js
@@ -0,0 +1,7 @@
+//
+// LESS - Leaner CSS v at VERSION
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
diff --git a/util/less/build/require-rhino.js b/util/less/build/require-rhino.js
new file mode 100644
index 0000000..02bc83c
--- /dev/null
+++ b/util/less/build/require-rhino.js
@@ -0,0 +1,7 @@
+//
+// Stub out `require` in rhino
+//
+function require(arg) {
+    return less[arg.split('/')[1]];
+};
+
diff --git a/util/less/build/require.js b/util/less/build/require.js
new file mode 100644
index 0000000..4d5b172
--- /dev/null
+++ b/util/less/build/require.js
@@ -0,0 +1,7 @@
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
diff --git a/util/less/dist/less-1.1.0.js b/util/less/dist/less-1.1.0.js
new file mode 100644
index 0000000..487c06a
--- /dev/null
+++ b/util/less/dist/less-1.1.0.js
@@ -0,0 +1,2695 @@
+//
+// LESS - Leaner CSS v1.1.0
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+    less = exports,
+    tree = require('less/tree');
+} else {
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        mime:  env && env.mime,         // MIME type of .less files
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+
+                callback(root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam,
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && !inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString && !inParam) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString && !inParam) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else if (c === '(' && !inString && !inParam) {
+                        chunk.push(c);
+                        inParam = true;
+                    } else if (c === ')' && !inString && inParam) {
+                        chunk.push(c);
+                        inParam = false;
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            root = new(tree.Ruleset)([], $(this.parsers.primary));
+            root.root = true;
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [];
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        lines = input.split('\n');
+                        line = getLine(e.index);
+
+                        for (var n = e.index, column = -1;
+                                 n >= 0 && input.charAt(n) !== '\n';
+                                 n--) { column++ }
+
+                        throw {
+                            type: e.type,
+                            message: e.message,
+                            filename: env.filename,
+                            index: e.index,
+                            line: typeof(line) === 'number' ? line + 1 : null,
+                            callLine: e.call && (getLine(e.call) + 1),
+                            callExtract: lines[getLine(e.call)],
+                            stack: e.stack,
+                            column: column,
+                            extract: [
+                                lines[line - 1],
+                                lines[line],
+                                lines[line + 1]
+                            ]
+                        };
+                    }
+                    if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+
+                    function getLine(index) {
+                        return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    name: "ParseError",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+                    if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args;
+
+                    if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+                    if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value;
+
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    if (value = $(this.expression)) {
+                                        params.push({ name: param.name, value: value });
+                                    } else {
+                                        throw new(Error)("Expected value");
+                                    }
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset);
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c;
+
+                c = $(this.combinator);
+                e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (e) { return new(tree.Element)(c, e) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '&' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+                    i += match[0].length - 1;
+                    selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+                } else {
+                    while (s = $(this.selector)) {
+                        selectors.push(s);
+                        $(this.comment);
+                        if (! $(',')) { break }
+                        $(this.comment);
+                    }
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url)) &&
+                    $(';')) {
+                    return new(tree.Import)(path, imports);
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import'])) {
+                    return value;
+                } else if (name = $(/^@media|@page|@-[-a-z]+/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (typeof(window) !== 'undefined') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math.round(number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math.round(n);
+        } else {
+	    throw {
+                error: "RuntimeError",
+                message: "math functions take numbers as parameters"
+            };
+        }
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args) {
+    this.name = name;
+    this.args = args;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            return tree.functions[this.name].apply(tree.functions, args);
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else if (rgb.length == 8) {
+        this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+        this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+    this.value = value.trim();
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else {
+            return this.value[0].eval(env);
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(' ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+    var that = this;
+
+    this._path = path;
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (root) {
+            if (! root) {
+                throw new(Error)("Error parsing " + that.path);
+            }
+            that.root = root;
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function () {
+        if (this.css) {
+            return "@import " + this._path.toCSS() + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset;
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return ruleset.rules;
+        }
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.evaluated;
+        } else {
+            return JSON.stringify(this.evaluated);
+        }
+    },
+    eval: function (env) {
+        var result,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return new(tree.Variable)('@' + name).eval(env).value;
+        });
+
+        expression = new(Function)('return (' + expression + ')');
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            this.evaluated = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        return this;
+    }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(this.arguments, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index };
+                }
+            }
+        }
+        throw { message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    eval: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments)));
+
+        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        this.value = this.value.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return new(tree.Variable)('@' + name).eval(env).value;
+        }).replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, this.index, true).eval(env).toCSS();
+        });
+        return this;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + ";";
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > 1) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                for (var s = 0; s < this.selectors.length; s++) {
+                    for (var c = 0; c < context.length; c++) {
+                        paths.push(context[c].concat([this.selectors[s]]));
+                    }
+                }
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    if (this.elements[0].value === other.elements[0].value) {
+        return true;
+    } else {
+        return false;
+    }
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { message: "variable " + name + " is undefined",
+                    index: this.index };
+        }
+    }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'chrome-extension:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (root, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (root, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                styles[i].type      = 'text/css';
+                styles[i].innerHTML = tree.toCSS();
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+
+    var template = ['<ul>',
+                        '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+                        '<li><label>[0]</label><pre>{current}</pre></li>',
+                        '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+                    '</ul>'].join('\n');
+
+    var elem = document.createElement('div'), timer, content;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p><a href="' + href   + '">' + href + "</a> ";
+
+    if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+            template.replace(/\[(-?\d)\]/g, function (_, i) {
+                return (parseInt(e.line) + parseInt(i)) || '';
+            }).replace(/\{(\d)\}/g, function (_, i) {
+                return e.extract[parseInt(i)] || '';
+            }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+                                      e.extract[1].slice(e.column)    + '</span>');
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #ee4444;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.ctx {',
+            'color: #dd4444;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/util/less/dist/less-1.1.0.min.js b/util/less/dist/less-1.1.0.min.js
new file mode 100644
index 0000000..ede454e
--- /dev/null
+++ b/util/less/dist/less-1.1.0.min.js
@@ -0,0 +1,16 @@
+//
+// LESS - Leaner CSS v1.1.0
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+//
+// LESS - Leaner CSS v1.1.0
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function v(a,b){var c="less-error-message:"+p(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+ [...]
+protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.hostname=="localhost"||location.port.length>0||g?"development":"production"),d.async=!1,d.poll=d.poll||(g?1e3:1500),d.watch=function(){return this.watchMode=!0},d.unwatch=function(){return this.watchMode=!1},d.env==="development"?(d.optimization=0,/!watch/.test(location.hash)&&d.watch(),d.watchTimer=setInterval(function(){d.watchMode&&n(func [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.1.1.js b/util/less/dist/less-1.1.1.js
new file mode 100644
index 0000000..3261620
--- /dev/null
+++ b/util/less/dist/less-1.1.1.js
@@ -0,0 +1,2710 @@
+//
+// LESS - Leaner CSS v1.1.1
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+    less = exports,
+    tree = require('less/tree');
+} else {
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        mime:  env && env.mime,         // MIME type of .less files
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+
+                callback(root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam,
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && !inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString && !inParam) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString && !inParam) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else if (c === '(' && !inString && !inParam) {
+                        chunk.push(c);
+                        inParam = true;
+                    } else if (c === ')' && !inString && inParam) {
+                        chunk.push(c);
+                        inParam = false;
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            root = new(tree.Ruleset)([], $(this.parsers.primary));
+            root.root = true;
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [];
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        lines = input.split('\n');
+                        line = getLine(e.index);
+
+                        for (var n = e.index, column = -1;
+                                 n >= 0 && input.charAt(n) !== '\n';
+                                 n--) { column++ }
+
+                        throw {
+                            type: e.type,
+                            message: e.message,
+                            filename: env.filename,
+                            index: e.index,
+                            line: typeof(line) === 'number' ? line + 1 : null,
+                            callLine: e.call && (getLine(e.call) + 1),
+                            callExtract: lines[getLine(e.call)],
+                            stack: e.stack,
+                            column: column,
+                            extract: [
+                                lines[line - 1],
+                                lines[line],
+                                lines[line + 1]
+                            ]
+                        };
+                    }
+                    if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+
+                    function getLine(index) {
+                        return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    name: "ParseError",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+                    if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args;
+
+                    if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+                    if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value;
+
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    if (value = $(this.expression)) {
+                                        params.push({ name: param.name, value: value });
+                                    } else {
+                                        throw new(Error)("Expected value");
+                                    }
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset);
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c;
+
+                c = $(this.combinator);
+                e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (e) { return new(tree.Element)(c, e) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '&' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+                    i += match[0].length - 1;
+                    selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+                } else {
+                    while (s = $(this.selector)) {
+                        selectors.push(s);
+                        $(this.comment);
+                        if (! $(',')) { break }
+                        $(this.comment);
+                    }
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url)) &&
+                    $(';')) {
+                    return new(tree.Import)(path, imports);
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import'])) {
+                    return value;
+                } else if (name = $(/^@media|@page|@-[-a-z]+/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (typeof(window) !== 'undefined') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math.round(number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math.round(n);
+        } else {
+	    throw {
+                error: "RuntimeError",
+                message: "math functions take numbers as parameters"
+            };
+        }
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args) {
+    this.name = name;
+    this.args = args;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            return tree.functions[this.name].apply(tree.functions, args);
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else if (rgb.length == 8) {
+        this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+        this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+    this.value = value.trim();
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(' ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+    var that = this;
+
+    this._path = path;
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (root) {
+            if (! root) {
+                throw new(Error)("Error parsing " + that.path);
+            }
+            that.root = root;
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function () {
+        if (this.css) {
+            return "@import " + this._path.toCSS() + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset;
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return ruleset.rules;
+        }
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(this.arguments, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index };
+                }
+            }
+        }
+        throw { message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    eval: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        this.value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return new(tree.Variable)('@' + name, that.index).eval(env).value;
+        });
+        return this;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + ";";
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > 1) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                for (var s = 0; s < this.selectors.length; s++) {
+                    for (var c = 0; c < context.length; c++) {
+                        paths.push(context[c].concat([this.selectors[s]]));
+                    }
+                }
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    if (this.elements[0].value === other.elements[0].value) {
+        return true;
+    } else {
+        return false;
+    }
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { message: "variable " + name + " is undefined",
+                    index: this.index };
+        }
+    }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+require('less/tree').jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'chrome-extension:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (root, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (root, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                styles[i].type      = 'text/css';
+                styles[i].innerHTML = tree.toCSS();
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+
+    var template = ['<ul>',
+                        '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+                        '<li><label>[0]</label><pre>{current}</pre></li>',
+                        '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+                    '</ul>'].join('\n');
+
+    var elem = document.createElement('div'), timer, content;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p><a href="' + href   + '">' + href + "</a> ";
+
+    if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+            template.replace(/\[(-?\d)\]/g, function (_, i) {
+                return (parseInt(e.line) + parseInt(i)) || '';
+            }).replace(/\{(\d)\}/g, function (_, i) {
+                return e.extract[parseInt(i)] || '';
+            }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+                                      e.extract[1].slice(e.column)    + '</span>');
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #ee4444;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.ctx {',
+            'color: #dd4444;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/util/less/dist/less-1.1.1.min.js b/util/less/dist/less-1.1.1.min.js
new file mode 100644
index 0000000..c204123
--- /dev/null
+++ b/util/less/dist/less-1.1.1.min.js
@@ -0,0 +1,16 @@
+//
+// LESS - Leaner CSS v1.1.1
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+//
+// LESS - Leaner CSS v1.1.1
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function v(a,b){var c="less-error-message:"+p(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+ [...]
+)),c("less/tree").find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},c("less/tree").jsify=function(a){return Array.isArray(a.value)&&a.value.length>1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)};var g=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-extension:"||location.protocol==="resource:";d.env=d.env||(location.hostname=="127.0.0.1"||location.hostname=="0.0.0.0"||location.ho [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.1.2.js b/util/less/dist/less-1.1.2.js
new file mode 100644
index 0000000..32a5e05
--- /dev/null
+++ b/util/less/dist/less-1.1.2.js
@@ -0,0 +1,2712 @@
+//
+// LESS - Leaner CSS v1.1.2
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+    less = exports,
+    tree = require('less/tree');
+} else {
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        mime:  env && env.mime,         // MIME type of .less files
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+
+                callback(root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam,
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && !inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString && !inParam) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString && !inParam) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else if (c === '(' && !inString && !inParam) {
+                        chunk.push(c);
+                        inParam = true;
+                    } else if (c === ')' && !inString && inParam) {
+                        chunk.push(c);
+                        inParam = false;
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            root = new(tree.Ruleset)([], $(this.parsers.primary));
+            root.root = true;
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [];
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        lines = input.split('\n');
+                        line = getLine(e.index);
+
+                        for (var n = e.index, column = -1;
+                                 n >= 0 && input.charAt(n) !== '\n';
+                                 n--) { column++ }
+
+                        throw {
+                            type: e.type,
+                            message: e.message,
+                            filename: env.filename,
+                            index: e.index,
+                            line: typeof(line) === 'number' ? line + 1 : null,
+                            callLine: e.call && (getLine(e.call) + 1),
+                            callExtract: lines[getLine(e.call)],
+                            stack: e.stack,
+                            column: column,
+                            extract: [
+                                lines[line - 1],
+                                lines[line],
+                                lines[line + 1]
+                            ]
+                        };
+                    }
+                    if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+
+                    function getLine(index) {
+                        return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    name: "ParseError",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+                    if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args;
+
+                    if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+                    if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value;
+
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    if (value = $(this.expression)) {
+                                        params.push({ name: param.name, value: value });
+                                    } else {
+                                        throw new(Error)("Expected value");
+                                    }
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset);
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c;
+
+                c = $(this.combinator);
+                e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (e) { return new(tree.Element)(c, e) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '&' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+                    i += match[0].length - 1;
+                    selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+                } else {
+                    while (s = $(this.selector)) {
+                        selectors.push(s);
+                        $(this.comment);
+                        if (! $(',')) { break }
+                        $(this.comment);
+                    }
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url)) &&
+                    $(';')) {
+                    return new(tree.Import)(path, imports);
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import'])) {
+                    return value;
+                } else if (name = $(/^@media|@page|@-[-a-z]+/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (typeof(window) !== 'undefined') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math.round(number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math.round(n);
+        } else {
+	    throw {
+                error: "RuntimeError",
+                message: "math functions take numbers as parameters"
+            };
+        }
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args) {
+    this.name = name;
+    this.args = args;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            return tree.functions[this.name].apply(tree.functions, args);
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else if (rgb.length == 8) {
+        this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+        this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+    this.value = value.trim();
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(' ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+    var that = this;
+
+    this._path = path;
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (root) {
+            if (! root) {
+                throw new(Error)("Error parsing " + that.path);
+            }
+            that.root = root;
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function () {
+        if (this.css) {
+            return "@import " + this._path.toCSS() + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset;
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return ruleset.rules;
+        }
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index };
+                }
+            }
+        }
+        throw { message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    eval: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return v.value || v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + ";";
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > 1) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                for (var s = 0; s < this.selectors.length; s++) {
+                    for (var c = 0; c < context.length; c++) {
+                        paths.push(context[c].concat([this.selectors[s]]));
+                    }
+                }
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    if (this.elements[0].value === other.elements[0].value) {
+        return true;
+    } else {
+        return false;
+    }
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { message: "variable " + name + " is undefined",
+                    index: this.index };
+        }
+    }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+require('less/tree').jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'chrome-extension:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (root, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (root, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                styles[i].type      = 'text/css';
+                styles[i].innerHTML = tree.toCSS();
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+
+    var template = ['<ul>',
+                        '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+                        '<li><label>[0]</label><pre>{current}</pre></li>',
+                        '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+                    '</ul>'].join('\n');
+
+    var elem = document.createElement('div'), timer, content;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p><a href="' + href   + '">' + href + "</a> ";
+
+    if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+            template.replace(/\[(-?\d)\]/g, function (_, i) {
+                return (parseInt(e.line) + parseInt(i)) || '';
+            }).replace(/\{(\d)\}/g, function (_, i) {
+                return e.extract[parseInt(i)] || '';
+            }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+                                      e.extract[1].slice(e.column)    + '</span>');
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #ee4444;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.ctx {',
+            'color: #dd4444;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/util/less/dist/less-1.1.2.min.js b/util/less/dist/less-1.1.2.min.js
new file mode 100644
index 0000000..9b2fc8a
--- /dev/null
+++ b/util/less/dist/less-1.1.2.min.js
@@ -0,0 +1,16 @@
+//
+// LESS - Leaner CSS v1.1.2
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+//
+// LESS - Leaner CSS v1.1.2
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function v(a,b){var c="less-error-message:"+p(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+ [...]
+if(d=a.variable(e))return d.value.eval(b)}))return c;throw{message:"variable "+e+" is undefined",index:this.index}}}}(c("less/tree")),c("less/tree").find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},c("less/tree").jsify=function(a){return Array.isArray(a.value)&&a.value.length>1?"["+a.value.map(function(a){return a.toCSS(!1)}).join(", ")+"]":a.toCSS(!1)};var g=location.protocol==="file:"||location.protocol==="chrome:"||location.protocol==="chrome-e [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.1.3.js b/util/less/dist/less-1.1.3.js
new file mode 100644
index 0000000..cc80101
--- /dev/null
+++ b/util/less/dist/less-1.1.3.js
@@ -0,0 +1,2721 @@
+//
+// LESS - Leaner CSS v1.1.3
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+    less = exports,
+    tree = require('less/tree');
+} else {
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        mime:  env && env.mime,         // MIME type of .less files
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+
+                callback(root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam,
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && !inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString && !inParam) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString && !inParam) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else if (c === '(' && !inString && !inParam) {
+                        chunk.push(c);
+                        inParam = true;
+                    } else if (c === ')' && !inString && inParam) {
+                        chunk.push(c);
+                        inParam = false;
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            root = new(tree.Ruleset)([], $(this.parsers.primary));
+            root.root = true;
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [];
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        lines = input.split('\n');
+                        line = getLine(e.index);
+
+                        for (var n = e.index, column = -1;
+                                 n >= 0 && input.charAt(n) !== '\n';
+                                 n--) { column++ }
+
+                        throw {
+                            type: e.type,
+                            message: e.message,
+                            filename: env.filename,
+                            index: e.index,
+                            line: typeof(line) === 'number' ? line + 1 : null,
+                            callLine: e.call && (getLine(e.call) + 1),
+                            callExtract: lines[getLine(e.call)],
+                            stack: e.stack,
+                            column: column,
+                            extract: [
+                                lines[line - 1],
+                                lines[line],
+                                lines[line + 1]
+                            ]
+                        };
+                    }
+                    if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+
+                    function getLine(index) {
+                        return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    name: "ParseError",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+                    if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args, index = i;
+
+                    if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+                    if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value;
+
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    if (value = $(this.expression)) {
+                                        params.push({ name: param.name, value: value });
+                                    } else {
+                                        throw new(Error)("Expected value");
+                                    }
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset);
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c;
+
+                c = $(this.combinator);
+                e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (e) { return new(tree.Element)(c, e) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '&' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+                    i += match[0].length - 1;
+                    selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+                } else {
+                    while (s = $(this.selector)) {
+                        selectors.push(s);
+                        $(this.comment);
+                        if (! $(',')) { break }
+                        $(this.comment);
+                    }
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url)) &&
+                    $(';')) {
+                    return new(tree.Import)(path, imports);
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import'])) {
+                    return value;
+                } else if (name = $(/^@media|@page|@-[-a-z]+/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (typeof(window) !== 'undefined') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math.round(number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math.round(n);
+        } else {
+	    throw {
+                error: "RuntimeError",
+                message: "math functions take numbers as parameters"
+            };
+        }
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { message: "error evaluating function `" + this.name + "`",
+                        index: this.index };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else if (rgb.length == 8) {
+        this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+        this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+    this.value = value.trim();
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(' ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+    var that = this;
+
+    this._path = path;
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (root) {
+            if (! root) {
+                throw new(Error)("Error parsing " + that.path);
+            }
+            that.root = root;
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function () {
+        if (this.css) {
+            return "@import " + this._path.toCSS() + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset;
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return ruleset.rules;
+        }
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index };
+                }
+            }
+        }
+        throw { message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    eval: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return v.value || v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + ";";
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > 1) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                for (var s = 0; s < this.selectors.length; s++) {
+                    for (var c = 0; c < context.length; c++) {
+                        paths.push(context[c].concat([this.selectors[s]]));
+                    }
+                }
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    if (this.elements[0].value === other.elements[0].value) {
+        return true;
+    } else {
+        return false;
+    }
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { message: "variable " + name + " is undefined",
+                    index: this.index };
+        }
+    }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+require('less/tree').jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'chrome-extension:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (root, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (root, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                styles[i].type      = 'text/css';
+                styles[i].innerHTML = tree.toCSS();
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+
+    var template = ['<ul>',
+                        '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+                        '<li><label>[0]</label><pre>{current}</pre></li>',
+                        '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+                    '</ul>'].join('\n');
+
+    var elem = document.createElement('div'), timer, content;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p><a href="' + href   + '">' + href + "</a> ";
+
+    if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+            template.replace(/\[(-?\d)\]/g, function (_, i) {
+                return (parseInt(e.line) + parseInt(i)) || '';
+            }).replace(/\{(\d)\}/g, function (_, i) {
+                return e.extract[parseInt(i)] || '';
+            }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+                                      e.extract[1].slice(e.column)    + '</span>');
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #ee4444;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.ctx {',
+            'color: #dd4444;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/util/less/dist/less-1.1.3.min.js b/util/less/dist/less-1.1.3.min.js
new file mode 100644
index 0000000..6e4d5cf
--- /dev/null
+++ b/util/less/dist/less-1.1.3.min.js
@@ -0,0 +1,16 @@
+//
+// LESS - Leaner CSS v1.1.3
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+//
+// LESS - Leaner CSS v1.1.3
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function v(a,b){var c="less-error-message:"+p(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+ [...]
+.index=b},a.Variable.prototype={eval:function(b){var c,d,e=this.name;e.indexOf("@@")==0&&(e="@"+(new a.Variable(e.slice(1))).eval(b).value);if(c=a.find(b.frames,function(a){if(d=a.variable(e))return d.value.eval(b)}))return c;throw{message:"variable "+e+" is undefined",index:this.index}}}}(c("less/tree")),c("less/tree").find=function(a,b){for(var c=0,d;c<a.length;c++)if(d=b.call(a,a[c]))return d;return null},c("less/tree").jsify=function(a){return Array.isArray(a.value)&&a.value.length>1 [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.1.4.js b/util/less/dist/less-1.1.4.js
new file mode 100644
index 0000000..cb27c43
--- /dev/null
+++ b/util/less/dist/less-1.1.4.js
@@ -0,0 +1,2769 @@
+//
+// LESS - Leaner CSS v1.1.4
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+    less = exports,
+    tree = require('less/tree');
+} else {
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        mime:  env && env.mime,         // MIME type of .less files
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+
+                callback(root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam,
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && !inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString && !inParam) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString && !inParam) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else if (c === '(' && !inString && !inParam) {
+                        chunk.push(c);
+                        inParam = true;
+                    } else if (c === ')' && !inString && inParam) {
+                        chunk.push(c);
+                        inParam = false;
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            root = new(tree.Ruleset)([], $(this.parsers.primary));
+            root.root = true;
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [];
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        lines = input.split('\n');
+                        line = getLine(e.index);
+
+                        for (var n = e.index, column = -1;
+                                 n >= 0 && input.charAt(n) !== '\n';
+                                 n--) { column++ }
+
+                        throw {
+                            type: e.type,
+                            message: e.message,
+                            filename: env.filename,
+                            index: e.index,
+                            line: typeof(line) === 'number' ? line + 1 : null,
+                            callLine: e.call && (getLine(e.call) + 1),
+                            callExtract: lines[getLine(e.call)],
+                            stack: e.stack,
+                            column: column,
+                            extract: [
+                                lines[line - 1],
+                                lines[line],
+                                lines[line + 1]
+                            ]
+                        };
+                    }
+                    if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+
+                    function getLine(index) {
+                        return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    name: "ParseError",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+                    if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args, index = i;
+
+                    if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+                    if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value;
+
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    if (value = $(this.expression)) {
+                                        params.push({ name: param.name, value: value });
+                                    } else {
+                                        throw new(Error)("Expected value");
+                                    }
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset);
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c;
+
+                c = $(this.combinator);
+                e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/) || $(/^(?:\d*\.)?\d+%/);
+
+                if (e) { return new(tree.Element)(c, e) }
+
+                if (c.value && c.value[0] === '&') {
+                  return new(tree.Element)(c, null);
+                }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === '&') {
+                    match = '&';
+                    i++;
+                    if(input.charAt(i) === ' ') {
+                        match = '& ';
+                    }
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(match);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                if (match = /^([.#:% \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+                    i += match[0].length - 1;
+                    selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+                } else {
+                    while (s = $(this.selector)) {
+                        selectors.push(s);
+                        $(this.comment);
+                        if (! $(',')) { break }
+                        $(this.comment);
+                    }
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url)) &&
+                    $(';')) {
+                    return new(tree.Import)(path, imports);
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import'])) {
+                    return value;
+                } else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-)?keyframes/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (typeof(window) !== 'undefined') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math.round(number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math.round(n);
+        } else {
+	    throw {
+                error: "RuntimeError",
+                message: "math functions take numbers as parameters"
+            };
+        }
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { message: "error evaluating function `" + this.name + "`",
+                        index: this.index };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else if (rgb.length == 8) {
+        this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+        this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+    this.value = value ? value.trim() : "";
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else if (value === '& ') {
+        this.value = '& ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        '& ' : ' ',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(' ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+    var that = this;
+
+    this._path = path;
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (root) {
+            if (! root) {
+                throw new(Error)("Error parsing " + that.path);
+            }
+            that.root = root;
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function () {
+        if (this.css) {
+            return "@import " + this._path.toCSS() + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset;
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return ruleset.rules;
+        }
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index };
+                }
+            }
+        }
+        throw { message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    eval: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return v.value || v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + ";";
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > 1) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                this.joinSelectors( paths, context, this.selectors );
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+        var before = [], after = [], beforeElements = [],
+            afterElements = [], hasParentSelector = false, el;
+
+        for (var i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.combinator.value[0] === '&') {
+                hasParentSelector = true;
+            }
+            if (hasParentSelector) afterElements.push(el);
+            else                   beforeElements.push(el);
+        }
+
+        if (! hasParentSelector) {
+            afterElements = beforeElements;
+            beforeElements = [];
+        }
+
+        if (beforeElements.length > 0) {
+            before.push(new(tree.Selector)(beforeElements));
+        }
+
+        if (afterElements.length > 0) {
+            after.push(new(tree.Selector)(afterElements));
+        }
+
+        for (var c = 0; c < context.length; c++) {
+            paths.push(before.concat(context[c]).concat(after));
+        }
+    }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    if (this.elements[0].value === other.elements[0].value) {
+        return true;
+    } else {
+        return false;
+    }
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { message: "variable " + name + " is undefined",
+                    index: this.index };
+        }
+    }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+require('less/tree').jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'chrome-extension:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (root, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (root, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                styles[i].type      = 'text/css';
+                styles[i].innerHTML = tree.toCSS();
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+
+    var template = ['<ul>',
+                        '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+                        '<li><label>[0]</label><pre>{current}</pre></li>',
+                        '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+                    '</ul>'].join('\n');
+
+    var elem = document.createElement('div'), timer, content;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p><a href="' + href   + '">' + href + "</a> ";
+
+    if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+            template.replace(/\[(-?\d)\]/g, function (_, i) {
+                return (parseInt(e.line) + parseInt(i)) || '';
+            }).replace(/\{(\d)\}/g, function (_, i) {
+                return e.extract[parseInt(i)] || '';
+            }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+                                      e.extract[1].slice(e.column)    + '</span>');
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #ee4444;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.ctx {',
+            'color: #dd4444;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/util/less/dist/less-1.1.4.min.js b/util/less/dist/less-1.1.4.min.js
new file mode 100644
index 0000000..182b526
--- /dev/null
+++ b/util/less/dist/less-1.1.4.min.js
@@ -0,0 +1,16 @@
+//
+// LESS - Leaner CSS v1.1.4
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+//
+// LESS - Leaner CSS v1.1.4
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function u(a,b){var c="less-error-message:"+o(b),e=["<ul>",'<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',"<li><label>[0]</label><pre>{current}</pre></li>",'<li><label>[1]</label><pre class="ctx">{2}</pre></li>',"</ul>"].join("\n"),f=document.createElement("div"),g,h;f.id=c,f.className="less-error-message",h="<h3>"+(a.message||"There is an error in your .less file")+"</h3>"+'<p><a href="'+b+'">'+b+"</a> ",a.extract&&(h+="on line "+a.line+", column "+(a.column+1)+ [...]
+.mime+this.attrs.charset+this.attrs.base64+this.attrs.data:this.value.toCSS())+")"},eval:function(a){return this.attrs?this:new b.URL(this.value.eval(a),this.paths)}}}(c("less/tree")),function(a){a.Value=function(a){this.value=a,this.is="value"},a.Value.prototype={eval:function(b){return this.value.length===1?this.value[0].eval(b):new a.Value(this.value.map(function(a){return a.eval(b)}))},toCSS:function(a){return this.value.map(function(b){return b.toCSS(a)}).join(a.compress?",":", ")}} [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.1.5.js b/util/less/dist/less-1.1.5.js
new file mode 100644
index 0000000..0f375d7
--- /dev/null
+++ b/util/less/dist/less-1.1.5.js
@@ -0,0 +1,2805 @@
+//
+// LESS - Leaner CSS v1.1.5
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    less = {};
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        mime:  env && env.mime,         // MIME type of .less files
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+
+                callback(root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam,
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && !inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString && !inParam) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString && !inParam) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else if (c === '(' && !inString && !inParam) {
+                        chunk.push(c);
+                        inParam = true;
+                    } else if (c === ')' && !inString && inParam) {
+                        chunk.push(c);
+                        inParam = false;
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            root = new(tree.Ruleset)([], $(this.parsers.primary));
+            root.root = true;
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [];
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        lines = input.split('\n');
+                        line = getLine(e.index);
+
+                        for (var n = e.index, column = -1;
+                                 n >= 0 && input.charAt(n) !== '\n';
+                                 n--) { column++ }
+
+                        throw {
+                            type: e.type,
+                            message: e.message,
+                            filename: env.filename,
+                            index: e.index,
+                            line: typeof(line) === 'number' ? line + 1 : null,
+                            callLine: e.call && (getLine(e.call) + 1),
+                            callExtract: lines[getLine(e.call)],
+                            stack: e.stack,
+                            column: column,
+                            extract: [
+                                lines[line - 1],
+                                lines[line],
+                                lines[line + 1]
+                            ]
+                        };
+                    }
+                    if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+
+                    function getLine(index) {
+                        return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    name: "ParseError",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { return new(tree.Keyword)(k) }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args, index = i;
+
+                    if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+                    if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value;
+
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    if (value = $(this.expression)) {
+                                        params.push({ name: param.name, value: value });
+                                    } else {
+                                        throw new(Error)("Expected value");
+                                    }
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset);
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c;
+
+                c = $(this.combinator);
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+                    $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (e) { return new(tree.Element)(c, e, i) }
+
+                if (c.value && c.value.charAt(0) === '&') {
+                    return new(tree.Element)(c, null, i);
+                }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === '&') {
+                    match = '&';
+                    i++;
+                    if(input.charAt(i) === ' ') {
+                        match = '& ';
+                    }
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(match);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url)) &&
+                    $(';')) {
+                    return new(tree.Import)(path, imports);
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import'])) {
+                    return value;
+                } else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-|-moz-)?keyframes/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math.round(number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math.round(n);
+        } else {
+	    throw {
+                error: "RuntimeError",
+                message: "math functions take numbers as parameters"
+            };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { message: "error evaluating function `" + this.name + "`",
+                        index: this.index };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+    this.value = value ? value.trim() : "";
+    this.index = index;
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else if (value === '& ') {
+        this.value = '& ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        '& ' : ' ',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+    var that = this;
+
+    this._path = path;
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css(\?.*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (root) {
+            if (! root) {
+                throw new(Error)("Error parsing " + that.path);
+            }
+            that.root = root;
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function () {
+        if (this.css) {
+            return "@import " + this._path.toCSS() + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset;
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index };
+                }
+            }
+        }
+        throw { message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    eval: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return v.value || v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + ";";
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                this.joinSelectors( paths, context, this.selectors );
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+        var before = [], after = [], beforeElements = [],
+            afterElements = [], hasParentSelector = false, el;
+
+        for (var i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.combinator.value.charAt(0) === '&') {
+                hasParentSelector = true;
+            }
+            if (hasParentSelector) afterElements.push(el);
+            else                   beforeElements.push(el);
+        }
+
+        if (! hasParentSelector) {
+            afterElements = beforeElements;
+            beforeElements = [];
+        }
+
+        if (beforeElements.length > 0) {
+            before.push(new(tree.Selector)(beforeElements));
+        }
+
+        if (afterElements.length > 0) {
+            after.push(new(tree.Selector)(afterElements));
+        }
+
+        for (var c = 0; c < context.length; c++) {
+            paths.push(before.concat(context[c]).concat(after));
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    var len  = this.elements.length,
+        olen = other.elements.length,
+        max  = Math.min(len, olen);
+
+    if (len < olen) {
+        return false;
+    } else {
+        for (var i = 0; i < max; i++) {
+            if (this.elements[i].value !== other.elements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (less.mode === 'browser' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { message: "variable " + name + " is undefined",
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+require('./tree').find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+require('./tree').jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'chrome-extension:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (root, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (root, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                var css = tree.toCSS();
+                var style = styles[i];
+                try {
+                    style.innerHTML = css;
+                } catch (_) {
+                    style.styleSheets.cssText = css;
+                }
+                style.type = 'text/css';
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+
+    var template = ['<ul>',
+                        '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+                        '<li><label>[0]</label><pre>{current}</pre></li>',
+                        '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+                    '</ul>'].join('\n');
+
+    var elem = document.createElement('div'), timer, content;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p><a href="' + href   + '">' + href + "</a> ";
+
+    if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+            template.replace(/\[(-?\d)\]/g, function (_, i) {
+                return (parseInt(e.line) + parseInt(i)) || '';
+            }).replace(/\{(\d)\}/g, function (_, i) {
+                return e.extract[parseInt(i)] || '';
+            }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+                                      e.extract[1].slice(e.column)    + '</span>');
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #ee4444;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.ctx {',
+            'color: #dd4444;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/util/less/dist/less-1.1.5.min.js b/util/less/dist/less-1.1.5.min.js
new file mode 100644
index 0000000..49949fb
--- /dev/null
+++ b/util/less/dist/less-1.1.5.min.js
@@ -0,0 +1,9 @@
+//
+// LESS - Leaner CSS v1.1.5
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function l(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(j)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];try{f.innerHTML=e}catch(g){f.styleSheets.cssText=e}f.type="text/css"})}function m(a,b){for(var c=0;c<d.sheets.length;c++)n(d.sheets[c],a,b,d.sheets.length-(c+1))}function n(b,c,e,f){var h=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/ [...]
+;return!0},a.Selector.prototype.toCSS=function(a){return this._css?this._css:this._css=this.elements.map(function(b){return typeof b=="string"?" "+b.trim():b.toCSS(a)}).join("")}}(c("../tree")),function(a){a.URL=function(a,b){a.data?this.attrs=a:(d.mode==="browser"&&!/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(a.value)&&b.length>0&&(a.value=b[0]+(a.value.charAt(0)==="/"?a.value.slice(1):a.value)),this.value=a,this.paths=b)},a.URL.prototype={toCSS:function(){return"url("+(this.attrs?"data: [...]
diff --git a/util/less/dist/less-1.1.6.js b/util/less/dist/less-1.1.6.js
new file mode 100644
index 0000000..93014ee
--- /dev/null
+++ b/util/less/dist/less-1.1.6.js
@@ -0,0 +1,3004 @@
+//
+// LESS - Leaner CSS v1.1.6
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    less = {};
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        mime:  env && env.mime,         // MIME type of .less files
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+
+                callback(root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam,
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && !inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString && !inParam) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString && !inParam) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else if (c === '(' && !inString && !inParam) {
+                        chunk.push(c);
+                        inParam = true;
+                    } else if (c === ')' && !inString && inParam) {
+                        chunk.push(c);
+                        inParam = false;
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            root = new(tree.Ruleset)([], $(this.parsers.primary));
+            root.root = true;
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [];
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        lines = input.split('\n');
+                        line = getLine(e.index);
+
+                        for (var n = e.index, column = -1;
+                                 n >= 0 && input.charAt(n) !== '\n';
+                                 n--) { column++ }
+
+                        throw {
+                            type: e.type,
+                            message: e.message,
+                            filename: env.filename,
+                            index: e.index,
+                            line: typeof(line) === 'number' ? line + 1 : null,
+                            callLine: e.call && (getLine(e.call) + 1),
+                            callExtract: lines[getLine(e.call)],
+                            stack: e.stack,
+                            column: column,
+                            extract: [
+                                lines[line - 1],
+                                lines[line],
+                                lines[line + 1]
+                            ]
+                        };
+                    }
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('./cssmin').compressor.cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+
+                    function getLine(index) {
+                        return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    name: "ParseError",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { 
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k) 
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+                    if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value;
+
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    if (value = $(this.expression)) {
+                                        params.push({ name: param.name, value: value });
+                                    } else {
+                                        throw new(Error)("Expected value");
+                                    }
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset);
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c;
+
+                c = $(this.combinator);
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+                    $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (e) { return new(tree.Element)(c, e, i) }
+
+                if (c.value && c.value.charAt(0) === '&') {
+                    return new(tree.Element)(c, null, i);
+                }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === '&') {
+                    match = '&';
+                    i++;
+                    if(input.charAt(i) === ' ') {
+                        match = '& ';
+                    }
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(match);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url)) &&
+                    $(';')) {
+                    return new(tree.Import)(path, imports);
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import'])) {
+                    return value;
+                } else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/) || $('keyframes')) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        return this._math('round', n);
+    },
+    ceil: function (n) {
+        return this._math('ceil', n);
+    },
+    floor: function (n) {
+        return this._math('floor', n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math[fn](n);
+        } else {
+            throw {
+                error: "RuntimeError",
+                message: "math functions take numbers as parameters"
+            };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { message: "error evaluating function `" + this.name + "`",
+                        index: this.index };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+    this.value = value ? value.trim() : "";
+    this.index = index;
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else if (value === '& ') {
+        this.value = '& ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        '& ' : ' ',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+    var that = this;
+
+    this._path = path;
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css(\?.*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (root) {
+            if (! root) {
+                throw new(Error)("Error parsing " + that.path);
+            }
+            that.root = root;
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function () {
+        if (this.css) {
+            return "@import " + this._path.toCSS() + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset;
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index };
+                }
+            }
+        }
+        throw { message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    eval: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return v.value || v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + ";";
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                this.joinSelectors( paths, context, this.selectors );
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+        var before = [], after = [], beforeElements = [],
+            afterElements = [], hasParentSelector = false, el;
+
+        for (var i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.combinator.value.charAt(0) === '&') {
+                hasParentSelector = true;
+            }
+            if (hasParentSelector) afterElements.push(el);
+            else                   beforeElements.push(el);
+        }
+
+        if (! hasParentSelector) {
+            afterElements = beforeElements;
+            beforeElements = [];
+        }
+
+        if (beforeElements.length > 0) {
+            before.push(new(tree.Selector)(beforeElements));
+        }
+
+        if (afterElements.length > 0) {
+            after.push(new(tree.Selector)(afterElements));
+        }
+
+        for (var c = 0; c < context.length; c++) {
+            paths.push(before.concat(context[c]).concat(after));
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    var len  = this.elements.length,
+        olen = other.elements.length,
+        max  = Math.min(len, olen);
+
+    if (len < olen) {
+        return false;
+    } else {
+        for (var i = 0; i < max; i++) {
+            if (this.elements[i].value !== other.elements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { message: "variable " + name + " is undefined",
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+require('./tree').find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+require('./tree').jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'chrome-extension:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (root, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (root, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                var css = tree.toCSS();
+                var style = styles[i];
+                try {
+                    style.innerHTML = css;
+                } catch (_) {
+                    style.styleSheets.cssText = css;
+                }
+                style.type = 'text/css';
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+
+    var template = ['<ul>',
+                        '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+                        '<li><label>[0]</label><pre>{current}</pre></li>',
+                        '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+                    '</ul>'].join('\n');
+
+    var elem = document.createElement('div'), timer, content;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p><a href="' + href   + '">' + href + "</a> ";
+
+    if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+            template.replace(/\[(-?\d)\]/g, function (_, i) {
+                return (parseInt(e.line) + parseInt(i)) || '';
+            }).replace(/\{(\d)\}/g, function (_, i) {
+                return e.extract[parseInt(i)] || '';
+            }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+                                      e.extract[1].slice(e.column)    + '</span>');
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #ee4444;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.ctx {',
+            'color: #dd4444;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/util/less/dist/less-1.1.6.min.js b/util/less/dist/less-1.1.6.min.js
new file mode 100644
index 0000000..a30623b
--- /dev/null
+++ b/util/less/dist/less-1.1.6.min.js
@@ -0,0 +1,9 @@
+//
+// LESS - Leaner CSS v1.1.6
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function l(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(j)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];try{f.innerHTML=e}catch(g){f.styleSheets.cssText=e}f.type="text/css"})}function m(a,b){for(var c=0;c<d.sheets.length;c++)n(d.sheets[c],a,b,d.sheets.length-(c+1))}function n(b,c,e,f){var h=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/ [...]
+)}}}(c("../tree")),function(a){a.Rule=function(b,c,d,e){this.name=b,this.value=c instanceof a.Value?c:new a.Value([c]),this.important=d?" "+d.trim():"",this.index=e,b.charAt(0)==="@"?this.variable=!0:this.variable=!1},a.Rule.prototype.toCSS=function(a){return this.variable?"":this.name+(a.compress?":":": ")+this.value.toCSS(a)+this.important+";"},a.Rule.prototype.eval=function(b){return new a.Rule(this.name,this.value.eval(b),this.important,this.index)},a.Shorthand=function(a,b){this.a=a [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.2.0.js b/util/less/dist/less-1.2.0.js
new file mode 100644
index 0000000..df376ae
--- /dev/null
+++ b/util/less/dist/less-1.2.0.js
@@ -0,0 +1,3293 @@
+//
+// LESS - Leaner CSS v1.2.0
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    if (typeof(window) === 'undefined') { less = {} }
+    else                                { less = window.less = {} }
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        mime:  env && env.mime,         // MIME type of .less files
+        error: null,                    // Error in parsing/evaluating an import
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (e, root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+
+                if (e && !that.error) { that.error = e }
+                callback(e, root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    function expect(arg, msg) {
+        var result = $(arg);
+        if (! result) {
+            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+                                                   : "unexpected token"));
+        } else {
+            return result;
+        }
+    }
+
+    function error(msg, type) {
+        throw { index: i, type: type || 'Syntax', message: msg };
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    function getLocation(index) {
+        for (var n = index, column = -1;
+                 n >= 0 && input.charAt(n) !== '\n';
+                 n--) { column++ }
+
+        return { line:   index ? (input.slice(0, index).match(/\n/g) || "").length : null,
+                 column: column };
+    }
+
+    function LessError(e, env) {
+        var lines = input.split('\n'),
+            loc = getLocation(e.index),
+            line = loc.line,
+            col  = loc.column;
+
+        this.type = e.type || 'SyntaxError';
+        this.message = e.message;
+        this.filename = e.filename || env.filename;
+        this.index = e.index;
+        this.line = typeof(line) === 'number' ? line + 1 : null;
+        this.callLine = e.call && (getLocation(e.call) + 1);
+        this.callExtract = lines[getLocation(e.call)];
+        this.stack = e.stack;
+        this.column = col;
+        this.extract = [
+            lines[line - 1],
+            lines[line],
+            lines[line + 1]
+        ];
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam,
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && !inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString && !inParam) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString && !inParam) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else if (c === '(' && !inString && !inParam) {
+                        chunk.push(c);
+                        inParam = true;
+                    } else if (c === ')' && !inString && inParam) {
+                        chunk.push(c);
+                        inParam = false;
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            try {
+                root = new(tree.Ruleset)([], $(this.parsers.primary));
+                root.root = true;
+            } catch (e) {
+                return callback(new(LessError)(e, env));
+            }
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [];
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        throw new(LessError)(e, env);
+                    }
+
+                    if (parser.imports.error) { throw parser.imports.error }
+
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('./cssmin').compressor.cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    type: "Parse",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { 
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k);
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+
+                    expect(')');
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i), important = false;
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if ($(this.important)) {
+                        important = true;
+                    }
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index, important);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value, cond;
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    save();
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    value = expect(this.expression, 'expected expression');
+                                    params.push({ name: param.name, value: value });
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        expect(')');
+
+                        if ($(/^when/)) { // Guard
+                            cond = expect(this.conditions, 'expected condition');
+                        }
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset, cond);
+                        } else {
+                            restore();
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    expect(')');
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c, v;
+
+                c = $(this.combinator);
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+                    $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (! e) {
+                    $('(') && (v = $(this.entities.variable)) && $(')') && (e = new(tree.Paren)(v));
+                }
+
+                if (e) { return new(tree.Element)(c, e, i) }
+
+                if (c.value && c.value.charAt(0) === '&') {
+                    return new(tree.Element)(c, null, i);
+                }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === '&') {
+                    match = '&';
+                    i++;
+                    if(input.charAt(i) === ' ') {
+                        match = '& ';
+                    }
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(match);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path, features;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url))) {
+                    features = $(this.mediaFeatures);
+                    if ($(';')) {
+                        return new(tree.Import)(path, imports, features);
+                    }
+                }
+            },
+
+            mediaFeature: function () {
+                var nodes = [];
+
+                do {
+                    if (e = $(this.entities.keyword)) {
+                        nodes.push(e);
+                    } else if ($('(')) {
+                        p = $(this.property);
+                        e = $(this.entity);
+                        if ($(')')) {
+                            if (p && e) {
+                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+                            } else if (e) {
+                                nodes.push(new(tree.Paren)(e));
+                            } else {
+                                return null;
+                            }
+                        } else { return null }
+                    }
+                } while (e);
+
+                if (nodes.length > 0) {
+                    return new(tree.Expression)(nodes);
+                }
+            },
+
+            mediaFeatures: function () {
+                var f, features = [];
+                while (f = $(this.mediaFeature)) {
+                    features.push(f);
+                    if (! $(',')) { break }
+                }
+                return features.length > 0 ? features : null;
+            },
+
+            media: function () {
+                var features;
+
+                if ($(/^@media/)) {
+                    features = $(this.mediaFeatures);
+
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)('@media', rules, features);
+                    }
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types, e, nodes;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import']) || $(this.media)) {
+                    return value;
+                } else if (name = $(/^@page|@keyframes/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            conditions: function () {
+                var a, b, index = i, condition;
+
+                if (a = $(this.condition)) {
+                    while ($(',') && (b = $(this.condition))) {
+                        condition = new(tree.Condition)('or', condition || a, b, index);
+                    }
+                    return condition || a;
+                }
+            },
+            condition: function () {
+                var a, b, c, op, index = i, negate = false;
+
+                if ($(/^not/)) { negate = true }
+                expect('(');
+                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                    if (op = $(/^(?:>=|=<|[<=>])/)) {
+                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                            c = new(tree.Condition)(op, a, b, index, negate);
+                        } else {
+                            error('expected expression');
+                        }
+                    } else {
+                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+                    }
+                    expect(')');
+                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        return this._math('round', n);
+    },
+    ceil: function (n) {
+        return this._math('ceil', n);
+    },
+    floor: function (n) {
+        return this._math('floor', n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math[fn](n);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    },
+    percentage: function (n) {
+        return new(tree.Dimension)(n.value * 100, '%');
+    },
+    color: function (n) {
+        if (n instanceof tree.Quoted) {
+            return new(tree.Color)(n.value.slice(1));
+        } else {
+            throw { type: "Argument", message: "argument must be a string" };
+        }
+    },
+    iscolor: function (n) {
+        return this._isa(n, tree.Color);
+    },
+    isnumber: function (n) {
+        return this._isa(n, tree.Dimension);
+    },
+    isstring: function (n) {
+        return this._isa(n, tree.Quoted);
+    },
+    iskeyword: function (n) {
+        return this._isa(n, tree.Keyword);
+    },
+    isurl: function (n) {
+        return this._isa(n, tree.URL);
+    },
+    ispixel: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+    },
+    ispercentage: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+    },
+    isem: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+    },
+    _isa: function (n, Type) {
+        return (n instanceof Type) ? tree.True : tree.False;
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { type: e.type || "Runtime",
+                        message: "error evaluating function `" + this.name + "`" +
+                                 (e.message ? ': ' + e.message : ''),
+                        index: this.index };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+    this.op = op.trim();
+    this.lvalue = l;
+    this.rvalue = r;
+    this.index = i;
+    this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+    var a = this.lvalue.eval(env),
+        b = this.rvalue.eval(env);
+
+    var i = this.index, result
+
+    var result = (function (op) {
+        switch (op) {
+            case 'and':
+                return a && b;
+            case 'or':
+                return a || b;
+            default:
+                if (a.compare) {
+                    result = a.compare(b);
+                } else if (b.compare) {
+                    result = b.compare(a);
+                } else {
+                    throw { type: "Type",
+                            message: "Unable to perform comparison",
+                            index: i };
+                }
+                switch (result) {
+                    case -1: return op === '<' || op === '=<';
+                    case  0: return op === '=' || op === '>=' || op === '=<';
+                    case  1: return op === '>' || op === '>=';
+                }
+        }
+    })(this.op);
+    return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    },
+
+    // TODO: Perform unit conversion before comparing
+    compare: function (other) {
+        if (other instanceof tree.Dimension) {
+            if (other.value > this.value) {
+                return -1;
+            } else if (other.value < this.value) {
+                return 1;
+            } else {
+                return 0;
+            }
+        } else {
+            return -1;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value, features) {
+    this.name = name;
+    this.features = features && new(tree.Value)(features);
+
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+        this.ruleset.allowImports = true;
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + features + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        this.features = this.features && this.features.eval(env);
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+
+    if (typeof(value) === 'string') {
+        this.value = value.trim();
+    } else if (value) {
+        this.value = value;
+    } else {
+        this.value = "";
+    }
+    this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+    return new(tree.Element)(this.combinator,
+                             this.value.eval ? this.value.eval(env) : this.value,
+                             this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + (this.value.toCSS ? this.value.toCSS(env) : this.value);
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else if (value === '& ') {
+        this.value = '& ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        '& ' : ' ',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS ? e.toCSS(env) : '';
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features) {
+    var that = this;
+
+    this._path = path;
+    this.features = features && new(tree.Value)(features);
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css(\?.*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (e, root) {
+            that.root = root;
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function (env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.css) {
+            return "@import " + this._path.toCSS() + features + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset, features = this.features && this.features.eval(env);
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return this.features ? new(tree.Directive)('@media', ruleset.rules, this.features.value) : ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value },
+    compare: function (other) {
+        if (other instanceof tree.Keyword) {
+            return other.value === this.value ? 0 : 1;
+        } else {
+            return -1;
+        }
+    }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, important) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+    this.important = important;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments, this.important).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { type:    'Runtime',
+                            message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index };
+                }
+            }
+        }
+        throw { type: 'Name',
+                message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.condition = condition;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    evalParams: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []);
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        return frame;
+    },
+    eval: function (env, args, important) {
+        var frame = this.evalParams(env, args), context, _arguments = [], rules;
+
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        rules = important ?
+            this.rules.map(function (r) {
+                return new(tree.Rule)(r.name, r.value, '!important', r.index);
+            }) : this.rules.slice(0);
+
+        return new(tree.Ruleset)(null, rules).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len, frame;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+        if (this.condition && !this.condition.eval({
+            frames: [this.evalParams(env, args)].concat(env.frames)
+        }))                                                           { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+    this.value = node;
+};
+tree.Paren.prototype = {
+    toCSS: function (env) {
+        return '(' + this.value.toCSS(env) + ')';
+    },
+    eval: function (env) {
+        return new(tree.Paren)(this.value.eval(env));
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return ('value' in v) ? v.value : v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+    this.inline = inline || false;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + (this.inline ? "" : ";");
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name,
+                          this.value.eval(context),
+                          this.important,
+                          this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+        ruleset.allowImports = this.allowImports;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root || ruleset.allowImports) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                this.joinSelectors(paths, context, this.selectors);
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+        var before = [], after = [], beforeElements = [],
+            afterElements = [], hasParentSelector = false, el;
+
+        for (var i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.combinator.value.charAt(0) === '&') {
+                hasParentSelector = true;
+            }
+            if (hasParentSelector) afterElements.push(el);
+            else                   beforeElements.push(el);
+        }
+
+        if (! hasParentSelector) {
+            afterElements = beforeElements;
+            beforeElements = [];
+        }
+
+        if (beforeElements.length > 0) {
+            before.push(new(tree.Selector)(beforeElements));
+        }
+
+        if (afterElements.length > 0) {
+            after.push(new(tree.Selector)(afterElements));
+        }
+
+        for (var c = 0; c < context.length; c++) {
+            paths.push(before.concat(context[c]).concat(after));
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    var len  = this.elements.length,
+        olen = other.elements.length,
+        max  = Math.min(len, olen);
+
+    if (len < olen) {
+        return false;
+    } else {
+        for (var i = 0; i < max; i++) {
+            if (this.elements[i].value !== other.elements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.eval = function (env) {
+    return new(tree.Selector)(this.elements.map(function (e) {
+        return e.eval(env);
+    }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { message: "variable " + name + " is undefined",
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+tree.jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'chrome-extension:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (root, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (root, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                var css = tree.toCSS();
+                var style = styles[i];
+                style.type = 'text/css';
+                if (style.styleSheet) {
+                    style.styleSheet.cssText = css;
+                } else {
+                    style.innerHTML = css;
+                }
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(root, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+
+    var template = ['<ul>',
+                        '<li><label>[-1]</label><pre class="ctx">{0}</pre></li>',
+                        '<li><label>[0]</label><pre>{current}</pre></li>',
+                        '<li><label>[1]</label><pre class="ctx">{2}</pre></li>',
+                    '</ul>'].join('\n');
+
+    var elem = document.createElement('div'), timer, content;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p><a href="' + href   + '">' + href + "</a> ";
+
+    if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+            template.replace(/\[(-?\d)\]/g, function (_, i) {
+                return (parseInt(e.line) + parseInt(i)) || '';
+            }).replace(/\{(\d)\}/g, function (_, i) {
+                return e.extract[parseInt(i)] || '';
+            }).replace(/\{current\}/, e.extract[1].slice(0, e.column) + '<span class="error">' +
+                                      e.extract[1].slice(e.column)    + '</span>');
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #ee4444;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.ctx {',
+            'color: #dd4444;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/util/less/dist/less-1.2.0.min.js b/util/less/dist/less-1.2.0.min.js
new file mode 100644
index 0000000..84e9047
--- /dev/null
+++ b/util/less/dist/less-1.2.0.min.js
@@ -0,0 +1,9 @@
+//
+// LESS - Leaner CSS v1.2.0
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function m(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(k)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];f.type="text/css",f.styleSheet?f.styleSheet.cssText=e:f.innerHTML=e})}function n(a,b){for(var c=0;c<d.sheets.length;c++)o(d.sheets[c],a,b,d.sheets.length-(c+1))}function o(b,c,e,f){var g=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/, [...]
+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymous(c.join(", ")):new a.Anonymous(c)}}}(c("../tree")),function(a){a.Keyword=function(a){this.value=a},a.Keyword.prototype={eval:function(){return this},toCSS:function(){return this.value},compare:function(b){return b instanceof a.Keyword?b.value===this.value?0:1:-1}},a.True=new a.Keyword("true"),a.False=new a.Keyword("false")}(c("../tree")), [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.2.1.js b/util/less/dist/less-1.2.1.js
new file mode 100644
index 0000000..3b33bc6
--- /dev/null
+++ b/util/less/dist/less-1.2.1.js
@@ -0,0 +1,3318 @@
+//
+// LESS - Leaner CSS v1.2.1
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    if (typeof(window) === 'undefined') { less = {} }
+    else                                { less = window.less = {} }
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        contents: {},                   // Holds the imported file contents
+        mime:  env && env.mime,         // MIME type of .less files
+        error: null,                    // Error in parsing/evaluating an import
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (e, root, contents) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+                that.contents[path] = contents;
+
+                if (e && !that.error) { that.error = e }
+                callback(e, root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    function expect(arg, msg) {
+        var result = $(arg);
+        if (! result) {
+            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+                                                   : "unexpected token"));
+        } else {
+            return result;
+        }
+    }
+
+    function error(msg, type) {
+        throw { index: i, type: type || 'Syntax', message: msg };
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    function getInput(e, env) {
+        if (e.filename && env.filename && (e.filename !== env.filename)) {
+            return parser.imports.contents[e.filename];
+        } else {
+            return input;
+        }
+    }
+
+    function getLocation(index, input) {
+        for (var n = index, column = -1;
+                 n >= 0 && input.charAt(n) !== '\n';
+                 n--) { column++ }
+
+        return { line:   typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+                 column: column };
+    }
+
+    function LessError(e, env) {
+        var input = getInput(e, env),
+            loc = getLocation(e.index, input),
+            line = loc.line,
+            col  = loc.column,
+            lines = input.split('\n');
+
+        this.type = e.type || 'Syntax';
+        this.message = e.message;
+        this.filename = e.filename || env.filename;
+        this.index = e.index;
+        this.line = typeof(line) === 'number' ? line + 1 : null;
+        this.callLine = e.call && (getLocation(e.call, input) + 1);
+        this.callExtract = lines[getLocation(e.call, input)];
+        this.stack = e.stack;
+        this.column = col;
+        this.extract = [
+            lines[line - 1],
+            lines[line],
+            lines[line + 1]
+        ];
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam,
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && !inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString && !inParam) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString && !inParam) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else if (c === '(' && !inString && !inParam) {
+                        chunk.push(c);
+                        inParam = true;
+                    } else if (c === ')' && !inString && inParam) {
+                        chunk.push(c);
+                        inParam = false;
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            try {
+                root = new(tree.Ruleset)([], $(this.parsers.primary));
+                root.root = true;
+            } catch (e) {
+                return callback(new(LessError)(e, env));
+            }
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [], importError;
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        throw new(LessError)(e, env);
+                    }
+
+                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
+                        if (importError instanceof LessError) throw importError;
+                        else                                  throw new(LessError)(importError, env);
+                    }
+
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('./cssmin').compressor.cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    type: "Parse",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { 
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k);
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index, env.filename) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+
+                    expect(')');
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index, env.filename);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i), important = false;
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if ($(this.important)) {
+                        important = true;
+                    }
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value, cond;
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    save();
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    value = expect(this.expression, 'expected expression');
+                                    params.push({ name: param.name, value: value });
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        expect(')');
+
+                        if ($(/^when/)) { // Guard
+                            cond = expect(this.conditions, 'expected condition');
+                        }
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset, cond);
+                        } else {
+                            restore();
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    expect(')');
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c, v;
+
+                c = $(this.combinator);
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+                    $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (! e) {
+                    $('(') && (v = $(this.entities.variable)) && $(')') && (e = new(tree.Paren)(v));
+                }
+
+                if (e) { return new(tree.Element)(c, e, i) }
+
+                if (c.value && c.value.charAt(0) === '&') {
+                    return new(tree.Element)(c, null, i);
+                }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === '&') {
+                    match = '&';
+                    i++;
+                    if(input.charAt(i) === ' ') {
+                        match = '& ';
+                    }
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(match);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path, features, index = i;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url))) {
+                    features = $(this.mediaFeatures);
+                    if ($(';')) {
+                        return new(tree.Import)(path, imports, features, index);
+                    }
+                }
+            },
+
+            mediaFeature: function () {
+                var nodes = [];
+
+                do {
+                    if (e = $(this.entities.keyword)) {
+                        nodes.push(e);
+                    } else if ($('(')) {
+                        p = $(this.property);
+                        e = $(this.entity);
+                        if ($(')')) {
+                            if (p && e) {
+                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+                            } else if (e) {
+                                nodes.push(new(tree.Paren)(e));
+                            } else {
+                                return null;
+                            }
+                        } else { return null }
+                    }
+                } while (e);
+
+                if (nodes.length > 0) {
+                    return new(tree.Expression)(nodes);
+                }
+            },
+
+            mediaFeatures: function () {
+                var f, features = [];
+                while (f = $(this.mediaFeature)) {
+                    features.push(f);
+                    if (! $(',')) { break }
+                }
+                return features.length > 0 ? features : null;
+            },
+
+            media: function () {
+                var features;
+
+                if ($(/^@media/)) {
+                    features = $(this.mediaFeatures);
+
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)('@media', rules, features);
+                    }
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types, e, nodes;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import']) || $(this.media)) {
+                    return value;
+                } else if (name = $(/^@page|@keyframes/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            conditions: function () {
+                var a, b, index = i, condition;
+
+                if (a = $(this.condition)) {
+                    while ($(',') && (b = $(this.condition))) {
+                        condition = new(tree.Condition)('or', condition || a, b, index);
+                    }
+                    return condition || a;
+                }
+            },
+            condition: function () {
+                var a, b, c, op, index = i, negate = false;
+
+                if ($(/^not/)) { negate = true }
+                expect('(');
+                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                    if (op = $(/^(?:>=|=<|[<=>])/)) {
+                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                            c = new(tree.Condition)(op, a, b, index, negate);
+                        } else {
+                            error('expected expression');
+                        }
+                    } else {
+                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+                    }
+                    expect(')');
+                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        return this._math('round', n);
+    },
+    ceil: function (n) {
+        return this._math('ceil', n);
+    },
+    floor: function (n) {
+        return this._math('floor', n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math[fn](n);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    },
+    percentage: function (n) {
+        return new(tree.Dimension)(n.value * 100, '%');
+    },
+    color: function (n) {
+        if (n instanceof tree.Quoted) {
+            return new(tree.Color)(n.value.slice(1));
+        } else {
+            throw { type: "Argument", message: "argument must be a string" };
+        }
+    },
+    iscolor: function (n) {
+        return this._isa(n, tree.Color);
+    },
+    isnumber: function (n) {
+        return this._isa(n, tree.Dimension);
+    },
+    isstring: function (n) {
+        return this._isa(n, tree.Quoted);
+    },
+    iskeyword: function (n) {
+        return this._isa(n, tree.Keyword);
+    },
+    isurl: function (n) {
+        return this._isa(n, tree.URL);
+    },
+    ispixel: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+    },
+    ispercentage: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+    },
+    isem: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+    },
+    _isa: function (n, Type) {
+        return (n instanceof Type) ? tree.True : tree.False;
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+    this.filename = filename;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { type: e.type || "Runtime",
+                        message: "error evaluating function `" + this.name + "`" +
+                                 (e.message ? ': ' + e.message : ''),
+                        index: this.index, filename: this.filename };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+    this.op = op.trim();
+    this.lvalue = l;
+    this.rvalue = r;
+    this.index = i;
+    this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+    var a = this.lvalue.eval(env),
+        b = this.rvalue.eval(env);
+
+    var i = this.index, result
+
+    var result = (function (op) {
+        switch (op) {
+            case 'and':
+                return a && b;
+            case 'or':
+                return a || b;
+            default:
+                if (a.compare) {
+                    result = a.compare(b);
+                } else if (b.compare) {
+                    result = b.compare(a);
+                } else {
+                    throw { type: "Type",
+                            message: "Unable to perform comparison",
+                            index: i };
+                }
+                switch (result) {
+                    case -1: return op === '<' || op === '=<';
+                    case  0: return op === '=' || op === '>=' || op === '=<';
+                    case  1: return op === '>' || op === '>=';
+                }
+        }
+    })(this.op);
+    return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    },
+
+    // TODO: Perform unit conversion before comparing
+    compare: function (other) {
+        if (other instanceof tree.Dimension) {
+            if (other.value > this.value) {
+                return -1;
+            } else if (other.value < this.value) {
+                return 1;
+            } else {
+                return 0;
+            }
+        } else {
+            return -1;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value, features) {
+    this.name = name;
+    this.features = features && new(tree.Value)(features);
+
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+        this.ruleset.allowImports = true;
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + features + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        this.features = this.features && this.features.eval(env);
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+
+    if (typeof(value) === 'string') {
+        this.value = value.trim();
+    } else if (value) {
+        this.value = value;
+    } else {
+        this.value = "";
+    }
+    this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+    return new(tree.Element)(this.combinator,
+                             this.value.eval ? this.value.eval(env) : this.value,
+                             this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + (this.value.toCSS ? this.value.toCSS(env) : this.value);
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else if (value === '& ') {
+        this.value = '& ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        '& ' : ' ',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS ? e.toCSS(env) : '';
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, index) {
+    var that = this;
+
+    this.index = index;
+    this._path = path;
+    this.features = features && new(tree.Value)(features);
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css(\?.*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (e, root) {
+            if (e) { e.index = index }
+            that.root = root || new(tree.Ruleset)([], []);
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function (env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.css) {
+            return "@import " + this._path.toCSS() + features + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset, features = this.features && this.features.eval(env);
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return this.features ? new(tree.Directive)('@media', ruleset.rules, this.features.value) : ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value },
+    compare: function (other) {
+        if (other instanceof tree.Keyword) {
+            return other.value === this.value ? 0 : 1;
+        } else {
+            return -1;
+        }
+    }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+    this.filename = filename;
+    this.important = important;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments, this.important).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, filename: this.filename, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { type:    'Runtime',
+                            message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index, filename: this.filename };
+                }
+            }
+        }
+        throw { type: 'Name',
+                message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index, filename: this.filename };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.condition = condition;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    evalParams: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []);
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        return frame;
+    },
+    eval: function (env, args, important) {
+        var frame = this.evalParams(env, args), context, _arguments = [], rules;
+
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        rules = important ?
+            this.rules.map(function (r) {
+                return new(tree.Rule)(r.name, r.value, '!important', r.index);
+            }) : this.rules.slice(0);
+
+        return new(tree.Ruleset)(null, rules).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len, frame;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+        if (this.condition && !this.condition.eval({
+            frames: [this.evalParams(env, args)].concat(env.frames)
+        }))                                                           { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+    this.value = node;
+};
+tree.Paren.prototype = {
+    toCSS: function (env) {
+        return '(' + this.value.toCSS(env) + ')';
+    },
+    eval: function (env) {
+        return new(tree.Paren)(this.value.eval(env));
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return ('value' in v) ? v.value : v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+    this.inline = inline || false;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + (this.inline ? "" : ";");
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name,
+                          this.value.eval(context),
+                          this.important,
+                          this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+        ruleset.allowImports = this.allowImports;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root || ruleset.allowImports) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                this.joinSelectors(paths, context, this.selectors);
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+        var before = [], after = [], beforeElements = [],
+            afterElements = [], hasParentSelector = false, el;
+
+        for (var i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.combinator.value.charAt(0) === '&') {
+                hasParentSelector = true;
+            }
+            if (hasParentSelector) afterElements.push(el);
+            else                   beforeElements.push(el);
+        }
+
+        if (! hasParentSelector) {
+            afterElements = beforeElements;
+            beforeElements = [];
+        }
+
+        if (beforeElements.length > 0) {
+            before.push(new(tree.Selector)(beforeElements));
+        }
+
+        if (afterElements.length > 0) {
+            after.push(new(tree.Selector)(afterElements));
+        }
+
+        for (var c = 0; c < context.length; c++) {
+            paths.push(before.concat(context[c]).concat(after));
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    var len  = this.elements.length,
+        olen = other.elements.length,
+        max  = Math.min(len, olen);
+
+    if (len < olen) {
+        return false;
+    } else {
+        for (var i = 0; i < max; i++) {
+            if (this.elements[i].value !== other.elements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.eval = function (env) {
+    return new(tree.Selector)(this.elements.map(function (e) {
+        return e.eval(env);
+    }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { type: 'Name',
+                    message: "variable " + name + " is undefined",
+                    filename: this.file,
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+tree.jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'chrome-extension:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (e, root, _, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (e, root, _, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                var css = tree.toCSS();
+                var style = styles[i];
+                style.type = 'text/css';
+                if (style.styleSheet) {
+                    style.styleSheet.cssText = css;
+                } else {
+                    style.innerHTML = css;
+                }
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+    var filename = href.match(/([^\/]+)$/)[1];
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type,
+                    filename: filename
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+    var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+    var elem = document.createElement('div'), timer, content, error = [];
+    var filename = e.filename || href;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p>in <a href="' + filename   + '">' + filename + "</a> ";
+
+    var errorline = function (e, i, classname) {
+        if (e.extract[i]) {
+            error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+                               .replace(/\{class\}/, classname)
+                               .replace(/\{content\}/, e.extract[i]));
+        }
+    };
+
+    if (e.stack) {
+        content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+    } else if (e.extract) {
+        errorline(e, 0, '');
+        errorline(e, 1, 'line');
+        errorline(e, 2, '');
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+                    '<ul>' + error.join('') + '</ul>';
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #dd6666;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.line {',
+            'color: #ff0000;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/util/less/dist/less-1.2.1.min.js b/util/less/dist/less-1.2.1.min.js
new file mode 100644
index 0000000..89b7637
--- /dev/null
+++ b/util/less/dist/less-1.2.1.min.js
@@ -0,0 +1,9 @@
+//
+// LESS - Leaner CSS v1.2.1
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function m(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(k)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];f.type="text/css",f.styleSheet?f.styleSheet.cssText=e:f.innerHTML=e})}function n(a,b){for(var c=0;c<d.sheets.length;c++)o(d.sheets[c],a,b,d.sheets.length-(c+1))}function o(b,c,e,f){var g=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/, [...]
+f+"`",index:this.index}}for(var h in b.frames[0].variables())e[h.slice(1)]={value:b.frames[0].variables()[h].value,toJS:function(){return this.value.eval(b).toCSS()}};try{c=f.call(e)}catch(g){throw{message:"JavaScript evaluation error: '"+g.name+": "+g.message+"'",index:this.index}}return typeof c=="string"?new a.Quoted('"'+c+'"',c,this.escaped,this.index):Array.isArray(c)?new a.Anonymous(c.join(", ")):new a.Anonymous(c)}}}(c("../tree")),function(a){a.Keyword=function(a){this.value=a},a. [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.2.2.js b/util/less/dist/less-1.2.2.js
new file mode 100644
index 0000000..4db2652
--- /dev/null
+++ b/util/less/dist/less-1.2.2.js
@@ -0,0 +1,3337 @@
+//
+// LESS - Leaner CSS v1.2.2
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+// amd.js
+//
+// Define Less as an AMD module.
+if (typeof define === "function" && define.amd) {
+    define("less", [], function () { return less; } );
+}
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    if (typeof(window) === 'undefined') { less = {} }
+    else                                { less = window.less = {} }
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        contents: {},                   // Holds the imported file contents
+        mime:  env && env.mime,         // MIME type of .less files
+        error: null,                    // Error in parsing/evaluating an import
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (e, root, contents) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+                that.contents[path] = contents;
+
+                if (e && !that.error) { that.error = e }
+                callback(e, root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    function expect(arg, msg) {
+        var result = $(arg);
+        if (! result) {
+            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+                                                   : "unexpected token"));
+        } else {
+            return result;
+        }
+    }
+
+    function error(msg, type) {
+        throw { index: i, type: type || 'Syntax', message: msg };
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    function basename(pathname) {
+        if (less.mode === 'node') {
+            return require('path').basename(pathname);
+        } else {
+            return pathname.match(/[^\/]+$/)[0];
+        }
+    }
+
+    function getInput(e, env) {
+        if (e.filename && env.filename && (e.filename !== env.filename)) {
+            return parser.imports.contents[basename(e.filename)];
+        } else {
+            return input;
+        }
+    }
+
+    function getLocation(index, input) {
+        for (var n = index, column = -1;
+                 n >= 0 && input.charAt(n) !== '\n';
+                 n--) { column++ }
+
+        return { line:   typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+                 column: column };
+    }
+
+    function LessError(e, env) {
+        var input = getInput(e, env),
+            loc = getLocation(e.index, input),
+            line = loc.line,
+            col  = loc.column,
+            lines = input.split('\n');
+
+        this.type = e.type || 'Syntax';
+        this.message = e.message;
+        this.filename = e.filename || env.filename;
+        this.index = e.index;
+        this.line = typeof(line) === 'number' ? line + 1 : null;
+        this.callLine = e.call && (getLocation(e.call, input) + 1);
+        this.callExtract = lines[getLocation(e.call, input)];
+        this.stack = e.stack;
+        this.column = col;
+        this.extract = [
+            lines[line - 1],
+            lines[line],
+            lines[line + 1]
+        ];
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)\\]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`\\\r\n]|\\.)*)`/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = string.lastIndex = i;
+
+                    if (match = string.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                            c = input.charAt(i);
+                        }
+                    }
+
+                    if (!inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    switch (c) {
+                        case '{': if (! inParam) { level ++;        chunk.push(c);                           break }
+                        case '}': if (! inParam) { level --;        chunk.push(c); chunks[++j] = chunk = []; break }
+                        case '(': if (! inParam) { inParam = true;  chunk.push(c);                           break }
+                        case ')': if (  inParam) { inParam = false; chunk.push(c);                           break }
+                        default:                                    chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    error = new(LessError)({
+                        index: i,
+                        type: 'Parse',
+                        message: "missing closing `}`",
+                        filename: env.filename
+                    }, env);
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            if (error) {
+                return callback(error);
+            }
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            try {
+                root = new(tree.Ruleset)([], $(this.parsers.primary));
+                root.root = true;
+            } catch (e) {
+                return callback(new(LessError)(e, env));
+            }
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [], importError;
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        throw new(LessError)(e, env);
+                    }
+
+                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
+                        if (importError instanceof LessError) throw importError;
+                        else                                  throw new(LessError)(importError, env);
+                    }
+
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('./cssmin').compressor.cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    type: "Parse",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { 
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k);
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index, env.filename) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+
+                    expect(')');
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index, env.filename);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i), important = false;
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if ($(this.important)) {
+                        important = true;
+                    }
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value, cond;
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    save();
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    value = expect(this.expression, 'expected expression');
+                                    params.push({ name: param.name, value: value });
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        expect(')');
+
+                        if ($(/^when/)) { // Guard
+                            cond = expect(this.conditions, 'expected condition');
+                        }
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset, cond);
+                        } else {
+                            restore();
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    expect(')');
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c, v;
+
+                c = $(this.combinator);
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+                    $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (! e) {
+                    $('(') && (v = $(this.entities.variable)) && $(')') && (e = new(tree.Paren)(v));
+                }
+
+                if (e) { return new(tree.Element)(c, e, i) }
+
+                if (c.value && c.value.charAt(0) === '&') {
+                    return new(tree.Element)(c, null, i);
+                }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === '&') {
+                    match = '&';
+                    i++;
+                    if(input.charAt(i) === ' ') {
+                        match = '& ';
+                    }
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(match);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path, features, index = i;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url))) {
+                    features = $(this.mediaFeatures);
+                    if ($(';')) {
+                        return new(tree.Import)(path, imports, features, index);
+                    }
+                }
+            },
+
+            mediaFeature: function () {
+                var nodes = [];
+
+                do {
+                    if (e = $(this.entities.keyword)) {
+                        nodes.push(e);
+                    } else if ($('(')) {
+                        p = $(this.property);
+                        e = $(this.entity);
+                        if ($(')')) {
+                            if (p && e) {
+                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+                            } else if (e) {
+                                nodes.push(new(tree.Paren)(e));
+                            } else {
+                                return null;
+                            }
+                        } else { return null }
+                    }
+                } while (e);
+
+                if (nodes.length > 0) {
+                    return new(tree.Expression)(nodes);
+                }
+            },
+
+            mediaFeatures: function () {
+                var f, features = [];
+                while (f = $(this.mediaFeature)) {
+                    features.push(f);
+                    if (! $(',')) { break }
+                }
+                return features.length > 0 ? features : null;
+            },
+
+            media: function () {
+                var features;
+
+                if ($(/^@media/)) {
+                    features = $(this.mediaFeatures);
+
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)('@media', rules, features);
+                    }
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types, e, nodes;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import']) || $(this.media)) {
+                    return value;
+                } else if (name = $(/^@page|@keyframes/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            conditions: function () {
+                var a, b, index = i, condition;
+
+                if (a = $(this.condition)) {
+                    while ($(',') && (b = $(this.condition))) {
+                        condition = new(tree.Condition)('or', condition || a, b, index);
+                    }
+                    return condition || a;
+                }
+            },
+            condition: function () {
+                var a, b, c, op, index = i, negate = false;
+
+                if ($(/^not/)) { negate = true }
+                expect('(');
+                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                    if (op = $(/^(?:>=|=<|[<=>])/)) {
+                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                            c = new(tree.Condition)(op, a, b, index, negate);
+                        } else {
+                            error('expected expression');
+                        }
+                    } else {
+                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+                    }
+                    expect(')');
+                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (!/^([a-z]+:)?\//.test(path) && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, function (e) {
+            if (e && typeof(env.errback) === "function") {
+                env.errback.call(null, path, paths, callback, env);
+            } else {
+                callback.apply(null, arguments);
+            }
+        }, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        return this._math('round', n);
+    },
+    ceil: function (n) {
+        return this._math('ceil', n);
+    },
+    floor: function (n) {
+        return this._math('floor', n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math[fn](n);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    },
+    percentage: function (n) {
+        return new(tree.Dimension)(n.value * 100, '%');
+    },
+    color: function (n) {
+        if (n instanceof tree.Quoted) {
+            return new(tree.Color)(n.value.slice(1));
+        } else {
+            throw { type: "Argument", message: "argument must be a string" };
+        }
+    },
+    iscolor: function (n) {
+        return this._isa(n, tree.Color);
+    },
+    isnumber: function (n) {
+        return this._isa(n, tree.Dimension);
+    },
+    isstring: function (n) {
+        return this._isa(n, tree.Quoted);
+    },
+    iskeyword: function (n) {
+        return this._isa(n, tree.Keyword);
+    },
+    isurl: function (n) {
+        return this._isa(n, tree.URL);
+    },
+    ispixel: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+    },
+    ispercentage: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+    },
+    isem: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+    },
+    _isa: function (n, Type) {
+        return (n instanceof Type) ? tree.True : tree.False;
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+    this.filename = filename;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { type: e.type || "Runtime",
+                        message: "error evaluating function `" + this.name + "`" +
+                                 (e.message ? ': ' + e.message : ''),
+                        index: this.index, filename: this.filename };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+    this.op = op.trim();
+    this.lvalue = l;
+    this.rvalue = r;
+    this.index = i;
+    this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+    var a = this.lvalue.eval(env),
+        b = this.rvalue.eval(env);
+
+    var i = this.index, result;
+
+    var result = (function (op) {
+        switch (op) {
+            case 'and':
+                return a && b;
+            case 'or':
+                return a || b;
+            default:
+                if (a.compare) {
+                    result = a.compare(b);
+                } else if (b.compare) {
+                    result = b.compare(a);
+                } else {
+                    throw { type: "Type",
+                            message: "Unable to perform comparison",
+                            index: i };
+                }
+                switch (result) {
+                    case -1: return op === '<' || op === '=<';
+                    case  0: return op === '=' || op === '>=' || op === '=<';
+                    case  1: return op === '>' || op === '>=';
+                }
+        }
+    })(this.op);
+    return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    },
+
+    // TODO: Perform unit conversion before comparing
+    compare: function (other) {
+        if (other instanceof tree.Dimension) {
+            if (other.value > this.value) {
+                return -1;
+            } else if (other.value < this.value) {
+                return 1;
+            } else {
+                return 0;
+            }
+        } else {
+            return -1;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value, features) {
+    this.name = name;
+    this.features = features && new(tree.Value)(features);
+
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+        this.ruleset.allowImports = true;
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + features + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        this.features = this.features && this.features.eval(env);
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+
+    if (typeof(value) === 'string') {
+        this.value = value.trim();
+    } else if (value) {
+        this.value = value;
+    } else {
+        this.value = "";
+    }
+    this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+    return new(tree.Element)(this.combinator,
+                             this.value.eval ? this.value.eval(env) : this.value,
+                             this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + (this.value.toCSS ? this.value.toCSS(env) : this.value);
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else if (value === '& ') {
+        this.value = '& ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        '& ' : ' ',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS ? e.toCSS(env) : '';
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, index) {
+    var that = this;
+
+    this.index = index;
+    this._path = path;
+    this.features = features && new(tree.Value)(features);
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css(\?.*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (e, root) {
+            if (e) { e.index = index }
+            that.root = root || new(tree.Ruleset)([], []);
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function (env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.css) {
+            return "@import " + this._path.toCSS() + features + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset, features = this.features && this.features.eval(env);
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return this.features ? new(tree.Directive)('@media', ruleset.rules, this.features.value) : ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value },
+    compare: function (other) {
+        if (other instanceof tree.Keyword) {
+            return other.value === this.value ? 0 : 1;
+        } else {
+            return -1;
+        }
+    }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+    this.filename = filename;
+    this.important = important;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments, this.important).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, filename: this.filename, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { type:    'Runtime',
+                            message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index, filename: this.filename };
+                }
+            }
+        }
+        throw { type: 'Name',
+                message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index, filename: this.filename };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.condition = condition;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    evalParams: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []);
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        return frame;
+    },
+    eval: function (env, args, important) {
+        var frame = this.evalParams(env, args), context, _arguments = [], rules;
+
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        rules = important ?
+            this.rules.map(function (r) {
+                return new(tree.Rule)(r.name, r.value, '!important', r.index);
+            }) : this.rules.slice(0);
+
+        return new(tree.Ruleset)(null, rules).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len, frame;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+        if (this.condition && !this.condition.eval({
+            frames: [this.evalParams(env, args)].concat(env.frames)
+        }))                                                           { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+    this.value = node;
+};
+tree.Paren.prototype = {
+    toCSS: function (env) {
+        return '(' + this.value.toCSS(env) + ')';
+    },
+    eval: function (env) {
+        return new(tree.Paren)(this.value.eval(env));
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return ('value' in v) ? v.value : v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+    this.inline = inline || false;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + (this.inline ? "" : ";");
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name,
+                          this.value.eval(context),
+                          this.important,
+                          this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+        ruleset.allowImports = this.allowImports;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root || ruleset.allowImports) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                this.joinSelectors(paths, context, this.selectors);
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join( env.compress ? ',' : ',\n');
+
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+        var before = [], after = [], beforeElements = [],
+            afterElements = [], hasParentSelector = false, el;
+
+        for (var i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.combinator.value.charAt(0) === '&') {
+                hasParentSelector = true;
+            }
+            if (hasParentSelector) afterElements.push(el);
+            else                   beforeElements.push(el);
+        }
+
+        if (! hasParentSelector) {
+            afterElements = beforeElements;
+            beforeElements = [];
+        }
+
+        if (beforeElements.length > 0) {
+            before.push(new(tree.Selector)(beforeElements));
+        }
+
+        if (afterElements.length > 0) {
+            after.push(new(tree.Selector)(afterElements));
+        }
+
+        for (var c = 0; c < context.length; c++) {
+            paths.push(before.concat(context[c]).concat(after));
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    var len  = this.elements.length,
+        olen = other.elements.length,
+        max  = Math.min(len, olen);
+
+    if (len < olen) {
+        return false;
+    } else {
+        for (var i = 0; i < max; i++) {
+            if (this.elements[i].value !== other.elements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.eval = function (env) {
+    return new(tree.Selector)(this.elements.map(function (e) {
+        return e.eval(env);
+    }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { type: 'Name',
+                    message: "variable " + name + " is undefined",
+                    filename: this.file,
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+tree.jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'chrome-extension:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (e, root, _, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (e, root, _, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                var css = tree.toCSS();
+                var style = styles[i];
+                style.type = 'text/css';
+                if (style.styleSheet) {
+                    style.styleSheet.cssText = css;
+                } else {
+                    style.innerHTML = css;
+                }
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+    var filename = href.match(/([^\/]+)$/)[1];
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, null, data, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type,
+                    filename: filename
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+    var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+    var elem = document.createElement('div'), timer, content, error = [];
+    var filename = e.filename || href;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p>in <a href="' + filename   + '">' + filename + "</a> ";
+
+    var errorline = function (e, i, classname) {
+        if (e.extract[i]) {
+            error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+                               .replace(/\{class\}/, classname)
+                               .replace(/\{content\}/, e.extract[i]));
+        }
+    };
+
+    if (e.stack) {
+        content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+    } else if (e.extract) {
+        errorline(e, 0, '');
+        errorline(e, 1, 'line');
+        errorline(e, 2, '');
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+                    '<ul>' + error.join('') + '</ul>';
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #dd6666;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.line {',
+            'color: #ff0000;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/util/less/dist/less-1.2.2.min.js b/util/less/dist/less-1.2.2.min.js
new file mode 100644
index 0000000..55042ec
--- /dev/null
+++ b/util/less/dist/less-1.2.2.min.js
@@ -0,0 +1,9 @@
+//
+// LESS - Leaner CSS v1.2.2
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function m(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(k)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];f.type="text/css",f.styleSheet?f.styleSheet.cssText=e:f.innerHTML=e})}function n(a,b){for(var c=0;c<d.sheets.length;c++)o(d.sheets[c],a,b,d.sheets.length-(c+1))}function o(b,c,e,f){var g=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/, [...]
+a.Directive("@media",c.rules,this.features.value):c.rules}}}(c("../tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation error: `"+f+"`",index:this.index}}for(var h in b.frames[0].variables())e [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.3.0.js b/util/less/dist/less-1.3.0.js
new file mode 100644
index 0000000..fce5fb5
--- /dev/null
+++ b/util/less/dist/less-1.3.0.js
@@ -0,0 +1,3478 @@
+//
+// LESS - Leaner CSS v1.3.0
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+// amd.js
+//
+// Define Less as an AMD module.
+if (typeof define === "function" && define.amd) {
+    define("less", [], function () { return less; } );
+}
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    if (typeof(window) === 'undefined') { less = {} }
+    else                                { less = window.less = {} }
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        contents: {},                   // Holds the imported file contents
+        mime:  env && env.mime,         // MIME type of .less files
+        error: null,                    // Error in parsing/evaluating an import
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (e, root, contents) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+                that.contents[path] = contents;
+
+                if (e && !that.error) { that.error = e }
+                callback(e, root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    function expect(arg, msg) {
+        var result = $(arg);
+        if (! result) {
+            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+                                                   : "unexpected token"));
+        } else {
+            return result;
+        }
+    }
+
+    function error(msg, type) {
+        throw { index: i, type: type || 'Syntax', message: msg };
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    function basename(pathname) {
+        if (less.mode === 'node') {
+            return require('path').basename(pathname);
+        } else {
+            return pathname.match(/[^\/]+$/)[0];
+        }
+    }
+
+    function getInput(e, env) {
+        if (e.filename && env.filename && (e.filename !== env.filename)) {
+            return parser.imports.contents[basename(e.filename)];
+        } else {
+            return input;
+        }
+    }
+
+    function getLocation(index, input) {
+        for (var n = index, column = -1;
+                 n >= 0 && input.charAt(n) !== '\n';
+                 n--) { column++ }
+
+        return { line:   typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+                 column: column };
+    }
+
+    function LessError(e, env) {
+        var input = getInput(e, env),
+            loc = getLocation(e.index, input),
+            line = loc.line,
+            col  = loc.column,
+            lines = input.split('\n');
+
+        this.type = e.type || 'Syntax';
+        this.message = e.message;
+        this.filename = e.filename || env.filename;
+        this.index = e.index;
+        this.line = typeof(line) === 'number' ? line + 1 : null;
+        this.callLine = e.call && (getLocation(e.call, input).line + 1);
+        this.callExtract = lines[getLocation(e.call, input).line];
+        this.stack = e.stack;
+        this.column = col;
+        this.extract = [
+            lines[line - 1],
+            lines[line],
+            lines[line + 1]
+        ];
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)\\]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`\\\r\n]|\\.)*)`/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = string.lastIndex = i;
+
+                    if (match = string.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                            c = input.charAt(i);
+                        }
+                    }
+
+                    if (!inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    switch (c) {
+                        case '{': if (! inParam) { level ++;        chunk.push(c);                           break }
+                        case '}': if (! inParam) { level --;        chunk.push(c); chunks[++j] = chunk = []; break }
+                        case '(': if (! inParam) { inParam = true;  chunk.push(c);                           break }
+                        case ')': if (  inParam) { inParam = false; chunk.push(c);                           break }
+                        default:                                    chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    error = new(LessError)({
+                        index: i,
+                        type: 'Parse',
+                        message: "missing closing `}`",
+                        filename: env.filename
+                    }, env);
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            if (error) {
+                return callback(error);
+            }
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            try {
+                root = new(tree.Ruleset)([], $(this.parsers.primary));
+                root.root = true;
+            } catch (e) {
+                return callback(new(LessError)(e, env));
+            }
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [], importError;
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        throw new(LessError)(e, env);
+                    }
+
+                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
+                        if (importError instanceof LessError) throw importError;
+                        else                                  throw new(LessError)(importError, env);
+                    }
+
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('./cssmin').compressor.cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    type: "Parse",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { 
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k);
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index, env.filename) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+
+                    expect(')');
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index, env.filename);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|rem|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i), important = false;
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if ($(this.important)) {
+                        important = true;
+                    }
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args || [], index, env.filename, important);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value, cond, variadic = false;
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    save();
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        do {
+                            if (input.charAt(i) === '.' && $(/^\.{3}/)) {
+                                variadic = true;
+                                break;
+                            } else if (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                         || $(this.entities.keyword)) {
+                                // Variable
+                                if (param instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        value = expect(this.expression, 'expected expression');
+                                        params.push({ name: param.name, value: value });
+                                    } else if ($(/^\.{3}/)) {
+                                        params.push({ name: param.name, variadic: true });
+                                        variadic = true;
+                                        break;
+                                    } else {
+                                        params.push({ name: param.name });
+                                    }
+                                } else {
+                                    params.push({ value: param });
+                                }
+                            } else {
+                                break;
+                            }
+                        } while ($(','))
+
+                        expect(')');
+
+                        if ($(/^when/)) { // Guard
+                            cond = expect(this.conditions, 'expected condition');
+                        }
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
+                        } else {
+                            restore();
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    expect(')');
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c, v;
+
+                c = $(this.combinator);
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+                    $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (! e) {
+                    $('(') && (v = $(this.entities.variable)) && $(')') && (e = new(tree.Paren)(v));
+                }
+
+                if (e) { return new(tree.Element)(c, e, i) }
+
+                if (c.value && c.value.charAt(0) === '&') {
+                    return new(tree.Element)(c, null, i);
+                }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === '&') {
+                    match = '&';
+                    i++;
+                    if(input.charAt(i) === ' ') {
+                        match = '& ';
+                    }
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(match);
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                if ($('(')) {
+                    sel = $(this.entity);
+                    expect(')');
+                    return new(tree.Selector)([new(tree.Element)('', sel, i)]);
+                }
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules, env.strictImports);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path, features, index = i;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url))) {
+                    features = $(this.mediaFeatures);
+                    if ($(';')) {
+                        return new(tree.Import)(path, imports, features, index);
+                    }
+                }
+            },
+
+            mediaFeature: function () {
+                var e, p, nodes = [];
+
+                do {
+                    if (e = $(this.entities.keyword)) {
+                        nodes.push(e);
+                    } else if ($('(')) {
+                        p = $(this.property);
+                        e = $(this.entity);
+                        if ($(')')) {
+                            if (p && e) {
+                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+                            } else if (e) {
+                                nodes.push(new(tree.Paren)(e));
+                            } else {
+                                return null;
+                            }
+                        } else { return null }
+                    }
+                } while (e);
+
+                if (nodes.length > 0) {
+                    return new(tree.Expression)(nodes);
+                }
+            },
+
+            mediaFeatures: function () {
+                var e, features = [];
+                
+                do {
+                  if (e = $(this.mediaFeature)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  } else if (e = $(this.entities.variable)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  }
+                } while (e);
+                
+                return features.length > 0 ? features : null;
+            },
+
+            media: function () {
+                var features, rules;
+
+                if ($(/^@media/)) {
+                    features = $(this.mediaFeatures);
+
+                    if (rules = $(this.block)) {
+                        return new(tree.Media)(rules, features);
+                    }
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types, e, nodes;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import']) || $(this.media)) {
+                    return value;
+                } else if (name = $(/^@page|@keyframes/) || $(/^@(?:-webkit-|-moz-|-o-|-ms-)[a-z0-9-]+/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            conditions: function () {
+                var a, b, index = i, condition;
+
+                if (a = $(this.condition)) {
+                    while ($(',') && (b = $(this.condition))) {
+                        condition = new(tree.Condition)('or', condition || a, b, index);
+                    }
+                    return condition || a;
+                }
+            },
+            condition: function () {
+                var a, b, c, op, index = i, negate = false;
+
+                if ($(/^not/)) { negate = true }
+                expect('(');
+                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                    if (op = $(/^(?:>=|=<|[<=>])/)) {
+                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                            c = new(tree.Condition)(op, a, b, index, negate);
+                        } else {
+                            error('expected expression');
+                        }
+                    } else {
+                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+                    }
+                    expect(')');
+                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (!/^([a-z]+:)?\//.test(path) && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, function (e) {
+            if (e && typeof(env.errback) === "function") {
+                env.errback.call(null, path, paths, callback, env);
+            } else {
+                callback.apply(null, arguments);
+            }
+        }, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        return this._math('round', n);
+    },
+    ceil: function (n) {
+        return this._math('ceil', n);
+    },
+    floor: function (n) {
+        return this._math('floor', n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math[fn](n);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    },
+    percentage: function (n) {
+        return new(tree.Dimension)(n.value * 100, '%');
+    },
+    color: function (n) {
+        if (n instanceof tree.Quoted) {
+            return new(tree.Color)(n.value.slice(1));
+        } else {
+            throw { type: "Argument", message: "argument must be a string" };
+        }
+    },
+    iscolor: function (n) {
+        return this._isa(n, tree.Color);
+    },
+    isnumber: function (n) {
+        return this._isa(n, tree.Dimension);
+    },
+    isstring: function (n) {
+        return this._isa(n, tree.Quoted);
+    },
+    iskeyword: function (n) {
+        return this._isa(n, tree.Keyword);
+    },
+    isurl: function (n) {
+        return this._isa(n, tree.URL);
+    },
+    ispixel: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+    },
+    ispercentage: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+    },
+    isem: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+    },
+    _isa: function (n, Type) {
+        return (n instanceof Type) ? tree.True : tree.False;
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+    this.filename = filename;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { type: e.type || "Runtime",
+                        message: "error evaluating function `" + this.name + "`" +
+                                 (e.message ? ': ' + e.message : ''),
+                        index: this.index, filename: this.filename };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+    this.op = op.trim();
+    this.lvalue = l;
+    this.rvalue = r;
+    this.index = i;
+    this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+    var a = this.lvalue.eval(env),
+        b = this.rvalue.eval(env);
+
+    var i = this.index, result;
+
+    var result = (function (op) {
+        switch (op) {
+            case 'and':
+                return a && b;
+            case 'or':
+                return a || b;
+            default:
+                if (a.compare) {
+                    result = a.compare(b);
+                } else if (b.compare) {
+                    result = b.compare(a);
+                } else {
+                    throw { type: "Type",
+                            message: "Unable to perform comparison",
+                            index: i };
+                }
+                switch (result) {
+                    case -1: return op === '<' || op === '=<';
+                    case  0: return op === '=' || op === '>=' || op === '=<';
+                    case  1: return op === '>' || op === '>=';
+                }
+        }
+    })(this.op);
+    return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    },
+
+    // TODO: Perform unit conversion before comparing
+    compare: function (other) {
+        if (other instanceof tree.Dimension) {
+            if (other.value > this.value) {
+                return -1;
+            } else if (other.value < this.value) {
+                return 1;
+            } else {
+                return 0;
+            }
+        } else {
+            return -1;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value, features) {
+    this.name = name;
+
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+        this.ruleset.allowImports = true;
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+
+    if (typeof(value) === 'string') {
+        this.value = value.trim();
+    } else if (value) {
+        this.value = value;
+    } else {
+        this.value = "";
+    }
+    this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+    return new(tree.Element)(this.combinator,
+                             this.value.eval ? this.value.eval(env) : this.value,
+                             this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + (this.value.toCSS ? this.value.toCSS(env) : this.value);
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else if (value === '& ') {
+        this.value = '& ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        '& ' : ' ',
+        ':' : ' :',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS ? e.toCSS(env) : '';
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, index) {
+    var that = this;
+
+    this.index = index;
+    this._path = path;
+    this.features = features && new(tree.Value)(features);
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css(\?.*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (e, root) {
+            if (e) { e.index = index }
+            that.root = root || new(tree.Ruleset)([], []);
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function (env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.css) {
+            return "@import " + this._path.toCSS() + features + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset, features = this.features && this.features.eval(env);
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value },
+    compare: function (other) {
+        if (other instanceof tree.Keyword) {
+            return other.value === this.value ? 0 : 1;
+        } else {
+            return -1;
+        }
+    }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Media = function (value, features) {
+    var el = new(tree.Element)('&', null, 0),
+        selectors = [new(tree.Selector)([el])];
+
+    this.features = new(tree.Value)(features);
+    this.ruleset = new(tree.Ruleset)(selectors, value);
+    this.ruleset.allowImports = true;
+};
+tree.Media.prototype = {
+    toCSS: function (ctx, env) {
+        var features = this.features.toCSS(env);
+
+        this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
+        return '@media ' + features + (env.compress ? '{' : ' {\n  ') +
+               this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                           (env.compress ? '}': '\n}\n');
+    },
+    eval: function (env) {
+        if (!env.mediaBlocks) {
+            env.mediaBlocks = [];
+            env.mediaPath = [];
+        }
+        
+        var blockIndex = env.mediaBlocks.length;
+        env.mediaPath.push(this);
+        env.mediaBlocks.push(this);
+
+        var media = new(tree.Media)([], []);
+        media.features = this.features.eval(env);
+        
+        env.frames.unshift(this.ruleset);
+        media.ruleset = this.ruleset.eval(env);
+        env.frames.shift();
+        
+        env.mediaBlocks[blockIndex] = media;
+        env.mediaPath.pop();
+
+        return env.mediaPath.length === 0 ? media.evalTop(env) :
+                    media.evalNested(env)
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
+
+    evalTop: function (env) {
+        var result = this;
+
+        // Render all dependent Media blocks.
+        if (env.mediaBlocks.length > 1) {
+            var el = new(tree.Element)('&', null, 0);
+            var selectors = [new(tree.Selector)([el])];
+            result = new(tree.Ruleset)(selectors, env.mediaBlocks);
+            result.multiMedia = true;
+        }
+
+        delete env.mediaBlocks;
+        delete env.mediaPath;
+
+        return result;
+    },
+    evalNested: function (env) {
+        var i, value,
+            path = env.mediaPath.concat([this]);
+
+        // Extract the media-query conditions separated with `,` (OR).
+        for (i = 0; i < path.length; i++) {
+            value = path[i].features instanceof tree.Value ?
+                        path[i].features.value : path[i].features;
+            path[i] = Array.isArray(value) ? value : [value];
+        }
+
+        // Trace all permutations to generate the resulting media-query.
+        //
+        // (a, b and c) with nested (d, e) ->
+        //    a and d
+        //    a and e
+        //    b and c and d
+        //    b and c and e
+        this.features = new(tree.Value)(this.permute(path).map(function (path) {
+            path = path.map(function (fragment) {
+                return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
+            });
+
+            for(i = path.length - 1; i > 0; i--) {
+                path.splice(i, 0, new(tree.Anonymous)("and"));
+            }
+
+            return new(tree.Expression)(path);
+        }));
+
+        // Fake a tree-node that doesn't output anything.
+        return new(tree.Ruleset)([], []);
+    },
+    permute: function (arr) {
+      if (arr.length === 0) {
+          return [];
+      } else if (arr.length === 1) {
+          return arr[0];
+      } else {
+          var result = [];
+          var rest = this.permute(arr.slice(1));
+          for (var i = 0; i < rest.length; i++) {
+              for (var j = 0; j < arr[0].length; j++) {
+                  result.push([arr[0][j]].concat(rest[i]));
+              }
+          }
+          return result;
+      }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+    this.filename = filename;
+    this.important = important;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments, this.important).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { type:    'Runtime',
+                            message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index, filename: this.filename };
+                }
+            }
+        }
+        throw { type: 'Name',
+                message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index, filename: this.filename };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition, variadic) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.condition = condition;
+    this.variadic = variadic;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    evalParams: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), varargs;
+
+        for (var i = 0, val, name; i < this.params.length; i++) {
+            if (name = this.params[i].name) {
+                if (this.params[i].variadic && args) {
+                    varargs = [];
+                    for (var j = i; j < args.length; j++) {
+                        varargs.push(args[j].eval(env));
+                    }
+                    frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
+                } else if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(name, val.eval(env)));
+                } else {
+                    throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        return frame;
+    },
+    eval: function (env, args, important) {
+        var frame = this.evalParams(env, args), context, _arguments = [], rules, start;
+
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        rules = important ?
+            this.rules.map(function (r) {
+                return new(tree.Rule)(r.name, r.value, '!important', r.index);
+            }) : this.rules.slice(0);
+
+        return new(tree.Ruleset)(null, rules).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len, frame;
+
+        if (! this.variadic) {
+            if (argsLength < this.required)                               { return false }
+            if (argsLength > this.params.length)                          { return false }
+            if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+        }
+
+        if (this.condition && !this.condition.eval({
+            frames: [this.evalParams(env, args)].concat(env.frames)
+        }))                                                           { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+    this.value = node;
+};
+tree.Paren.prototype = {
+    toCSS: function (env) {
+        return '(' + this.value.toCSS(env) + ')';
+    },
+    eval: function (env) {
+        return new(tree.Paren)(this.value.eval(env));
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return ('value' in v) ? v.value : v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+    this.inline = inline || false;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + (this.inline ? "" : ";");
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name,
+                          this.value.eval(context),
+                          this.important,
+                          this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules, strictImports) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+    this.strictImports = strictImports;
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
+
+        ruleset.root = this.root;
+        ruleset.allowImports = this.allowImports;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                this.joinSelectors(paths, context, this.selectors);
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive) || (rule instanceof tree.Media)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join( env.compress ? ',' : ',\n');
+
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+        var before = [], after = [], beforeElements = [],
+            afterElements = [], hasParentSelector = false, el;
+
+        for (var i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.combinator.value.charAt(0) === '&') {
+                hasParentSelector = true;
+            }
+            if (hasParentSelector) afterElements.push(el);
+            else                   beforeElements.push(el);
+        }
+
+        if (! hasParentSelector) {
+            afterElements = beforeElements;
+            beforeElements = [];
+        }
+
+        if (beforeElements.length > 0) {
+            before.push(new(tree.Selector)(beforeElements));
+        }
+
+        if (afterElements.length > 0) {
+            after.push(new(tree.Selector)(afterElements));
+        }
+
+        for (var c = 0; c < context.length; c++) {
+            paths.push(before.concat(context[c]).concat(after));
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    var len  = this.elements.length,
+        olen = other.elements.length,
+        max  = Math.min(len, olen);
+
+    if (len < olen) {
+        return false;
+    } else {
+        for (var i = 0; i < max; i++) {
+            if (this.elements[i].value !== other.elements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.eval = function (env) {
+    return new(tree.Selector)(this.elements.map(function (e) {
+        return e.eval(env);
+    }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (typeof(window) !== 'undefined' && !/^(?:https?:\/\/|file:\/\/|data:|\/)/.test(val.value) && paths.length > 0) {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { type: 'Name',
+                    message: "variable " + name + " is undefined",
+                    filename: this.file,
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+tree.jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = (location.protocol === 'file:'    ||
+                      location.protocol === 'chrome:'  ||
+                      location.protocol === 'chrome-extension:'  ||
+                      location.protocol === 'resource:');
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (e, root, _, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (e, root, _, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)().parse(styles[i].innerHTML || '', function (e, tree) {
+                var css = tree.toCSS();
+                var style = styles[i];
+                style.type = 'text/css';
+                if (style.styleSheet) {
+                    style.styleSheet.cssText = css;
+                } else {
+                    style.innerHTML = css;
+                }
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^(https?|file):/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+    var filename = href.match(/([^\/]+)$/)[1];
+
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, null, data, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type,
+                    filename: filename
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        css.media = sheet.media || 'screen';
+        css.id = id;
+        document.getElementsByTagName('head')[0].appendChild(css);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        cache.setItem(href, styles);
+        cache.setItem(href + ':timestamp', lastModified);
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? false : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol) {
+        if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+    var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+    var elem = document.createElement('div'), timer, content, error = [];
+    var filename = e.filename || href;
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p>in <a href="' + filename   + '">' + filename + "</a> ";
+
+    var errorline = function (e, i, classname) {
+        if (e.extract[i]) {
+            error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+                               .replace(/\{class\}/, classname)
+                               .replace(/\{content\}/, e.extract[i]));
+        }
+    };
+
+    if (e.stack) {
+        content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+    } else if (e.extract) {
+        errorline(e, 0, '');
+        errorline(e, 1, 'line');
+        errorline(e, 2, '');
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+                    '<ul>' + error.join('') + '</ul>';
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #dd6666;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.line {',
+            'color: #ff0000;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+})(window);
diff --git a/util/less/dist/less-1.3.0.min.js b/util/less/dist/less-1.3.0.min.js
new file mode 100644
index 0000000..309bf55
--- /dev/null
+++ b/util/less/dist/less-1.3.0.min.js
@@ -0,0 +1,9 @@
+//
+// LESS - Leaner CSS v1.3.0
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(a,b){function c(b){return a.less[b.split("/")[1]]}function l(){var a=document.getElementsByTagName("style");for(var b=0;b<a.length;b++)a[b].type.match(j)&&(new d.Parser).parse(a[b].innerHTML||"",function(c,d){var e=d.toCSS(),f=a[b];f.type="text/css",f.styleSheet?f.styleSheet.cssText=e:f.innerHTML=e})}function m(a,b){for(var c=0;c<d.sheets.length;c++)n(d.sheets[c],a,b,d.sheets.length-(c+1))}function n(b,c,e,f){var h=a.location.href.replace(/[#?].*$/,""),i=b.href.replace(/\?.*$/, [...]
+.splice.apply(c.rules,[e,1].concat(c.rules[e].eval(b)));return this.features?new a.Media(c.rules,this.features.value):c.rules}}}(c("../tree")),function(a){a.JavaScript=function(a,b,c){this.escaped=c,this.expression=a,this.index=b},a.JavaScript.prototype={eval:function(b){var c,d=this,e={},f=this.expression.replace(/@\{([\w-]+)\}/g,function(c,e){return a.jsify((new a.Variable("@"+e,d.index)).eval(b))});try{f=new Function("return ("+f+")")}catch(g){throw{message:"JavaScript evaluation erro [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.3.1.js b/util/less/dist/less-1.3.1.js
new file mode 100644
index 0000000..0d2a48c
--- /dev/null
+++ b/util/less/dist/less-1.3.1.js
@@ -0,0 +1,4011 @@
+//
+// LESS - Leaner CSS v1.3.1
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    if (typeof(window) === 'undefined') { less = {} }
+    else                                { less = window.less = {} }
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // Top parser on an import tree must be sure there is one "env"
+    // which will then be passed arround by reference.
+    var env = env || { };
+    if (!env.contents) { env.contents={}; }  // env.contents must be passed arround with top env
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        contents: env.contents,         // Holds the imported file contents
+        mime:  env && env.mime,         // MIME type of .less files
+        error: null,                    // Error in parsing/evaluating an import
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (e, root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+
+                var imported = path in that.files;
+
+                that.files[path] = root;                        // Store the root
+
+                if (e && !that.error) { that.error = e }
+
+                callback(e, root, imported);
+
+                if (that.queue.length === 0) { finish(e) }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    function isWhitespace(c) {
+        // Could change to \s?
+        var code = c.charCodeAt(0);
+        return code === 32 || code === 10 || code === 9;
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, index, k;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            skipWhitespace(length);
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    function skipWhitespace(length) {
+        var oldi = i, oldj = j,
+            endIndex = i + chunks[j].length,
+            mem = i += length;
+
+        while (i < endIndex) {
+            if (! isWhitespace(input.charAt(i))) { break }
+            i++;
+        }
+        chunks[j] = chunks[j].slice(length + (i - mem));
+        current = i;
+
+        if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+        return oldi !== i || oldj !== j;
+    }
+
+    function expect(arg, msg) {
+        var result = $(arg);
+        if (! result) {
+            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+                                                   : "unexpected token"));
+        } else {
+            return result;
+        }
+    }
+
+    function error(msg, type) {
+        throw { index: i, type: type || 'Syntax', message: msg };
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    function getInput(e, env) {
+        if (e.filename && env.filename && (e.filename !== env.filename)) {
+            return parser.imports.contents[e.filename];
+        } else {
+            return input;
+        }
+    }
+
+    function getLocation(index, input) {
+        for (var n = index, column = -1;
+                 n >= 0 && input.charAt(n) !== '\n';
+                 n--) { column++ }
+
+        return { line:   typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+                 column: column };
+    }
+
+    function getFileName(e) {
+        if(less.mode === 'browser' || less.mode === 'rhino')
+            return e.filename;
+        else
+            return require('path').resolve(e.filename);
+    }
+
+    function getDebugInfo(index, inputStream, e) {
+        return {
+            lineNumber: getLocation(index, inputStream).line + 1,
+            fileName: getFileName(e)
+        };
+    }
+
+    function LessError(e, env) {
+        var input = getInput(e, env),
+            loc = getLocation(e.index, input),
+            line = loc.line,
+            col  = loc.column,
+            lines = input.split('\n');
+
+        this.type = e.type || 'Syntax';
+        this.message = e.message;
+        this.filename = e.filename || env.filename;
+        this.index = e.index;
+        this.line = typeof(line) === 'number' ? line + 1 : null;
+        this.callLine = e.call && (getLocation(e.call, input).line + 1);
+        this.callExtract = lines[getLocation(e.call, input).line];
+        this.stack = e.stack;
+        this.column = col;
+        this.extract = [
+            lines[line - 1],
+            lines[line],
+            lines[line + 1]
+        ];
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            input = str.replace(/\r\n/g, '\n');
+
+            // Remove potential UTF Byte Order Mark
+            input = input.replace(/^\uFEFF/, '');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = string.lastIndex = i;
+
+                    if (match = string.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                            c = input.charAt(i);
+                        }
+                    }
+
+                    if (!inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+                    
+                    switch (c) {
+                        case '{': if (! inParam) { level ++;        chunk.push(c);                           break }
+                        case '}': if (! inParam) { level --;        chunk.push(c); chunks[++j] = chunk = []; break }
+                        case '(': if (! inParam) { inParam = true;  chunk.push(c);                           break }
+                        case ')': if (  inParam) { inParam = false; chunk.push(c);                           break }
+                        default:                                    chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    error = new(LessError)({
+                        index: i,
+                        type: 'Parse',
+                        message: "missing closing `}`",
+                        filename: env.filename
+                    }, env);
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            if (error) {
+                return callback(error);
+            }
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            try {
+                root = new(tree.Ruleset)([], $(this.parsers.primary));
+                root.root = true;
+            } catch (e) {
+                return callback(new(LessError)(e, env));
+            }
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [], importError;
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false, dumpLineNumbers: env.dumpLineNumbers });
+                    } catch (e) {
+                        throw new(LessError)(e, env);
+                    }
+
+                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
+                        if (importError instanceof LessError) throw importError;
+                        else                                  throw new(LessError)(importError, env);
+                    }
+
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('./cssmin').compressor.cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    type: "Parse",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function (e) {
+                    if (e) callback(e);
+                    else callback(null, root);
+                };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k);
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, nameLC, args, alpha_ret, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1];
+                    nameLC = name.toLowerCase();
+
+                    if (nameLC === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (nameLC === 'alpha') {
+                        alpha_ret = $(this.alpha);
+                        if(typeof alpha_ret !== 'undefined') {
+                            return alpha_ret;
+                        }
+                    }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index, env.filename) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.ratio) ||
+                           $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || "";
+
+                    expect(')');
+
+                    return new(tree.URL)((value.value != null || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index, env.filename);
+                    }
+                },
+
+                // A variable entity useing the protective {} e.g. @{var}
+                variableCurly: function () {
+                    var name, curly, index = i;
+
+                    if (input.charAt(i) === '@' && (curly = $(/^@\{([\w-]+)\}/))) {
+                        return new(tree.Variable)("@" + curly[1], index, env.filename);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn|dpi|dpcm|dppx|rem|vw|vh|vmin|vm|ch)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // A Ratio
+                //
+                //    16/9
+                //
+                ratio: function () {
+                  var value, c = input.charCodeAt(i);
+                  if (c > 57 || c < 48) return;
+
+                  if (value = $(/^(\d+\/\d+)/)) {
+                    return new(tree.Ratio)(value[1]);
+                  }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                save();
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+
+                restore();
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args = [], arg, index = i, s = input.charAt(i), name, value, important = false;
+
+                    if (s !== '.' && s !== '#') { return }
+                    
+                    save(); // stop us absorbing part of an invalid selector
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    if ($('(')) {
+                        while (arg = $(this.expression)) {
+                            value = arg;
+                            name = null;
+
+                            // Variable
+                            if (arg.value.length == 1) {
+                                var val = arg.value[0];
+                                if (val instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        if (value = $(this.expression)) {
+                                            name = val.name;
+                                        } else {
+                                            throw new(Error)("Expected value");
+                                        }
+                                    }
+                                }
+                            }
+
+                            args.push({ name: name, value: value });
+
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+                    }
+
+                    if ($(this.important)) {
+                        important = true;
+                    }
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+                    }
+                    
+                    restore();
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value, cond, variadic = false;
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    save();
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        do {
+                            if (input.charAt(i) === '.' && $(/^\.{3}/)) {
+                                variadic = true;
+                                break;
+                            } else if (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                         || $(this.entities.keyword)) {
+                                // Variable
+                                if (param instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        value = expect(this.expression, 'expected expression');
+                                        params.push({ name: param.name, value: value });
+                                    } else if ($(/^\.{3}/)) {
+                                        params.push({ name: param.name, variadic: true });
+                                        variadic = true;
+                                        break;
+                                    } else {
+                                        params.push({ name: param.name });
+                                    }
+                                } else {
+                                    params.push({ value: param });
+                                }
+                            } else {
+                                break;
+                            }
+                        } while ($(','))
+
+                        // .mixincall("@{a}"); 
+                        // looks a bit like a mixin definition.. so we have to be nice and restore
+                        if (!$(')')) {
+                            furthest = i;
+                            restore();
+                        }
+
+                        if ($(/^when/)) { // Guard
+                            cond = expect(this.conditions, 'expected condition');
+                        }
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
+                        } else {
+                            restore();
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    expect(')');
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c, v;
+
+                c = $(this.combinator);
+
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
+                    $('*') || $('&') || $(this.attribute) || $(/^\([^)@]+\)/) || $(/^[\.#](?=@)/) || $(this.entities.variableCurly);
+
+                if (! e) {
+                    if ($('(') && (v = ($(this.entities.variableCurly) || $(this.entities.variable))) && $(')')) {
+                        e = new(tree.Paren)(v);
+                    }
+                }
+
+                if (e) { return new(tree.Element)(c, e, i) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i).match(/\s/)) { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (input.charAt(i - 1).match(/\s/)) {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                // depreciated, will be removed soon
+                if ($('(')) {
+                    sel = $(this.entity);
+                    expect(')');
+                    return new(tree.Selector)([new(tree.Element)('', sel, i)]);
+                }
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[A-Za-z][A-Za-z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^(?:[_A-Za-z0-9-]|\\.)+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match, debugInfo;
+                save();
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports);
+                    if (env.dumpLineNumbers)
+                        ruleset.debugInfo = debugInfo;
+                    return ruleset;
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path, features, index = i;
+                
+                save();
+                
+                var dir = $(/^@import(?:-(once))?\s+/);
+
+                if (dir && (path = $(this.entities.quoted) || $(this.entities.url))) {
+                    features = $(this.mediaFeatures);
+                    if ($(';')) {
+                        return new(tree.Import)(path, imports, features, (dir[1] === 'once'), index);
+                    }
+                }
+                
+                restore();
+            },
+
+            mediaFeature: function () {
+                var e, p, nodes = [];
+
+                do {
+                    if (e = $(this.entities.keyword)) {
+                        nodes.push(e);
+                    } else if ($('(')) {
+                        p = $(this.property);
+                        e = $(this.entity);
+                        if ($(')')) {
+                            if (p && e) {
+                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+                            } else if (e) {
+                                nodes.push(new(tree.Paren)(e));
+                            } else {
+                                return null;
+                            }
+                        } else { return null }
+                    }
+                } while (e);
+
+                if (nodes.length > 0) {
+                    return new(tree.Expression)(nodes);
+                }
+            },
+
+            mediaFeatures: function () {
+                var e, features = [];
+
+                do {
+                  if (e = $(this.mediaFeature)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  } else if (e = $(this.entities.variable)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  }
+                } while (e);
+
+                return features.length > 0 ? features : null;
+            },
+
+            media: function () {
+                var features, rules, media, debugInfo;
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                if ($(/^@media/)) {
+                    features = $(this.mediaFeatures);
+
+                    if (rules = $(this.block)) {
+                        media = new(tree.Media)(rules, features);
+                        if(env.dumpLineNumbers)
+                            media.debugInfo = debugInfo;
+                        return media;
+                    }
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, identifier, e, nodes, nonVendorSpecificName,
+                    hasBlock, hasIdentifier;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import']) || $(this.media)) {
+                    return value;
+                }
+                
+                save();
+
+                name = $(/^@[a-z-]+/);
+
+                nonVendorSpecificName = name;
+                if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
+                    nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
+                }
+
+                switch(nonVendorSpecificName) {
+                    case "@font-face":
+                        hasBlock = true;
+                        break;
+                    case "@viewport":
+                    case "@top-left":
+                    case "@top-left-corner":
+                    case "@top-center":
+                    case "@top-right":
+                    case "@top-right-corner":
+                    case "@bottom-left":
+                    case "@bottom-left-corner":
+                    case "@bottom-center":
+                    case "@bottom-right":
+                    case "@bottom-right-corner":
+                    case "@left-top":
+                    case "@left-middle":
+                    case "@left-bottom":
+                    case "@right-top":
+                    case "@right-middle":
+                    case "@right-bottom":
+                        hasBlock = true;
+                        break;
+                    case "@page":
+                    case "@document":
+                    case "@supports":
+                    case "@keyframes":
+                        hasBlock = true;
+                        hasIdentifier = true;
+                        break;
+                }
+
+                if (hasIdentifier) {
+                    name += " " + ($(/^[^{]+/) || '').trim();
+                }
+
+                if (hasBlock)
+                {
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name, rules);
+                    }
+                } else {
+                    if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+                
+                restore();
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (!isWhitespace(input.charAt(i - 1)) && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            conditions: function () {
+                var a, b, index = i, condition;
+
+                if (a = $(this.condition)) {
+                    while ($(',') && (b = $(this.condition))) {
+                        condition = new(tree.Condition)('or', condition || a, b, index);
+                    }
+                    return condition || a;
+                }
+            },
+            condition: function () {
+                var a, b, c, op, index = i, negate = false;
+
+                if ($(/^not/)) { negate = true }
+                expect('(');
+                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                    if (op = $(/^(?:>=|=<|[<=>])/)) {
+                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                            c = new(tree.Condition)(op, a, b, index, negate);
+                        } else {
+                            error('expected expression');
+                        }
+                    } else {
+                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+                    }
+                    expect(')');
+                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[_a-z0-9-]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (!/^([a-z-]+:)?\//.test(path) && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        // __ Now using the hack of passing a ref to top parser's content cache in the 1st arg. __
+        loadStyleSheet({ href: path, title: path, type: env.mime, contents: env.contents }, function (e) {
+            if (e && typeof(env.errback) === "function") {
+                env.errback.call(null, path, paths, callback, env);
+            } else {
+                callback.apply(null, arguments);
+            }
+        }, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    red: function (color) {
+        return new(tree.Dimension)(color.rgb[0]);
+    },
+    green: function (color) {
+        return new(tree.Dimension)(color.rgb[1]);
+    },
+    blue: function (color) {
+        return new(tree.Dimension)(color.rgb[2]);
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    luma: function (color) {
+        return new(tree.Dimension)(Math.round((0.2126 * (color.rgb[0]/255) +
+            0.7152 * (color.rgb[1]/255) +
+            0.0722 * (color.rgb[2]/255))
+            * color.alpha * 100), '%');
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        if (!weight) {
+            weight = new(tree.Dimension)(50);
+        }
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    contrast: function (color, dark, light, threshold) {
+        if (typeof light === 'undefined') {
+            light = this.rgba(255, 255, 255, 1.0);
+        }
+        if (typeof dark === 'undefined') {
+            dark = this.rgba(0, 0, 0, 1.0);
+        }
+        if (typeof threshold === 'undefined') {
+            threshold = 0.43;
+        } else {
+            threshold = threshold.value;
+        }
+        if (((0.2126 * (color.rgb[0]/255) + 0.7152 * (color.rgb[1]/255) + 0.0722 * (color.rgb[2]/255)) * color.alpha) < threshold) {
+            return light;
+        } else {
+            return dark;
+        }
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n, f) {
+        var fraction = typeof(f) === "undefined" ? 0 : f.value;
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(number(n).toFixed(fraction), n.unit);
+        } else if (typeof(n) === 'number') {
+            return n.toFixed(fraction);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    ceil: function (n) {
+        return this._math('ceil', n);
+    },
+    floor: function (n) {
+        return this._math('floor', n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math[fn](n);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    },
+    percentage: function (n) {
+        return new(tree.Dimension)(n.value * 100, '%');
+    },
+    color: function (n) {
+        if (n instanceof tree.Quoted) {
+            return new(tree.Color)(n.value.slice(1));
+        } else {
+            throw { type: "Argument", message: "argument must be a string" };
+        }
+    },
+    iscolor: function (n) {
+        return this._isa(n, tree.Color);
+    },
+    isnumber: function (n) {
+        return this._isa(n, tree.Dimension);
+    },
+    isstring: function (n) {
+        return this._isa(n, tree.Quoted);
+    },
+    iskeyword: function (n) {
+        return this._isa(n, tree.Keyword);
+    },
+    isurl: function (n) {
+        return this._isa(n, tree.URL);
+    },
+    ispixel: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+    },
+    ispercentage: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+    },
+    isem: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+    },
+    _isa: function (n, Type) {
+        return (n instanceof Type) ? tree.True : tree.False;
+    },
+    
+    /* Blending modes */
+    
+    multiply: function(color1, color2) {
+        var r = color1.rgb[0] * color2.rgb[0] / 255;
+        var g = color1.rgb[1] * color2.rgb[1] / 255;
+        var b = color1.rgb[2] * color2.rgb[2] / 255;
+        return this.rgb(r, g, b);
+    },
+    screen: function(color1, color2) {
+        var r = 255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = 255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = 255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    overlay: function(color1, color2) {
+        var r = color1.rgb[0] < 128 ? 2 * color1.rgb[0] * color2.rgb[0] / 255 : 255 - 2 * (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = color1.rgb[1] < 128 ? 2 * color1.rgb[1] * color2.rgb[1] / 255 : 255 - 2 * (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = color1.rgb[2] < 128 ? 2 * color1.rgb[2] * color2.rgb[2] / 255 : 255 - 2 * (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    softlight: function(color1, color2) {
+        var t = color2.rgb[0] * color1.rgb[0] / 255;
+        var r = t + color1.rgb[0] * (255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255 - t) / 255;
+        t = color2.rgb[1] * color1.rgb[1] / 255;
+        var g = t + color1.rgb[1] * (255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255 - t) / 255;
+        t = color2.rgb[2] * color1.rgb[2] / 255;
+        var b = t + color1.rgb[2] * (255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255 - t) / 255;
+        return this.rgb(r, g, b);
+    },
+    hardlight: function(color1, color2) {
+        var r = color2.rgb[0] < 128 ? 2 * color2.rgb[0] * color1.rgb[0] / 255 : 255 - 2 * (255 - color2.rgb[0]) * (255 - color1.rgb[0]) / 255;
+        var g = color2.rgb[1] < 128 ? 2 * color2.rgb[1] * color1.rgb[1] / 255 : 255 - 2 * (255 - color2.rgb[1]) * (255 - color1.rgb[1]) / 255;
+        var b = color2.rgb[2] < 128 ? 2 * color2.rgb[2] * color1.rgb[2] / 255 : 255 - 2 * (255 - color2.rgb[2]) * (255 - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    difference: function(color1, color2) {
+        var r = Math.abs(color1.rgb[0] - color2.rgb[0]);
+        var g = Math.abs(color1.rgb[1] - color2.rgb[1]);
+        var b = Math.abs(color1.rgb[2] - color2.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    exclusion: function(color1, color2) {
+        var r = color1.rgb[0] + color2.rgb[0] * (255 - color1.rgb[0] - color1.rgb[0]) / 255;
+        var g = color1.rgb[1] + color2.rgb[1] * (255 - color1.rgb[1] - color1.rgb[1]) / 255;
+        var b = color1.rgb[2] + color2.rgb[2] * (255 - color1.rgb[2] - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    average: function(color1, color2) {
+        var r = (color1.rgb[0] + color2.rgb[0]) / 2;
+        var g = (color1.rgb[1] + color2.rgb[1]) / 2;
+        var b = (color1.rgb[2] + color2.rgb[2]) / 2;
+        return this.rgb(r, g, b);
+    },
+    negation: function(color1, color2) {
+        var r = 255 - Math.abs(255 - color2.rgb[0] - color1.rgb[0]);
+        var g = 255 - Math.abs(255 - color2.rgb[1] - color1.rgb[1]);
+        var b = 255 - Math.abs(255 - color2.rgb[2] - color1.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    tint: function(color, amount) {
+        return this.mix(this.rgb(255,255,255), color, amount);
+    },
+    shade: function(color, amount) {
+        return this.mix(this.rgb(0, 0, 0), color, amount);
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        // 'transparent':'rgba(0,0,0,0)',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) {
+            return new(tree.Assignment)(this.key, this.value.eval(env));
+        }
+        return this;
+    }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+    this.filename = filename;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { type: e.type || "Runtime",
+                        message: "error evaluating function `" + this.name + "`" +
+                                 (e.message ? ': ' + e.message : ''),
+                        index: this.index, filename: this.filename };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS(env) }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    },
+    compare: function (x) {
+        if (!x.rgb) {
+            return -1;
+        }
+        
+        return (x.rgb[0] === this.rgb[0] &&
+            x.rgb[1] === this.rgb[1] &&
+            x.rgb[2] === this.rgb[2] &&
+            x.alpha === this.alpha) ? 0 : -1;
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+    this.op = op.trim();
+    this.lvalue = l;
+    this.rvalue = r;
+    this.index = i;
+    this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+    var a = this.lvalue.eval(env),
+        b = this.rvalue.eval(env);
+
+    var i = this.index, result;
+
+    var result = (function (op) {
+        switch (op) {
+            case 'and':
+                return a && b;
+            case 'or':
+                return a || b;
+            default:
+                if (a.compare) {
+                    result = a.compare(b);
+                } else if (b.compare) {
+                    result = b.compare(a);
+                } else {
+                    throw { type: "Type",
+                            message: "Unable to perform comparison",
+                            index: i };
+                }
+                switch (result) {
+                    case -1: return op === '<' || op === '=<';
+                    case  0: return op === '=' || op === '>=' || op === '=<';
+                    case  1: return op === '>' || op === '>=';
+                }
+        }
+    })(this.op);
+    return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    },
+
+    // TODO: Perform unit conversion before comparing
+    compare: function (other) {
+        if (other instanceof tree.Dimension) {
+            if (other.value > this.value) {
+                return -1;
+            } else if (other.value < this.value) {
+                return 1;
+            } else {
+                return 0;
+            }
+        } else {
+            return -1;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+        this.ruleset.allowImports = true;
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        var evaldDirective = this;
+        if (this.ruleset) {
+            env.frames.unshift(this);
+            evaldDirective = new(tree.Directive)(this.name);
+            evaldDirective.ruleset = this.ruleset.eval(env);
+            env.frames.shift();
+        }
+        return evaldDirective;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+
+    if (typeof(value) === 'string') {
+        this.value = value.trim();
+    } else if (value) {
+        this.value = value;
+    } else {
+        this.value = "";
+    }
+    this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+    return new(tree.Element)(this.combinator,
+                             this.value.eval ? this.value.eval(env) : this.value,
+                             this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+	var value = (this.value.toCSS ? this.value.toCSS(env) : this.value);
+	if (value == '' && this.combinator.value.charAt(0) == '&') {
+		return '';
+	} else {
+		return this.combinator.toCSS(env || {}) + value;
+	}
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        ':' : ' :',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS ? e.toCSS(env) : '';
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, once, index) {
+    var that = this;
+
+    this.once = once;
+    this.index = index;
+    this._path = path;
+    this.features = features && new(tree.Value)(features);
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css(\?.*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (e, root, imported) {
+            if (e) { e.index = index }
+            if (imported && that.once) that.skip = imported;
+            that.root = root || new(tree.Ruleset)([], []);
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function (env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.css) {
+            return "@import " + this._path.toCSS() + features + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset, features = this.features && this.features.eval(env);
+
+        if (this.skip) return [];
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value },
+    compare: function (other) {
+        if (other instanceof tree.Keyword) {
+            return other.value === this.value ? 0 : 1;
+        } else {
+            return -1;
+        }
+    }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Media = function (value, features) {
+    var selectors = this.emptySelectors();
+
+    this.features = new(tree.Value)(features);
+    this.ruleset = new(tree.Ruleset)(selectors, value);
+    this.ruleset.allowImports = true;
+};
+tree.Media.prototype = {
+    toCSS: function (ctx, env) {
+        var features = this.features.toCSS(env);
+
+        this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
+        return '@media ' + features + (env.compress ? '{' : ' {\n  ') +
+               this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                           (env.compress ? '}': '\n}\n');
+    },
+    eval: function (env) {
+        if (!env.mediaBlocks) {
+            env.mediaBlocks = [];
+            env.mediaPath = [];
+        }
+        
+        var blockIndex = env.mediaBlocks.length;
+        env.mediaPath.push(this);
+        env.mediaBlocks.push(this);
+
+        var media = new(tree.Media)([], []);
+        if(this.debugInfo) {
+            this.ruleset.debugInfo = this.debugInfo;
+            media.debugInfo = this.debugInfo;
+        }
+        media.features = this.features.eval(env);
+        
+        env.frames.unshift(this.ruleset);
+        media.ruleset = this.ruleset.eval(env);
+        env.frames.shift();
+        
+        env.mediaBlocks[blockIndex] = media;
+        env.mediaPath.pop();
+
+        return env.mediaPath.length === 0 ? media.evalTop(env) :
+                    media.evalNested(env)
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
+    emptySelectors: function() { 
+        var el = new(tree.Element)('', '&', 0);
+        return [new(tree.Selector)([el])];
+    },
+
+    evalTop: function (env) {
+        var result = this;
+
+        // Render all dependent Media blocks.
+        if (env.mediaBlocks.length > 1) {
+            var selectors = this.emptySelectors();
+            result = new(tree.Ruleset)(selectors, env.mediaBlocks);
+            result.multiMedia = true;
+        }
+
+        delete env.mediaBlocks;
+        delete env.mediaPath;
+
+        return result;
+    },
+    evalNested: function (env) {
+        var i, value,
+            path = env.mediaPath.concat([this]);
+
+        // Extract the media-query conditions separated with `,` (OR).
+        for (i = 0; i < path.length; i++) {
+            value = path[i].features instanceof tree.Value ?
+                        path[i].features.value : path[i].features;
+            path[i] = Array.isArray(value) ? value : [value];
+        }
+
+        // Trace all permutations to generate the resulting media-query.
+        //
+        // (a, b and c) with nested (d, e) ->
+        //    a and d
+        //    a and e
+        //    b and c and d
+        //    b and c and e
+        this.features = new(tree.Value)(this.permute(path).map(function (path) {
+            path = path.map(function (fragment) {
+                return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
+            });
+
+            for(i = path.length - 1; i > 0; i--) {
+                path.splice(i, 0, new(tree.Anonymous)("and"));
+            }
+
+            return new(tree.Expression)(path);
+        }));
+
+        // Fake a tree-node that doesn't output anything.
+        return new(tree.Ruleset)([], []);
+    },
+    permute: function (arr) {
+      if (arr.length === 0) {
+          return [];
+      } else if (arr.length === 1) {
+          return arr[0];
+      } else {
+          var result = [];
+          var rest = this.permute(arr.slice(1));
+          for (var i = 0; i < rest.length; i++) {
+              for (var j = 0; j < arr[0].length; j++) {
+                  result.push([arr[0][j]].concat(rest[i]));
+              }
+          }
+          return result;
+      }
+    },
+    bubbleSelectors: function (selectors) {
+      this.ruleset = new(tree.Ruleset)(selectors.slice(0), [this.ruleset]);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+    this.filename = filename;
+    this.important = important;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) {
+                    return { name: a.name, value: a.value.eval(env) };
+                });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments, this.important).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { type:    'Runtime',
+                            message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index, filename: this.filename };
+                }
+            }
+        }
+        throw { type: 'Name',
+                message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index, filename: this.filename };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition, variadic) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.condition = condition;
+    this.variadic = variadic;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    evalParams: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), varargs, arg;
+
+        for (var i = 0, val, name; i < this.params.length; i++) {
+            arg = args && args[i]
+
+            if (arg && arg.name) {
+                frame.rules.unshift(new(tree.Rule)(arg.name, arg.value.eval(env)));
+                args.splice(i, 1);
+                i--;
+                continue;
+            }
+			
+            if (name = this.params[i].name) {
+                if (this.params[i].variadic && args) {
+                    varargs = [];
+                    for (var j = i; j < args.length; j++) {
+                        varargs.push(args[j].value.eval(env));
+                    }
+                    frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
+                } else if (val = (arg && arg.value) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(name, val.eval(env)));
+                } else {
+                    throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        return frame;
+    },
+    eval: function (env, args, important) {
+        var frame = this.evalParams(env, args), context, _arguments = [], rules, start;
+
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push((args[i] && args[i].value) || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        rules = important ?
+            this.rules.map(function (r) {
+                return new(tree.Rule)(r.name, r.value, '!important', r.index);
+            }) : this.rules.slice(0);
+
+        return new(tree.Ruleset)(null, rules).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len, frame;
+
+        if (! this.variadic) {
+            if (argsLength < this.required)                               { return false }
+            if (argsLength > this.params.length)                          { return false }
+            if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+        }
+
+        if (this.condition && !this.condition.eval({
+            frames: [this.evalParams(env, args)].concat(env.frames)
+        }))                                                           { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+    this.value = node;
+};
+tree.Paren.prototype = {
+    toCSS: function (env) {
+        return '(' + this.value.toCSS(env) + ')';
+    },
+    eval: function (env) {
+        return new(tree.Paren)(this.value.eval(env));
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return ('value' in v) ? v.value : v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ratio = function (value) {
+    this.value = value;
+};
+tree.Ratio.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+    this.inline = inline || false;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + (this.inline ? "" : ";");
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name,
+                          this.value.eval(context),
+                          this.important,
+                          this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules, strictImports) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+    this.strictImports = strictImports;
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
+        var rules = [];
+        
+        ruleset.root = this.root;
+        ruleset.allowImports = this.allowImports;
+
+        if(this.debugInfo) {
+            ruleset.debugInfo = this.debugInfo;
+        }
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    rules = rules.concat(ruleset.rules[i].eval(env));
+                } else {
+                    rules.push(ruleset.rules[i]);
+                }
+            }
+            ruleset.rules = rules;
+            rules = [];
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+        
+        var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0;
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                rules = rules.concat(ruleset.rules[i].eval(env));
+            } else {
+                rules.push(ruleset.rules[i]);
+            }
+        }
+        ruleset.rules = rules;
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+        
+        if (env.mediaBlocks) {
+            for(var i = mediaBlockCount; i < env.mediaBlocks.length; i++) {
+                env.mediaBlocks[i].bubbleSelectors(selectors);
+            }
+        }
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+           _rules = [],    //
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            debugInfo,     // Line number debugging
+            rule;
+
+        if (! this.root) {
+            this.joinSelectors(paths, context, this.selectors);
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive) || (rule instanceof tree.Media)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                debugInfo = tree.debugInfo(env, this);
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : ',\n');
+
+                // Remove duplicates
+                for (var i = rules.length - 1; i >= 0; i--) {
+                    if (_rules.indexOf(rules[i]) === -1) {
+                        _rules.unshift(rules[i]);
+                    }
+                }
+                rules = _rules;
+
+                css.push(debugInfo + selector + 
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('')  + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+
+        var i, j, k, 
+            hasParentSelector, newSelectors, el, sel, parentSel, 
+            newSelectorPath, afterParentJoin, newJoinedSelector, 
+            newJoinedSelectorEmpty, lastSelector, currentElements,
+            selectorsMultiplied;
+    
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.value === '&') {
+                hasParentSelector = true;
+            }
+        }
+    
+        if (!hasParentSelector) {
+            if (context.length > 0) {
+                for(i = 0; i < context.length; i++) {
+                    paths.push(context[i].concat(selector));
+                }
+            }
+            else {
+                paths.push([selector]);
+            }
+            return;
+        }
+
+        // The paths are [[Selector]]
+        // The first list is a list of comma seperated selectors
+        // The inner list is a list of inheritance seperated selectors
+        // e.g.
+        // .a, .b {
+        //   .c {
+        //   }
+        // }
+        // == [[.a] [.c]] [[.b] [.c]]
+        //
+
+        // the elements from the current selector so far
+        currentElements = [];
+        // the current list of new selectors to add to the path.
+        // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
+        // by the parents
+        newSelectors = [[]];
+
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            // non parent reference elements just get added
+            if (el.value !== "&") {
+                currentElements.push(el);
+            } else {
+                // the new list of selectors to add
+                selectorsMultiplied = [];
+
+                // merge the current list of non parent selector elements
+                // on to the current list of selectors to add
+                if (currentElements.length > 0) {
+                    this.mergeElementsOnToSelectors(currentElements, newSelectors);
+                }
+
+                // loop through our current selectors
+                for(j = 0; j < newSelectors.length; j++) {
+                    sel = newSelectors[j];
+                    // if we don't have any parent paths, the & might be in a mixin so that it can be used
+                    // whether there are parents or not
+                    if (context.length == 0) {
+                        // the combinator used on el should now be applied to the next element instead so that
+                        // it is not lost
+                        if (sel.length > 0) {
+                            sel[0].elements = sel[0].elements.slice(0);
+                            sel[0].elements.push(new(tree.Element)(el.combinator, '', 0)); //new Element(el.Combinator,  ""));
+                        }
+                        selectorsMultiplied.push(sel);
+                    }
+                    else {
+                        // and the parent selectors
+                        for(k = 0; k < context.length; k++) {
+                            parentSel = context[k];
+                            // We need to put the current selectors
+                            // then join the last selector's elements on to the parents selectors
+
+                            // our new selector path
+                            newSelectorPath = [];
+                            // selectors from the parent after the join
+                            afterParentJoin = [];
+                            newJoinedSelectorEmpty = true;
+
+                            //construct the joined selector - if & is the first thing this will be empty,
+                            // if not newJoinedSelector will be the last set of elements in the selector
+                            if (sel.length > 0) {
+                                newSelectorPath = sel.slice(0);
+                                lastSelector = newSelectorPath.pop();
+                                newJoinedSelector = new(tree.Selector)(lastSelector.elements.slice(0));
+                                newJoinedSelectorEmpty = false;
+                            }
+                            else {
+                                newJoinedSelector = new(tree.Selector)([]);
+                            }
+
+                            //put together the parent selectors after the join
+                            if (parentSel.length > 1) {
+                                afterParentJoin = afterParentJoin.concat(parentSel.slice(1));
+                            }
+
+                            if (parentSel.length > 0) {
+                                newJoinedSelectorEmpty = false;
+
+                                // join the elements so far with the first part of the parent
+                                newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, 0));
+                                newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1));
+                            }
+
+                            if (!newJoinedSelectorEmpty) {
+                                // now add the joined selector
+                                newSelectorPath.push(newJoinedSelector);
+                            }
+
+                            // and the rest of the parent
+                            newSelectorPath = newSelectorPath.concat(afterParentJoin);
+
+                            // add that to our new set of selectors
+                            selectorsMultiplied.push(newSelectorPath);
+                        }
+                    }
+                }
+
+                // our new selectors has been multiplied, so reset the state
+                newSelectors = selectorsMultiplied;
+                currentElements = [];
+            }
+        }
+
+        // if we have any elements left over (e.g. .a& .b == .b)
+        // add them on to all the current selectors
+        if (currentElements.length > 0) {
+            this.mergeElementsOnToSelectors(currentElements, newSelectors);
+        }
+
+        for(i = 0; i < newSelectors.length; i++) {
+            paths.push(newSelectors[i]);
+        }
+    },
+    
+    mergeElementsOnToSelectors: function(elements, selectors) {
+        var i, sel;
+
+        if (selectors.length == 0) {
+            selectors.push([ new(tree.Selector)(elements) ]);
+            return;
+        }
+
+        for(i = 0; i < selectors.length; i++) {
+            sel = selectors[i];
+
+            // if the previous thing in sel is a parent this needs to join on to it
+            if (sel.length > 0) {
+                sel[sel.length - 1] = new(tree.Selector)(sel[sel.length - 1].elements.concat(elements));
+            }
+            else {
+                sel.push(new(tree.Selector)(elements));
+            }
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+};
+tree.Selector.prototype.match = function (other) {
+    var len  = this.elements.length,
+        olen = other.elements.length,
+        max  = Math.min(len, olen);
+
+    if (len < olen) {
+        return false;
+    } else {
+        for (var i = 0; i < max; i++) {
+            if (this.elements[i].value !== other.elements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.eval = function (env) {
+    return new(tree.Selector)(this.elements.map(function (e) {
+        return e.eval(env);
+    }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+    
+    if (this.elements[0].combinator.value === "") {
+        this._css = ' ';
+    } else {
+        this._css = '';
+    }
+    
+    this._css += this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+    
+    return this._css;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    this.value = val;
+    this.paths = paths;
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + this.value.toCSS() + ")";
+    },
+    eval: function (ctx) {
+        var val = this.value.eval(ctx);
+
+        // Add the base path if the URL is relative and we are in the browser
+        if (typeof window !== 'undefined' && typeof val.value === "string" && !/^(?:[a-z-]+:|\/)/.test(val.value) && this.paths.length > 0) {
+            val.value = this.paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+
+        return new(tree.URL)(val, this.paths);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { type: 'Name',
+                    message: "variable " + name + " is undefined",
+                    filename: this.file,
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.debugInfo = function(env, ctx) {
+    var result="";
+    if (env.dumpLineNumbers && !env.compress) {
+        switch(env.dumpLineNumbers) {
+            case 'comments':
+                result = tree.debugInfo.asComment(ctx);
+                break;
+            case 'mediaquery':
+                result = tree.debugInfo.asMediaQuery(ctx);
+                break;
+            case 'all':
+                result = tree.debugInfo.asComment(ctx)+tree.debugInfo.asMediaQuery(ctx);
+                break;
+        }
+    }
+    return result;
+};
+
+tree.debugInfo.asComment = function(ctx) {
+    return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
+};
+
+tree.debugInfo.asMediaQuery = function(ctx) {
+    return '@media -sass-debug-info{filename{font-family:"' + ctx.debugInfo.fileName + '";}line{font-family:"' + ctx.debugInfo.lineNumber + '";}}\n';
+};
+
+tree.find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+tree.jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = less.async || false;
+less.fileAsync = less.fileAsync || false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//
+// Watch mode
+//
+less.watch   = function () { return this.watchMode = true };
+less.unwatch = function () { return this.watchMode = false };
+
+if (less.env === 'development') {
+    less.optimization = 0;
+
+    if (/!watch/.test(location.hash)) {
+        less.watch();
+    }
+    var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);
+    if (dumpLineNumbers) {
+        less.dumpLineNumbers = dumpLineNumbers[1];
+    }
+    less.watchTimer = setInterval(function () {
+        if (less.watchMode) {
+            loadStyleSheets(function (e, root, _, sheet, env) {
+                if (root) {
+                    createCSS(root.toCSS(), sheet, env.lastModified);
+                }
+            });
+        }
+    }, less.poll);
+} else {
+    less.optimization = 3;
+}
+
+var cache;
+
+try {
+    cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+} catch (_) {
+    cache = null;
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (e, root, _, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)({
+                filename: document.location.href.replace(/#.*$/, ''),
+                dumpLineNumbers: less.dumpLineNumbers
+            }).parse(styles[i].innerHTML || '', function (e, tree) {
+                var css = tree.toCSS();
+                var style = styles[i];
+                style.type = 'text/css';
+                if (style.styleSheet) {
+                    style.styleSheet.cssText = css;
+                } else {
+                    style.innerHTML = css;
+                }
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var contents  = sheet.contents || {};  // Passing a ref to top importing parser content cache trough 'sheet' arg.
+    var url       = window.location.href.replace(/[#?].*$/, '');
+    var href      = sheet.href.replace(/\?.*$/, '');
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+
+    // Stylesheets in IE don't always return the full path
+    if (! /^[a-z-]+:/.test(href)) {
+        if (href.charAt(0) == "/") {
+            href = window.location.protocol + "//" + window.location.host + href;
+        } else {
+            href = url.slice(0, url.lastIndexOf('/') + 1) + href;
+        }
+    }
+    xhr(sheet.href, sheet.type, function (data, lastModified) {
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, null, data, sheet, { local: true, remaining: remaining });
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                contents[href] = data;  // Updating top importing parser content cache
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [href.replace(/[\w\.-]+$/, '')],
+                    mime: sheet.type,
+                    filename: href,
+                    'contents': contents,    // Passing top importing parser content cache ref down.
+                    dumpLineNumbers: less.dumpLineNumbers
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining });
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\?.*$/,               '' )  // Remove query
+               .replace(/\.[^\.\/]+$/,         '' )  // Remove file extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href ? sheet.href.replace(/\?.*$/, '') : '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        if( sheet.media ){ css.media = sheet.media; }
+        css.id = id;
+        var nextEl = sheet && sheet.nextSibling || null;
+        document.getElementsByTagName('head')[0].insertBefore(css, nextEl);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        try {
+            cache.setItem(href, styles);
+            cache.setItem(href + ':timestamp', lastModified);
+        } catch(e) {
+            //TODO - could do with adding more robust error handling
+            log('failed to save');
+        }
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? less.fileAsync : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol && !less.fileAsync) {
+        if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+    var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+    var elem = document.createElement('div'), timer, content, error = [];
+    var filename = e.filename || href;
+    var filenameNoPath = filename.match(/([^\/]+)$/)[1];
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p>in <a href="' + filename   + '">' + filenameNoPath + "</a> ";
+
+    var errorline = function (e, i, classname) {
+        if (e.extract[i]) {
+            error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+                               .replace(/\{class\}/, classname)
+                               .replace(/\{content\}/, e.extract[i]));
+        }
+    };
+
+    if (e.stack) {
+        content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+    } else if (e.extract) {
+        errorline(e, 0, '');
+        errorline(e, 1, 'line');
+        errorline(e, 2, '');
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+                    '<ul>' + error.join('') + '</ul>';
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #dd6666;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.line {',
+            'color: #ff0000;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+
+// amd.js
+//
+// Define Less as an AMD module.
+if (typeof define === "function" && define.amd) {
+    define("less", [], function () { return less; } );
+}
+})(window);
diff --git a/util/less/dist/less-1.3.1.min.js b/util/less/dist/less-1.3.1.min.js
new file mode 100644
index 0000000..4043d44
--- /dev/null
+++ b/util/less/dist/less-1.3.1.min.js
@@ -0,0 +1,9 @@
+//
+// LESS - Leaner CSS v1.3.1
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(e,t){function n(t){return e.less[t.split("/")[1]]}function h(){var e=document.getElementsByTagName("style");for(var t=0;t<e.length;t++)e[t].type.match(l)&&(new r.Parser({filename:document.location.href.replace(/#.*$/,""),dumpLineNumbers:r.dumpLineNumbers})).parse(e[t].innerHTML||"",function(n,r){var i=r.toCSS(),s=e[t];s.type="text/css",s.styleSheet?s.styleSheet.cssText=i:s.innerHTML=i})}function p(e,t){for(var n=0;n<r.sheets.length;n++)d(r.sheets[n],e,t,r.sheets.length-(n+1))}f [...]
+n),o,u,a=(i+s)/2,f=i-s;if(i===s)o=u=0;else{u=a>.5?f/(2-i-s):f/(i+s);switch(i){case e:o=(t-n)/f+(t<n?6:0);break;case t:o=(n-e)/f+2;break;case n:o=(e-t)/f+4}o/=6}return{h:o*360,s:u,l:a,a:r}},toARGB:function(){var e=[Math.round(this.alpha*255)].concat(this.rgb);return"#"+e.map(function(e){return e=Math.round(e),e=(e>255?255:e<0?0:e).toString(16),e.length===1?"0"+e:e}).join("")},compare:function(e){return e.rgb?e.rgb[0]===this.rgb[0]&&e.rgb[1]===this.rgb[1]&&e.rgb[2]===this.rgb[2]&&e.alpha== [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.3.2.js b/util/less/dist/less-1.3.2.js
new file mode 100644
index 0000000..290f8f4
--- /dev/null
+++ b/util/less/dist/less-1.3.2.js
@@ -0,0 +1,4401 @@
+//
+// LESS - Leaner CSS v1.3.2
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree, charset;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    if (typeof(window) === 'undefined') { less = {} }
+    else                                { less = window.less = {} }
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // Top parser on an import tree must be sure there is one "env"
+    // which will then be passed arround by reference.
+    var env = env || { };
+    // env.contents and files must be passed arround with top env
+    if (!env.contents) { env.contents = {}; }
+    env.rootpath = env.rootpath || '';       // env.rootpath must be initialized to '' if not provided
+    if (!env.files) { env.files = {}; }
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env.paths || [],  // Search paths, when importing
+        queue: [],               // Files which haven't been imported yet
+        files: env.files,        // Holds the imported parse trees
+        contents: env.contents,  // Holds the imported file contents
+        mime:  env.mime,         // MIME type of .less files
+        error: null,             // Error in parsing/evaluating an import
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (e, root, fullPath) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+
+                var imported = fullPath in that.files;
+
+                that.files[fullPath] = root;                        // Store the root
+
+                if (e && !that.error) { that.error = e }
+
+                callback(e, root, imported);
+
+                if (that.queue.length === 0) { finish(that.error) }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    function isWhitespace(c) {
+        // Could change to \s?
+        var code = c.charCodeAt(0);
+        return code === 32 || code === 10 || code === 9;
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, index, k;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            skipWhitespace(length);
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    function skipWhitespace(length) {
+        var oldi = i, oldj = j,
+            endIndex = i + chunks[j].length,
+            mem = i += length;
+
+        while (i < endIndex) {
+            if (! isWhitespace(input.charAt(i))) { break }
+            i++;
+        }
+        chunks[j] = chunks[j].slice(length + (i - mem));
+        current = i;
+
+        if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+        return oldi !== i || oldj !== j;
+    }
+
+    function expect(arg, msg) {
+        var result = $(arg);
+        if (! result) {
+            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+                                                   : "unexpected token"));
+        } else {
+            return result;
+        }
+    }
+
+    function error(msg, type) {
+        var e = new Error(msg);
+        e.index = i;
+        e.type = type || 'Syntax';
+        throw e;
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    function getInput(e, env) {
+        if (e.filename && env.filename && (e.filename !== env.filename)) {
+            return parser.imports.contents[e.filename];
+        } else {
+            return input;
+        }
+    }
+
+    function getLocation(index, input) {
+        for (var n = index, column = -1;
+                 n >= 0 && input.charAt(n) !== '\n';
+                 n--) { column++ }
+
+        return { line:   typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+                 column: column };
+    }
+
+    function getFileName(e) {
+        if(less.mode === 'browser' || less.mode === 'rhino')
+            return e.filename;
+        else
+            return require('path').resolve(e.filename);
+    }
+
+    function getDebugInfo(index, inputStream, e) {
+        return {
+            lineNumber: getLocation(index, inputStream).line + 1,
+            fileName: getFileName(e)
+        };
+    }
+
+    function LessError(e, env) {
+        var input = getInput(e, env),
+            loc = getLocation(e.index, input),
+            line = loc.line,
+            col  = loc.column,
+            lines = input.split('\n');
+
+        this.type = e.type || 'Syntax';
+        this.message = e.message;
+        this.filename = e.filename || env.filename;
+        this.index = e.index;
+        this.line = typeof(line) === 'number' ? line + 1 : null;
+        this.callLine = e.call && (getLocation(e.call, input).line + 1);
+        this.callExtract = lines[getLocation(e.call, input).line];
+        this.stack = e.stack;
+        this.column = col;
+        this.extract = [
+            lines[line - 1],
+            lines[line],
+            lines[line + 1]
+        ];
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            input = str.replace(/\r\n/g, '\n');
+
+            // Remove potential UTF Byte Order Mark
+            input = input.replace(/^\uFEFF/, '');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam;
+
+                for (var i = 0, c, cc; i < input.length;) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = string.lastIndex = i;
+
+                    if (match = string.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                            continue;
+                        }
+                    }
+
+                    if (!inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    continue;
+                                }
+                            }
+                        }
+                    }
+                    
+                    switch (c) {
+                        case '{': if (! inParam) { level ++;        chunk.push(c);                           break }
+                        case '}': if (! inParam) { level --;        chunk.push(c); chunks[++j] = chunk = []; break }
+                        case '(': if (! inParam) { inParam = true;  chunk.push(c);                           break }
+                        case ')': if (  inParam) { inParam = false; chunk.push(c);                           break }
+                        default:                                    chunk.push(c);
+                    }
+                    
+                    i++;
+                }
+                if (level != 0) {
+                    error = new(LessError)({
+                        index: i-1,
+                        type: 'Parse',
+                        message: (level > 0) ? "missing closing `}`" : "missing opening `{`",
+                        filename: env.filename
+                    }, env);
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            if (error) {
+                return callback(error, env);
+            }
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            try {
+                root = new(tree.Ruleset)([], $(this.parsers.primary));
+                root.root = true;
+            } catch (e) {
+                return callback(new(LessError)(e, env));
+            }
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [], importError;
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false, dumpLineNumbers: env.dumpLineNumbers });
+                    } catch (e) {
+                        throw new(LessError)(e, env);
+                    }
+
+                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
+                        if (importError instanceof LessError) throw importError;
+                        else                                  throw new(LessError)(importError, env);
+                    }
+
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('ycssmin').cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    type: "Parse",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function (e) {
+                    e = error || e;
+                    if (e) callback(e);
+                    else callback(null, root);
+                };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/) || $(/^;+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k);
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, nameLC, args, alpha_ret, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1];
+                    nameLC = name.toLowerCase();
+
+                    if (nameLC === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (nameLC === 'alpha') {
+                        alpha_ret = $(this.alpha);
+                        if(typeof alpha_ret !== 'undefined') {
+                            return alpha_ret;
+                        }
+                    }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index, env.filename) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.ratio) ||
+                           $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted) ||
+                           $(this.entities.unicodeDescriptor);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || "";
+
+                    expect(')');
+
+                    return new(tree.URL)((value.value != null || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), env.rootpath);
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index, env.filename);
+                    }
+                },
+
+                // A variable entity useing the protective {} e.g. @{var}
+                variableCurly: function () {
+                    var name, curly, index = i;
+
+                    if (input.charAt(i) === '@' && (curly = $(/^@\{([\w-]+)\}/))) {
+                        return new(tree.Variable)("@" + curly[1], index, env.filename);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    //Is the first char of the dimension 0-9, '.', '+' or '-'
+                    if ((c > 57 || c < 43) || c === 47 || c == 44) return;
+
+                    if (value = $(/^([+-]?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn|dpi|dpcm|dppx|rem|vw|vh|vmin|vm|ch)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // A Ratio
+                //
+                //    16/9
+                //
+                ratio: function () {
+                  var value, c = input.charCodeAt(i);
+                  if (c > 57 || c < 48) return;
+
+                  if (value = $(/^(\d+\/\d+)/)) {
+                    return new(tree.Ratio)(value[1]);
+                  }
+                },
+                
+                //
+                // A unicode descriptor, as is used in unicode-range
+                //
+                // U+0??  or U+00A1-00A9
+                //
+                unicodeDescriptor: function () {
+                    var ud;
+                    
+                    if (ud = $(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/)) {
+                        return new(tree.UnicodeDescriptor)(ud[0]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                save();
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+
+                restore();
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, argsSemiColon = [], argsComma = [], args, delim, arg, nameLoop, expressions, isSemiColonSeperated, expressionContainsNamed, index = i, s = input.charAt(i), name, value, important = false;
+
+                    if (s !== '.' && s !== '#') { return }
+                    
+                    save(); // stop us absorbing part of an invalid selector
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    if ($('(')) {
+                        expressions = [];
+                        while (arg = $(this.expression)) {
+                            nameLoop = null;
+                            value = arg;
+
+                            // Variable
+                            if (arg.value.length == 1) {
+                                var val = arg.value[0];
+                                if (val instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        if (expressions.length > 0) {
+                                            if (isSemiColonSeperated) {
+                                                error("Cannot mix ; and , as delimiter types");
+                                            }
+                                            expressionContainsNamed = true;
+                                        }
+                                        value = expect(this.expression);
+                                        nameLoop = (name = val.name);
+                                    }
+                                }
+                            }
+                            
+                            expressions.push(value);
+                            
+                            argsComma.push({ name: nameLoop, value: value });
+                            
+                            if ($(',')) {
+                                continue;
+                            }
+                            
+                            if ($(';') || isSemiColonSeperated) {
+                            
+                                if (expressionContainsNamed) {
+                                    error("Cannot mix ; and , as delimiter types");
+                                }
+                            
+                                isSemiColonSeperated = true;
+                                                        
+                                if (expressions.length > 1) {
+                                    value = new(tree.Value)(expressions);
+                                }
+                                argsSemiColon.push({ name: name, value: value });
+                            
+                                name = null;
+                                expressions = [];
+                                expressionContainsNamed = false;
+                            }
+                        }
+
+                        expect(')');
+                    }
+
+                    args = isSemiColonSeperated ? argsSemiColon : argsComma;
+
+                    if ($(this.important)) {
+                        important = true;
+                    }
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+                    }
+                    
+                    restore();
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value, cond, variadic = false;
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*\}/)) return;
+
+                    save();
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        do {
+                            $(this.comment);
+                            if (input.charAt(i) === '.' && $(/^\.{3}/)) {
+                                variadic = true;
+                                params.push({ variadic: true });
+                                break;
+                            } else if (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                         || $(this.entities.keyword)) {
+                                // Variable
+                                if (param instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        value = expect(this.expression, 'expected expression');
+                                        params.push({ name: param.name, value: value });
+                                    } else if ($(/^\.{3}/)) {
+                                        params.push({ name: param.name, variadic: true });
+                                        variadic = true;
+                                        break;
+                                    } else {
+                                        params.push({ name: param.name });
+                                    }
+                                } else {
+                                    params.push({ value: param });
+                                }
+                            } else {
+                                break;
+                            }
+                        } while ($(',') || $(';'))
+
+                        // .mixincall("@{a}"); 
+                        // looks a bit like a mixin definition.. so we have to be nice and restore
+                        if (!$(')')) {
+                            furthest = i;
+                            restore();
+                        }
+                        
+                        $(this.comment);
+
+                        if ($(/^when/)) { // Guard
+                            cond = expect(this.conditions, 'expected condition');
+                        }
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
+                        } else {
+                            restore();
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  ||$(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    expect(')');
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c, v;
+
+                c = $(this.combinator);
+
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
+                    $('*') || $('&') || $(this.attribute) || $(/^\([^()@]+\)/) || $(/^[\.#](?=@)/) || $(this.entities.variableCurly);
+
+                if (! e) {
+                    if ($('(')) {
+                        if ((v = ($(this.entities.variableCurly) || 
+                                $(this.entities.variable) || 
+                                $(this.selector))) && 
+                                $(')')) {
+                            e = new(tree.Paren)(v);
+                        }
+                    }
+                }
+
+                if (e) { return new(tree.Element)(c, e, i) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~' || c === '|') {
+                    i++;
+                    while (input.charAt(i).match(/\s/)) { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (input.charAt(i - 1).match(/\s/)) {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                // depreciated, will be removed soon
+                if ($('(')) {
+                    sel = $(this.entity);
+                    expect(')');
+                    return new(tree.Selector)([new(tree.Element)('', sel, i)]);
+                }
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^(?:[_A-Za-z0-9-]|\\.)+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match, debugInfo;
+                save();
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports);
+                    if (env.dumpLineNumbers)
+                        ruleset.debugInfo = debugInfo;
+                    return ruleset;
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path, features, index = i;
+                
+                save();
+                
+                var dir = $(/^@import(?:-(once))?\s+/);
+
+                if (dir && (path = $(this.entities.quoted) || $(this.entities.url))) {
+                    features = $(this.mediaFeatures);
+                    if ($(';')) {
+                        return new(tree.Import)(path, imports, features, (dir[1] === 'once'), index, env.rootpath);
+                    }
+                }
+                
+                restore();
+            },
+
+            mediaFeature: function () {
+                var e, p, nodes = [];
+
+                do {
+                    if (e = $(this.entities.keyword)) {
+                        nodes.push(e);
+                    } else if ($('(')) {
+                        p = $(this.property);
+                        e = $(this.entity);
+                        if ($(')')) {
+                            if (p && e) {
+                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+                            } else if (e) {
+                                nodes.push(new(tree.Paren)(e));
+                            } else {
+                                return null;
+                            }
+                        } else { return null }
+                    }
+                } while (e);
+
+                if (nodes.length > 0) {
+                    return new(tree.Expression)(nodes);
+                }
+            },
+
+            mediaFeatures: function () {
+                var e, features = [];
+
+                do {
+                  if (e = $(this.mediaFeature)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  } else if (e = $(this.entities.variable)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  }
+                } while (e);
+
+                return features.length > 0 ? features : null;
+            },
+
+            media: function () {
+                var features, rules, media, debugInfo;
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                if ($(/^@media/)) {
+                    features = $(this.mediaFeatures);
+
+                    if (rules = $(this.block)) {
+                        media = new(tree.Media)(rules, features);
+                        if(env.dumpLineNumbers)
+                            media.debugInfo = debugInfo;
+                        return media;
+                    }
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, identifier, e, nodes, nonVendorSpecificName,
+                    hasBlock, hasIdentifier, hasExpression;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import']) || $(this.media)) {
+                    return value;
+                }
+                
+                save();
+
+                name = $(/^@[a-z-]+/);
+                
+                if (!name) return;
+
+                nonVendorSpecificName = name;
+                if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
+                    nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
+                }
+
+                switch(nonVendorSpecificName) {
+                    case "@font-face":
+                        hasBlock = true;
+                        break;
+                    case "@viewport":
+                    case "@top-left":
+                    case "@top-left-corner":
+                    case "@top-center":
+                    case "@top-right":
+                    case "@top-right-corner":
+                    case "@bottom-left":
+                    case "@bottom-left-corner":
+                    case "@bottom-center":
+                    case "@bottom-right":
+                    case "@bottom-right-corner":
+                    case "@left-top":
+                    case "@left-middle":
+                    case "@left-bottom":
+                    case "@right-top":
+                    case "@right-middle":
+                    case "@right-bottom":
+                        hasBlock = true;
+                        break;
+                    case "@page":
+                    case "@document":
+                    case "@supports":
+                    case "@keyframes":
+                        hasBlock = true;
+                        hasIdentifier = true;
+                        break;
+                    case "@namespace":
+                        hasExpression = true;
+                        break;
+                }
+
+                if (hasIdentifier) {
+                    name += " " + ($(/^[^{]+/) || '').trim();
+                }
+
+                if (hasBlock)
+                {
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name, rules);
+                    }
+                } else {
+                    if ((value = hasExpression ? $(this.expression) : $(this.entity)) && $(';')) {
+                        var directive = new(tree.Directive)(name, value);
+                        if (env.dumpLineNumbers) {
+                            directive.debugInfo = getDebugInfo(i, input, env);
+                        }
+                        return directive;
+                    }
+                }
+                
+                restore();
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/[*\/]/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (!isWhitespace(input.charAt(i - 1)) && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            conditions: function () {
+                var a, b, index = i, condition;
+
+                if (a = $(this.condition)) {
+                    while ($(',') && (b = $(this.condition))) {
+                        condition = new(tree.Condition)('or', condition || a, b, index);
+                    }
+                    return condition || a;
+                }
+            },
+            condition: function () {
+                var a, b, c, op, index = i, negate = false;
+
+                if ($(/^not/)) { negate = true }
+                expect('(');
+                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                    if (op = $(/^(?:>=|=<|[<=>])/)) {
+                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                            c = new(tree.Condition)(op, a, b, index, negate);
+                        } else {
+                            error('expected expression');
+                        }
+                    } else {
+                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+                    }
+                    expect(')');
+                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[_a-z0-9-]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (!/^([a-z-]+:)?\//.test(path) && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ 
+            href: path, 
+            title: path, 
+            type: env.mime, 
+            contents: env.contents, 
+            files: env.files, 
+            rootpath: env.rootpath,
+            entryPath: env.entryPath,
+            relativeUrls: env.relativeUrls }, 
+        function (e, root, data, sheet, _, path) {
+            if (e && typeof(env.errback) === "function") {
+                env.errback.call(null, path, paths, callback, env);
+            } else {
+                callback.call(null, e, root, path);
+            }
+        }, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return scaled(c, 256); });
+        a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+
+    hsv: function(h, s, v) {
+        return this.hsva(h, s, v, 1.0);
+    },
+
+    hsva: function(h, s, v, a) {
+        h = ((number(h) % 360) / 360) * 360;
+        s = number(s); v = number(v); a = number(a);
+
+        var i, f;
+        i = Math.floor((h / 60) % 6);
+        f = (h / 60) - i;
+
+        var vs = [v,
+                  v * (1 - s),
+                  v * (1 - f * s),
+                  v * (1 - (1 - f) * s)];
+        var perm = [[0, 3, 1],
+                    [2, 0, 1],
+                    [1, 0, 3],
+                    [1, 2, 0],
+                    [3, 1, 0],
+                    [0, 1, 2]];
+
+        return this.rgba(vs[perm[i][0]] * 255,
+                         vs[perm[i][1]] * 255,
+                         vs[perm[i][2]] * 255,
+                         a);
+    },
+
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    red: function (color) {
+        return new(tree.Dimension)(color.rgb[0]);
+    },
+    green: function (color) {
+        return new(tree.Dimension)(color.rgb[1]);
+    },
+    blue: function (color) {
+        return new(tree.Dimension)(color.rgb[2]);
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    luma: function (color) {
+        return new(tree.Dimension)(Math.round((0.2126 * (color.rgb[0]/255) +
+            0.7152 * (color.rgb[1]/255) +
+            0.0722 * (color.rgb[2]/255)) *
+            color.alpha * 100), '%');
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        if (!weight) {
+            weight = new(tree.Dimension)(50);
+        }
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    contrast: function (color, dark, light, threshold) {
+        if (typeof light === 'undefined') {
+            light = this.rgba(255, 255, 255, 1.0);
+        }
+        if (typeof dark === 'undefined') {
+            dark = this.rgba(0, 0, 0, 1.0);
+        }
+        if (typeof threshold === 'undefined') {
+            threshold = 0.43;
+        } else {
+            threshold = threshold.value;
+        }
+        if (((0.2126 * (color.rgb[0]/255) + 0.7152 * (color.rgb[1]/255) + 0.0722 * (color.rgb[2]/255)) * color.alpha) < threshold) {
+            return light;
+        } else {
+            return dark;
+        }
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    unit: function (val, unit) {
+        return new(tree.Dimension)(val.value, unit ? unit.toCSS() : "");
+    },
+    round: function (n, f) {
+        var fraction = typeof(f) === "undefined" ? 0 : f.value;
+        return this._math(function(num) { return num.toFixed(fraction); }, n);
+    },
+    ceil: function (n) {
+        return this._math(Math.ceil, n);
+    },
+    floor: function (n) {
+        return this._math(Math.floor, n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(fn(parseFloat(n.value)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return fn(n);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    },
+    percentage: function (n) {
+        return new(tree.Dimension)(n.value * 100, '%');
+    },
+    color: function (n) {
+        if (n instanceof tree.Quoted) {
+            return new(tree.Color)(n.value.slice(1));
+        } else {
+            throw { type: "Argument", message: "argument must be a string" };
+        }
+    },
+    iscolor: function (n) {
+        return this._isa(n, tree.Color);
+    },
+    isnumber: function (n) {
+        return this._isa(n, tree.Dimension);
+    },
+    isstring: function (n) {
+        return this._isa(n, tree.Quoted);
+    },
+    iskeyword: function (n) {
+        return this._isa(n, tree.Keyword);
+    },
+    isurl: function (n) {
+        return this._isa(n, tree.URL);
+    },
+    ispixel: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+    },
+    ispercentage: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+    },
+    isem: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+    },
+    _isa: function (n, Type) {
+        return (n instanceof Type) ? tree.True : tree.False;
+    },
+    
+    /* Blending modes */
+    
+    multiply: function(color1, color2) {
+        var r = color1.rgb[0] * color2.rgb[0] / 255;
+        var g = color1.rgb[1] * color2.rgb[1] / 255;
+        var b = color1.rgb[2] * color2.rgb[2] / 255;
+        return this.rgb(r, g, b);
+    },
+    screen: function(color1, color2) {
+        var r = 255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = 255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = 255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    overlay: function(color1, color2) {
+        var r = color1.rgb[0] < 128 ? 2 * color1.rgb[0] * color2.rgb[0] / 255 : 255 - 2 * (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = color1.rgb[1] < 128 ? 2 * color1.rgb[1] * color2.rgb[1] / 255 : 255 - 2 * (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = color1.rgb[2] < 128 ? 2 * color1.rgb[2] * color2.rgb[2] / 255 : 255 - 2 * (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    softlight: function(color1, color2) {
+        var t = color2.rgb[0] * color1.rgb[0] / 255;
+        var r = t + color1.rgb[0] * (255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255 - t) / 255;
+        t = color2.rgb[1] * color1.rgb[1] / 255;
+        var g = t + color1.rgb[1] * (255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255 - t) / 255;
+        t = color2.rgb[2] * color1.rgb[2] / 255;
+        var b = t + color1.rgb[2] * (255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255 - t) / 255;
+        return this.rgb(r, g, b);
+    },
+    hardlight: function(color1, color2) {
+        var r = color2.rgb[0] < 128 ? 2 * color2.rgb[0] * color1.rgb[0] / 255 : 255 - 2 * (255 - color2.rgb[0]) * (255 - color1.rgb[0]) / 255;
+        var g = color2.rgb[1] < 128 ? 2 * color2.rgb[1] * color1.rgb[1] / 255 : 255 - 2 * (255 - color2.rgb[1]) * (255 - color1.rgb[1]) / 255;
+        var b = color2.rgb[2] < 128 ? 2 * color2.rgb[2] * color1.rgb[2] / 255 : 255 - 2 * (255 - color2.rgb[2]) * (255 - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    difference: function(color1, color2) {
+        var r = Math.abs(color1.rgb[0] - color2.rgb[0]);
+        var g = Math.abs(color1.rgb[1] - color2.rgb[1]);
+        var b = Math.abs(color1.rgb[2] - color2.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    exclusion: function(color1, color2) {
+        var r = color1.rgb[0] + color2.rgb[0] * (255 - color1.rgb[0] - color1.rgb[0]) / 255;
+        var g = color1.rgb[1] + color2.rgb[1] * (255 - color1.rgb[1] - color1.rgb[1]) / 255;
+        var b = color1.rgb[2] + color2.rgb[2] * (255 - color1.rgb[2] - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    average: function(color1, color2) {
+        var r = (color1.rgb[0] + color2.rgb[0]) / 2;
+        var g = (color1.rgb[1] + color2.rgb[1]) / 2;
+        var b = (color1.rgb[2] + color2.rgb[2]) / 2;
+        return this.rgb(r, g, b);
+    },
+    negation: function(color1, color2) {
+        var r = 255 - Math.abs(255 - color2.rgb[0] - color1.rgb[0]);
+        var g = 255 - Math.abs(255 - color2.rgb[1] - color1.rgb[1]);
+        var b = 255 - Math.abs(255 - color2.rgb[2] - color1.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    tint: function(color, amount) {
+        return this.mix(this.rgb(255,255,255), color, amount);
+    },
+    shade: function(color, amount) {
+        return this.mix(this.rgb(0, 0, 0), color, amount);
+    }
+};
+
+function hsla(color) {
+    return tree.functions.hsla(color.h, color.s, color.l, color.a);
+}
+
+function scaled(n, size) {
+    if (n instanceof tree.Dimension && n.unit == '%') {
+        return parseFloat(n.value * size / 100);
+    } else {
+        return number(n);
+    }
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        // 'transparent':'rgba(0,0,0,0)',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) {
+            return new(tree.Assignment)(this.key, this.value.eval(env));
+        }
+        return this;
+    }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+    this.filename = filename;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { type: e.type || "Runtime",
+                        message: "error evaluating function `" + this.name + "`" +
+                                 (e.message ? ': ' + e.message : ''),
+                        index: this.index, filename: this.filename };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS(env) }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    },
+    compare: function (x) {
+        if (!x.rgb) {
+            return -1;
+        }
+        
+        return (x.rgb[0] === this.rgb[0] &&
+            x.rgb[1] === this.rgb[1] &&
+            x.rgb[2] === this.rgb[2] &&
+            x.alpha === this.alpha) ? 0 : -1;
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+    this.op = op.trim();
+    this.lvalue = l;
+    this.rvalue = r;
+    this.index = i;
+    this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+    var a = this.lvalue.eval(env),
+        b = this.rvalue.eval(env);
+
+    var i = this.index, result;
+
+    var result = (function (op) {
+        switch (op) {
+            case 'and':
+                return a && b;
+            case 'or':
+                return a || b;
+            default:
+                if (a.compare) {
+                    result = a.compare(b);
+                } else if (b.compare) {
+                    result = b.compare(a);
+                } else {
+                    throw { type: "Type",
+                            message: "Unable to perform comparison",
+                            index: i };
+                }
+                switch (result) {
+                    case -1: return op === '<' || op === '=<';
+                    case  0: return op === '=' || op === '>=' || op === '=<';
+                    case  1: return op === '>' || op === '>=';
+                }
+        }
+    })(this.op);
+    return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    },
+
+    compare: function (other) {
+        if (other instanceof tree.Dimension) {
+            if (other.value > this.value) {
+                return -1;
+            } else if (other.value < this.value) {
+                return 1;
+            } else {
+                if (other.unit && this.unit !== other.unit) {
+                    return -1;
+                }
+                return 0;
+            }
+        } else {
+            return -1;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+        this.ruleset.allowImports = true;
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        var evaldDirective = this;
+        if (this.ruleset) {
+            env.frames.unshift(this);
+            evaldDirective = new(tree.Directive)(this.name);
+            evaldDirective.ruleset = this.ruleset.eval(env);
+            env.frames.shift();
+        }
+        return evaldDirective;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+
+    if (typeof(value) === 'string') {
+        this.value = value.trim();
+    } else if (value) {
+        this.value = value;
+    } else {
+        this.value = "";
+    }
+    this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+    return new(tree.Element)(this.combinator,
+                             this.value.eval ? this.value.eval(env) : this.value,
+                             this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+	var value = (this.value.toCSS ? this.value.toCSS(env) : this.value);
+	if (value == '' && this.combinator.value.charAt(0) == '&') {
+		return '';
+	} else {
+		return this.combinator.toCSS(env || {}) + value;
+	}
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        ':' : ' :',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > ',
+        '|' : env.compress ? '|' : ' | '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS ? e.toCSS(env) : '';
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, once, index, rootpath) {
+    var that = this;
+
+    this.once = once;
+    this.index = index;
+    this._path = path;
+    this.features = features && new(tree.Value)(features);
+    this.rootpath = rootpath;
+		
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /(\.[a-z]*$)|([\?;].*)$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css([\?;].*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (e, root, imported) {
+            if (e) { e.index = index }
+            if (imported && that.once) that.skip = imported;
+            that.root = root || new(tree.Ruleset)([], []);
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function (env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.css) {
+            // Add the base path if the import is relative
+            if (typeof this._path.value === "string" && !/^(?:[a-z-]+:|\/)/.test(this._path.value)) {
+                this._path.value = this.rootpath + this._path.value;
+            }
+            return "@import " + this._path.toCSS() + features + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset, features = this.features && this.features.eval(env);
+
+        if (this.skip) return [];
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+            ruleset.evalImports(env);
+
+            return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value },
+    compare: function (other) {
+        if (other instanceof tree.Keyword) {
+            return other.value === this.value ? 0 : 1;
+        } else {
+            return -1;
+        }
+    }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Media = function (value, features) {
+    var selectors = this.emptySelectors();
+
+    this.features = new(tree.Value)(features);
+    this.ruleset = new(tree.Ruleset)(selectors, value);
+    this.ruleset.allowImports = true;
+};
+tree.Media.prototype = {
+    toCSS: function (ctx, env) {
+        var features = this.features.toCSS(env);
+
+        this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
+        return '@media ' + features + (env.compress ? '{' : ' {\n  ') +
+               this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                           (env.compress ? '}': '\n}\n');
+    },
+    eval: function (env) {
+        if (!env.mediaBlocks) {
+            env.mediaBlocks = [];
+            env.mediaPath = [];
+        }
+        
+        var media = new(tree.Media)([], []);
+        if(this.debugInfo) {
+            this.ruleset.debugInfo = this.debugInfo;
+            media.debugInfo = this.debugInfo;
+        }
+        media.features = this.features.eval(env);
+        
+        env.mediaPath.push(media);
+        env.mediaBlocks.push(media);
+        
+        env.frames.unshift(this.ruleset);
+        media.ruleset = this.ruleset.eval(env);
+        env.frames.shift();
+        
+        env.mediaPath.pop();
+
+        return env.mediaPath.length === 0 ? media.evalTop(env) :
+                    media.evalNested(env)
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
+    emptySelectors: function() { 
+        var el = new(tree.Element)('', '&', 0);
+        return [new(tree.Selector)([el])];
+    },
+
+    evalTop: function (env) {
+        var result = this;
+
+        // Render all dependent Media blocks.
+        if (env.mediaBlocks.length > 1) {
+            var selectors = this.emptySelectors();
+            result = new(tree.Ruleset)(selectors, env.mediaBlocks);
+            result.multiMedia = true;
+        }
+
+        delete env.mediaBlocks;
+        delete env.mediaPath;
+
+        return result;
+    },
+    evalNested: function (env) {
+        var i, value,
+            path = env.mediaPath.concat([this]);
+
+        // Extract the media-query conditions separated with `,` (OR).
+        for (i = 0; i < path.length; i++) {
+            value = path[i].features instanceof tree.Value ?
+                        path[i].features.value : path[i].features;
+            path[i] = Array.isArray(value) ? value : [value];
+        }
+
+        // Trace all permutations to generate the resulting media-query.
+        //
+        // (a, b and c) with nested (d, e) ->
+        //    a and d
+        //    a and e
+        //    b and c and d
+        //    b and c and e
+        this.features = new(tree.Value)(this.permute(path).map(function (path) {
+            path = path.map(function (fragment) {
+                return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
+            });
+
+            for(i = path.length - 1; i > 0; i--) {
+                path.splice(i, 0, new(tree.Anonymous)("and"));
+            }
+
+            return new(tree.Expression)(path);
+        }));
+
+        // Fake a tree-node that doesn't output anything.
+        return new(tree.Ruleset)([], []);
+    },
+    permute: function (arr) {
+      if (arr.length === 0) {
+          return [];
+      } else if (arr.length === 1) {
+          return arr[0];
+      } else {
+          var result = [];
+          var rest = this.permute(arr.slice(1));
+          for (var i = 0; i < rest.length; i++) {
+              for (var j = 0; j < arr[0].length; j++) {
+                  result.push([arr[0][j]].concat(rest[i]));
+              }
+          }
+          return result;
+      }
+    },
+    bubbleSelectors: function (selectors) {
+      this.ruleset = new(tree.Ruleset)(selectors.slice(0), [this.ruleset]);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+    this.filename = filename;
+    this.important = important;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound;
+
+        args = this.arguments && this.arguments.map(function (a) {
+            return { name: a.name, value: a.value.eval(env) };
+        });
+
+        for (i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                isOneFound = true;
+                for (m = 0; m < mixins.length; m++) {
+                    mixin = mixins[m];
+                    isRecursive = false;
+                    for(f = 0; f < env.frames.length; f++) {
+                        if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) {
+                            isRecursive = true;
+                            break;
+                        }
+                    }
+                    if (isRecursive) {
+                        continue;
+                    }
+                    if (mixin.matchArgs(args, env)) {
+                        if (!mixin.matchCondition || mixin.matchCondition(args, env)) {
+                            try {
+                                Array.prototype.push.apply(
+                                      rules, mixin.eval(env, args, this.important).rules);
+                            } catch (e) {
+                                throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
+                            }
+                        }
+                        match = true;
+                    }
+                }
+                if (match) {
+                    return rules;
+                }
+            }
+        }
+        if (isOneFound) {
+            throw { type:    'Runtime',
+                    message: 'No matching definition was found for `' +
+                              this.selector.toCSS().trim() + '('      +
+                              (args ? args.map(function (a) {
+                                  var argValue = "";
+                                  if (a.name) {
+                                      argValue += a.name + ":";
+                                  }
+                                  if (a.value.toCSS) {
+                                      argValue += a.value.toCSS();
+                                  } else {
+                                      argValue += "???";
+                                  }
+                                  return argValue;
+                              }).join(', ') : "") + ")`",
+                    index:   this.index, filename: this.filename };
+        } else {
+            throw { type: 'Name',
+                message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index, filename: this.filename };
+        }
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition, variadic) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.condition = condition;
+    this.variadic = variadic;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    evalParams: function (env, mixinEnv, args, evaldArguments) {
+        var frame = new(tree.Ruleset)(null, []), varargs, arg, params = this.params.slice(0), i, j, val, name, isNamedFound, argIndex;
+        
+        if (args) {
+            args = args.slice(0);
+
+            for(i = 0; i < args.length; i++) {
+                arg = args[i];
+                if (name = (arg && arg.name)) {
+                    isNamedFound = false;
+                    for(j = 0; j < params.length; j++) {
+                        if (!evaldArguments[j] && name === params[j].name) {
+                            evaldArguments[j] = arg.value.eval(env);
+                            frame.rules.unshift(new(tree.Rule)(name, arg.value.eval(env)));
+                            isNamedFound = true;
+                            break;
+                        }
+                    }
+                    if (isNamedFound) {
+                        args.splice(i, 1);
+                        i--;
+                        continue;
+                    } else {
+                        throw { type: 'Runtime', message: "Named argument for " + this.name +
+                            ' ' + args[i].name + ' not found' };
+                    }
+                }
+            }
+        }
+        argIndex = 0;
+        for (i = 0; i < params.length; i++) {
+            if (evaldArguments[i]) continue;
+            
+            arg = args && args[argIndex];
+
+            if (name = params[i].name) {
+                if (params[i].variadic && args) {
+                    varargs = [];
+                    for (j = argIndex; j < args.length; j++) {
+                        varargs.push(args[j].value.eval(env));
+                    }
+                    frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
+                } else {
+                    val = arg && arg.value;
+                    if (val) {
+                        val = val.eval(env);
+                    } else if (params[i].value) {
+                        val = params[i].value.eval(mixinEnv);
+                    } else {
+                        throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                    }
+                    
+                    frame.rules.unshift(new(tree.Rule)(name, val));
+                    evaldArguments[i] = val;
+                }
+            }
+            
+            if (params[i].variadic && args) {
+                for (j = argIndex; j < args.length; j++) {
+                    evaldArguments[j] = args[j].value.eval(env);
+                }
+            }
+            argIndex++;
+        }
+
+        return frame;
+    },
+    eval: function (env, args, important) {
+        var _arguments = [],
+            mixinFrames = this.frames.concat(env.frames),
+            frame = this.evalParams(env, {frames: mixinFrames}, args, _arguments), 
+            context, rules, start, ruleset;
+
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        rules = important ?
+            this.parent.makeImportant.apply(this).rules : this.rules.slice(0);
+
+        ruleset = new(tree.Ruleset)(null, rules).eval({
+            frames: [this, frame].concat(mixinFrames)
+        });
+        ruleset.originalRuleset = this;
+        return ruleset;
+    },
+    matchCondition: function (args, env) {
+        if (this.condition && !this.condition.eval({
+            frames: [this.evalParams(env, {frames: this.frames.concat(env.frames)}, args, [])].concat(env.frames)
+        }))                                                           { return false }
+        return true;
+    },
+    matchArgs: function (args, env) {
+        var argsLength = (args && args.length) || 0, len, frame;
+
+        if (! this.variadic) {
+            if (argsLength < this.required)                               { return false }
+            if (argsLength > this.params.length)                          { return false }
+            if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+        }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name && !this.params[i].variadic) {
+                if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    if (!a.operate) {
+        throw { name: "OperationError",
+                message: "Operation on an invalid type" };
+    }
+
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+    this.value = node;
+};
+tree.Paren.prototype = {
+    toCSS: function (env) {
+        return '(' + this.value.toCSS(env) + ')';
+    },
+    eval: function (env) {
+        return new(tree.Paren)(this.value.eval(env));
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return (v instanceof tree.Quoted) ? v.value : v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ratio = function (value) {
+    this.value = value;
+};
+tree.Ratio.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+    this.inline = inline || false;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + (this.inline ? "" : ";");
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name,
+                          this.value.eval(context),
+                          this.important,
+                          this.index, this.inline);
+};
+
+tree.Rule.prototype.makeImportant = function () {
+    return new(tree.Rule)(this.name,
+                          this.value,
+                          "!important",
+                          this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules, strictImports) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+    this.strictImports = strictImports;
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
+        var rules;
+        
+        ruleset.originalRuleset = this;
+        ruleset.root = this.root;
+        ruleset.allowImports = this.allowImports;
+
+        if(this.debugInfo) {
+            ruleset.debugInfo = this.debugInfo;
+        }
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
+            ruleset.evalImports(env);
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+        
+        var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0;
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                rules = ruleset.rules[i].eval(env);
+                ruleset.rules.splice.apply(ruleset.rules, [i, 1].concat(rules));
+                i += rules.length-1;
+                ruleset.resetCache();
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+        
+        if (env.mediaBlocks) {
+            for(var i = mediaBlockCount; i < env.mediaBlocks.length; i++) {
+                env.mediaBlocks[i].bubbleSelectors(selectors);
+            }
+        }
+
+        return ruleset;
+    },
+    evalImports: function(env) {
+        var i, rules;
+        for (i = 0; i < this.rules.length; i++) {
+            if (this.rules[i] instanceof tree.Import) {
+                rules = this.rules[i].eval(env);
+                if (typeof rules.length === "number") {
+                    this.rules.splice.apply(this.rules, [i, 1].concat(rules));
+                    i+= rules.length-1;
+                } else {
+                    this.rules.splice(i, 1, rules);
+                }
+                this.resetCache();
+            }
+        }
+    },
+    makeImportant: function() {
+        return new tree.Ruleset(this.selectors, this.rules.map(function (r) {
+                    if (r.makeImportant) {
+                        return r.makeImportant();
+                    } else {
+                        return r;
+                    }
+                }), this.strictImports);
+    },
+    matchArgs: function (args) {
+        return !args || args.length === 0;
+    },
+    resetCache: function () {
+        this._rulesets = null;
+        this._variables = null;
+        this._lookups = {};
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+           _rules = [],    //
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            debugInfo,     // Line number debugging
+            rule;
+
+        if (! this.root) {
+            this.joinSelectors(paths, context, this.selectors);
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Media)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Directive) {
+                var cssValue = rule.toCSS(paths, env);
+                // Output only the first @charset definition as such - convert the others
+                // to comments in case debug is enabled
+                if (rule.name === "@charset") {
+                    // Only output the debug info together with subsequent @charset definitions
+                    // a comment (or @media statement) before the actual @charset directive would
+                    // be considered illegal css as it has to be on the first line
+                    if (env.charset) {
+                        if (rule.debugInfo) {
+                            rulesets.push(tree.debugInfo(env, rule));
+                            rulesets.push(new tree.Comment("/* "+cssValue.replace(/\n/g, "")+" */\n").toCSS(env));
+                        }
+                        continue;
+                    }
+                    env.charset = true;
+                }
+                rulesets.push(cssValue);
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                debugInfo = tree.debugInfo(env, this);
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : ',\n');
+
+                // Remove duplicates
+                for (var i = rules.length - 1; i >= 0; i--) {
+                    if (_rules.indexOf(rules[i]) === -1) {
+                        _rules.unshift(rules[i]);
+                    }
+                }
+                rules = _rules;
+
+                css.push(debugInfo + selector + 
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('')  + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+
+        var i, j, k, 
+            hasParentSelector, newSelectors, el, sel, parentSel, 
+            newSelectorPath, afterParentJoin, newJoinedSelector, 
+            newJoinedSelectorEmpty, lastSelector, currentElements,
+            selectorsMultiplied;
+    
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.value === '&') {
+                hasParentSelector = true;
+            }
+        }
+    
+        if (!hasParentSelector) {
+            if (context.length > 0) {
+                for(i = 0; i < context.length; i++) {
+                    paths.push(context[i].concat(selector));
+                }
+            }
+            else {
+                paths.push([selector]);
+            }
+            return;
+        }
+
+        // The paths are [[Selector]]
+        // The first list is a list of comma seperated selectors
+        // The inner list is a list of inheritance seperated selectors
+        // e.g.
+        // .a, .b {
+        //   .c {
+        //   }
+        // }
+        // == [[.a] [.c]] [[.b] [.c]]
+        //
+
+        // the elements from the current selector so far
+        currentElements = [];
+        // the current list of new selectors to add to the path.
+        // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
+        // by the parents
+        newSelectors = [[]];
+
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            // non parent reference elements just get added
+            if (el.value !== "&") {
+                currentElements.push(el);
+            } else {
+                // the new list of selectors to add
+                selectorsMultiplied = [];
+
+                // merge the current list of non parent selector elements
+                // on to the current list of selectors to add
+                if (currentElements.length > 0) {
+                    this.mergeElementsOnToSelectors(currentElements, newSelectors);
+                }
+
+                // loop through our current selectors
+                for(j = 0; j < newSelectors.length; j++) {
+                    sel = newSelectors[j];
+                    // if we don't have any parent paths, the & might be in a mixin so that it can be used
+                    // whether there are parents or not
+                    if (context.length == 0) {
+                        // the combinator used on el should now be applied to the next element instead so that
+                        // it is not lost
+                        if (sel.length > 0) {
+                            sel[0].elements = sel[0].elements.slice(0);
+                            sel[0].elements.push(new(tree.Element)(el.combinator, '', 0)); //new Element(el.Combinator,  ""));
+                        }
+                        selectorsMultiplied.push(sel);
+                    }
+                    else {
+                        // and the parent selectors
+                        for(k = 0; k < context.length; k++) {
+                            parentSel = context[k];
+                            // We need to put the current selectors
+                            // then join the last selector's elements on to the parents selectors
+
+                            // our new selector path
+                            newSelectorPath = [];
+                            // selectors from the parent after the join
+                            afterParentJoin = [];
+                            newJoinedSelectorEmpty = true;
+
+                            //construct the joined selector - if & is the first thing this will be empty,
+                            // if not newJoinedSelector will be the last set of elements in the selector
+                            if (sel.length > 0) {
+                                newSelectorPath = sel.slice(0);
+                                lastSelector = newSelectorPath.pop();
+                                newJoinedSelector = new(tree.Selector)(lastSelector.elements.slice(0));
+                                newJoinedSelectorEmpty = false;
+                            }
+                            else {
+                                newJoinedSelector = new(tree.Selector)([]);
+                            }
+
+                            //put together the parent selectors after the join
+                            if (parentSel.length > 1) {
+                                afterParentJoin = afterParentJoin.concat(parentSel.slice(1));
+                            }
+
+                            if (parentSel.length > 0) {
+                                newJoinedSelectorEmpty = false;
+
+                                // join the elements so far with the first part of the parent
+                                newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, 0));
+                                newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1));
+                            }
+
+                            if (!newJoinedSelectorEmpty) {
+                                // now add the joined selector
+                                newSelectorPath.push(newJoinedSelector);
+                            }
+
+                            // and the rest of the parent
+                            newSelectorPath = newSelectorPath.concat(afterParentJoin);
+
+                            // add that to our new set of selectors
+                            selectorsMultiplied.push(newSelectorPath);
+                        }
+                    }
+                }
+
+                // our new selectors has been multiplied, so reset the state
+                newSelectors = selectorsMultiplied;
+                currentElements = [];
+            }
+        }
+
+        // if we have any elements left over (e.g. .a& .b == .b)
+        // add them on to all the current selectors
+        if (currentElements.length > 0) {
+            this.mergeElementsOnToSelectors(currentElements, newSelectors);
+        }
+
+        for(i = 0; i < newSelectors.length; i++) {
+            paths.push(newSelectors[i]);
+        }
+    },
+    
+    mergeElementsOnToSelectors: function(elements, selectors) {
+        var i, sel;
+
+        if (selectors.length == 0) {
+            selectors.push([ new(tree.Selector)(elements) ]);
+            return;
+        }
+
+        for(i = 0; i < selectors.length; i++) {
+            sel = selectors[i];
+
+            // if the previous thing in sel is a parent this needs to join on to it
+            if (sel.length > 0) {
+                sel[sel.length - 1] = new(tree.Selector)(sel[sel.length - 1].elements.concat(elements));
+            }
+            else {
+                sel.push(new(tree.Selector)(elements));
+            }
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+};
+tree.Selector.prototype.match = function (other) {
+    var elements = this.elements,
+        len = elements.length,
+        oelements, olen, max, i;
+
+    oelements = other.elements.slice(
+        (other.elements.length && other.elements[0].value === "&") ? 1 : 0);
+    olen = oelements.length;
+    max = Math.min(len, olen)
+
+    if (olen === 0 || len < olen) {
+        return false;
+    } else {
+        for (i = 0; i < max; i++) {
+            if (elements[i].value !== oelements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.eval = function (env) {
+    return new(tree.Selector)(this.elements.map(function (e) {
+        return e.eval(env);
+    }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+    
+    if (this.elements[0].combinator.value === "") {
+        this._css = ' ';
+    } else {
+        this._css = '';
+    }
+    
+    this._css += this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+    
+    return this._css;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.UnicodeDescriptor = function (value) {
+    this.value = value;
+};
+tree.UnicodeDescriptor.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, rootpath) {
+    this.value = val;
+    this.rootpath = rootpath;
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + this.value.toCSS() + ")";
+    },
+    eval: function (ctx) {
+        var val = this.value.eval(ctx), rootpath;
+
+        // Add the base path if the URL is relative
+        if (typeof val.value === "string" && !/^(?:[a-z-]+:|\/)/.test(val.value)) {
+            rootpath = this.rootpath;
+            if (!val.quote) {
+                rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; });
+            }
+            val.value = rootpath + val.value;
+        }
+
+        return new(tree.URL)(val, this.rootpath);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+        
+        if (this.evaluating) {
+            throw { type: 'Name',
+                    message: "Recursive variable definition for " + name,
+                    filename: this.file,
+                    index: this.index };
+        }
+        
+        this.evaluating = true;
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { 
+            this.evaluating = false;
+            return variable;
+        }
+        else {
+            throw { type: 'Name',
+                    message: "variable " + name + " is undefined",
+                    filename: this.file,
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.debugInfo = function(env, ctx) {
+    var result="";
+    if (env.dumpLineNumbers && !env.compress) {
+        switch(env.dumpLineNumbers) {
+            case 'comments':
+                result = tree.debugInfo.asComment(ctx);
+                break;
+            case 'mediaquery':
+                result = tree.debugInfo.asMediaQuery(ctx);
+                break;
+            case 'all':
+                result = tree.debugInfo.asComment(ctx)+tree.debugInfo.asMediaQuery(ctx);
+                break;
+        }
+    }
+    return result;
+};
+
+tree.debugInfo.asComment = function(ctx) {
+    return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
+};
+
+tree.debugInfo.asMediaQuery = function(ctx) {
+    return '@media -sass-debug-info{filename{font-family:' +
+        ('file://' + ctx.debugInfo.fileName).replace(/[\/:.]/g, '\\$&') +
+        '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n';
+};
+
+tree.find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+tree.jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = less.async || false;
+less.fileAsync = less.fileAsync || false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//Setup user functions
+if (less.functions) {
+    for(var func in less.functions) {
+        less.tree.functions[func] = less.functions[func];
+   }
+}
+
+var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);
+if (dumpLineNumbers) {
+    less.dumpLineNumbers = dumpLineNumbers[1];
+}
+
+//
+// Watch mode
+//
+less.watch   = function () {	
+	if (!less.watchMode ){		
+		less.env = 'development';
+		initRunningMode();
+	}
+	return this.watchMode = true 
+};
+
+less.unwatch = function () {clearInterval(less.watchTimer); return this.watchMode = false; };
+
+function initRunningMode(){
+	if (less.env === 'development') {		
+		less.optimization = 0;		
+		less.watchTimer = setInterval(function () {			
+			if (less.watchMode) {
+				loadStyleSheets(function (e, root, _, sheet, env) {
+					if (root) {
+						createCSS(root.toCSS(), sheet, env.lastModified);
+					}
+				});
+			}
+		}, less.poll);
+	} else {
+		less.optimization = 3;
+	}
+}
+
+if (/!watch/.test(location.hash)) {
+	less.watch();
+}
+
+var cache = null;
+
+if (less.env != 'development') {
+    try {
+        cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+    } catch (_) {}
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+//
+// With this function, it's possible to alter variables and re-render
+// CSS without reloading less-files
+//
+var session_cache = '';
+less.modifyVars = function(record) {
+	var str = session_cache;
+    for (name in record) {
+        str += ((name.slice(0,1) === '@')? '' : '@') + name +': '+ 
+                ((record[name].slice(-1) === ';')? record[name] : record[name] +';');
+    }
+    new(less.Parser)().parse(str, function (e, root) {
+        createCSS(root.toCSS(), less.sheets[less.sheets.length - 1]);
+    });
+};
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (e, root, _, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)({
+                filename: document.location.href.replace(/#.*$/, ''),
+                dumpLineNumbers: less.dumpLineNumbers
+            }).parse(styles[i].innerHTML || '', function (e, tree) {
+                var css = tree.toCSS();
+                var style = styles[i];
+                style.type = 'text/css';
+                if (style.styleSheet) {
+                    style.styleSheet.cssText = css;
+                } else {
+                    style.innerHTML = css;
+                }
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function pathDiff(url, baseUrl) {
+    // diff between two paths to create a relative path
+
+    var urlParts = extractUrlParts(url),
+        baseUrlParts = extractUrlParts(baseUrl),
+        i, max, urlDirectories, baseUrlDirectories, diff = "";
+    if (urlParts.hostPart !== baseUrlParts.hostPart) {
+        return "";
+    }
+    max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
+    for(i = 0; i < max; i++) {
+        if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }
+    }
+    baseUrlDirectories = baseUrlParts.directories.slice(i);
+    urlDirectories = urlParts.directories.slice(i);
+    for(i = 0; i < baseUrlDirectories.length-1; i++) {
+        diff += "../";
+    }
+    for(i = 0; i < urlDirectories.length-1; i++) {
+        diff += urlDirectories[i] + "/";
+    }
+    return diff;
+}
+
+function extractUrlParts(url, baseUrl) {
+    // urlParts[1] = protocol&hostname || /
+    // urlParts[2] = / if path relative to host base
+    // urlParts[3] = directories
+    // urlParts[4] = filename
+    // urlParts[5] = parameters
+
+    var urlPartsRegex = /^((?:[a-z-]+:)?\/\/(?:[^\/\?#]+\/)|([\/\\]))?((?:[^\/\\\?#]+[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/,
+        urlParts = url.match(urlPartsRegex),
+        returner = {}, directories = [], i, baseUrlParts;
+
+    if (!urlParts) {
+        throw new Error("Could not parse sheet href - '"+url+"'");
+    }
+
+    // Stylesheets in IE don't always return the full path    
+    if (!urlParts[1] || urlParts[2]) {
+        baseUrlParts = baseUrl.match(urlPartsRegex);
+        if (!baseUrlParts) {
+            throw new Error("Could not parse page url - '"+baseUrl+"'");
+        }
+        urlParts[1] = baseUrlParts[1];
+        if (!urlParts[2]) {
+            urlParts[3] = baseUrlParts[3] + urlParts[3];
+        }
+    }
+    
+    if (urlParts[3]) {
+        directories = urlParts[3].replace("\\", "/").split("/");
+
+        for(i = 0; i < directories.length; i++) {
+            if (directories[i] === ".." && i > 0) {
+                directories.splice(i-1, 2);
+                i -= 2;
+            }
+        }
+    }
+
+    returner.hostPart = urlParts[1];
+    returner.directories = directories;
+    returner.path = urlParts[1] + directories.join("/");
+    returner.fileUrl = returner.path + (urlParts[4] || "");
+    returner.url = returner.fileUrl + (urlParts[5] || "");
+    return returner;
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    // sheet may be set to the stylesheet for the initial load or a collection of properties including
+    // some env variables for imports
+    var contents  = sheet.contents || {};
+    var files     = sheet.files || {};
+    var hrefParts = extractUrlParts(sheet.href, window.location.href);
+    var href      = hrefParts.url;
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+    var rootpath;
+
+    if (less.relativeUrls) {
+        if (less.rootpath) {
+            if (sheet.entryPath) {
+                rootpath = extractUrlParts(less.rootpath + pathDiff(hrefParts.path, sheet.entryPath)).path;
+            } else {
+                rootpath = less.rootpath;
+            }
+        } else {
+            rootpath = hrefParts.path;
+        }
+    } else  {
+        if (less.rootpath) {
+            rootpath = less.rootpath;
+        } else {
+            if (sheet.entryPath) {
+                rootpath = sheet.entryPath;
+            } else {
+                rootpath = hrefParts.path;
+            }
+        }
+    }
+
+    xhr(href, sheet.type, function (data, lastModified) {
+        // Store data this session
+        session_cache += data.replace(/@import .+?;/ig, '');
+
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, null, data, sheet, { local: true, remaining: remaining }, href);
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                contents[href] = data;  // Updating top importing parser content cache
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [hrefParts.path],
+                    entryPath: sheet.entryPath || hrefParts.path,
+                    mime: sheet.type,
+                    filename: href,
+                    rootpath: rootpath,
+                    relativeUrls: sheet.relativeUrls,
+                    contents: contents,    // Passing top importing parser content cache ref down.
+                    files: files,
+                    dumpLineNumbers: less.dumpLineNumbers
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining }, href);
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\.[a-zA-Z]+$/,        '' )  // Remove simple extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href || '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        if( sheet.media ){ css.media = sheet.media; }
+        css.id = id;
+        var nextEl = sheet && sheet.nextSibling || null;
+        (nextEl || document.getElementsByTagName('head')[0]).parentNode.insertBefore(css, nextEl);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        try {
+            cache.setItem(href, styles);
+            cache.setItem(href + ':timestamp', lastModified);
+        } catch(e) {
+            //TODO - could do with adding more robust error handling
+            log('failed to save');
+        }
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? less.fileAsync : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol && !less.fileAsync) {
+        if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+    var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+    var elem = document.createElement('div'), timer, content, error = [];
+    var filename = e.filename || href;
+    var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1];
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p>in <a href="' + filename   + '">' + filenameNoPath + "</a> ";
+
+    var errorline = function (e, i, classname) {
+        if (e.extract[i]) {
+            error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+                               .replace(/\{class\}/, classname)
+                               .replace(/\{content\}/, e.extract[i]));
+        }
+    };
+
+    if (e.stack) {
+        content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+    } else if (e.extract) {
+        errorline(e, 0, '');
+        errorline(e, 1, 'line');
+        errorline(e, 2, '');
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+                    '<ul>' + error.join('') + '</ul>';
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #dd6666;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.line {',
+            'color: #ff0000;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+// amd.js
+//
+// Define Less as an AMD module.
+if (typeof define === "function" && define.amd) {
+    define("less", [], function () { return less; } );
+}
+})(window);
diff --git a/util/less/dist/less-1.3.2.min.js b/util/less/dist/less-1.3.2.min.js
new file mode 100644
index 0000000..5985526
--- /dev/null
+++ b/util/less/dist/less-1.3.2.min.js
@@ -0,0 +1,9 @@
+//
+// LESS - Leaner CSS v1.3.2
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(e,t){function n(t){return e.less[t.split("/")[1]]}function f(){r.env==="development"?(r.optimization=0,r.watchTimer=setInterval(function(){r.watchMode&&g(function(e,t,n,r,i){t&&S(t.toCSS(),r,i.lastModified)})},r.poll)):r.optimization=3}function m(){var e=document.getElementsByTagName("style");for(var t=0;t<e.length;t++)e[t].type.match(p)&&(new r.Parser({filename:document.location.href.replace(/#.*$/,""),dumpLineNumbers:r.dumpLineNumbers})).parse(e[t].innerHTML||"",function(n,r) [...]
+n("./tree")),function(e){e.Alpha=function(e){this.value=e},e.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(e){return this.value.eval&&(this.value=this.value.eval(e)),this}}}(n("../tree")),function(e){e.Anonymous=function(e){this.value=e.value||e},e.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this},compare:function(e){if(!e.toCSS)return-1;var t=this.toCSS(),n=e.toCSS();return [...]
\ No newline at end of file
diff --git a/util/less/dist/less-1.3.3.js b/util/less/dist/less-1.3.3.js
new file mode 100644
index 0000000..2bc53c7
--- /dev/null
+++ b/util/less/dist/less-1.3.3.js
@@ -0,0 +1,4413 @@
+//
+// LESS - Leaner CSS v1.3.3
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function (window, undefined) {
+//
+// Stub out `require` in the browser
+//
+function require(arg) {
+    return window.less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree, charset;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    if (typeof(window) === 'undefined') { less = {} }
+    else                                { less = window.less = {} }
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // Top parser on an import tree must be sure there is one "env"
+    // which will then be passed arround by reference.
+    var env = env || { };
+    // env.contents and files must be passed arround with top env
+    if (!env.contents) { env.contents = {}; }
+    env.rootpath = env.rootpath || '';       // env.rootpath must be initialized to '' if not provided
+    if (!env.files) { env.files = {}; }
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env.paths || [],  // Search paths, when importing
+        queue: [],               // Files which haven't been imported yet
+        files: env.files,        // Holds the imported parse trees
+        contents: env.contents,  // Holds the imported file contents
+        mime:  env.mime,         // MIME type of .less files
+        error: null,             // Error in parsing/evaluating an import
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (e, root, fullPath) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+
+                var imported = fullPath in that.files;
+
+                that.files[fullPath] = root;                        // Store the root
+
+                if (e && !that.error) { that.error = e }
+
+                callback(e, root, imported);
+
+                if (that.queue.length === 0) { finish(that.error) }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    function isWhitespace(c) {
+        // Could change to \s?
+        var code = c.charCodeAt(0);
+        return code === 32 || code === 10 || code === 9;
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, index, k;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            skipWhitespace(length);
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    function skipWhitespace(length) {
+        var oldi = i, oldj = j,
+            endIndex = i + chunks[j].length,
+            mem = i += length;
+
+        while (i < endIndex) {
+            if (! isWhitespace(input.charAt(i))) { break }
+            i++;
+        }
+        chunks[j] = chunks[j].slice(length + (i - mem));
+        current = i;
+
+        if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+        return oldi !== i || oldj !== j;
+    }
+
+    function expect(arg, msg) {
+        var result = $(arg);
+        if (! result) {
+            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+                                                   : "unexpected token"));
+        } else {
+            return result;
+        }
+    }
+
+    function error(msg, type) {
+        var e = new Error(msg);
+        e.index = i;
+        e.type = type || 'Syntax';
+        throw e;
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    function getInput(e, env) {
+        if (e.filename && env.filename && (e.filename !== env.filename)) {
+            return parser.imports.contents[e.filename];
+        } else {
+            return input;
+        }
+    }
+
+    function getLocation(index, input) {
+        for (var n = index, column = -1;
+                 n >= 0 && input.charAt(n) !== '\n';
+                 n--) { column++ }
+
+        return { line:   typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+                 column: column };
+    }
+
+    function getFileName(e) {
+        if(less.mode === 'browser' || less.mode === 'rhino')
+            return e.filename;
+        else
+            return require('path').resolve(e.filename);
+    }
+
+    function getDebugInfo(index, inputStream, e) {
+        return {
+            lineNumber: getLocation(index, inputStream).line + 1,
+            fileName: getFileName(e)
+        };
+    }
+
+    function LessError(e, env) {
+        var input = getInput(e, env),
+            loc = getLocation(e.index, input),
+            line = loc.line,
+            col  = loc.column,
+            lines = input.split('\n');
+
+        this.type = e.type || 'Syntax';
+        this.message = e.message;
+        this.filename = e.filename || env.filename;
+        this.index = e.index;
+        this.line = typeof(line) === 'number' ? line + 1 : null;
+        this.callLine = e.call && (getLocation(e.call, input).line + 1);
+        this.callExtract = lines[getLocation(e.call, input).line];
+        this.stack = e.stack;
+        this.column = col;
+        this.extract = [
+            lines[line - 1],
+            lines[line],
+            lines[line + 1]
+        ];
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            input = str.replace(/\r\n/g, '\n');
+
+            // Remove potential UTF Byte Order Mark
+            input = input.replace(/^\uFEFF/, '');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam;
+
+                for (var i = 0, c, cc; i < input.length;) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = string.lastIndex = i;
+
+                    if (match = string.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                            continue;
+                        }
+                    }
+
+                    if (!inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    continue;
+                                }
+                            }
+                        }
+                    }
+                    
+                    switch (c) {
+                        case '{': if (! inParam) { level ++;        chunk.push(c);                           break }
+                        case '}': if (! inParam) { level --;        chunk.push(c); chunks[++j] = chunk = []; break }
+                        case '(': if (! inParam) { inParam = true;  chunk.push(c);                           break }
+                        case ')': if (  inParam) { inParam = false; chunk.push(c);                           break }
+                        default:                                    chunk.push(c);
+                    }
+                    
+                    i++;
+                }
+                if (level != 0) {
+                    error = new(LessError)({
+                        index: i-1,
+                        type: 'Parse',
+                        message: (level > 0) ? "missing closing `}`" : "missing opening `{`",
+                        filename: env.filename
+                    }, env);
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            if (error) {
+                return callback(error, env);
+            }
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            try {
+                root = new(tree.Ruleset)([], $(this.parsers.primary));
+                root.root = true;
+            } catch (e) {
+                return callback(new(LessError)(e, env));
+            }
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [], importError;
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false, dumpLineNumbers: env.dumpLineNumbers });
+                    } catch (e) {
+                        throw new(LessError)(e, env);
+                    }
+
+                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
+                        if (importError instanceof LessError) throw importError;
+                        else                                  throw new(LessError)(importError, env);
+                    }
+
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('ycssmin').cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    type: "Parse",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function (e) {
+                    e = error || e;
+                    if (e) callback(e);
+                    else callback(null, root);
+                };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/) || $(/^;+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k);
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, nameLC, args, alpha_ret, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1];
+                    nameLC = name.toLowerCase();
+
+                    if (nameLC === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (nameLC === 'alpha') {
+                        alpha_ret = $(this.alpha);
+                        if(typeof alpha_ret !== 'undefined') {
+                            return alpha_ret;
+                        }
+                    }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index, env.filename) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.ratio) ||
+                           $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted) ||
+                           $(this.entities.unicodeDescriptor);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || "";
+
+                    expect(')');
+
+                    return new(tree.URL)((value.value != null || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), env.rootpath);
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index, env.filename);
+                    }
+                },
+
+                // A variable entity useing the protective {} e.g. @{var}
+                variableCurly: function () {
+                    var name, curly, index = i;
+
+                    if (input.charAt(i) === '@' && (curly = $(/^@\{([\w-]+)\}/))) {
+                        return new(tree.Variable)("@" + curly[1], index, env.filename);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    //Is the first char of the dimension 0-9, '.', '+' or '-'
+                    if ((c > 57 || c < 43) || c === 47 || c == 44) return;
+
+                    if (value = $(/^([+-]?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn|dpi|dpcm|dppx|rem|vw|vh|vmin|vm|ch)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // A Ratio
+                //
+                //    16/9
+                //
+                ratio: function () {
+                  var value, c = input.charCodeAt(i);
+                  if (c > 57 || c < 48) return;
+
+                  if (value = $(/^(\d+\/\d+)/)) {
+                    return new(tree.Ratio)(value[1]);
+                  }
+                },
+                
+                //
+                // A unicode descriptor, as is used in unicode-range
+                //
+                // U+0??  or U+00A1-00A9
+                //
+                unicodeDescriptor: function () {
+                    var ud;
+                    
+                    if (ud = $(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/)) {
+                        return new(tree.UnicodeDescriptor)(ud[0]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                save();
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+
+                restore();
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, argsSemiColon = [], argsComma = [], args, delim, arg, nameLoop, expressions, isSemiColonSeperated, expressionContainsNamed, index = i, s = input.charAt(i), name, value, important = false;
+
+                    if (s !== '.' && s !== '#') { return }
+                    
+                    save(); // stop us absorbing part of an invalid selector
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    if ($('(')) {
+                        expressions = [];
+                        while (arg = $(this.expression)) {
+                            nameLoop = null;
+                            value = arg;
+
+                            // Variable
+                            if (arg.value.length == 1) {
+                                var val = arg.value[0];
+                                if (val instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        if (expressions.length > 0) {
+                                            if (isSemiColonSeperated) {
+                                                error("Cannot mix ; and , as delimiter types");
+                                            }
+                                            expressionContainsNamed = true;
+                                        }
+                                        value = expect(this.expression);
+                                        nameLoop = (name = val.name);
+                                    }
+                                }
+                            }
+                            
+                            expressions.push(value);
+                            
+                            argsComma.push({ name: nameLoop, value: value });
+                            
+                            if ($(',')) {
+                                continue;
+                            }
+                            
+                            if ($(';') || isSemiColonSeperated) {
+                            
+                                if (expressionContainsNamed) {
+                                    error("Cannot mix ; and , as delimiter types");
+                                }
+                            
+                                isSemiColonSeperated = true;
+                                                        
+                                if (expressions.length > 1) {
+                                    value = new(tree.Value)(expressions);
+                                }
+                                argsSemiColon.push({ name: name, value: value });
+                            
+                                name = null;
+                                expressions = [];
+                                expressionContainsNamed = false;
+                            }
+                        }
+
+                        expect(')');
+                    }
+
+                    args = isSemiColonSeperated ? argsSemiColon : argsComma;
+
+                    if ($(this.important)) {
+                        important = true;
+                    }
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+                    }
+                    
+                    restore();
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value, cond, variadic = false;
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*\}/)) return;
+
+                    save();
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        do {
+                            $(this.comment);
+                            if (input.charAt(i) === '.' && $(/^\.{3}/)) {
+                                variadic = true;
+                                params.push({ variadic: true });
+                                break;
+                            } else if (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                         || $(this.entities.keyword)) {
+                                // Variable
+                                if (param instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        value = expect(this.expression, 'expected expression');
+                                        params.push({ name: param.name, value: value });
+                                    } else if ($(/^\.{3}/)) {
+                                        params.push({ name: param.name, variadic: true });
+                                        variadic = true;
+                                        break;
+                                    } else {
+                                        params.push({ name: param.name });
+                                    }
+                                } else {
+                                    params.push({ value: param });
+                                }
+                            } else {
+                                break;
+                            }
+                        } while ($(',') || $(';'))
+
+                        // .mixincall("@{a}"); 
+                        // looks a bit like a mixin definition.. so we have to be nice and restore
+                        if (!$(')')) {
+                            furthest = i;
+                            restore();
+                        }
+                        
+                        $(this.comment);
+
+                        if ($(/^when/)) { // Guard
+                            cond = expect(this.conditions, 'expected condition');
+                        }
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
+                        } else {
+                            restore();
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  ||$(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    expect(')');
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c, v;
+
+                c = $(this.combinator);
+
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
+                    $('*') || $('&') || $(this.attribute) || $(/^\([^()@]+\)/) || $(/^[\.#](?=@)/) || $(this.entities.variableCurly);
+
+                if (! e) {
+                    if ($('(')) {
+                        if ((v = ($(this.entities.variableCurly) || 
+                                $(this.entities.variable) || 
+                                $(this.selector))) && 
+                                $(')')) {
+                            e = new(tree.Paren)(v);
+                        }
+                    }
+                }
+
+                if (e) { return new(tree.Element)(c, e, i) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~' || c === '|') {
+                    i++;
+                    while (input.charAt(i).match(/\s/)) { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (input.charAt(i - 1).match(/\s/)) {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                // depreciated, will be removed soon
+                if ($('(')) {
+                    sel = $(this.entity);
+                    if (!$(')')) { return null; }
+                    return new(tree.Selector)([new(tree.Element)('', sel, i)]);
+                }
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^(?:[_A-Za-z0-9-]|\\.)+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match, debugInfo;
+                
+                save();
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports);
+                    if (env.dumpLineNumbers)
+                        ruleset.debugInfo = debugInfo;
+                    return ruleset;
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path, features, index = i;
+                
+                save();
+                
+                var dir = $(/^@import(?:-(once))?\s+/);
+
+                if (dir && (path = $(this.entities.quoted) || $(this.entities.url))) {
+                    features = $(this.mediaFeatures);
+                    if ($(';')) {
+                        return new(tree.Import)(path, imports, features, (dir[1] === 'once'), index, env.rootpath);
+                    }
+                }
+                
+                restore();
+            },
+
+            mediaFeature: function () {
+                var e, p, nodes = [];
+
+                do {
+                    if (e = $(this.entities.keyword)) {
+                        nodes.push(e);
+                    } else if ($('(')) {
+                        p = $(this.property);
+                        e = $(this.entity);
+                        if ($(')')) {
+                            if (p && e) {
+                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+                            } else if (e) {
+                                nodes.push(new(tree.Paren)(e));
+                            } else {
+                                return null;
+                            }
+                        } else { return null }
+                    }
+                } while (e);
+
+                if (nodes.length > 0) {
+                    return new(tree.Expression)(nodes);
+                }
+            },
+
+            mediaFeatures: function () {
+                var e, features = [];
+
+                do {
+                  if (e = $(this.mediaFeature)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  } else if (e = $(this.entities.variable)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  }
+                } while (e);
+
+                return features.length > 0 ? features : null;
+            },
+
+            media: function () {
+                var features, rules, media, debugInfo;
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                if ($(/^@media/)) {
+                    features = $(this.mediaFeatures);
+
+                    if (rules = $(this.block)) {
+                        media = new(tree.Media)(rules, features);
+                        if(env.dumpLineNumbers)
+                            media.debugInfo = debugInfo;
+                        return media;
+                    }
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, identifier, e, nodes, nonVendorSpecificName,
+                    hasBlock, hasIdentifier, hasExpression;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import']) || $(this.media)) {
+                    return value;
+                }
+                
+                save();
+
+                name = $(/^@[a-z-]+/);
+                
+                if (!name) return;
+
+                nonVendorSpecificName = name;
+                if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
+                    nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
+                }
+
+                switch(nonVendorSpecificName) {
+                    case "@font-face":
+                        hasBlock = true;
+                        break;
+                    case "@viewport":
+                    case "@top-left":
+                    case "@top-left-corner":
+                    case "@top-center":
+                    case "@top-right":
+                    case "@top-right-corner":
+                    case "@bottom-left":
+                    case "@bottom-left-corner":
+                    case "@bottom-center":
+                    case "@bottom-right":
+                    case "@bottom-right-corner":
+                    case "@left-top":
+                    case "@left-middle":
+                    case "@left-bottom":
+                    case "@right-top":
+                    case "@right-middle":
+                    case "@right-bottom":
+                        hasBlock = true;
+                        break;
+                    case "@page":
+                    case "@document":
+                    case "@supports":
+                    case "@keyframes":
+                        hasBlock = true;
+                        hasIdentifier = true;
+                        break;
+                    case "@namespace":
+                        hasExpression = true;
+                        break;
+                }
+
+                if (hasIdentifier) {
+                    name += " " + ($(/^[^{]+/) || '').trim();
+                }
+
+                if (hasBlock)
+                {
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name, rules);
+                    }
+                } else {
+                    if ((value = hasExpression ? $(this.expression) : $(this.entity)) && $(';')) {
+                        var directive = new(tree.Directive)(name, value);
+                        if (env.dumpLineNumbers) {
+                            directive.debugInfo = getDebugInfo(i, input, env);
+                        }
+                        return directive;
+                    }
+                }
+                
+                restore();
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/[*\/]/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (!isWhitespace(input.charAt(i - 1)) && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            conditions: function () {
+                var a, b, index = i, condition;
+
+                if (a = $(this.condition)) {
+                    while ($(',') && (b = $(this.condition))) {
+                        condition = new(tree.Condition)('or', condition || a, b, index);
+                    }
+                    return condition || a;
+                }
+            },
+            condition: function () {
+                var a, b, c, op, index = i, negate = false;
+
+                if ($(/^not/)) { negate = true }
+                expect('(');
+                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                    if (op = $(/^(?:>=|=<|[<=>])/)) {
+                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                            c = new(tree.Condition)(op, a, b, index, negate);
+                        } else {
+                            error('expected expression');
+                        }
+                    } else {
+                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+                    }
+                    expect(')');
+                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[_a-z0-9-]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (!/^([a-z-]+:)?\//.test(path) && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ 
+            href: path, 
+            title: path, 
+            type: env.mime, 
+            contents: env.contents, 
+            files: env.files, 
+            rootpath: env.rootpath,
+            entryPath: env.entryPath,
+            relativeUrls: env.relativeUrls }, 
+        function (e, root, data, sheet, _, path) {
+            if (e && typeof(env.errback) === "function") {
+                env.errback.call(null, path, paths, callback, env);
+            } else {
+                callback.call(null, e, root, path);
+            }
+        }, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return scaled(c, 256); });
+        a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+
+    hsv: function(h, s, v) {
+        return this.hsva(h, s, v, 1.0);
+    },
+
+    hsva: function(h, s, v, a) {
+        h = ((number(h) % 360) / 360) * 360;
+        s = number(s); v = number(v); a = number(a);
+
+        var i, f;
+        i = Math.floor((h / 60) % 6);
+        f = (h / 60) - i;
+
+        var vs = [v,
+                  v * (1 - s),
+                  v * (1 - f * s),
+                  v * (1 - (1 - f) * s)];
+        var perm = [[0, 3, 1],
+                    [2, 0, 1],
+                    [1, 0, 3],
+                    [1, 2, 0],
+                    [3, 1, 0],
+                    [0, 1, 2]];
+
+        return this.rgba(vs[perm[i][0]] * 255,
+                         vs[perm[i][1]] * 255,
+                         vs[perm[i][2]] * 255,
+                         a);
+    },
+
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    red: function (color) {
+        return new(tree.Dimension)(color.rgb[0]);
+    },
+    green: function (color) {
+        return new(tree.Dimension)(color.rgb[1]);
+    },
+    blue: function (color) {
+        return new(tree.Dimension)(color.rgb[2]);
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    luma: function (color) {
+        return new(tree.Dimension)(Math.round((0.2126 * (color.rgb[0]/255) +
+            0.7152 * (color.rgb[1]/255) +
+            0.0722 * (color.rgb[2]/255)) *
+            color.alpha * 100), '%');
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        if (!weight) {
+            weight = new(tree.Dimension)(50);
+        }
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    contrast: function (color, dark, light, threshold) {
+        // filter: contrast(3.2);
+        // should be kept as is, so check for color
+        if (!color.rgb) {
+            return null;
+        }
+        if (typeof light === 'undefined') {
+            light = this.rgba(255, 255, 255, 1.0);
+        }
+        if (typeof dark === 'undefined') {
+            dark = this.rgba(0, 0, 0, 1.0);
+        }
+        if (typeof threshold === 'undefined') {
+            threshold = 0.43;
+        } else {
+            threshold = threshold.value;
+        }
+        if (((0.2126 * (color.rgb[0]/255) + 0.7152 * (color.rgb[1]/255) + 0.0722 * (color.rgb[2]/255)) * color.alpha) < threshold) {
+            return light;
+        } else {
+            return dark;
+        }
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    unit: function (val, unit) {
+        return new(tree.Dimension)(val.value, unit ? unit.toCSS() : "");
+    },
+    round: function (n, f) {
+        var fraction = typeof(f) === "undefined" ? 0 : f.value;
+        return this._math(function(num) { return num.toFixed(fraction); }, n);
+    },
+    ceil: function (n) {
+        return this._math(Math.ceil, n);
+    },
+    floor: function (n) {
+        return this._math(Math.floor, n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(fn(parseFloat(n.value)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return fn(n);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    },
+    percentage: function (n) {
+        return new(tree.Dimension)(n.value * 100, '%');
+    },
+    color: function (n) {
+        if (n instanceof tree.Quoted) {
+            return new(tree.Color)(n.value.slice(1));
+        } else {
+            throw { type: "Argument", message: "argument must be a string" };
+        }
+    },
+    iscolor: function (n) {
+        return this._isa(n, tree.Color);
+    },
+    isnumber: function (n) {
+        return this._isa(n, tree.Dimension);
+    },
+    isstring: function (n) {
+        return this._isa(n, tree.Quoted);
+    },
+    iskeyword: function (n) {
+        return this._isa(n, tree.Keyword);
+    },
+    isurl: function (n) {
+        return this._isa(n, tree.URL);
+    },
+    ispixel: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+    },
+    ispercentage: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+    },
+    isem: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+    },
+    _isa: function (n, Type) {
+        return (n instanceof Type) ? tree.True : tree.False;
+    },
+    
+    /* Blending modes */
+    
+    multiply: function(color1, color2) {
+        var r = color1.rgb[0] * color2.rgb[0] / 255;
+        var g = color1.rgb[1] * color2.rgb[1] / 255;
+        var b = color1.rgb[2] * color2.rgb[2] / 255;
+        return this.rgb(r, g, b);
+    },
+    screen: function(color1, color2) {
+        var r = 255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = 255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = 255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    overlay: function(color1, color2) {
+        var r = color1.rgb[0] < 128 ? 2 * color1.rgb[0] * color2.rgb[0] / 255 : 255 - 2 * (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = color1.rgb[1] < 128 ? 2 * color1.rgb[1] * color2.rgb[1] / 255 : 255 - 2 * (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = color1.rgb[2] < 128 ? 2 * color1.rgb[2] * color2.rgb[2] / 255 : 255 - 2 * (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    softlight: function(color1, color2) {
+        var t = color2.rgb[0] * color1.rgb[0] / 255;
+        var r = t + color1.rgb[0] * (255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255 - t) / 255;
+        t = color2.rgb[1] * color1.rgb[1] / 255;
+        var g = t + color1.rgb[1] * (255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255 - t) / 255;
+        t = color2.rgb[2] * color1.rgb[2] / 255;
+        var b = t + color1.rgb[2] * (255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255 - t) / 255;
+        return this.rgb(r, g, b);
+    },
+    hardlight: function(color1, color2) {
+        var r = color2.rgb[0] < 128 ? 2 * color2.rgb[0] * color1.rgb[0] / 255 : 255 - 2 * (255 - color2.rgb[0]) * (255 - color1.rgb[0]) / 255;
+        var g = color2.rgb[1] < 128 ? 2 * color2.rgb[1] * color1.rgb[1] / 255 : 255 - 2 * (255 - color2.rgb[1]) * (255 - color1.rgb[1]) / 255;
+        var b = color2.rgb[2] < 128 ? 2 * color2.rgb[2] * color1.rgb[2] / 255 : 255 - 2 * (255 - color2.rgb[2]) * (255 - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    difference: function(color1, color2) {
+        var r = Math.abs(color1.rgb[0] - color2.rgb[0]);
+        var g = Math.abs(color1.rgb[1] - color2.rgb[1]);
+        var b = Math.abs(color1.rgb[2] - color2.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    exclusion: function(color1, color2) {
+        var r = color1.rgb[0] + color2.rgb[0] * (255 - color1.rgb[0] - color1.rgb[0]) / 255;
+        var g = color1.rgb[1] + color2.rgb[1] * (255 - color1.rgb[1] - color1.rgb[1]) / 255;
+        var b = color1.rgb[2] + color2.rgb[2] * (255 - color1.rgb[2] - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    average: function(color1, color2) {
+        var r = (color1.rgb[0] + color2.rgb[0]) / 2;
+        var g = (color1.rgb[1] + color2.rgb[1]) / 2;
+        var b = (color1.rgb[2] + color2.rgb[2]) / 2;
+        return this.rgb(r, g, b);
+    },
+    negation: function(color1, color2) {
+        var r = 255 - Math.abs(255 - color2.rgb[0] - color1.rgb[0]);
+        var g = 255 - Math.abs(255 - color2.rgb[1] - color1.rgb[1]);
+        var b = 255 - Math.abs(255 - color2.rgb[2] - color1.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    tint: function(color, amount) {
+        return this.mix(this.rgb(255,255,255), color, amount);
+    },
+    shade: function(color, amount) {
+        return this.mix(this.rgb(0, 0, 0), color, amount);
+    }
+};
+
+function hsla(color) {
+    return tree.functions.hsla(color.h, color.s, color.l, color.a);
+}
+
+function scaled(n, size) {
+    if (n instanceof tree.Dimension && n.unit == '%') {
+        return parseFloat(n.value * size / 100);
+    } else {
+        return number(n);
+    }
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        // 'transparent':'rgba(0,0,0,0)',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) {
+            return new(tree.Assignment)(this.key, this.value.eval(env));
+        }
+        return this;
+    }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+    this.filename = filename;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // if this returns null or we cannot find the function, we 
+    // simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) }),
+            result;
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                result = tree.functions[this.name].apply(tree.functions, args);
+                if (result != null) {
+                    return result;
+                }
+            } catch (e) {
+                throw { type: e.type || "Runtime",
+                        message: "error evaluating function `" + this.name + "`" +
+                                 (e.message ? ': ' + e.message : ''),
+                        index: this.index, filename: this.filename };
+            }
+        }
+        
+        // 2.
+        return new(tree.Anonymous)(this.name +
+            "(" + args.map(function (a) { return a.toCSS(env) }).join(', ') + ")");
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    },
+    compare: function (x) {
+        if (!x.rgb) {
+            return -1;
+        }
+        
+        return (x.rgb[0] === this.rgb[0] &&
+            x.rgb[1] === this.rgb[1] &&
+            x.rgb[2] === this.rgb[2] &&
+            x.alpha === this.alpha) ? 0 : -1;
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+    this.op = op.trim();
+    this.lvalue = l;
+    this.rvalue = r;
+    this.index = i;
+    this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+    var a = this.lvalue.eval(env),
+        b = this.rvalue.eval(env);
+
+    var i = this.index, result;
+
+    var result = (function (op) {
+        switch (op) {
+            case 'and':
+                return a && b;
+            case 'or':
+                return a || b;
+            default:
+                if (a.compare) {
+                    result = a.compare(b);
+                } else if (b.compare) {
+                    result = b.compare(a);
+                } else {
+                    throw { type: "Type",
+                            message: "Unable to perform comparison",
+                            index: i };
+                }
+                switch (result) {
+                    case -1: return op === '<' || op === '=<';
+                    case  0: return op === '=' || op === '>=' || op === '=<';
+                    case  1: return op === '>' || op === '>=';
+                }
+        }
+    })(this.op);
+    return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    },
+
+    compare: function (other) {
+        if (other instanceof tree.Dimension) {
+            if (other.value > this.value) {
+                return -1;
+            } else if (other.value < this.value) {
+                return 1;
+            } else {
+                if (other.unit && this.unit !== other.unit) {
+                    return -1;
+                }
+                return 0;
+            }
+        } else {
+            return -1;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+        this.ruleset.allowImports = true;
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        var evaldDirective = this;
+        if (this.ruleset) {
+            env.frames.unshift(this);
+            evaldDirective = new(tree.Directive)(this.name);
+            evaldDirective.ruleset = this.ruleset.eval(env);
+            env.frames.shift();
+        }
+        return evaldDirective;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+
+    if (typeof(value) === 'string') {
+        this.value = value.trim();
+    } else if (value) {
+        this.value = value;
+    } else {
+        this.value = "";
+    }
+    this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+    return new(tree.Element)(this.combinator,
+                             this.value.eval ? this.value.eval(env) : this.value,
+                             this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+	var value = (this.value.toCSS ? this.value.toCSS(env) : this.value);
+	if (value == '' && this.combinator.value.charAt(0) == '&') {
+		return '';
+	} else {
+		return this.combinator.toCSS(env || {}) + value;
+	}
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        ':' : ' :',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > ',
+        '|' : env.compress ? '|' : ' | '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS ? e.toCSS(env) : '';
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, once, index, rootpath) {
+    var that = this;
+
+    this.once = once;
+    this.index = index;
+    this._path = path;
+    this.features = features && new(tree.Value)(features);
+    this.rootpath = rootpath;
+		
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /(\.[a-z]*$)|([\?;].*)$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css([\?;].*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (e, root, imported) {
+            if (e) { e.index = index }
+            if (imported && that.once) that.skip = imported;
+            that.root = root || new(tree.Ruleset)([], []);
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function (env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.css) {
+            // Add the base path if the import is relative
+            if (typeof this._path.value === "string" && !/^(?:[a-z-]+:|\/)/.test(this._path.value)) {
+                this._path.value = this.rootpath + this._path.value;
+            }
+            return "@import " + this._path.toCSS() + features + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset, features = this.features && this.features.eval(env);
+
+        if (this.skip) return [];
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+            ruleset.evalImports(env);
+
+            return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value },
+    compare: function (other) {
+        if (other instanceof tree.Keyword) {
+            return other.value === this.value ? 0 : 1;
+        } else {
+            return -1;
+        }
+    }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Media = function (value, features) {
+    var selectors = this.emptySelectors();
+
+    this.features = new(tree.Value)(features);
+    this.ruleset = new(tree.Ruleset)(selectors, value);
+    this.ruleset.allowImports = true;
+};
+tree.Media.prototype = {
+    toCSS: function (ctx, env) {
+        var features = this.features.toCSS(env);
+
+        this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
+        return '@media ' + features + (env.compress ? '{' : ' {\n  ') +
+               this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                           (env.compress ? '}': '\n}\n');
+    },
+    eval: function (env) {
+        if (!env.mediaBlocks) {
+            env.mediaBlocks = [];
+            env.mediaPath = [];
+        }
+        
+        var media = new(tree.Media)([], []);
+        if(this.debugInfo) {
+            this.ruleset.debugInfo = this.debugInfo;
+            media.debugInfo = this.debugInfo;
+        }
+        media.features = this.features.eval(env);
+        
+        env.mediaPath.push(media);
+        env.mediaBlocks.push(media);
+        
+        env.frames.unshift(this.ruleset);
+        media.ruleset = this.ruleset.eval(env);
+        env.frames.shift();
+        
+        env.mediaPath.pop();
+
+        return env.mediaPath.length === 0 ? media.evalTop(env) :
+                    media.evalNested(env)
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
+    emptySelectors: function() { 
+        var el = new(tree.Element)('', '&', 0);
+        return [new(tree.Selector)([el])];
+    },
+
+    evalTop: function (env) {
+        var result = this;
+
+        // Render all dependent Media blocks.
+        if (env.mediaBlocks.length > 1) {
+            var selectors = this.emptySelectors();
+            result = new(tree.Ruleset)(selectors, env.mediaBlocks);
+            result.multiMedia = true;
+        }
+
+        delete env.mediaBlocks;
+        delete env.mediaPath;
+
+        return result;
+    },
+    evalNested: function (env) {
+        var i, value,
+            path = env.mediaPath.concat([this]);
+
+        // Extract the media-query conditions separated with `,` (OR).
+        for (i = 0; i < path.length; i++) {
+            value = path[i].features instanceof tree.Value ?
+                        path[i].features.value : path[i].features;
+            path[i] = Array.isArray(value) ? value : [value];
+        }
+
+        // Trace all permutations to generate the resulting media-query.
+        //
+        // (a, b and c) with nested (d, e) ->
+        //    a and d
+        //    a and e
+        //    b and c and d
+        //    b and c and e
+        this.features = new(tree.Value)(this.permute(path).map(function (path) {
+            path = path.map(function (fragment) {
+                return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
+            });
+
+            for(i = path.length - 1; i > 0; i--) {
+                path.splice(i, 0, new(tree.Anonymous)("and"));
+            }
+
+            return new(tree.Expression)(path);
+        }));
+
+        // Fake a tree-node that doesn't output anything.
+        return new(tree.Ruleset)([], []);
+    },
+    permute: function (arr) {
+      if (arr.length === 0) {
+          return [];
+      } else if (arr.length === 1) {
+          return arr[0];
+      } else {
+          var result = [];
+          var rest = this.permute(arr.slice(1));
+          for (var i = 0; i < rest.length; i++) {
+              for (var j = 0; j < arr[0].length; j++) {
+                  result.push([arr[0][j]].concat(rest[i]));
+              }
+          }
+          return result;
+      }
+    },
+    bubbleSelectors: function (selectors) {
+      this.ruleset = new(tree.Ruleset)(selectors.slice(0), [this.ruleset]);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+    this.filename = filename;
+    this.important = important;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound;
+
+        args = this.arguments && this.arguments.map(function (a) {
+            return { name: a.name, value: a.value.eval(env) };
+        });
+
+        for (i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                isOneFound = true;
+                for (m = 0; m < mixins.length; m++) {
+                    mixin = mixins[m];
+                    isRecursive = false;
+                    for(f = 0; f < env.frames.length; f++) {
+                        if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) {
+                            isRecursive = true;
+                            break;
+                        }
+                    }
+                    if (isRecursive) {
+                        continue;
+                    }
+                    if (mixin.matchArgs(args, env)) {
+                        if (!mixin.matchCondition || mixin.matchCondition(args, env)) {
+                            try {
+                                Array.prototype.push.apply(
+                                      rules, mixin.eval(env, args, this.important).rules);
+                            } catch (e) {
+                                throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
+                            }
+                        }
+                        match = true;
+                    }
+                }
+                if (match) {
+                    return rules;
+                }
+            }
+        }
+        if (isOneFound) {
+            throw { type:    'Runtime',
+                    message: 'No matching definition was found for `' +
+                              this.selector.toCSS().trim() + '('      +
+                              (args ? args.map(function (a) {
+                                  var argValue = "";
+                                  if (a.name) {
+                                      argValue += a.name + ":";
+                                  }
+                                  if (a.value.toCSS) {
+                                      argValue += a.value.toCSS();
+                                  } else {
+                                      argValue += "???";
+                                  }
+                                  return argValue;
+                              }).join(', ') : "") + ")`",
+                    index:   this.index, filename: this.filename };
+        } else {
+            throw { type: 'Name',
+                message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index, filename: this.filename };
+        }
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition, variadic) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.condition = condition;
+    this.variadic = variadic;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    evalParams: function (env, mixinEnv, args, evaldArguments) {
+        var frame = new(tree.Ruleset)(null, []), varargs, arg, params = this.params.slice(0), i, j, val, name, isNamedFound, argIndex;
+        
+        if (args) {
+            args = args.slice(0);
+
+            for(i = 0; i < args.length; i++) {
+                arg = args[i];
+                if (name = (arg && arg.name)) {
+                    isNamedFound = false;
+                    for(j = 0; j < params.length; j++) {
+                        if (!evaldArguments[j] && name === params[j].name) {
+                            evaldArguments[j] = arg.value.eval(env);
+                            frame.rules.unshift(new(tree.Rule)(name, arg.value.eval(env)));
+                            isNamedFound = true;
+                            break;
+                        }
+                    }
+                    if (isNamedFound) {
+                        args.splice(i, 1);
+                        i--;
+                        continue;
+                    } else {
+                        throw { type: 'Runtime', message: "Named argument for " + this.name +
+                            ' ' + args[i].name + ' not found' };
+                    }
+                }
+            }
+        }
+        argIndex = 0;
+        for (i = 0; i < params.length; i++) {
+            if (evaldArguments[i]) continue;
+            
+            arg = args && args[argIndex];
+
+            if (name = params[i].name) {
+                if (params[i].variadic && args) {
+                    varargs = [];
+                    for (j = argIndex; j < args.length; j++) {
+                        varargs.push(args[j].value.eval(env));
+                    }
+                    frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
+                } else {
+                    val = arg && arg.value;
+                    if (val) {
+                        val = val.eval(env);
+                    } else if (params[i].value) {
+                        val = params[i].value.eval(mixinEnv);
+                    } else {
+                        throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                    }
+                    
+                    frame.rules.unshift(new(tree.Rule)(name, val));
+                    evaldArguments[i] = val;
+                }
+            }
+            
+            if (params[i].variadic && args) {
+                for (j = argIndex; j < args.length; j++) {
+                    evaldArguments[j] = args[j].value.eval(env);
+                }
+            }
+            argIndex++;
+        }
+
+        return frame;
+    },
+    eval: function (env, args, important) {
+        var _arguments = [],
+            mixinFrames = this.frames.concat(env.frames),
+            frame = this.evalParams(env, {frames: mixinFrames}, args, _arguments), 
+            context, rules, start, ruleset;
+
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        rules = important ?
+            this.parent.makeImportant.apply(this).rules : this.rules.slice(0);
+
+        ruleset = new(tree.Ruleset)(null, rules).eval({
+            frames: [this, frame].concat(mixinFrames)
+        });
+        ruleset.originalRuleset = this;
+        return ruleset;
+    },
+    matchCondition: function (args, env) {
+        if (this.condition && !this.condition.eval({
+            frames: [this.evalParams(env, {frames: this.frames.concat(env.frames)}, args, [])].concat(env.frames)
+        }))                                                           { return false }
+        return true;
+    },
+    matchArgs: function (args, env) {
+        var argsLength = (args && args.length) || 0, len, frame;
+
+        if (! this.variadic) {
+            if (argsLength < this.required)                               { return false }
+            if (argsLength > this.params.length)                          { return false }
+            if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+        }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name && !this.params[i].variadic) {
+                if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    if (!a.operate) {
+        throw { name: "OperationError",
+                message: "Operation on an invalid type" };
+    }
+
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+    this.value = node;
+};
+tree.Paren.prototype = {
+    toCSS: function (env) {
+        return '(' + this.value.toCSS(env) + ')';
+    },
+    eval: function (env) {
+        return new(tree.Paren)(this.value.eval(env));
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return (v instanceof tree.Quoted) ? v.value : v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ratio = function (value) {
+    this.value = value;
+};
+tree.Ratio.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+    this.inline = inline || false;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + (this.inline ? "" : ";");
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name,
+                          this.value.eval(context),
+                          this.important,
+                          this.index, this.inline);
+};
+
+tree.Rule.prototype.makeImportant = function () {
+    return new(tree.Rule)(this.name,
+                          this.value,
+                          "!important",
+                          this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules, strictImports) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+    this.strictImports = strictImports;
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
+        var rules;
+        
+        ruleset.originalRuleset = this;
+        ruleset.root = this.root;
+        ruleset.allowImports = this.allowImports;
+
+        if(this.debugInfo) {
+            ruleset.debugInfo = this.debugInfo;
+        }
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
+            ruleset.evalImports(env);
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+        
+        var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0;
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                rules = ruleset.rules[i].eval(env);
+                ruleset.rules.splice.apply(ruleset.rules, [i, 1].concat(rules));
+                i += rules.length-1;
+                ruleset.resetCache();
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+        
+        if (env.mediaBlocks) {
+            for(var i = mediaBlockCount; i < env.mediaBlocks.length; i++) {
+                env.mediaBlocks[i].bubbleSelectors(selectors);
+            }
+        }
+
+        return ruleset;
+    },
+    evalImports: function(env) {
+        var i, rules;
+        for (i = 0; i < this.rules.length; i++) {
+            if (this.rules[i] instanceof tree.Import) {
+                rules = this.rules[i].eval(env);
+                if (typeof rules.length === "number") {
+                    this.rules.splice.apply(this.rules, [i, 1].concat(rules));
+                    i+= rules.length-1;
+                } else {
+                    this.rules.splice(i, 1, rules);
+                }
+                this.resetCache();
+            }
+        }
+    },
+    makeImportant: function() {
+        return new tree.Ruleset(this.selectors, this.rules.map(function (r) {
+                    if (r.makeImportant) {
+                        return r.makeImportant();
+                    } else {
+                        return r;
+                    }
+                }), this.strictImports);
+    },
+    matchArgs: function (args) {
+        return !args || args.length === 0;
+    },
+    resetCache: function () {
+        this._rulesets = null;
+        this._variables = null;
+        this._lookups = {};
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+           _rules = [],    //
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            debugInfo,     // Line number debugging
+            rule;
+
+        if (! this.root) {
+            this.joinSelectors(paths, context, this.selectors);
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Media)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Directive) {
+                var cssValue = rule.toCSS(paths, env);
+                // Output only the first @charset definition as such - convert the others
+                // to comments in case debug is enabled
+                if (rule.name === "@charset") {
+                    // Only output the debug info together with subsequent @charset definitions
+                    // a comment (or @media statement) before the actual @charset directive would
+                    // be considered illegal css as it has to be on the first line
+                    if (env.charset) {
+                        if (rule.debugInfo) {
+                            rulesets.push(tree.debugInfo(env, rule));
+                            rulesets.push(new tree.Comment("/* "+cssValue.replace(/\n/g, "")+" */\n").toCSS(env));
+                        }
+                        continue;
+                    }
+                    env.charset = true;
+                }
+                rulesets.push(cssValue);
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                debugInfo = tree.debugInfo(env, this);
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : ',\n');
+
+                // Remove duplicates
+                for (var i = rules.length - 1; i >= 0; i--) {
+                    if (_rules.indexOf(rules[i]) === -1) {
+                        _rules.unshift(rules[i]);
+                    }
+                }
+                rules = _rules;
+
+                css.push(debugInfo + selector + 
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('')  + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+
+        var i, j, k, 
+            hasParentSelector, newSelectors, el, sel, parentSel, 
+            newSelectorPath, afterParentJoin, newJoinedSelector, 
+            newJoinedSelectorEmpty, lastSelector, currentElements,
+            selectorsMultiplied;
+    
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.value === '&') {
+                hasParentSelector = true;
+            }
+        }
+    
+        if (!hasParentSelector) {
+            if (context.length > 0) {
+                for(i = 0; i < context.length; i++) {
+                    paths.push(context[i].concat(selector));
+                }
+            }
+            else {
+                paths.push([selector]);
+            }
+            return;
+        }
+
+        // The paths are [[Selector]]
+        // The first list is a list of comma seperated selectors
+        // The inner list is a list of inheritance seperated selectors
+        // e.g.
+        // .a, .b {
+        //   .c {
+        //   }
+        // }
+        // == [[.a] [.c]] [[.b] [.c]]
+        //
+
+        // the elements from the current selector so far
+        currentElements = [];
+        // the current list of new selectors to add to the path.
+        // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
+        // by the parents
+        newSelectors = [[]];
+
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            // non parent reference elements just get added
+            if (el.value !== "&") {
+                currentElements.push(el);
+            } else {
+                // the new list of selectors to add
+                selectorsMultiplied = [];
+
+                // merge the current list of non parent selector elements
+                // on to the current list of selectors to add
+                if (currentElements.length > 0) {
+                    this.mergeElementsOnToSelectors(currentElements, newSelectors);
+                }
+
+                // loop through our current selectors
+                for(j = 0; j < newSelectors.length; j++) {
+                    sel = newSelectors[j];
+                    // if we don't have any parent paths, the & might be in a mixin so that it can be used
+                    // whether there are parents or not
+                    if (context.length == 0) {
+                        // the combinator used on el should now be applied to the next element instead so that
+                        // it is not lost
+                        if (sel.length > 0) {
+                            sel[0].elements = sel[0].elements.slice(0);
+                            sel[0].elements.push(new(tree.Element)(el.combinator, '', 0)); //new Element(el.Combinator,  ""));
+                        }
+                        selectorsMultiplied.push(sel);
+                    }
+                    else {
+                        // and the parent selectors
+                        for(k = 0; k < context.length; k++) {
+                            parentSel = context[k];
+                            // We need to put the current selectors
+                            // then join the last selector's elements on to the parents selectors
+
+                            // our new selector path
+                            newSelectorPath = [];
+                            // selectors from the parent after the join
+                            afterParentJoin = [];
+                            newJoinedSelectorEmpty = true;
+
+                            //construct the joined selector - if & is the first thing this will be empty,
+                            // if not newJoinedSelector will be the last set of elements in the selector
+                            if (sel.length > 0) {
+                                newSelectorPath = sel.slice(0);
+                                lastSelector = newSelectorPath.pop();
+                                newJoinedSelector = new(tree.Selector)(lastSelector.elements.slice(0));
+                                newJoinedSelectorEmpty = false;
+                            }
+                            else {
+                                newJoinedSelector = new(tree.Selector)([]);
+                            }
+
+                            //put together the parent selectors after the join
+                            if (parentSel.length > 1) {
+                                afterParentJoin = afterParentJoin.concat(parentSel.slice(1));
+                            }
+
+                            if (parentSel.length > 0) {
+                                newJoinedSelectorEmpty = false;
+
+                                // join the elements so far with the first part of the parent
+                                newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, 0));
+                                newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1));
+                            }
+
+                            if (!newJoinedSelectorEmpty) {
+                                // now add the joined selector
+                                newSelectorPath.push(newJoinedSelector);
+                            }
+
+                            // and the rest of the parent
+                            newSelectorPath = newSelectorPath.concat(afterParentJoin);
+
+                            // add that to our new set of selectors
+                            selectorsMultiplied.push(newSelectorPath);
+                        }
+                    }
+                }
+
+                // our new selectors has been multiplied, so reset the state
+                newSelectors = selectorsMultiplied;
+                currentElements = [];
+            }
+        }
+
+        // if we have any elements left over (e.g. .a& .b == .b)
+        // add them on to all the current selectors
+        if (currentElements.length > 0) {
+            this.mergeElementsOnToSelectors(currentElements, newSelectors);
+        }
+
+        for(i = 0; i < newSelectors.length; i++) {
+            paths.push(newSelectors[i]);
+        }
+    },
+    
+    mergeElementsOnToSelectors: function(elements, selectors) {
+        var i, sel;
+
+        if (selectors.length == 0) {
+            selectors.push([ new(tree.Selector)(elements) ]);
+            return;
+        }
+
+        for(i = 0; i < selectors.length; i++) {
+            sel = selectors[i];
+
+            // if the previous thing in sel is a parent this needs to join on to it
+            if (sel.length > 0) {
+                sel[sel.length - 1] = new(tree.Selector)(sel[sel.length - 1].elements.concat(elements));
+            }
+            else {
+                sel.push(new(tree.Selector)(elements));
+            }
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+};
+tree.Selector.prototype.match = function (other) {
+    var elements = this.elements,
+        len = elements.length,
+        oelements, olen, max, i;
+
+    oelements = other.elements.slice(
+        (other.elements.length && other.elements[0].value === "&") ? 1 : 0);
+    olen = oelements.length;
+    max = Math.min(len, olen)
+
+    if (olen === 0 || len < olen) {
+        return false;
+    } else {
+        for (i = 0; i < max; i++) {
+            if (elements[i].value !== oelements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.eval = function (env) {
+    return new(tree.Selector)(this.elements.map(function (e) {
+        return e.eval(env);
+    }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+    
+    if (this.elements[0].combinator.value === "") {
+        this._css = ' ';
+    } else {
+        this._css = '';
+    }
+    
+    this._css += this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+    
+    return this._css;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.UnicodeDescriptor = function (value) {
+    this.value = value;
+};
+tree.UnicodeDescriptor.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, rootpath) {
+    this.value = val;
+    this.rootpath = rootpath;
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + this.value.toCSS() + ")";
+    },
+    eval: function (ctx) {
+        var val = this.value.eval(ctx), rootpath;
+
+        // Add the base path if the URL is relative
+        if (typeof val.value === "string" && !/^(?:[a-z-]+:|\/)/.test(val.value)) {
+            rootpath = this.rootpath;
+            if (!val.quote) {
+                rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; });
+            }
+            val.value = rootpath + val.value;
+        }
+
+        return new(tree.URL)(val, this.rootpath);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+        
+        if (this.evaluating) {
+            throw { type: 'Name',
+                    message: "Recursive variable definition for " + name,
+                    filename: this.file,
+                    index: this.index };
+        }
+        
+        this.evaluating = true;
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { 
+            this.evaluating = false;
+            return variable;
+        }
+        else {
+            throw { type: 'Name',
+                    message: "variable " + name + " is undefined",
+                    filename: this.file,
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.debugInfo = function(env, ctx) {
+    var result="";
+    if (env.dumpLineNumbers && !env.compress) {
+        switch(env.dumpLineNumbers) {
+            case 'comments':
+                result = tree.debugInfo.asComment(ctx);
+                break;
+            case 'mediaquery':
+                result = tree.debugInfo.asMediaQuery(ctx);
+                break;
+            case 'all':
+                result = tree.debugInfo.asComment(ctx)+tree.debugInfo.asMediaQuery(ctx);
+                break;
+        }
+    }
+    return result;
+};
+
+tree.debugInfo.asComment = function(ctx) {
+    return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
+};
+
+tree.debugInfo.asMediaQuery = function(ctx) {
+    return '@media -sass-debug-info{filename{font-family:' +
+        ('file://' + ctx.debugInfo.fileName).replace(/[\/:.]/g, '\\$&') +
+        '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n';
+};
+
+tree.find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+tree.jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+
+})(require('./tree'));
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = less.async || false;
+less.fileAsync = less.fileAsync || false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//Setup user functions
+if (less.functions) {
+    for(var func in less.functions) {
+        less.tree.functions[func] = less.functions[func];
+   }
+}
+
+var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);
+if (dumpLineNumbers) {
+    less.dumpLineNumbers = dumpLineNumbers[1];
+}
+
+//
+// Watch mode
+//
+less.watch   = function () {	
+	if (!less.watchMode ){		
+		less.env = 'development';
+		initRunningMode();
+	}
+	return this.watchMode = true 
+};
+
+less.unwatch = function () {clearInterval(less.watchTimer); return this.watchMode = false; };
+
+function initRunningMode(){
+	if (less.env === 'development') {		
+		less.optimization = 0;		
+		less.watchTimer = setInterval(function () {			
+			if (less.watchMode) {
+				loadStyleSheets(function (e, root, _, sheet, env) {
+					if (root) {
+						createCSS(root.toCSS(), sheet, env.lastModified);
+					}
+				});
+			}
+		}, less.poll);
+	} else {
+		less.optimization = 3;
+	}
+}
+
+if (/!watch/.test(location.hash)) {
+	less.watch();
+}
+
+var cache = null;
+
+if (less.env != 'development') {
+    try {
+        cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+    } catch (_) {}
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+//
+// With this function, it's possible to alter variables and re-render
+// CSS without reloading less-files
+//
+var session_cache = '';
+less.modifyVars = function(record) {
+	var str = session_cache;
+    for (name in record) {
+        str += ((name.slice(0,1) === '@')? '' : '@') + name +': '+ 
+                ((record[name].slice(-1) === ';')? record[name] : record[name] +';');
+    }
+    new(less.Parser)().parse(str, function (e, root) {
+        createCSS(root.toCSS(), less.sheets[less.sheets.length - 1]);
+    });
+};
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (e, root, _, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)({
+                filename: document.location.href.replace(/#.*$/, ''),
+                dumpLineNumbers: less.dumpLineNumbers
+            }).parse(styles[i].innerHTML || '', function (e, tree) {
+                var css = tree.toCSS();
+                var style = styles[i];
+                style.type = 'text/css';
+                if (style.styleSheet) {
+                    style.styleSheet.cssText = css;
+                } else {
+                    style.innerHTML = css;
+                }
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function pathDiff(url, baseUrl) {
+    // diff between two paths to create a relative path
+
+    var urlParts = extractUrlParts(url),
+        baseUrlParts = extractUrlParts(baseUrl),
+        i, max, urlDirectories, baseUrlDirectories, diff = "";
+    if (urlParts.hostPart !== baseUrlParts.hostPart) {
+        return "";
+    }
+    max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
+    for(i = 0; i < max; i++) {
+        if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }
+    }
+    baseUrlDirectories = baseUrlParts.directories.slice(i);
+    urlDirectories = urlParts.directories.slice(i);
+    for(i = 0; i < baseUrlDirectories.length-1; i++) {
+        diff += "../";
+    }
+    for(i = 0; i < urlDirectories.length-1; i++) {
+        diff += urlDirectories[i] + "/";
+    }
+    return diff;
+}
+
+function extractUrlParts(url, baseUrl) {
+    // urlParts[1] = protocol&hostname || /
+    // urlParts[2] = / if path relative to host base
+    // urlParts[3] = directories
+    // urlParts[4] = filename
+    // urlParts[5] = parameters
+
+    var urlPartsRegex = /^((?:[a-z-]+:)?\/\/(?:[^\/\?#]+\/)|([\/\\]))?((?:[^\/\\\?#]+[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/,
+        urlParts = url.match(urlPartsRegex),
+        returner = {}, directories = [], i, baseUrlParts;
+
+    if (!urlParts) {
+        throw new Error("Could not parse sheet href - '"+url+"'");
+    }
+
+    // Stylesheets in IE don't always return the full path    
+    if (!urlParts[1] || urlParts[2]) {
+        baseUrlParts = baseUrl.match(urlPartsRegex);
+        if (!baseUrlParts) {
+            throw new Error("Could not parse page url - '"+baseUrl+"'");
+        }
+        urlParts[1] = baseUrlParts[1];
+        if (!urlParts[2]) {
+            urlParts[3] = baseUrlParts[3] + urlParts[3];
+        }
+    }
+    
+    if (urlParts[3]) {
+        directories = urlParts[3].replace("\\", "/").split("/");
+
+        for(i = 0; i < directories.length; i++) {
+            if (directories[i] === ".." && i > 0) {
+                directories.splice(i-1, 2);
+                i -= 2;
+            }
+        }
+    }
+
+    returner.hostPart = urlParts[1];
+    returner.directories = directories;
+    returner.path = urlParts[1] + directories.join("/");
+    returner.fileUrl = returner.path + (urlParts[4] || "");
+    returner.url = returner.fileUrl + (urlParts[5] || "");
+    return returner;
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    // sheet may be set to the stylesheet for the initial load or a collection of properties including
+    // some env variables for imports
+    var contents  = sheet.contents || {};
+    var files     = sheet.files || {};
+    var hrefParts = extractUrlParts(sheet.href, window.location.href);
+    var href      = hrefParts.url;
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+    var rootpath;
+
+    if (less.relativeUrls) {
+        if (less.rootpath) {
+            if (sheet.entryPath) {
+                rootpath = extractUrlParts(less.rootpath + pathDiff(hrefParts.path, sheet.entryPath)).path;
+            } else {
+                rootpath = less.rootpath;
+            }
+        } else {
+            rootpath = hrefParts.path;
+        }
+    } else  {
+        if (less.rootpath) {
+            rootpath = less.rootpath;
+        } else {
+            if (sheet.entryPath) {
+                rootpath = sheet.entryPath;
+            } else {
+                rootpath = hrefParts.path;
+            }
+        }
+    }
+
+    xhr(href, sheet.type, function (data, lastModified) {
+        // Store data this session
+        session_cache += data.replace(/@import .+?;/ig, '');
+
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, null, data, sheet, { local: true, remaining: remaining }, href);
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                contents[href] = data;  // Updating top importing parser content cache
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [hrefParts.path],
+                    entryPath: sheet.entryPath || hrefParts.path,
+                    mime: sheet.type,
+                    filename: href,
+                    rootpath: rootpath,
+                    relativeUrls: sheet.relativeUrls,
+                    contents: contents,    // Passing top importing parser content cache ref down.
+                    files: files,
+                    dumpLineNumbers: less.dumpLineNumbers
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining }, href);
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\.[a-zA-Z]+$/,        '' )  // Remove simple extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href || '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        if( sheet.media ){ css.media = sheet.media; }
+        css.id = id;
+        var nextEl = sheet && sheet.nextSibling || null;
+        (nextEl || document.getElementsByTagName('head')[0]).parentNode.insertBefore(css, nextEl);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        try {
+            cache.setItem(href, styles);
+            cache.setItem(href + ':timestamp', lastModified);
+        } catch(e) {
+            //TODO - could do with adding more robust error handling
+            log('failed to save');
+        }
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? less.fileAsync : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol && !less.fileAsync) {
+        if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+    var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+    var elem = document.createElement('div'), timer, content, error = [];
+    var filename = e.filename || href;
+    var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1];
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p>in <a href="' + filename   + '">' + filenameNoPath + "</a> ";
+
+    var errorline = function (e, i, classname) {
+        if (e.extract[i]) {
+            error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+                               .replace(/\{class\}/, classname)
+                               .replace(/\{content\}/, e.extract[i]));
+        }
+    };
+
+    if (e.stack) {
+        content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+    } else if (e.extract) {
+        errorline(e, 0, '');
+        errorline(e, 1, 'line');
+        errorline(e, 2, '');
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+                    '<ul>' + error.join('') + '</ul>';
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #dd6666;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.line {',
+            'color: #ff0000;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
+// amd.js
+//
+// Define Less as an AMD module.
+if (typeof define === "function" && define.amd) {
+    define("less", [], function () { return less; } );
+}
+})(window);
diff --git a/util/less/dist/less-1.3.3.min.js b/util/less/dist/less-1.3.3.min.js
new file mode 100644
index 0000000..f6d56f0
--- /dev/null
+++ b/util/less/dist/less-1.3.3.min.js
@@ -0,0 +1,9 @@
+//
+// LESS - Leaner CSS v1.3.3
+// http://lesscss.org
+// 
+// Copyright (c) 2009-2011, Alexis Sellier
+// Licensed under the Apache 2.0 License.
+//
+(function(e,t){function n(t){return e.less[t.split("/")[1]]}function f(){r.env==="development"?(r.optimization=0,r.watchTimer=setInterval(function(){r.watchMode&&g(function(e,t,n,r,i){t&&S(t.toCSS(),r,i.lastModified)})},r.poll)):r.optimization=3}function m(){var e=document.getElementsByTagName("style");for(var t=0;t<e.length;t++)e[t].type.match(p)&&(new r.Parser({filename:document.location.href.replace(/#.*$/,""),dumpLineNumbers:r.dumpLineNumbers})).parse(e[t].innerHTML||"",function(n,r) [...]
+:"#9acd32"}}(n("./tree")),function(e){e.Alpha=function(e){this.value=e},e.Alpha.prototype={toCSS:function(){return"alpha(opacity="+(this.value.toCSS?this.value.toCSS():this.value)+")"},eval:function(e){return this.value.eval&&(this.value=this.value.eval(e)),this}}}(n("../tree")),function(e){e.Anonymous=function(e){this.value=e.value||e},e.Anonymous.prototype={toCSS:function(){return this.value},eval:function(){return this},compare:function(e){if(!e.toCSS)return-1;var t=this.toCSS(),n=e.t [...]
\ No newline at end of file
diff --git a/util/less/dist/less-rhino-1.1.3.js b/util/less/dist/less-rhino-1.1.3.js
new file mode 100644
index 0000000..b31b25f
--- /dev/null
+++ b/util/less/dist/less-rhino-1.1.3.js
@@ -0,0 +1,2460 @@
+//
+// Stub out `require` in rhino
+//
+function require(arg) {
+    return less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof(window) === 'undefined') {
+    if (typeof(exports) === 'undefined') {
+        // Rhino
+        less = {};
+        tree = less.tree = {};
+    } else {
+        // Node.js
+        less = exports,
+        tree = require('less/tree');
+    }
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        mime:  env && env.mime,         // MIME type of .less files
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+
+                callback(root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam,
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && !inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString && !inParam) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString && !inParam) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else if (c === '(' && !inString && !inParam) {
+                        chunk.push(c);
+                        inParam = true;
+                    } else if (c === ')' && !inString && inParam) {
+                        chunk.push(c);
+                        inParam = false;
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            root = new(tree.Ruleset)([], $(this.parsers.primary));
+            root.root = true;
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [];
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        lines = input.split('\n');
+                        line = getLine(e.index);
+
+                        for (var n = e.index, column = -1;
+                                 n >= 0 && input.charAt(n) !== '\n';
+                                 n--) { column++ }
+
+                        throw {
+                            type: e.type,
+                            message: e.message,
+                            filename: env.filename,
+                            index: e.index,
+                            line: typeof(line) === 'number' ? line + 1 : null,
+                            callLine: e.call && (getLine(e.call) + 1),
+                            callExtract: lines[getLine(e.call)],
+                            stack: e.stack,
+                            column: column,
+                            extract: [
+                                lines[line - 1],
+                                lines[line],
+                                lines[line + 1]
+                            ]
+                        };
+                    }
+                    if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+
+                    function getLine(index) {
+                        return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    name: "ParseError",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+                    if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args, index = i;
+
+                    if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+                    if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value;
+
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    if (value = $(this.expression)) {
+                                        params.push({ name: param.name, value: value });
+                                    } else {
+                                        throw new(Error)("Expected value");
+                                    }
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset);
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c;
+
+                c = $(this.combinator);
+                e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (e) { return new(tree.Element)(c, e) }
+
+                if (c.value && c.value[0] === '&') {
+                  return new(tree.Element)(c, null);
+                }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === '&') {
+                    match = '&';
+                    i++;
+                    if(input.charAt(i) === ' ') {
+                        match = '& ';
+                    }
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(match);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                if (match = /^([.#: \w-]+)[\s\n]*\{/.exec(chunks[j])) {
+                    i += match[0].length - 1;
+                    selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
+                } else {
+                    while (s = $(this.selector)) {
+                        selectors.push(s);
+                        $(this.comment);
+                        if (! $(',')) { break }
+                        $(this.comment);
+                    }
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url)) &&
+                    $(';')) {
+                    return new(tree.Import)(path, imports);
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import'])) {
+                    return value;
+                } else if (name = $(/^@media|@page|@-[-a-z]+/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (typeof(window) !== 'undefined' /* browser */ || typeof(exports) === 'undefined' /* rhino */) {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math.round(number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math.round(n);
+        } else {
+	    throw {
+                error: "RuntimeError",
+                message: "math functions take numbers as parameters"
+            };
+        }
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { message: "error evaluating function `" + this.name + "`",
+                        index: this.index };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else if (rgb.length == 8) {
+        this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
+        this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    }
+};
+
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+    this.value = value ? value.trim() : "";
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else if (value === '& ') {
+        this.value = '& ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        '& ' : ' ',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(' ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+    var that = this;
+
+    this._path = path;
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (root) {
+            if (! root) {
+                throw new(Error)("Error parsing " + that.path);
+            }
+            that.root = root;
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function () {
+        if (this.css) {
+            return "@import " + this._path.toCSS() + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset;
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return ruleset.rules;
+        }
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('less/tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index };
+                }
+            }
+        }
+        throw { message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    eval: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return v.value || v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + ";";
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > 1) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                this.joinSelectors( paths, context, this.selectors );
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function( paths, context, selectors ) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function( paths, context, selector ) {
+        var before = [], after = [], beforeElements = [], afterElements = [], hasParentSelector = false, el;
+
+        for (var i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.combinator.value[0] === '&') {
+                hasParentSelector = true;
+            }
+            if(!hasParentSelector) {
+                beforeElements.push(el);
+            } else {
+                afterElements.push(el);
+            }
+        }
+
+        if(!hasParentSelector) {
+            afterElements = beforeElements;
+            beforeElements = [];
+        }
+
+        if(beforeElements.length > 0) {
+            before.push(new (tree.Selector)(beforeElements));
+        }
+        if(afterElements.length > 0) {
+            after.push(new (tree.Selector)(afterElements));
+        }
+
+        for (var c = 0; c < context.length; c++) {
+            paths.push(before.concat(context[c]).concat(after));
+        }
+    }
+};
+})(require('less/tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    if (this.elements[0].value === other.elements[0].value) {
+        return true;
+    } else {
+        return false;
+    }
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('less/tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { message: "variable " + name + " is undefined",
+                    index: this.index };
+        }
+    }
+};
+
+})(require('less/tree'));
+require('less/tree').find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+require('less/tree').jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+var name;
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var sheetName = name.slice(0, name.lastIndexOf('/') + 1) + sheet.href;
+    var input = readFile(sheetName);
+    var parser = new less.Parser();
+    parser.parse(input, function (e, root) {
+        if (e) {
+            print("Error: " + e);
+            quit(1);
+        }
+        callback(root, sheet, { local: false, lastModified: 0, remaining: remaining });
+    });
+
+    // callback({}, sheet, { local: true, remaining: remaining });
+}
+
+function writeFile(filename, content) {
+    var fstream = new java.io.FileWriter(filename);
+    var out = new java.io.BufferedWriter(fstream);
+    out.write(content);
+    out.close();
+}
+
+// Command line integration via Rhino
+(function (args) {
+    name = args[0];
+    var output = args[1];
+
+    if (!name) {
+        print('No files present in the fileset; Check your pattern match in build.xml');
+        quit(1);
+    }
+    path = name.split("/");path.pop();path=path.join("/")
+
+    var input = readFile(name);
+
+    if (!input) {
+        print('lesscss: couldn\'t open file ' + name);
+        quit(1);
+    }
+
+    var result;
+    var parser = new less.Parser();
+    parser.parse(input, function (e, root) {
+        if (e) {
+            quit(1);
+        } else {
+            result = root.toCSS();
+            if (output) {
+                writeFile(output, result);
+                print("Written to " + output);
+            } else {
+                print(result);
+            }
+            quit(0);
+        }
+    });
+    print("done");
+}(arguments));
diff --git a/util/less/dist/less-rhino-1.1.5.js b/util/less/dist/less-rhino-1.1.5.js
new file mode 100644
index 0000000..e755f63
--- /dev/null
+++ b/util/less/dist/less-rhino-1.1.5.js
@@ -0,0 +1,2481 @@
+//
+// Stub out `require` in rhino
+//
+function require(arg) {
+    return less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    less = {};
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'rhino';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        mime:  env && env.mime,         // MIME type of .less files
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+                that.files[path] = root;                        // Store the root
+
+                callback(root);
+
+                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, c, index, endIndex, k, mem;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            mem = i += length;
+            endIndex = i + chunks[j].length - length;
+
+            while (i < endIndex) {
+                c = input.charCodeAt(i);
+                if (! (c === 32 || c === 10 || c === 9)) { break }
+                i++;
+            }
+            chunks[j] = chunks[j].slice(length + (i - mem));
+            current = i;
+
+            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            chunks = [];
+            input = str.replace(/\r\n/g, '\n');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /[^"'`\{\}\/\(\)]+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam,
+                    inString;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = i;
+
+                    if (!inString && !inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+
+                    if        (c === '{' && !inString && !inParam) { level ++;
+                        chunk.push(c);
+                    } else if (c === '}' && !inString && !inParam) { level --;
+                        chunk.push(c);
+                        chunks[++j] = chunk = [];
+                    } else if (c === '(' && !inString && !inParam) {
+                        chunk.push(c);
+                        inParam = true;
+                    } else if (c === ')' && !inString && inParam) {
+                        chunk.push(c);
+                        inParam = false;
+                    } else {
+                        if (c === '"' || c === "'" || c === '`') {
+                            if (! inString) {
+                                inString = c;
+                            } else {
+                                inString = inString === c ? false : inString;
+                            }
+                        }
+                        chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    throw {
+                        type: 'Syntax',
+                        message: "Missing closing `}`",
+                        filename: env.filename
+                    };
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            root = new(tree.Ruleset)([], $(this.parsers.primary));
+            root.root = true;
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [];
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false });
+                    } catch (e) {
+                        lines = input.split('\n');
+                        line = getLine(e.index);
+
+                        for (var n = e.index, column = -1;
+                                 n >= 0 && input.charAt(n) !== '\n';
+                                 n--) { column++ }
+
+                        throw {
+                            type: e.type,
+                            message: e.message,
+                            filename: env.filename,
+                            index: e.index,
+                            line: typeof(line) === 'number' ? line + 1 : null,
+                            callLine: e.call && (getLine(e.call) + 1),
+                            callExtract: lines[getLine(e.call)],
+                            stack: e.stack,
+                            column: column,
+                            extract: [
+                                lines[line - 1],
+                                lines[line],
+                                lines[line + 1]
+                            ]
+                        };
+                    }
+                    if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+
+                    function getLine(index) {
+                        return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    name: "ParseError",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function () { callback(error, root) };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) { return new(tree.Keyword)(k) }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, args, index = i;
+
+                    if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
+
+                    name = name[1].toLowerCase();
+
+                    if (name === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (name === 'alpha') { return $(this.alpha) }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
+                    if (! $(')')) throw new(Error)("missing closing ) for url()");
+
+                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                dataURI: function () {
+                    var obj;
+
+                    if ($(/^data:/)) {
+                        obj         = {};
+                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
+                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
+                        obj.base64  = $(/^;\s*base64/)          || '';
+                        obj.data    = $(/^,\s*[^)]+/);
+
+                        if (obj.data) { return obj }
+                    }
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args, index = i, s = input.charAt(i);
+
+                    if (s !== '.' && s !== '#') { return }
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    $('(') && (args = $(this.entities.arguments)) && $(')');
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index);
+                    }
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value;
+
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        while (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                 || $(this.entities.keyword)) {
+                            // Variable
+                            if (param instanceof tree.Variable) {
+                                if ($(':')) {
+                                    if (value = $(this.expression)) {
+                                        params.push({ name: param.name, value: value });
+                                    } else {
+                                        throw new(Error)("Expected value");
+                                    }
+                                } else {
+                                    params.push({ name: param.name });
+                                }
+                            } else {
+                                params.push({ value: param });
+                            }
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset);
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    if (! $(')')) throw new(Error)("missing closing ) for alpha()");
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c;
+
+                c = $(this.combinator);
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) ||
+                    $('*') || $(this.attribute) || $(/^\([^)@]+\)/);
+
+                if (e) { return new(tree.Element)(c, e, i) }
+
+                if (c.value && c.value.charAt(0) === '&') {
+                    return new(tree.Element)(c, null, i);
+                }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (c === '&') {
+                    match = '&';
+                    i++;
+                    if(input.charAt(i) === ' ') {
+                        match = '& ';
+                    }
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)(match);
+                } else if (c === ':' && input.charAt(i + 1) === ':') {
+                    i += 2;
+                    while (input.charAt(i) === ' ') { i++ }
+                    return new(tree.Combinator)('::');
+                } else if (input.charAt(i - 1) === ' ') {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match;
+                save();
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    return new(tree.Ruleset)(selectors, rules);
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path;
+                if ($(/^@import\s+/) &&
+                    (path = $(this.entities.quoted) || $(this.entities.url)) &&
+                    $(';')) {
+                    return new(tree.Import)(path, imports);
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, types;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import'])) {
+                    return value;
+                } else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-|-moz-)?keyframes/)) {
+                    types = ($(/^[^{]+/) || '').trim();
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name + " " + types, rules);
+                    }
+                } else if (name = $(/^@[-a-z]+/)) {
+                    if (name === '@font-face') {
+                        if (rules = $(this.block)) {
+                            return new(tree.Directive)(name, rules);
+                        }
+                    } else if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (path.charAt(0) !== '/' && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math.round(number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math.round(n);
+        } else {
+	    throw {
+                error: "RuntimeError",
+                message: "math functions take numbers as parameters"
+            };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { message: "error evaluating function `" + this.name + "`",
+                        index: this.index };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        env.frames.unshift(this);
+        this.ruleset = this.ruleset && this.ruleset.eval(env);
+        env.frames.shift();
+        return this;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+    this.value = value ? value.trim() : "";
+    this.index = index;
+};
+tree.Element.prototype.toCSS = function (env) {
+    return this.combinator.toCSS(env || {}) + this.value;
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else if (value === '& ') {
+        this.value = '& ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        '&' : '',
+        '& ' : ' ',
+        ':' : ' :',
+        '::': '::',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports) {
+    var that = this;
+
+    this._path = path;
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css(\?.*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (root) {
+            if (! root) {
+                throw new(Error)("Error parsing " + that.path);
+            }
+            that.root = root;
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function () {
+        if (this.css) {
+            return "@import " + this._path.toCSS() + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset;
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index };
+                }
+            }
+        }
+        throw { message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    eval: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
+
+        for (var i = 0, val; i < this.params.length; i++) {
+            if (this.params[i].name) {
+                if (val = (args && args[i]) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
+                } else {
+                    throw { message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push(args[i] || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len;
+
+        if (argsLength < this.required)                               { return false }
+        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return v.value || v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + ";";
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
+
+        ruleset.root = this.root;
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype.splice
+                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                Array.prototype.splice
+                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            rule;
+
+        if (! this.root) {
+            if (context.length === 0) {
+                paths = this.selectors.map(function (s) { return [s] });
+            } else {
+                this.joinSelectors( paths, context, this.selectors );
+            }
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
+                css.push(selector,
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('') + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+        var before = [], after = [], beforeElements = [],
+            afterElements = [], hasParentSelector = false, el;
+
+        for (var i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.combinator.value.charAt(0) === '&') {
+                hasParentSelector = true;
+            }
+            if (hasParentSelector) afterElements.push(el);
+            else                   beforeElements.push(el);
+        }
+
+        if (! hasParentSelector) {
+            afterElements = beforeElements;
+            beforeElements = [];
+        }
+
+        if (beforeElements.length > 0) {
+            before.push(new(tree.Selector)(beforeElements));
+        }
+
+        if (afterElements.length > 0) {
+            after.push(new(tree.Selector)(afterElements));
+        }
+
+        for (var c = 0; c < context.length; c++) {
+            paths.push(before.concat(context[c]).concat(after));
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+    if (this.elements[0].combinator.value === "") {
+        this.elements[0].combinator.value = ' ';
+    }
+};
+tree.Selector.prototype.match = function (other) {
+    var len  = this.elements.length,
+        olen = other.elements.length,
+        max  = Math.min(len, olen);
+
+    if (len < olen) {
+        return false;
+    } else {
+        for (var i = 0; i < max; i++) {
+            if (this.elements[i].value !== other.elements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+
+    return this._css = this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    if (val.data) {
+        this.attrs = val;
+    } else {
+        // Add the base path if the URL is relative and we are in the browser
+        if (!/^(?:https?:\/\/|file:\/\/|data:)?/.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
+            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+        this.value = val;
+        this.paths = paths;
+    }
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
+                                    : this.value.toCSS()) + ")";
+    },
+    eval: function (ctx) {
+        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index) { this.name = name, this.index = index };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { message: "variable " + name + " is undefined",
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+require('./tree').find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+require('./tree').jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+var name;
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var sheetName = name.slice(0, name.lastIndexOf('/') + 1) + sheet.href;
+    var input = readFile(sheetName);
+    var parser = new less.Parser();
+    parser.parse(input, function (e, root) {
+        if (e) {
+            print("Error: " + e);
+            quit(1);
+        }
+        callback(root, sheet, { local: false, lastModified: 0, remaining: remaining });
+    });
+
+    // callback({}, sheet, { local: true, remaining: remaining });
+}
+
+function writeFile(filename, content) {
+    var fstream = new java.io.FileWriter(filename);
+    var out = new java.io.BufferedWriter(fstream);
+    out.write(content);
+    out.close();
+}
+
+// Command line integration via Rhino
+(function (args) {
+    name = args[0];
+    var output = args[1];
+
+    if (!name) {
+        print('No files present in the fileset; Check your pattern match in build.xml');
+        quit(1);
+    }
+    path = name.split("/");path.pop();path=path.join("/")
+
+    var input = readFile(name);
+
+    if (!input) {
+        print('lesscss: couldn\'t open file ' + name);
+        quit(1);
+    }
+
+    var result;
+    var parser = new less.Parser();
+    parser.parse(input, function (e, root) {
+        if (e) {
+            quit(1);
+        } else {
+            result = root.toCSS();
+            if (output) {
+                writeFile(output, result);
+                print("Written to " + output);
+            } else {
+                print(result);
+            }
+            quit(0);
+        }
+    });
+    print("done");
+}(arguments));
diff --git a/util/less/dist/less-rhino-1.3.1.js b/util/less/dist/less-rhino-1.3.1.js
new file mode 100644
index 0000000..1ebe0ea
--- /dev/null
+++ b/util/less/dist/less-rhino-1.3.1.js
@@ -0,0 +1,3725 @@
+//
+// Stub out `require` in rhino
+//
+function require(arg) {
+    return less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    if (typeof(window) === 'undefined') { less = {} }
+    else                                { less = window.less = {} }
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // Top parser on an import tree must be sure there is one "env"
+    // which will then be passed arround by reference.
+    var env = env || { };
+    if (!env.contents) { env.contents={}; }  // env.contents must be passed arround with top env
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env && env.paths || [],  // Search paths, when importing
+        queue: [],                      // Files which haven't been imported yet
+        files: {},                      // Holds the imported parse trees
+        contents: env.contents,         // Holds the imported file contents
+        mime:  env && env.mime,         // MIME type of .less files
+        error: null,                    // Error in parsing/evaluating an import
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (e, root) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+
+                var imported = path in that.files;
+
+                that.files[path] = root;                        // Store the root
+
+                if (e && !that.error) { that.error = e }
+
+                callback(e, root, imported);
+
+                if (that.queue.length === 0) { finish(e) }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    function isWhitespace(c) {
+        // Could change to \s?
+        var code = c.charCodeAt(0);
+        return code === 32 || code === 10 || code === 9;
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, index, k;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            skipWhitespace(length);
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    function skipWhitespace(length) {
+        var oldi = i, oldj = j,
+            endIndex = i + chunks[j].length,
+            mem = i += length;
+
+        while (i < endIndex) {
+            if (! isWhitespace(input.charAt(i))) { break }
+            i++;
+        }
+        chunks[j] = chunks[j].slice(length + (i - mem));
+        current = i;
+
+        if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+        return oldi !== i || oldj !== j;
+    }
+
+    function expect(arg, msg) {
+        var result = $(arg);
+        if (! result) {
+            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+                                                   : "unexpected token"));
+        } else {
+            return result;
+        }
+    }
+
+    function error(msg, type) {
+        throw { index: i, type: type || 'Syntax', message: msg };
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    function getInput(e, env) {
+        if (e.filename && env.filename && (e.filename !== env.filename)) {
+            return parser.imports.contents[e.filename];
+        } else {
+            return input;
+        }
+    }
+
+    function getLocation(index, input) {
+        for (var n = index, column = -1;
+                 n >= 0 && input.charAt(n) !== '\n';
+                 n--) { column++ }
+
+        return { line:   typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+                 column: column };
+    }
+
+    function getFileName(e) {
+        if(less.mode === 'browser' || less.mode === 'rhino')
+            return e.filename;
+        else
+            return require('path').resolve(e.filename);
+    }
+
+    function getDebugInfo(index, inputStream, e) {
+        return {
+            lineNumber: getLocation(index, inputStream).line + 1,
+            fileName: getFileName(e)
+        };
+    }
+
+    function LessError(e, env) {
+        var input = getInput(e, env),
+            loc = getLocation(e.index, input),
+            line = loc.line,
+            col  = loc.column,
+            lines = input.split('\n');
+
+        this.type = e.type || 'Syntax';
+        this.message = e.message;
+        this.filename = e.filename || env.filename;
+        this.index = e.index;
+        this.line = typeof(line) === 'number' ? line + 1 : null;
+        this.callLine = e.call && (getLocation(e.call, input).line + 1);
+        this.callExtract = lines[getLocation(e.call, input).line];
+        this.stack = e.stack;
+        this.column = col;
+        this.extract = [
+            lines[line - 1],
+            lines[line],
+            lines[line + 1]
+        ];
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            input = str.replace(/\r\n/g, '\n');
+
+            // Remove potential UTF Byte Order Mark
+            input = input.replace(/^\uFEFF/, '');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam;
+
+                for (var i = 0, c, cc; i < input.length; i++) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = string.lastIndex = i;
+
+                    if (match = string.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                            c = input.charAt(i);
+                        }
+                    }
+
+                    if (!inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    c = input.charAt(i);
+                                }
+                            }
+                        }
+                    }
+                    
+                    switch (c) {
+                        case '{': if (! inParam) { level ++;        chunk.push(c);                           break }
+                        case '}': if (! inParam) { level --;        chunk.push(c); chunks[++j] = chunk = []; break }
+                        case '(': if (! inParam) { inParam = true;  chunk.push(c);                           break }
+                        case ')': if (  inParam) { inParam = false; chunk.push(c);                           break }
+                        default:                                    chunk.push(c);
+                    }
+                }
+                if (level > 0) {
+                    error = new(LessError)({
+                        index: i,
+                        type: 'Parse',
+                        message: "missing closing `}`",
+                        filename: env.filename
+                    }, env);
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            if (error) {
+                return callback(error);
+            }
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            try {
+                root = new(tree.Ruleset)([], $(this.parsers.primary));
+                root.root = true;
+            } catch (e) {
+                return callback(new(LessError)(e, env));
+            }
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [], importError;
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false, dumpLineNumbers: env.dumpLineNumbers });
+                    } catch (e) {
+                        throw new(LessError)(e, env);
+                    }
+
+                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
+                        if (importError instanceof LessError) throw importError;
+                        else                                  throw new(LessError)(importError, env);
+                    }
+
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('./cssmin').compressor.cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    type: "Parse",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function (e) {
+                    if (e) callback(e);
+                    else callback(null, root);
+                };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k);
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, nameLC, args, alpha_ret, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1];
+                    nameLC = name.toLowerCase();
+
+                    if (nameLC === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (nameLC === 'alpha') {
+                        alpha_ret = $(this.alpha);
+                        if(typeof alpha_ret !== 'undefined') {
+                            return alpha_ret;
+                        }
+                    }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index, env.filename) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.ratio) ||
+                           $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || "";
+
+                    expect(')');
+
+                    return new(tree.URL)((value.value != null || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), imports.paths);
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index, env.filename);
+                    }
+                },
+
+                // A variable entity useing the protective {} e.g. @{var}
+                variableCurly: function () {
+                    var name, curly, index = i;
+
+                    if (input.charAt(i) === '@' && (curly = $(/^@\{([\w-]+)\}/))) {
+                        return new(tree.Variable)("@" + curly[1], index, env.filename);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    if ((c > 57 || c < 45) || c === 47) return;
+
+                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn|dpi|dpcm|dppx|rem|vw|vh|vmin|vm|ch)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // A Ratio
+                //
+                //    16/9
+                //
+                ratio: function () {
+                  var value, c = input.charCodeAt(i);
+                  if (c > 57 || c < 48) return;
+
+                  if (value = $(/^(\d+\/\d+)/)) {
+                    return new(tree.Ratio)(value[1]);
+                  }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                save();
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+
+                restore();
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, args = [], arg, index = i, s = input.charAt(i), name, value, important = false;
+
+                    if (s !== '.' && s !== '#') { return }
+                    
+                    save(); // stop us absorbing part of an invalid selector
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    if ($('(')) {
+                        while (arg = $(this.expression)) {
+                            value = arg;
+                            name = null;
+
+                            // Variable
+                            if (arg.value.length == 1) {
+                                var val = arg.value[0];
+                                if (val instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        if (value = $(this.expression)) {
+                                            name = val.name;
+                                        } else {
+                                            throw new(Error)("Expected value");
+                                        }
+                                    }
+                                }
+                            }
+
+                            args.push({ name: name, value: value });
+
+                            if (! $(',')) { break }
+                        }
+                        if (! $(')')) throw new(Error)("Expected )");
+                    }
+
+                    if ($(this.important)) {
+                        important = true;
+                    }
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+                    }
+                    
+                    restore();
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value, cond, variadic = false;
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*(;|})/)) return;
+
+                    save();
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        do {
+                            if (input.charAt(i) === '.' && $(/^\.{3}/)) {
+                                variadic = true;
+                                break;
+                            } else if (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                         || $(this.entities.keyword)) {
+                                // Variable
+                                if (param instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        value = expect(this.expression, 'expected expression');
+                                        params.push({ name: param.name, value: value });
+                                    } else if ($(/^\.{3}/)) {
+                                        params.push({ name: param.name, variadic: true });
+                                        variadic = true;
+                                        break;
+                                    } else {
+                                        params.push({ name: param.name });
+                                    }
+                                } else {
+                                    params.push({ value: param });
+                                }
+                            } else {
+                                break;
+                            }
+                        } while ($(','))
+
+                        // .mixincall("@{a}"); 
+                        // looks a bit like a mixin definition.. so we have to be nice and restore
+                        if (!$(')')) {
+                            furthest = i;
+                            restore();
+                        }
+
+                        if ($(/^when/)) { // Guard
+                            cond = expect(this.conditions, 'expected condition');
+                        }
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
+                        } else {
+                            restore();
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    expect(')');
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c, v;
+
+                c = $(this.combinator);
+
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
+                    $('*') || $('&') || $(this.attribute) || $(/^\([^)@]+\)/) || $(/^[\.#](?=@)/) || $(this.entities.variableCurly);
+
+                if (! e) {
+                    if ($('(') && (v = ($(this.entities.variableCurly) || $(this.entities.variable))) && $(')')) {
+                        e = new(tree.Paren)(v);
+                    }
+                }
+
+                if (e) { return new(tree.Element)(c, e, i) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~') {
+                    i++;
+                    while (input.charAt(i).match(/\s/)) { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (input.charAt(i - 1).match(/\s/)) {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                // depreciated, will be removed soon
+                if ($('(')) {
+                    sel = $(this.entity);
+                    expect(')');
+                    return new(tree.Selector)([new(tree.Element)('', sel, i)]);
+                }
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            tag: function () {
+                return $(/^[A-Za-z][A-Za-z-]*[0-9]?/) || $('*');
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^(?:[_A-Za-z0-9-]|\\.)+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match, debugInfo;
+                save();
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports);
+                    if (env.dumpLineNumbers)
+                        ruleset.debugInfo = debugInfo;
+                    return ruleset;
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path, features, index = i;
+                
+                save();
+                
+                var dir = $(/^@import(?:-(once))?\s+/);
+
+                if (dir && (path = $(this.entities.quoted) || $(this.entities.url))) {
+                    features = $(this.mediaFeatures);
+                    if ($(';')) {
+                        return new(tree.Import)(path, imports, features, (dir[1] === 'once'), index);
+                    }
+                }
+                
+                restore();
+            },
+
+            mediaFeature: function () {
+                var e, p, nodes = [];
+
+                do {
+                    if (e = $(this.entities.keyword)) {
+                        nodes.push(e);
+                    } else if ($('(')) {
+                        p = $(this.property);
+                        e = $(this.entity);
+                        if ($(')')) {
+                            if (p && e) {
+                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+                            } else if (e) {
+                                nodes.push(new(tree.Paren)(e));
+                            } else {
+                                return null;
+                            }
+                        } else { return null }
+                    }
+                } while (e);
+
+                if (nodes.length > 0) {
+                    return new(tree.Expression)(nodes);
+                }
+            },
+
+            mediaFeatures: function () {
+                var e, features = [];
+
+                do {
+                  if (e = $(this.mediaFeature)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  } else if (e = $(this.entities.variable)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  }
+                } while (e);
+
+                return features.length > 0 ? features : null;
+            },
+
+            media: function () {
+                var features, rules, media, debugInfo;
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                if ($(/^@media/)) {
+                    features = $(this.mediaFeatures);
+
+                    if (rules = $(this.block)) {
+                        media = new(tree.Media)(rules, features);
+                        if(env.dumpLineNumbers)
+                            media.debugInfo = debugInfo;
+                        return media;
+                    }
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, identifier, e, nodes, nonVendorSpecificName,
+                    hasBlock, hasIdentifier;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import']) || $(this.media)) {
+                    return value;
+                }
+                
+                save();
+
+                name = $(/^@[a-z-]+/);
+
+                nonVendorSpecificName = name;
+                if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
+                    nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
+                }
+
+                switch(nonVendorSpecificName) {
+                    case "@font-face":
+                        hasBlock = true;
+                        break;
+                    case "@viewport":
+                    case "@top-left":
+                    case "@top-left-corner":
+                    case "@top-center":
+                    case "@top-right":
+                    case "@top-right-corner":
+                    case "@bottom-left":
+                    case "@bottom-left-corner":
+                    case "@bottom-center":
+                    case "@bottom-right":
+                    case "@bottom-right-corner":
+                    case "@left-top":
+                    case "@left-middle":
+                    case "@left-bottom":
+                    case "@right-top":
+                    case "@right-middle":
+                    case "@right-bottom":
+                        hasBlock = true;
+                        break;
+                    case "@page":
+                    case "@document":
+                    case "@supports":
+                    case "@keyframes":
+                        hasBlock = true;
+                        hasIdentifier = true;
+                        break;
+                }
+
+                if (hasIdentifier) {
+                    name += " " + ($(/^[^{]+/) || '').trim();
+                }
+
+                if (hasBlock)
+                {
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name, rules);
+                    }
+                } else {
+                    if ((value = $(this.entity)) && $(';')) {
+                        return new(tree.Directive)(name, value);
+                    }
+                }
+                
+                restore();
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/\*/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (!isWhitespace(input.charAt(i - 1)) && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            conditions: function () {
+                var a, b, index = i, condition;
+
+                if (a = $(this.condition)) {
+                    while ($(',') && (b = $(this.condition))) {
+                        condition = new(tree.Condition)('or', condition || a, b, index);
+                    }
+                    return condition || a;
+                }
+            },
+            condition: function () {
+                var a, b, c, op, index = i, negate = false;
+
+                if ($(/^not/)) { negate = true }
+                expect('(');
+                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                    if (op = $(/^(?:>=|=<|[<=>])/)) {
+                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                            c = new(tree.Condition)(op, a, b, index, negate);
+                        } else {
+                            error('expected expression');
+                        }
+                    } else {
+                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+                    }
+                    expect(')');
+                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[_a-z0-9-]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (!/^([a-z-]+:)?\//.test(path) && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        // __ Now using the hack of passing a ref to top parser's content cache in the 1st arg. __
+        loadStyleSheet({ href: path, title: path, type: env.mime, contents: env.contents }, function (e) {
+            if (e && typeof(env.errback) === "function") {
+                env.errback.call(null, path, paths, callback, env);
+            } else {
+                callback.apply(null, arguments);
+            }
+        }, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return number(c) }),
+            a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    red: function (color) {
+        return new(tree.Dimension)(color.rgb[0]);
+    },
+    green: function (color) {
+        return new(tree.Dimension)(color.rgb[1]);
+    },
+    blue: function (color) {
+        return new(tree.Dimension)(color.rgb[2]);
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    luma: function (color) {
+        return new(tree.Dimension)(Math.round((0.2126 * (color.rgb[0]/255) +
+            0.7152 * (color.rgb[1]/255) +
+            0.0722 * (color.rgb[2]/255))
+            * color.alpha * 100), '%');
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        if (!weight) {
+            weight = new(tree.Dimension)(50);
+        }
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    contrast: function (color, dark, light, threshold) {
+        if (typeof light === 'undefined') {
+            light = this.rgba(255, 255, 255, 1.0);
+        }
+        if (typeof dark === 'undefined') {
+            dark = this.rgba(0, 0, 0, 1.0);
+        }
+        if (typeof threshold === 'undefined') {
+            threshold = 0.43;
+        } else {
+            threshold = threshold.value;
+        }
+        if (((0.2126 * (color.rgb[0]/255) + 0.7152 * (color.rgb[1]/255) + 0.0722 * (color.rgb[2]/255)) * color.alpha) < threshold) {
+            return light;
+        } else {
+            return dark;
+        }
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    round: function (n, f) {
+        var fraction = typeof(f) === "undefined" ? 0 : f.value;
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(number(n).toFixed(fraction), n.unit);
+        } else if (typeof(n) === 'number') {
+            return n.toFixed(fraction);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    ceil: function (n) {
+        return this._math('ceil', n);
+    },
+    floor: function (n) {
+        return this._math('floor', n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(Math[fn](number(n)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return Math[fn](n);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    },
+    percentage: function (n) {
+        return new(tree.Dimension)(n.value * 100, '%');
+    },
+    color: function (n) {
+        if (n instanceof tree.Quoted) {
+            return new(tree.Color)(n.value.slice(1));
+        } else {
+            throw { type: "Argument", message: "argument must be a string" };
+        }
+    },
+    iscolor: function (n) {
+        return this._isa(n, tree.Color);
+    },
+    isnumber: function (n) {
+        return this._isa(n, tree.Dimension);
+    },
+    isstring: function (n) {
+        return this._isa(n, tree.Quoted);
+    },
+    iskeyword: function (n) {
+        return this._isa(n, tree.Keyword);
+    },
+    isurl: function (n) {
+        return this._isa(n, tree.URL);
+    },
+    ispixel: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+    },
+    ispercentage: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+    },
+    isem: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+    },
+    _isa: function (n, Type) {
+        return (n instanceof Type) ? tree.True : tree.False;
+    },
+    
+    /* Blending modes */
+    
+    multiply: function(color1, color2) {
+        var r = color1.rgb[0] * color2.rgb[0] / 255;
+        var g = color1.rgb[1] * color2.rgb[1] / 255;
+        var b = color1.rgb[2] * color2.rgb[2] / 255;
+        return this.rgb(r, g, b);
+    },
+    screen: function(color1, color2) {
+        var r = 255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = 255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = 255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    overlay: function(color1, color2) {
+        var r = color1.rgb[0] < 128 ? 2 * color1.rgb[0] * color2.rgb[0] / 255 : 255 - 2 * (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = color1.rgb[1] < 128 ? 2 * color1.rgb[1] * color2.rgb[1] / 255 : 255 - 2 * (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = color1.rgb[2] < 128 ? 2 * color1.rgb[2] * color2.rgb[2] / 255 : 255 - 2 * (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    softlight: function(color1, color2) {
+        var t = color2.rgb[0] * color1.rgb[0] / 255;
+        var r = t + color1.rgb[0] * (255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255 - t) / 255;
+        t = color2.rgb[1] * color1.rgb[1] / 255;
+        var g = t + color1.rgb[1] * (255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255 - t) / 255;
+        t = color2.rgb[2] * color1.rgb[2] / 255;
+        var b = t + color1.rgb[2] * (255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255 - t) / 255;
+        return this.rgb(r, g, b);
+    },
+    hardlight: function(color1, color2) {
+        var r = color2.rgb[0] < 128 ? 2 * color2.rgb[0] * color1.rgb[0] / 255 : 255 - 2 * (255 - color2.rgb[0]) * (255 - color1.rgb[0]) / 255;
+        var g = color2.rgb[1] < 128 ? 2 * color2.rgb[1] * color1.rgb[1] / 255 : 255 - 2 * (255 - color2.rgb[1]) * (255 - color1.rgb[1]) / 255;
+        var b = color2.rgb[2] < 128 ? 2 * color2.rgb[2] * color1.rgb[2] / 255 : 255 - 2 * (255 - color2.rgb[2]) * (255 - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    difference: function(color1, color2) {
+        var r = Math.abs(color1.rgb[0] - color2.rgb[0]);
+        var g = Math.abs(color1.rgb[1] - color2.rgb[1]);
+        var b = Math.abs(color1.rgb[2] - color2.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    exclusion: function(color1, color2) {
+        var r = color1.rgb[0] + color2.rgb[0] * (255 - color1.rgb[0] - color1.rgb[0]) / 255;
+        var g = color1.rgb[1] + color2.rgb[1] * (255 - color1.rgb[1] - color1.rgb[1]) / 255;
+        var b = color1.rgb[2] + color2.rgb[2] * (255 - color1.rgb[2] - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    average: function(color1, color2) {
+        var r = (color1.rgb[0] + color2.rgb[0]) / 2;
+        var g = (color1.rgb[1] + color2.rgb[1]) / 2;
+        var b = (color1.rgb[2] + color2.rgb[2]) / 2;
+        return this.rgb(r, g, b);
+    },
+    negation: function(color1, color2) {
+        var r = 255 - Math.abs(255 - color2.rgb[0] - color1.rgb[0]);
+        var g = 255 - Math.abs(255 - color2.rgb[1] - color1.rgb[1]);
+        var b = 255 - Math.abs(255 - color2.rgb[2] - color1.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    tint: function(color, amount) {
+        return this.mix(this.rgb(255,255,255), color, amount);
+    },
+    shade: function(color, amount) {
+        return this.mix(this.rgb(0, 0, 0), color, amount);
+    }
+};
+
+function hsla(hsla) {
+    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        // 'transparent':'rgba(0,0,0,0)',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) {
+            return new(tree.Assignment)(this.key, this.value.eval(env));
+        }
+        return this;
+    }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+    this.filename = filename;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { type: e.type || "Runtime",
+                        message: "error evaluating function `" + this.name + "`" +
+                                 (e.message ? ': ' + e.message : ''),
+                        index: this.index, filename: this.filename };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS(env) }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    },
+    compare: function (x) {
+        if (!x.rgb) {
+            return -1;
+        }
+        
+        return (x.rgb[0] === this.rgb[0] &&
+            x.rgb[1] === this.rgb[1] &&
+            x.rgb[2] === this.rgb[2] &&
+            x.alpha === this.alpha) ? 0 : -1;
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+    this.op = op.trim();
+    this.lvalue = l;
+    this.rvalue = r;
+    this.index = i;
+    this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+    var a = this.lvalue.eval(env),
+        b = this.rvalue.eval(env);
+
+    var i = this.index, result;
+
+    var result = (function (op) {
+        switch (op) {
+            case 'and':
+                return a && b;
+            case 'or':
+                return a || b;
+            default:
+                if (a.compare) {
+                    result = a.compare(b);
+                } else if (b.compare) {
+                    result = b.compare(a);
+                } else {
+                    throw { type: "Type",
+                            message: "Unable to perform comparison",
+                            index: i };
+                }
+                switch (result) {
+                    case -1: return op === '<' || op === '=<';
+                    case  0: return op === '=' || op === '>=' || op === '=<';
+                    case  1: return op === '>' || op === '>=';
+                }
+        }
+    })(this.op);
+    return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    },
+
+    // TODO: Perform unit conversion before comparing
+    compare: function (other) {
+        if (other instanceof tree.Dimension) {
+            if (other.value > this.value) {
+                return -1;
+            } else if (other.value < this.value) {
+                return 1;
+            } else {
+                return 0;
+            }
+        } else {
+            return -1;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+        this.ruleset.allowImports = true;
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        var evaldDirective = this;
+        if (this.ruleset) {
+            env.frames.unshift(this);
+            evaldDirective = new(tree.Directive)(this.name);
+            evaldDirective.ruleset = this.ruleset.eval(env);
+            env.frames.shift();
+        }
+        return evaldDirective;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+
+    if (typeof(value) === 'string') {
+        this.value = value.trim();
+    } else if (value) {
+        this.value = value;
+    } else {
+        this.value = "";
+    }
+    this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+    return new(tree.Element)(this.combinator,
+                             this.value.eval ? this.value.eval(env) : this.value,
+                             this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+	var value = (this.value.toCSS ? this.value.toCSS(env) : this.value);
+	if (value == '' && this.combinator.value.charAt(0) == '&') {
+		return '';
+	} else {
+		return this.combinator.toCSS(env || {}) + value;
+	}
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        ':' : ' :',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS ? e.toCSS(env) : '';
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, once, index) {
+    var that = this;
+
+    this.once = once;
+    this.index = index;
+    this._path = path;
+    this.features = features && new(tree.Value)(features);
+
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /\.(le?|c)ss(\?.*)?$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css(\?.*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (e, root, imported) {
+            if (e) { e.index = index }
+            if (imported && that.once) that.skip = imported;
+            that.root = root || new(tree.Ruleset)([], []);
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function (env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.css) {
+            return "@import " + this._path.toCSS() + features + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset, features = this.features && this.features.eval(env);
+
+        if (this.skip) return [];
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    Array.prototype
+                         .splice
+                         .apply(ruleset.rules,
+                                [i, 1].concat(ruleset.rules[i].eval(env)));
+                }
+            }
+            return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value },
+    compare: function (other) {
+        if (other instanceof tree.Keyword) {
+            return other.value === this.value ? 0 : 1;
+        } else {
+            return -1;
+        }
+    }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Media = function (value, features) {
+    var selectors = this.emptySelectors();
+
+    this.features = new(tree.Value)(features);
+    this.ruleset = new(tree.Ruleset)(selectors, value);
+    this.ruleset.allowImports = true;
+};
+tree.Media.prototype = {
+    toCSS: function (ctx, env) {
+        var features = this.features.toCSS(env);
+
+        this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
+        return '@media ' + features + (env.compress ? '{' : ' {\n  ') +
+               this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                           (env.compress ? '}': '\n}\n');
+    },
+    eval: function (env) {
+        if (!env.mediaBlocks) {
+            env.mediaBlocks = [];
+            env.mediaPath = [];
+        }
+        
+        var blockIndex = env.mediaBlocks.length;
+        env.mediaPath.push(this);
+        env.mediaBlocks.push(this);
+
+        var media = new(tree.Media)([], []);
+        if(this.debugInfo) {
+            this.ruleset.debugInfo = this.debugInfo;
+            media.debugInfo = this.debugInfo;
+        }
+        media.features = this.features.eval(env);
+        
+        env.frames.unshift(this.ruleset);
+        media.ruleset = this.ruleset.eval(env);
+        env.frames.shift();
+        
+        env.mediaBlocks[blockIndex] = media;
+        env.mediaPath.pop();
+
+        return env.mediaPath.length === 0 ? media.evalTop(env) :
+                    media.evalNested(env)
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
+    emptySelectors: function() { 
+        var el = new(tree.Element)('', '&', 0);
+        return [new(tree.Selector)([el])];
+    },
+
+    evalTop: function (env) {
+        var result = this;
+
+        // Render all dependent Media blocks.
+        if (env.mediaBlocks.length > 1) {
+            var selectors = this.emptySelectors();
+            result = new(tree.Ruleset)(selectors, env.mediaBlocks);
+            result.multiMedia = true;
+        }
+
+        delete env.mediaBlocks;
+        delete env.mediaPath;
+
+        return result;
+    },
+    evalNested: function (env) {
+        var i, value,
+            path = env.mediaPath.concat([this]);
+
+        // Extract the media-query conditions separated with `,` (OR).
+        for (i = 0; i < path.length; i++) {
+            value = path[i].features instanceof tree.Value ?
+                        path[i].features.value : path[i].features;
+            path[i] = Array.isArray(value) ? value : [value];
+        }
+
+        // Trace all permutations to generate the resulting media-query.
+        //
+        // (a, b and c) with nested (d, e) ->
+        //    a and d
+        //    a and e
+        //    b and c and d
+        //    b and c and e
+        this.features = new(tree.Value)(this.permute(path).map(function (path) {
+            path = path.map(function (fragment) {
+                return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
+            });
+
+            for(i = path.length - 1; i > 0; i--) {
+                path.splice(i, 0, new(tree.Anonymous)("and"));
+            }
+
+            return new(tree.Expression)(path);
+        }));
+
+        // Fake a tree-node that doesn't output anything.
+        return new(tree.Ruleset)([], []);
+    },
+    permute: function (arr) {
+      if (arr.length === 0) {
+          return [];
+      } else if (arr.length === 1) {
+          return arr[0];
+      } else {
+          var result = [];
+          var rest = this.permute(arr.slice(1));
+          for (var i = 0; i < rest.length; i++) {
+              for (var j = 0; j < arr[0].length; j++) {
+                  result.push([arr[0][j]].concat(rest[i]));
+              }
+          }
+          return result;
+      }
+    },
+    bubbleSelectors: function (selectors) {
+      this.ruleset = new(tree.Ruleset)(selectors.slice(0), [this.ruleset]);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+    this.filename = filename;
+    this.important = important;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, args, rules = [], match = false;
+
+        for (var i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                args = this.arguments && this.arguments.map(function (a) {
+                    return { name: a.name, value: a.value.eval(env) };
+                });
+                for (var m = 0; m < mixins.length; m++) {
+                    if (mixins[m].match(args, env)) {
+                        try {
+                            Array.prototype.push.apply(
+                                  rules, mixins[m].eval(env, this.arguments, this.important).rules);
+                            match = true;
+                        } catch (e) {
+                            throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
+                        }
+                    }
+                }
+                if (match) {
+                    return rules;
+                } else {
+                    throw { type:    'Runtime',
+                            message: 'No matching definition was found for `' +
+                                      this.selector.toCSS().trim() + '('      +
+                                      this.arguments.map(function (a) {
+                                          return a.toCSS();
+                                      }).join(', ') + ")`",
+                            index:   this.index, filename: this.filename };
+                }
+            }
+        }
+        throw { type: 'Name',
+                message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index, filename: this.filename };
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition, variadic) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.condition = condition;
+    this.variadic = variadic;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    evalParams: function (env, args) {
+        var frame = new(tree.Ruleset)(null, []), varargs, arg;
+
+        for (var i = 0, val, name; i < this.params.length; i++) {
+            arg = args && args[i]
+
+            if (arg && arg.name) {
+                frame.rules.unshift(new(tree.Rule)(arg.name, arg.value.eval(env)));
+                args.splice(i, 1);
+                i--;
+                continue;
+            }
+			
+            if (name = this.params[i].name) {
+                if (this.params[i].variadic && args) {
+                    varargs = [];
+                    for (var j = i; j < args.length; j++) {
+                        varargs.push(args[j].value.eval(env));
+                    }
+                    frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
+                } else if (val = (arg && arg.value) || this.params[i].value) {
+                    frame.rules.unshift(new(tree.Rule)(name, val.eval(env)));
+                } else {
+                    throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                }
+            }
+        }
+        return frame;
+    },
+    eval: function (env, args, important) {
+        var frame = this.evalParams(env, args), context, _arguments = [], rules, start;
+
+        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
+            _arguments.push((args[i] && args[i].value) || this.params[i].value);
+        }
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        rules = important ?
+            this.rules.map(function (r) {
+                return new(tree.Rule)(r.name, r.value, '!important', r.index);
+            }) : this.rules.slice(0);
+
+        return new(tree.Ruleset)(null, rules).eval({
+            frames: [this, frame].concat(this.frames, env.frames)
+        });
+    },
+    match: function (args, env) {
+        var argsLength = (args && args.length) || 0, len, frame;
+
+        if (! this.variadic) {
+            if (argsLength < this.required)                               { return false }
+            if (argsLength > this.params.length)                          { return false }
+            if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+        }
+
+        if (this.condition && !this.condition.eval({
+            frames: [this.evalParams(env, args)].concat(env.frames)
+        }))                                                           { return false }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name) {
+                if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+    this.value = node;
+};
+tree.Paren.prototype = {
+    toCSS: function (env) {
+        return '(' + this.value.toCSS(env) + ')';
+    },
+    eval: function (env) {
+        return new(tree.Paren)(this.value.eval(env));
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return ('value' in v) ? v.value : v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ratio = function (value) {
+    this.value = value;
+};
+tree.Ratio.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+    this.inline = inline || false;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + (this.inline ? "" : ";");
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name,
+                          this.value.eval(context),
+                          this.important,
+                          this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules, strictImports) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+    this.strictImports = strictImports;
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
+        var rules = [];
+        
+        ruleset.root = this.root;
+        ruleset.allowImports = this.allowImports;
+
+        if(this.debugInfo) {
+            ruleset.debugInfo = this.debugInfo;
+        }
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
+            for (var i = 0; i < ruleset.rules.length; i++) {
+                if (ruleset.rules[i] instanceof tree.Import) {
+                    rules = rules.concat(ruleset.rules[i].eval(env));
+                } else {
+                    rules.push(ruleset.rules[i]);
+                }
+            }
+            ruleset.rules = rules;
+            rules = [];
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+        
+        var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0;
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                rules = rules.concat(ruleset.rules[i].eval(env));
+            } else {
+                rules.push(ruleset.rules[i]);
+            }
+        }
+        ruleset.rules = rules;
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+        
+        if (env.mediaBlocks) {
+            for(var i = mediaBlockCount; i < env.mediaBlocks.length; i++) {
+                env.mediaBlocks[i].bubbleSelectors(selectors);
+            }
+        }
+
+        return ruleset;
+    },
+    match: function (args) {
+        return !args || args.length === 0;
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+           _rules = [],    //
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            debugInfo,     // Line number debugging
+            rule;
+
+        if (! this.root) {
+            this.joinSelectors(paths, context, this.selectors);
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Directive) || (rule instanceof tree.Media)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                debugInfo = tree.debugInfo(env, this);
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : ',\n');
+
+                // Remove duplicates
+                for (var i = rules.length - 1; i >= 0; i--) {
+                    if (_rules.indexOf(rules[i]) === -1) {
+                        _rules.unshift(rules[i]);
+                    }
+                }
+                rules = _rules;
+
+                css.push(debugInfo + selector + 
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('')  + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+
+        var i, j, k, 
+            hasParentSelector, newSelectors, el, sel, parentSel, 
+            newSelectorPath, afterParentJoin, newJoinedSelector, 
+            newJoinedSelectorEmpty, lastSelector, currentElements,
+            selectorsMultiplied;
+    
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.value === '&') {
+                hasParentSelector = true;
+            }
+        }
+    
+        if (!hasParentSelector) {
+            if (context.length > 0) {
+                for(i = 0; i < context.length; i++) {
+                    paths.push(context[i].concat(selector));
+                }
+            }
+            else {
+                paths.push([selector]);
+            }
+            return;
+        }
+
+        // The paths are [[Selector]]
+        // The first list is a list of comma seperated selectors
+        // The inner list is a list of inheritance seperated selectors
+        // e.g.
+        // .a, .b {
+        //   .c {
+        //   }
+        // }
+        // == [[.a] [.c]] [[.b] [.c]]
+        //
+
+        // the elements from the current selector so far
+        currentElements = [];
+        // the current list of new selectors to add to the path.
+        // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
+        // by the parents
+        newSelectors = [[]];
+
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            // non parent reference elements just get added
+            if (el.value !== "&") {
+                currentElements.push(el);
+            } else {
+                // the new list of selectors to add
+                selectorsMultiplied = [];
+
+                // merge the current list of non parent selector elements
+                // on to the current list of selectors to add
+                if (currentElements.length > 0) {
+                    this.mergeElementsOnToSelectors(currentElements, newSelectors);
+                }
+
+                // loop through our current selectors
+                for(j = 0; j < newSelectors.length; j++) {
+                    sel = newSelectors[j];
+                    // if we don't have any parent paths, the & might be in a mixin so that it can be used
+                    // whether there are parents or not
+                    if (context.length == 0) {
+                        // the combinator used on el should now be applied to the next element instead so that
+                        // it is not lost
+                        if (sel.length > 0) {
+                            sel[0].elements = sel[0].elements.slice(0);
+                            sel[0].elements.push(new(tree.Element)(el.combinator, '', 0)); //new Element(el.Combinator,  ""));
+                        }
+                        selectorsMultiplied.push(sel);
+                    }
+                    else {
+                        // and the parent selectors
+                        for(k = 0; k < context.length; k++) {
+                            parentSel = context[k];
+                            // We need to put the current selectors
+                            // then join the last selector's elements on to the parents selectors
+
+                            // our new selector path
+                            newSelectorPath = [];
+                            // selectors from the parent after the join
+                            afterParentJoin = [];
+                            newJoinedSelectorEmpty = true;
+
+                            //construct the joined selector - if & is the first thing this will be empty,
+                            // if not newJoinedSelector will be the last set of elements in the selector
+                            if (sel.length > 0) {
+                                newSelectorPath = sel.slice(0);
+                                lastSelector = newSelectorPath.pop();
+                                newJoinedSelector = new(tree.Selector)(lastSelector.elements.slice(0));
+                                newJoinedSelectorEmpty = false;
+                            }
+                            else {
+                                newJoinedSelector = new(tree.Selector)([]);
+                            }
+
+                            //put together the parent selectors after the join
+                            if (parentSel.length > 1) {
+                                afterParentJoin = afterParentJoin.concat(parentSel.slice(1));
+                            }
+
+                            if (parentSel.length > 0) {
+                                newJoinedSelectorEmpty = false;
+
+                                // join the elements so far with the first part of the parent
+                                newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, 0));
+                                newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1));
+                            }
+
+                            if (!newJoinedSelectorEmpty) {
+                                // now add the joined selector
+                                newSelectorPath.push(newJoinedSelector);
+                            }
+
+                            // and the rest of the parent
+                            newSelectorPath = newSelectorPath.concat(afterParentJoin);
+
+                            // add that to our new set of selectors
+                            selectorsMultiplied.push(newSelectorPath);
+                        }
+                    }
+                }
+
+                // our new selectors has been multiplied, so reset the state
+                newSelectors = selectorsMultiplied;
+                currentElements = [];
+            }
+        }
+
+        // if we have any elements left over (e.g. .a& .b == .b)
+        // add them on to all the current selectors
+        if (currentElements.length > 0) {
+            this.mergeElementsOnToSelectors(currentElements, newSelectors);
+        }
+
+        for(i = 0; i < newSelectors.length; i++) {
+            paths.push(newSelectors[i]);
+        }
+    },
+    
+    mergeElementsOnToSelectors: function(elements, selectors) {
+        var i, sel;
+
+        if (selectors.length == 0) {
+            selectors.push([ new(tree.Selector)(elements) ]);
+            return;
+        }
+
+        for(i = 0; i < selectors.length; i++) {
+            sel = selectors[i];
+
+            // if the previous thing in sel is a parent this needs to join on to it
+            if (sel.length > 0) {
+                sel[sel.length - 1] = new(tree.Selector)(sel[sel.length - 1].elements.concat(elements));
+            }
+            else {
+                sel.push(new(tree.Selector)(elements));
+            }
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+};
+tree.Selector.prototype.match = function (other) {
+    var len  = this.elements.length,
+        olen = other.elements.length,
+        max  = Math.min(len, olen);
+
+    if (len < olen) {
+        return false;
+    } else {
+        for (var i = 0; i < max; i++) {
+            if (this.elements[i].value !== other.elements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.eval = function (env) {
+    return new(tree.Selector)(this.elements.map(function (e) {
+        return e.eval(env);
+    }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+    
+    if (this.elements[0].combinator.value === "") {
+        this._css = ' ';
+    } else {
+        this._css = '';
+    }
+    
+    this._css += this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+    
+    return this._css;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, paths) {
+    this.value = val;
+    this.paths = paths;
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + this.value.toCSS() + ")";
+    },
+    eval: function (ctx) {
+        var val = this.value.eval(ctx);
+
+        // Add the base path if the URL is relative and we are in the browser
+        if (typeof window !== 'undefined' && typeof val.value === "string" && !/^(?:[a-z-]+:|\/)/.test(val.value) && this.paths.length > 0) {
+            val.value = this.paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
+        }
+
+        return new(tree.URL)(val, this.paths);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { return variable }
+        else {
+            throw { type: 'Name',
+                    message: "variable " + name + " is undefined",
+                    filename: this.file,
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.debugInfo = function(env, ctx) {
+    var result="";
+    if (env.dumpLineNumbers && !env.compress) {
+        switch(env.dumpLineNumbers) {
+            case 'comments':
+                result = tree.debugInfo.asComment(ctx);
+                break;
+            case 'mediaquery':
+                result = tree.debugInfo.asMediaQuery(ctx);
+                break;
+            case 'all':
+                result = tree.debugInfo.asComment(ctx)+tree.debugInfo.asMediaQuery(ctx);
+                break;
+        }
+    }
+    return result;
+};
+
+tree.debugInfo.asComment = function(ctx) {
+    return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
+};
+
+tree.debugInfo.asMediaQuery = function(ctx) {
+    return '@media -sass-debug-info{filename{font-family:"' + ctx.debugInfo.fileName + '";}line{font-family:"' + ctx.debugInfo.lineNumber + '";}}\n';
+};
+
+tree.find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+tree.jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+
+})(require('./tree'));
+var name;
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var endOfPath = Math.max(name.lastIndexOf('/'), name.lastIndexOf('\\')),
+        sheetName = name.slice(0, endOfPath + 1) + sheet.href,
+        contents = sheet.contents || {},
+        input = readFile(sheetName);
+        
+    contents[sheetName] = input;
+        
+    var parser = new less.Parser({
+        paths: [sheet.href.replace(/[\w\.-]+$/, '')],
+        contents: contents
+    });
+    parser.parse(input, function (e, root) {
+        if (e) {
+            return error(e, sheetName);
+        }
+        try {
+            callback(e, root, sheet, { local: false, lastModified: 0, remaining: remaining });
+        } catch(e) {
+            error(e, sheetName);
+        }
+    });
+}
+
+function writeFile(filename, content) {
+    var fstream = new java.io.FileWriter(filename);
+    var out = new java.io.BufferedWriter(fstream);
+    out.write(content);
+    out.close();
+}
+
+// Command line integration via Rhino
+(function (args) {
+    var output,
+        compress = false,
+        i;
+        
+    for(i = 0; i < args.length; i++) {
+        switch(args[i]) {
+            case "-x":
+                compress = true;
+                break;
+            default:
+                if (!name) {
+                    name = args[i];
+                } else if (!output) {
+                    output = args[i];
+                } else {
+                    print("unrecognised parameters");
+                    print("input_file [output_file] [-x]");
+                }
+        }
+    }
+
+    if (!name) {
+        print('No files present in the fileset; Check your pattern match in build.xml');
+        quit(1);
+    }
+    path = name.split("/");path.pop();path=path.join("/")
+
+    var input = readFile(name);
+
+    if (!input) {
+        print('lesscss: couldn\'t open file ' + name);
+        quit(1);
+    }
+
+    var result;
+    try {
+        var parser = new less.Parser();
+        parser.parse(input, function (e, root) {
+            if (e) {
+                error(e, name);
+                quit(1);
+            } else {
+                result = root.toCSS({compress: compress || false});
+                if (output) {
+                    writeFile(output, result);
+                    print("Written to " + output);
+                } else {
+                    print(result);
+                }
+                quit(0);
+            }
+        });
+    }
+    catch(e) {
+        error(e, name);
+        quit(1);
+    }
+    print("done");
+}(arguments));
+
+function error(e, filename) {
+
+    var content = "Error : " + filename + "\n";
+    
+    filename = e.filename || filename;
+    
+    if (e.message) {
+        content += e.message + "\n";
+    }
+
+    var errorline = function (e, i, classname) {
+        if (e.extract[i]) {
+            content += 
+                String(parseInt(e.line) + (i - 1)) + 
+                ":" + e.extract[i] + "\n";
+        }
+    };
+
+    if (e.stack) {
+        content += e.stack;
+    } else if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n';
+        errorline(e, 0);
+        errorline(e, 1);
+        errorline(e, 2);
+    }
+   print(content);
+}
\ No newline at end of file
diff --git a/util/less/dist/less-rhino-1.3.2.js b/util/less/dist/less-rhino-1.3.2.js
new file mode 100644
index 0000000..4b83596
--- /dev/null
+++ b/util/less/dist/less-rhino-1.3.2.js
@@ -0,0 +1,3990 @@
+//
+// Stub out `require` in rhino
+//
+function require(arg) {
+    return less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree, charset;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    if (typeof(window) === 'undefined') { less = {} }
+    else                                { less = window.less = {} }
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // Top parser on an import tree must be sure there is one "env"
+    // which will then be passed arround by reference.
+    var env = env || { };
+    // env.contents and files must be passed arround with top env
+    if (!env.contents) { env.contents = {}; }
+    env.rootpath = env.rootpath || '';       // env.rootpath must be initialized to '' if not provided
+    if (!env.files) { env.files = {}; }
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env.paths || [],  // Search paths, when importing
+        queue: [],               // Files which haven't been imported yet
+        files: env.files,        // Holds the imported parse trees
+        contents: env.contents,  // Holds the imported file contents
+        mime:  env.mime,         // MIME type of .less files
+        error: null,             // Error in parsing/evaluating an import
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (e, root, fullPath) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+
+                var imported = fullPath in that.files;
+
+                that.files[fullPath] = root;                        // Store the root
+
+                if (e && !that.error) { that.error = e }
+
+                callback(e, root, imported);
+
+                if (that.queue.length === 0) { finish(that.error) }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    function isWhitespace(c) {
+        // Could change to \s?
+        var code = c.charCodeAt(0);
+        return code === 32 || code === 10 || code === 9;
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, index, k;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            skipWhitespace(length);
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    function skipWhitespace(length) {
+        var oldi = i, oldj = j,
+            endIndex = i + chunks[j].length,
+            mem = i += length;
+
+        while (i < endIndex) {
+            if (! isWhitespace(input.charAt(i))) { break }
+            i++;
+        }
+        chunks[j] = chunks[j].slice(length + (i - mem));
+        current = i;
+
+        if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+        return oldi !== i || oldj !== j;
+    }
+
+    function expect(arg, msg) {
+        var result = $(arg);
+        if (! result) {
+            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+                                                   : "unexpected token"));
+        } else {
+            return result;
+        }
+    }
+
+    function error(msg, type) {
+        var e = new Error(msg);
+        e.index = i;
+        e.type = type || 'Syntax';
+        throw e;
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    function getInput(e, env) {
+        if (e.filename && env.filename && (e.filename !== env.filename)) {
+            return parser.imports.contents[e.filename];
+        } else {
+            return input;
+        }
+    }
+
+    function getLocation(index, input) {
+        for (var n = index, column = -1;
+                 n >= 0 && input.charAt(n) !== '\n';
+                 n--) { column++ }
+
+        return { line:   typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+                 column: column };
+    }
+
+    function getFileName(e) {
+        if(less.mode === 'browser' || less.mode === 'rhino')
+            return e.filename;
+        else
+            return require('path').resolve(e.filename);
+    }
+
+    function getDebugInfo(index, inputStream, e) {
+        return {
+            lineNumber: getLocation(index, inputStream).line + 1,
+            fileName: getFileName(e)
+        };
+    }
+
+    function LessError(e, env) {
+        var input = getInput(e, env),
+            loc = getLocation(e.index, input),
+            line = loc.line,
+            col  = loc.column,
+            lines = input.split('\n');
+
+        this.type = e.type || 'Syntax';
+        this.message = e.message;
+        this.filename = e.filename || env.filename;
+        this.index = e.index;
+        this.line = typeof(line) === 'number' ? line + 1 : null;
+        this.callLine = e.call && (getLocation(e.call, input).line + 1);
+        this.callExtract = lines[getLocation(e.call, input).line];
+        this.stack = e.stack;
+        this.column = col;
+        this.extract = [
+            lines[line - 1],
+            lines[line],
+            lines[line + 1]
+        ];
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            input = str.replace(/\r\n/g, '\n');
+
+            // Remove potential UTF Byte Order Mark
+            input = input.replace(/^\uFEFF/, '');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam;
+
+                for (var i = 0, c, cc; i < input.length;) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = string.lastIndex = i;
+
+                    if (match = string.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                            continue;
+                        }
+                    }
+
+                    if (!inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    continue;
+                                }
+                            }
+                        }
+                    }
+                    
+                    switch (c) {
+                        case '{': if (! inParam) { level ++;        chunk.push(c);                           break }
+                        case '}': if (! inParam) { level --;        chunk.push(c); chunks[++j] = chunk = []; break }
+                        case '(': if (! inParam) { inParam = true;  chunk.push(c);                           break }
+                        case ')': if (  inParam) { inParam = false; chunk.push(c);                           break }
+                        default:                                    chunk.push(c);
+                    }
+                    
+                    i++;
+                }
+                if (level != 0) {
+                    error = new(LessError)({
+                        index: i-1,
+                        type: 'Parse',
+                        message: (level > 0) ? "missing closing `}`" : "missing opening `{`",
+                        filename: env.filename
+                    }, env);
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            if (error) {
+                return callback(error, env);
+            }
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            try {
+                root = new(tree.Ruleset)([], $(this.parsers.primary));
+                root.root = true;
+            } catch (e) {
+                return callback(new(LessError)(e, env));
+            }
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [], importError;
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false, dumpLineNumbers: env.dumpLineNumbers });
+                    } catch (e) {
+                        throw new(LessError)(e, env);
+                    }
+
+                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
+                        if (importError instanceof LessError) throw importError;
+                        else                                  throw new(LessError)(importError, env);
+                    }
+
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('ycssmin').cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    type: "Parse",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function (e) {
+                    e = error || e;
+                    if (e) callback(e);
+                    else callback(null, root);
+                };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/) || $(/^;+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k);
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, nameLC, args, alpha_ret, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1];
+                    nameLC = name.toLowerCase();
+
+                    if (nameLC === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (nameLC === 'alpha') {
+                        alpha_ret = $(this.alpha);
+                        if(typeof alpha_ret !== 'undefined') {
+                            return alpha_ret;
+                        }
+                    }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index, env.filename) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.ratio) ||
+                           $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted) ||
+                           $(this.entities.unicodeDescriptor);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || "";
+
+                    expect(')');
+
+                    return new(tree.URL)((value.value != null || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), env.rootpath);
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index, env.filename);
+                    }
+                },
+
+                // A variable entity useing the protective {} e.g. @{var}
+                variableCurly: function () {
+                    var name, curly, index = i;
+
+                    if (input.charAt(i) === '@' && (curly = $(/^@\{([\w-]+)\}/))) {
+                        return new(tree.Variable)("@" + curly[1], index, env.filename);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    //Is the first char of the dimension 0-9, '.', '+' or '-'
+                    if ((c > 57 || c < 43) || c === 47 || c == 44) return;
+
+                    if (value = $(/^([+-]?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn|dpi|dpcm|dppx|rem|vw|vh|vmin|vm|ch)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // A Ratio
+                //
+                //    16/9
+                //
+                ratio: function () {
+                  var value, c = input.charCodeAt(i);
+                  if (c > 57 || c < 48) return;
+
+                  if (value = $(/^(\d+\/\d+)/)) {
+                    return new(tree.Ratio)(value[1]);
+                  }
+                },
+                
+                //
+                // A unicode descriptor, as is used in unicode-range
+                //
+                // U+0??  or U+00A1-00A9
+                //
+                unicodeDescriptor: function () {
+                    var ud;
+                    
+                    if (ud = $(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/)) {
+                        return new(tree.UnicodeDescriptor)(ud[0]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                save();
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+
+                restore();
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, argsSemiColon = [], argsComma = [], args, delim, arg, nameLoop, expressions, isSemiColonSeperated, expressionContainsNamed, index = i, s = input.charAt(i), name, value, important = false;
+
+                    if (s !== '.' && s !== '#') { return }
+                    
+                    save(); // stop us absorbing part of an invalid selector
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    if ($('(')) {
+                        expressions = [];
+                        while (arg = $(this.expression)) {
+                            nameLoop = null;
+                            value = arg;
+
+                            // Variable
+                            if (arg.value.length == 1) {
+                                var val = arg.value[0];
+                                if (val instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        if (expressions.length > 0) {
+                                            if (isSemiColonSeperated) {
+                                                error("Cannot mix ; and , as delimiter types");
+                                            }
+                                            expressionContainsNamed = true;
+                                        }
+                                        value = expect(this.expression);
+                                        nameLoop = (name = val.name);
+                                    }
+                                }
+                            }
+                            
+                            expressions.push(value);
+                            
+                            argsComma.push({ name: nameLoop, value: value });
+                            
+                            if ($(',')) {
+                                continue;
+                            }
+                            
+                            if ($(';') || isSemiColonSeperated) {
+                            
+                                if (expressionContainsNamed) {
+                                    error("Cannot mix ; and , as delimiter types");
+                                }
+                            
+                                isSemiColonSeperated = true;
+                                                        
+                                if (expressions.length > 1) {
+                                    value = new(tree.Value)(expressions);
+                                }
+                                argsSemiColon.push({ name: name, value: value });
+                            
+                                name = null;
+                                expressions = [];
+                                expressionContainsNamed = false;
+                            }
+                        }
+
+                        expect(')');
+                    }
+
+                    args = isSemiColonSeperated ? argsSemiColon : argsComma;
+
+                    if ($(this.important)) {
+                        important = true;
+                    }
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+                    }
+                    
+                    restore();
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value, cond, variadic = false;
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*\}/)) return;
+
+                    save();
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        do {
+                            $(this.comment);
+                            if (input.charAt(i) === '.' && $(/^\.{3}/)) {
+                                variadic = true;
+                                params.push({ variadic: true });
+                                break;
+                            } else if (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                         || $(this.entities.keyword)) {
+                                // Variable
+                                if (param instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        value = expect(this.expression, 'expected expression');
+                                        params.push({ name: param.name, value: value });
+                                    } else if ($(/^\.{3}/)) {
+                                        params.push({ name: param.name, variadic: true });
+                                        variadic = true;
+                                        break;
+                                    } else {
+                                        params.push({ name: param.name });
+                                    }
+                                } else {
+                                    params.push({ value: param });
+                                }
+                            } else {
+                                break;
+                            }
+                        } while ($(',') || $(';'))
+
+                        // .mixincall("@{a}"); 
+                        // looks a bit like a mixin definition.. so we have to be nice and restore
+                        if (!$(')')) {
+                            furthest = i;
+                            restore();
+                        }
+                        
+                        $(this.comment);
+
+                        if ($(/^when/)) { // Guard
+                            cond = expect(this.conditions, 'expected condition');
+                        }
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
+                        } else {
+                            restore();
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  ||$(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    expect(')');
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c, v;
+
+                c = $(this.combinator);
+
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
+                    $('*') || $('&') || $(this.attribute) || $(/^\([^()@]+\)/) || $(/^[\.#](?=@)/) || $(this.entities.variableCurly);
+
+                if (! e) {
+                    if ($('(')) {
+                        if ((v = ($(this.entities.variableCurly) || 
+                                $(this.entities.variable) || 
+                                $(this.selector))) && 
+                                $(')')) {
+                            e = new(tree.Paren)(v);
+                        }
+                    }
+                }
+
+                if (e) { return new(tree.Element)(c, e, i) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~' || c === '|') {
+                    i++;
+                    while (input.charAt(i).match(/\s/)) { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (input.charAt(i - 1).match(/\s/)) {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                // depreciated, will be removed soon
+                if ($('(')) {
+                    sel = $(this.entity);
+                    expect(')');
+                    return new(tree.Selector)([new(tree.Element)('', sel, i)]);
+                }
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^(?:[_A-Za-z0-9-]|\\.)+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match, debugInfo;
+                save();
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports);
+                    if (env.dumpLineNumbers)
+                        ruleset.debugInfo = debugInfo;
+                    return ruleset;
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path, features, index = i;
+                
+                save();
+                
+                var dir = $(/^@import(?:-(once))?\s+/);
+
+                if (dir && (path = $(this.entities.quoted) || $(this.entities.url))) {
+                    features = $(this.mediaFeatures);
+                    if ($(';')) {
+                        return new(tree.Import)(path, imports, features, (dir[1] === 'once'), index, env.rootpath);
+                    }
+                }
+                
+                restore();
+            },
+
+            mediaFeature: function () {
+                var e, p, nodes = [];
+
+                do {
+                    if (e = $(this.entities.keyword)) {
+                        nodes.push(e);
+                    } else if ($('(')) {
+                        p = $(this.property);
+                        e = $(this.entity);
+                        if ($(')')) {
+                            if (p && e) {
+                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+                            } else if (e) {
+                                nodes.push(new(tree.Paren)(e));
+                            } else {
+                                return null;
+                            }
+                        } else { return null }
+                    }
+                } while (e);
+
+                if (nodes.length > 0) {
+                    return new(tree.Expression)(nodes);
+                }
+            },
+
+            mediaFeatures: function () {
+                var e, features = [];
+
+                do {
+                  if (e = $(this.mediaFeature)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  } else if (e = $(this.entities.variable)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  }
+                } while (e);
+
+                return features.length > 0 ? features : null;
+            },
+
+            media: function () {
+                var features, rules, media, debugInfo;
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                if ($(/^@media/)) {
+                    features = $(this.mediaFeatures);
+
+                    if (rules = $(this.block)) {
+                        media = new(tree.Media)(rules, features);
+                        if(env.dumpLineNumbers)
+                            media.debugInfo = debugInfo;
+                        return media;
+                    }
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, identifier, e, nodes, nonVendorSpecificName,
+                    hasBlock, hasIdentifier, hasExpression;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import']) || $(this.media)) {
+                    return value;
+                }
+                
+                save();
+
+                name = $(/^@[a-z-]+/);
+                
+                if (!name) return;
+
+                nonVendorSpecificName = name;
+                if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
+                    nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
+                }
+
+                switch(nonVendorSpecificName) {
+                    case "@font-face":
+                        hasBlock = true;
+                        break;
+                    case "@viewport":
+                    case "@top-left":
+                    case "@top-left-corner":
+                    case "@top-center":
+                    case "@top-right":
+                    case "@top-right-corner":
+                    case "@bottom-left":
+                    case "@bottom-left-corner":
+                    case "@bottom-center":
+                    case "@bottom-right":
+                    case "@bottom-right-corner":
+                    case "@left-top":
+                    case "@left-middle":
+                    case "@left-bottom":
+                    case "@right-top":
+                    case "@right-middle":
+                    case "@right-bottom":
+                        hasBlock = true;
+                        break;
+                    case "@page":
+                    case "@document":
+                    case "@supports":
+                    case "@keyframes":
+                        hasBlock = true;
+                        hasIdentifier = true;
+                        break;
+                    case "@namespace":
+                        hasExpression = true;
+                        break;
+                }
+
+                if (hasIdentifier) {
+                    name += " " + ($(/^[^{]+/) || '').trim();
+                }
+
+                if (hasBlock)
+                {
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name, rules);
+                    }
+                } else {
+                    if ((value = hasExpression ? $(this.expression) : $(this.entity)) && $(';')) {
+                        var directive = new(tree.Directive)(name, value);
+                        if (env.dumpLineNumbers) {
+                            directive.debugInfo = getDebugInfo(i, input, env);
+                        }
+                        return directive;
+                    }
+                }
+                
+                restore();
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/[*\/]/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (!isWhitespace(input.charAt(i - 1)) && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            conditions: function () {
+                var a, b, index = i, condition;
+
+                if (a = $(this.condition)) {
+                    while ($(',') && (b = $(this.condition))) {
+                        condition = new(tree.Condition)('or', condition || a, b, index);
+                    }
+                    return condition || a;
+                }
+            },
+            condition: function () {
+                var a, b, c, op, index = i, negate = false;
+
+                if ($(/^not/)) { negate = true }
+                expect('(');
+                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                    if (op = $(/^(?:>=|=<|[<=>])/)) {
+                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                            c = new(tree.Condition)(op, a, b, index, negate);
+                        } else {
+                            error('expected expression');
+                        }
+                    } else {
+                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+                    }
+                    expect(')');
+                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[_a-z0-9-]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (!/^([a-z-]+:)?\//.test(path) && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ 
+            href: path, 
+            title: path, 
+            type: env.mime, 
+            contents: env.contents, 
+            files: env.files, 
+            rootpath: env.rootpath,
+            entryPath: env.entryPath,
+            relativeUrls: env.relativeUrls }, 
+        function (e, root, data, sheet, _, path) {
+            if (e && typeof(env.errback) === "function") {
+                env.errback.call(null, path, paths, callback, env);
+            } else {
+                callback.call(null, e, root, path);
+            }
+        }, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return scaled(c, 256); });
+        a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+
+    hsv: function(h, s, v) {
+        return this.hsva(h, s, v, 1.0);
+    },
+
+    hsva: function(h, s, v, a) {
+        h = ((number(h) % 360) / 360) * 360;
+        s = number(s); v = number(v); a = number(a);
+
+        var i, f;
+        i = Math.floor((h / 60) % 6);
+        f = (h / 60) - i;
+
+        var vs = [v,
+                  v * (1 - s),
+                  v * (1 - f * s),
+                  v * (1 - (1 - f) * s)];
+        var perm = [[0, 3, 1],
+                    [2, 0, 1],
+                    [1, 0, 3],
+                    [1, 2, 0],
+                    [3, 1, 0],
+                    [0, 1, 2]];
+
+        return this.rgba(vs[perm[i][0]] * 255,
+                         vs[perm[i][1]] * 255,
+                         vs[perm[i][2]] * 255,
+                         a);
+    },
+
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    red: function (color) {
+        return new(tree.Dimension)(color.rgb[0]);
+    },
+    green: function (color) {
+        return new(tree.Dimension)(color.rgb[1]);
+    },
+    blue: function (color) {
+        return new(tree.Dimension)(color.rgb[2]);
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    luma: function (color) {
+        return new(tree.Dimension)(Math.round((0.2126 * (color.rgb[0]/255) +
+            0.7152 * (color.rgb[1]/255) +
+            0.0722 * (color.rgb[2]/255)) *
+            color.alpha * 100), '%');
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        if (!weight) {
+            weight = new(tree.Dimension)(50);
+        }
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    contrast: function (color, dark, light, threshold) {
+        if (typeof light === 'undefined') {
+            light = this.rgba(255, 255, 255, 1.0);
+        }
+        if (typeof dark === 'undefined') {
+            dark = this.rgba(0, 0, 0, 1.0);
+        }
+        if (typeof threshold === 'undefined') {
+            threshold = 0.43;
+        } else {
+            threshold = threshold.value;
+        }
+        if (((0.2126 * (color.rgb[0]/255) + 0.7152 * (color.rgb[1]/255) + 0.0722 * (color.rgb[2]/255)) * color.alpha) < threshold) {
+            return light;
+        } else {
+            return dark;
+        }
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    unit: function (val, unit) {
+        return new(tree.Dimension)(val.value, unit ? unit.toCSS() : "");
+    },
+    round: function (n, f) {
+        var fraction = typeof(f) === "undefined" ? 0 : f.value;
+        return this._math(function(num) { return num.toFixed(fraction); }, n);
+    },
+    ceil: function (n) {
+        return this._math(Math.ceil, n);
+    },
+    floor: function (n) {
+        return this._math(Math.floor, n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(fn(parseFloat(n.value)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return fn(n);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    },
+    percentage: function (n) {
+        return new(tree.Dimension)(n.value * 100, '%');
+    },
+    color: function (n) {
+        if (n instanceof tree.Quoted) {
+            return new(tree.Color)(n.value.slice(1));
+        } else {
+            throw { type: "Argument", message: "argument must be a string" };
+        }
+    },
+    iscolor: function (n) {
+        return this._isa(n, tree.Color);
+    },
+    isnumber: function (n) {
+        return this._isa(n, tree.Dimension);
+    },
+    isstring: function (n) {
+        return this._isa(n, tree.Quoted);
+    },
+    iskeyword: function (n) {
+        return this._isa(n, tree.Keyword);
+    },
+    isurl: function (n) {
+        return this._isa(n, tree.URL);
+    },
+    ispixel: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+    },
+    ispercentage: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+    },
+    isem: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+    },
+    _isa: function (n, Type) {
+        return (n instanceof Type) ? tree.True : tree.False;
+    },
+    
+    /* Blending modes */
+    
+    multiply: function(color1, color2) {
+        var r = color1.rgb[0] * color2.rgb[0] / 255;
+        var g = color1.rgb[1] * color2.rgb[1] / 255;
+        var b = color1.rgb[2] * color2.rgb[2] / 255;
+        return this.rgb(r, g, b);
+    },
+    screen: function(color1, color2) {
+        var r = 255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = 255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = 255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    overlay: function(color1, color2) {
+        var r = color1.rgb[0] < 128 ? 2 * color1.rgb[0] * color2.rgb[0] / 255 : 255 - 2 * (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = color1.rgb[1] < 128 ? 2 * color1.rgb[1] * color2.rgb[1] / 255 : 255 - 2 * (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = color1.rgb[2] < 128 ? 2 * color1.rgb[2] * color2.rgb[2] / 255 : 255 - 2 * (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    softlight: function(color1, color2) {
+        var t = color2.rgb[0] * color1.rgb[0] / 255;
+        var r = t + color1.rgb[0] * (255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255 - t) / 255;
+        t = color2.rgb[1] * color1.rgb[1] / 255;
+        var g = t + color1.rgb[1] * (255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255 - t) / 255;
+        t = color2.rgb[2] * color1.rgb[2] / 255;
+        var b = t + color1.rgb[2] * (255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255 - t) / 255;
+        return this.rgb(r, g, b);
+    },
+    hardlight: function(color1, color2) {
+        var r = color2.rgb[0] < 128 ? 2 * color2.rgb[0] * color1.rgb[0] / 255 : 255 - 2 * (255 - color2.rgb[0]) * (255 - color1.rgb[0]) / 255;
+        var g = color2.rgb[1] < 128 ? 2 * color2.rgb[1] * color1.rgb[1] / 255 : 255 - 2 * (255 - color2.rgb[1]) * (255 - color1.rgb[1]) / 255;
+        var b = color2.rgb[2] < 128 ? 2 * color2.rgb[2] * color1.rgb[2] / 255 : 255 - 2 * (255 - color2.rgb[2]) * (255 - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    difference: function(color1, color2) {
+        var r = Math.abs(color1.rgb[0] - color2.rgb[0]);
+        var g = Math.abs(color1.rgb[1] - color2.rgb[1]);
+        var b = Math.abs(color1.rgb[2] - color2.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    exclusion: function(color1, color2) {
+        var r = color1.rgb[0] + color2.rgb[0] * (255 - color1.rgb[0] - color1.rgb[0]) / 255;
+        var g = color1.rgb[1] + color2.rgb[1] * (255 - color1.rgb[1] - color1.rgb[1]) / 255;
+        var b = color1.rgb[2] + color2.rgb[2] * (255 - color1.rgb[2] - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    average: function(color1, color2) {
+        var r = (color1.rgb[0] + color2.rgb[0]) / 2;
+        var g = (color1.rgb[1] + color2.rgb[1]) / 2;
+        var b = (color1.rgb[2] + color2.rgb[2]) / 2;
+        return this.rgb(r, g, b);
+    },
+    negation: function(color1, color2) {
+        var r = 255 - Math.abs(255 - color2.rgb[0] - color1.rgb[0]);
+        var g = 255 - Math.abs(255 - color2.rgb[1] - color1.rgb[1]);
+        var b = 255 - Math.abs(255 - color2.rgb[2] - color1.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    tint: function(color, amount) {
+        return this.mix(this.rgb(255,255,255), color, amount);
+    },
+    shade: function(color, amount) {
+        return this.mix(this.rgb(0, 0, 0), color, amount);
+    }
+};
+
+function hsla(color) {
+    return tree.functions.hsla(color.h, color.s, color.l, color.a);
+}
+
+function scaled(n, size) {
+    if (n instanceof tree.Dimension && n.unit == '%') {
+        return parseFloat(n.value * size / 100);
+    } else {
+        return number(n);
+    }
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        // 'transparent':'rgba(0,0,0,0)',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) {
+            return new(tree.Assignment)(this.key, this.value.eval(env));
+        }
+        return this;
+    }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+    this.filename = filename;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // or we simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) });
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                return tree.functions[this.name].apply(tree.functions, args);
+            } catch (e) {
+                throw { type: e.type || "Runtime",
+                        message: "error evaluating function `" + this.name + "`" +
+                                 (e.message ? ': ' + e.message : ''),
+                        index: this.index, filename: this.filename };
+            }
+        } else { // 2.
+            return new(tree.Anonymous)(this.name +
+                   "(" + args.map(function (a) { return a.toCSS(env) }).join(', ') + ")");
+        }
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    },
+    compare: function (x) {
+        if (!x.rgb) {
+            return -1;
+        }
+        
+        return (x.rgb[0] === this.rgb[0] &&
+            x.rgb[1] === this.rgb[1] &&
+            x.rgb[2] === this.rgb[2] &&
+            x.alpha === this.alpha) ? 0 : -1;
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+    this.op = op.trim();
+    this.lvalue = l;
+    this.rvalue = r;
+    this.index = i;
+    this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+    var a = this.lvalue.eval(env),
+        b = this.rvalue.eval(env);
+
+    var i = this.index, result;
+
+    var result = (function (op) {
+        switch (op) {
+            case 'and':
+                return a && b;
+            case 'or':
+                return a || b;
+            default:
+                if (a.compare) {
+                    result = a.compare(b);
+                } else if (b.compare) {
+                    result = b.compare(a);
+                } else {
+                    throw { type: "Type",
+                            message: "Unable to perform comparison",
+                            index: i };
+                }
+                switch (result) {
+                    case -1: return op === '<' || op === '=<';
+                    case  0: return op === '=' || op === '>=' || op === '=<';
+                    case  1: return op === '>' || op === '>=';
+                }
+        }
+    })(this.op);
+    return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    },
+
+    compare: function (other) {
+        if (other instanceof tree.Dimension) {
+            if (other.value > this.value) {
+                return -1;
+            } else if (other.value < this.value) {
+                return 1;
+            } else {
+                if (other.unit && this.unit !== other.unit) {
+                    return -1;
+                }
+                return 0;
+            }
+        } else {
+            return -1;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+        this.ruleset.allowImports = true;
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        var evaldDirective = this;
+        if (this.ruleset) {
+            env.frames.unshift(this);
+            evaldDirective = new(tree.Directive)(this.name);
+            evaldDirective.ruleset = this.ruleset.eval(env);
+            env.frames.shift();
+        }
+        return evaldDirective;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+
+    if (typeof(value) === 'string') {
+        this.value = value.trim();
+    } else if (value) {
+        this.value = value;
+    } else {
+        this.value = "";
+    }
+    this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+    return new(tree.Element)(this.combinator,
+                             this.value.eval ? this.value.eval(env) : this.value,
+                             this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+	var value = (this.value.toCSS ? this.value.toCSS(env) : this.value);
+	if (value == '' && this.combinator.value.charAt(0) == '&') {
+		return '';
+	} else {
+		return this.combinator.toCSS(env || {}) + value;
+	}
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        ':' : ' :',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > ',
+        '|' : env.compress ? '|' : ' | '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS ? e.toCSS(env) : '';
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, once, index, rootpath) {
+    var that = this;
+
+    this.once = once;
+    this.index = index;
+    this._path = path;
+    this.features = features && new(tree.Value)(features);
+    this.rootpath = rootpath;
+		
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /(\.[a-z]*$)|([\?;].*)$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css([\?;].*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (e, root, imported) {
+            if (e) { e.index = index }
+            if (imported && that.once) that.skip = imported;
+            that.root = root || new(tree.Ruleset)([], []);
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function (env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.css) {
+            // Add the base path if the import is relative
+            if (typeof this._path.value === "string" && !/^(?:[a-z-]+:|\/)/.test(this._path.value)) {
+                this._path.value = this.rootpath + this._path.value;
+            }
+            return "@import " + this._path.toCSS() + features + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset, features = this.features && this.features.eval(env);
+
+        if (this.skip) return [];
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+            ruleset.evalImports(env);
+
+            return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value },
+    compare: function (other) {
+        if (other instanceof tree.Keyword) {
+            return other.value === this.value ? 0 : 1;
+        } else {
+            return -1;
+        }
+    }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Media = function (value, features) {
+    var selectors = this.emptySelectors();
+
+    this.features = new(tree.Value)(features);
+    this.ruleset = new(tree.Ruleset)(selectors, value);
+    this.ruleset.allowImports = true;
+};
+tree.Media.prototype = {
+    toCSS: function (ctx, env) {
+        var features = this.features.toCSS(env);
+
+        this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
+        return '@media ' + features + (env.compress ? '{' : ' {\n  ') +
+               this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                           (env.compress ? '}': '\n}\n');
+    },
+    eval: function (env) {
+        if (!env.mediaBlocks) {
+            env.mediaBlocks = [];
+            env.mediaPath = [];
+        }
+        
+        var media = new(tree.Media)([], []);
+        if(this.debugInfo) {
+            this.ruleset.debugInfo = this.debugInfo;
+            media.debugInfo = this.debugInfo;
+        }
+        media.features = this.features.eval(env);
+        
+        env.mediaPath.push(media);
+        env.mediaBlocks.push(media);
+        
+        env.frames.unshift(this.ruleset);
+        media.ruleset = this.ruleset.eval(env);
+        env.frames.shift();
+        
+        env.mediaPath.pop();
+
+        return env.mediaPath.length === 0 ? media.evalTop(env) :
+                    media.evalNested(env)
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
+    emptySelectors: function() { 
+        var el = new(tree.Element)('', '&', 0);
+        return [new(tree.Selector)([el])];
+    },
+
+    evalTop: function (env) {
+        var result = this;
+
+        // Render all dependent Media blocks.
+        if (env.mediaBlocks.length > 1) {
+            var selectors = this.emptySelectors();
+            result = new(tree.Ruleset)(selectors, env.mediaBlocks);
+            result.multiMedia = true;
+        }
+
+        delete env.mediaBlocks;
+        delete env.mediaPath;
+
+        return result;
+    },
+    evalNested: function (env) {
+        var i, value,
+            path = env.mediaPath.concat([this]);
+
+        // Extract the media-query conditions separated with `,` (OR).
+        for (i = 0; i < path.length; i++) {
+            value = path[i].features instanceof tree.Value ?
+                        path[i].features.value : path[i].features;
+            path[i] = Array.isArray(value) ? value : [value];
+        }
+
+        // Trace all permutations to generate the resulting media-query.
+        //
+        // (a, b and c) with nested (d, e) ->
+        //    a and d
+        //    a and e
+        //    b and c and d
+        //    b and c and e
+        this.features = new(tree.Value)(this.permute(path).map(function (path) {
+            path = path.map(function (fragment) {
+                return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
+            });
+
+            for(i = path.length - 1; i > 0; i--) {
+                path.splice(i, 0, new(tree.Anonymous)("and"));
+            }
+
+            return new(tree.Expression)(path);
+        }));
+
+        // Fake a tree-node that doesn't output anything.
+        return new(tree.Ruleset)([], []);
+    },
+    permute: function (arr) {
+      if (arr.length === 0) {
+          return [];
+      } else if (arr.length === 1) {
+          return arr[0];
+      } else {
+          var result = [];
+          var rest = this.permute(arr.slice(1));
+          for (var i = 0; i < rest.length; i++) {
+              for (var j = 0; j < arr[0].length; j++) {
+                  result.push([arr[0][j]].concat(rest[i]));
+              }
+          }
+          return result;
+      }
+    },
+    bubbleSelectors: function (selectors) {
+      this.ruleset = new(tree.Ruleset)(selectors.slice(0), [this.ruleset]);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+    this.filename = filename;
+    this.important = important;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound;
+
+        args = this.arguments && this.arguments.map(function (a) {
+            return { name: a.name, value: a.value.eval(env) };
+        });
+
+        for (i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                isOneFound = true;
+                for (m = 0; m < mixins.length; m++) {
+                    mixin = mixins[m];
+                    isRecursive = false;
+                    for(f = 0; f < env.frames.length; f++) {
+                        if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) {
+                            isRecursive = true;
+                            break;
+                        }
+                    }
+                    if (isRecursive) {
+                        continue;
+                    }
+                    if (mixin.matchArgs(args, env)) {
+                        if (!mixin.matchCondition || mixin.matchCondition(args, env)) {
+                            try {
+                                Array.prototype.push.apply(
+                                      rules, mixin.eval(env, args, this.important).rules);
+                            } catch (e) {
+                                throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
+                            }
+                        }
+                        match = true;
+                    }
+                }
+                if (match) {
+                    return rules;
+                }
+            }
+        }
+        if (isOneFound) {
+            throw { type:    'Runtime',
+                    message: 'No matching definition was found for `' +
+                              this.selector.toCSS().trim() + '('      +
+                              (args ? args.map(function (a) {
+                                  var argValue = "";
+                                  if (a.name) {
+                                      argValue += a.name + ":";
+                                  }
+                                  if (a.value.toCSS) {
+                                      argValue += a.value.toCSS();
+                                  } else {
+                                      argValue += "???";
+                                  }
+                                  return argValue;
+                              }).join(', ') : "") + ")`",
+                    index:   this.index, filename: this.filename };
+        } else {
+            throw { type: 'Name',
+                message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index, filename: this.filename };
+        }
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition, variadic) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.condition = condition;
+    this.variadic = variadic;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    evalParams: function (env, mixinEnv, args, evaldArguments) {
+        var frame = new(tree.Ruleset)(null, []), varargs, arg, params = this.params.slice(0), i, j, val, name, isNamedFound, argIndex;
+        
+        if (args) {
+            args = args.slice(0);
+
+            for(i = 0; i < args.length; i++) {
+                arg = args[i];
+                if (name = (arg && arg.name)) {
+                    isNamedFound = false;
+                    for(j = 0; j < params.length; j++) {
+                        if (!evaldArguments[j] && name === params[j].name) {
+                            evaldArguments[j] = arg.value.eval(env);
+                            frame.rules.unshift(new(tree.Rule)(name, arg.value.eval(env)));
+                            isNamedFound = true;
+                            break;
+                        }
+                    }
+                    if (isNamedFound) {
+                        args.splice(i, 1);
+                        i--;
+                        continue;
+                    } else {
+                        throw { type: 'Runtime', message: "Named argument for " + this.name +
+                            ' ' + args[i].name + ' not found' };
+                    }
+                }
+            }
+        }
+        argIndex = 0;
+        for (i = 0; i < params.length; i++) {
+            if (evaldArguments[i]) continue;
+            
+            arg = args && args[argIndex];
+
+            if (name = params[i].name) {
+                if (params[i].variadic && args) {
+                    varargs = [];
+                    for (j = argIndex; j < args.length; j++) {
+                        varargs.push(args[j].value.eval(env));
+                    }
+                    frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
+                } else {
+                    val = arg && arg.value;
+                    if (val) {
+                        val = val.eval(env);
+                    } else if (params[i].value) {
+                        val = params[i].value.eval(mixinEnv);
+                    } else {
+                        throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                    }
+                    
+                    frame.rules.unshift(new(tree.Rule)(name, val));
+                    evaldArguments[i] = val;
+                }
+            }
+            
+            if (params[i].variadic && args) {
+                for (j = argIndex; j < args.length; j++) {
+                    evaldArguments[j] = args[j].value.eval(env);
+                }
+            }
+            argIndex++;
+        }
+
+        return frame;
+    },
+    eval: function (env, args, important) {
+        var _arguments = [],
+            mixinFrames = this.frames.concat(env.frames),
+            frame = this.evalParams(env, {frames: mixinFrames}, args, _arguments), 
+            context, rules, start, ruleset;
+
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        rules = important ?
+            this.parent.makeImportant.apply(this).rules : this.rules.slice(0);
+
+        ruleset = new(tree.Ruleset)(null, rules).eval({
+            frames: [this, frame].concat(mixinFrames)
+        });
+        ruleset.originalRuleset = this;
+        return ruleset;
+    },
+    matchCondition: function (args, env) {
+        if (this.condition && !this.condition.eval({
+            frames: [this.evalParams(env, {frames: this.frames.concat(env.frames)}, args, [])].concat(env.frames)
+        }))                                                           { return false }
+        return true;
+    },
+    matchArgs: function (args, env) {
+        var argsLength = (args && args.length) || 0, len, frame;
+
+        if (! this.variadic) {
+            if (argsLength < this.required)                               { return false }
+            if (argsLength > this.params.length)                          { return false }
+            if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+        }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name && !this.params[i].variadic) {
+                if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    if (!a.operate) {
+        throw { name: "OperationError",
+                message: "Operation on an invalid type" };
+    }
+
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+    this.value = node;
+};
+tree.Paren.prototype = {
+    toCSS: function (env) {
+        return '(' + this.value.toCSS(env) + ')';
+    },
+    eval: function (env) {
+        return new(tree.Paren)(this.value.eval(env));
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return (v instanceof tree.Quoted) ? v.value : v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ratio = function (value) {
+    this.value = value;
+};
+tree.Ratio.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+    this.inline = inline || false;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + (this.inline ? "" : ";");
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name,
+                          this.value.eval(context),
+                          this.important,
+                          this.index, this.inline);
+};
+
+tree.Rule.prototype.makeImportant = function () {
+    return new(tree.Rule)(this.name,
+                          this.value,
+                          "!important",
+                          this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules, strictImports) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+    this.strictImports = strictImports;
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
+        var rules;
+        
+        ruleset.originalRuleset = this;
+        ruleset.root = this.root;
+        ruleset.allowImports = this.allowImports;
+
+        if(this.debugInfo) {
+            ruleset.debugInfo = this.debugInfo;
+        }
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
+            ruleset.evalImports(env);
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+        
+        var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0;
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                rules = ruleset.rules[i].eval(env);
+                ruleset.rules.splice.apply(ruleset.rules, [i, 1].concat(rules));
+                i += rules.length-1;
+                ruleset.resetCache();
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+        
+        if (env.mediaBlocks) {
+            for(var i = mediaBlockCount; i < env.mediaBlocks.length; i++) {
+                env.mediaBlocks[i].bubbleSelectors(selectors);
+            }
+        }
+
+        return ruleset;
+    },
+    evalImports: function(env) {
+        var i, rules;
+        for (i = 0; i < this.rules.length; i++) {
+            if (this.rules[i] instanceof tree.Import) {
+                rules = this.rules[i].eval(env);
+                if (typeof rules.length === "number") {
+                    this.rules.splice.apply(this.rules, [i, 1].concat(rules));
+                    i+= rules.length-1;
+                } else {
+                    this.rules.splice(i, 1, rules);
+                }
+                this.resetCache();
+            }
+        }
+    },
+    makeImportant: function() {
+        return new tree.Ruleset(this.selectors, this.rules.map(function (r) {
+                    if (r.makeImportant) {
+                        return r.makeImportant();
+                    } else {
+                        return r;
+                    }
+                }), this.strictImports);
+    },
+    matchArgs: function (args) {
+        return !args || args.length === 0;
+    },
+    resetCache: function () {
+        this._rulesets = null;
+        this._variables = null;
+        this._lookups = {};
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+           _rules = [],    //
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            debugInfo,     // Line number debugging
+            rule;
+
+        if (! this.root) {
+            this.joinSelectors(paths, context, this.selectors);
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Media)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Directive) {
+                var cssValue = rule.toCSS(paths, env);
+                // Output only the first @charset definition as such - convert the others
+                // to comments in case debug is enabled
+                if (rule.name === "@charset") {
+                    // Only output the debug info together with subsequent @charset definitions
+                    // a comment (or @media statement) before the actual @charset directive would
+                    // be considered illegal css as it has to be on the first line
+                    if (env.charset) {
+                        if (rule.debugInfo) {
+                            rulesets.push(tree.debugInfo(env, rule));
+                            rulesets.push(new tree.Comment("/* "+cssValue.replace(/\n/g, "")+" */\n").toCSS(env));
+                        }
+                        continue;
+                    }
+                    env.charset = true;
+                }
+                rulesets.push(cssValue);
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                debugInfo = tree.debugInfo(env, this);
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : ',\n');
+
+                // Remove duplicates
+                for (var i = rules.length - 1; i >= 0; i--) {
+                    if (_rules.indexOf(rules[i]) === -1) {
+                        _rules.unshift(rules[i]);
+                    }
+                }
+                rules = _rules;
+
+                css.push(debugInfo + selector + 
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('')  + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+
+        var i, j, k, 
+            hasParentSelector, newSelectors, el, sel, parentSel, 
+            newSelectorPath, afterParentJoin, newJoinedSelector, 
+            newJoinedSelectorEmpty, lastSelector, currentElements,
+            selectorsMultiplied;
+    
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.value === '&') {
+                hasParentSelector = true;
+            }
+        }
+    
+        if (!hasParentSelector) {
+            if (context.length > 0) {
+                for(i = 0; i < context.length; i++) {
+                    paths.push(context[i].concat(selector));
+                }
+            }
+            else {
+                paths.push([selector]);
+            }
+            return;
+        }
+
+        // The paths are [[Selector]]
+        // The first list is a list of comma seperated selectors
+        // The inner list is a list of inheritance seperated selectors
+        // e.g.
+        // .a, .b {
+        //   .c {
+        //   }
+        // }
+        // == [[.a] [.c]] [[.b] [.c]]
+        //
+
+        // the elements from the current selector so far
+        currentElements = [];
+        // the current list of new selectors to add to the path.
+        // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
+        // by the parents
+        newSelectors = [[]];
+
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            // non parent reference elements just get added
+            if (el.value !== "&") {
+                currentElements.push(el);
+            } else {
+                // the new list of selectors to add
+                selectorsMultiplied = [];
+
+                // merge the current list of non parent selector elements
+                // on to the current list of selectors to add
+                if (currentElements.length > 0) {
+                    this.mergeElementsOnToSelectors(currentElements, newSelectors);
+                }
+
+                // loop through our current selectors
+                for(j = 0; j < newSelectors.length; j++) {
+                    sel = newSelectors[j];
+                    // if we don't have any parent paths, the & might be in a mixin so that it can be used
+                    // whether there are parents or not
+                    if (context.length == 0) {
+                        // the combinator used on el should now be applied to the next element instead so that
+                        // it is not lost
+                        if (sel.length > 0) {
+                            sel[0].elements = sel[0].elements.slice(0);
+                            sel[0].elements.push(new(tree.Element)(el.combinator, '', 0)); //new Element(el.Combinator,  ""));
+                        }
+                        selectorsMultiplied.push(sel);
+                    }
+                    else {
+                        // and the parent selectors
+                        for(k = 0; k < context.length; k++) {
+                            parentSel = context[k];
+                            // We need to put the current selectors
+                            // then join the last selector's elements on to the parents selectors
+
+                            // our new selector path
+                            newSelectorPath = [];
+                            // selectors from the parent after the join
+                            afterParentJoin = [];
+                            newJoinedSelectorEmpty = true;
+
+                            //construct the joined selector - if & is the first thing this will be empty,
+                            // if not newJoinedSelector will be the last set of elements in the selector
+                            if (sel.length > 0) {
+                                newSelectorPath = sel.slice(0);
+                                lastSelector = newSelectorPath.pop();
+                                newJoinedSelector = new(tree.Selector)(lastSelector.elements.slice(0));
+                                newJoinedSelectorEmpty = false;
+                            }
+                            else {
+                                newJoinedSelector = new(tree.Selector)([]);
+                            }
+
+                            //put together the parent selectors after the join
+                            if (parentSel.length > 1) {
+                                afterParentJoin = afterParentJoin.concat(parentSel.slice(1));
+                            }
+
+                            if (parentSel.length > 0) {
+                                newJoinedSelectorEmpty = false;
+
+                                // join the elements so far with the first part of the parent
+                                newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, 0));
+                                newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1));
+                            }
+
+                            if (!newJoinedSelectorEmpty) {
+                                // now add the joined selector
+                                newSelectorPath.push(newJoinedSelector);
+                            }
+
+                            // and the rest of the parent
+                            newSelectorPath = newSelectorPath.concat(afterParentJoin);
+
+                            // add that to our new set of selectors
+                            selectorsMultiplied.push(newSelectorPath);
+                        }
+                    }
+                }
+
+                // our new selectors has been multiplied, so reset the state
+                newSelectors = selectorsMultiplied;
+                currentElements = [];
+            }
+        }
+
+        // if we have any elements left over (e.g. .a& .b == .b)
+        // add them on to all the current selectors
+        if (currentElements.length > 0) {
+            this.mergeElementsOnToSelectors(currentElements, newSelectors);
+        }
+
+        for(i = 0; i < newSelectors.length; i++) {
+            paths.push(newSelectors[i]);
+        }
+    },
+    
+    mergeElementsOnToSelectors: function(elements, selectors) {
+        var i, sel;
+
+        if (selectors.length == 0) {
+            selectors.push([ new(tree.Selector)(elements) ]);
+            return;
+        }
+
+        for(i = 0; i < selectors.length; i++) {
+            sel = selectors[i];
+
+            // if the previous thing in sel is a parent this needs to join on to it
+            if (sel.length > 0) {
+                sel[sel.length - 1] = new(tree.Selector)(sel[sel.length - 1].elements.concat(elements));
+            }
+            else {
+                sel.push(new(tree.Selector)(elements));
+            }
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+};
+tree.Selector.prototype.match = function (other) {
+    var elements = this.elements,
+        len = elements.length,
+        oelements, olen, max, i;
+
+    oelements = other.elements.slice(
+        (other.elements.length && other.elements[0].value === "&") ? 1 : 0);
+    olen = oelements.length;
+    max = Math.min(len, olen)
+
+    if (olen === 0 || len < olen) {
+        return false;
+    } else {
+        for (i = 0; i < max; i++) {
+            if (elements[i].value !== oelements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.eval = function (env) {
+    return new(tree.Selector)(this.elements.map(function (e) {
+        return e.eval(env);
+    }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+    
+    if (this.elements[0].combinator.value === "") {
+        this._css = ' ';
+    } else {
+        this._css = '';
+    }
+    
+    this._css += this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+    
+    return this._css;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.UnicodeDescriptor = function (value) {
+    this.value = value;
+};
+tree.UnicodeDescriptor.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, rootpath) {
+    this.value = val;
+    this.rootpath = rootpath;
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + this.value.toCSS() + ")";
+    },
+    eval: function (ctx) {
+        var val = this.value.eval(ctx), rootpath;
+
+        // Add the base path if the URL is relative
+        if (typeof val.value === "string" && !/^(?:[a-z-]+:|\/)/.test(val.value)) {
+            rootpath = this.rootpath;
+            if (!val.quote) {
+                rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; });
+            }
+            val.value = rootpath + val.value;
+        }
+
+        return new(tree.URL)(val, this.rootpath);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+        
+        if (this.evaluating) {
+            throw { type: 'Name',
+                    message: "Recursive variable definition for " + name,
+                    filename: this.file,
+                    index: this.index };
+        }
+        
+        this.evaluating = true;
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { 
+            this.evaluating = false;
+            return variable;
+        }
+        else {
+            throw { type: 'Name',
+                    message: "variable " + name + " is undefined",
+                    filename: this.file,
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.debugInfo = function(env, ctx) {
+    var result="";
+    if (env.dumpLineNumbers && !env.compress) {
+        switch(env.dumpLineNumbers) {
+            case 'comments':
+                result = tree.debugInfo.asComment(ctx);
+                break;
+            case 'mediaquery':
+                result = tree.debugInfo.asMediaQuery(ctx);
+                break;
+            case 'all':
+                result = tree.debugInfo.asComment(ctx)+tree.debugInfo.asMediaQuery(ctx);
+                break;
+        }
+    }
+    return result;
+};
+
+tree.debugInfo.asComment = function(ctx) {
+    return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
+};
+
+tree.debugInfo.asMediaQuery = function(ctx) {
+    return '@media -sass-debug-info{filename{font-family:' +
+        ('file://' + ctx.debugInfo.fileName).replace(/[\/:.]/g, '\\$&') +
+        '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n';
+};
+
+tree.find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+tree.jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+
+})(require('./tree'));
+var name;
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var endOfPath = Math.max(name.lastIndexOf('/'), name.lastIndexOf('\\')),
+        sheetName = name.slice(0, endOfPath + 1) + sheet.href,
+        contents = sheet.contents || {},
+        input = readFile(sheetName);
+        
+    contents[sheetName] = input;
+        
+    var parser = new less.Parser({
+        paths: [sheet.href.replace(/[\w\.-]+$/, '')],
+        contents: contents
+    });
+    parser.parse(input, function (e, root) {
+        if (e) {
+            return error(e, sheetName);
+        }
+        try {
+            callback(e, root, input, sheet, { local: false, lastModified: 0, remaining: remaining }, sheetName);
+        } catch(e) {
+            error(e, sheetName);
+        }
+    });
+}
+
+function writeFile(filename, content) {
+    var fstream = new java.io.FileWriter(filename);
+    var out = new java.io.BufferedWriter(fstream);
+    out.write(content);
+    out.close();
+}
+
+// Command line integration via Rhino
+(function (args) {
+    var output,
+        compress = false,
+        i;
+        
+    for(i = 0; i < args.length; i++) {
+        switch(args[i]) {
+            case "-x":
+                compress = true;
+                break;
+            default:
+                if (!name) {
+                    name = args[i];
+                } else if (!output) {
+                    output = args[i];
+                } else {
+                    print("unrecognised parameters");
+                    print("input_file [output_file] [-x]");
+                }
+        }
+    }
+
+    if (!name) {
+        print('No files present in the fileset; Check your pattern match in build.xml');
+        quit(1);
+    }
+    path = name.split("/");path.pop();path=path.join("/")
+
+    var input = readFile(name);
+
+    if (!input) {
+        print('lesscss: couldn\'t open file ' + name);
+        quit(1);
+    }
+
+    var result;
+    try {
+        var parser = new less.Parser();
+        parser.parse(input, function (e, root) {
+            if (e) {
+                error(e, name);
+                quit(1);
+            } else {
+                result = root.toCSS({compress: compress || false});
+                if (output) {
+                    writeFile(output, result);
+                    print("Written to " + output);
+                } else {
+                    print(result);
+                }
+                quit(0);
+            }
+        });
+    }
+    catch(e) {
+        error(e, name);
+        quit(1);
+    }
+    print("done");
+}(arguments));
+
+function error(e, filename) {
+
+    var content = "Error : " + filename + "\n";
+    
+    filename = e.filename || filename;
+    
+    if (e.message) {
+        content += e.message + "\n";
+    }
+
+    var errorline = function (e, i, classname) {
+        if (e.extract[i]) {
+            content += 
+                String(parseInt(e.line) + (i - 1)) + 
+                ":" + e.extract[i] + "\n";
+        }
+    };
+
+    if (e.stack) {
+        content += e.stack;
+    } else if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n';
+        errorline(e, 0);
+        errorline(e, 1);
+        errorline(e, 2);
+    }
+   print(content);
+}
\ No newline at end of file
diff --git a/util/less/dist/less-rhino-1.3.3.js b/util/less/dist/less-rhino-1.3.3.js
new file mode 100644
index 0000000..857a97c
--- /dev/null
+++ b/util/less/dist/less-rhino-1.3.3.js
@@ -0,0 +1,4002 @@
+//
+// Stub out `require` in rhino
+//
+function require(arg) {
+    return less[arg.split('/')[1]];
+};
+
+
+// ecma-5.js
+//
+// -- kriskowal Kris Kowal Copyright (C) 2009-2010 MIT License
+// -- tlrobinson Tom Robinson
+// dantman Daniel Friesen
+
+//
+// Array
+//
+if (!Array.isArray) {
+    Array.isArray = function(obj) {
+        return Object.prototype.toString.call(obj) === "[object Array]" ||
+               (obj instanceof Array);
+    };
+}
+if (!Array.prototype.forEach) {
+    Array.prototype.forEach =  function(block, thisObject) {
+        var len = this.length >>> 0;
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                block.call(thisObject, this[i], i, this);
+            }
+        }
+    };
+}
+if (!Array.prototype.map) {
+    Array.prototype.map = function(fun /*, thisp*/) {
+        var len = this.length >>> 0;
+        var res = new Array(len);
+        var thisp = arguments[1];
+
+        for (var i = 0; i < len; i++) {
+            if (i in this) {
+                res[i] = fun.call(thisp, this[i], i, this);
+            }
+        }
+        return res;
+    };
+}
+if (!Array.prototype.filter) {
+    Array.prototype.filter = function (block /*, thisp */) {
+        var values = [];
+        var thisp = arguments[1];
+        for (var i = 0; i < this.length; i++) {
+            if (block.call(thisp, this[i])) {
+                values.push(this[i]);
+            }
+        }
+        return values;
+    };
+}
+if (!Array.prototype.reduce) {
+    Array.prototype.reduce = function(fun /*, initial*/) {
+        var len = this.length >>> 0;
+        var i = 0;
+
+        // no value to return if no initial value and an empty array
+        if (len === 0 && arguments.length === 1) throw new TypeError();
+
+        if (arguments.length >= 2) {
+            var rv = arguments[1];
+        } else {
+            do {
+                if (i in this) {
+                    rv = this[i++];
+                    break;
+                }
+                // if array contains no values, no initial value to return
+                if (++i >= len) throw new TypeError();
+            } while (true);
+        }
+        for (; i < len; i++) {
+            if (i in this) {
+                rv = fun.call(null, rv, this[i], i, this);
+            }
+        }
+        return rv;
+    };
+}
+if (!Array.prototype.indexOf) {
+    Array.prototype.indexOf = function (value /*, fromIndex */ ) {
+        var length = this.length;
+        var i = arguments[1] || 0;
+
+        if (!length)     return -1;
+        if (i >= length) return -1;
+        if (i < 0)       i += length;
+
+        for (; i < length; i++) {
+            if (!Object.prototype.hasOwnProperty.call(this, i)) { continue }
+            if (value === this[i]) return i;
+        }
+        return -1;
+    };
+}
+
+//
+// Object
+//
+if (!Object.keys) {
+    Object.keys = function (object) {
+        var keys = [];
+        for (var name in object) {
+            if (Object.prototype.hasOwnProperty.call(object, name)) {
+                keys.push(name);
+            }
+        }
+        return keys;
+    };
+}
+
+//
+// String
+//
+if (!String.prototype.trim) {
+    String.prototype.trim = function () {
+        return String(this).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
+    };
+}
+var less, tree, charset;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    if (typeof(window) === 'undefined') { less = {} }
+    else                                { less = window.less = {} }
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // Top parser on an import tree must be sure there is one "env"
+    // which will then be passed arround by reference.
+    var env = env || { };
+    // env.contents and files must be passed arround with top env
+    if (!env.contents) { env.contents = {}; }
+    env.rootpath = env.rootpath || '';       // env.rootpath must be initialized to '' if not provided
+    if (!env.files) { env.files = {}; }
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env.paths || [],  // Search paths, when importing
+        queue: [],               // Files which haven't been imported yet
+        files: env.files,        // Holds the imported parse trees
+        contents: env.contents,  // Holds the imported file contents
+        mime:  env.mime,         // MIME type of .less files
+        error: null,             // Error in parsing/evaluating an import
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (e, root, fullPath) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+
+                var imported = fullPath in that.files;
+
+                that.files[fullPath] = root;                        // Store the root
+
+                if (e && !that.error) { that.error = e }
+
+                callback(e, root, imported);
+
+                if (that.queue.length === 0) { finish(that.error) }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    function isWhitespace(c) {
+        // Could change to \s?
+        var code = c.charCodeAt(0);
+        return code === 32 || code === 10 || code === 9;
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, index, k;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            skipWhitespace(length);
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    function skipWhitespace(length) {
+        var oldi = i, oldj = j,
+            endIndex = i + chunks[j].length,
+            mem = i += length;
+
+        while (i < endIndex) {
+            if (! isWhitespace(input.charAt(i))) { break }
+            i++;
+        }
+        chunks[j] = chunks[j].slice(length + (i - mem));
+        current = i;
+
+        if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+        return oldi !== i || oldj !== j;
+    }
+
+    function expect(arg, msg) {
+        var result = $(arg);
+        if (! result) {
+            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+                                                   : "unexpected token"));
+        } else {
+            return result;
+        }
+    }
+
+    function error(msg, type) {
+        var e = new Error(msg);
+        e.index = i;
+        e.type = type || 'Syntax';
+        throw e;
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    function getInput(e, env) {
+        if (e.filename && env.filename && (e.filename !== env.filename)) {
+            return parser.imports.contents[e.filename];
+        } else {
+            return input;
+        }
+    }
+
+    function getLocation(index, input) {
+        for (var n = index, column = -1;
+                 n >= 0 && input.charAt(n) !== '\n';
+                 n--) { column++ }
+
+        return { line:   typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+                 column: column };
+    }
+
+    function getFileName(e) {
+        if(less.mode === 'browser' || less.mode === 'rhino')
+            return e.filename;
+        else
+            return require('path').resolve(e.filename);
+    }
+
+    function getDebugInfo(index, inputStream, e) {
+        return {
+            lineNumber: getLocation(index, inputStream).line + 1,
+            fileName: getFileName(e)
+        };
+    }
+
+    function LessError(e, env) {
+        var input = getInput(e, env),
+            loc = getLocation(e.index, input),
+            line = loc.line,
+            col  = loc.column,
+            lines = input.split('\n');
+
+        this.type = e.type || 'Syntax';
+        this.message = e.message;
+        this.filename = e.filename || env.filename;
+        this.index = e.index;
+        this.line = typeof(line) === 'number' ? line + 1 : null;
+        this.callLine = e.call && (getLocation(e.call, input).line + 1);
+        this.callExtract = lines[getLocation(e.call, input).line];
+        this.stack = e.stack;
+        this.column = col;
+        this.extract = [
+            lines[line - 1],
+            lines[line],
+            lines[line + 1]
+        ];
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            input = str.replace(/\r\n/g, '\n');
+
+            // Remove potential UTF Byte Order Mark
+            input = input.replace(/^\uFEFF/, '');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam;
+
+                for (var i = 0, c, cc; i < input.length;) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = string.lastIndex = i;
+
+                    if (match = string.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                            continue;
+                        }
+                    }
+
+                    if (!inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    continue;
+                                }
+                            }
+                        }
+                    }
+                    
+                    switch (c) {
+                        case '{': if (! inParam) { level ++;        chunk.push(c);                           break }
+                        case '}': if (! inParam) { level --;        chunk.push(c); chunks[++j] = chunk = []; break }
+                        case '(': if (! inParam) { inParam = true;  chunk.push(c);                           break }
+                        case ')': if (  inParam) { inParam = false; chunk.push(c);                           break }
+                        default:                                    chunk.push(c);
+                    }
+                    
+                    i++;
+                }
+                if (level != 0) {
+                    error = new(LessError)({
+                        index: i-1,
+                        type: 'Parse',
+                        message: (level > 0) ? "missing closing `}`" : "missing opening `{`",
+                        filename: env.filename
+                    }, env);
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            if (error) {
+                return callback(error, env);
+            }
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            try {
+                root = new(tree.Ruleset)([], $(this.parsers.primary));
+                root.root = true;
+            } catch (e) {
+                return callback(new(LessError)(e, env));
+            }
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [], importError;
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false, dumpLineNumbers: env.dumpLineNumbers });
+                    } catch (e) {
+                        throw new(LessError)(e, env);
+                    }
+
+                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
+                        if (importError instanceof LessError) throw importError;
+                        else                                  throw new(LessError)(importError, env);
+                    }
+
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('ycssmin').cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    type: "Parse",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function (e) {
+                    e = error || e;
+                    if (e) callback(e);
+                    else callback(null, root);
+                };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/) || $(/^;+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k);
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, nameLC, args, alpha_ret, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1];
+                    nameLC = name.toLowerCase();
+
+                    if (nameLC === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (nameLC === 'alpha') {
+                        alpha_ret = $(this.alpha);
+                        if(typeof alpha_ret !== 'undefined') {
+                            return alpha_ret;
+                        }
+                    }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index, env.filename) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.ratio) ||
+                           $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted) ||
+                           $(this.entities.unicodeDescriptor);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || "";
+
+                    expect(')');
+
+                    return new(tree.URL)((value.value != null || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), env.rootpath);
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index, env.filename);
+                    }
+                },
+
+                // A variable entity useing the protective {} e.g. @{var}
+                variableCurly: function () {
+                    var name, curly, index = i;
+
+                    if (input.charAt(i) === '@' && (curly = $(/^@\{([\w-]+)\}/))) {
+                        return new(tree.Variable)("@" + curly[1], index, env.filename);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    //Is the first char of the dimension 0-9, '.', '+' or '-'
+                    if ((c > 57 || c < 43) || c === 47 || c == 44) return;
+
+                    if (value = $(/^([+-]?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn|dpi|dpcm|dppx|rem|vw|vh|vmin|vm|ch)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // A Ratio
+                //
+                //    16/9
+                //
+                ratio: function () {
+                  var value, c = input.charCodeAt(i);
+                  if (c > 57 || c < 48) return;
+
+                  if (value = $(/^(\d+\/\d+)/)) {
+                    return new(tree.Ratio)(value[1]);
+                  }
+                },
+                
+                //
+                // A unicode descriptor, as is used in unicode-range
+                //
+                // U+0??  or U+00A1-00A9
+                //
+                unicodeDescriptor: function () {
+                    var ud;
+                    
+                    if (ud = $(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/)) {
+                        return new(tree.UnicodeDescriptor)(ud[0]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                save();
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+
+                restore();
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, argsSemiColon = [], argsComma = [], args, delim, arg, nameLoop, expressions, isSemiColonSeperated, expressionContainsNamed, index = i, s = input.charAt(i), name, value, important = false;
+
+                    if (s !== '.' && s !== '#') { return }
+                    
+                    save(); // stop us absorbing part of an invalid selector
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    if ($('(')) {
+                        expressions = [];
+                        while (arg = $(this.expression)) {
+                            nameLoop = null;
+                            value = arg;
+
+                            // Variable
+                            if (arg.value.length == 1) {
+                                var val = arg.value[0];
+                                if (val instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        if (expressions.length > 0) {
+                                            if (isSemiColonSeperated) {
+                                                error("Cannot mix ; and , as delimiter types");
+                                            }
+                                            expressionContainsNamed = true;
+                                        }
+                                        value = expect(this.expression);
+                                        nameLoop = (name = val.name);
+                                    }
+                                }
+                            }
+                            
+                            expressions.push(value);
+                            
+                            argsComma.push({ name: nameLoop, value: value });
+                            
+                            if ($(',')) {
+                                continue;
+                            }
+                            
+                            if ($(';') || isSemiColonSeperated) {
+                            
+                                if (expressionContainsNamed) {
+                                    error("Cannot mix ; and , as delimiter types");
+                                }
+                            
+                                isSemiColonSeperated = true;
+                                                        
+                                if (expressions.length > 1) {
+                                    value = new(tree.Value)(expressions);
+                                }
+                                argsSemiColon.push({ name: name, value: value });
+                            
+                                name = null;
+                                expressions = [];
+                                expressionContainsNamed = false;
+                            }
+                        }
+
+                        expect(')');
+                    }
+
+                    args = isSemiColonSeperated ? argsSemiColon : argsComma;
+
+                    if ($(this.important)) {
+                        important = true;
+                    }
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+                    }
+                    
+                    restore();
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value, cond, variadic = false;
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*\}/)) return;
+
+                    save();
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        do {
+                            $(this.comment);
+                            if (input.charAt(i) === '.' && $(/^\.{3}/)) {
+                                variadic = true;
+                                params.push({ variadic: true });
+                                break;
+                            } else if (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                         || $(this.entities.keyword)) {
+                                // Variable
+                                if (param instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        value = expect(this.expression, 'expected expression');
+                                        params.push({ name: param.name, value: value });
+                                    } else if ($(/^\.{3}/)) {
+                                        params.push({ name: param.name, variadic: true });
+                                        variadic = true;
+                                        break;
+                                    } else {
+                                        params.push({ name: param.name });
+                                    }
+                                } else {
+                                    params.push({ value: param });
+                                }
+                            } else {
+                                break;
+                            }
+                        } while ($(',') || $(';'))
+
+                        // .mixincall("@{a}"); 
+                        // looks a bit like a mixin definition.. so we have to be nice and restore
+                        if (!$(')')) {
+                            furthest = i;
+                            restore();
+                        }
+                        
+                        $(this.comment);
+
+                        if ($(/^when/)) { // Guard
+                            cond = expect(this.conditions, 'expected condition');
+                        }
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
+                        } else {
+                            restore();
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  ||$(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    expect(')');
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c, v;
+
+                c = $(this.combinator);
+
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
+                    $('*') || $('&') || $(this.attribute) || $(/^\([^()@]+\)/) || $(/^[\.#](?=@)/) || $(this.entities.variableCurly);
+
+                if (! e) {
+                    if ($('(')) {
+                        if ((v = ($(this.entities.variableCurly) || 
+                                $(this.entities.variable) || 
+                                $(this.selector))) && 
+                                $(')')) {
+                            e = new(tree.Paren)(v);
+                        }
+                    }
+                }
+
+                if (e) { return new(tree.Element)(c, e, i) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~' || c === '|') {
+                    i++;
+                    while (input.charAt(i).match(/\s/)) { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (input.charAt(i - 1).match(/\s/)) {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                // depreciated, will be removed soon
+                if ($('(')) {
+                    sel = $(this.entity);
+                    if (!$(')')) { return null; }
+                    return new(tree.Selector)([new(tree.Element)('', sel, i)]);
+                }
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^(?:[_A-Za-z0-9-]|\\.)+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match, debugInfo;
+                
+                save();
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports);
+                    if (env.dumpLineNumbers)
+                        ruleset.debugInfo = debugInfo;
+                    return ruleset;
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path, features, index = i;
+                
+                save();
+                
+                var dir = $(/^@import(?:-(once))?\s+/);
+
+                if (dir && (path = $(this.entities.quoted) || $(this.entities.url))) {
+                    features = $(this.mediaFeatures);
+                    if ($(';')) {
+                        return new(tree.Import)(path, imports, features, (dir[1] === 'once'), index, env.rootpath);
+                    }
+                }
+                
+                restore();
+            },
+
+            mediaFeature: function () {
+                var e, p, nodes = [];
+
+                do {
+                    if (e = $(this.entities.keyword)) {
+                        nodes.push(e);
+                    } else if ($('(')) {
+                        p = $(this.property);
+                        e = $(this.entity);
+                        if ($(')')) {
+                            if (p && e) {
+                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+                            } else if (e) {
+                                nodes.push(new(tree.Paren)(e));
+                            } else {
+                                return null;
+                            }
+                        } else { return null }
+                    }
+                } while (e);
+
+                if (nodes.length > 0) {
+                    return new(tree.Expression)(nodes);
+                }
+            },
+
+            mediaFeatures: function () {
+                var e, features = [];
+
+                do {
+                  if (e = $(this.mediaFeature)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  } else if (e = $(this.entities.variable)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  }
+                } while (e);
+
+                return features.length > 0 ? features : null;
+            },
+
+            media: function () {
+                var features, rules, media, debugInfo;
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                if ($(/^@media/)) {
+                    features = $(this.mediaFeatures);
+
+                    if (rules = $(this.block)) {
+                        media = new(tree.Media)(rules, features);
+                        if(env.dumpLineNumbers)
+                            media.debugInfo = debugInfo;
+                        return media;
+                    }
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, identifier, e, nodes, nonVendorSpecificName,
+                    hasBlock, hasIdentifier, hasExpression;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import']) || $(this.media)) {
+                    return value;
+                }
+                
+                save();
+
+                name = $(/^@[a-z-]+/);
+                
+                if (!name) return;
+
+                nonVendorSpecificName = name;
+                if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
+                    nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
+                }
+
+                switch(nonVendorSpecificName) {
+                    case "@font-face":
+                        hasBlock = true;
+                        break;
+                    case "@viewport":
+                    case "@top-left":
+                    case "@top-left-corner":
+                    case "@top-center":
+                    case "@top-right":
+                    case "@top-right-corner":
+                    case "@bottom-left":
+                    case "@bottom-left-corner":
+                    case "@bottom-center":
+                    case "@bottom-right":
+                    case "@bottom-right-corner":
+                    case "@left-top":
+                    case "@left-middle":
+                    case "@left-bottom":
+                    case "@right-top":
+                    case "@right-middle":
+                    case "@right-bottom":
+                        hasBlock = true;
+                        break;
+                    case "@page":
+                    case "@document":
+                    case "@supports":
+                    case "@keyframes":
+                        hasBlock = true;
+                        hasIdentifier = true;
+                        break;
+                    case "@namespace":
+                        hasExpression = true;
+                        break;
+                }
+
+                if (hasIdentifier) {
+                    name += " " + ($(/^[^{]+/) || '').trim();
+                }
+
+                if (hasBlock)
+                {
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name, rules);
+                    }
+                } else {
+                    if ((value = hasExpression ? $(this.expression) : $(this.entity)) && $(';')) {
+                        var directive = new(tree.Directive)(name, value);
+                        if (env.dumpLineNumbers) {
+                            directive.debugInfo = getDebugInfo(i, input, env);
+                        }
+                        return directive;
+                    }
+                }
+                
+                restore();
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/[*\/]/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (!isWhitespace(input.charAt(i - 1)) && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            conditions: function () {
+                var a, b, index = i, condition;
+
+                if (a = $(this.condition)) {
+                    while ($(',') && (b = $(this.condition))) {
+                        condition = new(tree.Condition)('or', condition || a, b, index);
+                    }
+                    return condition || a;
+                }
+            },
+            condition: function () {
+                var a, b, c, op, index = i, negate = false;
+
+                if ($(/^not/)) { negate = true }
+                expect('(');
+                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                    if (op = $(/^(?:>=|=<|[<=>])/)) {
+                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                            c = new(tree.Condition)(op, a, b, index, negate);
+                        } else {
+                            error('expected expression');
+                        }
+                    } else {
+                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+                    }
+                    expect(')');
+                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[_a-z0-9-]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (!/^([a-z-]+:)?\//.test(path) && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ 
+            href: path, 
+            title: path, 
+            type: env.mime, 
+            contents: env.contents, 
+            files: env.files, 
+            rootpath: env.rootpath,
+            entryPath: env.entryPath,
+            relativeUrls: env.relativeUrls }, 
+        function (e, root, data, sheet, _, path) {
+            if (e && typeof(env.errback) === "function") {
+                env.errback.call(null, path, paths, callback, env);
+            } else {
+                callback.call(null, e, root, path);
+            }
+        }, true);
+    };
+}
+
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return scaled(c, 256); });
+        a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+
+    hsv: function(h, s, v) {
+        return this.hsva(h, s, v, 1.0);
+    },
+
+    hsva: function(h, s, v, a) {
+        h = ((number(h) % 360) / 360) * 360;
+        s = number(s); v = number(v); a = number(a);
+
+        var i, f;
+        i = Math.floor((h / 60) % 6);
+        f = (h / 60) - i;
+
+        var vs = [v,
+                  v * (1 - s),
+                  v * (1 - f * s),
+                  v * (1 - (1 - f) * s)];
+        var perm = [[0, 3, 1],
+                    [2, 0, 1],
+                    [1, 0, 3],
+                    [1, 2, 0],
+                    [3, 1, 0],
+                    [0, 1, 2]];
+
+        return this.rgba(vs[perm[i][0]] * 255,
+                         vs[perm[i][1]] * 255,
+                         vs[perm[i][2]] * 255,
+                         a);
+    },
+
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    red: function (color) {
+        return new(tree.Dimension)(color.rgb[0]);
+    },
+    green: function (color) {
+        return new(tree.Dimension)(color.rgb[1]);
+    },
+    blue: function (color) {
+        return new(tree.Dimension)(color.rgb[2]);
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    luma: function (color) {
+        return new(tree.Dimension)(Math.round((0.2126 * (color.rgb[0]/255) +
+            0.7152 * (color.rgb[1]/255) +
+            0.0722 * (color.rgb[2]/255)) *
+            color.alpha * 100), '%');
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        if (!weight) {
+            weight = new(tree.Dimension)(50);
+        }
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    contrast: function (color, dark, light, threshold) {
+        // filter: contrast(3.2);
+        // should be kept as is, so check for color
+        if (!color.rgb) {
+            return null;
+        }
+        if (typeof light === 'undefined') {
+            light = this.rgba(255, 255, 255, 1.0);
+        }
+        if (typeof dark === 'undefined') {
+            dark = this.rgba(0, 0, 0, 1.0);
+        }
+        if (typeof threshold === 'undefined') {
+            threshold = 0.43;
+        } else {
+            threshold = threshold.value;
+        }
+        if (((0.2126 * (color.rgb[0]/255) + 0.7152 * (color.rgb[1]/255) + 0.0722 * (color.rgb[2]/255)) * color.alpha) < threshold) {
+            return light;
+        } else {
+            return dark;
+        }
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    unit: function (val, unit) {
+        return new(tree.Dimension)(val.value, unit ? unit.toCSS() : "");
+    },
+    round: function (n, f) {
+        var fraction = typeof(f) === "undefined" ? 0 : f.value;
+        return this._math(function(num) { return num.toFixed(fraction); }, n);
+    },
+    ceil: function (n) {
+        return this._math(Math.ceil, n);
+    },
+    floor: function (n) {
+        return this._math(Math.floor, n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(fn(parseFloat(n.value)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return fn(n);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    },
+    percentage: function (n) {
+        return new(tree.Dimension)(n.value * 100, '%');
+    },
+    color: function (n) {
+        if (n instanceof tree.Quoted) {
+            return new(tree.Color)(n.value.slice(1));
+        } else {
+            throw { type: "Argument", message: "argument must be a string" };
+        }
+    },
+    iscolor: function (n) {
+        return this._isa(n, tree.Color);
+    },
+    isnumber: function (n) {
+        return this._isa(n, tree.Dimension);
+    },
+    isstring: function (n) {
+        return this._isa(n, tree.Quoted);
+    },
+    iskeyword: function (n) {
+        return this._isa(n, tree.Keyword);
+    },
+    isurl: function (n) {
+        return this._isa(n, tree.URL);
+    },
+    ispixel: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+    },
+    ispercentage: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+    },
+    isem: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+    },
+    _isa: function (n, Type) {
+        return (n instanceof Type) ? tree.True : tree.False;
+    },
+    
+    /* Blending modes */
+    
+    multiply: function(color1, color2) {
+        var r = color1.rgb[0] * color2.rgb[0] / 255;
+        var g = color1.rgb[1] * color2.rgb[1] / 255;
+        var b = color1.rgb[2] * color2.rgb[2] / 255;
+        return this.rgb(r, g, b);
+    },
+    screen: function(color1, color2) {
+        var r = 255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = 255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = 255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    overlay: function(color1, color2) {
+        var r = color1.rgb[0] < 128 ? 2 * color1.rgb[0] * color2.rgb[0] / 255 : 255 - 2 * (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = color1.rgb[1] < 128 ? 2 * color1.rgb[1] * color2.rgb[1] / 255 : 255 - 2 * (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = color1.rgb[2] < 128 ? 2 * color1.rgb[2] * color2.rgb[2] / 255 : 255 - 2 * (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    softlight: function(color1, color2) {
+        var t = color2.rgb[0] * color1.rgb[0] / 255;
+        var r = t + color1.rgb[0] * (255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255 - t) / 255;
+        t = color2.rgb[1] * color1.rgb[1] / 255;
+        var g = t + color1.rgb[1] * (255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255 - t) / 255;
+        t = color2.rgb[2] * color1.rgb[2] / 255;
+        var b = t + color1.rgb[2] * (255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255 - t) / 255;
+        return this.rgb(r, g, b);
+    },
+    hardlight: function(color1, color2) {
+        var r = color2.rgb[0] < 128 ? 2 * color2.rgb[0] * color1.rgb[0] / 255 : 255 - 2 * (255 - color2.rgb[0]) * (255 - color1.rgb[0]) / 255;
+        var g = color2.rgb[1] < 128 ? 2 * color2.rgb[1] * color1.rgb[1] / 255 : 255 - 2 * (255 - color2.rgb[1]) * (255 - color1.rgb[1]) / 255;
+        var b = color2.rgb[2] < 128 ? 2 * color2.rgb[2] * color1.rgb[2] / 255 : 255 - 2 * (255 - color2.rgb[2]) * (255 - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    difference: function(color1, color2) {
+        var r = Math.abs(color1.rgb[0] - color2.rgb[0]);
+        var g = Math.abs(color1.rgb[1] - color2.rgb[1]);
+        var b = Math.abs(color1.rgb[2] - color2.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    exclusion: function(color1, color2) {
+        var r = color1.rgb[0] + color2.rgb[0] * (255 - color1.rgb[0] - color1.rgb[0]) / 255;
+        var g = color1.rgb[1] + color2.rgb[1] * (255 - color1.rgb[1] - color1.rgb[1]) / 255;
+        var b = color1.rgb[2] + color2.rgb[2] * (255 - color1.rgb[2] - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    average: function(color1, color2) {
+        var r = (color1.rgb[0] + color2.rgb[0]) / 2;
+        var g = (color1.rgb[1] + color2.rgb[1]) / 2;
+        var b = (color1.rgb[2] + color2.rgb[2]) / 2;
+        return this.rgb(r, g, b);
+    },
+    negation: function(color1, color2) {
+        var r = 255 - Math.abs(255 - color2.rgb[0] - color1.rgb[0]);
+        var g = 255 - Math.abs(255 - color2.rgb[1] - color1.rgb[1]);
+        var b = 255 - Math.abs(255 - color2.rgb[2] - color1.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    tint: function(color, amount) {
+        return this.mix(this.rgb(255,255,255), color, amount);
+    },
+    shade: function(color, amount) {
+        return this.mix(this.rgb(0, 0, 0), color, amount);
+    }
+};
+
+function hsla(color) {
+    return tree.functions.hsla(color.h, color.s, color.l, color.a);
+}
+
+function scaled(n, size) {
+    if (n instanceof tree.Dimension && n.unit == '%') {
+        return parseFloat(n.value * size / 100);
+    } else {
+        return number(n);
+    }
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        // 'transparent':'rgba(0,0,0,0)',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) {
+            return new(tree.Assignment)(this.key, this.value.eval(env));
+        }
+        return this;
+    }
+};
+
+})(require('../tree'));(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+    this.filename = filename;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // if this returns null or we cannot find the function, we 
+    // simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) }),
+            result;
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                result = tree.functions[this.name].apply(tree.functions, args);
+                if (result != null) {
+                    return result;
+                }
+            } catch (e) {
+                throw { type: e.type || "Runtime",
+                        message: "error evaluating function `" + this.name + "`" +
+                                 (e.message ? ': ' + e.message : ''),
+                        index: this.index, filename: this.filename };
+            }
+        }
+        
+        // 2.
+        return new(tree.Anonymous)(this.name +
+            "(" + args.map(function (a) { return a.toCSS(env) }).join(', ') + ")");
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    },
+    compare: function (x) {
+        if (!x.rgb) {
+            return -1;
+        }
+        
+        return (x.rgb[0] === this.rgb[0] &&
+            x.rgb[1] === this.rgb[1] &&
+            x.rgb[2] === this.rgb[2] &&
+            x.alpha === this.alpha) ? 0 : -1;
+    }
+};
+
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+    this.op = op.trim();
+    this.lvalue = l;
+    this.rvalue = r;
+    this.index = i;
+    this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+    var a = this.lvalue.eval(env),
+        b = this.rvalue.eval(env);
+
+    var i = this.index, result;
+
+    var result = (function (op) {
+        switch (op) {
+            case 'and':
+                return a && b;
+            case 'or':
+                return a || b;
+            default:
+                if (a.compare) {
+                    result = a.compare(b);
+                } else if (b.compare) {
+                    result = b.compare(a);
+                } else {
+                    throw { type: "Type",
+                            message: "Unable to perform comparison",
+                            index: i };
+                }
+                switch (result) {
+                    case -1: return op === '<' || op === '=<';
+                    case  0: return op === '=' || op === '>=' || op === '=<';
+                    case  1: return op === '>' || op === '>=';
+                }
+        }
+    })(this.op);
+    return this.negate ? !result : result;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    },
+
+    compare: function (other) {
+        if (other instanceof tree.Dimension) {
+            if (other.value > this.value) {
+                return -1;
+            } else if (other.value < this.value) {
+                return 1;
+            } else {
+                if (other.unit && this.unit !== other.unit) {
+                    return -1;
+                }
+                return 0;
+            }
+        } else {
+            return -1;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+        this.ruleset.allowImports = true;
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        var evaldDirective = this;
+        if (this.ruleset) {
+            env.frames.unshift(this);
+            evaldDirective = new(tree.Directive)(this.name);
+            evaldDirective.ruleset = this.ruleset.eval(env);
+            env.frames.shift();
+        }
+        return evaldDirective;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+
+    if (typeof(value) === 'string') {
+        this.value = value.trim();
+    } else if (value) {
+        this.value = value;
+    } else {
+        this.value = "";
+    }
+    this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+    return new(tree.Element)(this.combinator,
+                             this.value.eval ? this.value.eval(env) : this.value,
+                             this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+	var value = (this.value.toCSS ? this.value.toCSS(env) : this.value);
+	if (value == '' && this.combinator.value.charAt(0) == '&') {
+		return '';
+	} else {
+		return this.combinator.toCSS(env || {}) + value;
+	}
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        ':' : ' :',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > ',
+        '|' : env.compress ? '|' : ' | '
+    }[this.value];
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS ? e.toCSS(env) : '';
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, once, index, rootpath) {
+    var that = this;
+
+    this.once = once;
+    this.index = index;
+    this._path = path;
+    this.features = features && new(tree.Value)(features);
+    this.rootpath = rootpath;
+		
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /(\.[a-z]*$)|([\?;].*)$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css([\?;].*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (e, root, imported) {
+            if (e) { e.index = index }
+            if (imported && that.once) that.skip = imported;
+            that.root = root || new(tree.Ruleset)([], []);
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function (env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.css) {
+            // Add the base path if the import is relative
+            if (typeof this._path.value === "string" && !/^(?:[a-z-]+:|\/)/.test(this._path.value)) {
+                this._path.value = this.rootpath + this._path.value;
+            }
+            return "@import " + this._path.toCSS() + features + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset, features = this.features && this.features.eval(env);
+
+        if (this.skip) return [];
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+            ruleset.evalImports(env);
+
+            return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value },
+    compare: function (other) {
+        if (other instanceof tree.Keyword) {
+            return other.value === this.value ? 0 : 1;
+        } else {
+            return -1;
+        }
+    }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Media = function (value, features) {
+    var selectors = this.emptySelectors();
+
+    this.features = new(tree.Value)(features);
+    this.ruleset = new(tree.Ruleset)(selectors, value);
+    this.ruleset.allowImports = true;
+};
+tree.Media.prototype = {
+    toCSS: function (ctx, env) {
+        var features = this.features.toCSS(env);
+
+        this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
+        return '@media ' + features + (env.compress ? '{' : ' {\n  ') +
+               this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                           (env.compress ? '}': '\n}\n');
+    },
+    eval: function (env) {
+        if (!env.mediaBlocks) {
+            env.mediaBlocks = [];
+            env.mediaPath = [];
+        }
+        
+        var media = new(tree.Media)([], []);
+        if(this.debugInfo) {
+            this.ruleset.debugInfo = this.debugInfo;
+            media.debugInfo = this.debugInfo;
+        }
+        media.features = this.features.eval(env);
+        
+        env.mediaPath.push(media);
+        env.mediaBlocks.push(media);
+        
+        env.frames.unshift(this.ruleset);
+        media.ruleset = this.ruleset.eval(env);
+        env.frames.shift();
+        
+        env.mediaPath.pop();
+
+        return env.mediaPath.length === 0 ? media.evalTop(env) :
+                    media.evalNested(env)
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
+    emptySelectors: function() { 
+        var el = new(tree.Element)('', '&', 0);
+        return [new(tree.Selector)([el])];
+    },
+
+    evalTop: function (env) {
+        var result = this;
+
+        // Render all dependent Media blocks.
+        if (env.mediaBlocks.length > 1) {
+            var selectors = this.emptySelectors();
+            result = new(tree.Ruleset)(selectors, env.mediaBlocks);
+            result.multiMedia = true;
+        }
+
+        delete env.mediaBlocks;
+        delete env.mediaPath;
+
+        return result;
+    },
+    evalNested: function (env) {
+        var i, value,
+            path = env.mediaPath.concat([this]);
+
+        // Extract the media-query conditions separated with `,` (OR).
+        for (i = 0; i < path.length; i++) {
+            value = path[i].features instanceof tree.Value ?
+                        path[i].features.value : path[i].features;
+            path[i] = Array.isArray(value) ? value : [value];
+        }
+
+        // Trace all permutations to generate the resulting media-query.
+        //
+        // (a, b and c) with nested (d, e) ->
+        //    a and d
+        //    a and e
+        //    b and c and d
+        //    b and c and e
+        this.features = new(tree.Value)(this.permute(path).map(function (path) {
+            path = path.map(function (fragment) {
+                return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
+            });
+
+            for(i = path.length - 1; i > 0; i--) {
+                path.splice(i, 0, new(tree.Anonymous)("and"));
+            }
+
+            return new(tree.Expression)(path);
+        }));
+
+        // Fake a tree-node that doesn't output anything.
+        return new(tree.Ruleset)([], []);
+    },
+    permute: function (arr) {
+      if (arr.length === 0) {
+          return [];
+      } else if (arr.length === 1) {
+          return arr[0];
+      } else {
+          var result = [];
+          var rest = this.permute(arr.slice(1));
+          for (var i = 0; i < rest.length; i++) {
+              for (var j = 0; j < arr[0].length; j++) {
+                  result.push([arr[0][j]].concat(rest[i]));
+              }
+          }
+          return result;
+      }
+    },
+    bubbleSelectors: function (selectors) {
+      this.ruleset = new(tree.Ruleset)(selectors.slice(0), [this.ruleset]);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+    this.filename = filename;
+    this.important = important;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound;
+
+        args = this.arguments && this.arguments.map(function (a) {
+            return { name: a.name, value: a.value.eval(env) };
+        });
+
+        for (i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                isOneFound = true;
+                for (m = 0; m < mixins.length; m++) {
+                    mixin = mixins[m];
+                    isRecursive = false;
+                    for(f = 0; f < env.frames.length; f++) {
+                        if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) {
+                            isRecursive = true;
+                            break;
+                        }
+                    }
+                    if (isRecursive) {
+                        continue;
+                    }
+                    if (mixin.matchArgs(args, env)) {
+                        if (!mixin.matchCondition || mixin.matchCondition(args, env)) {
+                            try {
+                                Array.prototype.push.apply(
+                                      rules, mixin.eval(env, args, this.important).rules);
+                            } catch (e) {
+                                throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
+                            }
+                        }
+                        match = true;
+                    }
+                }
+                if (match) {
+                    return rules;
+                }
+            }
+        }
+        if (isOneFound) {
+            throw { type:    'Runtime',
+                    message: 'No matching definition was found for `' +
+                              this.selector.toCSS().trim() + '('      +
+                              (args ? args.map(function (a) {
+                                  var argValue = "";
+                                  if (a.name) {
+                                      argValue += a.name + ":";
+                                  }
+                                  if (a.value.toCSS) {
+                                      argValue += a.value.toCSS();
+                                  } else {
+                                      argValue += "???";
+                                  }
+                                  return argValue;
+                              }).join(', ') : "") + ")`",
+                    index:   this.index, filename: this.filename };
+        } else {
+            throw { type: 'Name',
+                message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index, filename: this.filename };
+        }
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition, variadic) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.condition = condition;
+    this.variadic = variadic;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    evalParams: function (env, mixinEnv, args, evaldArguments) {
+        var frame = new(tree.Ruleset)(null, []), varargs, arg, params = this.params.slice(0), i, j, val, name, isNamedFound, argIndex;
+        
+        if (args) {
+            args = args.slice(0);
+
+            for(i = 0; i < args.length; i++) {
+                arg = args[i];
+                if (name = (arg && arg.name)) {
+                    isNamedFound = false;
+                    for(j = 0; j < params.length; j++) {
+                        if (!evaldArguments[j] && name === params[j].name) {
+                            evaldArguments[j] = arg.value.eval(env);
+                            frame.rules.unshift(new(tree.Rule)(name, arg.value.eval(env)));
+                            isNamedFound = true;
+                            break;
+                        }
+                    }
+                    if (isNamedFound) {
+                        args.splice(i, 1);
+                        i--;
+                        continue;
+                    } else {
+                        throw { type: 'Runtime', message: "Named argument for " + this.name +
+                            ' ' + args[i].name + ' not found' };
+                    }
+                }
+            }
+        }
+        argIndex = 0;
+        for (i = 0; i < params.length; i++) {
+            if (evaldArguments[i]) continue;
+            
+            arg = args && args[argIndex];
+
+            if (name = params[i].name) {
+                if (params[i].variadic && args) {
+                    varargs = [];
+                    for (j = argIndex; j < args.length; j++) {
+                        varargs.push(args[j].value.eval(env));
+                    }
+                    frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
+                } else {
+                    val = arg && arg.value;
+                    if (val) {
+                        val = val.eval(env);
+                    } else if (params[i].value) {
+                        val = params[i].value.eval(mixinEnv);
+                    } else {
+                        throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                    }
+                    
+                    frame.rules.unshift(new(tree.Rule)(name, val));
+                    evaldArguments[i] = val;
+                }
+            }
+            
+            if (params[i].variadic && args) {
+                for (j = argIndex; j < args.length; j++) {
+                    evaldArguments[j] = args[j].value.eval(env);
+                }
+            }
+            argIndex++;
+        }
+
+        return frame;
+    },
+    eval: function (env, args, important) {
+        var _arguments = [],
+            mixinFrames = this.frames.concat(env.frames),
+            frame = this.evalParams(env, {frames: mixinFrames}, args, _arguments), 
+            context, rules, start, ruleset;
+
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        rules = important ?
+            this.parent.makeImportant.apply(this).rules : this.rules.slice(0);
+
+        ruleset = new(tree.Ruleset)(null, rules).eval({
+            frames: [this, frame].concat(mixinFrames)
+        });
+        ruleset.originalRuleset = this;
+        return ruleset;
+    },
+    matchCondition: function (args, env) {
+        if (this.condition && !this.condition.eval({
+            frames: [this.evalParams(env, {frames: this.frames.concat(env.frames)}, args, [])].concat(env.frames)
+        }))                                                           { return false }
+        return true;
+    },
+    matchArgs: function (args, env) {
+        var argsLength = (args && args.length) || 0, len, frame;
+
+        if (! this.variadic) {
+            if (argsLength < this.required)                               { return false }
+            if (argsLength > this.params.length)                          { return false }
+            if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+        }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name && !this.params[i].variadic) {
+                if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    if (!a.operate) {
+        throw { name: "OperationError",
+                message: "Operation on an invalid type" };
+    }
+
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
+
+(function (tree) {
+
+tree.Paren = function (node) {
+    this.value = node;
+};
+tree.Paren.prototype = {
+    toCSS: function (env) {
+        return '(' + this.value.toCSS(env) + ')';
+    },
+    eval: function (env) {
+        return new(tree.Paren)(this.value.eval(env));
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return (v instanceof tree.Quoted) ? v.value : v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ratio = function (value) {
+    this.value = value;
+};
+tree.Ratio.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+    this.inline = inline || false;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + (this.inline ? "" : ";");
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name,
+                          this.value.eval(context),
+                          this.important,
+                          this.index, this.inline);
+};
+
+tree.Rule.prototype.makeImportant = function () {
+    return new(tree.Rule)(this.name,
+                          this.value,
+                          "!important",
+                          this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules, strictImports) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+    this.strictImports = strictImports;
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
+        var rules;
+        
+        ruleset.originalRuleset = this;
+        ruleset.root = this.root;
+        ruleset.allowImports = this.allowImports;
+
+        if(this.debugInfo) {
+            ruleset.debugInfo = this.debugInfo;
+        }
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
+            ruleset.evalImports(env);
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+        
+        var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0;
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                rules = ruleset.rules[i].eval(env);
+                ruleset.rules.splice.apply(ruleset.rules, [i, 1].concat(rules));
+                i += rules.length-1;
+                ruleset.resetCache();
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+        
+        if (env.mediaBlocks) {
+            for(var i = mediaBlockCount; i < env.mediaBlocks.length; i++) {
+                env.mediaBlocks[i].bubbleSelectors(selectors);
+            }
+        }
+
+        return ruleset;
+    },
+    evalImports: function(env) {
+        var i, rules;
+        for (i = 0; i < this.rules.length; i++) {
+            if (this.rules[i] instanceof tree.Import) {
+                rules = this.rules[i].eval(env);
+                if (typeof rules.length === "number") {
+                    this.rules.splice.apply(this.rules, [i, 1].concat(rules));
+                    i+= rules.length-1;
+                } else {
+                    this.rules.splice(i, 1, rules);
+                }
+                this.resetCache();
+            }
+        }
+    },
+    makeImportant: function() {
+        return new tree.Ruleset(this.selectors, this.rules.map(function (r) {
+                    if (r.makeImportant) {
+                        return r.makeImportant();
+                    } else {
+                        return r;
+                    }
+                }), this.strictImports);
+    },
+    matchArgs: function (args) {
+        return !args || args.length === 0;
+    },
+    resetCache: function () {
+        this._rulesets = null;
+        this._variables = null;
+        this._lookups = {};
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+           _rules = [],    //
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            debugInfo,     // Line number debugging
+            rule;
+
+        if (! this.root) {
+            this.joinSelectors(paths, context, this.selectors);
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Media)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Directive) {
+                var cssValue = rule.toCSS(paths, env);
+                // Output only the first @charset definition as such - convert the others
+                // to comments in case debug is enabled
+                if (rule.name === "@charset") {
+                    // Only output the debug info together with subsequent @charset definitions
+                    // a comment (or @media statement) before the actual @charset directive would
+                    // be considered illegal css as it has to be on the first line
+                    if (env.charset) {
+                        if (rule.debugInfo) {
+                            rulesets.push(tree.debugInfo(env, rule));
+                            rulesets.push(new tree.Comment("/* "+cssValue.replace(/\n/g, "")+" */\n").toCSS(env));
+                        }
+                        continue;
+                    }
+                    env.charset = true;
+                }
+                rulesets.push(cssValue);
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                debugInfo = tree.debugInfo(env, this);
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : ',\n');
+
+                // Remove duplicates
+                for (var i = rules.length - 1; i >= 0; i--) {
+                    if (_rules.indexOf(rules[i]) === -1) {
+                        _rules.unshift(rules[i]);
+                    }
+                }
+                rules = _rules;
+
+                css.push(debugInfo + selector + 
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('')  + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+
+        var i, j, k, 
+            hasParentSelector, newSelectors, el, sel, parentSel, 
+            newSelectorPath, afterParentJoin, newJoinedSelector, 
+            newJoinedSelectorEmpty, lastSelector, currentElements,
+            selectorsMultiplied;
+    
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.value === '&') {
+                hasParentSelector = true;
+            }
+        }
+    
+        if (!hasParentSelector) {
+            if (context.length > 0) {
+                for(i = 0; i < context.length; i++) {
+                    paths.push(context[i].concat(selector));
+                }
+            }
+            else {
+                paths.push([selector]);
+            }
+            return;
+        }
+
+        // The paths are [[Selector]]
+        // The first list is a list of comma seperated selectors
+        // The inner list is a list of inheritance seperated selectors
+        // e.g.
+        // .a, .b {
+        //   .c {
+        //   }
+        // }
+        // == [[.a] [.c]] [[.b] [.c]]
+        //
+
+        // the elements from the current selector so far
+        currentElements = [];
+        // the current list of new selectors to add to the path.
+        // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
+        // by the parents
+        newSelectors = [[]];
+
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            // non parent reference elements just get added
+            if (el.value !== "&") {
+                currentElements.push(el);
+            } else {
+                // the new list of selectors to add
+                selectorsMultiplied = [];
+
+                // merge the current list of non parent selector elements
+                // on to the current list of selectors to add
+                if (currentElements.length > 0) {
+                    this.mergeElementsOnToSelectors(currentElements, newSelectors);
+                }
+
+                // loop through our current selectors
+                for(j = 0; j < newSelectors.length; j++) {
+                    sel = newSelectors[j];
+                    // if we don't have any parent paths, the & might be in a mixin so that it can be used
+                    // whether there are parents or not
+                    if (context.length == 0) {
+                        // the combinator used on el should now be applied to the next element instead so that
+                        // it is not lost
+                        if (sel.length > 0) {
+                            sel[0].elements = sel[0].elements.slice(0);
+                            sel[0].elements.push(new(tree.Element)(el.combinator, '', 0)); //new Element(el.Combinator,  ""));
+                        }
+                        selectorsMultiplied.push(sel);
+                    }
+                    else {
+                        // and the parent selectors
+                        for(k = 0; k < context.length; k++) {
+                            parentSel = context[k];
+                            // We need to put the current selectors
+                            // then join the last selector's elements on to the parents selectors
+
+                            // our new selector path
+                            newSelectorPath = [];
+                            // selectors from the parent after the join
+                            afterParentJoin = [];
+                            newJoinedSelectorEmpty = true;
+
+                            //construct the joined selector - if & is the first thing this will be empty,
+                            // if not newJoinedSelector will be the last set of elements in the selector
+                            if (sel.length > 0) {
+                                newSelectorPath = sel.slice(0);
+                                lastSelector = newSelectorPath.pop();
+                                newJoinedSelector = new(tree.Selector)(lastSelector.elements.slice(0));
+                                newJoinedSelectorEmpty = false;
+                            }
+                            else {
+                                newJoinedSelector = new(tree.Selector)([]);
+                            }
+
+                            //put together the parent selectors after the join
+                            if (parentSel.length > 1) {
+                                afterParentJoin = afterParentJoin.concat(parentSel.slice(1));
+                            }
+
+                            if (parentSel.length > 0) {
+                                newJoinedSelectorEmpty = false;
+
+                                // join the elements so far with the first part of the parent
+                                newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, 0));
+                                newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1));
+                            }
+
+                            if (!newJoinedSelectorEmpty) {
+                                // now add the joined selector
+                                newSelectorPath.push(newJoinedSelector);
+                            }
+
+                            // and the rest of the parent
+                            newSelectorPath = newSelectorPath.concat(afterParentJoin);
+
+                            // add that to our new set of selectors
+                            selectorsMultiplied.push(newSelectorPath);
+                        }
+                    }
+                }
+
+                // our new selectors has been multiplied, so reset the state
+                newSelectors = selectorsMultiplied;
+                currentElements = [];
+            }
+        }
+
+        // if we have any elements left over (e.g. .a& .b == .b)
+        // add them on to all the current selectors
+        if (currentElements.length > 0) {
+            this.mergeElementsOnToSelectors(currentElements, newSelectors);
+        }
+
+        for(i = 0; i < newSelectors.length; i++) {
+            paths.push(newSelectors[i]);
+        }
+    },
+    
+    mergeElementsOnToSelectors: function(elements, selectors) {
+        var i, sel;
+
+        if (selectors.length == 0) {
+            selectors.push([ new(tree.Selector)(elements) ]);
+            return;
+        }
+
+        for(i = 0; i < selectors.length; i++) {
+            sel = selectors[i];
+
+            // if the previous thing in sel is a parent this needs to join on to it
+            if (sel.length > 0) {
+                sel[sel.length - 1] = new(tree.Selector)(sel[sel.length - 1].elements.concat(elements));
+            }
+            else {
+                sel.push(new(tree.Selector)(elements));
+            }
+        }
+    }
+};
+})(require('../tree'));
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+};
+tree.Selector.prototype.match = function (other) {
+    var elements = this.elements,
+        len = elements.length,
+        oelements, olen, max, i;
+
+    oelements = other.elements.slice(
+        (other.elements.length && other.elements[0].value === "&") ? 1 : 0);
+    olen = oelements.length;
+    max = Math.min(len, olen)
+
+    if (olen === 0 || len < olen) {
+        return false;
+    } else {
+        for (i = 0; i < max; i++) {
+            if (elements[i].value !== oelements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.eval = function (env) {
+    return new(tree.Selector)(this.elements.map(function (e) {
+        return e.eval(env);
+    }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+    
+    if (this.elements[0].combinator.value === "") {
+        this._css = ' ';
+    } else {
+        this._css = '';
+    }
+    
+    this._css += this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+    
+    return this._css;
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.UnicodeDescriptor = function (value) {
+    this.value = value;
+};
+tree.UnicodeDescriptor.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.URL = function (val, rootpath) {
+    this.value = val;
+    this.rootpath = rootpath;
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + this.value.toCSS() + ")";
+    },
+    eval: function (ctx) {
+        var val = this.value.eval(ctx), rootpath;
+
+        // Add the base path if the URL is relative
+        if (typeof val.value === "string" && !/^(?:[a-z-]+:|\/)/.test(val.value)) {
+            rootpath = this.rootpath;
+            if (!val.quote) {
+                rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; });
+            }
+            val.value = rootpath + val.value;
+        }
+
+        return new(tree.URL)(val, this.rootpath);
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+        
+        if (this.evaluating) {
+            throw { type: 'Name',
+                    message: "Recursive variable definition for " + name,
+                    filename: this.file,
+                    index: this.index };
+        }
+        
+        this.evaluating = true;
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { 
+            this.evaluating = false;
+            return variable;
+        }
+        else {
+            throw { type: 'Name',
+                    message: "variable " + name + " is undefined",
+                    filename: this.file,
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
+(function (tree) {
+
+tree.debugInfo = function(env, ctx) {
+    var result="";
+    if (env.dumpLineNumbers && !env.compress) {
+        switch(env.dumpLineNumbers) {
+            case 'comments':
+                result = tree.debugInfo.asComment(ctx);
+                break;
+            case 'mediaquery':
+                result = tree.debugInfo.asMediaQuery(ctx);
+                break;
+            case 'all':
+                result = tree.debugInfo.asComment(ctx)+tree.debugInfo.asMediaQuery(ctx);
+                break;
+        }
+    }
+    return result;
+};
+
+tree.debugInfo.asComment = function(ctx) {
+    return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
+};
+
+tree.debugInfo.asMediaQuery = function(ctx) {
+    return '@media -sass-debug-info{filename{font-family:' +
+        ('file://' + ctx.debugInfo.fileName).replace(/[\/:.]/g, '\\$&') +
+        '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n';
+};
+
+tree.find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+tree.jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+
+})(require('./tree'));
+var name;
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var endOfPath = Math.max(name.lastIndexOf('/'), name.lastIndexOf('\\')),
+        sheetName = name.slice(0, endOfPath + 1) + sheet.href,
+        contents = sheet.contents || {},
+        input = readFile(sheetName);
+        
+    contents[sheetName] = input;
+        
+    var parser = new less.Parser({
+        paths: [sheet.href.replace(/[\w\.-]+$/, '')],
+        contents: contents
+    });
+    parser.parse(input, function (e, root) {
+        if (e) {
+            return error(e, sheetName);
+        }
+        try {
+            callback(e, root, input, sheet, { local: false, lastModified: 0, remaining: remaining }, sheetName);
+        } catch(e) {
+            error(e, sheetName);
+        }
+    });
+}
+
+function writeFile(filename, content) {
+    var fstream = new java.io.FileWriter(filename);
+    var out = new java.io.BufferedWriter(fstream);
+    out.write(content);
+    out.close();
+}
+
+// Command line integration via Rhino
+(function (args) {
+    var output,
+        compress = false,
+        i;
+        
+    for(i = 0; i < args.length; i++) {
+        switch(args[i]) {
+            case "-x":
+                compress = true;
+                break;
+            default:
+                if (!name) {
+                    name = args[i];
+                } else if (!output) {
+                    output = args[i];
+                } else {
+                    print("unrecognised parameters");
+                    print("input_file [output_file] [-x]");
+                }
+        }
+    }
+
+    if (!name) {
+        print('No files present in the fileset; Check your pattern match in build.xml');
+        quit(1);
+    }
+    path = name.split("/");path.pop();path=path.join("/")
+
+    var input = readFile(name);
+
+    if (!input) {
+        print('lesscss: couldn\'t open file ' + name);
+        quit(1);
+    }
+
+    var result;
+    try {
+        var parser = new less.Parser();
+        parser.parse(input, function (e, root) {
+            if (e) {
+                error(e, name);
+                quit(1);
+            } else {
+                result = root.toCSS({compress: compress || false});
+                if (output) {
+                    writeFile(output, result);
+                    print("Written to " + output);
+                } else {
+                    print(result);
+                }
+                quit(0);
+            }
+        });
+    }
+    catch(e) {
+        error(e, name);
+        quit(1);
+    }
+    print("done");
+}(arguments));
+
+function error(e, filename) {
+
+    var content = "Error : " + filename + "\n";
+    
+    filename = e.filename || filename;
+    
+    if (e.message) {
+        content += e.message + "\n";
+    }
+
+    var errorline = function (e, i, classname) {
+        if (e.extract[i]) {
+            content += 
+                String(parseInt(e.line) + (i - 1)) + 
+                ":" + e.extract[i] + "\n";
+        }
+    };
+
+    if (e.stack) {
+        content += e.stack;
+    } else if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n';
+        errorline(e, 0);
+        errorline(e, 1);
+        errorline(e, 2);
+    }
+   print(content);
+}
\ No newline at end of file
diff --git a/util/less/functions.js b/util/less/functions.js
deleted file mode 100755
index 804b9e6..0000000
--- a/util/less/functions.js
+++ /dev/null
@@ -1,174 +0,0 @@
-(function (tree) {
-
-tree.functions = {
-    rgb: function (r, g, b) {
-        return this.rgba(r, g, b, 1.0);
-    },
-    rgba: function (r, g, b, a) {
-        var rgb = [r, g, b].map(function (c) { return number(c) }),
-            a = number(a);
-        return new(tree.Color)(rgb, a);
-    },
-    hsl: function (h, s, l) {
-        return this.hsla(h, s, l, 1.0);
-    },
-    hsla: function (h, s, l, a) {
-        h = (number(h) % 360) / 360;
-        s = number(s); l = number(l); a = number(a);
-
-        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
-        var m1 = l * 2 - m2;
-
-        return this.rgba(hue(h + 1/3) * 255,
-                         hue(h)       * 255,
-                         hue(h - 1/3) * 255,
-                         a);
-
-        function hue(h) {
-            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
-            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
-            else if (h * 2 < 1) return m2;
-            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
-            else                return m1;
-        }
-    },
-    hue: function (color) {
-        return new(tree.Dimension)(Math.round(color.toHSL().h));
-    },
-    saturation: function (color) {
-        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
-    },
-    lightness: function (color) {
-        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
-    },
-    alpha: function (color) {
-        return new(tree.Dimension)(color.toHSL().a);
-    },
-    saturate: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.s += amount.value / 100;
-        hsl.s = clamp(hsl.s);
-        return hsla(hsl);
-    },
-    desaturate: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.s -= amount.value / 100;
-        hsl.s = clamp(hsl.s);
-        return hsla(hsl);
-    },
-    lighten: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.l += amount.value / 100;
-        hsl.l = clamp(hsl.l);
-        return hsla(hsl);
-    },
-    darken: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.l -= amount.value / 100;
-        hsl.l = clamp(hsl.l);
-        return hsla(hsl);
-    },
-    fadein: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.a += amount.value / 100;
-        hsl.a = clamp(hsl.a);
-        return hsla(hsl);
-    },
-    fadeout: function (color, amount) {
-        var hsl = color.toHSL();
-
-        hsl.a -= amount.value / 100;
-        hsl.a = clamp(hsl.a);
-        return hsla(hsl);
-    },
-    spin: function (color, amount) {
-        var hsl = color.toHSL();
-        var hue = (hsl.h + amount.value) % 360;
-
-        hsl.h = hue < 0 ? 360 + hue : hue;
-
-        return hsla(hsl);
-    },
-    //
-    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
-    // http://sass-lang.com
-    //
-    mix: function (color1, color2, weight) {
-        var p = weight.value / 100.0;
-        var w = p * 2 - 1;
-        var a = color1.toHSL().a - color2.toHSL().a;
-
-        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
-        var w2 = 1 - w1;
-
-        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
-                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
-                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
-
-        var alpha = color1.alpha * p + color2.alpha * (1 - p);
-
-        return new(tree.Color)(rgb, alpha);
-    },
-    greyscale: function (color) {
-        return this.desaturate(color, new(tree.Dimension)(100));
-    },
-    e: function (str) {
-        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
-    },
-    escape: function (str) {
-        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
-    },
-    '%': function (quoted /* arg, arg, ...*/) {
-        var args = Array.prototype.slice.call(arguments, 1),
-            str = quoted.value;
-
-        for (var i = 0; i < args.length; i++) {
-            str = str.replace(/%[sda]/i, function(token) {
-                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
-                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
-            });
-        }
-        str = str.replace(/%%/g, '%');
-        return new(tree.Quoted)('"' + str + '"', str);
-    },
-    round: function (n) {
-        if (n instanceof tree.Dimension) {
-            return new(tree.Dimension)(Math.round(number(n)), n.unit);
-        } else if (typeof(n) === 'number') {
-            return Math.round(n);
-        } else {
-	    throw {
-                error: "RuntimeError",
-                message: "math functions take numbers as parameters"
-            };
-        }
-    }
-};
-
-function hsla(hsla) {
-    return tree.functions.hsla(hsla.h, hsla.s, hsla.l, hsla.a);
-}
-
-function number(n) {
-    if (n instanceof tree.Dimension) {
-        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
-    } else if (typeof(n) === 'number') {
-        return n;
-    } else {
-        throw {
-            error: "RuntimeError",
-            message: "color functions take numbers as parameters"
-        };
-    }
-}
-
-function clamp(val) {
-    return Math.min(1, Math.max(0, val));
-}
-
-})(require('less/tree'));
diff --git a/util/less/index.js b/util/less/index.js
deleted file mode 100755
index 4c341f5..0000000
--- a/util/less/index.js
+++ /dev/null
@@ -1,137 +0,0 @@
-var path = require('path'),
-    sys = require('sys'),
-    fs = require('fs');
-
-require.paths.unshift(path.join(__dirname, '..'));
-
-var less = {
-    version: [1, 1, 3],
-    Parser: require('less/parser').Parser,
-    importer: require('less/parser').importer,
-    tree: require('less/tree'),
-    render: function (input, options, callback) {
-        options = options || {};
-
-        if (typeof(options) === 'function') {
-            callback = options, options = {};
-        }
-
-        var parser = new(this.Parser)(options),
-            ee;
-
-        if (callback) {
-            parser.parse(input, function (e, root) {
-                callback(e, root.toCSS(options));
-            });
-        } else {
-            ee = new(require('events').EventEmitter);
-
-            process.nextTick(function () {
-                parser.parse(input, function (e, root) {
-                    if (e) { ee.emit('error', e) }
-                    else   { ee.emit('success', root.toCSS(options)) }
-                });
-            });
-            return ee;
-        }
-    },
-    writeError: function (ctx, options) {
-        var message = "";
-        var extract = ctx.extract;
-        var error = [];
-
-        options = options || {};
-
-        if (options.silent) { return }
-
-        if (!ctx.index) {
-            return sys.error(ctx.stack || ctx.message);
-        }
-
-        if (typeof(extract[0]) === 'string') {
-            error.push(stylize((ctx.line - 1) + ' ' + extract[0], 'grey'));
-        }
-
-        error.push(ctx.line + ' ' + extract[1].slice(0, ctx.column)
-                            + stylize(stylize(extract[1][ctx.column], 'bold')
-                            + extract[1].slice(ctx.column + 1), 'yellow'));
-
-        if (typeof(extract[2]) === 'string') {
-            error.push(stylize((ctx.line + 1) + ' ' + extract[2], 'grey'));
-        }
-        error = error.join('\n') + '\033[0m\n';
-
-        message += stylize(ctx.message, 'red');
-        ctx.filename && (message += stylize(' in ', 'red') + ctx.filename);
-
-        sys.error(message, error);
-
-        if (ctx.callLine) {
-            sys.error(stylize('from ', 'red')       + (ctx.filename || ''));
-            sys.error(stylize(ctx.callLine, 'grey') + ' ' + ctx.callExtract);
-        }
-        if (ctx.stack) { sys.error(stylize(ctx.stack, 'red')) }
-    }
-};
-
-['color',    'directive', 'operation',  'dimension',
- 'keyword',  'variable',  'ruleset',    'element',
- 'selector', 'quoted',    'expression', 'rule',
- 'call',     'url',       'alpha',      'import',
- 'mixin',    'comment',   'anonymous',  'value', 'javascript'
-].forEach(function (n) {
-    require(path.join('less', 'tree', n));
-});
-
-less.Parser.importer = function (file, paths, callback) {
-    var pathname;
-
-    paths.unshift('.');
-
-    for (var i = 0; i < paths.length; i++) {
-        try {
-            pathname = path.join(paths[i], file);
-            fs.statSync(pathname);
-            break;
-        } catch (e) {
-            pathname = null;
-        }
-    }
-
-    if (pathname) {
-        fs.readFile(pathname, 'utf-8', function(e, data) {
-          if (e) sys.error(e);
-
-          new(less.Parser)({
-              paths: [path.dirname(pathname)],
-              filename: pathname
-          }).parse(data, function (e, root) {
-              if (e) less.writeError(e);
-              callback(root);
-          });
-        });
-    } else {
-        sys.error("file '" + file + "' wasn't found.\n");
-        process.exit(1);
-    }
-}
-
-require('less/functions');
-
-for (var k in less) { exports[k] = less[k] }
-
-// Stylize a string
-function stylize(str, style) {
-    var styles = {
-        'bold'      : [1,  22],
-        'inverse'   : [7,  27],
-        'underline' : [4,  24],
-        'yellow'    : [33, 39],
-        'green'     : [32, 39],
-        'red'       : [31, 39],
-        'grey'      : [90, 39]
-    };
-    return '\033[' + styles[style][0] + 'm' + str +
-           '\033[' + styles[style][1] + 'm';
-}
-
diff --git a/util/less/lib/less/browser.js b/util/less/lib/less/browser.js
new file mode 100644
index 0000000..e00ff27
--- /dev/null
+++ b/util/less/lib/less/browser.js
@@ -0,0 +1,519 @@
+//
+// browser.js - client-side engine
+//
+
+var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol);
+
+less.env = less.env || (location.hostname == '127.0.0.1' ||
+                        location.hostname == '0.0.0.0'   ||
+                        location.hostname == 'localhost' ||
+                        location.port.length > 0         ||
+                        isFileProtocol                   ? 'development'
+                                                         : 'production');
+
+// Load styles asynchronously (default: false)
+//
+// This is set to `false` by default, so that the body
+// doesn't start loading before the stylesheets are parsed.
+// Setting this to `true` can result in flickering.
+//
+less.async = less.async || false;
+less.fileAsync = less.fileAsync || false;
+
+// Interval between watch polls
+less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+
+//Setup user functions
+if (less.functions) {
+    for(var func in less.functions) {
+        less.tree.functions[func] = less.functions[func];
+   }
+}
+
+var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);
+if (dumpLineNumbers) {
+    less.dumpLineNumbers = dumpLineNumbers[1];
+}
+
+//
+// Watch mode
+//
+less.watch   = function () {	
+	if (!less.watchMode ){		
+		less.env = 'development';
+		initRunningMode();
+	}
+	return this.watchMode = true 
+};
+
+less.unwatch = function () {clearInterval(less.watchTimer); return this.watchMode = false; };
+
+function initRunningMode(){
+	if (less.env === 'development') {		
+		less.optimization = 0;		
+		less.watchTimer = setInterval(function () {			
+			if (less.watchMode) {
+				loadStyleSheets(function (e, root, _, sheet, env) {
+					if (root) {
+						createCSS(root.toCSS(), sheet, env.lastModified);
+					}
+				});
+			}
+		}, less.poll);
+	} else {
+		less.optimization = 3;
+	}
+}
+
+if (/!watch/.test(location.hash)) {
+	less.watch();
+}
+
+var cache = null;
+
+if (less.env != 'development') {
+    try {
+        cache = (typeof(window.localStorage) === 'undefined') ? null : window.localStorage;
+    } catch (_) {}
+}
+
+//
+// Get all <link> tags with the 'rel' attribute set to "stylesheet/less"
+//
+var links = document.getElementsByTagName('link');
+var typePattern = /^text\/(x-)?less$/;
+
+less.sheets = [];
+
+for (var i = 0; i < links.length; i++) {
+    if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+       (links[i].type.match(typePattern)))) {
+        less.sheets.push(links[i]);
+    }
+}
+
+//
+// With this function, it's possible to alter variables and re-render
+// CSS without reloading less-files
+//
+var session_cache = '';
+less.modifyVars = function(record) {
+	var str = session_cache;
+    for (name in record) {
+        str += ((name.slice(0,1) === '@')? '' : '@') + name +': '+ 
+                ((record[name].slice(-1) === ';')? record[name] : record[name] +';');
+    }
+    new(less.Parser)().parse(str, function (e, root) {
+        createCSS(root.toCSS(), less.sheets[less.sheets.length - 1]);
+    });
+};
+
+less.refresh = function (reload) {
+    var startTime, endTime;
+    startTime = endTime = new(Date);
+
+    loadStyleSheets(function (e, root, _, sheet, env) {
+        if (env.local) {
+            log("loading " + sheet.href + " from cache.");
+        } else {
+            log("parsed " + sheet.href + " successfully.");
+            createCSS(root.toCSS(), sheet, env.lastModified);
+        }
+        log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
+        (env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
+        endTime = new(Date);
+    }, reload);
+
+    loadStyles();
+};
+less.refreshStyles = loadStyles;
+
+less.refresh(less.env === 'development');
+
+function loadStyles() {
+    var styles = document.getElementsByTagName('style');
+    for (var i = 0; i < styles.length; i++) {
+        if (styles[i].type.match(typePattern)) {
+            new(less.Parser)({
+                filename: document.location.href.replace(/#.*$/, ''),
+                dumpLineNumbers: less.dumpLineNumbers
+            }).parse(styles[i].innerHTML || '', function (e, tree) {
+                var css = tree.toCSS();
+                var style = styles[i];
+                style.type = 'text/css';
+                if (style.styleSheet) {
+                    style.styleSheet.cssText = css;
+                } else {
+                    style.innerHTML = css;
+                }
+            });
+        }
+    }
+}
+
+function loadStyleSheets(callback, reload) {
+    for (var i = 0; i < less.sheets.length; i++) {
+        loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1));
+    }
+}
+
+function pathDiff(url, baseUrl) {
+    // diff between two paths to create a relative path
+
+    var urlParts = extractUrlParts(url),
+        baseUrlParts = extractUrlParts(baseUrl),
+        i, max, urlDirectories, baseUrlDirectories, diff = "";
+    if (urlParts.hostPart !== baseUrlParts.hostPart) {
+        return "";
+    }
+    max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
+    for(i = 0; i < max; i++) {
+        if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }
+    }
+    baseUrlDirectories = baseUrlParts.directories.slice(i);
+    urlDirectories = urlParts.directories.slice(i);
+    for(i = 0; i < baseUrlDirectories.length-1; i++) {
+        diff += "../";
+    }
+    for(i = 0; i < urlDirectories.length-1; i++) {
+        diff += urlDirectories[i] + "/";
+    }
+    return diff;
+}
+
+function extractUrlParts(url, baseUrl) {
+    // urlParts[1] = protocol&hostname || /
+    // urlParts[2] = / if path relative to host base
+    // urlParts[3] = directories
+    // urlParts[4] = filename
+    // urlParts[5] = parameters
+
+    var urlPartsRegex = /^((?:[a-z-]+:)?\/\/(?:[^\/\?#]+\/)|([\/\\]))?((?:[^\/\\\?#]+[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/,
+        urlParts = url.match(urlPartsRegex),
+        returner = {}, directories = [], i, baseUrlParts;
+
+    if (!urlParts) {
+        throw new Error("Could not parse sheet href - '"+url+"'");
+    }
+
+    // Stylesheets in IE don't always return the full path    
+    if (!urlParts[1] || urlParts[2]) {
+        baseUrlParts = baseUrl.match(urlPartsRegex);
+        if (!baseUrlParts) {
+            throw new Error("Could not parse page url - '"+baseUrl+"'");
+        }
+        urlParts[1] = baseUrlParts[1];
+        if (!urlParts[2]) {
+            urlParts[3] = baseUrlParts[3] + urlParts[3];
+        }
+    }
+    
+    if (urlParts[3]) {
+        directories = urlParts[3].replace("\\", "/").split("/");
+
+        for(i = 0; i < directories.length; i++) {
+            if (directories[i] === ".." && i > 0) {
+                directories.splice(i-1, 2);
+                i -= 2;
+            }
+        }
+    }
+
+    returner.hostPart = urlParts[1];
+    returner.directories = directories;
+    returner.path = urlParts[1] + directories.join("/");
+    returner.fileUrl = returner.path + (urlParts[4] || "");
+    returner.url = returner.fileUrl + (urlParts[5] || "");
+    return returner;
+}
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    // sheet may be set to the stylesheet for the initial load or a collection of properties including
+    // some env variables for imports
+    var contents  = sheet.contents || {};
+    var files     = sheet.files || {};
+    var hrefParts = extractUrlParts(sheet.href, window.location.href);
+    var href      = hrefParts.url;
+    var css       = cache && cache.getItem(href);
+    var timestamp = cache && cache.getItem(href + ':timestamp');
+    var styles    = { css: css, timestamp: timestamp };
+    var rootpath;
+
+    if (less.relativeUrls) {
+        if (less.rootpath) {
+            if (sheet.entryPath) {
+                rootpath = extractUrlParts(less.rootpath + pathDiff(hrefParts.path, sheet.entryPath)).path;
+            } else {
+                rootpath = less.rootpath;
+            }
+        } else {
+            rootpath = hrefParts.path;
+        }
+    } else  {
+        if (less.rootpath) {
+            rootpath = less.rootpath;
+        } else {
+            if (sheet.entryPath) {
+                rootpath = sheet.entryPath;
+            } else {
+                rootpath = hrefParts.path;
+            }
+        }
+    }
+
+    xhr(href, sheet.type, function (data, lastModified) {
+        // Store data this session
+        session_cache += data.replace(/@import .+?;/ig, '');
+
+        if (!reload && styles && lastModified &&
+           (new(Date)(lastModified).valueOf() ===
+            new(Date)(styles.timestamp).valueOf())) {
+            // Use local copy
+            createCSS(styles.css, sheet);
+            callback(null, null, data, sheet, { local: true, remaining: remaining }, href);
+        } else {
+            // Use remote copy (re-parse)
+            try {
+                contents[href] = data;  // Updating top importing parser content cache
+                new(less.Parser)({
+                    optimization: less.optimization,
+                    paths: [hrefParts.path],
+                    entryPath: sheet.entryPath || hrefParts.path,
+                    mime: sheet.type,
+                    filename: href,
+                    rootpath: rootpath,
+                    relativeUrls: sheet.relativeUrls,
+                    contents: contents,    // Passing top importing parser content cache ref down.
+                    files: files,
+                    dumpLineNumbers: less.dumpLineNumbers
+                }).parse(data, function (e, root) {
+                    if (e) { return error(e, href) }
+                    try {
+                        callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining }, href);
+                        removeNode(document.getElementById('less-error-message:' + extractId(href)));
+                    } catch (e) {
+                        error(e, href);
+                    }
+                });
+            } catch (e) {
+                error(e, href);
+            }
+        }
+    }, function (status, url) {
+        throw new(Error)("Couldn't load " + url + " (" + status + ")");
+    });
+}
+
+function extractId(href) {
+    return href.replace(/^[a-z]+:\/\/?[^\/]+/, '' )  // Remove protocol & domain
+               .replace(/^\//,                 '' )  // Remove root /
+               .replace(/\.[a-zA-Z]+$/,        '' )  // Remove simple extension
+               .replace(/[^\.\w-]+/g,          '-')  // Replace illegal characters
+               .replace(/\./g,                 ':'); // Replace dots with colons(for valid id)
+}
+
+function createCSS(styles, sheet, lastModified) {
+    var css;
+
+    // Strip the query-string
+    var href = sheet.href || '';
+
+    // If there is no title set, use the filename, minus the extension
+    var id = 'less:' + (sheet.title || extractId(href));
+
+    // If the stylesheet doesn't exist, create a new node
+    if ((css = document.getElementById(id)) === null) {
+        css = document.createElement('style');
+        css.type = 'text/css';
+        if( sheet.media ){ css.media = sheet.media; }
+        css.id = id;
+        var nextEl = sheet && sheet.nextSibling || null;
+        (nextEl || document.getElementsByTagName('head')[0]).parentNode.insertBefore(css, nextEl);
+    }
+
+    if (css.styleSheet) { // IE
+        try {
+            css.styleSheet.cssText = styles;
+        } catch (e) {
+            throw new(Error)("Couldn't reassign styleSheet.cssText.");
+        }
+    } else {
+        (function (node) {
+            if (css.childNodes.length > 0) {
+                if (css.firstChild.nodeValue !== node.nodeValue) {
+                    css.replaceChild(node, css.firstChild);
+                }
+            } else {
+                css.appendChild(node);
+            }
+        })(document.createTextNode(styles));
+    }
+
+    // Don't update the local store if the file wasn't modified
+    if (lastModified && cache) {
+        log('saving ' + href + ' to cache.');
+        try {
+            cache.setItem(href, styles);
+            cache.setItem(href + ':timestamp', lastModified);
+        } catch(e) {
+            //TODO - could do with adding more robust error handling
+            log('failed to save');
+        }
+    }
+}
+
+function xhr(url, type, callback, errback) {
+    var xhr = getXMLHttpRequest();
+    var async = isFileProtocol ? less.fileAsync : less.async;
+
+    if (typeof(xhr.overrideMimeType) === 'function') {
+        xhr.overrideMimeType('text/css');
+    }
+    xhr.open('GET', url, async);
+    xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
+    xhr.send(null);
+
+    if (isFileProtocol && !less.fileAsync) {
+        if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
+            callback(xhr.responseText);
+        } else {
+            errback(xhr.status, url);
+        }
+    } else if (async) {
+        xhr.onreadystatechange = function () {
+            if (xhr.readyState == 4) {
+                handleResponse(xhr, callback, errback);
+            }
+        };
+    } else {
+        handleResponse(xhr, callback, errback);
+    }
+
+    function handleResponse(xhr, callback, errback) {
+        if (xhr.status >= 200 && xhr.status < 300) {
+            callback(xhr.responseText,
+                     xhr.getResponseHeader("Last-Modified"));
+        } else if (typeof(errback) === 'function') {
+            errback(xhr.status, url);
+        }
+    }
+}
+
+function getXMLHttpRequest() {
+    if (window.XMLHttpRequest) {
+        return new(XMLHttpRequest);
+    } else {
+        try {
+            return new(ActiveXObject)("MSXML2.XMLHTTP.3.0");
+        } catch (e) {
+            log("browser doesn't support AJAX.");
+            return null;
+        }
+    }
+}
+
+function removeNode(node) {
+    return node && node.parentNode.removeChild(node);
+}
+
+function log(str) {
+    if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
+}
+
+function error(e, href) {
+    var id = 'less-error-message:' + extractId(href);
+    var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+    var elem = document.createElement('div'), timer, content, error = [];
+    var filename = e.filename || href;
+    var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1];
+
+    elem.id        = id;
+    elem.className = "less-error-message";
+
+    content = '<h3>'  + (e.message || 'There is an error in your .less file') +
+              '</h3>' + '<p>in <a href="' + filename   + '">' + filenameNoPath + "</a> ";
+
+    var errorline = function (e, i, classname) {
+        if (e.extract[i]) {
+            error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
+                               .replace(/\{class\}/, classname)
+                               .replace(/\{content\}/, e.extract[i]));
+        }
+    };
+
+    if (e.stack) {
+        content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+    } else if (e.extract) {
+        errorline(e, 0, '');
+        errorline(e, 1, 'line');
+        errorline(e, 2, '');
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+                    '<ul>' + error.join('') + '</ul>';
+    }
+    elem.innerHTML = content;
+
+    // CSS for error messages
+    createCSS([
+        '.less-error-message ul, .less-error-message li {',
+            'list-style-type: none;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message label {',
+            'font-size: 12px;',
+            'margin-right: 15px;',
+            'padding: 4px 0;',
+            'color: #cc7777;',
+        '}',
+        '.less-error-message pre {',
+            'color: #dd6666;',
+            'padding: 4px 0;',
+            'margin: 0;',
+            'display: inline-block;',
+        '}',
+        '.less-error-message pre.line {',
+            'color: #ff0000;',
+        '}',
+        '.less-error-message h3 {',
+            'font-size: 20px;',
+            'font-weight: bold;',
+            'padding: 15px 0 5px 0;',
+            'margin: 0;',
+        '}',
+        '.less-error-message a {',
+            'color: #10a',
+        '}',
+        '.less-error-message .error {',
+            'color: red;',
+            'font-weight: bold;',
+            'padding-bottom: 2px;',
+            'border-bottom: 1px dashed red;',
+        '}'
+    ].join('\n'), { title: 'error-message' });
+
+    elem.style.cssText = [
+        "font-family: Arial, sans-serif",
+        "border: 1px solid #e00",
+        "background-color: #eee",
+        "border-radius: 5px",
+        "-webkit-border-radius: 5px",
+        "-moz-border-radius: 5px",
+        "color: #e00",
+        "padding: 15px",
+        "margin-bottom: 15px"
+    ].join(';');
+
+    if (less.env == 'development') {
+        timer = setInterval(function () {
+            if (document.body) {
+                if (document.getElementById(id)) {
+                    document.body.replaceChild(elem, document.getElementById(id));
+                } else {
+                    document.body.insertBefore(elem, document.body.firstChild);
+                }
+                clearInterval(timer);
+            }
+        }, 10);
+    }
+}
diff --git a/util/less/lib/less/colors.js b/util/less/lib/less/colors.js
new file mode 100644
index 0000000..b417af6
--- /dev/null
+++ b/util/less/lib/less/colors.js
@@ -0,0 +1,152 @@
+(function (tree) {
+    tree.colors = {
+        'aliceblue':'#f0f8ff',
+        'antiquewhite':'#faebd7',
+        'aqua':'#00ffff',
+        'aquamarine':'#7fffd4',
+        'azure':'#f0ffff',
+        'beige':'#f5f5dc',
+        'bisque':'#ffe4c4',
+        'black':'#000000',
+        'blanchedalmond':'#ffebcd',
+        'blue':'#0000ff',
+        'blueviolet':'#8a2be2',
+        'brown':'#a52a2a',
+        'burlywood':'#deb887',
+        'cadetblue':'#5f9ea0',
+        'chartreuse':'#7fff00',
+        'chocolate':'#d2691e',
+        'coral':'#ff7f50',
+        'cornflowerblue':'#6495ed',
+        'cornsilk':'#fff8dc',
+        'crimson':'#dc143c',
+        'cyan':'#00ffff',
+        'darkblue':'#00008b',
+        'darkcyan':'#008b8b',
+        'darkgoldenrod':'#b8860b',
+        'darkgray':'#a9a9a9',
+        'darkgrey':'#a9a9a9',
+        'darkgreen':'#006400',
+        'darkkhaki':'#bdb76b',
+        'darkmagenta':'#8b008b',
+        'darkolivegreen':'#556b2f',
+        'darkorange':'#ff8c00',
+        'darkorchid':'#9932cc',
+        'darkred':'#8b0000',
+        'darksalmon':'#e9967a',
+        'darkseagreen':'#8fbc8f',
+        'darkslateblue':'#483d8b',
+        'darkslategray':'#2f4f4f',
+        'darkslategrey':'#2f4f4f',
+        'darkturquoise':'#00ced1',
+        'darkviolet':'#9400d3',
+        'deeppink':'#ff1493',
+        'deepskyblue':'#00bfff',
+        'dimgray':'#696969',
+        'dimgrey':'#696969',
+        'dodgerblue':'#1e90ff',
+        'firebrick':'#b22222',
+        'floralwhite':'#fffaf0',
+        'forestgreen':'#228b22',
+        'fuchsia':'#ff00ff',
+        'gainsboro':'#dcdcdc',
+        'ghostwhite':'#f8f8ff',
+        'gold':'#ffd700',
+        'goldenrod':'#daa520',
+        'gray':'#808080',
+        'grey':'#808080',
+        'green':'#008000',
+        'greenyellow':'#adff2f',
+        'honeydew':'#f0fff0',
+        'hotpink':'#ff69b4',
+        'indianred':'#cd5c5c',
+        'indigo':'#4b0082',
+        'ivory':'#fffff0',
+        'khaki':'#f0e68c',
+        'lavender':'#e6e6fa',
+        'lavenderblush':'#fff0f5',
+        'lawngreen':'#7cfc00',
+        'lemonchiffon':'#fffacd',
+        'lightblue':'#add8e6',
+        'lightcoral':'#f08080',
+        'lightcyan':'#e0ffff',
+        'lightgoldenrodyellow':'#fafad2',
+        'lightgray':'#d3d3d3',
+        'lightgrey':'#d3d3d3',
+        'lightgreen':'#90ee90',
+        'lightpink':'#ffb6c1',
+        'lightsalmon':'#ffa07a',
+        'lightseagreen':'#20b2aa',
+        'lightskyblue':'#87cefa',
+        'lightslategray':'#778899',
+        'lightslategrey':'#778899',
+        'lightsteelblue':'#b0c4de',
+        'lightyellow':'#ffffe0',
+        'lime':'#00ff00',
+        'limegreen':'#32cd32',
+        'linen':'#faf0e6',
+        'magenta':'#ff00ff',
+        'maroon':'#800000',
+        'mediumaquamarine':'#66cdaa',
+        'mediumblue':'#0000cd',
+        'mediumorchid':'#ba55d3',
+        'mediumpurple':'#9370d8',
+        'mediumseagreen':'#3cb371',
+        'mediumslateblue':'#7b68ee',
+        'mediumspringgreen':'#00fa9a',
+        'mediumturquoise':'#48d1cc',
+        'mediumvioletred':'#c71585',
+        'midnightblue':'#191970',
+        'mintcream':'#f5fffa',
+        'mistyrose':'#ffe4e1',
+        'moccasin':'#ffe4b5',
+        'navajowhite':'#ffdead',
+        'navy':'#000080',
+        'oldlace':'#fdf5e6',
+        'olive':'#808000',
+        'olivedrab':'#6b8e23',
+        'orange':'#ffa500',
+        'orangered':'#ff4500',
+        'orchid':'#da70d6',
+        'palegoldenrod':'#eee8aa',
+        'palegreen':'#98fb98',
+        'paleturquoise':'#afeeee',
+        'palevioletred':'#d87093',
+        'papayawhip':'#ffefd5',
+        'peachpuff':'#ffdab9',
+        'peru':'#cd853f',
+        'pink':'#ffc0cb',
+        'plum':'#dda0dd',
+        'powderblue':'#b0e0e6',
+        'purple':'#800080',
+        'red':'#ff0000',
+        'rosybrown':'#bc8f8f',
+        'royalblue':'#4169e1',
+        'saddlebrown':'#8b4513',
+        'salmon':'#fa8072',
+        'sandybrown':'#f4a460',
+        'seagreen':'#2e8b57',
+        'seashell':'#fff5ee',
+        'sienna':'#a0522d',
+        'silver':'#c0c0c0',
+        'skyblue':'#87ceeb',
+        'slateblue':'#6a5acd',
+        'slategray':'#708090',
+        'slategrey':'#708090',
+        'snow':'#fffafa',
+        'springgreen':'#00ff7f',
+        'steelblue':'#4682b4',
+        'tan':'#d2b48c',
+        'teal':'#008080',
+        'thistle':'#d8bfd8',
+        'tomato':'#ff6347',
+        // 'transparent':'rgba(0,0,0,0)',
+        'turquoise':'#40e0d0',
+        'violet':'#ee82ee',
+        'wheat':'#f5deb3',
+        'white':'#ffffff',
+        'whitesmoke':'#f5f5f5',
+        'yellow':'#ffff00',
+        'yellowgreen':'#9acd32'
+    };
+})(require('./tree'));
diff --git a/util/less/lib/less/functions.js b/util/less/lib/less/functions.js
new file mode 100644
index 0000000..b077123
--- /dev/null
+++ b/util/less/lib/less/functions.js
@@ -0,0 +1,377 @@
+(function (tree) {
+
+tree.functions = {
+    rgb: function (r, g, b) {
+        return this.rgba(r, g, b, 1.0);
+    },
+    rgba: function (r, g, b, a) {
+        var rgb = [r, g, b].map(function (c) { return scaled(c, 256); });
+        a = number(a);
+        return new(tree.Color)(rgb, a);
+    },
+    hsl: function (h, s, l) {
+        return this.hsla(h, s, l, 1.0);
+    },
+    hsla: function (h, s, l, a) {
+        h = (number(h) % 360) / 360;
+        s = number(s); l = number(l); a = number(a);
+
+        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
+        var m1 = l * 2 - m2;
+
+        return this.rgba(hue(h + 1/3) * 255,
+                         hue(h)       * 255,
+                         hue(h - 1/3) * 255,
+                         a);
+
+        function hue(h) {
+            h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
+            if      (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+            else if (h * 2 < 1) return m2;
+            else if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+            else                return m1;
+        }
+    },
+
+    hsv: function(h, s, v) {
+        return this.hsva(h, s, v, 1.0);
+    },
+
+    hsva: function(h, s, v, a) {
+        h = ((number(h) % 360) / 360) * 360;
+        s = number(s); v = number(v); a = number(a);
+
+        var i, f;
+        i = Math.floor((h / 60) % 6);
+        f = (h / 60) - i;
+
+        var vs = [v,
+                  v * (1 - s),
+                  v * (1 - f * s),
+                  v * (1 - (1 - f) * s)];
+        var perm = [[0, 3, 1],
+                    [2, 0, 1],
+                    [1, 0, 3],
+                    [1, 2, 0],
+                    [3, 1, 0],
+                    [0, 1, 2]];
+
+        return this.rgba(vs[perm[i][0]] * 255,
+                         vs[perm[i][1]] * 255,
+                         vs[perm[i][2]] * 255,
+                         a);
+    },
+
+    hue: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().h));
+    },
+    saturation: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().s * 100), '%');
+    },
+    lightness: function (color) {
+        return new(tree.Dimension)(Math.round(color.toHSL().l * 100), '%');
+    },
+    red: function (color) {
+        return new(tree.Dimension)(color.rgb[0]);
+    },
+    green: function (color) {
+        return new(tree.Dimension)(color.rgb[1]);
+    },
+    blue: function (color) {
+        return new(tree.Dimension)(color.rgb[2]);
+    },
+    alpha: function (color) {
+        return new(tree.Dimension)(color.toHSL().a);
+    },
+    luma: function (color) {
+        return new(tree.Dimension)(Math.round((0.2126 * (color.rgb[0]/255) +
+            0.7152 * (color.rgb[1]/255) +
+            0.0722 * (color.rgb[2]/255)) *
+            color.alpha * 100), '%');
+    },
+    saturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s += amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    desaturate: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.s -= amount.value / 100;
+        hsl.s = clamp(hsl.s);
+        return hsla(hsl);
+    },
+    lighten: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l += amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    darken: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.l -= amount.value / 100;
+        hsl.l = clamp(hsl.l);
+        return hsla(hsl);
+    },
+    fadein: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a += amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fadeout: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a -= amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    fade: function (color, amount) {
+        var hsl = color.toHSL();
+
+        hsl.a = amount.value / 100;
+        hsl.a = clamp(hsl.a);
+        return hsla(hsl);
+    },
+    spin: function (color, amount) {
+        var hsl = color.toHSL();
+        var hue = (hsl.h + amount.value) % 360;
+
+        hsl.h = hue < 0 ? 360 + hue : hue;
+
+        return hsla(hsl);
+    },
+    //
+    // Copyright (c) 2006-2009 Hampton Catlin, Nathan Weizenbaum, and Chris Eppstein
+    // http://sass-lang.com
+    //
+    mix: function (color1, color2, weight) {
+        if (!weight) {
+            weight = new(tree.Dimension)(50);
+        }
+        var p = weight.value / 100.0;
+        var w = p * 2 - 1;
+        var a = color1.toHSL().a - color2.toHSL().a;
+
+        var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
+        var w2 = 1 - w1;
+
+        var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
+                   color1.rgb[1] * w1 + color2.rgb[1] * w2,
+                   color1.rgb[2] * w1 + color2.rgb[2] * w2];
+
+        var alpha = color1.alpha * p + color2.alpha * (1 - p);
+
+        return new(tree.Color)(rgb, alpha);
+    },
+    greyscale: function (color) {
+        return this.desaturate(color, new(tree.Dimension)(100));
+    },
+    contrast: function (color, dark, light, threshold) {
+        // filter: contrast(3.2);
+        // should be kept as is, so check for color
+        if (!color.rgb) {
+            return null;
+        }
+        if (typeof light === 'undefined') {
+            light = this.rgba(255, 255, 255, 1.0);
+        }
+        if (typeof dark === 'undefined') {
+            dark = this.rgba(0, 0, 0, 1.0);
+        }
+        if (typeof threshold === 'undefined') {
+            threshold = 0.43;
+        } else {
+            threshold = threshold.value;
+        }
+        if (((0.2126 * (color.rgb[0]/255) + 0.7152 * (color.rgb[1]/255) + 0.0722 * (color.rgb[2]/255)) * color.alpha) < threshold) {
+            return light;
+        } else {
+            return dark;
+        }
+    },
+    e: function (str) {
+        return new(tree.Anonymous)(str instanceof tree.JavaScript ? str.evaluated : str);
+    },
+    escape: function (str) {
+        return new(tree.Anonymous)(encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B").replace(/\(/g, "%28").replace(/\)/g, "%29"));
+    },
+    '%': function (quoted /* arg, arg, ...*/) {
+        var args = Array.prototype.slice.call(arguments, 1),
+            str = quoted.value;
+
+        for (var i = 0; i < args.length; i++) {
+            str = str.replace(/%[sda]/i, function(token) {
+                var value = token.match(/s/i) ? args[i].value : args[i].toCSS();
+                return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
+            });
+        }
+        str = str.replace(/%%/g, '%');
+        return new(tree.Quoted)('"' + str + '"', str);
+    },
+    unit: function (val, unit) {
+        return new(tree.Dimension)(val.value, unit ? unit.toCSS() : "");
+    },
+    round: function (n, f) {
+        var fraction = typeof(f) === "undefined" ? 0 : f.value;
+        return this._math(function(num) { return num.toFixed(fraction); }, n);
+    },
+    ceil: function (n) {
+        return this._math(Math.ceil, n);
+    },
+    floor: function (n) {
+        return this._math(Math.floor, n);
+    },
+    _math: function (fn, n) {
+        if (n instanceof tree.Dimension) {
+            return new(tree.Dimension)(fn(parseFloat(n.value)), n.unit);
+        } else if (typeof(n) === 'number') {
+            return fn(n);
+        } else {
+            throw { type: "Argument", message: "argument must be a number" };
+        }
+    },
+    argb: function (color) {
+        return new(tree.Anonymous)(color.toARGB());
+
+    },
+    percentage: function (n) {
+        return new(tree.Dimension)(n.value * 100, '%');
+    },
+    color: function (n) {
+        if (n instanceof tree.Quoted) {
+            return new(tree.Color)(n.value.slice(1));
+        } else {
+            throw { type: "Argument", message: "argument must be a string" };
+        }
+    },
+    iscolor: function (n) {
+        return this._isa(n, tree.Color);
+    },
+    isnumber: function (n) {
+        return this._isa(n, tree.Dimension);
+    },
+    isstring: function (n) {
+        return this._isa(n, tree.Quoted);
+    },
+    iskeyword: function (n) {
+        return this._isa(n, tree.Keyword);
+    },
+    isurl: function (n) {
+        return this._isa(n, tree.URL);
+    },
+    ispixel: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'px' ? tree.True : tree.False;
+    },
+    ispercentage: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === '%' ? tree.True : tree.False;
+    },
+    isem: function (n) {
+        return (n instanceof tree.Dimension) && n.unit === 'em' ? tree.True : tree.False;
+    },
+    _isa: function (n, Type) {
+        return (n instanceof Type) ? tree.True : tree.False;
+    },
+    
+    /* Blending modes */
+    
+    multiply: function(color1, color2) {
+        var r = color1.rgb[0] * color2.rgb[0] / 255;
+        var g = color1.rgb[1] * color2.rgb[1] / 255;
+        var b = color1.rgb[2] * color2.rgb[2] / 255;
+        return this.rgb(r, g, b);
+    },
+    screen: function(color1, color2) {
+        var r = 255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = 255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = 255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    overlay: function(color1, color2) {
+        var r = color1.rgb[0] < 128 ? 2 * color1.rgb[0] * color2.rgb[0] / 255 : 255 - 2 * (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255;
+        var g = color1.rgb[1] < 128 ? 2 * color1.rgb[1] * color2.rgb[1] / 255 : 255 - 2 * (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255;
+        var b = color1.rgb[2] < 128 ? 2 * color1.rgb[2] * color2.rgb[2] / 255 : 255 - 2 * (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    softlight: function(color1, color2) {
+        var t = color2.rgb[0] * color1.rgb[0] / 255;
+        var r = t + color1.rgb[0] * (255 - (255 - color1.rgb[0]) * (255 - color2.rgb[0]) / 255 - t) / 255;
+        t = color2.rgb[1] * color1.rgb[1] / 255;
+        var g = t + color1.rgb[1] * (255 - (255 - color1.rgb[1]) * (255 - color2.rgb[1]) / 255 - t) / 255;
+        t = color2.rgb[2] * color1.rgb[2] / 255;
+        var b = t + color1.rgb[2] * (255 - (255 - color1.rgb[2]) * (255 - color2.rgb[2]) / 255 - t) / 255;
+        return this.rgb(r, g, b);
+    },
+    hardlight: function(color1, color2) {
+        var r = color2.rgb[0] < 128 ? 2 * color2.rgb[0] * color1.rgb[0] / 255 : 255 - 2 * (255 - color2.rgb[0]) * (255 - color1.rgb[0]) / 255;
+        var g = color2.rgb[1] < 128 ? 2 * color2.rgb[1] * color1.rgb[1] / 255 : 255 - 2 * (255 - color2.rgb[1]) * (255 - color1.rgb[1]) / 255;
+        var b = color2.rgb[2] < 128 ? 2 * color2.rgb[2] * color1.rgb[2] / 255 : 255 - 2 * (255 - color2.rgb[2]) * (255 - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    difference: function(color1, color2) {
+        var r = Math.abs(color1.rgb[0] - color2.rgb[0]);
+        var g = Math.abs(color1.rgb[1] - color2.rgb[1]);
+        var b = Math.abs(color1.rgb[2] - color2.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    exclusion: function(color1, color2) {
+        var r = color1.rgb[0] + color2.rgb[0] * (255 - color1.rgb[0] - color1.rgb[0]) / 255;
+        var g = color1.rgb[1] + color2.rgb[1] * (255 - color1.rgb[1] - color1.rgb[1]) / 255;
+        var b = color1.rgb[2] + color2.rgb[2] * (255 - color1.rgb[2] - color1.rgb[2]) / 255;
+        return this.rgb(r, g, b);
+    },
+    average: function(color1, color2) {
+        var r = (color1.rgb[0] + color2.rgb[0]) / 2;
+        var g = (color1.rgb[1] + color2.rgb[1]) / 2;
+        var b = (color1.rgb[2] + color2.rgb[2]) / 2;
+        return this.rgb(r, g, b);
+    },
+    negation: function(color1, color2) {
+        var r = 255 - Math.abs(255 - color2.rgb[0] - color1.rgb[0]);
+        var g = 255 - Math.abs(255 - color2.rgb[1] - color1.rgb[1]);
+        var b = 255 - Math.abs(255 - color2.rgb[2] - color1.rgb[2]);
+        return this.rgb(r, g, b);
+    },
+    tint: function(color, amount) {
+        return this.mix(this.rgb(255,255,255), color, amount);
+    },
+    shade: function(color, amount) {
+        return this.mix(this.rgb(0, 0, 0), color, amount);
+    }
+};
+
+function hsla(color) {
+    return tree.functions.hsla(color.h, color.s, color.l, color.a);
+}
+
+function scaled(n, size) {
+    if (n instanceof tree.Dimension && n.unit == '%') {
+        return parseFloat(n.value * size / 100);
+    } else {
+        return number(n);
+    }
+}
+
+function number(n) {
+    if (n instanceof tree.Dimension) {
+        return parseFloat(n.unit == '%' ? n.value / 100 : n.value);
+    } else if (typeof(n) === 'number') {
+        return n;
+    } else {
+        throw {
+            error: "RuntimeError",
+            message: "color functions take numbers as parameters"
+        };
+    }
+}
+
+function clamp(val) {
+    return Math.min(1, Math.max(0, val));
+}
+
+})(require('./tree'));
diff --git a/util/less/lib/less/index.js b/util/less/lib/less/index.js
new file mode 100644
index 0000000..37fc902
--- /dev/null
+++ b/util/less/lib/less/index.js
@@ -0,0 +1,216 @@
+var path = require('path'),
+    sys = require('util'),
+    url = require('url'),
+    http = require('http'),
+    fs = require('fs');
+
+var less = {
+    version: [1, 3, 3],
+    Parser: require('./parser').Parser,
+    importer: require('./parser').importer,
+    tree: require('./tree'),
+    render: function (input, options, callback) {
+        options = options || {};
+
+        if (typeof(options) === 'function') {
+            callback = options, options = {};
+        }
+
+        var parser = new(less.Parser)(options),
+            ee;
+
+        if (callback) {
+            parser.parse(input, function (e, root) {
+                callback(e, root && root.toCSS && root.toCSS(options));
+            });
+        } else {
+            ee = new(require('events').EventEmitter);
+
+            process.nextTick(function () {
+                parser.parse(input, function (e, root) {
+                    if (e) { ee.emit('error', e) }
+                    else   { ee.emit('success', root.toCSS(options)) }
+                });
+            });
+            return ee;
+        }
+    },
+    formatError: function(ctx, options) {
+        options = options || {};
+
+        var message = "";
+        var extract = ctx.extract;
+        var error = [];
+        var stylize = options.color ? require('./lessc_helper').stylize : function (str) { return str };
+
+        // only output a stack if it isn't a less error
+        if (ctx.stack && !ctx.type) { return stylize(ctx.stack, 'red') }
+
+        if (!ctx.hasOwnProperty('index') || !extract) {
+            return ctx.stack || ctx.message;
+        }
+
+        if (typeof(extract[0]) === 'string') {
+            error.push(stylize((ctx.line - 1) + ' ' + extract[0], 'grey'));
+        }
+
+        if (extract[1]) {
+            error.push(ctx.line + ' ' + extract[1].slice(0, ctx.column)
+                                + stylize(stylize(stylize(extract[1][ctx.column], 'bold')
+                                + extract[1].slice(ctx.column + 1), 'red'), 'inverse'));
+        }
+
+        if (typeof(extract[2]) === 'string') {
+            error.push(stylize((ctx.line + 1) + ' ' + extract[2], 'grey'));
+        }
+        error = error.join('\n') + stylize('', 'reset') + '\n';
+
+        message += stylize(ctx.type + 'Error: ' + ctx.message, 'red');
+        ctx.filename && (message += stylize(' in ', 'red') + ctx.filename +
+                stylize(':' + ctx.line + ':' + ctx.column, 'grey'));
+
+        message += '\n' + error;
+
+        if (ctx.callLine) {
+            message += stylize('from ', 'red') + (ctx.filename || '') + '/n';
+            message += stylize(ctx.callLine, 'grey') + ' ' + ctx.callExtract + '/n';
+        }
+
+        return message;
+    },
+    writeError: function (ctx, options) {
+        options = options || {};
+        if (options.silent) { return }
+        sys.error(less.formatError(ctx, options));
+    }
+};
+
+['color',      'directive',  'operation',  'dimension',
+ 'keyword',    'variable',   'ruleset',    'element',
+ 'selector',   'quoted',     'expression', 'rule',
+ 'call',       'url',        'alpha',      'import',
+ 'mixin',      'comment',    'anonymous',  'value',
+ 'javascript', 'assignment', 'condition',  'paren',
+ 'media',      'ratio',      'unicode-descriptor'
+].forEach(function (n) {
+    require('./tree/' + n);
+});
+
+
+var isUrlRe = /^(?:https?:)?\/\//i;
+
+less.Parser.importer = function (file, paths, callback, env) {
+    var pathname, dirname, data;
+
+    function parseFile(e, data) {
+        if (e) return callback(e);
+        
+        var rootpath = env.rootpath,
+            j = file.lastIndexOf('/');
+
+        // Pass on an updated rootpath if path of imported file is relative and file 
+        // is in a (sub|sup) directory
+        // 
+        // Examples: 
+        // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',
+        //   then rootpath should become 'less/module/nav/'
+        // - If path of imported file is '../mixins.less' and rootpath is 'less/', 
+        //   then rootpath should become 'less/../'
+        if(env.relativeUrls && !/^(?:[a-z-]+:|\/)/.test(file) && j != -1) {
+            rootpath = rootpath + file.slice(0, j+1); // append (sub|sup) directory path of imported file
+        }
+
+        env.contents[pathname] = data;      // Updating top importing parser content cache.
+        new(less.Parser)({
+                paths: [dirname].concat(paths),
+                filename: pathname,
+                contents: env.contents,
+                files: env.files,
+                syncImport: env.syncImport,
+                relativeUrls: env.relativeUrls,
+                rootpath: rootpath,
+                dumpLineNumbers: env.dumpLineNumbers
+        }).parse(data, function (e, root) {
+            callback(e, root, pathname);
+        });
+    };
+    
+    var isUrl = isUrlRe.test( file );
+    if (isUrl || isUrlRe.test(paths[0])) {
+
+        var urlStr = isUrl ? file : url.resolve(paths[0], file),
+            urlObj = url.parse(urlStr),
+            req = {
+                host:   urlObj.hostname,
+                port:   urlObj.port || 80,
+                path:   urlObj.pathname + (urlObj.search||'')
+            };
+
+        http.get(req, function (res) {
+            var body = '';
+            res.on('data', function (chunk) {
+                body += chunk.toString();
+            });
+            res.on('end', function () {
+                if (res.statusCode === 404) {
+                    callback({ type: 'File', message: "resource '" + urlStr + "' was not found\n" });
+                }
+                if (!body) {
+                    sys.error( 'Warning: Empty body (HTTP '+ res.statusCode + ') returned by "' + urlStr +'"' );
+                }
+                pathname = urlStr;
+                dirname = urlObj.protocol +'//'+ urlObj.host + urlObj.pathname.replace(/[^\/]*$/, '');
+                parseFile(null, body);
+            });
+        }).on('error', function (err) {
+            callback({ type: 'File', message: "resource '" + urlStr + "' gave this Error:\n  "+ err +"\n" });
+        });
+
+    } else {
+
+        // TODO: Undo this at some point,
+        // or use different approach.
+        var paths = [].concat(paths);
+        paths.push('.');
+
+        for (var i = 0; i < paths.length; i++) {
+            try {
+                pathname = path.join(paths[i], file);
+                fs.statSync(pathname);
+                break;
+            } catch (e) {
+                pathname = null;
+            }
+        }
+        
+        paths = paths.slice(0, paths.length - 1);
+
+        if (!pathname) {
+
+            if (typeof(env.errback) === "function") {
+                env.errback(file, paths, callback);
+            } else {
+                callback({ type: 'File', message: "'" + file + "' wasn't found.\n" });
+            }
+            return;
+        }
+        
+        dirname = path.dirname(pathname);
+
+        if (env.syncImport) {
+            try {
+                data = fs.readFileSync(pathname, 'utf-8');
+                parseFile(null, data);
+            } catch (e) {
+                parseFile(e);
+            }
+        } else {
+            fs.readFile(pathname, 'utf-8', parseFile);
+        }
+    }
+}
+
+require('./functions');
+require('./colors');
+
+for (var k in less) { exports[k] = less[k] }
diff --git a/util/less/lib/less/lessc_helper.js b/util/less/lib/less/lessc_helper.js
new file mode 100644
index 0000000..1a82ef9
--- /dev/null
+++ b/util/less/lib/less/lessc_helper.js
@@ -0,0 +1,62 @@
+// lessc_helper.js
+//
+//      helper functions for lessc
+sys = require('util');
+
+var lessc_helper = {
+
+    //Stylize a string
+    stylize : function(str, style) {
+        var styles = {
+            'reset'     : [0,   0],
+            'bold'      : [1,  22],
+            'inverse'   : [7,  27],
+            'underline' : [4,  24],
+            'yellow'    : [33, 39],
+            'green'     : [32, 39],
+            'red'       : [31, 39],
+            'grey'      : [90, 39]
+        };
+        return '\033[' + styles[style][0] + 'm' + str +
+               '\033[' + styles[style][1] + 'm';
+    },
+
+    //Print command line options
+    printUsage: function() {
+        sys.puts("usage: lessc [option option=parameter ...] <source> [destination]");
+        sys.puts("");
+        sys.puts("If source is set to `-' (dash or hyphen-minus), input is read from stdin.");
+        sys.puts("");
+        sys.puts("options:");
+        sys.puts("  -h, --help              Print help (this message) and exit.");
+        sys.puts("  --include-path          Set include paths. Separated by `:'. Use `;' on Windows.");
+        sys.puts("  --no-color              Disable colorized output.");
+        sys.puts("  -s, --silent            Suppress output of error messages.");
+        sys.puts("  --strict-imports        Force evaluation of imports.");
+        sys.puts("  --verbose               Be verbose.");
+        sys.puts("  -v, --version           Print version number and exit.");
+        sys.puts("  -x, --compress          Compress output by removing some whitespaces.");
+        sys.puts("  --yui-compress          Compress output using ycssmin");
+        sys.puts("  -O0, -O1, -O2           Set the parser's optimization level. The lower");
+        sys.puts("                          the number, the less nodes it will create in the");
+        sys.puts("                          tree. This could matter for debugging, or if you");
+        sys.puts("                          want to access the individual nodes in the tree.");
+        sys.puts("  --line-numbers=TYPE     Outputs filename and line numbers.");
+        sys.puts("                          TYPE can be either 'comments', which will output");
+        sys.puts("                          the debug info within comments, 'mediaquery'");
+        sys.puts("                          that will output the information within a fake");
+        sys.puts("                          media query which is compatible with the SASS");
+        sys.puts("                          format, and 'all' which will do both.");
+        sys.puts("  -rp, --rootpath         Set rootpath for url rewriting in relative imports and urls.");
+        sys.puts("                          Works with or withour the relative-urls option.");
+        sys.puts("  -ru, --relative-urls    re-write relative urls to the base less file.");
+        sys.puts("");
+        sys.puts("Report bugs to: http://github.com/cloudhead/less.js/issues");
+        sys.puts("Home page: <http://lesscss.org/>");
+    }
+
+
+}
+
+// Exports helper functions
+for (var h in lessc_helper) { exports[h] = lessc_helper[h] }
diff --git a/util/less/lib/less/parser.js b/util/less/lib/less/parser.js
new file mode 100644
index 0000000..c8c280b
--- /dev/null
+++ b/util/less/lib/less/parser.js
@@ -0,0 +1,1522 @@
+var less, tree, charset;
+
+if (typeof environment === "object" && ({}).toString.call(environment) === "[object Environment]") {
+    // Rhino
+    // Details on how to detect Rhino: https://github.com/ringo/ringojs/issues/88
+    if (typeof(window) === 'undefined') { less = {} }
+    else                                { less = window.less = {} }
+    tree = less.tree = {};
+    less.mode = 'rhino';
+} else if (typeof(window) === 'undefined') {
+    // Node.js
+    less = exports,
+    tree = require('./tree');
+    less.mode = 'node';
+} else {
+    // Browser
+    if (typeof(window.less) === 'undefined') { window.less = {} }
+    less = window.less,
+    tree = window.less.tree = {};
+    less.mode = 'browser';
+}
+//
+// less.js - parser
+//
+//    A relatively straight-forward predictive parser.
+//    There is no tokenization/lexing stage, the input is parsed
+//    in one sweep.
+//
+//    To make the parser fast enough to run in the browser, several
+//    optimization had to be made:
+//
+//    - Matching and slicing on a huge input is often cause of slowdowns.
+//      The solution is to chunkify the input into smaller strings.
+//      The chunks are stored in the `chunks` var,
+//      `j` holds the current chunk index, and `current` holds
+//      the index of the current chunk in relation to `input`.
+//      This gives us an almost 4x speed-up.
+//
+//    - In many cases, we don't need to match individual tokens;
+//      for example, if a value doesn't hold any variables, operations
+//      or dynamic references, the parser can effectively 'skip' it,
+//      treating it as a literal.
+//      An example would be '1px solid #000' - which evaluates to itself,
+//      we don't need to know what the individual components are.
+//      The drawback, of course is that you don't get the benefits of
+//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
+//      and a smaller speed-up in the code-gen.
+//
+//
+//    Token matching is done with the `$` function, which either takes
+//    a terminal string or regexp, or a non-terminal function to call.
+//    It also takes care of moving all the indices forwards.
+//
+//
+less.Parser = function Parser(env) {
+    var input,       // LeSS input string
+        i,           // current index in `input`
+        j,           // current chunk
+        temp,        // temporarily holds a chunk's state, for backtracking
+        memo,        // temporarily holds `i`, when backtracking
+        furthest,    // furthest index the parser has gone to
+        chunks,      // chunkified input
+        current,     // index of current chunk, in `input`
+        parser;
+
+    var that = this;
+
+    // Top parser on an import tree must be sure there is one "env"
+    // which will then be passed arround by reference.
+    var env = env || { };
+    // env.contents and files must be passed arround with top env
+    if (!env.contents) { env.contents = {}; }
+    env.rootpath = env.rootpath || '';       // env.rootpath must be initialized to '' if not provided
+    if (!env.files) { env.files = {}; }
+
+    // This function is called after all files
+    // have been imported through `@import`.
+    var finish = function () {};
+
+    var imports = this.imports = {
+        paths: env.paths || [],  // Search paths, when importing
+        queue: [],               // Files which haven't been imported yet
+        files: env.files,        // Holds the imported parse trees
+        contents: env.contents,  // Holds the imported file contents
+        mime:  env.mime,         // MIME type of .less files
+        error: null,             // Error in parsing/evaluating an import
+        push: function (path, callback) {
+            var that = this;
+            this.queue.push(path);
+
+            //
+            // Import a file asynchronously
+            //
+            less.Parser.importer(path, this.paths, function (e, root, fullPath) {
+                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
+
+                var imported = fullPath in that.files;
+
+                that.files[fullPath] = root;                        // Store the root
+
+                if (e && !that.error) { that.error = e }
+
+                callback(e, root, imported);
+
+                if (that.queue.length === 0) { finish(that.error) }       // Call `finish` if we're done importing
+            }, env);
+        }
+    };
+
+    function save()    { temp = chunks[j], memo = i, current = i }
+    function restore() { chunks[j] = temp, i = memo, current = i }
+
+    function sync() {
+        if (i > current) {
+            chunks[j] = chunks[j].slice(i - current);
+            current = i;
+        }
+    }
+    function isWhitespace(c) {
+        // Could change to \s?
+        var code = c.charCodeAt(0);
+        return code === 32 || code === 10 || code === 9;
+    }
+    //
+    // Parse from a token, regexp or string, and move forward if match
+    //
+    function $(tok) {
+        var match, args, length, index, k;
+
+        //
+        // Non-terminal
+        //
+        if (tok instanceof Function) {
+            return tok.call(parser.parsers);
+        //
+        // Terminal
+        //
+        //     Either match a single character in the input,
+        //     or match a regexp in the current chunk (chunk[j]).
+        //
+        } else if (typeof(tok) === 'string') {
+            match = input.charAt(i) === tok ? tok : null;
+            length = 1;
+            sync ();
+        } else {
+            sync ();
+
+            if (match = tok.exec(chunks[j])) {
+                length = match[0].length;
+            } else {
+                return null;
+            }
+        }
+
+        // The match is confirmed, add the match length to `i`,
+        // and consume any extra white-space characters (' ' || '\n')
+        // which come after that. The reason for this is that LeSS's
+        // grammar is mostly white-space insensitive.
+        //
+        if (match) {
+            skipWhitespace(length);
+
+            if(typeof(match) === 'string') {
+                return match;
+            } else {
+                return match.length === 1 ? match[0] : match;
+            }
+        }
+    }
+
+    function skipWhitespace(length) {
+        var oldi = i, oldj = j,
+            endIndex = i + chunks[j].length,
+            mem = i += length;
+
+        while (i < endIndex) {
+            if (! isWhitespace(input.charAt(i))) { break }
+            i++;
+        }
+        chunks[j] = chunks[j].slice(length + (i - mem));
+        current = i;
+
+        if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
+
+        return oldi !== i || oldj !== j;
+    }
+
+    function expect(arg, msg) {
+        var result = $(arg);
+        if (! result) {
+            error(msg || (typeof(arg) === 'string' ? "expected '" + arg + "' got '" + input.charAt(i) + "'"
+                                                   : "unexpected token"));
+        } else {
+            return result;
+        }
+    }
+
+    function error(msg, type) {
+        var e = new Error(msg);
+        e.index = i;
+        e.type = type || 'Syntax';
+        throw e;
+    }
+
+    // Same as $(), but don't change the state of the parser,
+    // just return the match.
+    function peek(tok) {
+        if (typeof(tok) === 'string') {
+            return input.charAt(i) === tok;
+        } else {
+            if (tok.test(chunks[j])) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    function getInput(e, env) {
+        if (e.filename && env.filename && (e.filename !== env.filename)) {
+            return parser.imports.contents[e.filename];
+        } else {
+            return input;
+        }
+    }
+
+    function getLocation(index, input) {
+        for (var n = index, column = -1;
+                 n >= 0 && input.charAt(n) !== '\n';
+                 n--) { column++ }
+
+        return { line:   typeof(index) === 'number' ? (input.slice(0, index).match(/\n/g) || "").length : null,
+                 column: column };
+    }
+
+    function getFileName(e) {
+        if(less.mode === 'browser' || less.mode === 'rhino')
+            return e.filename;
+        else
+            return require('path').resolve(e.filename);
+    }
+
+    function getDebugInfo(index, inputStream, e) {
+        return {
+            lineNumber: getLocation(index, inputStream).line + 1,
+            fileName: getFileName(e)
+        };
+    }
+
+    function LessError(e, env) {
+        var input = getInput(e, env),
+            loc = getLocation(e.index, input),
+            line = loc.line,
+            col  = loc.column,
+            lines = input.split('\n');
+
+        this.type = e.type || 'Syntax';
+        this.message = e.message;
+        this.filename = e.filename || env.filename;
+        this.index = e.index;
+        this.line = typeof(line) === 'number' ? line + 1 : null;
+        this.callLine = e.call && (getLocation(e.call, input).line + 1);
+        this.callExtract = lines[getLocation(e.call, input).line];
+        this.stack = e.stack;
+        this.column = col;
+        this.extract = [
+            lines[line - 1],
+            lines[line],
+            lines[line + 1]
+        ];
+    }
+
+    this.env = env = env || {};
+
+    // The optimization level dictates the thoroughness of the parser,
+    // the lower the number, the less nodes it will create in the tree.
+    // This could matter for debugging, or if you want to access
+    // the individual nodes in the tree.
+    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
+
+    this.env.filename = this.env.filename || null;
+
+    //
+    // The Parser
+    //
+    return parser = {
+
+        imports: imports,
+        //
+        // Parse an input string into an abstract syntax tree,
+        // call `callback` when done.
+        //
+        parse: function (str, callback) {
+            var root, start, end, zone, line, lines, buff = [], c, error = null;
+
+            i = j = current = furthest = 0;
+            input = str.replace(/\r\n/g, '\n');
+
+            // Remove potential UTF Byte Order Mark
+            input = input.replace(/^\uFEFF/, '');
+
+            // Split the input into chunks.
+            chunks = (function (chunks) {
+                var j = 0,
+                    skip = /(?:@\{[\w-]+\}|[^"'`\{\}\/\(\)\\])+/g,
+                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
+                    string = /"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'|`((?:[^`]|\\.)*)`/g,
+                    level = 0,
+                    match,
+                    chunk = chunks[0],
+                    inParam;
+
+                for (var i = 0, c, cc; i < input.length;) {
+                    skip.lastIndex = i;
+                    if (match = skip.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                        }
+                    }
+                    c = input.charAt(i);
+                    comment.lastIndex = string.lastIndex = i;
+
+                    if (match = string.exec(input)) {
+                        if (match.index === i) {
+                            i += match[0].length;
+                            chunk.push(match[0]);
+                            continue;
+                        }
+                    }
+
+                    if (!inParam && c === '/') {
+                        cc = input.charAt(i + 1);
+                        if (cc === '/' || cc === '*') {
+                            if (match = comment.exec(input)) {
+                                if (match.index === i) {
+                                    i += match[0].length;
+                                    chunk.push(match[0]);
+                                    continue;
+                                }
+                            }
+                        }
+                    }
+                    
+                    switch (c) {
+                        case '{': if (! inParam) { level ++;        chunk.push(c);                           break }
+                        case '}': if (! inParam) { level --;        chunk.push(c); chunks[++j] = chunk = []; break }
+                        case '(': if (! inParam) { inParam = true;  chunk.push(c);                           break }
+                        case ')': if (  inParam) { inParam = false; chunk.push(c);                           break }
+                        default:                                    chunk.push(c);
+                    }
+                    
+                    i++;
+                }
+                if (level != 0) {
+                    error = new(LessError)({
+                        index: i-1,
+                        type: 'Parse',
+                        message: (level > 0) ? "missing closing `}`" : "missing opening `{`",
+                        filename: env.filename
+                    }, env);
+                }
+
+                return chunks.map(function (c) { return c.join('') });;
+            })([[]]);
+
+            if (error) {
+                return callback(error, env);
+            }
+
+            // Start with the primary rule.
+            // The whole syntax tree is held under a Ruleset node,
+            // with the `root` property set to true, so no `{}` are
+            // output. The callback is called when the input is parsed.
+            try {
+                root = new(tree.Ruleset)([], $(this.parsers.primary));
+                root.root = true;
+            } catch (e) {
+                return callback(new(LessError)(e, env));
+            }
+
+            root.toCSS = (function (evaluate) {
+                var line, lines, column;
+
+                return function (options, variables) {
+                    var frames = [], importError;
+
+                    options = options || {};
+                    //
+                    // Allows setting variables with a hash, so:
+                    //
+                    //   `{ color: new(tree.Color)('#f01') }` will become:
+                    //
+                    //   new(tree.Rule)('@color',
+                    //     new(tree.Value)([
+                    //       new(tree.Expression)([
+                    //         new(tree.Color)('#f01')
+                    //       ])
+                    //     ])
+                    //   )
+                    //
+                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
+                        variables = Object.keys(variables).map(function (k) {
+                            var value = variables[k];
+
+                            if (! (value instanceof tree.Value)) {
+                                if (! (value instanceof tree.Expression)) {
+                                    value = new(tree.Expression)([value]);
+                                }
+                                value = new(tree.Value)([value]);
+                            }
+                            return new(tree.Rule)('@' + k, value, false, 0);
+                        });
+                        frames = [new(tree.Ruleset)(null, variables)];
+                    }
+
+                    try {
+                        var css = evaluate.call(this, { frames: frames })
+                                          .toCSS([], { compress: options.compress || false, dumpLineNumbers: env.dumpLineNumbers });
+                    } catch (e) {
+                        throw new(LessError)(e, env);
+                    }
+
+                    if ((importError = parser.imports.error)) { // Check if there was an error during importing
+                        if (importError instanceof LessError) throw importError;
+                        else                                  throw new(LessError)(importError, env);
+                    }
+
+                    if (options.yuicompress && less.mode === 'node') {
+                        return require('ycssmin').cssmin(css);
+                    } else if (options.compress) {
+                        return css.replace(/(\s)+/g, "$1");
+                    } else {
+                        return css;
+                    }
+                };
+            })(root.eval);
+
+            // If `i` is smaller than the `input.length - 1`,
+            // it means the parser wasn't able to parse the whole
+            // string, so we've got a parsing error.
+            //
+            // We try to extract a \n delimited string,
+            // showing the line where the parse error occured.
+            // We split it up into two parts (the part which parsed,
+            // and the part which didn't), so we can color them differently.
+            if (i < input.length - 1) {
+                i = furthest;
+                lines = input.split('\n');
+                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
+
+                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
+
+                error = {
+                    type: "Parse",
+                    message: "Syntax Error on line " + line,
+                    index: i,
+                    filename: env.filename,
+                    line: line,
+                    column: column,
+                    extract: [
+                        lines[line - 2],
+                        lines[line - 1],
+                        lines[line]
+                    ]
+                };
+            }
+
+            if (this.imports.queue.length > 0) {
+                finish = function (e) {
+                    e = error || e;
+                    if (e) callback(e);
+                    else callback(null, root);
+                };
+            } else {
+                callback(error, root);
+            }
+        },
+
+        //
+        // Here in, the parsing rules/functions
+        //
+        // The basic structure of the syntax tree generated is as follows:
+        //
+        //   Ruleset ->  Rule -> Value -> Expression -> Entity
+        //
+        // Here's some LESS code:
+        //
+        //    .class {
+        //      color: #fff;
+        //      border: 1px solid #000;
+        //      width: @w + 4px;
+        //      > .child {...}
+        //    }
+        //
+        // And here's what the parse tree might look like:
+        //
+        //     Ruleset (Selector '.class', [
+        //         Rule ("color",  Value ([Expression [Color #fff]]))
+        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
+        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
+        //         Ruleset (Selector [Element '>', '.child'], [...])
+        //     ])
+        //
+        //  In general, most rules will try to parse a token with the `$()` function, and if the return
+        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
+        //  first, before parsing, that's when we use `peek()`.
+        //
+        parsers: {
+            //
+            // The `primary` rule is the *entry* and *exit* point of the parser.
+            // The rules here can appear at any level of the parse tree.
+            //
+            // The recursive nature of the grammar is an interplay between the `block`
+            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
+            // as represented by this simplified grammar:
+            //
+            //     primary  →  (ruleset | rule)+
+            //     ruleset  →  selector+ block
+            //     block    →  '{' primary '}'
+            //
+            // Only at one point is the primary rule not called from the
+            // block rule: at the root level.
+            //
+            primary: function () {
+                var node, root = [];
+
+                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
+                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
+                               || $(/^[\s\n]+/) || $(/^;+/)) {
+                    node && root.push(node);
+                }
+                return root;
+            },
+
+            // We create a Comment node for CSS comments `/* */`,
+            // but keep the LeSS comments `//` silent, by just skipping
+            // over them.
+            comment: function () {
+                var comment;
+
+                if (input.charAt(i) !== '/') return;
+
+                if (input.charAt(i + 1) === '/') {
+                    return new(tree.Comment)($(/^\/\/.*/), true);
+                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
+                    return new(tree.Comment)(comment);
+                }
+            },
+
+            //
+            // Entities are tokens which can be found inside an Expression
+            //
+            entities: {
+                //
+                // A string, which supports escaping " and '
+                //
+                //     "milky way" 'he\'s the one!'
+                //
+                quoted: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
+
+                    e && $('~');
+
+                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
+                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
+                    }
+                },
+
+                //
+                // A catch-all word, such as:
+                //
+                //     black border-collapse
+                //
+                keyword: function () {
+                    var k;
+
+                    if (k = $(/^[_A-Za-z-][_A-Za-z0-9-]*/)) {
+                        if (tree.colors.hasOwnProperty(k)) {
+                            // detect named color
+                            return new(tree.Color)(tree.colors[k].slice(1));
+                        } else {
+                            return new(tree.Keyword)(k);
+                        }
+                    }
+                },
+
+                //
+                // A function call
+                //
+                //     rgb(255, 0, 255)
+                //
+                // We also try to catch IE's `alpha()`, but let the `alpha` parser
+                // deal with the details.
+                //
+                // The arguments are parsed with the `entities.arguments` parser.
+                //
+                call: function () {
+                    var name, nameLC, args, alpha_ret, index = i;
+
+                    if (! (name = /^([\w-]+|%|progid:[\w\.]+)\(/.exec(chunks[j]))) return;
+
+                    name = name[1];
+                    nameLC = name.toLowerCase();
+
+                    if (nameLC === 'url') { return null }
+                    else                { i += name.length }
+
+                    if (nameLC === 'alpha') {
+                        alpha_ret = $(this.alpha);
+                        if(typeof alpha_ret !== 'undefined') {
+                            return alpha_ret;
+                        }
+                    }
+
+                    $('('); // Parse the '(' and consume whitespace.
+
+                    args = $(this.entities.arguments);
+
+                    if (! $(')')) return;
+
+                    if (name) { return new(tree.Call)(name, args, index, env.filename) }
+                },
+                arguments: function () {
+                    var args = [], arg;
+
+                    while (arg = $(this.entities.assignment) || $(this.expression)) {
+                        args.push(arg);
+                        if (! $(',')) { break }
+                    }
+                    return args;
+                },
+                literal: function () {
+                    return $(this.entities.ratio) ||
+                           $(this.entities.dimension) ||
+                           $(this.entities.color) ||
+                           $(this.entities.quoted) ||
+                           $(this.entities.unicodeDescriptor);
+                },
+
+                // Assignments are argument entities for calls.
+                // They are present in ie filter properties as shown below.
+                //
+                //     filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
+                //
+
+                assignment: function () {
+                    var key, value;
+                    if ((key = $(/^\w+(?=\s?=)/i)) && $('=') && (value = $(this.entity))) {
+                        return new(tree.Assignment)(key, value);
+                    }
+                },
+
+                //
+                // Parse url() tokens
+                //
+                // We use a specific rule for urls, because they don't really behave like
+                // standard function calls. The difference is that the argument doesn't have
+                // to be enclosed within a string, so it can't be parsed as an Expression.
+                //
+                url: function () {
+                    var value;
+
+                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
+                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
+                            $(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || "";
+
+                    expect(')');
+
+                    return new(tree.URL)((value.value != null || value instanceof tree.Variable)
+                                        ? value : new(tree.Anonymous)(value), env.rootpath);
+                },
+
+                //
+                // A Variable entity, such as `@fink`, in
+                //
+                //     width: @fink + 2px
+                //
+                // We use a different parser for variable definitions,
+                // see `parsers.variable`.
+                //
+                variable: function () {
+                    var name, index = i;
+
+                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
+                        return new(tree.Variable)(name, index, env.filename);
+                    }
+                },
+
+                // A variable entity useing the protective {} e.g. @{var}
+                variableCurly: function () {
+                    var name, curly, index = i;
+
+                    if (input.charAt(i) === '@' && (curly = $(/^@\{([\w-]+)\}/))) {
+                        return new(tree.Variable)("@" + curly[1], index, env.filename);
+                    }
+                },
+
+                //
+                // A Hexadecimal color
+                //
+                //     #4F3C2F
+                //
+                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
+                //
+                color: function () {
+                    var rgb;
+
+                    if (input.charAt(i) === '#' && (rgb = $(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
+                        return new(tree.Color)(rgb[1]);
+                    }
+                },
+
+                //
+                // A Dimension, that is, a number and a unit
+                //
+                //     0.5em 95%
+                //
+                dimension: function () {
+                    var value, c = input.charCodeAt(i);
+                    //Is the first char of the dimension 0-9, '.', '+' or '-'
+                    if ((c > 57 || c < 43) || c === 47 || c == 44) return;
+
+                    if (value = $(/^([+-]?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn|dpi|dpcm|dppx|rem|vw|vh|vmin|vm|ch)?/)) {
+                        return new(tree.Dimension)(value[1], value[2]);
+                    }
+                },
+
+                //
+                // A Ratio
+                //
+                //    16/9
+                //
+                ratio: function () {
+                  var value, c = input.charCodeAt(i);
+                  if (c > 57 || c < 48) return;
+
+                  if (value = $(/^(\d+\/\d+)/)) {
+                    return new(tree.Ratio)(value[1]);
+                  }
+                },
+                
+                //
+                // A unicode descriptor, as is used in unicode-range
+                //
+                // U+0??  or U+00A1-00A9
+                //
+                unicodeDescriptor: function () {
+                    var ud;
+                    
+                    if (ud = $(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/)) {
+                        return new(tree.UnicodeDescriptor)(ud[0]);
+                    }
+                },
+
+                //
+                // JavaScript code to be evaluated
+                //
+                //     `window.location.href`
+                //
+                javascript: function () {
+                    var str, j = i, e;
+
+                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
+                    if (input.charAt(j) !== '`') { return }
+
+                    e && $('~');
+
+                    if (str = $(/^`([^`]*)`/)) {
+                        return new(tree.JavaScript)(str[1], i, e);
+                    }
+                }
+            },
+
+            //
+            // The variable part of a variable definition. Used in the `rule` parser
+            //
+            //     @fink:
+            //
+            variable: function () {
+                var name;
+
+                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
+            },
+
+            //
+            // A font size/line-height shorthand
+            //
+            //     small/12px
+            //
+            // We need to peek first, or we'll match on keywords and dimensions
+            //
+            shorthand: function () {
+                var a, b;
+
+                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
+
+                save();
+
+                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
+                    return new(tree.Shorthand)(a, b);
+                }
+
+                restore();
+            },
+
+            //
+            // Mixins
+            //
+            mixin: {
+                //
+                // A Mixin call, with an optional argument list
+                //
+                //     #mixins > .square(#fff);
+                //     .rounded(4px, black);
+                //     .button;
+                //
+                // The `while` loop is there because mixins can be
+                // namespaced, but we only support the child and descendant
+                // selector for now.
+                //
+                call: function () {
+                    var elements = [], e, c, argsSemiColon = [], argsComma = [], args, delim, arg, nameLoop, expressions, isSemiColonSeperated, expressionContainsNamed, index = i, s = input.charAt(i), name, value, important = false;
+
+                    if (s !== '.' && s !== '#') { return }
+                    
+                    save(); // stop us absorbing part of an invalid selector
+
+                    while (e = $(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)) {
+                        elements.push(new(tree.Element)(c, e, i));
+                        c = $('>');
+                    }
+                    if ($('(')) {
+                        expressions = [];
+                        while (arg = $(this.expression)) {
+                            nameLoop = null;
+                            value = arg;
+
+                            // Variable
+                            if (arg.value.length == 1) {
+                                var val = arg.value[0];
+                                if (val instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        if (expressions.length > 0) {
+                                            if (isSemiColonSeperated) {
+                                                error("Cannot mix ; and , as delimiter types");
+                                            }
+                                            expressionContainsNamed = true;
+                                        }
+                                        value = expect(this.expression);
+                                        nameLoop = (name = val.name);
+                                    }
+                                }
+                            }
+                            
+                            expressions.push(value);
+                            
+                            argsComma.push({ name: nameLoop, value: value });
+                            
+                            if ($(',')) {
+                                continue;
+                            }
+                            
+                            if ($(';') || isSemiColonSeperated) {
+                            
+                                if (expressionContainsNamed) {
+                                    error("Cannot mix ; and , as delimiter types");
+                                }
+                            
+                                isSemiColonSeperated = true;
+                                                        
+                                if (expressions.length > 1) {
+                                    value = new(tree.Value)(expressions);
+                                }
+                                argsSemiColon.push({ name: name, value: value });
+                            
+                                name = null;
+                                expressions = [];
+                                expressionContainsNamed = false;
+                            }
+                        }
+
+                        expect(')');
+                    }
+
+                    args = isSemiColonSeperated ? argsSemiColon : argsComma;
+
+                    if ($(this.important)) {
+                        important = true;
+                    }
+
+                    if (elements.length > 0 && ($(';') || peek('}'))) {
+                        return new(tree.mixin.Call)(elements, args, index, env.filename, important);
+                    }
+                    
+                    restore();
+                },
+
+                //
+                // A Mixin definition, with a list of parameters
+                //
+                //     .rounded (@radius: 2px, @color) {
+                //        ...
+                //     }
+                //
+                // Until we have a finer grained state-machine, we have to
+                // do a look-ahead, to make sure we don't have a mixin call.
+                // See the `rule` function for more information.
+                //
+                // We start by matching `.rounded (`, and then proceed on to
+                // the argument list, which has optional default values.
+                // We store the parameters in `params`, with a `value` key,
+                // if there is a value, such as in the case of `@radius`.
+                //
+                // Once we've got our params list, and a closing `)`, we parse
+                // the `{...}` block.
+                //
+                definition: function () {
+                    var name, params = [], match, ruleset, param, value, cond, variadic = false;
+                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
+                        peek(/^[^{]*\}/)) return;
+
+                    save();
+
+                    if (match = $(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)) {
+                        name = match[1];
+
+                        do {
+                            $(this.comment);
+                            if (input.charAt(i) === '.' && $(/^\.{3}/)) {
+                                variadic = true;
+                                params.push({ variadic: true });
+                                break;
+                            } else if (param = $(this.entities.variable) || $(this.entities.literal)
+                                                                         || $(this.entities.keyword)) {
+                                // Variable
+                                if (param instanceof tree.Variable) {
+                                    if ($(':')) {
+                                        value = expect(this.expression, 'expected expression');
+                                        params.push({ name: param.name, value: value });
+                                    } else if ($(/^\.{3}/)) {
+                                        params.push({ name: param.name, variadic: true });
+                                        variadic = true;
+                                        break;
+                                    } else {
+                                        params.push({ name: param.name });
+                                    }
+                                } else {
+                                    params.push({ value: param });
+                                }
+                            } else {
+                                break;
+                            }
+                        } while ($(',') || $(';'))
+
+                        // .mixincall("@{a}"); 
+                        // looks a bit like a mixin definition.. so we have to be nice and restore
+                        if (!$(')')) {
+                            furthest = i;
+                            restore();
+                        }
+                        
+                        $(this.comment);
+
+                        if ($(/^when/)) { // Guard
+                            cond = expect(this.conditions, 'expected condition');
+                        }
+
+                        ruleset = $(this.block);
+
+                        if (ruleset) {
+                            return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
+                        } else {
+                            restore();
+                        }
+                    }
+                }
+            },
+
+            //
+            // Entities are the smallest recognized token,
+            // and can be found inside a rule's value.
+            //
+            entity: function () {
+                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
+                       $(this.entities.call)    || $(this.entities.keyword)  ||$(this.entities.javascript) ||
+                       $(this.comment);
+            },
+
+            //
+            // A Rule terminator. Note that we use `peek()` to check for '}',
+            // because the `block` rule will be expecting it, but we still need to make sure
+            // it's there, if ';' was ommitted.
+            //
+            end: function () {
+                return $(';') || peek('}');
+            },
+
+            //
+            // IE's alpha function
+            //
+            //     alpha(opacity=88)
+            //
+            alpha: function () {
+                var value;
+
+                if (! $(/^\(opacity=/i)) return;
+                if (value = $(/^\d+/) || $(this.entities.variable)) {
+                    expect(')');
+                    return new(tree.Alpha)(value);
+                }
+            },
+
+            //
+            // A Selector Element
+            //
+            //     div
+            //     + h1
+            //     #socks
+            //     input[type="text"]
+            //
+            // Elements are the building blocks for Selectors,
+            // they are made out of a `Combinator` (see combinator rule),
+            // and an element name, such as a tag a class, or `*`.
+            //
+            element: function () {
+                var e, t, c, v;
+
+                c = $(this.combinator);
+
+                e = $(/^(?:\d+\.\d+|\d+)%/) || $(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
+                    $('*') || $('&') || $(this.attribute) || $(/^\([^()@]+\)/) || $(/^[\.#](?=@)/) || $(this.entities.variableCurly);
+
+                if (! e) {
+                    if ($('(')) {
+                        if ((v = ($(this.entities.variableCurly) || 
+                                $(this.entities.variable) || 
+                                $(this.selector))) && 
+                                $(')')) {
+                            e = new(tree.Paren)(v);
+                        }
+                    }
+                }
+
+                if (e) { return new(tree.Element)(c, e, i) }
+            },
+
+            //
+            // Combinators combine elements together, in a Selector.
+            //
+            // Because our parser isn't white-space sensitive, special care
+            // has to be taken, when parsing the descendant combinator, ` `,
+            // as it's an empty space. We have to check the previous character
+            // in the input, to see if it's a ` ` character. More info on how
+            // we deal with this in *combinator.js*.
+            //
+            combinator: function () {
+                var match, c = input.charAt(i);
+
+                if (c === '>' || c === '+' || c === '~' || c === '|') {
+                    i++;
+                    while (input.charAt(i).match(/\s/)) { i++ }
+                    return new(tree.Combinator)(c);
+                } else if (input.charAt(i - 1).match(/\s/)) {
+                    return new(tree.Combinator)(" ");
+                } else {
+                    return new(tree.Combinator)(null);
+                }
+            },
+
+            //
+            // A CSS Selector
+            //
+            //     .class > div + h1
+            //     li a:hover
+            //
+            // Selectors are made out of one or more Elements, see above.
+            //
+            selector: function () {
+                var sel, e, elements = [], c, match;
+
+                // depreciated, will be removed soon
+                if ($('(')) {
+                    sel = $(this.entity);
+                    if (!$(')')) { return null; }
+                    return new(tree.Selector)([new(tree.Element)('', sel, i)]);
+                }
+
+                while (e = $(this.element)) {
+                    c = input.charAt(i);
+                    elements.push(e)
+                    if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { break }
+                }
+
+                if (elements.length > 0) { return new(tree.Selector)(elements) }
+            },
+            attribute: function () {
+                var attr = '', key, val, op;
+
+                if (! $('[')) return;
+
+                if (key = $(/^(?:[_A-Za-z0-9-]|\\.)+/) || $(this.entities.quoted)) {
+                    if ((op = $(/^[|~*$^]?=/)) &&
+                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
+                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
+                    } else { attr = key }
+                }
+
+                if (! $(']')) return;
+
+                if (attr) { return "[" + attr + "]" }
+            },
+
+            //
+            // The `block` rule is used by `ruleset` and `mixin.definition`.
+            // It's a wrapper around the `primary` rule, with added `{}`.
+            //
+            block: function () {
+                var content;
+                if ($('{') && (content = $(this.primary)) && $('}')) {
+                    return content;
+                }
+            },
+
+            //
+            // div, .class, body > p {...}
+            //
+            ruleset: function () {
+                var selectors = [], s, rules, match, debugInfo;
+                
+                save();
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                while (s = $(this.selector)) {
+                    selectors.push(s);
+                    $(this.comment);
+                    if (! $(',')) { break }
+                    $(this.comment);
+                }
+
+                if (selectors.length > 0 && (rules = $(this.block))) {
+                    var ruleset = new(tree.Ruleset)(selectors, rules, env.strictImports);
+                    if (env.dumpLineNumbers)
+                        ruleset.debugInfo = debugInfo;
+                    return ruleset;
+                } else {
+                    // Backtrack
+                    furthest = i;
+                    restore();
+                }
+            },
+            rule: function () {
+                var name, value, c = input.charAt(i), important, match;
+                save();
+
+                if (c === '.' || c === '#' || c === '&') { return }
+
+                if (name = $(this.variable) || $(this.property)) {
+                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
+                        i += match[0].length - 1;
+                        value = new(tree.Anonymous)(match[1]);
+                    } else if (name === "font") {
+                        value = $(this.font);
+                    } else {
+                        value = $(this.value);
+                    }
+                    important = $(this.important);
+
+                    if (value && $(this.end)) {
+                        return new(tree.Rule)(name, value, important, memo);
+                    } else {
+                        furthest = i;
+                        restore();
+                    }
+                }
+            },
+
+            //
+            // An @import directive
+            //
+            //     @import "lib";
+            //
+            // Depending on our environemnt, importing is done differently:
+            // In the browser, it's an XHR request, in Node, it would be a
+            // file-system operation. The function used for importing is
+            // stored in `import`, which we pass to the Import constructor.
+            //
+            "import": function () {
+                var path, features, index = i;
+                
+                save();
+                
+                var dir = $(/^@import(?:-(once))?\s+/);
+
+                if (dir && (path = $(this.entities.quoted) || $(this.entities.url))) {
+                    features = $(this.mediaFeatures);
+                    if ($(';')) {
+                        return new(tree.Import)(path, imports, features, (dir[1] === 'once'), index, env.rootpath);
+                    }
+                }
+                
+                restore();
+            },
+
+            mediaFeature: function () {
+                var e, p, nodes = [];
+
+                do {
+                    if (e = $(this.entities.keyword)) {
+                        nodes.push(e);
+                    } else if ($('(')) {
+                        p = $(this.property);
+                        e = $(this.entity);
+                        if ($(')')) {
+                            if (p && e) {
+                                nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, i, true)));
+                            } else if (e) {
+                                nodes.push(new(tree.Paren)(e));
+                            } else {
+                                return null;
+                            }
+                        } else { return null }
+                    }
+                } while (e);
+
+                if (nodes.length > 0) {
+                    return new(tree.Expression)(nodes);
+                }
+            },
+
+            mediaFeatures: function () {
+                var e, features = [];
+
+                do {
+                  if (e = $(this.mediaFeature)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  } else if (e = $(this.entities.variable)) {
+                      features.push(e);
+                      if (! $(',')) { break }
+                  }
+                } while (e);
+
+                return features.length > 0 ? features : null;
+            },
+
+            media: function () {
+                var features, rules, media, debugInfo;
+
+                if (env.dumpLineNumbers)
+                    debugInfo = getDebugInfo(i, input, env);
+
+                if ($(/^@media/)) {
+                    features = $(this.mediaFeatures);
+
+                    if (rules = $(this.block)) {
+                        media = new(tree.Media)(rules, features);
+                        if(env.dumpLineNumbers)
+                            media.debugInfo = debugInfo;
+                        return media;
+                    }
+                }
+            },
+
+            //
+            // A CSS Directive
+            //
+            //     @charset "utf-8";
+            //
+            directive: function () {
+                var name, value, rules, identifier, e, nodes, nonVendorSpecificName,
+                    hasBlock, hasIdentifier, hasExpression;
+
+                if (input.charAt(i) !== '@') return;
+
+                if (value = $(this['import']) || $(this.media)) {
+                    return value;
+                }
+                
+                save();
+
+                name = $(/^@[a-z-]+/);
+                
+                if (!name) return;
+
+                nonVendorSpecificName = name;
+                if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
+                    nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
+                }
+
+                switch(nonVendorSpecificName) {
+                    case "@font-face":
+                        hasBlock = true;
+                        break;
+                    case "@viewport":
+                    case "@top-left":
+                    case "@top-left-corner":
+                    case "@top-center":
+                    case "@top-right":
+                    case "@top-right-corner":
+                    case "@bottom-left":
+                    case "@bottom-left-corner":
+                    case "@bottom-center":
+                    case "@bottom-right":
+                    case "@bottom-right-corner":
+                    case "@left-top":
+                    case "@left-middle":
+                    case "@left-bottom":
+                    case "@right-top":
+                    case "@right-middle":
+                    case "@right-bottom":
+                        hasBlock = true;
+                        break;
+                    case "@page":
+                    case "@document":
+                    case "@supports":
+                    case "@keyframes":
+                        hasBlock = true;
+                        hasIdentifier = true;
+                        break;
+                    case "@namespace":
+                        hasExpression = true;
+                        break;
+                }
+
+                if (hasIdentifier) {
+                    name += " " + ($(/^[^{]+/) || '').trim();
+                }
+
+                if (hasBlock)
+                {
+                    if (rules = $(this.block)) {
+                        return new(tree.Directive)(name, rules);
+                    }
+                } else {
+                    if ((value = hasExpression ? $(this.expression) : $(this.entity)) && $(';')) {
+                        var directive = new(tree.Directive)(name, value);
+                        if (env.dumpLineNumbers) {
+                            directive.debugInfo = getDebugInfo(i, input, env);
+                        }
+                        return directive;
+                    }
+                }
+                
+                restore();
+            },
+            font: function () {
+                var value = [], expression = [], weight, shorthand, font, e;
+
+                while (e = $(this.shorthand) || $(this.entity)) {
+                    expression.push(e);
+                }
+                value.push(new(tree.Expression)(expression));
+
+                if ($(',')) {
+                    while (e = $(this.expression)) {
+                        value.push(e);
+                        if (! $(',')) { break }
+                    }
+                }
+                return new(tree.Value)(value);
+            },
+
+            //
+            // A Value is a comma-delimited list of Expressions
+            //
+            //     font-family: Baskerville, Georgia, serif;
+            //
+            // In a Rule, a Value represents everything after the `:`,
+            // and before the `;`.
+            //
+            value: function () {
+                var e, expressions = [], important;
+
+                while (e = $(this.expression)) {
+                    expressions.push(e);
+                    if (! $(',')) { break }
+                }
+
+                if (expressions.length > 0) {
+                    return new(tree.Value)(expressions);
+                }
+            },
+            important: function () {
+                if (input.charAt(i) === '!') {
+                    return $(/^! *important/);
+                }
+            },
+            sub: function () {
+                var e;
+
+                if ($('(') && (e = $(this.expression)) && $(')')) {
+                    return e;
+                }
+            },
+            multiplication: function () {
+                var m, a, op, operation;
+                if (m = $(this.operand)) {
+                    while (!peek(/^\/[*\/]/) && (op = ($('/') || $('*'))) && (a = $(this.operand))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            addition: function () {
+                var m, a, op, operation;
+                if (m = $(this.multiplication)) {
+                    while ((op = $(/^[-+]\s+/) || (!isWhitespace(input.charAt(i - 1)) && ($('+') || $('-')))) &&
+                           (a = $(this.multiplication))) {
+                        operation = new(tree.Operation)(op, [operation || m, a]);
+                    }
+                    return operation || m;
+                }
+            },
+            conditions: function () {
+                var a, b, index = i, condition;
+
+                if (a = $(this.condition)) {
+                    while ($(',') && (b = $(this.condition))) {
+                        condition = new(tree.Condition)('or', condition || a, b, index);
+                    }
+                    return condition || a;
+                }
+            },
+            condition: function () {
+                var a, b, c, op, index = i, negate = false;
+
+                if ($(/^not/)) { negate = true }
+                expect('(');
+                if (a = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                    if (op = $(/^(?:>=|=<|[<=>])/)) {
+                        if (b = $(this.addition) || $(this.entities.keyword) || $(this.entities.quoted)) {
+                            c = new(tree.Condition)(op, a, b, index, negate);
+                        } else {
+                            error('expected expression');
+                        }
+                    } else {
+                        c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, negate);
+                    }
+                    expect(')');
+                    return $(/^and/) ? new(tree.Condition)('and', c, $(this.condition)) : c;
+                }
+            },
+
+            //
+            // An operand is anything that can be part of an operation,
+            // such as a Color, or a Variable
+            //
+            operand: function () {
+                var negate, p = input.charAt(i + 1);
+
+                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
+                var o = $(this.sub) || $(this.entities.dimension) ||
+                        $(this.entities.color) || $(this.entities.variable) ||
+                        $(this.entities.call);
+                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
+                              : o;
+            },
+
+            //
+            // Expressions either represent mathematical operations,
+            // or white-space delimited Entities.
+            //
+            //     1px solid black
+            //     @var * 2
+            //
+            expression: function () {
+                var e, delim, entities = [], d;
+
+                while (e = $(this.addition) || $(this.entity)) {
+                    entities.push(e);
+                }
+                if (entities.length > 0) {
+                    return new(tree.Expression)(entities);
+                }
+            },
+            property: function () {
+                var name;
+
+                if (name = $(/^(\*?-?[_a-z0-9-]+)\s*:/)) {
+                    return name[1];
+                }
+            }
+        }
+    };
+};
+
+if (less.mode === 'browser' || less.mode === 'rhino') {
+    //
+    // Used by `@import` directives
+    //
+    less.Parser.importer = function (path, paths, callback, env) {
+        if (!/^([a-z-]+:)?\//.test(path) && paths.length > 0) {
+            path = paths[0] + path;
+        }
+        // We pass `true` as 3rd argument, to force the reload of the import.
+        // This is so we can get the syntax tree as opposed to just the CSS output,
+        // as we need this to evaluate the current stylesheet.
+        loadStyleSheet({ 
+            href: path, 
+            title: path, 
+            type: env.mime, 
+            contents: env.contents, 
+            files: env.files, 
+            rootpath: env.rootpath,
+            entryPath: env.entryPath,
+            relativeUrls: env.relativeUrls }, 
+        function (e, root, data, sheet, _, path) {
+            if (e && typeof(env.errback) === "function") {
+                env.errback.call(null, path, paths, callback, env);
+            } else {
+                callback.call(null, e, root, path);
+            }
+        }, true);
+    };
+}
+
diff --git a/util/less/lib/less/rhino.js b/util/less/lib/less/rhino.js
new file mode 100644
index 0000000..57d60f5
--- /dev/null
+++ b/util/less/lib/less/rhino.js
@@ -0,0 +1,123 @@
+var name;
+
+function loadStyleSheet(sheet, callback, reload, remaining) {
+    var endOfPath = Math.max(name.lastIndexOf('/'), name.lastIndexOf('\\')),
+        sheetName = name.slice(0, endOfPath + 1) + sheet.href,
+        contents = sheet.contents || {},
+        input = readFile(sheetName);
+        
+    contents[sheetName] = input;
+        
+    var parser = new less.Parser({
+        paths: [sheet.href.replace(/[\w\.-]+$/, '')],
+        contents: contents
+    });
+    parser.parse(input, function (e, root) {
+        if (e) {
+            return error(e, sheetName);
+        }
+        try {
+            callback(e, root, input, sheet, { local: false, lastModified: 0, remaining: remaining }, sheetName);
+        } catch(e) {
+            error(e, sheetName);
+        }
+    });
+}
+
+function writeFile(filename, content) {
+    var fstream = new java.io.FileWriter(filename);
+    var out = new java.io.BufferedWriter(fstream);
+    out.write(content);
+    out.close();
+}
+
+// Command line integration via Rhino
+(function (args) {
+    var output,
+        compress = false,
+        i;
+        
+    for(i = 0; i < args.length; i++) {
+        switch(args[i]) {
+            case "-x":
+                compress = true;
+                break;
+            default:
+                if (!name) {
+                    name = args[i];
+                } else if (!output) {
+                    output = args[i];
+                } else {
+                    print("unrecognised parameters");
+                    print("input_file [output_file] [-x]");
+                }
+        }
+    }
+
+    if (!name) {
+        print('No files present in the fileset; Check your pattern match in build.xml');
+        quit(1);
+    }
+    path = name.split("/");path.pop();path=path.join("/")
+
+    var input = readFile(name);
+
+    if (!input) {
+        print('lesscss: couldn\'t open file ' + name);
+        quit(1);
+    }
+
+    var result;
+    try {
+        var parser = new less.Parser();
+        parser.parse(input, function (e, root) {
+            if (e) {
+                error(e, name);
+                quit(1);
+            } else {
+                result = root.toCSS({compress: compress || false});
+                if (output) {
+                    writeFile(output, result);
+                    print("Written to " + output);
+                } else {
+                    print(result);
+                }
+                quit(0);
+            }
+        });
+    }
+    catch(e) {
+        error(e, name);
+        quit(1);
+    }
+    print("done");
+}(arguments));
+
+function error(e, filename) {
+
+    var content = "Error : " + filename + "\n";
+    
+    filename = e.filename || filename;
+    
+    if (e.message) {
+        content += e.message + "\n";
+    }
+
+    var errorline = function (e, i, classname) {
+        if (e.extract[i]) {
+            content += 
+                String(parseInt(e.line) + (i - 1)) + 
+                ":" + e.extract[i] + "\n";
+        }
+    };
+
+    if (e.stack) {
+        content += e.stack;
+    } else if (e.extract) {
+        content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n';
+        errorline(e, 0);
+        errorline(e, 1);
+        errorline(e, 2);
+    }
+   print(content);
+}
\ No newline at end of file
diff --git a/util/less/lib/less/tree.js b/util/less/lib/less/tree.js
new file mode 100644
index 0000000..134adbd
--- /dev/null
+++ b/util/less/lib/less/tree.js
@@ -0,0 +1,45 @@
+(function (tree) {
+
+tree.debugInfo = function(env, ctx) {
+    var result="";
+    if (env.dumpLineNumbers && !env.compress) {
+        switch(env.dumpLineNumbers) {
+            case 'comments':
+                result = tree.debugInfo.asComment(ctx);
+                break;
+            case 'mediaquery':
+                result = tree.debugInfo.asMediaQuery(ctx);
+                break;
+            case 'all':
+                result = tree.debugInfo.asComment(ctx)+tree.debugInfo.asMediaQuery(ctx);
+                break;
+        }
+    }
+    return result;
+};
+
+tree.debugInfo.asComment = function(ctx) {
+    return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
+};
+
+tree.debugInfo.asMediaQuery = function(ctx) {
+    return '@media -sass-debug-info{filename{font-family:' +
+        ('file://' + ctx.debugInfo.fileName).replace(/[\/:.]/g, '\\$&') +
+        '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n';
+};
+
+tree.find = function (obj, fun) {
+    for (var i = 0, r; i < obj.length; i++) {
+        if (r = fun.call(obj, obj[i])) { return r }
+    }
+    return null;
+};
+tree.jsify = function (obj) {
+    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
+        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
+    } else {
+        return obj.toCSS(false);
+    }
+};
+
+})(require('./tree'));
diff --git a/util/less/lib/less/tree/alpha.js b/util/less/lib/less/tree/alpha.js
new file mode 100644
index 0000000..139ae92
--- /dev/null
+++ b/util/less/lib/less/tree/alpha.js
@@ -0,0 +1,17 @@
+(function (tree) {
+
+tree.Alpha = function (val) {
+    this.value = val;
+};
+tree.Alpha.prototype = {
+    toCSS: function () {
+        return "alpha(opacity=" +
+               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
+    },
+    eval: function (env) {
+        if (this.value.eval) { this.value = this.value.eval(env) }
+        return this;
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/anonymous.js b/util/less/lib/less/tree/anonymous.js
new file mode 100644
index 0000000..4461490
--- /dev/null
+++ b/util/less/lib/less/tree/anonymous.js
@@ -0,0 +1,27 @@
+(function (tree) {
+
+tree.Anonymous = function (string) {
+    this.value = string.value || string;
+};
+tree.Anonymous.prototype = {
+    toCSS: function () {
+        return this.value;
+    },
+    eval: function () { return this },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/assignment.js b/util/less/lib/less/tree/assignment.js
new file mode 100644
index 0000000..a5559ad
--- /dev/null
+++ b/util/less/lib/less/tree/assignment.js
@@ -0,0 +1,19 @@
+(function (tree) {
+
+tree.Assignment = function (key, val) {
+    this.key = key;
+    this.value = val;
+};
+tree.Assignment.prototype = {
+    toCSS: function () {
+        return this.key + '=' + (this.value.toCSS ? this.value.toCSS() : this.value);
+    },
+    eval: function (env) {
+        if (this.value.eval) {
+            return new(tree.Assignment)(this.key, this.value.eval(env));
+        }
+        return this;
+    }
+};
+
+})(require('../tree'));
\ No newline at end of file
diff --git a/util/less/lib/less/tree/call.js b/util/less/lib/less/tree/call.js
new file mode 100644
index 0000000..f8045ed
--- /dev/null
+++ b/util/less/lib/less/tree/call.js
@@ -0,0 +1,54 @@
+(function (tree) {
+
+//
+// A function call node.
+//
+tree.Call = function (name, args, index, filename) {
+    this.name = name;
+    this.args = args;
+    this.index = index;
+    this.filename = filename;
+};
+tree.Call.prototype = {
+    //
+    // When evaluating a function call,
+    // we either find the function in `tree.functions` [1],
+    // in which case we call it, passing the  evaluated arguments,
+    // if this returns null or we cannot find the function, we 
+    // simply print it out as it appeared originally [2].
+    //
+    // The *functions.js* file contains the built-in functions.
+    //
+    // The reason why we evaluate the arguments, is in the case where
+    // we try to pass a variable to a function, like: `saturate(@color)`.
+    // The function should receive the value, not the variable.
+    //
+    eval: function (env) {
+        var args = this.args.map(function (a) { return a.eval(env) }),
+            result;
+
+        if (this.name in tree.functions) { // 1.
+            try {
+                result = tree.functions[this.name].apply(tree.functions, args);
+                if (result != null) {
+                    return result;
+                }
+            } catch (e) {
+                throw { type: e.type || "Runtime",
+                        message: "error evaluating function `" + this.name + "`" +
+                                 (e.message ? ': ' + e.message : ''),
+                        index: this.index, filename: this.filename };
+            }
+        }
+        
+        // 2.
+        return new(tree.Anonymous)(this.name +
+            "(" + args.map(function (a) { return a.toCSS(env) }).join(', ') + ")");
+    },
+
+    toCSS: function (env) {
+        return this.eval(env).toCSS();
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/color.js b/util/less/lib/less/tree/color.js
new file mode 100644
index 0000000..6adf317
--- /dev/null
+++ b/util/less/lib/less/tree/color.js
@@ -0,0 +1,111 @@
+(function (tree) {
+//
+// RGB Colors - #ff0014, #eee
+//
+tree.Color = function (rgb, a) {
+    //
+    // The end goal here, is to parse the arguments
+    // into an integer triplet, such as `128, 255, 0`
+    //
+    // This facilitates operations and conversions.
+    //
+    if (Array.isArray(rgb)) {
+        this.rgb = rgb;
+    } else if (rgb.length == 6) {
+        this.rgb = rgb.match(/.{2}/g).map(function (c) {
+            return parseInt(c, 16);
+        });
+    } else {
+        this.rgb = rgb.split('').map(function (c) {
+            return parseInt(c + c, 16);
+        });
+    }
+    this.alpha = typeof(a) === 'number' ? a : 1;
+};
+tree.Color.prototype = {
+    eval: function () { return this },
+
+    //
+    // If we have some transparency, the only way to represent it
+    // is via `rgba`. Otherwise, we use the hex representation,
+    // which has better compatibility with older browsers.
+    // Values are capped between `0` and `255`, rounded and zero-padded.
+    //
+    toCSS: function () {
+        if (this.alpha < 1.0) {
+            return "rgba(" + this.rgb.map(function (c) {
+                return Math.round(c);
+            }).concat(this.alpha).join(', ') + ")";
+        } else {
+            return '#' + this.rgb.map(function (i) {
+                i = Math.round(i);
+                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+                return i.length === 1 ? '0' + i : i;
+            }).join('');
+        }
+    },
+
+    //
+    // Operations have to be done per-channel, if not,
+    // channels will spill onto each other. Once we have
+    // our result, in the form of an integer triplet,
+    // we create a new Color node to hold the result.
+    //
+    operate: function (op, other) {
+        var result = [];
+
+        if (! (other instanceof tree.Color)) {
+            other = other.toColor();
+        }
+
+        for (var c = 0; c < 3; c++) {
+            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
+        }
+        return new(tree.Color)(result, this.alpha + other.alpha);
+    },
+
+    toHSL: function () {
+        var r = this.rgb[0] / 255,
+            g = this.rgb[1] / 255,
+            b = this.rgb[2] / 255,
+            a = this.alpha;
+
+        var max = Math.max(r, g, b), min = Math.min(r, g, b);
+        var h, s, l = (max + min) / 2, d = max - min;
+
+        if (max === min) {
+            h = s = 0;
+        } else {
+            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
+
+            switch (max) {
+                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
+                case g: h = (b - r) / d + 2;               break;
+                case b: h = (r - g) / d + 4;               break;
+            }
+            h /= 6;
+        }
+        return { h: h * 360, s: s, l: l, a: a };
+    },
+    toARGB: function () {
+        var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
+        return '#' + argb.map(function (i) {
+            i = Math.round(i);
+            i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
+            return i.length === 1 ? '0' + i : i;
+        }).join('');
+    },
+    compare: function (x) {
+        if (!x.rgb) {
+            return -1;
+        }
+        
+        return (x.rgb[0] === this.rgb[0] &&
+            x.rgb[1] === this.rgb[1] &&
+            x.rgb[2] === this.rgb[2] &&
+            x.alpha === this.alpha) ? 0 : -1;
+    }
+};
+
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/comment.js b/util/less/lib/less/tree/comment.js
new file mode 100644
index 0000000..f4a3384
--- /dev/null
+++ b/util/less/lib/less/tree/comment.js
@@ -0,0 +1,14 @@
+(function (tree) {
+
+tree.Comment = function (value, silent) {
+    this.value = value;
+    this.silent = !!silent;
+};
+tree.Comment.prototype = {
+    toCSS: function (env) {
+        return env.compress ? '' : this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/condition.js b/util/less/lib/less/tree/condition.js
new file mode 100644
index 0000000..6b79dc9
--- /dev/null
+++ b/util/less/lib/less/tree/condition.js
@@ -0,0 +1,42 @@
+(function (tree) {
+
+tree.Condition = function (op, l, r, i, negate) {
+    this.op = op.trim();
+    this.lvalue = l;
+    this.rvalue = r;
+    this.index = i;
+    this.negate = negate;
+};
+tree.Condition.prototype.eval = function (env) {
+    var a = this.lvalue.eval(env),
+        b = this.rvalue.eval(env);
+
+    var i = this.index, result;
+
+    var result = (function (op) {
+        switch (op) {
+            case 'and':
+                return a && b;
+            case 'or':
+                return a || b;
+            default:
+                if (a.compare) {
+                    result = a.compare(b);
+                } else if (b.compare) {
+                    result = b.compare(a);
+                } else {
+                    throw { type: "Type",
+                            message: "Unable to perform comparison",
+                            index: i };
+                }
+                switch (result) {
+                    case -1: return op === '<' || op === '=<';
+                    case  0: return op === '=' || op === '>=' || op === '=<';
+                    case  1: return op === '>' || op === '>=';
+                }
+        }
+    })(this.op);
+    return this.negate ? !result : result;
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/dimension.js b/util/less/lib/less/tree/dimension.js
new file mode 100644
index 0000000..22241b8
--- /dev/null
+++ b/util/less/lib/less/tree/dimension.js
@@ -0,0 +1,51 @@
+(function (tree) {
+
+//
+// A number with a unit
+//
+tree.Dimension = function (value, unit) {
+    this.value = parseFloat(value);
+    this.unit = unit || null;
+};
+
+tree.Dimension.prototype = {
+    eval: function () { return this },
+    toColor: function () {
+        return new(tree.Color)([this.value, this.value, this.value]);
+    },
+    toCSS: function () {
+        var css = this.value + this.unit;
+        return css;
+    },
+
+    // In an operation between two Dimensions,
+    // we default to the first Dimension's unit,
+    // so `1px + 2em` will yield `3px`.
+    // In the future, we could implement some unit
+    // conversions such that `100cm + 10mm` would yield
+    // `101cm`.
+    operate: function (op, other) {
+        return new(tree.Dimension)
+                  (tree.operate(op, this.value, other.value),
+                  this.unit || other.unit);
+    },
+
+    compare: function (other) {
+        if (other instanceof tree.Dimension) {
+            if (other.value > this.value) {
+                return -1;
+            } else if (other.value < this.value) {
+                return 1;
+            } else {
+                if (other.unit && this.unit !== other.unit) {
+                    return -1;
+                }
+                return 0;
+            }
+        } else {
+            return -1;
+        }
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/directive.js b/util/less/lib/less/tree/directive.js
new file mode 100644
index 0000000..4d682e6
--- /dev/null
+++ b/util/less/lib/less/tree/directive.js
@@ -0,0 +1,39 @@
+(function (tree) {
+
+tree.Directive = function (name, value) {
+    this.name = name;
+
+    if (Array.isArray(value)) {
+        this.ruleset = new(tree.Ruleset)([], value);
+        this.ruleset.allowImports = true;
+    } else {
+        this.value = value;
+    }
+};
+tree.Directive.prototype = {
+    toCSS: function (ctx, env) {
+        if (this.ruleset) {
+            this.ruleset.root = true;
+            return this.name + (env.compress ? '{' : ' {\n  ') +
+                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                               (env.compress ? '}': '\n}\n');
+        } else {
+            return this.name + ' ' + this.value.toCSS() + ';\n';
+        }
+    },
+    eval: function (env) {
+        var evaldDirective = this;
+        if (this.ruleset) {
+            env.frames.unshift(this);
+            evaldDirective = new(tree.Directive)(this.name);
+            evaldDirective.ruleset = this.ruleset.eval(env);
+            env.frames.shift();
+        }
+        return evaldDirective;
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/element.js b/util/less/lib/less/tree/element.js
new file mode 100644
index 0000000..4e251ee
--- /dev/null
+++ b/util/less/lib/less/tree/element.js
@@ -0,0 +1,49 @@
+(function (tree) {
+
+tree.Element = function (combinator, value, index) {
+    this.combinator = combinator instanceof tree.Combinator ?
+                      combinator : new(tree.Combinator)(combinator);
+
+    if (typeof(value) === 'string') {
+        this.value = value.trim();
+    } else if (value) {
+        this.value = value;
+    } else {
+        this.value = "";
+    }
+    this.index = index;
+};
+tree.Element.prototype.eval = function (env) {
+    return new(tree.Element)(this.combinator,
+                             this.value.eval ? this.value.eval(env) : this.value,
+                             this.index);
+};
+tree.Element.prototype.toCSS = function (env) {
+	var value = (this.value.toCSS ? this.value.toCSS(env) : this.value);
+	if (value == '' && this.combinator.value.charAt(0) == '&') {
+		return '';
+	} else {
+		return this.combinator.toCSS(env || {}) + value;
+	}
+};
+
+tree.Combinator = function (value) {
+    if (value === ' ') {
+        this.value = ' ';
+    } else {
+        this.value = value ? value.trim() : "";
+    }
+};
+tree.Combinator.prototype.toCSS = function (env) {
+    return {
+        ''  : '',
+        ' ' : ' ',
+        ':' : ' :',
+        '+' : env.compress ? '+' : ' + ',
+        '~' : env.compress ? '~' : ' ~ ',
+        '>' : env.compress ? '>' : ' > ',
+        '|' : env.compress ? '|' : ' | '
+    }[this.value];
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/expression.js b/util/less/lib/less/tree/expression.js
new file mode 100644
index 0000000..fbfa9c5
--- /dev/null
+++ b/util/less/lib/less/tree/expression.js
@@ -0,0 +1,23 @@
+(function (tree) {
+
+tree.Expression = function (value) { this.value = value };
+tree.Expression.prototype = {
+    eval: function (env) {
+        if (this.value.length > 1) {
+            return new(tree.Expression)(this.value.map(function (e) {
+                return e.eval(env);
+            }));
+        } else if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return this;
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS ? e.toCSS(env) : '';
+        }).join(' ');
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/import.js b/util/less/lib/less/tree/import.js
new file mode 100644
index 0000000..02594a7
--- /dev/null
+++ b/util/less/lib/less/tree/import.js
@@ -0,0 +1,82 @@
+(function (tree) {
+//
+// CSS @import node
+//
+// The general strategy here is that we don't want to wait
+// for the parsing to be completed, before we start importing
+// the file. That's because in the context of a browser,
+// most of the time will be spent waiting for the server to respond.
+//
+// On creation, we push the import path to our import queue, though
+// `import,push`, we also pass it a callback, which it'll call once
+// the file has been fetched, and parsed.
+//
+tree.Import = function (path, imports, features, once, index, rootpath) {
+    var that = this;
+
+    this.once = once;
+    this.index = index;
+    this._path = path;
+    this.features = features && new(tree.Value)(features);
+    this.rootpath = rootpath;
+		
+    // The '.less' extension is optional
+    if (path instanceof tree.Quoted) {
+        this.path = /(\.[a-z]*$)|([\?;].*)$/.test(path.value) ? path.value : path.value + '.less';
+    } else {
+        this.path = path.value.value || path.value;
+    }
+
+    this.css = /css([\?;].*)?$/.test(this.path);
+
+    // Only pre-compile .less files
+    if (! this.css) {
+        imports.push(this.path, function (e, root, imported) {
+            if (e) { e.index = index }
+            if (imported && that.once) that.skip = imported;
+            that.root = root || new(tree.Ruleset)([], []);
+        });
+    }
+};
+
+//
+// The actual import node doesn't return anything, when converted to CSS.
+// The reason is that it's used at the evaluation stage, so that the rules
+// it imports can be treated like any other rules.
+//
+// In `eval`, we make sure all Import nodes get evaluated, recursively, so
+// we end up with a flat structure, which can easily be imported in the parent
+// ruleset.
+//
+tree.Import.prototype = {
+    toCSS: function (env) {
+        var features = this.features ? ' ' + this.features.toCSS(env) : '';
+
+        if (this.css) {
+            // Add the base path if the import is relative
+            if (typeof this._path.value === "string" && !/^(?:[a-z-]+:|\/)/.test(this._path.value)) {
+                this._path.value = this.rootpath + this._path.value;
+            }
+            return "@import " + this._path.toCSS() + features + ';\n';
+        } else {
+            return "";
+        }
+    },
+    eval: function (env) {
+        var ruleset, features = this.features && this.features.eval(env);
+
+        if (this.skip) return [];
+
+        if (this.css) {
+            return this;
+        } else {
+            ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
+
+            ruleset.evalImports(env);
+
+            return this.features ? new(tree.Media)(ruleset.rules, this.features.value) : ruleset.rules;
+        }
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/javascript.js b/util/less/lib/less/tree/javascript.js
new file mode 100644
index 0000000..772a31d
--- /dev/null
+++ b/util/less/lib/less/tree/javascript.js
@@ -0,0 +1,51 @@
+(function (tree) {
+
+tree.JavaScript = function (string, index, escaped) {
+    this.escaped = escaped;
+    this.expression = string;
+    this.index = index;
+};
+tree.JavaScript.prototype = {
+    eval: function (env) {
+        var result,
+            that = this,
+            context = {};
+
+        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
+            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
+        });
+
+        try {
+            expression = new(Function)('return (' + expression + ')');
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
+                    index: this.index };
+        }
+
+        for (var k in env.frames[0].variables()) {
+            context[k.slice(1)] = {
+                value: env.frames[0].variables()[k].value,
+                toJS: function () {
+                    return this.value.eval(env).toCSS();
+                }
+            };
+        }
+
+        try {
+            result = expression.call(context);
+        } catch (e) {
+            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
+                    index: this.index };
+        }
+        if (typeof(result) === 'string') {
+            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
+        } else if (Array.isArray(result)) {
+            return new(tree.Anonymous)(result.join(', '));
+        } else {
+            return new(tree.Anonymous)(result);
+        }
+    }
+};
+
+})(require('../tree'));
+
diff --git a/util/less/lib/less/tree/keyword.js b/util/less/lib/less/tree/keyword.js
new file mode 100644
index 0000000..701b79e
--- /dev/null
+++ b/util/less/lib/less/tree/keyword.js
@@ -0,0 +1,19 @@
+(function (tree) {
+
+tree.Keyword = function (value) { this.value = value };
+tree.Keyword.prototype = {
+    eval: function () { return this },
+    toCSS: function () { return this.value },
+    compare: function (other) {
+        if (other instanceof tree.Keyword) {
+            return other.value === this.value ? 0 : 1;
+        } else {
+            return -1;
+        }
+    }
+};
+
+tree.True = new(tree.Keyword)('true');
+tree.False = new(tree.Keyword)('false');
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/media.js b/util/less/lib/less/tree/media.js
new file mode 100644
index 0000000..d2a5347
--- /dev/null
+++ b/util/less/lib/less/tree/media.js
@@ -0,0 +1,121 @@
+(function (tree) {
+
+tree.Media = function (value, features) {
+    var selectors = this.emptySelectors();
+
+    this.features = new(tree.Value)(features);
+    this.ruleset = new(tree.Ruleset)(selectors, value);
+    this.ruleset.allowImports = true;
+};
+tree.Media.prototype = {
+    toCSS: function (ctx, env) {
+        var features = this.features.toCSS(env);
+
+        this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
+        return '@media ' + features + (env.compress ? '{' : ' {\n  ') +
+               this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
+                           (env.compress ? '}': '\n}\n');
+    },
+    eval: function (env) {
+        if (!env.mediaBlocks) {
+            env.mediaBlocks = [];
+            env.mediaPath = [];
+        }
+        
+        var media = new(tree.Media)([], []);
+        if(this.debugInfo) {
+            this.ruleset.debugInfo = this.debugInfo;
+            media.debugInfo = this.debugInfo;
+        }
+        media.features = this.features.eval(env);
+        
+        env.mediaPath.push(media);
+        env.mediaBlocks.push(media);
+        
+        env.frames.unshift(this.ruleset);
+        media.ruleset = this.ruleset.eval(env);
+        env.frames.shift();
+        
+        env.mediaPath.pop();
+
+        return env.mediaPath.length === 0 ? media.evalTop(env) :
+                    media.evalNested(env)
+    },
+    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
+    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
+    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) },
+    emptySelectors: function() { 
+        var el = new(tree.Element)('', '&', 0);
+        return [new(tree.Selector)([el])];
+    },
+
+    evalTop: function (env) {
+        var result = this;
+
+        // Render all dependent Media blocks.
+        if (env.mediaBlocks.length > 1) {
+            var selectors = this.emptySelectors();
+            result = new(tree.Ruleset)(selectors, env.mediaBlocks);
+            result.multiMedia = true;
+        }
+
+        delete env.mediaBlocks;
+        delete env.mediaPath;
+
+        return result;
+    },
+    evalNested: function (env) {
+        var i, value,
+            path = env.mediaPath.concat([this]);
+
+        // Extract the media-query conditions separated with `,` (OR).
+        for (i = 0; i < path.length; i++) {
+            value = path[i].features instanceof tree.Value ?
+                        path[i].features.value : path[i].features;
+            path[i] = Array.isArray(value) ? value : [value];
+        }
+
+        // Trace all permutations to generate the resulting media-query.
+        //
+        // (a, b and c) with nested (d, e) ->
+        //    a and d
+        //    a and e
+        //    b and c and d
+        //    b and c and e
+        this.features = new(tree.Value)(this.permute(path).map(function (path) {
+            path = path.map(function (fragment) {
+                return fragment.toCSS ? fragment : new(tree.Anonymous)(fragment);
+            });
+
+            for(i = path.length - 1; i > 0; i--) {
+                path.splice(i, 0, new(tree.Anonymous)("and"));
+            }
+
+            return new(tree.Expression)(path);
+        }));
+
+        // Fake a tree-node that doesn't output anything.
+        return new(tree.Ruleset)([], []);
+    },
+    permute: function (arr) {
+      if (arr.length === 0) {
+          return [];
+      } else if (arr.length === 1) {
+          return arr[0];
+      } else {
+          var result = [];
+          var rest = this.permute(arr.slice(1));
+          for (var i = 0; i < rest.length; i++) {
+              for (var j = 0; j < arr[0].length; j++) {
+                  result.push([arr[0][j]].concat(rest[i]));
+              }
+          }
+          return result;
+      }
+    },
+    bubbleSelectors: function (selectors) {
+      this.ruleset = new(tree.Ruleset)(selectors.slice(0), [this.ruleset]);
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/mixin.js b/util/less/lib/less/tree/mixin.js
new file mode 100644
index 0000000..0533036
--- /dev/null
+++ b/util/less/lib/less/tree/mixin.js
@@ -0,0 +1,212 @@
+(function (tree) {
+
+tree.mixin = {};
+tree.mixin.Call = function (elements, args, index, filename, important) {
+    this.selector = new(tree.Selector)(elements);
+    this.arguments = args;
+    this.index = index;
+    this.filename = filename;
+    this.important = important;
+};
+tree.mixin.Call.prototype = {
+    eval: function (env) {
+        var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound;
+
+        args = this.arguments && this.arguments.map(function (a) {
+            return { name: a.name, value: a.value.eval(env) };
+        });
+
+        for (i = 0; i < env.frames.length; i++) {
+            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
+                isOneFound = true;
+                for (m = 0; m < mixins.length; m++) {
+                    mixin = mixins[m];
+                    isRecursive = false;
+                    for(f = 0; f < env.frames.length; f++) {
+                        if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) {
+                            isRecursive = true;
+                            break;
+                        }
+                    }
+                    if (isRecursive) {
+                        continue;
+                    }
+                    if (mixin.matchArgs(args, env)) {
+                        if (!mixin.matchCondition || mixin.matchCondition(args, env)) {
+                            try {
+                                Array.prototype.push.apply(
+                                      rules, mixin.eval(env, args, this.important).rules);
+                            } catch (e) {
+                                throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
+                            }
+                        }
+                        match = true;
+                    }
+                }
+                if (match) {
+                    return rules;
+                }
+            }
+        }
+        if (isOneFound) {
+            throw { type:    'Runtime',
+                    message: 'No matching definition was found for `' +
+                              this.selector.toCSS().trim() + '('      +
+                              (args ? args.map(function (a) {
+                                  var argValue = "";
+                                  if (a.name) {
+                                      argValue += a.name + ":";
+                                  }
+                                  if (a.value.toCSS) {
+                                      argValue += a.value.toCSS();
+                                  } else {
+                                      argValue += "???";
+                                  }
+                                  return argValue;
+                              }).join(', ') : "") + ")`",
+                    index:   this.index, filename: this.filename };
+        } else {
+            throw { type: 'Name',
+                message: this.selector.toCSS().trim() + " is undefined",
+                index: this.index, filename: this.filename };
+        }
+    }
+};
+
+tree.mixin.Definition = function (name, params, rules, condition, variadic) {
+    this.name = name;
+    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
+    this.params = params;
+    this.condition = condition;
+    this.variadic = variadic;
+    this.arity = params.length;
+    this.rules = rules;
+    this._lookups = {};
+    this.required = params.reduce(function (count, p) {
+        if (!p.name || (p.name && !p.value)) { return count + 1 }
+        else                                 { return count }
+    }, 0);
+    this.parent = tree.Ruleset.prototype;
+    this.frames = [];
+};
+tree.mixin.Definition.prototype = {
+    toCSS:     function ()     { return "" },
+    variable:  function (name) { return this.parent.variable.call(this, name) },
+    variables: function ()     { return this.parent.variables.call(this) },
+    find:      function ()     { return this.parent.find.apply(this, arguments) },
+    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
+
+    evalParams: function (env, mixinEnv, args, evaldArguments) {
+        var frame = new(tree.Ruleset)(null, []), varargs, arg, params = this.params.slice(0), i, j, val, name, isNamedFound, argIndex;
+        
+        if (args) {
+            args = args.slice(0);
+
+            for(i = 0; i < args.length; i++) {
+                arg = args[i];
+                if (name = (arg && arg.name)) {
+                    isNamedFound = false;
+                    for(j = 0; j < params.length; j++) {
+                        if (!evaldArguments[j] && name === params[j].name) {
+                            evaldArguments[j] = arg.value.eval(env);
+                            frame.rules.unshift(new(tree.Rule)(name, arg.value.eval(env)));
+                            isNamedFound = true;
+                            break;
+                        }
+                    }
+                    if (isNamedFound) {
+                        args.splice(i, 1);
+                        i--;
+                        continue;
+                    } else {
+                        throw { type: 'Runtime', message: "Named argument for " + this.name +
+                            ' ' + args[i].name + ' not found' };
+                    }
+                }
+            }
+        }
+        argIndex = 0;
+        for (i = 0; i < params.length; i++) {
+            if (evaldArguments[i]) continue;
+            
+            arg = args && args[argIndex];
+
+            if (name = params[i].name) {
+                if (params[i].variadic && args) {
+                    varargs = [];
+                    for (j = argIndex; j < args.length; j++) {
+                        varargs.push(args[j].value.eval(env));
+                    }
+                    frame.rules.unshift(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
+                } else {
+                    val = arg && arg.value;
+                    if (val) {
+                        val = val.eval(env);
+                    } else if (params[i].value) {
+                        val = params[i].value.eval(mixinEnv);
+                    } else {
+                        throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
+                            ' (' + args.length + ' for ' + this.arity + ')' };
+                    }
+                    
+                    frame.rules.unshift(new(tree.Rule)(name, val));
+                    evaldArguments[i] = val;
+                }
+            }
+            
+            if (params[i].variadic && args) {
+                for (j = argIndex; j < args.length; j++) {
+                    evaldArguments[j] = args[j].value.eval(env);
+                }
+            }
+            argIndex++;
+        }
+
+        return frame;
+    },
+    eval: function (env, args, important) {
+        var _arguments = [],
+            mixinFrames = this.frames.concat(env.frames),
+            frame = this.evalParams(env, {frames: mixinFrames}, args, _arguments), 
+            context, rules, start, ruleset;
+
+        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
+
+        rules = important ?
+            this.parent.makeImportant.apply(this).rules : this.rules.slice(0);
+
+        ruleset = new(tree.Ruleset)(null, rules).eval({
+            frames: [this, frame].concat(mixinFrames)
+        });
+        ruleset.originalRuleset = this;
+        return ruleset;
+    },
+    matchCondition: function (args, env) {
+        if (this.condition && !this.condition.eval({
+            frames: [this.evalParams(env, {frames: this.frames.concat(env.frames)}, args, [])].concat(env.frames)
+        }))                                                           { return false }
+        return true;
+    },
+    matchArgs: function (args, env) {
+        var argsLength = (args && args.length) || 0, len, frame;
+
+        if (! this.variadic) {
+            if (argsLength < this.required)                               { return false }
+            if (argsLength > this.params.length)                          { return false }
+            if ((this.required > 0) && (argsLength > this.params.length)) { return false }
+        }
+
+        len = Math.min(argsLength, this.arity);
+
+        for (var i = 0; i < len; i++) {
+            if (!this.params[i].name && !this.params[i].variadic) {
+                if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/operation.js b/util/less/lib/less/tree/operation.js
new file mode 100644
index 0000000..3c4f093
--- /dev/null
+++ b/util/less/lib/less/tree/operation.js
@@ -0,0 +1,37 @@
+(function (tree) {
+
+tree.Operation = function (op, operands) {
+    this.op = op.trim();
+    this.operands = operands;
+};
+tree.Operation.prototype.eval = function (env) {
+    var a = this.operands[0].eval(env),
+        b = this.operands[1].eval(env),
+        temp;
+
+    if (a instanceof tree.Dimension && b instanceof tree.Color) {
+        if (this.op === '*' || this.op === '+') {
+            temp = b, b = a, a = temp;
+        } else {
+            throw { name: "OperationError",
+                    message: "Can't substract or divide a color from a number" };
+        }
+    }
+    if (!a.operate) {
+        throw { name: "OperationError",
+                message: "Operation on an invalid type" };
+    }
+
+    return a.operate(this.op, b);
+};
+
+tree.operate = function (op, a, b) {
+    switch (op) {
+        case '+': return a + b;
+        case '-': return a - b;
+        case '*': return a * b;
+        case '/': return a / b;
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/paren.js b/util/less/lib/less/tree/paren.js
new file mode 100644
index 0000000..384a43c
--- /dev/null
+++ b/util/less/lib/less/tree/paren.js
@@ -0,0 +1,16 @@
+
+(function (tree) {
+
+tree.Paren = function (node) {
+    this.value = node;
+};
+tree.Paren.prototype = {
+    toCSS: function (env) {
+        return '(' + this.value.toCSS(env) + ')';
+    },
+    eval: function (env) {
+        return new(tree.Paren)(this.value.eval(env));
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/quoted.js b/util/less/lib/less/tree/quoted.js
new file mode 100644
index 0000000..4ec6713
--- /dev/null
+++ b/util/less/lib/less/tree/quoted.js
@@ -0,0 +1,43 @@
+(function (tree) {
+
+tree.Quoted = function (str, content, escaped, i) {
+    this.escaped = escaped;
+    this.value = content || '';
+    this.quote = str.charAt(0);
+    this.index = i;
+};
+tree.Quoted.prototype = {
+    toCSS: function () {
+        if (this.escaped) {
+            return this.value;
+        } else {
+            return this.quote + this.value + this.quote;
+        }
+    },
+    eval: function (env) {
+        var that = this;
+        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
+            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
+        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
+            var v = new(tree.Variable)('@' + name, that.index).eval(env);
+            return (v instanceof tree.Quoted) ? v.value : v.toCSS();
+        });
+        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
+    },
+    compare: function (x) {
+        if (!x.toCSS) {
+            return -1;
+        }
+        
+        var left = this.toCSS(),
+            right = x.toCSS();
+        
+        if (left === right) {
+            return 0;
+        }
+        
+        return left < right ? -1 : 1;
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/ratio.js b/util/less/lib/less/tree/ratio.js
new file mode 100644
index 0000000..f7622fb
--- /dev/null
+++ b/util/less/lib/less/tree/ratio.js
@@ -0,0 +1,13 @@
+(function (tree) {
+
+tree.Ratio = function (value) {
+    this.value = value;
+};
+tree.Ratio.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/rule.js b/util/less/lib/less/tree/rule.js
new file mode 100644
index 0000000..8990fef
--- /dev/null
+++ b/util/less/lib/less/tree/rule.js
@@ -0,0 +1,49 @@
+(function (tree) {
+
+tree.Rule = function (name, value, important, index, inline) {
+    this.name = name;
+    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
+    this.important = important ? ' ' + important.trim() : '';
+    this.index = index;
+    this.inline = inline || false;
+
+    if (name.charAt(0) === '@') {
+        this.variable = true;
+    } else { this.variable = false }
+};
+tree.Rule.prototype.toCSS = function (env) {
+    if (this.variable) { return "" }
+    else {
+        return this.name + (env.compress ? ':' : ': ') +
+               this.value.toCSS(env) +
+               this.important + (this.inline ? "" : ";");
+    }
+};
+
+tree.Rule.prototype.eval = function (context) {
+    return new(tree.Rule)(this.name,
+                          this.value.eval(context),
+                          this.important,
+                          this.index, this.inline);
+};
+
+tree.Rule.prototype.makeImportant = function () {
+    return new(tree.Rule)(this.name,
+                          this.value,
+                          "!important",
+                          this.index, this.inline);
+};
+
+tree.Shorthand = function (a, b) {
+    this.a = a;
+    this.b = b;
+};
+
+tree.Shorthand.prototype = {
+    toCSS: function (env) {
+        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/ruleset.js b/util/less/lib/less/tree/ruleset.js
new file mode 100644
index 0000000..a198617
--- /dev/null
+++ b/util/less/lib/less/tree/ruleset.js
@@ -0,0 +1,414 @@
+(function (tree) {
+
+tree.Ruleset = function (selectors, rules, strictImports) {
+    this.selectors = selectors;
+    this.rules = rules;
+    this._lookups = {};
+    this.strictImports = strictImports;
+};
+tree.Ruleset.prototype = {
+    eval: function (env) {
+        var selectors = this.selectors && this.selectors.map(function (s) { return s.eval(env) });
+        var ruleset = new(tree.Ruleset)(selectors, this.rules.slice(0), this.strictImports);
+        var rules;
+        
+        ruleset.originalRuleset = this;
+        ruleset.root = this.root;
+        ruleset.allowImports = this.allowImports;
+
+        if(this.debugInfo) {
+            ruleset.debugInfo = this.debugInfo;
+        }
+
+        // push the current ruleset to the frames stack
+        env.frames.unshift(ruleset);
+
+        // Evaluate imports
+        if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
+            ruleset.evalImports(env);
+        }
+
+        // Store the frames around mixin definitions,
+        // so they can be evaluated like closures when the time comes.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
+                ruleset.rules[i].frames = env.frames.slice(0);
+            }
+        }
+        
+        var mediaBlockCount = (env.mediaBlocks && env.mediaBlocks.length) || 0;
+
+        // Evaluate mixin calls.
+        for (var i = 0; i < ruleset.rules.length; i++) {
+            if (ruleset.rules[i] instanceof tree.mixin.Call) {
+                rules = ruleset.rules[i].eval(env);
+                ruleset.rules.splice.apply(ruleset.rules, [i, 1].concat(rules));
+                i += rules.length-1;
+                ruleset.resetCache();
+            }
+        }
+
+        // Evaluate everything else
+        for (var i = 0, rule; i < ruleset.rules.length; i++) {
+            rule = ruleset.rules[i];
+
+            if (! (rule instanceof tree.mixin.Definition)) {
+                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
+            }
+        }
+
+        // Pop the stack
+        env.frames.shift();
+        
+        if (env.mediaBlocks) {
+            for(var i = mediaBlockCount; i < env.mediaBlocks.length; i++) {
+                env.mediaBlocks[i].bubbleSelectors(selectors);
+            }
+        }
+
+        return ruleset;
+    },
+    evalImports: function(env) {
+        var i, rules;
+        for (i = 0; i < this.rules.length; i++) {
+            if (this.rules[i] instanceof tree.Import) {
+                rules = this.rules[i].eval(env);
+                if (typeof rules.length === "number") {
+                    this.rules.splice.apply(this.rules, [i, 1].concat(rules));
+                    i+= rules.length-1;
+                } else {
+                    this.rules.splice(i, 1, rules);
+                }
+                this.resetCache();
+            }
+        }
+    },
+    makeImportant: function() {
+        return new tree.Ruleset(this.selectors, this.rules.map(function (r) {
+                    if (r.makeImportant) {
+                        return r.makeImportant();
+                    } else {
+                        return r;
+                    }
+                }), this.strictImports);
+    },
+    matchArgs: function (args) {
+        return !args || args.length === 0;
+    },
+    resetCache: function () {
+        this._rulesets = null;
+        this._variables = null;
+        this._lookups = {};
+    },
+    variables: function () {
+        if (this._variables) { return this._variables }
+        else {
+            return this._variables = this.rules.reduce(function (hash, r) {
+                if (r instanceof tree.Rule && r.variable === true) {
+                    hash[r.name] = r;
+                }
+                return hash;
+            }, {});
+        }
+    },
+    variable: function (name) {
+        return this.variables()[name];
+    },
+    rulesets: function () {
+        if (this._rulesets) { return this._rulesets }
+        else {
+            return this._rulesets = this.rules.filter(function (r) {
+                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
+            });
+        }
+    },
+    find: function (selector, self) {
+        self = self || this;
+        var rules = [], rule, match,
+            key = selector.toCSS();
+
+        if (key in this._lookups) { return this._lookups[key] }
+
+        this.rulesets().forEach(function (rule) {
+            if (rule !== self) {
+                for (var j = 0; j < rule.selectors.length; j++) {
+                    if (match = selector.match(rule.selectors[j])) {
+                        if (selector.elements.length > rule.selectors[j].elements.length) {
+                            Array.prototype.push.apply(rules, rule.find(
+                                new(tree.Selector)(selector.elements.slice(1)), self));
+                        } else {
+                            rules.push(rule);
+                        }
+                        break;
+                    }
+                }
+            }
+        });
+        return this._lookups[key] = rules;
+    },
+    //
+    // Entry point for code generation
+    //
+    //     `context` holds an array of arrays.
+    //
+    toCSS: function (context, env) {
+        var css = [],      // The CSS output
+            rules = [],    // node.Rule instances
+           _rules = [],    //
+            rulesets = [], // node.Ruleset instances
+            paths = [],    // Current selectors
+            selector,      // The fully rendered selector
+            debugInfo,     // Line number debugging
+            rule;
+
+        if (! this.root) {
+            this.joinSelectors(paths, context, this.selectors);
+        }
+
+        // Compile rules and rulesets
+        for (var i = 0; i < this.rules.length; i++) {
+            rule = this.rules[i];
+
+            if (rule.rules || (rule instanceof tree.Media)) {
+                rulesets.push(rule.toCSS(paths, env));
+            } else if (rule instanceof tree.Directive) {
+                var cssValue = rule.toCSS(paths, env);
+                // Output only the first @charset definition as such - convert the others
+                // to comments in case debug is enabled
+                if (rule.name === "@charset") {
+                    // Only output the debug info together with subsequent @charset definitions
+                    // a comment (or @media statement) before the actual @charset directive would
+                    // be considered illegal css as it has to be on the first line
+                    if (env.charset) {
+                        if (rule.debugInfo) {
+                            rulesets.push(tree.debugInfo(env, rule));
+                            rulesets.push(new tree.Comment("/* "+cssValue.replace(/\n/g, "")+" */\n").toCSS(env));
+                        }
+                        continue;
+                    }
+                    env.charset = true;
+                }
+                rulesets.push(cssValue);
+            } else if (rule instanceof tree.Comment) {
+                if (!rule.silent) {
+                    if (this.root) {
+                        rulesets.push(rule.toCSS(env));
+                    } else {
+                        rules.push(rule.toCSS(env));
+                    }
+                }
+            } else {
+                if (rule.toCSS && !rule.variable) {
+                    rules.push(rule.toCSS(env));
+                } else if (rule.value && !rule.variable) {
+                    rules.push(rule.value.toString());
+                }
+            }
+        } 
+
+        rulesets = rulesets.join('');
+
+        // If this is the root node, we don't render
+        // a selector, or {}.
+        // Otherwise, only output if this ruleset has rules.
+        if (this.root) {
+            css.push(rules.join(env.compress ? '' : '\n'));
+        } else {
+            if (rules.length > 0) {
+                debugInfo = tree.debugInfo(env, this);
+                selector = paths.map(function (p) {
+                    return p.map(function (s) {
+                        return s.toCSS(env);
+                    }).join('').trim();
+                }).join(env.compress ? ',' : ',\n');
+
+                // Remove duplicates
+                for (var i = rules.length - 1; i >= 0; i--) {
+                    if (_rules.indexOf(rules[i]) === -1) {
+                        _rules.unshift(rules[i]);
+                    }
+                }
+                rules = _rules;
+
+                css.push(debugInfo + selector + 
+                        (env.compress ? '{' : ' {\n  ') +
+                        rules.join(env.compress ? '' : '\n  ') +
+                        (env.compress ? '}' : '\n}\n'));
+            }
+        }
+        css.push(rulesets);
+
+        return css.join('')  + (env.compress ? '\n' : '');
+    },
+
+    joinSelectors: function (paths, context, selectors) {
+        for (var s = 0; s < selectors.length; s++) {
+            this.joinSelector(paths, context, selectors[s]);
+        }
+    },
+
+    joinSelector: function (paths, context, selector) {
+
+        var i, j, k, 
+            hasParentSelector, newSelectors, el, sel, parentSel, 
+            newSelectorPath, afterParentJoin, newJoinedSelector, 
+            newJoinedSelectorEmpty, lastSelector, currentElements,
+            selectorsMultiplied;
+    
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            if (el.value === '&') {
+                hasParentSelector = true;
+            }
+        }
+    
+        if (!hasParentSelector) {
+            if (context.length > 0) {
+                for(i = 0; i < context.length; i++) {
+                    paths.push(context[i].concat(selector));
+                }
+            }
+            else {
+                paths.push([selector]);
+            }
+            return;
+        }
+
+        // The paths are [[Selector]]
+        // The first list is a list of comma seperated selectors
+        // The inner list is a list of inheritance seperated selectors
+        // e.g.
+        // .a, .b {
+        //   .c {
+        //   }
+        // }
+        // == [[.a] [.c]] [[.b] [.c]]
+        //
+
+        // the elements from the current selector so far
+        currentElements = [];
+        // the current list of new selectors to add to the path.
+        // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
+        // by the parents
+        newSelectors = [[]];
+
+        for (i = 0; i < selector.elements.length; i++) {
+            el = selector.elements[i];
+            // non parent reference elements just get added
+            if (el.value !== "&") {
+                currentElements.push(el);
+            } else {
+                // the new list of selectors to add
+                selectorsMultiplied = [];
+
+                // merge the current list of non parent selector elements
+                // on to the current list of selectors to add
+                if (currentElements.length > 0) {
+                    this.mergeElementsOnToSelectors(currentElements, newSelectors);
+                }
+
+                // loop through our current selectors
+                for(j = 0; j < newSelectors.length; j++) {
+                    sel = newSelectors[j];
+                    // if we don't have any parent paths, the & might be in a mixin so that it can be used
+                    // whether there are parents or not
+                    if (context.length == 0) {
+                        // the combinator used on el should now be applied to the next element instead so that
+                        // it is not lost
+                        if (sel.length > 0) {
+                            sel[0].elements = sel[0].elements.slice(0);
+                            sel[0].elements.push(new(tree.Element)(el.combinator, '', 0)); //new Element(el.Combinator,  ""));
+                        }
+                        selectorsMultiplied.push(sel);
+                    }
+                    else {
+                        // and the parent selectors
+                        for(k = 0; k < context.length; k++) {
+                            parentSel = context[k];
+                            // We need to put the current selectors
+                            // then join the last selector's elements on to the parents selectors
+
+                            // our new selector path
+                            newSelectorPath = [];
+                            // selectors from the parent after the join
+                            afterParentJoin = [];
+                            newJoinedSelectorEmpty = true;
+
+                            //construct the joined selector - if & is the first thing this will be empty,
+                            // if not newJoinedSelector will be the last set of elements in the selector
+                            if (sel.length > 0) {
+                                newSelectorPath = sel.slice(0);
+                                lastSelector = newSelectorPath.pop();
+                                newJoinedSelector = new(tree.Selector)(lastSelector.elements.slice(0));
+                                newJoinedSelectorEmpty = false;
+                            }
+                            else {
+                                newJoinedSelector = new(tree.Selector)([]);
+                            }
+
+                            //put together the parent selectors after the join
+                            if (parentSel.length > 1) {
+                                afterParentJoin = afterParentJoin.concat(parentSel.slice(1));
+                            }
+
+                            if (parentSel.length > 0) {
+                                newJoinedSelectorEmpty = false;
+
+                                // join the elements so far with the first part of the parent
+                                newJoinedSelector.elements.push(new(tree.Element)(el.combinator, parentSel[0].elements[0].value, 0));
+                                newJoinedSelector.elements = newJoinedSelector.elements.concat(parentSel[0].elements.slice(1));
+                            }
+
+                            if (!newJoinedSelectorEmpty) {
+                                // now add the joined selector
+                                newSelectorPath.push(newJoinedSelector);
+                            }
+
+                            // and the rest of the parent
+                            newSelectorPath = newSelectorPath.concat(afterParentJoin);
+
+                            // add that to our new set of selectors
+                            selectorsMultiplied.push(newSelectorPath);
+                        }
+                    }
+                }
+
+                // our new selectors has been multiplied, so reset the state
+                newSelectors = selectorsMultiplied;
+                currentElements = [];
+            }
+        }
+
+        // if we have any elements left over (e.g. .a& .b == .b)
+        // add them on to all the current selectors
+        if (currentElements.length > 0) {
+            this.mergeElementsOnToSelectors(currentElements, newSelectors);
+        }
+
+        for(i = 0; i < newSelectors.length; i++) {
+            paths.push(newSelectors[i]);
+        }
+    },
+    
+    mergeElementsOnToSelectors: function(elements, selectors) {
+        var i, sel;
+
+        if (selectors.length == 0) {
+            selectors.push([ new(tree.Selector)(elements) ]);
+            return;
+        }
+
+        for(i = 0; i < selectors.length; i++) {
+            sel = selectors[i];
+
+            // if the previous thing in sel is a parent this needs to join on to it
+            if (sel.length > 0) {
+                sel[sel.length - 1] = new(tree.Selector)(sel[sel.length - 1].elements.concat(elements));
+            }
+            else {
+                sel.push(new(tree.Selector)(elements));
+            }
+        }
+    }
+};
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/selector.js b/util/less/lib/less/tree/selector.js
new file mode 100644
index 0000000..1ce2c30
--- /dev/null
+++ b/util/less/lib/less/tree/selector.js
@@ -0,0 +1,52 @@
+(function (tree) {
+
+tree.Selector = function (elements) {
+    this.elements = elements;
+};
+tree.Selector.prototype.match = function (other) {
+    var elements = this.elements,
+        len = elements.length,
+        oelements, olen, max, i;
+
+    oelements = other.elements.slice(
+        (other.elements.length && other.elements[0].value === "&") ? 1 : 0);
+    olen = oelements.length;
+    max = Math.min(len, olen)
+
+    if (olen === 0 || len < olen) {
+        return false;
+    } else {
+        for (i = 0; i < max; i++) {
+            if (elements[i].value !== oelements[i].value) {
+                return false;
+            }
+        }
+    }
+    return true;
+};
+tree.Selector.prototype.eval = function (env) {
+    return new(tree.Selector)(this.elements.map(function (e) {
+        return e.eval(env);
+    }));
+};
+tree.Selector.prototype.toCSS = function (env) {
+    if (this._css) { return this._css }
+    
+    if (this.elements[0].combinator.value === "") {
+        this._css = ' ';
+    } else {
+        this._css = '';
+    }
+    
+    this._css += this.elements.map(function (e) {
+        if (typeof(e) === 'string') {
+            return ' ' + e.trim();
+        } else {
+            return e.toCSS(env);
+        }
+    }).join('');
+    
+    return this._css;
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/unicode-descriptor.js b/util/less/lib/less/tree/unicode-descriptor.js
new file mode 100644
index 0000000..79b6b23
--- /dev/null
+++ b/util/less/lib/less/tree/unicode-descriptor.js
@@ -0,0 +1,13 @@
+(function (tree) {
+
+tree.UnicodeDescriptor = function (value) {
+    this.value = value;
+};
+tree.UnicodeDescriptor.prototype = {
+    toCSS: function (env) {
+        return this.value;
+    },
+    eval: function () { return this }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/url.js b/util/less/lib/less/tree/url.js
new file mode 100644
index 0000000..e37dbef
--- /dev/null
+++ b/util/less/lib/less/tree/url.js
@@ -0,0 +1,27 @@
+(function (tree) {
+
+tree.URL = function (val, rootpath) {
+    this.value = val;
+    this.rootpath = rootpath;
+};
+tree.URL.prototype = {
+    toCSS: function () {
+        return "url(" + this.value.toCSS() + ")";
+    },
+    eval: function (ctx) {
+        var val = this.value.eval(ctx), rootpath;
+
+        // Add the base path if the URL is relative
+        if (typeof val.value === "string" && !/^(?:[a-z-]+:|\/)/.test(val.value)) {
+            rootpath = this.rootpath;
+            if (!val.quote) {
+                rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\"+match; });
+            }
+            val.value = rootpath + val.value;
+        }
+
+        return new(tree.URL)(val, this.rootpath);
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/value.js b/util/less/lib/less/tree/value.js
new file mode 100644
index 0000000..3c1eb29
--- /dev/null
+++ b/util/less/lib/less/tree/value.js
@@ -0,0 +1,24 @@
+(function (tree) {
+
+tree.Value = function (value) {
+    this.value = value;
+    this.is = 'value';
+};
+tree.Value.prototype = {
+    eval: function (env) {
+        if (this.value.length === 1) {
+            return this.value[0].eval(env);
+        } else {
+            return new(tree.Value)(this.value.map(function (v) {
+                return v.eval(env);
+            }));
+        }
+    },
+    toCSS: function (env) {
+        return this.value.map(function (e) {
+            return e.toCSS(env);
+        }).join(env.compress ? ',' : ', ');
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/lib/less/tree/variable.js b/util/less/lib/less/tree/variable.js
new file mode 100644
index 0000000..674ca8e
--- /dev/null
+++ b/util/less/lib/less/tree/variable.js
@@ -0,0 +1,38 @@
+(function (tree) {
+
+tree.Variable = function (name, index, file) { this.name = name, this.index = index, this.file = file };
+tree.Variable.prototype = {
+    eval: function (env) {
+        var variable, v, name = this.name;
+
+        if (name.indexOf('@@') == 0) {
+            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
+        }
+        
+        if (this.evaluating) {
+            throw { type: 'Name',
+                    message: "Recursive variable definition for " + name,
+                    filename: this.file,
+                    index: this.index };
+        }
+        
+        this.evaluating = true;
+
+        if (variable = tree.find(env.frames, function (frame) {
+            if (v = frame.variable(name)) {
+                return v.value.eval(env);
+            }
+        })) { 
+            this.evaluating = false;
+            return variable;
+        }
+        else {
+            throw { type: 'Name',
+                    message: "variable " + name + " is undefined",
+                    filename: this.file,
+                    index: this.index };
+        }
+    }
+};
+
+})(require('../tree'));
diff --git a/util/less/package.json b/util/less/package.json
new file mode 100644
index 0000000..efc105e
--- /dev/null
+++ b/util/less/package.json
@@ -0,0 +1,23 @@
+{
+  "name"          : "less",
+  "description"   : "Leaner CSS",
+  "homepage"      : "http://lesscss.org",
+  "keywords"      : ["css", "parser", "lesscss", "browser"],
+  "author"        : "Alexis Sellier <self at cloudhead.net>",
+  "contributors"  : [],
+  "version"       : "1.3.3",
+  "bin"           : { "lessc": "./bin/lessc" },
+  "main"          : "./lib/less/index",
+  "directories"   : { "test": "./test" },
+  "engines"       : { "node": ">=0.4.2" },
+  "optionalDependencies" : { "ycssmin": ">=1.0.1" },
+  "devDependencies" : { "diff": "~1.0" },
+  "scripts": {
+   "test": "make test"
+  },
+  "bugs": { "url" : "https://github.com/cloudhead/less.js/issues"},
+  "repository" :
+  { "type" : "git",
+    "url" : "https://github.com/cloudhead/less.js.git"
+  }
+}
diff --git a/util/less/parser.js b/util/less/parser.js
deleted file mode 100755
index 8ca4e61..0000000
--- a/util/less/parser.js
+++ /dev/null
@@ -1,1110 +0,0 @@
-var less, tree;
-
-if (typeof(window) === 'undefined') {
-    less = exports,
-    tree = require('less/tree');
-} else {
-    if (typeof(window.less) === 'undefined') { window.less = {} }
-    less = window.less,
-    tree = window.less.tree = {};
-}
-//
-// less.js - parser
-//
-//    A relatively straight-forward predictive parser.
-//    There is no tokenization/lexing stage, the input is parsed
-//    in one sweep.
-//
-//    To make the parser fast enough to run in the browser, several
-//    optimization had to be made:
-//
-//    - Matching and slicing on a huge input is often cause of slowdowns.
-//      The solution is to chunkify the input into smaller strings.
-//      The chunks are stored in the `chunks` var,
-//      `j` holds the current chunk index, and `current` holds
-//      the index of the current chunk in relation to `input`.
-//      This gives us an almost 4x speed-up.
-//
-//    - In many cases, we don't need to match individual tokens;
-//      for example, if a value doesn't hold any variables, operations
-//      or dynamic references, the parser can effectively 'skip' it,
-//      treating it as a literal.
-//      An example would be '1px solid #000' - which evaluates to itself,
-//      we don't need to know what the individual components are.
-//      The drawback, of course is that you don't get the benefits of
-//      syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
-//      and a smaller speed-up in the code-gen.
-//
-//
-//    Token matching is done with the `$` function, which either takes
-//    a terminal string or regexp, or a non-terminal function to call.
-//    It also takes care of moving all the indices forwards.
-//
-//
-less.Parser = function Parser(env) {
-    var input,       // LeSS input string
-        i,           // current index in `input`
-        j,           // current chunk
-        temp,        // temporarily holds a chunk's state, for backtracking
-        memo,        // temporarily holds `i`, when backtracking
-        furthest,    // furthest index the parser has gone to
-        chunks,      // chunkified input
-        current,     // index of current chunk, in `input`
-        parser;
-
-    var that = this;
-
-    // This function is called after all files
-    // have been imported through `@import`.
-    var finish = function () {};
-
-    var imports = this.imports = {
-        paths: env && env.paths || [],  // Search paths, when importing
-        queue: [],                      // Files which haven't been imported yet
-        files: {},                      // Holds the imported parse trees
-        mime:  env && env.mime,         // MIME type of .less files
-        push: function (path, callback) {
-            var that = this;
-            this.queue.push(path);
-
-            //
-            // Import a file asynchronously
-            //
-            less.Parser.importer(path, this.paths, function (root) {
-                that.queue.splice(that.queue.indexOf(path), 1); // Remove the path from the queue
-                that.files[path] = root;                        // Store the root
-
-                callback(root);
-
-                if (that.queue.length === 0) { finish() }       // Call `finish` if we're done importing
-            }, env);
-        }
-    };
-
-    function save()    { temp = chunks[j], memo = i, current = i }
-    function restore() { chunks[j] = temp, i = memo, current = i }
-
-    function sync() {
-        if (i > current) {
-            chunks[j] = chunks[j].slice(i - current);
-            current = i;
-        }
-    }
-    //
-    // Parse from a token, regexp or string, and move forward if match
-    //
-    function $(tok) {
-        var match, args, length, c, index, endIndex, k, mem;
-
-        //
-        // Non-terminal
-        //
-        if (tok instanceof Function) {
-            return tok.call(parser.parsers);
-        //
-        // Terminal
-        //
-        //     Either match a single character in the input,
-        //     or match a regexp in the current chunk (chunk[j]).
-        //
-        } else if (typeof(tok) === 'string') {
-            match = input.charAt(i) === tok ? tok : null;
-            length = 1;
-            sync ();
-        } else {
-            sync ();
-
-            if (match = tok.exec(chunks[j])) {
-                length = match[0].length;
-            } else {
-                return null;
-            }
-        }
-
-        // The match is confirmed, add the match length to `i`,
-        // and consume any extra white-space characters (' ' || '\n')
-        // which come after that. The reason for this is that LeSS's
-        // grammar is mostly white-space insensitive.
-        //
-        if (match) {
-            mem = i += length;
-            endIndex = i + chunks[j].length - length;
-
-            while (i < endIndex) {
-                c = input.charCodeAt(i);
-                if (! (c === 32 || c === 10 || c === 9)) { break }
-                i++;
-            }
-            chunks[j] = chunks[j].slice(length + (i - mem));
-            current = i;
-
-            if (chunks[j].length === 0 && j < chunks.length - 1) { j++ }
-
-            if(typeof(match) === 'string') {
-                return match;
-            } else {
-                return match.length === 1 ? match[0] : match;
-            }
-        }
-    }
-
-    // Same as $(), but don't change the state of the parser,
-    // just return the match.
-    function peek(tok) {
-        if (typeof(tok) === 'string') {
-            return input.charAt(i) === tok;
-        } else {
-            if (tok.test(chunks[j])) {
-                return true;
-            } else {
-                return false;
-            }
-        }
-    }
-
-    this.env = env = env || {};
-
-    // The optimization level dictates the thoroughness of the parser,
-    // the lower the number, the less nodes it will create in the tree.
-    // This could matter for debugging, or if you want to access
-    // the individual nodes in the tree.
-    this.optimization = ('optimization' in this.env) ? this.env.optimization : 1;
-
-    this.env.filename = this.env.filename || null;
-
-    //
-    // The Parser
-    //
-    return parser = {
-
-        imports: imports,
-        //
-        // Parse an input string into an abstract syntax tree,
-        // call `callback` when done.
-        //
-        parse: function (str, callback) {
-            var root, start, end, zone, line, lines, buff = [], c, error = null;
-
-            i = j = current = furthest = 0;
-            chunks = [];
-            input = str.replace(/\r\n/g, '\n');
-
-            // Split the input into chunks.
-            chunks = (function (chunks) {
-                var j = 0,
-                    skip = /[^"'`\{\}\/\(\)]+/g,
-                    comment = /\/\*(?:[^*]|\*+[^\/*])*\*+\/|\/\/.*/g,
-                    level = 0,
-                    match,
-                    chunk = chunks[0],
-                    inParam,
-                    inString;
-
-                for (var i = 0, c, cc; i < input.length; i++) {
-                    skip.lastIndex = i;
-                    if (match = skip.exec(input)) {
-                        if (match.index === i) {
-                            i += match[0].length;
-                            chunk.push(match[0]);
-                        }
-                    }
-                    c = input.charAt(i);
-                    comment.lastIndex = i;
-
-                    if (!inString && !inParam && c === '/') {
-                        cc = input.charAt(i + 1);
-                        if (cc === '/' || cc === '*') {
-                            if (match = comment.exec(input)) {
-                                if (match.index === i) {
-                                    i += match[0].length;
-                                    chunk.push(match[0]);
-                                    c = input.charAt(i);
-                                }
-                            }
-                        }
-                    }
-
-                    if        (c === '{' && !inString && !inParam) { level ++;
-                        chunk.push(c);
-                    } else if (c === '}' && !inString && !inParam) { level --;
-                        chunk.push(c);
-                        chunks[++j] = chunk = [];
-                    } else if (c === '(' && !inString && !inParam) {
-                        chunk.push(c);
-                        inParam = true;
-                    } else if (c === ')' && !inString && inParam) {
-                        chunk.push(c);
-                        inParam = false;
-                    } else {
-                        if (c === '"' || c === "'" || c === '`') {
-                            if (! inString) {
-                                inString = c;
-                            } else {
-                                inString = inString === c ? false : inString;
-                            }
-                        }
-                        chunk.push(c);
-                    }
-                }
-                if (level > 0) {
-                    throw {
-                        type: 'Syntax',
-                        message: "Missing closing `}`",
-                        filename: env.filename
-                    };
-                }
-
-                return chunks.map(function (c) { return c.join('') });;
-            })([[]]);
-
-            // Start with the primary rule.
-            // The whole syntax tree is held under a Ruleset node,
-            // with the `root` property set to true, so no `{}` are
-            // output. The callback is called when the input is parsed.
-            root = new(tree.Ruleset)([], $(this.parsers.primary));
-            root.root = true;
-
-            root.toCSS = (function (evaluate) {
-                var line, lines, column;
-
-                return function (options, variables) {
-                    var frames = [];
-
-                    options = options || {};
-                    //
-                    // Allows setting variables with a hash, so:
-                    //
-                    //   `{ color: new(tree.Color)('#f01') }` will become:
-                    //
-                    //   new(tree.Rule)('@color',
-                    //     new(tree.Value)([
-                    //       new(tree.Expression)([
-                    //         new(tree.Color)('#f01')
-                    //       ])
-                    //     ])
-                    //   )
-                    //
-                    if (typeof(variables) === 'object' && !Array.isArray(variables)) {
-                        variables = Object.keys(variables).map(function (k) {
-                            var value = variables[k];
-
-                            if (! (value instanceof tree.Value)) {
-                                if (! (value instanceof tree.Expression)) {
-                                    value = new(tree.Expression)([value]);
-                                }
-                                value = new(tree.Value)([value]);
-                            }
-                            return new(tree.Rule)('@' + k, value, false, 0);
-                        });
-                        frames = [new(tree.Ruleset)(null, variables)];
-                    }
-
-                    try {
-                        var css = evaluate.call(this, { frames: frames })
-                                          .toCSS([], { compress: options.compress || false });
-                    } catch (e) {
-                        lines = input.split('\n');
-                        line = getLine(e.index);
-
-                        for (var n = e.index, column = -1;
-                                 n >= 0 && input.charAt(n) !== '\n';
-                                 n--) { column++ }
-
-                        throw {
-                            type: e.type,
-                            message: e.message,
-                            filename: env.filename,
-                            index: e.index,
-                            line: typeof(line) === 'number' ? line + 1 : null,
-                            callLine: e.call && (getLine(e.call) + 1),
-                            callExtract: lines[getLine(e.call)],
-                            stack: e.stack,
-                            column: column,
-                            extract: [
-                                lines[line - 1],
-                                lines[line],
-                                lines[line + 1]
-                            ]
-                        };
-                    }
-                    if (options.compress) {
-                        return css.replace(/(\s)+/g, "$1");
-                    } else {
-                        return css;
-                    }
-
-                    function getLine(index) {
-                        return index ? (input.slice(0, index).match(/\n/g) || "").length : null;
-                    }
-                };
-            })(root.eval);
-
-            // If `i` is smaller than the `input.length - 1`,
-            // it means the parser wasn't able to parse the whole
-            // string, so we've got a parsing error.
-            //
-            // We try to extract a \n delimited string,
-            // showing the line where the parse error occured.
-            // We split it up into two parts (the part which parsed,
-            // and the part which didn't), so we can color them differently.
-            if (i < input.length - 1) {
-                i = furthest;
-                lines = input.split('\n');
-                line = (input.slice(0, i).match(/\n/g) || "").length + 1;
-
-                for (var n = i, column = -1; n >= 0 && input.charAt(n) !== '\n'; n--) { column++ }
-
-                error = {
-                    name: "ParseError",
-                    message: "Syntax Error on line " + line,
-                    index: i,
-                    filename: env.filename,
-                    line: line,
-                    column: column,
-                    extract: [
-                        lines[line - 2],
-                        lines[line - 1],
-                        lines[line]
-                    ]
-                };
-            }
-
-            if (this.imports.queue.length > 0) {
-                finish = function () { callback(error, root) };
-            } else {
-                callback(error, root);
-            }
-        },
-
-        //
-        // Here in, the parsing rules/functions
-        //
-        // The basic structure of the syntax tree generated is as follows:
-        //
-        //   Ruleset ->  Rule -> Value -> Expression -> Entity
-        //
-        // Here's some LESS code:
-        //
-        //    .class {
-        //      color: #fff;
-        //      border: 1px solid #000;
-        //      width: @w + 4px;
-        //      > .child {...}
-        //    }
-        //
-        // And here's what the parse tree might look like:
-        //
-        //     Ruleset (Selector '.class', [
-        //         Rule ("color",  Value ([Expression [Color #fff]]))
-        //         Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
-        //         Rule ("width",  Value ([Expression [Operation "+" [Variable "@w"][Dimension 4px]]]))
-        //         Ruleset (Selector [Element '>', '.child'], [...])
-        //     ])
-        //
-        //  In general, most rules will try to parse a token with the `$()` function, and if the return
-        //  value is truly, will return a new node, of the relevant type. Sometimes, we need to check
-        //  first, before parsing, that's when we use `peek()`.
-        //
-        parsers: {
-            //
-            // The `primary` rule is the *entry* and *exit* point of the parser.
-            // The rules here can appear at any level of the parse tree.
-            //
-            // The recursive nature of the grammar is an interplay between the `block`
-            // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
-            // as represented by this simplified grammar:
-            //
-            //     primary  →  (ruleset | rule)+
-            //     ruleset  →  selector+ block
-            //     block    →  '{' primary '}'
-            //
-            // Only at one point is the primary rule not called from the
-            // block rule: at the root level.
-            //
-            primary: function () {
-                var node, root = [];
-
-                while ((node = $(this.mixin.definition) || $(this.rule)    ||  $(this.ruleset) ||
-                               $(this.mixin.call)       || $(this.comment) ||  $(this.directive))
-                               || $(/^[\s\n]+/)) {
-                    node && root.push(node);
-                }
-                return root;
-            },
-
-            // We create a Comment node for CSS comments `/* */`,
-            // but keep the LeSS comments `//` silent, by just skipping
-            // over them.
-            comment: function () {
-                var comment;
-
-                if (input.charAt(i) !== '/') return;
-
-                if (input.charAt(i + 1) === '/') {
-                    return new(tree.Comment)($(/^\/\/.*/), true);
-                } else if (comment = $(/^\/\*(?:[^*]|\*+[^\/*])*\*+\/\n?/)) {
-                    return new(tree.Comment)(comment);
-                }
-            },
-
-            //
-            // Entities are tokens which can be found inside an Expression
-            //
-            entities: {
-                //
-                // A string, which supports escaping " and '
-                //
-                //     "milky way" 'he\'s the one!'
-                //
-                quoted: function () {
-                    var str, j = i, e;
-
-                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
-                    if (input.charAt(j) !== '"' && input.charAt(j) !== "'") return;
-
-                    e && $('~');
-
-                    if (str = $(/^"((?:[^"\\\r\n]|\\.)*)"|'((?:[^'\\\r\n]|\\.)*)'/)) {
-                        return new(tree.Quoted)(str[0], str[1] || str[2], e);
-                    }
-                },
-
-                //
-                // A catch-all word, such as:
-                //
-                //     black border-collapse
-                //
-                keyword: function () {
-                    var k;
-                    if (k = $(/^[A-Za-z-]+/)) { return new(tree.Keyword)(k) }
-                },
-
-                //
-                // A function call
-                //
-                //     rgb(255, 0, 255)
-                //
-                // We also try to catch IE's `alpha()`, but let the `alpha` parser
-                // deal with the details.
-                //
-                // The arguments are parsed with the `entities.arguments` parser.
-                //
-                call: function () {
-                    var name, args, index = i;
-
-                    if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
-
-                    name = name[1].toLowerCase();
-
-                    if (name === 'url') { return null }
-                    else                { i += name.length }
-
-                    if (name === 'alpha') { return $(this.alpha) }
-
-                    $('('); // Parse the '(' and consume whitespace.
-
-                    args = $(this.entities.arguments);
-
-                    if (! $(')')) return;
-
-                    if (name) { return new(tree.Call)(name, args, index) }
-                },
-                arguments: function () {
-                    var args = [], arg;
-
-                    while (arg = $(this.expression)) {
-                        args.push(arg);
-                        if (! $(',')) { break }
-                    }
-                    return args;
-                },
-                literal: function () {
-                    return $(this.entities.dimension) ||
-                           $(this.entities.color) ||
-                           $(this.entities.quoted);
-                },
-
-                //
-                // Parse url() tokens
-                //
-                // We use a specific rule for urls, because they don't really behave like
-                // standard function calls. The difference is that the argument doesn't have
-                // to be enclosed within a string, so it can't be parsed as an Expression.
-                //
-                url: function () {
-                    var value;
-
-                    if (input.charAt(i) !== 'u' || !$(/^url\(/)) return;
-                    value = $(this.entities.quoted)  || $(this.entities.variable) ||
-                            $(this.entities.dataURI) || $(/^[-\w%@$\/.&=:;#+?~]+/) || "";
-                    if (! $(')')) throw new(Error)("missing closing ) for url()");
-
-                    return new(tree.URL)((value.value || value.data || value instanceof tree.Variable)
-                                        ? value : new(tree.Anonymous)(value), imports.paths);
-                },
-
-                dataURI: function () {
-                    var obj;
-
-                    if ($(/^data:/)) {
-                        obj         = {};
-                        obj.mime    = $(/^[^\/]+\/[^,;)]+/)     || '';
-                        obj.charset = $(/^;\s*charset=[^,;)]+/) || '';
-                        obj.base64  = $(/^;\s*base64/)          || '';
-                        obj.data    = $(/^,\s*[^)]+/);
-
-                        if (obj.data) { return obj }
-                    }
-                },
-
-                //
-                // A Variable entity, such as `@fink`, in
-                //
-                //     width: @fink + 2px
-                //
-                // We use a different parser for variable definitions,
-                // see `parsers.variable`.
-                //
-                variable: function () {
-                    var name, index = i;
-
-                    if (input.charAt(i) === '@' && (name = $(/^@@?[\w-]+/))) {
-                        return new(tree.Variable)(name, index);
-                    }
-                },
-
-                //
-                // A Hexadecimal color
-                //
-                //     #4F3C2F
-                //
-                // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
-                //
-                color: function () {
-                    var rgb;
-
-                    if (input.charAt(i) === '#' && (rgb = $(/^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})/))) {
-                        return new(tree.Color)(rgb[1]);
-                    }
-                },
-
-                //
-                // A Dimension, that is, a number and a unit
-                //
-                //     0.5em 95%
-                //
-                dimension: function () {
-                    var value, c = input.charCodeAt(i);
-                    if ((c > 57 || c < 45) || c === 47) return;
-
-                    if (value = $(/^(-?\d*\.?\d+)(px|%|em|pc|ex|in|deg|s|ms|pt|cm|mm|rad|grad|turn)?/)) {
-                        return new(tree.Dimension)(value[1], value[2]);
-                    }
-                },
-
-                //
-                // JavaScript code to be evaluated
-                //
-                //     `window.location.href`
-                //
-                javascript: function () {
-                    var str, j = i, e;
-
-                    if (input.charAt(j) === '~') { j++, e = true } // Escaped strings
-                    if (input.charAt(j) !== '`') { return }
-
-                    e && $('~');
-
-                    if (str = $(/^`([^`]*)`/)) {
-                        return new(tree.JavaScript)(str[1], i, e);
-                    }
-                }
-            },
-
-            //
-            // The variable part of a variable definition. Used in the `rule` parser
-            //
-            //     @fink:
-            //
-            variable: function () {
-                var name;
-
-                if (input.charAt(i) === '@' && (name = $(/^(@[\w-]+)\s*:/))) { return name[1] }
-            },
-
-            //
-            // A font size/line-height shorthand
-            //
-            //     small/12px
-            //
-            // We need to peek first, or we'll match on keywords and dimensions
-            //
-            shorthand: function () {
-                var a, b;
-
-                if (! peek(/^[@\w.%-]+\/[@\w.-]+/)) return;
-
-                if ((a = $(this.entity)) && $('/') && (b = $(this.entity))) {
-                    return new(tree.Shorthand)(a, b);
-                }
-            },
-
-            //
-            // Mixins
-            //
-            mixin: {
-                //
-                // A Mixin call, with an optional argument list
-                //
-                //     #mixins > .square(#fff);
-                //     .rounded(4px, black);
-                //     .button;
-                //
-                // The `while` loop is there because mixins can be
-                // namespaced, but we only support the child and descendant
-                // selector for now.
-                //
-                call: function () {
-                    var elements = [], e, c, args, index = i, s = input.charAt(i);
-
-                    if (s !== '.' && s !== '#') { return }
-
-                    while (e = $(/^[#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/)) {
-                        elements.push(new(tree.Element)(c, e));
-                        c = $('>');
-                    }
-                    $('(') && (args = $(this.entities.arguments)) && $(')');
-
-                    if (elements.length > 0 && ($(';') || peek('}'))) {
-                        return new(tree.mixin.Call)(elements, args, index);
-                    }
-                },
-
-                //
-                // A Mixin definition, with a list of parameters
-                //
-                //     .rounded (@radius: 2px, @color) {
-                //        ...
-                //     }
-                //
-                // Until we have a finer grained state-machine, we have to
-                // do a look-ahead, to make sure we don't have a mixin call.
-                // See the `rule` function for more information.
-                //
-                // We start by matching `.rounded (`, and then proceed on to
-                // the argument list, which has optional default values.
-                // We store the parameters in `params`, with a `value` key,
-                // if there is a value, such as in the case of `@radius`.
-                //
-                // Once we've got our params list, and a closing `)`, we parse
-                // the `{...}` block.
-                //
-                definition: function () {
-                    var name, params = [], match, ruleset, param, value;
-
-                    if ((input.charAt(i) !== '.' && input.charAt(i) !== '#') ||
-                        peek(/^[^{]*(;|})/)) return;
-
-                    if (match = $(/^([#.](?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+)\s*\(/)) {
-                        name = match[1];
-
-                        while (param = $(this.entities.variable) || $(this.entities.literal)
-                                                                 || $(this.entities.keyword)) {
-                            // Variable
-                            if (param instanceof tree.Variable) {
-                                if ($(':')) {
-                                    if (value = $(this.expression)) {
-                                        params.push({ name: param.name, value: value });
-                                    } else {
-                                        throw new(Error)("Expected value");
-                                    }
-                                } else {
-                                    params.push({ name: param.name });
-                                }
-                            } else {
-                                params.push({ value: param });
-                            }
-                            if (! $(',')) { break }
-                        }
-                        if (! $(')')) throw new(Error)("Expected )");
-
-                        ruleset = $(this.block);
-
-                        if (ruleset) {
-                            return new(tree.mixin.Definition)(name, params, ruleset);
-                        }
-                    }
-                }
-            },
-
-            //
-            // Entities are the smallest recognized token,
-            // and can be found inside a rule's value.
-            //
-            entity: function () {
-                return $(this.entities.literal) || $(this.entities.variable) || $(this.entities.url) ||
-                       $(this.entities.call)    || $(this.entities.keyword)  || $(this.entities.javascript) ||
-                       $(this.comment);
-            },
-
-            //
-            // A Rule terminator. Note that we use `peek()` to check for '}',
-            // because the `block` rule will be expecting it, but we still need to make sure
-            // it's there, if ';' was ommitted.
-            //
-            end: function () {
-                return $(';') || peek('}');
-            },
-
-            //
-            // IE's alpha function
-            //
-            //     alpha(opacity=88)
-            //
-            alpha: function () {
-                var value;
-
-                if (! $(/^\(opacity=/i)) return;
-                if (value = $(/^\d+/) || $(this.entities.variable)) {
-                    if (! $(')')) throw new(Error)("missing closing ) for alpha()");
-                    return new(tree.Alpha)(value);
-                }
-            },
-
-            //
-            // A Selector Element
-            //
-            //     div
-            //     + h1
-            //     #socks
-            //     input[type="text"]
-            //
-            // Elements are the building blocks for Selectors,
-            // they are made out of a `Combinator` (see combinator rule),
-            // and an element name, such as a tag a class, or `*`.
-            //
-            element: function () {
-                var e, t, c;
-
-                c = $(this.combinator);
-                e = $(/^(?:[.#]?|:*)(?:[\w-]|\\(?:[a-fA-F0-9]{1,6} ?|[^a-fA-F0-9]))+/) || $('*') || $(this.attribute) || $(/^\([^)@]+\)/) || $(/^(?:\d*\.)?\d+%/);
-
-                if (e) { return new(tree.Element)(c, e) }
-
-                if (c.value && c.value[0] === '&') {
-                  return new(tree.Element)(c, null);
-                }
-            },
-
-            //
-            // Combinators combine elements together, in a Selector.
-            //
-            // Because our parser isn't white-space sensitive, special care
-            // has to be taken, when parsing the descendant combinator, ` `,
-            // as it's an empty space. We have to check the previous character
-            // in the input, to see if it's a ` ` character. More info on how
-            // we deal with this in *combinator.js*.
-            //
-            combinator: function () {
-                var match, c = input.charAt(i);
-
-                if (c === '>' || c === '+' || c === '~') {
-                    i++;
-                    while (input.charAt(i) === ' ') { i++ }
-                    return new(tree.Combinator)(c);
-                } else if (c === '&') {
-                    match = '&';
-                    i++;
-                    if(input.charAt(i) === ' ') {
-                        match = '& ';
-                    }
-                    while (input.charAt(i) === ' ') { i++ }
-                    return new(tree.Combinator)(match);
-                } else if (c === ':' && input.charAt(i + 1) === ':') {
-                    i += 2;
-                    while (input.charAt(i) === ' ') { i++ }
-                    return new(tree.Combinator)('::');
-                } else if (input.charAt(i - 1) === ' ') {
-                    return new(tree.Combinator)(" ");
-                } else {
-                    return new(tree.Combinator)(null);
-                }
-            },
-
-            //
-            // A CSS Selector
-            //
-            //     .class > div + h1
-            //     li a:hover
-            //
-            // Selectors are made out of one or more Elements, see above.
-            //
-            selector: function () {
-                var sel, e, elements = [], c, match;
-
-                while (e = $(this.element)) {
-                    c = input.charAt(i);
-                    elements.push(e)
-                    if (c === '{' || c === '}' || c === ';' || c === ',') { break }
-                }
-
-                if (elements.length > 0) { return new(tree.Selector)(elements) }
-            },
-            tag: function () {
-                return $(/^[a-zA-Z][a-zA-Z-]*[0-9]?/) || $('*');
-            },
-            attribute: function () {
-                var attr = '', key, val, op;
-
-                if (! $('[')) return;
-
-                if (key = $(/^[a-zA-Z-]+/) || $(this.entities.quoted)) {
-                    if ((op = $(/^[|~*$^]?=/)) &&
-                        (val = $(this.entities.quoted) || $(/^[\w-]+/))) {
-                        attr = [key, op, val.toCSS ? val.toCSS() : val].join('');
-                    } else { attr = key }
-                }
-
-                if (! $(']')) return;
-
-                if (attr) { return "[" + attr + "]" }
-            },
-
-            //
-            // The `block` rule is used by `ruleset` and `mixin.definition`.
-            // It's a wrapper around the `primary` rule, with added `{}`.
-            //
-            block: function () {
-                var content;
-
-                if ($('{') && (content = $(this.primary)) && $('}')) {
-                    return content;
-                }
-            },
-
-            //
-            // div, .class, body > p {...}
-            //
-            ruleset: function () {
-                var selectors = [], s, rules, match;
-                save();
-
-                if (match = /^([.#:% \w-]+)[\s\n]*\{/.exec(chunks[j])) {
-                    i += match[0].length - 1;
-                    selectors = [new(tree.Selector)([new(tree.Element)(null, match[1])])];
-                } else {
-                    while (s = $(this.selector)) {
-                        selectors.push(s);
-                        $(this.comment);
-                        if (! $(',')) { break }
-                        $(this.comment);
-                    }
-                }
-
-                if (selectors.length > 0 && (rules = $(this.block))) {
-                    return new(tree.Ruleset)(selectors, rules);
-                } else {
-                    // Backtrack
-                    furthest = i;
-                    restore();
-                }
-            },
-            rule: function () {
-                var name, value, c = input.charAt(i), important, match;
-                save();
-
-                if (c === '.' || c === '#' || c === '&') { return }
-
-                if (name = $(this.variable) || $(this.property)) {
-                    if ((name.charAt(0) != '@') && (match = /^([^@+\/'"*`(;{}-]*);/.exec(chunks[j]))) {
-                        i += match[0].length - 1;
-                        value = new(tree.Anonymous)(match[1]);
-                    } else if (name === "font") {
-                        value = $(this.font);
-                    } else {
-                        value = $(this.value);
-                    }
-                    important = $(this.important);
-
-                    if (value && $(this.end)) {
-                        return new(tree.Rule)(name, value, important, memo);
-                    } else {
-                        furthest = i;
-                        restore();
-                    }
-                }
-            },
-
-            //
-            // An @import directive
-            //
-            //     @import "lib";
-            //
-            // Depending on our environemnt, importing is done differently:
-            // In the browser, it's an XHR request, in Node, it would be a
-            // file-system operation. The function used for importing is
-            // stored in `import`, which we pass to the Import constructor.
-            //
-            "import": function () {
-                var path;
-                if ($(/^@import\s+/) &&
-                    (path = $(this.entities.quoted) || $(this.entities.url)) &&
-                    $(';')) {
-                    return new(tree.Import)(path, imports);
-                }
-            },
-
-            //
-            // A CSS Directive
-            //
-            //     @charset "utf-8";
-            //
-            directive: function () {
-                var name, value, rules, types;
-
-                if (input.charAt(i) !== '@') return;
-
-                if (value = $(this['import'])) {
-                    return value;
-                } else if (name = $(/^@media|@page/) || $(/^@(?:-webkit-)?keyframes/)) {
-                    types = ($(/^[^{]+/) || '').trim();
-                    if (rules = $(this.block)) {
-                        return new(tree.Directive)(name + " " + types, rules);
-                    }
-                } else if (name = $(/^@[-a-z]+/)) {
-                    if (name === '@font-face') {
-                        if (rules = $(this.block)) {
-                            return new(tree.Directive)(name, rules);
-                        }
-                    } else if ((value = $(this.entity)) && $(';')) {
-                        return new(tree.Directive)(name, value);
-                    }
-                }
-            },
-            font: function () {
-                var value = [], expression = [], weight, shorthand, font, e;
-
-                while (e = $(this.shorthand) || $(this.entity)) {
-                    expression.push(e);
-                }
-                value.push(new(tree.Expression)(expression));
-
-                if ($(',')) {
-                    while (e = $(this.expression)) {
-                        value.push(e);
-                        if (! $(',')) { break }
-                    }
-                }
-                return new(tree.Value)(value);
-            },
-
-            //
-            // A Value is a comma-delimited list of Expressions
-            //
-            //     font-family: Baskerville, Georgia, serif;
-            //
-            // In a Rule, a Value represents everything after the `:`,
-            // and before the `;`.
-            //
-            value: function () {
-                var e, expressions = [], important;
-
-                while (e = $(this.expression)) {
-                    expressions.push(e);
-                    if (! $(',')) { break }
-                }
-
-                if (expressions.length > 0) {
-                    return new(tree.Value)(expressions);
-                }
-            },
-            important: function () {
-                if (input.charAt(i) === '!') {
-                    return $(/^! *important/);
-                }
-            },
-            sub: function () {
-                var e;
-
-                if ($('(') && (e = $(this.expression)) && $(')')) {
-                    return e;
-                }
-            },
-            multiplication: function () {
-                var m, a, op, operation;
-                if (m = $(this.operand)) {
-                    while ((op = ($('/') || $('*'))) && (a = $(this.operand))) {
-                        operation = new(tree.Operation)(op, [operation || m, a]);
-                    }
-                    return operation || m;
-                }
-            },
-            addition: function () {
-                var m, a, op, operation;
-                if (m = $(this.multiplication)) {
-                    while ((op = $(/^[-+]\s+/) || (input.charAt(i - 1) != ' ' && ($('+') || $('-')))) &&
-                           (a = $(this.multiplication))) {
-                        operation = new(tree.Operation)(op, [operation || m, a]);
-                    }
-                    return operation || m;
-                }
-            },
-
-            //
-            // An operand is anything that can be part of an operation,
-            // such as a Color, or a Variable
-            //
-            operand: function () {
-                var negate, p = input.charAt(i + 1);
-
-                if (input.charAt(i) === '-' && (p === '@' || p === '(')) { negate = $('-') }
-                var o = $(this.sub) || $(this.entities.dimension) ||
-                        $(this.entities.color) || $(this.entities.variable) ||
-                        $(this.entities.call);
-                return negate ? new(tree.Operation)('*', [new(tree.Dimension)(-1), o])
-                              : o;
-            },
-
-            //
-            // Expressions either represent mathematical operations,
-            // or white-space delimited Entities.
-            //
-            //     1px solid black
-            //     @var * 2
-            //
-            expression: function () {
-                var e, delim, entities = [], d;
-
-                while (e = $(this.addition) || $(this.entity)) {
-                    entities.push(e);
-                }
-                if (entities.length > 0) {
-                    return new(tree.Expression)(entities);
-                }
-            },
-            property: function () {
-                var name;
-
-                if (name = $(/^(\*?-?[-a-z_0-9]+)\s*:/)) {
-                    return name[1];
-                }
-            }
-        }
-    };
-};
-
-if (typeof(window) !== 'undefined') {
-    //
-    // Used by `@import` directives
-    //
-    less.Parser.importer = function (path, paths, callback, env) {
-        if (path.charAt(0) !== '/' && paths.length > 0) {
-            path = paths[0] + path;
-        }
-        // We pass `true` as 3rd argument, to force the reload of the import.
-        // This is so we can get the syntax tree as opposed to just the CSS output,
-        // as we need this to evaluate the current stylesheet.
-        loadStyleSheet({ href: path, title: path, type: env.mime }, callback, true);
-    };
-}
-
diff --git a/util/less/test/browser-test-prepare.js b/util/less/test/browser-test-prepare.js
new file mode 100644
index 0000000..a1b0e5c
--- /dev/null
+++ b/util/less/test/browser-test-prepare.js
@@ -0,0 +1,29 @@
+var path = require('path'),
+    fs = require('fs'),
+    sys = require('util');
+
+var createTestRunnerPage = function(dir, exclude, testSuiteName, dir2) {
+    var output = '<html><head>\n';
+
+    fs.readdirSync(path.join("test", dir, 'less', dir2 || "")).forEach(function (file) {
+        if (! /\.less/.test(file)) { return; }
+        
+        var name = path.basename(file, '.less'),
+            id = (dir ? dir + '-' : "") + 'less-' + (dir2 ? dir2 + "-" : "") + name;
+        
+        if (exclude && name.match(exclude)) { return; }
+        
+        output += '<link id="original-less:' + id + '" rel="stylesheet/less" type="text/css" href="http://localhost:8081/' + path.join(dir, 'less', dir2 || "", name) + '.less' +'">\n';
+        output += '<link id="expected-less:' + id + '" rel="stylesheet"  type="text/css" href="http://localhost:8081/' + path.join(dir, 'css', dir2 || "", name) + '.css' + '">\n';
+    });
+
+    output += String(fs.readFileSync(path.join('test/browser', 'template.htm'))).replace("{runner-name}", testSuiteName);
+
+    fs.writeFileSync(path.join('test/browser', 'test-runner-'+testSuiteName+'.htm'), output);
+};
+
+createTestRunnerPage("", /javascript|urls/, "main");
+createTestRunnerPage("browser", null, "browser");
+createTestRunnerPage("browser", null, "relative-urls", "relative-urls");
+createTestRunnerPage("browser", null, "rootpath", "rootpath");
+createTestRunnerPage("browser", null, "rootpath-relative", "rootpath-relative");
\ No newline at end of file
diff --git a/util/less/test/browser/common.js b/util/less/test/browser/common.js
new file mode 100644
index 0000000..1c0c0af
--- /dev/null
+++ b/util/less/test/browser/common.js
@@ -0,0 +1,74 @@
+/*if not async then phantomjs fails to run the webserver and the test concurrently*/
+var less = { async: true };
+
+var testLessEqualsInDocument = function() {
+    var links = document.getElementsByTagName('link'),
+        typePattern = /^text\/(x-)?less$/;
+
+    for (var i = 0; i < links.length; i++) {
+        if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
+           (links[i].type.match(typePattern)))) {
+            testSheet(links[i]);
+        }
+    }
+};
+
+var testSheet = function(sheet) {
+    it(sheet.id + " should match the expected output", function() {
+        var lessOutputId =  sheet.id.replace("original-", ""),
+            expectedOutputId = "expected-" + lessOutputId,
+            lessOutput = document.getElementById(lessOutputId).innerText,
+            expectedOutputHref = document.getElementById(expectedOutputId).href,
+            expectedOutput = loadFile(expectedOutputHref);
+
+        waitsFor(function() {
+            return expectedOutput.loaded;
+        }, "failed to load expected outout", 10000);
+        
+        runs(function() {
+            // use sheet to do testing
+            expect(lessOutput).toEqual(expectedOutput.text);
+        });
+    });
+};
+
+var loadFile = function(href) {
+    var request = new XMLHttpRequest(),
+        response = { loaded: false, text: ""};
+    request.open('GET', href, true);
+    request.onload = function(e) {
+        response.text = request.response;
+        response.loaded = true;
+    }
+    request.send();
+    return response;
+};
+
+(function() {
+  var jasmineEnv = jasmine.getEnv();
+  jasmineEnv.updateInterval = 1000;
+
+  var htmlReporter = new jasmine.HtmlReporter();
+
+  jasmineEnv.addReporter(htmlReporter);
+
+  jasmineEnv.specFilter = function(spec) {
+    return htmlReporter.specFilter(spec);
+  };
+
+  var currentWindowOnload = window.onload;
+
+  window.onload = function() {
+    if (currentWindowOnload) {
+      currentWindowOnload();
+    }
+    execJasmine();
+  };
+
+  function execJasmine() {
+    setTimeout(function() {
+        jasmineEnv.execute();
+    }, 3000);
+  }
+
+})();
\ No newline at end of file
diff --git a/util/less/test/browser/css/relative-urls/urls.css b/util/less/test/browser/css/relative-urls/urls.css
new file mode 100644
index 0000000..d0da499
--- /dev/null
+++ b/util/less/test/browser/css/relative-urls/urls.css
@@ -0,0 +1,36 @@
+ at import "http://localhost:8081/browser/less/imports/modify-this.css";
+
+ at import "http://localhost:8081/browser/less/imports/modify-again.css";
+.modify {
+  my-url: url("http://localhost:8081/browser/less/imports/a.png");
+}
+.modify {
+  my-url: url("http://localhost:8081/browser/less/imports/b.png");
+}
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium), url(http://localhost:8081/browser/less/relative-urls/fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(http://localhost:8081/browser/less/relative-urls/images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+.comma-delimited {
+  background: url(http://localhost:8081/browser/less/relative-urls/bg.jpg) no-repeat, url(http://localhost:8081/browser/less/relative-urls/bg.png) repeat-x top left, url(http://localhost:8081/browser/less/relative-urls/bg);
+}
+.values {
+  url: url('http://localhost:8081/browser/less/relative-urls/Trebuchet');
+}
diff --git a/util/less/test/browser/css/rootpath-relative/urls.css b/util/less/test/browser/css/rootpath-relative/urls.css
new file mode 100644
index 0000000..817d581
--- /dev/null
+++ b/util/less/test/browser/css/rootpath-relative/urls.css
@@ -0,0 +1,36 @@
+ at import "https://www.github.com/cloudhead/imports/modify-this.css";
+
+ at import "https://www.github.com/cloudhead/imports/modify-again.css";
+.modify {
+  my-url: url("https://www.github.com/cloudhead/imports/a.png");
+}
+.modify {
+  my-url: url("https://www.github.com/cloudhead/imports/b.png");
+}
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium), url(https://www.github.com/cloudhead/less.js/fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(https://www.github.com/cloudhead/less.js/images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+.comma-delimited {
+  background: url(https://www.github.com/cloudhead/less.js/bg.jpg) no-repeat, url(https://www.github.com/cloudhead/less.js/bg.png) repeat-x top left, url(https://www.github.com/cloudhead/less.js/bg);
+}
+.values {
+  url: url('https://www.github.com/cloudhead/less.js/Trebuchet');
+}
diff --git a/util/less/test/browser/css/rootpath/urls.css b/util/less/test/browser/css/rootpath/urls.css
new file mode 100644
index 0000000..a3ef5d9
--- /dev/null
+++ b/util/less/test/browser/css/rootpath/urls.css
@@ -0,0 +1,36 @@
+ at import "https://www.github.com/modify-this.css";
+
+ at import "https://www.github.com/modify-again.css";
+.modify {
+  my-url: url("https://www.github.com/a.png");
+}
+.modify {
+  my-url: url("https://www.github.com/b.png");
+}
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium), url(https://www.github.com/fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(https://www.github.com/images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+.comma-delimited {
+  background: url(https://www.github.com/bg.jpg) no-repeat, url(https://www.github.com/bg.png) repeat-x top left, url(https://www.github.com/bg);
+}
+.values {
+  url: url('https://www.github.com/Trebuchet');
+}
diff --git a/util/less/test/browser/css/urls.css b/util/less/test/browser/css/urls.css
new file mode 100644
index 0000000..a465aed
--- /dev/null
+++ b/util/less/test/browser/css/urls.css
@@ -0,0 +1,36 @@
+ at import "http://localhost:8081/browser/less/modify-this.css";
+
+ at import "http://localhost:8081/browser/less/modify-again.css";
+.modify {
+  my-url: url("http://localhost:8081/browser/less/a.png");
+}
+.modify {
+  my-url: url("http://localhost:8081/browser/less/b.png");
+}
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium), url(http://localhost:8081/browser/less/fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(http://localhost:8081/browser/less/images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+.comma-delimited {
+  background: url(http://localhost:8081/browser/less/bg.jpg) no-repeat, url(http://localhost:8081/browser/less/bg.png) repeat-x top left, url(http://localhost:8081/browser/less/bg);
+}
+.values {
+  url: url('http://localhost:8081/browser/less/Trebuchet');
+}
diff --git a/util/less/test/browser/jasmine-html.js b/util/less/test/browser/jasmine-html.js
new file mode 100644
index 0000000..543d569
--- /dev/null
+++ b/util/less/test/browser/jasmine-html.js
@@ -0,0 +1,681 @@
+jasmine.HtmlReporterHelpers = {};
+
+jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
+  var el = document.createElement(type);
+
+  for (var i = 2; i < arguments.length; i++) {
+    var child = arguments[i];
+
+    if (typeof child === 'string') {
+      el.appendChild(document.createTextNode(child));
+    } else {
+      if (child) {
+        el.appendChild(child);
+      }
+    }
+  }
+
+  for (var attr in attrs) {
+    if (attr == "className") {
+      el[attr] = attrs[attr];
+    } else {
+      el.setAttribute(attr, attrs[attr]);
+    }
+  }
+
+  return el;
+};
+
+jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
+  var results = child.results();
+  var status = results.passed() ? 'passed' : 'failed';
+  if (results.skipped) {
+    status = 'skipped';
+  }
+
+  return status;
+};
+
+jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
+  var parentDiv = this.dom.summary;
+  var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
+  var parent = child[parentSuite];
+
+  if (parent) {
+    if (typeof this.views.suites[parent.id] == 'undefined') {
+      this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
+    }
+    parentDiv = this.views.suites[parent.id].element;
+  }
+
+  parentDiv.appendChild(childElement);
+};
+
+
+jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
+  for(var fn in jasmine.HtmlReporterHelpers) {
+    ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
+  }
+};
+
+jasmine.HtmlReporter = function(_doc) {
+  var self = this;
+  var doc = _doc || window.document;
+
+  var reporterView;
+
+  var dom = {};
+
+  // Jasmine Reporter Public Interface
+  self.logRunningSpecs = false;
+
+  self.reportRunnerStarting = function(runner) {
+    var specs = runner.specs() || [];
+
+    if (specs.length == 0) {
+      return;
+    }
+
+    createReporterDom(runner.env.versionString());
+    doc.body.appendChild(dom.reporter);
+    setExceptionHandling();
+
+    reporterView = new jasmine.HtmlReporter.ReporterView(dom);
+    reporterView.addSpecs(specs, self.specFilter);
+  };
+
+  self.reportRunnerResults = function(runner) {
+    reporterView && reporterView.complete();
+  };
+
+  self.reportSuiteResults = function(suite) {
+    reporterView.suiteComplete(suite);
+  };
+
+  self.reportSpecStarting = function(spec) {
+    if (self.logRunningSpecs) {
+      self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
+    }
+  };
+
+  self.reportSpecResults = function(spec) {
+    reporterView.specComplete(spec);
+  };
+
+  self.log = function() {
+    var console = jasmine.getGlobal().console;
+    if (console && console.log) {
+      if (console.log.apply) {
+        console.log.apply(console, arguments);
+      } else {
+        console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
+      }
+    }
+  };
+
+  self.specFilter = function(spec) {
+    if (!focusedSpecName()) {
+      return true;
+    }
+
+    return spec.getFullName().indexOf(focusedSpecName()) === 0;
+  };
+
+  return self;
+
+  function focusedSpecName() {
+    var specName;
+
+    (function memoizeFocusedSpec() {
+      if (specName) {
+        return;
+      }
+
+      var paramMap = [];
+      var params = jasmine.HtmlReporter.parameters(doc);
+
+      for (var i = 0; i < params.length; i++) {
+        var p = params[i].split('=');
+        paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
+      }
+
+      specName = paramMap.spec;
+    })();
+
+    return specName;
+  }
+
+  function createReporterDom(version) {
+    dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
+      dom.banner = self.createDom('div', { className: 'banner' },
+        self.createDom('span', { className: 'title' }, "Jasmine "),
+        self.createDom('span', { className: 'version' }, version)),
+
+      dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
+      dom.alert = self.createDom('div', {className: 'alert'},
+        self.createDom('span', { className: 'exceptions' },
+          self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
+          self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
+      dom.results = self.createDom('div', {className: 'results'},
+        dom.summary = self.createDom('div', { className: 'summary' }),
+        dom.details = self.createDom('div', { id: 'details' }))
+    );
+  }
+
+  function noTryCatch() {
+    return window.location.search.match(/catch=false/);
+  }
+
+  function searchWithCatch() {
+    var params = jasmine.HtmlReporter.parameters(window.document);
+    var removed = false;
+    var i = 0;
+
+    while (!removed && i < params.length) {
+      if (params[i].match(/catch=/)) {
+        params.splice(i, 1);
+        removed = true;
+      }
+      i++;
+    }
+    if (jasmine.CATCH_EXCEPTIONS) {
+      params.push("catch=false");
+    }
+
+    return params.join("&");
+  }
+
+  function setExceptionHandling() {
+    var chxCatch = document.getElementById('no_try_catch');
+
+    if (noTryCatch()) {
+      chxCatch.setAttribute('checked', true);
+      jasmine.CATCH_EXCEPTIONS = false;
+    }
+    chxCatch.onclick = function() {
+      window.location.search = searchWithCatch();
+    };
+  }
+};
+jasmine.HtmlReporter.parameters = function(doc) {
+  var paramStr = doc.location.search.substring(1);
+  var params = [];
+
+  if (paramStr.length > 0) {
+    params = paramStr.split('&');
+  }
+  return params;
+}
+jasmine.HtmlReporter.sectionLink = function(sectionName) {
+  var link = '?';
+  var params = [];
+
+  if (sectionName) {
+    params.push('spec=' + encodeURIComponent(sectionName));
+  }
+  if (!jasmine.CATCH_EXCEPTIONS) {
+    params.push("catch=false");
+  }
+  if (params.length > 0) {
+    link += params.join("&");
+  }
+
+  return link;
+};
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
+jasmine.HtmlReporter.ReporterView = function(dom) {
+  this.startedAt = new Date();
+  this.runningSpecCount = 0;
+  this.completeSpecCount = 0;
+  this.passedCount = 0;
+  this.failedCount = 0;
+  this.skippedCount = 0;
+
+  this.createResultsMenu = function() {
+    this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
+      this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
+      ' | ',
+      this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
+
+    this.summaryMenuItem.onclick = function() {
+      dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
+    };
+
+    this.detailsMenuItem.onclick = function() {
+      showDetails();
+    };
+  };
+
+  this.addSpecs = function(specs, specFilter) {
+    this.totalSpecCount = specs.length;
+
+    this.views = {
+      specs: {},
+      suites: {}
+    };
+
+    for (var i = 0; i < specs.length; i++) {
+      var spec = specs[i];
+      this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
+      if (specFilter(spec)) {
+        this.runningSpecCount++;
+      }
+    }
+  };
+
+  this.specComplete = function(spec) {
+    this.completeSpecCount++;
+
+    if (isUndefined(this.views.specs[spec.id])) {
+      this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
+    }
+
+    var specView = this.views.specs[spec.id];
+
+    switch (specView.status()) {
+      case 'passed':
+        this.passedCount++;
+        break;
+
+      case 'failed':
+        this.failedCount++;
+        break;
+
+      case 'skipped':
+        this.skippedCount++;
+        break;
+    }
+
+    specView.refresh();
+    this.refresh();
+  };
+
+  this.suiteComplete = function(suite) {
+    var suiteView = this.views.suites[suite.id];
+    if (isUndefined(suiteView)) {
+      return;
+    }
+    suiteView.refresh();
+  };
+
+  this.refresh = function() {
+
+    if (isUndefined(this.resultsMenu)) {
+      this.createResultsMenu();
+    }
+
+    // currently running UI
+    if (isUndefined(this.runningAlert)) {
+      this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" });
+      dom.alert.appendChild(this.runningAlert);
+    }
+    this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
+
+    // skipped specs UI
+    if (isUndefined(this.skippedAlert)) {
+      this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" });
+    }
+
+    this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
+
+    if (this.skippedCount === 1 && isDefined(dom.alert)) {
+      dom.alert.appendChild(this.skippedAlert);
+    }
+
+    // passing specs UI
+    if (isUndefined(this.passedAlert)) {
+      this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" });
+    }
+    this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
+
+    // failing specs UI
+    if (isUndefined(this.failedAlert)) {
+      this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
+    }
+    this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
+
+    if (this.failedCount === 1 && isDefined(dom.alert)) {
+      dom.alert.appendChild(this.failedAlert);
+      dom.alert.appendChild(this.resultsMenu);
+    }
+
+    // summary info
+    this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
+    this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
+  };
+
+  this.complete = function() {
+    dom.alert.removeChild(this.runningAlert);
+
+    this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
+
+    if (this.failedCount === 0) {
+      dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
+    } else {
+      showDetails();
+    }
+
+    dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
+  };
+
+  return this;
+
+  function showDetails() {
+    if (dom.reporter.className.search(/showDetails/) === -1) {
+      dom.reporter.className += " showDetails";
+    }
+  }
+
+  function isUndefined(obj) {
+    return typeof obj === 'undefined';
+  }
+
+  function isDefined(obj) {
+    return !isUndefined(obj);
+  }
+
+  function specPluralizedFor(count) {
+    var str = count + " spec";
+    if (count > 1) {
+      str += "s"
+    }
+    return str;
+  }
+
+};
+
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
+
+
+jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
+  this.spec = spec;
+  this.dom = dom;
+  this.views = views;
+
+  this.symbol = this.createDom('li', { className: 'pending' });
+  this.dom.symbolSummary.appendChild(this.symbol);
+
+  this.summary = this.createDom('div', { className: 'specSummary' },
+    this.createDom('a', {
+      className: 'description',
+      href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()),
+      title: this.spec.getFullName()
+    }, this.spec.description)
+  );
+
+  this.detail = this.createDom('div', { className: 'specDetail' },
+      this.createDom('a', {
+        className: 'description',
+        href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
+        title: this.spec.getFullName()
+      }, this.spec.getFullName())
+  );
+};
+
+jasmine.HtmlReporter.SpecView.prototype.status = function() {
+  return this.getSpecStatus(this.spec);
+};
+
+jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
+  this.symbol.className = this.status();
+
+  switch (this.status()) {
+    case 'skipped':
+      break;
+
+    case 'passed':
+      this.appendSummaryToSuiteDiv();
+      break;
+
+    case 'failed':
+      this.appendSummaryToSuiteDiv();
+      this.appendFailureDetail();
+      break;
+  }
+};
+
+jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
+  this.summary.className += ' ' + this.status();
+  this.appendToSummary(this.spec, this.summary);
+};
+
+jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
+  this.detail.className += ' ' + this.status();
+
+  var resultItems = this.spec.results().getItems();
+  var messagesDiv = this.createDom('div', { className: 'messages' });
+
+  for (var i = 0; i < resultItems.length; i++) {
+    var result = resultItems[i];
+
+    if (result.type == 'log') {
+      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
+    } else if (result.type == 'expect' && result.passed && !result.passed()) {
+      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
+
+      if (result.trace.stack) {
+        messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
+      }
+    }
+  }
+
+  if (messagesDiv.childNodes.length > 0) {
+    this.detail.appendChild(messagesDiv);
+    this.dom.details.appendChild(this.detail);
+  }
+};
+
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
+  this.suite = suite;
+  this.dom = dom;
+  this.views = views;
+
+  this.element = this.createDom('div', { className: 'suite' },
+    this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)
+  );
+
+  this.appendToSummary(this.suite, this.element);
+};
+
+jasmine.HtmlReporter.SuiteView.prototype.status = function() {
+  return this.getSpecStatus(this.suite);
+};
+
+jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
+  this.element.className += " " + this.status();
+};
+
+jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
+
+/* @deprecated Use jasmine.HtmlReporter instead
+ */
+jasmine.TrivialReporter = function(doc) {
+  this.document = doc || document;
+  this.suiteDivs = {};
+  this.logRunningSpecs = false;
+};
+
+jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
+  var el = document.createElement(type);
+
+  for (var i = 2; i < arguments.length; i++) {
+    var child = arguments[i];
+
+    if (typeof child === 'string') {
+      el.appendChild(document.createTextNode(child));
+    } else {
+      if (child) { el.appendChild(child); }
+    }
+  }
+
+  for (var attr in attrs) {
+    if (attr == "className") {
+      el[attr] = attrs[attr];
+    } else {
+      el.setAttribute(attr, attrs[attr]);
+    }
+  }
+
+  return el;
+};
+
+jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
+  var showPassed, showSkipped;
+
+  this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
+      this.createDom('div', { className: 'banner' },
+        this.createDom('div', { className: 'logo' },
+            this.createDom('span', { className: 'title' }, "Jasmine"),
+            this.createDom('span', { className: 'version' }, runner.env.versionString())),
+        this.createDom('div', { className: 'options' },
+            "Show ",
+            showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
+            this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
+            showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
+            this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
+            )
+          ),
+
+      this.runnerDiv = this.createDom('div', { className: 'runner running' },
+          this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
+          this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
+          this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
+      );
+
+  this.document.body.appendChild(this.outerDiv);
+
+  var suites = runner.suites();
+  for (var i = 0; i < suites.length; i++) {
+    var suite = suites[i];
+    var suiteDiv = this.createDom('div', { className: 'suite' },
+        this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
+        this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
+    this.suiteDivs[suite.id] = suiteDiv;
+    var parentDiv = this.outerDiv;
+    if (suite.parentSuite) {
+      parentDiv = this.suiteDivs[suite.parentSuite.id];
+    }
+    parentDiv.appendChild(suiteDiv);
+  }
+
+  this.startedAt = new Date();
+
+  var self = this;
+  showPassed.onclick = function(evt) {
+    if (showPassed.checked) {
+      self.outerDiv.className += ' show-passed';
+    } else {
+      self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
+    }
+  };
+
+  showSkipped.onclick = function(evt) {
+    if (showSkipped.checked) {
+      self.outerDiv.className += ' show-skipped';
+    } else {
+      self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
+    }
+  };
+};
+
+jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
+  var results = runner.results();
+  var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
+  this.runnerDiv.setAttribute("class", className);
+  //do it twice for IE
+  this.runnerDiv.setAttribute("className", className);
+  var specs = runner.specs();
+  var specCount = 0;
+  for (var i = 0; i < specs.length; i++) {
+    if (this.specFilter(specs[i])) {
+      specCount++;
+    }
+  }
+  var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
+  message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
+  this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
+
+  this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
+};
+
+jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
+  var results = suite.results();
+  var status = results.passed() ? 'passed' : 'failed';
+  if (results.totalCount === 0) { // todo: change this to check results.skipped
+    status = 'skipped';
+  }
+  this.suiteDivs[suite.id].className += " " + status;
+};
+
+jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
+  if (this.logRunningSpecs) {
+    this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
+  }
+};
+
+jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
+  var results = spec.results();
+  var status = results.passed() ? 'passed' : 'failed';
+  if (results.skipped) {
+    status = 'skipped';
+  }
+  var specDiv = this.createDom('div', { className: 'spec '  + status },
+      this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
+      this.createDom('a', {
+        className: 'description',
+        href: '?spec=' + encodeURIComponent(spec.getFullName()),
+        title: spec.getFullName()
+      }, spec.description));
+
+
+  var resultItems = results.getItems();
+  var messagesDiv = this.createDom('div', { className: 'messages' });
+  for (var i = 0; i < resultItems.length; i++) {
+    var result = resultItems[i];
+
+    if (result.type == 'log') {
+      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
+    } else if (result.type == 'expect' && result.passed && !result.passed()) {
+      messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
+
+      if (result.trace.stack) {
+        messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
+      }
+    }
+  }
+
+  if (messagesDiv.childNodes.length > 0) {
+    specDiv.appendChild(messagesDiv);
+  }
+
+  this.suiteDivs[spec.suite.id].appendChild(specDiv);
+};
+
+jasmine.TrivialReporter.prototype.log = function() {
+  var console = jasmine.getGlobal().console;
+  if (console && console.log) {
+    if (console.log.apply) {
+      console.log.apply(console, arguments);
+    } else {
+      console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
+    }
+  }
+};
+
+jasmine.TrivialReporter.prototype.getLocation = function() {
+  return this.document.location;
+};
+
+jasmine.TrivialReporter.prototype.specFilter = function(spec) {
+  var paramMap = {};
+  var params = this.getLocation().search.substring(1).split('&');
+  for (var i = 0; i < params.length; i++) {
+    var p = params[i].split('=');
+    paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
+  }
+
+  if (!paramMap.spec) {
+    return true;
+  }
+  return spec.getFullName().indexOf(paramMap.spec) === 0;
+};
diff --git a/util/less/test/browser/jasmine.css b/util/less/test/browser/jasmine.css
new file mode 100644
index 0000000..8c008dc
--- /dev/null
+++ b/util/less/test/browser/jasmine.css
@@ -0,0 +1,82 @@
+body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
+
+#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
+#HTMLReporter a { text-decoration: none; }
+#HTMLReporter a:hover { text-decoration: underline; }
+#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
+#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
+#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
+#HTMLReporter .version { color: #aaaaaa; }
+#HTMLReporter .banner { margin-top: 14px; }
+#HTMLReporter .duration { color: #aaaaaa; float: right; }
+#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
+#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
+#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
+#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
+#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
+#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
+#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
+#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
+#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
+#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
+#HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
+#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
+#HTMLReporter .runningAlert { background-color: #666666; }
+#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
+#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
+#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
+#HTMLReporter .passingAlert { background-color: #a6b779; }
+#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
+#HTMLReporter .failingAlert { background-color: #cf867e; }
+#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
+#HTMLReporter .results { margin-top: 14px; }
+#HTMLReporter #details { display: none; }
+#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
+#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
+#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
+#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
+#HTMLReporter.showDetails .summary { display: none; }
+#HTMLReporter.showDetails #details { display: block; }
+#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
+#HTMLReporter .summary { margin-top: 14px; }
+#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
+#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
+#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
+#HTMLReporter .description + .suite { margin-top: 0; }
+#HTMLReporter .suite { margin-top: 14px; }
+#HTMLReporter .suite a { color: #333333; }
+#HTMLReporter #details .specDetail { margin-bottom: 28px; }
+#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
+#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
+#HTMLReporter .resultMessage span.result { display: block; }
+#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
+
+#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
+#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
+#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
+#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
+#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
+#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
+#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
+#TrivialReporter .runner.running { background-color: yellow; }
+#TrivialReporter .options { text-align: right; font-size: .8em; }
+#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
+#TrivialReporter .suite .suite { margin: 5px; }
+#TrivialReporter .suite.passed { background-color: #dfd; }
+#TrivialReporter .suite.failed { background-color: #fdd; }
+#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
+#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
+#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
+#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
+#TrivialReporter .spec.skipped { background-color: #bbb; }
+#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
+#TrivialReporter .passed { background-color: #cfc; display: none; }
+#TrivialReporter .failed { background-color: #fbb; }
+#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
+#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
+#TrivialReporter .resultMessage .mismatch { color: black; }
+#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
+#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
+#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
+#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
+#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
diff --git a/util/less/test/browser/jasmine.js b/util/less/test/browser/jasmine.js
new file mode 100644
index 0000000..6b3459b
--- /dev/null
+++ b/util/less/test/browser/jasmine.js
@@ -0,0 +1,2600 @@
+var isCommonJS = typeof window == "undefined" && typeof exports == "object";
+
+/**
+ * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
+ *
+ * @namespace
+ */
+var jasmine = {};
+if (isCommonJS) exports.jasmine = jasmine;
+/**
+ * @private
+ */
+jasmine.unimplementedMethod_ = function() {
+  throw new Error("unimplemented method");
+};
+
+/**
+ * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
+ * a plain old variable and may be redefined by somebody else.
+ *
+ * @private
+ */
+jasmine.undefined = jasmine.___undefined___;
+
+/**
+ * Show diagnostic messages in the console if set to true
+ *
+ */
+jasmine.VERBOSE = false;
+
+/**
+ * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
+ *
+ */
+jasmine.DEFAULT_UPDATE_INTERVAL = 250;
+
+/**
+ * Maximum levels of nesting that will be included when an object is pretty-printed
+ */
+jasmine.MAX_PRETTY_PRINT_DEPTH = 40;
+
+/**
+ * Default timeout interval in milliseconds for waitsFor() blocks.
+ */
+jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
+
+/**
+ * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite.
+ * Set to false to let the exception bubble up in the browser.
+ *
+ */
+jasmine.CATCH_EXCEPTIONS = true;
+
+jasmine.getGlobal = function() {
+  function getGlobal() {
+    return this;
+  }
+
+  return getGlobal();
+};
+
+/**
+ * Allows for bound functions to be compared.  Internal use only.
+ *
+ * @ignore
+ * @private
+ * @param base {Object} bound 'this' for the function
+ * @param name {Function} function to find
+ */
+jasmine.bindOriginal_ = function(base, name) {
+  var original = base[name];
+  if (original.apply) {
+    return function() {
+      return original.apply(base, arguments);
+    };
+  } else {
+    // IE support
+    return jasmine.getGlobal()[name];
+  }
+};
+
+jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
+jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
+jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
+jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
+
+jasmine.MessageResult = function(values) {
+  this.type = 'log';
+  this.values = values;
+  this.trace = new Error(); // todo: test better
+};
+
+jasmine.MessageResult.prototype.toString = function() {
+  var text = "";
+  for (var i = 0; i < this.values.length; i++) {
+    if (i > 0) text += " ";
+    if (jasmine.isString_(this.values[i])) {
+      text += this.values[i];
+    } else {
+      text += jasmine.pp(this.values[i]);
+    }
+  }
+  return text;
+};
+
+jasmine.ExpectationResult = function(params) {
+  this.type = 'expect';
+  this.matcherName = params.matcherName;
+  this.passed_ = params.passed;
+  this.expected = params.expected;
+  this.actual = params.actual;
+  this.message = this.passed_ ? 'Passed.' : params.message;
+
+  var trace = (params.trace || new Error(this.message));
+  this.trace = this.passed_ ? '' : trace;
+};
+
+jasmine.ExpectationResult.prototype.toString = function () {
+  return this.message;
+};
+
+jasmine.ExpectationResult.prototype.passed = function () {
+  return this.passed_;
+};
+
+/**
+ * Getter for the Jasmine environment. Ensures one gets created
+ */
+jasmine.getEnv = function() {
+  var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
+  return env;
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isArray_ = function(value) {
+  return jasmine.isA_("Array", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isString_ = function(value) {
+  return jasmine.isA_("String", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isNumber_ = function(value) {
+  return jasmine.isA_("Number", value);
+};
+
+/**
+ * @ignore
+ * @private
+ * @param {String} typeName
+ * @param value
+ * @returns {Boolean}
+ */
+jasmine.isA_ = function(typeName, value) {
+  return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
+};
+
+/**
+ * Pretty printer for expecations.  Takes any object and turns it into a human-readable string.
+ *
+ * @param value {Object} an object to be outputted
+ * @returns {String}
+ */
+jasmine.pp = function(value) {
+  var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
+  stringPrettyPrinter.format(value);
+  return stringPrettyPrinter.string;
+};
+
+/**
+ * Returns true if the object is a DOM Node.
+ *
+ * @param {Object} obj object to check
+ * @returns {Boolean}
+ */
+jasmine.isDomNode = function(obj) {
+  return obj.nodeType > 0;
+};
+
+/**
+ * Returns a matchable 'generic' object of the class type.  For use in expecations of type when values don't matter.
+ *
+ * @example
+ * // don't care about which function is passed in, as long as it's a function
+ * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
+ *
+ * @param {Class} clazz
+ * @returns matchable object of the type clazz
+ */
+jasmine.any = function(clazz) {
+  return new jasmine.Matchers.Any(clazz);
+};
+
+/**
+ * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
+ * attributes on the object.
+ *
+ * @example
+ * // don't care about any other attributes than foo.
+ * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
+ *
+ * @param sample {Object} sample
+ * @returns matchable object for the sample
+ */
+jasmine.objectContaining = function (sample) {
+    return new jasmine.Matchers.ObjectContaining(sample);
+};
+
+/**
+ * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
+ *
+ * Spies should be created in test setup, before expectations.  They can then be checked, using the standard Jasmine
+ * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
+ *
+ * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
+ *
+ * Spies are torn down at the end of every spec.
+ *
+ * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
+ *
+ * @example
+ * // a stub
+ * var myStub = jasmine.createSpy('myStub');  // can be used anywhere
+ *
+ * // spy example
+ * var foo = {
+ *   not: function(bool) { return !bool; }
+ * }
+ *
+ * // actual foo.not will not be called, execution stops
+ * spyOn(foo, 'not');
+
+ // foo.not spied upon, execution will continue to implementation
+ * spyOn(foo, 'not').andCallThrough();
+ *
+ * // fake example
+ * var foo = {
+ *   not: function(bool) { return !bool; }
+ * }
+ *
+ * // foo.not(val) will return val
+ * spyOn(foo, 'not').andCallFake(function(value) {return value;});
+ *
+ * // mock example
+ * foo.not(7 == 7);
+ * expect(foo.not).toHaveBeenCalled();
+ * expect(foo.not).toHaveBeenCalledWith(true);
+ *
+ * @constructor
+ * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
+ * @param {String} name
+ */
+jasmine.Spy = function(name) {
+  /**
+   * The name of the spy, if provided.
+   */
+  this.identity = name || 'unknown';
+  /**
+   *  Is this Object a spy?
+   */
+  this.isSpy = true;
+  /**
+   * The actual function this spy stubs.
+   */
+  this.plan = function() {
+  };
+  /**
+   * Tracking of the most recent call to the spy.
+   * @example
+   * var mySpy = jasmine.createSpy('foo');
+   * mySpy(1, 2);
+   * mySpy.mostRecentCall.args = [1, 2];
+   */
+  this.mostRecentCall = {};
+
+  /**
+   * Holds arguments for each call to the spy, indexed by call count
+   * @example
+   * var mySpy = jasmine.createSpy('foo');
+   * mySpy(1, 2);
+   * mySpy(7, 8);
+   * mySpy.mostRecentCall.args = [7, 8];
+   * mySpy.argsForCall[0] = [1, 2];
+   * mySpy.argsForCall[1] = [7, 8];
+   */
+  this.argsForCall = [];
+  this.calls = [];
+};
+
+/**
+ * Tells a spy to call through to the actual implemenatation.
+ *
+ * @example
+ * var foo = {
+ *   bar: function() { // do some stuff }
+ * }
+ *
+ * // defining a spy on an existing property: foo.bar
+ * spyOn(foo, 'bar').andCallThrough();
+ */
+jasmine.Spy.prototype.andCallThrough = function() {
+  this.plan = this.originalValue;
+  return this;
+};
+
+/**
+ * For setting the return value of a spy.
+ *
+ * @example
+ * // defining a spy from scratch: foo() returns 'baz'
+ * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
+ *
+ * // defining a spy on an existing property: foo.bar() returns 'baz'
+ * spyOn(foo, 'bar').andReturn('baz');
+ *
+ * @param {Object} value
+ */
+jasmine.Spy.prototype.andReturn = function(value) {
+  this.plan = function() {
+    return value;
+  };
+  return this;
+};
+
+/**
+ * For throwing an exception when a spy is called.
+ *
+ * @example
+ * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
+ * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
+ *
+ * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
+ * spyOn(foo, 'bar').andThrow('baz');
+ *
+ * @param {String} exceptionMsg
+ */
+jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
+  this.plan = function() {
+    throw exceptionMsg;
+  };
+  return this;
+};
+
+/**
+ * Calls an alternate implementation when a spy is called.
+ *
+ * @example
+ * var baz = function() {
+ *   // do some stuff, return something
+ * }
+ * // defining a spy from scratch: foo() calls the function baz
+ * var foo = jasmine.createSpy('spy on foo').andCall(baz);
+ *
+ * // defining a spy on an existing property: foo.bar() calls an anonymnous function
+ * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
+ *
+ * @param {Function} fakeFunc
+ */
+jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
+  this.plan = fakeFunc;
+  return this;
+};
+
+/**
+ * Resets all of a spy's the tracking variables so that it can be used again.
+ *
+ * @example
+ * spyOn(foo, 'bar');
+ *
+ * foo.bar();
+ *
+ * expect(foo.bar.callCount).toEqual(1);
+ *
+ * foo.bar.reset();
+ *
+ * expect(foo.bar.callCount).toEqual(0);
+ */
+jasmine.Spy.prototype.reset = function() {
+  this.wasCalled = false;
+  this.callCount = 0;
+  this.argsForCall = [];
+  this.calls = [];
+  this.mostRecentCall = {};
+};
+
+jasmine.createSpy = function(name) {
+
+  var spyObj = function() {
+    spyObj.wasCalled = true;
+    spyObj.callCount++;
+    var args = jasmine.util.argsToArray(arguments);
+    spyObj.mostRecentCall.object = this;
+    spyObj.mostRecentCall.args = args;
+    spyObj.argsForCall.push(args);
+    spyObj.calls.push({object: this, args: args});
+    return spyObj.plan.apply(this, arguments);
+  };
+
+  var spy = new jasmine.Spy(name);
+
+  for (var prop in spy) {
+    spyObj[prop] = spy[prop];
+  }
+
+  spyObj.reset();
+
+  return spyObj;
+};
+
+/**
+ * Determines whether an object is a spy.
+ *
+ * @param {jasmine.Spy|Object} putativeSpy
+ * @returns {Boolean}
+ */
+jasmine.isSpy = function(putativeSpy) {
+  return putativeSpy && putativeSpy.isSpy;
+};
+
+/**
+ * Creates a more complicated spy: an Object that has every property a function that is a spy.  Used for stubbing something
+ * large in one call.
+ *
+ * @param {String} baseName name of spy class
+ * @param {Array} methodNames array of names of methods to make spies
+ */
+jasmine.createSpyObj = function(baseName, methodNames) {
+  if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
+    throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
+  }
+  var obj = {};
+  for (var i = 0; i < methodNames.length; i++) {
+    obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
+  }
+  return obj;
+};
+
+/**
+ * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
+ *
+ * Be careful not to leave calls to <code>jasmine.log</code> in production code.
+ */
+jasmine.log = function() {
+  var spec = jasmine.getEnv().currentSpec;
+  spec.log.apply(spec, arguments);
+};
+
+/**
+ * Function that installs a spy on an existing object's method name.  Used within a Spec to create a spy.
+ *
+ * @example
+ * // spy example
+ * var foo = {
+ *   not: function(bool) { return !bool; }
+ * }
+ * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
+ *
+ * @see jasmine.createSpy
+ * @param obj
+ * @param methodName
+ * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods
+ */
+var spyOn = function(obj, methodName) {
+  return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
+};
+if (isCommonJS) exports.spyOn = spyOn;
+
+/**
+ * Creates a Jasmine spec that will be added to the current suite.
+ *
+ * // TODO: pending tests
+ *
+ * @example
+ * it('should be true', function() {
+ *   expect(true).toEqual(true);
+ * });
+ *
+ * @param {String} desc description of this specification
+ * @param {Function} func defines the preconditions and expectations of the spec
+ */
+var it = function(desc, func) {
+  return jasmine.getEnv().it(desc, func);
+};
+if (isCommonJS) exports.it = it;
+
+/**
+ * Creates a <em>disabled</em> Jasmine spec.
+ *
+ * A convenience method that allows existing specs to be disabled temporarily during development.
+ *
+ * @param {String} desc description of this specification
+ * @param {Function} func defines the preconditions and expectations of the spec
+ */
+var xit = function(desc, func) {
+  return jasmine.getEnv().xit(desc, func);
+};
+if (isCommonJS) exports.xit = xit;
+
+/**
+ * Starts a chain for a Jasmine expectation.
+ *
+ * It is passed an Object that is the actual value and should chain to one of the many
+ * jasmine.Matchers functions.
+ *
+ * @param {Object} actual Actual value to test against and expected value
+ * @return {jasmine.Matchers}
+ */
+var expect = function(actual) {
+  return jasmine.getEnv().currentSpec.expect(actual);
+};
+if (isCommonJS) exports.expect = expect;
+
+/**
+ * Defines part of a jasmine spec.  Used in cominbination with waits or waitsFor in asynchrnous specs.
+ *
+ * @param {Function} func Function that defines part of a jasmine spec.
+ */
+var runs = function(func) {
+  jasmine.getEnv().currentSpec.runs(func);
+};
+if (isCommonJS) exports.runs = runs;
+
+/**
+ * Waits a fixed time period before moving to the next block.
+ *
+ * @deprecated Use waitsFor() instead
+ * @param {Number} timeout milliseconds to wait
+ */
+var waits = function(timeout) {
+  jasmine.getEnv().currentSpec.waits(timeout);
+};
+if (isCommonJS) exports.waits = waits;
+
+/**
+ * Waits for the latchFunction to return true before proceeding to the next block.
+ *
+ * @param {Function} latchFunction
+ * @param {String} optional_timeoutMessage
+ * @param {Number} optional_timeout
+ */
+var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
+  jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
+};
+if (isCommonJS) exports.waitsFor = waitsFor;
+
+/**
+ * A function that is called before each spec in a suite.
+ *
+ * Used for spec setup, including validating assumptions.
+ *
+ * @param {Function} beforeEachFunction
+ */
+var beforeEach = function(beforeEachFunction) {
+  jasmine.getEnv().beforeEach(beforeEachFunction);
+};
+if (isCommonJS) exports.beforeEach = beforeEach;
+
+/**
+ * A function that is called after each spec in a suite.
+ *
+ * Used for restoring any state that is hijacked during spec execution.
+ *
+ * @param {Function} afterEachFunction
+ */
+var afterEach = function(afterEachFunction) {
+  jasmine.getEnv().afterEach(afterEachFunction);
+};
+if (isCommonJS) exports.afterEach = afterEach;
+
+/**
+ * Defines a suite of specifications.
+ *
+ * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
+ * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
+ * of setup in some tests.
+ *
+ * @example
+ * // TODO: a simple suite
+ *
+ * // TODO: a simple suite with a nested describe block
+ *
+ * @param {String} description A string, usually the class under test.
+ * @param {Function} specDefinitions function that defines several specs.
+ */
+var describe = function(description, specDefinitions) {
+  return jasmine.getEnv().describe(description, specDefinitions);
+};
+if (isCommonJS) exports.describe = describe;
+
+/**
+ * Disables a suite of specifications.  Used to disable some suites in a file, or files, temporarily during development.
+ *
+ * @param {String} description A string, usually the class under test.
+ * @param {Function} specDefinitions function that defines several specs.
+ */
+var xdescribe = function(description, specDefinitions) {
+  return jasmine.getEnv().xdescribe(description, specDefinitions);
+};
+if (isCommonJS) exports.xdescribe = xdescribe;
+
+
+// Provide the XMLHttpRequest class for IE 5.x-6.x:
+jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
+  function tryIt(f) {
+    try {
+      return f();
+    } catch(e) {
+    }
+    return null;
+  }
+
+  var xhr = tryIt(function() {
+    return new ActiveXObject("Msxml2.XMLHTTP.6.0");
+  }) ||
+    tryIt(function() {
+      return new ActiveXObject("Msxml2.XMLHTTP.3.0");
+    }) ||
+    tryIt(function() {
+      return new ActiveXObject("Msxml2.XMLHTTP");
+    }) ||
+    tryIt(function() {
+      return new ActiveXObject("Microsoft.XMLHTTP");
+    });
+
+  if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
+
+  return xhr;
+} : XMLHttpRequest;
+/**
+ * @namespace
+ */
+jasmine.util = {};
+
+/**
+ * Declare that a child class inherit it's prototype from the parent class.
+ *
+ * @private
+ * @param {Function} childClass
+ * @param {Function} parentClass
+ */
+jasmine.util.inherit = function(childClass, parentClass) {
+  /**
+   * @private
+   */
+  var subclass = function() {
+  };
+  subclass.prototype = parentClass.prototype;
+  childClass.prototype = new subclass();
+};
+
+jasmine.util.formatException = function(e) {
+  var lineNumber;
+  if (e.line) {
+    lineNumber = e.line;
+  }
+  else if (e.lineNumber) {
+    lineNumber = e.lineNumber;
+  }
+
+  var file;
+
+  if (e.sourceURL) {
+    file = e.sourceURL;
+  }
+  else if (e.fileName) {
+    file = e.fileName;
+  }
+
+  var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
+
+  if (file && lineNumber) {
+    message += ' in ' + file + ' (line ' + lineNumber + ')';
+  }
+
+  return message;
+};
+
+jasmine.util.htmlEscape = function(str) {
+  if (!str) return str;
+  return str.replace(/&/g, '&')
+    .replace(/</g, '<')
+    .replace(/>/g, '>');
+};
+
+jasmine.util.argsToArray = function(args) {
+  var arrayOfArgs = [];
+  for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
+  return arrayOfArgs;
+};
+
+jasmine.util.extend = function(destination, source) {
+  for (var property in source) destination[property] = source[property];
+  return destination;
+};
+
+/**
+ * Environment for Jasmine
+ *
+ * @constructor
+ */
+jasmine.Env = function() {
+  this.currentSpec = null;
+  this.currentSuite = null;
+  this.currentRunner_ = new jasmine.Runner(this);
+
+  this.reporter = new jasmine.MultiReporter();
+
+  this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
+  this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
+  this.lastUpdate = 0;
+  this.specFilter = function() {
+    return true;
+  };
+
+  this.nextSpecId_ = 0;
+  this.nextSuiteId_ = 0;
+  this.equalityTesters_ = [];
+
+  // wrap matchers
+  this.matchersClass = function() {
+    jasmine.Matchers.apply(this, arguments);
+  };
+  jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
+
+  jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
+};
+
+
+jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
+jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
+jasmine.Env.prototype.setInterval = jasmine.setInterval;
+jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
+
+/**
+ * @returns an object containing jasmine version build info, if set.
+ */
+jasmine.Env.prototype.version = function () {
+  if (jasmine.version_) {
+    return jasmine.version_;
+  } else {
+    throw new Error('Version not set');
+  }
+};
+
+/**
+ * @returns string containing jasmine version build info, if set.
+ */
+jasmine.Env.prototype.versionString = function() {
+  if (!jasmine.version_) {
+    return "version unknown";
+  }
+
+  var version = this.version();
+  var versionString = version.major + "." + version.minor + "." + version.build;
+  if (version.release_candidate) {
+    versionString += ".rc" + version.release_candidate;
+  }
+  versionString += " revision " + version.revision;
+  return versionString;
+};
+
+/**
+ * @returns a sequential integer starting at 0
+ */
+jasmine.Env.prototype.nextSpecId = function () {
+  return this.nextSpecId_++;
+};
+
+/**
+ * @returns a sequential integer starting at 0
+ */
+jasmine.Env.prototype.nextSuiteId = function () {
+  return this.nextSuiteId_++;
+};
+
+/**
+ * Register a reporter to receive status updates from Jasmine.
+ * @param {jasmine.Reporter} reporter An object which will receive status updates.
+ */
+jasmine.Env.prototype.addReporter = function(reporter) {
+  this.reporter.addReporter(reporter);
+};
+
+jasmine.Env.prototype.execute = function() {
+  this.currentRunner_.execute();
+};
+
+jasmine.Env.prototype.describe = function(description, specDefinitions) {
+  var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
+
+  var parentSuite = this.currentSuite;
+  if (parentSuite) {
+    parentSuite.add(suite);
+  } else {
+    this.currentRunner_.add(suite);
+  }
+
+  this.currentSuite = suite;
+
+  var declarationError = null;
+  try {
+    specDefinitions.call(suite);
+  } catch(e) {
+    declarationError = e;
+  }
+
+  if (declarationError) {
+    this.it("encountered a declaration exception", function() {
+      throw declarationError;
+    });
+  }
+
+  this.currentSuite = parentSuite;
+
+  return suite;
+};
+
+jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
+  if (this.currentSuite) {
+    this.currentSuite.beforeEach(beforeEachFunction);
+  } else {
+    this.currentRunner_.beforeEach(beforeEachFunction);
+  }
+};
+
+jasmine.Env.prototype.currentRunner = function () {
+  return this.currentRunner_;
+};
+
+jasmine.Env.prototype.afterEach = function(afterEachFunction) {
+  if (this.currentSuite) {
+    this.currentSuite.afterEach(afterEachFunction);
+  } else {
+    this.currentRunner_.afterEach(afterEachFunction);
+  }
+
+};
+
+jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
+  return {
+    execute: function() {
+    }
+  };
+};
+
+jasmine.Env.prototype.it = function(description, func) {
+  var spec = new jasmine.Spec(this, this.currentSuite, description);
+  this.currentSuite.add(spec);
+  this.currentSpec = spec;
+
+  if (func) {
+    spec.runs(func);
+  }
+
+  return spec;
+};
+
+jasmine.Env.prototype.xit = function(desc, func) {
+  return {
+    id: this.nextSpecId(),
+    runs: function() {
+    }
+  };
+};
+
+jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
+  if (a.source != b.source)
+    mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
+
+  if (a.ignoreCase != b.ignoreCase)
+    mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
+
+  if (a.global != b.global)
+    mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
+
+  if (a.multiline != b.multiline)
+    mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
+
+  if (a.sticky != b.sticky)
+    mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
+
+  return (mismatchValues.length === 0);
+};
+
+jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
+  if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
+    return true;
+  }
+
+  a.__Jasmine_been_here_before__ = b;
+  b.__Jasmine_been_here_before__ = a;
+
+  var hasKey = function(obj, keyName) {
+    return obj !== null && obj[keyName] !== jasmine.undefined;
+  };
+
+  for (var property in b) {
+    if (!hasKey(a, property) && hasKey(b, property)) {
+      mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
+    }
+  }
+  for (property in a) {
+    if (!hasKey(b, property) && hasKey(a, property)) {
+      mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
+    }
+  }
+  for (property in b) {
+    if (property == '__Jasmine_been_here_before__') continue;
+    if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
+      mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
+    }
+  }
+
+  if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
+    mismatchValues.push("arrays were not the same length");
+  }
+
+  delete a.__Jasmine_been_here_before__;
+  delete b.__Jasmine_been_here_before__;
+  return (mismatchKeys.length === 0 && mismatchValues.length === 0);
+};
+
+jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
+  mismatchKeys = mismatchKeys || [];
+  mismatchValues = mismatchValues || [];
+
+  for (var i = 0; i < this.equalityTesters_.length; i++) {
+    var equalityTester = this.equalityTesters_[i];
+    var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
+    if (result !== jasmine.undefined) return result;
+  }
+
+  if (a === b) return true;
+
+  if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
+    return (a == jasmine.undefined && b == jasmine.undefined);
+  }
+
+  if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
+    return a === b;
+  }
+
+  if (a instanceof Date && b instanceof Date) {
+    return a.getTime() == b.getTime();
+  }
+
+  if (a.jasmineMatches) {
+    return a.jasmineMatches(b);
+  }
+
+  if (b.jasmineMatches) {
+    return b.jasmineMatches(a);
+  }
+
+  if (a instanceof jasmine.Matchers.ObjectContaining) {
+    return a.matches(b);
+  }
+
+  if (b instanceof jasmine.Matchers.ObjectContaining) {
+    return b.matches(a);
+  }
+
+  if (jasmine.isString_(a) && jasmine.isString_(b)) {
+    return (a == b);
+  }
+
+  if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
+    return (a == b);
+  }
+
+  if (a instanceof RegExp && b instanceof RegExp) {
+    return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
+  }
+
+  if (typeof a === "object" && typeof b === "object") {
+    return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
+  }
+
+  //Straight check
+  return (a === b);
+};
+
+jasmine.Env.prototype.contains_ = function(haystack, needle) {
+  if (jasmine.isArray_(haystack)) {
+    for (var i = 0; i < haystack.length; i++) {
+      if (this.equals_(haystack[i], needle)) return true;
+    }
+    return false;
+  }
+  return haystack.indexOf(needle) >= 0;
+};
+
+jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
+  this.equalityTesters_.push(equalityTester);
+};
+/** No-op base class for Jasmine reporters.
+ *
+ * @constructor
+ */
+jasmine.Reporter = function() {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.reportSpecResults = function(spec) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.Reporter.prototype.log = function(str) {
+};
+
+/**
+ * Blocks are functions with executable code that make up a spec.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {Function} func
+ * @param {jasmine.Spec} spec
+ */
+jasmine.Block = function(env, func, spec) {
+  this.env = env;
+  this.func = func;
+  this.spec = spec;
+};
+
+jasmine.Block.prototype.execute = function(onComplete) {
+  if (!jasmine.CATCH_EXCEPTIONS) {
+    this.func.apply(this.spec);
+  }
+  else {
+    try {
+      this.func.apply(this.spec);
+    } catch (e) {
+      this.spec.fail(e);
+    }
+  }
+  onComplete();
+};
+/** JavaScript API reporter.
+ *
+ * @constructor
+ */
+jasmine.JsApiReporter = function() {
+  this.started = false;
+  this.finished = false;
+  this.suites_ = [];
+  this.results_ = {};
+};
+
+jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
+  this.started = true;
+  var suites = runner.topLevelSuites();
+  for (var i = 0; i < suites.length; i++) {
+    var suite = suites[i];
+    this.suites_.push(this.summarize_(suite));
+  }
+};
+
+jasmine.JsApiReporter.prototype.suites = function() {
+  return this.suites_;
+};
+
+jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
+  var isSuite = suiteOrSpec instanceof jasmine.Suite;
+  var summary = {
+    id: suiteOrSpec.id,
+    name: suiteOrSpec.description,
+    type: isSuite ? 'suite' : 'spec',
+    children: []
+  };
+  
+  if (isSuite) {
+    var children = suiteOrSpec.children();
+    for (var i = 0; i < children.length; i++) {
+      summary.children.push(this.summarize_(children[i]));
+    }
+  }
+  return summary;
+};
+
+jasmine.JsApiReporter.prototype.results = function() {
+  return this.results_;
+};
+
+jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
+  return this.results_[specId];
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
+  this.finished = true;
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
+  this.results_[spec.id] = {
+    messages: spec.results().getItems(),
+    result: spec.results().failedCount > 0 ? "failed" : "passed"
+  };
+};
+
+//noinspection JSUnusedLocalSymbols
+jasmine.JsApiReporter.prototype.log = function(str) {
+};
+
+jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
+  var results = {};
+  for (var i = 0; i < specIds.length; i++) {
+    var specId = specIds[i];
+    results[specId] = this.summarizeResult_(this.results_[specId]);
+  }
+  return results;
+};
+
+jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
+  var summaryMessages = [];
+  var messagesLength = result.messages.length;
+  for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
+    var resultMessage = result.messages[messageIndex];
+    summaryMessages.push({
+      text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
+      passed: resultMessage.passed ? resultMessage.passed() : true,
+      type: resultMessage.type,
+      message: resultMessage.message,
+      trace: {
+        stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
+      }
+    });
+  }
+
+  return {
+    result : result.result,
+    messages : summaryMessages
+  };
+};
+
+/**
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param actual
+ * @param {jasmine.Spec} spec
+ */
+jasmine.Matchers = function(env, actual, spec, opt_isNot) {
+  this.env = env;
+  this.actual = actual;
+  this.spec = spec;
+  this.isNot = opt_isNot || false;
+  this.reportWasCalled_ = false;
+};
+
+// todo: @deprecated as of Jasmine 0.11, remove soon [xw]
+jasmine.Matchers.pp = function(str) {
+  throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
+};
+
+// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
+jasmine.Matchers.prototype.report = function(result, failing_message, details) {
+  throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
+};
+
+jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
+  for (var methodName in prototype) {
+    if (methodName == 'report') continue;
+    var orig = prototype[methodName];
+    matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
+  }
+};
+
+jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
+  return function() {
+    var matcherArgs = jasmine.util.argsToArray(arguments);
+    var result = matcherFunction.apply(this, arguments);
+
+    if (this.isNot) {
+      result = !result;
+    }
+
+    if (this.reportWasCalled_) return result;
+
+    var message;
+    if (!result) {
+      if (this.message) {
+        message = this.message.apply(this, arguments);
+        if (jasmine.isArray_(message)) {
+          message = message[this.isNot ? 1 : 0];
+        }
+      } else {
+        var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
+        message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;
+        if (matcherArgs.length > 0) {
+          for (var i = 0; i < matcherArgs.length; i++) {
+            if (i > 0) message += ",";
+            message += " " + jasmine.pp(matcherArgs[i]);
+          }
+        }
+        message += ".";
+      }
+    }
+    var expectationResult = new jasmine.ExpectationResult({
+      matcherName: matcherName,
+      passed: result,
+      expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
+      actual: this.actual,
+      message: message
+    });
+    this.spec.addMatcherResult(expectationResult);
+    return jasmine.undefined;
+  };
+};
+
+
+
+
+/**
+ * toBe: compares the actual to the expected using ===
+ * @param expected
+ */
+jasmine.Matchers.prototype.toBe = function(expected) {
+  return this.actual === expected;
+};
+
+/**
+ * toNotBe: compares the actual to the expected using !==
+ * @param expected
+ * @deprecated as of 1.0. Use not.toBe() instead.
+ */
+jasmine.Matchers.prototype.toNotBe = function(expected) {
+  return this.actual !== expected;
+};
+
+/**
+ * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
+ *
+ * @param expected
+ */
+jasmine.Matchers.prototype.toEqual = function(expected) {
+  return this.env.equals_(this.actual, expected);
+};
+
+/**
+ * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
+ * @param expected
+ * @deprecated as of 1.0. Use not.toEqual() instead.
+ */
+jasmine.Matchers.prototype.toNotEqual = function(expected) {
+  return !this.env.equals_(this.actual, expected);
+};
+
+/**
+ * Matcher that compares the actual to the expected using a regular expression.  Constructs a RegExp, so takes
+ * a pattern or a String.
+ *
+ * @param expected
+ */
+jasmine.Matchers.prototype.toMatch = function(expected) {
+  return new RegExp(expected).test(this.actual);
+};
+
+/**
+ * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
+ * @param expected
+ * @deprecated as of 1.0. Use not.toMatch() instead.
+ */
+jasmine.Matchers.prototype.toNotMatch = function(expected) {
+  return !(new RegExp(expected).test(this.actual));
+};
+
+/**
+ * Matcher that compares the actual to jasmine.undefined.
+ */
+jasmine.Matchers.prototype.toBeDefined = function() {
+  return (this.actual !== jasmine.undefined);
+};
+
+/**
+ * Matcher that compares the actual to jasmine.undefined.
+ */
+jasmine.Matchers.prototype.toBeUndefined = function() {
+  return (this.actual === jasmine.undefined);
+};
+
+/**
+ * Matcher that compares the actual to null.
+ */
+jasmine.Matchers.prototype.toBeNull = function() {
+  return (this.actual === null);
+};
+
+/**
+ * Matcher that compares the actual to NaN.
+ */
+jasmine.Matchers.prototype.toBeNaN = function() {
+	this.message = function() {
+		return [ "Expected " + jasmine.pp(this.actual) + " to be NaN." ];
+	};
+
+	return (this.actual !== this.actual);
+};
+
+/**
+ * Matcher that boolean not-nots the actual.
+ */
+jasmine.Matchers.prototype.toBeTruthy = function() {
+  return !!this.actual;
+};
+
+
+/**
+ * Matcher that boolean nots the actual.
+ */
+jasmine.Matchers.prototype.toBeFalsy = function() {
+  return !this.actual;
+};
+
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was called.
+ */
+jasmine.Matchers.prototype.toHaveBeenCalled = function() {
+  if (arguments.length > 0) {
+    throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
+  }
+
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+
+  this.message = function() {
+    return [
+      "Expected spy " + this.actual.identity + " to have been called.",
+      "Expected spy " + this.actual.identity + " not to have been called."
+    ];
+  };
+
+  return this.actual.wasCalled;
+};
+
+/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
+jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was not called.
+ *
+ * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead
+ */
+jasmine.Matchers.prototype.wasNotCalled = function() {
+  if (arguments.length > 0) {
+    throw new Error('wasNotCalled does not take arguments');
+  }
+
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+
+  this.message = function() {
+    return [
+      "Expected spy " + this.actual.identity + " to not have been called.",
+      "Expected spy " + this.actual.identity + " to have been called."
+    ];
+  };
+
+  return !this.actual.wasCalled;
+};
+
+/**
+ * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
+ *
+ * @example
+ *
+ */
+jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
+  var expectedArgs = jasmine.util.argsToArray(arguments);
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+  this.message = function() {
+    var invertedMessage = "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was.";
+    var positiveMessage = "";
+    if (this.actual.callCount === 0) {
+      positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
+    } else {
+      positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '')
+    }
+    return [positiveMessage, invertedMessage];
+  };
+
+  return this.env.contains_(this.actual.argsForCall, expectedArgs);
+};
+
+/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
+jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
+
+/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
+jasmine.Matchers.prototype.wasNotCalledWith = function() {
+  var expectedArgs = jasmine.util.argsToArray(arguments);
+  if (!jasmine.isSpy(this.actual)) {
+    throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
+  }
+
+  this.message = function() {
+    return [
+      "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
+      "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
+    ];
+  };
+
+  return !this.env.contains_(this.actual.argsForCall, expectedArgs);
+};
+
+/**
+ * Matcher that checks that the expected item is an element in the actual Array.
+ *
+ * @param {Object} expected
+ */
+jasmine.Matchers.prototype.toContain = function(expected) {
+  return this.env.contains_(this.actual, expected);
+};
+
+/**
+ * Matcher that checks that the expected item is NOT an element in the actual Array.
+ *
+ * @param {Object} expected
+ * @deprecated as of 1.0. Use not.toContain() instead.
+ */
+jasmine.Matchers.prototype.toNotContain = function(expected) {
+  return !this.env.contains_(this.actual, expected);
+};
+
+jasmine.Matchers.prototype.toBeLessThan = function(expected) {
+  return this.actual < expected;
+};
+
+jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
+  return this.actual > expected;
+};
+
+/**
+ * Matcher that checks that the expected item is equal to the actual item
+ * up to a given level of decimal precision (default 2).
+ *
+ * @param {Number} expected
+ * @param {Number} precision, as number of decimal places
+ */
+jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
+  if (!(precision === 0)) {
+    precision = precision || 2;
+  }
+  return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);
+};
+
+/**
+ * Matcher that checks that the expected exception was thrown by the actual.
+ *
+ * @param {String} [expected]
+ */
+jasmine.Matchers.prototype.toThrow = function(expected) {
+  var result = false;
+  var exception;
+  if (typeof this.actual != 'function') {
+    throw new Error('Actual is not a function');
+  }
+  try {
+    this.actual();
+  } catch (e) {
+    exception = e;
+  }
+  if (exception) {
+    result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
+  }
+
+  var not = this.isNot ? "not " : "";
+
+  this.message = function() {
+    if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
+      return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
+    } else {
+      return "Expected function to throw an exception.";
+    }
+  };
+
+  return result;
+};
+
+jasmine.Matchers.Any = function(expectedClass) {
+  this.expectedClass = expectedClass;
+};
+
+jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
+  if (this.expectedClass == String) {
+    return typeof other == 'string' || other instanceof String;
+  }
+
+  if (this.expectedClass == Number) {
+    return typeof other == 'number' || other instanceof Number;
+  }
+
+  if (this.expectedClass == Function) {
+    return typeof other == 'function' || other instanceof Function;
+  }
+
+  if (this.expectedClass == Object) {
+    return typeof other == 'object';
+  }
+
+  return other instanceof this.expectedClass;
+};
+
+jasmine.Matchers.Any.prototype.jasmineToString = function() {
+  return '<jasmine.any(' + this.expectedClass + ')>';
+};
+
+jasmine.Matchers.ObjectContaining = function (sample) {
+  this.sample = sample;
+};
+
+jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
+  mismatchKeys = mismatchKeys || [];
+  mismatchValues = mismatchValues || [];
+
+  var env = jasmine.getEnv();
+
+  var hasKey = function(obj, keyName) {
+    return obj != null && obj[keyName] !== jasmine.undefined;
+  };
+
+  for (var property in this.sample) {
+    if (!hasKey(other, property) && hasKey(this.sample, property)) {
+      mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
+    }
+    else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
+      mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
+    }
+  }
+
+  return (mismatchKeys.length === 0 && mismatchValues.length === 0);
+};
+
+jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
+  return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
+};
+// Mock setTimeout, clearTimeout
+// Contributed by Pivotal Computer Systems, www.pivotalsf.com
+
+jasmine.FakeTimer = function() {
+  this.reset();
+
+  var self = this;
+  self.setTimeout = function(funcToCall, millis) {
+    self.timeoutsMade++;
+    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
+    return self.timeoutsMade;
+  };
+
+  self.setInterval = function(funcToCall, millis) {
+    self.timeoutsMade++;
+    self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
+    return self.timeoutsMade;
+  };
+
+  self.clearTimeout = function(timeoutKey) {
+    self.scheduledFunctions[timeoutKey] = jasmine.undefined;
+  };
+
+  self.clearInterval = function(timeoutKey) {
+    self.scheduledFunctions[timeoutKey] = jasmine.undefined;
+  };
+
+};
+
+jasmine.FakeTimer.prototype.reset = function() {
+  this.timeoutsMade = 0;
+  this.scheduledFunctions = {};
+  this.nowMillis = 0;
+};
+
+jasmine.FakeTimer.prototype.tick = function(millis) {
+  var oldMillis = this.nowMillis;
+  var newMillis = oldMillis + millis;
+  this.runFunctionsWithinRange(oldMillis, newMillis);
+  this.nowMillis = newMillis;
+};
+
+jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
+  var scheduledFunc;
+  var funcsToRun = [];
+  for (var timeoutKey in this.scheduledFunctions) {
+    scheduledFunc = this.scheduledFunctions[timeoutKey];
+    if (scheduledFunc != jasmine.undefined &&
+        scheduledFunc.runAtMillis >= oldMillis &&
+        scheduledFunc.runAtMillis <= nowMillis) {
+      funcsToRun.push(scheduledFunc);
+      this.scheduledFunctions[timeoutKey] = jasmine.undefined;
+    }
+  }
+
+  if (funcsToRun.length > 0) {
+    funcsToRun.sort(function(a, b) {
+      return a.runAtMillis - b.runAtMillis;
+    });
+    for (var i = 0; i < funcsToRun.length; ++i) {
+      try {
+        var funcToRun = funcsToRun[i];
+        this.nowMillis = funcToRun.runAtMillis;
+        funcToRun.funcToCall();
+        if (funcToRun.recurring) {
+          this.scheduleFunction(funcToRun.timeoutKey,
+              funcToRun.funcToCall,
+              funcToRun.millis,
+              true);
+        }
+      } catch(e) {
+      }
+    }
+    this.runFunctionsWithinRange(oldMillis, nowMillis);
+  }
+};
+
+jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
+  this.scheduledFunctions[timeoutKey] = {
+    runAtMillis: this.nowMillis + millis,
+    funcToCall: funcToCall,
+    recurring: recurring,
+    timeoutKey: timeoutKey,
+    millis: millis
+  };
+};
+
+/**
+ * @namespace
+ */
+jasmine.Clock = {
+  defaultFakeTimer: new jasmine.FakeTimer(),
+
+  reset: function() {
+    jasmine.Clock.assertInstalled();
+    jasmine.Clock.defaultFakeTimer.reset();
+  },
+
+  tick: function(millis) {
+    jasmine.Clock.assertInstalled();
+    jasmine.Clock.defaultFakeTimer.tick(millis);
+  },
+
+  runFunctionsWithinRange: function(oldMillis, nowMillis) {
+    jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
+  },
+
+  scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
+    jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
+  },
+
+  useMock: function() {
+    if (!jasmine.Clock.isInstalled()) {
+      var spec = jasmine.getEnv().currentSpec;
+      spec.after(jasmine.Clock.uninstallMock);
+
+      jasmine.Clock.installMock();
+    }
+  },
+
+  installMock: function() {
+    jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
+  },
+
+  uninstallMock: function() {
+    jasmine.Clock.assertInstalled();
+    jasmine.Clock.installed = jasmine.Clock.real;
+  },
+
+  real: {
+    setTimeout: jasmine.getGlobal().setTimeout,
+    clearTimeout: jasmine.getGlobal().clearTimeout,
+    setInterval: jasmine.getGlobal().setInterval,
+    clearInterval: jasmine.getGlobal().clearInterval
+  },
+
+  assertInstalled: function() {
+    if (!jasmine.Clock.isInstalled()) {
+      throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
+    }
+  },
+
+  isInstalled: function() {
+    return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
+  },
+
+  installed: null
+};
+jasmine.Clock.installed = jasmine.Clock.real;
+
+//else for IE support
+jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
+  if (jasmine.Clock.installed.setTimeout.apply) {
+    return jasmine.Clock.installed.setTimeout.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.setTimeout(funcToCall, millis);
+  }
+};
+
+jasmine.getGlobal().setInterval = function(funcToCall, millis) {
+  if (jasmine.Clock.installed.setInterval.apply) {
+    return jasmine.Clock.installed.setInterval.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.setInterval(funcToCall, millis);
+  }
+};
+
+jasmine.getGlobal().clearTimeout = function(timeoutKey) {
+  if (jasmine.Clock.installed.clearTimeout.apply) {
+    return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.clearTimeout(timeoutKey);
+  }
+};
+
+jasmine.getGlobal().clearInterval = function(timeoutKey) {
+  if (jasmine.Clock.installed.clearTimeout.apply) {
+    return jasmine.Clock.installed.clearInterval.apply(this, arguments);
+  } else {
+    return jasmine.Clock.installed.clearInterval(timeoutKey);
+  }
+};
+
+/**
+ * @constructor
+ */
+jasmine.MultiReporter = function() {
+  this.subReporters_ = [];
+};
+jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
+
+jasmine.MultiReporter.prototype.addReporter = function(reporter) {
+  this.subReporters_.push(reporter);
+};
+
+(function() {
+  var functionNames = [
+    "reportRunnerStarting",
+    "reportRunnerResults",
+    "reportSuiteResults",
+    "reportSpecStarting",
+    "reportSpecResults",
+    "log"
+  ];
+  for (var i = 0; i < functionNames.length; i++) {
+    var functionName = functionNames[i];
+    jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
+      return function() {
+        for (var j = 0; j < this.subReporters_.length; j++) {
+          var subReporter = this.subReporters_[j];
+          if (subReporter[functionName]) {
+            subReporter[functionName].apply(subReporter, arguments);
+          }
+        }
+      };
+    })(functionName);
+  }
+})();
+/**
+ * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
+ *
+ * @constructor
+ */
+jasmine.NestedResults = function() {
+  /**
+   * The total count of results
+   */
+  this.totalCount = 0;
+  /**
+   * Number of passed results
+   */
+  this.passedCount = 0;
+  /**
+   * Number of failed results
+   */
+  this.failedCount = 0;
+  /**
+   * Was this suite/spec skipped?
+   */
+  this.skipped = false;
+  /**
+   * @ignore
+   */
+  this.items_ = [];
+};
+
+/**
+ * Roll up the result counts.
+ *
+ * @param result
+ */
+jasmine.NestedResults.prototype.rollupCounts = function(result) {
+  this.totalCount += result.totalCount;
+  this.passedCount += result.passedCount;
+  this.failedCount += result.failedCount;
+};
+
+/**
+ * Adds a log message.
+ * @param values Array of message parts which will be concatenated later.
+ */
+jasmine.NestedResults.prototype.log = function(values) {
+  this.items_.push(new jasmine.MessageResult(values));
+};
+
+/**
+ * Getter for the results: message & results.
+ */
+jasmine.NestedResults.prototype.getItems = function() {
+  return this.items_;
+};
+
+/**
+ * Adds a result, tracking counts (total, passed, & failed)
+ * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
+ */
+jasmine.NestedResults.prototype.addResult = function(result) {
+  if (result.type != 'log') {
+    if (result.items_) {
+      this.rollupCounts(result);
+    } else {
+      this.totalCount++;
+      if (result.passed()) {
+        this.passedCount++;
+      } else {
+        this.failedCount++;
+      }
+    }
+  }
+  this.items_.push(result);
+};
+
+/**
+ * @returns {Boolean} True if <b>everything</b> below passed
+ */
+jasmine.NestedResults.prototype.passed = function() {
+  return this.passedCount === this.totalCount;
+};
+/**
+ * Base class for pretty printing for expectation results.
+ */
+jasmine.PrettyPrinter = function() {
+  this.ppNestLevel_ = 0;
+};
+
+/**
+ * Formats a value in a nice, human-readable string.
+ *
+ * @param value
+ */
+jasmine.PrettyPrinter.prototype.format = function(value) {
+  this.ppNestLevel_++;
+  try {
+    if (value === jasmine.undefined) {
+      this.emitScalar('undefined');
+    } else if (value === null) {
+      this.emitScalar('null');
+    } else if (value === jasmine.getGlobal()) {
+      this.emitScalar('<global>');
+    } else if (value.jasmineToString) {
+      this.emitScalar(value.jasmineToString());
+    } else if (typeof value === 'string') {
+      this.emitString(value);
+    } else if (jasmine.isSpy(value)) {
+      this.emitScalar("spy on " + value.identity);
+    } else if (value instanceof RegExp) {
+      this.emitScalar(value.toString());
+    } else if (typeof value === 'function') {
+      this.emitScalar('Function');
+    } else if (typeof value.nodeType === 'number') {
+      this.emitScalar('HTMLNode');
+    } else if (value instanceof Date) {
+      this.emitScalar('Date(' + value + ')');
+    } else if (value.__Jasmine_been_here_before__) {
+      this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
+    } else if (jasmine.isArray_(value) || typeof value == 'object') {
+      value.__Jasmine_been_here_before__ = true;
+      if (jasmine.isArray_(value)) {
+        this.emitArray(value);
+      } else {
+        this.emitObject(value);
+      }
+      delete value.__Jasmine_been_here_before__;
+    } else {
+      this.emitScalar(value.toString());
+    }
+  } finally {
+    this.ppNestLevel_--;
+  }
+};
+
+jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
+  for (var property in obj) {
+    if (!obj.hasOwnProperty(property)) continue;
+    if (property == '__Jasmine_been_here_before__') continue;
+    fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && 
+                                         obj.__lookupGetter__(property) !== null) : false);
+  }
+};
+
+jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
+jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
+
+jasmine.StringPrettyPrinter = function() {
+  jasmine.PrettyPrinter.call(this);
+
+  this.string = '';
+};
+jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
+
+jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
+  this.append(value);
+};
+
+jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
+  this.append("'" + value + "'");
+};
+
+jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
+  if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
+    this.append("Array");
+    return;
+  }
+
+  this.append('[ ');
+  for (var i = 0; i < array.length; i++) {
+    if (i > 0) {
+      this.append(', ');
+    }
+    this.format(array[i]);
+  }
+  this.append(' ]');
+};
+
+jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
+  if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
+    this.append("Object");
+    return;
+  }
+
+  var self = this;
+  this.append('{ ');
+  var first = true;
+
+  this.iterateObject(obj, function(property, isGetter) {
+    if (first) {
+      first = false;
+    } else {
+      self.append(', ');
+    }
+
+    self.append(property);
+    self.append(' : ');
+    if (isGetter) {
+      self.append('<getter>');
+    } else {
+      self.format(obj[property]);
+    }
+  });
+
+  this.append(' }');
+};
+
+jasmine.StringPrettyPrinter.prototype.append = function(value) {
+  this.string += value;
+};
+jasmine.Queue = function(env) {
+  this.env = env;
+
+  // parallel to blocks. each true value in this array means the block will
+  // get executed even if we abort
+  this.ensured = [];
+  this.blocks = [];
+  this.running = false;
+  this.index = 0;
+  this.offset = 0;
+  this.abort = false;
+};
+
+jasmine.Queue.prototype.addBefore = function(block, ensure) {
+  if (ensure === jasmine.undefined) {
+    ensure = false;
+  }
+
+  this.blocks.unshift(block);
+  this.ensured.unshift(ensure);
+};
+
+jasmine.Queue.prototype.add = function(block, ensure) {
+  if (ensure === jasmine.undefined) {
+    ensure = false;
+  }
+
+  this.blocks.push(block);
+  this.ensured.push(ensure);
+};
+
+jasmine.Queue.prototype.insertNext = function(block, ensure) {
+  if (ensure === jasmine.undefined) {
+    ensure = false;
+  }
+
+  this.ensured.splice((this.index + this.offset + 1), 0, ensure);
+  this.blocks.splice((this.index + this.offset + 1), 0, block);
+  this.offset++;
+};
+
+jasmine.Queue.prototype.start = function(onComplete) {
+  this.running = true;
+  this.onComplete = onComplete;
+  this.next_();
+};
+
+jasmine.Queue.prototype.isRunning = function() {
+  return this.running;
+};
+
+jasmine.Queue.LOOP_DONT_RECURSE = true;
+
+jasmine.Queue.prototype.next_ = function() {
+  var self = this;
+  var goAgain = true;
+
+  while (goAgain) {
+    goAgain = false;
+    
+    if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) {
+      var calledSynchronously = true;
+      var completedSynchronously = false;
+
+      var onComplete = function () {
+        if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
+          completedSynchronously = true;
+          return;
+        }
+
+        if (self.blocks[self.index].abort) {
+          self.abort = true;
+        }
+
+        self.offset = 0;
+        self.index++;
+
+        var now = new Date().getTime();
+        if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
+          self.env.lastUpdate = now;
+          self.env.setTimeout(function() {
+            self.next_();
+          }, 0);
+        } else {
+          if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
+            goAgain = true;
+          } else {
+            self.next_();
+          }
+        }
+      };
+      self.blocks[self.index].execute(onComplete);
+
+      calledSynchronously = false;
+      if (completedSynchronously) {
+        onComplete();
+      }
+      
+    } else {
+      self.running = false;
+      if (self.onComplete) {
+        self.onComplete();
+      }
+    }
+  }
+};
+
+jasmine.Queue.prototype.results = function() {
+  var results = new jasmine.NestedResults();
+  for (var i = 0; i < this.blocks.length; i++) {
+    if (this.blocks[i].results) {
+      results.addResult(this.blocks[i].results());
+    }
+  }
+  return results;
+};
+
+
+/**
+ * Runner
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ */
+jasmine.Runner = function(env) {
+  var self = this;
+  self.env = env;
+  self.queue = new jasmine.Queue(env);
+  self.before_ = [];
+  self.after_ = [];
+  self.suites_ = [];
+};
+
+jasmine.Runner.prototype.execute = function() {
+  var self = this;
+  if (self.env.reporter.reportRunnerStarting) {
+    self.env.reporter.reportRunnerStarting(this);
+  }
+  self.queue.start(function () {
+    self.finishCallback();
+  });
+};
+
+jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
+  beforeEachFunction.typeName = 'beforeEach';
+  this.before_.splice(0,0,beforeEachFunction);
+};
+
+jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
+  afterEachFunction.typeName = 'afterEach';
+  this.after_.splice(0,0,afterEachFunction);
+};
+
+
+jasmine.Runner.prototype.finishCallback = function() {
+  this.env.reporter.reportRunnerResults(this);
+};
+
+jasmine.Runner.prototype.addSuite = function(suite) {
+  this.suites_.push(suite);
+};
+
+jasmine.Runner.prototype.add = function(block) {
+  if (block instanceof jasmine.Suite) {
+    this.addSuite(block);
+  }
+  this.queue.add(block);
+};
+
+jasmine.Runner.prototype.specs = function () {
+  var suites = this.suites();
+  var specs = [];
+  for (var i = 0; i < suites.length; i++) {
+    specs = specs.concat(suites[i].specs());
+  }
+  return specs;
+};
+
+jasmine.Runner.prototype.suites = function() {
+  return this.suites_;
+};
+
+jasmine.Runner.prototype.topLevelSuites = function() {
+  var topLevelSuites = [];
+  for (var i = 0; i < this.suites_.length; i++) {
+    if (!this.suites_[i].parentSuite) {
+      topLevelSuites.push(this.suites_[i]);
+    }
+  }
+  return topLevelSuites;
+};
+
+jasmine.Runner.prototype.results = function() {
+  return this.queue.results();
+};
+/**
+ * Internal representation of a Jasmine specification, or test.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {jasmine.Suite} suite
+ * @param {String} description
+ */
+jasmine.Spec = function(env, suite, description) {
+  if (!env) {
+    throw new Error('jasmine.Env() required');
+  }
+  if (!suite) {
+    throw new Error('jasmine.Suite() required');
+  }
+  var spec = this;
+  spec.id = env.nextSpecId ? env.nextSpecId() : null;
+  spec.env = env;
+  spec.suite = suite;
+  spec.description = description;
+  spec.queue = new jasmine.Queue(env);
+
+  spec.afterCallbacks = [];
+  spec.spies_ = [];
+
+  spec.results_ = new jasmine.NestedResults();
+  spec.results_.description = description;
+  spec.matchersClass = null;
+};
+
+jasmine.Spec.prototype.getFullName = function() {
+  return this.suite.getFullName() + ' ' + this.description + '.';
+};
+
+
+jasmine.Spec.prototype.results = function() {
+  return this.results_;
+};
+
+/**
+ * All parameters are pretty-printed and concatenated together, then written to the spec's output.
+ *
+ * Be careful not to leave calls to <code>jasmine.log</code> in production code.
+ */
+jasmine.Spec.prototype.log = function() {
+  return this.results_.log(arguments);
+};
+
+jasmine.Spec.prototype.runs = function (func) {
+  var block = new jasmine.Block(this.env, func, this);
+  this.addToQueue(block);
+  return this;
+};
+
+jasmine.Spec.prototype.addToQueue = function (block) {
+  if (this.queue.isRunning()) {
+    this.queue.insertNext(block);
+  } else {
+    this.queue.add(block);
+  }
+};
+
+/**
+ * @param {jasmine.ExpectationResult} result
+ */
+jasmine.Spec.prototype.addMatcherResult = function(result) {
+  this.results_.addResult(result);
+};
+
+jasmine.Spec.prototype.expect = function(actual) {
+  var positive = new (this.getMatchersClass_())(this.env, actual, this);
+  positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
+  return positive;
+};
+
+/**
+ * Waits a fixed time period before moving to the next block.
+ *
+ * @deprecated Use waitsFor() instead
+ * @param {Number} timeout milliseconds to wait
+ */
+jasmine.Spec.prototype.waits = function(timeout) {
+  var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
+  this.addToQueue(waitsFunc);
+  return this;
+};
+
+/**
+ * Waits for the latchFunction to return true before proceeding to the next block.
+ *
+ * @param {Function} latchFunction
+ * @param {String} optional_timeoutMessage
+ * @param {Number} optional_timeout
+ */
+jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
+  var latchFunction_ = null;
+  var optional_timeoutMessage_ = null;
+  var optional_timeout_ = null;
+
+  for (var i = 0; i < arguments.length; i++) {
+    var arg = arguments[i];
+    switch (typeof arg) {
+      case 'function':
+        latchFunction_ = arg;
+        break;
+      case 'string':
+        optional_timeoutMessage_ = arg;
+        break;
+      case 'number':
+        optional_timeout_ = arg;
+        break;
+    }
+  }
+
+  var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
+  this.addToQueue(waitsForFunc);
+  return this;
+};
+
+jasmine.Spec.prototype.fail = function (e) {
+  var expectationResult = new jasmine.ExpectationResult({
+    passed: false,
+    message: e ? jasmine.util.formatException(e) : 'Exception',
+    trace: { stack: e.stack }
+  });
+  this.results_.addResult(expectationResult);
+};
+
+jasmine.Spec.prototype.getMatchersClass_ = function() {
+  return this.matchersClass || this.env.matchersClass;
+};
+
+jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
+  var parent = this.getMatchersClass_();
+  var newMatchersClass = function() {
+    parent.apply(this, arguments);
+  };
+  jasmine.util.inherit(newMatchersClass, parent);
+  jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
+  this.matchersClass = newMatchersClass;
+};
+
+jasmine.Spec.prototype.finishCallback = function() {
+  this.env.reporter.reportSpecResults(this);
+};
+
+jasmine.Spec.prototype.finish = function(onComplete) {
+  this.removeAllSpies();
+  this.finishCallback();
+  if (onComplete) {
+    onComplete();
+  }
+};
+
+jasmine.Spec.prototype.after = function(doAfter) {
+  if (this.queue.isRunning()) {
+    this.queue.add(new jasmine.Block(this.env, doAfter, this), true);
+  } else {
+    this.afterCallbacks.unshift(doAfter);
+  }
+};
+
+jasmine.Spec.prototype.execute = function(onComplete) {
+  var spec = this;
+  if (!spec.env.specFilter(spec)) {
+    spec.results_.skipped = true;
+    spec.finish(onComplete);
+    return;
+  }
+
+  this.env.reporter.reportSpecStarting(this);
+
+  spec.env.currentSpec = spec;
+
+  spec.addBeforesAndAftersToQueue();
+
+  spec.queue.start(function () {
+    spec.finish(onComplete);
+  });
+};
+
+jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
+  var runner = this.env.currentRunner();
+  var i;
+
+  for (var suite = this.suite; suite; suite = suite.parentSuite) {
+    for (i = 0; i < suite.before_.length; i++) {
+      this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
+    }
+  }
+  for (i = 0; i < runner.before_.length; i++) {
+    this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
+  }
+  for (i = 0; i < this.afterCallbacks.length; i++) {
+    this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true);
+  }
+  for (suite = this.suite; suite; suite = suite.parentSuite) {
+    for (i = 0; i < suite.after_.length; i++) {
+      this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true);
+    }
+  }
+  for (i = 0; i < runner.after_.length; i++) {
+    this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);
+  }
+};
+
+jasmine.Spec.prototype.explodes = function() {
+  throw 'explodes function should not have been called';
+};
+
+jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
+  if (obj == jasmine.undefined) {
+    throw "spyOn could not find an object to spy upon for " + methodName + "()";
+  }
+
+  if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
+    throw methodName + '() method does not exist';
+  }
+
+  if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
+    throw new Error(methodName + ' has already been spied upon');
+  }
+
+  var spyObj = jasmine.createSpy(methodName);
+
+  this.spies_.push(spyObj);
+  spyObj.baseObj = obj;
+  spyObj.methodName = methodName;
+  spyObj.originalValue = obj[methodName];
+
+  obj[methodName] = spyObj;
+
+  return spyObj;
+};
+
+jasmine.Spec.prototype.removeAllSpies = function() {
+  for (var i = 0; i < this.spies_.length; i++) {
+    var spy = this.spies_[i];
+    spy.baseObj[spy.methodName] = spy.originalValue;
+  }
+  this.spies_ = [];
+};
+
+/**
+ * Internal representation of a Jasmine suite.
+ *
+ * @constructor
+ * @param {jasmine.Env} env
+ * @param {String} description
+ * @param {Function} specDefinitions
+ * @param {jasmine.Suite} parentSuite
+ */
+jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
+  var self = this;
+  self.id = env.nextSuiteId ? env.nextSuiteId() : null;
+  self.description = description;
+  self.queue = new jasmine.Queue(env);
+  self.parentSuite = parentSuite;
+  self.env = env;
+  self.before_ = [];
+  self.after_ = [];
+  self.children_ = [];
+  self.suites_ = [];
+  self.specs_ = [];
+};
+
+jasmine.Suite.prototype.getFullName = function() {
+  var fullName = this.description;
+  for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
+    fullName = parentSuite.description + ' ' + fullName;
+  }
+  return fullName;
+};
+
+jasmine.Suite.prototype.finish = function(onComplete) {
+  this.env.reporter.reportSuiteResults(this);
+  this.finished = true;
+  if (typeof(onComplete) == 'function') {
+    onComplete();
+  }
+};
+
+jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
+  beforeEachFunction.typeName = 'beforeEach';
+  this.before_.unshift(beforeEachFunction);
+};
+
+jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
+  afterEachFunction.typeName = 'afterEach';
+  this.after_.unshift(afterEachFunction);
+};
+
+jasmine.Suite.prototype.results = function() {
+  return this.queue.results();
+};
+
+jasmine.Suite.prototype.add = function(suiteOrSpec) {
+  this.children_.push(suiteOrSpec);
+  if (suiteOrSpec instanceof jasmine.Suite) {
+    this.suites_.push(suiteOrSpec);
+    this.env.currentRunner().addSuite(suiteOrSpec);
+  } else {
+    this.specs_.push(suiteOrSpec);
+  }
+  this.queue.add(suiteOrSpec);
+};
+
+jasmine.Suite.prototype.specs = function() {
+  return this.specs_;
+};
+
+jasmine.Suite.prototype.suites = function() {
+  return this.suites_;
+};
+
+jasmine.Suite.prototype.children = function() {
+  return this.children_;
+};
+
+jasmine.Suite.prototype.execute = function(onComplete) {
+  var self = this;
+  this.queue.start(function () {
+    self.finish(onComplete);
+  });
+};
+jasmine.WaitsBlock = function(env, timeout, spec) {
+  this.timeout = timeout;
+  jasmine.Block.call(this, env, null, spec);
+};
+
+jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
+
+jasmine.WaitsBlock.prototype.execute = function (onComplete) {
+  if (jasmine.VERBOSE) {
+    this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
+  }
+  this.env.setTimeout(function () {
+    onComplete();
+  }, this.timeout);
+};
+/**
+ * A block which waits for some condition to become true, with timeout.
+ *
+ * @constructor
+ * @extends jasmine.Block
+ * @param {jasmine.Env} env The Jasmine environment.
+ * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
+ * @param {Function} latchFunction A function which returns true when the desired condition has been met.
+ * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
+ * @param {jasmine.Spec} spec The Jasmine spec.
+ */
+jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
+  this.timeout = timeout || env.defaultTimeoutInterval;
+  this.latchFunction = latchFunction;
+  this.message = message;
+  this.totalTimeSpentWaitingForLatch = 0;
+  jasmine.Block.call(this, env, null, spec);
+};
+jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
+
+jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
+
+jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
+  if (jasmine.VERBOSE) {
+    this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
+  }
+  var latchFunctionResult;
+  try {
+    latchFunctionResult = this.latchFunction.apply(this.spec);
+  } catch (e) {
+    this.spec.fail(e);
+    onComplete();
+    return;
+  }
+
+  if (latchFunctionResult) {
+    onComplete();
+  } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
+    var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
+    this.spec.fail({
+      name: 'timeout',
+      message: message
+    });
+
+    this.abort = true;
+    onComplete();
+  } else {
+    this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
+    var self = this;
+    this.env.setTimeout(function() {
+      self.execute(onComplete);
+    }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
+  }
+};
+
+jasmine.version_= {
+  "major": 1,
+  "minor": 3,
+  "build": 1,
+  "revision": 1354556913
+};
diff --git a/util/less/test/browser/less/imports/urls.less b/util/less/test/browser/less/imports/urls.less
new file mode 100644
index 0000000..290e6b4
--- /dev/null
+++ b/util/less/test/browser/less/imports/urls.less
@@ -0,0 +1,4 @@
+ at import "modify-this.css";
+.modify {
+  my-url: url("a.png");
+}
\ No newline at end of file
diff --git a/util/less/test/browser/less/imports/urls2.less b/util/less/test/browser/less/imports/urls2.less
new file mode 100644
index 0000000..b834bb9
--- /dev/null
+++ b/util/less/test/browser/less/imports/urls2.less
@@ -0,0 +1,4 @@
+ at import "modify-again.css";
+.modify {
+  my-url: url("b.png");
+}
\ No newline at end of file
diff --git a/util/less/test/browser/less/relative-urls/urls.less b/util/less/test/browser/less/relative-urls/urls.less
new file mode 100644
index 0000000..1c5ac88
--- /dev/null
+++ b/util/less/test/browser/less/relative-urls/urls.less
@@ -0,0 +1,33 @@
+ at import "../imports/urls.less";
+ at import "http://localhost:8081/browser/less/imports/urls2.less";
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium),
+       url(fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+
+.comma-delimited {
+  background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+}
+.values {
+    @a: 'Trebuchet';
+    url: url(@a);
+}
diff --git a/util/less/test/browser/less/rootpath-relative/urls.less b/util/less/test/browser/less/rootpath-relative/urls.less
new file mode 100644
index 0000000..1c5ac88
--- /dev/null
+++ b/util/less/test/browser/less/rootpath-relative/urls.less
@@ -0,0 +1,33 @@
+ at import "../imports/urls.less";
+ at import "http://localhost:8081/browser/less/imports/urls2.less";
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium),
+       url(fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+
+.comma-delimited {
+  background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+}
+.values {
+    @a: 'Trebuchet';
+    url: url(@a);
+}
diff --git a/util/less/test/browser/less/rootpath/urls.less b/util/less/test/browser/less/rootpath/urls.less
new file mode 100644
index 0000000..1c5ac88
--- /dev/null
+++ b/util/less/test/browser/less/rootpath/urls.less
@@ -0,0 +1,33 @@
+ at import "../imports/urls.less";
+ at import "http://localhost:8081/browser/less/imports/urls2.less";
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium),
+       url(fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+
+.comma-delimited {
+  background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+}
+.values {
+    @a: 'Trebuchet';
+    url: url(@a);
+}
diff --git a/util/less/test/browser/less/urls.less b/util/less/test/browser/less/urls.less
new file mode 100644
index 0000000..c2040cf
--- /dev/null
+++ b/util/less/test/browser/less/urls.less
@@ -0,0 +1,33 @@
+ at import "imports/urls.less";
+ at import "http://localhost:8081/browser/less/imports/urls2.less";
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium),
+       url(fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+
+.comma-delimited {
+  background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+}
+.values {
+    @a: 'Trebuchet';
+    url: url(@a);
+}
diff --git a/util/less/test/browser/phantom-runner.js b/util/less/test/browser/phantom-runner.js
new file mode 100644
index 0000000..477411b
--- /dev/null
+++ b/util/less/test/browser/phantom-runner.js
@@ -0,0 +1,139 @@
+var webpage = require('webpage');
+var server = require('webserver').create();
+var system = require('system');
+var fs = require('fs');
+var host, port = 8081;
+
+var listening = server.listen(port, function (request, response) {
+    //console.log("Requested "+request.url);
+    
+    var filename = ("test/" + request.url.slice(1)).replace(/[\\\/]/g, fs.separator);
+    
+    if (!fs.exists(filename) || !fs.isFile(filename)) {
+        response.statusCode = 404;
+        response.write("<html><head></head><body><h1>File Not Found</h1><h2>File:"+filename+"</h2></body></html>");
+        response.close();
+        return;
+    }
+
+    // we set the headers here
+    response.statusCode = 200;
+    response.headers = {"Cache": "no-cache", "Content-Type": "text/html"};
+   
+    response.write(fs.read(filename));
+    
+    response.close();
+});
+if (!listening) {
+    console.log("could not create web server listening on port " + port);
+    phantom.exit();
+}
+
+/**
+ * Wait until the test condition is true or a timeout occurs. Useful for waiting
+ * on a server response or for a ui change (fadeIn, etc.) to occur.
+ *
+ * @param testFx javascript condition that evaluates to a boolean,
+ * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
+ * as a callback function.
+ * @param onReady what to do when testFx condition is fulfilled,
+ * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
+ * as a callback function.
+ * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
+ */
+function waitFor(testFx, onReady, timeOutMillis) {
+    var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 10001, //< Default Max Timeout is 10s
+        start = new Date().getTime(),
+        condition = false,
+        interval = setInterval(function() {
+            if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
+                // If not time-out yet and condition not yet fulfilled
+                condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code
+            } else {
+                if(!condition) {
+                    // If condition still not fulfilled (timeout but condition is 'false')
+                    console.log("'waitFor()' timeout");
+                    phantom.exit(1);
+                } else {
+                    // Condition fulfilled (timeout and/or condition is 'true')
+                    //console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
+                    typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
+                    clearInterval(interval); //< Stop this interval
+                }
+            }
+        }, 100); //< repeat check every 100ms
+};
+
+function testPage(url) {
+    var page = webpage.create();
+    page.open(url, function (status) {
+        if (status !== "success") {
+            console.log("Unable to access network - " + status);
+            phantom.exit();
+        } else {
+            waitFor(function(){
+                return page.evaluate(function(){
+                    return document.body && document.body.querySelector && 
+                        document.body.querySelector('.symbolSummary .pending') === null &&
+                        document.body.querySelector('.results') !== null;
+                });
+            }, function(){
+                page.onConsoleMessage = function (msg) {
+                    console.log(msg);
+                };
+                var exitCode = page.evaluate(function(){
+                    console.log('');
+                    console.log(document.body.querySelector('.description').innerText);
+                    var list = document.body.querySelectorAll('.results > #details > .specDetail.failed');
+                    if (list && list.length > 0) {
+                      console.log('');
+                      console.log(list.length + ' test(s) FAILED:');
+                      for (i = 0; i < list.length; ++i) {
+                          var el = list[i],
+                              desc = el.querySelector('.description'),
+                              msg = el.querySelector('.resultMessage.fail');
+                          console.log('');
+                          console.log(desc.innerText);
+                          console.log(msg.innerText);
+                          console.log('');
+                      }
+                      return 1;
+                    } else {
+                      console.log(document.body.querySelector('.alert > .passingAlert.bar').innerText);
+                      return 0;
+                    }
+                });
+                testFinished(exitCode);
+            });
+        }
+    });
+}
+
+function scanDirectory(path, regex) {
+    var files = [];
+    fs.list(path).forEach(function (file) {
+        if (file.match(regex)) {
+            files.push(file);
+        }
+    });
+    return files;
+};
+
+var totalTests = 0,
+    totalFailed = 0,
+    totalDone = 0;
+
+function testFinished(failed) {
+    if (failed) { totalFailed++; }
+    totalDone++;
+    if (totalDone === totalTests) { phantom.exit(totalFailed > 0 ? 1 : 0); }
+}
+
+if (system.args.length != 2 && system.args[1] != "--no-tests") {
+    var files = scanDirectory("test/browser/", /^test-runner-.+\.htm$/);
+    totalTests = files.length;
+    console.log("found " + files.length + " tests");
+    files.forEach(function(file) {
+        testPage("http://localhost:8081/browser/" + file);
+        });
+}
\ No newline at end of file
diff --git a/util/less/test/browser/runner-browser.js b/util/less/test/browser/runner-browser.js
new file mode 100644
index 0000000..54419da
--- /dev/null
+++ b/util/less/test/browser/runner-browser.js
@@ -0,0 +1,3 @@
+describe("less.js browser tests", function() {
+    testLessEqualsInDocument();
+});
\ No newline at end of file
diff --git a/util/less/test/browser/runner-main.js b/util/less/test/browser/runner-main.js
new file mode 100644
index 0000000..d9637c0
--- /dev/null
+++ b/util/less/test/browser/runner-main.js
@@ -0,0 +1,15 @@
+less.functions = {
+    add: function (a, b) {
+        return new(less.tree.Dimension)(a.value + b.value);
+    },
+    increment: function (a) {
+        return new(less.tree.Dimension)(a.value + 1);
+    },
+    _color: function (str) {
+        if (str.value === "evil red") { return new(less.tree.Color)("600") }
+    }
+};
+
+describe("less.js main tests", function() {
+    testLessEqualsInDocument();
+});
\ No newline at end of file
diff --git a/util/less/test/browser/runner-relative-urls.js b/util/less/test/browser/runner-relative-urls.js
new file mode 100644
index 0000000..4e47f63
--- /dev/null
+++ b/util/less/test/browser/runner-relative-urls.js
@@ -0,0 +1,4 @@
+less.relativeUrls = true;
+describe("less.js browser test - relative url's", function() {
+    testLessEqualsInDocument();
+});
\ No newline at end of file
diff --git a/util/less/test/browser/runner-rootpath-relative.js b/util/less/test/browser/runner-rootpath-relative.js
new file mode 100644
index 0000000..b318b42
--- /dev/null
+++ b/util/less/test/browser/runner-rootpath-relative.js
@@ -0,0 +1,5 @@
+less.rootpath = "https://www.github.com/cloudhead/less.js/";
+less.relativeUrls = true;
+describe("less.js browser test - rootpath and relative url's", function() {
+    testLessEqualsInDocument();
+});
\ No newline at end of file
diff --git a/util/less/test/browser/runner-rootpath.js b/util/less/test/browser/runner-rootpath.js
new file mode 100644
index 0000000..2c7edd7
--- /dev/null
+++ b/util/less/test/browser/runner-rootpath.js
@@ -0,0 +1,4 @@
+less.rootpath = "https://www.github.com/";
+describe("less.js browser test - rootpath url's", function() {
+    testLessEqualsInDocument();
+});
\ No newline at end of file
diff --git a/util/less/test/browser/template.htm b/util/less/test/browser/template.htm
new file mode 100644
index 0000000..f25e9c8
--- /dev/null
+++ b/util/less/test/browser/template.htm
@@ -0,0 +1,10 @@
+<script src="http://localhost:8081/browser/jasmine.js" type="text/javascript"></script>
+<script src="http://localhost:8081/browser/jasmine-html.js" type="text/javascript"></script>
+<script src="http://localhost:8081/browser/common.js" type="text/javascript"></script>
+<script src="http://localhost:8081/browser/runner-{runner-name}.js" type="text/javascript"></script>
+<script src="http://localhost:8081/browser/less.js" type="text/javascript"></script>
+<link rel="stylesheet"  type="text/css" href="http://localhost:8081/browser/jasmine.css"></link>
+</head>
+<body>
+</body>
+</html>
\ No newline at end of file
diff --git a/util/less/test/css/charsets.css b/util/less/test/css/charsets.css
new file mode 100644
index 0000000..9f44090
--- /dev/null
+++ b/util/less/test/css/charsets.css
@@ -0,0 +1 @@
+ at charset "UTF-8";
diff --git a/util/less/test/css/colors.css b/util/less/test/css/colors.css
new file mode 100644
index 0000000..1695677
--- /dev/null
+++ b/util/less/test/css/colors.css
@@ -0,0 +1,80 @@
+#yelow #short {
+  color: #fea;
+}
+#yelow #long {
+  color: #ffeeaa;
+}
+#yelow #rgba {
+  color: rgba(255, 238, 170, 0.1);
+}
+#yelow #argb {
+  color: #1affeeaa;
+}
+#blue #short {
+  color: #00f;
+}
+#blue #long {
+  color: #0000ff;
+}
+#blue #rgba {
+  color: rgba(0, 0, 255, 0.1);
+}
+#blue #argb {
+  color: #1a0000ff;
+}
+#alpha #hsla {
+  color: rgba(61, 45, 41, 0.6);
+}
+#overflow .a {
+  color: #000000;
+}
+#overflow .b {
+  color: #ffffff;
+}
+#overflow .c {
+  color: #ffffff;
+}
+#overflow .d {
+  color: #00ff00;
+}
+#grey {
+  color: #c8c8c8;
+}
+#333333 {
+  color: #333333;
+}
+#808080 {
+  color: #808080;
+}
+#00ff00 {
+  color: #00ff00;
+}
+.lightenblue {
+  color: #3333ff;
+}
+.darkenblue {
+  color: #0000cc;
+}
+.unknowncolors {
+  color: blue2;
+  border: 2px solid superred;
+}
+.transparent {
+  color: transparent;
+  background-color: rgba(0, 0, 0, 0);
+}
+#alpha #fromvar {
+  opacity: 0.7;
+}
+#alpha #short {
+  opacity: 1;
+}
+#alpha #long {
+  opacity: 1;
+}
+#alpha #rgba {
+  opacity: 0.2;
+}
+#alpha #hsl {
+  opacity: 1;
+}
diff --git a/util/less/test/css/comments.css b/util/less/test/css/comments.css
new file mode 100644
index 0000000..0aea21b
--- /dev/null
+++ b/util/less/test/css/comments.css
@@ -0,0 +1,63 @@
+/******************\
+*                  *
+*  Comment Header  *
+*                  *
+\******************/
+/*
+
+    Comment
+
+*/
+/*
+ * Comment Test
+ *
+ * - cloudhead (http://cloudhead.net)
+ *
+ */
+/* Colors
+ * ------
+ *   #EDF8FC (background blue)
+ *   #166C89 (darkest blue)
+ *
+ * Text:
+ *   #333 (standard text) // A comment within a comment!
+ *   #1F9EC9 (standard link)
+ *
+ */
+/* @group Variables
+------------------- */
+#comments {
+  /**/
+  color: red;
+  /* A C-style comment */
+
+  background-color: orange;
+  font-size: 12px;
+  /* lost comment */
+  content: "content";
+  border: 1px solid black;
+  padding: 0;
+  margin: 2em;
+}
+/* commented out
+  #more-comments {
+    color: grey;
+  }
+*/
+.selector,
+.lots,
+.comments {
+  color: #808080, /* blue */ #ffa500;
+  -webkit-border-radius: 2px /* webkit only */;
+  -moz-border-radius: 8px /* moz only with operation */;
+}
+.test {
+  color: 1px //put in @b - causes problems! --->;
+}
+#last {
+  color: #0000ff;
+}
+/*  *//* { *//*  *//*  *//*  */#div {
+  color: #A33;
+}
+/* } */
diff --git a/util/less/test/css/css-3.css b/util/less/test/css/css-3.css
new file mode 100644
index 0000000..d48dbe5
--- /dev/null
+++ b/util/less/test/css/css-3.css
@@ -0,0 +1,113 @@
+.comma-delimited {
+  text-shadow: -1px -1px 1px #ff0000, 6px 5px 5px #ffff00;
+  -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
+}
+ at font-face {
+  font-family: Headline;
+  unicode-range: U+??????, U+0???, U+0-7F, U+A5;
+}
+.other {
+  -moz-transform: translate(0, 11em) rotate(-90deg);
+  transform: rotateX(45deg);
+}
+.item[data-cra_zy-attr1b-ut3=bold] {
+  font-weight: bold;
+}
+p:not([class*="lead"]) {
+  color: black;
+}
+input[type="text"].class#id[attr=32]:not(1) {
+  color: white;
+}
+div#id.class[a=1][b=2].class:not(1) {
+  color: white;
+}
+ul.comma > li:not(:only-child)::after {
+  color: white;
+}
+ol.comma > li:nth-last-child(2)::after {
+  color: white;
+}
+li:nth-child(4n+1),
+li:nth-child(-5n),
+li:nth-child(-n+2) {
+  color: white;
+}
+a[href^="http://"] {
+  color: black;
+}
+a[href$="http://"] {
+  color: black;
+}
+form[data-disabled] {
+  color: black;
+}
+p::before {
+  color: black;
+}
+#issue322 {
+  -webkit-animation: anim2 7s infinite ease-in-out;
+}
+ at -webkit-keyframes frames {
+  0% {
+    border: 1px;
+  }
+  5.5% {
+    border: 2px;
+  }
+  100% {
+    border: 3px;
+  }
+}
+ at keyframes fontbulger1 {
+  to {
+    font-size: 15px;
+  }
+  from,
+  to {
+    font-size: 12px;
+  }
+  0%,
+  100% {
+    font-size: 12px;
+  }
+}
+.units {
+  font: 1.2rem/2rem;
+  font: 8vw/9vw;
+  font: 10vh/12vh;
+  font: 12vm/15vm;
+  font: 12vmin/15vmin;
+  font: 1.2ch/1.5ch;
+}
+ at supports ( box-shadow: 2px 2px 2px black ) or
+          ( -moz-box-shadow: 2px 2px 2px black ) {
+  .outline {
+    box-shadow: 2px 2px 2px black;
+    -moz-box-shadow: 2px 2px 2px black;
+  }
+}
+ at -x-document url-prefix(""github.com"") {
+  h1 {
+    color: red;
+  }
+}
+ at viewport {
+  font-size: 10px;
+}
+ at namespace foo url(http://www.example.com);
+foo | h1 {
+  color: blue;
+}
+foo | * {
+  color: yellow;
+}
+| h1 {
+  color: red;
+}
+* | h1 {
+  color: green;
+}
+h1 {
+  color: green;
+}
diff --git a/util/less/test/css/css-escapes.css b/util/less/test/css/css-escapes.css
new file mode 100644
index 0000000..4d343aa
--- /dev/null
+++ b/util/less/test/css/css-escapes.css
@@ -0,0 +1,24 @@
+.escape\|random\|char {
+  color: red;
+}
+.mixin\!tUp {
+  font-weight: bold;
+}
+.\34 04 {
+  background: red;
+}
+.\34 04 strong {
+  color: #ff00ff;
+  font-weight: bold;
+}
+.trailingTest\+ {
+  color: red;
+}
+/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */
+\62\6c\6f \63 \6B \0071 \000075o\74 e {
+  color: silver;
+}
+[ng\:cloak],
+ng\:form {
+  display: none;
+}
diff --git a/util/less/test/css/css.css b/util/less/test/css/css.css
new file mode 100644
index 0000000..5d9516a
--- /dev/null
+++ b/util/less/test/css/css.css
@@ -0,0 +1,89 @@
+ at charset "utf-8";
+div {
+  color: black;
+}
+div {
+  width: 99%;
+}
+* {
+  min-width: 45em;
+}
+h1,
+h2 > a > p,
+h3 {
+  color: none;
+}
+div.class {
+  color: blue;
+}
+div#id {
+  color: green;
+}
+.class#id {
+  color: purple;
+}
+.one.two.three {
+  color: grey;
+}
+ at media print {
+  font-size: 3em;
+}
+ at media screen {
+  font-size: 10px;
+}
+ at font-face {
+  font-family: 'Garamond Pro';
+}
+a:hover,
+a:link {
+  color: #999;
+}
+p,
+p:first-child {
+  text-transform: none;
+}
+q:lang(no) {
+  quotes: none;
+}
+p + h1 {
+  font-size: 2.2em;
+}
+#shorthands {
+  border: 1px solid #000;
+  font: 12px/16px Arial;
+  font: 100%/16px Arial;
+  margin: 1px 0;
+  padding: 0 auto;
+}
+#more-shorthands {
+  margin: 0;
+  padding: 1px 0 2px 0;
+  font: normal small/20px 'Trebuchet MS', Verdana, sans-serif;
+  font: 0/0 a;
+}
+.misc {
+  -moz-border-radius: 2px;
+  display: -moz-inline-stack;
+  width: .1em;
+  background-color: #009998;
+  background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), to(#0000ff));
+  margin: ;
+  filter: alpha(opacity=100);
+}
+.misc .nested-multiple {
+  multiple-semi-colons: yes;
+}
+#important {
+  color: red !important;
+  width: 100%!important;
+  height: 20px ! important;
+}
+ at font-face {
+  font-family: font-a;
+}
+ at font-face {
+  font-family: font-b;
+}
+.æøå {
+  margin: 0;
+}
diff --git a/util/less/test/css/debug/linenumbers-all.css b/util/less/test/css/debug/linenumbers-all.css
new file mode 100644
index 0000000..c6fb355
--- /dev/null
+++ b/util/less/test/css/debug/linenumbers-all.css
@@ -0,0 +1,43 @@
+ at charset "UTF-8";
+/* line 3, {pathimport}test.less */
+ at media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000033}}
+/* @charset "ISO-8859-1"; */
+/* line 23, {pathimport}test.less */
+ at media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000323}}
+.tst3 {
+  color: grey;
+}
+/* line 15, {path}linenumbers.less */
+ at media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000315}}
+.test1 {
+  color: black;
+}
+/* line 6, {path}linenumbers.less */
+ at media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\000036}}
+.test2 {
+  color: red;
+}
+ at media all {
+  /* line 5, {pathimport}test.less */
+  @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000035}}
+  .tst {
+    color: black;
+  }
+}
+ at media all and screen {
+  /* line 7, {pathimport}test.less */
+  @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000037}}
+  .tst {
+    color: red;
+  }
+  /* line 9, {pathimport}test.less */
+  @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000039}}
+  .tst .tst3 {
+    color: white;
+  }
+}
+/* line 18, {pathimport}test.less */
+ at media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000318}}
+.tst2 {
+  color: white;
+}
diff --git a/util/less/test/css/debug/linenumbers-comments.css b/util/less/test/css/debug/linenumbers-comments.css
new file mode 100644
index 0000000..9c48baa
--- /dev/null
+++ b/util/less/test/css/debug/linenumbers-comments.css
@@ -0,0 +1,35 @@
+ at charset "UTF-8";
+/* line 3, {pathimport}test.less */
+/* @charset "ISO-8859-1"; */
+/* line 23, {pathimport}test.less */
+.tst3 {
+  color: grey;
+}
+/* line 15, {path}linenumbers.less */
+.test1 {
+  color: black;
+}
+/* line 6, {path}linenumbers.less */
+.test2 {
+  color: red;
+}
+ at media all {
+  /* line 5, {pathimport}test.less */
+  .tst {
+    color: black;
+  }
+}
+ at media all and screen {
+  /* line 7, {pathimport}test.less */
+  .tst {
+    color: red;
+  }
+  /* line 9, {pathimport}test.less */
+  .tst .tst3 {
+    color: white;
+  }
+}
+/* line 18, {pathimport}test.less */
+.tst2 {
+  color: white;
+}
diff --git a/util/less/test/css/debug/linenumbers-mediaquery.css b/util/less/test/css/debug/linenumbers-mediaquery.css
new file mode 100644
index 0000000..3fdbbaf
--- /dev/null
+++ b/util/less/test/css/debug/linenumbers-mediaquery.css
@@ -0,0 +1,35 @@
+ at charset "UTF-8";
+ at media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000033}}
+/* @charset "ISO-8859-1"; */
+ at media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000323}}
+.tst3 {
+  color: grey;
+}
+ at media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000315}}
+.test1 {
+  color: black;
+}
+ at media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\000036}}
+.test2 {
+  color: red;
+}
+ at media all {
+  @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000035}}
+  .tst {
+    color: black;
+  }
+}
+ at media all and screen {
+  @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000037}}
+  .tst {
+    color: red;
+  }
+  @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000039}}
+  .tst .tst3 {
+    color: white;
+  }
+}
+ at media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000318}}
+.tst2 {
+  color: white;
+}
diff --git a/util/less/test/css/functions.css b/util/less/test/css/functions.css
new file mode 100644
index 0000000..bf612d4
--- /dev/null
+++ b/util/less/test/css/functions.css
@@ -0,0 +1,100 @@
+#functions {
+  color: #660000;
+  width: 16;
+  height: undefined("self");
+  border-width: 5;
+  variable: 11;
+  background: linear-gradient(#000000, #ffffff);
+}
+#built-in {
+  escaped: -Some::weird(#thing, y);
+  lighten: #ffcccc;
+  darken: #330000;
+  saturate: #203c31;
+  desaturate: #29332f;
+  greyscale: #2e2e2e;
+  spin-p: #bf6a40;
+  spin-n: #bf4055;
+  luma-white: 100%;
+  luma-black: 0%;
+  luma-black-alpha: 0%;
+  luma-red: 21%;
+  luma-green: 72%;
+  luma-blue: 7%;
+  luma-yellow: 93%;
+  luma-cyan: 79%;
+  luma-white-alpha: 50%;
+  contrast-filter: contrast(30%);
+  contrast-white: #000000;
+  contrast-black: #ffffff;
+  contrast-red: #ffffff;
+  contrast-green: #000000;
+  contrast-blue: #ffffff;
+  contrast-yellow: #000000;
+  contrast-cyan: #000000;
+  contrast-light: #111111;
+  contrast-dark: #eeeeee;
+  contrast-light-thresh: #111111;
+  contrast-dark-thresh: #eeeeee;
+  contrast-high-thresh: #eeeeee;
+  contrast-low-thresh: #111111;
+  format: "rgb(32, 128, 64)";
+  format-string: "hello world";
+  format-multiple: "hello earth 2";
+  format-url-encode: "red is %23ff0000";
+  eformat: rgb(32, 128, 64);
+  unitless: 12;
+  unit: 14em;
+  hue: 98;
+  saturation: 12%;
+  lightness: 95%;
+  red: 255;
+  green: 255;
+  blue: 255;
+  rounded: 11;
+  rounded-two: 10.67;
+  roundedpx: 3px;
+  roundedpx-three: 3.333px;
+  rounded-percentage: 10%;
+  ceil: 11px;
+  floor: 12px;
+  percentage: 20%;
+  color: #ff0011;
+  tint: #898989;
+  tint-full: #ffffff;
+  tint-percent: #898989;
+  shade: #686868;
+  shade-full: #000000;
+  shade-percent: #686868;
+  hsv: #4d2926;
+  hsva: rgba(77, 40, 38, 0.2);
+  mix: #ff3300;
+  mix-0: #ffff00;
+  mix-100: #ff0000;
+  mix-weightless: #ff8000;
+}
+#built-in .is-a {
+  color: true;
+  color1: true;
+  color2: true;
+  keyword: true;
+  number: true;
+  string: true;
+  pixel: true;
+  percent: true;
+  em: true;
+}
+#alpha {
+  alpha: rgba(153, 94, 51, 0.6);
+}
+#blendmodes {
+  multiply: #ed0000;
+  screen: #f600f6;
+  overlay: #ed0000;
+  softlight: #ff0000;
+  hardlight: #0000ed;
+  difference: #f600f6;
+  exclusion: #f600f6;
+  average: #7b007b;
+  negation: #d73131;
+}
diff --git a/util/less/test/css/ie-filters.css b/util/less/test/css/ie-filters.css
new file mode 100644
index 0000000..007aa53
--- /dev/null
+++ b/util/less/test/css/ie-filters.css
@@ -0,0 +1,9 @@
+.nav {
+  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=20);
+  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="#000000", GradientType=0);
+}
+.evalTest1 {
+  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=30);
+  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=5);
+}
diff --git a/util/less/test/css/import-once.css b/util/less/test/css/import-once.css
new file mode 100644
index 0000000..b2a15d3
--- /dev/null
+++ b/util/less/test/css/import-once.css
@@ -0,0 +1,3 @@
+#import {
+  color: #ff0000;
+}
diff --git a/util/less/test/css/import.css b/util/less/test/css/import.css
new file mode 100644
index 0000000..3ed7de5
--- /dev/null
+++ b/util/less/test/css/import.css
@@ -0,0 +1,21 @@
+ at import url(http://fonts.googleapis.com/css?family=Open+Sans);
+
+ at import url(something.css) screen and (color) and (max-width: 600px);
+#import-test {
+  height: 10px;
+  color: #ff0000;
+  width: 10px;
+  height: 30%;
+}
+ at media screen and (max-width: 600px) {
+  body {
+    width: 100%;
+  }
+}
+#import {
+  color: #ff0000;
+}
+.mixin {
+  height: 10px;
+  color: #ff0000;
+}
diff --git a/util/less/test/css/javascript.css b/util/less/test/css/javascript.css
new file mode 100644
index 0000000..8268ab3
--- /dev/null
+++ b/util/less/test/css/javascript.css
@@ -0,0 +1,23 @@
+.eval {
+  js: 42;
+  js: 2;
+  js: "hello world";
+  js: 1, 2, 3;
+  title: "string";
+  ternary: true;
+  multiline: 2;
+}
+.scope {
+  var: 42;
+  escaped: 7px;
+}
+.vars {
+  width: 8;
+}
+.escape-interpol {
+  width: hello world;
+}
+.arrays {
+  ary: "1, 2, 3";
+  ary1: "1, 2, 3";
+}
diff --git a/util/less/test/css/lazy-eval.css b/util/less/test/css/lazy-eval.css
new file mode 100644
index 0000000..1adfb8f
--- /dev/null
+++ b/util/less/test/css/lazy-eval.css
@@ -0,0 +1,3 @@
+.lazy-eval {
+  width: 100%;
+}
diff --git a/util/less/test/css/media.css b/util/less/test/css/media.css
new file mode 100644
index 0000000..d16ce63
--- /dev/null
+++ b/util/less/test/css/media.css
@@ -0,0 +1,195 @@
+ at media print {
+  .class {
+    color: blue;
+  }
+  .class .sub {
+    width: 42;
+  }
+  .top,
+  header > h1 {
+    color: #444444;
+  }
+}
+ at media screen {
+  body {
+    max-width: 480;
+  }
+}
+ at media all and (device-aspect-ratio: 16/9) {
+  body {
+    max-width: 800px;
+  }
+}
+ at media all and (orientation: portrait) {
+  aside {
+    float: none;
+  }
+}
+ at media handheld and (min-width: 42), screen and (min-width: 20em) {
+  body {
+    max-width: 480px;
+  }
+}
+ at media print {
+  body {
+    padding: 20px;
+  }
+  body header {
+    background-color: red;
+  }
+}
+ at media print and (orientation: landscape) {
+  body {
+    margin-left: 20px;
+  }
+}
+ at media screen {
+  .sidebar {
+    width: 300px;
+  }
+}
+ at media screen and (orientation: landscape) {
+  .sidebar {
+    width: 500px;
+  }
+}
+ at media a {
+  
+}
+ at media a and b {
+  .first .second .third {
+    width: 300px;
+  }
+  .first .second .fourth {
+    width: 3;
+  }
+}
+ at media a and b and c {
+  .first .second .third {
+    width: 500px;
+  }
+}
+ at media a, b and c {
+  body {
+    width: 95%;
+  }
+}
+ at media a and x, b and c and x, a and y, b and c and y {
+  body {
+    width: 100%;
+  }
+}
+.a {
+  background: black;
+}
+ at media handheld {
+  .a {
+    background: white;
+  }
+}
+ at media handheld and (max-width: 100px) {
+  .a {
+    background: red;
+  }
+}
+.b {
+  background: black;
+}
+ at media handheld {
+  .b {
+    background: white;
+  }
+}
+ at media handheld and (max-width: 200px) {
+  .b {
+    background: red;
+  }
+}
+ at media only screen and (max-width: 200px) {
+  width: 480px;
+}
+ at media print {
+  @page :left {
+    margin: 0.5cm;
+  }
+  @page :right {
+    margin: 0.5cm;
+  }
+  @page Test:first {
+    margin: 1cm;
+  }
+  @page :first {
+    size: 8.5in 11in;@top-left {
+      margin: 1cm;
+    }
+    @top-left-corner {
+      margin: 1cm;
+    }
+    @top-center {
+      margin: 1cm;
+    }
+    @top-right {
+      margin: 1cm;
+    }
+    @top-right-corner {
+      margin: 1cm;
+    }
+    @bottom-left {
+      margin: 1cm;
+    }
+    @bottom-left-corner {
+      margin: 1cm;
+    }
+    @bottom-center {
+      margin: 1cm;
+    }
+    @bottom-right {
+      margin: 1cm;
+    }
+    @bottom-right-corner {
+      margin: 1cm;
+    }
+    @left-top {
+      margin: 1cm;
+    }
+    @left-middle {
+      margin: 1cm;
+    }
+    @left-bottom {
+      margin: 1cm;
+    }
+    @right-top {
+      margin: 1cm;
+    }
+    @right-middle {
+      content: "Page " counter(page);
+    }
+    @right-bottom {
+      margin: 1cm;
+    }
+  }
+}
+ at media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) {
+  .b {
+    background: red;
+  }
+}
+body {
+  background: red;
+}
+ at media (max-width: 500px) {
+  body {
+    background: green;
+  }
+}
+ at media (max-width: 1000px) {
+  body {
+    background: red;
+    background: blue;
+  }
+}
+ at media (max-width: 1000px) and (max-width: 500px) {
+  body {
+    background: green;
+  }
+}
diff --git a/util/less/test/css/mixins-args.css b/util/less/test/css/mixins-args.css
new file mode 100644
index 0000000..91104ac
--- /dev/null
+++ b/util/less/test/css/mixins-args.css
@@ -0,0 +1,95 @@
+#hidden {
+  color: transparent;
+}
+#hidden1 {
+  color: transparent;
+}
+.two-args {
+  color: blue;
+  width: 10px;
+  height: 99%;
+  border: 2px dotted #000000;
+}
+.one-arg {
+  width: 15px;
+  height: 49%;
+}
+.no-parens {
+  width: 5px;
+  height: 49%;
+}
+.no-args {
+  width: 5px;
+  height: 49%;
+}
+.var-args {
+  width: 45;
+  height: 17%;
+}
+.multi-mix {
+  width: 10px;
+  height: 29%;
+  margin: 4;
+  padding: 5;
+}
+body {
+  padding: 30px;
+  color: #ff0000;
+}
+.scope-mix {
+  width: 8;
+}
+.content {
+  width: 600px;
+}
+.content .column {
+  margin: 600px;
+}
+#same-var-name {
+  radius: 5px;
+}
+#var-inside {
+  width: 10px;
+}
+.arguments {
+  border: 1px solid #000000;
+  width: 1px;
+}
+.arguments2 {
+  border: 0px;
+  width: 0px;
+}
+.arguments3 {
+  border: 0px;
+  width: 0px;
+}
+.arguments4 {
+  border: 0 1 2 3 4;
+  rest: 1 2 3 4;
+  width: 0;
+}
+.edge-case {
+  border: "{";
+  width: "{";
+}
+.comma-vs-semi-colon {
+  one: a;
+  two: b, c;
+  one: d, e;
+  two: f;
+  one: g;
+  one: h;
+  one: i;
+  one: j;
+  one: k;
+  two: l;
+  one: m, n;
+  one: o, p;
+  two: q;
+  one: r, s;
+  two: t;
+}
+#named-conflict {
+  four: a, 11, 12, 13;
+  four: a, 21, 22, 23;
+}
diff --git a/util/less/test/css/mixins-closure.css b/util/less/test/css/mixins-closure.css
new file mode 100644
index 0000000..b1021b6
--- /dev/null
+++ b/util/less/test/css/mixins-closure.css
@@ -0,0 +1,9 @@
+.class {
+  width: 99px;
+}
+.overwrite {
+  width: 99px;
+}
+.nested .class {
+  width: 5px;
+}
diff --git a/util/less/test/css/mixins-guards.css b/util/less/test/css/mixins-guards.css
new file mode 100644
index 0000000..f899a8e
--- /dev/null
+++ b/util/less/test/css/mixins-guards.css
@@ -0,0 +1,71 @@
+.light1 {
+  color: white;
+  margin: 1px;
+}
+.light2 {
+  color: black;
+  margin: 1px;
+}
+.max1 {
+  width: 6;
+}
+.max2 {
+  width: 8;
+}
+.glob1 {
+  margin: auto auto;
+}
+.ops1 {
+  height: gt-or-eq;
+  height: lt-or-eq;
+}
+.ops2 {
+  height: gt-or-eq;
+  height: not-eq;
+}
+.ops3 {
+  height: lt-or-eq;
+  height: not-eq;
+}
+.default1 {
+  content: default;
+}
+.test1 {
+  content: "true.";
+}
+.test2 {
+  content: "false.";
+}
+.test3 {
+  content: "false.";
+}
+.test4 {
+  content: "false.";
+}
+.test5 {
+  content: "false.";
+}
+.bool1 {
+  content: true and true;
+  content: true;
+  content: false, true;
+  content: false and true and true, true;
+  content: false, true and true;
+  content: false, false, true;
+  content: false, true and true and true, false;
+  content: not false;
+  content: not false and false, not false;
+}
+.equality-units {
+  test: pass;
+}
+.colorguardtest {
+  content: is #ff0000;
+  content: is not #0000ff its #ff0000;
+  content: is not #0000ff its #800080;
+}
+.stringguardtest {
+  content: is theme1;
+  content: is not theme2;
+  content: is theme1 no quotes;
+}
diff --git a/util/less/test/css/mixins-important.css b/util/less/test/css/mixins-important.css
new file mode 100644
index 0000000..535726b
--- /dev/null
+++ b/util/less/test/css/mixins-important.css
@@ -0,0 +1,38 @@
+.class {
+  border: 1;
+  boxer: 1;
+  border: 2 !important;
+  boxer: 2 !important;
+  border: 3;
+  boxer: 3;
+  border: 4 !important;
+  boxer: 4 !important;
+  border: 5;
+  boxer: 5;
+  border: 0 !important;
+  boxer: 0 !important;
+  border: 9 !important;
+  border: 9;
+  boxer: 9;
+}
+.class .inner {
+  test: 1;
+}
+.class .inner {
+  test: 2 !important;
+}
+.class .inner {
+  test: 3;
+}
+.class .inner {
+  test: 4 !important;
+}
+.class .inner {
+  test: 5;
+}
+.class .inner {
+  test: 0 !important;
+}
+.class .inner {
+  test: 9;
+}
diff --git a/util/less/test/css/mixins-named-args.css b/util/less/test/css/mixins-named-args.css
new file mode 100644
index 0000000..e460aa1
--- /dev/null
+++ b/util/less/test/css/mixins-named-args.css
@@ -0,0 +1,27 @@
+.named-arg {
+  color: blue;
+  width: 5px;
+  height: 99%;
+  args: 1px 100%;
+  text-align: center;
+}
+.class {
+  width: 5px;
+  height: 19%;
+  args: 1px 20%;
+}
+.all-args-wrong-args {
+  width: 10px;
+  height: 9%;
+  args: 2px 10%;
+}
+.named-args2 {
+  width: 15px;
+  height: 49%;
+  color: #646464;
+}
+.named-args3 {
+  width: 5px;
+  height: 29%;
+  color: #123456;
+}
diff --git a/util/less/test/css/mixins-nested.css b/util/less/test/css/mixins-nested.css
new file mode 100644
index 0000000..6378c47
--- /dev/null
+++ b/util/less/test/css/mixins-nested.css
@@ -0,0 +1,14 @@
+.class .inner {
+  height: 300;
+}
+.class .inner .innest {
+  width: 30;
+  border-width: 60;
+}
+.class2 .inner {
+  height: 600;
+}
+.class2 .inner .innest {
+  width: 60;
+  border-width: 120;
+}
diff --git a/util/less/test/css/mixins-pattern.css b/util/less/test/css/mixins-pattern.css
new file mode 100644
index 0000000..8b82833
--- /dev/null
+++ b/util/less/test/css/mixins-pattern.css
@@ -0,0 +1,47 @@
+.zero {
+  variadic: true;
+  zero: 0;
+  one: 1;
+  two: 2;
+  three: 3;
+}
+.one {
+  variadic: true;
+  one: 1;
+  one-req: 1;
+  two: 2;
+  three: 3;
+}
+.two {
+  variadic: true;
+  two: 2;
+  three: 3;
+}
+.three {
+  variadic: true;
+  three-req: 3;
+  three: 3;
+}
+.left {
+  left: 1;
+}
+.right {
+  right: 1;
+}
+.border-right {
+  color: black;
+  border-right: 4px;
+}
+.border-left {
+  color: black;
+  border-left: 4px;
+}
+.only-right {
+  right: 33;
+}
+.only-left {
+  left: 33;
+}
+.left-right {
+  both: 330;
+}
diff --git a/util/less/test/css/mixins.css b/util/less/test/css/mixins.css
new file mode 100644
index 0000000..62939e1
--- /dev/null
+++ b/util/less/test/css/mixins.css
@@ -0,0 +1,121 @@
+.mixin {
+  border: 1px solid black;
+}
+.mixout {
+  border-color: orange;
+}
+.borders {
+  border-style: dashed;
+}
+#namespace .borders {
+  border-style: dotted;
+}
+#namespace .biohazard {
+  content: "death";
+}
+#namespace .biohazard .man {
+  color: transparent;
+}
+#theme > .mixin {
+  background-color: grey;
+}
+#container {
+  color: black;
+  border: 1px solid black;
+  border-color: orange;
+  background-color: grey;
+}
+#header .milk {
+  color: white;
+  border: 1px solid black;
+  background-color: grey;
+}
+#header #cookie {
+  border-style: dashed;
+}
+#header #cookie .chips {
+  border-style: dotted;
+}
+#header #cookie .chips .calories {
+  color: black;
+  border: 1px solid black;
+  border-color: orange;
+  background-color: grey;
+}
+.secure-zone {
+  color: transparent;
+}
+.direct {
+  border-style: dotted;
+}
+.bo,
+.bar {
+  width: 100%;
+}
+.bo {
+  border: 1px;
+}
+.ar.bo.ca {
+  color: black;
+}
+.jo.ki {
+  background: none;
+}
+.amp.support {
+  color: orange;
+}
+.extended {
+  width: 100%;
+  border: 1px;
+  background: none;
+  color: orange;
+}
+.foo .bar {
+  width: 100%;
+}
+.underParents {
+  color: red;
+}
+.parent .underParents {
+  color: red;
+}
+* + h1 {
+  margin-top: 25px;
+}
+legend + h1 {
+  margin-top: 0;
+}
+h1 + * {
+  margin-top: 10px;
+}
+* + h2 {
+  margin-top: 20px;
+}
+legend + h2 {
+  margin-top: 0;
+}
+h2 + * {
+  margin-top: 8px;
+}
+* + h3 {
+  margin-top: 15px;
+}
+legend + h3 {
+  margin-top: 0;
+}
+h3 + * {
+  margin-top: 5px;
+}
+.error {
+  background-image: "/a.png";
+  background-position: center center;
+}
+.test-rec .recursion {
+  color: black;
+}
+.button {
+  padding-left: 44px;
+}
+.button.large {
+  padding-left: 40em;
+}
diff --git a/util/less/test/css/operations.css b/util/less/test/css/operations.css
new file mode 100644
index 0000000..fb9e0af
--- /dev/null
+++ b/util/less/test/css/operations.css
@@ -0,0 +1,49 @@
+#operations {
+  color: #111111;
+  height: 9px;
+  width: 3em;
+  substraction: 0;
+  division: 1;
+}
+#operations .spacing {
+  height: 9px;
+  width: 3em;
+}
+.with-variables {
+  height: 16em;
+  width: 24em;
+  size: 1cm;
+}
+.with-functions {
+  color: #646464;
+  color: #ff8080;
+  color: #c94a4a;
+}
+.negative {
+  height: 0px;
+  width: 4px;
+}
+.shorthands {
+  padding: -1px 2px 0 -4px;
+}
+.rem-dimensions {
+  font-size: 5.5rem;
+}
+.colors {
+  color: #123;
+  border-color: #334455;
+  background-color: #000000;
+}
+.colors .other {
+  color: #222222;
+  border-color: #222222;
+}
+.negations {
+  variable: -4px;
+  variable1: 0px;
+  variable2: 0px;
+  variable3: 8px;
+  variable4: 0px;
+  paren: -4px;
+  paren2: 16px;
+}
diff --git a/util/less/test/css/parens.css b/util/less/test/css/parens.css
new file mode 100644
index 0000000..36487fe
--- /dev/null
+++ b/util/less/test/css/parens.css
@@ -0,0 +1,20 @@
+.parens {
+  border: 2px solid #000000;
+  margin: 1px 3px 16 3;
+  width: 36;
+  padding: 2px 36px;
+}
+.more-parens {
+  padding: 8 4 4 4px;
+  width: 96;
+  height: 113;
+  margin: 12;
+}
+.nested-parens {
+  width: 71;
+  height: 6;
+}
+.mixed-units {
+  margin: 2px 4em 1 5pc;
+  padding: 6px 1em 2px 2;
+}
diff --git a/util/less/test/css/rulesets.css b/util/less/test/css/rulesets.css
new file mode 100644
index 0000000..408c76a
--- /dev/null
+++ b/util/less/test/css/rulesets.css
@@ -0,0 +1,33 @@
+#first > .one {
+  font-size: 2em;
+}
+#first > .one > #second .two > #deux {
+  width: 50%;
+}
+#first > .one > #second .two > #deux #third {
+  height: 100%;
+}
+#first > .one > #second .two > #deux #third:focus {
+  color: black;
+}
+#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth + #ninth {
+  color: purple;
+}
+#first > .one > #second .two > #deux #fourth,
+#first > .one > #second .two > #deux #five,
+#first > .one > #second .two > #deux #six {
+  color: #110000;
+}
+#first > .one > #second .two > #deux #fourth .seven,
+#first > .one > #second .two > #deux #five .seven,
+#first > .one > #second .two > #deux #six .seven,
+#first > .one > #second .two > #deux #fourth .eight > #nine,
+#first > .one > #second .two > #deux #five .eight > #nine,
+#first > .one > #second .two > #deux #six .eight > #nine {
+  border: 1px solid black;
+}
+#first > .one > #second .two > #deux #fourth #ten,
+#first > .one > #second .two > #deux #five #ten,
+#first > .one > #second .two > #deux #six #ten {
+  color: red;
+}
diff --git a/util/less/test/css/scope.css b/util/less/test/css/scope.css
new file mode 100644
index 0000000..baa0552
--- /dev/null
+++ b/util/less/test/css/scope.css
@@ -0,0 +1,35 @@
+.tiny-scope {
+  color: #998899;
+}
+.scope1 {
+  color: #0000ff;
+  border-color: #000000;
+}
+.scope1 .scope2 {
+  color: #0000ff;
+}
+.scope1 .scope2 .scope3 {
+  color: #ff0000;
+  border-color: #000000;
+  background-color: #ffffff;
+}
+.scope {
+  scoped-val: #008000;
+}
+.heightIsSet {
+  height: 1024px;
+}
+.useHeightInMixinCall {
+  mixin-height: 1024px;
+}
+.imported {
+  exists: true;
+}
+.testImported {
+  exists: true;
+}
+#allAreUsedHere {
+  default: 'top level';
+  scope: 'top level';
+  sub-scope-only: 'inside';
+}
diff --git a/util/less/test/css/selectors.css b/util/less/test/css/selectors.css
new file mode 100644
index 0000000..6995983
--- /dev/null
+++ b/util/less/test/css/selectors.css
@@ -0,0 +1,133 @@
+h1 a:hover,
+h2 a:hover,
+h3 a:hover,
+h1 p:hover,
+h2 p:hover,
+h3 p:hover {
+  color: red;
+}
+#all {
+  color: blue;
+}
+#the {
+  color: blue;
+}
+#same {
+  color: blue;
+}
+ul,
+li,
+div,
+q,
+blockquote,
+textarea {
+  margin: 0;
+}
+td {
+  margin: 0;
+  padding: 0;
+}
+td,
+input {
+  line-height: 1em;
+}
+a {
+  color: red;
+}
+a:hover {
+  color: blue;
+}
+div a {
+  color: green;
+}
+p a span {
+  color: yellow;
+}
+.foo .bar .qux,
+.foo .baz .qux {
+  display: block;
+}
+.qux .foo .bar,
+.qux .foo .baz {
+  display: inline;
+}
+.qux.foo .bar,
+.qux.foo .baz {
+  display: inline-block;
+}
+.qux .foo .bar .biz,
+.qux .foo .baz .biz {
+  display: none;
+}
+.a.b.c {
+  color: red;
+}
+.c .b.a {
+  color: red;
+}
+.foo .p.bar {
+  color: red;
+}
+.foo.p.bar {
+  color: red;
+}
+.foo + .foo {
+  background: amber;
+}
+.foo + .foo {
+  background: amber;
+}
+.foo + .foo,
+.foo + .bar,
+.bar + .foo,
+.bar + .bar {
+  background: amber;
+}
+.foo a > .foo a,
+.foo a > .bar a,
+.foo a > .foo b,
+.foo a > .bar b,
+.bar a > .foo a,
+.bar a > .bar a,
+.bar a > .foo b,
+.bar a > .bar b,
+.foo b > .foo a,
+.foo b > .bar a,
+.foo b > .foo b,
+.foo b > .bar b,
+.bar b > .foo a,
+.bar b > .bar a,
+.bar b > .foo b,
+.bar b > .bar b {
+  background: amber;
+}
+.other ::fnord {
+  color: #ff0000;
+}
+.other::fnord {
+  color: #ff0000;
+}
+.other ::bnord {
+  color: #ff0000;
+}
+.other::bnord {
+  color: #ff0000;
+}
+.blood {
+  color: red;
+}
+.blood {
+  color: red;
+}
+.bloodred {
+  color: green;
+}
+#blood.blood.red.black {
+  color: black;
+}
+:nth-child(3):nth-child(3) {
+  second-use: deprecated;
+}
+.test:nth-child(odd):not( :nth-child(3)) {
+  color: #ff0000;
+}
diff --git a/util/less/test/css/static-urls/urls.css b/util/less/test/css/static-urls/urls.css
new file mode 100644
index 0000000..b5a690e
--- /dev/null
+++ b/util/less/test/css/static-urls/urls.css
@@ -0,0 +1,42 @@
+ at import "folder (1)/../css/background.css";
+
+ at import "folder (1)/import-test-d.css";
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium), url(folder\ \(1\)/fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(folder\ \(1\)/images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+.comma-delimited {
+  background: url(folder\ \(1\)/bg.jpg) no-repeat, url(folder\ \(1\)/bg.png) repeat-x top left, url(folder\ \(1\)/bg);
+}
+.values {
+  url: url('folder (1)/Trebuchet');
+}
+#logo {
+  width: 100px;
+  height: 100px;
+  background: url('folder (1)/../assets/logo.png');
+}
+ at font-face {
+  font-family: xecret;
+  src: url('folder (1)/../assets/xecret.ttf');
+}
+#secret {
+  font-family: xecret, sans-serif;
+}
diff --git a/util/less/test/css/strings.css b/util/less/test/css/strings.css
new file mode 100644
index 0000000..522bae5
--- /dev/null
+++ b/util/less/test/css/strings.css
@@ -0,0 +1,40 @@
+#strings {
+  background-image: url("http://son-of-a-banana.com");
+  quotes: "~" "~";
+  content: "#*%:&^,)!.(~*})";
+  empty: "";
+  brackets: "{" "}";
+  escapes: "\"hello\" \\world";
+  escapes2: "\"llo";
+}
+#comments {
+  content: "/* hello */ // not-so-secret";
+}
+#single-quote {
+  quotes: "'" "'";
+  content: '""#!&""';
+  empty: '';
+  semi-colon: ';';
+}
+#escaped {
+  filter: DX.Transform.MS.BS.filter(opacity=50);
+}
+#one-line {
+  image: url(http://tooks.com);
+}
+#crazy {
+  image: url(http://), "}", url("http://}");
+}
+#interpolation {
+  url: "http://lesscss.org/dev/image.jpg";
+  url2: "http://lesscss.org/image-256.jpg";
+  url3: "http://lesscss.org#445566";
+  url4: "http://lesscss.org/hello";
+  url5: "http://lesscss.org/54.4px";
+}
+.mix-mul-class {
+  color: #0000ff;
+  color: #ff0000;
+  color: #000000;
+  color: #ffa500;
+}
diff --git a/util/less/test/css/urls.css b/util/less/test/css/urls.css
new file mode 100644
index 0000000..6a8a4e9
--- /dev/null
+++ b/util/less/test/css/urls.css
@@ -0,0 +1,42 @@
+ at import "import/../css/background.css";
+
+ at import "import/import-test-d.css";
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+.comma-delimited {
+  background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+}
+.values {
+  url: url('Trebuchet');
+}
+#logo {
+  width: 100px;
+  height: 100px;
+  background: url('import/imports/../assets/logo.png');
+}
+ at font-face {
+  font-family: xecret;
+  src: url('import/imports/../assets/xecret.ttf');
+}
+#secret {
+  font-family: xecret, sans-serif;
+}
diff --git a/util/less/test/css/variables.css b/util/less/test/css/variables.css
new file mode 100644
index 0000000..aac5faa
--- /dev/null
+++ b/util/less/test/css/variables.css
@@ -0,0 +1,26 @@
+.variables {
+  width: 14cm;
+}
+.variables {
+  height: 24px;
+  color: #888888;
+  font-family: "Trebuchet MS", Verdana, sans-serif;
+  quotes: "~" "~";
+}
+.redefinition {
+  three: 3;
+}
+.values {
+  font-family: 'Trebuchet', 'Trebuchet', 'Trebuchet';
+  color: #888888 !important;
+  multi: something 'A', B, C, 'Trebuchet';
+}
+.variable-names {
+  name: 'hello';
+}
+.alpha {
+  filter: alpha(opacity=42);
+}
+a:nth-child(2) {
+  border: 1px;
+}
diff --git a/util/less/test/css/whitespace.css b/util/less/test/css/whitespace.css
new file mode 100644
index 0000000..74c9b65
--- /dev/null
+++ b/util/less/test/css/whitespace.css
@@ -0,0 +1,42 @@
+.whitespace {
+  color: white;
+}
+.whitespace {
+  color: white;
+}
+.whitespace {
+  color: white;
+}
+.whitespace {
+  color: white;
+}
+.whitespace {
+  color: white ;
+}
+.white,
+.space,
+.mania {
+  color: white;
+}
+.no-semi-column {
+  color: #ffffff;
+}
+.no-semi-column {
+  color: white;
+  white-space: pre;
+}
+.no-semi-column {
+  border: 2px solid #ffffff;
+}
+.newlines {
+  background: the,
+              great,
+              wall;
+  border: 2px
+          solid
+          black;
+}
+.sel .newline_ws .tab_ws {
+  color: white;
+  background-position: 45 -23;
+}
diff --git a/util/less/test/less-test.js b/util/less/test/less-test.js
new file mode 100644
index 0000000..ad11d00
--- /dev/null
+++ b/util/less/test/less-test.js
@@ -0,0 +1,182 @@
+var path = require('path'),
+    fs = require('fs'),
+    sys = require('util');
+
+var less = require('../lib/less');
+var stylize = require('../lib/less/lessc_helper').stylize;
+
+var oneTestOnly = process.argv[2];
+
+var totalTests = 0,
+    failedTests = 0,
+    passedTests = 0;
+
+less.tree.functions.add = function (a, b) {
+    return new(less.tree.Dimension)(a.value + b.value);
+};
+less.tree.functions.increment = function (a) {
+    return new(less.tree.Dimension)(a.value + 1);
+};
+less.tree.functions._color = function (str) {
+    if (str.value === "evil red") { return new(less.tree.Color)("600") }
+};
+
+sys.puts("\n" + stylize("LESS", 'underline') + "\n");
+
+runTestSet({relativeUrls: true});
+
+runTestSet(null, "errors/", function(name, err, compiledLess, doReplacements) {
+    fs.readFile(path.join('test/less/', name) + '.txt', 'utf8', function (e, expectedErr) {
+        sys.print("- " + name + ": ");
+        expectedErr = doReplacements(expectedErr, 'test/less/errors/');
+        if (!err) {
+            if (compiledLess) {
+                fail("No Error", 'red');
+            } else {
+                fail("No Error, No Output");
+            }
+        } else {
+            var errMessage = less.formatError(err);
+            if (errMessage === expectedErr) {
+                ok('OK');                    
+            } else {
+                difference("FAIL", expectedErr, errMessage);
+            }
+        }
+        sys.puts("");
+    });}, null, function(input, directory) {
+        return input.replace(
+            "{path}", path.join(process.cwd(), "/test/less/errors/"))
+            .replace("{pathrel}", path.join("test", "less", "errors/"))
+            .replace(/\r\n/g, '\n');
+    });
+
+runTestSet({dumpLineNumbers: 'comments'}, "debug/", null,
+           function(name) { return name + '-comments'; });
+runTestSet({dumpLineNumbers: 'mediaquery'}, "debug/", null,
+           function(name) { return name + '-mediaquery'; });
+runTestSet({dumpLineNumbers: 'all'}, "debug/", null,
+           function(name) { return name + '-all'; });
+runTestSet({relativeUrls: false, rootpath: "folder (1)/"}, "static-urls/");
+
+function globalReplacements(input, directory) {
+    var p = path.join(process.cwd(), directory),
+        pathimport = path.join(process.cwd(), directory + "import/"),
+        pathesc = p.replace(/[.:\/]/g, '\\$&'),
+        pathimportesc = pathimport.replace(/[.:\/]/g, '\\$&');
+
+    return input.replace(/\{path\}/g, p)
+            .replace(/\{pathesc\}/g, pathesc)
+            .replace(/\{pathimport\}/g, pathimport)
+            .replace(/\{pathimportesc\}/g, pathimportesc)
+            .replace(/\r\n/g, '\n');
+}
+
+function runTestSet(options, foldername, verifyFunction, nameModifier, doReplacements) {
+    foldername = foldername || "";
+
+    if(!doReplacements)
+        doReplacements = globalReplacements;
+
+    fs.readdirSync(path.join('test/less/', foldername)).forEach(function (file) {
+        if (! /\.less/.test(file)) { return }
+        
+        var name = foldername + path.basename(file, '.less');
+        
+        if (oneTestOnly && name !== oneTestOnly) { return; }
+        
+        totalTests++;
+
+        toCSS(options, path.join('test/less/', foldername + file), function (err, less) {
+
+            if (verifyFunction) {
+                return verifyFunction(name, err, less, doReplacements);
+            }
+            var css_name = name;
+            if(nameModifier) css_name=nameModifier(name);
+            fs.readFile(path.join('test/css', css_name) + '.css', 'utf8', function (e, css) {
+                sys.print("- " + css_name + ": ")
+                
+                css = css && doReplacements(css, 'test/less/' + foldername);
+                if (less === css) { ok('OK'); }
+                else if (err) {
+                    fail("ERROR: " + (err && err.message));
+                } else {
+                    difference("FAIL", css, less);
+                }
+                sys.puts("");
+            });
+        });
+    });
+}
+
+function diff(left, right) {
+    sys.puts("");
+    require('diff').diffLines(left, right).forEach(function(item) {
+      if(item.added || item.removed) {
+        sys.print(stylize(item.value, item.added ? 'green' : 'red'));
+      } else {
+        sys.print(item.value);
+      }
+    });
+}
+
+function fail(msg) {
+    sys.print(stylize(msg, 'red'));
+    failedTests++;
+    endTest();
+}
+
+function difference(msg, left, right) {
+    sys.print(stylize(msg, 'yellow'));
+    failedTests++;
+                
+    diff(left, right);
+    endTest();
+}
+
+function ok(msg) {
+    sys.print(stylize(msg, 'green'));
+    passedTests++;
+    endTest();
+}
+
+function endTest() {
+    if (failedTests + passedTests === totalTests) {
+        sys.puts("");
+        sys.puts("");
+        if (failedTests > 0) {
+            sys.print(failedTests);
+            sys.print(stylize(" Failed", "red"));
+            sys.print(", " + passedTests + " passed");
+        } else {
+            sys.print(stylize("All Passed ", "green"));
+            sys.print(passedTests + " run");
+        }
+    }
+}
+
+function toCSS(options, path, callback) {
+    var tree, css;
+    options = options || {};
+    fs.readFile(path, 'utf8', function (e, str) {
+        if (e) { return callback(e) }
+        
+        options.paths = [require('path').dirname(path)];
+        options.filename = require('path').resolve(process.cwd(), path);
+        options.optimization = options.optimization || 0;
+
+        new(less.Parser)(options).parse(str, function (err, tree) {
+            if (err) {
+                callback(err);
+            } else {
+                try {
+                    css = tree.toCSS();
+                    callback(null, css);
+                } catch (e) {
+                    callback(e);
+                }
+            }
+        });
+    });
+}
diff --git a/util/less/test/less/charsets.less b/util/less/test/less/charsets.less
new file mode 100644
index 0000000..550d40e
--- /dev/null
+++ b/util/less/test/less/charsets.less
@@ -0,0 +1,3 @@
+ at charset "UTF-8";
+
+ at import "import/import-charset-test";
\ No newline at end of file
diff --git a/util/less/test/less/colors.less b/util/less/test/less/colors.less
new file mode 100644
index 0000000..9ec78f9
--- /dev/null
+++ b/util/less/test/less/colors.less
@@ -0,0 +1,92 @@
+#yelow {
+  #short {
+    color: #fea;
+  }
+  #long {
+    color: #ffeeaa;
+  }
+  #rgba {
+    color: rgba(255, 238, 170, 0.1);
+  }
+  #argb {
+    color: argb(rgba(255, 238, 170, 0.1));
+  }
+}
+
+#blue {
+  #short {
+    color: #00f;
+  }
+  #long {
+    color: #0000ff;
+  }
+  #rgba {
+    color: rgba(0, 0, 255, 0.1);
+  }
+  #argb {
+    color: argb(rgba(0, 0, 255, 0.1));
+  }
+}
+
+#alpha #hsla {
+    color: hsla(11, 20%, 20%, 0.6);
+}
+
+#overflow {
+  .a { color: #111111 - #444444; } // #000000
+  .b { color: #eee + #fff; } // #ffffff
+  .c { color: #aaa * 3; } // #ffffff
+  .d { color: #00ee00 + #009900; } // #00ff00
+}
+
+#grey {
+  color: rgb(200, 200, 200);
+}
+
+#333333 {
+  color: rgb(20%, 20%, 20%);
+}
+
+#808080 {
+  color: hsl(50, 0%, 50%);
+}
+
+#00ff00 {
+  color: hsl(120, 100%, 50%);
+}
+
+.lightenblue {
+    color: lighten(blue, 10%);
+}
+
+.darkenblue {
+    color: darken(blue, 10%);
+}
+
+.unknowncolors {
+    color: blue2;
+    border: 2px solid superred;
+}
+
+.transparent {
+    color: transparent;
+    background-color: rgba(0, 0, 0, 0);
+}
+#alpha {
+    @colorvar: rgba(150, 200, 150, 0.7);
+    #fromvar {
+        opacity: alpha(@colorvar);
+    }
+    #short {
+        opacity: alpha(#aaa);
+    }
+    #long {
+        opacity: alpha(#bababa);
+    }
+    #rgba {
+        opacity: alpha(rgba(50, 120, 95, 0.2));
+    }
+    #hsl {
+        opacity: alpha(hsl(120, 100%, 50%));
+    }
+}
diff --git a/util/less/test/less/comments.less b/util/less/test/less/comments.less
new file mode 100644
index 0000000..85007c4
--- /dev/null
+++ b/util/less/test/less/comments.less
@@ -0,0 +1,77 @@
+/******************\
+*                  *
+*  Comment Header  *
+*                  *
+\******************/
+
+/*
+
+    Comment
+
+*/
+
+/*
+ * Comment Test
+ *
+ * - cloudhead (http://cloudhead.net)
+ *
+ */
+
+////////////////
+ at var: "content";
+////////////////
+
+/* Colors
+ * ------
+ *   #EDF8FC (background blue)
+ *   #166C89 (darkest blue)
+ *
+ * Text:
+ *   #333 (standard text) // A comment within a comment!
+ *   #1F9EC9 (standard link)
+ *
+ */
+
+/* @group Variables
+------------------- */
+#comments /* boo */ {
+  /**/ // An empty comment
+  color: red; /* A C-style comment */
+  background-color: orange; // A little comment
+  font-size: 12px;
+
+  /* lost comment */ content: @var;
+
+  border: 1px solid black;
+
+  // padding & margin //
+  padding: 0; // }{ '"
+  margin: 2em;
+} //
+
+/* commented out
+  #more-comments {
+    color: grey;
+  }
+*/
+
+.selector /* .with */, .lots, /* of */ .comments {
+  color: grey, /* blue */ orange;
+  -webkit-border-radius: 2px /* webkit only */;
+  -moz-border-radius: 2px * 4 /* moz only with operation */;
+}
+
+.mixin_def_with_colors(@a: white, // in
+       @b: 1px //put in @b - causes problems! --->
+	   ) // the
+	   when (@a = white) {
+	.test {
+	    color: @b;
+	}
+}
+.mixin_def_with_colors();
+
+#last { color: blue }
+//
+
+/*  *//* { *//*  *//*  *//*  */#div { color:#A33; }/* } */
diff --git a/util/less/test/less/css-3.less b/util/less/test/less/css-3.less
new file mode 100644
index 0000000..dc92f20
--- /dev/null
+++ b/util/less/test/less/css-3.less
@@ -0,0 +1,113 @@
+.comma-delimited {
+  text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
+  -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset,
+    0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
+}
+ at font-face {
+  font-family: Headline;
+  unicode-range: U+??????, U+0???, U+0-7F, U+A5;
+}
+.other {
+  -moz-transform: translate(0, 11em) rotate(-90deg);
+  transform: rotateX(45deg);
+}
+.item[data-cra_zy-attr1b-ut3=bold] {
+  font-weight: bold;
+}
+p:not([class*="lead"]) {
+  color: black;
+}
+
+input[type="text"].class#id[attr=32]:not(1) {
+  color: white;
+}
+
+div#id.class[a=1][b=2].class:not(1) {
+  color: white;
+}
+
+ul.comma > li:not(:only-child)::after {
+  color: white;
+}
+
+ol.comma > li:nth-last-child(2)::after {
+  color: white;
+}
+
+li:nth-child(4n+1),
+li:nth-child(-5n),
+li:nth-child(-n+2) {
+  color: white;
+}
+
+a[href^="http://"] {
+  color: black;
+}
+
+a[href$="http://"] {
+  color: black;
+}
+
+form[data-disabled] {
+  color: black;
+}
+
+p::before {
+  color: black;
+}
+
+#issue322 {
+  -webkit-animation: anim2 7s infinite ease-in-out;
+}
+
+ at -webkit-keyframes frames {
+  0% { border: 1px }
+  5.5% { border: 2px }
+  100% { border: 3px }
+}
+
+ at keyframes fontbulger1 {
+  to {
+    font-size: 15px;
+  }
+  from,to {
+    font-size: 12px;
+  }
+  0%,100% {
+    font-size: 12px;
+  }
+}
+
+.units {
+  font: 1.2rem/2rem;
+  font: 8vw/9vw;
+  font: 10vh/12vh;
+  font: 12vm/15vm;
+  font: 12vmin/15vmin;
+  font: 1.2ch/1.5ch;
+}
+
+ at supports ( box-shadow: 2px 2px 2px black ) or
+          ( -moz-box-shadow: 2px 2px 2px black ) {
+  .outline {
+    box-shadow: 2px 2px 2px black;
+    -moz-box-shadow: 2px 2px 2px black;
+  }
+}
+
+ at -x-document url-prefix(""github.com"") {
+  h1 {
+    color: red;
+  }
+}
+
+ at viewport {
+  font-size: 10px;
+}
+ at namespace foo url(http://www.example.com);
+
+foo|h1 { color: blue; }
+foo|* { color: yellow; }
+|h1 { color: red; }
+*|h1 { color: green; }
+h1 { color: green; }
\ No newline at end of file
diff --git a/util/less/test/less/css-escapes.less b/util/less/test/less/css-escapes.less
new file mode 100644
index 0000000..6a4b283
--- /dev/null
+++ b/util/less/test/less/css-escapes.less
@@ -0,0 +1,33 @@
+ at ugly: fuchsia;
+
+.escape\|random\|char {
+	color: red;
+}
+
+.mixin\!tUp {
+	font-weight: bold;
+}
+
+// class="404"
+.\34 04 {
+	background: red;
+	
+	strong {
+		color: @ugly;
+		.mixin\!tUp;
+	}
+}
+
+.trailingTest\+ {
+	color: red;
+}
+
+/* This hideous test of hideousness checks for the selector "blockquote" with various permutations of hex escapes */
+\62\6c\6f \63 \6B \0071 \000075o\74 e {
+	color: silver;
+}
+
+[ng\:cloak],
+ng\:form {
+  display: none;
+}
diff --git a/util/less/test/less/css.less b/util/less/test/less/css.less
new file mode 100644
index 0000000..afeebb3
--- /dev/null
+++ b/util/less/test/less/css.less
@@ -0,0 +1,102 @@
+ at charset "utf-8";
+div { color: black; }
+div { width: 99%; }
+
+* {
+  min-width: 45em;
+}
+
+h1, h2 > a > p, h3 {
+  color: none;
+}
+
+div.class {
+  color: blue;
+}
+
+div#id {
+  color: green;
+}
+
+.class#id {
+  color: purple;
+}
+
+.one.two.three {
+  color: grey;
+}
+
+ at media print {
+  font-size: 3em;
+}
+
+ at media screen {
+  font-size: 10px;
+}
+
+ at font-face {
+  font-family: 'Garamond Pro';
+}
+
+a:hover, a:link {
+  color: #999;
+}
+
+p, p:first-child {
+  text-transform: none;
+}
+
+q:lang(no) {
+  quotes: none;
+}
+
+p + h1 {
+  font-size: +2.2em;
+}
+
+#shorthands {
+  border: 1px solid #000;
+  font: 12px/16px Arial;
+  font: 100%/16px Arial;
+  margin: 1px 0;
+  padding: 0 auto;
+}
+
+#more-shorthands {
+  margin: 0;
+  padding: 1px 0 2px 0;
+  font: normal small/20px 'Trebuchet MS', Verdana, sans-serif; 
+  font: 0/0 a;
+}
+
+.misc {
+  -moz-border-radius: 2px;
+  display: -moz-inline-stack;
+  width: .1em;
+  background-color: #009998;
+  background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
+  margin: ;
+  .nested-multiple {
+	multiple-semi-colons: yes;;;;;;
+  };
+  filter: alpha(opacity=100);
+}
+
+#important {
+  color: red !important;
+  width: 100%!important;
+  height: 20px ! important;
+}
+
+.def-font(@name) {
+    @font-face {
+        font-family: @name
+    }
+}
+
+.def-font(font-a);
+.def-font(font-b);
+
+.æøå {
+  margin: 0;
+}
diff --git a/util/less/test/less/debug/import/test.less b/util/less/test/less/debug/import/test.less
new file mode 100644
index 0000000..795082f
--- /dev/null
+++ b/util/less/test/less/debug/import/test.less
@@ -0,0 +1,25 @@
+ at charset "ISO-8859-1";
+
+.mixin_import1() {
+    @media all {
+        .tst {
+            color: black;
+            @media screen {
+                color: red;
+                .tst3 {
+                    color: white;
+                }
+            }
+        }
+    }
+}
+
+.mixin_import2() {
+    .tst2 {
+        color: white;
+    }
+}
+
+.tst3 {
+    color: grey;
+}
\ No newline at end of file
diff --git a/util/less/test/less/debug/linenumbers.less b/util/less/test/less/debug/linenumbers.less
new file mode 100644
index 0000000..172ba02
--- /dev/null
+++ b/util/less/test/less/debug/linenumbers.less
@@ -0,0 +1,23 @@
+ at charset "UTF-8";
+
+ at import "import/test.less";
+
+.start() {
+  .test2 {
+      color: red;
+  }
+}
+
+.mix() {
+    color: black;
+}
+
+.test1 {
+  .mix();
+}
+
+.start();
+
+.mixin_import1();
+
+.mixin_import2();
\ No newline at end of file
diff --git a/util/less/test/less/errors/bad-variable-declaration1.less b/util/less/test/less/errors/bad-variable-declaration1.less
new file mode 100644
index 0000000..c2dc6ac
--- /dev/null
+++ b/util/less/test/less/errors/bad-variable-declaration1.less
@@ -0,0 +1 @@
+@@demo: "hi";
\ No newline at end of file
diff --git a/util/less/test/less/errors/bad-variable-declaration1.txt b/util/less/test/less/errors/bad-variable-declaration1.txt
new file mode 100644
index 0000000..9dd72a2
--- /dev/null
+++ b/util/less/test/less/errors/bad-variable-declaration1.txt
@@ -0,0 +1,2 @@
+ParseError: Syntax Error on line 1 in {path}bad-variable-declaration1.less:1:0
+1 @@demo: "hi";
diff --git a/util/less/test/less/errors/comment-in-selector.less b/util/less/test/less/errors/comment-in-selector.less
new file mode 100644
index 0000000..a7d2639
--- /dev/null
+++ b/util/less/test/less/errors/comment-in-selector.less
@@ -0,0 +1 @@
+#gaga /* Comment */ span { color: red }
\ No newline at end of file
diff --git a/util/less/test/less/errors/comment-in-selector.txt b/util/less/test/less/errors/comment-in-selector.txt
new file mode 100644
index 0000000..571462f
--- /dev/null
+++ b/util/less/test/less/errors/comment-in-selector.txt
@@ -0,0 +1,2 @@
+ParseError: Syntax Error on line 1 in {path}comment-in-selector.less:1:20
+1 #gaga /* Comment */ span { color: red }
diff --git a/util/less/test/less/errors/import-missing.less b/util/less/test/less/errors/import-missing.less
new file mode 100644
index 0000000..b740c11
--- /dev/null
+++ b/util/less/test/less/errors/import-missing.less
@@ -0,0 +1 @@
+ at import "file-does-not-exist.less";
\ No newline at end of file
diff --git a/util/less/test/less/errors/import-missing.txt b/util/less/test/less/errors/import-missing.txt
new file mode 100644
index 0000000..2502e09
--- /dev/null
+++ b/util/less/test/less/errors/import-missing.txt
@@ -0,0 +1,3 @@
+FileError: 'file-does-not-exist.less' wasn't found.
+ in {path}import-missing.less:1:0
+1 @import "file-does-not-exist.less";
diff --git a/util/less/test/less/errors/import-no-semi.less b/util/less/test/less/errors/import-no-semi.less
new file mode 100644
index 0000000..bf2c7f6
--- /dev/null
+++ b/util/less/test/less/errors/import-no-semi.less
@@ -0,0 +1 @@
+ at import "this-statement-is-invalid.less"
\ No newline at end of file
diff --git a/util/less/test/less/errors/import-no-semi.txt b/util/less/test/less/errors/import-no-semi.txt
new file mode 100644
index 0000000..60ae3f3
--- /dev/null
+++ b/util/less/test/less/errors/import-no-semi.txt
@@ -0,0 +1,2 @@
+ParseError: Syntax Error on line 1 in {path}import-no-semi.less:1:0
+1 @import "this-statement-is-invalid.less"
diff --git a/util/less/test/less/errors/import-subfolder1.less b/util/less/test/less/errors/import-subfolder1.less
new file mode 100644
index 0000000..4280673
--- /dev/null
+++ b/util/less/test/less/errors/import-subfolder1.less
@@ -0,0 +1 @@
+ at import "imports/import-subfolder1.less";
\ No newline at end of file
diff --git a/util/less/test/less/errors/import-subfolder1.txt b/util/less/test/less/errors/import-subfolder1.txt
new file mode 100644
index 0000000..7bfd3b3
--- /dev/null
+++ b/util/less/test/less/errors/import-subfolder1.txt
@@ -0,0 +1,3 @@
+NameError: .mixin-not-defined is undefined in {pathrel}mixin-not-defined.less:11:0
+10 
+11 .mixin-not-defined();
diff --git a/util/less/test/less/errors/import-subfolder2.less b/util/less/test/less/errors/import-subfolder2.less
new file mode 100644
index 0000000..a6b9b9c
--- /dev/null
+++ b/util/less/test/less/errors/import-subfolder2.less
@@ -0,0 +1 @@
+ at import "imports/import-subfolder2.less";
\ No newline at end of file
diff --git a/util/less/test/less/errors/import-subfolder2.txt b/util/less/test/less/errors/import-subfolder2.txt
new file mode 100644
index 0000000..62e0bab
--- /dev/null
+++ b/util/less/test/less/errors/import-subfolder2.txt
@@ -0,0 +1,2 @@
+ParseError: missing opening `{` in {pathrel}parse-error-curly-bracket.less:1:1
+1 }}
diff --git a/util/less/test/less/errors/imports/import-subfolder1.less b/util/less/test/less/errors/imports/import-subfolder1.less
new file mode 100644
index 0000000..24ec053
--- /dev/null
+++ b/util/less/test/less/errors/imports/import-subfolder1.less
@@ -0,0 +1 @@
+ at import "subfolder/mixin-not-defined.less";
\ No newline at end of file
diff --git a/util/less/test/less/errors/imports/import-subfolder2.less b/util/less/test/less/errors/imports/import-subfolder2.less
new file mode 100644
index 0000000..6058ad1
--- /dev/null
+++ b/util/less/test/less/errors/imports/import-subfolder2.less
@@ -0,0 +1 @@
+ at import "subfolder/parse-error-curly-bracket.less";
\ No newline at end of file
diff --git a/util/less/test/less/errors/imports/import-test.less b/util/less/test/less/errors/imports/import-test.less
new file mode 100644
index 0000000..a91ae05
--- /dev/null
+++ b/util/less/test/less/errors/imports/import-test.less
@@ -0,0 +1,4 @@
+.someclass
+{
+    font-weight: bold;
+}
\ No newline at end of file
diff --git a/util/less/test/less/errors/imports/subfolder/mixin-not-defined.less b/util/less/test/less/errors/imports/subfolder/mixin-not-defined.less
new file mode 100644
index 0000000..2bb2d09
--- /dev/null
+++ b/util/less/test/less/errors/imports/subfolder/mixin-not-defined.less
@@ -0,0 +1 @@
+ at import "../../mixin-not-defined.less";
\ No newline at end of file
diff --git a/util/less/test/less/errors/imports/subfolder/parse-error-curly-bracket.less b/util/less/test/less/errors/imports/subfolder/parse-error-curly-bracket.less
new file mode 100644
index 0000000..f37fa9d
--- /dev/null
+++ b/util/less/test/less/errors/imports/subfolder/parse-error-curly-bracket.less
@@ -0,0 +1 @@
+ at import "../../parse-error-curly-bracket.less";
\ No newline at end of file
diff --git a/util/less/test/less/errors/javascript-error.less b/util/less/test/less/errors/javascript-error.less
new file mode 100644
index 0000000..9cffb9f
--- /dev/null
+++ b/util/less/test/less/errors/javascript-error.less
@@ -0,0 +1,3 @@
+.scope {
+    var: `this.foo.toJS()`;
+}
diff --git a/util/less/test/less/errors/javascript-error.txt b/util/less/test/less/errors/javascript-error.txt
new file mode 100644
index 0000000..16dc9b7
--- /dev/null
+++ b/util/less/test/less/errors/javascript-error.txt
@@ -0,0 +1,4 @@
+SyntaxError: JavaScript evaluation error: 'TypeError: Cannot call method 'toJS' of undefined' in {path}javascript-error.less:2:26
+1 .scope {
+2     var: `this.foo.toJS()`;
+3 }
diff --git a/util/less/test/less/errors/mixed-mixin-definition-args-1.less b/util/less/test/less/errors/mixed-mixin-definition-args-1.less
new file mode 100644
index 0000000..9b0e23a
--- /dev/null
+++ b/util/less/test/less/errors/mixed-mixin-definition-args-1.less
@@ -0,0 +1,6 @@
+.mixin(@a : 4, @b : 3, @c: 2) {
+    will: fail;
+}
+.mixin-test {
+    .mixin(@a: 5; @b: 6, @c: 7);
+}
\ No newline at end of file
diff --git a/util/less/test/less/errors/mixed-mixin-definition-args-1.txt b/util/less/test/less/errors/mixed-mixin-definition-args-1.txt
new file mode 100644
index 0000000..6ceda7d
--- /dev/null
+++ b/util/less/test/less/errors/mixed-mixin-definition-args-1.txt
@@ -0,0 +1,4 @@
+SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-1.less:5:29
+4 .mixin-test {
+5     .mixin(@a: 5; @b: 6, @c: 7);
+6 }
diff --git a/util/less/test/less/errors/mixed-mixin-definition-args-2.less b/util/less/test/less/errors/mixed-mixin-definition-args-2.less
new file mode 100644
index 0000000..c970942
--- /dev/null
+++ b/util/less/test/less/errors/mixed-mixin-definition-args-2.less
@@ -0,0 +1,6 @@
+.mixin(@a : 4, @b : 3, @c: 2) {
+    will: fail;
+}
+.mixin-test {
+    .mixin(@a: 5, @b: 6; @c: 7);
+}
diff --git a/util/less/test/less/errors/mixed-mixin-definition-args-2.txt b/util/less/test/less/errors/mixed-mixin-definition-args-2.txt
new file mode 100644
index 0000000..ebb5666
--- /dev/null
+++ b/util/less/test/less/errors/mixed-mixin-definition-args-2.txt
@@ -0,0 +1,4 @@
+SyntaxError: Cannot mix ; and , as delimiter types in {path}mixed-mixin-definition-args-2.less:5:25
+4 .mixin-test {
+5     .mixin(@a: 5, @b: 6; @c: 7);
+6 }
diff --git a/util/less/test/less/errors/mixin-not-defined.less b/util/less/test/less/errors/mixin-not-defined.less
new file mode 100644
index 0000000..e2dad5c
--- /dev/null
+++ b/util/less/test/less/errors/mixin-not-defined.less
@@ -0,0 +1,11 @@
+
+.error-is-further-on() {
+}
+
+.pad-here-to-reproduce-error-in() {
+}
+
+.the-import-subfolder-test() {
+}
+
+.mixin-not-defined();
\ No newline at end of file
diff --git a/util/less/test/less/errors/mixin-not-defined.txt b/util/less/test/less/errors/mixin-not-defined.txt
new file mode 100644
index 0000000..f45de6a
--- /dev/null
+++ b/util/less/test/less/errors/mixin-not-defined.txt
@@ -0,0 +1,3 @@
+NameError: .mixin-not-defined is undefined in {path}mixin-not-defined.less:11:0
+10 
+11 .mixin-not-defined();
diff --git a/util/less/test/less/errors/mixin-not-matched.less b/util/less/test/less/errors/mixin-not-matched.less
new file mode 100644
index 0000000..be0d6b1
--- /dev/null
+++ b/util/less/test/less/errors/mixin-not-matched.less
@@ -0,0 +1,6 @@
+ at saxofon:trumpete;
+
+.mixin(saxofon) {
+}
+
+.mixin(@saxofon);
\ No newline at end of file
diff --git a/util/less/test/less/errors/mixin-not-matched.txt b/util/less/test/less/errors/mixin-not-matched.txt
new file mode 100644
index 0000000..468eb76
--- /dev/null
+++ b/util/less/test/less/errors/mixin-not-matched.txt
@@ -0,0 +1,3 @@
+RuntimeError: No matching definition was found for `.mixin(trumpete)` in {path}mixin-not-matched.less:6:0
+5 
+6 .mixin(@saxofon);
diff --git a/util/less/test/less/errors/mixin-not-matched2.less b/util/less/test/less/errors/mixin-not-matched2.less
new file mode 100644
index 0000000..14f44bf
--- /dev/null
+++ b/util/less/test/less/errors/mixin-not-matched2.less
@@ -0,0 +1,6 @@
+ at saxofon:trumpete;
+
+.mixin(@a, @b) {
+}
+
+.mixin(@a: @saxofon);
\ No newline at end of file
diff --git a/util/less/test/less/errors/mixin-not-matched2.txt b/util/less/test/less/errors/mixin-not-matched2.txt
new file mode 100644
index 0000000..2f01e74
--- /dev/null
+++ b/util/less/test/less/errors/mixin-not-matched2.txt
@@ -0,0 +1,3 @@
+RuntimeError: No matching definition was found for `.mixin(@a:trumpete)` in {path}mixin-not-matched2.less:6:0
+5 
+6 .mixin(@a: @saxofon);
diff --git a/util/less/test/less/errors/parse-error-curly-bracket.less b/util/less/test/less/errors/parse-error-curly-bracket.less
new file mode 100644
index 0000000..a2950a1
--- /dev/null
+++ b/util/less/test/less/errors/parse-error-curly-bracket.less
@@ -0,0 +1 @@
+}}
\ No newline at end of file
diff --git a/util/less/test/less/errors/parse-error-curly-bracket.txt b/util/less/test/less/errors/parse-error-curly-bracket.txt
new file mode 100644
index 0000000..bccdd98
--- /dev/null
+++ b/util/less/test/less/errors/parse-error-curly-bracket.txt
@@ -0,0 +1,2 @@
+ParseError: missing opening `{` in {path}parse-error-curly-bracket.less:1:1
+1 }}
diff --git a/util/less/test/less/errors/parse-error-missing-bracket.less b/util/less/test/less/errors/parse-error-missing-bracket.less
new file mode 100644
index 0000000..144a6ed
--- /dev/null
+++ b/util/less/test/less/errors/parse-error-missing-bracket.less
@@ -0,0 +1,2 @@
+body {
+  background-color: #fff;
diff --git a/util/less/test/less/errors/parse-error-missing-bracket.txt b/util/less/test/less/errors/parse-error-missing-bracket.txt
new file mode 100644
index 0000000..6887b23
--- /dev/null
+++ b/util/less/test/less/errors/parse-error-missing-bracket.txt
@@ -0,0 +1,2 @@
+ParseError: missing closing `}` in {path}parse-error-missing-bracket.less:3:0
+2   background-color: #fff;
diff --git a/util/less/test/less/errors/parse-error-with-import.less b/util/less/test/less/errors/parse-error-with-import.less
new file mode 100644
index 0000000..6be3de8
--- /dev/null
+++ b/util/less/test/less/errors/parse-error-with-import.less
@@ -0,0 +1,13 @@
+ at import 'import/import-test.less';
+
+body
+{
+    font-family: arial, sans-serif;
+}
+
+nonsense;
+
+.clickable
+{
+    cursor: pointer;
+}
\ No newline at end of file
diff --git a/util/less/test/less/errors/parse-error-with-import.txt b/util/less/test/less/errors/parse-error-with-import.txt
new file mode 100644
index 0000000..323ee82
--- /dev/null
+++ b/util/less/test/less/errors/parse-error-with-import.txt
@@ -0,0 +1,4 @@
+ParseError: Syntax Error on line 8 in {path}parse-error-with-import.less:8:8
+7 
+8 nonsense;
+9 
diff --git a/util/less/test/less/errors/property-ie5-hack.less b/util/less/test/less/errors/property-ie5-hack.less
new file mode 100644
index 0000000..51bf6e3
--- /dev/null
+++ b/util/less/test/less/errors/property-ie5-hack.less
@@ -0,0 +1,3 @@
+.test {
+  display/*/: block; /*sorry for IE5*/
+}
\ No newline at end of file
diff --git a/util/less/test/less/errors/property-ie5-hack.txt b/util/less/test/less/errors/property-ie5-hack.txt
new file mode 100644
index 0000000..c809140
--- /dev/null
+++ b/util/less/test/less/errors/property-ie5-hack.txt
@@ -0,0 +1,4 @@
+ParseError: Syntax Error on line 2 in {path}property-ie5-hack.less:2:2
+1 .test {
+2   display/*/: block; /*sorry for IE5*/
+3 }
diff --git a/util/less/test/less/errors/recursive-variable.less b/util/less/test/less/errors/recursive-variable.less
new file mode 100644
index 0000000..c1ca75f
--- /dev/null
+++ b/util/less/test/less/errors/recursive-variable.less
@@ -0,0 +1 @@
+ at bodyColor: darken(@bodyColor, 30%);
\ No newline at end of file
diff --git a/util/less/test/less/errors/recursive-variable.txt b/util/less/test/less/errors/recursive-variable.txt
new file mode 100644
index 0000000..87fd6fc
--- /dev/null
+++ b/util/less/test/less/errors/recursive-variable.txt
@@ -0,0 +1,2 @@
+NameError: Recursive variable definition for @bodyColor in {path}recursive-variable.less:1:19
+1 @bodyColor: darken(@bodyColor, 30%);
diff --git a/util/less/test/less/functions.less b/util/less/test/less/functions.less
new file mode 100644
index 0000000..8b80ccc
--- /dev/null
+++ b/util/less/test/less/functions.less
@@ -0,0 +1,111 @@
+#functions {
+  @var: 10;
+  @colors: #000, #fff;
+  color: _color("evil red"); // #660000
+  width: increment(15);
+  height: undefined("self");
+  border-width: add(2, 3);
+  variable: increment(@var);
+  background: linear-gradient(@colors);
+}
+
+#built-in {
+  @r: 32;
+  escaped: e("-Some::weird(#thing, y)");
+  lighten: lighten(#ff0000, 40%);
+  darken: darken(#ff0000, 40%);
+  saturate: saturate(#29332f, 20%);
+  desaturate: desaturate(#203c31, 20%);
+  greyscale: greyscale(#203c31);
+  spin-p: spin(hsl(340, 50%, 50%), 40);
+  spin-n: spin(hsl(30, 50%, 50%), -40);
+  luma-white: luma(#fff);
+  luma-black: luma(#000);
+  luma-black-alpha: luma(rgba(0,0,0,0.5));
+  luma-red: luma(#ff0000);
+  luma-green: luma(#00ff00);
+  luma-blue: luma(#0000ff);
+  luma-yellow: luma(#ffff00);
+  luma-cyan: luma(#00ffff);
+  luma-white-alpha: luma(rgba(255,255,255,0.5));
+  contrast-filter: contrast(30%);
+  contrast-white: contrast(#fff);
+  contrast-black: contrast(#000);
+  contrast-red: contrast(#ff0000);
+  contrast-green: contrast(#00ff00);
+  contrast-blue: contrast(#0000ff);
+  contrast-yellow: contrast(#ffff00);
+  contrast-cyan: contrast(#00ffff);
+  contrast-light: contrast(#fff, #111111, #eeeeee);
+  contrast-dark: contrast(#000, #111111, #eeeeee);
+  contrast-light-thresh: contrast(#fff, #111111, #eeeeee, 0.5);
+  contrast-dark-thresh: contrast(#000, #111111, #eeeeee, 0.5);
+  contrast-high-thresh: contrast(#555, #111111, #eeeeee, 0.6);
+  contrast-low-thresh: contrast(#555, #111111, #eeeeee, 0.1);
+  format: %("rgb(%d, %d, %d)", @r, 128, 64);
+  format-string: %("hello %s", "world");
+  format-multiple: %("hello %s %d", "earth", 2);
+  format-url-encode: %('red is %A', #ff0000);
+  eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64));
+  
+  unitless: unit(12px);
+  unit: unit(13px + 1px, em);
+
+  hue: hue(hsl(98, 12%, 95%));
+  saturation: saturation(hsl(98, 12%, 95%));
+  lightness: lightness(hsl(98, 12%, 95%));
+  red: red(#f00);
+  green: green(#0f0);
+  blue: blue(#00f);
+  rounded: round(@r/3);
+  rounded-two: round(@r/3, 2);
+  roundedpx: round(10px / 3);
+  roundedpx-three: round(10px / 3, 3);
+  rounded-percentage: round(10.2%);
+  ceil: ceil(10.1px);
+  floor: floor(12.9px);
+  percentage: percentage(10px / 50);
+  color: color("#ff0011");
+  tint: tint(#777777, 13);
+  tint-full: tint(#777777, 100);
+  tint-percent: tint(#777777, 13%);
+  shade: shade(#777777, 13);
+  shade-full: shade(#777777, 100);
+  shade-percent: shade(#777777, 13%);
+  
+  hsv: hsv(5, 50%, 30%);
+  hsva: hsva(3, 50%, 30%, 0.2);
+
+  mix: mix(#ff0000, #ffff00, 80);
+  mix-0: mix(#ff0000, #ffff00, 0);
+  mix-100: mix(#ff0000, #ffff00, 100);
+  mix-weightless: mix(#ff0000, #ffff00);
+
+  .is-a {
+    color: iscolor(#ddd);
+    color1: iscolor(red);
+    color2: iscolor(rgb(0, 0, 0));
+    keyword: iskeyword(hello);
+    number: isnumber(32);
+    string: isstring("hello");
+    pixel: ispixel(32px);
+    percent: ispercentage(32%);
+    em: isem(32em);
+  }
+}
+
+#alpha {
+  alpha: darken(hsla(25, 50%, 50%, 0.6), 10%);
+}
+
+#blendmodes {
+  multiply: multiply(#f60000, #f60000);
+  screen: screen(#f60000, #0000f6);
+  overlay: overlay(#f60000, #0000f6);
+  softlight: softlight(#f60000, #ffffff);
+  hardlight: hardlight(#f60000, #0000f6);
+  difference: difference(#f60000, #0000f6);
+  exclusion: exclusion(#f60000, #0000f6);
+  average: average(#f60000, #0000f6);
+  negation: negation(#f60000, #313131);
+}
diff --git a/util/less/test/less/ie-filters.less b/util/less/test/less/ie-filters.less
new file mode 100644
index 0000000..3350b65
--- /dev/null
+++ b/util/less/test/less/ie-filters.less
@@ -0,0 +1,15 @@
+ at fat: 0;
+ at cloudhead: "#000000";
+
+.nav {
+  filter: progid:DXImageTransform.Microsoft.Alpha(opacity = 20);
+  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@fat);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr=@cloudhead, GradientType=@fat);
+}
+.evalTest(@arg) {
+  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=@arg);
+}
+.evalTest1 {
+  .evalTest(30);
+  .evalTest(5);
+}
\ No newline at end of file
diff --git a/util/less/test/less/import-once.less b/util/less/test/less/import-once.less
new file mode 100644
index 0000000..5588be4
--- /dev/null
+++ b/util/less/test/less/import-once.less
@@ -0,0 +1,4 @@
+ at import-once "import/import-once-test-c";
+ at import-once "import/import-once-test-c";
+ at import-once "import/import-once-test-c.less";
+ at import-once "import/deeper/import-once-test-a";
diff --git a/util/less/test/less/import.less b/util/less/test/less/import.less
new file mode 100644
index 0000000..2a442ea
--- /dev/null
+++ b/util/less/test/less/import.less
@@ -0,0 +1,12 @@
+ at import url(http://fonts.googleapis.com/css?family=Open+Sans);
+
+ at import url(something.css) screen and (color) and (max-width: 600px);
+
+#import-test {
+  .mixin;
+  width: 10px;
+  height: @a + 10%;
+}
+ at import "import/import-test-e" screen and (max-width: 600px);
+
+ at import url("import/import-test-a.less");
diff --git a/util/less/test/less/import/deeper/import-once-test-a.less b/util/less/test/less/import/deeper/import-once-test-a.less
new file mode 100644
index 0000000..de2233d
--- /dev/null
+++ b/util/less/test/less/import/deeper/import-once-test-a.less
@@ -0,0 +1 @@
+ at import-once "../import-once-test-c";
\ No newline at end of file
diff --git a/util/less/test/less/import/import-and-relative-paths-test.less b/util/less/test/less/import/import-and-relative-paths-test.less
new file mode 100644
index 0000000..da69998
--- /dev/null
+++ b/util/less/test/less/import/import-and-relative-paths-test.less
@@ -0,0 +1,6 @@
+ at import "../css/background.css";
+ at import "import-test-d.css";
+
+ at import "imports/logo";
+ at import "imports/font";
+
diff --git a/util/less/test/less/import/import-charset-test.less b/util/less/test/less/import/import-charset-test.less
new file mode 100644
index 0000000..07a66e1
--- /dev/null
+++ b/util/less/test/less/import/import-charset-test.less
@@ -0,0 +1 @@
+ at charset "ISO-8859-1";
\ No newline at end of file
diff --git a/util/less/test/less/import/import-once-test-c.less b/util/less/test/less/import/import-once-test-c.less
new file mode 100644
index 0000000..686747a
--- /dev/null
+++ b/util/less/test/less/import/import-once-test-c.less
@@ -0,0 +1,6 @@
+
+ at c: red;
+
+#import {
+  color: @c;
+}
diff --git a/util/less/test/less/import/import-test-a.less b/util/less/test/less/import/import-test-a.less
new file mode 100644
index 0000000..b3b3b8f
--- /dev/null
+++ b/util/less/test/less/import/import-test-a.less
@@ -0,0 +1,3 @@
+ at import "import-test-b.less";
+ at a: 20%;
+ at import "urls.less";
\ No newline at end of file
diff --git a/util/less/test/less/import/import-test-b.less b/util/less/test/less/import/import-test-b.less
new file mode 100644
index 0000000..ce2d35a
--- /dev/null
+++ b/util/less/test/less/import/import-test-b.less
@@ -0,0 +1,8 @@
+ at import "import-test-c";
+
+ at b: 100%;
+
+.mixin {
+  height: 10px;
+  color: @c;
+}
diff --git a/util/less/test/less/import/import-test-c.less b/util/less/test/less/import/import-test-c.less
new file mode 100644
index 0000000..686747a
--- /dev/null
+++ b/util/less/test/less/import/import-test-c.less
@@ -0,0 +1,6 @@
+
+ at c: red;
+
+#import {
+  color: @c;
+}
diff --git a/util/less/test/less/import/import-test-d.css b/util/less/test/less/import/import-test-d.css
new file mode 100644
index 0000000..30575f0
--- /dev/null
+++ b/util/less/test/less/import/import-test-d.css
@@ -0,0 +1 @@
+#css { color: yellow; }
diff --git a/util/less/test/less/import/import-test-e.less b/util/less/test/less/import/import-test-e.less
new file mode 100644
index 0000000..98b84b0
--- /dev/null
+++ b/util/less/test/less/import/import-test-e.less
@@ -0,0 +1,2 @@
+
+body { width: 100% }
diff --git a/util/less/test/less/import/imports/font.less b/util/less/test/less/import/imports/font.less
new file mode 100644
index 0000000..5abb7e7
--- /dev/null
+++ b/util/less/test/less/import/imports/font.less
@@ -0,0 +1,8 @@
+ at font-face {
+	font-family: xecret;
+	src: url('../assets/xecret.ttf');
+}
+
+#secret {
+	font-family: xecret, sans-serif;
+}
diff --git a/util/less/test/less/import/imports/logo.less b/util/less/test/less/import/imports/logo.less
new file mode 100644
index 0000000..22893a2
--- /dev/null
+++ b/util/less/test/less/import/imports/logo.less
@@ -0,0 +1,5 @@
+#logo {
+  width: 100px;
+  height: 100px;
+  background: url('../assets/logo.png');
+}
diff --git a/util/less/test/less/import/urls.less b/util/less/test/less/import/urls.less
new file mode 100644
index 0000000..bb48f77
--- /dev/null
+++ b/util/less/test/less/import/urls.less
@@ -0,0 +1 @@
+// empty file showing that it loads from the relative path first
diff --git a/util/less/test/less/javascript.less b/util/less/test/less/javascript.less
new file mode 100644
index 0000000..b76859e
--- /dev/null
+++ b/util/less/test/less/javascript.less
@@ -0,0 +1,29 @@
+.eval {
+    js: `42`;
+    js: `1 + 1`;
+    js: `"hello world"`;
+    js: `[1, 2, 3]`;
+    title: `typeof process.title`;
+    ternary: `(1 + 1 == 2 ? true : false)`;
+    multiline: `(function(){var x = 1 + 1;
+           return x})()`;
+}
+.scope {
+    @foo: 42;
+    var: `this.foo.toJS()`;
+    escaped: ~`2 + 5 + 'px'`;
+}
+.vars {
+    @var: `4 + 4`;
+    width: @var;
+}
+.escape-interpol {
+    @world: "world";
+    width: ~`"hello" + " " + @{world}`;
+}
+.arrays {
+    @ary:  1, 2, 3;
+    @ary2: 1  2  3;
+    ary: `@{ary}.join(', ')`;
+    ary1: `@{ary2}.join(', ')`;
+}
diff --git a/util/less/test/less/lazy-eval.less b/util/less/test/less/lazy-eval.less
new file mode 100644
index 0000000..72b3fd4
--- /dev/null
+++ b/util/less/test/less/lazy-eval.less
@@ -0,0 +1,6 @@
+ at var: @a;
+ at a: 100%;
+
+.lazy-eval {
+  width: @var;
+}
diff --git a/util/less/test/less/media.less b/util/less/test/less/media.less
new file mode 100644
index 0000000..b401ae9
--- /dev/null
+++ b/util/less/test/less/media.less
@@ -0,0 +1,199 @@
+
+// For now, variables can't be declared inside @media blocks.
+
+ at var: 42;
+
+ at media print {
+    .class {
+        color: blue;
+        .sub {
+            width: @var;
+        }
+    }
+    .top, header > h1 {
+        color: #222 * 2;
+    }
+}
+
+ at media screen {
+    @base: 8;
+    body { max-width: @base * 60; }
+}
+
+ at media all and (device-aspect-ratio: 16/9) {
+   body { max-width: 800px; }
+}
+
+ at media all and (orientation:portrait) {
+    aside { float: none; }
+}
+
+ at media handheld and (min-width: @var), screen and (min-width: 20em) {
+    body {
+        max-width: 480px;
+    }
+}
+
+body {
+    @media print {
+        padding: 20px;
+
+        header {
+            background-color: red;
+        }
+
+        @media (orientation:landscape) {
+            margin-left: 20px;
+        }
+    }
+}
+
+ at media screen {
+  .sidebar {
+    width: 300px;
+    @media (orientation: landscape) {
+      width: 500px;
+    }
+  }
+}
+
+ at media a {
+  .first {
+    @media b {
+      .second {
+        .third {
+          width: 300px;
+          @media c {
+            width: 500px;
+          }
+        }
+        .fourth {
+          width: 3;
+        }
+      }
+    }
+  }
+}
+
+body {
+    @media a, b and c {
+        width: 95%;
+
+        @media x, y {
+            width: 100%;
+        }
+    }
+}
+
+.mediaMixin(@fallback: 200px) {
+    background: black;
+
+    @media handheld {
+        background: white;
+
+        @media (max-width: @fallback) {
+            background: red;
+        }
+    }
+}
+
+.a {
+  .mediaMixin(100px);
+}
+
+.b {
+  .mediaMixin();
+}
+ at smartphone: ~"only screen and (max-width: 200px)";
+ at media @smartphone {
+  width: 480px;
+}
+
+ at media print {
+  @page :left {
+    margin: 0.5cm;
+  }
+  @page :right {
+    margin: 0.5cm;
+  }
+  @page Test:first {
+    margin: 1cm;
+  }
+  @page :first {
+    size: 8.5in 11in;
+	@top-left {
+      margin: 1cm;
+    }
+    @top-left-corner {
+      margin: 1cm;
+    }
+    @top-center {
+      margin: 1cm;
+    }
+    @top-right {
+      margin: 1cm;
+    }
+    @top-right-corner {
+      margin: 1cm;
+    }
+    @bottom-left {
+      margin: 1cm;
+    }
+    @bottom-left-corner {
+      margin: 1cm;
+    }
+    @bottom-center {
+      margin: 1cm;
+    }
+    @bottom-right {
+      margin: 1cm;
+    }
+    @bottom-right-corner {
+      margin: 1cm;
+    }
+    @left-top {
+      margin: 1cm;
+    }
+    @left-middle {
+      margin: 1cm;
+    }
+    @left-bottom {
+      margin: 1cm;
+    }
+    @right-top {
+      margin: 1cm;
+    }
+    @right-middle {
+      content: "Page " counter(page);
+    }
+    @right-bottom {
+      margin: 1cm;
+    }
+  }
+}
+
+ at media (-webkit-min-device-pixel-ratio: 2), (min--moz-device-pixel-ratio: 2), (-o-min-device-pixel-ratio: 2/1), (min-resolution: 2dppx), (min-resolution: 128dpcm) {
+  .b {
+    background: red;
+  }
+}
+
+.bg() {
+    background: red;
+
+    @media (max-width: 500px) {
+        background: green;
+    }
+}
+
+body {
+    .bg();
+}
+
+ at bpMedium: 1000px;
+ at media (max-width: @bpMedium) {
+    body {        
+        .bg();
+        background: blue;
+    }
+}
diff --git a/util/less/test/less/mixins-args.less b/util/less/test/less/mixins-args.less
new file mode 100644
index 0000000..f71bdce
--- /dev/null
+++ b/util/less/test/less/mixins-args.less
@@ -0,0 +1,167 @@
+.mixin (@a: 1px, @b: 50%) {
+  width: @a * 5;
+  height: @b - 1%;
+}
+
+.mixina (@style, @width, @color: black) {
+    border: @width @style @color;
+}
+
+.mixiny
+(@a: 0, @b: 0) {
+  margin: @a;
+  padding: @b;
+}
+
+.hidden() {
+  color: transparent; // asd
+}
+
+#hidden {
+  .hidden;
+}
+
+#hidden1 {
+  .hidden();
+}
+
+.two-args {
+  color: blue;
+  .mixin(2px, 100%);
+  .mixina(dotted, 2px);
+}
+
+.one-arg {
+  .mixin(3px);
+}
+
+.no-parens {
+  .mixin;
+}
+
+.no-args {
+  .mixin();
+}
+
+.var-args {
+  @var: 9;
+  .mixin(@var, @var * 2);
+}
+
+.multi-mix {
+  .mixin(2px, 30%);
+  .mixiny(4, 5);
+}
+
+.maxa(@arg1: 10, @arg2: #f00) {
+  padding: @arg1 * 2px;
+  color: @arg2;
+}
+
+body {
+  .maxa(15);
+}
+
+ at glob: 5;
+.global-mixin(@a:2) {
+  width: @glob + @a;
+}
+
+.scope-mix {
+  .global-mixin(3);
+}
+
+.nested-ruleset (@width: 200px) {
+    width: @width;
+    .column { margin: @width; }
+}
+.content {
+    .nested-ruleset(600px);
+}
+
+//
+
+.same-var-name2(@radius) {
+  radius: @radius;
+}
+.same-var-name(@radius) {
+  .same-var-name2(@radius);
+}
+#same-var-name {
+  .same-var-name(5px);
+}
+
+//
+
+.var-inside () {
+    @var: 10px;
+    width: @var;
+}
+#var-inside { .var-inside; }
+
+.mixin-arguments (@width: 0px, ...) {
+    border: @arguments;
+    width: @width;
+}
+
+.arguments {
+    .mixin-arguments(1px, solid, black);
+}
+.arguments2 {
+    .mixin-arguments();
+}
+.arguments3 {
+    .mixin-arguments;
+}
+
+.mixin-arguments2 (@width, @rest...) {
+    border: @arguments;
+    rest: @rest;
+    width: @width;
+}
+.arguments4 {
+    .mixin-arguments2(0, 1, 2, 3, 4);
+}
+
+// Edge cases
+
+.edge-case {
+    .mixin-arguments("{");
+}
+
+// semi-colon vs comma for delimiting
+
+.mixin-takes-one(@a) {
+    one: @a;
+}
+
+.mixin-takes-two(@a; @b) {
+    one: @a;
+    two: @b;
+}
+
+.comma-vs-semi-colon {
+    .mixin-takes-two(@a : a; @b : b, c);
+    .mixin-takes-two(@a : d, e; @b : f);
+    .mixin-takes-one(@a: g);
+    .mixin-takes-one(@a : h;);
+    .mixin-takes-one(i);
+    .mixin-takes-one(j;);
+    .mixin-takes-two(k, l);
+    .mixin-takes-one(m, n;);
+    .mixin-takes-two(o, p; q);
+    .mixin-takes-two(r, s; t;);
+}
+
+.mixin-conflict(@a:defA, @b:defB, @c:defC) {
+  three: @a, @b, @c;
+}
+
+.mixin-conflict(@a:defA, @b:defB, @c:defC, @d:defD) {
+  four: @a, @b, @c, @d;
+}
+
+#named-conflict {
+  .mixin-conflict(11, 12, 13, @a:a);
+  .mixin-conflict(@a:a, 21, 22, 23);
+}
\ No newline at end of file
diff --git a/util/less/test/less/mixins-closure.less b/util/less/test/less/mixins-closure.less
new file mode 100644
index 0000000..01251d2
--- /dev/null
+++ b/util/less/test/less/mixins-closure.less
@@ -0,0 +1,26 @@
+.scope {
+    @var: 99px;
+    .mixin () {
+        width: @var;
+    }
+}
+
+.class {
+    .scope > .mixin;
+}
+
+.overwrite {
+    @var: 0px;
+    .scope > .mixin;
+}
+
+.nested {
+    @var: 5px;
+    .mixin () {
+        width: @var;    
+    }
+    .class {
+        @var: 10px;    
+       .mixin; 
+    }    
+}
diff --git a/util/less/test/less/mixins-guards.less b/util/less/test/less/mixins-guards.less
new file mode 100644
index 0000000..4414e32
--- /dev/null
+++ b/util/less/test/less/mixins-guards.less
@@ -0,0 +1,124 @@
+
+// Stacking, functions..
+
+.light (@a) when (lightness(@a) > 50%) {
+  color: white;
+}
+.light (@a) when (lightness(@a) < 50%) {
+  color: black;
+}
+.light (@a) {
+  margin: 1px;
+}
+
+.light1 { .light(#ddd) }
+.light2 { .light(#444) }
+
+// Arguments against each other
+
+.max (@a, @b) when (@a > @b) {
+  width: @a;
+}
+.max (@a, @b) when (@a < @b) {
+  width: @b;
+}
+
+.max1 { .max(3, 6) }
+.max2 { .max(8, 1) }
+
+// Globals inside guards
+
+ at g: auto;
+
+.glob (@a) when (@a = @g) {
+  margin: @a @g;
+}
+.glob1 { .glob(auto) }
+
+// Other operators
+
+.ops (@a) when (@a >= 0) {
+  height: gt-or-eq;
+}
+.ops (@a) when (@a =< 0) {
+  height: lt-or-eq;
+}
+.ops (@a) when not(@a = 0) {
+  height: not-eq;
+}
+.ops1 { .ops(0) }
+.ops2 { .ops(1) }
+.ops3 { .ops(-1) }
+
+// Scope and default values
+
+ at a: auto;
+
+.default (@a: inherit) when (@a = inherit) {
+  content: default;
+}
+.default1 { .default }
+
+// true & false keywords
+.test (@a) when (@a) {
+    content: "true.";
+}
+.test (@a) when not (@a) {
+    content: "false.";
+}
+
+.test1 { .test(true) }
+.test2 { .test(false) }
+.test3 { .test(1) }
+.test4 { .test(boo) }
+.test5 { .test("true") }
+
+// Boolean expressions
+
+.bool () when (true) and (false)                             { content: true and false } // FALSE
+.bool () when (true) and (true)                              { content: true and true } // TRUE
+.bool () when (true)                                         { content: true } // TRUE
+.bool () when (false) and (false)                            { content: true } // FALSE
+.bool () when (false), (true)                                { content: false, true } // TRUE
+.bool () when (false) and (true) and (true),  (true)         { content: false and true and true, true } // TRUE
+.bool () when (true)  and (true) and (false), (false)        { content: true and true and false, false } // FALSE
+.bool () when (false), (true) and (true)                     { content: false, true and true } // TRUE
+.bool () when (false), (false), (true)                       { content: false, false, true } // TRUE
+.bool () when (false), (false) and (true), (false)           { content: false, false and true, false } // FALSE
+.bool () when (false), (true) and (true) and (true), (false) { content: false, true and true and true, false } // TRUE
+.bool () when not (false)                                    { content: not false }
+.bool () when not (true) and not (false)                     { content: not true and not false }
+.bool () when not (true) and not (true)                      { content: not true and not true }
+.bool () when not (false) and (false), not (false)           { content: not false and false, not false }
+
+.bool1 { .bool }
+
+.equality-unit-test(@num) when (@num = 1%) {
+  test: fail;
+}
+.equality-unit-test(@num) when (@num = 2) {
+  test: pass;
+}
+.equality-units {
+  .equality-unit-test(1px);
+  .equality-unit-test(2px);
+}
+
+.colorguard(@col) when (@col = red)							{ content: is @col; }
+.colorguard(@col) when not (blue = @col)					{ content: is not blue its @col; }
+.colorguard(@col)											{}
+.colorguardtest {
+    .colorguard(red);
+	.colorguard(blue);
+	.colorguard(purple);
+}
+
+.stringguard(@str) when (@str = "theme1")					{ content: is theme1; }
+.stringguard(@str) when not ("theme2" = @str)				{ content: is not theme2; }
+.stringguard(@str) when (~"theme1" = @str)					{ content: is theme1 no quotes; }
+.stringguard(@str)											{}
+.stringguardtest {
+    .stringguard("theme1");
+	.stringguard("theme2");
+	.stringguard(theme1);
+}
\ No newline at end of file
diff --git a/util/less/test/less/mixins-important.less b/util/less/test/less/mixins-important.less
new file mode 100644
index 0000000..df1fd71
--- /dev/null
+++ b/util/less/test/less/mixins-important.less
@@ -0,0 +1,22 @@
+
+.mixin (9) {
+  border: 9 !important;  
+}
+.mixin (@a: 0) {
+  border: @a;
+  boxer: @a;
+  .inner {
+    test: @a;
+  }
+  // comment
+}
+
+.class {
+  .mixin(1);
+  .mixin(2) !important;
+  .mixin(3);
+  .mixin(4) !important;
+  .mixin(5);
+  .mixin !important;
+  .mixin(9);
+}
diff --git a/util/less/test/less/mixins-named-args.less b/util/less/test/less/mixins-named-args.less
new file mode 100644
index 0000000..afe9ad6
--- /dev/null
+++ b/util/less/test/less/mixins-named-args.less
@@ -0,0 +1,36 @@
+.mixin (@a: 1px, @b: 50%) {
+  width: @a * 5;
+  height: @b - 1%;
+  args: @arguments;
+}
+.mixin (@a: 1px, @b: 50%) when (@b > 75%){
+  text-align: center;
+}
+ 
+.named-arg {
+  color: blue;
+  .mixin(@b: 100%);
+}
+ 
+.class {
+  @var: 20%;
+  .mixin(@b: @var);
+}
+
+.all-args-wrong-args {
+  .mixin(@b: 10%, @a: 2px);
+}
+
+.mixin2 (@a: 1px, @b: 50%, @c: 50) {
+  width: @a * 5;
+  height: @b - 1%;
+  color: #000000 + @c;
+}
+
+.named-args2 {
+  .mixin2(3px, @c: 100);
+}
+
+.named-args3 {
+  .mixin2(@b: 30%, @c: #123456);
+}
\ No newline at end of file
diff --git a/util/less/test/less/mixins-nested.less b/util/less/test/less/mixins-nested.less
new file mode 100644
index 0000000..d086279
--- /dev/null
+++ b/util/less/test/less/mixins-nested.less
@@ -0,0 +1,22 @@
+.mix-inner (@var) {
+  border-width: @var;
+}
+
+.mix (@a: 10) {
+  .inner {
+    height: @a * 10;
+
+    .innest {
+      width: @a;  
+      .mix-inner(@a * 2);
+    }  
+  }
+}
+
+.class {
+  .mix(30);
+}
+
+.class2 {
+  .mix(60);
+}
diff --git a/util/less/test/less/mixins-pattern.less b/util/less/test/less/mixins-pattern.less
new file mode 100644
index 0000000..b2121e9
--- /dev/null
+++ b/util/less/test/less/mixins-pattern.less
@@ -0,0 +1,99 @@
+.mixin (...) {
+  variadic: true;
+}
+.mixin () {
+    zero: 0;
+}
+.mixin (@a: 1px) {
+    one: 1;
+}
+.mixin (@a) {
+    one-req: 1;
+}
+.mixin (@a: 1px, @b: 2px) {
+    two: 2;
+}
+
+.mixin (@a, @b, @c) {
+    three-req: 3;
+}
+
+.mixin (@a: 1px, @b: 2px, @c: 3px) {
+    three: 3;
+}
+
+.zero {
+    .mixin();
+}
+
+.one {
+    .mixin(1);
+}
+
+.two {
+    .mixin(1, 2);
+}
+
+.three {
+    .mixin(1, 2, 3);
+}
+
+//
+
+.mixout ('left') {
+    left: 1;
+}
+
+.mixout ('right') {
+    right: 1;
+}
+
+.left {
+    .mixout('left');
+}
+.right {
+    .mixout('right');
+}
+
+//
+
+.border (@side, @width) {
+    color: black;
+    .border-side(@side, @width);
+}
+.border-side (left, @w) {
+    border-left: @w;
+}
+.border-side (right, @w) {
+    border-right: @w;
+}
+
+.border-right {
+    .border(right, 4px);
+}
+.border-left {
+    .border(left, 4px);
+}
+
+//
+
+
+.border-radius (@r) {
+    both: @r * 10;
+}
+.border-radius (@r, left) {
+    left: @r;
+}
+.border-radius (@r, right) {
+    right: @r;
+}
+
+.only-right {
+    .border-radius(33, right);
+}
+.only-left {
+    .border-radius(33, left);
+}
+.left-right {
+    .border-radius(33);
+}
diff --git a/util/less/test/less/mixins.less b/util/less/test/less/mixins.less
new file mode 100644
index 0000000..9e38243
--- /dev/null
+++ b/util/less/test/less/mixins.less
@@ -0,0 +1,114 @@
+.mixin { border: 1px solid black; }
+.mixout { border-color: orange; }
+.borders { border-style: dashed; }
+
+#namespace {
+  .borders {
+    border-style: dotted;
+  }
+  .biohazard {
+    content: "death";
+    .man {
+      color: transparent;
+    }
+  }
+}
+#theme {
+  > .mixin {
+    background-color: grey;
+  }
+}
+#container {
+  color: black;
+  .mixin;
+  .mixout;
+  #theme > .mixin;
+}
+
+#header {
+  .milk {
+    color: white;
+    .mixin;
+    #theme > .mixin;
+  }
+  #cookie {
+    .chips {
+      #namespace .borders;
+      .calories {
+        #container;
+      }
+    }
+    .borders;
+  }
+}
+.secure-zone { #namespace .biohazard .man; }
+.direct {
+  #namespace > .borders;
+}
+
+.bo, .bar {
+    width: 100%;
+}
+.bo {
+    border: 1px;
+}
+.ar.bo.ca {
+    color: black;
+}
+.jo.ki {
+    background: none;
+}
+.amp {
+    &.support {
+        color: orange;
+    }
+}
+.extended {
+    .bo;
+    .jo.ki;
+    .amp.support;
+}
+.foo .bar {
+  .bar;
+}
+.has_parents() {
+  & .underParents {
+    color: red;
+  }
+}
+.has_parents();
+.parent {
+  .has_parents();
+}
+.margin_between(@above, @below) {
+     * + & { margin-top: @above; }
+     legend + & { margin-top: 0; }
+     & + * { margin-top: @below; }
+}
+h1 { .margin_between(25px, 10px); }
+h2 { .margin_between(20px, 8px); }
+h3 { .margin_between(15px, 5px); }
+
+.mixin_def(@url, @position){
+    background-image: @url;
+    background-position: @position;
+}
+.error{
+  @s: "/";
+  .mixin_def( "@{s}a.png", center center);
+}
+.recursion() {
+  color: black;
+}
+.test-rec {
+  .recursion {
+    .recursion();
+  }
+}
+.paddingFloat(@padding) { padding-left: @padding; }
+
+.button { 
+    .paddingFloat(((10px + 12) * 2));
+
+    &.large { .paddingFloat((10em * 2) * 2); }
+}
diff --git a/util/less/test/less/operations.less b/util/less/test/less/operations.less
new file mode 100644
index 0000000..46b0aa3
--- /dev/null
+++ b/util/less/test/less/operations.less
@@ -0,0 +1,62 @@
+#operations {
+  color: #110000 + #000011 + #001100; // #111111
+  height: 10px / 2px + 6px - 1px * 2; // 9px
+  width: 2 * 4 - 5em; // 3em
+  .spacing {
+    height: 10px / 2px+6px-1px*2;
+    width: 2  * 4-5em;
+  }
+  substraction: 20 - 10 - 5 - 5; // 0
+  division: 20 / 5 / 4; // 1
+}
+
+ at x: 4;
+ at y: 12em;
+
+.with-variables {
+  height: @x + @y; // 16em
+  width: 12 + @y; // 24em
+  size: 5cm - @x; // 1cm
+}
+
+.with-functions {
+  color: rgb(200, 200, 200) / 2;
+  color: 2 * hsl(0, 50%, 50%);
+  color: rgb(10, 10, 10) + hsl(0, 50%, 50%);
+}
+
+ at z: -2;
+
+.negative {
+  height: 2px + @z; // 0px
+  width: 2px - @z; // 4px
+}
+
+.shorthands {
+  padding: -1px 2px 0 -4px; //
+}
+
+.rem-dimensions {
+  font-size: 20rem / 5 + 1.5rem; // 5.5rem
+}
+
+.colors {
+  color: #123; // #112233
+  border-color: #234 + #111111; // #334455
+  background-color: #222222 - #fff; // #000000
+  .other {
+    color: 2 * #111; // #222222
+    border-color: #333333 / 3 + #111; // #222222
+  }
+}
+
+.negations {
+    @var: 4px;
+    variable: - at var; // 4
+    variable1: - at var + @var; // 0
+    variable2: @var + - at var; // 0
+    variable3: @var - - at var; // 8
+    variable4: - at var - - at var; // 0
+    paren: -(@var); // -4px
+    paren2: -(2 + 2) * - at var; // 16
+}
diff --git a/util/less/test/less/parens.less b/util/less/test/less/parens.less
new file mode 100644
index 0000000..e020c7e
--- /dev/null
+++ b/util/less/test/less/parens.less
@@ -0,0 +1,26 @@
+.parens {
+  @var: 1px;
+  border: (@var * 2) solid black;
+  margin: (@var * 1) (@var + 2) (4 * 4) 3;
+  width: (6 * 6);
+  padding: 2px (6px * 6px);
+}
+
+.more-parens {
+  @var: (2 * 2);
+  padding: (2 * @var) 4 4 (@var * 1px);
+  width: (@var * @var) * 6;
+  height: (7 * 7) + (8 * 8);
+  margin: 4 * (5 + 5) / 2 - (@var * 2);
+  //margin: (6 * 6)px;
+}
+
+.nested-parens {
+  width: 2 * (4 * (2 + (1 + 6))) - 1;
+  height: ((2+3)*(2+3) / (9-4)) + 1;
+}
+
+.mixed-units {
+  margin: 2px 4em 1 5pc;
+  padding: (2px + 4px) 1em 2px 2;
+}
diff --git a/util/less/test/less/rulesets.less b/util/less/test/less/rulesets.less
new file mode 100644
index 0000000..e81192d
--- /dev/null
+++ b/util/less/test/less/rulesets.less
@@ -0,0 +1,30 @@
+#first > .one {
+  > #second .two > #deux {
+    width: 50%;
+    #third {
+      &:focus {
+        color: black;
+        #fifth {
+          > #sixth {
+            .seventh #eighth {
+              + #ninth {
+                color: purple;
+              }
+            }
+          }
+        }
+      }
+      height: 100%;
+    }
+    #fourth, #five, #six {
+      color: #110000;
+      .seven, .eight > #nine {
+        border: 1px solid black;
+      }
+      #ten {
+        color: red;
+      }
+    }
+  }
+  font-size: 2em;
+}
diff --git a/util/less/test/less/scope.less b/util/less/test/less/scope.less
new file mode 100644
index 0000000..36d3706
--- /dev/null
+++ b/util/less/test/less/scope.less
@@ -0,0 +1,79 @@
+ at x: red;
+ at x: blue;
+ at z: transparent;
+ at mix: none;
+
+.mixin {
+  @mix: #989;
+}
+ at mix: blue;
+.tiny-scope {
+  color: @mix; // #989
+  .mixin;
+}
+
+.scope1 {
+  @y: orange;
+  @z: black;
+  color: @x; // blue
+  border-color: @z; // black
+  .hidden {
+    @x: #131313;
+  }
+  .scope2 {
+    @y: red;
+    color: @x; // blue
+    .scope3 {
+      @local: white;
+      color: @y; // red
+      border-color: @z; // black
+      background-color: @local; // white
+    }
+  }
+}
+
+#namespace {
+  .scoped_mixin() {
+    @local-will-be-made-global: green;
+    .scope {
+      scoped-val: @local-will-be-made-global;
+	}
+  }
+}
+
+#namespace > .scoped_mixin();
+
+.setHeight(@h) { @height: 1024px; }
+.useHeightInMixinCall(@h) { .useHeightInMixinCall { mixin-height: @h; } }
+ at mainHeight: 50%;
+.setHeight(@mainHeight);
+.heightIsSet { height: @height; }
+.useHeightInMixinCall(@height);
+
+.importRuleset() {
+  .imported {
+    exists: true;
+  }
+}
+.importRuleset();
+.testImported {
+  .imported;
+}
+
+ at parameterDefault: 'top level';
+ at anotherVariable: 'top level';
+//mixin uses top-level variables
+.mixinNoParam(@parameter: @parameterDefault) when (@parameter = 'top level') {
+  default: @parameter;
+  scope: @anotherVariable;
+  sub-scope-only: @subScopeOnly;
+}
+
+#allAreUsedHere {
+  //redefine top-level variables in different scope
+  @parameterDefault: 'inside';
+  @anotherVariable: 'inside';
+  @subScopeOnly: 'inside';
+  //use the mixin
+  .mixinNoParam();
+}
\ No newline at end of file
diff --git a/util/less/test/less/selectors.less b/util/less/test/less/selectors.less
new file mode 100644
index 0000000..8cb8838
--- /dev/null
+++ b/util/less/test/less/selectors.less
@@ -0,0 +1,136 @@
+h1, h2, h3 {
+  a, p {
+    &:hover {
+      color: red;
+    }
+  }
+}
+
+#all { color: blue; }
+#the { color: blue; }
+#same { color: blue; }
+
+ul, li, div, q, blockquote, textarea {
+  margin: 0;
+}
+
+td {
+  margin: 0;
+  padding: 0;
+}
+
+td, input {
+  line-height: 1em;
+}
+
+a {
+  color: red;
+
+  &:hover { color: blue; }
+
+  div & { color: green; }
+
+  p & span { color: yellow; }
+}
+
+.foo {
+  .bar, .baz {
+    & .qux {
+      display: block;
+    }
+    .qux & {
+      display: inline;
+    }
+	.qux& {
+	  display: inline-block;
+	}
+    .qux & .biz {
+      display: none;
+    }
+  }
+}
+
+.b {
+ &.c {
+  .a& {
+   color: red;
+  }
+ }
+}
+
+.b {
+ .c & {
+  &.a {
+   color: red;
+  }
+ }
+}
+
+.p {
+  .foo &.bar {
+    color: red;
+  }
+}
+
+.p {
+  .foo&.bar {
+    color: red;
+  }
+}
+
+.foo {
+  .foo + & {
+    background: amber;
+  }
+  & + & {
+    background: amber;
+  }
+}
+
+.foo, .bar {
+  & + & {
+    background: amber;
+  }
+}
+
+.foo, .bar {
+  a, b {
+    & > & {
+      background: amber;
+    }
+  }
+}
+
+.other ::fnord { color: red }
+.other::fnord { color: red }
+.other {
+  ::bnord {color: red }
+  &::bnord {color: red }
+}
+// selector interpolation - deprecated
+ at theme: blood;
+(~".@{theme}") {
+  color: red;
+}
+// selector interpolation - new format
+ at selector: ~".@{theme}";
+@{selector} {
+  color:red;
+}
+@{selector}red {
+  color: green;
+}
+.red {
+  #@{theme}.@{theme}&.black {
+    color:black;
+  }
+}
+ at num: 3;
+:nth-child(@{num}):nth-child(@num) {
+	second-use: deprecated;
+}
+.test {
+  &:nth-child(odd):not(:nth-child(3)) {
+    color: #ff0000;
+  }
+}
\ No newline at end of file
diff --git a/util/less/test/less/static-urls/urls.less b/util/less/test/less/static-urls/urls.less
new file mode 100644
index 0000000..b0c7de0
--- /dev/null
+++ b/util/less/test/less/static-urls/urls.less
@@ -0,0 +1,33 @@
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium),
+       url(fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+
+.comma-delimited {
+  background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+}
+.values {
+    @a: 'Trebuchet';
+    url: url(@a);
+}
+
+ at import "../import/import-and-relative-paths-test";
diff --git a/util/less/test/less/strings.less b/util/less/test/less/strings.less
new file mode 100644
index 0000000..32fad72
--- /dev/null
+++ b/util/less/test/less/strings.less
@@ -0,0 +1,51 @@
+#strings {
+  background-image: url("http://son-of-a-banana.com");
+  quotes: "~" "~";
+  content: "#*%:&^,)!.(~*})";
+  empty: "";
+  brackets: "{" "}";
+  escapes: "\"hello\" \\world";
+  escapes2: "\"llo";
+}
+#comments {
+  content: "/* hello */ // not-so-secret";
+}
+#single-quote {
+  quotes: "'" "'";
+  content: '""#!&""';
+  empty: '';
+  semi-colon: ';';
+}
+#escaped {
+  filter: ~"DX.Transform.MS.BS.filter(opacity=50)";
+}
+#one-line { image: url(http://tooks.com) }
+#crazy { image: url(http://), "}", url("http://}") }
+#interpolation {
+  @var: '/dev';
+  url: "http://lesscss.org@{var}/image.jpg";
+
+  @var2: 256;
+  url2: "http://lesscss.org/image-@{var2}.jpg";
+
+  @var3: #456;
+  url3: "http://lesscss.org@{var3}";
+
+  @var4: hello;
+  url4: "http://lesscss.org/@{var4}";
+
+  @var5: 54.4px;
+  url5: "http://lesscss.org/@{var5}";
+}
+
+// multiple calls with string interpolation
+
+.mix-mul (@a: green) {
+    color: ~"@{a}";
+}
+.mix-mul-class {
+    .mix-mul(blue);
+    .mix-mul(red);
+    .mix-mul(black);
+    .mix-mul(orange);
+}
diff --git a/util/less/test/less/urls.less b/util/less/test/less/urls.less
new file mode 100644
index 0000000..93ec412
--- /dev/null
+++ b/util/less/test/less/urls.less
@@ -0,0 +1,33 @@
+ at font-face {
+  src: url("/fonts/garamond-pro.ttf");
+  src: local(Futura-Medium),
+       url(fonts.svg#MyGeometricModern) format("svg");
+}
+#shorthands {
+  background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
+}
+#misc {
+  background-image: url(images/image.jpg);
+}
+#data-uri {
+  background: url(data:image/png;charset=utf-8;base64,
+    kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
+    k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
+    kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
+  background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
+  background-image: url(http://fonts.googleapis.com/css?family=\"Rokkitt\":\(400\),700);
+}
+
+#svg-data-uri {
+  background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
+}
+
+.comma-delimited {
+  background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
+}
+.values {
+    @a: 'Trebuchet';
+    url: url(@a);
+}
+
+ at import "import/import-and-relative-paths-test";
diff --git a/util/less/test/less/variables.less b/util/less/test/less/variables.less
new file mode 100644
index 0000000..f91c209
--- /dev/null
+++ b/util/less/test/less/variables.less
@@ -0,0 +1,53 @@
+ at a: 2;
+ at x: @a * @a;
+ at y: @x + 1;
+ at z: @x * 2 + @y;
+
+.variables {
+  width: @z + 1cm; // 14cm
+}
+
+ at b: @a * 10;
+ at c: #888;
+
+ at fonts: "Trebuchet MS", Verdana, sans-serif;
+ at f: @fonts;
+
+ at quotes: "~" "~";
+ at q: @quotes;
+
+.variables {
+  height: @b + @x + 0px; // 24px
+  color: @c;
+  font-family: @f;
+  quotes: @q;
+}
+
+.redefinition {
+    @var: 4;
+    @var: 2;
+    @var: 3;
+    three: @var;
+}
+
+.values {
+    @a: 'Trebuchet';
+    @multi: 'A', B, C;
+    font-family: @a, @a, @a;
+    color: @c !important;
+    multi: something @multi, @a;
+}
+
+.variable-names {
+    @var: 'hello';
+    @name: 'var';
+    name: @@name;
+}
+.alpha {
+    @var: 42;
+    filter: alpha(opacity=@var);
+}
+
+a:nth-child(@a) {
+    border: 1px;
+}
diff --git a/util/less/test/less/whitespace.less b/util/less/test/less/whitespace.less
new file mode 100644
index 0000000..ab4804d
--- /dev/null
+++ b/util/less/test/less/whitespace.less
@@ -0,0 +1,44 @@
+
+
+.whitespace
+  { color: white; }  
+  
+.whitespace
+{
+  color: white;
+}
+  .whitespace
+{ color: white; }
+
+.whitespace{color:white;}  
+.whitespace { color : white ; }
+
+.white,
+.space,
+.mania
+{ color: white; }
+
+.no-semi-column { color: white }
+.no-semi-column {
+  color: white;
+  white-space: pre
+}
+.no-semi-column {border: 2px solid white}
+.newlines {
+  background: the,
+              great,
+              wall;
+  border: 2px
+          solid
+          black;
+}
+.empty {
+  
+}
+.sel
+.newline_ws	.tab_ws	{
+color:
+white;
+background-position: 45
+-23;
+}
diff --git a/util/less/tree.js b/util/less/tree.js
deleted file mode 100755
index eb08aa4..0000000
--- a/util/less/tree.js
+++ /dev/null
@@ -1,13 +0,0 @@
-require('less/tree').find = function (obj, fun) {
-    for (var i = 0, r; i < obj.length; i++) {
-        if (r = fun.call(obj, obj[i])) { return r }
-    }
-    return null;
-};
-require('less/tree').jsify = function (obj) {
-    if (Array.isArray(obj.value) && (obj.value.length > 1)) {
-        return '[' + obj.value.map(function (v) { return v.toCSS(false) }).join(', ') + ']';
-    } else {
-        return obj.toCSS(false);
-    }
-};
diff --git a/util/less/tree/alpha.js b/util/less/tree/alpha.js
deleted file mode 100755
index 551ccba..0000000
--- a/util/less/tree/alpha.js
+++ /dev/null
@@ -1,17 +0,0 @@
-(function (tree) {
-
-tree.Alpha = function (val) {
-    this.value = val;
-};
-tree.Alpha.prototype = {
-    toCSS: function () {
-        return "alpha(opacity=" +
-               (this.value.toCSS ? this.value.toCSS() : this.value) + ")";
-    },
-    eval: function (env) {
-        if (this.value.eval) { this.value = this.value.eval(env) }
-        return this;
-    }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/anonymous.js b/util/less/tree/anonymous.js
deleted file mode 100755
index 89840d0..0000000
--- a/util/less/tree/anonymous.js
+++ /dev/null
@@ -1,13 +0,0 @@
-(function (tree) {
-
-tree.Anonymous = function (string) {
-    this.value = string.value || string;
-};
-tree.Anonymous.prototype = {
-    toCSS: function () {
-        return this.value;
-    },
-    eval: function () { return this }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/call.js b/util/less/tree/call.js
deleted file mode 100755
index 4a72932..0000000
--- a/util/less/tree/call.js
+++ /dev/null
@@ -1,45 +0,0 @@
-(function (tree) {
-
-//
-// A function call node.
-//
-tree.Call = function (name, args, index) {
-    this.name = name;
-    this.args = args;
-    this.index = index;
-};
-tree.Call.prototype = {
-    //
-    // When evaluating a function call,
-    // we either find the function in `tree.functions` [1],
-    // in which case we call it, passing the  evaluated arguments,
-    // or we simply print it out as it appeared originally [2].
-    //
-    // The *functions.js* file contains the built-in functions.
-    //
-    // The reason why we evaluate the arguments, is in the case where
-    // we try to pass a variable to a function, like: `saturate(@color)`.
-    // The function should receive the value, not the variable.
-    //
-    eval: function (env) {
-        var args = this.args.map(function (a) { return a.eval(env) });
-
-        if (this.name in tree.functions) { // 1.
-            try {
-                return tree.functions[this.name].apply(tree.functions, args);
-            } catch (e) {
-                throw { message: "error evaluating function `" + this.name + "`",
-                        index: this.index };
-            }
-        } else { // 2.
-            return new(tree.Anonymous)(this.name +
-                   "(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
-        }
-    },
-
-    toCSS: function (env) {
-        return this.eval(env).toCSS();
-    }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/color.js b/util/less/tree/color.js
deleted file mode 100755
index 38d34f8..0000000
--- a/util/less/tree/color.js
+++ /dev/null
@@ -1,98 +0,0 @@
-(function (tree) {
-//
-// RGB Colors - #ff0014, #eee
-//
-tree.Color = function (rgb, a) {
-    //
-    // The end goal here, is to parse the arguments
-    // into an integer triplet, such as `128, 255, 0`
-    //
-    // This facilitates operations and conversions.
-    //
-    if (Array.isArray(rgb)) {
-        this.rgb = rgb;
-    } else if (rgb.length == 6) {
-        this.rgb = rgb.match(/.{2}/g).map(function (c) {
-            return parseInt(c, 16);
-        });
-    } else if (rgb.length == 8) {
-        this.alpha = parseInt(rgb.substring(0,2), 16) / 255.0;
-        this.rgb = rgb.substr(2).match(/.{2}/g).map(function (c) {
-            return parseInt(c, 16);
-        });
-    } else {
-        this.rgb = rgb.split('').map(function (c) {
-            return parseInt(c + c, 16);
-        });
-    }
-    this.alpha = typeof(a) === 'number' ? a : 1;
-};
-tree.Color.prototype = {
-    eval: function () { return this },
-
-    //
-    // If we have some transparency, the only way to represent it
-    // is via `rgba`. Otherwise, we use the hex representation,
-    // which has better compatibility with older browsers.
-    // Values are capped between `0` and `255`, rounded and zero-padded.
-    //
-    toCSS: function () {
-        if (this.alpha < 1.0) {
-            return "rgba(" + this.rgb.map(function (c) {
-                return Math.round(c);
-            }).concat(this.alpha).join(', ') + ")";
-        } else {
-            return '#' + this.rgb.map(function (i) {
-                i = Math.round(i);
-                i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
-                return i.length === 1 ? '0' + i : i;
-            }).join('');
-        }
-    },
-
-    //
-    // Operations have to be done per-channel, if not,
-    // channels will spill onto each other. Once we have
-    // our result, in the form of an integer triplet,
-    // we create a new Color node to hold the result.
-    //
-    operate: function (op, other) {
-        var result = [];
-
-        if (! (other instanceof tree.Color)) {
-            other = other.toColor();
-        }
-
-        for (var c = 0; c < 3; c++) {
-            result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
-        }
-        return new(tree.Color)(result, this.alpha + other.alpha);
-    },
-
-    toHSL: function () {
-        var r = this.rgb[0] / 255,
-            g = this.rgb[1] / 255,
-            b = this.rgb[2] / 255,
-            a = this.alpha;
-
-        var max = Math.max(r, g, b), min = Math.min(r, g, b);
-        var h, s, l = (max + min) / 2, d = max - min;
-
-        if (max === min) {
-            h = s = 0;
-        } else {
-            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
-
-            switch (max) {
-                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
-                case g: h = (b - r) / d + 2;               break;
-                case b: h = (r - g) / d + 4;               break;
-            }
-            h /= 6;
-        }
-        return { h: h * 360, s: s, l: l, a: a };
-    }
-};
-
-
-})(require('less/tree'));
diff --git a/util/less/tree/comment.js b/util/less/tree/comment.js
deleted file mode 100755
index 2d95dff..0000000
--- a/util/less/tree/comment.js
+++ /dev/null
@@ -1,14 +0,0 @@
-(function (tree) {
-
-tree.Comment = function (value, silent) {
-    this.value = value;
-    this.silent = !!silent;
-};
-tree.Comment.prototype = {
-    toCSS: function (env) {
-        return env.compress ? '' : this.value;
-    },
-    eval: function () { return this }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/dimension.js b/util/less/tree/dimension.js
deleted file mode 100755
index 41f3ca2..0000000
--- a/util/less/tree/dimension.js
+++ /dev/null
@@ -1,34 +0,0 @@
-(function (tree) {
-
-//
-// A number with a unit
-//
-tree.Dimension = function (value, unit) {
-    this.value = parseFloat(value);
-    this.unit = unit || null;
-};
-
-tree.Dimension.prototype = {
-    eval: function () { return this },
-    toColor: function () {
-        return new(tree.Color)([this.value, this.value, this.value]);
-    },
-    toCSS: function () {
-        var css = this.value + this.unit;
-        return css;
-    },
-
-    // In an operation between two Dimensions,
-    // we default to the first Dimension's unit,
-    // so `1px + 2em` will yield `3px`.
-    // In the future, we could implement some unit
-    // conversions such that `100cm + 10mm` would yield
-    // `101cm`.
-    operate: function (op, other) {
-        return new(tree.Dimension)
-                  (tree.operate(op, this.value, other.value),
-                  this.unit || other.unit);
-    }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/directive.js b/util/less/tree/directive.js
deleted file mode 100755
index fbe9a93..0000000
--- a/util/less/tree/directive.js
+++ /dev/null
@@ -1,33 +0,0 @@
-(function (tree) {
-
-tree.Directive = function (name, value) {
-    this.name = name;
-    if (Array.isArray(value)) {
-        this.ruleset = new(tree.Ruleset)([], value);
-    } else {
-        this.value = value;
-    }
-};
-tree.Directive.prototype = {
-    toCSS: function (ctx, env) {
-        if (this.ruleset) {
-            this.ruleset.root = true;
-            return this.name + (env.compress ? '{' : ' {\n  ') +
-                   this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n  ') +
-                               (env.compress ? '}': '\n}\n');
-        } else {
-            return this.name + ' ' + this.value.toCSS() + ';\n';
-        }
-    },
-    eval: function (env) {
-        env.frames.unshift(this);
-        this.ruleset = this.ruleset && this.ruleset.eval(env);
-        env.frames.shift();
-        return this;
-    },
-    variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
-    find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
-    rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/element.js b/util/less/tree/element.js
deleted file mode 100755
index 27cf822..0000000
--- a/util/less/tree/element.js
+++ /dev/null
@@ -1,35 +0,0 @@
-(function (tree) {
-
-tree.Element = function (combinator, value) {
-    this.combinator = combinator instanceof tree.Combinator ?
-                      combinator : new(tree.Combinator)(combinator);
-    this.value = value ? value.trim() : "";
-};
-tree.Element.prototype.toCSS = function (env) {
-    return this.combinator.toCSS(env || {}) + this.value;
-};
-
-tree.Combinator = function (value) {
-    if (value === ' ') {
-        this.value = ' ';
-    } else if (value === '& ') {
-        this.value = '& ';
-    } else {
-        this.value = value ? value.trim() : "";
-    }
-};
-tree.Combinator.prototype.toCSS = function (env) {
-    return {
-        ''  : '',
-        ' ' : ' ',
-        '&' : '',
-        '& ' : ' ',
-        ':' : ' :',
-        '::': '::',
-        '+' : env.compress ? '+' : ' + ',
-        '~' : env.compress ? '~' : ' ~ ',
-        '>' : env.compress ? '>' : ' > '
-    }[this.value];
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/expression.js b/util/less/tree/expression.js
deleted file mode 100755
index f638a1b..0000000
--- a/util/less/tree/expression.js
+++ /dev/null
@@ -1,23 +0,0 @@
-(function (tree) {
-
-tree.Expression = function (value) { this.value = value };
-tree.Expression.prototype = {
-    eval: function (env) {
-        if (this.value.length > 1) {
-            return new(tree.Expression)(this.value.map(function (e) {
-                return e.eval(env);
-            }));
-        } else if (this.value.length === 1) {
-            return this.value[0].eval(env);
-        } else {
-            return this;
-        }
-    },
-    toCSS: function (env) {
-        return this.value.map(function (e) {
-            return e.toCSS(env);
-        }).join(' ');
-    }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/import.js b/util/less/tree/import.js
deleted file mode 100755
index 2a95120..0000000
--- a/util/less/tree/import.js
+++ /dev/null
@@ -1,77 +0,0 @@
-(function (tree) {
-//
-// CSS @import node
-//
-// The general strategy here is that we don't want to wait
-// for the parsing to be completed, before we start importing
-// the file. That's because in the context of a browser,
-// most of the time will be spent waiting for the server to respond.
-//
-// On creation, we push the import path to our import queue, though
-// `import,push`, we also pass it a callback, which it'll call once
-// the file has been fetched, and parsed.
-//
-tree.Import = function (path, imports) {
-    var that = this;
-
-    this._path = path;
-
-    // The '.less' extension is optional
-    if (path instanceof tree.Quoted) {
-        this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
-    } else {
-        this.path = path.value.value || path.value;
-    }
-
-    this.css = /css$/.test(this.path);
-
-    // Only pre-compile .less files
-    if (! this.css) {
-        imports.push(this.path, function (root) {
-            if (! root) {
-                throw new(Error)("Error parsing " + that.path);
-            }
-            that.root = root;
-        });
-    }
-};
-
-//
-// The actual import node doesn't return anything, when converted to CSS.
-// The reason is that it's used at the evaluation stage, so that the rules
-// it imports can be treated like any other rules.
-//
-// In `eval`, we make sure all Import nodes get evaluated, recursively, so
-// we end up with a flat structure, which can easily be imported in the parent
-// ruleset.
-//
-tree.Import.prototype = {
-    toCSS: function () {
-        if (this.css) {
-            return "@import " + this._path.toCSS() + ';\n';
-        } else {
-            return "";
-        }
-    },
-    eval: function (env) {
-        var ruleset;
-
-        if (this.css) {
-            return this;
-        } else {
-            ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
-
-            for (var i = 0; i < ruleset.rules.length; i++) {
-                if (ruleset.rules[i] instanceof tree.Import) {
-                    Array.prototype
-                         .splice
-                         .apply(ruleset.rules,
-                                [i, 1].concat(ruleset.rules[i].eval(env)));
-                }
-            }
-            return ruleset.rules;
-        }
-    }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/javascript.js b/util/less/tree/javascript.js
deleted file mode 100755
index 4ec66b9..0000000
--- a/util/less/tree/javascript.js
+++ /dev/null
@@ -1,51 +0,0 @@
-(function (tree) {
-
-tree.JavaScript = function (string, index, escaped) {
-    this.escaped = escaped;
-    this.expression = string;
-    this.index = index;
-};
-tree.JavaScript.prototype = {
-    eval: function (env) {
-        var result,
-            that = this,
-            context = {};
-
-        var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
-            return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
-        });
-
-        try {
-            expression = new(Function)('return (' + expression + ')');
-        } catch (e) {
-            throw { message: "JavaScript evaluation error: `" + expression + "`" ,
-                    index: this.index };
-        }
-
-        for (var k in env.frames[0].variables()) {
-            context[k.slice(1)] = {
-                value: env.frames[0].variables()[k].value,
-                toJS: function () {
-                    return this.value.eval(env).toCSS();
-                }
-            };
-        }
-
-        try {
-            result = expression.call(context);
-        } catch (e) {
-            throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
-                    index: this.index };
-        }
-        if (typeof(result) === 'string') {
-            return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
-        } else if (Array.isArray(result)) {
-            return new(tree.Anonymous)(result.join(', '));
-        } else {
-            return new(tree.Anonymous)(result);
-        }
-    }
-};
-
-})(require('less/tree'));
-
diff --git a/util/less/tree/keyword.js b/util/less/tree/keyword.js
deleted file mode 100755
index a4431ba..0000000
--- a/util/less/tree/keyword.js
+++ /dev/null
@@ -1,9 +0,0 @@
-(function (tree) {
-
-tree.Keyword = function (value) { this.value = value };
-tree.Keyword.prototype = {
-    eval: function () { return this },
-    toCSS: function () { return this.value }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/mixin.js b/util/less/tree/mixin.js
deleted file mode 100755
index 24cb8e4..0000000
--- a/util/less/tree/mixin.js
+++ /dev/null
@@ -1,106 +0,0 @@
-(function (tree) {
-
-tree.mixin = {};
-tree.mixin.Call = function (elements, args, index) {
-    this.selector = new(tree.Selector)(elements);
-    this.arguments = args;
-    this.index = index;
-};
-tree.mixin.Call.prototype = {
-    eval: function (env) {
-        var mixins, args, rules = [], match = false;
-
-        for (var i = 0; i < env.frames.length; i++) {
-            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
-                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
-                for (var m = 0; m < mixins.length; m++) {
-                    if (mixins[m].match(args, env)) {
-                        try {
-                            Array.prototype.push.apply(
-                                  rules, mixins[m].eval(env, this.arguments).rules);
-                            match = true;
-                        } catch (e) {
-                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
-                        }
-                    }
-                }
-                if (match) {
-                    return rules;
-                } else {
-                    throw { message: 'No matching definition was found for `' +
-                                      this.selector.toCSS().trim() + '('      +
-                                      this.arguments.map(function (a) {
-                                          return a.toCSS();
-                                      }).join(', ') + ")`",
-                            index:   this.index };
-                }
-            }
-        }
-        throw { message: this.selector.toCSS().trim() + " is undefined",
-                index: this.index };
-    }
-};
-
-tree.mixin.Definition = function (name, params, rules) {
-    this.name = name;
-    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
-    this.params = params;
-    this.arity = params.length;
-    this.rules = rules;
-    this._lookups = {};
-    this.required = params.reduce(function (count, p) {
-        if (!p.name || (p.name && !p.value)) { return count + 1 }
-        else                                 { return count }
-    }, 0);
-    this.parent = tree.Ruleset.prototype;
-    this.frames = [];
-};
-tree.mixin.Definition.prototype = {
-    toCSS:     function ()     { return "" },
-    variable:  function (name) { return this.parent.variable.call(this, name) },
-    variables: function ()     { return this.parent.variables.call(this) },
-    find:      function ()     { return this.parent.find.apply(this, arguments) },
-    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
-
-    eval: function (env, args) {
-        var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
-
-        for (var i = 0, val; i < this.params.length; i++) {
-            if (this.params[i].name) {
-                if (val = (args && args[i]) || this.params[i].value) {
-                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
-                } else {
-                    throw { message: "wrong number of arguments for " + this.name +
-                            ' (' + args.length + ' for ' + this.arity + ')' };
-                }
-            }
-        }
-        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
-            _arguments.push(args[i] || this.params[i].value);
-        }
-        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
-
-        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
-            frames: [this, frame].concat(this.frames, env.frames)
-        });
-    },
-    match: function (args, env) {
-        var argsLength = (args && args.length) || 0, len;
-
-        if (argsLength < this.required)                               { return false }
-        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
-
-        len = Math.min(argsLength, this.arity);
-
-        for (var i = 0; i < len; i++) {
-            if (!this.params[i].name) {
-                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/operation.js b/util/less/tree/operation.js
deleted file mode 100755
index d2e4d57..0000000
--- a/util/less/tree/operation.js
+++ /dev/null
@@ -1,32 +0,0 @@
-(function (tree) {
-
-tree.Operation = function (op, operands) {
-    this.op = op.trim();
-    this.operands = operands;
-};
-tree.Operation.prototype.eval = function (env) {
-    var a = this.operands[0].eval(env),
-        b = this.operands[1].eval(env),
-        temp;
-
-    if (a instanceof tree.Dimension && b instanceof tree.Color) {
-        if (this.op === '*' || this.op === '+') {
-            temp = b, b = a, a = temp;
-        } else {
-            throw { name: "OperationError",
-                    message: "Can't substract or divide a color from a number" };
-        }
-    }
-    return a.operate(this.op, b);
-};
-
-tree.operate = function (op, a, b) {
-    switch (op) {
-        case '+': return a + b;
-        case '-': return a - b;
-        case '*': return a * b;
-        case '/': return a / b;
-    }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/quoted.js b/util/less/tree/quoted.js
deleted file mode 100755
index 6ddfa40..0000000
--- a/util/less/tree/quoted.js
+++ /dev/null
@@ -1,29 +0,0 @@
-(function (tree) {
-
-tree.Quoted = function (str, content, escaped, i) {
-    this.escaped = escaped;
-    this.value = content || '';
-    this.quote = str.charAt(0);
-    this.index = i;
-};
-tree.Quoted.prototype = {
-    toCSS: function () {
-        if (this.escaped) {
-            return this.value;
-        } else {
-            return this.quote + this.value + this.quote;
-        }
-    },
-    eval: function (env) {
-        var that = this;
-        var value = this.value.replace(/`([^`]+)`/g, function (_, exp) {
-            return new(tree.JavaScript)(exp, that.index, true).eval(env).value;
-        }).replace(/@\{([\w-]+)\}/g, function (_, name) {
-            var v = new(tree.Variable)('@' + name, that.index).eval(env);
-            return v.value || v.toCSS();
-        });
-        return new(tree.Quoted)(this.quote + value + this.quote, value, this.escaped, this.index);
-    }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/rule.js b/util/less/tree/rule.js
deleted file mode 100755
index 18cc49b..0000000
--- a/util/less/tree/rule.js
+++ /dev/null
@@ -1,38 +0,0 @@
-(function (tree) {
-
-tree.Rule = function (name, value, important, index) {
-    this.name = name;
-    this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
-    this.important = important ? ' ' + important.trim() : '';
-    this.index = index;
-
-    if (name.charAt(0) === '@') {
-        this.variable = true;
-    } else { this.variable = false }
-};
-tree.Rule.prototype.toCSS = function (env) {
-    if (this.variable) { return "" }
-    else {
-        return this.name + (env.compress ? ':' : ': ') +
-               this.value.toCSS(env) +
-               this.important + ";";
-    }
-};
-
-tree.Rule.prototype.eval = function (context) {
-    return new(tree.Rule)(this.name, this.value.eval(context), this.important, this.index);
-};
-
-tree.Shorthand = function (a, b) {
-    this.a = a;
-    this.b = b;
-};
-
-tree.Shorthand.prototype = {
-    toCSS: function (env) {
-        return this.a.toCSS(env) + "/" + this.b.toCSS(env);
-    },
-    eval: function () { return this }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/ruleset.js b/util/less/tree/ruleset.js
deleted file mode 100755
index 3ba1c13..0000000
--- a/util/less/tree/ruleset.js
+++ /dev/null
@@ -1,212 +0,0 @@
-(function (tree) {
-
-tree.Ruleset = function (selectors, rules) {
-    this.selectors = selectors;
-    this.rules = rules;
-    this._lookups = {};
-};
-tree.Ruleset.prototype = {
-    eval: function (env) {
-        var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
-
-        ruleset.root = this.root;
-
-        // push the current ruleset to the frames stack
-        env.frames.unshift(ruleset);
-
-        // Evaluate imports
-        if (ruleset.root) {
-            for (var i = 0; i < ruleset.rules.length; i++) {
-                if (ruleset.rules[i] instanceof tree.Import) {
-                    Array.prototype.splice
-                         .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
-                }
-            }
-        }
-
-        // Store the frames around mixin definitions,
-        // so they can be evaluated like closures when the time comes.
-        for (var i = 0; i < ruleset.rules.length; i++) {
-            if (ruleset.rules[i] instanceof tree.mixin.Definition) {
-                ruleset.rules[i].frames = env.frames.slice(0);
-            }
-        }
-
-        // Evaluate mixin calls.
-        for (var i = 0; i < ruleset.rules.length; i++) {
-            if (ruleset.rules[i] instanceof tree.mixin.Call) {
-                Array.prototype.splice
-                     .apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
-            }
-        }
-
-        // Evaluate everything else
-        for (var i = 0, rule; i < ruleset.rules.length; i++) {
-            rule = ruleset.rules[i];
-
-            if (! (rule instanceof tree.mixin.Definition)) {
-                ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
-            }
-        }
-
-        // Pop the stack
-        env.frames.shift();
-
-        return ruleset;
-    },
-    match: function (args) {
-        return !args || args.length === 0;
-    },
-    variables: function () {
-        if (this._variables) { return this._variables }
-        else {
-            return this._variables = this.rules.reduce(function (hash, r) {
-                if (r instanceof tree.Rule && r.variable === true) {
-                    hash[r.name] = r;
-                }
-                return hash;
-            }, {});
-        }
-    },
-    variable: function (name) {
-        return this.variables()[name];
-    },
-    rulesets: function () {
-        if (this._rulesets) { return this._rulesets }
-        else {
-            return this._rulesets = this.rules.filter(function (r) {
-                return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
-            });
-        }
-    },
-    find: function (selector, self) {
-        self = self || this;
-        var rules = [], rule, match,
-            key = selector.toCSS();
-
-        if (key in this._lookups) { return this._lookups[key] }
-
-        this.rulesets().forEach(function (rule) {
-            if (rule !== self) {
-                for (var j = 0; j < rule.selectors.length; j++) {
-                    if (match = selector.match(rule.selectors[j])) {
-                        if (selector.elements.length > 1) {
-                            Array.prototype.push.apply(rules, rule.find(
-                                new(tree.Selector)(selector.elements.slice(1)), self));
-                        } else {
-                            rules.push(rule);
-                        }
-                        break;
-                    }
-                }
-            }
-        });
-        return this._lookups[key] = rules;
-    },
-    //
-    // Entry point for code generation
-    //
-    //     `context` holds an array of arrays.
-    //
-    toCSS: function (context, env) {
-        var css = [],      // The CSS output
-            rules = [],    // node.Rule instances
-            rulesets = [], // node.Ruleset instances
-            paths = [],    // Current selectors
-            selector,      // The fully rendered selector
-            rule;
-
-        if (! this.root) {
-            if (context.length === 0) {
-                paths = this.selectors.map(function (s) { return [s] });
-            } else {
-                this.joinSelectors( paths, context, this.selectors );
-            }
-        }
-
-        // Compile rules and rulesets
-        for (var i = 0; i < this.rules.length; i++) {
-            rule = this.rules[i];
-
-            if (rule.rules || (rule instanceof tree.Directive)) {
-                rulesets.push(rule.toCSS(paths, env));
-            } else if (rule instanceof tree.Comment) {
-                if (!rule.silent) {
-                    if (this.root) {
-                        rulesets.push(rule.toCSS(env));
-                    } else {
-                        rules.push(rule.toCSS(env));
-                    }
-                }
-            } else {
-                if (rule.toCSS && !rule.variable) {
-                    rules.push(rule.toCSS(env));
-                } else if (rule.value && !rule.variable) {
-                    rules.push(rule.value.toString());
-                }
-            }
-        } 
-
-        rulesets = rulesets.join('');
-
-        // If this is the root node, we don't render
-        // a selector, or {}.
-        // Otherwise, only output if this ruleset has rules.
-        if (this.root) {
-            css.push(rules.join(env.compress ? '' : '\n'));
-        } else {
-            if (rules.length > 0) {
-                selector = paths.map(function (p) {
-                    return p.map(function (s) {
-                        return s.toCSS(env);
-                    }).join('').trim();
-                }).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
-                css.push(selector,
-                        (env.compress ? '{' : ' {\n  ') +
-                        rules.join(env.compress ? '' : '\n  ') +
-                        (env.compress ? '}' : '\n}\n'));
-            }
-        }
-        css.push(rulesets);
-
-        return css.join('') + (env.compress ? '\n' : '');
-    },
-
-    joinSelectors: function (paths, context, selectors) {
-        for (var s = 0; s < selectors.length; s++) {
-            this.joinSelector(paths, context, selectors[s]);
-        }
-    },
-
-    joinSelector: function (paths, context, selector) {
-        var before = [], after = [], beforeElements = [],
-            afterElements = [], hasParentSelector = false, el;
-
-        for (var i = 0; i < selector.elements.length; i++) {
-            el = selector.elements[i];
-            if (el.combinator.value[0] === '&') {
-                hasParentSelector = true;
-            }
-            if (hasParentSelector) afterElements.push(el);
-            else                   beforeElements.push(el);
-        }
-
-        if (! hasParentSelector) {
-            afterElements = beforeElements;
-            beforeElements = [];
-        }
-
-        if (beforeElements.length > 0) {
-            before.push(new(tree.Selector)(beforeElements));
-        }
-
-        if (afterElements.length > 0) {
-            after.push(new(tree.Selector)(afterElements));
-        }
-
-        for (var c = 0; c < context.length; c++) {
-            paths.push(before.concat(context[c]).concat(after));
-        }
-    }
-};
-})(require('less/tree'));
diff --git a/util/less/tree/selector.js b/util/less/tree/selector.js
deleted file mode 100755
index eaaa042..0000000
--- a/util/less/tree/selector.js
+++ /dev/null
@@ -1,28 +0,0 @@
-(function (tree) {
-
-tree.Selector = function (elements) {
-    this.elements = elements;
-    if (this.elements[0].combinator.value === "") {
-        this.elements[0].combinator.value = ' ';
-    }
-};
-tree.Selector.prototype.match = function (other) {
-    if (this.elements[0].value === other.elements[0].value) {
-        return true;
-    } else {
-        return false;
-    }
-};
-tree.Selector.prototype.toCSS = function (env) {
-    if (this._css) { return this._css }
-
-    return this._css = this.elements.map(function (e) {
-        if (typeof(e) === 'string') {
-            return ' ' + e.trim();
-        } else {
-            return e.toCSS(env);
-        }
-    }).join('');
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/url.js b/util/less/tree/url.js
deleted file mode 100755
index f427070..0000000
--- a/util/less/tree/url.js
+++ /dev/null
@@ -1,25 +0,0 @@
-(function (tree) {
-
-tree.URL = function (val, paths) {
-    if (val.data) {
-        this.attrs = val;
-    } else {
-        // Add the base path if the URL is relative and we are in the browser
-        if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
-            val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
-        }
-        this.value = val;
-        this.paths = paths;
-    }
-};
-tree.URL.prototype = {
-    toCSS: function () {
-        return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
-                                    : this.value.toCSS()) + ")";
-    },
-    eval: function (ctx) {
-        return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
-    }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/value.js b/util/less/tree/value.js
deleted file mode 100755
index 922096c..0000000
--- a/util/less/tree/value.js
+++ /dev/null
@@ -1,24 +0,0 @@
-(function (tree) {
-
-tree.Value = function (value) {
-    this.value = value;
-    this.is = 'value';
-};
-tree.Value.prototype = {
-    eval: function (env) {
-        if (this.value.length === 1) {
-            return this.value[0].eval(env);
-        } else {
-            return new(tree.Value)(this.value.map(function (v) {
-                return v.eval(env);
-            }));
-        }
-    },
-    toCSS: function (env) {
-        return this.value.map(function (e) {
-            return e.toCSS(env);
-        }).join(env.compress ? ',' : ', ');
-    }
-};
-
-})(require('less/tree'));
diff --git a/util/less/tree/variable.js b/util/less/tree/variable.js
deleted file mode 100755
index 10f7c08..0000000
--- a/util/less/tree/variable.js
+++ /dev/null
@@ -1,24 +0,0 @@
-(function (tree) {
-
-tree.Variable = function (name, index) { this.name = name, this.index = index };
-tree.Variable.prototype = {
-    eval: function (env) {
-        var variable, v, name = this.name;
-
-        if (name.indexOf('@@') == 0) {
-            name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
-        }
-
-        if (variable = tree.find(env.frames, function (frame) {
-            if (v = frame.variable(name)) {
-                return v.value.eval(env);
-            }
-        })) { return variable }
-        else {
-            throw { message: "variable " + name + " is undefined",
-                    index: this.index };
-        }
-    }
-};
-
-})(require('less/tree'));
diff --git a/util/shrinksafe/shrinksafe.jar b/util/shrinksafe/shrinksafe.jar
index 53c37f9..4aa6137 100644
Binary files a/util/shrinksafe/shrinksafe.jar and b/util/shrinksafe/shrinksafe.jar differ
diff --git a/util/shrinksafe/src/manifest b/util/shrinksafe/src/manifest
index 85b8ea3..90f76f6 100644
--- a/util/shrinksafe/src/manifest
+++ b/util/shrinksafe/src/manifest
@@ -1,3 +1,3 @@
-Manifest-Version: 1.0
-Main-Class: org.dojotoolkit.shrinksafe.Main
-Class-Path: js.jar
+Manifest-Version: 1.0
+Main-Class: org.dojotoolkit.shrinksafe.Main
+Class-Path: js.jar
diff --git a/util/shrinksafe/src/org/dojotoolkit/shrinksafe/Compressor.java b/util/shrinksafe/src/org/dojotoolkit/shrinksafe/Compressor.java
index 4288d64..f01a9f3 100644
--- a/util/shrinksafe/src/org/dojotoolkit/shrinksafe/Compressor.java
+++ b/util/shrinksafe/src/org/dojotoolkit/shrinksafe/Compressor.java
@@ -945,7 +945,7 @@ public class Compressor {
                 sb.append('\\');
                 sb.append(escapeQuote);
             } else {
-            	if (escapeUnicode || c == 0) { // always escape the null character (#5027)
+            	if (escapeUnicode || c == 0 || c == 65534 || c == 65535) { // always escape non-characters (#5027,#15969)
 	                int hexSize;
 	                if (c < 256) {
 	                    // 2-digit hex
diff --git a/util/shrinksafe/src/org/dojotoolkit/shrinksafe/resources/Messages.properties b/util/shrinksafe/src/org/dojotoolkit/shrinksafe/resources/Messages.properties
index 947132d..fefdf00 100644
--- a/util/shrinksafe/src/org/dojotoolkit/shrinksafe/resources/Messages.properties
+++ b/util/shrinksafe/src/org/dojotoolkit/shrinksafe/resources/Messages.properties
@@ -38,7 +38,7 @@ msg.shell.stripConsoleInvalid =\
     Invalid value provided for stripConsole
 
 msg.shell.usage =\
-    Dojo ShrinkSafe 2.0 $Rev: 22183 $ \n\
+    Dojo ShrinkSafe 2.0 $Rev$ \n\
     \n\
     Usage: java -jar shrinksafe.jar [options...] [files or urls]\n\
     Valid options are:\n\
diff --git a/util/shrinksafe/tests/escapeunicode.js b/util/shrinksafe/tests/escapeunicode.js
index 0044dc9..5691fc7 100644
--- a/util/shrinksafe/tests/escapeunicode.js
+++ b/util/shrinksafe/tests/escapeunicode.js
@@ -1 +1,2 @@
-"\u03B1";//+" ω"
\ No newline at end of file
+"\u03B1";//+" ω"
+"_\u0000_\uFFFD_\uFFFE_\uFFFF_"
diff --git a/util/shrinksafe/tests/module.js b/util/shrinksafe/tests/module.js
index e3945df..94ae880 100644
--- a/util/shrinksafe/tests/module.js
+++ b/util/shrinksafe/tests/module.js
@@ -2,25 +2,28 @@ dojo.provide("shrinksafe.tests.module");
 
 // basic helper functions for running multiple tests.
 shrinksafe.tests.module.getContents = function(path){
-	// summary: Load a file from this /tests/ path into a variable
+	// summary:
+	//		Load a file from this /tests/ path into a variable
 	path = "../shrinksafe/tests/" + path;
 	return readFile(path); // String
-}
+};
 
 shrinksafe.tests.module.compress = function(source, stripConsole, escapeUnicode){
-	// summary: Shorthand to compress some String version of JS code
+	// summary:
+	//		Shorthand to compress some String version of JS code
 	return new String(Packages.org.dojotoolkit.shrinksafe.Compressor.compressScript(source, 0, 1, escapeUnicode, stripConsole)).toString();
-}
+};
 
 shrinksafe.tests.module.loader = function(path, stripConsole, escapeUnicode){
-	// summary: Simple function to load and compress some file. Returns and object
-	//	 with 'original' and 'compressed' members, respectively.
+	// summary:
+	//		Simple function to load and compress some file. Returns and object
+	//	 	with 'original' and 'compressed' members, respectively.
 	var s = shrinksafe.tests.module.getContents(path);
 	return {
 		original: s,
 		compressed: shrinksafe.tests.module.compress(s, stripConsole, escapeUnicode || false)
 	};
-}
+};
 
 try{
 	tests.register("shrinksafe",
@@ -149,10 +152,18 @@ try{
 		function escapeUnicode(t){
 			var src = shrinksafe.tests.module.loader("escapeunicode.js", null);
 			t.assertTrue(src.compressed.indexOf('"\u03b1";') == 0);
+			t.assertTrue(src.compressed.indexOf('_\\x00_') > 0);
+			t.assertTrue(src.compressed.indexOf('_\ufffd_') > 0);
+			t.assertTrue(src.compressed.indexOf('_\\ufffe_') > 0);
+			t.assertTrue(src.compressed.indexOf('_\\uffff_') > 0);
 //			t.is('"\u03b1 \u03c9";', src.compressed); // extended test isn't working... encoding problem with input?
 
 			src = shrinksafe.tests.module.loader("escapeunicode.js", null, true);
 			t.assertTrue(src.compressed.indexOf('"\\u03b1";') == 0);
+			t.assertTrue(src.compressed.indexOf('_\\x00_') > 0);
+			t.assertTrue(src.compressed.indexOf('_\\ufffd_') > 0);
+			t.assertTrue(src.compressed.indexOf('_\\ufffe_') > 0);
+			t.assertTrue(src.compressed.indexOf('_\\uffff_') > 0);
 //			t.is('"\\u03b1 \\u03c9";', src.compressed);
 		},
 
diff --git a/util/shrinksafe/tests/runner.sh b/util/shrinksafe/tests/runner.sh
index e678321..d339566 100755
--- a/util/shrinksafe/tests/runner.sh
+++ b/util/shrinksafe/tests/runner.sh
@@ -1,4 +1,4 @@
 #!/bin/sh
 
 cd ../../doh
-java -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main runner.js testModule=shrinksafe.tests.module testUrl=../shrinksafe/tests/module.js
+java -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar org.mozilla.javascript.tools.shell.Main ../../dojo/dojo.js baseUrl=../../dojo load=doh test=util/shrinksafe/tests/module testUrl=../shrinksafe/tests/module.js

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/dojo.git



More information about the Pkg-javascript-commits mailing list